Genesis-Plus-GX/source/gx/main.c
ekeeke31 8af85558d0 .fixed YM2413 context restore when changing options
.added YM2413 context to Master System savestates
.removed support for older savestates format (1.3.x, 1.4.x), use 1.5.0 to convert old savestates to new (1.5.x) format
2011-04-30 12:56:01 +00:00

418 lines
10 KiB
C

/****************************************************************************
* main.c
*
* Genesis Plus GX
*
* Softdev (2006)
* Eke-Eke (2007-2010)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
***************************************************************************/
#include "shared.h"
#include "font.h"
#include "gui.h"
#include "menu.h"
#include "aram.h"
#include "history.h"
#include "file_slot.h"
#include "file_load.h"
#include "filesel.h"
#include "cheats.h"
#include <fat.h>
#ifdef HW_RVL
#include <wiiuse/wpad.h>
#endif
/* audio "exact" samplerate, measured on real hardware */
#ifdef HW_RVL
#define SAMPLERATE_48KHZ 48000
#else
#define SAMPLERATE_48KHZ 48044
#endif
u32 Shutdown = 0;
u32 ConfigRequested = 1;
#ifdef HW_RVL
/****************************************************************************
* Power Button callback
***************************************************************************/
static void PowerOff_cb(void)
{
Shutdown = 1;
ConfigRequested = 1;
}
#endif
/****************************************************************************
* Reset Button callback
***************************************************************************/
static void Reset_cb(void)
{
gen_reset(0);
}
/***************************************************************************
* Genesis Plus Virtual Machine
*
***************************************************************************/
static void load_bios(void)
{
/* clear BIOS detection flag */
config.tmss &= ~2;
/* open BIOS file */
FILE *fp = fopen(OS_ROM, "rb");
if (fp == NULL) return;
/* read file */
fread(bios_rom, 1, 0x800, fp);
fclose(fp);
/* check ROM file */
if (!strncmp((char *)(bios_rom + 0x120),"GENESIS OS", 10))
{
/* valid BIOS detected */
config.tmss |= 2;
}
}
static void init_machine(void)
{
/* allocate cart.rom here (10 MBytes) */
cart.rom = memalign(32, MAXROMSIZE);
if (!cart.rom)
{
FONT_writeCenter("Failed to allocate ROM buffer... Rebooting",18,0,640,200,(GXColor)WHITE);
gxSetScreen();
sleep(2);
gx_audio_Shutdown();
gx_video_Shutdown();
#ifdef HW_RVL
DI_Close();
SYS_ResetSystem(SYS_RESTART,0,0);
#else
SYS_ResetSystem(SYS_HOTRESET,0,0);
#endif
}
/* BIOS support */
load_bios();
/* allocate global work bitmap */
memset (&bitmap, 0, sizeof (bitmap));
bitmap.width = 720;
bitmap.height = 576;
bitmap.depth = 16;
bitmap.granularity = 2;
bitmap.pitch = bitmap.width * bitmap.granularity;
bitmap.viewport.w = 256;
bitmap.viewport.h = 224;
bitmap.viewport.x = 0;
bitmap.viewport.y = 0;
bitmap.data = texturemem;
}
static void run_emulation(void)
{
/* main emulation loop */
while (1)
{
/* Main Menu request */
if (ConfigRequested)
{
/* stop video & audio */
gx_audio_Stop();
gx_video_Stop();
/* show menu */
menu_execute();
ConfigRequested = 0;
/* start video & audio */
gx_video_Start();
gx_audio_Start();
frameticker = 1;
}
/* automatic frame skipping */
if (frameticker > 1)
{
/* skip frame */
system_frame(1);
frameticker = 1;
}
else
{
/* render frame */
frameticker = 0;
system_frame(0);
/* update video */
gx_video_Update();
}
/* update audio */
gx_audio_Update();
/* check interlaced mode change */
if (bitmap.viewport.changed & 4)
{
/* VSYNC "original" mode */
if (!config.render && (gc_pal == vdp_pal))
{
/* framerate has changed, reinitialize audio timings */
if (vdp_pal)
{
audio_init(SAMPLERATE_48KHZ, interlaced ? 50.00 : (1000000.0/19968.0));
}
else
{
audio_init(SAMPLERATE_48KHZ, interlaced ? 59.94 : (1000000.0/16715.0));
}
/* reinitialize sound chips */
sound_restore();
}
/* clear flag */
bitmap.viewport.changed &= ~4;
}
/* wait for next frame */
while (frameticker < 1) usleep(1);
}
}
/**************************************************
Load a new rom and performs some initialization
***************************************************/
void reloadrom (int size, char *name)
{
/* hot-swap previous & current cartridge */
bool hotswap = config.hot_swap && cart.romsize;
/* ROM size */
cart.romsize = size;
/* load ROM file */
load_rom(name);
/* ROM filename without extension*/
sprintf(rom_filename,"%s",name);
int i = strlen(rom_filename) - 1;
while ((i > 0) && (rom_filename[i] != '.')) i--;
if (i > 0) rom_filename[i] = 0;
if (hotswap)
{
if (system_hw == SYSTEM_PBC)
{
sms_cart_init();
sms_cart_reset();
}
else
{
md_cart_init();
md_cart_reset(1);
}
}
else
{
/* Initialize audio emulation */
/* To prevent any sound skipping, sound chips must run at the exact same speed as the rest of emulation (see sound.c) */
/* When TV output mode matches emulated video mode, we use video hardware interrupt (VSYNC) and exact framerates for perfect synchronization */
/* In 60Hz TV modes, Wii & GC framerates have been measured to be 59.94 (interlaced or progressive) and ~59.825 fps (non-interlaced) */
/* In 50Hz TV modes, Wii & GC framerates have been measured to be 50.00 (interlaced) and ~50.845 fps (non-interlaced) */
/* When modes does not match, emulation is synchronized with audio hardware interrupt (DMA) and we use default framerates (50Hz for PAL, 60Hz for NTSC). */
if (vdp_pal)
{
audio_init(SAMPLERATE_48KHZ, (config.tv_mode == 0) ? 50.0 : (config.render ? 50.00 : (1000000.0/19968.0)));
}
else
{
audio_init(SAMPLERATE_48KHZ, (config.tv_mode == 1) ? 60.0 : (config.render ? 59.94 : (1000000.0/16715.0)));
}
/* system power ON */
system_init ();
system_reset ();
}
/* load Cheats */
CheatLoad();
/* load SRAM */
if (config.s_auto & 1)
{
slot_autoload(0,config.s_device);
}
/* load State */
if (config.s_auto & 2)
{
slot_autoload(config.s_default,config.s_device);
}
}
/**************************************************
Shutdown everything properly
***************************************************/
void shutdown(void)
{
/* save current config */
config_save();
/* save current game state */
if (config.s_auto & 2)
{
slot_autosave(config.s_default,config.s_device);
}
/* shutdown emulation */
system_shutdown();
audio_shutdown();
free(cart.rom);
gx_audio_Shutdown();
gx_video_Shutdown();
#ifdef HW_RVL
DI_Close();
#endif
}
/***************************************************************************
* M A I N
*
***************************************************************************/
u32 frameticker = 0;
int main (int argc, char *argv[])
{
char pathname[MAXPATHLEN];
#ifdef HW_RVL
/* initialize DI interface */
DI_UseCache(0);
DI_Init();
#endif
/* initialize video engine */
gx_video_Init();
#ifdef HW_DOL
/* initialize DVD interface */
DVD_Init ();
#endif
/* initialize input engine */
gx_input_Init();
/* initialize FAT devices */
int retry = 0;
int fatMounted = 0;
/* try to mount FAT devices during 3 seconds */
while (!fatMounted && (retry < 12))
{
fatMounted = fatInitDefault();
usleep(250000);
retry++;
}
if (fatMounted)
{
/* base directory */
sprintf (pathname, DEFAULT_PATH);
DIR_ITER *dir = diropen(pathname);
if (dir) dirclose(dir);
else mkdir(pathname,S_IRWXU);
/* default SRAM & Savestate files directory */
sprintf (pathname, "%s/saves",DEFAULT_PATH);
dir = diropen(pathname);
if (dir) dirclose(dir);
else mkdir(pathname,S_IRWXU);
/* default Snapshot files directory */
sprintf (pathname, "%s/snaps",DEFAULT_PATH);
dir = diropen(pathname);
if (dir) dirclose(dir);
else mkdir(pathname,S_IRWXU);
/* default Cheat files directory */
sprintf (pathname, "%s/cheats",DEFAULT_PATH);
dir = diropen(pathname);
if (dir) dirclose(dir);
else mkdir(pathname,S_IRWXU);
}
/* initialize sound engine */
gx_audio_Init();
/* initialize genesis plus core */
legal();
config_default();
history_default();
init_machine();
/* run any injected rom */
if (cart.romsize)
{
int size = cart.romsize;
cart.romsize = 0;
ARAMFetch((char *)cart.rom, (void *)0x8000, size);
reloadrom(size,"INJECT.bin");
ConfigRequested = 0;
gx_video_Start();
gx_audio_Start();
frameticker = 1;
}
else if (config.autoload)
{
SILENT = 1;
if (OpenDirectory(TYPE_RECENT))
{
int size = LoadFile(cart.rom,0,pathname);
if (size)
{
reloadrom(size,pathname);
gx_video_Start();
gx_audio_Start();
frameticker = 1;
ConfigRequested = 0;
}
}
SILENT = 0;
}
#ifdef HW_RVL
/* power button callback */
SYS_SetPowerCallback(PowerOff_cb);
#endif
/* reset button callback */
SYS_SetResetCallback(Reset_cb);
/* main emulation loop */
run_emulation();
/* we should never return anyway */
return 0;
}