From c4fee427ee5e9d8602a465e73b3b42d76e0e5544 Mon Sep 17 00:00:00 2001 From: grinvader <> Date: Sat, 19 Feb 2005 22:11:38 +0000 Subject: [PATCH] After a hefty load of hours without eating, movie replay/record is now ported to C, movies/states compatibility is finally restored, uic.c now has a real port of zstart, and video modes have now more room. Now gimme a kitten. --- zsnes/src/Makefile.in | 8 +- zsnes/src/SConstruct | 3 +- zsnes/src/cpu/execute.asm | 46 +- zsnes/src/gui/gui.asm | 200 +++---- zsnes/src/gui/guimisc.inc | 139 +---- zsnes/src/gui/guimouse.inc | 36 +- zsnes/src/gui/guinetpl.inc | 25 +- zsnes/src/gui/guiwindp.inc | 35 +- zsnes/src/init.asm | 254 +-------- zsnes/src/linux/sdlintrf.asm | 38 +- zsnes/src/macros.mac | 2 +- zsnes/src/makefile.ms | 8 +- zsnes/src/uic.c | 117 ++-- zsnes/src/win/winintrf.asm | 66 +-- zsnes/src/zmovie.c | 448 +++++++++++++++ zsnes/src/zstate.c | 1020 ++++++++++++++++++++++++++++++++++ 16 files changed, 1787 insertions(+), 658 deletions(-) create mode 100644 zsnes/src/zmovie.c create mode 100755 zsnes/src/zstate.c diff --git a/zsnes/src/Makefile.in b/zsnes/src/Makefile.in index ae0798bc..813b231a 100644 --- a/zsnes/src/Makefile.in +++ b/zsnes/src/Makefile.in @@ -39,7 +39,7 @@ CHIPSOBJ=${CHIPDIR}/sfxproc.o ${CHIPDIR}/fxemu2.o ${CHIPDIR}/dsp1proc.o\ CPUOBJ=${CPUDIR}/addrni.o ${CPUDIR}/dma.o ${CPUDIR}/dsp.o ${CPUDIR}/dspproc.o\ ${CPUDIR}/execute.o ${CPUDIR}/irq.o ${CPUDIR}/memory.o\ ${CPUDIR}/spc700.o ${CPUDIR}/stable.o ${CPUDIR}/table.o\ - ${CPUDIR}/tableb.o ${CPUDIR}/tablec.o ${CPUDIR}/zstate.o + ${CPUDIR}/tableb.o ${CPUDIR}/tablec.o GUIOBJ=${GUIDIR}/gui.o ${GUIDIR}/menu.o @@ -72,7 +72,8 @@ ZIPOBJ=${ZIPDIR}/unzip.o ${ZIPDIR}/zpng.o EFFECTSOBJ=${EFFECTSDIR}/burn.o ${EFFECTSDIR}/water.o ${EFFECTSDIR}/smoke.o -MAINOBJ=cfgload.o endmem.o init.o initc.o uic.o patch.o ui.o vcache.o version.o +MAINOBJ=cfgload.o endmem.o init.o initc.o uic.o patch.o ui.o vcache.o version.o\ + zmovie.o zstate.o OBJS=${CHIPSOBJ} ${CPUOBJ} ${WINOBJ} ${WINDOSOBJ} ${GUIOBJ} ${VIDEOBJ} ${MAINOBJ} ${NETOBJ} ${ZIPOBJ} ${EFFECTSOBJ} ${JMAOBJ} @@ -120,6 +121,8 @@ init.o:init.asm macros.mac initc.o:initc.c ${JMADIR}/zsnesjma.h uic.o:uic.c patch.o:patch.c +zmovie.o:zmovie.c +zstate.o:zstate.c ALL: rm -f version.o @@ -127,7 +130,6 @@ version.o:version.c ${DOSDIR}/debug.o: ${DOSDIR}/debug.asm macros.mac ${CPUDIR}/execute.o: ${CPUDIR}/execute.asm macros.mac -${CPUDIR}/zstate.o: ${CPUDIR}/zstate.c ${CPUDIR}/table.o: ${CPUDIR}/table.asm ${CPUDIR}/65816d.inc\ ${CPUDIR}/address.inc ${CPUDIR}/addrni.inc ${CPUDIR}/e65816.inc\ ${CPUDIR}/regs.mac ${CPUDIR}/regs.inc ${CPUDIR}/regsw.mac\ diff --git a/zsnes/src/SConstruct b/zsnes/src/SConstruct index 8a084845..170b6ed1 100644 --- a/zsnes/src/SConstruct +++ b/zsnes/src/SConstruct @@ -31,7 +31,6 @@ source_files = Split(""" cpu/table.asm cpu/tableb.asm cpu/tablec.asm - cpu/zstate.c dos/debug.asm dos/joy.asm dos/modemrtn.asm @@ -91,6 +90,8 @@ source_files = Split(""" ui.asm vcache.asm version.c + zmovie.c + zstate.c """) linux_source_files = Split(""" diff --git a/zsnes/src/cpu/execute.asm b/zsnes/src/cpu/execute.asm index f790bd68..c0763b0d 100644 --- a/zsnes/src/cpu/execute.asm +++ b/zsnes/src/cpu/execute.asm @@ -20,17 +20,13 @@ %include "macros.mac" -EXTSYM StringLength -EXTSYM Get_Time -EXTSYM objhipr -EXTSYM KeyRewind, statesaver +EXTSYM StringLength,Get_Time,objhipr,KeyRewind,statesaver EXTSYM xa,timer2upd,prevoamptr,ReadHead EXTSYM prevedi,SA1xpc,SA1RAMArea,sa1dmaptr EXTSYM DSP1COp,C4WFXVal,C41FXVal,Op00Multiplicand,Op10Coefficient,Op04Angle EXTSYM Op08X,Op18X,Op28X,Op0CA,Op02FX,Op0AVS,Op06X,Op0DX,Op03F,Op14Zr EXTSYM Op0EH,DSP1Type,Op01m -EXTSYM Voice0Status -EXTSYM UpdateDPage +EXTSYM Voice0Status,UpdateDPage EXTSYM MessageOn,MsgCount,Msgptr,StartGUI,cbitmode,debuggeron,romdata EXTSYM frameskip,initvideo,newgfx16b,soundon,cvidmode EXTSYM vidbuffer,vidbufferofsa,vidbufferofsb,disable65816sh,GUISaveVars,virqnodisable @@ -41,16 +37,13 @@ EXTSYM IRQHack,HIRQLoc,Offby1line,splitflags,joinflags,KeyQuickSnapShot EXTSYM csounddisable,videotroub,Open_File,Close_File,Read_File,ResetTripleBuf EXTSYM Write_File,Output_Text,Create_File,Check_Key,Get_Key,Change_Dir,InitPreGame ; EXTSYM tempblah,romdata -EXTSYM Curtableaddr -EXTSYM curcyc,debugdisble,dmadata,guioff,memtabler8,SetupPreGame +EXTSYM Curtableaddr,curcyc,debugdisble,dmadata,guioff,memtabler8,SetupPreGame EXTSYM memtablew8,regaccessbankr8,showmenu,snesmap2,snesmmap,DeInitPostGame EXTSYM spcPCRam,startdebugger,xp,xpb,xpc,tablead,tableadb,tableadc ; EXTSYM oamram EXTSYM SA1UpdateDPage,Makemode7Table EXTSYM memtabler16,memaccessbankr848mb,memaccessbankr1648mb -EXTSYM nextmenupopup -EXTSYM MovieProcessing -EXTSYM MovieFileHand, PrintStr +EXTSYM nextmenupopup,MovieProcessing,PrintStr EXTSYM OSExit,DosExit,InitDir,InitDrive,createnewcfg,fnames,gotoroot,previdmode EXTSYM ramsize,sfxramdata,setaramdata,SETAEnable,sram,SRAMChdir ; EXTSYM tempstore @@ -63,10 +56,8 @@ EXTSYM deinitvideo EXTSYM BRRBuffer,DSPMem,PrepareSaveState,ResetState,SFXEnable,PHdspsave EXTSYM fnamest,sndrot,spcRam,spcRamDP,tableA,vram,wramdata EXTSYM PHnum2writesfxreg,SfxR0,PHspcsave -EXTSYM C4Ram -EXTSYM SPC7110Enable +EXTSYM C4Ram,SPC7110Enable,SDD1Enable EXTSYM SA1Mode,PHnum2writesa1reg,SaveSA1,RestoreSA1,UpdateBanksSDD1 -EXTSYM SDD1Enable EXTSYM CapturePicture,PrevPicture,NoPictureSave EXTSYM BRRPlace0,SfxCPB,SfxCROM,SfxLastRamAdr,SfxMemTable EXTSYM SfxRAMBR,SfxRAMMem,SfxROMBR,SfxRomBuffer,Voice0Freq @@ -99,16 +90,13 @@ EXTSYM RemoteSendChar,RemoteGetChar,pl1neten,pl2neten,pl3neten,pl4neten EXTSYM pl5neten,RemoteSendEAX,prevp1net,prevp2net,prevp3net,prevp4net EXTSYM RemoteGetEAX,cnetplaybuf,netdelayed,cnetptrtail,cnetptrhead EXTSYM ChatProgress,RecvProgress,chatTL,WritetochatBuffer,NetAddChar -EXTSYM PreparePacket, SendPacket, NoInputRead, RemoteDisconnect -EXTSYM SendPacketUDP -EXTSYM ChatNick +EXTSYM PreparePacket,SendPacket,NoInputRead,RemoteDisconnect +EXTSYM SendPacketUDP,ChatNick EXTSYM JoyRead,ChatType2,chatstrR2,chatstrR3,chatstrR4,chatstrR5 EXTSYM chatRTL2,chatRTL3,chatRTL4,chatRTL5 -EXTSYM NetLoadState -EXTSYM ProcessMovies +EXTSYM NetLoadState,ProcessMovies,MovieStop EXTSYM ioportval,ppustatus -EXTSYM C4VBlank -EXTSYM dsp1teststuff +EXTSYM C4VBlank,dsp1teststuff EXTSYM ReturnFromSPCStall,SPCStallSetting,cycpb268,cycpb358,HIRQSkip,scanlines EXTSYM smallscreenon,ScreenScale EXTSYM MainLoop,NumberOfOpcodes,SfxCLSR,SfxSCMR,SfxPOR @@ -119,8 +107,7 @@ EXTSYM fxbit01,fxbit01pcal,fxbit23,fxbit23pcal,fxbit45,fxbit45pcal,fxbit67,fxbit EXTSYM SfxSFR,nosprincr EXTSYM cpucycle,debstop,switchtovirqdeb,debstop3,switchtonmideb EXTSYM NetPlayNoMore -EXTSYM statefileloc -EXTSYM CHIPBATT,SaveSramData,BackupCVFrame,RestoreCVFrame,loadstate +EXTSYM statefileloc,CHIPBATT,SaveSramData,BackupCVFrame,RestoreCVFrame,loadstate %ifdef __MSDOS__ EXTSYM dssel @@ -976,8 +963,6 @@ reexecuteb2: NEWSYM endprog call deinitvideo - cmp byte[previdmode],3 - ; mov eax,[opcd] ; mov eax,[numinst] ;Temporary ; mov eax,[NumBRRconv] @@ -987,12 +972,9 @@ NEWSYM endprog call createnewcfg call GUISaveVars - cmp byte[MovieProcessing],0 - je .nomovieclose - mov bx,[MovieFileHand] - mov byte[MovieProcessing],0 - call Close_File -.nomovieclose + pushad + call MovieStop + popad ; change dir to InitDrive/InitDir mov dl,[InitDrive] @@ -2730,7 +2712,9 @@ NEWSYM cpuover cmp byte[MovieProcessing],0 je .noprocmovie + pushad call ProcessMovies + popad .noprocmovie test byte[INTEnab],1 diff --git a/zsnes/src/gui/gui.asm b/zsnes/src/gui/gui.asm index 3acaf744..0b06b4fc 100644 --- a/zsnes/src/gui/gui.asm +++ b/zsnes/src/gui/gui.asm @@ -167,6 +167,7 @@ EXTSYM GUIHQ3X EXTSYM GUIHQ4X EXTSYM firstsaveinc EXTSYM nssdip1,nssdip2,nssdip3,nssdip4,nssdip5,nssdip6 +EXTSYM SkipMovie,MovieStop,MoviePlay,MovieRecord %ifdef __LINUX__ EXTSYM numlockptr @@ -719,7 +720,7 @@ vbuflimbot resd 1 GUIScrolTim1 resd 1 GUIScrolTim2 resd 1 GUICHold resd 1 -GUICBHold resd 1 +NEWSYM GUICBHold, resd 1 GUICBHold2 resd 1 GUIDClickTL resd 1 GUIDClCWin resd 1 @@ -2346,6 +2347,9 @@ NEWSYM StartGUI mov dword[PBackupPos],0 call RestoreCVFrame popad + mov esi,[tempesi] + mov edi,[tempedi] + mov ebp,[tempebp] .norestoreval mov dword[nmiprevaddrl],0 @@ -3061,103 +3065,103 @@ ManualStatus resb 1 NEWSYM MovieCounter, resd 1 SECTION .data -UnableMovie2 db 'MUST PLAY WITH SOUND OFF',0 -UnableMovie3 db 'MUST PLAY WITH SOUND ON',0 - -SECTION .text - -MoviePlay: - cmp byte[CNetType],20 - je near .dontplay - mov byte[GUICBHold],0 - mov dword[MovieCounter],0 - cmp byte[MovieProcessing],0 - jne near .dontplay - mov byte[GUIQuit],2 - mov ebx,[statefileloc] - mov eax,[fnamest+ebx-3] - push eax - mov dword[fnamest+ebx-3],'.zmv' - mov al,[CMovieExt] - mov byte[fnamest+ebx],al - pushad - call SRAMChdir - popad - mov dword[Totalbyteloaded],0 - pushad - call loadstate2 - popad - mov edx,fnamest+1 - call Open_File - jc near .notexist - mov bx,ax - mov [MovieFileHand],bx - mov cx,[Totalbyteloaded+2] - mov dx,[Totalbyteloaded] - call File_Seek - mov edx,RecData - mov ecx,16 - call Read_File - cmp byte[RecData+2],1 - jne .noextra - mov eax,[RecData+3] - mov [timer2upd],eax - mov eax,[RecData+7] - mov [curexecstate],eax - mov dword[nmiprevaddrl],0 - mov dword[nmiprevaddrh],0 - mov dword[nmirept],0 - mov dword[nmiprevline],224 - mov dword[nmistatus],0 - mov dword[spcnumread],0 - mov dword[spchalted],-1 - mov byte[NextLineCache],0 -.noextra - mov al,[RecData] - cmp al,[soundon] - jne near .soundisoff - cmp dword[ramsize],0 - je .noram - mov edx,[sram] - mov ecx,[ramsize] - call Read_File -.noram - mov byte[MovieProcessing],1 -.skip - mov dword[PJoyAOrig],0 - mov dword[PJoyBOrig],0 - mov dword[PJoyCOrig],0 - mov dword[PJoyDOrig],0 - mov dword[PJoyEOrig],0 - mov byte[sramsavedis],1 - mov byte[UseRemoteSRAMData],0 - mov byte[DSPMem+08h],0 - mov byte[DSPMem+18h],0 - mov byte[DSPMem+28h],0 - mov byte[DSPMem+38h],0 - mov byte[DSPMem+48h],0 - mov byte[DSPMem+58h],0 - mov byte[DSPMem+68h],0 - mov byte[DSPMem+78h],0 -.notexist - call ChangetoLOADdir - pop eax - mov ebx,[statefileloc] - mov [fnamest+ebx-3],eax -.dontplay - ret -.soundisoff - mov dword[Msgptr],UnableMovie2 - cmp byte[soundon],0 - jne .soundon - mov dword[Msgptr],UnableMovie3 -.soundon - mov eax,[MsgCount] - mov [MessageOn],eax - call Close_File - pop eax - ret +NEWSYM UnableMovie2, db 'MUST PLAY WITH SOUND OFF',0 +NEWSYM UnableMovie3, db 'MUST PLAY WITH SOUND ON',0 +;SECTION .text +; +;MoviePlay: +; cmp byte[CNetType],20 +; je near .dontplay +; mov byte[GUICBHold],0 +; mov dword[MovieCounter],0 +; cmp byte[MovieProcessing],0 +; jne near .dontplay +; mov byte[GUIQuit],2 +; mov ebx,[statefileloc] +; mov eax,[fnamest+ebx-3] +; push eax +; mov dword[fnamest+ebx-3],'.zmv' +; mov al,[CMovieExt] +; mov byte[fnamest+ebx],al +; pushad +; call SRAMChdir +; popad +; mov dword[Totalbyteloaded],0 +; pushad +; call loadstate2 +; popad +; mov edx,fnamest+1 +; call Open_File +; jc near .notexist +; mov bx,ax +; mov [MovieFileHand],bx +; mov cx,[Totalbyteloaded+2] +; mov dx,[Totalbyteloaded] +; call File_Seek +; mov edx,RecData +; mov ecx,16 +; call Read_File +; cmp byte[RecData+2],1 +; jne .noextra +; mov eax,[RecData+3] +; mov [timer2upd],eax +; mov eax,[RecData+7] +; mov [curexecstate],eax +; mov dword[nmiprevaddrl],0 +; mov dword[nmiprevaddrh],0 +; mov dword[nmirept],0 +; mov dword[nmiprevline],224 +; mov dword[nmistatus],0 +; mov dword[spcnumread],0 +; mov dword[spchalted],-1 +; mov byte[NextLineCache],0 +;.noextra +; mov al,[RecData] +; cmp al,[soundon] +; jne near .soundisoff +; cmp dword[ramsize],0 +; je .noram +; mov edx,[sram] +; mov ecx,[ramsize] +; call Read_File +;.noram +; mov byte[MovieProcessing],1 +;.skip +; mov dword[PJoyAOrig],0 +; mov dword[PJoyBOrig],0 +; mov dword[PJoyCOrig],0 +; mov dword[PJoyDOrig],0 +; mov dword[PJoyEOrig],0 +; mov byte[sramsavedis],1 +; mov byte[UseRemoteSRAMData],0 +; mov byte[DSPMem+08h],0 +; mov byte[DSPMem+18h],0 +; mov byte[DSPMem+28h],0 +; mov byte[DSPMem+38h],0 +; mov byte[DSPMem+48h],0 +; mov byte[DSPMem+58h],0 +; mov byte[DSPMem+68h],0 +; mov byte[DSPMem+78h],0 +;.notexist +; call ChangetoLOADdir +; pop eax +; mov ebx,[statefileloc] +; mov [fnamest+ebx-3],eax +;.dontplay +; ret +;.soundisoff +; mov dword[Msgptr],UnableMovie2 +; cmp byte[soundon],0 +; jne .soundon +; mov dword[Msgptr],UnableMovie3 +;.soundon +; mov eax,[MsgCount] +; mov [MessageOn],eax +; call Close_File +; pop eax +; ret +; SECTION .bss NEWSYM Totalbyteloaded, resd 1 NEWSYM sramsavedis, resb 1 @@ -3605,7 +3609,7 @@ DisplayBoxes: .nomore ret -ChangetoLOADdir: +NEWSYM ChangetoLOADdir mov dl,[LoadDrive] mov ebx,LoadDir call Change_Dir diff --git a/zsnes/src/gui/guimisc.inc b/zsnes/src/gui/guimisc.inc index 7fc39457..4623a3dd 100644 --- a/zsnes/src/gui/guimisc.inc +++ b/zsnes/src/gui/guimisc.inc @@ -22,145 +22,15 @@ ; Movie, Joystick setting (display) routines, SNES Reset Function -MovieRecord: - mov byte[GUICBHold],0 - cmp byte[MovieProcessing],0 - jne near .dontrecord - ;jne .noreset - mov dword[MovieCounter],0 -.noreset - ; check if movie exists already - mov ebx,[statefileloc] - mov eax,[fnamest+ebx-3] - push eax - mov dword[fnamest+ebx-3],'.zmv' - mov al,[CMovieExt] - mov byte[fnamest+ebx],al - - ; check if file exists - cmp byte[MovieRecordWinVal],1 - je .nocheck - mov edx,fnamest+1 - call Open_File - jc .nocheck - mov bx,ax - call Close_File - mov byte[MovieRecordWinVal],1 - jmp .skipstate -.nocheck - cmp byte[MovieProcessing],0 - jne near .nocheckit - mov dword[CFWriteHead],0 - mov dword[CReadHead],0 - mov dword[ReadHead],0 - mov dword[CFWriteStart],64 -.nocheckit - mov byte[MovieRecordWinVal],0 - pushad - call SRAMChdir - popad - mov byte[NoPictureSave],1 - cmp byte[MovieProcessing],0 - jne .nostatesaver - pushad - call statesaver - popad -.nostatesaver - mov byte[NoPictureSave],0 - mov edx,fnamest+1 - call Open_File_Write - mov bx,ax - mov [MovieFileHand],bx - mov cx,0 - mov dx,0 - call File_Seek_End - cmp byte[MovieProcessing],0 - je .noappend - mov byte[MovieProcessing],2 - jmp .netstuff -.noappend - mov al,[soundon] - mov [RecData],al - mov eax,[versionNumber] - mov [RecData+1],eax - mov byte[RecData+2],1 - mov eax,[timer2upd] - mov [RecData+3],eax - mov eax,[curexecstate] - mov [RecData+7],eax - mov edx,RecData - mov ecx,16 - call Write_File - cmp dword[ramsize],0 - je .noram - mov edx,[sram] - mov ecx,[ramsize] - call Write_File -.noram - mov byte[MovieProcessing],2 - mov dword[MovieBuffSize],0 - mov dword[MovieBuffFrame],0 - mov byte[RepeatFrame],0 - cmp byte[CNetType],20 - je near .netstuff - cmp byte[CNetType],21 - je near .netstuff - mov dword[nmiprevaddrl],0 - mov dword[nmiprevaddrh],0 - mov dword[nmirept],0 - mov dword[nmiprevline],224 - mov dword[nmistatus],0 - mov dword[spcnumread],0 - mov dword[spchalted],-1 - mov byte[NextLineCache],0 - mov dword[PJoyAOrig],0 - mov dword[PJoyBOrig],0 - mov dword[PJoyCOrig],0 - mov dword[PJoyDOrig],0 - mov dword[PJoyEOrig],0 - mov byte[DSPMem+08h],0 - mov byte[DSPMem+18h],0 - mov byte[DSPMem+28h],0 - mov byte[DSPMem+38h],0 - mov byte[DSPMem+48h],0 - mov byte[DSPMem+58h],0 - mov byte[DSPMem+68h],0 - mov byte[DSPMem+78h],0 -.netstuff - mov byte[MovieProcessing],2 - call ChangetoLOADdir -.skipstate - pop eax - mov ebx,[statefileloc] - mov [fnamest+ebx-3],eax -.dontrecord - ret - SECTION .bss -MovieRecordWinVal resb 1 +NEWSYM MovieRecordWinVal, resb 1 NEWSYM MovieProcessing, resb 1 NEWSYM MovieFileHand, resw 1 -NEWSYM RepeatFrame, resb 1 NEWSYM RecData, resb 16 NEWSYM NoPictureSave, resb 1 SECTION .text -SkipMovie: - mov byte[MovieRecordWinVal],0 - mov byte[GUICBHold],0 - ret - -MovieStop: - mov byte[GUICBHold],0 - cmp byte[MovieProcessing],0 - je .skipfileend - mov bx,[MovieFileHand] - mov byte[MovieProcessing],0 - call Close_File -.skipfileend - ret - CalibrateDispA: xor ebx,ebx mov ecx,256 @@ -495,13 +365,8 @@ NEWSYM GUIDoReset ; mov byte[NetPlayNoMore],1 mov byte[RestoreValues],0 - cmp byte[MovieProcessing],0 - je .skipfileend - mov bx,[MovieFileHand] - mov byte[MovieProcessing],0 - call Close_File -.skipfileend pushad + call MovieStop call RestoreSystemVars popad diff --git a/zsnes/src/gui/guimouse.inc b/zsnes/src/gui/guimouse.inc index e2dbdca7..c5e92fa4 100644 --- a/zsnes/src/gui/guimouse.inc +++ b/zsnes/src/gui/guimouse.inc @@ -567,15 +567,41 @@ ProcessMouseButtons: cmp byte[GUICBHold],15 je near CalibrateDev1 cmp byte[GUICBHold],16 - je near MoviePlay + jne .notMoviePlay + pushad + call MoviePlay + popad + ret +.notMoviePlay cmp byte[GUICBHold],17 - je near MovieRecord + jne .notMovieRecord0 + pushad + call MovieRecord + popad + ret +.notMovieRecord0 cmp byte[GUICBHold],18 - je near MovieStop + jne .notMovieStop + mov byte[GUICBHold],0 + pushad + call MovieStop + popad + ret +.notMovieStop cmp byte[GUICBHold],19 - je near MovieRecord + jne .notMovieRecord1 + pushad + call MovieRecord + popad + ret +.notMovieRecord1 cmp byte[GUICBHold],20 - je near SkipMovie + jne .notSkipMovie + pushad + call SkipMovie + popad + ret +.notSkipMovie cmp byte[GUICBHold],40 je near SetAllKeys cmp byte[GUICBHold],50 diff --git a/zsnes/src/gui/guinetpl.inc b/zsnes/src/gui/guinetpl.inc index 49abb68a..4d4e1bb2 100644 --- a/zsnes/src/gui/guinetpl.inc +++ b/zsnes/src/gui/guinetpl.inc @@ -530,15 +530,14 @@ SECTION .text call RemoteSendChar mov al,222 call RemoteSendChar - ; Dan - Change this from looking into the welcome message forthe version. - mov al,[versionNumber + 0] - call RemoteSendChar - mov al,[versionNumber + 1] - call RemoteSendChar - mov al,[versionNumber + 2] - call RemoteSendChar - mov al,[versionNumber + 3] - call RemoteSendChar + mov al,[versionNumber] + call RemoteSendChar + mov al,[versionNumber+1] + call RemoteSendChar + mov al,[versionNumber+2] + call RemoteSendChar + mov al,[versionNumber+3] + call RemoteSendChar mov al,[soundon] call RemoteSendChar cmp al,byte[CNetType] @@ -581,28 +580,28 @@ SECTION .text .nocheck3 cmp byte[IDCheckPos],3 jne .nocheck4 - cmp dl,[versionNumber + 0] + cmp dl,[versionNumber] jne near .invversion mov byte[IDCheckPos],4 ret .nocheck4 cmp byte[IDCheckPos],4 jne .nocheck5 - cmp dl,[versionNumber + 1] + cmp dl,[versionNumber+1] jne near .invversion mov byte[IDCheckPos],5 ret .nocheck5 cmp byte[IDCheckPos],5 jne .nocheck6 - cmp dl,[versionNumber + 2] + cmp dl,[versionNumber+2] jne .invversion mov byte[IDCheckPos],6 ret .nocheck6 cmp byte[IDCheckPos],6 jne .nocheck7 - cmp dl,[versionNumber + 3] + cmp dl,[versionNumber+3] jne .invversion mov byte[IDCheckPos],9 ret diff --git a/zsnes/src/gui/guiwindp.inc b/zsnes/src/gui/guiwindp.inc index ba76d0eb..1e02a9cd 100644 --- a/zsnes/src/gui/guiwindp.inc +++ b/zsnes/src/gui/guiwindp.inc @@ -1921,13 +1921,13 @@ DisplayGUIVideo: sub byte[GUItextcolor],15 %ifndef __MSDOS__ - GUIOuttextwin2 5,12,76,GUIVideoTextw0 - GUIOuttextwin2 5,12,83,GUIVideoTextw1 - GUIOuttextwin2 5,12,90,GUIVideoTextw2 - GUIOuttextwin2 5,12,97,GUIVideoTextw3 + GUIOuttextwin2 5,8,76,GUIVideoTextw0 + GUIOuttextwin2 5,10,85,GUIVideoTextw1 + GUIOuttextwin2 5,10,92,GUIVideoTextw2 + GUIOuttextwin2 5,10,99,GUIVideoTextw3 %endif %ifdef __LINUX__ - GUIOuttextwin2 5,12,104,GUIVideoTextw4 + GUIOuttextwin2 5,10,106,GUIVideoTextw4 %endif xor eax,eax mov al,[cvidmode] @@ -2057,13 +2057,13 @@ DisplayGUIVideo: add byte[GUItextcolor],15 %ifndef __MSDOS__ - GUIOuttextwin2 5,11,75,GUIVideoTextw0 - GUIOuttextwin2 5,11,82,GUIVideoTextw1 - GUIOuttextwin2 5,11,89,GUIVideoTextw2 - GUIOuttextwin2 5,11,96,GUIVideoTextw3 + GUIOuttextwin2 5,7,75,GUIVideoTextw0 + GUIOuttextwin2 5,9,84,GUIVideoTextw1 + GUIOuttextwin2 5,9,91,GUIVideoTextw2 + GUIOuttextwin2 5,9,98,GUIVideoTextw3 %endif %ifdef __LINUX__ - GUIOuttextwin2 5,11,103,GUIVideoTextw4 + GUIOuttextwin2 5,9,105,GUIVideoTextw4 %endif xor eax,eax mov al,[cvidmode] @@ -2531,10 +2531,11 @@ GUIVideoText8 db 'SET',0 ; set button GUIVideoText9 db 'VSYNC',0 ; -c GUIVideoTextH db 'MODE : ',0 GUIVideoTextw0 db 'LEGEND:',0 -GUIVideoTextw1 db ' S = SCALED TO FIT SCREEN',0 -GUIVideoTextw2 db ' R = MATCHED SCREEN RATIO',0 -GUIVideoTextw3 db ' D = ALLOW 2XSAI,HIRES,ETC',0 -GUIVideoTextw4 db ' O = OPENGL MODE',0 +GUIVideoTextw1 db 'S = STRETCH R = KEEP RATIO',0 +GUIVideoTextw2 db ' D = ALLOW SPECIAL FILTERS',0 +GUIVideoTextw3 db ' W = WIN F = FULL',0 +GUIVideoTextw4 db ' O = USES OPENGL',0 + SECTION .bss GUIVStA resd 3 @@ -4825,7 +4826,7 @@ NEWSYM LatencyLeft, db 2 SECTION .bss NEWSYM NetSwap, resb 1 RemCNetType resb 1 -UseRemoteSRAMData resb 1 +NEWSYM UseRemoteSRAMData, resb 1 ChatString resb 276 FileNameMod resb 512 CurCStringPos resd 1 @@ -5648,7 +5649,7 @@ DisplayGUIAbout: ret SECTION .data -GUIGUIAboutText1 db 'ZSNES ',ZVERSION,' ',0 ;Need room for date +GUIGUIAboutText1 db 'ZSNES V',ZVERSION,' ',0 ;Need room for date GUIGUIAboutText2 db 'CODED BY : ',0 GUIGUIAboutText3 db ' ZSKNIGHT _DEMO_',0 GUIGUIAboutText4 db ' PAGEFAULT NACH',0 @@ -5793,7 +5794,7 @@ GUIMovieText7 db 'OKAY TO OVERWRITE?',0 GUIMovieText8 db 'YES',0 GUIMovieText9 db 'NO',0 GUIMovieTextA db 'STATUS : ',0 -CMovieExt db 'v' +NEWSYM CMovieExt, db 'v' SECTION .text diff --git a/zsnes/src/init.asm b/zsnes/src/init.asm index 54400c0f..218555d1 100644 --- a/zsnes/src/init.asm +++ b/zsnes/src/init.asm @@ -23,7 +23,7 @@ EXTSYM DosExit,UpdateDevices,InitSPC,Makemode7Table,MusicRelVol,MusicVol EXTSYM makesprprtable,romloadskip,start65816,startdebugger,SfxR0 EXTSYM MovieProcessing -EXTSYM MovieFileHand,filefound,inittable,SA1inittable +EXTSYM filefound,inittable,SA1inittable EXTSYM MessageOn,Msgptr,MsgCount,sndrot,GenerateBank0Table,SnowTimer EXTSYM inittableb,inittablec,newgfx16b,cfgreinittime EXTSYM Open_File,Read_File,Write_File,Close_File,Output_Text,Get_Key,CNetType @@ -36,7 +36,6 @@ EXTSYM NewEngEnForce EXTSYM PrintChar EXTSYM TextFile EXTSYM Setper2exec,per2exec -EXTSYM MovieCounter EXTSYM chaton EXTSYM JoyRead,JoyReadControl,joy4218,joy4219 EXTSYM joy421A,joy421B,pressed @@ -53,7 +52,7 @@ EXTSYM pl3Xtk,pl3Ytk,pl3Atk,pl3Btk,pl4Xtk,pl4Ytk,pl4Atk,pl4Btk EXTSYM pl1ULk,pl1URk,pl1DLk,pl1DRk,pl2ULk,pl2URk,pl2DLk,pl2DRk EXTSYM pl3ULk,pl3URk,pl3DLk,pl3DRk,pl4ULk,pl4URk,pl4DLk,pl4DRk EXTSYM pl5ULk,pl5URk,pl5DLk,pl5DRk,pl5Xtk,pl5Ytk,pl5Atk,pl5Btk -EXTSYM Turbo30hz,RepeatFrame,nojoystickpoll +EXTSYM Turbo30hz,nojoystickpoll EXTSYM NumComboLocl,ComboBlHeader,ComboHeader,CombinDataLocl EXTSYM CombinDataGlob,NumCombo,GUIComboGameSpec EXTSYM mousexloc,mouseyloc @@ -161,6 +160,8 @@ blah times 450 db 0 ; FIX STATMAT NEWSYM autoloadstate, db 0 ; auto load state slot number ; FIX STATMAT +NEWSYM EndMessage + db ' ',13,10,0 SECTION .text @@ -322,9 +323,6 @@ NEWSYM init mov byte[newengen],1 mov byte[cfgnewgfx],1 .noforce - ; Dan - I don't know what this is, but all it seems to do is update - ; EndMessage which I've nuked. -%if 0 mov ebx,ebm mov eax,EndMessage mov dh,17h @@ -346,7 +344,6 @@ NEWSYM init inc ebx dec ch jnz .loopen -%endif cmp byte[yesoutofmemory],1 jne .noout @@ -1045,254 +1042,13 @@ NEWSYM ReadInputDevice .nopl24 ret -NEWSYM ProcessMovies - cmp byte[MovieProcessing],2 - je near .record - -.repeater - pushad - mov bx,[MovieFileHand] - mov ecx,1 - mov edx,MovieTemp - call Read_File - cmp eax,0 - je near .endplay2 - cmp byte[MovieTemp],1 - ja near .endplay - cmp byte[MovieTemp],1 - je .nomovement - mov ecx,20 - mov edx,PJoyAOrig - call Read_File -.nomovement - popad - mov eax,[PJoyAOrig] - mov [JoyAOrig],eax - mov eax,[PJoyBOrig] - mov [JoyBOrig],eax - mov eax,[PJoyCOrig] - mov [JoyCOrig],eax - mov eax,[PJoyDOrig] - mov [JoyDOrig],eax - mov eax,[PJoyEOrig] - mov [JoyEOrig],eax - ret -.endplay2 - mov dword[Msgptr],.movieended - mov eax,[MsgCount] - mov [MessageOn],eax -.endplay - mov byte[MovieProcessing],0 - call Close_File - popad - ret -.record - cmp byte[BackState],1 - jne .nobackstate - cmp byte[CNetType],20 - jae near .storefullcrecv -.nobackstate - mov eax,[JoyAOrig] - cmp eax,[PJoyAOrig] - jne .storefull - mov eax,[JoyBOrig] - cmp eax,[PJoyBOrig] - jne .storefull - mov eax,[JoyCOrig] - cmp eax,[PJoyCOrig] - jne .storefull - mov eax,[JoyDOrig] - cmp eax,[PJoyDOrig] - jne .storefull - mov eax,[JoyEOrig] - cmp eax,[PJoyEOrig] - jne .storefull - mov byte[MovieTemp],1 - push ebx - mov ebx,[MovieBuffSize] - mov byte[MovieBuffer+ebx],1 - inc dword[MovieBuffSize] - pop ebx - inc dword[MovieBuffFrame] - cmp dword[MovieBuffFrame],60 - je near .writebuffertodisk - ret -.storefull - mov eax,[JoyAOrig] - mov [PJoyAOrig],eax - mov eax,[JoyBOrig] - mov [PJoyBOrig],eax - mov eax,[JoyCOrig] - mov [PJoyCOrig],eax - mov eax,[JoyDOrig] - mov [PJoyDOrig],eax - mov eax,[JoyEOrig] - mov [PJoyEOrig],eax - mov byte[MovieTemp],0 - push ebx - mov ebx,[MovieBuffSize] - mov byte[MovieBuffer+ebx],0 - mov eax,[JoyAOrig] - mov [MovieBuffer+ebx+1],eax - mov eax,[JoyBOrig] - mov [MovieBuffer+ebx+5],eax - mov eax,[JoyCOrig] - mov [MovieBuffer+ebx+9],eax - mov eax,[JoyDOrig] - mov [MovieBuffer+ebx+13],eax - mov eax,[JoyEOrig] - mov [MovieBuffer+ebx+17],eax - add dword[MovieBuffSize],21 - pop ebx - inc dword[MovieBuffFrame] - cmp dword[MovieBuffFrame],60 - je near .writebuffertodisk - ret -.writebuffertodisk - pushad - mov bx,[MovieFileHand] - mov ecx,[MovieBuffSize] - mov edx,MovieBuffer - call Write_File - popad - mov dword[MovieBuffSize],0 - mov dword[MovieBuffFrame],0 - ret - -.notstorefullcrecv - push ebx - mov eax,[ReadHead] - cmp [CReadHead],eax - jne .juststoredata - inc dword[CFWriteStart] - and dword[CFWriteStart],7Fh - mov eax,[CFWriteHead] - cmp eax,[CFWriteStart] - jne .nowrite - call .writetobuffer - inc dword[CFWriteHead] - and dword[CFWriteHead],7Fh -.nowrite - inc dword[CReadHead] - and dword[CReadHead],7Fh -.juststoredata - mov ebx,[ReadHead] - shl ebx,5 - mov byte[StoreBuffer+ebx],1 - inc dword[ReadHead] - and dword[ReadHead],7Fh - pop ebx - ret - -.storefullcrecv - push ebx - mov eax,[ReadHead] - cmp [CReadHead],eax - jne .juststoredata2 - inc dword[CFWriteStart] - and dword[CFWriteStart],7Fh - mov eax,[CFWriteHead] - cmp eax,[CFWriteStart] - jne .nowrite2 - call .writetobuffer - inc dword[CFWriteHead] - and dword[CFWriteHead],7Fh -.nowrite2 - inc dword[CReadHead] - and dword[CReadHead],7Fh -.juststoredata2 - mov ebx,[ReadHead] - shl ebx,5 - add ebx,StoreBuffer - mov byte[ebx],0 - mov eax,[JoyAOrig] - mov [ebx+1],eax - mov eax,[JoyBOrig] - mov [ebx+5],eax - mov eax,[JoyCOrig] - mov [ebx+9],eax - mov eax,[JoyDOrig] - mov [ebx+13],eax - mov eax,[JoyEOrig] - mov [ebx+17],eax - inc dword[ReadHead] - and dword[ReadHead],7Fh - pop ebx - ret - -.writetobuffer - push ecx - mov ecx,[CFWriteHead] - shl ecx,5 - add ecx,StoreBuffer -; cmp byte[ecx],1 -; je .nochange - mov eax,[ecx+1] - cmp [PJoyAOrig],eax - jne .change - mov eax,[ecx+5] - cmp [PJoyBOrig],eax - jne .change - mov eax,[ecx+9] - cmp [PJoyCOrig],eax - jne .change - mov eax,[ecx+13] - cmp [PJoyDOrig],eax - jne .change - mov eax,[ecx+17] - cmp [PJoyEOrig],eax - jne .change -.nochange - pop ecx - mov ebx,[MovieBuffSize] - mov byte[MovieBuffer+ebx],1 - inc dword[MovieBuffSize] - inc dword[MovieBuffFrame] - cmp dword[MovieBuffFrame],60 - je near .writebuffer - ret -.change - mov eax,[ecx+1] - mov [PJoyAOrig],eax - mov eax,[ecx+5] - mov [PJoyBOrig],eax - mov eax,[ecx+9] - mov [PJoyCOrig],eax - mov eax,[ecx+13] - mov [PJoyDOrig],eax - mov eax,[ecx+17] - mov [PJoyEOrig],eax - mov ebx,[MovieBuffSize] - mov byte[MovieBuffer+ebx],0 - mov eax,[ecx+1] - mov [MovieBuffer+ebx+1],eax - mov eax,[ecx+5] - mov [MovieBuffer+ebx+5],eax - mov eax,[ecx+9] - mov [MovieBuffer+ebx+9],eax - mov eax,[ecx+13] - mov [MovieBuffer+ebx+13],eax - mov eax,[ecx+17] - mov [MovieBuffer+ebx+17],eax - add dword[MovieBuffSize],21 - pop ecx - inc dword[MovieBuffFrame] - cmp dword[MovieBuffFrame],60 - je .writebuffer - ret -.writebuffer - call .writebuffertodisk - ret - SECTION .data - -.movieended db 'MOVIE FINISHED.',0 +NEWSYM txtmovieended, db 'MOVIE FINISHED.',0 NEWSYM CFWriteStart, dd 64+30 SECTION .bss NEWSYM MovieBuffSize, resd 1 NEWSYM MovieBuffFrame, resd 1 -MovieBuffer resd 21*60 NEWSYM CReadHead, resd 1 NEWSYM ReadHead, resd 1 NEWSYM CFWriteHead, resd 1 diff --git a/zsnes/src/linux/sdlintrf.asm b/zsnes/src/linux/sdlintrf.asm index 86889e7b..6eacdd75 100644 --- a/zsnes/src/linux/sdlintrf.asm +++ b/zsnes/src/linux/sdlintrf.asm @@ -901,26 +901,26 @@ NEWSYM NumVideoModes, dd 4 ; GUI Video Mode Names - Make sure that all names are of the same length ; and end with a NULL terminator NEWSYM GUIVideoModeNames -db '256X224 R WIN ',0 ;0 -db '256x224 R FULL',0 ;1 -db '512X448 DR WIN ',0 ;2 -db '640x480 DS FULL',0 ;3 +db '256X224 R W',0 ;0 +db '256x224 R F',0 ;1 +db '512X448 DR W',0 ;2 +db '640x480 DR F',0 ;3 %ifdef __OPENGL__ -db '256x224 OR WIN ',0 ;4 -db '512x448 ODR WIN ',0 ;5 -db '640x480 ODS FULL',0 ;6 -db '640x480 ODS WIN ',0 ;7 -db '640x576 ODR WIN ',0 ;8 -db '768x672 ODR WIN ',0 ;9 -db '800x600 ODS FULL',0 ;10 -db '800x600 ODS WIN ',0 ;11 -db '896x784 ODR WIN ',0 ;12 -db '1024x768 ODS FULL',0 ;13 -db '1024x768 ODS WIN ',0 ;14 -db '1024x896 ODR WIN ',0 ;15 -db '1280x1024ODS FULL',0 ;16 -db '1600x1200ODS FULL',0 ;17 -db 'VARIABLE ODR WIN ',0 ;18 +db '256x224 OR W',0 ;4 +db '512x448 ODR W',0 ;5 +db '640x480 ODS F',0 ;6 +db '640x480 ODS W',0 ;7 +db '640x576 ODR W',0 ;8 +db '768x672 ODR W',0 ;9 +db '800x600 ODS F',0 ;10 +db '800x600 ODS W',0 ;11 +db '896x784 ODR W',0 ;12 +db '1024x768 ODS F',0 ;13 +db '1024x768 ODS W',0 ;14 +db '1024x896 ODR W',0 ;15 +db '1280x1024 ODS F',0 ;16 +db '1600x1200 ODS F',0 ;17 +db 'VARIABLE ODR W',0 ;18 %endif diff --git a/zsnes/src/macros.mac b/zsnes/src/macros.mac index 757e19c6..ab9bbcc3 100644 --- a/zsnes/src/macros.mac +++ b/zsnes/src/macros.mac @@ -23,7 +23,7 @@ bits 32 section .text ; Zsnes required macros -%define ZVERSION 'Pre 1.43' ; Don't forget to put the 'v' here now +%define ZVERSION 'Pre 1.43' %ifdef ELF %imacro newsym 1 diff --git a/zsnes/src/makefile.ms b/zsnes/src/makefile.ms index 5eec8c72..5c60ada8 100644 --- a/zsnes/src/makefile.ms +++ b/zsnes/src/makefile.ms @@ -152,7 +152,7 @@ CHIPSOBJ=${CHIPDIR}/dsp1emu${OE} ${CHIPDIR}/fxemu2${OE} ${CHIPDIR}/sfxproc${OE}\ CPUOBJ=${CPUDIR}/dma${OE} ${CPUDIR}/dsp${OE} ${CPUDIR}/dspproc${OE}\ ${CPUDIR}/execute${OE} ${CPUDIR}/irq${OE} ${CPUDIR}/memory${OE}\ ${CPUDIR}/spc700${OE} ${CPUDIR}/stable${OE} ${CPUDIR}/table${OE}\ - ${CPUDIR}/tableb${OE} ${CPUDIR}/tablec${OE} ${CPUDIR}/zstate${OE} + ${CPUDIR}/tableb${OE} ${CPUDIR}/tablec${OE} GUIOBJ=${GUIDIR}/gui${OE} ${GUIDIR}/menu${OE} @@ -185,7 +185,8 @@ JMAOBJ=${JMADIR}/7zlzma${OE} ${JMADIR}/crc32${OE} ${JMADIR}/iiostrm${OE}\ ${JMADIR}/inbyte${OE} ${JMADIR}/jma${OE} ${JMADIR}/lzma${OE} ${JMADIR}/lzmadec${OE}\ ${JMADIR}/winout${OE} ${JMADIR}/zsnesjma${OE} -MAINOBJ=cfgload${OE} endmem${OE} init${OE} initc${OE} uic${OE} patch${OE} ui${OE} vcache${OE} version${OE} +MAINOBJ=cfgload${OE} endmem${OE} init${OE} initc${OE} uic${OE} patch${OE}\ + ui${OE} vcache${OE} version${OE} zmovie${OE} zstate${OE} DOSOBJORIG=${DOSDIR}/debug${OE} ${DOSDIR}/joy${OE} ${DOSDIR}/modemrtn${OE} ${DOSDIR}/vesa2${OE}\ ${DOSDIR}/initvid${OE} ${DOSDIR}/sw${OE} ${DOSDIR}/gppro${OE} ${DOSDIR}/vesa12${OE}\ @@ -252,9 +253,10 @@ initc${OE}: $< ${JMADIR}/zsnesjma.h uic${OE}: $< patch${OE}: $< endmem${OE}: $< macros.mac +zmovie${OE}: $< gblvars.h +zstate${OE}: $< gblvars.h ${CPUDIR}/execute${OE}: $< macros.mac -${CPUDIR}/zstate${OE}: $< gblvars.h ${CPUDIR}/table${OE}: $< ${CPUDIR}/65816d.inc ${CPUDIR}/address.inc ${CPUDIR}/addrni.inc ${CPUDIR}/e65816.inc\ ${CPUDIR}/regs.mac ${CPUDIR}/regs.inc ${CPUDIR}/regsw.mac ${CPUDIR}/regsw.inc macros.mac ${CPUDIR}/tableb${OE}: $< ${CPUDIR}/65816db.inc ${CPUDIR}/address.inc ${CPUDIR}/addrni.inc ${CPUDIR}/e65816b.inc\ diff --git a/zsnes/src/uic.c b/zsnes/src/uic.c index 48c72b98..25fe0ad9 100644 --- a/zsnes/src/uic.c +++ b/zsnes/src/uic.c @@ -35,14 +35,11 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #define true 1 #define false 0 -extern void outofmemory(); - extern unsigned char *vbufaptr; extern unsigned char *vbufeptr; extern unsigned char *ngwinptrb; extern unsigned char *vbufdptr; extern unsigned char *romaptr; -extern unsigned char welcome[452+16]; // 452=message string, 16=version string extern unsigned char mydebug[2]; extern unsigned char outofmem[51]; extern unsigned char YesMMX[34]; @@ -147,7 +144,7 @@ void *doMemAlloc(size_t size) { void *ptr = NULL; ptr = malloc(size); - if (!ptr) { outofmemory(); } + if (!ptr) { asm_call(outofmemory); } return(ptr); } @@ -175,22 +172,22 @@ void cycleinputdevice() if (snesmouse == 0) { if (input1gp && input2gp) { return; } - snesmouse++; + snesmouse++; } if (snesmouse == 1) { if (input1mouse) { return; } - snesmouse++; + snesmouse++; } if (snesmouse == 2) { if (input2mouse) { return; } - snesmouse++; + snesmouse++; } if (snesmouse == 3) { if (input2scope) { return; } - snesmouse++; + snesmouse++; } if (snesmouse == 4) { @@ -199,60 +196,84 @@ void cycleinputdevice() } } -extern unsigned char soundon; -extern unsigned char SPCDisable; -extern unsigned char spcon; -extern unsigned char FPSOn; -extern unsigned char FPSAtStart; +extern unsigned int xa; +extern unsigned char soundon, SPCDisable, spcon, FPSOn, FPSAtStart; -const unsigned int versionNumber = 0x00000143; -const char* ZVERSION = "Pre 1.43"; +const unsigned int versionNumber = 0x0000008F; // 1.43 +unsigned char *ZVERSION = "Pre 1.43"; +unsigned char txtfailedalignd[25] = "Data Alignment Failure : "; +unsigned char txtfailedalignc[25] = "Code Alignment Failure : "; + +void outofmemory(); void zstart () { - asm_call(StartUp); + unsigned int ptr; - // Print welcome message. - printf("ZSNES v%s, (c) 1997-2005, ZSNES Team\n", ZVERSION); - puts("Be sure to check http://www.zsnes.com/ for the latest version."); - puts("Please report crashes to zsnes-devel@lists.sourceforge.net.\n"); - puts("ZSNES is written by the ZSNES Team (See AUTHORS.TXT)"); - puts("ZSNES comes with ABSOLUTELY NO WARRANTY. This is free software,"); - puts("and you are welcome to redistribute it under certain conditions;"); - puts("please read 'LICENSE.TXT' thoroughly before doing so.\n"); - puts("Use ZSNES -? for command line definitions.\n"); + asm_call(StartUp); - asm_call(SystemInit); + printf("%s", mydebug); + + // Print welcome message. + printf("ZSNES v%s, (c) 1997-2005, ZSNES Team\n", ZVERSION); + puts("Be sure to check http://www.zsnes.com/ for the latest version."); + puts("Please report crashes to zsnes-devel@lists.sourceforge.net.\n"); + puts("ZSNES is written by the ZSNES Team (See AUTHORS.TXT)"); + puts("ZSNES comes with ABSOLUTELY NO WARRANTY. This is free software,"); + puts("and you are welcome to redistribute it under certain conditions;"); + puts("please read 'LICENSE.TXT' thoroughly before doing so.\n"); + puts("Use ZSNES -? for command line definitions.\n"); + + asm_call(SystemInit); #ifdef OPENSPC - OSPC_Init (); + OSPC_Init(); #else - asm_call(setnoise); - asm_call(InitSPC); + asm_call(setnoise); + asm_call(InitSPC); #endif - asm_call(allocmem); + asm_call(allocmem); - if (!soundon && !SPCDisable) - { - soundon = 1; - spcon = 1; - DSPDisable = 1; - } + if (!soundon && (SPCDisable != 1)) + { + soundon = 1; + spcon = 1; + DSPDisable = 1; + } - if (SPCDisable) - { - soundon = 0; - spcon = 0; - } + if (SPCDisable) + { + soundon = 0; + spcon = 0; + } - if (!frameskip) - { - FPSOn = FPSAtStart; - } + if (!frameskip) + { + FPSOn = FPSAtStart; + } - gammalevel16b = gammalevel * 2; + gammalevel16b = gammalevel >> 1; - asm_call(MMXCheck); - asm_call(init); + asm_call(MMXCheck); + + ptr = (unsigned int)&outofmemory; + + if ((ptr & 3)) + { + printf("%s%d", txtfailedalignc, (ptr & 0x1F)); + + asm_call(WaitForKey); + } + + ptr = (unsigned int)&xa; + + if ((ptr & 3)) + { + printf("%s%d", txtfailedalignd, (ptr & 0x1F)); + + asm_call(WaitForKey); + } + + asm_call(init); } diff --git a/zsnes/src/win/winintrf.asm b/zsnes/src/win/winintrf.asm index 3b0a2c02..aa3a3e06 100644 --- a/zsnes/src/win/winintrf.asm +++ b/zsnes/src/win/winintrf.asm @@ -1213,39 +1213,39 @@ NEWSYM NumVideoModes, dd 33 ; GUI Video Mode Names - Make sure that all names are of the same length ; and end with a NULL terminator NEWSYM GUIVideoModeNames -db '256x224 R WIN ',0 ;0 -db '256x224 R FULL',0 ;1 -db '512x448 R WIN ',0 ;2 -db '512x448 DR WIN ',0 ;3 -db '640x480 S WIN ',0 ;4 -db '640x480 DS WIN ',0 ;5 -db '640x480 DR FULL',0 ;6 -db '640x480 DS FULL',0 ;7 -db '640x480 S FULL',0 ;8 -db '768x672 R WIN ',0 ;9 -db '768x672 DR WIN ',0 ;10 -db '800x600 S WIN ',0 ;11 -db '800x600 DS WIN ',0 ;12 -db '800x600 S FULL',0 ;13 -db '800x600 DR FULL',0 ;14 -db '800x600 DS FULL',0 ;15 -db '1024x768 S WIN ',0 ;16 -db '1024x768 DS WIN ',0 ;17 -db '1024x768 S FULL',0 ;18 -db '1024x768 DR FULL',0 ;19 -db '1024x768 DS FULL',0 ;20 -db '1024x896 R WIN ',0 ;21 -db '1024x896 DR WIN ',0 ;22 -db '1280x960 S WIN ',0 ;23 -db '1280x960 DS WIN ',0 ;24 -db '1280x960 S FULL',0 ;25 -db '1280x960 DR FULL',0 ;26 -db '1280x960 DS FULL',0 ;27 -db '1280x1024 S WIN ',0 ;28 -db '1280x1024 DS WIN ',0 ;29 -db '1280x1024 S FULL',0 ;30 -db '1280x1024 DR FULL',0 ;31 -db '1280x1024 DS FULL',0 ;32 +db '256x224 R W',0 ;0 +db '256x224 R F',0 ;1 +db '512x448 R W',0 ;2 +db '512x448 DR W',0 ;3 +db '640x480 S W',0 ;4 +db '640x480 DS W',0 ;5 +db '640x480 DR F',0 ;6 +db '640x480 DS F',0 ;7 +db '640x480 S F',0 ;8 +db '768x672 R W',0 ;9 +db '768x672 DR W',0 ;10 +db '800x600 S W',0 ;11 +db '800x600 DS W',0 ;12 +db '800x600 S F',0 ;13 +db '800x600 DR F',0 ;14 +db '800x600 DS F',0 ;15 +db '1024x768 S W',0 ;16 +db '1024x768 DS W',0 ;17 +db '1024x768 S F',0 ;18 +db '1024x768 DR F',0 ;19 +db '1024x768 DS F',0 ;20 +db '1024x896 R W',0 ;21 +db '1024x896 DR W',0 ;22 +db '1280x960 S W',0 ;23 +db '1280x960 DS W',0 ;24 +db '1280x960 S F',0 ;25 +db '1280x960 DR F',0 ;26 +db '1280x960 DS F',0 ;27 +db '1280x1024 S W',0 ;28 +db '1280x1024 DS W',0 ;29 +db '1280x1024 S F',0 ;30 +db '1280x1024 DR F',0 ;31 +db '1280x1024 DS F',0 ;32 ; Video Mode Feature Availability (1 = Available, 0 = Not Available) ; Left side starts with Video Mode 0 diff --git a/zsnes/src/zmovie.c b/zsnes/src/zmovie.c new file mode 100644 index 00000000..a7e197a9 --- /dev/null +++ b/zsnes/src/zmovie.c @@ -0,0 +1,448 @@ +/* +Copyright (C) 1997-2005 ZSNES Team ( zsKnight, _Demo_, pagefault, Nach ) + +http://www.zsnes.com +http://sourceforge.net/projects/zsnes + +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., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + + +#ifdef __LINUX__ +#include "gblhdr.h" +#define DIR_SLASH "/" +#else +#include +#include +#include +#define DIR_SLASH "\\" +#endif +#include "gblvars.h" +#include "asm_call.h" + +extern unsigned int PJoyAOrig, PJoyBOrig, PJoyCOrig, PJoyDOrig, PJoyEOrig; +extern unsigned int JoyAOrig, JoyBOrig, JoyCOrig, JoyDOrig, JoyEOrig; +extern unsigned int MsgCount, MessageOn; +extern unsigned char MovieTemp, txtmovieended[15], MovieProcessing, *Msgptr; + +static FILE *movfhandle; + +void Replay() +{ + if (fread(&MovieTemp, 1, 1, movfhandle)) + { + if (MovieTemp < 2) // 1 or 0 are correct values + { + if (MovieTemp == 0) // 0 means the input has changed + { + fread(&PJoyAOrig, 1, 4, movfhandle); + fread(&PJoyBOrig, 1, 4, movfhandle); + fread(&PJoyCOrig, 1, 4, movfhandle); + fread(&PJoyDOrig, 1, 4, movfhandle); + fread(&PJoyEOrig, 1, 4, movfhandle); + } + + JoyAOrig = PJoyAOrig; + JoyBOrig = PJoyBOrig; + JoyCOrig = PJoyCOrig; + JoyDOrig = PJoyDOrig; + JoyEOrig = PJoyEOrig; + } + else // anything else is bad - the file isn't a movie. + { + MovieProcessing = 0; + + fclose(movfhandle); + } + } + else + { + Msgptr = txtmovieended; + MessageOn = MsgCount; + MovieProcessing = 0; + + fclose(movfhandle); + } +} + +extern unsigned int MovieBuffFrame, MovieBuffSize; +unsigned char MovieBuffer[21*60]; + +void IncFrameWriteBuffer() +{ + MovieBuffFrame++; + + if (MovieBuffFrame == 60) + { + fwrite(MovieBuffer, 1, MovieBuffSize, movfhandle); + + MovieBuffSize = 0; + MovieBuffFrame = 0; + } +} + +void intsplitter (unsigned char *buffer, unsigned int offset, unsigned int value) +{ + unsigned char i; + + for (i=0 ; i<4 ; i++) + { + buffer[offset + i] = ((value >> i*8) & 0xFF); + } +} + +unsigned int bytemerger (unsigned char heaviest, unsigned char heavy, unsigned char light, unsigned char lightest) +{ + return ((heaviest << 24) | (heavy << 16) | (light << 8) | (lightest)); +} + +extern unsigned int CReadHead, ReadHead, CFWriteStart, CFWriteHead; +extern unsigned char BackState, CNetType, StoreBuffer[128*32]; + +void Record() +{ + unsigned int offst, PJoyATemp, PJoyBTemp, PJoyCTemp, PJoyDTemp, PJoyETemp; + + if ((BackState == 1) && (CNetType >= 20)) + { + if (CReadHead == ReadHead) + { + CFWriteStart++; + CFWriteStart &= 0x7F; + + if (CFWriteStart == CFWriteHead) + { + offst = (CFWriteHead << 5); + + offst++; + PJoyATemp = bytemerger (StoreBuffer[offst+3],StoreBuffer[offst+2],StoreBuffer[offst+1],StoreBuffer[offst]); + offst+=4; + PJoyBTemp = bytemerger (StoreBuffer[offst+3],StoreBuffer[offst+2],StoreBuffer[offst+1],StoreBuffer[offst]); + offst+=4; + PJoyCTemp = bytemerger (StoreBuffer[offst+3],StoreBuffer[offst+2],StoreBuffer[offst+1],StoreBuffer[offst]); + offst+=4; + PJoyDTemp = bytemerger (StoreBuffer[offst+3],StoreBuffer[offst+2],StoreBuffer[offst+1],StoreBuffer[offst]); + offst+=4; + PJoyETemp = bytemerger (StoreBuffer[offst+3],StoreBuffer[offst+2],StoreBuffer[offst+1],StoreBuffer[offst]); + offst+=4; + +// if (StoreBuffer[offst]) - commented out in the ASM. + if ((PJoyAOrig == PJoyATemp) && (PJoyBOrig == PJoyBTemp) && (PJoyCOrig == PJoyCTemp) && (PJoyDOrig == PJoyDTemp) && (PJoyEOrig == PJoyETemp)) + { + MovieBuffer[MovieBuffSize] = 1; + MovieBuffSize++; + } + else + { + PJoyAOrig = PJoyATemp; + PJoyBOrig = PJoyBTemp; + PJoyCOrig = PJoyCTemp; + PJoyDOrig = PJoyDTemp; + PJoyEOrig = PJoyETemp; + + MovieBuffer[MovieBuffSize] = 0; + MovieBuffSize++; + + intsplitter (MovieBuffer, MovieBuffSize, PJoyAOrig); + MovieBuffSize += 4; + intsplitter (MovieBuffer, MovieBuffSize, PJoyBOrig); + MovieBuffSize += 4; + intsplitter (MovieBuffer, MovieBuffSize, PJoyCOrig); + MovieBuffSize += 4; + intsplitter (MovieBuffer, MovieBuffSize, PJoyDOrig); + MovieBuffSize += 4; + intsplitter (MovieBuffer, MovieBuffSize, PJoyEOrig); + MovieBuffSize += 4; + } + + IncFrameWriteBuffer(); + + CFWriteHead++; + CFWriteHead &= 0x7F; + } + + CReadHead++; + CReadHead &= 0x7F; + } + + offst = (ReadHead << 5); + StoreBuffer[offst] = 0; + offst++; + + intsplitter (StoreBuffer, offst, JoyAOrig); + offst += 4; + intsplitter (StoreBuffer, offst, JoyBOrig); + offst += 4; + intsplitter (StoreBuffer, offst, JoyCOrig); + offst += 4; + intsplitter (StoreBuffer, offst, JoyDOrig); + offst += 4; + intsplitter (StoreBuffer, offst, JoyEOrig); + offst +=4; + + ReadHead++; + ReadHead &= 0x7F; + } + else + { + if ((PJoyAOrig != JoyAOrig) || (PJoyBOrig != JoyBOrig) || (PJoyCOrig != JoyCOrig) || (PJoyDOrig != JoyDOrig) || (PJoyEOrig != JoyEOrig)) + { + PJoyAOrig = JoyAOrig; + PJoyBOrig = JoyBOrig; + PJoyCOrig = JoyCOrig; + PJoyDOrig = JoyDOrig; + PJoyEOrig = JoyEOrig; + MovieTemp = 0; + MovieBuffer[MovieBuffSize] = 0; + MovieBuffSize++; + + intsplitter (MovieBuffer, MovieBuffSize, JoyAOrig); + MovieBuffSize += 4; + intsplitter (MovieBuffer, MovieBuffSize, JoyBOrig); + MovieBuffSize += 4; + intsplitter (MovieBuffer, MovieBuffSize, JoyCOrig); + MovieBuffSize += 4; + intsplitter (MovieBuffer, MovieBuffSize, JoyDOrig); + MovieBuffSize += 4; + intsplitter (MovieBuffer, MovieBuffSize, JoyEOrig); + MovieBuffSize += 4; + } + else + { + MovieTemp = 1; + MovieBuffer[MovieBuffSize] = 1; + MovieBuffSize++; + } + + IncFrameWriteBuffer(); + } +} + +void ProcessMovies() +{ + if (MovieProcessing == 2) { Record(); } + else { Replay(); } +} + +// The following will maybe end up in guic.c once we get it started. +// It came from guiwindp.inc and gui.asm, after all +extern unsigned char MovieRecordWinVal; +extern unsigned int GUICBHold; + +void SkipMovie() +{ + MovieRecordWinVal = 0; + GUICBHold &= 0xFFFFFF00; +} + +void MovieStop() +{ + if (MovieProcessing) + { + fclose(movfhandle); + MovieProcessing = 0; + } +} + +extern unsigned int MovieCounter, statefileloc, Totalbyteloaded, curexecstate; +extern unsigned int nmiprevaddrl, nmiprevaddrh, nmirept, nmiprevline, nmistatus; +extern unsigned char GUIQuit, fnamest[512], CMovieExt, RecData[16], soundon; +extern unsigned char NextLineCache, sramsavedis, UseRemoteSRAMData; +extern unsigned char UnableMovie2[24], UnableMovie3[23]; + +void SRAMChdir(); +void loadstate2(); + +void MoviePlay() +{ + unsigned char FileExt[4]; + + GUICBHold &= 0xFFFFFF00; + + if (CNetType != 20) + { + MovieCounter= 0; + + if (!MovieProcessing) + { + GUIQuit = 2; + memcpy (FileExt, &fnamest[statefileloc-3], 4); + memcpy (&fnamest[statefileloc-3], ".zmv", 4); + fnamest[statefileloc] = CMovieExt; + + SRAMChdir(); + + loadstate2(); + + if ((movfhandle = fopen(fnamest+1,"rb")) != NULL) + { + fseek(movfhandle, Totalbyteloaded, SEEK_SET); + fread(RecData, 1, 16, movfhandle); + printf("Movie made with version: %d\n", RecData[1]); + + if (RecData[2] == 1) + { + timer2upd = bytemerger(RecData[6], RecData[5], RecData[4], RecData[3]); + curexecstate = bytemerger(RecData[10], RecData[9], RecData[9], RecData[7]); + nmiprevaddrl = 0; + nmiprevaddrh = 0; + nmirept = 0; + nmiprevline = 224; + nmistatus = 0; + spcnumread = 0; + spchalted = 0xFFFFFFFF; + NextLineCache = 0; + } + + if (soundon == RecData[0]) + { + if (ramsize) { fread(sram, 1, ramsize, movfhandle); } + + MovieProcessing = 1; + PJoyAOrig = 0; + PJoyBOrig = 0; + PJoyCOrig = 0; + PJoyDOrig = 0; + PJoyEOrig = 0; + sramsavedis = 1; + UseRemoteSRAMData = 0; + DSPMem[0x08] = 0; + DSPMem[0x18] = 0; + DSPMem[0x28] = 0; + DSPMem[0x38] = 0; + DSPMem[0x48] = 0; + DSPMem[0x58] = 0; + DSPMem[0x68] = 0; + DSPMem[0x78] = 0; + + memcpy (&fnamest[statefileloc-3], FileExt, 4); + } + else + { + Msgptr = (!soundon) ? UnableMovie3 : UnableMovie2; + MessageOn = MsgCount; + fclose(movfhandle); + } + } + else + { + + memcpy (&fnamest[statefileloc-3], FileExt, 4); + } + + asm_call(ChangetoLOADdir); + } + } +} + +extern unsigned char NoPictureSave; +extern unsigned int versionNumber; + +void statesaver(); + +void MovieRecord() +{ + unsigned char FileExt[4]; + + FILE *tempfhandle; + + GUICBHold &= 0xFFFFFF00; + + if (!MovieProcessing) + { + MovieCounter = 0; + memcpy (FileExt, &fnamest[statefileloc-3], 4); + memcpy (&fnamest[statefileloc-3], ".zmv", 4); + fnamest[statefileloc] = CMovieExt; + tempfhandle = fopen(fnamest+1,"rb"); + + // check if file exists + if ((MovieRecordWinVal == 1) || (tempfhandle == NULL)) + { + if (!MovieProcessing) + { + CFWriteHead = 0; + CReadHead = 0; + ReadHead = 0; + CFWriteStart = 64; + } + + MovieRecordWinVal = 0; + + SRAMChdir(); + + NoPictureSave = 1; + // saves the statedata as first chunk of movie + if (!MovieProcessing) { statesaver(); } + + NoPictureSave = 0; + // it shouldn't fail, but paranoids can add an 'if'... + movfhandle = fopen(fnamest+1,"r+b"); + fseek(movfhandle, 0, SEEK_END); + + if (!MovieProcessing) + { + RecData[0] = soundon; + RecData[1] = (versionNumber & 0xFF); // valid for versions under 2.56 + RecData[2] = 1; + intsplitter (RecData, 3, timer2upd); + intsplitter (RecData, 7, curexecstate); + fwrite(RecData, 1, 16, movfhandle); + + if (ramsize) { fwrite(sram, 1, ramsize, movfhandle); } + + MovieBuffSize = 0; + MovieBuffFrame = 0; + + if ((CNetType != 20) && (CNetType != 21)) + { + nmiprevaddrl = 0; + nmiprevaddrh = 0; + nmirept = 0; + nmiprevline = 224; + nmistatus = 0; + spcnumread = 0; + spchalted = 0xFFFFFFFF; + NextLineCache = 0; + PJoyAOrig = 0; + PJoyBOrig = 0; + PJoyCOrig = 0; + PJoyDOrig = 0; + PJoyEOrig = 0; + DSPMem[0x08] = 0; + DSPMem[0x18] = 0; + DSPMem[0x28] = 0; + DSPMem[0x38] = 0; + DSPMem[0x48] = 0; + DSPMem[0x58] = 0; + DSPMem[0x68] = 0; + DSPMem[0x78] = 0; + } + } + + MovieProcessing = 2; + + asm_call(ChangetoLOADdir); + } + else + { + fclose(tempfhandle); + MovieRecordWinVal = 1; + } + memcpy (&fnamest[statefileloc-3], FileExt, 4); + } +} diff --git a/zsnes/src/zstate.c b/zsnes/src/zstate.c new file mode 100755 index 00000000..c18601ed --- /dev/null +++ b/zsnes/src/zstate.c @@ -0,0 +1,1020 @@ +/* +Copyright (C) 1997-2005 ZSNES Team ( zsKnight, _Demo_, pagefault, Nach ) + +http://www.zsnes.com +http://sourceforge.net/projects/zsnes + +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., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + + +#ifdef __LINUX__ +#include "gblhdr.h" +#define DIR_SLASH "/" +#else +#include +#include +#include +#define DIR_SLASH "\\" +#endif +#include "gblvars.h" +#include "asm_call.h" + +#ifdef __MSDOS__ +#define clim() __asm__ __volatile__ ("cli"); +#define stim() __asm__ __volatile__ ("sti"); +#else +#define clim() +#define stim() +#endif + +static void copy_snes_data(unsigned char **buffer, void (*copy_func)(unsigned char **, void *, size_t)) +{ + //65816 status, etc. + copy_func(buffer, &curcyc, PH65816regsize); + //SPC Timers + copy_func(buffer, &cycpbl, 2*4); + //SNES PPU Register status + copy_func(buffer, &sndrot, 3019); +} + +static void copy_spc_data(unsigned char **buffer, void (*copy_func)(unsigned char **, void *, size_t)) +{ + //SPC stuff, DSP stuff + copy_func(buffer, spcRam, PHspcsave); + copy_func(buffer, &BRRBuffer, PHdspsave); + copy_func(buffer, &DSPMem, sizeof(DSPMem)); +} + +static void copy_extra_data(unsigned char **buffer, void (*copy_func)(unsigned char **, void *, size_t)) +{ + copy_func(buffer, &soundcycleft, 33); + copy_func(buffer, &spc700read, 10*4); + copy_func(buffer, &timer2upd, 1*4); + copy_func(buffer, &xa, 14*4); + copy_func(buffer, &spcnumread, 4); + copy_func(buffer, &spchalted, 4); + copy_func(buffer, &opcd, 6*4); + copy_func(buffer, &HIRQCycNext, 5); + copy_func(buffer, &oamaddr, 14*4); + copy_func(buffer, &prevoamptr, 1); + copy_func(buffer, &ReadHead, 1*4); +} + +static size_t load_save_size; +static unsigned int zst_version; + +//For compatibility with old save states (pre v1.43) +#define loading_old_state (!buffer && read && (zst_version < 143)) +#define loading_state_no_sram (!buffer && read && !SRAMState) + +static void copy_state_data(unsigned char *buffer, void (*copy_func)(unsigned char **, void *, size_t), bool read) +{ + copy_snes_data(&buffer, copy_func); + + //WRAM (128k), VRAM (64k) + copy_func(&buffer, wramdata, 8192*16); + copy_func(&buffer, vram, 4096*16); + + if (spcon) + { + copy_spc_data(&buffer, copy_func); + if (buffer) //Rewind stuff + { + copy_func(&buffer, &echoon0, PHdspsave2); + } + } + + if (C4Enable) + { + copy_func(&buffer, C4Ram, 2048*4); + } + + if (SFXEnable) + { + copy_func(&buffer, sfxramdata, 8192*16); + copy_func(&buffer, &SfxR0, PHnum2writesfxreg); + } + + if (SA1Enable) + { + copy_func(&buffer, &SA1Mode, PHnum2writesa1reg); + copy_func(&buffer, SA1RAMArea, 8192*16); + if (!loading_old_state) + { + copy_func(&buffer, &SA1Status, 3); + copy_func(&buffer, &SA1xpc, 1*4); + copy_func(&buffer, &sa1dmaptr, 2*4); + } + } + + if (DSP1Type && !loading_old_state) + { + copy_func(&buffer, &DSP1COp, 70+128); + copy_func(&buffer, &Op00Multiplicand, 3*4+128); + copy_func(&buffer, &Op10Coefficient, 4*4+128); + copy_func(&buffer, &Op04Angle, 4*4+128); + copy_func(&buffer, &Op08X, 5*4+128); + copy_func(&buffer, &Op18X, 5*4+128); + copy_func(&buffer, &Op28X, 4*4+128); + copy_func(&buffer, &Op0CA, 5*4+128); + copy_func(&buffer, &Op02FX, 11*4+3*4+28*8+128); + copy_func(&buffer, &Op0AVS, 5*4+14*8+128); + copy_func(&buffer, &Op06X, 6*4+10*8+4+128); + copy_func(&buffer, &Op01m, 4*4+128); + copy_func(&buffer, &Op0DX, 6*4+128); + copy_func(&buffer, &Op03F, 6*4+128); + copy_func(&buffer, &Op14Zr, 9*4+128); + copy_func(&buffer, &Op0EH, 4*4+128); + } + + if (SETAEnable) + { + copy_func(&buffer, setaramdata, 256*16); + + //Todo: copy the SetaCmdEnable? For completeness we should do it + //but currently we ignore it anyway. + } + + if (SPC7110Enable) + { + copy_func(&buffer, romdata+0x510000, 65536); + copy_func(&buffer, &SPCMultA, PHnum2writespc7110reg); + } + + if (!loading_old_state) + { + copy_extra_data(&buffer, copy_func); + + if (!loading_state_no_sram) + { + copy_func(&buffer, sram, ramsize); + } + + if (buffer) //Not to a file, i.e. rewind + { + copy_func(&buffer, &tempesi, 4); + copy_func(&buffer, &tempedi, 4); + copy_func(&buffer, &tempedx, 4); + copy_func(&buffer, &tempebp, 4); + } + } + else + { + spcnumread = 0; + spchalted = 0xFFFFFFFF; + } +} + + +static void memcpyinc(unsigned char **dest, void *src, size_t len) +{ + memcpy(*dest, src, len); + *dest += len; +} + +static void memcpyrinc(unsigned char **src, void *dest, size_t len) +{ + memcpy(dest, *src, len); + *src += len; +} + +extern unsigned int RewindTimer; +extern unsigned char RewindStates; +unsigned char *StateBackup = 0; +size_t rewind_state_size, cur_zst_size, old_zst_size; + +/* A nice idea, but needs more ported from the assembly first. +size_t RewindPos, RewindEarliestPos; + +void BackupCVFrame() +{ + unsigned char *RewindBufferPos = StateBackup + RewindPos*rewind_state_size; + printf("Backing up rewind in slot #%u\n", RewindPos); + copy_state_data(RewindBufferPos, memcpyinc, false); + RewindPos++; + if (RewindPos == RewindStates) + { + RewindPos = 0; + } + if (RewindPos == RewindEarliestPos) + { + RewindEarliestPos++; + if (RewindEarliestPos == RewindStates) + { + RewindEarliestPos = 0; + } + } + RewindTimer = 60*3; +} + +void RestoreCVFrame() +{ + if (RewindPos != RewindEarliestPos) + { + unsigned char *RewindBufferPos; + + if (!RewindPos) + { + RewindPos = RewindStates; + } + RewindPos--; + + RewindBufferPos = StateBackup + RewindPos*rewind_state_size; + printf("Restoring rewind in slot #%u\n", RewindPos); + copy_state_data(RewindBufferPos, memcpyrinc, true); + + //Clear Cache Check + memset(vidmemch2, 1, sizeof(vidmemch2)); + memset(vidmemch4, 1, sizeof(vidmemch4)); + memset(vidmemch8, 1, sizeof(vidmemch8)); + + RewindTimer = 60*3; + } +} + +void MultipleFrameBack(unsigned int i) +{ + while (i--) + { + if (RewindPos != RewindEarliestPos) + { + if (!RewindPos) + { + RewindPos = RewindStates; + } + RewindPos--; + } + else + { + break; + } + } +} + +void SetupRewindBuffer() +{ + if (StateBackup){ free(StateBackup); } + for (; RewindStates; RewindStates--) + { + StateBackup = 0; + StateBackup = (unsigned char *)malloc(rewind_state_size*RewindStates); + if (StateBackup) { break; } + } +} +*/ + +extern unsigned int CBackupPos, PBackupPos, RewindPos, RewindOldPos; +extern unsigned char RewindFrames, romispal; +#define ActualRewindFrames (RewindFrames * (romispal ? 25 : 30)) + + +void BackupCVFrame() +{ + unsigned char *RewindBufferPos = StateBackup + CBackupPos*rewind_state_size; + //printf("Backing up rewind in slot #%u\n", CBackupPos); + copy_state_data(RewindBufferPos, memcpyinc, false); + RewindTimer = ActualRewindFrames; +} + +void RestoreCVFrame() +{ + unsigned char *RewindBufferPos = StateBackup + PBackupPos*rewind_state_size; + //printf("Restoring rewind in slot #%u\n", PBackupPos); + copy_state_data(RewindBufferPos, memcpyrinc, true); + RewindTimer = ActualRewindFrames; +} + +void SetupRewindBuffer() +{ + if (StateBackup){ free(StateBackup); } + StateBackup = 0; + StateBackup = (unsigned char *)malloc(rewind_state_size*16); + if (!StateBackup) { asm_call(outofmemory); } +} + +static size_t state_size; +static void state_size_tally(unsigned char **dest, void *src, size_t len) +{ + state_size += len; +} + +void InitRewindVars() +{ +#ifndef __MSDOS__ //When all the code is ported to C, we can make this work with DOS too + unsigned char almost_useless_array[1]; //An array is needed for copy_state_data to give the correct size + state_size = 0; + copy_state_data(almost_useless_array, state_size_tally, false); + rewind_state_size = state_size; + + SetupRewindBuffer(); + RewindPos = 0; + RewindOldPos = 0; + //RewindEarliestPos = 0; + RewindTimer = ActualRewindFrames; +#endif +} + +//This is used to preserve system load state between loads +static unsigned char BackupSystemBuffer[0x800000]; //Half a megabyte, should be enough for a while +void BackupSystemVars() +{ + unsigned char *buffer = BackupSystemBuffer; + copy_snes_data(&buffer, memcpyinc); + copy_spc_data(&buffer, memcpyinc); + copy_extra_data(&buffer, memcpyinc); +} + +void RestoreSystemVars() +{ + unsigned char *buffer = BackupSystemBuffer; + InitRewindVars(); + copy_snes_data(&buffer, memcpyrinc); + copy_spc_data(&buffer, memcpyrinc); + copy_extra_data(&buffer, memcpyrinc); +} + +extern unsigned int Bank0datr8[256], Bank0datr16[256], Bank0datw8[256]; +extern unsigned int Bank0datw16[256], xd, DPageR8, DPageR16, DPageW8; +extern unsigned int DPageW16; + +void UpdateDPageC() +{ + DPageR8 = Bank0datr8[(xd >> 8) & 0xFF]; + DPageR16 = Bank0datr16[(xd >> 8) & 0xFF]; + DPageW8 = Bank0datw8[(xd >> 8) & 0xFF]; + DPageW16 = Bank0datw16[(xd >> 8) & 0xFF]; +} + +extern unsigned int SA1xd, SA1DPageR8, SA1DPageR16, SA1DPageW8, SA1DPageW16; + +void SA1UpdateDPageC() +{ + SA1DPageR8 = Bank0datr8[(SA1xd >> 8) & 0xFF]; + SA1DPageR16 = Bank0datr16[(SA1xd >> 8) & 0xFF]; + SA1DPageW8 = Bank0datw8[(SA1xd >> 8) & 0xFF]; + SA1DPageW16 = Bank0datw16[(SA1xd >> 8) & 0xFF]; +} + +extern unsigned int xdb, xpb, xs, xx, xy; +extern unsigned short oamaddrt, xat, xst, xdt, xxt, xyt; +extern unsigned char xdbt, xpbt; + +void unpackfunct() +{ + oamaddrt = (oamaddr & 0xFFFF); + xat = (xa & 0xFFFF); + xdbt = (xdb & 0xFF); + xpbt = (xpb & 0xFF); + xst = (xs & 0xFFFF); + xdt = (xd & 0xFFFF); + xxt = (xx & 0xFFFF); + xyt = (xy & 0xFFFF); +} + +extern unsigned int spcBuffera; +extern unsigned int Voice0BufPtr, Voice1BufPtr, Voice2BufPtr, Voice3BufPtr; +extern unsigned int Voice4BufPtr, Voice5BufPtr, Voice6BufPtr, Voice7BufPtr; +extern unsigned int Curtableaddr, tableA[256], spcPCRam, spcRamDP; + +void PrepareSaveState() +{ + unsigned int offst = (unsigned int)spcRam; + + spcPCRam -= offst; + spcRamDP -= offst; + + Voice0BufPtr -= spcBuffera; + Voice1BufPtr -= spcBuffera; + Voice2BufPtr -= spcBuffera; + Voice3BufPtr -= spcBuffera; + Voice4BufPtr -= spcBuffera; + Voice5BufPtr -= spcBuffera; + Voice6BufPtr -= spcBuffera; + Voice7BufPtr -= spcBuffera; +} + +#define byteset(byte, checkbit) (byte & (1 << checkbit)) ? 1 : 0 + +extern unsigned int GlobalVL, GlobalVR, EchoVL, EchoVR, EchoRate[16], MaxEcho; +extern unsigned int EchoFB, NoiseSpeeds[32], dspPAdj, NoiseInc, bg1ptrx; +extern unsigned int bg1ptry, bg2ptrx, bg2ptry, bg3ptrx, bg3ptry, bg4ptrx; +extern unsigned int bg4ptry; +extern signed int FIRTAPVal0, FIRTAPVal1, FIRTAPVal2, FIRTAPVal3, FIRTAPVal4; +extern signed int FIRTAPVal5, FIRTAPVal6, FIRTAPVal7; +extern unsigned short VolumeConvTable[32768], bg1ptr, bg1ptrb, bg1ptrc; +extern unsigned short bg2ptr, bg2ptrb, bg2ptrc, bg3ptr, bg3ptrb, bg3ptrc; +extern unsigned short bg4ptr, bg4ptrb, bg4ptrc; +extern unsigned char VolumeTableb[256], MusicVol, Voice0Status; +extern unsigned char Voice1Status, Voice2Status, Voice3Status, Voice4Status; +extern unsigned char Voice5Status, Voice6Status, Voice7Status, Voice0Noise; +extern unsigned char Voice1Noise, Voice2Noise, Voice3Noise, Voice4Noise; +extern unsigned char Voice5Noise, Voice6Noise, Voice7Noise, bgtilesz; +extern unsigned char BG116x16t, BG216x16t, BG316x16t, BG416x16t, vramincby8on; +extern unsigned char vramincr; + +extern void (**regptw)(); +void reg2118(); +void reg2118inc(); +void reg2118inc8(); +void reg2118inc8inc(); +void reg2119(); +void reg2119inc(); +void reg2119inc8(); +void reg2119inc8inc(); + +void repackfunct() +{ + signed char val; + unsigned char block; + + // Global/Echo Volumes + GlobalVL = (VolumeConvTable[(MusicVol << 8) + VolumeTableb[DSPMem[0x0C]]] & 0xFF); + GlobalVR = (VolumeConvTable[(MusicVol << 8) + VolumeTableb[DSPMem[0x1C]]] & 0xFF); + EchoVL = (VolumeConvTable[(MusicVol << 8) + VolumeTableb[DSPMem[0x2C]]] & 0xFF); + EchoVR = (VolumeConvTable[(MusicVol << 8) + VolumeTableb[DSPMem[0x3C]]] & 0xFF); + + // Echo Values + MaxEcho = EchoRate[(DSPMem[0x7D] & 0xF)]; + EchoFB = VolumeTableb[DSPMem[0x0D]]; + + // FIR Filter Values + val = DSPMem[0x0F]; + FIRTAPVal0 = (signed int)val; + val = DSPMem[0x1F]; + FIRTAPVal1 = (signed int)val; + val = DSPMem[0x2F]; + FIRTAPVal2 = (signed int)val; + val = DSPMem[0x3F]; + FIRTAPVal3 = (signed int)val; + val = DSPMem[0x4F]; + FIRTAPVal4 = (signed int)val; + val = DSPMem[0x5F]; + FIRTAPVal5 = (signed int)val; + val = DSPMem[0x6F]; + FIRTAPVal6 = (signed int)val; + val = DSPMem[0x7F]; + FIRTAPVal7 = (signed int)val; + + // Noise + block = DSPMem[0x6C]; + DSPMem[0x6C] &= 0x7F; + + if (block && 0xC0) + { + Voice0Status = Voice1Status = Voice2Status = Voice3Status = 0; + Voice4Status = Voice5Status = Voice6Status = Voice7Status = 0; + } + + NoiseInc = (((NoiseSpeeds[(block & 0x1F)] * dspPAdj) >> 17) & 0xFFFFFFFF); + + Voice0Noise = byteset (DSPMem[0x3D], 0); + Voice1Noise = byteset (DSPMem[0x3D], 1); + Voice2Noise = byteset (DSPMem[0x3D], 2); + Voice3Noise = byteset (DSPMem[0x3D], 3); + Voice4Noise = byteset (DSPMem[0x3D], 4); + Voice5Noise = byteset (DSPMem[0x3D], 5); + Voice6Noise = byteset (DSPMem[0x3D], 6); + Voice7Noise = byteset (DSPMem[0x3D], 7); + + bg1ptrx = bg1ptrb - bg1ptr; + bg1ptry = bg1ptrc - bg1ptr; + bg2ptrx = bg2ptrb - bg2ptr; + bg2ptry = bg2ptrc - bg2ptr; + bg3ptrx = bg3ptrb - bg3ptr; + bg3ptry = bg3ptrc - bg3ptr; + bg4ptrx = bg4ptrb - bg4ptr; + bg4ptry = bg4ptrc - bg4ptr; + + // 16x16 tiles + BG116x16t = byteset (bgtilesz, 0); + BG216x16t = byteset (bgtilesz, 1); + BG316x16t = byteset (bgtilesz, 2); + BG416x16t = byteset (bgtilesz, 3); + + oamaddr = oamaddrt; + xa = xat; + xdb = xdbt; + xpb = xpbt; + xs = xst; + xd = xdt; + xx = xxt; + xy = xyt; + + if (vramincby8on == 1) + { + if (vramincr == 1) + { + regptw[0x2118] = reg2118inc8inc; + regptw[0x2119] = reg2119inc8; + } + else + { + regptw[0x2118] = reg2118inc8; + regptw[0x2119] = reg2119inc8inc; + } + } + else + { + if (vramincr == 1) + { + regptw[0x2118] = reg2118inc; + regptw[0x2119] = reg2119; + } + else + { + regptw[0x2118] = reg2118; + regptw[0x2119] = reg2119inc; + } + } +} + +extern unsigned int SA1Stat; +extern unsigned char IRAM[2049], *SA1Ptr, *SA1RegPCS, *CurBWPtr, *SA1BWPtr; +extern unsigned char *SNSBWPtr; + +void SaveSA1() +{ + unsigned int offst=(unsigned int)SA1RegPCS; + + SA1Stat &= 0xFFFFFF00; + SA1Ptr -= offst; + + if (SA1RegPCS == IRAM) + { + SA1Stat = (SA1Stat & 0xFFFFFF00) + 1; + } + + if (SA1RegPCS == IRAM-0x3000) + { + SA1Stat = (SA1Stat & 0xFFFFFF00) + 2; + } + + offst = (unsigned int)romdata; + SA1RegPCS -= offst; + CurBWPtr -= offst; + SA1BWPtr -= offst; + SNSBWPtr -= offst; +} + +void RestoreSA1() +{ + unsigned int offst=(unsigned int)romdata; + + SA1RegPCS += offst; + CurBWPtr += offst; + SA1BWPtr += offst; + SNSBWPtr += offst; + + if ((SA1Stat & 0xFF) == 1) + { + SA1RegPCS = IRAM; + } + + if ((SA1Stat & 0xFF) == 2) + { + SA1RegPCS = IRAM-0x3000; + } + + offst = (unsigned int)SA1RegPCS; + SA1Ptr += offst; + SA1RAMArea = romdata + 4096*1024; +} + +#define ResState(Voice_BufPtr) \ + Voice_BufPtr += spcBuffera; \ + if (Voice_BufPtr >= spcBuffera + 65536*4) \ + { \ + Voice_BufPtr = spcBuffera; \ + } + +void ResetState() +{ + unsigned int offst = (unsigned int)spcRam; + + spcPCRam += offst; + spcRamDP += offst; + + ResState(Voice0BufPtr); + ResState(Voice1BufPtr); + ResState(Voice2BufPtr); + ResState(Voice3BufPtr); + ResState(Voice4BufPtr); + ResState(Voice5BufPtr); + ResState(Voice6BufPtr); + ResState(Voice7BufPtr); +} + +extern unsigned int statefileloc, CurrentHandle, SfxRomBuffer; +extern unsigned int SfxCROM, SfxLastRamAdr, SfxRAMMem; +extern unsigned int MsgCount, MessageOn; +extern unsigned char AutoIncSaveSlot, firstsaveinc, fnamest[512]; +extern unsigned char cbitmode, NoPictureSave, txtsavemsg[14]; +extern unsigned char *Msgptr, txtsavemsgfail[15]; +extern unsigned short PrevPicture[64*56]; + +static FILE *fhandle; +void SRAMChdir(); +void CapturePicture(); + +static void write_save_state_data(unsigned char **dest, void *data, size_t len) +{ + fwrite(data, 1, len, fhandle); +} + +static const char zst_header_old[] = "ZSNES Save State File V0.6\x1a\x3c"; +static const char zst_header_cur[] = "ZSNES Save State File V143\x1a\x8f"; + +void calculate_state_sizes() +{ + state_size = 0; + zst_version = 143; + copy_state_data(0, state_size_tally, false); + cur_zst_size = state_size + sizeof(zst_header_cur)-1; + + state_size = 0; + zst_version = 60; + copy_state_data(0, state_size_tally, true); + old_zst_size = state_size + sizeof(zst_header_old)-1; +} + +void PrepareOffset() +{ + Curtableaddr -= (unsigned int)tableA; +} + +void ResetOffset() +{ + Curtableaddr += (unsigned int)tableA; +} + +void statesaver() +{ + //'Auto increment savestate slot' code + if (AutoIncSaveSlot) + { + if (firstsaveinc) + { + firstsaveinc = 0; + } + else + { + switch (fnamest[statefileloc]) + { + case 't': + fnamest[statefileloc] = '1'; + break; + case '9': + fnamest[statefileloc] = 't'; + break; + default: + fnamest[statefileloc]++; + } + } + } + + //Save State code + + #ifdef __LINUX__ + SRAMChdir(); + #endif + + clim () + + if ((fhandle = fopen(fnamest+1,"wb"))) + { + fwrite(zst_header_cur, 1, sizeof(zst_header_cur)-1, fhandle); //-1 for null + + PrepareOffset(); + PrepareSaveState(); + unpackfunct(); + + if (SFXEnable) + { + SfxRomBuffer -= SfxCROM; + SfxLastRamAdr -= SfxRAMMem; + } + + if (SA1Enable) + { + SaveSA1(); //Convert SA-1 stuff to standard, non displacement format + } + + copy_state_data(0, write_save_state_data, false); + + if (SFXEnable) + { + SfxRomBuffer += SfxCROM; + SfxLastRamAdr += SfxRAMMem; + } + + if (SA1Enable) + { + RestoreSA1(); //Convert back SA-1 stuff + } + + if (cbitmode && !NoPictureSave) + { + CapturePicture(); + fwrite(PrevPicture, 1, 64*56*sizeof(unsigned short), fhandle); + } + + fclose(fhandle); + + //Display message on the screen, 'STATE X SAVED.' + if (fnamest[statefileloc] == 't') + { + txtsavemsg[6]='0'; + } + else + { + txtsavemsg[6]=fnamest[statefileloc]; + } + + Msgptr = txtsavemsg; + MessageOn = MsgCount; + + ResetOffset(); + ResetState(); + } + else + { + //Display message on the screen, 'UNABLE TO SAVE.' + Msgptr = txtsavemsgfail; + MessageOn = MsgCount; + } + + stim(); +} + +extern unsigned int snesmmap[256], snesmap2[256]; +/*extern unsigned int NumofBanks; +extern unsigned char SA1BankVal[4]; + +void BankSwitchC (unsigned char bank, unsigned int offset1, unsigned int offset2, unsigned int pointer) +{ + unsigned int curbankval=SA1BankVal[bank], membankval, i; + + if ((NumofBanks & 0xFF) == 64) { curbankval &= 1 ; } + + curbankval &= 7; + curbankval <<= 20; + + if (SA1BankVal[bank] & 0x80) + { + membankval = (pointer + (unsigned int)romdata - 0x8000); + } + else + { + membankval = (curbankval + (unsigned int)romdata - 0x8000); + } + + for (i=0 ; i<32 ; i++) + { + snesmmap[offset1+i] = membankval; + membankval += 0x8000; + } + + membankval = curbankval + (unsigned int)romdata; + + for (i=0 ; i<16 ; i++) + { + snesmap2[offset2+i] = membankval; + snesmmap[offset2+i] = membankval; + membankval += 0x10000; + } +} + +extern unsigned int SA1BankSw; + +void UpdateBanks() +{ + if ((SA1BankSw & 0xFF) == 1) + { + BankSwitchC (0, 0x000, 0x0C0, 0x000000) ; + BankSwitchC (1, 0x020, 0x0D0, 0x100000) ; + BankSwitchC (2, 0x080, 0x0E0, 0x200000) ; + BankSwitchC (3, 0x0A0, 0x0F0, 0x300000) ; + } +}*/ + +void BankSwitchSDD1C (unsigned char bankval, unsigned int offset) +{ + unsigned int curbankval = bankval, i; + + curbankval &= 7; + curbankval <<= 20; + curbankval += (unsigned int)romdata; + + for (i=0; i<16 ; i++) + { + snesmap2[offset+i] = curbankval; + snesmmap[offset+i] = curbankval; + curbankval += 0x10000; + } +} + +extern unsigned char SDD1BankA, SDD1BankB, SDD1BankC, SDD1BankD; + +void UpdateBanksSDD1() +{ + if (SDD1BankA) + { + BankSwitchSDD1C(SDD1BankA, 0x0C0); + BankSwitchSDD1C(SDD1BankB, 0x0D0); + BankSwitchSDD1C(SDD1BankC, 0x0E0); + BankSwitchSDD1C(SDD1BankD, 0x0F0); + } +} + +extern unsigned int Voice0Freq, Voice1Freq, Voice2Freq, Voice3Freq; +extern unsigned int Voice4Freq, Voice5Freq, Voice6Freq, Voice7Freq; +extern unsigned short Voice0Pitch, Voice1Pitch, Voice2Pitch, Voice3Pitch; +extern unsigned short Voice4Pitch, Voice5Pitch, Voice6Pitch, Voice7Pitch; + +void initpitch() +{ + Voice0Pitch = DSPMem[2+0*0x10]; + Voice0Freq = ((((Voice0Pitch & 0x3FFF) * dspPAdj) >> 8) & 0xFFFFFFFF); + Voice1Pitch = DSPMem[2+1*0x10]; + Voice1Freq = ((((Voice1Pitch & 0x3FFF) * dspPAdj) >> 8) & 0xFFFFFFFF); + Voice2Pitch = DSPMem[2+2*0x10]; + Voice2Freq = ((((Voice2Pitch & 0x3FFF) * dspPAdj) >> 8) & 0xFFFFFFFF); + Voice3Pitch = DSPMem[2+3*0x10]; + Voice3Freq = ((((Voice3Pitch & 0x3FFF) * dspPAdj) >> 8) & 0xFFFFFFFF); + Voice4Pitch = DSPMem[2+4*0x10]; + Voice4Freq = ((((Voice4Pitch & 0x3FFF) * dspPAdj) >> 8) & 0xFFFFFFFF); + Voice5Pitch = DSPMem[2+5*0x10]; + Voice5Freq = ((((Voice5Pitch & 0x3FFF) * dspPAdj) >> 8) & 0xFFFFFFFF); + Voice6Pitch = DSPMem[2+6*0x10]; + Voice6Freq = ((((Voice6Pitch & 0x3FFF) * dspPAdj) >> 8) & 0xFFFFFFFF); + Voice7Pitch = DSPMem[2+7*0x10]; + Voice7Freq = ((((Voice7Pitch & 0x3FFF) * dspPAdj) >> 8) & 0xFFFFFFFF); +} + +extern unsigned int KeyLoadState, Totalbyteloaded, SfxMemTable[256], SfxCPB; +extern unsigned int SfxPBR, SfxROMBR, SfxRAMBR; +extern unsigned char pressed[256+128+64], multchange, txtloadmsg[15]; +extern unsigned char txtconvmsg[16], txtnfndmsg[23], MovieProcessing; +extern unsigned char ioportval, SDD1Enable, nexthdma; + +void procexecloop(); + +static void read_save_state_data(unsigned char **dest, void *data, size_t len) +{ + load_save_size += fread(data, 1, len, fhandle); +} + +void stateloader (unsigned char *statename, unsigned char keycheck, unsigned char xfercheck) +{ + char zst_header_check[sizeof(zst_header_cur)-1]; + + if (keycheck) + { + unsigned char statevalue; + + pressed[1] = 0; + pressed[KeyLoadState] = 2; + multchange = 1; + + //Get the state number + if (fnamest[statefileloc] == 't') + { + statevalue = '0'; + } + else + { + statevalue = fnamest[statefileloc]; + } + + txtloadmsg[6] = statevalue; + txtconvmsg[6] = statevalue; + txtnfndmsg[21] = statevalue; + } + + #ifdef __LINUX__ + SRAMChdir(); + #endif + + clim(); + + //Actual state loading code + if ((fhandle = fopen(statename,"rb")) != NULL) + { + zst_version = 0; + if (xfercheck) { Totalbyteloaded = 0; } + + Totalbyteloaded += fread(zst_header_check, 1, sizeof(zst_header_check), fhandle); + if (!memcmp(zst_header_check, zst_header_cur, sizeof(zst_header_check)-2)) + { + zst_version = 143; //v1.43+ + } + if (!memcmp(zst_header_check, zst_header_old, sizeof(zst_header_check)-2)) + { + zst_version = 60; //v0.60 - v1.42 + } // the -2 means we only check the text - trust me, that's ok + + if (zst_version) //Pre v0.60 saves are no longer loaded + { + load_save_size = 0; + copy_state_data(0, read_save_state_data, true); + Totalbyteloaded += load_save_size; + + if (SFXEnable) + { + SfxCPB = SfxMemTable[(SfxPBR & 0xFF)]; + SfxCROM = SfxMemTable[(SfxROMBR & 0xFF)]; + SfxRAMMem = (unsigned int)sfxramdata + ((SfxRAMBR & 0xFF) << 16); + SfxRomBuffer += SfxCROM; + SfxLastRamAdr += SfxRAMMem; + } + + if (SA1Enable) + { + RestoreSA1(); //Convert back SA-1 stuff + /* + All UpdateBanks() seems to do is break Oshaberi Parodius... + The C port is still present, just commented out + */ + //UpdateBanks(); + SA1UpdateDPageC(); + } + + if (SDD1Enable) + { + UpdateBanksSDD1(); + } + + //Clear cache check if state loaded + memset(vidmemch2, 1, sizeof(vidmemch2)); + memset(vidmemch4, 1, sizeof(vidmemch4)); + memset(vidmemch8, 1, sizeof(vidmemch8)); + + MovieProcessing = 0; + + repackfunct(); + + //headerhack(); //Was in the asm, but why is this needed? + + initpitch(); + ResetOffset(); + ResetState(); + procexecloop(); + + Msgptr = txtloadmsg; // 'STATE X LOADED.' + } + else + { + Msgptr = txtconvmsg; // 'STATE X TOO OLD.' + } + + fclose(fhandle); + } + else + { + Msgptr = txtnfndmsg; // 'UNABLE TO LOAD STATE X.' + } + + stim(); + + if (keycheck) + { + MessageOn = MsgCount; + } +} + +void debugloadstate() +{ + stateloader(fnamest+1, 0, 0); +} + +void loadstate() +{ + stateloader(fnamest+1, 1, 0); +} + +void loadstate2() +{ + stateloader(fnamest+1, 0, 1); +} + +extern unsigned char Netfname[11]; + +void loadstate3() +{ + stateloader(Netfname, 0, 1); +}