giz dblbuff, scanline mode

git-svn-id: file:///home/notaz/opt/svn/PicoDrive@270 be3aeb3a-fb24-0410-a615-afba39da0efa
This commit is contained in:
notaz 2007-10-06 12:20:44 +00:00
parent 7eed09b34f
commit c77ca79e89
7 changed files with 63 additions and 34 deletions

View file

@ -132,11 +132,10 @@ graphics problems for some games, so it's best to use 16bit one.
#endif #endif
#ifdef GIZ #ifdef GIZ
@@0. "Interlaced rendering" @@0. "Scanline mode"
This option was designed to work around slow framebuffer access (the Gizmondo's This option was designed to work around slow framebuffer access (the Gizmondo's
main bottleneck) by drawing every other line (odd numbered lines during odd main bottleneck) by drawing every other line (even nummbered lines only).
numbered frames and even numbered lines during even frames). This improves This improves performance greatly, but looses detail.
performance greatly, but introduces artifacts for fast scrolling games.
#endif #endif
#ifdef GP2X #ifdef GP2X
@ -272,10 +271,14 @@ game to get sound. This is because most games initialize sound chips on
startup, and this data is lost when sound chips are being enabled/disabled. startup, and this data is lost when sound chips are being enabled/disabled.
#ifdef GIZ #ifdef GIZ
@@1. "Double buffering"
Draws the display to offscreen buffer, and flips it with visible one when done.
Unfortunately this causes serious tearing, unless v-sync is used (next option).
@@1. "Wait for V-sync" @@1. "Wait for V-sync"
Waits for vertical sync before drawing. This option doesn't eliminate tearing Waits for vertical sync before drawing (or flipping buffers, if previous option
problems, because full framebuffer update takes much more time then the blanking is enabled). Emulation is stopped while waiting, so this causes large performance
period lasts on Gizmondo.. hit.
#endif #endif
@@1. "gzip savestates" @@1. "gzip savestates"

View file

@ -8,7 +8,7 @@ typedef struct {
int EmuOpt; // LSb->MSb: use_sram, show_fps, enable_sound, gzip_saves, int EmuOpt; // LSb->MSb: use_sram, show_fps, enable_sound, gzip_saves,
// squidgehack, no_save_cfg_on_exit, <unused>, 16_bit_mode // squidgehack, no_save_cfg_on_exit, <unused>, 16_bit_mode
// craigix_ram, confirm_save, show_cd_leds, confirm_load // craigix_ram, confirm_save, show_cd_leds, confirm_load
// A_SNs_gamma, perfect_vsync, interlace // A_SNs_gamma, perfect_vsync, giz_scanlines, giz_dblbuff
int PicoOpt; // used for config saving only, see Pico.h int PicoOpt; // used for config saving only, see Pico.h
int PsndRate; // ditto int PsndRate; // ditto
int PicoRegion; // ditto int PicoRegion; // ditto

View file

@ -53,6 +53,7 @@ typedef enum
MA_OPT_INTERLACED, /* giz */ MA_OPT_INTERLACED, /* giz */
MA_OPT2_GAMMA, MA_OPT2_GAMMA,
MA_OPT2_A_SN_GAMMA, MA_OPT2_A_SN_GAMMA,
MA_OPT2_DBLBUFF, /* giz */
MA_OPT2_VSYNC, MA_OPT2_VSYNC,
MA_OPT2_ENABLE_Z80, MA_OPT2_ENABLE_Z80,
MA_OPT2_ENABLE_YM2612, MA_OPT2_ENABLE_YM2612,

View file

@ -52,8 +52,8 @@ void emu_getMainDir(char *dst, int len)
static void emu_msg_cb(const char *msg) static void emu_msg_cb(const char *msg)
{ {
if (giz_screen == NULL) if (giz_screen != NULL) Framework2D_UnlockBuffer();
giz_screen = Framework2D_LockBuffer(); giz_screen = Framework2D_LockBuffer(1);
memset32((int *)((char *)giz_screen + 321*232*2), 0, 321*8*2/4); memset32((int *)((char *)giz_screen + 321*232*2), 0, 321*8*2/4);
emu_textOut16(4, 232, msg); emu_textOut16(4, 232, msg);
@ -61,12 +61,15 @@ static void emu_msg_cb(const char *msg)
/* assumption: emu_msg_cb gets called only when something slow is about to happen */ /* assumption: emu_msg_cb gets called only when something slow is about to happen */
reset_timing = 1; reset_timing = 1;
Framework2D_UnlockBuffer();
giz_screen = Framework2D_LockBuffer((currentConfig.EmuOpt&0x8000) ? 0 : 1);
} }
static void emu_state_cb(const char *str) void emu_stateCb(const char *str)
{ {
if (giz_screen == NULL) if (giz_screen != NULL) Framework2D_UnlockBuffer();
giz_screen = Framework2D_LockBuffer(); giz_screen = Framework2D_LockBuffer(1);
clearArea(0); clearArea(0);
blit("", str); blit("", str);
@ -157,7 +160,7 @@ static int EmuScan16(unsigned int num, void *sdata)
if (!(Pico.video.reg[1]&8)) num += 8; if (!(Pico.video.reg[1]&8)) num += 8;
DrawLineDest = (unsigned short *) giz_screen + 321*(num+1); DrawLineDest = (unsigned short *) giz_screen + 321*(num+1);
if ((currentConfig.EmuOpt&0x4000) && (num&1) == (Pico.m.frame_count&1)) if ((currentConfig.EmuOpt&0x4000) && (num&1) == 0) // (Pico.m.frame_count&1))
return 1; // skip next line return 1; // skip next line
return 0; return 0;
@ -224,7 +227,7 @@ static void blit(const char *fps, const char *notice)
} }
if (!(Pico.video.reg[12]&1)) lines_flags|=0x10000; if (!(Pico.video.reg[12]&1)) lines_flags|=0x10000;
if (currentConfig.EmuOpt&0x4000) if (currentConfig.EmuOpt&0x4000)
lines_flags|=(Pico.m.frame_count&1)?0x20000:0x40000; lines_flags|=0x40000; // (Pico.m.frame_count&1)?0x20000:0x40000;
vidCpy8to16((unsigned short *)giz_screen+321*8, PicoDraw2FB+328*8, localPal, lines_flags); vidCpy8to16((unsigned short *)giz_screen+321*8, PicoDraw2FB+328*8, localPal, lines_flags);
} }
else if (!(emu_opt&0x80)) else if (!(emu_opt&0x80))
@ -252,7 +255,7 @@ static void blit(const char *fps, const char *notice)
lines_flags = (Pico.video.reg[1]&8) ? 240 : 224; lines_flags = (Pico.video.reg[1]&8) ? 240 : 224;
if (!(Pico.video.reg[12]&1)) lines_flags|=0x10000; if (!(Pico.video.reg[12]&1)) lines_flags|=0x10000;
if (currentConfig.EmuOpt&0x4000) if (currentConfig.EmuOpt&0x4000)
lines_flags|=(Pico.m.frame_count&1)?0x20000:0x40000; lines_flags|=0x40000; // (Pico.m.frame_count&1)?0x20000:0x40000;
vidCpy8to16((unsigned short *)giz_screen+321*8, PicoDraw2FB+328*8, localPal, lines_flags); vidCpy8to16((unsigned short *)giz_screen+321*8, PicoDraw2FB+328*8, localPal, lines_flags);
} }
@ -270,14 +273,21 @@ static void blit(const char *fps, const char *notice)
static void clearArea(int full) static void clearArea(int full)
{ {
if (giz_screen == NULL) if (giz_screen == NULL)
giz_screen = Framework2D_LockBuffer(); giz_screen = Framework2D_LockBuffer(1);
if (full) memset32(giz_screen, 0, 320*240*2/4); if (full) memset32(giz_screen, 0, 320*240*2/4);
else memset32((int *)((char *)giz_screen + 321*232*2), 0, 321*8*2/4); else memset32((int *)((char *)giz_screen + 321*232*2), 0, 321*8*2/4);
if (currentConfig.EmuOpt&0x8000) {
Framework2D_UnlockBuffer();
giz_screen = Framework2D_LockBuffer(0);
if (full) memset32(giz_screen, 0, 320*240*2/4);
else memset32((int *)((char *)giz_screen + 321*232*2), 0, 321*8*2/4);
}
} }
static void vidResetMode(void) static void vidResetMode(void)
{ {
giz_screen = Framework2D_LockBuffer(); giz_screen = Framework2D_LockBuffer(1);
if (PicoOpt&0x10) { if (PicoOpt&0x10) {
} else if (currentConfig.EmuOpt&0x80) { } else if (currentConfig.EmuOpt&0x80) {
@ -297,6 +307,11 @@ static void vidResetMode(void)
Pico.m.dirtyPal = 1; Pico.m.dirtyPal = 1;
memset32(giz_screen, 0, 321*240*2/4); memset32(giz_screen, 0, 321*240*2/4);
if (currentConfig.EmuOpt&0x8000) {
Framework2D_UnlockBuffer();
giz_screen = Framework2D_LockBuffer(0);
memset32(giz_screen, 0, 321*240*2/4);
}
Framework2D_UnlockBuffer(); Framework2D_UnlockBuffer();
giz_screen = NULL; giz_screen = NULL;
} }
@ -339,6 +354,7 @@ static void SkipFrame(void)
PicoSkipFrame=0; PicoSkipFrame=0;
} }
/* forced frame to front buffer */
void emu_forcedFrame(void) void emu_forcedFrame(void)
{ {
int po_old = PicoOpt; int po_old = PicoOpt;
@ -349,7 +365,7 @@ void emu_forcedFrame(void)
currentConfig.EmuOpt |= 0x80; currentConfig.EmuOpt |= 0x80;
if (giz_screen == NULL) if (giz_screen == NULL)
giz_screen = Framework2D_LockBuffer(); giz_screen = Framework2D_LockBuffer(1);
PicoDrawSetColorFormat(1); PicoDrawSetColorFormat(1);
PicoScan = EmuScan16; PicoScan = EmuScan16;
@ -374,7 +390,7 @@ static void RunEvents(unsigned int which)
if (PsndOut != NULL) if (PsndOut != NULL)
FrameworkAudio_SetPause(1); FrameworkAudio_SetPause(1);
if (giz_screen == NULL) if (giz_screen == NULL)
giz_screen = Framework2D_LockBuffer(); giz_screen = Framework2D_LockBuffer(1);
if ( emu_checkSaveFile(state_slot) && if ( emu_checkSaveFile(state_slot) &&
(( (which & 0x1000) && (currentConfig.EmuOpt & 0x800)) || // load (( (which & 0x1000) && (currentConfig.EmuOpt & 0x800)) || // load
(!(which & 0x1000) && (currentConfig.EmuOpt & 0x200))) ) // save (!(which & 0x1000) && (currentConfig.EmuOpt & 0x200))) ) // save
@ -392,7 +408,7 @@ static void RunEvents(unsigned int which)
if (do_it) if (do_it)
{ {
osd_text(4, 232, (which & 0x1000) ? "LOADING GAME" : "SAVING GAME"); osd_text(4, 232, (which & 0x1000) ? "LOADING GAME" : "SAVING GAME");
PicoStateProgressCB = emu_state_cb; PicoStateProgressCB = emu_stateCb;
emu_SaveLoadGame((which & 0x1000) >> 12, 0); emu_SaveLoadGame((which & 0x1000) >> 12, 0);
PicoStateProgressCB = NULL; PicoStateProgressCB = NULL;
Sleep(0); Sleep(0);
@ -735,18 +751,17 @@ void emu_Loop(void)
updateKeys(); updateKeys();
if (giz_screen == NULL && (currentConfig.EmuOpt&0x80)) if (currentConfig.EmuOpt&0x80)
giz_screen = Framework2D_LockBuffer(); /* be sure correct framebuffer is locked */
giz_screen = Framework2D_LockBuffer((currentConfig.EmuOpt&0x8000) ? 0 : 1);
if (!(PicoOpt&0x10)) if (!(PicoOpt&0x10))
PicoScan((unsigned) -1, NULL); PicoScan((unsigned) -1, NULL);
PicoFrame(); PicoFrame();
if (currentConfig.EmuOpt&0x2000)
Framework2D_WaitVSync();
if (giz_screen == NULL) if (giz_screen == NULL)
giz_screen = Framework2D_LockBuffer(); giz_screen = Framework2D_LockBuffer((currentConfig.EmuOpt&0x8000) ? 0 : 1);
blit(fpsbuff, notice); blit(fpsbuff, notice);
@ -755,6 +770,12 @@ void emu_Loop(void)
giz_screen = NULL; giz_screen = NULL;
} }
if (currentConfig.EmuOpt&0x2000)
Framework2D_WaitVSync();
if (currentConfig.EmuOpt&0x8000)
Framework2D_Flip();
// check time // check time
tval = GetTickCount(); tval = GetTickCount();
tval_diff = (int)(tval - tval_thissec) << 8; tval_diff = (int)(tval - tval_thissec) << 8;
@ -784,7 +805,7 @@ void emu_Loop(void)
// save SRAM // save SRAM
if ((currentConfig.EmuOpt & 1) && SRam.changed) { if ((currentConfig.EmuOpt & 1) && SRam.changed) {
emu_state_cb("Writing SRAM/BRAM.."); emu_stateCb("Writing SRAM/BRAM..");
emu_SaveLoadGame(0, 1); emu_SaveLoadGame(0, 1);
SRam.changed = 0; SRam.changed = 0;
} }

View file

@ -27,3 +27,5 @@ void emu_Loop(void);
void emu_ResetGame(void); void emu_ResetGame(void);
void emu_forcedFrame(void); void emu_forcedFrame(void);
void emu_stateCb(const char *str);

View file

@ -60,7 +60,7 @@ void giz_init(HINSTANCE hInstance, HINSTANCE hPrevInstance)
} }
// test screen // test screen
giz_screen = Framework2D_LockBuffer(); giz_screen = Framework2D_LockBuffer(1);
if (giz_screen == NULL) if (giz_screen == NULL)
{ {
lprintf_al("Framework2D_LockBuffer() failed\n"); lprintf_al("Framework2D_LockBuffer() failed\n");

View file

@ -92,8 +92,7 @@ static void menu_draw_begin(int use_bgbuff)
static void menu_draw_end(void) static void menu_draw_end(void)
{ {
Framework2D_WaitVSync(); giz_screen = Framework2D_LockBuffer(0);
giz_screen = Framework2D_LockBuffer();
if (giz_screen == NULL) if (giz_screen == NULL)
{ {
lprintf_al("%s: Framework2D_LockBuffer() returned NULL\n", __FUNCTION__); lprintf_al("%s: Framework2D_LockBuffer() returned NULL\n", __FUNCTION__);
@ -102,6 +101,7 @@ static void menu_draw_end(void)
memcpy32(giz_screen, (int *)menu_screen, 321*240*2/4); memcpy32(giz_screen, (int *)menu_screen, 321*240*2/4);
Framework2D_UnlockBuffer(); Framework2D_UnlockBuffer();
giz_screen = NULL; giz_screen = NULL;
Framework2D_Flip(1);
} }
@ -635,6 +635,7 @@ static int savestate_menu_loop(int is_loading)
if(inp & BTN_PLAY) { // save/load if(inp & BTN_PLAY) { // save/load
if (menu_sel < 10) { if (menu_sel < 10) {
state_slot = menu_sel; state_slot = menu_sel;
PicoStateProgressCB = emu_stateCb; /* also suitable for menu */
if (emu_SaveLoadGame(is_loading, 0)) { if (emu_SaveLoadGame(is_loading, 0)) {
strcpy(menuErrorMsg, is_loading ? "Load failed" : "Save failed"); strcpy(menuErrorMsg, is_loading ? "Load failed" : "Save failed");
return 1; return 1;
@ -991,6 +992,7 @@ menu_entry opt2_entries[] =
{ "Emulate Z80", MB_ONOFF, MA_OPT2_ENABLE_Z80, &currentConfig.PicoOpt,0x0004, 0, 0, 1 }, { "Emulate Z80", MB_ONOFF, MA_OPT2_ENABLE_Z80, &currentConfig.PicoOpt,0x0004, 0, 0, 1 },
{ "Emulate YM2612 (FM)", MB_ONOFF, MA_OPT2_ENABLE_YM2612, &currentConfig.PicoOpt,0x0001, 0, 0, 1 }, { "Emulate YM2612 (FM)", MB_ONOFF, MA_OPT2_ENABLE_YM2612, &currentConfig.PicoOpt,0x0001, 0, 0, 1 },
{ "Emulate SN76496 (PSG)", MB_ONOFF, MA_OPT2_ENABLE_SN76496,&currentConfig.PicoOpt,0x0002, 0, 0, 1 }, { "Emulate SN76496 (PSG)", MB_ONOFF, MA_OPT2_ENABLE_SN76496,&currentConfig.PicoOpt,0x0002, 0, 0, 1 },
{ "Double buffering", MB_ONOFF, MA_OPT2_DBLBUFF, &currentConfig.EmuOpt, 0x8000, 0, 0, 1 },
{ "Wait for V-sync (slow)", MB_ONOFF, MA_OPT2_VSYNC, &currentConfig.EmuOpt, 0x2000, 0, 0, 1 }, { "Wait for V-sync (slow)", MB_ONOFF, MA_OPT2_VSYNC, &currentConfig.EmuOpt, 0x2000, 0, 0, 1 },
{ "gzip savestates", MB_ONOFF, MA_OPT2_GZIP_STATES, &currentConfig.EmuOpt, 0x0008, 0, 0, 1 }, { "gzip savestates", MB_ONOFF, MA_OPT2_GZIP_STATES, &currentConfig.EmuOpt, 0x0008, 0, 0, 1 },
{ "Don't save last used ROM", MB_ONOFF, MA_OPT2_NO_LAST_ROM, &currentConfig.EmuOpt, 0x0020, 0, 0, 1 }, { "Don't save last used ROM", MB_ONOFF, MA_OPT2_NO_LAST_ROM, &currentConfig.EmuOpt, 0x0020, 0, 0, 1 },
@ -1057,7 +1059,7 @@ static void amenu_loop_options(void)
menu_entry opt_entries[] = menu_entry opt_entries[] =
{ {
{ NULL, MB_NONE, MA_OPT_RENDERER, NULL, 0, 0, 0, 1 }, { NULL, MB_NONE, MA_OPT_RENDERER, NULL, 0, 0, 0, 1 },
{ "Interlaced rend. (faster)", MB_ONOFF, MA_OPT_INTERLACED, &currentConfig.EmuOpt, 0x4000, 0, 0, 1 }, { "Scanline mode (faster)", MB_ONOFF, MA_OPT_INTERLACED, &currentConfig.EmuOpt, 0x4000, 0, 0, 1 },
{ "Scale low res mode", MB_ONOFF, MA_OPT_SCALING, &currentConfig.scaling, 0x0001, 0, 3, 1 }, { "Scale low res mode", MB_ONOFF, MA_OPT_SCALING, &currentConfig.scaling, 0x0001, 0, 3, 1 },
{ "Accurate timing (slower)", MB_ONOFF, MA_OPT_ACC_TIMING, &currentConfig.PicoOpt, 0x0040, 0, 0, 1 }, { "Accurate timing (slower)", MB_ONOFF, MA_OPT_ACC_TIMING, &currentConfig.PicoOpt, 0x0040, 0, 0, 1 },
{ "Accurate sprites (slower)", MB_ONOFF, MA_OPT_ACC_SPRITES, &currentConfig.PicoOpt, 0x0080, 0, 0, 1 }, { "Accurate sprites (slower)", MB_ONOFF, MA_OPT_ACC_SPRITES, &currentConfig.PicoOpt, 0x0080, 0, 0, 1 },
@ -1562,7 +1564,7 @@ static void menu_prepare_bg(int use_game_bg)
{ {
// darken the active framebuffer // darken the active framebuffer
if (giz_screen == NULL) if (giz_screen == NULL)
giz_screen = Framework2D_LockBuffer(); giz_screen = Framework2D_LockBuffer(1);
memset(bg_buffer, 0, 321*8*2); memset(bg_buffer, 0, 321*8*2);
menu_darken_bg(bg_buffer + 321*8*2, (char *)giz_screen + 321*8*2, 321*224, 1); menu_darken_bg(bg_buffer + 321*8*2, (char *)giz_screen + 321*8*2, 321*224, 1);
memset(bg_buffer + 321*232*2, 0, 321*8*2); memset(bg_buffer + 321*232*2, 0, 321*8*2);