mirror of
https://github.com/ekeeke/Genesis-Plus-GX.git
synced 2024-12-28 12:11:50 +01:00
-removed unused files
This commit is contained in:
parent
62f1204476
commit
c07e7ae644
@ -1,201 +0,0 @@
|
|||||||
/******************************************************************************
|
|
||||||
*
|
|
||||||
* unzip.c
|
|
||||||
*
|
|
||||||
* Zip Support
|
|
||||||
*
|
|
||||||
* Only partial support is included, in that only the first file within the archive
|
|
||||||
* is considered to be a ROM image.
|
|
||||||
*
|
|
||||||
* Softdev (2006)
|
|
||||||
* Eke-Eke (2007,2008)
|
|
||||||
*
|
|
||||||
* 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 "gui.h"
|
|
||||||
|
|
||||||
/*
|
|
||||||
* PKWare Zip Header - adopted into zip standard
|
|
||||||
*/
|
|
||||||
#define PKZIPID 0x504b0304
|
|
||||||
#define MAXROM 0x500000
|
|
||||||
#define ZIPCHUNK 2048
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Zip file header definition
|
|
||||||
*/
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
unsigned int zipid __attribute__ ((__packed__)); // 0x04034b50
|
|
||||||
unsigned short zipversion __attribute__ ((__packed__));
|
|
||||||
unsigned short zipflags __attribute__ ((__packed__));
|
|
||||||
unsigned short compressionMethod __attribute__ ((__packed__));
|
|
||||||
unsigned short lastmodtime __attribute__ ((__packed__));
|
|
||||||
unsigned short lastmoddate __attribute__ ((__packed__));
|
|
||||||
unsigned int crc32 __attribute__ ((__packed__));
|
|
||||||
unsigned int compressedSize __attribute__ ((__packed__));
|
|
||||||
unsigned int uncompressedSize __attribute__ ((__packed__));
|
|
||||||
unsigned short filenameLength __attribute__ ((__packed__));
|
|
||||||
unsigned short extraDataLength __attribute__ ((__packed__));
|
|
||||||
} PKZIPHEADER;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Zip files are stored little endian
|
|
||||||
* Support functions for short and int types
|
|
||||||
*/
|
|
||||||
static inline u32 FLIP32 (u32 b)
|
|
||||||
{
|
|
||||||
unsigned int c;
|
|
||||||
c = (b & 0xff000000) >> 24;
|
|
||||||
c |= (b & 0xff0000) >> 8;
|
|
||||||
c |= (b & 0xff00) << 8;
|
|
||||||
c |= (b & 0xff) << 24;
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline u16 FLIP16 (u16 b)
|
|
||||||
{
|
|
||||||
u16 c;
|
|
||||||
c = (b & 0xff00) >> 8;
|
|
||||||
c |= (b & 0xff) << 8;
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* IsZipFile
|
|
||||||
*
|
|
||||||
* Returns TRUE when PKZIPID is first four characters of buffer
|
|
||||||
****************************************************************************/
|
|
||||||
int IsZipFile (char *buffer)
|
|
||||||
{
|
|
||||||
unsigned int *check;
|
|
||||||
check = (unsigned int *) buffer;
|
|
||||||
if (check[0] == PKZIPID) return 1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
* UnZipBuffer
|
|
||||||
*
|
|
||||||
******************************************************************************/
|
|
||||||
int UnZipBuffer (unsigned char *outbuffer, FILE *fd, char *filename)
|
|
||||||
{
|
|
||||||
PKZIPHEADER pkzip;
|
|
||||||
int zipoffset = 0;
|
|
||||||
int zipchunk = 0;
|
|
||||||
char out[ZIPCHUNK];
|
|
||||||
z_stream zs;
|
|
||||||
int res;
|
|
||||||
int bufferoffset = 0;
|
|
||||||
int have = 0;
|
|
||||||
char readbuffer[ZIPCHUNK];
|
|
||||||
char msg[64];
|
|
||||||
|
|
||||||
/*** Read Zip Header ***/
|
|
||||||
fread(readbuffer, ZIPCHUNK, 1, fd);
|
|
||||||
|
|
||||||
/*** Copy PKZip header to local, used as info ***/
|
|
||||||
memcpy (&pkzip, &readbuffer, sizeof (PKZIPHEADER));
|
|
||||||
|
|
||||||
if (FLIP32 (pkzip.uncompressedSize) > MAXROMSIZE)
|
|
||||||
{
|
|
||||||
GUI_WaitPrompt("Error","File is too large !");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
sprintf (msg, "Unzipping %d bytes ...", FLIP32 (pkzip.uncompressedSize));
|
|
||||||
GUI_MsgBoxOpen("Information",msg,1);
|
|
||||||
|
|
||||||
/*** Prepare the zip stream ***/
|
|
||||||
memset (&zs, 0, sizeof (z_stream));
|
|
||||||
zs.zalloc = Z_NULL;
|
|
||||||
zs.zfree = Z_NULL;
|
|
||||||
zs.opaque = Z_NULL;
|
|
||||||
zs.avail_in = 0;
|
|
||||||
zs.next_in = Z_NULL;
|
|
||||||
res = inflateInit2 (&zs, -MAX_WBITS);
|
|
||||||
|
|
||||||
if (res != Z_OK)
|
|
||||||
{
|
|
||||||
GUI_WaitPrompt("Error","Unable to unzip file !");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*** Get file name (first file) ***/
|
|
||||||
int size = FLIP16 (pkzip.filenameLength);
|
|
||||||
if (size > 255) size = 255;
|
|
||||||
strncpy(filename, &readbuffer[sizeof(PKZIPHEADER)], size);
|
|
||||||
filename[size] = 0;
|
|
||||||
|
|
||||||
/*** Set ZipChunk for first pass ***/
|
|
||||||
zipoffset = (sizeof (PKZIPHEADER) + size + FLIP16 (pkzip.extraDataLength));
|
|
||||||
zipchunk = ZIPCHUNK - zipoffset;
|
|
||||||
|
|
||||||
/*** Now do it! ***/
|
|
||||||
do
|
|
||||||
{
|
|
||||||
zs.avail_in = zipchunk;
|
|
||||||
zs.next_in = (Bytef *) &readbuffer[zipoffset];
|
|
||||||
|
|
||||||
/*** Now inflate until input buffer is exhausted ***/
|
|
||||||
do
|
|
||||||
{
|
|
||||||
zs.avail_out = ZIPCHUNK;
|
|
||||||
zs.next_out = (Bytef *) &out;
|
|
||||||
res = inflate (&zs, Z_NO_FLUSH);
|
|
||||||
|
|
||||||
if (res == Z_MEM_ERROR)
|
|
||||||
{
|
|
||||||
inflateEnd (&zs);
|
|
||||||
GUI_WaitPrompt("Error","Unable to unzip file !");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
have = ZIPCHUNK - zs.avail_out;
|
|
||||||
if (have)
|
|
||||||
{
|
|
||||||
/*** Copy to normal block buffer ***/
|
|
||||||
memcpy (&outbuffer[bufferoffset], &out, have);
|
|
||||||
bufferoffset += have;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
while (zs.avail_out == 0);
|
|
||||||
|
|
||||||
/*** Readup the next 2k block ***/
|
|
||||||
zipoffset = 0;
|
|
||||||
zipchunk = ZIPCHUNK;
|
|
||||||
fread(readbuffer, ZIPCHUNK, 1, fd);
|
|
||||||
}
|
|
||||||
while (res != Z_STREAM_END);
|
|
||||||
|
|
||||||
inflateEnd (&zs);
|
|
||||||
GUI_MsgBoxClose();
|
|
||||||
|
|
||||||
if (res == Z_STREAM_END)
|
|
||||||
{
|
|
||||||
if (FLIP32 (pkzip.uncompressedSize) == (u32) bufferoffset)
|
|
||||||
return bufferoffset;
|
|
||||||
else
|
|
||||||
return FLIP32 (pkzip.uncompressedSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,35 +0,0 @@
|
|||||||
/******************************************************************************
|
|
||||||
*
|
|
||||||
* unzip.c
|
|
||||||
*
|
|
||||||
* Zip Support
|
|
||||||
*
|
|
||||||
* Only partial support is included, in that only the first file within the archive
|
|
||||||
* is considered to be a ROM image.
|
|
||||||
*
|
|
||||||
* Softdev (2006)
|
|
||||||
* Eke-Eke (2007,2008)
|
|
||||||
*
|
|
||||||
* 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
|
|
||||||
*
|
|
||||||
********************************************************************************/
|
|
||||||
|
|
||||||
#ifndef _UNZIP_H_
|
|
||||||
#define _UNZIP_H_
|
|
||||||
|
|
||||||
extern int IsZipFile (char *buffer);
|
|
||||||
int UnZipBuffer (unsigned char *outbuffer, FILE *fd, char *filename);
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,401 +0,0 @@
|
|||||||
--------------------
|
|
||||||
Genesis Plus History
|
|
||||||
--------------------
|
|
||||||
|
|
||||||
All recent changes were backported from the GX version (Gamecube/Wii port), maintained by Eke-Eke.
|
|
||||||
Please look at http://code.google.com/p/genplus-gx/ for more infos.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
---------------------------------------------------------------------------------------------------------
|
|
||||||
[04/12/2010] version 1.4.1 (Eke-Eke)
|
|
||||||
---------------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
[Core/Sound]
|
|
||||||
---------------
|
|
||||||
* implemented Blargg's blip buffer in SN76489 core (all channels are now lineary interpolated)
|
|
||||||
|
|
||||||
[Core/VDP]
|
|
||||||
---------------
|
|
||||||
* improved 2-cell vscroll emulation accuracy, as verified on real hardware (Gynoug, Cutie Suzuki no Ringside Angel, Formula One, Kawasaki Superbike Challenge)
|
|
||||||
* improved VBLANK flag accuracy, as observed on real hardware.
|
|
||||||
* improved DMA operations accuracy, writes are now performed on a scanline basis: fixes Gaiares (flickering title screen).
|
|
||||||
* improved DMA Fill timing accuracy.
|
|
||||||
* fixed DMA with bad code values: fixes Williams Arcade Classics (corrupted gfx after soft reset).
|
|
||||||
* fixed horizontal resolution changes during HBLANK: fixes Bugs Bunny in Double Trouble (2nd stage).
|
|
||||||
* fixed Vertical Counter in interlace mode 1, as observed on real hardware.
|
|
||||||
* fixed horizontal border width, as observed on real hardware.
|
|
||||||
* various code improvments & optimizations.
|
|
||||||
|
|
||||||
[Core/CPU]
|
|
||||||
---------------
|
|
||||||
* fixed state of Z80 registers on reset (sound issues with Defender & Defender 2 in Williams Arcade Classics)
|
|
||||||
* implemented 68k undocumented flags behavior for DIVU/DIVS instructions (Bloodshot / Battle Frenzy)
|
|
||||||
|
|
||||||
[Core/Extra]
|
|
||||||
---------------
|
|
||||||
* improved emulation of copy-protection hardware found in some unlicensed cartridges (Mulan, Pocket Monsters II).
|
|
||||||
* enabled simultaneous use of multitap & J-CART (Super Skidmarks 6-player mode)
|
|
||||||
* improved savestate format: added DMA, SVP, cartridge mapping & internal registers state informations
|
|
||||||
* improved unlicensed ROM mappers emulation
|
|
||||||
* added Chinese Fighters III mapper support
|
|
||||||
* added Top Fighter mapper support
|
|
||||||
* fixed Barver Battle Saga mapper support
|
|
||||||
* fixed cartridge hardware soft-reset (Game Genie, SVP, ...)
|
|
||||||
* fixed Game Genie registers byte reads
|
|
||||||
|
|
||||||
|
|
||||||
----------------------------------------------------------------------------------------------------------------------------------------------------
|
|
||||||
[06/30/10] version 1.4.0 (Eke-Eke)
|
|
||||||
----------------------------------------------------------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
[Core/Sound]
|
|
||||||
|
|
||||||
* completely rewrote sound processing/mixing: sound chips are now clocked with exact output framerate
|
|
||||||
to ensure 100% smooth video & audio playback, with no lag or skipping, while rendering an accurate number
|
|
||||||
of samples per frame and keeping PSG & FM chips in sync.
|
|
||||||
* improved PSG & FM chips synchronization with CPU execution (fixed point precision).
|
|
||||||
* improved YM2612 core general accuracy (SSG-EG, CSM mode,...) (based upon Nemesis recent tests on real hardware)
|
|
||||||
* improved YM2612 LFO emulation accuracy: fixes "Spider-Man & Venom : Separation Anxiety" (intro)
|
|
||||||
* fixed YM2612 bug with Timer B: fixes "Langrisser Hikari II"/"Der Langrisser II" (Sega logo)
|
|
||||||
* fixed YM2612 context saving/loading.
|
|
||||||
* fixed YM2612 state on reset.
|
|
||||||
* removed outdated & less accurate Gens YM2612 core
|
|
||||||
* added configurable YM2612 DAC resolution emulation.
|
|
||||||
* added configurable & faster FIR resampler (thanks to Blargg & AamirM), removed libsamplerate support.
|
|
||||||
* added configurable Low-Pass filtering
|
|
||||||
* added configurable 3-Band Equalizer (thanks to Neil C).
|
|
||||||
* added an option to boost SN76489 Noise Channel.
|
|
||||||
* adjusted SN76489 cut-off frequency.
|
|
||||||
|
|
||||||
|
|
||||||
[Core/VDP]
|
|
||||||
|
|
||||||
* added support for CRAM writes during horizontal blanking (Striker, Zero the Kamikaze Squirrel,...)
|
|
||||||
* added support for 2-Cell vertical scrolling in Interlaced 2 mode
|
|
||||||
* added support for some undocumented mode register bits
|
|
||||||
* added proper emulation of HV Counter latch: fixes Sunset Riders intro
|
|
||||||
* added pixel-accurate emulation of mid-line display on/off (Nigel Mansell World Championship PAL, Ren & Stimpy's Invention PAL,...)
|
|
||||||
* improved FIFO timings accuracy: fixes Sol Deace intro
|
|
||||||
* improved sprite masking accuracy (thanks to Nemesis for his test program)
|
|
||||||
* improved sprites processing accuracy: fixes (un)masked sprites in Mickey Mania (3D level), Sonic 2 (VS mode).
|
|
||||||
* improved HBLANK flag timing accuracy: fixes Mega Turrican (Sky level)
|
|
||||||
* improved horizontal blanking & HINT/VINT occurence timing accuracy, as measured on real hardware.
|
|
||||||
* improved HCounter accuracy in 40-cell mode, as measured on real hardware.
|
|
||||||
* improved color accuracy in VDP highlight mode to match results observed on real hardware
|
|
||||||
|
|
||||||
|
|
||||||
[Core/CPU]
|
|
||||||
|
|
||||||
* updated Z80 core to last version (fixes interrupt Mode 0 timing and some BIT instructions).
|
|
||||||
* fixed some Z80 instructions timing.
|
|
||||||
* improved Z80 interrupt accuracy
|
|
||||||
* improved 68k accuracy (initial Reset timing + auto-vectored interrupts handling).
|
|
||||||
* improved 68k timing accuracy for DIVU/DVIS (thanks to Jorge Cwik) & MULU/MULS instructions.
|
|
||||||
* improved Z80 & 68k cpu execution/synchronization accuracy by using Master Clock as common reference (now run exactly 3420 M-Cycles per line).
|
|
||||||
* modified Z80 & 68k cores to directly use external cycle count instead of intermediate counters.
|
|
||||||
|
|
||||||
|
|
||||||
[Core/Extra]
|
|
||||||
|
|
||||||
* added Game Genie hardware emulation (Game Genie ROM is now fully supported).
|
|
||||||
* added Action Replay hardware emulation (Action replay ROM is now fully supported).
|
|
||||||
* added S&K "Lock-On" hardware emulation (you can "lock" any games to Sonic & Knuckles).
|
|
||||||
* added Cartridge "hot swap" feature.
|
|
||||||
* added missing EEPROM support in some games.
|
|
||||||
* added accurate TMSS emulation (VDP lock-out)
|
|
||||||
* fixed Realtec mapper emulation: fixes missing sound in Balloon Boy / Funny World.
|
|
||||||
* fixed lightgun auto-detection: fixes default cursor position in Lethal Enforcers II.
|
|
||||||
* lots of code cleanup, bugfixes & optimization.
|
|
||||||
|
|
||||||
|
|
||||||
----------------------------------------------------------------------------------------------------------------------------------------------------
|
|
||||||
[12/14/08] version 1.3.0 (Eke-Eke)
|
|
||||||
----------------------------------------------------------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
* YM2612 bugfixes (MAME core):
|
|
||||||
.fixed EG Decay->Substain transition when SL & DR are minimals: fix tracks #3 and #9 in "Mega Turrican"
|
|
||||||
.fixed a bug in SSG-EG emulation code: fix Level 1 music in "Alisia Dragoon"
|
|
||||||
.modified SSG-EG Decay End Level: fix some sound effects (ChainSaw, Zap...) in "Beavis & Butthead"
|
|
||||||
.improved Detune overflow accuracy: fix very high frequency sounds in many games
|
|
||||||
.fixed registers 0x20-0x26 Reset state: fix intro music in "B.O.B"
|
|
||||||
.reverted incorrect fix with KEY ON: fix "Flamethrower" sound effect in "Alien 3" and many others
|
|
||||||
* adjusted HCounter values: fixes line flickering in "Sonic 3D" bonus stage
|
|
||||||
* adjusted VINT timing: fixes hang-up in "V.R Troopers"
|
|
||||||
* improved HBLANK flag accuracy: fixes line flickering in "Gouketsuji Ichizoku"
|
|
||||||
* fixed broken Z80 access to WRAM: fixes hang-up in "Mamono Hunter Youko"
|
|
||||||
* modified JCART emulation: fixes corrupted tracks logo in "Micro Machines 2"
|
|
||||||
* added Blargg's NTSC Filters support (NTSC video artifacts emulation)
|
|
||||||
* optimized VDP rendering core, rewrote 68k interface (memory handlers, cycle execution, interrupts): greatly improved emulation speed
|
|
||||||
|
|
||||||
|
|
||||||
----------------------------------------------------------------------------------------------------------------------------------------------------
|
|
||||||
[08/26/08] (Eke-Eke)
|
|
||||||
----------------------------------------------------------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
* YM2612(MAME): fixed LFO phase update for CH3 special mode: fix sound effects in Warlock & Aladdin (thanks to AamirM)
|
|
||||||
* YM2612(MAME): fixed EG attenuation level on "KEY ON": fix Ecco 2's splash sound
|
|
||||||
* YM2612(MAME): fixed SSG-EG emulation: fix Bubba'n Stix (Track 5) and many others
|
|
||||||
* YM2612(MAME): replaced sample interpolation with libsamplerate support, High Quality mode is now more accurate
|
|
||||||
* implemented cycle-accurate HINT timings: every timing sensitive games/demos are now *finally* working fine
|
|
||||||
* fixed a bug affecting CRAM/VSRAM DMA timings
|
|
||||||
* fixed Sprite Attribute Table address mask for VRAM writes
|
|
||||||
* improved accuracy of 68k access to Z80: fix music in Pacman 2 when entering PAUSE menu
|
|
||||||
* disabled "Address Error" emulation when UMK3 hack is loaded: fix game crashing after a round ends up
|
|
||||||
* added support for some more unlicensed games: Pocket Monster, King of Fighter 98, Soul Blade (credits to Haze)
|
|
||||||
* improved Menacer emulation: fix lightgun support in Body Count & T2: The Arcade Game
|
|
||||||
* added Konami Justifier emulation: fix lightgun support in Lethal Enforcers 1 & 2
|
|
||||||
* added Sega Mouse emulation (Populous 2, Body Count, Shangai 2, Fun'n Games, ...)
|
|
||||||
|
|
||||||
|
|
||||||
----------------------------------------------------------------------------------------------------------------------------------------------------
|
|
||||||
[07/16/08] (Eke-Eke)
|
|
||||||
----------------------------------------------------------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
* adjusted (again) HINT timings: fix Double Dragon 2 (game freezed), hopefully does not break anything else
|
|
||||||
* fixed broken EEPROM support for Codemaster games
|
|
||||||
* modified input update timings: fix Dungeons & Dragons * Warriors of the Eternal Sun (thanks to Notaz)
|
|
||||||
* added support for "Ultimate Mortal Kombat Trilogy" hack (max. size supported is 10MBytes)
|
|
||||||
* added (VERY) preliminar support for PICO roms (credits to Notaz for his documentation)
|
|
||||||
* improved YM2612 emulation (credits to Nemesis for his tests on real hardware):
|
|
||||||
.implemented phase overflow emulation: improved fix for special music instrument used in Comix Zone, Flashback, Ariel, Shaq Fu...
|
|
||||||
.improved SSG-EG emulation in MAME core (also based on additional code from Alone Coder)
|
|
||||||
.improved Timers emulation accuracy
|
|
||||||
.improved Enveloppe Generator accuracy
|
|
||||||
.fixed Channel 3 CSM mode emulation
|
|
||||||
.implemented sample interpolation in MAME core to emulate the chip at original frequency (HQ YM2612 mode, from gens)
|
|
||||||
|
|
||||||
|
|
||||||
----------------------------------------------------------------------------------------------------------------------------------------------------
|
|
||||||
[06/01/08] (Eke-Eke)
|
|
||||||
----------------------------------------------------------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
* improved HCounter accuracy: fix graphic glitches in "Striker (Europe)"
|
|
||||||
* improved HINT timing accuracy: fix flickering in "Zero The Kamikaze Squirrel (USA)"
|
|
||||||
* improved rendering accuracy when backdrop color is modified during HBLANK (Road Rash I/II/III)
|
|
||||||
* fixed broken Game Genie support
|
|
||||||
|
|
||||||
|
|
||||||
----------------------------------------------------------------------------------------------------------------------------------------------------
|
|
||||||
[04/19/08] (Eke-Eke)
|
|
||||||
----------------------------------------------------------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
* modified VINT timings a little bit: fix lockup during Desert Strike's intro
|
|
||||||
* corrected 68k interrupts handling: fix graphic glitches in Darius II/Sagaia
|
|
||||||
|
|
||||||
|
|
||||||
----------------------------------------------------------------------------------------------------------------------------------------------------
|
|
||||||
[04/06/08] (Eke-Eke)
|
|
||||||
----------------------------------------------------------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
* updated SVP core: fix some perspective issues in Virtua Racing (thanks to Notaz)
|
|
||||||
* added internal SAT update during VRAM Fill: fix unmasked sprites during Battletech's intro
|
|
||||||
* fixed m68k core issues with gcc 4.2.3: fix Xperts, Lemmings 2, M1 Abrams Battle Tank
|
|
||||||
* forced YM2612 Enveloppe update: fix intro music in Batman&Robin (thanks to Aamir)
|
|
||||||
|
|
||||||
|
|
||||||
----------------------------------------------------------------------------------------------------------------------------------------------------
|
|
||||||
[03/01/08] (Eke-Eke)
|
|
||||||
----------------------------------------------------------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
* added SVP emulation: Virtua Racing is now emulated (big thanks to Notaz and TascoDeluxe)
|
|
||||||
* fixed VDP registers behaviour when VDP Mode 4 is enabled: fix Bass Masters Classic Pro, Captain Planet & The Planeeters
|
|
||||||
* corrected a bug in DMA Fill operation: fix James Pond 3, Rockman World/Megaman Willy Wars (corrupted VRAM)
|
|
||||||
* corrected typo errors in CPU cycle counters update: fix optiom screen music in "College Slam" and probably others games.
|
|
||||||
* added preliminary support of undocumented YM2612 bug: fixes soundtracks of Shaq Fu, Spiderman, Comix Zone, Ariel and some others
|
|
||||||
* added support for mappers & copy protection devices used in many unlicensed/pirate cartridges (see cart_hw.c for details)
|
|
||||||
* rewrote memory handlers for better modularity and some (little) speedup
|
|
||||||
* reduced Savestate size
|
|
||||||
|
|
||||||
|
|
||||||
----------------------------------------------------------------------------------------------------------------------------------------------------
|
|
||||||
[01/07/08] (Eke-Eke)
|
|
||||||
----------------------------------------------------------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
* fixed interleaved rom detection: roms with .smd extension should now work fine
|
|
||||||
* fixed a recently introduced bug in VDP registers writes: fixes bad colors in Toy Story (intro)
|
|
||||||
* updated list of games using EEPROM: added Sports Talk Baseball (internal memory check fixed) and Brian Lara Cricket
|
|
||||||
* fixed VINT flag update when VINT is disabled: fixes NCAA College Football
|
|
||||||
* adjusted DMA timings in H32 mode: fixes flickering in Out of this World, Kawasaki Superbike Challenge & Formula One
|
|
||||||
* adjusted line rendering and HBLANK timings: fixes flickering in Nigel Mansell's World Championship Racing, Deadly Moves/Power Athlete
|
|
||||||
* fixed unmapped ROM reads through Z80 Bank: fixes Zombie High (Proto)
|
|
||||||
* added support for custom ROM/RAM mapping used by Game no Kanzume Otokuyou
|
|
||||||
|
|
||||||
|
|
||||||
----------------------------------------------------------------------------------------------------------------------------------------------------
|
|
||||||
[12/28/07] (Eke-Eke)
|
|
||||||
----------------------------------------------------------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
* many sourcecode cleanup and optimization
|
|
||||||
* completely rewrote EEPROM emulation: now support all known EEPROM types (24C01-24C65) and mappers (Sega, Acclaim, EA, Codemasters)
|
|
||||||
used in a few games (now use internal game database) as external RAM. This should at least fix save support in the following games:
|
|
||||||
. NBA Jam (alternate Acclaim mapper)
|
|
||||||
. College Slam, Frank Thomas Big Hurt Baseball (24C65 type)
|
|
||||||
. NHLPA Hockey 93, Rings of Power (EA mapper)
|
|
||||||
. Micro Machines serie, Brian Lara Cricket 96/Shane Warne Cricket (Codemasters mapper)
|
|
||||||
* external RAM is now initialized to 0xFF by default: fix Micromachines 2, Dino Dini Soccer
|
|
||||||
* fixed SRAM 16-bits memory handlers: fix some Sega Sports and EA Sports games (NFL95, NBA Action 95, NHL97, NHL98,...)
|
|
||||||
* modified WRITE_xxx & READ_xxx macros for better portability and faster memory access on BIG ENDIAN platform
|
|
||||||
* completely rewrote BIG ENDIAN support in render.c and vdp.c: rendering should be a little faster
|
|
||||||
* rewrote ROM bankswitch emulation (Super Street Fighter II): ROM access are faster, using memory pointers instead of reading ROM copy from ARAM
|
|
||||||
* fixed leftmost Window/PlaneA column render and implemented Window bug (as described by Charles Mc Donald)
|
|
||||||
* improved "Sprite Limit" and "Sprite Collision" detection accuracy
|
|
||||||
* modified RGB565 Color Palette to use the full available color range (0-31;0-63)
|
|
||||||
* implemented "cycle accurate" HV Interrupt timings: fix Sesame's Street Counting Cafe, Legend of Galahad (intro)
|
|
||||||
* improved VDP access timings accuracy (added FIFO emulation): fix Double Clutch
|
|
||||||
* improved DMA timings accuracy: fix Winter Olympics (E), Arch Rivals and probably more
|
|
||||||
* fixed HCounter again: Road Rash serie (I,II,III) don't need timing hacks anymore
|
|
||||||
* fixed VCounter in Interlaced 2 mode: fix Combat Cars "VS-Mode"
|
|
||||||
* improved Interlaced 2 mode (double resolution) rendering: Sonic 2, Combat Cars ("VS-Modes") look far better
|
|
||||||
* added TMSS BIOS support (optional)
|
|
||||||
* rewrote part of the YM2162 MAME's core: fixed internal FM timers handling, removed non-YM2612 emulation code and unused multiple cpu support
|
|
||||||
* implemented "cycle accurate" FM timers & sound samples rendering
|
|
||||||
* improved Z80 Interrupt timing accuracy: fix Sonic 3 music slowdowns
|
|
||||||
* updated Z80 & 68000 cores to last MAME versions
|
|
||||||
* improved Soft Reset emulation: X-Men 2 and Eternal Champions (random character selection) now work more like on real hardware.
|
|
||||||
* added full overscan emulation (vertical & horizontal borders) for "pixel perfect" aspect ratio (tested against a real genesis)
|
|
||||||
|
|
||||||
|
|
||||||
----------------------------------------------------------------------------------------------------------------------------------------------------
|
|
||||||
[07/20/07] (Eke-Eke)
|
|
||||||
----------------------------------------------------------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
* corrected TeamPlayer support: fix multiplayer in Gauntlet 4 (Sept. version), Pengo and a lot of others
|
|
||||||
* added J-Cart support: enable multiplayer in Codemasters games (Pete Sampras, Micromachines games, Super Skidmarks)
|
|
||||||
* added serial EEPROM autodetection: fix games with bad SRAM informations in header (NBA Jam TE)
|
|
||||||
* added SVP faking: display 2D graphics in Virtua Racing (the game is however still unplayable)
|
|
||||||
* added support for more internal IO registers: fixe some unlicensed games (Wisdom Tree games...)
|
|
||||||
* added preliminary support for unmapped protection device: fix some unlicensed games with special built-in hardware (Squirell King, Lion King 2...)
|
|
||||||
* added "Soft Reset" combo (in game, use L+Z triggers): this should be like pressing the RESET button on a real Genesis and this is required
|
|
||||||
in some games to enable special features or even complete the game (ex: X-Men).
|
|
||||||
|
|
||||||
|
|
||||||
----------------------------------------------------------------------------------------------------------------------------------------------------
|
|
||||||
[06/21/07] (Eke-Eke)
|
|
||||||
----------------------------------------------------------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
* added Multitap support (EA 4-Way Play and Sega Teamplayer): allowed up to four players in games supporting those peripherals
|
|
||||||
* added partial Sega Menacer lightgun support (use Analog Stick): automatically set when detecting the 6-in-1 Menacer game
|
|
||||||
|
|
||||||
|
|
||||||
----------------------------------------------------------------------------------------------------------------------------------------------------
|
|
||||||
[05/18/07] (Eke-Eke)
|
|
||||||
----------------------------------------------------------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
* you can now switch between FM cores without reseting the game. FM registers value are automatically restored when switching.
|
|
||||||
* removed the previous VINT timings modification because it brokes some games (Rocket Knight, Thunderforce III,...)
|
|
||||||
* added automatic Timing configuration (VDP latency, VINT timing & alternate Line Timing) at game loading, based upon specific romname detection.
|
|
||||||
This means you can still modify some of these options afterwards but they are now automatically set/unset when loading a game which need
|
|
||||||
special timing fixes. These fixes are also automatically desactivated when the current game doesn't need them.
|
|
||||||
For information, games that are actually detected and need special timings to run properly are:
|
|
||||||
.Legend of Galahad & Road Rash series (single line not rendered properly)
|
|
||||||
.Sesame Street Counting Cafe (don't boot)
|
|
||||||
.Chaos Engine/Soldiers of Fortune (graphic glitches on scrolling)
|
|
||||||
|
|
||||||
|
|
||||||
----------------------------------------------------------------------------------------------------------------------------------------------------
|
|
||||||
[05/08/07] (Eke-Eke)
|
|
||||||
----------------------------------------------------------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
* VINT timings are now a little more accurate: fixes Sesame's Street Counting Cafe
|
|
||||||
* SN76496 MAX_OUTPUT back to normal
|
|
||||||
* modified FB_WNOISE value in SN76496 core according to John Kortink's last informations
|
|
||||||
* added support for Maxim's PSG core, same as used in SMSPLUS (it becomes the default PSG core)
|
|
||||||
* updated FM core to the latest MAME version
|
|
||||||
* corrected DAC output level (fixes voices and some special FX being too low)
|
|
||||||
* added support for Gens YM2612 (FM) core (MAME's one still remains default FM core)
|
|
||||||
* added configurable preamplification for each sound cores (see Emulator Options)
|
|
||||||
* added some other configurable sound options (boost overall volume, FM improvment for Gens YM2612)
|
|
||||||
|
|
||||||
|
|
||||||
----------------------------------------------------------------------------------------------------------------------------------------------------
|
|
||||||
[04/11/07] (Eke-Eke)
|
|
||||||
----------------------------------------------------------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
* corrected MAX_OUTPUT value in SN76496 core: fix PSG sound (SFX) volume
|
|
||||||
|
|
||||||
|
|
||||||
----------------------------------------------------------------------------------------------------------------------------------------------------
|
|
||||||
[03/17/07] (Eke-Eke)
|
|
||||||
----------------------------------------------------------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
* added an option to enable alternate line rendering timing (fix single line error in Road Rash series and Legend of Galahad's Intro)
|
|
||||||
* Color RAM update now always reset color 0 to border color (fix color glitches in Mortal Kombat,...) (thanks to Noop's for the idea)
|
|
||||||
|
|
||||||
|
|
||||||
----------------------------------------------------------------------------------------------------------------------------------------------------
|
|
||||||
[03/09/07] (Eke-Eke)
|
|
||||||
----------------------------------------------------------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
* modified HV counter tables (fix graphic glitches in Skitchin's sky, Lotus 2 Recs, Panorama Cotton, Dashin Desperados & maybe more)
|
|
||||||
* completely rewrote DMA timings emulation so that it works for all games (no more cpu freezing)
|
|
||||||
* added all DMA tranfer rates handling for each three DMA modes and added dma busy flag emulation
|
|
||||||
* modified interrupts handling on VDP register #0 and #1 writes (fix Lemmings status bar)
|
|
||||||
* added VDP RAM write latency (fix Chaos Engine/Soldier of Fortune gfx glitches)
|
|
||||||
* modified FM timers handling a bit (fix Vectorman2 music)
|
|
||||||
* corrected Sprite Limit rendering (fix Sonic 1 & Micromachines 2 title screens)
|
|
||||||
* corrected IO Registers writes (fix Decap' Attack controls, no more need for alternate input)
|
|
||||||
* corrected 6 Buttons Pad emulation (fix 6buttons detection in Mortal Kombat 3, Comix Zone and other 6-buttons compatible games)
|
|
||||||
* modified sound mixing a bit according to Generator sourcecode (FM and PSG ratios seems more correct)
|
|
||||||
|
|
||||||
|
|
||||||
----------------------------------------------------------------------------------------------------------------------------------------------------
|
|
||||||
[02/07/07] (Eke-Eke)
|
|
||||||
----------------------------------------------------------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
* fixed fm timers (fix missing music in Castle of Illusion, Quackshot, Undead Line, Wonderboy in Monster Lair, Cal 50, Turbo Outrun, Thundeforce 4 and maybe more)
|
|
||||||
* added complete EEPROM emulation (save support now works fine in Wonderboy5, Megaman Willy Wars, NBA Jam...) (credits to Notaz, adapted from Picodrive code)
|
|
||||||
* added preliminar dma timing emulation (fix bottom screen in Legend of Galahad) (credits to Notaz, adapted from Picodrive code)
|
|
||||||
* hack: clear Vint pending after Hint (INT level 4) acknowledge (fix Fatal Rewind)
|
|
||||||
* hack: modify read_bus16 to return a random value (fake fetch) (fix Time Killers)
|
|
||||||
* modified cpu execution timings, with more correct hblank and interrupts timing (fix ISS Deluxe, Double Dragon 2 and certainly more) (Based on Gens code)
|
|
||||||
* modified busreq mechanism: better synchro between z80 & 68k (no need to dejitter anymore) (Based on Gens code)
|
|
||||||
* added sprite collision detection (fix Strider 2)
|
|
||||||
* modified dma fill operation for big endian platform (fix Contra Hardcorps gfx garbage)
|
|
||||||
|
|
||||||
|
|
||||||
----------------------------------------------------------------------------------------------------------------------------------------------------
|
|
||||||
[05/25/03] (Charles MacDonald)
|
|
||||||
----------------------------------------------------------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
* Fixed a typo that made Z80 banked access to the VDP registers always fail.
|
|
||||||
|
|
||||||
|
|
||||||
----------------------------------------------------------------------------------------------------------------------------------------------------
|
|
||||||
[05/17/03] (Charles MacDonald)
|
|
||||||
----------------------------------------------------------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
* Modified the rendering code to handle unaligned longword access to memory.
|
|
||||||
|
|
||||||
|
|
||||||
----------------------------------------------------------------------------------------------------------------------------------------------------
|
|
||||||
[04/20/03] (Charles MacDonald)
|
|
||||||
----------------------------------------------------------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
* Modified 68000 emulator to prevent 'tas.b $mem' from writing data back
|
|
||||||
after a read (fixes Gargoyles).
|
|
||||||
* Fixed bug in 68000 emulator to swap order of words written for address
|
|
||||||
register indirect pre-decremented writes (fixes Jim Power graphics).
|
|
||||||
* Added support for 240-line displays (for Super Skidmarks).
|
|
||||||
* Rewrote part of the interrupt handling (fixes some raster effects).
|
|
||||||
* Removed sprite collision detection code (never really worked).
|
|
||||||
* Optimized sprite rendering inner loop.
|
|
||||||
|
|
||||||
|
|
||||||
----------------------------------------------------------------------------------------------------------------------------------------------------
|
|
||||||
[04/13/03] (Charles MacDonald)
|
|
||||||
----------------------------------------------------------------------------------------------------------------------------------------------------
|
|
||||||
* Finished up memory map for VDP DMA V-bus reads.
|
|
||||||
* Fixed handling of 68000 writes to I/O chip at even addresses.
|
|
||||||
* Fixed bit 7 handling of control register in I/O chip.
|
|
||||||
* Finished up Z80 memory map.
|
|
||||||
* Added code to handle Genesis hardware lock-ups.
|
|
||||||
* Removed some faulty code from the 68000 memory map handlers.
|
|
||||||
|
|
||||||
|
|
||||||
----------------------------------------------------------------------------------------------------------------------------------------------------
|
|
||||||
[03/22/03] (Charles MacDonald)
|
|
||||||
----------------------------------------------------------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
* Completed implementation of Z80 banked memory handlers.
|
|
||||||
|
|
@ -1,89 +0,0 @@
|
|||||||
|
|
||||||
Introduction
|
|
||||||
|
|
||||||
Genesis Plus has reasonable speed, and very fast rendering. Here are some
|
|
||||||
details about porting it to another platform
|
|
||||||
|
|
||||||
Porting rules
|
|
||||||
|
|
||||||
- This program is released under the GPL, so please release the source
|
|
||||||
code for your derivative ports. Let me know if you need an alternative
|
|
||||||
to this.
|
|
||||||
|
|
||||||
- Do not change the name of the emulator. Something like 'Genesis Plus / MacOS'
|
|
||||||
is fine as it keeps the original name.
|
|
||||||
|
|
||||||
- Configure the CPU emulators for little or big-endian CPUs, and use the
|
|
||||||
ALIGN_LONG option to handle unaligned memory accesses if needed. E.g. if
|
|
||||||
the emulator crashes when a game scrolls horizontally, you need to enable
|
|
||||||
it.
|
|
||||||
|
|
||||||
Requirements
|
|
||||||
|
|
||||||
- At this time the 16-bit rendering code has been well tested and should
|
|
||||||
be used. There is code to support 8 through 32-bit displays, but I
|
|
||||||
haven't checked if it still works.
|
|
||||||
|
|
||||||
- Audio output, if enabled, uses stereo 16-bit samples.
|
|
||||||
|
|
||||||
Functions to use:
|
|
||||||
|
|
||||||
int load_rom(char *filename);
|
|
||||||
|
|
||||||
Loads a game which can be in BIN, SMD or ZIP formats. It returns zero if
|
|
||||||
an error has occured.
|
|
||||||
|
|
||||||
void system_init(void);
|
|
||||||
|
|
||||||
Initializes the virtual Genesis console. Call this once during startup.
|
|
||||||
|
|
||||||
void audio_init(int rate);
|
|
||||||
|
|
||||||
Initialize the sound emulation part of the emulator. Pass zero or don't
|
|
||||||
call the function to disable sound. Call this after running system_init().
|
|
||||||
|
|
||||||
void system_reset(void);
|
|
||||||
|
|
||||||
Resets the virtual Genesis console. Call this once during setup, and later
|
|
||||||
as needed.
|
|
||||||
|
|
||||||
int system_frame(int skip);
|
|
||||||
|
|
||||||
Updates the emulation for a frame. Pass 1 to prevent rendering (which can
|
|
||||||
be used for frame skipping) and 0 to render the current display.
|
|
||||||
|
|
||||||
This function returns 0 if the virtual Genesis console has locked up.
|
|
||||||
You can do what you'd like with this information, such as notify the user,
|
|
||||||
reset the machine, etc.
|
|
||||||
|
|
||||||
If audio is enabled, the snd.buffer[] array will hold the current audio
|
|
||||||
data for this frame.
|
|
||||||
|
|
||||||
void system_shutdown(void);
|
|
||||||
|
|
||||||
Shuts down the emulator.
|
|
||||||
|
|
||||||
Variables:
|
|
||||||
|
|
||||||
The 'bitmap' structure needs to be filled out prior to calling system_init().
|
|
||||||
This provides the rendering code with information about the type of bitmap
|
|
||||||
it is rendering to. I would advise sticking with a 1024x512 16-bit bitmap:
|
|
||||||
|
|
||||||
memset(&bitmap, 0, sizeof(t_bitmap));
|
|
||||||
bitmap.width = 1024;
|
|
||||||
bitmap.height = 512;
|
|
||||||
bitmap.depth = 16;
|
|
||||||
bitmap.granularity = 2; /* Bytes per pixel */
|
|
||||||
bitmap.pitch = (bitmap.width * bitmap.granularity);
|
|
||||||
bitmap.data = (unsigned char *)bmp->pixels; /* Pointer to your bitmap */
|
|
||||||
bitmap.viewport.w = 256; /* Initial size of display on power-up (do not change) */
|
|
||||||
bitmap.viewport.h = 224;
|
|
||||||
bitmap.viewport.x = 0x20; /* Offset used for rendering (do not change) */
|
|
||||||
bitmap.viewport.y = 0x00;
|
|
||||||
bitmap.remap = 1;
|
|
||||||
|
|
||||||
The variable 'input.pad[0]' holds the button states for the first player
|
|
||||||
gamepad. Update this prior to calling system_frame(), and use the bitmasks
|
|
||||||
defined in system.h such as 'INPUT_UP', etc.
|
|
||||||
|
|
||||||
See the Windows/SDL and DOS drivers for examples.
|
|
@ -1,186 +0,0 @@
|
|||||||
----------------------------------------------------------------------------
|
|
||||||
Genesis Plus
|
|
||||||
----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
based on the original version 1.2a
|
|
||||||
by Charles Mac Donald
|
|
||||||
WWW: http://cgfm2.emuviews.com
|
|
||||||
|
|
||||||
version 1.4
|
|
||||||
by Eke-Eke
|
|
||||||
WWW: http://code.google.com/p/genplus-gx
|
|
||||||
|
|
||||||
|
|
||||||
What's New
|
|
||||||
----------
|
|
||||||
|
|
||||||
see CHANGELOG
|
|
||||||
|
|
||||||
|
|
||||||
Features
|
|
||||||
---------
|
|
||||||
|
|
||||||
* NTSC (60Hz) & PAL (50Hz) hardware emulation
|
|
||||||
* highly accurate 68000 & Z80 CPU emulation
|
|
||||||
* highly accurate VDP emulation (HBLANK, DMA, FIFO, HV interrupts, undocumented registers, display mid-line changes…)
|
|
||||||
* cycle-accurate YM2612 emulation (FM synthesis is done at the original frequency, using FIR resampling)
|
|
||||||
* cycle-accurate chip synchronization (68000/Z80/YM2612/SN76489)
|
|
||||||
* basic hardware latency emulation (VDP/68k, Z80/68k)
|
|
||||||
* full overscan area (horizontal & vertical colored borders) emulation (optional)
|
|
||||||
* accurate TMSS model emulation incl. internal BIOS support (optional)
|
|
||||||
* Blargg's software NTSC filters support (optional)
|
|
||||||
* PICO emulation (partial)
|
|
||||||
* 3-buttons & 6-buttons controllers support
|
|
||||||
* Sega Team Player & EA 4-Way Play multitap adapters support
|
|
||||||
* Sega Menacer & Konami Justifier lightguns support
|
|
||||||
* Sega Mouse support
|
|
||||||
* J-Cart adapter support(Micro Machines & Pete Sampras series, Super Skidmarks)
|
|
||||||
* SVP DSP emulation (Virtua Racing)
|
|
||||||
* SRAM support (up to 64kB)
|
|
||||||
* serial EEPROM emulation (all known chips)
|
|
||||||
* ROM bankswitch hardware support (Super Street Fighter 2)
|
|
||||||
* ROM/SRAM bankswitch hardware support (Phantasy Star 4, Legend of Thor, Sonic the Hedgehog 3)
|
|
||||||
* emulates most banking & copy protection devices used in unlicensed/pirate cartridges
|
|
||||||
* native Game Genie & Action Replay hardware emulation
|
|
||||||
* Lock-On hardware emulation
|
|
||||||
* support for ROM image up to 10MB (Ultimate MK3 hack)
|
|
||||||
|
|
||||||
|
|
||||||
Usage
|
|
||||||
-----
|
|
||||||
|
|
||||||
The Windows version runs windowed in a 16-bit desktop with 48Hz sound using SDL but
|
|
||||||
without joystick support.
|
|
||||||
|
|
||||||
The DOS version has most of the functionality from SMS Plus, such
|
|
||||||
as audio, joysticks, etc.
|
|
||||||
|
|
||||||
Windows/DOS controls:
|
|
||||||
|
|
||||||
Arrow Keys - Directional pad
|
|
||||||
A,S,D,F - 1P gamepad, buttons A, B, C, StartTab - Hard Reset
|
|
||||||
Esc - Exit program
|
|
||||||
|
|
||||||
F7 - Load Savestate (game.gpz)
|
|
||||||
F8 - Save Savestate (game.gpz)
|
|
||||||
F9 - Toggle CPU clock: PAL(50hz)/NTSC(60hz)
|
|
||||||
F10 - Soft Reset
|
|
||||||
F11 - Toggle Border emulation (vertical only)
|
|
||||||
F12 - Toggle Player # (keyboard/mouse)
|
|
||||||
|
|
||||||
DOS only:
|
|
||||||
|
|
||||||
F1-F4 - Set frameskip level (F1 = no skip ... F4 = skip 3 frames)
|
|
||||||
|
|
||||||
Windows only:
|
|
||||||
|
|
||||||
F4 - Toggle Audio (ONLY when Turbo mode is OFF)
|
|
||||||
F6 - Toggle Turbo mode (ONLY when Audio is OFF)
|
|
||||||
|
|
||||||
|
|
||||||
The mouse can be used for lightgun games, PICO games and when the Sega Mouse is activated.
|
|
||||||
|
|
||||||
A SRAM file (game.srm) is automatically saved on exit and loaded on startup.
|
|
||||||
|
|
||||||
DOS details:
|
|
||||||
|
|
||||||
You can only support a second player if you are using a joystick driver
|
|
||||||
that supports more than one joystick. (e.g. Sidewinder, dual pads, etc.)
|
|
||||||
|
|
||||||
Type 'gen -help' on the command line for a list of useful options.
|
|
||||||
|
|
||||||
-res <x> <y> set the display resolution.
|
|
||||||
-vdriver <n> specify video driver.
|
|
||||||
-depth <n> specify color depth. (8, 16)
|
|
||||||
-scanlines use scanlines effect.
|
|
||||||
-scale scale display to full resolution. (slow)
|
|
||||||
-vsync wait for vertical sync before blitting.
|
|
||||||
-sound enable sound. (force speed throttling)
|
|
||||||
-sndrate <n> specify sound rate. (8000, 11025, 22050, 44100)
|
|
||||||
-sndcard <n> specify sound card. (0-7)
|
|
||||||
-swap swap left and right stereo output.
|
|
||||||
-joy <s> specify joystick type.
|
|
||||||
|
|
||||||
Here is a list of all the video drivers you can pass as a parameter
|
|
||||||
to the '-vdriver' option:
|
|
||||||
|
|
||||||
auto, safe, vga, modex, vesa2l, vesa3, vbeaf
|
|
||||||
|
|
||||||
Here is a list of all the joystick drivers you can pass as a parameter
|
|
||||||
to the '-joy' option:
|
|
||||||
|
|
||||||
auto, none, standard, 2pads, 4button, 6button, 8button, fspro, wingex,
|
|
||||||
sidewinder, gamepadpro, grip, grip4, sneslpt1, sneslpt2, sneslpt3,
|
|
||||||
psxlpt1, psxlpt2, psxlpt3, n64lpt1, n64lpt2, n64lpt3, db9lpt1, db9lpt2,
|
|
||||||
db9lpt3, tglpt1, tglpt2, tglpt3, wingwar, segaisa, segapci, segapci2
|
|
||||||
|
|
||||||
You can put any commandline option into a plain text file which should
|
|
||||||
be called "gen.cfg". Put one option per line, please. Command line options
|
|
||||||
will override anything in the configuration file.
|
|
||||||
|
|
||||||
Currently the zip loading code can manage a zipfile where the game
|
|
||||||
image is the first thing in it. If you try to open a huge archive of
|
|
||||||
games, only the first will be played.
|
|
||||||
|
|
||||||
Credits and Acknowlegements
|
|
||||||
---------------------------
|
|
||||||
|
|
||||||
I would like to thank Omar Cornut, Christian Schiller, and Chris MacDonald
|
|
||||||
for their invaluable help and support with this project.
|
|
||||||
|
|
||||||
Richard Bannister for the Macintosh port and all of the code fixes and
|
|
||||||
suggestions that have made Genesis Plus a better program.
|
|
||||||
(http://www.bannister.org)
|
|
||||||
|
|
||||||
Extra features, emulation accuracy & game compatibility improvments by Eke-Eke
|
|
||||||
(from the Gamecube/Wii port: http://code.google.com/p/genplus-gx )
|
|
||||||
|
|
||||||
The Genesis emulator authors: Bart Trzynadlowski, Quintesson, Steve Snake,
|
|
||||||
James Ponder, Stef, Gerrie, Sardu, AamirM
|
|
||||||
|
|
||||||
The regular people and many lurkers at segadev and spritesmind.net.
|
|
||||||
|
|
||||||
The MAME team for the CPU and sound chip emulators.
|
|
||||||
|
|
||||||
Maxim for his SN76489 emulator.
|
|
||||||
|
|
||||||
Nemesis for his researches about the YM2612 and VDP.
|
|
||||||
|
|
||||||
Notaz for his SVP emulator.
|
|
||||||
|
|
||||||
Tasco Deluxe for his documentation of Realtec mapper.
|
|
||||||
|
|
||||||
Haze for his reverse-engineering of most unlicensed games protection.
|
|
||||||
|
|
||||||
Shay Green (Blargg) for his FIR Resampler & NTSC Video Filter.
|
|
||||||
|
|
||||||
Neil C for his 3-Band EQ implementation.
|
|
||||||
|
|
||||||
Jean-Loup Gailly and Mark Adler for their useful zip library.
|
|
||||||
|
|
||||||
|
|
||||||
Contact
|
|
||||||
-------
|
|
||||||
|
|
||||||
Charles MacDonald
|
|
||||||
E-mail: cgfm2@hotmail.com
|
|
||||||
WWW: http://cgfm2.emuviews.com
|
|
||||||
|
|
||||||
Eke-Eke
|
|
||||||
E-mail: eke_eke31@yahoo.fr
|
|
||||||
WWW: http://code.google.com/p/genplus-gx
|
|
||||||
|
|
||||||
|
|
||||||
Legal
|
|
||||||
-----
|
|
||||||
|
|
||||||
Copyright (C) 1999, 2000, 2001, 2002, 2003 Charles MacDonald
|
|
||||||
Copyright (C) 2006-2010 Eke-Eke
|
|
||||||
|
|
||||||
The source code is distributed under the terms of the GNU General Public
|
|
||||||
License.
|
|
||||||
|
|
||||||
The Z80 CPU emulator, 68K CPU emulator, and the YM2612 emulation code
|
|
||||||
are taken from the MAME project, and terms of their use are covered under
|
|
||||||
the MAME license. (http://www.mame.net)
|
|
||||||
|
|
@ -1,151 +0,0 @@
|
|||||||
# Makefile for genplus DOS
|
|
||||||
#
|
|
||||||
# (c) 1999, 2000, 2001, 2002, 2003 Charles MacDonald
|
|
||||||
# modified by Eke-Eke <eke_eke31@yahoo.fr>
|
|
||||||
#
|
|
||||||
# Defines :
|
|
||||||
# -DLSB_FIRST - Leave undefined for big-endian processors.
|
|
||||||
# -DDOS - Enable DOS/x86 specific code.
|
|
||||||
# -DDEBUG - Enable debugging code
|
|
||||||
# -DX86_ASM - Enable inline x86 assembly code in Z80 emulator
|
|
||||||
|
|
||||||
CC = gcc
|
|
||||||
AS = nasm -f coff
|
|
||||||
LDFLAGS =
|
|
||||||
FLAGS = -I. -I.. -I../z80 -I../m68k -I../dos -I../sound -I../sound/SRC -I../cart_hw -I../cart_hw/svp -I../ntsc \
|
|
||||||
-Wall -g \
|
|
||||||
-O6 -march=i686 -fomit-frame-pointer \
|
|
||||||
-DLSB_FIRST -DX86_ASM -DDOS
|
|
||||||
|
|
||||||
LIBS = -lalleg -laudio -lz -lm
|
|
||||||
|
|
||||||
OBJECTS = obj/z80.o
|
|
||||||
|
|
||||||
OBJECTS += obj/m68kcpu.o \
|
|
||||||
obj/m68kops.o
|
|
||||||
|
|
||||||
|
|
||||||
OBJECTS += obj/genesis.o \
|
|
||||||
obj/vdp_ctrl.o \
|
|
||||||
obj/vdp_render.o \
|
|
||||||
obj/system.o \
|
|
||||||
obj/io_ctrl.o \
|
|
||||||
obj/mem68k.o \
|
|
||||||
obj/memz80.o \
|
|
||||||
obj/membnk.o \
|
|
||||||
obj/state.o
|
|
||||||
|
|
||||||
OBJECTS += obj/input.o \
|
|
||||||
obj/gamepad.o \
|
|
||||||
obj/lightgun.o \
|
|
||||||
obj/mouse.o \
|
|
||||||
obj/activator.o \
|
|
||||||
obj/xe_a1p.o \
|
|
||||||
obj/teamplayer.o \
|
|
||||||
obj/paddle.o \
|
|
||||||
obj/sportspad.o
|
|
||||||
|
|
||||||
|
|
||||||
OBJECTS += obj/sound.o \
|
|
||||||
obj/sn76489.o \
|
|
||||||
obj/ym2612.o
|
|
||||||
|
|
||||||
OBJECTS += obj/Fir_Resampler.o
|
|
||||||
OBJECTS += obj/blip.o
|
|
||||||
|
|
||||||
OBJECTS += obj/eq.o \
|
|
||||||
|
|
||||||
OBJECTS += obj/sram.o \
|
|
||||||
obj/eeprom.o \
|
|
||||||
obj/svp.o \
|
|
||||||
obj/ssp16.o \
|
|
||||||
obj/ggenie.o \
|
|
||||||
obj/areplay.o \
|
|
||||||
obj/md_cart.o \
|
|
||||||
obj/sms_cart.o
|
|
||||||
|
|
||||||
OBJECTS += obj/dos.o \
|
|
||||||
obj/sealintf.o \
|
|
||||||
obj/config.o \
|
|
||||||
obj/error.o \
|
|
||||||
obj/unzip.o \
|
|
||||||
obj/fileio.o \
|
|
||||||
obj/loadrom.o
|
|
||||||
|
|
||||||
OBJECTS += obj/sms_ntsc.o \
|
|
||||||
obj/md_ntsc.o
|
|
||||||
|
|
||||||
|
|
||||||
EXE = ../gen.exe
|
|
||||||
|
|
||||||
all : $(EXE)
|
|
||||||
|
|
||||||
$(EXE) : $(OBJ)
|
|
||||||
$(CC) -o $(EXE) $(OBJ) $(LIBS) $(LDFLAGS)
|
|
||||||
|
|
||||||
obj/%.o : ../%.c ../%.h
|
|
||||||
$(CC) -c $< -o $@ $(FLAGS)
|
|
||||||
|
|
||||||
obj/%.o : ../asm/%.s
|
|
||||||
$(AS) $< -o $@
|
|
||||||
|
|
||||||
obj/%.o : ../sound/%.c ../sound/%.h
|
|
||||||
$(CC) -c $< -o $@ $(FLAGS)
|
|
||||||
obj/%.o : ../sound/%.c
|
|
||||||
$(CC) -c $< -o $@ $(FLAGS)
|
|
||||||
|
|
||||||
obj/%.o : ../sound/SRC/%.c ../sound/SRC/%.h
|
|
||||||
$(CC) -c $< -o $@ $(FLAGS)
|
|
||||||
obj/%.o : ../sound/SRC/%.c
|
|
||||||
$(CC) -c $< -o $@ $(FLAGS)
|
|
||||||
|
|
||||||
obj/%.o : ../input_hw/%.c ../input_hw/%.h
|
|
||||||
$(CC) -c $< -o $@ $(FLAGS)
|
|
||||||
|
|
||||||
obj/%.o : ../cart_hw/%.c ../cart_hw/%.h
|
|
||||||
$(CC) -c $< -o $@ $(FLAGS)
|
|
||||||
|
|
||||||
obj/%.o : ../cart_hw/svp/%.c
|
|
||||||
$(CC) -c $< -o $@ $(FLAGS)
|
|
||||||
|
|
||||||
obj/%.o : ../cart_hw/svp/%.c ../cart_hw/svp/%.h
|
|
||||||
$(CC) -c $< -o $@ $(FLAGS)
|
|
||||||
|
|
||||||
obj/%.o : ../z80/%.c ../z80/%.h
|
|
||||||
$(CC) -c $< -o $@ $(FLAGS)
|
|
||||||
|
|
||||||
obj/%.o : ../m68k/%.c ../m68k/%.h
|
|
||||||
$(CC) -c $< -o $@ $(FLAGS)
|
|
||||||
|
|
||||||
obj/%.o : ./%.c ./%.h
|
|
||||||
$(CC) -c $< -o $@ $(FLAGS)
|
|
||||||
|
|
||||||
|
|
||||||
obj/%.o : ../ntsc/%.c ../ntsc/%.h
|
|
||||||
$(CC) -c $(CFLAGS) $(INCLUDES) $(DEFINES) $< -o $@
|
|
||||||
|
|
||||||
pack :
|
|
||||||
strip $(EXE)
|
|
||||||
upx -1 $(EXE)
|
|
||||||
|
|
||||||
clean :
|
|
||||||
rm -f obj/*.o
|
|
||||||
rm -f *.bak
|
|
||||||
rm -f *.exe
|
|
||||||
rm -f *.log
|
|
||||||
rm -f *.wav
|
|
||||||
rm -f *.zip
|
|
||||||
cleancpu :
|
|
||||||
rm -f obj/z80.oa
|
|
||||||
|
|
||||||
makedir :
|
|
||||||
mkdir obj
|
|
||||||
|
|
||||||
archive:
|
|
||||||
pk -dir -add -max \
|
|
||||||
-excl=rom -excl=test \
|
|
||||||
mdsrc.zip *.*
|
|
||||||
|
|
||||||
#
|
|
||||||
# end of makefile
|
|
||||||
#
|
|
@ -1,288 +0,0 @@
|
|||||||
|
|
||||||
#include "osd.h"
|
|
||||||
|
|
||||||
int seal_sample_rate = 44100;
|
|
||||||
int seal_sound_card = -1;
|
|
||||||
|
|
||||||
HAC hVoice[NUMVOICES];
|
|
||||||
LPAUDIOWAVE lpWave[NUMVOICES];
|
|
||||||
AUDIOINFO info;
|
|
||||||
AUDIOCAPS caps;
|
|
||||||
int c[MAX_STREAM_CHANNELS];
|
|
||||||
int nominal_sample_rate;
|
|
||||||
static int attenuation = 0;
|
|
||||||
static int master_volume = 256;
|
|
||||||
|
|
||||||
|
|
||||||
void osd_update_audio(void)
|
|
||||||
{
|
|
||||||
if (seal_sample_rate == 0) return;
|
|
||||||
AUpdateAudio();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* attenuation in dB */
|
|
||||||
void osd_set_mastervolume(int _attenuation)
|
|
||||||
{
|
|
||||||
float volume;
|
|
||||||
|
|
||||||
attenuation = _attenuation;
|
|
||||||
|
|
||||||
volume = 256.0; /* range is 0-256 */
|
|
||||||
while (_attenuation++ < 0)
|
|
||||||
volume /= 1.122018454; /* = (10 ^ (1/20)) = 1dB */
|
|
||||||
|
|
||||||
master_volume = volume;
|
|
||||||
|
|
||||||
ASetAudioMixerValue(AUDIO_MIXER_MASTER_VOLUME,master_volume);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int msdos_init_sound(int *rate, int card)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
seal_sample_rate = *rate;
|
|
||||||
seal_sound_card = card;
|
|
||||||
|
|
||||||
if (AInitialize() != AUDIO_ERROR_NONE)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
/* Ask the user if no sound card was chosen */
|
|
||||||
if (seal_sound_card == -1)
|
|
||||||
{
|
|
||||||
unsigned int k;
|
|
||||||
|
|
||||||
printf("\n SELECT YOUR AUDIO DEVICE :\n\n"
|
|
||||||
" AWE32/64 playback requires onboard DRAM,\n"
|
|
||||||
" Sound Blaster playback is the most compatible & better for emulation\n\n");
|
|
||||||
|
|
||||||
for (k = 0;k < AGetAudioNumDevs();k++)
|
|
||||||
{
|
|
||||||
if (AGetAudioDevCaps(k,&caps) == AUDIO_ERROR_NONE)
|
|
||||||
printf(" %2d. %s\n",k,caps.szProductName);
|
|
||||||
}
|
|
||||||
printf("\n");
|
|
||||||
|
|
||||||
if (k < 10)
|
|
||||||
{
|
|
||||||
i = getch();
|
|
||||||
seal_sound_card = i - '0';
|
|
||||||
}
|
|
||||||
else
|
|
||||||
scanf("%d",&seal_sound_card);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* initialize SEAL audio library */
|
|
||||||
if (seal_sound_card == 0) /* silence */
|
|
||||||
{
|
|
||||||
/* update the Machine structure to show that sound is disabled */
|
|
||||||
seal_sample_rate = 0;
|
|
||||||
exit(0);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* open audio device */
|
|
||||||
/* info.nDeviceId = AUDIO_DEVICE_MAPPER;*/
|
|
||||||
info.nDeviceId = seal_sound_card;
|
|
||||||
/* always use 16 bit mixing if possible - better quality and same speed of 8 bit */
|
|
||||||
info.wFormat = AUDIO_FORMAT_16BITS | AUDIO_FORMAT_STEREO | AUDIO_FORMAT_RAW_SAMPLE;
|
|
||||||
|
|
||||||
info.nSampleRate = seal_sample_rate;
|
|
||||||
if (AOpenAudio(&info) != AUDIO_ERROR_NONE)
|
|
||||||
{
|
|
||||||
return (1);
|
|
||||||
}
|
|
||||||
|
|
||||||
AGetAudioDevCaps(info.nDeviceId,&caps);
|
|
||||||
printf("Using `%s' at %d-bit %s %u Hz\n",
|
|
||||||
caps.szProductName,
|
|
||||||
info.wFormat & AUDIO_FORMAT_16BITS ? 16 : 8,
|
|
||||||
info.wFormat & AUDIO_FORMAT_STEREO ? "stereo" : "mono",
|
|
||||||
info.nSampleRate);
|
|
||||||
|
|
||||||
/* open and allocate voices, allocate waveforms */
|
|
||||||
if (AOpenVoices(NUMVOICES) != AUDIO_ERROR_NONE)
|
|
||||||
{
|
|
||||||
printf("voices initialization failed\n");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < NUMVOICES; i++)
|
|
||||||
{
|
|
||||||
if (ACreateAudioVoice(&hVoice[i]) != AUDIO_ERROR_NONE)
|
|
||||||
{
|
|
||||||
printf("voice #%d creation failed\n",i);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
ASetVoicePanning(hVoice[i],128);
|
|
||||||
|
|
||||||
lpWave[i] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* update the Machine structure to reflect the actual sample rate */
|
|
||||||
*rate = seal_sample_rate = info.nSampleRate;
|
|
||||||
|
|
||||||
{
|
|
||||||
uclock_t a,b;
|
|
||||||
LONG start,end;
|
|
||||||
|
|
||||||
|
|
||||||
if ((lpWave[0] = (LPAUDIOWAVE)malloc(sizeof(AUDIOWAVE))) == 0)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
lpWave[0]->wFormat = AUDIO_FORMAT_8BITS | AUDIO_FORMAT_MONO;
|
|
||||||
lpWave[0]->nSampleRate = seal_sample_rate;
|
|
||||||
lpWave[0]->dwLength = 3*seal_sample_rate;
|
|
||||||
lpWave[0]->dwLoopStart = 0;
|
|
||||||
lpWave[0]->dwLoopEnd = 3*seal_sample_rate;
|
|
||||||
if (ACreateAudioData(lpWave[0]) != AUDIO_ERROR_NONE)
|
|
||||||
{
|
|
||||||
free(lpWave[0]);
|
|
||||||
lpWave[0] = 0;
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
memset(lpWave[0]->lpData,0,3*seal_sample_rate);
|
|
||||||
/* upload the data to the audio DRAM local memory */
|
|
||||||
AWriteAudioData(lpWave[0],0,3*seal_sample_rate);
|
|
||||||
APrimeVoice(hVoice[0],lpWave[0]);
|
|
||||||
ASetVoiceFrequency(hVoice[0],seal_sample_rate);
|
|
||||||
ASetVoiceVolume(hVoice[0],0);
|
|
||||||
AStartVoice(hVoice[0]);
|
|
||||||
|
|
||||||
a = uclock();
|
|
||||||
/* wait some time to let everything stabilize */
|
|
||||||
do
|
|
||||||
{
|
|
||||||
osd_update_audio();
|
|
||||||
b = uclock();
|
|
||||||
} while (b-a < UCLOCKS_PER_SEC/10);
|
|
||||||
|
|
||||||
a = uclock();
|
|
||||||
AGetVoicePosition(hVoice[0],&start);
|
|
||||||
do
|
|
||||||
{
|
|
||||||
osd_update_audio();
|
|
||||||
b = uclock();
|
|
||||||
} while (b-a < UCLOCKS_PER_SEC);
|
|
||||||
AGetVoicePosition(hVoice[0],&end);
|
|
||||||
|
|
||||||
nominal_sample_rate = seal_sample_rate;
|
|
||||||
seal_sample_rate = end - start;
|
|
||||||
|
|
||||||
AStopVoice(hVoice[0]);
|
|
||||||
ADestroyAudioData(lpWave[0]);
|
|
||||||
free(lpWave[0]);
|
|
||||||
lpWave[0] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
osd_set_mastervolume(0); /* start at maximum volume */
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void msdos_shutdown_sound(void)
|
|
||||||
{
|
|
||||||
if (seal_sample_rate != 0)
|
|
||||||
{
|
|
||||||
int n;
|
|
||||||
|
|
||||||
/* stop and release voices */
|
|
||||||
for (n = 0; n < NUMVOICES; n++)
|
|
||||||
{
|
|
||||||
AStopVoice(hVoice[n]);
|
|
||||||
ADestroyAudioVoice(hVoice[n]);
|
|
||||||
if (lpWave[n])
|
|
||||||
{
|
|
||||||
ADestroyAudioData(lpWave[n]);
|
|
||||||
free(lpWave[n]);
|
|
||||||
lpWave[n] = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ACloseVoices();
|
|
||||||
ACloseAudio();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void playstreamedsample(int channel,signed char *data,int len,int freq,int volume,int pan,int bits)
|
|
||||||
{
|
|
||||||
static int playing[NUMVOICES];
|
|
||||||
static int c[NUMVOICES];
|
|
||||||
|
|
||||||
/* backwards compatibility with old 0-255 volume range */
|
|
||||||
if (volume > 100) volume = volume * 25 / 255;
|
|
||||||
|
|
||||||
if (seal_sample_rate == 0 || channel >= NUMVOICES) return;
|
|
||||||
|
|
||||||
if (!playing[channel])
|
|
||||||
{
|
|
||||||
if (lpWave[channel])
|
|
||||||
{
|
|
||||||
AStopVoice(hVoice[channel]);
|
|
||||||
ADestroyAudioData(lpWave[channel]);
|
|
||||||
free(lpWave[channel]);
|
|
||||||
lpWave[channel] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((lpWave[channel] = (LPAUDIOWAVE)malloc(sizeof(AUDIOWAVE))) == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
lpWave[channel]->wFormat = (bits == 8 ? AUDIO_FORMAT_8BITS : AUDIO_FORMAT_16BITS)
|
|
||||||
| AUDIO_FORMAT_MONO | AUDIO_FORMAT_LOOP;
|
|
||||||
lpWave[channel]->nSampleRate = nominal_sample_rate;
|
|
||||||
lpWave[channel]->dwLength = 3*len;
|
|
||||||
lpWave[channel]->dwLoopStart = 0;
|
|
||||||
lpWave[channel]->dwLoopEnd = 3*len;
|
|
||||||
if (ACreateAudioData(lpWave[channel]) != AUDIO_ERROR_NONE)
|
|
||||||
{
|
|
||||||
free(lpWave[channel]);
|
|
||||||
lpWave[channel] = 0;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
memset(lpWave[channel]->lpData,0,3*len);
|
|
||||||
memcpy(lpWave[channel]->lpData,data,len);
|
|
||||||
|
|
||||||
/* upload the data to the audio DRAM local memory */
|
|
||||||
AWriteAudioData(lpWave[channel],0,3*len);
|
|
||||||
APrimeVoice(hVoice[channel],lpWave[channel]);
|
|
||||||
|
|
||||||
/* need to cast to double because freq*nominal_sample_rate can exceed the size of an int */
|
|
||||||
ASetVoiceFrequency(hVoice[channel],(double)freq*nominal_sample_rate/seal_sample_rate);
|
|
||||||
AStartVoice(hVoice[channel]);
|
|
||||||
playing[channel] = 1;
|
|
||||||
c[channel] = 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
LONG pos;
|
|
||||||
|
|
||||||
for(;;)
|
|
||||||
{
|
|
||||||
AGetVoicePosition(hVoice[channel],&pos);
|
|
||||||
if (c[channel] == 0 && pos >= len) break;
|
|
||||||
if (c[channel] == 1 && (pos < len || pos >= 2*len)) break;
|
|
||||||
if (c[channel] == 2 && pos < 2*len) break;
|
|
||||||
osd_update_audio();
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(&lpWave[channel]->lpData[len * c[channel]],data,len);
|
|
||||||
AWriteAudioData(lpWave[channel],len*c[channel],len);
|
|
||||||
c[channel]++;
|
|
||||||
if (c[channel] == 3) c[channel] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
ASetVoiceVolume(hVoice[channel],volume * 64 / 100);
|
|
||||||
ASetVoicePanning(hVoice[channel],(pan + 100) * 255 / 200);
|
|
||||||
}
|
|
||||||
|
|
||||||
void osd_play_streamed_sample_16(int channel,signed short *data,int len,int freq,int volume,int pan)
|
|
||||||
{
|
|
||||||
playstreamedsample(channel,(signed char *)data,len,freq,volume,pan,16);
|
|
||||||
}
|
|
||||||
|
|
@ -1,17 +0,0 @@
|
|||||||
|
|
||||||
#ifndef _SEALINTF_H_
|
|
||||||
#define _SEALINTF_H_
|
|
||||||
|
|
||||||
#define MAX_SOUND 4
|
|
||||||
#define NUMVOICES 16
|
|
||||||
#define MAX_STREAM_CHANNELS 6
|
|
||||||
|
|
||||||
/* Function prototypes */
|
|
||||||
void osd_update_audio(void);
|
|
||||||
void osd_set_mastervolume(int _attenuation);
|
|
||||||
int msdos_init_sound(int *rate, int card);
|
|
||||||
void msdos_shutdown_sound(void);
|
|
||||||
void playstreamedsample(int channel,signed char *data,int len,int freq,int volume,int pan,int bits);
|
|
||||||
void osd_play_streamed_sample_16(int channel,signed short *data,int len,int freq,int volume,int pan);
|
|
||||||
|
|
||||||
#endif /* _SEALINTF_H_ */
|
|
@ -1,298 +0,0 @@
|
|||||||
|
|
||||||
#include "osd.h"
|
|
||||||
|
|
||||||
t_option option;
|
|
||||||
t_config config;
|
|
||||||
|
|
||||||
void do_config(char *file)
|
|
||||||
{
|
|
||||||
extern int __crt0_argc;
|
|
||||||
extern char **__crt0_argv;
|
|
||||||
|
|
||||||
/* Our token list */
|
|
||||||
int i, argc;
|
|
||||||
char *argv[TOKEN_LIST_SIZE];
|
|
||||||
|
|
||||||
set_option_defaults();
|
|
||||||
for(i = 0; i < TOKEN_LIST_SIZE; i += 1) argv[i] = NULL;
|
|
||||||
|
|
||||||
/* Check configuration file */
|
|
||||||
if(file) parse_file(file, &argc, argv);
|
|
||||||
|
|
||||||
/* Check extracted tokens */
|
|
||||||
parse_args(argc, argv);
|
|
||||||
|
|
||||||
/* Free token list */
|
|
||||||
for(i = 0; i < argc; i += 1) if(argv[argc]) free (argv[argc]);
|
|
||||||
|
|
||||||
/* Check command line */
|
|
||||||
parse_args(__crt0_argc, __crt0_argv);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Parse configuration file */
|
|
||||||
int parse_file(char *filename, int *argc, char **argv)
|
|
||||||
{
|
|
||||||
char token[0x100];
|
|
||||||
FILE *handle = NULL;
|
|
||||||
|
|
||||||
*argc = 0;
|
|
||||||
handle = fopen(filename, "r");
|
|
||||||
if(!handle) return (0);
|
|
||||||
|
|
||||||
fscanf(handle, "%s", &token[0]);
|
|
||||||
while(!(feof(handle)))
|
|
||||||
{
|
|
||||||
int size = strlen(token) + 1;
|
|
||||||
argv[*argc] = malloc(size);
|
|
||||||
if(!argv[*argc]) return (0);
|
|
||||||
strcpy(argv[*argc], token);
|
|
||||||
*argc += 1;
|
|
||||||
fscanf(handle, "%s", &token[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(handle) fclose(handle);
|
|
||||||
return (1);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int check_bool(char *token)
|
|
||||||
{
|
|
||||||
int result = 1;
|
|
||||||
if(stricmp("off", token) == 0)
|
|
||||||
result = 0;
|
|
||||||
if(stricmp("no", token) == 0)
|
|
||||||
result = 0;
|
|
||||||
return (result);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void set_option_defaults(void)
|
|
||||||
{
|
|
||||||
option.video_driver = GFX_AUTODETECT;
|
|
||||||
option.video_width = 640;
|
|
||||||
option.video_height = 480;
|
|
||||||
option.video_depth = 16;
|
|
||||||
|
|
||||||
option.remap = 0;
|
|
||||||
option.scanlines = 0;
|
|
||||||
option.scale = 0;
|
|
||||||
|
|
||||||
option.vsync = 0;
|
|
||||||
option.throttle = 0;
|
|
||||||
option.skip = 1;
|
|
||||||
|
|
||||||
option.sound = 0;
|
|
||||||
option.sndcard = -1;
|
|
||||||
option.sndrate = 48000;
|
|
||||||
option.swap = 0;
|
|
||||||
|
|
||||||
option.joy_driver = JOY_TYPE_NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void set_config_defaults(void)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
/* sound options */
|
|
||||||
config.psg_preamp = 150;
|
|
||||||
config.fm_preamp = 100;
|
|
||||||
config.hq_fm = 1;
|
|
||||||
config.psgBoostNoise = 0;
|
|
||||||
config.filter = 1;
|
|
||||||
config.low_freq = 200;
|
|
||||||
config.high_freq = 8000;
|
|
||||||
config.lg = 1.0;
|
|
||||||
config.mg = 1.0;
|
|
||||||
config.hg = 1.0;
|
|
||||||
config.lp_range = 50;
|
|
||||||
config.rolloff = 0.999;
|
|
||||||
|
|
||||||
/* system options */
|
|
||||||
config.region_detect = 0;
|
|
||||||
config.force_dtack = 0;
|
|
||||||
config.addr_error = 1;
|
|
||||||
config.tmss = 0;
|
|
||||||
config.lock_on = 0;
|
|
||||||
config.romtype = 0;
|
|
||||||
|
|
||||||
/* display options */
|
|
||||||
config.overscan = 1;
|
|
||||||
config.render = 0;
|
|
||||||
|
|
||||||
/* controllers options */
|
|
||||||
input.system[0] = SYSTEM_MD_GAMEPAD;
|
|
||||||
input.system[1] = SYSTEM_MD_GAMEPAD;
|
|
||||||
config.gun_cursor[0] = 1;
|
|
||||||
config.gun_cursor[1] = 1;
|
|
||||||
config.invert_mouse = 0;
|
|
||||||
for (i=0;i<MAX_INPUTS;i++)
|
|
||||||
config.input[i].padtype = DEVICE_PAD3B;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void print_options(void)
|
|
||||||
{
|
|
||||||
printf(" -vdriver <s> \t Select video driver (auto)\n");
|
|
||||||
printf(" -res <w> <h> \t Specify display resolution (320x240)\n");
|
|
||||||
printf(" -depth <n> \t Specify display depth (8)\n");
|
|
||||||
printf(" -remap <on|off> \t Enable raster-based palette effects (8-bit color only)\n");
|
|
||||||
printf(" -scanlines <on|off> \t Enable scanlines effect\n");
|
|
||||||
printf(" -scale <on|off> \t Scale display to width of screen\n");
|
|
||||||
printf(" -vsync <on|off> \t Enable vsync polling\n");
|
|
||||||
printf(" -throttle <on|off> \t Enable speed throttling\n");
|
|
||||||
printf(" -skip <n> \t Specify frame skip level (1=no frames skipped)\n");
|
|
||||||
printf(" -sound <on|off> \t Enable sound output\n");
|
|
||||||
printf(" -sndcard <n> \t Select sound card\n");
|
|
||||||
printf(" -sndrate <n> \t Specify sound sample rate (8000-44100)\n");
|
|
||||||
printf(" -swap <on|off> \t Swap left and right channels\n");
|
|
||||||
printf(" -joy <s> \t Select joystick driver (auto)\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void parse_args(int argc, char **argv)
|
|
||||||
{
|
|
||||||
int i, j;
|
|
||||||
|
|
||||||
for(i = 0; i < argc; i += 1)
|
|
||||||
{
|
|
||||||
if(stricmp("-vdriver", argv[i]) == 0)
|
|
||||||
{
|
|
||||||
for(j = 0; video_driver_table[j].token != NULL; j += 1)
|
|
||||||
{
|
|
||||||
if(stricmp(argv[i+1], video_driver_table[j].token) == 0)
|
|
||||||
{
|
|
||||||
option.video_driver = video_driver_table[j].value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(stricmp("-res", argv[i]) == 0)
|
|
||||||
{
|
|
||||||
option.video_width = atoi(argv[i+1]);
|
|
||||||
option.video_height = atoi(argv[i+2]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(stricmp("-depth", argv[i]) == 0)
|
|
||||||
{
|
|
||||||
option.video_depth = atoi(argv[i+1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(stricmp("-remap", argv[i]) == 0)
|
|
||||||
{
|
|
||||||
option.remap = check_bool(argv[i+1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(stricmp("-scanlines", argv[i]) == 0)
|
|
||||||
{
|
|
||||||
option.scanlines = check_bool(argv[i+1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(stricmp("-scale", argv[i]) == 0)
|
|
||||||
{
|
|
||||||
option.scale = check_bool(argv[i+1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(stricmp("-vsync", argv[i]) == 0)
|
|
||||||
{
|
|
||||||
option.vsync = check_bool(argv[i+1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(stricmp("-throttle", argv[i]) == 0)
|
|
||||||
{
|
|
||||||
option.throttle = check_bool(argv[i+1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(stricmp("-skip", argv[i]) == 0)
|
|
||||||
{
|
|
||||||
option.skip = atoi(argv[i+1]);
|
|
||||||
if(!option.skip) option.skip = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(stricmp("-sound", argv[i]) == 0)
|
|
||||||
{
|
|
||||||
option.sound = check_bool(argv[i+1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(stricmp("-sndcard", argv[i]) == 0)
|
|
||||||
{
|
|
||||||
option.sndcard = atoi(argv[i+1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(stricmp("-sndrate", argv[i]) == 0)
|
|
||||||
{
|
|
||||||
option.sndrate = atoi(argv[i+1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(stricmp("-swap", argv[i]) == 0)
|
|
||||||
{
|
|
||||||
option.swap = check_bool(argv[i+1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(stricmp("-joy", argv[i]) == 0)
|
|
||||||
{
|
|
||||||
for(j = 0; joy_driver_table[j].token != NULL; j += 1)
|
|
||||||
{
|
|
||||||
if(stricmp(argv[i+1], joy_driver_table[j].token) == 0)
|
|
||||||
{
|
|
||||||
option.joy_driver = joy_driver_table[j].value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(option.remap) option.video_depth = 8;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
t_strint video_driver_table[] =
|
|
||||||
{
|
|
||||||
{ "auto", GFX_AUTODETECT },
|
|
||||||
{ "safe", GFX_SAFE },
|
|
||||||
{ "vga", GFX_VGA },
|
|
||||||
{ "modex", GFX_MODEX },
|
|
||||||
{ "vesa2l", GFX_VESA2L },
|
|
||||||
{ "vesa3", GFX_VESA3 },
|
|
||||||
{ "vbeaf", GFX_VBEAF },
|
|
||||||
{ NULL, 0 }
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
t_strint joy_driver_table[] =
|
|
||||||
{
|
|
||||||
{ "auto", JOY_TYPE_AUTODETECT },
|
|
||||||
{ "none", JOY_TYPE_NONE },
|
|
||||||
{ "standard", JOY_TYPE_STANDARD },
|
|
||||||
{ "2pads", JOY_TYPE_2PADS },
|
|
||||||
{ "4button", JOY_TYPE_4BUTTON },
|
|
||||||
{ "6button", JOY_TYPE_6BUTTON },
|
|
||||||
{ "8button", JOY_TYPE_8BUTTON },
|
|
||||||
{ "fspro", JOY_TYPE_FSPRO },
|
|
||||||
{ "wingex", JOY_TYPE_WINGEX },
|
|
||||||
{ "sidewinder", JOY_TYPE_SIDEWINDER },
|
|
||||||
{ "gamepadpro", JOY_TYPE_GAMEPAD_PRO },
|
|
||||||
{ "grip", JOY_TYPE_GRIP },
|
|
||||||
{ "grip4", JOY_TYPE_GRIP4 },
|
|
||||||
{ "sneslpt1", JOY_TYPE_SNESPAD_LPT1 },
|
|
||||||
{ "sneslpt2", JOY_TYPE_SNESPAD_LPT2 },
|
|
||||||
{ "sneslpt3", JOY_TYPE_SNESPAD_LPT3 },
|
|
||||||
{ "psxlpt1", JOY_TYPE_PSXPAD_LPT1 },
|
|
||||||
{ "psxlpt2", JOY_TYPE_PSXPAD_LPT2 },
|
|
||||||
{ "psxlpt3", JOY_TYPE_PSXPAD_LPT3 },
|
|
||||||
{ "n64lpt1", JOY_TYPE_N64PAD_LPT1 },
|
|
||||||
{ "n64lpt2", JOY_TYPE_N64PAD_LPT2 },
|
|
||||||
{ "n64lpt3", JOY_TYPE_N64PAD_LPT3 },
|
|
||||||
{ "db9lpt1", JOY_TYPE_DB9_LPT1 },
|
|
||||||
{ "db9lpt2", JOY_TYPE_DB9_LPT2 },
|
|
||||||
{ "db9lpt3", JOY_TYPE_DB9_LPT3 },
|
|
||||||
{ "tglpt1", JOY_TYPE_TURBOGRAFX_LPT1 },
|
|
||||||
{ "tglpt2", JOY_TYPE_TURBOGRAFX_LPT2 },
|
|
||||||
{ "tglpt3", JOY_TYPE_TURBOGRAFX_LPT3 },
|
|
||||||
{ "wingwar", JOY_TYPE_WINGWARRIOR },
|
|
||||||
{ "segaisa", JOY_TYPE_IFSEGA_ISA},
|
|
||||||
{ "segapci", JOY_TYPE_IFSEGA_PCI},
|
|
||||||
{ "segapci2", JOY_TYPE_IFSEGA_PCI_FAST},
|
|
||||||
{ NULL, 0 }
|
|
||||||
};
|
|
||||||
|
|
@ -1,104 +0,0 @@
|
|||||||
|
|
||||||
#ifndef _CONFIG_H_
|
|
||||||
#define _CONFIG_H_
|
|
||||||
|
|
||||||
#define PATH_SIZE (0x100)
|
|
||||||
#define TOKEN_LIST_SIZE (0x20)
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
char *token;
|
|
||||||
int value;
|
|
||||||
}t_strint;
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
int video_width;
|
|
||||||
int video_height;
|
|
||||||
int video_depth;
|
|
||||||
int video_driver;
|
|
||||||
|
|
||||||
int autores;
|
|
||||||
int autores_w;
|
|
||||||
int autores_h;
|
|
||||||
|
|
||||||
int remap;
|
|
||||||
int blur;
|
|
||||||
int scanlines;
|
|
||||||
int scale;
|
|
||||||
|
|
||||||
int vsync;
|
|
||||||
int throttle;
|
|
||||||
int fps;
|
|
||||||
int skip;
|
|
||||||
|
|
||||||
int sound;
|
|
||||||
int sndcard;
|
|
||||||
int sndrate;
|
|
||||||
int swap;
|
|
||||||
|
|
||||||
int wave;
|
|
||||||
char wavpath[PATH_SIZE];
|
|
||||||
|
|
||||||
int joy_driver;
|
|
||||||
|
|
||||||
int split; /* 1= Split image at 2 megabit boundary */
|
|
||||||
int flip; /* 1= Bit-flip image */
|
|
||||||
int usa; /* 1= Set D6 of $1000 to indicate US machine */
|
|
||||||
int softres; /* 1= Allow RUN+SELECT */
|
|
||||||
} t_option;
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Config Option
|
|
||||||
*
|
|
||||||
****************************************************************************/
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
uint8 padtype;
|
|
||||||
} t_input_c;
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
uint8 hq_fm;
|
|
||||||
uint8 psgBoostNoise;
|
|
||||||
int32 psg_preamp;
|
|
||||||
int32 fm_preamp;
|
|
||||||
uint8 filter;
|
|
||||||
uint16 low_freq;
|
|
||||||
uint16 high_freq;
|
|
||||||
uint8 lp_range;
|
|
||||||
float lg;
|
|
||||||
float mg;
|
|
||||||
float hg;
|
|
||||||
float rolloff;
|
|
||||||
uint8 region_detect;
|
|
||||||
uint8 force_dtack;
|
|
||||||
uint8 addr_error;
|
|
||||||
uint8 tmss;
|
|
||||||
uint8 lock_on;
|
|
||||||
uint8 romtype;
|
|
||||||
uint8 overscan;
|
|
||||||
uint8 render;
|
|
||||||
uint8 ntsc;
|
|
||||||
t_input_c input[MAX_INPUTS];
|
|
||||||
uint8 gun_cursor[2];
|
|
||||||
uint8 invert_mouse;
|
|
||||||
} t_config;
|
|
||||||
|
|
||||||
/* Global variables */
|
|
||||||
extern t_option option;
|
|
||||||
extern t_config config;
|
|
||||||
extern t_strint video_driver_table[];
|
|
||||||
extern t_strint joy_driver_table[];
|
|
||||||
|
|
||||||
/* Function prototypes */
|
|
||||||
void do_config(char *file);
|
|
||||||
int parse_file(char *filename, int *argc, char **argv);
|
|
||||||
void parse_args(int argc, char **argv);
|
|
||||||
void print_options(void);
|
|
||||||
int check_bool(char *token);
|
|
||||||
void set_option_defaults(void);
|
|
||||||
void set_config_defaults(void);
|
|
||||||
|
|
||||||
#endif /* _CONFIG_H_ */
|
|
||||||
|
|
@ -1,681 +0,0 @@
|
|||||||
/*
|
|
||||||
dos.c --
|
|
||||||
DOS interface code for the emulator
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "shared.h"
|
|
||||||
#include "osd.h"
|
|
||||||
|
|
||||||
#define FRAMES_PER_SECOND 60
|
|
||||||
#define MSG_LEN 1024
|
|
||||||
|
|
||||||
RGB vdp_palette[3][0x200];
|
|
||||||
PALETTE gen_pal;
|
|
||||||
BITMAP *gen_bmp;
|
|
||||||
|
|
||||||
volatile int frame_skip = 1;
|
|
||||||
volatile int frame_count = 0;
|
|
||||||
volatile int frames_rendered = 0;
|
|
||||||
volatile int frame_rate = 0;
|
|
||||||
volatile int tick_count = 0;
|
|
||||||
volatile int old_tick_count = 0;
|
|
||||||
volatile int skip = 0;
|
|
||||||
|
|
||||||
int quit = 0;
|
|
||||||
unsigned char buf[STATE_SIZE];
|
|
||||||
|
|
||||||
uint8 log_error = 1;
|
|
||||||
uint8 debug_on = 0;
|
|
||||||
|
|
||||||
void msg_print(int x, int y, char *fmt, ...)
|
|
||||||
{
|
|
||||||
int i = bitmap.viewport.x;
|
|
||||||
int j = bitmap.viewport.y;
|
|
||||||
va_list ap;
|
|
||||||
char token[MSG_LEN];
|
|
||||||
char str[MSG_LEN];
|
|
||||||
|
|
||||||
strcpy(str, "\0");
|
|
||||||
va_start(ap, fmt);
|
|
||||||
vsprintf(token, fmt, ap);
|
|
||||||
strcat(str, token);
|
|
||||||
va_end(ap);
|
|
||||||
|
|
||||||
textprintf_ex(gen_bmp, font, i+x+1, j+y , 0x00, -1, "%s", str);
|
|
||||||
textprintf_ex(gen_bmp, font, i+x-1, j+y , 0x00, -1, "%s", str);
|
|
||||||
textprintf_ex(gen_bmp, font, i+x , j+y+1, 0x00, -1, "%s", str);
|
|
||||||
textprintf_ex(gen_bmp, font, i+x , j+y-1, 0x00, -1, "%s", str);
|
|
||||||
textprintf_ex(gen_bmp, font, i+x , j+y , 0xffff, -1, "%s", str);
|
|
||||||
}
|
|
||||||
|
|
||||||
int main (int argc, char *argv[])
|
|
||||||
{
|
|
||||||
if(argc < 2)
|
|
||||||
{
|
|
||||||
printf("Genesis Plus - Sega Mega Drive emulator (v1.0)\n");
|
|
||||||
printf("(C) 1999, 2000, 2001, 2002, 2003 Charles MacDonald\n");
|
|
||||||
printf("Usage %s file.[bin|smd|zip] [-options]\n", argv[0]);
|
|
||||||
printf("Type `%s -help' for a list of options.\n", argv[0]);
|
|
||||||
exit(1);
|
|
||||||
};
|
|
||||||
|
|
||||||
if(stricmp(argv[1], "-help") == 0)
|
|
||||||
{
|
|
||||||
print_options();
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
error_init();
|
|
||||||
|
|
||||||
cart.rom = malloc(0xA00000);
|
|
||||||
memset(cart.rom, 0, 0xA00000);
|
|
||||||
|
|
||||||
if(!load_rom(argv[1]))
|
|
||||||
{
|
|
||||||
printf("File `%s' not found.\n", argv[1]);
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* load BIOS */
|
|
||||||
memset(bios_rom, 0, sizeof(bios_rom));
|
|
||||||
FILE *f = fopen("./BIOS.bin", "rb");
|
|
||||||
if (f!=NULL)
|
|
||||||
{
|
|
||||||
fread(&bios_rom, 0x800,1,f);
|
|
||||||
fclose(f);
|
|
||||||
int i;
|
|
||||||
for(i = 0; i < 0x800; i += 2)
|
|
||||||
{
|
|
||||||
uint8 temp = bios_rom[i];
|
|
||||||
bios_rom[i] = bios_rom[i+1];
|
|
||||||
bios_rom[i+1] = temp;
|
|
||||||
}
|
|
||||||
config.tmss |= 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* initialize genesis VM */
|
|
||||||
init_machine();
|
|
||||||
|
|
||||||
/* default config */
|
|
||||||
do_config("genplus.cfg");
|
|
||||||
set_config_defaults();
|
|
||||||
|
|
||||||
/* initialize emulation */
|
|
||||||
system_init();
|
|
||||||
audio_init(option.sndrate, vdp_pal ? 50 : 60);
|
|
||||||
|
|
||||||
f = fopen("./game.srm", "rb");
|
|
||||||
if (f!=NULL)
|
|
||||||
{
|
|
||||||
fread(&sram.sram,0x10000,1, f);
|
|
||||||
fclose(f);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* reset emulation */
|
|
||||||
system_reset();
|
|
||||||
|
|
||||||
/* emulation loop */
|
|
||||||
for(;;)
|
|
||||||
{
|
|
||||||
dos_update_input();
|
|
||||||
frame_count += 1;
|
|
||||||
if(quit) break;
|
|
||||||
if(frame_count % frame_skip == 0)
|
|
||||||
{
|
|
||||||
system_frame(0);
|
|
||||||
frames_rendered++;
|
|
||||||
dos_update_video();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
system_frame(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
audio_update();
|
|
||||||
if(option.sound)
|
|
||||||
dos_update_audio();
|
|
||||||
}
|
|
||||||
|
|
||||||
f = fopen("./game.srm", "wb");
|
|
||||||
if (f!=NULL)
|
|
||||||
{
|
|
||||||
fwrite(&sram.sram, 0x10000,1,f);
|
|
||||||
fclose(f);
|
|
||||||
}
|
|
||||||
|
|
||||||
trash_machine();
|
|
||||||
system_shutdown();
|
|
||||||
error_shutdown();
|
|
||||||
free(cart.rom);
|
|
||||||
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Timer handler */
|
|
||||||
void tick_handler(void)
|
|
||||||
{
|
|
||||||
tick_count += 1;
|
|
||||||
if(tick_count % FRAMES_PER_SECOND == 0)
|
|
||||||
{
|
|
||||||
frame_rate = frames_rendered;
|
|
||||||
frames_rendered = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
END_OF_FUNCTION(tick_handler);
|
|
||||||
|
|
||||||
|
|
||||||
int load_file(char *filename, char *buf, int size)
|
|
||||||
{
|
|
||||||
FILE *fd = fopen(filename, "rb");
|
|
||||||
if(!fd) return (0);
|
|
||||||
fread(buf, size, 1, fd);
|
|
||||||
fclose(fd);
|
|
||||||
return (1);
|
|
||||||
}
|
|
||||||
|
|
||||||
int save_file(char *filename, char *buf, int size)
|
|
||||||
{
|
|
||||||
FILE *fd = NULL;
|
|
||||||
if(!(fd = fopen(filename, "wb"))) return (0);
|
|
||||||
fwrite(buf, size, 1, fd);
|
|
||||||
fclose(fd);
|
|
||||||
return (1);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int joynum = 0;
|
|
||||||
|
|
||||||
void dos_update_input(void)
|
|
||||||
{
|
|
||||||
FILE *f;
|
|
||||||
|
|
||||||
if(key[KEY_ESC] || key[KEY_END])
|
|
||||||
{
|
|
||||||
quit = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (input.dev[joynum] == NO_DEVICE)
|
|
||||||
{
|
|
||||||
joynum ++;
|
|
||||||
if (joynum > MAX_DEVICES - 1) joynum = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(check_key(KEY_F11))
|
|
||||||
{
|
|
||||||
joynum ++;
|
|
||||||
if (joynum > MAX_DEVICES - 1) joynum = 0;
|
|
||||||
|
|
||||||
while (input.dev[joynum] == NO_DEVICE)
|
|
||||||
{
|
|
||||||
joynum ++;
|
|
||||||
if (joynum > MAX_DEVICES - 1) joynum = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
input.pad[joynum] = 0;
|
|
||||||
|
|
||||||
/* Is the joystick being used ? */
|
|
||||||
if(option.joy_driver != JOY_TYPE_NONE)
|
|
||||||
{
|
|
||||||
poll_joystick();
|
|
||||||
|
|
||||||
/* Check player 1 joystick */
|
|
||||||
if(joy[0].stick[0].axis[1].d1) input.pad[0] |= INPUT_UP;
|
|
||||||
else
|
|
||||||
if(joy[0].stick[0].axis[1].d2) input.pad[0] |= INPUT_DOWN;
|
|
||||||
|
|
||||||
if(joy[0].stick[0].axis[0].d1) input.pad[0] |= INPUT_LEFT;
|
|
||||||
else
|
|
||||||
if(joy[0].stick[0].axis[0].d2) input.pad[0] |= INPUT_RIGHT;
|
|
||||||
|
|
||||||
if(joy[0].button[0].b) input.pad[0] |= INPUT_A;
|
|
||||||
if(joy[0].button[1].b) input.pad[0] |= INPUT_B;
|
|
||||||
if(joy[0].button[2].b) input.pad[0] |= INPUT_C;
|
|
||||||
if(joy[0].button[3].b) input.pad[0] |= INPUT_START;
|
|
||||||
if(joy[0].button[4].b) input.pad[0] |= INPUT_X;
|
|
||||||
if(joy[0].button[5].b) input.pad[0] |= INPUT_Y;
|
|
||||||
if(joy[0].button[6].b) input.pad[0] |= INPUT_Z;
|
|
||||||
if(joy[0].button[7].b) input.pad[0] |= INPUT_MODE;
|
|
||||||
|
|
||||||
/* More than one joystick supported ? */
|
|
||||||
if(num_joysticks > 2)
|
|
||||||
{
|
|
||||||
/* Check player 2 joystick */
|
|
||||||
if(joy[1].stick[0].axis[1].d1) input.pad[1] |= INPUT_UP;
|
|
||||||
else
|
|
||||||
if(joy[1].stick[0].axis[1].d2) input.pad[1] |= INPUT_DOWN;
|
|
||||||
|
|
||||||
if(joy[1].stick[0].axis[0].d1) input.pad[1] |= INPUT_LEFT;
|
|
||||||
else
|
|
||||||
if(joy[1].stick[0].axis[0].d1) input.pad[1] |= INPUT_RIGHT;
|
|
||||||
|
|
||||||
if(joy[1].button[0].b) input.pad[1] |= INPUT_A;
|
|
||||||
if(joy[1].button[1].b) input.pad[1] |= INPUT_B;
|
|
||||||
if(joy[1].button[2].b) input.pad[1] |= INPUT_C;
|
|
||||||
if(joy[1].button[3].b) input.pad[1] |= INPUT_START;
|
|
||||||
if(joy[1].button[4].b) input.pad[1] |= INPUT_X;
|
|
||||||
if(joy[1].button[5].b) input.pad[1] |= INPUT_Y;
|
|
||||||
if(joy[1].button[6].b) input.pad[1] |= INPUT_Z;
|
|
||||||
if(joy[1].button[7].b) input.pad[1] |= INPUT_MODE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* keyboard */
|
|
||||||
if(key[KEY_UP]) input.pad[joynum] |= INPUT_UP;
|
|
||||||
else
|
|
||||||
if(key[KEY_DOWN]) input.pad[joynum] |= INPUT_DOWN;
|
|
||||||
|
|
||||||
if(key[KEY_LEFT]) input.pad[joynum] |= INPUT_LEFT;
|
|
||||||
else
|
|
||||||
if(key[KEY_RIGHT]) input.pad[joynum] |= INPUT_RIGHT;
|
|
||||||
|
|
||||||
if(key[KEY_A]) input.pad[joynum] |= INPUT_A;
|
|
||||||
if(key[KEY_S]) input.pad[joynum] |= INPUT_B;
|
|
||||||
if(key[KEY_D]) input.pad[joynum] |= INPUT_C;
|
|
||||||
if(key[KEY_Z]) input.pad[joynum] |= INPUT_X;
|
|
||||||
if(key[KEY_X]) input.pad[joynum] |= INPUT_Y;
|
|
||||||
if(key[KEY_C]) input.pad[joynum] |= INPUT_Z;
|
|
||||||
if(key[KEY_V]) input.pad[joynum] |= INPUT_MODE;
|
|
||||||
|
|
||||||
if(key[KEY_F]) input.pad[joynum] |= INPUT_START;
|
|
||||||
|
|
||||||
extern uint8 pico_current;
|
|
||||||
if (input.dev[joynum] == DEVICE_LIGHTGUN)
|
|
||||||
{
|
|
||||||
/* Poll mouse if necessary */
|
|
||||||
if(mouse_needs_poll() == TRUE)
|
|
||||||
poll_mouse();
|
|
||||||
|
|
||||||
/* Calculate X Y axis values */
|
|
||||||
input.analog[joynum][0] = (mouse_x * bitmap.viewport.w) / SCREEN_W;
|
|
||||||
input.analog[joynum][1] = (mouse_y * bitmap.viewport.h) / SCREEN_H;
|
|
||||||
|
|
||||||
/* Map mouse buttons to player #1 inputs */
|
|
||||||
if(mouse_b & 4) input.pad[joynum] |= INPUT_C;
|
|
||||||
if(mouse_b & 2) input.pad[joynum] |= INPUT_B;
|
|
||||||
if(mouse_b & 1) input.pad[joynum] |= INPUT_A;
|
|
||||||
}
|
|
||||||
else if (input.dev[joynum] == DEVICE_MOUSE)
|
|
||||||
{
|
|
||||||
/* Poll mouse if necessary */
|
|
||||||
if(mouse_needs_poll() == TRUE)
|
|
||||||
poll_mouse();
|
|
||||||
|
|
||||||
/* Get X & Y quantity of movement */
|
|
||||||
get_mouse_mickeys(&input.analog[joynum][0], &input.analog[joynum][1]);
|
|
||||||
|
|
||||||
/* Sega Mouse range is -256;+256 */
|
|
||||||
input.analog[joynum][0] = (input.analog[joynum][0] * 256) / SCREEN_W;
|
|
||||||
input.analog[joynum][1] = (input.analog[joynum][1] * 256) / SCREEN_H;
|
|
||||||
|
|
||||||
/* Vertical movement is upsidedown */
|
|
||||||
if (!config.invert_mouse) input.analog[joynum][1] = 0 - input.analog[joynum][1];
|
|
||||||
|
|
||||||
/* Map mouse buttons to player #1 inputs */
|
|
||||||
if(mouse_b & 4) input.pad[joynum] |= INPUT_C;
|
|
||||||
if(mouse_b & 1) input.pad[joynum] |= INPUT_B;
|
|
||||||
if(mouse_b & 2) input.pad[joynum] |= INPUT_A;
|
|
||||||
}
|
|
||||||
else if (system_hw == SYSTEM_PICO)
|
|
||||||
{
|
|
||||||
/* Poll mouse if necessary */
|
|
||||||
if(mouse_needs_poll() == TRUE)
|
|
||||||
poll_mouse();
|
|
||||||
|
|
||||||
/* Calculate X Y axis values */
|
|
||||||
input.analog[0][0] = 0x3c + (mouse_x * (0x17c-0x03c+1)) / SCREEN_W;
|
|
||||||
input.analog[0][1] = 0x1fc + (mouse_y * (0x2f7-0x1fc+1)) / SCREEN_H;
|
|
||||||
|
|
||||||
/* Map mouse buttons to player #1 inputs */
|
|
||||||
if(mouse_b & 2) input.pad[0] |= INPUT_B;
|
|
||||||
if(mouse_b & 1) input.pad[0] |= INPUT_A;
|
|
||||||
if(mouse_b & 4) pico_current++;
|
|
||||||
if (pico_current > 6) pico_current = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(check_key(KEY_F1)) frame_skip = 1;
|
|
||||||
if(check_key(KEY_F2)) frame_skip = 2;
|
|
||||||
if(check_key(KEY_F3)) frame_skip = 3;
|
|
||||||
if(check_key(KEY_F4)) frame_skip = 4;
|
|
||||||
|
|
||||||
if(check_key(KEY_F5)) log_error ^= 1;
|
|
||||||
if(check_key(KEY_F6)) debug_on ^= 1;
|
|
||||||
|
|
||||||
if(check_key(KEY_F7))
|
|
||||||
{
|
|
||||||
f = fopen("game.gpz","r+b");
|
|
||||||
if (f)
|
|
||||||
{
|
|
||||||
fread(&buf, STATE_SIZE, 1, f);
|
|
||||||
state_load(buf);
|
|
||||||
fclose(f);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(check_key(KEY_F8))
|
|
||||||
{
|
|
||||||
f = fopen("game.gpz","w+b");
|
|
||||||
if (f)
|
|
||||||
{
|
|
||||||
state_save(buf);
|
|
||||||
fwrite(&buf, STATE_SIZE, 1, f);
|
|
||||||
fclose(f);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(check_key(KEY_F9))
|
|
||||||
{
|
|
||||||
vdp_pal ^= 1;
|
|
||||||
|
|
||||||
/* save YM2612 context */
|
|
||||||
unsigned char *temp = malloc(YM2612GetContextSize());
|
|
||||||
if (temp)
|
|
||||||
memcpy(temp, YM2612GetContextPtr(), YM2612GetContextSize());
|
|
||||||
|
|
||||||
/* reinitialize all timings */
|
|
||||||
audio_init(snd.sample_rate, snd.frame_rate);
|
|
||||||
system_init();
|
|
||||||
|
|
||||||
/* restore YM2612 context */
|
|
||||||
if (temp)
|
|
||||||
{
|
|
||||||
YM2612Restore(temp);
|
|
||||||
free(temp);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* reinitialize VC max value */
|
|
||||||
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) */
|
|
||||||
};
|
|
||||||
vc_max = vc_table[(reg[1] >> 2) & 3][vdp_pal];
|
|
||||||
|
|
||||||
/* reinitialize overscan area */
|
|
||||||
bitmap.viewport.y = (config.overscan & 1) ? (((reg[1] & 8) ? 0 : 8) + (vdp_pal ? 24 : 0)) : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(check_key(KEY_F10)) set_softreset();
|
|
||||||
if(check_key(KEY_TAB)) system_reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
void dos_update_audio(void)
|
|
||||||
{
|
|
||||||
osd_play_streamed_sample_16(option.swap ^ 0, snd.buffer[0], snd.buffer_size * 2, option.sndrate, FRAMES_PER_SECOND, -100);
|
|
||||||
osd_play_streamed_sample_16(option.swap ^ 1, snd.buffer[1], snd.buffer_size * 2, option.sndrate, FRAMES_PER_SECOND, 100);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
void dos_update_palette(void)
|
|
||||||
{
|
|
||||||
if(is_border_dirty)
|
|
||||||
{
|
|
||||||
uint16 data = *(uint16 *)&cram[(border << 1)];
|
|
||||||
RGB *color;
|
|
||||||
|
|
||||||
is_border_dirty = 0;
|
|
||||||
|
|
||||||
if(reg[12] & 8)
|
|
||||||
{
|
|
||||||
int j;
|
|
||||||
for(j = 0; j < 3; j += 1)
|
|
||||||
{
|
|
||||||
color = &vdp_palette[j][data];
|
|
||||||
set_color((j << 6), color);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
color = &vdp_palette[1][data];
|
|
||||||
set_color(0x00, color);
|
|
||||||
set_color(0x40, color);
|
|
||||||
set_color(0x80, color);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(is_color_dirty)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
uint16 *p = (uint16 *)&cram[0];
|
|
||||||
is_color_dirty = 0;
|
|
||||||
|
|
||||||
for(i = 0; i < 64; i += 1)
|
|
||||||
{
|
|
||||||
if((color_dirty[i]) && ((i & 0x0F) != 0x00))
|
|
||||||
{
|
|
||||||
RGB *color;
|
|
||||||
color_dirty[i] = 0;
|
|
||||||
if(reg[12] & 8)
|
|
||||||
{
|
|
||||||
int j;
|
|
||||||
for(j = 0; j < 3; j += 1)
|
|
||||||
{
|
|
||||||
color = &vdp_palette[j][p[i]];
|
|
||||||
set_color((j << 6) | i, color);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
color = &vdp_palette[1][p[i]];
|
|
||||||
set_color(0x00 | i, color);
|
|
||||||
set_color(0x40 | i, color);
|
|
||||||
set_color(0x80 | i, color);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void dos_update_video(void)
|
|
||||||
{
|
|
||||||
int width = (bitmap.viewport.w + 2 * bitmap.viewport.x);
|
|
||||||
int height = (bitmap.viewport.h + 2 * bitmap.viewport.y) << (interlaced ? 1:0);
|
|
||||||
int center_x = (SCREEN_W - width) / 2;
|
|
||||||
int center_y = (SCREEN_H / (option.scanlines ? 4 : 2)) - (height / 2);
|
|
||||||
|
|
||||||
/* Wait for VSync */
|
|
||||||
if(option.vsync) vsync();
|
|
||||||
|
|
||||||
if(bitmap.viewport.changed)
|
|
||||||
{
|
|
||||||
bitmap.viewport.changed = 0;
|
|
||||||
if(bitmap.remap)
|
|
||||||
{
|
|
||||||
clear(screen);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
clear_to_color(screen, 0xFF);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
if(bitmap.remap == 0)
|
|
||||||
{
|
|
||||||
dos_update_palette();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
msg_print(2, 2, "%d", frame_rate);
|
|
||||||
|
|
||||||
if(option.scanlines)
|
|
||||||
{
|
|
||||||
int y;
|
|
||||||
for(y = 0; y < height; y += 1)
|
|
||||||
{
|
|
||||||
blit(gen_bmp, screen, 0x0, y, center_x, (center_y + y) << 1, width, 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
stretch_blit(gen_bmp, screen, 0, 0, width, height, (SCREEN_W-352)/2, (SCREEN_H-240)/2, 352,240 << (interlaced ? 1:0));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void init_machine(void)
|
|
||||||
{
|
|
||||||
do_config("gen.cfg");
|
|
||||||
|
|
||||||
if(option.sound)
|
|
||||||
{
|
|
||||||
msdos_init_sound(&option.sndrate, option.sndcard);
|
|
||||||
}
|
|
||||||
|
|
||||||
allegro_init();
|
|
||||||
install_mouse();
|
|
||||||
install_keyboard();
|
|
||||||
install_joystick(option.joy_driver);
|
|
||||||
|
|
||||||
install_timer();
|
|
||||||
LOCK_FUNCTION(tick_handler);
|
|
||||||
LOCK_VARIABLE(tick_count);
|
|
||||||
LOCK_VARIABLE(frame_rate);
|
|
||||||
install_int_ex(tick_handler, BPS_TO_TIMER(FRAMES_PER_SECOND));
|
|
||||||
|
|
||||||
set_color_depth(option.video_depth);
|
|
||||||
gen_bmp = create_bitmap(720, 576);
|
|
||||||
clear(gen_bmp);
|
|
||||||
|
|
||||||
memset(&bitmap, 0, sizeof(bitmap));
|
|
||||||
bitmap.data = (uint8 *)&gen_bmp->line[0][0];
|
|
||||||
bitmap.width = gen_bmp->w;
|
|
||||||
bitmap.height = gen_bmp->h;
|
|
||||||
bitmap.depth = option.video_depth;
|
|
||||||
switch(option.video_depth)
|
|
||||||
{
|
|
||||||
case 8:
|
|
||||||
bitmap.granularity = 1;
|
|
||||||
break;
|
|
||||||
case 15:
|
|
||||||
bitmap.granularity = 2;
|
|
||||||
break;
|
|
||||||
case 16:
|
|
||||||
bitmap.granularity = 2;
|
|
||||||
break;
|
|
||||||
case 32:
|
|
||||||
bitmap.granularity = 4;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
bitmap.pitch = (bitmap.width * bitmap.granularity);
|
|
||||||
bitmap.viewport.w = 256;
|
|
||||||
bitmap.viewport.h = 224;
|
|
||||||
bitmap.viewport.x = 0x00;
|
|
||||||
bitmap.viewport.y = 0x00;
|
|
||||||
bitmap.remap = 0;
|
|
||||||
if(option.remap) bitmap.remap = 1;
|
|
||||||
else
|
|
||||||
if(bitmap.depth > 8) bitmap.remap = 1;
|
|
||||||
|
|
||||||
make_vdp_palette();
|
|
||||||
|
|
||||||
memcpy(gen_pal, black_palette, sizeof(PALETTE));
|
|
||||||
gen_pal[0xFE].r = \
|
|
||||||
gen_pal[0xFE].g = \
|
|
||||||
gen_pal[0xFE].b = 0x3F;
|
|
||||||
|
|
||||||
dos_change_mode();
|
|
||||||
}
|
|
||||||
|
|
||||||
void trash_machine(void)
|
|
||||||
{
|
|
||||||
if(option.sound)
|
|
||||||
{
|
|
||||||
msdos_shutdown_sound();
|
|
||||||
}
|
|
||||||
clear(screen);
|
|
||||||
destroy_bitmap(gen_bmp);
|
|
||||||
set_gfx_mode(GFX_TEXT, 0, 0, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void make_vdp_palette(void)
|
|
||||||
{
|
|
||||||
uint8 lut[3][8] =
|
|
||||||
{
|
|
||||||
{0x00, 0x04, 0x08, 0x0C, 0x10, 0x14, 0x18, 0x1C},
|
|
||||||
{0x00, 0x08, 0x10, 0x18, 0x20, 0x28, 0x30, 0x38},
|
|
||||||
{0x20, 0x24, 0x28, 0x2C, 0x30, 0x34, 0x38, 0x3C},
|
|
||||||
};
|
|
||||||
|
|
||||||
int j;
|
|
||||||
for(j = 0; j < 0x600; j += 1)
|
|
||||||
{
|
|
||||||
|
|
||||||
int r = (j >> 6) & 7;
|
|
||||||
int g = (j >> 3) & 7;
|
|
||||||
int b = (j >> 0) & 7;
|
|
||||||
int i = (j >> 9) & 3;
|
|
||||||
|
|
||||||
vdp_palette[i][j & 0x1FF].r = lut[i][r];
|
|
||||||
vdp_palette[i][j & 0x1FF].g = lut[i][g];
|
|
||||||
vdp_palette[i][j & 0x1FF].b = lut[i][b];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void dos_change_mode(void)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
int width = option.video_width;
|
|
||||||
int height = option.video_height;
|
|
||||||
|
|
||||||
if(option.scanlines) height *= 2;
|
|
||||||
ret = set_gfx_mode(option.video_driver, width, height, 0, 0);
|
|
||||||
if(ret != 0)
|
|
||||||
{
|
|
||||||
set_gfx_mode(GFX_TEXT, 0, 0, 0, 0);
|
|
||||||
printf("Error setting graphics mode (%dx%d %dbpp).\nAllegro says: `%s'\n", width, height, option.video_depth, allegro_error);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(bitmap.depth == 8)
|
|
||||||
{
|
|
||||||
if(bitmap.remap)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
for(i = 0; i < 0x100; i += 1)
|
|
||||||
{
|
|
||||||
gen_pal[i].r = ((i >> 5) & 7) << 3;
|
|
||||||
gen_pal[i].g = ((i >> 2) & 7) << 3;
|
|
||||||
gen_pal[i].b = ((i >> 0) & 3) << 4;
|
|
||||||
}
|
|
||||||
set_palette(gen_pal);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
clear_to_color(screen, 0xFF);
|
|
||||||
gen_pal[0xfe].r = 0xff;
|
|
||||||
gen_pal[0xfe].g = 0xff;
|
|
||||||
gen_pal[0xfe].b = 0xff;
|
|
||||||
set_palette(gen_pal);
|
|
||||||
inp(0x3DA);
|
|
||||||
outp(0x3C0, 0x31);
|
|
||||||
outp(0x3C0, 0xFF);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
clear(screen);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Check if a key is pressed */
|
|
||||||
int check_key(int code)
|
|
||||||
{
|
|
||||||
static char lastbuf[0x100] = {0};
|
|
||||||
|
|
||||||
if((!key[code]) && (lastbuf[code] == 1))
|
|
||||||
lastbuf[code] = 0;
|
|
||||||
|
|
||||||
if((key[code]) && (lastbuf[code] == 0))
|
|
||||||
{
|
|
||||||
lastbuf[code] = 1;
|
|
||||||
return (1);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
@ -1,26 +0,0 @@
|
|||||||
|
|
||||||
#ifndef _DOS_H_
|
|
||||||
#define _DOS_H_
|
|
||||||
|
|
||||||
#define LOGERROR 1
|
|
||||||
|
|
||||||
/* Function prototypes */
|
|
||||||
int load_file(char *filename, char *buf, int size);
|
|
||||||
int save_file(char *filename, char *buf, int size);
|
|
||||||
void dos_update_input(void);
|
|
||||||
void dos_update_audio(void);
|
|
||||||
void dos_update_palette(void);
|
|
||||||
void dos_update_video(void);
|
|
||||||
void init_machine(void);
|
|
||||||
void trash_machine(void);
|
|
||||||
void make_vdp_palette(void);
|
|
||||||
void dos_change_mode(void);
|
|
||||||
int check_key(int code);
|
|
||||||
|
|
||||||
#define MAX_INPUTS 8
|
|
||||||
|
|
||||||
extern uint8 debug_on;
|
|
||||||
extern uint8 log_error;
|
|
||||||
|
|
||||||
#endif /* _DOS_H_ */
|
|
||||||
|
|
@ -1,32 +0,0 @@
|
|||||||
|
|
||||||
#include "osd.h"
|
|
||||||
|
|
||||||
FILE *error_log;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
int enabled;
|
|
||||||
int verbose;
|
|
||||||
FILE *log;
|
|
||||||
} t_error;
|
|
||||||
|
|
||||||
void error_init(void)
|
|
||||||
{
|
|
||||||
#ifdef LOG_ERROR
|
|
||||||
error_log = fopen("error.log","w");
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void error_shutdown(void)
|
|
||||||
{
|
|
||||||
if(error_log) fclose(error_log);
|
|
||||||
}
|
|
||||||
|
|
||||||
void error(char *format, ...)
|
|
||||||
{
|
|
||||||
if (!log_error) return;
|
|
||||||
va_list ap;
|
|
||||||
va_start(ap, format);
|
|
||||||
if(error_log) vfprintf(error_log, format, ap);
|
|
||||||
va_end(ap);
|
|
||||||
}
|
|
||||||
|
|
@ -1,13 +0,0 @@
|
|||||||
|
|
||||||
#ifndef _ERROR_H_
|
|
||||||
#define _ERROR_H_
|
|
||||||
|
|
||||||
/* Global variables */
|
|
||||||
FILE *error_log;
|
|
||||||
|
|
||||||
/* Function prototypes */
|
|
||||||
void error_init(void);
|
|
||||||
void error_shutdown(void);
|
|
||||||
void error(char *format, ...);
|
|
||||||
|
|
||||||
#endif /* _ERROR_H_ */
|
|
@ -1,151 +0,0 @@
|
|||||||
#include "shared.h"
|
|
||||||
|
|
||||||
/*
|
|
||||||
Load a normal file, or ZIP/GZ archive.
|
|
||||||
Returns NULL if an error occured.
|
|
||||||
*/
|
|
||||||
uint8 *load_archive(char *filename, int *file_size)
|
|
||||||
{
|
|
||||||
int size = 0;
|
|
||||||
uint8 *buf = NULL;
|
|
||||||
|
|
||||||
if(check_zip(filename))
|
|
||||||
{
|
|
||||||
unzFile *fd = NULL;
|
|
||||||
unz_file_info info;
|
|
||||||
int ret = 0;
|
|
||||||
|
|
||||||
/* Attempt to open the archive */
|
|
||||||
fd = unzOpen(filename);
|
|
||||||
if(!fd) return (NULL);
|
|
||||||
|
|
||||||
/* Go to first file in archive */
|
|
||||||
ret = unzGoToFirstFile(fd);
|
|
||||||
if(ret != UNZ_OK)
|
|
||||||
{
|
|
||||||
unzClose(fd);
|
|
||||||
return (NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = unzGetCurrentFileInfo(fd, &info, filename, 128, NULL, 0, NULL, 0);
|
|
||||||
if(ret != UNZ_OK)
|
|
||||||
{
|
|
||||||
unzClose(fd);
|
|
||||||
return (NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Open the file for reading */
|
|
||||||
ret = unzOpenCurrentFile(fd);
|
|
||||||
if(ret != UNZ_OK)
|
|
||||||
{
|
|
||||||
unzClose(fd);
|
|
||||||
return (NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Allocate file data buffer */
|
|
||||||
size = info.uncompressed_size;
|
|
||||||
buf = malloc(size);
|
|
||||||
if(!buf)
|
|
||||||
{
|
|
||||||
unzClose(fd);
|
|
||||||
return (NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Read (decompress) the file */
|
|
||||||
ret = unzReadCurrentFile(fd, buf, info.uncompressed_size);
|
|
||||||
if(ret != info.uncompressed_size)
|
|
||||||
{
|
|
||||||
free(buf);
|
|
||||||
unzCloseCurrentFile(fd);
|
|
||||||
unzClose(fd);
|
|
||||||
return (NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Close the current file */
|
|
||||||
ret = unzCloseCurrentFile(fd);
|
|
||||||
if(ret != UNZ_OK)
|
|
||||||
{
|
|
||||||
free(buf);
|
|
||||||
unzClose(fd);
|
|
||||||
return (NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Close the archive */
|
|
||||||
ret = unzClose(fd);
|
|
||||||
if(ret != UNZ_OK)
|
|
||||||
{
|
|
||||||
free(buf);
|
|
||||||
return (NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Update file size and return pointer to file data */
|
|
||||||
*file_size = size;
|
|
||||||
return (buf);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
gzFile *gd = NULL;
|
|
||||||
|
|
||||||
/* Open file */
|
|
||||||
gd = gzopen(filename, "rb");
|
|
||||||
if(!gd) return (0);
|
|
||||||
|
|
||||||
/* Get file size */
|
|
||||||
size = gzsize(gd);
|
|
||||||
|
|
||||||
/* Allocate file data buffer */
|
|
||||||
buf = malloc(size);
|
|
||||||
if(!buf)
|
|
||||||
{
|
|
||||||
gzclose(gd);
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Read file data */
|
|
||||||
gzread(gd, buf, size);
|
|
||||||
|
|
||||||
/* Close file */
|
|
||||||
gzclose(gd);
|
|
||||||
|
|
||||||
/* Update file size and return pointer to file data */
|
|
||||||
*file_size = size;
|
|
||||||
return (buf);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
Verifies if a file is a ZIP archive or not.
|
|
||||||
Returns: 1= ZIP archive, 0= not a ZIP archive
|
|
||||||
*/
|
|
||||||
int check_zip(char *filename)
|
|
||||||
{
|
|
||||||
uint8 buf[2];
|
|
||||||
FILE *fd = NULL;
|
|
||||||
fd = fopen(filename, "rb");
|
|
||||||
if(!fd) return (0);
|
|
||||||
fread(buf, 2, 1, fd);
|
|
||||||
fclose(fd);
|
|
||||||
if(memcmp(buf, "PK", 2) == 0) return (1);
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
Returns the size of a GZ compressed file.
|
|
||||||
*/
|
|
||||||
int gzsize(gzFile *gd)
|
|
||||||
{
|
|
||||||
#define CHUNKSIZE (0x10000)
|
|
||||||
int size = 0, length = 0;
|
|
||||||
unsigned char buffer[CHUNKSIZE];
|
|
||||||
gzrewind(gd);
|
|
||||||
do {
|
|
||||||
size = gzread(gd, buffer, CHUNKSIZE);
|
|
||||||
if(size <= 0) break;
|
|
||||||
length += size;
|
|
||||||
} while (!gzeof(gd));
|
|
||||||
gzrewind(gd);
|
|
||||||
return (length);
|
|
||||||
#undef CHUNKSIZE
|
|
||||||
}
|
|
@ -1,14 +0,0 @@
|
|||||||
#ifndef _FILEIO_H_
|
|
||||||
#define _FILEIO_H_
|
|
||||||
|
|
||||||
/* Global variables */
|
|
||||||
extern int cart_size;
|
|
||||||
extern char cart_name[0x100];
|
|
||||||
|
|
||||||
/* Function prototypes */
|
|
||||||
uint8 *load_archive(char *filename, int *file_size);
|
|
||||||
int load_cart(char *filename);
|
|
||||||
int check_zip(char *filename);
|
|
||||||
int gzsize(gzFile *gd);
|
|
||||||
|
|
||||||
#endif /* _FILEIO_H_ */
|
|
@ -1,22 +0,0 @@
|
|||||||
|
|
||||||
#ifndef _OSD_H_
|
|
||||||
#define _OSD_H_
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <allegro.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <audio.h>
|
|
||||||
#include <time.h>
|
|
||||||
#include <conio.h>
|
|
||||||
|
|
||||||
#include "shared.h"
|
|
||||||
#include "dos.h"
|
|
||||||
#include "config.h"
|
|
||||||
#include "sealintf.h"
|
|
||||||
#include "error.h"
|
|
||||||
#include "unzip.h"
|
|
||||||
#include "fileio.h"
|
|
||||||
|
|
||||||
volatile int frame_count;
|
|
||||||
|
|
||||||
#endif /* _OSD_H_ */
|
|
@ -1,3 +0,0 @@
|
|||||||
Compile with DJGPP.
|
|
||||||
You will also need to install Allegro and Seal libraries.
|
|
||||||
Zlib is required for zipped rom support.
|
|
File diff suppressed because it is too large
Load Diff
@ -1,273 +0,0 @@
|
|||||||
/* unzip.h -- IO for uncompress .zip files using zlib
|
|
||||||
Version 0.15 beta, Mar 19th, 1998,
|
|
||||||
|
|
||||||
Copyright (C) 1998 Gilles Vollant
|
|
||||||
|
|
||||||
This unzip package allow extract file from .ZIP file, compatible with PKZip 2.04g
|
|
||||||
WinZip, InfoZip tools and compatible.
|
|
||||||
Encryption and multi volume ZipFile (span) are not supported.
|
|
||||||
Old compressions used by old PKZip 1.x are not supported
|
|
||||||
|
|
||||||
THIS IS AN ALPHA VERSION. AT THIS STAGE OF DEVELOPPEMENT, SOMES API OR STRUCTURE
|
|
||||||
CAN CHANGE IN FUTURE VERSION !!
|
|
||||||
I WAIT FEEDBACK at mail info@winimage.com
|
|
||||||
Visit also http://www.winimage.com/zLibDll/unzip.htm for evolution
|
|
||||||
|
|
||||||
Condition of use and distribution are the same than zlib :
|
|
||||||
|
|
||||||
This software is provided 'as-is', without any express or implied
|
|
||||||
warranty. In no event will the authors be held liable for any damages
|
|
||||||
arising from the use of this software.
|
|
||||||
|
|
||||||
Permission is granted to anyone to use this software for any purpose,
|
|
||||||
including commercial applications, and to alter it and redistribute it
|
|
||||||
freely, subject to the following restrictions:
|
|
||||||
|
|
||||||
1. The origin of this software must not be misrepresented; you must not
|
|
||||||
claim that you wrote the original software. If you use this software
|
|
||||||
in a product, an acknowledgment in the product documentation would be
|
|
||||||
appreciated but is not required.
|
|
||||||
2. Altered source versions must be plainly marked as such, and must not be
|
|
||||||
misrepresented as being the original software.
|
|
||||||
3. This notice may not be removed or altered from any source distribution.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* for more info about .ZIP format, see
|
|
||||||
ftp://ftp.cdrom.com/pub/infozip/doc/appnote-970311-iz.zip
|
|
||||||
PkWare has also a specification at :
|
|
||||||
ftp://ftp.pkware.com/probdesc.zip */
|
|
||||||
|
|
||||||
#ifndef _unz_H
|
|
||||||
#define _unz_H
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef _ZLIB_H
|
|
||||||
#include "zlib.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(STRICTUNZIP) || defined(STRICTZIPUNZIP)
|
|
||||||
/* like the STRICT of WIN32, we define a pointer that cannot be converted
|
|
||||||
from (void*) without cast */
|
|
||||||
typedef struct TagunzFile__ { int unused; } unzFile__;
|
|
||||||
typedef unzFile__ *unzFile;
|
|
||||||
#else
|
|
||||||
typedef voidp unzFile;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#define UNZ_OK (0)
|
|
||||||
#define UNZ_END_OF_LIST_OF_FILE (-100)
|
|
||||||
#define UNZ_ERRNO (Z_ERRNO)
|
|
||||||
#define UNZ_EOF (0)
|
|
||||||
#define UNZ_PARAMERROR (-102)
|
|
||||||
#define UNZ_BADZIPFILE (-103)
|
|
||||||
#define UNZ_INTERNALERROR (-104)
|
|
||||||
#define UNZ_CRCERROR (-105)
|
|
||||||
|
|
||||||
/* tm_unz contain date/time info */
|
|
||||||
typedef struct tm_unz_s
|
|
||||||
{
|
|
||||||
uInt tm_sec; /* seconds after the minute - [0,59] */
|
|
||||||
uInt tm_min; /* minutes after the hour - [0,59] */
|
|
||||||
uInt tm_hour; /* hours since midnight - [0,23] */
|
|
||||||
uInt tm_mday; /* day of the month - [1,31] */
|
|
||||||
uInt tm_mon; /* months since January - [0,11] */
|
|
||||||
uInt tm_year; /* years - [1980..2044] */
|
|
||||||
} tm_unz;
|
|
||||||
|
|
||||||
/* unz_global_info structure contain global data about the ZIPfile
|
|
||||||
These data comes from the end of central dir */
|
|
||||||
typedef struct unz_global_info_s
|
|
||||||
{
|
|
||||||
uLong number_entry; /* total number of entries in
|
|
||||||
the central dir on this disk */
|
|
||||||
uLong size_comment; /* size of the global comment of the zipfile */
|
|
||||||
} unz_global_info;
|
|
||||||
|
|
||||||
|
|
||||||
/* unz_file_info contain information about a file in the zipfile */
|
|
||||||
typedef struct unz_file_info_s
|
|
||||||
{
|
|
||||||
uLong version; /* version made by 2 bytes */
|
|
||||||
uLong version_needed; /* version needed to extract 2 bytes */
|
|
||||||
uLong flag; /* general purpose bit flag 2 bytes */
|
|
||||||
uLong compression_method; /* compression method 2 bytes */
|
|
||||||
uLong dosDate; /* last mod file date in Dos fmt 4 bytes */
|
|
||||||
uLong crc; /* crc-32 4 bytes */
|
|
||||||
uLong compressed_size; /* compressed size 4 bytes */
|
|
||||||
uLong uncompressed_size; /* uncompressed size 4 bytes */
|
|
||||||
uLong size_filename; /* filename length 2 bytes */
|
|
||||||
uLong size_file_extra; /* extra field length 2 bytes */
|
|
||||||
uLong size_file_comment; /* file comment length 2 bytes */
|
|
||||||
|
|
||||||
uLong disk_num_start; /* disk number start 2 bytes */
|
|
||||||
uLong internal_fa; /* internal file attributes 2 bytes */
|
|
||||||
uLong external_fa; /* external file attributes 4 bytes */
|
|
||||||
|
|
||||||
tm_unz tmu_date;
|
|
||||||
} unz_file_info;
|
|
||||||
|
|
||||||
extern int ZEXPORT unzStringFileNameCompare OF ((const char* fileName1,
|
|
||||||
const char* fileName2,
|
|
||||||
int iCaseSensitivity));
|
|
||||||
/*
|
|
||||||
Compare two filename (fileName1,fileName2).
|
|
||||||
If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)
|
|
||||||
If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi
|
|
||||||
or strcasecmp)
|
|
||||||
If iCaseSenisivity = 0, case sensitivity is defaut of your operating system
|
|
||||||
(like 1 on Unix, 2 on Windows)
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
extern unzFile ZEXPORT unzOpen OF((const char *path));
|
|
||||||
/*
|
|
||||||
Open a Zip file. path contain the full pathname (by example,
|
|
||||||
on a Windows NT computer "c:\\zlib\\zlib111.zip" or on an Unix computer
|
|
||||||
"zlib/zlib111.zip".
|
|
||||||
If the zipfile cannot be opened (file don't exist or in not valid), the
|
|
||||||
return value is NULL.
|
|
||||||
Else, the return value is a unzFile Handle, usable with other function
|
|
||||||
of this unzip package.
|
|
||||||
*/
|
|
||||||
|
|
||||||
extern int ZEXPORT unzClose OF((unzFile file));
|
|
||||||
/*
|
|
||||||
Close a ZipFile opened with unzipOpen.
|
|
||||||
If there is files inside the .Zip opened with unzOpenCurrentFile (see later),
|
|
||||||
these files MUST be closed with unzipCloseCurrentFile before call unzipClose.
|
|
||||||
return UNZ_OK if there is no problem. */
|
|
||||||
|
|
||||||
extern int ZEXPORT unzGetGlobalInfo OF((unzFile file,
|
|
||||||
unz_global_info *pglobal_info));
|
|
||||||
/*
|
|
||||||
Write info about the ZipFile in the *pglobal_info structure.
|
|
||||||
No preparation of the structure is needed
|
|
||||||
return UNZ_OK if there is no problem. */
|
|
||||||
|
|
||||||
|
|
||||||
extern int ZEXPORT unzGetGlobalComment OF((unzFile file,
|
|
||||||
char *szComment,
|
|
||||||
uLong uSizeBuf));
|
|
||||||
/*
|
|
||||||
Get the global comment string of the ZipFile, in the szComment buffer.
|
|
||||||
uSizeBuf is the size of the szComment buffer.
|
|
||||||
return the number of byte copied or an error code <0
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
/* Unzip package allow you browse the directory of the zipfile */
|
|
||||||
|
|
||||||
extern int ZEXPORT unzGoToFirstFile OF((unzFile file));
|
|
||||||
/*
|
|
||||||
Set the current file of the zipfile to the first file.
|
|
||||||
return UNZ_OK if there is no problem
|
|
||||||
*/
|
|
||||||
|
|
||||||
extern int ZEXPORT unzGoToNextFile OF((unzFile file));
|
|
||||||
/*
|
|
||||||
Set the current file of the zipfile to the next file.
|
|
||||||
return UNZ_OK if there is no problem
|
|
||||||
return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
|
|
||||||
*/
|
|
||||||
|
|
||||||
extern int ZEXPORT unzLocateFile OF((unzFile file,
|
|
||||||
const char *szFileName,
|
|
||||||
int iCaseSensitivity));
|
|
||||||
/*
|
|
||||||
Try locate the file szFileName in the zipfile.
|
|
||||||
For the iCaseSensitivity signification, see unzStringFileNameCompare
|
|
||||||
|
|
||||||
return value :
|
|
||||||
UNZ_OK if the file is found. It becomes the current file.
|
|
||||||
UNZ_END_OF_LIST_OF_FILE if the file is not found
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
extern int ZEXPORT unzGetCurrentFileInfo OF((unzFile file,
|
|
||||||
unz_file_info *pfile_info,
|
|
||||||
char *szFileName,
|
|
||||||
uLong fileNameBufferSize,
|
|
||||||
void *extraField,
|
|
||||||
uLong extraFieldBufferSize,
|
|
||||||
char *szComment,
|
|
||||||
uLong commentBufferSize));
|
|
||||||
/*
|
|
||||||
Get Info about the current file
|
|
||||||
if pfile_info!=NULL, the *pfile_info structure will contain somes info about
|
|
||||||
the current file
|
|
||||||
if szFileName!=NULL, the filemane string will be copied in szFileName
|
|
||||||
(fileNameBufferSize is the size of the buffer)
|
|
||||||
if extraField!=NULL, the extra field information will be copied in extraField
|
|
||||||
(extraFieldBufferSize is the size of the buffer).
|
|
||||||
This is the Central-header version of the extra field
|
|
||||||
if szComment!=NULL, the comment string of the file will be copied in szComment
|
|
||||||
(commentBufferSize is the size of the buffer)
|
|
||||||
*/
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
/* for reading the content of the current zipfile, you can open it, read data
|
|
||||||
from it, and close it (you can close it before reading all the file)
|
|
||||||
*/
|
|
||||||
|
|
||||||
extern int ZEXPORT unzOpenCurrentFile OF((unzFile file));
|
|
||||||
/*
|
|
||||||
Open for reading data the current file in the zipfile.
|
|
||||||
If there is no error, the return value is UNZ_OK.
|
|
||||||
*/
|
|
||||||
|
|
||||||
extern int ZEXPORT unzCloseCurrentFile OF((unzFile file));
|
|
||||||
/*
|
|
||||||
Close the file in zip opened with unzOpenCurrentFile
|
|
||||||
Return UNZ_CRCERROR if all the file was read but the CRC is not good
|
|
||||||
*/
|
|
||||||
|
|
||||||
extern int ZEXPORT unzReadCurrentFile OF((unzFile file,
|
|
||||||
voidp buf,
|
|
||||||
unsigned len));
|
|
||||||
/*
|
|
||||||
Read bytes from the current file (opened by unzOpenCurrentFile)
|
|
||||||
buf contain buffer where data must be copied
|
|
||||||
len the size of buf.
|
|
||||||
|
|
||||||
return the number of byte copied if somes bytes are copied
|
|
||||||
return 0 if the end of file was reached
|
|
||||||
return <0 with error code if there is an error
|
|
||||||
(UNZ_ERRNO for IO error, or zLib error for uncompress error)
|
|
||||||
*/
|
|
||||||
|
|
||||||
extern z_off_t ZEXPORT unztell OF((unzFile file));
|
|
||||||
/*
|
|
||||||
Give the current position in uncompressed data
|
|
||||||
*/
|
|
||||||
|
|
||||||
extern int ZEXPORT unzeof OF((unzFile file));
|
|
||||||
/*
|
|
||||||
return 1 if the end of file was reached, 0 elsewhere
|
|
||||||
*/
|
|
||||||
|
|
||||||
extern int ZEXPORT unzGetLocalExtrafield OF((unzFile file,
|
|
||||||
voidp buf,
|
|
||||||
unsigned len));
|
|
||||||
/*
|
|
||||||
Read extra field from the current file (opened by unzOpenCurrentFile)
|
|
||||||
This is the local-header version of the extra field (sometimes, there is
|
|
||||||
more info in the local-header version than in the central-header)
|
|
||||||
|
|
||||||
if buf==NULL, it return the size of the local extra field
|
|
||||||
|
|
||||||
if buf!=NULL, len is the size of the buffer, the extra header is copied in
|
|
||||||
buf.
|
|
||||||
the return value is the number of bytes copied in buf, or (if <0)
|
|
||||||
the error code
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* _unz_H */
|
|
@ -1,129 +0,0 @@
|
|||||||
|
|
||||||
# Makefile for genplus SDL
|
|
||||||
#
|
|
||||||
# (c) 1999, 2000, 2001, 2002, 2003 Charles MacDonald
|
|
||||||
# modified by Eke-Eke <eke_eke31@yahoo.fr>
|
|
||||||
#
|
|
||||||
# Defines :
|
|
||||||
# -DLSB_FIRST : for little endian systems.
|
|
||||||
# -DLOGERROR : enable message logging
|
|
||||||
# -DLOGVDP : enable VDP debug messages
|
|
||||||
# -DLOGSOUND : enable AUDIO debug messages
|
|
||||||
|
|
||||||
NAME = gen_sdl.exe
|
|
||||||
|
|
||||||
CC = gcc
|
|
||||||
CFLAGS = `sdl-config --cflags` -march=i686 -O6 -fomit-frame-pointer -Wall -Wno-strict-aliasing
|
|
||||||
#-g -ggdb -pg
|
|
||||||
#-fomit-frame-pointer
|
|
||||||
#LDFLAGS = -pg
|
|
||||||
DEFINES = -DLSB_FIRST
|
|
||||||
|
|
||||||
INCLUDES = -I. -I.. -I../z80 -I../m68k -I../sound -I../input_hw -I../cart_hw -I../cart_hw/svp -I../ntsc
|
|
||||||
LIBS = `sdl-config --libs` -lz -lm
|
|
||||||
|
|
||||||
OBJECTS = obj/z80.o
|
|
||||||
|
|
||||||
OBJECTS += obj/m68kcpu.o \
|
|
||||||
obj/m68kops.o
|
|
||||||
|
|
||||||
|
|
||||||
OBJECTS += obj/genesis.o \
|
|
||||||
obj/vdp_ctrl.o \
|
|
||||||
obj/vdp_render.o \
|
|
||||||
obj/system.o \
|
|
||||||
obj/io_ctrl.o \
|
|
||||||
obj/mem68k.o \
|
|
||||||
obj/memz80.o \
|
|
||||||
obj/membnk.o \
|
|
||||||
obj/state.o
|
|
||||||
|
|
||||||
OBJECTS += obj/input.o \
|
|
||||||
obj/gamepad.o \
|
|
||||||
obj/lightgun.o \
|
|
||||||
obj/mouse.o \
|
|
||||||
obj/activator.o \
|
|
||||||
obj/xe_a1p.o \
|
|
||||||
obj/teamplayer.o \
|
|
||||||
obj/paddle.o \
|
|
||||||
obj/sportspad.o
|
|
||||||
|
|
||||||
|
|
||||||
OBJECTS += obj/sound.o \
|
|
||||||
obj/sn76489.o \
|
|
||||||
obj/ym2612.o
|
|
||||||
|
|
||||||
OBJECTS += obj/Fir_Resampler.o
|
|
||||||
OBJECTS += obj/blip.o
|
|
||||||
|
|
||||||
OBJECTS += obj/eq.o \
|
|
||||||
|
|
||||||
OBJECTS += obj/sram.o \
|
|
||||||
obj/eeprom.o \
|
|
||||||
obj/svp.o \
|
|
||||||
obj/ssp16.o \
|
|
||||||
obj/ggenie.o \
|
|
||||||
obj/areplay.o \
|
|
||||||
obj/md_cart.o \
|
|
||||||
obj/sms_cart.o
|
|
||||||
|
|
||||||
OBJECTS += obj/main.o \
|
|
||||||
obj/config.o \
|
|
||||||
obj/error.o \
|
|
||||||
obj/unzip.o \
|
|
||||||
obj/fileio.o \
|
|
||||||
obj/loadrom.o
|
|
||||||
|
|
||||||
OBJECTS += obj/sms_ntsc.o \
|
|
||||||
obj/md_ntsc.o
|
|
||||||
|
|
||||||
OBJECTS += obj/icon.o
|
|
||||||
|
|
||||||
all: $(NAME)
|
|
||||||
|
|
||||||
$(NAME): $(OBJECTS)
|
|
||||||
$(CC) $(LDFLAGS) $(OBJECTS) $(LIBS) -o $@
|
|
||||||
|
|
||||||
obj/%.o : ../%.c ../%.h
|
|
||||||
$(CC) -c $(CFLAGS) $(INCLUDES) $(DEFINES) $< -o $@
|
|
||||||
|
|
||||||
obj/%.o : ../asm/%.s
|
|
||||||
$(AS) $< -o $@
|
|
||||||
|
|
||||||
obj/%.o : ../sound/%.c ../sound/%.h
|
|
||||||
$(CC) -c $(CFLAGS) $(INCLUDES) $(DEFINES) $< -o $@
|
|
||||||
obj/%.o : ../sound/%.c
|
|
||||||
$(CC) -c $(CFLAGS) $(INCLUDES) $(DEFINES) $< -o $@
|
|
||||||
|
|
||||||
obj/%.o : ../input_hw/%.c ../input_hw/%.h
|
|
||||||
$(CC) -c $(CFLAGS) $(INCLUDES) $(DEFINES) $< -o $@
|
|
||||||
|
|
||||||
obj/%.o : ../cart_hw/%.c ../cart_hw/%.h
|
|
||||||
$(CC) -c $(CFLAGS) $(INCLUDES) $(DEFINES) $< -o $@
|
|
||||||
|
|
||||||
obj/%.o : ../cart_hw/svp/%.c
|
|
||||||
$(CC) -c $(CFLAGS) $(INCLUDES) $(DEFINES) $< -o $@
|
|
||||||
obj/%.o : ../cart_hw/svp/%.c ../cart_hw/svp/%.h
|
|
||||||
$(CC) -c $(CFLAGS) $(INCLUDES) $(DEFINES) $< -o $@
|
|
||||||
|
|
||||||
obj/%.o : ../z80/%.c ../z80/%.h
|
|
||||||
$(CC) -c $(CFLAGS) $(INCLUDES) $(DEFINES) $< -o $@
|
|
||||||
|
|
||||||
obj/%.o : ../m68k/%.c ../m68k/%.h
|
|
||||||
$(CC) -c $(CFLAGS) $(INCLUDES) $(DEFINES) $< -o $@
|
|
||||||
|
|
||||||
obj/%.o : ./%.c ./%.h
|
|
||||||
$(CC) -c $(CFLAGS) $(INCLUDES) $(DEFINES) $< -o $@
|
|
||||||
|
|
||||||
obj/%.o : ../ntsc/%.c ../ntsc/%.h
|
|
||||||
$(CC) -c $(CFLAGS) $(INCLUDES) $(DEFINES) $< -o $@
|
|
||||||
|
|
||||||
obj/icon.o :
|
|
||||||
windres icon.rc $@
|
|
||||||
|
|
||||||
pack :
|
|
||||||
strip $(NAME)
|
|
||||||
upx -9 $(NAME)
|
|
||||||
|
|
||||||
clean:
|
|
||||||
rm -f $(OBJECTS) $(NAME)
|
|
@ -1,48 +0,0 @@
|
|||||||
|
|
||||||
#include "osd.h"
|
|
||||||
|
|
||||||
t_config config;
|
|
||||||
|
|
||||||
|
|
||||||
void set_config_defaults(void)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
/* sound options */
|
|
||||||
config.psg_preamp = 150;
|
|
||||||
config.fm_preamp = 100;
|
|
||||||
config.hq_fm = 1;
|
|
||||||
config.psgBoostNoise = 0;
|
|
||||||
config.filter = 1;
|
|
||||||
config.low_freq = 200;
|
|
||||||
config.high_freq = 8000;
|
|
||||||
config.lg = 1.0;
|
|
||||||
config.mg = 1.0;
|
|
||||||
config.hg = 1.0;
|
|
||||||
config.lp_range = 60;
|
|
||||||
config.rolloff = 0.995;
|
|
||||||
config.dac_bits = 14;
|
|
||||||
|
|
||||||
/* system options */
|
|
||||||
config.region_detect = 0;
|
|
||||||
config.force_dtack = 0;
|
|
||||||
config.addr_error = 1;
|
|
||||||
config.tmss = 0;
|
|
||||||
config.lock_on = 0;//TYPE_SK;
|
|
||||||
config.romtype = 0;
|
|
||||||
|
|
||||||
/* display options */
|
|
||||||
config.overscan = 1;
|
|
||||||
config.render = 0;
|
|
||||||
|
|
||||||
/* controllers options */
|
|
||||||
input.system[0] = SYSTEM_MD_GAMEPAD;
|
|
||||||
input.system[1] = SYSTEM_MD_GAMEPAD;
|
|
||||||
config.gun_cursor[0] = 1;
|
|
||||||
config.gun_cursor[1] = 1;
|
|
||||||
config.invert_mouse = 0;
|
|
||||||
for (i=0;i<MAX_INPUTS;i++)
|
|
||||||
{
|
|
||||||
config.input[i].padtype = DEVICE_PAD6B;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,49 +0,0 @@
|
|||||||
|
|
||||||
#ifndef _CONFIG_H_
|
|
||||||
#define _CONFIG_H_
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Config Option
|
|
||||||
*
|
|
||||||
****************************************************************************/
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
uint8 padtype;
|
|
||||||
} t_input_config;
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
uint8 hq_fm;
|
|
||||||
uint8 filter;
|
|
||||||
uint8 psgBoostNoise;
|
|
||||||
uint8 dac_bits;
|
|
||||||
int16 psg_preamp;
|
|
||||||
int16 fm_preamp;
|
|
||||||
int16 lp_range;
|
|
||||||
int16 low_freq;
|
|
||||||
int16 high_freq;
|
|
||||||
int16 lg;
|
|
||||||
int16 mg;
|
|
||||||
int16 hg;
|
|
||||||
float rolloff;
|
|
||||||
uint8 region_detect;
|
|
||||||
uint8 force_dtack;
|
|
||||||
uint8 addr_error;
|
|
||||||
uint8 tmss;
|
|
||||||
uint8 lock_on;
|
|
||||||
uint8 hot_swap;
|
|
||||||
uint8 romtype;
|
|
||||||
uint8 invert_mouse;
|
|
||||||
uint8 gun_cursor[2];
|
|
||||||
uint8 overscan;
|
|
||||||
uint8 ntsc;
|
|
||||||
uint8 render;
|
|
||||||
t_input_config input[MAX_INPUTS];
|
|
||||||
} t_config;
|
|
||||||
|
|
||||||
/* Global variables */
|
|
||||||
extern t_config config;
|
|
||||||
extern void set_config_defaults(void);
|
|
||||||
|
|
||||||
#endif /* _CONFIG_H_ */
|
|
||||||
|
|
@ -1,36 +0,0 @@
|
|||||||
/*
|
|
||||||
error.c --
|
|
||||||
Error logging
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "osd.h"
|
|
||||||
|
|
||||||
FILE *error_log;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
int enabled;
|
|
||||||
int verbose;
|
|
||||||
FILE *log;
|
|
||||||
} t_error;
|
|
||||||
|
|
||||||
void error_init(void)
|
|
||||||
{
|
|
||||||
#ifdef LOGERROR
|
|
||||||
error_log = fopen("error.log","w");
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void error_shutdown(void)
|
|
||||||
{
|
|
||||||
if(error_log) fclose(error_log);
|
|
||||||
}
|
|
||||||
|
|
||||||
void error(char *format, ...)
|
|
||||||
{
|
|
||||||
if (!log_error) return;
|
|
||||||
va_list ap;
|
|
||||||
va_start(ap, format);
|
|
||||||
if(error_log) vfprintf(error_log, format, ap);
|
|
||||||
va_end(ap);
|
|
||||||
}
|
|
||||||
|
|
@ -1,13 +0,0 @@
|
|||||||
|
|
||||||
#ifndef _ERROR_H_
|
|
||||||
#define _ERROR_H_
|
|
||||||
|
|
||||||
/* Global variables */
|
|
||||||
FILE *error_log;
|
|
||||||
|
|
||||||
/* Function prototypes */
|
|
||||||
void error_init(void);
|
|
||||||
void error_shutdown(void);
|
|
||||||
void error(char *format, ...);
|
|
||||||
|
|
||||||
#endif /* _ERROR_H_ */
|
|
@ -1,151 +0,0 @@
|
|||||||
#include "shared.h"
|
|
||||||
|
|
||||||
/*
|
|
||||||
Load a normal file, or ZIP/GZ archive.
|
|
||||||
Returns NULL if an error occured.
|
|
||||||
*/
|
|
||||||
uint8 *load_archive(char *filename, int *file_size)
|
|
||||||
{
|
|
||||||
int size = 0;
|
|
||||||
uint8 *buf = NULL;
|
|
||||||
|
|
||||||
if(check_zip(filename))
|
|
||||||
{
|
|
||||||
unzFile *fd = NULL;
|
|
||||||
unz_file_info info;
|
|
||||||
int ret = 0;
|
|
||||||
|
|
||||||
/* Attempt to open the archive */
|
|
||||||
fd = unzOpen(filename);
|
|
||||||
if(!fd) return (NULL);
|
|
||||||
|
|
||||||
/* Go to first file in archive */
|
|
||||||
ret = unzGoToFirstFile(fd);
|
|
||||||
if(ret != UNZ_OK)
|
|
||||||
{
|
|
||||||
unzClose(fd);
|
|
||||||
return (NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = unzGetCurrentFileInfo(fd, &info, filename, 128, NULL, 0, NULL, 0);
|
|
||||||
if(ret != UNZ_OK)
|
|
||||||
{
|
|
||||||
unzClose(fd);
|
|
||||||
return (NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Open the file for reading */
|
|
||||||
ret = unzOpenCurrentFile(fd);
|
|
||||||
if(ret != UNZ_OK)
|
|
||||||
{
|
|
||||||
unzClose(fd);
|
|
||||||
return (NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Allocate file data buffer */
|
|
||||||
size = info.uncompressed_size;
|
|
||||||
buf = malloc(size);
|
|
||||||
if(!buf)
|
|
||||||
{
|
|
||||||
unzClose(fd);
|
|
||||||
return (NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Read (decompress) the file */
|
|
||||||
ret = unzReadCurrentFile(fd, buf, info.uncompressed_size);
|
|
||||||
if(ret != info.uncompressed_size)
|
|
||||||
{
|
|
||||||
free(buf);
|
|
||||||
unzCloseCurrentFile(fd);
|
|
||||||
unzClose(fd);
|
|
||||||
return (NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Close the current file */
|
|
||||||
ret = unzCloseCurrentFile(fd);
|
|
||||||
if(ret != UNZ_OK)
|
|
||||||
{
|
|
||||||
free(buf);
|
|
||||||
unzClose(fd);
|
|
||||||
return (NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Close the archive */
|
|
||||||
ret = unzClose(fd);
|
|
||||||
if(ret != UNZ_OK)
|
|
||||||
{
|
|
||||||
free(buf);
|
|
||||||
return (NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Update file size and return pointer to file data */
|
|
||||||
*file_size = size;
|
|
||||||
return (buf);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
gzFile *gd = NULL;
|
|
||||||
|
|
||||||
/* Open file */
|
|
||||||
gd = gzopen(filename, "rb");
|
|
||||||
if(!gd) return (0);
|
|
||||||
|
|
||||||
/* Get file size */
|
|
||||||
size = gzsize(gd);
|
|
||||||
|
|
||||||
/* Allocate file data buffer */
|
|
||||||
buf = malloc(size);
|
|
||||||
if(!buf)
|
|
||||||
{
|
|
||||||
gzclose(gd);
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Read file data */
|
|
||||||
gzread(gd, buf, size);
|
|
||||||
|
|
||||||
/* Close file */
|
|
||||||
gzclose(gd);
|
|
||||||
|
|
||||||
/* Update file size and return pointer to file data */
|
|
||||||
*file_size = size;
|
|
||||||
return (buf);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
Verifies if a file is a ZIP archive or not.
|
|
||||||
Returns: 1= ZIP archive, 0= not a ZIP archive
|
|
||||||
*/
|
|
||||||
int check_zip(char *filename)
|
|
||||||
{
|
|
||||||
uint8 buf[2];
|
|
||||||
FILE *fd = NULL;
|
|
||||||
fd = fopen(filename, "rb");
|
|
||||||
if(!fd) return (0);
|
|
||||||
fread(buf, 2, 1, fd);
|
|
||||||
fclose(fd);
|
|
||||||
if(memcmp(buf, "PK", 2) == 0) return (1);
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
Returns the size of a GZ compressed file.
|
|
||||||
*/
|
|
||||||
int gzsize(gzFile *gd)
|
|
||||||
{
|
|
||||||
#define CHUNKSIZE (0x10000)
|
|
||||||
int size = 0, length = 0;
|
|
||||||
unsigned char buffer[CHUNKSIZE];
|
|
||||||
gzrewind(gd);
|
|
||||||
do {
|
|
||||||
size = gzread(gd, buffer, CHUNKSIZE);
|
|
||||||
if(size <= 0) break;
|
|
||||||
length += size;
|
|
||||||
} while (!gzeof(gd));
|
|
||||||
gzrewind(gd);
|
|
||||||
return (length);
|
|
||||||
#undef CHUNKSIZE
|
|
||||||
}
|
|
@ -1,14 +0,0 @@
|
|||||||
#ifndef _FILEIO_H_
|
|
||||||
#define _FILEIO_H_
|
|
||||||
|
|
||||||
/* Global variables */
|
|
||||||
extern int cart_size;
|
|
||||||
extern char cart_name[0x100];
|
|
||||||
|
|
||||||
/* Function prototypes */
|
|
||||||
uint8 *load_archive(char *filename, int *file_size);
|
|
||||||
int load_cart(char *filename);
|
|
||||||
int check_zip(char *filename);
|
|
||||||
int gzsize(gzFile *gd);
|
|
||||||
|
|
||||||
#endif /* _FILEIO_H_ */
|
|
@ -1 +0,0 @@
|
|||||||
MAINICON ICON "md.ico"
|
|
@ -1,727 +0,0 @@
|
|||||||
#include <windows.h>
|
|
||||||
|
|
||||||
#include "SDL.h"
|
|
||||||
#include "SDL_thread.h"
|
|
||||||
|
|
||||||
#include "shared.h"
|
|
||||||
#include "sms_ntsc.h"
|
|
||||||
#include "md_ntsc.h"
|
|
||||||
|
|
||||||
#define SOUND_FREQUENCY 48000
|
|
||||||
#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 = 0; /* SDL_FULLSCREEN */
|
|
||||||
|
|
||||||
/* sound */
|
|
||||||
|
|
||||||
struct {
|
|
||||||
char* current_pos;
|
|
||||||
char* buffer;
|
|
||||||
int current_emulated_samples;
|
|
||||||
} sdl_sound;
|
|
||||||
|
|
||||||
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) * 11;
|
|
||||||
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()
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
short* p;
|
|
||||||
|
|
||||||
int size = audio_update();
|
|
||||||
|
|
||||||
if (use_sound)
|
|
||||||
{
|
|
||||||
SDL_LockAudio();
|
|
||||||
p = (short*)sdl_sound.current_pos;
|
|
||||||
for(i = 0; i < size; ++i) {
|
|
||||||
*p = snd.buffer[0][i];
|
|
||||||
++p;
|
|
||||||
*p = snd.buffer[1][i];
|
|
||||||
++p;
|
|
||||||
}
|
|
||||||
sdl_sound.current_pos = (char*)p;
|
|
||||||
sdl_sound.current_emulated_samples += size * 2 * sizeof(short);
|
|
||||||
SDL_UnlockAudio();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void sdl_sound_close()
|
|
||||||
{
|
|
||||||
SDL_PauseAudio(1);
|
|
||||||
SDL_CloseAudio();
|
|
||||||
if (sdl_sound.buffer)
|
|
||||||
free(sdl_sound.buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 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 0;
|
|
||||||
}
|
|
||||||
sdl_video.surf_screen = SDL_SetVideoMode(VIDEO_WIDTH, VIDEO_HEIGHT, 16, SDL_SWSURFACE | fullscreen);
|
|
||||||
sdl_video.surf_bitmap = SDL_CreateRGBSurface(SDL_SWSURFACE, 720, 576, 16, 0, 0, 0, 0);
|
|
||||||
sdl_video.frames_rendered = 0;
|
|
||||||
SDL_ShowCursor(0);
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void sdl_video_update()
|
|
||||||
{
|
|
||||||
system_frame(0);
|
|
||||||
|
|
||||||
/* viewport size changed */
|
|
||||||
if(bitmap.viewport.changed & 1)
|
|
||||||
{
|
|
||||||
bitmap.viewport.changed &= ~1;
|
|
||||||
|
|
||||||
/* source bitmap */
|
|
||||||
sdl_video.srect.w = bitmap.viewport.w+2*bitmap.viewport.x;
|
|
||||||
sdl_video.srect.h = bitmap.viewport.h+2*bitmap.viewport.y;
|
|
||||||
sdl_video.srect.x = 0;
|
|
||||||
sdl_video.srect.y = 0;
|
|
||||||
if (sdl_video.srect.w > VIDEO_WIDTH)
|
|
||||||
{
|
|
||||||
sdl_video.srect.x = (sdl_video.srect.w - VIDEO_WIDTH) / 2;
|
|
||||||
sdl_video.srect.w = VIDEO_WIDTH;
|
|
||||||
}
|
|
||||||
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);
|
|
||||||
|
|
||||||
/*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;
|
|
||||||
}
|
|
||||||
} */
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
++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;
|
|
||||||
|
|
||||||
/* sync */
|
|
||||||
|
|
||||||
static Uint32 sdl_sync_timer_callback(Uint32 interval)
|
|
||||||
{
|
|
||||||
SDL_SemPost(sdl_sync.sem_sync);
|
|
||||||
char caption[100];
|
|
||||||
sdl_sync.ticks++;
|
|
||||||
if (sdl_sync.ticks == (vdp_pal ? 50 : 20))
|
|
||||||
{
|
|
||||||
int fps = vdp_pal ? (sdl_video.frames_rendered / 3) : sdl_video.frames_rendered;
|
|
||||||
sdl_sync.ticks = sdl_video.frames_rendered = 0;
|
|
||||||
sprintf(caption,"%d fps - %s ", fps, rominfo.international);
|
|
||||||
SDL_WM_SetCaption(caption, NULL);
|
|
||||||
}
|
|
||||||
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 int sdl_control_update(SDLKey keystate)
|
|
||||||
{
|
|
||||||
switch (keystate)
|
|
||||||
{
|
|
||||||
case SDLK_TAB:
|
|
||||||
{
|
|
||||||
system_init();
|
|
||||||
system_reset();
|
|
||||||
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:
|
|
||||||
{
|
|
||||||
config.render ^=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;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case SDLK_F7:
|
|
||||||
{
|
|
||||||
FILE *f = fopen("game.gpz","r+b");
|
|
||||||
if (f)
|
|
||||||
{
|
|
||||||
uint8 buf[STATE_SIZE];
|
|
||||||
fread(&buf, STATE_SIZE, 1, f);
|
|
||||||
state_load(buf);
|
|
||||||
fclose(f);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case SDLK_F8:
|
|
||||||
{
|
|
||||||
FILE *f = fopen("game.gpz","w+b");
|
|
||||||
if (f)
|
|
||||||
{
|
|
||||||
uint8 buf[STATE_SIZE];
|
|
||||||
state_save(buf);
|
|
||||||
fwrite(&buf, STATE_SIZE, 1, f);
|
|
||||||
fclose(f);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case SDLK_F9:
|
|
||||||
{
|
|
||||||
vdp_pal ^= 1;
|
|
||||||
|
|
||||||
/* save YM2612 context */
|
|
||||||
unsigned char *temp = malloc(YM2612GetContextSize());
|
|
||||||
if (temp)
|
|
||||||
memcpy(temp, YM2612GetContextPtr(), YM2612GetContextSize());
|
|
||||||
|
|
||||||
/* reinitialize all timings */
|
|
||||||
audio_init(snd.sample_rate, snd.frame_rate);
|
|
||||||
system_init();
|
|
||||||
|
|
||||||
/* restore YM2612 context */
|
|
||||||
if (temp)
|
|
||||||
{
|
|
||||||
YM2612Restore(temp);
|
|
||||||
free(temp);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* reinitialize VC max value */
|
|
||||||
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) */
|
|
||||||
};
|
|
||||||
vc_max = vc_table[(reg[1] >> 2) & 3][vdp_pal];
|
|
||||||
|
|
||||||
/* reinitialize display area */
|
|
||||||
bitmap.viewport.changed = 3;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case SDLK_F10:
|
|
||||||
{
|
|
||||||
gen_softreset(1);
|
|
||||||
gen_softreset(0);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case SDLK_F11:
|
|
||||||
{
|
|
||||||
config.overscan ^= 1;
|
|
||||||
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:
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int sdl_input_update(void)
|
|
||||||
{
|
|
||||||
uint8 *keystate = SDL_GetKeyState(NULL);
|
|
||||||
|
|
||||||
/* reset input */
|
|
||||||
input.pad[joynum] = 0;
|
|
||||||
|
|
||||||
switch (input.dev[joynum])
|
|
||||||
{
|
|
||||||
case DEVICE_LIGHTGUN:
|
|
||||||
{
|
|
||||||
/* get mouse (absolute values) */
|
|
||||||
int x,y;
|
|
||||||
int state = SDL_GetMouseState(&x,&y);
|
|
||||||
|
|
||||||
/* Calculate X Y axis values */
|
|
||||||
input.analog[joynum][0] = (x * bitmap.viewport.w) / VIDEO_WIDTH;
|
|
||||||
input.analog[joynum][1] = (y * bitmap.viewport.h) / VIDEO_HEIGHT;
|
|
||||||
|
|
||||||
/* 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_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:
|
|
||||||
{
|
|
||||||
/* 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_A1P:
|
|
||||||
{
|
|
||||||
/* 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_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;
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
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;
|
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (system_hw == SYSTEM_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++;
|
|
||||||
if(state & SDL_BUTTON_RMASK) input.pad[joynum] |= INPUT_B;
|
|
||||||
if(state & SDL_BUTTON_LMASK) input.pad[joynum] |= INPUT_A;
|
|
||||||
}
|
|
||||||
|
|
||||||
free (keystate);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int main (int argc, char **argv)
|
|
||||||
{
|
|
||||||
int running = 1;
|
|
||||||
|
|
||||||
/* Print help if no game specified */
|
|
||||||
if(argc < 2)
|
|
||||||
{
|
|
||||||
char caption[256];
|
|
||||||
sprintf(caption, "Genesis Plus\\SDL by Charles MacDonald\nWWW: http://cgfm2.emuviews.com\nusage: %s gamename\n", argv[0]);
|
|
||||||
MessageBox(NULL, caption, "Information", 0);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* set default config */
|
|
||||||
error_init();
|
|
||||||
set_config_defaults();
|
|
||||||
|
|
||||||
/* Load ROM file */
|
|
||||||
cart.rom = malloc(10*1024*1024);
|
|
||||||
memset(cart.rom, 0, 10*1024*1024);
|
|
||||||
if(!load_rom(argv[1]))
|
|
||||||
{
|
|
||||||
char caption[256];
|
|
||||||
sprintf(caption, "Error loading file `%s'.", argv[1]);
|
|
||||||
MessageBox(NULL, caption, "Error", 0);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* load BIOS */
|
|
||||||
memset(bios_rom, 0, sizeof(bios_rom));
|
|
||||||
FILE *f = fopen(OS_ROM, "rb");
|
|
||||||
if (f!=NULL)
|
|
||||||
{
|
|
||||||
fread(&bios_rom, 0x800,1,f);
|
|
||||||
fclose(f);
|
|
||||||
int i;
|
|
||||||
for(i = 0; i < 0x800; i += 2)
|
|
||||||
{
|
|
||||||
uint8 temp = bios_rom[i];
|
|
||||||
bios_rom[i] = bios_rom[i+1];
|
|
||||||
bios_rom[i+1] = temp;
|
|
||||||
}
|
|
||||||
config.tmss |= 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* initialize SDL */
|
|
||||||
if(SDL_Init(0) < 0)
|
|
||||||
{
|
|
||||||
char caption[256];
|
|
||||||
sprintf(caption, "SDL initialization failed");
|
|
||||||
MessageBox(NULL, caption, "Error", 0);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
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;
|
|
||||||
bitmap.depth = 16;
|
|
||||||
bitmap.granularity = 2;
|
|
||||||
bitmap.pitch = (bitmap.width * bitmap.granularity);
|
|
||||||
bitmap.data = sdl_video.surf_bitmap->pixels;
|
|
||||||
SDL_UnlockSurface(sdl_video.surf_bitmap);
|
|
||||||
bitmap.viewport.changed = 3;
|
|
||||||
|
|
||||||
/* initialize emulation */
|
|
||||||
audio_init(SOUND_FREQUENCY, vdp_pal ? 50.0 : 60.0);
|
|
||||||
system_init();
|
|
||||||
|
|
||||||
/* load SRAM */
|
|
||||||
f = fopen("./game.srm", "rb");
|
|
||||||
if (f!=NULL)
|
|
||||||
{
|
|
||||||
fread(sram.sram,0x10000,1, f);
|
|
||||||
fclose(f);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* reset emulation */
|
|
||||||
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_QUIT:
|
|
||||||
running = 0;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SDL_KEYDOWN:
|
|
||||||
running = sdl_control_update(event.key.keysym.sym);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sdl_video_update();
|
|
||||||
sdl_sound_update();
|
|
||||||
|
|
||||||
if(!turbo_mode && sdl_sync.sem_sync && sdl_video.frames_rendered % 3 == 0)
|
|
||||||
{
|
|
||||||
SDL_SemWait(sdl_sync.sem_sync);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/* save SRAM */
|
|
||||||
f = fopen("./game.srm", "wb");
|
|
||||||
if (f!=NULL)
|
|
||||||
{
|
|
||||||
fwrite(sram.sram,0x10000,1, f);
|
|
||||||
fclose(f);
|
|
||||||
}
|
|
||||||
|
|
||||||
system_shutdown();
|
|
||||||
audio_shutdown();
|
|
||||||
error_shutdown();
|
|
||||||
free(cart.rom);
|
|
||||||
|
|
||||||
sdl_video_close();
|
|
||||||
sdl_sound_close();
|
|
||||||
sdl_sync_close();
|
|
||||||
SDL_Quit();
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -1,10 +0,0 @@
|
|||||||
|
|
||||||
#ifndef _MAIN_H_
|
|
||||||
#define _MAIN_H_
|
|
||||||
|
|
||||||
#define MAX_INPUTS 8
|
|
||||||
|
|
||||||
extern int debug_on;
|
|
||||||
extern int log_error;
|
|
||||||
|
|
||||||
#endif /* _MAIN_H_ */
|
|
Binary file not shown.
Before Width: | Height: | Size: 41 KiB |
@ -1,29 +0,0 @@
|
|||||||
|
|
||||||
#ifndef _OSD_H_
|
|
||||||
#define _OSD_H_
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include <time.h>
|
|
||||||
#include <conio.h>
|
|
||||||
|
|
||||||
#include <SDL.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
#include "shared.h"
|
|
||||||
#include "main.h"
|
|
||||||
#include "config.h"
|
|
||||||
#include "error.h"
|
|
||||||
#include "unzip.h"
|
|
||||||
#include "fileio.h"
|
|
||||||
|
|
||||||
#define osd_input_Update sdl_input_update
|
|
||||||
|
|
||||||
#define GG_ROM "./ggenie.bin"
|
|
||||||
#define AR_ROM "./areplay.bin"
|
|
||||||
#define OS_ROM "./bios.bin"
|
|
||||||
#define SK_ROM "./sk.bin"
|
|
||||||
#define SK_UPMEM "./sk2chip.bin"
|
|
||||||
|
|
||||||
#endif /* _OSD_H_ */
|
|
@ -1,5 +0,0 @@
|
|||||||
Compile with MinGW.
|
|
||||||
You will also need to install the SDL library (http://www.libsdl.org/).
|
|
||||||
Zlib is required for zipped rom support.
|
|
||||||
|
|
||||||
Please distribute required dlls with the executable.
|
|
File diff suppressed because it is too large
Load Diff
@ -1,273 +0,0 @@
|
|||||||
/* unzip.h -- IO for uncompress .zip files using zlib
|
|
||||||
Version 0.15 beta, Mar 19th, 1998,
|
|
||||||
|
|
||||||
Copyright (C) 1998 Gilles Vollant
|
|
||||||
|
|
||||||
This unzip package allow extract file from .ZIP file, compatible with PKZip 2.04g
|
|
||||||
WinZip, InfoZip tools and compatible.
|
|
||||||
Encryption and multi volume ZipFile (span) are not supported.
|
|
||||||
Old compressions used by old PKZip 1.x are not supported
|
|
||||||
|
|
||||||
THIS IS AN ALPHA VERSION. AT THIS STAGE OF DEVELOPPEMENT, SOMES API OR STRUCTURE
|
|
||||||
CAN CHANGE IN FUTURE VERSION !!
|
|
||||||
I WAIT FEEDBACK at mail info@winimage.com
|
|
||||||
Visit also http://www.winimage.com/zLibDll/unzip.htm for evolution
|
|
||||||
|
|
||||||
Condition of use and distribution are the same than zlib :
|
|
||||||
|
|
||||||
This software is provided 'as-is', without any express or implied
|
|
||||||
warranty. In no event will the authors be held liable for any damages
|
|
||||||
arising from the use of this software.
|
|
||||||
|
|
||||||
Permission is granted to anyone to use this software for any purpose,
|
|
||||||
including commercial applications, and to alter it and redistribute it
|
|
||||||
freely, subject to the following restrictions:
|
|
||||||
|
|
||||||
1. The origin of this software must not be misrepresented; you must not
|
|
||||||
claim that you wrote the original software. If you use this software
|
|
||||||
in a product, an acknowledgment in the product documentation would be
|
|
||||||
appreciated but is not required.
|
|
||||||
2. Altered source versions must be plainly marked as such, and must not be
|
|
||||||
misrepresented as being the original software.
|
|
||||||
3. This notice may not be removed or altered from any source distribution.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* for more info about .ZIP format, see
|
|
||||||
ftp://ftp.cdrom.com/pub/infozip/doc/appnote-970311-iz.zip
|
|
||||||
PkWare has also a specification at :
|
|
||||||
ftp://ftp.pkware.com/probdesc.zip */
|
|
||||||
|
|
||||||
#ifndef _unz_H
|
|
||||||
#define _unz_H
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef _ZLIB_H
|
|
||||||
#include "zlib.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(STRICTUNZIP) || defined(STRICTZIPUNZIP)
|
|
||||||
/* like the STRICT of WIN32, we define a pointer that cannot be converted
|
|
||||||
from (void*) without cast */
|
|
||||||
typedef struct TagunzFile__ { int unused; } unzFile__;
|
|
||||||
typedef unzFile__ *unzFile;
|
|
||||||
#else
|
|
||||||
typedef voidp unzFile;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#define UNZ_OK (0)
|
|
||||||
#define UNZ_END_OF_LIST_OF_FILE (-100)
|
|
||||||
#define UNZ_ERRNO (Z_ERRNO)
|
|
||||||
#define UNZ_EOF (0)
|
|
||||||
#define UNZ_PARAMERROR (-102)
|
|
||||||
#define UNZ_BADZIPFILE (-103)
|
|
||||||
#define UNZ_INTERNALERROR (-104)
|
|
||||||
#define UNZ_CRCERROR (-105)
|
|
||||||
|
|
||||||
/* tm_unz contain date/time info */
|
|
||||||
typedef struct tm_unz_s
|
|
||||||
{
|
|
||||||
uInt tm_sec; /* seconds after the minute - [0,59] */
|
|
||||||
uInt tm_min; /* minutes after the hour - [0,59] */
|
|
||||||
uInt tm_hour; /* hours since midnight - [0,23] */
|
|
||||||
uInt tm_mday; /* day of the month - [1,31] */
|
|
||||||
uInt tm_mon; /* months since January - [0,11] */
|
|
||||||
uInt tm_year; /* years - [1980..2044] */
|
|
||||||
} tm_unz;
|
|
||||||
|
|
||||||
/* unz_global_info structure contain global data about the ZIPfile
|
|
||||||
These data comes from the end of central dir */
|
|
||||||
typedef struct unz_global_info_s
|
|
||||||
{
|
|
||||||
uLong number_entry; /* total number of entries in
|
|
||||||
the central dir on this disk */
|
|
||||||
uLong size_comment; /* size of the global comment of the zipfile */
|
|
||||||
} unz_global_info;
|
|
||||||
|
|
||||||
|
|
||||||
/* unz_file_info contain information about a file in the zipfile */
|
|
||||||
typedef struct unz_file_info_s
|
|
||||||
{
|
|
||||||
uLong version; /* version made by 2 bytes */
|
|
||||||
uLong version_needed; /* version needed to extract 2 bytes */
|
|
||||||
uLong flag; /* general purpose bit flag 2 bytes */
|
|
||||||
uLong compression_method; /* compression method 2 bytes */
|
|
||||||
uLong dosDate; /* last mod file date in Dos fmt 4 bytes */
|
|
||||||
uLong crc; /* crc-32 4 bytes */
|
|
||||||
uLong compressed_size; /* compressed size 4 bytes */
|
|
||||||
uLong uncompressed_size; /* uncompressed size 4 bytes */
|
|
||||||
uLong size_filename; /* filename length 2 bytes */
|
|
||||||
uLong size_file_extra; /* extra field length 2 bytes */
|
|
||||||
uLong size_file_comment; /* file comment length 2 bytes */
|
|
||||||
|
|
||||||
uLong disk_num_start; /* disk number start 2 bytes */
|
|
||||||
uLong internal_fa; /* internal file attributes 2 bytes */
|
|
||||||
uLong external_fa; /* external file attributes 4 bytes */
|
|
||||||
|
|
||||||
tm_unz tmu_date;
|
|
||||||
} unz_file_info;
|
|
||||||
|
|
||||||
extern int ZEXPORT unzStringFileNameCompare OF ((const char* fileName1,
|
|
||||||
const char* fileName2,
|
|
||||||
int iCaseSensitivity));
|
|
||||||
/*
|
|
||||||
Compare two filename (fileName1,fileName2).
|
|
||||||
If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)
|
|
||||||
If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi
|
|
||||||
or strcasecmp)
|
|
||||||
If iCaseSenisivity = 0, case sensitivity is defaut of your operating system
|
|
||||||
(like 1 on Unix, 2 on Windows)
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
extern unzFile ZEXPORT unzOpen OF((const char *path));
|
|
||||||
/*
|
|
||||||
Open a Zip file. path contain the full pathname (by example,
|
|
||||||
on a Windows NT computer "c:\\zlib\\zlib111.zip" or on an Unix computer
|
|
||||||
"zlib/zlib111.zip".
|
|
||||||
If the zipfile cannot be opened (file don't exist or in not valid), the
|
|
||||||
return value is NULL.
|
|
||||||
Else, the return value is a unzFile Handle, usable with other function
|
|
||||||
of this unzip package.
|
|
||||||
*/
|
|
||||||
|
|
||||||
extern int ZEXPORT unzClose OF((unzFile file));
|
|
||||||
/*
|
|
||||||
Close a ZipFile opened with unzipOpen.
|
|
||||||
If there is files inside the .Zip opened with unzOpenCurrentFile (see later),
|
|
||||||
these files MUST be closed with unzipCloseCurrentFile before call unzipClose.
|
|
||||||
return UNZ_OK if there is no problem. */
|
|
||||||
|
|
||||||
extern int ZEXPORT unzGetGlobalInfo OF((unzFile file,
|
|
||||||
unz_global_info *pglobal_info));
|
|
||||||
/*
|
|
||||||
Write info about the ZipFile in the *pglobal_info structure.
|
|
||||||
No preparation of the structure is needed
|
|
||||||
return UNZ_OK if there is no problem. */
|
|
||||||
|
|
||||||
|
|
||||||
extern int ZEXPORT unzGetGlobalComment OF((unzFile file,
|
|
||||||
char *szComment,
|
|
||||||
uLong uSizeBuf));
|
|
||||||
/*
|
|
||||||
Get the global comment string of the ZipFile, in the szComment buffer.
|
|
||||||
uSizeBuf is the size of the szComment buffer.
|
|
||||||
return the number of byte copied or an error code <0
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
/* Unzip package allow you browse the directory of the zipfile */
|
|
||||||
|
|
||||||
extern int ZEXPORT unzGoToFirstFile OF((unzFile file));
|
|
||||||
/*
|
|
||||||
Set the current file of the zipfile to the first file.
|
|
||||||
return UNZ_OK if there is no problem
|
|
||||||
*/
|
|
||||||
|
|
||||||
extern int ZEXPORT unzGoToNextFile OF((unzFile file));
|
|
||||||
/*
|
|
||||||
Set the current file of the zipfile to the next file.
|
|
||||||
return UNZ_OK if there is no problem
|
|
||||||
return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
|
|
||||||
*/
|
|
||||||
|
|
||||||
extern int ZEXPORT unzLocateFile OF((unzFile file,
|
|
||||||
const char *szFileName,
|
|
||||||
int iCaseSensitivity));
|
|
||||||
/*
|
|
||||||
Try locate the file szFileName in the zipfile.
|
|
||||||
For the iCaseSensitivity signification, see unzStringFileNameCompare
|
|
||||||
|
|
||||||
return value :
|
|
||||||
UNZ_OK if the file is found. It becomes the current file.
|
|
||||||
UNZ_END_OF_LIST_OF_FILE if the file is not found
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
extern int ZEXPORT unzGetCurrentFileInfo OF((unzFile file,
|
|
||||||
unz_file_info *pfile_info,
|
|
||||||
char *szFileName,
|
|
||||||
uLong fileNameBufferSize,
|
|
||||||
void *extraField,
|
|
||||||
uLong extraFieldBufferSize,
|
|
||||||
char *szComment,
|
|
||||||
uLong commentBufferSize));
|
|
||||||
/*
|
|
||||||
Get Info about the current file
|
|
||||||
if pfile_info!=NULL, the *pfile_info structure will contain somes info about
|
|
||||||
the current file
|
|
||||||
if szFileName!=NULL, the filemane string will be copied in szFileName
|
|
||||||
(fileNameBufferSize is the size of the buffer)
|
|
||||||
if extraField!=NULL, the extra field information will be copied in extraField
|
|
||||||
(extraFieldBufferSize is the size of the buffer).
|
|
||||||
This is the Central-header version of the extra field
|
|
||||||
if szComment!=NULL, the comment string of the file will be copied in szComment
|
|
||||||
(commentBufferSize is the size of the buffer)
|
|
||||||
*/
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
/* for reading the content of the current zipfile, you can open it, read data
|
|
||||||
from it, and close it (you can close it before reading all the file)
|
|
||||||
*/
|
|
||||||
|
|
||||||
extern int ZEXPORT unzOpenCurrentFile OF((unzFile file));
|
|
||||||
/*
|
|
||||||
Open for reading data the current file in the zipfile.
|
|
||||||
If there is no error, the return value is UNZ_OK.
|
|
||||||
*/
|
|
||||||
|
|
||||||
extern int ZEXPORT unzCloseCurrentFile OF((unzFile file));
|
|
||||||
/*
|
|
||||||
Close the file in zip opened with unzOpenCurrentFile
|
|
||||||
Return UNZ_CRCERROR if all the file was read but the CRC is not good
|
|
||||||
*/
|
|
||||||
|
|
||||||
extern int ZEXPORT unzReadCurrentFile OF((unzFile file,
|
|
||||||
voidp buf,
|
|
||||||
unsigned len));
|
|
||||||
/*
|
|
||||||
Read bytes from the current file (opened by unzOpenCurrentFile)
|
|
||||||
buf contain buffer where data must be copied
|
|
||||||
len the size of buf.
|
|
||||||
|
|
||||||
return the number of byte copied if somes bytes are copied
|
|
||||||
return 0 if the end of file was reached
|
|
||||||
return <0 with error code if there is an error
|
|
||||||
(UNZ_ERRNO for IO error, or zLib error for uncompress error)
|
|
||||||
*/
|
|
||||||
|
|
||||||
extern z_off_t ZEXPORT unztell OF((unzFile file));
|
|
||||||
/*
|
|
||||||
Give the current position in uncompressed data
|
|
||||||
*/
|
|
||||||
|
|
||||||
extern int ZEXPORT unzeof OF((unzFile file));
|
|
||||||
/*
|
|
||||||
return 1 if the end of file was reached, 0 elsewhere
|
|
||||||
*/
|
|
||||||
|
|
||||||
extern int ZEXPORT unzGetLocalExtrafield OF((unzFile file,
|
|
||||||
voidp buf,
|
|
||||||
unsigned len));
|
|
||||||
/*
|
|
||||||
Read extra field from the current file (opened by unzOpenCurrentFile)
|
|
||||||
This is the local-header version of the extra field (sometimes, there is
|
|
||||||
more info in the local-header version than in the central-header)
|
|
||||||
|
|
||||||
if buf==NULL, it return the size of the local extra field
|
|
||||||
|
|
||||||
if buf!=NULL, len is the size of the buffer, the extra header is copied in
|
|
||||||
buf.
|
|
||||||
the return value is the number of bytes copied in buf, or (if <0)
|
|
||||||
the error code
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* _unz_H */
|
|
@ -25,7 +25,7 @@
|
|||||||
* NTSC (60Hz) & PAL (50Hz) hardware emulation
|
* NTSC (60Hz) & PAL (50Hz) hardware emulation
|
||||||
* highly accurate 68000 & Z80 CPU emulation
|
* highly accurate 68000 & Z80 CPU emulation
|
||||||
* highly accurate VDP emulation (all rendering modes, HBLANK, DMA, FIFO, HV interrupts, undocumented registers, display mid-line changes…)
|
* highly accurate VDP emulation (all rendering modes, HBLANK, DMA, FIFO, HV interrupts, undocumented registers, display mid-line changes…)
|
||||||
* cycle-accurate YM2612 emulation (FM synthesis is done at the original frequency, using FIR resampling)
|
* cycle-accurate YM2612 & YM2413 emulation (FM synthesis is done at the original frequency, using FIR resampling)
|
||||||
* cycle-accurate chip synchronization (68000/Z80/YM2612/SN76489)
|
* cycle-accurate chip synchronization (68000/Z80/YM2612/SN76489)
|
||||||
* basic hardware latency emulation (VDP/68k, Z80/68k)
|
* basic hardware latency emulation (VDP/68k, Z80/68k)
|
||||||
* full overscan area (horizontal & vertical colored borders) emulation (optional)
|
* full overscan area (horizontal & vertical colored borders) emulation (optional)
|
||||||
|
Loading…
Reference in New Issue
Block a user