Files
ZSNES/zsnes/src/gui/guicheat.inc
2001-04-05 13:27:14 +00:00

1340 lines
26 KiB
PHP

;Copyright (C) 1997-2001 ZSNES Team ( zsknight@zsnes.com / _demo_@zsnes.com )
;
;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.
; GUI Cheat Code Routines
AddCSCheatCode:
cmp byte[CSInputDisplay],'_'
je .nodisplay
jmp .okay
.nodisplay
ret
.okay
mov eax,[curentryval]
mov [curaddrvalcs],eax
mov eax,[CSCurValue]
mov [curvaluecs],eax
xor ecx,ecx
mov cl,[CheatSrcByteSize]
inc cl
cmp byte[CheatUpperByteOnly],0
je .cspardisploop
mov cl,1
.cspardispagain
cmp dword[curvaluecs],0FFh
jbe .cspardisploop
shr dword[curvaluecs],8
inc dword[curaddrvalcs]
jmp .cspardispagain
.cspardisploop
push ecx
mov esi,GUICSrcTextQ
mov ecx,3
mov eax,[curaddrvalcs]
add eax,7E0000h
mov bl,[curvaluecs]
; write bl at address eax
call AddCheatCode
shr dword[curvaluecs],8
mov byte[GUItextcolor],223
add dword[CheatSearchYPos],10
inc dword[curaddrvalcs]
pop ecx
dec ecx
jnz near .cspardisploop
mov byte[CheatWinMode],2
ret
%macro SearchCMPByte 0
mov bl,[edi]
cmp bl,[esi]
%endmacro
%macro SearchCMP2Bytes 0
mov bx,[edi]
cmp bx,[esi]
%endmacro
%macro SearchCMP3Bytes 0
push ecx
mov ebx,[edi]
mov ecx,[esi]
and ebx,0FFFFFFh
and ecx,0FFFFFFh
cmp ebx,ecx
pop ecx
%endmacro
%macro SearchCMP4Bytes 0
mov ebx,[edi]
cmp ebx,[esi]
%endmacro
%macro SearchMacro 2
mov dl,0FEh
%%searchloop
%2
%1 %%nofail
and [eax],dl
%%nofail
inc edi
inc esi
cmp dl,7Fh
jne %%noinceax
inc eax
%%noinceax
rol dl,1
loop %%searchloop
%endmacro
%macro SearchMacroB 1
cmp byte[CheatCompareValue],0
je near %%greater
cmp byte[CheatCompareValue],1
je near %%lessthan
cmp byte[CheatCompareValue],3
je near %%notequalthan
SearchMacro je, %1
jmp .end
%%greater
SearchMacro ja, %1
jmp .end
%%lessthan
SearchMacro jb, %1
jmp .end
%%notequalthan
SearchMacro jne, %1
jmp .end
%endmacro
CheatCodeSearchProcess:
cmp byte[CheatSrcSearchType],1
je near .comparative
cmp byte[CSInputDisplay],0
je near .nodisplay
cmp byte[CSInputDisplay],'_'
je near .nodisplay
cmp byte[CSOverValue],1
je near .nodisplay
mov byte[CSInputDisplay],'_'
mov byte[CSInputDisplay+1],0
; Process Cheat Search
mov ecx,65536*2
xor ebx,ebx
mov bl,byte[CheatSrcByteSize]
sub ecx,ebx
mov edx,[SrcMask+ebx*4]
mov edi,dword[vidbuffer]
add edi,129600+65536*2
mov esi,[wramdata]
mov bl,0FEh
mov bh,01h
.exactloop
mov eax,[esi]
and eax,edx
cmp eax,[CSCurValue]
je .found
inc eax
and eax,edx
cmp eax,[CSCurValue]
je .foundb
.failedfind
and [edi],bl
jmp .foundc
.found
test byte[edi+16384],bh
jz .failedfind
jmp .foundc
.foundb
cmp byte[FirstSearch],1
je .clear
test byte[edi+16384],bh
jnz .failedfind
jmp .foundc
.clear
and byte[edi+16384],bl
.foundc
cmp bl,7Fh
jne .noincedi
inc edi
.noincedi
rol bl,1
rol bh,1
inc esi
loop .exactloop
; CSCurValue dd 0
mov byte[CopyRamToggle],1
mov byte[CheatSearchStatus],1
.nodisplay
ret
.comparative
mov byte[CSInputDisplay],'_'
mov byte[CSInputDisplay+1],0
mov byte[CheatSearchStatus],1
mov eax,dword[vidbuffer]
add eax,129600+65536*2
mov esi,dword[vidbuffer]
add esi,129600
mov edi,[wramdata]
mov ecx,65536*2
cmp byte[CheatSrcByteSize],1
je near .bytesize2
cmp byte[CheatSrcByteSize],2
je near .bytesize3
cmp byte[CheatSrcByteSize],3
je near .bytesize4
SearchMacroB SearchCMPByte
.bytesize2
dec ecx
SearchMacroB SearchCMP2Bytes
.bytesize3
sub ecx,2
SearchMacroB SearchCMP3Bytes
.bytesize4
sub ecx,3
SearchMacroB SearchCMP4Bytes
.end
mov byte[CopyRamToggle],1
ret
CopyRamToggle db 0
FirstSearch db 0
CheatCodeSearchInit:
mov byte[CSInputDisplay],'_'
mov byte[CSInputDisplay+1],0
mov byte[CheatWinMode],1
mov byte[CheatSearchStatus],0
cmp byte[CopyRamToggle],0
mov byte[FirstSearch],1
mov eax,dword[vidbuffer]
add eax,129600
; copy 128k ram
mov ebx,[wramdata]
mov ecx,32768
.loop
mov edx,[ebx]
mov [eax],edx
add ebx,4
add eax,4
loop .loop
; fill searched buffer with 0xFF
mov eax,dword[vidbuffer]
add eax,129600+65536*2
mov ecx,8192
.loop2
mov dword[eax],0FFFFFFFFh
add eax,4
loop .loop2
cmp byte[CheatSrcSearchType],1
jne .nottype1
mov byte[CheatSearchStatus],1
.nottype1
mov dword[CheatCompareValue],0
mov eax,dword[vidbuffer]
add eax,129600+65536*2
cmp byte[CheatSrcByteSize],1
je near .bytesize2
cmp byte[CheatSrcByteSize],2
je near .bytesize3
cmp byte[CheatSrcByteSize],3
je near .bytesize4
ret
.bytesize2
and byte[eax+16383],07Fh
ret
.bytesize3
and byte[eax+16383],03Fh
ret
.bytesize4
and byte[eax+16383],01Fh
ret
CheatCodeSave:
cmp byte[NumCheats],0
jne .okay
mov byte[GUICBHold],0
ret
.okay
mov byte[cheatdata+6],254
mov byte[cheatdata+7],252
call SRAMDirc
mov byte[GUICBHold],0
mov ebx,[statefileloc]
sub ebx,2
mov eax,[fnamest+ebx]
mov dword[fnamest+ebx],'CHT'
push eax
push ebx
mov edx,fnamest+1
call Create_File
jc .cheatsavefail
mov bx,ax
mov ecx,[NumCheats]
mov edx,ecx
shl ecx,4
shl edx,2
add ecx,edx
add ecx,edx
add ecx,edx
mov edx,cheatdata
call Write_File
call Close_File
.cheatsavefail
pop ebx
pop eax
mov [fnamest+ebx],eax
call LOADDir
ret
CheatCodeLoad:
call SRAMDirc
mov byte[GUICBHold],0
mov ebx,[statefileloc]
sub ebx,2
mov eax,[fnamest+ebx]
mov dword[fnamest+ebx],'CHT'
push eax
push ebx
mov edx,fnamest+1
call Open_File
jc near .fail
mov bx,ax
; Disable all codes
push ebx
mov esi,cheatdata
mov ecx,[NumCheats]
cmp ecx,0
je .skip
.loop2
test byte[esi],4
jnz .disabled2
push esi
push ecx
call DisableCheatCode
pop ecx
pop esi
.disabled2
add esi,28
dec ecx
jnz .loop2
.skip
pop ebx
mov ecx,255*28
mov edx,cheatdata
call Read_File
push eax
call Close_File
pop eax
cmp byte[cheatdata+6],254
jne .notnewformat
cmp byte[cheatdata+7],252
jne .notnewformat
jmp .newformat
.notnewformat
; Convert format
mov esi,cheatdata
mov ebx,18
push eax
xor edx,edx
div ebx
push edx
mov [NumCheats],eax
mov ebx,28
mul ebx
mov ecx,eax
pop edx
pop eax
sub eax,edx
.convloop
sub ecx,28
sub eax,18
mov ebx,6
.convloopb
mov dl,[cheatdata+eax+ebx-1]
mov [cheatdata+ecx+ebx-1],dl
dec ebx
jnz .convloopb
mov ebx,12
.convloopd
mov dl,[cheatdata+eax+ebx+5]
mov [cheatdata+ecx+ebx+7],dl
dec ebx
jnz .convloopd
mov ebx,8
.convloopc
mov byte[cheatdata+ecx+ebx+19],0
dec ebx
jnz .convloopc
or ecx,ecx
jnz .convloop
jmp .fin
.newformat
mov ebx,28
xor edx,edx
div ebx
mov [NumCheats],eax
.fin
pop ebx
pop eax
mov [fnamest+ebx],eax
; Enable all ON toggled cheat codes
mov esi,cheatdata
mov ecx,[NumCheats]
cmp ecx,0
je .skip2
.loop
test byte[esi],4
jnz .disabled
push esi
push ecx
call EnableCheatCode
pop ecx
pop esi
.disabled
add esi,28
dec ecx
jnz .loop
.skip2
mov eax,[NumCheats]
cmp eax,[GUIcurrentcheatcursloc]
ja .noconf
dec eax
mov dword[GUIcurrentcheatcursloc],eax
.noconf
cmp dword[NumCheats],0
jne .nozero
mov dword[GUIcurrentcheatcursloc],0
mov byte[CheatOn],0
call LOADDir
ret
.nozero
mov byte[CheatOn],1
call LOADDir
ret
.fail
pop ebx
pop eax
mov [fnamest+ebx],eax
call LOADDir
ret
CheatCodeRemove:
cmp dword[NumCheats],0
jne .nonone
mov byte[GUICBHold],0
ret
.nonone
mov byte[GUICBHold],0
mov esi,[GUIcurrentcheatcursloc]
shl esi,5
sub esi,[GUIcurrentcheatcursloc]
sub esi,[GUIcurrentcheatcursloc]
sub esi,[GUIcurrentcheatcursloc]
sub esi,[GUIcurrentcheatcursloc]
add esi,cheatdata
push esi
call DisableCheatCode
pop esi
mov eax,255
sub eax,[GUIcurrentcheatcursloc]
mov ebx,eax
shl eax,4
add eax,ebx
add eax,ebx
.loop
mov bl,[esi+28]
mov [esi],bl
inc esi
dec eax
jnz .loop
dec dword[NumCheats]
mov eax,[GUIcurrentcheatcursloc]
cmp dword[NumCheats],0
je .okay
cmp eax,[NumCheats]
jne .okay
dec dword[GUIcurrentcheatcursloc]
.okay
cmp byte[NumCheats],0
jne .cheatexists
mov byte[CheatOn],0
.cheatexists
ret
CheatCodeFix:
cmp dword[NumCheats],0
jne .nonone
mov byte[GUICBHold],0
ret
.nonone
mov byte[GUICBHold],0
call DisableCheatCode
mov esi,[GUIcurrentcheatcursloc]
shl esi,5
sub esi,[GUIcurrentcheatcursloc]
sub esi,[GUIcurrentcheatcursloc]
sub esi,[GUIcurrentcheatcursloc]
sub esi,[GUIcurrentcheatcursloc]
add esi,cheatdata
xor byte[esi+3],80h
call EnableCheatCodeNoPrevMod
ret
CheatCodeToggle:
cmp dword[NumCheats],0
jne .nonone
mov byte[GUICBHold],0
ret
.nonone
mov byte[GUICBHold],0
mov esi,[GUIcurrentcheatcursloc]
shl esi,5
sub esi,[GUIcurrentcheatcursloc]
sub esi,[GUIcurrentcheatcursloc]
sub esi,[GUIcurrentcheatcursloc]
sub esi,[GUIcurrentcheatcursloc]
add esi,cheatdata
test byte[esi],4
jz DisableCheatCode
jmp EnableCheatCodeNoPrevMod
DisableCheatCode:
; code is at esi
xor ecx,ecx
xor ebx,ebx
or byte[esi],4
test byte[esi],1
jnz .gfrom
mov al,[esi+5]
mov cx,[esi+2]
mov bl,[esi+4]
mov byte[writeon],1
test byte[esi],80h
jnz .nowrite
test byte[esi-28],80h
jnz .nowrite
call dword near [memtablew8+ebx*4]
.nowrite
mov byte[writeon],0
ret
.gfrom
mov al,[esi+5]
mov ecx,[esi+2]
and ecx,0FFFFFFh
mov esi,[romdata]
mov [esi+ecx],al
ret
.gfram
mov al,[esi+5]
mov ecx,[esi+2]
and ecx,0FFFFFFh
mov esi,[sram]
mov [esi+ecx],al
ret
EnableCheatCode:
; code is at esi
xor ecx,ecx
xor ebx,ebx
and byte[esi],0FBh
test byte[esi],1
jnz .gfrom
mov al,[esi+1]
mov cx,[esi+2]
mov bl,[esi+4]
push ecx
push eax
push ebx
push edx
call dword near [memtabler8+ebx*4]
pop edx
mov byte[esi+5],al
pop ebx
pop eax
pop ecx
mov byte[writeon],1
test byte[esi],80h
jnz .nowrite
test byte[esi-28],80h
jnz .nowrite
call dword near [memtablew8+ebx*4]
.nowrite
mov byte[writeon],0
ret
.gfrom
mov al,[esi+1]
mov ecx,[esi+2]
and ecx,0FFFFFFh
mov esi,[romdata]
mov bl,[esi+ecx]
mov [esi+ecx],al
mov [esi+5],bl
ret
.gfram
mov al,[esi+1]
mov ecx,[esi+2]
and ecx,0FFFFFFh
mov esi,[sram]
mov bl,[esi+ecx]
mov [esi+ecx],al
mov [esi+5],bl
ret
EnableCheatCodeNoPrevMod:
; code is at esi
xor ecx,ecx
xor ebx,ebx
and byte[esi],0FBh
test byte[esi],1
jnz .gfrom
mov al,[esi+1]
mov cx,[esi+2]
mov bl,[esi+4]
mov byte[writeon],1
test byte[esi],80h
jnz .nowrite
test byte[esi-28],80h
jnz .nowrite
call dword near [memtablew8+ebx*4]
.nowrite
mov byte[writeon],0
ret
.gfrom
mov al,[esi+1]
mov ecx,[esi+2]
and ecx,0FFFFFFh
mov esi,[romdata]
mov bl,[esi+ecx]
mov [esi+ecx],al
mov [esi+5],bl
ret
.gfram
mov al,[esi+1]
mov ecx,[esi+2]
and ecx,0FFFFFFh
mov esi,[sram]
mov bl,[esi+ecx]
mov [esi+ecx],al
mov [esi+5],bl
ret
AddCheatCode:
mov byte[GUICBHold],0
cmp dword[NumCheats],255
jne .okay
ret
.okay
push eax
push ebx
; transfer description
mov eax,[NumCheats]
shl eax,5
sub eax,[NumCheats]
sub eax,[NumCheats]
sub eax,[NumCheats]
sub eax,[NumCheats]
add eax,cheatdata
mov edx,eax
push edx
add eax,6
mov ebx,CSDescDisplay
mov ecx,20
.dloop
mov dl,[ebx]
mov [eax+2],dl
mov [eax+18+2],dl
mov [eax+18*2+2],dl
inc ebx
inc eax
loop .dloop
pop edx
pop ebx
pop eax
; toggle, value, address, pvalue, name(12)
mov byte[edx],0
mov [edx+1],bl
push eax
sub eax,7E0000h
add eax,[wramdata]
mov bh,[eax]
mov [eax],bl
pop eax
mov [edx+2],eax
mov [edx+5],bh
inc dword[NumCheats]
mov edx,7
mov al,[GUIpmenupos]
push eax
call CheckMenuItemHelp
pop eax
mov [GUIpmenupos],al
mov byte[CheatOn],1
ret
ProcessCheatCode:
mov byte[GUICBHold],0
cmp dword[NumCheats],255
je .fail
cmp byte[GUICheatPosA],0
je .fail
jmp .okay
.fail
ret
.okay
; make sure flashing cursor doesn't exist
xor ebx,ebx
mov bl,[GUICheatPosB]
mov byte[GUICheatTextA+ebx],0
; transfer description
mov eax,[NumCheats]
shl eax,5
sub eax,[NumCheats]
sub eax,[NumCheats]
sub eax,[NumCheats]
sub eax,[NumCheats]
add eax,cheatdata
add eax,6
mov ebx,GUICheatTextA
mov ecx,20
.dloop
mov dl,[ebx]
mov [eax+2],dl
mov [eax+18+2],dl
mov [eax+18*2+2],dl
inc ebx
inc eax
loop .dloop
; determine whether it is gamegenie, par, or GF
; uppercase all codes if necessary
mov eax,GUICheatText9
mov ecx,14
.loop
mov bl,[eax]
cmp bl,'a'
jb .nolower
cmp bl,'z'
ja .nolower
sub bl,'a'-'A'
mov [eax],bl
.nolower
inc eax
loop .loop
mov byte[guicheatvalrep],0
xor eax,eax
mov al,[GUICheatPosA]
dec al
cmp byte[GUICheatText9+eax],'R'
jne .notrep
mov byte[guicheatvalrep],80h
dec byte[GUICheatPosA]
.notrep
cmp byte[GUICheatPosA],8
je near .par
cmp byte[GUICheatPosA],9
je near .gg
cmp byte[GUICheatPosA],14
je near .gf
.invalidpar
jmp guicheaterror
.par
; check if code is valid
mov eax,GUICheatText9
mov ecx,8
.looppar
mov bl,[eax]
cmp bl,'0'
jb .invalidpar
cmp bl,'9'
jbe .okaypar
cmp bl,'A'
jb .invalidpar
cmp bl,'F'
ja .invalidpar
.okaypar
inc eax
loop .looppar
jmp decodepar
.invalidgg
jmp guicheaterror
.gg
; check if code is valid
mov eax,GUICheatText9
mov ecx,9
.loopgg
cmp ecx,5
jne .nomid
cmp byte[eax],'-'
jne .invalidgg
inc eax
dec ecx
.nomid
mov bl,[eax]
cmp bl,'0'
jb .invalidgg
cmp bl,'9'
jbe .okaygg
cmp bl,'A'
jb .invalidgg
cmp bl,'F'
ja .invalidgg
.okaygg
inc eax
loop .loopgg
jmp decodegg
ret
.invalidgf
jmp guicheaterror
.gf
; check if code is valid
mov eax,GUICheatText9
mov ecx,5
.loopgf
mov bl,[eax]
cmp bl,'0'
jb .invalidgf
cmp bl,'9'
jbe .okaygf
cmp bl,'A'
jb .invalidgf
cmp bl,'F'
ja .invalidgf
.okaygf
inc eax
loop .loopgf
mov eax,GUICheatText9+5
mov ecx,6
.loopgf2
mov bl,[eax]
cmp bl,'X'
je .okaygf2
cmp bl,'0'
jb .invalidgf
cmp bl,'9'
jbe .okaygf2
cmp bl,'A'
jb near .invalidgf
cmp bl,'F'
ja near .invalidgf
.okaygf2
inc eax
loop .loopgf2
mov bl,[GUICheatText9+13]
cmp bl,'0'
je .okaygf3
cmp bl,'1'
jne near .invalidgf
.okaygf3
jmp decodegf
decodegf:
; convert code to number format
mov ecx,14
mov esi,GUICheatText9
.loopb2
mov al,[esi]
cmp al,'X'
je .let2
cmp al,'A'
jb .num2
sub al,'A'
add al,10
jmp .let2
.num2
sub al,'0'
.let2
mov [esi],al
inc esi
dec ecx
jnz .loopb2
; get address
xor ebx,ebx
xor ecx,ecx
mov cl,[GUICheatText9]
shl ecx,4
add cl,[GUICheatText9+1]
shl ecx,4
add cl,[GUICheatText9+2]
shl ecx,4
add cl,[GUICheatText9+3]
shl ecx,4
add cl,[GUICheatText9+4]
mov edx,[NumCheats]
shl edx,5
sub edx,[NumCheats]
sub edx,[NumCheats]
sub edx,[NumCheats]
sub edx,[NumCheats]
; Write data to memory
cmp byte[GUICheatText9+13],1
je near .modifysram
; get data
cmp byte[GUICheatText9+5],'X'
je near .nocode
cmp byte[GUICheatText9+6],'X'
je near .nocode
mov bl,[GUICheatText9+5]
shl bl,4
add bl,[GUICheatText9+6]
mov esi,[romdata]
mov al,[esi+ecx]
mov [esi+ecx],bl
mov byte[cheatdata+edx],1
mov [cheatdata+edx+2],ecx
mov [cheatdata+edx+1],bl
mov [cheatdata+edx+5],al
push eax
mov al,[guicheatvalrep]
or [cheatdata+edx],al
pop eax
inc byte[NumCheats]
add edx,28
.nocode
inc ecx
cmp byte[GUICheatText9+7],'X'
je near .nocode1
cmp byte[GUICheatText9+8],'X'
je near .nocode1
cmp byte[NumCheats],255
je near .nocode1
mov bl,[GUICheatText9+7]
shl bl,4
add bl,[GUICheatText9+8]
mov esi,[romdata]
mov al,[esi+ecx]
mov [esi+ecx],bl
mov byte[cheatdata+edx],1
mov [cheatdata+edx+2],ecx
mov [cheatdata+edx+1],bl
mov [cheatdata+edx+5],al
inc byte[NumCheats]
add edx,28
.nocode1
inc ecx
cmp byte[GUICheatText9+9],'X'
je near .nocode2
cmp byte[GUICheatText9+10],'X'
je near .nocode2
cmp byte[NumCheats],255
je near .nocode2
mov bl,[GUICheatText9+9]
shl bl,4
add bl,[GUICheatText9+10]
mov esi,[romdata]
mov al,[esi+ecx]
mov [esi+ecx],bl
mov byte[cheatdata+edx],1
mov [cheatdata+edx+2],ecx
mov [cheatdata+edx+1],bl
mov [cheatdata+edx+5],al
inc byte[NumCheats]
.nocode2
jmp .quit
.modifysram
cmp ecx,65535
ja near .quit
mov esi,[sram]
; get data
cmp byte[GUICheatText9+5],'X'
je .nocodeb
cmp byte[GUICheatText9+6],'X'
je .nocodeb
mov bl,[GUICheatText9+5]
shl bl,4
add bl,[GUICheatText9+6]
mov al,[esi+ecx]
mov [esi+ecx],bl
mov byte[cheatdata+edx],2
mov [cheatdata+edx+2],ecx
mov [cheatdata+edx+1],bl
mov [cheatdata+edx+5],al
inc byte[NumCheats]
add edx,28
.nocodeb
inc ecx
cmp byte[GUICheatText9+7],'X'
je .nocode1b
cmp byte[GUICheatText9+8],'X'
je .nocode1b
cmp byte[NumCheats],255
je .nocode1b
cmp ecx,65535
ja .nocode1b
mov bl,[GUICheatText9+7]
shl bl,4
add bl,[GUICheatText9+8]
mov al,[esi+ecx+1]
mov [esi+ecx+1],bl
mov byte[cheatdata+edx],2
mov [cheatdata+edx+2],ecx
mov [cheatdata+edx+1],bl
mov [cheatdata+edx+5],al
inc byte[NumCheats]
add edx,28
.nocode1b
inc ecx
cmp byte[GUICheatText9+9],'X'
je .nocode2c
cmp byte[GUICheatText9+10],'X'
je .nocode2c
cmp byte[NumCheats],255
je .nocode2c
cmp ecx,65535
ja .nocode2c
mov bl,[GUICheatText9+9]
shl bl,4
add bl,[GUICheatText9+10]
mov al,[esi+ecx+2]
mov [esi+ecx+2],bl
mov byte[cheatdata+edx],2
mov [cheatdata+edx+2],ecx
mov [cheatdata+edx+1],bl
mov [cheatdata+edx+5],al
inc byte[NumCheats]
.nocode2c
.quit
cmp byte[NumCheats],0
je .nocheat
mov byte[CheatOn],1
mov dword[GUIcurrentcheatwin],1
mov eax,[NumCheats]
dec eax
mov [GUIcurrentcheatcursloc],eax
sub eax,11
mov [GUIcurrentcheatviewloc],eax
test dword[GUIcurrentcheatviewloc],80000000h
jz .noview
mov dword[GUIcurrentcheatviewloc],0
.noview
.nocheat
mov dword[GUICheatText9],0
mov dword[GUICheatTextA],0
mov byte[GUICheatPosA],0
mov byte[GUICheatPosB],0
ret
decodegg:
;Genie Hex: D F 4 7 0 9 1 5 6 B C 8 A 2 3 E
;Normal Hex: 0 1 2 3 4 5 6 7 8 9 A B C D E F
; 4 6 D E 2 7 8 3 B 5 C 9 A 0 F 1
; Convert code
mov esi,GUICheatText9
mov eax,[esi+5]
mov [esi+4],eax
; convert code to number format
mov ecx,8
xor eax,eax
.loopb3
mov al,[esi]
cmp al,'A'
jb .num3
sub al,'A'
add al,10
jmp .let3
.num3
sub al,'0'
.let3
mov al,[.GG2Norm+eax]
mov [esi],al
inc esi
dec ecx
jnz .loopb3
mov esi,GUICheatText9
xor ecx,ecx
mov cl,[esi+2]
shl ecx,4
add cl,[esi+3]
shl ecx,4
add cl,[esi+4]
shl ecx,4
add cl,[esi+5]
shl ecx,4
add cl,[esi+6]
shl ecx,4
add cl,[esi+7]
; 0123456789ABCDEF01234567
; 24bit encoded address: ijklqrstopabcduvwxefghmn
; abcdefghijklmnopqrstuvwx
; >8 >12 >6<10 >6 <14 <10
mov ebx,ecx
and ebx,000000000011110000000000b ;abcd
shl ebx,10
mov eax,ecx
and eax,000000000000000000111100b ;efgh
shl eax,14
add ebx,eax
mov eax,ecx
and eax,111100000000000000000000b ;ijkl
shr eax,8
add ebx,eax
mov eax,ecx
and eax,000000000000000000000011b ;mn
shl eax,10
add ebx,eax
mov eax,ecx
and eax,000000001100000000000000b ;op
shr eax,6
add ebx,eax
mov eax,ecx
and eax,000011110000000000000000b ;qrst
shr eax,12
add ebx,eax
mov eax,ecx
and eax,000000000000001111000000b ;uvwx
shr eax,6
add ebx,eax
xor ecx,ecx
mov cx,bx
shr ebx,16
test bl,40h
jz .noover
; xor cx,8000h
.noover
mov al,[esi]
shl al,4
add al,[esi+1]
; store into cheatdata
mov edx,[NumCheats]
shl edx,5
sub edx,[NumCheats]
sub edx,[NumCheats]
sub edx,[NumCheats]
sub edx,[NumCheats]
mov byte[cheatdata+edx],0
mov [cheatdata+edx+1],al
mov [cheatdata+edx+2],cx
mov [cheatdata+edx+4],bl
push eax
mov al,[guicheatvalrep]
or [cheatdata+edx],al
pop eax
push ecx
push eax
push ebx
push edx
call dword near [memtabler8+ebx*4]
pop edx
mov byte[cheatdata+edx+5],al
pop ebx
pop eax
pop ecx
mov byte[writeon],1
test byte[cheatdata+edx],80h
jnz .nowrite
test byte[cheatdata+edx-28],80h
jnz .nowrite
call dword near [memtablew8+ebx*4]
.nowrite
mov byte[writeon],0
mov byte[CheatOn],1
inc byte[NumCheats]
mov dword[GUICheatText9],0
mov dword[GUICheatTextA],0
mov byte[GUICheatPosA],0
mov byte[GUICheatPosB],0
mov dword[GUIcurrentcheatwin],1
mov eax,[NumCheats]
dec eax
mov [GUIcurrentcheatcursloc],eax
sub eax,11
mov [GUIcurrentcheatviewloc],eax
test dword[GUIcurrentcheatviewloc],80000000h
jz .noview
mov dword[GUIcurrentcheatviewloc],0
.noview
ret
.GG2Norm db 04h,06h,0Dh,0Eh,02h,07h,08h,03h,0Bh,05h,0Ch,09h,0Ah,00h,0Fh,01h
decodepar:
; convert code to number format
mov ecx,8
mov esi,GUICheatText9
.loopb
mov al,[esi]
cmp al,'A'
jb .num
sub al,'A'
add al,10
jmp .let
.num
sub al,'0'
.let
mov [esi],al
inc esi
dec ecx
jnz .loopb
; get address
xor ebx,ebx
xor ecx,ecx
mov bl,[GUICheatText9]
shl bl,4
add bl,[GUICheatText9+1]
mov cl,[GUICheatText9+2]
shl cx,4
add cl,[GUICheatText9+3]
shl cx,4
add cl,[GUICheatText9+4]
shl cx,4
add cl,[GUICheatText9+5]
mov al,[GUICheatText9+6]
shl al,4
add al,[GUICheatText9+7]
; store into cheatdata
xor edx,edx
mov dl,[NumCheats]
push ebx
mov ebx,edx
shl edx,5
sub edx,ebx
sub edx,ebx
sub edx,ebx
sub edx,ebx
pop ebx
mov byte[cheatdata+edx],0
mov [cheatdata+edx+1],al
mov [cheatdata+edx+2],cx
mov [cheatdata+edx+4],bl
push eax
mov al,[guicheatvalrep]
or [cheatdata+edx],al
pop eax
push ecx
push eax
push ebx
push edx
call dword near [memtabler8+ebx*4]
pop edx
mov byte[cheatdata+edx+5],al
pop ebx
pop eax
pop ecx
mov byte[writeon],1
test byte[cheatdata+edx],80h
jnz .nowrite
test byte[cheatdata+edx-28],80h
jnz .nowrite
call dword near [memtablew8+ebx*4]
.nowrite
mov byte[writeon],0
mov byte[CheatOn],1
inc dword[NumCheats]
mov dword[GUICheatText9],0
mov dword[GUICheatTextA],0
mov byte[GUICheatPosA],0
mov byte[GUICheatPosB],0
mov dword[GUIcurrentcheatwin],1
mov eax,[NumCheats]
dec eax
mov [GUIcurrentcheatcursloc],eax
sub eax,11
mov [GUIcurrentcheatviewloc],eax
test dword[GUIcurrentcheatviewloc],80000000h
jz .noview
mov dword[GUIcurrentcheatviewloc],0
.noview
ret
guicheaterror:
xor ebx,ebx
mov ecx,256+128+64
.a
mov byte[pressed+ebx],0
inc ebx
loop .a
.again
call GUIUnBuffer
call DisplayBoxes
call DisplayMenu
GUIBox 75,95,192,143,160
GUIBox 75,95,192,95,162
GUIBox 75,95,75,143,161
GUIBox 192,95,192,143,159
GUIBox 75,143,192,143,158
GUIOuttext 81,101,guicheaterror1,220-15
GUIOuttext 80,100,guicheaterror1,220
GUIOuttext 81,109,guicheaterror2,220-15
GUIOuttext 80,108,guicheaterror2,220
GUIOuttext 81,117,guicheaterror3,220-15
GUIOuttext 80,116,guicheaterror3,220
GUIOuttext 81,125,guicheaterror4,220-15
GUIOuttext 80,124,guicheaterror4,220
GUIOuttext 81,135,guicheaterror5,220-15
GUIOuttext 80,134,guicheaterror5,220
call vidpastecopyscr
call JoyRead
xor ebx,ebx
mov ecx,256+128+64
.b
cmp byte[pressed+ebx],0
jne .pressedokay
inc ebx
loop .b
cmp byte[MouseDis],1
je .mousedis
call Get_MouseData
test bx,01h
jnz .pressedokay
.mousedis
jmp .again
.pressedokay
.again2
call Check_Key
or al,al
jz .nokey
call Get_Key
jmp .again2
.nokey
cmp byte[MouseDis],1
je .mousedis2
push ebx
; mov eax,0Bh
; int 33h
pop ebx
.mousedis2
mov dword[GUIcurrentcheatwin],1
mov byte[GUIpclicked],1
ret
guicheaterror1 db 'INVALID CODE! YOU',0
guicheaterror2 db 'MUST ENTER A VALID',0
guicheaterror3 db 'GAME GENIE,PAR, OR',0
guicheaterror4 db 'GOLD FINGER CODE.',0
guicheaterror5 db 'PRESS ANY KEY.',0
guicheatvalrep db 0