Genesis-Plus-GX/source/gx/main.c
ekeeke31 62f1204476 ----------------------
Genesis Plus GX 1.6.0 
----------------------

[Core/Sound]
---------------
* added YM2413 emulation in Master System compatibility mode.
* fixed SN76489 noise boost initialization.
* minor YM2612 core optimizations.

[Core/VDP]
---------------
* added accurate emulation of SG-1000, Master System (315-5124, 315-5246) & Game Gear VDP.
* added support for all TMS9918 rendering modes.
* improved Mega Drive VDP timings accuracy in Master System Compatibility mode.
* fixed color palette initialization.
* fixed shifted sprites rendering in Mode 4.
* modified pixel rendering support (pixel depth is now forced at compilation time).

[Core/CPU]
---------------
* optimized 68k core (rewrote 68k interrupt handling, removed multiple CPU types support & unused code) for 5~8% speed improvment

[Core/IO]
---------------
* added accurate emulation of Master System (315-5216, 315-5237, 315-5297) & Game Gear I/O controllers.
* added Terebi Oekaki tablet emulation.
* improved Mouse emulation (fixes mouse support in Cannon Fodder).
* improved Justifier emulation (fixes gun support in Lethal Enforcers 2).
* improved 6-Buttons control pad emulation (fixes Duke Nukem 3D)
* modified lightgun emulation to use common key inputs for all devices.
* 2-buttons controller is now picked by default for Master System games.

[Core/MD]
---------------
* added copy-protection hardware emulation for some new dumped games (Tiny Toon Adventures 3, Mighty Morphin Power Rangers & The Battle of Red Cliffs).
* added Game Toshokan in EEPROM database (verified on real cartridge).
* fixed Micro Machines 2 - Turbo Tournament EEPROM size (verified on real cartridge).
* modified SRAM banswitch hardware emulation to be more compatible with some hacks.

[Core/MS]
---------------
* added Cyborg Z to Korean mapper database.

[Core/GG]
---------------
* added 93C46 EEPROM emulation (Majors Pro Baseball, World Series Baseball & World Series Baseball 95).

[Core/General]
---------------
* added support for .mdx ROM format.
* added Game Gear & SG-1000 ROM support.
* added accurate emulation of SG-1000, Master System (I, II) & Game Gear hardware models for 100% compatibility.
* updated to new Genesis Plus license (see http://cgfm2.emuviews.com/)
* removed DOS port
* various code cleanup.

[Gamecube/Wii]
---------------
* IMPORTANT: cheats, screenshots & save files are now stored in console-specific directories (ex: /snaps/md, /cheats/ms, /saves/gg, ...)
* added 8-bit Action Replay & Game Genie codes support (for Master System & Game Gear games).
* improved audio/video synchronization for PAL games in 50Hz TV modes (now use VSYNC like NTSC games in 60hz modes).
* improved gun cursor positioning accuracy.
* improved horizontal scaling & screenshots rendering in H32 mode.
* fixed a bug with ROM file extension handling that would affect cheats, snapshots, sram & savestate files.
* removed ARAM/injected ROM support (unused).
* removed WPAD_ and PAD_ update from VSYNC callback.
* increased GCC inlining limits for some speed improvment.
* compiled with devkitPPC r24 & libogc 1.8.7.
2011-08-07 17:49:46 +00:00

453 lines
12 KiB
C

/****************************************************************************
* main.c
*
* Genesis Plus GX
*
* Copyright Eke-Eke (2007-2011), based on original work from Softdev (2006)
*
* Redistribution and use of this code or any derivative works are permitted
* provided that the following conditions are met:
*
* - Redistributions may not be sold, nor may they be used in a commercial
* product or activity.
*
* - Redistributions that are modified from the original source must include the
* complete source code, including the source code for all components used by a
* binary built from the modified sources. However, as a special exception, the
* source code distributed need not include anything that is normally distributed
* (in either source or binary form) with the major components (compiler, kernel,
* and so on) of the operating system on which the executable runs, unless that
* component itself accompanies the executable.
*
* - Redistributions must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************************/
#include "shared.h"
#include "font.h"
#include "gui.h"
#include "menu.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>
#include <ogc/machine/processor.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;
u32 frameticker;
#ifdef HW_RVL
/****************************************************************************
* Power Button callback
***************************************************************************/
static void PowerOff_cb(void)
{
Shutdown = 1;
ConfigRequested = 1;
}
#endif
/****************************************************************************
* Reset Button callback
***************************************************************************/
static void Reset_cb(void)
{
if (system_hw & SYSTEM_MD)
{
/* SOFT-RESET */
gen_reset(0);
}
else if (system_hw == SYSTEM_SMS)
{
/* assert RESET input */
io_reg[0x0D] &= ~IO_RESET_HI;
}
}
/***************************************************************************
* 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);
/* BIOS support */
load_bios();
/* allocate global work bitmap */
memset(&bitmap, 0, sizeof (bitmap));
bitmap.width = 720;
bitmap.height = 576;
bitmap.pitch = bitmap.width * 2;
bitmap.viewport.w = 256;
bitmap.viewport.h = 224;
bitmap.viewport.x = 0;
bitmap.viewport.y = 0;
bitmap.data = texturemem;
}
/*******************************************
Restart emulation when loading a new game
********************************************/
static void reload(void)
{
/* Cartridge Hot Swap (make sure system has already been inited once) */
if (config.hot_swap && snd.enabled)
{
if ((system_hw & SYSTEM_PBC) == SYSTEM_MD)
{
md_cart_init();
md_cart_reset(1);
}
else
{
sms_cart_init();
sms_cart_reset();
}
}
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)));
}
/* Switch virtual system on */
system_init();
system_reset();
}
/* Auto-Load SRAM file */
if (config.s_auto & 1)
{
slot_autoload(0,config.s_device);
}
/* Auto-Load State file */
if (config.s_auto & 2)
{
slot_autoload(config.s_default,config.s_device);
}
/* Load Cheat file */
CheatLoad();
}
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 */
ConfigRequested = 0;
if (menu_execute())
{
/* new ROM has been loaded */
reload();
}
/* start video & audio */
gx_video_Start();
gx_audio_Start();
frameticker = 1;
}
/* automatic frame skipping (only necessary for Virtua Racing in Gamecube mode) */
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);
}
}
/**************************************************
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
*
***************************************************************************/
int main (int argc, char *argv[])
{
#ifdef HW_RVL
/* enable 64-byte fetch mode for L2 cache */
L2Enhance();
/* 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 */
char pathname[MAXPATHLEN];
sprintf (pathname, DEFAULT_PATH);
DIR *dir = opendir(pathname);
if (dir) closedir(dir);
else mkdir(pathname,S_IRWXU);
/* default SRAM & Savestate files directories */
sprintf (pathname, "%s/saves",DEFAULT_PATH);
dir = opendir(pathname);
if (dir) closedir(dir);
else mkdir(pathname,S_IRWXU);
sprintf (pathname, "%s/saves/md",DEFAULT_PATH);
dir = opendir(pathname);
if (dir) closedir(dir);
else mkdir(pathname,S_IRWXU);
sprintf (pathname, "%s/saves/ms",DEFAULT_PATH);
dir = opendir(pathname);
if (dir) closedir(dir);
else mkdir(pathname,S_IRWXU);
sprintf (pathname, "%s/saves/gg",DEFAULT_PATH);
dir = opendir(pathname);
if (dir) closedir(dir);
else mkdir(pathname,S_IRWXU);
sprintf (pathname, "%s/saves/sg",DEFAULT_PATH);
dir = opendir(pathname);
if (dir) closedir(dir);
else mkdir(pathname,S_IRWXU);
/* default Snapshot files directories */
sprintf (pathname, "%s/snaps",DEFAULT_PATH);
dir = opendir(pathname);
if (dir) closedir(dir);
else mkdir(pathname,S_IRWXU);
sprintf (pathname, "%s/snaps/md",DEFAULT_PATH);
dir = opendir(pathname);
if (dir) closedir(dir);
else mkdir(pathname,S_IRWXU);
sprintf (pathname, "%s/snaps/ms",DEFAULT_PATH);
dir = opendir(pathname);
if (dir) closedir(dir);
else mkdir(pathname,S_IRWXU);
sprintf (pathname, "%s/snaps/gg",DEFAULT_PATH);
dir = opendir(pathname);
if (dir) closedir(dir);
else mkdir(pathname,S_IRWXU);
sprintf (pathname, "%s/snaps/sg",DEFAULT_PATH);
dir = opendir(pathname);
if (dir) closedir(dir);
else mkdir(pathname,S_IRWXU);
/* default Cheat files directories */
sprintf (pathname, "%s/cheats",DEFAULT_PATH);
dir = opendir(pathname);
if (dir) closedir(dir);
else mkdir(pathname,S_IRWXU);
sprintf (pathname, "%s/cheats/md",DEFAULT_PATH);
dir = opendir(pathname);
if (dir) closedir(dir);
else mkdir(pathname,S_IRWXU);
sprintf (pathname, "%s/cheats/ms",DEFAULT_PATH);
dir = opendir(pathname);
if (dir) closedir(dir);
else mkdir(pathname,S_IRWXU);
sprintf (pathname, "%s/cheats/gg",DEFAULT_PATH);
dir = opendir(pathname);
if (dir) closedir(dir);
else mkdir(pathname,S_IRWXU);
sprintf (pathname, "%s/cheats/sg",DEFAULT_PATH);
dir = opendir(pathname);
if (dir) closedir(dir);
else mkdir(pathname,S_IRWXU);
}
/* initialize sound engine */
gx_audio_Init();
/* initialize genesis plus core */
legal();
config_default();
history_default();
init_machine();
/* auto-load last ROM file */
if (config.autoload)
{
SILENT = 1;
if (OpenDirectory(TYPE_RECENT))
{
if (LoadFile(0))
{
reload();
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;
}