From edf31fa4c577246667413b3899fea27c01e2a893 Mon Sep 17 00:00:00 2001 From: theoddone33 <> Date: Tue, 10 Apr 2001 03:52:02 +0000 Subject: [PATCH] adding linux stuff --- zsnes/src/linux/copyvwin.asm | 1528 +++++++++++++++++++ zsnes/src/linux/protect.c | 206 +++ zsnes/src/linux/resource.h | 34 + zsnes/src/linux/sdllink.c | 2787 ++++++++++++++++++++++++++++++++++ zsnes/src/linux/winintrf.asm | 2108 +++++++++++++++++++++++++ zsnes/src/linux/zfilew.c | 328 ++++ zsnes/src/linux/zipxw.c | 57 + zsnes/src/linux/zloaderw.c | 577 +++++++ zsnes/src/linux/zsnes.rc | 1 + zsnes/src/linux/ztcp.c | 1277 ++++++++++++++++ 10 files changed, 8903 insertions(+) create mode 100644 zsnes/src/linux/copyvwin.asm create mode 100644 zsnes/src/linux/protect.c create mode 100644 zsnes/src/linux/resource.h create mode 100644 zsnes/src/linux/sdllink.c create mode 100644 zsnes/src/linux/winintrf.asm create mode 100644 zsnes/src/linux/zfilew.c create mode 100644 zsnes/src/linux/zipxw.c create mode 100644 zsnes/src/linux/zloaderw.c create mode 100644 zsnes/src/linux/zsnes.rc create mode 100644 zsnes/src/linux/ztcp.c diff --git a/zsnes/src/linux/copyvwin.asm b/zsnes/src/linux/copyvwin.asm new file mode 100644 index 00000000..0f19a718 --- /dev/null +++ b/zsnes/src/linux/copyvwin.asm @@ -0,0 +1,1528 @@ +;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. + +%include "macros.mac" + +EXTSYM vesa2selec,vidbuffer,GUIOn,FPUCopy,resolutn,En2xSaI,antienab,scanlines +EXTSYM hirestiledat,res512switch,curblank,spritetablea +EXTSYM lineleft,_2xSaILineW,_2xSaISuperEagleLineW +EXTSYM newengen,cfield,HalfTrans +EXTSYM GUIOn2 +EXTSYM SpecialLine +EXTSYM vidbufferofsb +EXTSYM Super2xSaI +EXTSYM HalfTransB,HalfTransC + +NEWSYM CopyVWinAsmStart + + +NEWSYM AddEndBytes, dd 0 ; Number of bytes between each line +NEWSYM NumBytesPerLine, dd 0 ; Total number of bytes per line (1024+AddEndBytes) +NEWSYM WinVidMemStart, dd 0 + +NEWSYM copy640x480x16bwin + cmp byte[curblank],40h + jne .startcopy + ret +.startcopy + push es + mov ax,ds + mov es,ax + mov esi,[vidbuffer] + mov edi,[WinVidMemStart] + add esi,16*2+256*2+32*2 + xor eax,eax + ; Check if interpolation mode + cmp byte[GUIOn2],1 + je .nointerp + cmp byte[FPUCopy],2 + jne .nommx + cmp byte[En2xSaI],0 + jne near Process2xSaIwin +.nommx + cmp byte[antienab],1 + je near interpolate640x480x16bwin +.nointerp + mov dl,[resolutn] + dec dl + dec dl + cmp byte[scanlines],1 + je near .scanlines + cmp byte[scanlines],3 + je near .halfscanlines + cmp byte[scanlines],2 + je near .quartscanlines + + mov ebx,hirestiledat+1 + cmp byte[newengen],0 + je .loopa + mov ebx,SpecialLine+1 +.loopa + mov ecx,256 + cmp byte[ebx],1 + je near .yeshires + cmp byte[GUIOn],1 + je .ignorehr + cmp byte[ebx],1 + ja near .yeshiresng +.ignorehr + cmp byte[FPUCopy],2 + je near .mmx +.a + mov ax,[esi] + shl eax,16 + mov ax,[esi] + mov [edi],eax + add esi,2 + add edi,4 + dec ecx + jnz .a + sub esi,256*2 + add edi,[AddEndBytes] + mov ecx,256 +.a2 + mov ax,[esi] + shl eax,16 + mov ax,[esi] + mov [edi],eax + add esi,2 + add edi,4 + dec ecx + jnz .a2 +.return + add esi,64 + add edi,[AddEndBytes] + inc ebx + dec dl + jnz near .loopa + pop es + xor byte[res512switch],1 + cmp byte[FPUCopy],2 + je .mmx2 + ret +.mmx2 + emms + ret +.yeshires + mov byte[ebx],0 + test byte[res512switch],1 + jnz .rightside + push ebx + mov ebx,[NumBytesPerLine] +.b + mov ax,[esi] + mov [edi],ax + mov [edi+ebx],ax + add esi,2 + add edi,4 + dec ecx + jnz .b + pop ebx + add edi,[NumBytesPerLine] + jmp .return +.rightside + push ebx + mov ebx,[NumBytesPerLine] +.c + mov ax,[esi] + mov [edi+2],ax + mov [edi+2+ebx],ax + add esi,2 + add edi,4 + dec ecx + jnz .c + pop ebx + add edi,[NumBytesPerLine] + jmp .return +.mmx + mov eax,[spritetablea] + mov ecx,64 + add eax,512 +.mmxr + movq mm0,[esi] + movq mm1,mm0 + punpcklwd mm0,mm1 + movq [edi],mm0 + punpckhwd mm1,mm1 + movq [edi+8],mm1 + movq [eax],mm0 + movq [eax+8],mm1 + add esi,8 + add edi,16 + add eax,16 + dec ecx + jnz .mmxr + mov eax,[spritetablea] + mov ecx,32 + add eax,512 + add edi,[AddEndBytes] +.mmxr2 + movq mm0,[eax] + movq [edi],mm0 + movq mm1,[eax+8] + movq [edi+8],mm1 + movq mm2,[eax+16] + movq [edi+16],mm2 + movq mm3,[eax+24] + movq [edi+24],mm3 + add eax,32 + add edi,32 + dec ecx + jnz .mmxr2 + jmp .return +.yeshiresng + call HighResProc + jmp .return + +.bng + mov eax,[esi+75036*4-2] + mov ax,[esi] + mov [edi],eax + add esi,2 + add edi,4 + dec ecx + jnz .bng + add edi,[AddEndBytes] + sub esi,256*2 + mov ecx,256 +.bngb + mov eax,[esi+75036*4-2] + mov ax,[esi] + mov [edi],eax + add esi,2 + add edi,4 + dec ecx + jnz .bngb + jmp .return + +.scanlines + mov ebx,hirestiledat+1 + cmp byte[GUIOn],1 + je .loopab + cmp byte[newengen],0 + je .loopab + mov ebx,SpecialLine+1 +.loopab + mov ecx,256 + cmp byte[ebx],1 + je .yeshiresb + cmp byte[ebx],1 + jbe .ignorehrb + call HighResProc + jmp .returnb +.ignorehrb + cmp byte[FPUCopy],2 + je near .mmxsl +.ab + mov ax,[esi] + shl eax,16 + mov ax,[esi] + mov [edi],eax + add esi,2 + add edi,4 + dec ecx + jnz .ab +.returnb + add esi,64 + add edi,[AddEndBytes] + add edi,[NumBytesPerLine] + inc ebx + dec dl + jnz .loopab + pop es + xor byte[res512switch],1 + cmp byte[FPUCopy],2 + je near .mmx2 + ret +.yeshiresb + mov byte[ebx],0 + test byte[res512switch],1 + jnz .rightsideb +.bb + mov ax,[esi] + mov [edi],ax + add esi,2 + add edi,4 + dec ecx + jnz .bb + jmp .returnb +.rightsideb +.cb + mov ax,[esi] + mov [edi+2],ax + add esi,2 + add edi,4 + dec ecx + jnz .cb + jmp .returnb +.mmxsl + mov ecx,64 +.mmxrsl + movq mm0,[esi] + movq mm1,mm0 + punpcklwd mm0,mm1 + punpckhwd mm1,mm1 + movq [edi],mm0 + movq [edi+8],mm1 + add esi,8 + add edi,16 + add eax,16 + dec ecx + jnz .mmxrsl + jmp .returnb + +.halfscanlines + mov ebx,hirestiledat+1 + cmp byte[GUIOn],1 + je .loopabh + cmp byte[newengen],0 + je .loopabh + mov ebx,SpecialLine+1 +.loopabh + cmp byte[ebx],1 + jbe .ignorehrbh + call HighResProc + jmp .returnbh +.ignorehrbh + cmp byte[FPUCopy],2 + je near .mmxslh + mov ecx,256 +.abh + mov ax,[esi] + shl eax,16 + mov ax,[esi] + mov [edi],eax + add esi,2 + add edi,4 + dec ecx + jnz .abh + mov ecx,256 + sub esi,512 + add edi,[AddEndBytes] +.abhs + mov ax,[esi] + shl eax,16 + mov ax,[esi] + and eax,[HalfTrans] + shr eax,1 + mov [edi],eax + add esi,2 + add edi,4 + dec ecx + jnz .abhs +.returnbh + add esi,64 + add edi,[AddEndBytes] + inc ebx + dec dl + jnz near .loopabh + pop es + cmp byte[FPUCopy],2 + je near .mmx2 + ret +.mmxslh + mov eax,[spritetablea] + mov ecx,64 + add eax,512 +.mmxrslh + movq mm0,[esi] + movq mm1,mm0 + punpcklwd mm0,mm1 + punpckhwd mm1,mm1 + movq [edi],mm0 + movq [edi+8],mm1 + movq [eax],mm0 + movq [eax+8],mm1 + add esi,8 + add edi,16 + add eax,16 + dec ecx + jnz .mmxrslh + mov eax,[spritetablea] + mov ecx,32 + add eax,512 + add edi,[AddEndBytes] + movq mm4,[HalfTrans] +.mmxr2h + movq mm0,[eax] + movq mm1,[eax+8] + movq mm2,[eax+16] + movq mm3,[eax+24] + pand mm0,mm4 + pand mm1,mm4 + pand mm2,mm4 + pand mm3,mm4 + psrlw mm0,1 + psrlw mm1,1 + psrlw mm2,1 + psrlw mm3,1 + movq [edi],mm0 + movq [edi+8],mm1 + movq [edi+16],mm2 + movq [edi+24],mm3 + add eax,32 + add edi,32 + dec ecx + jnz .mmxr2h + jmp .returnbh + +.quartscanlines + mov [lineleft],dl + mov ebx,hirestiledat+1 + cmp byte[GUIOn],1 + je .loopabh2 + cmp byte[newengen],0 + je .loopabh2 + mov ebx,SpecialLine+1 +.loopabh2 + cmp byte[ebx],1 + jbe .ignorehrbh2 + call HighResProc + jmp .returnbh2 +.ignorehrbh2 + cmp byte[FPUCopy],2 + je near .mmxslh2 + mov ecx,256 +.abh2 + mov ax,[esi] + shl eax,16 + mov ax,[esi] + mov [edi],eax + add esi,2 + add edi,4 + dec ecx + jnz .abh2 + mov ecx,256 + sub esi,512 + add edi,[AddEndBytes] +.abhs2 + mov ax,[esi] + shl eax,16 + mov ax,[esi] + and eax,[HalfTrans] + shr eax,1 + mov edx,eax + and edx,[HalfTrans] + shr edx,1 + add eax,edx + mov [edi],eax + add esi,2 + add edi,4 + dec ecx + jnz .abhs2 +.returnbh2 + add esi,64 + add edi,[AddEndBytes] + inc ebx + dec byte[lineleft] + jnz near .loopabh2 + pop es + cmp byte[FPUCopy],2 + je near .mmx2 + ret +.mmxslh2 + mov eax,[spritetablea] + mov ecx,64 + add eax,512 +.mmxrslh2 + movq mm0,[esi] + movq mm1,mm0 + punpcklwd mm0,mm1 + punpckhwd mm1,mm1 + movq [edi],mm0 + movq [edi+8],mm1 + movq [eax],mm0 + movq [eax+8],mm1 + add esi,8 + add edi,16 + add eax,16 + dec ecx + jnz .mmxrslh2 + mov eax,[spritetablea] + mov ecx,64 + add eax,512 + add edi,[AddEndBytes] + movq mm4,[HalfTrans] +.mmxr2h2 + movq mm0,[eax] + movq mm1,[eax+8] + pand mm0,mm4 + pand mm1,mm4 + psrlw mm0,1 + psrlw mm1,1 + movq mm2,mm0 + movq mm3,mm1 + pand mm2,mm4 + pand mm3,mm4 + psrlw mm2,1 + psrlw mm3,1 + paddd mm0,mm2 + paddd mm1,mm3 + movq [edi],mm0 + movq [edi+8],mm1 + add eax,16 + add edi,16 + dec ecx + jnz .mmxr2h2 + jmp .returnbh2 + +HighResProc: + mov ecx,256 + cmp byte[ebx],3 + je near .hiresmode7 + cmp byte[ebx],7 + je near .hiresmode7 + test byte[ebx],4 + jz .nofield + cmp byte[scanlines],0 + jne .nofield + test byte[cfield],1 + jz .nofield + add edi,[NumBytesPerLine] +.nofield + test byte[ebx],3 + jnz near .hires +.a + mov ax,[esi] + shl eax,16 + mov ax,[esi] + mov [edi],eax + add esi,2 + add edi,4 + dec ecx + jnz .a + cmp byte[scanlines],0 + jne .nofield + test byte[cfield],1 + jnz .nofielde + add edi,[NumBytesPerLine] +.nofielde + ret +.hiresmode7 + cmp byte[FPUCopy],2 + je .yeshiresngmmxmode7 +.a2 + mov ax,[esi] + shl eax,16 + mov ax,[esi] + mov [edi],eax + add esi,2 + add edi,4 + dec ecx + jnz .a2 + add edi,[AddEndBytes] + sub esi,512 + mov ecx,256 + add esi,75036*4 +.a2b + mov ax,[esi] + shl eax,16 + mov ax,[esi] + mov [edi],eax + add esi,2 + add edi,4 + dec ecx + jnz .a2b + sub esi,75036*4 + ret +.yeshiresngmmxmode7 + mov ecx,64 +.mmxr + movq mm0,[esi] + movq mm1,mm0 + punpcklwd mm0,mm1 + movq [edi],mm0 + punpckhwd mm1,mm1 + movq [edi+8],mm1 + add esi,8 + add edi,16 + add eax,16 + dec ecx + jnz .mmxr + add edi,[AddEndBytes] + sub esi,512 + add esi,75036*4 + mov ecx,64 +.mmxrb + movq mm0,[esi] + movq mm1,mm0 + punpcklwd mm0,mm1 + movq [edi],mm0 + punpckhwd mm1,mm1 + movq [edi+8],mm1 + add esi,8 + add edi,16 + add eax,16 + dec ecx + jnz .mmxrb + sub esi,75036*4 + ret +.hires + cmp byte[FPUCopy],2 + je near .yeshiresngmmx +.bng + mov eax,[esi+75036*4-2] + mov ax,[esi] + mov [edi],eax + add esi,2 + add edi,4 + dec ecx + jnz .bng + test byte[ebx],4 + jz .nofieldb + cmp byte[scanlines],0 + jne .nofieldb + test byte[cfield],1 + jnz .lowerfield + add edi,[NumBytesPerLine] +.lowerfield + ret +.nofieldb + cmp byte[scanlines],1 + je near .scanlines + cmp byte[scanlines],3 + je near .halfscanlines + cmp byte[scanlines],2 + je near .quartscanlines + add edi,[AddEndBytes] + sub esi,256*2 + mov ecx,256 +.bngb + mov eax,[esi+75036*4-2] + mov ax,[esi] + mov [edi],eax + add esi,2 + add edi,4 + dec ecx + jnz .bngb + ret +.scanlines + ret +.yeshiresngmmx + mov eax,[spritetablea] + mov ecx,64 + add eax,512 +.ngal + movq mm0,[esi] + movq mm1,[esi+75036*4] + movq mm2,mm0 + punpcklwd mm0,mm1 + movq [edi],mm0 + punpckhwd mm2,mm1 + movq [edi+8],mm2 + movq [eax],mm0 + movq [eax+8],mm2 + add esi,8 + add edi,16 + add eax,16 + dec ecx + jnz .ngal + test byte[ebx],4 + jz .nofieldc + cmp byte[scanlines],0 + jne .nofieldc + test byte[cfield],1 + jnz .lowerfieldb + add edi,[NumBytesPerLine] +.lowerfieldb + ret +.nofieldc + cmp byte[scanlines],1 + je near .scanlines + cmp byte[scanlines],3 + je near .halfscanlinesmmx + cmp byte[scanlines],2 + je near .quartscanlinesmmx + test byte[ebx+1],3 + jz .noaa + cmp byte[En2xSaI],0 + jne near .antialias + cmp byte[antienab],0 + jne near .antialias +.noaa + add edi,[AddEndBytes] + mov eax,[spritetablea] + mov ecx,32 + add eax,512 +.mmxr2 + movq mm0,[eax] + movq [edi],mm0 + movq mm1,[eax+8] + movq [edi+8],mm1 + movq mm2,[eax+16] + movq [edi+16],mm2 + movq mm3,[eax+24] + movq [edi+24],mm3 + add eax,32 + add edi,32 + dec ecx + jnz .mmxr2 + ret +.antialias + add edi,[AddEndBytes] + mov eax,[spritetablea] + mov ecx,64 + add eax,512 + movq mm4,[HalfTrans] + sub esi,256*2 +.mmxr2aa + movq mm0,[esi+288*2] + movq mm1,[esi+288*2+75036*4] + movq mm2,mm0 + punpcklwd mm0,mm1 + punpckhwd mm2,mm1 + movq mm1,[eax] + movq mm3,[eax+8] + pand mm0,mm4 + pand mm1,mm4 + pand mm2,mm4 + pand mm3,mm4 + psrlw mm0,1 + psrlw mm1,1 + psrlw mm2,1 + psrlw mm3,1 + paddd mm0,mm1 + paddd mm2,mm3 + movq [edi],mm0 + movq [edi+8],mm2 + add eax,16 + add edi,16 + add esi,8 + dec ecx + jnz .mmxr2aa + ret +.halfscanlines + add edi,[AddEndBytes] + sub esi,256*2 + mov ecx,256 +.abhs + mov eax,[esi+75036*4-2] + mov ax,[esi] + and eax,[HalfTrans] + shr eax,1 + mov edx,eax + mov [edi],eax + add esi,2 + add edi,4 + dec ecx + jnz .abhs + ret +.quartscanlines + add edi,[AddEndBytes] + sub esi,256*2 + mov ecx,256 +.abhs2 + mov eax,[esi+75036*4-2] + mov ax,[esi] + and eax,[HalfTrans] + shr eax,1 + mov edx,eax + and edx,[HalfTrans] + shr edx,1 + add eax,edx + mov [edi],eax + add esi,2 + add edi,4 + dec ecx + jnz .abhs2 + ret +.halfscanlinesmmx + mov eax,[spritetablea] + mov ecx,32 + add eax,512 + add edi,[AddEndBytes] + movq mm4,[HalfTrans] +.mmxr2h + movq mm0,[eax] + movq mm1,[eax+8] + movq mm2,[eax+16] + movq mm3,[eax+24] + pand mm0,mm4 + pand mm1,mm4 + pand mm2,mm4 + pand mm3,mm4 + psrlw mm0,1 + psrlw mm1,1 + psrlw mm2,1 + psrlw mm3,1 + movq [edi],mm0 + movq [edi+8],mm1 + movq [edi+16],mm2 + movq [edi+24],mm3 + add eax,32 + add edi,32 + dec ecx + jnz .mmxr2h + ret +.quartscanlinesmmx + mov eax,[spritetablea] + mov ecx,64 + add eax,512 + add edi,[AddEndBytes] + movq mm4,[HalfTransC] +.mmxr2h2 + movq mm0,[eax] + movq mm1,[eax+8] + pand mm0,mm4 + pand mm1,mm4 + psrlw mm0,1 + psrlw mm1,1 + movq mm2,mm0 + movq mm3,mm1 + pand mm2,mm4 + pand mm3,mm4 + psrlw mm2,1 + psrlw mm3,1 + paddd mm0,mm2 + paddd mm1,mm3 + movq [edi],mm0 + movq [edi+8],mm1 + add eax,16 + add edi,16 + dec ecx + jnz .mmxr2h2 + ret + +Process2xSaIwin: + mov ebx,hirestiledat+1 + cmp byte[GUIOn],1 + je .loopabi + cmp byte[newengen],0 + je .loopabi + mov ebx,SpecialLine+1 +.loopabi + mov [InterPtr],ebx + +; add edi,[VESAAddr] + mov dl,[resolutn] + sub dl,2 ; Compensate for top/bottom line + 2 lines in 2xSaI + mov byte[lineleft],dl + mov dword[esi+512],0 + mov dword[esi+512+576*2],0 + mov ebx,[vidbufferofsb] + add ebx,288*2 + +.next + mov dword[esi+512+576*3],0 + + mov eax,[InterPtr] + cmp byte[eax],1 + jbe .ignorehr + push ebx + mov ebx,[InterPtr] + call HighResProc + pop ebx + push ebx + mov ecx,144 +.nextb + mov dword[ebx],0FFFFFFFFh + add ebx,4 + loop .nextb + pop ebx + jmp .returninterp +.ignorehr + +;srcPtr equ 8 +;deltaPtr equ 12 +;srcPitch equ 16 +;width equ 20 +;dstOffset equ 24 +;dstPitch equ 28 +;dstSegment equ 32 + + + push ebx + mov eax,[NumBytesPerLine] + push eax + mov eax,edi ; destination offset + push eax + mov eax,256 ; width + push eax + mov eax,576 ; source pitch + push eax + push ebx + mov eax,esi ; source pointer + push eax + cmp byte[En2xSaI],2 + je .supereagle + cmp byte[En2xSaI],3 + je .super2xSaI + call _2xSaILineW + jmp .normal +.supereagle + call _2xSaISuperEagleLineW + jmp .normal +.super2xSaI + call Super2xSaI +.normal + add esp,24 + pop ebx + add esi,576 + add edi,[NumBytesPerLine] + add edi,[NumBytesPerLine] + add ebx,576 + inc dword[InterPtr] + dec dword[lineleft] + jnz near .next + mov ecx,256 + sub edi,[NumBytesPerLine] +.loop + mov dword[es:edi],0 + add edi,4 + loop .loop + pop es + emms + ret +.returninterp + add esi,64 + inc dword[InterPtr] + add edi,[AddEndBytes] + add ebx,576 + dec byte[lineleft] + jnz near .next + emms + pop es + ret + +MMXInterpolwin: + mov ebx,hirestiledat+1 + cmp byte[GUIOn],1 + je .loopab + cmp byte[newengen],0 + je .loopab + mov ebx,SpecialLine+1 +.loopab + + mov dl,[resolutn] + dec dl + dec dl + dec dl + movq mm2,[HalfTransC] + cmp byte[scanlines],1 + je near .scanlines + cmp byte[scanlines],2 + je near .scanlinesquart + cmp byte[scanlines],3 + je near .scanlineshalf + inc ebx + mov [lineleft],dl + ; do scanlines + mov edx,[spritetablea] + mov ecx,64 + mov eax,[esi+510] + add edx,512 + mov [esi+512],eax +.a2 + movq mm0,[esi] + movq mm3,mm0 + movq mm4,mm0 + movq mm1,[esi+2] + pand mm3,mm1 + pand mm0,mm2 + pand mm1,mm2 + psrlw mm0,1 + psrlw mm1,1 + paddd mm0,mm1 + pand mm3,[HalfTransB] + paddw mm0,mm3 + movq mm5,mm4 + ; mm4/mm5 contains original values, mm0 contains mixed values + punpcklwd mm4,mm0 + punpckhwd mm5,mm0 + movq [edi],mm4 + movq [edi+8],mm5 + movq [edx],mm4 + movq [edx+8],mm5 + add esi,8 + add edi,16 + add edx,16 + dec ecx + jnz .a2 + add esi,64 + add edi,[AddEndBytes] +.a5 + cmp byte[ebx],1 + jbe .ignorehr + call HighResProc + movq mm2,[HalfTransC] + jmp .returninterp +.ignorehr + mov eax,[esi+510] + mov ecx,64 + mov [esi+512],eax + mov edx,[spritetablea] + add edx,512 + ; Process next line +.a3 + movq mm0,[esi] + movq mm3,mm0 + movq mm4,mm0 + movq mm1,[esi+2] + pand mm3,mm1 + pand mm0,mm2 + pand mm1,mm2 + psrlw mm0,1 + psrlw mm1,1 + paddd mm0,mm1 + pand mm3,[HalfTransB] + paddw mm0,mm3 + movq mm5,mm4 + ; mm4/mm5 contains original values, mm0 contains mixed values + movq mm6,[edx] + movq mm7,[edx+8] + punpcklwd mm4,mm0 + punpckhwd mm5,mm0 + movq [edx],mm4 + movq [edx+8],mm5 + pand mm0,mm4 + movq mm0,mm6 + pand mm4,mm2 + pand mm6,mm2 + psrlw mm4,1 + psrlw mm6,1 + pand mm0,[HalfTransB] + paddd mm4,mm6 + paddw mm4,mm0 + movq mm0,mm5 + pand mm0,mm7 + pand mm5,mm2 + pand mm7,mm2 + psrlw mm5,1 + pand mm0,[HalfTransB] + psrlw mm7,1 + paddd mm5,mm7 + paddw mm5,mm0 + movq [edi],mm4 + movq [edi+8],mm5 + add esi,8 + add edi,16 + add edx,16 + dec ecx + jnz near .a3 + add edi,[AddEndBytes] + mov edx,[spritetablea] + add edx,512 + mov ecx,64 +.a4 + movq mm0,[edx] + movq mm1,[edx+8] + movq [edi],mm0 + movq [edi+8],mm1 + add edi,16 + add edx,16 + dec ecx + jnz .a4 +.returninterp + add esi,64 + add edi,[AddEndBytes] + inc ebx + dec byte[lineleft] + jnz near .a5 + emms + pop es + ret + +.scanlines + inc dl + mov [lineleft],dl + ; do scanlines + mov eax,[esi+510] + mov ecx,64 + mov [esi+512],eax +.asl + cmp byte[ebx],1 + jbe .ignorehrs + call HighResProc + movq mm2,[HalfTrans] + jmp .returninterps +.ignorehrs +.a + movq mm0,[esi] + movq mm4,mm0 + movq mm1,[esi+2] + pand mm0,mm2 + pand mm1,mm2 + psrlw mm0,1 + psrlw mm1,1 + paddd mm0,mm1 + movq mm5,mm4 + ; mm4/mm5 contains original values, mm0 contains mixed values + punpcklwd mm4,mm0 + punpckhwd mm5,mm0 + movq [edi],mm4 + movq [edi+8],mm5 + add esi,8 + add edi,16 + dec ecx + jnz .a + mov eax,[esi+510] + mov [esi+512],eax +.returninterps + add esi,64 + add edi,[AddEndBytes] + add edi,[NumBytesPerLine] + inc ebx + mov ecx,64 + dec byte[lineleft] + jnz near .asl + emms + pop es + ret + +.scanlineshalf + inc dl + mov [lineleft],dl + ; do scanlines +.ahb + cmp byte[ebx],1 + jbe .ignorehrhs + call HighResProc + movq mm2,[HalfTrans] + jmp .returninterphs +.ignorehrhs + mov eax,[esi+510] + mov ecx,64 + mov [esi+512],eax + mov edx,[spritetablea] + add edx,512 +.ah + movq mm0,[esi] + movq mm4,mm0 + movq mm1,[esi+2] + pand mm0,mm2 + pand mm1,mm2 + psrlw mm0,1 + psrlw mm1,1 + paddd mm0,mm1 + movq mm5,mm4 + ; mm4/mm5 contains original values, mm0 contains mixed values + punpcklwd mm4,mm0 + punpckhwd mm5,mm0 + movq [edx],mm4 + movq [edx+8],mm5 + movq [edi],mm4 + movq [edi+8],mm5 + add esi,8 + add edi,16 + add edx,16 + dec ecx + jnz .ah + add edi,[AddEndBytes] + sub edx,16*64 + mov ecx,64 +.ahc + movq mm0,[edx] + movq mm1,[edx+8] + pand mm0,mm2 + pand mm1,mm2 + psrlw mm0,1 + psrlw mm1,1 + movq [edi],mm0 + movq [edi+8],mm1 + add edi,16 + add edx,16 + dec ecx + jnz .ahc +.returninterphs + add edi,[AddEndBytes] + add esi,64 + inc ebx + dec byte[lineleft] + jnz near .ahb + emms + pop es + ret + +.scanlinesquart + inc dl + mov [lineleft],dl + ; do scanlines +.ahb2 + cmp byte[ebx],1 + jbe .ignorehrqs + call HighResProc + movq mm2,[HalfTransC] + jmp .returninterpqs +.ignorehrqs + mov eax,[esi+510] + mov ecx,64 + mov [esi+512],eax + mov edx,[spritetablea] + add edx,512 +.ah2 + movq mm0,[esi] + movq mm3,mm0 + movq mm4,mm0 + movq mm1,[esi+2] + pand mm3,mm1 + pand mm0,mm2 + pand mm1,mm2 + psrlw mm0,1 + psrlw mm1,1 + paddd mm0,mm1 + pand mm3,[HalfTransB] + paddw mm0,mm3 + movq mm5,mm4 + ; mm4/mm5 contains original values, mm0 contains mixed values + punpcklwd mm4,mm0 + punpckhwd mm5,mm0 + movq [edx],mm4 + movq [edx+8],mm5 + movq [edi],mm4 + movq [edi+8],mm5 + add esi,8 + add edi,16 + add edx,16 + dec ecx + jnz .ah2 + add edi,[AddEndBytes] + sub edx,16*64 + mov ecx,64 +.ahc2 + movq mm0,[edx] + movq mm1,[edx+8] + pand mm0,mm2 + pand mm1,mm2 + psrlw mm0,1 + psrlw mm1,1 + movq mm4,mm0 + movq mm5,mm1 + pand mm4,mm2 + pand mm5,mm2 + psrlw mm4,1 + psrlw mm5,1 + paddd mm0,mm4 + paddd mm1,mm5 + movq [edi],mm0 + movq [edi+8],mm1 + add edi,16 + add edx,16 + dec ecx + jnz .ahc2 +.returninterpqs + add esi,64 + add edi,[AddEndBytes] + inc ebx + dec byte[lineleft] + jnz near .ahb2 + emms + pop es + ret + +NEWSYM interpolate640x480x16bwin + cmp byte[FPUCopy],2 + je near MMXInterpolwin + + mov ebx,hirestiledat+1 + cmp byte[GUIOn],1 + je .loopabi + cmp byte[newengen],0 + je .loopabi + mov ebx,SpecialLine+1 +.loopabi + mov [InterPtr],ebx + + mov dl,[resolutn] + dec dl + dec dl + dec dl + cmp byte[scanlines],1 + je near .scanlines + cmp byte[scanlines],2 + je near .scanlinesquart + cmp byte[scanlines],3 + je near .scanlineshalf + inc dword[InterPtr] + mov [lineleft],dl + ; do first line + mov ecx,255 + mov edx,[spritetablea] +.a + mov ax,[esi] + mov bx,[esi+2] + and ebx,[HalfTrans+6] + and eax,[HalfTrans+6] + add ebx,eax + shl ebx,15 + mov bx,[esi] + mov [edi],ebx + mov [edx],ebx + add esi,2 + add edi,4 + add edx,4 + loop .a + add esi,66 + add edi,[AddEndBytes] + add edi,4 +.loopb + mov ebx,[InterPtr] + cmp byte[ebx],1 + jbe .ignorehr + call HighResProc + jmp .returninterp +.ignorehr + mov ecx,255 + mov edx,[spritetablea] +.c + mov ax,[esi] + mov bx,[esi+2] + and ebx,[HalfTrans+6] + and eax,[HalfTrans+6] + add ebx,eax + shl ebx,15 + mov eax,[edx] + mov bx,[esi] + and eax,[HalfTrans] + mov [edx],ebx + and ebx,[HalfTrans] + shr eax,1 + shr ebx,1 + add eax,ebx + mov [edi],eax + add esi,2 + add edi,4 + add edx,4 + loop .c + add edi,4 + add edi,[AddEndBytes] + mov edx,[spritetablea] + mov ecx,255 +.d + mov eax,[edx] + mov [edi],eax + add edx,4 + add edi,4 + loop .d + add esi,66 + inc dword[InterPtr] + add edi,[AddEndBytes] + add edi,4 + dec byte[lineleft] + jnz near .loopb + pop es + ret +.returninterp + add esi,64 + inc dword[InterPtr] + add edi,[AddEndBytes] + dec byte[lineleft] + jnz near .loopb + pop es + ret + +.scanlines + xor eax,eax + mov ebx,hirestiledat+1 + cmp byte[GUIOn],1 + je .loopabis + cmp byte[newengen],0 + je .loopabis + mov ebx,SpecialLine+1 +.loopabis +.loopab + mov ecx,255 + cmp byte[ebx],1 + jbe .ignorehrs + call HighResProc + jmp .returninterps +.ignorehrs + cmp byte[ebx],1 + je .yeshiresb +.ignorehrb + push ebx +.ab + mov ax,[esi] + mov bx,[esi+2] + and ebx,[HalfTrans+6] + and eax,[HalfTrans+6] + add ebx,eax + shl ebx,15 + mov bx,[esi] + mov [edi],ebx + add esi,2 + add edi,4 + dec ecx + jnz .ab + pop ebx +.returnb + add esi,66 + add edi,4 + add edi,[AddEndBytes] + add edi,[NumBytesPerLine] + inc ebx + dec dl + jnz .loopab + pop es + xor byte[res512switch],1 + ret +.yeshiresb + mov byte[ebx],0 + test byte[res512switch],1 + jnz .rightsideb +.bb + mov ax,[esi] + mov [edi],ax + add esi,2 + add edi,4 + dec ecx + jnz .bb + jmp .returnb +.rightsideb +.cb + mov ax,[esi] + mov [edi+2],ax + add esi,2 + add edi,4 + dec ecx + jnz .cb + jmp .returnb +.returninterps + add esi,64 + inc dword[InterPtr] + add edi,[AddEndBytes] + add edi,[NumBytesPerLine] + dec byte[lineleft] + jnz near .loopab + pop es + ret + +.scanlineshalf + xor eax,eax + mov [lineleft],dl +.loopab2 + mov ebx,[InterPtr] + cmp byte[ebx],1 + jbe .ignorehrhs + call HighResProc + jmp .returninterphs +.ignorehrhs + mov ecx,255 + mov edx,[spritetablea] + add edx,512 +.ab2 + mov ax,[esi] + mov bx,[esi+2] + and ebx,[HalfTrans+6] + and eax,[HalfTrans+6] + add ebx,eax + shl ebx,15 + mov bx,[esi] + mov [edx],ebx + mov [edi],ebx + add esi,2 + add edi,4 + add edx,4 + dec ecx + jnz .ab2 + add edi,4 + add edi,[AddEndBytes] + mov ecx,255 + mov edx,[spritetablea] + add edx,512 +.ab2b + mov eax,[edx] + and eax,[HalfTrans] + shr eax,1 + mov [edi],eax + add edi,4 + add edx,4 + dec ecx + jnz .ab2b + inc dword[InterPtr] + add esi,66 + add edi,4 + add edi,[AddEndBytes] + dec byte[lineleft] + jnz near .loopab2 + pop es + ret +.returninterphs + add esi,64 + inc dword[InterPtr] + add edi,[AddEndBytes] + dec byte[lineleft] + jnz near .loopab2 + pop es + ret + +.scanlinesquart + xor eax,eax + mov [lineleft],dl +.loopab3 + mov ebx,[InterPtr] + cmp byte[ebx],1 + jbe .ignorehrqs + call HighResProc + jmp .returninterpqs +.ignorehrqs + mov ecx,255 + mov edx,[spritetablea] + add edx,512 +.ab3 + mov ax,[esi] + mov bx,[esi+2] + and ebx,[HalfTrans+6] + and eax,[HalfTrans+6] + add ebx,eax + shl ebx,15 + mov bx,[esi] + mov [edx],ebx + mov [edi],ebx + add esi,2 + add edi,4 + add edx,4 + dec ecx + jnz .ab3 + add edi,AddEndBytes + add edi,4 + mov ecx,255 + mov edx,[spritetablea] + add edx,512 +.ab3b + mov eax,[edx] + and eax,[HalfTrans] + shr eax,1 + mov ebx,eax + and ebx,[HalfTrans] + shr ebx,1 + add eax,ebx + mov [edi],eax + add edi,4 + add edx,4 + dec ecx + jnz .ab3b + inc dword[InterPtr] + add esi,66 + add edi,4 + add edi,[AddEndBytes] + dec byte[lineleft] + jnz near .loopab3 + pop es + ret +.returninterpqs + add esi,64 + inc dword[InterPtr] + add edi,[AddEndBytes] + dec byte[lineleft] + jnz near .loopab3 + pop es + ret + +ALIGN32 +InterPtr dd 0 + +NEWSYM CopyVWinAsmEnd diff --git a/zsnes/src/linux/protect.c b/zsnes/src/linux/protect.c new file mode 100644 index 00000000..6fecc104 --- /dev/null +++ b/zsnes/src/linux/protect.c @@ -0,0 +1,206 @@ +//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. + +#include +#include +#include +#include + +extern void GuiAsmStart(); +extern void GuiAsmEnd(); +extern void SfxProcAsmStart(); +extern void SfxProcAsmEnd(); +extern void FxEmu2AsmStart(); +extern void FxEmu2AsmEnd(); +extern void Dsp1ProcAsmStart(); +extern void Dsp1ProcAsmEnd(); +extern void FxEmu2BAsmStart(); +extern void FxEmu2BAsmEnd(); +extern void FxEmu2CAsmStart(); +extern void FxEmu2CAsmEnd(); +extern void FxTableAsmStart(); +extern void FxTableAsmEnd(); +extern void ExecuteAsmStart(); +extern void ExecuteAsmEnd(); +extern void Sa1ProcAsmStart(); +extern void Sa1ProcAsmEnd(); +extern void Sa1RegsAsmStart(); +extern void Sa1RegsAsmEnd(); +extern void WinIntRFAsmStart(); +extern void WinIntRFAsmEnd(); +extern void ProcVidAsmStart(); +extern void ProcVidAsmEnd(); +extern void CfgLoadAsmStart(); +extern void CfgLoadAsmEnd(); +extern void IrqAsmStart(); +extern void IrqAsmEnd(); +extern void MemoryAsmStart(); +extern void MemoryAsmEnd(); +extern void Spc700AsmStart(); +extern void Spc700AsmEnd(); +extern void StableAsmStart(); +extern void StableAsmEnd(); +extern void DspProcAsmStart(); +extern void DspProcAsmEnd(); +extern void DmaAsmStart(); +extern void DmaAsmEnd(); +extern void DspAsmStart(); +extern void DspAsmEnd(); +extern void TableAsmStart(); +extern void TableAsmEnd(); +extern void TableBAsmStart(); +extern void TableBAsmEnd(); +extern void TableCAsmStart(); +extern void TableCAsmEnd(); +extern void CopyVWinAsmStart(); +extern void CopyVWinAsmEnd(); +extern void DebugAsmStart(); +extern void DebugAsmEnd(); +extern void JoyAsmStart(); +extern void JoyAsmEnd(); +extern void InitAsmStart(); +extern void InitAsmEnd(); +extern void UIAsmStart(); +extern void UIAsmEnd(); +extern void DosModemRTNAsmStart(); +extern void DosModemRTNAsmEnd(); +extern void Vesa2AsmStart(); +extern void Vesa2AsmEnd(); +extern void InitVidAsmStart(); +extern void InitVidAsmEnd(); +extern void SWAsmStart(); +extern void SWAsmEnd(); +extern void GPProAsmStart(); +extern void GPProAsmEnd(); +extern void Vesa12AsmStart(); +extern void Vesa12AsmEnd(); +extern void MenuAsmStart(); +extern void MenuAsmEnd(); +extern void MakeV16BAsmStart(); +extern void MakeV16BAsmEnd(); +extern void MakeV16TAsmStart(); +extern void MakeV16TAsmEnd(); +extern void MakeVidAsmStart(); +extern void MakeVidAsmEnd(); +extern void Mode716AsmStart(); +extern void Mode716AsmEnd(); +extern void Mode716BAsmStart(); +extern void Mode716BAsmEnd(); +extern void Mode716DAsmStart(); +extern void Mode716DAsmEnd(); +extern void Mode716EAsmStart(); +extern void Mode716EAsmEnd(); +extern void Mode716TAsmStart(); +extern void Mode716TAsmEnd(); +extern void Mode7AsmStart(); +extern void Mode7AsmEnd(); +extern void Mode7ExtAsmStart(); +extern void Mode7ExtAsmEnd(); +extern void M716TExtAsmStart(); +extern void M716TExtAsmEnd(); +extern void TwoxSaiWAsmStart(); +extern void TwoxSaiWAsmEnd(); +extern void EndMemAsmStart(); +extern void EndMemAsmEnd(); +extern void MV16TMSAsmStart(); +extern void MV16TMSAsmEnd(); +extern void NewG162AsmStart(); +extern void NewG162AsmEnd(); +extern void NewGfx16AsmStart(); +extern void NewGfx16AsmEnd(); +extern void NewGfx2AsmStart(); +extern void NewGfx2AsmEnd(); +extern void NewGfxAsmStart(); +extern void NewGfxAsmEnd(); +extern void VCacheAsmStart(); +extern void VCacheAsmEnd(); + +// Thanks QuakeForge +void MakeCodeWriteable (unsigned long startaddr, unsigned long length) +{ + int r; + unsigned int addr; + int psize = getpagesize(); + + + //fprintf(stderr, "Unprotecting 0x%x to 0x%x\n", startaddr, startaddr+length); + addr = (startaddr & ~(psize -1)) - psize; + + r = mprotect ((char *) addr, length + startaddr - addr + psize, 7); + + if (r < 0) + fprintf (stderr, "Error! Memory *NOT* unprotected.\n"); +} + +void UnProtectMemory(void) +{ + MakeCodeWriteable((long) SfxProcAsmStart, (long) SfxProcAsmEnd - (long) SfxProcAsmStart); + MakeCodeWriteable((long) FxEmu2AsmStart, (long) FxEmu2AsmEnd - (long) FxEmu2AsmStart); + MakeCodeWriteable((long) Dsp1ProcAsmStart, (long) Dsp1ProcAsmEnd - (long) Dsp1ProcAsmStart); + MakeCodeWriteable((long) FxEmu2BAsmStart, (long) FxEmu2BAsmEnd - (long) FxEmu2BAsmStart); + MakeCodeWriteable((long) FxEmu2CAsmStart, (long) FxEmu2CAsmEnd - (long) FxEmu2CAsmStart); + MakeCodeWriteable((long) FxTableAsmStart, (long) FxTableAsmEnd - (long) FxTableAsmStart); + MakeCodeWriteable((long) ExecuteAsmStart, (long) ExecuteAsmEnd - (long) ExecuteAsmStart); + MakeCodeWriteable((long) Sa1ProcAsmStart, (long) Sa1ProcAsmEnd - (long) Sa1ProcAsmStart); + MakeCodeWriteable((long) Sa1RegsAsmStart, (long) Sa1RegsAsmEnd - (long) Sa1RegsAsmStart); + MakeCodeWriteable((long) WinIntRFAsmStart, (long) WinIntRFAsmEnd - (long) WinIntRFAsmStart); + MakeCodeWriteable((long) GuiAsmStart, (long) GuiAsmEnd - (long) GuiAsmStart); + MakeCodeWriteable((long) ProcVidAsmStart, (long) ProcVidAsmEnd - (long) ProcVidAsmStart); + MakeCodeWriteable((long) CfgLoadAsmStart, (long) CfgLoadAsmEnd - (long) CfgLoadAsmStart); + MakeCodeWriteable((long) IrqAsmStart, (long) IrqAsmEnd - (long) IrqAsmStart); + MakeCodeWriteable((long) MemoryAsmStart, (long) MemoryAsmEnd - (long) MemoryAsmStart); + MakeCodeWriteable((long) Spc700AsmStart, (long) Spc700AsmEnd - (long) Spc700AsmStart); + MakeCodeWriteable((long) StableAsmStart, (long) StableAsmEnd - (long) StableAsmStart); + MakeCodeWriteable((long) DspProcAsmStart, (long) DspProcAsmEnd - (long) DspProcAsmStart); + MakeCodeWriteable((long) DmaAsmStart, (long) DmaAsmEnd - (long) DmaAsmStart); + MakeCodeWriteable((long) DspAsmStart, (long) DspAsmEnd - (long) DspAsmStart); + MakeCodeWriteable((long) TableAsmStart, (long) TableAsmEnd - (long) TableAsmStart); + MakeCodeWriteable((long) TableBAsmStart, (long) TableBAsmEnd - (long) TableBAsmStart); + MakeCodeWriteable((long) TableCAsmStart, (long) TableCAsmEnd - (long) TableCAsmStart); + MakeCodeWriteable((long) CopyVWinAsmStart, (long) CopyVWinAsmEnd - (long) CopyVWinAsmStart); + MakeCodeWriteable((long) DebugAsmStart, (long) DebugAsmEnd - (long) DebugAsmStart); + MakeCodeWriteable((long) JoyAsmStart, (long) JoyAsmEnd - (long) JoyAsmStart); + MakeCodeWriteable((long) InitAsmStart, (long) InitAsmEnd - (long) InitAsmStart); + MakeCodeWriteable((long) UIAsmStart, (long) UIAsmEnd - (long) UIAsmStart); + MakeCodeWriteable((long) DosModemRTNAsmStart, (long) DosModemRTNAsmEnd - (long) DosModemRTNAsmStart); + MakeCodeWriteable((long) Vesa2AsmStart, (long) Vesa2AsmEnd - (long) Vesa2AsmStart); + MakeCodeWriteable((long) InitVidAsmStart, (long) InitVidAsmEnd - (long) InitVidAsmStart); + MakeCodeWriteable((long) SWAsmStart, (long) SWAsmEnd - (long) SWAsmStart); + MakeCodeWriteable((long) GPProAsmStart, (long) GPProAsmEnd - (long) GPProAsmStart); + MakeCodeWriteable((long) Vesa12AsmStart, (long) Vesa12AsmEnd - (long) Vesa12AsmStart); + MakeCodeWriteable((long) MenuAsmStart, (long) MenuAsmEnd - (long) MenuAsmStart); + MakeCodeWriteable((long) MakeV16BAsmStart, (long) MakeV16BAsmEnd - (long) MakeV16BAsmStart); + MakeCodeWriteable((long) MakeV16TAsmStart, (long) MakeV16TAsmEnd - (long) MakeV16TAsmStart); + MakeCodeWriteable((long) MakeVidAsmStart, (long) MakeVidAsmEnd - (long) MakeVidAsmStart); + MakeCodeWriteable((long) Mode716AsmStart, (long) Mode716AsmEnd - (long) Mode716AsmStart); + + MakeCodeWriteable((long) Mode716BAsmStart, (long) Mode716BAsmEnd - (long) Mode716BAsmStart); + MakeCodeWriteable((long) Mode716DAsmStart, (long) Mode716DAsmEnd - (long) Mode716DAsmStart); + MakeCodeWriteable((long) Mode716EAsmStart, (long) Mode716EAsmEnd - (long) Mode716EAsmStart); + MakeCodeWriteable((long) Mode716TAsmStart, (long) Mode716TAsmEnd - (long) Mode716TAsmStart); + MakeCodeWriteable((long) Mode7AsmStart, (long) Mode7AsmEnd - (long) Mode7AsmStart); + MakeCodeWriteable((long) Mode7ExtAsmStart, (long) Mode7ExtAsmEnd - (long) Mode7ExtAsmStart); + MakeCodeWriteable((long) M716TExtAsmStart, (long) M716TExtAsmEnd - (long) M716TExtAsmStart); + MakeCodeWriteable((long) TwoxSaiWAsmStart, (long) TwoxSaiWAsmEnd - (long) TwoxSaiWAsmStart); + MakeCodeWriteable((long) EndMemAsmStart, (long) EndMemAsmEnd - (long) EndMemAsmStart); + MakeCodeWriteable((long) MV16TMSAsmStart, (long) MV16TMSAsmEnd - (long) MV16TMSAsmStart); + MakeCodeWriteable((long) NewG162AsmStart, (long) NewG162AsmEnd - (long) NewG162AsmStart); + MakeCodeWriteable((long) NewGfx16AsmStart, (long) NewGfx16AsmEnd - (long) NewGfx16AsmStart); + MakeCodeWriteable((long) NewGfx2AsmStart, (long) NewGfx2AsmEnd - (long) NewGfx2AsmStart); + MakeCodeWriteable((long) NewGfxAsmStart, (long) NewGfxAsmEnd - (long) NewGfxAsmStart); + MakeCodeWriteable((long) VCacheAsmStart, (long) VCacheAsmEnd - (long) VCacheAsmStart); +} diff --git a/zsnes/src/linux/resource.h b/zsnes/src/linux/resource.h new file mode 100644 index 00000000..ea19d442 --- /dev/null +++ b/zsnes/src/linux/resource.h @@ -0,0 +1,34 @@ +//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. + + +//{{NO_DEPENDENCIES}} +// Microsoft Developer Studio generated include file. +// Used by zloader.rc +// +#define IDI_ICON1 101 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 102 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1000 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif \ No newline at end of file diff --git a/zsnes/src/linux/sdllink.c b/zsnes/src/linux/sdllink.c new file mode 100644 index 00000000..04403874 --- /dev/null +++ b/zsnes/src/linux/sdllink.c @@ -0,0 +1,2787 @@ + +#ifdef __LINUX__ // AH +#include +#include +#include +#include "SDL.h" +#else // __WIN32__ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "resource.h" +#endif // __LINUX__ + +#define BYTE unsigned char +#define WORD unsigned short +#define DWORD unsigned long + +BYTE Tester[]={"WinTest1"}; + +DWORD WindowWidth = 256; +DWORD WindowHeight = 224; +DWORD FullScreen = 0; +BYTE TestID1[]={""}; +DWORD Moving= 0; +DWORD SoundBufferSize=1024*18; +DWORD FirstSound=1; +int AllowDefault=0; +int SoundEnabled=1; + +#ifdef __LINUX__ // AH +typedef enum {TRUE, FALSE} BOOL; +typedef void *HWND; +typedef void *MSG; +typedef void *HINSTANCE; +typedef void *LPVOID; +typedef void *DEVMODE; +typedef Uint32 UINT32; +typedef long long _int64; +typedef long long LARGE_INTEGER; +typedef int HRESULT; +#define STUB_FUNCTION fprintf(stderr,"STUB: %s at " __FILE__ ", line %d, thread %d\n",__FUNCTION__,__LINE__,getpid()) +#define FAR +#define PASCAL +#endif // __LINUX__ + +HWND hMainWindow; + +HINSTANCE hInst; + +#ifndef __LINUX__ // AH +LPDIRECTSOUND lpDirectSound; +LPDIRECTSOUNDBUFFER SoundBuffer; +LPDIRECTSOUNDBUFFER lpPrimaryBuffer; +DSBUFFERDESC dsbd; +#else +SDL_Surface *surface; +int sdl_inited = 0; +#endif // __LINUX__ + + LPVOID lpvPtr1; + DWORD dwBytes1; + LPVOID lpvPtr2; + DWORD dwBytes2; + +#ifndef __LINUX__ // AH +LPDIRECTDRAW BasiclpDD = NULL; + +LPDIRECTDRAW2 lpDD = NULL; +LPDIRECTDRAWSURFACE DD_Primary = NULL; +LPDIRECTDRAWSURFACE DD_CFB = NULL; +LPDIRECTDRAWCLIPPER lpDDClipper =NULL; +RECT rcWindow; + +LPDIRECTINPUT DInput; +LPDIRECTINPUTDEVICE MouseInput; +LPDIRECTINPUTDEVICE KeyboardInput; +LPDIRECTINPUTDEVICE7 JoystickInput[4]; +DIJOYSTATE js[4]; +#endif // __LINUX__ + +DWORD X1Disable[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; +DWORD X2Disable[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; +DWORD Y1Disable[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; +DWORD Y2Disable[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; +DWORD Z1Disable[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; +DWORD Z2Disable[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; +DWORD RX1Disable[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; +DWORD RX2Disable[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; +DWORD RY1Disable[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; +DWORD RY2Disable[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; +DWORD RZ1Disable[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; +DWORD RZ2Disable[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; +DWORD S01Disable[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; +DWORD S02Disable[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; +DWORD S11Disable[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; +DWORD S12Disable[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; + +DWORD CurrentJoy=0; + +DWORD BitDepth; +DWORD GBitMask; +BYTE BackColor=0; +DEVMODE mode; + +float MouseMinX=0; +float MouseMaxX=256; +float MouseMinY=0; +float MouseMaxY=223; +int MouseX; +int MouseY; +float MouseMoveX; +float MouseMoveY; +int MouseMove2X; +int MouseMove2Y; + +DWORD SurfaceX=0; +DWORD SurfaceY=0; + +Uint8 MouseButton; + + +#define UPDATE_TICKS_GAME 1000/60 // milliseconds per world update +#define UPDATE_TICKS_GAMEPAL 1000/50 // milliseconds per world update +#define UPDATE_TICKS_GUI 1000/36 // milliseconds per world update +#define UPDATE_TICKS_UDP 1000/60 // milliseconds per world update + +_int64 start, end, freq, update_ticks_pc, start2, end2, update_ticks_pc2; + + +extern unsigned char pressed[]; + + void drawscreenwin(void); + void Init_2xSaI(UINT32 BitFormat); + DWORD LastUsedPos=0; + DWORD CurMode=-1; + +DWORD InputEn=0; +BOOL InputAcquire(void) +{ +#ifdef __LINUX__ // AH + STUB_FUNCTION; +#else // __WIN32__ + if(JoystickInput[0]) JoystickInput[0]->Acquire(); + if(JoystickInput[1]) JoystickInput[1]->Acquire(); + if(JoystickInput[2]) JoystickInput[2]->Acquire(); + if(JoystickInput[3]) JoystickInput[3]->Acquire(); + + if(MouseInput) MouseInput->Acquire(); + if(KeyboardInput) KeyboardInput->Acquire(); + InputEn=1; + return TRUE; +#endif // __LINUX__ +} + +BOOL InputDeAcquire(void) +{ +#ifdef __LINUX__ // AH + STUB_FUNCTION; +#else // __WIN32__ + if(MouseInput) { MouseInput->Unacquire(); } + if(KeyboardInput) KeyboardInput->Unacquire(); + if(JoystickInput[0]) JoystickInput[0]->Unacquire(); + if(JoystickInput[1]) JoystickInput[1]->Unacquire(); + if(JoystickInput[2]) JoystickInput[2]->Unacquire(); + if(JoystickInput[3]) JoystickInput[3]->Unacquire(); +#endif // __LINUX__ + InputEn=0; + return TRUE; +} + +unsigned char keyboardhit=0; +void initwinvideo(); +extern BYTE StereoSound; +extern DWORD SoundQuality; +extern int CurKeyPos; +extern int CurKeyReadPos; +extern int KeyBuffer[16]; + + +BYTE PrevStereoSound; +DWORD PrevSoundQuality; + +void ExitFunction(void) +{ +#ifdef __LINUX__ + STUB_FUNCTION; +#else + ChangeDisplaySettings(NULL,0); +#endif // __LINUX__ +} + +#ifdef __LINUX__ // AH +int Main_Proc(void) +{ + // TODO: Main event loop + SDL_Event event; + + //STUB_FUNCTION; + while (SDL_PollEvent(&event)) { + switch(event.type) + { + case SDL_KEYDOWN: + if(event.key.keysym.sym == SDLK_ESCAPE) + { + SDL_Quit(); + exit(0); + } else { + if (pressed[event.key.keysym.sym]!=2) + pressed[event.key.keysym.sym]=1; + } + break; + case SDL_KEYUP: + pressed[event.key.keysym.sym]=0; + break; + } + } + return TRUE; +} +#else // __WIN32__ +LRESULT CALLBACK Main_Proc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + static bool shiftpr; + bool accept; + int vkeyval; + short zDelta; + + switch (uMsg) + { + case WM_KEYDOWN: // sent when user presses a key + if (!((CurKeyPos+1==CurKeyReadPos) || ((CurKeyPos+1==16) + && (CurKeyReadPos==0)))){ + accept=false; + +// char bla[256]; +// sprintf(bla,"%d",wParam); +// MessageBox(NULL,bla,"Key",MB_SYSTEMMODAL|MB_OK); + + if (wParam==16) + shiftpr=true; + if (((wParam>='A') && (wParam<='Z')) || + ((wParam>='a') && (wParam<='z')) || (wParam==27) || + (wParam==32) || (wParam==8) || (wParam==13) || (wParam==9)) { + accept=true; vkeyval=wParam; + } + if ((wParam>='0') && (wParam<='9')) { + accept=true; vkeyval=wParam; + if (shiftpr) { + switch (wParam) { + case '1': vkeyval='!'; break; + case '2': vkeyval='@'; break; + case '3': vkeyval='#'; break; + case '4': vkeyval='$'; break; + case '5': vkeyval='%'; break; + case '6': vkeyval='^'; break; + case '7': vkeyval='&'; break; + case '8': vkeyval='*'; break; + case '9': vkeyval='('; break; + case '0': vkeyval=')'; break; + } + } + } + if ((wParam>=VK_NUMPAD0) && (wParam<=VK_NUMPAD9)) { + accept=true; vkeyval=wParam-VK_NUMPAD0+'0'; + } + if (!shiftpr){ + switch (wParam) { + case 189: vkeyval='-'; accept=true; break; + case 187: vkeyval='='; accept=true; break; + case 219: vkeyval='['; accept=true; break; + case 221: vkeyval=']'; accept=true; break; + case 186: vkeyval=';'; accept=true; break; + case 222: vkeyval=39; accept=true; break; + case 188: vkeyval=','; accept=true; break; + case 190: vkeyval='.'; accept=true; break; + case 191: vkeyval='/'; accept=true; break; + case 192: vkeyval='`'; accept=true; break; + case 220: vkeyval=92; accept=true; break; + } + } else { + switch (wParam) { + case 189: vkeyval='_'; accept=true; break; + case 187: vkeyval='+'; accept=true; break; + case 219: vkeyval='{'; accept=true; break; + case 221: vkeyval='}'; accept=true; break; + case 186: vkeyval=':'; accept=true; break; + case 222: vkeyval='"'; accept=true; break; + case 188: vkeyval='<'; accept=true; break; + case 190: vkeyval='>'; accept=true; break; + case 191: vkeyval='?'; accept=true; break; + case 192: vkeyval='~'; accept=true; break; + case 220: vkeyval='|'; accept=true; break; + } + } + switch (wParam) { + case 33: vkeyval=256+73; accept=true; break; + case 38: vkeyval=256+72; accept=true; break; + case 36: vkeyval=256+71; accept=true; break; + case 39: vkeyval=256+77; accept=true; break; + case 12: vkeyval=256+76; accept=true; break; + case 37: vkeyval=256+75; accept=true; break; + case 34: vkeyval=256+81; accept=true; break; + case 40: vkeyval=256+80; accept=true; break; + case 35: vkeyval=256+79; accept=true; break; + case 107: vkeyval='+'; accept=true; break; + case 109: vkeyval='-'; accept=true; break; + case 106: vkeyval='*'; accept=true; break; + case 111: vkeyval='/'; accept=true; break; + case 110: vkeyval='.'; accept=true; break; + } + if (accept){ + KeyBuffer[CurKeyPos]=vkeyval; + CurKeyPos++; + if (CurKeyPos==16) CurKeyPos=0; + } + } + break; + case WM_KEYUP: // sent when user releases a key + if (wParam==16) + shiftpr=false; + break; + case WM_MOUSEMOVE: + if(MouseInput) MouseInput->Acquire(); + break; +/* case 0x020A: + zDelta = (short) HIWORD(wParam); + zDelta=120; + while (zDelta>0){ + zDelta-=120; + if (!((CurKeyPos+1==CurKeyReadPos) || ((CurKeyPos+1==16) + && (CurKeyReadPos==0)))){ + KeyBuffer[CurKeyPos]=72+256; + CurKeyPos++; + if (CurKeyPos==16) CurKeyPos=0; + } + } + while (zDelta<0){ + zDelta+=120; + if (!((CurKeyPos+1==CurKeyReadPos) || ((CurKeyPos+1==16) + && (CurKeyReadPos==0)))){ + KeyBuffer[CurKeyPos]=72+256; + CurKeyPos++; + if (CurKeyPos==16) CurKeyPos=0; + } + } + break;*/ + case WM_MOVE: + initwinvideo(); + break; + case WM_PAINT: + ValidateRect(hWnd,NULL); + break; + case WM_ACTIVATE: + if(LOWORD(wParam)==WA_INACTIVE) + { + ChangeDisplaySettings(NULL,0); + } + else + { + if(FullScreen==1) + { + ChangeDisplaySettings(&mode,0); + } + initwinvideo(); + } + InputAcquire(); + break; + case WM_SETFOCUS: + if(FullScreen==1) + { + ChangeDisplaySettings(&mode,0); + } + ShowWindow(hMainWindow, SW_SHOWNORMAL); + InputAcquire(); + break; + case WM_KILLFOCUS: + ChangeDisplaySettings(NULL,0); + InputDeAcquire(); + break; + case WM_DESTROY: + ChangeDisplaySettings(NULL,0); + PostQuitMessage(0); + break; + case WM_SETTEXT: + case WM_SHOWWINDOW: + case WM_SETTINGCHANGE: + case WM_SETICON: + case WM_CREATE: + case WM_SETREDRAW: + return DefWindowProc(hWnd,uMsg,wParam,lParam); + break; + default: + break; + } + return TRUE; +} +#endif // __LINUX__ + +#ifdef __LINUX__ // AH +int RegisterWinClass ( void ) +{ + // TODO: WM stuff goes here + STUB_FUNCTION; + return TRUE; +} +#else // __WIN32__ +int RegisterWinClass ( void ) +{ + WNDCLASS wcl; + + wcl.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW | CS_NOCLOSE ; + wcl.cbClsExtra = 0; + wcl.cbWndExtra = 0; + wcl.hIcon = LoadIcon(NULL,IDI_APPLICATION); + wcl.hCursor = NULL; + wcl.hInstance = hInst; + + wcl.lpfnWndProc = (WNDPROC)Main_Proc; + wcl.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); + wcl.lpszMenuName = NULL; + wcl.lpszClassName = "ZSNESWIN"; + + if (RegisterClass(&wcl) == 0) return FALSE; + + return TRUE; +} +#endif // __LINUX__ + +void ShutdownApplication() +{ + +} + +#ifdef __LINUX__ +void UpdateSound(void *userdata, Uint8 *stream, int len); + +int InitSound (void) +{ + static SDL_AudioSpec wanted; + + SDL_CloseAudio(); + + if (!SoundEnabled) return FALSE; + + PrevSoundQuality = SoundQuality; + PrevStereoSound = StereoSound; + + switch(SoundQuality) { + case 0: + wanted.freq = 8000; + wanted.samples = 1024*2; + break; + case 1: + wanted.freq = 11025; + wanted.samples = 1024*2; + break; + case 2: + wanted.freq = 22050; + wanted.samples = 1024*4; + break; + case 3: + wanted.freq = 44100; + wanted.samples = 1024*8; + break; + case 4: + wanted.freq = 16000; + wanted.samples = 1024*4; + break; + case 5: + wanted.freq = 32000; + wanted.samples = 1024*8; + break; + case 6: + wanted.freq = 48000; + wanted.samples = 1024*8; + break; + default: + wanted.freq = 11025; + wanted.samples = 1024*2; + break; + } + if (StereoSound) { + wanted.channels = 2; + wanted.samples *= 2; + } else { + wanted.channels = 1; + } + + wanted.samples /= 4; + + wanted.format = AUDIO_S16LSB; + wanted.userdata = NULL; + wanted.callback = UpdateSound; + + if (SDL_OpenAudio(&wanted, NULL) < 0) { + SoundEnabled = 0; + return FALSE; + } + SDL_PauseAudio(0); + + return TRUE; +} +#else // __WIN32__ +InitSound() +{ + HRESULT hr; + WAVEFORMATEX wfx; + + if (!SoundEnabled) return FALSE; + + PrevSoundQuality=SoundQuality; + PrevStereoSound=StereoSound; + + if(DS_OK == DirectSoundCreate(NULL, &lpDirectSound,NULL)) + { + hr = lpDirectSound->SetCooperativeLevel(hMainWindow, DSSCL_NORMAL ); + if (hr != DS_OK) {SoundEnabled=0; return FALSE;} + } + else + { + SoundEnabled=0; return FALSE; + } + + wfx.wFormatTag = WAVE_FORMAT_PCM; + switch(SoundQuality) + { + case 0: + wfx.nSamplesPerSec = 8000; + SoundBufferSize=1024*2; + break; + case 1: + wfx.nSamplesPerSec = 11025; + SoundBufferSize=1024*2; + break; + case 2: + wfx.nSamplesPerSec = 22050; + SoundBufferSize=1024*4; + break; + case 3: + wfx.nSamplesPerSec = 44100; + SoundBufferSize=1024*8; + break; + case 4: + wfx.nSamplesPerSec = 16000; + SoundBufferSize=1024*4; + break; + case 5: + wfx.nSamplesPerSec = 32000; + SoundBufferSize=1024*8; + break; + case 6: + wfx.nSamplesPerSec = 48000; + SoundBufferSize=1024*8; + break; + default: + wfx.nSamplesPerSec = 11025; + } + + if(StereoSound==1) + { + wfx.nChannels = 2; + wfx.nBlockAlign = 4; + SoundBufferSize*=2; + } + else + { + wfx.nChannels = 1; + wfx.nBlockAlign = 2; + } + + wfx.wBitsPerSample = 16; + wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign; + wfx.cbSize=0; + + memset(&dsbd, 0, sizeof(DSBUFFERDESC)); + dsbd.dwSize = sizeof(DSBUFFERDESC); + dsbd.dwFlags = DSBCAPS_STICKYFOCUS; // | DSBCAPS_PRIMARYBUFFER; + dsbd.dwBufferBytes = SoundBufferSize; + dsbd.lpwfxFormat = &wfx; + + hr = lpDirectSound->CreateSoundBuffer(&dsbd, &SoundBuffer, NULL); + + if(DS_OK == hr) + { + if(DS_OK != SoundBuffer->Play(0,0,DSBPLAY_LOOPING )) + { + SoundEnabled=0; return FALSE; + } + FirstSound=0; + return TRUE; + } + else + { + SoundEnabled=0; return FALSE; + } + +} +#endif // __LINUX__ + +#ifdef __LINUX__ // AH +int ReInitSound(void) +{ + return InitSound(); +} +#else // __WIN32__ +ReInitSound() +{ + HRESULT hr; + WAVEFORMATEX wfx; + + if (!SoundEnabled) return FALSE; + + SoundBuffer->Stop(); + SoundBuffer->Release(); + + PrevSoundQuality=SoundQuality; + PrevStereoSound=StereoSound; + + + wfx.wFormatTag = WAVE_FORMAT_PCM; + switch(SoundQuality) + { + case 0: + wfx.nSamplesPerSec = 8000; + SoundBufferSize=1024*2; + break; + case 1: + wfx.nSamplesPerSec = 11025; + SoundBufferSize=1024*2; + break; + case 2: + wfx.nSamplesPerSec = 22050; + SoundBufferSize=1024*4; + break; + case 3: + wfx.nSamplesPerSec = 44100; + SoundBufferSize=1024*8; + break; + case 4: + wfx.nSamplesPerSec = 16000; + SoundBufferSize=1024*4; + break; + case 5: + wfx.nSamplesPerSec = 32000; + SoundBufferSize=1024*8; + break; + case 6: + wfx.nSamplesPerSec = 48000; + SoundBufferSize=1024*8; + break; + + default: + wfx.nSamplesPerSec = 11025; + } + + if(StereoSound==1) + { + wfx.nChannels = 2; + wfx.nBlockAlign = 4; + SoundBufferSize*=2; + } + else + { + wfx.nChannels = 1; + wfx.nBlockAlign = 2; + } + + wfx.wBitsPerSample = 16; + wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign; + wfx.cbSize=0; + + memset(&dsbd, 0, sizeof(DSBUFFERDESC)); + dsbd.dwSize = sizeof(DSBUFFERDESC); + dsbd.dwFlags = DSBCAPS_STICKYFOCUS; + dsbd.dwBufferBytes = SoundBufferSize; + dsbd.lpwfxFormat = &wfx; + + hr = lpDirectSound->CreateSoundBuffer(&dsbd, &SoundBuffer, NULL); + + if(DS_OK == hr) + { + if(DS_OK != SoundBuffer->Play(0,0,DSBPLAY_LOOPING )) + { + return FALSE; + } + LastUsedPos=0; + return TRUE; + } + else + { + return FALSE; + } + +} +#endif // __LINUX__ + +#ifdef __LINUX__ // AH +BOOL InitJoystickInput(void) +{ + STUB_FUNCTION; + return TRUE; +} +#else // __WIN32__ +BOOL FAR PASCAL InitJoystickInput(LPCDIDEVICEINSTANCE pdinst, LPVOID pvRef) +{ + LPDIRECTINPUT7 pdi = (LPDIRECTINPUT7)pvRef; +// fprintf(tempf,"Cur :%d %X\n",CurrentJoy,pdinst->guidInstance); + GUID DeviceGuid = pdinst->guidInstance; + + if(CurrentJoy>3) + return DIENUM_CONTINUE; + + // Create the DirectInput joystick device. + if (pdi->CreateDeviceEx(DeviceGuid,IID_IDirectInputDevice7, + (void**)&JoystickInput[CurrentJoy], NULL) != DI_OK) + { +// fprintf(tempf,"IDirectInput7::CreateDeviceEx FAILED\n"); + return DIENUM_CONTINUE; + } + + if (JoystickInput[CurrentJoy]->SetDataFormat(&c_dfDIJoystick) != DI_OK) + { +// fprintf(tempf,"IDirectInputDevice7::SetDataFormat FAILED\n"); + JoystickInput[CurrentJoy]->Release(); + return DIENUM_CONTINUE; + } + + if(JoystickInput[CurrentJoy]->SetCooperativeLevel(hMainWindow, +DISCL_NONEXCLUSIVE | DISCL_FOREGROUND) != DI_OK) + { +// fprintf(tempf,"IDirectInputDevice7::SetCooperativeLevel FAILED\n"); + JoystickInput[CurrentJoy]->Release(); + return DIENUM_CONTINUE; + } + + + DIPROPRANGE diprg; + + diprg.diph.dwSize = sizeof(diprg); + diprg.diph.dwHeaderSize = sizeof(diprg.diph); + diprg.diph.dwObj = DIJOFS_X; + diprg.diph.dwHow = DIPH_BYOFFSET; + diprg.lMin = -1000; + diprg.lMax = +1000; + + if FAILED(JoystickInput[CurrentJoy]->SetProperty(DIPROP_RANGE, &diprg.diph)) + { +// fprintf(tempf,"IDirectInputDevice7::SetProperty(DIPH_RANGE) FAILED\n"); +// JoystickInput[CurrentJoy]->Release(); +// return FALSE; + X1Disable[CurrentJoy]=1; + X2Disable[CurrentJoy]=1; + } + + diprg.diph.dwObj = DIJOFS_Y; + + if FAILED(JoystickInput[CurrentJoy]->SetProperty(DIPROP_RANGE, &diprg.diph)) + { +// fprintf(tempf,"IDirectInputDevice7::SetProperty(DIPH_RANGE) FAILED\n"); +// JoystickInput[CurrentJoy]->Release(); +// return FALSE; + Y1Disable[CurrentJoy]=1; + Y2Disable[CurrentJoy]=1; + } + + + + diprg.diph.dwObj = DIJOFS_Z; + if(FAILED(JoystickInput[CurrentJoy]->SetProperty(DIPROP_RANGE, &diprg.diph))) + { + Z1Disable[CurrentJoy]=1; + Z2Disable[CurrentJoy]=1; + } + + diprg.diph.dwObj = DIJOFS_RX; + if(FAILED(JoystickInput[CurrentJoy]->SetProperty(DIPROP_RANGE, &diprg.diph))) + { + RX1Disable[CurrentJoy]=1; + RX2Disable[CurrentJoy]=1; + } + + diprg.diph.dwObj = DIJOFS_RY; + if(FAILED(JoystickInput[CurrentJoy]->SetProperty(DIPROP_RANGE, &diprg.diph))) + { + RY1Disable[CurrentJoy]=1; + RY2Disable[CurrentJoy]=1; + } + + diprg.diph.dwObj = DIJOFS_RZ; + if(FAILED(JoystickInput[CurrentJoy]->SetProperty(DIPROP_RANGE, &diprg.diph))) + { + RZ1Disable[CurrentJoy]=1; + RZ2Disable[CurrentJoy]=1; + } + + diprg.diph.dwObj = DIJOFS_SLIDER(0); + if(FAILED(JoystickInput[CurrentJoy]->SetProperty(DIPROP_RANGE, &diprg.diph))) + { + S01Disable[CurrentJoy]=1; + S02Disable[CurrentJoy]=1; + } + + diprg.diph.dwObj = DIJOFS_SLIDER(1); + if(FAILED(JoystickInput[CurrentJoy]->SetProperty(DIPROP_RANGE, &diprg.diph))) + { + S11Disable[CurrentJoy]=1; + S12Disable[CurrentJoy]=1; + } + + + + + DIPROPDWORD dipdw; + + dipdw.diph.dwSize = sizeof(DIPROPDWORD); + dipdw.diph.dwHeaderSize = sizeof(dipdw.diph); + dipdw.diph.dwHow = DIPH_BYOFFSET; + dipdw.dwData = 2500; + dipdw.diph.dwObj = DIJOFS_X; + JoystickInput[CurrentJoy]->SetProperty(DIPROP_DEADZONE, &dipdw.diph); + + dipdw.diph.dwObj = DIJOFS_Y; + JoystickInput[CurrentJoy]->SetProperty(DIPROP_DEADZONE, &dipdw.diph); + + dipdw.diph.dwObj = DIJOFS_Z; + JoystickInput[CurrentJoy]->SetProperty(DIPROP_DEADZONE, &dipdw.diph); + + dipdw.diph.dwObj = DIJOFS_RX; + JoystickInput[CurrentJoy]->SetProperty(DIPROP_DEADZONE, &dipdw.diph); + + dipdw.diph.dwObj = DIJOFS_RY; + JoystickInput[CurrentJoy]->SetProperty(DIPROP_DEADZONE, &dipdw.diph); + + dipdw.diph.dwObj = DIJOFS_RZ; + JoystickInput[CurrentJoy]->SetProperty(DIPROP_DEADZONE, &dipdw.diph); + + dipdw.diph.dwObj = DIJOFS_SLIDER(0); + JoystickInput[CurrentJoy]->SetProperty(DIPROP_DEADZONE, &dipdw.diph); + + dipdw.diph.dwObj = DIJOFS_SLIDER(1); + JoystickInput[CurrentJoy]->SetProperty(DIPROP_DEADZONE, &dipdw.diph); + + + + dipdw.diph.dwSize = sizeof(DIPROPDWORD); + dipdw.diph.dwHeaderSize = sizeof(dipdw.diph); + dipdw.diph.dwHow = DIPH_DEVICE; + dipdw.dwData = DIPROPAXISMODE_ABS; + dipdw.diph.dwObj = 0; + JoystickInput[CurrentJoy]->SetProperty(DIPROP_AXISMODE, &dipdw.diph); + + CurrentJoy+=1; +// fprintf(tempf,"joystick initialized!\n"); + + return DIENUM_CONTINUE; +} +#endif // __LINUX__ + +void endgame() +{ + +#ifdef __LINUX__ // AH + // TODO: Cleanup, dealloc buffers, etc. + STUB_FUNCTION; + SDL_Quit(); +#else // __WIN32__ + if(DD_CFB) + { + DD_CFB->Release(); + DD_CFB=NULL; + } + + + if(lpDD) + { + lpDD->Release(); + lpDD=NULL; + } + + + if(lpDDClipper) + { + lpDDClipper->Release(); + lpDDClipper=NULL; + } + + if(DD_Primary) + { + DD_Primary->Release(); + DD_Primary=NULL; + } +#endif // __LINUX__ +} + +#ifdef __WIN32__ // AH +void DInputError(){ + char message1[256]; + + sprintf(message1,"Error initializing DirectInput\nYou may need to install +DirectX 7.0a or higher located at www.microsoft.com/directx \0"); + MessageBox (NULL, message1, "Init Error" , MB_ICONERROR ); +} +#endif // __WIN32__ + +BOOL InitInput() +{ + char message1[256]; +#ifdef __LINUX__ // AH + STUB_FUNCTION; +#else // __WIN32__ + HRESULT hr; + + if(FAILED(hr=DirectInputCreate(hInst,DIRECTINPUT_VERSION,&DInput,NULL))) + { + sprintf(message1,"Error initializing DirectInput\nYou may need to install +DirectX 7.0a or higher located at www.microsoft.com/directx \0"); + MessageBox (NULL, message1, "Init Error" , MB_ICONERROR ); + + switch(hr) + { + case DIERR_BETADIRECTINPUTVERSION: + sprintf(message1,"Beta %X\n\0",hr); + MessageBox (NULL, message1, "Init", MB_ICONERROR ); + break; + case DIERR_INVALIDPARAM: + sprintf(message1,"Invalid %X\n\0",hr); + MessageBox (NULL, message1, "Init", MB_ICONERROR ); + break; + case DIERR_OLDDIRECTINPUTVERSION: + sprintf(message1,"OLDDIRECTINPUTVERSION %X\n\0",hr); + MessageBox (NULL, message1, "Init", MB_ICONERROR ); + break; + case DIERR_OUTOFMEMORY: + sprintf(message1,"OUTOFMEMORY %X\n\0",hr); + MessageBox (NULL, message1, "Init", MB_ICONERROR ); + break; + default: + sprintf(message1,"UNKNOWN %X\n\0",hr); + MessageBox (NULL, message1, "Init", MB_ICONERROR ); + break; + } + return FALSE; + } + + hr=DInput->CreateDevice(GUID_SysKeyboard, &KeyboardInput,NULL); + if(FAILED(hr)) {DInputError();return FALSE;} + + hr=KeyboardInput->SetDataFormat(&c_dfDIKeyboard); + if(FAILED(hr)) {DInputError();return FALSE;} + + + + hr=KeyboardInput->SetCooperativeLevel(hMainWindow,DISCL_NONEXCLUSIVE | +DISCL_FOREGROUND ); + + hr=DInput->CreateDevice(GUID_SysMouse, &MouseInput,NULL); + if(FAILED(hr)) {DInputError();return FALSE;} + + hr=MouseInput->SetDataFormat(&c_dfDIMouse); + if(FAILED(hr)) {DInputError();return FALSE;} + + +hr=MouseInput->SetCooperativeLevel(hMainWindow,DISCL_EXCLUSIVE|DISCL_FOREGROUND); + if(FAILED(hr)) {DInputError();return FALSE;} + + +JoystickInput[0]=NULL;JoystickInput[1]=NULL;JoystickInput[2]=NULL;JoystickInput[3]=NULL; + + + hr=DInput->EnumDevices(DIDEVTYPE_JOYSTICK, InitJoystickInput, + DInput, DIEDFL_ATTACHEDONLY); + if(FAILED(hr)) {DInputError();return FALSE;} + + + InputAcquire(); +#endif // __LINUX__ + return TRUE; + +} + +void TestJoy() +{ +#ifdef __LINUX__ // AH + STUB_FUNCTION; +#else // __WIN32__ + int i; + + for(i=0;i<4;i++) + { + if(JoystickInput[i]) + { + JoystickInput[i]->Poll(); +// memset(&js[i], 0, sizeof(DIJOYSTATE)); + + +if(IDirectInputDevice7_GetDeviceState(JoystickInput[i],sizeof(DIJOYSTATE), +&js[i])==DIERR_INPUTLOST) + { + if(JoystickInput[i]) JoystickInput[i]->Acquire(); + +if(FAILED(IDirectInputDevice7_GetDeviceState(JoystickInput[i],sizeof(DIJOYSTATE), +&js[i]))) return; + } + + + if(!X1Disable[i]) + { + if(js[i].lX>0) X1Disable[i]=1; + } + + if(!X2Disable[i]) + { + if(js[i].lX<0) X2Disable[i]=1; + } + + if(!Y1Disable[i]) + { + if(js[i].lY>0) Y1Disable[i]=1; + } + + if(!Y2Disable[i]) + { + if(js[i].lY<0) Y2Disable[i]=1; + } + + if(!Z1Disable[i]) + { + if(js[i].lZ>0) Z1Disable[i]=1; + } + + if(!Z2Disable[i]) + { + if(js[i].lZ<0) Z2Disable[i]=1; + } + + if(!RY1Disable[i]) + { + if(js[i].lRy>0) RY1Disable[i]=1; + } + if(!RY2Disable[i]) + { + if(js[i].lRy<0) RY2Disable[i]=1; + } + if(!RZ1Disable[i]) + { + if(js[i].lRz>0) RZ1Disable[i]=1; + } + if(!RZ2Disable[i]) + { + if(js[i].lRz<0) RZ2Disable[i]=1; + } + if(!S01Disable[i]) + { + if(js[i].rglSlider[0]>0) S01Disable[i]=1; + } + if(!S02Disable[i]) + { + if(js[i].rglSlider[0]<0) S02Disable[i]=1; + } + + if(!S11Disable[i]) + { + if(js[i].rglSlider[1]>0) S11Disable[i]=1; + } + if(!S12Disable[i]) + { + if(js[i].rglSlider[1]<0) S12Disable[i]=1; + } + + } + } +#endif // __LINUX__ +} + +DWORD converta; +unsigned int BitConv32Ptr; + +#ifdef __LINUX__ // AH +int startgame(void) +{ + unsigned int color32,ScreenPtr2; + int i; + Uint32 flags = SDL_SWSURFACE | SDL_HWPALETTE; + + //STUB_FUNCTION; + // This was crashing zsnes for some strange reason + ScreenPtr2=BitConv32Ptr; + for(i=0;i<65536;i++) + { + color32=((i&0xF800)<<8)+ + ((i&0x07E0)<<5)+ + ((i&0x001F)<<3)+0x7F000000; + (*(unsigned int *)(ScreenPtr2))=color32; + ScreenPtr2+=4; + } + // Temporary I hope - DDOI + BitDepth = 16; + // Check hardware for 565/555 + GBitMask = 0x07E0; + + if(BitDepth==16 && GBitMask!=0x07E0) + { + converta=1; + Init_2xSaI(555); + } + else + { + converta=0; + } + + if (sdl_inited == 0) { + if (SDL_Init(SDL_INIT_TIMER|SDL_INIT_VIDEO) < 0) { + fprintf(stderr, "Could not initialize SDL!\n"); + return FALSE; + } else { + sdl_inited = 1; + } + } + + flags != ( FullScreen ? SDL_FULLSCREEN : 0); + + surface = SDL_SetVideoMode(WindowWidth, WindowHeight, BitDepth, flags); + if (surface == NULL) { + fprintf (stderr, "Could not set %dx%dx%d video mode.\n",SurfaceX, + SurfaceY, BitDepth); + return FALSE; + } + SDL_WM_SetCaption ("ZSNES Linux","ZSNES"); + SDL_ShowCursor(0); + return TRUE; +} +#else // __WIN32__ +startgame() +{ + DDSURFACEDESC ddsd; + DDPIXELFORMAT format; + HRESULT hr; + char message1[256]; + unsigned int color32,ScreenPtr2; + int i; + + ScreenPtr2=BitConv32Ptr; + for(i=0;i<65536;i++) + { + color32=((i&0xF800)<<8)+ + ((i&0x07E0)<<5)+ + ((i&0x001F)<<3)+0x7F000000; + (*(unsigned int *)(ScreenPtr2))=color32; + ScreenPtr2+=4; + } + + GetClientRect(hMainWindow, &rcWindow ); + ClientToScreen(hMainWindow, ( LPPOINT )&rcWindow ); + ClientToScreen(hMainWindow, ( LPPOINT )&rcWindow + 1 ); + + if(FAILED(DirectDrawCreate(NULL,&BasiclpDD,NULL))) + { + return FALSE; + } + + + if(FAILED(BasiclpDD->SetCooperativeLevel(hMainWindow, DDSCL_NORMAL ))) + { + return FALSE; + } + + if(FAILED(BasiclpDD->QueryInterface(IID_IDirectDraw2,(LPVOID *)&lpDD))) + { + return FALSE; + } + + BasiclpDD->Release(); + + ddsd.dwSize = sizeof( ddsd ); + ddsd.dwFlags = DDSD_CAPS; + ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; + + if (FAILED(lpDD->CreateSurface( &ddsd, &DD_Primary, NULL ))) + { + return FALSE; + } + + + if (FAILED(lpDD->CreateClipper(0,&lpDDClipper,NULL))) + { + return FALSE; + } + + if (FAILED(lpDDClipper->SetHWnd(0,hMainWindow))) + { + return FALSE; + } + + if (FAILED( DD_Primary->SetClipper(lpDDClipper))) + { + return FALSE; + } + + format.dwSize = sizeof(DDPIXELFORMAT); + if (DD_Primary->GetPixelFormat(&format) != DD_OK) + { + return FALSE; + } + + BitDepth=format.dwRGBBitCount; + GBitMask=format.dwGBitMask; // 0x07E0 or not + + if(BitDepth==16&& GBitMask!=0x07E0) + { + converta=1; + Init_2xSaI(555); + } + else + { + converta=0; + } + + if(DD_CFB!=NULL) DD_CFB->Release(); + + DD_CFB=NULL; + + ddsd.dwSize = sizeof( ddsd ); + ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT |DDSD_WIDTH; + ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN ; + + ddsd.dwWidth = SurfaceX; + ddsd.dwHeight = SurfaceY; + + if ( lpDD->CreateSurface( &ddsd, &DD_CFB, NULL ) != DD_OK ) + { + DD_CFB = NULL; + return FALSE; + } + + return TRUE; +} +#endif // __LINUX__ + +BYTE* SurfBuf; + +DWORD LockSurface(void) +{ + // Lock SDL surface, return surface pitch + SDL_LockSurface(surface); + return(surface->pitch); +} + +void UnlockSurface(void) +{ + SDL_UnlockSurface(surface); + SurfBuf = surface->pixels; +} + +void WinUpdateDevices(); + +DWORD NeedBuffer=1; +short Buffer[1800*2]; +int Running=0; + +unsigned char Noise[]={ +27,232,234,138,187,246,176,81,25,241,1,127,154,190,195,103,231,165,220,238, +232,189,57,201,123,75,63,143,145,159,13,236,191,142,56,164,222,80,88,13, +148,118,162,212,157,146,176,0,241,88,244,238,51,235,149,50,77,212,186,241, +88,32,23,206,1,24,48,244,248,210,253,77,19,100,83,222,108,68,11,58, +152,161,223,245,4,105,3,82,15,130,171,242,141,2,172,218,152,97,223,157, +93,75,83,238,104,238,131,70,22,252,180,82,110,123,106,133,183,209,48,230, +157,205,27,21,107,63,85,164}; + + + int X, Y; + DWORD Temp1; + MSG msg; + DWORD SurfBufD; + int count, x,count2; + HRESULT hr; + int i; + short *Sound; + DWORD CurrentPos; + DWORD WritePos; + DWORD SoundBufD; + DWORD SoundBufD2; + + + +DWORD T60HZEnabled=0; +DWORD T36HZEnabled=0; + +extern unsigned char romispal; + +void Start60HZ(void) +{ + freq = 1000; + update_ticks_pc2 = UPDATE_TICKS_UDP * freq / 1000; + if(romispal==1) + { + update_ticks_pc = UPDATE_TICKS_GAMEPAL * freq / 1000; + } + else + { + update_ticks_pc = UPDATE_TICKS_GAME * freq / 1000; + } + + start = SDL_GetTicks(); + start2 = SDL_GetTicks(); + // QueryPerformanceCounter((LARGE_INTEGER*)&start); +// QueryPerformanceCounter((LARGE_INTEGER*)&start2); + T36HZEnabled=0; + T60HZEnabled=1; +} + +void Stop60HZ(void) +{ + T60HZEnabled=0; +} + +void Start36HZ(void) +{ + freq = 1000; + update_ticks_pc2 = UPDATE_TICKS_UDP * freq / 1000; + update_ticks_pc = UPDATE_TICKS_GUI * freq / 1000; +// QueryPerformanceCounter((LARGE_INTEGER*)&start); +// QueryPerformanceCounter((LARGE_INTEGER*)&start2); + + start = SDL_GetTicks(); + start2 = SDL_GetTicks(); + T60HZEnabled=0; + T36HZEnabled=1; +} + +void Stop36HZ(void) +{ + T36HZEnabled=0; +} + +char WinMessage[256]; +extern unsigned char cvidmode; +DWORD FirstVid=1; +DWORD FirstFull=1; +extern BYTE GUIWFVID[]; +void clearwin(); + +char WinName[]={"ZSNESW\0"}; +void initwinvideo(void) +{ +#ifdef __LINUX__ + //RECT zwindowrect; + // WINDOWPLACEMENT wndpl; + //RECT rc1, swrect; + DWORD newmode=0; + + STUB_FUNCTION; + + if(CurMode!=cvidmode) + { + CurMode=cvidmode; + newmode=1; + SurfaceX=256; + SurfaceY=224; + X=0; + Y=0; + FullScreen=GUIWFVID[cvidmode]; + + switch(cvidmode) + { + case 0: + WindowWidth=64; + WindowHeight=56; + break; + case 1: + WindowWidth=128; + WindowHeight=112; + break; + case 2: + WindowWidth=256; + WindowHeight=224; + break; + case 3: + WindowWidth=640; + WindowHeight=480; + SurfaceX=320; + SurfaceY=240; + break; + case 4: + WindowWidth=512; + WindowHeight=448; + break; + case 5: + WindowWidth=512; + WindowHeight=448; + SurfaceX=512; + SurfaceY=448; + break; + case 6: + WindowWidth=640; + WindowHeight=480; + break; + case 7: + WindowWidth=640; + WindowHeight=480; + SurfaceX=640; + SurfaceY=480; + break; + case 8: + WindowWidth=640; + WindowHeight=480; + SurfaceX=512; + SurfaceY=448; + break; + case 9: + WindowWidth=640; + WindowHeight=480; + break; + case 10: + WindowWidth=800; + WindowHeight=600; + break; + case 11: + WindowWidth=800; + WindowHeight=600; + SurfaceX=512; + SurfaceY=448; + break; + case 12: + WindowWidth=800; + WindowHeight=600; + break; + case 13: + WindowWidth=800; + WindowHeight=600; + SurfaceX=512; + SurfaceY=448; + break; + case 14: + WindowWidth=1024; + WindowHeight=768; + break; + case 15: + WindowWidth=1024; + WindowHeight=768; + SurfaceX=512; + SurfaceY=448; + break; + case 16: + WindowWidth=1024; + WindowHeight=768; + break; + case 17: + WindowWidth=1024; + WindowHeight=768; + SurfaceX=512; + SurfaceY=448; + break; + default: + WindowWidth=256; + WindowHeight=224; + break; + } + } + + if(startgame()!=TRUE) {return; } + if(newmode==1) clearwin(); + + if (FirstVid == 1) { + FirstVid = 0; + + InitSound(); + } + if(((PrevStereoSound!=StereoSound)||(PrevSoundQuality!=SoundQuality))) + ReInitSound(); +#else + if(FirstVid!=1) + { +// sprintf(WinMessage,"FirstVid!=1 start\n\0"); +// MessageBox (NULL, WinMessage, "Init", MB_ICONERROR ); + + if(X<0)X=0; + if(X>(GetSystemMetrics( SM_CXSCREEN )-WindowWidth)) X=(GetSystemMetrics( +SM_CXSCREEN )-WindowWidth); + if(Y<0)Y=0; + if(Y>(GetSystemMetrics( SM_CYSCREEN )-WindowHeight)) Y=(GetSystemMetrics( +SM_CYSCREEN )-WindowHeight); + if(FullScreen==1) {X=0; Y=0;} + + MoveWindow( hMainWindow, X, Y, + WindowWidth, WindowHeight, TRUE ); + + wndpl.length = sizeof(wndpl); + GetWindowPlacement( hMainWindow, &wndpl); + SetRect( &rc1, 0, 0, WindowWidth, WindowHeight ); + + AdjustWindowRectEx( &rc1,GetWindowLong( hMainWindow, GWL_STYLE ), + GetMenu( hMainWindow ) != NULL, GetWindowLong( hMainWindow, GWL_EXSTYLE ) +); +// X=(GetSystemMetrics( SM_CXSCREEN ) - WindowWidth) / 2; +// Y=(GetSystemMetrics( SM_CYSCREEN ) - WindowHeight) / 2; + + GetClientRect( hMainWindow, &rc1 ); + ClientToScreen( hMainWindow, ( LPPOINT )&rc1 ); + ClientToScreen( hMainWindow, ( LPPOINT )&rc1 + 1 ); +// return; +// sprintf(WinMessage,"FirstVid!=1 end\n\0"); +// MessageBox (NULL, WinMessage, "Init", MB_ICONERROR ); + +// MoveScreen(wndpl.rcNormalPosition.left, wndpl.rcNormalPosition.top); + } + else + { + FirstVid=0; + if (!QueryPerformanceFrequency((LARGE_INTEGER*)&freq)) return; +// hInst=GetModuleHandle(0); + if ( !RegisterWinClass() ); // { return; } + X=(GetSystemMetrics( SM_CXSCREEN ) - WindowWidth) / 2; + Y=(GetSystemMetrics( SM_CYSCREEN ) - WindowHeight) / 2; + if(FullScreen==1) {X=0; Y=0;} + if(hMainWindow) CloseWindow(hMainWindow); + + hMainWindow = CreateWindow( "ZSNESWIN", WinName, WS_VISIBLE|WS_POPUP,X,Y, +//WS_OVERLAPPED "ZSNESWIN" + WindowWidth,WindowHeight,NULL,NULL,hInst,NULL); + + if(!hMainWindow) { return; } + + ShowWindow(hMainWindow, SW_SHOWNORMAL); + SetWindowText(hMainWindow,"ZSNESWIN"); + InitInput(); + InitSound(); + TestJoy(); + } + + + if(Moving==1) return; + if(FullScreen==1) + { + if(FirstFull==1) + { + atexit(ExitFunction); + } + mode.dmSize=sizeof(DEVMODE); + mode.dmBitsPerPel=16; + mode.dmPelsWidth=WindowWidth; + mode.dmPelsHeight=WindowHeight; + mode.dmDisplayFlags=0; + mode.dmDisplayFrequency=0; + mode.dmFields=DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT; + ChangeDisplaySettings(&mode,0); + } + else + { + ChangeDisplaySettings(NULL,0); + } + //endgame(); + + if(startgame()!=TRUE) {return; } + if(newmode==1) clearwin(); +// MessageBox (NULL, "Done", "Init", MB_ICONERROR ); +#endif // __LINUX__ +} + +extern unsigned int vidbuffer; +extern void SoundProcess(); +extern int DSPBuffer; +int * DSPBuffer1; +DWORD ScreenPtr; +DWORD ScreenPtr2; +extern int GUI36hzcall(void); +extern int Game60hzcall(void); +extern int packettimeleft[256]; +extern int PacketCounter; +extern int CounterA; +extern int CounterB; + + +void CheckTimers(void) +{ + int i; + //QueryPerformanceCounter((LARGE_INTEGER*)&end2); + end2 = SDL_GetTicks(); + while ((end2 - start2) >= update_ticks_pc2) + { + if (CounterA>0) CounterA--; + if (CounterB>0) CounterB--; + if (PacketCounter){ + for (i=0;i<256;i++){ + if (packettimeleft[i]>0) + packettimeleft[i]--; + } + } + start2 += update_ticks_pc2; + } + + if(T60HZEnabled) + { + //QueryPerformanceCounter((LARGE_INTEGER*)&end); + end = SDL_GetTicks(); + + while ((end - start) >= update_ticks_pc) + { +// _asm{ +// pushad +// call Game60hzcall +// popad +// } + Game60hzcall(); + start += update_ticks_pc; + } + } + + if(T36HZEnabled) + { + //QueryPerformanceCounter((LARGE_INTEGER*)&end); + end = SDL_GetTicks(); + + while ((end - start) >= update_ticks_pc) + { +// _asm{ +// pushad +// call GUI36hzcall +// popad +// } + GUI36hzcall(); + start += update_ticks_pc; + } + } +} + +#ifdef __LINUX__ +void UpdateSound(void *userdata, Uint8 *stream, int len) +{ + int SPCSize = 256; + int DataNeeded; + int i; + Uint8 *ptr; + + ptr = stream; + DataNeeded = len; + + //DataNeeded /= (SPCSize * 2); + //DataNeeded *= (SPCSize * 2); + + while (DataNeeded > 0) { + SoundProcess(); + + DSPBuffer1=(int *)&DSPBuffer; + + for (i = 0; i < SPCSize; i++) { + if (T36HZEnabled) { + Buffer[i]=0; + } else { + if(DSPBuffer1[i]>32767)Buffer[i]=32767; + else if(DSPBuffer1[i]<-32767)Buffer[i]=-32767; + else Buffer[i]=DSPBuffer1[i]; + } + } + + memcpy(ptr, &Buffer[0], SPCSize*2); + ptr += SPCSize*2; + + DataNeeded -= (SPCSize*2); + } +} +#endif + +void UpdateVFrame(void) +{ +#ifdef __LINUX__ + //STUB_FUNCTION; + Main_Proc(); + + WinUpdateDevices(); + CheckTimers(); + + SDL_UpdateRect(surface,0,0,0,0); +#else + int DataNeeded; + int SPCSize=256; + + if(StereoSound==1)SPCSize=256; + + while (PeekMessage(&msg,NULL,0,0,PM_REMOVE)) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + + WinUpdateDevices(); + CheckTimers(); + + if (!SoundEnabled) return; + + SoundBuffer->GetCurrentPosition(&CurrentPos,&WritePos); + + if(LastUsedPos <= CurrentPos) + { + DataNeeded=CurrentPos-LastUsedPos; + } + else + { + DataNeeded=SoundBufferSize- LastUsedPos + CurrentPos; + } + + DataNeeded/=(SPCSize*2); + DataNeeded*=(SPCSize*2); + + while(DataNeeded>0) + { + _asm + { + pushad + call SoundProcess + popad + } + + DSPBuffer1=(int *)&DSPBuffer; + + for(i=0;i32767)Buffer[i]=32767; + if(DSPBuffer1[i]<-32767)Buffer[i]=-32767; + if(T36HZEnabled)Buffer[i]=0; + } + + if(DS_OK!=SoundBuffer->Lock(LastUsedPos, + SPCSize*2, &lpvPtr1, + &dwBytes1, &lpvPtr2, + &dwBytes2, 0)) + { + return; + } + + Sound=(short *)lpvPtr1; + + CopyMemory(lpvPtr1, &Buffer[0], dwBytes1); + + if(NULL != lpvPtr2) + { + CopyMemory(lpvPtr2, &Buffer[0]+dwBytes1, dwBytes2); + } + + if(DS_OK != SoundBuffer->Unlock(lpvPtr1, dwBytes1, lpvPtr2, dwBytes2)) + { + return; + } + + LastUsedPos+=SPCSize*2; + if(LastUsedPos==SoundBufferSize) LastUsedPos=0; + DataNeeded-=(SPCSize*2); + } +#endif // __LINUX__ +} + +extern unsigned char curblank; +extern DWORD AddEndBytes; +extern DWORD NumBytesPerLine; +extern unsigned char * WinVidMemStart; +extern void copy640x480x16bwin(void); +extern unsigned char FPUCopy; +extern unsigned char NGNoTransp; +extern unsigned char newengen; + +void clearwin() +{ + DWORD i,j,color32; + DWORD *SURFDW; + +#ifdef __LINUX__ + Temp1=LockSurface(); + if(Temp1==0) { return; } + STUB_FUNCTION; + + SurfBufD=(DWORD) &SurfBuf[0]; + SURFDW=(DWORD *) &SurfBuf[0]; + switch(BitDepth) + { + case 16: +/* + __asm__ __volatile__ (" + pushl %%es + movw %%ds, %%ax + movw %%ax, %%es + xorl %%eax, %%eax + movl SurfBufD, %%edi + xorl %%ebx, %%ebx + Blank2: + xorl %%eax, %%eax + movl SurfaceX, %%ecx + rep stosw + addl Temp1, %%edi + subl SurfaceX, %%edi + subl SurfaceX, %%edi + addl $1, %%ebx + cmpl SurfaceX, %%ebx + jne Blank2 + " : : : "cc", "memory", "eax", "ebx", "ecx","edi", "esi"); + break; + */ + case 32: + /* + _asm { + push es + mov ax,ds + mov es,ax + xor eax,eax + mov edi,SurfBufD + xor ebx,ebx + Blank3: + xor eax,eax + mov ecx,SurfaceX + rep stosd + add edi,Temp1 + sub edi,SurfaceX + sub edi,SurfaceX + sub edi,SurfaceX + sub edi,SurfaceX + add ebx,1 + cmp ebx,SurfaceY + jne Blank3 + } + */ + break; + } + UnlockSurface(); +#else + Temp1=LockSurface(); + if(Temp1==0) { return; } + + SurfBufD=(DWORD) &SurfBuf[0]; + SURFDW=(DWORD *) &SurfBuf[0]; + + switch(BitDepth) + { + case 16: + _asm { + push es + mov ax,ds + mov es,ax + xor eax,eax + mov edi,SurfBufD + xor ebx,ebx + Blank2: + xor eax,eax + mov ecx,SurfaceX + rep stosw + add edi,Temp1 + sub edi,SurfaceX + sub edi,SurfaceX + add ebx,1 + cmp ebx,SurfaceY + jne Blank2 + } + break; + case 32: + _asm { + push es + mov ax,ds + mov es,ax + xor eax,eax + mov edi,SurfBufD + xor ebx,ebx + Blank3: + xor eax,eax + mov ecx,SurfaceX + rep stosd + add edi,Temp1 + sub edi,SurfaceX + sub edi,SurfaceX + sub edi,SurfaceX + sub edi,SurfaceX + add ebx,1 + cmp ebx,SurfaceY + jne Blank3 + } + break; + } + UnlockSurface(); +#endif +} + +void drawscreenwin(void) +{ + DWORD i,j,color32; + DWORD *SURFDW; + + NGNoTransp = 0; // Set this value to 1 within the appropriate + // video mode if you want to add a custom + // transparency routine or hardware + // transparency. This only works if + // the value of newengen is equal to 1. + // (see ProcessTransparencies in newgfx16.asm + // for ZSNES' current transparency code) +#ifdef __LINUX__ + //STUB_FUNCTION; + UpdateVFrame(); + if(curblank!=0) return; + + Temp1=LockSurface(); + if(Temp1==0) { return; } + + ScreenPtr=vidbuffer; + ScreenPtr+=16*2+32*2+256*2; + SurfBufD=(DWORD) &SurfBuf[0]; + SURFDW=(DWORD *) &SurfBuf[0]; + + if(SurfaceX==256&&SurfaceY==224) + { + switch(BitDepth) + { + case 16: + if (FPUCopy){ + __asm__ __volatile__ (" + pushw %%es + movw %%ds, %%ax + movw %%ax, %%es + xorl %%eax, %%eax + movl ScreenPtr, %%esi + movl SurfBufD, %%edi + Copying3: + movl $32, %%ecx + CopyLoop: + movq (%%esi), %%mm0 + movq 8(%%esi), %%mm1 + movq %%mm0, (%%edi) + movq %%mm1, 8(%%edi) + addl $16, %%esi + addl $16, %%edi + decl %%ecx + jnz CopyLoop + incl %%eax + addl Temp1, %%edi + subl $512, %%edi + subl $512, %%esi + addl $576, %%esi + cmpl $223, %%eax + jne Copying3 + + xorl %%eax, %%eax + movl $128, %%ecx + rep stosl + popw %%es + emms + " : : : "cc", "memory", "eax", "ebx", "ecx","edi", "esi"); + } else { + // Doesn't seem to work - DDOI + __asm__ __volatile__ (" + pushw %%es + movw %%ds, %%ax + movw %%ax, %%es + xorl %%eax, %%eax + movl ScreenPtr, %%esi + movl SurfBufD, %%edi + Copying: + movl $128, %%ecx + rep movsl + incl %%eax + addl Temp1, %%edi + subl $512, %%edi + subl $512, %%esi + addl $576, %%esi + cmpl $223, %%eax + jne Copying + xorl %%eax, %%eax + movl $128, %%ecx + rep stosl + popw %%es + " : : : "cc", "memory", "eax", "ebx", "ecx","edi", "esi"); + } + break; + case 32: + // Untested - DDOI + __asm__ __volatile__ (" + pushw %%es + movw %%ds, %%ax + movw %%ax, %%es + xorl %%eax, %%eax + movl BitConv32Ptr, %%ebx + movl ScreenPtr, %%esi + movl SurfBufD, %%edi + Copying32b: + movl $256, %%ecx + pushl %%eax + xorl %%eax, %%eax + CopyLoop32b: + movw (%%esi), %%ax + addl $2, %%esi + movl (%%ebx, %%eax, 4), %%edx + movl %%edx, (%%edi) + addl $4, %%edi + loop CopyLoop32b + popl %%eax + incl %%eax + addl Temp1, %%edi + subl $1024, %%edi + subl $512, %%esi + addl $576, %%esi + cmpl $223, %%eax + jne Copying32b + popw %%es + " : : : "cc", "memory", "eax", "ebx", "ecx","edi", "esi"); + SURFDW=(DWORD *) &SurfBuf[222*Temp1]; + color32=0x7F000000; + + for(i=0;i<256;i++) + { + SURFDW[i]=color32; + } + + SURFDW=(DWORD *) &SurfBuf[223*Temp1]; + color32=0x7F000000; + + for(i=0;i<256;i++) + { + SURFDW[i]=color32; + } + break; + case 24: + fprintf (stderr, "Sorry, ZSNES does not work in windowed 24 bit color modes.\nSwitching to fullscreen mode\n"); + cvidmode=3; + initwinvideo(); + sleep(1000); + drawscreenwin(); + break; + default: + UnlockSurface(); + fprintf(stderr, "Mode only available in 16 and 32 bit color.\n"); + cvidmode=2; + initwinvideo(); + sleep(1000); + drawscreenwin(); + break; + } // switch (BitDepth) + } // if(SurfaceX==256&&SurfaceY==224) + + if(SurfaceX==320&&SurfaceY==240) + { + switch(BitDepth) + { + case 16: + if (FPUCopy) { + STUB_FUNCTION; + } else { + STUB_FUNCTION; + } + break; + case 32: + for(j=0;j<8;j++) + { + SURFDW=(DWORD *) &SurfBuf[j*Temp1]; + color32=0x7F000000; + + for(i=0;i<320;i++) + { + SURFDW[i]=color32; + } + } + + for(j=8;j<223+8;j++) + { + color32=0x7F000000; + for(i=0;i<32;i++) + { + SURFDW[i]=color32; + } + + for(i=32;i<(256+32);i++) + { + color32=(((*(WORD *)(ScreenPtr))&0xF800)<<8)+ + (((*(WORD *)(ScreenPtr))&0x07E0)<<5)+ + (((*(WORD *)(ScreenPtr))&0x001F)<<3)+0x7F000000; + // SURFDW[i]=color32; + ScreenPtr+=2; + } + + color32=0x7F000000; + for(i=(256+32);i<320;i++) + { + SURFDW[i]=color32; + } + + ScreenPtr=ScreenPtr+576-512; + SURFDW=(DWORD *) &SurfBuf[(j)*Temp1]; + } + + for(j=(223+8);j<240;j++) + { + SURFDW=(DWORD *) &SurfBuf[j*Temp1]; + + color32=0x7F000000; + for(i=0;i<320;i++) + { + SURFDW[i]=color32; + } + } + break; + default: + UnlockSurface(); + fprintf(stderr, "Mode only available in 16 and 32 bit color.\n"); + cvidmode=2; + initwinvideo(); + sleep(1000); + drawscreenwin(); + break; + } // switch + } // if + + if(SurfaceX==512&&SurfaceY==448) + { + switch(BitDepth) + { + case 16: + AddEndBytes=Temp1-1024; + NumBytesPerLine=Temp1; + WinVidMemStart=&SurfBuf[0]; + copy640x480x16bwin(); + break; + default: + UnlockSurface(); + fprintf(stderr, "Mode only available in 16 and 32 bit color.\n"); + cvidmode=2; + initwinvideo(); + sleep(1000); + drawscreenwin(); + break; + } // switch + } // if + + + UnlockSurface(); +#else + UpdateVFrame(); + if(curblank!=0) return; + + Temp1=LockSurface(); + if(Temp1==0) { return; } + + ScreenPtr=vidbuffer; + ScreenPtr+=16*2+32*2+256*2; + SurfBufD=(DWORD) &SurfBuf[0]; + SURFDW=(DWORD *) &SurfBuf[0]; + if(SurfaceX==256&&SurfaceY==224) + { + switch(BitDepth) + { + case 16: + if (FPUCopy){ + _asm { + push es + mov ax,ds + mov es,ax + xor eax,eax + mov esi,ScreenPtr + mov edi,SurfBufD + Copying3: + mov ecx,32 + CopyLoop: + movq mm0,[esi] + movq mm1,[esi+8] + movq [edi],mm0 + movq [edi+8],mm1 + add esi,16 + add edi,16 + dec ecx + jnz CopyLoop + inc eax + add edi,Temp1 + sub edi,512 + sub esi,512 + add esi,576 + cmp eax,223 + jne Copying3 + + xor eax,eax + mov ecx,128 + rep stosd + pop es + emms + } + } else { + _asm { + push es + mov ax,ds + mov es,ax + xor eax,eax + mov esi,ScreenPtr + mov edi,SurfBufD + Copying: + mov ecx,128 + rep movsd + inc eax + add edi,Temp1 + sub edi,512 + sub esi,512 + add esi,576 + cmp eax,223 + jne Copying + + xor eax,eax + mov ecx,128 + rep stosd + pop es + } + } + break; + case 32: + _asm { + push es + mov ax,ds + mov es,ax + xor eax,eax + mov ebx,BitConv32Ptr + mov esi,ScreenPtr + mov edi,SurfBufD + Copying32b: + mov ecx,256 + push eax + xor eax,eax + CopyLoop32b: + mov ax,[esi] + add esi,2 + mov edx,[ebx+eax*4] + mov [edi],edx + add edi,4 + loop CopyLoop32b + pop eax + inc eax + add edi,Temp1 + sub edi,1024 + sub esi,512 + add esi,576 + cmp eax,223 + jne Copying32b + pop es + } + + +/* for(j=0;j<223;j++) + { + for(i=0;i<256;i++) + { + color32=(((*(WORD *)(ScreenPtr))&0xF800)<<8)+ + (((*(WORD *)(ScreenPtr))&0x07E0)<<5)+ + (((*(WORD *)(ScreenPtr))&0x001F)<<3)+0x7F000000; + SURFDW[i]=color32; + ScreenPtr+=2; + } + ScreenPtr=ScreenPtr+576-512; + SURFDW=(DWORD *) &SurfBuf[j*Temp1]; + } */ + + SURFDW=(DWORD *) &SurfBuf[222*Temp1]; + color32=0x7F000000; + + for(i=0;i<256;i++) + { + SURFDW[i]=color32; + } + + SURFDW=(DWORD *) &SurfBuf[223*Temp1]; + color32=0x7F000000; + + for(i=0;i<256;i++) + { + SURFDW[i]=color32; + } + break; + case 24: + MessageBox (NULL, "Sorry. ZSNESw does not work in windowed 24 bit +color modes. \nClick 'OK' to switch to a full screen mode.", "DDRAW Error" , +MB_ICONERROR ); + cvidmode=3; + initwinvideo(); + Sleep(1000); + drawscreenwin(); + break; + default: + UnlockSurface(); + MessageBox (NULL, "Mode only available in 16 and 32 bit color", +"DDRAW Error" , MB_ICONERROR ); + cvidmode=2; + initwinvideo(); + Sleep(1000); + drawscreenwin(); +// exit(0); + break; + } + } + + if(SurfaceX==320&&SurfaceY==240) + { + switch(BitDepth) + { + case 16: + if (FPUCopy){ + _asm { + push es + mov ax,ds + mov es,ax + xor eax,eax + xor ebx,ebx + mov esi,ScreenPtr + mov edi,SurfBufD + Blank1MMX: + xor eax,eax + mov ecx,160 + rep stosd + sub edi,640 + add edi,Temp1 + add ebx,1 + cmp ebx,8 + jne Blank1MMX + xor ebx,ebx + pxor mm0,mm0 + Copying2MMX: + mov ecx,4 + MMXLoopA: + movq [edi],mm0 + movq [edi+8],mm0 + add edi,16 + dec ecx + jnz MMXLoopA + mov ecx,32 + MMXLoopB: + movq mm1,[esi] + movq mm2,[esi+8] + movq [edi],mm1 + movq [edi+8],mm2 + add esi,16 + add edi,16 + dec ecx + jnz MMXLoopB + mov ecx,4 + MMXLoopC: + movq [edi],mm0 + movq [edi+8],mm0 + add edi,16 + dec ecx + jnz MMXLoopC + inc ebx + add edi,Temp1 + sub edi,640 + sub esi,512 + add esi,576 + cmp ebx,223 + jne Copying2MMX + + xor eax,eax + mov ecx,128 + rep stosd + pop es + emms + } + } else { + _asm { + push es + mov ax,ds + mov es,ax + xor eax,eax + xor ebx,ebx + mov esi,ScreenPtr + mov edi,SurfBufD + Blank1: + xor eax,eax + mov ecx,160 + rep stosd + sub edi,640 + add edi,Temp1 + add ebx,1 + cmp ebx,8 + jne Blank1 + xor ebx,ebx + Copying2: + xor eax,eax + mov ecx,16 + rep stosd + mov ecx,128 + rep movsd + xor eax,eax + mov ecx,16 + rep stosd + inc ebx + add edi,Temp1 + sub edi,640 + sub esi,512 + add esi,576 + cmp ebx,223 + jne Copying2 + + xor eax,eax + mov ecx,128 + rep stosd + pop es + } + } + break; + case 32: + for(j=0;j<8;j++) + { + SURFDW=(DWORD *) &SurfBuf[j*Temp1]; + color32=0x7F000000; + + for(i=0;i<320;i++) + { + SURFDW[i]=color32; + } + } + + for(j=8;j<223+8;j++) + { + color32=0x7F000000; + for(i=0;i<32;i++) + { + SURFDW[i]=color32; + } + + for(i=32;i<(256+32);i++) + { + color32=(((*(WORD *)(ScreenPtr))&0xF800)<<8)+ + (((*(WORD *)(ScreenPtr))&0x07E0)<<5)+ + (((*(WORD *)(ScreenPtr))&0x001F)<<3)+0x7F000000; +// SURFDW[i]=color32; + ScreenPtr+=2; + } + + color32=0x7F000000; + for(i=(256+32);i<320;i++) + { + SURFDW[i]=color32; + } + + ScreenPtr=ScreenPtr+576-512; + SURFDW=(DWORD *) &SurfBuf[(j)*Temp1]; + } + + for(j=(223+8);j<240;j++) + { + SURFDW=(DWORD *) &SurfBuf[j*Temp1]; + + color32=0x7F000000; + for(i=0;i<320;i++) + { + SURFDW[i]=color32; + } + } + break; + default: + UnlockSurface(); + MessageBox (NULL, "Mode only available in 16 and 32 bit color", +"DDRAW Error" , MB_ICONERROR ); + cvidmode=2; + initwinvideo(); + Sleep(1000); + drawscreenwin(); +// exit(0); + break; + } + } + + if(SurfaceX==512&&SurfaceY==448) + { + switch(BitDepth) + { + case 16: + AddEndBytes=Temp1-1024; + NumBytesPerLine=Temp1; + WinVidMemStart=&SurfBuf[0]; + _asm + { + pushad + call copy640x480x16bwin + popad + } + break; + default: + UnlockSurface(); + MessageBox (NULL, "Mode only available in 16 bit color", "DDRAW +Error" , MB_ICONERROR ); + cvidmode=2; + initwinvideo(); + Sleep(1000); + drawscreenwin(); +// exit(0); + } + } + + if(SurfaceX==640&&SurfaceY==480) + { + switch(BitDepth) + { + case 16: + AddEndBytes=Temp1-1024; + NumBytesPerLine=Temp1; + WinVidMemStart=&SurfBuf[16*640*2+64*2]; + _asm + { + pushad + call copy640x480x16bwin + popad + } + break; + default: + UnlockSurface(); + MessageBox (NULL, "Mode only available in 16 bit color", "DDRAW +Error" , MB_ICONERROR ); + cvidmode=2; + initwinvideo(); + Sleep(1000); + drawscreenwin(); +// exit(0); + } + } + + + UnlockSurface(); +#endif +} + + + +extern char fulladdtab[65536*2]; +extern WORD vesa2_usbit; +extern WORD vesa2_clbit; +extern WORD vesa2_rpos; +extern WORD vesa2_rfull; +extern WORD vesa2_rtrcl; +extern WORD vesa2_rtrcla; +extern WORD vesa2_gpos; +extern WORD vesa2_gfull; +extern WORD vesa2_gtrcl; +extern WORD vesa2_gtrcla; +extern WORD vesa2_bpos; +extern WORD vesa2_bfull; +extern WORD vesa2_btrcl; +extern WORD vesa2_btrcla; +extern WORD nojoystickpoll; + +extern void SwitchFullScreen(void); + +void WinUpdateDevices() +{ + int i,j; + unsigned char * keys; + unsigned char keys2[256]; + HRESULT hRes; + +#ifdef __LINUX__ + //STUB_FUNCTION; + MouseButton = SDL_GetMouseState( &MouseX, &MouseY); +#else + for (i=0;i<256;i++) + keys2[i]=0; + keys=(unsigned char *)&pressed; + + if(KeyboardInput&&InputEn==1) + { + KeyboardInput->GetDeviceState(256, keys2); + } + else + { + return; + } + if(keys2[0x38]!=0&&keys2[0x3E]!=0) exit(0); + if(keys2[0x38]!=0&&keys2[0x1c]!=0) + { + _asm{ + pushad + call SwitchFullScreen + popad + } + return; + } + for(i=0;i<256;i++) + { + if(keys2[i]==0) keys[i]=0; + if(keys2[i]!=0&&keys[i]==0) keys[i]=1; + } +// keys[1]=keys[16]; + keys[0]=0; + +// if (nojoystickpoll) return; + + for(i=0;i<4;i++) + { + if(JoystickInput[i]) + { + for(j=0;j<32;j++) + { + keys[0x100+i*32+j]=0; + } + +// memset(&js[i], 0, sizeof(DIJOYSTATE)); + JoystickInput[i]->Poll(); + +if(IDirectInputDevice7_GetDeviceState(JoystickInput[i],sizeof(DIJOYSTATE), +&js[i])==DIERR_INPUTLOST) + { + if(JoystickInput[i]) JoystickInput[i]->Acquire(); + +if(FAILED(IDirectInputDevice7_GetDeviceState(JoystickInput[i],sizeof(DIJOYSTATE), +&js[i]))) return; + } + + if(!X1Disable[i]) + { + if(js[i].lX>0) keys[0x100+i*32+0]=1; + } + + if(!X2Disable[i]) + { + if(js[i].lX<0) keys[0x100+i*32+1]=1; + } + + + if(!Y1Disable[i]) + { + if(js[i].lY>0) keys[0x100+i*32+2]=1; + } + + if(!Y2Disable[i]) + { + if(js[i].lY<0) keys[0x100+i*32+3]=1; + } + + if(!Z1Disable[i]) + { + if(js[i].lZ>0) keys[0x100+i*32+4]=1; + } + + if(!Z2Disable[i]) + { + if(js[i].lZ<0) keys[0x100+i*32+5]=1; + } + if(!RY1Disable[i]) + { + if(js[i].lRy>0) keys[0x100+i*32+6]=1; + } + if(!RY2Disable[i]) + { + if(js[i].lRy<0) keys[0x100+i*32+7]=1; + } + + if(!RZ1Disable[i]) + { + if(js[i].lRz>0) keys[0x100+i*32+8]=1; + } + if(!RZ2Disable[i]) + { + if(js[i].lRz<0) keys[0x100+i*32+9]=1; + } + if(!S01Disable[i]) + { + if(js[i].rglSlider[0]>0) keys[0x100+i*32+10]=1; + } + if(!S02Disable[i]) + { + if(js[i].rglSlider[0]<0) keys[0x100+i*32+11]=1; + } + if(!S11Disable[i]) + { + if(js[i].rglSlider[1]>0) keys[0x100+i*32+12]=1; + } + if(!S12Disable[i]) + { + if(js[i].rglSlider[1]<0) keys[0x100+i*32+13]=1; + } + if(js[i].rgbButtons[0]) keys[0x100+i*32+16]=1; + if(js[i].rgbButtons[1]) keys[0x100+i*32+17]=1; + if(js[i].rgbButtons[2]) keys[0x100+i*32+18]=1; + if(js[i].rgbButtons[3]) keys[0x100+i*32+19]=1; + if(js[i].rgbButtons[4]) keys[0x100+i*32+20]=1; + if(js[i].rgbButtons[5]) keys[0x100+i*32+21]=1; + if(js[i].rgbButtons[6]) keys[0x100+i*32+22]=1; + if(js[i].rgbButtons[7]) keys[0x100+i*32+23]=1; + if(js[i].rgbButtons[8]) keys[0x100+i*32+24]=1; + if(js[i].rgbButtons[9]) keys[0x100+i*32+25]=1; + if(js[i].rgbButtons[10]) keys[0x100+i*32+26]=1; + if(js[i].rgbButtons[11]) keys[0x100+i*32+27]=1; + if(js[i].rgbButtons[12]) keys[0x100+i*32+28]=1; + if(js[i].rgbButtons[13]) keys[0x100+i*32+29]=1; + if(js[i].rgbButtons[14]) keys[0x100+i*32+30]=1; + if(js[i].rgbButtons[15]) keys[0x100+i*32+31]=1; + } + else + { + for(j=0;j<32;j++) + { + keys[0x100+i*32+j]=0; + } + } + } +#endif // __LINUX__ +} + + +int GetMouseX(void) +{ + return((int)MouseX); +} + +int GetMouseY(void) +{ + return((int)MouseY); +} + +int GetMouseMoveX(void) +{ +// InputRead(); + MouseMove2X=MouseMoveX; + return(MouseMove2X); +} + +int GetMouseMoveY(void) +{ + MouseMove2Y=MouseMoveY; + return(MouseMove2Y); +} + +int GetMouseButton(void) +{ + //STUB_FUNCTION; + return((int)MouseButton); +} + +void SetMouseMinX(int MinX) +{ +// MinX&=0xFFF; +// char message1[256]; +// sprintf(message1,"MinX %d",MinX); +// MessageBox (NULL, message1, "Init", MB_ICONERROR ); +// MouseMinX=MinX; +} + +void SetMouseMaxX(int MaxX) +{ +// MaxX&=0xFFF; +// char message1[256]; +// sprintf(message1,"MaxX %d",MaxX); +// MessageBox (NULL, message1, "Init", MB_ICONERROR ); +// MouseMaxX=MaxX; +} + +void SetMouseMinY(int MinY) +{ +// MinY&=0xFFF; +// char message1[256]; +// sprintf(message1,"MinY %d",MinY); +// MessageBox (NULL, message1, "Init", MB_ICONERROR ); +// MouseMinY=MinY; +} + +void SetMouseMaxY(int MaxY) +{ +// MaxY&=0xFFF; +// char message1[256]; +// sprintf(message1,"MaxY %d",MaxY); +// MessageBox (NULL, message1, "Init", MB_ICONERROR ); +// MouseMaxY=MaxY; +} + +void SetMouseX(int X) +{ +// MouseX=X; +} + +void SetMouseY(int Y) +{ +// MouseY=Y; +} + +void ZsnesPage() +{ +#ifdef __LINUX__ + STUB_FUNCTION; +#else + ShellExecute(NULL, NULL, "http://www.zsnes.com", NULL, NULL, 0); +#endif // __LINUX__ +} + +#ifdef __LINUX__ +void GetLocalTime(void *pointer) +{ + STUB_FUNCTION; +} +#endif diff --git a/zsnes/src/linux/winintrf.asm b/zsnes/src/linux/winintrf.asm new file mode 100644 index 00000000..bce8f4cc --- /dev/null +++ b/zsnes/src/linux/winintrf.asm @@ -0,0 +1,2108 @@ +;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. + +%include "macros.mac" + +EXTSYM dssel, selcA000, selcB800, selc0040, previdmode, DosExit, ZFileSystemInit +EXTSYM getcmdline,GUIRestoreVars,getcfg,obtaindir,ConvertJoyMap,tparms +EXTSYM preparedir,getblaster,Force8b,SBHDMA +EXTSYM ccmdline +EXTSYM FilenameStart +EXTSYM spcon +EXTSYM cfgsoundon +EXTSYM pl1selk +EXTSYM pl1startk +EXTSYM pl1upk +EXTSYM pl1downk +EXTSYM pl1leftk +EXTSYM pl1rightk +EXTSYM pl1Xk +EXTSYM pl1Ak +EXTSYM pl1Lk +EXTSYM pl1Yk +EXTSYM pl1Bk +EXTSYM pl1Rk +EXTSYM cfgcvidmode +EXTSYM pl1contrl,pl2contrl +EXTSYM InitDir,InitDrive +EXTSYM DOScreatenewcfg,ExecGUISaveVars +EXTSYM allocptr +EXTSYM putchar +EXTSYM getchar +EXTSYM exit +EXTSYM FPUCopy +EXTSYM ZOpenFile,ZOpenMode,CurrentHandle,ZFileSeek,ZOpenFileName,ZFileSeekMode +EXTSYM ZFileSeekPos,ZFileSeekHandle +EXTSYM ZFileWriteHandle,ZFileWriteSize,ZFileWriteBlock,ZFileWrite +EXTSYM ZFileReadHandle,ZFileReadSize,ZFileReadBlock,ZFileRead +EXTSYM ZFileDelFName,ZFileDelete +EXTSYM ZCloseFileHandle,ZCloseFile +EXTSYM ZFileTellHandle,ZFileTell +EXTSYM ZFFTimeFName,ZFTime,ZFDate,ZFileGetFTime +EXTSYM kbhit +EXTSYM keyboardhit +EXTSYM GUIkeydelay2 +;EXTSYM _kbhit +;EXTSYM _getch +EXTSYM _chdrive +EXTSYM ZFileMKDir,ZFileCHDir,ZFileRMDir,CHPath,MKPath,RMPath +EXTSYM ZFileGetDir,DriveNumber,DirName +EXTSYM _getdrive +EXTSYM DTALoc,DTALocPos,ZFileFindATTRIB,ZFileFindFirst,ZFileFindNext,ZFileFindPATH +EXTSYM oldhand9s,oldhand9o,interror,oldhand8s,oldhand8o,oldhandSBs,oldhandSBo +EXTSYM NoSoundReinit,soundon,DSPDisable,SBInt,NoSoundReinit,PICMaskP,SBIrq +EXTSYM SBHandler,InitSB,handler8h,handler9h,init60hz,Interror,init18_2hz,DeInitSPC +EXTSYM Start60HZ +EXTSYM pressed +EXTSYM RaisePitch,AdjustFrequency +EXTSYM vidbufferofsb,vidbuffer +EXTSYM clearwin +EXTSYM Stop60HZ +EXTSYM dosmakepal +EXTSYM doschangepal +EXTSYM dosinitvideo,dosinitvideo2 +EXTSYM initwinvideo +EXTSYM vesa2_rpos +EXTSYM vesa2_gpos +EXTSYM vesa2_bpos +EXTSYM vesa2_rposng +EXTSYM vesa2_gposng +EXTSYM vesa2_bposng +EXTSYM vesa2_usbit +EXTSYM vesa2_clbit +EXTSYM vesa2_clbitng +EXTSYM vesa2_clbitng2 +EXTSYM vesa2_clbitng3 +EXTSYM genfulladdtabng +EXTSYM vesa2red10 +EXTSYM res640 +EXTSYM res480 +EXTSYM AddSub256,InitVesa2,cbitmode,cvidmode +EXTSYM scanlines,vesa2_bits +EXTSYM vesa2_x,vesa2_y +EXTSYM vesa2selec,InitVesa12,videotroub +EXTSYM genfulladdtab +EXTSYM DosDrawScreen,dosvidpastecopyscr,GUICPC +EXTSYM drawscreenwin +EXTSYM ConvertToAFormat +EXTSYM UnusedBit,HalfTrans,UnusedBitXor,UnusedBit,UnusedBitXor +EXTSYM ngrposng,nggposng,ngbposng,HalfTransB,HalfTransC +EXTSYM DOSClearScreen +EXTSYM DosUpdateDevices +EXTSYM WinUpdateDevices +EXTSYM DOSJoyRead +EXTSYM UpdateVFrame +EXTSYM GetMouseX +EXTSYM GetMouseY +EXTSYM GetMouseMoveX +EXTSYM GetMouseMoveY +EXTSYM GetMouseButton +EXTSYM SetMouseMinX,SetMouseMaxX +EXTSYM SetMouseMinY,SetMouseMaxY +EXTSYM SetMouseX,SetMouseY +EXTSYM T36HZEnabled +EXTSYM MouseButton +EXTSYM GUIinit36_4hz,GUIoldhand9s,GUIoldhand9o,GUIoldhand8s,GUIoldhand8o +EXTSYM GUIhandler9h,GUIhandler8h,GUIinit18_2hz +EXTSYM Start36HZ +EXTSYM Stop36HZ +EXTSYM BufferSizeW,BufferSizeB,ProcessSoundBuffer +EXTSYM CheckTimers +EXTSYM vesa2_rfull,vesa2_rtrcl,vesa2_rtrcla +EXTSYM vesa2_gfull,vesa2_gtrcl,vesa2_gtrcla +EXTSYM vesa2_bfull,vesa2_btrcl,vesa2_btrcla +EXTSYM Init_2xSaIMMXW +EXTSYM TCPIPPortNum +EXTSYM InitTCP +EXTSYM StartServerCycle +EXTSYM ServerCheckNewClient +EXTSYM acceptzuser +EXTSYM GUINetTextk2 +EXTSYM ConnectServer +EXTSYM WaitForServer +EXTSYM SendData +EXTSYM SendDataUDP +EXTSYM GetData +EXTSYM DeInitTCP +EXTSYM StopServer +EXTSYM Disconnect +EXTSYM UDPDisableMode,UDPEnableMode,UDPClearVars,UDPWait1Sec +EXTSYM WinErrorA2,WinErrorB2,WinErrorC2 +EXTSYM ZsnesPage +EXTSYM GetLocalTime + +NEWSYM WinIntRFAsmStart + +; 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 .data +NEWSYM OSPort, db 3 ; 0 = DOS (C), 1 = DOS (ASM), 2 = Linux, 3 = Win95 +SECTION .text + +NEWSYM StartUp + call ZFileSystemInit + 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 + push es + mov byte[cfgcvidmode],2 + mov byte[cvidmode],2 + call getcmdline +%ifdef __LINUX__ + mov byte[esi],'z' + mov byte[esi+1],'s' + mov byte[esi+2],'n' + mov byte[esi+3],'e' + mov byte[esi+4],'s' + mov byte[esi+5],'l' + mov byte[esi+6],'.' + mov byte[esi+7],'c' + mov byte[esi+8],'f' + mov byte[esi+9],'g' + mov byte[esi+10],0 + mov byte[esi+256],'z' + mov byte[esi+1+256],'g' + mov byte[esi+2+256],'u' + mov byte[esi+3+256],'i' + mov byte[esi+4+256],'c' + mov byte[esi+5+256],'f' + mov byte[esi+6+256],'g' + mov byte[esi+7+256],'l' + mov byte[esi+8+256],'.' + mov byte[esi+9+256],'d' + mov byte[esi+10+256],'a' + mov byte[esi+11+256],'t' + mov byte[esi+12+256],0 +%else + mov byte[esi],'Z' + mov byte[esi+1],'S' + mov byte[esi+2],'N' + mov byte[esi+3],'E' + mov byte[esi+4],'S' + mov byte[esi+5],'W' + mov byte[esi+6],'.' + mov byte[esi+7],'C' + mov byte[esi+8],'F' + mov byte[esi+9],'G' + mov byte[esi+10],0 + mov byte[esi+256],'Z' + mov byte[esi+1+256],'G' + mov byte[esi+2+256],'U' + mov byte[esi+3+256],'I' + mov byte[esi+4+256],'C' + mov byte[esi+5+256],'F' + mov byte[esi+6+256],'G' + mov byte[esi+7+256],'W' + mov byte[esi+8+256],'.' + mov byte[esi+9+256],'D' + mov byte[esi+10+256],'A' + mov byte[esi+11+256],'T' + mov byte[esi+12+256],0 +%endif + + mov byte[pl1selk],54 + mov byte[pl1startk],28 ; 1START = ENTER + mov byte[pl1upk],200 ; 1UP = up + mov byte[pl1downk],208 ; 1DOWN = down + mov byte[pl1leftk],203 ; 1LEFT = left + mov byte[pl1rightk],205 ; 1RIGHT = right + mov byte[pl1Xk],31 ; 1X = INS + mov byte[pl1Ak],45 ; 1A = HOME + mov byte[pl1Lk],32 ; 1L = PAGE UP + mov byte[pl1Yk],30 ; 1Y = DELETE + mov byte[pl1Bk],44 ; 1B = END + mov byte[pl1Rk],46 ; 1R = PAGE DOWN + mov byte[pl1contrl],1 + mov byte[pl2contrl],1 + + mov byte[spcon],1 + mov byte[soundon],1 + mov byte[cfgsoundon],1 + + ; Get and set the initial directory + mov ebx,InitDir + mov edx,InitDrive + call Get_Dir + mov dl,[InitDrive] + mov ebx,InitDir + call Change_Dir + + call GUIRestoreVars ; Load GUI stuff + call getcfg ; Load cfg stuff + call obtaindir ; Get Save/Init Directories + call ConvertJoyMap ; Mini joystick init + call ccmdline + call tparms + call preparedir + mov byte[soundon],0 +; call getblaster ; get set blaster environment +; cmp byte[Force8b],1 +; jne .noforce8b + mov byte[SBHDMA],1 +;.noforce8b + pop es + ret + +; Configuration save re-routing functions. You can comment these out +; for debugging purposes or change it if you're using a different +; configuration format +NEWSYM createnewcfg + call DOScreatenewcfg + ret +NEWSYM GUISaveVars + call ExecGUISaveVars + ret + +; Allocate memory - see allocptr in ui.asm for details on what to allocate +NEWSYM allocmem + call allocptr + ret + + +NEWSYM PrintChar + ret + ; print character at dl, push all modified registers + pushad + push eax + push edx + call putchar + pop edx +; mov ah,02h +; int 21h + pop eax + popad + 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 + + +NEWSYM wfkey, db 0 + +NEWSYM WaitForKey ; Wait for a key to be pressed + pushad + call getchar + mov [wfkey],al + popad + mov al,[wfkey] + ;mov ah,7 + ;int 21h + ; return key in al + ret + + +NEWSYM OsExit +NEWSYM OSExit + call exit + int 3h + jmp DosExit + +NEWSYM MMXCheck + ; Check for cpu that doesn't support CPUID + mov edx,cpuidfname + call Open_File + jc .skipcheck + mov bx,ax + call Close_File + jmp .nommx2 +.skipcheck + + ; Create file + mov edx,cpuidfname + call Create_File + mov bx,ax + call Close_File + + mov edx,cpuidtext + call PrintStr + + ; MMX support + mov byte[FPUCopy],0 + mov eax,1 + CPUID + + push edx + mov edx,cpuidtext2 + call PrintStr + pop edx + + test edx,1 << 23 + jz .nommx + mov byte[FPUCopy],2 + mov edx,YesMMX + call PrintStr +.nommx + ; Delete file + mov edx,cpuidfname + call Delete_File +.nommx2 + ret + + +NEWSYM TempHandle, dd 0 + + +NEWSYM Open_File + pushad + mov dword[ZOpenMode],0 + mov dword[ZOpenFileName],edx + call ZOpenFile + cmp eax,0FFFFFFFFh + je .error + mov [TempHandle],eax + mov dword[ZFileSeekMode],0 + mov dword[ZFileSeekPos],0 + mov dword[ZFileSeekHandle],eax + call ZFileSeek + popad + mov ax,[TempHandle] + clc + ret +.error + popad + stc + ret + mov ax,3D00h + int 21h + ; return bx = file handle, carry = error + ret + +NEWSYM Open_File_Write + pushad + mov dword[ZOpenMode],2 + mov dword[ZOpenFileName],edx + call ZOpenFile + cmp eax,0FFFFFFFFh + je .error + mov [TempHandle],eax + mov dword[ZFileSeekMode],0 + mov dword[ZFileSeekPos],0 + mov dword[ZFileSeekHandle],eax + call ZFileSeek + popad + mov ax,[TempHandle] + clc + ret +.error + popad + stc + ret + mov ax,3D01h + int 21h + ; return bx = file handle, carry = error + ret + +NEWSYM Create_File + pushad + mov dword[ZOpenMode],1 + mov dword[ZOpenFileName],edx + call ZOpenFile + cmp eax,0FFFFFFFFh + je .error + mov [TempHandle],eax + popad + mov ax,[TempHandle] + clc + ret +.error + popad + stc + ret + mov ah,3Ch + mov cx,0 + int 21h + ; return bx = file handle + ret + +NEWSYM Write_File + mov dword[ZFileWriteHandle],0 + mov [ZFileWriteHandle],bx + mov [ZFileWriteSize],ecx + mov [ZFileWriteBlock],edx + pushad + call ZFileWrite + cmp eax,0FFFFFFFFh + je .fail + popad + mov eax,1 + clc + ret +.fail + popad + mov eax,0 + stc + ret + mov ah,40h + int 21h + ret + +NEWSYM Read_File + mov dword[ZFileReadHandle],0 + mov [ZFileReadHandle],bx + mov [ZFileReadSize],ecx + mov [ZFileReadBlock],edx + pushad + call ZFileRead + mov [TempVarSeek],eax + popad + mov eax,[TempVarSeek] + clc + ret + mov ah,3Fh + int 21h + ret + +NEWSYM Delete_File + mov [ZFileDelFName],edx + pushad + call ZFileDelete + popad + ret + mov ah,41h + int 21h + ret + +NEWSYM Close_File + mov dword[ZCloseFileHandle],0 + mov [ZCloseFileHandle],bx + pushad + call ZCloseFile + popad + clc + ret + mov ah,3Eh + int 21h + ret + +NEWSYM File_Seek + mov word[ZFileSeekPos+2],cx + mov word[ZFileSeekPos],dx + mov dword[ZFileSeekMode],0 + mov dword[ZFileSeekHandle],0 + mov word[ZFileSeekHandle],bx + pushad + call ZFileSeek + popad + mov ax,dx + mov dx,cx + ret + ; seek to cx:dx from 0 position, return carry as error + mov ax,4200h + int 21h + ret + +NEWSYM File_Seek_End + mov word[ZFileSeekPos+2],cx + mov word[ZFileSeekPos],dx + mov dword[ZFileSeekHandle],0 + mov word[ZFileSeekHandle],bx + mov dword[ZFileSeekMode],1 + mov dword[ZFileTellHandle],0 + mov word[ZFileTellHandle],bx + pushad + call ZFileSeek + call ZFileTell + mov [TempVarSeek],eax + popad + mov ax,[TempVarSeek] + mov dx,[TempVarSeek+2] + ret + ; seek to cx:dx from end position, and return file location in dx:ax + mov ax,4202h + int 21h + ret + +NEWSYM Get_Time + pushad +; call GetTime + mov [TempVarSeek],eax + popad + mov eax,[TempVarSeek] + ret +NEWSYM Get_TimeDate + pushad +; call GetDate + mov [TempVarSeek],eax + popad + mov eax,[TempVarSeek] + ret + +NEWSYM Get_Date + ; dl = day, dh = month, cx = year + mov dx,0 + mov cx,0 +; mov ah,2Ah +; int 21h + ret + +NEWSYM Get_File_Date + mov [ZFFTimeFName],edx + pushad + call ZFileGetFTime + popad + mov dx,[ZFDate] + mov cx,[ZFTime] + ret + ; return packed date in dx:cx + mov ah,57h + mov al,00h + int 21h + 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 + sub ebx,80h +.skipdecval + cmp ebx,58h + jae .none + xor eax,eax + mov al,[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 +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 + +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 +; mov al,byte [keyboardhit] +; push eax +; xor eax,eax +; mov byte [keyboardhit],al +; pop eax + pushad +; call kbhit + 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 + pushad + call JoyRead + popad + 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 + sub word[KeyBuffer+eax*4],100h + xor al,al + ret + + pushad +.nonewkey + call RefreshKeybBuffer + xor eax,eax + mov al,[Keybhead] + cmp al,[Keybtail] + je .nonewkey + mov bl,[HoldKeyBuf+eax] + test bl,80h + jz .notupperkey + xor bl,bl + sub 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 + +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 + +; mov dl,[SRAMDrive] +; mov ebx,SRAMDir +; call Change_Dir + +NEWSYM Change_Drive + ; change to drive in dl (0 = A, 1 = B, etc.) + and edx,0FFh + add edx,1 + push edx + call _chdrive + pop edx +; mov ah,0Eh +; int 21h + ret + +NEWSYM Change_Single_Dir + mov [CHPath],edx + pushad + call ZFileCHDir + or eax,eax + jnz .notokay + popad + clc + ret +.notokay + popad + stc + ret + ; Dir in edx, return error in carry flag + mov ah,3Bh + int 21h + ret + +NEWSYM Create_Dir + ; change to dir in edx + mov [MKPath],edx + pushad + call ZFileMKDir + or eax,eax + jnz .notokay + popad + clc + ret +.notokay + popad + stc + ret + mov ah,39h + int 21h + ret + +NEWSYM Remove_Dir + ; remove dir in edx + mov [RMPath],edx + pushad + call ZFileRMDir + or eax,eax + jnz .notokay + popad + clc + ret +.notokay + popad + stc + ret + mov ah,3Ah + int 21h + ret + +; mov dl,[LoadDrive] +; mov ebx,LoadDir +; call Change_Dir +NEWSYM Change_Dir + pushad + + and edx,0FFh + add edx,1 + push edx + call _chdrive + pop edx + +; mov ah,0Eh +; int 21h +; jc .fail + mov dword[CHPath],gotoroot + call ZFileCHDir + or eax,eax + jnz .fail + popad + mov [CHPath],ebx + cmp byte[ebx],0 + je .nocdir + pushad + call ZFileCHDir + or eax,eax + jnz .fail + popad +.nocdir + clc + ret +.fail + popad + stc + ret + + ; dl = drive, ebx = dir + push ebx + mov ah,0Eh + int 21h + mov ah,3Bh + mov edx,gotoroot + int 21h + pop ebx + mov edx,ebx + cmp byte[edx],0 + je .nodir + mov ah,3Bh + int 21h +.nodir + ret + +; mov ebx,LoadDir +; mov edx,LoadDrive +; call Get_Dir +NEWSYM Get_Dir + mov [DirName],ebx + pushad + call ZFileGetDir + mov eax,[DirName] + mov ebx,eax + mov ecx,125 +.loop + mov dl,[eax+3] + cmp dl,'/' + jne .noslash + mov dl,'\' +.noslash + mov [eax],dl + inc eax + loop .loop + popad + push edx + call _getdrive +; mov ah,19h +; int 21h + sub al,1 + pop edx + mov [edx],al + ret + + push edx + mov ah,47h + mov dl,0 + mov esi,ebx + int 21h + mov ah,19h + int 21h + pop edx + mov [edx],al + ret + +NEWSYM Get_First_Entry + ; cx = attributes, edx = pointer to wildcard + ; returns : DTALoc+15h, bit 4 = Dir (1) or File (0) + ; DTALoc+1Eh = filename, carry flag set = no more entry + mov [ZFileFindPATH],edx + mov dword[ZFileFindATTRIB],0 + mov [ZFileFindATTRIB],cx + mov dword[DTALocPos],DTALoc + pushad + call ZFileFindFirst + or eax,eax + jnz .end + popad + clc + ret +.end + popad + stc + ret + mov ah,4Eh + mov al,0 + int 21h + ret + +NEWSYM Get_Next_Entry + mov dword[DTALocPos],DTALoc + pushad + call ZFileFindNext + or eax,eax + jnz .end + popad + clc + ret +.end + popad + stc + ret + mov ah,04Fh + int 21h + ret + +NEWSYM Set_DTA_Address + ; Only needed for dos stuff +; mov edx,DTALoc +; mov ah,1Ah +; int 21h + ret + +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 byte[RaisePitch],1 + pushad + call AdjustFrequency + popad + + pushad + xor eax,eax + mov edi,[vidbufferofsb] + mov ecx,228*120 + 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 +; **************************** + +; ** Palette Functions ** +NEWSYM makepal ; 8-bit palette set + ret +; jmp dosmakepal +NEWSYM changepal ; 8-bit palette set (changes only) + ret +; jmp doschangepal +NEWSYM displayfpspal + ret + + 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,128+64 + mov dx,03C8h + out dx,al + inc dx + mov al,0 + out dx,al + out dx,al + out dx,al + ret + +NEWSYM superscopepal + ret + + mov al,128+16 + mov dx,03C8h + out dx,al + inc dx + mov al,63 + out dx,al + xor al,al + out dx,al + out dx,al + ret + +NEWSYM saveselectpal + ret + + ; 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 + mov al,176 + mov dx,03C8h + out dx,al + inc dx + mov al,47 + out dx,al + xor al,al + out dx,al + out dx,al + mov al,208 + mov dx,03C8h + out dx,al + inc dx + mov al,50 + out dx,al + mov al,25 + out dx,al + xor al,al + out dx,al + ret + +; ** init video mode functions ** +NEWSYM firstvideo, dd 1 + + +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 + + cmp dword[firstvideo],1 + je .skipinitgfx + pushad + call InitializeGfxStuff + popad + +.skipinitgfx + mov dword[firstvideo],0 + + pushad + call InitializeGfxStuff + popad + + ret + + +; pushad +; call genfulladdtabng +; popad +; jmp dosinitvideo +NEWSYM initvideo2 ; ModeQ scanline re-init (Keep blank on non-dos ports) + ret +; jmp dosinitvideo2 +NEWSYM deinitvideo +; mov al,[previdmode] +; mov ah,0 +; int 10h + ret + +; ** copy video mode functions ** +NEWSYM converta, dd 0 +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 + xor eax,eax + mov al,[cvidmode] + cmp byte[GUI16VID+eax],1 + jne .no16bconv + mov eax,[vidbuffer] + mov ecx,224*288 + mov edx,ecx + sub ecx,288 + dec edx +.loop + xor ebx,ebx + mov bl,[eax+edx] + mov bx,[GUICPC+ebx*2] + mov [eax+edx*2],bx + dec edx + loop .loop +.no16bconv + popad + jmp DrawScreen + + +; ** Clear Screen function ** +NEWSYM ClearScreen + ret + + +; ** Video Mode Variables ** +SECTION .data + +; Total Number of Video Modes +NEWSYM NumVideoModes, dd 18 + +; GUI Video Mode Names - Make sure that all names are of the same length +; and end with a NULL terminator +NEWSYM GUIVideoModeNames +db '64x56 R WIN ',0 ;0 +db '128x112 R WIN ',0 ;1 +db '256X224 R WIN ',0 ;2 +db '256x224 R FULL',0 ;3 +db '512X448 R WIN ',0 ;4 +db '512X448 DR WIN ',0 ;5 +db '640x480 S WIN ',0 ;6 +db '640x480 DR FULL',0 ;7 +db '640X480 DS FULL',0 ;8 +db '640X480 S FULL',0 ;9 +db '800x600 S WIN ',0 ;10 +db '800x600 DS WIN ',0 ;11 +db '800x600 S FULL',0 ;12 +db '800x600 DS FULL',0 ;13 +db '1024X768 S WIN ',0 ;14 +db '1024X768 DS WIN ',0 ;15 +db '1024x768 S FULL',0 ;16 +db '1024x768 DS FULL',0 ;17 + + +; Video Mode Feature Availability (1 = Available, 0 = Not Available) +; Left side starts with Video Mode 0 +NEWSYM GUI16VID, db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 ; 16-bit mode +NEWSYM GUINGVID, db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ; New Graphics Mode Available +NEWSYM GUISLVID, db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ; Scanlines +NEWSYM GUIINVID, db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ; Interpolation +NEWSYM GUII2VID, db 0,0,0,0,0,1,0,1,1,0,0,1,0,1,0,1,0,1 ; Interpolation(w) +NEWSYM GUIEAVID, db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ; Eagle +NEWSYM GUIIEVID, db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ; (Interp | Eagle) +NEWSYM GUIFSVID, db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ; Full Screen +NEWSYM GUISSVID, db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ; Small Screen +NEWSYM GUITBVID, db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ; Triple Buffering +NEWSYM GUIHSVID, db 0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0 ; Half/Quarter Scanlines +NEWSYM GUI2xVID, db 0,0,0,0,0,1,0,1,1,0,0,1,0,1,0,1,0,1 ; 2xSaI/Super Eagle Engines +NEWSYM GUIM7VID, db 0,0,0,0,0,1,0,1,1,0,0,1,0,1,0,1,0,1 ; ?Mode 7 video thing? +NEWSYM GUIWFVID, db 0,0,0,1,0,0,0,1,1,1,0,0,1,1,0,0,1,1 ; If Windows Full Screen +NEWSYM GUIDSIZE, db 0,0,0,0,0,1,0,1,1,0,0,1,0,1,0,1,0,1 +NEWSYM GUIRATIO, db 0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + +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 +; call DosUpdateDevices + ret + +NEWSYM JoyRead +; call SoundProcess ; Put the sound stuff here since it's + ; called 60 times per second +; call DOSJoyRead + 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 'KEYB/JOYSTICK ',0 +db ' ',0 +db ' ',0 +db ' ',0 +db ' ',0 +db 'SIDEWINDERPAD1 ',0 +db 'SIDEWINDERPAD2 ',0 +db 'SIDEWINDERPAD3 ',0 +db 'SIDEWINDERPAD4 ',0 +db 'GAMEPAD PRO P0 ',0 +db 'GAMEPAD PRO P1 ',0 +db 'PARALLEL LPT1 P1',0 +db 'PARALLEL LPT1 P2',0 +db 'PARALLEL LPT2 P1',0 +db 'PARALLEL LPT2 P2',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','N 7' ; 40h + db 'N 8','N 9','N -','N 4','N 5','N 6','N +','N 1' + db 'N 2','N 3','N 0','N .',' ',' ','OEM','F11' ; 50h + db 'F12','59h','5Ah','5BH','5CH','5DH','5EH','5FH' + db '60H','61H','62H','63H','64H','65H','66H','67H' ; 80h + db '68H','69H','6AH','6BH','6CH','6DH','6EH','6FH' + db '70H','71H','72H','73H','74H','75H','76H','77H' ; 90h + 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 + +SECTION .data +NEWSYM ZSNESBase, dd 0 +cpuidfname db 'nocpuzid.dat',0 +cpuidtext db 'NOTE: If ZSNES crashes here, then please re-run. ',0 +cpuidtext2 db 13,' ',13,0 +YesMMX db 'MMX support enabled.',13,10,13,10,0 +TempVarSeek dd 0 +gotoroot db '\',0 +SECTION .text + +; **************************** +; Mouse Stuff +; **************************** + +NEWSYM Init_Mouse + ; return non-zero if successful + mov eax,01h + ret + +NEWSYM WMouseX, dd 0 +NEWSYM WMouseY, dd 0 +NEWSYM WMouseMoveX, dd 0 +NEWSYM WMouseMoveY, dd 0 +NEWSYM WMouseButton, dd 0 + + + + +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 + or ecx,0FFFh + push ecx + call SetMouseMinX + pop ecx + or edx,0FFFh + push edx + call SetMouseMaxX + pop edx + popad + ret + +NEWSYM Set_MouseYMax ; Sets the Y boundaries (ecx = left, edx = right) + pushad + or ecx,0FFFh + push ecx + call SetMouseMinY + pop ecx + or edx,0FFFh + push edx + call SetMouseMaxY + pop edx + popad + ret + +NEWSYM Set_MousePosition ; Sets Mouse Position (x:cx,y:dx) + pushad + or ecx,0FFFFh + push ecx + call SetMouseX + pop ecx + push edx + or edx,0FFFFh + 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 + pushad +; cmp byte[OSPort],1 ; Do not call in the dos port +; ja .notdos +;.notdos + cmp byte[soundon],0 + je .nosound + cmp byte[DSPDisable],1 + je .nosound + mov eax,256 ; Size + mov dword[BufferSizeB],eax + add eax,eax + mov dword[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 + popad + ret + +NEWSYM delay + ret + +NEWSYM Check60hz + ; Call the timer update function here + pushad + call CheckTimers + popad + ret + +BitPosR db 11 +BitPosG db 5 +BitPosB db 0 +BitSizeR db 5 +BitSizeG db 6 +BitSizeB db 5 + + +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 word[vesa2_rfull],bx + add al,5 + mov bx,1 + mov cl,al + shl bx,cl + mov word[vesa2_rtrcl],bx + xor bx,0FFFFh + mov word[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 word[vesa2_gfull],bx + add al,5 + mov bx,1 + mov cl,al + shl bx,cl + mov word[vesa2_gtrcl],bx + xor bx,0FFFFh + mov word[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 word[vesa2_bfull],bx + add al,5 + mov bx,1 + mov cl,al + shl bx,cl + mov word[vesa2_btrcl],bx + xor bx,0FFFFh + mov word[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 + + +NEWSYM SetInputDevice + ; eax = pointer to devices, bl = device #, bh = player # (0-4) + ; Sets keys according to input device selected + cmp bl,0 + jne near .nozero + mov dword[eax],0 + mov dword[eax+4],0 + mov dword[eax+8],0 + mov dword[eax+12],0 + mov dword[eax+16],0 + mov dword[eax+20],0 + mov dword[eax+24],0 + mov dword[eax+28],0 + mov dword[eax+32],0 + mov dword[eax+36],0 + mov dword[eax+40],0 + mov dword[eax+44],0 + ret +.nozero + cmp bh,1 + je near .input2 + mov dword[eax],54 + mov dword[eax+4],28 + mov dword[eax+8],200 + mov dword[eax+12],208 + mov dword[eax+16],203 + mov dword[eax+20],205 + mov dword[eax+24],31 + mov dword[eax+28],45 + mov dword[eax+32],32 + mov dword[eax+36],30 + mov dword[eax+40],44 + mov dword[eax+44],46 + ret +.input2 + mov dword[eax],56 + mov dword[eax+4],29 + mov dword[eax+8],37 + mov dword[eax+12],50 + mov dword[eax+16],49 + mov dword[eax+20],51 + mov dword[eax+24],31 + mov dword[eax+28],32 + mov dword[eax+32],33 + mov dword[eax+36],44 + mov dword[eax+40],45 + mov dword[eax+44],46 + ret + +; **************************** +; TCP/IP Stuff +; **************************** + +; TCPIPPortNum +NEWSYM TCPIPStatus, db 0 +NEWSYM PacketSendSize, dd 0 +NEWSYM PacketRecvSize, dd 0 +NEWSYM PacketRecvPtr, dd 0 +NEWSYM PacketSendArray, times 2048+256 db 0 +NEWSYM PacketRecvArray, times 2048+256 db 0 +NEWSYM IPAddrStr, times 20 db 0 +NEWSYM RemoteDisconnect, db 0 + +NEWSYM TCPIPStartServer + mov byte[RemoteDisconnect],0 + pushad + mov dword[PacketSendSize],0 + mov dword[PacketRecvSize],0 + call InitTCP + or eax,eax + jnz .failed + mov byte[TCPIPStatus],1 +; StartServer(unsigned short port) + xor eax,eax + mov ax,[TCPIPPortNum] + push eax + call StartServerCycle + add esp,4 + or eax,eax + jnz .failed + mov byte[TCPIPStatus],2 + popad + xor eax,eax + ret +.failed + popad + mov eax,-1 + ret + +NEWSYM TCPIPWaitForConnection + mov byte[RemoteDisconnect],0 + pushad + call ServerCheckNewClient + mov [.temp],eax + cmp eax,1 + jne .notwaiting + call acceptzuser + or eax,eax + jnz .failed +.notwaiting + popad + mov eax,[.temp] + ret +.failed + popad + mov eax,-1 + ret +.temp dd 0 + +NEWSYM TCPIPInitConnectToServer + pushad + mov dword[PacketSendSize],0 + mov dword[PacketRecvSize],0 + call InitTCP + or eax,eax + jnz .failed + mov byte[TCPIPStatus],1 + ; Convert GUINetTextk2 to IPAddrStr + mov ebx,GUINetTextk2 + mov edx,IPAddrStr +.notend + mov al,[ebx] + cmp al,' ' + je .dontinclude + mov [edx],al + inc edx +.dontinclude + inc ebx + cmp al,0 + jne .notend + popad + xor eax,eax + ret +.failed + popad + mov eax,1 + ret + +NEWSYM TCPIPConnectToServer +; int ConnectServer(char *servername, unsigned short port) + pushad + xor eax,eax + mov ax,[TCPIPPortNum] + push eax + mov eax,IPAddrStr + push eax + xor eax,eax + call ConnectServer + add esp,8 + or eax,eax + jnz .noclient + mov byte[TCPIPStatus],3 + popad + xor eax,eax + ret +.noclient + mov [.temp],eax + popad + mov eax,[.temp] + ret +.temp dd 0 + +NEWSYM TCPIPConnectToServerW +; int ConnectServer(char *servername, unsigned short port) + pushad + xor eax,eax + call WaitForServer + or eax,eax + jnz .foundclient + mov byte[TCPIPStatus],3 + popad + xor eax,eax + ret +.foundclient + mov [.temp],eax + popad + mov eax,[.temp] + ret +.temp dd 0 + +NEWSYM TCPIPStoreByte + ; Store al into the array +; cmp dword[PacketSendSize],2048 +; je .packeterror + push ebx + mov ebx,[PacketSendSize] + mov [PacketSendArray+ebx],al + pop ebx + inc dword[PacketSendSize] + ret +.packeterror + mov byte[RemoteDisconnect],1 + ret + +NEWSYM TCPIPGetByte + ; dh = 0 : No bytes in buffer + ; dl = resulting character + cmp dword[PacketRecvSize],0 + jne .bytereceived + mov dword[PacketRecvPtr],0 + call TCPIPRecvPacket + cmp dword[PacketRecvSize],0 + jne .bytereceived + xor dh,dh + ret +.bytereceived + push eax + mov eax,[PacketRecvPtr] + mov dl,[PacketRecvArray+eax] + mov dh,1 + inc dword[PacketRecvPtr] + mov eax,[PacketRecvPtr] + cmp [PacketRecvSize],eax + jne .notequal + mov dword[PacketRecvSize],0 +.notequal + pop eax + ret + +NEWSYM TCPIPSendPacket + cmp dword[PacketSendSize],0 + je .nopacket + pushad + ; Send PacketSendArray with size of PacketSendSize + ; SendData(int dsize,char *dptr) + mov eax,PacketSendArray + push eax + mov eax,[PacketSendSize] + push eax + call SendData + or eax,eax + jnz .failed + add esp,8 + popad +.nopacket + ret +.failed + add esp,8 + popad + call TCPIPDisconnect + mov byte[RemoteDisconnect],1 + ret + +NEWSYM TCPIPSendPacketUDP + cmp dword[PacketSendSize],0 + je .nopacket + pushad + ; Send PacketSendArray with size of PacketSendSize + ; SendData(int dsize,char *dptr) + mov eax,PacketSendArray + push eax + mov eax,[PacketSendSize] + push eax + call SendDataUDP + or eax,eax + jnz .failed + add esp,8 + popad +.nopacket + ret +.failed + add esp,8 + popad + call TCPIPDisconnect + mov byte[RemoteDisconnect],1 + ret + +NEWSYM TCPIPRecvPacket + pushad + ; Store packet to PacketRecvArray, size at PacketRecvSize + ; int GetData(int dsize,char *dptr) + mov eax,PacketRecvArray + push eax + mov eax,2048 + push eax + call GetData + cmp eax,-1 + je .failed + mov [PacketRecvSize],eax + add esp,8 + popad + ret +.failed + add esp,8 + popad + call TCPIPDisconnect + mov byte[RemoteDisconnect],1 + ret + +NEWSYM TCPIPDisconnect + call DeInitTCP + cmp byte[TCPIPStatus],2 + jne .notserver + call StopServer +.notserver + cmp byte[TCPIPStatus],3 + jne .notclient + call Disconnect +.notclient + mov byte[TCPIPStatus],0 + ret + +NEWSYM TCPIPPreparePacket + mov dword[PacketSendSize],0 + ret + +NEWSYM ClearUDPStuff + pushad + call UDPClearVars + popad + ret + +NEWSYM Wait1SecWin + pushad + call UDPWait1Sec + popad + ret + +NEWSYM EnableSUDPPacket + pushad + call UDPEnableMode + popad + ret + +NEWSYM DisableSUDPPacket + pushad + call UDPDisableMode + popad + ret + +NEWSYM WinErrorA + call WinErrorA2 + ret +NEWSYM WinErrorB + call WinErrorB2 + ret +NEWSYM WinErrorC + call WinErrorC2 + ret + +NEWSYM GotoHomepage + pushad + call ZsnesPage + popad + ret + +NEWSYM GetTimeInSeconds + push dword SystemTime + call [GetLocalTime] + movzx eax,word [SystemTime.wHour] + mov ebx,60 + mul ebx + movzx ebx,word [SystemTime.wMinute] + add eax,ebx + mov ebx,60 + mul ebx + movzx ebx,word [SystemTime.wSecond] + add eax,ebx + ret + +SystemTime: +.wYear dw 0 +.wMonth dw 0 +.wDayOfWeek dw 0 +.wDay dw 0 +.wHour dw 0 +.wMinute dw 0 +.wSecond dw 0 +.wMilliseconds dw 0 + +NEWSYM WinIntRFAsmEnd diff --git a/zsnes/src/linux/zfilew.c b/zsnes/src/linux/zfilew.c new file mode 100644 index 00000000..8e8de059 --- /dev/null +++ b/zsnes/src/linux/zfilew.c @@ -0,0 +1,328 @@ +//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. + + +#include +#ifdef __LINUX__ +#include +#include +#include +#else +#include +#include +#endif + +#define DWORD unsigned int +#define BYTE unsigned char + +#ifdef __LINUX__ +#define STUB_FUNCTION fprintf(stderr,"STUB: %s at " __FILE__ ", line %d, thread %d\n",__FUNCTION__,__LINE__,getpid()) +#endif + +FILE *FILEHANDLE[16]; +DWORD CurrentHandle=0; + + + +// ZFileSystemInit +// return 0 + +// ZOpenFile info : +BYTE * ZOpenFileName; +DWORD ZOpenMode; +// Open modes : 0 read/write in +// 1 write (create file, overwrite) +// return file handle if success, 0xFFFFFFFF if error + +// ZCloseFile info : +DWORD ZCloseFileHandle; +// return 0 + +// ZFileSeek info : +DWORD ZFileSeekHandle; +DWORD ZFileSeekPos; +DWORD ZFileSeekMode; // 0 start, 1 end +// return 0 + +// ZFileReadBlock info : +BYTE * ZFileReadBlock; +DWORD ZFileReadSize; +DWORD ZFileReadHandle; +// return 0 + +// ZFileWriteBlock info : +BYTE * ZFileWriteBlock; +DWORD ZFileWriteSize; +DWORD ZFileWriteHandle; +// return 0 + +// ZFileTell +DWORD ZFileTellHandle; + +// ZFileGetftime +BYTE * ZFFTimeFName; +DWORD ZFTimeHandle; +DWORD ZFDate; +DWORD ZFTime; + +// MKDir/CHDir +BYTE * MKPath; +BYTE * CHPath; +BYTE * RMPath; + +// GetDir +BYTE * DirName; +DWORD DriveNumber; + +// ZFileDelete +BYTE * ZFileDelFName; +// return current position + +DWORD ZFileSystemInit() +{ + CurrentHandle=0; + return(0); +} + +DWORD ZOpenFile() +{ + if(ZOpenMode==0) + { + if((FILEHANDLE[CurrentHandle]=fopen(ZOpenFileName,"rb"))!=NULL) + { + CurrentHandle+=1; + return(CurrentHandle-1); + } + return(0xFFFFFFFF); + } + if(ZOpenMode==1) + { + if((FILEHANDLE[CurrentHandle]=fopen(ZOpenFileName,"wb"))!=NULL) + { + CurrentHandle+=1; + return(CurrentHandle-1); + } + return(0xFFFFFFFF); + } + if(ZOpenMode==2) + { + if((FILEHANDLE[CurrentHandle]=fopen(ZOpenFileName,"r+b"))!=NULL) + { + CurrentHandle+=1; + return(CurrentHandle-1); + } + return(0xFFFFFFFF); + } + return(0xFFFFFFFF); +} + +DWORD ZCloseFile() +{ + fclose(FILEHANDLE[ZCloseFileHandle]); + CurrentHandle-=1; + return(0); +} + +DWORD ZFileSeek() +{ + if(ZFileSeekMode==0) + { + fseek(FILEHANDLE[ZFileSeekHandle],ZFileSeekPos,SEEK_SET); + return(0); + } + if(ZFileSeekMode==1) + { + fseek(FILEHANDLE[ZFileSeekHandle],ZFileSeekPos,SEEK_END); + return(0); + } + return(0xFFFFFFFF); +} + +DWORD ZFileRead() +{ + return(fread(ZFileReadBlock,1,ZFileReadSize,FILEHANDLE[ZFileReadHandle])); +} + + +DWORD ZFileWrite() +{ + if((fwrite(ZFileWriteBlock,1,ZFileWriteSize,FILEHANDLE[ZFileWriteHandle]))!=ZFileWriteSize) return(0xFFFFFFFF); + return(0); +} + +DWORD ZFileTell() +{ + return(ftell(FILEHANDLE[ZFileTellHandle])); +} + +DWORD ZFileDelete() +{ + return(remove(ZFileDelFName)); +} + +DWORD ZFileGetFTime() +{ + ZFDate=0; + ZFTime=0; + return(0); +} + +DWORD ZFileMKDir() +{ + return(mkdir(MKPath)); +} + +DWORD ZFileCHDir() +{ + return(chdir(CHPath)); +} + +DWORD ZFileRMDir() +{ + return(rmdir(RMPath)); +} + +char *ZFileGetDir() +{ + return(getcwd(DirName,128)); +} + +BYTE * ZFileFindPATH; +DWORD ZFileFindATTRIB; +DWORD DTALocPos; + +//struct _find_t { +// char reserved[21] __attribute__((packed)); +// unsigned char attrib __attribute__((packed)); +// unsigned short wr_time __attribute__((packed)); +// unsigned short wr_date __attribute__((packed)); +// unsigned long size __attribute__((packed)); +// char name[256] __attribute__((packed)); +//}; + + +int FindFirstHandle; +int TempFind; +#ifndef __LINUX__ +struct _finddata_t FindDataStruct; +#endif + +DWORD ZFileFindNext() +{ +#ifdef __LINUX__ + STUB_FUNCTION; +#else + TempFind=_findnext(FindFirstHandle,&FindDataStruct); + if(TempFind==-1) return(-1); + + *(char *)(DTALocPos+0x15)=0; + + if(ZFileFindATTRIB&0x10 && (FindDataStruct.attrib&0x10)==0) return(ZFileFindNext()); + if((ZFileFindATTRIB&0x10==0) && FindDataStruct.attrib&0x10) return(ZFileFindNext()); + + if(FindDataStruct.attrib&_A_SUBDIR) *(char *)(DTALocPos+0x15)=0x10; + strcpy((char *)DTALocPos+0x1E,FindDataStruct.name); + if(TempFind==-1) return(-1); + return(0); +#endif +} + +DWORD ZFileFindFirst() +{ +#ifdef __LINUX__ + STUB_FUNCTION; +#else + FindFirstHandle=_findfirst(ZFileFindPATH,&FindDataStruct); + *(char *)(DTALocPos+0x15)=0; + TempFind=0; + if(FindFirstHandle==-1) return(-1); + if(ZFileFindATTRIB&0x10 && (FindDataStruct.attrib&0x10)==0) return(ZFileFindNext()); + if((ZFileFindATTRIB&0x10==0) && FindDataStruct.attrib&0x10) return(ZFileFindNext()); + + if(FindDataStruct.attrib&_A_SUBDIR) *(char *)(DTALocPos+0x15)=0x10; + strcpy((char *) DTALocPos+0x1E,FindDataStruct.name); + if(FindFirstHandle==-1) return(-1); + return(0); +#endif +} + + +DWORD ZFileFindEnd() // for compatibility with windows later +{ +#ifdef __LINUX__ + STUB_FUNCTION; +#else + _findclose(FindFirstHandle); + return(0); +#endif +} + + +//BYTE * DirName; +//DWORD DriveNumber; + +//unsigned int _dos_findfirst(char *_name, unsigned int _attr, struct _find_t *_result); +//unsigned int _dos_findnext(struct _find_t *_result); + + +DWORD GetTime() +{ + + DWORD value; + struct tm *newtime; + time_t long_time; + + time( &long_time ); + newtime = localtime( &long_time ); + + value = ((newtime->tm_sec) % 10)+((newtime->tm_sec)/10)*16 + +((((newtime->tm_min) % 10)+((newtime->tm_min)/10)*16) << 8) + +((((newtime->tm_hour) % 10)+((newtime->tm_hour)/10)*16) << 16); + return(value); +} + +DWORD GetDate() +{ + + DWORD value; + struct tm *newtime; + time_t long_time; + + time( &long_time ); + newtime = localtime( &long_time ); + value = ((newtime->tm_mday) % 10)+((newtime->tm_mday)/10)*16 + +(((newtime->tm_mon)+1) << 8) + +((((newtime->tm_year) % 10)+((newtime->tm_year)/10)*16) << 16); + +((newtime->tm_wday) << 28); + + return(value); +} + +#ifdef __LINUX__ +int _chdrive( int drive ) +{ + STUB_FUNCTION; +} +int _getdrive( void ) +{ + STUB_FUNCTION; +} +void _splitpath( const char *path, char *drive, char *dir, char *fname, char *ext ) +{ + STUB_FUNCTION; +} +#endif diff --git a/zsnes/src/linux/zipxw.c b/zsnes/src/linux/zipxw.c new file mode 100644 index 00000000..36f9cc3a --- /dev/null +++ b/zsnes/src/linux/zipxw.c @@ -0,0 +1,57 @@ +//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. + +#ifndef __LINUX__ +#include +#endif + +void ipx_init(){}; +void sendpacket(){}; +void checkpacket(){}; +void read_packet(){}; +void ipx_deinit(){}; +void deinitipx(){}; +void initipx(){}; +void ipxgetchar(){}; +void ipxsendchar(){}; +void ipxlookforconnect(){}; +void PreparePacketIPX(){}; +void SendPacketIPX(){}; + +unsigned char IPXSearchval; +unsigned short ipx_initcode; +unsigned int ipx_packet; +unsigned int ipx_packet_size; +unsigned char ipx_packet_ready; +unsigned int ipx_read_packet; + +/* +EXTSYM _ipx_init ; To init ipx +EXTSYM _ipx_initcode ; return 0 if everything is ok (int) + +EXTSYM _ipx_packet ; 80 bytes buffer to send +EXTSYM _ipx_packet_size ; size to send (max 80 bytes) (dword) +EXTSYM _sendpacket ; to send a packet + +EXTSYM _checkpacket ; check if a packet is ready to receive +EXTSYM _ipx_packet_ready ; return 1 if there is a packet ready (byte) + +EXTSYM _read_packet ; to read an incoming packet +EXTSYM _ipx_read_packet ; 80 bytes buffer of received packet + +EXTSYM _ipx_deinit ; to deinit the ipx +*/ diff --git a/zsnes/src/linux/zloaderw.c b/zsnes/src/linux/zloaderw.c new file mode 100644 index 00000000..9b3aabbe --- /dev/null +++ b/zsnes/src/linux/zloaderw.c @@ -0,0 +1,577 @@ +//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. + + +#ifdef __LINUX__ +#include +#else +#include +#include +#endif // __LINUX__ + +#ifdef __LINUX__ +#define STUB_FUNCTION fprintf(stderr,"STUB: %s at " __FILE__ ", line %d, thread %d\n",__FUNCTION__,__LINE__,getpid()) +#define DWORD unsigned long +#define _MAX_PATH 80 +#define _MAX_DRIVE 80 +#define _MAX_DIR 80 +#define _MAX_FNAME 80 +#define _MAX_EXT 80 +#endif // __LINUX__ + +extern void zstart(void); +extern void DosExit(void); +extern void ConvertJoyMap1(void); +extern void ConvertJoyMap2(void); +extern void displayparams(void); +extern void makeextension(void); + +extern unsigned char Palette0, SPC700sh, OffBy1Line, DSPDisable, + FPUCopy, Force8b, ForcePal, GUIClick, MouseDis, + MusicRelVol, ScreenScale, SoundCompD, SoundQuality, + StereoSound, V8Mode, antienab, cvidmode, debugdisble, + debugger, enterpress, finterleave, frameskip, + gammalevel, guioff, per2exec, pl1contrl, pl2contrl, + romtype, scanlines, showallext, smallscreenon, soundon, + spcon, vsyncon, DisplayS, fname, filefound, SnowOn, + NetChatFirst,NetServer,NetNewNick, + NetFilename,GUINetTextk2,NetQuitAfter,UDPConfig; + +void ccmdline(void); + +char *ers[] = +{ + "Frame Skip must be a value of 0 to 9!\n", + "Gamma Correction Level must be a value of 0 to 5!\n", + "Sound Sampling Rate must be a value of 0 to 5!\n", + "Invalid Video Mode!\n", + "Percentage of instructions to execute must be a number from 50 to 150!\n", + "Player Input must be a value from 0 to 6!\n", + "Volume must be a number from 0 to 100!\n" + +}; + + + +int argc; +char **argv; + +char ucase(char ch){ + if ((ch>='a') && (ch<='z')) ch-='a'-'A'; + return(ch); +} + +#ifdef __LINUX__ +int main (int argc, char *argv[]) +#else +extern HINSTANCE hInst; +WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) +#endif // __LINUX__ +{ + int longueur; + + char path_buffer[_MAX_PATH], drive[_MAX_DRIVE] ,dir[_MAX_DIR]; + char fname2[_MAX_FNAME],ext[_MAX_EXT], File[_MAX_PATH]; + DWORD dwRead; + + char * strp; + + char ExtA[4][512]; + int charptr,strptr,strcharptr,dquotes; + int i,j,nofile; + +#ifndef __LINUX__ + hInst=hInstance; +#else + UnProtectMemory(); +#endif // !__LINUX__ + + // Commandline: /ABCDE + // nickname = user nickname + // fname = filename w/ full path (if L) or path name (if C) + // = IP Address (Client Only) + // A = U (UDP - Recommended if works), T (TCP/IP) + // B = S (Server), C (Client) + // C = C (Chat first), L (load game first) + // D = N (Stay in ZSNESw after disconnect), Q (Quit after disconnect) + // E = # of connections (Keep it 2 for now) + // eg: ZSNESW /UCCN2 nickname d:\snesroms 202.36.124.28 + + strptr=0; + charptr=0; + +#ifdef __LINUX__ + STUB_FUNCTION; +#else + while (szCmdLine[charptr]!=0){ + while (szCmdLine[charptr]==' ') charptr++; + dquotes=0; + if (szCmdLine[charptr]=='"'){ + dquotes=1; + charptr++; + } + strcharptr=0; + while (((szCmdLine[charptr]!=' ') || (dquotes)) && (szCmdLine[charptr]!=0)) { + if (szCmdLine[charptr]=='"'){ + dquotes=0; + } else { + if (strptr<4){ + ExtA[strptr][strcharptr]=szCmdLine[charptr]; + if (strcharptr<511) + strcharptr++; + } + } + charptr++; + } + ExtA[strptr][strcharptr]=0; + if (strcharptr) strptr++; + charptr++; + } +#endif // __LINUX__ + + NetServer=0; + NetChatFirst=0; + NetQuitAfter=0; + nofile=0; + if ((strptr>2) && (ExtA[0][0]=='/') && (strlen(ExtA[0])>=5)){ + nofile=1; + if (ucase(ExtA[0][1])=='T') UDPConfig=0; + if (ucase(ExtA[0][2])=='S') NetServer=1; + if (ucase(ExtA[0][2])=='C') NetServer=2; + if (ucase(ExtA[0][3])=='C') NetChatFirst=0; + if (ucase(ExtA[0][3])=='L') NetChatFirst=1; + if (ucase(ExtA[0][4])=='N') NetQuitAfter=0; + if (ucase(ExtA[0][4])=='Q') NetQuitAfter=1; + strp=&NetNewNick; + i=0; j=0; + while (ExtA[1][i]!=0){ + switch (ExtA[1][i]){ + case '_': + case '-': + case '^': + case '=': + case '+': + case '[': + case ']': + if (j<10){ + strp[j]=ExtA[1][i]; + j++; + } + break; + default: + if (((ucase(ExtA[1][i])>='A') && (ucase(ExtA[1][i])<='Z')) + || ((ExtA[1][i]>='0') && (ExtA[1][i]<='9'))){ + if (j<10){ + strp[j]=ExtA[1][i]; + j++; + } + } + break; + } + i++; + } + strp[j]=0; + strp=&NetFilename; + strncpy(strp,ExtA[2],512); + strp[511]=0; + if (NetServer==2){ + if (strptr<4) { + NetServer=0; + } else { + strp=&GUINetTextk2; + strncpy(strp,ExtA[3],28); + } + } + } + +#ifdef __LINUX__ + STUB_FUNCTION; +#else + GetModuleFileName(NULL,path_buffer,sizeof(path_buffer)); + _splitpath( path_buffer, drive, dir, fname2, ext ); + _chdrive(drive[0]-'A'+1); + chdir(dir+1); +#endif + + //argc=0; + +#ifdef __LINUX__ + STUB_FUNCTION; +#else + longueur=strlen(szCmdLine); + + if((longueur!=0) && (!nofile)) + { + char *fvar; + fvar=&fname; + + fvar[0] = longueur; + if(szCmdLine[0]=='"') + { + strncpy(&fvar[1],&szCmdLine[1],127); + fvar[longueur-1]=0; + } + else + { + strncpy(&fvar[1],szCmdLine,127); + } + makeextension(); + } +#endif +if ( argc > 1) { + char *fvar; + fvar=&fname; + fvar[0] = 10; + strcpy(&fvar[1], argv[1]); + makeextension(); + } + zstart(); +} + + +int my_atoi(char *nptr) +{ + int p,c; + c=0; + for(p=0;nptr[p];p++) + { + if( !isdigit(nptr[p]) ) c+=1; + } + if(c) return -1; + else return atoi(nptr); + +} + + +void ccmdline(void) +{ + int p=0; + p=pccmdline(); + if(p == 0) return; + + if(p == 9) + { + displayparams(); + } + if(p == 4) + { +// printf("Mangled command line, did you forget a parm?\n"); + printf("Invalid Commandline!\n"); + DosExit(); + } + + if((p > 9) && (p < 17)) + { + printf(ers[p-10]); + DosExit(); + } + if(p == 2) + { + DosExit(); + } + + + printf("cmdline returned %i\n",p); + DosExit(); + +} + +int pccmdline(void) +{ + int p; + int gfnm=0; + + for(p=1;p 6) return 15; + p++; + ConvertJoyMap1(); + break; + } + case '2': /* Player 2 Input */ + { + if(!hasroom) return 4; + pl2contrl=my_atoi(argv[p+1]); + if(pl2contrl > 6) return 15; + p++; + ConvertJoyMap2(); + break; + } + case 'f': + { + if(!hasroom) return 4; + frameskip=my_atoi(argv[p+1]); + if(frameskip > 9) return 10; + p++; + break; + } + case 'g': + { + if(!hasroom) return 4; + gammalevel=my_atoi(argv[p+1]); + if(gammalevel > 5) return 11; + p++; + break; + } + case 'p': + { + if(!hasroom) return 4; + per2exec=my_atoi(argv[p+1]); + if(per2exec > 150) return 14; + if(per2exec < 50) return 14; + p++; + break; + } + case 'r': + { + if(!hasroom) return 4; + SoundQuality=my_atoi(argv[p+1]); + if(SoundQuality > 5) return 12; + p++; + break; + } + case 'v': + { + if(nn == '8') + { + V8Mode=1; + pp++; + } + else + { + if(!hasroom) return 4; + cvidmode=my_atoi(argv[p+1]); + if(cvidmode > 10) return 13; + p++; + } + break; + } + case 'k': + { + if(!hasroom) return 4; + MusicRelVol=my_atoi(argv[p+1]); + if(MusicRelVol > 100) return 16; + p++; + break; + } + case '8': + { + Force8b=1; + break; + } + case '0': /* Palette 0 disable */ + { + Palette0=1; + break; + } + case '7': /* SPC700 speed hack disable */ + { + SPC700sh=1; + break; + } + case '9': /* Off by 1 line */ + { + OffBy1Line=1; + break; + } + case 'e': + { + enterpress=1; + break; + } + case 'h': + { + romtype=2; + break; + } + case 'l': + { + romtype=1; + break; + } + case 'm': + { + guioff=1; /* disables GUI */ + break; + } + case 'n': + { + scanlines=1; + break; + } + case 's': + { + if(nn == 'p') + { + DisplayS=1; + pp++; + } + else + if(nn == 'a') + { + showallext=1; + pp++; + } + else + if(nn == 'n') + { + SnowOn=1; + pp++; + } + else + { + spcon=1; + soundon=1; + } + break; + } + case 't': + { + ForcePal=1; + break; + } + case 'u': + { + ForcePal=2; + break; + } + case 'w': + { + vsyncon=1; + break; + } + case 'z': + { + StereoSound=1; + break; + } + case 'd': + { + if(nn == 'd') + { + DSPDisable=1; + pp++; + } + else + { + debugger=1; + debugdisble=0; + } + break; + } + case 'b': + { + SoundCompD=1; + break; + } + + case 'c': + { + if(nn == 'c') + { + smallscreenon=1; + pp++; + } + else + { + ScreenScale=1; + } + break; + } + + case 'y': + { + antienab=1; + break; + } + case 'o': + { + if(nn == 'm') + { + FPUCopy=2; + pp++; + } + else + { + FPUCopy=0; + } + break; + } + case 'i': + { + finterleave=1; + break; + } + case 'j': + { + GUIClick=0; + MouseDis=1; + break; + } + case '?': + { + return 9; + } + } + + } + + } + else + { + if(gfnm > 0) + { + printf("Limit yourself to one filename\n"); + return 2; + } + else + { + char *fvar; + fvar=&fname; + fvar[0] = strlen(argv[p]); + strncpy(&fvar[1],argv[p],127); + gfnm++; + } + } + } + if(gfnm == 1) + { + filefound=0; + makeextension(); + } + return 0; +} diff --git a/zsnes/src/linux/zsnes.rc b/zsnes/src/linux/zsnes.rc new file mode 100644 index 00000000..54f989d4 --- /dev/null +++ b/zsnes/src/linux/zsnes.rc @@ -0,0 +1 @@ +IDR_MAINFRAME ICON DISCARDABLE "ZSNES.ICO" diff --git a/zsnes/src/linux/ztcp.c b/zsnes/src/linux/ztcp.c new file mode 100644 index 00000000..256e2577 --- /dev/null +++ b/zsnes/src/linux/ztcp.c @@ -0,0 +1,1277 @@ +//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. + + +/**********************************************************\ +* ZSNES TCP/IP MODULE FOR NETWORK PLAY * +* * +* Coded by the ZSNES team * +* TCP/IP drivers coded by _Demo_, revised by Pharos * +* UDP drivers coded by _Demo_, revised by zsKnight * +* Gameplay netplay implementation by zsKnight * +* UDP Packet loss/out of order algorithm/implementation * +* by zsKnight, assistance on normal packets by Pharos * +\**********************************************************/ + +// UDP Algorithm: +// +// UDP Header (1 byte): 1 = Normal Packet w/ reply req, 2 = Reply Packet, +// 3 = Gameplay Packet (single byte), +// 4 = Gameplay Packet (larger packet), 5 = Re-request gameplay +// packet +// +// Normal Packets: +// Note: The actual implementation turned out to be quite different +// than the below descriptions. +// First byte contains the packet counter, followed by packet contents. +// Remote will send a Reply Packet (just contains packet counter) +// Each packet buffer will have a timer counter which decreases after +// every 1/60 seconds (value set at start is 60). If this reaches 0 +// that packet will be re-sent and reset the timer value back to 60. +// If the local side receives the reply packet, it will set the timer +// counter to -1. +// +// Gameplay Packets: +// Note: Gameplay counter is separate from normal packet counter. +// Note2: When referring to TCP/IP, it refers to the Normal Packets above. +// Each packet in TCP/IP will contain a byte counter when UDP is +// enabled. +// Each UDP packet will contain a byte counter, the number of packets, +// then each packet will contain a byte size only if there are > 1 +// packets. If the packet is just one byte long and contains a value<2, +// it will follow by a byte containing info on how many packets its has +// been like that for (it will not go beyond 32). If the packet is +// more than one byte long, it will repeat that packet as the extra +// packets for the next 3 packets, with the first byte of those packets +// as the byte counter of that packet, then the second as the size. +// Also, the send data will be stored in a 256*32 byte buffer in case +// of packet loss. +// When receiving, since no UDP packets will exceed 32bytes in length, +// there will be a 256*32 byte buffer and a 256 byte flag buffer. +// The flag clearing pointer will move at an offset of 128 from the +// actual point of the receive buffer. When it receives data from +// the UDP (or TCP), if the byte count of the data matches the +// receive pointer, it will just send the data directly and increase the +// receive pointer. Else it will fill the buffer accordingly based on +// the send data (for a maximum of 32 bytes). Then if the bit on the +// flag buffer is set for the current receive pointer, return the +// appropriate buffer and increase receive pointer. +// In case of packet loss, if no data has been received for every 500ms, the +// local side would send a re-send package request. What this would +// do is let the remote side build up a package containing all the +// data from the requested send point to the current receive point. +// A resend request will start off with 0x00,0xFF, then the counter +// number. A resent packet will start off with 0x00,0xFE, the # of +// packets, then the packet data (size of packet, data). A resend will +// only be done if the requested packet is within the past 64 packets. +// In-game chat will be moved to a separate packet in TCP/IP + +#include +#include +#ifdef __LINUX__ +#include +#include +#include +#include +#include +#include +#include +#include +#include // for FIONREAD +#else +#include +#include +#endif + +#ifdef __LINUX__ +#define closesocket(A) close(A) +#define CopyMemory(A,B,C) memcpy(A,B,C) +#define STUB_FUNCTION fprintf(stderr,"STUB: %s at " __FILE__ ", line %d, thread %d\n",__FUNCTION__,__LINE__,getpid()) +#define UINT unsigned int +#define WORD unsigned short +#define SOCKET int +#define SOCKADDR_IN struct sockaddr_in +#define LPSOCKADDR struct sockaddr* +#define LPHOSTENT struct hostent* +#define HOSTENT struct hostent +#define LPINADDR struct in_addr* +#define LPIN_ADDR struct in_addr* +#define SOCKET_ERROR -1 +#define INVALID_SOCKET -1 +#endif + +int RecvPtr; +int RecvPtr2; +unsigned char RecvFlags[256]; +unsigned char RecvBuffer[256*32]; +int RecvBufferSize[256]; + +int SendPtr; +int SendPtr2; +unsigned char SendBuffer[256*32]; +int SendBufferSize[256]; + +int SendRepeated; + +int PrevSPacket[16]; +int PrevSData[16*32]; +int PrevSSize[16]; +int PrevSPtr[16]; + +int tcperr; +unsigned short portval; +int UDPEnable = 1; +int UDPConfig = 1; +int UDPBackTrace = 6; +int blahblahblah = 0; +int CounterA = -1; +int CounterB = -1; +int UDPMode2 = 0; + +int packetnum,packetnumhead; +int packetrecvhead; +unsigned char packetdata[2048*16]; +unsigned char packetrdata[2048*32]; +int packetconfirm[256]; +int packetreceived[256]; +int packetreceivesize[256]; +int packetsize[256]; +unsigned char cpacketdata[2048+32]; +UINT ConnectAddr; +int packettimeleft[256]; +int packetresent[256]; +int PacketCounter=0; +unsigned char CLatencyVal=0; + + +SOCKET gamesocket; /* tcp socket for the game */ +SOCKET serversocket; /* tcp socket when the server is listening */ + +SOCKET ugamesocket; /* udp socket sending */ +SOCKET userversocket; /* udp socket listening */ + +SOCKADDR_IN serveraddress; /* address of the server */ +SOCKADDR_IN ugameaddress; /* address of the server */ +SOCKADDR_IN userveraddress; /* address of the server */ + +char blah[256]; +char remotehost[256]; +char hostname[50] = "IP N/A"; + +// Function Prototypes + +int SendData(int dsize,unsigned char *dptr); +int GetData(int dsize,unsigned char *dptr); + +/**********************************************************\ +* Initialize the zsnes tcpip module * +* - no parameters * +* - return 0 on success other value on error * +* * +* - no known side effects * +\**********************************************************/ + +int InitTCP() +{ + +#ifndef __LINUX__ + char blah[255]; + WORD versionneeded = MAKEWORD(2,2); + WSADATA wsadata; +#endif + + UDPEnable=0; + +#ifndef __LINUX__ + /* Startup winsock */ + WSAStartup(versionneeded, &wsadata); + + /* Verify version number and exit on wrong version */ + if (wsadata.wVersion != versionneeded) + { + return(-1); + } + serversocket=INVALID_SOCKET; +#endif + return(0); +} + + +/**********************************************************\ +* Deinitialize the zsnes tcpip module * +* - no parameters * +* * +* - no known side effects * +\**********************************************************/ + +void DeInitTCP() +{ +#ifndef __LINUX__ + WSACleanup(); +#endif +} + +/**********************************************************\ +* Gets UDP Status through sending data * +* - no parameters * +* * +* - no known side effects * +\**********************************************************/ + +void GetUDPStatus() { + int retval; + char NoSend = 0; + + UDPEnable=UDPConfig; + + if (!UDPEnable){ + blah[0]=0; + retval = send(gamesocket,blah,1,0); + gethostname(blah,255); + retval = send(gamesocket,blah,strlen(blah),0); + } + else { + blah[0]=1; + retval = send(gamesocket,blah,1,0); + gethostname(blah,255); + retval = send(gamesocket,blah,strlen(&blah[1])+1,0); + } + + retval = recv(gamesocket,blah,256,0); + if (blah[0]==0) UDPEnable=0; + retval = recv(gamesocket,blah,256,0); +} + +/**********************************************************\ +* Connect to game server * +* - parameters * +* - pointer server name * +* - server port * +* - return 0 on success other value on error * +* * +* - no known side effects * +\**********************************************************/ + +int isipval(char *name){ + int i; + int tcperr; + i=0; + while(name[i]!=0){ + if (!((name[i]=='.') || ((name[i]>='0') && (name[i]<='9')))) + return(0); + i++; + } + return(1); +} + +int ConnectServer(char *servername, unsigned int port) +{ + char blah[255]; + int retval,i; + LPHOSTENT host1; + unsigned long addr1; + int yesip; +#ifndef __LINUX__ + WSADATA wsadata; +#endif + + packetnum = 0; + packetnumhead = 0; + packetrecvhead = 0; + RecvPtr = 0; + SendPtr = 0; + RecvPtr2 = 0; + SendPtr2 = 0; + + ConnectAddr = 0; + SendRepeated = 0; + for (i=0;i<16;i++) + PrevSPacket[i]=0; + + /* get host and verify if it is valid */ + yesip = isipval(servername); + if (!yesip){ + host1 = gethostbyname(servername); + if (host1 == NULL) + { + return(-1); + } + } + +// return(-1); + if (UDPConfig) UDPEnable = 1; + + if (UDPEnable) + { + PacketCounter=1; + for (i=0;i<256;i++) {packettimeleft[i]=-1; packetconfirm[i]=1; packetreceived[i]=0; RecvFlags[i]=0;} + + userveraddress.sin_family = AF_INET; + ugameaddress.sin_family = AF_INET; + + if (!yesip) + { + ugameaddress.sin_addr = *( (LPIN_ADDR) *host1->h_addr_list ); + } + else + { + ugameaddress.sin_addr.s_addr = inet_addr(servername); + } + + ConnectAddr = ugameaddress.sin_addr.s_addr; + + userveraddress.sin_addr.s_addr = INADDR_ANY; + +// port++; + ugameaddress.sin_port = htons((unsigned short) port); + userveraddress.sin_port = htons((unsigned short) port); +// port--; + + userversocket = socket(AF_INET, SOCK_DGRAM,0); + ugamesocket = socket(AF_INET, SOCK_DGRAM,0); + + if (ugamesocket == INVALID_SOCKET) + { +#ifdef __LINUX__ + STUB_FUNCTION; +#else + tcperr=WSAGetLastError(); + sprintf(blah,"Could not initialize UDP(2) : %d",tcperr); + MessageBox(NULL,blah,"Error",MB_SYSTEMMODAL|MB_OK); +#endif + return(-2); + } + + if (userversocket == INVALID_SOCKET) + { +#ifdef __LINUX__ + STUB_FUNCTION; +#else + tcperr=WSAGetLastError(); + sprintf(blah,"Could not initialize UDP(2.5) : %d",tcperr); + MessageBox(NULL,blah,"Error",MB_SYSTEMMODAL|MB_OK); +#endif + return(-2); + } + + if (bind(userversocket,(struct sockaddr*)&userveraddress,sizeof(userveraddress))== + SOCKET_ERROR) + { +#ifdef __LINUX__ + STUB_FUNCTION; +#else + tcperr=WSAGetLastError(); + sprintf(blah,"Could not initialize UDP(16) : %d",tcperr); + MessageBox(NULL,blah,"Error",MB_SYSTEMMODAL|MB_OK); +#endif + return(-2); + } + + +// blah[0]=1; +// retval = sendto(ugamesocket,blah,1,0,(struct sockaddr*)&ugameaddress,sizeof(struct sockaddr)); +// if (retval == SOCKET_ERROR) return(-1); + + blah[0]=1; + SendData(1,blah); + +// retval = sendto(ugamesocket,blah,5,0,(struct sockaddr*)&ugameaddress,sizeof(struct sockaddr)); +// blah[0]=0; +// i = sizeof(struct sockaddr); +// retval = recvfrom(userversocket,blah,5,0,(struct sockaddr*)&userveraddress,&i); + +// MessageBox(NULL,blah, +// "Error", +// MB_SYSTEMMODAL|MB_OK); + + return(0); + +// retval = send(gamesocket,blah,1,0); +// retval = recv(gamesocket,blah,1,0); + } + + + /* create the game socket and verify if it is valid */ + gamesocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (gamesocket == INVALID_SOCKET) + { + return(-2); + } + + + /* initialize server address */ + serveraddress.sin_family = AF_INET; + if (!yesip) + serveraddress.sin_addr = *( (LPIN_ADDR) *host1->h_addr_list ); + else + serveraddress.sin_addr.s_addr = inet_addr(servername); + + serveraddress.sin_port = htons((unsigned short)port); + + + /* try to connect to the server */ + retval = connect( gamesocket, + (LPSOCKADDR)&serveraddress, + sizeof(struct sockaddr)); + if (retval == SOCKET_ERROR) + { +#ifdef __LINUX__ + STUB_FUNCTION; +#else + sprintf(blah,"Could not connect to other side"); + MessageBox(NULL,blah, + "Error", + MB_SYSTEMMODAL|MB_OK); +#endif + + closesocket(gamesocket); + return(-3); + } + +// GetUDPStatus(); + + return(0); +} + +int WaitForServer(){ + int i; + + if (UDPEnable){ + if (i=GetData(1,blah)){ + if ((i==1) && (blah[0]==1)) + return(1); + } + return(0); + } + return(1); +} + + +/**********************************************************\ +* Disconnect from game server * +* - no parameters * +* * +* - no known side effects * +\**********************************************************/ + +void Disconnect() +{ + if (UDPEnable) + { + closesocket(ugamesocket); + closesocket(userversocket); + return; + } + PacketCounter=0; + closesocket(gamesocket); +} + + +/**********************************************************\ +* Start the game server * +* - parameters * + - port number +* - return 0 on success other value on error * +* * +* - no known side effects * +\**********************************************************/ + +int StartServerCycle(unsigned short port) +{ + int retval,sizet,i; + + portval = port; + packetnum = 0; + packetnumhead = 0; + packetrecvhead = 0; + ConnectAddr = 0; + SendRepeated = 0; + RecvPtr = 0; + SendPtr = 0; + RecvPtr2 = 0; + SendPtr2 = 0; + + for (i=0;i<16;i++) + PrevSPacket[i]=0; + + + if (UDPConfig) UDPEnable = 1; + + if (UDPEnable) + { + /* get host and verify if it is valid */ + PacketCounter=1; + for (i=0;i<256;i++) {packettimeleft[i]=-1; packetconfirm[i]=1; packetreceived[i]=0; RecvFlags[i]=0;} + + userveraddress.sin_family = AF_INET; + ugameaddress.sin_family = AF_INET; + + userveraddress.sin_addr.s_addr = INADDR_ANY; + ugameaddress.sin_addr.s_addr = INADDR_ANY; + +// portval++; + ugameaddress.sin_port = htons((unsigned short) portval); + userveraddress.sin_port = htons((unsigned short) portval); +// portval--; + + userversocket = socket(AF_INET, SOCK_DGRAM,0); + ugamesocket = socket(AF_INET, SOCK_DGRAM,0); + + if (userversocket == INVALID_SOCKET) + { +#ifdef __LINUX__ + STUB_FUNCTION; +#else + tcperr=WSAGetLastError(); + sprintf(blah,"Could not initialize UDP(5) : %d",tcperr); + MessageBox(NULL,blah,"Error",MB_SYSTEMMODAL|MB_OK); +#endif + return(-2); + } + if (bind(userversocket,(struct sockaddr*)&userveraddress,sizeof(userveraddress))== + SOCKET_ERROR) + { +#ifdef __LINUX__ + STUB_FUNCTION; +#else + tcperr=WSAGetLastError(); + sprintf(blah,"Could not initialize UDP(6) : %d",tcperr); + MessageBox(NULL,blah,"Error",MB_SYSTEMMODAL|MB_OK); +#endif + return(-2); + } + + + blah[0]=2; + blah[1]='C'; + blah[2]='B'; + blah[3]='A'; + blah[4]=0; + + +// retval = recvfrom(userversocket,blah,5,0, +// (struct sockaddr *)&userveraddress,&socklen); + + ugameaddress.sin_addr.s_addr = userveraddress.sin_addr.s_addr; + + ugamesocket = socket(AF_INET, SOCK_DGRAM,0); + + return(0); + +// retval = send(gamesocket,blah,1,0); +// retval = recv(gamesocket,blah,1,0); + + } + + /* Create the listen socket */ + serversocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (serversocket == INVALID_SOCKET) + { +#ifndef __LINUX__ + tcperr=WSAGetLastError(); +#endif + + return(-1); + } + + serveraddress.sin_family = AF_INET; + serveraddress.sin_addr.s_addr = INADDR_ANY; + serveraddress.sin_port = htons(port); + + /* bind name and socket */ + retval = bind(serversocket, + (LPSOCKADDR)&serveraddress, + sizeof(struct sockaddr)); + if (retval == SOCKET_ERROR) + { +#ifndef __LINUX__ + tcperr=WSAGetLastError(); +#endif + closesocket(serversocket); + return(-2); + } + + /* setup socket to listen */ + retval = listen(serversocket, SOMAXCONN); + if (retval == SOCKET_ERROR) + { +#ifndef __LINUX__ + tcperr=WSAGetLastError(); +#endif + closesocket(serversocket); + return(-3); + } + + return 0; +} + +int acceptzuser() +{ + int retval,r,i; + LPHOSTENT host1; + int yesip; + + if (UDPEnable) + { + return(0); + } + + /* wait for connection */ + + gamesocket = accept(serversocket, NULL, NULL); + if (gamesocket == INVALID_SOCKET) + { +#ifndef __LINUX__ + tcperr=WSAGetLastError(); +#endif + closesocket(serversocket); + serversocket=-1; + return(-1); + } + +// GetUDPStatus(); + + return(0); +} + +int ServerCheckNewClient() +{ +#ifdef __LINUX__ + fd_set zrf; +#else + FD_SET zrf; +#endif + struct timeval nto; + int r; + + if (UDPEnable) + { + r=GetData(256,blah); + if (r == -1) return(-1); + if (r > 0){ + ugameaddress.sin_addr.s_addr=userveraddress.sin_addr.s_addr; + ConnectAddr = ugameaddress.sin_addr.s_addr; + blah[0]=1; + r=SendData(1,blah); + return(1); + } + return(0); + } + + if(serversocket == INVALID_SOCKET) + { + return(-1); + } + nto.tv_sec=0; + nto.tv_usec=0; /* return immediately */ + + FD_ZERO(&zrf); + FD_SET(serversocket,&zrf); + r=select(serversocket+1,&zrf,0,0,&nto); + + if(r == -1) + { +#ifndef __LINUX__ + tcperr=WSAGetLastError(); +#endif + return(-2); + } + if(r == 0) + { + return(0); + } + if(FD_ISSET(serversocket,&zrf)) + { + return 1; + } + return(0); + +} + + +/**********************************************************\ +* Stop the game server * +* - no parameters * +* * +* - no known side effects * +\**********************************************************/ + +void StopServer() +{ + if (UDPEnable) + { + closesocket(ugamesocket); + closesocket(userversocket); + return; + } + PacketCounter=0; + closesocket(gamesocket); + closesocket(serversocket); +} + + +/**********************************************************\ +* Send data * +* - parameters : * +* - size of data * +* - pointer to data * +* - return 0 on success other value on error * +* * +* - side effects : * +* - close the socket on error * +\**********************************************************/ + +int PacketReceive() +{ + int dataleft,i,i2,i3,i4,i5,i6,i7,retval; + + dataleft=GetLeftUDP(); + if (dataleft<=0) return(dataleft); + i = sizeof(userveraddress); + retval = recvfrom(userversocket,cpacketdata,2048+32,0,(struct sockaddr *)&userveraddress,&i); + if ((ConnectAddr!=0) && (ConnectAddr != userveraddress.sin_addr.s_addr)) return(0); + if (retval == SOCKET_ERROR) + { + closesocket(ugamesocket); + return(-1); + } + if ((cpacketdata[0]==1) && (retval>0)) { + i=(unsigned char)cpacketdata[1]; + blah[0]=2; + blah[1]=cpacketdata[1]; + sendto(ugamesocket,blah,2,0,(struct sockaddr *)&ugameaddress,sizeof(ugameaddress)); + if (!packetreceived[i]){ + packetreceived[i]=1; + packetreceivesize[i]=retval-2; + CopyMemory(&(packetrdata[2048*(i & 0x0F)]),&(cpacketdata[2]),retval-2); + } + } + if (cpacketdata[0]==2){ + packetconfirm[cpacketdata[1]]=1; + while ((packetconfirm[packetnumhead]) && (packetnum!=packetnumhead)) + packetnumhead=(packetnumhead+1) & 0xFF; + } + + if ((cpacketdata[0]==16) && (cpacketdata[1]!=SendPtr)){ + i=cpacketdata[1]; + cpacketdata[0]=17; + cpacketdata[2]=SendPtr; + i3=3; + while (i!=SendPtr){ + cpacketdata[i3]=SendBufferSize[i]; + i3++; + for (i4=0;i4=0) && (i3<=127))) { + + + CLatencyVal=cpacketdata[1]; + i=cpacketdata[2]; + i3=0; + + if ((cpacketdata[0] & 0x07)==4){ + for (i2=0;i2512) packettimeleft[packetnum]=60*3; + packetresent[i]++; + CopyMemory(&(cpacketdata[2]),&(packetdata[2048*(i & 0x0F)]),packetsize[i]); + cpacketdata[0]=1; + cpacketdata[1]=(char)i; + sendto(ugamesocket,cpacketdata,packetsize[i]+2,0,(struct sockaddr *)&ugameaddress,sizeof(ugameaddress)); + } + } +} + +extern void UpdateVFrame(void); + +int SendData(int dsize,unsigned char *dptr) +{ + int retval; + char message1[256]; + + if (UDPEnable){ +/* retval = sendto(ugamesocket,dptr,dsize,0,(struct sockaddr *)&ugameaddress,sizeof(ugameaddress)); + if (retval == SOCKET_ERROR) + { + closesocket(gamesocket); + return(-1); + } + return(0); */ + + if (((packetnum-packetnumhead) & 0xFF) >= 15){ +// sprintf(message1,"Packet Overflow."); +// MessageBox (NULL, message1, "Init Error" , MB_ICONERROR ); + + // wait for receive packet, call JoyRead while waiting + while (((packetnum-packetnumhead) & 0xFF) >= 15){ + PacketResend(); + PacketReceive(); + UpdateVFrame(); + while ((packetconfirm[packetnumhead]) && (packetnum!=packetnumhead)) + packetnumhead=(packetnumhead+1) & 0xFF; + } + } + CopyMemory(&(cpacketdata[2]),dptr,dsize); + CopyMemory(&(packetdata[2048*(packetnum & 0x0F)]),dptr,dsize); + packetsize[packetnum]=dsize; + packetconfirm[packetnum]=0; + cpacketdata[0]=1; + cpacketdata[1]=(char)packetnum; + retval = sendto(ugamesocket,cpacketdata,dsize+2,0,(struct sockaddr *)&ugameaddress,sizeof(ugameaddress)); + packettimeleft[packetnum]=60; + if (dsize>512) packettimeleft[packetnum]=90; + packetresent[packetnum]=1; + packetnum=(packetnum+1) & 0xFF; + if (retval == SOCKET_ERROR) + { + closesocket(ugamesocket); + return(-1); + } + return(0); + } + + /* send data with the socket */ + retval = send(gamesocket,dptr,dsize,0); + if (retval == SOCKET_ERROR) + { + closesocket(gamesocket); + return(-1); + } + return(0); +} + + +/**********************************************************\ +* Send data UDP * +* - parameters : * +* - size of data * +* - pointer to data * +* - return 0 on success other value on error * +* * +* - side effects : * +* - close the socket on error * +\**********************************************************/ + +int AttachEnd(int psb){ + int i,i2,i3,ps; +//int PrevSPacket[4]; +//int PrevSData[4*32]; +//int PrevSSize[4]; + + ps=psb; + i2=0; + for (i=0;i<(UDPBackTrace-1);i++){ + if (PrevSPacket[i]) i2++; + } +// if (PrevSPacket[0]) i2=0; + if (i2){ + cpacketdata[0]+=8; + cpacketdata[ps]=(char)i2; + ps++; + for (i=0;i<(UDPBackTrace-1);i++){ + if (PrevSPacket[i]){ + cpacketdata[ps]=PrevSPtr[i]; + cpacketdata[ps+1]=PrevSSize[i]; + ps+=2; + for (i3=0;i3h_addr)); + strcat(hostname,blah); + } +} + +void UDPWait1Sec(){ + CounterB=60; + while (CounterB>0) + UpdateVFrame(); +} + +void UDPClearVars(){ + int i; + CounterA=-1; + RecvPtr = 0; + SendPtr = 0; + for (i=0;i<16;i++) + PrevSPacket[i]=0; + for (i=0;i<256;i++) + RecvFlags[i]=0; +} + +void UDPEnableMode(){ + UDPMode2=1; +} + +void UDPDisableMode(){ + UDPMode2=0; +} + +void WinErrorA2(void){ +#ifdef __LINUX__ + STUB_FUNCTION; +#else + char message1[256]; + sprintf(message1,"Failed waiting for checksum."); + MessageBox (NULL, message1, "Init Error" , MB_ICONERROR ); +#endif +} + +void WinErrorB2(void){ +#ifdef __LINUX__ + STUB_FUNCTION; +#else + char message1[256]; + sprintf(message1,"Failed waiting for confirmation."); + MessageBox (NULL, message1, "Init Error" , MB_ICONERROR ); +#endif +} + +void WinErrorC2(void){ +#ifdef __LINUX__ + STUB_FUNCTION; +#else + char message1[256]; + sprintf(message1,"Failed waiting for confirmation(B)."); + MessageBox (NULL, message1, "Init Error" , MB_ICONERROR ); +#endif +} +