| | 1 | /***************************************************************************\r |
| | 2 | gpu.c - description\r |
| | 3 | -------------------\r |
| | 4 | begin : Sun Mar 08 2009\r |
| | 5 | copyright : (C) 1999-2009 by Pete Bernert\r |
| | 6 | email : BlackDove@addcom.de\r |
| | 7 | ***************************************************************************/\r |
| | 8 | \r |
| | 9 | /***************************************************************************\r |
| | 10 | * *\r |
| | 11 | * This program is free software; you can redistribute it and/or modify *\r |
| | 12 | * it under the terms of the GNU General Public License as published by *\r |
| | 13 | * the Free Software Foundation; either version 2 of the License, or *\r |
| | 14 | * (at your option) any later version. See also the license.txt file for *\r |
| | 15 | * additional informations. *\r |
| | 16 | * *\r |
| | 17 | ***************************************************************************/\r |
| | 18 | \r |
| | 19 | //*************************************************************************// \r |
| | 20 | // History of changes:\r |
| | 21 | //\r |
| | 22 | // 2009/03/08 - Pete \r |
| | 23 | // - generic cleanup for the Peops release\r |
| | 24 | //\r |
| | 25 | //*************************************************************************// \r |
| | 26 | \r |
| | 27 | //#include "gpuStdafx.h"\r |
| | 28 | \r |
| | 29 | //#include <mmsystem.h>\r |
| | 30 | #define _IN_GPU\r |
| | 31 | \r |
| | 32 | #include <stdlib.h>\r |
| | 33 | #include <stdio.h>\r |
| | 34 | #include <stdarg.h>\r |
| | 35 | #include <string.h>\r |
| | 36 | #include "gpuExternals.h"\r |
| | 37 | #include "gpuPlugin.h"\r |
| | 38 | #include "gpuDraw.h"\r |
| | 39 | #include "gpuTexture.h"\r |
| | 40 | #include "gpuFps.h"\r |
| | 41 | #include "gpuPrim.h"\r |
| | 42 | \r |
| | 43 | //#include "NoPic.h"\r |
| | 44 | \r |
| | 45 | #include "gpuStdafx.h"\r |
| | 46 | \r |
| | 47 | short g_m1=255,g_m2=255,g_m3=255;\r |
| | 48 | short DrawSemiTrans=FALSE;\r |
| | 49 | short Ymin;\r |
| | 50 | short Ymax;\r |
| | 51 | \r |
| | 52 | short ly0,lx0,ly1,lx1,ly2,lx2,ly3,lx3; // global psx vertex coords\r |
| | 53 | long GlobalTextAddrX,GlobalTextAddrY,GlobalTextTP;\r |
| | 54 | long GlobalTextREST,GlobalTextABR,GlobalTextPAGE;\r |
| | 55 | \r |
| | 56 | unsigned long dwGPUVersion=0;\r |
| | 57 | int iGPUHeight=512;\r |
| | 58 | int iGPUHeightMask=511;\r |
| | 59 | int GlobalTextIL=0;\r |
| | 60 | int iTileCheat=0;\r |
| | 61 | \r |
| | 62 | ////////////////////////////////////////////////////////////////////////\r |
| | 63 | // memory image of the PSX vram\r |
| | 64 | ////////////////////////////////////////////////////////////////////////\r |
| | 65 | \r |
| | 66 | unsigned char *psxVSecure;\r |
| | 67 | unsigned char *psxVub;\r |
| | 68 | signed char *psxVsb;\r |
| | 69 | unsigned short *psxVuw;\r |
| | 70 | unsigned short *psxVuw_eom;\r |
| | 71 | signed short *psxVsw;\r |
| | 72 | unsigned long *psxVul;\r |
| | 73 | signed long *psxVsl;\r |
| | 74 | \r |
| | 75 | // macro for easy access to packet information\r |
| | 76 | #define GPUCOMMAND(x) ((x>>24) & 0xff)\r |
| | 77 | \r |
| | 78 | GLfloat gl_z=0.0f;\r |
| | 79 | BOOL bNeedInterlaceUpdate=FALSE;\r |
| | 80 | BOOL bNeedRGB24Update=FALSE;\r |
| | 81 | BOOL bChangeWinMode=FALSE;\r |
| | 82 | \r |
| | 83 | unsigned long ulStatusControl[256];\r |
| | 84 | \r |
| | 85 | ////////////////////////////////////////////////////////////////////////\r |
| | 86 | // global GPU vars\r |
| | 87 | ////////////////////////////////////////////////////////////////////////\r |
| | 88 | \r |
| | 89 | static long GPUdataRet;\r |
| | 90 | long lGPUstatusRet;\r |
| | 91 | char szDispBuf[64];\r |
| | 92 | \r |
| | 93 | static unsigned long gpuDataM[256];\r |
| | 94 | static unsigned char gpuCommand = 0;\r |
| | 95 | static long gpuDataC = 0;\r |
| | 96 | static long gpuDataP = 0;\r |
| | 97 | \r |
| | 98 | VRAMLoad_t VRAMWrite;\r |
| | 99 | VRAMLoad_t VRAMRead;\r |
| | 100 | int iDataWriteMode;\r |
| | 101 | int iDataReadMode;\r |
| | 102 | \r |
| | 103 | long lClearOnSwap;\r |
| | 104 | long lClearOnSwapColor;\r |
| | 105 | BOOL bSkipNextFrame = FALSE;\r |
| | 106 | int iColDepth;\r |
| | 107 | BOOL bChangeRes;\r |
| | 108 | BOOL bWindowMode;\r |
| | 109 | int iWinSize;\r |
| | 110 | \r |
| | 111 | // possible psx display widths\r |
| | 112 | short dispWidths[8] = {256,320,512,640,368,384,512,640};\r |
| | 113 | \r |
| | 114 | PSXDisplay_t PSXDisplay;\r |
| | 115 | PSXDisplay_t PreviousPSXDisplay;\r |
| | 116 | TWin_t TWin;\r |
| | 117 | short imageX0,imageX1;\r |
| | 118 | short imageY0,imageY1;\r |
| | 119 | BOOL bDisplayNotSet = TRUE;\r |
| | 120 | GLuint uiScanLine=0;\r |
| | 121 | int iUseScanLines=0;\r |
| | 122 | long lSelectedSlot=0;\r |
| | 123 | unsigned char * pGfxCardScreen=0;\r |
| | 124 | int iBlurBuffer=0;\r |
| | 125 | int iScanBlend=0;\r |
| | 126 | int iRenderFVR=0;\r |
| | 127 | int iNoScreenSaver=0;\r |
| | 128 | unsigned long ulGPUInfoVals[16];\r |
| | 129 | int iFakePrimBusy = 0;\r |
| | 130 | int iRumbleVal = 0;\r |
| | 131 | int iRumbleTime = 0;\r |
| | 132 | \r |
| | 133 | static void (*rearmed_get_layer_pos)(int *x, int *y, int *w, int *h);\r |
| | 134 | static void flipEGL(void);\r |
| | 135 | \r |
| | 136 | ////////////////////////////////////////////////////////////////////////\r |
| | 137 | // stuff to make this a true PDK module\r |
| | 138 | ////////////////////////////////////////////////////////////////////////\r |
| | 139 | \r |
| | 140 | ////////////////////////////////////////////////////////////////////////\r |
| | 141 | // snapshot funcs (saves screen to bitmap / text infos into file)\r |
| | 142 | ////////////////////////////////////////////////////////////////////////\r |
| | 143 | \r |
| | 144 | void ResizeWindow()\r |
| | 145 | {\r |
| | 146 | rRatioRect.left = rRatioRect.top=0;\r |
| | 147 | rRatioRect.right = iResX;\r |
| | 148 | rRatioRect.bottom = iResY;\r |
| | 149 | glViewport(rRatioRect.left, // init viewport by ratio rect\r |
| | 150 | iResY-(rRatioRect.top+rRatioRect.bottom),\r |
| | 151 | rRatioRect.right, \r |
| | 152 | rRatioRect.bottom); glError();\r |
| | 153 | \r |
| | 154 | glScissor(0, 0, iResX, iResY); glError(); // init clipping (fullscreen)\r |
| | 155 | glEnable(GL_SCISSOR_TEST); glError();\r |
| | 156 | \r |
| | 157 | #ifndef OWNSCALE\r |
| | 158 | glMatrixMode(GL_TEXTURE); // init psx tex sow and tow if not "ownscale"\r |
| | 159 | glLoadIdentity();\r |
| | 160 | glScalef(1.0f/255.99f,1.0f/255.99f,1.0f); // geforce precision hack\r |
| | 161 | #endif \r |
| | 162 | \r |
| | 163 | glMatrixMode(GL_PROJECTION); glError(); // init projection with psx resolution\r |
| | 164 | glLoadIdentity(); glError();\r |
| | 165 | glOrtho(0,PSXDisplay.DisplayMode.x,\r |
| | 166 | PSXDisplay.DisplayMode.y, 0, -1, 1); glError();\r |
| | 167 | if (bKeepRatio)\r |
| | 168 | SetAspectRatio();\r |
| | 169 | }\r |
| | 170 | \r |
| | 171 | char * GetConfigInfos(int hW)\r |
| | 172 | {\r |
| | 173 | char szO[2][4]={"off","on "};\r |
| | 174 | char szTxt[256];\r |
| | 175 | char * pB=(char *)malloc(32767);\r |
| | 176 | /*\r |
| | 177 | if(!pB) return NULL;\r |
| | 178 | *pB=0;\r |
| | 179 | //----------------------------------------------------//\r |
| | 180 | strcat(pB,szTxt);\r |
| | 181 | strcat(pB,szTxt);\r |
| | 182 | #ifdef _WINDOWS\r |
| | 183 | if(hW)\r |
| | 184 | {\r |
| | 185 | hdc = GetDC(hW);\r |
| | 186 | bSetupPixelFormat(hdc);\r |
| | 187 | hglrc = wglCreateContext(hdc);\r |
| | 188 | wglMakeCurrent(hdc, hglrc);\r |
| | 189 | }\r |
| | 190 | #endif\r |
| | 191 | sprintf(szTxt,"Card vendor: %s\r\n",(char *)glGetString(GL_VENDOR));\r |
| | 192 | strcat(pB,szTxt);\r |
| | 193 | sprintf(szTxt,"GFX card: %s\r\n",(char *)glGetString(GL_RENDERER));\r |
| | 194 | strcat(pB,szTxt);\r |
| | 195 | sprintf(szTxt,"OGL version: %s\r\n\r\n",(char *)glGetString(GL_VERSION));\r |
| | 196 | strcat(pB,szTxt);\r |
| | 197 | //strcat(pB,(char *)glGetString(GL_EXTENSIONS));\r |
| | 198 | //strcat(pB,"\r\n\r\n");\r |
| | 199 | \r |
| | 200 | #ifdef _WINDOWS\r |
| | 201 | if(hW)\r |
| | 202 | {\r |
| | 203 | wglMakeCurrent(NULL, NULL);\r |
| | 204 | wglDeleteContext(hglrc);\r |
| | 205 | ReleaseDC(hW,hdc);\r |
| | 206 | }\r |
| | 207 | //----------------------------------------------------//\r |
| | 208 | #endif\r |
| | 209 | if(hW && bWindowMode)\r |
| | 210 | sprintf(szTxt,"Resolution/Color:\r\n- %dx%d ",LOWORD(iWinSize),HIWORD(iWinSize));\r |
| | 211 | else\r |
| | 212 | sprintf(szTxt,"Resolution/Color:\r\n- %dx%d ",iResX,iResY);\r |
| | 213 | strcat(pB,szTxt);\r |
| | 214 | if(bWindowMode) sprintf(szTxt,"Window mode\r\n");\r |
| | 215 | else\r |
| | 216 | {\r |
| | 217 | sprintf(szTxt,"Fullscreen ");\r |
| | 218 | strcat(pB,szTxt);\r |
| | 219 | if(bChangeRes) sprintf(szTxt,"- Desktop changing [%d Bit]\r\n",iColDepth);\r |
| | 220 | else sprintf(szTxt,"- NO desktop changing\r\n");\r |
| | 221 | } \r |
| | 222 | strcat(pB,szTxt);\r |
| | 223 | \r |
| | 224 | // if(iForceVSync>=0) sprintf(szTxt,"- V-Sync: %s\r\n",szO[iForceVSync]);\r |
| | 225 | // else strcpy(szTxt,"- V-Sync: Driver\r\n");\r |
| | 226 | strcat(pB,szTxt); \r |
| | 227 | sprintf(szTxt,"- Keep psx aspect ratio: %s\r\n\r\n",szO[bKeepRatio]);\r |
| | 228 | strcat(pB,szTxt);\r |
| | 229 | //----------------------------------------------------//\r |
| | 230 | strcpy(szTxt,"Textures:\r\n- ");\r |
| | 231 | /*! if(iTexQuality==0) strcat(szTxt,"Default");\r |
| | 232 | else if(iTexQuality==1) strcat(szTxt,"R4G4B4A4");\r |
| | 233 | else if(iTexQuality==2) strcat(szTxt,"R5G5B5A1");\r |
| | 234 | else if(iTexQuality==3) strcat(szTxt,"R8G8A8A8");\r |
| | 235 | else if(iTexQuality==4) strcat(szTxt,"B8G8R8A8");\r |
| | 236 | if(!hW && bGLExt) strcat(szTxt," (packed pixels)\r\n");\r |
| | 237 | else strcat(szTxt,"\r\n");\r |
| | 238 | strcat(pB,szTxt);\r |
| | 239 | if(!hW)\r |
| | 240 | {\r |
| | 241 | sprintf(szTxt,"- Filtering: %d - edge clamping ",iFilterType);\r |
| | 242 | if(iClampType==GL_TO_EDGE_CLAMP) strcat(szTxt,"supported\r\n");\r |
| | 243 | else strcat(szTxt,"NOT supported\r\n");\r |
| | 244 | }\r |
| | 245 | else sprintf(szTxt,"- iFiltering: %d\r\n",iFilterType);\r |
| | 246 | strcat(pB,szTxt);\r |
| | 247 | sprintf(szTxt,"- Hi-Res textures: %d\r\n",iHiResTextures);\r |
| | 248 | strcat(pB,szTxt); \r |
| | 249 | if(!hW)\r |
| | 250 | {\r |
| | 251 | sprintf(szTxt,"- Palettized tex windows: %s\r\n",szO[iUsePalTextures]);\r |
| | 252 | strcat(pB,szTxt); \r |
| | 253 | }\r |
| | 254 | !*/\r |
| | 255 | /*sprintf(szTxt,"- VRam size: %d MBytes",iVRamSize);\r |
| | 256 | if(!hW)\r |
| | 257 | sprintf(szTxt+strlen(szTxt)," - %d textures usable\r\n\r\n",iSortTexCnt);\r |
| | 258 | else strcat(szTxt,"\r\n\r\n");\r |
| | 259 | strcat(pB,szTxt);\r |
| | 260 | //----------------------------------------------------//\r |
| | 261 | sprintf(szTxt,"Framerate:\r\n- FPS limitation: %s\r\n",szO[bUseFrameLimit]);\r |
| | 262 | strcat(pB,szTxt);\r |
| | 263 | sprintf(szTxt,"- Frame skipping: %s\r\n",szO[bUseFrameSkip]);\r |
| | 264 | strcat(pB,szTxt);\r |
| | 265 | if(iFrameLimit==2)\r |
| | 266 | strcpy(szTxt,"- FPS limit: Auto\r\n\r\n");\r |
| | 267 | else sprintf(szTxt,"- FPS limit: %.1f\r\n\r\n",fFrameRate);\r |
| | 268 | strcat(pB,szTxt);\r |
| | 269 | //----------------------------------------------------//\r |
| | 270 | sprintf(szTxt,"Compatibility:\r\n- Offscreen drawing: %d\r\n",iOffscreenDrawing);\r |
| | 271 | strcat(pB,szTxt);\r |
| | 272 | sprintf(szTxt,"- Framebuffer texture: %d",iFrameTexType);\r |
| | 273 | if(!hW && iFrameTexType==2)\r |
| | 274 | {\r |
| | 275 | if(gTexFrameName) strcat(szTxt," - texture created\r\n");\r |
| | 276 | else strcat(szTxt," - not used yet\r\n");\r |
| | 277 | }\r |
| | 278 | else strcat(szTxt,"\r\n");\r |
| | 279 | strcat(pB,szTxt);\r |
| | 280 | sprintf(szTxt,"- Framebuffer access: %d\r\n",iFrameReadType);\r |
| | 281 | strcat(pB,szTxt);\r |
| | 282 | // sprintf(szTxt,"- Alpha multipass: %s\r\n",szO[bOpaquePass]);\r |
| | 283 | strcat(pB,szTxt);\r |
| | 284 | sprintf(szTxt,"- Mask bit: %s\r\n",szO[iUseMask]);\r |
| | 285 | strcat(pB,szTxt);\r |
| | 286 | //sprintf(szTxt,"- Advanced blending: %s",szO[bAdvancedBlend]);\r |
| | 287 | //if(!hW && bAdvancedBlend)\r |
| | 288 | // {\r |
| | 289 | // if(bGLBlend) strcat(szTxt," (hardware)\r\n");\r |
| | 290 | // else strcat(szTxt," (software)\r\n");\r |
| | 291 | // }\r |
| | 292 | strcat(szTxt,"\r\n");\r |
| | 293 | strcat(pB,szTxt);\r |
| | 294 | \r |
| | 295 | if(!hW)\r |
| | 296 | {\r |
| | 297 | strcpy(szTxt,"- Subtractive blending: ");\r |
| | 298 | // if(glBlendEquationEXTEx)\r |
| | 299 | // {\r |
| | 300 | // if(bUseMultiPass) strcat(szTxt,"supported, but not used!");\r |
| | 301 | // else strcat(szTxt,"activated");\r |
| | 302 | // }\r |
| | 303 | strcat(szTxt," NOT supported!");\r |
| | 304 | strcat(szTxt,"\r\n\r\n");\r |
| | 305 | }\r |
| | 306 | else strcpy(szTxt,"\r\n");\r |
| | 307 | \r |
| | 308 | strcat(pB,szTxt); \r |
| | 309 | //----------------------------------------------------//\r |
| | 310 | sprintf(szTxt,"Misc:\r\n- Scanlines: %s",szO[iUseScanLines]);\r |
| | 311 | strcat(pB,szTxt);\r |
| | 312 | if(iUseScanLines) sprintf(szTxt," [%d]\r\n",iScanBlend);\r |
| | 313 | else strcpy(szTxt,"\r\n");\r |
| | 314 | strcat(pB,szTxt);\r |
| | 315 | // sprintf(szTxt,"- Line mode: %s\r\n",szO[bUseLines]);\r |
| | 316 | strcat(pB,szTxt);\r |
| | 317 | // sprintf(szTxt,"- Line AA: %s\r\n",szO[bUseAntiAlias]);\r |
| | 318 | // fwrite(szTxt,lstrlen(szTxt),1,txtfile);\r |
| | 319 | sprintf(szTxt,"- Unfiltered FB: %s\r\n",szO[bUseFastMdec]);\r |
| | 320 | strcat(pB,szTxt);\r |
| | 321 | sprintf(szTxt,"- 15 bit FB: %s\r\n",szO[bUse15bitMdec]);\r |
| | 322 | strcat(pB,szTxt);\r |
| | 323 | sprintf(szTxt,"- Dithering: %s\r\n",szO[bDrawDither]);\r |
| | 324 | strcat(pB,szTxt);\r |
| | 325 | sprintf(szTxt,"- Screen smoothing: %s",szO[iBlurBuffer]);\r |
| | 326 | strcat(pB,szTxt);\r |
| | 327 | if(!hW && iBlurBuffer) \r |
| | 328 | {\r |
| | 329 | if(gTexBlurName) strcat(pB," - supported\r\n");\r |
| | 330 | else strcat(pB," - not supported\r\n");\r |
| | 331 | }\r |
| | 332 | else strcat(pB,"\r\n");\r |
| | 333 | sprintf(szTxt,"- Game fixes: %s [%08lx]\r\n",szO[bUseFixes],dwCfgFixes);\r |
| | 334 | strcat(pB,szTxt);\r |
| | 335 | //----------------------------------------------------//\r |
| | 336 | */ return pB;\r |
| | 337 | }\r |
| | 338 | \r |
| | 339 | ////////////////////////////////////////////////////////////////////////\r |
| | 340 | // save text infos to file\r |
| | 341 | ////////////////////////////////////////////////////////////////////////\r |
| | 342 | \r |
| | 343 | void DoTextSnapShot(int iNum)\r |
| | 344 | {\r |
| | 345 | }\r |
| | 346 | \r |
| | 347 | ////////////////////////////////////////////////////////////////////////\r |
| | 348 | // saves screen bitmap to file\r |
| | 349 | ////////////////////////////////////////////////////////////////////////\r |
| | 350 | \r |
| | 351 | void DoSnapShot(void)\r |
| | 352 | {\r |
| | 353 | } \r |
| | 354 | \r |
| | 355 | void CALLBACK GPUmakeSnapshot(void)\r |
| | 356 | {\r |
| | 357 | //bSnapShot = TRUE;\r |
| | 358 | } \r |
| | 359 | \r |
| | 360 | ////////////////////////////////////////////////////////////////////////\r |
| | 361 | // GPU INIT... here starts it all (first func called by emu)\r |
| | 362 | ////////////////////////////////////////////////////////////////////////\r |
| | 363 | \r |
| | 364 | long CALLBACK GPUinit()\r |
| | 365 | {\r |
| | 366 | memset(ulStatusControl,0,256*sizeof(unsigned long));\r |
| | 367 | \r |
| | 368 | bChangeRes=FALSE;\r |
| | 369 | bWindowMode=FALSE;\r |
| | 370 | \r |
| | 371 | bKeepRatio = TRUE;\r |
| | 372 | // different ways of accessing PSX VRAM\r |
| | 373 | \r |
| | 374 | psxVSecure=(unsigned char *)malloc((iGPUHeight*2)*1024 + (1024*1024)); // always alloc one extra MB for soft drawing funcs security\r |
| | 375 | if(!psxVSecure) return -1;\r |
| | 376 | \r |
| | 377 | psxVub=psxVSecure+512*1024; // security offset into double sized psx vram!\r |
| | 378 | psxVsb=(signed char *)psxVub;\r |
| | 379 | psxVsw=(signed short *)psxVub;\r |
| | 380 | psxVsl=(signed long *)psxVub;\r |
| | 381 | psxVuw=(unsigned short *)psxVub;\r |
| | 382 | psxVul=(unsigned long *)psxVub;\r |
| | 383 | \r |
| | 384 | psxVuw_eom=psxVuw+1024*iGPUHeight; // pre-calc of end of vram\r |
| | 385 | \r |
| | 386 | memset(psxVSecure,0x00,(iGPUHeight*2)*1024 + (1024*1024));\r |
| | 387 | memset(ulGPUInfoVals,0x00,16*sizeof(unsigned long));\r |
| | 388 | \r |
| | 389 | InitFrameCap(); // init frame rate stuff\r |
| | 390 | \r |
| | 391 | PSXDisplay.RGB24 = 0; // init vars\r |
| | 392 | PreviousPSXDisplay.RGB24= 0;\r |
| | 393 | PSXDisplay.Interlaced = 0;\r |
| | 394 | PSXDisplay.InterlacedTest=0;\r |
| | 395 | PSXDisplay.DrawOffset.x = 0;\r |
| | 396 | PSXDisplay.DrawOffset.y = 0;\r |
| | 397 | PSXDisplay.DrawArea.x0 = 0;\r |
| | 398 | PSXDisplay.DrawArea.y0 = 0;\r |
| | 399 | PSXDisplay.DrawArea.x1 = 320;\r |
| | 400 | PSXDisplay.DrawArea.y1 = 240;\r |
| | 401 | PSXDisplay.DisplayMode.x= 320;\r |
| | 402 | PSXDisplay.DisplayMode.y= 240;\r |
| | 403 | PSXDisplay.Disabled = FALSE;\r |
| | 404 | PreviousPSXDisplay.Range.x0 =0;\r |
| | 405 | PreviousPSXDisplay.Range.x1 =0;\r |
| | 406 | PreviousPSXDisplay.Range.y0 =0;\r |
| | 407 | PreviousPSXDisplay.Range.y1 =0;\r |
| | 408 | PSXDisplay.Range.x0=0;\r |
| | 409 | PSXDisplay.Range.x1=0;\r |
| | 410 | PSXDisplay.Range.y0=0;\r |
| | 411 | PSXDisplay.Range.y1=0;\r |
| | 412 | PreviousPSXDisplay.DisplayPosition.x = 1;\r |
| | 413 | PreviousPSXDisplay.DisplayPosition.y = 1;\r |
| | 414 | PSXDisplay.DisplayPosition.x = 1;\r |
| | 415 | PSXDisplay.DisplayPosition.y = 1;\r |
| | 416 | PreviousPSXDisplay.DisplayModeNew.y=0;\r |
| | 417 | PSXDisplay.Double=1;\r |
| | 418 | GPUdataRet=0x400;\r |
| | 419 | \r |
| | 420 | PSXDisplay.DisplayModeNew.x=0;\r |
| | 421 | PSXDisplay.DisplayModeNew.y=0;\r |
| | 422 | \r |
| | 423 | //PreviousPSXDisplay.Height = PSXDisplay.Height = 239;\r |
| | 424 | \r |
| | 425 | iDataWriteMode = DR_NORMAL;\r |
| | 426 | \r |
| | 427 | // Reset transfer values, to prevent mis-transfer of data\r |
| | 428 | memset(&VRAMWrite,0,sizeof(VRAMLoad_t));\r |
| | 429 | memset(&VRAMRead,0,sizeof(VRAMLoad_t));\r |
| | 430 | \r |
| | 431 | // device initialised already !\r |
| | 432 | //lGPUstatusRet = 0x74000000;\r |
| | 433 | \r |
| | 434 | STATUSREG = 0x14802000;\r |
| | 435 | GPUIsIdle;\r |
| | 436 | GPUIsReadyForCommands;\r |
| | 437 | \r |
| | 438 | return 0;\r |
| | 439 | } \r |
| | 440 | \r |
| | 441 | \r |
| | 442 | ////////////////////////////////////////////////////////////////////////\r |
| | 443 | // OPEN interface func: attention! \r |
| | 444 | // some emus are calling this func in their main Window thread,\r |
| | 445 | // but all other interface funcs (to draw stuff) in a different thread!\r |
| | 446 | // that's a problem, since OGL is thread safe! Therefore we cannot \r |
| | 447 | // initialize the OGL stuff right here, we simply set a "bIsFirstFrame = TRUE"\r |
| | 448 | // flag, to initialize OGL on the first real draw call.\r |
| | 449 | // btw, we also call this open func ourselfes, each time when the user \r |
| | 450 | // is changing between fullscreen/window mode (ENTER key)\r |
| | 451 | // btw part 2: in windows the plugin gets the window handle from the\r |
| | 452 | // main emu, and doesn't create it's own window (if it would do it,\r |
| | 453 | // some PAD or SPU plugins would not work anymore)\r |
| | 454 | ////////////////////////////////////////////////////////////////////////\r |
| | 455 | \r |
| | 456 | long CALLBACK GPUopen(unsigned long *disp, char *cap, char *cfg)\r |
| | 457 | {\r |
| | 458 | iResX=800;iResY=480;\r |
| | 459 | iColDepth=8;\r |
| | 460 | bChangeRes=FALSE;\r |
| | 461 | bWindowMode=FALSE;\r |
| | 462 | bFullVRam=FALSE;\r |
| | 463 | iFilterType=0;\r |
| | 464 | // bAdvancedBlend=FALSE;\r |
| | 465 | bDrawDither=FALSE;\r |
| | 466 | // bUseLines=FALSE;\r |
| | 467 | bUseFrameLimit=FALSE;\r |
| | 468 | bUseFrameSkip=FALSE;\r |
| | 469 | iFrameLimit=0;\r |
| | 470 | fFrameRate=50.0f;\r |
| | 471 | iOffscreenDrawing=0;\r |
| | 472 | //bOpaquePass=FALSE;\r |
| | 473 | //bUseAntiAlias=FALSE;\r |
| | 474 | //iTexQuality=0;\r |
| | 475 | iUseMask=0;\r |
| | 476 | iZBufferDepth=0;\r |
| | 477 | bUseFastMdec=FALSE;\r |
| | 478 | bUse15bitMdec=FALSE;\r |
| | 479 | dwCfgFixes=0;\r |
| | 480 | bUseFixes=FALSE;\r |
| | 481 | // iUseScanLines=0;\r |
| | 482 | iFrameTexType=0;\r |
| | 483 | iFrameReadType=0;\r |
| | 484 | //iShowFPS=0;\r |
| | 485 | bKeepRatio=TRUE;\r |
| | 486 | iScanBlend=0;\r |
| | 487 | iVRamSize=0;\r |
| | 488 | iTexGarbageCollection=0;\r |
| | 489 | iBlurBuffer=0; \r |
| | 490 | //iHiResTextures=0;\r |
| | 491 | iNoScreenSaver=0;\r |
| | 492 | //iForceVSync=0;\r |
| | 493 | \r |
| | 494 | \r |
| | 495 | \r |
| | 496 | bIsFirstFrame = TRUE; // flag: we have to init OGL later in windows!\r |
| | 497 | \r |
| | 498 | rRatioRect.left = rRatioRect.top=0;\r |
| | 499 | rRatioRect.right = iResX;\r |
| | 500 | rRatioRect.bottom = iResY;\r |
| | 501 | \r |
| | 502 | bDisplayNotSet = TRUE; \r |
| | 503 | bSetClip=TRUE;\r |
| | 504 | \r |
| | 505 | SetFixes(); // setup game fixes\r |
| | 506 | \r |
| | 507 | InitializeTextureStore(); // init texture mem\r |
| | 508 | \r |
| | 509 | CSTEXTURE = CSVERTEX = CSCOLOR = 0;\r |
| | 510 | \r |
| | 511 | // lGPUstatusRet = 0x74000000;\r |
| | 512 | \r |
| | 513 | // with some emus, we could do the OGL init right here... oh my\r |
| | 514 | if(bIsFirstFrame) GLinitialize(NULL, NULL);\r |
| | 515 | \r |
| | 516 | return 0;\r |
| | 517 | }\r |
| | 518 | \r |
| | 519 | ////////////////////////////////////////////////////////////////////////\r |
| | 520 | // close\r |
| | 521 | ////////////////////////////////////////////////////////////////////////\r |
| | 522 | \r |
| | 523 | \r |
| | 524 | long GPUclose() // LINUX CLOSE\r |
| | 525 | {\r |
| | 526 | GLcleanup(); // close OGL\r |
| | 527 | \r |
| | 528 | if(pGfxCardScreen) free(pGfxCardScreen); // free helper memory\r |
| | 529 | pGfxCardScreen=0;\r |
| | 530 | \r |
| | 531 | // osd_close_display(); // destroy display\r |
| | 532 | \r |
| | 533 | return 0;\r |
| | 534 | }\r |
| | 535 | \r |
| | 536 | ////////////////////////////////////////////////////////////////////////\r |
| | 537 | // I shot the sheriff... last function called from emu \r |
| | 538 | ////////////////////////////////////////////////////////////////////////\r |
| | 539 | \r |
| | 540 | long CALLBACK GPUshutdown()\r |
| | 541 | {\r |
| | 542 | if(psxVSecure) free(psxVSecure); // kill emulated vram memory\r |
| | 543 | psxVSecure=0;\r |
| | 544 | \r |
| | 545 | return 0;\r |
| | 546 | }\r |
| | 547 | \r |
| | 548 | ////////////////////////////////////////////////////////////////////////\r |
| | 549 | // paint it black: simple func to clean up optical border garbage\r |
| | 550 | ////////////////////////////////////////////////////////////////////////\r |
| | 551 | \r |
| | 552 | void PaintBlackBorders(void)\r |
| | 553 | {\r |
| | 554 | short s;\r |
| | 555 | glDisable(GL_SCISSOR_TEST); glError();\r |
| | 556 | if(bTexEnabled) {glDisable(GL_TEXTURE_2D);bTexEnabled=FALSE;} glError();\r |
| | 557 | if(bOldSmoothShaded) {glShadeModel(GL_FLAT);bOldSmoothShaded=FALSE;} glError();\r |
| | 558 | if(bBlendEnable) {glDisable(GL_BLEND);bBlendEnable=FALSE;} glError();\r |
| | 559 | glDisable(GL_ALPHA_TEST); glError();\r |
| | 560 | \r |
| | 561 | glEnable(GL_ALPHA_TEST); glError();\r |
| | 562 | glEnable(GL_SCISSOR_TEST); glError();\r |
| | 563 | \r |
| | 564 | }\r |
| | 565 | \r |
| | 566 | ////////////////////////////////////////////////////////////////////////\r |
| | 567 | // helper to draw scanlines\r |
| | 568 | ////////////////////////////////////////////////////////////////////////\r |
| | 569 | \r |
| | 570 | __inline void XPRIMdrawTexturedQuad(OGLVertex* vertex1, OGLVertex* vertex2, \r |
| | 571 | OGLVertex* vertex3, OGLVertex* vertex4) \r |
| | 572 | {\r |
| | 573 | \r |
| | 574 | }\r |
| | 575 | \r |
| | 576 | ////////////////////////////////////////////////////////////////////////\r |
| | 577 | // scanlines\r |
| | 578 | ////////////////////////////////////////////////////////////////////////\r |
| | 579 | \r |
| | 580 | void SetScanLines(void)\r |
| | 581 | {\r |
| | 582 | }\r |
| | 583 | \r |
| | 584 | ////////////////////////////////////////////////////////////////////////\r |
| | 585 | // blur, babe, blur (heavy performance hit for a so-so fullscreen effect)\r |
| | 586 | ////////////////////////////////////////////////////////////////////////\r |
| | 587 | \r |
| | 588 | \r |
| | 589 | ////////////////////////////////////////////////////////////////////////\r |
| | 590 | // Update display (swap buffers)... called in interlaced mode on \r |
| | 591 | // every emulated vsync, otherwise whenever the displayed screen region\r |
| | 592 | // has been changed\r |
| | 593 | ////////////////////////////////////////////////////////////////////////\r |
| | 594 | \r |
| | 595 | int iLastRGB24=0; // special vars for checking when to skip two display updates\r |
| | 596 | int iSkipTwo=0;\r |
| | 597 | void GPUvSinc(void){\r |
| | 598 | updateDisplay();\r |
| | 599 | }\r |
| | 600 | void updateDisplay(void) // UPDATE DISPLAY\r |
| | 601 | {\r |
| | 602 | BOOL bBlur=FALSE;\r |
| | 603 | \r |
| | 604 | \r |
| | 605 | bFakeFrontBuffer=FALSE;\r |
| | 606 | bRenderFrontBuffer=FALSE;\r |
| | 607 | \r |
| | 608 | if(iRenderFVR) // frame buffer read fix mode still active?\r |
| | 609 | {\r |
| | 610 | iRenderFVR--; // -> if some frames in a row without read access: turn off mode\r |
| | 611 | if(!iRenderFVR) bFullVRam=FALSE;\r |
| | 612 | }\r |
| | 613 | \r |
| | 614 | if(iLastRGB24 && iLastRGB24!=PSXDisplay.RGB24+1) // (mdec) garbage check\r |
| | 615 | {\r |
| | 616 | iSkipTwo=2; // -> skip two frames to avoid garbage if color mode changes\r |
| | 617 | }\r |
| | 618 | iLastRGB24=0;\r |
| | 619 | \r |
| | 620 | if(PSXDisplay.RGB24)// && !bNeedUploadAfter) // (mdec) upload wanted?\r |
| | 621 | {\r |
| | 622 | PrepareFullScreenUpload(-1);\r |
| | 623 | UploadScreen(PSXDisplay.Interlaced); // -> upload whole screen from psx vram\r |
| | 624 | bNeedUploadTest=FALSE;\r |
| | 625 | bNeedInterlaceUpdate=FALSE;\r |
| | 626 | bNeedUploadAfter=FALSE;\r |
| | 627 | bNeedRGB24Update=FALSE;\r |
| | 628 | }\r |
| | 629 | else\r |
| | 630 | if(bNeedInterlaceUpdate) // smaller upload?\r |
| | 631 | {\r |
| | 632 | bNeedInterlaceUpdate=FALSE;\r |
| | 633 | xrUploadArea=xrUploadAreaIL; // -> upload this rect\r |
| | 634 | UploadScreen(TRUE);\r |
| | 635 | }\r |
| | 636 | \r |
| | 637 | if(dwActFixes&512) bCheckFF9G4(NULL); // special game fix for FF9 \r |
| | 638 | \r |
| | 639 | if(PreviousPSXDisplay.Range.x0|| // paint black borders around display area, if needed\r |
| | 640 | PreviousPSXDisplay.Range.y0)\r |
| | 641 | PaintBlackBorders();\r |
| | 642 | \r |
| | 643 | if(PSXDisplay.Disabled) // display disabled?\r |
| | 644 | {\r |
| | 645 | //LOGE("PSXDisplay.Disabled");\r |
| | 646 | \r |
| | 647 | // moved here\r |
| | 648 | glDisable(GL_SCISSOR_TEST); glError(); \r |
| | 649 | glClearColor(0,0,0,128); glError(); // -> clear whole backbuffer\r |
| | 650 | glClear(uiBufferBits); glError();\r |
| | 651 | glEnable(GL_SCISSOR_TEST); glError(); \r |
| | 652 | gl_z=0.0f;\r |
| | 653 | bDisplayNotSet = TRUE;\r |
| | 654 | }\r |
| | 655 | \r |
| | 656 | if(iSkipTwo) // we are in skipping mood?\r |
| | 657 | {\r |
| | 658 | iSkipTwo--;\r |
| | 659 | iDrawnSomething=0; // -> simply lie about something drawn\r |
| | 660 | }\r |
| | 661 | \r |
| | 662 | //if(iBlurBuffer && !bSkipNextFrame) // "blur display" activated?\r |
| | 663 | // {BlurBackBuffer();bBlur=TRUE;} // -> blur it\r |
| | 664 | \r |
| | 665 | // if(iUseScanLines) SetScanLines(); // "scan lines" activated? do it\r |
| | 666 | \r |
| | 667 | // if(usCursorActive) ShowGunCursor(); // "gun cursor" wanted? show 'em\r |
| | 668 | \r |
| | 669 | if(dwActFixes&128) // special FPS limitation mode?\r |
| | 670 | {\r |
| | 671 | if(bUseFrameLimit) PCFrameCap(); // -> ok, do it\r |
| | 672 | // if(bUseFrameSkip || ulKeybits&KEY_SHOWFPS) \r |
| | 673 | PCcalcfps(); \r |
| | 674 | }\r |
| | 675 | \r |
| | 676 | // if(gTexPicName) DisplayPic(); // some gpu info picture active? display it\r |
| | 677 | \r |
| | 678 | // if(bSnapShot) DoSnapShot(); // snapshot key pressed? cheeeese :)\r |
| | 679 | \r |
| | 680 | // if(ulKeybits&KEY_SHOWFPS) // wanna see FPS?\r |
| | 681 | {\r |
| | 682 | // sprintf(szDispBuf,"%06.1f",fps_cur);\r |
| | 683 | // DisplayText(); // -> show it\r |
| | 684 | }\r |
| | 685 | \r |
| | 686 | //----------------------------------------------------//\r |
| | 687 | // main buffer swapping (well, or skip it)\r |
| | 688 | \r |
| | 689 | if(bUseFrameSkip) // frame skipping active ?\r |
| | 690 | {\r |
| | 691 | if(!bSkipNextFrame) \r |
| | 692 | {\r |
| | 693 | if(iDrawnSomething) flipEGL();\r |
| | 694 | }\r |
| | 695 | if((fps_skip < fFrameRateHz) && !(bSkipNextFrame)) \r |
| | 696 | {bSkipNextFrame = TRUE; fps_skip=fFrameRateHz;}\r |
| | 697 | else bSkipNextFrame = FALSE;\r |
| | 698 | \r |
| | 699 | }\r |
| | 700 | else // no skip ?\r |
| | 701 | {\r |
| | 702 | if(iDrawnSomething) flipEGL();\r |
| | 703 | }\r |
| | 704 | \r |
| | 705 | iDrawnSomething=0;\r |
| | 706 | \r |
| | 707 | //----------------------------------------------------//\r |
| | 708 | \r |
| | 709 | if(lClearOnSwap) // clear buffer after swap?\r |
| | 710 | {\r |
| | 711 | GLclampf g,b,r;\r |
| | 712 | \r |
| | 713 | if(bDisplayNotSet) // -> set new vals\r |
| | 714 | SetOGLDisplaySettings(1);\r |
| | 715 | \r |
| | 716 | g=((GLclampf)GREEN(lClearOnSwapColor))/255.0f; // -> get col\r |
| | 717 | b=((GLclampf)BLUE(lClearOnSwapColor))/255.0f;\r |
| | 718 | r=((GLclampf)RED(lClearOnSwapColor))/255.0f;\r |
| | 719 | glDisable(GL_SCISSOR_TEST); glError(); \r |
| | 720 | glClearColor(r,g,b,128); glError(); // -> clear \r |
| | 721 | glClear(uiBufferBits); glError();\r |
| | 722 | glEnable(GL_SCISSOR_TEST); glError(); \r |
| | 723 | lClearOnSwap=0; // -> done\r |
| | 724 | }\r |
| | 725 | else \r |
| | 726 | {\r |
| | 727 | // if(bBlur) UnBlurBackBuffer(); // unblur buff, if blurred before\r |
| | 728 | \r |
| | 729 | if(iZBufferDepth) // clear zbuffer as well (if activated)\r |
| | 730 | {\r |
| | 731 | glDisable(GL_SCISSOR_TEST); glError();\r |
| | 732 | glClear(GL_DEPTH_BUFFER_BIT); glError();\r |
| | 733 | glEnable(GL_SCISSOR_TEST); glError();\r |
| | 734 | }\r |
| | 735 | }\r |
| | 736 | \r |
| | 737 | gl_z=0.0f;\r |
| | 738 | \r |
| | 739 | //----------------------------------------------------//\r |
| | 740 | // additional uploads immediatly after swapping\r |
| | 741 | \r |
| | 742 | if(bNeedUploadAfter) // upload wanted?\r |
| | 743 | {\r |
| | 744 | bNeedUploadAfter=FALSE; \r |
| | 745 | bNeedUploadTest=FALSE;\r |
| | 746 | UploadScreen(-1); // -> upload\r |
| | 747 | }\r |
| | 748 | \r |
| | 749 | if(bNeedUploadTest)\r |
| | 750 | {\r |
| | 751 | bNeedUploadTest=FALSE;\r |
| | 752 | if(PSXDisplay.InterlacedTest &&\r |
| | 753 | //iOffscreenDrawing>2 &&\r |
| | 754 | PreviousPSXDisplay.DisplayPosition.x==PSXDisplay.DisplayPosition.x &&\r |
| | 755 | PreviousPSXDisplay.DisplayEnd.x==PSXDisplay.DisplayEnd.x &&\r |
| | 756 | PreviousPSXDisplay.DisplayPosition.y==PSXDisplay.DisplayPosition.y &&\r |
| | 757 | PreviousPSXDisplay.DisplayEnd.y==PSXDisplay.DisplayEnd.y)\r |
| | 758 | {\r |
| | 759 | PrepareFullScreenUpload(TRUE);\r |
| | 760 | UploadScreen(TRUE);\r |
| | 761 | }\r |
| | 762 | }\r |
| | 763 | \r |
| | 764 | //----------------------------------------------------//\r |
| | 765 | // rumbling (main emu pad effect)\r |
| | 766 | \r |
| | 767 | if(iRumbleTime) // shake screen by modifying view port\r |
| | 768 | {\r |
| | 769 | int i1=0,i2=0,i3=0,i4=0;\r |
| | 770 | \r |
| | 771 | iRumbleTime--;\r |
| | 772 | if(iRumbleTime) \r |
| | 773 | {\r |
| | 774 | i1=((rand()*iRumbleVal)/RAND_MAX)-(iRumbleVal/2); \r |
| | 775 | i2=((rand()*iRumbleVal)/RAND_MAX)-(iRumbleVal/2); \r |
| | 776 | i3=((rand()*iRumbleVal)/RAND_MAX)-(iRumbleVal/2); \r |
| | 777 | i4=((rand()*iRumbleVal)/RAND_MAX)-(iRumbleVal/2); \r |
| | 778 | }\r |
| | 779 | \r |
| | 780 | glViewport(rRatioRect.left+i1, \r |
| | 781 | iResY-(rRatioRect.top+rRatioRect.bottom)+i2,\r |
| | 782 | rRatioRect.right+i3, \r |
| | 783 | rRatioRect.bottom+i4); glError();\r |
| | 784 | }\r |
| | 785 | \r |
| | 786 | //----------------------------------------------------//\r |
| | 787 | \r |
| | 788 | \r |
| | 789 | \r |
| | 790 | // if(ulKeybits&KEY_RESETTEXSTORE) ResetStuff(); // reset on gpu mode changes? do it before next frame is filled\r |
| | 791 | }\r |
| | 792 | \r |
| | 793 | ////////////////////////////////////////////////////////////////////////\r |
| | 794 | // update front display: smaller update func, if something has changed \r |
| | 795 | // in the frontbuffer... dirty, but hey... real men know no pain\r |
| | 796 | ////////////////////////////////////////////////////////////////////////\r |
| | 797 | \r |
| | 798 | void updateFrontDisplay(void)\r |
| | 799 | {\r |
| | 800 | if(PreviousPSXDisplay.Range.x0||\r |
| | 801 | PreviousPSXDisplay.Range.y0)\r |
| | 802 | PaintBlackBorders();\r |
| | 803 | \r |
| | 804 | //if(iBlurBuffer) BlurBackBuffer();\r |
| | 805 | \r |
| | 806 | //if(iUseScanLines) SetScanLines();\r |
| | 807 | \r |
| | 808 | // if(usCursorActive) ShowGunCursor();\r |
| | 809 | \r |
| | 810 | bFakeFrontBuffer=FALSE;\r |
| | 811 | bRenderFrontBuffer=FALSE;\r |
| | 812 | \r |
| | 813 | // if(gTexPicName) DisplayPic();\r |
| | 814 | // if(ulKeybits&KEY_SHOWFPS) DisplayText();\r |
| | 815 | \r |
| | 816 | if(iDrawnSomething) // linux:\r |
| | 817 | flipEGL();\r |
| | 818 | \r |
| | 819 | \r |
| | 820 | //if(iBlurBuffer) UnBlurBackBuffer();\r |
| | 821 | }\r |
| | 822 | \r |
| | 823 | ////////////////////////////////////////////////////////////////////////\r |
| | 824 | // check if update needed\r |
| | 825 | ////////////////////////////////////////////////////////////////////////\r |
| | 826 | void ChangeDispOffsetsX(void) // CENTER X\r |
| | 827 | {\r |
| | 828 | long lx,l;short sO;\r |
| | 829 | \r |
| | 830 | if(!PSXDisplay.Range.x1) return; // some range given?\r |
| | 831 | \r |
| | 832 | l=PSXDisplay.DisplayMode.x;\r |
| | 833 | \r |
| | 834 | l*=(long)PSXDisplay.Range.x1; // some funky calculation\r |
| | 835 | l/=2560;lx=l;l&=0xfffffff8;\r |
| | 836 | \r |
| | 837 | if(l==PreviousPSXDisplay.Range.x1) return; // some change?\r |
| | 838 | \r |
| | 839 | sO=PreviousPSXDisplay.Range.x0; // store old\r |
| | 840 | \r |
| | 841 | if(lx>=PSXDisplay.DisplayMode.x) // range bigger?\r |
| | 842 | {\r |
| | 843 | PreviousPSXDisplay.Range.x1= // -> take display width\r |
| | 844 | PSXDisplay.DisplayMode.x;\r |
| | 845 | PreviousPSXDisplay.Range.x0=0; // -> start pos is 0\r |
| | 846 | }\r |
| | 847 | else // range smaller? center it\r |
| | 848 | {\r |
| | 849 | PreviousPSXDisplay.Range.x1=l; // -> store width (8 pixel aligned)\r |
| | 850 | PreviousPSXDisplay.Range.x0= // -> calc start pos\r |
| | 851 | (PSXDisplay.Range.x0-500)/8;\r |
| | 852 | if(PreviousPSXDisplay.Range.x0<0) // -> we don't support neg. values yet\r |
| | 853 | PreviousPSXDisplay.Range.x0=0;\r |
| | 854 | \r |
| | 855 | if((PreviousPSXDisplay.Range.x0+lx)> // -> uhuu... that's too much\r |
| | 856 | PSXDisplay.DisplayMode.x)\r |
| | 857 | {\r |
| | 858 | PreviousPSXDisplay.Range.x0= // -> adjust start\r |
| | 859 | PSXDisplay.DisplayMode.x-lx;\r |
| | 860 | PreviousPSXDisplay.Range.x1+=lx-l; // -> adjust width\r |
| | 861 | } \r |
| | 862 | }\r |
| | 863 | \r |
| | 864 | if(sO!=PreviousPSXDisplay.Range.x0) // something changed?\r |
| | 865 | {\r |
| | 866 | bDisplayNotSet=TRUE; // -> recalc display stuff\r |
| | 867 | }\r |
| | 868 | }\r |
| | 869 | \r |
| | 870 | ////////////////////////////////////////////////////////////////////////\r |
| | 871 | \r |
| | 872 | void ChangeDispOffsetsY(void) // CENTER Y\r |
| | 873 | {\r |
| | 874 | int iT;short sO; // store previous y size\r |
| | 875 | \r |
| | 876 | if(PSXDisplay.PAL) iT=48; else iT=28; // different offsets on PAL/NTSC\r |
| | 877 | \r |
| | 878 | if(PSXDisplay.Range.y0>=iT) // crossed the security line? :)\r |
| | 879 | {\r |
| | 880 | PreviousPSXDisplay.Range.y1= // -> store width\r |
| | 881 | PSXDisplay.DisplayModeNew.y;\r |
| | 882 | \r |
| | 883 | sO=(PSXDisplay.Range.y0-iT-4)*PSXDisplay.Double; // -> calc offset\r |
| | 884 | if(sO<0) sO=0;\r |
| | 885 | \r |
| | 886 | PSXDisplay.DisplayModeNew.y+=sO; // -> add offset to y size, too\r |
| | 887 | }\r |
| | 888 | else sO=0; // else no offset\r |
| | 889 | \r |
| | 890 | if(sO!=PreviousPSXDisplay.Range.y0) // something changed?\r |
| | 891 | {\r |
| | 892 | PreviousPSXDisplay.Range.y0=sO;\r |
| | 893 | bDisplayNotSet=TRUE; // -> recalc display stuff\r |
| | 894 | }\r |
| | 895 | }\r |
| | 896 | \r |
| | 897 | ////////////////////////////////////////////////////////////////////////\r |
| | 898 | // Aspect ratio of ogl screen: simply adjusting ogl view port\r |
| | 899 | ////////////////////////////////////////////////////////////////////////\r |
| | 900 | \r |
| | 901 | void SetAspectRatio(void)\r |
| | 902 | {\r |
| | 903 | float xs,ys,s;RECT r;\r |
| | 904 | \r |
| | 905 | if(!PSXDisplay.DisplayModeNew.x) return;\r |
| | 906 | if(!PSXDisplay.DisplayModeNew.y) return;\r |
| | 907 | \r |
| | 908 | #if 0\r |
| | 909 | xs=(float)iResX/(float)PSXDisplay.DisplayModeNew.x;\r |
| | 910 | ys=(float)iResY/(float)PSXDisplay.DisplayModeNew.y;\r |
| | 911 | \r |
| | 912 | s=min(xs,ys);\r |
| | 913 | r.right =(int)((float)PSXDisplay.DisplayModeNew.x*s);\r |
| | 914 | r.bottom=(int)((float)PSXDisplay.DisplayModeNew.y*s);\r |
| | 915 | if(r.right > iResX) r.right = iResX;\r |
| | 916 | if(r.bottom > iResY) r.bottom = iResY;\r |
| | 917 | if(r.right < 1) r.right = 1;\r |
| | 918 | if(r.bottom < 1) r.bottom = 1;\r |
| | 919 | \r |
| | 920 | r.left = (iResX-r.right)/2;\r |
| | 921 | r.top = (iResY-r.bottom)/2;\r |
| | 922 | if(r.bottom<rRatioRect.bottom ||\r |
| | 923 | r.right <rRatioRect.right)\r |
| | 924 | {\r |
| | 925 | RECT rC;\r |
| | 926 | glClearColor(0,0,0,128); glError();\r |
| | 927 | \r |
| | 928 | if(r.right <rRatioRect.right)\r |
| | 929 | {\r |
| | 930 | rC.left=0;\r |
| | 931 | rC.top=0;\r |
| | 932 | rC.right=r.left;\r |
| | 933 | rC.bottom=iResY;\r |
| | 934 | glScissor(rC.left,rC.top,rC.right,rC.bottom); glError();\r |
| | 935 | glClear(uiBufferBits); glError();\r |
| | 936 | rC.left=iResX-rC.right;\r |
| | 937 | glScissor(rC.left,rC.top,rC.right,rC.bottom); glError();\r |
| | 938 | \r |
| | 939 | glClear(uiBufferBits); glError();\r |
| | 940 | }\r |
| | 941 | \r |
| | 942 | if(r.bottom <rRatioRect.bottom)\r |
| | 943 | {\r |
| | 944 | rC.left=0;\r |
| | 945 | rC.top=0;\r |
| | 946 | rC.right=iResX;\r |
| | 947 | rC.bottom=r.top;\r |
| | 948 | glScissor(rC.left,rC.top,rC.right,rC.bottom); glError();\r |
| | 949 | \r |
| | 950 | glClear(uiBufferBits); glError();\r |
| | 951 | rC.top=iResY-rC.bottom;\r |
| | 952 | glScissor(rC.left,rC.top,rC.right,rC.bottom); glError();\r |
| | 953 | glClear(uiBufferBits); glError();\r |
| | 954 | }\r |
| | 955 | \r |
| | 956 | bSetClip=TRUE;\r |
| | 957 | bDisplayNotSet=TRUE;\r |
| | 958 | }\r |
| | 959 | \r |
| | 960 | rRatioRect=r;\r |
| | 961 | #else\r |
| | 962 | // pcsx-rearmed hack\r |
| | 963 | if (rearmed_get_layer_pos != NULL)\r |
| | 964 | rearmed_get_layer_pos(&rRatioRect.left, &rRatioRect.top, &rRatioRect.right, &rRatioRect.bottom);\r |
| | 965 | #endif\r |
| | 966 | \r |
| | 967 | glViewport(rRatioRect.left,\r |
| | 968 | iResY-(rRatioRect.top+rRatioRect.bottom),\r |
| | 969 | rRatioRect.right,\r |
| | 970 | rRatioRect.bottom); glError(); // init viewport\r |
| | 971 | }\r |
| | 972 | \r |
| | 973 | ////////////////////////////////////////////////////////////////////////\r |
| | 974 | // big ass check, if an ogl swap buffer is needed\r |
| | 975 | ////////////////////////////////////////////////////////////////////////\r |
| | 976 | \r |
| | 977 | void updateDisplayIfChanged(void)\r |
| | 978 | {\r |
| | 979 | BOOL bUp;\r |
| | 980 | \r |
| | 981 | if ((PSXDisplay.DisplayMode.y == PSXDisplay.DisplayModeNew.y) && \r |
| | 982 | (PSXDisplay.DisplayMode.x == PSXDisplay.DisplayModeNew.x))\r |
| | 983 | {\r |
| | 984 | if((PSXDisplay.RGB24 == PSXDisplay.RGB24New) && \r |
| | 985 | (PSXDisplay.Interlaced == PSXDisplay.InterlacedNew)) \r |
| | 986 | return; // nothing has changed? fine, no swap buffer needed\r |
| | 987 | }\r |
| | 988 | else // some res change?\r |
| | 989 | {\r |
| | 990 | glLoadIdentity(); glError();\r |
| | 991 | glOrtho(0,PSXDisplay.DisplayModeNew.x, // -> new psx resolution\r |
| | 992 | PSXDisplay.DisplayModeNew.y, 0, -1, 1); glError();\r |
| | 993 | if(bKeepRatio) SetAspectRatio();\r |
| | 994 | }\r |
| | 995 | \r |
| | 996 | bDisplayNotSet = TRUE; // re-calc offsets/display area\r |
| | 997 | \r |
| | 998 | bUp=FALSE;\r |
| | 999 | if(PSXDisplay.RGB24!=PSXDisplay.RGB24New) // clean up textures, if rgb mode change (usually mdec on/off)\r |
| | 1000 | {\r |
| | 1001 | PreviousPSXDisplay.RGB24=0; // no full 24 frame uploaded yet\r |
| | 1002 | ResetTextureArea(FALSE);\r |
| | 1003 | bUp=TRUE;\r |
| | 1004 | }\r |
| | 1005 | \r |
| | 1006 | PSXDisplay.RGB24 = PSXDisplay.RGB24New; // get new infos\r |
| | 1007 | PSXDisplay.DisplayMode.y = PSXDisplay.DisplayModeNew.y;\r |
| | 1008 | PSXDisplay.DisplayMode.x = PSXDisplay.DisplayModeNew.x;\r |
| | 1009 | PSXDisplay.Interlaced = PSXDisplay.InterlacedNew;\r |
| | 1010 | \r |
| | 1011 | PSXDisplay.DisplayEnd.x= // calc new ends\r |
| | 1012 | PSXDisplay.DisplayPosition.x+ PSXDisplay.DisplayMode.x;\r |
| | 1013 | PSXDisplay.DisplayEnd.y=\r |
| | 1014 | PSXDisplay.DisplayPosition.y+ PSXDisplay.DisplayMode.y+PreviousPSXDisplay.DisplayModeNew.y;\r |
| | 1015 | PreviousPSXDisplay.DisplayEnd.x=\r |
| | 1016 | PreviousPSXDisplay.DisplayPosition.x+ PSXDisplay.DisplayMode.x;\r |
| | 1017 | PreviousPSXDisplay.DisplayEnd.y=\r |
| | 1018 | PreviousPSXDisplay.DisplayPosition.y+ PSXDisplay.DisplayMode.y+PreviousPSXDisplay.DisplayModeNew.y;\r |
| | 1019 | \r |
| | 1020 | ChangeDispOffsetsX();\r |
| | 1021 | \r |
| | 1022 | if(iFrameLimit==2) SetAutoFrameCap(); // set new fps limit vals (depends on interlace)\r |
| | 1023 | \r |
| | 1024 | if(bUp) updateDisplay(); // yeah, real update (swap buffer)\r |
| | 1025 | }\r |
| | 1026 | \r |
| | 1027 | ////////////////////////////////////////////////////////////////////////\r |
| | 1028 | // window mode <-> fullscreen mode (windows)\r |
| | 1029 | ////////////////////////////////////////////////////////////////////////\r |
| | 1030 | \r |
| | 1031 | \r |
| | 1032 | ////////////////////////////////////////////////////////////////////////\r |
| | 1033 | // swap update check (called by psx vsync function)\r |
| | 1034 | ////////////////////////////////////////////////////////////////////////\r |
| | 1035 | \r |
| | 1036 | BOOL bSwapCheck(void)\r |
| | 1037 | {\r |
| | 1038 | static int iPosCheck=0;\r |
| | 1039 | static PSXPoint_t pO;\r |
| | 1040 | static PSXPoint_t pD;\r |
| | 1041 | static int iDoAgain=0;\r |
| | 1042 | \r |
| | 1043 | if(PSXDisplay.DisplayPosition.x==pO.x &&\r |
| | 1044 | PSXDisplay.DisplayPosition.y==pO.y &&\r |
| | 1045 | PSXDisplay.DisplayEnd.x==pD.x &&\r |
| | 1046 | PSXDisplay.DisplayEnd.y==pD.y)\r |
| | 1047 | iPosCheck++;\r |
| | 1048 | else iPosCheck=0;\r |
| | 1049 | \r |
| | 1050 | pO=PSXDisplay.DisplayPosition;\r |
| | 1051 | pD=PSXDisplay.DisplayEnd;\r |
| | 1052 | \r |
| | 1053 | if(iPosCheck<=4) return FALSE;\r |
| | 1054 | \r |
| | 1055 | iPosCheck=4;\r |
| | 1056 | \r |
| | 1057 | if(PSXDisplay.Interlaced) return FALSE;\r |
| | 1058 | \r |
| | 1059 | if (bNeedInterlaceUpdate||\r |
| | 1060 | bNeedRGB24Update ||\r |
| | 1061 | bNeedUploadAfter|| \r |
| | 1062 | bNeedUploadTest || \r |
| | 1063 | iDoAgain\r |
| | 1064 | )\r |
| | 1065 | {\r |
| | 1066 | iDoAgain=0;\r |
| | 1067 | if(bNeedUploadAfter) \r |
| | 1068 | iDoAgain=1;\r |
| | 1069 | if(bNeedUploadTest && PSXDisplay.InterlacedTest)\r |
| | 1070 | iDoAgain=1;\r |
| | 1071 | \r |
| | 1072 | bDisplayNotSet = TRUE;\r |
| | 1073 | updateDisplay();\r |
| | 1074 | \r |
| | 1075 | PreviousPSXDisplay.DisplayPosition.x=PSXDisplay.DisplayPosition.x;\r |
| | 1076 | PreviousPSXDisplay.DisplayPosition.y=PSXDisplay.DisplayPosition.y;\r |
| | 1077 | PreviousPSXDisplay.DisplayEnd.x=PSXDisplay.DisplayEnd.x;\r |
| | 1078 | PreviousPSXDisplay.DisplayEnd.y=PSXDisplay.DisplayEnd.y;\r |
| | 1079 | pO=PSXDisplay.DisplayPosition;\r |
| | 1080 | pD=PSXDisplay.DisplayEnd;\r |
| | 1081 | \r |
| | 1082 | return TRUE;\r |
| | 1083 | }\r |
| | 1084 | \r |
| | 1085 | return FALSE;\r |
| | 1086 | } \r |
| | 1087 | ////////////////////////////////////////////////////////////////////////\r |
| | 1088 | // gun cursor func: player=0-7, x=0-511, y=0-255\r |
| | 1089 | ////////////////////////////////////////////////////////////////////////\r |
| | 1090 | \r |
| | 1091 | ////////////////////////////////////////////////////////////////////////\r |
| | 1092 | // update lace is called every VSync. Basically we limit frame rate \r |
| | 1093 | // here, and in interlaced mode we swap ogl display buffers.\r |
| | 1094 | ////////////////////////////////////////////////////////////////////////\r |
| | 1095 | \r |
| | 1096 | static unsigned short usFirstPos=2;\r |
| | 1097 | \r |
| | 1098 | void CALLBACK GPUupdateLace(void)\r |
| | 1099 | {\r |
| | 1100 | if(!(dwActFixes&0x1000)) \r |
| | 1101 | STATUSREG^=0x80000000; // interlaced bit toggle, if the CC game fix is not active (see gpuReadStatus)\r |
| | 1102 | \r |
| | 1103 | if(!(dwActFixes&128)) // normal frame limit func\r |
| | 1104 | CheckFrameRate();\r |
| | 1105 | \r |
| | 1106 | if(iOffscreenDrawing==4) // special check if high offscreen drawing is on\r |
| | 1107 | {\r |
| | 1108 | if(bSwapCheck()) return;\r |
| | 1109 | }\r |
| | 1110 | \r |
| | 1111 | if(PSXDisplay.Interlaced) // interlaced mode?\r |
| | 1112 | {\r |
| | 1113 | if(PSXDisplay.DisplayMode.x>0 && PSXDisplay.DisplayMode.y>0)\r |
| | 1114 | {\r |
| | 1115 | updateDisplay(); // -> swap buffers (new frame)\r |
| | 1116 | }\r |
| | 1117 | }\r |
| | 1118 | else if(bRenderFrontBuffer) // no interlace mode? and some stuff in front has changed?\r |
| | 1119 | {\r |
| | 1120 | updateFrontDisplay(); // -> update front buffer\r |
| | 1121 | }\r |
| | 1122 | else if(usFirstPos==1) // initial updates (after startup)\r |
| | 1123 | {\r |
| | 1124 | updateDisplay();\r |
| | 1125 | }\r |
| | 1126 | \r |
| | 1127 | }\r |
| | 1128 | \r |
| | 1129 | ////////////////////////////////////////////////////////////////////////\r |
| | 1130 | // process read request from GPU status register\r |
| | 1131 | ////////////////////////////////////////////////////////////////////////\r |
| | 1132 | \r |
| | 1133 | unsigned long CALLBACK GPUreadStatus(void)\r |
| | 1134 | {\r |
| | 1135 | if(dwActFixes&0x1000) // CC game fix\r |
| | 1136 | {\r |
| | 1137 | static int iNumRead=0;\r |
| | 1138 | if((iNumRead++)==2)\r |
| | 1139 | {\r |
| | 1140 | iNumRead=0;\r |
| | 1141 | STATUSREG^=0x80000000; // interlaced bit toggle... we do it on every second read status... needed by some games (like ChronoCross)\r |
| | 1142 | }\r |
| | 1143 | }\r |
| | 1144 | \r |
| | 1145 | if(iFakePrimBusy) // 27.10.2007 - emulating some 'busy' while drawing... pfff... not perfect, but since our emulated dma is not done in an extra thread...\r |
| | 1146 | {\r |
| | 1147 | iFakePrimBusy--;\r |
| | 1148 | \r |
| | 1149 | if(iFakePrimBusy&1) // we do a busy-idle-busy-idle sequence after/while drawing prims\r |
| | 1150 | {\r |
| | 1151 | GPUIsBusy;\r |
| | 1152 | GPUIsNotReadyForCommands;\r |
| | 1153 | }\r |
| | 1154 | else\r |
| | 1155 | {\r |
| | 1156 | GPUIsIdle;\r |
| | 1157 | GPUIsReadyForCommands;\r |
| | 1158 | }\r |
| | 1159 | }\r |
| | 1160 | \r |
| | 1161 | return STATUSREG;\r |
| | 1162 | }\r |
| | 1163 | \r |
| | 1164 | ////////////////////////////////////////////////////////////////////////\r |
| | 1165 | // processes data send to GPU status register\r |
| | 1166 | // these are always single packet commands.\r |
| | 1167 | ////////////////////////////////////////////////////////////////////////\r |
| | 1168 | \r |
| | 1169 | void CALLBACK GPUwriteStatus(unsigned long gdata)\r |
| | 1170 | {\r |
| | 1171 | unsigned long lCommand=(gdata>>24)&0xff;\r |
| | 1172 | \r |
| | 1173 | if(bIsFirstFrame) GLinitialize(NULL, NULL); // real ogl startup (needed by some emus)\r |
| | 1174 | \r |
| | 1175 | ulStatusControl[lCommand]=gdata;\r |
| | 1176 | \r |
| | 1177 | switch(lCommand)\r |
| | 1178 | {\r |
| | 1179 | //--------------------------------------------------//\r |
| | 1180 | // reset gpu\r |
| | 1181 | case 0x00:\r |
| | 1182 | memset(ulGPUInfoVals,0x00,16*sizeof(unsigned long));\r |
| | 1183 | lGPUstatusRet=0x14802000;\r |
| | 1184 | PSXDisplay.Disabled=1;\r |
| | 1185 | iDataWriteMode=iDataReadMode=DR_NORMAL;\r |
| | 1186 | PSXDisplay.DrawOffset.x=PSXDisplay.DrawOffset.y=0;\r |
| | 1187 | drawX=drawY=0;drawW=drawH=0;\r |
| | 1188 | sSetMask=0;lSetMask=0;bCheckMask=FALSE;iSetMask=0;\r |
| | 1189 | usMirror=0;\r |
| | 1190 | GlobalTextAddrX=0;GlobalTextAddrY=0;\r |
| | 1191 | GlobalTextTP=0;GlobalTextABR=0;\r |
| | 1192 | PSXDisplay.RGB24=FALSE;\r |
| | 1193 | PSXDisplay.Interlaced=FALSE;\r |
| | 1194 | bUsingTWin = FALSE;\r |
| | 1195 | return;\r |
| | 1196 | \r |
| | 1197 | // dis/enable display\r |
| | 1198 | case 0x03: \r |
| | 1199 | PreviousPSXDisplay.Disabled = PSXDisplay.Disabled;\r |
| | 1200 | PSXDisplay.Disabled = (gdata & 1);\r |
| | 1201 | \r |
| | 1202 | if(PSXDisplay.Disabled) \r |
| | 1203 | STATUSREG|=GPUSTATUS_DISPLAYDISABLED;\r |
| | 1204 | else STATUSREG&=~GPUSTATUS_DISPLAYDISABLED;\r |
| | 1205 | \r |
| | 1206 | if (iOffscreenDrawing==4 &&\r |
| | 1207 | PreviousPSXDisplay.Disabled && \r |
| | 1208 | !(PSXDisplay.Disabled))\r |
| | 1209 | {\r |
| | 1210 | \r |
| | 1211 | if(!PSXDisplay.RGB24)\r |
| | 1212 | {\r |
| | 1213 | PrepareFullScreenUpload(TRUE);\r |
| | 1214 | UploadScreen(TRUE); \r |
| | 1215 | updateDisplay();\r |
| | 1216 | }\r |
| | 1217 | }\r |
| | 1218 | \r |
| | 1219 | return;\r |
| | 1220 | \r |
| | 1221 | // setting transfer mode\r |
| | 1222 | case 0x04:\r |
| | 1223 | gdata &= 0x03; // only want the lower two bits\r |
| | 1224 | \r |
| | 1225 | iDataWriteMode=iDataReadMode=DR_NORMAL;\r |
| | 1226 | if(gdata==0x02) iDataWriteMode=DR_VRAMTRANSFER;\r |
| | 1227 | if(gdata==0x03) iDataReadMode =DR_VRAMTRANSFER;\r |
| | 1228 | \r |
| | 1229 | STATUSREG&=~GPUSTATUS_DMABITS; // clear the current settings of the DMA bits\r |
| | 1230 | STATUSREG|=(gdata << 29); // set the DMA bits according to the received data\r |
| | 1231 | \r |
| | 1232 | return;\r |
| | 1233 | \r |
| | 1234 | // setting display position\r |
| | 1235 | case 0x05: \r |
| | 1236 | {\r |
| | 1237 | short sx=(short)(gdata & 0x3ff);\r |
| | 1238 | short sy;\r |
| | 1239 | \r |
| | 1240 | if(iGPUHeight==1024)\r |
| | 1241 | {\r |
| | 1242 | if(dwGPUVersion==2) \r |
| | 1243 | sy = (short)((gdata>>12)&0x3ff);\r |
| | 1244 | else sy = (short)((gdata>>10)&0x3ff);\r |
| | 1245 | }\r |
| | 1246 | else sy = (short)((gdata>>10)&0x3ff); // really: 0x1ff, but we adjust it later\r |
| | 1247 | \r |
| | 1248 | if (sy & 0x200) \r |
| | 1249 | {\r |
| | 1250 | sy|=0xfc00;\r |
| | 1251 | PreviousPSXDisplay.DisplayModeNew.y=sy/PSXDisplay.Double;\r |
| | 1252 | sy=0;\r |
| | 1253 | }\r |
| | 1254 | else PreviousPSXDisplay.DisplayModeNew.y=0;\r |
| | 1255 | \r |
| | 1256 | if(sx>1000) sx=0;\r |
| | 1257 | \r |
| | 1258 | if(usFirstPos)\r |
| | 1259 | {\r |
| | 1260 | usFirstPos--;\r |
| | 1261 | if(usFirstPos)\r |
| | 1262 | {\r |
| | 1263 | PreviousPSXDisplay.DisplayPosition.x = sx;\r |
| | 1264 | PreviousPSXDisplay.DisplayPosition.y = sy;\r |
| | 1265 | PSXDisplay.DisplayPosition.x = sx;\r |
| | 1266 | PSXDisplay.DisplayPosition.y = sy;\r |
| | 1267 | }\r |
| | 1268 | }\r |
| | 1269 | \r |
| | 1270 | if(dwActFixes&8) \r |
| | 1271 | {\r |
| | 1272 | if((!PSXDisplay.Interlaced) &&\r |
| | 1273 | PreviousPSXDisplay.DisplayPosition.x == sx &&\r |
| | 1274 | PreviousPSXDisplay.DisplayPosition.y == sy)\r |
| | 1275 | return;\r |
| | 1276 | \r |
| | 1277 | PSXDisplay.DisplayPosition.x = PreviousPSXDisplay.DisplayPosition.x;\r |
| | 1278 | PSXDisplay.DisplayPosition.y = PreviousPSXDisplay.DisplayPosition.y;\r |
| | 1279 | PreviousPSXDisplay.DisplayPosition.x = sx;\r |
| | 1280 | PreviousPSXDisplay.DisplayPosition.y = sy;\r |
| | 1281 | }\r |
| | 1282 | else\r |
| | 1283 | {\r |
| | 1284 | if((!PSXDisplay.Interlaced) &&\r |
| | 1285 | PSXDisplay.DisplayPosition.x == sx &&\r |
| | 1286 | PSXDisplay.DisplayPosition.y == sy)\r |
| | 1287 | return;\r |
| | 1288 | PreviousPSXDisplay.DisplayPosition.x = PSXDisplay.DisplayPosition.x;\r |
| | 1289 | PreviousPSXDisplay.DisplayPosition.y = PSXDisplay.DisplayPosition.y;\r |
| | 1290 | PSXDisplay.DisplayPosition.x = sx;\r |
| | 1291 | PSXDisplay.DisplayPosition.y = sy;\r |
| | 1292 | }\r |
| | 1293 | \r |
| | 1294 | PSXDisplay.DisplayEnd.x=\r |
| | 1295 | PSXDisplay.DisplayPosition.x+ PSXDisplay.DisplayMode.x;\r |
| | 1296 | PSXDisplay.DisplayEnd.y=\r |
| | 1297 | PSXDisplay.DisplayPosition.y+ PSXDisplay.DisplayMode.y+PreviousPSXDisplay.DisplayModeNew.y;\r |
| | 1298 | \r |
| | 1299 | PreviousPSXDisplay.DisplayEnd.x=\r |
| | 1300 | PreviousPSXDisplay.DisplayPosition.x+ PSXDisplay.DisplayMode.x;\r |
| | 1301 | PreviousPSXDisplay.DisplayEnd.y=\r |
| | 1302 | PreviousPSXDisplay.DisplayPosition.y+ PSXDisplay.DisplayMode.y+PreviousPSXDisplay.DisplayModeNew.y;\r |
| | 1303 | \r |
| | 1304 | bDisplayNotSet = TRUE;\r |
| | 1305 | \r |
| | 1306 | if (!(PSXDisplay.Interlaced))\r |
| | 1307 | {\r |
| | 1308 | updateDisplay();\r |
| | 1309 | }\r |
| | 1310 | else\r |
| | 1311 | if(PSXDisplay.InterlacedTest && \r |
| | 1312 | ((PreviousPSXDisplay.DisplayPosition.x != PSXDisplay.DisplayPosition.x)||\r |
| | 1313 | (PreviousPSXDisplay.DisplayPosition.y != PSXDisplay.DisplayPosition.y)))\r |
| | 1314 | PSXDisplay.InterlacedTest--;\r |
| | 1315 | \r |
| | 1316 | return;\r |
| | 1317 | }\r |
| | 1318 | \r |
| | 1319 | // setting width\r |
| | 1320 | case 0x06:\r |
| | 1321 | \r |
| | 1322 | PSXDisplay.Range.x0=gdata & 0x7ff; //0x3ff;\r |
| | 1323 | PSXDisplay.Range.x1=(gdata>>12) & 0xfff;//0x7ff;\r |
| | 1324 | \r |
| | 1325 | PSXDisplay.Range.x1-=PSXDisplay.Range.x0;\r |
| | 1326 | \r |
| | 1327 | ChangeDispOffsetsX();\r |
| | 1328 | \r |
| | 1329 | return;\r |
| | 1330 | \r |
| | 1331 | // setting height\r |
| | 1332 | case 0x07:\r |
| | 1333 | \r |
| | 1334 | PreviousPSXDisplay.Height = PSXDisplay.Height;\r |
| | 1335 | \r |
| | 1336 | PSXDisplay.Range.y0=gdata & 0x3ff;\r |
| | 1337 | PSXDisplay.Range.y1=(gdata>>10) & 0x3ff;\r |
| | 1338 | \r |
| | 1339 | PSXDisplay.Height = PSXDisplay.Range.y1 - \r |
| | 1340 | PSXDisplay.Range.y0 +\r |
| | 1341 | PreviousPSXDisplay.DisplayModeNew.y;\r |
| | 1342 | \r |
| | 1343 | if (PreviousPSXDisplay.Height != PSXDisplay.Height)\r |
| | 1344 | {\r |
| | 1345 | PSXDisplay.DisplayModeNew.y=PSXDisplay.Height*PSXDisplay.Double;\r |
| | 1346 | ChangeDispOffsetsY();\r |
| | 1347 | updateDisplayIfChanged();\r |
| | 1348 | }\r |
| | 1349 | return;\r |
| | 1350 | \r |
| | 1351 | // setting display infos\r |
| | 1352 | case 0x08:\r |
| | 1353 | \r |
| | 1354 | PSXDisplay.DisplayModeNew.x = dispWidths[(gdata & 0x03) | ((gdata & 0x40) >> 4)];\r |
| | 1355 | \r |
| | 1356 | if (gdata&0x04) PSXDisplay.Double=2;\r |
| | 1357 | else PSXDisplay.Double=1;\r |
| | 1358 | PSXDisplay.DisplayModeNew.y = PSXDisplay.Height*PSXDisplay.Double;\r |
| | 1359 | \r |
| | 1360 | ChangeDispOffsetsY();\r |
| | 1361 | \r |
| | 1362 | PSXDisplay.PAL = (gdata & 0x08)?TRUE:FALSE; // if 1 - PAL mode, else NTSC\r |
| | 1363 | PSXDisplay.RGB24New = (gdata & 0x10)?TRUE:FALSE; // if 1 - TrueColor\r |
| | 1364 | PSXDisplay.InterlacedNew = (gdata & 0x20)?TRUE:FALSE; // if 1 - Interlace\r |
| | 1365 | \r |
| | 1366 | STATUSREG&=~GPUSTATUS_WIDTHBITS; // clear the width bits\r |
| | 1367 | \r |
| | 1368 | STATUSREG|=\r |
| | 1369 | (((gdata & 0x03) << 17) | \r |
| | 1370 | ((gdata & 0x40) << 10)); // set the width bits\r |
| | 1371 | \r |
| | 1372 | PreviousPSXDisplay.InterlacedNew=FALSE;\r |
| | 1373 | if (PSXDisplay.InterlacedNew)\r |
| | 1374 | {\r |
| | 1375 | if(!PSXDisplay.Interlaced)\r |
| | 1376 | {\r |
| | 1377 | PSXDisplay.InterlacedTest=2;\r |
| | 1378 | PreviousPSXDisplay.DisplayPosition.x = PSXDisplay.DisplayPosition.x;\r |
| | 1379 | PreviousPSXDisplay.DisplayPosition.y = PSXDisplay.DisplayPosition.y;\r |
| | 1380 | PreviousPSXDisplay.InterlacedNew=TRUE;\r |
| | 1381 | }\r |
| | 1382 | \r |
| | 1383 | STATUSREG|=GPUSTATUS_INTERLACED;\r |
| | 1384 | }\r |
| | 1385 | else \r |
| | 1386 | {\r |
| | 1387 | PSXDisplay.InterlacedTest=0;\r |
| | 1388 | STATUSREG&=~GPUSTATUS_INTERLACED;\r |
| | 1389 | }\r |
| | 1390 | \r |
| | 1391 | if (PSXDisplay.PAL)\r |
| | 1392 | STATUSREG|=GPUSTATUS_PAL;\r |
| | 1393 | else STATUSREG&=~GPUSTATUS_PAL;\r |
| | 1394 | \r |
| | 1395 | if (PSXDisplay.Double==2)\r |
| | 1396 | STATUSREG|=GPUSTATUS_DOUBLEHEIGHT;\r |
| | 1397 | else STATUSREG&=~GPUSTATUS_DOUBLEHEIGHT;\r |
| | 1398 | \r |
| | 1399 | if (PSXDisplay.RGB24New)\r |
| | 1400 | STATUSREG|=GPUSTATUS_RGB24;\r |
| | 1401 | else STATUSREG&=~GPUSTATUS_RGB24;\r |
| | 1402 | \r |
| | 1403 | updateDisplayIfChanged();\r |
| | 1404 | \r |
| | 1405 | return;\r |
| | 1406 | \r |
| | 1407 | //--------------------------------------------------//\r |
| | 1408 | // ask about GPU version and other stuff\r |
| | 1409 | case 0x10: \r |
| | 1410 | \r |
| | 1411 | gdata&=0xff;\r |
| | 1412 | \r |
| | 1413 | switch(gdata) \r |
| | 1414 | {\r |
| | 1415 | case 0x02:\r |
| | 1416 | GPUdataRet=ulGPUInfoVals[INFO_TW]; // tw infos\r |
| | 1417 | return;\r |
| | 1418 | case 0x03:\r |
| | 1419 | GPUdataRet=ulGPUInfoVals[INFO_DRAWSTART]; // draw start\r |
| | 1420 | return;\r |
| | 1421 | case 0x04:\r |
| | 1422 | GPUdataRet=ulGPUInfoVals[INFO_DRAWEND]; // draw end\r |
| | 1423 | return;\r |
| | 1424 | case 0x05:\r |
| | 1425 | case 0x06:\r |
| | 1426 | GPUdataRet=ulGPUInfoVals[INFO_DRAWOFF]; // draw offset\r |
| | 1427 | return;\r |
| | 1428 | case 0x07:\r |
| | 1429 | if(dwGPUVersion==2)\r |
| | 1430 | GPUdataRet=0x01;\r |
| | 1431 | else GPUdataRet=0x02; // gpu type\r |
| | 1432 | return;\r |
| | 1433 | case 0x08:\r |
| | 1434 | case 0x0F: // some bios addr?\r |
| | 1435 | GPUdataRet=0xBFC03720;\r |
| | 1436 | return;\r |
| | 1437 | }\r |
| | 1438 | return;\r |
| | 1439 | //--------------------------------------------------//\r |
| | 1440 | }\r |
| | 1441 | }\r |
| | 1442 | \r |
| | 1443 | ////////////////////////////////////////////////////////////////////////\r |
| | 1444 | // vram read/write helpers\r |
| | 1445 | ////////////////////////////////////////////////////////////////////////\r |
| | 1446 | \r |
| | 1447 | BOOL bNeedWriteUpload=FALSE;\r |
| | 1448 | \r |
| | 1449 | __inline void FinishedVRAMWrite(void)\r |
| | 1450 | {\r |
| | 1451 | if(bNeedWriteUpload)\r |
| | 1452 | {\r |
| | 1453 | bNeedWriteUpload=FALSE;\r |
| | 1454 | CheckWriteUpdate();\r |
| | 1455 | }\r |
| | 1456 | \r |
| | 1457 | // set register to NORMAL operation\r |
| | 1458 | iDataWriteMode = DR_NORMAL;\r |
| | 1459 | \r |
| | 1460 | // reset transfer values, to prevent mis-transfer of data\r |
| | 1461 | VRAMWrite.ColsRemaining = 0;\r |
| | 1462 | VRAMWrite.RowsRemaining = 0;\r |
| | 1463 | }\r |
| | 1464 | \r |
| | 1465 | __inline void FinishedVRAMRead(void)\r |
| | 1466 | {\r |
| | 1467 | // set register to NORMAL operation\r |
| | 1468 | iDataReadMode = DR_NORMAL;\r |
| | 1469 | // reset transfer values, to prevent mis-transfer of data\r |
| | 1470 | VRAMRead.x = 0;\r |
| | 1471 | VRAMRead.y = 0;\r |
| | 1472 | VRAMRead.Width = 0;\r |
| | 1473 | VRAMRead.Height = 0;\r |
| | 1474 | VRAMRead.ColsRemaining = 0;\r |
| | 1475 | VRAMRead.RowsRemaining = 0;\r |
| | 1476 | \r |
| | 1477 | // indicate GPU is no longer ready for VRAM data in the STATUS REGISTER\r |
| | 1478 | STATUSREG&=~GPUSTATUS_READYFORVRAM;\r |
| | 1479 | }\r |
| | 1480 | \r |
| | 1481 | ////////////////////////////////////////////////////////////////////////\r |
| | 1482 | // vram read check ex (reading from card's back/frontbuffer if needed...\r |
| | 1483 | // slow!)\r |
| | 1484 | ////////////////////////////////////////////////////////////////////////\r |
| | 1485 | \r |
| | 1486 | void CheckVRamReadEx(int x, int y, int dx, int dy)\r |
| | 1487 | {\r |
| | 1488 | unsigned short sArea;\r |
| | 1489 | int ux,uy,udx,udy,wx,wy;\r |
| | 1490 | unsigned short * p1, *p2;\r |
| | 1491 | float XS,YS;\r |
| | 1492 | unsigned char * ps;\r |
| | 1493 | unsigned char * px;\r |
| | 1494 | unsigned short s,sx;\r |
| | 1495 | \r |
| | 1496 | if(STATUSREG&GPUSTATUS_RGB24) return;\r |
| | 1497 | \r |
| | 1498 | if(((dx > PSXDisplay.DisplayPosition.x) &&\r |
| | 1499 | (x < PSXDisplay.DisplayEnd.x) &&\r |
| | 1500 | (dy > PSXDisplay.DisplayPosition.y) &&\r |
| | 1501 | (y < PSXDisplay.DisplayEnd.y)))\r |
| | 1502 | sArea=0;\r |
| | 1503 | else\r |
| | 1504 | if((!(PSXDisplay.InterlacedTest) &&\r |
| | 1505 | (dx > PreviousPSXDisplay.DisplayPosition.x) &&\r |
| | 1506 | (x < PreviousPSXDisplay.DisplayEnd.x) &&\r |
| | 1507 | (dy > PreviousPSXDisplay.DisplayPosition.y) &&\r |
| | 1508 | (y < PreviousPSXDisplay.DisplayEnd.y)))\r |
| | 1509 | sArea=1;\r |
| | 1510 | else \r |
| | 1511 | {\r |
| | 1512 | return;\r |
| | 1513 | }\r |
| | 1514 | \r |
| | 1515 | //////////////\r |
| | 1516 | \r |
| | 1517 | if(iRenderFVR)\r |
| | 1518 | {\r |
| | 1519 | bFullVRam=TRUE;iRenderFVR=2;return;\r |
| | 1520 | }\r |
| | 1521 | bFullVRam=TRUE;iRenderFVR=2;\r |
| | 1522 | \r |
| | 1523 | //////////////\r |
| | 1524 | \r |
| | 1525 | p2=0;\r |
| | 1526 | \r |
| | 1527 | if(sArea==0)\r |
| | 1528 | {\r |
| | 1529 | ux=PSXDisplay.DisplayPosition.x;\r |
| | 1530 | uy=PSXDisplay.DisplayPosition.y;\r |
| | 1531 | udx=PSXDisplay.DisplayEnd.x-ux;\r |
| | 1532 | udy=PSXDisplay.DisplayEnd.y-uy;\r |
| | 1533 | if((PreviousPSXDisplay.DisplayEnd.x-\r |
| | 1534 | PreviousPSXDisplay.DisplayPosition.x)==udx &&\r |
| | 1535 | (PreviousPSXDisplay.DisplayEnd.y-\r |
| | 1536 | PreviousPSXDisplay.DisplayPosition.y)==udy)\r |
| | 1537 | p2=(psxVuw + (1024*PreviousPSXDisplay.DisplayPosition.y) + \r |
| | 1538 | PreviousPSXDisplay.DisplayPosition.x);\r |
| | 1539 | }\r |
| | 1540 | else\r |
| | 1541 | {\r |
| | 1542 | ux=PreviousPSXDisplay.DisplayPosition.x;\r |
| | 1543 | uy=PreviousPSXDisplay.DisplayPosition.y;\r |
| | 1544 | udx=PreviousPSXDisplay.DisplayEnd.x-ux;\r |
| | 1545 | udy=PreviousPSXDisplay.DisplayEnd.y-uy;\r |
| | 1546 | if((PSXDisplay.DisplayEnd.x-\r |
| | 1547 | PSXDisplay.DisplayPosition.x)==udx &&\r |
| | 1548 | (PSXDisplay.DisplayEnd.y-\r |
| | 1549 | PSXDisplay.DisplayPosition.y)==udy)\r |
| | 1550 | p2=(psxVuw + (1024*PSXDisplay.DisplayPosition.y) + \r |
| | 1551 | PSXDisplay.DisplayPosition.x);\r |
| | 1552 | }\r |
| | 1553 | \r |
| | 1554 | p1=(psxVuw + (1024*uy) + ux);\r |
| | 1555 | if(p1==p2) p2=0;\r |
| | 1556 | \r |
| | 1557 | x=0;y=0;\r |
| | 1558 | wx=dx=udx;wy=dy=udy;\r |
| | 1559 | \r |
| | 1560 | if(udx<=0) return;\r |
| | 1561 | if(udy<=0) return;\r |
| | 1562 | if(dx<=0) return;\r |
| | 1563 | if(dy<=0) return;\r |
| | 1564 | if(wx<=0) return;\r |
| | 1565 | if(wy<=0) return;\r |
| | 1566 | \r |
| | 1567 | XS=(float)rRatioRect.right/(float)wx;\r |
| | 1568 | YS=(float)rRatioRect.bottom/(float)wy;\r |
| | 1569 | \r |
| | 1570 | dx=(int)((float)(dx)*XS);\r |
| | 1571 | dy=(int)((float)(dy)*YS);\r |
| | 1572 | \r |
| | 1573 | if(dx>iResX) dx=iResX;\r |
| | 1574 | if(dy>iResY) dy=iResY;\r |
| | 1575 | \r |
| | 1576 | if(dx<=0) return;\r |
| | 1577 | if(dy<=0) return;\r |
| | 1578 | \r |
| | 1579 | // ogl y adjust\r |
| | 1580 | y=iResY-y-dy;\r |
| | 1581 | \r |
| | 1582 | x+=rRatioRect.left;\r |
| | 1583 | y-=rRatioRect.top;\r |
| | 1584 | \r |
| | 1585 | if(y<0) y=0; if((y+dy)>iResY) dy=iResY-y;\r |
| | 1586 | \r |
| | 1587 | if(!pGfxCardScreen)\r |
| | 1588 | {\r |
| | 1589 | glPixelStorei(GL_PACK_ALIGNMENT,1); glError();\r |
| | 1590 | pGfxCardScreen=(unsigned char *)malloc(iResX*iResY*4);\r |
| | 1591 | }\r |
| | 1592 | \r |
| | 1593 | ps=pGfxCardScreen;\r |
| | 1594 | \r |
| | 1595 | //if(!sArea) glReadBuffer(GL_FRONT);\r |
| | 1596 | \r |
| | 1597 | glReadPixels(x,y,dx,dy,GL_RGB,GL_UNSIGNED_BYTE,ps); glError();\r |
| | 1598 | //if(!sArea) glReadBuffer(GL_BACK);\r |
| | 1599 | \r |
| | 1600 | s=0;\r |
| | 1601 | \r |
| | 1602 | XS=(float)dx/(float)(udx);\r |
| | 1603 | YS=(float)dy/(float)(udy+1);\r |
| | 1604 | \r |
| | 1605 | for(y=udy;y>0;y--)\r |
| | 1606 | {\r |
| | 1607 | for(x=0;x<udx;x++)\r |
| | 1608 | {\r |
| | 1609 | if(p1>=psxVuw && p1<psxVuw_eom)\r |
| | 1610 | {\r |
| | 1611 | px=ps+(3*((int)((float)x * XS))+\r |
| | 1612 | (3*dx)*((int)((float)y*YS)));\r |
| | 1613 | sx=(*px)>>3;px++;\r |
| | 1614 | s=sx;\r |
| | 1615 | sx=(*px)>>3;px++;\r |
| | 1616 | s|=sx<<5;\r |
| | 1617 | sx=(*px)>>3;\r |
| | 1618 | s|=sx<<10;\r |
| | 1619 | s&=~0x8000;\r |
| | 1620 | *p1=s;\r |
| | 1621 | }\r |
| | 1622 | if(p2>=psxVuw && p2<psxVuw_eom) *p2=s;\r |
| | 1623 | \r |
| | 1624 | p1++;\r |
| | 1625 | if(p2) p2++;\r |
| | 1626 | }\r |
| | 1627 | \r |
| | 1628 | p1 += 1024 - udx;\r |
| | 1629 | if(p2) p2 += 1024 - udx;\r |
| | 1630 | }\r |
| | 1631 | }\r |
| | 1632 | \r |
| | 1633 | ////////////////////////////////////////////////////////////////////////\r |
| | 1634 | // vram read check (reading from card's back/frontbuffer if needed... \r |
| | 1635 | // slow!)\r |
| | 1636 | ////////////////////////////////////////////////////////////////////////\r |
| | 1637 | \r |
| | 1638 | void CheckVRamRead(int x, int y, int dx, int dy, bool bFront)\r |
| | 1639 | {\r |
| | 1640 | unsigned short sArea;unsigned short * p;\r |
| | 1641 | int ux,uy,udx,udy,wx,wy;float XS,YS;\r |
| | 1642 | unsigned char * ps, * px;\r |
| | 1643 | unsigned short s=0,sx;\r |
| | 1644 | \r |
| | 1645 | if(STATUSREG&GPUSTATUS_RGB24) return;\r |
| | 1646 | \r |
| | 1647 | if(((dx > PSXDisplay.DisplayPosition.x) &&\r |
| | 1648 | (x < PSXDisplay.DisplayEnd.x) &&\r |
| | 1649 | (dy > PSXDisplay.DisplayPosition.y) &&\r |
| | 1650 | (y < PSXDisplay.DisplayEnd.y)))\r |
| | 1651 | sArea=0;\r |
| | 1652 | else\r |
| | 1653 | if((!(PSXDisplay.InterlacedTest) &&\r |
| | 1654 | (dx > PreviousPSXDisplay.DisplayPosition.x) &&\r |
| | 1655 | (x < PreviousPSXDisplay.DisplayEnd.x) &&\r |
| | 1656 | (dy > PreviousPSXDisplay.DisplayPosition.y) &&\r |
| | 1657 | (y < PreviousPSXDisplay.DisplayEnd.y)))\r |
| | 1658 | sArea=1;\r |
| | 1659 | else \r |
| | 1660 | {\r |
| | 1661 | return;\r |
| | 1662 | }\r |
| | 1663 | \r |
| | 1664 | if(dwActFixes&0x40)\r |
| | 1665 | {\r |
| | 1666 | if(iRenderFVR)\r |
| | 1667 | {\r |
| | 1668 | bFullVRam=TRUE;iRenderFVR=2;return;\r |
| | 1669 | }\r |
| | 1670 | bFullVRam=TRUE;iRenderFVR=2;\r |
| | 1671 | }\r |
| | 1672 | \r |
| | 1673 | ux=x;uy=y;udx=dx;udy=dy;\r |
| | 1674 | \r |
| | 1675 | if(sArea==0)\r |
| | 1676 | {\r |
| | 1677 | x -=PSXDisplay.DisplayPosition.x;\r |
| | 1678 | dx-=PSXDisplay.DisplayPosition.x;\r |
| | 1679 | y -=PSXDisplay.DisplayPosition.y;\r |
| | 1680 | dy-=PSXDisplay.DisplayPosition.y;\r |
| | 1681 | wx=PSXDisplay.DisplayEnd.x-PSXDisplay.DisplayPosition.x;\r |
| | 1682 | wy=PSXDisplay.DisplayEnd.y-PSXDisplay.DisplayPosition.y;\r |
| | 1683 | }\r |
| | 1684 | else\r |
| | 1685 | {\r |
| | 1686 | x -=PreviousPSXDisplay.DisplayPosition.x;\r |
| | 1687 | dx-=PreviousPSXDisplay.DisplayPosition.x;\r |
| | 1688 | y -=PreviousPSXDisplay.DisplayPosition.y;\r |
| | 1689 | dy-=PreviousPSXDisplay.DisplayPosition.y;\r |
| | 1690 | wx=PreviousPSXDisplay.DisplayEnd.x-PreviousPSXDisplay.DisplayPosition.x;\r |
| | 1691 | wy=PreviousPSXDisplay.DisplayEnd.y-PreviousPSXDisplay.DisplayPosition.y;\r |
| | 1692 | }\r |
| | 1693 | if(x<0) {ux-=x;x=0;}\r |
| | 1694 | if(y<0) {uy-=y;y=0;}\r |
| | 1695 | if(dx>wx) {udx-=(dx-wx);dx=wx;}\r |
| | 1696 | if(dy>wy) {udy-=(dy-wy);dy=wy;}\r |
| | 1697 | udx-=ux;\r |
| | 1698 | udy-=uy;\r |
| | 1699 | \r |
| | 1700 | p=(psxVuw + (1024*uy) + ux);\r |
| | 1701 | \r |
| | 1702 | if(udx<=0) return;\r |
| | 1703 | if(udy<=0) return;\r |
| | 1704 | if(dx<=0) return;\r |
| | 1705 | if(dy<=0) return;\r |
| | 1706 | if(wx<=0) return;\r |
| | 1707 | if(wy<=0) return;\r |
| | 1708 | \r |
| | 1709 | XS=(float)rRatioRect.right/(float)wx;\r |
| | 1710 | YS=(float)rRatioRect.bottom/(float)wy;\r |
| | 1711 | \r |
| | 1712 | dx=(int)((float)(dx)*XS);\r |
| | 1713 | dy=(int)((float)(dy)*YS);\r |
| | 1714 | x=(int)((float)x*XS);\r |
| | 1715 | y=(int)((float)y*YS);\r |
| | 1716 | \r |
| | 1717 | dx-=x;\r |
| | 1718 | dy-=y;\r |
| | 1719 | \r |
| | 1720 | if(dx>iResX) dx=iResX;\r |
| | 1721 | if(dy>iResY) dy=iResY;\r |
| | 1722 | \r |
| | 1723 | if(dx<=0) return;\r |
| | 1724 | if(dy<=0) return;\r |
| | 1725 | \r |
| | 1726 | // ogl y adjust\r |
| | 1727 | y=iResY-y-dy;\r |
| | 1728 | \r |
| | 1729 | x+=rRatioRect.left;\r |
| | 1730 | y-=rRatioRect.top;\r |
| | 1731 | \r |
| | 1732 | if(y<0) y=0; if((y+dy)>iResY) dy=iResY-y;\r |
| | 1733 | \r |
| | 1734 | if(!pGfxCardScreen)\r |
| | 1735 | {\r |
| | 1736 | glPixelStorei(GL_PACK_ALIGNMENT,1); glError();\r |
| | 1737 | pGfxCardScreen=(unsigned char *)malloc(iResX*iResY*4);\r |
| | 1738 | }\r |
| | 1739 | \r |
| | 1740 | ps=pGfxCardScreen;\r |
| | 1741 | \r |
| | 1742 | // if(bFront) glReadBuffer(GL_FRONT);\r |
| | 1743 | \r |
| | 1744 | glReadPixels(x,y,dx,dy,GL_RGB,GL_UNSIGNED_BYTE,ps); glError(); glError();\r |
| | 1745 | // if(bFront) glReadBuffer(GL_BACK);\r |
| | 1746 | \r |
| | 1747 | XS=(float)dx/(float)(udx);\r |
| | 1748 | YS=(float)dy/(float)(udy+1);\r |
| | 1749 | \r |
| | 1750 | for(y=udy;y>0;y--)\r |
| | 1751 | {\r |
| | 1752 | for(x=0;x<udx;x++)\r |
| | 1753 | {\r |
| | 1754 | if(p>=psxVuw && p<psxVuw_eom)\r |
| | 1755 | {\r |
| | 1756 | px=ps+(3*((int)((float)x * XS))+\r |
| | 1757 | (3*dx)*((int)((float)y*YS)));\r |
| | 1758 | sx=(*px)>>3;px++;\r |
| | 1759 | s=sx;\r |
| | 1760 | sx=(*px)>>3;px++;\r |
| | 1761 | s|=sx<<5;\r |
| | 1762 | sx=(*px)>>3;\r |
| | 1763 | s|=sx<<10;\r |
| | 1764 | s&=~0x8000;\r |
| | 1765 | *p=s;\r |
| | 1766 | }\r |
| | 1767 | p++;\r |
| | 1768 | }\r |
| | 1769 | p += 1024 - udx;\r |
| | 1770 | }\r |
| | 1771 | }\r |
| | 1772 | \r |
| | 1773 | ////////////////////////////////////////////////////////////////////////\r |
| | 1774 | // core read from vram\r |
| | 1775 | ////////////////////////////////////////////////////////////////////////\r |
| | 1776 | \r |
| | 1777 | void CALLBACK GPUreadDataMem(unsigned long * pMem, int iSize)\r |
| | 1778 | {\r |
| | 1779 | int i;\r |
| | 1780 | \r |
| | 1781 | if(iDataReadMode!=DR_VRAMTRANSFER) return;\r |
| | 1782 | \r |
| | 1783 | GPUIsBusy;\r |
| | 1784 | \r |
| | 1785 | // adjust read ptr, if necessary\r |
| | 1786 | while(VRAMRead.ImagePtr>=psxVuw_eom)\r |
| | 1787 | VRAMRead.ImagePtr-=iGPUHeight*1024;\r |
| | 1788 | while(VRAMRead.ImagePtr<psxVuw)\r |
| | 1789 | VRAMRead.ImagePtr+=iGPUHeight*1024;\r |
| | 1790 | \r |
| | 1791 | if((iFrameReadType&1 && iSize>1) &&\r |
| | 1792 | !(iDrawnSomething==2 &&\r |
| | 1793 | VRAMRead.x == VRAMWrite.x &&\r |
| | 1794 | VRAMRead.y == VRAMWrite.y &&\r |
| | 1795 | VRAMRead.Width == VRAMWrite.Width &&\r |
| | 1796 | VRAMRead.Height == VRAMWrite.Height))\r |
| | 1797 | CheckVRamRead(VRAMRead.x,VRAMRead.y,\r |
| | 1798 | VRAMRead.x+VRAMRead.RowsRemaining,\r |
| | 1799 | VRAMRead.y+VRAMRead.ColsRemaining,\r |
| | 1800 | TRUE);\r |
| | 1801 | \r |
| | 1802 | for(i=0;i<iSize;i++)\r |
| | 1803 | {\r |
| | 1804 | // do 2 seperate 16bit reads for compatibility (wrap issues)\r |
| | 1805 | if ((VRAMRead.ColsRemaining > 0) && (VRAMRead.RowsRemaining > 0))\r |
| | 1806 | {\r |
| | 1807 | // lower 16 bit\r |
| | 1808 | GPUdataRet=(unsigned long)*VRAMRead.ImagePtr;\r |
| | 1809 | \r |
| | 1810 | VRAMRead.ImagePtr++;\r |
| | 1811 | if(VRAMRead.ImagePtr>=psxVuw_eom) VRAMRead.ImagePtr-=iGPUHeight*1024;\r |
| | 1812 | VRAMRead.RowsRemaining --;\r |
| | 1813 | \r |
| | 1814 | if(VRAMRead.RowsRemaining<=0)\r |
| | 1815 | {\r |
| | 1816 | VRAMRead.RowsRemaining = VRAMRead.Width;\r |
| | 1817 | VRAMRead.ColsRemaining--;\r |
| | 1818 | VRAMRead.ImagePtr += 1024 - VRAMRead.Width;\r |
| | 1819 | if(VRAMRead.ImagePtr>=psxVuw_eom) VRAMRead.ImagePtr-=iGPUHeight*1024;\r |
| | 1820 | }\r |
| | 1821 | \r |
| | 1822 | // higher 16 bit (always, even if it's an odd width)\r |
| | 1823 | GPUdataRet|=(unsigned long)(*VRAMRead.ImagePtr)<<16;\r |
| | 1824 | *pMem++=GPUdataRet;\r |
| | 1825 | \r |
| | 1826 | if(VRAMRead.ColsRemaining <= 0)\r |
| | 1827 | {FinishedVRAMRead();goto ENDREAD;}\r |
| | 1828 | \r |
| | 1829 | VRAMRead.ImagePtr++;\r |
| | 1830 | if(VRAMRead.ImagePtr>=psxVuw_eom) VRAMRead.ImagePtr-=iGPUHeight*1024;\r |
| | 1831 | VRAMRead.RowsRemaining--;\r |
| | 1832 | if(VRAMRead.RowsRemaining<=0)\r |
| | 1833 | {\r |
| | 1834 | VRAMRead.RowsRemaining = VRAMRead.Width;\r |
| | 1835 | VRAMRead.ColsRemaining--;\r |
| | 1836 | VRAMRead.ImagePtr += 1024 - VRAMRead.Width;\r |
| | 1837 | if(VRAMRead.ImagePtr>=psxVuw_eom) VRAMRead.ImagePtr-=iGPUHeight*1024;\r |
| | 1838 | }\r |
| | 1839 | if(VRAMRead.ColsRemaining <= 0)\r |
| | 1840 | {FinishedVRAMRead();goto ENDREAD;}\r |
| | 1841 | }\r |
| | 1842 | else {FinishedVRAMRead();goto ENDREAD;}\r |
| | 1843 | }\r |
| | 1844 | \r |
| | 1845 | ENDREAD:\r |
| | 1846 | GPUIsIdle;\r |
| | 1847 | }\r |
| | 1848 | \r |
| | 1849 | unsigned long CALLBACK GPUreadData(void)\r |
| | 1850 | {\r |
| | 1851 | unsigned long l;\r |
| | 1852 | GPUreadDataMem(&l,1);\r |
| | 1853 | return GPUdataRet;\r |
| | 1854 | }\r |
| | 1855 | \r |
| | 1856 | ////////////////////////////////////////////////////////////////////////\r |
| | 1857 | // helper table to know how much data is used by drawing commands\r |
| | 1858 | ////////////////////////////////////////////////////////////////////////\r |
| | 1859 | \r |
| | 1860 | const unsigned char primTableCX[256] =\r |
| | 1861 | {\r |
| | 1862 | // 00\r |
| | 1863 | 0,0,3,0,0,0,0,0,\r |
| | 1864 | // 08\r |
| | 1865 | 0,0,0,0,0,0,0,0,\r |
| | 1866 | // 10\r |
| | 1867 | 0,0,0,0,0,0,0,0,\r |
| | 1868 | // 18\r |
| | 1869 | 0,0,0,0,0,0,0,0,\r |
| | 1870 | // 20\r |
| | 1871 | 4,4,4,4,7,7,7,7,\r |
| | 1872 | // 28\r |
| | 1873 | 5,5,5,5,9,9,9,9,\r |
| | 1874 | // 30\r |
| | 1875 | 6,6,6,6,9,9,9,9,\r |
| | 1876 | // 38\r |
| | 1877 | 8,8,8,8,12,12,12,12,\r |
| | 1878 | // 40\r |
| | 1879 | 3,3,3,3,0,0,0,0,\r |
| | 1880 | // 48\r |
| | 1881 | // 5,5,5,5,6,6,6,6, //FLINE\r |
| | 1882 | 254,254,254,254,254,254,254,254,\r |
| | 1883 | // 50\r |
| | 1884 | 4,4,4,4,0,0,0,0,\r |
| | 1885 | // 58\r |
| | 1886 | // 7,7,7,7,9,9,9,9, // LINEG3 LINEG4\r |
| | 1887 | 255,255,255,255,255,255,255,255,\r |
| | 1888 | // 60\r |
| | 1889 | 3,3,3,3,4,4,4,4, // TILE SPRT\r |
| | 1890 | // 68\r |
| | 1891 | 2,2,2,2,3,3,3,3, // TILE1\r |
| | 1892 | // 70\r |
| | 1893 | 2,2,2,2,3,3,3,3,\r |
| | 1894 | // 78\r |
| | 1895 | 2,2,2,2,3,3,3,3,\r |
| | 1896 | // 80\r |
| | 1897 | 4,0,0,0,0,0,0,0,\r |
| | 1898 | // 88\r |
| | 1899 | 0,0,0,0,0,0,0,0,\r |
| | 1900 | // 90\r |
| | 1901 | 0,0,0,0,0,0,0,0,\r |
| | 1902 | // 98\r |
| | 1903 | 0,0,0,0,0,0,0,0,\r |
| | 1904 | // a0\r |
| | 1905 | 3,0,0,0,0,0,0,0,\r |
| | 1906 | // a8\r |
| | 1907 | 0,0,0,0,0,0,0,0,\r |
| | 1908 | // b0\r |
| | 1909 | 0,0,0,0,0,0,0,0,\r |
| | 1910 | // b8\r |
| | 1911 | 0,0,0,0,0,0,0,0,\r |
| | 1912 | // c0\r |
| | 1913 | 3,0,0,0,0,0,0,0,\r |
| | 1914 | // c8\r |
| | 1915 | 0,0,0,0,0,0,0,0,\r |
| | 1916 | // d0\r |
| | 1917 | 0,0,0,0,0,0,0,0,\r |
| | 1918 | // d8\r |
| | 1919 | 0,0,0,0,0,0,0,0,\r |
| | 1920 | // e0\r |
| | 1921 | 0,1,1,1,1,1,1,0,\r |
| | 1922 | // e8\r |
| | 1923 | 0,0,0,0,0,0,0,0,\r |
| | 1924 | // f0\r |
| | 1925 | 0,0,0,0,0,0,0,0,\r |
| | 1926 | // f8\r |
| | 1927 | 0,0,0,0,0,0,0,0\r |
| | 1928 | };\r |
| | 1929 | \r |
| | 1930 | ////////////////////////////////////////////////////////////////////////\r |
| | 1931 | // processes data send to GPU data register\r |
| | 1932 | ////////////////////////////////////////////////////////////////////////\r |
| | 1933 | \r |
| | 1934 | void CALLBACK GPUwriteDataMem(unsigned long * pMem, int iSize)\r |
| | 1935 | {\r |
| | 1936 | unsigned char command;\r |
| | 1937 | unsigned long gdata=0;\r |
| | 1938 | int i=0;\r |
| | 1939 | GPUIsBusy;\r |
| | 1940 | GPUIsNotReadyForCommands;\r |
| | 1941 | \r |
| | 1942 | STARTVRAM:\r |
| | 1943 | \r |
| | 1944 | if(iDataWriteMode==DR_VRAMTRANSFER)\r |
| | 1945 | {\r |
| | 1946 | // make sure we are in vram\r |
| | 1947 | while(VRAMWrite.ImagePtr>=psxVuw_eom)\r |
| | 1948 | VRAMWrite.ImagePtr-=iGPUHeight*1024;\r |
| | 1949 | while(VRAMWrite.ImagePtr<psxVuw)\r |
| | 1950 | VRAMWrite.ImagePtr+=iGPUHeight*1024;\r |
| | 1951 | \r |
| | 1952 | // now do the loop\r |
| | 1953 | while(VRAMWrite.ColsRemaining>0)\r |
| | 1954 | {\r |
| | 1955 | while(VRAMWrite.RowsRemaining>0)\r |
| | 1956 | {\r |
| | 1957 | if(i>=iSize) {goto ENDVRAM;}\r |
| | 1958 | i++;\r |
| | 1959 | \r |
| | 1960 | gdata=*pMem++;\r |
| | 1961 | \r |
| | 1962 | *VRAMWrite.ImagePtr++ = (unsigned short)gdata;\r |
| | 1963 | if(VRAMWrite.ImagePtr>=psxVuw_eom) VRAMWrite.ImagePtr-=iGPUHeight*1024;\r |
| | 1964 | VRAMWrite.RowsRemaining --;\r |
| | 1965 | \r |
| | 1966 | if(VRAMWrite.RowsRemaining <= 0)\r |
| | 1967 | {\r |
| | 1968 | VRAMWrite.ColsRemaining--;\r |
| | 1969 | if (VRAMWrite.ColsRemaining <= 0) // last pixel is odd width\r |
| | 1970 | {\r |
| | 1971 | gdata=(gdata&0xFFFF)|(((unsigned long)(*VRAMWrite.ImagePtr))<<16);\r |
| | 1972 | FinishedVRAMWrite();\r |
| | 1973 | goto ENDVRAM;\r |
| | 1974 | }\r |
| | 1975 | VRAMWrite.RowsRemaining = VRAMWrite.Width;\r |
| | 1976 | VRAMWrite.ImagePtr += 1024 - VRAMWrite.Width;\r |
| | 1977 | }\r |
| | 1978 | \r |
| | 1979 | *VRAMWrite.ImagePtr++ = (unsigned short)(gdata>>16);\r |
| | 1980 | if(VRAMWrite.ImagePtr>=psxVuw_eom) VRAMWrite.ImagePtr-=iGPUHeight*1024;\r |
| | 1981 | VRAMWrite.RowsRemaining --;\r |
| | 1982 | }\r |
| | 1983 | \r |
| | 1984 | VRAMWrite.RowsRemaining = VRAMWrite.Width;\r |
| | 1985 | VRAMWrite.ColsRemaining--;\r |
| | 1986 | VRAMWrite.ImagePtr += 1024 - VRAMWrite.Width;\r |
| | 1987 | }\r |
| | 1988 | \r |
| | 1989 | FinishedVRAMWrite();\r |
| | 1990 | }\r |
| | 1991 | \r |
| | 1992 | ENDVRAM:\r |
| | 1993 | \r |
| | 1994 | if(iDataWriteMode==DR_NORMAL)\r |
| | 1995 | {\r |
| | 1996 | void (* *primFunc)(unsigned char *);\r |
| | 1997 | if(bSkipNextFrame) primFunc=primTableSkip;\r |
| | 1998 | else primFunc=primTableJ;\r |
| | 1999 | \r |
| | 2000 | for(;i<iSize;)\r |
| | 2001 | {\r |
| | 2002 | if(iDataWriteMode==DR_VRAMTRANSFER) goto STARTVRAM;\r |
| | 2003 | \r |
| | 2004 | gdata=*pMem++;i++;\r |
| | 2005 | \r |
| | 2006 | if(gpuDataC == 0)\r |
| | 2007 | {\r |
| | 2008 | command = (unsigned char)((gdata>>24) & 0xff);\r |
| | 2009 | \r |
| | 2010 | if(primTableCX[command])\r |
| | 2011 | {\r |
| | 2012 | gpuDataC = primTableCX[command];\r |
| | 2013 | gpuCommand = command;\r |
| | 2014 | gpuDataM[0] = gdata;\r |
| | 2015 | gpuDataP = 1;\r |
| | 2016 | }\r |
| | 2017 | else continue;\r |
| | 2018 | }\r |
| | 2019 | else\r |
| | 2020 | {\r |
| | 2021 | gpuDataM[gpuDataP] = gdata;\r |
| | 2022 | if(gpuDataC>128)\r |
| | 2023 | {\r |
| | 2024 | if((gpuDataC==254 && gpuDataP>=3) ||\r |
| | 2025 | (gpuDataC==255 && gpuDataP>=4 && !(gpuDataP&1)))\r |
| | 2026 | {\r |
| | 2027 | if((gpuDataM[gpuDataP] & 0xF000F000) == 0x50005000)\r |
| | 2028 | gpuDataP=gpuDataC-1;\r |
| | 2029 | }\r |
| | 2030 | }\r |
| | 2031 | gpuDataP++;\r |
| | 2032 | }\r |
| | 2033 | \r |
| | 2034 | if(gpuDataP == gpuDataC)\r |
| | 2035 | {\r |
| | 2036 | gpuDataC=gpuDataP=0;\r |
| | 2037 | primFunc[gpuCommand]((unsigned char *)gpuDataM);\r |
| | 2038 | \r |
| | 2039 | if(dwEmuFixes&0x0001 || dwActFixes&0x20000) // hack for emulating "gpu busy" in some games\r |
| | 2040 | iFakePrimBusy=4;\r |
| | 2041 | }\r |
| | 2042 | } \r |
| | 2043 | }\r |
| | 2044 | \r |
| | 2045 | GPUdataRet=gdata;\r |
| | 2046 | \r |
| | 2047 | GPUIsReadyForCommands;\r |
| | 2048 | GPUIsIdle; \r |
| | 2049 | }\r |
| | 2050 | \r |
| | 2051 | ////////////////////////////////////////////////////////////////////////\r |
| | 2052 | \r |
| | 2053 | void CALLBACK GPUwriteData(unsigned long gdata)\r |
| | 2054 | {\r |
| | 2055 | GPUwriteDataMem(&gdata,1);\r |
| | 2056 | }\r |
| | 2057 | \r |
| | 2058 | ////////////////////////////////////////////////////////////////////////\r |
| | 2059 | // this function will be removed soon (or 'soonish') (or never)\r |
| | 2060 | ////////////////////////////////////////////////////////////////////////\r |
| | 2061 | \r |
| | 2062 | void CALLBACK GPUsetMode(unsigned int gdata)\r |
| | 2063 | {\r |
| | 2064 | // ignore old psemu setmode:\r |
| | 2065 | \r |
| | 2066 | // imageTransfer = gdata;\r |
| | 2067 | // iDataWriteMode=(gdata&1)?DR_VRAMTRANSFER:DR_NORMAL;\r |
| | 2068 | // iDataReadMode =(gdata&2)?DR_VRAMTRANSFER:DR_NORMAL;\r |
| | 2069 | }\r |
| | 2070 | \r |
| | 2071 | // and this function will be removed soon as well, hehehe...\r |
| | 2072 | long CALLBACK GPUgetMode(void)\r |
| | 2073 | {\r |
| | 2074 | // ignore old psemu setmode\r |
| | 2075 | // return imageTransfer;\r |
| | 2076 | \r |
| | 2077 | long iT=0;\r |
| | 2078 | \r |
| | 2079 | if(iDataWriteMode==DR_VRAMTRANSFER) iT|=0x1;\r |
| | 2080 | if(iDataReadMode ==DR_VRAMTRANSFER) iT|=0x2;\r |
| | 2081 | \r |
| | 2082 | return iT;\r |
| | 2083 | }\r |
| | 2084 | \r |
| | 2085 | ////////////////////////////////////////////////////////////////////////\r |
| | 2086 | // call config dlg (Windows + Linux)\r |
| | 2087 | ////////////////////////////////////////////////////////////////////////\r |
| | 2088 | \r |
| | 2089 | #ifndef _WINDOWS\r |
| | 2090 | \r |
| | 2091 | /*#include <unistd.h>\r |
| | 2092 | \r |
| | 2093 | void StartCfgTool(char * pCmdLine) // linux: start external cfg tool\r |
| | 2094 | {\r |
| | 2095 | FILE * cf;char filename[255],t[255];\r |
| | 2096 | \r |
| | 2097 | strcpy(filename,"cfg/cfgPeopsMesaGL"); // look in cfg sub folder first\r |
| | 2098 | cf=fopen(filename,"rb");\r |
| | 2099 | if(cf!=NULL)\r |
| | 2100 | {\r |
| | 2101 | fclose(cf);\r |
| | 2102 | getcwd(t,255);\r |
| | 2103 | chdir("cfg");\r |
| | 2104 | sprintf(filename,"./cfgPeopsMesaGL %s",pCmdLine);\r |
| | 2105 | system(filename);\r |
| | 2106 | chdir(t);\r |
| | 2107 | }\r |
| | 2108 | else\r |
| | 2109 | {\r |
| | 2110 | strcpy(filename,"cfgPeopsMesaGL"); // look in current folder\r |
| | 2111 | cf=fopen(filename,"rb");\r |
| | 2112 | if(cf!=NULL)\r |
| | 2113 | {\r |
| | 2114 | fclose(cf);\r |
| | 2115 | sprintf(filename,"./cfgPeopsMesaGL %s",pCmdLine);\r |
| | 2116 | system(filename);\r |
| | 2117 | }\r |
| | 2118 | else\r |
| | 2119 | {\r |
| | 2120 | sprintf(filename,"%s/cfgPeopsMesaGL",getenv("HOME")); // look in home folder\r |
| | 2121 | cf=fopen(filename,"rb");\r |
| | 2122 | if(cf!=NULL)\r |
| | 2123 | {\r |
| | 2124 | fclose(cf);\r |
| | 2125 | getcwd(t,255);\r |
| | 2126 | chdir(getenv("HOME"));\r |
| | 2127 | sprintf(filename,"./cfgPeopsMesaGL %s",pCmdLine);\r |
| | 2128 | system(filename);\r |
| | 2129 | chdir(t);\r |
| | 2130 | }\r |
| | 2131 | else printf("cfgPeopsMesaGL not found!\n");\r |
| | 2132 | }\r |
| | 2133 | }\r |
| | 2134 | }\r |
| | 2135 | */\r |
| | 2136 | #endif\r |
| | 2137 | \r |
| | 2138 | \r |
| | 2139 | long CALLBACK GPUconfigure(void)\r |
| | 2140 | {\r |
| | 2141 | \r |
| | 2142 | \r |
| | 2143 | return 0;\r |
| | 2144 | }\r |
| | 2145 | \r |
| | 2146 | ////////////////////////////////////////////////////////////////////////\r |
| | 2147 | // sets all kind of act fixes\r |
| | 2148 | ////////////////////////////////////////////////////////////////////////\r |
| | 2149 | \r |
| | 2150 | void SetFixes(void)\r |
| | 2151 | {\r |
| | 2152 | ReInitFrameCap();\r |
| | 2153 | \r |
| | 2154 | if(dwActFixes & 0x2000) \r |
| | 2155 | dispWidths[4]=384;\r |
| | 2156 | else dispWidths[4]=368;\r |
| | 2157 | }\r |
| | 2158 | \r |
| | 2159 | ////////////////////////////////////////////////////////////////////////\r |
| | 2160 | // Pete Special: make an 'intelligent' dma chain check (<-Tekken3)\r |
| | 2161 | ////////////////////////////////////////////////////////////////////////\r |
| | 2162 | \r |
| | 2163 | unsigned long lUsedAddr[3];\r |
| | 2164 | \r |
| | 2165 | __inline BOOL CheckForEndlessLoop(unsigned long laddr)\r |
| | 2166 | {\r |
| | 2167 | if(laddr==lUsedAddr[1]) return TRUE;\r |
| | 2168 | if(laddr==lUsedAddr[2]) return TRUE;\r |
| | 2169 | \r |
| | 2170 | if(laddr<lUsedAddr[0]) lUsedAddr[1]=laddr;\r |
| | 2171 | else lUsedAddr[2]=laddr;\r |
| | 2172 | lUsedAddr[0]=laddr;\r |
| | 2173 | return FALSE;\r |
| | 2174 | }\r |
| | 2175 | \r |
| | 2176 | ////////////////////////////////////////////////////////////////////////\r |
| | 2177 | // core gives a dma chain to gpu: same as the gpuwrite interface funcs\r |
| | 2178 | ////////////////////////////////////////////////////////////////////////\r |
| | 2179 | \r |
| | 2180 | long CALLBACK GPUdmaChain(unsigned long * baseAddrL, unsigned long addr)\r |
| | 2181 | {\r |
| | 2182 | unsigned long dmaMem;\r |
| | 2183 | unsigned char * baseAddrB;\r |
| | 2184 | short count;unsigned int DMACommandCounter = 0;\r |
| | 2185 | \r |
| | 2186 | if(bIsFirstFrame) GLinitialize(NULL, NULL);\r |
| | 2187 | \r |
| | 2188 | GPUIsBusy;\r |
| | 2189 | \r |
| | 2190 | lUsedAddr[0]=lUsedAddr[1]=lUsedAddr[2]=0xffffff;\r |
| | 2191 | \r |
| | 2192 | baseAddrB = (unsigned char*) baseAddrL;\r |
| | 2193 | \r |
| | 2194 | do\r |
| | 2195 | {\r |
| | 2196 | if(iGPUHeight==512) addr&=0x1FFFFC;\r |
| | 2197 | \r |
| | 2198 | if(DMACommandCounter++ > 2000000) break;\r |
| | 2199 | if(CheckForEndlessLoop(addr)) break;\r |
| | 2200 | \r |
| | 2201 | count = baseAddrB[addr+3];\r |
| | 2202 | \r |
| | 2203 | dmaMem=addr+4;\r |
| | 2204 | \r |
| | 2205 | if(count>0) GPUwriteDataMem(&baseAddrL[dmaMem>>2],count);\r |
| | 2206 | \r |
| | 2207 | addr = baseAddrL[addr>>2]&0xffffff;\r |
| | 2208 | } while (!(addr & 0x800000)); // contrary to some documentation, the end-of-linked-list marker is not actually 0xFF'FFFF\r |
| | 2209 | // any pointer with bit 23 set will do.\r |
| | 2210 | GPUIsIdle;\r |
| | 2211 | \r |
| | 2212 | return 0;\r |
| | 2213 | }\r |
| | 2214 | \r |
| | 2215 | ////////////////////////////////////////////////////////////////////////\r |
| | 2216 | // show about dlg\r |
| | 2217 | ////////////////////////////////////////////////////////////////////////\r |
| | 2218 | \r |
| | 2219 | void CALLBACK GPUabout(void)\r |
| | 2220 | {\r |
| | 2221 | \r |
| | 2222 | }\r |
| | 2223 | \r |
| | 2224 | ////////////////////////////////////////////////////////////////////////\r |
| | 2225 | // We are ever fine ;)\r |
| | 2226 | ////////////////////////////////////////////////////////////////////////\r |
| | 2227 | \r |
| | 2228 | long CALLBACK GPUtest(void)\r |
| | 2229 | {\r |
| | 2230 | // if test fails this function should return negative value for error (unable to continue)\r |
| | 2231 | // and positive value for warning (can continue but output might be crappy)\r |
| | 2232 | \r |
| | 2233 | return 0;\r |
| | 2234 | }\r |
| | 2235 | \r |
| | 2236 | ////////////////////////////////////////////////////////////////////////\r |
| | 2237 | // save state funcs\r |
| | 2238 | ////////////////////////////////////////////////////////////////////////\r |
| | 2239 | \r |
| | 2240 | ////////////////////////////////////////////////////////////////////////\r |
| | 2241 | \r |
| | 2242 | long CALLBACK GPUfreeze(unsigned long ulGetFreezeData,GPUFreeze_t * pF)\r |
| | 2243 | {\r |
| | 2244 | if(ulGetFreezeData==2) \r |
| | 2245 | {\r |
| | 2246 | long lSlotNum=*((long *)pF);\r |
| | 2247 | if(lSlotNum<0) return 0;\r |
| | 2248 | if(lSlotNum>8) return 0;\r |
| | 2249 | lSelectedSlot=lSlotNum+1;\r |
| | 2250 | return 1;\r |
| | 2251 | }\r |
| | 2252 | \r |
| | 2253 | if(!pF) return 0; \r |
| | 2254 | if(pF->ulFreezeVersion!=1) return 0;\r |
| | 2255 | \r |
| | 2256 | if(ulGetFreezeData==1)\r |
| | 2257 | {\r |
| | 2258 | pF->ulStatus=STATUSREG;\r |
| | 2259 | memcpy(pF->ulControl,ulStatusControl,256*sizeof(unsigned long));\r |
| | 2260 | memcpy(pF->psxVRam, psxVub, 1024*iGPUHeight*2);\r |
| | 2261 | \r |
| | 2262 | return 1;\r |
| | 2263 | }\r |
| | 2264 | \r |
| | 2265 | if(ulGetFreezeData!=0) return 0;\r |
| | 2266 | \r |
| | 2267 | STATUSREG=pF->ulStatus;\r |
| | 2268 | memcpy(ulStatusControl,pF->ulControl,256*sizeof(unsigned long));\r |
| | 2269 | memcpy(psxVub, pF->psxVRam, 1024*iGPUHeight*2);\r |
| | 2270 | \r |
| | 2271 | ResetTextureArea(TRUE);\r |
| | 2272 | \r |
| | 2273 | GPUwriteStatus(ulStatusControl[0]);\r |
| | 2274 | GPUwriteStatus(ulStatusControl[1]);\r |
| | 2275 | GPUwriteStatus(ulStatusControl[2]);\r |
| | 2276 | GPUwriteStatus(ulStatusControl[3]);\r |
| | 2277 | GPUwriteStatus(ulStatusControl[8]);\r |
| | 2278 | GPUwriteStatus(ulStatusControl[6]);\r |
| | 2279 | GPUwriteStatus(ulStatusControl[7]);\r |
| | 2280 | GPUwriteStatus(ulStatusControl[5]);\r |
| | 2281 | GPUwriteStatus(ulStatusControl[4]);\r |
| | 2282 | return 1;\r |
| | 2283 | }\r |
| | 2284 | \r |
| | 2285 | ////////////////////////////////////////////////////////////////////////\r |
| | 2286 | // special "emu infos" / "emu effects" functions\r |
| | 2287 | ////////////////////////////////////////////////////////////////////////\r |
| | 2288 | \r |
| | 2289 | //00 = black\r |
| | 2290 | //01 = white\r |
| | 2291 | //10 = red\r |
| | 2292 | //11 = transparent\r |
| | 2293 | \r |
| | 2294 | unsigned char cFont[10][120]=\r |
| | 2295 | {\r |
| | 2296 | // 0\r |
| | 2297 | {0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,\r |
| | 2298 | 0x80,0x00,0x00,0x00,0x00,0x00,\r |
| | 2299 | 0x80,0x00,0x00,0x00,0x00,0x00,\r |
| | 2300 | 0x80,0x00,0x00,0x00,0x00,0x00,\r |
| | 2301 | 0x80,0x00,0x00,0x00,0x00,0x00,\r |
| | 2302 | 0x80,0x00,0x05,0x54,0x00,0x00,\r |
| | 2303 | 0x80,0x00,0x14,0x05,0x00,0x00,\r |
| | 2304 | 0x80,0x00,0x14,0x05,0x00,0x00,\r |
| | 2305 | 0x80,0x00,0x14,0x05,0x00,0x00,\r |
| | 2306 | 0x80,0x00,0x14,0x05,0x00,0x00,\r |
| | 2307 | 0x80,0x00,0x14,0x05,0x00,0x00,\r |
| | 2308 | 0x80,0x00,0x14,0x05,0x00,0x00,\r |
| | 2309 | 0x80,0x00,0x14,0x05,0x00,0x00,\r |
| | 2310 | 0x80,0x00,0x14,0x05,0x00,0x00,\r |
| | 2311 | 0x80,0x00,0x05,0x54,0x00,0x00,\r |
| | 2312 | 0x80,0x00,0x00,0x00,0x00,0x00,\r |
| | 2313 | 0x80,0x00,0x00,0x00,0x00,0x00,\r |
| | 2314 | 0x80,0x00,0x00,0x00,0x00,0x00,\r |
| | 2315 | 0x80,0x00,0x00,0x00,0x00,0x00,\r |
| | 2316 | 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa\r |
| | 2317 | },\r |
| | 2318 | // 1\r |
| | 2319 | {0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,\r |
| | 2320 | 0x80,0x00,0x00,0x00,0x00,0x00,\r |
| | 2321 | 0x80,0x00,0x00,0x00,0x00,0x00,\r |
| | 2322 | 0x80,0x00,0x00,0x00,0x00,0x00,\r |
| | 2323 | 0x80,0x00,0x00,0x00,0x00,0x00,\r |
| | 2324 | 0x80,0x00,0x00,0x50,0x00,0x00,\r |
| | 2325 | 0x80,0x00,0x05,0x50,0x00,0x00,\r |
| | 2326 | 0x80,0x00,0x00,0x50,0x00,0x00,\r |
| | 2327 | 0x80,0x00,0x00,0x50,0x00,0x00,\r |
| | 2328 | 0x80,0x00,0x00,0x50,0x00,0x00,\r |
| | 2329 | 0x80,0x00,0x00,0x50,0x00,0x00,\r |
| | 2330 | 0x80,0x00,0x00,0x50,0x00,0x00,\r |
| | 2331 | 0x80,0x00,0x00,0x50,0x00,0x00,\r |
| | 2332 | 0x80,0x00,0x00,0x50,0x00,0x00,\r |
| | 2333 | 0x80,0x00,0x05,0x55,0x00,0x00,\r |
| | 2334 | 0x80,0x00,0x00,0x00,0x00,0x00,\r |
| | 2335 | 0x80,0x00,0x00,0x00,0x00,0x00,\r |
| | 2336 | 0x80,0x00,0x00,0x00,0x00,0x00,\r |
| | 2337 | 0x80,0x00,0x00,0x00,0x00,0x00,\r |
| | 2338 | 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa\r |
| | 2339 | },\r |
| | 2340 | // 2\r |
| | 2341 | {0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,\r |
| | 2342 | 0x80,0x00,0x00,0x00,0x00,0x00,\r |
| | 2343 | 0x80,0x00,0x00,0x00,0x00,0x00,\r |
| | 2344 | 0x80,0x00,0x00,0x00,0x00,0x00,\r |
| | 2345 | 0x80,0x00,0x00,0x00,0x00,0x00,\r |
| | 2346 | 0x80,0x00,0x05,0x54,0x00,0x00,\r |
| | 2347 | 0x80,0x00,0x14,0x05,0x00,0x00,\r |
| | 2348 | 0x80,0x00,0x00,0x05,0x00,0x00,\r |
| | 2349 | 0x80,0x00,0x00,0x05,0x00,0x00,\r |
| | 2350 | 0x80,0x00,0x00,0x14,0x00,0x00,\r |
| | 2351 | 0x80,0x00,0x00,0x50,0x00,0x00,\r |
| | 2352 | 0x80,0x00,0x01,0x40,0x00,0x00,\r |
| | 2353 | 0x80,0x00,0x05,0x00,0x00,0x00,\r |
| | 2354 | 0x80,0x00,0x14,0x00,0x00,0x00,\r |
| | 2355 | 0x80,0x00,0x15,0x55,0x00,0x00,\r |
| | 2356 | 0x80,0x00,0x00,0x00,0x00,0x00,\r |
| | 2357 | 0x80,0x00,0x00,0x00,0x00,0x00,\r |
| | 2358 | 0x80,0x00,0x00,0x00,0x00,0x00,\r |
| | 2359 | 0x80,0x00,0x00,0x00,0x00,0x00,\r |
| | 2360 | 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa\r |
| | 2361 | },\r |
| | 2362 | // 3\r |
| | 2363 | {0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,\r |
| | 2364 | 0x80,0x00,0x00,0x00,0x00,0x00,\r |
| | 2365 | 0x80,0x00,0x00,0x00,0x00,0x00,\r |
| | 2366 | 0x80,0x00,0x00,0x00,0x00,0x00,\r |
| | 2367 | 0x80,0x00,0x00,0x00,0x00,0x00,\r |
| | 2368 | 0x80,0x00,0x05,0x54,0x00,0x00,\r |
| | 2369 | 0x80,0x00,0x14,0x05,0x00,0x00,\r |
| | 2370 | 0x80,0x00,0x00,0x05,0x00,0x00,\r |
| | 2371 | 0x80,0x00,0x00,0x05,0x00,0x00,\r |
| | 2372 | 0x80,0x00,0x01,0x54,0x00,0x00,\r |
| | 2373 | 0x80,0x00,0x00,0x05,0x00,0x00,\r |
| | 2374 | 0x80,0x00,0x00,0x05,0x00,0x00,\r |
| | 2375 | 0x80,0x00,0x00,0x05,0x00,0x00,\r |
| | 2376 | 0x80,0x00,0x14,0x05,0x00,0x00,\r |
| | 2377 | 0x80,0x00,0x05,0x54,0x00,0x00,\r |
| | 2378 | 0x80,0x00,0x00,0x00,0x00,0x00,\r |
| | 2379 | 0x80,0x00,0x00,0x00,0x00,0x00,\r |
| | 2380 | 0x80,0x00,0x00,0x00,0x00,0x00,\r |
| | 2381 | 0x80,0x00,0x00,0x00,0x00,0x00,\r |
| | 2382 | 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa\r |
| | 2383 | },\r |
| | 2384 | // 4\r |
| | 2385 | {0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,\r |
| | 2386 | 0x80,0x00,0x00,0x00,0x00,0x00,\r |
| | 2387 | 0x80,0x00,0x00,0x00,0x00,0x00,\r |
| | 2388 | 0x80,0x00,0x00,0x00,0x00,0x00,\r |
| | 2389 | 0x80,0x00,0x00,0x00,0x00,0x00,\r |
| | 2390 | 0x80,0x00,0x00,0x14,0x00,0x00,\r |
| | 2391 | 0x80,0x00,0x00,0x54,0x00,0x00,\r |
| | 2392 | 0x80,0x00,0x01,0x54,0x00,0x00,\r |
| | 2393 | 0x80,0x00,0x01,0x54,0x00,0x00,\r |
| | 2394 | 0x80,0x00,0x05,0x14,0x00,0x00,\r |
| | 2395 | 0x80,0x00,0x14,0x14,0x00,0x00,\r |
| | 2396 | 0x80,0x00,0x15,0x55,0x00,0x00,\r |
| | 2397 | 0x80,0x00,0x00,0x14,0x00,0x00,\r |
| | 2398 | 0x80,0x00,0x00,0x14,0x00,0x00,\r |
| | 2399 | 0x80,0x00,0x00,0x55,0x00,0x00,\r |
| | 2400 | 0x80,0x00,0x00,0x00,0x00,0x00,\r |
| | 2401 | 0x80,0x00,0x00,0x00,0x00,0x00,\r |
| | 2402 | 0x80,0x00,0x00,0x00,0x00,0x00,\r |
| | 2403 | 0x80,0x00,0x00,0x00,0x00,0x00,\r |
| | 2404 | 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa\r |
| | 2405 | },\r |
| | 2406 | // 5\r |
| | 2407 | {0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,\r |
| | 2408 | 0x80,0x00,0x00,0x00,0x00,0x00,\r |
| | 2409 | 0x80,0x00,0x00,0x00,0x00,0x00,\r |
| | 2410 | 0x80,0x00,0x00,0x00,0x00,0x00,\r |
| | 2411 | 0x80,0x00,0x00,0x00,0x00,0x00,\r |
| | 2412 | 0x80,0x00,0x15,0x55,0x00,0x00,\r |
| | 2413 | 0x80,0x00,0x14,0x00,0x00,0x00,\r |
| | 2414 | 0x80,0x00,0x14,0x00,0x00,0x00,\r |
| | 2415 | 0x80,0x00,0x14,0x00,0x00,0x00,\r |
| | 2416 | 0x80,0x00,0x15,0x54,0x00,0x00,\r |
| | 2417 | 0x80,0x00,0x00,0x05,0x00,0x00,\r |
| | 2418 | 0x80,0x00,0x00,0x05,0x00,0x00,\r |
| | 2419 | 0x80,0x00,0x00,0x05,0x00,0x00,\r |
| | 2420 | 0x80,0x00,0x14,0x05,0x00,0x00,\r |
| | 2421 | 0x80,0x00,0x05,0x54,0x00,0x00,\r |
| | 2422 | 0x80,0x00,0x00,0x00,0x00,0x00,\r |
| | 2423 | 0x80,0x00,0x00,0x00,0x00,0x00,\r |
| | 2424 | 0x80,0x00,0x00,0x00,0x00,0x00,\r |
| | 2425 | 0x80,0x00,0x00,0x00,0x00,0x00,\r |
| | 2426 | 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa\r |
| | 2427 | },\r |
| | 2428 | // 6\r |
| | 2429 | {0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,\r |
| | 2430 | 0x80,0x00,0x00,0x00,0x00,0x00,\r |
| | 2431 | 0x80,0x00,0x00,0x00,0x00,0x00,\r |
| | 2432 | 0x80,0x00,0x00,0x00,0x00,0x00,\r |
| | 2433 | 0x80,0x00,0x00,0x00,0x00,0x00,\r |
| | 2434 | 0x80,0x00,0x01,0x54,0x00,0x00,\r |
| | 2435 | 0x80,0x00,0x05,0x00,0x00,0x00,\r |
| | 2436 | 0x80,0x00,0x14,0x00,0x00,0x00,\r |
| | 2437 | 0x80,0x00,0x14,0x00,0x00,0x00,\r |
| | 2438 | 0x80,0x00,0x15,0x54,0x00,0x00,\r |
| | 2439 | 0x80,0x00,0x15,0x05,0x00,0x00,\r |
| | 2440 | 0x80,0x00,0x14,0x05,0x00,0x00,\r |
| | 2441 | 0x80,0x00,0x14,0x05,0x00,0x00,\r |
| | 2442 | 0x80,0x00,0x14,0x05,0x00,0x00,\r |
| | 2443 | 0x80,0x00,0x05,0x54,0x00,0x00,\r |
| | 2444 | 0x80,0x00,0x00,0x00,0x00,0x00,\r |
| | 2445 | 0x80,0x00,0x00,0x00,0x00,0x00,\r |
| | 2446 | 0x80,0x00,0x00,0x00,0x00,0x00,\r |
| | 2447 | 0x80,0x00,0x00,0x00,0x00,0x00,\r |
| | 2448 | 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa\r |
| | 2449 | },\r |
| | 2450 | // 7\r |
| | 2451 | {0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,\r |
| | 2452 | 0x80,0x00,0x00,0x00,0x00,0x00,\r |
| | 2453 | 0x80,0x00,0x00,0x00,0x00,0x00,\r |
| | 2454 | 0x80,0x00,0x00,0x00,0x00,0x00,\r |
| | 2455 | 0x80,0x00,0x00,0x00,0x00,0x00,\r |
| | 2456 | 0x80,0x00,0x15,0x55,0x00,0x00,\r |
| | 2457 | 0x80,0x00,0x14,0x05,0x00,0x00,\r |
| | 2458 | 0x80,0x00,0x00,0x14,0x00,0x00,\r |
| | 2459 | 0x80,0x00,0x00,0x14,0x00,0x00,\r |
| | 2460 | 0x80,0x00,0x00,0x50,0x00,0x00,\r |
| | 2461 | 0x80,0x00,0x00,0x50,0x00,0x00,\r |
| | 2462 | 0x80,0x00,0x01,0x40,0x00,0x00,\r |
| | 2463 | 0x80,0x00,0x01,0x40,0x00,0x00,\r |
| | 2464 | 0x80,0x00,0x05,0x00,0x00,0x00,\r |
| | 2465 | 0x80,0x00,0x05,0x00,0x00,0x00,\r |
| | 2466 | 0x80,0x00,0x00,0x00,0x00,0x00,\r |
| | 2467 | 0x80,0x00,0x00,0x00,0x00,0x00,\r |
| | 2468 | 0x80,0x00,0x00,0x00,0x00,0x00,\r |
| | 2469 | 0x80,0x00,0x00,0x00,0x00,0x00,\r |
| | 2470 | 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa\r |
| | 2471 | },\r |
| | 2472 | // 8\r |
| | 2473 | {0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,\r |
| | 2474 | 0x80,0x00,0x00,0x00,0x00,0x00,\r |
| | 2475 | 0x80,0x00,0x00,0x00,0x00,0x00,\r |
| | 2476 | 0x80,0x00,0x00,0x00,0x00,0x00,\r |
| | 2477 | 0x80,0x00,0x00,0x00,0x00,0x00,\r |
| | 2478 | 0x80,0x00,0x05,0x54,0x00,0x00,\r |
| | 2479 | 0x80,0x00,0x14,0x05,0x00,0x00,\r |
| | 2480 | 0x80,0x00,0x14,0x05,0x00,0x00,\r |
| | 2481 | 0x80,0x00,0x14,0x05,0x00,0x00,\r |
| | 2482 | 0x80,0x00,0x05,0x54,0x00,0x00,\r |
| | 2483 | 0x80,0x00,0x14,0x05,0x00,0x00,\r |
| | 2484 | 0x80,0x00,0x14,0x05,0x00,0x00,\r |
| | 2485 | 0x80,0x00,0x14,0x05,0x00,0x00,\r |
| | 2486 | 0x80,0x00,0x14,0x05,0x00,0x00,\r |
| | 2487 | 0x80,0x00,0x05,0x54,0x00,0x00,\r |
| | 2488 | 0x80,0x00,0x00,0x00,0x00,0x00,\r |
| | 2489 | 0x80,0x00,0x00,0x00,0x00,0x00,\r |
| | 2490 | 0x80,0x00,0x00,0x00,0x00,0x00,\r |
| | 2491 | 0x80,0x00,0x00,0x00,0x00,0x00,\r |
| | 2492 | 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa\r |
| | 2493 | },\r |
| | 2494 | // 9\r |
| | 2495 | {0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,\r |
| | 2496 | 0x80,0x00,0x00,0x00,0x00,0x00,\r |
| | 2497 | 0x80,0x00,0x00,0x00,0x00,0x00,\r |
| | 2498 | 0x80,0x00,0x00,0x00,0x00,0x00,\r |
| | 2499 | 0x80,0x00,0x00,0x00,0x00,0x00,\r |
| | 2500 | 0x80,0x00,0x05,0x54,0x00,0x00,\r |
| | 2501 | 0x80,0x00,0x14,0x05,0x00,0x00,\r |
| | 2502 | 0x80,0x00,0x14,0x05,0x00,0x00,\r |
| | 2503 | 0x80,0x00,0x14,0x05,0x00,0x00,\r |
| | 2504 | 0x80,0x00,0x14,0x15,0x00,0x00,\r |
| | 2505 | 0x80,0x00,0x05,0x55,0x00,0x00,\r |
| | 2506 | 0x80,0x00,0x00,0x05,0x00,0x00,\r |
| | 2507 | 0x80,0x00,0x00,0x05,0x00,0x00,\r |
| | 2508 | 0x80,0x00,0x00,0x14,0x00,0x00,\r |
| | 2509 | 0x80,0x00,0x05,0x50,0x00,0x00,\r |
| | 2510 | 0x80,0x00,0x00,0x00,0x00,0x00,\r |
| | 2511 | 0x80,0x00,0x00,0x00,0x00,0x00,\r |
| | 2512 | 0x80,0x00,0x00,0x00,0x00,0x00,\r |
| | 2513 | 0x80,0x00,0x00,0x00,0x00,0x00,\r |
| | 2514 | 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa\r |
| | 2515 | }\r |
| | 2516 | };\r |
| | 2517 | \r |
| | 2518 | ////////////////////////////////////////////////////////////////////////\r |
| | 2519 | \r |
| | 2520 | void PaintPicDot(unsigned char * p,unsigned char c)\r |
| | 2521 | {\r |
| | 2522 | if(c==0) {*p++=0x00;*p++=0x00;*p=0x00;return;}\r |
| | 2523 | if(c==1) {*p++=0xff;*p++=0xff;*p=0xff;return;}\r |
| | 2524 | if(c==2) {*p++=0x00;*p++=0x00;*p=0xff;return;}\r |
| | 2525 | }\r |
| | 2526 | \r |
| | 2527 | ////////////////////////////////////////////////////////////////////////\r |
| | 2528 | \r |
| | 2529 | long CALLBACK GPUgetScreenPic(unsigned char * pMem)\r |
| | 2530 | {\r |
| | 2531 | float XS,YS;int x,y,v;\r |
| | 2532 | unsigned char * ps, * px, * pf;\r |
| | 2533 | unsigned char c;\r |
| | 2534 | \r |
| | 2535 | if(!pGfxCardScreen)\r |
| | 2536 | {\r |
| | 2537 | glPixelStorei(GL_PACK_ALIGNMENT,1); glError();\r |
| | 2538 | pGfxCardScreen=(unsigned char *)malloc(iResX*iResY*4);\r |
| | 2539 | }\r |
| | 2540 | \r |
| | 2541 | ps=pGfxCardScreen;\r |
| | 2542 | \r |
| | 2543 | // glReadBuffer(GL_FRONT);\r |
| | 2544 | \r |
| | 2545 | glReadPixels(0,0,iResX,iResY,GL_RGB,GL_UNSIGNED_BYTE,ps); glError();\r |
| | 2546 | \r |
| | 2547 | // glReadBuffer(GL_BACK);\r |
| | 2548 | \r |
| | 2549 | XS=(float)iResX/128;\r |
| | 2550 | YS=(float)iResY/96;\r |
| | 2551 | pf=pMem;\r |
| | 2552 | \r |
| | 2553 | for(y=96;y>0;y--)\r |
| | 2554 | {\r |
| | 2555 | for(x=0;x<128;x++)\r |
| | 2556 | {\r |
| | 2557 | px=ps+(3*((int)((float)x * XS))+\r |
| | 2558 | (3*iResX)*((int)((float)y*YS)));\r |
| | 2559 | *(pf+0)=*(px+2);\r |
| | 2560 | *(pf+1)=*(px+1);\r |
| | 2561 | *(pf+2)=*(px+0);\r |
| | 2562 | pf+=3;\r |
| | 2563 | }\r |
| | 2564 | }\r |
| | 2565 | \r |
| | 2566 | /////////////////////////////////////////////////////////////////////\r |
| | 2567 | // generic number/border painter\r |
| | 2568 | \r |
| | 2569 | pf=pMem+(103*3);\r |
| | 2570 | \r |
| | 2571 | for(y=0;y<20;y++)\r |
| | 2572 | {\r |
| | 2573 | for(x=0;x<6;x++)\r |
| | 2574 | {\r |
| | 2575 | c=cFont[lSelectedSlot][x+y*6];\r |
| | 2576 | v=(c&0xc0)>>6;\r |
| | 2577 | PaintPicDot(pf,(unsigned char)v);pf+=3; // paint the dots into the rect\r |
| | 2578 | v=(c&0x30)>>4;\r |
| | 2579 | PaintPicDot(pf,(unsigned char)v);pf+=3;\r |
| | 2580 | v=(c&0x0c)>>2;\r |
| | 2581 | PaintPicDot(pf,(unsigned char)v);pf+=3;\r |
| | 2582 | v=c&0x03;\r |
| | 2583 | PaintPicDot(pf,(unsigned char)v);pf+=3;\r |
| | 2584 | }\r |
| | 2585 | pf+=104*3;\r |
| | 2586 | }\r |
| | 2587 | \r |
| | 2588 | pf=pMem;\r |
| | 2589 | for(x=0;x<128;x++)\r |
| | 2590 | {\r |
| | 2591 | *(pf+(95*128*3))=0x00;*pf++=0x00;\r |
| | 2592 | *(pf+(95*128*3))=0x00;*pf++=0x00;\r |
| | 2593 | *(pf+(95*128*3))=0xff;*pf++=0xff;\r |
| | 2594 | }\r |
| | 2595 | pf=pMem;\r |
| | 2596 | for(y=0;y<96;y++)\r |
| | 2597 | {\r |
| | 2598 | *(pf+(127*3))=0x00;*pf++=0x00;\r |
| | 2599 | *(pf+(127*3))=0x00;*pf++=0x00;\r |
| | 2600 | *(pf+(127*3))=0xff;*pf++=0xff;\r |
| | 2601 | pf+=127*3;\r |
| | 2602 | }\r |
| | 2603 | \r |
| | 2604 | }\r |
| | 2605 | \r |
| | 2606 | ////////////////////////////////////////////////////////////////////////\r |
| | 2607 | \r |
| | 2608 | long CALLBACK GPUshowScreenPic(unsigned char * pMem)\r |
| | 2609 | {\r |
| | 2610 | // DestroyPic();\r |
| | 2611 | // if(pMem==0) return;\r |
| | 2612 | // CreatePic(pMem);\r |
| | 2613 | }\r |
| | 2614 | \r |
| | 2615 | ////////////////////////////////////////////////////////////////////////\r |
| | 2616 | \r |
| | 2617 | void CALLBACK GPUsetfix(unsigned long dwFixBits)\r |
| | 2618 | {\r |
| | 2619 | dwEmuFixes=dwFixBits;\r |
| | 2620 | }\r |
| | 2621 | \r |
| | 2622 | ////////////////////////////////////////////////////////////////////////\r |
| | 2623 | \r |
| | 2624 | void CALLBACK GPUvisualVibration(unsigned long iSmall, unsigned long iBig)\r |
| | 2625 | {\r |
| | 2626 | int iVibVal;\r |
| | 2627 | \r |
| | 2628 | if(PSXDisplay.DisplayModeNew.x) // calc min "shake pixel" from screen width\r |
| | 2629 | iVibVal=max(1,iResX/PSXDisplay.DisplayModeNew.x);\r |
| | 2630 | else iVibVal=1;\r |
| | 2631 | // big rumble: 4...15 sp ; small rumble 1...3 sp\r |
| | 2632 | if(iBig) iRumbleVal=max(4*iVibVal,min(15*iVibVal,((int)iBig *iVibVal)/10));\r |
| | 2633 | else iRumbleVal=max(1*iVibVal,min( 3*iVibVal,((int)iSmall*iVibVal)/10));\r |
| | 2634 | \r |
| | 2635 | srand(timeGetTime()); // init rand (will be used in BufferSwap)\r |
| | 2636 | \r |
| | 2637 | iRumbleTime=15; // let the rumble last 16 buffer swaps\r |
| | 2638 | }\r |
| | 2639 | \r |
| | 2640 | ////////////////////////////////////////////////////////////////////////\r |
| | 2641 | // main emu can set display infos (A/M/G/D) \r |
| | 2642 | ////////////////////////////////////////////////////////////////////////\r |
| | 2643 | \r |
| | 2644 | void CALLBACK GPUdisplayFlags(unsigned long dwFlags)\r |
| | 2645 | {\r |
| | 2646 | // dwCoreFlags=dwFlags;\r |
| | 2647 | }\r |
| | 2648 | \r |
| | 2649 | // pcsx-rearmed callbacks\r |
| | 2650 | void CALLBACK GPUrearmedCallbacks(const void **cbs)\r |
| | 2651 | {\r |
| | 2652 | rearmed_get_layer_pos = cbs[0];\r |
| | 2653 | }\r |
| | 2654 | \r |
| | 2655 | static void flipEGL(void)\r |
| | 2656 | {\r |
| | 2657 | eglSwapBuffers(display, surface);\r |
| | 2658 | }\r |