Files
ZSNES/zsnes/src/gui/menu.asm

1619 lines
32 KiB
NASM

;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.
%include "macros.mac"
EXTSYM DSPMem,FPSOn,Makemode7Table,MessageOn,vesa2red10,scanlines,smallscreenon
EXTSYM MsgCount,Msgptr,OutputGraphicString,OutputGraphicString16b
EXTSYM PrepareSaveState,ResetState,breakatsignb,breakatsignc,cvidmode
EXTSYM cbitmode,copyvid,curblank,drawhline,drawhline16b,drawvline
EXTSYM drawvline16b,fnames,frameskip,mode7tab,pressed,spcA
EXTSYM spcBuffera,spcNZ,spcP,spcPCRam,spcRam,spcRamDP,spcS,spcX,spcY
EXTSYM spcon,vesa2_bpos,vesa2_clbit,vesa2_gpos,vesa2_rpos,vesa2selec
EXTSYM vidbuffer,spritetablea,sprlefttot,newengen,spcextraram,resolutn
EXTSYM Open_File,Close_File,Read_File,Write_File,Create_File,Get_Key,Get_Date
EXTSYM continueprognokeys,ForceNonTransp,GUIOn,Check_Key,JoyRead
EXTSYM GetScreen,SSKeyPressed,SPCKeyPressed,StopSound,StartSound
EXTSYM ExecExitOkay,t1cc
EXTSYM Clear2xSaIBuffer
EXTSYM romdata,romtype,ScreenShotFormat
EXTSYM Voice0Disable,Voice1Disable,Voice2Disable,Voice3Disable
EXTSYM Voice4Disable,Voice5Disable,Voice6Disable,Voice7Disable
EXTSYM SRAMChdir, SPCPath, SnapPath, Change_Dir, CHPath, ZFileCHDir
%ifndef NO_PNG
EXTSYM Grab_PNG_Data
%endif
%macro ChangeDir 1
cmp byte[%1],0
je %%end
pushad
mov ebx,%1
mov [CHPath],ebx
call ZFileCHDir
popad
%%end
%endmacro
%macro ChangeDirSRAM 0
pushad
call SRAMChdir
popad
%endmacro
GUIBufferData:
mov ecx,16384
cmp byte[cbitmode],1
jne near .16b
add ecx,16384
.16b
; copy to spritetable
mov esi,[vidbuffer]
mov edi,[spritetablea]
.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,16384
cmp byte[cbitmode],1
jne near .16b
add ecx,16384
.16b
; copy from spritetable
mov esi,[vidbuffer]
mov edi,[spritetablea]
.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
%ifdef SPCDUMP
SECTION .data
NEWSYM SPCSave_dump, db 0
SECTION .bss
EXTSYM SPCSave_buffer, SPCSave_ports
NEWSYM SPCSave_handle, resd 1
%endif
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 savepcx
jmp .nopalwrite
.nosskey
cmp byte[SPCKeyPressed],1
je near .savespckey
test byte[pressed+14],1
jz .nof12
call savepcx
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
mov dword[menudrawbox8b.stringi+13],' PNG'
%endif
.normalscrn
cmp byte[cbitmode],1
je near .nopcx
mov dword[menudrawbox8b.stringi+13],' PCX'
.nopcx
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 .nosavepcx
call savepcx
.nosavepcx
cmp dword[menucloc],40*288
jne .nosavepcx2
call savepcx
mov byte[ExecExitOkay],0
mov byte[nextmenupopup],3
mov byte[NoInputRead],1
mov byte[t1cc],0
mov byte[PrevMenuPos],0
.nosavepcx2
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
%ifdef SPCDUMP
cmp byte[SPCSave_dump], 1
jne .start_dump
mov ebx, [SPCSave_handle]
mov eax, -1
mov [SPCSave_buffer], eax
mov ecx, 4
mov edx, SPCSave_buffer
call Write_File
call Close_File
mov byte[SPCSave_dump], 0
jmp .nospcsave
.start_dump
%endif
; cmp byte[newengen],1
; je .unablespc
mov dword[Msgptr],.search
mov eax,[MsgCount]
mov [MessageOn],eax
; mov al,[newengen]
; mov byte[newengen],0
; push eax
call copyvid
; pop eax
; mov [newengen],al
; call breakatsignc
; cmp byte[prbreak],1
; je .yesesc
mov byte[SPCSave],1
call breakatsignb
mov byte[SPCSave],0
; cmp byte[prbreak],1
; je .yesesc
call savespcdata
mov byte[curblank],40h
mov dword[Msgptr],.saved
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
call dumpsound
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
call Clear2xSaIBuffer
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
.saved db '.SPC FILE SAVED.',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,85
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
NEWSYM savespcdata
sub dword[spcPCRam],spcRam
; Assemble N/Z flags into P
and byte[spcP],0FDh
test byte[spcNZ],0FFh
jnz .nozero
or byte[spcP],02h
.nozero
and byte[spcP],07Fh
test byte[spcNZ],80h
jz .noneg
or byte[spcP],80h
.noneg
mov ax,[spcPCRam]
mov [ssdatst+37],ax
mov al,[spcA]
mov [ssdatst+39],al
mov al,[spcX]
mov [ssdatst+40],al
mov al,[spcY]
mov [ssdatst+41],al
mov al,[spcP]
mov [ssdatst+42],al
mov al,[spcS]
mov [ssdatst+43],al
add dword[spcPCRam],spcRam
.savestuff
ChangeDir SPCPath
pushad
call PrepareSaveState
popad
; Copy from fnames to .spcfname, replacing .srm with .spc
mov esi,fnames+1
mov edi,.spcfname
.next
mov al,[esi]
mov [edi],al
inc esi
inc edi
cmp al,'.'
jne .next
; Save stuff
mov byte[edi],'s'
mov byte[edi+1],'p'
mov byte[edi+2],'c'
mov byte[edi+3],0
; Find an unoccupied file
.tryagainspc
mov edx,.spcfname
call Open_File
jc .nofileopen
mov bx,ax
call Close_File
cmp byte[edi+2],'c'
jne .notc
mov byte[edi+2],'1'
jmp .tryagainspc
.notc
cmp byte[edi+2],'9'
je .donext10
inc byte[edi+2]
jmp .tryagainspc
.donext10
mov al,[edi+1]
cmp al,[edi+2]
je .nofileopen
cmp byte[edi+1],'p'
jne .notp
mov byte[edi+1],'0'
.notp
inc byte[edi+1]
mov byte[edi+2],'0'
jmp .tryagainspc
.nofileopen
xor al,al
mov al,[edi+1]
mov [showmenu.saved+2],al
mov al,[edi+2]
mov [showmenu.saved+3],al
; copy spcextra ram to dspmem+192
mov esi,spcextraram
mov edi,DSPMem+192
mov ecx,64
.loop
mov al,[esi]
mov [edi],al
inc esi
inc edi
dec ecx
jnz .loop
; Copy Game Title
mov esi,[romdata]
add esi,7FC0h
cmp byte[romtype],2
jne .nohirom2
add esi,8000h
.nohirom2
mov ecx,20
mov edi,ssdatst+46+32
.romloop
mov al,[esi]
mov [edi],al
inc esi
inc edi
dec ecx
jnz .romloop
; Copy Date of spc dumped
call Get_Date
mov [ssdatst+09Eh],dl
mov [ssdatst+09Fh],dh
mov [ssdatst+0A0h],cx
; Set Channel Disables
mov byte[ssdatst+0D0h],0
cmp byte[Voice0Disable],1
je .enable0
or byte[ssdatst+0D0h],1
.enable0
cmp byte[Voice1Disable],1
je .enable1
or byte[ssdatst+0D0h],2
.enable1
cmp byte[Voice2Disable],1
je .enable2
or byte[ssdatst+0D0h],4
.enable2
cmp byte[Voice3Disable],1
je .enable3
or byte[ssdatst+0D0h],8
.enable3
cmp byte[Voice4Disable],1
je .enable4
or byte[ssdatst+0D0h],16
.enable4
cmp byte[Voice5Disable],1
je .enable5
or byte[ssdatst+0D0h],32
.enable5
cmp byte[Voice6Disable],1
je .enable6
or byte[ssdatst+0D0h],64
.enable6
cmp byte[Voice7Disable],1
je .enable7
or byte[ssdatst+0D0h],128
.enable7
; times 32 ; Title of game (Offset 48)
; times 32 ; Song Name
; times 32 ; Author of Song
; times 32 ; Name of dumper
; times 32 ; Comments
; times 4 ; date of spc dumped
; times 4 ; time in milliseconds before fading out
; times 2 ; fade-out length in milliseconds
; 0 ; default channel enables
mov edx,.spcfname
call Create_File
mov bx,ax
mov ecx,256
mov edx,ssdatst
call Write_File
; Save SPC stuff
mov ecx,65536
mov edx,spcRam
call Write_File
mov ecx,256
mov edx,DSPMem
call Write_File
%ifdef SPCDUMP
mov [SPCSave_handle], ebx
%else
call Close_File
%endif
pushad
call ResetState
popad
%ifdef SPCDUMP
; w00t, reg dump crapola
; using a time reference because I don't feel like adding
; cycle counting to the SPC emulation just for this
mov byte[SPCSave_dump],1
mov eax, [spcRam+0F4h]
mov [SPCSave_ports], eax
xor eax, eax
mov [SPCSave_buffer], eax
%endif
ChangeDirSRAM
ret
SECTION .bss
.spcfname resb 128
SECTION .data
;.SPC File Format
;Offset 00000h - File Header : SNES-SPC700 Sound File Data v0.10
;Offset 00021h - 0x26,0x26,0x26
;Offset 00024h - Version #(/100)
;Offset 00025h - PC Register value (1 Word)
;Offset 00027h - A Register Value (1 byte)
;Offset 00028h - X Register Value (1 byte)
;Offset 00029h - Y Register Value (1 byte)
;Offset 0002Ah - Status Flags Value (1 byte)
;Offset 0002Bh - Stack Register Value (1 byte)
;Offset 0002Ch-000FFh - Reserved For Future Use
;Offset 00100h-100FFh - SPCRam
;Offset 10100h-101FFh - DSPRam
;Offset 0002Eh-0004Dh - SubTitle/Song Name
;Offset 0004Eh-0006Dh - Title of Game
;Offset 0006Eh-0007Dh - Name of Dumper
;Offset 0007Eh-0009Dh - Comments
;Offset 0009Eh-000A4h - Date of SPC Dumped in decimal (DD/MM/YYYY)
;Offset 000A9h-000ABh - Time in seconds for the spc to play before fading
;Offset 000ACh-000AFh - Fade out time in milliseconds
;Offset 000B0h-000CFh - Author of Song
;Offset 000D0h - Default Channel Disables (0 = enable, 1 = disable)
;Offset 000D1h - Emulator used to dump .spc file
; (0 = UNKNOWN, 1 = ZSNES, 2 = SNES9X)
; (Note : Contact the authors if you're an snes emu
; author with an .spc capture in order to assign
; you a number)
;Offset 0002Eh-0004Dh - Name of SPC (32 bytes)
;Offset 0004Eh-0005Dh - Name of Game (16 bytes)
;Offset 0006Eh-0007Dh - Name of SPC dumper (16 bytes)
;Offset 0007Eh-0009Dh - Comments (32 bytes)
;Offset 0009Eh-000A8h - Date the SPC was Dumped (10 bytes)
;Offset 000A9h-000ABh - Internal SPC timer (3 bytes)
NEWSYM ssdatst
db 'SNES-SPC700 Sound File Data v0.30',26,26,26 ; offset 0
db 10 ; Version #(/100), offset 36
; SPC Registers
dw 0 ; PC, offset 37
db 0 ; A, offset 39
db 0 ; X, offset 40
db 0 ; Y, offset 41
db 0 ; P, offset 42
db 0 ; S, offset 43
db 0,0 ; offset 44 (reserved)
times 32 db 0 ; Title of game (Offset 46)
times 32 db 0 ; Song Name
times 16 db 0 ; Name of dumper
times 32 db 0 ; Comments
times 10 db 0 ; date of spc dumped
times 4 db 0 ; time in seconds before fading out
times 4 db 0 ; fade-out length in milliseconds
times 32 db 0 ; Author of Song
db 0 ; default channel enables
db 1 ; emulator used to dump .spc files
; 32*5+20 = 180
times 48 db 0 ;(reserved), offset 224
; SPCRAM (offset 256), 64k
; DSPRAM (offset 256+65536), 256 bytes
SECTION .text
NEWSYM dumpsound
mov cx,0
mov edx,.filename
call Create_File
; Process sound data
mov bx,ax
xor ecx,ecx
xor esi,esi
.loop
push eax
mov eax,[spcBuffera]
mov edx,dword[eax+ecx*4]
pop eax
cmp edx,0
je .nowrite
mov [mode7tab+esi],edx
add esi,4
cmp esi,65536
je .savenow
.return
.nowrite
inc cx
jnz .loop
cmp esi,0
je .nosave
mov ecx,esi
mov edx,mode7tab
call Write_File
.nosave
call Close_File
call Makemode7Table
ret
.savenow
push ecx
mov ecx,65536
mov edx,mode7tab
call Write_File
pop ecx
xor esi,esi
jmp .return
SECTION .data
.filename db 'SOUNDDMP.RAW',0
NEWSYM pcxheader
db 10,5,1,8
dw 0,0,255,223
dw 256,224
times 48 db 0
db 0,1
.bpline dw 256
times 128-68 db 0
SECTION .bss
NEWSYM picnum, resw 1
SECTION .data
NEWSYM savepcx
%ifndef NO_PNG
cmp byte[ScreenShotFormat],1
jne .notpng
ChangeDir SnapPath
pushad
call Grab_PNG_Data
popad
ChangeDirSRAM
ret
.notpng
%endif
mov byte[pressed+1],0
mov byte[pressed+59],0
cmp byte[cbitmode],1
je near .save16b
mov edi,pcxheader
mov ecx,128
.clearhead
mov byte[edi],0
inc edi
dec ecx
jnz .clearhead
mov byte[pcxheader+0],10
mov byte[pcxheader+1],5
mov byte[pcxheader+2],1
mov byte[pcxheader+3],8
mov word[pcxheader+8],255
mov word[pcxheader+10],222
mov byte[pcxheader.bpline-1],1
mov word[pcxheader.bpline],256
cmp byte[resolutn],224
je .res224ph
mov word[pcxheader+10],237
.res224ph
ChangeDir SnapPath
mov ecx,0 ;GetFreeFile use ecx==0 to tell if it's PCX
call GetFreeFile
call Create_File
; Save header
mov bx,ax
mov ecx,128
mov edx,pcxheader
call Write_File
; Save picture Data
mov byte[.rowsleft],223
cmp byte[resolutn],224
je .res224p
mov byte[.rowsleft],238
.res224p
mov ecx,256
mov edx,[vidbuffer]
add edx,16+288
.a
xor ecx,ecx
mov esi,edx
mov edi,mode7tab
push ebx
mov ebx,256
.loopp
mov al,[esi]
mov [edi],al
mov ah,al
and ah,0C0h
cmp ah,0C0h
jne .norep
mov byte[edi],0C1h
inc edi
inc ecx
mov byte[edi],al
.norep
inc ecx
inc esi
inc edi
dec ebx
jnz .loopp
pop ebx
xor al,al
push edx
mov edx,mode7tab
call Write_File
pop edx
add edx,288
dec byte[.rowsleft]
jnz .a
; Save Palette
mov ecx,769
mov edx,[vidbuffer]
add edx,100000
call Write_File
call Makemode7Table
call Close_File
; mov dword[Msgptr],.pcxsaved
; mov eax,[MsgCount]
; mov [MessageOn],eax
ChangeDirSRAM
ret
.save16b
test byte[pressed+14],1
jnz near save16b2
call prepare16b
mov edi,pcxheader
mov ecx,128
.clearhead2
mov byte[edi],0
inc edi
dec ecx
jnz .clearhead2
; Initial header = 14 bytes
mov byte[pcxheader],'B'
mov byte[pcxheader+1],'M'
mov dword[pcxheader+2],02A01Ah-768
mov dword[pcxheader+10],26
mov dword[pcxheader+14],12
mov word[pcxheader+18],256
mov word[pcxheader+20],223
mov word[pcxheader+22],1
mov word[pcxheader+24],24
cmp byte[resolutn],224
je .res224b
add dword[pcxheader+2],768*15
mov word[pcxheader+20],238
.res224b
ChangeDir SnapPath
mov ecx,1 ;GetFreeFile use ecx==1 to tell if it's BMP
call GetFreeFile
call Create_File
; Save header
mov bx,ax
mov ecx,26
mov edx,pcxheader
call Write_File
; Save picture Data
mov byte[.rowsleft],223
mov esi,[vidbuffer]
add esi,32+288*2*223
cmp byte[resolutn],224
je .res224b2
mov byte[.rowsleft],238
add esi,288*2*15
.res224b2
mov [.curdptr],esi
.a2
mov ecx,256
mov edi,mode7tab
mov esi,[.curdptr]
sub dword[.curdptr],288*2
.b2
push ecx
mov ax,[esi]
mov cl,[vesa2_bpos]
shr ax,cl
and ax,1Fh
shl al,3
mov byte[edi],al
mov ax,[esi]
mov cl,[vesa2_gpos]
shr ax,cl
and ax,1Fh
shl al,3
mov byte[edi+1],al
mov ax,[esi]
mov cl,[vesa2_rpos]
shr ax,cl
and ax,1Fh
shl al,3
mov byte[edi+2],al
pop ecx
add edi,3
add esi,2
dec ecx
jnz .b2
push edx
mov ecx,768
mov edx,mode7tab
call Write_File
pop edx
add edx,288*2
dec byte[.rowsleft]
jnz near .a2
call Makemode7Table
call Close_File
; mov dword[Msgptr],.rawsaved
; mov eax,[MsgCount]
; mov [MessageOn],eax
call restore16b
ChangeDirSRAM
ret
SECTION .bss
.rowsleft resb 1
.curdptr resd 1
SECTION .text
NEWSYM GetFreeFile
%ifdef __MSDOS__
cmp ecx,0
jne .isbmp
mov byte[.filename+9],'p'
mov byte[.filename+10],'c'
mov byte[.filename+11],'x'
jmp .doneextselect
.isbmp
mov byte[.filename+9],'b'
mov byte[.filename+10],'m'
mov byte[.filename+11],'p'
.doneextselect
mov byte[.filename+12],0
mov word[picnum],0
.findagain
mov edx,.filename
call Open_File
jc near .nofile
mov bx,ax
call Close_File
inc word[picnum]
cmp word[picnum],1000
je .nofile
mov ax,[picnum]
xor edx,edx
mov bx,100
div bx
mov cl,al
mov ax,dx
xor edx,edx
mov bx,10
div bx
mov esi,.filename+5
add cl,48
add al,48
add dl,48
mov esi,.filename+5
mov byte[esi],cl
mov byte[esi+1],al
mov byte[esi+2],dl
jmp .findagain
.nofile
mov edx,.filename
%else
mov esi,fnames+1
mov ebx,.imagefname
.end1
mov al,[esi]
inc esi
cmp al,0
jne .end1
.end2
dec esi
mov al,[esi]
cmp al,'.'
jne .end2
mov edx,fnames+1
.next
mov al,[edx]
mov [ebx],al
inc edx
inc ebx
cmp edx,esi
jne .next
mov esi,ebx
mov byte[esi],' '
mov byte[esi+1],'0'
mov byte[esi+2],'0'
mov byte[esi+3],'0'
mov byte[esi+4],'0'
mov byte[esi+5],'.'
cmp ecx,0
jne .isbmp
mov byte[esi+6],'p'
mov byte[esi+7],'c'
mov byte[esi+8],'x'
jmp .doneextselect
.isbmp
mov byte[esi+6],'b'
mov byte[esi+7],'m'
mov byte[esi+8],'p'
.doneextselect
mov byte[esi+9],0
mov word[picnum],0
.findagain
mov edx,.imagefname
call Open_File
jc near .nofile
mov bx,ax
call Close_File
inc word[picnum]
cmp word[picnum],10000
je .nofile
mov ax,[picnum]
xor edx,edx
mov bx,1000
div bx
add al,48
mov byte[esi+1],al
mov ax,dx
xor edx,edx
mov bx,100
div bx
add al,48
mov byte[esi+2],al
mov ax,dx
xor edx,edx
mov bx,10
div bx
add al,48
add dl,48
mov byte[esi+3],al
mov byte[esi+4],dl
jmp .findagain
.nofile
mov edx,.imagefname
%endif
ret
SECTION .data
.filename db 'image000.pcx',0,0,0,0
;.pcxsaved db 'SNAPSHOT SAVED TO '
;.rawsaved db 'SNAPSHOT SAVED TO '
SECTION .bss
.imagefname resb 128
SECTION .text
NEWSYM save16b2
call prepare16b
mov byte[pressed+14],2
push es
mov edi,pcxheader
mov ecx,128
.clearhead2
mov byte[edi],0
inc edi
dec ecx
jnz .clearhead2
; Initial header = 14 bytes
mov byte[pcxheader],'B'
mov byte[pcxheader+1],'M'
mov dword[pcxheader+2],02A01Ah-256*224*3+512*448*3
mov dword[pcxheader+10],26
mov dword[pcxheader+14],12
mov word[pcxheader+18],512
mov word[pcxheader+20],448
mov word[pcxheader+22],1
mov word[pcxheader+24],24
ChangeDir SnapPath
mov ecx,1 ;GetFreeFile use ecx==1 to tell if it's BMP
call GetFreeFile
mov cx,0
call Create_File
; Save header
mov bx,ax
mov ecx,26
mov edx,pcxheader
call Write_File
; Save picture Data
mov dword[.rowsleft],448
mov ax,[vesa2selec]
mov es,ax
mov esi,32*2+640*2*223*2+640*2
mov [.curdptr],esi
.a2
mov ecx,512
mov edi,mode7tab
mov esi,[.curdptr]
sub dword[.curdptr],640*2
.b2
push ecx
mov ax,[es:esi]
mov cl,[vesa2_bpos]
shr ax,cl
and ax,1Fh
shl al,3
mov byte[edi],al
mov ax,[es:esi]
mov cl,[vesa2_gpos]
shr ax,cl
and ax,1Fh
shl al,3
mov byte[edi+1],al
mov ax,[es:esi]
mov cl,[vesa2_rpos]
shr ax,cl
and ax,1Fh
shl al,3
mov byte[edi+2],al
pop ecx
add edi,3
add esi,2
dec ecx
jnz .b2
push edx
mov ecx,768*2
mov edx,mode7tab
call Write_File
pop edx
add edx,288*2
dec dword[.rowsleft]
jnz near .a2
call Makemode7Table
call Close_File
; mov dword[Msgptr],.rawsaved
; mov eax,[MsgCount]
; mov [MessageOn],eax
pop es
call restore16b
ChangeDirSRAM
ret
SECTION .data
;.rawsaved db 'SNAPSHOT SAVED TO '
SECTION .bss
.rowsleft resd 1
.curdptr resd 1
SECTION .text
prepare16b:
cmp byte[vesa2red10],1
jne .nored
cmp byte[cvidmode],5
jne .nored
cmp byte[scanlines],1
je .nored
cmp byte[smallscreenon],1
je .nored
mov byte[vesa2_rpos],10
mov byte[vesa2_gpos],5
.nored
ret
restore16b:
cmp byte[vesa2red10],1
jne .nored
mov byte[vesa2_rpos],11
mov byte[vesa2_gpos],6
.nored
ret