Fixed framerate problem with vsyc

This commit is contained in:
Dimitris Panokostas 2016-12-16 16:53:22 +01:00
parent d4c2ab0884
commit df3bd366e2
4 changed files with 1530 additions and 1466 deletions

View file

@ -10,9 +10,9 @@
<Transport>None</Transport> <Transport>None</Transport>
</BuildHost> </BuildHost>
<DeploymentHost> <DeploymentHost>
<HostName>192.168.1.155</HostName> <HostName>172.16.2.42</HostName>
<Transport>SSH</Transport> <Transport>SSH</Transport>
<UserName>root</UserName> <UserName>pi</UserName>
</DeploymentHost> </DeploymentHost>
<MainSourceTransferCommand> <MainSourceTransferCommand>
<SkipWhenRunningCommandList>false</SkipWhenRunningCommandList> <SkipWhenRunningCommandList>false</SkipWhenRunningCommandList>

File diff suppressed because it is too large Load diff

View file

@ -23,26 +23,26 @@
#define lores_shift 0 #define lores_shift 0
extern bool aga_mode; extern bool aga_mode;
STATIC_INLINE int coord_hw_to_window_x (int x) STATIC_INLINE int coord_hw_to_window_x(int x)
{ {
x -= DISPLAY_LEFT_SHIFT; x -= DISPLAY_LEFT_SHIFT;
return x; return x;
} }
STATIC_INLINE int coord_window_to_hw_x (int x) STATIC_INLINE int coord_window_to_hw_x(int x)
{ {
return x + DISPLAY_LEFT_SHIFT; return x + DISPLAY_LEFT_SHIFT;
} }
STATIC_INLINE int coord_diw_to_window_x (int x) STATIC_INLINE int coord_diw_to_window_x(int x)
{ {
return (x - DISPLAY_LEFT_SHIFT + DIW_DDF_OFFSET - 1); return (x - DISPLAY_LEFT_SHIFT + DIW_DDF_OFFSET - 1);
} }
STATIC_INLINE int coord_window_to_diw_x (int x) STATIC_INLINE int coord_window_to_diw_x(int x)
{ {
x = coord_window_to_hw_x (x); x = coord_window_to_hw_x(x);
return x - DIW_DDF_OFFSET; return x - DIW_DDF_OFFSET;
} }
extern int framecnt; extern int framecnt;
@ -54,9 +54,9 @@ extern int framecnt;
* !!! See color_reg_xxx functions below before touching !!! * !!! See color_reg_xxx functions below before touching !!!
*/ */
struct color_entry { struct color_entry {
uae_u16 color_regs_ecs[32]; uae_u16 color_regs_ecs[32];
xcolnr acolors[256]; xcolnr acolors[256];
uae_u32 color_regs_aga[256]; uae_u32 color_regs_aga[256];
bool borderblank, bordersprite; bool borderblank, bordersprite;
}; };
@ -68,19 +68,20 @@ struct color_entry {
#else #else
STATIC_INLINE uae_u16 CONVERT_RGB(uae_u32 c) STATIC_INLINE uae_u16 CONVERT_RGB(uae_u32 c)
{ {
uae_u16 ret; uae_u16 ret;
__asm__ ( __asm__(
"ubfx r1, %[c], #19, #5 \n\t" "ubfx r1, %[c], #19, #5 \n\t"
"ubfx r2, %[c], #10, #6 \n\t" "ubfx r2, %[c], #10, #6 \n\t"
"ubfx %[v], %[c], #3, #5 \n\t" "ubfx %[v], %[c], #3, #5 \n\t"
"orr %[v], %[v], r1, lsl #11 \n\t" "orr %[v], %[v], r1, lsl #11 \n\t"
"orr %[v], %[v], r2, lsl #5 \n\t" "orr %[v], %[v], r2, lsl #5 \n\t"
: [v] "=r" (ret) : [c] "r" (c) : "r1", "r2" ); : [v] "=r" (ret) : [c] "r" (c) : "r1",
return ret; "r2");
return ret;
} }
#endif #endif
STATIC_INLINE xcolnr getxcolor (int c) STATIC_INLINE xcolnr getxcolor(int c)
{ {
if (aga_mode) if (aga_mode)
return CONVERT_RGB(c); return CONVERT_RGB(c);
@ -89,7 +90,7 @@ STATIC_INLINE xcolnr getxcolor (int c)
} }
/* functions for reading, writing, copying and comparing struct color_entry */ /* functions for reading, writing, copying and comparing struct color_entry */
STATIC_INLINE int color_reg_get (struct color_entry *ce, int c) STATIC_INLINE int color_reg_get(struct color_entry *ce, int c)
{ {
if (aga_mode) if (aga_mode)
return ce->color_regs_aga[c]; return ce->color_regs_aga[c];
@ -97,7 +98,7 @@ STATIC_INLINE int color_reg_get (struct color_entry *ce, int c)
return ce->color_regs_ecs[c]; return ce->color_regs_ecs[c];
} }
STATIC_INLINE void color_reg_set (struct color_entry *ce, int c, int v) STATIC_INLINE void color_reg_set(struct color_entry *ce, int c, int v)
{ {
if (aga_mode) if (aga_mode)
ce->color_regs_aga[c] = v; ce->color_regs_aga[c] = v;
@ -106,15 +107,15 @@ STATIC_INLINE void color_reg_set (struct color_entry *ce, int c, int v)
} }
/* ugly copy hack, is there better solution? */ /* ugly copy hack, is there better solution? */
STATIC_INLINE void color_reg_cpy (struct color_entry *dst, struct color_entry *src) STATIC_INLINE void color_reg_cpy(struct color_entry *dst, struct color_entry *src)
{ {
dst->borderblank = src->borderblank; dst->borderblank = src->borderblank;
if (aga_mode) if (aga_mode)
/* copy acolors and color_regs_aga */ /* copy acolors and color_regs_aga */
memcpy (dst->acolors, src->acolors, sizeof(struct color_entry) - sizeof(uae_u16) * 32); memcpy(dst->acolors, src->acolors, sizeof(struct color_entry) - sizeof(uae_u16) * 32);
else else
/* copy first 32 acolors and color_regs_ecs */ /* copy first 32 acolors and color_regs_ecs */
memcpy(dst->color_regs_ecs, src->color_regs_ecs, sizeof(uae_u16) * 32 + sizeof(xcolnr) * 32); memcpy(dst->color_regs_ecs, src->color_regs_ecs, sizeof(uae_u16) * 32 + sizeof(xcolnr) * 32);
} }
/* /*
@ -128,9 +129,9 @@ STATIC_INLINE void color_reg_cpy (struct color_entry *dst, struct color_entry *s
#define COLOR_CHANGE_BRDBLANK 0x80000000 #define COLOR_CHANGE_BRDBLANK 0x80000000
struct color_change { struct color_change {
int linepos; int linepos;
int regno; int regno;
unsigned int value; unsigned int value;
}; };
/* 440 rather than 880, since sprites are always lores. */ /* 440 rather than 880, since sprites are always lores. */
@ -143,15 +144,15 @@ struct color_change {
struct sprite_entry struct sprite_entry
{ {
unsigned short pos; unsigned short pos;
unsigned short max; unsigned short max;
unsigned int first_pixel; unsigned int first_pixel;
bool has_attached; bool has_attached;
}; };
union sps_union { union sps_union {
uae_u8 bytes[MAX_SPR_PIXELS]; uae_u8 bytes[MAX_SPR_PIXELS];
uae_u32 words[MAX_SPR_PIXELS / 4]; uae_u32 words[MAX_SPR_PIXELS / 4];
}; };
extern union sps_union spixstate; extern union sps_union spixstate;
@ -170,26 +171,26 @@ extern struct draw_info curr_drawinfo[2 * (MAXVPOS + 2) + 1];
* comparison (smart update stuff). */ * comparison (smart update stuff). */
struct decision { struct decision {
/* Records the leftmost access of BPL1DAT. */ /* Records the leftmost access of BPL1DAT. */
int plfleft, plfright, plflinelen; int plfleft, plfright, plflinelen;
/* Display window: native coordinates, depend on lores state. */ /* Display window: native coordinates, depend on lores state. */
int diwfirstword, diwlastword; int diwfirstword, diwlastword;
int ctable; int ctable;
uae_u16 bplcon0, bplcon2; uae_u16 bplcon0, bplcon2;
uae_u16 bplcon3, bplcon4; uae_u16 bplcon3, bplcon4;
uae_u8 nr_planes; uae_u8 nr_planes;
uae_u8 bplres; uae_u8 bplres;
bool ham_seen; bool ham_seen;
bool ham_at_start; bool ham_at_start;
bool bordersprite_seen; bool bordersprite_seen;
}; };
/* Anything related to changes in hw registers during the DDF for one /* Anything related to changes in hw registers during the DDF for one
* line. */ * line. */
struct draw_info { struct draw_info {
int first_sprite_entry, last_sprite_entry; int first_sprite_entry, last_sprite_entry;
int first_color_change, last_color_change; int first_color_change, last_color_change;
int nr_color_changes, nr_sprites; int nr_color_changes, nr_sprites;
}; };
extern struct decision line_decisions[2 * (MAXVPOS + 2) + 1]; extern struct decision line_decisions[2 * (MAXVPOS + 2) + 1];
@ -197,17 +198,17 @@ extern struct decision line_decisions[2 * (MAXVPOS + 2) + 1];
extern uae_u8 line_data[(MAXVPOS + 2) * 2][MAX_PLANES * MAX_WORDS_PER_LINE * 2]; extern uae_u8 line_data[(MAXVPOS + 2) * 2][MAX_PLANES * MAX_WORDS_PER_LINE * 2];
/* Functions in drawing.c. */ /* Functions in drawing.c. */
extern int coord_native_to_amiga_y (int); extern int coord_native_to_amiga_y(int);
extern int coord_native_to_amiga_x (int); extern int coord_native_to_amiga_x(int);
extern void hsync_record_line_state (int lineno); extern void hsync_record_line_state(int lineno);
extern void vsync_handle_redraw (void); extern void vsync_handle_redraw(void);
extern void vsync_handle_check (void); extern void vsync_handle_check(void);
extern void init_hardware_for_drawing_frame (void); extern void init_hardware_for_drawing_frame(void);
extern void reset_drawing (void); extern void reset_drawing(void);
extern void drawing_init (void); extern void drawing_init(void);
extern unsigned long time_per_frame; extern long time_per_frame;
extern void adjust_idletime(long ns_waited); extern void adjust_idletime(long ns_waited);
/* Finally, stuff that shouldn't really be shared. */ /* Finally, stuff that shouldn't really be shared. */
@ -218,15 +219,15 @@ extern void adjust_idletime(long ns_waited);
extern int inhibit_frame; extern int inhibit_frame;
STATIC_INLINE void set_inhibit_frame (int bit) STATIC_INLINE void set_inhibit_frame(int bit)
{ {
inhibit_frame |= 1 << bit; inhibit_frame |= 1 << bit;
} }
STATIC_INLINE void clear_inhibit_frame (int bit) STATIC_INLINE void clear_inhibit_frame(int bit)
{ {
inhibit_frame &= ~(1 << bit); inhibit_frame &= ~(1 << bit);
} }
STATIC_INLINE void toggle_inhibit_frame (int bit) STATIC_INLINE void toggle_inhibit_frame(int bit)
{ {
inhibit_frame ^= 1 << bit; inhibit_frame ^= 1 << bit;
} }

View file

@ -4,7 +4,7 @@
#include "uae.h" #include "uae.h"
#include "options.h" #include "options.h"
#include "gui.h" #include "gui.h"
#include "include/memory.h" #include "memory.h"
#include "newcpu.h" #include "newcpu.h"
#include "inputdevice.h" #include "inputdevice.h"
#include "custom.h" #include "custom.h"
@ -42,7 +42,7 @@ int screen_is_picasso = 0;
static int curr_layer_width = 0; static int curr_layer_width = 0;
static char screenshot_filename_default[255] = { static char screenshot_filename_default[255] = {
'/', '/',
't', 't',
'm', 'm',
@ -65,10 +65,12 @@ static int save_thumb(char *path);
int delay_savestate_frame = 0; int delay_savestate_frame = 0;
int DispManXElementpresent = 0; int DispManXElementpresent = 0;
static long next_synctime = 0; static long next_synctime = 0;
uae_sem_t vsync_wait_sem; uae_sem_t vsync_wait_sem;
DISPMANX_DISPLAY_HANDLE_T dispmanxdisplay; DISPMANX_DISPLAY_HANDLE_T dispmanxdisplay;
DISPMANX_MODEINFO_T dispmanxdinfo; DISPMANX_MODEINFO_T dispmanxdinfo;
DISPMANX_RESOURCE_HANDLE_T dispmanxresource_amigafb_1; DISPMANX_RESOURCE_HANDLE_T dispmanxresource_amigafb_1;
@ -80,26 +82,28 @@ VC_RECT_T dst_rect;
VC_RECT_T blit_rect; VC_RECT_T blit_rect;
unsigned char current_resource_amigafb = 0; unsigned char current_resource_amigafb = 0;
unsigned char need_wait_dispmanx_semaphore = 0; unsigned char need_wait_dispmanx_semaphore = 0;
long start; long start;
void vsync_callback(unsigned int a, void* b) void vsync_callback(unsigned int a, void* b)
{ {
uae_sem_post(&vsync_wait_sem); // Here we are synchronized with VSync
// Here we are synchronized with VSync // next_synctime is what we were expected as sync time.
// next_synctime is what we were expected as sync time.
last_synctime = read_processor_time(); last_synctime = read_processor_time();
// check if we miss a frame (with a margin of 1000 cycles) // 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) if (last_synctime - next_synctime > time_per_frame * (1 + currprefs.gfx_framerate) - (long)1000)
adjust_idletime(-1); adjust_idletime(-1);
else else
adjust_idletime(last_synctime - start); adjust_idletime(last_synctime - start);
// Update next synctime with current sync // Update next synctime with current sync.
next_synctime = last_synctime + time_per_frame * (1 + currprefs.gfx_framerate); next_synctime = last_synctime + time_per_frame * (1 + currprefs.gfx_framerate);
uae_sem_post(&vsync_wait_sem); uae_sem_post(&vsync_wait_sem);
} }
int graphics_setup(void) int graphics_setup(void)
{ {
#ifdef PICASSO96 #ifdef PICASSO96
@ -110,9 +114,10 @@ int graphics_setup(void)
return 1; return 1;
} }
void InitAmigaVidMode(struct uae_prefs *p) void InitAmigaVidMode(struct uae_prefs *p)
{ {
/* Initialize structure for Amiga video modes */ /* Initialize structure for Amiga video modes */
gfxvidinfo.pixbytes = 2; gfxvidinfo.pixbytes = 2;
gfxvidinfo.bufmem = (uae_u8 *)prSDLScreen->pixels; gfxvidinfo.bufmem = (uae_u8 *)prSDLScreen->pixels;
gfxvidinfo.outwidth = p->gfx_size.width; gfxvidinfo.outwidth = p->gfx_size.width;
@ -124,7 +129,7 @@ void InitAmigaVidMode(struct uae_prefs *p)
//gfxvidinfo.outheight = picasso_vidinfo.height; //gfxvidinfo.outheight = picasso_vidinfo.height;
} }
#endif #endif
//gfxvidinfo.rowbytes = prSDLScreen->pitch; //gfxvidinfo.rowbytes = prSDLScreen->pitch;
gfxvidinfo.rowbytes = blit_rect.width * 2; gfxvidinfo.rowbytes = blit_rect.width * 2;
} }
@ -139,23 +144,30 @@ void graphics_dispmanshutdown(void)
} }
} }
void graphics_subshutdown(void) void graphics_subshutdown(void)
{ {
if (dispmanxresource_amigafb_1 != 0) if (dispmanxresource_amigafb_1 != 0)
graphics_dispmanshutdown(); graphics_dispmanshutdown();
// Dunno if below lines are usefull for Rpi... // Dunno if below lines are usefull for Rpi...
//SDL_FreeSurface(prSDLScreen); //SDL_FreeSurface(prSDLScreen);
//prSDLScreen = NULL; //prSDLScreen = NULL;
} }
static void open_screen(struct uae_prefs *p) static void open_screen(struct uae_prefs *p)
{ {
VC_DISPMANX_ALPHA_T alpha = { VC_DISPMANX_ALPHA_T alpha = {
(DISPMANX_FLAGS_ALPHA_T)(DISPMANX_FLAGS_ALPHA_FROM_SOURCE | DISPMANX_FLAGS_ALPHA_FIXED_ALL_PIXELS), (DISPMANX_FLAGS_ALPHA_T)(DISPMANX_FLAGS_ALPHA_FROM_SOURCE | DISPMANX_FLAGS_ALPHA_FIXED_ALL_PIXELS),
255, /*alpha 0->255*/ 255, /*alpha 0->255*/
0 0
}; };
uint32_t vc_image_ptr; uint32_t vc_image_ptr;
int width; int width;
int height; int height;
@ -174,33 +186,30 @@ static void open_screen(struct uae_prefs *p)
height = p->gfx_size.height; height = p->gfx_size.height;
} }
//if(prSDLScreen != NULL)
//{ //if(prSDLScreen != NULL)
// SDL_FreeSurface(prSDLScreen); //{
// prSDLScreen = NULL; // SDL_FreeSurface(prSDLScreen);
//} // prSDLScreen = NULL;
//}
if (Dummy_prSDLScreen == NULL) if (Dummy_prSDLScreen == NULL)
{ {
const SDL_VideoInfo* videoInfo = SDL_GetVideoInfo(); const SDL_VideoInfo* videoInfo = SDL_GetVideoInfo();
#ifdef DEBUG
printf("DispmanX: Current resolution: %d x %d %d bpp\n", videoInfo->current_w, videoInfo->current_h, videoInfo->vfmt->BitsPerPixel); printf("DispmanX: Current resolution: %d x %d %d bpp\n", videoInfo->current_w, videoInfo->current_h, videoInfo->vfmt->BitsPerPixel);
#endif // For debug, in order to avoid full screen.
// For debug, in order to avoid full screen.
Dummy_prSDLScreen = SDL_SetVideoMode(videoInfo->current_w, videoInfo->current_h, 16, SDL_SWSURFACE | SDL_FULLSCREEN); Dummy_prSDLScreen = SDL_SetVideoMode(videoInfo->current_w, videoInfo->current_h, 16, SDL_SWSURFACE | SDL_FULLSCREEN);
//Dummy_prSDLScreen = SDL_SetVideoMode(800,480,16,SDL_SWSURFACE ); //Dummy_prSDLScreen = SDL_SetVideoMode(800,480,16,SDL_SWSURFACE );
} }
SDL_ShowCursor(SDL_DISABLE); SDL_ShowCursor(SDL_DISABLE);
// check if resolution hasn't change in menu. otherwise free the resources so that they will be re-generated with new resolution. // check if resolution hasn't change in menu. otherwise free the resources so that they will be re-generated with new resolution.
if ((dispmanxresource_amigafb_1 != 0) && if ((dispmanxresource_amigafb_1 != 0) &&
((blit_rect.width != width) || (blit_rect.height != height) || (currprefs.gfx_correct_aspect != changed_prefs.gfx_correct_aspect) || ((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))) (currprefs.gfx_fullscreen_ratio != changed_prefs.gfx_fullscreen_ratio)))
{ {
#ifdef DEBUG
printf("Emulation resolution change detected.\n"); printf("Emulation resolution change detected.\n");
#endif
if (prSDLScreen != NULL) if (prSDLScreen != NULL)
{ {
SDL_FreeSurface(prSDLScreen); SDL_FreeSurface(prSDLScreen);
@ -215,9 +224,7 @@ static void open_screen(struct uae_prefs *p)
if (dispmanxresource_amigafb_1 == 0) if (dispmanxresource_amigafb_1 == 0)
{ {
#ifdef DEBUG
printf("Emulation resolution: Width %i Height: %i\n", width, height); printf("Emulation resolution: Width %i Height: %i\n", width, height);
#endif
currprefs.gfx_correct_aspect = changed_prefs.gfx_correct_aspect; currprefs.gfx_correct_aspect = changed_prefs.gfx_correct_aspect;
currprefs.gfx_fullscreen_ratio = changed_prefs.gfx_fullscreen_ratio; currprefs.gfx_fullscreen_ratio = changed_prefs.gfx_fullscreen_ratio;
prSDLScreen = SDL_CreateRGBSurface(SDL_SWSURFACE, prSDLScreen = SDL_CreateRGBSurface(SDL_SWSURFACE,
@ -246,7 +253,7 @@ static void open_screen(struct uae_prefs *p)
// 16/9 to 4/3 ratio adaptation. // 16/9 to 4/3 ratio adaptation.
if (currprefs.gfx_correct_aspect == 0) if (currprefs.gfx_correct_aspect == 0)
{ {
// Fullscreen. // Fullscreen.
int scaled_width = dispmanxdinfo.width * currprefs.gfx_fullscreen_ratio / 100; int scaled_width = dispmanxdinfo.width * currprefs.gfx_fullscreen_ratio / 100;
int scaled_height = dispmanxdinfo.height * currprefs.gfx_fullscreen_ratio / 100; int scaled_height = dispmanxdinfo.height * currprefs.gfx_fullscreen_ratio / 100;
vc_dispmanx_rect_set( &dst_rect, vc_dispmanx_rect_set( &dst_rect,
@ -257,7 +264,7 @@ static void open_screen(struct uae_prefs *p)
} }
else else
{ {
// 4/3 shrink. // 4/3 shrink.
int scaled_width = dispmanxdinfo.width * currprefs.gfx_fullscreen_ratio / 100; int scaled_width = dispmanxdinfo.width * currprefs.gfx_fullscreen_ratio / 100;
int scaled_height = dispmanxdinfo.height * currprefs.gfx_fullscreen_ratio / 100; int scaled_height = dispmanxdinfo.height * currprefs.gfx_fullscreen_ratio / 100;
vc_dispmanx_rect_set( &dst_rect, vc_dispmanx_rect_set( &dst_rect,
@ -267,11 +274,11 @@ static void open_screen(struct uae_prefs *p)
scaled_height); scaled_height);
} }
// For debug, in order to avoid full screen. // For debug, in order to avoid full screen.
//vc_dispmanx_rect_set( &dst_rect, (dispmanxdinfo.width /2.7), //vc_dispmanx_rect_set( &dst_rect, (dispmanxdinfo.width /2.7),
// 0 , // 0 ,
// (dispmanxdinfo.width - (dispmanxdinfo.width * 6)/100 )/1.5, // (dispmanxdinfo.width - (dispmanxdinfo.width * 6)/100 )/1.5,
// (dispmanxdinfo.height - (dispmanxdinfo.height * 7)/100 )/1.5); // (dispmanxdinfo.height - (dispmanxdinfo.height * 7)/100 )/1.5);
if (DispManXElementpresent == 0) if (DispManXElementpresent == 0)
@ -297,27 +304,29 @@ static void open_screen(struct uae_prefs *p)
{ {
InitAmigaVidMode(p); InitAmigaVidMode(p);
init_row_map(); init_row_map();
} }
//framecnt = 1; // Don't draw frame before reset done //framecnt = 1; // Don't draw frame before reset done
} }
void update_display(struct uae_prefs *p) void update_display(struct uae_prefs *p)
{ {
open_screen(p); open_screen(p);
SDL_ShowCursor(SDL_DISABLE); SDL_ShowCursor(SDL_DISABLE);
framecnt = 1; // Don't draw frame before reset done framecnt = 1; // Don't draw frame before reset done
} }
int check_prefs_changed_gfx(void) int check_prefs_changed_gfx(void)
{ {
int changed = 0; int changed = 0;
if (currprefs.gfx_size.height != changed_prefs.gfx_size.height || if (currprefs.gfx_size.height != changed_prefs.gfx_size.height ||
currprefs.gfx_size.width != changed_prefs.gfx_size.width || currprefs.gfx_size.width != changed_prefs.gfx_size.width ||
currprefs.gfx_size_fs.width != changed_prefs.gfx_size_fs.width || currprefs.gfx_size_fs.width != changed_prefs.gfx_size_fs.width ||
currprefs.gfx_resolution != changed_prefs.gfx_resolution) currprefs.gfx_resolution != changed_prefs.gfx_resolution)
{ {
cfgfile_configuration_change(1); cfgfile_configuration_change(1);
currprefs.gfx_size.height = changed_prefs.gfx_size.height; currprefs.gfx_size.height = changed_prefs.gfx_size.height;
@ -328,21 +337,21 @@ int check_prefs_changed_gfx(void)
changed = 1; changed = 1;
} }
if (currprefs.leds_on_screen != changed_prefs.leds_on_screen || if (currprefs.leds_on_screen != changed_prefs.leds_on_screen ||
currprefs.pandora_hide_idle_led != changed_prefs.pandora_hide_idle_led || currprefs.pandora_hide_idle_led != changed_prefs.pandora_hide_idle_led ||
currprefs.pandora_vertical_offset != changed_prefs.pandora_vertical_offset) currprefs.pandora_vertical_offset != changed_prefs.pandora_vertical_offset)
{ {
currprefs.leds_on_screen = changed_prefs.leds_on_screen; currprefs.leds_on_screen = changed_prefs.leds_on_screen;
currprefs.pandora_hide_idle_led = changed_prefs.pandora_hide_idle_led; currprefs.pandora_hide_idle_led = changed_prefs.pandora_hide_idle_led;
currprefs.pandora_vertical_offset = changed_prefs.pandora_vertical_offset; currprefs.pandora_vertical_offset = changed_prefs.pandora_vertical_offset;
changed = 1; changed = 1;
} }
if (currprefs.chipset_refreshrate != changed_prefs.chipset_refreshrate) if (currprefs.chipset_refreshrate != changed_prefs.chipset_refreshrate)
{ {
currprefs.chipset_refreshrate = changed_prefs.chipset_refreshrate; currprefs.chipset_refreshrate = changed_prefs.chipset_refreshrate;
init_hz_full(); init_hz_full();
changed = 1; changed = 1;
} }
return changed; return changed;
} }
@ -361,11 +370,13 @@ void unlockscr(void)
void wait_for_vsync(void) void wait_for_vsync(void)
{ {
// Temporary // Temporary
} }
void flush_screen() void flush_screen()
{ {
//SDL_UnlockSurface (prSDLScreen);
if (savestate_state == STATE_DOSAVE) if (savestate_state == STATE_DOSAVE)
{ {
@ -379,13 +390,19 @@ void flush_screen()
} }
} }
//start = read_processor_time();
//if(start < next_synctime && next_synctime - start > time_per_frame - 1000)
// usleep((next_synctime - start) - 1000);
//SDL_Flip(prSDLScreen);
if (need_wait_dispmanx_semaphore == 1) if (need_wait_dispmanx_semaphore == 1)
{ {
need_wait_dispmanx_semaphore = 0; need_wait_dispmanx_semaphore = 0;
start = read_processor_time(); start = read_processor_time();
uae_sem_wait(&vsync_wait_sem); uae_sem_wait(&vsync_wait_sem);
} }
if (current_resource_amigafb == 1) if (current_resource_amigafb == 1)
{ {
current_resource_amigafb = 0; current_resource_amigafb = 0;
@ -414,13 +431,13 @@ void flush_screen()
vc_dispmanx_update_submit(dispmanxupdate, vsync_callback, NULL); vc_dispmanx_update_submit(dispmanxupdate, vsync_callback, NULL);
} }
need_wait_dispmanx_semaphore = 1; need_wait_dispmanx_semaphore = 1;
init_row_map(); init_row_map();
} }
void black_screen_now(void) void black_screen_now(void)
{ {
SDL_FillRect(prSDLScreen, NULL, 0); SDL_FillRect(prSDLScreen, NULL, 0);
@ -428,6 +445,7 @@ void black_screen_now(void)
flush_screen(); flush_screen();
} }
static void graphics_subinit(void) static void graphics_subinit(void)
{ {
if (prSDLScreen == NULL) if (prSDLScreen == NULL)
@ -445,7 +463,7 @@ static void graphics_subinit(void)
STATIC_INLINE int bitsInMask(unsigned long mask) STATIC_INLINE int bitsInMask(unsigned long mask)
{ {
/* count bits in mask */ /* count bits in mask */
int n = 0; int n = 0;
while (mask) while (mask)
{ {
@ -455,9 +473,10 @@ STATIC_INLINE int bitsInMask(unsigned long mask)
return n; return n;
} }
STATIC_INLINE int maskShift(unsigned long mask) STATIC_INLINE int maskShift(unsigned long mask)
{ {
/* determine how far mask is shifted */ /* determine how far mask is shifted */
int n = 0; int n = 0;
while (!(mask & 1)) while (!(mask & 1))
{ {
@ -467,13 +486,14 @@ STATIC_INLINE int maskShift(unsigned long mask)
return n; return n;
} }
static int init_colors(void) static int init_colors(void)
{ {
int i; int i;
int red_bits, green_bits, blue_bits; int red_bits, green_bits, blue_bits;
int red_shift, green_shift, blue_shift; int red_shift, green_shift, blue_shift;
/* Truecolor: */ /* Truecolor: */
red_bits = bitsInMask(prSDLScreen->format->Rmask); red_bits = bitsInMask(prSDLScreen->format->Rmask);
green_bits = bitsInMask(prSDLScreen->format->Gmask); green_bits = bitsInMask(prSDLScreen->format->Gmask);
blue_bits = bitsInMask(prSDLScreen->format->Bmask); blue_bits = bitsInMask(prSDLScreen->format->Bmask);
@ -488,6 +508,7 @@ static int init_colors(void)
return 1; return 1;
} }
/* /*
* Find the colour depth of the display * Find the colour depth of the display
*/ */
@ -496,13 +517,12 @@ static int get_display_depth(void)
const SDL_VideoInfo *vid_info; const SDL_VideoInfo *vid_info;
int depth = 0; int depth = 0;
if ((vid_info = SDL_GetVideoInfo())) if ((vid_info = SDL_GetVideoInfo())) {
{
depth = vid_info->vfmt->BitsPerPixel; depth = vid_info->vfmt->BitsPerPixel;
/* Don't trust the answer if it's 16 bits; the display /* Don't trust the answer if it's 16 bits; the display
* could actually be 15 bits deep. We'll count the bits * could actually be 15 bits deep. We'll count the bits
* ourselves */ * ourselves */
if (depth == 16) if (depth == 16)
depth = bitsInMask(vid_info->vfmt->Rmask) + bitsInMask(vid_info->vfmt->Gmask) + bitsInMask(vid_info->vfmt->Bmask); depth = bitsInMask(vid_info->vfmt->Rmask) + bitsInMask(vid_info->vfmt->Gmask) + bitsInMask(vid_info->vfmt->Bmask);
} }
@ -515,13 +535,14 @@ int GetSurfacePixelFormat(void)
int unit = (depth + 1) & 0xF8; int unit = (depth + 1) & 0xF8;
return (unit == 8 ? RGBFB_CHUNKY return (unit == 8 ? RGBFB_CHUNKY
: depth == 15 && unit == 16 ? RGBFB_R5G5B5 : depth == 15 && unit == 16 ? RGBFB_R5G5B5
: depth == 16 && unit == 16 ? RGBFB_R5G6B5 : depth == 16 && unit == 16 ? RGBFB_R5G6B5
: unit == 24 ? RGBFB_B8G8R8 : unit == 24 ? RGBFB_B8G8R8
: unit == 32 ? RGBFB_R8G8B8A8 : unit == 32 ? RGBFB_R8G8B8A8
: RGBFB_NONE); : RGBFB_NONE);
} }
int graphics_init(bool mousecapture) int graphics_init(bool mousecapture)
{ {
int i, j; int i, j;
@ -530,12 +551,13 @@ int graphics_init(bool mousecapture)
graphics_subinit(); graphics_subinit();
if (!init_colors()) if (!init_colors())
return 0; return 0;
//buttonstate[0] = buttonstate[1] = buttonstate[2] = 0; //buttonstate[0] = buttonstate[1] = buttonstate[2] = 0;
//keyboard_init(); //keyboard_init();
return 1; return 1;
} }
@ -547,6 +569,7 @@ void graphics_leave(void)
SDL_VideoQuit(); SDL_VideoQuit();
} }
#define systemRedShift (prSDLScreen->format->Rshift) #define systemRedShift (prSDLScreen->format->Rshift)
#define systemGreenShift (prSDLScreen->format->Gshift) #define systemGreenShift (prSDLScreen->format->Gshift)
#define systemBlueShift (prSDLScreen->format->Bshift) #define systemBlueShift (prSDLScreen->format->Bshift)
@ -566,16 +589,14 @@ static int save_png(SDL_Surface* surface, char *path)
NULL, NULL,
NULL, NULL,
NULL); NULL);
if (!png_ptr) if (!png_ptr) {
{
fclose(f); fclose(f);
return 0; return 0;
} }
png_infop info_ptr = png_create_info_struct(png_ptr); png_infop info_ptr = png_create_info_struct(png_ptr);
if (!info_ptr) if (!info_ptr) {
{
png_destroy_write_struct(&png_ptr, NULL); png_destroy_write_struct(&png_ptr, NULL);
fclose(f); fclose(f);
return 0; return 0;
@ -603,14 +624,14 @@ static int save_png(SDL_Surface* surface, char *path)
int x; int x;
unsigned short *p = (unsigned short *)pix; unsigned short *p = (unsigned short *)pix;
for (y = 0; y < sizeY; y++) for (y = 0; y < sizeY; y++)
{ {
for (x = 0; x < sizeX; x++) for (x = 0; x < sizeX; x++)
{ {
unsigned short v = p[x]; unsigned short v = p[x];
*b++ = ((v & systemRedMask) >> systemRedShift) << 3; // R *b++ = ((v & systemRedMask) >> systemRedShift) << 3; // R
*b++ = ((v & systemGreenMask) >> systemGreenShift) << 2; // G *b++ = ((v & systemGreenMask) >> systemGreenShift) << 2; // G
*b++ = ((v & systemBlueMask) >> systemBlueShift) << 3; // B *b++ = ((v & systemBlueMask) >> systemBlueShift) << 3; // B
} }
p += surface->pitch / 2; p += surface->pitch / 2;
@ -626,6 +647,7 @@ static int save_png(SDL_Surface* surface, char *path)
return 1; return 1;
} }
static void CreateScreenshot(void) static void CreateScreenshot(void)
{ {
int w, h; int w, h;
@ -649,6 +671,7 @@ static void CreateScreenshot(void)
prSDLScreen->format->Amask); prSDLScreen->format->Amask);
} }
static int save_thumb(char *path) static int save_thumb(char *path)
{ {
int ret = 0; int ret = 0;
@ -661,114 +684,25 @@ static int save_thumb(char *path)
return ret; return ret;
} }
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 #ifdef PICASSO96
int picasso_palette(void) int picasso_palette(void)
{ {
int i, changed; int i, changed;
changed = 0; changed = 0;
for (i = 0; i < 256; i++) for (i = 0; i < 256; i++) {
{
int r = picasso96_state.CLUT[i].Red; int r = picasso96_state.CLUT[i].Red;
int g = picasso96_state.CLUT[i].Green; int g = picasso96_state.CLUT[i].Green;
int b = picasso96_state.CLUT[i].Blue; int b = picasso96_state.CLUT[i].Blue;
int value = (r << 16 | g << 8 | b); int value = (r << 16 | g << 8 | b);
uae_u32 v = CONVERT_RGB(value); uae_u32 v = CONVERT_RGB(value);
if (v != picasso_vidinfo.clut[i]) if (v != picasso_vidinfo.clut[i]) {
{
picasso_vidinfo.clut[i] = v; picasso_vidinfo.clut[i] = v;
changed = 1; changed = 1;
} }
} }
return changed; return changed;
} }
@ -794,10 +728,8 @@ static void sortmodes(void)
while (DisplayModes[i].depth >= 0) while (DisplayModes[i].depth >= 0)
i++; i++;
qsort(DisplayModes, i, sizeof(struct PicassoResolution), resolution_compare); qsort(DisplayModes, i, sizeof(struct PicassoResolution), resolution_compare);
for (i = 0; DisplayModes[i].depth >= 0; i++) for (i = 0; DisplayModes[i].depth >= 0; i++) {
{ if (DisplayModes[i].res.height != ph || DisplayModes[i].res.width != pw) {
if (DisplayModes[i].res.height != ph || DisplayModes[i].res.width != pw)
{
ph = DisplayModes[i].res.height; ph = DisplayModes[i].res.height;
pw = DisplayModes[i].res.width; pw = DisplayModes[i].res.width;
idx++; idx++;
@ -811,12 +743,10 @@ static void modesList(void)
int i, j; int i, j;
i = 0; i = 0;
while (DisplayModes[i].depth >= 0) while (DisplayModes[i].depth >= 0) {
{
write_log("%d: %s (", i, DisplayModes[i].name); write_log("%d: %s (", i, DisplayModes[i].name);
j = 0; j = 0;
while (DisplayModes[i].refresh[j] > 0) while (DisplayModes[i].refresh[j] > 0) {
{
if (j > 0) if (j > 0)
write_log(","); write_log(",");
write_log("%d", DisplayModes[i].refresh[j]); write_log("%d", DisplayModes[i].refresh[j]);
@ -834,7 +764,7 @@ void picasso_InitResolutions(void)
char tmp[200]; char tmp[200];
int bit_idx; int bit_idx;
int bits[] = { 8, 16, 32 }; int bits[] = { 8, 16, 32 };
Displays[0].primary = 1; Displays[0].primary = 1;
Displays[0].disabled = 0; Displays[0].disabled = 0;
Displays[0].rect.left = 0; Displays[0].rect.left = 0;
@ -847,17 +777,15 @@ void picasso_InitResolutions(void)
md1 = Displays; md1 = Displays;
DisplayModes = md1->DisplayModes = xmalloc(struct PicassoResolution, MAX_PICASSO_MODES); DisplayModes = md1->DisplayModes = xmalloc(struct PicassoResolution, MAX_PICASSO_MODES);
for (i = 0; i < MAX_SCREEN_MODES && count < MAX_PICASSO_MODES; i++) for (i = 0; i < MAX_SCREEN_MODES && count < MAX_PICASSO_MODES; i++) {
{ for (bit_idx = 0; bit_idx < 3; ++bit_idx) {
for (bit_idx = 0; bit_idx < 3; ++bit_idx)
{
int bitdepth = bits[bit_idx]; int bitdepth = bits[bit_idx];
int bit_unit = (bitdepth + 1) & 0xF8; int bit_unit = (bitdepth + 1) & 0xF8;
int rgbFormat = (bitdepth == 8 ? RGBFB_CLUT : (bitdepth == 16 ? RGBFB_R5G6B5 : RGBFB_R8G8B8A8)); int rgbFormat = (bitdepth == 8 ? RGBFB_CLUT : (bitdepth == 16 ? RGBFB_R5G6B5 : RGBFB_R8G8B8A8));
int pixelFormat = 1 << rgbFormat; int pixelFormat = 1 << rgbFormat;
pixelFormat |= RGBFF_CHUNKY; pixelFormat |= RGBFF_CHUNKY;
//if (SDL_VideoModeOK (x_size_table[i], y_size_table[i], 16, SDL_SWSURFACE)) //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.width = x_size_table[i];
DisplayModes[count].res.height = y_size_table[i]; DisplayModes[count].res.height = y_size_table[i];
@ -871,7 +799,7 @@ void picasso_InitResolutions(void)
DisplayModes[count].res.width, DisplayModes[count].res.width,
DisplayModes[count].res.height, DisplayModes[count].res.height,
DisplayModes[count].depth * 8); DisplayModes[count].depth * 8);
count++; count++;
} }
} }
@ -882,6 +810,74 @@ void picasso_InitResolutions(void)
DisplayModes = Displays[0].DisplayModes; 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) void gfx_set_picasso_state(int on)
{ {
if (on == screen_is_picasso) if (on == screen_is_picasso)
@ -896,9 +892,9 @@ void gfx_set_picasso_modeinfo(uae_u32 w, uae_u32 h, uae_u32 depth, RGBFTYPE rgbf
{ {
depth >>= 3; depth >>= 3;
if (((unsigned)picasso_vidinfo.width == w) && if (((unsigned)picasso_vidinfo.width == w) &&
((unsigned)picasso_vidinfo.height == h) && ((unsigned)picasso_vidinfo.height == h) &&
((unsigned)picasso_vidinfo.depth == depth) && ((unsigned)picasso_vidinfo.depth == depth) &&
(picasso_vidinfo.selected_rgbformat == rgbfmt)) (picasso_vidinfo.selected_rgbformat == rgbfmt))
return; return;
picasso_vidinfo.selected_rgbformat = rgbfmt; picasso_vidinfo.selected_rgbformat = rgbfmt;
@ -918,14 +914,14 @@ void gfx_set_picasso_modeinfo(uae_u32 w, uae_u32 h, uae_u32 depth, RGBFTYPE rgbf
uae_u8 *gfx_lock_picasso(void) uae_u8 *gfx_lock_picasso(void)
{ {
// We lock the surface directly after create and flip // We lock the surface directly after create and flip
picasso_vidinfo.rowbytes = prSDLScreen->pitch; picasso_vidinfo.rowbytes = prSDLScreen->pitch;
return (uae_u8 *)prSDLScreen->pixels; return (uae_u8 *)prSDLScreen->pixels;
} }
void gfx_unlock_picasso(void) void gfx_unlock_picasso(void)
{ {
// We lock the surface directly after create and flip, so no unlock here // We lock the surface directly after create and flip, so no unlock here
} }
#endif // PICASSO96 #endif // PICASSO96