From e0a14909f0569dce47729350aa1909020c6a52b3 Mon Sep 17 00:00:00 2001 From: zeromus Date: Tue, 17 Jun 2008 06:55:07 +0000 Subject: [PATCH] faster compiles (mappers include 1/3 as much code now) fix some memory leaks by changing the path generation APIs to return std::string.. but it still gets strdupped by a lot of clients. switch over more movie and savestate code to use iostreams instead of stdio remove the temporary savestate stuff for more tasing speed hopefully --- src/boards/mapinc.h | 1 - src/cart.cpp | 765 ++++++++++---------- src/cheat.cpp | 1315 +++++++++++++++++----------------- src/config.cpp | 1 + src/debug.cpp | 16 +- src/drawing.cpp | 1 + src/driver.h | 6 +- src/drivers/win/basicbot.cpp | 16 +- src/drivers/win/input.cpp | 6 +- src/drivers/win/main.cpp | 2 + src/drivers/win/memwatch.cpp | 6 +- src/drivers/win/replay.cpp | 23 +- src/drivers/win/tasedit.cpp | 4 +- src/drivers/win/throttle.cpp | 1 + src/drivers/win/window.cpp | 3 +- src/fceu.cpp | 6 +- src/fceu.h | 5 +- src/fds.cpp | 1113 ++++++++++++++-------------- src/file.cpp | 122 ++-- src/file.h | 8 +- src/ines.cpp | 1 + src/input.cpp | 1 + src/movie.cpp | 42 +- src/movie.h | 3 +- src/netplay.cpp | 480 +++++++------ src/nsf.cpp | 811 ++++++++++----------- src/ops.inc | 54 +- src/palette.cpp | 514 ++++++------- src/ppu.cpp | 1 + src/state.cpp | 835 +++++++++------------ src/state.h | 5 +- src/types.h | 69 +- src/unif.cpp | 819 ++++++++++----------- src/utils/endian.cpp | 14 + src/utils/endian.h | 5 + src/utils/guid.cpp | 47 ++ src/utils/guid.h | 18 + src/utils/md5.h | 1 + src/utils/valuearray.h | 20 + src/utils/xstring.cpp | 6 + src/utils/xstring.h | 2 + src/video.cpp | 362 +++++----- src/vsuni.cpp | 1 + src/x6502.cpp | 70 +- src/x6502.h | 4 +- vc8/fceux.vcproj | 20 + 46 files changed, 3764 insertions(+), 3861 deletions(-) create mode 100644 src/utils/guid.cpp create mode 100644 src/utils/guid.h create mode 100644 src/utils/valuearray.h diff --git a/src/boards/mapinc.h b/src/boards/mapinc.h index 92a8291d..11d254ce 100644 --- a/src/boards/mapinc.h +++ b/src/boards/mapinc.h @@ -8,4 +8,3 @@ #include "../cart.h" #include "../cheat.h" #include "../unif.h" -#include diff --git a/src/cart.cpp b/src/cart.cpp index 4eca11aa..ebc31a44 100644 --- a/src/cart.cpp +++ b/src/cart.cpp @@ -1,22 +1,22 @@ /* FCE Ultra - NES/Famicom Emulator - * - * Copyright notice for this file: - * Copyright (C) 2002 Xodnizel - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ +* +* Copyright notice for this file: +* Copyright (C) 2002 Xodnizel +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ /// \file /// \brief This file contains all code for coordinating the mapping in of the address space external to the NES. @@ -28,6 +28,7 @@ #include "types.h" #include "fceu.h" #include "ppu.h" +#include "driver.h" #include "cart.h" #include "x6502.h" @@ -76,585 +77,585 @@ uint32 genieaddr[3]; static INLINE void setpageptr(int s, uint32 A, uint8 *p, int ram) { - uint32 AB=A>>11; - int x; + uint32 AB=A>>11; + int x; - if(p) - for(x=(s>>1)-1;x>=0;x--) - { - PRGIsRAM[AB+x]=ram; - Page[AB+x]=p-A; - } - else - for(x=(s>>1)-1;x>=0;x--) - { - PRGIsRAM[AB+x]=0; - Page[AB+x]=0; - } + if(p) + for(x=(s>>1)-1;x>=0;x--) + { + PRGIsRAM[AB+x]=ram; + Page[AB+x]=p-A; + } + else + for(x=(s>>1)-1;x>=0;x--) + { + PRGIsRAM[AB+x]=0; + Page[AB+x]=0; + } } static uint8 nothing[8192]; void ResetCartMapping(void) { - int x; + int x; - for(x=0;x<32;x++) - { - Page[x]=nothing-x*2048; - PRGptr[x]=CHRptr[x]=0; - PRGsize[x]=CHRsize[x]=0; - } - for(x=0;x<8;x++) - { - MMC5SPRVPage[x]=MMC5BGVPage[x]=VPageR[x]=nothing-0x400*x; - } + for(x=0;x<32;x++) + { + Page[x]=nothing-x*2048; + PRGptr[x]=CHRptr[x]=0; + PRGsize[x]=CHRsize[x]=0; + } + for(x=0;x<8;x++) + { + MMC5SPRVPage[x]=MMC5BGVPage[x]=VPageR[x]=nothing-0x400*x; + } } void SetupCartPRGMapping(int chip, uint8 *p, uint32 size, int ram) { - PRGptr[chip]=p; - PRGsize[chip]=size; + PRGptr[chip]=p; + PRGsize[chip]=size; - PRGmask2[chip]=(size>>11)-1; - PRGmask4[chip]=(size>>12)-1; - PRGmask8[chip]=(size>>13)-1; - PRGmask16[chip]=(size>>14)-1; - PRGmask32[chip]=(size>>15)-1; + PRGmask2[chip]=(size>>11)-1; + PRGmask4[chip]=(size>>12)-1; + PRGmask8[chip]=(size>>13)-1; + PRGmask16[chip]=(size>>14)-1; + PRGmask32[chip]=(size>>15)-1; - PRGram[chip]=ram?1:0; + PRGram[chip]=ram?1:0; } void SetupCartCHRMapping(int chip, uint8 *p, uint32 size, int ram) { - CHRptr[chip]=p; - CHRsize[chip]=size; + CHRptr[chip]=p; + CHRsize[chip]=size; - CHRmask1[chip]=(size>>10)-1; - CHRmask2[chip]=(size>>11)-1; - CHRmask4[chip]=(size>>12)-1; - CHRmask8[chip]=(size>>13)-1; + CHRmask1[chip]=(size>>10)-1; + CHRmask2[chip]=(size>>11)-1; + CHRmask4[chip]=(size>>12)-1; + CHRmask8[chip]=(size>>13)-1; - CHRram[chip]=ram; + CHRram[chip]=ram; } DECLFR(CartBR) { - return Page[A>>11][A]; + return Page[A>>11][A]; } DECLFW(CartBW) { - //printf("Ok: %04x:%02x, %d\n",A,V,PRGIsRAM[A>>11]); - if(PRGIsRAM[A>>11] && Page[A>>11]) - Page[A>>11][A]=V; + //printf("Ok: %04x:%02x, %d\n",A,V,PRGIsRAM[A>>11]); + if(PRGIsRAM[A>>11] && Page[A>>11]) + Page[A>>11][A]=V; } DECLFR(CartBROB) { - if(!Page[A>>11]) return(X.DB); - return Page[A>>11][A]; + if(!Page[A>>11]) return(X.DB); + return Page[A>>11][A]; } void setprg2r(int r, unsigned int A, unsigned int V) { - V&=PRGmask2[r]; - setpageptr(2,A,PRGptr[r]?(&PRGptr[r][V<<11]):0,PRGram[r]); + V&=PRGmask2[r]; + setpageptr(2,A,PRGptr[r]?(&PRGptr[r][V<<11]):0,PRGram[r]); } void setprg2(uint32 A, uint32 V) { - setprg2r(0,A,V); + setprg2r(0,A,V); } void setprg4r(int r, unsigned int A, unsigned int V) { - V&=PRGmask4[r]; - setpageptr(4,A,PRGptr[r]?(&PRGptr[r][V<<12]):0,PRGram[r]); + V&=PRGmask4[r]; + setpageptr(4,A,PRGptr[r]?(&PRGptr[r][V<<12]):0,PRGram[r]); } void setprg4(uint32 A, uint32 V) { - setprg4r(0,A,V); + setprg4r(0,A,V); } void setprg8r(int r, unsigned int A, unsigned int V) { - if(PRGsize[r]>=8192) - { - V&=PRGmask8[r]; - setpageptr(8,A,PRGptr[r]?(&PRGptr[r][V<<13]):0,PRGram[r]); - } - else - { - uint32 VA=V<<2; - int x; - for(x=0;x<4;x++) - setpageptr(2,A+(x<<11),PRGptr[r]?(&PRGptr[r][((VA+x)&PRGmask2[r])<<11]):0,PRGram[r]); - } + if(PRGsize[r]>=8192) + { + V&=PRGmask8[r]; + setpageptr(8,A,PRGptr[r]?(&PRGptr[r][V<<13]):0,PRGram[r]); + } + else + { + uint32 VA=V<<2; + int x; + for(x=0;x<4;x++) + setpageptr(2,A+(x<<11),PRGptr[r]?(&PRGptr[r][((VA+x)&PRGmask2[r])<<11]):0,PRGram[r]); + } } void setprg8(uint32 A, uint32 V) { - setprg8r(0,A,V); + setprg8r(0,A,V); } void setprg16r(int r, unsigned int A, unsigned int V) { - if(PRGsize[r]>=16384) - { - V&=PRGmask16[r]; - setpageptr(16,A,PRGptr[r]?(&PRGptr[r][V<<14]):0,PRGram[r]); - } - else - { - uint32 VA=V<<3; - int x; + if(PRGsize[r]>=16384) + { + V&=PRGmask16[r]; + setpageptr(16,A,PRGptr[r]?(&PRGptr[r][V<<14]):0,PRGram[r]); + } + else + { + uint32 VA=V<<3; + int x; - for(x=0;x<8;x++) - setpageptr(2,A+(x<<11),PRGptr[r]?(&PRGptr[r][((VA+x)&PRGmask2[r])<<11]):0,PRGram[r]); - } + for(x=0;x<8;x++) + setpageptr(2,A+(x<<11),PRGptr[r]?(&PRGptr[r][((VA+x)&PRGmask2[r])<<11]):0,PRGram[r]); + } } void setprg16(uint32 A, uint32 V) { - setprg16r(0,A,V); + setprg16r(0,A,V); } void setprg32r(int r,unsigned int A, unsigned int V) { - if(PRGsize[r]>=32768) - { - V&=PRGmask32[r]; - setpageptr(32,A,PRGptr[r]?(&PRGptr[r][V<<15]):0,PRGram[r]); - } - else - { - uint32 VA=V<<4; - int x; + if(PRGsize[r]>=32768) + { + V&=PRGmask32[r]; + setpageptr(32,A,PRGptr[r]?(&PRGptr[r][V<<15]):0,PRGram[r]); + } + else + { + uint32 VA=V<<4; + int x; - for(x=0;x<16;x++) - setpageptr(2,A+(x<<11),PRGptr[r]?(&PRGptr[r][((VA+x)&PRGmask2[r])<<11]):0,PRGram[r]); - } + for(x=0;x<16;x++) + setpageptr(2,A+(x<<11),PRGptr[r]?(&PRGptr[r][((VA+x)&PRGmask2[r])<<11]):0,PRGram[r]); + } } void setprg32(uint32 A, uint32 V) { - setprg32r(0,A,V); + setprg32r(0,A,V); } void setchr1r(int r, unsigned int A, unsigned int V) { - if(!CHRptr[r]) return; - FCEUPPU_LineUpdate(); - V&=CHRmask1[r]; - if(CHRram[r]) - PPUCHRRAM|=(1<<(A>>10)); - else - PPUCHRRAM&=~(1<<(A>>10)); - VPageR[(A)>>10]=&CHRptr[r][(V)<<10]-(A); + if(!CHRptr[r]) return; + FCEUPPU_LineUpdate(); + V&=CHRmask1[r]; + if(CHRram[r]) + PPUCHRRAM|=(1<<(A>>10)); + else + PPUCHRRAM&=~(1<<(A>>10)); + VPageR[(A)>>10]=&CHRptr[r][(V)<<10]-(A); } void setchr2r(int r, unsigned int A, unsigned int V) { - if(!CHRptr[r]) return; - FCEUPPU_LineUpdate(); - V&=CHRmask2[r]; - VPageR[(A)>>10]=VPageR[((A)>>10)+1]=&CHRptr[r][(V)<<11]-(A); - if(CHRram[r]) - PPUCHRRAM|=(3<<(A>>10)); - else - PPUCHRRAM&=~(3<<(A>>10)); + if(!CHRptr[r]) return; + FCEUPPU_LineUpdate(); + V&=CHRmask2[r]; + VPageR[(A)>>10]=VPageR[((A)>>10)+1]=&CHRptr[r][(V)<<11]-(A); + if(CHRram[r]) + PPUCHRRAM|=(3<<(A>>10)); + else + PPUCHRRAM&=~(3<<(A>>10)); } void setchr4r(int r, unsigned int A, unsigned int V) { - if(!CHRptr[r]) return; - FCEUPPU_LineUpdate(); - V&=CHRmask4[r]; - VPageR[(A)>>10]=VPageR[((A)>>10)+1]= - VPageR[((A)>>10)+2]=VPageR[((A)>>10)+3]=&CHRptr[r][(V)<<12]-(A); - if(CHRram[r]) - PPUCHRRAM|=(15<<(A>>10)); - else - PPUCHRRAM&=~(15<<(A>>10)); + if(!CHRptr[r]) return; + FCEUPPU_LineUpdate(); + V&=CHRmask4[r]; + VPageR[(A)>>10]=VPageR[((A)>>10)+1]= + VPageR[((A)>>10)+2]=VPageR[((A)>>10)+3]=&CHRptr[r][(V)<<12]-(A); + if(CHRram[r]) + PPUCHRRAM|=(15<<(A>>10)); + else + PPUCHRRAM&=~(15<<(A>>10)); } void setchr8r(int r, unsigned int V) { - int x; + int x; - if(!CHRptr[r]) return; - FCEUPPU_LineUpdate(); - V&=CHRmask8[r]; - for(x=7;x>=0;x--) - VPageR[x]=&CHRptr[r][V<<13]; - if(CHRram[r]) - PPUCHRRAM|=(255); - else - PPUCHRRAM&=~(255); + if(!CHRptr[r]) return; + FCEUPPU_LineUpdate(); + V&=CHRmask8[r]; + for(x=7;x>=0;x--) + VPageR[x]=&CHRptr[r][V<<13]; + if(CHRram[r]) + PPUCHRRAM|=(255); + else + PPUCHRRAM&=~(255); } void setchr1(unsigned int A, unsigned int V) { - setchr1r(0,A,V); + setchr1r(0,A,V); } void setchr2(unsigned int A, unsigned int V) { - setchr2r(0,A,V); + setchr2r(0,A,V); } void setchr4(unsigned int A, unsigned int V) { - setchr4r(0,A,V); + setchr4r(0,A,V); } void setchr8(unsigned int V) { - setchr8r(0,V); + setchr8r(0,V); } void setvram8(uint8 *p) { - int x; - for(x=7;x>=0;x--) - VPageR[x]=p; - PPUCHRRAM|=255; + int x; + for(x=7;x>=0;x--) + VPageR[x]=p; + PPUCHRRAM|=255; } void setvram4(uint32 A, uint8 *p) { - int x; - for(x=3;x>=0;x--) - VPageR[(A>>10)+x]=p-A; - PPUCHRRAM|=(15<<(A>>10)); + int x; + for(x=3;x>=0;x--) + VPageR[(A>>10)+x]=p-A; + PPUCHRRAM|=(15<<(A>>10)); } void setvramb1(uint8 *p, uint32 A, uint32 b) { - FCEUPPU_LineUpdate(); - VPageR[A>>10]=p-A+(b<<10); - PPUCHRRAM|=(1<<(A>>10)); + FCEUPPU_LineUpdate(); + VPageR[A>>10]=p-A+(b<<10); + PPUCHRRAM|=(1<<(A>>10)); } void setvramb2(uint8 *p, uint32 A, uint32 b) { - FCEUPPU_LineUpdate(); - VPageR[(A>>10)]=VPageR[(A>>10)+1]=p-A+(b<<11); - PPUCHRRAM|=(3<<(A>>10)); + FCEUPPU_LineUpdate(); + VPageR[(A>>10)]=VPageR[(A>>10)+1]=p-A+(b<<11); + PPUCHRRAM|=(3<<(A>>10)); } void setvramb4(uint8 *p, uint32 A, uint32 b) { - int x; + int x; - FCEUPPU_LineUpdate(); - for(x=3;x>=0;x--) - VPageR[(A>>10)+x]=p-A+(b<<12); - PPUCHRRAM|=(15<<(A>>10)); + FCEUPPU_LineUpdate(); + for(x=3;x>=0;x--) + VPageR[(A>>10)+x]=p-A+(b<<12); + PPUCHRRAM|=(15<<(A>>10)); } void setvramb8(uint8 *p, uint32 b) { - int x; + int x; - FCEUPPU_LineUpdate(); - for(x=7;x>=0;x--) - VPageR[x]=p+(b<<13); - PPUCHRRAM|=255; + FCEUPPU_LineUpdate(); + for(x=7;x>=0;x--) + VPageR[x]=p+(b<<13); + PPUCHRRAM|=255; } /* This function can be called without calling SetupCartMirroring(). */ void setntamem(uint8 *p, int ram, uint32 b) { - FCEUPPU_LineUpdate(); - vnapage[b]=p; - PPUNTARAM&=~(1<>2]=V;break; + switch(A) + { + case 0x800c: + case 0x8008: + case 0x8004:genieval[((A-4)&0xF)>>2]=V;break; - case 0x800b: - case 0x8007: - case 0x8003:geniech[((A-3)&0xF)>>2]=V;break; + case 0x800b: + case 0x8007: + case 0x8003:geniech[((A-3)&0xF)>>2]=V;break; - case 0x800a: - case 0x8006: - case 0x8002:genieaddr[((A-2)&0xF)>>2]&=0xFF00;genieaddr[((A-2)&0xF)>>2]|=V;break; + case 0x800a: + case 0x8006: + case 0x8002:genieaddr[((A-2)&0xF)>>2]&=0xFF00;genieaddr[((A-2)&0xF)>>2]|=V;break; - case 0x8009: - case 0x8005: - case 0x8001:genieaddr[((A-1)&0xF)>>2]&=0xFF;genieaddr[((A-1)&0xF)>>2]|=(V|0x80)<<8;break; + case 0x8009: + case 0x8005: + case 0x8001:genieaddr[((A-1)&0xF)>>2]&=0xFF;genieaddr[((A-1)&0xF)>>2]|=(V|0x80)<<8;break; - case 0x8000:if(!V) - FixGenieMap(); - else - { - modcon=V^0xFF; - if(V==0x71) - modcon=0; - } - break; - } + case 0x8000:if(!V) + FixGenieMap(); + else + { + modcon=V^0xFF; + if(V==0x71) + modcon=0; + } + break; + } } static readfunc GenieBackup[3]; static DECLFR(GenieFix1) { - uint8 r=GenieBackup[0](A); + uint8 r=GenieBackup[0](A); - if((modcon>>1)&1) // No check - return genieval[0]; - else if(r==geniech[0]) - return genieval[0]; + if((modcon>>1)&1) // No check + return genieval[0]; + else if(r==geniech[0]) + return genieval[0]; - return r; + return r; } static DECLFR(GenieFix2) { - uint8 r=GenieBackup[1](A); + uint8 r=GenieBackup[1](A); - if((modcon>>2)&1) // No check - return genieval[1]; - else if(r==geniech[1]) - return genieval[1]; + if((modcon>>2)&1) // No check + return genieval[1]; + else if(r==geniech[1]) + return genieval[1]; - return r; + return r; } static DECLFR(GenieFix3) { - uint8 r=GenieBackup[2](A); + uint8 r=GenieBackup[2](A); - if((modcon>>3)&1) // No check - return genieval[2]; - else if(r==geniech[2]) - return genieval[2]; + if((modcon>>3)&1) // No check + return genieval[2]; + else if(r==geniech[2]) + return genieval[2]; - return r; + return r; } void FixGenieMap(void) { - int x; + int x; - geniestage=2; + geniestage=2; - for(x=0;x<8;x++) - VPage[x]=VPageG[x]; + for(x=0;x<8;x++) + VPage[x]=VPageG[x]; - VPageR=VPage; - FlushGenieRW(); - //printf("Rightyo\n"); - for(x=0;x<3;x++) - if((modcon>>(4+x))&1) - { - readfunc tmp[3]={GenieFix1,GenieFix2,GenieFix3}; - GenieBackup[x]=GetReadHandler(genieaddr[x]); - SetReadHandler(genieaddr[x],genieaddr[x],tmp[x]); - } + VPageR=VPage; + FlushGenieRW(); + //printf("Rightyo\n"); + for(x=0;x<3;x++) + if((modcon>>(4+x))&1) + { + readfunc tmp[3]={GenieFix1,GenieFix2,GenieFix3}; + GenieBackup[x]=GetReadHandler(genieaddr[x]); + SetReadHandler(genieaddr[x],genieaddr[x],tmp[x]); + } } void GeniePower(void) { - uint32 x; + uint32 x; - if(!geniestage) - return; + if(!geniestage) + return; - geniestage=1; - for(x=0;x<3;x++) - { - genieval[x]=0xFF; - geniech[x]=0xFF; - genieaddr[x]=0xFFFF; - } - modcon=0; + geniestage=1; + for(x=0;x<3;x++) + { + genieval[x]=0xFF; + geniech[x]=0xFF; + genieaddr[x]=0xFFFF; + } + modcon=0; - SetWriteHandler(0x8000,0xFFFF,GenieWrite); - SetReadHandler(0x8000,0xFFFF,GenieRead); + SetWriteHandler(0x8000,0xFFFF,GenieWrite); + SetReadHandler(0x8000,0xFFFF,GenieRead); - for(x=0;x<8;x++) - VPage[x]=GENIEROM+4096-0x400*x; + for(x=0;x<8;x++) + VPage[x]=GENIEROM+4096-0x400*x; - if(AllocGenieRW()) - VPageR=VPageG; - else - geniestage=2; + if(AllocGenieRW()) + VPageR=VPageG; + else + geniestage=2; } void FCEU_SaveGameSave(CartInfo *LocalHWInfo) { - if(LocalHWInfo->battery && LocalHWInfo->SaveGame[0]) - { - FILE *sp; - char *soot; + if(LocalHWInfo->battery && LocalHWInfo->SaveGame[0]) + { + FILE *sp; + char *soot; - soot=FCEU_MakeFName(FCEUMKF_SAV,0,"sav"); - if((sp=FCEUD_UTF8fopen(soot,"wb"))==NULL) - { - FCEU_PrintError("WRAM file \"%s\" cannot be written to.\n",soot); - } - else - { - int x; + soot=strdup(FCEU_MakeFName(FCEUMKF_SAV,0,"sav").c_str()); + if((sp=FCEUD_UTF8fopen(soot,"wb"))==NULL) + { + FCEU_PrintError("WRAM file \"%s\" cannot be written to.\n",soot); + } + else + { + int x; - for(x=0;x<4;x++) - if(LocalHWInfo->SaveGame[x]) - { - fwrite(LocalHWInfo->SaveGame[x],1, - LocalHWInfo->SaveGameLen[x],sp); - } - } - free(soot); - } + for(x=0;x<4;x++) + if(LocalHWInfo->SaveGame[x]) + { + fwrite(LocalHWInfo->SaveGame[x],1, + LocalHWInfo->SaveGameLen[x],sp); + } + } + free(soot); + } } // hack, movie.c has to communicate with this function somehow @@ -662,22 +663,22 @@ int disableBatteryLoading=0; void FCEU_LoadGameSave(CartInfo *LocalHWInfo) { - if(LocalHWInfo->battery && LocalHWInfo->SaveGame[0] && !disableBatteryLoading) - { - FILE *sp; - char *soot; + if(LocalHWInfo->battery && LocalHWInfo->SaveGame[0] && !disableBatteryLoading) + { + FILE *sp; + char *soot; - soot=FCEU_MakeFName(FCEUMKF_SAV,0,"sav"); - sp=FCEUD_UTF8fopen(soot,"rb"); - if(sp!=NULL) - { - int x; - for(x=0;x<4;x++) - if(LocalHWInfo->SaveGame[x]) - fread(LocalHWInfo->SaveGame[x],1,LocalHWInfo->SaveGameLen[x],sp); - } - free(soot); - } + soot=strdup(FCEU_MakeFName(FCEUMKF_SAV,0,"sav").c_str()); + sp=FCEUD_UTF8fopen(soot,"rb"); + if(sp!=NULL) + { + int x; + for(x=0;x<4;x++) + if(LocalHWInfo->SaveGame[x]) + fread(LocalHWInfo->SaveGame[x],1,LocalHWInfo->SaveGameLen[x],sp); + } + free(soot); + } } diff --git a/src/cheat.cpp b/src/cheat.cpp index 0eec23b8..8bb83bd6 100644 --- a/src/cheat.cpp +++ b/src/cheat.cpp @@ -1,22 +1,22 @@ /* FCE Ultra - NES/Famicom Emulator - * - * Copyright notice for this file: - * Copyright (C) 2002 Xodnizel - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ +* +* Copyright notice for this file: +* Copyright (C) 2002 Xodnizel +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ #include #include @@ -31,35 +31,36 @@ #include "file.h" #include "cart.h" #include "memory.h" +#include "driver.h" static uint8 *CheatRPtrs[64]; void FCEU_CheatResetRAM(void) { - int x; + int x; - for(x=0;x<64;x++) - CheatRPtrs[x]=0; + for(x=0;x<64;x++) + CheatRPtrs[x]=0; } void FCEU_CheatAddRAM(int s, uint32 A, uint8 *p) { - uint32 AB=A>>10; - int x; + uint32 AB=A>>10; + int x; - for(x=s-1;x>=0;x--) - CheatRPtrs[AB+x]=p-A; + for(x=s-1;x>=0;x--) + CheatRPtrs[AB+x]=p-A; } struct CHEATF { - struct CHEATF *next; - char *name; - uint16 addr; - uint8 val; - int compare; /* -1 for no compare. */ - int type; /* 0 for replace, 1 for substitute(GG). */ - int status; + struct CHEATF *next; + char *name; + uint16 addr; + uint8 val; + int compare; /* -1 for no compare. */ + int type; /* 0 for replace, 1 for substitute(GG). */ + int status; }; typedef struct { @@ -84,500 +85,500 @@ static int savecheats; static DECLFR(SubCheatsRead) { - CHEATF_SUBFAST *s=SubCheats; - int x=numsubcheats; + CHEATF_SUBFAST *s=SubCheats; + int x=numsubcheats; - do - { - if(s->addr==A) - { - if(s->compare>=0) - { - uint8 pv=s->PrevRead(A); + do + { + if(s->addr==A) + { + if(s->compare>=0) + { + uint8 pv=s->PrevRead(A); - if(pv==s->compare) - return(s->val); - else return(pv); - } - else return(s->val); - } - s++; - } while(--x); - return(0); /* We should never get here. */ + if(pv==s->compare) + return(s->val); + else return(pv); + } + else return(s->val); + } + s++; + } while(--x); + return(0); /* We should never get here. */ } void RebuildSubCheats(void) { - int x; - struct CHEATF *c=cheats; + int x; + struct CHEATF *c=cheats; - for(x=0;xtype==1 && c->status) - { - if(GetReadHandler(c->addr)==SubCheatsRead) - { - /* Prevent a catastrophe by this check. */ - //FCEU_DispMessage("oops"); - } - else - { - SubCheats[numsubcheats].PrevRead=GetReadHandler(c->addr); - SubCheats[numsubcheats].addr=c->addr; - SubCheats[numsubcheats].val=c->val; - SubCheats[numsubcheats].compare=c->compare; - SetReadHandler(c->addr,c->addr,SubCheatsRead); - numsubcheats++; - } - } - c=c->next; - } + numsubcheats=0; + while(c) + { + if(c->type==1 && c->status) + { + if(GetReadHandler(c->addr)==SubCheatsRead) + { + /* Prevent a catastrophe by this check. */ + //FCEU_DispMessage("oops"); + } + else + { + SubCheats[numsubcheats].PrevRead=GetReadHandler(c->addr); + SubCheats[numsubcheats].addr=c->addr; + SubCheats[numsubcheats].val=c->val; + SubCheats[numsubcheats].compare=c->compare; + SetReadHandler(c->addr,c->addr,SubCheatsRead); + numsubcheats++; + } + } + c=c->next; + } } void FCEU_PowerCheats() { - numsubcheats=0; /* Quick hack to prevent setting of ancient read addresses. */ - RebuildSubCheats(); + numsubcheats=0; /* Quick hack to prevent setting of ancient read addresses. */ + RebuildSubCheats(); } static int AddCheatEntry(char *name, uint32 addr, uint8 val, int compare, int status, int type); static void CheatMemErr(void) { - FCEUD_PrintError("Error allocating memory for cheat data."); + FCEUD_PrintError("Error allocating memory for cheat data."); } /* This function doesn't allocate any memory for "name" */ static int AddCheatEntry(char *name, uint32 addr, uint8 val, int compare, int status, int type) { - struct CHEATF *temp; - if(!(temp=(struct CHEATF *)malloc(sizeof(struct CHEATF)))) - { - CheatMemErr(); - return(0); - } - temp->name=name; - temp->addr=addr; - temp->val=val; - temp->status=status; - temp->compare=compare; - temp->type=type; - temp->next=0; + struct CHEATF *temp; + if(!(temp=(struct CHEATF *)malloc(sizeof(struct CHEATF)))) + { + CheatMemErr(); + return(0); + } + temp->name=name; + temp->addr=addr; + temp->val=val; + temp->status=status; + temp->compare=compare; + temp->type=type; + temp->next=0; - if(cheats) - { - cheatsl->next=temp; - cheatsl=temp; - } - else - cheats=cheatsl=temp; + if(cheats) + { + cheatsl->next=temp; + cheatsl=temp; + } + else + cheats=cheatsl=temp; - return(1); + return(1); } void FCEU_LoadGameCheats(FILE *override) { - FILE *fp; - unsigned int addr; - unsigned int val; - unsigned int status; - unsigned int type; - unsigned int compare; - int x; + FILE *fp; + unsigned int addr; + unsigned int val; + unsigned int status; + unsigned int type; + unsigned int compare; + int x; - char linebuf[2048]; - char *namebuf; - int tc=0; - char *fn; + char linebuf[2048]; + char *namebuf; + int tc=0; + char *fn; - numsubcheats=savecheats=0; + numsubcheats=savecheats=0; - if(override) - fp = override; - else - { - fn=FCEU_MakeFName(FCEUMKF_CHEAT,0,0); - fp=FCEUD_UTF8fopen(fn,"rb"); - free(fn); - if(!fp) return; - } + if(override) + fp = override; + else + { + fn=strdup(FCEU_MakeFName(FCEUMKF_CHEAT,0,0).c_str()); + fp=FCEUD_UTF8fopen(fn,"rb"); + free(fn); + if(!fp) return; + } - FCEU_printf("Cheats file loaded.\n"); - while(fgets(linebuf,2048,fp)>0) - { - char *tbuf=linebuf; - int doc=0; + FCEU_printf("Cheats file loaded.\n"); + while(fgets(linebuf,2048,fp)>0) + { + char *tbuf=linebuf; + int doc=0; - addr=val=compare=status=type=0; + addr=val=compare=status=type=0; - if(tbuf[0]=='S') - { - tbuf++; - type=1; - } - else type=0; + if(tbuf[0]=='S') + { + tbuf++; + type=1; + } + else type=0; - if(tbuf[0]=='C') - { - tbuf++; - doc=1; - } + if(tbuf[0]=='C') + { + tbuf++; + doc=1; + } - if(tbuf[0]==':') - { - tbuf++; - status=0; - } - else status=1; + if(tbuf[0]==':') + { + tbuf++; + status=0; + } + else status=1; - if(doc) - { - char *neo=&tbuf[4+2+2+1+1+1]; - if(sscanf(tbuf,"%04x%*[:]%02x%*[:]%02x",&addr,&val,&compare)!=3) - continue; - namebuf=(char *)malloc(strlen(neo)+1); - strcpy(namebuf,neo); - } - else - { - char *neo=&tbuf[4+2+1+1]; - if(sscanf(tbuf,"%04x%*[:]%02x",&addr,&val)!=2) - continue; - namebuf=(char *)malloc(strlen(neo)+1); - strcpy(namebuf,neo); - } + if(doc) + { + char *neo=&tbuf[4+2+2+1+1+1]; + if(sscanf(tbuf,"%04x%*[:]%02x%*[:]%02x",&addr,&val,&compare)!=3) + continue; + namebuf=(char *)malloc(strlen(neo)+1); + strcpy(namebuf,neo); + } + else + { + char *neo=&tbuf[4+2+1+1]; + if(sscanf(tbuf,"%04x%*[:]%02x",&addr,&val)!=2) + continue; + namebuf=(char *)malloc(strlen(neo)+1); + strcpy(namebuf,neo); + } - for(x=0;x<(int)strlen(namebuf);x++) - { - if(namebuf[x]==10 || namebuf[x]==13) - { - namebuf[x]=0; - break; - } - else if(namebuf[x]<0x20) namebuf[x]=' '; - } + for(x=0;x<(int)strlen(namebuf);x++) + { + if(namebuf[x]==10 || namebuf[x]==13) + { + namebuf[x]=0; + break; + } + else if(namebuf[x]<0x20) namebuf[x]=' '; + } - AddCheatEntry(namebuf,addr,val,doc?compare:-1,status,type); - tc++; - } - RebuildSubCheats(); - if(!override) - fclose(fp); + AddCheatEntry(namebuf,addr,val,doc?compare:-1,status,type); + tc++; + } + RebuildSubCheats(); + if(!override) + fclose(fp); } void FCEU_FlushGameCheats(FILE *override, int nosave) { - if(CheatComp) - { - free(CheatComp); - CheatComp=0; - } - if((!savecheats || nosave) && !override) /* Always save cheats if we're being overridden. */ - { - if(cheats) - { - struct CHEATF *next=cheats; - for(;;) - { - struct CHEATF *last=next; - next=next->next; - free(last->name); - free(last); - if(!next) break; - } - cheats=cheatsl=0; - } - } - else - { - char *fn = 0; + if(CheatComp) + { + free(CheatComp); + CheatComp=0; + } + if((!savecheats || nosave) && !override) /* Always save cheats if we're being overridden. */ + { + if(cheats) + { + struct CHEATF *next=cheats; + for(;;) + { + struct CHEATF *last=next; + next=next->next; + free(last->name); + free(last); + if(!next) break; + } + cheats=cheatsl=0; + } + } + else + { + char *fn = 0; - if(!override) - fn = FCEU_MakeFName(FCEUMKF_CHEAT,0,0); + if(!override) + fn = strdup(FCEU_MakeFName(FCEUMKF_CHEAT,0,0).c_str()); - if(cheats) - { - struct CHEATF *next=cheats; - FILE *fp; + if(cheats) + { + struct CHEATF *next=cheats; + FILE *fp; - if(override) - fp = override; - else - fp=FCEUD_UTF8fopen(fn,"wb"); + if(override) + fp = override; + else + fp=FCEUD_UTF8fopen(fn,"wb"); - if(fp) - { - for(;;) - { - struct CHEATF *t; - if(next->type) - fputc('S',fp); - if(next->compare>=0) - fputc('C',fp); + if(fp) + { + for(;;) + { + struct CHEATF *t; + if(next->type) + fputc('S',fp); + if(next->compare>=0) + fputc('C',fp); - if(!next->status) - fputc(':',fp); + if(!next->status) + fputc(':',fp); - if(next->compare>=0) - fprintf(fp,"%04x:%02x:%02x:%s\n",next->addr,next->val,next->compare,next->name); - else - fprintf(fp,"%04x:%02x:%s\n",next->addr,next->val,next->name); + if(next->compare>=0) + fprintf(fp,"%04x:%02x:%02x:%s\n",next->addr,next->val,next->compare,next->name); + else + fprintf(fp,"%04x:%02x:%s\n",next->addr,next->val,next->name); - free(next->name); - t=next; - next=next->next; - free(t); - if(!next) break; - } - if(!override) - fclose(fp); - } - else - FCEUD_PrintError("Error saving cheats."); - cheats=cheatsl=0; - } - else if(!override) - remove(fn); - if(!override) - free(fn); - } + free(next->name); + t=next; + next=next->next; + free(t); + if(!next) break; + } + if(!override) + fclose(fp); + } + else + FCEUD_PrintError("Error saving cheats."); + cheats=cheatsl=0; + } + else if(!override) + remove(fn); + if(!override) + free(fn); + } - RebuildSubCheats(); /* Remove memory handlers. */ + RebuildSubCheats(); /* Remove memory handlers. */ } int FCEUI_AddCheat(const char *name, uint32 addr, uint8 val, int compare, int type) { - char *t; + char *t; - if(!(t=(char *)malloc(strlen(name)+1))) - { - CheatMemErr(); - return(0); - } - strcpy(t,name); - if(!AddCheatEntry(t,addr,val,compare,1,type)) - { - free(t); - return(0); - } - savecheats=1; - RebuildSubCheats(); - return(1); + if(!(t=(char *)malloc(strlen(name)+1))) + { + CheatMemErr(); + return(0); + } + strcpy(t,name); + if(!AddCheatEntry(t,addr,val,compare,1,type)) + { + free(t); + return(0); + } + savecheats=1; + RebuildSubCheats(); + return(1); } int FCEUI_DelCheat(uint32 which) { - struct CHEATF *prev; - struct CHEATF *cur; - uint32 x=0; + struct CHEATF *prev; + struct CHEATF *cur; + uint32 x=0; - for(prev=0,cur=cheats;;) - { - if(x==which) // Remove this cheat. - { - if(prev) // Update pointer to this cheat. - { - if(cur->next) // More cheats. - prev->next=cur->next; - else // No more. - { - prev->next=0; - cheatsl=prev; // Set the previous cheat as the last cheat. - } - } - else // This is the first cheat. - { - if(cur->next) // More cheats - cheats=cur->next; - else - cheats=cheatsl=0; // No (more) cheats. - } - free(cur->name); // Now that all references to this cheat are removed, - free(cur); // free the memory. - break; - } // *END REMOVE THIS CHEAT* + for(prev=0,cur=cheats;;) + { + if(x==which) // Remove this cheat. + { + if(prev) // Update pointer to this cheat. + { + if(cur->next) // More cheats. + prev->next=cur->next; + else // No more. + { + prev->next=0; + cheatsl=prev; // Set the previous cheat as the last cheat. + } + } + else // This is the first cheat. + { + if(cur->next) // More cheats + cheats=cur->next; + else + cheats=cheatsl=0; // No (more) cheats. + } + free(cur->name); // Now that all references to this cheat are removed, + free(cur); // free the memory. + break; + } // *END REMOVE THIS CHEAT* - if(!cur->next) // No more cheats to go through(this shouldn't ever happen...) - return(0); - prev=cur; - cur=prev->next; - x++; - } + if(!cur->next) // No more cheats to go through(this shouldn't ever happen...) + return(0); + prev=cur; + cur=prev->next; + x++; + } - savecheats=1; - RebuildSubCheats(); + savecheats=1; + RebuildSubCheats(); - return(1); + return(1); } void FCEU_ApplyPeriodicCheats(void) { - struct CHEATF *cur=cheats; - if(!cur) return; + struct CHEATF *cur=cheats; + if(!cur) return; - for(;;) - { - if(cur->status && !(cur->type)) - if(CheatRPtrs[cur->addr>>10]) - CheatRPtrs[cur->addr>>10][cur->addr]=cur->val; - if(cur->next) - cur=cur->next; - else - break; - } + for(;;) + { + if(cur->status && !(cur->type)) + if(CheatRPtrs[cur->addr>>10]) + CheatRPtrs[cur->addr>>10][cur->addr]=cur->val; + if(cur->next) + cur=cur->next; + else + break; + } } void FCEUI_ListCheats(int (*callb)(char *name, uint32 a, uint8 v, int compare, int s, int type, void *data), void *data) { - struct CHEATF *next=cheats; + struct CHEATF *next=cheats; - while(next) - { - if(!callb(next->name,next->addr,next->val,next->compare,next->status,next->type,data)) break; - next=next->next; - } + while(next) + { + if(!callb(next->name,next->addr,next->val,next->compare,next->status,next->type,data)) break; + next=next->next; + } } int FCEUI_GetCheat(uint32 which, char **name, uint32 *a, uint8 *v, int *compare, int *s, int *type) { - struct CHEATF *next=cheats; - uint32 x=0; + struct CHEATF *next=cheats; + uint32 x=0; - while(next) - { - if(x==which) - { - if(name) - *name=next->name; - if(a) - *a=next->addr; - if(v) - *v=next->val; - if(s) - *s=next->status; - if(compare) - *compare=next->compare; - if(type) - *type=next->type; - return(1); - } - next=next->next; - x++; - } - return(0); + while(next) + { + if(x==which) + { + if(name) + *name=next->name; + if(a) + *a=next->addr; + if(v) + *v=next->val; + if(s) + *s=next->status; + if(compare) + *compare=next->compare; + if(type) + *type=next->type; + return(1); + } + next=next->next; + x++; + } + return(0); } static int GGtobin(char c) { - static char lets[16]={'A','P','Z','L','G','I','T','Y','E','O','X','U','K','S','V','N'}; - int x; + static char lets[16]={'A','P','Z','L','G','I','T','Y','E','O','X','U','K','S','V','N'}; + int x; - for(x=0;x<16;x++) - if(lets[x] == toupper(c)) return(x); - return(0); + for(x=0;x<16;x++) + if(lets[x] == toupper(c)) return(x); + return(0); } /* Returns 1 on success, 0 on failure. Sets *a,*v,*c. */ int FCEUI_DecodeGG(const char *str, int *a, int *v, int *c) { - uint16 A; - uint8 V,C; - uint8 t; - int s; + uint16 A; + uint8 V,C; + uint8 t; + int s; - A=0x8000; - V=0; - C=0; + A=0x8000; + V=0; + C=0; - s=strlen(str); - if(s!=6 && s!=8) return(0); + s=strlen(str); + if(s!=6 && s!=8) return(0); - t=GGtobin(*str++); - V|=(t&0x07); - V|=(t&0x08)<<4; + t=GGtobin(*str++); + V|=(t&0x07); + V|=(t&0x08)<<4; - t=GGtobin(*str++); - V|=(t&0x07)<<4; - A|=(t&0x08)<<4; + t=GGtobin(*str++); + V|=(t&0x07)<<4; + A|=(t&0x08)<<4; - t=GGtobin(*str++); - A|=(t&0x07)<<4; - //if(t&0x08) return(0); /* 8-character code?! */ + t=GGtobin(*str++); + A|=(t&0x07)<<4; + //if(t&0x08) return(0); /* 8-character code?! */ - t=GGtobin(*str++); - A|=(t&0x07)<<12; - A|=(t&0x08); + t=GGtobin(*str++); + A|=(t&0x07)<<12; + A|=(t&0x08); - t=GGtobin(*str++); - A|=(t&0x07); - A|=(t&0x08)<<8; + t=GGtobin(*str++); + A|=(t&0x07); + A|=(t&0x08)<<8; - if(s==6) - { - t=GGtobin(*str++); - A|=(t&0x07)<<8; - V|=(t&0x08); + if(s==6) + { + t=GGtobin(*str++); + A|=(t&0x07)<<8; + V|=(t&0x08); - *a=A; - *v=V; - *c=-1; - return(1); - } - else - { - t=GGtobin(*str++); - A|=(t&0x07)<<8; - C|=(t&0x08); + *a=A; + *v=V; + *c=-1; + return(1); + } + else + { + t=GGtobin(*str++); + A|=(t&0x07)<<8; + C|=(t&0x08); - t=GGtobin(*str++); - C|=(t&0x07); - C|=(t&0x08)<<4; + t=GGtobin(*str++); + C|=(t&0x07); + C|=(t&0x08)<<4; - t=GGtobin(*str++); - C|=(t&0x07)<<4; - V|=(t&0x08); - *a=A; - *v=V; - *c=C; - return(1); - } - return(0); + t=GGtobin(*str++); + C|=(t&0x07)<<4; + V|=(t&0x08); + *a=A; + *v=V; + *c=C; + return(1); + } + return(0); } int FCEUI_DecodePAR(const char *str, int *a, int *v, int *c, int *type) { - int boo[4]; - if(strlen(str)!=8) return(0); + int boo[4]; + if(strlen(str)!=8) return(0); - sscanf(str,"%02x%02x%02x%02x",boo,boo+1,boo+2,boo+3); + sscanf(str,"%02x%02x%02x%02x",boo,boo+1,boo+2,boo+3); - *c=-1; + *c=-1; - if(1) - { - *a=(boo[3]<<8)|(boo[2]+0x7F); - *v=0; - } - else - { - *v=boo[3]; - *a=boo[2]|(boo[1]<<8); - } - /* Zero-page addressing modes don't go through the normal read/write handlers in FCEU, so - we must do the old hacky method of RAM cheats. - */ - if(*a<0x0100) - *type=0; - else - *type=1; - return(1); + if(1) + { + *a=(boo[3]<<8)|(boo[2]+0x7F); + *v=0; + } + else + { + *v=boo[3]; + *a=boo[2]|(boo[1]<<8); + } + /* Zero-page addressing modes don't go through the normal read/write handlers in FCEU, so + we must do the old hacky method of RAM cheats. + */ + if(*a<0x0100) + *type=0; + else + *type=1; + return(1); } /* name can be NULL if the name isn't going to be changed. */ @@ -585,325 +586,325 @@ int FCEUI_DecodePAR(const char *str, int *a, int *v, int *c, int *type) int FCEUI_SetCheat(uint32 which, const char *name, int32 a, int32 v, int compare,int s, int type) { - struct CHEATF *next=cheats; - uint32 x=0; + struct CHEATF *next=cheats; + uint32 x=0; - while(next) - { - if(x==which) - { - if(name) - { - char *t; + while(next) + { + if(x==which) + { + if(name) + { + char *t; - if((t=(char *)realloc(next->name,strlen(name+1)))) - { - next->name=t; - strcpy(next->name,name); - } - else - return(0); - } - if(a>=0) - next->addr=a; - if(v>=0) - next->val=v; - if(s>=0) - next->status=s; - next->compare=compare; - next->type=type; + if((t=(char *)realloc(next->name,strlen(name+1)))) + { + next->name=t; + strcpy(next->name,name); + } + else + return(0); + } + if(a>=0) + next->addr=a; + if(v>=0) + next->val=v; + if(s>=0) + next->status=s; + next->compare=compare; + next->type=type; - savecheats=1; - RebuildSubCheats(); + savecheats=1; + RebuildSubCheats(); - return(1); - } - next=next->next; - x++; - } - return(0); + return(1); + } + next=next->next; + x++; + } + return(0); } /* Convenience function. */ int FCEUI_ToggleCheat(uint32 which) { - struct CHEATF *next=cheats; - uint32 x=0; + struct CHEATF *next=cheats; + uint32 x=0; - while(next) - { - if(x==which) - { - next->status=!next->status; - savecheats=1; - RebuildSubCheats(); - return(next->status); - } - next=next->next; - x++; - } + while(next) + { + if(x==which) + { + next->status=!next->status; + savecheats=1; + RebuildSubCheats(); + return(next->status); + } + next=next->next; + x++; + } - return(-1); + return(-1); } static int InitCheatComp(void) { - uint32 x; + uint32 x; - CheatComp=(uint16*)malloc(65536*sizeof(uint16)); - if(!CheatComp) - { - CheatMemErr(); - return(0); - } - for(x=0;x<65536;x++) - CheatComp[x]=CHEATC_NONE; + CheatComp=(uint16*)malloc(65536*sizeof(uint16)); + if(!CheatComp) + { + CheatMemErr(); + return(0); + } + for(x=0;x<65536;x++) + CheatComp[x]=CHEATC_NONE; - return(1); + return(1); } void FCEUI_CheatSearchSetCurrentAsOriginal(void) { - uint32 x; - for(x=0x000;x<0x10000;x++) - if(!(CheatComp[x]&CHEATC_NOSHOW)) - { - if(CheatRPtrs[x>>10]) - CheatComp[x]=CheatRPtrs[x>>10][x]; - else - CheatComp[x]|=CHEATC_NONE; - } + uint32 x; + for(x=0x000;x<0x10000;x++) + if(!(CheatComp[x]&CHEATC_NOSHOW)) + { + if(CheatRPtrs[x>>10]) + CheatComp[x]=CheatRPtrs[x>>10][x]; + else + CheatComp[x]|=CHEATC_NONE; + } } void FCEUI_CheatSearchShowExcluded(void) { - uint32 x; + uint32 x; - for(x=0x000;x<0x10000;x++) - CheatComp[x]&=~CHEATC_EXCLUDED; + for(x=0x000;x<0x10000;x++) + CheatComp[x]&=~CHEATC_EXCLUDED; } int32 FCEUI_CheatSearchGetCount(void) { - uint32 x,c=0; + uint32 x,c=0; - if(CheatComp) - { - for(x=0x0000;x<0x10000;x++) - if(!(CheatComp[x]&CHEATC_NOSHOW) && CheatRPtrs[x>>10]) - c++; - } + if(CheatComp) + { + for(x=0x0000;x<0x10000;x++) + if(!(CheatComp[x]&CHEATC_NOSHOW) && CheatRPtrs[x>>10]) + c++; + } - return c; + return c; } /* This function will give the initial value of the search and the current value at a location. */ void FCEUI_CheatSearchGet(int (*callb)(uint32 a, uint8 last, uint8 current, void *data),void *data) { - uint32 x; + uint32 x; - if(!CheatComp) - { - if(!InitCheatComp()) - CheatMemErr(); - return; - } + if(!CheatComp) + { + if(!InitCheatComp()) + CheatMemErr(); + return; + } - for(x=0;x<0x10000;x++) - if(!(CheatComp[x]&CHEATC_NOSHOW) && CheatRPtrs[x>>10]) - if(!callb(x,CheatComp[x],CheatRPtrs[x>>10][x],data)) - break; + for(x=0;x<0x10000;x++) + if(!(CheatComp[x]&CHEATC_NOSHOW) && CheatRPtrs[x>>10]) + if(!callb(x,CheatComp[x],CheatRPtrs[x>>10][x],data)) + break; } void FCEUI_CheatSearchGetRange(uint32 first, uint32 last, int (*callb)(uint32 a, uint8 last, uint8 current)) { - uint32 x; - uint32 in=0; + uint32 x; + uint32 in=0; - if(!CheatComp) - { - if(!InitCheatComp()) - CheatMemErr(); - return; - } + if(!CheatComp) + { + if(!InitCheatComp()) + CheatMemErr(); + return; + } - for(x=0;x<0x10000;x++) - if(!(CheatComp[x]&CHEATC_NOSHOW) && CheatRPtrs[x>>10]) - { - if(in>=first) - if(!callb(x,CheatComp[x],CheatRPtrs[x>>10][x])) - break; - in++; - if(in>last) return; - } + for(x=0;x<0x10000;x++) + if(!(CheatComp[x]&CHEATC_NOSHOW) && CheatRPtrs[x>>10]) + { + if(in>=first) + if(!callb(x,CheatComp[x],CheatRPtrs[x>>10][x])) + break; + in++; + if(in>last) return; + } } void FCEUI_CheatSearchBegin(void) { - uint32 x; + uint32 x; - if(!CheatComp) - { - if(!InitCheatComp()) - { - CheatMemErr(); - return; - } - } - for(x=0;x<0x10000;x++) - { - if(CheatRPtrs[x>>10]) - CheatComp[x]=CheatRPtrs[x>>10][x]; - else - CheatComp[x]=CHEATC_NONE; - } + if(!CheatComp) + { + if(!InitCheatComp()) + { + CheatMemErr(); + return; + } + } + for(x=0;x<0x10000;x++) + { + if(CheatRPtrs[x>>10]) + CheatComp[x]=CheatRPtrs[x>>10][x]; + else + CheatComp[x]=CHEATC_NONE; + } } static int INLINE CAbs(int x) { - if(x<0) - return(0-x); - return x; + if(x<0) + return(0-x); + return x; } void FCEUI_CheatSearchEnd(int type, uint8 v1, uint8 v2) { - uint32 x; + uint32 x; - if(!CheatComp) - { - if(!InitCheatComp()) - { - CheatMemErr(); - return; - } - } + if(!CheatComp) + { + if(!InitCheatComp()) + { + CheatMemErr(); + return; + } + } -if(!type) // Change to a specific value. - { - for(x=0;x<0x10000;x++) - if(!(CheatComp[x]&CHEATC_NOSHOW)) - { - if(CheatComp[x]==v1 && CheatRPtrs[x>>10][x]==v2) - { + if(!type) // Change to a specific value. + { + for(x=0;x<0x10000;x++) + if(!(CheatComp[x]&CHEATC_NOSHOW)) + { + if(CheatComp[x]==v1 && CheatRPtrs[x>>10][x]==v2) + { - } - else - CheatComp[x]|=CHEATC_EXCLUDED; - } - } - else if(type==1) // Search for relative change(between values). - { - for(x=0;x<0x10000;x++) - if(!(CheatComp[x]&CHEATC_NOSHOW)) - { - if(CheatComp[x]==v1 && CAbs(CheatComp[x]-CheatRPtrs[x>>10][x])==v2) - { + } + else + CheatComp[x]|=CHEATC_EXCLUDED; + } + } + else if(type==1) // Search for relative change(between values). + { + for(x=0;x<0x10000;x++) + if(!(CheatComp[x]&CHEATC_NOSHOW)) + { + if(CheatComp[x]==v1 && CAbs(CheatComp[x]-CheatRPtrs[x>>10][x])==v2) + { - } - else - CheatComp[x]|=CHEATC_EXCLUDED; - } - } - else if(type==2) // Purely relative change. - { - for(x=0x000;x<0x10000;x++) - if(!(CheatComp[x]&CHEATC_NOSHOW)) - { - if(CAbs(CheatComp[x]-CheatRPtrs[x>>10][x])==v2) - { + } + else + CheatComp[x]|=CHEATC_EXCLUDED; + } + } + else if(type==2) // Purely relative change. + { + for(x=0x000;x<0x10000;x++) + if(!(CheatComp[x]&CHEATC_NOSHOW)) + { + if(CAbs(CheatComp[x]-CheatRPtrs[x>>10][x])==v2) + { - } - else - CheatComp[x]|=CHEATC_EXCLUDED; - } - } - else if(type==3) // Any change. - { - for(x=0x000;x<0x10000;x++) - if(!(CheatComp[x]&CHEATC_NOSHOW)) - { - if(CheatComp[x]!=CheatRPtrs[x>>10][x]) - { + } + else + CheatComp[x]|=CHEATC_EXCLUDED; + } + } + else if(type==3) // Any change. + { + for(x=0x000;x<0x10000;x++) + if(!(CheatComp[x]&CHEATC_NOSHOW)) + { + if(CheatComp[x]!=CheatRPtrs[x>>10][x]) + { - } - else - CheatComp[x]|=CHEATC_EXCLUDED; - } + } + else + CheatComp[x]|=CHEATC_EXCLUDED; + } - } - else if(type==4) // new value = known - { - for(x=0x000;x<0x10000;x++) - if(!(CheatComp[x]&CHEATC_NOSHOW)) - { - if(CheatRPtrs[x>>10][x]==v1) - { + } + else if(type==4) // new value = known + { + for(x=0x000;x<0x10000;x++) + if(!(CheatComp[x]&CHEATC_NOSHOW)) + { + if(CheatRPtrs[x>>10][x]==v1) + { - } - else - CheatComp[x]|=CHEATC_EXCLUDED; - } + } + else + CheatComp[x]|=CHEATC_EXCLUDED; + } - } - else if(type==5) // new value greater than - { - for(x=0x000;x<0x10000;x++) - if(!(CheatComp[x]&CHEATC_NOSHOW)) - { - if(CheatComp[x]>10][x]) - { + } + else if(type==5) // new value greater than + { + for(x=0x000;x<0x10000;x++) + if(!(CheatComp[x]&CHEATC_NOSHOW)) + { + if(CheatComp[x]>10][x]) + { - } - else - CheatComp[x]|=CHEATC_EXCLUDED; - } + } + else + CheatComp[x]|=CHEATC_EXCLUDED; + } - } - else if(type==6) // new value less than - { - for(x=0x000;x<0x10000;x++) - if(!(CheatComp[x]&CHEATC_NOSHOW)) - { - if(CheatComp[x]>CheatRPtrs[x>>10][x]) - { + } + else if(type==6) // new value less than + { + for(x=0x000;x<0x10000;x++) + if(!(CheatComp[x]&CHEATC_NOSHOW)) + { + if(CheatComp[x]>CheatRPtrs[x>>10][x]) + { - } - else - CheatComp[x]|=CHEATC_EXCLUDED; - } + } + else + CheatComp[x]|=CHEATC_EXCLUDED; + } - } - else if(type==7) // new value greater than by known value - { - for(x=0x000;x<0x10000;x++) - if(!(CheatComp[x]&CHEATC_NOSHOW)) - { - if((CheatRPtrs[x>>10][x]-CheatComp[x])==v2) - { + } + else if(type==7) // new value greater than by known value + { + for(x=0x000;x<0x10000;x++) + if(!(CheatComp[x]&CHEATC_NOSHOW)) + { + if((CheatRPtrs[x>>10][x]-CheatComp[x])==v2) + { - } - else - CheatComp[x]|=CHEATC_EXCLUDED; - } + } + else + CheatComp[x]|=CHEATC_EXCLUDED; + } - } - else if(type==8) // new value less than by known value - { - for(x=0x000;x<0x10000;x++) - if(!(CheatComp[x]&CHEATC_NOSHOW)) - { - if((CheatComp[x]-CheatRPtrs[x>>10][x])==v2) - { + } + else if(type==8) // new value less than by known value + { + for(x=0x000;x<0x10000;x++) + if(!(CheatComp[x]&CHEATC_NOSHOW)) + { + if((CheatComp[x]-CheatRPtrs[x>>10][x])==v2) + { - } - else - CheatComp[x]|=CHEATC_EXCLUDED; - } + } + else + CheatComp[x]|=CHEATC_EXCLUDED; + } - } + } } diff --git a/src/config.cpp b/src/config.cpp index 59cd69d3..ed5b6931 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -7,6 +7,7 @@ #include "types.h" #include "fceu.h" +#include "driver.h" static char *aboutString = 0; diff --git a/src/debug.cpp b/src/debug.cpp index f2307e3a..76ea2e54 100644 --- a/src/debug.cpp +++ b/src/debug.cpp @@ -386,14 +386,14 @@ int getValue(int type) case 'A': return _A; case 'X': return _X; case 'Y': return _Y; - case 'N': return _P & N_FLAG ? 1 : 0; - case 'V': return _P & V_FLAG ? 1 : 0; - case 'U': return _P & U_FLAG ? 1 : 0; - case 'B': return _P & B_FLAG ? 1 : 0; - case 'D': return _P & D_FLAG ? 1 : 0; - case 'I': return _P & I_FLAG ? 1 : 0; - case 'Z': return _P & Z_FLAG ? 1 : 0; - case 'C': return _P & C_FLAG ? 1 : 0; + case 'N': return __P & N_FLAG ? 1 : 0; + case 'V': return __P & V_FLAG ? 1 : 0; + case 'U': return __P & U_FLAG ? 1 : 0; + case 'B': return __P & B_FLAG ? 1 : 0; + case 'D': return __P & D_FLAG ? 1 : 0; + case 'I': return __P & I_FLAG ? 1 : 0; + case 'Z': return __P & Z_FLAG ? 1 : 0; + case 'C': return __P & C_FLAG ? 1 : 0; case 'P': return _PC; } diff --git a/src/drawing.cpp b/src/drawing.cpp index d8a89dbb..b4f2a99a 100644 --- a/src/drawing.cpp +++ b/src/drawing.cpp @@ -3,6 +3,7 @@ #include "drawing.h" #include "video.h" #include "movie.h" +#include "driver.h" static uint8 Font6x5[594] = { diff --git a/src/driver.h b/src/driver.h index ff7326b7..d7f0463d 100644 --- a/src/driver.h +++ b/src/driver.h @@ -3,13 +3,15 @@ #include #include -#include +#include #include "types.h" #include "git.h" 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); } std::fstream* 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); } //mbg 7/23/06 @@ -188,7 +190,7 @@ void FCEUI_LoadMovie(char *fname, bool read_only, int _stopframe); void FCEUI_MoviePlayFromBeginning(void); void FCEUI_StopMovie(void); //int FCEUI_IsMovieActive(void); -bool FCEUI_MovieGetInfo(const char* fname, MOVIE_INFO* /* [in, out] */ info, bool skipFrameCount = false); +bool FCEUI_MovieGetInfo(const std::string& fname, MOVIE_INFO* /* [in, out] */ info, bool skipFrameCount = false); char* FCEUI_MovieGetCurrentName(int addSlotNumber); void FCEUI_MovieToggleReadOnly(void); bool FCEUI_GetMovieToggleReadOnly(); diff --git a/src/drivers/win/basicbot.cpp b/src/drivers/win/basicbot.cpp index 6e348f44..c8d9c77f 100644 --- a/src/drivers/win/basicbot.cpp +++ b/src/drivers/win/basicbot.cpp @@ -2029,7 +2029,8 @@ static bool SaveBasicBot() ofn.lpstrFile=nameo; ofn.nMaxFile=256; ofn.Flags=OFN_EXPLORER|OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT; - ofn.lpstrInitialDir=FCEU_GetPath(FCEUMKF_BBOT); + std::string initdir = FCEU_GetPath(FCEUMKF_BBOT); + ofn.lpstrInitialDir=initdir.c_str(); if(GetSaveFileName(&ofn)) { /* @@ -2107,11 +2108,11 @@ static bool SaveBasicBotFile(char fn[]) error(1005); return false; } -/** - * Loads a previously saved file - * todo: need to add ensurance that saved file has the same BOT_MAXCODE value - * as currently set, or offer some kind of support for this "problem" - **/ + +// Loads a previously saved file +// todo: need to add ensurance that saved file has the same BOT_MAXCODE value +// as currently set, or offer some kind of support for this "problem" +// static bool LoadBasicBot() { const char filter[]="Basic Bot (*.bot)\0*.bot\0"; @@ -2126,7 +2127,8 @@ static bool LoadBasicBot() ofn.lpstrFile=nameo; ofn.nMaxFile=256; ofn.Flags=OFN_EXPLORER|OFN_FILEMUSTEXIST|OFN_HIDEREADONLY; - ofn.lpstrInitialDir=FCEU_GetPath(FCEUMKF_BBOT); + std::string initdir = FCEU_GetPath(FCEUMKF_BBOT); + ofn.lpstrInitialDir=initdir.c_str(); if(GetOpenFileName(&ofn)) { diff --git a/src/drivers/win/input.cpp b/src/drivers/win/input.cpp index 6045a675..e7de2942 100644 --- a/src/drivers/win/input.cpp +++ b/src/drivers/win/input.cpp @@ -1460,7 +1460,8 @@ static void PresetExport(int preset) ofn.lpstrFile=nameo; ofn.nMaxFile=256; ofn.Flags=OFN_EXPLORER|OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT; - ofn.lpstrInitialDir=FCEU_GetPath(FCEUMKF_INPUT); + std::string initdir = FCEU_GetPath(FCEUMKF_INPUT).c_str(); + ofn.lpstrInitialDir=initdir.c_str(); if(GetSaveFileName(&ofn)) { int i; @@ -1517,7 +1518,8 @@ static void PresetImport(int preset) ofn.lpstrFile=nameo; ofn.nMaxFile=256; ofn.Flags=OFN_EXPLORER|OFN_FILEMUSTEXIST|OFN_HIDEREADONLY; - ofn.lpstrInitialDir=FCEU_GetPath(FCEUMKF_INPUT); + std::string initdir = FCEU_GetPath(FCEUMKF_INPUT); + ofn.lpstrInitialDir=initdir.c_str(); if(GetOpenFileName(&ofn)) { diff --git a/src/drivers/win/main.cpp b/src/drivers/win/main.cpp index 57360539..4e70c67a 100644 --- a/src/drivers/win/main.cpp +++ b/src/drivers/win/main.cpp @@ -32,6 +32,8 @@ #include // For directories configuration dialog. #undef uint8 +#include + #include "../../types.h" #include "../../fceu.h" #include "../../state.h" diff --git a/src/drivers/win/memwatch.cpp b/src/drivers/win/memwatch.cpp index ad95bb4b..6a893a6c 100644 --- a/src/drivers/win/memwatch.cpp +++ b/src/drivers/win/memwatch.cpp @@ -363,7 +363,8 @@ static void SaveMemWatch() ofn.lpstrFile=memwLastFilename; ofn.nMaxFile=256; ofn.Flags=OFN_EXPLORER|OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT; - ofn.lpstrInitialDir=FCEU_GetPath(FCEUMKF_MEMW); + std::string initdir = FCEU_GetPath(FCEUMKF_MEMW); + ofn.lpstrInitialDir=initdir.c_str(); if(GetSaveFileName(&ofn)) { int i; @@ -478,7 +479,8 @@ static void LoadMemWatch() ofn.lpstrFile=memwLastFilename; ofn.nMaxFile=256; ofn.Flags=OFN_EXPLORER|OFN_FILEMUSTEXIST|OFN_HIDEREADONLY; - ofn.lpstrInitialDir=FCEU_GetPath(FCEUMKF_MEMW); + std::string initdir = FCEU_GetPath(FCEUMKF_MEMW); + ofn.lpstrInitialDir=initdir.c_str(); if(GetOpenFileName(&ofn)) { diff --git a/src/drivers/win/replay.cpp b/src/drivers/win/replay.cpp index d355fade..52331e6a 100644 --- a/src/drivers/win/replay.cpp +++ b/src/drivers/win/replay.cpp @@ -44,7 +44,7 @@ static char* GetReplayPath(HWND hwndDlg) _splitpath(szChoice, szDrive, szDirectory, szFilename, szExt); if(szDrive[0]=='\0' && szDirectory[0]=='\0') - fn=FCEU_MakePath(FCEUMKF_MOVIE, szChoice); // need to make a full path + fn=strdup(FCEU_MakePath(FCEUMKF_MOVIE, szChoice).c_str()); // need to make a full path else fn=strdup(szChoice); // given a full path } @@ -66,7 +66,7 @@ static char* GetRecordPath(HWND hwndDlg) _splitpath(szChoice, szDrive, szDirectory, szFilename, szExt); if(szDrive[0]=='\0' && szDirectory[0]=='\0') - fn=FCEU_MakePath(FCEUMKF_MOVIE, szChoice); // need to make a full path + fn=strdup(FCEU_MakePath(FCEUMKF_MOVIE, szChoice).c_str()); // need to make a full path else fn=strdup(szChoice); // given a full path @@ -89,7 +89,7 @@ static char* GetSavePath(HWND hwndDlg) _splitpath(fn, szDrive, szDirectory, szFilename, szExt); if(szDrive[0]=='\0' && szDirectory[0]=='\0') { - char* newfn=FCEU_MakePath(FCEUMKF_STATE, fn); // need to make a full path + char* newfn=strdup(FCEU_MakePath(FCEUMKF_STATE, fn).c_str()); // need to make a full path free(fn); fn=newfn; } @@ -255,11 +255,8 @@ BOOL CALLBACK ReplayDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lP SendDlgItemMessage(hwndDlg, IDC_CHECK_READONLY, BM_SETCHECK, replayReadOnlySetting?BST_CHECKED:BST_UNCHECKED, 0); SendDlgItemMessage(hwndDlg, IDC_CHECK_STOPMOVIE,BM_SETCHECK, BST_UNCHECKED, 0); - char* findGlob[2] = {FCEU_MakeFName(FCEUMKF_MOVIEGLOB, 0, 0), - FCEU_MakeFName(FCEUMKF_MOVIEGLOB2, 0, 0)}; - - extern int suppress_scan_chunks; - suppress_scan_chunks=1; + char* findGlob[2] = {strdup(FCEU_MakeFName(FCEUMKF_MOVIEGLOB, 0, 0).c_str()), + strdup(FCEU_MakeFName(FCEUMKF_MOVIEGLOB2, 0, 0).c_str())}; int i=0, j=0; @@ -372,8 +369,6 @@ BOOL CALLBACK ReplayDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lP } } - suppress_scan_chunks=0; - free(findGlob[0]); free(findGlob[1]); @@ -427,7 +422,7 @@ BOOL CALLBACK ReplayDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lP if(lIndex == lCount-1) { // pop open a file browser... - char *pn=FCEU_GetPath(FCEUMKF_MOVIE); + char *pn=strdup(FCEU_GetPath(FCEUMKF_MOVIE).c_str()); char szFile[MAX_PATH]={0}; OPENFILENAME ofn; //int nRet; //mbg merge 7/17/06 removed @@ -564,7 +559,7 @@ static void UpdateRecordDialog(HWND hwndDlg) static void UpdateRecordDialogPath(HWND hwndDlg, const char* fname) { - char* baseMovieDir = FCEU_GetPath(FCEUMKF_MOVIE); + char* baseMovieDir = strdup(FCEU_GetPath(FCEUMKF_MOVIE).c_str()); char* fn=0; // display a shortened filename if the file exists in the base movie directory @@ -603,7 +598,7 @@ static BOOL CALLBACK RecordDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LP // Populate the "record from..." dialog { - char* findGlob=FCEU_MakeFName(FCEUMKF_STATEGLOB, 0, 0); + char* findGlob=strdup(FCEU_MakeFName(FCEUMKF_STATEGLOB, 0, 0).c_str()); WIN32_FIND_DATA wfd; HANDLE hFind; int i=0; @@ -731,7 +726,7 @@ static BOOL CALLBACK RecordDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LP void FCEUD_MovieRecordTo() { struct CreateMovieParameters p; - p.szFilename = FCEU_MakeFName(FCEUMKF_MOVIE,0,0); + p.szFilename = strdup(FCEU_MakeFName(FCEUMKF_MOVIE,0,0).c_str()); if(DialogBoxParam(fceu_hInstance, "IDD_RECORDINP", hAppWnd, RecordDialogProc, (LPARAM)&p)) { diff --git a/src/drivers/win/tasedit.cpp b/src/drivers/win/tasedit.cpp index 88d24abf..c3ae3fcd 100644 --- a/src/drivers/win/tasedit.cpp +++ b/src/drivers/win/tasedit.cpp @@ -1,4 +1,5 @@ #include +#include #include "common.h" #include "tasedit.h" @@ -305,7 +306,8 @@ static void Export() ofn.lpstrFilter=filter; ofn.lpstrFile=fname; ofn.nMaxFile=256; - ofn.lpstrInitialDir=FCEU_GetPath(FCEUMKF_MOVIE); + std::string initdir = FCEU_GetPath(FCEUMKF_MOVIE); + ofn.lpstrInitialDir=initdir.c_str(); if(GetSaveFileName(&ofn)) { fstream* osRecordingMovie = FCEUD_UTF8_fstream(ofn.lpstrFile, "wb"); diff --git a/src/drivers/win/throttle.cpp b/src/drivers/win/throttle.cpp index 803c910d..0557166e 100644 --- a/src/drivers/win/throttle.cpp +++ b/src/drivers/win/throttle.cpp @@ -21,6 +21,7 @@ #include "../../types.h" #include "../../fceu.h" #include "windows.h" +#include "driver.h" static uint64 tmethod,tfreq; static uint64 desiredfps; diff --git a/src/drivers/win/window.cpp b/src/drivers/win/window.cpp index d269c8e0..74ad005d 100644 --- a/src/drivers/win/window.cpp +++ b/src/drivers/win/window.cpp @@ -504,7 +504,8 @@ void LoadNewGamey(HWND hParent, const char *initialdir) ofn.lpstrFile=nameo; ofn.nMaxFile=256; ofn.Flags=OFN_EXPLORER|OFN_FILEMUSTEXIST|OFN_HIDEREADONLY; //OFN_EXPLORER|OFN_ENABLETEMPLATE|OFN_ENABLEHOOK; - ofn.lpstrInitialDir = initialdir ? initialdir : FCEU_GetPath(FCEUMKF_ROMS); + std::string stdinitdir =FCEU_GetPath(FCEUMKF_ROMS); + ofn.lpstrInitialDir = initialdir ? initialdir : stdinitdir.c_str(); // Show the Open File dialog if(GetOpenFileName(&ofn)) diff --git a/src/fceu.cpp b/src/fceu.cpp index 1c6fb188..66081ba8 100644 --- a/src/fceu.cpp +++ b/src/fceu.cpp @@ -316,7 +316,7 @@ FCEUGI *FCEUI_LoadGame(const char *name, int OverwriteVidMode) FCEU_printf("Loading %s...\n\n",name); GetFileBase(name); - ipsfn=FCEU_MakeFName(FCEUMKF_IPS,0,0); + ipsfn=strdup(FCEU_MakeFName(FCEUMKF_IPS,0,0).c_str()); fp=FCEU_fopen(name,ipsfn,"rb",0); free(ipsfn); @@ -817,7 +817,7 @@ void UpdateRewind(void) if(RewindCounter == 0) { RewindIndex = (RewindIndex + 1) % 4; - f = FCEU_MakeFName(FCEUMKF_REWINDSTATE,RewindIndex,0); + f = strdup(FCEU_MakeFName(FCEUMKF_REWINDSTATE,RewindIndex,0).c_str()); FCEUSS_Save(f); free(f); RewindStatus[RewindIndex] = 1; @@ -832,7 +832,7 @@ void FCEUI_Rewind(void) if(RewindStatus[RewindIndex] == 1) { char * f; - f = FCEU_MakeFName(FCEUMKF_REWINDSTATE,RewindIndex,0); + f = strdup(FCEU_MakeFName(FCEUMKF_REWINDSTATE,RewindIndex,0).c_str()); FCEUSS_Load(f); free(f); diff --git a/src/fceu.h b/src/fceu.h index 5bb18294..e403e380 100644 --- a/src/fceu.h +++ b/src/fceu.h @@ -1,9 +1,6 @@ #ifndef _FCEUH #define _FCEUH -#include -#include - extern int fceuindbg; void ResetGameLoaded(void); @@ -65,7 +62,7 @@ extern int GameAttributes; extern uint8 PAL; -#include "driver.h" +//#include "driver.h" typedef struct { int PAL; diff --git a/src/fds.cpp b/src/fds.cpp index 67289d4d..de369c8d 100644 --- a/src/fds.cpp +++ b/src/fds.cpp @@ -1,22 +1,22 @@ /* FCE Ultra - NES/Famicom Emulator - * - * Copyright notice for this file: - * Copyright (C) 2002 Xodnizel - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ +* +* Copyright notice for this file: +* Copyright (C) 2002 Xodnizel +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ #include #include @@ -34,12 +34,13 @@ #include "file.h" #include "cart.h" #include "netplay.h" +#include "driver.h" + +// TODO: Add code to put a delay in between the time a disk is inserted +// and the when it can be successfully read/written to. This should +// prevent writes to wrong places OR add code to prevent disk ejects +// when the virtual motor is on(mmm...virtual motor). -/* TODO: Add code to put a delay in between the time a disk is inserted - and the when it can be successfully read/written to. This should - prevent writes to wrong places OR add code to prevent disk ejects - when the virtual motor is on(mmm...virtual motor). -*/ static DECLFR(FDSRead4030); static DECLFR(FDSRead4031); @@ -85,26 +86,26 @@ static uint8 SelectDisk,InDisk; void FDSGI(int h) { - switch(h) - { - case GI_CLOSE: FDSClose();break; - case GI_POWER: FDSInit();break; - } + switch(h) + { + case GI_CLOSE: FDSClose();break; + case GI_POWER: FDSInit();break; + } } static void FDSStateRestore(int version) { - int x; + int x; - setmirror(((FDSRegs[5]&8)>>3)^1); + setmirror(((FDSRegs[5]&8)>>3)^1); - if(version >= 9810) - for(x=0;x= 9810) + for(x=0;x>1,(SelectDisk&1)?"B":"A"); - InDisk=SelectDisk; - } - else - { - FCEU_DispMessage("Disk %d Side %s Ejected",SelectDisk>>1,(SelectDisk&1)?"B":"A"); - InDisk=255; - } + { + FCEU_DispMessage("Disk %d Side %s Inserted",SelectDisk>>1,(SelectDisk&1)?"B":"A"); + InDisk=SelectDisk; + } + else + { + FCEU_DispMessage("Disk %d Side %s Ejected",SelectDisk>>1,(SelectDisk&1)?"B":"A"); + InDisk=255; + } } /* void FCEU_FDSEject(void) { - InDisk=255; +InDisk=255; } */ void FCEU_FDSSelect(void) { if(TotalSides==0) { - FCEU_DispMessage("Not FDS; can't select disk."); - return; + FCEU_DispMessage("Not FDS; can't select disk."); + return; } if(InDisk!=255) - { - FCEU_DispMessage("Eject disk before selecting."); - return; - } - SelectDisk=((SelectDisk+1)%TotalSides)&3; - FCEU_DispMessage("Disk %d Side %c Selected",SelectDisk>>1,(SelectDisk&1)?'B':'A'); + { + FCEU_DispMessage("Eject disk before selecting."); + return; + } + SelectDisk=((SelectDisk+1)%TotalSides)&3; + FCEU_DispMessage("Disk %d Side %c Selected",SelectDisk>>1,(SelectDisk&1)?'B':'A'); } static void FDSFix(int a) { - if((IRQa&2) && IRQCount) - { - IRQCount-=a; - if(IRQCount<=0) - { - if(!(IRQa&1)) - { - IRQa&=~2; - IRQCount=IRQLatch=0; - } - else - IRQCount=IRQLatch; - //IRQCount=IRQLatch; //0xFFFF; - X6502_IRQBegin(FCEU_IQEXT); - //printf("IRQ: %d\n",timestamp); -// printf("IRQ: %d\n",scanline); - } - } - if(DiskSeekIRQ>0) - { - DiskSeekIRQ-=a; - if(DiskSeekIRQ<=0) - { - if(FDSRegs[5]&0x80) - { - X6502_IRQBegin(FCEU_IQEXT2); - } - } - } + if((IRQa&2) && IRQCount) + { + IRQCount-=a; + if(IRQCount<=0) + { + if(!(IRQa&1)) + { + IRQa&=~2; + IRQCount=IRQLatch=0; + } + else + IRQCount=IRQLatch; + //IRQCount=IRQLatch; //0xFFFF; + X6502_IRQBegin(FCEU_IQEXT); + //printf("IRQ: %d\n",timestamp); + // printf("IRQ: %d\n",scanline); + } + } + if(DiskSeekIRQ>0) + { + DiskSeekIRQ-=a; + if(DiskSeekIRQ<=0) + { + if(FDSRegs[5]&0x80) + { + X6502_IRQBegin(FCEU_IQEXT2); + } + } + } } static DECLFR(FDSRead4030) @@ -227,8 +228,8 @@ static DECLFR(FDSRead4030) if(!fceuindbg) { - X6502_IRQEnd(FCEU_IQEXT); - X6502_IRQEnd(FCEU_IQEXT2); + X6502_IRQEnd(FCEU_IQEXT); + X6502_IRQEnd(FCEU_IQEXT2); } return ret; } @@ -238,27 +239,27 @@ static DECLFR(FDSRead4031) static uint8 z=0; if(InDisk!=255) { - z=diskdata[InDisk][DiskPtr]; - if(!fceuindbg) - { - if(DiskPtr<64999) DiskPtr++; - DiskSeekIRQ=150; - X6502_IRQEnd(FCEU_IQEXT2); - } + z=diskdata[InDisk][DiskPtr]; + if(!fceuindbg) + { + if(DiskPtr<64999) DiskPtr++; + DiskSeekIRQ=150; + X6502_IRQEnd(FCEU_IQEXT2); + } } - return z; + return z; } static DECLFR(FDSRead4032) { - uint8 ret; + uint8 ret; - ret=X.DB&~7; - if(InDisk==255) - ret|=5; + ret=X.DB&~7; + if(InDisk==255) + ret|=5; - if(InDisk==255 || !(FDSRegs[5]&1) || (FDSRegs[5]&2)) - ret|=2; - return ret; + if(InDisk==255 || !(FDSRegs[5]&1) || (FDSRegs[5]&2)) + ret|=2; + return ret; } static DECLFR(FDSRead4033) @@ -268,17 +269,17 @@ static DECLFR(FDSRead4033) static DECLFW(FDSRAMWrite) { - (FDSRAM-0x6000)[A]=V; + (FDSRAM-0x6000)[A]=V; } static DECLFR(FDSBIOSRead) { - return (FDSBIOS-0xE000)[A]; + return (FDSBIOS-0xE000)[A]; } static DECLFR(FDSRAMRead) { - return (FDSRAM-0x6000)[A]; + return (FDSRAM-0x6000)[A]; } /* Begin FDS sound */ @@ -286,22 +287,22 @@ static DECLFR(FDSRAMRead) #define FDSClock (1789772.7272727272727272/2) typedef struct { - int64 cycles; // Cycles per PCM sample - int64 count; // Cycle counter - int64 envcount; // Envelope cycle counter + int64 cycles; // Cycles per PCM sample + int64 count; // Cycle counter + int64 envcount; // Envelope cycle counter uint32 b19shiftreg60; uint32 b24adder66; uint32 b24latch68; uint32 b17latch76; - int32 clockcount; // Counter to divide frequency by 8. - uint8 b8shiftreg88; // Modulation register. - uint8 amplitude[2]; // Current amplitudes. + int32 clockcount; // Counter to divide frequency by 8. + uint8 b8shiftreg88; // Modulation register. + uint8 amplitude[2]; // Current amplitudes. uint8 speedo[2]; uint8 mwcount; uint8 mwstart; - uint8 mwave[0x20]; // Modulation waveform - uint8 cwave[0x40]; // Game-defined waveform(carrier) - uint8 SPSG[0xB]; + uint8 mwave[0x20]; // Modulation waveform + uint8 cwave[0x40]; // Game-defined waveform(carrier) + uint8 SPSG[0xB]; } FDSSOUND; static FDSSOUND fdso; @@ -318,62 +319,62 @@ static FDSSOUND fdso; void FDSSoundStateAdd(void) { - AddExState(fdso.cwave,64,0,"WAVE"); - AddExState(fdso.mwave,32,0,"MWAV"); - AddExState(amplitude,2,0,"AMPL"); - AddExState(SPSG,0xB,0,"SPSG"); + AddExState(fdso.cwave,64,0,"WAVE"); + AddExState(fdso.mwave,32,0,"MWAV"); + AddExState(amplitude,2,0,"AMPL"); + AddExState(SPSG,0xB,0,"SPSG"); - AddExState(&b8shiftreg88,1,0,"B88"); + AddExState(&b8shiftreg88,1,0,"B88"); - AddExState(&clockcount, 4, 1, "CLOC"); - AddExState(&b19shiftreg60,4,1,"B60"); - AddExState(&b24adder66,4,1,"B66"); - AddExState(&b24latch68,4,1,"B68"); - AddExState(&b17latch76,4,1,"B76"); + AddExState(&clockcount, 4, 1, "CLOC"); + AddExState(&b19shiftreg60,4,1,"B60"); + AddExState(&b24adder66,4,1,"B66"); + AddExState(&b24latch68,4,1,"B68"); + AddExState(&b17latch76,4,1,"B76"); } static DECLFR(FDSSRead) { - switch(A&0xF) - { - case 0x0:return(amplitude[0]|(X.DB&0xC0)); - case 0x2:return(amplitude[1]|(X.DB&0xC0)); - } - return(X.DB); + switch(A&0xF) + { + case 0x0:return(amplitude[0]|(X.DB&0xC0)); + case 0x2:return(amplitude[1]|(X.DB&0xC0)); + } + return(X.DB); } static DECLFW(FDSSWrite) { - if(FSettings.SndRate) - { - if(FSettings.soundq>=1) - RenderSoundHQ(); - else - RenderSound(); - } - A-=0x4080; - switch(A) - { - case 0x0: - case 0x4: if(V&0x80) - amplitude[(A&0xF)>>2]=V&0x3F; //)>0x20?0x20:(V&0x3F); - break; - case 0x5://printf("$%04x:$%02x\n",A,V); + if(FSettings.SndRate) + { + if(FSettings.soundq>=1) + RenderSoundHQ(); + else + RenderSound(); + } + A-=0x4080; + switch(A) + { + case 0x0: + case 0x4: if(V&0x80) + amplitude[(A&0xF)>>2]=V&0x3F; //)>0x20?0x20:(V&0x3F); break; - case 0x7: b17latch76=0;SPSG[0x5]=0;//printf("$%04x:$%02x\n",A,V); + case 0x5://printf("$%04x:$%02x\n",A,V); break; - case 0x8: - b17latch76=0; - // printf("%d:$%02x, $%02x\n",SPSG[0x5],V,b17latch76); - fdso.mwave[SPSG[0x5]&0x1F]=V&0x7; - SPSG[0x5]=(SPSG[0x5]+1)&0x1F; - break; - } - //if(A>=0x7 && A!=0x8 && A<=0xF) - //if(A==0xA || A==0x9) - //printf("$%04x:$%02x\n",A,V); - SPSG[A]=V; + case 0x7: b17latch76=0;SPSG[0x5]=0;//printf("$%04x:$%02x\n",A,V); + break; + case 0x8: + b17latch76=0; + // printf("%d:$%02x, $%02x\n",SPSG[0x5],V,b17latch76); + fdso.mwave[SPSG[0x5]&0x1F]=V&0x7; + SPSG[0x5]=(SPSG[0x5]+1)&0x1F; + break; + } + //if(A>=0x7 && A!=0x8 && A<=0xF) + //if(A==0xA || A==0x9) + //printf("$%04x:$%02x\n",A,V); + SPSG[A]=V; } // $4080 - Fundamental wave amplitude data register 92 @@ -387,501 +388,501 @@ static DECLFW(FDSSWrite) static void DoEnv() { - int x; + int x; - for(x=0;x<2;x++) - if(!(SPSG[x<<2]&0x80) && !(SPSG[0x3]&0x40)) - { - static int counto[2]={0,0}; + for(x=0;x<2;x++) + if(!(SPSG[x<<2]&0x80) && !(SPSG[0x3]&0x40)) + { + static int counto[2]={0,0}; - if(counto[x]<=0) - { - if(!(SPSG[x<<2]&0x80)) - { - if(SPSG[x<<2]&0x40) - { - if(amplitude[x]<0x3F) - amplitude[x]++; - } - else - { - if(amplitude[x]>0) - amplitude[x]--; - } - } - counto[x]=(SPSG[x<<2]&0x3F); - } - else - counto[x]--; - } + if(counto[x]<=0) + { + if(!(SPSG[x<<2]&0x80)) + { + if(SPSG[x<<2]&0x40) + { + if(amplitude[x]<0x3F) + amplitude[x]++; + } + else + { + if(amplitude[x]>0) + amplitude[x]--; + } + } + counto[x]=(SPSG[x<<2]&0x3F); + } + else + counto[x]--; + } } static DECLFR(FDSWaveRead) { - return(fdso.cwave[A&0x3f]|(X.DB&0xC0)); + return(fdso.cwave[A&0x3f]|(X.DB&0xC0)); } static DECLFW(FDSWaveWrite) { - //printf("$%04x:$%02x, %d\n",A,V,SPSG[0x9]&0x80); - if(SPSG[0x9]&0x80) - fdso.cwave[A&0x3f]=V&0x3F; + //printf("$%04x:$%02x, %d\n",A,V,SPSG[0x9]&0x80); + if(SPSG[0x9]&0x80) + fdso.cwave[A&0x3f]=V&0x3F; } static int ta; static INLINE void ClockRise(void) { - if(!clockcount) - { - ta++; + if(!clockcount) + { + ta++; - b19shiftreg60=(SPSG[0x2]|((SPSG[0x3]&0xF)<<8)); - b17latch76=(SPSG[0x6]|((SPSG[0x07]&0xF)<<8))+b17latch76; + b19shiftreg60=(SPSG[0x2]|((SPSG[0x3]&0xF)<<8)); + b17latch76=(SPSG[0x6]|((SPSG[0x07]&0xF)<<8))+b17latch76; - if(!(SPSG[0x7]&0x80)) - { - int t=fdso.mwave[(b17latch76>>13)&0x1F]&7; - int t2=amplitude[1]; - int adj = 0; + if(!(SPSG[0x7]&0x80)) + { + int t=fdso.mwave[(b17latch76>>13)&0x1F]&7; + int t2=amplitude[1]; + int adj = 0; - if((t&3)) - { - if((t&4)) - adj -= (t2 * ((4 - (t&3) ) )); - else - adj += (t2 * ( (t&3) )); - } - adj *= 2; - if(adj > 0x7F) adj = 0x7F; - if(adj < -0x80) adj = -0x80; - //if(adj) printf("%d ",adj); - b8shiftreg88=0x80 + adj; - } - else - { - b8shiftreg88=0x80; - } - } - else - { - b19shiftreg60<<=1; - b8shiftreg88>>=1; - } -// b24adder66=(b24latch68+b19shiftreg60)&0x3FFFFFF; - b24adder66=(b24latch68+b19shiftreg60)&0x1FFFFFF; + if((t&3)) + { + if((t&4)) + adj -= (t2 * ((4 - (t&3) ) )); + else + adj += (t2 * ( (t&3) )); + } + adj *= 2; + if(adj > 0x7F) adj = 0x7F; + if(adj < -0x80) adj = -0x80; + //if(adj) printf("%d ",adj); + b8shiftreg88=0x80 + adj; + } + else + { + b8shiftreg88=0x80; + } + } + else + { + b19shiftreg60<<=1; + b8shiftreg88>>=1; + } + // b24adder66=(b24latch68+b19shiftreg60)&0x3FFFFFF; + b24adder66=(b24latch68+b19shiftreg60)&0x1FFFFFF; } static INLINE void ClockFall(void) { - //if(!(SPSG[0x7]&0x80)) - { - if((b8shiftreg88&1)) // || clockcount==7) - b24latch68=b24adder66; - } - clockcount=(clockcount+1)&7; + //if(!(SPSG[0x7]&0x80)) + { + if((b8shiftreg88&1)) // || clockcount==7) + b24latch68=b24adder66; + } + clockcount=(clockcount+1)&7; } static INLINE int32 FDSDoSound(void) { - fdso.count+=fdso.cycles; - if(fdso.count>=((int64)1<<40)) - { - dogk: - fdso.count-=(int64)1<<40; - ClockRise(); - ClockFall(); - fdso.envcount--; - if(fdso.envcount<=0) - { - fdso.envcount+=SPSG[0xA]*3; - DoEnv(); - } - } - if(fdso.count>=32768) goto dogk; + fdso.count+=fdso.cycles; + if(fdso.count>=((int64)1<<40)) + { +dogk: + fdso.count-=(int64)1<<40; + ClockRise(); + ClockFall(); + fdso.envcount--; + if(fdso.envcount<=0) + { + fdso.envcount+=SPSG[0xA]*3; + DoEnv(); + } + } + if(fdso.count>=32768) goto dogk; - // Might need to emulate applying the amplitude to the waveform a bit better... - { - int k=amplitude[0]; - if(k>0x20) k=0x20; - return (fdso.cwave[b24latch68>>19]*k)*4/((SPSG[0x9]&0x3)+2); - } + // Might need to emulate applying the amplitude to the waveform a bit better... + { + int k=amplitude[0]; + if(k>0x20) k=0x20; + return (fdso.cwave[b24latch68>>19]*k)*4/((SPSG[0x9]&0x3)+2); + } } static int32 FBC=0; static void RenderSound(void) { - int32 end, start; - int32 x; + int32 end, start; + int32 x; - start=FBC; - end=(SOUNDTS<<16)/soundtsinc; - if(end<=start) - return; - FBC=end; + start=FBC; + end=(SOUNDTS<<16)/soundtsinc; + if(end<=start) + return; + FBC=end; - if(!(SPSG[0x9]&0x80)) - for(x=start;x>1; - t>>=4; - Wave[x>>4]+=t; //(t>>2)-(t>>3); //>>3; - } + if(!(SPSG[0x9]&0x80)) + for(x=start;x>1; + t>>=4; + Wave[x>>4]+=t; //(t>>2)-(t>>3); //>>3; + } } static void RenderSoundHQ(void) { - uint32 x; //mbg merge 7/17/06 - made this unsigned - - if(!(SPSG[0x9]&0x80)) - for(x=FBC;x>1; - WaveHi[x]+=t; //(t<<2)-(t<<1); - } - FBC=SOUNDTS; + uint32 x; //mbg merge 7/17/06 - made this unsigned + + if(!(SPSG[0x9]&0x80)) + for(x=FBC;x>1; + WaveHi[x]+=t; //(t<<2)-(t<<1); + } + FBC=SOUNDTS; } static void HQSync(int32 ts) { - FBC=ts; + FBC=ts; } void FDSSound(int c) { - RenderSound(); - FBC=c; + RenderSound(); + FBC=c; } /* static DECLFR(FDSBIOSPatch) { - if(FDSRegs[5]&0x4) - { - X.X=FDSRead4031(0x4031); - FDSWrite(0x4024,X.A); - X.A=X.X; - return(0x60); - } - else - { - return(0x58); - //puts("Write"); - } +if(FDSRegs[5]&0x4) +{ +X.X=FDSRead4031(0x4031); +FDSWrite(0x4024,X.A); +X.A=X.X; +return(0x60); +} +else +{ +return(0x58); +//puts("Write"); +} } */ static void FDS_ESI(void) { - if(FSettings.SndRate) - { - if(FSettings.soundq>=1) - { - fdso.cycles=(int64)1<<39; - } - else - { - fdso.cycles=((int64)1<<40)*FDSClock; - fdso.cycles/=FSettings.SndRate *16; - } - } -// fdso.cycles=(int64)32768*FDSClock/(FSettings.SndRate *16); - SetReadHandler(0x4040,0x407f,FDSWaveRead); - SetWriteHandler(0x4040,0x407f,FDSWaveWrite); - SetWriteHandler(0x4080,0x408A,FDSSWrite); - SetReadHandler(0x4090,0x4092,FDSSRead); + if(FSettings.SndRate) + { + if(FSettings.soundq>=1) + { + fdso.cycles=(int64)1<<39; + } + else + { + fdso.cycles=((int64)1<<40)*FDSClock; + fdso.cycles/=FSettings.SndRate *16; + } + } + // fdso.cycles=(int64)32768*FDSClock/(FSettings.SndRate *16); + SetReadHandler(0x4040,0x407f,FDSWaveRead); + SetWriteHandler(0x4040,0x407f,FDSWaveWrite); + SetWriteHandler(0x4080,0x408A,FDSSWrite); + SetReadHandler(0x4090,0x4092,FDSSRead); - //SetReadHandler(0xE7A3,0xE7A3,FDSBIOSPatch); + //SetReadHandler(0xE7A3,0xE7A3,FDSBIOSPatch); } void FDSSoundReset(void) { - memset(&fdso,0,sizeof(fdso)); - FDS_ESI(); - GameExpSound.HiSync=HQSync; - GameExpSound.HiFill=RenderSoundHQ; - GameExpSound.Fill=FDSSound; - GameExpSound.RChange=FDS_ESI; + memset(&fdso,0,sizeof(fdso)); + FDS_ESI(); + GameExpSound.HiSync=HQSync; + GameExpSound.HiFill=RenderSoundHQ; + GameExpSound.Fill=FDSSound; + GameExpSound.RChange=FDS_ESI; } static DECLFW(FDSWrite) { - //extern int scanline; - //FCEU_printf("$%04x:$%02x, %d\n",A,V,scanline); - switch(A) - { - case 0x4020: - X6502_IRQEnd(FCEU_IQEXT); - IRQLatch&=0xFF00; - IRQLatch|=V; -// printf("$%04x:$%02x\n",A,V); - break; - case 0x4021: - X6502_IRQEnd(FCEU_IQEXT); - IRQLatch&=0xFF; - IRQLatch|=V<<8; -// printf("$%04x:$%02x\n",A,V); - break; - case 0x4022: - X6502_IRQEnd(FCEU_IQEXT); - IRQCount=IRQLatch; - IRQa=V&3; -// printf("$%04x:$%02x\n",A,V); - break; - case 0x4023:break; - case 0x4024: - if(InDisk!=255 && !(FDSRegs[5]&0x4) && (FDSRegs[3]&0x1)) - { - if(DiskPtr>=0 && DiskPtr<65500) - { - if(writeskip) writeskip--; - else if(DiskPtr>=2) - { - DiskWritten=1; - diskdata[InDisk][DiskPtr-2]=V; - } - } - } - break; - case 0x4025: - X6502_IRQEnd(FCEU_IQEXT2); - if(InDisk!=255) + //extern int scanline; + //FCEU_printf("$%04x:$%02x, %d\n",A,V,scanline); + switch(A) { - if(!(V&0x40)) - { - if(FDSRegs[5]&0x40 && !(V&0x10)) - { - DiskSeekIRQ=200; - DiskPtr-=2; - } - if(DiskPtr<0) DiskPtr=0; - } - if(!(V&0x4)) writeskip=2; - if(V&2) {DiskPtr=0;DiskSeekIRQ=200;} - if(V&0x40) DiskSeekIRQ=200; + case 0x4020: + X6502_IRQEnd(FCEU_IQEXT); + IRQLatch&=0xFF00; + IRQLatch|=V; + // printf("$%04x:$%02x\n",A,V); + break; + case 0x4021: + X6502_IRQEnd(FCEU_IQEXT); + IRQLatch&=0xFF; + IRQLatch|=V<<8; + // printf("$%04x:$%02x\n",A,V); + break; + case 0x4022: + X6502_IRQEnd(FCEU_IQEXT); + IRQCount=IRQLatch; + IRQa=V&3; + // printf("$%04x:$%02x\n",A,V); + break; + case 0x4023:break; + case 0x4024: + if(InDisk!=255 && !(FDSRegs[5]&0x4) && (FDSRegs[3]&0x1)) + { + if(DiskPtr>=0 && DiskPtr<65500) + { + if(writeskip) writeskip--; + else if(DiskPtr>=2) + { + DiskWritten=1; + diskdata[InDisk][DiskPtr-2]=V; + } + } + } + break; + case 0x4025: + X6502_IRQEnd(FCEU_IQEXT2); + if(InDisk!=255) + { + if(!(V&0x40)) + { + if(FDSRegs[5]&0x40 && !(V&0x10)) + { + DiskSeekIRQ=200; + DiskPtr-=2; + } + if(DiskPtr<0) DiskPtr=0; + } + if(!(V&0x4)) writeskip=2; + if(V&2) {DiskPtr=0;DiskSeekIRQ=200;} + if(V&0x40) DiskSeekIRQ=200; + } + setmirror(((V>>3)&1)^1); + break; } - setmirror(((V>>3)&1)^1); - break; - } - FDSRegs[A&7]=V; + FDSRegs[A&7]=V; } static void FreeFDSMemory(void) { - int x; + int x; - for(x=0;x8) TotalSides=8; - if(TotalSides<1) TotalSides=1; + md5_starts(&md5); - for(x=0;xMD5.data); - return(1); + if(TotalSides>8) TotalSides=8; + if(TotalSides<1) TotalSides=1; + + for(x=0;xMD5.data); + return(1); } static void PreSave(void) { - int x; + int x; - //if(DiskWritten) - for(x=0;xtype=GIT_FDS; - GameInterface=FDSGI; + if(fread(FDSBIOS,1,8192,zp)!=8192) + { + fclose(zp); + FreeFDSMemory(); + FCEU_PrintError("Error reading FDS BIOS ROM image."); + return 0; + } - SelectDisk=0; - InDisk=255; + fclose(zp); - ResetExState(PreSave,PostSave); - FDSSoundStateAdd(); - for(x=0;xtype=GIT_FDS; + GameInterface=FDSGI; - FCEUI_SetVidSystem(0); + SelectDisk=0; + InDisk=255; - return 1; + ResetExState(PreSave,PostSave); + FDSSoundStateAdd(); + + for(x=0;x + typedef struct { void *fp; // FILE* or ptr to ZIPWRAP uint32 type; // 0=normal file, 1=gzip, 2=zip @@ -22,9 +24,9 @@ int FCEU_fisarchive(FCEUFILE*); void GetFileBase(const char *f); -char* FCEU_GetPath(int type); -char *FCEU_MakePath(int type, const char* filebase); -char *FCEU_MakeFName(int type, int id1, char *cd1); +std::string FCEU_GetPath(int type); +std::string FCEU_MakePath(int type, const char* filebase); +std::string FCEU_MakeFName(int type, int id1, char *cd1); #define FCEUMKF_STATE 1 #define FCEUMKF_SNAP 2 diff --git a/src/ines.cpp b/src/ines.cpp index a51682cf..af0157a5 100644 --- a/src/ines.cpp +++ b/src/ines.cpp @@ -44,6 +44,7 @@ #include "utils/md5.h" #include "cheat.h" #include "vsuni.h" +#include "driver.h" extern SFORMAT FCEUVSUNI_STATEINFO[]; diff --git a/src/input.cpp b/src/input.cpp index f5ee9355..e182d252 100644 --- a/src/input.cpp +++ b/src/input.cpp @@ -37,6 +37,7 @@ #include "input.h" #include "vsuni.h" #include "fds.h" +#include "driver.h" // qfox: For UpdateExternalButton(), called when the // botmode state changes, to update a label in gui. diff --git a/src/movie.cpp b/src/movie.cpp index 6b21450b..32c1e125 100644 --- a/src/movie.cpp +++ b/src/movie.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #ifdef WIN32 #include @@ -19,6 +20,7 @@ #include "file.h" #include "video.h" #include "movie.h" +#include "utils/guid.h" #include "utils/memory.h" #include "utils/memorystream.h" #include "utils/xstring.h" @@ -338,7 +340,7 @@ bool FCEUMOV_Mode(int modemask) } //yuck... another custom text parser. -void LoadFM2(MovieData& movieData, std::istream* fp, bool stopAfterHeader = false) +static void LoadFM2(MovieData& movieData, std::istream* fp, int size=-1, bool stopAfterHeader = false) { std::string key,value; enum { @@ -348,6 +350,7 @@ void LoadFM2(MovieData& movieData, std::istream* fp, bool stopAfterHeader = fals for(;;) { bool iswhitespace, isrecchar, isnewline; + if(size--==0) goto bail; int c = fp->get(); if(c == -1) goto bail; @@ -506,15 +509,8 @@ void FCEUMOV_ExitTasEdit() bool MovieData::loadSavestateFrom(std::vector* buf) { - //dump the savestate to disk - FILE* fp = tmpfile(); - fwrite(&(*buf)[0],1,buf->size(),fp); - fseek(fp,0,SEEK_SET); - - //and load the state - bool success = FCEUSS_LoadFP(fp,SSLOADPARAM_BACKUP); - fclose(fp); - return success; + memorystream ms(buf); + return FCEUSS_LoadFP(&ms,SSLOADPARAM_BACKUP); } void MovieData::dumpSavestateTo(std::vector* buf, int compressionLevel) @@ -780,22 +776,22 @@ int FCEUMOV_WriteState(std::ostream* os) static bool load_successful; -bool FCEUMOV_ReadState(FILE* st, uint32 size) +bool FCEUMOV_ReadState(std::istream* is, uint32 size) { load_successful = false; - //write the state to disk so we can reload - std::vector buf(size); - fread(&buf[0],1,size,st); - //--------- - //(debug) - //FILE* wtf = fopen("d:\\wtf.txt","wb"); - //fwrite(&buf[0],1,size,wtf); - //fclose(wtf); - //--------- - memorystream mstemp(&buf); + ////write the state to disk so we can reload + //std::vector buf(size); + //fread(&buf[0],1,size,st); + ////--------- + ////(debug) + ////FILE* wtf = fopen("d:\\wtf.txt","wb"); + ////fwrite(&buf[0],1,size,wtf); + ////fclose(wtf); + ////--------- + //memorystream mstemp(&buf); MovieData tempMovieData = MovieData(); - LoadFM2(tempMovieData, &mstemp); + LoadFM2(tempMovieData, is); //complex TAS logic for when a savestate is loaded: //---------------- @@ -934,7 +930,7 @@ void FCEUI_MoviePlayFromBeginning(void) } -bool FCEUI_MovieGetInfo(const char* fname, MOVIE_INFO* info, bool skipFrameCount) +bool FCEUI_MovieGetInfo(const std::string& fname, MOVIE_INFO* info, bool skipFrameCount) { memset(info,0,sizeof(MOVIE_INFO)); diff --git a/src/movie.h b/src/movie.h index 6b4fd8f3..2e1dbecc 100644 --- a/src/movie.h +++ b/src/movie.h @@ -7,6 +7,7 @@ #include #include "input/zapper.h" +#include "utils/guid.h" void FCEUMOV_AddInputState(); void FCEUMOV_AddCommand(int cmd); @@ -33,7 +34,7 @@ bool FCEUMOV_ShouldPause(void); int FCEUMOV_GetFrame(void); int FCEUMOV_WriteState(std::ostream* os); -bool FCEUMOV_ReadState(FILE* st, uint32 size); +bool FCEUMOV_ReadState(std::istream* is, uint32 size); void FCEUMOV_PreLoad(); bool FCEUMOV_PostLoad(); diff --git a/src/netplay.cpp b/src/netplay.cpp index 2af83900..452986e7 100644 --- a/src/netplay.cpp +++ b/src/netplay.cpp @@ -1,22 +1,22 @@ /* FCE Ultra - NES/Famicom Emulator - * - * Copyright notice for this file: - * Copyright (C) 2002 Xodnizel - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ +* +* Copyright notice for this file: +* Copyright (C) 2002 Xodnizel +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ #include @@ -35,44 +35,43 @@ #include "state.h" #include "cheat.h" #include "input.h" +#include "driver.h" int FCEUnetplay=0; -static uint8 netjoy[4]; /* Controller cache. */ +static uint8 netjoy[4]; // Controller cache. static int numlocal; static int netdivisor; static int netdcount; -/* NetError should only be called after a FCEUD_*Data function returned 0, in the function - that called FCEUD_*Data, to prevent it from being called twice. -*/ +//NetError should only be called after a FCEUD_*Data function returned 0, in the function +//that called FCEUD_*Data, to prevent it from being called twice. static void NetError(void) { - FCEU_DispMessage("Network error/connection lost!"); - FCEUD_NetworkClose(); + FCEU_DispMessage("Network error/connection lost!"); + FCEUD_NetworkClose(); } void FCEUI_NetplayStop(void) { if(FCEUnetplay) { - FCEUnetplay = 0; - FCEU_FlushGameCheats(0,1); /* Don't save netplay cheats. */ - FCEU_LoadGameCheats(0); /* Reload our original cheats. */ + FCEUnetplay = 0; + FCEU_FlushGameCheats(0,1); //Don't save netplay cheats. + FCEU_LoadGameCheats(0); //Reload our original cheats. } else puts("Check your code!"); } int FCEUI_NetplayStart(int nlocal, int divisor) { - FCEU_FlushGameCheats(0, 0); /* Save our pre-netplay cheats. */ - FCEU_LoadGameCheats(0); /* Load them again, for pre-multiplayer - action. - */ + FCEU_FlushGameCheats(0, 0); //Save our pre-netplay cheats. + FCEU_LoadGameCheats(0); // Load them again, for pre-multiplayer action. + FCEUnetplay = 1; - memset(netjoy,0,sizeof(netjoy)); - numlocal = nlocal; + memset(netjoy,0,sizeof(netjoy)); + numlocal = nlocal; netdivisor = divisor; netdcount = 0; return(1); @@ -80,249 +79,252 @@ int FCEUI_NetplayStart(int nlocal, int divisor) int FCEUNET_SendCommand(uint8 cmd, uint32 len) { - //mbg merge 7/17/06 changed to alloca - //uint8 buf[numlocal + 1 + 4]; - uint8 *buf = (uint8*)alloca(numlocal+1+4); - + //mbg merge 7/17/06 changed to alloca + //uint8 buf[numlocal + 1 + 4]; + uint8 *buf = (uint8*)alloca(numlocal+1+4); - buf[0] = 0xFF; - FCEU_en32lsb(&buf[numlocal], len); - buf[numlocal + 4] = cmd; - if(!FCEUD_SendData(buf,numlocal + 1 + 4)) - { - NetError(); - return(0); - } - return(1); + + buf[0] = 0xFF; + FCEU_en32lsb(&buf[numlocal], len); + buf[numlocal + 4] = cmd; + if(!FCEUD_SendData(buf,numlocal + 1 + 4)) + { + NetError(); + return(0); + } + return(1); } void FCEUI_NetplayText(uint8 *text) { - uint32 len; + uint32 len; - len = strlen((char*)text); //mbg merge 7/17/06 added cast + len = strlen((char*)text); //mbg merge 7/17/06 added cast - if(!FCEUNET_SendCommand(FCEUNPCMD_TEXT,len)) return; + if(!FCEUNET_SendCommand(FCEUNPCMD_TEXT,len)) return; - if(!FCEUD_SendData(text,len)) - NetError(); + if(!FCEUD_SendData(text,len)) + NetError(); } int FCEUNET_SendFile(uint8 cmd, char *fn) { - uint32 len; - uLongf clen; - char *buf, *cbuf; - FILE *fp; - struct stat sb; + uint32 len; + uLongf clen; + char *buf, *cbuf; + FILE *fp; + struct stat sb; - if(!(fp=FCEUD_UTF8fopen(fn,"rb"))) return(0); + if(!(fp=FCEUD_UTF8fopen(fn,"rb"))) return(0); - fstat(fileno(fp),&sb); - len = sb.st_size; - buf = (char*)malloc(len); //mbg merge 7/17/06 added cast - fread(buf, 1, len, fp); - fclose(fp); + fstat(fileno(fp),&sb); + len = sb.st_size; + buf = (char*)malloc(len); //mbg merge 7/17/06 added cast + fread(buf, 1, len, fp); + fclose(fp); - cbuf = (char*)malloc(4 + len + len / 1000 + 12); //mbg merge 7/17/06 added cast - FCEU_en32lsb((uint8*)cbuf, len); //mbg merge 7/17/06 added cast - compress2((uint8*)cbuf + 4, &clen, (uint8*)buf, len, 7); //mbg merge 7/17/06 added casts - free(buf); + cbuf = (char*)malloc(4 + len + len / 1000 + 12); //mbg merge 7/17/06 added cast + FCEU_en32lsb((uint8*)cbuf, len); //mbg merge 7/17/06 added cast + compress2((uint8*)cbuf + 4, &clen, (uint8*)buf, len, 7); //mbg merge 7/17/06 added casts + free(buf); - //printf("Sending file: %s, %d, %d\n",fn,len,clen); + //printf("Sending file: %s, %d, %d\n",fn,len,clen); - len = clen + 4; + len = clen + 4; - if(!FCEUNET_SendCommand(cmd,len)) - { - free(cbuf); - return(0); - } - if(!FCEUD_SendData(cbuf, len)) - { - NetError(); - free(cbuf); - return(0); - } - free(cbuf); + if(!FCEUNET_SendCommand(cmd,len)) + { + free(cbuf); + return(0); + } + if(!FCEUD_SendData(cbuf, len)) + { + NetError(); + free(cbuf); + return(0); + } + free(cbuf); - return(1); + return(1); } static FILE *FetchFile(uint32 remlen) { - uint32 clen = remlen; - char *cbuf; - uLongf len; - char *buf; - FILE *fp; - char *fn; - - if(clen > 500000) // Sanity check - { - NetError(); - return(0); - } + uint32 clen = remlen; + char *cbuf; + uLongf len; + char *buf; + FILE *fp; + char *fn; - //printf("Receiving file: %d...\n",clen); - fn = FCEU_MakeFName(FCEUMKF_NPTEMP,0,0); - if((fp = fopen(fn,"w+b"))) - { - cbuf = (char *)malloc(clen); //mbg merge 7/17/06 added cast - if(!FCEUD_RecvData(cbuf, clen)) - { - NetError(); - unlink(fn); - fclose(fp); - free(cbuf); - free(fn); - return(0); - } - - len = FCEU_de32lsb((uint8*)cbuf); //mbg merge 7/17/06 added cast - if(len > 500000) // Another sanity check - { - NetError(); - unlink(fn); - fclose(fp); - free(cbuf); - free(fn); - return(0); - } - buf = (char *)malloc(len); //mbg merge 7/17/06 added cast - uncompress((uint8*)buf, &len, (uint8*)cbuf + 4, clen - 4); //mbg merge 7/17/06 added casts - - fwrite(buf, 1, len, fp); - free(buf); - fseek(fp, 0, SEEK_SET); - unlink(fn); - free(fn); - return(fp); - } - free(fn); - return(0); + if(clen > 500000) // Sanity check + { + NetError(); + return(0); + } + + //printf("Receiving file: %d...\n",clen); + fn = strdup(FCEU_MakeFName(FCEUMKF_NPTEMP,0,0).c_str()); + if((fp = fopen(fn,"w+b"))) + { + cbuf = (char *)malloc(clen); //mbg merge 7/17/06 added cast + if(!FCEUD_RecvData(cbuf, clen)) + { + NetError(); + unlink(fn); + fclose(fp); + free(cbuf); + free(fn); + return(0); + } + + len = FCEU_de32lsb((uint8*)cbuf); //mbg merge 7/17/06 added cast + if(len > 500000) // Another sanity check + { + NetError(); + unlink(fn); + fclose(fp); + free(cbuf); + free(fn); + return(0); + } + buf = (char *)malloc(len); //mbg merge 7/17/06 added cast + uncompress((uint8*)buf, &len, (uint8*)cbuf + 4, clen - 4); //mbg merge 7/17/06 added casts + + fwrite(buf, 1, len, fp); + free(buf); + fseek(fp, 0, SEEK_SET); + unlink(fn); + free(fn); + return(fp); + } + free(fn); + return(0); } void NetplayUpdate(uint8 *joyp) { - static uint8 buf[5]; /* 4 play states, + command/extra byte */ - static uint8 joypb[4]; + static uint8 buf[5]; /* 4 play states, + command/extra byte */ + static uint8 joypb[4]; - memcpy(joypb,joyp,4); + memcpy(joypb,joyp,4); - /* This shouldn't happen, but just in case. 0xFF is used as a command escape elsewhere. */ - if(joypb[0] == 0xFF) - joypb[0] = 0xF; - if(!netdcount) - if(!FCEUD_SendData(joypb,numlocal)) - { - NetError(); - return; - } + /* This shouldn't happen, but just in case. 0xFF is used as a command escape elsewhere. */ + if(joypb[0] == 0xFF) + joypb[0] = 0xF; + if(!netdcount) + if(!FCEUD_SendData(joypb,numlocal)) + { + NetError(); + return; + } - if(!netdcount) - do - { - if(!FCEUD_RecvData(buf,5)) - { - NetError(); - return; - } - - switch(buf[4]) - { - default: FCEU_DoSimpleCommand(buf[4]);break; - case FCEUNPCMD_TEXT: - { - uint8 *tbuf; - uint32 len = FCEU_de32lsb(buf); - - if(len > 100000) // Insanity check! + if(!netdcount) + { + do + { + if(!FCEUD_RecvData(buf,5)) { - NetError(); - return; + NetError(); + return; } - tbuf = (uint8*)malloc(len + 1); //mbg merge 7/17/06 added cast - tbuf[len] = 0; - if(!FCEUD_RecvData(tbuf, len)) - { - NetError(); - free(tbuf); - return; - } - FCEUD_NetplayText(tbuf); - free(tbuf); - } - break; - case FCEUNPCMD_SAVESTATE: - { - char *fn; - FILE *fp; - /* Send the cheats first, then the save state, since - there might be a frame or two in between the two sendfile - commands on the server side. - */ - fn = FCEU_MakeFName(FCEUMKF_CHEAT,0,0); - //if(! - FCEUNET_SendFile(FCEUNPCMD_LOADCHEATS,fn); - - // { - // free(fn); - // return; - // } - free(fn); - if(!FCEUnetplay) return; - - fn = FCEU_MakeFName(FCEUMKF_NPTEMP,0,0); - fp = fopen(fn, "wb"); - if(FCEUSS_SaveFP(fp,Z_BEST_COMPRESSION)) - { - fclose(fp); - if(!FCEUNET_SendFile(FCEUNPCMD_LOADSTATE, fn)) - { - unlink(fn); - free(fn); - return; - } - unlink(fn); - free(fn); - } - else - { - fclose(fp); - FCEUD_PrintError("File error. (K)ill, (M)aim, (D)estroy? Now!"); - unlink(fn); - free(fn); - return; - } - - } - break; - case FCEUNPCMD_LOADCHEATS: + switch(buf[4]) + { + default: FCEU_DoSimpleCommand(buf[4]);break; + case FCEUNPCMD_TEXT: { - FILE *fp = FetchFile(FCEU_de32lsb(buf)); - if(!fp) return; - FCEU_FlushGameCheats(0,1); - FCEU_LoadGameCheats(fp); + uint8 *tbuf; + uint32 len = FCEU_de32lsb(buf); + + if(len > 100000) // Insanity check! + { + NetError(); + return; + } + tbuf = (uint8*)malloc(len + 1); //mbg merge 7/17/06 added cast + tbuf[len] = 0; + if(!FCEUD_RecvData(tbuf, len)) + { + NetError(); + free(tbuf); + return; + } + FCEUD_NetplayText(tbuf); + free(tbuf); } - break; - case FCEUNPCMD_LOADSTATE: + break; + case FCEUNPCMD_SAVESTATE: { - FILE *fp = FetchFile(FCEU_de32lsb(buf)); - if(!fp) return; - if(FCEUSS_LoadFP(fp,SSLOADPARAM_BACKUP)) - { - fclose(fp); - FCEU_DispMessage("Remote state loaded."); - } else FCEUD_PrintError("File error. (K)ill, (M)aim, (D)estroy?"); - } - break; - } - } while(buf[4]); + char *fn; + FILE *fp; - netdcount=(netdcount+1)%netdivisor; + /* Send the cheats first, then the save state, since + there might be a frame or two in between the two sendfile + commands on the server side. + */ + fn = strdup(FCEU_MakeFName(FCEUMKF_CHEAT,0,0).c_str()); + //if(! + FCEUNET_SendFile(FCEUNPCMD_LOADCHEATS,fn); - memcpy(netjoy,buf,4); - *(uint32 *)joyp=*(uint32 *)netjoy; + // { + // free(fn); + // return; + // } + free(fn); + if(!FCEUnetplay) return; + + fn = strdup(FCEU_MakeFName(FCEUMKF_NPTEMP,0,0).c_str()); + fp = fopen(fn, "wb"); + if(FCEUSS_SaveFP(fp,Z_BEST_COMPRESSION)) + { + fclose(fp); + if(!FCEUNET_SendFile(FCEUNPCMD_LOADSTATE, fn)) + { + unlink(fn); + free(fn); + return; + } + unlink(fn); + free(fn); + } + else + { + fclose(fp); + FCEUD_PrintError("File error. (K)ill, (M)aim, (D)estroy? Now!"); + unlink(fn); + free(fn); + return; + } + + } + break; + case FCEUNPCMD_LOADCHEATS: + { + FILE *fp = FetchFile(FCEU_de32lsb(buf)); + if(!fp) return; + FCEU_FlushGameCheats(0,1); + FCEU_LoadGameCheats(fp); + } + break; + //mbg 6/16/08 - netplay doesnt work right now anyway + /*case FCEUNPCMD_LOADSTATE: + { + FILE *fp = FetchFile(FCEU_de32lsb(buf)); + if(!fp) return; + if(FCEUSS_LoadFP(fp,SSLOADPARAM_BACKUP)) + { + fclose(fp); + FCEU_DispMessage("Remote state loaded."); + } else FCEUD_PrintError("File error. (K)ill, (M)aim, (D)estroy?"); + } + break;*/ + } + } while(buf[4]); + + netdcount=(netdcount+1)%netdivisor; + + memcpy(netjoy,buf,4); + *(uint32 *)joyp=*(uint32 *)netjoy; + } } diff --git a/src/nsf.cpp b/src/nsf.cpp index 63194866..46ed3c11 100644 --- a/src/nsf.cpp +++ b/src/nsf.cpp @@ -1,22 +1,22 @@ /* FCE Ultra - NES/Famicom Emulator - * - * Copyright notice for this file: - * Copyright (C) 2002 Xodnizel - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ +* +* Copyright notice for this file: +* Copyright (C) 2002 Xodnizel +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ /// \file /// \brief implements a built-in NSF player. This is a perk--not a part of the emu core @@ -38,6 +38,7 @@ #include "fds.h" #include "cart.h" #include "input.h" +#include "driver.h" #ifndef M_PI #define M_PI 3.14159265358979323846 @@ -74,33 +75,33 @@ static int vismode=1; */ static uint8 NSFROM[0x30+6]= { -/* 0x00 - NMI */ -0x8D,0xF4,0x3F, /* Stop play routine NMIs. */ -0xA2,0xFF,0x9A, /* Initialize the stack pointer. */ -0xAD,0xF0,0x3F, /* See if we need to init. */ -0xF0,0x09, /* If 0, go to play routine playing. */ + /* 0x00 - NMI */ + 0x8D,0xF4,0x3F, /* Stop play routine NMIs. */ + 0xA2,0xFF,0x9A, /* Initialize the stack pointer. */ + 0xAD,0xF0,0x3F, /* See if we need to init. */ + 0xF0,0x09, /* If 0, go to play routine playing. */ -0xAD,0xF1,0x3F, /* Confirm and load A */ -0xAE,0xF3,0x3F, /* Load X with PAL/NTSC byte */ + 0xAD,0xF1,0x3F, /* Confirm and load A */ + 0xAE,0xF3,0x3F, /* Load X with PAL/NTSC byte */ -0x20,0x00,0x00, /* JSR to init routine */ + 0x20,0x00,0x00, /* JSR to init routine */ -0xA9,0x00, -0xAA, -0xA8, -0x20,0x00,0x00, /* JSR to play routine */ -0x8D,0xF5,0x3F, /* Start play routine NMIs. */ -0x90,0xFE, /* Loopie time. */ + 0xA9,0x00, + 0xAA, + 0xA8, + 0x20,0x00,0x00, /* JSR to play routine */ + 0x8D,0xF5,0x3F, /* Start play routine NMIs. */ + 0x90,0xFE, /* Loopie time. */ -/* 0x20 */ -0x8D,0xF3,0x3F, /* Init init NMIs */ -0x18, -0x90,0xFE /* Loopie time. */ + /* 0x20 */ + 0x8D,0xF3,0x3F, /* Init init NMIs */ + 0x18, + 0x90,0xFE /* Loopie time. */ }; static DECLFR(NSFROMRead) { - return (NSFROM-0x3800)[A]; + return (NSFROM-0x3800)[A]; } static int doreset=0; @@ -121,148 +122,148 @@ static uint8 *ExWRAM=0; void NSFGI(int h) { - switch(h) - { - case GI_CLOSE: - if(NSFDATA) {free(NSFDATA);NSFDATA=0;} - if(ExWRAM) {free(ExWRAM);ExWRAM=0;} - if(NSFHeader.SoundChip&1) { -// NSFVRC6_Init(); - } else if(NSFHeader.SoundChip&2) { -// NSFVRC7_Init(); - } else if(NSFHeader.SoundChip&4) { -// FDSSoundReset(); - } else if(NSFHeader.SoundChip&8) { - NSFMMC5_Close(); - } else if(NSFHeader.SoundChip&0x10) { -// NSFN106_Init(); - } else if(NSFHeader.SoundChip&0x20) { -// NSFAY_Init(); - } - break; - case GI_RESETM2: - case GI_POWER: NSF_init();break; - } + switch(h) + { + case GI_CLOSE: + if(NSFDATA) {free(NSFDATA);NSFDATA=0;} + if(ExWRAM) {free(ExWRAM);ExWRAM=0;} + if(NSFHeader.SoundChip&1) { + // NSFVRC6_Init(); + } else if(NSFHeader.SoundChip&2) { + // NSFVRC7_Init(); + } else if(NSFHeader.SoundChip&4) { + // FDSSoundReset(); + } else if(NSFHeader.SoundChip&8) { + NSFMMC5_Close(); + } else if(NSFHeader.SoundChip&0x10) { + // NSFN106_Init(); + } else if(NSFHeader.SoundChip&0x20) { + // NSFAY_Init(); + } + break; + case GI_RESETM2: + case GI_POWER: NSF_init();break; + } } // First 32KB is reserved for sound chip emulation in the iNES mapper code. static INLINE void BANKSET(uint32 A, uint32 bank) { - bank&=NSFMaxBank; - if(NSFHeader.SoundChip&4) - memcpy(ExWRAM+(A-0x6000),NSFDATA+(bank<<12),4096); - else - setprg4(A,bank); + bank&=NSFMaxBank; + if(NSFHeader.SoundChip&4) + memcpy(ExWRAM+(A-0x6000),NSFDATA+(bank<<12),4096); + else + setprg4(A,bank); } int NSFLoad(FCEUFILE *fp) { - int x; + int x; - FCEU_fseek(fp,0,SEEK_SET); - FCEU_fread(&NSFHeader,1,0x80,fp); - if(memcmp(NSFHeader.ID,"NESM\x1a",5)) - return 0; - NSFHeader.SongName[31]=NSFHeader.Artist[31]=NSFHeader.Copyright[31]=0; + FCEU_fseek(fp,0,SEEK_SET); + FCEU_fread(&NSFHeader,1,0x80,fp); + if(memcmp(NSFHeader.ID,"NESM\x1a",5)) + return 0; + NSFHeader.SongName[31]=NSFHeader.Artist[31]=NSFHeader.Copyright[31]=0; - LoadAddr=NSFHeader.LoadAddressLow; - LoadAddr|=NSFHeader.LoadAddressHigh<<8; + LoadAddr=NSFHeader.LoadAddressLow; + LoadAddr|=NSFHeader.LoadAddressHigh<<8; - if(LoadAddr<0x6000) - { - FCEUD_PrintError("Invalid load address."); - return(0); - } - InitAddr=NSFHeader.InitAddressLow; - InitAddr|=NSFHeader.InitAddressHigh<<8; + if(LoadAddr<0x6000) + { + FCEUD_PrintError("Invalid load address."); + return(0); + } + InitAddr=NSFHeader.InitAddressLow; + InitAddr|=NSFHeader.InitAddressHigh<<8; - PlayAddr=NSFHeader.PlayAddressLow; - PlayAddr|=NSFHeader.PlayAddressHigh<<8; + PlayAddr=NSFHeader.PlayAddressLow; + PlayAddr|=NSFHeader.PlayAddressHigh<<8; - NSFSize=FCEU_fgetsize(fp)-0x80; + NSFSize=FCEU_fgetsize(fp)-0x80; - NSFMaxBank=((NSFSize+(LoadAddr&0xfff)+4095)/4096); - NSFMaxBank=uppow2(NSFMaxBank); + NSFMaxBank=((NSFSize+(LoadAddr&0xfff)+4095)/4096); + NSFMaxBank=uppow2(NSFMaxBank); - if(!(NSFDATA=(uint8 *)FCEU_malloc(NSFMaxBank*4096))) - return 0; + if(!(NSFDATA=(uint8 *)FCEU_malloc(NSFMaxBank*4096))) + return 0; - FCEU_fseek(fp,0x80,SEEK_SET); - memset(NSFDATA,0x00,NSFMaxBank*4096); - FCEU_fread(NSFDATA+(LoadAddr&0xfff),1,NSFSize,fp); - - NSFMaxBank--; + FCEU_fseek(fp,0x80,SEEK_SET); + memset(NSFDATA,0x00,NSFMaxBank*4096); + FCEU_fread(NSFDATA+(LoadAddr&0xfff),1,NSFSize,fp); - BSon=0; - for(x=0;x<8;x++) - BSon|=NSFHeader.BankSwitch[x]; + NSFMaxBank--; - GameInfo->type=GIT_NSF; - GameInfo->input[0]=GameInfo->input[1]=SI_GAMEPAD; - GameInfo->cspecial=SIS_NSF; + BSon=0; + for(x=0;x<8;x++) + BSon|=NSFHeader.BankSwitch[x]; - for(x=0;;x++) - { - if(NSFROM[x]==0x20) - { - NSFROM[x+1]=InitAddr&0xFF; - NSFROM[x+2]=InitAddr>>8; - NSFROM[x+8]=PlayAddr&0xFF; - NSFROM[x+9]=PlayAddr>>8; - break; - } - } + GameInfo->type=GIT_NSF; + GameInfo->input[0]=GameInfo->input[1]=SI_GAMEPAD; + GameInfo->cspecial=SIS_NSF; - if(NSFHeader.VideoSystem==0) - GameInfo->vidsys=GIV_NTSC; - else if(NSFHeader.VideoSystem==1) - GameInfo->vidsys=GIV_PAL; + for(x=0;;x++) + { + if(NSFROM[x]==0x20) + { + NSFROM[x+1]=InitAddr&0xFF; + NSFROM[x+2]=InitAddr>>8; + NSFROM[x+8]=PlayAddr&0xFF; + NSFROM[x+9]=PlayAddr>>8; + break; + } + } - GameInterface=NSFGI; + if(NSFHeader.VideoSystem==0) + GameInfo->vidsys=GIV_NTSC; + else if(NSFHeader.VideoSystem==1) + GameInfo->vidsys=GIV_PAL; - FCEU_printf("NSF Loaded. File information:\n\n"); - FCEU_printf(" Name: %s\n Artist: %s\n Copyright: %s\n\n",NSFHeader.SongName,NSFHeader.Artist,NSFHeader.Copyright); - if(NSFHeader.SoundChip) - { - static char *tab[6]={"Konami VRCVI","Konami VRCVII","Nintendo FDS","Nintendo MMC5","Namco 106","Sunsoft FME-07"}; + GameInterface=NSFGI; - for(x=0;x<6;x++) - if(NSFHeader.SoundChip&(1<=6) - BANKSET(0x6000+(x-6)*4096,NSFHeader.BankSwitch[x]); - BANKSET(0x8000+x*4096,NSFHeader.BankSwitch[x]); - } - } - else - { - int32 x; - for(x=(LoadAddr&0xF000);x<0x10000;x+=0x1000) - BANKSET(x,((x-(LoadAddr&0x7000))>>12)); - } + if(BSon) + { + int32 x; + for(x=0;x<8;x++) + { + if(NSFHeader.SoundChip&4 && x>=6) + BANKSET(0x6000+(x-6)*4096,NSFHeader.BankSwitch[x]); + BANKSET(0x8000+x*4096,NSFHeader.BankSwitch[x]); + } + } + else + { + int32 x; + for(x=(LoadAddr&0xF000);x<0x10000;x+=0x1000) + BANKSET(x,((x-(LoadAddr&0x7000))>>12)); + } - SetReadHandler(0xFFFA,0xFFFD,NSFVectorRead); + SetReadHandler(0xFFFA,0xFFFD,NSFVectorRead); - SetWriteHandler(0x2000,0x3fff,0); - SetReadHandler(0x2000,0x37ff,0); - SetReadHandler(0x3836,0x3FFF,0); - SetReadHandler(0x3800,0x3835,NSFROMRead); + SetWriteHandler(0x2000,0x3fff,0); + SetReadHandler(0x2000,0x37ff,0); + SetReadHandler(0x3836,0x3FFF,0); + SetReadHandler(0x3800,0x3835,NSFROMRead); - SetWriteHandler(0x5ff6,0x5fff,NSF_write); + SetWriteHandler(0x5ff6,0x5fff,NSF_write); - SetWriteHandler(0x3ff0,0x3fff,NSF_write); - SetReadHandler(0x3ff0,0x3fff,NSF_read); + SetWriteHandler(0x3ff0,0x3fff,NSF_write); + SetReadHandler(0x3ff0,0x3fff,NSF_read); - if(NSFHeader.SoundChip&1) { - NSFVRC6_Init(); - } else if(NSFHeader.SoundChip&2) { - NSFVRC7_Init(); - } else if(NSFHeader.SoundChip&4) { - FDSSoundReset(); - } else if(NSFHeader.SoundChip&8) { - NSFMMC5_Init(); - } else if(NSFHeader.SoundChip&0x10) { - NSFN106_Init(); - } else if(NSFHeader.SoundChip&0x20) { - NSFAY_Init(); - } - CurrentSong=NSFHeader.StartingSong; - SongReload=0xFF; - NSFNMIFlags=0; + if(NSFHeader.SoundChip&1) { + NSFVRC6_Init(); + } else if(NSFHeader.SoundChip&2) { + NSFVRC7_Init(); + } else if(NSFHeader.SoundChip&4) { + FDSSoundReset(); + } else if(NSFHeader.SoundChip&8) { + NSFMMC5_Init(); + } else if(NSFHeader.SoundChip&0x10) { + NSFN106_Init(); + } else if(NSFHeader.SoundChip&0x20) { + NSFAY_Init(); + } + CurrentSong=NSFHeader.StartingSong; + SongReload=0xFF; + NSFNMIFlags=0; } static DECLFW(NSF_write) { - switch(A) - { - case 0x3FF3:NSFNMIFlags|=1;break; - case 0x3FF4:NSFNMIFlags&=~2;break; - case 0x3FF5:NSFNMIFlags|=2;break; + switch(A) + { + case 0x3FF3:NSFNMIFlags|=1;break; + case 0x3FF4:NSFNMIFlags&=~2;break; + case 0x3FF5:NSFNMIFlags|=2;break; - case 0x5FF6: - case 0x5FF7:if(!(NSFHeader.SoundChip&4)) return; - case 0x5FF8: - case 0x5FF9: - case 0x5FFA: - case 0x5FFB: - case 0x5FFC: - case 0x5FFD: - case 0x5FFE: - case 0x5FFF:if(!BSon) return; - A&=0xF; - BANKSET((A*4096),V); - break; - } + case 0x5FF6: + case 0x5FF7:if(!(NSFHeader.SoundChip&4)) return; + case 0x5FF8: + case 0x5FF9: + case 0x5FFA: + case 0x5FFB: + case 0x5FFC: + case 0x5FFD: + case 0x5FFE: + case 0x5FFF:if(!BSon) return; + A&=0xF; + BANKSET((A*4096),V); + break; + } } static DECLFR(NSF_read) { - int x; + int x; - switch(A) - { - case 0x3ff0:x=SongReload; - if(!fceuindbg) - SongReload=0; - return x; - case 0x3ff1: - if(!fceuindbg) - { - memset(RAM,0x00,0x800); + switch(A) + { + case 0x3ff0:x=SongReload; + if(!fceuindbg) + SongReload=0; + return x; + case 0x3ff1: + if(!fceuindbg) + { + memset(RAM,0x00,0x800); - BWrite[0x4015](0x4015,0x0); - for(x=0;x<0x14;x++) - BWrite[0x4000+x](0x4000+x,0); - BWrite[0x4015](0x4015,0xF); + BWrite[0x4015](0x4015,0x0); + for(x=0;x<0x14;x++) + BWrite[0x4000+x](0x4000+x,0); + BWrite[0x4015](0x4015,0xF); - if(NSFHeader.SoundChip&4) - { - BWrite[0x4017](0x4017,0xC0); /* FDS BIOS writes $C0 */ - BWrite[0x4089](0x4089,0x80); - BWrite[0x408A](0x408A,0xE8); - } - else - { - memset(ExWRAM,0x00,8192); - BWrite[0x4017](0x4017,0xC0); - BWrite[0x4017](0x4017,0xC0); - BWrite[0x4017](0x4017,0x40); - } + if(NSFHeader.SoundChip&4) + { + BWrite[0x4017](0x4017,0xC0); /* FDS BIOS writes $C0 */ + BWrite[0x4089](0x4089,0x80); + BWrite[0x408A](0x408A,0xE8); + } + else + { + memset(ExWRAM,0x00,8192); + BWrite[0x4017](0x4017,0xC0); + BWrite[0x4017](0x4017,0xC0); + BWrite[0x4017](0x4017,0x40); + } - if(BSon) - { - for(x=0;x<8;x++) - BANKSET(0x8000+x*4096,NSFHeader.BankSwitch[x]); - } - return (CurrentSong-1); - } - case 0x3FF3:return PAL; - } - return 0; + if(BSon) + { + for(x=0;x<8;x++) + BANKSET(0x8000+x*4096,NSFHeader.BankSwitch[x]); + } + return (CurrentSong-1); + } + case 0x3FF3:return PAL; + } + return 0; } uint8 FCEU_GetJoyJoy(void); @@ -420,173 +421,173 @@ static int special=0; void DrawNSF(uint8 *XBuf) { - char snbuf[16]; - int x; + char snbuf[16]; + int x; - if(vismode==0) return; + if(vismode==0) return; - memset(XBuf,0,256*240); + memset(XBuf,0,256*240); - { - int32 *Bufpl; - int32 mul=0; + { + int32 *Bufpl; + int32 mul=0; - int l; - l=GetSoundBuffer(&Bufpl); + int l; + l=GetSoundBuffer(&Bufpl); - if(special==0) - { - if(FSettings.SoundVolume) - mul=8192*240/(16384*FSettings.SoundVolume/50); - for(x=0;x<256;x++) - { - uint32 y; - y=142+((Bufpl[(x*l)>>8]*mul)>>14); - if(y<240) - XBuf[x+y*256]=3; - } - } - else if(special==1) - { - if(FSettings.SoundVolume) - mul=8192*240/(8192*FSettings.SoundVolume/50); - for(x=0;x<256;x++) - { - double r; - uint32 xp,yp; + if(special==0) + { + if(FSettings.SoundVolume) + mul=8192*240/(16384*FSettings.SoundVolume/50); + for(x=0;x<256;x++) + { + uint32 y; + y=142+((Bufpl[(x*l)>>8]*mul)>>14); + if(y<240) + XBuf[x+y*256]=3; + } + } + else if(special==1) + { + if(FSettings.SoundVolume) + mul=8192*240/(8192*FSettings.SoundVolume/50); + for(x=0;x<256;x++) + { + double r; + uint32 xp,yp; - r=(Bufpl[(x*l)>>8]*mul)>>14; - xp=128+r*cos(x*M_PI*2/256); - yp=120+r*sin(x*M_PI*2/256); - xp&=255; - yp%=240; - XBuf[xp+yp*256]=3; - } - } - else if(special==2) - { - static double theta=0; - if(FSettings.SoundVolume) - mul=8192*240/(16384*FSettings.SoundVolume/50); - for(x=0;x<128;x++) - { - double xc,yc; - double r,t; - uint32 m,n; - - xc=(double)128-x; - yc=0-((double)( ((Bufpl[(x*l)>>8]) *mul)>>14)); - t=M_PI+atan(yc/xc); - r=sqrt(xc*xc+yc*yc); - - t+=theta; - m=128+r*cos(t); - n=120+r*sin(t); - - if(m<256 && n<240) - XBuf[m+n*256]=3; + r=(Bufpl[(x*l)>>8]*mul)>>14; + xp=128+r*cos(x*M_PI*2/256); + yp=120+r*sin(x*M_PI*2/256); + xp&=255; + yp%=240; + XBuf[xp+yp*256]=3; + } + } + else if(special==2) + { + static double theta=0; + if(FSettings.SoundVolume) + mul=8192*240/(16384*FSettings.SoundVolume/50); + for(x=0;x<128;x++) + { + double xc,yc; + double r,t; + uint32 m,n; - } - for(x=128;x<256;x++) - { - double xc,yc; - double r,t; - uint32 m,n; + xc=(double)128-x; + yc=0-((double)( ((Bufpl[(x*l)>>8]) *mul)>>14)); + t=M_PI+atan(yc/xc); + r=sqrt(xc*xc+yc*yc); - xc=(double)x-128; - yc=(double)((Bufpl[(x*l)>>8]*mul)>>14); - t=atan(yc/xc); - r=sqrt(xc*xc+yc*yc); - - t+=theta; - m=128+r*cos(t); - n=120+r*sin(t); - - if(m<256 && n<240) - XBuf[m+n*256]=3; + t+=theta; + m=128+r*cos(t); + n=120+r*sin(t); - } - theta+=(double)M_PI/256; - } - } + if(m<256 && n<240) + XBuf[m+n*256]=3; - DrawTextTrans(XBuf+10*256+4+(((31-strlen((char*)NSFHeader.SongName))<<2)), 256, NSFHeader.SongName, 6); - DrawTextTrans(XBuf+26*256+4+(((31-strlen((char*)NSFHeader.Artist))<<2)), 256,NSFHeader.Artist, 6); - DrawTextTrans(XBuf+42*256+4+(((31-strlen((char*)NSFHeader.Copyright))<<2)), 256,NSFHeader.Copyright, 6); - - DrawTextTrans(XBuf+70*256+4+(((31-strlen("Song:"))<<2)), 256, (uint8*)"Song:", 6); - sprintf(snbuf,"<%d/%d>",CurrentSong,NSFHeader.TotalSongs); - DrawTextTrans(XBuf+82*256+4+(((31-strlen(snbuf))<<2)), 256, (uint8*)snbuf, 6); + } + for(x=128;x<256;x++) + { + double xc,yc; + double r,t; + uint32 m,n; - { - static uint8 last=0; - uint8 tmp; - tmp=FCEU_GetJoyJoy(); - if((tmp&JOY_RIGHT) && !(last&JOY_RIGHT)) - { - if(CurrentSong1) - { - CurrentSong--; - SongReload=0xFF; - } - } - else if((tmp&JOY_UP) && !(last&JOY_UP)) - { - CurrentSong+=10; - if(CurrentSong>NSFHeader.TotalSongs) CurrentSong=NSFHeader.TotalSongs; - SongReload=0xFF; - } - else if((tmp&JOY_DOWN) && !(last&JOY_DOWN)) - { - CurrentSong-=10; - if(CurrentSong<1) CurrentSong=1; - SongReload=0xFF; - } - else if((tmp&JOY_START) && !(last&JOY_START)) - SongReload=0xFF; - else if((tmp&JOY_A) && !(last&JOY_A)) - { - special=(special+1)%3; - } - last=tmp; - } + xc=(double)x-128; + yc=(double)((Bufpl[(x*l)>>8]*mul)>>14); + t=atan(yc/xc); + r=sqrt(xc*xc+yc*yc); + + t+=theta; + m=128+r*cos(t); + n=120+r*sin(t); + + if(m<256 && n<240) + XBuf[m+n*256]=3; + + } + theta+=(double)M_PI/256; + } + } + + DrawTextTrans(XBuf+10*256+4+(((31-strlen((char*)NSFHeader.SongName))<<2)), 256, NSFHeader.SongName, 6); + DrawTextTrans(XBuf+26*256+4+(((31-strlen((char*)NSFHeader.Artist))<<2)), 256,NSFHeader.Artist, 6); + DrawTextTrans(XBuf+42*256+4+(((31-strlen((char*)NSFHeader.Copyright))<<2)), 256,NSFHeader.Copyright, 6); + + DrawTextTrans(XBuf+70*256+4+(((31-strlen("Song:"))<<2)), 256, (uint8*)"Song:", 6); + sprintf(snbuf,"<%d/%d>",CurrentSong,NSFHeader.TotalSongs); + DrawTextTrans(XBuf+82*256+4+(((31-strlen(snbuf))<<2)), 256, (uint8*)snbuf, 6); + + { + static uint8 last=0; + uint8 tmp; + tmp=FCEU_GetJoyJoy(); + if((tmp&JOY_RIGHT) && !(last&JOY_RIGHT)) + { + if(CurrentSong1) + { + CurrentSong--; + SongReload=0xFF; + } + } + else if((tmp&JOY_UP) && !(last&JOY_UP)) + { + CurrentSong+=10; + if(CurrentSong>NSFHeader.TotalSongs) CurrentSong=NSFHeader.TotalSongs; + SongReload=0xFF; + } + else if((tmp&JOY_DOWN) && !(last&JOY_DOWN)) + { + CurrentSong-=10; + if(CurrentSong<1) CurrentSong=1; + SongReload=0xFF; + } + else if((tmp&JOY_START) && !(last&JOY_START)) + SongReload=0xFF; + else if((tmp&JOY_A) && !(last&JOY_A)) + { + special=(special+1)%3; + } + last=tmp; + } } void DoNSFFrame(void) { - if(((NSFNMIFlags&1) && SongReload) || (NSFNMIFlags&2)) - TriggerNMI(); + if(((NSFNMIFlags&1) && SongReload) || (NSFNMIFlags&2)) + TriggerNMI(); } void FCEUI_NSFSetVis(int mode) { - vismode=mode; + vismode=mode; } int FCEUI_NSFChange(int amount) { - CurrentSong+=amount; - if(CurrentSong<1) CurrentSong=1; - else if(CurrentSong>NSFHeader.TotalSongs) CurrentSong=NSFHeader.TotalSongs; - SongReload=0xFF; + CurrentSong+=amount; + if(CurrentSong<1) CurrentSong=1; + else if(CurrentSong>NSFHeader.TotalSongs) CurrentSong=NSFHeader.TotalSongs; + SongReload=0xFF; - return(CurrentSong); + return(CurrentSong); } -/* Returns total songs */ +//Returns total songs int FCEUI_NSFGetInfo(uint8 *name, uint8 *artist, uint8 *copyright, int maxlen) { - strncpy((char*)name,(char*)NSFHeader.SongName,maxlen); //mbg merge 7/17/06 added casts - strncpy((char*)artist,(char*)NSFHeader.Artist,maxlen); //mbg merge 7/17/06 added casts - strncpy((char*)copyright,(char*)NSFHeader.Copyright,maxlen); //mbg merge 7/17/06 added casts - return(NSFHeader.TotalSongs); + strncpy((char*)name,(char*)NSFHeader.SongName,maxlen); //mbg merge 7/17/06 added casts + strncpy((char*)artist,(char*)NSFHeader.Artist,maxlen); //mbg merge 7/17/06 added casts + strncpy((char*)copyright,(char*)NSFHeader.Copyright,maxlen); //mbg merge 7/17/06 added casts + return(NSFHeader.TotalSongs); } diff --git a/src/ops.inc b/src/ops.inc index 0d66b632..dd1c2b13 100644 --- a/src/ops.inc +++ b/src/ops.inc @@ -22,17 +22,17 @@ case 0x00: /* BRK */ _PC++; PUSH(_PC>>8); PUSH(_PC); - PUSH(_P|U_FLAG|B_FLAG); - _P|=I_FLAG; + PUSH(__P|U_FLAG|B_FLAG); + __P|=I_FLAG; _PI|=I_FLAG; _PC=RdMem(0xFFFE); _PC|=RdMem(0xFFFF)<<8; break; case 0x40: /* RTI */ - _P=POP(); + __P=POP(); /* _PI=_P; This is probably incorrect, so it's commented out. */ - _PI = _P; + _PI = __P; _PC=POP(); _PC|=POP()<<8; break; @@ -47,14 +47,14 @@ case 0x48: /* PHA */ PUSH(_A); break; case 0x08: /* PHP */ - PUSH(_P|U_FLAG|B_FLAG); + PUSH(__P|U_FLAG|B_FLAG); break; case 0x68: /* PLA */ _A=POP(); X_ZN(_A); break; case 0x28: /* PLP */ - _P=POP(); + __P=POP(); break; case 0x4C: { @@ -107,11 +107,11 @@ case 0x98: /* TYA */ break; case 0xBA: /* TSX */ - _X=_S; + _X=__S; X_ZN(_X); break; case 0x9A: /* TXS */ - _S=_X; + __S=_X; break; case 0xCA: /* DEX */ @@ -133,26 +133,26 @@ case 0xC8: /* INY */ break; case 0x18: /* CLC */ - _P&=~C_FLAG; + __P&=~C_FLAG; break; case 0xD8: /* CLD */ - _P&=~D_FLAG; + __P&=~D_FLAG; break; case 0x58: /* CLI */ - _P&=~I_FLAG; + __P&=~I_FLAG; break; case 0xB8: /* CLV */ - _P&=~V_FLAG; + __P&=~V_FLAG; break; case 0x38: /* SEC */ - _P|=C_FLAG; + __P|=C_FLAG; break; case 0xF8: /* SED */ - _P|=D_FLAG; + __P|=D_FLAG; break; case 0x78: /* SEI */ - _P|=I_FLAG; + __P|=I_FLAG; break; case 0xEA: /* NOP */ @@ -296,28 +296,28 @@ case 0x94: ST_ZPX(_Y); case 0x8C: ST_AB(_Y); /* BCC */ -case 0x90: JR(!(_P&C_FLAG)); break; +case 0x90: JR(!(__P&C_FLAG)); break; /* BCS */ -case 0xB0: JR(_P&C_FLAG); break; +case 0xB0: JR(__P&C_FLAG); break; /* BEQ */ -case 0xF0: JR(_P&Z_FLAG); break; +case 0xF0: JR(__P&Z_FLAG); break; /* BNE */ -case 0xD0: JR(!(_P&Z_FLAG)); break; +case 0xD0: JR(!(__P&Z_FLAG)); break; /* BMI */ -case 0x30: JR(_P&N_FLAG); break; +case 0x30: JR(__P&N_FLAG); break; /* BPL */ -case 0x10: JR(!(_P&N_FLAG)); break; +case 0x10: JR(!(__P&N_FLAG)); break; /* BVC */ -case 0x50: JR(!(_P&V_FLAG)); break; +case 0x50: JR(!(__P&V_FLAG)); break; /* BVS */ -case 0x70: JR(_P&V_FLAG); break; +case 0x70: JR(__P&V_FLAG); break; //default: printf("Bad %02x at $%04x\n",b1,X.PC);break; //ifdef moo @@ -327,7 +327,7 @@ case 0x70: JR(_P&V_FLAG); break; /* AAC */ case 0x2B: -case 0x0B: LD_IM(AND;_P&=~C_FLAG;_P|=_A>>7); +case 0x0B: LD_IM(AND;__P&=~C_FLAG;__P|=_A>>7); /* AAX */ case 0x87: ST_ZP(_A&_X); @@ -338,7 +338,7 @@ case 0x83: ST_IX(_A&_X); /* ARR - ARGH, MATEY! */ case 0x6B: { uint8 arrtmp; - LD_IM(AND;_P&=~V_FLAG;_P|=(_A^(_A>>1))&0x40;arrtmp=_A>>7;_A>>=1;_A|=(_P&C_FLAG)<<7;_P&=~C_FLAG;_P|=arrtmp;X_ZN(_A)); + LD_IM(AND;__P&=~V_FLAG;__P|=(_A^(_A>>1))&0x40;arrtmp=_A>>7;_A>>=1;_A|=(__P&C_FLAG)<<7;__P&=~C_FLAG;__P|=arrtmp;X_ZN(_A)); } /* ASR */ case 0x4B: LD_IM(AND;LSRA); @@ -404,7 +404,7 @@ case 0xF2:ADDCYC(0xFF); break; /* LAR */ -case 0xBB: RMW_ABY(_S&=x;_A=_X=_S;X_ZN(_X)); +case 0xBB: RMW_ABY(__S&=x;_A=_X=__S;X_ZN(_X)); /* LAX */ case 0xA7: LD_ZP(LDA;LDX); @@ -469,7 +469,7 @@ case 0x9C: ST_ABX(_Y&(((A-_X)>>8)+1)); case 0x9E: ST_ABY(_X&(((A-_Y)>>8)+1)); /* XAS */ -case 0x9B: _S=_A&_X;ST_ABY(_S& (((A-_Y)>>8)+1) ); +case 0x9B: __S=_A&_X;ST_ABY(__S& (((A-_Y)>>8)+1) ); /* TOP */ case 0x0C: LD_AB(;); diff --git a/src/palette.cpp b/src/palette.cpp index fcf30e1d..0b9a2f56 100644 --- a/src/palette.cpp +++ b/src/palette.cpp @@ -1,22 +1,22 @@ /* FCE Ultra - NES/Famicom Emulator - * - * Copyright notice for this file: - * Copyright (C) 2002,2003 Xodnizel - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ +* +* Copyright notice for this file: +* Copyright (C) 2002,2003 Xodnizel +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ #include #include @@ -50,219 +50,219 @@ uint8 pale=0; pal *palo; static pal *palpoint[8]= - { - palette, - rp2c04001, - rp2c04002, - rp2c04003, - rp2c05004, - }; +{ + palette, + rp2c04001, + rp2c04002, + rp2c04003, + rp2c05004, +}; void FCEUI_SetPaletteArray(uint8 *pal) { - if(!pal) - palpoint[0]=palette; - else - { - int x; - palpoint[0]=palettec; - for(x=0;x<64;x++) - { - palpoint[0][x].r=*((uint8 *)pal+x+x+x); - palpoint[0][x].g=*((uint8 *)pal+x+x+x+1); - palpoint[0][x].b=*((uint8 *)pal+x+x+x+2); - } - } - FCEU_ResetPalette(); + if(!pal) + palpoint[0]=palette; + else + { + int x; + palpoint[0]=palettec; + for(x=0;x<64;x++) + { + palpoint[0][x].r=*((uint8 *)pal+x+x+x); + palpoint[0][x].g=*((uint8 *)pal+x+x+x+1); + palpoint[0][x].b=*((uint8 *)pal+x+x+x+2); + } + } + FCEU_ResetPalette(); } void FCEUI_SetNTSCTH(int n, int tint, int hue) { - ntsctint=tint; - ntschue=hue; - ntsccol=n; - FCEU_ResetPalette(); + ntsctint=tint; + ntschue=hue; + ntsccol=n; + FCEU_ResetPalette(); } static uint8 lastd=0; void SetNESDeemph(uint8 d, int force) { - static uint16 rtmul[7]={32768*1.239,32768*.794,32768*1.019,32768*.905,32768*1.023,32768*.741,32768*.75}; - static uint16 gtmul[7]={32768*.915,32768*1.086,32768*.98,32768*1.026,32768*.908,32768*.987,32768*.75}; - static uint16 btmul[7]={32768*.743,32768*.882,32768*.653,32768*1.277,32768*.979,32768*.101,32768*.75}; - uint32 r,g,b; - int x; + static uint16 rtmul[7]={32768*1.239,32768*.794,32768*1.019,32768*.905,32768*1.023,32768*.741,32768*.75}; + static uint16 gtmul[7]={32768*.915,32768*1.086,32768*.98,32768*1.026,32768*.908,32768*.987,32768*.75}; + static uint16 btmul[7]={32768*.743,32768*.882,32768*.653,32768*1.277,32768*.979,32768*.101,32768*.75}; + uint32 r,g,b; + int x; - /* If it's not forced(only forced when the palette changes), - don't waste cpu time if the same deemphasis bits are set as the last call. - */ - if(!force) - { - if(d==lastd) - return; - } - else /* Only set this when palette has changed. */ - { - r=rtmul[6]; - g=rtmul[6]; - b=rtmul[6]; + /* If it's not forced(only forced when the palette changes), + don't waste cpu time if the same deemphasis bits are set as the last call. + */ + if(!force) + { + if(d==lastd) + return; + } + else /* Only set this when palette has changed. */ + { + r=rtmul[6]; + g=rtmul[6]; + b=rtmul[6]; - for(x=0;x<0x40;x++) - { - uint32 m,n,o; - m=palo[x].r; - n=palo[x].g; - o=palo[x].b; - m=(m*r)>>15; - n=(n*g)>>15; - o=(o*b)>>15; - if(m>0xff) m=0xff; - if(n>0xff) n=0xff; - if(o>0xff) o=0xff; - FCEUD_SetPalette(x|0xC0,m,n,o); - } - } - if(!d) return; /* No deemphasis, so return. */ + for(x=0;x<0x40;x++) + { + uint32 m,n,o; + m=palo[x].r; + n=palo[x].g; + o=palo[x].b; + m=(m*r)>>15; + n=(n*g)>>15; + o=(o*b)>>15; + if(m>0xff) m=0xff; + if(n>0xff) n=0xff; + if(o>0xff) o=0xff; + FCEUD_SetPalette(x|0xC0,m,n,o); + } + } + if(!d) return; /* No deemphasis, so return. */ - r=rtmul[d-1]; - g=gtmul[d-1]; - b=btmul[d-1]; + r=rtmul[d-1]; + g=gtmul[d-1]; + b=btmul[d-1]; - for(x=0;x<0x40;x++) - { - uint32 m,n,o; - - m=palo[x].r; - n=palo[x].g; - o=palo[x].b; - m=(m*r)>>15; - n=(n*g)>>15; - o=(o*b)>>15; - if(m>0xff) m=0xff; - if(n>0xff) n=0xff; - if(o>0xff) o=0xff; - - FCEUD_SetPalette(x|0x40,m,n,o); - } - - lastd=d; + for(x=0;x<0x40;x++) + { + uint32 m,n,o; + + m=palo[x].r; + n=palo[x].g; + o=palo[x].b; + m=(m*r)>>15; + n=(n*g)>>15; + o=(o*b)>>15; + if(m>0xff) m=0xff; + if(n>0xff) n=0xff; + if(o>0xff) o=0xff; + + FCEUD_SetPalette(x|0x40,m,n,o); + } + + lastd=d; } - + /* Converted from Kevin Horton's qbasic palette generator. */ static void CalculatePalette(void) { - int x,z; - int r,g,b; - double s,luma,theta; - static uint8 cols[16]={0,24,21,18,15,12,9,6,3,0,33,30,27,0,0,0}; - static uint8 br1[4]={6,9,12,12}; - static double br2[4]={.29,.45,.73,.9}; - static double br3[4]={0,.24,.47,.77}; - - for(x=0;x<=3;x++) - for(z=0;z<16;z++) - { - s=(double)ntsctint/128; - luma=br2[x]; - if(z==0) {s=0;luma=((double)br1[x])/12;} - - if(z>=13) - { - s=luma=0; - if(z==13) - luma=br3[x]; - } - - theta=(double)M_PI*(double)(((double)cols[z]*10+ (((double)ntschue/2)+300) )/(double)180); - r=(int)((luma+s*sin(theta))*256); - g=(int)((luma-(double)27/53*s*sin(theta)+(double)10/53*s*cos(theta))*256); - b=(int)((luma-s*cos(theta))*256); - - - if(r>255) r=255; - if(g>255) g=255; - if(b>255) b=255; - if(r<0) r=0; - if(g<0) g=0; - if(b<0) b=0; - - paletten[(x<<4)+z].r=r; - paletten[(x<<4)+z].g=g; - paletten[(x<<4)+z].b=b; - } - WritePalette(); + int x,z; + int r,g,b; + double s,luma,theta; + static uint8 cols[16]={0,24,21,18,15,12,9,6,3,0,33,30,27,0,0,0}; + static uint8 br1[4]={6,9,12,12}; + static double br2[4]={.29,.45,.73,.9}; + static double br3[4]={0,.24,.47,.77}; + + for(x=0;x<=3;x++) + for(z=0;z<16;z++) + { + s=(double)ntsctint/128; + luma=br2[x]; + if(z==0) {s=0;luma=((double)br1[x])/12;} + + if(z>=13) + { + s=luma=0; + if(z==13) + luma=br3[x]; + } + + theta=(double)M_PI*(double)(((double)cols[z]*10+ (((double)ntschue/2)+300) )/(double)180); + r=(int)((luma+s*sin(theta))*256); + g=(int)((luma-(double)27/53*s*sin(theta)+(double)10/53*s*cos(theta))*256); + b=(int)((luma-s*cos(theta))*256); + + + if(r>255) r=255; + if(g>255) g=255; + if(b>255) b=255; + if(r<0) r=0; + if(g<0) g=0; + if(b<0) b=0; + + paletten[(x<<4)+z].r=r; + paletten[(x<<4)+z].g=g; + paletten[(x<<4)+z].b=b; + } + WritePalette(); } static int ipalette=0; - + void FCEU_LoadGamePalette(void) { - uint8 ptmp[192]; - FILE *fp; - char *fn; + uint8 ptmp[192]; + FILE *fp; + char *fn; - ipalette=0; + ipalette=0; - fn=FCEU_MakeFName(FCEUMKF_PALETTE,0,0); + fn=strdup(FCEU_MakeFName(FCEUMKF_PALETTE,0,0).c_str()); - if((fp=FCEUD_UTF8fopen(fn,"rb"))) - { - int x; - fread(ptmp,1,192,fp); - fclose(fp); - for(x=0;x<64;x++) - { - palettei[x].r=ptmp[x+x+x]; - palettei[x].g=ptmp[x+x+x+1]; - palettei[x].b=ptmp[x+x+x+2]; - } - ipalette=1; - } - free(fn); + if((fp=FCEUD_UTF8fopen(fn,"rb"))) + { + int x; + fread(ptmp,1,192,fp); + fclose(fp); + for(x=0;x<64;x++) + { + palettei[x].r=ptmp[x+x+x]; + palettei[x].g=ptmp[x+x+x+1]; + palettei[x].b=ptmp[x+x+x+2]; + } + ipalette=1; + } + free(fn); } void FCEU_ResetPalette(void) { - if(GameInfo) - { - ChoosePalette(); - WritePalette(); - } + if(GameInfo) + { + ChoosePalette(); + WritePalette(); + } } - + static void ChoosePalette(void) { - if(GameInfo->type==GIT_NSF) - palo=0; - else if(ipalette) - palo=palettei; - else if(ntsccol && !PAL && GameInfo->type!=GIT_VSUNI) - { - palo=paletten; - CalculatePalette(); - } - else - palo=palpoint[pale]; + if(GameInfo->type==GIT_NSF) + palo=0; + else if(ipalette) + palo=palettei; + else if(ntsccol && !PAL && GameInfo->type!=GIT_VSUNI) + { + palo=paletten; + CalculatePalette(); + } + else + palo=palpoint[pale]; } void WritePalette(void) { - int x; - - for(x=0;x<7;x++) - FCEUD_SetPalette(x,unvpalette[x].r,unvpalette[x].g,unvpalette[x].b); - if(GameInfo->type==GIT_NSF) - { - //for(x=0;x<128;x++) - // FCEUD_SetPalette(x,x,0,x); - } - else - { - for(x=0;x<64;x++) - FCEUD_SetPalette(128+x,palo[x].r,palo[x].g,palo[x].b); - SetNESDeemph(lastd,1); - } + int x; + + for(x=0;x<7;x++) + FCEUD_SetPalette(x,unvpalette[x].r,unvpalette[x].g,unvpalette[x].b); + if(GameInfo->type==GIT_NSF) + { + //for(x=0;x<128;x++) + // FCEUD_SetPalette(x,x,0,x); + } + else + { + for(x=0;x<64;x++) + FCEUD_SetPalette(128+x,palo[x].r,palo[x].g,palo[x].b); + SetNESDeemph(lastd,1); + } } void FCEUI_GetNTSCTH(int *tint, int *hue) @@ -277,90 +277,90 @@ static int controllength=0; void FCEUI_NTSCDEC(void) { if(ntsccol && GameInfo->type!=GIT_VSUNI &&!PAL && GameInfo->type!=GIT_NSF) - { - int which; - if(controlselect) - { - if(controllength) - { - which=controlselect==1?ntschue:ntsctint; - which--; - if(which<0) which=0; - if(controlselect==1) - ntschue=which; - else ntsctint=which; - CalculatePalette(); - } - controllength=360; - } + { + int which; + if(controlselect) + { + if(controllength) + { + which=controlselect==1?ntschue:ntsctint; + which--; + if(which<0) which=0; + if(controlselect==1) + ntschue=which; + else ntsctint=which; + CalculatePalette(); + } + controllength=360; + } } } void FCEUI_NTSCINC(void) { - if(ntsccol && GameInfo->type!=GIT_VSUNI && !PAL && GameInfo->type!=GIT_NSF) - if(controlselect) - { - if(controllength) - { - switch(controlselect) - { - case 1:ntschue++; - if(ntschue>128) ntschue=128; - CalculatePalette(); - break; - case 2:ntsctint++; - if(ntsctint>128) ntsctint=128; - CalculatePalette(); - break; - } - } - controllength=360; - } + if(ntsccol && GameInfo->type!=GIT_VSUNI && !PAL && GameInfo->type!=GIT_NSF) + if(controlselect) + { + if(controllength) + { + switch(controlselect) + { + case 1:ntschue++; + if(ntschue>128) ntschue=128; + CalculatePalette(); + break; + case 2:ntsctint++; + if(ntsctint>128) ntsctint=128; + CalculatePalette(); + break; + } + } + controllength=360; + } } void FCEUI_NTSCSELHUE(void) { - if(ntsccol && GameInfo->type!=GIT_VSUNI && !PAL && GameInfo->type!=GIT_NSF){controlselect=1;controllength=360;} + if(ntsccol && GameInfo->type!=GIT_VSUNI && !PAL && GameInfo->type!=GIT_NSF){controlselect=1;controllength=360;} } void FCEUI_NTSCSELTINT(void) { - if(ntsccol && GameInfo->type!=GIT_VSUNI && !PAL && GameInfo->type!=GIT_NSF){controlselect=2;controllength=360;} + if(ntsccol && GameInfo->type!=GIT_VSUNI && !PAL && GameInfo->type!=GIT_NSF){controlselect=2;controllength=360;} } void FCEU_DrawNTSCControlBars(uint8 *XBuf) { - uint8 *XBaf; - int which=0; - int x,x2; + uint8 *XBaf; + int which=0; + int x,x2; - if(!controllength) return; - controllength--; - if(!XBuf) return; + if(!controllength) return; + controllength--; + if(!XBuf) return; - if(controlselect==1) - { - DrawTextTrans(XBuf+128-12+180*256, 256, (uint8 *)"Hue", 0x85); - which=ntschue<<1; - } - else if(controlselect==2) - { - DrawTextTrans(XBuf+128-16+180*256, 256, (uint8 *)"Tint", 0x85); - which=ntsctint<<1; - } + if(controlselect==1) + { + DrawTextTrans(XBuf+128-12+180*256, 256, (uint8 *)"Hue", 0x85); + which=ntschue<<1; + } + else if(controlselect==2) + { + DrawTextTrans(XBuf+128-16+180*256, 256, (uint8 *)"Tint", 0x85); + which=ntsctint<<1; + } - XBaf=XBuf+200*256; - for(x=0;x=-6;x2--) - { - XBaf[x-256*x2]=0x85; - } - } - for(;x<256;x+=2) - { - for(x2=2;x2>=-2;x2--) - XBaf[x-256*x2]=0x85; - } + XBaf=XBuf+200*256; + for(x=0;x=-6;x2--) + { + XBaf[x-256*x2]=0x85; + } + } + for(;x<256;x+=2) + { + for(x2=2;x2>=-2;x2--) + XBaf[x-256*x2]=0x85; + } } diff --git a/src/ppu.cpp b/src/ppu.cpp index e317f851..59927d46 100644 --- a/src/ppu.cpp +++ b/src/ppu.cpp @@ -38,6 +38,7 @@ #include "state.h" #include "video.h" #include "input.h" +#include "driver.h" #define VBlankON (PPU[0]&0x80) /* Generate VBlank NMI */ #define Sprite16 (PPU[0]&0x20) /* Sprites 8x16/8x8 */ diff --git a/src/state.cpp b/src/state.cpp index 3fa333c6..f8a5bd1c 100644 --- a/src/state.cpp +++ b/src/state.cpp @@ -1,25 +1,24 @@ /* FCE Ultra - NES/Famicom Emulator - * - * Copyright notice for this file: - * Copyright (C) 2002 Xodnizel - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ +* +* Copyright notice for this file: +* Copyright (C) 2002 Xodnizel +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ -/* TODO: Add (better) file io error checking */ -/* TODO: Change save state file format. */ +// TODO: Add (better) file io error checking #include #include @@ -28,6 +27,7 @@ //#include //mbg merge 7/17/06 removed #include +#include #include "types.h" #include "x6502.h" @@ -46,6 +46,7 @@ #include "video.h" #include "input.h" #include "zlib.h" +#include "driver.h" static void (*SPreSave)(void); static void (*SPostSave)(void); @@ -67,114 +68,114 @@ extern SFORMAT FCEUMOV_STATEINFO[]; SFORMAT SFCPU[]={ - { &X.PC, 2|RLSB, "PC\0"}, - { &X.A, 1, "A\0\0"}, - { &X.P, 1, "P\0\0"}, - { &X.X, 1, "X\0\0"}, - { &X.Y, 1, "Y\0\0"}, - { &X.S, 1, "S\0\0"}, - { &RAM, 0x800 | FCEUSTATE_INDIRECT, "RAM", }, - { 0 } + { &X.PC, 2|RLSB, "PC\0"}, + { &X.A, 1, "A\0\0"}, + { &X.P, 1, "P\0\0"}, + { &X.X, 1, "X\0\0"}, + { &X.Y, 1, "Y\0\0"}, + { &X.S, 1, "S\0\0"}, + { &RAM, 0x800 | FCEUSTATE_INDIRECT, "RAM", }, + { 0 } }; SFORMAT SFCPUC[]={ - { &X.jammed, 1, "JAMM"}, - { &X.IRQlow, 4|RLSB, "IQLB"}, - { &X.tcount, 4|RLSB, "ICoa"}, - { &X.count, 4|RLSB, "ICou"}, - { ×tampbase, sizeof(timestampbase) | RLSB, "TSBS"}, - { &X.mooPI, 1, "MooP"}, // alternative to the "quick and dirty hack" - { 0 } + { &X.jammed, 1, "JAMM"}, + { &X.IRQlow, 4|RLSB, "IQLB"}, + { &X.tcount, 4|RLSB, "ICoa"}, + { &X.count, 4|RLSB, "ICou"}, + { ×tampbase, sizeof(timestampbase) | RLSB, "TSBS"}, + { &X.mooPI, 1, "MooP"}, // alternative to the "quick and dirty hack" + { 0 } }; static int SubWrite(std::ostream* os, SFORMAT *sf) { - uint32 acc=0; + uint32 acc=0; - while(sf->v) - { - if(sf->s==~0) //Link to another struct - { - uint32 tmp; + while(sf->v) + { + if(sf->s==~0) //Link to another struct + { + uint32 tmp; - if(!(tmp=SubWrite(os,(SFORMAT *)sf->v))) - return(0); - acc+=tmp; - sf++; - continue; - } + if(!(tmp=SubWrite(os,(SFORMAT *)sf->v))) + return(0); + acc+=tmp; + sf++; + continue; + } - acc+=8; //Description + size - acc+=sf->s&(~FCEUSTATE_FLAGS); + acc+=8; //Description + size + acc+=sf->s&(~FCEUSTATE_FLAGS); - if(os) //Are we writing or calculating the size of this block? - { - os->write(sf->desc,4); - write32le(sf->s&(~FCEUSTATE_FLAGS),os); + if(os) //Are we writing or calculating the size of this block? + { + os->write(sf->desc,4); + write32le(sf->s&(~FCEUSTATE_FLAGS),os); - #ifndef LSB_FIRST - if(sf->s&RLSB) - FlipByteOrder(sf->v,sf->s&(~FCEUSTATE_FLAGS)); - #endif - - if(sf->s&FCEUSTATE_INDIRECT) - os->write(*(char **)sf->v,sf->s&(~FCEUSTATE_FLAGS)); - else - os->write((char*)sf->v,sf->s&(~FCEUSTATE_FLAGS)); +#ifndef LSB_FIRST + if(sf->s&RLSB) + FlipByteOrder(sf->v,sf->s&(~FCEUSTATE_FLAGS)); +#endif - //Now restore the original byte order. - #ifndef LSB_FIRST - if(sf->s&RLSB) - FlipByteOrder(sf->v,sf->s&(~FCEUSTATE_FLAGS)); - #endif - } - sf++; - } + if(sf->s&FCEUSTATE_INDIRECT) + os->write(*(char **)sf->v,sf->s&(~FCEUSTATE_FLAGS)); + else + os->write((char*)sf->v,sf->s&(~FCEUSTATE_FLAGS)); - return(acc); + //Now restore the original byte order. +#ifndef LSB_FIRST + if(sf->s&RLSB) + FlipByteOrder(sf->v,sf->s&(~FCEUSTATE_FLAGS)); +#endif + } + sf++; + } + + return(acc); } static int SubWrite(FILE *st, SFORMAT *sf) { - uint32 acc=0; + uint32 acc=0; - while(sf->v) - { - if(sf->s==~0) //Link to another struct - { - uint32 tmp; + while(sf->v) + { + if(sf->s==~0) //Link to another struct + { + uint32 tmp; - if(!(tmp=SubWrite(st,(SFORMAT *)sf->v))) - return(0); - acc+=tmp; - sf++; - continue; - } + if(!(tmp=SubWrite(st,(SFORMAT *)sf->v))) + return(0); + acc+=tmp; + sf++; + continue; + } - acc+=8; //Description + size - acc+=sf->s&(~FCEUSTATE_FLAGS); + acc+=8; //Description + size + acc+=sf->s&(~FCEUSTATE_FLAGS); - if(st) // Are we writing or calculating the size of this block? - { - fwrite(sf->desc,1,4,st); - write32le(sf->s&(~FCEUSTATE_FLAGS),st); + if(st) // Are we writing or calculating the size of this block? + { + fwrite(sf->desc,1,4,st); + write32le(sf->s&(~FCEUSTATE_FLAGS),st); - #ifndef LSB_FIRST - if(sf->s&RLSB) - FlipByteOrder(sf->v,sf->s&(~FCEUSTATE_FLAGS)); - #endif - - fwrite((uint8 *)sf->v,1,sf->s&(~FCEUSTATE_FLAGS),st); - //Now restore the original byte order. - #ifndef LSB_FIRST - if(sf->s&RLSB) - FlipByteOrder(sf->v,sf->s&(~FCEUSTATE_FLAGS)); - #endif - } - sf++; - } +#ifndef LSB_FIRST + if(sf->s&RLSB) + FlipByteOrder(sf->v,sf->s&(~FCEUSTATE_FLAGS)); +#endif - return(acc); + fwrite((uint8 *)sf->v,1,sf->s&(~FCEUSTATE_FLAGS),st); + //Now restore the original byte order. +#ifndef LSB_FIRST + if(sf->s&RLSB) + FlipByteOrder(sf->v,sf->s&(~FCEUSTATE_FLAGS)); +#endif + } + sf++; + } + + return(acc); } static int WriteStateChunk(std::ostream* os, int type, SFORMAT *sf) @@ -192,181 +193,181 @@ static int WriteStateChunk(std::ostream* os, int type, SFORMAT *sf) static int WriteStateChunk(FILE *st, int type, SFORMAT *sf) { - int bsize; + int bsize; - fputc(type,st); - - bsize=SubWrite((FILE*)0,sf); - write32le(bsize,st); + fputc(type,st); - if(!SubWrite(st,sf)) - { - return 5; - } - return (bsize+5); + bsize=SubWrite((FILE*)0,sf); + write32le(bsize,st); + + if(!SubWrite(st,sf)) + { + return 5; + } + return (bsize+5); } static SFORMAT *CheckS(SFORMAT *sf, uint32 tsize, char *desc) { - while(sf->v) - { - if(sf->s==~0) /* Link to another SFORMAT structure. */ - { - SFORMAT *tmp; - if((tmp= CheckS((SFORMAT *)sf->v, tsize, desc) )) - return(tmp); - sf++; - continue; - } - if(!memcmp(desc,sf->desc,4)) - { - if(tsize!=(sf->s&(~FCEUSTATE_FLAGS))) - return(0); - return(sf); - } - sf++; - } - return(0); + while(sf->v) + { + if(sf->s==~0) // Link to another SFORMAT structure. + { + SFORMAT *tmp; + if((tmp= CheckS((SFORMAT *)sf->v, tsize, desc) )) + return(tmp); + sf++; + continue; + } + if(!memcmp(desc,sf->desc,4)) + { + if(tsize!=(sf->s&(~FCEUSTATE_FLAGS))) + return(0); + return(sf); + } + sf++; + } + return(0); } -static int scan_chunks=0; -int suppress_scan_chunks=0; - -static int ReadStateChunk(FILE *st, SFORMAT *sf, int size) +static bool ReadStateChunk(std::istream* is, SFORMAT *sf, int size) { - if(scan_chunks) - return fseek(st,size,SEEK_CUR) == 0; + SFORMAT *tmp; + int temp = is->tellg(); - SFORMAT *tmp; - int temp; - temp=ftell(st); + while(is->tellg()readsome(toa,4)<4) + return false; - while(ftell(st)s&FCEUSTATE_INDIRECT) + is->readsome(*(char **)tmp->v,tmp->s&(~FCEUSTATE_FLAGS)); + else + is->readsome((char *)tmp->v,tmp->s&(~FCEUSTATE_FLAGS)); - if((tmp=CheckS(sf,tsize,toa))) - { - if(tmp->s&FCEUSTATE_INDIRECT) - fread(*(uint8 **)tmp->v,1,tmp->s&(~FCEUSTATE_FLAGS),st); - else - fread((uint8 *)tmp->v,1,tmp->s&(~FCEUSTATE_FLAGS),st); - - #ifndef LSB_FIRST - if(tmp->s&RLSB) - FlipByteOrder(tmp->v,tmp->s&(~FCEUSTATE_FLAGS)); - #endif - } - else - fseek(st,tsize,SEEK_CUR); - } // while(...) - return 1; +#ifndef LSB_FIRST + if(tmp->s&RLSB) + FlipByteOrder(tmp->v,tmp->s&(~FCEUSTATE_FLAGS)); +#endif + } + else + is->seekg(tsize,std::ios::cur); + } // while(...) + return true; } static int read_sfcpuc=0, read_snd=0; 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 -static int ReadStateChunks(FILE *st, int32 totalsize) +static bool ReadStateChunks(std::istream* is, int32 totalsize) { - int t; - uint32 size; - int ret=1; - int warned=0; + int t; + uint32 size; + bool ret=true; + bool warned=false; - read_sfcpuc=0; - read_snd=0; + read_sfcpuc=0; + read_snd=0; -// int moo=X.mooPI; - if(!scan_chunks) - X.mooPI=/*X.P*/0xFF; + //mbg 6/16/08 - wtf + //// int moo=X.mooPI; + // if(!scan_chunks) + // X.mooPI=/*X.P*/0xFF; - while(totalsize > 0) - { - t=fgetc(st); - if(t==EOF) break; - if(!read32le(&size,st)) break; - totalsize -= size + 5; + while(totalsize > 0) + { + t=is->get(); + if(t==EOF) break; + if(!read32le(&size,is)) break; + totalsize -= size + 5; - switch(t) - { - case 1:if(!ReadStateChunk(st,SFCPU,size)) ret=0;break; - case 3:if(!ReadStateChunk(st,FCEUPPU_STATEINFO,size)) ret=0;break; - case 4:if(!ReadStateChunk(st,FCEUCTRL_STATEINFO,size)) ret=0;break; - case 7:if(!FCEUMOV_ReadState(st,size)) ret=0;break; - case 0x10:if(!ReadStateChunk(st,SFMDATA,size)) ret=0; break; - - // now it gets hackier: - case 5: - if(!ReadStateChunk(st,FCEUSND_STATEINFO,size)) - ret=0; - else - read_snd=1; - break; - case 6: - if(FCEUMOV_Mode(MOVIEMODE_PLAY|MOVIEMODE_RECORD)) - { - if(!ReadStateChunk(st,FCEUMOV_STATEINFO,size)) ret=0; - } - else - { - if(fseek(st,size,SEEK_CUR)!=0) ret=0; - } - break; - case 8: - // load back buffer + switch(t) { - extern uint8 *XBackBuf; - if(size != fread(XBackBuf,1,size,st)) - ret = 0; -#ifdef WIN32 + case 1:if(!ReadStateChunk(is,SFCPU,size)) ret=false;break; + case 3:if(!ReadStateChunk(is,FCEUPPU_STATEINFO,size)) ret=false;break; + case 4:if(!ReadStateChunk(is,FCEUCTRL_STATEINFO,size)) ret=false;break; + case 7:if(!FCEUMOV_ReadState(is,size)) ret=false;break; + case 0x10:if(!ReadStateChunk(is,SFMDATA,size)) ret=false; break; + + // now it gets hackier: + case 5: + if(!ReadStateChunk(is,FCEUSND_STATEINFO,size)) + ret=false; + else + read_snd=1; + break; + case 6: + if(FCEUMOV_Mode(MOVIEMODE_PLAY|MOVIEMODE_RECORD)) + { + if(!ReadStateChunk(is,FCEUMOV_STATEINFO,size)) ret=false; + } else { - FCEUD_BlitScreen(XBuf); - UpdateFCEUWindow(); + is->seekg(size,std::ios::cur); } + break; + case 8: + // load back buffer + { + extern uint8 *XBackBuf; + if(is->readsome((char*)XBackBuf,size) != size) + ret = false; + + //MBG TODO - can this be moved to a better place? + //does it even make sense, displaying XBuf when its XBackBuf we just loaded? +#ifdef WIN32 + else + { + FCEUD_BlitScreen(XBuf); + UpdateFCEUWindow(); + } #endif + + } + break; + case 2: + { + if(!ReadStateChunk(is,SFCPUC,size)) + ret=false; + else + read_sfcpuc=1; + } break; + default: + // for somebody's sanity's sake, at least warn about it: + if(!warned) + { + char str [256]; + sprintf(str, "Warning: Found unknown save chunk of type %d.\nThis could indicate the save state is corrupted\nor made with a different (incompatible) emulator version.", t); + FCEUD_PrintError(str); + warned=true; + } + //if(fseek(st,size,SEEK_CUR)<0) goto endo;break; + is->seekg(size,std::ios::cur); } - break; - case 2: - { - if(!ReadStateChunk(st,SFCPUC,size)) - ret=0; - else - read_sfcpuc=1; - } break; - default: - // for somebody's sanity's sake, at least warn about it: - if(!warned && !scan_chunks) - { - char str [256]; - sprintf(str, "Warning: Found unknown save chunk of type %d.\nThis could indicate the save state is corrupted\nor made with a different (incompatible) emulator version.", t); - FCEUD_PrintError(str); - warned=1; - } - if(fseek(st,size,SEEK_CUR)<0) goto endo;break; - } - } - endo: + } + //endo: - if(X.mooPI==0xFF && !scan_chunks) - { -// FCEU_PrintError("prevmoo=%d, p=%d",moo,X.P); - X.mooPI=X.P; // "Quick and dirty hack." //begone - } + //mbg 6/16/08 - wtf + // if(X.mooPI==0xFF && !scan_chunks) + // { + //// FCEU_PrintError("prevmoo=%d, p=%d",moo,X.P); + // X.mooPI=X.P; // "Quick and dirty hack." //begone + // } - extern int resetDMCacc; - if(read_snd) - resetDMCacc=0; - else - resetDMCacc=1; + extern int resetDMCacc; + if(read_snd) + resetDMCacc=0; + else + resetDMCacc=1; - return ret; + return ret; } int CurrentState=1; @@ -479,7 +480,8 @@ void FCEUSS_Save(char *fname) else { //FCEU_PrintError("daCurrentState=%d",CurrentState); - st = FCEUD_UTF8_fstream(fn=FCEU_MakeFName(FCEUMKF_STATE,CurrentState,0),"wb"); + fn = strdup(FCEU_MakeFName(FCEUMKF_STATE,CurrentState,0).c_str()); + st = FCEUD_UTF8_fstream(fn,"wb"); free(fn); } @@ -495,7 +497,6 @@ void FCEUSS_Save(char *fname) else FCEUSS_SaveMS(st,0); - st->close(); delete st; if(!fname) @@ -507,37 +508,10 @@ void FCEUSS_Save(char *fname) bool FCEUSS_LoadFP(std::istream* is, ENUM_SSLOADPARAMS params) { - if(params==SSLOADPARAM_DUMMY && suppress_scan_chunks) - return true; - - bool x; uint8 header[16]; char* fn=0; - //Make temporary savestate in case something screws up during the load - if(params == SSLOADPARAM_BACKUP) - { - fn=FCEU_MakeFName(FCEUMKF_NPTEMP,0,0); - FILE *fp; - - if((fp=fopen(fn,"wb"))) - { - if(FCEUSS_SaveFP(fp,0)) - { - fclose(fp); - } - else - { - fclose(fp); - unlink(fn); - free(fn); - fn=0; - } - } - } - - if(params!=SSLOADPARAM_DUMMY) - FCEUMOV_PreLoad(); + FCEUMOV_PreLoad(); //read and analyze the header is->read((char*)&header,16); @@ -547,17 +521,17 @@ bool FCEUSS_LoadFP(std::istream* is, ENUM_SSLOADPARAMS params) int stateversion = FCEU_de32lsb(header + 8); int comprlen = FCEU_de32lsb(header + 12); - std::vector buf(totalsize); + std::vector buf(totalsize); //not compressed: if(comprlen != -1) { //load the compressed chunk and decompress - std::vector cbuf(comprlen); + std::vector cbuf(comprlen); is->read((char*)&cbuf[0],comprlen); uLongf uncomprlen = totalsize; - int error = uncompress(&buf[0],&uncomprlen,&cbuf[0],comprlen); + int error = uncompress((uint8*)&buf[0],&uncomprlen,(uint8*)&cbuf[0],comprlen); if(error != Z_OK || uncomprlen != totalsize) return false; } @@ -566,24 +540,8 @@ bool FCEUSS_LoadFP(std::istream* is, ENUM_SSLOADPARAMS params) is->read((char*)&buf[0],totalsize); } - //dump it back to a tempfile - FILE* tmp = tmpfile(); - fwrite(&buf[0],1,totalsize,tmp); - fseek(tmp,0,SEEK_SET); - - if(params == SSLOADPARAM_DUMMY) - { - scan_chunks=1; - } - - x = ReadStateChunks(tmp,totalsize)!=0; - - if(params == SSLOADPARAM_DUMMY) - { - scan_chunks=0; - fclose(tmp); - return true; - } + memorystream mstemp(&buf); + bool x = ReadStateChunks(&mstemp,totalsize)!=0; //mbg 5/24/08 - we don't support old states, so this shouldnt matter. //if(read_sfcpuc && stateversion<9500) @@ -597,153 +555,16 @@ bool FCEUSS_LoadFP(std::istream* is, ENUM_SSLOADPARAMS params) { FCEUPPU_LoadState(stateversion); FCEUSND_LoadState(stateversion); - x=FCEUMOV_PostLoad()!=0; + x=FCEUMOV_PostLoad(); } - if(fn) - { - if(!x || params == SSLOADPARAM_DUMMY) //is make_backup==2 possible?? oh well. - { - /* Oops! Load the temporary savestate */ - FILE *fp; - - if((fp=fopen(fn,"rb"))) - { - FCEUSS_LoadFP(fp,SSLOADPARAM_NOBACKUP); - fclose(fp); - } - unlink(fn); - } - free(fn); - } - - fclose(tmp); - return x; - - return false; -} - -bool FCEUSS_LoadFP(FILE *st, ENUM_SSLOADPARAMS params) -{ - if(params==SSLOADPARAM_DUMMY && suppress_scan_chunks) - return true; - - bool x; - uint8 header[16]; - char* fn=0; - - //Make temporary savestate in case something screws up during the load - if(params == SSLOADPARAM_BACKUP) - { - fn=FCEU_MakeFName(FCEUMKF_NPTEMP,0,0); - FILE *fp; - - if((fp=fopen(fn,"wb"))) - { - if(FCEUSS_SaveFP(fp,0)) - { - fclose(fp); - } - else - { - fclose(fp); - unlink(fn); - free(fn); - fn=0; - } - } - } - - if(params!=SSLOADPARAM_DUMMY) - FCEUMOV_PreLoad(); - - //read and analyze the header - fread(&header,1,16,st); - if(memcmp(header,"FCSX",4)) - return false; - int totalsize = FCEU_de32lsb(header + 4); - int stateversion = FCEU_de32lsb(header + 8); - int comprlen = FCEU_de32lsb(header + 12); - - //load the compressed chunk and decompress if necessary - std::vector buf(totalsize); - if(comprlen == -1) - { - int ret = fread(&buf[0],1,totalsize,st); - if(ret != totalsize) - return false; - } - else - { - std::vector cbuf(comprlen); - if(fread(&cbuf[0],1,comprlen,st) != comprlen) - return false; - - uLongf uncomprlen = totalsize; - int error = uncompress(&buf[0],&uncomprlen,&cbuf[0],comprlen); - if(error != Z_OK || uncomprlen != totalsize) - return false; - } - - //dump it back to a tempfile - FILE* tmp = tmpfile(); - fwrite(&buf[0],1,totalsize,tmp); - fseek(tmp,0,SEEK_SET); - - if(params == SSLOADPARAM_DUMMY) - { - scan_chunks=1; - } - - x = ReadStateChunks(tmp,totalsize)!=0; - - if(params == SSLOADPARAM_DUMMY) - { - scan_chunks=0; - fclose(tmp); - return true; - } - - //mbg 5/24/08 - we don't support old states, so this shouldnt matter. - //if(read_sfcpuc && stateversion<9500) - // X.IRQlow=0; - - if(GameStateRestore) - { - GameStateRestore(stateversion); - } - if(x) - { - FCEUPPU_LoadState(stateversion); - FCEUSND_LoadState(stateversion); - x=FCEUMOV_PostLoad()!=0; - } - - if(fn) - { - if(!x || params == SSLOADPARAM_DUMMY) //is make_backup==2 possible?? oh well. - { - /* Oops! Load the temporary savestate */ - FILE *fp; - - if((fp=fopen(fn,"rb"))) - { - FCEUSS_LoadFP(fp,SSLOADPARAM_NOBACKUP); - fclose(fp); - } - unlink(fn); - } - free(fn); - } - - fclose(tmp); return x; } -int FCEUSS_Load(char *fname) + +bool FCEUSS_Load(char *fname) { - FILE *st; - char *fn; + std::fstream* st; //mbg movie - this needs to be overhauled ////this fixes read-only toggle problems @@ -755,23 +576,22 @@ int FCEUSS_Load(char *fname) if(geniestage==1) { FCEU_DispMessage("Cannot load FCS in GG screen."); - return(0); + return false; } if(fname) { - st=FCEUD_UTF8fopen(fname, "rb"); + st=FCEUD_UTF8_fstream(fname, "rb"); } else { - st=FCEUD_UTF8fopen(fn=FCEU_MakeFName(FCEUMKF_STATE,CurrentState,fname),"rb"); - free(fn); + st=FCEUD_UTF8_fstream(FCEU_MakeFName(FCEUMKF_STATE,CurrentState,fname),"rb"); } if(st == NULL) { FCEU_DispMessage("State %d load error.",CurrentState); SaveStateStatus[CurrentState]=0; - return(0); + return false; } //If in bot mode, don't do a backup when loading. @@ -793,8 +613,8 @@ int FCEUSS_Load(char *fname) FCEU_DispMessage("State %d loaded.",CurrentState); SaveStateStatus[CurrentState]=1; } - fclose(st); - return(1); + delete st; + return true; } else { @@ -803,29 +623,28 @@ int FCEUSS_Load(char *fname) SaveStateStatus[CurrentState]=1; } FCEU_DispMessage("Error(s) reading state %d!",CurrentState); - fclose(st); - return(0); + delete st; + return 0; } } void FCEUSS_CheckStates(void) { - FILE *st=NULL; - char *fn; - int ssel; + FILE *st=NULL; + char *fn; + int ssel; - for(ssel=0;ssel<10;ssel++) - { - st=FCEUD_UTF8fopen(fn=FCEU_MakeFName(FCEUMKF_STATE,ssel,0),"rb"); - free(fn); - if(st) - { - SaveStateStatus[ssel]=1; - fclose(st); - } - else - SaveStateStatus[ssel]=0; - } + for(ssel=0;ssel<10;ssel++) + { + st=FCEUD_UTF8fopen(FCEU_MakeFName(FCEUMKF_STATE,ssel,0),"rb"); + if(st) + { + SaveStateStatus[ssel]=1; + fclose(st); + } + else + SaveStateStatus[ssel]=0; + } CurrentState=1; StateShow=0; @@ -833,41 +652,41 @@ void FCEUSS_CheckStates(void) void ResetExState(void (*PreSave)(void), void (*PostSave)(void)) { - int x; - for(x=0;x #include +#include #define FCEU_VERSION_NUMERIC 19901 #define FCEU_NAME "FCE Ultra" @@ -134,73 +134,6 @@ typedef uint32_t uint32; typedef void (*writefunc)(uint32 A, uint8 V); typedef uint8 (*readfunc)(uint32 A); - -template -struct ValueArray -{ - T data[N]; - T &operator[](int index) { return data[index]; } - static const int size = N; - bool operator!=(ValueArray &other) { return !operator==(other); } - bool operator==(ValueArray &other) - { - for(int i=0;i -{ - void newGuid() - { - for(int i=0;i='A') a=a-'A'+10; - else a-='0'; - if(b>='A') b=b-'A'+10; - else b-='0'; - return ((unsigned char)a<<4)|(unsigned char)b; - } - - void scan(std::string str) - { - char* endptr = (char*)str.c_str(); - FCEU_en32lsb(data,strtoul(endptr,&endptr,16)); - FCEU_en16lsb(data+4,strtoul(endptr+1,&endptr,16)); - FCEU_en16lsb(data+6,strtoul(endptr+1,&endptr,16)); - FCEU_en16lsb(data+8,strtoul(endptr+1,&endptr,16)); - endptr++; - for(int i=0;i<6;i++) - data[10+i] = hexToByte(&endptr); - } -}; - #endif diff --git a/src/unif.cpp b/src/unif.cpp index 8af71da2..67a53083 100644 --- a/src/unif.cpp +++ b/src/unif.cpp @@ -1,22 +1,22 @@ /* FCE Ultra - NES/Famicom Emulator - * - * Copyright notice for this file: - * Copyright (C) 2002 Xodnizel - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ +* +* Copyright notice for this file: +* Copyright (C) 2002 Xodnizel +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ /* TODO: Battery backup file saving, mirror force */ /* **INCOMPLETE** */ @@ -27,32 +27,33 @@ #include -#include "types.h" -#include "fceu.h" -#include "cart.h" -#include "unif.h" -#include "ines.h" -#include "utils/endian.h" -#include "utils/memory.h" -#include "utils/md5.h" -#include "state.h" -#include "file.h" -#include "input.h" +#include "types.h" +#include "fceu.h" +#include "cart.h" +#include "unif.h" +#include "ines.h" +#include "utils/endian.h" +#include "utils/memory.h" +#include "utils/md5.h" +#include "state.h" +#include "file.h" +#include "input.h" +#include "driver.h" typedef struct { - char ID[4]; - uint32 info; + char ID[4]; + uint32 info; } UNIF_HEADER; typedef struct { - char *name; - void (*init)(CartInfo *); - int flags; + char *name; + void (*init)(CartInfo *); + int flags; } BMAPPING; typedef struct { - char *name; - int (*init)(FCEUFILE *fp); + char *name; + int (*init)(FCEUFILE *fp); } BFMAPPING; static CartInfo UNIFCart; @@ -74,238 +75,238 @@ static uint32 mallocedsizes[32]; static int FixRomSize(uint32 size, uint32 minimum) { - uint32 x=1; //mbg merge 7/17/06 made uint + uint32 x=1; //mbg merge 7/17/06 made uint - if(size0) - if(index<99) - namebuf[index++]=t; + while((t=FCEU_fgetc(fp))>0) + if(index<99) + namebuf[index++]=t; - namebuf[index]=0; - FCEU_printf("%s\n",namebuf); + namebuf[index]=0; + FCEU_printf("%s\n",namebuf); - if(!GameInfo->name) - { - GameInfo->name=(uint8*)malloc(strlen(namebuf)+1); //mbg merge 7/17/06 added cast - strcpy((char*)GameInfo->name,namebuf); //mbg merge 7/17/06 added cast - } - return(1); + if(!GameInfo->name) + { + GameInfo->name=(uint8*)malloc(strlen(namebuf)+1); //mbg merge 7/17/06 added cast + strcpy((char*)GameInfo->name,namebuf); //mbg merge 7/17/06 added cast + } + return(1); } static int DINF(FCEUFILE *fp) { - char name[100], method[100]; - uint8 d, m; - uint16 y; - int t; + char name[100], method[100]; + uint8 d, m; + uint16 y; + int t; - if(FCEU_fread(name,1,100,fp)!=100) - return(0); - if((t=FCEU_fgetc(fp))==EOF) return(0); - d=t; - if((t=FCEU_fgetc(fp))==EOF) return(0); - m=t; - if((t=FCEU_fgetc(fp))==EOF) return(0); - y=t; - if((t=FCEU_fgetc(fp))==EOF) return(0); - y|=t<<8; - if(FCEU_fread(method,1,100,fp)!=100) - return(0); - name[99]=method[99]=0; - FCEU_printf(" Dumped by: %s\n",name); - FCEU_printf(" Dumped with: %s\n",method); - { - char *months[12]={"January","February","March","April","May","June","July", - "August","September","October","November","December"}; - FCEU_printf(" Dumped on: %s %d, %d\n",months[(m-1)%12],d,y); - } - return(1); + if(FCEU_fread(name,1,100,fp)!=100) + return(0); + if((t=FCEU_fgetc(fp))==EOF) return(0); + d=t; + if((t=FCEU_fgetc(fp))==EOF) return(0); + m=t; + if((t=FCEU_fgetc(fp))==EOF) return(0); + y=t; + if((t=FCEU_fgetc(fp))==EOF) return(0); + y|=t<<8; + if(FCEU_fread(method,1,100,fp)!=100) + return(0); + name[99]=method[99]=0; + FCEU_printf(" Dumped by: %s\n",name); + FCEU_printf(" Dumped with: %s\n",method); + { + char *months[12]={"January","February","March","April","May","June","July", + "August","September","October","November","December"}; + FCEU_printf(" Dumped on: %s %d, %d\n",months[(m-1)%12],d,y); + } + return(1); } static int CTRL(FCEUFILE *fp) { - int t; + int t; - if((t=FCEU_fgetc(fp))==EOF) - return(0); - /* The information stored in this byte isn't very helpful, but it's - better than nothing...maybe. - */ + if((t=FCEU_fgetc(fp))==EOF) + return(0); + /* The information stored in this byte isn't very helpful, but it's + better than nothing...maybe. + */ - if(t&1) GameInfo->input[0]=GameInfo->input[1]=SI_GAMEPAD; - else GameInfo->input[0]=GameInfo->input[1]=SI_NONE; + if(t&1) GameInfo->input[0]=GameInfo->input[1]=SI_GAMEPAD; + else GameInfo->input[0]=GameInfo->input[1]=SI_NONE; - if(t&2) GameInfo->input[1]=SI_ZAPPER; - //else if(t&0x10) GameInfo->input[1]=SI_POWERPAD; + if(t&2) GameInfo->input[1]=SI_ZAPPER; + //else if(t&0x10) GameInfo->input[1]=SI_POWERPAD; - return(1); + return(1); } static int TVCI(FCEUFILE *fp) { - int t; - if( (t=FCEU_fgetc(fp)) ==EOF) - return(0); - if(t<=2) - { - char *stuffo[3]={"NTSC","PAL","NTSC and PAL"}; - if(t==0) - { - GameInfo->vidsys=GIV_NTSC; - FCEUI_SetVidSystem(0); - } - else if(t==1) - { - GameInfo->vidsys=GIV_PAL; - FCEUI_SetVidSystem(1); - } - FCEU_printf(" TV Standard Compatibility: %s\n",stuffo[t]); - } - return(1); + int t; + if( (t=FCEU_fgetc(fp)) ==EOF) + return(0); + if(t<=2) + { + char *stuffo[3]={"NTSC","PAL","NTSC and PAL"}; + if(t==0) + { + GameInfo->vidsys=GIV_NTSC; + FCEUI_SetVidSystem(0); + } + else if(t==1) + { + GameInfo->vidsys=GIV_PAL; + FCEUI_SetVidSystem(1); + } + FCEU_printf(" TV Standard Compatibility: %s\n",stuffo[t]); + } + return(1); } static int EnableBattery(FCEUFILE *fp) { - FCEU_printf(" Battery-backed.\n"); - if(FCEU_fgetc(fp)==EOF) - return(0); - UNIFCart.battery=1; - return(1); + FCEU_printf(" Battery-backed.\n"); + if(FCEU_fgetc(fp)==EOF) + return(0); + UNIFCart.battery=1; + return(1); } static int LoadPRG(FCEUFILE *fp) { - int z,t; - z=uchead.ID[3]-'0'; + int z,t; + z=uchead.ID[3]-'0'; - if(z<0 || z>15) - return(0); - FCEU_printf(" PRG ROM %d size: %d",z,(int) uchead.info); - if(malloced[z]) - free(malloced[z]); - t=FixRomSize(uchead.info,2048); - if(!(malloced[z]=(uint8 *)FCEU_malloc(t))) - return(0); - mallocedsizes[z]=t; - memset(malloced[z]+uchead.info,0xFF,t-uchead.info); - if(FCEU_fread(malloced[z],1,uchead.info,fp)!=uchead.info) - { - FCEU_printf("Read Error!\n"); - return(0); - } - else - FCEU_printf("\n"); + if(z<0 || z>15) + return(0); + FCEU_printf(" PRG ROM %d size: %d",z,(int) uchead.info); + if(malloced[z]) + free(malloced[z]); + t=FixRomSize(uchead.info,2048); + if(!(malloced[z]=(uint8 *)FCEU_malloc(t))) + return(0); + mallocedsizes[z]=t; + memset(malloced[z]+uchead.info,0xFF,t-uchead.info); + if(FCEU_fread(malloced[z],1,uchead.info,fp)!=uchead.info) + { + FCEU_printf("Read Error!\n"); + return(0); + } + else + FCEU_printf("\n"); - SetupCartPRGMapping(z,malloced[z],t,0); - return(1); + SetupCartPRGMapping(z,malloced[z],t,0); + return(1); } static int SetBoardName(FCEUFILE *fp) { - if(!(boardname=(uint8 *)FCEU_malloc(uchead.info+1))) - return(0); - FCEU_fread(boardname,1,uchead.info,fp); - boardname[uchead.info]=0; - FCEU_printf(" Board name: %s\n",boardname); - sboardname=boardname; - if(!memcmp(boardname,"NES-",4) || !memcmp(boardname,"UNL-",4) || !memcmp(boardname,"HVC-",4) || !memcmp(boardname,"BTL-",4) || !memcmp(boardname,"BMC-",4)) - sboardname+=4; - return(1); + if(!(boardname=(uint8 *)FCEU_malloc(uchead.info+1))) + return(0); + FCEU_fread(boardname,1,uchead.info,fp); + boardname[uchead.info]=0; + FCEU_printf(" Board name: %s\n",boardname); + sboardname=boardname; + if(!memcmp(boardname,"NES-",4) || !memcmp(boardname,"UNL-",4) || !memcmp(boardname,"HVC-",4) || !memcmp(boardname,"BTL-",4) || !memcmp(boardname,"BMC-",4)) + sboardname+=4; + return(1); } static int LoadCHR(FCEUFILE *fp) { - int z,t; - z=uchead.ID[3]-'0'; - if(z<0 || z>15) - return(0); - FCEU_printf(" CHR ROM %d size: %d",z,(int) uchead.info); - if(malloced[16+z]) - free(malloced[16+z]); - t=FixRomSize(uchead.info,8192); - if(!(malloced[16+z]=(uint8 *)FCEU_malloc(t))) - return(0); - mallocedsizes[16+z]=t; - memset(malloced[16+z]+uchead.info,0xFF,t-uchead.info); - if(FCEU_fread(malloced[16+z],1,uchead.info,fp)!=uchead.info) - { - FCEU_printf("Read Error!\n"); - return(0); - } - else - FCEU_printf("\n"); + int z,t; + z=uchead.ID[3]-'0'; + if(z<0 || z>15) + return(0); + FCEU_printf(" CHR ROM %d size: %d",z,(int) uchead.info); + if(malloced[16+z]) + free(malloced[16+z]); + t=FixRomSize(uchead.info,8192); + if(!(malloced[16+z]=(uint8 *)FCEU_malloc(t))) + return(0); + mallocedsizes[16+z]=t; + memset(malloced[16+z]+uchead.info,0xFF,t-uchead.info); + if(FCEU_fread(malloced[16+z],1,uchead.info,fp)!=uchead.info) + { + FCEU_printf("Read Error!\n"); + return(0); + } + else + FCEU_printf("\n"); - SetupCartCHRMapping(z,malloced[16+z],t,0); - return(1); + SetupCartCHRMapping(z,malloced[16+z],t,0); + return(1); } @@ -315,257 +316,257 @@ static int LoadCHR(FCEUFILE *fp) static BMAPPING bmap[] = { -/* Sachen Carts */ - { "TC-U01-1.5M", TCU01_Init,0}, - { "Sachen-8259A", S8259A_Init,0}, - { "Sachen-8259B", S8259B_Init,0}, - { "Sachen-8259C", S8259C_Init,0}, - { "Sachen-8259D", S8259D_Init,0}, - { "Sachen-74LS374N", S74LS374N_Init,0}, - { "Sachen-74LS374NA", S74LS374NA_Init,0}, //seems to be custom mapper - { "SA-016-1M", SA0161M_Init,0}, - { "SA-72007", SA72007_Init,0}, - { "SA-72008", SA72008_Init,0}, - { "SA-0036", SA0036_Init,0}, - { "SA-0037", SA0037_Init,0}, - { "SA-NROM", TCA01_Init,0}, + /* Sachen Carts */ + { "TC-U01-1.5M", TCU01_Init,0}, + { "Sachen-8259A", S8259A_Init,0}, + { "Sachen-8259B", S8259B_Init,0}, + { "Sachen-8259C", S8259C_Init,0}, + { "Sachen-8259D", S8259D_Init,0}, + { "Sachen-74LS374N", S74LS374N_Init,0}, + { "Sachen-74LS374NA", S74LS374NA_Init,0}, //seems to be custom mapper + { "SA-016-1M", SA0161M_Init,0}, + { "SA-72007", SA72007_Init,0}, + { "SA-72008", SA72008_Init,0}, + { "SA-0036", SA0036_Init,0}, + { "SA-0037", SA0037_Init,0}, + { "SA-NROM", TCA01_Init,0}, -// /* AVE carts. */ -// { "MB-91", MB91_Init,0}, // DeathBots -// { "NINA-06", NINA06_Init,0}, // F-15 City War -// { "NINA-03", NINA03_Init,0}, // Tiles of Fate -// { "NINA-001", NINA001_Init,0}, // Impossible Mission 2 + // /* AVE carts. */ + // { "MB-91", MB91_Init,0}, // DeathBots + // { "NINA-06", NINA06_Init,0}, // F-15 City War + // { "NINA-03", NINA03_Init,0}, // Tiles of Fate + // { "NINA-001", NINA001_Init,0}, // Impossible Mission 2 - { "ANROM", ANROM_Init,0}, + { "ANROM", ANROM_Init,0}, - { "HKROM", HKROM_Init,0}, + { "HKROM", HKROM_Init,0}, - { "EWROM", EWROM_Init,0}, - { "EKROM", EKROM_Init,0}, - { "ELROM", ELROM_Init,0}, - { "ETROM", ETROM_Init,0}, + { "EWROM", EWROM_Init,0}, + { "EKROM", EKROM_Init,0}, + { "ELROM", ELROM_Init,0}, + { "ETROM", ETROM_Init,0}, - { "SAROM", SAROM_Init,0}, - { "SBROM", SBROM_Init,0}, - { "SCROM", SCROM_Init,0}, - { "SEROM", SEROM_Init,0}, - { "SGROM", SGROM_Init,0}, - { "SKROM", SKROM_Init,0}, - { "SLROM", SLROM_Init,0}, - { "SL1ROM", SL1ROM_Init,0}, - { "SNROM", SNROM_Init,0}, - { "SOROM", SOROM_Init,0}, + { "SAROM", SAROM_Init,0}, + { "SBROM", SBROM_Init,0}, + { "SCROM", SCROM_Init,0}, + { "SEROM", SEROM_Init,0}, + { "SGROM", SGROM_Init,0}, + { "SKROM", SKROM_Init,0}, + { "SLROM", SLROM_Init,0}, + { "SL1ROM", SL1ROM_Init,0}, + { "SNROM", SNROM_Init,0}, + { "SOROM", SOROM_Init,0}, - { "TGROM", TGROM_Init,0}, - { "TR1ROM", TFROM_Init,BMCFLAG_FORCE4}, + { "TGROM", TGROM_Init,0}, + { "TR1ROM", TFROM_Init,BMCFLAG_FORCE4}, - { "TEROM", TEROM_Init,0}, - { "TFROM", TFROM_Init,0}, - { "TLROM", TLROM_Init,0}, - { "TKROM", TKROM_Init,0}, - { "TSROM", TSROM_Init,0}, + { "TEROM", TEROM_Init,0}, + { "TFROM", TFROM_Init,0}, + { "TLROM", TLROM_Init,0}, + { "TKROM", TKROM_Init,0}, + { "TSROM", TSROM_Init,0}, - { "TLSROM", TLSROM_Init,0}, - { "TKSROM", TKSROM_Init,0}, - { "TQROM", TQROM_Init,0}, - { "TVROM", TLROM_Init,BMCFLAG_FORCE4}, + { "TLSROM", TLSROM_Init,0}, + { "TKSROM", TKSROM_Init,0}, + { "TQROM", TQROM_Init,0}, + { "TVROM", TLROM_Init,BMCFLAG_FORCE4}, - { "CPROM", CPROM_Init,BMCFLAG_16KCHRR}, - { "CNROM", CNROM_Init,0}, - { "NROM", NROM_Init,0 }, //NROM256_Init,0 }, - { "NROM-128", NROM_Init,0 }, //NROM128_Init,0 }, - { "NROM-256", NROM_Init,0 }, //NROM256_Init,0 }, - { "RROM", NROM_Init,0 }, //NROM128_Init,0 }, - { "RROM-128", NROM_Init,0 }, //NROM128_Init,0 }, - { "MHROM", MHROM_Init,0}, - { "UNROM", UNROM_Init,0}, - { "SUNSOFT_UNROM", SUNSOFT_UNROM_Init,0}, - { "MARIO1-MALEE2", MALEE_Init,0}, + { "CPROM", CPROM_Init,BMCFLAG_16KCHRR}, + { "CNROM", CNROM_Init,0}, + { "NROM", NROM_Init,0 }, //NROM256_Init,0 }, + { "NROM-128", NROM_Init,0 }, //NROM128_Init,0 }, + { "NROM-256", NROM_Init,0 }, //NROM256_Init,0 }, + { "RROM", NROM_Init,0 }, //NROM128_Init,0 }, + { "RROM-128", NROM_Init,0 }, //NROM128_Init,0 }, + { "MHROM", MHROM_Init,0}, + { "UNROM", UNROM_Init,0}, + { "SUNSOFT_UNROM", SUNSOFT_UNROM_Init,0}, + { "MARIO1-MALEE2", MALEE_Init,0}, - { "CC-21", UNLCC21_Init,0}, + { "CC-21", UNLCC21_Init,0}, - { "H2288", UNLH2288_Init,0}, - { "KOF97", UNLKOF97_Init,0}, - { "SL1632", UNLSL1632_Init,0}, - { "SHERO", UNLSHeroes_Init,0}, - { "8237", UNL8237_Init,0}, - { "8157", UNL8157_Init,0}, - { "T-262", BMCT262_Init,0}, - { "FK23C", BMCFK23C_Init,0}, - { "A65AS", BMCA65AS_Init,0}, - { "C-N22M", UNLCN22M_Init,0}, - { "EDU2000", UNLEDU2000_Init,0}, - { "603-5052", UNL6035052_Init,0}, - { "Supervision16in1", Supervision16_Init,0}, - { "NovelDiamond9999999in1", Novel_Init,0}, - { "Super24in1SC03", Super24_Init,0}, - { "42in1ResetSwitch", BMC42in1r_Init, 0}, - { "64in1NoRepeat", BMC64in1nr_Init, 0}, - { "13in1JY110", BMC13in1JY110_Init, 0}, - { "70in1", BMC70in1_Init, 0}, - { "70in1B", BMC70in1B_Init, 0}, - { "D1038", BMCD1038_Init, 0}, - { "GK-192", BMCGK192_Init, 0}, - { "SuperHIK8in1", Mapper45_Init,0}, - { "22211", UNL22211_Init,0}, + { "H2288", UNLH2288_Init,0}, + { "KOF97", UNLKOF97_Init,0}, + { "SL1632", UNLSL1632_Init,0}, + { "SHERO", UNLSHeroes_Init,0}, + { "8237", UNL8237_Init,0}, + { "8157", UNL8157_Init,0}, + { "T-262", BMCT262_Init,0}, + { "FK23C", BMCFK23C_Init,0}, + { "A65AS", BMCA65AS_Init,0}, + { "C-N22M", UNLCN22M_Init,0}, + { "EDU2000", UNLEDU2000_Init,0}, + { "603-5052", UNL6035052_Init,0}, + { "Supervision16in1", Supervision16_Init,0}, + { "NovelDiamond9999999in1", Novel_Init,0}, + { "Super24in1SC03", Super24_Init,0}, + { "42in1ResetSwitch", BMC42in1r_Init, 0}, + { "64in1NoRepeat", BMC64in1nr_Init, 0}, + { "13in1JY110", BMC13in1JY110_Init, 0}, + { "70in1", BMC70in1_Init, 0}, + { "70in1B", BMC70in1B_Init, 0}, + { "D1038", BMCD1038_Init, 0}, + { "GK-192", BMCGK192_Init, 0}, + { "SuperHIK8in1", Mapper45_Init,0}, + { "22211", UNL22211_Init,0}, - { "DREAMTECH01", DreamTech01_Init,0}, - { "KONAMI-QTAI", Mapper190_Init,0}, + { "DREAMTECH01", DreamTech01_Init,0}, + { "KONAMI-QTAI", Mapper190_Init,0}, - { "TEK90", Mapper90_Init,0}, + { "TEK90", Mapper90_Init,0}, - {0,0,0} + {0,0,0} }; static BFMAPPING bfunc[] = { - { "CTRL", CTRL }, - { "TVCI", TVCI }, - { "BATR", EnableBattery }, - { "MIRR", DoMirroring }, - { "PRG", LoadPRG }, - { "CHR", LoadCHR }, - { "NAME", NAME }, - { "MAPR", SetBoardName }, - { "DINF", DINF }, - { 0, 0 } + { "CTRL", CTRL }, + { "TVCI", TVCI }, + { "BATR", EnableBattery }, + { "MIRR", DoMirroring }, + { "PRG", LoadPRG }, + { "CHR", LoadCHR }, + { "NAME", NAME }, + { "MAPR", SetBoardName }, + { "DINF", DINF }, + { 0, 0 } }; int LoadUNIFChunks(FCEUFILE *fp) { - int x; - int t; - for(;;) - { - t=FCEU_fread(&uchead,1,4,fp); - if(t<4) - { - if(t>0) - return 0; - return 1; - } - if(!(FCEU_read32le(&uchead.info,fp))) - return 0; - t=0; - x=0; - //printf("Funky: %s\n",((uint8 *)&uchead)); - while(bfunc[x].name) - { - if(!memcmp(&uchead,bfunc[x].name,strlen(bfunc[x].name))) - { - if(!bfunc[x].init(fp)) - return 0; - t=1; - break; - } - x++; - } - if(!t) - if(FCEU_fseek(fp,uchead.info,SEEK_CUR)) - return(0); - } + int x; + int t; + for(;;) + { + t=FCEU_fread(&uchead,1,4,fp); + if(t<4) + { + if(t>0) + return 0; + return 1; + } + if(!(FCEU_read32le(&uchead.info,fp))) + return 0; + t=0; + x=0; + //printf("Funky: %s\n",((uint8 *)&uchead)); + while(bfunc[x].name) + { + if(!memcmp(&uchead,bfunc[x].name,strlen(bfunc[x].name))) + { + if(!bfunc[x].init(fp)) + return 0; + t=1; + break; + } + x++; + } + if(!t) + if(FCEU_fseek(fp,uchead.info,SEEK_CUR)) + return(0); + } } static int InitializeBoard(void) { - int x=0; + int x=0; - if(!sboardname) return(0); + if(!sboardname) return(0); - while(bmap[x].name) - { - if(!strcmp((char *)sboardname,(char *)bmap[x].name)) - { - if(!malloced[16]) - { - if(bmap[x].flags & BMCFLAG_16KCHRR) - CHRRAMSize = 16384; - else - CHRRAMSize = 8192; - if((UNIFchrrama=(uint8 *)FCEU_malloc(CHRRAMSize))) - { - SetupCartCHRMapping(0,UNIFchrrama,CHRRAMSize,1); - AddExState(UNIFchrrama, CHRRAMSize, 0,"CHRR"); - } - else - return(-1); - } - if(bmap[x].flags&BMCFLAG_FORCE4) - mirrortodo=4; - MooMirroring(); - bmap[x].init(&UNIFCart); - return(1); - } - x++; - } - FCEU_PrintError("Board type not supported."); - return(0); + while(bmap[x].name) + { + if(!strcmp((char *)sboardname,(char *)bmap[x].name)) + { + if(!malloced[16]) + { + if(bmap[x].flags & BMCFLAG_16KCHRR) + CHRRAMSize = 16384; + else + CHRRAMSize = 8192; + if((UNIFchrrama=(uint8 *)FCEU_malloc(CHRRAMSize))) + { + SetupCartCHRMapping(0,UNIFchrrama,CHRRAMSize,1); + AddExState(UNIFchrrama, CHRRAMSize, 0,"CHRR"); + } + else + return(-1); + } + if(bmap[x].flags&BMCFLAG_FORCE4) + mirrortodo=4; + MooMirroring(); + bmap[x].init(&UNIFCart); + return(1); + } + x++; + } + FCEU_PrintError("Board type not supported."); + return(0); } static void UNIFGI(int h) { - switch(h) - { - case GI_RESETM2: - if(UNIFCart.Reset) - UNIFCart.Reset(); + switch(h) + { + case GI_RESETM2: + if(UNIFCart.Reset) + UNIFCart.Reset(); break; - case GI_POWER: - if(UNIFCart.Power) - UNIFCart.Power(); + case GI_POWER: + if(UNIFCart.Power) + UNIFCart.Power(); if(UNIFchrrama) memset(UNIFchrrama,0,8192); break; - case GI_CLOSE: - FCEU_SaveGameSave(&UNIFCart); + case GI_CLOSE: + FCEU_SaveGameSave(&UNIFCart); if(UNIFCart.Close) - UNIFCart.Close(); - FreeUNIF(); - break; - } + UNIFCart.Close(); + FreeUNIF(); + break; + } } int UNIFLoad(const char *name, FCEUFILE *fp) { - FCEU_fseek(fp,0,SEEK_SET); - FCEU_fread(&unhead,1,4,fp); - if(memcmp(&unhead,"UNIF",4)) - return 0; + FCEU_fseek(fp,0,SEEK_SET); + FCEU_fread(&unhead,1,4,fp); + if(memcmp(&unhead,"UNIF",4)) + return 0; ResetCartMapping(); - ResetExState(0,0); - ResetUNIF(); - if(!FCEU_read32le(&unhead.info,fp)) - goto aborto; - if(FCEU_fseek(fp,0x20,SEEK_SET)<0) - goto aborto; - if(!LoadUNIFChunks(fp)) - goto aborto; + ResetExState(0,0); + ResetUNIF(); + if(!FCEU_read32le(&unhead.info,fp)) + goto aborto; + if(FCEU_fseek(fp,0x20,SEEK_SET)<0) + goto aborto; + if(!LoadUNIFChunks(fp)) + goto aborto; { - int x; - struct md5_context md5; - - md5_starts(&md5); + int x; + struct md5_context md5; - for(x=0;x<32;x++) - if(malloced[x]) - { - md5_update(&md5,malloced[x],mallocedsizes[x]); - } - md5_finish(&md5,UNIFCart.MD5); - FCEU_printf(" ROM MD5: 0x"); - for(x=0;x<16;x++) - FCEU_printf("%02x",UNIFCart.MD5[x]); - FCEU_printf("\n"); - memcpy(&GameInfo->MD5,&UNIFCart.MD5,sizeof(UNIFCart.MD5)); + md5_starts(&md5); + + for(x=0;x<32;x++) + if(malloced[x]) + { + md5_update(&md5,malloced[x],mallocedsizes[x]); + } + md5_finish(&md5,UNIFCart.MD5); + FCEU_printf(" ROM MD5: 0x"); + for(x=0;x<16;x++) + FCEU_printf("%02x",UNIFCart.MD5[x]); + FCEU_printf("\n"); + memcpy(&GameInfo->MD5,&UNIFCart.MD5,sizeof(UNIFCart.MD5)); } - if(!InitializeBoard()) - goto aborto; + if(!InitializeBoard()) + goto aborto; FCEU_LoadGameSave(&UNIFCart); - GameInterface=UNIFGI; - return 1; - - aborto: + GameInterface=UNIFGI; + return 1; + +aborto: FreeUNIF(); ResetUNIF(); diff --git a/src/utils/endian.cpp b/src/utils/endian.cpp index 120c6615..e19fcc3a 100644 --- a/src/utils/endian.cpp +++ b/src/utils/endian.cpp @@ -23,6 +23,7 @@ #include #include +#include #include "../types.h" #include "endian.h" @@ -91,6 +92,19 @@ int read32le(uint32 *Bufo, FILE *fp) return 1; } +int read32le(uint32 *Bufo, std::istream *is) +{ + uint32 buf; + if(is->readsome((char*)&buf,4) != 4) + return 0; +#ifdef LSB_FIRST + *(uint32*)Bufo=buf; +#else + *(uint32*)Bufo=((buf&0xFF)<<24)|((buf&0xFF00)<<8)|((buf&0xFF0000)>>8)|((buf&0xFF000000)>>24); +#endif + return 1; +} + ///reads a little endian 16bit value from the specified file int read16le(char *d, FILE *fp) { diff --git a/src/utils/endian.h b/src/utils/endian.h index 581bd58b..2b70d9e4 100644 --- a/src/utils/endian.h +++ b/src/utils/endian.h @@ -1,9 +1,14 @@ #ifndef __FCEU_ENDIAN #define __FCEU_ENDIAN +//#include +#include + + int write16le(uint16 b, FILE *fp); int write32le(uint32 b, FILE *fp); int write32le(uint32 b, std::ostream* os); +int read32le(uint32 *Bufo, std::istream *is); int read32le(uint32 *Bufo, FILE *fp); void FlipByteOrder(uint8 *src, uint32 count); diff --git a/src/utils/guid.cpp b/src/utils/guid.cpp new file mode 100644 index 00000000..7c9dc8cd --- /dev/null +++ b/src/utils/guid.cpp @@ -0,0 +1,47 @@ +#include "guid.h" + +void FCEU_Guid::newGuid() +{ + for(int i=0;i='A') a=a-'A'+10; + else a-='0'; + if(b>='A') b=b-'A'+10; + else b-='0'; + return ((unsigned char)a<<4)|(unsigned char)b; +} + +void FCEU_Guid::scan(std::string& str) +{ + char* endptr = (char*)str.c_str(); + FCEU_en32lsb(data,strtoul(endptr,&endptr,16)); + FCEU_en16lsb(data+4,strtoul(endptr+1,&endptr,16)); + FCEU_en16lsb(data+6,strtoul(endptr+1,&endptr,16)); + FCEU_en16lsb(data+8,strtoul(endptr+1,&endptr,16)); + endptr++; + for(int i=0;i<6;i++) + data[10+i] = hexToByte(&endptr); +} \ No newline at end of file diff --git a/src/utils/guid.h b/src/utils/guid.h new file mode 100644 index 00000000..f9c1e821 --- /dev/null +++ b/src/utils/guid.h @@ -0,0 +1,18 @@ +#ifndef _guid_h_ +#define _guid_h_ + +#include +#include "types.h" +#include "valuearray.h" + +struct FCEU_Guid : public ValueArray +{ + void newGuid(); + std::string toString(); + static FCEU_Guid fromString(std::string str); + static uint8 hexToByte(char** ptrptr); + void scan(std::string& str); +}; + + +#endif \ No newline at end of file diff --git a/src/utils/md5.h b/src/utils/md5.h index 54f6de96..ace98b56 100644 --- a/src/utils/md5.h +++ b/src/utils/md5.h @@ -2,6 +2,7 @@ #define _MD5_H #include "../types.h" +#include "valuearray.h" struct md5_context { diff --git a/src/utils/valuearray.h b/src/utils/valuearray.h new file mode 100644 index 00000000..7d9c4e3f --- /dev/null +++ b/src/utils/valuearray.h @@ -0,0 +1,20 @@ +#ifndef _VALUEARRAY_H_ +#define _VALUEARRAY_H_ + +template +struct ValueArray +{ + T data[N]; + T &operator[](int index) { return data[index]; } + static const int size = N; + bool operator!=(ValueArray &other) { return !operator==(other); } + bool operator==(ValueArray &other) + { + for(int i=0;iunget(); return ret; +} + +std::string stditoa(int n) +{ + char tempbuf[16]; + return itoa(n,tempbuf,10); } \ No newline at end of file diff --git a/src/utils/xstring.h b/src/utils/xstring.h index 10a614c8..d2e2de12 100644 --- a/src/utils/xstring.h +++ b/src/utils/xstring.h @@ -55,5 +55,7 @@ char *U8ToDecStr(uint8 a); char *U8ToHexStr(uint8 a); char *U16ToHexStr(uint16 a); +std::string stditoa(int n); + //extracts a decimal uint from an istream unsigned int uintDecFromIstream(std::istream* is); \ No newline at end of file diff --git a/src/video.cpp b/src/video.cpp index 263a192d..986d5f3e 100644 --- a/src/video.cpp +++ b/src/video.cpp @@ -1,22 +1,22 @@ /* FCE Ultra - NES/Famicom Emulator - * - * Copyright notice for this file: - * Copyright (C) 2002 Xodnizel - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ +* +* Copyright notice for this file: +* Copyright (C) 2002 Xodnizel +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ #ifndef WIN32 #include @@ -64,22 +64,22 @@ HANDLE mapXBuf; void FCEU_KillVirtualVideo(void) { //mbg merge TODO 7/17/06 temporarily removed - //if(xbsave) - //{ - // free(xbsave); - // xbsave=0; - //} - //if(XBuf) - //{ + //if(xbsave) + //{ + // free(xbsave); + // xbsave=0; + //} + //if(XBuf) + //{ //UnmapViewOfFile(XBuf); //CloseHandle(mapXBuf); //mapXBuf=NULL; - //} - //if(XBackBuf) - //{ - // free(XBackBuf); - // XBackBuf=0; - //} + //} + //if(XBackBuf) + //{ + // free(XBackBuf); + // XBackBuf=0; + //} } /** @@ -90,13 +90,13 @@ void FCEU_KillVirtualVideo(void) int FCEU_InitVirtualVideo(void) { if(!XBuf) /* Some driver code may allocate XBuf externally. */ - /* 256 bytes per scanline, * 240 scanline maximum, +16 for alignment, - */ + /* 256 bytes per scanline, * 240 scanline maximum, +16 for alignment, + */ #ifdef _USE_SHARED_MEMORY_ - mapXBuf = CreateFileMapping((HANDLE)0xFFFFFFFF,NULL,PAGE_READWRITE, 0, 256 * 256 + 16, "fceu.XBuf"); - + mapXBuf = CreateFileMapping((HANDLE)0xFFFFFFFF,NULL,PAGE_READWRITE, 0, 256 * 256 + 16, "fceu.XBuf"); + if(mapXBuf == NULL || GetLastError() == ERROR_ALREADY_EXISTS) { CloseHandle(mapXBuf); @@ -114,30 +114,30 @@ int FCEU_InitVirtualVideo(void) { return 0; } - + #else - if(!(XBuf= (uint8*) (FCEU_malloc(256 * 256 + 16))) || - !(XBackBuf= (uint8*) (FCEU_malloc(256 * 256 + 16)))) - { - return 0; - } - + if(!(XBuf= (uint8*) (FCEU_malloc(256 * 256 + 16))) || + !(XBackBuf= (uint8*) (FCEU_malloc(256 * 256 + 16)))) + { + return 0; + } + #endif //_USE_SHARED_MEMORY_ - xbsave = XBuf; + xbsave = XBuf; - if( sizeof(uint8*) == 4 ) - { - uintptr_t m = (uintptr_t)XBuf; - m = ( 8 - m) & 7; - XBuf+=m; - } - - memset(XBuf,128,256*256); //*240); - memset(XBackBuf,128,256*256); - - return 1; + if( sizeof(uint8*) == 4 ) + { + uintptr_t m = (uintptr_t)XBuf; + m = ( 8 - m) & 7; + XBuf+=m; + } + + memset(XBuf,128,256*256); //*240); + memset(XBackBuf,128,256*256); + + return 1; } @@ -147,23 +147,23 @@ int FCEU_InitVirtualVideo(void) void ShowFPS(void); void FCEU_PutImageDummy(void) { - #ifdef SHOWFPS - ShowFPS(); - #endif - if(GameInfo->type!=GIT_NSF) - { - FCEU_DrawNTSCControlBars(XBuf); - FCEU_DrawSaveStates(XBuf); - FCEU_DrawMovies(XBuf); - } - if(guiMessage.howlong) guiMessage.howlong--; /* DrawMessage() */ +#ifdef SHOWFPS + ShowFPS(); +#endif + if(GameInfo->type!=GIT_NSF) + { + FCEU_DrawNTSCControlBars(XBuf); + FCEU_DrawSaveStates(XBuf); + FCEU_DrawMovies(XBuf); + } + if(guiMessage.howlong) guiMessage.howlong--; /* DrawMessage() */ } #endif static int dosnapsave=0; void FCEUI_SaveSnapshot(void) { - dosnapsave=1; + dosnapsave=1; } @@ -182,11 +182,11 @@ void FCEU_PutImage(void) #ifdef SHOWFPS ShowFPS(); #endif - + if(GameInfo->type==GIT_NSF) { DrawNSF(XBuf); - + //Save snapshot after NSF screen is drawn. Why would we want to do it before? if(dosnapsave) { @@ -203,7 +203,7 @@ void FCEU_PutImage(void) //Update AVI before overlay stuff is written if(!FCEUI_EmulationPaused()) FCEUI_AviVideoUpdate(XBuf); - + //Save backbuffer before overlay stuff is written. if(!FCEUI_EmulationPaused()) memcpy(XBackBuf, XBuf, 256*256); @@ -222,7 +222,7 @@ void FCEU_PutImage(void) FCEU_DrawNTSCControlBars(XBuf); FCEU_DrawRecordingStatus(XBuf); } - + DrawMessage(false); if(FCEUD_ShouldDrawInputAids()) @@ -354,140 +354,140 @@ void FCEU_ResetMessages() static int WritePNGChunk(FILE *fp, uint32 size, char *type, uint8 *data) { - uint32 crc; + uint32 crc; - uint8 tempo[4]; + uint8 tempo[4]; - tempo[0]=size>>24; - tempo[1]=size>>16; - tempo[2]=size>>8; - tempo[3]=size; + tempo[0]=size>>24; + tempo[1]=size>>16; + tempo[2]=size>>8; + tempo[3]=size; - if(fwrite(tempo,4,1,fp)!=1) - return 0; - if(fwrite(type,4,1,fp)!=1) - return 0; + if(fwrite(tempo,4,1,fp)!=1) + return 0; + if(fwrite(type,4,1,fp)!=1) + return 0; - if(size) - if(fwrite(data,1,size,fp)!=size) - return 0; + if(size) + if(fwrite(data,1,size,fp)!=size) + return 0; - crc=CalcCRC32(0,(uint8 *)type,4); - if(size) - crc=CalcCRC32(crc,data,size); + crc=CalcCRC32(0,(uint8 *)type,4); + if(size) + crc=CalcCRC32(crc,data,size); - tempo[0]=crc>>24; - tempo[1]=crc>>16; - tempo[2]=crc>>8; - tempo[3]=crc; + tempo[0]=crc>>24; + tempo[1]=crc>>16; + tempo[2]=crc>>8; + tempo[3]=crc; - if(fwrite(tempo,4,1,fp)!=1) - return 0; - return 1; + if(fwrite(tempo,4,1,fp)!=1) + return 0; + return 1; } int SaveSnapshot(void) { - static unsigned int lastu=0; + static unsigned int lastu=0; - char *fn=0; - int totallines=FSettings.LastSLine-FSettings.FirstSLine+1; - int x,u,y; - FILE *pp=NULL; - uint8 *compmem=NULL; - uLongf compmemsize=totallines*263+12; + char *fn=0; + int totallines=FSettings.LastSLine-FSettings.FirstSLine+1; + int x,u,y; + FILE *pp=NULL; + uint8 *compmem=NULL; + uLongf compmemsize=totallines*263+12; - if(!(compmem=(uint8 *)FCEU_malloc(compmemsize))) - return 0; + if(!(compmem=(uint8 *)FCEU_malloc(compmemsize))) + return 0; - for(u=lastu;u<99999;u++) - { - pp=FCEUD_UTF8fopen((fn=FCEU_MakeFName(FCEUMKF_SNAP,u,"png")),"rb"); - if(pp==NULL) break; - fclose(pp); - } + for(u=lastu;u<99999;u++) + { + pp=FCEUD_UTF8fopen((fn=strdup(FCEU_MakeFName(FCEUMKF_SNAP,u,"png").c_str())),"rb"); + if(pp==NULL) break; + fclose(pp); + } - lastu=u; + lastu=u; - if(!(pp=FCEUD_UTF8fopen(fn,"wb"))) - { - free(fn); - return 0; - } - free(fn); - { - static uint8 header[8]={137,80,78,71,13,10,26,10}; - if(fwrite(header,8,1,pp)!=1) - goto PNGerr; - } + if(!(pp=FCEUD_UTF8fopen(fn,"wb"))) + { + free(fn); + return 0; + } + free(fn); + { + static uint8 header[8]={137,80,78,71,13,10,26,10}; + if(fwrite(header,8,1,pp)!=1) + goto PNGerr; + } - { - uint8 chunko[13]; + { + uint8 chunko[13]; - chunko[0]=chunko[1]=chunko[3]=0; - chunko[2]=0x1; // Width of 256 + 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[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. + 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; - } + 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 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; + { + uint8 *tmp=XBuf+FSettings.FirstSLine*256; + uint8 *dest,*mal,*mork; - if(!(mal=mork=dest=(uint8 *)malloc((totallines<<8)+totallines))) - goto PNGerr; - // mork=dest=XBuf; + if(!(mal=mork=dest=(uint8 *)malloc((totallines<<8)+totallines))) + goto PNGerr; + // mork=dest=XBuf; - for(y=0;y>1; \ - _P|=(l>>8)&C_FLAG; \ + uint32 l=_A+x+(__P&1); \ + __P&=~(Z_FLAG|C_FLAG|N_FLAG|V_FLAG); \ + __P|=((((_A^x)&0x80)^0x80) & ((_A^l)&0x80))>>1; \ + __P|=(l>>8)&C_FLAG; \ _A=l; \ X_ZNT(_A); \ } #define SBC { \ - uint32 l=_A-x-((_P&1)^1); \ - _P&=~(Z_FLAG|C_FLAG|N_FLAG|V_FLAG); \ - _P|=((_A^l)&(_A^x)&0x80)>>1; \ - _P|=((l>>8)&C_FLAG)^C_FLAG; \ + uint32 l=_A-x-((__P&1)^1); \ + __P&=~(Z_FLAG|C_FLAG|N_FLAG|V_FLAG); \ + __P|=((_A^l)&(_A^x)&0x80)>>1; \ + __P|=((l>>8)&C_FLAG)^C_FLAG; \ _A=l; \ X_ZNT(_A); \ } @@ -138,16 +138,16 @@ static uint8 ZNTable[256]; #define CMPL(a1,a2) { \ uint32 t=a1-a2; \ X_ZN(t&0xFF); \ - _P&=~C_FLAG; \ - _P|=((t>>8)&C_FLAG)^C_FLAG; \ + __P&=~C_FLAG; \ + __P|=((t>>8)&C_FLAG)^C_FLAG; \ } /* Special undocumented operation. Very similar to CMP. */ #define AXS { \ uint32 t=(_A&_X)-x; \ X_ZN(t&0xFF); \ - _P&=~C_FLAG; \ - _P|=((t>>8)&C_FLAG)^C_FLAG; \ + __P&=~C_FLAG; \ + __P|=((t>>8)&C_FLAG)^C_FLAG; \ _X=t; \ } @@ -159,26 +159,26 @@ static uint8 ZNTable[256]; #define DEC x--;X_ZN(x) #define INC x++;X_ZN(x) -#define ASL _P&=~C_FLAG;_P|=x>>7;x<<=1;X_ZN(x) -#define LSR _P&=~(C_FLAG|N_FLAG|Z_FLAG);_P|=x&1;x>>=1;X_ZNT(x) +#define ASL __P&=~C_FLAG;__P|=x>>7;x<<=1;X_ZN(x) +#define LSR __P&=~(C_FLAG|N_FLAG|Z_FLAG);__P|=x&1;x>>=1;X_ZNT(x) /* For undocumented instructions, maybe for other things later... */ -#define LSRA _P&=~(C_FLAG|N_FLAG|Z_FLAG);_P|=_A&1;_A>>=1;X_ZNT(_A) +#define LSRA __P&=~(C_FLAG|N_FLAG|Z_FLAG);__P|=_A&1;_A>>=1;X_ZNT(_A) #define ROL { \ uint8 l=x>>7; \ x<<=1; \ - x|=_P&C_FLAG; \ - _P&=~(Z_FLAG|N_FLAG|C_FLAG); \ - _P|=l; \ + x|=__P&C_FLAG; \ + __P&=~(Z_FLAG|N_FLAG|C_FLAG); \ + __P|=l; \ X_ZNT(x); \ } #define ROR { \ uint8 l=x&1; \ x>>=1; \ - x|=(_P&C_FLAG)<<7; \ - _P&=~(Z_FLAG|N_FLAG|C_FLAG); \ - _P|=l; \ + x|=(__P&C_FLAG)<<7; \ + __P&=~(Z_FLAG|N_FLAG|C_FLAG); \ + __P|=l; \ X_ZNT(x); \ } @@ -392,7 +392,7 @@ void X6502_Init(void) void X6502_Power(void) { - _count=_tcount=_IRQlow=_PC=_A=_X=_Y=_S=_P=_PI=_DB=_jammed=0; + _count=_tcount=_IRQlow=_PC=_A=_X=_Y=__S=__P=_PI=_DB=_jammed=0; timestamp=0; X6502_Reset(); } @@ -419,7 +419,7 @@ void X6502_Run(int32 cycles) _PC=RdMem(0xFFFC); _PC|=RdMem(0xFFFD)<<8; _jammed=0; - _PI=_P=I_FLAG; + _PI=__P=I_FLAG; _IRQlow&=~FCEU_IQRESET; } else if(_IRQlow&FCEU_IQNMI2) @@ -434,8 +434,8 @@ void X6502_Run(int32 cycles) ADDCYC(7); PUSH(_PC>>8); PUSH(_PC); - PUSH((_P&~B_FLAG)|(U_FLAG)); - _P|=I_FLAG; + PUSH((__P&~B_FLAG)|(U_FLAG)); + __P|=I_FLAG; DEBUG( if(debug_loggingCD) LogCDVectors(1) ); _PC=RdMem(0xFFFA); _PC|=RdMem(0xFFFB)<<8; @@ -449,8 +449,8 @@ void X6502_Run(int32 cycles) ADDCYC(7); PUSH(_PC>>8); PUSH(_PC); - PUSH((_P&~B_FLAG)|(U_FLAG)); - _P|=I_FLAG; + PUSH((__P&~B_FLAG)|(U_FLAG)); + __P|=I_FLAG; DEBUG( if(debug_loggingCD) LogCDVectors(1) ); _PC=RdMem(0xFFFE); _PC|=RdMem(0xFFFF)<<8; @@ -459,7 +459,7 @@ void X6502_Run(int32 cycles) _IRQlow&=~(FCEU_IQTEMP); if(_count<=0) { - _PI=_P; + _PI=__P; return; } //Should increase accuracy without a //major speed hit. @@ -468,7 +468,7 @@ void X6502_Run(int32 cycles) //will probably cause a major speed decrease on low-end systems DEBUG( DebugCycle() ); - _PI=_P; + _PI=__P; b1=RdMem(_PC); ADDCYC(CycTable[b1]); diff --git a/src/x6502.h b/src/x6502.h index 085a6a1f..4db9135c 100644 --- a/src/x6502.h +++ b/src/x6502.h @@ -27,8 +27,8 @@ extern X6502 X; #define _A X.A #define _X X.X #define _Y X.Y -#define _S X.S -#define _P X.P +#define __S X.S +#define __P X.P #define _PI X.mooPI #define _DB X.DB #define _count X.count diff --git a/vc8/fceux.vcproj b/vc8/fceux.vcproj index e9de10c6..22745866 100644 --- a/vc8/fceux.vcproj +++ b/vc8/fceux.vcproj @@ -358,6 +358,14 @@ + + + + + + + @@ -2184,6 +2200,10 @@ RelativePath="..\src\utils\unzip.h" > + +