redquark-amiberry-rb/src/osdep/rasp_gfx.cpp
2017-01-16 00:32:31 +01:00

894 lines
21 KiB
C++

#include "sysconfig.h"
#include "sysdeps.h"
#include "config.h"
#include "uae.h"
#include "options.h"
#include "gui.h"
#include "memory.h"
#include "newcpu.h"
#include "inputdevice.h"
#include "custom.h"
#include "xwin.h"
#include "drawing.h"
#include "savestate.h"
#include "picasso96.h"
#include <png.h>
#include <SDL.h>
#include <SDL_image.h>
#include <SDL_gfxPrimitives.h>
#ifdef ANDROIDSDL
#include <android/log.h>
#endif
#include "threaddep/thread.h"
#include "bcm_host.h"
/* SDL surface variable for output of emulation */
SDL_Surface *prSDLScreen = NULL;
/* Dummy SDL variable for screen init */
SDL_Surface *Dummy_prSDLScreen = NULL;
static SDL_Surface *current_screenshot = NULL;
/* Possible screen modes (x and y resolutions) */
#define MAX_SCREEN_MODES 11
static int x_size_table[MAX_SCREEN_MODES] = { 640, 640, 720, 800, 800, 960, 1024, 1280, 1280, 1680, 1920 };
static int y_size_table[MAX_SCREEN_MODES] = { 400, 480, 400, 480, 600, 540, 768, 720, 800, 1050, 1080 };
struct PicassoResolution *DisplayModes;
struct MultiDisplay Displays[MAX_DISPLAYS];
int screen_is_picasso = 0;
static int curr_layer_width = 0;
static char screenshot_filename_default[255] = {
'/',
't',
'm',
'p',
'/',
'n',
'u',
'l',
'l',
'.',
'p',
'n',
'g',
'\0'
};
char *screenshot_filename = (char *)&screenshot_filename_default[0];
FILE *screenshot_file = NULL;
static void CreateScreenshot(void);
static int save_thumb(char *path);
int delay_savestate_frame = 0;
int DispManXElementpresent = 0;
static long next_synctime = 0;
uae_sem_t vsync_wait_sem;
DISPMANX_DISPLAY_HANDLE_T dispmanxdisplay;
DISPMANX_MODEINFO_T dispmanxdinfo;
DISPMANX_RESOURCE_HANDLE_T dispmanxresource_amigafb_1;
DISPMANX_RESOURCE_HANDLE_T dispmanxresource_amigafb_2;
DISPMANX_ELEMENT_HANDLE_T dispmanxelement;
DISPMANX_UPDATE_HANDLE_T dispmanxupdate;
VC_RECT_T src_rect;
VC_RECT_T dst_rect;
VC_RECT_T blit_rect;
unsigned char current_resource_amigafb = 0;
unsigned char need_wait_dispmanx_semaphore = 0;
long start;
void vsync_callback(unsigned int a, void* b)
{
// Here we are synchronized with VSync
// next_synctime is what we were expected as sync time.
last_synctime = read_processor_time();
// Check if we miss a frame (with a margin of 1000 cycles)
if (last_synctime - next_synctime > time_per_frame * (1 + currprefs.gfx_framerate) - (long)1000)
adjust_idletime(-1);
else
adjust_idletime(last_synctime - start);
// Update next synctime with current sync.
next_synctime = last_synctime + time_per_frame * (1 + currprefs.gfx_framerate);
uae_sem_post(&vsync_wait_sem);
}
int graphics_setup(void)
{
#ifdef PICASSO96
picasso_InitResolutions();
InitPicasso96();
#endif
bcm_host_init();
return 1;
}
void InitAmigaVidMode(struct uae_prefs *p)
{
/* Initialize structure for Amiga video modes */
gfxvidinfo.pixbytes = 2;
gfxvidinfo.bufmem = (uae_u8 *)prSDLScreen->pixels;
gfxvidinfo.outwidth = p->gfx_size.width;
gfxvidinfo.outheight = p->gfx_size.height;
gfxvidinfo.rowbytes = prSDLScreen->pitch;
#ifdef PICASSO96
if (screen_is_picasso)
{
gfxvidinfo.outwidth = picasso_vidinfo.width;
gfxvidinfo.outheight = picasso_vidinfo.height;
}
#endif
}
void graphics_dispmanshutdown(void)
{
if (DispManXElementpresent == 1)
{
DispManXElementpresent = 0;
dispmanxupdate = vc_dispmanx_update_start(0);
vc_dispmanx_element_remove(dispmanxupdate, dispmanxelement);
vc_dispmanx_update_submit_sync(dispmanxupdate);
}
}
void graphics_subshutdown(void)
{
if (dispmanxresource_amigafb_1 != 0)
graphics_dispmanshutdown();
}
static void open_screen(struct uae_prefs *p)
{
VC_DISPMANX_ALPHA_T alpha = {
(DISPMANX_FLAGS_ALPHA_T)(DISPMANX_FLAGS_ALPHA_FROM_SOURCE | DISPMANX_FLAGS_ALPHA_FIXED_ALL_PIXELS),
255, /*alpha 0->255*/
0
};
uint32_t vc_image_ptr;
int width;
int height;
#ifdef PICASSO96
if (screen_is_picasso)
{
width = picasso_vidinfo.width;
height = picasso_vidinfo.height;
}
else
#endif
{
p->gfx_resolution = p->gfx_size.width > 600 ? 1 : 0;
width = p->gfx_size.width;
height = p->gfx_size.height;
}
if (Dummy_prSDLScreen)
{ // y.f. 2016-10-13 : free the previous screen surface every time,
// so we can have fullscreen while running and windowed while in config window.
// Apparently, something somewhere is resetting the screen.
SDL_FreeSurface(Dummy_prSDLScreen);
Dummy_prSDLScreen = NULL;
}
if (Dummy_prSDLScreen == NULL)
{
// Dummy_prSDLScreen = SDL_SetVideoMode(videoInfo->current_w, videoInfo->current_h, videoInfo->vfmt->BitsPerPixel, SDL_SWSURFACE | SDL_FULLSCREEN);
Dummy_prSDLScreen = SDL_SetVideoMode(width, height, 16, SDL_SWSURFACE | SDL_FULLSCREEN);
}
// check if resolution hasn't changed in menu. Otherwise free the resources so that they will be re-generated with new resolution.
if ((dispmanxresource_amigafb_1 != 0) &&
((blit_rect.width != width) || (blit_rect.height != height) || (currprefs.gfx_correct_aspect != changed_prefs.gfx_correct_aspect) ||
(currprefs.gfx_fullscreen_ratio != changed_prefs.gfx_fullscreen_ratio)))
{
#ifdef DEBUG
printf("Emulation resolution change detected.\n");
#endif // DEBUG
if (prSDLScreen != NULL)
{
SDL_FreeSurface(prSDLScreen);
prSDLScreen = 0;
}
graphics_dispmanshutdown();
vc_dispmanx_resource_delete(dispmanxresource_amigafb_1);
vc_dispmanx_resource_delete(dispmanxresource_amigafb_2);
dispmanxresource_amigafb_1 = 0;
dispmanxresource_amigafb_2 = 0;
}
if (dispmanxresource_amigafb_1 == 0)
{
#ifdef DEBUG
printf("Emulation resolution: Width %i Height: %i\n", width, height);
#endif //DEBUG
currprefs.gfx_correct_aspect = changed_prefs.gfx_correct_aspect;
currprefs.gfx_fullscreen_ratio = changed_prefs.gfx_fullscreen_ratio;
prSDLScreen = SDL_CreateRGBSurface(SDL_SWSURFACE,
width,
height,
16,
Dummy_prSDLScreen->format->Rmask,
Dummy_prSDLScreen->format->Gmask,
Dummy_prSDLScreen->format->Bmask,
Dummy_prSDLScreen->format->Amask);
dispmanxdisplay = vc_dispmanx_display_open(0);
vc_dispmanx_display_get_info(dispmanxdisplay, &dispmanxdinfo);
dispmanxresource_amigafb_1 = vc_dispmanx_resource_create(VC_IMAGE_RGB565, width, height, &vc_image_ptr);
dispmanxresource_amigafb_2 = vc_dispmanx_resource_create(VC_IMAGE_RGB565, width, height, &vc_image_ptr);
vc_dispmanx_rect_set(&blit_rect, 0, 0, width, height);
vc_dispmanx_resource_write_data(dispmanxresource_amigafb_1,
VC_IMAGE_RGB565,
width *2,
prSDLScreen->pixels,
&blit_rect);
vc_dispmanx_rect_set(&src_rect, 0, 0, width << 16, height << 16);
}
// 16/9 to 4/3 ratio adaptation.
if (currprefs.gfx_correct_aspect == 0)
{
// Fullscreen.
int scaled_width = dispmanxdinfo.width * currprefs.gfx_fullscreen_ratio / 100;
int scaled_height = dispmanxdinfo.height * currprefs.gfx_fullscreen_ratio / 100;
vc_dispmanx_rect_set( &dst_rect,
(dispmanxdinfo.width - scaled_width)/2,
(dispmanxdinfo.height - scaled_height)/2,
scaled_width,
scaled_height);
}
else
{
// 4/3 shrink.
int scaled_width = dispmanxdinfo.width * currprefs.gfx_fullscreen_ratio / 100;
int scaled_height = dispmanxdinfo.height * currprefs.gfx_fullscreen_ratio / 100;
vc_dispmanx_rect_set( &dst_rect,
(dispmanxdinfo.width - scaled_width / 16 * 12)/2,
(dispmanxdinfo.height - scaled_height)/2,
scaled_width/16*12,
scaled_height);
}
if (DispManXElementpresent == 0)
{
DispManXElementpresent = 1;
dispmanxupdate = vc_dispmanx_update_start(0);
dispmanxelement = vc_dispmanx_element_add( dispmanxupdate,
dispmanxdisplay,
2, // layer
&dst_rect,
dispmanxresource_amigafb_1,
&src_rect,
DISPMANX_PROTECTION_NONE,
&alpha,
NULL, // clamp
DISPMANX_NO_ROTATE);
vc_dispmanx_update_submit(dispmanxupdate, NULL, NULL);
}
if (prSDLScreen != NULL)
{
InitAmigaVidMode(p);
init_row_map();
}
//framecnt = 1; // Don't draw frame before reset done
}
void update_display(struct uae_prefs *p)
{
open_screen(p);
SDL_ShowCursor(SDL_DISABLE);
framecnt = 1; // Don't draw frame before reset done
}
int check_prefs_changed_gfx(void)
{
int changed = 0;
if (currprefs.gfx_size.height != changed_prefs.gfx_size.height ||
currprefs.gfx_size.width != changed_prefs.gfx_size.width ||
currprefs.gfx_size_fs.width != changed_prefs.gfx_size_fs.width ||
currprefs.gfx_resolution != changed_prefs.gfx_resolution)
{
cfgfile_configuration_change(1);
currprefs.gfx_size.height = changed_prefs.gfx_size.height;
currprefs.gfx_size.width = changed_prefs.gfx_size.width;
currprefs.gfx_size_fs.width = changed_prefs.gfx_size_fs.width;
currprefs.gfx_resolution = changed_prefs.gfx_resolution;
update_display(&currprefs);
changed = 1;
}
if (currprefs.leds_on_screen != changed_prefs.leds_on_screen ||
currprefs.pandora_hide_idle_led != changed_prefs.pandora_hide_idle_led ||
currprefs.pandora_vertical_offset != changed_prefs.pandora_vertical_offset)
{
currprefs.leds_on_screen = changed_prefs.leds_on_screen;
currprefs.pandora_hide_idle_led = changed_prefs.pandora_hide_idle_led;
currprefs.pandora_vertical_offset = changed_prefs.pandora_vertical_offset;
changed = 1;
}
if (currprefs.chipset_refreshrate != changed_prefs.chipset_refreshrate)
{
currprefs.chipset_refreshrate = changed_prefs.chipset_refreshrate;
init_hz_full();
changed = 1;
}
return changed;
}
int lockscr(void)
{
//SDL_LockSurface(prSDLScreen);
return 1;
}
void unlockscr(void)
{
//SDL_UnlockSurface(prSDLScreen);
}
void wait_for_vsync(void)
{
// Temporary
}
void flush_screen()
{
if (savestate_state == STATE_DOSAVE)
{
if (delay_savestate_frame > 0)
--delay_savestate_frame;
else
{
CreateScreenshot();
save_thumb(screenshot_filename);
savestate_state = 0;
}
}
if (need_wait_dispmanx_semaphore == 1)
{
need_wait_dispmanx_semaphore = 0;
start = read_processor_time();
uae_sem_wait(&vsync_wait_sem);
}
if (current_resource_amigafb == 1)
{
current_resource_amigafb = 0;
vc_dispmanx_resource_write_data( dispmanxresource_amigafb_1,
VC_IMAGE_RGB565,
gfxvidinfo.outwidth * 2,
gfxvidinfo.bufmem,
&blit_rect);
dispmanxupdate = vc_dispmanx_update_start(0);
vc_dispmanx_element_change_source(dispmanxupdate, dispmanxelement, dispmanxresource_amigafb_1);
vc_dispmanx_update_submit(dispmanxupdate, vsync_callback, NULL);
//vc_dispmanx_update_submit_sync(dispmanxupdate);
}
else
{
current_resource_amigafb = 1;
vc_dispmanx_resource_write_data( dispmanxresource_amigafb_2,
VC_IMAGE_RGB565,
gfxvidinfo.outwidth * 2,
gfxvidinfo.bufmem,
&blit_rect);
dispmanxupdate = vc_dispmanx_update_start(0);
vc_dispmanx_element_change_source(dispmanxupdate, dispmanxelement, dispmanxresource_amigafb_2);
vc_dispmanx_update_submit(dispmanxupdate, vsync_callback, NULL);
}
need_wait_dispmanx_semaphore = 1;
init_row_map();
}
void black_screen_now(void)
{
SDL_FillRect(prSDLScreen, NULL, 0);
SDL_Flip(prSDLScreen);
flush_screen();
}
static void graphics_subinit(void)
{
if (prSDLScreen == NULL)
{
fprintf(stderr, "Unable to set video mode: %s\n", SDL_GetError());
return;
}
else
{
SDL_ShowCursor(SDL_DISABLE);
InitAmigaVidMode(&currprefs);
}
}
STATIC_INLINE int bitsInMask(unsigned long mask)
{
/* count bits in mask */
int n = 0;
while (mask)
{
n += mask & 1;
mask >>= 1;
}
return n;
}
STATIC_INLINE int maskShift(unsigned long mask)
{
/* determine how far mask is shifted */
int n = 0;
while (!(mask & 1))
{
n++;
mask >>= 1;
}
return n;
}
static int init_colors(void)
{
int i;
int red_bits, green_bits, blue_bits;
int red_shift, green_shift, blue_shift;
/* Truecolor: */
red_bits = bitsInMask(prSDLScreen->format->Rmask);
green_bits = bitsInMask(prSDLScreen->format->Gmask);
blue_bits = bitsInMask(prSDLScreen->format->Bmask);
red_shift = maskShift(prSDLScreen->format->Rmask);
green_shift = maskShift(prSDLScreen->format->Gmask);
blue_shift = maskShift(prSDLScreen->format->Bmask);
alloc_colors64k(red_bits, green_bits, blue_bits, red_shift, green_shift, blue_shift, 0);
notice_new_xcolors();
for (i = 0; i < 4096; i++)
xcolors[i] = xcolors[i] * 0x00010001;
return 1;
}
/*
* Find the colour depth of the display
*/
static int get_display_depth(void)
{
const SDL_VideoInfo *vid_info;
int depth = 0;
if ((vid_info = SDL_GetVideoInfo())) {
depth = vid_info->vfmt->BitsPerPixel;
/* Don't trust the answer if it's 16 bits; the display
* could actually be 15 bits deep. We'll count the bits
* ourselves */
if (depth == 16)
depth = bitsInMask(vid_info->vfmt->Rmask) + bitsInMask(vid_info->vfmt->Gmask) + bitsInMask(vid_info->vfmt->Bmask);
}
return depth;
}
int GetSurfacePixelFormat(void)
{
int depth = get_display_depth();
int unit = (depth + 1) & 0xF8;
return (unit == 8 ? RGBFB_CHUNKY
: depth == 15 && unit == 16 ? RGBFB_R5G5B5
: depth == 16 && unit == 16 ? RGBFB_R5G6B5
: unit == 24 ? RGBFB_B8G8R8
: unit == 32 ? RGBFB_R8G8B8A8
: RGBFB_NONE);
}
int graphics_init(bool mousecapture)
{
uae_sem_init(&vsync_wait_sem, 0, 0);
graphics_subinit();
if (!init_colors())
return 0;
return 1;
}
void graphics_leave(void)
{
graphics_subshutdown();
SDL_FreeSurface(Dummy_prSDLScreen);
bcm_host_deinit();
SDL_VideoQuit();
}
#define systemRedShift (prSDLScreen->format->Rshift)
#define systemGreenShift (prSDLScreen->format->Gshift)
#define systemBlueShift (prSDLScreen->format->Bshift)
#define systemRedMask (prSDLScreen->format->Rmask)
#define systemGreenMask (prSDLScreen->format->Gmask)
#define systemBlueMask (prSDLScreen->format->Bmask)
static int save_png(SDL_Surface* surface, char *path)
{
int w = surface->w;
int h = surface->h;
unsigned char * pix = (unsigned char *)surface->pixels;
unsigned char writeBuffer[1024 * 3];
FILE *f = fopen(path, "wb");
if (!f) return 0;
png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,
NULL,
NULL,
NULL);
if (!png_ptr) {
fclose(f);
return 0;
}
png_infop info_ptr = png_create_info_struct(png_ptr);
if (!info_ptr) {
png_destroy_write_struct(&png_ptr, NULL);
fclose(f);
return 0;
}
png_init_io(png_ptr, f);
png_set_IHDR(png_ptr,
info_ptr,
w,
h,
8,
PNG_COLOR_TYPE_RGB,
PNG_INTERLACE_NONE,
PNG_COMPRESSION_TYPE_DEFAULT,
PNG_FILTER_TYPE_DEFAULT);
png_write_info(png_ptr, info_ptr);
unsigned char *b = writeBuffer;
int sizeX = w;
int sizeY = h;
int y;
int x;
unsigned short *p = (unsigned short *)pix;
for (y = 0; y < sizeY; y++)
{
for (x = 0; x < sizeX; x++)
{
unsigned short v = p[x];
*b++ = ((v & systemRedMask) >> systemRedShift) << 3; // R
*b++ = ((v & systemGreenMask) >> systemGreenShift) << 2; // G
*b++ = ((v & systemBlueMask) >> systemBlueShift) << 3; // B
}
p += surface->pitch / 2;
png_write_row(png_ptr, writeBuffer);
b = writeBuffer;
}
png_write_end(png_ptr, info_ptr);
png_destroy_write_struct(&png_ptr, &info_ptr);
fclose(f);
return 1;
}
static void CreateScreenshot(void)
{
int w, h;
if (current_screenshot != NULL)
{
SDL_FreeSurface(current_screenshot);
current_screenshot = NULL;
}
w = prSDLScreen->w;
h = prSDLScreen->h;
current_screenshot = SDL_CreateRGBSurfaceFrom(prSDLScreen->pixels,
w,
h,
prSDLScreen->format->BitsPerPixel,
prSDLScreen->pitch,
prSDLScreen->format->Rmask,
prSDLScreen->format->Gmask,
prSDLScreen->format->Bmask,
prSDLScreen->format->Amask);
}
static int save_thumb(char *path)
{
int ret = 0;
if (current_screenshot != NULL)
{
ret = save_png(current_screenshot, path);
SDL_FreeSurface(current_screenshot);
current_screenshot = NULL;
}
return ret;
}
#ifdef PICASSO96
int picasso_palette(void)
{
int i, changed;
changed = 0;
for (i = 0; i < 256; i++) {
int r = picasso96_state.CLUT[i].Red;
int g = picasso96_state.CLUT[i].Green;
int b = picasso96_state.CLUT[i].Blue;
int value = (r << 16 | g << 8 | b);
uae_u32 v = CONVERT_RGB(value);
if (v != picasso_vidinfo.clut[i]) {
picasso_vidinfo.clut[i] = v;
changed = 1;
}
}
return changed;
}
static int resolution_compare(const void *a, const void *b)
{
struct PicassoResolution *ma = (struct PicassoResolution *)a;
struct PicassoResolution *mb = (struct PicassoResolution *)b;
if (ma->res.width < mb->res.width)
return -1;
if (ma->res.width > mb->res.width)
return 1;
if (ma->res.height < mb->res.height)
return -1;
if (ma->res.height > mb->res.height)
return 1;
return ma->depth - mb->depth;
}
static void sortmodes(void)
{
int i = 0, idx = -1;
int pw = -1, ph = -1;
while (DisplayModes[i].depth >= 0)
i++;
qsort(DisplayModes, i, sizeof(struct PicassoResolution), resolution_compare);
for (i = 0; DisplayModes[i].depth >= 0; i++) {
if (DisplayModes[i].res.height != ph || DisplayModes[i].res.width != pw) {
ph = DisplayModes[i].res.height;
pw = DisplayModes[i].res.width;
idx++;
}
DisplayModes[i].residx = idx;
}
}
static void modesList(void)
{
int i, j;
i = 0;
while (DisplayModes[i].depth >= 0) {
write_log("%d: %s (", i, DisplayModes[i].name);
j = 0;
while (DisplayModes[i].refresh[j] > 0) {
if (j > 0)
write_log(",");
write_log("%d", DisplayModes[i].refresh[j]);
j++;
}
write_log(")\n");
i++;
}
}
void picasso_InitResolutions(void)
{
struct MultiDisplay *md1;
int i, count = 0;
char tmp[200];
int bit_idx;
int bits[] = { 8, 16, 32 };
Displays[0].primary = 1;
Displays[0].disabled = 0;
Displays[0].rect.left = 0;
Displays[0].rect.top = 0;
Displays[0].rect.right = 800;
Displays[0].rect.bottom = 640;
sprintf(tmp, "%s (%d*%d)", "Display", Displays[0].rect.right, Displays[0].rect.bottom);
Displays[0].name = my_strdup(tmp);
Displays[0].name2 = my_strdup("Display");
md1 = Displays;
DisplayModes = md1->DisplayModes = xmalloc(struct PicassoResolution, MAX_PICASSO_MODES);
for (i = 0; i < MAX_SCREEN_MODES && count < MAX_PICASSO_MODES; i++) {
for (bit_idx = 0; bit_idx < 3; ++bit_idx) {
int bitdepth = bits[bit_idx];
int bit_unit = (bitdepth + 1) & 0xF8;
int rgbFormat = (bitdepth == 8 ? RGBFB_CLUT : (bitdepth == 16 ? RGBFB_R5G6B5 : RGBFB_R8G8B8A8));
int pixelFormat = 1 << rgbFormat;
pixelFormat |= RGBFF_CHUNKY;
if (SDL_VideoModeOK (x_size_table[i], y_size_table[i], 16, SDL_SWSURFACE))
{
DisplayModes[count].res.width = x_size_table[i];
DisplayModes[count].res.height = y_size_table[i];
DisplayModes[count].depth = bit_unit >> 3;
DisplayModes[count].refresh[0] = 50;
DisplayModes[count].refresh[1] = 60;
DisplayModes[count].refresh[2] = 0;
DisplayModes[count].colormodes = pixelFormat;
sprintf(DisplayModes[count].name,
"%dx%d, %d-bit",
DisplayModes[count].res.width,
DisplayModes[count].res.height,
DisplayModes[count].depth * 8);
count++;
}
}
}
DisplayModes[count].depth = -1;
sortmodes();
modesList();
DisplayModes = Displays[0].DisplayModes;
}
#endif
bool vsync_switchmode(int hz)
{
int changed_height = changed_prefs.gfx_size.height;
if (hz >= 55)
hz = 60;
else
hz = 50;
if (hz == 50 && currVSyncRate == 60)
{
// Switch from NTSC -> PAL
switch (changed_height) {
case 200: changed_height = 240; break;
case 216: changed_height = 262; break;
case 240: changed_height = 270; break;
case 256: changed_height = 270; break;
case 262: changed_height = 270; break;
case 270: changed_height = 270; break;
}
}
else if (hz == 60 && currVSyncRate == 50)
{
// Switch from PAL -> NTSC
switch (changed_height) {
case 200: changed_height = 200; break;
case 216: changed_height = 200; break;
case 240: changed_height = 200; break;
case 256: changed_height = 216; break;
case 262: changed_height = 216; break;
case 270: changed_height = 240; break;
}
}
if (changed_height == currprefs.gfx_size.height && hz == currprefs.chipset_refreshrate)
return true;
changed_prefs.gfx_size.height = changed_height;
return true;
}
bool target_graphics_buffer_update(void)
{
bool rate_changed = 0;
// bool rate_changed = SetVSyncRate(currprefs.chipset_refreshrate);
if (currprefs.gfx_size.height != changed_prefs.gfx_size.height)
{
update_display(&changed_prefs);
rate_changed = true;
}
if (rate_changed)
{
black_screen_now();
fpscounter_reset();
time_per_frame = 1000 * 1000 / (currprefs.chipset_refreshrate);
}
return true;
}
#ifdef PICASSO96
void gfx_set_picasso_state(int on)
{
if (on == screen_is_picasso)
return;
screen_is_picasso = on;
open_screen(&currprefs);
picasso_vidinfo.rowbytes = prSDLScreen->pitch;
}
void gfx_set_picasso_modeinfo(uae_u32 w, uae_u32 h, uae_u32 depth, RGBFTYPE rgbfmt)
{
depth >>= 3;
if (((unsigned)picasso_vidinfo.width == w) &&
((unsigned)picasso_vidinfo.height == h) &&
((unsigned)picasso_vidinfo.depth == depth) &&
(picasso_vidinfo.selected_rgbformat == rgbfmt))
return;
picasso_vidinfo.selected_rgbformat = rgbfmt;
picasso_vidinfo.width = w;
picasso_vidinfo.height = h;
picasso_vidinfo.depth = 2; // Native depth
picasso_vidinfo.extra_mem = 1;
picasso_vidinfo.pixbytes = 2; // Native bytes
if (screen_is_picasso)
{
open_screen(&currprefs);
picasso_vidinfo.rowbytes = prSDLScreen->pitch;
picasso_vidinfo.rgbformat = RGBFB_R5G6B5;
}
}
uae_u8 *gfx_lock_picasso(void)
{
// We lock the surface directly after create and flip
picasso_vidinfo.rowbytes = prSDLScreen->pitch;
return (uae_u8 *)prSDLScreen->pixels;
}
void gfx_unlock_picasso(void)
{
// We lock the surface directly after create and flip, so no unlock here
}
#endif // PICASSO96