quickdev16/tools/zsnes/src/gui/guicheat.inc
2009-04-22 20:04:28 +02:00

1166 lines
23 KiB
PHP

;Copyright (C) 1997-2007 ZSNES Team ( zsKnight, _Demo_, pagefault, Nach )
;
;http://www.zsnes.com
;http://sourceforge.net/projects/zsnes
;https://zsnes.bountysource.com
;
;This program is free software; you can redistribute it and/or
;modify it under the terms of the GNU General Public License
;version 2 as published by the Free Software Foundation.
;
;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.
SECTION .text
; 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,GUICSrcTextG1
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
dec ecx
jnz %%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,[CheatSrcByteSize]
sub ecx,ebx
mov edx,[SrcMask+ebx*4]
mov edi,[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
dec ecx
jnz .exactloop
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,[vidbuffer]
add eax,129600+65536*2
mov esi,[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
SECTION .bss
CopyRamToggle resb 1
FirstSearch resb 1
SECTION .text
CheatCodeSearchInit:
mov byte[CSInputDisplay],'_'
mov byte[CSInputDisplay+1],0
mov byte[CheatWinMode],1
mov byte[CheatSearchStatus],0
mov byte[FirstSearch],1
mov eax,[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
dec ecx
jnz .loop
; fill searched buffer with 0xFF
mov eax,[vidbuffer]
add eax,129600+65536*2
mov ecx,8192
.loop2
mov dword[eax],0FFFFFFFFh
add eax,4
dec ecx
jnz .loop2
cmp byte[CheatSrcSearchType],1
jne .nottype1
mov byte[CheatSearchStatus],1
.nottype1
mov dword[CheatCompareValue],0
mov eax,[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
NEWSYM DisableCheatsOnLoad
; Disable all codes
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
ret
NEWSYM EnableCheatsOnLoad
; 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
ret
CheatCodeRemove:
mov byte[GUICBHold],0
cmp dword[NumCheats],0
jne .nonone
ret
.nonone
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 eax
mov [GUIcurrentcheatcursloc],eax
sub eax,11
mov [GUIcurrentcheatviewloc],eax
test dword[GUIcurrentcheatviewloc],80000000h
jz .noview
mov dword[GUIcurrentcheatviewloc],0
.noview
.okay
cmp byte[NumCheats],0
jne .cheatexists
mov byte[CheatOn],0
.cheatexists
ret
CheatCodeFix:
mov byte[GUICBHold],0
cmp dword[NumCheats],0
jne .nonone
ret
.nonone
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
xor byte[esi+3],80h
call EnableCheatCodeNoPrevMod
ret
CheatCodeToggle:
mov byte[GUICBHold],0
cmp dword[NumCheats],0
jne .nonone
ret
.nonone
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 [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
dec ecx
jnz .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[GUICheatTextZ2+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,GUICheatTextZ2
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
dec ecx
jnz .dloop
; determine whether it is gamegenie, par, or GF
; uppercase all codes if necessary
mov eax,GUICheatTextZ1
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
dec ecx
jnz .loop
mov byte[guicheatvalrep],0
xor eax,eax
mov al,[GUICheatPosA]
dec al
cmp byte[GUICheatTextZ1+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,GUICheatTextZ1
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
dec ecx
jnz .looppar
jmp decodepar
.invalidgg
jmp guicheaterror
.gg
; check if code is valid
mov eax,GUICheatTextZ1
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
dec ecx
jnz .loopgg
jmp decodegg
ret
.invalidgf
jmp guicheaterror
.gf
; check if code is valid
mov eax,GUICheatTextZ1
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
dec ecx
jnz .loopgf
mov eax,GUICheatTextZ1+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
dec ecx
jnz .loopgf2
mov bl,[GUICheatTextZ1+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,GUICheatTextZ1
.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,[GUICheatTextZ1]
shl ecx,4
add cl,[GUICheatTextZ1+1]
shl ecx,4
add cl,[GUICheatTextZ1+2]
shl ecx,4
add cl,[GUICheatTextZ1+3]
shl ecx,4
add cl,[GUICheatTextZ1+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[GUICheatTextZ1+13],1
je near .modifysram
; get data
cmp byte[GUICheatTextZ1+5],'X'
je near .nocode
cmp byte[GUICheatTextZ1+6],'X'
je near .nocode
mov bl,[GUICheatTextZ1+5]
shl bl,4
add bl,[GUICheatTextZ1+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[GUICheatTextZ1+7],'X'
je near .nocode1
cmp byte[GUICheatTextZ1+8],'X'
je near .nocode1
cmp byte[NumCheats],255
je near .nocode1
mov bl,[GUICheatTextZ1+7]
shl bl,4
add bl,[GUICheatTextZ1+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[GUICheatTextZ1+9],'X'
je near .nocode2
cmp byte[GUICheatTextZ1+10],'X'
je near .nocode2
cmp byte[NumCheats],255
je near .nocode2
mov bl,[GUICheatTextZ1+9]
shl bl,4
add bl,[GUICheatTextZ1+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[GUICheatTextZ1+5],'X'
je .nocodeb
cmp byte[GUICheatTextZ1+6],'X'
je .nocodeb
mov bl,[GUICheatTextZ1+5]
shl bl,4
add bl,[GUICheatTextZ1+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[GUICheatTextZ1+7],'X'
je .nocode1b
cmp byte[GUICheatTextZ1+8],'X'
je .nocode1b
cmp byte[NumCheats],255
je .nocode1b
cmp ecx,65535
ja .nocode1b
mov bl,[GUICheatTextZ1+7]
shl bl,4
add bl,[GUICheatTextZ1+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[GUICheatTextZ1+9],'X'
je .nocode2c
cmp byte[GUICheatTextZ1+10],'X'
je .nocode2c
cmp byte[NumCheats],255
je .nocode2c
cmp ecx,65535
ja .nocode2c
mov bl,[GUICheatTextZ1+9]
shl bl,4
add bl,[GUICheatTextZ1+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[GUICheatTextZ1],0
mov dword[GUICheatTextZ2],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,GUICheatTextZ1
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,GUICheatTextZ1
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 [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[GUICheatTextZ1],0
mov dword[GUICheatTextZ2],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
SECTION .data
.GG2Norm db 04h,06h,0Dh,0Eh,02h,07h,08h,03h,0Bh,05h,0Ch,09h,0Ah,00h,0Fh,01h
SECTION .text
decodepar:
; convert code to number format
mov ecx,8
mov esi,GUICheatTextZ1
.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,[GUICheatTextZ1]
shl bl,4
add bl,[GUICheatTextZ1+1]
mov cl,[GUICheatTextZ1+2]
shl cx,4
add cl,[GUICheatTextZ1+3]
shl cx,4
add cl,[GUICheatTextZ1+4]
shl cx,4
add cl,[GUICheatTextZ1+5]
mov al,[GUICheatTextZ1+6]
shl al,4
add al,[GUICheatTextZ1+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 [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[GUICheatTextZ1],0
mov dword[GUICheatTextZ2],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
SECTION .bss
guicheatvalrep resb 1