;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 GUIkeydelay2,SBHDMA EXTSYM soundon,DSPDisable,Start60HZ,pressed,putchar,getch EXTSYM vidbufferofsb,vidbuffer,clearwin,Stop60HZ,initwinvideo,vesa2_rpos EXTSYM vesa2_gpos,vesa2_bpos,vesa2_rposng,vesa2_gposng,vesa2_bposng,vesa2_usbit EXTSYM vesa2_clbit,vesa2_clbitng,vesa2_clbitng2,vesa2_clbitng3,vesa2red10,res640 EXTSYM res480,cbitmode,cvidmode,vesa2_bits,vesa2_x,vesa2_y,genfulladdtab,GUICPC EXTSYM drawscreenwin,ConvertToAFormat,HalfTrans,UnusedBitXor,UnusedBit EXTSYM ngrposng,nggposng,ngbposng,HalfTransB,HalfTransC EXTSYM WinUpdateDevices,UpdateVFrame,GetMouseX,GetMouseY,GetMouseMoveX EXTSYM GetMouseMoveY,GetMouseButton,SetMouseMinX,SetMouseMaxX,SetMouseMinY EXTSYM SetMouseMaxY,SetMouseX,SetMouseY,T36HZEnabled,MouseButton,Start36HZ EXTSYM Stop36HZ,BufferSizeW,BufferSizeB,ProcessSoundBuffer,CheckTimers EXTSYM vesa2_rfull,vesa2_rtrcl,vesa2_rtrcla,vesa2_gfull,vesa2_gtrcl,vesa2_gtrcla EXTSYM vesa2_bfull,vesa2_btrcl,vesa2_btrcla,Init_2xSaIMMXW,DoSleep EXTSYM V8Mode,GrayscaleMode,PrevWinMode,PrevFSMode,FrameSemaphore EXTSYM DisplayWIPDisclaimer EXTSYM pl1upk,pl1downk,pl1leftk,pl1rightk,pl1startk,pl1selk EXTSYM pl1Ak,pl1Bk,pl1Xk,pl1Yk,pl1Lk,pl1Rk EXTSYM pl2upk,pl2downk,pl2leftk,pl2rightk,pl2startk,pl2selk EXTSYM pl2Ak,pl2Bk,pl2Xk,pl2Yk,pl2Lk,pl2Rk EXTSYM pl3upk,pl3downk,pl3leftk,pl3rightk,pl3startk,pl3selk EXTSYM pl3Ak,pl3Bk,pl3Xk,pl3Yk,pl3Lk,pl3Rk EXTSYM pl4upk,pl4downk,pl4leftk,pl4rightk,pl4startk,pl4selk EXTSYM pl4Ak,pl4Bk,pl4Xk,pl4Yk,pl4Lk,pl4Rk EXTSYM pl5upk,pl5downk,pl5leftk,pl5rightk,pl5startk,pl5selk EXTSYM pl5Ak,pl5Bk,pl5Xk,pl5Yk,pl5Lk,pl5Rk ; NOTE: For timing, Game60hzcall should be called at 50hz or 60hz (depending ; on romispal) after a call to InitPreGame and before DeInitPostGame are ; made. GUI36hzcall should be called at 36hz after a call GUIInit and ; before GUIDeInit. SECTION .text NEWSYM StartUp ret ; SystemInit - Initialize all Joystick stuff, load in all configuration data, ; parse commandline data, obtain current directory (One time initialization) NEWSYM SystemInit ; Be sure to set SBHDMA to a value other than 0 if 16bit sound exists %ifndef __RELEASE__ pushad call DisplayWIPDisclaimer popad %endif mov byte[SBHDMA],1 ret NEWSYM PrintStr ; Print ASCIIZ string pushad .next mov al,[edx] or al,al jz .finish push edx mov dl,al push edx call putchar pop edx ; mov ah,02h ; int 21h pop edx inc edx jmp .next .finish popad ret SECTION .data NEWSYM wfkey, db 0 SECTION .text NEWSYM WaitForKey ; Wait for a key to be pressed pushad call getch mov [wfkey],al popad mov al,[wfkey] ;mov ah,7 ;int 21h ; return key in al ret RefreshKeybBuffer: call JoyRead mov ebx,[HoldKey] cmp byte[pressed+ebx],0 jne .holding mov dword[HoldKey],0 .holding xor eax,eax xor ebx,ebx .loop cmp byte[PKeyBuf+eax],0 jne .not1 cmp byte[pressed+eax],0 je .not1 mov byte[PKeyBuf+eax],1 mov ebx,eax .not1 cmp byte[pressed+eax],0 jne .not0 mov byte[PKeyBuf+eax],0 .not0 inc eax cmp eax,100h jne .loop or ebx,ebx jz .notpressed mov [HoldKey],ebx mov byte[GUIkeydelay2],14 call .processkey .notpressed ; Execute the following at 36hz cmp dword[HoldKey],0 je .noholder cmp byte[GUIkeydelay2],0 jne .noholder mov byte[GUIkeydelay2],3 call .processkey .noholder ret .processkey mov ebx,[HoldKey] cmp ebx,0A8h jb .skipdecval add ebx,-80h .skipdecval cmp ebx,58h jae .none movzx eax,byte[Keybtail] inc al and al,0Fh cmp al,[Keybhead] je .none mov al,[Keybtail] mov cl,[KeyConvTable+ebx] cmp byte[pressed+2Ah],0 jne .shift cmp byte[pressed+36h],0 je .noshift .shift mov cl,[KeyConvTableS+ebx] .noshift mov [HoldKeyBuf+eax],cl inc al and al,0Fh mov [Keybtail],al .none ret SECTION .data Keybhead db 0 Keybtail db 0 HoldKey dd 0 HoldKeyBuf times 16 db 0 PKeyBuf times 100h db 0 NEWSYM CurKeyPos, dd 0 NEWSYM CurKeyReadPos, dd 0 NEWSYM KeyBuffer, times 16 dd 0 SECTION .text NEWSYM Check_Key mov al,[CurKeyPos] cmp al,[CurKeyReadPos] jne .yeskey xor al,al ret .yeskey mov al,0FFh ret ; returns 0 if there are no keys in the keyboard buffer, 0xFF otherwise pushad call RefreshKeybBuffer mov byte[wfkey],0 mov al,[Keybhead] cmp al,[Keybtail] je .nokeys mov byte[wfkey],0FFh .nokeys popad mov al,[wfkey] ; mov ah,0Bh ; int 21h ret NEWSYM Get_Key ; wait if there are no keys in buffer, then return key in al ; for extended keys, return a 0, then the extended key afterwards xor eax,eax .nokey ; call JoyRead mov al,[CurKeyReadPos] cmp al,[CurKeyPos] je .nokey test word[KeyBuffer+eax*4],100h jnz .upper mov al,[KeyBuffer+eax*4] inc dword[CurKeyReadPos] and dword[CurKeyReadPos],0Fh ret .upper add word[KeyBuffer+eax*4],-100h xor al,al ret pushad .nonewkey call RefreshKeybBuffer movzx eax,byte[Keybhead] cmp al,[Keybtail] je .nonewkey mov bl,[HoldKeyBuf+eax] test bl,80h jz .notupperkey xor bl,bl add byte[HoldKeyBuf+eax],-80h jmp .yesupperkey .notupperkey inc al and al,0Fh mov [Keybhead],al .yesupperkey ; call getch mov [wfkey],bl popad mov al,[wfkey] ;mov ah,7 ;int 21h ; return key in al ret SECTION .data KeyConvTable: db 255,27 ,'1','2','3','4','5','6' ; 00h db '7','8','9','0','-','=',8 ,9 db 'Q','W','E','R','T','Y','U','I' ; 10h db 'O','P','[',']',13 ,255,'A','S' db 'D','F','G','H','J','K','L',';' ; 20h db 39 ,'`',255,'\','Z','X','C','V' db 'B','N','M',',','.','/',255,'*' ; 30h db 255,32 ,255,255,255,255,255,255 db 255,255,255,255,255,255,255,255 ; 40h db 200,201,202,203,204,205,206,207 db 208,209,210,211,255,255,255,255 ; 50h KeyConvTableS: db 255,27 ,'!','@','#','$','%','^' ; 00h db '&','*','(',')','_','+',8 ,9 db 'Q','W','E','R','T','Y','U','I' ; 10h db 'O','P','{','}',13 ,255,'A','S' db 'D','F','G','H','J','K','L',':' ; 20h db '"','~',255,'|','Z','X','C','V' db 'B','N','M','<','>','?',255,'*' ; 30h db 255,32 ,255,255,255,255,255,255 db 255,255,255,255,255,255,255,255 ; 40h db 200,201,202,203,204,205,206,207 db 208,209,210,211,255,255,255,255 ; 50h SECTION .text NEWSYM Get_Memfree mov eax,02000000h ; mov ax,0500h ; mov edi,edx ; int 31h ret NEWSYM Output_Text ; Output character (ah=02h) or string (ah=09h) pushad ; This function usually displays an error message on-screen cmp ah,02h je .char cmp ah,09h je .string ret .char push edx call putchar pop edx ; int 21h ; print dl popad ret .string pushad call PrintStr ; print edx popad popad ret NEWSYM InitPreGame ; Executes before starting/continuing a game mov byte[pressed+1],2 pushad call Start60HZ popad pushad call initwinvideo popad mov al,[GrayscaleMode] cmp al,[V8Mode] je .nochangemode xor byte[V8Mode],1 xor al,al .nochangemode pushad xor eax,eax mov edi,[vidbufferofsb] mov ecx,288*128 rep stosd popad pushad call clearwin popad ret ; set up interrupt handler ; get old handler pmode mode address ; Process stuff such as sound init, interrupt initialization ret NEWSYM SetupPreGame ; Executes after pre-game init, can execute multiple ; times after a single InitPreGame mov byte[pressed+1],2 ret NEWSYM DeInitPostGame ; Called after game is ended pushad call Stop60HZ popad ret ; **************************** ; Video Stuff ; **************************** ; ** init video mode functions ** SECTION .data NEWSYM firstvideo, dd 1 SECTION .text NEWSYM initvideo ; Returns 1 in videotroub if trouble occurs mov byte[res640],1 mov byte[res480],1 mov byte[cbitmode],1 mov word[vesa2_x],512 mov word[vesa2_y],480 mov byte[vesa2_bits],16 mov dword[vesa2_bits],16 mov dword[vesa2_rpos],11 mov dword[vesa2_gpos],5 mov dword[vesa2_bpos],0 mov byte[vesa2red10],0 mov byte[vesa2_rposng],11 mov byte[vesa2_gposng],5 mov byte[vesa2_bposng],0 mov dword[vesa2_clbitng],1111011111011110b mov dword[vesa2_clbitng2],11110111110111101111011111011110b mov dword[vesa2_clbitng2+4],11110111110111101111011111011110b mov dword[vesa2_clbitng3],0111101111101111b pushad call initwinvideo popad movzx eax,byte[cvidmode] cmp byte[GUIWFVID+eax],0 je .prevwinmode mov [PrevFSMode],al jmp .doneprevmode .prevwinmode mov [PrevWinMode],al .doneprevmode cmp dword[firstvideo],1 je .skipinitgfx pushad call InitializeGfxStuff popad .skipinitgfx mov dword[firstvideo],0 pushad call InitializeGfxStuff popad ret NEWSYM deinitvideo ret ; ** copy video mode functions ** SECTION .data NEWSYM converta, dd 0 SECTION .text NEWSYM DrawScreen ; In-game screen render w/ triple buffer check cmp dword[converta],1 jne near .skipconv pushad mov dword[UnusedBit], 10000000000000001000000000000000b mov dword[HalfTrans], 01111011110111100111101111011110b mov dword[UnusedBitXor], 01111111111111110111111111111111b mov dword[UnusedBit+4], 10000000000000001000000000000000b mov dword[HalfTrans+4], 01111011110111100111101111011110b mov dword[UnusedBitXor+4],01111111111111110111111111111111b mov dword[HalfTransB], 00000100001000010000010000100001b mov dword[HalfTransB+4], 00000100001000010000010000100001b mov dword[HalfTransC], 01111011110111100111101111011110b mov dword[HalfTransC+4], 01111011110111100111101111011110b mov dword[ngrposng],10 mov dword[nggposng],5 mov dword[ngbposng],0 call ConvertToAFormat popad .skipconv pushad call drawscreenwin popad ret ; jmp DosDrawScreen NEWSYM vidpastecopyscr ; GUI screen render pushad mov eax,[vidbuffer] mov ecx,224*288 mov edx,ecx add ecx,-288 dec edx .loop movzx ebx,byte[eax+edx] mov bx,[GUICPC+ebx*2] mov [eax+edx*2],bx dec edx dec ecx jnz .loop popad jmp DrawScreen ; ** Video Mode Variables ** SECTION .data ; Total Number of Video Modes NEWSYM NumVideoModes, dd 43 ; GUI Video Mode Names - Make sure that all names are of the same length ; and end with a NULL terminator NEWSYM GUIVideoModeNames db '256x224 R W',0 ;0 db '256x224 R F',0 ;1 db '512x448 R W',0 ;2 db '512x448 DR W',0 ;3 db '640x480 S W',0 ;4 db '640x480 DS W',0 ;5 db '640x480 DR F',0 ;6 db '640x480 DS F',0 ;7 db '640x480 S F',0 ;8 db '768x672 R W',0 ;9 db '768x672 DR W',0 ;10 db '800x600 S W',0 ;11 db '800x600 DS W',0 ;12 db '800x600 S F',0 ;13 db '800x600 DR F',0 ;14 db '800x600 DS F',0 ;15 db '1024x768 S W',0 ;16 db '1024x768 DS W',0 ;17 db '1024x768 S F',0 ;18 db '1024x768 DR F',0 ;19 db '1024x768 DS F',0 ;20 db '1024x896 R W',0 ;21 db '1024x896 DR W',0 ;22 db '1280x960 S W',0 ;23 db '1280x960 DS W',0 ;24 db '1280x960 S F',0 ;25 db '1280x960 DR F',0 ;26 db '1280x960 DS F',0 ;27 db '1280x1024 S W',0 ;28 db '1280x1024 DS W',0 ;29 db '1280x1024 S F',0 ;30 db '1280x1024 DR F',0 ;31 db '1280x1024 DS F',0 ;32 db '1600x1200 S W',0 ;33 db '1600x1200 DS W',0 ;34 db '1600x1200 DR F',0 ;35 db '1600x1200 DS F',0 ;36 db '1600x1200 S F',0 ;37 db 'CUSTOM D W',0 ;38 db 'CUSTOM DS F',0 ;39 db 'CUSTOM W',0 ;40 db 'CUSTOM S F',0 ;41 db 'CUSTOM DR F',0 ;42 ; Video Mode Feature Availability (1 = Available, 0 = Not Available) ; Left side starts with Video Mode 0 ; 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 NEWSYM GUIWFVID, db 0,1,0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,1,1,1,0,0,0,0,1,1,1,0,0,1,1,1,0,0,1,1,1,0,1,0,1,1; Fullscreen NEWSYM GUIDSIZE, db 0,0,0,1,0,1,1,1,0,0,1,0,1,0,1,1,0,1,0,1,1,0,1,0,1,0,1,1,0,1,0,1,1,0,1,1,1,0,1,1,0,0,1; D Modes NEWSYM GUISMODE, db 0,0,0,0,1,0,0,0,1,0,0,1,0,1,0,0,1,0,1,0,0,0,0,1,0,1,0,0,1,0,1,0,0,1,0,0,0,1,0,0,1,1,0; Win Stretched Modes NEWSYM GUIDSMODE, db 0,0,0,0,0,1,0,1,0,0,0,0,1,0,0,1,0,1,0,0,1,0,0,0,1,0,0,1,0,1,0,0,1,0,1,0,1,0,1,1,0,0,0; Win D-Stretched Modes NEWSYM GUIKEEP43, db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,1,0,0,0,0,0,1,1,1,1,0; Keep 4:3 Ratio NEWSYM GUIM7VID, db 0,0,0,1,0,1,1,1,0,0,1,0,1,0,1,1,0,1,0,1,1,0,1,0,1,0,1,1,0,1,0,1,1,0,1,1,1,0,1,1,0,0,1; Hires Mode 7 NEWSYM GUIHQ2X, db 0,0,0,1,0,1,1,1,0,0,1,0,1,0,1,1,0,1,0,1,1,0,1,0,1,0,1,1,0,1,0,1,1,0,1,1,1,0,1,1,0,0,1; Hq2x Filter NEWSYM GUIHQ3X, db 0,0,0,0,0,0,0,0,0,0,1,0,1,0,1,1,0,1,0,1,1,0,1,0,1,0,1,1,0,1,0,1,1,0,1,1,1,0,1,1,0,0,1; Hq3x Filter NEWSYM GUIHQ4X, db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,1,1,0,1,0,1,1,0,1,1,1,0,1,1,0,0,1; Hq4x Filter NEWSYM GUINTVID, db 0,0,0,0,0,1,1,1,0,0,1,0,1,0,1,1,0,1,0,1,1,0,1,0,1,0,1,1,0,1,0,1,1,0,1,1,1,0,1,1,0,0,1; NTSC Filter SECTION .text ; **************************** ; Input Device Stuff ; **************************** ; Variables related to Input Device Routines: ; pl1selk,pl1startk,pl1upk,pl1downk,pl1leftk,pl1rightk,pl1Xk, ; pl1Ak,pl1Lk,pl1Yk,pl1Bk,pl1Rk ; (Change 1 to 2,3,4 for other players) ; Each of these variables contains the corresponding key pressed value ; for the key data ; pressed[] ; - This is an array of pressed/released data (bytes) where the ; corresponding key pressed value is used as the index. The value ; for each entry is 0 for released and 1 for pressed. Also, when ; writing keyboard data to this array, be sure to first check if ; the value of the array entry is 2 or not. If it is 2, do not write 1 ; to that array entry. (however, you can write 0 to it) ; As an example, to access Player 1 L button press data, it is ; done like : pressed[pl1Lk] ; The 3 character key description of that array entry is accessed by the ; GUI through ScanCodeListing[pl1Lk*3] ; Note: When storing the input device configuration of a dynamic input ; device system (ie. Win9x) rather than a static system (ie. Dos), it ; is best to store in the name of the device and relative button ; assignments in the configuration file, then convert it to ZSNES' ; numerical corresponding key format after reading from it. And then ; convert it back when writing to it back. NEWSYM UpdateDevices ; One-time input device init call WinUpdateDevices ret NEWSYM JoyRead pushad call UpdateVFrame popad ret SECTION .data ; Total Number of Input Devices NEWSYM NumInputDevices, dd 2 ; Input Device Names NEWSYM GUIInputNames db 'NONE ',0 db 'KEYBOARD/GAMEPAD',0 db ' ',0 db ' ',0 db ' ',0 db ' ',0 db ' ',0 db ' ',0 db ' ',0 db ' ',0 db ' ',0 db ' ',0 db ' ',0 db ' ',0 db ' ',0 db ' ',0 ; GUI Description codes for each corresponding key pressed value NEWSYM ScanCodeListing db '---','ESC',' 1 ',' 2 ',' 3 ',' 4 ',' 5 ',' 6 ' ; 00h db ' 7 ',' 8 ',' 9 ',' 0 ',' - ',' = ','BKS','TAB' db ' Q ',' W ',' E ',' R ',' T ',' Y ',' U ',' I ' ; 10h db ' O ',' P ',' [ ',' ] ','RET','LCT',' A ',' S ' db ' D ',' F ',' G ',' H ',' J ',' K ',' L ',' : ' ; 20h db ' " ',' ~ ','LSH',' \ ',' Z ',' X ',' C ',' V ' db ' B ',' N ',' M ',' , ',' . ',' / ','RSH',' * ' ; 30h db 'LAL','SPC','CAP','F1 ','F2 ','F3 ','F4 ','F5 ' db 'F6 ','F7 ','F8 ','F9 ','F10','NUM','SCR','KP7' ; 40h db 'KP8','KP9','KP-','KP4','KP5','KP6','KP+','KP1' db 'KP2','KP3','KP0','KP.',' ',' ','OEM','F11' ; 50h db 'F12','59H','5AH','5BH','5CH','5DH','5EH','5FH' db '60H','61H','62H','63H','64H','65H','66H','67H' ; 60h db '68H','69H','6AH','6BH','6CH','6DH','6EH','6FH' db '70H','71H','72H','73H','74H','75H','76H','77H' ; 70h db '78H','79H','7AH','7BH','7CH','7DH','7EH','7FH' ; Keyboard continued (Direct Input) db '80H','81H','82H','83H','84H','85H','86H','87H' ; 80h db '88H','89H','8AH','8BH','8CH','8DH','8EH','8FH' db '90H','91H','92H','93H','94H','95H','96H','97H' ; 90h db '98H','99H','9AH','9BH','9CH','9DH','9EH','9FH' db 'A0H','A1H','A2H','A3H','A4H','A5H','A6H','A7H' ; A0h db 'A8H','A9H','AAH','ABH','ACH','ADH','AEH','AFH' db 'B0H','B1H','B2H','B3H','B4H','B5H','B6H','B7H' ; B0h db 'B8H','B9H','BAH','BBH','BCH','BDH','BEH','BFH' db 'C0H','C1H','C2H','C3H','C4H','C5H','C6H','C7H' ; C0h db 'C8H','C9H','CAH','CBH','CCH','CDH','CEH','CFH' db 'D0H','D1H','D2H','D3H','D4H','D5H','D6H','D7H' ; D0h db 'D8H','D9H','DAH','DBH','DCH','DDH','DEH','DFH' db 'E0H','E1H','E2H','E3H','E4H','E5H','E6H','E7H' ; E0h db 'E8H','E9H','EAH','EBH','ECH','EDH','EEH','EFH' db 'F0H','F1H','F2H','F3H','F4H','F5H','F6H','F7H' ; F0h db 'F8H','F9H','FAH','FBH','FCH','FDH','FEH','FFH' ; Joystick Stuff (Direct Input) db 'J00','J01','J02','J03','J04','J05','J06','J07' db 'J08','J09','J0A','J0B','J0C','J0D','J0E','J0F' db 'J10','J11','J12','J13','J14','J15','J16','J17' db 'J18','J19','J1A','J1B','J1C','J1D','J1E','J1F' db 'J20','J21','J22','J23','J24','J25','J26','J27' db 'J28','J29','J2A','J2B','J2C','J2D','J2E','J2F' db 'J30','J31','J32','J33','J34','J35','J36','J37' db 'J38','J39','J3A','J3B','J3C','J3D','J3E','J3F' db 'J40','J41','J42','J43','J44','J45','J46','J47' db 'J48','J49','J4A','J4B','J4C','J4D','J4E','J4F' db 'J50','J51','J52','J53','J54','J55','J56','J57' db 'J58','J59','J5A','J5B','J5C','J5D','J5E','J5F' db 'J60','J61','J62','J63','J64','J65','J66','J67' db 'J68','J69','J6A','J6B','J6C','J6D','J6E','J6F' db 'J70','J71','J72','J73','J74','J75','J76','J77' db 'J78','J79','J7A','J7B','J7C','J7D','J7E','J7F' ; Extra Stuff (180h) (Parallel Port) db 'PPB','PPY','PSL','PST','PUP','PDN','PLT','PRT' db 'PPA','PPX','PPL','PPR',' ',' ',' ',' ' db 'P2B','P2Y','P2S','P2T','P2U','P2D','P2L','P2R' db 'P2A','P2X','P2L','P2R',' ',' ',' ',' ' db 'PPB','PPY','PSL','PST','PUP','PDN','PLT','PRT' db 'PPA','PPX','PPL','PPR',' ',' ',' ',' ' db 'P2B','P2Y','P2S','P2T','P2U','P2D','P2L','P2R' db 'P2A','P2X','P2L','P2R',' ',' ',' ',' ' SECTION .text ; **************************** ; Mouse Stuff ; **************************** NEWSYM Init_Mouse ; return non-zero if successful mov eax,01h ret SECTION .data NEWSYM WMouseX, dd 0 NEWSYM WMouseY, dd 0 NEWSYM WMouseMoveX, dd 0 NEWSYM WMouseMoveY, dd 0 NEWSYM WMouseButton, dd 0 SECTION .text NEWSYM Get_MouseData ; Returns both pressed and coordinates ; bx : bit 0 = left button, bit 1 = right button ; cx = Mouse X Position, dx = Mouse Y Position pushad call GetMouseX mov [WMouseX],eax call GetMouseY mov [WMouseY],eax call GetMouseButton mov [WMouseButton],eax popad mov cx,[WMouseX] mov dx,[WMouseY] mov bx,[WMouseButton] ret NEWSYM Set_MouseXMax ; Sets the X boundaries (ecx = left, edx = right) pushad push ecx call SetMouseMinX pop ecx push edx call SetMouseMaxX pop edx popad ret NEWSYM Set_MouseYMax ; Sets the Y boundaries (ecx = left, edx = right) pushad push ecx call SetMouseMinY pop ecx push edx call SetMouseMaxY pop edx popad ret NEWSYM Set_MousePosition ; Sets Mouse Position (x:cx,y:dx) pushad push ecx call SetMouseX pop ecx push edx call SetMouseY pop edx popad ret NEWSYM Get_MousePositionDisplacement ; returns x,y displacement in pixel in cx,dx pushad call GetMouseMoveX mov [WMouseMoveX],eax call GetMouseMoveY mov [WMouseMoveY],eax popad mov cx,[WMouseMoveX] mov dx,[WMouseMoveY] ret NEWSYM MouseWindow pushad or byte[MouseButton],2 mov byte[T36HZEnabled],1 call GetMouseButton and byte[MouseButton],0FDh popad ret NEWSYM GUIInit pushad call Start36HZ popad ret NEWSYM GUIDeInit pushad call Stop36HZ popad ret ; **************************** ; Sound Stuff ; **************************** NEWSYM StopSound call Start36HZ call JoyRead ret NEWSYM StartSound call Start60HZ call JoyRead ret NEWSYM SoundProcess ; This function is called ~60 times/s at full speed cmp byte[soundon],0 je .nosound cmp byte[DSPDisable],1 je .nosound mov eax,256 ; Size mov [BufferSizeB],eax add eax,eax mov [BufferSizeW],eax pushad call ProcessSoundBuffer popad ; DSPBuffer should contain the processed buffer in the specified size ; You will have to convert/clip it to 16-bit for actual sound process .nosound ret section .data NEWSYM delayvalue, dd 0 section .text NEWSYM delay mov [delayvalue],ecx pushad call DoSleep popad ret NEWSYM Check60hz ; Call the timer update function here pushad call CheckTimers call FrameSemaphore popad ret SECTION .data BitPosR db 11 BitPosG db 5 BitPosB db 0 BitSizeR db 5 BitSizeG db 6 BitSizeB db 5 SECTION .text InitializeGfxStuff: ; Process Red Stuff mov al,[BitPosR] mov cl,al mov bx,1 shl bx,cl cmp byte[BitSizeR],6 jne .no6bit mov [vesa2_usbit],bx inc al .no6bit or [vesa2_clbit],bx mov [vesa2_rpos],al dec al mov cl,al mov bx,001Fh cmp cl,0FFh je .shrr shl bx,cl jmp .shlr .shrr shr bx,1 .shlr mov [vesa2_rfull],bx add al,5 mov bx,1 mov cl,al shl bx,cl mov [vesa2_rtrcl],bx xor bx,0FFFFh mov [vesa2_rtrcla],bx ; Process Green Stuff mov al,[BitPosG] mov cl,al mov bx,1 shl bx,cl cmp byte[BitSizeG],6 jne .no6bitb mov [vesa2_usbit],bx inc al .no6bitb or [vesa2_clbit],bx mov [vesa2_gpos],al dec al mov cl,al mov bx,001Fh cmp cl,0FFh je .shrg shl bx,cl jmp .shlg .shrg shr bx,1 .shlg mov [vesa2_gfull],bx add al,5 mov bx,1 mov cl,al shl bx,cl mov [vesa2_gtrcl],bx xor bx,0FFFFh mov [vesa2_gtrcla],bx ; Process Blue Stuff mov al,[BitPosB] mov cl,al mov bx,1 shl bx,cl cmp byte[BitSizeB],6 jne .no6bitc mov [vesa2_usbit],bx inc al .no6bitc or [vesa2_clbit],bx mov [vesa2_bpos],al dec al mov cl,al mov bx,001Fh cmp cl,0FFh je .shrb shl bx,cl jmp .shlb .shrb shr bx,1 .shlb mov [vesa2_bfull],bx add al,5 mov bx,1 mov cl,al shl bx,cl mov [vesa2_btrcl],bx xor bx,0FFFFh mov [vesa2_btrcla],bx xor word[vesa2_clbit],0FFFFh call genfulladdtab cmp byte[converta],1 je .red10 mov eax,565 jmp .red11 .red10 mov eax,555 .red11 push eax call Init_2xSaIMMXW pop eax ret %macro SetDefaultKey2 13 mov dword[%1upk],%4 ; Up mov dword[%1downk],%5 ; Down mov dword[%1leftk],%6 ; Left mov dword[%1rightk],%7 ; Right mov dword[%1startk],%3 ; Start mov dword[%1selk],%2 ; Select mov dword[%1Ak],%9 ; A mov dword[%1Bk],%12 ; B mov dword[%1Xk],%8 ; X mov dword[%1Yk],%11 ; Y mov dword[%1Lk],%10 ; L mov dword[%1Rk],%13 ; R %endmacro %macro SetDefaultKey 12 cmp bh,0 jne %%nopl1 SetDefaultKey2 pl1,%1,%2,%3,%4,%5,%6,%7,%8,%9,%10,%11,%12 %%nopl1 cmp bh,1 jne %%nopl2 SetDefaultKey2 pl2,%1,%2,%3,%4,%5,%6,%7,%8,%9,%10,%11,%12 %%nopl2 cmp bh,2 jne %%nopl3 SetDefaultKey2 pl3,%1,%2,%3,%4,%5,%6,%7,%8,%9,%10,%11,%12 %%nopl3 cmp bh,3 jne %%nopl4 SetDefaultKey2 pl4,%1,%2,%3,%4,%5,%6,%7,%8,%9,%10,%11,%12 %%nopl4 cmp bh,4 jne %%nopl5 SetDefaultKey2 pl5,%1,%2,%3,%4,%5,%6,%7,%8,%9,%10,%11,%12 %%nopl5 %endmacro NEWSYM SetInputDevice ; bl = device #, bh = player # (0-4) ; Sets keys according to input device selected cmp bl,0 jne near .nozero SetDefaultKey 0,0,0,0,0,0,0,0,0,0,0,0 ret .nozero cmp bh,1 je near .input2 SetDefaultKey 54,28,200,208,203,205,31,45,32,30,44,46 ret .input2 SetDefaultKey 56,29,36,50,49,51,210,199,201,211,207,209 ret