mirror of
https://github.com/dborth/fceugx.git
synced 2024-11-01 06:55:05 +01:00
sync to latest FCEUX SVN
This commit is contained in:
parent
9dadc743d1
commit
647bf81a74
@ -10,6 +10,7 @@
|
|||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
|
#include <gctypes.h>
|
||||||
|
|
||||||
#include "fceugx.h"
|
#include "fceugx.h"
|
||||||
#include "fceusupport.h"
|
#include "fceusupport.h"
|
||||||
|
@ -310,7 +310,7 @@ void USBGeckoOutput()
|
|||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
//USBGeckoOutput(); // uncomment to enable USB gecko output
|
USBGeckoOutput(); // uncomment to enable USB gecko output
|
||||||
__exception_setreload(8);
|
__exception_setreload(8);
|
||||||
|
|
||||||
#ifdef HW_DOL
|
#ifdef HW_DOL
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
|
#include <gctypes.h>
|
||||||
|
|
||||||
#include "fceultra/file.h"
|
#include "fceultra/file.h"
|
||||||
|
|
||||||
@ -64,7 +65,7 @@ int GCMemROM(int size)
|
|||||||
fceufp->size = size;
|
fceufp->size = size;
|
||||||
fceufp->filename = romFilename;
|
fceufp->filename = romFilename;
|
||||||
fceufp->mode = FCEUFILE::READ; // read only
|
fceufp->mode = FCEUFILE::READ; // read only
|
||||||
memorystream * fceumem = new memorystream((char *) nesrom, size);
|
EMUFILE_MEMFILE *fceumem = new EMUFILE_MEMFILE(nesrom, size);
|
||||||
fceufp->stream = fceumem;
|
fceufp->stream = fceumem;
|
||||||
|
|
||||||
romLoaded = iNESLoad(romFilename, fceufp, 1);
|
romLoaded = iNESLoad(romFilename, fceufp, 1);
|
||||||
|
@ -139,7 +139,7 @@ static uint64 lreset;
|
|||||||
static DECLFW(MMC1_write)
|
static DECLFW(MMC1_write)
|
||||||
{
|
{
|
||||||
int n=(A>>13)-4;
|
int n=(A>>13)-4;
|
||||||
//FCEU_DispMessage("%016x",timestampbase+timestamp);
|
//FCEU_DispMessage("%016x",0,timestampbase+timestamp);
|
||||||
// FCEU_printf("$%04x:$%02x, $%04x\n",A,V,X.PC);
|
// FCEU_printf("$%04x:$%02x, $%04x\n",A,V,X.PC);
|
||||||
//DumpMem("out",0xe000,0xffff);
|
//DumpMem("out",0xe000,0xffff);
|
||||||
|
|
||||||
|
@ -467,4 +467,5 @@ void Mapper210_Init(CartInfo *info)
|
|||||||
GameStateRestore=Mapper210_StateRestore;
|
GameStateRestore=Mapper210_StateRestore;
|
||||||
info->Power=N106_Power;
|
info->Power=N106_Power;
|
||||||
AddExState(WRAM, 8192, 0, "WRAM");
|
AddExState(WRAM, 8192, 0, "WRAM");
|
||||||
|
AddExState(N106_StateRegs, ~0, 0, 0);
|
||||||
}
|
}
|
||||||
|
@ -132,7 +132,7 @@ void RebuildSubCheats(void)
|
|||||||
if(GetReadHandler(c->addr)==SubCheatsRead)
|
if(GetReadHandler(c->addr)==SubCheatsRead)
|
||||||
{
|
{
|
||||||
/* Prevent a catastrophe by this check. */
|
/* Prevent a catastrophe by this check. */
|
||||||
//FCEU_DispMessage("oops");
|
//FCEU_DispMessage("oops",0);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -148,7 +148,7 @@ void RebuildSubCheats(void)
|
|||||||
}
|
}
|
||||||
FrozenAddressCount = numsubcheats; //Update the frozen address list
|
FrozenAddressCount = numsubcheats; //Update the frozen address list
|
||||||
UpdateFrozenList();
|
UpdateFrozenList();
|
||||||
//FCEUI_DispMessage("Active Cheats: %d", FrozenAddresses.size()/*FrozenAddressCount*/); //Debug
|
//FCEUI_DispMessage("Active Cheats: %d",0, FrozenAddresses.size()/*FrozenAddressCount*/); //Debug
|
||||||
}
|
}
|
||||||
|
|
||||||
void FCEU_PowerCheats()
|
void FCEU_PowerCheats()
|
||||||
@ -217,8 +217,8 @@ void FCEU_LoadGameCheats(FILE *override)
|
|||||||
if(!fp) return;
|
if(!fp) return;
|
||||||
}
|
}
|
||||||
|
|
||||||
FCEU_DispMessage("Cheats file loaded."); //Tells user a cheats file was loaded.
|
FCEU_DispMessage("Cheats file loaded.",0); //Tells user a cheats file was loaded.
|
||||||
FCEU_printf("Cheats file loaded.\n"); //Sends message to message log.
|
FCEU_printf("Cheats file loaded.\n",0); //Sends message to message log.
|
||||||
while(fgets(linebuf,2048,fp)>0)
|
while(fgets(linebuf,2048,fp)>0)
|
||||||
{
|
{
|
||||||
char *tbuf=linebuf;
|
char *tbuf=linebuf;
|
||||||
@ -951,5 +951,5 @@ void UpdateFrozenList(void)
|
|||||||
FrozenAddresses.push_back(SubCheats[x].addr);
|
FrozenAddresses.push_back(SubCheats[x].addr);
|
||||||
//FCEU_printf("Address %d: %d \n",x,FrozenAddresses[x]); //Debug
|
//FCEU_printf("Address %d: %d \n",x,FrozenAddresses[x]); //Debug
|
||||||
}
|
}
|
||||||
//FCEUI_DispMessage("FrozenCount: %d",FrozenAddressCount);//Debug
|
//FCEUI_DispMessage("FrozenCount: %d",0,FrozenAddressCount);//Debug
|
||||||
}
|
}
|
@ -36,6 +36,7 @@
|
|||||||
* Address -> '$' [1-9A-F]* | '$' '[' Connect ']'
|
* Address -> '$' [1-9A-F]* | '$' '[' Connect ']'
|
||||||
* Register -> 'A' | 'X' | 'Y' | 'R'
|
* Register -> 'A' | 'X' | 'Y' | 'R'
|
||||||
* Flag -> 'N' | 'C' | 'Z' | 'I' | 'B' | 'V'
|
* Flag -> 'N' | 'C' | 'Z' | 'I' | 'B' | 'V'
|
||||||
|
* PC Bank -> 'K'
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@ -131,6 +132,12 @@ int isRegister(char c)
|
|||||||
return c == 'A' || c == 'X' || c == 'Y' || c == 'P';
|
return c == 'A' || c == 'X' || c == 'Y' || c == 'P';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Determines if a character is for bank
|
||||||
|
int isBank(char c)
|
||||||
|
{
|
||||||
|
return c == 'K';
|
||||||
|
}
|
||||||
|
|
||||||
// Reads a hexadecimal number from str
|
// Reads a hexadecimal number from str
|
||||||
int getNumber(unsigned int* number, const char** str)
|
int getNumber(unsigned int* number, const char** str)
|
||||||
{
|
{
|
||||||
@ -217,6 +224,23 @@ Condition* Primitive(const char** str, Condition* c)
|
|||||||
|
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
else if (isBank(next)) /* Registers */
|
||||||
|
{
|
||||||
|
if (c->type1 == TYPE_NO)
|
||||||
|
{
|
||||||
|
c->type1 = TYPE_BANK;
|
||||||
|
c->value1 = next;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
c->type2 = TYPE_BANK;
|
||||||
|
c->value2 = next;
|
||||||
|
}
|
||||||
|
|
||||||
|
scan(str);
|
||||||
|
|
||||||
|
return c;
|
||||||
|
}
|
||||||
else if (next == '#') /* Numbers */
|
else if (next == '#') /* Numbers */
|
||||||
{
|
{
|
||||||
unsigned int number = 0;
|
unsigned int number = 0;
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
#define TYPE_FLAG 2
|
#define TYPE_FLAG 2
|
||||||
#define TYPE_NUM 3
|
#define TYPE_NUM 3
|
||||||
#define TYPE_ADDR 4
|
#define TYPE_ADDR 4
|
||||||
|
#define TYPE_BANK 5
|
||||||
|
|
||||||
#define OP_NO 0
|
#define OP_NO 0
|
||||||
#define OP_EQ 1
|
#define OP_EQ 1
|
||||||
|
@ -195,13 +195,36 @@ unsigned int NewBreak(const char* name, int start, int end, unsigned int type, c
|
|||||||
}
|
}
|
||||||
|
|
||||||
int GetPRGAddress(int A){
|
int GetPRGAddress(int A){
|
||||||
unsigned int result;
|
int result;
|
||||||
if((A < 0x8000) || (A > 0xFFFF))return -1;
|
if((A < 0x8000) || (A > 0xFFFF))return -1;
|
||||||
result = &Page[A>>11][A]-PRGptr[0];
|
result = &Page[A>>11][A]-PRGptr[0];
|
||||||
if((result > PRGsize[0]) || (result < 0))return -1;
|
if((result > (int)PRGsize[0]) || (result < 0))return -1;
|
||||||
else return result;
|
else return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the bank for a given offset.
|
||||||
|
* Technically speaking this function does not calculate the actual bank
|
||||||
|
* where the offset resides but the 0x4000 bytes large chunk of the ROM of the offset.
|
||||||
|
*
|
||||||
|
* @param offs The offset
|
||||||
|
* @return The bank of that offset or -1 if the offset is not part of the ROM.
|
||||||
|
**/
|
||||||
|
int getBank(int offs)
|
||||||
|
{
|
||||||
|
//NSF data is easy to overflow the return on.
|
||||||
|
//Anything over FFFFF will kill it.
|
||||||
|
|
||||||
|
|
||||||
|
//GetNesFileAddress doesn't work well with Unif files
|
||||||
|
int addr = GetNesFileAddress(offs)-16;
|
||||||
|
|
||||||
|
if (GameInfo && GameInfo->type==GIT_NSF) {
|
||||||
|
return addr != -1 ? addr / 0x1000 : -1;
|
||||||
|
}
|
||||||
|
return addr != -1 ? addr / 0x4000 : -1;
|
||||||
|
}
|
||||||
|
|
||||||
int GetNesFileAddress(int A){
|
int GetNesFileAddress(int A){
|
||||||
unsigned int result;
|
unsigned int result;
|
||||||
if((A < 0x8000) || (A > 0xFFFF))return -1;
|
if((A < 0x8000) || (A > 0xFFFF))return -1;
|
||||||
@ -272,15 +295,16 @@ int evaluate(Condition* c)
|
|||||||
{
|
{
|
||||||
switch(c->type1)
|
switch(c->type1)
|
||||||
{
|
{
|
||||||
case TYPE_ADDR:
|
case TYPE_ADDR: // This is intended to not break, and use the TYPE_NUM code
|
||||||
case TYPE_NUM: value1 = c->value1; break;
|
case TYPE_NUM: value1 = c->value1; break;
|
||||||
default: value1 = getValue(c->value1);
|
default: value1 = getValue(c->value1); break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (c->type1 == TYPE_ADDR)
|
switch(c->type1)
|
||||||
{
|
{
|
||||||
value1 = GetMem(value1);
|
case TYPE_ADDR: value1 = GetMem(value1); break;
|
||||||
|
case TYPE_BANK: value1 = getBank(_PC); break;
|
||||||
}
|
}
|
||||||
|
|
||||||
f = value1;
|
f = value1;
|
||||||
@ -295,15 +319,16 @@ int evaluate(Condition* c)
|
|||||||
{
|
{
|
||||||
switch(c->type2)
|
switch(c->type2)
|
||||||
{
|
{
|
||||||
case TYPE_ADDR:
|
case TYPE_ADDR: // This is intended to not break, and use the TYPE_NUM code
|
||||||
case TYPE_NUM: value2 = c->value2; break;
|
case TYPE_NUM: value2 = c->value2; break;
|
||||||
default: value2 = getValue(c->type2);
|
default: value2 = getValue(c->type2); break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (c->type2 == TYPE_ADDR)
|
switch(c->type2)
|
||||||
{
|
{
|
||||||
value2 = GetMem(value2);
|
case TYPE_ADDR: value2 = GetMem(value2); break;
|
||||||
|
case TYPE_BANK: value2 = getBank(_PC); break;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (c->op)
|
switch (c->op)
|
||||||
@ -335,93 +360,94 @@ int condition(watchpointinfo* wp)
|
|||||||
//---------------------
|
//---------------------
|
||||||
|
|
||||||
volatile int codecount, datacount, undefinedcount;
|
volatile int codecount, datacount, undefinedcount;
|
||||||
//HWND hCDLogger=0;
|
|
||||||
unsigned char *cdloggerdata;
|
unsigned char *cdloggerdata;
|
||||||
char *cdlogfilename;
|
char *cdlogfilename;
|
||||||
//char loadedcdfile[MAX_PATH];
|
|
||||||
static int indirectnext;
|
static int indirectnext;
|
||||||
|
|
||||||
int debug_loggingCD;
|
int debug_loggingCD;
|
||||||
|
|
||||||
//called by the cpu to perform logging if CDLogging is enabled
|
//called by the cpu to perform logging if CDLogging is enabled
|
||||||
void LogCDVectors(int which){
|
void LogCDVectors(int which){
|
||||||
int i = 0xFFFA+(which*2);
|
|
||||||
int j;
|
int j;
|
||||||
j = GetPRGAddress(i);
|
j = GetPRGAddress(which);
|
||||||
if(j == -1){
|
if(j == -1){
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(cdloggerdata[j] == 0){
|
if(!(cdloggerdata[j] & 2)){
|
||||||
cdloggerdata[j] |= 0x0E; // we're in the last bank and recording it as data so 0x1110 or 0xE should be what we need
|
cdloggerdata[j] |= 0x0E; // we're in the last bank and recording it as data so 0x1110 or 0xE should be what we need
|
||||||
datacount++;
|
datacount++;
|
||||||
undefinedcount--;
|
if(!(cdloggerdata[j] & 1))undefinedcount--;
|
||||||
}
|
}
|
||||||
j++;
|
j++;
|
||||||
|
|
||||||
if(cdloggerdata[j] == 0){
|
if(!(cdloggerdata[j] & 2)){
|
||||||
cdloggerdata[j] |= 0x0E; // we're in the last bank and recording it as data so 0x1110 or 0xE should be what we need
|
cdloggerdata[j] |= 0x0E;
|
||||||
datacount++;
|
datacount++;
|
||||||
undefinedcount--;
|
if(!(cdloggerdata[j] & 1))undefinedcount--;
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void LogCDData(){
|
void LogCDData(){
|
||||||
int i, j;
|
int i, j;
|
||||||
uint16 A = 0;
|
uint16 A = 0;
|
||||||
uint8 opcode[3] = {0};
|
uint8 opcode[3] = {0}, memop = 0;
|
||||||
|
|
||||||
j = GetPRGAddress(_PC);
|
j = GetPRGAddress(_PC);
|
||||||
|
|
||||||
opcode[0] = GetMem(_PC);
|
|
||||||
for (i = 1; i < opsize[opcode[0]]; i++) opcode[i] = GetMem(_PC+i);
|
|
||||||
|
|
||||||
if(j != -1) {
|
if(j != -1) {
|
||||||
|
opcode[0] = GetMem(_PC);
|
||||||
|
switch (opsize[opcode[0]]) {
|
||||||
|
case 2:
|
||||||
|
opcode[1] = GetMem(_PC + 1);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
opcode[1] = GetMem(_PC + 1);
|
||||||
|
opcode[2] = GetMem(_PC + 2);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < opsize[opcode[0]]; i++){
|
for (i = 0; i < opsize[opcode[0]]; i++){
|
||||||
if(cdloggerdata[j+i] & 1)continue; //this has been logged so skip
|
if(cdloggerdata[j+i] & 1)continue; //this has been logged so skip
|
||||||
cdloggerdata[j+i] |= 1;
|
cdloggerdata[j+i] |= 1;
|
||||||
cdloggerdata[j+i] |=((_PC+i)>>11)&12;
|
cdloggerdata[j+i] |=((_PC+i)>>11)&0x0c;
|
||||||
if(indirectnext)cdloggerdata[j+i] |= 0x10;
|
if(indirectnext)cdloggerdata[j+i] |= 0x10;
|
||||||
codecount++;
|
codecount++;
|
||||||
if(!(cdloggerdata[j+i] & 0x42))undefinedcount--;
|
if(!(cdloggerdata[j+i] & 2))undefinedcount--;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
indirectnext = 0;
|
|
||||||
//log instruction jumped to in an indirect jump
|
//log instruction jumped to in an indirect jump
|
||||||
if(opcode[0] == 0x6c){
|
if(opcode[0] == 0x6c) indirectnext = 1; else indirectnext = 0;
|
||||||
indirectnext = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (optype[opcode[0]]) {
|
switch (optype[opcode[0]]) {
|
||||||
case 0: break;
|
case 0: break;
|
||||||
case 1:
|
case 1:
|
||||||
A = (opcode[1]+_X) & 0xFF;
|
A = (opcode[1]+_X) & 0xFF;
|
||||||
A = GetMem(A) | (GetMem(A+1))<<8;
|
A = GetMem(A) | (GetMem(A+1)<<8);
|
||||||
|
memop = 0x20;
|
||||||
break;
|
break;
|
||||||
case 2: A = opcode[1]; break;
|
case 2: A = opcode[1]; break;
|
||||||
case 3: A = opcode[1] | opcode[2]<<8; break;
|
case 3: A = opcode[1] | opcode[2]<<8; break;
|
||||||
case 4: A = (GetMem(opcode[1]) | (GetMem(opcode[1]+1))<<8)+_Y; break;
|
case 4:
|
||||||
|
A = (GetMem(opcode[1]) | (GetMem(opcode[1]+1)<<8))+_Y;
|
||||||
|
memop = 0x20;
|
||||||
|
break;
|
||||||
case 5: A = opcode[1]+_X; break;
|
case 5: A = opcode[1]+_X; break;
|
||||||
case 6: A = (opcode[1] | opcode[2]<<8)+_Y; break;
|
case 6: A = (opcode[1] | (opcode[2]<<8))+_Y; break;
|
||||||
case 7: A = (opcode[1] | opcode[2]<<8)+_X; break;
|
case 7: A = (opcode[1] | (opcode[2]<<8))+_X; break;
|
||||||
case 8: A = opcode[1]+_Y; break;
|
case 8: A = opcode[1]+_Y; break;
|
||||||
}
|
}
|
||||||
|
|
||||||
//if(opbrktype[opcode[0]] != WP_R)return; //we only want reads
|
if((j = GetPRGAddress(A)) != -1) {
|
||||||
|
if(!(cdloggerdata[j] & 2)) {
|
||||||
if((j = GetPRGAddress(A)) == -1)return;
|
|
||||||
//if(j == 0)BreakHit();
|
|
||||||
|
|
||||||
|
|
||||||
if(cdloggerdata[j] & 2)return;
|
|
||||||
cdloggerdata[j] |= 2;
|
cdloggerdata[j] |= 2;
|
||||||
cdloggerdata[j] |=((A/*+i*/)>>11)&12;
|
cdloggerdata[j] |=(A>>11)&0x0c;
|
||||||
if((optype[opcode[0]] == 1) || (optype[opcode[0]] == 4))cdloggerdata[j] |= 0x20;
|
cdloggerdata[j] |= memop;
|
||||||
datacount++;
|
datacount++;
|
||||||
if(!(cdloggerdata[j+i] & 1))undefinedcount--;
|
if(!(cdloggerdata[j] & 1))undefinedcount--;
|
||||||
return;
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------debugger stuff
|
//-----------debugger stuff
|
||||||
@ -444,7 +470,7 @@ void BreakHit(bool force = false) {
|
|||||||
//check to see whether we fall in any forbid zone
|
//check to see whether we fall in any forbid zone
|
||||||
for (int i = 0; i < numWPs; i++) {
|
for (int i = 0; i < numWPs; i++) {
|
||||||
watchpointinfo& wp = watchpoint[i];
|
watchpointinfo& wp = watchpoint[i];
|
||||||
if(!(wp.flags & WP_F))
|
if(!(wp.flags & WP_F) || !(wp.flags & WP_E))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (condition(&wp))
|
if (condition(&wp))
|
||||||
@ -467,47 +493,17 @@ void BreakHit(bool force = false) {
|
|||||||
|
|
||||||
FCEUD_DebugBreakpoint();
|
FCEUD_DebugBreakpoint();
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
//very ineffecient, but this shouldn't get executed THAT much
|
uint8 StackAddrBackup = X.S;
|
||||||
if(!(cdloggerdata[GetPRGAddress(0xFFFA)] & 2)){
|
uint16 StackNextIgnorePC = 0xFFFF;
|
||||||
cdloggerdata[GetPRGAddress(0xFFFA)]|=2;
|
|
||||||
codecount++;
|
|
||||||
undefinedcount--;
|
|
||||||
}
|
|
||||||
if(!(cdloggerdata[GetPRGAddress(0xFFFB)] & 2)){
|
|
||||||
cdloggerdata[GetPRGAddress(0xFFFB)]|=2;
|
|
||||||
codecount++;
|
|
||||||
undefinedcount--;
|
|
||||||
}
|
|
||||||
if(!(cdloggerdata[GetPRGAddress(0xFFFC)] & 2)){
|
|
||||||
cdloggerdata[GetPRGAddress(0xFFFC)]|=2;
|
|
||||||
codecount++;
|
|
||||||
undefinedcount--;
|
|
||||||
}
|
|
||||||
if(!(cdloggerdata[GetPRGAddress(0xFFFD)] & 2)){
|
|
||||||
cdloggerdata[GetPRGAddress(0xFFFD)]|=2;
|
|
||||||
codecount++;
|
|
||||||
undefinedcount--;
|
|
||||||
}
|
|
||||||
if(!(cdloggerdata[GetPRGAddress(0xFFFE)] & 2)){
|
|
||||||
cdloggerdata[GetPRGAddress(0xFFFE)]|=2;
|
|
||||||
codecount++;
|
|
||||||
undefinedcount--;
|
|
||||||
}
|
|
||||||
if(!(cdloggerdata[GetPRGAddress(0xFFFF)] & 2)){
|
|
||||||
cdloggerdata[GetPRGAddress(0xFFFF)]|=2;
|
|
||||||
codecount++;
|
|
||||||
undefinedcount--;
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
///fires a breakpoint
|
///fires a breakpoint
|
||||||
void breakpoint() {
|
void breakpoint() {
|
||||||
int i;
|
int i,j;
|
||||||
uint16 A=0;
|
uint16 A=0;
|
||||||
uint8 brk_type,opcode[3] = {0};
|
uint8 brk_type,opcode[3] = {0};
|
||||||
|
uint8 stackop=0;
|
||||||
|
uint8 stackopstartaddr,stackopendaddr;
|
||||||
|
|
||||||
//inspect the current opcode
|
//inspect the current opcode
|
||||||
opcode[0] = GetMem(_PC);
|
opcode[0] = GetMem(_PC);
|
||||||
@ -572,6 +568,21 @@ void breakpoint() {
|
|||||||
case 8: A = opcode[1]+_Y; break;
|
case 8: A = opcode[1]+_Y; break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch (opcode[0]) {
|
||||||
|
//Push Ops
|
||||||
|
case 0x08: //Fall to next
|
||||||
|
case 0x48: stackopstartaddr=stackopendaddr=X.S-1; stackop=WP_W; StackAddrBackup = X.S; StackNextIgnorePC=_PC+1; break;
|
||||||
|
//Pull Ops
|
||||||
|
case 0x28: //Fall to next
|
||||||
|
case 0x68: stackopstartaddr=stackopendaddr=X.S+1; stackop=WP_R; StackAddrBackup = X.S; StackNextIgnorePC=_PC+1; break;
|
||||||
|
//JSR (Includes return address - 1)
|
||||||
|
case 0x20: stackopstartaddr=stackopendaddr=X.S-1; stackop=WP_W; StackAddrBackup = X.S; StackNextIgnorePC=(opcode[1]|opcode[2]<<8); break;
|
||||||
|
//RTI (Includes processor status, and exact return address)
|
||||||
|
case 0x40: stackopstartaddr=X.S+1; stackopendaddr=X.S+3; stackop=WP_R; StackAddrBackup = X.S; StackNextIgnorePC=(GetMem(X.S+2|0x0100)|GetMem(X.S+3|0x0100)<<8); break;
|
||||||
|
//RTS (Includes return address - 1)
|
||||||
|
case 0x60: stackopstartaddr=X.S+1; stackopendaddr=X.S+2; stackop=WP_R; StackAddrBackup = X.S; StackNextIgnorePC=(GetMem(stackopstartaddr|0x0100)|GetMem(stackopendaddr|0x0100)<<8)+1; break;
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < numWPs; i++) {
|
for (i = 0; i < numWPs; i++) {
|
||||||
// ################################## Start of SP CODE ###########################
|
// ################################## Start of SP CODE ###########################
|
||||||
if (condition(&watchpoint[i]))
|
if (condition(&watchpoint[i]))
|
||||||
@ -597,17 +608,67 @@ void breakpoint() {
|
|||||||
else { //CPU mem breaks
|
else { //CPU mem breaks
|
||||||
if ((watchpoint[i].flags & WP_E) && (watchpoint[i].flags & brk_type)) {
|
if ((watchpoint[i].flags & WP_E) && (watchpoint[i].flags & brk_type)) {
|
||||||
if (watchpoint[i].endaddress) {
|
if (watchpoint[i].endaddress) {
|
||||||
if (((!(watchpoint[i].flags & WP_X)) && (watchpoint[i].address <= A) && (watchpoint[i].endaddress >= A)) ||
|
if (((watchpoint[i].flags & (WP_R | WP_W)) && (watchpoint[i].address <= A) && (watchpoint[i].endaddress >= A)) ||
|
||||||
((watchpoint[i].flags & WP_X) && (watchpoint[i].address <= _PC) && (watchpoint[i].endaddress >= _PC))) BreakHit();
|
((watchpoint[i].flags & WP_X) && (watchpoint[i].address <= _PC) && (watchpoint[i].endaddress >= _PC))) BreakHit();
|
||||||
}
|
}
|
||||||
else if (((!(watchpoint[i].flags & WP_X)) && (watchpoint[i].address == A)) ||
|
else if (((watchpoint[i].flags & (WP_R | WP_W)) && (watchpoint[i].address == A)) ||
|
||||||
((watchpoint[i].flags & WP_X) && (watchpoint[i].address == _PC))) BreakHit();
|
((watchpoint[i].flags & WP_X) && (watchpoint[i].address == _PC))) BreakHit();
|
||||||
}
|
}
|
||||||
|
else if (watchpoint[i].flags & WP_E) {
|
||||||
|
//brk_type independant coding
|
||||||
|
|
||||||
|
if (stackop>0) {
|
||||||
|
//Announced stack mem breaks
|
||||||
|
//PHA, PLA, PHP, and PLP affect the stack data.
|
||||||
|
//TXS and TSX only deal with the pointer.
|
||||||
|
if (watchpoint[i].flags & stackop) {
|
||||||
|
for (j = (stackopstartaddr|0x0100); j <= (stackopendaddr|0x0100); j++) {
|
||||||
|
if (watchpoint[i].endaddress) {
|
||||||
|
if ((watchpoint[i].address <= j) && (watchpoint[i].endaddress >= j)) BreakHit();
|
||||||
|
}
|
||||||
|
else if (watchpoint[i].address == j) BreakHit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (StackNextIgnorePC==_PC) {
|
||||||
|
//Used to make it ignore the unannounced stack code one time
|
||||||
|
StackNextIgnorePC = 0xFFFF;
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
if ((X.S < StackAddrBackup) && (stackop==0)) {
|
||||||
|
//Unannounced stack mem breaks
|
||||||
|
//Pushes to stack
|
||||||
|
if (watchpoint[i].flags & WP_W) {
|
||||||
|
for (j = (X.S|0x0100); j < (StackAddrBackup|0x0100); j++) {
|
||||||
|
if (watchpoint[i].endaddress) {
|
||||||
|
if ((watchpoint[i].address <= j) && (watchpoint[i].endaddress >= j)) BreakHit();
|
||||||
|
}
|
||||||
|
else if (watchpoint[i].address == j) BreakHit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ((StackAddrBackup < X.S) && (stackop==0)) {
|
||||||
|
//Pulls from stack
|
||||||
|
if (watchpoint[i].flags & WP_R) {
|
||||||
|
for (j = (StackAddrBackup|0x0100); j < (X.S|0x0100); j++) {
|
||||||
|
if (watchpoint[i].endaddress) {
|
||||||
|
if ((watchpoint[i].address <= j) && (watchpoint[i].endaddress >= j)) BreakHit();
|
||||||
|
}
|
||||||
|
else if (watchpoint[i].address == j) BreakHit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// ################################## Start of SP CODE ###########################
|
// ################################## Start of SP CODE ###########################
|
||||||
}
|
}
|
||||||
// ################################## End of SP CODE ###########################
|
// ################################## End of SP CODE ###########################
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Update the stack address with the current one, now that changes have registered.
|
||||||
|
StackAddrBackup = X.S;
|
||||||
}
|
}
|
||||||
//bbit edited: this is the end of the inserted code
|
//bbit edited: this is the end of the inserted code
|
||||||
|
|
||||||
@ -617,8 +678,8 @@ void DebugCycle() {
|
|||||||
|
|
||||||
if (scanline == 240)
|
if (scanline == 240)
|
||||||
{
|
{
|
||||||
vblankScanLines = (timestamp / 114); //114 approximates the number of timestamps per scanline during vblank. Approx 2508
|
vblankScanLines = (PAL?int((double)timestamp / ((double)341 / (double)3.2)):timestamp / 114); //114 approximates the number of timestamps per scanline during vblank. Approx 2508. NTSC: (341 / 3.0) PAL: (341 / 3.2). Uses (3.? * cpu_cycles) / 341.0, and assumes 1 cpu cycle.
|
||||||
if (vblankScanLines) vblankPixel = 341 / vblankScanLines; //314 pixels per scanline
|
if (vblankScanLines) vblankPixel = 341 / vblankScanLines; //341 pixels per scanline
|
||||||
//FCEUI_printf("vbPixel = %d",vblankPixel); //Debug
|
//FCEUI_printf("vbPixel = %d",vblankPixel); //Debug
|
||||||
//FCEUI_printf("ts: %d line: %d\n", timestamp, vblankScanLines); //Debug
|
//FCEUI_printf("ts: %d line: %d\n", timestamp, vblankScanLines); //Debug
|
||||||
}
|
}
|
||||||
|
@ -55,6 +55,7 @@ typedef struct {
|
|||||||
//mbg merge 7/18/06 had to make this extern
|
//mbg merge 7/18/06 had to make this extern
|
||||||
extern watchpointinfo watchpoint[65]; //64 watchpoints, + 1 reserved for step over
|
extern watchpointinfo watchpoint[65]; //64 watchpoints, + 1 reserved for step over
|
||||||
|
|
||||||
|
int getBank(int offs);
|
||||||
int GetNesFileAddress(int A);
|
int GetNesFileAddress(int A);
|
||||||
int GetPRGAddress(int A);
|
int GetPRGAddress(int A);
|
||||||
int GetRomAddress(int A);
|
int GetRomAddress(int A);
|
||||||
|
@ -135,6 +135,10 @@ void DrawMessage(bool beforeMovie)
|
|||||||
|
|
||||||
uint8 *t;
|
uint8 *t;
|
||||||
guiMessage.howlong--;
|
guiMessage.howlong--;
|
||||||
|
|
||||||
|
if (guiMessage.linesFromBottom > 0)
|
||||||
|
t=XBuf+FCEU_TextScanlineOffsetFromBottom(guiMessage.linesFromBottom)+1;
|
||||||
|
else
|
||||||
t=XBuf+FCEU_TextScanlineOffsetFromBottom(20)+1;
|
t=XBuf+FCEU_TextScanlineOffsetFromBottom(20)+1;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -336,7 +340,7 @@ void FCEU_DrawRecordingStatus(uint8* XBuf)
|
|||||||
drawstatus(XBuf-ClipSidesOffset,2,28,0);
|
drawstatus(XBuf-ClipSidesOffset,2,28,0);
|
||||||
hasPlayRecIcon = true;
|
hasPlayRecIcon = true;
|
||||||
}
|
}
|
||||||
else if(FCEUMOV_Mode(MOVIEMODE_PLAY))
|
else if(FCEUMOV_Mode(MOVIEMODE_PLAY|MOVIEMODE_FINISHED))
|
||||||
{
|
{
|
||||||
drawstatus(XBuf-ClipSidesOffset,1,28,0);
|
drawstatus(XBuf-ClipSidesOffset,1,28,0);
|
||||||
hasPlayRecIcon = true;
|
hasPlayRecIcon = true;
|
||||||
|
@ -11,8 +11,8 @@
|
|||||||
|
|
||||||
FILE *FCEUD_UTF8fopen(const char *fn, const char *mode);
|
FILE *FCEUD_UTF8fopen(const char *fn, const char *mode);
|
||||||
inline FILE *FCEUD_UTF8fopen(const std::string &n, const char *mode) { return FCEUD_UTF8fopen(n.c_str(),mode); }
|
inline FILE *FCEUD_UTF8fopen(const std::string &n, const char *mode) { return FCEUD_UTF8fopen(n.c_str(),mode); }
|
||||||
std::fstream* FCEUD_UTF8_fstream(const char *n, const char *m);
|
EMUFILE_FILE* FCEUD_UTF8_fstream(const char *n, const char *m);
|
||||||
inline std::fstream* FCEUD_UTF8_fstream(const std::string &n, const char *m) { return FCEUD_UTF8_fstream(n.c_str(),m); }
|
inline EMUFILE_FILE* FCEUD_UTF8_fstream(const std::string &n, const char *m) { return FCEUD_UTF8_fstream(n.c_str(),m); }
|
||||||
FCEUFILE* FCEUD_OpenArchiveIndex(ArchiveScanRecord& asr, std::string& fname, int innerIndex);
|
FCEUFILE* FCEUD_OpenArchiveIndex(ArchiveScanRecord& asr, std::string& fname, int innerIndex);
|
||||||
FCEUFILE* FCEUD_OpenArchive(ArchiveScanRecord& asr, std::string& fname, std::string* innerFilename);
|
FCEUFILE* FCEUD_OpenArchive(ArchiveScanRecord& asr, std::string& fname, std::string* innerFilename);
|
||||||
ArchiveScanRecord FCEUD_ScanArchive(std::string fname);
|
ArchiveScanRecord FCEUD_ScanArchive(std::string fname);
|
||||||
@ -77,6 +77,8 @@ void FCEUI_SetInputFC(ESIFC type, void *ptr, int attrib);
|
|||||||
void FCEUI_SetInputFourscore(bool attachFourscore);
|
void FCEUI_SetInputFourscore(bool attachFourscore);
|
||||||
//tells whether a fourscore is attached
|
//tells whether a fourscore is attached
|
||||||
bool FCEUI_GetInputFourscore();
|
bool FCEUI_GetInputFourscore();
|
||||||
|
//tells whether the microphone is used
|
||||||
|
bool FCEUI_GetInputMicrophone();
|
||||||
|
|
||||||
void FCEUI_UseInputPreset(int preset);
|
void FCEUI_UseInputPreset(int preset);
|
||||||
|
|
||||||
@ -167,7 +169,7 @@ void FCEUD_LoadStateFrom(void);
|
|||||||
|
|
||||||
//at the minimum, you should call FCEUI_SetInput, FCEUI_SetInputFC, and FCEUI_SetInputFourscore
|
//at the minimum, you should call FCEUI_SetInput, FCEUI_SetInputFC, and FCEUI_SetInputFourscore
|
||||||
//you may also need to maintain your own internal state
|
//you may also need to maintain your own internal state
|
||||||
void FCEUD_SetInput(bool fourscore, ESI port0, ESI port1, ESIFC fcexp);
|
void FCEUD_SetInput(bool fourscore, bool microphone, ESI port0, ESI port1, ESIFC fcexp);
|
||||||
|
|
||||||
|
|
||||||
void FCEUD_MovieRecordTo(void);
|
void FCEUD_MovieRecordTo(void);
|
||||||
@ -176,7 +178,8 @@ void FCEUD_LuaRunFrom(void);
|
|||||||
|
|
||||||
int32 FCEUI_GetDesiredFPS(void);
|
int32 FCEUI_GetDesiredFPS(void);
|
||||||
void FCEUI_SaveSnapshot(void);
|
void FCEUI_SaveSnapshot(void);
|
||||||
void FCEU_DispMessage(char *format, ...);
|
void FCEUI_SaveSnapshotAs(void);
|
||||||
|
void FCEU_DispMessage(char *format, int disppos, ...);
|
||||||
#define FCEUI_DispMessage FCEU_DispMessage
|
#define FCEUI_DispMessage FCEU_DispMessage
|
||||||
|
|
||||||
int FCEUI_DecodePAR(const char *code, int *a, int *v, int *c, int *type);
|
int FCEUI_DecodePAR(const char *code, int *a, int *v, int *c, int *type);
|
||||||
|
28
source/fceultra/emufile.cpp
Normal file
28
source/fceultra/emufile.cpp
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
#include "types.h"
|
||||||
|
#include "emufile.h"
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
bool EMUFILE::readAllBytes(std::vector<u8>* dstbuf, const std::string& fname)
|
||||||
|
{
|
||||||
|
EMUFILE_FILE file(fname.c_str(),"rb");
|
||||||
|
if(file.fail()) return false;
|
||||||
|
int size = file.size();
|
||||||
|
dstbuf->resize(size);
|
||||||
|
file.fread(&dstbuf->at(0),size);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
EMUFILE* EMUFILE::memwrap(EMUFILE* fp)
|
||||||
|
{
|
||||||
|
EMUFILE_FILE* file;
|
||||||
|
EMUFILE_MEMORY* mem;
|
||||||
|
file = dynamic_cast<EMUFILE_FILE*>(fp);
|
||||||
|
mem = dynamic_cast<EMUFILE_MEMORY*>(fp);
|
||||||
|
if(mem) return mem;
|
||||||
|
mem = new EMUFILE_MEMORY(file->size());
|
||||||
|
if(file->size()==0) return mem;
|
||||||
|
file->fread(mem->buf(),file->size());
|
||||||
|
delete file;
|
||||||
|
return mem;
|
||||||
|
}
|
428
source/fceultra/emufile.h
Normal file
428
source/fceultra/emufile.h
Normal file
@ -0,0 +1,428 @@
|
|||||||
|
/* Copyright (C) 2009 DeSmuME team
|
||||||
|
*
|
||||||
|
* This file is part of DeSmuME
|
||||||
|
*
|
||||||
|
* DeSmuME 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.
|
||||||
|
*
|
||||||
|
* DeSmuME 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 DeSmuME; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef EMUFILE_H
|
||||||
|
#define EMUFILE_H
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <vector>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <string>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <malloc.h>
|
||||||
|
|
||||||
|
//should be changed to #ifdef FCEUX but too much work
|
||||||
|
#ifndef DESMUME
|
||||||
|
#ifndef __GCTYPES_H__
|
||||||
|
typedef unsigned char u8;
|
||||||
|
typedef unsigned short u16;
|
||||||
|
typedef unsigned int u32;
|
||||||
|
typedef char s8;
|
||||||
|
typedef short s16;
|
||||||
|
typedef int s32;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef _XBOX
|
||||||
|
#undef min;
|
||||||
|
#undef max;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
class EMUFILE {
|
||||||
|
protected:
|
||||||
|
bool failbit;
|
||||||
|
|
||||||
|
public:
|
||||||
|
EMUFILE()
|
||||||
|
: failbit(false)
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
//takes control of the provided EMUFILE and returns a new EMUFILE which is guranteed to be in memory
|
||||||
|
static EMUFILE* memwrap(EMUFILE* fp);
|
||||||
|
|
||||||
|
virtual ~EMUFILE() {}
|
||||||
|
|
||||||
|
static bool readAllBytes(std::vector<u8>* buf, const std::string& fname);
|
||||||
|
|
||||||
|
bool fail() { return failbit; }
|
||||||
|
|
||||||
|
bool eof() { return size()==ftell(); }
|
||||||
|
|
||||||
|
size_t fread(const void *ptr, size_t bytes){
|
||||||
|
return _fread(ptr,bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
void unget() { fseek(-1,SEEK_CUR); }
|
||||||
|
|
||||||
|
//virtuals
|
||||||
|
public:
|
||||||
|
|
||||||
|
virtual FILE *get_fp() = 0;
|
||||||
|
|
||||||
|
virtual int fprintf(const char *format, ...) = 0;
|
||||||
|
|
||||||
|
virtual int fgetc() = 0;
|
||||||
|
virtual int fputc(int c) = 0;
|
||||||
|
|
||||||
|
virtual size_t _fread(const void *ptr, size_t bytes) = 0;
|
||||||
|
|
||||||
|
//removing these return values for now so we can find any code that might be using them and make sure
|
||||||
|
//they handle the return values correctly
|
||||||
|
|
||||||
|
virtual void fwrite(const void *ptr, size_t bytes) = 0;
|
||||||
|
|
||||||
|
virtual int fseek(int offset, int origin) = 0;
|
||||||
|
|
||||||
|
virtual int ftell() = 0;
|
||||||
|
virtual int size() = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
//todo - handle read-only specially?
|
||||||
|
class EMUFILE_MEMORY : public EMUFILE {
|
||||||
|
protected:
|
||||||
|
std::vector<u8> *vec;
|
||||||
|
bool ownvec;
|
||||||
|
s32 pos, len;
|
||||||
|
|
||||||
|
void reserve(u32 amt) {
|
||||||
|
if(vec->size() < amt)
|
||||||
|
vec->resize(amt);
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
EMUFILE_MEMORY(std::vector<u8> *underlying) : vec(underlying), ownvec(false), pos(0), len(underlying->size()) { }
|
||||||
|
EMUFILE_MEMORY(u32 preallocate) : vec(new std::vector<u8>()), ownvec(true), pos(0), len(0) {
|
||||||
|
vec->resize(preallocate);
|
||||||
|
len = preallocate;
|
||||||
|
}
|
||||||
|
EMUFILE_MEMORY() : vec(new std::vector<u8>()), ownvec(true), pos(0), len(0) { vec->reserve(1024); }
|
||||||
|
EMUFILE_MEMORY(void* buf, s32 size) : vec(new std::vector<u8>()), ownvec(true), pos(0), len(size) {
|
||||||
|
vec->resize(size);
|
||||||
|
if(size != 0)
|
||||||
|
memcpy(&vec[0],buf,size);
|
||||||
|
}
|
||||||
|
|
||||||
|
~EMUFILE_MEMORY() {
|
||||||
|
if(ownvec) delete vec;
|
||||||
|
}
|
||||||
|
|
||||||
|
u8* buf() { return &(*vec)[0]; }
|
||||||
|
|
||||||
|
std::vector<u8>* get_vec() { return vec; };
|
||||||
|
|
||||||
|
virtual FILE *get_fp() { return NULL; }
|
||||||
|
|
||||||
|
virtual int fprintf(const char *format, ...) {
|
||||||
|
va_list argptr;
|
||||||
|
va_start(argptr, format);
|
||||||
|
|
||||||
|
//we dont generate straight into the buffer because it will null terminate (one more byte than we want)
|
||||||
|
int amt = vsnprintf(0,0,format,argptr);
|
||||||
|
char* tempbuf = new char[amt+1];
|
||||||
|
vsprintf(tempbuf,format,argptr);
|
||||||
|
fwrite(tempbuf,amt);
|
||||||
|
delete[] tempbuf;
|
||||||
|
va_end(argptr);
|
||||||
|
return amt;
|
||||||
|
};
|
||||||
|
|
||||||
|
virtual int fgetc() {
|
||||||
|
u8 temp;
|
||||||
|
|
||||||
|
//need an optimized codepath
|
||||||
|
//if(_fread(&temp,1) != 1)
|
||||||
|
// return EOF;
|
||||||
|
//else return temp;
|
||||||
|
u32 remain = len-pos;
|
||||||
|
if(remain<1) {
|
||||||
|
failbit = true;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
temp = buf()[pos];
|
||||||
|
pos++;
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
virtual int fputc(int c) {
|
||||||
|
u8 temp = (u8)c;
|
||||||
|
//TODO
|
||||||
|
//if(fwrite(&temp,1)!=1) return EOF;
|
||||||
|
fwrite(&temp,1);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual size_t _fread(const void *ptr, size_t bytes){
|
||||||
|
u32 remain = len-pos;
|
||||||
|
u32 todo = std::min<u32>(remain,(u32)bytes);
|
||||||
|
memcpy((void*)ptr,buf()+pos,todo);
|
||||||
|
pos += todo;
|
||||||
|
if(todo<bytes)
|
||||||
|
failbit = true;
|
||||||
|
return todo;
|
||||||
|
}
|
||||||
|
|
||||||
|
//removing these return values for now so we can find any code that might be using them and make sure
|
||||||
|
//they handle the return values correctly
|
||||||
|
|
||||||
|
virtual void fwrite(const void *ptr, size_t bytes){
|
||||||
|
reserve(pos+bytes);
|
||||||
|
memcpy(buf()+pos,ptr,bytes);
|
||||||
|
pos += bytes;
|
||||||
|
len = std::max(pos,len);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual int fseek(int offset, int origin){
|
||||||
|
//work differently for read-only...?
|
||||||
|
switch(origin) {
|
||||||
|
case SEEK_SET:
|
||||||
|
pos = offset;
|
||||||
|
break;
|
||||||
|
case SEEK_CUR:
|
||||||
|
pos += offset;
|
||||||
|
break;
|
||||||
|
case SEEK_END:
|
||||||
|
pos = size()+offset;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
reserve(pos);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual int ftell() {
|
||||||
|
return pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
void trim()
|
||||||
|
{
|
||||||
|
vec->resize(len);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual int size() { return (int)len; }
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef GEKKO
|
||||||
|
class EMUFILE_MEMFILE : public EMUFILE {
|
||||||
|
protected:
|
||||||
|
bool own_buffer;
|
||||||
|
char *buffer;
|
||||||
|
s32 buffersize, pos, len;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
EMUFILE_MEMFILE(u32 preallocate) {
|
||||||
|
buffer = (char *)memalign(32, preallocate);
|
||||||
|
own_buffer = true;
|
||||||
|
buffersize = 0;
|
||||||
|
len = 0;
|
||||||
|
pos = 0;
|
||||||
|
|
||||||
|
if(!buffer)
|
||||||
|
return;
|
||||||
|
|
||||||
|
buffersize = preallocate;
|
||||||
|
}
|
||||||
|
EMUFILE_MEMFILE(void* src, s32 src_size) {
|
||||||
|
buffer = (char *)src;
|
||||||
|
own_buffer = false;
|
||||||
|
buffersize = src_size;
|
||||||
|
len = src_size;
|
||||||
|
pos = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
~EMUFILE_MEMFILE() {
|
||||||
|
if(own_buffer && buffer) free(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
char* buf() { return buffer; }
|
||||||
|
|
||||||
|
virtual FILE *get_fp() { return NULL; }
|
||||||
|
|
||||||
|
virtual int fprintf(const char *format, ...) {
|
||||||
|
va_list argptr;
|
||||||
|
va_start(argptr, format);
|
||||||
|
|
||||||
|
//we dont generate straight into the buffer because it will null terminate (one more byte than we want)
|
||||||
|
int amt = vsnprintf(0,0,format,argptr);
|
||||||
|
char* tempbuf = new char[amt+1];
|
||||||
|
vsprintf(tempbuf,format,argptr);
|
||||||
|
fwrite(tempbuf,amt);
|
||||||
|
delete[] tempbuf;
|
||||||
|
va_end(argptr);
|
||||||
|
return amt;
|
||||||
|
};
|
||||||
|
|
||||||
|
virtual int fgetc() {
|
||||||
|
if(pos >= len) {
|
||||||
|
failbit = true;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return (int)buffer[pos++];
|
||||||
|
}
|
||||||
|
virtual int fputc(int c) {
|
||||||
|
if(pos >= buffersize) {
|
||||||
|
failbit = true;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
buffer[pos] = (char)c;
|
||||||
|
pos++;
|
||||||
|
len++;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual size_t _fread(const void *ptr, size_t bytes){
|
||||||
|
u32 remain = len-pos;
|
||||||
|
if(remain == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
u32 todo = std::min<u32>(remain,(u32)bytes);
|
||||||
|
memcpy((void*)ptr,buffer+pos,todo);
|
||||||
|
pos += todo;
|
||||||
|
return todo;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void fwrite(const void *ptr, size_t bytes){
|
||||||
|
if(pos+bytes > (u32)buffersize) return;
|
||||||
|
memcpy(buffer+pos,ptr,bytes);
|
||||||
|
pos += bytes;
|
||||||
|
len = std::max(pos,len);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual int fseek(int offset, int origin){
|
||||||
|
switch(origin) {
|
||||||
|
case SEEK_SET:
|
||||||
|
if(offset >= 0 && offset <= len)
|
||||||
|
pos = offset;
|
||||||
|
else
|
||||||
|
return 1; // failure
|
||||||
|
break;
|
||||||
|
case SEEK_CUR:
|
||||||
|
if((pos + offset) >= 0 && (pos + offset) <= len)
|
||||||
|
pos += offset;
|
||||||
|
else
|
||||||
|
return 1; // failure
|
||||||
|
break;
|
||||||
|
case SEEK_END:
|
||||||
|
if((pos + offset) >= 0 && (pos + offset) <= len)
|
||||||
|
pos = len + offset;
|
||||||
|
else
|
||||||
|
return 1; // failure
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return 1; // failure
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual int ftell() {
|
||||||
|
return pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
void trim()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual int size() { return (int)len; }
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
class EMUFILE_FILE : public EMUFILE {
|
||||||
|
protected:
|
||||||
|
FILE* fp;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void open(const char* fname, const char* mode)
|
||||||
|
{
|
||||||
|
fp = fopen(fname,mode);
|
||||||
|
if(!fp)
|
||||||
|
failbit = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
EMUFILE_FILE(const std::string& fname, const char* mode) { open(fname.c_str(),mode); }
|
||||||
|
EMUFILE_FILE(const char* fname, const char* mode) { open(fname,mode); }
|
||||||
|
|
||||||
|
virtual ~EMUFILE_FILE() {
|
||||||
|
if(NULL != fp)
|
||||||
|
fclose(fp);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual FILE *get_fp() {
|
||||||
|
return fp;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_open() { return fp != NULL; }
|
||||||
|
|
||||||
|
virtual int fprintf(const char *format, ...) {
|
||||||
|
va_list argptr;
|
||||||
|
va_start(argptr, format);
|
||||||
|
int ret = ::vfprintf(fp, format, argptr);
|
||||||
|
va_end(argptr);
|
||||||
|
return ret;
|
||||||
|
};
|
||||||
|
|
||||||
|
virtual int fgetc() {
|
||||||
|
return ::fgetc(fp);
|
||||||
|
}
|
||||||
|
virtual int fputc(int c) {
|
||||||
|
return ::fputc(c, fp);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual size_t _fread(const void *ptr, size_t bytes){
|
||||||
|
size_t ret = ::fread((void*)ptr, 1, bytes, fp);
|
||||||
|
if(ret < bytes)
|
||||||
|
failbit = true;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
//removing these return values for now so we can find any code that might be using them and make sure
|
||||||
|
//they handle the return values correctly
|
||||||
|
|
||||||
|
virtual void fwrite(const void *ptr, size_t bytes){
|
||||||
|
size_t ret = ::fwrite((void*)ptr, 1, bytes, fp);
|
||||||
|
if(ret < bytes)
|
||||||
|
failbit = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual int fseek(int offset, int origin){
|
||||||
|
return ::fseek(fp, offset, origin);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual int ftell() {
|
||||||
|
return (u32)::ftell(fp);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual int size() {
|
||||||
|
int oldpos = ftell();
|
||||||
|
fseek(0,SEEK_END);
|
||||||
|
int len = ftell();
|
||||||
|
fseek(oldpos,SEEK_SET);
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
@ -85,6 +85,7 @@ bool justLagged = false;
|
|||||||
bool frameAdvanceLagSkip = false; //If this is true, frame advance will skip over lag frame (i.e. it will emulate 2 frames instead of 1)
|
bool frameAdvanceLagSkip = false; //If this is true, frame advance will skip over lag frame (i.e. it will emulate 2 frames instead of 1)
|
||||||
bool AutoSS = false; //Flagged true when the first auto-savestate is made while a game is loaded, flagged false on game close
|
bool AutoSS = false; //Flagged true when the first auto-savestate is made while a game is loaded, flagged false on game close
|
||||||
bool movieSubtitles = true; //Toggle for displaying movie subtitles
|
bool movieSubtitles = true; //Toggle for displaying movie subtitles
|
||||||
|
bool DebuggerWasUpdated = false; //To prevent the debugger from updating things without being updated.
|
||||||
|
|
||||||
FCEUGI::FCEUGI()
|
FCEUGI::FCEUGI()
|
||||||
: filename(0)
|
: filename(0)
|
||||||
@ -99,20 +100,53 @@ FCEUGI::~FCEUGI()
|
|||||||
if(archiveFilename) delete archiveFilename;
|
if(archiveFilename) delete archiveFilename;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CheckFileExists(const char* filename)
|
||||||
|
{
|
||||||
|
//This function simply checks to see if the given filename exists
|
||||||
|
if (!filename) return false;
|
||||||
|
fstream test;
|
||||||
|
test.open(filename,fstream::in);
|
||||||
|
|
||||||
|
if (test.fail())
|
||||||
|
{
|
||||||
|
test.close();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
test.close();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FCEU_TogglePPU(void)
|
||||||
|
{
|
||||||
|
newppu ^= 1;
|
||||||
|
if (newppu)
|
||||||
|
{
|
||||||
|
FCEU_DispMessage("New PPU loaded", 0);
|
||||||
|
FCEUI_printf("New PPU loaded");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FCEU_DispMessage("Old PPU loaded", 0);
|
||||||
|
FCEUI_printf("Old PPU loaded");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void FCEU_CloseGame(void)
|
static void FCEU_CloseGame(void)
|
||||||
{
|
{
|
||||||
if(GameInfo)
|
if(GameInfo)
|
||||||
{
|
{
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
// ################################## Start of SP CODE ###########################
|
//SP CODE
|
||||||
extern char LoadedRomFName[2048];
|
extern char LoadedRomFName[2048];
|
||||||
|
|
||||||
if (storePreferences(LoadedRomFName))
|
if (storePreferences(LoadedRomFName))
|
||||||
{
|
{
|
||||||
FCEUD_PrintError("Couldn't store debugging data");
|
FCEUD_PrintError("Couldn't store debugging data");
|
||||||
}
|
}
|
||||||
// ################################## End of SP CODE ###########################
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if(FCEUnetplay)
|
if(FCEUnetplay)
|
||||||
@ -128,11 +162,7 @@ static void FCEU_CloseGame(void)
|
|||||||
|
|
||||||
if(GameInfo->type!=GIT_NSF)
|
if(GameInfo->type!=GIT_NSF)
|
||||||
{
|
{
|
||||||
#ifdef GEKKO
|
|
||||||
FCEU_FlushGameCheats(0,1); // don't save cheats
|
|
||||||
#else
|
|
||||||
FCEU_FlushGameCheats(0,0);
|
FCEU_FlushGameCheats(0,0);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GameInterface(GI_CLOSE);
|
GameInterface(GI_CLOSE);
|
||||||
@ -141,8 +171,7 @@ static void FCEU_CloseGame(void)
|
|||||||
|
|
||||||
ResetExState(0,0);
|
ResetExState(0,0);
|
||||||
|
|
||||||
//mbg 5/9/08 - clear screen when game is closed
|
//clear screen when game is closed
|
||||||
//http://sourceforge.net/tracker/index.php?func=detail&aid=1787298&group_id=13536&atid=113536
|
|
||||||
extern uint8 *XBuf;
|
extern uint8 *XBuf;
|
||||||
if(XBuf)
|
if(XBuf)
|
||||||
memset(XBuf,0,256*256);
|
memset(XBuf,0,256*256);
|
||||||
@ -152,10 +181,9 @@ static void FCEU_CloseGame(void)
|
|||||||
delete GameInfo;
|
delete GameInfo;
|
||||||
GameInfo = 0;
|
GameInfo = 0;
|
||||||
|
|
||||||
//Reset frame counter
|
|
||||||
currFrameCounter = 0;
|
currFrameCounter = 0;
|
||||||
|
|
||||||
//Reset flags for Undo/Redo/Auto Savestating
|
//Reset flags for Undo/Redo/Auto Savestating //adelikat: TODO: maybe this stuff would be cleaner as a struct or class
|
||||||
lastSavestateMade[0] = 0;
|
lastSavestateMade[0] = 0;
|
||||||
undoSS = false;
|
undoSS = false;
|
||||||
redoSS = false;
|
redoSS = false;
|
||||||
@ -318,7 +346,8 @@ static void AllocBuffers()
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void FreeBuffers() {
|
static void FreeBuffers()
|
||||||
|
{
|
||||||
#ifdef _USE_SHARED_MEMORY_
|
#ifdef _USE_SHARED_MEMORY_
|
||||||
void win_FreeBuffers(uint8 *GameMemBlock, uint8 *RAM);
|
void win_FreeBuffers(uint8 *GameMemBlock, uint8 *RAM);
|
||||||
win_FreeBuffers(GameMemBlock, RAM);
|
win_FreeBuffers(GameMemBlock, RAM);
|
||||||
@ -493,7 +522,7 @@ endlseq:
|
|||||||
FCEU_LoadGameCheats(0);
|
FCEU_LoadGameCheats(0);
|
||||||
|
|
||||||
#if defined (WIN32) || defined (WIN64)
|
#if defined (WIN32) || defined (WIN64)
|
||||||
DoDebuggerRunCheck(); //Can't safely do it in loadPreferences
|
DoDebuggerDataReload(); // Reloads data without reopening window
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return GameInfo;
|
return GameInfo;
|
||||||
@ -590,12 +619,13 @@ void SetAutoFireOffset(int offset)
|
|||||||
void AutoFire(void)
|
void AutoFire(void)
|
||||||
{
|
{
|
||||||
static int counter = 0;
|
static int counter = 0;
|
||||||
if (justLagged == false) counter = (counter + 1) % (8*7*5*3);
|
if (justLagged == false)
|
||||||
|
counter = (counter + 1) % (8*7*5*3);
|
||||||
//If recording a movie, use the frame # for the autofire so the offset
|
//If recording a movie, use the frame # for the autofire so the offset
|
||||||
//doesn't get screwed up when loading.
|
//doesn't get screwed up when loading.
|
||||||
if(FCEUMOV_Mode(MOVIEMODE_RECORD | MOVIEMODE_PLAY))
|
if(FCEUMOV_Mode(MOVIEMODE_RECORD | MOVIEMODE_PLAY))
|
||||||
{
|
{
|
||||||
rapidAlternator= AutoFirePattern[(AutoFireOffset + FCEUMOV_GetFrame())%AutoFirePatternLength];
|
rapidAlternator= AutoFirePattern[(AutoFireOffset + FCEUMOV_GetFrame())%AutoFirePatternLength]; //adelikat: TODO: Think through this, MOVIEMODE_FINISHED should not use movie data for auto-fire?
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -661,12 +691,15 @@ void FCEUI_Emulate(uint8 **pXBuf, int32 **SoundBuf, int32 *SoundBufSize, int ski
|
|||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
//These Windows only dialogs need to be updated only once per frame so they are included here
|
//These Windows only dialogs need to be updated only once per frame so they are included here
|
||||||
UpdateCheatList();
|
UpdateCheatList(); // CaH4e3: can't see why, this is only cause problems with selection - adelikat: selection is only a problem when not paused, it shoudl be paused to select, we want to see the values update
|
||||||
UpdateTextHooker();
|
UpdateTextHooker();
|
||||||
Update_RAM_Search(); // Update_RAM_Watch() is also called.
|
Update_RAM_Search(); // Update_RAM_Watch() is also called.
|
||||||
RamChange();
|
RamChange();
|
||||||
UpdateLogWindow();
|
UpdateLogWindow();
|
||||||
//FCEUI_AviVideoUpdate(XBuf);
|
//FCEUI_AviVideoUpdate(XBuf);
|
||||||
|
extern int KillFCEUXonFrame;
|
||||||
|
if (KillFCEUXonFrame && (FCEUMOV_GetFrame() >= KillFCEUXonFrame))
|
||||||
|
DoFCEUExit();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
timestampbase += timestamp;
|
timestampbase += timestamp;
|
||||||
@ -928,6 +961,7 @@ void FCEUI_SetEmulationPaused(int val)
|
|||||||
void FCEUI_ToggleEmulationPause(void)
|
void FCEUI_ToggleEmulationPause(void)
|
||||||
{
|
{
|
||||||
EmulationPaused = (EmulationPaused&1)^1;
|
EmulationPaused = (EmulationPaused&1)^1;
|
||||||
|
DebuggerWasUpdated = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FCEUI_FrameAdvanceEnd(void)
|
void FCEUI_FrameAdvanceEnd(void)
|
||||||
@ -945,7 +979,7 @@ static int AutosaveCounter = 0;
|
|||||||
|
|
||||||
void UpdateAutosave(void)
|
void UpdateAutosave(void)
|
||||||
{
|
{
|
||||||
if(!EnableAutosave)
|
if(!EnableAutosave || turbo)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
char * f;
|
char * f;
|
||||||
@ -963,7 +997,7 @@ void UpdateAutosave(void)
|
|||||||
|
|
||||||
void FCEUI_Autosave(void)
|
void FCEUI_Autosave(void)
|
||||||
{
|
{
|
||||||
if(!EnableAutosave || !AutoSS)
|
if(!EnableAutosave || !AutoSS || FCEUMOV_Mode(MOVIEMODE_TASEDIT))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if(AutosaveStatus[AutosaveIndex] == 1)
|
if(AutosaveStatus[AutosaveIndex] == 1)
|
||||||
@ -1016,7 +1050,7 @@ bool FCEU_IsValidUI(EFCEUI ui)
|
|||||||
|
|
||||||
case FCEUI_STOPMOVIE:
|
case FCEUI_STOPMOVIE:
|
||||||
case FCEUI_PLAYFROMBEGINNING:
|
case FCEUI_PLAYFROMBEGINNING:
|
||||||
return FCEUMOV_Mode(MOVIEMODE_PLAY|MOVIEMODE_RECORD);
|
return (FCEUMOV_Mode(MOVIEMODE_PLAY|MOVIEMODE_RECORD|MOVIEMODE_FINISHED));
|
||||||
|
|
||||||
case FCEUI_STOPAVI:
|
case FCEUI_STOPAVI:
|
||||||
return FCEUI_AviIsRecording();
|
return FCEUI_AviIsRecording();
|
||||||
@ -1027,7 +1061,7 @@ bool FCEU_IsValidUI(EFCEUI ui)
|
|||||||
|
|
||||||
case FCEUI_RESET:
|
case FCEUI_RESET:
|
||||||
if(!GameInfo) return false;
|
if(!GameInfo) return false;
|
||||||
if(FCEUMOV_Mode(MOVIEMODE_TASEDIT|MOVIEMODE_PLAY)) return false;
|
if(FCEUMOV_Mode(MOVIEMODE_FINISHED|MOVIEMODE_TASEDIT|MOVIEMODE_PLAY)) return false;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FCEUI_POWER:
|
case FCEUI_POWER:
|
||||||
|
@ -108,10 +108,13 @@ int FCEU_TextScanlineOffsetFromBottom(int y);
|
|||||||
|
|
||||||
extern FCEUS FSettings;
|
extern FCEUS FSettings;
|
||||||
|
|
||||||
|
bool CheckFileExists(const char* filename); //Receives a filename (fullpath) and checks to see if that file exists
|
||||||
|
|
||||||
void FCEU_PrintError(char *format, ...);
|
void FCEU_PrintError(char *format, ...);
|
||||||
void FCEU_printf(char *format, ...);
|
void FCEU_printf(char *format, ...);
|
||||||
void FCEU_DispMessage(char *format, ...);
|
void FCEU_DispMessage(char *format, int disppos, ...);
|
||||||
void FCEU_DispMessageOnMovie(char *format, ...);
|
void FCEU_DispMessageOnMovie(char *format, ...);
|
||||||
|
void FCEU_TogglePPU();
|
||||||
|
|
||||||
void SetNESDeemph(uint8 d, int force);
|
void SetNESDeemph(uint8 d, int force);
|
||||||
void DrawTextTrans(uint8 *dest, uint32 width, uint8 *textmsg, uint8 fgcolor);
|
void DrawTextTrans(uint8 *dest, uint32 width, uint8 *textmsg, uint8 fgcolor);
|
||||||
|
@ -161,17 +161,17 @@ void FCEU_FDSInsert(void)
|
|||||||
|
|
||||||
if(TotalSides==0)
|
if(TotalSides==0)
|
||||||
{
|
{
|
||||||
FCEU_DispMessage("Not FDS; can't eject disk.");
|
FCEU_DispMessage("Not FDS; can't eject disk.",0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(InDisk==255)
|
if(InDisk==255)
|
||||||
{
|
{
|
||||||
FCEU_DispMessage("Disk %d Side %s Inserted",SelectDisk>>1,(SelectDisk&1)?"B":"A");
|
FCEU_DispMessage("Disk %d Side %s Inserted",0,SelectDisk>>1,(SelectDisk&1)?"B":"A");
|
||||||
InDisk=SelectDisk;
|
InDisk=SelectDisk;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
FCEU_DispMessage("Disk %d Side %s Ejected",SelectDisk>>1,(SelectDisk&1)?"B":"A");
|
FCEU_DispMessage("Disk %d Side %s Ejected",0,SelectDisk>>1,(SelectDisk&1)?"B":"A");
|
||||||
InDisk=255;
|
InDisk=255;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -190,16 +190,16 @@ void FCEU_FDSSelect(void)
|
|||||||
|
|
||||||
if(TotalSides==0)
|
if(TotalSides==0)
|
||||||
{
|
{
|
||||||
FCEU_DispMessage("Not FDS; can't select disk.");
|
FCEU_DispMessage("Not FDS; can't select disk.",0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(InDisk!=255)
|
if(InDisk!=255)
|
||||||
{
|
{
|
||||||
FCEU_DispMessage("Eject disk before selecting.");
|
FCEU_DispMessage("Eject disk before selecting.",0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
SelectDisk=((SelectDisk+1)%TotalSides)&3;
|
SelectDisk=((SelectDisk+1)%TotalSides)&3;
|
||||||
FCEU_DispMessage("Disk %d Side %c Selected",SelectDisk>>1,(SelectDisk&1)?'B':'A');
|
FCEU_DispMessage("Disk %d Side %c Selected",0,SelectDisk>>1,(SelectDisk&1)?'B':'A');
|
||||||
}
|
}
|
||||||
|
|
||||||
static void FDSFix(int a)
|
static void FDSFix(int a)
|
||||||
@ -797,6 +797,15 @@ int FDSLoad(const char *name, FCEUFILE *fp)
|
|||||||
|
|
||||||
free(fn);
|
free(fn);
|
||||||
|
|
||||||
|
fseek( zp, 0L, SEEK_END );
|
||||||
|
if (ftell( zp ) != 8192 ) {
|
||||||
|
fclose(zp);
|
||||||
|
FreeFDSMemory();
|
||||||
|
FCEU_PrintError("FDS BIOS ROM image incompatible: %s", FCEU_MakeFName(FCEUMKF_FDSROM,0,0).c_str());
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
fseek( zp, 0L, SEEK_SET );
|
||||||
|
|
||||||
if(fread(FDSBIOS,1,8192,zp)!=8192)
|
if(fread(FDSBIOS,1,8192,zp)!=8192)
|
||||||
{
|
{
|
||||||
fclose(zp);
|
fclose(zp);
|
||||||
|
@ -48,7 +48,6 @@
|
|||||||
#include "movie.h"
|
#include "movie.h"
|
||||||
#include "driver.h"
|
#include "driver.h"
|
||||||
#include "utils/xstring.h"
|
#include "utils/xstring.h"
|
||||||
#include "utils/memorystream.h"
|
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
@ -143,8 +142,7 @@ void ApplyIPS(FILE *ips, FCEUFILE* fp)
|
|||||||
FCEU_printf(" Hard IPS end!\n");
|
FCEU_printf(" Hard IPS end!\n");
|
||||||
end:
|
end:
|
||||||
fclose(ips);
|
fclose(ips);
|
||||||
memorystream* ms = new memorystream(buf,fp->size);
|
EMUFILE_MEMORY* ms = new EMUFILE_MEMORY(buf,fp->size);
|
||||||
ms->giveBuf();
|
|
||||||
fp->SetStream(ms);
|
fp->SetStream(ms);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -224,7 +222,9 @@ static FCEUFILE * TryUnzip(const std::string& path) {
|
|||||||
if(unzGoToNextFile(tz)!=UNZ_OK)
|
if(unzGoToNextFile(tz)!=UNZ_OK)
|
||||||
{
|
{
|
||||||
if(unzGoToFirstFile(tz)!=UNZ_OK) goto zpfail;
|
if(unzGoToFirstFile(tz)!=UNZ_OK) goto zpfail;
|
||||||
break;
|
unzCloseCurrentFile(tz);
|
||||||
|
unzClose(tz);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(unzOpenCurrentFile(tz)!=UNZ_OK)
|
if(unzOpenCurrentFile(tz)!=UNZ_OK)
|
||||||
@ -241,7 +241,7 @@ zpfail:
|
|||||||
unzGetCurrentFileInfo(tz,&ufo,0,0,0,0,0,0);
|
unzGetCurrentFileInfo(tz,&ufo,0,0,0,0,0,0);
|
||||||
|
|
||||||
int size = ufo.uncompressed_size;
|
int size = ufo.uncompressed_size;
|
||||||
memorystream* ms = new memorystream(size);
|
EMUFILE_MEMORY* ms = new EMUFILE_MEMORY(size);
|
||||||
unzReadCurrentFile(tz,ms->buf(),ufo.uncompressed_size);
|
unzReadCurrentFile(tz,ms->buf(),ufo.uncompressed_size);
|
||||||
unzCloseCurrentFile(tz);
|
unzCloseCurrentFile(tz);
|
||||||
unzClose(tz);
|
unzClose(tz);
|
||||||
@ -283,7 +283,7 @@ FCEUFILE * FCEU_fopen(const char *path, const char *ipsfn, char *mode, char *ext
|
|||||||
if(!asr.isArchive())
|
if(!asr.isArchive())
|
||||||
{
|
{
|
||||||
//if the archive contained no files, try to open it the old fashioned way
|
//if the archive contained no files, try to open it the old fashioned way
|
||||||
std::fstream* fp = FCEUD_UTF8_fstream(fileToOpen,mode);
|
EMUFILE_FILE* fp = FCEUD_UTF8_fstream(fileToOpen,mode);
|
||||||
if(!fp)
|
if(!fp)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
@ -306,10 +306,10 @@ FCEUFILE * FCEU_fopen(const char *path, const char *ipsfn, char *mode, char *ext
|
|||||||
{
|
{
|
||||||
uint32 magic;
|
uint32 magic;
|
||||||
|
|
||||||
magic = fp->get();
|
magic = fp->fgetc();
|
||||||
magic|=fp->get()<<8;
|
magic|=fp->fgetc()<<8;
|
||||||
magic|=fp->get()<<16;
|
magic|=fp->fgetc()<<16;
|
||||||
fp->seekg(0,std::ios::beg);
|
fp->fseek(0,SEEK_SET);
|
||||||
|
|
||||||
if(magic==0x088b1f) {
|
if(magic==0x088b1f) {
|
||||||
// maybe gzip...
|
// maybe gzip...
|
||||||
@ -320,7 +320,7 @@ FCEUFILE * FCEU_fopen(const char *path, const char *ipsfn, char *mode, char *ext
|
|||||||
|
|
||||||
int size;
|
int size;
|
||||||
for(size=0; gzgetc(gzfile) != EOF; size++) {}
|
for(size=0; gzgetc(gzfile) != EOF; size++) {}
|
||||||
memorystream* ms = new memorystream(size);
|
EMUFILE_MEMORY* ms = new EMUFILE_MEMORY(size);
|
||||||
gzseek(gzfile,0,SEEK_SET);
|
gzseek(gzfile,0,SEEK_SET);
|
||||||
gzread(gzfile,ms->buf(),size);
|
gzread(gzfile,ms->buf(),size);
|
||||||
gzclose(gzfile);
|
gzclose(gzfile);
|
||||||
@ -344,7 +344,7 @@ FCEUFILE * FCEU_fopen(const char *path, const char *ipsfn, char *mode, char *ext
|
|||||||
fceufp->logicalPath = fileToOpen;
|
fceufp->logicalPath = fileToOpen;
|
||||||
fceufp->fullFilename = fileToOpen;
|
fceufp->fullFilename = fileToOpen;
|
||||||
fceufp->archiveIndex = -1;
|
fceufp->archiveIndex = -1;
|
||||||
fceufp->stream = (std::iostream*)fp;
|
fceufp->stream = fp;
|
||||||
FCEU_fseek(fceufp,0,SEEK_END);
|
FCEU_fseek(fceufp,0,SEEK_END);
|
||||||
fceufp->size = FCEU_ftell(fceufp);
|
fceufp->size = FCEU_ftell(fceufp);
|
||||||
FCEU_fseek(fceufp,0,SEEK_SET);
|
FCEU_fseek(fceufp,0,SEEK_SET);
|
||||||
@ -386,58 +386,26 @@ int FCEU_fclose(FCEUFILE *fp)
|
|||||||
|
|
||||||
uint64 FCEU_fread(void *ptr, size_t size, size_t nmemb, FCEUFILE *fp)
|
uint64 FCEU_fread(void *ptr, size_t size, size_t nmemb, FCEUFILE *fp)
|
||||||
{
|
{
|
||||||
fp->stream->read((char*)ptr,size*nmemb);
|
return fp->stream->fread((char*)ptr,size*nmemb);
|
||||||
uint32 read = fp->stream->gcount();
|
|
||||||
return read/size;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64 FCEU_fwrite(void *ptr, size_t size, size_t nmemb, FCEUFILE *fp)
|
uint64 FCEU_fwrite(void *ptr, size_t size, size_t nmemb, FCEUFILE *fp)
|
||||||
{
|
{
|
||||||
fp->stream->write((char*)ptr,size*nmemb);
|
fp->stream->fwrite((char*)ptr,size*nmemb);
|
||||||
//todo - how do we tell how many bytes we wrote?
|
//todo - how do we tell how many bytes we wrote?
|
||||||
return nmemb;
|
return nmemb;
|
||||||
}
|
}
|
||||||
|
|
||||||
int FCEU_fseek(FCEUFILE *fp, long offset, int whence)
|
int FCEU_fseek(FCEUFILE *fp, long offset, int whence)
|
||||||
{
|
{
|
||||||
//if(fp->type==1)
|
fp->stream->fseek(offset,whence);
|
||||||
//{
|
|
||||||
// return( (gzseek(fp->fp,offset,whence)>0)?0:-1);
|
|
||||||
//}
|
|
||||||
//else if(fp->type>=2)
|
|
||||||
//{
|
|
||||||
// MEMWRAP *wz;
|
|
||||||
// wz=(MEMWRAP*)fp->fp;
|
|
||||||
|
|
||||||
// switch(whence)
|
|
||||||
// {
|
|
||||||
// case SEEK_SET:if(offset>=(long)wz->size) //mbg merge 7/17/06 - added cast to long
|
|
||||||
// return(-1);
|
|
||||||
// wz->location=offset;break;
|
|
||||||
// case SEEK_CUR:if(offset+wz->location>wz->size)
|
|
||||||
// return (-1);
|
|
||||||
// wz->location+=offset;
|
|
||||||
// break;
|
|
||||||
// }
|
|
||||||
// return 0;
|
|
||||||
//}
|
|
||||||
//else
|
|
||||||
// return fseek((FILE *)fp->fp,offset,whence);
|
|
||||||
|
|
||||||
if(fp->mode == FCEUFILE::READ || fp->mode == FCEUFILE::READWRITE)
|
|
||||||
fp->stream->seekg(offset,(std::ios_base::seekdir)whence);
|
|
||||||
if(fp->mode == FCEUFILE::WRITE || fp->mode == FCEUFILE::READWRITE)
|
|
||||||
fp->stream->seekp(offset,(std::ios_base::seekdir)whence);
|
|
||||||
|
|
||||||
return FCEU_ftell(fp);
|
return FCEU_ftell(fp);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64 FCEU_ftell(FCEUFILE *fp)
|
uint64 FCEU_ftell(FCEUFILE *fp)
|
||||||
{
|
{
|
||||||
if(fp->mode == FCEUFILE::READ)
|
return fp->stream->ftell();
|
||||||
return fp->stream->tellg();
|
|
||||||
else
|
|
||||||
return fp->stream->tellp();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int FCEU_read16le(uint16 *val, FCEUFILE *fp)
|
int FCEU_read16le(uint16 *val, FCEUFILE *fp)
|
||||||
@ -452,7 +420,7 @@ int FCEU_read32le(uint32 *Bufo, FCEUFILE *fp)
|
|||||||
|
|
||||||
int FCEU_fgetc(FCEUFILE *fp)
|
int FCEU_fgetc(FCEUFILE *fp)
|
||||||
{
|
{
|
||||||
return fp->stream->get();
|
return fp->stream->fgetc();
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64 FCEU_fgetsize(FCEUFILE *fp)
|
uint64 FCEU_fgetsize(FCEUFILE *fp)
|
||||||
|
@ -4,13 +4,14 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
#include "utils/memorystream.h"
|
#include "emufile.h"
|
||||||
|
|
||||||
extern bool bindSavestate;
|
extern bool bindSavestate;
|
||||||
|
|
||||||
struct FCEUFILE {
|
struct FCEUFILE {
|
||||||
//the stream you can use to access the data
|
//the stream you can use to access the data
|
||||||
std::iostream *stream;
|
//std::iostream *stream;
|
||||||
|
EMUFILE *stream;
|
||||||
|
|
||||||
//the name of the file, or the logical name of the file within the archive
|
//the name of the file, or the logical name of the file within the archive
|
||||||
std::string filename;
|
std::string filename;
|
||||||
@ -51,25 +52,25 @@ struct FCEUFILE {
|
|||||||
} mode;
|
} mode;
|
||||||
|
|
||||||
//guarantees that the file contains a memorystream, and returns it for your convenience
|
//guarantees that the file contains a memorystream, and returns it for your convenience
|
||||||
memorystream* EnsureMemorystream() {
|
EMUFILE_MEMORY* EnsureMemorystream() {
|
||||||
memorystream* ret = dynamic_cast<memorystream*>(stream);
|
|
||||||
|
EMUFILE_MEMORY* ret = dynamic_cast<EMUFILE_MEMORY*>(stream);
|
||||||
if(ret) return ret;
|
if(ret) return ret;
|
||||||
|
|
||||||
//nope, we need to create it: copy the contents
|
//nope, we need to create it: copy the contents
|
||||||
ret = new memorystream(size);
|
ret = new EMUFILE_MEMORY(size);
|
||||||
stream->read(ret->buf(),size);
|
stream->fread(ret->buf(),size);
|
||||||
delete stream;
|
delete stream;
|
||||||
stream = ret;
|
stream = ret;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetStream(std::iostream *newstream) {
|
void SetStream(EMUFILE *newstream) {
|
||||||
if(stream) delete stream;
|
if(stream) delete stream;
|
||||||
stream = newstream;
|
stream = newstream;
|
||||||
//get the size of the stream
|
//get the size of the stream
|
||||||
stream->seekg(0,std::ios::end);
|
stream->fseek(0,SEEK_SET);
|
||||||
size = stream->tellg();
|
size = stream->size();
|
||||||
stream->seekg(0,std::ios::beg);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -56,7 +56,7 @@ void SexyFilter(int32 *in, int32 *out, int32 count)
|
|||||||
mul2=(24<<16)/FSettings.SndRate;
|
mul2=(24<<16)/FSettings.SndRate;
|
||||||
vmul=(FSettings.SoundVolume<<16)*3/4/100;
|
vmul=(FSettings.SoundVolume<<16)*3/4/100;
|
||||||
|
|
||||||
//FCEU_DispMessage("SoundVolume %d, vmul %d",FSettings.SoundVolume,vmul);
|
//FCEU_DispMessage("SoundVolume %d, vmul %d",0,FSettings.SoundVolume,vmul);
|
||||||
if(FSettings.soundq) vmul/=4;
|
if(FSettings.soundq) vmul/=4;
|
||||||
else vmul*=2; /* TODO: Increase volume in low quality sound rendering code itself */
|
else vmul*=2; /* TODO: Increase volume in low quality sound rendering code itself */
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
{0xdd8ced31,209,-1}, /* Power Rangers 3 */
|
{0xdd8ced31,209,-1}, /* Power Rangers 3 */
|
||||||
|
|
||||||
{0x0c47946d,210,1}, /* Chibi Maruko Chan */
|
{0x0c47946d,210,1}, /* Chibi Maruko Chan */
|
||||||
{0xbd523011,210,0}, /* Dream Master */
|
{0xbd523011,210,2}, /* Dream Master */ // may be wrong, but seems it solve most problems
|
||||||
{0xc247cc80,210,1}, /* Family Circuit '91 */
|
{0xc247cc80,210,1}, /* Family Circuit '91 */
|
||||||
{0x6ec51de5,210,1}, /* Famista '92 */
|
{0x6ec51de5,210,1}, /* Famista '92 */
|
||||||
{0xadffd64f,210,1}, /* Famista '93 */
|
{0xadffd64f,210,1}, /* Famista '93 */
|
||||||
|
@ -56,7 +56,7 @@ iNES_HEADER head ;
|
|||||||
|
|
||||||
|
|
||||||
#ifdef _USE_SHARED_MEMORY_
|
#ifdef _USE_SHARED_MEMORY_
|
||||||
HANDLE mapROM, mapVROM;
|
HANDLE mapROM = NULL, mapVROM = NULL;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
CartInfo iNESCart;
|
CartInfo iNESCart;
|
||||||
@ -132,33 +132,29 @@ void iNESGI(GI h) //bbit edited: removed static keyword
|
|||||||
{
|
{
|
||||||
if(mapROM)
|
if(mapROM)
|
||||||
{
|
{
|
||||||
UnmapViewOfFile(mapROM);
|
|
||||||
CloseHandle(mapROM);
|
CloseHandle(mapROM);
|
||||||
ROM=0;
|
mapROM = NULL;
|
||||||
|
UnmapViewOfFile(ROM);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
|
||||||
free(ROM);
|
free(ROM);
|
||||||
ROM = NULL;
|
ROM = NULL;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if(VROM)
|
if(VROM)
|
||||||
{
|
{
|
||||||
if(mapVROM)
|
if(mapVROM)
|
||||||
{
|
{
|
||||||
UnmapViewOfFile(mapVROM);
|
|
||||||
CloseHandle(mapVROM);
|
CloseHandle(mapVROM);
|
||||||
VROM=0;
|
mapVROM = NULL;
|
||||||
|
UnmapViewOfFile(VROM);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
|
||||||
free(VROM);
|
free(VROM);
|
||||||
VROM = NULL;
|
VROM = NULL;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
#else
|
#else
|
||||||
if(ROM) {free(ROM);ROM=0;}
|
if(ROM) {free(ROM); ROM = NULL;}
|
||||||
if(VROM) {free(VROM);VROM=0;}
|
if(VROM) {free(VROM); VROM = NULL;}
|
||||||
#endif
|
#endif
|
||||||
if(MapClose) MapClose();
|
if(MapClose) MapClose();
|
||||||
if(trainerpoo) {FCEU_gfree(trainerpoo);trainerpoo=0;}
|
if(trainerpoo) {FCEU_gfree(trainerpoo);trainerpoo=0;}
|
||||||
@ -230,6 +226,7 @@ static void SetInput(void)
|
|||||||
{0xde8fd935,SI_UNSET,SI_ZAPPER,SIFC_NONE}, // To the Earth
|
{0xde8fd935,SI_UNSET,SI_ZAPPER,SIFC_NONE}, // To the Earth
|
||||||
{0xedc3662b,SI_UNSET,SI_ZAPPER,SIFC_NONE}, // Operation Wolf
|
{0xedc3662b,SI_UNSET,SI_ZAPPER,SIFC_NONE}, // Operation Wolf
|
||||||
{0x2a6559a1,SI_UNSET,SI_ZAPPER,SIFC_NONE}, // Operation Wolf (J)
|
{0x2a6559a1,SI_UNSET,SI_ZAPPER,SIFC_NONE}, // Operation Wolf (J)
|
||||||
|
{0x4e959173,SI_UNSET,SI_ZAPPER,SIFC_NONE}, // Gotcha! - The Sport!
|
||||||
|
|
||||||
{0x23d17f5e,SI_GAMEPAD,SI_ZAPPER,SIFC_NONE}, // The Lone Ranger
|
{0x23d17f5e,SI_GAMEPAD,SI_ZAPPER,SIFC_NONE}, // The Lone Ranger
|
||||||
{0xb8b9aca3,SI_UNSET,SI_ZAPPER,SIFC_NONE}, // Wild Gunman
|
{0xb8b9aca3,SI_UNSET,SI_ZAPPER,SIFC_NONE}, // Wild Gunman
|
||||||
@ -425,8 +422,9 @@ static void CheckHInfo(void)
|
|||||||
#ifdef _USE_SHARED_MEMORY_
|
#ifdef _USE_SHARED_MEMORY_
|
||||||
if(mapVROM)
|
if(mapVROM)
|
||||||
{
|
{
|
||||||
UnmapViewOfFile(mapVROM);
|
|
||||||
CloseHandle(mapVROM);
|
CloseHandle(mapVROM);
|
||||||
|
UnmapViewOfFile(VROM);
|
||||||
|
mapVROM = NULL;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -435,7 +433,7 @@ static void CheckHInfo(void)
|
|||||||
#else
|
#else
|
||||||
free(VROM);
|
free(VROM);
|
||||||
#endif
|
#endif
|
||||||
VROM=0;
|
VROM = NULL;
|
||||||
tofix|=8;
|
tofix|=8;
|
||||||
}
|
}
|
||||||
if(MapperNo!=(moo[x].mapper&0xFF))
|
if(MapperNo!=(moo[x].mapper&0xFF))
|
||||||
@ -536,9 +534,9 @@ typedef struct {
|
|||||||
char* name;
|
char* name;
|
||||||
int number;
|
int number;
|
||||||
void (*init)(CartInfo *);
|
void (*init)(CartInfo *);
|
||||||
} BMAPPING;
|
} BMAPPINGLocal;
|
||||||
|
|
||||||
static BMAPPING bmap[] = {
|
static BMAPPINGLocal bmap[] = {
|
||||||
{"NROM", 0, NROM_Init},
|
{"NROM", 0, NROM_Init},
|
||||||
{"MMC1", 1, Mapper1_Init},
|
{"MMC1", 1, Mapper1_Init},
|
||||||
{"UNROM", 2, UNROM_Init},
|
{"UNROM", 2, UNROM_Init},
|
||||||
@ -741,48 +739,67 @@ int iNESLoad(const char *name, FCEUFILE *fp, int OverwriteVidMode)
|
|||||||
mapROM = CreateFileMapping((HANDLE)0xFFFFFFFF,NULL,PAGE_READWRITE, 0, ROM_size<<14,"fceu.ROM");
|
mapROM = CreateFileMapping((HANDLE)0xFFFFFFFF,NULL,PAGE_READWRITE, 0, ROM_size<<14,"fceu.ROM");
|
||||||
if(mapROM == NULL || GetLastError() == ERROR_ALREADY_EXISTS)
|
if(mapROM == NULL || GetLastError() == ERROR_ALREADY_EXISTS)
|
||||||
{
|
{
|
||||||
mapROM = NULL;
|
if((ROM = (uint8 *)FCEU_malloc(ROM_size<<14)) == NULL) return 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if((ROM = (uint8 *)MapViewOfFile(mapROM, FILE_MAP_WRITE, 0, 0, 0)) == NULL)
|
||||||
|
{
|
||||||
CloseHandle(mapROM);
|
CloseHandle(mapROM);
|
||||||
|
mapROM = NULL;
|
||||||
if(!(ROM=(uint8 *)FCEU_malloc(ROM_size<<14)))
|
if((ROM = (uint8 *)FCEU_malloc(ROM_size<<14)) == NULL) return 0;
|
||||||
return 0;
|
}
|
||||||
|
}
|
||||||
if(VROM_size)
|
if(VROM_size)
|
||||||
{
|
{
|
||||||
if(!(VROM=(uint8 *)FCEU_malloc(VROM_size<<13)))
|
mapVROM = CreateFileMapping((HANDLE)0xFFFFFFFF,NULL,PAGE_READWRITE, 0, VROM_size<<13,"fceu.VROM");
|
||||||
|
if(mapVROM == NULL || GetLastError() == ERROR_ALREADY_EXISTS)
|
||||||
{
|
{
|
||||||
|
if((VROM=(uint8 *)FCEU_malloc(VROM_size<<13)) == NULL)
|
||||||
|
{
|
||||||
|
if(mapROM)
|
||||||
|
{
|
||||||
|
UnmapViewOfFile(mapROM);
|
||||||
|
mapROM = NULL;
|
||||||
|
CloseHandle(ROM);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
free(ROM);
|
||||||
|
ROM = NULL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if((VROM = (uint8 *)MapViewOfFile(mapVROM, FILE_MAP_WRITE, 0, 0, 0)) == NULL)
|
||||||
|
{
|
||||||
|
CloseHandle(mapVROM);
|
||||||
|
mapVROM = NULL;
|
||||||
|
if((VROM=(uint8 *)FCEU_malloc(VROM_size<<13)) == NULL)
|
||||||
|
{
|
||||||
|
if(mapROM)
|
||||||
|
{
|
||||||
|
UnmapViewOfFile(mapROM);
|
||||||
|
mapROM = NULL;
|
||||||
|
CloseHandle(ROM);
|
||||||
|
}
|
||||||
|
else
|
||||||
free(ROM);
|
free(ROM);
|
||||||
ROM = NULL;
|
ROM = NULL;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
ROM = (uint8 *)MapViewOfFile(mapROM, FILE_MAP_WRITE, 0, 0, 0);
|
|
||||||
if( !ROM ) return 0;
|
|
||||||
|
|
||||||
if(VROM_size)
|
|
||||||
{
|
|
||||||
mapVROM = CreateFileMapping((HANDLE)0xFFFFFFFF,NULL,PAGE_READWRITE, 0, VROM_size<<13,"fceu.VROM");
|
|
||||||
VROM = (uint8 *)MapViewOfFile(mapVROM, FILE_MAP_WRITE, 0, 0, 0);
|
|
||||||
if( !VROM )
|
|
||||||
{
|
|
||||||
UnmapViewOfFile(mapROM);
|
|
||||||
CloseHandle(mapROM);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
if(!(ROM=(uint8 *)FCEU_malloc(ROM_size<<14)))
|
if((ROM = (uint8 *)FCEU_malloc(ROM_size<<14)) == NULL) return 0;
|
||||||
return 0;
|
|
||||||
|
|
||||||
if(VROM_size)
|
if(VROM_size)
|
||||||
{
|
{
|
||||||
if(!(VROM=(uint8 *)FCEU_malloc(VROM_size<<13)))
|
if((VROM = (uint8 *)FCEU_malloc(VROM_size<<13)) == NULL)
|
||||||
{
|
{
|
||||||
free(ROM);
|
free(ROM);
|
||||||
|
ROM = NULL;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -831,10 +848,23 @@ int iNESLoad(const char *name, FCEUFILE *fp, int OverwriteVidMode)
|
|||||||
FCEU_printf("%02x",iNESCart.MD5[x]);
|
FCEU_printf("%02x",iNESCart.MD5[x]);
|
||||||
FCEU_printf("\n");
|
FCEU_printf("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char* mappername = "Not Listed";
|
||||||
|
|
||||||
|
for(int mappertest=0;mappertest< (sizeof bmap / sizeof bmap[0]) - 1;mappertest++)
|
||||||
|
{
|
||||||
|
if (bmap[mappertest].number == MapperNo) {
|
||||||
|
mappername = bmap[mappertest].name;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
FCEU_printf(" Mapper #: %d\n Mapper name: %s\n Mirroring: %s\n",
|
FCEU_printf(" Mapper #: %d\n Mapper name: %s\n Mirroring: %s\n",
|
||||||
MapperNo, bmap[MapperNo].name, Mirroring==2?"None(Four-screen)":Mirroring?"Vertical":"Horizontal");
|
MapperNo, mappername, Mirroring==2?"None (Four-screen)":Mirroring?"Vertical":"Horizontal");
|
||||||
if(head.ROM_type&2) FCEU_printf(" Battery-backed.\n");
|
|
||||||
if(head.ROM_type&4) FCEU_printf(" Trained.\n");
|
FCEU_printf(" Battery-backed: %s\n", (head.ROM_type&2)?"Yes":"No");
|
||||||
|
FCEU_printf(" Trained: %s\n", (head.ROM_type&4)?"Yes":"No");
|
||||||
|
// (head.ROM_type&8) = Mirroring: None(Four-screen)
|
||||||
|
|
||||||
SetInput();
|
SetInput();
|
||||||
CheckHInfo();
|
CheckHInfo();
|
||||||
@ -880,6 +910,14 @@ int iNESLoad(const char *name, FCEUFILE *fp, int OverwriteVidMode)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
strcpy(LoadedRomFName,name); //bbit edited: line added
|
strcpy(LoadedRomFName,name); //bbit edited: line added
|
||||||
|
|
||||||
|
// Extract Filename only. Should account for Windows/Unix this way.
|
||||||
|
if (strrchr(name, '/')) {
|
||||||
|
name = strrchr(name, '/') + 1;
|
||||||
|
} else if(strrchr(name, '\\')) {
|
||||||
|
name = strrchr(name, '\\') + 1;
|
||||||
|
}
|
||||||
|
|
||||||
GameInterface=iNESGI;
|
GameInterface=iNESGI;
|
||||||
FCEU_printf("\n");
|
FCEU_printf("\n");
|
||||||
|
|
||||||
@ -1443,7 +1481,7 @@ static void iNESPower(void)
|
|||||||
|
|
||||||
static int NewiNES_Init(int num)
|
static int NewiNES_Init(int num)
|
||||||
{
|
{
|
||||||
BMAPPING *tmp=bmap;
|
BMAPPINGLocal *tmp=bmap;
|
||||||
|
|
||||||
if(GameInfo->type == GIT_VSUNI)
|
if(GameInfo->type == GIT_VSUNI)
|
||||||
AddExState(FCEUVSUNI_STATEINFO, ~0, 0, 0);
|
AddExState(FCEUVSUNI_STATEINFO, ~0, 0, 0);
|
||||||
@ -1470,14 +1508,19 @@ static int NewiNES_Init(int num)
|
|||||||
{
|
{
|
||||||
CloseHandle(mapVROM);
|
CloseHandle(mapVROM);
|
||||||
mapVROM = NULL;
|
mapVROM = NULL;
|
||||||
VROM=(uint8 *)malloc(CHRRAMSize);
|
if((VROM = (uint8 *)malloc(CHRRAMSize)) == NULL) return 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
VROM = (uint8 *)MapViewOfFile(mapVROM, FILE_MAP_WRITE, 0, 0, 0);
|
if((VROM = (uint8 *)MapViewOfFile(mapVROM, FILE_MAP_WRITE, 0, 0, 0)) == NULL)
|
||||||
|
{
|
||||||
|
CloseHandle(mapVROM);
|
||||||
|
mapVROM = NULL;
|
||||||
|
if((VROM = (uint8 *)malloc(CHRRAMSize)) == NULL) return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
VROM=(uint8 *)malloc(CHRRAMSize);
|
if((VROM = (uint8 *)malloc(CHRRAMSize)) == NULL) return 0;
|
||||||
#endif
|
#endif
|
||||||
UNIFchrrama=VROM;
|
UNIFchrrama=VROM;
|
||||||
SetupCartCHRMapping(0,VROM,CHRRAMSize,1);
|
SetupCartCHRMapping(0,VROM,CHRRAMSize,1);
|
||||||
@ -1486,9 +1529,9 @@ static int NewiNES_Init(int num)
|
|||||||
if(head.ROM_type&8)
|
if(head.ROM_type&8)
|
||||||
AddExState(ExtraNTARAM, 2048, 0, "EXNR");
|
AddExState(ExtraNTARAM, 2048, 0, "EXNR");
|
||||||
tmp->init(&iNESCart);
|
tmp->init(&iNESCart);
|
||||||
return(1);
|
return 1;
|
||||||
}
|
}
|
||||||
tmp++;
|
tmp++;
|
||||||
}
|
}
|
||||||
return(0);
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -85,6 +85,8 @@ static uint8 joy_readbit[2];
|
|||||||
uint8 joy[4]={0,0,0,0}; //HACK - should be static but movie needs it
|
uint8 joy[4]={0,0,0,0}; //HACK - should be static but movie needs it
|
||||||
static uint8 LastStrobe;
|
static uint8 LastStrobe;
|
||||||
|
|
||||||
|
bool replaceP2StartWithMicrophone = false;
|
||||||
|
|
||||||
#ifdef _USE_SHARED_MEMORY_
|
#ifdef _USE_SHARED_MEMORY_
|
||||||
static uint32 BotPointer = 0; //mbg merge 7/18/06 changed to uint32
|
static uint32 BotPointer = 0; //mbg merge 7/18/06 changed to uint32
|
||||||
#endif
|
#endif
|
||||||
@ -107,13 +109,36 @@ static DECLFR(JPRead)
|
|||||||
{
|
{
|
||||||
lagFlag = 0;
|
lagFlag = 0;
|
||||||
uint8 ret=0;
|
uint8 ret=0;
|
||||||
|
static bool microphone = false;
|
||||||
|
|
||||||
ret|=joyports[A&1].driver->Read(A&1);
|
ret|=joyports[A&1].driver->Read(A&1);
|
||||||
|
|
||||||
|
// Test if the port 2 start button is being pressed.
|
||||||
|
// On a famicom, port 2 start shouldn't exist, so this removes it.
|
||||||
|
// Games can't automatically be checked for NES/Famicom status,
|
||||||
|
// so it's an all-encompassing change in the input config menu.
|
||||||
|
if ((replaceP2StartWithMicrophone) && (A&1) && (joy_readbit[1] == 4)) {
|
||||||
|
// Nullify Port 2 Start Button
|
||||||
|
ret&=0xFE;
|
||||||
|
}
|
||||||
|
|
||||||
if(portFC.driver)
|
if(portFC.driver)
|
||||||
ret = portFC.driver->Read(A&1,ret);
|
ret = portFC.driver->Read(A&1,ret);
|
||||||
|
|
||||||
|
// Not verified against hardware.
|
||||||
|
if (replaceP2StartWithMicrophone) {
|
||||||
|
if (joy[1]&8) {
|
||||||
|
microphone = !microphone;
|
||||||
|
if (microphone) {
|
||||||
|
ret|=4;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
microphone = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ret|=X.DB&0xC0;
|
ret|=X.DB&0xC0;
|
||||||
|
|
||||||
return(ret);
|
return(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -471,6 +496,10 @@ bool FCEUI_GetInputFourscore()
|
|||||||
{
|
{
|
||||||
return FSAttached;
|
return FSAttached;
|
||||||
}
|
}
|
||||||
|
bool FCEUI_GetInputMicrophone()
|
||||||
|
{
|
||||||
|
return replaceP2StartWithMicrophone;
|
||||||
|
}
|
||||||
void FCEUI_SetInputFourscore(bool attachFourscore)
|
void FCEUI_SetInputFourscore(bool attachFourscore)
|
||||||
{
|
{
|
||||||
FSAttached = attachFourscore;
|
FSAttached = attachFourscore;
|
||||||
@ -603,6 +632,12 @@ static void LaunchTraceLogger(void);
|
|||||||
static void LaunchCodeDataLogger(void);
|
static void LaunchCodeDataLogger(void);
|
||||||
static void LaunchRamWatch(void);
|
static void LaunchRamWatch(void);
|
||||||
static void LaunchRamSearch(void);
|
static void LaunchRamSearch(void);
|
||||||
|
static void RamSearchOpLT(void);
|
||||||
|
static void RamSearchOpGT(void);
|
||||||
|
static void RamSearchOpLTE(void);
|
||||||
|
static void RamSearchOpGTE(void);
|
||||||
|
static void RamSearchOpEQ(void);
|
||||||
|
static void RamSearchOpNE(void);
|
||||||
static void FA_SkipLag(void);
|
static void FA_SkipLag(void);
|
||||||
static void OpenRom(void);
|
static void OpenRom(void);
|
||||||
static void CloseRom(void);
|
static void CloseRom(void);
|
||||||
@ -725,6 +760,12 @@ struct EMUCMDTABLE FCEUI_CommandTable[]=
|
|||||||
{ EMUCMD_MISC_TOGGLEFULLSCREEN, EMUCMDTYPE_MISC, ToggleFullscreen, 0, 0, "Toggle Fullscreen", 0},
|
{ EMUCMD_MISC_TOGGLEFULLSCREEN, EMUCMDTYPE_MISC, ToggleFullscreen, 0, 0, "Toggle Fullscreen", 0},
|
||||||
{ EMUCMD_TOOL_OPENRAMWATCH, EMUCMDTYPE_TOOL, LaunchRamWatch, 0, 0, "Open Ram Watch", 0},
|
{ EMUCMD_TOOL_OPENRAMWATCH, EMUCMDTYPE_TOOL, LaunchRamWatch, 0, 0, "Open Ram Watch", 0},
|
||||||
{ EMUCMD_TOOL_OPENRAMSEARCH, EMUCMDTYPE_TOOL, LaunchRamSearch, 0, 0, "Open Ram Search", 0},
|
{ EMUCMD_TOOL_OPENRAMSEARCH, EMUCMDTYPE_TOOL, LaunchRamSearch, 0, 0, "Open Ram Search", 0},
|
||||||
|
{ EMUCMD_TOOL_RAMSEARCHLT, EMUCMDTYPE_TOOL, RamSearchOpLT, 0, 0, "Ram Search - Less Than", 0},
|
||||||
|
{ EMUCMD_TOOL_RAMSEARCHGT, EMUCMDTYPE_TOOL, RamSearchOpGT, 0, 0, "Ram Search - Greater Than", 0},
|
||||||
|
{ EMUCMD_TOOL_RAMSEARCHLTE, EMUCMDTYPE_TOOL, RamSearchOpLTE, 0, 0, "Ram Search - Less Than or Equal", 0},
|
||||||
|
{ EMUCMD_TOOL_RAMSEARCHGTE, EMUCMDTYPE_TOOL, RamSearchOpGTE, 0, 0, "Ram Search - Greater Than or Equal", 0},
|
||||||
|
{ EMUCMD_TOOL_RAMSEARCHEQ, EMUCMDTYPE_TOOL, RamSearchOpEQ, 0, 0, "Ram Search - Equal", 0},
|
||||||
|
{ EMUCMD_TOOL_RAMSEARCHNE, EMUCMDTYPE_TOOL, RamSearchOpNE, 0, 0, "Ram Search - Not Equal", 0},
|
||||||
};
|
};
|
||||||
|
|
||||||
#define NUM_EMU_CMDS (sizeof(FCEUI_CommandTable)/sizeof(FCEUI_CommandTable[0]))
|
#define NUM_EMU_CMDS (sizeof(FCEUI_CommandTable)/sizeof(FCEUI_CommandTable[0]))
|
||||||
@ -758,7 +799,7 @@ void FCEUI_HandleEmuCommands(TestCommandState* testfn)
|
|||||||
|
|
||||||
static void CommandUnImpl(void)
|
static void CommandUnImpl(void)
|
||||||
{
|
{
|
||||||
FCEU_DispMessage("command '%s' unimplemented.", FCEUI_CommandTable[i].name);
|
FCEU_DispMessage("command '%s' unimplemented.",0, FCEUI_CommandTable[i].name);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void CommandToggleDip(void)
|
static void CommandToggleDip(void)
|
||||||
@ -925,7 +966,59 @@ static void LaunchRamSearch(void)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void RamSearchOpLT(void) {
|
||||||
|
#ifdef WIN32
|
||||||
|
extern void SetSearchType(int SearchType);
|
||||||
|
extern void DoRamSearchOperation();
|
||||||
|
SetSearchType(0);
|
||||||
|
DoRamSearchOperation();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static void RamSearchOpGT(void) {
|
||||||
|
#ifdef WIN32
|
||||||
|
extern void SetSearchType(int SearchType);
|
||||||
|
extern void DoRamSearchOperation();
|
||||||
|
SetSearchType(1);
|
||||||
|
DoRamSearchOperation();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static void RamSearchOpLTE(void) {
|
||||||
|
#ifdef WIN32
|
||||||
|
extern void SetSearchType(int SearchType);
|
||||||
|
extern void DoRamSearchOperation();
|
||||||
|
SetSearchType(2);
|
||||||
|
DoRamSearchOperation();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static void RamSearchOpGTE(void) {
|
||||||
|
#ifdef WIN32
|
||||||
|
extern void SetSearchType(int SearchType);
|
||||||
|
extern void DoRamSearchOperation();
|
||||||
|
SetSearchType(3);
|
||||||
|
DoRamSearchOperation();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static void RamSearchOpEQ(void) {
|
||||||
|
#ifdef WIN32
|
||||||
|
extern void SetSearchType(int SearchType);
|
||||||
|
extern void DoRamSearchOperation();
|
||||||
|
SetSearchType(4);
|
||||||
|
DoRamSearchOperation();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static void RamSearchOpNE(void) {
|
||||||
|
#ifdef WIN32
|
||||||
|
extern void SetSearchType(int SearchType);
|
||||||
|
extern void DoRamSearchOperation();
|
||||||
|
SetSearchType(5);
|
||||||
|
DoRamSearchOperation();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
static void FA_SkipLag(void)
|
static void FA_SkipLag(void)
|
||||||
{
|
{
|
||||||
@ -950,8 +1043,8 @@ static void CloseRom(void)
|
|||||||
static void MovieSubtitleToggle(void)
|
static void MovieSubtitleToggle(void)
|
||||||
{
|
{
|
||||||
movieSubtitles ^= 1;
|
movieSubtitles ^= 1;
|
||||||
if (movieSubtitles) FCEU_DispMessage("Movie subtitles on");
|
if (movieSubtitles) FCEU_DispMessage("Movie subtitles on",0);
|
||||||
else FCEU_DispMessage("Movie subtitles off");
|
else FCEU_DispMessage("Movie subtitles off",0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void UndoRedoSavestate(void)
|
static void UndoRedoSavestate(void)
|
||||||
|
@ -221,6 +221,12 @@ enum EMUCMD
|
|||||||
EMUCMD_MISC_TOGGLEFULLSCREEN,
|
EMUCMD_MISC_TOGGLEFULLSCREEN,
|
||||||
EMUCMD_TOOL_OPENRAMWATCH,
|
EMUCMD_TOOL_OPENRAMWATCH,
|
||||||
EMUCMD_TOOL_OPENRAMSEARCH,
|
EMUCMD_TOOL_OPENRAMSEARCH,
|
||||||
|
EMUCMD_TOOL_RAMSEARCHLT,
|
||||||
|
EMUCMD_TOOL_RAMSEARCHGT,
|
||||||
|
EMUCMD_TOOL_RAMSEARCHLTE,
|
||||||
|
EMUCMD_TOOL_RAMSEARCHGTE,
|
||||||
|
EMUCMD_TOOL_RAMSEARCHEQ,
|
||||||
|
EMUCMD_TOOL_RAMSEARCHNE,
|
||||||
EMUCMD_MAX
|
EMUCMD_MAX
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -269,4 +275,3 @@ extern bool turbo;
|
|||||||
void LagCounterReset();
|
void LagCounterReset();
|
||||||
|
|
||||||
#endif //_INPUT_H_
|
#endif //_INPUT_H_
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
* (VRC4 mapper)
|
* (VRCII mapper)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "mapinc.h"
|
#include "mapinc.h"
|
||||||
@ -26,8 +26,20 @@
|
|||||||
#define K4sel mapbyte1[0]
|
#define K4sel mapbyte1[0]
|
||||||
|
|
||||||
static int acount=0;
|
static int acount=0;
|
||||||
|
static int weirdo=0;
|
||||||
static DECLFW(Mapper25_write)
|
static DECLFW(Mapper25_write)
|
||||||
{
|
{
|
||||||
|
if(A==0xC007)
|
||||||
|
{
|
||||||
|
weirdo=8; // Ganbare Goemon Gaiden does strange things!!! at the end credits
|
||||||
|
// quick dirty hack, seems there is no other games with such PCB, so
|
||||||
|
// we never know if it will not work for something else lol
|
||||||
|
VROM_BANK1(0x0000,0xFC);
|
||||||
|
VROM_BANK1(0x0400,0xFD);
|
||||||
|
VROM_BANK1(0x0800,0xFF);
|
||||||
|
VROM_BANK1(0x0c00,0xCF);
|
||||||
|
}
|
||||||
|
|
||||||
A=(A&0xF003)|((A&0xC)>>2);
|
A=(A&0xF003)|((A&0xC)>>2);
|
||||||
|
|
||||||
if((A&0xF000)==0xA000)
|
if((A&0xF000)==0xA000)
|
||||||
@ -38,6 +50,9 @@ static DECLFW(Mapper25_write)
|
|||||||
|
|
||||||
K4buf[x]&=(0xF0)>>((A&2)<<1);
|
K4buf[x]&=(0xF0)>>((A&2)<<1);
|
||||||
K4buf[x]|=(V&0xF)<<((A&2)<<1);
|
K4buf[x]|=(V&0xF)<<((A&2)<<1);
|
||||||
|
if(weirdo)
|
||||||
|
weirdo--;
|
||||||
|
else
|
||||||
VROM_BANK1(x<<10,K4buf[x]);
|
VROM_BANK1(x<<10,K4buf[x]);
|
||||||
}
|
}
|
||||||
else if((A&0xF000)==0x8000)
|
else if((A&0xF000)==0x8000)
|
||||||
|
@ -39,7 +39,7 @@ static DECLFR(SUN5AWRAM)
|
|||||||
{
|
{
|
||||||
if((sungah&0xC0)==0x40)
|
if((sungah&0xC0)==0x40)
|
||||||
return X.DB;
|
return X.DB;
|
||||||
return CartBR(A);
|
return CartBROB(A);
|
||||||
}
|
}
|
||||||
|
|
||||||
static DECLFW(Mapper69_SWL)
|
static DECLFW(Mapper69_SWL)
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -37,7 +37,7 @@ typedef struct
|
|||||||
int movie_version; // version of the movie format in the file
|
int movie_version; // version of the movie format in the file
|
||||||
uint32 num_frames;
|
uint32 num_frames;
|
||||||
uint32 rerecord_count;
|
uint32 rerecord_count;
|
||||||
bool poweron, pal, nosynchack;
|
bool poweron, pal, nosynchack, ppuflag;
|
||||||
bool reset; //mbg 6/21/08 - this flag isnt used anymore.. but maybe one day we can scan it out of the first record in the movie file
|
bool reset; //mbg 6/21/08 - this flag isnt used anymore.. but maybe one day we can scan it out of the first record in the movie file
|
||||||
uint32 emu_version_used; // 9813 = 0.98.13
|
uint32 emu_version_used; // 9813 = 0.98.13
|
||||||
MD5DATA md5_of_rom_used;
|
MD5DATA md5_of_rom_used;
|
||||||
@ -58,7 +58,8 @@ enum EMOVIEMODE
|
|||||||
MOVIEMODE_INACTIVE = 1,
|
MOVIEMODE_INACTIVE = 1,
|
||||||
MOVIEMODE_RECORD = 2,
|
MOVIEMODE_RECORD = 2,
|
||||||
MOVIEMODE_PLAY = 4,
|
MOVIEMODE_PLAY = 4,
|
||||||
MOVIEMODE_TASEDIT = 8
|
MOVIEMODE_TASEDIT = 8,
|
||||||
|
MOVIEMODE_FINISHED = 16
|
||||||
};
|
};
|
||||||
|
|
||||||
enum EMOVIECMD
|
enum EMOVIECMD
|
||||||
@ -72,27 +73,31 @@ enum EMOVIECMD
|
|||||||
EMOVIEMODE FCEUMOV_Mode();
|
EMOVIEMODE FCEUMOV_Mode();
|
||||||
bool FCEUMOV_Mode(EMOVIEMODE modemask);
|
bool FCEUMOV_Mode(EMOVIEMODE modemask);
|
||||||
bool FCEUMOV_Mode(int modemask);
|
bool FCEUMOV_Mode(int modemask);
|
||||||
inline bool FCEUMOV_IsPlaying() { return FCEUMOV_Mode(MOVIEMODE_PLAY); }
|
inline bool FCEUMOV_IsPlaying() { return (FCEUMOV_Mode(MOVIEMODE_PLAY|MOVIEMODE_FINISHED)); }
|
||||||
inline bool FCEUMOV_IsRecording() { return FCEUMOV_Mode(MOVIEMODE_RECORD); }
|
inline bool FCEUMOV_IsRecording() { return FCEUMOV_Mode(MOVIEMODE_RECORD); }
|
||||||
|
inline bool FCEUMOV_IsFinished() { return FCEUMOV_Mode(MOVIEMODE_FINISHED);}
|
||||||
|
inline bool FCEUMOV_IsLoaded() { return (FCEUMOV_Mode(MOVIEMODE_PLAY|MOVIEMODE_RECORD|MOVIEMODE_FINISHED)); }
|
||||||
|
|
||||||
bool FCEUMOV_ShouldPause(void);
|
bool FCEUMOV_ShouldPause(void);
|
||||||
int FCEUMOV_GetFrame(void);
|
int FCEUMOV_GetFrame(void);
|
||||||
int FCEUI_GetLagCount(void);
|
int FCEUI_GetLagCount(void);
|
||||||
bool FCEUI_GetLagged(void);
|
bool FCEUI_GetLagged(void);
|
||||||
|
|
||||||
int FCEUMOV_WriteState(std::ostream* os);
|
int FCEUMOV_WriteState(EMUFILE* os);
|
||||||
bool FCEUMOV_ReadState(std::istream* is, uint32 size);
|
bool FCEUMOV_ReadState(EMUFILE* is, uint32 size);
|
||||||
void FCEUMOV_PreLoad();
|
void FCEUMOV_PreLoad();
|
||||||
bool FCEUMOV_PostLoad();
|
bool FCEUMOV_PostLoad();
|
||||||
|
|
||||||
void FCEUMOV_EnterTasEdit();
|
void FCEUMOV_EnterTasEdit();
|
||||||
void FCEUMOV_ExitTasEdit();
|
void FCEUMOV_ExitTasEdit();
|
||||||
|
bool FCEUMOV_FromPoweron();
|
||||||
|
|
||||||
class MovieData;
|
class MovieData;
|
||||||
class MovieRecord
|
class MovieRecord
|
||||||
{
|
{
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
MovieRecord();
|
||||||
ValueArray<uint8,4> joysticks;
|
ValueArray<uint8,4> joysticks;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
@ -135,17 +140,15 @@ public:
|
|||||||
return (joysticks[joy] & mask(bit))!=0;
|
return (joysticks[joy] & mask(bit))!=0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Compare(MovieRecord& compareRec);
|
||||||
void clear();
|
void clear();
|
||||||
|
|
||||||
//a waste of memory in lots of cases.. maybe make it a pointer later?
|
void parse(MovieData* md, EMUFILE* is);
|
||||||
std::vector<char> savestate;
|
bool parseBinary(MovieData* md, EMUFILE* is);
|
||||||
|
void dump(MovieData* md, EMUFILE* os, int index);
|
||||||
void parse(MovieData* md, std::istream* is);
|
void dumpBinary(MovieData* md, EMUFILE* os, int index);
|
||||||
bool parseBinary(MovieData* md, std::istream* is);
|
void parseJoy(EMUFILE* is, uint8& joystate);
|
||||||
void dump(MovieData* md, std::ostream* os, int index);
|
void dumpJoy(EMUFILE* os, uint8 joystate);
|
||||||
void dumpBinary(MovieData* md, std::ostream* os, int index);
|
|
||||||
void parseJoy(std::istream* is, uint8& joystate);
|
|
||||||
void dumpJoy(std::ostream* os, uint8 joystate);
|
|
||||||
|
|
||||||
static const char mnemonics[8];
|
static const char mnemonics[8];
|
||||||
|
|
||||||
@ -157,17 +160,19 @@ class MovieData
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
MovieData();
|
MovieData();
|
||||||
|
// Default Values: MovieData::MovieData()
|
||||||
|
|
||||||
int version;
|
int version;
|
||||||
int emuVersion;
|
int emuVersion;
|
||||||
int fds;
|
int fds;
|
||||||
//todo - somehow force mutual exclusion for poweron and reset (with an error in the parser)
|
//todo - somehow force mutual exclusion for poweron and reset (with an error in the parser)
|
||||||
bool palFlag;
|
bool palFlag;
|
||||||
|
bool PPUflag;
|
||||||
MD5DATA romChecksum;
|
MD5DATA romChecksum;
|
||||||
std::string romFilename;
|
std::string romFilename;
|
||||||
std::vector<char> savestate;
|
std::vector<uint8> savestate;
|
||||||
std::vector<MovieRecord> records;
|
std::vector<MovieRecord> records;
|
||||||
|
std::vector<std::vector<uint8> > savestates;
|
||||||
std::vector<std::wstring> comments;
|
std::vector<std::wstring> comments;
|
||||||
std::vector<std::string> subtitles;
|
std::vector<std::string> subtitles;
|
||||||
//this is the RERECORD COUNT. please rename variable.
|
//this is the RERECORD COUNT. please rename variable.
|
||||||
@ -181,6 +186,8 @@ public:
|
|||||||
int ports[3];
|
int ports[3];
|
||||||
//whether fourscore is enabled
|
//whether fourscore is enabled
|
||||||
bool fourscore;
|
bool fourscore;
|
||||||
|
//whether microphone is enabled
|
||||||
|
bool microphone;
|
||||||
|
|
||||||
//----TasEdit stuff---
|
//----TasEdit stuff---
|
||||||
int greenZoneCount;
|
int greenZoneCount;
|
||||||
@ -219,15 +226,18 @@ public:
|
|||||||
|
|
||||||
void truncateAt(int frame);
|
void truncateAt(int frame);
|
||||||
void installValue(std::string& key, std::string& val);
|
void installValue(std::string& key, std::string& val);
|
||||||
int dump(std::ostream* os, bool binary);
|
int dump(EMUFILE* os, bool binary);
|
||||||
int dumpGreenzone(std::ostream *os, bool binary);
|
int dumpGreenzone(EMUFILE *os, bool binary);
|
||||||
int loadGreenzone(std::istream *is, bool binary);
|
int loadGreenzone(EMUFILE *is, bool binary);
|
||||||
|
|
||||||
void clearRecordRange(int start, int len);
|
void clearRecordRange(int start, int len);
|
||||||
void insertEmpty(int at, int frames);
|
void insertEmpty(int at, int frames);
|
||||||
|
|
||||||
static bool loadSavestateFrom(std::vector<char>* buf);
|
static bool loadSavestateFrom(std::vector<uint8>* buf);
|
||||||
static void dumpSavestateTo(std::vector<char>* buf, int compressionLevel);
|
static void dumpSavestateTo(std::vector<uint8>* buf, int compressionLevel);
|
||||||
|
|
||||||
|
bool loadTasSavestate(int frame);
|
||||||
|
void storeTasSavestate(int frame, int compression_level);
|
||||||
void TryDumpIncremental();
|
void TryDumpIncremental();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -250,8 +260,8 @@ extern bool freshMovie;
|
|||||||
extern bool movie_readonly;
|
extern bool movie_readonly;
|
||||||
extern bool autoMovieBackup;
|
extern bool autoMovieBackup;
|
||||||
extern int pauseframe;
|
extern int pauseframe;
|
||||||
|
extern bool fullSaveStateLoads;
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
bool CheckFileExists(const char* filename); //Receives a filename (fullpath) and checks to see if that file exists
|
|
||||||
void FCEUI_MakeBackupMovie(bool dispMessage);
|
void FCEUI_MakeBackupMovie(bool dispMessage);
|
||||||
void FCEUI_CreateMovieFile(std::string fn);
|
void FCEUI_CreateMovieFile(std::string fn);
|
||||||
void FCEUI_SaveMovie(const char *fname, EMOVIE_FLAG flags, std::wstring author);
|
void FCEUI_SaveMovie(const char *fname, EMOVIE_FLAG flags, std::wstring author);
|
||||||
@ -259,7 +269,7 @@ bool FCEUI_LoadMovie(const char *fname, bool read_only, bool tasedit, int _stopf
|
|||||||
void FCEUI_MoviePlayFromBeginning(void);
|
void FCEUI_MoviePlayFromBeginning(void);
|
||||||
void FCEUI_StopMovie(void);
|
void FCEUI_StopMovie(void);
|
||||||
bool FCEUI_MovieGetInfo(FCEUFILE* fp, MOVIE_INFO& info, bool skipFrameCount = false);
|
bool FCEUI_MovieGetInfo(FCEUFILE* fp, MOVIE_INFO& info, bool skipFrameCount = false);
|
||||||
char* FCEUI_MovieGetCurrentName(int addSlotNumber);
|
//char* FCEUI_MovieGetCurrentName(int addSlotNumber);
|
||||||
void FCEUI_MovieToggleReadOnly(void);
|
void FCEUI_MovieToggleReadOnly(void);
|
||||||
bool FCEUI_GetMovieToggleReadOnly();
|
bool FCEUI_GetMovieToggleReadOnly();
|
||||||
void FCEUI_SetMovieToggleReadOnly(bool which);
|
void FCEUI_SetMovieToggleReadOnly(bool which);
|
||||||
@ -269,7 +279,7 @@ std::string FCEUI_GetMovieName(void);
|
|||||||
void FCEUI_MovieToggleFrameDisplay();
|
void FCEUI_MovieToggleFrameDisplay();
|
||||||
void FCEUI_ToggleInputDisplay(void);
|
void FCEUI_ToggleInputDisplay(void);
|
||||||
|
|
||||||
void LoadSubtitles(MovieData);
|
void LoadSubtitles(MovieData &);
|
||||||
void ProcessSubtitles(void);
|
void ProcessSubtitles(void);
|
||||||
void FCEU_DisplaySubtitles(char *format, ...);
|
void FCEU_DisplaySubtitles(char *format, ...);
|
||||||
|
|
||||||
|
@ -50,7 +50,7 @@ static int netdcount;
|
|||||||
|
|
||||||
static void NetError(void)
|
static void NetError(void)
|
||||||
{
|
{
|
||||||
FCEU_DispMessage("Network error/connection lost!");
|
FCEU_DispMessage("Network error/connection lost!",0);
|
||||||
FCEUD_NetworkClose();
|
FCEUD_NetworkClose();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -310,7 +310,7 @@ void NetplayUpdate(uint8 *joyp)
|
|||||||
if(FCEUSS_LoadFP(fp,SSLOADPARAM_BACKUP))
|
if(FCEUSS_LoadFP(fp,SSLOADPARAM_BACKUP))
|
||||||
{
|
{
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
FCEU_DispMessage("Remote state loaded.");
|
FCEU_DispMessage("Remote state loaded.",0);
|
||||||
} else FCEUD_PrintError("File error. (K)ill, (M)aim, (D)estroy?");
|
} else FCEUD_PrintError("File error. (K)ill, (M)aim, (D)estroy?");
|
||||||
}
|
}
|
||||||
break;*/
|
break;*/
|
||||||
|
@ -790,8 +790,31 @@ static DECLFR(A2007)
|
|||||||
if(!fceuindbg)
|
if(!fceuindbg)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
if(INC32) RefreshAddr+=32;
|
if((ScreenON || SpriteON) && (scanline < 240))
|
||||||
else RefreshAddr++;
|
{
|
||||||
|
uint32 rad=RefreshAddr;
|
||||||
|
|
||||||
|
if((rad&0x7000)==0x7000)
|
||||||
|
{
|
||||||
|
rad^=0x7000;
|
||||||
|
if((rad&0x3E0)==0x3A0)
|
||||||
|
rad^=0xBA0;
|
||||||
|
else if((rad&0x3E0)==0x3e0)
|
||||||
|
rad^=0x3e0;
|
||||||
|
else
|
||||||
|
rad+=0x20;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
rad+=0x1000;
|
||||||
|
RefreshAddr=rad;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (INC32)
|
||||||
|
RefreshAddr+=32;
|
||||||
|
else
|
||||||
|
RefreshAddr++;
|
||||||
|
}
|
||||||
if(PPU_hook) PPU_hook(RefreshAddr&0x3fff);
|
if(PPU_hook) PPU_hook(RefreshAddr&0x3fff);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1337,21 +1360,15 @@ static void Fixit1(void)
|
|||||||
{
|
{
|
||||||
rad ^= 0x7000;
|
rad ^= 0x7000;
|
||||||
if((rad & 0x3E0) == 0x3A0)
|
if((rad & 0x3E0) == 0x3A0)
|
||||||
{
|
rad ^= 0xBA0;
|
||||||
rad^=0x3A0;
|
else if((rad & 0x3E0) == 0x3e0)
|
||||||
rad^=0x800;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if((rad&0x3E0)==0x3e0)
|
|
||||||
rad ^= 0x3e0;
|
rad ^= 0x3e0;
|
||||||
else rad+=0x20;
|
else
|
||||||
}
|
rad += 0x20;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
rad += 0x1000;
|
rad += 0x1000;
|
||||||
RefreshAddr = rad;
|
RefreshAddr = rad;
|
||||||
//PPU_hook(RefreshAddr); //,-1);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2002,7 +2019,7 @@ int FCEUPPU_Loop(int skip)
|
|||||||
}
|
}
|
||||||
deempcnt[x]=0;
|
deempcnt[x]=0;
|
||||||
}
|
}
|
||||||
//FCEU_DispMessage("%2x:%2x:%2x:%2x:%2x:%2x:%2x:%2x %d",deempcnt[0],deempcnt[1],deempcnt[2],deempcnt[3],deempcnt[4],deempcnt[5],deempcnt[6],deempcnt[7],maxref);
|
//FCEU_DispMessage("%2x:%2x:%2x:%2x:%2x:%2x:%2x:%2x %d",0,deempcnt[0],deempcnt[1],deempcnt[2],deempcnt[3],deempcnt[4],deempcnt[5],deempcnt[6],deempcnt[7],maxref);
|
||||||
//memset(deempcnt,0,sizeof(deempcnt));
|
//memset(deempcnt,0,sizeof(deempcnt));
|
||||||
SetNESDeemph(maxref,0);
|
SetNESDeemph(maxref,0);
|
||||||
}
|
}
|
||||||
|
@ -201,8 +201,6 @@ void LogDPCM(int romaddress, int dpcmsize){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Instantaneous? Maybe the new freq value is being calculated all of the time... */
|
/* Instantaneous? Maybe the new freq value is being calculated all of the time... */
|
||||||
|
@ -36,7 +36,6 @@
|
|||||||
#include "sound.h"
|
#include "sound.h"
|
||||||
#include "utils/endian.h"
|
#include "utils/endian.h"
|
||||||
#include "utils/memory.h"
|
#include "utils/memory.h"
|
||||||
#include "utils/memorystream.h"
|
|
||||||
#include "utils/xstring.h"
|
#include "utils/xstring.h"
|
||||||
#include "file.h"
|
#include "file.h"
|
||||||
#include "fds.h"
|
#include "fds.h"
|
||||||
@ -120,7 +119,7 @@ SFORMAT SFCPUC[]={
|
|||||||
|
|
||||||
void foo(uint8* test) { (void)test; }
|
void foo(uint8* test) { (void)test; }
|
||||||
|
|
||||||
static int SubWrite(std::ostream* os, SFORMAT *sf)
|
static int SubWrite(EMUFILE* os, SFORMAT *sf)
|
||||||
{
|
{
|
||||||
uint32 acc=0;
|
uint32 acc=0;
|
||||||
|
|
||||||
@ -142,7 +141,7 @@ static int SubWrite(std::ostream* os, SFORMAT *sf)
|
|||||||
|
|
||||||
if(os) //Are we writing or calculating the size of this block?
|
if(os) //Are we writing or calculating the size of this block?
|
||||||
{
|
{
|
||||||
os->write(sf->desc,4);
|
os->fwrite(sf->desc,4);
|
||||||
write32le(sf->s&(~FCEUSTATE_FLAGS),os);
|
write32le(sf->s&(~FCEUSTATE_FLAGS),os);
|
||||||
|
|
||||||
#ifndef LSB_FIRST
|
#ifndef LSB_FIRST
|
||||||
@ -151,9 +150,9 @@ static int SubWrite(std::ostream* os, SFORMAT *sf)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
if(sf->s&FCEUSTATE_INDIRECT)
|
if(sf->s&FCEUSTATE_INDIRECT)
|
||||||
os->write(*(char **)sf->v,sf->s&(~FCEUSTATE_FLAGS));
|
os->fwrite(*(char **)sf->v,sf->s&(~FCEUSTATE_FLAGS));
|
||||||
else
|
else
|
||||||
os->write((char*)sf->v,sf->s&(~FCEUSTATE_FLAGS));
|
os->fwrite((char*)sf->v,sf->s&(~FCEUSTATE_FLAGS));
|
||||||
|
|
||||||
//Now restore the original byte order.
|
//Now restore the original byte order.
|
||||||
#ifndef LSB_FIRST
|
#ifndef LSB_FIRST
|
||||||
@ -167,10 +166,10 @@ static int SubWrite(std::ostream* os, SFORMAT *sf)
|
|||||||
return(acc);
|
return(acc);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int WriteStateChunk(std::ostream* os, int type, SFORMAT *sf)
|
static int WriteStateChunk(EMUFILE* os, int type, SFORMAT *sf)
|
||||||
{
|
{
|
||||||
os->put(type);
|
os->fputc(type);
|
||||||
int bsize = SubWrite((std::ostream*)0,sf);
|
int bsize = SubWrite((EMUFILE*)0,sf);
|
||||||
write32le(bsize,os);
|
write32le(bsize,os);
|
||||||
|
|
||||||
if(!SubWrite(os,sf))
|
if(!SubWrite(os,sf))
|
||||||
@ -203,16 +202,16 @@ static SFORMAT *CheckS(SFORMAT *sf, uint32 tsize, char *desc)
|
|||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool ReadStateChunk(std::istream* is, SFORMAT *sf, int size)
|
static bool ReadStateChunk(EMUFILE* is, SFORMAT *sf, int size)
|
||||||
{
|
{
|
||||||
SFORMAT *tmp;
|
SFORMAT *tmp;
|
||||||
int temp = is->tellg();
|
int temp = is->ftell();
|
||||||
|
|
||||||
while(is->tellg()<temp+size)
|
while(is->ftell()<temp+size)
|
||||||
{
|
{
|
||||||
uint32 tsize;
|
uint32 tsize;
|
||||||
char toa[4];
|
char toa[4];
|
||||||
if(is->read(toa,4).gcount()<4)
|
if(is->fread(toa,4)<4)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
read32le(&tsize,is);
|
read32le(&tsize,is);
|
||||||
@ -220,9 +219,9 @@ static bool ReadStateChunk(std::istream* is, SFORMAT *sf, int size)
|
|||||||
if((tmp=CheckS(sf,tsize,toa)))
|
if((tmp=CheckS(sf,tsize,toa)))
|
||||||
{
|
{
|
||||||
if(tmp->s&FCEUSTATE_INDIRECT)
|
if(tmp->s&FCEUSTATE_INDIRECT)
|
||||||
is->read(*(char **)tmp->v,tmp->s&(~FCEUSTATE_FLAGS));
|
is->fread(*(char **)tmp->v,tmp->s&(~FCEUSTATE_FLAGS));
|
||||||
else
|
else
|
||||||
is->read((char *)tmp->v,tmp->s&(~FCEUSTATE_FLAGS));
|
is->fread((char *)tmp->v,tmp->s&(~FCEUSTATE_FLAGS));
|
||||||
|
|
||||||
#ifndef LSB_FIRST
|
#ifndef LSB_FIRST
|
||||||
if(tmp->s&RLSB)
|
if(tmp->s&RLSB)
|
||||||
@ -230,7 +229,7 @@ static bool ReadStateChunk(std::istream* is, SFORMAT *sf, int size)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
is->seekg(tsize,std::ios::cur);
|
is->fseek(tsize,SEEK_CUR);
|
||||||
} // while(...)
|
} // while(...)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -239,7 +238,7 @@ static int read_sfcpuc=0, read_snd=0;
|
|||||||
|
|
||||||
void FCEUD_BlitScreen(uint8 *XBuf); //mbg merge 7/17/06 YUCKY had to add
|
void FCEUD_BlitScreen(uint8 *XBuf); //mbg merge 7/17/06 YUCKY had to add
|
||||||
void UpdateFCEUWindow(void); //mbg merge 7/17/06 YUCKY had to add
|
void UpdateFCEUWindow(void); //mbg merge 7/17/06 YUCKY had to add
|
||||||
static bool ReadStateChunks(std::istream* is, int32 totalsize)
|
static bool ReadStateChunks(EMUFILE* is, int32 totalsize)
|
||||||
{
|
{
|
||||||
int t;
|
int t;
|
||||||
uint32 size;
|
uint32 size;
|
||||||
@ -256,7 +255,7 @@ static bool ReadStateChunks(std::istream* is, int32 totalsize)
|
|||||||
|
|
||||||
while(totalsize > 0)
|
while(totalsize > 0)
|
||||||
{
|
{
|
||||||
t=is->get();
|
t=is->fgetc();
|
||||||
if(t==EOF) break;
|
if(t==EOF) break;
|
||||||
if(!read32le(&size,is)) break;
|
if(!read32le(&size,is)) break;
|
||||||
totalsize -= size + 5;
|
totalsize -= size + 5;
|
||||||
@ -284,20 +283,20 @@ static bool ReadStateChunks(std::istream* is, int32 totalsize)
|
|||||||
read_snd=1;
|
read_snd=1;
|
||||||
break;
|
break;
|
||||||
case 6:
|
case 6:
|
||||||
if(FCEUMOV_Mode(MOVIEMODE_PLAY|MOVIEMODE_RECORD))
|
if(FCEUMOV_Mode(MOVIEMODE_PLAY|MOVIEMODE_RECORD|MOVIEMODE_FINISHED))
|
||||||
{
|
{
|
||||||
if(!ReadStateChunk(is,FCEUMOV_STATEINFO,size)) ret=false;
|
if(!ReadStateChunk(is,FCEUMOV_STATEINFO,size)) ret=false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
is->seekg(size,std::ios::cur);
|
is->fseek(size,SEEK_CUR);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 8:
|
case 8:
|
||||||
// load back buffer
|
// load back buffer
|
||||||
{
|
{
|
||||||
extern uint8 *XBackBuf;
|
extern uint8 *XBackBuf;
|
||||||
if(is->read((char*)XBackBuf,size).gcount() != size)
|
if(is->fread((char*)XBackBuf,size) != size)
|
||||||
ret = false;
|
ret = false;
|
||||||
|
|
||||||
//MBG TODO - can this be moved to a better place?
|
//MBG TODO - can this be moved to a better place?
|
||||||
@ -329,7 +328,7 @@ static bool ReadStateChunks(std::istream* is, int32 totalsize)
|
|||||||
warned=true;
|
warned=true;
|
||||||
}
|
}
|
||||||
//if(fseek(st,size,SEEK_CUR)<0) goto endo;break;
|
//if(fseek(st,size,SEEK_CUR)<0) goto endo;break;
|
||||||
is->seekg(size,std::ios::cur);
|
is->fseek(size,SEEK_CUR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//endo:
|
//endo:
|
||||||
@ -354,17 +353,13 @@ int CurrentState=0;
|
|||||||
extern int geniestage;
|
extern int geniestage;
|
||||||
|
|
||||||
|
|
||||||
bool FCEUSS_SaveMS(std::ostream* outstream, int compressionLevel)
|
bool FCEUSS_SaveMS(EMUFILE* outstream, int compressionLevel)
|
||||||
{
|
{
|
||||||
//a temp memory stream. we'll dump some data here and then compress
|
//a temp memory stream. we'll dump some data here and then compress
|
||||||
//TODO - support dumping directly without compressing to save a buffer copy
|
//TODO - support dumping directly without compressing to save a buffer copy
|
||||||
|
|
||||||
#ifdef GEKKO
|
EMUFILE_MEMORY ms;
|
||||||
memorystream ms(512*1024); // set aside some space, otherwise expand fails on Wii!
|
EMUFILE* os = &ms;
|
||||||
#else
|
|
||||||
memorystream ms;
|
|
||||||
#endif
|
|
||||||
std::ostream* os = (std::ostream*)&ms;
|
|
||||||
|
|
||||||
uint32 totalsize = 0;
|
uint32 totalsize = 0;
|
||||||
|
|
||||||
@ -376,7 +371,7 @@ bool FCEUSS_SaveMS(std::ostream* outstream, int compressionLevel)
|
|||||||
totalsize+=WriteStateChunk(os,31,FCEU_NEWPPU_STATEINFO);
|
totalsize+=WriteStateChunk(os,31,FCEU_NEWPPU_STATEINFO);
|
||||||
totalsize+=WriteStateChunk(os,4,FCEUCTRL_STATEINFO);
|
totalsize+=WriteStateChunk(os,4,FCEUCTRL_STATEINFO);
|
||||||
totalsize+=WriteStateChunk(os,5,FCEUSND_STATEINFO);
|
totalsize+=WriteStateChunk(os,5,FCEUSND_STATEINFO);
|
||||||
if(FCEUMOV_Mode(MOVIEMODE_PLAY|MOVIEMODE_RECORD))
|
if(FCEUMOV_Mode(MOVIEMODE_PLAY|MOVIEMODE_RECORD|MOVIEMODE_FINISHED))
|
||||||
{
|
{
|
||||||
totalsize+=WriteStateChunk(os,6,FCEUMOV_STATEINFO);
|
totalsize+=WriteStateChunk(os,6,FCEUMOV_STATEINFO);
|
||||||
|
|
||||||
@ -384,12 +379,12 @@ bool FCEUSS_SaveMS(std::ostream* outstream, int compressionLevel)
|
|||||||
//do not save the movie state if we are in tasedit! that is a huge waste of time and space!
|
//do not save the movie state if we are in tasedit! that is a huge waste of time and space!
|
||||||
if(!FCEUMOV_Mode(MOVIEMODE_TASEDIT))
|
if(!FCEUMOV_Mode(MOVIEMODE_TASEDIT))
|
||||||
{
|
{
|
||||||
os->seekp(5,std::ios::cur);
|
os->fseek(5,SEEK_CUR);
|
||||||
int size = FCEUMOV_WriteState(os);
|
int size = FCEUMOV_WriteState(os);
|
||||||
os->seekp(-(size+5),std::ios::cur);
|
os->fseek(-(size+5),SEEK_CUR);
|
||||||
os->put(7);
|
os->fputc(7);
|
||||||
write32le(size, os);
|
write32le(size, os);
|
||||||
os->seekp(size,std::ios::cur);
|
os->fseek(size,SEEK_CUR);
|
||||||
|
|
||||||
totalsize += 5 + size;
|
totalsize += 5 + size;
|
||||||
}
|
}
|
||||||
@ -398,9 +393,9 @@ bool FCEUSS_SaveMS(std::ostream* outstream, int compressionLevel)
|
|||||||
{
|
{
|
||||||
extern uint8 *XBackBuf;
|
extern uint8 *XBackBuf;
|
||||||
uint32 size = 256 * 256 + 8;
|
uint32 size = 256 * 256 + 8;
|
||||||
os->put(8);
|
os->fputc(8);
|
||||||
write32le(size, os);
|
write32le(size, os);
|
||||||
os->write((char*)XBackBuf,size);
|
os->fwrite((char*)XBackBuf,size);
|
||||||
totalsize += 5 + size;
|
totalsize += 5 + size;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -409,11 +404,7 @@ bool FCEUSS_SaveMS(std::ostream* outstream, int compressionLevel)
|
|||||||
if(SPreSave) SPostSave();
|
if(SPreSave) SPostSave();
|
||||||
|
|
||||||
//save the length of the file
|
//save the length of the file
|
||||||
#ifdef GEKKO
|
|
||||||
int len = ms.tellp();
|
|
||||||
#else
|
|
||||||
int len = ms.size();
|
int len = ms.size();
|
||||||
#endif
|
|
||||||
|
|
||||||
//sanity check: len and totalsize should be the same
|
//sanity check: len and totalsize should be the same
|
||||||
if(len != totalsize)
|
if(len != totalsize)
|
||||||
@ -441,8 +432,8 @@ bool FCEUSS_SaveMS(std::ostream* outstream, int compressionLevel)
|
|||||||
FCEU_en32lsb(header+12, comprlen);
|
FCEU_en32lsb(header+12, comprlen);
|
||||||
|
|
||||||
//dump it to the destination file
|
//dump it to the destination file
|
||||||
outstream->write((char*)header,16);
|
outstream->fwrite((char*)header,16);
|
||||||
outstream->write((char*)cbuf,comprlen==-1?totalsize:comprlen);
|
outstream->fwrite((char*)cbuf,comprlen==-1?totalsize:comprlen);
|
||||||
|
|
||||||
if(cbuf != (uint8*)ms.buf()) delete[] cbuf;
|
if(cbuf != (uint8*)ms.buf()) delete[] cbuf;
|
||||||
return error == Z_OK;
|
return error == Z_OK;
|
||||||
@ -451,12 +442,12 @@ bool FCEUSS_SaveMS(std::ostream* outstream, int compressionLevel)
|
|||||||
|
|
||||||
void FCEUSS_Save(const char *fname)
|
void FCEUSS_Save(const char *fname)
|
||||||
{
|
{
|
||||||
std::fstream* st = 0;
|
EMUFILE* st = 0;
|
||||||
char fn[2048];
|
char fn[2048];
|
||||||
|
|
||||||
if(geniestage==1)
|
if(geniestage==1)
|
||||||
{
|
{
|
||||||
FCEU_DispMessage("Cannot save FCS in GG screen.");
|
FCEU_DispMessage("Cannot save FCS in GG screen.",0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -485,7 +476,7 @@ void FCEUSS_Save(const char *fname)
|
|||||||
|
|
||||||
if(st == NULL)
|
if(st == NULL)
|
||||||
{
|
{
|
||||||
FCEU_DispMessage("State %d save error.",CurrentState);
|
FCEU_DispMessage("State %d save error.",0,CurrentState);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -525,12 +516,12 @@ void FCEUSS_Save(const char *fname)
|
|||||||
if(!fname)
|
if(!fname)
|
||||||
{
|
{
|
||||||
SaveStateStatus[CurrentState]=1;
|
SaveStateStatus[CurrentState]=1;
|
||||||
FCEU_DispMessage("State %d saved.",CurrentState);
|
FCEU_DispMessage("State %d saved.",0,CurrentState);
|
||||||
}
|
}
|
||||||
redoSS = false; //we have a new savestate so redo is not possible
|
redoSS = false; //we have a new savestate so redo is not possible
|
||||||
}
|
}
|
||||||
|
|
||||||
int FCEUSS_LoadFP_old(std::istream* is, ENUM_SSLOADPARAMS params)
|
int FCEUSS_LoadFP_old(EMUFILE* is, ENUM_SSLOADPARAMS params)
|
||||||
{
|
{
|
||||||
//if(params==SSLOADPARAM_DUMMY && suppress_scan_chunks)
|
//if(params==SSLOADPARAM_DUMMY && suppress_scan_chunks)
|
||||||
// return 1;
|
// return 1;
|
||||||
@ -566,7 +557,7 @@ int FCEUSS_LoadFP_old(std::istream* is, ENUM_SSLOADPARAMS params)
|
|||||||
{
|
{
|
||||||
FCEUMOV_PreLoad();
|
FCEUMOV_PreLoad();
|
||||||
}
|
}
|
||||||
is->read((char*)&header,16);
|
is->fread((char*)&header,16);
|
||||||
if(memcmp(header,"FCS",3))
|
if(memcmp(header,"FCS",3))
|
||||||
{
|
{
|
||||||
return(0);
|
return(0);
|
||||||
@ -624,21 +615,25 @@ int FCEUSS_LoadFP_old(std::istream* is, ENUM_SSLOADPARAMS params)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool FCEUSS_LoadFP(std::istream* is, ENUM_SSLOADPARAMS params)
|
bool FCEUSS_LoadFP(EMUFILE* is, ENUM_SSLOADPARAMS params)
|
||||||
{
|
{
|
||||||
//maybe make a backup savestate
|
//maybe make a backup savestate
|
||||||
memorystream msBackupSavestate;
|
EMUFILE_MEMORY msBackupSavestate;
|
||||||
bool backup = (params == SSLOADPARAM_BACKUP);
|
bool backup = (params == SSLOADPARAM_BACKUP);
|
||||||
|
|
||||||
|
if(!is)
|
||||||
|
return false;
|
||||||
|
|
||||||
if(backup)
|
if(backup)
|
||||||
FCEUSS_SaveMS(&msBackupSavestate,Z_NO_COMPRESSION);
|
FCEUSS_SaveMS(&msBackupSavestate,Z_NO_COMPRESSION);
|
||||||
|
|
||||||
uint8 header[16];
|
uint8 header[16];
|
||||||
|
|
||||||
//read and analyze the header
|
//read and analyze the header
|
||||||
is->read((char*)&header,16);
|
is->fread((char*)&header,16);
|
||||||
if(memcmp(header,"FCSX",4)) {
|
if(memcmp(header,"FCSX",4)) {
|
||||||
//its not an fceux save file.. perhaps it is an fceu savefile
|
//its not an fceux save file.. perhaps it is an fceu savefile
|
||||||
is->seekg(0);
|
is->fseek(0,SEEK_SET);
|
||||||
FCEU_state_loading_old_format = true;
|
FCEU_state_loading_old_format = true;
|
||||||
bool ret = FCEUSS_LoadFP_old(is,params)!=0;
|
bool ret = FCEUSS_LoadFP_old(is,params)!=0;
|
||||||
FCEU_state_loading_old_format = false;
|
FCEU_state_loading_old_format = false;
|
||||||
@ -650,14 +645,14 @@ bool FCEUSS_LoadFP(std::istream* is, ENUM_SSLOADPARAMS params)
|
|||||||
int stateversion = FCEU_de32lsb(header + 8);
|
int stateversion = FCEU_de32lsb(header + 8);
|
||||||
int comprlen = FCEU_de32lsb(header + 12);
|
int comprlen = FCEU_de32lsb(header + 12);
|
||||||
|
|
||||||
std::vector<char> buf(totalsize);
|
std::vector<uint8> buf(totalsize);
|
||||||
|
|
||||||
//not compressed:
|
//not compressed:
|
||||||
if(comprlen != -1)
|
if(comprlen != -1)
|
||||||
{
|
{
|
||||||
//load the compressed chunk and decompress
|
//load the compressed chunk and decompress
|
||||||
std::vector<char> cbuf(comprlen);
|
std::vector<char> cbuf(comprlen);
|
||||||
is->read((char*)&cbuf[0],comprlen);
|
is->fread((char*)&cbuf[0],comprlen);
|
||||||
|
|
||||||
uLongf uncomprlen = totalsize;
|
uLongf uncomprlen = totalsize;
|
||||||
int error = uncompress((uint8*)&buf[0],&uncomprlen,(uint8*)&cbuf[0],comprlen);
|
int error = uncompress((uint8*)&buf[0],&uncomprlen,(uint8*)&cbuf[0],comprlen);
|
||||||
@ -667,12 +662,12 @@ bool FCEUSS_LoadFP(std::istream* is, ENUM_SSLOADPARAMS params)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
is->read((char*)&buf[0],totalsize);
|
is->fread((char*)&buf[0],totalsize);
|
||||||
}
|
}
|
||||||
|
|
||||||
FCEUMOV_PreLoad();
|
FCEUMOV_PreLoad();
|
||||||
|
|
||||||
memorystream mstemp(&buf);
|
EMUFILE_MEMORY mstemp(&buf);
|
||||||
bool x = ReadStateChunks(&mstemp,totalsize)!=0;
|
bool x = ReadStateChunks(&mstemp,totalsize)!=0;
|
||||||
|
|
||||||
//mbg 5/24/08 - we don't support old states, so this shouldnt matter.
|
//mbg 5/24/08 - we don't support old states, so this shouldnt matter.
|
||||||
@ -691,7 +686,7 @@ bool FCEUSS_LoadFP(std::istream* is, ENUM_SSLOADPARAMS params)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(!x && backup) {
|
if(!x && backup) {
|
||||||
msBackupSavestate.sync();
|
msBackupSavestate.fseek(0,SEEK_SET);
|
||||||
FCEUSS_LoadFP(&msBackupSavestate,SSLOADPARAM_NOBACKUP);
|
FCEUSS_LoadFP(&msBackupSavestate,SSLOADPARAM_NOBACKUP);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -701,7 +696,7 @@ bool FCEUSS_LoadFP(std::istream* is, ENUM_SSLOADPARAMS params)
|
|||||||
|
|
||||||
bool FCEUSS_Load(const char *fname)
|
bool FCEUSS_Load(const char *fname)
|
||||||
{
|
{
|
||||||
std::fstream* st;
|
EMUFILE* st;
|
||||||
char fn[2048];
|
char fn[2048];
|
||||||
|
|
||||||
//mbg movie - this needs to be overhauled
|
//mbg movie - this needs to be overhauled
|
||||||
@ -713,7 +708,7 @@ bool FCEUSS_Load(const char *fname)
|
|||||||
|
|
||||||
if(geniestage==1)
|
if(geniestage==1)
|
||||||
{
|
{
|
||||||
FCEU_DispMessage("Cannot load FCS in GG screen.");
|
FCEU_DispMessage("Cannot load FCS in GG screen.",0);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if(fname)
|
if(fname)
|
||||||
@ -730,7 +725,7 @@ bool FCEUSS_Load(const char *fname)
|
|||||||
|
|
||||||
if(st == NULL)
|
if(st == NULL)
|
||||||
{
|
{
|
||||||
FCEU_DispMessage("State %d load error.",CurrentState);
|
FCEU_DispMessage("State %d load error.",0,CurrentState);
|
||||||
SaveStateStatus[CurrentState]=0;
|
SaveStateStatus[CurrentState]=0;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -738,20 +733,17 @@ bool FCEUSS_Load(const char *fname)
|
|||||||
//If in bot mode, don't do a backup when loading.
|
//If in bot mode, don't do a backup when loading.
|
||||||
//Otherwise you eat at the hard disk, since so many
|
//Otherwise you eat at the hard disk, since so many
|
||||||
//states are being loaded.
|
//states are being loaded.
|
||||||
if(FCEUSS_LoadFP(st,SSLOADPARAM_BACKUP))
|
if(FCEUSS_LoadFP(st, backupSavestates ? SSLOADPARAM_BACKUP : SSLOADPARAM_NOBACKUP))
|
||||||
{
|
{
|
||||||
if(fname)
|
if(fname)
|
||||||
{
|
{
|
||||||
char szFilename[260]={0};
|
char szFilename[260]={0};
|
||||||
splitpath(fname, 0, 0, szFilename, 0);
|
splitpath(fname, 0, 0, szFilename, 0);
|
||||||
FCEU_DispMessage("State %s loaded.",szFilename);
|
FCEU_DispMessage("State %s loaded.",0,szFilename);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//This looks redudant to me... but why bother deleting it:)
|
FCEU_DispMessage("State %d loaded.",0,CurrentState);
|
||||||
SaveStateStatus[CurrentState]=1;
|
|
||||||
|
|
||||||
FCEU_DispMessage("State %d loaded.",CurrentState);
|
|
||||||
SaveStateStatus[CurrentState]=1;
|
SaveStateStatus[CurrentState]=1;
|
||||||
}
|
}
|
||||||
delete st;
|
delete st;
|
||||||
@ -779,6 +771,13 @@ bool FCEUSS_Load(const char *fname)
|
|||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
Update_RAM_Search(); // Update_RAM_Watch() is also called.
|
Update_RAM_Search(); // Update_RAM_Watch() is also called.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
//Update input display if movie is loaded
|
||||||
|
extern uint32 cur_input_display;
|
||||||
|
extern uint8 FCEU_GetJoyJoy(void);
|
||||||
|
|
||||||
|
cur_input_display = FCEU_GetJoyJoy(); //Input display should show the last buttons pressed (stored in the savestate)
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -787,7 +786,7 @@ bool FCEUSS_Load(const char *fname)
|
|||||||
{
|
{
|
||||||
SaveStateStatus[CurrentState]=1;
|
SaveStateStatus[CurrentState]=1;
|
||||||
}
|
}
|
||||||
FCEU_DispMessage("Error(s) reading state %d!",CurrentState);
|
FCEU_DispMessage("Error(s) reading state %d!",0,CurrentState);
|
||||||
delete st;
|
delete st;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -875,7 +874,7 @@ int FCEUI_SelectState(int w, int show)
|
|||||||
if(show)
|
if(show)
|
||||||
{
|
{
|
||||||
StateShow=180;
|
StateShow=180;
|
||||||
FCEU_DispMessage("-select state-");
|
FCEU_DispMessage("-select state-",0);
|
||||||
}
|
}
|
||||||
return oldstate;
|
return oldstate;
|
||||||
}
|
}
|
||||||
@ -891,6 +890,15 @@ void FCEUI_SaveState(const char *fname)
|
|||||||
|
|
||||||
int loadStateFailed = 0; // hack, this function should return a value instead
|
int loadStateFailed = 0; // hack, this function should return a value instead
|
||||||
|
|
||||||
|
bool file_exists(const char * filename)
|
||||||
|
{
|
||||||
|
if (FILE * file = fopen(filename, "r")) //I'm sure, you meant for READING =)
|
||||||
|
{
|
||||||
|
fclose(file);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
void FCEUI_LoadState(const char *fname)
|
void FCEUI_LoadState(const char *fname)
|
||||||
{
|
{
|
||||||
if(!FCEU_IsValidUI(FCEUI_LOADSTATE)) return;
|
if(!FCEU_IsValidUI(FCEUI_LOADSTATE)) return;
|
||||||
@ -909,6 +917,11 @@ void FCEUI_LoadState(const char *fname)
|
|||||||
{
|
{
|
||||||
FCEUI_MakeBackupMovie(false); //Backup the movie before the contents get altered, but do not display messages
|
FCEUI_MakeBackupMovie(false); //Backup the movie before the contents get altered, but do not display messages
|
||||||
}
|
}
|
||||||
|
if (fname != NULL && !file_exists(fname))
|
||||||
|
{
|
||||||
|
loadStateFailed = 1;
|
||||||
|
return; // state doesn't exist; exit cleanly
|
||||||
|
}
|
||||||
if(FCEUSS_Load(fname))
|
if(FCEUSS_Load(fname))
|
||||||
{
|
{
|
||||||
//mbg todo netplay
|
//mbg todo netplay
|
||||||
@ -984,14 +997,14 @@ void SwapSaveState()
|
|||||||
|
|
||||||
if (!lastSavestateMade)
|
if (!lastSavestateMade)
|
||||||
{
|
{
|
||||||
FCEUI_DispMessage("Can't Undo");
|
FCEUI_DispMessage("Can't Undo",0);
|
||||||
FCEUI_printf("Undo savestate was attempted but unsuccessful because there was not a recently used savestate.\n");
|
FCEUI_printf("Undo savestate was attempted but unsuccessful because there was not a recently used savestate.\n");
|
||||||
return; //If there is no last savestate, can't undo
|
return; //If there is no last savestate, can't undo
|
||||||
}
|
}
|
||||||
string backup = GenerateBackupSaveStateFn(lastSavestateMade); //Get filename of backup state
|
string backup = GenerateBackupSaveStateFn(lastSavestateMade); //Get filename of backup state
|
||||||
if (!CheckFileExists(backup.c_str()))
|
if (!CheckFileExists(backup.c_str()))
|
||||||
{
|
{
|
||||||
FCEUI_DispMessage("Can't Undo");
|
FCEUI_DispMessage("Can't Undo",0);
|
||||||
FCEUI_printf("Undo savestate was attempted but unsuccessful because there was not a backup of the last used savestate.\n");
|
FCEUI_printf("Undo savestate was attempted but unsuccessful because there was not a backup of the last used savestate.\n");
|
||||||
return; //If no backup, can't undo
|
return; //If no backup, can't undo
|
||||||
}
|
}
|
||||||
@ -1012,8 +1025,8 @@ void SwapSaveState()
|
|||||||
else //This was an undo function so next will be redo, so flag it
|
else //This was an undo function so next will be redo, so flag it
|
||||||
redoSS = true;
|
redoSS = true;
|
||||||
|
|
||||||
FCEUI_DispMessage("%s restored",backup.c_str());
|
FCEUI_DispMessage("%s restored",0,backup.c_str());
|
||||||
FCEUI_printf("%s restored\n",backup.c_str());
|
FCEUI_printf("%s restored\n",0,backup.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
@ -1081,7 +1094,7 @@ void LoadBackup()
|
|||||||
undoLS = false; //Flag that LoadBackup cannot be run again
|
undoLS = false; //Flag that LoadBackup cannot be run again
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
FCEUI_DispMessage("Error: Could not load %s",filename.c_str());
|
FCEUI_DispMessage("Error: Could not load %s",0,filename.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void RedoLoadState()
|
void RedoLoadState()
|
||||||
|
@ -28,9 +28,9 @@ void FCEUSS_Save(const char *);
|
|||||||
bool FCEUSS_Load(const char *);
|
bool FCEUSS_Load(const char *);
|
||||||
|
|
||||||
//zlib values: 0 (none) through 9 (max) or -1 (default)
|
//zlib values: 0 (none) through 9 (max) or -1 (default)
|
||||||
bool FCEUSS_SaveMS(std::ostream* outstream, int compressionLevel);
|
bool FCEUSS_SaveMS(EMUFILE* outstream, int compressionLevel);
|
||||||
|
|
||||||
bool FCEUSS_LoadFP(std::istream* is, ENUM_SSLOADPARAMS params);
|
bool FCEUSS_LoadFP(EMUFILE* is, ENUM_SSLOADPARAMS params);
|
||||||
|
|
||||||
extern int CurrentState;
|
extern int CurrentState;
|
||||||
void FCEUSS_CheckStates(void);
|
void FCEUSS_CheckStates(void);
|
||||||
|
@ -72,6 +72,7 @@ typedef uint32_t uint32;
|
|||||||
|
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
typedef unsigned long long uint64;
|
typedef unsigned long long uint64;
|
||||||
|
typedef uint64 u64;
|
||||||
typedef long long int64;
|
typedef long long int64;
|
||||||
#define INLINE inline
|
#define INLINE inline
|
||||||
#define GINLINE inline
|
#define GINLINE inline
|
||||||
@ -127,10 +128,10 @@ typedef uint32_t uint32;
|
|||||||
typedef void (*writefunc)(uint32 A, uint8 V);
|
typedef void (*writefunc)(uint32 A, uint8 V);
|
||||||
typedef uint8 (*readfunc)(uint32 A);
|
typedef uint8 (*readfunc)(uint32 A);
|
||||||
|
|
||||||
#include "utils/endian.h"
|
|
||||||
|
|
||||||
#ifndef CTASSERT
|
#ifndef CTASSERT
|
||||||
#define CTASSERT(x) typedef char __assert ## y[(x) ? 1 : -1];
|
#define CTASSERT(x) typedef char __assert ## y[(x) ? 1 : -1];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "utils/endian.h"
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -26,6 +26,27 @@
|
|||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include "../types.h"
|
#include "../types.h"
|
||||||
#include "endian.h"
|
#include "endian.h"
|
||||||
|
#include "../emufile.h"
|
||||||
|
|
||||||
|
//OMG ! configure this correctly
|
||||||
|
#define LOCAL_BE
|
||||||
|
|
||||||
|
/* little endian to local endianess convert macros */
|
||||||
|
#ifdef LOCAL_BE /* local arch is big endian */
|
||||||
|
# define LE_TO_LOCAL_16(x) ((((x)&0xff)<<8)|(((x)>>8)&0xff))
|
||||||
|
# define LE_TO_LOCAL_32(x) ((((x)&0xff)<<24)|(((x)&0xff00)<<8)|(((x)>>8)&0xff00)|(((x)>>24)&0xff))
|
||||||
|
# define LE_TO_LOCAL_64(x) ((((x)&0xff)<<56)|(((x)&0xff00)<<40)|(((x)&0xff0000)<<24)|(((x)&0xff000000)<<8)|(((x)>>8)&0xff000000)|(((x)>>24)&0xff00)|(((x)>>40)&0xff00)|(((x)>>56)&0xff))
|
||||||
|
# define LOCAL_TO_LE_16(x) ((((x)&0xff)<<8)|(((x)>>8)&0xff))
|
||||||
|
# define LOCAL_TO_LE_32(x) ((((x)&0xff)<<24)|(((x)&0xff00)<<8)|(((x)>>8)&0xff00)|(((x)>>24)&0xff))
|
||||||
|
# define LOCAL_TO_LE_64(x) ((((x)&0xff)<<56)|(((x)&0xff00)<<40)|(((x)&0xff0000)<<24)|(((x)&0xff000000)<<8)|(((x)>>8)&0xff000000)|(((x)>>24)&0xff00)|(((x)>>40)&0xff00)|(((x)>>56)&0xff))
|
||||||
|
#else /* local arch is little endian */
|
||||||
|
# define LE_TO_LOCAL_16(x) (x)
|
||||||
|
# define LE_TO_LOCAL_32(x) (x)
|
||||||
|
# define LE_TO_LOCAL_64(x) (x)
|
||||||
|
# define LOCAL_TO_LE_16(x) (x)
|
||||||
|
# define LOCAL_TO_LE_32(x) (x)
|
||||||
|
# define LOCAL_TO_LE_64(x) (x)
|
||||||
|
#endif
|
||||||
|
|
||||||
///endian-flips count bytes. count should be even and nonzero.
|
///endian-flips count bytes. count should be even and nonzero.
|
||||||
void FlipByteOrder(uint8 *src, uint32 count)
|
void FlipByteOrder(uint8 *src, uint32 count)
|
||||||
@ -194,3 +215,99 @@ uint16 FCEU_de16lsb(uint8 *morp)
|
|||||||
{
|
{
|
||||||
return morp[0]|(morp[1]<<8);
|
return morp[0]|(morp[1]<<8);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//well. just for the sake of consistency
|
||||||
|
int write8le(u8 b, EMUFILE*os)
|
||||||
|
{
|
||||||
|
os->fwrite((char*)&b,1);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//well. just for the sake of consistency
|
||||||
|
int read8le(u8 *Bufo, EMUFILE*is)
|
||||||
|
{
|
||||||
|
if(is->_fread((char*)Bufo,1) != 1)
|
||||||
|
return 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
///writes a little endian 16bit value to the specified file
|
||||||
|
int write16le(u16 b, EMUFILE *fp)
|
||||||
|
{
|
||||||
|
u8 s[2];
|
||||||
|
s[0]=(u8)b;
|
||||||
|
s[1]=(u8)(b>>8);
|
||||||
|
fp->fwrite(s,2);
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///writes a little endian 32bit value to the specified file
|
||||||
|
int write32le(u32 b, EMUFILE *fp)
|
||||||
|
{
|
||||||
|
uint8 s[4];
|
||||||
|
s[0]=(u8)b;
|
||||||
|
s[1]=(u8)(b>>8);
|
||||||
|
s[2]=(u8)(b>>16);
|
||||||
|
s[3]=(u8)(b>>24);
|
||||||
|
fp->fwrite(s,4);
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
void writebool(bool b, EMUFILE* os) { write32le(b?1:0,os); }
|
||||||
|
|
||||||
|
int write64le(uint64 b, EMUFILE* os)
|
||||||
|
{
|
||||||
|
uint8 s[8];
|
||||||
|
s[0]=(u8)b;
|
||||||
|
s[1]=(u8)(b>>8);
|
||||||
|
s[2]=(u8)(b>>16);
|
||||||
|
s[3]=(u8)(b>>24);
|
||||||
|
s[4]=(u8)(b>>32);
|
||||||
|
s[5]=(u8)(b>>40);
|
||||||
|
s[6]=(u8)(b>>48);
|
||||||
|
s[7]=(u8)(b>>56);
|
||||||
|
os->fwrite((char*)&s,8);
|
||||||
|
return 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int read32le(uint32 *Bufo, EMUFILE *fp)
|
||||||
|
{
|
||||||
|
uint32 buf;
|
||||||
|
if(fp->_fread(&buf,4)<4)
|
||||||
|
return 0;
|
||||||
|
#ifdef LOCAL_LE
|
||||||
|
*(u32*)Bufo=buf;
|
||||||
|
#else
|
||||||
|
*(u32*)Bufo=((buf&0xFF)<<24)|((buf&0xFF00)<<8)|((buf&0xFF0000)>>8)|((buf&0xFF000000)>>24);
|
||||||
|
#endif
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int read16le(u16 *Bufo, EMUFILE *is)
|
||||||
|
{
|
||||||
|
u16 buf;
|
||||||
|
if(is->_fread((char*)&buf,2) != 2)
|
||||||
|
return 0;
|
||||||
|
#ifdef LOCAL_LE
|
||||||
|
*Bufo=buf;
|
||||||
|
#else
|
||||||
|
*Bufo = LE_TO_LOCAL_16(buf);
|
||||||
|
#endif
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int read64le(uint64 *Bufo, EMUFILE *is)
|
||||||
|
{
|
||||||
|
uint64 buf;
|
||||||
|
if(is->_fread((char*)&buf,8) != 8)
|
||||||
|
return 0;
|
||||||
|
#ifdef LOCAL_LE
|
||||||
|
*Bufo=buf;
|
||||||
|
#else
|
||||||
|
*Bufo = LE_TO_LOCAL_64(buf);
|
||||||
|
#endif
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
@ -3,6 +3,44 @@
|
|||||||
|
|
||||||
#include <iosfwd>
|
#include <iosfwd>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include "../emufile.h"
|
||||||
|
#include "../types.h"
|
||||||
|
|
||||||
|
inline uint64 double_to_u64(double d) {
|
||||||
|
union {
|
||||||
|
uint64 a;
|
||||||
|
double b;
|
||||||
|
} fuxor;
|
||||||
|
fuxor.b = d;
|
||||||
|
return fuxor.a;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline double u64_to_double(uint64 u) {
|
||||||
|
union {
|
||||||
|
uint64 a;
|
||||||
|
double b;
|
||||||
|
} fuxor;
|
||||||
|
fuxor.a = u;
|
||||||
|
return fuxor.b;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline uint32 float_to_u32(float f) {
|
||||||
|
union {
|
||||||
|
uint32 a;
|
||||||
|
float b;
|
||||||
|
} fuxor;
|
||||||
|
fuxor.b = f;
|
||||||
|
return fuxor.a;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline float u32_to_float(uint32 u) {
|
||||||
|
union {
|
||||||
|
uint32 a;
|
||||||
|
float b;
|
||||||
|
} fuxor;
|
||||||
|
fuxor.a = u;
|
||||||
|
return fuxor.b;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int write16le(uint16 b, FILE *fp);
|
int write16le(uint16 b, FILE *fp);
|
||||||
@ -22,5 +60,50 @@ uint64 FCEU_de64lsb(uint8 *morp);
|
|||||||
uint32 FCEU_de32lsb(uint8 *morp);
|
uint32 FCEU_de32lsb(uint8 *morp);
|
||||||
uint16 FCEU_de16lsb(uint8 *morp);
|
uint16 FCEU_de16lsb(uint8 *morp);
|
||||||
|
|
||||||
#endif
|
//well. just for the sake of consistency
|
||||||
|
int write8le(uint8 b, EMUFILE *fp);
|
||||||
|
inline int write8le(uint8* b, EMUFILE *fp) { return write8le(*b,fp); }
|
||||||
|
int write16le(uint16 b, EMUFILE* os);
|
||||||
|
int write32le(uint32 b, EMUFILE* os);
|
||||||
|
int write64le(uint64 b, EMUFILE* os);
|
||||||
|
inline int write_double_le(double b, EMUFILE*is) { uint64 temp = double_to_u64(b); int ret = write64le(temp,is); return ret; }
|
||||||
|
|
||||||
|
int read8le(uint8 *Bufo, EMUFILE*is);
|
||||||
|
int read16le(uint16 *Bufo, EMUFILE*is);
|
||||||
|
inline int read16le(int16 *Bufo, EMUFILE*is) { return read16le((u16*)Bufo,is); }
|
||||||
|
int read32le(uint32 *Bufo, EMUFILE*is);
|
||||||
|
inline int read32le(int32 *Bufo, EMUFILE*is) { return read32le((u32*)Bufo,is); }
|
||||||
|
int read64le(uint64 *Bufo, EMUFILE*is);
|
||||||
|
inline int read_double_le(double *Bufo, EMUFILE*is) { uint64 temp; int ret = read64le(&temp,is); *Bufo = u64_to_double(temp); return ret; }
|
||||||
|
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
int readle(T *Bufo, EMUFILE*is)
|
||||||
|
{
|
||||||
|
CTASSERT(sizeof(T)==1||sizeof(T)==2||sizeof(T)==4||sizeof(T)==8);
|
||||||
|
switch(sizeof(T)) {
|
||||||
|
case 1: return read8le((u8*)Bufo,is);
|
||||||
|
case 2: return read16le((u16*)Bufo,is);
|
||||||
|
case 4: return read32le((u32*)Bufo,is);
|
||||||
|
case 8: return read64le((u64*)Bufo,is);
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
int writele(T *Bufo, EMUFILE*os)
|
||||||
|
{
|
||||||
|
CTASSERT(sizeof(T)==1||sizeof(T)==2||sizeof(T)==4||sizeof(T)==8);
|
||||||
|
switch(sizeof(T)) {
|
||||||
|
case 1: return write8le((u8*)Bufo,os);
|
||||||
|
case 2: return write16le((u16*)Bufo,os);
|
||||||
|
case 4: return write32le((u32*)Bufo,os);
|
||||||
|
case 8: return write64le((u64*)Bufo,os);
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif //__FCEU_ENDIAN
|
||||||
|
|
||||||
|
@ -553,13 +553,13 @@ std::string stditoa(int n)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::string readNullTerminatedAscii(std::istream* is)
|
std::string readNullTerminatedAscii(EMUFILE* is)
|
||||||
{
|
{
|
||||||
std::string ret;
|
std::string ret;
|
||||||
ret.reserve(50);
|
ret.reserve(50);
|
||||||
for(;;)
|
for(;;)
|
||||||
{
|
{
|
||||||
int c = is->get();
|
int c = is->fgetc();
|
||||||
if(c == 0) break;
|
if(c == 0) break;
|
||||||
else ret += (char)c;
|
else ret += (char)c;
|
||||||
}
|
}
|
||||||
@ -723,7 +723,7 @@ namespace UtfConverter
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef GEKKO
|
|
||||||
std::wstring FromUtf8(std::string& input) // string -> wstring
|
std::wstring FromUtf8(std::string& input) // string -> wstring
|
||||||
{
|
{
|
||||||
std::wstring result;
|
std::wstring result;
|
||||||
@ -739,11 +739,10 @@ namespace UtfConverter
|
|||||||
SeqValue(result, input[pos]);
|
SeqValue(result, input[pos]);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef GEKKO
|
|
||||||
//convert a std::string to std::wstring
|
//convert a std::string to std::wstring
|
||||||
std::wstring mbstowcs(std::string str) // UTF8->UTF32
|
std::wstring mbstowcs(std::string str) // UTF8->UTF32
|
||||||
{
|
{
|
||||||
@ -759,7 +758,7 @@ std::string wcstombs(std::wstring str) // UTF32->UTF8
|
|||||||
{
|
{
|
||||||
return UtfConverter::ToUtf8(str);
|
return UtfConverter::ToUtf8(str);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
//TODO - dont we already have another function that can do this
|
//TODO - dont we already have another function that can do this
|
||||||
std::string getExtension(const char* input) {
|
std::string getExtension(const char* input) {
|
||||||
@ -775,3 +774,16 @@ std::string getExtension(const char* input) {
|
|||||||
ext[k]=tolower(ext[k]);
|
ext[k]=tolower(ext[k]);
|
||||||
return ext;
|
return ext;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//strips the file extension off a filename
|
||||||
|
std::string StripExtension(std::string filename)
|
||||||
|
{
|
||||||
|
return filename.substr(0, filename.find_last_of("."));
|
||||||
|
}
|
||||||
|
|
||||||
|
//strips the path off a filename
|
||||||
|
std::string StripPath(std::string filename)
|
||||||
|
{
|
||||||
|
int x = filename.find_last_of("\\") + 1;
|
||||||
|
return filename.substr(x, filename.length() - x);
|
||||||
|
}
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
#include "../types.h"
|
#include "../types.h"
|
||||||
|
#include "../emufile.h"
|
||||||
|
|
||||||
#ifndef __GNUC__
|
#ifndef __GNUC__
|
||||||
#define strcasecmp strcmp
|
#define strcasecmp strcmp
|
||||||
@ -62,17 +63,17 @@ char *U16ToHexStr(uint16 a);
|
|||||||
|
|
||||||
std::string stditoa(int n);
|
std::string stditoa(int n);
|
||||||
|
|
||||||
std::string readNullTerminatedAscii(std::istream* is);
|
std::string readNullTerminatedAscii(EMUFILE* is);
|
||||||
|
|
||||||
//extracts a decimal uint from an istream
|
//extracts a decimal uint from an istream
|
||||||
template<typename T> T templateIntegerDecFromIstream(std::istream* is)
|
template<typename T> T templateIntegerDecFromIstream(EMUFILE* is)
|
||||||
{
|
{
|
||||||
unsigned int ret = 0;
|
unsigned int ret = 0;
|
||||||
bool pre = true;
|
bool pre = true;
|
||||||
|
|
||||||
for(;;)
|
for(;;)
|
||||||
{
|
{
|
||||||
int c = is->get();
|
int c = is->fgetc();
|
||||||
if(c == -1) return ret;
|
if(c == -1) return ret;
|
||||||
int d = c - '0';
|
int d = c - '0';
|
||||||
if((d<0 || d>9))
|
if((d<0 || d>9))
|
||||||
@ -91,11 +92,11 @@ template<typename T> T templateIntegerDecFromIstream(std::istream* is)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline uint32 uint32DecFromIstream(std::istream* is) { return templateIntegerDecFromIstream<uint32>(is); }
|
inline uint32 uint32DecFromIstream(EMUFILE* is) { return templateIntegerDecFromIstream<uint32>(is); }
|
||||||
inline uint64 uint64DecFromIstream(std::istream* is) { return templateIntegerDecFromIstream<uint64>(is); }
|
inline uint64 uint64DecFromIstream(EMUFILE* is) { return templateIntegerDecFromIstream<uint64>(is); }
|
||||||
|
|
||||||
//puts an optionally 0-padded decimal integer of type T into the ostream (0-padding is quicker)
|
//puts an optionally 0-padded decimal integer of type T into the ostream (0-padding is quicker)
|
||||||
template<typename T, int DIGITS, bool PAD> void putdec(std::ostream* os, T dec)
|
template<typename T, int DIGITS, bool PAD> void putdec(EMUFILE* os, T dec)
|
||||||
{
|
{
|
||||||
char temp[DIGITS];
|
char temp[DIGITS];
|
||||||
int ctr = 0;
|
int ctr = 0;
|
||||||
@ -111,18 +112,20 @@ template<typename T, int DIGITS, bool PAD> void putdec(std::ostream* os, T dec)
|
|||||||
dec = quot;
|
dec = quot;
|
||||||
}
|
}
|
||||||
if(!PAD)
|
if(!PAD)
|
||||||
os->write(temp+DIGITS-ctr-1,ctr+1);
|
os->fwrite(temp+DIGITS-ctr-1,ctr+1);
|
||||||
else
|
else
|
||||||
os->write(temp,DIGITS);
|
os->fwrite(temp,DIGITS);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string mass_replace(const std::string &source, const std::string &victim, const std::string &replacement);
|
std::string mass_replace(const std::string &source, const std::string &victim, const std::string &replacement);
|
||||||
|
|
||||||
#ifndef GEKKO
|
|
||||||
std::wstring mbstowcs(std::string str);
|
std::wstring mbstowcs(std::string str);
|
||||||
std::string wcstombs(std::wstring str);
|
std::string wcstombs(std::wstring str);
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
//TODO - dont we already have another function that can do this
|
//TODO - dont we already have another function that can do this
|
||||||
std::string getExtension(const char* input);
|
std::string getExtension(const char* input);
|
||||||
|
|
||||||
|
std::string StripExtension(std::string filename);
|
||||||
|
std::string StripPath(std::string filename);
|
@ -58,8 +58,8 @@
|
|||||||
#define FCEU_COMPILER_DETAIL ""
|
#define FCEU_COMPILER_DETAIL ""
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define FCEU_VERSION_NUMERIC 21020
|
#define FCEU_VERSION_NUMERIC 21040
|
||||||
#define FCEU_VERSION_STRING "2.1.3" FCEU_SUBVERSION_STRING FCEU_FEATURE_STRING FCEU_COMPILER
|
#define FCEU_VERSION_STRING "2.1.5" FCEU_SUBVERSION_STRING FCEU_FEATURE_STRING FCEU_COMPILER
|
||||||
#define FCEU_NAME_AND_VERSION FCEU_NAME " " FCEU_VERSION_STRING
|
#define FCEU_NAME_AND_VERSION FCEU_NAME " " FCEU_VERSION_STRING
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -50,6 +50,11 @@
|
|||||||
#include "fceulua.h"
|
#include "fceulua.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
#include "drivers/win/common.h" //For DirectX constants
|
||||||
|
#include "drivers/win/input.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef CREATE_AVI
|
#ifdef CREATE_AVI
|
||||||
#include "drivers/videolog/nesvideos-piece.h"
|
#include "drivers/videolog/nesvideos-piece.h"
|
||||||
#endif
|
#endif
|
||||||
@ -66,10 +71,17 @@ GUIMESSAGE subtitleMessage;
|
|||||||
extern int input_display;
|
extern int input_display;
|
||||||
extern uint32 cur_input_display;
|
extern uint32 cur_input_display;
|
||||||
|
|
||||||
|
bool oldInputDisplay = false;
|
||||||
|
|
||||||
#ifdef _USE_SHARED_MEMORY_
|
#ifdef _USE_SHARED_MEMORY_
|
||||||
HANDLE mapXBuf;
|
HANDLE mapXBuf;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
std::string AsSnapshotName =""; //adelikat:this will set the snapshot name when for s savesnapshot as function
|
||||||
|
|
||||||
|
void FCEUI_SetSnapshotAsName(std::string name) { AsSnapshotName = name; }
|
||||||
|
std::string FCEUI_GetSnapshotAsName() { return AsSnapshotName; }
|
||||||
|
|
||||||
void FCEU_KillVirtualVideo(void)
|
void FCEU_KillVirtualVideo(void)
|
||||||
{
|
{
|
||||||
//mbg merge TODO 7/17/06 temporarily removed
|
//mbg merge TODO 7/17/06 temporarily removed
|
||||||
@ -175,15 +187,19 @@ void FCEUI_SaveSnapshot(void)
|
|||||||
dosnapsave=1;
|
dosnapsave=1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FCEUI_SaveSnapshotAs(void)
|
||||||
|
{
|
||||||
|
dosnapsave=2;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void ReallySnap(void)
|
static void ReallySnap(void)
|
||||||
{
|
{
|
||||||
int x=SaveSnapshot();
|
int x=SaveSnapshot();
|
||||||
if(!x)
|
if(!x)
|
||||||
FCEU_DispMessage("Error saving screen snapshot.");
|
FCEU_DispMessage("Error saving screen snapshot.",0);
|
||||||
else
|
else
|
||||||
FCEU_DispMessage("Screen snapshot %d saved.",x-1);
|
FCEU_DispMessage("Screen snapshot %d saved.",0,x-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FCEU_PutImage(void)
|
void FCEU_PutImage(void)
|
||||||
@ -191,13 +207,23 @@ void FCEU_PutImage(void)
|
|||||||
#ifdef SHOWFPS
|
#ifdef SHOWFPS
|
||||||
ShowFPS();
|
ShowFPS();
|
||||||
#endif
|
#endif
|
||||||
|
if(dosnapsave==2) //Save screenshot as, currently only flagged & run by the Win32 build. //TODO SDL: implement this?
|
||||||
|
{
|
||||||
|
char nameo[512];
|
||||||
|
strcpy(nameo,FCEUI_GetSnapshotAsName().c_str());
|
||||||
|
if (nameo)
|
||||||
|
{
|
||||||
|
SaveSnapshot(nameo);
|
||||||
|
FCEU_DispMessage("Snapshot Saved.",0);
|
||||||
|
}
|
||||||
|
dosnapsave=0;
|
||||||
|
}
|
||||||
if(GameInfo->type==GIT_NSF)
|
if(GameInfo->type==GIT_NSF)
|
||||||
{
|
{
|
||||||
DrawNSF(XBuf);
|
DrawNSF(XBuf);
|
||||||
|
|
||||||
//Save snapshot after NSF screen is drawn. Why would we want to do it before?
|
//Save snapshot after NSF screen is drawn. Why would we want to do it before?
|
||||||
if(dosnapsave)
|
if(dosnapsave==1)
|
||||||
{
|
{
|
||||||
ReallySnap();
|
ReallySnap();
|
||||||
dosnapsave=0;
|
dosnapsave=0;
|
||||||
@ -222,7 +248,7 @@ void FCEU_PutImage(void)
|
|||||||
FCEUI_AviVideoUpdate(XBuf);
|
FCEUI_AviVideoUpdate(XBuf);
|
||||||
|
|
||||||
//Save snapshot before overlay stuff is written.
|
//Save snapshot before overlay stuff is written.
|
||||||
if(dosnapsave)
|
if(dosnapsave==1)
|
||||||
{
|
{
|
||||||
ReallySnap();
|
ReallySnap();
|
||||||
dosnapsave=0;
|
dosnapsave=0;
|
||||||
@ -245,8 +271,17 @@ void FCEU_PutImage(void)
|
|||||||
//Fancy input display code
|
//Fancy input display code
|
||||||
if(input_display)
|
if(input_display)
|
||||||
{
|
{
|
||||||
int controller, c, color;
|
extern uint32 JSAutoHeld;
|
||||||
|
uint32 held;
|
||||||
|
|
||||||
|
int controller, c, ci, color;
|
||||||
int i, j;
|
int i, j;
|
||||||
|
uint32 on = FCEUMOV_Mode(MOVIEMODE_PLAY) ? 0x90:0xA7; //Standard, or Gray depending on movie mode
|
||||||
|
uint32 oni = 0xA0; //Color for immediate keyboard buttons
|
||||||
|
uint32 blend = 0xB6; //Blend of immiate and last held buttons
|
||||||
|
uint32 ahold = 0x87; //Auto hold
|
||||||
|
uint32 off = 0xCF;
|
||||||
|
|
||||||
uint8 *t = XBuf+(FSettings.LastSLine-9)*256 + 20; //mbg merge 7/17/06 changed t to uint8*
|
uint8 *t = XBuf+(FSettings.LastSLine-9)*256 + 20; //mbg merge 7/17/06 changed t to uint8*
|
||||||
if(input_display > 4) input_display = 4;
|
if(input_display > 4) input_display = 4;
|
||||||
for(controller = 0; controller < input_display; controller++, t += 56)
|
for(controller = 0; controller < input_display; controller++, t += 56)
|
||||||
@ -258,9 +293,32 @@ void FCEU_PutImage(void)
|
|||||||
for(j = 3; j< 6; j++)
|
for(j = 3; j< 6; j++)
|
||||||
t[i+j*256] = 0xCF;
|
t[i+j*256] = 0xCF;
|
||||||
c = cur_input_display >> (controller * 8);
|
c = cur_input_display >> (controller * 8);
|
||||||
c &= 255;
|
|
||||||
|
// This doesn't work in anything except windows for now.
|
||||||
|
// It doesn't get set anywhere in other ports.
|
||||||
|
#ifdef WIN32
|
||||||
|
if (!oldInputDisplay) ci = FCEUMOV_Mode(MOVIEMODE_PLAY) ? 0:GetGamepadPressedImmediate() >> (controller * 8);
|
||||||
|
else ci = 0;
|
||||||
|
|
||||||
|
if (!oldInputDisplay && !FCEUMOV_Mode(MOVIEMODE_PLAY)) held = (JSAutoHeld >> (controller * 8));
|
||||||
|
else held = 0;
|
||||||
|
#else
|
||||||
|
// Put other port info here
|
||||||
|
ci = 0;
|
||||||
|
held = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//adelikat: I apologize to anyone who ever sifts through this color assignment
|
||||||
//A
|
//A
|
||||||
color = c&1?0xA7:0xCF;
|
if (held&1) { //If auto-hold
|
||||||
|
if (!(ci&1) ) color = ahold;
|
||||||
|
else
|
||||||
|
color = (c&1) ? on : off; //If the button is pressed down (immediate) that negates auto hold, however it is only off if the previous frame the button wasn't pressed!
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (c&1) color = (ci&1) ? blend : on; //If immedaite buttons are pressed and they match the previous frame, blend the colors
|
||||||
|
else color = (ci&1) ? oni : off;
|
||||||
|
}
|
||||||
for(i=0; i < 4; i++)
|
for(i=0; i < 4; i++)
|
||||||
{
|
{
|
||||||
for(j = 0; j < 4; j++)
|
for(j = 0; j < 4; j++)
|
||||||
@ -271,7 +329,15 @@ void FCEU_PutImage(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
//B
|
//B
|
||||||
color = c&2?0xA7:0xCF;
|
if (held&2) { //If auto-hold
|
||||||
|
if (!(ci&2) ) color = ahold;
|
||||||
|
else
|
||||||
|
color = (c&2) ? on : off; //If the button is pressed down (immediate) that negates auto hold, however it is only off if the previous frame the button wasn't pressed!
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (c&2) color = (ci&2) ? blend : on; //If immedaite buttons are pressed and they match the previous frame, blend the colors
|
||||||
|
else color = (ci&2) ? oni : off;
|
||||||
|
}
|
||||||
for(i=0; i < 4; i++)
|
for(i=0; i < 4; i++)
|
||||||
{
|
{
|
||||||
for(j = 0; j < 4; j++)
|
for(j = 0; j < 4; j++)
|
||||||
@ -282,21 +348,45 @@ void FCEU_PutImage(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
//Select
|
//Select
|
||||||
color = c&4?0xA7:0xCF;
|
if (held&4) { //If auto-hold
|
||||||
|
if (!(ci&4) ) color = ahold;
|
||||||
|
else
|
||||||
|
color = (c&4) ? on : off; //If the button is pressed down (immediate) that negates auto hold, however it is only off if the previous frame the button wasn't pressed!
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (c&4) color = (ci&4) ? blend : on; //If immedaite buttons are pressed and they match the previous frame, blend the colors
|
||||||
|
else color = (ci&4) ? oni : off;
|
||||||
|
}
|
||||||
for(i = 0; i < 4; i++)
|
for(i = 0; i < 4; i++)
|
||||||
{
|
{
|
||||||
t[11+5*256+i] = color;
|
t[11+5*256+i] = color;
|
||||||
t[11+6*256+i] = color;
|
t[11+6*256+i] = color;
|
||||||
}
|
}
|
||||||
//Start
|
//Start
|
||||||
color = c&8?0xA7:0xCF;
|
if (held&8) { //If auto-hold
|
||||||
|
if (!(ci&8) ) color = ahold;
|
||||||
|
else
|
||||||
|
color = (c&8) ? on : off; //If the button is pressed down (immediate) that negates auto hold, however it is only off if the previous frame the button wasn't pressed!
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (c&8) color = (ci&8) ? blend : on; //If immedaite buttons are pressed and they match the previous frame, blend the colors
|
||||||
|
else color = (ci&8) ? oni : off;
|
||||||
|
}
|
||||||
for(i = 0; i < 4; i++)
|
for(i = 0; i < 4; i++)
|
||||||
{
|
{
|
||||||
t[17+5*256+i] = color;
|
t[17+5*256+i] = color;
|
||||||
t[17+6*256+i] = color;
|
t[17+6*256+i] = color;
|
||||||
}
|
}
|
||||||
//Up
|
//Up
|
||||||
color = c&16?0xA7:0xCF;
|
if (held&16) { //If auto-hold
|
||||||
|
if (!(ci&16) ) color = ahold;
|
||||||
|
else
|
||||||
|
color = (c&16) ? on : off; //If the button is pressed down (immediate) that negates auto hold, however it is only off if the previous frame the button wasn't pressed!
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (c&16) color = (ci&16) ? blend : on; //If immedaite buttons are pressed and they match the previous frame, blend the colors
|
||||||
|
else color = (ci&16) ? oni : off;
|
||||||
|
}
|
||||||
for(i = 0; i < 3; i++)
|
for(i = 0; i < 3; i++)
|
||||||
{
|
{
|
||||||
for(j = 0; j < 3; j++)
|
for(j = 0; j < 3; j++)
|
||||||
@ -305,7 +395,15 @@ void FCEU_PutImage(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
//Down
|
//Down
|
||||||
color = c&32?0xA7:0xCF;
|
if (held&32) { //If auto-hold
|
||||||
|
if (!(ci&32) ) color = ahold;
|
||||||
|
else
|
||||||
|
color = (c&32) ? on : off; //If the button is pressed down (immediate) that negates auto hold, however it is only off if the previous frame the button wasn't pressed!
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (c&32) color = (ci&32) ? blend : on; //If immedaite buttons are pressed and they match the previous frame, blend the colors
|
||||||
|
else color = (ci&32) ? oni : off;
|
||||||
|
}
|
||||||
for(i = 0; i < 3; i++)
|
for(i = 0; i < 3; i++)
|
||||||
{
|
{
|
||||||
for(j = 0; j < 3; j++)
|
for(j = 0; j < 3; j++)
|
||||||
@ -314,7 +412,15 @@ void FCEU_PutImage(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
//Left
|
//Left
|
||||||
color = c&64?0xA7:0xCF;
|
if (held&64) { //If auto-hold
|
||||||
|
if (!(ci&64) ) color = ahold;
|
||||||
|
else
|
||||||
|
color = (c&64) ? on : off; //If the button is pressed down (immediate) that negates auto hold, however it is only off if the previous frame the button wasn't pressed!
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (c&64) color = (ci&64) ? blend : on; //If immedaite buttons are pressed and they match the previous frame, blend the colors
|
||||||
|
else color = (ci&64) ? oni : off;
|
||||||
|
}
|
||||||
for(i = 0; i < 3; i++)
|
for(i = 0; i < 3; i++)
|
||||||
{
|
{
|
||||||
for(j = 0; j < 3; j++)
|
for(j = 0; j < 3; j++)
|
||||||
@ -323,7 +429,15 @@ void FCEU_PutImage(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
//Right
|
//Right
|
||||||
color = c&128?0xA7:0xCF;
|
if (held&128) { //If auto-hold
|
||||||
|
if (!(ci&128) ) color = ahold;
|
||||||
|
else
|
||||||
|
color = (c&128) ? on : off; //If the button is pressed down (immediate) that negates auto hold, however it is only off if the previous frame the button wasn't pressed!
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (c&128) color = (ci&128) ? blend : on; //If immedaite buttons are pressed and they match the previous frame, blend the colors
|
||||||
|
else color = (ci&128) ? oni : off;
|
||||||
|
}
|
||||||
for(i = 0; i < 3; i++)
|
for(i = 0; i < 3; i++)
|
||||||
{
|
{
|
||||||
for(j = 0; j < 3; j++)
|
for(j = 0; j < 3; j++)
|
||||||
@ -345,21 +459,25 @@ void FCEU_DispMessageOnMovie(char *format, ...)
|
|||||||
|
|
||||||
guiMessage.howlong = 180;
|
guiMessage.howlong = 180;
|
||||||
guiMessage.isMovieMessage = true;
|
guiMessage.isMovieMessage = true;
|
||||||
|
guiMessage.linesFromBottom = 0;
|
||||||
|
|
||||||
if (FCEUI_AviIsRecording() && FCEUI_AviDisableMovieMessages())
|
if (FCEUI_AviIsRecording() && FCEUI_AviDisableMovieMessages())
|
||||||
guiMessage.howlong = 0;
|
guiMessage.howlong = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FCEU_DispMessage(char *format, ...)
|
void FCEU_DispMessage(char *format, int disppos=0, ...)
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
|
||||||
va_start(ap,format);
|
va_start(ap,disppos);
|
||||||
vsnprintf(guiMessage.errmsg,sizeof(guiMessage.errmsg),format,ap);
|
vsnprintf(guiMessage.errmsg,sizeof(guiMessage.errmsg),format,ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
|
|
||||||
guiMessage.howlong = 180;
|
guiMessage.howlong = 180;
|
||||||
guiMessage.isMovieMessage = false;
|
guiMessage.isMovieMessage = false;
|
||||||
|
|
||||||
|
guiMessage.linesFromBottom = disppos;
|
||||||
|
|
||||||
//adelikat: Pretty sure this code fails, Movie playback stopped is done with FCEU_DispMessageOnMovie()
|
//adelikat: Pretty sure this code fails, Movie playback stopped is done with FCEU_DispMessageOnMovie()
|
||||||
#ifdef CREATE_AVI
|
#ifdef CREATE_AVI
|
||||||
if(LoggingEnabled == 2)
|
if(LoggingEnabled == 2)
|
||||||
@ -377,6 +495,7 @@ void FCEU_ResetMessages()
|
|||||||
{
|
{
|
||||||
guiMessage.howlong = 0;
|
guiMessage.howlong = 0;
|
||||||
guiMessage.isMovieMessage = false;
|
guiMessage.isMovieMessage = false;
|
||||||
|
guiMessage.linesFromBottom = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -414,6 +533,34 @@ static int WritePNGChunk(FILE *fp, uint32 size, char *type, uint8 *data)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32 GetScreenPixel(int x, int y, bool usebackup) {
|
||||||
|
|
||||||
|
uint8 r,g,b;
|
||||||
|
|
||||||
|
if (((x < 0) || (x > 255)) || ((y < 0) || (y > 255)))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (usebackup)
|
||||||
|
FCEUD_GetPalette(XBackBuf[(y*256)+x],&r,&g,&b);
|
||||||
|
else
|
||||||
|
FCEUD_GetPalette(XBuf[(y*256)+x],&r,&g,&b);
|
||||||
|
|
||||||
|
|
||||||
|
return ((int) (r) << 16) | ((int) (g) << 8) | (int) (b);
|
||||||
|
}
|
||||||
|
|
||||||
|
int GetScreenPixelPalette(int x, int y, bool usebackup) {
|
||||||
|
|
||||||
|
if (((x < 0) || (x > 255)) || ((y < 0) || (y > 255)))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (usebackup)
|
||||||
|
return XBackBuf[(y*256)+x] & 0x3f;
|
||||||
|
else
|
||||||
|
return XBuf[(y*256)+x] & 0x3f;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
int SaveSnapshot(void)
|
int SaveSnapshot(void)
|
||||||
{
|
{
|
||||||
unsigned int lastu=0;
|
unsigned int lastu=0;
|
||||||
@ -440,6 +587,7 @@ int SaveSnapshot(void)
|
|||||||
if(!(pp=FCEUD_UTF8fopen(fn,"wb")))
|
if(!(pp=FCEUD_UTF8fopen(fn,"wb")))
|
||||||
{
|
{
|
||||||
free(fn);
|
free(fn);
|
||||||
|
free(compmem);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
free(fn);
|
free(fn);
|
||||||
@ -510,6 +658,101 @@ int SaveSnapshot(void)
|
|||||||
return u+1;
|
return u+1;
|
||||||
|
|
||||||
|
|
||||||
|
PNGerr:
|
||||||
|
if(compmem)
|
||||||
|
free(compmem);
|
||||||
|
if(pp)
|
||||||
|
fclose(pp);
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
//overloaded SaveSnapshot for "Savesnapshot As" function
|
||||||
|
int SaveSnapshot(char fileName[512])
|
||||||
|
{
|
||||||
|
int totallines=FSettings.LastSLine-FSettings.FirstSLine+1;
|
||||||
|
int x,y;
|
||||||
|
FILE *pp=NULL;
|
||||||
|
uint8 *compmem=NULL;
|
||||||
|
uLongf compmemsize=totallines*263+12;
|
||||||
|
|
||||||
|
if(!(compmem=(uint8 *)FCEU_malloc(compmemsize)))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
pp = fopen(fileName, "w");
|
||||||
|
|
||||||
|
if(!(pp=FCEUD_UTF8fopen(fileName,"wb")))
|
||||||
|
{
|
||||||
|
free(compmem);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
static uint8 header[8]={137,80,78,71,13,10,26,10};
|
||||||
|
if(fwrite(header,8,1,pp)!=1)
|
||||||
|
goto PNGerr;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
uint8 chunko[13];
|
||||||
|
|
||||||
|
chunko[0]=chunko[1]=chunko[3]=0;
|
||||||
|
chunko[2]=0x1; // Width of 256
|
||||||
|
|
||||||
|
chunko[4]=chunko[5]=chunko[6]=0;
|
||||||
|
chunko[7]=totallines; // Height
|
||||||
|
|
||||||
|
chunko[8]=8; // bit depth
|
||||||
|
chunko[9]=3; // Color type; indexed 8-bit
|
||||||
|
chunko[10]=0; // compression: deflate
|
||||||
|
chunko[11]=0; // Basic adapative filter set(though none are used).
|
||||||
|
chunko[12]=0; // No interlace.
|
||||||
|
|
||||||
|
if(!WritePNGChunk(pp,13,"IHDR",chunko))
|
||||||
|
goto PNGerr;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
uint8 pdata[256*3];
|
||||||
|
for(x=0;x<256;x++)
|
||||||
|
FCEUD_GetPalette(x,pdata+x*3,pdata+x*3+1,pdata+x*3+2);
|
||||||
|
if(!WritePNGChunk(pp,256*3,"PLTE",pdata))
|
||||||
|
goto PNGerr;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
uint8 *tmp=XBuf+FSettings.FirstSLine*256;
|
||||||
|
uint8 *dest,*mal,*mork;
|
||||||
|
|
||||||
|
if(!(mal=mork=dest=(uint8 *)malloc((totallines<<8)+totallines)))
|
||||||
|
goto PNGerr;
|
||||||
|
// mork=dest=XBuf;
|
||||||
|
|
||||||
|
for(y=0;y<totallines;y++)
|
||||||
|
{
|
||||||
|
*dest=0; // No filter.
|
||||||
|
dest++;
|
||||||
|
for(x=256;x;x--,tmp++,dest++)
|
||||||
|
*dest=*tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(compress(compmem,&compmemsize,mork,(totallines<<8)+totallines)!=Z_OK)
|
||||||
|
{
|
||||||
|
if(mal) free(mal);
|
||||||
|
goto PNGerr;
|
||||||
|
}
|
||||||
|
if(mal) free(mal);
|
||||||
|
if(!WritePNGChunk(pp,compmemsize,"IDAT",compmem))
|
||||||
|
goto PNGerr;
|
||||||
|
}
|
||||||
|
if(!WritePNGChunk(pp,0,"IEND",0))
|
||||||
|
goto PNGerr;
|
||||||
|
|
||||||
|
free(compmem);
|
||||||
|
fclose(pp);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
|
||||||
PNGerr:
|
PNGerr:
|
||||||
if(compmem)
|
if(compmem)
|
||||||
free(compmem);
|
free(compmem);
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
int FCEU_InitVirtualVideo(void);
|
int FCEU_InitVirtualVideo(void);
|
||||||
void FCEU_KillVirtualVideo(void);
|
void FCEU_KillVirtualVideo(void);
|
||||||
int SaveSnapshot(void);
|
int SaveSnapshot(void);
|
||||||
|
int SaveSnapshot(char[]);
|
||||||
|
uint32 GetScreenPixel(int x, int y, bool usebackup);
|
||||||
|
int GetScreenPixelPalette(int x, int y, bool usebackup);
|
||||||
extern uint8 *XBuf;
|
extern uint8 *XBuf;
|
||||||
extern uint8 *XBackBuf;
|
extern uint8 *XBackBuf;
|
||||||
extern int ClipSidesOffset;
|
extern int ClipSidesOffset;
|
||||||
@ -15,8 +18,14 @@ extern struct GUIMESSAGE
|
|||||||
//indicates that the movie should be drawn even on top of movies
|
//indicates that the movie should be drawn even on top of movies
|
||||||
bool isMovieMessage;
|
bool isMovieMessage;
|
||||||
|
|
||||||
|
//in case of multiple lines, allow one to move the message
|
||||||
|
int linesFromBottom;
|
||||||
|
|
||||||
} guiMessage;
|
} guiMessage;
|
||||||
|
|
||||||
extern GUIMESSAGE subtitleMessage;
|
extern GUIMESSAGE subtitleMessage;
|
||||||
|
|
||||||
void FCEU_DrawNumberRow(uint8 *XBuf, int *nstatus, int cur);
|
void FCEU_DrawNumberRow(uint8 *XBuf, int *nstatus, int cur);
|
||||||
|
|
||||||
|
std::string FCEUI_GetSnapshotAsName();
|
||||||
|
void FCEUI_SetSnapshotAsName(std::string name);
|
@ -428,7 +428,7 @@ extern int test; test++;
|
|||||||
{
|
{
|
||||||
if(_IRQlow&FCEU_IQRESET)
|
if(_IRQlow&FCEU_IQRESET)
|
||||||
{
|
{
|
||||||
if(debug_loggingCD) LogCDVectors(0);
|
DEBUG( if(debug_loggingCD) LogCDVectors(0xFFFC); )
|
||||||
_PC=RdMem(0xFFFC);
|
_PC=RdMem(0xFFFC);
|
||||||
_PC|=RdMem(0xFFFD)<<8;
|
_PC|=RdMem(0xFFFD)<<8;
|
||||||
_jammed=0;
|
_jammed=0;
|
||||||
@ -449,7 +449,7 @@ extern int test; test++;
|
|||||||
PUSH(_PC);
|
PUSH(_PC);
|
||||||
PUSH((_P&~B_FLAG)|(U_FLAG));
|
PUSH((_P&~B_FLAG)|(U_FLAG));
|
||||||
_P|=I_FLAG;
|
_P|=I_FLAG;
|
||||||
DEBUG( if(debug_loggingCD) LogCDVectors(1) );
|
DEBUG( if(debug_loggingCD) LogCDVectors(0xFFFA) );
|
||||||
_PC=RdMem(0xFFFA);
|
_PC=RdMem(0xFFFA);
|
||||||
_PC|=RdMem(0xFFFB)<<8;
|
_PC|=RdMem(0xFFFB)<<8;
|
||||||
_IRQlow&=~FCEU_IQNMI;
|
_IRQlow&=~FCEU_IQNMI;
|
||||||
@ -464,7 +464,7 @@ extern int test; test++;
|
|||||||
PUSH(_PC);
|
PUSH(_PC);
|
||||||
PUSH((_P&~B_FLAG)|(U_FLAG));
|
PUSH((_P&~B_FLAG)|(U_FLAG));
|
||||||
_P|=I_FLAG;
|
_P|=I_FLAG;
|
||||||
DEBUG( if(debug_loggingCD) LogCDVectors(1) );
|
DEBUG( if(debug_loggingCD) LogCDVectors(0xFFFE) );
|
||||||
_PC=RdMem(0xFFFE);
|
_PC=RdMem(0xFFFE);
|
||||||
_PC|=RdMem(0xFFFF)<<8;
|
_PC|=RdMem(0xFFFF)<<8;
|
||||||
}
|
}
|
||||||
|
@ -47,10 +47,9 @@ bool SaveState (char * filepath, bool silent)
|
|||||||
SaveFile((char *)gameScreenPng, screenpath, gameScreenPngSize, silent);
|
SaveFile((char *)gameScreenPng, screenpath, gameScreenPngSize, silent);
|
||||||
}
|
}
|
||||||
|
|
||||||
memorystream save(SAVEBUFFERSIZE);
|
EMUFILE_MEMFILE save(SAVEBUFFERSIZE);
|
||||||
FCEUSS_SaveMS(&save, Z_BEST_COMPRESSION);
|
FCEUSS_SaveMS(&save, Z_BEST_COMPRESSION);
|
||||||
save.sync();
|
datasize = save.size();
|
||||||
datasize = save.tellp();
|
|
||||||
|
|
||||||
if (datasize)
|
if (datasize)
|
||||||
offset = SaveFile(save.buf(), filepath, datasize, silent);
|
offset = SaveFile(save.buf(), filepath, datasize, silent);
|
||||||
@ -90,7 +89,7 @@ bool LoadState (char * filepath, bool silent)
|
|||||||
|
|
||||||
if (offset > 0)
|
if (offset > 0)
|
||||||
{
|
{
|
||||||
memorystream save((char *)savebuffer, offset);
|
EMUFILE_MEMFILE save(savebuffer, offset);
|
||||||
FCEUSS_LoadFP(&save, SSLOADPARAM_NOBACKUP);
|
FCEUSS_LoadFP(&save, SSLOADPARAM_NOBACKUP);
|
||||||
retval = true;
|
retval = true;
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
* FCEU Support Functions
|
* FCEU Support Functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include <gctypes.h>
|
||||||
#include "fceugx.h"
|
#include "fceugx.h"
|
||||||
#include "fceusupport.h"
|
#include "fceusupport.h"
|
||||||
#include "pad.h"
|
#include "pad.h"
|
||||||
@ -16,6 +17,8 @@
|
|||||||
#include "gcvideo.h"
|
#include "gcvideo.h"
|
||||||
#include "menu.h"
|
#include "menu.h"
|
||||||
|
|
||||||
|
bool turbo = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Closes a game. Frees memory, and deinitializes the drivers.
|
* Closes a game. Frees memory, and deinitializes the drivers.
|
||||||
*/
|
*/
|
||||||
@ -36,7 +39,7 @@ FILE *FCEUD_UTF8fopen(const char *n, const char *m)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::fstream* FCEUD_UTF8_fstream(const char *fn, const char *m)
|
EMUFILE_FILE* FCEUD_UTF8_fstream(const char *n, const char *m)
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
#include <di/di.h>
|
#include <di/di.h>
|
||||||
#include <ogc/dvd.h>
|
#include <ogc/dvd.h>
|
||||||
#include <iso9660.h>
|
#include <iso9660.h>
|
||||||
|
#include <fat.h>
|
||||||
|
|
||||||
#include "fceugx.h"
|
#include "fceugx.h"
|
||||||
#include "fceusupport.h"
|
#include "fceusupport.h"
|
||||||
|
@ -12,11 +12,8 @@
|
|||||||
#ifndef _FILEOP_H_
|
#ifndef _FILEOP_H_
|
||||||
#define _FILEOP_H_
|
#define _FILEOP_H_
|
||||||
|
|
||||||
#include <gccore.h>
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <ogcsys.h>
|
|
||||||
#include <fat.h>
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#define SAVEBUFFERSIZE (1024 * 512)
|
#define SAVEBUFFERSIZE (1024 * 512)
|
||||||
|
@ -12,8 +12,6 @@
|
|||||||
#ifndef _MENU_H
|
#ifndef _MENU_H
|
||||||
#define _MENU_H
|
#define _MENU_H
|
||||||
|
|
||||||
#include <ogcsys.h>
|
|
||||||
|
|
||||||
bool GuiLoaded();
|
bool GuiLoaded();
|
||||||
void InitGUIThreads();
|
void InitGUIThreads();
|
||||||
void MainMenu (int menuitem);
|
void MainMenu (int menuitem);
|
||||||
|
@ -19,6 +19,7 @@ ConnectShare (bool silent)
|
|||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
|
#include <gccore.h>
|
||||||
#include <network.h>
|
#include <network.h>
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
#include <ogc/lwp_watchdog.h>
|
#include <ogc/lwp_watchdog.h>
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
#ifndef _PAD_H_
|
#ifndef _PAD_H_
|
||||||
#define _PAD_H_
|
#define _PAD_H_
|
||||||
|
|
||||||
#include <gccore.h>
|
#include <gctypes.h>
|
||||||
#include <wiiuse/wpad.h>
|
#include <wiiuse/wpad.h>
|
||||||
|
|
||||||
#define PI 3.14159265f
|
#define PI 3.14159265f
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
#include <zlib.h>
|
#include <zlib.h>
|
||||||
|
#include <gctypes.h>
|
||||||
|
|
||||||
#include "fceugx.h"
|
#include "fceugx.h"
|
||||||
#include "fceusupport.h"
|
#include "fceusupport.h"
|
||||||
|
Loading…
Reference in New Issue
Block a user