Files
ZSNES/zsnes/src/gui/guicheat.inc
2001-04-02 22:30:58 +00:00

1340 lines
27 KiB
PHP
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
;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