Commit 67c0c9b2 authored by Cayce's avatar Cayce
Browse files

finalize migration to fMSX 5.1 by adding some missing cheat-related code.

Parts of this will be removed later, in a 'dead code removal' sweep
parent 0bae7b1b
...@@ -15,6 +15,21 @@ ...@@ -15,6 +15,21 @@
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <streams/file_stream.h>
/* Forward declarations */
RFILE* rfopen(const char *path, const char *mode);
char *rfgets(char *buffer, int maxCount, RFILE* stream);
int rfclose(RFILE* stream);
int64_t rfread(void* buffer,
size_t elem_size, size_t elem_count, RFILE* stream);
int64_t rfseek(RFILE* stream, int64_t offset, int origin);
int64_t rftell(RFILE* stream);
int64_t rfwrite(void const* buffer,
size_t elem_size, size_t elem_count, RFILE* stream);
int rfgetc(RFILE* stream);
int rfeof(RFILE* stream);
/** LoadFileMCF() ********************************************/ /** LoadFileMCF() ********************************************/
/** Load cheats from .MCF file. Returns number of loaded **/ /** Load cheats from .MCF file. Returns number of loaded **/
/** cheat entries or 0 on failure. **/ /** cheat entries or 0 on failure. **/
......
...@@ -29,6 +29,7 @@ SOURCES_C := \ ...@@ -29,6 +29,7 @@ SOURCES_C := \
$(EMULIB)/SHA1.c \ $(EMULIB)/SHA1.c \
$(EMULIB)/Floppy.c \ $(EMULIB)/Floppy.c \
$(EMULIB)/FDIDisk.c \ $(EMULIB)/FDIDisk.c \
$(EMULIB)/MCF.c \
$(LIBZ80)/Z80.c \ $(LIBZ80)/Z80.c \
$(EMULIB)/I8255.c \ $(EMULIB)/I8255.c \
$(EMULIB)/YM2413.c \ $(EMULIB)/YM2413.c \
......
fmsx fmsx
==== ====
this is a port of fMSX 4.9 to the libretro API this is a port of fMSX 5.1 to the libretro API
source : http://fms.komkon.org/fMSX/ source : http://fms.komkon.org/fMSX/
......
...@@ -181,10 +181,14 @@ int Palette[16]; /* Current palette */ ...@@ -181,10 +181,14 @@ int Palette[16]; /* Current palette */
int MCFCount = 0; /* Size of MCFEntries[] */ int MCFCount = 0; /* Size of MCFEntries[] */
MCFEntry MCFEntries[MAXCHEATS]; /* Entries from .MCF file */ MCFEntry MCFEntries[MAXCHEATS]; /* Entries from .MCF file */
/** Cheat codes **********************************************/
byte CheatsON = 0; /* 1: Cheats are on */
int CheatCount = 0; /* # cheats, <=MAXCHEATS */
CheatCode CheatCodes[MAXCHEATS];
/** Places in DiskROM to be patched with ED FE C9 ************/ /** Places in DiskROM to be patched with ED FE C9 ************/
static const word DiskPatches[] = static const word DiskPatches[] =
{ 0x4010,0x4013,0x4016,0x401C,0x401F,0 }; { 0x4010,0x4013,0x4016,0x401C,0x401F,0 };
CheatCode CheatCodes[MAXCHEATS];
/** Places in BIOS to be patched with ED FE C9 ***************/ /** Places in BIOS to be patched with ED FE C9 ***************/
static const word BIOSPatches[] = static const word BIOSPatches[] =
...@@ -299,6 +303,7 @@ byte RTCIn(byte R); /* Read RTC registers */ ...@@ -299,6 +303,7 @@ byte RTCIn(byte R); /* Read RTC registers */
byte SetScreen(void); /* Change screen mode */ byte SetScreen(void); /* Change screen mode */
word SetIRQ(byte IRQ); /* Set/Reset IRQ */ word SetIRQ(byte IRQ); /* Set/Reset IRQ */
word StateID(void); /* Compute emulation state ID */ word StateID(void); /* Compute emulation state ID */
int ApplyCheats(void); /* Apply RAM-based cheats */
static int hasext(const char *FileName,const char *Ext); static int hasext(const char *FileName,const char *Ext);
static byte *GetMemory(int Size); /* Get memory chunk */ static byte *GetMemory(int Size); /* Get memory chunk */
...@@ -316,6 +321,7 @@ int64_t rftell(RFILE* stream); ...@@ -316,6 +321,7 @@ int64_t rftell(RFILE* stream);
int64_t rfwrite(void const* buffer, int64_t rfwrite(void const* buffer,
size_t elem_size, size_t elem_count, RFILE* stream); size_t elem_size, size_t elem_count, RFILE* stream);
int rfgetc(RFILE* stream); int rfgetc(RFILE* stream);
int rfeof(RFILE* stream);
/** hasext() *************************************************/ /** hasext() *************************************************/
/** Check if file name has given extension. **/ /** Check if file name has given extension. **/
...@@ -438,6 +444,8 @@ int StartMSX(int NewMode,int NewRAMPages,int NewVRAMPages) ...@@ -438,6 +444,8 @@ int StartMSX(int NewMode,int NewRAMPages,int NewVRAMPages)
FMPACKey = 0x0000; FMPACKey = 0x0000;
ExitNow = 0; ExitNow = 0;
NChunks = 0; NChunks = 0;
CheatsON = 0;
CheatCount = 0;
MCFCount = 0; MCFCount = 0;
/* Zero cartridge related data */ /* Zero cartridge related data */
...@@ -2056,7 +2064,7 @@ word LoopZ80(Z80 *R) ...@@ -2056,7 +2064,7 @@ word LoopZ80(Z80 *R)
Sync2413(&OPLL,YM2413_FLUSH); Sync2413(&OPLL,YM2413_FLUSH);
/* Render and play all sound now */ /* Render and play all sound now */
PlayAllSound(J); //PlayAllSound(J); - fmsx-libretro renders audio & video per scanline
} }
/* Keyboard, sound, and other stuff always runs at line 192 */ /* Keyboard, sound, and other stuff always runs at line 192 */
...@@ -2069,6 +2077,8 @@ word LoopZ80(Z80 *R) ...@@ -2069,6 +2077,8 @@ word LoopZ80(Z80 *R)
/* Check sprites and set Collision bit */ /* Check sprites and set Collision bit */
if(!(VDPStatus[0]&0x20)&&CheckSprites()) VDPStatus[0]|=0x20; if(!(VDPStatus[0]&0x20)&&CheckSprites()) VDPStatus[0]|=0x20;
/* Apply RAM-based cheats */
if(CheatsON&&CheatCount) ApplyCheats();
/* Check joystick */ /* Check joystick */
JoyState=Joystick(); JoyState=Joystick();
...@@ -2354,6 +2364,8 @@ int LoadFile(const char *FileName) ...@@ -2354,6 +2364,8 @@ int LoadFile(const char *FileName)
if(hasext(FileName,".FNT")) return(!!LoadFNT(FileName)); if(hasext(FileName,".FNT")) return(!!LoadFNT(FileName));
/* Try loading as palette */ /* Try loading as palette */
if(hasext(FileName,".PAL")) return(!!LoadPAL(FileName)); if(hasext(FileName,".PAL")) return(!!LoadPAL(FileName));
/* Try loading as cheats */
if(hasext(FileName,".CHT")) return(!!LoadCHT(FileName));
if(hasext(FileName,".MCF")) return(!!LoadMCF(FileName)); if(hasext(FileName,".MCF")) return(!!LoadMCF(FileName));
/* Unknown file type */ /* Unknown file type */
...@@ -2398,6 +2410,169 @@ int ApplyMCFCheat(int N) ...@@ -2398,6 +2410,169 @@ int ApplyMCFCheat(int N)
return(CheatCount); return(CheatCount);
} }
/** AddCheat() ***********************************************/
/** Add a new cheat. Returns 0 on failure or the number of **/
/** cheats on success. **/
/*************************************************************/
int AddCheat(const char *Cheat)
{
static const char *Hex = "0123456789ABCDEF";
unsigned int A,D;
char *P;
int J,N;
/* Table full: no more cheats */
if(CheatCount>=MAXCHEATS) return(0);
/* Check cheat length and decode */
N=strlen(Cheat);
if(((N==13)||(N==11))&&(Cheat[8]=='-'))
{
for(J=0,A=0;J<8;J++)
{
P=strchr(Hex,toupper(Cheat[J]));
if(!P) return(0); else A=(A<<4)|(P-Hex);
}
for(J=9,D=0;J<N;J++)
{
P=strchr(Hex,toupper(Cheat[J]));
if(!P) return(0); else D=(D<<4)|(P-Hex);
}
}
else if(((N==9)||(N==7))&&(Cheat[4]=='-'))
{
for(J=0,A=0x0100;J<4;J++)
{
P=strchr(Hex,toupper(Cheat[J]));
if(!P) return(0); else A=(A<<4)|(P-Hex);
}
for(J=5,D=0;J<N;J++)
{
P=strchr(Hex,toupper(Cheat[J]));
if(!P) return(0); else D=(D<<4)|(P-Hex);
}
}
else
{
/* Cannot parse this cheat */
return(0);
}
/* Add cheat */
strcpy((char *)CheatCodes[CheatCount].Text,Cheat);
if(N==13)
{
CheatCodes[CheatCount].Addr = A;
CheatCodes[CheatCount].Data = D&0xFFFF;
CheatCodes[CheatCount].Size = 2;
}
else
{
CheatCodes[CheatCount].Addr = A;
CheatCodes[CheatCount].Data = D&0xFF;
CheatCodes[CheatCount].Size = 1;
}
/* Successfully added a cheat! */
return(++CheatCount);
}
/** ResetCheats() ********************************************/
/** Remove all cheats. **/
/*************************************************************/
void ResetCheats(void) { Cheats(CHTS_OFF);CheatCount=0; }
/** ApplyCheats() ********************************************/
/** Apply RAM-based cheats. Returns the number of applied **/
/** cheats. **/
/*************************************************************/
int ApplyCheats(void)
{
int J,I;
/* For all current cheats that look like 01AAAAAA-DD/DDDD... */
for(J=I=0;J<CheatCount;++J)
if((CheatCodes[J].Addr>>24)==0x01)
{
WrZ80(CheatCodes[J].Addr&0xFFFF,CheatCodes[J].Data&0xFF);
if(CheatCodes[J].Size>1)
WrZ80((CheatCodes[J].Addr+1)&0xFFFF,CheatCodes[J].Data>>8);
++I;
}
/* Return number of applied cheats */
return(I);
}
/** Cheats() *************************************************/
/** Toggle cheats on (1), off (0), inverse state (2) or **/
/** query (3). **/
/*************************************************************/
int Cheats(int Switch)
{
byte *P,*Base;
int J,Size;
switch(Switch)
{
case CHTS_ON:
case CHTS_OFF: if(Switch==CheatsON) return(CheatsON);
case CHTS_TOGGLE: Switch=!CheatsON;break;
default: return(CheatsON);
}
/* Find valid cartridge */
for(J=1;(J<=2)&&!ROMData[J];++J);
/* Must have ROM */
if(J>2) return(Switch=CHTS_OFF);
/* Compute ROM address and size */
Base = ROMData[J];
Size = ((int)ROMMask[J]+1)<<14;
/* If toggling cheats... */
if(Switch!=CheatsON)
{
/* If enabling cheats... */
if(Switch)
{
/* Patch ROM with the cheat values */
for(J=0;J<CheatCount;++J)
if(!(CheatCodes[J].Addr>>24)&&(CheatCodes[J].Addr+CheatCodes[J].Size<=Size))
{
P = Base + CheatCodes[J].Addr;
CheatCodes[J].Orig = P[0];
P[0] = CheatCodes[J].Data;
if(CheatCodes[J].Size>1)
{
CheatCodes[J].Orig |= (int)P[1]<<8;
P[1] = CheatCodes[J].Data>>8;
}
}
}
else
{
/* Restore original ROM values */
for(J=0;J<CheatCount;++J)
if(!(CheatCodes[J].Addr>>24)&&(CheatCodes[J].Addr+CheatCodes[J].Size<=Size))
{
P = Base + CheatCodes[J].Addr;
P[0] = CheatCodes[J].Orig;
if(CheatCodes[J].Size>1)
P[1] = CheatCodes[J].Orig>>8;
}
}
/* Done toggling cheats */
CheatsON = Switch;
}
/* Done */
return(CheatsON);
}
/** GuessROM() ***********************************************/ /** GuessROM() ***********************************************/
/** Guess MegaROM mapper of a ROM. **/ /** Guess MegaROM mapper of a ROM. **/
/*************************************************************/ /*************************************************************/
...@@ -2882,6 +3057,43 @@ int LoadCart(const char *FileName,int Slot,int Type) ...@@ -2882,6 +3057,43 @@ int LoadCart(const char *FileName,int Slot,int Type)
return(Pages); return(Pages);
} }
/** LoadCHT() ************************************************/
/** Load cheats from .CHT file. Cheat format is either **/
/** 00XXXXXX-XX (one byte) or 00XXXXXX-XXXX (two bytes) for **/
/** ROM-based cheats and XXXX-XX or XXXX-XXXX for RAM-based **/
/** cheats. Returns the number of cheats on success, 0 on **/
/** failure. **/
/*************************************************************/
int LoadCHT(const char *Name)
{
char Buf[256],S[16];
int Status;
RFILE *F;
/* Open .CHT text file with cheats */
F = rfopen(Name,"rb");
if(!F) return(0);
/* Switch cheats off for now and remove all present cheats */
Status = Cheats(CHTS_QUERY);
Cheats(CHTS_OFF);
ResetCheats();
/* Try adding cheats loaded from file */
while(!rfeof(F))
if(rfgets(Buf,sizeof(Buf),F) && (sscanf(Buf,"%13s",S)==1))
AddCheat(S);
/* Done with the file */
rfclose(F);
/* Turn cheats back on, if they were on */
Cheats(Status);
/* Done */
return(CheatCount);
}
/** LoadPAL() ************************************************/ /** LoadPAL() ************************************************/
/** Load new palette from .PAL file. Returns number of **/ /** Load new palette from .PAL file. Returns number of **/
/** loaded colors on success, 0 on failure. **/ /** loaded colors on success, 0 on failure. **/
......
...@@ -104,6 +104,7 @@ extern "C" { ...@@ -104,6 +104,7 @@ extern "C" {
#define MAXCARTS 2 /* Number of user cartridges */ #define MAXCARTS 2 /* Number of user cartridges */
#define MAXMAPPERS 8 /* Total defined MegaROM mappers */ #define MAXMAPPERS 8 /* Total defined MegaROM mappers */
#define MAXCHUNKS 256 /* Max number of memory blocks */ #define MAXCHUNKS 256 /* Max number of memory blocks */
#define MAXCHEATS 256 /* Max number of cheats */
#define MAXCHANNELS (AY8910_CHANNELS+YM2413_CHANNELS) #define MAXCHANNELS (AY8910_CHANNELS+YM2413_CHANNELS)
/* Number of sound channels used by the emulation */ /* Number of sound channels used by the emulation */
...@@ -201,6 +202,13 @@ extern volatile byte KeyState[16]; ...@@ -201,6 +202,13 @@ extern volatile byte KeyState[16];
#define KBD_NUMPAD9 0x81 #define KBD_NUMPAD9 0x81
/*************************************************************/ /*************************************************************/
/** Cheats() arguments ***************************************/
#define CHTS_OFF 0 /* Turn all cheats off */
#define CHTS_ON 1 /* Turn all cheats on */
#define CHTS_TOGGLE 2 /* Toggle cheats state */
#define CHTS_QUERY 3 /* Query cheats state */
/*************************************************************/
/** Following macros can be used in screen drivers ***********/ /** Following macros can be used in screen drivers ***********/
#define BigSprites (VDP[1]&0x01) /* Zoomed sprites */ #define BigSprites (VDP[1]&0x01) /* Zoomed sprites */
#define Sprites16x16 (VDP[1]&0x02) /* 16x16/8x8 sprites */ #define Sprites16x16 (VDP[1]&0x02) /* 16x16/8x8 sprites */
...@@ -301,6 +309,21 @@ int LoadFile(const char *FileName); ...@@ -301,6 +309,21 @@ int LoadFile(const char *FileName);
/*************************************************************/ /*************************************************************/
int LoadCart(const char *FileName,int Slot,int Type); int LoadCart(const char *FileName,int Slot,int Type);
/** LoadMCF() ************************************************/
/** Load cheats from .MCF file. Returns number of loaded **/
/** cheat entries or 0 on failure. **/
/*************************************************************/
int LoadMCF(const char *Name);
/** LoadCHT() ************************************************/
/** Load cheats from .CHT file. Cheat format is either **/
/** 00XXXXXX-XX (one byte) or 00XXXXXX-XXXX (two bytes) for **/
/** ROM-based cheats and XXXX-XX or XXXX-XXXX for RAM-based **/
/** cheats. Returns the number of cheats on success, 0 on **/
/** failure. **/
/*************************************************************/
int LoadCHT(const char *Name);
/** LoadPAL() ************************************************/ /** LoadPAL() ************************************************/
/** Load new palette from .PAL file. Returns number of **/ /** Load new palette from .PAL file. Returns number of **/
/** loaded colors on success, 0 on failure. **/ /** loaded colors on success, 0 on failure. **/
...@@ -357,6 +380,27 @@ int SetScreenDepth(int Depth); ...@@ -357,6 +380,27 @@ int SetScreenDepth(int Depth);
/*************************************************************/ /*************************************************************/
int ApplyMCFCheat(int N); int ApplyMCFCheat(int N);
/** AddCheat() ***********************************************/
/** Add a new cheat. Returns 0 on failure or the number of **/
/** cheats on success. **/
/*************************************************************/
int AddCheat(const char *Cheat);
/** DelCheat() ***********************************************/
/** Delete a cheat. Returns 0 on failure, 1 on success. **/
/*************************************************************/
int DelCheat(const char *Cheat);
/** ResetCheats() ********************************************/
/** Remove all cheats. **/
/*************************************************************/
void ResetCheats(void);
/** Cheats() *************************************************/
/** Toggle cheats on (1), off (0), inverse state (2) or **/
/** query (3). **/
/*************************************************************/
int Cheats(int Switch);
/** SaveState() **********************************************/ /** SaveState() **********************************************/
/** Save emulation state to a memory buffer. Returns size **/ /** Save emulation state to a memory buffer. Returns size **/
/** on success, 0 on failure. **/ /** on success, 0 on failure. **/
...@@ -369,12 +413,6 @@ unsigned int SaveState(unsigned char *Buf,unsigned int MaxSize); ...@@ -369,12 +413,6 @@ unsigned int SaveState(unsigned char *Buf,unsigned int MaxSize);
/*************************************************************/ /*************************************************************/
unsigned int LoadState(unsigned char *Buf,unsigned int MaxSize); unsigned int LoadState(unsigned char *Buf,unsigned int MaxSize);
/** LoadMCF() ************************************************/
/** Load cheats from .MCF file. Returns number of loaded **/
/** cheat entries or 0 on failure. **/
/*************************************************************/
int LoadMCF(const char *Name);
/** InitMachine() ********************************************/ /** InitMachine() ********************************************/
/** Allocate resources needed by the machine-dependent code.**/ /** Allocate resources needed by the machine-dependent code.**/
/************************************ TO BE WRITTEN BY USER **/ /************************************ TO BE WRITTEN BY USER **/
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment