2015-04-26 22:10:42 +02:00
# ifdef __WIN32__
# include <windows.h>
# else
# define MessageBox(owner, text, caption, type) printf("%s: %s\n", caption, text)
# endif
# include "SDL.h"
# include "SDL_thread.h"
# include "shared.h"
# include "sms_ntsc.h"
# include "md_ntsc.h"
# include "utils.h"
# ifdef GCWZERO
# include <SDL_ttf.h>
# include <SDL_image.h>
# include <time.h>
static int do_once = 1 ;
static int gcw0_w = 320 ;
static int gcw0_h = 240 ;
static int gotomenu ;
static int show_lightgun ;
time_t current_time ;
const char * cursor [ 4 ] =
{
" ./CLASSIC_01_RED.png " , //doesn't flash (for epileptics it's default)
" ./CLASSIC_02.png " , //square flashing red and white
" ./CLASSIC_01.png " ,
" ./SQUARE_02.png " ,
} ;
# define JOY_DEADZONE 1000
# endif
# ifdef GCWZERO
# define SOUND_FREQUENCY 44100
# else
# define SOUND_FREQUENCY 48000
# endif
# define SOUND_SAMPLES_SIZE 2048
# define VIDEO_WIDTH 320
# define VIDEO_HEIGHT 240
int joynum = 0 ;
int log_error = 0 ;
int debug_on = 0 ;
int turbo_mode = 0 ;
int use_sound = 1 ;
int fullscreen = 1 ; /* SDL_FULLSCREEN */
char rom_filename [ 256 ] ;
/* sound */
struct
{
char * current_pos ;
char * buffer ;
int current_emulated_samples ;
} sdl_sound ;
static uint8 brm_format [ 0x40 ] =
{
0x5f , 0x5f , 0x5f , 0x5f , 0x5f , 0x5f , 0x5f , 0x5f , 0x5f , 0x5f , 0x5f , 0x00 , 0x00 , 0x00 , 0x00 , 0x40 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x53 , 0x45 , 0x47 , 0x41 , 0x5f , 0x43 , 0x44 , 0x5f , 0x52 , 0x4f , 0x4d , 0x00 , 0x01 , 0x00 , 0x00 , 0x00 ,
0x52 , 0x41 , 0x4d , 0x5f , 0x43 , 0x41 , 0x52 , 0x54 , 0x52 , 0x49 , 0x44 , 0x47 , 0x45 , 0x5f , 0x5f , 0x5f
} ;
static short soundframe [ SOUND_SAMPLES_SIZE ] ;
static void sdl_sound_callback ( void * userdata , Uint8 * stream , int len )
{
if ( sdl_sound . current_emulated_samples < len )
{
memset ( stream , 0 , len ) ;
}
else
{
memcpy ( stream , sdl_sound . buffer , len ) ;
/* loop to compensate desync */
do
{
sdl_sound . current_emulated_samples - = len ;
}
while ( sdl_sound . current_emulated_samples > 2 * len ) ;
memcpy ( sdl_sound . buffer ,
sdl_sound . current_pos - sdl_sound . current_emulated_samples ,
sdl_sound . current_emulated_samples ) ;
sdl_sound . current_pos = sdl_sound . buffer + sdl_sound . current_emulated_samples ;
}
}
static int sdl_sound_init ( )
{
int n ;
SDL_AudioSpec as_desired , as_obtained ;
if ( SDL_Init ( SDL_INIT_AUDIO ) < 0 )
{
MessageBox ( NULL , " SDL Audio initialization failed " , " Error " , 0 ) ;
return 0 ;
}
as_desired . freq = SOUND_FREQUENCY ;
as_desired . format = AUDIO_S16LSB ;
as_desired . channels = 2 ;
as_desired . samples = SOUND_SAMPLES_SIZE ;
as_desired . callback = sdl_sound_callback ;
if ( SDL_OpenAudio ( & as_desired , & as_obtained ) = = - 1 )
{
MessageBox ( NULL , " SDL Audio open failed " , " Error " , 0 ) ;
return 0 ;
}
if ( as_desired . samples ! = as_obtained . samples )
{
MessageBox ( NULL , " SDL Audio wrong setup " , " Error " , 0 ) ;
return 0 ;
}
sdl_sound . current_emulated_samples = 0 ;
n = SOUND_SAMPLES_SIZE * 2 * sizeof ( short ) * 20 ;
sdl_sound . buffer = ( char * ) malloc ( n ) ;
if ( ! sdl_sound . buffer )
{
MessageBox ( NULL , " Can't allocate audio buffer " , " Error " , 0 ) ;
return 0 ;
}
memset ( sdl_sound . buffer , 0 , n ) ;
sdl_sound . current_pos = sdl_sound . buffer ;
return 1 ;
}
static void sdl_sound_update ( enabled )
{
int size = audio_update ( soundframe ) * 2 ;
if ( enabled )
{
int i ;
short * out ;
SDL_LockAudio ( ) ;
out = ( short * ) sdl_sound . current_pos ;
for ( i = 0 ; i < size ; i + + )
{
* out + + = soundframe [ i ] ;
}
sdl_sound . current_pos = ( char * ) out ;
sdl_sound . current_emulated_samples + = size * sizeof ( short ) ;
SDL_UnlockAudio ( ) ;
}
}
static void sdl_sound_close ( )
{
SDL_PauseAudio ( 1 ) ;
SDL_CloseAudio ( ) ;
if ( sdl_sound . buffer )
free ( sdl_sound . buffer ) ;
}
# ifdef GCWZERO //A-stick support
static void sdl_joystick_init ( )
{
if ( SDL_Init ( SDL_INIT_JOYSTICK ) < 0 )
{
MessageBox ( NULL , " SDL Joystick initialization failed " , " Error " , 0 ) ;
return 0 ;
}
else
MessageBox ( NULL , " SDL Joystick initialisation successful " , " Success " , 0 ) ;
return 1 ;
}
# endif
/* video */
md_ntsc_t * md_ntsc ;
sms_ntsc_t * sms_ntsc ;
struct
{
SDL_Surface * surf_screen ;
SDL_Surface * surf_bitmap ;
SDL_Rect srect ;
SDL_Rect drect ;
Uint32 frames_rendered ;
} sdl_video ;
static int sdl_video_init ( )
{
if ( SDL_InitSubSystem ( SDL_INIT_VIDEO ) < 0 )
{
MessageBox ( NULL , " SDL Video initialization failed " , " Error " , 0 ) ;
return ;
}
# ifdef GCWZERO
sdl_video . surf_screen = SDL_SetVideoMode ( VIDEO_WIDTH , VIDEO_HEIGHT , 16 , SDL_HWSURFACE |
# else
sdl_video . surf_screen = SDL_SetVideoMode ( VIDEO_WIDTH , VIDEO_HEIGHT , 16 , SDL_HWSURFACE | fullscreen |
# endif
# ifdef SDL_TRIPLEBUF
SDL_TRIPLEBUF
# else
SDL_DOUBLEBUF
# endif
) ;
sdl_video . surf_bitmap = SDL_CreateRGBSurface ( SDL_HWSURFACE , 720 , 576 , 16 , 0 , 0 , 0 , 0 ) ;
sdl_video . frames_rendered = 0 ;
SDL_ShowCursor ( 0 ) ;
return ;
}
static void sdl_video_update ( )
{
static int test ;
if ( system_hw = = SYSTEM_MCD )
{
# ifdef GCWZERO
if ( test > = config . gcw0_frameskip ) // >= in case frameskip has just been lowered
{
system_frame_scd ( 0 ) ; //render frame
test = 0 ;
} else {
system_frame_scd ( 1 ) ; //skip frame render
test + + ;
}
# else
system_frame_scd ( 0 ) ;
# endif
}
else if ( ( system_hw & SYSTEM_PBC ) = = SYSTEM_MD )
# ifdef GCWZERO
{
if ( test > = config . gcw0_frameskip )
{
system_frame_gen ( 0 ) ;
test = 0 ;
} else {
system_frame_gen ( 1 ) ;
test + + ;
}
# else
system_frame_gen ( 0 ) ;
# endif
}
else
{
# ifdef GCWZERO
if ( test > = config . gcw0_frameskip )
{
system_frame_sms ( 0 ) ;
test = 0 ;
} else {
system_frame_sms ( 1 ) ;
test + + ;
}
# else
system_frame_sms ( 0 ) ;
# endif
}
/* viewport size changed */
if ( bitmap . viewport . changed & 1 )
{
bitmap . viewport . changed & = ~ 1 ;
/* source bitmap */
# ifdef GCWZERO //remove left bar bug with SMS roms
if ( ( system_hw = = SYSTEM_MARKIII ) | | ( system_hw = = SYSTEM_SMS ) | | ( system_hw = = SYSTEM_SMS2 ) | | ( system_hw = = SYSTEM_PBC ) )
{
if ( config . smsmaskleftbar )
sdl_video . srect . x = 8 ;
else
sdl_video . srect . x = 0 ;
}
else
{
sdl_video . srect . x = 0 ;
}
# else
sdl_video . srect . x = 0 ;
# endif
sdl_video . srect . y = 0 ;
sdl_video . srect . w = bitmap . viewport . w + 2 * bitmap . viewport . x ;
sdl_video . srect . h = bitmap . viewport . h + 2 * bitmap . viewport . y ;
if ( sdl_video . srect . w > VIDEO_WIDTH )
{
# ifdef GCWZERO
if ( ( system_hw = = SYSTEM_MARKIII ) | | ( system_hw = = SYSTEM_SMS ) | | ( system_hw = = SYSTEM_SMS2 ) | | ( system_hw = = SYSTEM_PBC ) )
{
if ( config . smsmaskleftbar )
sdl_video . srect . x = ( sdl_video . srect . w - VIDEO_WIDTH ) / 2 + 8 ;
else
sdl_video . srect . x = ( sdl_video . srect . w - VIDEO_WIDTH ) / 2 ;
sdl_video . srect . w = VIDEO_WIDTH ;
}
else
{
sdl_video . srect . x = ( sdl_video . srect . w - VIDEO_WIDTH ) / 2 ;
sdl_video . srect . w = VIDEO_WIDTH ;
}
# else
sdl_video . srect . x = ( sdl_video . srect . w - VIDEO_WIDTH ) / 2 ;
sdl_video . srect . w = VIDEO_WIDTH ;
# endif
}
if ( sdl_video . srect . h > VIDEO_HEIGHT )
{
sdl_video . srect . y = ( sdl_video . srect . h - VIDEO_HEIGHT ) / 2 ;
sdl_video . srect . h = VIDEO_HEIGHT ;
}
/* destination bitmap */
sdl_video . drect . w = sdl_video . srect . w ;
sdl_video . drect . h = sdl_video . srect . h ;
sdl_video . drect . x = ( VIDEO_WIDTH - sdl_video . drect . w ) / 2 ;
sdl_video . drect . y = ( VIDEO_HEIGHT - sdl_video . drect . h ) / 2 ;
/* clear destination surface */
SDL_FillRect ( sdl_video . surf_screen , 0 , 0 ) ;
# ifdef GCWZERO //triple buffering so stop flicker
SDL_Flip ( sdl_video . surf_screen ) ;
SDL_FillRect ( sdl_video . surf_screen , 0 , 0 ) ;
SDL_Flip ( sdl_video . surf_screen ) ;
SDL_FillRect ( sdl_video . surf_screen , 0 , 0 ) ;
# endif
#if 0
if ( config . render & & ( interlaced | | config . ntsc ) ) rect . h * = 2 ;
if ( config . ntsc ) rect . w = ( reg [ 12 ] & 1 ) ? MD_NTSC_OUT_WIDTH ( rect . w ) : SMS_NTSC_OUT_WIDTH ( rect . w ) ;
if ( config . ntsc )
{
sms_ntsc = ( sms_ntsc_t * ) malloc ( sizeof ( sms_ntsc_t ) ) ;
md_ntsc = ( md_ntsc_t * ) malloc ( sizeof ( md_ntsc_t ) ) ;
switch ( config . ntsc )
{
case 1 :
sms_ntsc_init ( sms_ntsc , & sms_ntsc_composite ) ;
md_ntsc_init ( md_ntsc , & md_ntsc_composite ) ;
break ;
case 2 :
sms_ntsc_init ( sms_ntsc , & sms_ntsc_svideo ) ;
md_ntsc_init ( md_ntsc , & md_ntsc_svideo ) ;
break ;
case 3 :
sms_ntsc_init ( sms_ntsc , & sms_ntsc_rgb ) ;
md_ntsc_init ( md_ntsc , & md_ntsc_rgb ) ;
break ;
}
}
else
{
if ( sms_ntsc )
{
free ( sms_ntsc ) ;
sms_ntsc = NULL ;
}
if ( md_ntsc )
{
free ( md_ntsc ) ;
md_ntsc = NULL ;
}
}
# endif
}
//DK IPU scaling for gg/sms roms
# ifdef GCWZERO
if ( config . gcw0_fullscreen )
{
if ( ( gcw0_w ! = sdl_video . drect . w ) | | ( gcw0_h ! = sdl_video . drect . h ) )
{
if ( ( system_hw = = SYSTEM_MARKIII ) | | ( system_hw = = SYSTEM_SMS ) | | ( system_hw = = SYSTEM_SMS2 ) | | ( system_hw = = SYSTEM_PBC ) )
{
if ( config . smsmaskleftbar )
{
sdl_video . srect . w = sdl_video . srect . w - 8 ;
sdl_video . drect . w = sdl_video . srect . w ;
sdl_video . drect . x = 4 ;
}
else
{
sdl_video . srect . w = sdl_video . srect . w ;
sdl_video . drect . w = sdl_video . srect . w ;
sdl_video . drect . x = 0 ;
}
}
else
{
sdl_video . drect . x = 0 ;
sdl_video . drect . w = sdl_video . srect . w ;
}
sdl_video . drect . h = sdl_video . srect . h ;
sdl_video . drect . y = 0 ;
gcw0_w = sdl_video . drect . w ;
gcw0_h = sdl_video . drect . h ;
if ( ( system_hw = = SYSTEM_MARKIII ) | | ( system_hw = = SYSTEM_SMS ) | | ( system_hw = = SYSTEM_SMS2 ) | | ( system_hw = = SYSTEM_PBC ) )
{
sdl_video . surf_screen = SDL_SetVideoMode ( 256 , gcw0_h , 16 , SDL_HWSURFACE |
# ifdef SDL_TRIPLEBUF
SDL_TRIPLEBUF ) ;
# else
SDL_DOUBLEBUF ) ;
# endif
}
else
{
sdl_video . surf_screen = SDL_SetVideoMode ( gcw0_w , gcw0_h , 16 , SDL_HWSURFACE |
# ifdef SDL_TRIPLEBUF
SDL_TRIPLEBUF ) ;
# else
SDL_DOUBLEBUF ) ;
# endif
}
}
}
if ( show_lightgun & & ! config . gcw0_fullscreen ) // hack to remove cursor corruption of over game screen edge
{
SDL_FillRect ( sdl_video . surf_screen , 0 , 0 ) ;
}
# endif
SDL_BlitSurface ( sdl_video . surf_bitmap , & sdl_video . srect , sdl_video . surf_screen , & sdl_video . drect ) ;
//SDL_UpdateRect(sdl_video.surf_screen, 0, 0, 0, 0);
# ifdef GCWZERO
// Add scanlines to Game Gear games if requested
if ( ( system_hw = = SYSTEM_GG ) & & config . gg_scanlines )
{
SDL_Surface * scanlinesSurface ;
scanlinesSurface = IMG_Load ( " ./scanlines.png " ) ;
SDL_BlitSurface ( scanlinesSurface , NULL , sdl_video . surf_screen , & sdl_video . drect ) ;
SDL_FreeSurface ( scanlinesSurface ) ;
}
if ( show_lightgun )
{
// Remove previous cursor from black bars
if ( config . gcw0_fullscreen )
{
if ( config . smsmaskleftbar )
{
if ( system_hw = = SYSTEM_SMS2 )
{
SDL_Rect srect ;
srect . x = 0 ;
srect . y = 0 ;
srect . w = 4 ;
srect . h = 192 ;
SDL_FillRect ( sdl_video . surf_screen , & srect , SDL_MapRGB ( sdl_video . surf_screen - > format , 0 , 0 , 0 ) ) ;
srect . x = 252 ;
SDL_FillRect ( sdl_video . surf_screen , & srect , SDL_MapRGB ( sdl_video . surf_screen - > format , 0 , 0 , 0 ) ) ;
}
}
}
/* get mouse coordinates (absolute values) */
int x , y ;
int state = SDL_GetMouseState ( & x , & y ) ;
SDL_Rect lrect ;
lrect . x = x - 7 ;
lrect . y = y - 7 ;
lrect . w = 15 ;
lrect . h = 15 ;
SDL_Surface * lightgunSurface ;
lightgunSurface = IMG_Load ( cursor [ config . cursor ] ) ;
static lightgun_af = 0 ;
SDL_Rect srect ;
srect . y = 0 ;
srect . w = 15 ;
srect . h = 15 ;
//only show cursor if movement occurred within 3 seconds.
time_t current_time2 ;
current_time2 = time ( NULL ) ;
if ( lightgun_af > = 10 )
{
srect . x = 0 ;
if ( ( current_time2 - current_time ) < 3 )
SDL_BlitSurface ( lightgunSurface , & srect , sdl_video . surf_screen , & lrect ) ;
} else
{
if ( config . cursor ! = 0 )
srect . x = 15 ;
else
srect . x = 0 ;
if ( ( current_time2 - current_time ) < 3 )
SDL_BlitSurface ( lightgunSurface , & srect , sdl_video . surf_screen , & lrect ) ;
}
lightgun_af + + ;
if ( lightgun_af = = 20 ) lightgun_af = 0 ;
SDL_FreeSurface ( lightgunSurface ) ;
} //show_lightgun
# endif
SDL_Flip ( sdl_video . surf_screen ) ;
+ + sdl_video . frames_rendered ;
}
static void sdl_video_close ( )
{
if ( sdl_video . surf_bitmap )
SDL_FreeSurface ( sdl_video . surf_bitmap ) ;
if ( sdl_video . surf_screen )
SDL_FreeSurface ( sdl_video . surf_screen ) ;
}
/* Timer Sync */
struct
{
SDL_sem * sem_sync ;
unsigned ticks ;
} sdl_sync ;
static Uint32 sdl_sync_timer_callback ( Uint32 interval )
{
# ifdef GCWZERO
if ( ! gotomenu )
{
SDL_SemPost ( sdl_sync . sem_sync ) ;
sdl_sync . ticks + + ;
}
# else
SDL_SemPost ( sdl_sync . sem_sync ) ;
sdl_sync . ticks + + ;
# endif
if ( sdl_sync . ticks = = ( vdp_pal ? 50 : 20 ) )
{
SDL_Event event ;
SDL_UserEvent userevent ;
userevent . type = SDL_USEREVENT ;
userevent . code = vdp_pal ? ( sdl_video . frames_rendered / 3 ) : sdl_video . frames_rendered ;
userevent . data1 = NULL ;
userevent . data2 = NULL ;
sdl_sync . ticks = sdl_video . frames_rendered = 0 ;
event . type = SDL_USEREVENT ;
event . user = userevent ;
SDL_PushEvent ( & event ) ;
}
return interval ;
}
static int sdl_sync_init ( )
{
if ( SDL_InitSubSystem ( SDL_INIT_TIMER | SDL_INIT_EVENTTHREAD ) < 0 )
{
MessageBox ( NULL , " SDL Timer initialization failed " , " Error " , 0 ) ;
return 0 ;
}
sdl_sync . sem_sync = SDL_CreateSemaphore ( 0 ) ;
sdl_sync . ticks = 0 ;
return 1 ;
}
static void sdl_sync_close ( )
{
if ( sdl_sync . sem_sync )
SDL_DestroySemaphore ( sdl_sync . sem_sync ) ;
}
static const uint16 vc_table [ 4 ] [ 2 ] =
{
/* NTSC, PAL */
{ 0xDA , 0xF2 } , /* Mode 4 (192 lines) */
{ 0xEA , 0x102 } , /* Mode 5 (224 lines) */
{ 0xDA , 0xF2 } , /* Mode 4 (192 lines) */
{ 0x106 , 0x10A } /* Mode 5 (240 lines) */
} ;
static int sdl_control_update ( SDLKey keystate )
{
switch ( keystate )
{
# ifndef GCWZERO
case SDLK_TAB :
{
system_reset ( ) ;
break ;
}
# endif
case SDLK_F1 :
{
if ( SDL_ShowCursor ( - 1 ) ) SDL_ShowCursor ( 0 ) ;
else SDL_ShowCursor ( 1 ) ;
break ;
}
case SDLK_F2 :
{
if ( fullscreen ) fullscreen = 0 ;
else fullscreen = SDL_FULLSCREEN ;
sdl_video . surf_screen = SDL_SetVideoMode ( VIDEO_WIDTH , VIDEO_HEIGHT , 16 , SDL_SWSURFACE | fullscreen ) ;
break ;
}
case SDLK_F3 :
{
if ( config . bios = = 0 ) config . bios = 3 ;
else if ( config . bios = = 3 ) config . bios = 1 ;
break ;
}
case SDLK_F4 :
{
if ( ! turbo_mode ) use_sound ^ = 1 ;
break ;
}
case SDLK_F5 :
{
log_error ^ = 1 ;
break ;
}
case SDLK_F6 :
{
if ( ! use_sound )
{
turbo_mode ^ = 1 ;
sdl_sync . ticks = 0 ;
}
break ;
}
case SDLK_F7 :
{
char save_state_file [ 256 ] ;
sprintf ( save_state_file , " %s/%X.gp0 " , get_save_directory ( ) , rominfo . realchecksum ) ;
FILE * f = fopen ( save_state_file , " rb " ) ;
if ( f )
{
uint8 buf [ STATE_SIZE ] ;
fread ( & buf , STATE_SIZE , 1 , f ) ;
state_load ( buf ) ;
fclose ( f ) ;
}
break ;
}
case SDLK_F8 :
{
char save_state_file [ 256 ] ;
sprintf ( save_state_file , " %s/%X.gp0 " , get_save_directory ( ) , rominfo . realchecksum ) ;
FILE * f = fopen ( save_state_file , " wb " ) ;
if ( f )
{
uint8 buf [ STATE_SIZE ] ;
int len = state_save ( buf ) ;
fwrite ( & buf , len , 1 , f ) ;
fclose ( f ) ;
}
break ;
}
case SDLK_F9 :
{
config . region_detect = ( config . region_detect + 1 ) % 5 ;
get_region ( 0 ) ;
/* framerate has changed, reinitialize audio timings */
audio_init ( snd . sample_rate , 0 ) ;
/* system with region BIOS should be reinitialized */
if ( ( system_hw = = SYSTEM_MCD ) | | ( ( system_hw & SYSTEM_SMS ) & & ( config . bios & 1 ) ) )
{
system_init ( ) ;
system_reset ( ) ;
}
else
{
/* reinitialize I/O region register */
if ( system_hw = = SYSTEM_MD )
{
io_reg [ 0x00 ] = 0x20 | region_code | ( config . bios & 1 ) ;
}
else
{
io_reg [ 0x00 ] = 0x80 | ( region_code > > 1 ) ;
}
/* reinitialize VDP */
if ( vdp_pal )
{
status | = 1 ;
lines_per_frame = 313 ;
}
else
{
status & = ~ 1 ;
lines_per_frame = 262 ;
}
/* reinitialize VC max value */
switch ( bitmap . viewport . h )
{
case 192 :
vc_max = vc_table [ 0 ] [ vdp_pal ] ;
break ;
case 224 :
vc_max = vc_table [ 1 ] [ vdp_pal ] ;
break ;
case 240 :
vc_max = vc_table [ 3 ] [ vdp_pal ] ;
break ;
}
}
break ;
}
case SDLK_F10 :
{
gen_reset ( 0 ) ;
break ;
}
case SDLK_F11 :
{
config . overscan = ( config . overscan + 1 ) & 3 ;
if ( ( system_hw = = SYSTEM_GG ) & & ! config . gg_extra )
{
bitmap . viewport . x = ( config . overscan & 2 ) ? 14 : - 48 ;
}
else
{
bitmap . viewport . x = ( config . overscan & 2 ) * 7 ;
}
bitmap . viewport . changed = 3 ;
break ;
}
case SDLK_F12 :
{
joynum = ( joynum + 1 ) % MAX_DEVICES ;
while ( input . dev [ joynum ] = = NO_DEVICE )
{
joynum = ( joynum + 1 ) % MAX_DEVICES ;
}
break ;
}
case SDLK_ESCAPE :
{
# ifndef GCWZERO
/* exit */
return 0 ;
# endif
}
default :
break ;
}
return 1 ;
}
static void shutdown ( )
{
FILE * fp ;
if ( system_hw = = SYSTEM_MCD )
{
/* save internal backup RAM (if formatted) */
char brm_file [ 256 ] ;
if ( ! memcmp ( scd . bram + 0x2000 - 0x20 , brm_format + 0x20 , 0x20 ) )
{
sprintf ( brm_file , " %s/ " , get_save_directory ( ) , " scd.brm " ) ;
fp = fopen ( brm_file , " wb " ) ;
if ( fp ! = NULL )
{
fwrite ( scd . bram , 0x2000 , 1 , fp ) ;
fclose ( fp ) ;
}
}
/* save cartridge backup RAM (if formatted) */
if ( scd . cartridge . id )
{
if ( ! memcmp ( scd . cartridge . area + scd . cartridge . mask + 1 - 0x20 , brm_format + 0x20 , 0x20 ) )
{
sprintf ( brm_file , " %s/ " , get_save_directory ( ) , " cart.brm " ) ;
fp = fopen ( brm_file , " wb " ) ;
if ( fp ! = NULL )
{
fwrite ( scd . cartridge . area , scd . cartridge . mask + 1 , 1 , fp ) ;
fclose ( fp ) ;
}
}
}
}
if ( sram . on )
{
/* save SRAM */
char save_file [ 256 ] ;
if ( rom_filename [ 0 ] ! = ' \0 ' ) {
sprintf ( save_file , " %s/%s.srm " , get_save_directory ( ) , rom_filename ) ;
fp = fopen ( save_file , " wb " ) ;
if ( fp ! = NULL )
{
fwrite ( sram . sram , 0x10000 , 1 , fp ) ;
fclose ( fp ) ;
}
}
}
audio_shutdown ( ) ;
error_shutdown ( ) ;
sdl_video_close ( ) ;
sdl_sound_close ( ) ;
sdl_sync_close ( ) ;
SDL_Quit ( ) ;
}
# ifdef GCWZERO //menu!
static int gcw0menu ( void )
{
SDL_PauseAudio ( 1 ) ;
/* display menu */
// change video mode
sdl_video . surf_screen = SDL_SetVideoMode ( 320 , 240 , 32 , SDL_HWSURFACE |
# ifdef SDL_TRIPLEBUF
SDL_TRIPLEBUF ) ;
# else
SDL_DOUBLEBUF ) ;
# endif
// blank screen
SDL_FillRect ( sdl_video . surf_screen , 0 , 0 ) ;
enum { MAINMENU = 0 , GRAPHICS_OPTIONS = 1 , REMAP_OPTIONS = 2 , SAVE_STATE = 3 , LOAD_STATE = 4 , MISC_OPTIONS = 5 } ;
static int menustate = MAINMENU ;
// Menu text
const char * gcw0menu_mainlist [ 9 ] =
{
" Resume game " ,
" Save state " ,
" Load state " ,
" Graphics options " ,
" Remap buttons " ,
" Misc. Options " ,
" " , //spacer
" Reset " ,
" Quit "
} ;
const char * gcw0menu_gfxlist [ 6 ] =
{
" Scaling " ,
" Keep aspect ratio " ,
" Scanlines (GG) " ,
" Mask left bar (SMS) " ,
" Frameskip " ,
" Return to main menu " ,
} ;
const char * gcw0menu_numericlist [ 4 ] =
{
" 0 " ,
" 1 " ,
" 2 " ,
" 3 " ,
} ;
const char * gcw0menu_onofflist [ 2 ] =
{
" Off " ,
" On " ,
} ;
const char * gcw0menu_remapoptionslist [ 9 ] =
{
" A " ,
" B " ,
" C " ,
" X " ,
" Y " ,
" Z " ,
" Start " ,
" Mode " ,
" Return to main menu " ,
} ;
const char * gcw0menu_savestate [ 10 ] =
{
" Back to main menu " ,
" Save state 1 (Quicksave) " ,
" Save state 2 " ,
" Save state 3 " ,
" Save state 4 " ,
" Save state 5 " ,
" Save state 6 " ,
" Save state 7 " ,
" Save state 8 " ,
" Save state 9 " ,
} ;
const char * gcw0menu_loadstate [ 10 ] =
{
" Back to main menu " ,
" Load state 1 (Quickload) " ,
" Load state 2 " ,
" Load state 3 " ,
" Load state 4 " ,
" Load state 5 " ,
" Load state 6 " ,
" Load state 7 " ,
" Load state 8 " ,
" Load state 9 " ,
} ;
const char * gcw0menu_misc [ 7 ] =
{
" Back to main menu " ,
" Resume on Save/Load " ,
" A-stick " ,
" Lock-on " ,
" FM sound (SMS) " ,
" Lightgun speed " ,
" Lightgun Cursor " ,
} ;
const char * lock_on_desc [ 4 ] =
{
" Off " ,
" Game Genie " ,
" Action Replay " ,
" Sonic & Knuckles " ,
} ;
// start menu loop
bitmap . viewport . changed = 1 ; //change screen res if required
while ( gotomenu )
{
// set up menu surface
SDL_Surface * menuSurface = NULL ;
menuSurface = SDL_CreateRGBSurface ( SDL_HWSURFACE , 320 , 240 , 16 , 0 , 0 , 0 , 0 ) ;
// identify system we are using to show correct background just cos we can :P
if ( system_hw = = SYSTEM_PICO ) //Sega Pico
{
SDL_Surface * tempbgSurface ;
SDL_Surface * bgSurface ;
tempbgSurface = IMG_Load ( " ./PICO.png " ) ;
bgSurface = SDL_DisplayFormat ( tempbgSurface ) ;
SDL_BlitSurface ( bgSurface , NULL , menuSurface , NULL ) ;
SDL_FreeSurface ( tempbgSurface ) ;
SDL_FreeSurface ( bgSurface ) ;
}
2022-10-29 13:51:34 +02:00
else if ( ( system_hw = = SYSTEM_SG ) | | ( system_hw = = SYSTEM_SGII ) | | ( system_hw = = SYSTEM_SGII_RAM_EXT ) ) //SG-1000 I&II
2015-04-26 22:10:42 +02:00
{
SDL_Surface * tempbgSurface ;
SDL_Surface * bgSurface ;
tempbgSurface = IMG_Load ( " ./SG1000.png " ) ;
bgSurface = SDL_DisplayFormat ( tempbgSurface ) ;
SDL_BlitSurface ( bgSurface , NULL , menuSurface , NULL ) ;
SDL_FreeSurface ( tempbgSurface ) ;
SDL_FreeSurface ( bgSurface ) ;
}
else if ( ( system_hw = = SYSTEM_MARKIII ) | | ( system_hw = = SYSTEM_SMS ) | | ( system_hw = = SYSTEM_GGMS ) | | ( system_hw = = SYSTEM_SMS2 ) | | ( system_hw = = SYSTEM_PBC ) ) //Mark III & Sega Master System I&II & Megadrive with power base converter
{
SDL_Surface * tempbgSurface ;
SDL_Surface * bgSurface ;
tempbgSurface = IMG_Load ( " ./SMS.png " ) ;
bgSurface = SDL_DisplayFormat ( tempbgSurface ) ;
SDL_BlitSurface ( bgSurface , NULL , menuSurface , NULL ) ;
SDL_FreeSurface ( tempbgSurface ) ;
SDL_FreeSurface ( bgSurface ) ;
}
else if ( system_hw = = SYSTEM_GG )
{
SDL_Surface * tempbgSurface ;
SDL_Surface * bgSurface ;
tempbgSurface = IMG_Load ( " ./GG.png " ) ;
bgSurface = SDL_DisplayFormat ( tempbgSurface ) ;
SDL_BlitSurface ( bgSurface , NULL , menuSurface , NULL ) ;
SDL_FreeSurface ( tempbgSurface ) ;
SDL_FreeSurface ( bgSurface ) ;
}
else if ( system_hw = = SYSTEM_MD ) //Megadrive
{
SDL_Surface * tempbgSurface ;
SDL_Surface * bgSurface ;
tempbgSurface = IMG_Load ( " ./MD.png " ) ;
bgSurface = SDL_DisplayFormat ( tempbgSurface ) ;
SDL_BlitSurface ( bgSurface , NULL , menuSurface , NULL ) ;
SDL_FreeSurface ( tempbgSurface ) ;
SDL_FreeSurface ( bgSurface ) ;
}
else if ( system_hw = = SYSTEM_MCD ) //MegaCD
{
SDL_Surface * tempbgSurface ;
SDL_Surface * bgSurface ;
tempbgSurface = IMG_Load ( " ./MCD.png " ) ;
bgSurface = SDL_DisplayFormat ( tempbgSurface ) ;
SDL_BlitSurface ( bgSurface , NULL , menuSurface , NULL ) ;
SDL_FreeSurface ( tempbgSurface ) ;
SDL_FreeSurface ( bgSurface ) ;
}
// show menu
TTF_Init ( ) ;
TTF_Font * ttffont = NULL ;
SDL_Color text_color = { 180 , 180 , 180 } ;
SDL_Color selected_text_color = { 23 , 86 , 155 } ; //selected colour = Sega blue ;)
SDL_Surface * textSurface ;
int i ;
static int selectedoption = 0 ;
// Fill menu box
SDL_Surface * MenuBackground ;
if ( menustate = = REMAP_OPTIONS )
{
MenuBackground = SDL_CreateRGBSurface ( SDL_HWSURFACE , 320 , 185 , 16 , 0 , 0 , 0 , 0 ) ;
SDL_Rect rect ;
rect . x = 0 ;
rect . y = 35 ;
rect . w = 320 ;
rect . h = 185 ;
SDL_FillRect ( MenuBackground , 0 , 0 ) ;
SDL_SetAlpha ( MenuBackground , SDL_SRCALPHA , 50 ) ;
SDL_BlitSurface ( MenuBackground , NULL , menuSurface , & rect ) ;
SDL_FreeSurface ( MenuBackground ) ;
}
else
{
MenuBackground = SDL_CreateRGBSurface ( SDL_HWSURFACE , 180 , 185 , 16 , 0 , 0 , 0 , 0 ) ;
SDL_Rect rect ;
rect . x = 60 ;
rect . y = 35 ;
rect . w = 180 ;
rect . h = 185 ;
SDL_FillRect ( MenuBackground , 0 , 0 ) ;
SDL_SetAlpha ( MenuBackground , SDL_SRCALPHA , 50 ) ;
SDL_BlitSurface ( MenuBackground , NULL , menuSurface , & rect ) ;
SDL_FreeSurface ( MenuBackground ) ;
}
// Show title
ttffont = TTF_OpenFont ( " ./ProggyTiny.ttf " , 16 ) ;
SDL_Rect destination ;
destination . x = 80 ;
destination . y = 40 ;
destination . w = 100 ;
destination . h = 50 ;
textSurface = TTF_RenderText_Solid ( ttffont , " Genesis Plus GX " , text_color ) ;
SDL_BlitSurface ( textSurface , NULL , menuSurface , & destination ) ;
SDL_FreeSurface ( textSurface ) ;
TTF_CloseFont ( ttffont ) ;
if ( menustate = = MAINMENU )
{
//there's no need to open/close font each cycle :P
ttffont = TTF_OpenFont ( " ./ProggyTiny.ttf " , 16 ) ;
for ( i = 0 ; i < 9 ; i + + )
{
SDL_Rect destination ;
destination . x = 80 ;
destination . y = 70 + ( 15 * i ) ;
destination . w = 100 ;
destination . h = 50 ;
if ( i = = selectedoption )
textSurface = TTF_RenderText_Solid ( ttffont , gcw0menu_mainlist [ i ] , selected_text_color ) ;
else
textSurface = TTF_RenderText_Solid ( ttffont , gcw0menu_mainlist [ i ] , text_color ) ;
SDL_BlitSurface ( textSurface , NULL , menuSurface , & destination ) ;
SDL_FreeSurface ( textSurface ) ;
}
TTF_CloseFont ( ttffont ) ;
}
else if ( menustate = = GRAPHICS_OPTIONS )
{
ttffont = TTF_OpenFont ( " ./ProggyTiny.ttf " , 16 ) ;
for ( i = 0 ; i < 6 ; i + + )
{
SDL_Rect destination ;
destination . x = 80 ;
destination . y = 70 + ( 15 * i ) ;
destination . w = 100 ;
destination . h = 50 ;
if ( ( i + 10 ) = = selectedoption )
textSurface = TTF_RenderText_Solid ( ttffont , gcw0menu_gfxlist [ i ] , selected_text_color ) ;
else
textSurface = TTF_RenderText_Solid ( ttffont , gcw0menu_gfxlist [ i ] , text_color ) ;
SDL_BlitSurface ( textSurface , NULL , menuSurface , & destination ) ;
SDL_FreeSurface ( textSurface ) ;
}
/* Display On/Off */
SDL_Rect destination ;
destination . x = 220 ;
destination . w = 100 ;
destination . h = 50 ;
// Scaling
destination . y = 70 + ( 15 * 0 ) ;
textSurface = TTF_RenderText_Solid ( ttffont , gcw0menu_onofflist [ config . gcw0_fullscreen ] , selected_text_color ) ;
SDL_BlitSurface ( textSurface , NULL , menuSurface , & destination ) ;
SDL_FreeSurface ( textSurface ) ;
// Aspect ratio
destination . y = 70 + ( 15 * 1 ) ;
textSurface = TTF_RenderText_Solid ( ttffont , gcw0menu_onofflist [ config . keepaspectratio ] , selected_text_color ) ;
SDL_BlitSurface ( textSurface , NULL , menuSurface , & destination ) ;
SDL_FreeSurface ( textSurface ) ;
// Scanlines
destination . y = 70 + ( 15 * 2 ) ;
textSurface = TTF_RenderText_Solid ( ttffont , gcw0menu_onofflist [ config . gg_scanlines ] , selected_text_color ) ;
SDL_BlitSurface ( textSurface , NULL , menuSurface , & destination ) ;
SDL_FreeSurface ( textSurface ) ;
// Mask left bar
destination . y = 70 + ( 15 * 3 ) ;
textSurface = TTF_RenderText_Solid ( ttffont , gcw0menu_onofflist [ config . smsmaskleftbar ] , selected_text_color ) ;
SDL_BlitSurface ( textSurface , NULL , menuSurface , & destination ) ;
SDL_FreeSurface ( textSurface ) ;
// Frameskip
destination . y = 70 + ( 15 * 4 ) ;
textSurface = TTF_RenderText_Solid ( ttffont , gcw0menu_numericlist [ config . gcw0_frameskip ] , selected_text_color ) ;
SDL_BlitSurface ( textSurface , NULL , menuSurface , & destination ) ;
SDL_FreeSurface ( textSurface ) ;
TTF_CloseFont ( ttffont ) ;
}
else if ( menustate = = REMAP_OPTIONS )
{
char * remap_text [ 256 ] ;
ttffont = TTF_OpenFont ( " ./ProggyTiny.ttf " , 16 ) ;
sprintf ( remap_text , " %s%25s " , " GenPlus " , " GCW-Zero " ) ;
SDL_Rect destination = { 30 , 60 , 100 , 50 } ;
textSurface = TTF_RenderText_Solid ( ttffont , remap_text , text_color ) ;
SDL_BlitSurface ( textSurface , NULL , menuSurface , & destination ) ;
SDL_FreeSurface ( textSurface ) ;
for ( i = 0 ; i < 9 ; i + + )
{
if ( i < 8 )
{
sprintf ( remap_text , " %-5s %-7s " , gcw0menu_remapoptionslist [ i ] , gcw0_get_key_name ( config . buttons [ i ] ) ) ;
} else
{
sprintf ( remap_text , gcw0menu_remapoptionslist [ i ] ) ; // for return option
}
SDL_Rect destination = { 30 , 80 + ( 15 * i ) , 100 , 50 } ;
if ( ( i + 20 ) = = selectedoption )
{
textSurface = TTF_RenderText_Solid ( ttffont , remap_text , selected_text_color ) ;
} else
{
textSurface = TTF_RenderText_Solid ( ttffont , remap_text , text_color ) ;
}
SDL_BlitSurface ( textSurface , NULL , menuSurface , & destination ) ;
SDL_FreeSurface ( textSurface ) ;
}
TTF_CloseFont ( ttffont ) ;
}
else if ( menustate = = SAVE_STATE )
{
//Show saved BMP as background if available
SDL_Surface * screenshot ;
char load_state_screenshot [ 256 ] ;
sprintf ( load_state_screenshot , " %s/%s.%d.bmp " , get_save_directory ( ) , rom_filename , selectedoption - 30 ) ;
screenshot = SDL_LoadBMP ( load_state_screenshot ) ;
if ( screenshot )
{
SDL_Rect destination ;
destination . x = ( 320 - screenshot - > w ) / 2 ;
destination . y = ( 240 - screenshot - > h ) / 2 ;
destination . w = 320 ;
destination . h = 240 ;
SDL_BlitSurface ( screenshot , NULL , menuSurface , & destination ) ;
// Fill menu box
SDL_Surface * MenuBackground = SDL_CreateRGBSurface ( SDL_HWSURFACE , 180 , 185 , 16 , 0 , 0 , 0 , 0 ) ;
SDL_Rect rect ;
rect . x = 60 ;
rect . y = 35 ;
rect . w = 180 ;
rect . h = 185 ;
SDL_FillRect ( MenuBackground , 0 , 0 ) ;
SDL_SetAlpha ( MenuBackground , SDL_SRCALPHA , 180 ) ;
SDL_BlitSurface ( MenuBackground , NULL , menuSurface , & rect ) ;
SDL_FreeSurface ( MenuBackground ) ;
}
SDL_FreeSurface ( screenshot ) ;
// Show title
ttffont = TTF_OpenFont ( " ./ProggyTiny.ttf " , 16 ) ;
SDL_Rect destination ;
destination . x = 80 ;
destination . y = 40 ;
destination . w = 100 ;
destination . h = 50 ;
textSurface = TTF_RenderText_Solid ( ttffont , " Genesis Plus GX " , text_color ) ;
SDL_BlitSurface ( textSurface , NULL , menuSurface , & destination ) ;
SDL_FreeSurface ( textSurface ) ;
TTF_CloseFont ( ttffont ) ;
ttffont = TTF_OpenFont ( " ./ProggyTiny.ttf " , 16 ) ;
for ( i = 0 ; i < 10 ; i + + )
{
SDL_Rect destination ;
destination . x = 80 ;
destination . y = 70 + ( 15 * i ) ;
destination . w = 100 ;
destination . h = 50 ;
if ( ( i + 30 ) = = selectedoption )
textSurface = TTF_RenderText_Solid ( ttffont , gcw0menu_savestate [ i ] , selected_text_color ) ;
else
textSurface = TTF_RenderText_Solid ( ttffont , gcw0menu_savestate [ i ] , text_color ) ;
SDL_BlitSurface ( textSurface , NULL , menuSurface , & destination ) ;
SDL_FreeSurface ( textSurface ) ;
}
TTF_CloseFont ( ttffont ) ;
}
else if ( menustate = = LOAD_STATE )
{
//Show saved BMP as background if available
SDL_Surface * screenshot ;
char load_state_screenshot [ 256 ] ;
sprintf ( load_state_screenshot , " %s/%s.%d.bmp " , get_save_directory ( ) , rom_filename , selectedoption - 40 ) ;
screenshot = SDL_LoadBMP ( load_state_screenshot ) ;
if ( screenshot )
{
SDL_Rect destination ;
destination . x = ( 320 - screenshot - > w ) / 2 ;
destination . y = ( 240 - screenshot - > h ) / 2 ;
destination . w = 320 ;
destination . h = 240 ;
SDL_BlitSurface ( screenshot , NULL , menuSurface , & destination ) ;
// Fill menu box
SDL_Surface * MenuBackground = SDL_CreateRGBSurface ( SDL_HWSURFACE , 180 , 185 , 16 , 0 , 0 , 0 , 0 ) ;
SDL_Rect rect ;
rect . x = 60 ;
rect . y = 35 ;
rect . w = 180 ;
rect . h = 185 ;
SDL_FillRect ( MenuBackground , 0 , 0 ) ;
SDL_SetAlpha ( MenuBackground , SDL_SRCALPHA , 180 ) ;
SDL_BlitSurface ( MenuBackground , NULL , menuSurface , & rect ) ;
SDL_FreeSurface ( MenuBackground ) ;
}
SDL_FreeSurface ( screenshot ) ;
// Show title
ttffont = TTF_OpenFont ( " ./ProggyTiny.ttf " , 16 ) ;
SDL_Rect destination ;
destination . x = 80 ;
destination . y = 40 ;
destination . w = 100 ;
destination . h = 50 ;
textSurface = TTF_RenderText_Solid ( ttffont , " Genesis Plus GX " , text_color ) ;
SDL_BlitSurface ( textSurface , NULL , menuSurface , & destination ) ;
SDL_FreeSurface ( textSurface ) ;
TTF_CloseFont ( ttffont ) ;
ttffont = TTF_OpenFont ( " ./ProggyTiny.ttf " , 16 ) ;
for ( i = 0 ; i < 10 ; i + + )
{
SDL_Rect destination ;
destination . x = 80 ;
destination . y = 70 + ( 15 * i ) ;
destination . w = 100 ;
destination . h = 50 ;
if ( ( i + 40 ) = = selectedoption )
textSurface = TTF_RenderText_Solid ( ttffont , gcw0menu_loadstate [ i ] , selected_text_color ) ;
else
textSurface = TTF_RenderText_Solid ( ttffont , gcw0menu_loadstate [ i ] , text_color ) ;
SDL_BlitSurface ( textSurface , NULL , menuSurface , & destination ) ;
SDL_FreeSurface ( textSurface ) ;
}
TTF_CloseFont ( ttffont ) ;
}
else if ( menustate = = MISC_OPTIONS )
{
ttffont = TTF_OpenFont ( " ./ProggyTiny.ttf " , 16 ) ;
for ( i = 0 ; i < 7 ; i + + )
{
SDL_Rect destination ;
destination . x = 80 ;
destination . y = 70 + ( 15 * i ) ;
destination . w = 100 ;
destination . h = 50 ;
if ( ( i + 50 ) = = selectedoption )
textSurface = TTF_RenderText_Solid ( ttffont , gcw0menu_misc [ i ] , selected_text_color ) ;
else
textSurface = TTF_RenderText_Solid ( ttffont , gcw0menu_misc [ i ] , text_color ) ;
SDL_BlitSurface ( textSurface , NULL , menuSurface , & destination ) ;
SDL_FreeSurface ( textSurface ) ;
}
/* Display On/Off */
SDL_Rect destination ;
destination . x = 220 ;
destination . w = 100 ;
destination . h = 50 ;
// Save/load autoresume
destination . y = 70 + ( 15 * 1 ) ;
textSurface = TTF_RenderText_Solid ( ttffont , gcw0menu_onofflist [ config . sl_autoresume ] , selected_text_color ) ;
SDL_BlitSurface ( textSurface , NULL , menuSurface , & destination ) ;
SDL_FreeSurface ( textSurface ) ;
// A-stick
destination . y = 70 + ( 15 * 2 ) ;
textSurface = TTF_RenderText_Solid ( ttffont , gcw0menu_onofflist [ config . a_stick ] , selected_text_color ) ;
SDL_BlitSurface ( textSurface , NULL , menuSurface , & destination ) ;
SDL_FreeSurface ( textSurface ) ;
/* Display Lock-on Types */
destination . x = 142 ;
destination . y = 70 + ( 15 * 3 ) ;
textSurface = TTF_RenderText_Solid ( ttffont , lock_on_desc [ config . lock_on ] , selected_text_color ) ;
SDL_BlitSurface ( textSurface , NULL , menuSurface , & destination ) ;
SDL_FreeSurface ( textSurface ) ;
// FM sound(SMS)
destination . x = 220 ;
destination . y = 70 + ( 15 * 4 ) ;
textSurface = TTF_RenderText_Solid ( ttffont , gcw0menu_onofflist [ config . ym2413 ] , selected_text_color ) ;
SDL_BlitSurface ( textSurface , NULL , menuSurface , & destination ) ;
SDL_FreeSurface ( textSurface ) ;
// Lightgun speed
destination . x = 220 ;
destination . y = 70 + ( 15 * 5 ) ;
textSurface = TTF_RenderText_Solid ( ttffont , gcw0menu_numericlist [ config . lightgun_speed ] , selected_text_color ) ;
SDL_BlitSurface ( textSurface , NULL , menuSurface , & destination ) ;
SDL_FreeSurface ( textSurface ) ;
// Lightgun Cursor
destination . y = 70 + ( 15 * 6 ) ;
SDL_Surface * lightgunSurface ;
lightgunSurface = IMG_Load ( cursor [ config . cursor ] ) ;
static lightgun_af_demo = 0 ;
SDL_Rect srect ;
srect . x = 0 ;
srect . y = 0 ;
srect . w = 15 ;
srect . h = 15 ;
if ( lightgun_af_demo > = 10 & & config . cursor ! = 0 )
{
srect . x = 15 ;
}
lightgun_af_demo + + ;
if ( lightgun_af_demo = = 20 ) lightgun_af_demo = 0 ;
SDL_BlitSurface ( lightgunSurface , & srect , menuSurface , & destination ) ;
SDL_FreeSurface ( lightgunSurface ) ;
TTF_CloseFont ( ttffont ) ;
}
//TODO other menu's go here
/* Update display */
SDL_Rect dest ;
dest . w = 320 ;
dest . h = 240 ;
dest . x = 0 ;
dest . y = 0 ;
SDL_BlitSurface ( menuSurface , NULL , sdl_video . surf_screen , & dest ) ;
SDL_FreeSurface ( menuSurface ) ;
SDL_Flip ( sdl_video . surf_screen ) ;
/* Check for user input */
SDL_EnableKeyRepeat ( 0 , 0 ) ;
static int keyheld = 0 ;
SDL_Event event ;
while ( SDL_PollEvent ( & event ) )
{
switch ( event . type )
{
case SDL_KEYDOWN :
sdl_control_update ( event . key . keysym . sym ) ;
break ;
case SDL_KEYUP :
keyheld = 0 ;
break ;
default :
break ;
}
}
if ( event . type = = SDL_KEYDOWN & & ! keyheld )
{
keyheld + + ;
uint8 * keystate2 ;
keystate2 = SDL_GetKeyState ( NULL ) ;
if ( keystate2 [ SDLK_DOWN ] )
{
if ( selectedoption > 9 & & selectedoption < 20 ) //graphics menu
{
selectedoption + + ;
if ( selectedoption = = 16 ) selectedoption = 10 ;
}
else if ( selectedoption > 19 & & selectedoption < 30 ) //remap menu
{
selectedoption + + ;
if ( selectedoption = = 29 ) selectedoption = 20 ;
}
else if ( selectedoption > 29 & & selectedoption < 40 ) //save menu
{
selectedoption + + ;
if ( selectedoption = = 40 ) selectedoption = 30 ;
}
else if ( selectedoption > 39 & & selectedoption < 50 ) //load menu
{
selectedoption + + ;
if ( selectedoption = = 50 ) selectedoption = 40 ;
}
else if ( selectedoption > 49 & & selectedoption < 60 ) //misc menu
{
selectedoption + + ;
if ( selectedoption = = 57 ) selectedoption = 50 ;
}
else //main menu
{
selectedoption + + ;
if ( selectedoption = = 6 ) selectedoption = 7 ;
if ( selectedoption > 8 ) selectedoption = 0 ;
}
SDL_Delay ( 100 ) ;
}
else if ( keystate2 [ SDLK_UP ] )
{
if ( selectedoption > 9 & & selectedoption < 20 ) //graphics menu
{
selectedoption - - ;
if ( selectedoption = = 9 ) selectedoption = 15 ;
}
else if ( selectedoption > 19 & & selectedoption < 30 ) //remap menu
{
selectedoption - - ;
if ( selectedoption = = 19 ) selectedoption = 28 ;
}
else if ( selectedoption > 29 & & selectedoption < 40 ) //save menu
{
selectedoption - - ;
if ( selectedoption = = 29 ) selectedoption = 39 ;
}
else if ( selectedoption > 39 & & selectedoption < 50 ) //load menu
{
selectedoption - - ;
if ( selectedoption = = 39 ) selectedoption = 49 ;
}
else if ( selectedoption > 49 & & selectedoption < 60 ) //misc menu
{
selectedoption - - ;
if ( selectedoption = = 49 ) selectedoption = 56 ;
}
else
{ //main menu
if ( ! selectedoption ) selectedoption = 8 ;
else selectedoption - - ;
if ( selectedoption = = 6 ) selectedoption = 5 ;
}
SDL_Delay ( 100 ) ;
}
else if ( keystate2 [ SDLK_LALT ] & & menustate ! = REMAP_OPTIONS ) //back to last menu or quit menu
{
if ( menustate = = GRAPHICS_OPTIONS )
{
menustate = MAINMENU ;
selectedoption = 3 ;
SDL_Delay ( 130 ) ;
}
else if ( menustate = = SAVE_STATE )
{
menustate = MAINMENU ;
selectedoption = 1 ;
SDL_Delay ( 130 ) ;
}
else if ( menustate = = LOAD_STATE )
{
menustate = MAINMENU ;
selectedoption = 2 ;
SDL_Delay ( 130 ) ;
}
else if ( menustate = = MISC_OPTIONS )
{
menustate = MAINMENU ;
selectedoption = 5 ;
SDL_Delay ( 130 ) ;
}
else if ( menustate = = MAINMENU )
{
gotomenu = 0 ;
selectedoption = 0 ;
SDL_Delay ( 130 ) ;
break ;
}
}
else if ( keystate2 [ SDLK_LCTRL ] & & menustate ! = REMAP_OPTIONS )
{
if ( selectedoption = = 0 )
{ //Resume
gotomenu = 0 ;
selectedoption = 0 ;
SDL_Delay ( 130 ) ;
break ;
}
else if ( selectedoption = = 1 ) //Save
{
menustate = SAVE_STATE ;
selectedoption = 30 ;
SDL_Delay ( 130 ) ;
}
else if ( selectedoption = = 2 ) //Load
{
menustate = LOAD_STATE ;
selectedoption = 40 ;
SDL_Delay ( 130 ) ;
}
else if ( selectedoption = = 3 ) //Graphics
{
menustate = GRAPHICS_OPTIONS ;
selectedoption = 10 ;
SDL_Delay ( 200 ) ;
}
else if ( selectedoption = = 4 ) //Remap
{
menustate = REMAP_OPTIONS ;
selectedoption = 20 ;
SDL_Delay ( 200 ) ;
}
else if ( selectedoption = = 5 ) //Misc.
{
menustate = MISC_OPTIONS ;
selectedoption = 50 ;
SDL_Delay ( 200 ) ;
}
else if ( selectedoption = = 7 ) //Reset
{
gotomenu = 0 ;
selectedoption = 0 ;
system_reset ( ) ;
SDL_Delay ( 130 ) ;
break ;
}
else if ( selectedoption = = 8 ) //Quit
{
exit ( 0 ) ;
SDL_Delay ( 130 ) ;
break ;
}
else if ( selectedoption = = 10 )
{ //Scaling
config . gcw0_fullscreen = ! config . gcw0_fullscreen ;
SDL_Delay ( 130 ) ;
config_save ( ) ;
}
else if ( selectedoption = = 11 )
{ //Keep aspect ratio
SDL_Delay ( 130 ) ;
config . keepaspectratio = ! config . keepaspectratio ;
config_save ( ) ;
do_once = 1 ;
}
else if ( selectedoption = = 12 )
{ //Scanlines (GG)
SDL_Delay ( 130 ) ;
config . gg_scanlines = ! config . gg_scanlines ;
config_save ( ) ;
}
else if ( selectedoption = = 13 )
{ //Mask left bar
SDL_Delay ( 130 ) ;
config . smsmaskleftbar = ! config . smsmaskleftbar ;
config_save ( ) ;
}
else if ( selectedoption = = 14 )
{ //Frameskip
SDL_Delay ( 130 ) ;
config . gcw0_frameskip + + ;
if ( config . gcw0_frameskip = = 4 ) config . gcw0_frameskip = 0 ;
config_save ( ) ;
}
else if ( selectedoption = = 15 )
{ //Back to main menu
menustate = MAINMENU ;
selectedoption = 3 ;
SDL_Delay ( 130 ) ;
}
else if ( selectedoption = = 30 )
{
//Return to main menu
menustate = MAINMENU ;
selectedoption = 1 ;
SDL_Delay ( 130 ) ;
}
else if ( selectedoption > 30 & & selectedoption < 40 )
{
//save to selected savestate
char save_state_file [ 256 ] ;
sprintf ( save_state_file , " %s/%s.gp%d " , get_save_directory ( ) , rom_filename , selectedoption - 30 ) ;
FILE * f = fopen ( save_state_file , " wb " ) ;
if ( f )
{
uint8 buf [ STATE_SIZE ] ;
int len = state_save ( buf ) ;
fwrite ( & buf , len , 1 , f ) ;
fclose ( f ) ;
}
//Save BMP screenshot
char save_state_screenshot [ 256 ] ;
sprintf ( save_state_screenshot , " %s/%s.%d.bmp " , get_save_directory ( ) , rom_filename , selectedoption - 30 ) ;
SDL_Surface * screenshot ;
if ( ! config . gcw0_fullscreen )
{
screenshot = SDL_CreateRGBSurface ( SDL_HWSURFACE , sdl_video . srect . w , sdl_video . srect . h , 16 , 0 , 0 , 0 , 0 ) ;
SDL_Rect temp ;
temp . x = 0 ;
temp . y = 0 ;
temp . w = sdl_video . srect . w ;
temp . h = sdl_video . srect . h ;
SDL_BlitSurface ( sdl_video . surf_bitmap , & temp , screenshot , & temp ) ;
SDL_SaveBMP ( screenshot , save_state_screenshot ) ;
SDL_FreeSurface ( screenshot ) ;
}
else
{
screenshot = SDL_CreateRGBSurface ( SDL_HWSURFACE , gcw0_w , gcw0_h , 16 , 0 , 0 , 0 , 0 ) ;
SDL_Rect temp ;
temp . x = 0 ;
temp . y = 0 ;
temp . w = gcw0_w ;
temp . h = gcw0_h ;
SDL_BlitSurface ( sdl_video . surf_bitmap , & temp , screenshot , & temp ) ;
SDL_SaveBMP ( screenshot , save_state_screenshot ) ;
SDL_FreeSurface ( screenshot ) ;
}
SDL_Delay ( 250 ) ;
if ( config . sl_autoresume )
{
menustate = MAINMENU ;
selectedoption = 0 ;
gotomenu = 0 ;
break ;
}
}
else if ( selectedoption = = 40 )
{
//return to main menu
menustate = MAINMENU ;
selectedoption = 2 ;
SDL_Delay ( 130 ) ;
}
else if ( selectedoption > 40 & & selectedoption < 50 )
{
//load selected loadstate
char save_state_file [ 256 ] ;
sprintf ( save_state_file , " %s/%s.gp%d " , get_save_directory ( ) , rom_filename , selectedoption - 40 ) ;
FILE * f = fopen ( save_state_file , " rb " ) ;
if ( f )
{
uint8 buf [ STATE_SIZE ] ;
fread ( & buf , STATE_SIZE , 1 , f ) ;
state_load ( buf ) ;
fclose ( f ) ;
}
if ( config . sl_autoresume )
{
gotomenu = 0 ;
menustate = MAINMENU ;
selectedoption = 0 ;
SDL_Delay ( 250 ) ;
break ;
}
}
else if ( selectedoption = = 50 )
{
//return to main menu
menustate = MAINMENU ;
selectedoption = 5 ;
SDL_Delay ( 130 ) ;
}
else if ( selectedoption = = 51 )
{
//toggle auto resume when save/loading
config . sl_autoresume = ! config . sl_autoresume ;
config_save ( ) ;
SDL_Delay ( 130 ) ;
}
else if ( selectedoption = = 52 )
{
//toggle A-Stick
config . a_stick = ! config . a_stick ;
config_save ( ) ;
SDL_Delay ( 130 ) ;
}
else if ( selectedoption = = 53 )
{
config . lock_on = ( + + config . lock_on = = 4 ) ? 0 : config . lock_on ;
config_save ( ) ;
SDL_Delay ( 130 ) ;
}
else if ( selectedoption = = 54 )
{
config . ym2413 = ! config . ym2413 ;
config_save ( ) ;
SDL_Delay ( 130 ) ;
}
else if ( selectedoption = = 55 )
{
config . lightgun_speed + + ;
if ( config . lightgun_speed = = 4 )
config . lightgun_speed = 1 ;
config_save ( ) ;
SDL_Delay ( 130 ) ;
}
else if ( selectedoption = = 56 )
{
config . cursor + + ;
if ( config . cursor = = 4 )
config . cursor = 0 ;
config_save ( ) ;
SDL_Delay ( 130 ) ;
}
}
else if ( menustate = = REMAP_OPTIONS )
{ // REMAP_OPTIONS needs to capture all input
SDLKey pressed_key = 0 ;
if ( keystate2 [ SDLK_RETURN ] )
pressed_key = SDLK_RETURN ;
else if ( keystate2 [ SDLK_LCTRL ] )
pressed_key = SDLK_LCTRL ;
else if ( keystate2 [ SDLK_LALT ] )
pressed_key = SDLK_LALT ;
else if ( keystate2 [ SDLK_LSHIFT ] )
pressed_key = SDLK_LSHIFT ;
else if ( keystate2 [ SDLK_SPACE ] )
pressed_key = SDLK_SPACE ;
else if ( keystate2 [ SDLK_TAB ] )
pressed_key = SDLK_TAB ;
else if ( keystate2 [ SDLK_BACKSPACE ] )
pressed_key = SDLK_BACKSPACE ;
else if ( keystate2 [ SDLK_ESCAPE ] )
pressed_key = SDLK_ESCAPE ;
if ( pressed_key )
{
if ( selectedoption = = 20 )
{
//button a remap
config . buttons [ A ] = ( pressed_key = = SDLK_ESCAPE ) ? 0 : pressed_key ;
config_save ( ) ;
SDL_Delay ( 130 ) ;
selectedoption + + ;
}
else if ( selectedoption = = 21 )
{
//button b remap
config . buttons [ B ] = ( pressed_key = = SDLK_ESCAPE ) ? 0 : pressed_key ;
config_save ( ) ;
SDL_Delay ( 130 ) ;
selectedoption + + ;
}
else if ( selectedoption = = 22 )
{
//button c remap
config . buttons [ C ] = ( pressed_key = = SDLK_ESCAPE ) ? 0 : pressed_key ;
config_save ( ) ;
SDL_Delay ( 130 ) ;
selectedoption + + ;
}
else if ( selectedoption = = 23 )
{
//button x remap
config . buttons [ X ] = ( pressed_key = = SDLK_ESCAPE ) ? 0 : pressed_key ;
config_save ( ) ;
SDL_Delay ( 130 ) ;
selectedoption + + ;
}
else if ( selectedoption = = 24 )
{
//button y remap
config . buttons [ Y ] = ( pressed_key = = SDLK_ESCAPE ) ? 0 : pressed_key ;
config_save ( ) ;
SDL_Delay ( 130 ) ;
selectedoption + + ;
}
else if ( selectedoption = = 25 )
{
//button z remap
config . buttons [ Z ] = ( pressed_key = = SDLK_ESCAPE ) ? 0 : pressed_key ;
config_save ( ) ;
SDL_Delay ( 130 ) ;
selectedoption + + ;
}
else if ( selectedoption = = 26 )
{
//button start remap
config . buttons [ START ] = ( pressed_key = = SDLK_ESCAPE ) ? 0 : pressed_key ;
config_save ( ) ;
SDL_Delay ( 130 ) ;
selectedoption + + ;
}
else if ( selectedoption = = 27 )
{
//button mode remap
config . buttons [ MODE ] = pressed_key ;
config_save ( ) ;
SDL_Delay ( 130 ) ;
selectedoption + + ;
}
else if ( selectedoption = = 28 )
{
//return to main menu
menustate = MAINMENU ;
selectedoption = 4 ;
SDL_Delay ( 130 ) ;
}
}
}
}
} //menu loop
SDL_PauseAudio ( 0 ) ;
if ( config . gcw0_fullscreen ) {
if ( ( system_hw = = SYSTEM_MARKIII ) | | ( system_hw = = SYSTEM_SMS ) | | ( system_hw = = SYSTEM_SMS2 ) | | ( system_hw = = SYSTEM_PBC ) )
{
gcw0_w = sdl_video . drect . w ;
gcw0_h = sdl_video . drect . h ;
sdl_video . surf_screen = SDL_SetVideoMode ( 256 , gcw0_h , 16 , SDL_HWSURFACE |
# ifdef SDL_TRIPLEBUF
SDL_TRIPLEBUF ) ;
# else
SDL_DOUBLEBUF ) ;
# endif
}
else
{
sdl_video . drect . w = sdl_video . srect . w ;
sdl_video . drect . h = sdl_video . srect . h ;
sdl_video . drect . x = 0 ;
sdl_video . drect . y = 0 ;
gcw0_w = sdl_video . drect . w ;
gcw0_h = sdl_video . drect . h ;
sdl_video . surf_screen = SDL_SetVideoMode ( gcw0_w , gcw0_h , 16 , SDL_HWSURFACE |
# ifdef SDL_TRIPLEBUF
SDL_TRIPLEBUF ) ;
# else
SDL_DOUBLEBUF ) ;
# endif
}
} else {
SDL_FillRect ( sdl_video . surf_screen , 0 , 0 ) ;
SDL_Flip ( sdl_video . surf_screen ) ;
SDL_FillRect ( sdl_video . surf_screen , 0 , 0 ) ;
SDL_Flip ( sdl_video . surf_screen ) ;
SDL_FillRect ( sdl_video . surf_screen , 0 , 0 ) ;
SDL_Flip ( sdl_video . surf_screen ) ;
}
return 1 ;
}
# endif
int sdl_input_update ( void )
{
uint8 * keystate = SDL_GetKeyState ( NULL ) ;
/* reset input */
input . pad [ joynum ] = 0 ;
if ( show_lightgun )
input . pad [ 4 ] = 0 ; //player2:
switch ( input . dev [ 4 ] )
{
case DEVICE_LIGHTGUN :
show_lightgun = 1 ;
/* get mouse coordinates (absolute values) */
int x , y ;
int state = SDL_GetMouseState ( & x , & y ) ;
if ( config . gcw0_fullscreen )
{
input . analog [ 4 ] [ 0 ] = x ;
input . analog [ 4 ] [ 1 ] = y ;
} else
{
input . analog [ 4 ] [ 0 ] = x - ( VIDEO_WIDTH - bitmap . viewport . w ) / 2 ;
input . analog [ 4 ] [ 1 ] = y - ( VIDEO_HEIGHT - bitmap . viewport . h ) / 2 ;
}
if ( config . smsmaskleftbar ) x + = 8 ;
/* TRIGGER, B, C (Menacer only), START (Menacer & Justifier only) */
if ( keystate [ SDLK_ESCAPE ] ) input . pad [ 4 ] | = INPUT_START ;
default :
break ;
}
switch ( input . dev [ joynum ] )
{
case DEVICE_LIGHTGUN :
{
# ifdef GCWZERO
show_lightgun = 2 ;
/* get mouse coordinates (absolute values) */
int x , y ;
int state = SDL_GetMouseState ( & x , & y ) ;
if ( config . gcw0_fullscreen )
{
input . analog [ 0 ] [ 0 ] = x ;
input . analog [ 0 ] [ 1 ] = y ;
} else
{
input . analog [ 0 ] [ 0 ] = x - ( VIDEO_WIDTH - bitmap . viewport . w ) / 2 ;
input . analog [ 0 ] [ 1 ] = y - ( VIDEO_HEIGHT - bitmap . viewport . h ) / 2 ;
}
if ( config . smsmaskleftbar ) x + = 8 ;
/* TRIGGER, B, C (Menacer only), START (Menacer & Justifier only) */
if ( state & SDL_BUTTON_LMASK ) input . pad [ joynum ] | = INPUT_A ;
if ( state & SDL_BUTTON_RMASK ) input . pad [ joynum ] | = INPUT_B ;
if ( state & SDL_BUTTON_MMASK ) input . pad [ joynum ] | = INPUT_C ;
if ( keystate [ SDLK_ESCAPE ] ) input . pad [ 0 ] | = INPUT_START ;
# else
/* get mouse coordinates (absolute values) */
int x , y ;
int state = SDL_GetMouseState ( & x , & y ) ;
/* X axis */
input . analog [ joynum ] [ 0 ] = x - ( VIDEO_WIDTH - bitmap . viewport . w ) / 2 ;
/* Y axis */
input . analog [ joynum ] [ 1 ] = y - ( VIDEO_HEIGHT - bitmap . viewport . h ) / 2 ;
/* TRIGGER, B, C (Menacer only), START (Menacer & Justifier only) */
if ( state & SDL_BUTTON_LMASK ) input . pad [ joynum ] | = INPUT_A ;
if ( state & SDL_BUTTON_RMASK ) input . pad [ joynum ] | = INPUT_B ;
if ( state & SDL_BUTTON_MMASK ) input . pad [ joynum ] | = INPUT_C ;
if ( keystate [ SDLK_f ] ) input . pad [ joynum ] | = INPUT_START ;
break ;
# endif
}
# ifndef GCWZERO
case DEVICE_PADDLE :
{
/* get mouse (absolute values) */
int x ;
int state = SDL_GetMouseState ( & x , NULL ) ;
/* Range is [0;256], 128 being middle position */
input . analog [ joynum ] [ 0 ] = x * 256 / VIDEO_WIDTH ;
/* Button I -> 0 0 0 0 0 0 0 I*/
if ( state & SDL_BUTTON_LMASK ) input . pad [ joynum ] | = INPUT_B ;
break ;
}
case DEVICE_SPORTSPAD :
{
/* get mouse (relative values) */
int x , y ;
int state = SDL_GetRelativeMouseState ( & x , & y ) ;
/* Range is [0;256] */
input . analog [ joynum ] [ 0 ] = ( unsigned char ) ( - x & 0xFF ) ;
input . analog [ joynum ] [ 1 ] = ( unsigned char ) ( - y & 0xFF ) ;
/* Buttons I & II -> 0 0 0 0 0 0 II I*/
if ( state & SDL_BUTTON_LMASK ) input . pad [ joynum ] | = INPUT_B ;
if ( state & SDL_BUTTON_RMASK ) input . pad [ joynum ] | = INPUT_C ;
break ;
}
case DEVICE_MOUSE :
{
SDL_ShowCursor ( 1 ) ;
/* get mouse (relative values) */
int x , y ;
int state = SDL_GetRelativeMouseState ( & x , & y ) ;
/* Sega Mouse range is [-256;+256] */
input . analog [ joynum ] [ 0 ] = x * 2 ;
input . analog [ joynum ] [ 1 ] = y * 2 ;
/* Vertical movement is upsidedown */
if ( ! config . invert_mouse )
input . analog [ joynum ] [ 1 ] = 0 - input . analog [ joynum ] [ 1 ] ;
/* Start,Left,Right,Middle buttons -> 0 0 0 0 START MIDDLE RIGHT LEFT */
if ( state & SDL_BUTTON_LMASK ) input . pad [ joynum ] | = INPUT_B ;
if ( state & SDL_BUTTON_RMASK ) input . pad [ joynum ] | = INPUT_C ;
if ( state & SDL_BUTTON_MMASK ) input . pad [ joynum ] | = INPUT_A ;
if ( keystate [ SDLK_f ] ) input . pad [ joynum ] | = INPUT_START ;
break ;
}
case DEVICE_XE_1AP :
{
/* A,B,C,D,Select,START,E1,E2 buttons -> E1(?) E2(?) START SELECT(?) A B C D */
if ( keystate [ SDLK_a ] ) input . pad [ joynum ] | = INPUT_START ;
if ( keystate [ SDLK_s ] ) input . pad [ joynum ] | = INPUT_A ;
if ( keystate [ SDLK_d ] ) input . pad [ joynum ] | = INPUT_C ;
if ( keystate [ SDLK_f ] ) input . pad [ joynum ] | = INPUT_Y ;
if ( keystate [ SDLK_z ] ) input . pad [ joynum ] | = INPUT_B ;
if ( keystate [ SDLK_x ] ) input . pad [ joynum ] | = INPUT_X ;
if ( keystate [ SDLK_c ] ) input . pad [ joynum ] | = INPUT_MODE ;
if ( keystate [ SDLK_v ] ) input . pad [ joynum ] | = INPUT_Z ;
/* Left Analog Stick (bidirectional) */
if ( keystate [ SDLK_UP ] ) input . analog [ joynum ] [ 1 ] - = 2 ;
else if ( keystate [ SDLK_DOWN ] ) input . analog [ joynum ] [ 1 ] + = 2 ;
else input . analog [ joynum ] [ 1 ] = 128 ;
if ( keystate [ SDLK_LEFT ] ) input . analog [ joynum ] [ 0 ] - = 2 ;
else if ( keystate [ SDLK_RIGHT ] ) input . analog [ joynum ] [ 0 ] + = 2 ;
else input . analog [ joynum ] [ 0 ] = 128 ;
/* Right Analog Stick (unidirectional) */
if ( keystate [ SDLK_KP8 ] ) input . analog [ joynum + 1 ] [ 0 ] - = 2 ;
else if ( keystate [ SDLK_KP2 ] ) input . analog [ joynum + 1 ] [ 0 ] + = 2 ;
else if ( keystate [ SDLK_KP4 ] ) input . analog [ joynum + 1 ] [ 0 ] - = 2 ;
else if ( keystate [ SDLK_KP6 ] ) input . analog [ joynum + 1 ] [ 0 ] + = 2 ;
else input . analog [ joynum + 1 ] [ 0 ] = 128 ;
/* Limiters */
if ( input . analog [ joynum ] [ 0 ] > 0xFF ) input . analog [ joynum ] [ 0 ] = 0xFF ;
else if ( input . analog [ joynum ] [ 0 ] < 0 ) input . analog [ joynum ] [ 0 ] = 0 ;
if ( input . analog [ joynum ] [ 1 ] > 0xFF ) input . analog [ joynum ] [ 1 ] = 0xFF ;
else if ( input . analog [ joynum ] [ 1 ] < 0 ) input . analog [ joynum ] [ 1 ] = 0 ;
if ( input . analog [ joynum + 1 ] [ 0 ] > 0xFF ) input . analog [ joynum + 1 ] [ 0 ] = 0xFF ;
else if ( input . analog [ joynum + 1 ] [ 0 ] < 0 ) input . analog [ joynum + 1 ] [ 0 ] = 0 ;
if ( input . analog [ joynum + 1 ] [ 1 ] > 0xFF ) input . analog [ joynum + 1 ] [ 1 ] = 0xFF ;
else if ( input . analog [ joynum + 1 ] [ 1 ] < 0 ) input . analog [ joynum + 1 ] [ 1 ] = 0 ;
break ;
}
case DEVICE_PICO :
{
/* get mouse (absolute values) */
int x , y ;
int state = SDL_GetMouseState ( & x , & y ) ;
/* Calculate X Y axis values */
input . analog [ 0 ] [ 0 ] = 0x3c + ( x * ( 0x17c - 0x03c + 1 ) ) / VIDEO_WIDTH ;
input . analog [ 0 ] [ 1 ] = 0x1fc + ( y * ( 0x2f7 - 0x1fc + 1 ) ) / VIDEO_HEIGHT ;
/* Map mouse buttons to player #1 inputs */
if ( state & SDL_BUTTON_MMASK ) pico_current = ( pico_current + 1 ) & 7 ;
if ( state & SDL_BUTTON_RMASK ) input . pad [ 0 ] | = INPUT_PICO_RED ;
if ( state & SDL_BUTTON_LMASK ) input . pad [ 0 ] | = INPUT_PICO_PEN ;
break ;
}
case DEVICE_TEREBI :
{
/* get mouse (absolute values) */
int x , y ;
int state = SDL_GetMouseState ( & x , & y ) ;
/* Calculate X Y axis values */
input . analog [ 0 ] [ 0 ] = ( x * 250 ) / VIDEO_WIDTH ;
input . analog [ 0 ] [ 1 ] = ( y * 250 ) / VIDEO_HEIGHT ;
/* Map mouse buttons to player #1 inputs */
if ( state & SDL_BUTTON_RMASK ) input . pad [ 0 ] | = INPUT_B ;
break ;
}
case DEVICE_GRAPHIC_BOARD :
{
/* get mouse (absolute values) */
int x , y ;
int state = SDL_GetMouseState ( & x , & y ) ;
/* Calculate X Y axis values */
input . analog [ 0 ] [ 0 ] = ( x * 255 ) / VIDEO_WIDTH ;
input . analog [ 0 ] [ 1 ] = ( y * 255 ) / VIDEO_HEIGHT ;
/* Map mouse buttons to player #1 inputs */
if ( state & SDL_BUTTON_LMASK ) input . pad [ 0 ] | = INPUT_GRAPHIC_PEN ;
if ( state & SDL_BUTTON_RMASK ) input . pad [ 0 ] | = INPUT_GRAPHIC_MENU ;
if ( state & SDL_BUTTON_MMASK ) input . pad [ 0 ] | = INPUT_GRAPHIC_DO ;
break ;
}
case DEVICE_ACTIVATOR :
{
if ( keystate [ SDLK_g ] ) input . pad [ joynum ] | = INPUT_ACTIVATOR_7L ;
if ( keystate [ SDLK_h ] ) input . pad [ joynum ] | = INPUT_ACTIVATOR_7U ;
if ( keystate [ SDLK_j ] ) input . pad [ joynum ] | = INPUT_ACTIVATOR_8L ;
if ( keystate [ SDLK_k ] ) input . pad [ joynum ] | = INPUT_ACTIVATOR_8U ;
}
# endif
default :
{
# ifdef GCWZERO
if ( keystate [ config . buttons [ A ] ] ) input . pad [ joynum ] | = INPUT_A ;
if ( keystate [ config . buttons [ B ] ] ) input . pad [ joynum ] | = INPUT_B ;
if ( keystate [ config . buttons [ C ] ] ) input . pad [ joynum ] | = INPUT_C ;
if ( keystate [ config . buttons [ START ] ] ) input . pad [ joynum ] | = INPUT_START ;
if ( show_lightgun = = 1 )
{
if ( keystate [ config . buttons [ X ] ] ) input . pad [ 4 ] | = INPUT_A ; //player 2
if ( keystate [ config . buttons [ Y ] ] ) input . pad [ 4 ] | = INPUT_B ; //player 2
if ( keystate [ config . buttons [ Z ] ] ) input . pad [ 4 ] | = INPUT_C ; //player 2
} else
if ( show_lightgun = = 2 )
{
if ( keystate [ config . buttons [ X ] ] ) input . pad [ 4 ] | = INPUT_A ; //player 2
if ( keystate [ config . buttons [ Y ] ] ) input . pad [ 4 ] | = INPUT_B ; //player 2
if ( keystate [ config . buttons [ Z ] ] ) input . pad [ 4 ] | = INPUT_C ; //player 2
} else
{
if ( keystate [ config . buttons [ X ] ] ) input . pad [ joynum ] | = INPUT_X ;
if ( keystate [ config . buttons [ Y ] ] ) input . pad [ joynum ] | = INPUT_Y ;
if ( keystate [ config . buttons [ Z ] ] ) input . pad [ joynum ] | = INPUT_Z ;
}
if ( keystate [ config . buttons [ MODE ] ] ) input . pad [ joynum ] | = INPUT_MODE ;
if ( keystate [ SDLK_ESCAPE ] & & keystate [ SDLK_RETURN ] )
{
gotomenu = 1 ;
}
if ( keystate [ SDLK_ESCAPE ] & & keystate [ SDLK_TAB ] )
{
//save to quicksave slot
char save_state_file [ 256 ] ;
sprintf ( save_state_file , " %s/%s.gp1 " , get_save_directory ( ) , rom_filename ) ;
FILE * f = fopen ( save_state_file , " wb " ) ;
if ( f )
{
uint8 buf [ STATE_SIZE ] ;
int len = state_save ( buf ) ;
fwrite ( & buf , len , 1 , f ) ;
fclose ( f ) ;
}
//Save BMP screenshot
char save_state_screenshot [ 256 ] ;
sprintf ( save_state_screenshot , " %s/%s.1.bmp " , get_save_directory ( ) , rom_filename ) ;
SDL_Surface * screenshot ;
if ( ! config . gcw0_fullscreen )
{
screenshot = SDL_CreateRGBSurface ( SDL_HWSURFACE , sdl_video . srect . w , sdl_video . srect . h , 16 , 0 , 0 , 0 , 0 ) ;
SDL_Rect temp ;
temp . x = 0 ;
temp . y = 0 ;
temp . w = sdl_video . srect . w ;
temp . h = sdl_video . srect . h ;
SDL_BlitSurface ( sdl_video . surf_bitmap , & temp , screenshot , & temp ) ;
SDL_SaveBMP ( screenshot , save_state_screenshot ) ;
SDL_FreeSurface ( screenshot ) ;
}
else
{
screenshot = SDL_CreateRGBSurface ( SDL_HWSURFACE , gcw0_w , gcw0_h , 16 , 0 , 0 , 0 , 0 ) ;
SDL_Rect temp ;
temp . x = 0 ;
temp . y = 0 ;
temp . w = gcw0_w ;
temp . h = gcw0_h ;
SDL_BlitSurface ( sdl_video . surf_bitmap , & temp , screenshot , & temp ) ;
SDL_SaveBMP ( screenshot , save_state_screenshot ) ;
SDL_FreeSurface ( screenshot ) ;
}
SDL_Delay ( 250 ) ;
}
if ( keystate [ SDLK_ESCAPE ] & & keystate [ SDLK_BACKSPACE ] )
{
//load quicksave slot
char save_state_file [ 256 ] ;
sprintf ( save_state_file , " %s/%s.gp1 " , get_save_directory ( ) , rom_filename ) ;
FILE * f = fopen ( save_state_file , " rb " ) ;
if ( f )
{
uint8 buf [ STATE_SIZE ] ;
fread ( & buf , STATE_SIZE , 1 , f ) ;
state_load ( buf ) ;
fclose ( f ) ;
}
SDL_Delay ( 250 ) ;
}
# else
if ( keystate [ SDLK_a ] ) input . pad [ joynum ] | = INPUT_A ;
if ( keystate [ SDLK_s ] ) input . pad [ joynum ] | = INPUT_B ;
if ( keystate [ SDLK_d ] ) input . pad [ joynum ] | = INPUT_C ;
if ( keystate [ SDLK_f ] ) input . pad [ joynum ] | = INPUT_START ;
if ( keystate [ SDLK_z ] ) input . pad [ joynum ] | = INPUT_X ;
if ( keystate [ SDLK_x ] ) input . pad [ joynum ] | = INPUT_Y ;
if ( keystate [ SDLK_c ] ) input . pad [ joynum ] | = INPUT_Z ;
if ( keystate [ SDLK_v ] ) input . pad [ joynum ] | = INPUT_MODE ;
# endif
# ifdef GCWZERO //A-stick support
static int MoveLeft = 0 ;
static int MoveRight = 0 ;
static int MoveUp = 0 ;
static int MoveDown = 0 ;
Sint16 x_move = 0 ;
Sint16 y_move = 0 ;
static int lg_left = 0 ;
static int lg_right = 0 ;
static int lg_up = 0 ;
static int lg_down = 0 ;
SDL_Joystick * joy ;
if ( SDL_NumJoysticks ( ) > 0 )
{
joy = SDL_JoystickOpen ( 0 ) ;
x_move = SDL_JoystickGetAxis ( joy , 0 ) ;
y_move = SDL_JoystickGetAxis ( joy , 1 ) ;
}
// Control lightgun with A-stick if activated
if ( show_lightgun )
{
lg_left = 0 ;
lg_right = 0 ;
lg_up = 0 ;
lg_down = 0 ;
if ( x_move < - 1000 | | x_move > 1000 )
{
if ( x_move < - 1000 ) lg_left = 1 ;
if ( x_move < - 20000 ) lg_left = 3 ;
if ( x_move > 1000 ) lg_right = 1 ;
if ( x_move > 20000 ) lg_right = 3 ;
current_time = time ( NULL ) ; //cursor disappears after 3 seconds...
}
if ( y_move < - 1000 | | y_move > 1000 )
{
if ( y_move < - 1000 ) lg_up = 1 ;
if ( y_move < - 20000 ) lg_up = 3 ;
if ( y_move > 1000 ) lg_down = 1 ;
if ( y_move > 20000 ) lg_down = 3 ;
current_time = time ( NULL ) ;
}
// Keep mouse within screen, wrap around!
int x , y ;
int state = SDL_GetMouseState ( & x , & y ) ;
if ( ! config . gcw0_fullscreen )
{
if ( ( x - lg_left ) < sdl_video . drect . x ) x = VIDEO_WIDTH - sdl_video . drect . x ;
if ( ( y - lg_up ) < sdl_video . drect . y ) y = VIDEO_HEIGHT - sdl_video . drect . y ;
// if ((x + lg_right) > 288) x = 288;
// if ((y + lg_down ) > 216) y = 216;
// if ((x + lg_right) > 320) x = 320;
// if ((y + lg_down ) > 240) y = 240;
if ( ( x + lg_right ) > VIDEO_WIDTH - sdl_video . drect . x ) x = sdl_video . drect . x ;
if ( ( y + lg_down ) > VIDEO_HEIGHT - sdl_video . drect . y ) y = sdl_video . drect . y ;
// sdl_video.drect.x = (VIDEO_WIDTH - sdl_video.drect.w) / 2;
// sdl_video.drect.y = (VIDEO_HEIGHT - sdl_video.drect.h) / 2;
} else //scaling on
{
if ( ( x - lg_left ) < 0 ) x = gcw0_w ;
if ( ( y - lg_up ) < 0 ) y = gcw0_h ;
if ( ( x + lg_right ) > gcw0_w ) x = 0 ;
if ( ( y + lg_down ) > gcw0_h ) y = 0 ;
}
SDL_WarpMouse ( ( x + ( ( lg_right - lg_left ) * config . lightgun_speed ) ) ,
( y + ( ( lg_down - lg_up ) * config . lightgun_speed ) ) ) ;
} else
// otherwise it's just mirroring the D-pad controls
if ( config . a_stick )
{
MoveLeft = 0 ;
MoveRight = 0 ;
MoveUp = 0 ;
MoveDown = 0 ;
if ( x_move < - 1000 | | x_move > 1000 )
{
if ( x_move < - 1000 ) MoveLeft = 1 ;
if ( x_move > 1000 ) MoveRight = 1 ;
}
if ( y_move < - 1000 | | y_move > 1000 )
{
if ( y_move < - 1000 ) MoveUp = 1 ;
if ( y_move > 1000 ) MoveDown = 1 ;
}
}
if ( show_lightgun = = 1 ) //Genesis/MD D-pad controls player 2
{
if ( MoveUp = = 1 ) input . pad [ 4 ] | = INPUT_UP ;
if ( MoveDown = = 1 ) input . pad [ 4 ] | = INPUT_DOWN ;
if ( MoveLeft = = 1 ) input . pad [ 4 ] | = INPUT_LEFT ;
if ( MoveRight = = 1 ) input . pad [ 4 ] | = INPUT_RIGHT ;
if ( keystate [ SDLK_UP ] = = 1 ) input . pad [ joynum ] | = INPUT_UP ;
if ( keystate [ SDLK_DOWN ] = = 1 ) input . pad [ joynum ] | = INPUT_DOWN ;
if ( keystate [ SDLK_LEFT ] = = 1 ) input . pad [ joynum ] | = INPUT_LEFT ;
if ( keystate [ SDLK_RIGHT ] = = 1 ) input . pad [ joynum ] | = INPUT_RIGHT ;
} else
if ( show_lightgun = = 2 ) //SMS D-pad controls player 2
{
if ( MoveUp = = 1 ) input . pad [ joynum ] | = INPUT_UP ;
if ( MoveDown = = 1 ) input . pad [ joynum ] | = INPUT_DOWN ;
if ( MoveLeft = = 1 ) input . pad [ joynum ] | = INPUT_LEFT ;
if ( MoveRight = = 1 ) input . pad [ joynum ] | = INPUT_RIGHT ;
if ( keystate [ SDLK_UP ] = = 1 ) input . pad [ 4 ] | = INPUT_UP ;
if ( keystate [ SDLK_DOWN ] = = 1 ) input . pad [ 4 ] | = INPUT_DOWN ;
if ( keystate [ SDLK_LEFT ] = = 1 ) input . pad [ 4 ] | = INPUT_LEFT ;
if ( keystate [ SDLK_RIGHT ] = = 1 ) input . pad [ 4 ] | = INPUT_RIGHT ;
} else
{
if ( keystate [ SDLK_UP ] | | MoveUp = = 1 ) input . pad [ joynum ] | = INPUT_UP ;
else if ( keystate [ SDLK_DOWN ] | | MoveDown = = 1 ) input . pad [ joynum ] | = INPUT_DOWN ;
if ( keystate [ SDLK_LEFT ] | | MoveLeft = = 1 ) input . pad [ joynum ] | = INPUT_LEFT ;
else if ( keystate [ SDLK_RIGHT ] | | MoveRight = = 1 ) input . pad [ joynum ] | = INPUT_RIGHT ;
}
# else
if ( keystate [ SDLK_UP ] ) input . pad [ joynum ] | = INPUT_UP ;
else if ( keystate [ SDLK_DOWN ] ) input . pad [ joynum ] | = INPUT_DOWN ;
if ( keystate [ SDLK_LEFT ] ) input . pad [ joynum ] | = INPUT_LEFT ;
else if ( keystate [ SDLK_RIGHT ] ) input . pad [ joynum ] | = INPUT_RIGHT ;
# endif
}
}
return 1 ;
}
int main ( int argc , char * * argv )
{
FILE * fp ;
int running = 1 ;
atexit ( shutdown ) ;
/* Print help if no game specified */
if ( argc < 2 )
{
char caption [ 256 ] ;
sprintf ( caption , " Genesis Plus GX \\ SDL \n usage: %s gamename \n " , argv [ 0 ] ) ;
MessageBox ( NULL , caption , " Information " , 0 ) ;
exit ( 1 ) ;
}
error_init ( ) ;
create_default_directories ( ) ;
/* set default config */
set_config_defaults ( ) ;
/* using rom file name instead of crc code to save files */
sprintf ( rom_filename , " %s " , get_file_name ( argv [ 1 ] ) ) ;
/* mark all BIOS as unloaded */
system_bios = 0 ;
/* Genesis BOOT ROM support (2KB max) */
memset ( boot_rom , 0xFF , 0x800 ) ;
fp = fopen ( MD_BIOS , " rb " ) ;
if ( fp ! = NULL )
{
int i ;
/* read BOOT ROM */
fread ( boot_rom , 1 , 0x800 , fp ) ;
fclose ( fp ) ;
/* check BOOT ROM */
if ( ! memcmp ( ( char * ) ( boot_rom + 0x120 ) , " GENESIS OS " , 10 ) )
{
/* mark Genesis BIOS as loaded */
system_bios = SYSTEM_MD ;
}
/* Byteswap ROM */
for ( i = 0 ; i < 0x800 ; i + = 2 )
{
uint8 temp = boot_rom [ i ] ;
boot_rom [ i ] = boot_rom [ i + 1 ] ;
boot_rom [ i + 1 ] = temp ;
}
}
/* initialize SDL */
if ( SDL_Init ( 0 ) < 0 )
{
char caption [ 256 ] ;
sprintf ( caption , " SDL initialization failed " ) ;
MessageBox ( NULL , caption , " Error " , 0 ) ;
exit ( 1 ) ;
}
# ifdef GCWZERO
sdl_joystick_init ( ) ;
# endif
sdl_video_init ( ) ;
if ( use_sound ) sdl_sound_init ( ) ;
sdl_sync_init ( ) ;
/* initialize Genesis virtual system */
SDL_LockSurface ( sdl_video . surf_bitmap ) ;
memset ( & bitmap , 0 , sizeof ( t_bitmap ) ) ;
bitmap . width = 720 ;
bitmap . height = 576 ;
# if defined(USE_8BPP_RENDERING)
bitmap . pitch = ( bitmap . width * 1 ) ;
# elif defined(USE_15BPP_RENDERING)
bitmap . pitch = ( bitmap . width * 2 ) ;
# elif defined(USE_16BPP_RENDERING)
bitmap . pitch = ( bitmap . width * 2 ) ;
# elif defined(USE_32BPP_RENDERING)
bitmap . pitch = ( bitmap . width * 4 ) ;
# endif
bitmap . data = sdl_video . surf_bitmap - > pixels ;
SDL_UnlockSurface ( sdl_video . surf_bitmap ) ;
bitmap . viewport . changed = 3 ;
/* Load game file */
if ( ! load_rom ( argv [ 1 ] ) )
{
char caption [ 256 ] ;
sprintf ( caption , " Error loading file `%s'. " , argv [ 1 ] ) ;
MessageBox ( NULL , caption , " Error " , 0 ) ;
exit ( 1 ) ;
}
/* initialize system hardware */
//NOTE gcw0 second value determines framerate
audio_init ( SOUND_FREQUENCY , 0 ) ;
system_init ( ) ;
/* Mega CD specific */
char brm_file [ 256 ] ;
if ( system_hw = = SYSTEM_MCD )
{
/* load internal backup RAM */
sprintf ( brm_file , " %s/ " , get_save_directory ( ) , " scd.brm " ) ;
fp = fopen ( brm_file , " rb " ) ;
if ( fp ! = NULL )
{
fread ( scd . bram , 0x2000 , 1 , fp ) ;
fclose ( fp ) ;
}
/* check if internal backup RAM is formatted */
if ( memcmp ( scd . bram + 0x2000 - 0x20 , brm_format + 0x20 , 0x20 ) )
{
/* clear internal backup RAM */
memset ( scd . bram , 0x00 , 0x200 ) ;
/* Internal Backup RAM size fields */
brm_format [ 0x10 ] = brm_format [ 0x12 ] = brm_format [ 0x14 ] = brm_format [ 0x16 ] = 0x00 ;
brm_format [ 0x11 ] = brm_format [ 0x13 ] = brm_format [ 0x15 ] = brm_format [ 0x17 ] = ( sizeof ( scd . bram ) / 64 ) - 3 ;
/* format internal backup RAM */
memcpy ( scd . bram + 0x2000 - 0x40 , brm_format , 0x40 ) ;
}
/* load cartridge backup RAM */
if ( scd . cartridge . id )
{
sprintf ( brm_file , " %s/ " , get_save_directory ( ) , " cart.brm " ) ;
fp = fopen ( brm_file , " rb " ) ;
if ( fp ! = NULL )
{
fread ( scd . cartridge . area , scd . cartridge . mask + 1 , 1 , fp ) ;
fclose ( fp ) ;
}
/* check if cartridge backup RAM is formatted */
if ( memcmp ( scd . cartridge . area + scd . cartridge . mask + 1 - 0x20 , brm_format + 0x20 , 0x20 ) )
{
/* clear cartridge backup RAM */
memset ( scd . cartridge . area , 0x00 , scd . cartridge . mask + 1 ) ;
/* Cartridge Backup RAM size fields */
brm_format [ 0x10 ] = brm_format [ 0x12 ] = brm_format [ 0x14 ] = brm_format [ 0x16 ] = ( ( ( scd . cartridge . mask + 1 ) / 64 ) - 3 ) > > 8 ;
brm_format [ 0x11 ] = brm_format [ 0x13 ] = brm_format [ 0x15 ] = brm_format [ 0x17 ] = ( ( ( scd . cartridge . mask + 1 ) / 64 ) - 3 ) & 0xff ;
/* format cartridge backup RAM */
memcpy ( scd . cartridge . area + scd . cartridge . mask + 1 - sizeof ( brm_format ) , brm_format , sizeof ( brm_format ) ) ;
}
}
}
if ( sram . on )
{
/* load SRAM */
char save_file [ 256 ] ;
sprintf ( save_file , " %s/%s.srm " , get_save_directory ( ) , rom_filename ) ;
fp = fopen ( save_file , " rb " ) ;
if ( fp ! = NULL )
{
fread ( sram . sram , 0x10000 , 1 , fp ) ;
fclose ( fp ) ;
}
}
/* reset system hardware */
system_reset ( ) ;
if ( use_sound ) SDL_PauseAudio ( 0 ) ;
/* 3 frames = 50 ms (60hz) or 60 ms (50hz) */
if ( sdl_sync . sem_sync )
SDL_SetTimer ( vdp_pal ? 60 : 50 , sdl_sync_timer_callback ) ;
/* emulation loop */
while ( running )
{
SDL_Event event ;
if ( SDL_PollEvent ( & event ) )
{
switch ( event . type )
{
case SDL_USEREVENT :
{
char caption [ 100 ] ;
sprintf ( caption , " Genesis Plus GX - %d fps - %s) " , event . user . code , ( rominfo . international [ 0 ] ! = 0x20 ) ? rominfo . international : rominfo . domestic ) ;
SDL_WM_SetCaption ( caption , NULL ) ;
break ;
}
case SDL_QUIT :
{
running = 0 ;
break ;
}
case SDL_KEYDOWN :
{
running = sdl_control_update ( event . key . keysym . sym ) ;
break ;
}
}
}
# ifdef GCWZERO
if ( do_once )
{
do_once - - ; //don't waste write cycles!
if ( config . keepaspectratio )
{
FILE * aspect_ratio_file = fopen ( " /sys/devices/platform/jz-lcd.0/keep_aspect_ratio " , " w " ) ;
if ( aspect_ratio_file )
{
fwrite ( " Y " , 1 , 1 , aspect_ratio_file ) ;
fclose ( aspect_ratio_file ) ;
}
}
if ( ! config . keepaspectratio )
{
FILE * aspect_ratio_file = fopen ( " /sys/devices/platform/jz-lcd.0/keep_aspect_ratio " , " w " ) ;
if ( aspect_ratio_file )
{
fwrite ( " N " , 1 , 1 , aspect_ratio_file ) ;
fclose ( aspect_ratio_file ) ;
}
}
}
# endif
sdl_video_update ( ) ;
sdl_sound_update ( use_sound ) ;
if ( ! turbo_mode & & sdl_sync . sem_sync & & sdl_video . frames_rendered % 3 = = 0 )
{
if ( ! config . gcw0_frameskip | | ( config . gcw0_frameskip & & ( system_hw ! = SYSTEM_MCD ) ) ) //we really only need this for fmv sequences
if ( ! gotomenu )
SDL_SemWait ( sdl_sync . sem_sync ) ;
# ifdef GCWZERO
}
else
{
if ( gotomenu )
gcw0menu ( ) ;
# endif
}
}
return 0 ;
}