Genesis-Plus-GX/gcw0/main.c

2586 lines
84 KiB
C

#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);
}
else if ( (system_hw == SYSTEM_SG)|| (system_hw == SYSTEM_SGII) || (system_hw == SYSTEM_SGII_RAM_EXT) ) //SG-1000 I&II
{
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\nusage: %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;
}