2009-04-22 20:04:28 +02:00

910 lines
18 KiB
NASM

;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.
%include "macros.mac"
EXTSYM FPSOn,MessageOn,cbitmode,copyvid
EXTSYM MsgCount,Msgptr,OutputGraphicString,OutputGraphicString16b,vidbuffer
EXTSYM curblank,drawhline,drawhline16b,drawvline,drawvline16b,frameskip
EXTSYM pressed,dumpsound,Grab_BMP_Data,Grab_BMP_Data_8
EXTSYM spcon,vesa2_bpos,vesa2_clbit,vesa2_gpos,vesa2_rpos,
EXTSYM spritetablea,sprlefttot,newengen,Get_Key,continueprognokeys
EXTSYM ForceNonTransp,GUIOn,Check_Key,JoyRead,GetScreen,SSKeyPressed
EXTSYM SPCKeyPressed,StopSound,StartSound,ExecExitOkay,t1cc,Clear2xSaIBuffer
EXTSYM ScreenShotFormat,spcsaved,savespcdata
EXTSYM exiter,xpb,xpc,snesmmap,memtabler8,snesmap2,regaccessbankr8,dmadata,initaddrl
EXTSYM spcPCRam,xp,curcyc,Curtableaddr,UpdateDPage,splitflags,execsingle,joinflags
EXTSYM pdh,SPCRAM,cvidmode
%ifdef __MSDOS__
EXTSYM GUI16VID
%endif
%ifndef NO_DEBUGGER
EXTSYM numinst,debuggeron
%endif
%ifndef NO_PNG
EXTSYM Grab_PNG_Data
%endif
SECTION .text
GUIBufferData:
mov ecx,16000
cmp byte[cbitmode],1
jne near .16b
add ecx,16384
.16b
; copy to spritetable
mov esi,[vidbuffer]
mov edi,[spritetablea]
add esi,4*384
add edi,4*384
.loop
mov eax,[esi]
mov [edi],eax
add esi,4
add edi,4
dec ecx
jnz .loop
mov edi,sprlefttot
mov ecx,64*5
.a
mov dword[edi],0
add edi,4
dec ecx
jnz .a
ret
GUIUnBuffer:
mov ecx,16000
cmp byte[cbitmode],1
jne near .16b
add ecx,16384
.16b
; copy from spritetable
mov esi,[vidbuffer]
mov edi,[spritetablea]
add esi,4*384
add edi,4*384
.loop
mov eax,[edi]
mov [esi],eax
add esi,4
add edi,4
dec ecx
jnz .loop
ret
SECTION .bss
NEWSYM nextmenupopup, resb 1
NEWSYM NoInputRead, resb 1
NEWSYM PrevMenuPos, resb 1
NEWSYM MenuDisplace, resd 1
NEWSYM MenuDisplace16, resd 1
NEWSYM MenuNoExit, resb 1
NEWSYM SPCSave, resb 1
SECTION .text
NEWSYM showmenu
mov byte[ForceNonTransp],1
cmp byte[cbitmode],1
je near .nopalread
mov edi,[vidbuffer]
add edi,100000
mov dx,03C7h
mov al,0
out dx,al
mov dx,03C9h
mov ecx,768
mov byte[edi],12
inc edi
.b
in al,dx
shl al,2
mov [edi],al
inc edi
dec ecx
jnz .b
.nopalread
cmp byte[cbitmode],1
je near .nopal16b
; set palette of colors 128,144, and 160 to white, blue, and red
mov al,128
mov dx,03C8h
out dx,al
inc dx
mov al,63
out dx,al
out dx,al
out dx,al
mov al,144
mov dx,03C8h
out dx,al
inc dx
xor al,al
out dx,al
out dx,al
mov al,50
out dx,al
mov al,160
mov dx,03C8h
out dx,al
inc dx
mov al,45
out dx,al
xor al,al
out dx,al
out dx,al
.nopal16b
mov byte[NoInputRead],0
cmp byte[newengen],0
je .nong16b
cmp byte[cbitmode],0
je .nong16b
call GetScreen
.nong16b
cmp byte[SSKeyPressed],1
jne .nosskey
mov byte[SSKeyPressed],0
call saveimage
jmp .nopalwrite
.nosskey
cmp byte[SPCKeyPressed],1
je near .savespckey
test byte[pressed+14],1
jz .nof12
call saveimage
jmp .nopalwrite
.nof12
mov dword[menucloc],0
cmp byte[nextmenupopup],0
je .nomenuinc2
mov byte[pressed+1Ch],0
mov dword[menucloc],40*288
cmp byte[PrevMenuPos],1
jne .nomenuinc
mov dword[menucloc],50*288
.nomenuinc
cmp byte[PrevMenuPos],2
jne .nomenuinc2
mov dword[menucloc],60*288
.nomenuinc2
cmp byte[PrevMenuPos],3
jne .nomenuinc3
mov dword[menucloc],70*288
.nomenuinc3
mov dword[menudrawbox8b.stringi+13],' BMP'
%ifndef NO_PNG
cmp byte[ScreenShotFormat],0
je .normalscrn
%ifdef __MSDOS__
movzx eax,byte[cvidmode]
cmp byte[GUI16VID+eax],1
je .pngok
mov byte[ScreenShotFormat],0
jmp .normalscrn
%endif
.pngok
mov dword[menudrawbox8b.stringi+13],' PNG'
%endif
.normalscrn
mov byte[nextmenupopup],0
mov byte[menu16btrans],0
mov byte[pressed+1],0
mov byte[pressed+59],0
mov byte[curblank],00h
call GUIBufferData
; Draw box
call menudrawbox8b
call menudrawbox8b
cmp byte[newengen],0
je .notng
mov byte[GUIOn],1
.notng
pushad
call copyvid
popad
call StopSound
.nextkey
;call GUIUnBuffer
call menudrawbox8b
push eax
call copyvid
pop eax
call JoyRead
call Check_Key
or al,al
jz .nextkey
call Get_Key
cmp al,0
jne near .processextend
call Get_Key
cmp al,72
jne .noup
cmp dword[menucloc],0
jne .nogoup
add dword[menucloc],80*288
.nogoup
sub dword[menucloc],10*288
call menudrawbox8b
; mov al,[newengen] ; WTF?
; mov byte[newengen],0
; mov [newengen],al
jmp .nextkey
.noup
cmp al,80
jne .nodown
cmp dword[menucloc],70*288
jne .nogodown
sub dword[menucloc],80*288
.nogodown
add dword[menucloc],10*288
call menudrawbox8b
; mov al,[newengen]
; mov byte[newengen],0
; push eax
call copyvid
; pop eax
; mov [newengen],al
jmp .nextkey
.nodown
jmp .nextkey
.processextend
cmp al,27
je near .exitloop
cmp al,13
je .done
jmp .nextkey
.done
call GUIUnBuffer
; mov al,[newengen]
; mov byte[newengen],0
; push eax
call copyvid
; pop eax
; mov [newengen],al
cmp dword[menucloc],0
jne .nosaveimg
call saveimage
.nosaveimg
cmp dword[menucloc],40*288
jne .nosaveimg2
call saveimage
mov byte[ExecExitOkay],0
mov byte[nextmenupopup],3
mov byte[NoInputRead],1
mov byte[t1cc],0
mov byte[PrevMenuPos],0
.nosaveimg2
cmp dword[menucloc],50*288
jne .noskipframe
mov byte[ExecExitOkay],0
mov byte[nextmenupopup],3
mov byte[NoInputRead],1
mov byte[t1cc],0
mov byte[PrevMenuPos],1
.noskipframe
cmp dword[menucloc],70*288
jne .noimagechange
cmp byte[cbitmode],0
je .noimagechange
xor byte[ScreenShotFormat],1
mov byte[MenuNoExit],1
mov byte[ExecExitOkay],0
mov byte[nextmenupopup],1
mov byte[NoInputRead],1
mov byte[t1cc],0
mov byte[PrevMenuPos],3
.noimagechange
cmp dword[menucloc],60*288
jne .nomovewin
mov byte[MenuNoExit],1
mov byte[ExecExitOkay],0
mov byte[nextmenupopup],1
mov byte[NoInputRead],1
mov byte[t1cc],0
mov byte[PrevMenuPos],2
cmp dword[MenuDisplace],0
je .movewin
mov dword[MenuDisplace],0
mov dword[MenuDisplace16],0
jmp .nomovewin
.movewin
mov dword[MenuDisplace],90*288
mov dword[MenuDisplace16],90*288*2
.nomovewin
cmp dword[menucloc],10*288
jne .nofps
cmp byte[frameskip],0
je .yesfs
mov dword[Msgptr],.unablefps
mov eax,[MsgCount]
mov [MessageOn],eax
jmp .nofps
.yesfs
xor byte[FPSOn],1
.nofps
cmp dword[menucloc],20*288
jne near .nospcsave
.savespckey
cmp byte[spcon],0
je .nospc
mov dword[Msgptr],.search
mov eax,[MsgCount]
mov [MessageOn],eax
call copyvid
mov byte[SPCSave],1
call breakatsignb
mov byte[SPCSave],0
pushad
call savespcdata
popad
mov byte[curblank],40h
mov dword[Msgptr],spcsaved
mov eax,[MsgCount]
mov [MessageOn],eax
jmp .nospcsave
.nospc
mov dword[Msgptr],.nosound
mov eax,[MsgCount]
mov [MessageOn],eax
jmp .nospcsave
.unablespc
mov dword[Msgptr],.unable
mov eax,[MsgCount]
mov [MessageOn],eax
jmp .nospcsave
.yesesc
mov dword[Msgptr],.escpress
mov eax,[MsgCount]
mov [MessageOn],eax
.nospcsave
cmp dword[menucloc],30*288
jne .nosnddmp
pushad
call dumpsound
popad
mov dword[Msgptr],.sndbufsav
mov eax,[MsgCount]
mov [MessageOn],eax
.nosnddmp
cmp byte[SPCKeyPressed],1
jne .exitloop
mov byte[SPCKeyPressed],0
jmp .nopalwrite
.exitloop
call GUIUnBuffer
; mov al,[newengen]
; mov byte[newengen],0
; push eax
call copyvid
; pop eax
; mov [newengen],al
cmp byte[cbitmode],1
je near .nopalwrite
mov edi,[vidbuffer]
add edi,100000
mov dx,03C8h
mov al,0
out dx,al
mov dx,03C9h
mov ecx,768
inc edi
.c
mov al,[edi]
shr al,2
out dx,al
inc edi
dec ecx
jnz .c
.nopalwrite
mov eax,pressed
mov ecx,256
.looppr
cmp byte[eax],1
jne .notpr
mov byte[eax],2
.notpr
inc eax
dec ecx
jnz .looppr
; mov byte[pressed+1],2
; cmp byte[pressed+59],1
; jne .not59
; mov byte[pressed+59],2
;.not59
; cmp byte[pressed+28],1
; jne .not28
; mov byte[pressed+28],2
;.not28
call StartSound
mov byte[ForceNonTransp],0
mov byte[GUIOn],0
pushad
call Clear2xSaIBuffer
popad
cmp byte[MenuNoExit],1
je .noexitmenu
jmp continueprognokeys
.noexitmenu
mov byte[MenuNoExit],0
jmp showmenu
SECTION .data
.unablefps db 'NEED AUTO FRAMERATE ON',0
.sndbufsav db 'BUFFER SAVED AS SOUNDDMP.RAW',0
.search db 'SEARCHING FOR SONG START.',0
.nosound db 'SOUND MUST BE ENABLED.',0
.unable db 'CANNOT USE IN NEW GFX ENGINE.',0
.escpress db 'ESC TERMINATED SEARCH.',0
SECTION .text
NEWSYM menudrawbox8b
cmp byte[cbitmode],1
je near menudrawbox16b
; draw a small blue box with a white border
mov esi,40+20*288
add esi,[vidbuffer]
add esi,[MenuDisplace]
mov ecx,150
mov al,95
.loop
mov byte[esi],144
inc esi
dec ecx
jnz .loop
add esi,288-150
dec al
mov ecx,150
jnz .loop
mov al,128
; Draw lines
mov esi,40+20*288
add esi,[vidbuffer]
add esi,[MenuDisplace]
mov ecx,150
call drawhline
mov esi,40+20*288
add esi,[vidbuffer]
add esi,[MenuDisplace]
mov ecx,95
call drawvline
mov esi,40+114*288
add esi,[vidbuffer]
add esi,[MenuDisplace]
mov ecx,150
call drawhline
mov esi,40+32*288
add esi,[vidbuffer]
add esi,[MenuDisplace]
mov ecx,150
call drawhline
mov esi,189+20*288
add esi,[vidbuffer]
add esi,[MenuDisplace]
mov ecx,95
call drawvline
call menudrawcursor8b
mov esi,45+23*288
add esi,[vidbuffer]
add esi,[MenuDisplace]
mov edi,.string
call OutputGraphicString
mov esi,45+35*288
add esi,[vidbuffer]
add esi,[MenuDisplace]
mov edi,.stringa
call OutputGraphicString
mov esi,45+45*288
add esi,[vidbuffer]
add esi,[MenuDisplace]
mov edi,.stringb
test byte[FPSOn],1
jz .nofps
mov edi,.stringc
.nofps
call OutputGraphicString
mov esi,45+55*288
add esi,[vidbuffer]
add esi,[MenuDisplace]
mov edi,.stringd
call OutputGraphicString
mov esi,45+65*288
add esi,[vidbuffer]
add esi,[MenuDisplace]
mov edi,.stringe
call OutputGraphicString
mov esi,45+75*288
add esi,[vidbuffer]
add esi,[MenuDisplace]
mov edi,.stringf
call OutputGraphicString
mov esi,45+85*288
add esi,[vidbuffer]
add esi,[MenuDisplace]
mov edi,.stringg
call OutputGraphicString
mov esi,45+95*288
add esi,[vidbuffer]
add esi,[MenuDisplace]
mov edi,.stringh
call OutputGraphicString
mov esi,45+105*288
add esi,[vidbuffer]
add esi,[MenuDisplace]
mov edi,.stringi
call OutputGraphicString
; mov al,[newengen]
; mov byte[newengen],0
; push eax
call copyvid
; pop eax
; mov [newengen],al
ret
SECTION .data
.string db 'MISC OPTIONS',0
.stringa db 'SAVE SNAPSHOT',0
.stringb db 'SHOW FPS',0
.stringc db 'HIDE FPS',0
.stringd db 'SAVE SPC DATA',0
.stringe db 'SOUND BUFFER DUMP',0
.stringf db 'SNAPSHOT/INCR FRM',0
.stringg db 'INCR FRAME ONLY',0
.stringh db 'MOVE THIS WINDOW',0
.stringi db 'IMAGE FORMAT: ---',0
SECTION .text
NEWSYM menudrawcursor8b
cmp byte[cbitmode],1
je near menudrawcursor16b
; draw a small red box
mov esi,41+34*288
add esi,[menucloc]
add esi,[vidbuffer]
add esi,[MenuDisplace]
mov ecx,148
mov al,9
.loop
mov byte[esi],160
inc esi
dec ecx
jnz .loop
add esi,288-148
dec al
mov ecx,148
jnz .loop
mov al,128
ret
SECTION .bss
NEWSYM menucloc, resd 1
SECTION .text
NEWSYM menudrawbox16b
; draw shadow behind box
cmp byte[menu16btrans],0
jne .noshadow
mov byte[menu16btrans],1
mov esi,50*2+30*288*2
add esi,[vidbuffer]
add esi,[MenuDisplace16]
mov ecx,150
mov al,95
mov ah,5
.loop16b2
mov dx,[esi]
and dx,[vesa2_clbit]
shr dx,1
mov [esi],dx
add esi,2
dec ecx
jnz .loop16b2
add esi,288*2-150*2
dec al
mov ecx,150
jnz .loop16b2
.noshadow
mov ax,01Fh
mov cl,[vesa2_rpos]
shl ax,cl
mov [.allred],ax
mov ax,012h
mov cl,[vesa2_bpos]
shl ax,cl
mov dx,ax
mov ax,01h
mov cl,[vesa2_gpos]
shl ax,cl
mov bx,ax
mov ax,01h
mov cl,[vesa2_rpos]
shl ax,cl
or bx,ax
; draw a small blue box with a white border
mov esi,40*2+20*288*2
add esi,[vidbuffer]
add esi,[MenuDisplace16]
mov ecx,150
mov al,95
mov ah,5
.loop16b
mov [esi],dx
add esi,2
dec ecx
jnz .loop16b
add esi,288*2-150*2
dec ah
jnz .nocolinc16b
add dx,bx
mov ah,5
.nocolinc16b
dec al
mov ecx,150
jnz .loop16b
; Draw lines
mov ax,0FFFFh
mov esi,40*2+20*288*2
add esi,[vidbuffer]
add esi,[MenuDisplace16]
mov ecx,150
call drawhline16b
mov esi,40*2+20*288*2
add esi,[vidbuffer]
add esi,[MenuDisplace16]
mov ecx,95
call drawvline16b
mov esi,40*2+114*288*2
add esi,[vidbuffer]
add esi,[MenuDisplace16]
mov ecx,150
call drawhline16b
mov esi,40*2+32*288*2
add esi,[vidbuffer]
add esi,[MenuDisplace16]
mov ecx,150
call drawhline16b
mov esi,189*2+20*288*2
add esi,[vidbuffer]
add esi,[MenuDisplace16]
mov ecx,95
call drawvline16b
call menudrawcursor16b
mov esi,45*2+23*288*2
add esi,[vidbuffer]
add esi,[MenuDisplace16]
mov edi,menudrawbox8b.string
call OutputGraphicString16b
mov esi,45*2+35*288*2
add esi,[vidbuffer]
add esi,[MenuDisplace16]
mov edi,menudrawbox8b.stringa
call OutputGraphicString16b
mov esi,45*2+45*288*2
add esi,[vidbuffer]
add esi,[MenuDisplace16]
mov edi,menudrawbox8b.stringb
test byte[FPSOn],1
jz .nofps
mov edi,menudrawbox8b.stringc
.nofps
call OutputGraphicString16b
mov esi,45*2+55*288*2
add esi,[vidbuffer]
add esi,[MenuDisplace16]
mov edi,menudrawbox8b.stringd
call OutputGraphicString16b
mov esi,45*2+65*288*2
add esi,[vidbuffer]
add esi,[MenuDisplace16]
mov edi,menudrawbox8b.stringe
call OutputGraphicString16b
mov esi,45*2+75*288*2
add esi,[vidbuffer]
add esi,[MenuDisplace16]
mov edi,menudrawbox8b.stringf
call OutputGraphicString16b
mov esi,45*2+85*288*2
add esi,[vidbuffer]
add esi,[MenuDisplace16]
mov edi,menudrawbox8b.stringg
call OutputGraphicString16b
mov esi,45*2+95*288*2
add esi,[vidbuffer]
add esi,[MenuDisplace16]
mov edi,menudrawbox8b.stringh
call OutputGraphicString16b
mov esi,45*2+105*288*2
add esi,[vidbuffer]
add esi,[MenuDisplace16]
mov edi,menudrawbox8b.stringi
call OutputGraphicString16b
; mov al,[newengen]
; mov byte[newengen],0
; push eax
call copyvid
; pop eax
; mov [newengen],al
ret
SECTION .bss
.allred resw 1
.blue resw 1
.stepb resw 1
NEWSYM menu16btrans, resb 1
SECTION .text
NEWSYM menudrawcursor16b
; draw a small red box
mov esi,41*2+34*288*2
add esi,[menucloc]
add esi,[menucloc]
add esi,[vidbuffer]
add esi,[MenuDisplace16]
mov ecx,148
mov al,9
mov bx,[menudrawbox16b.allred]
.loop
mov [esi],bx
add esi,2
dec ecx
jnz .loop
add esi,288*2-148*2
dec al
mov ecx,148
jnz .loop
mov al,128
ret
saveimage:
mov byte[pressed+1],0
mov byte[pressed+59],0
%ifndef NO_PNG
cmp byte[ScreenShotFormat],1
jne .notpng
pushad
call Grab_PNG_Data
popad
ret
.notpng
%endif
cmp byte[cbitmode],1
je near .save16b
pushad
call Grab_BMP_Data_8
popad
ret
.save16b
pushad
call Grab_BMP_Data
popad
ret
SECTION .data
NEWSYM keyonsn, db 0
NEWSYM prbreak, db 0
SECTION .text
breakatsignb:
mov byte[keyonsn],0
mov byte[prbreak],0
%ifndef NO_DEBUGGER
cmp byte[SPCSave],1
jne .nospcsave
mov byte[debuggeron],1
.nospcsave
%endif
mov byte[exiter],01h
xor eax,eax
xor ebx,ebx
xor ecx,ecx
xor edx,edx
mov bl,[xpb]
mov ax,[xpc]
test ax,8000h
jz .loweraddr
mov esi,[snesmmap+ebx*4]
jmp .skiplower
.loweraddr
cmp ax,4300h
jb .lower
cmp dword[memtabler8+ebx*4],regaccessbankr8
je .dma
.lower
mov esi,[snesmap2+ebx*4]
jmp .skiplower
.dma
mov esi,dmadata-4300h
.skiplower
mov [initaddrl],esi
add esi,eax ; add program counter to address
mov ebp,[spcPCRam]
mov dl,[xp] ; set flags
mov dh,[curcyc] ; set cycles
mov edi,[Curtableaddr]
call UpdateDPage
; execute
.loopa
call splitflags
call execsingle
call joinflags
mov dh,[pdh]
%ifndef NO_DEBUGGER
inc dword[numinst]
cmp byte[numinst],0
jne .skipa
call Check_Key
test al,0FFh
jz .skipa
call Get_Key
cmp al,27
je .skipc
.skipa
%endif
cmp byte[SPCRAM+6],40h
je .skipc
cmp byte[keyonsn],1
jne .loopa
jmp .noesc
.skipc
mov byte[prbreak],1
.noesc
; copy back data
mov [spcPCRam],ebp
mov [Curtableaddr],edi
mov [xp],dl
mov [curcyc],dh
mov eax,[initaddrl]
sub esi,eax ; subtract program counter by address
mov [xpc],si
mov byte[exiter],0
%ifndef NO_DEBUGGER
cmp byte[SPCSave],1
jne .nospcsave2
mov byte[debuggeron],0
.nospcsave2
%endif
ret