diff options
| author | SND\weimingzhi_cp <SND\weimingzhi_cp@e17a0e51-4ae3-4d35-97c3-1a29b211df97> | 2011-03-13 08:26:16 +0000 |
|---|---|---|
| committer | SND\weimingzhi_cp <SND\weimingzhi_cp@e17a0e51-4ae3-4d35-97c3-1a29b211df97> | 2011-03-13 08:26:16 +0000 |
| commit | 379a8879f7dae1a9074317c0270e12dd203b32c0 (patch) | |
| tree | 348efb7ecd4f7cbc030f4b5db6683a857f2ae6cf /plugins/peopsxgl | |
| parent | d34b4220bde29d7937d927e9d17a50470a36c500 (diff) | |
| download | pcsxr-379a8879f7dae1a9074317c0270e12dd203b32c0.tar.gz | |
Temporarily reverted r64524 until I (or someone else) find the time to sort out the stuff.
git-svn-id: https://pcsxr.svn.codeplex.com/svn/pcsxr@64536 e17a0e51-4ae3-4d35-97c3-1a29b211df97
Diffstat (limited to 'plugins/peopsxgl')
| -rw-r--r-- | plugins/peopsxgl/draw.c | 3316 | ||||
| -rw-r--r-- | plugins/peopsxgl/fps.c | 795 | ||||
| -rw-r--r-- | plugins/peopsxgl/gpu.c | 7056 | ||||
| -rw-r--r-- | plugins/peopsxgl/gpu.h | 83 | ||||
| -rw-r--r-- | plugins/peopsxgl/gpucfg/main.c | 1470 | ||||
| -rw-r--r-- | plugins/peopsxgl/key.c | 356 | ||||
| -rw-r--r-- | plugins/peopsxgl/prim.c | 9323 | ||||
| -rw-r--r-- | plugins/peopsxgl/soft.c | 16816 | ||||
| -rw-r--r-- | plugins/peopsxgl/texture.c | 9842 | ||||
| -rw-r--r-- | plugins/peopsxgl/texture.h | 137 |
10 files changed, 24588 insertions, 24606 deletions
diff --git a/plugins/peopsxgl/draw.c b/plugins/peopsxgl/draw.c index 36bcf360..748824a1 100644 --- a/plugins/peopsxgl/draw.c +++ b/plugins/peopsxgl/draw.c @@ -1,1658 +1,1658 @@ -/*************************************************************************** - draw.c - description - ------------------- - begin : Sun Mar 08 2009 - copyright : (C) 1999-2009 by Pete Bernert - web : www.pbernert.com - ***************************************************************************/ - -/*************************************************************************** - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. See also the license.txt file for * - * additional informations. * - * * - ***************************************************************************/ - -#include "stdafx.h" - -#define _IN_DRAW - -#include "externals.h" -#include "gpu.h" -#include "draw.h" -#include "prim.h" -#include "texture.h" -#include "menu.h" - -#if defined(_MACGL) -// if you use it, you must include it -#include <OpenGL/gl.h> -#include <OpenGL/glext.h> -#endif -//////////////////////////////////////////////////////////////////////////////////// -// defines - -#define SIGNBIT 0x800 -#define S_MASK 0xf000 -#define L_MASK 0xfffff000 - -// ownscale: some ogl drivers have buggy texture matrix funcs, so it -// is safer to calc sow/tow ourselves - -#ifdef OWNSCALE - -#define ST_FACSPRITE 255.99f -#define ST_BFFACSPRITE 0.5f/256.0f -#define ST_BFFACSPRITESORT 0.333f/256.0f - -#define ST_OFFSET 0.5f/256.0f; - -#define ST_FAC 255.99f -#define ST_BFFAC 0.5f/256.0f -#define ST_BFFACSORT 0.333f/256.0f - -#define ST_FACTRI 255.99f -#define ST_BFFACTRI 0.5f/256.0f -#define ST_BFFACTRISORT 0.333f/256.0f - -#define ST_FACVRAMX 255.0f -#define ST_FACVRAM 256.0f - -/////////////////////////////////////////////////////////////// - -#else - -#define ST_BFFACSPRITE 0.5f -#define ST_BFFACSPRITESORT 0.333f - -#define ST_BFFAC 0.5f -#define ST_BFFACSORT 0.333f - -#define ST_BFFACTRI 0.5f -#define ST_BFFACTRISORT 0.333f - -#define ST_OFFSET 0.5f; - -#endif - -//////////////////////////////////////////////////////////////////////////////////// -// draw globals; most will be initialized again later (by config or checks) - -#ifdef _WINDOWS -HDC dcGlobal = NULL; -HWND hWWindow; -#endif - -BOOL bIsFirstFrame = TRUE; - -// resolution/ratio vars - -int iResX; -int iResY; -BOOL bKeepRatio = FALSE; -RECT rRatioRect; - -// psx mask related vars - -BOOL bCheckMask = FALSE; -int iUseMask = 0; -int iSetMask = 0; -unsigned short sSetMask = 0; -uint32_t lSetMask = 0; - -// drawing/coord vars - -OGLVertex vertex[4]; -GLubyte gl_ux[8]; -GLubyte gl_vy[8]; -short sprtY,sprtX,sprtH,sprtW; - -// drawing options - -BOOL bOpaquePass; -BOOL bAdvancedBlend; -BOOL bUseLines; -BOOL bUseAntiAlias; -int iTexQuality; -int iUsePalTextures=1; -BOOL bSnapShot=FALSE; -BOOL bSmallAlpha=FALSE; -int iShowFPS=0; - -// OGL extension support - -int iForceVSync=-1; -int iUseExts=0; -BOOL bGLExt; -BOOL bGLFastMovie=FALSE; -BOOL bGLSoft; -BOOL bGLBlend; -#if defined (_MACGL) // always supported on OSX > 10.4.3 -#define glBlendEquationEXTEx glBlendEquationEXT -#define glColorTableEXTEx glColorTableEXT -#else -PFNGLBLENDEQU glBlendEquationEXTEx=NULL; -PFNGLCOLORTABLEEXT glColorTableEXTEx=NULL; -#endif -// gfx card buffer infos - -int iDepthFunc=0; -int iZBufferDepth=0; -GLbitfield uiBufferBits=GL_COLOR_BUFFER_BIT; - -//////////////////////////////////////////////////////////////////////// -// Set OGL pixel format -//////////////////////////////////////////////////////////////////////// - -#ifdef _WINDOWS -BOOL bSetupPixelFormat(HDC hDC) -{ - int pixelformat; - static PIXELFORMATDESCRIPTOR pfd = - { - sizeof(PIXELFORMATDESCRIPTOR), // size of this pfd - 1, // version number - PFD_DRAW_TO_WINDOW | // support window - PFD_SUPPORT_OPENGL | // support OpenGL - PFD_DOUBLEBUFFER, // double buffered - PFD_TYPE_RGBA, // RGBA type - 16, // 16-bit color depth (adjusted later) - 0, 0, 0, 0, 0, 0, // color bits ignored - 0, // no alpha buffer - 0, // shift bit ignored - 0, // no accumulation buffer - 0, 0, 0, 0, // accum bits ignored - 0, // z-buffer - 0, - 0, // no auxiliary buffer - PFD_MAIN_PLANE, // main layer - 0, // reserved - 0, 0, 0 // layer masks ignored - }; - - pfd.cColorBits=iColDepth; // set user color depth - pfd.cDepthBits=iZBufferDepth; // set user zbuffer (by psx mask) - - if((pixelformat=ChoosePixelFormat(hDC,&pfd))==0) - { - MessageBox(NULL,"ChoosePixelFormat failed","Error",MB_OK); - return FALSE; - } - - if(SetPixelFormat(hDC,pixelformat, &pfd)==FALSE) - { - MessageBox(NULL,"SetPixelFormat failed","Error",MB_OK); - return FALSE; - } - - return TRUE; -} -#endif - -//////////////////////////////////////////////////////////////////////// -// Get extension infos (f.e. pal textures / packed pixels) -//////////////////////////////////////////////////////////////////////// - -static void GetExtInfos(void) -{ - BOOL bPacked=FALSE; // default: no packed pixel support - - bGLExt=FALSE; // default: no extensions - bGLFastMovie=FALSE; - - if(strstr((char *)glGetString(GL_EXTENSIONS), // packed pixels available? - "GL_EXT_packed_pixels")) - bPacked=TRUE; // -> ok - - if(bPacked && bUse15bitMdec) // packed available and 15bit mdec wanted? - bGLFastMovie=TRUE; // -> ok - - if(bPacked && (iTexQuality==1 || iTexQuality==2)) // packed available and 16 bit texture format? - { - bGLFastMovie=TRUE; // -> ok - bGLExt=TRUE; - } - - if(iUseExts && // extension support wanted? - (strstr((char *)glGetString(GL_EXTENSIONS), - "GL_EXT_texture_edge_clamp") || - strstr((char *)glGetString(GL_EXTENSIONS), // -> check clamp support, if yes: use it - "GL_SGIS_texture_edge_clamp"))) - iClampType=GL_TO_EDGE_CLAMP; - else iClampType=GL_CLAMP; - -#if !defined (_MACGL) // OSX > 10.4.3 defines this - glColorTableEXTEx=(PFNGLCOLORTABLEEXT)NULL; // init ogl palette func pointer -#endif - -#ifndef __sun - if(iGPUHeight!=1024 && // no pal textures in ZN mode (height=1024)! - strstr((char *)glGetString(GL_EXTENSIONS), // otherwise: check ogl support - "GL_EXT_paletted_texture")) - { - iUsePalTextures=1; // -> wow, supported, get func pointer - -#ifdef _WINDOWS - glColorTableEXTEx=(PFNGLCOLORTABLEEXT)wglGetProcAddress("glColorTableEXT"); -#elif defined (_MACGL) - // no prob, done already in OSX > 10.4.3 -#else - glColorTableEXTEx=(PFNGLCOLORTABLEEXT)glXGetProcAddress((GLubyte *)"glColorTableEXT"); -#endif - - if(glColorTableEXTEx==NULL) iUsePalTextures=0; // -> ha, cheater... no func, no support - - } - else iUsePalTextures=0; -#else - iUsePalTextures=0; -#endif -} - -//////////////////////////////////////////////////////////////////////// -// Setup some stuff depending on user settings or in-game toggle -//////////////////////////////////////////////////////////////////////// - -void SetExtGLFuncs(void) -{ - //----------------------------------------------------// - - SetFixes(); // update fix infos - - //----------------------------------------------------// - -#ifdef _WINDOWS - if((iForceVSync>=0) && // force vsync? - strstr((char *)glGetString(GL_EXTENSIONS), // and extension available? - "WGL_EXT_swap_control")) - { - PFNWGLSWAPINTERVALFARPROC wglSwapIntervalEXT= - (PFNWGLSWAPINTERVALFARPROC)wglGetProcAddress("wglSwapIntervalEXT"); - - if(wglSwapIntervalEXT) wglSwapIntervalEXT(iForceVSync); - } -#endif -#ifdef _MACGL - SetVSync(iForceVSync); -#endif - if(iUseExts && !(dwActFixes&1024) && // extensions wanted? and not turned off by game fix? - strstr((char *)glGetString(GL_EXTENSIONS), // and blend_subtract available? - "GL_EXT_blend_subtract")) - { // -> get ogl blend function pointer -#ifdef _WINDOWS - glBlendEquationEXTEx=(PFNGLBLENDEQU)wglGetProcAddress("glBlendEquationEXT"); -#elif defined(_MACGL) - // no prob, OSX > 10.4.3 has this -#else - glBlendEquationEXTEx=(PFNGLBLENDEQU)glXGetProcAddress((GLubyte *)"glBlendEquationEXT"); -#endif - } - else // no subtract blending? - { - if(glBlendEquationEXTEx) // -> change to additive blending (if subract was active) - glBlendEquationEXTEx(FUNC_ADD_EXT); -#if !defined(_MACGL) // BTW, why set to null? strange... - glBlendEquationEXTEx=(PFNGLBLENDEQU)NULL; // -> no more blend function pointer -#endif - } - - //----------------------------------------------------// - - if(iUseExts && bAdvancedBlend && // advanced blending wanted ? - strstr((char *)glGetString(GL_EXTENSIONS), // and extension avail? - "GL_EXT_texture_env_combine")) - { - bUseMultiPass=FALSE;bGLBlend=TRUE; // -> no need for 2 passes, perfect - - glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, COMBINE_EXT); - glTexEnvf(GL_TEXTURE_ENV, COMBINE_RGB_EXT, GL_MODULATE); - glTexEnvf(GL_TEXTURE_ENV, COMBINE_ALPHA_EXT, GL_MODULATE); - glTexEnvf(GL_TEXTURE_ENV, RGB_SCALE_EXT, 2.0f); - } - else // no advanced blending wanted/available: - { - if(bAdvancedBlend) bUseMultiPass=TRUE; // -> pseudo-advanced with 2 passes - else bUseMultiPass=FALSE; // -> or simple 'bright color' mode - bGLBlend=FALSE; // -> no ext blending! - - glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - } - - //----------------------------------------------------// - // init standard tex quality 0-2, and big alpha mode 3 - - if(!(dwActFixes&0x4000) && iFilterType && iTexQuality>=3) - bSmallAlpha=TRUE; - else bSmallAlpha=FALSE; - - if(bOpaquePass) // opaque mode? - { - if(dwActFixes&32) - { - TCF[0]=CP8RGBA_0; - PalTexturedColourFn=CP8RGBA; // -> init col func - } - else - { - TCF[0]=XP8RGBA_0; - PalTexturedColourFn=XP8RGBA; // -> init col func - } - - TCF[1]=XP8RGBA_1; - glAlphaFunc(GL_GREATER,0.49f); - } - else // no opaque mode? - { - TCF[0]=TCF[1]=P8RGBA; - PalTexturedColourFn=P8RGBA; // -> init col func - glAlphaFunc(GL_NOTEQUAL,0); // --> set alpha func - } - - //----------------------------------------------------// - - LoadSubTexFn=LoadSubTexturePageSort; // init load tex ptr - - giWantedFMT=GL_RGBA; // init ogl tex format - - switch(iTexQuality) // -> quality: - { - //--------------------------------------------------// - case 0: // -> don't care - giWantedRGBA=4; - giWantedTYPE=GL_UNSIGNED_BYTE; - break; - //--------------------------------------------------// - case 1: // -> R4G4B4A4 - if(bGLExt) - { - giWantedRGBA=GL_RGBA4; - giWantedTYPE=GL_UNSIGNED_SHORT_4_4_4_4_EXT; - LoadSubTexFn=LoadPackedSubTexturePageSort; - if(bOpaquePass) - { - if(dwActFixes&32) PTCF[0]=CP4RGBA_0; - else PTCF[0]=XP4RGBA_0; - PTCF[1]=XP4RGBA_1; - } - else - { - PTCF[0]=PTCF[1]=P4RGBA; - } - } - else - { - giWantedRGBA=GL_RGBA4; - giWantedTYPE=GL_UNSIGNED_BYTE; - } - break; - //--------------------------------------------------// - case 2: // -> R5B5G5A1 - if(bGLExt) - { - giWantedRGBA=GL_RGB5_A1; - giWantedTYPE=GL_UNSIGNED_SHORT_5_5_5_1_EXT; - LoadSubTexFn=LoadPackedSubTexturePageSort; - if(bOpaquePass) - { - if(dwActFixes&32) PTCF[0]=CP5RGBA_0; - else PTCF[0]=XP5RGBA_0; - PTCF[1]=XP5RGBA_1; - } - else - { - PTCF[0]=PTCF[1]=P5RGBA; - } - } - else - { - giWantedRGBA=GL_RGB5_A1;giWantedTYPE=GL_UNSIGNED_BYTE; - } - break; - //--------------------------------------------------// - case 3: // -> R8G8B8A8 - giWantedRGBA=GL_RGBA8; - giWantedTYPE=GL_UNSIGNED_BYTE; - - if(bSmallAlpha) - { - if(bOpaquePass) // opaque mode? - { - if(dwActFixes&32) {TCF[0]=CP8RGBAEx_0;PalTexturedColourFn=CP8RGBAEx;} - else {TCF[0]=XP8RGBAEx_0;PalTexturedColourFn=XP8RGBAEx;} - TCF[1]=XP8RGBAEx_1; - } - } - - break; - //--------------------------------------------------// - case 4: // -> R8G8B8A8 - giWantedRGBA = GL_RGBA8; - giWantedTYPE = GL_UNSIGNED_BYTE; - - if(strstr((char *)glGetString(GL_EXTENSIONS), // and extension avail? - "GL_EXT_bgra")) - { - giWantedFMT = GL_BGRA_EXT; - - if(bOpaquePass) // opaque mode? - { - if(bSmallAlpha) - { - if(dwActFixes&32) {TCF[0]=CP8BGRAEx_0;PalTexturedColourFn=CP8RGBAEx;} - else {TCF[0]=XP8BGRAEx_0;PalTexturedColourFn=XP8RGBAEx;} - TCF[1]=XP8BGRAEx_1; - } - else - { - if(dwActFixes&32) {TCF[0]=CP8BGRA_0;PalTexturedColourFn=CP8RGBA;} - else {TCF[0]=XP8BGRA_0;PalTexturedColourFn=XP8RGBA;} - TCF[1]=XP8BGRA_1; - } - } - else // no opaque mode? - { - TCF[0]=TCF[1]=P8BGRA; // -> init col func - } - } - else - { - iTexQuality=3; - if(bSmallAlpha) - { - if(bOpaquePass) // opaque mode? - { - if(dwActFixes&32) {TCF[0]=CP8RGBAEx_0;PalTexturedColourFn=CP8RGBAEx;} - else {TCF[0]=XP8RGBAEx_0;PalTexturedColourFn=XP8RGBAEx;} - TCF[1]=XP8RGBAEx_1; - } - } - } - - break; - //--------------------------------------------------// - } - - bBlendEnable=FALSE; // init blending: off - glDisable(GL_BLEND); - - SetScanTrans(); // init scan lines (if wanted) -} - -//////////////////////////////////////////////////////////////////////// -// setup scan lines -//////////////////////////////////////////////////////////////////////// - -#define R_TSP 0x00,0x45,0x00,0xff -#define G_TSP 0x00,0x00,0x45,0xff -#define B_TSP 0x45,0x00,0x00,0xff -#define O_TSP 0x45,0x45,0x45,0xff -#define N_TSP 0x00,0x00,0x00,0xff - -GLuint gTexScanName=0; - -GLubyte texscan[4][16]= -{ -{R_TSP, G_TSP, B_TSP, N_TSP}, -{O_TSP, N_TSP, O_TSP, N_TSP}, -{B_TSP, N_TSP, R_TSP, G_TSP}, -{O_TSP, N_TSP, O_TSP, N_TSP} -}; - -static void CreateScanLines(void) -{ - if(iUseScanLines) - { - int y; - if(iScanBlend<0) // special scan mask mode - { - glGenTextures(1, &gTexScanName); - glBindTexture(GL_TEXTURE_2D, gTexScanName); - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexImage2D(GL_TEXTURE_2D, 0, 4, 4, 4, 0,GL_RGBA, GL_UNSIGNED_BYTE, texscan); - } - else // otherwise simple lines in a display list - { - uiScanLine=glGenLists(1); - glNewList(uiScanLine,GL_COMPILE); - #ifdef _MACGL - // not mac specific, just commenting out to be friendly - // use it if you like - // this draws anti-aliased lines with user-chosen color - glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_CURRENT_BIT); - glEnable(GL_BLEND | GL_LINE_SMOOTH); - glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); - glColor4f(iScanlineColor[0],iScanlineColor[1],iScanlineColor[2],iScanlineColor[3]); - glBegin(GL_LINES); - for(y=0;y<iResY;y+=2) - { - glVertex2f(0,y); - glVertex2f(iResX,y); - } - glEnd(); - glPopAttrib(); - #else - for(y=0;y<iResY;y+=2) - { - glBegin(GL_QUADS); - glVertex2f(0,y); - glVertex2f(iResX,y); - glVertex2f(iResX,y+1); - glVertex2f(0,y+1); - glEnd(); - } - - #endif - glEndList(); - } - } -} - -//////////////////////////////////////////////////////////////////////// -// Initialize OGL -//////////////////////////////////////////////////////////////////////// - -#ifdef _WINDOWS -HGLRC GLCONTEXT=NULL; -#endif - -int GLinitialize() -{ -#ifdef _WINDOWS - HGLRC objectRC; - // init - dcGlobal = GetDC(hWWindow); // FIRST: dc/rc stuff - objectRC = wglCreateContext(dcGlobal); - GLCONTEXT=objectRC; - wglMakeCurrent(dcGlobal, objectRC); - // CheckWGLExtensions(dcGlobal); - if(bWindowMode) ReleaseDC(hWWindow,dcGlobal); // win mode: release dc again -#endif -#if defined (_MACGL) - BringContextForward(); -#endif - glViewport(rRatioRect.left, // init viewport by ratio rect - iResY-(rRatioRect.top+rRatioRect.bottom), - rRatioRect.right, - rRatioRect.bottom); - - glScissor(0, 0, iResX, iResY); // init clipping (fullscreen) - glEnable(GL_SCISSOR_TEST); - -#ifndef OWNSCALE - glMatrixMode(GL_TEXTURE); // init psx tex sow and tow if not "ownscale" - glLoadIdentity(); - glScalef(1.0f/255.99f,1.0f/255.99f,1.0f); // geforce precision hack -#endif - - glMatrixMode(GL_PROJECTION); // init projection with psx resolution - glLoadIdentity(); - glOrtho(0,PSXDisplay.DisplayMode.x, - PSXDisplay.DisplayMode.y, 0, -1, 1); - - if(iZBufferDepth) // zbuffer? - { - uiBufferBits=GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT; - glEnable(GL_DEPTH_TEST); - glDepthFunc(GL_ALWAYS); - iDepthFunc=1; - } - else // no zbuffer? - { - uiBufferBits=GL_COLOR_BUFFER_BIT; - glDisable(GL_DEPTH_TEST); - } - - glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // first buffer clear - glClear(uiBufferBits); - - if(bUseLines) // funny lines - { - glPolygonMode(GL_FRONT, GL_LINE); - glPolygonMode(GL_BACK, GL_LINE); - } - else // or the real filled thing - { - glPolygonMode(GL_FRONT, GL_FILL); - glPolygonMode(GL_BACK, GL_FILL); - } - - MakeDisplayLists(); // lists for menu/opaque - GetExtInfos(); // get ext infos - SetExtGLFuncs(); // init all kind of stuff (tex function pointers) - - glEnable(GL_ALPHA_TEST); // wanna alpha test - - if(!bUseAntiAlias) // no anti-alias (default) - { - glDisable(GL_LINE_SMOOTH); - glDisable(GL_POLYGON_SMOOTH); - glDisable(GL_POINT_SMOOTH); - } - else // wanna try it? glitches galore... - { - glHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST); - glEnable(GL_LINE_SMOOTH); - glEnable(GL_POLYGON_SMOOTH); - glEnable(GL_POINT_SMOOTH); - glHint(GL_LINE_SMOOTH_HINT,GL_NICEST); - glHint(GL_POINT_SMOOTH_HINT,GL_NICEST); - glHint(GL_POLYGON_SMOOTH_HINT,GL_NICEST); - } - - ubGloAlpha=127; // init some drawing vars - ubGloColAlpha=127; - TWin.UScaleFactor = 1; - TWin.VScaleFactor = 1; - bDrawMultiPass=FALSE; - bTexEnabled=FALSE; - bUsingTWin=FALSE; - - if(bDrawDither) glEnable(GL_DITHER); // dither mode - else glDisable(GL_DITHER); - - glDisable(GL_FOG); // turn all (currently) unused modes off - glDisable(GL_LIGHTING); - glDisable(GL_LOGIC_OP); - glDisable(GL_STENCIL_TEST); - glDisable(GL_TEXTURE_1D); - glDisable(GL_TEXTURE_2D); - glDisable(GL_CULL_FACE); - - glPixelTransferi(GL_RED_SCALE, 1); // to be sure: - glPixelTransferi(GL_RED_BIAS, 0); // init more OGL vals - glPixelTransferi(GL_GREEN_SCALE, 1); - glPixelTransferi(GL_GREEN_BIAS, 0); - glPixelTransferi(GL_BLUE_SCALE, 1); - glPixelTransferi(GL_BLUE_BIAS, 0); - glPixelTransferi(GL_ALPHA_SCALE, 1); - glPixelTransferi(GL_ALPHA_BIAS, 0); - -#ifdef _WINDOWS - // detect Windows hw/sw mode (just for info) - if(!strcmp("Microsoft Corporation",(LPTSTR)glGetString(GL_VENDOR)) && - !strcmp("GDI Generic", (LPTSTR)glGetString(GL_RENDERER))) - bGLSoft=TRUE; - else bGLSoft=FALSE; -#endif - - glFlush(); // we are done... - glFinish(); - - CreateScanLines(); // setup scanline stuff (if wanted) - - CheckTextureMemory(); // check available tex memory - - if(bKeepRatio) SetAspectRatio(); // set ratio - - if(iShowFPS) // user wants FPS display on startup? - { - ulKeybits|=KEY_SHOWFPS; // -> ok, turn display on - szDispBuf[0]=0; - BuildDispMenu(0); - } - - bIsFirstFrame = FALSE; // we have survived the first frame :) - - return 0; -} - -//////////////////////////////////////////////////////////////////////// -// clean up OGL stuff -//////////////////////////////////////////////////////////////////////// - -void GLcleanup() -{ - KillDisplayLists(); // bye display lists - - if(iUseScanLines) // scanlines used? - { - if(iScanBlend<0) - { - if(gTexScanName!=0) // some scanline tex? - glDeleteTextures(1, &gTexScanName); // -> delete it - gTexScanName=0; - } - else glDeleteLists(uiScanLine,1); // otherwise del scanline display list - } - - CleanupTextureStore(); // bye textures - -#ifdef _WINDOWS - wglMakeCurrent(NULL, NULL); // bye context - if(GLCONTEXT) wglDeleteContext(GLCONTEXT); - if(!bWindowMode && dcGlobal) - ReleaseDC(hWWindow,dcGlobal); -#endif -} - -//////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -// Offset stuff -//////////////////////////////////////////////////////////////////////// - -// please note: it is hardly do-able in a hw/accel plugin to get the -// real psx polygon coord mapping right... the following -// works not to bad with many games, though - -static __inline BOOL CheckCoord4() -{ - if(lx0<0) - { - if(((lx1-lx0)>CHKMAX_X) || - ((lx2-lx0)>CHKMAX_X)) - { - if(lx3<0) - { - if((lx1-lx3)>CHKMAX_X) return TRUE; - if((lx2-lx3)>CHKMAX_X) return TRUE; - } - } - } - if(lx1<0) - { - if((lx0-lx1)>CHKMAX_X) return TRUE; - if((lx2-lx1)>CHKMAX_X) return TRUE; - if((lx3-lx1)>CHKMAX_X) return TRUE; - } - if(lx2<0) - { - if((lx0-lx2)>CHKMAX_X) return TRUE; - if((lx1-lx2)>CHKMAX_X) return TRUE; - if((lx3-lx2)>CHKMAX_X) return TRUE; - } - if(lx3<0) - { - if(((lx1-lx3)>CHKMAX_X) || - ((lx2-lx3)>CHKMAX_X)) - { - if(lx0<0) - { - if((lx1-lx0)>CHKMAX_X) return TRUE; - if((lx2-lx0)>CHKMAX_X) return TRUE; - } - } - } - - - if(ly0<0) - { - if((ly1-ly0)>CHKMAX_Y) return TRUE; - if((ly2-ly0)>CHKMAX_Y) return TRUE; - } - if(ly1<0) - { - if((ly0-ly1)>CHKMAX_Y) return TRUE; - if((ly2-ly1)>CHKMAX_Y) return TRUE; - if((ly3-ly1)>CHKMAX_Y) return TRUE; - } - if(ly2<0) - { - if((ly0-ly2)>CHKMAX_Y) return TRUE; - if((ly1-ly2)>CHKMAX_Y) return TRUE; - if((ly3-ly2)>CHKMAX_Y) return TRUE; - } - if(ly3<0) - { - if((ly1-ly3)>CHKMAX_Y) return TRUE; - if((ly2-ly3)>CHKMAX_Y) return TRUE; - } - - return FALSE; -} - -static __inline BOOL CheckCoord3() -{ - if(lx0<0) - { - if((lx1-lx0)>CHKMAX_X) return TRUE; - if((lx2-lx0)>CHKMAX_X) return TRUE; - } - if(lx1<0) - { - if((lx0-lx1)>CHKMAX_X) return TRUE; - if((lx2-lx1)>CHKMAX_X) return TRUE; - } - if(lx2<0) - { - if((lx0-lx2)>CHKMAX_X) return TRUE; - if((lx1-lx2)>CHKMAX_X) return TRUE; - } - if(ly0<0) - { - if((ly1-ly0)>CHKMAX_Y) return TRUE; - if((ly2-ly0)>CHKMAX_Y) return TRUE; - } - if(ly1<0) - { - if((ly0-ly1)>CHKMAX_Y) return TRUE; - if((ly2-ly1)>CHKMAX_Y) return TRUE; - } - if(ly2<0) - { - if((ly0-ly2)>CHKMAX_Y) return TRUE; - if((ly1-ly2)>CHKMAX_Y) return TRUE; - } - - return FALSE; -} - - -static __inline BOOL CheckCoord2() -{ - if(lx0<0) - { - if((lx1-lx0)>CHKMAX_X) return TRUE; - } - if(lx1<0) - { - if((lx0-lx1)>CHKMAX_X) return TRUE; - } - if(ly0<0) - { - if((ly1-ly0)>CHKMAX_Y) return TRUE; - } - if(ly1<0) - { - if((ly0-ly1)>CHKMAX_Y) return TRUE; - } - - return FALSE; -} - -/* -//Lewpys "offsetline" func: - -void offsetline(void) -{ - float x0, x1, y0, y1, oolength, xl, yl; - - if(bDisplayNotSet) - SetOGLDisplaySettings(1); - - if(!(dwActFixes&16)) - { - if((lx0 & SIGNBIT)) lx0|=S_MASK; - else lx0&=~S_MASK; - if((lx1 & SIGNBIT)) lx1|=S_MASK; - else lx1&=~S_MASK; - if((ly0 & SIGNBIT)) ly0|=S_MASK; - else ly0&=~S_MASK; - if((ly1 & SIGNBIT)) ly1|=S_MASK; - else ly1&=~S_MASK; - } - - x0 = (float)(lx0 + PSXDisplay.CumulOffset.x); - x1 = (float)(lx1 + PSXDisplay.CumulOffset.x); - y0 = (float)(ly0 + PSXDisplay.CumulOffset.y); - y1 = (float)(ly1 + PSXDisplay.CumulOffset.y); - - oolength = (float)1/((float)sqrt((y1 - y0)*(y1 - y0) + (x1 - x0)*(x1 - x0)) * (float)2); -// oolength = (float)1/((float)sqrt(((y1 - y0)*(y1 - y0) + (x1 - x0)*(x1 - x0)) * (float)2)); - - xl = (x1 - x0) * oolength; - yl = (y1 - y0) * oolength; - - x0 += 0.5f; - x1 += 0.5f; - - x0 -= xl - yl; - x1 += xl + yl; - y0 -= yl + xl; - y1 += yl - xl; - - vertex[0].x=x0; - vertex[1].x=x1; - vertex[0].y=y0; - vertex[1].y=y1; - - x0 -= yl * 2; - x1 -= yl * 2; - y0 += xl * 2; - y1 += xl * 2; - - vertex[2].x=x1; - vertex[3].x=x0; - vertex[2].y=y1; - vertex[3].y=y0; -} -*/ - - -// Pete's way: a very easy (and hopefully fast) approach for lines -// without sqrt... using a small float -> short cast trick :) - -#define VERTEX_OFFX 0.2f -#define VERTEX_OFFY 0.2f - -BOOL offsetline(void) -{ - short x0,x1,y0,y1,dx,dy;float px,py; - - if(bDisplayNotSet) - SetOGLDisplaySettings(1); - - if(!(dwActFixes&16)) - { - lx0=(short)(((int)lx0<<SIGNSHIFT)>>SIGNSHIFT); - lx1=(short)(((int)lx1<<SIGNSHIFT)>>SIGNSHIFT); - ly0=(short)(((int)ly0<<SIGNSHIFT)>>SIGNSHIFT); - ly1=(short)(((int)ly1<<SIGNSHIFT)>>SIGNSHIFT); - - if(CheckCoord2()) return TRUE; - } - - x0 = (lx0 + PSXDisplay.CumulOffset.x)+1; - x1 = (lx1 + PSXDisplay.CumulOffset.x)+1; - y0 = (ly0 + PSXDisplay.CumulOffset.y)+1; - y1 = (ly1 + PSXDisplay.CumulOffset.y)+1; - - dx=x1-x0; - dy=y1-y0; - - if(dx>=0) - { - if(dy>=0) - { - px=0.5f; - if(dx>dy) py=-0.5f; - else if(dx<dy) py= 0.5f; - else py= 0.0f; - } - else - { - py=-0.5f; - dy=-dy; - if(dx>dy) px= 0.5f; - else if(dx<dy) px=-0.5f; - else px= 0.0f; - } - } - else - { - if(dy>=0) - { - py=0.5f; - dx=-dx; - if(dx>dy) px=-0.5f; - else if(dx<dy) px= 0.5f; - else px= 0.0f; - } - else - { - px=-0.5f; - if(dx>dy) py=-0.5f; - else if(dx<dy) py= 0.5f; - else py= 0.0f; - } - } - - vertex[0].x=(short)((float)x0-px); - vertex[3].x=(short)((float)x0+py); - - vertex[0].y=(short)((float)y0-py); - vertex[3].y=(short)((float)y0-px); - - vertex[1].x=(short)((float)x1-py); - vertex[2].x=(short)((float)x1+px); - - vertex[1].y=(short)((float)y1+px); - vertex[2].y=(short)((float)y1+py); - - if(vertex[0].x==vertex[3].x && // ortho rect? done - vertex[1].x==vertex[2].x && - vertex[0].y==vertex[1].y && - vertex[2].y==vertex[3].y) return FALSE; - if(vertex[0].x==vertex[1].x && - vertex[2].x==vertex[3].x && - vertex[0].y==vertex[3].y && - vertex[1].y==vertex[2].y) return FALSE; - - vertex[0].x-=VERTEX_OFFX; // otherwise a small offset - vertex[0].y-=VERTEX_OFFY; // to get better accuracy - vertex[1].x-=VERTEX_OFFX; - vertex[1].y-=VERTEX_OFFY; - vertex[2].x-=VERTEX_OFFX; - vertex[2].y-=VERTEX_OFFY; - vertex[3].x-=VERTEX_OFFX; - vertex[3].y-=VERTEX_OFFY; - - return FALSE; -} - -///////////////////////////////////////////////////////// - -BOOL offset2(void) -{ - if(bDisplayNotSet) - SetOGLDisplaySettings(1); - - if(!(dwActFixes&16)) - { - lx0=(short)(((int)lx0<<SIGNSHIFT)>>SIGNSHIFT); - lx1=(short)(((int)lx1<<SIGNSHIFT)>>SIGNSHIFT); - ly0=(short)(((int)ly0<<SIGNSHIFT)>>SIGNSHIFT); - ly1=(short)(((int)ly1<<SIGNSHIFT)>>SIGNSHIFT); - - if(CheckCoord2()) return TRUE; - } - - vertex[0].x=lx0+PSXDisplay.CumulOffset.x; - vertex[1].x=lx1+PSXDisplay.CumulOffset.x; - vertex[0].y=ly0+PSXDisplay.CumulOffset.y; - vertex[1].y=ly1+PSXDisplay.CumulOffset.y; - - return FALSE; -} - -///////////////////////////////////////////////////////// - -BOOL offset3(void) -{ - if(bDisplayNotSet) - SetOGLDisplaySettings(1); - - if(!(dwActFixes&16)) - { - lx0=(short)(((int)lx0<<SIGNSHIFT)>>SIGNSHIFT); - lx1=(short)(((int)lx1<<SIGNSHIFT)>>SIGNSHIFT); - lx2=(short)(((int)lx2<<SIGNSHIFT)>>SIGNSHIFT); - ly0=(short)(((int)ly0<<SIGNSHIFT)>>SIGNSHIFT); - ly1=(short)(((int)ly1<<SIGNSHIFT)>>SIGNSHIFT); - ly2=(short)(((int)ly2<<SIGNSHIFT)>>SIGNSHIFT); - - if(CheckCoord3()) return TRUE; - } - - vertex[0].x=lx0+PSXDisplay.CumulOffset.x; - vertex[1].x=lx1+PSXDisplay.CumulOffset.x; - vertex[2].x=lx2+PSXDisplay.CumulOffset.x; - vertex[0].y=ly0+PSXDisplay.CumulOffset.y; - vertex[1].y=ly1+PSXDisplay.CumulOffset.y; - vertex[2].y=ly2+PSXDisplay.CumulOffset.y; - - return FALSE; -} - -///////////////////////////////////////////////////////// - -BOOL offset4(void) -{ - if(bDisplayNotSet) - SetOGLDisplaySettings(1); - - if(!(dwActFixes&16)) - { - lx0=(short)(((int)lx0<<SIGNSHIFT)>>SIGNSHIFT); - lx1=(short)(((int)lx1<<SIGNSHIFT)>>SIGNSHIFT); - lx2=(short)(((int)lx2<<SIGNSHIFT)>>SIGNSHIFT); - lx3=(short)(((int)lx3<<SIGNSHIFT)>>SIGNSHIFT); - ly0=(short)(((int)ly0<<SIGNSHIFT)>>SIGNSHIFT); - ly1=(short)(((int)ly1<<SIGNSHIFT)>>SIGNSHIFT); - ly2=(short)(((int)ly2<<SIGNSHIFT)>>SIGNSHIFT); - ly3=(short)(((int)ly3<<SIGNSHIFT)>>SIGNSHIFT); - - if(CheckCoord4()) return TRUE; - } - - vertex[0].x=lx0+PSXDisplay.CumulOffset.x; - vertex[1].x=lx1+PSXDisplay.CumulOffset.x; - vertex[2].x=lx2+PSXDisplay.CumulOffset.x; - vertex[3].x=lx3+PSXDisplay.CumulOffset.x; - vertex[0].y=ly0+PSXDisplay.CumulOffset.y; - vertex[1].y=ly1+PSXDisplay.CumulOffset.y; - vertex[2].y=ly2+PSXDisplay.CumulOffset.y; - vertex[3].y=ly3+PSXDisplay.CumulOffset.y; - - return FALSE; -} - -///////////////////////////////////////////////////////// - -void offsetST(void) -{ - if(bDisplayNotSet) - SetOGLDisplaySettings(1); - - if(!(dwActFixes&16)) - { - lx0=(short)(((int)lx0<<SIGNSHIFT)>>SIGNSHIFT); - ly0=(short)(((int)ly0<<SIGNSHIFT)>>SIGNSHIFT); - - if(lx0<-512 && PSXDisplay.DrawOffset.x<=-512) - lx0+=2048; - - if(ly0<-512 && PSXDisplay.DrawOffset.y<=-512) - ly0+=2048; - } - - ly1 = ly0; - ly2 = ly3 = ly0+sprtH; - lx3 = lx0; - lx1 = lx2 = lx0+sprtW; - - vertex[0].x=lx0+PSXDisplay.CumulOffset.x; - vertex[1].x=lx1+PSXDisplay.CumulOffset.x; - vertex[2].x=lx2+PSXDisplay.CumulOffset.x; - vertex[3].x=lx3+PSXDisplay.CumulOffset.x; - vertex[0].y=ly0+PSXDisplay.CumulOffset.y; - vertex[1].y=ly1+PSXDisplay.CumulOffset.y; - vertex[2].y=ly2+PSXDisplay.CumulOffset.y; - vertex[3].y=ly3+PSXDisplay.CumulOffset.y; -} - -///////////////////////////////////////////////////////// - -void offsetScreenUpload(int Position) -{ - if(bDisplayNotSet) - SetOGLDisplaySettings(1); - - if(Position==-1) - { - int lmdx,lmdy; - - lmdx=xrUploadArea.x0; - lmdy=xrUploadArea.y0; - - lx0-=lmdx; - ly0-=lmdy; - lx1-=lmdx; - ly1-=lmdy; - lx2-=lmdx; - ly2-=lmdy; - lx3-=lmdx; - ly3-=lmdy; - } - else - if(Position) - { - lx0-=PSXDisplay.DisplayPosition.x; - ly0-=PSXDisplay.DisplayPosition.y; - lx1-=PSXDisplay.DisplayPosition.x; - ly1-=PSXDisplay.DisplayPosition.y; - lx2-=PSXDisplay.DisplayPosition.x; - ly2-=PSXDisplay.DisplayPosition.y; - lx3-=PSXDisplay.DisplayPosition.x; - ly3-=PSXDisplay.DisplayPosition.y; - } - else - { - lx0-=PreviousPSXDisplay.DisplayPosition.x; - ly0-=PreviousPSXDisplay.DisplayPosition.y; - lx1-=PreviousPSXDisplay.DisplayPosition.x; - ly1-=PreviousPSXDisplay.DisplayPosition.y; - lx2-=PreviousPSXDisplay.DisplayPosition.x; - ly2-=PreviousPSXDisplay.DisplayPosition.y; - lx3-=PreviousPSXDisplay.DisplayPosition.x; - ly3-=PreviousPSXDisplay.DisplayPosition.y; - } - - vertex[0].x=lx0 + PreviousPSXDisplay.Range.x0; - vertex[1].x=lx1 + PreviousPSXDisplay.Range.x0; - vertex[2].x=lx2 + PreviousPSXDisplay.Range.x0; - vertex[3].x=lx3 + PreviousPSXDisplay.Range.x0; - vertex[0].y=ly0 + PreviousPSXDisplay.Range.y0; - vertex[1].y=ly1 + PreviousPSXDisplay.Range.y0; - vertex[2].y=ly2 + PreviousPSXDisplay.Range.y0; - vertex[3].y=ly3 + PreviousPSXDisplay.Range.y0; - - if(iUseMask) - { - vertex[0].z=vertex[1].z=vertex[2].z=vertex[3].z=gl_z; - gl_z+=0.00004f; - } -} - -///////////////////////////////////////////////////////// - -void offsetBlk(void) -{ - if(bDisplayNotSet) - SetOGLDisplaySettings(1); - - vertex[0].x=lx0-PSXDisplay.GDrawOffset.x + PreviousPSXDisplay.Range.x0; - vertex[1].x=lx1-PSXDisplay.GDrawOffset.x + PreviousPSXDisplay.Range.x0; - vertex[2].x=lx2-PSXDisplay.GDrawOffset.x + PreviousPSXDisplay.Range.x0; - vertex[3].x=lx3-PSXDisplay.GDrawOffset.x + PreviousPSXDisplay.Range.x0; - vertex[0].y=ly0-PSXDisplay.GDrawOffset.y + PreviousPSXDisplay.Range.y0; - vertex[1].y=ly1-PSXDisplay.GDrawOffset.y + PreviousPSXDisplay.Range.y0; - vertex[2].y=ly2-PSXDisplay.GDrawOffset.y + PreviousPSXDisplay.Range.y0; - vertex[3].y=ly3-PSXDisplay.GDrawOffset.y + PreviousPSXDisplay.Range.y0; - - if(iUseMask) - { - vertex[0].z=vertex[1].z=vertex[2].z=vertex[3].z=gl_z; - gl_z+=0.00004f; - } -} - -//////////////////////////////////////////////////////////////////////// -// texture sow/tow calculations -//////////////////////////////////////////////////////////////////////// - -void assignTextureVRAMWrite(void) -{ -#ifdef OWNSCALE - - vertex[0].sow=0.5f/ ST_FACVRAMX; - vertex[0].tow=0.5f/ ST_FACVRAM; - - vertex[1].sow=(float)gl_ux[1]/ ST_FACVRAMX; - vertex[1].tow=0.5f/ ST_FACVRAM; - - vertex[2].sow=(float)gl_ux[2]/ ST_FACVRAMX; - vertex[2].tow=(float)gl_vy[2]/ ST_FACVRAM; - - vertex[3].sow=0.5f/ ST_FACVRAMX; - vertex[3].tow=(float)gl_vy[3]/ ST_FACVRAM; - -#else - - if(gl_ux[1]==255) - { - vertex[0].sow=(gl_ux[0]*255.99f)/255.0f; - vertex[1].sow=(gl_ux[1]*255.99f)/255.0f; - vertex[2].sow=(gl_ux[2]*255.99f)/255.0f; - vertex[3].sow=(gl_ux[3]*255.99f)/255.0f; - } - else - { - vertex[0].sow=gl_ux[0]; - vertex[1].sow=gl_ux[1]; - vertex[2].sow=gl_ux[2]; - vertex[3].sow=gl_ux[3]; - } - - vertex[0].tow=gl_vy[0]; - vertex[1].tow=gl_vy[1]; - vertex[2].tow=gl_vy[2]; - vertex[3].tow=gl_vy[3]; - -#endif -} - -GLuint gLastTex=0; -GLuint gLastFMode=(GLuint)-1; - -///////////////////////////////////////////////////////// - -void assignTextureSprite(void) -{ - if(bUsingTWin) - { - vertex[0].sow=vertex[3].sow=(float)gl_ux[0]/TWin.UScaleFactor; - vertex[1].sow=vertex[2].sow=(float)sSprite_ux2/TWin.UScaleFactor; - vertex[0].tow=vertex[1].tow=(float)gl_vy[0]/TWin.VScaleFactor; - vertex[2].tow=vertex[3].tow=(float)sSprite_vy2/TWin.VScaleFactor; - gLastTex=gTexName; - - if(iFilterType>0 && iFilterType<3 && iHiResTextures!=2) - { - float fxmin=65536.0f,fxmax=0.0f,fymin=65536.0f,fymax=0.0f;int i; - - for(i=0;i<4;i++) - { - if(vertex[i].sow<fxmin) fxmin=vertex[i].sow; - if(vertex[i].tow<fymin) fymin=vertex[i].tow; - if(vertex[i].sow>fxmax) fxmax=vertex[i].sow; - if(vertex[i].tow>fymax) fymax=vertex[i].tow; - } - - for(i=0;i<4;i++) - { -#ifdef OWNSCALE - if(vertex[i].sow==fxmin) vertex[i].sow+=0.375f/(float)TWin.Position.x1; - if(vertex[i].sow==fxmax) vertex[i].sow-=0.375f/(float)TWin.Position.x1; - if(vertex[i].tow==fymin) vertex[i].tow+=0.375f/(float)TWin.Position.y1; - if(vertex[i].tow==fymax) vertex[i].tow-=0.375f/(float)TWin.Position.y1; -#else - if(vertex[i].sow==fxmin) vertex[i].sow+=96.0f/(float)TWin.Position.x1; - if(vertex[i].sow==fxmax) vertex[i].sow-=96.0f/(float)TWin.Position.x1; - if(vertex[i].tow==fymin) vertex[i].tow+=96.0f/(float)TWin.Position.y1; - if(vertex[i].tow==fymax) vertex[i].tow-=96.0f/(float)TWin.Position.y1; -#endif - } - } - - } - else - { -#ifdef OWNSCALE - - vertex[0].sow=vertex[3].sow=(float)gl_ux[0] / ST_FACSPRITE; - vertex[1].sow=vertex[2].sow=(float)sSprite_ux2 / ST_FACSPRITE; - vertex[0].tow=vertex[1].tow=(float)gl_vy[0] / ST_FACSPRITE; - vertex[2].tow=vertex[3].tow=(float)sSprite_vy2 / ST_FACSPRITE; - -#else - - vertex[0].sow=vertex[3].sow=gl_ux[0]; - vertex[1].sow=vertex[2].sow=sSprite_ux2; - vertex[0].tow=vertex[1].tow=gl_vy[0]; - vertex[2].tow=vertex[3].tow=sSprite_vy2; - -#endif - - if(iFilterType>2) - { - if(gLastTex!=gTexName || gLastFMode!=0) - { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - gLastTex=gTexName;gLastFMode=0; - } - } - } - - if(usMirror & 0x1000) - { - vertex[0].sow=vertex[1].sow; - vertex[1].sow=vertex[2].sow=vertex[3].sow; - vertex[3].sow=vertex[0].sow; - } - - if(usMirror & 0x2000) - { - vertex[0].tow=vertex[3].tow; - vertex[2].tow=vertex[3].tow=vertex[1].tow; - vertex[1].tow=vertex[0].tow; - } - -} - -///////////////////////////////////////////////////////// - -void assignTexture3(void) -{ - if(bUsingTWin) - { - vertex[0].sow=(float)gl_ux[0]/TWin.UScaleFactor; - vertex[0].tow=(float)gl_vy[0]/TWin.VScaleFactor; - vertex[1].sow=(float)gl_ux[1]/TWin.UScaleFactor; - vertex[1].tow=(float)gl_vy[1]/TWin.VScaleFactor; - vertex[2].sow=(float)gl_ux[2]/TWin.UScaleFactor; - vertex[2].tow=(float)gl_vy[2]/TWin.VScaleFactor; - gLastTex=gTexName; - } - else - { -#ifdef OWNSCALE - vertex[0].sow=(float)gl_ux[0] / ST_FACTRI; - vertex[0].tow=(float)gl_vy[0] / ST_FACTRI; - vertex[1].sow=(float)gl_ux[1] / ST_FACTRI; - - vertex[1].tow=(float)gl_vy[1] / ST_FACTRI; - vertex[2].sow=(float)gl_ux[2] / ST_FACTRI; - vertex[2].tow=(float)gl_vy[2] / ST_FACTRI; -#else - vertex[0].sow=gl_ux[0]; - vertex[0].tow=gl_vy[0]; - vertex[1].sow=gl_ux[1]; - vertex[1].tow=gl_vy[1]; - vertex[2].sow=gl_ux[2]; - vertex[2].tow=gl_vy[2]; -#endif - - if(iFilterType>2) - { - if(gLastTex!=gTexName || gLastFMode!=1) - { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - gLastTex=gTexName;gLastFMode=1; - } - } - - if(iFilterType) - { - float fxmin=256.0f,fxmax=0.0f,fymin=256.0f,fymax=0.0f;int i; - for(i=0;i<3;i++) - { - if(vertex[i].sow<fxmin) fxmin=vertex[i].sow; - if(vertex[i].tow<fymin) fymin=vertex[i].tow; - if(vertex[i].sow>fxmax) fxmax=vertex[i].sow; - if(vertex[i].tow>fymax) fymax=vertex[i].tow; - } - - for(i=0;i<3;i++) - { - if(vertex[i].sow==fxmin) vertex[i].sow+=ST_BFFACSORT; - if(vertex[i].sow==fxmax) vertex[i].sow-=ST_BFFACSORT; - if(vertex[i].tow==fymin) vertex[i].tow+=ST_BFFACSORT; - if(vertex[i].tow==fymax) vertex[i].tow-=ST_BFFACSORT; - } - } - } -} - -///////////////////////////////////////////////////////// - -void assignTexture4(void) -{ - if(bUsingTWin) - { - vertex[0].sow=(float)gl_ux[0]/TWin.UScaleFactor; - vertex[0].tow=(float)gl_vy[0]/TWin.VScaleFactor; - vertex[1].sow=(float)gl_ux[1]/TWin.UScaleFactor; - vertex[1].tow=(float)gl_vy[1]/TWin.VScaleFactor; - vertex[2].sow=(float)gl_ux[2]/TWin.UScaleFactor; - vertex[2].tow=(float)gl_vy[2]/TWin.VScaleFactor; - vertex[3].sow=(float)gl_ux[3]/TWin.UScaleFactor; - vertex[3].tow=(float)gl_vy[3]/TWin.VScaleFactor; - gLastTex=gTexName; - } - else - { -#ifdef OWNSCALE - vertex[0].sow=(float)gl_ux[0] / ST_FAC; - vertex[0].tow=(float)gl_vy[0] / ST_FAC; - vertex[1].sow=(float)gl_ux[1] / ST_FAC; - vertex[1].tow=(float)gl_vy[1] / ST_FAC; - vertex[2].sow=(float)gl_ux[2] / ST_FAC; - vertex[2].tow=(float)gl_vy[2] / ST_FAC; - vertex[3].sow=(float)gl_ux[3] / ST_FAC; - vertex[3].tow=(float)gl_vy[3] / ST_FAC; -#else - vertex[0].sow=gl_ux[0]; - vertex[0].tow=gl_vy[0]; - vertex[1].sow=gl_ux[1]; - vertex[1].tow=gl_vy[1]; - vertex[2].sow=gl_ux[2]; - vertex[2].tow=gl_vy[2]; - vertex[3].sow=gl_ux[3]; - vertex[3].tow=gl_vy[3]; -#endif - - if(iFilterType>2) - { - if(gLastTex!=gTexName || gLastFMode!=1) - { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - gLastTex=gTexName;gLastFMode=1; - } - } - - if(iFilterType) - { - float fxmin=256.0f,fxmax=0.0f,fymin=256.0f,fymax=0.0f;int i; - for(i=0;i<4;i++) - { - if(vertex[i].sow<fxmin) fxmin=vertex[i].sow; - if(vertex[i].tow<fymin) fymin=vertex[i].tow; - if(vertex[i].sow>fxmax) fxmax=vertex[i].sow; - if(vertex[i].tow>fymax) fymax=vertex[i].tow; - } - - for(i=0;i<4;i++) - { - if(vertex[i].sow==fxmin) vertex[i].sow+=ST_BFFACSORT; - if(vertex[i].sow==fxmax) vertex[i].sow-=ST_BFFACSORT; - if(vertex[i].tow==fymin) vertex[i].tow+=ST_BFFACSORT; - if(vertex[i].tow==fymax) vertex[i].tow-=ST_BFFACSORT; - } - } - } -} - -//////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -// render pos / buffers -//////////////////////////////////////////////////////////////////////// - -#ifndef _WINDOWS -#define EqualRect(pr1,pr2) ((pr1)->left==(pr2)->left && (pr1)->top==(pr2)->top && (pr1)->right==(pr2)->right && (pr1)->bottom==(pr2)->bottom) -#endif - -//////////////////////////////////////////////////////////////////////// -// SetDisplaySettings: "simply" calcs the new drawing area and updates -// the ogl clipping (scissor) - -BOOL bSetClip=FALSE; - -void SetOGLDisplaySettings(BOOL DisplaySet) -{ - static RECT rprev={0,0,0,0}; - static RECT rC ={0,0,0,0}; - static int iOldX=0; - static int iOldY=0; - RECT r;float XS,YS; - - bDisplayNotSet = FALSE; - - //----------------------------------------------------// that's a whole screen upload - if(!DisplaySet) - { - RECT rX; - PSXDisplay.GDrawOffset.x=0; - PSXDisplay.GDrawOffset.y=0; - - PSXDisplay.CumulOffset.x = PSXDisplay.DrawOffset.x+PreviousPSXDisplay.Range.x0; - PSXDisplay.CumulOffset.y = PSXDisplay.DrawOffset.y+PreviousPSXDisplay.Range.y0; - - rprev.left=rprev.left+1; - - rX=rRatioRect; - rX.top=iResY-(rRatioRect.top+rRatioRect.bottom); - - if(bSetClip || !EqualRect(&rC,&rX)) - { - rC=rX; - glScissor(rC.left,rC.top,rC.right,rC.bottom); - bSetClip=FALSE; - } - return; - } - //----------------------------------------------------// - - PSXDisplay.GDrawOffset.y = PreviousPSXDisplay.DisplayPosition.y; - PSXDisplay.GDrawOffset.x = PreviousPSXDisplay.DisplayPosition.x; - PSXDisplay.CumulOffset.x = PSXDisplay.DrawOffset.x - PSXDisplay.GDrawOffset.x+PreviousPSXDisplay.Range.x0; - PSXDisplay.CumulOffset.y = PSXDisplay.DrawOffset.y - PSXDisplay.GDrawOffset.y+PreviousPSXDisplay.Range.y0; - - r.top =PSXDisplay.DrawArea.y0 - PreviousPSXDisplay.DisplayPosition.y; - r.bottom=PSXDisplay.DrawArea.y1 - PreviousPSXDisplay.DisplayPosition.y; - - if(r.bottom<0 || r.top>=PSXDisplay.DisplayMode.y) - { - r.top =PSXDisplay.DrawArea.y0 - PSXDisplay.DisplayPosition.y; - r.bottom=PSXDisplay.DrawArea.y1 - PSXDisplay.DisplayPosition.y; - } - - r.left =PSXDisplay.DrawArea.x0 - PreviousPSXDisplay.DisplayPosition.x; - r.right =PSXDisplay.DrawArea.x1 - PreviousPSXDisplay.DisplayPosition.x; - - if(r.right<0 || r.left>=PSXDisplay.DisplayMode.x) - { - r.left =PSXDisplay.DrawArea.x0 - PSXDisplay.DisplayPosition.x; - r.right =PSXDisplay.DrawArea.x1 - PSXDisplay.DisplayPosition.x; - } - - if(!bSetClip && EqualRect(&r,&rprev) && - iOldX == PSXDisplay.DisplayMode.x && - iOldY == PSXDisplay.DisplayMode.y) - return; - - rprev = r; - iOldX = PSXDisplay.DisplayMode.x; - iOldY = PSXDisplay.DisplayMode.y; - - XS=(float)rRatioRect.right/(float)PSXDisplay.DisplayMode.x; - YS=(float)rRatioRect.bottom/(float)PSXDisplay.DisplayMode.y; - - if(PreviousPSXDisplay.Range.x0) - { - short s=PreviousPSXDisplay.Range.x0+PreviousPSXDisplay.Range.x1; - - r.left+=PreviousPSXDisplay.Range.x0+1; - - r.right+=PreviousPSXDisplay.Range.x0; - - if(r.left>s) r.left=s; - if(r.right>s) r.right=s; - } - - if(PreviousPSXDisplay.Range.y0) - { - short s=PreviousPSXDisplay.Range.y0+PreviousPSXDisplay.Range.y1; - - r.top+=PreviousPSXDisplay.Range.y0+1; - r.bottom+=PreviousPSXDisplay.Range.y0; - - if(r.top>s) r.top=s; - if(r.bottom>s) r.bottom=s; - } - - // Set the ClipArea variables to reflect the new screen, - // offset from zero (since it is a new display buffer) - r.left = (int)(((float)(r.left)) *XS); - r.top = (int)(((float)(r.top)) *YS); - r.right = (int)(((float)(r.right + 1))*XS); - r.bottom = (int)(((float)(r.bottom + 1))*YS); - - // Limit clip area to the screen size - if (r.left > iResX) r.left = iResX; - if (r.left < 0) r.left = 0; - if (r.top > iResY) r.top = iResY; - if (r.top < 0) r.top = 0; - if (r.right > iResX) r.right = iResX; - if (r.right < 0) r.right = 0; - if (r.bottom > iResY) r.bottom = iResY; - if (r.bottom < 0) r.bottom = 0; - - r.right -=r.left; - r.bottom-=r.top; - r.top=iResY-(r.top+r.bottom); - - r.left+=rRatioRect.left; - r.top -=rRatioRect.top; - - if(bSetClip || !EqualRect(&r,&rC)) - { - glScissor(r.left,r.top,r.right,r.bottom); - rC=r; - bSetClip=FALSE; - } -} - -//////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////// - +/***************************************************************************
+ draw.c - description
+ -------------------
+ begin : Sun Mar 08 2009
+ copyright : (C) 1999-2009 by Pete Bernert
+ web : www.pbernert.com
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. See also the license.txt file for *
+ * additional informations. *
+ * *
+ ***************************************************************************/
+
+#include "stdafx.h"
+
+#define _IN_DRAW
+
+#include "externals.h"
+#include "gpu.h"
+#include "draw.h"
+#include "prim.h"
+#include "texture.h"
+#include "menu.h"
+
+#if defined(_MACGL)
+// if you use it, you must include it
+#include <OpenGL/gl.h>
+#include <OpenGL/glext.h>
+#endif
+////////////////////////////////////////////////////////////////////////////////////
+// defines
+
+#define SIGNBIT 0x800
+#define S_MASK 0xf000
+#define L_MASK 0xfffff000
+
+// ownscale: some ogl drivers have buggy texture matrix funcs, so it
+// is safer to calc sow/tow ourselves
+
+#ifdef OWNSCALE
+
+#define ST_FACSPRITE 255.99f
+#define ST_BFFACSPRITE 0.5f/256.0f
+#define ST_BFFACSPRITESORT 0.333f/256.0f
+
+#define ST_OFFSET 0.5f/256.0f;
+
+#define ST_FAC 255.99f
+#define ST_BFFAC 0.5f/256.0f
+#define ST_BFFACSORT 0.333f/256.0f
+
+#define ST_FACTRI 255.99f
+#define ST_BFFACTRI 0.5f/256.0f
+#define ST_BFFACTRISORT 0.333f/256.0f
+
+#define ST_FACVRAMX 255.0f
+#define ST_FACVRAM 256.0f
+
+///////////////////////////////////////////////////////////////
+
+#else
+
+#define ST_BFFACSPRITE 0.5f
+#define ST_BFFACSPRITESORT 0.333f
+
+#define ST_BFFAC 0.5f
+#define ST_BFFACSORT 0.333f
+
+#define ST_BFFACTRI 0.5f
+#define ST_BFFACTRISORT 0.333f
+
+#define ST_OFFSET 0.5f;
+
+#endif
+
+////////////////////////////////////////////////////////////////////////////////////
+// draw globals; most will be initialized again later (by config or checks)
+
+#ifdef _WINDOWS
+HDC dcGlobal = NULL;
+HWND hWWindow;
+#endif
+
+BOOL bIsFirstFrame = TRUE;
+
+// resolution/ratio vars
+
+int iResX;
+int iResY;
+BOOL bKeepRatio = FALSE;
+RECT rRatioRect;
+
+// psx mask related vars
+
+BOOL bCheckMask = FALSE;
+int iUseMask = 0;
+int iSetMask = 0;
+unsigned short sSetMask = 0;
+uint32_t lSetMask = 0;
+
+// drawing/coord vars
+
+OGLVertex vertex[4];
+GLubyte gl_ux[8];
+GLubyte gl_vy[8];
+short sprtY,sprtX,sprtH,sprtW;
+
+// drawing options
+
+BOOL bOpaquePass;
+BOOL bAdvancedBlend;
+BOOL bUseLines;
+BOOL bUseAntiAlias;
+int iTexQuality;
+int iUsePalTextures=1;
+BOOL bSnapShot=FALSE;
+BOOL bSmallAlpha=FALSE;
+int iShowFPS=0;
+
+// OGL extension support
+
+int iForceVSync=-1;
+int iUseExts=0;
+BOOL bGLExt;
+BOOL bGLFastMovie=FALSE;
+BOOL bGLSoft;
+BOOL bGLBlend;
+#if defined (_MACGL) // always supported on OSX > 10.4.3
+#define glBlendEquationEXTEx glBlendEquationEXT
+#define glColorTableEXTEx glColorTableEXT
+#else
+PFNGLBLENDEQU glBlendEquationEXTEx=NULL;
+PFNGLCOLORTABLEEXT glColorTableEXTEx=NULL;
+#endif
+// gfx card buffer infos
+
+int iDepthFunc=0;
+int iZBufferDepth=0;
+GLbitfield uiBufferBits=GL_COLOR_BUFFER_BIT;
+
+////////////////////////////////////////////////////////////////////////
+// Set OGL pixel format
+////////////////////////////////////////////////////////////////////////
+
+#ifdef _WINDOWS
+BOOL bSetupPixelFormat(HDC hDC)
+{
+ int pixelformat;
+ static PIXELFORMATDESCRIPTOR pfd =
+ {
+ sizeof(PIXELFORMATDESCRIPTOR), // size of this pfd
+ 1, // version number
+ PFD_DRAW_TO_WINDOW | // support window
+ PFD_SUPPORT_OPENGL | // support OpenGL
+ PFD_DOUBLEBUFFER, // double buffered
+ PFD_TYPE_RGBA, // RGBA type
+ 16, // 16-bit color depth (adjusted later)
+ 0, 0, 0, 0, 0, 0, // color bits ignored
+ 0, // no alpha buffer
+ 0, // shift bit ignored
+ 0, // no accumulation buffer
+ 0, 0, 0, 0, // accum bits ignored
+ 0, // z-buffer
+ 0,
+ 0, // no auxiliary buffer
+ PFD_MAIN_PLANE, // main layer
+ 0, // reserved
+ 0, 0, 0 // layer masks ignored
+ };
+
+ pfd.cColorBits=iColDepth; // set user color depth
+ pfd.cDepthBits=iZBufferDepth; // set user zbuffer (by psx mask)
+
+ if((pixelformat=ChoosePixelFormat(hDC,&pfd))==0)
+ {
+ MessageBox(NULL,"ChoosePixelFormat failed","Error",MB_OK);
+ return FALSE;
+ }
+
+ if(SetPixelFormat(hDC,pixelformat, &pfd)==FALSE)
+ {
+ MessageBox(NULL,"SetPixelFormat failed","Error",MB_OK);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+#endif
+
+////////////////////////////////////////////////////////////////////////
+// Get extension infos (f.e. pal textures / packed pixels)
+////////////////////////////////////////////////////////////////////////
+
+void GetExtInfos(void)
+{
+ BOOL bPacked=FALSE; // default: no packed pixel support
+
+ bGLExt=FALSE; // default: no extensions
+ bGLFastMovie=FALSE;
+
+ if(strstr((char *)glGetString(GL_EXTENSIONS), // packed pixels available?
+ "GL_EXT_packed_pixels"))
+ bPacked=TRUE; // -> ok
+
+ if(bPacked && bUse15bitMdec) // packed available and 15bit mdec wanted?
+ bGLFastMovie=TRUE; // -> ok
+
+ if(bPacked && (iTexQuality==1 || iTexQuality==2)) // packed available and 16 bit texture format?
+ {
+ bGLFastMovie=TRUE; // -> ok
+ bGLExt=TRUE;
+ }
+
+ if(iUseExts && // extension support wanted?
+ (strstr((char *)glGetString(GL_EXTENSIONS),
+ "GL_EXT_texture_edge_clamp") ||
+ strstr((char *)glGetString(GL_EXTENSIONS), // -> check clamp support, if yes: use it
+ "GL_SGIS_texture_edge_clamp")))
+ iClampType=GL_TO_EDGE_CLAMP;
+ else iClampType=GL_CLAMP;
+
+#if !defined (_MACGL) // OSX > 10.4.3 defines this
+ glColorTableEXTEx=(PFNGLCOLORTABLEEXT)NULL; // init ogl palette func pointer
+#endif
+
+#ifndef __sun
+ if(iGPUHeight!=1024 && // no pal textures in ZN mode (height=1024)!
+ strstr((char *)glGetString(GL_EXTENSIONS), // otherwise: check ogl support
+ "GL_EXT_paletted_texture"))
+ {
+ iUsePalTextures=1; // -> wow, supported, get func pointer
+
+#ifdef _WINDOWS
+ glColorTableEXTEx=(PFNGLCOLORTABLEEXT)wglGetProcAddress("glColorTableEXT");
+#elif defined (_MACGL)
+ // no prob, done already in OSX > 10.4.3
+#else
+ glColorTableEXTEx=(PFNGLCOLORTABLEEXT)glXGetProcAddress("glColorTableEXT");
+#endif
+
+ if(glColorTableEXTEx==NULL) iUsePalTextures=0; // -> ha, cheater... no func, no support
+
+ }
+ else iUsePalTextures=0;
+#else
+ iUsePalTextures=0;
+#endif
+}
+
+////////////////////////////////////////////////////////////////////////
+// Setup some stuff depending on user settings or in-game toggle
+////////////////////////////////////////////////////////////////////////
+
+void SetExtGLFuncs(void)
+{
+ //----------------------------------------------------//
+
+ SetFixes(); // update fix infos
+
+ //----------------------------------------------------//
+
+#ifdef _WINDOWS
+ if((iForceVSync>=0) && // force vsync?
+ strstr((char *)glGetString(GL_EXTENSIONS), // and extension available?
+ "WGL_EXT_swap_control"))
+ {
+ PFNWGLSWAPINTERVALFARPROC wglSwapIntervalEXT=
+ (PFNWGLSWAPINTERVALFARPROC)wglGetProcAddress("wglSwapIntervalEXT");
+
+ if(wglSwapIntervalEXT) wglSwapIntervalEXT(iForceVSync);
+ }
+#endif
+#ifdef _MACGL
+ SetVSync(iForceVSync);
+#endif
+ if(iUseExts && !(dwActFixes&1024) && // extensions wanted? and not turned off by game fix?
+ strstr((char *)glGetString(GL_EXTENSIONS), // and blend_subtract available?
+ "GL_EXT_blend_subtract"))
+ { // -> get ogl blend function pointer
+#ifdef _WINDOWS
+ glBlendEquationEXTEx=(PFNGLBLENDEQU)wglGetProcAddress("glBlendEquationEXT");
+#elif defined(_MACGL)
+ // no prob, OSX > 10.4.3 has this
+#else
+ glBlendEquationEXTEx=(PFNGLBLENDEQU)glXGetProcAddress("glBlendEquationEXT");
+#endif
+ }
+ else // no subtract blending?
+ {
+ if(glBlendEquationEXTEx) // -> change to additive blending (if subract was active)
+ glBlendEquationEXTEx(FUNC_ADD_EXT);
+#if !defined(_MACGL) // BTW, why set to null? strange...
+ glBlendEquationEXTEx=(PFNGLBLENDEQU)NULL; // -> no more blend function pointer
+#endif
+ }
+
+ //----------------------------------------------------//
+
+ if(iUseExts && bAdvancedBlend && // advanced blending wanted ?
+ strstr((char *)glGetString(GL_EXTENSIONS), // and extension avail?
+ "GL_EXT_texture_env_combine"))
+ {
+ bUseMultiPass=FALSE;bGLBlend=TRUE; // -> no need for 2 passes, perfect
+
+ glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, COMBINE_EXT);
+ glTexEnvf(GL_TEXTURE_ENV, COMBINE_RGB_EXT, GL_MODULATE);
+ glTexEnvf(GL_TEXTURE_ENV, COMBINE_ALPHA_EXT, GL_MODULATE);
+ glTexEnvf(GL_TEXTURE_ENV, RGB_SCALE_EXT, 2.0f);
+ }
+ else // no advanced blending wanted/available:
+ {
+ if(bAdvancedBlend) bUseMultiPass=TRUE; // -> pseudo-advanced with 2 passes
+ else bUseMultiPass=FALSE; // -> or simple 'bright color' mode
+ bGLBlend=FALSE; // -> no ext blending!
+
+ glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+ }
+
+ //----------------------------------------------------//
+ // init standard tex quality 0-2, and big alpha mode 3
+
+ if(!(dwActFixes&0x4000) && iFilterType && iTexQuality>=3)
+ bSmallAlpha=TRUE;
+ else bSmallAlpha=FALSE;
+
+ if(bOpaquePass) // opaque mode?
+ {
+ if(dwActFixes&32)
+ {
+ TCF[0]=CP8RGBA_0;
+ PalTexturedColourFn=CP8RGBA; // -> init col func
+ }
+ else
+ {
+ TCF[0]=XP8RGBA_0;
+ PalTexturedColourFn=XP8RGBA; // -> init col func
+ }
+
+ TCF[1]=XP8RGBA_1;
+ glAlphaFunc(GL_GREATER,0.49f);
+ }
+ else // no opaque mode?
+ {
+ TCF[0]=TCF[1]=P8RGBA;
+ PalTexturedColourFn=P8RGBA; // -> init col func
+ glAlphaFunc(GL_NOTEQUAL,0); // --> set alpha func
+ }
+
+ //----------------------------------------------------//
+
+ LoadSubTexFn=LoadSubTexturePageSort; // init load tex ptr
+
+ giWantedFMT=GL_RGBA; // init ogl tex format
+
+ switch(iTexQuality) // -> quality:
+ {
+ //--------------------------------------------------//
+ case 0: // -> don't care
+ giWantedRGBA=4;
+ giWantedTYPE=GL_UNSIGNED_BYTE;
+ break;
+ //--------------------------------------------------//
+ case 1: // -> R4G4B4A4
+ if(bGLExt)
+ {
+ giWantedRGBA=GL_RGBA4;
+ giWantedTYPE=GL_UNSIGNED_SHORT_4_4_4_4_EXT;
+ LoadSubTexFn=LoadPackedSubTexturePageSort;
+ if(bOpaquePass)
+ {
+ if(dwActFixes&32) PTCF[0]=CP4RGBA_0;
+ else PTCF[0]=XP4RGBA_0;
+ PTCF[1]=XP4RGBA_1;
+ }
+ else
+ {
+ PTCF[0]=PTCF[1]=P4RGBA;
+ }
+ }
+ else
+ {
+ giWantedRGBA=GL_RGBA4;
+ giWantedTYPE=GL_UNSIGNED_BYTE;
+ }
+ break;
+ //--------------------------------------------------//
+ case 2: // -> R5B5G5A1
+ if(bGLExt)
+ {
+ giWantedRGBA=GL_RGB5_A1;
+ giWantedTYPE=GL_UNSIGNED_SHORT_5_5_5_1_EXT;
+ LoadSubTexFn=LoadPackedSubTexturePageSort;
+ if(bOpaquePass)
+ {
+ if(dwActFixes&32) PTCF[0]=CP5RGBA_0;
+ else PTCF[0]=XP5RGBA_0;
+ PTCF[1]=XP5RGBA_1;
+ }
+ else
+ {
+ PTCF[0]=PTCF[1]=P5RGBA;
+ }
+ }
+ else
+ {
+ giWantedRGBA=GL_RGB5_A1;giWantedTYPE=GL_UNSIGNED_BYTE;
+ }
+ break;
+ //--------------------------------------------------//
+ case 3: // -> R8G8B8A8
+ giWantedRGBA=GL_RGBA8;
+ giWantedTYPE=GL_UNSIGNED_BYTE;
+
+ if(bSmallAlpha)
+ {
+ if(bOpaquePass) // opaque mode?
+ {
+ if(dwActFixes&32) {TCF[0]=CP8RGBAEx_0;PalTexturedColourFn=CP8RGBAEx;}
+ else {TCF[0]=XP8RGBAEx_0;PalTexturedColourFn=XP8RGBAEx;}
+ TCF[1]=XP8RGBAEx_1;
+ }
+ }
+
+ break;
+ //--------------------------------------------------//
+ case 4: // -> R8G8B8A8
+ giWantedRGBA = GL_RGBA8;
+ giWantedTYPE = GL_UNSIGNED_BYTE;
+
+ if(strstr((char *)glGetString(GL_EXTENSIONS), // and extension avail?
+ "GL_EXT_bgra"))
+ {
+ giWantedFMT = GL_BGRA_EXT;
+
+ if(bOpaquePass) // opaque mode?
+ {
+ if(bSmallAlpha)
+ {
+ if(dwActFixes&32) {TCF[0]=CP8BGRAEx_0;PalTexturedColourFn=CP8RGBAEx;}
+ else {TCF[0]=XP8BGRAEx_0;PalTexturedColourFn=XP8RGBAEx;}
+ TCF[1]=XP8BGRAEx_1;
+ }
+ else
+ {
+ if(dwActFixes&32) {TCF[0]=CP8BGRA_0;PalTexturedColourFn=CP8RGBA;}
+ else {TCF[0]=XP8BGRA_0;PalTexturedColourFn=XP8RGBA;}
+ TCF[1]=XP8BGRA_1;
+ }
+ }
+ else // no opaque mode?
+ {
+ TCF[0]=TCF[1]=P8BGRA; // -> init col func
+ }
+ }
+ else
+ {
+ iTexQuality=3;
+ if(bSmallAlpha)
+ {
+ if(bOpaquePass) // opaque mode?
+ {
+ if(dwActFixes&32) {TCF[0]=CP8RGBAEx_0;PalTexturedColourFn=CP8RGBAEx;}
+ else {TCF[0]=XP8RGBAEx_0;PalTexturedColourFn=XP8RGBAEx;}
+ TCF[1]=XP8RGBAEx_1;
+ }
+ }
+ }
+
+ break;
+ //--------------------------------------------------//
+ }
+
+ bBlendEnable=FALSE; // init blending: off
+ glDisable(GL_BLEND);
+
+ SetScanTrans(); // init scan lines (if wanted)
+}
+
+////////////////////////////////////////////////////////////////////////
+// setup scan lines
+////////////////////////////////////////////////////////////////////////
+
+#define R_TSP 0x00,0x45,0x00,0xff
+#define G_TSP 0x00,0x00,0x45,0xff
+#define B_TSP 0x45,0x00,0x00,0xff
+#define O_TSP 0x45,0x45,0x45,0xff
+#define N_TSP 0x00,0x00,0x00,0xff
+
+GLuint gTexScanName=0;
+
+GLubyte texscan[4][16]=
+{
+{R_TSP, G_TSP, B_TSP, N_TSP},
+{O_TSP, N_TSP, O_TSP, N_TSP},
+{B_TSP, N_TSP, R_TSP, G_TSP},
+{O_TSP, N_TSP, O_TSP, N_TSP}
+};
+
+void CreateScanLines(void)
+{
+ if(iUseScanLines)
+ {
+ int y;
+ if(iScanBlend<0) // special scan mask mode
+ {
+ glGenTextures(1, &gTexScanName);
+ glBindTexture(GL_TEXTURE_2D, gTexScanName);
+
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexImage2D(GL_TEXTURE_2D, 0, 4, 4, 4, 0,GL_RGBA, GL_UNSIGNED_BYTE, texscan);
+ }
+ else // otherwise simple lines in a display list
+ {
+ uiScanLine=glGenLists(1);
+ glNewList(uiScanLine,GL_COMPILE);
+ #ifdef _MACGL
+ // not mac specific, just commenting out to be friendly
+ // use it if you like
+ // this draws anti-aliased lines with user-chosen color
+ glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_CURRENT_BIT);
+ glEnable(GL_BLEND | GL_LINE_SMOOTH);
+ glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
+ glColor4f(iScanlineColor[0],iScanlineColor[1],iScanlineColor[2],iScanlineColor[3]);
+ glBegin(GL_LINES);
+ for(y=0;y<iResY;y+=2)
+ {
+ glVertex2f(0,y);
+ glVertex2f(iResX,y);
+ }
+ glEnd();
+ glPopAttrib();
+ #else
+ for(y=0;y<iResY;y+=2)
+ {
+ glBegin(GL_QUADS);
+ glVertex2f(0,y);
+ glVertex2f(iResX,y);
+ glVertex2f(iResX,y+1);
+ glVertex2f(0,y+1);
+ glEnd();
+ }
+
+ #endif
+ glEndList();
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+// Initialize OGL
+////////////////////////////////////////////////////////////////////////
+
+#ifdef _WINDOWS
+HGLRC GLCONTEXT=NULL;
+#endif
+
+int GLinitialize()
+{
+#ifdef _WINDOWS
+ HGLRC objectRC;
+ // init
+ dcGlobal = GetDC(hWWindow); // FIRST: dc/rc stuff
+ objectRC = wglCreateContext(dcGlobal);
+ GLCONTEXT=objectRC;
+ wglMakeCurrent(dcGlobal, objectRC);
+ // CheckWGLExtensions(dcGlobal);
+ if(bWindowMode) ReleaseDC(hWWindow,dcGlobal); // win mode: release dc again
+#endif
+#if defined (_MACGL)
+ BringContextForward();
+#endif
+ glViewport(rRatioRect.left, // init viewport by ratio rect
+ iResY-(rRatioRect.top+rRatioRect.bottom),
+ rRatioRect.right,
+ rRatioRect.bottom);
+
+ glScissor(0, 0, iResX, iResY); // init clipping (fullscreen)
+ glEnable(GL_SCISSOR_TEST);
+
+#ifndef OWNSCALE
+ glMatrixMode(GL_TEXTURE); // init psx tex sow and tow if not "ownscale"
+ glLoadIdentity();
+ glScalef(1.0f/255.99f,1.0f/255.99f,1.0f); // geforce precision hack
+#endif
+
+ glMatrixMode(GL_PROJECTION); // init projection with psx resolution
+ glLoadIdentity();
+ glOrtho(0,PSXDisplay.DisplayMode.x,
+ PSXDisplay.DisplayMode.y, 0, -1, 1);
+
+ if(iZBufferDepth) // zbuffer?
+ {
+ uiBufferBits=GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT;
+ glEnable(GL_DEPTH_TEST);
+ glDepthFunc(GL_ALWAYS);
+ iDepthFunc=1;
+ }
+ else // no zbuffer?
+ {
+ uiBufferBits=GL_COLOR_BUFFER_BIT;
+ glDisable(GL_DEPTH_TEST);
+ }
+
+ glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // first buffer clear
+ glClear(uiBufferBits);
+
+ if(bUseLines) // funny lines
+ {
+ glPolygonMode(GL_FRONT, GL_LINE);
+ glPolygonMode(GL_BACK, GL_LINE);
+ }
+ else // or the real filled thing
+ {
+ glPolygonMode(GL_FRONT, GL_FILL);
+ glPolygonMode(GL_BACK, GL_FILL);
+ }
+
+ MakeDisplayLists(); // lists for menu/opaque
+ GetExtInfos(); // get ext infos
+ SetExtGLFuncs(); // init all kind of stuff (tex function pointers)
+
+ glEnable(GL_ALPHA_TEST); // wanna alpha test
+
+ if(!bUseAntiAlias) // no anti-alias (default)
+ {
+ glDisable(GL_LINE_SMOOTH);
+ glDisable(GL_POLYGON_SMOOTH);
+ glDisable(GL_POINT_SMOOTH);
+ }
+ else // wanna try it? glitches galore...
+ {
+ glHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST);
+ glEnable(GL_LINE_SMOOTH);
+ glEnable(GL_POLYGON_SMOOTH);
+ glEnable(GL_POINT_SMOOTH);
+ glHint(GL_LINE_SMOOTH_HINT,GL_NICEST);
+ glHint(GL_POINT_SMOOTH_HINT,GL_NICEST);
+ glHint(GL_POLYGON_SMOOTH_HINT,GL_NICEST);
+ }
+
+ ubGloAlpha=127; // init some drawing vars
+ ubGloColAlpha=127;
+ TWin.UScaleFactor = 1;
+ TWin.VScaleFactor = 1;
+ bDrawMultiPass=FALSE;
+ bTexEnabled=FALSE;
+ bUsingTWin=FALSE;
+
+ if(bDrawDither) glEnable(GL_DITHER); // dither mode
+ else glDisable(GL_DITHER);
+
+ glDisable(GL_FOG); // turn all (currently) unused modes off
+ glDisable(GL_LIGHTING);
+ glDisable(GL_LOGIC_OP);
+ glDisable(GL_STENCIL_TEST);
+ glDisable(GL_TEXTURE_1D);
+ glDisable(GL_TEXTURE_2D);
+ glDisable(GL_CULL_FACE);
+
+ glPixelTransferi(GL_RED_SCALE, 1); // to be sure:
+ glPixelTransferi(GL_RED_BIAS, 0); // init more OGL vals
+ glPixelTransferi(GL_GREEN_SCALE, 1);
+ glPixelTransferi(GL_GREEN_BIAS, 0);
+ glPixelTransferi(GL_BLUE_SCALE, 1);
+ glPixelTransferi(GL_BLUE_BIAS, 0);
+ glPixelTransferi(GL_ALPHA_SCALE, 1);
+ glPixelTransferi(GL_ALPHA_BIAS, 0);
+
+#ifdef _WINDOWS
+ // detect Windows hw/sw mode (just for info)
+ if(!strcmp("Microsoft Corporation",(LPTSTR)glGetString(GL_VENDOR)) &&
+ !strcmp("GDI Generic", (LPTSTR)glGetString(GL_RENDERER)))
+ bGLSoft=TRUE;
+ else bGLSoft=FALSE;
+#endif
+
+ glFlush(); // we are done...
+ glFinish();
+
+ CreateScanLines(); // setup scanline stuff (if wanted)
+
+ CheckTextureMemory(); // check available tex memory
+
+ if(bKeepRatio) SetAspectRatio(); // set ratio
+
+ if(iShowFPS) // user wants FPS display on startup?
+ {
+ ulKeybits|=KEY_SHOWFPS; // -> ok, turn display on
+ szDispBuf[0]=0;
+ BuildDispMenu(0);
+ }
+
+ bIsFirstFrame = FALSE; // we have survived the first frame :)
+
+ return 0;
+}
+
+////////////////////////////////////////////////////////////////////////
+// clean up OGL stuff
+////////////////////////////////////////////////////////////////////////
+
+void GLcleanup()
+{
+ KillDisplayLists(); // bye display lists
+
+ if(iUseScanLines) // scanlines used?
+ {
+ if(iScanBlend<0)
+ {
+ if(gTexScanName!=0) // some scanline tex?
+ glDeleteTextures(1, &gTexScanName); // -> delete it
+ gTexScanName=0;
+ }
+ else glDeleteLists(uiScanLine,1); // otherwise del scanline display list
+ }
+
+ CleanupTextureStore(); // bye textures
+
+#ifdef _WINDOWS
+ wglMakeCurrent(NULL, NULL); // bye context
+ if(GLCONTEXT) wglDeleteContext(GLCONTEXT);
+ if(!bWindowMode && dcGlobal)
+ ReleaseDC(hWWindow,dcGlobal);
+#endif
+}
+
+////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+// Offset stuff
+////////////////////////////////////////////////////////////////////////
+
+// please note: it is hardly do-able in a hw/accel plugin to get the
+// real psx polygon coord mapping right... the following
+// works not to bad with many games, though
+
+__inline BOOL CheckCoord4()
+{
+ if(lx0<0)
+ {
+ if(((lx1-lx0)>CHKMAX_X) ||
+ ((lx2-lx0)>CHKMAX_X))
+ {
+ if(lx3<0)
+ {
+ if((lx1-lx3)>CHKMAX_X) return TRUE;
+ if((lx2-lx3)>CHKMAX_X) return TRUE;
+ }
+ }
+ }
+ if(lx1<0)
+ {
+ if((lx0-lx1)>CHKMAX_X) return TRUE;
+ if((lx2-lx1)>CHKMAX_X) return TRUE;
+ if((lx3-lx1)>CHKMAX_X) return TRUE;
+ }
+ if(lx2<0)
+ {
+ if((lx0-lx2)>CHKMAX_X) return TRUE;
+ if((lx1-lx2)>CHKMAX_X) return TRUE;
+ if((lx3-lx2)>CHKMAX_X) return TRUE;
+ }
+ if(lx3<0)
+ {
+ if(((lx1-lx3)>CHKMAX_X) ||
+ ((lx2-lx3)>CHKMAX_X))
+ {
+ if(lx0<0)
+ {
+ if((lx1-lx0)>CHKMAX_X) return TRUE;
+ if((lx2-lx0)>CHKMAX_X) return TRUE;
+ }
+ }
+ }
+
+
+ if(ly0<0)
+ {
+ if((ly1-ly0)>CHKMAX_Y) return TRUE;
+ if((ly2-ly0)>CHKMAX_Y) return TRUE;
+ }
+ if(ly1<0)
+ {
+ if((ly0-ly1)>CHKMAX_Y) return TRUE;
+ if((ly2-ly1)>CHKMAX_Y) return TRUE;
+ if((ly3-ly1)>CHKMAX_Y) return TRUE;
+ }
+ if(ly2<0)
+ {
+ if((ly0-ly2)>CHKMAX_Y) return TRUE;
+ if((ly1-ly2)>CHKMAX_Y) return TRUE;
+ if((ly3-ly2)>CHKMAX_Y) return TRUE;
+ }
+ if(ly3<0)
+ {
+ if((ly1-ly3)>CHKMAX_Y) return TRUE;
+ if((ly2-ly3)>CHKMAX_Y) return TRUE;
+ }
+
+ return FALSE;
+}
+
+__inline BOOL CheckCoord3()
+{
+ if(lx0<0)
+ {
+ if((lx1-lx0)>CHKMAX_X) return TRUE;
+ if((lx2-lx0)>CHKMAX_X) return TRUE;
+ }
+ if(lx1<0)
+ {
+ if((lx0-lx1)>CHKMAX_X) return TRUE;
+ if((lx2-lx1)>CHKMAX_X) return TRUE;
+ }
+ if(lx2<0)
+ {
+ if((lx0-lx2)>CHKMAX_X) return TRUE;
+ if((lx1-lx2)>CHKMAX_X) return TRUE;
+ }
+ if(ly0<0)
+ {
+ if((ly1-ly0)>CHKMAX_Y) return TRUE;
+ if((ly2-ly0)>CHKMAX_Y) return TRUE;
+ }
+ if(ly1<0)
+ {
+ if((ly0-ly1)>CHKMAX_Y) return TRUE;
+ if((ly2-ly1)>CHKMAX_Y) return TRUE;
+ }
+ if(ly2<0)
+ {
+ if((ly0-ly2)>CHKMAX_Y) return TRUE;
+ if((ly1-ly2)>CHKMAX_Y) return TRUE;
+ }
+
+ return FALSE;
+}
+
+
+__inline BOOL CheckCoord2()
+{
+ if(lx0<0)
+ {
+ if((lx1-lx0)>CHKMAX_X) return TRUE;
+ }
+ if(lx1<0)
+ {
+ if((lx0-lx1)>CHKMAX_X) return TRUE;
+ }
+ if(ly0<0)
+ {
+ if((ly1-ly0)>CHKMAX_Y) return TRUE;
+ }
+ if(ly1<0)
+ {
+ if((ly0-ly1)>CHKMAX_Y) return TRUE;
+ }
+
+ return FALSE;
+}
+
+/*
+//Lewpys "offsetline" func:
+
+void offsetline(void)
+{
+ float x0, x1, y0, y1, oolength, xl, yl;
+
+ if(bDisplayNotSet)
+ SetOGLDisplaySettings(1);
+
+ if(!(dwActFixes&16))
+ {
+ if((lx0 & SIGNBIT)) lx0|=S_MASK;
+ else lx0&=~S_MASK;
+ if((lx1 & SIGNBIT)) lx1|=S_MASK;
+ else lx1&=~S_MASK;
+ if((ly0 & SIGNBIT)) ly0|=S_MASK;
+ else ly0&=~S_MASK;
+ if((ly1 & SIGNBIT)) ly1|=S_MASK;
+ else ly1&=~S_MASK;
+ }
+
+ x0 = (float)(lx0 + PSXDisplay.CumulOffset.x);
+ x1 = (float)(lx1 + PSXDisplay.CumulOffset.x);
+ y0 = (float)(ly0 + PSXDisplay.CumulOffset.y);
+ y1 = (float)(ly1 + PSXDisplay.CumulOffset.y);
+
+ oolength = (float)1/((float)sqrt((y1 - y0)*(y1 - y0) + (x1 - x0)*(x1 - x0)) * (float)2);
+// oolength = (float)1/((float)sqrt(((y1 - y0)*(y1 - y0) + (x1 - x0)*(x1 - x0)) * (float)2));
+
+ xl = (x1 - x0) * oolength;
+ yl = (y1 - y0) * oolength;
+
+ x0 += 0.5f;
+ x1 += 0.5f;
+
+ x0 -= xl - yl;
+ x1 += xl + yl;
+ y0 -= yl + xl;
+ y1 += yl - xl;
+
+ vertex[0].x=x0;
+ vertex[1].x=x1;
+ vertex[0].y=y0;
+ vertex[1].y=y1;
+
+ x0 -= yl * 2;
+ x1 -= yl * 2;
+ y0 += xl * 2;
+ y1 += xl * 2;
+
+ vertex[2].x=x1;
+ vertex[3].x=x0;
+ vertex[2].y=y1;
+ vertex[3].y=y0;
+}
+*/
+
+
+// Pete's way: a very easy (and hopefully fast) approach for lines
+// without sqrt... using a small float -> short cast trick :)
+
+#define VERTEX_OFFX 0.2f
+#define VERTEX_OFFY 0.2f
+
+BOOL offsetline(void)
+{
+ short x0,x1,y0,y1,dx,dy;float px,py;
+
+ if(bDisplayNotSet)
+ SetOGLDisplaySettings(1);
+
+ if(!(dwActFixes&16))
+ {
+ lx0=(short)(((int)lx0<<SIGNSHIFT)>>SIGNSHIFT);
+ lx1=(short)(((int)lx1<<SIGNSHIFT)>>SIGNSHIFT);
+ ly0=(short)(((int)ly0<<SIGNSHIFT)>>SIGNSHIFT);
+ ly1=(short)(((int)ly1<<SIGNSHIFT)>>SIGNSHIFT);
+
+ if(CheckCoord2()) return TRUE;
+ }
+
+ x0 = (lx0 + PSXDisplay.CumulOffset.x)+1;
+ x1 = (lx1 + PSXDisplay.CumulOffset.x)+1;
+ y0 = (ly0 + PSXDisplay.CumulOffset.y)+1;
+ y1 = (ly1 + PSXDisplay.CumulOffset.y)+1;
+
+ dx=x1-x0;
+ dy=y1-y0;
+
+ if(dx>=0)
+ {
+ if(dy>=0)
+ {
+ px=0.5f;
+ if(dx>dy) py=-0.5f;
+ else if(dx<dy) py= 0.5f;
+ else py= 0.0f;
+ }
+ else
+ {
+ py=-0.5f;
+ dy=-dy;
+ if(dx>dy) px= 0.5f;
+ else if(dx<dy) px=-0.5f;
+ else px= 0.0f;
+ }
+ }
+ else
+ {
+ if(dy>=0)
+ {
+ py=0.5f;
+ dx=-dx;
+ if(dx>dy) px=-0.5f;
+ else if(dx<dy) px= 0.5f;
+ else px= 0.0f;
+ }
+ else
+ {
+ px=-0.5f;
+ if(dx>dy) py=-0.5f;
+ else if(dx<dy) py= 0.5f;
+ else py= 0.0f;
+ }
+ }
+
+ vertex[0].x=(short)((float)x0-px);
+ vertex[3].x=(short)((float)x0+py);
+
+ vertex[0].y=(short)((float)y0-py);
+ vertex[3].y=(short)((float)y0-px);
+
+ vertex[1].x=(short)((float)x1-py);
+ vertex[2].x=(short)((float)x1+px);
+
+ vertex[1].y=(short)((float)y1+px);
+ vertex[2].y=(short)((float)y1+py);
+
+ if(vertex[0].x==vertex[3].x && // ortho rect? done
+ vertex[1].x==vertex[2].x &&
+ vertex[0].y==vertex[1].y &&
+ vertex[2].y==vertex[3].y) return FALSE;
+ if(vertex[0].x==vertex[1].x &&
+ vertex[2].x==vertex[3].x &&
+ vertex[0].y==vertex[3].y &&
+ vertex[1].y==vertex[2].y) return FALSE;
+
+ vertex[0].x-=VERTEX_OFFX; // otherwise a small offset
+ vertex[0].y-=VERTEX_OFFY; // to get better accuracy
+ vertex[1].x-=VERTEX_OFFX;
+ vertex[1].y-=VERTEX_OFFY;
+ vertex[2].x-=VERTEX_OFFX;
+ vertex[2].y-=VERTEX_OFFY;
+ vertex[3].x-=VERTEX_OFFX;
+ vertex[3].y-=VERTEX_OFFY;
+
+ return FALSE;
+}
+
+/////////////////////////////////////////////////////////
+
+BOOL offset2(void)
+{
+ if(bDisplayNotSet)
+ SetOGLDisplaySettings(1);
+
+ if(!(dwActFixes&16))
+ {
+ lx0=(short)(((int)lx0<<SIGNSHIFT)>>SIGNSHIFT);
+ lx1=(short)(((int)lx1<<SIGNSHIFT)>>SIGNSHIFT);
+ ly0=(short)(((int)ly0<<SIGNSHIFT)>>SIGNSHIFT);
+ ly1=(short)(((int)ly1<<SIGNSHIFT)>>SIGNSHIFT);
+
+ if(CheckCoord2()) return TRUE;
+ }
+
+ vertex[0].x=lx0+PSXDisplay.CumulOffset.x;
+ vertex[1].x=lx1+PSXDisplay.CumulOffset.x;
+ vertex[0].y=ly0+PSXDisplay.CumulOffset.y;
+ vertex[1].y=ly1+PSXDisplay.CumulOffset.y;
+
+ return FALSE;
+}
+
+/////////////////////////////////////////////////////////
+
+BOOL offset3(void)
+{
+ if(bDisplayNotSet)
+ SetOGLDisplaySettings(1);
+
+ if(!(dwActFixes&16))
+ {
+ lx0=(short)(((int)lx0<<SIGNSHIFT)>>SIGNSHIFT);
+ lx1=(short)(((int)lx1<<SIGNSHIFT)>>SIGNSHIFT);
+ lx2=(short)(((int)lx2<<SIGNSHIFT)>>SIGNSHIFT);
+ ly0=(short)(((int)ly0<<SIGNSHIFT)>>SIGNSHIFT);
+ ly1=(short)(((int)ly1<<SIGNSHIFT)>>SIGNSHIFT);
+ ly2=(short)(((int)ly2<<SIGNSHIFT)>>SIGNSHIFT);
+
+ if(CheckCoord3()) return TRUE;
+ }
+
+ vertex[0].x=lx0+PSXDisplay.CumulOffset.x;
+ vertex[1].x=lx1+PSXDisplay.CumulOffset.x;
+ vertex[2].x=lx2+PSXDisplay.CumulOffset.x;
+ vertex[0].y=ly0+PSXDisplay.CumulOffset.y;
+ vertex[1].y=ly1+PSXDisplay.CumulOffset.y;
+ vertex[2].y=ly2+PSXDisplay.CumulOffset.y;
+
+ return FALSE;
+}
+
+/////////////////////////////////////////////////////////
+
+BOOL offset4(void)
+{
+ if(bDisplayNotSet)
+ SetOGLDisplaySettings(1);
+
+ if(!(dwActFixes&16))
+ {
+ lx0=(short)(((int)lx0<<SIGNSHIFT)>>SIGNSHIFT);
+ lx1=(short)(((int)lx1<<SIGNSHIFT)>>SIGNSHIFT);
+ lx2=(short)(((int)lx2<<SIGNSHIFT)>>SIGNSHIFT);
+ lx3=(short)(((int)lx3<<SIGNSHIFT)>>SIGNSHIFT);
+ ly0=(short)(((int)ly0<<SIGNSHIFT)>>SIGNSHIFT);
+ ly1=(short)(((int)ly1<<SIGNSHIFT)>>SIGNSHIFT);
+ ly2=(short)(((int)ly2<<SIGNSHIFT)>>SIGNSHIFT);
+ ly3=(short)(((int)ly3<<SIGNSHIFT)>>SIGNSHIFT);
+
+ if(CheckCoord4()) return TRUE;
+ }
+
+ vertex[0].x=lx0+PSXDisplay.CumulOffset.x;
+ vertex[1].x=lx1+PSXDisplay.CumulOffset.x;
+ vertex[2].x=lx2+PSXDisplay.CumulOffset.x;
+ vertex[3].x=lx3+PSXDisplay.CumulOffset.x;
+ vertex[0].y=ly0+PSXDisplay.CumulOffset.y;
+ vertex[1].y=ly1+PSXDisplay.CumulOffset.y;
+ vertex[2].y=ly2+PSXDisplay.CumulOffset.y;
+ vertex[3].y=ly3+PSXDisplay.CumulOffset.y;
+
+ return FALSE;
+}
+
+/////////////////////////////////////////////////////////
+
+void offsetST(void)
+{
+ if(bDisplayNotSet)
+ SetOGLDisplaySettings(1);
+
+ if(!(dwActFixes&16))
+ {
+ lx0=(short)(((int)lx0<<SIGNSHIFT)>>SIGNSHIFT);
+ ly0=(short)(((int)ly0<<SIGNSHIFT)>>SIGNSHIFT);
+
+ if(lx0<-512 && PSXDisplay.DrawOffset.x<=-512)
+ lx0+=2048;
+
+ if(ly0<-512 && PSXDisplay.DrawOffset.y<=-512)
+ ly0+=2048;
+ }
+
+ ly1 = ly0;
+ ly2 = ly3 = ly0+sprtH;
+ lx3 = lx0;
+ lx1 = lx2 = lx0+sprtW;
+
+ vertex[0].x=lx0+PSXDisplay.CumulOffset.x;
+ vertex[1].x=lx1+PSXDisplay.CumulOffset.x;
+ vertex[2].x=lx2+PSXDisplay.CumulOffset.x;
+ vertex[3].x=lx3+PSXDisplay.CumulOffset.x;
+ vertex[0].y=ly0+PSXDisplay.CumulOffset.y;
+ vertex[1].y=ly1+PSXDisplay.CumulOffset.y;
+ vertex[2].y=ly2+PSXDisplay.CumulOffset.y;
+ vertex[3].y=ly3+PSXDisplay.CumulOffset.y;
+}
+
+/////////////////////////////////////////////////////////
+
+void offsetScreenUpload(int Position)
+{
+ if(bDisplayNotSet)
+ SetOGLDisplaySettings(1);
+
+ if(Position==-1)
+ {
+ int lmdx,lmdy;
+
+ lmdx=xrUploadArea.x0;
+ lmdy=xrUploadArea.y0;
+
+ lx0-=lmdx;
+ ly0-=lmdy;
+ lx1-=lmdx;
+ ly1-=lmdy;
+ lx2-=lmdx;
+ ly2-=lmdy;
+ lx3-=lmdx;
+ ly3-=lmdy;
+ }
+ else
+ if(Position)
+ {
+ lx0-=PSXDisplay.DisplayPosition.x;
+ ly0-=PSXDisplay.DisplayPosition.y;
+ lx1-=PSXDisplay.DisplayPosition.x;
+ ly1-=PSXDisplay.DisplayPosition.y;
+ lx2-=PSXDisplay.DisplayPosition.x;
+ ly2-=PSXDisplay.DisplayPosition.y;
+ lx3-=PSXDisplay.DisplayPosition.x;
+ ly3-=PSXDisplay.DisplayPosition.y;
+ }
+ else
+ {
+ lx0-=PreviousPSXDisplay.DisplayPosition.x;
+ ly0-=PreviousPSXDisplay.DisplayPosition.y;
+ lx1-=PreviousPSXDisplay.DisplayPosition.x;
+ ly1-=PreviousPSXDisplay.DisplayPosition.y;
+ lx2-=PreviousPSXDisplay.DisplayPosition.x;
+ ly2-=PreviousPSXDisplay.DisplayPosition.y;
+ lx3-=PreviousPSXDisplay.DisplayPosition.x;
+ ly3-=PreviousPSXDisplay.DisplayPosition.y;
+ }
+
+ vertex[0].x=lx0 + PreviousPSXDisplay.Range.x0;
+ vertex[1].x=lx1 + PreviousPSXDisplay.Range.x0;
+ vertex[2].x=lx2 + PreviousPSXDisplay.Range.x0;
+ vertex[3].x=lx3 + PreviousPSXDisplay.Range.x0;
+ vertex[0].y=ly0 + PreviousPSXDisplay.Range.y0;
+ vertex[1].y=ly1 + PreviousPSXDisplay.Range.y0;
+ vertex[2].y=ly2 + PreviousPSXDisplay.Range.y0;
+ vertex[3].y=ly3 + PreviousPSXDisplay.Range.y0;
+
+ if(iUseMask)
+ {
+ vertex[0].z=vertex[1].z=vertex[2].z=vertex[3].z=gl_z;
+ gl_z+=0.00004f;
+ }
+}
+
+/////////////////////////////////////////////////////////
+
+void offsetBlk(void)
+{
+ if(bDisplayNotSet)
+ SetOGLDisplaySettings(1);
+
+ vertex[0].x=lx0-PSXDisplay.GDrawOffset.x + PreviousPSXDisplay.Range.x0;
+ vertex[1].x=lx1-PSXDisplay.GDrawOffset.x + PreviousPSXDisplay.Range.x0;
+ vertex[2].x=lx2-PSXDisplay.GDrawOffset.x + PreviousPSXDisplay.Range.x0;
+ vertex[3].x=lx3-PSXDisplay.GDrawOffset.x + PreviousPSXDisplay.Range.x0;
+ vertex[0].y=ly0-PSXDisplay.GDrawOffset.y + PreviousPSXDisplay.Range.y0;
+ vertex[1].y=ly1-PSXDisplay.GDrawOffset.y + PreviousPSXDisplay.Range.y0;
+ vertex[2].y=ly2-PSXDisplay.GDrawOffset.y + PreviousPSXDisplay.Range.y0;
+ vertex[3].y=ly3-PSXDisplay.GDrawOffset.y + PreviousPSXDisplay.Range.y0;
+
+ if(iUseMask)
+ {
+ vertex[0].z=vertex[1].z=vertex[2].z=vertex[3].z=gl_z;
+ gl_z+=0.00004f;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+// texture sow/tow calculations
+////////////////////////////////////////////////////////////////////////
+
+void assignTextureVRAMWrite(void)
+{
+#ifdef OWNSCALE
+
+ vertex[0].sow=0.5f/ ST_FACVRAMX;
+ vertex[0].tow=0.5f/ ST_FACVRAM;
+
+ vertex[1].sow=(float)gl_ux[1]/ ST_FACVRAMX;
+ vertex[1].tow=0.5f/ ST_FACVRAM;
+
+ vertex[2].sow=(float)gl_ux[2]/ ST_FACVRAMX;
+ vertex[2].tow=(float)gl_vy[2]/ ST_FACVRAM;
+
+ vertex[3].sow=0.5f/ ST_FACVRAMX;
+ vertex[3].tow=(float)gl_vy[3]/ ST_FACVRAM;
+
+#else
+
+ if(gl_ux[1]==255)
+ {
+ vertex[0].sow=(gl_ux[0]*255.99f)/255.0f;
+ vertex[1].sow=(gl_ux[1]*255.99f)/255.0f;
+ vertex[2].sow=(gl_ux[2]*255.99f)/255.0f;
+ vertex[3].sow=(gl_ux[3]*255.99f)/255.0f;
+ }
+ else
+ {
+ vertex[0].sow=gl_ux[0];
+ vertex[1].sow=gl_ux[1];
+ vertex[2].sow=gl_ux[2];
+ vertex[3].sow=gl_ux[3];
+ }
+
+ vertex[0].tow=gl_vy[0];
+ vertex[1].tow=gl_vy[1];
+ vertex[2].tow=gl_vy[2];
+ vertex[3].tow=gl_vy[3];
+
+#endif
+}
+
+GLuint gLastTex=0;
+GLuint gLastFMode=(GLuint)-1;
+
+/////////////////////////////////////////////////////////
+
+void assignTextureSprite(void)
+{
+ if(bUsingTWin)
+ {
+ vertex[0].sow=vertex[3].sow=(float)gl_ux[0]/TWin.UScaleFactor;
+ vertex[1].sow=vertex[2].sow=(float)sSprite_ux2/TWin.UScaleFactor;
+ vertex[0].tow=vertex[1].tow=(float)gl_vy[0]/TWin.VScaleFactor;
+ vertex[2].tow=vertex[3].tow=(float)sSprite_vy2/TWin.VScaleFactor;
+ gLastTex=gTexName;
+
+ if(iFilterType>0 && iFilterType<3 && iHiResTextures!=2)
+ {
+ float fxmin=65536.0f,fxmax=0.0f,fymin=65536.0f,fymax=0.0f;int i;
+
+ for(i=0;i<4;i++)
+ {
+ if(vertex[i].sow<fxmin) fxmin=vertex[i].sow;
+ if(vertex[i].tow<fymin) fymin=vertex[i].tow;
+ if(vertex[i].sow>fxmax) fxmax=vertex[i].sow;
+ if(vertex[i].tow>fymax) fymax=vertex[i].tow;
+ }
+
+ for(i=0;i<4;i++)
+ {
+#ifdef OWNSCALE
+ if(vertex[i].sow==fxmin) vertex[i].sow+=0.375f/(float)TWin.Position.x1;
+ if(vertex[i].sow==fxmax) vertex[i].sow-=0.375f/(float)TWin.Position.x1;
+ if(vertex[i].tow==fymin) vertex[i].tow+=0.375f/(float)TWin.Position.y1;
+ if(vertex[i].tow==fymax) vertex[i].tow-=0.375f/(float)TWin.Position.y1;
+#else
+ if(vertex[i].sow==fxmin) vertex[i].sow+=96.0f/(float)TWin.Position.x1;
+ if(vertex[i].sow==fxmax) vertex[i].sow-=96.0f/(float)TWin.Position.x1;
+ if(vertex[i].tow==fymin) vertex[i].tow+=96.0f/(float)TWin.Position.y1;
+ if(vertex[i].tow==fymax) vertex[i].tow-=96.0f/(float)TWin.Position.y1;
+#endif
+ }
+ }
+
+ }
+ else
+ {
+#ifdef OWNSCALE
+
+ vertex[0].sow=vertex[3].sow=(float)gl_ux[0] / ST_FACSPRITE;
+ vertex[1].sow=vertex[2].sow=(float)sSprite_ux2 / ST_FACSPRITE;
+ vertex[0].tow=vertex[1].tow=(float)gl_vy[0] / ST_FACSPRITE;
+ vertex[2].tow=vertex[3].tow=(float)sSprite_vy2 / ST_FACSPRITE;
+
+#else
+
+ vertex[0].sow=vertex[3].sow=gl_ux[0];
+ vertex[1].sow=vertex[2].sow=sSprite_ux2;
+ vertex[0].tow=vertex[1].tow=gl_vy[0];
+ vertex[2].tow=vertex[3].tow=sSprite_vy2;
+
+#endif
+
+ if(iFilterType>2)
+ {
+ if(gLastTex!=gTexName || gLastFMode!=0)
+ {
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ gLastTex=gTexName;gLastFMode=0;
+ }
+ }
+ }
+
+ if(usMirror & 0x1000)
+ {
+ vertex[0].sow=vertex[1].sow;
+ vertex[1].sow=vertex[2].sow=vertex[3].sow;
+ vertex[3].sow=vertex[0].sow;
+ }
+
+ if(usMirror & 0x2000)
+ {
+ vertex[0].tow=vertex[3].tow;
+ vertex[2].tow=vertex[3].tow=vertex[1].tow;
+ vertex[1].tow=vertex[0].tow;
+ }
+
+}
+
+/////////////////////////////////////////////////////////
+
+void assignTexture3(void)
+{
+ if(bUsingTWin)
+ {
+ vertex[0].sow=(float)gl_ux[0]/TWin.UScaleFactor;
+ vertex[0].tow=(float)gl_vy[0]/TWin.VScaleFactor;
+ vertex[1].sow=(float)gl_ux[1]/TWin.UScaleFactor;
+ vertex[1].tow=(float)gl_vy[1]/TWin.VScaleFactor;
+ vertex[2].sow=(float)gl_ux[2]/TWin.UScaleFactor;
+ vertex[2].tow=(float)gl_vy[2]/TWin.VScaleFactor;
+ gLastTex=gTexName;
+ }
+ else
+ {
+#ifdef OWNSCALE
+ vertex[0].sow=(float)gl_ux[0] / ST_FACTRI;
+ vertex[0].tow=(float)gl_vy[0] / ST_FACTRI;
+ vertex[1].sow=(float)gl_ux[1] / ST_FACTRI;
+
+ vertex[1].tow=(float)gl_vy[1] / ST_FACTRI;
+ vertex[2].sow=(float)gl_ux[2] / ST_FACTRI;
+ vertex[2].tow=(float)gl_vy[2] / ST_FACTRI;
+#else
+ vertex[0].sow=gl_ux[0];
+ vertex[0].tow=gl_vy[0];
+ vertex[1].sow=gl_ux[1];
+ vertex[1].tow=gl_vy[1];
+ vertex[2].sow=gl_ux[2];
+ vertex[2].tow=gl_vy[2];
+#endif
+
+ if(iFilterType>2)
+ {
+ if(gLastTex!=gTexName || gLastFMode!=1)
+ {
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ gLastTex=gTexName;gLastFMode=1;
+ }
+ }
+
+ if(iFilterType)
+ {
+ float fxmin=256.0f,fxmax=0.0f,fymin=256.0f,fymax=0.0f;int i;
+ for(i=0;i<3;i++)
+ {
+ if(vertex[i].sow<fxmin) fxmin=vertex[i].sow;
+ if(vertex[i].tow<fymin) fymin=vertex[i].tow;
+ if(vertex[i].sow>fxmax) fxmax=vertex[i].sow;
+ if(vertex[i].tow>fymax) fymax=vertex[i].tow;
+ }
+
+ for(i=0;i<3;i++)
+ {
+ if(vertex[i].sow==fxmin) vertex[i].sow+=ST_BFFACSORT;
+ if(vertex[i].sow==fxmax) vertex[i].sow-=ST_BFFACSORT;
+ if(vertex[i].tow==fymin) vertex[i].tow+=ST_BFFACSORT;
+ if(vertex[i].tow==fymax) vertex[i].tow-=ST_BFFACSORT;
+ }
+ }
+ }
+}
+
+/////////////////////////////////////////////////////////
+
+void assignTexture4(void)
+{
+ if(bUsingTWin)
+ {
+ vertex[0].sow=(float)gl_ux[0]/TWin.UScaleFactor;
+ vertex[0].tow=(float)gl_vy[0]/TWin.VScaleFactor;
+ vertex[1].sow=(float)gl_ux[1]/TWin.UScaleFactor;
+ vertex[1].tow=(float)gl_vy[1]/TWin.VScaleFactor;
+ vertex[2].sow=(float)gl_ux[2]/TWin.UScaleFactor;
+ vertex[2].tow=(float)gl_vy[2]/TWin.VScaleFactor;
+ vertex[3].sow=(float)gl_ux[3]/TWin.UScaleFactor;
+ vertex[3].tow=(float)gl_vy[3]/TWin.VScaleFactor;
+ gLastTex=gTexName;
+ }
+ else
+ {
+#ifdef OWNSCALE
+ vertex[0].sow=(float)gl_ux[0] / ST_FAC;
+ vertex[0].tow=(float)gl_vy[0] / ST_FAC;
+ vertex[1].sow=(float)gl_ux[1] / ST_FAC;
+ vertex[1].tow=(float)gl_vy[1] / ST_FAC;
+ vertex[2].sow=(float)gl_ux[2] / ST_FAC;
+ vertex[2].tow=(float)gl_vy[2] / ST_FAC;
+ vertex[3].sow=(float)gl_ux[3] / ST_FAC;
+ vertex[3].tow=(float)gl_vy[3] / ST_FAC;
+#else
+ vertex[0].sow=gl_ux[0];
+ vertex[0].tow=gl_vy[0];
+ vertex[1].sow=gl_ux[1];
+ vertex[1].tow=gl_vy[1];
+ vertex[2].sow=gl_ux[2];
+ vertex[2].tow=gl_vy[2];
+ vertex[3].sow=gl_ux[3];
+ vertex[3].tow=gl_vy[3];
+#endif
+
+ if(iFilterType>2)
+ {
+ if(gLastTex!=gTexName || gLastFMode!=1)
+ {
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ gLastTex=gTexName;gLastFMode=1;
+ }
+ }
+
+ if(iFilterType)
+ {
+ float fxmin=256.0f,fxmax=0.0f,fymin=256.0f,fymax=0.0f;int i;
+ for(i=0;i<4;i++)
+ {
+ if(vertex[i].sow<fxmin) fxmin=vertex[i].sow;
+ if(vertex[i].tow<fymin) fymin=vertex[i].tow;
+ if(vertex[i].sow>fxmax) fxmax=vertex[i].sow;
+ if(vertex[i].tow>fymax) fymax=vertex[i].tow;
+ }
+
+ for(i=0;i<4;i++)
+ {
+ if(vertex[i].sow==fxmin) vertex[i].sow+=ST_BFFACSORT;
+ if(vertex[i].sow==fxmax) vertex[i].sow-=ST_BFFACSORT;
+ if(vertex[i].tow==fymin) vertex[i].tow+=ST_BFFACSORT;
+ if(vertex[i].tow==fymax) vertex[i].tow-=ST_BFFACSORT;
+ }
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+// render pos / buffers
+////////////////////////////////////////////////////////////////////////
+
+#ifndef _WINDOWS
+#define EqualRect(pr1,pr2) ((pr1)->left==(pr2)->left && (pr1)->top==(pr2)->top && (pr1)->right==(pr2)->right && (pr1)->bottom==(pr2)->bottom)
+#endif
+
+////////////////////////////////////////////////////////////////////////
+// SetDisplaySettings: "simply" calcs the new drawing area and updates
+// the ogl clipping (scissor)
+
+BOOL bSetClip=FALSE;
+
+void SetOGLDisplaySettings(BOOL DisplaySet)
+{
+ static RECT rprev={0,0,0,0};
+ static RECT rC ={0,0,0,0};
+ static int iOldX=0;
+ static int iOldY=0;
+ RECT r;float XS,YS;
+
+ bDisplayNotSet = FALSE;
+
+ //----------------------------------------------------// that's a whole screen upload
+ if(!DisplaySet)
+ {
+ RECT rX;
+ PSXDisplay.GDrawOffset.x=0;
+ PSXDisplay.GDrawOffset.y=0;
+
+ PSXDisplay.CumulOffset.x = PSXDisplay.DrawOffset.x+PreviousPSXDisplay.Range.x0;
+ PSXDisplay.CumulOffset.y = PSXDisplay.DrawOffset.y+PreviousPSXDisplay.Range.y0;
+
+ rprev.left=rprev.left+1;
+
+ rX=rRatioRect;
+ rX.top=iResY-(rRatioRect.top+rRatioRect.bottom);
+
+ if(bSetClip || !EqualRect(&rC,&rX))
+ {
+ rC=rX;
+ glScissor(rC.left,rC.top,rC.right,rC.bottom);
+ bSetClip=FALSE;
+ }
+ return;
+ }
+ //----------------------------------------------------//
+
+ PSXDisplay.GDrawOffset.y = PreviousPSXDisplay.DisplayPosition.y;
+ PSXDisplay.GDrawOffset.x = PreviousPSXDisplay.DisplayPosition.x;
+ PSXDisplay.CumulOffset.x = PSXDisplay.DrawOffset.x - PSXDisplay.GDrawOffset.x+PreviousPSXDisplay.Range.x0;
+ PSXDisplay.CumulOffset.y = PSXDisplay.DrawOffset.y - PSXDisplay.GDrawOffset.y+PreviousPSXDisplay.Range.y0;
+
+ r.top =PSXDisplay.DrawArea.y0 - PreviousPSXDisplay.DisplayPosition.y;
+ r.bottom=PSXDisplay.DrawArea.y1 - PreviousPSXDisplay.DisplayPosition.y;
+
+ if(r.bottom<0 || r.top>=PSXDisplay.DisplayMode.y)
+ {
+ r.top =PSXDisplay.DrawArea.y0 - PSXDisplay.DisplayPosition.y;
+ r.bottom=PSXDisplay.DrawArea.y1 - PSXDisplay.DisplayPosition.y;
+ }
+
+ r.left =PSXDisplay.DrawArea.x0 - PreviousPSXDisplay.DisplayPosition.x;
+ r.right =PSXDisplay.DrawArea.x1 - PreviousPSXDisplay.DisplayPosition.x;
+
+ if(r.right<0 || r.left>=PSXDisplay.DisplayMode.x)
+ {
+ r.left =PSXDisplay.DrawArea.x0 - PSXDisplay.DisplayPosition.x;
+ r.right =PSXDisplay.DrawArea.x1 - PSXDisplay.DisplayPosition.x;
+ }
+
+ if(!bSetClip && EqualRect(&r,&rprev) &&
+ iOldX == PSXDisplay.DisplayMode.x &&
+ iOldY == PSXDisplay.DisplayMode.y)
+ return;
+
+ rprev = r;
+ iOldX = PSXDisplay.DisplayMode.x;
+ iOldY = PSXDisplay.DisplayMode.y;
+
+ XS=(float)rRatioRect.right/(float)PSXDisplay.DisplayMode.x;
+ YS=(float)rRatioRect.bottom/(float)PSXDisplay.DisplayMode.y;
+
+ if(PreviousPSXDisplay.Range.x0)
+ {
+ short s=PreviousPSXDisplay.Range.x0+PreviousPSXDisplay.Range.x1;
+
+ r.left+=PreviousPSXDisplay.Range.x0+1;
+
+ r.right+=PreviousPSXDisplay.Range.x0;
+
+ if(r.left>s) r.left=s;
+ if(r.right>s) r.right=s;
+ }
+
+ if(PreviousPSXDisplay.Range.y0)
+ {
+ short s=PreviousPSXDisplay.Range.y0+PreviousPSXDisplay.Range.y1;
+
+ r.top+=PreviousPSXDisplay.Range.y0+1;
+ r.bottom+=PreviousPSXDisplay.Range.y0;
+
+ if(r.top>s) r.top=s;
+ if(r.bottom>s) r.bottom=s;
+ }
+
+ // Set the ClipArea variables to reflect the new screen,
+ // offset from zero (since it is a new display buffer)
+ r.left = (int)(((float)(r.left)) *XS);
+ r.top = (int)(((float)(r.top)) *YS);
+ r.right = (int)(((float)(r.right + 1))*XS);
+ r.bottom = (int)(((float)(r.bottom + 1))*YS);
+
+ // Limit clip area to the screen size
+ if (r.left > iResX) r.left = iResX;
+ if (r.left < 0) r.left = 0;
+ if (r.top > iResY) r.top = iResY;
+ if (r.top < 0) r.top = 0;
+ if (r.right > iResX) r.right = iResX;
+ if (r.right < 0) r.right = 0;
+ if (r.bottom > iResY) r.bottom = iResY;
+ if (r.bottom < 0) r.bottom = 0;
+
+ r.right -=r.left;
+ r.bottom-=r.top;
+ r.top=iResY-(r.top+r.bottom);
+
+ r.left+=rRatioRect.left;
+ r.top -=rRatioRect.top;
+
+ if(bSetClip || !EqualRect(&r,&rC))
+ {
+ glScissor(r.left,r.top,r.right,r.bottom);
+ rC=r;
+ bSetClip=FALSE;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////
+
diff --git a/plugins/peopsxgl/fps.c b/plugins/peopsxgl/fps.c index e7e0b3fe..dc89600f 100644 --- a/plugins/peopsxgl/fps.c +++ b/plugins/peopsxgl/fps.c @@ -1,399 +1,396 @@ -/*************************************************************************** - fps.c - description - ------------------- - begin : Sun Mar 08 2009 - copyright : (C) 1999-2009 by Pete Bernert - web : www.pbernert.com - ***************************************************************************/ - -/*************************************************************************** - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. See also the license.txt file for * - * additional informations. * - * * - ***************************************************************************/ - -//*************************************************************************// -// History of changes: -// -// 2009/03/08 - Pete -// - generic cleanup for the Peops release -// -//*************************************************************************// - -#include "stdafx.h" - -#define _IN_FPS - -#include "externals.h" -#include "fps.h" - -//////////////////////////////////////////////////////////////////////// -// FPS stuff -//////////////////////////////////////////////////////////////////////// - -BOOL bIsPerformanceCounter=FALSE; -float fFrameRateHz=0; -DWORD dwFrameRateTicks=16; -float fFrameRate; -int iFrameLimit; -BOOL bUseFrameLimit=FALSE; -BOOL bUseFrameSkip=0; -DWORD dwLaceCnt=0; - -//////////////////////////////////////////////////////////////////////// -// FPS skipping / limit -//////////////////////////////////////////////////////////////////////// - -BOOL bInitCap = TRUE; -float fps_skip = 0; -float fps_cur = 0; - -#define TIMEBASE 100000 - -unsigned long timeGetTime() -{ - struct timeval tv; - gettimeofday(&tv, 0); // well, maybe there are better ways - return tv.tv_sec * 100000 + tv.tv_usec/10; // to do that in linux, but at least it works -} - -static void FrameCap(void) -{ - static unsigned long curticks, lastticks, _ticks_since_last_update; - static unsigned long TicksToWait = 0; - bool Waiting = TRUE; - - { - curticks = timeGetTime(); - _ticks_since_last_update = curticks - lastticks; - - if((_ticks_since_last_update > TicksToWait) || - (curticks <lastticks)) - { - lastticks = curticks; - - if((_ticks_since_last_update-TicksToWait) > dwFrameRateTicks) - TicksToWait=0; - else TicksToWait=dwFrameRateTicks-(_ticks_since_last_update-TicksToWait); - } - else - { - while (Waiting) - { - curticks = timeGetTime(); - _ticks_since_last_update = curticks - lastticks; - if ((_ticks_since_last_update > TicksToWait) || - (curticks < lastticks)) - { - Waiting = FALSE; - lastticks = curticks; - TicksToWait = dwFrameRateTicks; - } - } - } - } -} - -#define MAXSKIP 120 -#define MAXLACE 16 - -void FrameSkip(void) -{ - static int iNumSkips=0,iAdditionalSkip=0; // number of additional frames to skip - static DWORD dwLastLace=0; // helper var for frame limitation - static DWORD curticks, lastticks, _ticks_since_last_update; - - if(!dwLaceCnt) return; // important: if no updatelace happened, we ignore it completely - - if(iNumSkips) // we are in skipping mode? - { - dwLastLace+=dwLaceCnt; // -> calc frame limit helper (number of laces) - bSkipNextFrame = TRUE; // -> we skip next frame - iNumSkips--; // -> ok, one done - } - else // ok, no additional skipping has to be done... - { // we check now, if some limitation is needed, or a new skipping has to get started - DWORD dwWaitTime; - - if(bInitCap || bSkipNextFrame) // first time or we skipped before? - { - if(bUseFrameLimit && !bInitCap) // frame limit wanted and not first time called? - { - DWORD dwT=_ticks_since_last_update; // -> that's the time of the last drawn frame - dwLastLace+=dwLaceCnt; // -> and that's the number of updatelace since the start of the last drawn frame - - curticks = timeGetTime(); - _ticks_since_last_update= dwT+curticks - lastticks; - - dwWaitTime=dwLastLace*dwFrameRateTicks; // -> and now we calc the time the real psx would have needed - - if(_ticks_since_last_update<dwWaitTime) // -> we were too fast? - { - if((dwWaitTime-_ticks_since_last_update)> // -> some more security, to prevent - (60*dwFrameRateTicks)) // wrong waiting times - _ticks_since_last_update=dwWaitTime; - - while(_ticks_since_last_update<dwWaitTime) // -> loop until we have reached the real psx time - { // (that's the additional limitation, yup) - curticks = timeGetTime(); - _ticks_since_last_update = dwT+curticks - lastticks; - } - } - else // we were still too slow ?!!? - { - if(iAdditionalSkip<MAXSKIP) // -> well, somewhen we really have to stop skipping on very slow systems - { - iAdditionalSkip++; // -> inc our watchdog var - dwLaceCnt=0; // -> reset lace count - lastticks = timeGetTime(); - return; // -> done, we will skip next frame to get more speed - } - } - } - - bInitCap=FALSE; // -> ok, we have inited the frameskip func - iAdditionalSkip=0; // -> init additional skip - bSkipNextFrame=FALSE; // -> we don't skip the next frame - lastticks = timeGetTime(); - dwLaceCnt=0; // -> and we start to count the laces - dwLastLace=0; - _ticks_since_last_update=0; - return; // -> done, the next frame will get drawn - } - - bSkipNextFrame=FALSE; // init the frame skip signal to 'no skipping' first - - curticks = timeGetTime(); - _ticks_since_last_update = curticks - lastticks; - - dwLastLace=dwLaceCnt; // store curr count (frame limitation helper) - dwWaitTime=dwLaceCnt*dwFrameRateTicks; // calc the 'real psx lace time' - - if(_ticks_since_last_update>dwWaitTime) // hey, we needed way too long for that frame... - { - if(bUseFrameLimit) // if limitation, we skip just next frame, - { // and decide after, if we need to do more - iNumSkips=0; - } - else - { - iNumSkips=_ticks_since_last_update/dwWaitTime; // -> calc number of frames to skip to catch up - iNumSkips--; // -> since we already skip next frame, one down - if(iNumSkips>MAXSKIP) iNumSkips=MAXSKIP; // -> well, somewhere we have to draw a line - } - bSkipNextFrame = TRUE; // -> signal for skipping the next frame - } - else // we were faster than real psx? fine :) - if(bUseFrameLimit) // frame limit used? so we wait til the 'real psx time' has been reached - { - if(dwLaceCnt>MAXLACE) // -> security check - _ticks_since_last_update=dwWaitTime; - - while(_ticks_since_last_update<dwWaitTime) // just do a waiting loop... - { - curticks = timeGetTime(); - _ticks_since_last_update = curticks - lastticks; - } - } - - lastticks = timeGetTime(); - } - - dwLaceCnt=0; // init lace counter -} - -static void calcfps(void) -{ - static unsigned long curticks,_ticks_since_last_update,lastticks; - static long fps_cnt = 0; - static unsigned long fps_tck = 1; - static long fpsskip_cnt = 0; - static unsigned long fpsskip_tck = 1; - - { - curticks = timeGetTime(); - _ticks_since_last_update=curticks-lastticks; - - if(bUseFrameSkip && !bUseFrameLimit && _ticks_since_last_update) - fps_skip=min(fps_skip,((float)TIMEBASE/(float)_ticks_since_last_update+1.0f)); - - lastticks = curticks; - } - - if(bUseFrameSkip && bUseFrameLimit) - { - fpsskip_tck += _ticks_since_last_update; - - if(++fpsskip_cnt==2) - { - fps_skip = (float)2000/(float)fpsskip_tck; - - fps_skip +=6.0f; - - fpsskip_cnt = 0; - fpsskip_tck = 1; - } - } - - fps_tck += _ticks_since_last_update; - - if(++fps_cnt==10) - { - fps_cur = (float)(TIMEBASE*10)/(float)fps_tck; - - fps_cnt = 0; - fps_tck = 1; - - if(bUseFrameLimit && fps_cur>fFrameRateHz) // optical adjust ;) avoids flickering fps display - fps_cur=fFrameRateHz; - } -} - -void PCFrameCap (void) -{ - static unsigned long curticks, lastticks, _ticks_since_last_update; - static unsigned long TicksToWait = 0; - bool Waiting = TRUE; - - while (Waiting) - { - curticks = timeGetTime(); - _ticks_since_last_update = curticks - lastticks; - if ((_ticks_since_last_update > TicksToWait) || - (curticks < lastticks)) - { - Waiting = FALSE; - lastticks = curticks; - TicksToWait = (TIMEBASE / (unsigned long)fFrameRateHz); - } - } -} - -void PCcalcfps(void) -{ - static unsigned long curticks,_ticks_since_last_update,lastticks; - static long fps_cnt = 0; - static float fps_acc = 0; - float CurrentFPS=0; - - curticks = timeGetTime(); - _ticks_since_last_update=curticks-lastticks; - if(_ticks_since_last_update) - CurrentFPS=(float)TIMEBASE/(float)_ticks_since_last_update; - else CurrentFPS = 0; - lastticks = curticks; - - fps_acc += CurrentFPS; - - if(++fps_cnt==10) - { - fps_cur = fps_acc / 10; - fps_acc = 0; - fps_cnt = 0; - } - - fps_skip=CurrentFPS+1.0f; -} - -void SetAutoFrameCap(void) -{ - if(iFrameLimit==1) - { - fFrameRateHz = fFrameRate; - dwFrameRateTicks=(TIMEBASE / (unsigned long)fFrameRateHz); - return; - } - - if(dwActFixes&128) - { - if (PSXDisplay.Interlaced) - fFrameRateHz = PSXDisplay.PAL?50.0f:60.0f; - else fFrameRateHz = PSXDisplay.PAL?25.0f:30.0f; - } - else - { - //fFrameRateHz = PSXDisplay.PAL?50.0f:59.94f; - - if(PSXDisplay.PAL) - { - if (STATUSREG&GPUSTATUS_INTERLACED) - fFrameRateHz=33868800.0f/677343.75f; // 50.00238 - else fFrameRateHz=33868800.0f/680595.00f; // 49.76351 - } - else - { - if (STATUSREG&GPUSTATUS_INTERLACED) - fFrameRateHz=33868800.0f/565031.25f; // 59.94146 - else fFrameRateHz=33868800.0f/566107.50f; // 59.82750 - } - - dwFrameRateTicks=(TIMEBASE / (unsigned long)fFrameRateHz); - } -} - -void SetFrameRateConfig(void) -{ - if(!fFrameRate) fFrameRate=200.0f; - - if(fFrameRateHz==0) - { - if(iFrameLimit==2) fFrameRateHz=59.94f; // auto framerate? set some init val (no pal/ntsc known yet) - else fFrameRateHz=fFrameRate; // else set user framerate - } - - dwFrameRateTicks=(TIMEBASE / (unsigned long)fFrameRateHz); - - if(iFrameLimit==2) SetAutoFrameCap(); -} - -void InitFrameCap(void) -{ -} - -void ReInitFrameCap(void) -{ -} - -void CheckFrameRate(void) // called in updatelace (on every emulated psx vsync) -{ - if(bUseFrameSkip) - { - if(!(dwActFixes&0x100)) - { - dwLaceCnt++; // -> and store cnt of vsync between frames - if(dwLaceCnt>=MAXLACE && bUseFrameLimit) - { - if(dwLaceCnt==MAXLACE) bInitCap=TRUE; - FrameCap(); - } - } - else if(bUseFrameLimit) FrameCap(); - calcfps(); // -> calc fps display in skipping mode - } - else // -> non-skipping mode: - { - if(bUseFrameLimit) FrameCap(); - if(ulKeybits&KEY_SHOWFPS) calcfps(); - } -} - -#if 0 /* unused by pcsx */ -void CALLBACK GPUsetframelimit(unsigned long option) // new EPSXE interface func: main emu can enable/disable fps limitation this way -{ - bInitCap = TRUE; - - if(option==1) // emu says: limit - { - bUseFrameLimit=TRUE;bUseFrameSkip=FALSE;iFrameLimit=2; - SetAutoFrameCap(); - } - else // emu says: no limit - { - bUseFrameLimit=FALSE; - } -} -#endif +/***************************************************************************
+ fps.c - description
+ -------------------
+ begin : Sun Mar 08 2009
+ copyright : (C) 1999-2009 by Pete Bernert
+ web : www.pbernert.com
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. See also the license.txt file for *
+ * additional informations. *
+ * *
+ ***************************************************************************/
+
+//*************************************************************************//
+// History of changes:
+//
+// 2009/03/08 - Pete
+// - generic cleanup for the Peops release
+//
+//*************************************************************************//
+
+#include "stdafx.h"
+
+#define _IN_FPS
+
+#include "externals.h"
+
+////////////////////////////////////////////////////////////////////////
+// FPS stuff
+////////////////////////////////////////////////////////////////////////
+
+BOOL bIsPerformanceCounter=FALSE;
+float fFrameRateHz=0;
+DWORD dwFrameRateTicks=16;
+float fFrameRate;
+int iFrameLimit;
+BOOL bUseFrameLimit=FALSE;
+BOOL bUseFrameSkip=0;
+DWORD dwLaceCnt=0;
+
+////////////////////////////////////////////////////////////////////////
+// FPS skipping / limit
+////////////////////////////////////////////////////////////////////////
+
+BOOL bInitCap = TRUE;
+float fps_skip = 0;
+float fps_cur = 0;
+
+#define TIMEBASE 100000
+
+unsigned long timeGetTime()
+{
+ struct timeval tv;
+ gettimeofday(&tv, 0); // well, maybe there are better ways
+ return tv.tv_sec * 100000 + tv.tv_usec/10; // to do that in linux, but at least it works
+}
+
+void FrameCap(void)
+{
+ static unsigned long curticks, lastticks, _ticks_since_last_update;
+ static unsigned long TicksToWait = 0;
+ bool Waiting = TRUE;
+
+ {
+ curticks = timeGetTime();
+ _ticks_since_last_update = curticks - lastticks;
+
+ if((_ticks_since_last_update > TicksToWait) ||
+ (curticks <lastticks))
+ {
+ lastticks = curticks;
+
+ if((_ticks_since_last_update-TicksToWait) > dwFrameRateTicks)
+ TicksToWait=0;
+ else TicksToWait=dwFrameRateTicks-(_ticks_since_last_update-TicksToWait);
+ }
+ else
+ {
+ while (Waiting)
+ {
+ curticks = timeGetTime();
+ _ticks_since_last_update = curticks - lastticks;
+ if ((_ticks_since_last_update > TicksToWait) ||
+ (curticks < lastticks))
+ {
+ Waiting = FALSE;
+ lastticks = curticks;
+ TicksToWait = dwFrameRateTicks;
+ }
+ }
+ }
+ }
+}
+
+#define MAXSKIP 120
+#define MAXLACE 16
+
+void FrameSkip(void)
+{
+ static int iNumSkips=0,iAdditionalSkip=0; // number of additional frames to skip
+ static DWORD dwLastLace=0; // helper var for frame limitation
+ static DWORD curticks, lastticks, _ticks_since_last_update;
+
+ if(!dwLaceCnt) return; // important: if no updatelace happened, we ignore it completely
+
+ if(iNumSkips) // we are in skipping mode?
+ {
+ dwLastLace+=dwLaceCnt; // -> calc frame limit helper (number of laces)
+ bSkipNextFrame = TRUE; // -> we skip next frame
+ iNumSkips--; // -> ok, one done
+ }
+ else // ok, no additional skipping has to be done...
+ { // we check now, if some limitation is needed, or a new skipping has to get started
+ DWORD dwWaitTime;
+
+ if(bInitCap || bSkipNextFrame) // first time or we skipped before?
+ {
+ if(bUseFrameLimit && !bInitCap) // frame limit wanted and not first time called?
+ {
+ DWORD dwT=_ticks_since_last_update; // -> that's the time of the last drawn frame
+ dwLastLace+=dwLaceCnt; // -> and that's the number of updatelace since the start of the last drawn frame
+
+ curticks = timeGetTime();
+ _ticks_since_last_update= dwT+curticks - lastticks;
+
+ dwWaitTime=dwLastLace*dwFrameRateTicks; // -> and now we calc the time the real psx would have needed
+
+ if(_ticks_since_last_update<dwWaitTime) // -> we were too fast?
+ {
+ if((dwWaitTime-_ticks_since_last_update)> // -> some more security, to prevent
+ (60*dwFrameRateTicks)) // wrong waiting times
+ _ticks_since_last_update=dwWaitTime;
+
+ while(_ticks_since_last_update<dwWaitTime) // -> loop until we have reached the real psx time
+ { // (that's the additional limitation, yup)
+ curticks = timeGetTime();
+ _ticks_since_last_update = dwT+curticks - lastticks;
+ }
+ }
+ else // we were still too slow ?!!?
+ {
+ if(iAdditionalSkip<MAXSKIP) // -> well, somewhen we really have to stop skipping on very slow systems
+ {
+ iAdditionalSkip++; // -> inc our watchdog var
+ dwLaceCnt=0; // -> reset lace count
+ lastticks = timeGetTime();
+ return; // -> done, we will skip next frame to get more speed
+ }
+ }
+ }
+
+ bInitCap=FALSE; // -> ok, we have inited the frameskip func
+ iAdditionalSkip=0; // -> init additional skip
+ bSkipNextFrame=FALSE; // -> we don't skip the next frame
+ lastticks = timeGetTime();
+ dwLaceCnt=0; // -> and we start to count the laces
+ dwLastLace=0;
+ _ticks_since_last_update=0;
+ return; // -> done, the next frame will get drawn
+ }
+
+ bSkipNextFrame=FALSE; // init the frame skip signal to 'no skipping' first
+
+ curticks = timeGetTime();
+ _ticks_since_last_update = curticks - lastticks;
+
+ dwLastLace=dwLaceCnt; // store curr count (frame limitation helper)
+ dwWaitTime=dwLaceCnt*dwFrameRateTicks; // calc the 'real psx lace time'
+
+ if(_ticks_since_last_update>dwWaitTime) // hey, we needed way too long for that frame...
+ {
+ if(bUseFrameLimit) // if limitation, we skip just next frame,
+ { // and decide after, if we need to do more
+ iNumSkips=0;
+ }
+ else
+ {
+ iNumSkips=_ticks_since_last_update/dwWaitTime; // -> calc number of frames to skip to catch up
+ iNumSkips--; // -> since we already skip next frame, one down
+ if(iNumSkips>MAXSKIP) iNumSkips=MAXSKIP; // -> well, somewhere we have to draw a line
+ }
+ bSkipNextFrame = TRUE; // -> signal for skipping the next frame
+ }
+ else // we were faster than real psx? fine :)
+ if(bUseFrameLimit) // frame limit used? so we wait til the 'real psx time' has been reached
+ {
+ if(dwLaceCnt>MAXLACE) // -> security check
+ _ticks_since_last_update=dwWaitTime;
+
+ while(_ticks_since_last_update<dwWaitTime) // just do a waiting loop...
+ {
+ curticks = timeGetTime();
+ _ticks_since_last_update = curticks - lastticks;
+ }
+ }
+
+ lastticks = timeGetTime();
+ }
+
+ dwLaceCnt=0; // init lace counter
+}
+
+void calcfps(void)
+{
+ static unsigned long curticks,_ticks_since_last_update,lastticks;
+ static long fps_cnt = 0;
+ static unsigned long fps_tck = 1;
+ static long fpsskip_cnt = 0;
+ static unsigned long fpsskip_tck = 1;
+
+ {
+ curticks = timeGetTime();
+ _ticks_since_last_update=curticks-lastticks;
+
+ if(bUseFrameSkip && !bUseFrameLimit && _ticks_since_last_update)
+ fps_skip=min(fps_skip,((float)TIMEBASE/(float)_ticks_since_last_update+1.0f));
+
+ lastticks = curticks;
+ }
+
+ if(bUseFrameSkip && bUseFrameLimit)
+ {
+ fpsskip_tck += _ticks_since_last_update;
+
+ if(++fpsskip_cnt==2)
+ {
+ fps_skip = (float)2000/(float)fpsskip_tck;
+
+ fps_skip +=6.0f;
+
+ fpsskip_cnt = 0;
+ fpsskip_tck = 1;
+ }
+ }
+
+ fps_tck += _ticks_since_last_update;
+
+ if(++fps_cnt==10)
+ {
+ fps_cur = (float)(TIMEBASE*10)/(float)fps_tck;
+
+ fps_cnt = 0;
+ fps_tck = 1;
+
+ if(bUseFrameLimit && fps_cur>fFrameRateHz) // optical adjust ;) avoids flickering fps display
+ fps_cur=fFrameRateHz;
+ }
+}
+
+void PCFrameCap (void)
+{
+ static unsigned long curticks, lastticks, _ticks_since_last_update;
+ static unsigned long TicksToWait = 0;
+ bool Waiting = TRUE;
+
+ while (Waiting)
+ {
+ curticks = timeGetTime();
+ _ticks_since_last_update = curticks - lastticks;
+ if ((_ticks_since_last_update > TicksToWait) ||
+ (curticks < lastticks))
+ {
+ Waiting = FALSE;
+ lastticks = curticks;
+ TicksToWait = (TIMEBASE / (unsigned long)fFrameRateHz);
+ }
+ }
+}
+
+void PCcalcfps(void)
+{
+ static unsigned long curticks,_ticks_since_last_update,lastticks;
+ static long fps_cnt = 0;
+ static float fps_acc = 0;
+ float CurrentFPS=0;
+
+ curticks = timeGetTime();
+ _ticks_since_last_update=curticks-lastticks;
+ if(_ticks_since_last_update)
+ CurrentFPS=(float)TIMEBASE/(float)_ticks_since_last_update;
+ else CurrentFPS = 0;
+ lastticks = curticks;
+
+ fps_acc += CurrentFPS;
+
+ if(++fps_cnt==10)
+ {
+ fps_cur = fps_acc / 10;
+ fps_acc = 0;
+ fps_cnt = 0;
+ }
+
+ fps_skip=CurrentFPS+1.0f;
+}
+
+void SetAutoFrameCap(void)
+{
+ if(iFrameLimit==1)
+ {
+ fFrameRateHz = fFrameRate;
+ dwFrameRateTicks=(TIMEBASE / (unsigned long)fFrameRateHz);
+ return;
+ }
+
+ if(dwActFixes&128)
+ {
+ if (PSXDisplay.Interlaced)
+ fFrameRateHz = PSXDisplay.PAL?50.0f:60.0f;
+ else fFrameRateHz = PSXDisplay.PAL?25.0f:30.0f;
+ }
+ else
+ {
+ //fFrameRateHz = PSXDisplay.PAL?50.0f:59.94f;
+
+ if(PSXDisplay.PAL)
+ {
+ if (STATUSREG&GPUSTATUS_INTERLACED)
+ fFrameRateHz=33868800.0f/677343.75f; // 50.00238
+ else fFrameRateHz=33868800.0f/680595.00f; // 49.76351
+ }
+ else
+ {
+ if (STATUSREG&GPUSTATUS_INTERLACED)
+ fFrameRateHz=33868800.0f/565031.25f; // 59.94146
+ else fFrameRateHz=33868800.0f/566107.50f; // 59.82750
+ }
+
+ dwFrameRateTicks=(TIMEBASE / (unsigned long)fFrameRateHz);
+ }
+}
+
+void SetFrameRateConfig(void)
+{
+ if(!fFrameRate) fFrameRate=200.0f;
+
+ if(fFrameRateHz==0)
+ {
+ if(iFrameLimit==2) fFrameRateHz=59.94f; // auto framerate? set some init val (no pal/ntsc known yet)
+ else fFrameRateHz=fFrameRate; // else set user framerate
+ }
+
+ dwFrameRateTicks=(TIMEBASE / (unsigned long)fFrameRateHz);
+
+ if(iFrameLimit==2) SetAutoFrameCap();
+}
+
+void InitFrameCap(void)
+{
+}
+
+void ReInitFrameCap(void)
+{
+}
+
+void CheckFrameRate(void) // called in updatelace (on every emulated psx vsync)
+{
+ if(bUseFrameSkip)
+ {
+ if(!(dwActFixes&0x100))
+ {
+ dwLaceCnt++; // -> and store cnt of vsync between frames
+ if(dwLaceCnt>=MAXLACE && bUseFrameLimit)
+ {
+ if(dwLaceCnt==MAXLACE) bInitCap=TRUE;
+ FrameCap();
+ }
+ }
+ else if(bUseFrameLimit) FrameCap();
+ calcfps(); // -> calc fps display in skipping mode
+ }
+ else // -> non-skipping mode:
+ {
+ if(bUseFrameLimit) FrameCap();
+ if(ulKeybits&KEY_SHOWFPS) calcfps();
+ }
+}
+
+void CALLBACK GPUsetframelimit(unsigned long option) // new EPSXE interface func: main emu can enable/disable fps limitation this way
+{
+ bInitCap = TRUE;
+
+ if(option==1) // emu says: limit
+ {
+ bUseFrameLimit=TRUE;bUseFrameSkip=FALSE;iFrameLimit=2;
+ SetAutoFrameCap();
+ }
+ else // emu says: no limit
+ {
+ bUseFrameLimit=FALSE;
+ }
+}
diff --git a/plugins/peopsxgl/gpu.c b/plugins/peopsxgl/gpu.c index 092d32a5..f379372b 100644 --- a/plugins/peopsxgl/gpu.c +++ b/plugins/peopsxgl/gpu.c @@ -1,3527 +1,3529 @@ -/*************************************************************************** - gpu.c - description - ------------------- - begin : Sun Mar 08 2009 - copyright : (C) 1999-2009 by Pete Bernert - email : BlackDove@addcom.de - ***************************************************************************/ - -/*************************************************************************** - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. See also the license.txt file for * - * additional informations. * - * * - ***************************************************************************/ - -// !!! enable this, if Linux XF86VidMode is not supported: -//#define NOVMODE - -#include "stdafx.h" - -#if !defined(_MACGL) && !defined(_WINDOWS) - -#include "config.h" - -#ifndef NOVMODE -#include <X11/extensions/xf86vmode.h> -static XF86VidModeModeInfo **modes=0; -static int iOldMode=0; -#endif - -#endif - -#define _IN_GPU - -#include "externals.h" -#include "psemu_plugin_defs.h" -#include "gpu.h" -#include "draw.h" -#include "cfg.h" -#include "prim.h" -#include "psemu_plugin_defs.h" -#include "texture.h" -#include "menu.h" -#include "fps.h" -#include "key.h" -#ifdef _WINDOWS -#include "resource.h" -#include "ssave.h" -#endif - -//////////////////////////////////////////////////////////////////////// -// PPDK developer must change libraryName field and can change revision and build -//////////////////////////////////////////////////////////////////////// - -const unsigned char version = 1; // do not touch - library for PSEmu 1.x -const unsigned char revision = 1; -const unsigned char build = 78; - -static char *libraryName = N_("OpenGL Driver"); - -static char *PluginAuthor = N_("Pete Bernert"); -#if 0 -static char *libraryInfo = N_("Based on P.E.Op.S. MesaGL Driver V1.78\nCoded by Pete Bernert\n"); -#endif - -//////////////////////////////////////////////////////////////////////// -// memory image of the PSX vram -//////////////////////////////////////////////////////////////////////// - -unsigned char *psxVSecure; -unsigned char *psxVub; -signed char *psxVsb; -unsigned short *psxVuw; -unsigned short *psxVuw_eom; -signed short *psxVsw; -uint32_t *psxVul; -signed int *psxVsl; - -// macro for easy access to packet information -#define GPUCOMMAND(x) ((x>>24) & 0xff) - -GLfloat gl_z=0.0f; -BOOL bNeedInterlaceUpdate=FALSE; -BOOL bNeedRGB24Update=FALSE; -BOOL bChangeWinMode=FALSE; - -uint32_t ulStatusControl[256]; - -//////////////////////////////////////////////////////////////////////// -// global GPU vars -//////////////////////////////////////////////////////////////////////// - -static int GPUdataRet; -int lGPUstatusRet; -char szDispBuf[64]; - -uint32_t dwGPUVersion = 0; -int iGPUHeight = 512; -int iGPUHeightMask = 511; -int GlobalTextIL = 0; -int iTileCheat = 0; - -static uint32_t gpuDataM[256]; -static unsigned char gpuCommand = 0; -static int gpuDataC = 0; -static int gpuDataP = 0; - -VRAMLoad_t VRAMWrite; -VRAMLoad_t VRAMRead; -int iDataWriteMode; -int iDataReadMode; - -int lClearOnSwap; -int lClearOnSwapColor; -BOOL bSkipNextFrame = FALSE; -int iColDepth; -BOOL bChangeRes; -BOOL bWindowMode; -int iWinSize; - -// possible psx display widths -short dispWidths[8] = {256,320,512,640,368,384,512,640}; - -PSXDisplay_t PSXDisplay; -PSXDisplay_t PreviousPSXDisplay; -TWin_t TWin; -short imageX0,imageX1; -short imageY0,imageY1; -BOOL bDisplayNotSet = TRUE; -GLuint uiScanLine=0; -int iUseScanLines=0; -float iScanlineColor[] = {0,0,0, 0.3}; // easy on the eyes. -int lSelectedSlot=0; -unsigned char * pGfxCardScreen=0; -int iBlurBuffer=0; -int iScanBlend=0; -int iRenderFVR=0; -int iNoScreenSaver=0; -uint32_t ulGPUInfoVals[16]; -int iFakePrimBusy = 0; -int iRumbleVal = 0; -int iRumbleTime = 0; -uint32_t vBlank=0; - -//////////////////////////////////////////////////////////////////////// -// stuff to make this a true PDK module -//////////////////////////////////////////////////////////////////////// - -char * CALLBACK PSEgetLibName(void) -{ - return _(libraryName); -} - -unsigned long CALLBACK PSEgetLibType(void) -{ - return PSE_LT_GPU; -} - -unsigned long CALLBACK PSEgetLibVersion(void) -{ - return version<<16|revision<<8|build; -} - -#if 0 -char * GPUgetLibInfos(void) -{ - return _(libraryInfo); -} -#endif - -//////////////////////////////////////////////////////////////////////// -// snapshot funcs (saves screen to bitmap / text infos into file) -//////////////////////////////////////////////////////////////////////// - -#ifdef _WINDOWS -static char * GetConfigInfos(HWND hW) -#else -static char * GetConfigInfos(int hW) -#endif -{ -#ifdef _WINDOWS - HDC hdc;HGLRC hglrc; -#endif - char szO[2][4]={"off","on "}; - char szTxt[256]; - char * pB=(char *)malloc(32767); - - if(!pB) return NULL; - *pB=0; - //----------------------------------------------------// - sprintf(szTxt,"Plugin: %s %d.%d.%d (mod)\r\n",libraryName,version,revision,build); - strcat(pB,szTxt); - sprintf(szTxt,"Author: %s\r\n",PluginAuthor); - strcat(pB,szTxt); - -#ifdef _WINDOWS - if(hW) - { - hdc = GetDC(hW); - bSetupPixelFormat(hdc); - hglrc = wglCreateContext(hdc); - wglMakeCurrent(hdc, hglrc); - } -#endif - - sprintf(szTxt,"Card vendor: %s\r\n",(char *)glGetString(GL_VENDOR)); - strcat(pB,szTxt); - sprintf(szTxt,"GFX card: %s\r\n",(char *)glGetString(GL_RENDERER)); - strcat(pB,szTxt); - sprintf(szTxt,"OGL version: %s\r\n\r\n",(char *)glGetString(GL_VERSION)); - strcat(pB,szTxt); - //strcat(pB,(char *)glGetString(GL_EXTENSIONS)); - //strcat(pB,"\r\n\r\n"); - -#ifdef _WINDOWS - if(hW) - { - wglMakeCurrent(NULL, NULL); - wglDeleteContext(hglrc); - ReleaseDC(hW,hdc); - } - //----------------------------------------------------// -#endif - - if(hW && bWindowMode) - sprintf(szTxt,"Resolution/Color:\r\n- %dx%d ",LOWORD(iWinSize),HIWORD(iWinSize)); - else - sprintf(szTxt,"Resolution/Color:\r\n- %dx%d ",iResX,iResY); - strcat(pB,szTxt); - if(bWindowMode) sprintf(szTxt,"Window mode\r\n"); - else - { - sprintf(szTxt,"Fullscreen "); - strcat(pB,szTxt); - if(bChangeRes) sprintf(szTxt,"- Desktop changing [%d Bit]\r\n",iColDepth); - else sprintf(szTxt,"- NO desktop changing\r\n"); - } - strcat(pB,szTxt); - - if(iForceVSync>=0) sprintf(szTxt,"- V-Sync: %s\r\n",szO[iForceVSync]); - else strcpy(szTxt,"- V-Sync: Driver\r\n"); - strcat(pB,szTxt); - sprintf(szTxt,"- Keep psx aspect ratio: %s\r\n\r\n",szO[bKeepRatio]); - strcat(pB,szTxt); - //----------------------------------------------------// - strcpy(szTxt,"Textures:\r\n- "); - if(iTexQuality==0) strcat(szTxt,"Default"); - else if(iTexQuality==1) strcat(szTxt,"R4G4B4A4"); - else if(iTexQuality==2) strcat(szTxt,"R5G5B5A1"); - else if(iTexQuality==3) strcat(szTxt,"R8G8A8A8"); - else if(iTexQuality==4) strcat(szTxt,"B8G8R8A8"); - if(!hW && bGLExt) strcat(szTxt," (packed pixels)\r\n"); - else strcat(szTxt,"\r\n"); - strcat(pB,szTxt); - if(!hW) - { - sprintf(szTxt,"- Filtering: %d - edge clamping ",iFilterType); - if(iClampType==GL_TO_EDGE_CLAMP) strcat(szTxt,"supported\r\n"); - else strcat(szTxt,"NOT supported\r\n"); - } - else sprintf(szTxt,"- iFiltering: %d\r\n",iFilterType); - strcat(pB,szTxt); - sprintf(szTxt,"- Hi-Res textures: %d\r\n",iHiResTextures); - strcat(pB,szTxt); - if(!hW) - { - sprintf(szTxt,"- Palettized tex windows: %s\r\n",szO[iUsePalTextures]); - strcat(pB,szTxt); - } - sprintf(szTxt,"- VRam size: %d MBytes",iVRamSize); - if(!hW) - sprintf(szTxt+strlen(szTxt)," - %d textures usable\r\n\r\n",iSortTexCnt); - else strcat(szTxt,"\r\n\r\n"); - strcat(pB,szTxt); - //----------------------------------------------------// - sprintf(szTxt,"Framerate:\r\n- FPS limitation: %s\r\n",szO[bUseFrameLimit]); - strcat(pB,szTxt); - sprintf(szTxt,"- Frame skipping: %s\r\n",szO[bUseFrameSkip]); - strcat(pB,szTxt); - if(iFrameLimit==2) - strcpy(szTxt,"- FPS limit: Auto\r\n\r\n"); - else sprintf(szTxt,"- FPS limit: %.1f\r\n\r\n",fFrameRate); - strcat(pB,szTxt); - //----------------------------------------------------// - sprintf(szTxt,"Compatibility:\r\n- Offscreen drawing: %d\r\n",iOffscreenDrawing); - strcat(pB,szTxt); - sprintf(szTxt,"- Framebuffer texture: %d",iFrameTexType); - if(!hW && iFrameTexType==2) - { - if(gTexFrameName) strcat(szTxt," - texture created\r\n"); - else strcat(szTxt," - not used yet\r\n"); - } - else strcat(szTxt,"\r\n"); - strcat(pB,szTxt); - sprintf(szTxt,"- Framebuffer access: %d\r\n",iFrameReadType); - strcat(pB,szTxt); - sprintf(szTxt,"- Alpha multipass: %s\r\n",szO[bOpaquePass]); - strcat(pB,szTxt); - sprintf(szTxt,"- Mask bit: %s\r\n",szO[iUseMask]); - strcat(pB,szTxt); - sprintf(szTxt,"- Advanced blending: %s",szO[bAdvancedBlend]); - if(!hW && bAdvancedBlend) - { - if(bGLBlend) strcat(szTxt," (hardware)\r\n"); - else strcat(szTxt," (software)\r\n"); - } - else strcat(szTxt,"\r\n"); - strcat(pB,szTxt); - - if(!hW) - { - strcpy(szTxt,"- Subtractive blending: "); - if(glBlendEquationEXTEx) - { - if(bUseMultiPass) strcat(szTxt,"supported, but not used!"); - else strcat(szTxt,"activated"); - } - else strcat(szTxt," NOT supported!"); - strcat(szTxt,"\r\n\r\n"); - } - else strcpy(szTxt,"\r\n"); - - strcat(pB,szTxt); - //----------------------------------------------------// - sprintf(szTxt,"Misc:\r\n- Scanlines: %s",szO[iUseScanLines]); - strcat(pB,szTxt); - if(iUseScanLines) sprintf(szTxt," [%d]\r\n",iScanBlend); - else strcpy(szTxt,"\r\n"); - strcat(pB,szTxt); - sprintf(szTxt,"- Line mode: %s\r\n",szO[bUseLines]); - strcat(pB,szTxt); -// sprintf(szTxt,"- Line AA: %s\r\n",szO[bUseAntiAlias]); -// fwrite(szTxt,lstrlen(szTxt),1,txtfile); - sprintf(szTxt,"- Unfiltered FB: %s\r\n",szO[bUseFastMdec]); - strcat(pB,szTxt); - sprintf(szTxt,"- 15 bit FB: %s\r\n",szO[bUse15bitMdec]); - strcat(pB,szTxt); - sprintf(szTxt,"- Dithering: %s\r\n",szO[bDrawDither]); - strcat(pB,szTxt); - sprintf(szTxt,"- Screen smoothing: %s",szO[iBlurBuffer]); - strcat(pB,szTxt); - if(!hW && iBlurBuffer) - { - if(gTexBlurName) strcat(pB," - supported\r\n"); - else strcat(pB," - not supported\r\n"); - } - else strcat(pB,"\r\n"); - sprintf(szTxt,"- Game fixes: %s [%08x]\r\n",szO[bUseFixes],dwCfgFixes); - strcat(pB,szTxt); - //----------------------------------------------------// - return pB; -} - -//////////////////////////////////////////////////////////////////////// -// save text infos to file -//////////////////////////////////////////////////////////////////////// - -static void DoTextSnapShot(int iNum) -{ - FILE *txtfile;char szTxt[256];char * pB; - -#ifdef _WINDOWS - sprintf(szTxt,"snap\\pcsx%04d.txt",iNum); -#else - sprintf(szTxt,"%s/pcsx%04d.txt",getenv("HOME"),iNum); -#endif - - if((txtfile=fopen(szTxt,"wb"))==NULL) - return; - - pB=GetConfigInfos(0); - if(pB) - { - if(fwrite(pB,strlen(pB),1,txtfile) != 1) { - free(pB); - fclose(txtfile); - remove(szTxt); - return; - } - free(pB); - } - fclose(txtfile); -} - -//////////////////////////////////////////////////////////////////////// -// saves screen bitmap to file -//////////////////////////////////////////////////////////////////////// - -void DoSnapShot(void) -{ - unsigned char * snapshotdumpmem=NULL,* p,c; - FILE *bmpfile;char filename[256]; - unsigned char header[0x36];int size; - unsigned char empty[2]={0,0};int i; - unsigned int snapshotnr = 0; - short SnapWidth; - short SnapHeigth; - - bSnapShot=FALSE; - - SnapWidth = iResX; - SnapHeigth = iResY; - - size=SnapWidth * SnapHeigth * 3 + 0x38; - - if((snapshotdumpmem=(unsigned char *) - malloc(SnapWidth*SnapHeigth*3))==NULL) - return; - - // fill in proper values for BMP - for(i=0;i<0x36;i++) header[i]=0; - header[0]='B'; - header[1]='M'; - header[2]=(unsigned char)(size&0xff); - header[3]=(unsigned char)((size>>8)&0xff); - header[4]=(unsigned char)((size>>16)&0xff); - header[5]=(unsigned char)((size>>24)&0xff); - header[0x0a]=0x36; - header[0x0e]=0x28; - header[0x12]=(unsigned char)(SnapWidth%256); - header[0x13]=(unsigned char)(SnapWidth/256); - header[0x16]=(unsigned char)(SnapHeigth%256); - header[0x17]=(unsigned char)(SnapHeigth/256); - header[0x1a]=0x01; - header[0x1c]=0x18; - header[0x26]=0x12; - header[0x27]=0x0B; - header[0x2A]=0x12; - header[0x2B]=0x0B; - - // increment snapshot value - // get filename - do - { - snapshotnr++; -#ifdef _WINDOWS - sprintf(filename,"snap/pcsx%04d.bmp",snapshotnr); -#else - sprintf(filename,"%s/pcsx%04d.bmp",getenv("HOME"),snapshotnr); -#endif - bmpfile=fopen(filename,"rb"); - if(bmpfile==NULL)break; - fclose(bmpfile); - if(snapshotnr==9999) break; - } - while(TRUE); - - // try opening new snapshot file - if((bmpfile=fopen(filename,"wb"))==NULL) - {free(snapshotdumpmem);return;} - - if(fwrite(header,0x36,1,bmpfile) != 1) { - free(snapshotdumpmem); - fclose(bmpfile); - remove(filename); - return; - } - - glReadPixels(0,0,SnapWidth,SnapHeigth,GL_RGB, - GL_UNSIGNED_BYTE,snapshotdumpmem); - p=snapshotdumpmem; - size=SnapWidth * SnapHeigth; - - for(i=0;i<size;i++,p+=3) - {c=*p;*p=*(p+2);*(p+2)=c;} - - if(fwrite(snapshotdumpmem,size*3,1,bmpfile) != 1 || - fwrite(empty,0x2,1,bmpfile) != 1) { - free(snapshotdumpmem); - fclose(bmpfile); - remove(filename); - return; - } - fclose(bmpfile); - free(snapshotdumpmem); - - DoTextSnapShot(snapshotnr); -#ifdef _WINDOWS - MessageBeep((UINT)-1); -#endif -} - -void CALLBACK GPUmakeSnapshot(void) -{ - bSnapShot = TRUE; -} - -//////////////////////////////////////////////////////////////////////// -// GPU INIT... here starts it all (first func called by emu) -//////////////////////////////////////////////////////////////////////// - -long CALLBACK GPUinit() -{ - memset(ulStatusControl,0,256*sizeof(uint32_t)); - - // different ways of accessing PSX VRAM - - psxVSecure=(unsigned char *)malloc((iGPUHeight*2)*1024 + (1024*1024)); // always alloc one extra MB for soft drawing funcs security - if(!psxVSecure) return -1; - - psxVub=psxVSecure+512*1024; // security offset into double sized psx vram! - psxVsb=(signed char *)psxVub; - psxVsw=(signed short *)psxVub; - psxVsl=(signed int *)psxVub; - psxVuw=(unsigned short *)psxVub; - psxVul=(uint32_t *)psxVub; - - psxVuw_eom=psxVuw+1024*iGPUHeight; // pre-calc of end of vram - - memset(psxVSecure,0x00,(iGPUHeight*2)*1024 + (1024*1024)); - memset(ulGPUInfoVals,0x00,16*sizeof(uint32_t)); - - InitFrameCap(); // init frame rate stuff - - PSXDisplay.RGB24 = 0; // init vars - PreviousPSXDisplay.RGB24= 0; - PSXDisplay.Interlaced = 0; - PSXDisplay.InterlacedTest=0; - PSXDisplay.DrawOffset.x = 0; - PSXDisplay.DrawOffset.y = 0; - PSXDisplay.DrawArea.x0 = 0; - PSXDisplay.DrawArea.y0 = 0; - PSXDisplay.DrawArea.x1 = 320; - PSXDisplay.DrawArea.y1 = 240; - PSXDisplay.DisplayMode.x= 320; - PSXDisplay.DisplayMode.y= 240; - PSXDisplay.Disabled = FALSE; - PreviousPSXDisplay.Range.x0 =0; - PreviousPSXDisplay.Range.x1 =0; - PreviousPSXDisplay.Range.y0 =0; - PreviousPSXDisplay.Range.y1 =0; - PSXDisplay.Range.x0=0; - PSXDisplay.Range.x1=0; - PSXDisplay.Range.y0=0; - PSXDisplay.Range.y1=0; - PreviousPSXDisplay.DisplayPosition.x = 1; - PreviousPSXDisplay.DisplayPosition.y = 1; - PSXDisplay.DisplayPosition.x = 1; - PSXDisplay.DisplayPosition.y = 1; - PreviousPSXDisplay.DisplayModeNew.y=0; - PSXDisplay.Double=1; - GPUdataRet=0x400; - - PSXDisplay.DisplayModeNew.x=0; - PSXDisplay.DisplayModeNew.y=0; - - //PreviousPSXDisplay.Height = PSXDisplay.Height = 239; - - iDataWriteMode = DR_NORMAL; - - // Reset transfer values, to prevent mis-transfer of data - memset(&VRAMWrite,0,sizeof(VRAMLoad_t)); - memset(&VRAMRead,0,sizeof(VRAMLoad_t)); - - // device initialised already ! - //lGPUstatusRet = 0x74000000; - vBlank = 0; - - STATUSREG = 0x14802000; - GPUIsIdle; - GPUIsReadyForCommands; - - return 0; -} - -//////////////////////////////////////////////////////////////////////// -// GPU OPEN: funcs to open up the gpu display (Windows) -//////////////////////////////////////////////////////////////////////// - -#ifdef _WINDOWS - -void ChangeDesktop() // change destop resolution -{ - DEVMODE dv;long lRes,iTry=0; - - while(iTry<10) // keep on hammering... - { - memset(&dv,0,sizeof(DEVMODE)); - dv.dmSize=sizeof(DEVMODE); - dv.dmBitsPerPel=iColDepth; - dv.dmPelsWidth=iResX; - dv.dmPelsHeight=iResY; - - dv.dmFields=DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT; - - lRes=ChangeDisplaySettings(&dv,0); // ...hammering the anvil - - if(lRes==DISP_CHANGE_SUCCESSFUL) return; - iTry++;Sleep(10); - } -} - -//////////////////////////////////////////////////////////////////////// -// OPEN interface func: attention! -// some emus are calling this func in their main Window thread, -// but all other interface funcs (to draw stuff) in a different thread! -// that's a problem, since OGL is thread safe! Therefore we cannot -// initialize the OGL stuff right here, we simply set a "bIsFirstFrame = TRUE" -// flag, to initialize OGL on the first real draw call. -// btw, we also call this open func ourselfes, each time when the user -// is changing between fullscreen/window mode (ENTER key) -// btw part 2: in windows the plugin gets the window handle from the -// main emu, and doesn't create it's own window (if it would do it, -// some PAD or SPU plugins would not work anymore) -//////////////////////////////////////////////////////////////////////// - -HMENU hPSEMenu=NULL; - -long CALLBACK GPUopen(HWND hwndGPU) -{ - HDC hdc;RECT r;DEVMODE dv; - - hWWindow = hwndGPU; // store hwnd globally - - InitKeyHandler(); // init key handler (subclass window) - - if(bChangeWinMode) // user wants to change fullscreen/window mode? - { - ReadWinSizeConfig(); // -> get sizes again - } - else // first real startup - { - ReadConfig(); // -> read config from registry - - SetFrameRateConfig(); // -> setup frame rate stuff - } - - if(iNoScreenSaver) EnableScreenSaver(FALSE); // at least we can try - - - memset(&dv,0,sizeof(DEVMODE)); - dv.dmSize=sizeof(DEVMODE); - EnumDisplaySettings(NULL,ENUM_CURRENT_SETTINGS,&dv); - - bIsFirstFrame = TRUE; // flag: we have to init OGL later in windows! - - if(bWindowMode) // win mode? - { - DWORD dw=GetWindowLong(hWWindow, GWL_STYLE); // -> adjust wnd style (owndc needed by some stupid ogl drivers) - dw&=~WS_THICKFRAME; - dw|=WS_BORDER|WS_CAPTION|CS_OWNDC; - SetWindowLong(hWWindow, GWL_STYLE, dw); - - hPSEMenu=GetMenu(hWWindow); // -> hide emu menu (if any) - if(hPSEMenu!=NULL) SetMenu(hWWindow,NULL); - - iResX=LOWORD(iWinSize);iResY=HIWORD(iWinSize); - ShowWindow(hWWindow,SW_SHOWNORMAL); - - MoveWindow(hWWindow, // -> center wnd - GetSystemMetrics(SM_CXFULLSCREEN)/2-iResX/2, - GetSystemMetrics(SM_CYFULLSCREEN)/2-iResY/2, - iResX+GetSystemMetrics(SM_CXFIXEDFRAME)+3, - iResY+GetSystemMetrics(SM_CYFIXEDFRAME)+GetSystemMetrics(SM_CYCAPTION)+3, - TRUE); - UpdateWindow(hWWindow); // -> let windows do some update - - if(dv.dmBitsPerPel==16 || dv.dmBitsPerPel==32) // -> overwrite user color info with desktop color info - iColDepth=dv.dmBitsPerPel; - } - else // fullscreen mode: - { - if(dv.dmBitsPerPel!=(unsigned int)iColDepth || // -> check, if we have to change resolution - dv.dmPelsWidth !=(unsigned int)iResX || - dv.dmPelsHeight!=(unsigned int)iResY) - bChangeRes=TRUE; else bChangeRes=FALSE; - - if(bChangeRes) ChangeDesktop(); // -> change the res (had to do an own func because of some MS 'optimizations') - - SetWindowLong(hWWindow, GWL_STYLE, CS_OWNDC); // -> adjust wnd style as well (to be sure) - - hPSEMenu=GetMenu(hWWindow); // -> hide menu - if(hPSEMenu!=NULL) SetMenu(hWWindow,NULL); - ShowWindow(hWWindow,SW_SHOWMAXIMIZED); // -> max mode - } - - rRatioRect.left = rRatioRect.top=0; - rRatioRect.right = iResX; - rRatioRect.bottom = iResY; - - r.left=r.top=0;r.right=iResX;r.bottom=iResY; // hack for getting a clean black window until OGL gets initialized - hdc = GetDC(hWWindow); - FillRect(hdc,&r,(HBRUSH)GetStockObject(BLACK_BRUSH)); - bSetupPixelFormat(hdc); - ReleaseDC(hWWindow,hdc); - - bDisplayNotSet = TRUE; - bSetClip=TRUE; - - SetFixes(); // setup game fixes - - InitializeTextureStore(); // init texture mem - -// lGPUstatusRet = 0x74000000; - -// with some emus, we could do the OGL init right here... oh my -// if(bIsFirstFrame) GLinitialize(); - - return 0; -} - -#elif !defined (_MACGL) - -//////////////////////////////////////////////////////////////////////// -// LINUX GPU OPEN: func to open up the gpu display (X stuff) -// please note: in linux we are creating our own display, and we return -// the display ID to the main emu... that's cleaner -//////////////////////////////////////////////////////////////////////// - -char * pCaptionText=0; -int bFullScreen=0; -Display *display; - -static Cursor cursor; -static XVisualInfo *myvisual; -static Colormap colormap; -static Window window; - -static int bModeChanged=0; - -typedef struct -{ -#define MWM_HINTS_DECORATIONS 2 - long flags; - long functions; - long decorations; - long input_mode; -} MotifWmHints; - -static int dbdepat[]={GLX_RGBA,GLX_DOUBLEBUFFER,GLX_DEPTH_SIZE,16,None}; -static int dbnodepat[]={GLX_RGBA,GLX_DOUBLEBUFFER,None}; -static GLXContext cx; - -static int fx=0; - -//////////////////////////////////////////////////////////////////////// - -static void osd_close_display (void) // close display -{ - if(display) // display exists? - { - glXDestroyContext(display,cx); // -> kill context - XFreeColormap(display, colormap); // -> kill colormap - XSync(display,False); // -> sync events - -#ifndef NOVMODE - if(bModeChanged) // -> repair screen mode - { - int myscreen=DefaultScreen(display); - XF86VidModeSwitchToMode(display,myscreen, // --> switch mode back - modes[iOldMode]); - XF86VidModeSetViewPort(display,myscreen,0,0); // --> set viewport upperleft - free(modes); // --> finally kill mode infos - bModeChanged=0; // --> done - } -#endif - - XCloseDisplay(display); // -> close display - } -} - -//////////////////////////////////////////////////////////////////////// - -static void sysdep_create_display(void) // create display -{ - XSetWindowAttributes winattr;float fxgamma=2; - int myscreen;char gammastr[14]; - Screen * screen;XEvent event; - XSizeHints hints;XWMHints wm_hints; - MotifWmHints mwmhints;Atom mwmatom;Atom delwindow; - char *glxfx; - - glxfx=getenv("MESA_GLX_FX"); // 3dfx mesa fullscreen flag - if(glxfx) - { - if(glxfx[0]=='f') // -> yup, fullscreen needed - { - fx=1; // -> raise flag - putenv("FX_GLIDE_NO_SPLASH="); - sprintf(gammastr,"SST_GAMMA=%2.1f",fxgamma); // -> set gamma - putenv(gammastr); - } - } - - display=XOpenDisplay(NULL); // open display - if(!display) // no display? - { - fprintf (stderr,"Failed to open display!!!\n"); - osd_close_display(); - return; // -> bye - } - - myscreen=DefaultScreen(display); // get screen id - -#ifdef NOVMODE - if(bFullScreen) {fx=1;bModeChanged=0;} -#else - if(bFullScreen) - { - XF86VidModeModeLine mode; - int nmodes,iC; - fx=1; // raise flag - XF86VidModeGetModeLine(display,myscreen,&iC,&mode); // get actual mode info - if(mode.privsize) XFree(mode.private); // no need for private stuff - bModeChanged=0; // init mode change flag - if(iResX!=mode.hdisplay || iResY!=mode.vdisplay) // wanted mode is different? - { - XF86VidModeGetAllModeLines(display,myscreen, // -> enum all mode infos - &nmodes,&modes); - if(modes) // -> infos got? - { - for(iC=0;iC<nmodes;++iC) // -> loop modes - { - if(mode.hdisplay==modes[iC]->hdisplay && // -> act mode found? - mode.vdisplay==modes[iC]->vdisplay) // if yes: store mode id - iOldMode=iC; - - if(iResX==modes[iC]->hdisplay && // -> wanted mode found? - iResY==modes[iC]->vdisplay) - { - XF86VidModeSwitchToMode(display,myscreen, // --> switch to mode - modes[iC]); - XF86VidModeSetViewPort(display,myscreen,0,0); - bModeChanged=1; // --> raise flag for repairing mode on close - } - } - - if(bModeChanged==0) // -> no mode found? - { - free(modes); // --> free infos - printf("No proper fullscreen mode found!\n"); // --> some info output - } - } - } - } -#endif - - screen=DefaultScreenOfDisplay(display); - - if(iZBufferDepth) // visual (with or without zbuffer) - myvisual=glXChooseVisual(display,myscreen,dbdepat); - else myvisual=glXChooseVisual(display,myscreen,dbnodepat); - - if(!myvisual) // no visual? - { - fprintf(stderr,"Failed to obtain visual!!!\n"); // -> bye - osd_close_display(); - return; - } - - cx=glXCreateContext(display,myvisual,0,GL_TRUE); // create rendering context - - if(!cx) // no context? - { - fprintf(stderr,"Failed to create OpenGL context!!!\n"); - osd_close_display(); // -> bxe - return; - } - - // pffff... much work for a simple blank cursor... oh, well... - if(!bFullScreen) cursor=XCreateFontCursor(display,XC_trek); - else - { - Pixmap p1,p2;XImage * img; - XColor b,w;unsigned char * idata; - XGCValues GCv; - GC GCc; - - memset(&b,0,sizeof(XColor)); - memset(&w,0,sizeof(XColor)); - idata=(unsigned char *)malloc(8); - memset(idata,0,8); - - p1=XCreatePixmap(display,RootWindow(display,myvisual->screen),8,8,1); - p2=XCreatePixmap(display,RootWindow(display,myvisual->screen),8,8,1); - - img = XCreateImage(display,myvisual->visual, - 1,XYBitmap,0,(char *)idata,8,8,8,1); - - GCv.function = GXcopy; - GCv.foreground = ~0; - GCv.background = 0; - GCv.plane_mask = AllPlanes; - GCc = XCreateGC(display,p1, - (GCFunction|GCForeground|GCBackground|GCPlaneMask),&GCv); - - XPutImage(display, p1,GCc,img,0,0,0,0,8,8); - XPutImage(display, p2,GCc,img,0,0,0,0,8,8); - XFreeGC(display, GCc); - - cursor = XCreatePixmapCursor(display,p1,p2,&b,&w,0,0); - - XFreePixmap(display,p1); - XFreePixmap(display,p2); - XDestroyImage(img); // will free idata as well - } - - colormap=XCreateColormap(display, // create colormap - RootWindow(display,myvisual->screen), - myvisual->visual,AllocNone); - - winattr.background_pixel=0; - winattr.border_pixel=WhitePixelOfScreen(screen); - winattr.bit_gravity=ForgetGravity; - winattr.win_gravity=NorthWestGravity; - winattr.backing_store=NotUseful; - winattr.override_redirect=False; - winattr.save_under=False; - winattr.event_mask=0; - winattr.do_not_propagate_mask=0; - winattr.colormap=colormap; - winattr.cursor=None; - - window=XCreateWindow(display, // create own window - RootWindow(display,DefaultScreen(display)), - 0,0,iResX,iResY, - 0,myvisual->depth, - InputOutput,myvisual->visual, - CWBorderPixel | CWBackPixel | - CWEventMask | CWDontPropagate | - CWColormap | CWCursor, - &winattr); - - if(!window) // no window? - { - fprintf(stderr,"Failed in XCreateWindow()!!!\n"); - osd_close_display(); // -> bye - return; - } - - delwindow = XInternAtom(display,"WM_DELETE_WINDOW",0); - XSetWMProtocols(display, window, &delwindow, 1); - - hints.flags=PMinSize|PMaxSize; // hints - if(fx) hints.flags|=USPosition|USSize; - else hints.flags|=PSize; - - hints.min_width = hints.max_width = hints.base_width = iResX; - hints.min_height = hints.max_height = hints.base_height = iResY; - - wm_hints.input=1; - wm_hints.flags=InputHint; - - XSetWMHints(display,window,&wm_hints); - XSetWMNormalHints(display,window,&hints); - if(pCaptionText) // caption - XStoreName(display,window,pCaptionText); - else XStoreName(display,window,"Pete MesaGL PSX Gpu"); - - XDefineCursor(display,window,cursor); // cursor - - if(fx) // window title bar hack - { - mwmhints.flags=MWM_HINTS_DECORATIONS; - mwmhints.decorations=0; - mwmatom=XInternAtom(display,"_MOTIF_WM_HINTS",0); - XChangeProperty(display,window,mwmatom,mwmatom,32, - PropModeReplace,(unsigned char *)&mwmhints,4); - } - - XSelectInput(display,window, // input setup - FocusChangeMask | ExposureMask | - KeyPressMask | KeyReleaseMask); - - XMapRaised(display,window); - XClearWindow(display,window); - XWindowEvent(display,window,ExposureMask,&event); - glXMakeCurrent(display,window,cx); - -/* - printf(glGetString(GL_VENDOR)); - printf("\n"); - printf(glGetString(GL_RENDERER)); - printf("\n"); -*/ - - if (fx) // after make current: fullscreen resize - { - XResizeWindow(display,window,screen->width,screen->height); - hints.min_width = hints.max_width = hints.base_width = screen->width; - hints.min_height= hints.max_height = hints.base_height = screen->height; - XSetWMNormalHints(display,window,&hints); - - // set the window layer for GNOME - { - XEvent xev; - - memset(&xev, 0, sizeof(xev)); - xev.xclient.type = ClientMessage; - xev.xclient.serial = 0; - xev.xclient.send_event = 1; - xev.xclient.message_type = XInternAtom(display, "_NET_WM_STATE", 0); - xev.xclient.window = window; - xev.xclient.format = 32; - xev.xclient.data.l[0] = 1; - xev.xclient.data.l[1] = XInternAtom(display, "_NET_WM_STATE_FULLSCREEN", 0); - xev.xclient.data.l[2] = 0; - xev.xclient.data.l[3] = 0; - xev.xclient.data.l[4] = 0; - - XSendEvent(display, RootWindow(display, DefaultScreen(display)), 0, - SubstructureRedirectMask | SubstructureNotifyMask, &xev); - } - } -} - -#endif // !defined(_MACGL) - -#ifndef _WINDOWS - -#if defined(_MACGL) -extern char * pCaptionText; -#endif - -//////////////////////////////////////////////////////////////////////// - -long GPUopen(unsigned long * disp,char * CapText,char * CfgFile) -{ - pCaptionText=CapText; - pConfigFile=CfgFile; - - ReadConfig(); // read text file for config - - SetFrameRateConfig(); // setup frame rate stuff - - bIsFirstFrame = TRUE; // we have to init later (well, no really... in Linux we do all in GPUopen) - - #if defined (_MACGL) - unsigned long display = ulInitDisplay(); - #else - sysdep_create_display(); // create display - #endif - - InitializeTextureStore(); // init texture mem - - rRatioRect.left = rRatioRect.top=0; - rRatioRect.right = iResX; - rRatioRect.bottom = iResY; - - GLinitialize(); // init opengl - - if(disp) - { - *disp = display; - } - - if(display) return 0; - return -1; -} - -#endif // ndef _WINDOWS - - - -//////////////////////////////////////////////////////////////////////// -// close -//////////////////////////////////////////////////////////////////////// - -#ifdef _WINDOWS - -long CALLBACK GPUclose() // WINDOWS CLOSE -{ - ExitKeyHandler(); - - GLcleanup(); // close OGL - - if(bChangeRes) // change res back - ChangeDisplaySettings(NULL,0); - - if(hPSEMenu) // set menu again - SetMenu(hWWindow,hPSEMenu); - - if(pGfxCardScreen) free(pGfxCardScreen); // free helper memory - pGfxCardScreen=0; - - if(iNoScreenSaver) EnableScreenSaver(TRUE); // enable screen saver again - - return 0; -} - -#else - -long GPUclose() // LINUX CLOSE -{ - GLcleanup(); // close OGL - - if(pGfxCardScreen) free(pGfxCardScreen); // free helper memory - pGfxCardScreen=0; - #if defined (_MACGL) - CloseDisplay(); - #else - osd_close_display(); // destroy display - #endif - return 0; -} - -#endif - -//////////////////////////////////////////////////////////////////////// -// I shot the sheriff... last function called from emu -//////////////////////////////////////////////////////////////////////// - -long CALLBACK GPUshutdown() -{ - if(psxVSecure) free(psxVSecure); // kill emulated vram memory - psxVSecure=0; - - return 0; -} - -//////////////////////////////////////////////////////////////////////// -// paint it black: simple func to clean up optical border garbage -//////////////////////////////////////////////////////////////////////// - -static void PaintBlackBorders(void) -{ - short s; - - glDisable(GL_SCISSOR_TEST); - if(bTexEnabled) {glDisable(GL_TEXTURE_2D);bTexEnabled=FALSE;} - if(bOldSmoothShaded) {glShadeModel(GL_FLAT);bOldSmoothShaded=FALSE;} - if(bBlendEnable) {glDisable(GL_BLEND);bBlendEnable=FALSE;} - glDisable(GL_ALPHA_TEST); - - glBegin(GL_QUADS); - - vertex[0].c.lcol=0xff000000; - SETCOL(vertex[0]); - - if(PreviousPSXDisplay.Range.x0) - { - s=PreviousPSXDisplay.Range.x0+1; - glVertex3f(0,0,0.99996f); - glVertex3f(0,PSXDisplay.DisplayMode.y,0.99996f); - glVertex3f(s,PSXDisplay.DisplayMode.y,0.99996f); - glVertex3f(s,0,0.99996f); - - s+=PreviousPSXDisplay.Range.x1-2; - - glVertex3f(s,0,0.99996f); - glVertex3f(s,PSXDisplay.DisplayMode.y,0.99996f); - glVertex3f(PSXDisplay.DisplayMode.x,PSXDisplay.DisplayMode.y,0.99996f); - glVertex3f(PSXDisplay.DisplayMode.x,0,0.99996f); - } - - if(PreviousPSXDisplay.Range.y0) - { - s=PreviousPSXDisplay.Range.y0+1; - glVertex3f(0,0,0.99996f); - glVertex3f(0,s,0.99996f); - glVertex3f(PSXDisplay.DisplayMode.x,s,0.99996f); - glVertex3f(PSXDisplay.DisplayMode.x,0,0.99996f); - } - - glEnd(); - - glEnable(GL_ALPHA_TEST); - glEnable(GL_SCISSOR_TEST); -} - -//////////////////////////////////////////////////////////////////////// -// helper to draw scanlines -//////////////////////////////////////////////////////////////////////// - -static __inline void XPRIMdrawTexturedQuad(OGLVertex* vertex1, OGLVertex* vertex2, - OGLVertex* vertex3, OGLVertex* vertex4) -{ - - glBegin(GL_QUAD_STRIP); - glTexCoord2fv(&vertex1->sow); - glVertex3fv(&vertex1->x); - - glTexCoord2fv(&vertex2->sow); - glVertex3fv(&vertex2->x); - - glTexCoord2fv(&vertex4->sow); - glVertex3fv(&vertex4->x); - - glTexCoord2fv(&vertex3->sow); - glVertex3fv(&vertex3->x); - glEnd(); -} - -//////////////////////////////////////////////////////////////////////// -// scanlines -//////////////////////////////////////////////////////////////////////// - -static void SetScanLines(void) -{ - glLoadIdentity(); - glOrtho(0,iResX,iResY, 0, -1, 1); - - if(bKeepRatio) - glViewport(0,0,iResX,iResY); - - glDisable(GL_SCISSOR_TEST); - glDisable(GL_ALPHA_TEST); - if(bOldSmoothShaded) {glShadeModel(GL_FLAT);bOldSmoothShaded=FALSE;} - - if(iScanBlend<0) // special texture mask scanline mode - { - if(!bTexEnabled) {glEnable(GL_TEXTURE_2D);bTexEnabled=TRUE;} - gTexName=gTexScanName; - glBindTexture(GL_TEXTURE_2D, gTexName); - if(bGLBlend) glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - if(!bBlendEnable) {glEnable(GL_BLEND);bBlendEnable=TRUE;} - SetScanTexTrans(); - - vertex[0].x=0; - vertex[0].y=iResY; - vertex[0].z=0.99996f; - - vertex[1].x=iResX; - vertex[1].y=iResY; - vertex[1].z=0.99996f; - - vertex[2].x=iResX; - vertex[2].y=0; - vertex[2].z=0.99996f; - - vertex[3].x=0; - vertex[3].y=0; - vertex[3].z=0.99996f; - - vertex[0].sow=0; - vertex[0].tow=0; - vertex[1].sow=(float)iResX/4.0f; - vertex[1].tow=0; - vertex[2].sow=vertex[1].sow; - vertex[2].tow=(float)iResY/4.0f; - vertex[3].sow=0; - vertex[3].tow=vertex[2].tow; - - vertex[0].c.lcol=0xffffffff; - SETCOL(vertex[0]); - - XPRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]); - - if(bGLBlend) glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, COMBINE_EXT); - } - else // typical line mode - { - if(bTexEnabled) {glDisable(GL_TEXTURE_2D);bTexEnabled=FALSE;} - - if(iScanBlend==0) - { - if(bBlendEnable) {glDisable(GL_BLEND);bBlendEnable=FALSE;} - vertex[0].c.lcol=0xff000000; - } - else - { - if(!bBlendEnable) {glEnable(GL_BLEND);bBlendEnable=TRUE;} - SetScanTrans(); - vertex[0].c.lcol=iScanBlend<<24; - } - - SETCOL(vertex[0]); - - glCallList(uiScanLine); - } - - glLoadIdentity(); - glOrtho(0,PSXDisplay.DisplayMode.x, - PSXDisplay.DisplayMode.y, 0, -1, 1); - - if(bKeepRatio) - glViewport(rRatioRect.left, - iResY-(rRatioRect.top+rRatioRect.bottom), - rRatioRect.right, - rRatioRect.bottom); // init viewport - - glEnable(GL_ALPHA_TEST); - glEnable(GL_SCISSOR_TEST); -} - -//////////////////////////////////////////////////////////////////////// -// blur, babe, blur (heavy performance hit for a so-so fullscreen effect) -//////////////////////////////////////////////////////////////////////// - -static void BlurBackBuffer(void) -{ - if(!gTexBlurName) return; - - if(bKeepRatio) glViewport(0,0,iResX,iResY); - - glDisable(GL_SCISSOR_TEST); - glDisable(GL_ALPHA_TEST); - if(bOldSmoothShaded) {glShadeModel(GL_FLAT);bOldSmoothShaded=FALSE;} - if(bBlendEnable) {glDisable(GL_BLEND);bBlendEnable=FALSE;} - if(!bTexEnabled) {glEnable(GL_TEXTURE_2D);bTexEnabled=TRUE;} - if(iZBufferDepth) glDisable(GL_DEPTH_TEST); - if(bDrawDither) glDisable(GL_DITHER); - - gTexName=gTexBlurName; - glBindTexture(GL_TEXTURE_2D, gTexName); - - glCopyTexSubImage2D( GL_TEXTURE_2D, 0, // get back buffer in texture - 0, - 0, - 0, - 0, - iResX,iResY); - - vertex[0].x=0; - vertex[0].y=PSXDisplay.DisplayMode.y; - vertex[1].x=PSXDisplay.DisplayMode.x; - vertex[1].y=PSXDisplay.DisplayMode.y; - vertex[2].x=PSXDisplay.DisplayMode.x; - vertex[2].y=0; - vertex[3].x=0; - vertex[3].y=0; - vertex[0].sow=0; - vertex[0].tow=0; - -#ifdef OWNSCALE - vertex[1].sow=((GLfloat)iFTexA)/256.0f; - vertex[2].tow=((GLfloat)iFTexB)/256.0f; -#else - vertex[1].sow=iFTexA; - vertex[2].tow=iFTexB; -#endif - vertex[1].tow=0; - vertex[2].sow=vertex[1].sow; - vertex[3].sow=0; - vertex[3].tow=vertex[2].tow; - - if(bGLBlend) glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - vertex[0].c.lcol=0x7fffffff; - SETCOL(vertex[0]); - - DrawMultiBlur(); // draw the backbuffer texture to create blur effect - - glEnable(GL_ALPHA_TEST); - glEnable(GL_SCISSOR_TEST); - if(iZBufferDepth) glEnable(GL_DEPTH_TEST); - if(bDrawDither) glEnable(GL_DITHER); - if(bGLBlend) glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, COMBINE_EXT); - - if(bKeepRatio) - glViewport(rRatioRect.left, // re-init viewport - iResY-(rRatioRect.top+rRatioRect.bottom), - rRatioRect.right, - rRatioRect.bottom); -} - -//////////////////////////////////////////////////////////////////////// -// "unblur" repairs the backbuffer after a blur - -static void UnBlurBackBuffer(void) -{ - if(!gTexBlurName) return; - - if(bKeepRatio) glViewport(0,0,iResX,iResY); - - glDisable(GL_SCISSOR_TEST); - glDisable(GL_ALPHA_TEST); - if(bBlendEnable) {glDisable(GL_BLEND);bBlendEnable=FALSE;} - if(!bTexEnabled) {glEnable(GL_TEXTURE_2D);bTexEnabled=TRUE;} - if(iZBufferDepth) glDisable(GL_DEPTH_TEST); - if(bDrawDither) glDisable(GL_DITHER); - - gTexName=gTexBlurName; - glBindTexture(GL_TEXTURE_2D, gTexName); - - vertex[0].x=0; - vertex[0].y=PSXDisplay.DisplayMode.y; - vertex[1].x=PSXDisplay.DisplayMode.x; - vertex[1].y=PSXDisplay.DisplayMode.y; - vertex[2].x=PSXDisplay.DisplayMode.x; - vertex[2].y=0; - vertex[3].x=0; - vertex[3].y=0; - vertex[0].sow=0; - vertex[0].tow=0; -#ifdef OWNSCALE - vertex[1].sow=((GLfloat)iFTexA)/256.0f; - vertex[2].tow=((GLfloat)iFTexB)/256.0f; -#else - vertex[1].sow=iFTexA; - vertex[2].tow=iFTexB; -#endif - vertex[1].tow=0; - vertex[2].sow=vertex[1].sow; - vertex[3].sow=0; - vertex[3].tow=vertex[2].tow; - if(bGLBlend) glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - vertex[0].c.lcol=0xffffffff; - SETCOL(vertex[0]); - - // simply draw the backbuffer texture (without blur) - XPRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]); - - glEnable(GL_ALPHA_TEST); - glEnable(GL_SCISSOR_TEST); - if(iZBufferDepth) glEnable(GL_DEPTH_TEST); - if(bDrawDither) glEnable(GL_DITHER); // dither mode - if(bGLBlend) glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, COMBINE_EXT); - - if(bKeepRatio) - glViewport(rRatioRect.left, - iResY-(rRatioRect.top+rRatioRect.bottom), - rRatioRect.right, - rRatioRect.bottom); // init viewport -} - -//////////////////////////////////////////////////////////////////////// -// Update display (swap buffers)... called in interlaced mode on -// every emulated vsync, otherwise whenever the displayed screen region -// has been changed -//////////////////////////////////////////////////////////////////////// - -int iLastRGB24=0; // special vars for checking when to skip two display updates -int iSkipTwo=0; - -void updateDisplay(void) // UPDATE DISPLAY -{ - BOOL bBlur=FALSE; - -#ifdef _WINDOWS - HDC hdc=GetDC(hWWindow); // windows: - wglMakeCurrent(hdc,GLCONTEXT); // -> make context current again -#endif -#if defined (_MACGL) - BringContextForward(); -#endif - bFakeFrontBuffer=FALSE; - bRenderFrontBuffer=FALSE; - - if(iRenderFVR) // frame buffer read fix mode still active? - { - iRenderFVR--; // -> if some frames in a row without read access: turn off mode - if(!iRenderFVR) bFullVRam=FALSE; - } - - if(iLastRGB24 && iLastRGB24!=PSXDisplay.RGB24+1) // (mdec) garbage check - { - iSkipTwo=2; // -> skip two frames to avoid garbage if color mode changes - } - iLastRGB24=0; - - if(PSXDisplay.RGB24)// && !bNeedUploadAfter) // (mdec) upload wanted? - { - PrepareFullScreenUpload(-1); - UploadScreen(PSXDisplay.Interlaced); // -> upload whole screen from psx vram - bNeedUploadTest=FALSE; - bNeedInterlaceUpdate=FALSE; - bNeedUploadAfter=FALSE; - bNeedRGB24Update=FALSE; - } - else - if(bNeedInterlaceUpdate) // smaller upload? - { - bNeedInterlaceUpdate=FALSE; - xrUploadArea=xrUploadAreaIL; // -> upload this rect - UploadScreen(TRUE); - } - - if(dwActFixes&512) bCheckFF9G4(NULL); // special game fix for FF9 - - if(PreviousPSXDisplay.Range.x0|| // paint black borders around display area, if needed - PreviousPSXDisplay.Range.y0) - PaintBlackBorders(); - - if(PSXDisplay.Disabled) // display disabled? - { - // moved here - glDisable(GL_SCISSOR_TEST); - glClearColor(0,0,0,128); // -> clear whole backbuffer - glClear(uiBufferBits); - glEnable(GL_SCISSOR_TEST); - gl_z=0.0f; - bDisplayNotSet = TRUE; - } - - if(iSkipTwo) // we are in skipping mood? - { - iSkipTwo--; - iDrawnSomething=0; // -> simply lie about something drawn - } - - if(iBlurBuffer && !bSkipNextFrame) // "blur display" activated? - {BlurBackBuffer();bBlur=TRUE;} // -> blur it - - if(iUseScanLines) SetScanLines(); // "scan lines" activated? do it - - if(usCursorActive) ShowGunCursor(); // "gun cursor" wanted? show 'em - - if(dwActFixes&128) // special FPS limitation mode? - { - if(bUseFrameLimit) PCFrameCap(); // -> ok, do it - if(bUseFrameSkip || ulKeybits&KEY_SHOWFPS) - PCcalcfps(); - } - - if(gTexPicName) DisplayPic(); // some gpu info picture active? display it - - if(bSnapShot) DoSnapShot(); // snapshot key pressed? cheeeese :) - - if(ulKeybits&KEY_SHOWFPS) // wanna see FPS? - { - sprintf(szDispBuf,"%06.1f",fps_cur); - DisplayText(); // -> show it - } - - //----------------------------------------------------// - // main buffer swapping (well, or skip it) - - if(bUseFrameSkip) // frame skipping active ? - { - if(!bSkipNextFrame) - { - if(iDrawnSomething) -#ifdef _WINDOWS - SwapBuffers(wglGetCurrentDC()); // -> to skip or not to skip -#elif defined(_MACGL) - DoBufferSwap(); -#else - glXSwapBuffers(display,window); -#endif - } - if(dwActFixes&0x180) // -> special old frame skipping: skip max one in a row - { - if((fps_skip < fFrameRateHz) && !(bSkipNextFrame)) - {bSkipNextFrame = TRUE; fps_skip=fFrameRateHz;} - else bSkipNextFrame = FALSE; - } - else FrameSkip(); - } - else // no skip ? - { - if(iDrawnSomething) -#ifdef _WINDOWS - SwapBuffers(wglGetCurrentDC()); // -> swap -#elif defined(_MACGL) - DoBufferSwap(); -#else - glXSwapBuffers(display,window); -#endif - } - - iDrawnSomething=0; - - //----------------------------------------------------// - - if(lClearOnSwap) // clear buffer after swap? - { - GLclampf g,b,r; - - if(bDisplayNotSet) // -> set new vals - SetOGLDisplaySettings(1); - - g=((GLclampf)GREEN(lClearOnSwapColor))/255.0f; // -> get col - b=((GLclampf)BLUE(lClearOnSwapColor))/255.0f; - r=((GLclampf)RED(lClearOnSwapColor))/255.0f; - - glDisable(GL_SCISSOR_TEST); - glClearColor(r,g,b,128); // -> clear - glClear(uiBufferBits); - glEnable(GL_SCISSOR_TEST); - lClearOnSwap=0; // -> done - } - else - { - if(bBlur) UnBlurBackBuffer(); // unblur buff, if blurred before - - if(iZBufferDepth) // clear zbuffer as well (if activated) - { - glDisable(GL_SCISSOR_TEST); - glClear(GL_DEPTH_BUFFER_BIT); - glEnable(GL_SCISSOR_TEST); - } - } - gl_z=0.0f; - - //----------------------------------------------------// - // additional uploads immediatly after swapping - - if(bNeedUploadAfter) // upload wanted? - { - bNeedUploadAfter=FALSE; - bNeedUploadTest=FALSE; - UploadScreen(-1); // -> upload - } - - if(bNeedUploadTest) - { - bNeedUploadTest=FALSE; - if(PSXDisplay.InterlacedTest && - //iOffscreenDrawing>2 && - PreviousPSXDisplay.DisplayPosition.x==PSXDisplay.DisplayPosition.x && - PreviousPSXDisplay.DisplayEnd.x==PSXDisplay.DisplayEnd.x && - PreviousPSXDisplay.DisplayPosition.y==PSXDisplay.DisplayPosition.y && - PreviousPSXDisplay.DisplayEnd.y==PSXDisplay.DisplayEnd.y) - { - PrepareFullScreenUpload(TRUE); - UploadScreen(TRUE); - } - } - - //----------------------------------------------------// - // rumbling (main emu pad effect) - - if(iRumbleTime) // shake screen by modifying view port - { - int i1=0,i2=0,i3=0,i4=0; - - iRumbleTime--; - if(iRumbleTime) - { - i1=((rand()*iRumbleVal)/RAND_MAX)-(iRumbleVal/2); - i2=((rand()*iRumbleVal)/RAND_MAX)-(iRumbleVal/2); - i3=((rand()*iRumbleVal)/RAND_MAX)-(iRumbleVal/2); - i4=((rand()*iRumbleVal)/RAND_MAX)-(iRumbleVal/2); - } - - glViewport(rRatioRect.left+i1, - iResY-(rRatioRect.top+rRatioRect.bottom)+i2, - rRatioRect.right+i3, - rRatioRect.bottom+i4); - } - -#ifdef _WINDOWS - ReleaseDC(hWWindow,hdc); // ! important ! -#endif - - if(ulKeybits&KEY_RESETTEXSTORE) ResetStuff(); // reset on gpu mode changes? do it before next frame is filled -} - -//////////////////////////////////////////////////////////////////////// -// update front display: smaller update func, if something has changed -// in the frontbuffer... dirty, but hey... real men know no pain -//////////////////////////////////////////////////////////////////////// - -void updateFrontDisplay(void) -{ - if(PreviousPSXDisplay.Range.x0|| - PreviousPSXDisplay.Range.y0) - PaintBlackBorders(); - - if(iBlurBuffer) BlurBackBuffer(); - - if(iUseScanLines) SetScanLines(); - - if(usCursorActive) ShowGunCursor(); - - bFakeFrontBuffer=FALSE; - bRenderFrontBuffer=FALSE; - - if(gTexPicName) DisplayPic(); - if(ulKeybits&KEY_SHOWFPS) DisplayText(); - -#ifdef _WINDOWS - { // windows: - HDC hdc=GetDC(hWWindow); - wglMakeCurrent(hdc,GLCONTEXT); // -> make current again - if(iDrawnSomething) - SwapBuffers(wglGetCurrentDC()); // -> swap - ReleaseDC(hWWindow,hdc); // -> ! important ! - } -#elif defined (_MACGL) -if (iDrawnSomething){ - DoBufferSwap(); - } -#else - if(iDrawnSomething) // linux: - glXSwapBuffers(display,window); -#endif - - if(iBlurBuffer) UnBlurBackBuffer(); -} - -//////////////////////////////////////////////////////////////////////// -// check if update needed -//////////////////////////////////////////////////////////////////////// - -static void ChangeDispOffsetsX(void) // CENTER X -{ - int lx,l;short sO; - - if(!PSXDisplay.Range.x1) return; // some range given? - - l=PSXDisplay.DisplayMode.x; - - l*=(int)PSXDisplay.Range.x1; // some funky calculation - l/=2560;lx=l;l&=0xfffffff8; - - if(l==PreviousPSXDisplay.Range.x1) return; // some change? - - sO=PreviousPSXDisplay.Range.x0; // store old - - if(lx>=PSXDisplay.DisplayMode.x) // range bigger? - { - PreviousPSXDisplay.Range.x1= // -> take display width - PSXDisplay.DisplayMode.x; - PreviousPSXDisplay.Range.x0=0; // -> start pos is 0 - } - else // range smaller? center it - { - PreviousPSXDisplay.Range.x1=l; // -> store width (8 pixel aligned) - PreviousPSXDisplay.Range.x0= // -> calc start pos - (PSXDisplay.Range.x0-500)/8; - if(PreviousPSXDisplay.Range.x0<0) // -> we don't support neg. values yet - PreviousPSXDisplay.Range.x0=0; - - if((PreviousPSXDisplay.Range.x0+lx)> // -> uhuu... that's too much - PSXDisplay.DisplayMode.x) - { - PreviousPSXDisplay.Range.x0= // -> adjust start - PSXDisplay.DisplayMode.x-lx; - PreviousPSXDisplay.Range.x1+=lx-l; // -> adjust width - } - } - - if(sO!=PreviousPSXDisplay.Range.x0) // something changed? - { - bDisplayNotSet=TRUE; // -> recalc display stuff - } -} - -//////////////////////////////////////////////////////////////////////// - -static void ChangeDispOffsetsY(void) // CENTER Y -{ - int iT;short sO; // store previous y size - - if(PSXDisplay.PAL) iT=48; else iT=28; // different offsets on PAL/NTSC - - if(PSXDisplay.Range.y0>=iT) // crossed the security line? :) - { - PreviousPSXDisplay.Range.y1= // -> store width - PSXDisplay.DisplayModeNew.y; - - sO=(PSXDisplay.Range.y0-iT-4)*PSXDisplay.Double; // -> calc offset - if(sO<0) sO=0; - - PSXDisplay.DisplayModeNew.y+=sO; // -> add offset to y size, too - } - else sO=0; // else no offset - - if(sO!=PreviousPSXDisplay.Range.y0) // something changed? - { - PreviousPSXDisplay.Range.y0=sO; - bDisplayNotSet=TRUE; // -> recalc display stuff - } -} - -//////////////////////////////////////////////////////////////////////// -// Aspect ratio of ogl screen: simply adjusting ogl view port -//////////////////////////////////////////////////////////////////////// - -void SetAspectRatio(void) -{ - float xs,ys,s;RECT r; - - if(!PSXDisplay.DisplayModeNew.x) return; - if(!PSXDisplay.DisplayModeNew.y) return; - - xs=(float)iResX/(float)PSXDisplay.DisplayModeNew.x; - ys=(float)iResY/(float)PSXDisplay.DisplayModeNew.y; - - s=min(xs,ys); - r.right =(int)((float)PSXDisplay.DisplayModeNew.x*s); - r.bottom=(int)((float)PSXDisplay.DisplayModeNew.y*s); - if(r.right > iResX) r.right = iResX; - if(r.bottom > iResY) r.bottom = iResY; - if(r.right < 1) r.right = 1; - if(r.bottom < 1) r.bottom = 1; - - r.left = (iResX-r.right)/2; - r.top = (iResY-r.bottom)/2; - - if(r.bottom<rRatioRect.bottom || - r.right <rRatioRect.right) - { - RECT rC; - glClearColor(0,0,0,128); - - if(r.right <rRatioRect.right) - { - rC.left=0; - rC.top=0; - rC.right=r.left; - rC.bottom=iResY; - glScissor(rC.left,rC.top,rC.right,rC.bottom); - glClear(uiBufferBits); - rC.left=iResX-rC.right; - glScissor(rC.left,rC.top,rC.right,rC.bottom); - glClear(uiBufferBits); - } - - if(r.bottom <rRatioRect.bottom) - { - rC.left=0; - rC.top=0; - rC.right=iResX; - rC.bottom=r.top; - glScissor(rC.left,rC.top,rC.right,rC.bottom); - glClear(uiBufferBits); - rC.top=iResY-rC.bottom; - glScissor(rC.left,rC.top,rC.right,rC.bottom); - glClear(uiBufferBits); - } - - bSetClip=TRUE; - bDisplayNotSet=TRUE; - } - - rRatioRect=r; - - - glViewport(rRatioRect.left, - iResY-(rRatioRect.top+rRatioRect.bottom), - rRatioRect.right, - rRatioRect.bottom); // init viewport -} - -//////////////////////////////////////////////////////////////////////// -// big ass check, if an ogl swap buffer is needed -//////////////////////////////////////////////////////////////////////// - -static void updateDisplayIfChanged(void) -{ - BOOL bUp; - - if ((PSXDisplay.DisplayMode.y == PSXDisplay.DisplayModeNew.y) && - (PSXDisplay.DisplayMode.x == PSXDisplay.DisplayModeNew.x)) - { - if((PSXDisplay.RGB24 == PSXDisplay.RGB24New) && - (PSXDisplay.Interlaced == PSXDisplay.InterlacedNew)) - return; // nothing has changed? fine, no swap buffer needed - } - else // some res change? - { - glLoadIdentity(); - glOrtho(0,PSXDisplay.DisplayModeNew.x, // -> new psx resolution - PSXDisplay.DisplayModeNew.y, 0, -1, 1); - if(bKeepRatio) SetAspectRatio(); - } - - bDisplayNotSet = TRUE; // re-calc offsets/display area - - bUp=FALSE; - if(PSXDisplay.RGB24!=PSXDisplay.RGB24New) // clean up textures, if rgb mode change (usually mdec on/off) - { - PreviousPSXDisplay.RGB24=0; // no full 24 frame uploaded yet - ResetTextureArea(FALSE); - bUp=TRUE; - } - - PSXDisplay.RGB24 = PSXDisplay.RGB24New; // get new infos - PSXDisplay.DisplayMode.y = PSXDisplay.DisplayModeNew.y; - PSXDisplay.DisplayMode.x = PSXDisplay.DisplayModeNew.x; - PSXDisplay.Interlaced = PSXDisplay.InterlacedNew; - - PSXDisplay.DisplayEnd.x= // calc new ends - PSXDisplay.DisplayPosition.x+ PSXDisplay.DisplayMode.x; - PSXDisplay.DisplayEnd.y= - PSXDisplay.DisplayPosition.y+ PSXDisplay.DisplayMode.y+PreviousPSXDisplay.DisplayModeNew.y; - PreviousPSXDisplay.DisplayEnd.x= - PreviousPSXDisplay.DisplayPosition.x+ PSXDisplay.DisplayMode.x; - PreviousPSXDisplay.DisplayEnd.y= - PreviousPSXDisplay.DisplayPosition.y+ PSXDisplay.DisplayMode.y+PreviousPSXDisplay.DisplayModeNew.y; - - ChangeDispOffsetsX(); - - if(iFrameLimit==2) SetAutoFrameCap(); // set new fps limit vals (depends on interlace) - - if(bUp) updateDisplay(); // yeah, real update (swap buffer) -} - -//////////////////////////////////////////////////////////////////////// -// window mode <-> fullscreen mode (windows) -//////////////////////////////////////////////////////////////////////// - -#ifdef _WINDOWS -void ChangeWindowMode(void) - { - GPUclose(); - bWindowMode=!bWindowMode; - GPUopen(hWWindow); - bChangeWinMode=FALSE; - } -#endif - -//////////////////////////////////////////////////////////////////////// -// swap update check (called by psx vsync function) -//////////////////////////////////////////////////////////////////////// - -static BOOL bSwapCheck(void) -{ - static int iPosCheck=0; - static PSXPoint_t pO; - static PSXPoint_t pD; - static int iDoAgain=0; - - if(PSXDisplay.DisplayPosition.x==pO.x && - PSXDisplay.DisplayPosition.y==pO.y && - PSXDisplay.DisplayEnd.x==pD.x && - PSXDisplay.DisplayEnd.y==pD.y) - iPosCheck++; - else iPosCheck=0; - - pO=PSXDisplay.DisplayPosition; - pD=PSXDisplay.DisplayEnd; - - if(iPosCheck<=4) return FALSE; - - iPosCheck=4; - - if(PSXDisplay.Interlaced) return FALSE; - - if (bNeedInterlaceUpdate|| - bNeedRGB24Update || - bNeedUploadAfter|| - bNeedUploadTest || - iDoAgain - ) - { - iDoAgain=0; - if(bNeedUploadAfter) - iDoAgain=1; - if(bNeedUploadTest && PSXDisplay.InterlacedTest) - iDoAgain=1; - - bDisplayNotSet = TRUE; - updateDisplay(); - - PreviousPSXDisplay.DisplayPosition.x=PSXDisplay.DisplayPosition.x; - PreviousPSXDisplay.DisplayPosition.y=PSXDisplay.DisplayPosition.y; - PreviousPSXDisplay.DisplayEnd.x=PSXDisplay.DisplayEnd.x; - PreviousPSXDisplay.DisplayEnd.y=PSXDisplay.DisplayEnd.y; - pO=PSXDisplay.DisplayPosition; - pD=PSXDisplay.DisplayEnd; - - return TRUE; - } - - return FALSE; -} - -//////////////////////////////////////////////////////////////////////// -// gun cursor func: player=0-7, x=0-511, y=0-255 -//////////////////////////////////////////////////////////////////////// - -void CALLBACK GPUcursor(int iPlayer,int x,int y) -{ - if(iPlayer<0) return; - if(iPlayer>7) return; - - usCursorActive|=(1<<iPlayer); - - if(x<0) x=0; - if(x>iGPUHeightMask) x=iGPUHeightMask; - if(y<0) y=0; - if(y>255) y=255; - - ptCursorPoint[iPlayer].x=x; - ptCursorPoint[iPlayer].y=y; -} - -//////////////////////////////////////////////////////////////////////// -// update lace is called every VSync. Basically we limit frame rate -// here, and in interlaced mode we swap ogl display buffers. -//////////////////////////////////////////////////////////////////////// - -static unsigned short usFirstPos=2; - -void CALLBACK GPUupdateLace(void) -{ - //if(!(dwActFixes&0x1000)) - // STATUSREG^=0x80000000; // interlaced bit toggle, if the CC game fix is not active (see gpuReadStatus) - - if(!(dwActFixes&128)) // normal frame limit func - CheckFrameRate(); - - if(iOffscreenDrawing==4) // special check if high offscreen drawing is on - { - if(bSwapCheck()) return; - } - - if(PSXDisplay.Interlaced) // interlaced mode? - { - STATUSREG^=0x80000000; - if(PSXDisplay.DisplayMode.x>0 && PSXDisplay.DisplayMode.y>0) - { - updateDisplay(); // -> swap buffers (new frame) - } - } - else if(bRenderFrontBuffer) // no interlace mode? and some stuff in front has changed? - { - updateFrontDisplay(); // -> update front buffer - } - else if(usFirstPos==1) // initial updates (after startup) - { - updateDisplay(); - } - -#if defined(_WINDOWS) || defined(_MACGL) - if(bChangeWinMode) ChangeWindowMode(); -#endif -} - -//////////////////////////////////////////////////////////////////////// -// process read request from GPU status register -//////////////////////////////////////////////////////////////////////// - -uint32_t CALLBACK GPUreadStatus(void) -{ - if(dwActFixes&0x1000) // CC game fix - { - static int iNumRead=0; - if((iNumRead++)==2) - { - iNumRead=0; - STATUSREG^=0x80000000; // interlaced bit toggle... we do it on every second read status... needed by some games (like ChronoCross) - } - } - - 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... - { - iFakePrimBusy--; - - if(iFakePrimBusy&1) // we do a busy-idle-busy-idle sequence after/while drawing prims - { - GPUIsBusy; - GPUIsNotReadyForCommands; - } - else - { - GPUIsIdle; - GPUIsReadyForCommands; - } - } - - return STATUSREG | (vBlank ? 0x80000000 : 0 );; -} - -//////////////////////////////////////////////////////////////////////// -// processes data send to GPU status register -// these are always single packet commands. -//////////////////////////////////////////////////////////////////////// - -void CALLBACK GPUwriteStatus(uint32_t gdata) -{ - uint32_t lCommand=(gdata>>24)&0xff; - -#ifdef _WINDOWS - if(bIsFirstFrame) GLinitialize(); // real ogl startup (needed by some emus) -#endif - - ulStatusControl[lCommand]=gdata; - - switch(lCommand) - { - //--------------------------------------------------// - // reset gpu - case 0x00: - memset(ulGPUInfoVals, 0x00, 16 * sizeof(uint32_t)); - lGPUstatusRet = 0x14802000; - PSXDisplay.Disabled=1; - iDataWriteMode=iDataReadMode=DR_NORMAL; - PSXDisplay.DrawOffset.x=PSXDisplay.DrawOffset.y=0; - drawX=drawY=0;drawW=drawH=0; - sSetMask=0;lSetMask=0;bCheckMask=FALSE;iSetMask=0; - usMirror=0; - GlobalTextAddrX=0;GlobalTextAddrY=0; - GlobalTextTP=0;GlobalTextABR=0; - PSXDisplay.RGB24=FALSE; - PSXDisplay.Interlaced=FALSE; - bUsingTWin = FALSE; - return; - - // dis/enable display - case 0x03: - PreviousPSXDisplay.Disabled = PSXDisplay.Disabled; - PSXDisplay.Disabled = (gdata & 1); - - if(PSXDisplay.Disabled) - STATUSREG|=GPUSTATUS_DISPLAYDISABLED; - else STATUSREG&=~GPUSTATUS_DISPLAYDISABLED; - - if (iOffscreenDrawing==4 && - PreviousPSXDisplay.Disabled && - !(PSXDisplay.Disabled)) - { - - if(!PSXDisplay.RGB24) - { - PrepareFullScreenUpload(TRUE); - UploadScreen(TRUE); - updateDisplay(); - } - } - - return; - - // setting transfer mode - case 0x04: - gdata &= 0x03; // only want the lower two bits - - iDataWriteMode=iDataReadMode=DR_NORMAL; - if(gdata==0x02) iDataWriteMode=DR_VRAMTRANSFER; - if(gdata==0x03) iDataReadMode =DR_VRAMTRANSFER; - - STATUSREG&=~GPUSTATUS_DMABITS; // clear the current settings of the DMA bits - STATUSREG|=(gdata << 29); // set the DMA bits according to the received data - - return; - - // setting display position - case 0x05: - { - short sx=(short)(gdata & 0x3ff); - short sy; - - if(iGPUHeight==1024) - { - if(dwGPUVersion==2) - sy = (short)((gdata>>12)&0x3ff); - else sy = (short)((gdata>>10)&0x3ff); - } - else sy = (short)((gdata>>10)&0x3ff); // really: 0x1ff, but we adjust it later - - if (sy & 0x200) - { - sy|=0xfc00; - PreviousPSXDisplay.DisplayModeNew.y=sy/PSXDisplay.Double; - sy=0; - } - else PreviousPSXDisplay.DisplayModeNew.y=0; - - if(sx>1000) sx=0; - - if(usFirstPos) - { - usFirstPos--; - if(usFirstPos) - { - PreviousPSXDisplay.DisplayPosition.x = sx; - PreviousPSXDisplay.DisplayPosition.y = sy; - PSXDisplay.DisplayPosition.x = sx; - PSXDisplay.DisplayPosition.y = sy; - } - } - - if(dwActFixes&8) - { - if((!PSXDisplay.Interlaced) && - PreviousPSXDisplay.DisplayPosition.x == sx && - PreviousPSXDisplay.DisplayPosition.y == sy) - return; - - PSXDisplay.DisplayPosition.x = PreviousPSXDisplay.DisplayPosition.x; - PSXDisplay.DisplayPosition.y = PreviousPSXDisplay.DisplayPosition.y; - PreviousPSXDisplay.DisplayPosition.x = sx; - PreviousPSXDisplay.DisplayPosition.y = sy; - } - else - { - if((!PSXDisplay.Interlaced) && - PSXDisplay.DisplayPosition.x == sx && - PSXDisplay.DisplayPosition.y == sy) - return; - PreviousPSXDisplay.DisplayPosition.x = PSXDisplay.DisplayPosition.x; - PreviousPSXDisplay.DisplayPosition.y = PSXDisplay.DisplayPosition.y; - PSXDisplay.DisplayPosition.x = sx; - PSXDisplay.DisplayPosition.y = sy; - } - - PSXDisplay.DisplayEnd.x= - PSXDisplay.DisplayPosition.x+ PSXDisplay.DisplayMode.x; - PSXDisplay.DisplayEnd.y= - PSXDisplay.DisplayPosition.y+ PSXDisplay.DisplayMode.y+PreviousPSXDisplay.DisplayModeNew.y; - - PreviousPSXDisplay.DisplayEnd.x= - PreviousPSXDisplay.DisplayPosition.x+ PSXDisplay.DisplayMode.x; - PreviousPSXDisplay.DisplayEnd.y= - PreviousPSXDisplay.DisplayPosition.y+ PSXDisplay.DisplayMode.y+PreviousPSXDisplay.DisplayModeNew.y; - - bDisplayNotSet = TRUE; - - if (!(PSXDisplay.Interlaced)) - { - updateDisplay(); - } - else - if(PSXDisplay.InterlacedTest && - ((PreviousPSXDisplay.DisplayPosition.x != PSXDisplay.DisplayPosition.x)|| - (PreviousPSXDisplay.DisplayPosition.y != PSXDisplay.DisplayPosition.y))) - PSXDisplay.InterlacedTest--; - - return; - } - - // setting width - case 0x06: - - PSXDisplay.Range.x0=gdata & 0x7ff; //0x3ff; - PSXDisplay.Range.x1=(gdata>>12) & 0xfff;//0x7ff; - - PSXDisplay.Range.x1-=PSXDisplay.Range.x0; - - ChangeDispOffsetsX(); - - return; - - // setting height - case 0x07: - - PreviousPSXDisplay.Height = PSXDisplay.Height; - - PSXDisplay.Range.y0=gdata & 0x3ff; - PSXDisplay.Range.y1=(gdata>>10) & 0x3ff; - - PSXDisplay.Height = PSXDisplay.Range.y1 - - PSXDisplay.Range.y0 + - PreviousPSXDisplay.DisplayModeNew.y; - - if (PreviousPSXDisplay.Height != PSXDisplay.Height) - { - PSXDisplay.DisplayModeNew.y=PSXDisplay.Height*PSXDisplay.Double; - ChangeDispOffsetsY(); - updateDisplayIfChanged(); - } - return; - - // setting display infos - case 0x08: - - PSXDisplay.DisplayModeNew.x = dispWidths[(gdata & 0x03) | ((gdata & 0x40) >> 4)]; - - if (gdata&0x04) PSXDisplay.Double=2; - else PSXDisplay.Double=1; - PSXDisplay.DisplayModeNew.y = PSXDisplay.Height*PSXDisplay.Double; - - ChangeDispOffsetsY(); - - PSXDisplay.PAL = (gdata & 0x08)?TRUE:FALSE; // if 1 - PAL mode, else NTSC - PSXDisplay.RGB24New = (gdata & 0x10)?TRUE:FALSE; // if 1 - TrueColor - PSXDisplay.InterlacedNew = (gdata & 0x20)?TRUE:FALSE; // if 1 - Interlace - - STATUSREG&=~GPUSTATUS_WIDTHBITS; // clear the width bits - - STATUSREG|= - (((gdata & 0x03) << 17) | - ((gdata & 0x40) << 10)); // set the width bits - - PreviousPSXDisplay.InterlacedNew=FALSE; - if (PSXDisplay.InterlacedNew) - { - if(!PSXDisplay.Interlaced) - { - PSXDisplay.InterlacedTest=2; - PreviousPSXDisplay.DisplayPosition.x = PSXDisplay.DisplayPosition.x; - PreviousPSXDisplay.DisplayPosition.y = PSXDisplay.DisplayPosition.y; - PreviousPSXDisplay.InterlacedNew=TRUE; - } - - STATUSREG|=GPUSTATUS_INTERLACED; - } - else - { - PSXDisplay.InterlacedTest=0; - STATUSREG&=~GPUSTATUS_INTERLACED; - } - - if (PSXDisplay.PAL) - STATUSREG|=GPUSTATUS_PAL; - else STATUSREG&=~GPUSTATUS_PAL; - - if (PSXDisplay.Double==2) - STATUSREG|=GPUSTATUS_DOUBLEHEIGHT; - else STATUSREG&=~GPUSTATUS_DOUBLEHEIGHT; - - if (PSXDisplay.RGB24New) - STATUSREG|=GPUSTATUS_RGB24; - else STATUSREG&=~GPUSTATUS_RGB24; - - updateDisplayIfChanged(); - - return; - - //--------------------------------------------------// - // ask about GPU version and other stuff - case 0x10: - - gdata&=0xff; - - switch(gdata) - { - case 0x02: - GPUdataRet=ulGPUInfoVals[INFO_TW]; // tw infos - return; - case 0x03: - GPUdataRet=ulGPUInfoVals[INFO_DRAWSTART]; // draw start - return; - case 0x04: - GPUdataRet=ulGPUInfoVals[INFO_DRAWEND]; // draw end - return; - case 0x05: - case 0x06: - GPUdataRet=ulGPUInfoVals[INFO_DRAWOFF]; // draw offset - return; - case 0x07: - if(dwGPUVersion==2) - GPUdataRet=0x01; - else GPUdataRet=0x02; // gpu type - return; - case 0x08: - case 0x0F: // some bios addr? - GPUdataRet=0xBFC03720; - return; - } - return; - //--------------------------------------------------// - } -} - -//////////////////////////////////////////////////////////////////////// -// vram read/write helpers -//////////////////////////////////////////////////////////////////////// - -BOOL bNeedWriteUpload=FALSE; - -static __inline void FinishedVRAMWrite(void) -{ - if(bNeedWriteUpload) - { - bNeedWriteUpload=FALSE; - CheckWriteUpdate(); - } - - // set register to NORMAL operation - iDataWriteMode = DR_NORMAL; - - // reset transfer values, to prevent mis-transfer of data - VRAMWrite.ColsRemaining = 0; - VRAMWrite.RowsRemaining = 0; -} - -static __inline void FinishedVRAMRead(void) -{ - // set register to NORMAL operation - iDataReadMode = DR_NORMAL; - // reset transfer values, to prevent mis-transfer of data - VRAMRead.x = 0; - VRAMRead.y = 0; - VRAMRead.Width = 0; - VRAMRead.Height = 0; - VRAMRead.ColsRemaining = 0; - VRAMRead.RowsRemaining = 0; - - // indicate GPU is no longer ready for VRAM data in the STATUS REGISTER - STATUSREG&=~GPUSTATUS_READYFORVRAM; -} - -//////////////////////////////////////////////////////////////////////// -// vram read check ex (reading from card's back/frontbuffer if needed... -// slow!) -//////////////////////////////////////////////////////////////////////// - -void CheckVRamReadEx(int x, int y, int dx, int dy) -{ - unsigned short sArea; - int ux,uy,udx,udy,wx,wy; - unsigned short * p1, *p2; - float XS,YS; - unsigned char * ps; - unsigned char * px; - unsigned short s,sx; - - if(STATUSREG&GPUSTATUS_RGB24) return; - - if(((dx > PSXDisplay.DisplayPosition.x) && - (x < PSXDisplay.DisplayEnd.x) && - (dy > PSXDisplay.DisplayPosition.y) && - (y < PSXDisplay.DisplayEnd.y))) - sArea=0; - else - if((!(PSXDisplay.InterlacedTest) && - (dx > PreviousPSXDisplay.DisplayPosition.x) && - (x < PreviousPSXDisplay.DisplayEnd.x) && - (dy > PreviousPSXDisplay.DisplayPosition.y) && - (y < PreviousPSXDisplay.DisplayEnd.y))) - sArea=1; - else - { - return; - } - - ////////////// - - if(iRenderFVR) - { - bFullVRam=TRUE;iRenderFVR=2;return; - } - bFullVRam=TRUE;iRenderFVR=2; - - ////////////// - - p2=0; - - if(sArea==0) - { - ux=PSXDisplay.DisplayPosition.x; - uy=PSXDisplay.DisplayPosition.y; - udx=PSXDisplay.DisplayEnd.x-ux; - udy=PSXDisplay.DisplayEnd.y-uy; - if((PreviousPSXDisplay.DisplayEnd.x- - PreviousPSXDisplay.DisplayPosition.x)==udx && - (PreviousPSXDisplay.DisplayEnd.y- - PreviousPSXDisplay.DisplayPosition.y)==udy) - p2=(psxVuw + (1024*PreviousPSXDisplay.DisplayPosition.y) + - PreviousPSXDisplay.DisplayPosition.x); - } - else - { - ux=PreviousPSXDisplay.DisplayPosition.x; - uy=PreviousPSXDisplay.DisplayPosition.y; - udx=PreviousPSXDisplay.DisplayEnd.x-ux; - udy=PreviousPSXDisplay.DisplayEnd.y-uy; - if((PSXDisplay.DisplayEnd.x- - PSXDisplay.DisplayPosition.x)==udx && - (PSXDisplay.DisplayEnd.y- - PSXDisplay.DisplayPosition.y)==udy) - p2=(psxVuw + (1024*PSXDisplay.DisplayPosition.y) + - PSXDisplay.DisplayPosition.x); - } - - p1=(psxVuw + (1024*uy) + ux); - if(p1==p2) p2=0; - - x=0;y=0; - wx=dx=udx;wy=dy=udy; - - if(udx<=0) return; - if(udy<=0) return; - if(dx<=0) return; - if(dy<=0) return; - if(wx<=0) return; - if(wy<=0) return; - - XS=(float)rRatioRect.right/(float)wx; - YS=(float)rRatioRect.bottom/(float)wy; - - dx=(int)((float)(dx)*XS); - dy=(int)((float)(dy)*YS); - - if(dx>iResX) dx=iResX; - if(dy>iResY) dy=iResY; - - if(dx<=0) return; - if(dy<=0) return; - - // ogl y adjust - y=iResY-y-dy; - - x+=rRatioRect.left; - y-=rRatioRect.top; - - if(y<0) y=0; if((y+dy)>iResY) dy=iResY-y; - - if(!pGfxCardScreen) - { - glPixelStorei(GL_PACK_ALIGNMENT,1); - pGfxCardScreen=(unsigned char *)malloc(iResX*iResY*4); - } - - ps=pGfxCardScreen; - - if(!sArea) glReadBuffer(GL_FRONT); - - glReadPixels(x,y,dx,dy,GL_RGB,GL_UNSIGNED_BYTE,ps); - - if(!sArea) glReadBuffer(GL_BACK); - - s=0; - - XS=(float)dx/(float)(udx); - YS=(float)dy/(float)(udy+1); - - for(y=udy;y>0;y--) - { - for(x=0;x<udx;x++) - { - if(p1>=psxVuw && p1<psxVuw_eom) - { - px=ps+(3*((int)((float)x * XS))+ - (3*dx)*((int)((float)y*YS))); - sx=(*px)>>3;px++; - s=sx; - sx=(*px)>>3;px++; - s|=sx<<5; - sx=(*px)>>3; - s|=sx<<10; - s&=~0x8000; - *p1=s; - } - if(p2>=psxVuw && p2<psxVuw_eom) *p2=s; - - p1++; - if(p2) p2++; - } - - p1 += 1024 - udx; - if(p2) p2 += 1024 - udx; - } -} - -//////////////////////////////////////////////////////////////////////// -// vram read check (reading from card's back/frontbuffer if needed... -// slow!) -//////////////////////////////////////////////////////////////////////// - -void CheckVRamRead(int x, int y, int dx, int dy,BOOL bFront) -{ - unsigned short sArea;unsigned short * p; - int ux,uy,udx,udy,wx,wy;float XS,YS; - unsigned char * ps, * px; - unsigned short s=0,sx; - - if(STATUSREG&GPUSTATUS_RGB24) return; - - if(((dx > PSXDisplay.DisplayPosition.x) && - (x < PSXDisplay.DisplayEnd.x) && - (dy > PSXDisplay.DisplayPosition.y) && - (y < PSXDisplay.DisplayEnd.y))) - sArea=0; - else - if((!(PSXDisplay.InterlacedTest) && - (dx > PreviousPSXDisplay.DisplayPosition.x) && - (x < PreviousPSXDisplay.DisplayEnd.x) && - (dy > PreviousPSXDisplay.DisplayPosition.y) && - (y < PreviousPSXDisplay.DisplayEnd.y))) - sArea=1; - else - { - return; - } - - if(dwActFixes&0x40) - { - if(iRenderFVR) - { - bFullVRam=TRUE;iRenderFVR=2;return; - } - bFullVRam=TRUE;iRenderFVR=2; - } - - ux=x;uy=y;udx=dx;udy=dy; - - if(sArea==0) - { - x -=PSXDisplay.DisplayPosition.x; - dx-=PSXDisplay.DisplayPosition.x; - y -=PSXDisplay.DisplayPosition.y; - dy-=PSXDisplay.DisplayPosition.y; - wx=PSXDisplay.DisplayEnd.x-PSXDisplay.DisplayPosition.x; - wy=PSXDisplay.DisplayEnd.y-PSXDisplay.DisplayPosition.y; - } - else - { - x -=PreviousPSXDisplay.DisplayPosition.x; - dx-=PreviousPSXDisplay.DisplayPosition.x; - y -=PreviousPSXDisplay.DisplayPosition.y; - dy-=PreviousPSXDisplay.DisplayPosition.y; - wx=PreviousPSXDisplay.DisplayEnd.x-PreviousPSXDisplay.DisplayPosition.x; - wy=PreviousPSXDisplay.DisplayEnd.y-PreviousPSXDisplay.DisplayPosition.y; - } - if(x<0) {ux-=x;x=0;} - if(y<0) {uy-=y;y=0;} - if(dx>wx) {udx-=(dx-wx);dx=wx;} - if(dy>wy) {udy-=(dy-wy);dy=wy;} - udx-=ux; - udy-=uy; - - p=(psxVuw + (1024*uy) + ux); - - if(udx<=0) return; - if(udy<=0) return; - if(dx<=0) return; - if(dy<=0) return; - if(wx<=0) return; - if(wy<=0) return; - - XS=(float)rRatioRect.right/(float)wx; - YS=(float)rRatioRect.bottom/(float)wy; - - dx=(int)((float)(dx)*XS); - dy=(int)((float)(dy)*YS); - x=(int)((float)x*XS); - y=(int)((float)y*YS); - - dx-=x; - dy-=y; - - if(dx>iResX) dx=iResX; - if(dy>iResY) dy=iResY; - - if(dx<=0) return; - if(dy<=0) return; - - // ogl y adjust - y=iResY-y-dy; - - x+=rRatioRect.left; - y-=rRatioRect.top; - - if(y<0) y=0; if((y+dy)>iResY) dy=iResY-y; - - if(!pGfxCardScreen) - { - glPixelStorei(GL_PACK_ALIGNMENT,1); - pGfxCardScreen=(unsigned char *)malloc(iResX*iResY*4); - } - - ps=pGfxCardScreen; - - if(bFront) glReadBuffer(GL_FRONT); - - glReadPixels(x,y,dx,dy,GL_RGB,GL_UNSIGNED_BYTE,ps); - - if(bFront) glReadBuffer(GL_BACK); - - XS=(float)dx/(float)(udx); - YS=(float)dy/(float)(udy+1); - - for(y=udy;y>0;y--) - { - for(x=0;x<udx;x++) - { - if(p>=psxVuw && p<psxVuw_eom) - { - px=ps+(3*((int)((float)x * XS))+ - (3*dx)*((int)((float)y*YS))); - sx=(*px)>>3;px++; - s=sx; - sx=(*px)>>3;px++; - s|=sx<<5; - sx=(*px)>>3; - s|=sx<<10; - s&=~0x8000; - *p=s; - } - p++; - } - p += 1024 - udx; - } -} - -//////////////////////////////////////////////////////////////////////// -// core read from vram -//////////////////////////////////////////////////////////////////////// - -void CALLBACK GPUreadDataMem(uint32_t *pMem, int iSize) -{ - int i; - - if(iDataReadMode!=DR_VRAMTRANSFER) return; - - GPUIsBusy; - - // adjust read ptr, if necessary - while(VRAMRead.ImagePtr>=psxVuw_eom) - VRAMRead.ImagePtr-=iGPUHeight*1024; - while(VRAMRead.ImagePtr<psxVuw) - VRAMRead.ImagePtr+=iGPUHeight*1024; - - if((iFrameReadType&1 && iSize>1) && - !(iDrawnSomething==2 && - VRAMRead.x == VRAMWrite.x && - VRAMRead.y == VRAMWrite.y && - VRAMRead.Width == VRAMWrite.Width && - VRAMRead.Height == VRAMWrite.Height)) - CheckVRamRead(VRAMRead.x,VRAMRead.y, - VRAMRead.x+VRAMRead.RowsRemaining, - VRAMRead.y+VRAMRead.ColsRemaining, - TRUE); - - for(i=0;i<iSize;i++) - { - // do 2 seperate 16bit reads for compatibility (wrap issues) - if ((VRAMRead.ColsRemaining > 0) && (VRAMRead.RowsRemaining > 0)) - { - // lower 16 bit - GPUdataRet=(uint32_t)*VRAMRead.ImagePtr; - - VRAMRead.ImagePtr++; - if(VRAMRead.ImagePtr>=psxVuw_eom) VRAMRead.ImagePtr-=iGPUHeight*1024; - VRAMRead.RowsRemaining --; - - if(VRAMRead.RowsRemaining<=0) - { - VRAMRead.RowsRemaining = VRAMRead.Width; - VRAMRead.ColsRemaining--; - VRAMRead.ImagePtr += 1024 - VRAMRead.Width; - if(VRAMRead.ImagePtr>=psxVuw_eom) VRAMRead.ImagePtr-=iGPUHeight*1024; - } - - // higher 16 bit (always, even if it's an odd width) - GPUdataRet|=(uint32_t)(*VRAMRead.ImagePtr)<<16; - *pMem++=GPUdataRet; - - if(VRAMRead.ColsRemaining <= 0) - {FinishedVRAMRead();goto ENDREAD;} - - VRAMRead.ImagePtr++; - if(VRAMRead.ImagePtr>=psxVuw_eom) VRAMRead.ImagePtr-=iGPUHeight*1024; - VRAMRead.RowsRemaining--; - if(VRAMRead.RowsRemaining<=0) - { - VRAMRead.RowsRemaining = VRAMRead.Width; - VRAMRead.ColsRemaining--; - VRAMRead.ImagePtr += 1024 - VRAMRead.Width; - if(VRAMRead.ImagePtr>=psxVuw_eom) VRAMRead.ImagePtr-=iGPUHeight*1024; - } - if(VRAMRead.ColsRemaining <= 0) - {FinishedVRAMRead();goto ENDREAD;} - } - else {FinishedVRAMRead();goto ENDREAD;} - } - -ENDREAD: - GPUIsIdle; -} - -uint32_t CALLBACK GPUreadData(void) -{ - uint32_t l; - GPUreadDataMem(&l,1); - return GPUdataRet; -} - -//////////////////////////////////////////////////////////////////////// -// helper table to know how much data is used by drawing commands -//////////////////////////////////////////////////////////////////////// - -const unsigned char primTableCX[256] = -{ - // 00 - 0,0,3,0,0,0,0,0, - // 08 - 0,0,0,0,0,0,0,0, - // 10 - 0,0,0,0,0,0,0,0, - // 18 - 0,0,0,0,0,0,0,0, - // 20 - 4,4,4,4,7,7,7,7, - // 28 - 5,5,5,5,9,9,9,9, - // 30 - 6,6,6,6,9,9,9,9, - // 38 - 8,8,8,8,12,12,12,12, - // 40 - 3,3,3,3,0,0,0,0, - // 48 -// 5,5,5,5,6,6,6,6, //FLINE - 254,254,254,254,254,254,254,254, - // 50 - 4,4,4,4,0,0,0,0, - // 58 -// 7,7,7,7,9,9,9,9, // LINEG3 LINEG4 - 255,255,255,255,255,255,255,255, - // 60 - 3,3,3,3,4,4,4,4, // TILE SPRT - // 68 - 2,2,2,2,3,3,3,3, // TILE1 - // 70 - 2,2,2,2,3,3,3,3, - // 78 - 2,2,2,2,3,3,3,3, - // 80 - 4,0,0,0,0,0,0,0, - // 88 - 0,0,0,0,0,0,0,0, - // 90 - 0,0,0,0,0,0,0,0, - // 98 - 0,0,0,0,0,0,0,0, - // a0 - 3,0,0,0,0,0,0,0, - // a8 - 0,0,0,0,0,0,0,0, - // b0 - 0,0,0,0,0,0,0,0, - // b8 - 0,0,0,0,0,0,0,0, - // c0 - 3,0,0,0,0,0,0,0, - // c8 - 0,0,0,0,0,0,0,0, - // d0 - 0,0,0,0,0,0,0,0, - // d8 - 0,0,0,0,0,0,0,0, - // e0 - 0,1,1,1,1,1,1,0, - // e8 - 0,0,0,0,0,0,0,0, - // f0 - 0,0,0,0,0,0,0,0, - // f8 - 0,0,0,0,0,0,0,0 -}; - -//////////////////////////////////////////////////////////////////////// -// processes data send to GPU data register -//////////////////////////////////////////////////////////////////////// - -void CALLBACK GPUwriteDataMem(uint32_t *pMem, int iSize) -{ - unsigned char command; - uint32_t gdata=0; - int i=0; - GPUIsBusy; - GPUIsNotReadyForCommands; - -STARTVRAM: - - if(iDataWriteMode==DR_VRAMTRANSFER) - { - // make sure we are in vram - while(VRAMWrite.ImagePtr>=psxVuw_eom) - VRAMWrite.ImagePtr-=iGPUHeight*1024; - while(VRAMWrite.ImagePtr<psxVuw) - VRAMWrite.ImagePtr+=iGPUHeight*1024; - - // now do the loop - while(VRAMWrite.ColsRemaining>0) - { - while(VRAMWrite.RowsRemaining>0) - { - if(i>=iSize) {goto ENDVRAM;} - i++; - - gdata=*pMem++; - - *VRAMWrite.ImagePtr++ = (unsigned short)gdata; - if(VRAMWrite.ImagePtr>=psxVuw_eom) VRAMWrite.ImagePtr-=iGPUHeight*1024; - VRAMWrite.RowsRemaining --; - - if(VRAMWrite.RowsRemaining <= 0) - { - VRAMWrite.ColsRemaining--; - if (VRAMWrite.ColsRemaining <= 0) // last pixel is odd width - { - gdata=(gdata&0xFFFF)|(((uint32_t)(*VRAMWrite.ImagePtr))<<16); - FinishedVRAMWrite(); - goto ENDVRAM; - } - VRAMWrite.RowsRemaining = VRAMWrite.Width; - VRAMWrite.ImagePtr += 1024 - VRAMWrite.Width; - } - - *VRAMWrite.ImagePtr++ = (unsigned short)(gdata>>16); - if(VRAMWrite.ImagePtr>=psxVuw_eom) VRAMWrite.ImagePtr-=iGPUHeight*1024; - VRAMWrite.RowsRemaining --; - } - - VRAMWrite.RowsRemaining = VRAMWrite.Width; - VRAMWrite.ColsRemaining--; - VRAMWrite.ImagePtr += 1024 - VRAMWrite.Width; - } - - FinishedVRAMWrite(); - } - -ENDVRAM: - - if(iDataWriteMode==DR_NORMAL) - { - void (* *primFunc)(unsigned char *); - if(bSkipNextFrame) primFunc=primTableSkip; - else primFunc=primTableJ; - - for(;i<iSize;) - { - if(iDataWriteMode==DR_VRAMTRANSFER) goto STARTVRAM; - - gdata=*pMem++;i++; - - if(gpuDataC == 0) - { - command = (unsigned char)((gdata>>24) & 0xff); - - if(primTableCX[command]) - { - gpuDataC = primTableCX[command]; - gpuCommand = command; - gpuDataM[0] = gdata; - gpuDataP = 1; - } - else continue; - } - else - { - gpuDataM[gpuDataP] = gdata; - if(gpuDataC>128) - { - if((gpuDataC==254 && gpuDataP>=3) || - (gpuDataC==255 && gpuDataP>=4 && !(gpuDataP&1))) - { - if((gpuDataM[gpuDataP] & 0xF000F000) == 0x50005000) - gpuDataP=gpuDataC-1; - } - } - gpuDataP++; - } - - if(gpuDataP == gpuDataC) - { - gpuDataC=gpuDataP=0; - primFunc[gpuCommand]((unsigned char *)gpuDataM); - - if(dwEmuFixes&0x0001 || dwActFixes&0x20000) // hack for emulating "gpu busy" in some games - iFakePrimBusy=4; - } - } - } - - GPUdataRet=gdata; - - GPUIsReadyForCommands; - GPUIsIdle; -} - -//////////////////////////////////////////////////////////////////////// - -void CALLBACK GPUwriteData(uint32_t gdata) -{ - GPUwriteDataMem(&gdata,1); -} - -//////////////////////////////////////////////////////////////////////// -// call config dlg -//////////////////////////////////////////////////////////////////////// - -#ifdef _WINDOWS - -long CALLBACK GPUconfigure(void) -{ - HWND hWP=GetActiveWindow(); - DialogBox(hInst,MAKEINTRESOURCE(IDD_CFGDLG), - hWP,(DLGPROC)CfgDlgProc); - - return 0; -} - -#elif defined(_MACGL) -long CALLBACK GPUconfigure(void) -{ - DlgProc(); - return 0; -} -#else - -static void StartCfgTool(char *arg) // linux: start external cfg tool -{ - char cfg[256]; - struct stat buf; - - strcpy(cfg, "./cfgpeopsxgl"); - if (stat(cfg, &buf) != -1) { - if (fork() == 0) { - execl(cfg, "cfgpeopsxgl", arg, NULL); - exit(0); - } - return; - } - - strcpy(cfg, "./cfg/cfgpeopsxgl"); - if (stat(cfg, &buf) != -1) { - if (fork() == 0) { - execl(cfg, "cfgpeopsxgl", arg, NULL); - exit(0); - } - return; - } - - sprintf(cfg, "%s/.pcsx/plugins/cfg/cfgpeopsxgl", getenv("HOME")); - if (stat(cfg, &buf) != -1) { - if (fork() == 0) { - execl(cfg, "cfgpeopsxgl", arg, NULL); - exit(0); - } - return; - } - - printf("ERROR: cfgpeopsxgl file not found!\n"); -} - -long CALLBACK GPUconfigure(void) -{ - StartCfgTool("CFG"); - return 0; -} - -#endif // def _WINDOWS / _MACGL - -//////////////////////////////////////////////////////////////////////// -// sets all kind of act fixes -//////////////////////////////////////////////////////////////////////// - -void SetFixes(void) -{ - ReInitFrameCap(); - - if(dwActFixes & 0x2000) - dispWidths[4]=384; - else dispWidths[4]=368; -} - -//////////////////////////////////////////////////////////////////////// -// Pete Special: make an 'intelligent' dma chain check (<-Tekken3) -//////////////////////////////////////////////////////////////////////// - -uint32_t lUsedAddr[3]; - -static __inline BOOL CheckForEndlessLoop(uint32_t laddr) -{ - if(laddr==lUsedAddr[1]) return TRUE; - if(laddr==lUsedAddr[2]) return TRUE; - - if(laddr<lUsedAddr[0]) lUsedAddr[1]=laddr; - else lUsedAddr[2]=laddr; - lUsedAddr[0]=laddr; - return FALSE; -} - -//////////////////////////////////////////////////////////////////////// -// core gives a dma chain to gpu: same as the gpuwrite interface funcs -//////////////////////////////////////////////////////////////////////// - -long CALLBACK GPUdmaChain(uint32_t *baseAddrL, uint32_t addr) -{ - uint32_t dmaMem; - unsigned char * baseAddrB; - short count;unsigned int DMACommandCounter = 0; - - if(bIsFirstFrame) GLinitialize(); - - GPUIsBusy; - - lUsedAddr[0]=lUsedAddr[1]=lUsedAddr[2]=0xffffff; - - baseAddrB = (unsigned char*) baseAddrL; - - do - { - if(iGPUHeight==512) addr&=0x1FFFFC; - - if(DMACommandCounter++ > 2000000) break; - if(CheckForEndlessLoop(addr)) break; - - count = baseAddrB[addr+3]; - - dmaMem=addr+4; - - if(count>0) GPUwriteDataMem(&baseAddrL[dmaMem>>2],count); - - addr = baseAddrL[addr>>2]&0xffffff; - } - while (addr != 0xffffff); - - GPUIsIdle; - - return 0; -} - -//////////////////////////////////////////////////////////////////////// -// show about dlg -//////////////////////////////////////////////////////////////////////// - -void CALLBACK GPUabout(void) -{ -#ifdef _WINDOWS - HWND hWP=GetActiveWindow(); // to be sure - DialogBox(hInst,MAKEINTRESOURCE(IDD_DIALOG_ABOUT), - hWP,(DLGPROC)AboutDlgProc); -#elif defined(_MACGL) - - AboutDlgProc(); -#else - - StartCfgTool("ABOUT"); - -#endif -} - -//////////////////////////////////////////////////////////////////////// -// We are ever fine ;) -//////////////////////////////////////////////////////////////////////// - -long CALLBACK GPUtest(void) -{ - // if test fails this function should return negative value for error (unable to continue) - // and positive value for warning (can continue but output might be crappy) - - return 0; -} - -//////////////////////////////////////////////////////////////////////// -// save state funcs -//////////////////////////////////////////////////////////////////////// - -long CALLBACK GPUfreeze(uint32_t ulGetFreezeData,GPUFreeze_t * pF) -{ - if(ulGetFreezeData==2) - { - int lSlotNum=*((int *)pF); - if(lSlotNum<0) return 0; - if(lSlotNum>8) return 0; - lSelectedSlot=lSlotNum+1; - return 1; - } - - if(!pF) return 0; - if(pF->ulFreezeVersion!=1) return 0; - - if(ulGetFreezeData==1) - { - pF->ulStatus=STATUSREG; - memcpy(pF->ulControl,ulStatusControl,256*sizeof(uint32_t)); - memcpy(pF->psxVRam, psxVub, 1024*iGPUHeight*2); - - return 1; - } - - if(ulGetFreezeData!=0) return 0; - - STATUSREG=pF->ulStatus; - memcpy(ulStatusControl,pF->ulControl,256*sizeof(uint32_t)); - memcpy(psxVub, pF->psxVRam, 1024*iGPUHeight*2); - - ResetTextureArea(TRUE); - - GPUwriteStatus(ulStatusControl[0]); - GPUwriteStatus(ulStatusControl[1]); - GPUwriteStatus(ulStatusControl[2]); - GPUwriteStatus(ulStatusControl[3]); - GPUwriteStatus(ulStatusControl[8]); - GPUwriteStatus(ulStatusControl[6]); - GPUwriteStatus(ulStatusControl[7]); - GPUwriteStatus(ulStatusControl[5]); - GPUwriteStatus(ulStatusControl[4]); - - return 1; -} - -//////////////////////////////////////////////////////////////////////// -// special "emu infos" / "emu effects" functions -//////////////////////////////////////////////////////////////////////// - -//00 = black -//01 = white -//10 = red -//11 = transparent - -unsigned char cFont[10][120]= -{ -// 0 -{0xaa,0xaa,0xaa,0xaa,0xaa,0xaa, - 0x80,0x00,0x00,0x00,0x00,0x00, - 0x80,0x00,0x00,0x00,0x00,0x00, - 0x80,0x00,0x00,0x00,0x00,0x00, - 0x80,0x00,0x00,0x00,0x00,0x00, - 0x80,0x00,0x05,0x54,0x00,0x00, - 0x80,0x00,0x14,0x05,0x00,0x00, - 0x80,0x00,0x14,0x05,0x00,0x00, - 0x80,0x00,0x14,0x05,0x00,0x00, - 0x80,0x00,0x14,0x05,0x00,0x00, - 0x80,0x00,0x14,0x05,0x00,0x00, - 0x80,0x00,0x14,0x05,0x00,0x00, - 0x80,0x00,0x14,0x05,0x00,0x00, - 0x80,0x00,0x14,0x05,0x00,0x00, - 0x80,0x00,0x05,0x54,0x00,0x00, - 0x80,0x00,0x00,0x00,0x00,0x00, - 0x80,0x00,0x00,0x00,0x00,0x00, - 0x80,0x00,0x00,0x00,0x00,0x00, - 0x80,0x00,0x00,0x00,0x00,0x00, - 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa -}, -// 1 -{0xaa,0xaa,0xaa,0xaa,0xaa,0xaa, - 0x80,0x00,0x00,0x00,0x00,0x00, - 0x80,0x00,0x00,0x00,0x00,0x00, - 0x80,0x00,0x00,0x00,0x00,0x00, - 0x80,0x00,0x00,0x00,0x00,0x00, - 0x80,0x00,0x00,0x50,0x00,0x00, - 0x80,0x00,0x05,0x50,0x00,0x00, - 0x80,0x00,0x00,0x50,0x00,0x00, - 0x80,0x00,0x00,0x50,0x00,0x00, - 0x80,0x00,0x00,0x50,0x00,0x00, - 0x80,0x00,0x00,0x50,0x00,0x00, - 0x80,0x00,0x00,0x50,0x00,0x00, - 0x80,0x00,0x00,0x50,0x00,0x00, - 0x80,0x00,0x00,0x50,0x00,0x00, - 0x80,0x00,0x05,0x55,0x00,0x00, - 0x80,0x00,0x00,0x00,0x00,0x00, - 0x80,0x00,0x00,0x00,0x00,0x00, - 0x80,0x00,0x00,0x00,0x00,0x00, - 0x80,0x00,0x00,0x00,0x00,0x00, - 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa -}, -// 2 -{0xaa,0xaa,0xaa,0xaa,0xaa,0xaa, - 0x80,0x00,0x00,0x00,0x00,0x00, - 0x80,0x00,0x00,0x00,0x00,0x00, - 0x80,0x00,0x00,0x00,0x00,0x00, - 0x80,0x00,0x00,0x00,0x00,0x00, - 0x80,0x00,0x05,0x54,0x00,0x00, - 0x80,0x00,0x14,0x05,0x00,0x00, - 0x80,0x00,0x00,0x05,0x00,0x00, - 0x80,0x00,0x00,0x05,0x00,0x00, - 0x80,0x00,0x00,0x14,0x00,0x00, - 0x80,0x00,0x00,0x50,0x00,0x00, - 0x80,0x00,0x01,0x40,0x00,0x00, - 0x80,0x00,0x05,0x00,0x00,0x00, - 0x80,0x00,0x14,0x00,0x00,0x00, - 0x80,0x00,0x15,0x55,0x00,0x00, - 0x80,0x00,0x00,0x00,0x00,0x00, - 0x80,0x00,0x00,0x00,0x00,0x00, - 0x80,0x00,0x00,0x00,0x00,0x00, - 0x80,0x00,0x00,0x00,0x00,0x00, - 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa -}, -// 3 -{0xaa,0xaa,0xaa,0xaa,0xaa,0xaa, - 0x80,0x00,0x00,0x00,0x00,0x00, - 0x80,0x00,0x00,0x00,0x00,0x00, - 0x80,0x00,0x00,0x00,0x00,0x00, - 0x80,0x00,0x00,0x00,0x00,0x00, - 0x80,0x00,0x05,0x54,0x00,0x00, - 0x80,0x00,0x14,0x05,0x00,0x00, - 0x80,0x00,0x00,0x05,0x00,0x00, - 0x80,0x00,0x00,0x05,0x00,0x00, - 0x80,0x00,0x01,0x54,0x00,0x00, - 0x80,0x00,0x00,0x05,0x00,0x00, - 0x80,0x00,0x00,0x05,0x00,0x00, - 0x80,0x00,0x00,0x05,0x00,0x00, - 0x80,0x00,0x14,0x05,0x00,0x00, - 0x80,0x00,0x05,0x54,0x00,0x00, - 0x80,0x00,0x00,0x00,0x00,0x00, - 0x80,0x00,0x00,0x00,0x00,0x00, - 0x80,0x00,0x00,0x00,0x00,0x00, - 0x80,0x00,0x00,0x00,0x00,0x00, - 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa -}, -// 4 -{0xaa,0xaa,0xaa,0xaa,0xaa,0xaa, - 0x80,0x00,0x00,0x00,0x00,0x00, - 0x80,0x00,0x00,0x00,0x00,0x00, - 0x80,0x00,0x00,0x00,0x00,0x00, - 0x80,0x00,0x00,0x00,0x00,0x00, - 0x80,0x00,0x00,0x14,0x00,0x00, - 0x80,0x00,0x00,0x54,0x00,0x00, - 0x80,0x00,0x01,0x54,0x00,0x00, - 0x80,0x00,0x01,0x54,0x00,0x00, - 0x80,0x00,0x05,0x14,0x00,0x00, - 0x80,0x00,0x14,0x14,0x00,0x00, - 0x80,0x00,0x15,0x55,0x00,0x00, - 0x80,0x00,0x00,0x14,0x00,0x00, - 0x80,0x00,0x00,0x14,0x00,0x00, - 0x80,0x00,0x00,0x55,0x00,0x00, - 0x80,0x00,0x00,0x00,0x00,0x00, - 0x80,0x00,0x00,0x00,0x00,0x00, - 0x80,0x00,0x00,0x00,0x00,0x00, - 0x80,0x00,0x00,0x00,0x00,0x00, - 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa -}, -// 5 -{0xaa,0xaa,0xaa,0xaa,0xaa,0xaa, - 0x80,0x00,0x00,0x00,0x00,0x00, - 0x80,0x00,0x00,0x00,0x00,0x00, - 0x80,0x00,0x00,0x00,0x00,0x00, - 0x80,0x00,0x00,0x00,0x00,0x00, - 0x80,0x00,0x15,0x55,0x00,0x00, - 0x80,0x00,0x14,0x00,0x00,0x00, - 0x80,0x00,0x14,0x00,0x00,0x00, - 0x80,0x00,0x14,0x00,0x00,0x00, - 0x80,0x00,0x15,0x54,0x00,0x00, - 0x80,0x00,0x00,0x05,0x00,0x00, - 0x80,0x00,0x00,0x05,0x00,0x00, - 0x80,0x00,0x00,0x05,0x00,0x00, - 0x80,0x00,0x14,0x05,0x00,0x00, - 0x80,0x00,0x05,0x54,0x00,0x00, - 0x80,0x00,0x00,0x00,0x00,0x00, - 0x80,0x00,0x00,0x00,0x00,0x00, - 0x80,0x00,0x00,0x00,0x00,0x00, - 0x80,0x00,0x00,0x00,0x00,0x00, - 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa -}, -// 6 -{0xaa,0xaa,0xaa,0xaa,0xaa,0xaa, - 0x80,0x00,0x00,0x00,0x00,0x00, - 0x80,0x00,0x00,0x00,0x00,0x00, - 0x80,0x00,0x00,0x00,0x00,0x00, - 0x80,0x00,0x00,0x00,0x00,0x00, - 0x80,0x00,0x01,0x54,0x00,0x00, - 0x80,0x00,0x05,0x00,0x00,0x00, - 0x80,0x00,0x14,0x00,0x00,0x00, - 0x80,0x00,0x14,0x00,0x00,0x00, - 0x80,0x00,0x15,0x54,0x00,0x00, - 0x80,0x00,0x15,0x05,0x00,0x00, - 0x80,0x00,0x14,0x05,0x00,0x00, - 0x80,0x00,0x14,0x05,0x00,0x00, - 0x80,0x00,0x14,0x05,0x00,0x00, - 0x80,0x00,0x05,0x54,0x00,0x00, - 0x80,0x00,0x00,0x00,0x00,0x00, - 0x80,0x00,0x00,0x00,0x00,0x00, - 0x80,0x00,0x00,0x00,0x00,0x00, - 0x80,0x00,0x00,0x00,0x00,0x00, - 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa -}, -// 7 -{0xaa,0xaa,0xaa,0xaa,0xaa,0xaa, - 0x80,0x00,0x00,0x00,0x00,0x00, - 0x80,0x00,0x00,0x00,0x00,0x00, - 0x80,0x00,0x00,0x00,0x00,0x00, - 0x80,0x00,0x00,0x00,0x00,0x00, - 0x80,0x00,0x15,0x55,0x00,0x00, - 0x80,0x00,0x14,0x05,0x00,0x00, - 0x80,0x00,0x00,0x14,0x00,0x00, - 0x80,0x00,0x00,0x14,0x00,0x00, - 0x80,0x00,0x00,0x50,0x00,0x00, - 0x80,0x00,0x00,0x50,0x00,0x00, - 0x80,0x00,0x01,0x40,0x00,0x00, - 0x80,0x00,0x01,0x40,0x00,0x00, - 0x80,0x00,0x05,0x00,0x00,0x00, - 0x80,0x00,0x05,0x00,0x00,0x00, - 0x80,0x00,0x00,0x00,0x00,0x00, - 0x80,0x00,0x00,0x00,0x00,0x00, - 0x80,0x00,0x00,0x00,0x00,0x00, - 0x80,0x00,0x00,0x00,0x00,0x00, - 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa -}, -// 8 -{0xaa,0xaa,0xaa,0xaa,0xaa,0xaa, - 0x80,0x00,0x00,0x00,0x00,0x00, - 0x80,0x00,0x00,0x00,0x00,0x00, - 0x80,0x00,0x00,0x00,0x00,0x00, - 0x80,0x00,0x00,0x00,0x00,0x00, - 0x80,0x00,0x05,0x54,0x00,0x00, - 0x80,0x00,0x14,0x05,0x00,0x00, - 0x80,0x00,0x14,0x05,0x00,0x00, - 0x80,0x00,0x14,0x05,0x00,0x00, - 0x80,0x00,0x05,0x54,0x00,0x00, - 0x80,0x00,0x14,0x05,0x00,0x00, - 0x80,0x00,0x14,0x05,0x00,0x00, - 0x80,0x00,0x14,0x05,0x00,0x00, - 0x80,0x00,0x14,0x05,0x00,0x00, - 0x80,0x00,0x05,0x54,0x00,0x00, - 0x80,0x00,0x00,0x00,0x00,0x00, - 0x80,0x00,0x00,0x00,0x00,0x00, - 0x80,0x00,0x00,0x00,0x00,0x00, - 0x80,0x00,0x00,0x00,0x00,0x00, - 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa -}, -// 9 -{0xaa,0xaa,0xaa,0xaa,0xaa,0xaa, - 0x80,0x00,0x00,0x00,0x00,0x00, - 0x80,0x00,0x00,0x00,0x00,0x00, - 0x80,0x00,0x00,0x00,0x00,0x00, - 0x80,0x00,0x00,0x00,0x00,0x00, - 0x80,0x00,0x05,0x54,0x00,0x00, - 0x80,0x00,0x14,0x05,0x00,0x00, - 0x80,0x00,0x14,0x05,0x00,0x00, - 0x80,0x00,0x14,0x05,0x00,0x00, - 0x80,0x00,0x14,0x15,0x00,0x00, - 0x80,0x00,0x05,0x55,0x00,0x00, - 0x80,0x00,0x00,0x05,0x00,0x00, - 0x80,0x00,0x00,0x05,0x00,0x00, - 0x80,0x00,0x00,0x14,0x00,0x00, - 0x80,0x00,0x05,0x50,0x00,0x00, - 0x80,0x00,0x00,0x00,0x00,0x00, - 0x80,0x00,0x00,0x00,0x00,0x00, - 0x80,0x00,0x00,0x00,0x00,0x00, - 0x80,0x00,0x00,0x00,0x00,0x00, - 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa -} -}; - -//////////////////////////////////////////////////////////////////////// - -static void PaintPicDot(unsigned char * p,unsigned char c) -{ - if(c==0) {*p++=0x00;*p++=0x00;*p=0x00;return;} - if(c==1) {*p++=0xff;*p++=0xff;*p=0xff;return;} - if(c==2) {*p++=0x00;*p++=0x00;*p=0xff;return;} -} - -//////////////////////////////////////////////////////////////////////// - -long CALLBACK GPUgetScreenPic(unsigned char * pMem) -{ - float XS,YS;int x,y,v; - unsigned char * ps, * px, * pf; - unsigned char c; - - if(!pGfxCardScreen) - { - glPixelStorei(GL_PACK_ALIGNMENT,1); - pGfxCardScreen=(unsigned char *)malloc(iResX*iResY*4); - } - - ps=pGfxCardScreen; - - glReadBuffer(GL_FRONT); - - glReadPixels(0,0,iResX,iResY,GL_RGB,GL_UNSIGNED_BYTE,ps); - - glReadBuffer(GL_BACK); - - XS=(float)iResX/128; - YS=(float)iResY/96; - pf=pMem; - - for(y=96;y>0;y--) - { - for(x=0;x<128;x++) - { - px=ps+(3*((int)((float)x * XS))+ - (3*iResX)*((int)((float)y*YS))); - *(pf+0)=*(px+2); - *(pf+1)=*(px+1); - *(pf+2)=*(px+0); - pf+=3; - } - } - - ///////////////////////////////////////////////////////////////////// - // generic number/border painter - - pf=pMem+(103*3); - - for(y=0;y<20;y++) - { - for(x=0;x<6;x++) - { - c=cFont[lSelectedSlot][x+y*6]; - v=(c&0xc0)>>6; - PaintPicDot(pf,(unsigned char)v);pf+=3; // paint the dots into the rect - v=(c&0x30)>>4; - PaintPicDot(pf,(unsigned char)v);pf+=3; - v=(c&0x0c)>>2; - PaintPicDot(pf,(unsigned char)v);pf+=3; - v=c&0x03; - PaintPicDot(pf,(unsigned char)v);pf+=3; - } - pf+=104*3; - } - - pf=pMem; - for(x=0;x<128;x++) - { - *(pf+(95*128*3))=0x00;*pf++=0x00; - *(pf+(95*128*3))=0x00;*pf++=0x00; - *(pf+(95*128*3))=0xff;*pf++=0xff; - } - pf=pMem; - for(y=0;y<96;y++) - { - *(pf+(127*3))=0x00;*pf++=0x00; - *(pf+(127*3))=0x00;*pf++=0x00; - *(pf+(127*3))=0xff;*pf++=0xff; - pf+=127*3; - } - return 0; -} - -//////////////////////////////////////////////////////////////////////// - -long CALLBACK GPUshowScreenPic(unsigned char * pMem) -{ - DestroyPic(); - if(pMem==0) return 0; - CreatePic(pMem); - return 0; -} - -//////////////////////////////////////////////////////////////////////// - -#if 0 -void CALLBACK GPUsetfix(uint32_t dwFixBits) -{ - dwEmuFixes=dwFixBits; -} -#endif - -//////////////////////////////////////////////////////////////////////// - -void CALLBACK GPUvisualVibration(uint32_t iSmall, uint32_t iBig) -{ - int iVibVal; - - if(PSXDisplay.DisplayModeNew.x) // calc min "shake pixel" from screen width - iVibVal=max(1,iResX/PSXDisplay.DisplayModeNew.x); - else iVibVal=1; - // big rumble: 4...15 sp ; small rumble 1...3 sp - if(iBig) iRumbleVal=max(4*iVibVal,min(15*iVibVal,((int)iBig *iVibVal)/10)); - else iRumbleVal=max(1*iVibVal,min( 3*iVibVal,((int)iSmall*iVibVal)/10)); - - srand(timeGetTime()); // init rand (will be used in BufferSwap) - - iRumbleTime=15; // let the rumble last 16 buffer swaps -} - -//////////////////////////////////////////////////////////////////////// -// main emu can set display infos (A/M/G/D) -//////////////////////////////////////////////////////////////////////// - -#if 0 -void CALLBACK GPUdisplayFlags(uint32_t dwFlags) -{ - dwCoreFlags=dwFlags; -} -#endif - -void CALLBACK GPUvBlank( int val ) -{ - vBlank = val; -} +/***************************************************************************
+ gpu.c - description
+ -------------------
+ begin : Sun Mar 08 2009
+ copyright : (C) 1999-2009 by Pete Bernert
+ email : BlackDove@addcom.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. See also the license.txt file for *
+ * additional informations. *
+ * *
+ ***************************************************************************/
+
+// !!! enable this, if Linux XF86VidMode is not supported:
+//#define NOVMODE
+
+#include "stdafx.h"
+
+#if !defined(_MACGL) && !defined(_WINDOWS)
+
+#include "config.h"
+
+#ifndef NOVMODE
+#include <X11/extensions/xf86vmode.h>
+static XF86VidModeModeInfo **modes=0;
+static int iOldMode=0;
+#endif
+
+#endif
+
+#define _IN_GPU
+
+#include "externals.h"
+#include "gpu.h"
+#include "draw.h"
+#include "cfg.h"
+#include "prim.h"
+#include "psemu_plugin_defs.h"
+#include "texture.h"
+#include "menu.h"
+#include "fps.h"
+#include "key.h"
+#ifdef _WINDOWS
+#include "resource.h"
+#include "ssave.h"
+#endif
+#ifdef ENABLE_NLS
+#include <libintl.h>
+#include <locale.h>
+#define _(x) gettext(x)
+#define N_(x) (x)
+#else
+#define _(x) (x)
+#define N_(x) (x)
+#endif
+
+////////////////////////////////////////////////////////////////////////
+// PPDK developer must change libraryName field and can change revision and build
+////////////////////////////////////////////////////////////////////////
+
+const unsigned char version = 1; // do not touch - library for PSEmu 1.x
+const unsigned char revision = 1;
+const unsigned char build = 78;
+
+static char *libraryName = N_("OpenGL Driver");
+
+static char *PluginAuthor = N_("Pete Bernert");
+static char *libraryInfo = N_("Based on P.E.Op.S. MesaGL Driver V1.78\nCoded by Pete Bernert\n");
+
+////////////////////////////////////////////////////////////////////////
+// memory image of the PSX vram
+////////////////////////////////////////////////////////////////////////
+
+unsigned char *psxVSecure;
+unsigned char *psxVub;
+signed char *psxVsb;
+unsigned short *psxVuw;
+unsigned short *psxVuw_eom;
+signed short *psxVsw;
+uint32_t *psxVul;
+signed int *psxVsl;
+
+// macro for easy access to packet information
+#define GPUCOMMAND(x) ((x>>24) & 0xff)
+
+GLfloat gl_z=0.0f;
+BOOL bNeedInterlaceUpdate=FALSE;
+BOOL bNeedRGB24Update=FALSE;
+BOOL bChangeWinMode=FALSE;
+
+#ifdef _WINDOWS
+extern HGLRC GLCONTEXT;
+#endif
+
+uint32_t ulStatusControl[256];
+
+////////////////////////////////////////////////////////////////////////
+// global GPU vars
+////////////////////////////////////////////////////////////////////////
+
+static int GPUdataRet;
+int lGPUstatusRet;
+char szDispBuf[64];
+
+uint32_t dwGPUVersion = 0;
+int iGPUHeight = 512;
+int iGPUHeightMask = 511;
+int GlobalTextIL = 0;
+int iTileCheat = 0;
+
+static uint32_t gpuDataM[256];
+static unsigned char gpuCommand = 0;
+static int gpuDataC = 0;
+static int gpuDataP = 0;
+
+VRAMLoad_t VRAMWrite;
+VRAMLoad_t VRAMRead;
+int iDataWriteMode;
+int iDataReadMode;
+
+int lClearOnSwap;
+int lClearOnSwapColor;
+BOOL bSkipNextFrame = FALSE;
+int iColDepth;
+BOOL bChangeRes;
+BOOL bWindowMode;
+int iWinSize;
+
+// possible psx display widths
+short dispWidths[8] = {256,320,512,640,368,384,512,640};
+
+PSXDisplay_t PSXDisplay;
+PSXDisplay_t PreviousPSXDisplay;
+TWin_t TWin;
+short imageX0,imageX1;
+short imageY0,imageY1;
+BOOL bDisplayNotSet = TRUE;
+GLuint uiScanLine=0;
+int iUseScanLines=0;
+float iScanlineColor[] = {0,0,0, 0.3}; // easy on the eyes.
+int lSelectedSlot=0;
+unsigned char * pGfxCardScreen=0;
+int iBlurBuffer=0;
+int iScanBlend=0;
+int iRenderFVR=0;
+int iNoScreenSaver=0;
+uint32_t ulGPUInfoVals[16];
+int iFakePrimBusy = 0;
+int iRumbleVal = 0;
+int iRumbleTime = 0;
+uint32_t vBlank=0;
+
+////////////////////////////////////////////////////////////////////////
+// stuff to make this a true PDK module
+////////////////////////////////////////////////////////////////////////
+
+char * CALLBACK PSEgetLibName(void)
+{
+ return _(libraryName);
+}
+
+unsigned long CALLBACK PSEgetLibType(void)
+{
+ return PSE_LT_GPU;
+}
+
+unsigned long CALLBACK PSEgetLibVersion(void)
+{
+ return version<<16|revision<<8|build;
+}
+
+char * GPUgetLibInfos(void)
+{
+ return _(libraryInfo);
+}
+
+////////////////////////////////////////////////////////////////////////
+// snapshot funcs (saves screen to bitmap / text infos into file)
+////////////////////////////////////////////////////////////////////////
+
+#ifdef _WINDOWS
+char * GetConfigInfos(HWND hW)
+#else
+char * GetConfigInfos(int hW)
+#endif
+{
+#ifdef _WINDOWS
+ HDC hdc;HGLRC hglrc;
+#endif
+ char szO[2][4]={"off","on "};
+ char szTxt[256];
+ char * pB=(char *)malloc(32767);
+
+ if(!pB) return NULL;
+ *pB=0;
+ //----------------------------------------------------//
+ sprintf(szTxt,"Plugin: %s %d.%d.%d (mod)\r\n",libraryName,version,revision,build);
+ strcat(pB,szTxt);
+ sprintf(szTxt,"Author: %s\r\n",PluginAuthor);
+ strcat(pB,szTxt);
+
+#ifdef _WINDOWS
+ if(hW)
+ {
+ hdc = GetDC(hW);
+ bSetupPixelFormat(hdc);
+ hglrc = wglCreateContext(hdc);
+ wglMakeCurrent(hdc, hglrc);
+ }
+#endif
+
+ sprintf(szTxt,"Card vendor: %s\r\n",(char *)glGetString(GL_VENDOR));
+ strcat(pB,szTxt);
+ sprintf(szTxt,"GFX card: %s\r\n",(char *)glGetString(GL_RENDERER));
+ strcat(pB,szTxt);
+ sprintf(szTxt,"OGL version: %s\r\n\r\n",(char *)glGetString(GL_VERSION));
+ strcat(pB,szTxt);
+ //strcat(pB,(char *)glGetString(GL_EXTENSIONS));
+ //strcat(pB,"\r\n\r\n");
+
+#ifdef _WINDOWS
+ if(hW)
+ {
+ wglMakeCurrent(NULL, NULL);
+ wglDeleteContext(hglrc);
+ ReleaseDC(hW,hdc);
+ }
+ //----------------------------------------------------//
+#endif
+
+ if(hW && bWindowMode)
+ sprintf(szTxt,"Resolution/Color:\r\n- %dx%d ",LOWORD(iWinSize),HIWORD(iWinSize));
+ else
+ sprintf(szTxt,"Resolution/Color:\r\n- %dx%d ",iResX,iResY);
+ strcat(pB,szTxt);
+ if(bWindowMode) sprintf(szTxt,"Window mode\r\n");
+ else
+ {
+ sprintf(szTxt,"Fullscreen ");
+ strcat(pB,szTxt);
+ if(bChangeRes) sprintf(szTxt,"- Desktop changing [%d Bit]\r\n",iColDepth);
+ else sprintf(szTxt,"- NO desktop changing\r\n");
+ }
+ strcat(pB,szTxt);
+
+ if(iForceVSync>=0) sprintf(szTxt,"- V-Sync: %s\r\n",szO[iForceVSync]);
+ else strcpy(szTxt,"- V-Sync: Driver\r\n");
+ strcat(pB,szTxt);
+ sprintf(szTxt,"- Keep psx aspect ratio: %s\r\n\r\n",szO[bKeepRatio]);
+ strcat(pB,szTxt);
+ //----------------------------------------------------//
+ strcpy(szTxt,"Textures:\r\n- ");
+ if(iTexQuality==0) strcat(szTxt,"Default");
+ else if(iTexQuality==1) strcat(szTxt,"R4G4B4A4");
+ else if(iTexQuality==2) strcat(szTxt,"R5G5B5A1");
+ else if(iTexQuality==3) strcat(szTxt,"R8G8A8A8");
+ else if(iTexQuality==4) strcat(szTxt,"B8G8R8A8");
+ if(!hW && bGLExt) strcat(szTxt," (packed pixels)\r\n");
+ else strcat(szTxt,"\r\n");
+ strcat(pB,szTxt);
+ if(!hW)
+ {
+ sprintf(szTxt,"- Filtering: %d - edge clamping ",iFilterType);
+ if(iClampType==GL_TO_EDGE_CLAMP) strcat(szTxt,"supported\r\n");
+ else strcat(szTxt,"NOT supported\r\n");
+ }
+ else sprintf(szTxt,"- iFiltering: %d\r\n",iFilterType);
+ strcat(pB,szTxt);
+ sprintf(szTxt,"- Hi-Res textures: %d\r\n",iHiResTextures);
+ strcat(pB,szTxt);
+ if(!hW)
+ {
+ sprintf(szTxt,"- Palettized tex windows: %s\r\n",szO[iUsePalTextures]);
+ strcat(pB,szTxt);
+ }
+ sprintf(szTxt,"- VRam size: %d MBytes",iVRamSize);
+ if(!hW)
+ sprintf(szTxt+strlen(szTxt)," - %d textures usable\r\n\r\n",iSortTexCnt);
+ else strcat(szTxt,"\r\n\r\n");
+ strcat(pB,szTxt);
+ //----------------------------------------------------//
+ sprintf(szTxt,"Framerate:\r\n- FPS limitation: %s\r\n",szO[bUseFrameLimit]);
+ strcat(pB,szTxt);
+ sprintf(szTxt,"- Frame skipping: %s\r\n",szO[bUseFrameSkip]);
+ strcat(pB,szTxt);
+ if(iFrameLimit==2)
+ strcpy(szTxt,"- FPS limit: Auto\r\n\r\n");
+ else sprintf(szTxt,"- FPS limit: %.1f\r\n\r\n",fFrameRate);
+ strcat(pB,szTxt);
+ //----------------------------------------------------//
+ sprintf(szTxt,"Compatibility:\r\n- Offscreen drawing: %d\r\n",iOffscreenDrawing);
+ strcat(pB,szTxt);
+ sprintf(szTxt,"- Framebuffer texture: %d",iFrameTexType);
+ if(!hW && iFrameTexType==2)
+ {
+ if(gTexFrameName) strcat(szTxt," - texture created\r\n");
+ else strcat(szTxt," - not used yet\r\n");
+ }
+ else strcat(szTxt,"\r\n");
+ strcat(pB,szTxt);
+ sprintf(szTxt,"- Framebuffer access: %d\r\n",iFrameReadType);
+ strcat(pB,szTxt);
+ sprintf(szTxt,"- Alpha multipass: %s\r\n",szO[bOpaquePass]);
+ strcat(pB,szTxt);
+ sprintf(szTxt,"- Mask bit: %s\r\n",szO[iUseMask]);
+ strcat(pB,szTxt);
+ sprintf(szTxt,"- Advanced blending: %s",szO[bAdvancedBlend]);
+ if(!hW && bAdvancedBlend)
+ {
+ if(bGLBlend) strcat(szTxt," (hardware)\r\n");
+ else strcat(szTxt," (software)\r\n");
+ }
+ else strcat(szTxt,"\r\n");
+ strcat(pB,szTxt);
+
+ if(!hW)
+ {
+ strcpy(szTxt,"- Subtractive blending: ");
+ if(glBlendEquationEXTEx)
+ {
+ if(bUseMultiPass) strcat(szTxt,"supported, but not used!");
+ else strcat(szTxt,"activated");
+ }
+ else strcat(szTxt," NOT supported!");
+ strcat(szTxt,"\r\n\r\n");
+ }
+ else strcpy(szTxt,"\r\n");
+
+ strcat(pB,szTxt);
+ //----------------------------------------------------//
+ sprintf(szTxt,"Misc:\r\n- Scanlines: %s",szO[iUseScanLines]);
+ strcat(pB,szTxt);
+ if(iUseScanLines) sprintf(szTxt," [%d]\r\n",iScanBlend);
+ else strcpy(szTxt,"\r\n");
+ strcat(pB,szTxt);
+ sprintf(szTxt,"- Line mode: %s\r\n",szO[bUseLines]);
+ strcat(pB,szTxt);
+// sprintf(szTxt,"- Line AA: %s\r\n",szO[bUseAntiAlias]);
+// fwrite(szTxt,lstrlen(szTxt),1,txtfile);
+ sprintf(szTxt,"- Unfiltered FB: %s\r\n",szO[bUseFastMdec]);
+ strcat(pB,szTxt);
+ sprintf(szTxt,"- 15 bit FB: %s\r\n",szO[bUse15bitMdec]);
+ strcat(pB,szTxt);
+ sprintf(szTxt,"- Dithering: %s\r\n",szO[bDrawDither]);
+ strcat(pB,szTxt);
+ sprintf(szTxt,"- Screen smoothing: %s",szO[iBlurBuffer]);
+ strcat(pB,szTxt);
+ if(!hW && iBlurBuffer)
+ {
+ if(gTexBlurName) strcat(pB," - supported\r\n");
+ else strcat(pB," - not supported\r\n");
+ }
+ else strcat(pB,"\r\n");
+ sprintf(szTxt,"- Game fixes: %s [%08x]\r\n",szO[bUseFixes],dwCfgFixes);
+ strcat(pB,szTxt);
+ //----------------------------------------------------//
+ return pB;
+}
+
+////////////////////////////////////////////////////////////////////////
+// save text infos to file
+////////////////////////////////////////////////////////////////////////
+
+void DoTextSnapShot(int iNum)
+{
+ FILE *txtfile;char szTxt[256];char * pB;
+
+#ifdef _WINDOWS
+ sprintf(szTxt,"snap\\pcsx%04d.txt",iNum);
+#else
+ sprintf(szTxt,"%s/pcsx%04d.txt",getenv("HOME"),iNum);
+#endif
+
+ if((txtfile=fopen(szTxt,"wb"))==NULL)
+ return;
+
+ pB=GetConfigInfos(0);
+ if(pB)
+ {
+ fwrite(pB,strlen(pB),1,txtfile);
+ free(pB);
+ }
+ fclose(txtfile);
+}
+
+////////////////////////////////////////////////////////////////////////
+// saves screen bitmap to file
+////////////////////////////////////////////////////////////////////////
+
+void DoSnapShot(void)
+{
+ unsigned char * snapshotdumpmem=NULL,* p,c;
+ FILE *bmpfile;char filename[256];
+ unsigned char header[0x36];int size;
+ unsigned char empty[2]={0,0};int i;
+ unsigned int snapshotnr = 0;
+ short SnapWidth;
+ short SnapHeigth;
+
+ bSnapShot=FALSE;
+
+ SnapWidth = iResX;
+ SnapHeigth = iResY;
+
+ size=SnapWidth * SnapHeigth * 3 + 0x38;
+
+ if((snapshotdumpmem=(unsigned char *)
+ malloc(SnapWidth*SnapHeigth*3))==NULL)
+ return;
+
+ // fill in proper values for BMP
+ for(i=0;i<0x36;i++) header[i]=0;
+ header[0]='B';
+ header[1]='M';
+ header[2]=(unsigned char)(size&0xff);
+ header[3]=(unsigned char)((size>>8)&0xff);
+ header[4]=(unsigned char)((size>>16)&0xff);
+ header[5]=(unsigned char)((size>>24)&0xff);
+ header[0x0a]=0x36;
+ header[0x0e]=0x28;
+ header[0x12]=(unsigned char)(SnapWidth%256);
+ header[0x13]=(unsigned char)(SnapWidth/256);
+ header[0x16]=(unsigned char)(SnapHeigth%256);
+ header[0x17]=(unsigned char)(SnapHeigth/256);
+ header[0x1a]=0x01;
+ header[0x1c]=0x18;
+ header[0x26]=0x12;
+ header[0x27]=0x0B;
+ header[0x2A]=0x12;
+ header[0x2B]=0x0B;
+
+ // increment snapshot value
+ // get filename
+ do
+ {
+ snapshotnr++;
+#ifdef _WINDOWS
+ sprintf(filename,"snap/pcsx%04d.bmp",snapshotnr);
+#else
+ sprintf(filename,"%s/pcsx%04d.bmp",getenv("HOME"),snapshotnr);
+#endif
+ bmpfile=fopen(filename,"rb");
+ if(bmpfile==NULL)break;
+ fclose(bmpfile);
+ if(snapshotnr==9999) break;
+ }
+ while(TRUE);
+
+ // try opening new snapshot file
+ if((bmpfile=fopen(filename,"wb"))==NULL)
+ {free(snapshotdumpmem);return;}
+
+ fwrite(header,0x36,1,bmpfile);
+
+ glReadPixels(0,0,SnapWidth,SnapHeigth,GL_RGB,
+ GL_UNSIGNED_BYTE,snapshotdumpmem);
+ p=snapshotdumpmem;
+ size=SnapWidth * SnapHeigth;
+
+ for(i=0;i<size;i++,p+=3)
+ {c=*p;*p=*(p+2);*(p+2)=c;}
+
+ fwrite(snapshotdumpmem,size*3,1,bmpfile);
+ fwrite(empty,0x2,1,bmpfile);
+ fclose(bmpfile);
+ free(snapshotdumpmem);
+
+ DoTextSnapShot(snapshotnr);
+#ifdef _WINDOWS
+ MessageBeep((UINT)-1);
+#endif
+}
+
+void CALLBACK GPUmakeSnapshot(void)
+{
+ bSnapShot = TRUE;
+}
+
+////////////////////////////////////////////////////////////////////////
+// GPU INIT... here starts it all (first func called by emu)
+////////////////////////////////////////////////////////////////////////
+
+long CALLBACK GPUinit()
+{
+ memset(ulStatusControl,0,256*sizeof(uint32_t));
+
+ // different ways of accessing PSX VRAM
+
+ psxVSecure=(unsigned char *)malloc((iGPUHeight*2)*1024 + (1024*1024)); // always alloc one extra MB for soft drawing funcs security
+ if(!psxVSecure) return -1;
+
+ psxVub=psxVSecure+512*1024; // security offset into double sized psx vram!
+ psxVsb=(signed char *)psxVub;
+ psxVsw=(signed short *)psxVub;
+ psxVsl=(signed int *)psxVub;
+ psxVuw=(unsigned short *)psxVub;
+ psxVul=(uint32_t *)psxVub;
+
+ psxVuw_eom=psxVuw+1024*iGPUHeight; // pre-calc of end of vram
+
+ memset(psxVSecure,0x00,(iGPUHeight*2)*1024 + (1024*1024));
+ memset(ulGPUInfoVals,0x00,16*sizeof(uint32_t));
+
+ InitFrameCap(); // init frame rate stuff
+
+ PSXDisplay.RGB24 = 0; // init vars
+ PreviousPSXDisplay.RGB24= 0;
+ PSXDisplay.Interlaced = 0;
+ PSXDisplay.InterlacedTest=0;
+ PSXDisplay.DrawOffset.x = 0;
+ PSXDisplay.DrawOffset.y = 0;
+ PSXDisplay.DrawArea.x0 = 0;
+ PSXDisplay.DrawArea.y0 = 0;
+ PSXDisplay.DrawArea.x1 = 320;
+ PSXDisplay.DrawArea.y1 = 240;
+ PSXDisplay.DisplayMode.x= 320;
+ PSXDisplay.DisplayMode.y= 240;
+ PSXDisplay.Disabled = FALSE;
+ PreviousPSXDisplay.Range.x0 =0;
+ PreviousPSXDisplay.Range.x1 =0;
+ PreviousPSXDisplay.Range.y0 =0;
+ PreviousPSXDisplay.Range.y1 =0;
+ PSXDisplay.Range.x0=0;
+ PSXDisplay.Range.x1=0;
+ PSXDisplay.Range.y0=0;
+ PSXDisplay.Range.y1=0;
+ PreviousPSXDisplay.DisplayPosition.x = 1;
+ PreviousPSXDisplay.DisplayPosition.y = 1;
+ PSXDisplay.DisplayPosition.x = 1;
+ PSXDisplay.DisplayPosition.y = 1;
+ PreviousPSXDisplay.DisplayModeNew.y=0;
+ PSXDisplay.Double=1;
+ GPUdataRet=0x400;
+
+ PSXDisplay.DisplayModeNew.x=0;
+ PSXDisplay.DisplayModeNew.y=0;
+
+ //PreviousPSXDisplay.Height = PSXDisplay.Height = 239;
+
+ iDataWriteMode = DR_NORMAL;
+
+ // Reset transfer values, to prevent mis-transfer of data
+ memset(&VRAMWrite,0,sizeof(VRAMLoad_t));
+ memset(&VRAMRead,0,sizeof(VRAMLoad_t));
+
+ // device initialised already !
+ //lGPUstatusRet = 0x74000000;
+ vBlank = 0;
+
+ STATUSREG = 0x14802000;
+ GPUIsIdle;
+ GPUIsReadyForCommands;
+
+ return 0;
+}
+
+////////////////////////////////////////////////////////////////////////
+// GPU OPEN: funcs to open up the gpu display (Windows)
+////////////////////////////////////////////////////////////////////////
+
+#ifdef _WINDOWS
+
+void ChangeDesktop() // change destop resolution
+{
+ DEVMODE dv;long lRes,iTry=0;
+
+ while(iTry<10) // keep on hammering...
+ {
+ memset(&dv,0,sizeof(DEVMODE));
+ dv.dmSize=sizeof(DEVMODE);
+ dv.dmBitsPerPel=iColDepth;
+ dv.dmPelsWidth=iResX;
+ dv.dmPelsHeight=iResY;
+
+ dv.dmFields=DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT;
+
+ lRes=ChangeDisplaySettings(&dv,0); // ...hammering the anvil
+
+ if(lRes==DISP_CHANGE_SUCCESSFUL) return;
+ iTry++;Sleep(10);
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+// OPEN interface func: attention!
+// some emus are calling this func in their main Window thread,
+// but all other interface funcs (to draw stuff) in a different thread!
+// that's a problem, since OGL is thread safe! Therefore we cannot
+// initialize the OGL stuff right here, we simply set a "bIsFirstFrame = TRUE"
+// flag, to initialize OGL on the first real draw call.
+// btw, we also call this open func ourselfes, each time when the user
+// is changing between fullscreen/window mode (ENTER key)
+// btw part 2: in windows the plugin gets the window handle from the
+// main emu, and doesn't create it's own window (if it would do it,
+// some PAD or SPU plugins would not work anymore)
+////////////////////////////////////////////////////////////////////////
+
+HMENU hPSEMenu=NULL;
+
+long CALLBACK GPUopen(HWND hwndGPU)
+{
+ HDC hdc;RECT r;DEVMODE dv;
+
+ hWWindow = hwndGPU; // store hwnd globally
+
+ InitKeyHandler(); // init key handler (subclass window)
+
+ if(bChangeWinMode) // user wants to change fullscreen/window mode?
+ {
+ ReadWinSizeConfig(); // -> get sizes again
+ }
+ else // first real startup
+ {
+ ReadConfig(); // -> read config from registry
+
+ SetFrameRateConfig(); // -> setup frame rate stuff
+ }
+
+ if(iNoScreenSaver) EnableScreenSaver(FALSE); // at least we can try
+
+
+ memset(&dv,0,sizeof(DEVMODE));
+ dv.dmSize=sizeof(DEVMODE);
+ EnumDisplaySettings(NULL,ENUM_CURRENT_SETTINGS,&dv);
+
+ bIsFirstFrame = TRUE; // flag: we have to init OGL later in windows!
+
+ if(bWindowMode) // win mode?
+ {
+ DWORD dw=GetWindowLong(hWWindow, GWL_STYLE); // -> adjust wnd style (owndc needed by some stupid ogl drivers)
+ dw&=~WS_THICKFRAME;
+ dw|=WS_BORDER|WS_CAPTION|CS_OWNDC;
+ SetWindowLong(hWWindow, GWL_STYLE, dw);
+
+ hPSEMenu=GetMenu(hWWindow); // -> hide emu menu (if any)
+ if(hPSEMenu!=NULL) SetMenu(hWWindow,NULL);
+
+ iResX=LOWORD(iWinSize);iResY=HIWORD(iWinSize);
+ ShowWindow(hWWindow,SW_SHOWNORMAL);
+
+ MoveWindow(hWWindow, // -> center wnd
+ GetSystemMetrics(SM_CXFULLSCREEN)/2-iResX/2,
+ GetSystemMetrics(SM_CYFULLSCREEN)/2-iResY/2,
+ iResX+GetSystemMetrics(SM_CXFIXEDFRAME)+3,
+ iResY+GetSystemMetrics(SM_CYFIXEDFRAME)+GetSystemMetrics(SM_CYCAPTION)+3,
+ TRUE);
+ UpdateWindow(hWWindow); // -> let windows do some update
+
+ if(dv.dmBitsPerPel==16 || dv.dmBitsPerPel==32) // -> overwrite user color info with desktop color info
+ iColDepth=dv.dmBitsPerPel;
+ }
+ else // fullscreen mode:
+ {
+ if(dv.dmBitsPerPel!=(unsigned int)iColDepth || // -> check, if we have to change resolution
+ dv.dmPelsWidth !=(unsigned int)iResX ||
+ dv.dmPelsHeight!=(unsigned int)iResY)
+ bChangeRes=TRUE; else bChangeRes=FALSE;
+
+ if(bChangeRes) ChangeDesktop(); // -> change the res (had to do an own func because of some MS 'optimizations')
+
+ SetWindowLong(hWWindow, GWL_STYLE, CS_OWNDC); // -> adjust wnd style as well (to be sure)
+
+ hPSEMenu=GetMenu(hWWindow); // -> hide menu
+ if(hPSEMenu!=NULL) SetMenu(hWWindow,NULL);
+ ShowWindow(hWWindow,SW_SHOWMAXIMIZED); // -> max mode
+ }
+
+ rRatioRect.left = rRatioRect.top=0;
+ rRatioRect.right = iResX;
+ rRatioRect.bottom = iResY;
+
+ r.left=r.top=0;r.right=iResX;r.bottom=iResY; // hack for getting a clean black window until OGL gets initialized
+ hdc = GetDC(hWWindow);
+ FillRect(hdc,&r,(HBRUSH)GetStockObject(BLACK_BRUSH));
+ bSetupPixelFormat(hdc);
+ ReleaseDC(hWWindow,hdc);
+
+ bDisplayNotSet = TRUE;
+ bSetClip=TRUE;
+
+ SetFixes(); // setup game fixes
+
+ InitializeTextureStore(); // init texture mem
+
+// lGPUstatusRet = 0x74000000;
+
+// with some emus, we could do the OGL init right here... oh my
+// if(bIsFirstFrame) GLinitialize();
+
+ return 0;
+}
+
+#elif !defined (_MACGL)
+
+////////////////////////////////////////////////////////////////////////
+// LINUX GPU OPEN: func to open up the gpu display (X stuff)
+// please note: in linux we are creating our own display, and we return
+// the display ID to the main emu... that's cleaner
+////////////////////////////////////////////////////////////////////////
+
+char * pCaptionText=0;
+int bFullScreen=0;
+Display *display;
+
+static Cursor cursor;
+static XVisualInfo *myvisual;
+static Colormap colormap;
+static Window window;
+
+static int bModeChanged=0;
+
+typedef struct
+{
+#define MWM_HINTS_DECORATIONS 2
+ long flags;
+ long functions;
+ long decorations;
+ long input_mode;
+} MotifWmHints;
+
+static int dbdepat[]={GLX_RGBA,GLX_DOUBLEBUFFER,GLX_DEPTH_SIZE,16,None};
+static int dbnodepat[]={GLX_RGBA,GLX_DOUBLEBUFFER,None};
+static GLXContext cx;
+
+static int fx=0;
+
+////////////////////////////////////////////////////////////////////////
+
+void osd_close_display (void) // close display
+{
+ if(display) // display exists?
+ {
+ glXDestroyContext(display,cx); // -> kill context
+ XFreeColormap(display, colormap); // -> kill colormap
+ XSync(display,False); // -> sync events
+
+#ifndef NOVMODE
+ if(bModeChanged) // -> repair screen mode
+ {
+ int myscreen=DefaultScreen(display);
+ XF86VidModeSwitchToMode(display,myscreen, // --> switch mode back
+ modes[iOldMode]);
+ XF86VidModeSetViewPort(display,myscreen,0,0); // --> set viewport upperleft
+ free(modes); // --> finally kill mode infos
+ bModeChanged=0; // --> done
+ }
+#endif
+
+ XCloseDisplay(display); // -> close display
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void sysdep_create_display(void) // create display
+{
+ XSetWindowAttributes winattr;float fxgamma=2;
+ int myscreen;char gammastr[14];
+ Screen * screen;XEvent event;
+ XSizeHints hints;XWMHints wm_hints;
+ MotifWmHints mwmhints;Atom mwmatom;Atom delwindow;
+ char *glxfx;
+
+ glxfx=getenv("MESA_GLX_FX"); // 3dfx mesa fullscreen flag
+ if(glxfx)
+ {
+ if(glxfx[0]=='f') // -> yup, fullscreen needed
+ {
+ fx=1; // -> raise flag
+ putenv("FX_GLIDE_NO_SPLASH=");
+ sprintf(gammastr,"SST_GAMMA=%2.1f",fxgamma); // -> set gamma
+ putenv(gammastr);
+ }
+ }
+
+ display=XOpenDisplay(NULL); // open display
+ if(!display) // no display?
+ {
+ fprintf (stderr,"Failed to open display!!!\n");
+ osd_close_display();
+ return; // -> bye
+ }
+
+ myscreen=DefaultScreen(display); // get screen id
+
+#ifdef NOVMODE
+ if(bFullScreen) {fx=1;bModeChanged=0;}
+#else
+ if(bFullScreen)
+ {
+ XF86VidModeModeLine mode;
+ int nmodes,iC;
+ fx=1; // raise flag
+ XF86VidModeGetModeLine(display,myscreen,&iC,&mode); // get actual mode info
+ if(mode.privsize) XFree(mode.private); // no need for private stuff
+ bModeChanged=0; // init mode change flag
+ if(iResX!=mode.hdisplay || iResY!=mode.vdisplay) // wanted mode is different?
+ {
+ XF86VidModeGetAllModeLines(display,myscreen, // -> enum all mode infos
+ &nmodes,&modes);
+ if(modes) // -> infos got?
+ {
+ for(iC=0;iC<nmodes;++iC) // -> loop modes
+ {
+ if(mode.hdisplay==modes[iC]->hdisplay && // -> act mode found?
+ mode.vdisplay==modes[iC]->vdisplay) // if yes: store mode id
+ iOldMode=iC;
+
+ if(iResX==modes[iC]->hdisplay && // -> wanted mode found?
+ iResY==modes[iC]->vdisplay)
+ {
+ XF86VidModeSwitchToMode(display,myscreen, // --> switch to mode
+ modes[iC]);
+ XF86VidModeSetViewPort(display,myscreen,0,0);
+ bModeChanged=1; // --> raise flag for repairing mode on close
+ }
+ }
+
+ if(bModeChanged==0) // -> no mode found?
+ {
+ free(modes); // --> free infos
+ printf("No proper fullscreen mode found!\n"); // --> some info output
+ }
+ }
+ }
+ }
+#endif
+
+ screen=DefaultScreenOfDisplay(display);
+
+ if(iZBufferDepth) // visual (with or without zbuffer)
+ myvisual=glXChooseVisual(display,myscreen,dbdepat);
+ else myvisual=glXChooseVisual(display,myscreen,dbnodepat);
+
+ if(!myvisual) // no visual?
+ {
+ fprintf(stderr,"Failed to obtain visual!!!\n"); // -> bye
+ osd_close_display();
+ return;
+ }
+
+ cx=glXCreateContext(display,myvisual,0,GL_TRUE); // create rendering context
+
+ if(!cx) // no context?
+ {
+ fprintf(stderr,"Failed to create OpenGL context!!!\n");
+ osd_close_display(); // -> bxe
+ return;
+ }
+
+ // pffff... much work for a simple blank cursor... oh, well...
+ if(!bFullScreen) cursor=XCreateFontCursor(display,XC_trek);
+ else
+ {
+ Pixmap p1,p2;XImage * img;
+ XColor b,w;unsigned char * idata;
+ XGCValues GCv;
+ GC GCc;
+
+ memset(&b,0,sizeof(XColor));
+ memset(&w,0,sizeof(XColor));
+ idata=(unsigned char *)malloc(8);
+ memset(idata,0,8);
+
+ p1=XCreatePixmap(display,RootWindow(display,myvisual->screen),8,8,1);
+ p2=XCreatePixmap(display,RootWindow(display,myvisual->screen),8,8,1);
+
+ img = XCreateImage(display,myvisual->visual,
+ 1,XYBitmap,0,idata,8,8,8,1);
+
+ GCv.function = GXcopy;
+ GCv.foreground = ~0;
+ GCv.background = 0;
+ GCv.plane_mask = AllPlanes;
+ GCc = XCreateGC(display,p1,
+ (GCFunction|GCForeground|GCBackground|GCPlaneMask),&GCv);
+
+ XPutImage(display, p1,GCc,img,0,0,0,0,8,8);
+ XPutImage(display, p2,GCc,img,0,0,0,0,8,8);
+ XFreeGC(display, GCc);
+
+ cursor = XCreatePixmapCursor(display,p1,p2,&b,&w,0,0);
+
+ XFreePixmap(display,p1);
+ XFreePixmap(display,p2);
+ XDestroyImage(img); // will free idata as well
+ }
+
+ colormap=XCreateColormap(display, // create colormap
+ RootWindow(display,myvisual->screen),
+ myvisual->visual,AllocNone);
+
+ winattr.background_pixel=0;
+ winattr.border_pixel=WhitePixelOfScreen(screen);
+ winattr.bit_gravity=ForgetGravity;
+ winattr.win_gravity=NorthWestGravity;
+ winattr.backing_store=NotUseful;
+ winattr.override_redirect=False;
+ winattr.save_under=False;
+ winattr.event_mask=0;
+ winattr.do_not_propagate_mask=0;
+ winattr.colormap=colormap;
+ winattr.cursor=None;
+
+ window=XCreateWindow(display, // create own window
+ RootWindow(display,DefaultScreen(display)),
+ 0,0,iResX,iResY,
+ 0,myvisual->depth,
+ InputOutput,myvisual->visual,
+ CWBorderPixel | CWBackPixel |
+ CWEventMask | CWDontPropagate |
+ CWColormap | CWCursor,
+ &winattr);
+
+ if(!window) // no window?
+ {
+ fprintf(stderr,"Failed in XCreateWindow()!!!\n");
+ osd_close_display(); // -> bye
+ return;
+ }
+
+ delwindow = XInternAtom(display,"WM_DELETE_WINDOW",0);
+ XSetWMProtocols(display, window, &delwindow, 1);
+
+ hints.flags=PMinSize|PMaxSize; // hints
+ if(fx) hints.flags|=USPosition|USSize;
+ else hints.flags|=PSize;
+
+ hints.min_width = hints.max_width = hints.base_width = iResX;
+ hints.min_height = hints.max_height = hints.base_height = iResY;
+
+ wm_hints.input=1;
+ wm_hints.flags=InputHint;
+
+ XSetWMHints(display,window,&wm_hints);
+ XSetWMNormalHints(display,window,&hints);
+ if(pCaptionText) // caption
+ XStoreName(display,window,pCaptionText);
+ else XStoreName(display,window,"Pete MesaGL PSX Gpu");
+
+ XDefineCursor(display,window,cursor); // cursor
+
+ if(fx) // window title bar hack
+ {
+ mwmhints.flags=MWM_HINTS_DECORATIONS;
+ mwmhints.decorations=0;
+ mwmatom=XInternAtom(display,"_MOTIF_WM_HINTS",0);
+ XChangeProperty(display,window,mwmatom,mwmatom,32,
+ PropModeReplace,(unsigned char *)&mwmhints,4);
+ }
+
+ XSelectInput(display,window, // input setup
+ FocusChangeMask | ExposureMask |
+ KeyPressMask | KeyReleaseMask);
+
+ XMapRaised(display,window);
+ XClearWindow(display,window);
+ XWindowEvent(display,window,ExposureMask,&event);
+ glXMakeCurrent(display,window,cx);
+
+/*
+ printf(glGetString(GL_VENDOR));
+ printf("\n");
+ printf(glGetString(GL_RENDERER));
+ printf("\n");
+*/
+
+ if (fx) // after make current: fullscreen resize
+ {
+ XResizeWindow(display,window,screen->width,screen->height);
+ hints.min_width = hints.max_width = hints.base_width = screen->width;
+ hints.min_height= hints.max_height = hints.base_height = screen->height;
+ XSetWMNormalHints(display,window,&hints);
+
+ // set the window layer for GNOME
+ {
+ XEvent xev;
+
+ memset(&xev, 0, sizeof(xev));
+ xev.xclient.type = ClientMessage;
+ xev.xclient.serial = 0;
+ xev.xclient.send_event = 1;
+ xev.xclient.message_type = XInternAtom(display, "_NET_WM_STATE", 0);
+ xev.xclient.window = window;
+ xev.xclient.format = 32;
+ xev.xclient.data.l[0] = 1;
+ xev.xclient.data.l[1] = XInternAtom(display, "_NET_WM_STATE_FULLSCREEN", 0);
+ xev.xclient.data.l[2] = 0;
+ xev.xclient.data.l[3] = 0;
+ xev.xclient.data.l[4] = 0;
+
+ XSendEvent(display, RootWindow(display, DefaultScreen(display)), 0,
+ SubstructureRedirectMask | SubstructureNotifyMask, &xev);
+ }
+ }
+}
+
+#endif // !defined(_MACGL)
+
+#ifndef _WINDOWS
+
+#if defined(_MACGL)
+extern char * pCaptionText;
+#endif
+
+////////////////////////////////////////////////////////////////////////
+
+long GPUopen(unsigned long * disp,char * CapText,char * CfgFile)
+{
+ pCaptionText=CapText;
+ pConfigFile=CfgFile;
+
+ ReadConfig(); // read text file for config
+
+ SetFrameRateConfig(); // setup frame rate stuff
+
+ bIsFirstFrame = TRUE; // we have to init later (well, no really... in Linux we do all in GPUopen)
+
+ #if defined (_MACGL)
+ unsigned long display = ulInitDisplay();
+ #else
+ sysdep_create_display(); // create display
+ #endif
+
+ InitializeTextureStore(); // init texture mem
+
+ rRatioRect.left = rRatioRect.top=0;
+ rRatioRect.right = iResX;
+ rRatioRect.bottom = iResY;
+
+ GLinitialize(); // init opengl
+
+ if(disp)
+ {
+ #if defined (_MACGL)
+ *disp = display;
+ #else
+ *disp=(unsigned long *)display; // return display ID to main emu
+ #endif
+ }
+
+ if(display) return 0;
+ return -1;
+}
+
+#endif // ndef _WINDOWS
+
+
+
+////////////////////////////////////////////////////////////////////////
+// close
+////////////////////////////////////////////////////////////////////////
+
+#ifdef _WINDOWS
+
+long CALLBACK GPUclose() // WINDOWS CLOSE
+{
+ ExitKeyHandler();
+
+ GLcleanup(); // close OGL
+
+ if(bChangeRes) // change res back
+ ChangeDisplaySettings(NULL,0);
+
+ if(hPSEMenu) // set menu again
+ SetMenu(hWWindow,hPSEMenu);
+
+ if(pGfxCardScreen) free(pGfxCardScreen); // free helper memory
+ pGfxCardScreen=0;
+
+ if(iNoScreenSaver) EnableScreenSaver(TRUE); // enable screen saver again
+
+ return 0;
+}
+
+#else
+
+long GPUclose() // LINUX CLOSE
+{
+ GLcleanup(); // close OGL
+
+ if(pGfxCardScreen) free(pGfxCardScreen); // free helper memory
+ pGfxCardScreen=0;
+ #if defined (_MACGL)
+ CloseDisplay();
+ #else
+ osd_close_display(); // destroy display
+ #endif
+ return 0;
+}
+
+#endif
+
+////////////////////////////////////////////////////////////////////////
+// I shot the sheriff... last function called from emu
+////////////////////////////////////////////////////////////////////////
+
+long CALLBACK GPUshutdown()
+{
+ if(psxVSecure) free(psxVSecure); // kill emulated vram memory
+ psxVSecure=0;
+
+ return 0;
+}
+
+////////////////////////////////////////////////////////////////////////
+// paint it black: simple func to clean up optical border garbage
+////////////////////////////////////////////////////////////////////////
+
+void PaintBlackBorders(void)
+{
+ short s;
+
+ glDisable(GL_SCISSOR_TEST);
+ if(bTexEnabled) {glDisable(GL_TEXTURE_2D);bTexEnabled=FALSE;}
+ if(bOldSmoothShaded) {glShadeModel(GL_FLAT);bOldSmoothShaded=FALSE;}
+ if(bBlendEnable) {glDisable(GL_BLEND);bBlendEnable=FALSE;}
+ glDisable(GL_ALPHA_TEST);
+
+ glBegin(GL_QUADS);
+
+ vertex[0].c.lcol=0xff000000;
+ SETCOL(vertex[0]);
+
+ if(PreviousPSXDisplay.Range.x0)
+ {
+ s=PreviousPSXDisplay.Range.x0+1;
+ glVertex3f(0,0,0.99996f);
+ glVertex3f(0,PSXDisplay.DisplayMode.y,0.99996f);
+ glVertex3f(s,PSXDisplay.DisplayMode.y,0.99996f);
+ glVertex3f(s,0,0.99996f);
+
+ s+=PreviousPSXDisplay.Range.x1-2;
+
+ glVertex3f(s,0,0.99996f);
+ glVertex3f(s,PSXDisplay.DisplayMode.y,0.99996f);
+ glVertex3f(PSXDisplay.DisplayMode.x,PSXDisplay.DisplayMode.y,0.99996f);
+ glVertex3f(PSXDisplay.DisplayMode.x,0,0.99996f);
+ }
+
+ if(PreviousPSXDisplay.Range.y0)
+ {
+ s=PreviousPSXDisplay.Range.y0+1;
+ glVertex3f(0,0,0.99996f);
+ glVertex3f(0,s,0.99996f);
+ glVertex3f(PSXDisplay.DisplayMode.x,s,0.99996f);
+ glVertex3f(PSXDisplay.DisplayMode.x,0,0.99996f);
+ }
+
+ glEnd();
+
+ glEnable(GL_ALPHA_TEST);
+ glEnable(GL_SCISSOR_TEST);
+}
+
+////////////////////////////////////////////////////////////////////////
+// helper to draw scanlines
+////////////////////////////////////////////////////////////////////////
+
+__inline void XPRIMdrawTexturedQuad(OGLVertex* vertex1, OGLVertex* vertex2,
+ OGLVertex* vertex3, OGLVertex* vertex4)
+{
+
+ glBegin(GL_QUAD_STRIP);
+ glTexCoord2fv(&vertex1->sow);
+ glVertex3fv(&vertex1->x);
+
+ glTexCoord2fv(&vertex2->sow);
+ glVertex3fv(&vertex2->x);
+
+ glTexCoord2fv(&vertex4->sow);
+ glVertex3fv(&vertex4->x);
+
+ glTexCoord2fv(&vertex3->sow);
+ glVertex3fv(&vertex3->x);
+ glEnd();
+}
+
+////////////////////////////////////////////////////////////////////////
+// scanlines
+////////////////////////////////////////////////////////////////////////
+
+void SetScanLines(void)
+{
+ glLoadIdentity();
+ glOrtho(0,iResX,iResY, 0, -1, 1);
+
+ if(bKeepRatio)
+ glViewport(0,0,iResX,iResY);
+
+ glDisable(GL_SCISSOR_TEST);
+ glDisable(GL_ALPHA_TEST);
+ if(bOldSmoothShaded) {glShadeModel(GL_FLAT);bOldSmoothShaded=FALSE;}
+
+ if(iScanBlend<0) // special texture mask scanline mode
+ {
+ if(!bTexEnabled) {glEnable(GL_TEXTURE_2D);bTexEnabled=TRUE;}
+ gTexName=gTexScanName;
+ glBindTexture(GL_TEXTURE_2D, gTexName);
+ if(bGLBlend) glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+ if(!bBlendEnable) {glEnable(GL_BLEND);bBlendEnable=TRUE;}
+ SetScanTexTrans();
+
+ vertex[0].x=0;
+ vertex[0].y=iResY;
+ vertex[0].z=0.99996f;
+
+ vertex[1].x=iResX;
+ vertex[1].y=iResY;
+ vertex[1].z=0.99996f;
+
+ vertex[2].x=iResX;
+ vertex[2].y=0;
+ vertex[2].z=0.99996f;
+
+ vertex[3].x=0;
+ vertex[3].y=0;
+ vertex[3].z=0.99996f;
+
+ vertex[0].sow=0;
+ vertex[0].tow=0;
+ vertex[1].sow=(float)iResX/4.0f;
+ vertex[1].tow=0;
+ vertex[2].sow=vertex[1].sow;
+ vertex[2].tow=(float)iResY/4.0f;
+ vertex[3].sow=0;
+ vertex[3].tow=vertex[2].tow;
+
+ vertex[0].c.lcol=0xffffffff;
+ SETCOL(vertex[0]);
+
+ XPRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);
+
+ if(bGLBlend) glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, COMBINE_EXT);
+ }
+ else // typical line mode
+ {
+ if(bTexEnabled) {glDisable(GL_TEXTURE_2D);bTexEnabled=FALSE;}
+
+ if(iScanBlend==0)
+ {
+ if(bBlendEnable) {glDisable(GL_BLEND);bBlendEnable=FALSE;}
+ vertex[0].c.lcol=0xff000000;
+ }
+ else
+ {
+ if(!bBlendEnable) {glEnable(GL_BLEND);bBlendEnable=TRUE;}
+ SetScanTrans();
+ vertex[0].c.lcol=iScanBlend<<24;
+ }
+
+ SETCOL(vertex[0]);
+
+ glCallList(uiScanLine);
+ }
+
+ glLoadIdentity();
+ glOrtho(0,PSXDisplay.DisplayMode.x,
+ PSXDisplay.DisplayMode.y, 0, -1, 1);
+
+ if(bKeepRatio)
+ glViewport(rRatioRect.left,
+ iResY-(rRatioRect.top+rRatioRect.bottom),
+ rRatioRect.right,
+ rRatioRect.bottom); // init viewport
+
+ glEnable(GL_ALPHA_TEST);
+ glEnable(GL_SCISSOR_TEST);
+}
+
+////////////////////////////////////////////////////////////////////////
+// blur, babe, blur (heavy performance hit for a so-so fullscreen effect)
+////////////////////////////////////////////////////////////////////////
+
+void BlurBackBuffer(void)
+{
+ if(!gTexBlurName) return;
+
+ if(bKeepRatio) glViewport(0,0,iResX,iResY);
+
+ glDisable(GL_SCISSOR_TEST);
+ glDisable(GL_ALPHA_TEST);
+ if(bOldSmoothShaded) {glShadeModel(GL_FLAT);bOldSmoothShaded=FALSE;}
+ if(bBlendEnable) {glDisable(GL_BLEND);bBlendEnable=FALSE;}
+ if(!bTexEnabled) {glEnable(GL_TEXTURE_2D);bTexEnabled=TRUE;}
+ if(iZBufferDepth) glDisable(GL_DEPTH_TEST);
+ if(bDrawDither) glDisable(GL_DITHER);
+
+ gTexName=gTexBlurName;
+ glBindTexture(GL_TEXTURE_2D, gTexName);
+
+ glCopyTexSubImage2D( GL_TEXTURE_2D, 0, // get back buffer in texture
+ 0,
+ 0,
+ 0,
+ 0,
+ iResX,iResY);
+
+ vertex[0].x=0;
+ vertex[0].y=PSXDisplay.DisplayMode.y;
+ vertex[1].x=PSXDisplay.DisplayMode.x;
+ vertex[1].y=PSXDisplay.DisplayMode.y;
+ vertex[2].x=PSXDisplay.DisplayMode.x;
+ vertex[2].y=0;
+ vertex[3].x=0;
+ vertex[3].y=0;
+ vertex[0].sow=0;
+ vertex[0].tow=0;
+
+#ifdef OWNSCALE
+ vertex[1].sow=((GLfloat)iFTexA)/256.0f;
+ vertex[2].tow=((GLfloat)iFTexB)/256.0f;
+#else
+ vertex[1].sow=iFTexA;
+ vertex[2].tow=iFTexB;
+#endif
+ vertex[1].tow=0;
+ vertex[2].sow=vertex[1].sow;
+ vertex[3].sow=0;
+ vertex[3].tow=vertex[2].tow;
+
+ if(bGLBlend) glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+ vertex[0].c.lcol=0x7fffffff;
+ SETCOL(vertex[0]);
+
+ DrawMultiBlur(); // draw the backbuffer texture to create blur effect
+
+ glEnable(GL_ALPHA_TEST);
+ glEnable(GL_SCISSOR_TEST);
+ if(iZBufferDepth) glEnable(GL_DEPTH_TEST);
+ if(bDrawDither) glEnable(GL_DITHER);
+ if(bGLBlend) glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, COMBINE_EXT);
+
+ if(bKeepRatio)
+ glViewport(rRatioRect.left, // re-init viewport
+ iResY-(rRatioRect.top+rRatioRect.bottom),
+ rRatioRect.right,
+ rRatioRect.bottom);
+}
+
+////////////////////////////////////////////////////////////////////////
+// "unblur" repairs the backbuffer after a blur
+
+void UnBlurBackBuffer(void)
+{
+ if(!gTexBlurName) return;
+
+ if(bKeepRatio) glViewport(0,0,iResX,iResY);
+
+ glDisable(GL_SCISSOR_TEST);
+ glDisable(GL_ALPHA_TEST);
+ if(bBlendEnable) {glDisable(GL_BLEND);bBlendEnable=FALSE;}
+ if(!bTexEnabled) {glEnable(GL_TEXTURE_2D);bTexEnabled=TRUE;}
+ if(iZBufferDepth) glDisable(GL_DEPTH_TEST);
+ if(bDrawDither) glDisable(GL_DITHER);
+
+ gTexName=gTexBlurName;
+ glBindTexture(GL_TEXTURE_2D, gTexName);
+
+ vertex[0].x=0;
+ vertex[0].y=PSXDisplay.DisplayMode.y;
+ vertex[1].x=PSXDisplay.DisplayMode.x;
+ vertex[1].y=PSXDisplay.DisplayMode.y;
+ vertex[2].x=PSXDisplay.DisplayMode.x;
+ vertex[2].y=0;
+ vertex[3].x=0;
+ vertex[3].y=0;
+ vertex[0].sow=0;
+ vertex[0].tow=0;
+#ifdef OWNSCALE
+ vertex[1].sow=((GLfloat)iFTexA)/256.0f;
+ vertex[2].tow=((GLfloat)iFTexB)/256.0f;
+#else
+ vertex[1].sow=iFTexA;
+ vertex[2].tow=iFTexB;
+#endif
+ vertex[1].tow=0;
+ vertex[2].sow=vertex[1].sow;
+ vertex[3].sow=0;
+ vertex[3].tow=vertex[2].tow;
+ if(bGLBlend) glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+ vertex[0].c.lcol=0xffffffff;
+ SETCOL(vertex[0]);
+
+ // simply draw the backbuffer texture (without blur)
+ XPRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);
+
+ glEnable(GL_ALPHA_TEST);
+ glEnable(GL_SCISSOR_TEST);
+ if(iZBufferDepth) glEnable(GL_DEPTH_TEST);
+ if(bDrawDither) glEnable(GL_DITHER); // dither mode
+ if(bGLBlend) glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, COMBINE_EXT);
+
+ if(bKeepRatio)
+ glViewport(rRatioRect.left,
+ iResY-(rRatioRect.top+rRatioRect.bottom),
+ rRatioRect.right,
+ rRatioRect.bottom); // init viewport
+}
+
+////////////////////////////////////////////////////////////////////////
+// Update display (swap buffers)... called in interlaced mode on
+// every emulated vsync, otherwise whenever the displayed screen region
+// has been changed
+////////////////////////////////////////////////////////////////////////
+
+int iLastRGB24=0; // special vars for checking when to skip two display updates
+int iSkipTwo=0;
+
+void updateDisplay(void) // UPDATE DISPLAY
+{
+ BOOL bBlur=FALSE;
+
+#ifdef _WINDOWS
+ HDC hdc=GetDC(hWWindow); // windows:
+ wglMakeCurrent(hdc,GLCONTEXT); // -> make context current again
+#endif
+#if defined (_MACGL)
+ BringContextForward();
+#endif
+ bFakeFrontBuffer=FALSE;
+ bRenderFrontBuffer=FALSE;
+
+ if(iRenderFVR) // frame buffer read fix mode still active?
+ {
+ iRenderFVR--; // -> if some frames in a row without read access: turn off mode
+ if(!iRenderFVR) bFullVRam=FALSE;
+ }
+
+ if(iLastRGB24 && iLastRGB24!=PSXDisplay.RGB24+1) // (mdec) garbage check
+ {
+ iSkipTwo=2; // -> skip two frames to avoid garbage if color mode changes
+ }
+ iLastRGB24=0;
+
+ if(PSXDisplay.RGB24)// && !bNeedUploadAfter) // (mdec) upload wanted?
+ {
+ PrepareFullScreenUpload(-1);
+ UploadScreen(PSXDisplay.Interlaced); // -> upload whole screen from psx vram
+ bNeedUploadTest=FALSE;
+ bNeedInterlaceUpdate=FALSE;
+ bNeedUploadAfter=FALSE;
+ bNeedRGB24Update=FALSE;
+ }
+ else
+ if(bNeedInterlaceUpdate) // smaller upload?
+ {
+ bNeedInterlaceUpdate=FALSE;
+ xrUploadArea=xrUploadAreaIL; // -> upload this rect
+ UploadScreen(TRUE);
+ }
+
+ if(dwActFixes&512) bCheckFF9G4(NULL); // special game fix for FF9
+
+ if(PreviousPSXDisplay.Range.x0|| // paint black borders around display area, if needed
+ PreviousPSXDisplay.Range.y0)
+ PaintBlackBorders();
+
+ if(PSXDisplay.Disabled) // display disabled?
+ {
+ // moved here
+ glDisable(GL_SCISSOR_TEST);
+ glClearColor(0,0,0,128); // -> clear whole backbuffer
+ glClear(uiBufferBits);
+ glEnable(GL_SCISSOR_TEST);
+ gl_z=0.0f;
+ bDisplayNotSet = TRUE;
+ }
+
+ if(iSkipTwo) // we are in skipping mood?
+ {
+ iSkipTwo--;
+ iDrawnSomething=0; // -> simply lie about something drawn
+ }
+
+ if(iBlurBuffer && !bSkipNextFrame) // "blur display" activated?
+ {BlurBackBuffer();bBlur=TRUE;} // -> blur it
+
+ if(iUseScanLines) SetScanLines(); // "scan lines" activated? do it
+
+ if(usCursorActive) ShowGunCursor(); // "gun cursor" wanted? show 'em
+
+ if(dwActFixes&128) // special FPS limitation mode?
+ {
+ if(bUseFrameLimit) PCFrameCap(); // -> ok, do it
+ if(bUseFrameSkip || ulKeybits&KEY_SHOWFPS)
+ PCcalcfps();
+ }
+
+ if(gTexPicName) DisplayPic(); // some gpu info picture active? display it
+
+ if(bSnapShot) DoSnapShot(); // snapshot key pressed? cheeeese :)
+
+ if(ulKeybits&KEY_SHOWFPS) // wanna see FPS?
+ {
+ sprintf(szDispBuf,"%06.1f",fps_cur);
+ DisplayText(); // -> show it
+ }
+
+ //----------------------------------------------------//
+ // main buffer swapping (well, or skip it)
+
+ if(bUseFrameSkip) // frame skipping active ?
+ {
+ if(!bSkipNextFrame)
+ {
+ if(iDrawnSomething)
+#ifdef _WINDOWS
+ SwapBuffers(wglGetCurrentDC()); // -> to skip or not to skip
+#elif defined(_MACGL)
+ DoBufferSwap();
+#else
+ glXSwapBuffers(display,window);
+#endif
+ }
+ if(dwActFixes&0x180) // -> special old frame skipping: skip max one in a row
+ {
+ if((fps_skip < fFrameRateHz) && !(bSkipNextFrame))
+ {bSkipNextFrame = TRUE; fps_skip=fFrameRateHz;}
+ else bSkipNextFrame = FALSE;
+ }
+ else FrameSkip();
+ }
+ else // no skip ?
+ {
+ if(iDrawnSomething)
+#ifdef _WINDOWS
+ SwapBuffers(wglGetCurrentDC()); // -> swap
+#elif defined(_MACGL)
+ DoBufferSwap();
+#else
+ glXSwapBuffers(display,window);
+#endif
+ }
+
+ iDrawnSomething=0;
+
+ //----------------------------------------------------//
+
+ if(lClearOnSwap) // clear buffer after swap?
+ {
+ GLclampf g,b,r;
+
+ if(bDisplayNotSet) // -> set new vals
+ SetOGLDisplaySettings(1);
+
+ g=((GLclampf)GREEN(lClearOnSwapColor))/255.0f; // -> get col
+ b=((GLclampf)BLUE(lClearOnSwapColor))/255.0f;
+ r=((GLclampf)RED(lClearOnSwapColor))/255.0f;
+
+ glDisable(GL_SCISSOR_TEST);
+ glClearColor(r,g,b,128); // -> clear
+ glClear(uiBufferBits);
+ glEnable(GL_SCISSOR_TEST);
+ lClearOnSwap=0; // -> done
+ }
+ else
+ {
+ if(bBlur) UnBlurBackBuffer(); // unblur buff, if blurred before
+
+ if(iZBufferDepth) // clear zbuffer as well (if activated)
+ {
+ glDisable(GL_SCISSOR_TEST);
+ glClear(GL_DEPTH_BUFFER_BIT);
+ glEnable(GL_SCISSOR_TEST);
+ }
+ }
+ gl_z=0.0f;
+
+ //----------------------------------------------------//
+ // additional uploads immediatly after swapping
+
+ if(bNeedUploadAfter) // upload wanted?
+ {
+ bNeedUploadAfter=FALSE;
+ bNeedUploadTest=FALSE;
+ UploadScreen(-1); // -> upload
+ }
+
+ if(bNeedUploadTest)
+ {
+ bNeedUploadTest=FALSE;
+ if(PSXDisplay.InterlacedTest &&
+ //iOffscreenDrawing>2 &&
+ PreviousPSXDisplay.DisplayPosition.x==PSXDisplay.DisplayPosition.x &&
+ PreviousPSXDisplay.DisplayEnd.x==PSXDisplay.DisplayEnd.x &&
+ PreviousPSXDisplay.DisplayPosition.y==PSXDisplay.DisplayPosition.y &&
+ PreviousPSXDisplay.DisplayEnd.y==PSXDisplay.DisplayEnd.y)
+ {
+ PrepareFullScreenUpload(TRUE);
+ UploadScreen(TRUE);
+ }
+ }
+
+ //----------------------------------------------------//
+ // rumbling (main emu pad effect)
+
+ if(iRumbleTime) // shake screen by modifying view port
+ {
+ int i1=0,i2=0,i3=0,i4=0;
+
+ iRumbleTime--;
+ if(iRumbleTime)
+ {
+ i1=((rand()*iRumbleVal)/RAND_MAX)-(iRumbleVal/2);
+ i2=((rand()*iRumbleVal)/RAND_MAX)-(iRumbleVal/2);
+ i3=((rand()*iRumbleVal)/RAND_MAX)-(iRumbleVal/2);
+ i4=((rand()*iRumbleVal)/RAND_MAX)-(iRumbleVal/2);
+ }
+
+ glViewport(rRatioRect.left+i1,
+ iResY-(rRatioRect.top+rRatioRect.bottom)+i2,
+ rRatioRect.right+i3,
+ rRatioRect.bottom+i4);
+ }
+
+#ifdef _WINDOWS
+ ReleaseDC(hWWindow,hdc); // ! important !
+#endif
+
+ if(ulKeybits&KEY_RESETTEXSTORE) ResetStuff(); // reset on gpu mode changes? do it before next frame is filled
+}
+
+////////////////////////////////////////////////////////////////////////
+// update front display: smaller update func, if something has changed
+// in the frontbuffer... dirty, but hey... real men know no pain
+////////////////////////////////////////////////////////////////////////
+
+void updateFrontDisplay(void)
+{
+ if(PreviousPSXDisplay.Range.x0||
+ PreviousPSXDisplay.Range.y0)
+ PaintBlackBorders();
+
+ if(iBlurBuffer) BlurBackBuffer();
+
+ if(iUseScanLines) SetScanLines();
+
+ if(usCursorActive) ShowGunCursor();
+
+ bFakeFrontBuffer=FALSE;
+ bRenderFrontBuffer=FALSE;
+
+ if(gTexPicName) DisplayPic();
+ if(ulKeybits&KEY_SHOWFPS) DisplayText();
+
+#ifdef _WINDOWS
+ { // windows:
+ HDC hdc=GetDC(hWWindow);
+ wglMakeCurrent(hdc,GLCONTEXT); // -> make current again
+ if(iDrawnSomething)
+ SwapBuffers(wglGetCurrentDC()); // -> swap
+ ReleaseDC(hWWindow,hdc); // -> ! important !
+ }
+#elif defined (_MACGL)
+if (iDrawnSomething){
+ DoBufferSwap();
+ }
+#else
+ if(iDrawnSomething) // linux:
+ glXSwapBuffers(display,window);
+#endif
+
+ if(iBlurBuffer) UnBlurBackBuffer();
+}
+
+////////////////////////////////////////////////////////////////////////
+// check if update needed
+////////////////////////////////////////////////////////////////////////
+
+void ChangeDispOffsetsX(void) // CENTER X
+{
+ int lx,l;short sO;
+
+ if(!PSXDisplay.Range.x1) return; // some range given?
+
+ l=PSXDisplay.DisplayMode.x;
+
+ l*=(int)PSXDisplay.Range.x1; // some funky calculation
+ l/=2560;lx=l;l&=0xfffffff8;
+
+ if(l==PreviousPSXDisplay.Range.x1) return; // some change?
+
+ sO=PreviousPSXDisplay.Range.x0; // store old
+
+ if(lx>=PSXDisplay.DisplayMode.x) // range bigger?
+ {
+ PreviousPSXDisplay.Range.x1= // -> take display width
+ PSXDisplay.DisplayMode.x;
+ PreviousPSXDisplay.Range.x0=0; // -> start pos is 0
+ }
+ else // range smaller? center it
+ {
+ PreviousPSXDisplay.Range.x1=l; // -> store width (8 pixel aligned)
+ PreviousPSXDisplay.Range.x0= // -> calc start pos
+ (PSXDisplay.Range.x0-500)/8;
+ if(PreviousPSXDisplay.Range.x0<0) // -> we don't support neg. values yet
+ PreviousPSXDisplay.Range.x0=0;
+
+ if((PreviousPSXDisplay.Range.x0+lx)> // -> uhuu... that's too much
+ PSXDisplay.DisplayMode.x)
+ {
+ PreviousPSXDisplay.Range.x0= // -> adjust start
+ PSXDisplay.DisplayMode.x-lx;
+ PreviousPSXDisplay.Range.x1+=lx-l; // -> adjust width
+ }
+ }
+
+ if(sO!=PreviousPSXDisplay.Range.x0) // something changed?
+ {
+ bDisplayNotSet=TRUE; // -> recalc display stuff
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void ChangeDispOffsetsY(void) // CENTER Y
+{
+ int iT;short sO; // store previous y size
+
+ if(PSXDisplay.PAL) iT=48; else iT=28; // different offsets on PAL/NTSC
+
+ if(PSXDisplay.Range.y0>=iT) // crossed the security line? :)
+ {
+ PreviousPSXDisplay.Range.y1= // -> store width
+ PSXDisplay.DisplayModeNew.y;
+
+ sO=(PSXDisplay.Range.y0-iT-4)*PSXDisplay.Double; // -> calc offset
+ if(sO<0) sO=0;
+
+ PSXDisplay.DisplayModeNew.y+=sO; // -> add offset to y size, too
+ }
+ else sO=0; // else no offset
+
+ if(sO!=PreviousPSXDisplay.Range.y0) // something changed?
+ {
+ PreviousPSXDisplay.Range.y0=sO;
+ bDisplayNotSet=TRUE; // -> recalc display stuff
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+// Aspect ratio of ogl screen: simply adjusting ogl view port
+////////////////////////////////////////////////////////////////////////
+
+void SetAspectRatio(void)
+{
+ float xs,ys,s;RECT r;
+
+ if(!PSXDisplay.DisplayModeNew.x) return;
+ if(!PSXDisplay.DisplayModeNew.y) return;
+
+ xs=(float)iResX/(float)PSXDisplay.DisplayModeNew.x;
+ ys=(float)iResY/(float)PSXDisplay.DisplayModeNew.y;
+
+ s=min(xs,ys);
+ r.right =(int)((float)PSXDisplay.DisplayModeNew.x*s);
+ r.bottom=(int)((float)PSXDisplay.DisplayModeNew.y*s);
+ if(r.right > iResX) r.right = iResX;
+ if(r.bottom > iResY) r.bottom = iResY;
+ if(r.right < 1) r.right = 1;
+ if(r.bottom < 1) r.bottom = 1;
+
+ r.left = (iResX-r.right)/2;
+ r.top = (iResY-r.bottom)/2;
+
+ if(r.bottom<rRatioRect.bottom ||
+ r.right <rRatioRect.right)
+ {
+ RECT rC;
+ glClearColor(0,0,0,128);
+
+ if(r.right <rRatioRect.right)
+ {
+ rC.left=0;
+ rC.top=0;
+ rC.right=r.left;
+ rC.bottom=iResY;
+ glScissor(rC.left,rC.top,rC.right,rC.bottom);
+ glClear(uiBufferBits);
+ rC.left=iResX-rC.right;
+ glScissor(rC.left,rC.top,rC.right,rC.bottom);
+ glClear(uiBufferBits);
+ }
+
+ if(r.bottom <rRatioRect.bottom)
+ {
+ rC.left=0;
+ rC.top=0;
+ rC.right=iResX;
+ rC.bottom=r.top;
+ glScissor(rC.left,rC.top,rC.right,rC.bottom);
+ glClear(uiBufferBits);
+ rC.top=iResY-rC.bottom;
+ glScissor(rC.left,rC.top,rC.right,rC.bottom);
+ glClear(uiBufferBits);
+ }
+
+ bSetClip=TRUE;
+ bDisplayNotSet=TRUE;
+ }
+
+ rRatioRect=r;
+
+
+ glViewport(rRatioRect.left,
+ iResY-(rRatioRect.top+rRatioRect.bottom),
+ rRatioRect.right,
+ rRatioRect.bottom); // init viewport
+}
+
+////////////////////////////////////////////////////////////////////////
+// big ass check, if an ogl swap buffer is needed
+////////////////////////////////////////////////////////////////////////
+
+void updateDisplayIfChanged(void)
+{
+ BOOL bUp;
+
+ if ((PSXDisplay.DisplayMode.y == PSXDisplay.DisplayModeNew.y) &&
+ (PSXDisplay.DisplayMode.x == PSXDisplay.DisplayModeNew.x))
+ {
+ if((PSXDisplay.RGB24 == PSXDisplay.RGB24New) &&
+ (PSXDisplay.Interlaced == PSXDisplay.InterlacedNew))
+ return; // nothing has changed? fine, no swap buffer needed
+ }
+ else // some res change?
+ {
+ glLoadIdentity();
+ glOrtho(0,PSXDisplay.DisplayModeNew.x, // -> new psx resolution
+ PSXDisplay.DisplayModeNew.y, 0, -1, 1);
+ if(bKeepRatio) SetAspectRatio();
+ }
+
+ bDisplayNotSet = TRUE; // re-calc offsets/display area
+
+ bUp=FALSE;
+ if(PSXDisplay.RGB24!=PSXDisplay.RGB24New) // clean up textures, if rgb mode change (usually mdec on/off)
+ {
+ PreviousPSXDisplay.RGB24=0; // no full 24 frame uploaded yet
+ ResetTextureArea(FALSE);
+ bUp=TRUE;
+ }
+
+ PSXDisplay.RGB24 = PSXDisplay.RGB24New; // get new infos
+ PSXDisplay.DisplayMode.y = PSXDisplay.DisplayModeNew.y;
+ PSXDisplay.DisplayMode.x = PSXDisplay.DisplayModeNew.x;
+ PSXDisplay.Interlaced = PSXDisplay.InterlacedNew;
+
+ PSXDisplay.DisplayEnd.x= // calc new ends
+ PSXDisplay.DisplayPosition.x+ PSXDisplay.DisplayMode.x;
+ PSXDisplay.DisplayEnd.y=
+ PSXDisplay.DisplayPosition.y+ PSXDisplay.DisplayMode.y+PreviousPSXDisplay.DisplayModeNew.y;
+ PreviousPSXDisplay.DisplayEnd.x=
+ PreviousPSXDisplay.DisplayPosition.x+ PSXDisplay.DisplayMode.x;
+ PreviousPSXDisplay.DisplayEnd.y=
+ PreviousPSXDisplay.DisplayPosition.y+ PSXDisplay.DisplayMode.y+PreviousPSXDisplay.DisplayModeNew.y;
+
+ ChangeDispOffsetsX();
+
+ if(iFrameLimit==2) SetAutoFrameCap(); // set new fps limit vals (depends on interlace)
+
+ if(bUp) updateDisplay(); // yeah, real update (swap buffer)
+}
+
+////////////////////////////////////////////////////////////////////////
+// window mode <-> fullscreen mode (windows)
+////////////////////////////////////////////////////////////////////////
+
+#ifdef _WINDOWS
+void ChangeWindowMode(void)
+ {
+ GPUclose();
+ bWindowMode=!bWindowMode;
+ GPUopen(hWWindow);
+ bChangeWinMode=FALSE;
+ }
+#endif
+
+////////////////////////////////////////////////////////////////////////
+// swap update check (called by psx vsync function)
+////////////////////////////////////////////////////////////////////////
+
+BOOL bSwapCheck(void)
+{
+ static int iPosCheck=0;
+ static PSXPoint_t pO;
+ static PSXPoint_t pD;
+ static int iDoAgain=0;
+
+ if(PSXDisplay.DisplayPosition.x==pO.x &&
+ PSXDisplay.DisplayPosition.y==pO.y &&
+ PSXDisplay.DisplayEnd.x==pD.x &&
+ PSXDisplay.DisplayEnd.y==pD.y)
+ iPosCheck++;
+ else iPosCheck=0;
+
+ pO=PSXDisplay.DisplayPosition;
+ pD=PSXDisplay.DisplayEnd;
+
+ if(iPosCheck<=4) return FALSE;
+
+ iPosCheck=4;
+
+ if(PSXDisplay.Interlaced) return FALSE;
+
+ if (bNeedInterlaceUpdate||
+ bNeedRGB24Update ||
+ bNeedUploadAfter||
+ bNeedUploadTest ||
+ iDoAgain
+ )
+ {
+ iDoAgain=0;
+ if(bNeedUploadAfter)
+ iDoAgain=1;
+ if(bNeedUploadTest && PSXDisplay.InterlacedTest)
+ iDoAgain=1;
+
+ bDisplayNotSet = TRUE;
+ updateDisplay();
+
+ PreviousPSXDisplay.DisplayPosition.x=PSXDisplay.DisplayPosition.x;
+ PreviousPSXDisplay.DisplayPosition.y=PSXDisplay.DisplayPosition.y;
+ PreviousPSXDisplay.DisplayEnd.x=PSXDisplay.DisplayEnd.x;
+ PreviousPSXDisplay.DisplayEnd.y=PSXDisplay.DisplayEnd.y;
+ pO=PSXDisplay.DisplayPosition;
+ pD=PSXDisplay.DisplayEnd;
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+////////////////////////////////////////////////////////////////////////
+// gun cursor func: player=0-7, x=0-511, y=0-255
+////////////////////////////////////////////////////////////////////////
+
+void CALLBACK GPUcursor(int iPlayer,int x,int y)
+{
+ if(iPlayer<0) return;
+ if(iPlayer>7) return;
+
+ usCursorActive|=(1<<iPlayer);
+
+ if(x<0) x=0;
+ if(x>iGPUHeightMask) x=iGPUHeightMask;
+ if(y<0) y=0;
+ if(y>255) y=255;
+
+ ptCursorPoint[iPlayer].x=x;
+ ptCursorPoint[iPlayer].y=y;
+}
+
+////////////////////////////////////////////////////////////////////////
+// update lace is called every VSync. Basically we limit frame rate
+// here, and in interlaced mode we swap ogl display buffers.
+////////////////////////////////////////////////////////////////////////
+
+static unsigned short usFirstPos=2;
+
+void CALLBACK GPUupdateLace(void)
+{
+ //if(!(dwActFixes&0x1000))
+ // STATUSREG^=0x80000000; // interlaced bit toggle, if the CC game fix is not active (see gpuReadStatus)
+
+ if(!(dwActFixes&128)) // normal frame limit func
+ CheckFrameRate();
+
+ if(iOffscreenDrawing==4) // special check if high offscreen drawing is on
+ {
+ if(bSwapCheck()) return;
+ }
+
+ if(PSXDisplay.Interlaced) // interlaced mode?
+ {
+ STATUSREG^=0x80000000;
+ if(PSXDisplay.DisplayMode.x>0 && PSXDisplay.DisplayMode.y>0)
+ {
+ updateDisplay(); // -> swap buffers (new frame)
+ }
+ }
+ else if(bRenderFrontBuffer) // no interlace mode? and some stuff in front has changed?
+ {
+ updateFrontDisplay(); // -> update front buffer
+ }
+ else if(usFirstPos==1) // initial updates (after startup)
+ {
+ updateDisplay();
+ }
+
+#if defined(_WINDOWS) || defined(_MACGL)
+ if(bChangeWinMode) ChangeWindowMode();
+#endif
+}
+
+////////////////////////////////////////////////////////////////////////
+// process read request from GPU status register
+////////////////////////////////////////////////////////////////////////
+
+uint32_t CALLBACK GPUreadStatus(void)
+{
+ if(dwActFixes&0x1000) // CC game fix
+ {
+ static int iNumRead=0;
+ if((iNumRead++)==2)
+ {
+ iNumRead=0;
+ STATUSREG^=0x80000000; // interlaced bit toggle... we do it on every second read status... needed by some games (like ChronoCross)
+ }
+ }
+
+ 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...
+ {
+ iFakePrimBusy--;
+
+ if(iFakePrimBusy&1) // we do a busy-idle-busy-idle sequence after/while drawing prims
+ {
+ GPUIsBusy;
+ GPUIsNotReadyForCommands;
+ }
+ else
+ {
+ GPUIsIdle;
+ GPUIsReadyForCommands;
+ }
+ }
+
+ return STATUSREG | (vBlank ? 0x80000000 : 0 );;
+}
+
+////////////////////////////////////////////////////////////////////////
+// processes data send to GPU status register
+// these are always single packet commands.
+////////////////////////////////////////////////////////////////////////
+
+void CALLBACK GPUwriteStatus(uint32_t gdata)
+{
+ uint32_t lCommand=(gdata>>24)&0xff;
+
+#ifdef _WINDOWS
+ if(bIsFirstFrame) GLinitialize(); // real ogl startup (needed by some emus)
+#endif
+
+ ulStatusControl[lCommand]=gdata;
+
+ switch(lCommand)
+ {
+ //--------------------------------------------------//
+ // reset gpu
+ case 0x00:
+ memset(ulGPUInfoVals, 0x00, 16 * sizeof(uint32_t));
+ lGPUstatusRet = 0x14802000;
+ PSXDisplay.Disabled=1;
+ iDataWriteMode=iDataReadMode=DR_NORMAL;
+ PSXDisplay.DrawOffset.x=PSXDisplay.DrawOffset.y=0;
+ drawX=drawY=0;drawW=drawH=0;
+ sSetMask=0;lSetMask=0;bCheckMask=FALSE;iSetMask=0;
+ usMirror=0;
+ GlobalTextAddrX=0;GlobalTextAddrY=0;
+ GlobalTextTP=0;GlobalTextABR=0;
+ PSXDisplay.RGB24=FALSE;
+ PSXDisplay.Interlaced=FALSE;
+ bUsingTWin = FALSE;
+ return;
+
+ // dis/enable display
+ case 0x03:
+ PreviousPSXDisplay.Disabled = PSXDisplay.Disabled;
+ PSXDisplay.Disabled = (gdata & 1);
+
+ if(PSXDisplay.Disabled)
+ STATUSREG|=GPUSTATUS_DISPLAYDISABLED;
+ else STATUSREG&=~GPUSTATUS_DISPLAYDISABLED;
+
+ if (iOffscreenDrawing==4 &&
+ PreviousPSXDisplay.Disabled &&
+ !(PSXDisplay.Disabled))
+ {
+
+ if(!PSXDisplay.RGB24)
+ {
+ PrepareFullScreenUpload(TRUE);
+ UploadScreen(TRUE);
+ updateDisplay();
+ }
+ }
+
+ return;
+
+ // setting transfer mode
+ case 0x04:
+ gdata &= 0x03; // only want the lower two bits
+
+ iDataWriteMode=iDataReadMode=DR_NORMAL;
+ if(gdata==0x02) iDataWriteMode=DR_VRAMTRANSFER;
+ if(gdata==0x03) iDataReadMode =DR_VRAMTRANSFER;
+
+ STATUSREG&=~GPUSTATUS_DMABITS; // clear the current settings of the DMA bits
+ STATUSREG|=(gdata << 29); // set the DMA bits according to the received data
+
+ return;
+
+ // setting display position
+ case 0x05:
+ {
+ short sx=(short)(gdata & 0x3ff);
+ short sy;
+
+ if(iGPUHeight==1024)
+ {
+ if(dwGPUVersion==2)
+ sy = (short)((gdata>>12)&0x3ff);
+ else sy = (short)((gdata>>10)&0x3ff);
+ }
+ else sy = (short)((gdata>>10)&0x3ff); // really: 0x1ff, but we adjust it later
+
+ if (sy & 0x200)
+ {
+ sy|=0xfc00;
+ PreviousPSXDisplay.DisplayModeNew.y=sy/PSXDisplay.Double;
+ sy=0;
+ }
+ else PreviousPSXDisplay.DisplayModeNew.y=0;
+
+ if(sx>1000) sx=0;
+
+ if(usFirstPos)
+ {
+ usFirstPos--;
+ if(usFirstPos)
+ {
+ PreviousPSXDisplay.DisplayPosition.x = sx;
+ PreviousPSXDisplay.DisplayPosition.y = sy;
+ PSXDisplay.DisplayPosition.x = sx;
+ PSXDisplay.DisplayPosition.y = sy;
+ }
+ }
+
+ if(dwActFixes&8)
+ {
+ if((!PSXDisplay.Interlaced) &&
+ PreviousPSXDisplay.DisplayPosition.x == sx &&
+ PreviousPSXDisplay.DisplayPosition.y == sy)
+ return;
+
+ PSXDisplay.DisplayPosition.x = PreviousPSXDisplay.DisplayPosition.x;
+ PSXDisplay.DisplayPosition.y = PreviousPSXDisplay.DisplayPosition.y;
+ PreviousPSXDisplay.DisplayPosition.x = sx;
+ PreviousPSXDisplay.DisplayPosition.y = sy;
+ }
+ else
+ {
+ if((!PSXDisplay.Interlaced) &&
+ PSXDisplay.DisplayPosition.x == sx &&
+ PSXDisplay.DisplayPosition.y == sy)
+ return;
+ PreviousPSXDisplay.DisplayPosition.x = PSXDisplay.DisplayPosition.x;
+ PreviousPSXDisplay.DisplayPosition.y = PSXDisplay.DisplayPosition.y;
+ PSXDisplay.DisplayPosition.x = sx;
+ PSXDisplay.DisplayPosition.y = sy;
+ }
+
+ PSXDisplay.DisplayEnd.x=
+ PSXDisplay.DisplayPosition.x+ PSXDisplay.DisplayMode.x;
+ PSXDisplay.DisplayEnd.y=
+ PSXDisplay.DisplayPosition.y+ PSXDisplay.DisplayMode.y+PreviousPSXDisplay.DisplayModeNew.y;
+
+ PreviousPSXDisplay.DisplayEnd.x=
+ PreviousPSXDisplay.DisplayPosition.x+ PSXDisplay.DisplayMode.x;
+ PreviousPSXDisplay.DisplayEnd.y=
+ PreviousPSXDisplay.DisplayPosition.y+ PSXDisplay.DisplayMode.y+PreviousPSXDisplay.DisplayModeNew.y;
+
+ bDisplayNotSet = TRUE;
+
+ if (!(PSXDisplay.Interlaced))
+ {
+ updateDisplay();
+ }
+ else
+ if(PSXDisplay.InterlacedTest &&
+ ((PreviousPSXDisplay.DisplayPosition.x != PSXDisplay.DisplayPosition.x)||
+ (PreviousPSXDisplay.DisplayPosition.y != PSXDisplay.DisplayPosition.y)))
+ PSXDisplay.InterlacedTest--;
+
+ return;
+ }
+
+ // setting width
+ case 0x06:
+
+ PSXDisplay.Range.x0=gdata & 0x7ff; //0x3ff;
+ PSXDisplay.Range.x1=(gdata>>12) & 0xfff;//0x7ff;
+
+ PSXDisplay.Range.x1-=PSXDisplay.Range.x0;
+
+ ChangeDispOffsetsX();
+
+ return;
+
+ // setting height
+ case 0x07:
+
+ PreviousPSXDisplay.Height = PSXDisplay.Height;
+
+ PSXDisplay.Range.y0=gdata & 0x3ff;
+ PSXDisplay.Range.y1=(gdata>>10) & 0x3ff;
+
+ PSXDisplay.Height = PSXDisplay.Range.y1 -
+ PSXDisplay.Range.y0 +
+ PreviousPSXDisplay.DisplayModeNew.y;
+
+ if (PreviousPSXDisplay.Height != PSXDisplay.Height)
+ {
+ PSXDisplay.DisplayModeNew.y=PSXDisplay.Height*PSXDisplay.Double;
+ ChangeDispOffsetsY();
+ updateDisplayIfChanged();
+ }
+ return;
+
+ // setting display infos
+ case 0x08:
+
+ PSXDisplay.DisplayModeNew.x = dispWidths[(gdata & 0x03) | ((gdata & 0x40) >> 4)];
+
+ if (gdata&0x04) PSXDisplay.Double=2;
+ else PSXDisplay.Double=1;
+ PSXDisplay.DisplayModeNew.y = PSXDisplay.Height*PSXDisplay.Double;
+
+ ChangeDispOffsetsY();
+
+ PSXDisplay.PAL = (gdata & 0x08)?TRUE:FALSE; // if 1 - PAL mode, else NTSC
+ PSXDisplay.RGB24New = (gdata & 0x10)?TRUE:FALSE; // if 1 - TrueColor
+ PSXDisplay.InterlacedNew = (gdata & 0x20)?TRUE:FALSE; // if 1 - Interlace
+
+ STATUSREG&=~GPUSTATUS_WIDTHBITS; // clear the width bits
+
+ STATUSREG|=
+ (((gdata & 0x03) << 17) |
+ ((gdata & 0x40) << 10)); // set the width bits
+
+ PreviousPSXDisplay.InterlacedNew=FALSE;
+ if (PSXDisplay.InterlacedNew)
+ {
+ if(!PSXDisplay.Interlaced)
+ {
+ PSXDisplay.InterlacedTest=2;
+ PreviousPSXDisplay.DisplayPosition.x = PSXDisplay.DisplayPosition.x;
+ PreviousPSXDisplay.DisplayPosition.y = PSXDisplay.DisplayPosition.y;
+ PreviousPSXDisplay.InterlacedNew=TRUE;
+ }
+
+ STATUSREG|=GPUSTATUS_INTERLACED;
+ }
+ else
+ {
+ PSXDisplay.InterlacedTest=0;
+ STATUSREG&=~GPUSTATUS_INTERLACED;
+ }
+
+ if (PSXDisplay.PAL)
+ STATUSREG|=GPUSTATUS_PAL;
+ else STATUSREG&=~GPUSTATUS_PAL;
+
+ if (PSXDisplay.Double==2)
+ STATUSREG|=GPUSTATUS_DOUBLEHEIGHT;
+ else STATUSREG&=~GPUSTATUS_DOUBLEHEIGHT;
+
+ if (PSXDisplay.RGB24New)
+ STATUSREG|=GPUSTATUS_RGB24;
+ else STATUSREG&=~GPUSTATUS_RGB24;
+
+ updateDisplayIfChanged();
+
+ return;
+
+ //--------------------------------------------------//
+ // ask about GPU version and other stuff
+ case 0x10:
+
+ gdata&=0xff;
+
+ switch(gdata)
+ {
+ case 0x02:
+ GPUdataRet=ulGPUInfoVals[INFO_TW]; // tw infos
+ return;
+ case 0x03:
+ GPUdataRet=ulGPUInfoVals[INFO_DRAWSTART]; // draw start
+ return;
+ case 0x04:
+ GPUdataRet=ulGPUInfoVals[INFO_DRAWEND]; // draw end
+ return;
+ case 0x05:
+ case 0x06:
+ GPUdataRet=ulGPUInfoVals[INFO_DRAWOFF]; // draw offset
+ return;
+ case 0x07:
+ if(dwGPUVersion==2)
+ GPUdataRet=0x01;
+ else GPUdataRet=0x02; // gpu type
+ return;
+ case 0x08:
+ case 0x0F: // some bios addr?
+ GPUdataRet=0xBFC03720;
+ return;
+ }
+ return;
+ //--------------------------------------------------//
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+// vram read/write helpers
+////////////////////////////////////////////////////////////////////////
+
+BOOL bNeedWriteUpload=FALSE;
+
+__inline void FinishedVRAMWrite(void)
+{
+ if(bNeedWriteUpload)
+ {
+ bNeedWriteUpload=FALSE;
+ CheckWriteUpdate();
+ }
+
+ // set register to NORMAL operation
+ iDataWriteMode = DR_NORMAL;
+
+ // reset transfer values, to prevent mis-transfer of data
+ VRAMWrite.ColsRemaining = 0;
+ VRAMWrite.RowsRemaining = 0;
+}
+
+__inline void FinishedVRAMRead(void)
+{
+ // set register to NORMAL operation
+ iDataReadMode = DR_NORMAL;
+ // reset transfer values, to prevent mis-transfer of data
+ VRAMRead.x = 0;
+ VRAMRead.y = 0;
+ VRAMRead.Width = 0;
+ VRAMRead.Height = 0;
+ VRAMRead.ColsRemaining = 0;
+ VRAMRead.RowsRemaining = 0;
+
+ // indicate GPU is no longer ready for VRAM data in the STATUS REGISTER
+ STATUSREG&=~GPUSTATUS_READYFORVRAM;
+}
+
+////////////////////////////////////////////////////////////////////////
+// vram read check ex (reading from card's back/frontbuffer if needed...
+// slow!)
+////////////////////////////////////////////////////////////////////////
+
+void CheckVRamReadEx(int x, int y, int dx, int dy)
+{
+ unsigned short sArea;
+ int ux,uy,udx,udy,wx,wy;
+ unsigned short * p1, *p2;
+ float XS,YS;
+ unsigned char * ps;
+ unsigned char * px;
+ unsigned short s,sx;
+
+ if(STATUSREG&GPUSTATUS_RGB24) return;
+
+ if(((dx > PSXDisplay.DisplayPosition.x) &&
+ (x < PSXDisplay.DisplayEnd.x) &&
+ (dy > PSXDisplay.DisplayPosition.y) &&
+ (y < PSXDisplay.DisplayEnd.y)))
+ sArea=0;
+ else
+ if((!(PSXDisplay.InterlacedTest) &&
+ (dx > PreviousPSXDisplay.DisplayPosition.x) &&
+ (x < PreviousPSXDisplay.DisplayEnd.x) &&
+ (dy > PreviousPSXDisplay.DisplayPosition.y) &&
+ (y < PreviousPSXDisplay.DisplayEnd.y)))
+ sArea=1;
+ else
+ {
+ return;
+ }
+
+ //////////////
+
+ if(iRenderFVR)
+ {
+ bFullVRam=TRUE;iRenderFVR=2;return;
+ }
+ bFullVRam=TRUE;iRenderFVR=2;
+
+ //////////////
+
+ p2=0;
+
+ if(sArea==0)
+ {
+ ux=PSXDisplay.DisplayPosition.x;
+ uy=PSXDisplay.DisplayPosition.y;
+ udx=PSXDisplay.DisplayEnd.x-ux;
+ udy=PSXDisplay.DisplayEnd.y-uy;
+ if((PreviousPSXDisplay.DisplayEnd.x-
+ PreviousPSXDisplay.DisplayPosition.x)==udx &&
+ (PreviousPSXDisplay.DisplayEnd.y-
+ PreviousPSXDisplay.DisplayPosition.y)==udy)
+ p2=(psxVuw + (1024*PreviousPSXDisplay.DisplayPosition.y) +
+ PreviousPSXDisplay.DisplayPosition.x);
+ }
+ else
+ {
+ ux=PreviousPSXDisplay.DisplayPosition.x;
+ uy=PreviousPSXDisplay.DisplayPosition.y;
+ udx=PreviousPSXDisplay.DisplayEnd.x-ux;
+ udy=PreviousPSXDisplay.DisplayEnd.y-uy;
+ if((PSXDisplay.DisplayEnd.x-
+ PSXDisplay.DisplayPosition.x)==udx &&
+ (PSXDisplay.DisplayEnd.y-
+ PSXDisplay.DisplayPosition.y)==udy)
+ p2=(psxVuw + (1024*PSXDisplay.DisplayPosition.y) +
+ PSXDisplay.DisplayPosition.x);
+ }
+
+ p1=(psxVuw + (1024*uy) + ux);
+ if(p1==p2) p2=0;
+
+ x=0;y=0;
+ wx=dx=udx;wy=dy=udy;
+
+ if(udx<=0) return;
+ if(udy<=0) return;
+ if(dx<=0) return;
+ if(dy<=0) return;
+ if(wx<=0) return;
+ if(wy<=0) return;
+
+ XS=(float)rRatioRect.right/(float)wx;
+ YS=(float)rRatioRect.bottom/(float)wy;
+
+ dx=(int)((float)(dx)*XS);
+ dy=(int)((float)(dy)*YS);
+
+ if(dx>iResX) dx=iResX;
+ if(dy>iResY) dy=iResY;
+
+ if(dx<=0) return;
+ if(dy<=0) return;
+
+ // ogl y adjust
+ y=iResY-y-dy;
+
+ x+=rRatioRect.left;
+ y-=rRatioRect.top;
+
+ if(y<0) y=0; if((y+dy)>iResY) dy=iResY-y;
+
+ if(!pGfxCardScreen)
+ {
+ glPixelStorei(GL_PACK_ALIGNMENT,1);
+ pGfxCardScreen=(unsigned char *)malloc(iResX*iResY*4);
+ }
+
+ ps=pGfxCardScreen;
+
+ if(!sArea) glReadBuffer(GL_FRONT);
+
+ glReadPixels(x,y,dx,dy,GL_RGB,GL_UNSIGNED_BYTE,ps);
+
+ if(!sArea) glReadBuffer(GL_BACK);
+
+ s=0;
+
+ XS=(float)dx/(float)(udx);
+ YS=(float)dy/(float)(udy+1);
+
+ for(y=udy;y>0;y--)
+ {
+ for(x=0;x<udx;x++)
+ {
+ if(p1>=psxVuw && p1<psxVuw_eom)
+ {
+ px=ps+(3*((int)((float)x * XS))+
+ (3*dx)*((int)((float)y*YS)));
+ sx=(*px)>>3;px++;
+ s=sx;
+ sx=(*px)>>3;px++;
+ s|=sx<<5;
+ sx=(*px)>>3;
+ s|=sx<<10;
+ s&=~0x8000;
+ *p1=s;
+ }
+ if(p2>=psxVuw && p2<psxVuw_eom) *p2=s;
+
+ p1++;
+ if(p2) p2++;
+ }
+
+ p1 += 1024 - udx;
+ if(p2) p2 += 1024 - udx;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+// vram read check (reading from card's back/frontbuffer if needed...
+// slow!)
+////////////////////////////////////////////////////////////////////////
+
+void CheckVRamRead(int x, int y, int dx, int dy,BOOL bFront)
+{
+ unsigned short sArea;unsigned short * p;
+ int ux,uy,udx,udy,wx,wy;float XS,YS;
+ unsigned char * ps, * px;
+ unsigned short s=0,sx;
+
+ if(STATUSREG&GPUSTATUS_RGB24) return;
+
+ if(((dx > PSXDisplay.DisplayPosition.x) &&
+ (x < PSXDisplay.DisplayEnd.x) &&
+ (dy > PSXDisplay.DisplayPosition.y) &&
+ (y < PSXDisplay.DisplayEnd.y)))
+ sArea=0;
+ else
+ if((!(PSXDisplay.InterlacedTest) &&
+ (dx > PreviousPSXDisplay.DisplayPosition.x) &&
+ (x < PreviousPSXDisplay.DisplayEnd.x) &&
+ (dy > PreviousPSXDisplay.DisplayPosition.y) &&
+ (y < PreviousPSXDisplay.DisplayEnd.y)))
+ sArea=1;
+ else
+ {
+ return;
+ }
+
+ if(dwActFixes&0x40)
+ {
+ if(iRenderFVR)
+ {
+ bFullVRam=TRUE;iRenderFVR=2;return;
+ }
+ bFullVRam=TRUE;iRenderFVR=2;
+ }
+
+ ux=x;uy=y;udx=dx;udy=dy;
+
+ if(sArea==0)
+ {
+ x -=PSXDisplay.DisplayPosition.x;
+ dx-=PSXDisplay.DisplayPosition.x;
+ y -=PSXDisplay.DisplayPosition.y;
+ dy-=PSXDisplay.DisplayPosition.y;
+ wx=PSXDisplay.DisplayEnd.x-PSXDisplay.DisplayPosition.x;
+ wy=PSXDisplay.DisplayEnd.y-PSXDisplay.DisplayPosition.y;
+ }
+ else
+ {
+ x -=PreviousPSXDisplay.DisplayPosition.x;
+ dx-=PreviousPSXDisplay.DisplayPosition.x;
+ y -=PreviousPSXDisplay.DisplayPosition.y;
+ dy-=PreviousPSXDisplay.DisplayPosition.y;
+ wx=PreviousPSXDisplay.DisplayEnd.x-PreviousPSXDisplay.DisplayPosition.x;
+ wy=PreviousPSXDisplay.DisplayEnd.y-PreviousPSXDisplay.DisplayPosition.y;
+ }
+ if(x<0) {ux-=x;x=0;}
+ if(y<0) {uy-=y;y=0;}
+ if(dx>wx) {udx-=(dx-wx);dx=wx;}
+ if(dy>wy) {udy-=(dy-wy);dy=wy;}
+ udx-=ux;
+ udy-=uy;
+
+ p=(psxVuw + (1024*uy) + ux);
+
+ if(udx<=0) return;
+ if(udy<=0) return;
+ if(dx<=0) return;
+ if(dy<=0) return;
+ if(wx<=0) return;
+ if(wy<=0) return;
+
+ XS=(float)rRatioRect.right/(float)wx;
+ YS=(float)rRatioRect.bottom/(float)wy;
+
+ dx=(int)((float)(dx)*XS);
+ dy=(int)((float)(dy)*YS);
+ x=(int)((float)x*XS);
+ y=(int)((float)y*YS);
+
+ dx-=x;
+ dy-=y;
+
+ if(dx>iResX) dx=iResX;
+ if(dy>iResY) dy=iResY;
+
+ if(dx<=0) return;
+ if(dy<=0) return;
+
+ // ogl y adjust
+ y=iResY-y-dy;
+
+ x+=rRatioRect.left;
+ y-=rRatioRect.top;
+
+ if(y<0) y=0; if((y+dy)>iResY) dy=iResY-y;
+
+ if(!pGfxCardScreen)
+ {
+ glPixelStorei(GL_PACK_ALIGNMENT,1);
+ pGfxCardScreen=(unsigned char *)malloc(iResX*iResY*4);
+ }
+
+ ps=pGfxCardScreen;
+
+ if(bFront) glReadBuffer(GL_FRONT);
+
+ glReadPixels(x,y,dx,dy,GL_RGB,GL_UNSIGNED_BYTE,ps);
+
+ if(bFront) glReadBuffer(GL_BACK);
+
+ XS=(float)dx/(float)(udx);
+ YS=(float)dy/(float)(udy+1);
+
+ for(y=udy;y>0;y--)
+ {
+ for(x=0;x<udx;x++)
+ {
+ if(p>=psxVuw && p<psxVuw_eom)
+ {
+ px=ps+(3*((int)((float)x * XS))+
+ (3*dx)*((int)((float)y*YS)));
+ sx=(*px)>>3;px++;
+ s=sx;
+ sx=(*px)>>3;px++;
+ s|=sx<<5;
+ sx=(*px)>>3;
+ s|=sx<<10;
+ s&=~0x8000;
+ *p=s;
+ }
+ p++;
+ }
+ p += 1024 - udx;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+// core read from vram
+////////////////////////////////////////////////////////////////////////
+
+void CALLBACK GPUreadDataMem(uint32_t *pMem, int iSize)
+{
+ int i;
+
+ if(iDataReadMode!=DR_VRAMTRANSFER) return;
+
+ GPUIsBusy;
+
+ // adjust read ptr, if necessary
+ while(VRAMRead.ImagePtr>=psxVuw_eom)
+ VRAMRead.ImagePtr-=iGPUHeight*1024;
+ while(VRAMRead.ImagePtr<psxVuw)
+ VRAMRead.ImagePtr+=iGPUHeight*1024;
+
+ if((iFrameReadType&1 && iSize>1) &&
+ !(iDrawnSomething==2 &&
+ VRAMRead.x == VRAMWrite.x &&
+ VRAMRead.y == VRAMWrite.y &&
+ VRAMRead.Width == VRAMWrite.Width &&
+ VRAMRead.Height == VRAMWrite.Height))
+ CheckVRamRead(VRAMRead.x,VRAMRead.y,
+ VRAMRead.x+VRAMRead.RowsRemaining,
+ VRAMRead.y+VRAMRead.ColsRemaining,
+ TRUE);
+
+ for(i=0;i<iSize;i++)
+ {
+ // do 2 seperate 16bit reads for compatibility (wrap issues)
+ if ((VRAMRead.ColsRemaining > 0) && (VRAMRead.RowsRemaining > 0))
+ {
+ // lower 16 bit
+ GPUdataRet=(uint32_t)*VRAMRead.ImagePtr;
+
+ VRAMRead.ImagePtr++;
+ if(VRAMRead.ImagePtr>=psxVuw_eom) VRAMRead.ImagePtr-=iGPUHeight*1024;
+ VRAMRead.RowsRemaining --;
+
+ if(VRAMRead.RowsRemaining<=0)
+ {
+ VRAMRead.RowsRemaining = VRAMRead.Width;
+ VRAMRead.ColsRemaining--;
+ VRAMRead.ImagePtr += 1024 - VRAMRead.Width;
+ if(VRAMRead.ImagePtr>=psxVuw_eom) VRAMRead.ImagePtr-=iGPUHeight*1024;
+ }
+
+ // higher 16 bit (always, even if it's an odd width)
+ GPUdataRet|=(uint32_t)(*VRAMRead.ImagePtr)<<16;
+ *pMem++=GPUdataRet;
+
+ if(VRAMRead.ColsRemaining <= 0)
+ {FinishedVRAMRead();goto ENDREAD;}
+
+ VRAMRead.ImagePtr++;
+ if(VRAMRead.ImagePtr>=psxVuw_eom) VRAMRead.ImagePtr-=iGPUHeight*1024;
+ VRAMRead.RowsRemaining--;
+ if(VRAMRead.RowsRemaining<=0)
+ {
+ VRAMRead.RowsRemaining = VRAMRead.Width;
+ VRAMRead.ColsRemaining--;
+ VRAMRead.ImagePtr += 1024 - VRAMRead.Width;
+ if(VRAMRead.ImagePtr>=psxVuw_eom) VRAMRead.ImagePtr-=iGPUHeight*1024;
+ }
+ if(VRAMRead.ColsRemaining <= 0)
+ {FinishedVRAMRead();goto ENDREAD;}
+ }
+ else {FinishedVRAMRead();goto ENDREAD;}
+ }
+
+ENDREAD:
+ GPUIsIdle;
+}
+
+uint32_t CALLBACK GPUreadData(void)
+{
+ uint32_t l;
+ GPUreadDataMem(&l,1);
+ return GPUdataRet;
+}
+
+////////////////////////////////////////////////////////////////////////
+// helper table to know how much data is used by drawing commands
+////////////////////////////////////////////////////////////////////////
+
+const unsigned char primTableCX[256] =
+{
+ // 00
+ 0,0,3,0,0,0,0,0,
+ // 08
+ 0,0,0,0,0,0,0,0,
+ // 10
+ 0,0,0,0,0,0,0,0,
+ // 18
+ 0,0,0,0,0,0,0,0,
+ // 20
+ 4,4,4,4,7,7,7,7,
+ // 28
+ 5,5,5,5,9,9,9,9,
+ // 30
+ 6,6,6,6,9,9,9,9,
+ // 38
+ 8,8,8,8,12,12,12,12,
+ // 40
+ 3,3,3,3,0,0,0,0,
+ // 48
+// 5,5,5,5,6,6,6,6, //FLINE
+ 254,254,254,254,254,254,254,254,
+ // 50
+ 4,4,4,4,0,0,0,0,
+ // 58
+// 7,7,7,7,9,9,9,9, // LINEG3 LINEG4
+ 255,255,255,255,255,255,255,255,
+ // 60
+ 3,3,3,3,4,4,4,4, // TILE SPRT
+ // 68
+ 2,2,2,2,3,3,3,3, // TILE1
+ // 70
+ 2,2,2,2,3,3,3,3,
+ // 78
+ 2,2,2,2,3,3,3,3,
+ // 80
+ 4,0,0,0,0,0,0,0,
+ // 88
+ 0,0,0,0,0,0,0,0,
+ // 90
+ 0,0,0,0,0,0,0,0,
+ // 98
+ 0,0,0,0,0,0,0,0,
+ // a0
+ 3,0,0,0,0,0,0,0,
+ // a8
+ 0,0,0,0,0,0,0,0,
+ // b0
+ 0,0,0,0,0,0,0,0,
+ // b8
+ 0,0,0,0,0,0,0,0,
+ // c0
+ 3,0,0,0,0,0,0,0,
+ // c8
+ 0,0,0,0,0,0,0,0,
+ // d0
+ 0,0,0,0,0,0,0,0,
+ // d8
+ 0,0,0,0,0,0,0,0,
+ // e0
+ 0,1,1,1,1,1,1,0,
+ // e8
+ 0,0,0,0,0,0,0,0,
+ // f0
+ 0,0,0,0,0,0,0,0,
+ // f8
+ 0,0,0,0,0,0,0,0
+};
+
+////////////////////////////////////////////////////////////////////////
+// processes data send to GPU data register
+////////////////////////////////////////////////////////////////////////
+
+void CALLBACK GPUwriteDataMem(uint32_t *pMem, int iSize)
+{
+ unsigned char command;
+ uint32_t gdata=0;
+ int i=0;
+ GPUIsBusy;
+ GPUIsNotReadyForCommands;
+
+STARTVRAM:
+
+ if(iDataWriteMode==DR_VRAMTRANSFER)
+ {
+ // make sure we are in vram
+ while(VRAMWrite.ImagePtr>=psxVuw_eom)
+ VRAMWrite.ImagePtr-=iGPUHeight*1024;
+ while(VRAMWrite.ImagePtr<psxVuw)
+ VRAMWrite.ImagePtr+=iGPUHeight*1024;
+
+ // now do the loop
+ while(VRAMWrite.ColsRemaining>0)
+ {
+ while(VRAMWrite.RowsRemaining>0)
+ {
+ if(i>=iSize) {goto ENDVRAM;}
+ i++;
+
+ gdata=*pMem++;
+
+ *VRAMWrite.ImagePtr++ = (unsigned short)gdata;
+ if(VRAMWrite.ImagePtr>=psxVuw_eom) VRAMWrite.ImagePtr-=iGPUHeight*1024;
+ VRAMWrite.RowsRemaining --;
+
+ if(VRAMWrite.RowsRemaining <= 0)
+ {
+ VRAMWrite.ColsRemaining--;
+ if (VRAMWrite.ColsRemaining <= 0) // last pixel is odd width
+ {
+ gdata=(gdata&0xFFFF)|(((uint32_t)(*VRAMWrite.ImagePtr))<<16);
+ FinishedVRAMWrite();
+ goto ENDVRAM;
+ }
+ VRAMWrite.RowsRemaining = VRAMWrite.Width;
+ VRAMWrite.ImagePtr += 1024 - VRAMWrite.Width;
+ }
+
+ *VRAMWrite.ImagePtr++ = (unsigned short)(gdata>>16);
+ if(VRAMWrite.ImagePtr>=psxVuw_eom) VRAMWrite.ImagePtr-=iGPUHeight*1024;
+ VRAMWrite.RowsRemaining --;
+ }
+
+ VRAMWrite.RowsRemaining = VRAMWrite.Width;
+ VRAMWrite.ColsRemaining--;
+ VRAMWrite.ImagePtr += 1024 - VRAMWrite.Width;
+ }
+
+ FinishedVRAMWrite();
+ }
+
+ENDVRAM:
+
+ if(iDataWriteMode==DR_NORMAL)
+ {
+ void (* *primFunc)(unsigned char *);
+ if(bSkipNextFrame) primFunc=primTableSkip;
+ else primFunc=primTableJ;
+
+ for(;i<iSize;)
+ {
+ if(iDataWriteMode==DR_VRAMTRANSFER) goto STARTVRAM;
+
+ gdata=*pMem++;i++;
+
+ if(gpuDataC == 0)
+ {
+ command = (unsigned char)((gdata>>24) & 0xff);
+
+ if(primTableCX[command])
+ {
+ gpuDataC = primTableCX[command];
+ gpuCommand = command;
+ gpuDataM[0] = gdata;
+ gpuDataP = 1;
+ }
+ else continue;
+ }
+ else
+ {
+ gpuDataM[gpuDataP] = gdata;
+ if(gpuDataC>128)
+ {
+ if((gpuDataC==254 && gpuDataP>=3) ||
+ (gpuDataC==255 && gpuDataP>=4 && !(gpuDataP&1)))
+ {
+ if((gpuDataM[gpuDataP] & 0xF000F000) == 0x50005000)
+ gpuDataP=gpuDataC-1;
+ }
+ }
+ gpuDataP++;
+ }
+
+ if(gpuDataP == gpuDataC)
+ {
+ gpuDataC=gpuDataP=0;
+ primFunc[gpuCommand]((unsigned char *)gpuDataM);
+
+ if(dwEmuFixes&0x0001 || dwActFixes&0x20000) // hack for emulating "gpu busy" in some games
+ iFakePrimBusy=4;
+ }
+ }
+ }
+
+ GPUdataRet=gdata;
+
+ GPUIsReadyForCommands;
+ GPUIsIdle;
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void CALLBACK GPUwriteData(uint32_t gdata)
+{
+ GPUwriteDataMem(&gdata,1);
+}
+
+////////////////////////////////////////////////////////////////////////
+// call config dlg
+////////////////////////////////////////////////////////////////////////
+
+#ifdef _WINDOWS
+
+long CALLBACK GPUconfigure(void)
+{
+ HWND hWP=GetActiveWindow();
+ DialogBox(hInst,MAKEINTRESOURCE(IDD_CFGDLG),
+ hWP,(DLGPROC)CfgDlgProc);
+
+ return 0;
+}
+
+#elif defined(_MACGL)
+long CALLBACK GPUconfigure(void)
+{
+ DlgProc();
+ return 0;
+}
+#else
+
+void StartCfgTool(char *arg) // linux: start external cfg tool
+{
+ char cfg[256];
+ struct stat buf;
+
+ strcpy(cfg, "./cfgpeopsxgl");
+ if (stat(cfg, &buf) != -1) {
+ if (fork() == 0) {
+ execl(cfg, "cfgpeopsxgl", arg, NULL);
+ exit(0);
+ }
+ return;
+ }
+
+ strcpy(cfg, "./cfg/cfgpeopsxgl");
+ if (stat(cfg, &buf) != -1) {
+ if (fork() == 0) {
+ execl(cfg, "cfgpeopsxgl", arg, NULL);
+ exit(0);
+ }
+ return;
+ }
+
+ sprintf(cfg, "%s/.pcsx/plugins/cfg/cfgpeopsxgl", getenv("HOME"));
+ if (stat(cfg, &buf) != -1) {
+ if (fork() == 0) {
+ execl(cfg, "cfgpeopsxgl", arg, NULL);
+ exit(0);
+ }
+ return;
+ }
+
+ printf("ERROR: cfgpeopsxgl file not found!\n");
+}
+
+long CALLBACK GPUconfigure(void)
+{
+ StartCfgTool("CFG");
+ return 0;
+}
+
+#endif // def _WINDOWS / _MACGL
+
+////////////////////////////////////////////////////////////////////////
+// sets all kind of act fixes
+////////////////////////////////////////////////////////////////////////
+
+void SetFixes(void)
+{
+ ReInitFrameCap();
+
+ if(dwActFixes & 0x2000)
+ dispWidths[4]=384;
+ else dispWidths[4]=368;
+}
+
+////////////////////////////////////////////////////////////////////////
+// Pete Special: make an 'intelligent' dma chain check (<-Tekken3)
+////////////////////////////////////////////////////////////////////////
+
+uint32_t lUsedAddr[3];
+
+__inline BOOL CheckForEndlessLoop(uint32_t laddr)
+{
+ if(laddr==lUsedAddr[1]) return TRUE;
+ if(laddr==lUsedAddr[2]) return TRUE;
+
+ if(laddr<lUsedAddr[0]) lUsedAddr[1]=laddr;
+ else lUsedAddr[2]=laddr;
+ lUsedAddr[0]=laddr;
+ return FALSE;
+}
+
+////////////////////////////////////////////////////////////////////////
+// core gives a dma chain to gpu: same as the gpuwrite interface funcs
+////////////////////////////////////////////////////////////////////////
+
+long CALLBACK GPUdmaChain(uint32_t *baseAddrL, uint32_t addr)
+{
+ uint32_t dmaMem;
+ unsigned char * baseAddrB;
+ short count;unsigned int DMACommandCounter = 0;
+
+ if(bIsFirstFrame) GLinitialize();
+
+ GPUIsBusy;
+
+ lUsedAddr[0]=lUsedAddr[1]=lUsedAddr[2]=0xffffff;
+
+ baseAddrB = (unsigned char*) baseAddrL;
+
+ do
+ {
+ if(iGPUHeight==512) addr&=0x1FFFFC;
+
+ if(DMACommandCounter++ > 2000000) break;
+ if(CheckForEndlessLoop(addr)) break;
+
+ count = baseAddrB[addr+3];
+
+ dmaMem=addr+4;
+
+ if(count>0) GPUwriteDataMem(&baseAddrL[dmaMem>>2],count);
+
+ addr = baseAddrL[addr>>2]&0xffffff;
+ }
+ while (addr != 0xffffff);
+
+ GPUIsIdle;
+
+ return 0;
+}
+
+////////////////////////////////////////////////////////////////////////
+// show about dlg
+////////////////////////////////////////////////////////////////////////
+
+void CALLBACK GPUabout(void)
+{
+#ifdef _WINDOWS
+ HWND hWP=GetActiveWindow(); // to be sure
+ DialogBox(hInst,MAKEINTRESOURCE(IDD_DIALOG_ABOUT),
+ hWP,(DLGPROC)AboutDlgProc);
+#elif defined(_MACGL)
+
+ AboutDlgProc();
+#else
+
+ StartCfgTool("ABOUT");
+
+#endif
+}
+
+////////////////////////////////////////////////////////////////////////
+// We are ever fine ;)
+////////////////////////////////////////////////////////////////////////
+
+long CALLBACK GPUtest(void)
+{
+ // if test fails this function should return negative value for error (unable to continue)
+ // and positive value for warning (can continue but output might be crappy)
+
+ return 0;
+}
+
+////////////////////////////////////////////////////////////////////////
+// save state funcs
+////////////////////////////////////////////////////////////////////////
+
+typedef struct GPUFREEZETAG
+{
+ uint32_t ulFreezeVersion; // should be always 1 for now (set by main emu)
+ uint32_t ulStatus; // current gpu status
+ uint32_t ulControl[256]; // latest control register values
+ unsigned char psxVRam[1024*1024*2]; // current VRam image (full 2 MB for ZN)
+} GPUFreeze_t;
+
+////////////////////////////////////////////////////////////////////////
+
+long CALLBACK GPUfreeze(uint32_t ulGetFreezeData,GPUFreeze_t * pF)
+{
+ if(ulGetFreezeData==2)
+ {
+ int lSlotNum=*((int *)pF);
+ if(lSlotNum<0) return 0;
+ if(lSlotNum>8) return 0;
+ lSelectedSlot=lSlotNum+1;
+ return 1;
+ }
+
+ if(!pF) return 0;
+ if(pF->ulFreezeVersion!=1) return 0;
+
+ if(ulGetFreezeData==1)
+ {
+ pF->ulStatus=STATUSREG;
+ memcpy(pF->ulControl,ulStatusControl,256*sizeof(uint32_t));
+ memcpy(pF->psxVRam, psxVub, 1024*iGPUHeight*2);
+
+ return 1;
+ }
+
+ if(ulGetFreezeData!=0) return 0;
+
+ STATUSREG=pF->ulStatus;
+ memcpy(ulStatusControl,pF->ulControl,256*sizeof(uint32_t));
+ memcpy(psxVub, pF->psxVRam, 1024*iGPUHeight*2);
+
+ ResetTextureArea(TRUE);
+
+ GPUwriteStatus(ulStatusControl[0]);
+ GPUwriteStatus(ulStatusControl[1]);
+ GPUwriteStatus(ulStatusControl[2]);
+ GPUwriteStatus(ulStatusControl[3]);
+ GPUwriteStatus(ulStatusControl[8]);
+ GPUwriteStatus(ulStatusControl[6]);
+ GPUwriteStatus(ulStatusControl[7]);
+ GPUwriteStatus(ulStatusControl[5]);
+ GPUwriteStatus(ulStatusControl[4]);
+
+ return 1;
+}
+
+////////////////////////////////////////////////////////////////////////
+// special "emu infos" / "emu effects" functions
+////////////////////////////////////////////////////////////////////////
+
+//00 = black
+//01 = white
+//10 = red
+//11 = transparent
+
+unsigned char cFont[10][120]=
+{
+// 0
+{0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x05,0x54,0x00,0x00,
+ 0x80,0x00,0x14,0x05,0x00,0x00,
+ 0x80,0x00,0x14,0x05,0x00,0x00,
+ 0x80,0x00,0x14,0x05,0x00,0x00,
+ 0x80,0x00,0x14,0x05,0x00,0x00,
+ 0x80,0x00,0x14,0x05,0x00,0x00,
+ 0x80,0x00,0x14,0x05,0x00,0x00,
+ 0x80,0x00,0x14,0x05,0x00,0x00,
+ 0x80,0x00,0x14,0x05,0x00,0x00,
+ 0x80,0x00,0x05,0x54,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa
+},
+// 1
+{0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x50,0x00,0x00,
+ 0x80,0x00,0x05,0x50,0x00,0x00,
+ 0x80,0x00,0x00,0x50,0x00,0x00,
+ 0x80,0x00,0x00,0x50,0x00,0x00,
+ 0x80,0x00,0x00,0x50,0x00,0x00,
+ 0x80,0x00,0x00,0x50,0x00,0x00,
+ 0x80,0x00,0x00,0x50,0x00,0x00,
+ 0x80,0x00,0x00,0x50,0x00,0x00,
+ 0x80,0x00,0x00,0x50,0x00,0x00,
+ 0x80,0x00,0x05,0x55,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa
+},
+// 2
+{0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x05,0x54,0x00,0x00,
+ 0x80,0x00,0x14,0x05,0x00,0x00,
+ 0x80,0x00,0x00,0x05,0x00,0x00,
+ 0x80,0x00,0x00,0x05,0x00,0x00,
+ 0x80,0x00,0x00,0x14,0x00,0x00,
+ 0x80,0x00,0x00,0x50,0x00,0x00,
+ 0x80,0x00,0x01,0x40,0x00,0x00,
+ 0x80,0x00,0x05,0x00,0x00,0x00,
+ 0x80,0x00,0x14,0x00,0x00,0x00,
+ 0x80,0x00,0x15,0x55,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa
+},
+// 3
+{0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x05,0x54,0x00,0x00,
+ 0x80,0x00,0x14,0x05,0x00,0x00,
+ 0x80,0x00,0x00,0x05,0x00,0x00,
+ 0x80,0x00,0x00,0x05,0x00,0x00,
+ 0x80,0x00,0x01,0x54,0x00,0x00,
+ 0x80,0x00,0x00,0x05,0x00,0x00,
+ 0x80,0x00,0x00,0x05,0x00,0x00,
+ 0x80,0x00,0x00,0x05,0x00,0x00,
+ 0x80,0x00,0x14,0x05,0x00,0x00,
+ 0x80,0x00,0x05,0x54,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa
+},
+// 4
+{0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x14,0x00,0x00,
+ 0x80,0x00,0x00,0x54,0x00,0x00,
+ 0x80,0x00,0x01,0x54,0x00,0x00,
+ 0x80,0x00,0x01,0x54,0x00,0x00,
+ 0x80,0x00,0x05,0x14,0x00,0x00,
+ 0x80,0x00,0x14,0x14,0x00,0x00,
+ 0x80,0x00,0x15,0x55,0x00,0x00,
+ 0x80,0x00,0x00,0x14,0x00,0x00,
+ 0x80,0x00,0x00,0x14,0x00,0x00,
+ 0x80,0x00,0x00,0x55,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa
+},
+// 5
+{0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x15,0x55,0x00,0x00,
+ 0x80,0x00,0x14,0x00,0x00,0x00,
+ 0x80,0x00,0x14,0x00,0x00,0x00,
+ 0x80,0x00,0x14,0x00,0x00,0x00,
+ 0x80,0x00,0x15,0x54,0x00,0x00,
+ 0x80,0x00,0x00,0x05,0x00,0x00,
+ 0x80,0x00,0x00,0x05,0x00,0x00,
+ 0x80,0x00,0x00,0x05,0x00,0x00,
+ 0x80,0x00,0x14,0x05,0x00,0x00,
+ 0x80,0x00,0x05,0x54,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa
+},
+// 6
+{0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x01,0x54,0x00,0x00,
+ 0x80,0x00,0x05,0x00,0x00,0x00,
+ 0x80,0x00,0x14,0x00,0x00,0x00,
+ 0x80,0x00,0x14,0x00,0x00,0x00,
+ 0x80,0x00,0x15,0x54,0x00,0x00,
+ 0x80,0x00,0x15,0x05,0x00,0x00,
+ 0x80,0x00,0x14,0x05,0x00,0x00,
+ 0x80,0x00,0x14,0x05,0x00,0x00,
+ 0x80,0x00,0x14,0x05,0x00,0x00,
+ 0x80,0x00,0x05,0x54,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa
+},
+// 7
+{0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x15,0x55,0x00,0x00,
+ 0x80,0x00,0x14,0x05,0x00,0x00,
+ 0x80,0x00,0x00,0x14,0x00,0x00,
+ 0x80,0x00,0x00,0x14,0x00,0x00,
+ 0x80,0x00,0x00,0x50,0x00,0x00,
+ 0x80,0x00,0x00,0x50,0x00,0x00,
+ 0x80,0x00,0x01,0x40,0x00,0x00,
+ 0x80,0x00,0x01,0x40,0x00,0x00,
+ 0x80,0x00,0x05,0x00,0x00,0x00,
+ 0x80,0x00,0x05,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa
+},
+// 8
+{0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x05,0x54,0x00,0x00,
+ 0x80,0x00,0x14,0x05,0x00,0x00,
+ 0x80,0x00,0x14,0x05,0x00,0x00,
+ 0x80,0x00,0x14,0x05,0x00,0x00,
+ 0x80,0x00,0x05,0x54,0x00,0x00,
+ 0x80,0x00,0x14,0x05,0x00,0x00,
+ 0x80,0x00,0x14,0x05,0x00,0x00,
+ 0x80,0x00,0x14,0x05,0x00,0x00,
+ 0x80,0x00,0x14,0x05,0x00,0x00,
+ 0x80,0x00,0x05,0x54,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa
+},
+// 9
+{0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x05,0x54,0x00,0x00,
+ 0x80,0x00,0x14,0x05,0x00,0x00,
+ 0x80,0x00,0x14,0x05,0x00,0x00,
+ 0x80,0x00,0x14,0x05,0x00,0x00,
+ 0x80,0x00,0x14,0x15,0x00,0x00,
+ 0x80,0x00,0x05,0x55,0x00,0x00,
+ 0x80,0x00,0x00,0x05,0x00,0x00,
+ 0x80,0x00,0x00,0x05,0x00,0x00,
+ 0x80,0x00,0x00,0x14,0x00,0x00,
+ 0x80,0x00,0x05,0x50,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x00,0x00,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa
+}
+};
+
+////////////////////////////////////////////////////////////////////////
+
+void PaintPicDot(unsigned char * p,unsigned char c)
+{
+ if(c==0) {*p++=0x00;*p++=0x00;*p=0x00;return;}
+ if(c==1) {*p++=0xff;*p++=0xff;*p=0xff;return;}
+ if(c==2) {*p++=0x00;*p++=0x00;*p=0xff;return;}
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void CALLBACK GPUgetScreenPic(unsigned char * pMem)
+{
+ float XS,YS;int x,y,v;
+ unsigned char * ps, * px, * pf;
+ unsigned char c;
+
+ if(!pGfxCardScreen)
+ {
+ glPixelStorei(GL_PACK_ALIGNMENT,1);
+ pGfxCardScreen=(unsigned char *)malloc(iResX*iResY*4);
+ }
+
+ ps=pGfxCardScreen;
+
+ glReadBuffer(GL_FRONT);
+
+ glReadPixels(0,0,iResX,iResY,GL_RGB,GL_UNSIGNED_BYTE,ps);
+
+ glReadBuffer(GL_BACK);
+
+ XS=(float)iResX/128;
+ YS=(float)iResY/96;
+ pf=pMem;
+
+ for(y=96;y>0;y--)
+ {
+ for(x=0;x<128;x++)
+ {
+ px=ps+(3*((int)((float)x * XS))+
+ (3*iResX)*((int)((float)y*YS)));
+ *(pf+0)=*(px+2);
+ *(pf+1)=*(px+1);
+ *(pf+2)=*(px+0);
+ pf+=3;
+ }
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ // generic number/border painter
+
+ pf=pMem+(103*3);
+
+ for(y=0;y<20;y++)
+ {
+ for(x=0;x<6;x++)
+ {
+ c=cFont[lSelectedSlot][x+y*6];
+ v=(c&0xc0)>>6;
+ PaintPicDot(pf,(unsigned char)v);pf+=3; // paint the dots into the rect
+ v=(c&0x30)>>4;
+ PaintPicDot(pf,(unsigned char)v);pf+=3;
+ v=(c&0x0c)>>2;
+ PaintPicDot(pf,(unsigned char)v);pf+=3;
+ v=c&0x03;
+ PaintPicDot(pf,(unsigned char)v);pf+=3;
+ }
+ pf+=104*3;
+ }
+
+ pf=pMem;
+ for(x=0;x<128;x++)
+ {
+ *(pf+(95*128*3))=0x00;*pf++=0x00;
+ *(pf+(95*128*3))=0x00;*pf++=0x00;
+ *(pf+(95*128*3))=0xff;*pf++=0xff;
+ }
+ pf=pMem;
+ for(y=0;y<96;y++)
+ {
+ *(pf+(127*3))=0x00;*pf++=0x00;
+ *(pf+(127*3))=0x00;*pf++=0x00;
+ *(pf+(127*3))=0xff;*pf++=0xff;
+ pf+=127*3;
+ }
+
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void CALLBACK GPUshowScreenPic(unsigned char * pMem)
+{
+ DestroyPic();
+ if(pMem==0) return;
+ CreatePic(pMem);
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void CALLBACK GPUsetfix(uint32_t dwFixBits)
+{
+ dwEmuFixes=dwFixBits;
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void CALLBACK GPUvisualVibration(uint32_t iSmall, uint32_t iBig)
+{
+ int iVibVal;
+
+ if(PSXDisplay.DisplayModeNew.x) // calc min "shake pixel" from screen width
+ iVibVal=max(1,iResX/PSXDisplay.DisplayModeNew.x);
+ else iVibVal=1;
+ // big rumble: 4...15 sp ; small rumble 1...3 sp
+ if(iBig) iRumbleVal=max(4*iVibVal,min(15*iVibVal,((int)iBig *iVibVal)/10));
+ else iRumbleVal=max(1*iVibVal,min( 3*iVibVal,((int)iSmall*iVibVal)/10));
+
+ srand(timeGetTime()); // init rand (will be used in BufferSwap)
+
+ iRumbleTime=15; // let the rumble last 16 buffer swaps
+}
+
+////////////////////////////////////////////////////////////////////////
+// main emu can set display infos (A/M/G/D)
+////////////////////////////////////////////////////////////////////////
+
+void CALLBACK GPUdisplayFlags(uint32_t dwFlags)
+{
+ dwCoreFlags=dwFlags;
+}
+
+void CALLBACK GPUvBlank( int val )
+{
+ vBlank = val;
+}
diff --git a/plugins/peopsxgl/gpu.h b/plugins/peopsxgl/gpu.h index 19276781..f21433d9 100644 --- a/plugins/peopsxgl/gpu.h +++ b/plugins/peopsxgl/gpu.h @@ -1,43 +1,40 @@ -/*************************************************************************** - gpu.h - description - ------------------- - begin : Sun Mar 08 2009 - copyright : (C) 1999-2009 by Pete Bernert - web : www.pbernert.com - ***************************************************************************/ - -/*************************************************************************** - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. See also the license.txt file for * - * additional informations. * - * * - ***************************************************************************/ - -#ifndef _GPU_INTERNALS_H -#define _GPU_INTERNALS_H - -#define PRED(x) ((x << 3) & 0xF8) -#define PBLUE(x) ((x >> 2) & 0xF8) -#define PGREEN(x) ((x >> 7) & 0xF8) - -#define RED(x) (x & 0xff) -#define BLUE(x) ((x>>16) & 0xff) -#define GREEN(x) ((x>>8) & 0xff) -#define COLOR(x) (x & 0xffffff) - -void DoSnapShot(void); -void updateDisplay(void); -void updateFrontDisplay(void); -void SetAutoFrameCap(void); -void SetAspectRatio(void); -void CheckVRamRead(int x, int y, int dx, int dy,BOOL bFront); -void CheckVRamReadEx(int x, int y, int dx, int dy); -void SetFixes(void); - -#ifdef _WINDOWS -extern HGLRC GLCONTEXT; -#endif -#endif // _GPU_INTERNALS_H +/***************************************************************************
+ gpu.h - description
+ -------------------
+ begin : Sun Mar 08 2009
+ copyright : (C) 1999-2009 by Pete Bernert
+ web : www.pbernert.com
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. See also the license.txt file for *
+ * additional informations. *
+ * *
+ ***************************************************************************/
+
+#ifndef _GPU_INTERNALS_H
+#define _GPU_INTERNALS_H
+
+#define PRED(x) ((x << 3) & 0xF8)
+#define PBLUE(x) ((x >> 2) & 0xF8)
+#define PGREEN(x) ((x >> 7) & 0xF8)
+
+#define RED(x) (x & 0xff)
+#define BLUE(x) ((x>>16) & 0xff)
+#define GREEN(x) ((x>>8) & 0xff)
+#define COLOR(x) (x & 0xffffff)
+
+void DoSnapShot(void);
+void updateDisplay(void);
+void updateFrontDisplay(void);
+void SetAutoFrameCap(void);
+void SetAspectRatio(void);
+void CheckVRamRead(int x, int y, int dx, int dy,BOOL bFront);
+void CheckVRamReadEx(int x, int y, int dx, int dy);
+void SetFixes(void);
+
+#endif // _GPU_INTERNALS_H
diff --git a/plugins/peopsxgl/gpucfg/main.c b/plugins/peopsxgl/gpucfg/main.c index 67258fee..3d7d9d68 100644 --- a/plugins/peopsxgl/gpucfg/main.c +++ b/plugins/peopsxgl/gpucfg/main.c @@ -1,735 +1,735 @@ -#include <gtk/gtk.h> -#include <stdlib.h> -#include <string.h> - -#include "config.h" - -#ifdef ENABLE_NLS -#include <libintl.h> -#include <locale.h> -#endif - -// Widgets -GtkWidget *window, - *btnCancel, - *btnSave, - *spinXSize, - *spinYSize, - *chkKeepRatio, - *chkDithering, - *chkFullScreen, - *cbxTexQuality, - *cbxTexFiltering, - *cbxHiResTex, - *spinVRam, - *chkShowFPS, - *chkUseFPSLimit, - *vboxFPSLimit, - *radFPSLimitAuto, - *radFPSLimitManual, - *spinFPSLimit, - *chkUseFrameSkipping, - *cbxOffscreen, - *cbxFBTex, - *cbxFBAccess, - *chkMaskDetect, - *chkOpaquePass, - *chkAdvancedBlend, - *chkScanLines, - *spinScanLinesBlend, - *chkFastMdec, - *chk15bitMdec, - *chkLineMode, - *chkAntiAlias, - *chkOGLExtensions, - *chkScreenSmoothing, - *chkUseGameFixes, - *tblGameFixes, - *chkCfgFix1, - *chkCfgFix2, - *chkCfgFix4, - *chkCfgFix8, - *chkCfgFix16, - *chkCfgFix32, - *chkCfgFix64, - *chkCfgFix128, - *chkCfgFix256, - *chkCfgFix512, - *chkCfgFix1024, - *chkCfgFix2048, - *chkCfgFix4096, - *chkCfgFix8192, - *chkCfgFix16384, - *chkCfgFix32768, - *chkCfgFix65536, - *chkCfgFix131072, - *btnFast, - *btnBeautiful; - -// Save values to the config file -static void on_btnSave_clicked( GtkObject *object, gpointer user_data ) { - FILE *out; - out = fopen( "gpuPeopsMesaGL.cfg", "w+" ); - - if ( out != NULL ) { - - // Computes the 'fixes' bitfield - int cfgFixes = 0; - if ( gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( chkCfgFix1 ) ) ) { cfgFixes |= (1 << 0); } - if ( gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( chkCfgFix2 ) ) ) { cfgFixes |= (1 << 1); } - if ( gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( chkCfgFix4 ) ) ) { cfgFixes |= (1 << 2); } - if ( gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( chkCfgFix8 ) ) ) { cfgFixes |= (1 << 3); } - if ( gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( chkCfgFix16 ) ) ) { cfgFixes |= (1 << 4); } - if ( gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( chkCfgFix32 ) ) ) { cfgFixes |= (1 << 5); } - if ( gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( chkCfgFix64 ) ) ) { cfgFixes |= (1 << 6); } - if ( gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( chkCfgFix128 ) ) ) { cfgFixes |= (1 << 7); } - if ( gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( chkCfgFix256 ) ) ) { cfgFixes |= (1 << 8); } - if ( gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( chkCfgFix512 ) ) ) { cfgFixes |= (1 << 9); } - if ( gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( chkCfgFix1024 ) ) ) { cfgFixes |= (1 << 10); } - if ( gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( chkCfgFix2048 ) ) ) { cfgFixes |= (1 << 11); } - if ( gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( chkCfgFix4096 ) ) ) { cfgFixes |= (1 << 12); } - if ( gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( chkCfgFix8192 ) ) ) { cfgFixes |= (1 << 13); } - if ( gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( chkCfgFix16384 ) ) ) { cfgFixes |= (1 << 14); } - if ( gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( chkCfgFix32768 ) ) ) { cfgFixes |= (1 << 15); } - if ( gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( chkCfgFix65536 ) ) ) { cfgFixes |= (1 << 16); } - if ( gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( chkCfgFix131072 ) ) ) { cfgFixes |= (1 << 17); } - - // Print data to the config file - fprintf( out, "\nResX = %i", gtk_spin_button_get_value_as_int( GTK_SPIN_BUTTON( spinXSize ) ) ); - fprintf( out, "\nResY = %i", gtk_spin_button_get_value_as_int( GTK_SPIN_BUTTON( spinYSize ) ) ); - fprintf( out, "\nKeepRatio = %i", gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( chkKeepRatio ) ) ); - fprintf( out, "\nDithering = %i", gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( chkDithering ) ) ); - fprintf( out, "\nFullScreen = %i", gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( chkFullScreen ) ) ); - fprintf( out, "\nTexQuality = %i", gtk_combo_box_get_active( GTK_COMBO_BOX( cbxTexQuality ) ) ); - fprintf( out, "\nTexFilter = %i", gtk_combo_box_get_active( GTK_COMBO_BOX( cbxTexFiltering ) ) ); - fprintf( out, "\nHiResTextures = %i", gtk_combo_box_get_active( GTK_COMBO_BOX( cbxHiResTex ) ) ); - fprintf( out, "\nVRamSize = %i", gtk_spin_button_get_value_as_int( GTK_SPIN_BUTTON( spinVRam ) ) ); - fprintf( out, "\nShowFPS = %i", gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( chkShowFPS ) ) ); - fprintf( out, "\nUseFrameLimit = %i", gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( chkUseFPSLimit ) ) ); - fprintf( out, "\nFPSDetection = %i", gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( radFPSLimitAuto ) ) ); - fprintf( out, "\nFrameRate = %i", gtk_spin_button_get_value_as_int( GTK_SPIN_BUTTON( spinFPSLimit ) ) ); - fprintf( out, "\nUseFrameSkip = %i", gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( chkUseFrameSkipping ) ) ); - fprintf( out, "\nOffscreenDrawing = %i", gtk_combo_box_get_active( GTK_COMBO_BOX( cbxOffscreen ) ) ); - fprintf( out, "\nFrameTextures = %i", gtk_combo_box_get_active( GTK_COMBO_BOX( cbxFBTex ) ) ); - fprintf( out, "\nFrameAccess = %i", gtk_combo_box_get_active( GTK_COMBO_BOX( cbxFBAccess ) ) ); - fprintf( out, "\nMaskDetect = %i", gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( chkMaskDetect ) ) ); - fprintf( out, "\nOpaquePass = %i", gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( chkOpaquePass ) ) ); - fprintf( out, "\nAdvancedBlend = %i", gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( chkAdvancedBlend ) ) ); - fprintf( out, "\nScanLines = %i", gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( chkScanLines ) ) ); - fprintf( out, "\nScanLinesBlend = %i", gtk_spin_button_get_value_as_int( GTK_SPIN_BUTTON( spinScanLinesBlend ) ) ); - fprintf( out, "\nFastMdec = %i", gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( chkFastMdec ) ) ); - fprintf( out, "\n15bitMdec = %i", gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( chk15bitMdec ) ) ); - fprintf( out, "\nLineMode = %i", gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( chkLineMode ) ) ); - fprintf( out, "\nAntiAlias = %i", gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( chkAntiAlias ) ) ); - fprintf( out, "\nOGLExtensions = %i", gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( chkOGLExtensions ) ) ); - fprintf( out, "\nScreenSmoothing = %i", gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( chkScreenSmoothing ) ) ); - fprintf( out, "\nUseFixes = %i", gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( chkUseGameFixes ) ) ); - fprintf( out, "\nCfgFixes = %i", cfgFixes ); - - fclose( out ); - } - - gtk_main_quit(); -} - -// Autoconfiguration callbacks - -static void on_btnFast_clicked( GtkObject *object, gpointer user_data ) { - gtk_spin_button_set_value( GTK_SPIN_BUTTON( spinXSize ), 640 ); - gtk_spin_button_set_value( GTK_SPIN_BUTTON( spinYSize ), 480 ); - gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkKeepRatio ), 0 ); - gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkDithering ), 0 ); - gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkFullScreen ), 0 ); - gtk_combo_box_set_active( GTK_COMBO_BOX( cbxTexQuality ), 0 ); - gtk_combo_box_set_active( GTK_COMBO_BOX( cbxTexFiltering ), 0 ); - gtk_combo_box_set_active( GTK_COMBO_BOX( cbxHiResTex ), 0 ); - gtk_spin_button_set_value( GTK_SPIN_BUTTON( spinVRam ), 0 ); - gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkShowFPS ), 0 ); - gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkUseFPSLimit ), 1 ); - gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( radFPSLimitAuto ), 1 ); - gtk_spin_button_set_value( GTK_SPIN_BUTTON( spinFPSLimit ), 200 ); - gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkUseFrameSkipping ), 0 ); - gtk_combo_box_set_active( GTK_COMBO_BOX( cbxOffscreen ), 1 ); - gtk_combo_box_set_active( GTK_COMBO_BOX( cbxFBTex ), 1 ); - gtk_combo_box_set_active( GTK_COMBO_BOX( cbxFBAccess ), 0 ); - gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkMaskDetect ), 0 ); - gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkOpaquePass ), 1 ); - gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkAdvancedBlend ), 0 ); - gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkScanLines ), 0 ); - gtk_spin_button_set_value( GTK_SPIN_BUTTON( spinScanLinesBlend ), 0 ); - gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkFastMdec ), 1 ); - gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chk15bitMdec ), 1 ); - gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkLineMode ), 0 ); - gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkAntiAlias ), 0 ); - gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkOGLExtensions ), 1 ); - gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkScreenSmoothing ), 0 ); -} - -static void on_btnBeautiful_clicked( GtkObject *object, gpointer user_data ) { - gtk_spin_button_set_value( GTK_SPIN_BUTTON( spinXSize ), 640 ); - gtk_spin_button_set_value( GTK_SPIN_BUTTON( spinYSize ), 480 ); - gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkKeepRatio ), 0 ); - gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkDithering ), 0 ); - gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkFullScreen ), 0 ); - gtk_combo_box_set_active( GTK_COMBO_BOX( cbxTexQuality ), 3 ); - gtk_combo_box_set_active( GTK_COMBO_BOX( cbxTexFiltering ), 0 ); - gtk_combo_box_set_active( GTK_COMBO_BOX( cbxHiResTex ), 0 ); - gtk_spin_button_set_value( GTK_SPIN_BUTTON( spinVRam ), 0 ); - gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkShowFPS ), 0 ); - gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkUseFPSLimit ), 1 ); - gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( radFPSLimitAuto ), 1 ); - gtk_spin_button_set_value( GTK_SPIN_BUTTON( spinFPSLimit ), 200 ); - gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkUseFrameSkipping ), 0 ); - gtk_combo_box_set_active( GTK_COMBO_BOX( cbxOffscreen ), 3 ); - gtk_combo_box_set_active( GTK_COMBO_BOX( cbxFBTex ), 2 ); - gtk_combo_box_set_active( GTK_COMBO_BOX( cbxFBAccess ), 0 ); - gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkMaskDetect ), 1 ); - gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkOpaquePass ), 1 ); - gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkAdvancedBlend ), 1 ); - gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkScanLines ), 0 ); - gtk_spin_button_set_value( GTK_SPIN_BUTTON( spinScanLinesBlend ), 0 ); - gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkFastMdec ), 0 ); - gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chk15bitMdec ), 0 ); - gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkLineMode ), 0 ); - gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkAntiAlias ), 0 ); - gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkOGLExtensions ), 1 ); - gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkScreenSmoothing ), 0 ); -} - -// Callbacks used to toggle the sensitivity of some parts of the GUI - -static void on_chkUseGameFixes_toggled( GtkObject *object, gpointer user_data ) { - gtk_widget_set_sensitive( tblGameFixes, gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( chkUseGameFixes ) ) ); -} - -static void on_chkUseFPSLimit_toggled( GtkObject *object, gpointer user_data ) { - gtk_widget_set_sensitive( vboxFPSLimit, gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( chkUseFPSLimit ) ) ); -} - -static void on_radFPSLimitManual_toggled( GtkObject *object, gpointer user_data ) { - gtk_widget_set_sensitive( spinFPSLimit, gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( radFPSLimitManual ) ) ); -} - -static void on_chkScanLines_toggled( GtkObject *object, gpointer user_data ) { - gtk_widget_set_sensitive( spinScanLinesBlend, gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( chkScanLines ) ) ); -} - -/* Instanciates the GUI - Reads the config file - Sets widget states according to the config file - Connect callbacks to signals */ -int main( int argc, char **argv ) { - GtkBuilder *builder; - GError *error = NULL; - FILE *in; - char *pB, *p; - int len, val; - char t[256]; - -#ifdef ENABLE_NLS - setlocale (LC_ALL, ""); - bindtextdomain (GETTEXT_PACKAGE, LOCALE_DIR); - bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); - textdomain (GETTEXT_PACKAGE); -#endif - - gtk_set_locale(); - gtk_init( &argc, &argv ); - - builder = gtk_builder_new(); - - // Load the glade file - if ( !gtk_builder_add_from_file( builder, DATADIR "peopsxgl.ui", &error ) ) { - g_warning( "%s", error->message ); - g_free( error ); - return( 1 ); - } - - // Display the About dialog when the emulator ask for it - if ( argv[1] && strcmp( argv[1], "ABOUT" ) == 0 ) { - GtkWidget *widget; - const char *authors[]= {"Adapted from P.E.Op.S OpenGL GPU by Pete Bernert", NULL}; - - widget = gtk_about_dialog_new(); - gtk_about_dialog_set_name(GTK_ABOUT_DIALOG(widget), "OpenGL GPU Driver"); - gtk_about_dialog_set_version(GTK_ABOUT_DIALOG(widget), "1.18"); - gtk_about_dialog_set_authors(GTK_ABOUT_DIALOG(widget), authors); - gtk_about_dialog_set_website(GTK_ABOUT_DIALOG(widget), "http://pcsxr.codeplex.com/"); - - gtk_dialog_run(GTK_DIALOG(widget)); - gtk_widget_destroy(widget); - - return 0; - } - - // Get widgets from the glade file - window = GTK_WIDGET( gtk_builder_get_object( builder, "MainDialog" ) ); - btnCancel = GTK_WIDGET( gtk_builder_get_object( builder, "btnCancel" ) ); - btnSave = GTK_WIDGET( gtk_builder_get_object( builder, "btnSave" ) ); - spinXSize = GTK_WIDGET( gtk_builder_get_object( builder, "spinXSize" ) ); - spinYSize = GTK_WIDGET( gtk_builder_get_object( builder, "spinYSize" ) ); - chkKeepRatio = GTK_WIDGET( gtk_builder_get_object( builder, "chkKeepRatio" ) ); - chkDithering = GTK_WIDGET( gtk_builder_get_object( builder, "chkDithering" ) ); - chkFullScreen = GTK_WIDGET( gtk_builder_get_object( builder, "chkFullScreen" ) ); - cbxTexQuality = GTK_WIDGET( gtk_builder_get_object( builder, "cbxTexQuality" ) ); - cbxTexFiltering = GTK_WIDGET( gtk_builder_get_object( builder, "cbxTexFiltering" ) ); - cbxHiResTex = GTK_WIDGET( gtk_builder_get_object( builder, "cbxHiResTex" ) ); - spinVRam = GTK_WIDGET( gtk_builder_get_object( builder, "spinVRam" ) ); - chkShowFPS = GTK_WIDGET( gtk_builder_get_object( builder, "chkShowFPS" ) ); - chkUseFPSLimit = GTK_WIDGET( gtk_builder_get_object( builder, "chkUseFPSLimit" ) ); - vboxFPSLimit = GTK_WIDGET( gtk_builder_get_object( builder, "vboxFPSLimit" ) ); - radFPSLimitAuto = GTK_WIDGET( gtk_builder_get_object( builder, "radFPSLimitAuto" ) ); - radFPSLimitManual = GTK_WIDGET( gtk_builder_get_object( builder, "radFPSLimitManual" ) ); - spinFPSLimit = GTK_WIDGET( gtk_builder_get_object( builder, "spinFPSLimit" ) ); - chkUseFrameSkipping = GTK_WIDGET( gtk_builder_get_object( builder, "chkUseFrameSkipping" ) ); - cbxOffscreen = GTK_WIDGET( gtk_builder_get_object( builder, "cbxOffscreen" ) ); - cbxFBTex = GTK_WIDGET( gtk_builder_get_object( builder, "cbxFBTex" ) ); - cbxFBAccess = GTK_WIDGET( gtk_builder_get_object( builder, "cbxFBAccess" ) ); - chkMaskDetect = GTK_WIDGET( gtk_builder_get_object( builder, "chkMaskDetect" ) ); - chkOpaquePass = GTK_WIDGET( gtk_builder_get_object( builder, "chkOpaquePass" ) ); - chkAdvancedBlend = GTK_WIDGET( gtk_builder_get_object( builder, "chkAdvancedBlend" ) ); - chkScanLines = GTK_WIDGET( gtk_builder_get_object( builder, "chkScanLines" ) ); - spinScanLinesBlend = GTK_WIDGET( gtk_builder_get_object( builder, "spinScanLinesBlend" ) ); - chkFastMdec = GTK_WIDGET( gtk_builder_get_object( builder, "chkFastMdec" ) ); - chk15bitMdec = GTK_WIDGET( gtk_builder_get_object( builder, "chk15bitMdec" ) ); - chkLineMode = GTK_WIDGET( gtk_builder_get_object( builder, "chkLineMode" ) ); - chkAntiAlias = GTK_WIDGET( gtk_builder_get_object( builder, "chkAntiAlias" ) ); - chkOGLExtensions = GTK_WIDGET( gtk_builder_get_object( builder, "chkOGLExtensions" ) ); - chkScreenSmoothing = GTK_WIDGET( gtk_builder_get_object( builder, "chkScreenSmoothing" ) ); - chkUseGameFixes = GTK_WIDGET( gtk_builder_get_object( builder, "chkUseGameFixes" ) ); - tblGameFixes = GTK_WIDGET( gtk_builder_get_object( builder, "tblGameFixes" ) ); - chkCfgFix1 = GTK_WIDGET( gtk_builder_get_object( builder, "chkCfgFix1" ) ); - chkCfgFix2 = GTK_WIDGET( gtk_builder_get_object( builder, "chkCfgFix2" ) ); - chkCfgFix4 = GTK_WIDGET( gtk_builder_get_object( builder, "chkCfgFix4" ) ); - chkCfgFix8 = GTK_WIDGET( gtk_builder_get_object( builder, "chkCfgFix8" ) ); - chkCfgFix16 = GTK_WIDGET( gtk_builder_get_object( builder, "chkCfgFix16" ) ); - chkCfgFix32 = GTK_WIDGET( gtk_builder_get_object( builder, "chkCfgFix32" ) ); - chkCfgFix64 = GTK_WIDGET( gtk_builder_get_object( builder, "chkCfgFix64" ) ); - chkCfgFix128 = GTK_WIDGET( gtk_builder_get_object( builder, "chkCfgFix128" ) ); - chkCfgFix256 = GTK_WIDGET( gtk_builder_get_object( builder, "chkCfgFix256" ) ); - chkCfgFix512 = GTK_WIDGET( gtk_builder_get_object( builder, "chkCfgFix512" ) ); - chkCfgFix1024 = GTK_WIDGET( gtk_builder_get_object( builder, "chkCfgFix1024" ) ); - chkCfgFix2048 = GTK_WIDGET( gtk_builder_get_object( builder, "chkCfgFix2048" ) ); - chkCfgFix4096 = GTK_WIDGET( gtk_builder_get_object( builder, "chkCfgFix4096" ) ); - chkCfgFix8192 = GTK_WIDGET( gtk_builder_get_object( builder, "chkCfgFix8192" ) ); - chkCfgFix16384 = GTK_WIDGET( gtk_builder_get_object( builder, "chkCfgFix16384" ) ); - chkCfgFix32768 = GTK_WIDGET( gtk_builder_get_object( builder, "chkCfgFix32768" ) ); - chkCfgFix65536 = GTK_WIDGET( gtk_builder_get_object( builder, "chkCfgFix65536" ) ); - chkCfgFix131072 = GTK_WIDGET( gtk_builder_get_object( builder, "chkCfgFix131072" ) ); - btnFast = GTK_WIDGET( gtk_builder_get_object( builder, "btnFast" ) ); - btnBeautiful = GTK_WIDGET( gtk_builder_get_object( builder, "btnBeautiful" ) ); - - // Read the config file - in = fopen( "gpuPeopsMesaGL.cfg", "rb" ); - if ( in ) { - pB = (char *) malloc( 32767 ); - memset( pB, 0, 32767 ); - len = fread( pB, 1, 32767, in ); - fclose(in); - } - else pB = 0; - - val = 640; - if ( pB ) { - strcpy( t, "\nResX" ); - p = strstr( pB, t ); - if ( p ) { - p = strstr( p, "=" ); - len = 1; - val = atoi( p + len ); - } - } - gtk_spin_button_set_value( GTK_SPIN_BUTTON( spinXSize ), val ); - - val = 480; - if ( pB ) { - strcpy( t, "\nResY" ); - p = strstr( pB, t ); - if ( p ) { - p = strstr( p, "=" ); - len = 1; - val = atoi( p + len ); - } - } - gtk_spin_button_set_value( GTK_SPIN_BUTTON( spinYSize ), val ); - - val = 0; - if ( pB ) { - strcpy( t, "\nKeepRatio" ); - p = strstr( pB, t ); - if ( p ) { - p = strstr( p, "=" ); - len = 1; - val = atoi( p + len ); - } - } - gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkKeepRatio ), val ); - - val = 0; - if ( pB ) { - strcpy( t, "\nDithering" ); - p = strstr( pB, t ); - if ( p ) { - p = strstr( p, "=" ); - len = 1; - val = atoi( p + len ); - } - } - gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkDithering ), val ); - - val = 0; - if ( pB ) { - strcpy( t, "\nFullScreen" ); - p = strstr( pB, t ); - if ( p ) { - p = strstr( p, "=" ); - len = 1; - val = atoi( p + len ); - } - } - gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkFullScreen ), val ); - - val = 0; - if ( pB ) { - strcpy( t, "\nTexQuality" ); - p = strstr( pB, t ); - if ( p ) { - p = strstr( p, "=" ); - len = 1; - val = atoi( p + len ); - } - } - gtk_combo_box_set_active( GTK_COMBO_BOX( cbxTexQuality ), val ); - - val = 0; - if ( pB ) { - strcpy( t, "\nTexFilter" ); - p = strstr( pB, t ); - if ( p ) { - p = strstr( p, "=" ); - len = 1; - val = atoi( p + len ); - } - } - gtk_combo_box_set_active( GTK_COMBO_BOX( cbxTexFiltering ), val ); - - val = 0; - if ( pB ) { - strcpy( t, "\nHiResTextures" ); - p = strstr( pB, t ); - if ( p ) { - p = strstr( p, "=" ); - len = 1; - val = atoi( p + len ); - } - } - gtk_combo_box_set_active( GTK_COMBO_BOX( cbxHiResTex ), val ); - - val = 0; - if ( pB ) { - strcpy(t,"\nVRamSize"); - p = strstr( pB, t ); - if ( p ) { - p = strstr( p, "=" ); - len = 1; - val = atoi( p + len ); - } - } - gtk_spin_button_set_value( GTK_SPIN_BUTTON( spinVRam ), val ); - - val = 0; - if ( pB ) { - strcpy( t, "\nShowFPS" ); - p = strstr( pB, t ); - if ( p ) { - p = strstr( p, "=" ); - len = 1; - val = atoi( p + len ); - } - } - gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkShowFPS ), val ); - - val = 1; - if ( pB ) { - strcpy( t, "\nUseFrameLimit" ); - p = strstr( pB, t ); - if ( p ) { - p = strstr( p, "=" ); - len = 1; - val = atoi( p + len ); - } - } - gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkUseFPSLimit ), val ); - - val = 1; - if ( pB ) { - strcpy( t, "\nFPSDetection" ); - p = strstr( pB, t ); - if ( p ) { - p = strstr( p, "=" ); - len = 1; - val = atoi( p + len ); - } - } - gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( radFPSLimitAuto ), val ); - - val = 200; - if ( pB ) { - strcpy(t,"\nFrameRate"); - p = strstr( pB, t ); - if ( p ) { - p = strstr( p, "=" ); - len = 1; - val = atoi( p + len ); - } - } - gtk_spin_button_set_value( GTK_SPIN_BUTTON( spinFPSLimit ), val ); - - val = 0; - if ( pB ) { - strcpy( t, "\nUseFrameSkip" ); - p = strstr( pB, t ); - if ( p ) { - p = strstr( p, "=" ); - len = 1; - val = atoi( p + len ); - } - } - gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkUseFrameSkipping ), val ); - - val = 2; - if ( pB ) { - strcpy( t, "\nOffscreenDrawing" ); - p = strstr( pB, t ); - if ( p ) { - p = strstr( p, "=" ); - len = 1; - val = atoi( p + len ); - } - } - gtk_combo_box_set_active( GTK_COMBO_BOX( cbxOffscreen ), val ); - - val = 1; - if ( pB ) { - strcpy( t, "\nFrameTextures" ); - p = strstr( pB, t ); - if ( p ) { - p = strstr( p, "=" ); - len = 1; - val = atoi( p + len ); - } - } - gtk_combo_box_set_active( GTK_COMBO_BOX( cbxFBTex ), val ); - - val = 0; - if ( pB ) { - strcpy( t, "\nFrameAccess" ); - p = strstr( pB, t ); - if ( p ) { - p = strstr( p, "=" ); - len = 1; - val = atoi( p + len ); - } - } - gtk_combo_box_set_active( GTK_COMBO_BOX( cbxFBAccess ), val ); - - val = 0; - if ( pB ) { - strcpy( t, "\nMaskDetect" ); - p = strstr( pB, t ); - if ( p ) { - p = strstr( p, "=" ); - len = 1; - val = atoi( p + len ); - } - } - gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkMaskDetect ), val ); - - val = 1; - if ( pB ) { - strcpy( t, "\nOpaquePass" ); - p = strstr( pB, t ); - if ( p ) { - p = strstr( p, "=" ); - len = 1; - val = atoi( p + len ); - } - } - gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkOpaquePass ), val ); - - val = 0; - if ( pB ) { - strcpy( t, "\nAdvancedBlend" ); - p = strstr( pB, t ); - if ( p ) { - p = strstr( p, "=" ); - len = 1; - val = atoi( p + len ); - } - } - gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkAdvancedBlend ), val ); - - val = 0; - if ( pB ) { - strcpy( t, "\nScanLines" ); - p = strstr( pB, t ); - if ( p ) { - p = strstr( p, "=" ); - len = 1; - val = atoi( p + len ); - } - } - gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkScanLines ), val ); - - val = 0; - if ( pB ) { - strcpy(t,"\nScanLinesBlend"); - p = strstr( pB, t ); - if ( p ) { - p = strstr( p, "=" ); - len = 1; - val = atoi( p + len ); - } - } - gtk_spin_button_set_value( GTK_SPIN_BUTTON( spinScanLinesBlend ), val ); - - val = 1; - if ( pB ) { - strcpy( t, "\nFastMdec" ); - p = strstr( pB, t ); - if ( p ) { - p = strstr( p, "=" ); - len = 1; - val = atoi( p + len ); - } - } - gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkFastMdec ), val ); - - val = 0; - if ( pB ) { - strcpy( t, "\n15bitMdec" ); - p = strstr( pB, t ); - if ( p ) { - p = strstr( p, "=" ); - len = 1; - val = atoi( p + len ); - } - } - gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chk15bitMdec ), val ); - - val = 0; - if ( pB ) { - strcpy( t, "\nLineMode" ); - p = strstr( pB, t ); - if ( p ) { - p = strstr( p, "=" ); - len = 1; - val = atoi( p + len ); - } - } - gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkLineMode ), val ); - - val = 0; - if ( pB ) { - strcpy( t, "\nAntiAlias" ); - p = strstr( pB, t ); - if ( p ) { - p = strstr( p, "=" ); - len = 1; - val = atoi( p + len ); - } - } - gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkAntiAlias ), val ); - - val = 0; - if ( pB ) { - strcpy( t, "\nOGLExtensions" ); - p = strstr( pB, t ); - if ( p ) { - p = strstr( p, "=" ); - len = 1; - val = atoi( p + len ); - } - } - gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkOGLExtensions ), val ); - - val = 0; - if ( pB ) { - strcpy( t, "\nScreenSmoothing" ); - p = strstr( pB, t ); - if ( p ) { - p = strstr( p, "=" ); - len = 1; - val = atoi( p + len ); - } - } - gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkScreenSmoothing ), val ); - - val = 0; - if ( pB ) { - strcpy( t, "\nUseFixes" ); - p = strstr( pB, t ); - if ( p ) { - p = strstr( p, "=" ); - len = 1; - val = atoi( p + len ); - } - } - gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkUseGameFixes ), val ); - - val = 0; - if ( pB ) { - strcpy( t, "\nCfgFixes" ); - p = strstr( pB, t ); - if ( p ) { - p = strstr( p, "=" ); - len = 1; - val = atoi( p + len ); - } - } - if ( val & (1 << 17) ) { gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkCfgFix131072 ), TRUE ); } - if ( val & (1 << 16) ) { gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkCfgFix65536 ), TRUE ); } - if ( val & (1 << 15) ) { gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkCfgFix32768 ), TRUE ); } - if ( val & (1 << 14) ) { gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkCfgFix16384 ), TRUE ); } - if ( val & (1 << 13) ) { gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkCfgFix8192 ), TRUE ); } - if ( val & (1 << 12) ) { gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkCfgFix4096 ), TRUE ); } - if ( val & (1 << 11) ) { gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkCfgFix2048 ), TRUE ); } - if ( val & (1 << 10) ) { gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkCfgFix1024 ), TRUE ); } - if ( val & (1 << 9) ) { gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkCfgFix512 ), TRUE ); } - if ( val & (1 << 8) ) { gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkCfgFix256 ), TRUE ); } - if ( val & (1 << 7) ) { gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkCfgFix128 ), TRUE ); } - if ( val & (1 << 6) ) { gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkCfgFix64 ), TRUE ); } - if ( val & (1 << 5) ) { gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkCfgFix32 ), TRUE ); } - if ( val & (1 << 4) ) { gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkCfgFix16 ), TRUE ); } - if ( val & (1 << 3) ) { gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkCfgFix8 ), TRUE ); } - if ( val & (1 << 2) ) { gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkCfgFix4 ), TRUE ); } - if ( val & (1 << 1) ) { gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkCfgFix2 ), TRUE ); } - if ( val & (1 << 0) ) { gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkCfgFix1 ), TRUE ); } - - gtk_builder_connect_signals( builder, NULL ); - - g_object_unref( G_OBJECT( builder ) ); - - // Connect callbacks to signals - gtk_signal_connect( GTK_OBJECT( window ), "destroy", G_CALLBACK( gtk_main_quit ), NULL ); - gtk_signal_connect( GTK_OBJECT( btnCancel ), "clicked", G_CALLBACK( gtk_main_quit ), NULL ); - gtk_signal_connect( GTK_OBJECT( btnSave ), "clicked", G_CALLBACK( on_btnSave_clicked ), NULL ); - gtk_signal_connect( GTK_OBJECT( chkUseGameFixes ), "toggled", G_CALLBACK( on_chkUseGameFixes_toggled ), NULL ); - gtk_signal_connect( GTK_OBJECT( chkUseFPSLimit ), "toggled", G_CALLBACK( on_chkUseFPSLimit_toggled ), NULL ); - gtk_signal_connect( GTK_OBJECT( radFPSLimitManual ), "toggled", G_CALLBACK( on_radFPSLimitManual_toggled ), NULL ); - gtk_signal_connect( GTK_OBJECT( chkScanLines ), "toggled", G_CALLBACK( on_chkScanLines_toggled ), NULL ); - gtk_signal_connect( GTK_OBJECT( btnFast ), "clicked", G_CALLBACK( on_btnFast_clicked ), NULL ); - gtk_signal_connect( GTK_OBJECT( btnBeautiful ), "clicked", G_CALLBACK( on_btnBeautiful_clicked ), NULL ); - - // Call some callbacks to ensure widget state consistency - on_chkUseGameFixes_toggled( GTK_OBJECT( chkUseGameFixes ), NULL ); - on_chkUseFPSLimit_toggled( GTK_OBJECT( chkUseFPSLimit ), NULL ); - on_radFPSLimitManual_toggled( GTK_OBJECT( radFPSLimitManual ), NULL ); - on_chkScanLines_toggled( GTK_OBJECT( chkScanLines ), NULL ); - - gtk_widget_show( window ); - - gtk_main(); - - return 0; -} +#include <gtk/gtk.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "config.h"
+
+#ifdef ENABLE_NLS
+#include <libintl.h>
+#include <locale.h>
+#endif
+
+// Widgets
+GtkWidget *window,
+ *btnCancel,
+ *btnSave,
+ *spinXSize,
+ *spinYSize,
+ *chkKeepRatio,
+ *chkDithering,
+ *chkFullScreen,
+ *cbxTexQuality,
+ *cbxTexFiltering,
+ *cbxHiResTex,
+ *spinVRam,
+ *chkShowFPS,
+ *chkUseFPSLimit,
+ *vboxFPSLimit,
+ *radFPSLimitAuto,
+ *radFPSLimitManual,
+ *spinFPSLimit,
+ *chkUseFrameSkipping,
+ *cbxOffscreen,
+ *cbxFBTex,
+ *cbxFBAccess,
+ *chkMaskDetect,
+ *chkOpaquePass,
+ *chkAdvancedBlend,
+ *chkScanLines,
+ *spinScanLinesBlend,
+ *chkFastMdec,
+ *chk15bitMdec,
+ *chkLineMode,
+ *chkAntiAlias,
+ *chkOGLExtensions,
+ *chkScreenSmoothing,
+ *chkUseGameFixes,
+ *tblGameFixes,
+ *chkCfgFix1,
+ *chkCfgFix2,
+ *chkCfgFix4,
+ *chkCfgFix8,
+ *chkCfgFix16,
+ *chkCfgFix32,
+ *chkCfgFix64,
+ *chkCfgFix128,
+ *chkCfgFix256,
+ *chkCfgFix512,
+ *chkCfgFix1024,
+ *chkCfgFix2048,
+ *chkCfgFix4096,
+ *chkCfgFix8192,
+ *chkCfgFix16384,
+ *chkCfgFix32768,
+ *chkCfgFix65536,
+ *chkCfgFix131072,
+ *btnFast,
+ *btnBeautiful;
+
+// Save values to the config file
+void on_btnSave_clicked( GtkObject *object, gpointer user_data ) {
+ FILE *out;
+ out = fopen( "gpuPeopsMesaGL.cfg", "w+" );
+
+ if ( out != NULL ) {
+
+ // Computes the 'fixes' bitfield
+ int cfgFixes = 0;
+ if ( gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( chkCfgFix1 ) ) ) { cfgFixes |= (1 << 0); }
+ if ( gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( chkCfgFix2 ) ) ) { cfgFixes |= (1 << 1); }
+ if ( gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( chkCfgFix4 ) ) ) { cfgFixes |= (1 << 2); }
+ if ( gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( chkCfgFix8 ) ) ) { cfgFixes |= (1 << 3); }
+ if ( gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( chkCfgFix16 ) ) ) { cfgFixes |= (1 << 4); }
+ if ( gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( chkCfgFix32 ) ) ) { cfgFixes |= (1 << 5); }
+ if ( gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( chkCfgFix64 ) ) ) { cfgFixes |= (1 << 6); }
+ if ( gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( chkCfgFix128 ) ) ) { cfgFixes |= (1 << 7); }
+ if ( gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( chkCfgFix256 ) ) ) { cfgFixes |= (1 << 8); }
+ if ( gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( chkCfgFix512 ) ) ) { cfgFixes |= (1 << 9); }
+ if ( gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( chkCfgFix1024 ) ) ) { cfgFixes |= (1 << 10); }
+ if ( gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( chkCfgFix2048 ) ) ) { cfgFixes |= (1 << 11); }
+ if ( gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( chkCfgFix4096 ) ) ) { cfgFixes |= (1 << 12); }
+ if ( gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( chkCfgFix8192 ) ) ) { cfgFixes |= (1 << 13); }
+ if ( gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( chkCfgFix16384 ) ) ) { cfgFixes |= (1 << 14); }
+ if ( gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( chkCfgFix32768 ) ) ) { cfgFixes |= (1 << 15); }
+ if ( gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( chkCfgFix65536 ) ) ) { cfgFixes |= (1 << 16); }
+ if ( gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( chkCfgFix131072 ) ) ) { cfgFixes |= (1 << 17); }
+
+ // Print data to the config file
+ fprintf( out, "\nResX = %i", gtk_spin_button_get_value_as_int( GTK_SPIN_BUTTON( spinXSize ) ) );
+ fprintf( out, "\nResY = %i", gtk_spin_button_get_value_as_int( GTK_SPIN_BUTTON( spinYSize ) ) );
+ fprintf( out, "\nKeepRatio = %i", gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( chkKeepRatio ) ) );
+ fprintf( out, "\nDithering = %i", gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( chkDithering ) ) );
+ fprintf( out, "\nFullScreen = %i", gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( chkFullScreen ) ) );
+ fprintf( out, "\nTexQuality = %i", gtk_combo_box_get_active( GTK_COMBO_BOX( cbxTexQuality ) ) );
+ fprintf( out, "\nTexFilter = %i", gtk_combo_box_get_active( GTK_COMBO_BOX( cbxTexFiltering ) ) );
+ fprintf( out, "\nHiResTextures = %i", gtk_combo_box_get_active( GTK_COMBO_BOX( cbxHiResTex ) ) );
+ fprintf( out, "\nVRamSize = %i", gtk_spin_button_get_value_as_int( GTK_SPIN_BUTTON( spinVRam ) ) );
+ fprintf( out, "\nShowFPS = %i", gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( chkShowFPS ) ) );
+ fprintf( out, "\nUseFrameLimit = %i", gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( chkUseFPSLimit ) ) );
+ fprintf( out, "\nFPSDetection = %i", gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( radFPSLimitAuto ) ) );
+ fprintf( out, "\nFrameRate = %i", gtk_spin_button_get_value_as_int( GTK_SPIN_BUTTON( spinFPSLimit ) ) );
+ fprintf( out, "\nUseFrameSkip = %i", gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( chkUseFrameSkipping ) ) );
+ fprintf( out, "\nOffscreenDrawing = %i", gtk_combo_box_get_active( GTK_COMBO_BOX( cbxOffscreen ) ) );
+ fprintf( out, "\nFrameTextures = %i", gtk_combo_box_get_active( GTK_COMBO_BOX( cbxFBTex ) ) );
+ fprintf( out, "\nFrameAccess = %i", gtk_combo_box_get_active( GTK_COMBO_BOX( cbxFBAccess ) ) );
+ fprintf( out, "\nMaskDetect = %i", gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( chkMaskDetect ) ) );
+ fprintf( out, "\nOpaquePass = %i", gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( chkOpaquePass ) ) );
+ fprintf( out, "\nAdvancedBlend = %i", gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( chkAdvancedBlend ) ) );
+ fprintf( out, "\nScanLines = %i", gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( chkScanLines ) ) );
+ fprintf( out, "\nScanLinesBlend = %i", gtk_spin_button_get_value_as_int( GTK_SPIN_BUTTON( spinScanLinesBlend ) ) );
+ fprintf( out, "\nFastMdec = %i", gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( chkFastMdec ) ) );
+ fprintf( out, "\n15bitMdec = %i", gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( chk15bitMdec ) ) );
+ fprintf( out, "\nLineMode = %i", gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( chkLineMode ) ) );
+ fprintf( out, "\nAntiAlias = %i", gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( chkAntiAlias ) ) );
+ fprintf( out, "\nOGLExtensions = %i", gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( chkOGLExtensions ) ) );
+ fprintf( out, "\nScreenSmoothing = %i", gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( chkScreenSmoothing ) ) );
+ fprintf( out, "\nUseFixes = %i", gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( chkUseGameFixes ) ) );
+ fprintf( out, "\nCfgFixes = %i", cfgFixes );
+
+ fclose( out );
+ }
+
+ gtk_main_quit();
+}
+
+// Autoconfiguration callbacks
+
+void on_btnFast_clicked( GtkObject *object, gpointer user_data ) {
+ gtk_spin_button_set_value( GTK_SPIN_BUTTON( spinXSize ), 640 );
+ gtk_spin_button_set_value( GTK_SPIN_BUTTON( spinYSize ), 480 );
+ gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkKeepRatio ), 0 );
+ gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkDithering ), 0 );
+ gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkFullScreen ), 0 );
+ gtk_combo_box_set_active( GTK_COMBO_BOX( cbxTexQuality ), 0 );
+ gtk_combo_box_set_active( GTK_COMBO_BOX( cbxTexFiltering ), 0 );
+ gtk_combo_box_set_active( GTK_COMBO_BOX( cbxHiResTex ), 0 );
+ gtk_spin_button_set_value( GTK_SPIN_BUTTON( spinVRam ), 0 );
+ gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkShowFPS ), 0 );
+ gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkUseFPSLimit ), 1 );
+ gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( radFPSLimitAuto ), 1 );
+ gtk_spin_button_set_value( GTK_SPIN_BUTTON( spinFPSLimit ), 200 );
+ gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkUseFrameSkipping ), 0 );
+ gtk_combo_box_set_active( GTK_COMBO_BOX( cbxOffscreen ), 1 );
+ gtk_combo_box_set_active( GTK_COMBO_BOX( cbxFBTex ), 1 );
+ gtk_combo_box_set_active( GTK_COMBO_BOX( cbxFBAccess ), 0 );
+ gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkMaskDetect ), 0 );
+ gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkOpaquePass ), 1 );
+ gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkAdvancedBlend ), 0 );
+ gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkScanLines ), 0 );
+ gtk_spin_button_set_value( GTK_SPIN_BUTTON( spinScanLinesBlend ), 0 );
+ gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkFastMdec ), 1 );
+ gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chk15bitMdec ), 1 );
+ gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkLineMode ), 0 );
+ gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkAntiAlias ), 0 );
+ gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkOGLExtensions ), 1 );
+ gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkScreenSmoothing ), 0 );
+}
+
+void on_btnBeautiful_clicked( GtkObject *object, gpointer user_data ) {
+ gtk_spin_button_set_value( GTK_SPIN_BUTTON( spinXSize ), 640 );
+ gtk_spin_button_set_value( GTK_SPIN_BUTTON( spinYSize ), 480 );
+ gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkKeepRatio ), 0 );
+ gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkDithering ), 0 );
+ gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkFullScreen ), 0 );
+ gtk_combo_box_set_active( GTK_COMBO_BOX( cbxTexQuality ), 3 );
+ gtk_combo_box_set_active( GTK_COMBO_BOX( cbxTexFiltering ), 0 );
+ gtk_combo_box_set_active( GTK_COMBO_BOX( cbxHiResTex ), 0 );
+ gtk_spin_button_set_value( GTK_SPIN_BUTTON( spinVRam ), 0 );
+ gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkShowFPS ), 0 );
+ gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkUseFPSLimit ), 1 );
+ gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( radFPSLimitAuto ), 1 );
+ gtk_spin_button_set_value( GTK_SPIN_BUTTON( spinFPSLimit ), 200 );
+ gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkUseFrameSkipping ), 0 );
+ gtk_combo_box_set_active( GTK_COMBO_BOX( cbxOffscreen ), 3 );
+ gtk_combo_box_set_active( GTK_COMBO_BOX( cbxFBTex ), 2 );
+ gtk_combo_box_set_active( GTK_COMBO_BOX( cbxFBAccess ), 0 );
+ gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkMaskDetect ), 1 );
+ gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkOpaquePass ), 1 );
+ gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkAdvancedBlend ), 1 );
+ gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkScanLines ), 0 );
+ gtk_spin_button_set_value( GTK_SPIN_BUTTON( spinScanLinesBlend ), 0 );
+ gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkFastMdec ), 0 );
+ gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chk15bitMdec ), 0 );
+ gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkLineMode ), 0 );
+ gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkAntiAlias ), 0 );
+ gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkOGLExtensions ), 1 );
+ gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkScreenSmoothing ), 0 );
+}
+
+// Callbacks used to toggle the sensitivity of some parts of the GUI
+
+void on_chkUseGameFixes_toggled( GtkObject *object, gpointer user_data ) {
+ gtk_widget_set_sensitive( tblGameFixes, gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( chkUseGameFixes ) ) );
+}
+
+void on_chkUseFPSLimit_toggled( GtkObject *object, gpointer user_data ) {
+ gtk_widget_set_sensitive( vboxFPSLimit, gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( chkUseFPSLimit ) ) );
+}
+
+void on_radFPSLimitManual_toggled( GtkObject *object, gpointer user_data ) {
+ gtk_widget_set_sensitive( spinFPSLimit, gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( radFPSLimitManual ) ) );
+}
+
+void on_chkScanLines_toggled( GtkObject *object, gpointer user_data ) {
+ gtk_widget_set_sensitive( spinScanLinesBlend, gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( chkScanLines ) ) );
+}
+
+/* Instanciates the GUI
+ Reads the config file
+ Sets widget states according to the config file
+ Connect callbacks to signals */
+int main( int argc, char **argv ) {
+ GtkBuilder *builder;
+ GError *error = NULL;
+ FILE *in;
+ char *pB, *p;
+ int len, val;
+ char t[256];
+
+#ifdef ENABLE_NLS
+ setlocale (LC_ALL, "");
+ bindtextdomain (GETTEXT_PACKAGE, LOCALE_DIR);
+ bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
+ textdomain (GETTEXT_PACKAGE);
+#endif
+
+ gtk_set_locale();
+ gtk_init( &argc, &argv );
+
+ builder = gtk_builder_new();
+
+ // Load the glade file
+ if ( !gtk_builder_add_from_file( builder, DATADIR "peopsxgl.ui", &error ) ) {
+ g_warning( "%s", error->message );
+ g_free( error );
+ return( 1 );
+ }
+
+ // Display the About dialog when the emulator ask for it
+ if ( argv[1] && strcmp( argv[1], "ABOUT" ) == 0 ) {
+ GtkWidget *widget;
+ const char *authors[]= {"Adapted from P.E.Op.S OpenGL GPU by Pete Bernert", NULL};
+
+ widget = gtk_about_dialog_new();
+ gtk_about_dialog_set_name(GTK_ABOUT_DIALOG(widget), "OpenGL GPU Driver");
+ gtk_about_dialog_set_version(GTK_ABOUT_DIALOG(widget), "1.18");
+ gtk_about_dialog_set_authors(GTK_ABOUT_DIALOG(widget), authors);
+ gtk_about_dialog_set_website(GTK_ABOUT_DIALOG(widget), "http://pcsxr.codeplex.com/");
+
+ gtk_dialog_run(GTK_DIALOG(widget));
+ gtk_widget_destroy(widget);
+
+ return 0;
+ }
+
+ // Get widgets from the glade file
+ window = GTK_WIDGET( gtk_builder_get_object( builder, "MainDialog" ) );
+ btnCancel = GTK_WIDGET( gtk_builder_get_object( builder, "btnCancel" ) );
+ btnSave = GTK_WIDGET( gtk_builder_get_object( builder, "btnSave" ) );
+ spinXSize = GTK_WIDGET( gtk_builder_get_object( builder, "spinXSize" ) );
+ spinYSize = GTK_WIDGET( gtk_builder_get_object( builder, "spinYSize" ) );
+ chkKeepRatio = GTK_WIDGET( gtk_builder_get_object( builder, "chkKeepRatio" ) );
+ chkDithering = GTK_WIDGET( gtk_builder_get_object( builder, "chkDithering" ) );
+ chkFullScreen = GTK_WIDGET( gtk_builder_get_object( builder, "chkFullScreen" ) );
+ cbxTexQuality = GTK_WIDGET( gtk_builder_get_object( builder, "cbxTexQuality" ) );
+ cbxTexFiltering = GTK_WIDGET( gtk_builder_get_object( builder, "cbxTexFiltering" ) );
+ cbxHiResTex = GTK_WIDGET( gtk_builder_get_object( builder, "cbxHiResTex" ) );
+ spinVRam = GTK_WIDGET( gtk_builder_get_object( builder, "spinVRam" ) );
+ chkShowFPS = GTK_WIDGET( gtk_builder_get_object( builder, "chkShowFPS" ) );
+ chkUseFPSLimit = GTK_WIDGET( gtk_builder_get_object( builder, "chkUseFPSLimit" ) );
+ vboxFPSLimit = GTK_WIDGET( gtk_builder_get_object( builder, "vboxFPSLimit" ) );
+ radFPSLimitAuto = GTK_WIDGET( gtk_builder_get_object( builder, "radFPSLimitAuto" ) );
+ radFPSLimitManual = GTK_WIDGET( gtk_builder_get_object( builder, "radFPSLimitManual" ) );
+ spinFPSLimit = GTK_WIDGET( gtk_builder_get_object( builder, "spinFPSLimit" ) );
+ chkUseFrameSkipping = GTK_WIDGET( gtk_builder_get_object( builder, "chkUseFrameSkipping" ) );
+ cbxOffscreen = GTK_WIDGET( gtk_builder_get_object( builder, "cbxOffscreen" ) );
+ cbxFBTex = GTK_WIDGET( gtk_builder_get_object( builder, "cbxFBTex" ) );
+ cbxFBAccess = GTK_WIDGET( gtk_builder_get_object( builder, "cbxFBAccess" ) );
+ chkMaskDetect = GTK_WIDGET( gtk_builder_get_object( builder, "chkMaskDetect" ) );
+ chkOpaquePass = GTK_WIDGET( gtk_builder_get_object( builder, "chkOpaquePass" ) );
+ chkAdvancedBlend = GTK_WIDGET( gtk_builder_get_object( builder, "chkAdvancedBlend" ) );
+ chkScanLines = GTK_WIDGET( gtk_builder_get_object( builder, "chkScanLines" ) );
+ spinScanLinesBlend = GTK_WIDGET( gtk_builder_get_object( builder, "spinScanLinesBlend" ) );
+ chkFastMdec = GTK_WIDGET( gtk_builder_get_object( builder, "chkFastMdec" ) );
+ chk15bitMdec = GTK_WIDGET( gtk_builder_get_object( builder, "chk15bitMdec" ) );
+ chkLineMode = GTK_WIDGET( gtk_builder_get_object( builder, "chkLineMode" ) );
+ chkAntiAlias = GTK_WIDGET( gtk_builder_get_object( builder, "chkAntiAlias" ) );
+ chkOGLExtensions = GTK_WIDGET( gtk_builder_get_object( builder, "chkOGLExtensions" ) );
+ chkScreenSmoothing = GTK_WIDGET( gtk_builder_get_object( builder, "chkScreenSmoothing" ) );
+ chkUseGameFixes = GTK_WIDGET( gtk_builder_get_object( builder, "chkUseGameFixes" ) );
+ tblGameFixes = GTK_WIDGET( gtk_builder_get_object( builder, "tblGameFixes" ) );
+ chkCfgFix1 = GTK_WIDGET( gtk_builder_get_object( builder, "chkCfgFix1" ) );
+ chkCfgFix2 = GTK_WIDGET( gtk_builder_get_object( builder, "chkCfgFix2" ) );
+ chkCfgFix4 = GTK_WIDGET( gtk_builder_get_object( builder, "chkCfgFix4" ) );
+ chkCfgFix8 = GTK_WIDGET( gtk_builder_get_object( builder, "chkCfgFix8" ) );
+ chkCfgFix16 = GTK_WIDGET( gtk_builder_get_object( builder, "chkCfgFix16" ) );
+ chkCfgFix32 = GTK_WIDGET( gtk_builder_get_object( builder, "chkCfgFix32" ) );
+ chkCfgFix64 = GTK_WIDGET( gtk_builder_get_object( builder, "chkCfgFix64" ) );
+ chkCfgFix128 = GTK_WIDGET( gtk_builder_get_object( builder, "chkCfgFix128" ) );
+ chkCfgFix256 = GTK_WIDGET( gtk_builder_get_object( builder, "chkCfgFix256" ) );
+ chkCfgFix512 = GTK_WIDGET( gtk_builder_get_object( builder, "chkCfgFix512" ) );
+ chkCfgFix1024 = GTK_WIDGET( gtk_builder_get_object( builder, "chkCfgFix1024" ) );
+ chkCfgFix2048 = GTK_WIDGET( gtk_builder_get_object( builder, "chkCfgFix2048" ) );
+ chkCfgFix4096 = GTK_WIDGET( gtk_builder_get_object( builder, "chkCfgFix4096" ) );
+ chkCfgFix8192 = GTK_WIDGET( gtk_builder_get_object( builder, "chkCfgFix8192" ) );
+ chkCfgFix16384 = GTK_WIDGET( gtk_builder_get_object( builder, "chkCfgFix16384" ) );
+ chkCfgFix32768 = GTK_WIDGET( gtk_builder_get_object( builder, "chkCfgFix32768" ) );
+ chkCfgFix65536 = GTK_WIDGET( gtk_builder_get_object( builder, "chkCfgFix65536" ) );
+ chkCfgFix131072 = GTK_WIDGET( gtk_builder_get_object( builder, "chkCfgFix131072" ) );
+ btnFast = GTK_WIDGET( gtk_builder_get_object( builder, "btnFast" ) );
+ btnBeautiful = GTK_WIDGET( gtk_builder_get_object( builder, "btnBeautiful" ) );
+
+ // Read the config file
+ in = fopen( "gpuPeopsMesaGL.cfg", "rb" );
+ if ( in ) {
+ pB = (char *) malloc( 32767 );
+ memset( pB, 0, 32767 );
+ len = fread( pB, 1, 32767, in );
+ fclose(in);
+ }
+ else pB = 0;
+
+ val = 640;
+ if ( pB ) {
+ strcpy( t, "\nResX" );
+ p = strstr( pB, t );
+ if ( p ) {
+ p = strstr( p, "=" );
+ len = 1;
+ val = atoi( p + len );
+ }
+ }
+ gtk_spin_button_set_value( GTK_SPIN_BUTTON( spinXSize ), val );
+
+ val = 480;
+ if ( pB ) {
+ strcpy( t, "\nResY" );
+ p = strstr( pB, t );
+ if ( p ) {
+ p = strstr( p, "=" );
+ len = 1;
+ val = atoi( p + len );
+ }
+ }
+ gtk_spin_button_set_value( GTK_SPIN_BUTTON( spinYSize ), val );
+
+ val = 0;
+ if ( pB ) {
+ strcpy( t, "\nKeepRatio" );
+ p = strstr( pB, t );
+ if ( p ) {
+ p = strstr( p, "=" );
+ len = 1;
+ val = atoi( p + len );
+ }
+ }
+ gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkKeepRatio ), val );
+
+ val = 0;
+ if ( pB ) {
+ strcpy( t, "\nDithering" );
+ p = strstr( pB, t );
+ if ( p ) {
+ p = strstr( p, "=" );
+ len = 1;
+ val = atoi( p + len );
+ }
+ }
+ gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkDithering ), val );
+
+ val = 0;
+ if ( pB ) {
+ strcpy( t, "\nFullScreen" );
+ p = strstr( pB, t );
+ if ( p ) {
+ p = strstr( p, "=" );
+ len = 1;
+ val = atoi( p + len );
+ }
+ }
+ gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkFullScreen ), val );
+
+ val = 0;
+ if ( pB ) {
+ strcpy( t, "\nTexQuality" );
+ p = strstr( pB, t );
+ if ( p ) {
+ p = strstr( p, "=" );
+ len = 1;
+ val = atoi( p + len );
+ }
+ }
+ gtk_combo_box_set_active( GTK_COMBO_BOX( cbxTexQuality ), val );
+
+ val = 0;
+ if ( pB ) {
+ strcpy( t, "\nTexFilter" );
+ p = strstr( pB, t );
+ if ( p ) {
+ p = strstr( p, "=" );
+ len = 1;
+ val = atoi( p + len );
+ }
+ }
+ gtk_combo_box_set_active( GTK_COMBO_BOX( cbxTexFiltering ), val );
+
+ val = 0;
+ if ( pB ) {
+ strcpy( t, "\nHiResTextures" );
+ p = strstr( pB, t );
+ if ( p ) {
+ p = strstr( p, "=" );
+ len = 1;
+ val = atoi( p + len );
+ }
+ }
+ gtk_combo_box_set_active( GTK_COMBO_BOX( cbxHiResTex ), val );
+
+ val = 0;
+ if ( pB ) {
+ strcpy(t,"\nVRamSize");
+ p = strstr( pB, t );
+ if ( p ) {
+ p = strstr( p, "=" );
+ len = 1;
+ val = atoi( p + len );
+ }
+ }
+ gtk_spin_button_set_value( GTK_SPIN_BUTTON( spinVRam ), val );
+
+ val = 0;
+ if ( pB ) {
+ strcpy( t, "\nShowFPS" );
+ p = strstr( pB, t );
+ if ( p ) {
+ p = strstr( p, "=" );
+ len = 1;
+ val = atoi( p + len );
+ }
+ }
+ gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkShowFPS ), val );
+
+ val = 1;
+ if ( pB ) {
+ strcpy( t, "\nUseFrameLimit" );
+ p = strstr( pB, t );
+ if ( p ) {
+ p = strstr( p, "=" );
+ len = 1;
+ val = atoi( p + len );
+ }
+ }
+ gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkUseFPSLimit ), val );
+
+ val = 1;
+ if ( pB ) {
+ strcpy( t, "\nFPSDetection" );
+ p = strstr( pB, t );
+ if ( p ) {
+ p = strstr( p, "=" );
+ len = 1;
+ val = atoi( p + len );
+ }
+ }
+ gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( radFPSLimitAuto ), val );
+
+ val = 200;
+ if ( pB ) {
+ strcpy(t,"\nFrameRate");
+ p = strstr( pB, t );
+ if ( p ) {
+ p = strstr( p, "=" );
+ len = 1;
+ val = atoi( p + len );
+ }
+ }
+ gtk_spin_button_set_value( GTK_SPIN_BUTTON( spinFPSLimit ), val );
+
+ val = 0;
+ if ( pB ) {
+ strcpy( t, "\nUseFrameSkip" );
+ p = strstr( pB, t );
+ if ( p ) {
+ p = strstr( p, "=" );
+ len = 1;
+ val = atoi( p + len );
+ }
+ }
+ gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkUseFrameSkipping ), val );
+
+ val = 2;
+ if ( pB ) {
+ strcpy( t, "\nOffscreenDrawing" );
+ p = strstr( pB, t );
+ if ( p ) {
+ p = strstr( p, "=" );
+ len = 1;
+ val = atoi( p + len );
+ }
+ }
+ gtk_combo_box_set_active( GTK_COMBO_BOX( cbxOffscreen ), val );
+
+ val = 1;
+ if ( pB ) {
+ strcpy( t, "\nFrameTextures" );
+ p = strstr( pB, t );
+ if ( p ) {
+ p = strstr( p, "=" );
+ len = 1;
+ val = atoi( p + len );
+ }
+ }
+ gtk_combo_box_set_active( GTK_COMBO_BOX( cbxFBTex ), val );
+
+ val = 0;
+ if ( pB ) {
+ strcpy( t, "\nFrameAccess" );
+ p = strstr( pB, t );
+ if ( p ) {
+ p = strstr( p, "=" );
+ len = 1;
+ val = atoi( p + len );
+ }
+ }
+ gtk_combo_box_set_active( GTK_COMBO_BOX( cbxFBAccess ), val );
+
+ val = 0;
+ if ( pB ) {
+ strcpy( t, "\nMaskDetect" );
+ p = strstr( pB, t );
+ if ( p ) {
+ p = strstr( p, "=" );
+ len = 1;
+ val = atoi( p + len );
+ }
+ }
+ gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkMaskDetect ), val );
+
+ val = 1;
+ if ( pB ) {
+ strcpy( t, "\nOpaquePass" );
+ p = strstr( pB, t );
+ if ( p ) {
+ p = strstr( p, "=" );
+ len = 1;
+ val = atoi( p + len );
+ }
+ }
+ gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkOpaquePass ), val );
+
+ val = 0;
+ if ( pB ) {
+ strcpy( t, "\nAdvancedBlend" );
+ p = strstr( pB, t );
+ if ( p ) {
+ p = strstr( p, "=" );
+ len = 1;
+ val = atoi( p + len );
+ }
+ }
+ gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkAdvancedBlend ), val );
+
+ val = 0;
+ if ( pB ) {
+ strcpy( t, "\nScanLines" );
+ p = strstr( pB, t );
+ if ( p ) {
+ p = strstr( p, "=" );
+ len = 1;
+ val = atoi( p + len );
+ }
+ }
+ gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkScanLines ), val );
+
+ val = 0;
+ if ( pB ) {
+ strcpy(t,"\nScanLinesBlend");
+ p = strstr( pB, t );
+ if ( p ) {
+ p = strstr( p, "=" );
+ len = 1;
+ val = atoi( p + len );
+ }
+ }
+ gtk_spin_button_set_value( GTK_SPIN_BUTTON( spinScanLinesBlend ), val );
+
+ val = 1;
+ if ( pB ) {
+ strcpy( t, "\nFastMdec" );
+ p = strstr( pB, t );
+ if ( p ) {
+ p = strstr( p, "=" );
+ len = 1;
+ val = atoi( p + len );
+ }
+ }
+ gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkFastMdec ), val );
+
+ val = 0;
+ if ( pB ) {
+ strcpy( t, "\n15bitMdec" );
+ p = strstr( pB, t );
+ if ( p ) {
+ p = strstr( p, "=" );
+ len = 1;
+ val = atoi( p + len );
+ }
+ }
+ gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chk15bitMdec ), val );
+
+ val = 0;
+ if ( pB ) {
+ strcpy( t, "\nLineMode" );
+ p = strstr( pB, t );
+ if ( p ) {
+ p = strstr( p, "=" );
+ len = 1;
+ val = atoi( p + len );
+ }
+ }
+ gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkLineMode ), val );
+
+ val = 0;
+ if ( pB ) {
+ strcpy( t, "\nAntiAlias" );
+ p = strstr( pB, t );
+ if ( p ) {
+ p = strstr( p, "=" );
+ len = 1;
+ val = atoi( p + len );
+ }
+ }
+ gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkAntiAlias ), val );
+
+ val = 0;
+ if ( pB ) {
+ strcpy( t, "\nOGLExtensions" );
+ p = strstr( pB, t );
+ if ( p ) {
+ p = strstr( p, "=" );
+ len = 1;
+ val = atoi( p + len );
+ }
+ }
+ gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkOGLExtensions ), val );
+
+ val = 0;
+ if ( pB ) {
+ strcpy( t, "\nScreenSmoothing" );
+ p = strstr( pB, t );
+ if ( p ) {
+ p = strstr( p, "=" );
+ len = 1;
+ val = atoi( p + len );
+ }
+ }
+ gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkScreenSmoothing ), val );
+
+ val = 0;
+ if ( pB ) {
+ strcpy( t, "\nUseFixes" );
+ p = strstr( pB, t );
+ if ( p ) {
+ p = strstr( p, "=" );
+ len = 1;
+ val = atoi( p + len );
+ }
+ }
+ gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkUseGameFixes ), val );
+
+ val = 0;
+ if ( pB ) {
+ strcpy( t, "\nCfgFixes" );
+ p = strstr( pB, t );
+ if ( p ) {
+ p = strstr( p, "=" );
+ len = 1;
+ val = atoi( p + len );
+ }
+ }
+ if ( val & (1 << 17) ) { gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkCfgFix131072 ), TRUE ); }
+ if ( val & (1 << 16) ) { gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkCfgFix65536 ), TRUE ); }
+ if ( val & (1 << 15) ) { gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkCfgFix32768 ), TRUE ); }
+ if ( val & (1 << 14) ) { gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkCfgFix16384 ), TRUE ); }
+ if ( val & (1 << 13) ) { gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkCfgFix8192 ), TRUE ); }
+ if ( val & (1 << 12) ) { gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkCfgFix4096 ), TRUE ); }
+ if ( val & (1 << 11) ) { gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkCfgFix2048 ), TRUE ); }
+ if ( val & (1 << 10) ) { gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkCfgFix1024 ), TRUE ); }
+ if ( val & (1 << 9) ) { gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkCfgFix512 ), TRUE ); }
+ if ( val & (1 << 8) ) { gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkCfgFix256 ), TRUE ); }
+ if ( val & (1 << 7) ) { gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkCfgFix128 ), TRUE ); }
+ if ( val & (1 << 6) ) { gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkCfgFix64 ), TRUE ); }
+ if ( val & (1 << 5) ) { gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkCfgFix32 ), TRUE ); }
+ if ( val & (1 << 4) ) { gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkCfgFix16 ), TRUE ); }
+ if ( val & (1 << 3) ) { gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkCfgFix8 ), TRUE ); }
+ if ( val & (1 << 2) ) { gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkCfgFix4 ), TRUE ); }
+ if ( val & (1 << 1) ) { gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkCfgFix2 ), TRUE ); }
+ if ( val & (1 << 0) ) { gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( chkCfgFix1 ), TRUE ); }
+
+ gtk_builder_connect_signals( builder, NULL );
+
+ g_object_unref( G_OBJECT( builder ) );
+
+ // Connect callbacks to signals
+ gtk_signal_connect( GTK_OBJECT( window ), "destroy", G_CALLBACK( gtk_main_quit ), NULL );
+ gtk_signal_connect( GTK_OBJECT( btnCancel ), "clicked", G_CALLBACK( gtk_main_quit ), NULL );
+ gtk_signal_connect( GTK_OBJECT( btnSave ), "clicked", G_CALLBACK( on_btnSave_clicked ), NULL );
+ gtk_signal_connect( GTK_OBJECT( chkUseGameFixes ), "toggled", G_CALLBACK( on_chkUseGameFixes_toggled ), NULL );
+ gtk_signal_connect( GTK_OBJECT( chkUseFPSLimit ), "toggled", G_CALLBACK( on_chkUseFPSLimit_toggled ), NULL );
+ gtk_signal_connect( GTK_OBJECT( radFPSLimitManual ), "toggled", G_CALLBACK( on_radFPSLimitManual_toggled ), NULL );
+ gtk_signal_connect( GTK_OBJECT( chkScanLines ), "toggled", G_CALLBACK( on_chkScanLines_toggled ), NULL );
+ gtk_signal_connect( GTK_OBJECT( btnFast ), "clicked", G_CALLBACK( on_btnFast_clicked ), NULL );
+ gtk_signal_connect( GTK_OBJECT( btnBeautiful ), "clicked", G_CALLBACK( on_btnBeautiful_clicked ), NULL );
+
+ // Call some callbacks to ensure widget state consistency
+ on_chkUseGameFixes_toggled( GTK_OBJECT( chkUseGameFixes ), NULL );
+ on_chkUseFPSLimit_toggled( GTK_OBJECT( chkUseFPSLimit ), NULL );
+ on_radFPSLimitManual_toggled( GTK_OBJECT( radFPSLimitManual ), NULL );
+ on_chkScanLines_toggled( GTK_OBJECT( chkScanLines ), NULL );
+
+ gtk_widget_show( window );
+
+ gtk_main();
+
+ return 0;
+}
diff --git a/plugins/peopsxgl/key.c b/plugins/peopsxgl/key.c index 200446a2..dba1c839 100644 --- a/plugins/peopsxgl/key.c +++ b/plugins/peopsxgl/key.c @@ -1,179 +1,177 @@ -/*************************************************************************** - key.c - description - ------------------- - begin : Sun Mar 08 2009 - copyright : (C) 1999-2009 by Pete Bernert - web : www.pbernert.com - ***************************************************************************/ - -/*************************************************************************** - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. See also the license.txt file for * - * additional informations. * - * * - ***************************************************************************/ - -#include "stdafx.h" - -#define _IN_KEY - -#include "externals.h" -#include "menu.h" -#include "texture.h" -#include "draw.h" -#include "fps.h" -#include "key.h" -#include "psemu_plugin_defs.h" - -//////////////////////////////////////////////////////////////////////// -// KeyBoard handler stuff -//////////////////////////////////////////////////////////////////////// - -uint32_t ulKeybits = 0; - -//////////////////////////////////////////////////////////////////////// -// keyboard handler (LINUX) -//////////////////////////////////////////////////////////////////////// - -#define VK_INSERT 65379 -#define VK_HOME 65360 -#define VK_PRIOR 65365 -#define VK_NEXT 65366 -#define VK_END 65367 -#define VK_DEL 65535 -#define VK_F5 65474 - -void GPUkeypressed(int keycode) -{ -/* arrives via the input plugin, so who knows what thread you're in */ - switch(keycode) - { - case VK_F5: - bSnapShot=1; - break; - - case VK_INSERT: - ulKeybits|=KEY_RESETTEXSTORE; - if(iBlurBuffer) iBlurBuffer=0; - else iBlurBuffer=1; - break; - - case VK_DEL: - if(ulKeybits&KEY_SHOWFPS) - { - ulKeybits&=~KEY_SHOWFPS; - HideText(); - DestroyPic(); - } - else - { - ulKeybits|=KEY_SHOWFPS; - szDispBuf[0]=0; - BuildDispMenu(0); - - } - break; - - case VK_PRIOR: BuildDispMenu(-1); break; - case VK_NEXT: BuildDispMenu( 1); break; - case VK_END: SwitchDispMenu( 1); break; - case VK_HOME: SwitchDispMenu(-1); break; -#if defined (_MACGL) - default: { void HandleKey(int keycode); HandleKey(keycode); }; -#endif - } - -} - -void InitKeyHandler(void) -{ -} - -void ExitKeyHandler(void) -{ -} - -//////////////////////////////////////////////////////////////////////// -// reset stuff on special keyboard commands -//////////////////////////////////////////////////////////////////////// - -void ResetStuff(void) -{ - ResetTextureArea(TRUE); - ulKeybits&=~KEY_RESETTEXSTORE; - - if(ulKeybits&KEY_BLACKWHITE) - { - if(bUseFixes) {bUseFixes=FALSE;dwActFixes=0;} - else {bUseFixes=TRUE; dwActFixes=dwCfgFixes;} - SetExtGLFuncs(); - if(iFrameLimit==2) SetAutoFrameCap(); - ulKeybits&=~KEY_BLACKWHITE; - } - - if(ulKeybits&KEY_RESETFILTER) - { - if(ulKeybits&KEY_STEPDOWN) - iFilterType--; - else iFilterType++; - if(iFilterType>6) iFilterType=0; - if(iFilterType<0) iFilterType=6; - SetExtGLFuncs(); - ulKeybits&=~(KEY_RESETFILTER|KEY_STEPDOWN); - BuildDispMenu(0); - } - - if(ulKeybits&KEY_RESETOPAQUE) - { - bOpaquePass=!bOpaquePass; - SetExtGLFuncs(); - ulKeybits&=~KEY_RESETOPAQUE; - BuildDispMenu(0); - } - - if(ulKeybits&KEY_RESETADVBLEND) - { - bAdvancedBlend=!bAdvancedBlend; - SetExtGLFuncs(); - ulKeybits&=~KEY_RESETADVBLEND; - BuildDispMenu(0); - } - - if(ulKeybits&KEY_RESETDITHER) - { - bDrawDither=!bDrawDither; - if(bDrawDither) glEnable(GL_DITHER); - else glDisable(GL_DITHER); - ulKeybits&=~KEY_RESETDITHER; - BuildDispMenu(0); - } - - if(ulKeybits & KEY_TOGGLEFBTEXTURE) - { - if(ulKeybits&KEY_STEPDOWN) - iFrameTexType--; - else iFrameTexType++; - if(iFrameTexType>3) iFrameTexType=0; - if(iFrameTexType<0) iFrameTexType=3; - if(gTexFrameName!=0) - glDeleteTextures(1, &gTexFrameName); - gTexFrameName=0; - ulKeybits&=~(KEY_TOGGLEFBTEXTURE|KEY_STEPDOWN); - } - - if(ulKeybits & KEY_TOGGLEFBREAD) - { - if(ulKeybits&KEY_STEPDOWN) - iFrameReadType--; - else iFrameReadType++; - if(iFrameReadType>4) iFrameReadType=0; - if(iFrameReadType<0) iFrameReadType=4; - if(iFrameReadType==4) bFullVRam=TRUE; - else bFullVRam=FALSE; - iRenderFVR=0; - ulKeybits&=~(KEY_TOGGLEFBREAD|KEY_STEPDOWN); - } -} +/***************************************************************************
+ key.c - description
+ -------------------
+ begin : Sun Mar 08 2009
+ copyright : (C) 1999-2009 by Pete Bernert
+ web : www.pbernert.com
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. See also the license.txt file for *
+ * additional informations. *
+ * *
+ ***************************************************************************/
+
+#include "stdafx.h"
+
+#define _IN_KEY
+
+#include "externals.h"
+#include "menu.h"
+#include "texture.h"
+#include "draw.h"
+#include "fps.h"
+
+////////////////////////////////////////////////////////////////////////
+// KeyBoard handler stuff
+////////////////////////////////////////////////////////////////////////
+
+uint32_t ulKeybits = 0;
+
+////////////////////////////////////////////////////////////////////////
+// keyboard handler (LINUX)
+////////////////////////////////////////////////////////////////////////
+
+#define VK_INSERT 65379
+#define VK_HOME 65360
+#define VK_PRIOR 65365
+#define VK_NEXT 65366
+#define VK_END 65367
+#define VK_DEL 65535
+#define VK_F5 65474
+
+void GPUkeypressed(int keycode)
+{
+/* arrives via the input plugin, so who knows what thread you're in */
+ switch(keycode)
+ {
+ case VK_F5:
+ bSnapShot=1;
+ break;
+
+ case VK_INSERT:
+ ulKeybits|=KEY_RESETTEXSTORE;
+ if(iBlurBuffer) iBlurBuffer=0;
+ else iBlurBuffer=1;
+ break;
+
+ case VK_DEL:
+ if(ulKeybits&KEY_SHOWFPS)
+ {
+ ulKeybits&=~KEY_SHOWFPS;
+ HideText();
+ DestroyPic();
+ }
+ else
+ {
+ ulKeybits|=KEY_SHOWFPS;
+ szDispBuf[0]=0;
+ BuildDispMenu(0);
+
+ }
+ break;
+
+ case VK_PRIOR: BuildDispMenu(-1); break;
+ case VK_NEXT: BuildDispMenu( 1); break;
+ case VK_END: SwitchDispMenu( 1); break;
+ case VK_HOME: SwitchDispMenu(-1); break;
+#if defined (_MACGL)
+ default: { void HandleKey(int keycode); HandleKey(keycode); };
+#endif
+ }
+
+}
+
+void InitKeyHandler(void)
+{
+}
+
+void ExitKeyHandler(void)
+{
+}
+
+////////////////////////////////////////////////////////////////////////
+// reset stuff on special keyboard commands
+////////////////////////////////////////////////////////////////////////
+
+void ResetStuff(void)
+{
+ ResetTextureArea(TRUE);
+ ulKeybits&=~KEY_RESETTEXSTORE;
+
+ if(ulKeybits&KEY_BLACKWHITE)
+ {
+ if(bUseFixes) {bUseFixes=FALSE;dwActFixes=0;}
+ else {bUseFixes=TRUE; dwActFixes=dwCfgFixes;}
+ SetExtGLFuncs();
+ if(iFrameLimit==2) SetAutoFrameCap();
+ ulKeybits&=~KEY_BLACKWHITE;
+ }
+
+ if(ulKeybits&KEY_RESETFILTER)
+ {
+ if(ulKeybits&KEY_STEPDOWN)
+ iFilterType--;
+ else iFilterType++;
+ if(iFilterType>6) iFilterType=0;
+ if(iFilterType<0) iFilterType=6;
+ SetExtGLFuncs();
+ ulKeybits&=~(KEY_RESETFILTER|KEY_STEPDOWN);
+ BuildDispMenu(0);
+ }
+
+ if(ulKeybits&KEY_RESETOPAQUE)
+ {
+ bOpaquePass=!bOpaquePass;
+ SetExtGLFuncs();
+ ulKeybits&=~KEY_RESETOPAQUE;
+ BuildDispMenu(0);
+ }
+
+ if(ulKeybits&KEY_RESETADVBLEND)
+ {
+ bAdvancedBlend=!bAdvancedBlend;
+ SetExtGLFuncs();
+ ulKeybits&=~KEY_RESETADVBLEND;
+ BuildDispMenu(0);
+ }
+
+ if(ulKeybits&KEY_RESETDITHER)
+ {
+ bDrawDither=!bDrawDither;
+ if(bDrawDither) glEnable(GL_DITHER);
+ else glDisable(GL_DITHER);
+ ulKeybits&=~KEY_RESETDITHER;
+ BuildDispMenu(0);
+ }
+
+ if(ulKeybits & KEY_TOGGLEFBTEXTURE)
+ {
+ if(ulKeybits&KEY_STEPDOWN)
+ iFrameTexType--;
+ else iFrameTexType++;
+ if(iFrameTexType>3) iFrameTexType=0;
+ if(iFrameTexType<0) iFrameTexType=3;
+ if(gTexFrameName!=0)
+ glDeleteTextures(1, &gTexFrameName);
+ gTexFrameName=0;
+ ulKeybits&=~(KEY_TOGGLEFBTEXTURE|KEY_STEPDOWN);
+ }
+
+ if(ulKeybits & KEY_TOGGLEFBREAD)
+ {
+ if(ulKeybits&KEY_STEPDOWN)
+ iFrameReadType--;
+ else iFrameReadType++;
+ if(iFrameReadType>4) iFrameReadType=0;
+ if(iFrameReadType<0) iFrameReadType=4;
+ if(iFrameReadType==4) bFullVRam=TRUE;
+ else bFullVRam=FALSE;
+ iRenderFVR=0;
+ ulKeybits&=~(KEY_TOGGLEFBREAD|KEY_STEPDOWN);
+ }
+}
diff --git a/plugins/peopsxgl/prim.c b/plugins/peopsxgl/prim.c index 3ee37c27..2209a1ad 100644 --- a/plugins/peopsxgl/prim.c +++ b/plugins/peopsxgl/prim.c @@ -1,4662 +1,4661 @@ -/*************************************************************************** - prim.c - description - ------------------- - begin : Sun Mar 08 2009 - copyright : (C) 1999-2009 by Pete Bernert - web : www.pbernert.com - ***************************************************************************/ - -/*************************************************************************** - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. See also the license.txt file for * - * additional informations. * - * * - ***************************************************************************/ - -#include "stdafx.h" - -#define _IN_PRIMDRAW - -#include "externals.h" -#include "gpu.h" -#include "draw.h" -#include "soft.h" -#include "texture.h" -#include "prim.h" - -//////////////////////////////////////////////////////////////////////// -// defines -//////////////////////////////////////////////////////////////////////// - -#define DEFOPAQUEON glAlphaFunc(GL_EQUAL,0.0f);bBlendEnable=FALSE;glDisable(GL_BLEND); -#define DEFOPAQUEOFF glAlphaFunc(GL_GREATER,0.49f); - -//////////////////////////////////////////////////////////////////////// -// globals -//////////////////////////////////////////////////////////////////////// - -BOOL bDrawTextured; // current active drawing states -BOOL bDrawSmoothShaded; -BOOL bOldSmoothShaded; -BOOL bDrawNonShaded; -BOOL bDrawMultiPass; -int iOffscreenDrawing; -int iDrawnSomething=0; - -BOOL bRenderFrontBuffer=FALSE; // flag for front buffer rendering - -GLubyte ubGloAlpha; // texture alpha -GLubyte ubGloColAlpha; // color alpha -int iFilterType; // type of filter -BOOL bFullVRam=FALSE; // sign for tex win -BOOL bDrawDither; // sign for dither -BOOL bUseMultiPass; // sign for multi pass -GLuint gTexName; // binded texture -BOOL bTexEnabled; // texture enable flag -BOOL bBlendEnable; // blend enable flag -PSXRect_t xrUploadArea; // rect to upload -PSXRect_t xrUploadAreaIL; // rect to upload -PSXRect_t xrUploadAreaRGB24; // rect to upload rgb24 -int iSpriteTex=0; // flag for "hey, it's a sprite" -unsigned short usMirror; // mirror, mirror on the wall - -BOOL bNeedUploadAfter=FALSE; // sign for uploading in next frame -BOOL bNeedUploadTest=FALSE; // sign for upload test -BOOL bUsingTWin=FALSE; // tex win active flag -BOOL bUsingMovie=FALSE; // movie active flag -PSXRect_t xrMovieArea; // rect for movie upload -short sSprite_ux2; // needed for sprire adjust -short sSprite_vy2; // -uint32_t ulOLDCOL=0; // active color -uint32_t ulClutID; // clut - -uint32_t dwCfgFixes; // game fixes -uint32_t dwActFixes=0; -uint32_t dwEmuFixes=0; -BOOL bUseFixes; - -int drawX,drawY,drawW,drawH; // offscreen drawing checkers -short sxmin,sxmax,symin,symax; - -//////////////////////////////////////////////////////////////////////// -// Update global TP infos -//////////////////////////////////////////////////////////////////////// - -static void UpdateGlobalTP(unsigned short gdata) -{ - GlobalTextAddrX = (gdata << 6) & 0x3c0; - - if(iGPUHeight==1024) // ZN mode - { - if(dwGPUVersion==2) // very special zn gpu - { - GlobalTextAddrY =((gdata & 0x60 ) << 3); - GlobalTextIL =(gdata & 0x2000) >> 13; - GlobalTextABR = (unsigned short)((gdata >> 7) & 0x3); - GlobalTextTP = (gdata >> 9) & 0x3; - if(GlobalTextTP==3) GlobalTextTP=2; - GlobalTexturePage = (GlobalTextAddrX>>6)+(GlobalTextAddrY>>4); - usMirror =0; - STATUSREG = (STATUSREG & 0xffffe000 ) | (gdata & 0x1fff ); - return; - } - else // "enhanced" psx gpu - { - GlobalTextAddrY = (unsigned short)(((gdata << 4) & 0x100) | ((gdata >> 2) & 0x200)); - } - } - else GlobalTextAddrY = (gdata << 4) & 0x100; // "normal" psx gpu - - usMirror=gdata&0x3000; - - GlobalTextTP = (gdata >> 7) & 0x3; // tex mode (4,8,15) - if(GlobalTextTP==3) GlobalTextTP=2; // seen in Wild9 :( - GlobalTextABR = (gdata >> 5) & 0x3; // blend mode - - GlobalTexturePage = (GlobalTextAddrX>>6)+(GlobalTextAddrY>>4); - - STATUSREG&=~0x07ff; // Clear the necessary bits - STATUSREG|=(gdata & 0x07ff); // set the necessary bits -} - -static unsigned int DoubleBGR2RGB (unsigned int BGR) -{ - unsigned int ebx,eax,edx; - - ebx=(BGR&0x000000ff)<<1; - if(ebx&0x00000100) ebx=0x000000ff; - - eax=(BGR&0x0000ff00)<<1; - if(eax&0x00010000) eax=0x0000ff00; - - edx=(BGR&0x00ff0000)<<1; - if(edx&0x01000000) edx=0x00ff0000; - - return (ebx|eax|edx); -} - -static unsigned short BGR24to16 (uint32_t BGR) -{ - return ((BGR>>3)&0x1f)|((BGR&0xf80000)>>9)|((BGR&0xf800)>>6); -} - -//////////////////////////////////////////////////////////////////////// -// OpenGL primitive drawing commands -//////////////////////////////////////////////////////////////////////// - -static __inline void PRIMdrawTexturedQuad(OGLVertex* vertex1, OGLVertex* vertex2, - OGLVertex* vertex3, OGLVertex* vertex4) -{ - glBegin(GL_TRIANGLE_STRIP); - glTexCoord2fv(&vertex1->sow); - glVertex3fv(&vertex1->x); - - glTexCoord2fv(&vertex2->sow); - glVertex3fv(&vertex2->x); - - glTexCoord2fv(&vertex4->sow); - glVertex3fv(&vertex4->x); - - glTexCoord2fv(&vertex3->sow); - glVertex3fv(&vertex3->x); - glEnd(); -} - -///////////////////////////////////////////////////////// - -static __inline void PRIMdrawTexturedTri(OGLVertex* vertex1, OGLVertex* vertex2, - OGLVertex* vertex3) -{ - glBegin(GL_TRIANGLES); - glTexCoord2fv(&vertex1->sow); - glVertex3fv(&vertex1->x); - - glTexCoord2fv(&vertex2->sow); - glVertex3fv(&vertex2->x); - - glTexCoord2fv(&vertex3->sow); - glVertex3fv(&vertex3->x); - glEnd(); -} - -///////////////////////////////////////////////////////// - -static __inline void PRIMdrawTexGouraudTriColor(OGLVertex* vertex1, OGLVertex* vertex2, - OGLVertex* vertex3) -{ - glBegin(GL_TRIANGLES); - - SETPCOL(vertex1); - glTexCoord2fv(&vertex1->sow); - glVertex3fv(&vertex1->x); - - SETPCOL(vertex2); - glTexCoord2fv(&vertex2->sow); - glVertex3fv(&vertex2->x); - - SETPCOL(vertex3); - glTexCoord2fv(&vertex3->sow); - glVertex3fv(&vertex3->x); - glEnd(); -} - -///////////////////////////////////////////////////////// - -static __inline void PRIMdrawTexGouraudTriColorQuad(OGLVertex* vertex1, OGLVertex* vertex2, - OGLVertex* vertex3, OGLVertex* vertex4) -{ - glBegin(GL_TRIANGLE_STRIP); - SETPCOL(vertex1); - glTexCoord2fv(&vertex1->sow); - glVertex3fv(&vertex1->x); - - SETPCOL(vertex2); - glTexCoord2fv(&vertex2->sow); - glVertex3fv(&vertex2->x); - - SETPCOL(vertex4); - glTexCoord2fv(&vertex4->sow); - glVertex3fv(&vertex4->x); - - SETPCOL(vertex3); - glTexCoord2fv(&vertex3->sow); - glVertex3fv(&vertex3->x); - glEnd(); -} - -///////////////////////////////////////////////////////// - -static __inline void PRIMdrawTri(OGLVertex* vertex1, OGLVertex* vertex2, OGLVertex* vertex3) -{ - glBegin(GL_TRIANGLES); - glVertex3fv(&vertex1->x); - glVertex3fv(&vertex2->x); - glVertex3fv(&vertex3->x); - glEnd(); -} - -///////////////////////////////////////////////////////// - -static __inline void PRIMdrawTri2(OGLVertex* vertex1, OGLVertex* vertex2, - OGLVertex* vertex3, OGLVertex* vertex4) -{ - glBegin(GL_TRIANGLE_STRIP); - glVertex3fv(&vertex1->x); - glVertex3fv(&vertex3->x); - glVertex3fv(&vertex2->x); - glVertex3fv(&vertex4->x); - glEnd(); -} - -///////////////////////////////////////////////////////// - -static __inline void PRIMdrawGouraudTriColor(OGLVertex* vertex1, OGLVertex* vertex2, - OGLVertex* vertex3) -{ - glBegin(GL_TRIANGLES); - SETPCOL(vertex1); - glVertex3fv(&vertex1->x); - - SETPCOL(vertex2); - glVertex3fv(&vertex2->x); - - SETPCOL(vertex3); - glVertex3fv(&vertex3->x); - glEnd(); -} - -///////////////////////////////////////////////////////// - -static __inline void PRIMdrawGouraudTri2Color(OGLVertex* vertex1, OGLVertex* vertex2, - OGLVertex* vertex3, OGLVertex* vertex4) -{ - glBegin(GL_TRIANGLE_STRIP); - SETPCOL(vertex1); - glVertex3fv(&vertex1->x); - - SETPCOL(vertex3); - glVertex3fv(&vertex3->x); - - SETPCOL(vertex2); - glVertex3fv(&vertex2->x); - - SETPCOL(vertex4); - glVertex3fv(&vertex4->x); - glEnd(); -} - -///////////////////////////////////////////////////////// - -static __inline void PRIMdrawFlatLine(OGLVertex* vertex1, OGLVertex* vertex2,OGLVertex* vertex3, OGLVertex* vertex4) -{ - glBegin(GL_QUADS); - - SETPCOL(vertex1); - - glVertex3fv(&vertex1->x); - glVertex3fv(&vertex2->x); - glVertex3fv(&vertex3->x); - glVertex3fv(&vertex4->x); - glEnd(); -} - -///////////////////////////////////////////////////////// - -static __inline void PRIMdrawGouraudLine(OGLVertex* vertex1, OGLVertex* vertex2,OGLVertex* vertex3, OGLVertex* vertex4) -{ - glBegin(GL_QUADS); - - SETPCOL(vertex1); - glVertex3fv(&vertex1->x); - - SETPCOL(vertex2); - glVertex3fv(&vertex2->x); - - SETPCOL(vertex3); - glVertex3fv(&vertex3->x); - - SETPCOL(vertex4); - glVertex3fv(&vertex4->x); - glEnd(); -} - -///////////////////////////////////////////////////////// - -static __inline void PRIMdrawQuad(OGLVertex* vertex1, OGLVertex* vertex2, - OGLVertex* vertex3, OGLVertex* vertex4) -{ - glBegin(GL_QUADS); - glVertex3fv(&vertex1->x); - glVertex3fv(&vertex2->x); - glVertex3fv(&vertex3->x); - glVertex3fv(&vertex4->x); - glEnd(); -} - -//////////////////////////////////////////////////////////////////////// -// Transparent blending settings -//////////////////////////////////////////////////////////////////////// - -static GLenum obm1=GL_ZERO; -static GLenum obm2=GL_ZERO; - -typedef struct SEMITRANSTAG -{ - GLenum srcFac; - GLenum dstFac; - GLubyte alpha; -} SemiTransParams; - -SemiTransParams TransSets[4]= -{ - {GL_SRC_ALPHA,GL_SRC_ALPHA, 127}, - {GL_ONE, GL_ONE, 255}, - {GL_ZERO, GL_ONE_MINUS_SRC_COLOR,255}, - {GL_ONE_MINUS_SRC_ALPHA,GL_ONE, 192} -}; - -//////////////////////////////////////////////////////////////////////// - -static void SetSemiTrans(void) -{ -/* -* 0.5 x B + 0.5 x F -* 1.0 x B + 1.0 x F -* 1.0 x B - 1.0 x F -* 1.0 x B +0.25 x F -*/ - - if(!DrawSemiTrans) // no semi trans at all? - { - if(bBlendEnable) - {glDisable(GL_BLEND);bBlendEnable=FALSE;} // -> don't wanna blend - ubGloAlpha=ubGloColAlpha=255; // -> full alpha - return; // -> and bye - } - - ubGloAlpha=ubGloColAlpha=TransSets[GlobalTextABR].alpha; - - if(!bBlendEnable) - {glEnable(GL_BLEND);bBlendEnable=TRUE;} // wanna blend - - if(TransSets[GlobalTextABR].srcFac!=obm1 || - TransSets[GlobalTextABR].dstFac!=obm2) - { - if(glBlendEquationEXTEx==NULL) - { - obm1=TransSets[GlobalTextABR].srcFac; - obm2=TransSets[GlobalTextABR].dstFac; - glBlendFunc(obm1,obm2); // set blend func - } - else - if(TransSets[GlobalTextABR].dstFac !=GL_ONE_MINUS_SRC_COLOR) - { - if(obm2==GL_ONE_MINUS_SRC_COLOR) - glBlendEquationEXTEx(FUNC_ADD_EXT); - obm1=TransSets[GlobalTextABR].srcFac; - obm2=TransSets[GlobalTextABR].dstFac; - glBlendFunc(obm1,obm2); // set blend func - } - else - { - glBlendEquationEXTEx(FUNC_REVERSESUBTRACT_EXT); - obm1=TransSets[GlobalTextABR].srcFac; - obm2=TransSets[GlobalTextABR].dstFac; - glBlendFunc(GL_ONE,GL_ONE); // set blend func - } - } -} - -void SetScanTrans(void) // blending for scan lines -{ - if(glBlendEquationEXTEx!=NULL) - { - if(obm2==GL_ONE_MINUS_SRC_COLOR) - glBlendEquationEXTEx(FUNC_ADD_EXT); - } - - obm1=TransSets[0].srcFac; - obm2=TransSets[0].dstFac; - glBlendFunc(obm1,obm2); // set blend func -} - -void SetScanTexTrans(void) // blending for scan mask texture -{ - if(glBlendEquationEXTEx!=NULL) - { - if(obm2==GL_ONE_MINUS_SRC_COLOR) - glBlendEquationEXTEx(FUNC_ADD_EXT); - } - - obm1=TransSets[2].srcFac; - obm2=TransSets[2].dstFac; - glBlendFunc(obm1,obm2); // set blend func -} - -//////////////////////////////////////////////////////////////////////// -// multi pass in old 'Advanced blending' mode... got it from Lewpy :) -//////////////////////////////////////////////////////////////////////// - -SemiTransParams MultiTexTransSets[4][2]= -{ - { - {GL_ONE ,GL_SRC_ALPHA, 127}, - {GL_SRC_ALPHA,GL_ONE, 127} - }, - { - {GL_ONE, GL_SRC_ALPHA, 255}, - {GL_SRC_ALPHA,GL_ONE, 255} - }, - { - {GL_ZERO, GL_ONE_MINUS_SRC_COLOR,255}, - {GL_ZERO, GL_ONE_MINUS_SRC_COLOR,255} - }, - { - {GL_SRC_ALPHA,GL_ONE, 127}, - {GL_ONE_MINUS_SRC_ALPHA,GL_ONE, 255} - } -}; - -//////////////////////////////////////////////////////////////////////// - -SemiTransParams MultiColTransSets[4]= -{ - {GL_ONE_MINUS_SRC_ALPHA,GL_SRC_ALPHA,127}, - {GL_ONE, GL_ONE, 255}, - {GL_ZERO, GL_ONE_MINUS_SRC_COLOR,255}, - {GL_SRC_ALPHA,GL_ONE, 127} -}; - -//////////////////////////////////////////////////////////////////////// - -static void SetSemiTransMulti(int Pass) -{ - static GLenum bm1=GL_ZERO; - static GLenum bm2=GL_ONE; - - ubGloAlpha=255; - ubGloColAlpha=255; - - // are we enabling SemiTransparent mode? - if(DrawSemiTrans) - { - if(bDrawTextured) - { - bm1=MultiTexTransSets[GlobalTextABR][Pass].srcFac; - bm2=MultiTexTransSets[GlobalTextABR][Pass].dstFac; - ubGloAlpha=MultiTexTransSets[GlobalTextABR][Pass].alpha; - } - // no texture - else - { - bm1=MultiColTransSets[GlobalTextABR].srcFac; - bm2=MultiColTransSets[GlobalTextABR].dstFac; - ubGloColAlpha=MultiColTransSets[GlobalTextABR].alpha; - } - } - // no shading - else - { - if(Pass==0) - { - // disable blending - bm1=GL_ONE;bm2=GL_ZERO; - } - else - { - // disable blending, but add src col a second time - bm1=GL_ONE;bm2=GL_ONE; - } - } - - if(!bBlendEnable) - {glEnable(GL_BLEND);bBlendEnable=TRUE;} // wanna blend - - if(bm1!=obm1 || bm2!=obm2) - { - glBlendFunc(bm1,bm2); // set blend func - obm1=bm1;obm2=bm2; - } -} - -//////////////////////////////////////////////////////////////////////// -// Set several rendering stuff including blending -//////////////////////////////////////////////////////////////////////// - -static __inline void SetZMask3O(void) -{ - if(iUseMask && DrawSemiTrans && !iSetMask) - { - vertex[0].z=vertex[1].z=vertex[2].z=gl_z; - gl_z+=0.00004f; - } -} - -static __inline void SetZMask3(void) -{ - if(iUseMask) - { - if(iSetMask || DrawSemiTrans) - {vertex[0].z=vertex[1].z=vertex[2].z=0.95f;} - else - { - vertex[0].z=vertex[1].z=vertex[2].z=gl_z; - gl_z+=0.00004f; - } - } -} - -static __inline void SetZMask3NT(void) -{ - if(iUseMask) - { - if(iSetMask) - {vertex[0].z=vertex[1].z=vertex[2].z=0.95f;} - else - { - vertex[0].z=vertex[1].z=vertex[2].z=gl_z; - gl_z+=0.00004f; - } - } -} - -//////////////////////////////////////////////////////////////////////// - -static __inline void SetZMask4O(void) -{ - if(iUseMask && DrawSemiTrans && !iSetMask) - { - vertex[0].z=vertex[1].z=vertex[2].z=vertex[3].z=gl_z; - gl_z+=0.00004f; - } -} - -static __inline void SetZMask4(void) -{ - if(iUseMask) - { - if(iSetMask || DrawSemiTrans) - {vertex[0].z=vertex[1].z=vertex[2].z=vertex[3].z=0.95f;} - else - { - vertex[0].z=vertex[1].z=vertex[2].z=vertex[3].z=gl_z; - gl_z+=0.00004f; - } - } -} - -static __inline void SetZMask4NT(void) -{ - if(iUseMask) - { - if(iSetMask==1) - {vertex[0].z=vertex[1].z=vertex[2].z=vertex[3].z=0.95f;} - else - { - vertex[0].z=vertex[1].z=vertex[2].z=vertex[3].z=gl_z; - gl_z+=0.00004f; - } - } -} - -static __inline void SetZMask4SP(void) -{ - if(iUseMask) - { - if(iSetMask==1) - {vertex[0].z=vertex[1].z=vertex[2].z=vertex[3].z=0.95f;} - else - { - if(bCheckMask) - { - vertex[0].z=vertex[1].z=vertex[2].z=vertex[3].z=gl_z; - gl_z+=0.00004f; - } - else - {vertex[0].z=vertex[1].z=vertex[2].z=vertex[3].z=0.95f;} - } - } -} - -//////////////////////////////////////////////////////////////////////// - -static __inline void SetRenderState(uint32_t DrawAttributes) -{ - bDrawNonShaded = (SHADETEXBIT(DrawAttributes)) ? TRUE : FALSE; - DrawSemiTrans = (SEMITRANSBIT(DrawAttributes)) ? TRUE : FALSE; -} - -//////////////////////////////////////////////////////////////////////// - -static __inline void SetRenderColor(uint32_t DrawAttributes) -{ - if(bDrawNonShaded) {g_m1=g_m2=g_m3=128;} - else - { - g_m1=DrawAttributes&0xff; - g_m2=(DrawAttributes>>8)&0xff; - g_m3=(DrawAttributes>>16)&0xff; - } -} - -//////////////////////////////////////////////////////////////////////// - -static void SetRenderMode(uint32_t DrawAttributes, BOOL bSCol) -{ - if((bUseMultiPass) && (bDrawTextured) && !(bDrawNonShaded)) - {bDrawMultiPass = TRUE; SetSemiTransMulti(0);} - else {bDrawMultiPass = FALSE;SetSemiTrans();} - - if(bDrawTextured) // texture ? build it/get it from cache - { - GLuint currTex; - if(bUsingTWin) currTex=LoadTextureWnd(GlobalTexturePage,GlobalTextTP, ulClutID); - else if(bUsingMovie) currTex=LoadTextureMovie(); - else currTex=SelectSubTextureS(GlobalTextTP,ulClutID); - - if(gTexName!=currTex) - {gTexName=currTex;glBindTexture(GL_TEXTURE_2D,currTex);} - - if(!bTexEnabled) // -> turn texturing on - {bTexEnabled=TRUE;glEnable(GL_TEXTURE_2D);} - } - else // no texture ? - if(bTexEnabled) - {bTexEnabled=FALSE;glDisable(GL_TEXTURE_2D);} // -> turn texturing off - - if(bSCol) // also set color ? - { - if((dwActFixes&4) && ((DrawAttributes&0x00ffffff)==0)) - DrawAttributes|=0x007f7f7f; - - if(bDrawNonShaded) // -> non shaded? - { - if(bGLBlend) vertex[0].c.lcol=0x7f7f7f; // --> solid color... - else vertex[0].c.lcol=0xffffff; - } - else // -> shaded? - { - if(!bUseMultiPass && !bGLBlend) // --> given color... - vertex[0].c.lcol=DoubleBGR2RGB(DrawAttributes); - else vertex[0].c.lcol=DrawAttributes; - } - vertex[0].c.col[3]=ubGloAlpha; // -> set color with - SETCOL(vertex[0]); // texture alpha - } - - if(bDrawSmoothShaded!=bOldSmoothShaded) // shading changed? - { - if(bDrawSmoothShaded) glShadeModel(GL_SMOOTH); // -> set actual shading - else glShadeModel(GL_FLAT); - bOldSmoothShaded=bDrawSmoothShaded; - } -} - -//////////////////////////////////////////////////////////////////////// -// Set Opaque multipass color -//////////////////////////////////////////////////////////////////////// - -static void SetOpaqueColor(uint32_t DrawAttributes) -{ - if(bDrawNonShaded) return; // no shading? bye - - DrawAttributes=DoubleBGR2RGB(DrawAttributes); // multipass is just half color, so double it on opaque pass - vertex[0].c.lcol=DrawAttributes|0xff000000; - SETCOL(vertex[0]); // set color -} - -//////////////////////////////////////////////////////////////////////// -// Fucking stupid screen coord checking -//////////////////////////////////////////////////////////////////////// - -static BOOL ClipVertexListScreen(void) -{ - if (lx0 >= PSXDisplay.DisplayEnd.x) goto NEXTSCRTEST; - if (ly0 >= PSXDisplay.DisplayEnd.y) goto NEXTSCRTEST; - if (lx2 < PSXDisplay.DisplayPosition.x) goto NEXTSCRTEST; - if (ly2 < PSXDisplay.DisplayPosition.y) goto NEXTSCRTEST; - - return TRUE; - -NEXTSCRTEST: - if(PSXDisplay.InterlacedTest) return FALSE; - - if (lx0 >= PreviousPSXDisplay.DisplayEnd.x) return FALSE; - if (ly0 >= PreviousPSXDisplay.DisplayEnd.y) return FALSE; - if (lx2 < PreviousPSXDisplay.DisplayPosition.x) return FALSE; - if (ly2 < PreviousPSXDisplay.DisplayPosition.y) return FALSE; - - return TRUE; -} - -//////////////////////////////////////////////////////////////////////// - -static BOOL bDrawOffscreenFront(void) -{ - if(sxmin < PSXDisplay.DisplayPosition.x) return FALSE; // must be complete in front - if(symin < PSXDisplay.DisplayPosition.y) return FALSE; - if(sxmax > PSXDisplay.DisplayEnd.x) return FALSE; - if(symax > PSXDisplay.DisplayEnd.y) return FALSE; - return TRUE; -} - -static BOOL bOnePointInFront(void) -{ - if(sxmax< PSXDisplay.DisplayPosition.x) - return FALSE; - - if(symax< PSXDisplay.DisplayPosition.y) - return FALSE; - - if(sxmin>=PSXDisplay.DisplayEnd.x) - return FALSE; - - if(symin>=PSXDisplay.DisplayEnd.y) - return FALSE; - - return TRUE; -} - - -static BOOL bOnePointInBack(void) -{ - if(sxmax< PreviousPSXDisplay.DisplayPosition.x) - return FALSE; - - if(symax< PreviousPSXDisplay.DisplayPosition.y) - return FALSE; - - if(sxmin>=PreviousPSXDisplay.DisplayEnd.x) - return FALSE; - - if(symin>=PreviousPSXDisplay.DisplayEnd.y) - return FALSE; - - return TRUE; -} - -static BOOL bDrawOffscreen4(void) -{ - BOOL bFront;short sW,sH; - - sxmax=max(lx0,max(lx1,max(lx2,lx3))); - if(sxmax<drawX) return FALSE; - sxmin=min(lx0,min(lx1,min(lx2,lx3))); - if(sxmin>drawW) return FALSE; - symax=max(ly0,max(ly1,max(ly2,ly3))); - if(symax<drawY) return FALSE; - symin=min(ly0,min(ly1,min(ly2,ly3))); - if(symin>drawH) return FALSE; - - if(PSXDisplay.Disabled) return TRUE; // disabled? ever - - if(iOffscreenDrawing==1) return bFullVRam; - - if(dwActFixes&1 && iOffscreenDrawing==4) - { - if(PreviousPSXDisplay.DisplayPosition.x==PSXDisplay.DisplayPosition.x && - PreviousPSXDisplay.DisplayPosition.y==PSXDisplay.DisplayPosition.y && - PreviousPSXDisplay.DisplayEnd.x==PSXDisplay.DisplayEnd.x && - PreviousPSXDisplay.DisplayEnd.y==PSXDisplay.DisplayEnd.y) - { - bRenderFrontBuffer=TRUE; - return FALSE; - } - } - - sW=drawW-1;sH=drawH-1; - - sxmin=min(sW,max(sxmin,drawX)); - sxmax=max(drawX,min(sxmax,sW)); - symin=min(sH,max(symin,drawY)); - symax=max(drawY,min(symax,sH)); - - if(bOnePointInBack()) return bFullVRam; - - if(iOffscreenDrawing==2) - bFront=bDrawOffscreenFront(); - else bFront=bOnePointInFront(); - - if(bFront) - { - if(PSXDisplay.InterlacedTest) return bFullVRam; // -> ok, no need for adjust - - vertex[0].x=lx0 - PSXDisplay.DisplayPosition.x+PreviousPSXDisplay.Range.x0; - vertex[1].x=lx1 - PSXDisplay.DisplayPosition.x+PreviousPSXDisplay.Range.x0; - vertex[2].x=lx2 - PSXDisplay.DisplayPosition.x+PreviousPSXDisplay.Range.x0; - vertex[3].x=lx3 - PSXDisplay.DisplayPosition.x+PreviousPSXDisplay.Range.x0; - vertex[0].y=ly0 - PSXDisplay.DisplayPosition.y+PreviousPSXDisplay.Range.y0; - vertex[1].y=ly1 - PSXDisplay.DisplayPosition.y+PreviousPSXDisplay.Range.y0; - vertex[2].y=ly2 - PSXDisplay.DisplayPosition.y+PreviousPSXDisplay.Range.y0; - vertex[3].y=ly3 - PSXDisplay.DisplayPosition.y+PreviousPSXDisplay.Range.y0; - - if(iOffscreenDrawing==4 && !(dwActFixes&1)) // -> frontbuffer wanted - { - bRenderFrontBuffer=TRUE; - //return TRUE; - } - return bFullVRam; // -> but no od - } - - return TRUE; -} - -//////////////////////////////////////////////////////////////////////// - -static BOOL bDrawOffscreen3(void) -{ - BOOL bFront;short sW,sH; - - sxmax=max(lx0,max(lx1,lx2)); - if(sxmax<drawX) return FALSE; - sxmin=min(lx0,min(lx1,lx2)); - if(sxmin>drawW) return FALSE; - symax=max(ly0,max(ly1,ly2)); - if(symax<drawY) return FALSE; - symin=min(ly0,min(ly1,ly2)); - if(symin>drawH) return FALSE; - - if(PSXDisplay.Disabled) return TRUE; // disabled? ever - - if(iOffscreenDrawing==1) return bFullVRam; - - sW=drawW-1;sH=drawH-1; - sxmin=min(sW,max(sxmin,drawX)); - sxmax=max(drawX,min(sxmax,sW)); - symin=min(sH,max(symin,drawY)); - symax=max(drawY,min(symax,sH)); - - if(bOnePointInBack()) return bFullVRam; - - if(iOffscreenDrawing==2) - bFront=bDrawOffscreenFront(); - else bFront=bOnePointInFront(); - - if(bFront) - { - if(PSXDisplay.InterlacedTest) return bFullVRam; // -> ok, no need for adjust - - vertex[0].x=lx0 - PSXDisplay.DisplayPosition.x+PreviousPSXDisplay.Range.x0; - vertex[1].x=lx1 - PSXDisplay.DisplayPosition.x+PreviousPSXDisplay.Range.x0; - vertex[2].x=lx2 - PSXDisplay.DisplayPosition.x+PreviousPSXDisplay.Range.x0; - vertex[0].y=ly0 - PSXDisplay.DisplayPosition.y+PreviousPSXDisplay.Range.y0; - vertex[1].y=ly1 - PSXDisplay.DisplayPosition.y+PreviousPSXDisplay.Range.y0; - vertex[2].y=ly2 - PSXDisplay.DisplayPosition.y+PreviousPSXDisplay.Range.y0; - - if(iOffscreenDrawing==4) // -> frontbuffer wanted - { - bRenderFrontBuffer=TRUE; - // return TRUE; - } - - return bFullVRam; // -> but no od - } - - return TRUE; -} - -//////////////////////////////////////////////////////////////////////// - -BOOL FastCheckAgainstScreen(short imageX0,short imageY0,short imageX1,short imageY1) -{ - PSXRect_t xUploadArea; - - imageX1 += imageX0; - imageY1 += imageY0; - - if (imageX0 < PreviousPSXDisplay.DisplayPosition.x) - xUploadArea.x0 = PreviousPSXDisplay.DisplayPosition.x; - else - if (imageX0 > PreviousPSXDisplay.DisplayEnd.x) - xUploadArea.x0 = PreviousPSXDisplay.DisplayEnd.x; - else - xUploadArea.x0 = imageX0; - - if(imageX1 < PreviousPSXDisplay.DisplayPosition.x) - xUploadArea.x1 = PreviousPSXDisplay.DisplayPosition.x; - else - if (imageX1 > PreviousPSXDisplay.DisplayEnd.x) - xUploadArea.x1 = PreviousPSXDisplay.DisplayEnd.x; - else - xUploadArea.x1 = imageX1; - - if (imageY0 < PreviousPSXDisplay.DisplayPosition.y) - xUploadArea.y0 = PreviousPSXDisplay.DisplayPosition.y; - else - if (imageY0 > PreviousPSXDisplay.DisplayEnd.y) - xUploadArea.y0 = PreviousPSXDisplay.DisplayEnd.y; - else - xUploadArea.y0 = imageY0; - - if (imageY1 < PreviousPSXDisplay.DisplayPosition.y) - xUploadArea.y1 = PreviousPSXDisplay.DisplayPosition.y; - else - if (imageY1 > PreviousPSXDisplay.DisplayEnd.y) - xUploadArea.y1 = PreviousPSXDisplay.DisplayEnd.y; - else - xUploadArea.y1 = imageY1; - - if ((xUploadArea.x0 != xUploadArea.x1) && (xUploadArea.y0 != xUploadArea.y1)) - return TRUE; - else return FALSE; -} - -BOOL CheckAgainstScreen(short imageX0,short imageY0,short imageX1,short imageY1) -{ - imageX1 += imageX0; - imageY1 += imageY0; - - if (imageX0 < PreviousPSXDisplay.DisplayPosition.x) - xrUploadArea.x0 = PreviousPSXDisplay.DisplayPosition.x; - else - if (imageX0 > PreviousPSXDisplay.DisplayEnd.x) - xrUploadArea.x0 = PreviousPSXDisplay.DisplayEnd.x; - else - xrUploadArea.x0 = imageX0; - - if(imageX1 < PreviousPSXDisplay.DisplayPosition.x) - xrUploadArea.x1 = PreviousPSXDisplay.DisplayPosition.x; - else - if (imageX1 > PreviousPSXDisplay.DisplayEnd.x) - xrUploadArea.x1 = PreviousPSXDisplay.DisplayEnd.x; - else - xrUploadArea.x1 = imageX1; - - if (imageY0 < PreviousPSXDisplay.DisplayPosition.y) - xrUploadArea.y0 = PreviousPSXDisplay.DisplayPosition.y; - else - if (imageY0 > PreviousPSXDisplay.DisplayEnd.y) - xrUploadArea.y0 = PreviousPSXDisplay.DisplayEnd.y; - else - xrUploadArea.y0 = imageY0; - - if (imageY1 < PreviousPSXDisplay.DisplayPosition.y) - xrUploadArea.y1 = PreviousPSXDisplay.DisplayPosition.y; - else - if (imageY1 > PreviousPSXDisplay.DisplayEnd.y) - xrUploadArea.y1 = PreviousPSXDisplay.DisplayEnd.y; - else - xrUploadArea.y1 = imageY1; - - if ((xrUploadArea.x0 != xrUploadArea.x1) && (xrUploadArea.y0 != xrUploadArea.y1)) - return TRUE; - else return FALSE; -} - -BOOL FastCheckAgainstFrontScreen(short imageX0,short imageY0,short imageX1,short imageY1) -{ - PSXRect_t xUploadArea; - - imageX1 += imageX0; - imageY1 += imageY0; - - if (imageX0 < PSXDisplay.DisplayPosition.x) - xUploadArea.x0 = PSXDisplay.DisplayPosition.x; - else - if (imageX0 > PSXDisplay.DisplayEnd.x) - xUploadArea.x0 = PSXDisplay.DisplayEnd.x; - else - xUploadArea.x0 = imageX0; - - if(imageX1 < PSXDisplay.DisplayPosition.x) - xUploadArea.x1 = PSXDisplay.DisplayPosition.x; - else - if (imageX1 > PSXDisplay.DisplayEnd.x) - xUploadArea.x1 = PSXDisplay.DisplayEnd.x; - else - xUploadArea.x1 = imageX1; - - if (imageY0 < PSXDisplay.DisplayPosition.y) - xUploadArea.y0 = PSXDisplay.DisplayPosition.y; - else - if (imageY0 > PSXDisplay.DisplayEnd.y) - xUploadArea.y0 = PSXDisplay.DisplayEnd.y; - else - xUploadArea.y0 = imageY0; - - if (imageY1 < PSXDisplay.DisplayPosition.y) - xUploadArea.y1 = PSXDisplay.DisplayPosition.y; - else - if (imageY1 > PSXDisplay.DisplayEnd.y) - xUploadArea.y1 = PSXDisplay.DisplayEnd.y; - else - xUploadArea.y1 = imageY1; - - if ((xUploadArea.x0 != xUploadArea.x1) && (xUploadArea.y0 != xUploadArea.y1)) - return TRUE; - else return FALSE; -} - -BOOL CheckAgainstFrontScreen(short imageX0,short imageY0,short imageX1,short imageY1) -{ - imageX1 += imageX0; - imageY1 += imageY0; - - if (imageX0 < PSXDisplay.DisplayPosition.x) - xrUploadArea.x0 = PSXDisplay.DisplayPosition.x; - else - if (imageX0 > PSXDisplay.DisplayEnd.x) - xrUploadArea.x0 = PSXDisplay.DisplayEnd.x; - else - xrUploadArea.x0 = imageX0; - - if(imageX1 < PSXDisplay.DisplayPosition.x) - xrUploadArea.x1 = PSXDisplay.DisplayPosition.x; - else - if (imageX1 > PSXDisplay.DisplayEnd.x) - xrUploadArea.x1 = PSXDisplay.DisplayEnd.x; - else - xrUploadArea.x1 = imageX1; - - if (imageY0 < PSXDisplay.DisplayPosition.y) - xrUploadArea.y0 = PSXDisplay.DisplayPosition.y; - else - if (imageY0 > PSXDisplay.DisplayEnd.y) - xrUploadArea.y0 = PSXDisplay.DisplayEnd.y; - else - xrUploadArea.y0 = imageY0; - - if (imageY1 < PSXDisplay.DisplayPosition.y) - xrUploadArea.y1 = PSXDisplay.DisplayPosition.y; - else - if (imageY1 > PSXDisplay.DisplayEnd.y) - xrUploadArea.y1 = PSXDisplay.DisplayEnd.y; - else - xrUploadArea.y1 = imageY1; - - if ((xrUploadArea.x0 != xrUploadArea.x1) && (xrUploadArea.y0 != xrUploadArea.y1)) - return TRUE; - else return FALSE; -} - -//////////////////////////////////////////////////////////////////////// - -void PrepareFullScreenUpload (int Position) -{ - if (Position==-1) // rgb24 - { - if(PSXDisplay.Interlaced) - { - xrUploadArea.x0 = PSXDisplay.DisplayPosition.x; - xrUploadArea.x1 = PSXDisplay.DisplayEnd.x; - xrUploadArea.y0 = PSXDisplay.DisplayPosition.y; - xrUploadArea.y1 = PSXDisplay.DisplayEnd.y; - } - else - { - xrUploadArea.x0 = PreviousPSXDisplay.DisplayPosition.x; - xrUploadArea.x1 = PreviousPSXDisplay.DisplayEnd.x; - xrUploadArea.y0 = PreviousPSXDisplay.DisplayPosition.y; - xrUploadArea.y1 = PreviousPSXDisplay.DisplayEnd.y; - } - - if(bNeedRGB24Update) - { - if(lClearOnSwap) - { -// lClearOnSwap=0; - } - else - if(PSXDisplay.Interlaced && PreviousPSXDisplay.RGB24<2) // in interlaced mode we upload at least two full frames (GT1 menu) - { - PreviousPSXDisplay.RGB24++; - } - else - { - xrUploadArea.y1 = min(xrUploadArea.y0+xrUploadAreaRGB24.y1,xrUploadArea.y1); - xrUploadArea.y0+=xrUploadAreaRGB24.y0; - } - } - } - else - if (Position) - { - xrUploadArea.x0 = PSXDisplay.DisplayPosition.x; - xrUploadArea.x1 = PSXDisplay.DisplayEnd.x; - xrUploadArea.y0 = PSXDisplay.DisplayPosition.y; - xrUploadArea.y1 = PSXDisplay.DisplayEnd.y; - } - else - { - xrUploadArea.x0 = PreviousPSXDisplay.DisplayPosition.x; - xrUploadArea.x1 = PreviousPSXDisplay.DisplayEnd.x; - xrUploadArea.y0 = PreviousPSXDisplay.DisplayPosition.y; - xrUploadArea.y1 = PreviousPSXDisplay.DisplayEnd.y; - } - - if (xrUploadArea.x0 < 0) xrUploadArea.x0 = 0; - else - if (xrUploadArea.x0 > 1023) xrUploadArea.x0 = 1023; - - if (xrUploadArea.x1 < 0) xrUploadArea.x1 = 0; - else - if (xrUploadArea.x1 > 1024) xrUploadArea.x1 = 1024; - - if (xrUploadArea.y0 < 0) xrUploadArea.y0 = 0; - else - if (xrUploadArea.y0 > iGPUHeightMask) xrUploadArea.y0 = iGPUHeightMask; - - if (xrUploadArea.y1 < 0) xrUploadArea.y1 = 0; - else - if (xrUploadArea.y1 > iGPUHeight) xrUploadArea.y1 = iGPUHeight; - - if (PSXDisplay.RGB24) - { - InvalidateTextureArea(xrUploadArea.x0,xrUploadArea.y0,xrUploadArea.x1-xrUploadArea.x0,xrUploadArea.y1-xrUploadArea.y0); - } -} - -//////////////////////////////////////////////////////////////////////// -// Upload screen (MDEC and such) -//////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////// - -static void UploadScreenEx(int Position) -{ - short ya,yb,xa,xb,x, y, YStep, XStep, U, UStep,ux[4],vy[4]; - - if(!PSXDisplay.DisplayMode.x) return; - if(!PSXDisplay.DisplayMode.y) return; - - glDisable(GL_SCISSOR_TEST); - glShadeModel(GL_FLAT); - bOldSmoothShaded=FALSE; - glDisable(GL_BLEND); - bBlendEnable=FALSE; - glDisable(GL_TEXTURE_2D); - bTexEnabled=FALSE; - glDisable(GL_ALPHA_TEST); - - glPixelZoom(((float)rRatioRect.right)/((float)PSXDisplay.DisplayMode.x), - -1.0f*(((float)rRatioRect.bottom)/((float)PSXDisplay.DisplayMode.y))); - - //----------------------------------------------------// - - YStep = 256; // max texture size - XStep = 256; - UStep = (PSXDisplay.RGB24 ? 128 : 0); - ya = xrUploadArea.y0; - yb = xrUploadArea.y1; - xa = xrUploadArea.x0; - xb = xrUploadArea.x1; - - for(y=ya;y<=yb;y+=YStep) // loop y - { - U = 0; - for(x=xa;x<=xb;x+=XStep) // loop x - { - ly0 = ly1 = y; // -> get y coords - ly2 = y + YStep; - if (ly2 > yb) ly2 = yb; - ly3 = ly2; - - lx0 = lx3 = x; // -> get x coords - lx1 = x + XStep; - if (lx1 > xb) lx1 = xb; - - lx2 = lx1; - - ux[0]=ux[3]=(xa - x); // -> set tex x coords - if (ux[0] < 0) ux[0]=ux[3]=0; - ux[2]=ux[1]=(xb - x); - if (ux[2] > 256) ux[2]=ux[1]=256; - - vy[0]=vy[1]=(ya - y); // -> set tex y coords - if (vy[0] < 0) vy[0]=vy[1]=0; - vy[2]=vy[3]=(yb - y); - if (vy[2] > 256) vy[2]=vy[3]=256; - - if ((ux[0] >= ux[2]) || // -> cheaters never win... - (vy[0] >= vy[2])) continue; // (but winners always cheat...) - - xrMovieArea.x0=lx0+U; xrMovieArea.y0=ly0; - xrMovieArea.x1=lx2+U; xrMovieArea.y1=ly2; - - offsetScreenUpload(Position); - - glRasterPos2f(vertex[0].x,vertex[0].y); - - glDrawPixels(xrMovieArea.x1-xrMovieArea.x0, - xrMovieArea.y1-xrMovieArea.y0, - GL_RGBA,GL_UNSIGNED_BYTE, - LoadDirectMovieFast()); - - U+=UStep; - } - } - - //----------------------------------------------------// - - glPixelZoom(1.0F,1.0F); - - glEnable(GL_ALPHA_TEST); - glEnable(GL_SCISSOR_TEST); -} - -//////////////////////////////////////////////////////////////////////// - -void UploadScreen(int Position) -{ - short x, y, YStep, XStep, U, s, UStep,ux[4],vy[4]; - short xa,xb,ya,yb; - - if(xrUploadArea.x0>1023) xrUploadArea.x0=1023; - if(xrUploadArea.x1>1024) xrUploadArea.x1=1024; - if(xrUploadArea.y0>iGPUHeightMask) xrUploadArea.y0=iGPUHeightMask; - if(xrUploadArea.y1>iGPUHeight) xrUploadArea.y1=iGPUHeight; - - if(xrUploadArea.x0==xrUploadArea.x1) return; - if(xrUploadArea.y0==xrUploadArea.y1) return; - - if(PSXDisplay.Disabled && iOffscreenDrawing<4) return; - - iDrawnSomething = 2; - iLastRGB24=PSXDisplay.RGB24+1; - - if(bSkipNextFrame) return; - - if(dwActFixes & 2) {UploadScreenEx(Position);return;} - - bUsingMovie = TRUE; - bDrawTextured = TRUE; // just doing textures - bDrawSmoothShaded = FALSE; - - if(bGLBlend) vertex[0].c.lcol=0xff7f7f7f; // set solid col - else vertex[0].c.lcol=0xffffffff; - SETCOL(vertex[0]); - - SetOGLDisplaySettings(0); - - YStep = 256; // max texture size - XStep = 256; - - UStep = (PSXDisplay.RGB24 ? 128 : 0); - - ya=xrUploadArea.y0; - yb=xrUploadArea.y1; - xa=xrUploadArea.x0; - xb=xrUploadArea.x1; - - for(y=ya;y<=yb;y+=YStep) // loop y - { - U = 0; - for(x=xa;x<=xb;x+=XStep) // loop x - { - ly0 = ly1 = y; // -> get y coords - ly2 = y + YStep; - if (ly2 > yb) ly2 = yb; - ly3 = ly2; - - lx0 = lx3 = x; // -> get x coords - lx1 = x + XStep; - if (lx1 > xb) lx1 = xb; - - lx2 = lx1; - - ux[0]=ux[3]=(xa - x); // -> set tex x coords - if (ux[0] < 0) ux[0]=ux[3]=0; - ux[2]=ux[1]=(xb - x); - if (ux[2] > 256) ux[2]=ux[1]=256; - - vy[0]=vy[1]=(ya - y); // -> set tex y coords - if (vy[0] < 0) vy[0]=vy[1]=0; - vy[2]=vy[3]=(yb - y); - if (vy[2] > 256) vy[2]=vy[3]=256; - - if ((ux[0] >= ux[2]) || // -> cheaters never win... - (vy[0] >= vy[2])) continue; // (but winners always cheat...) - - xrMovieArea.x0=lx0+U; xrMovieArea.y0=ly0; - xrMovieArea.x1=lx2+U; xrMovieArea.y1=ly2; - - s=ux[2] - ux[0]; if(s>255) s=255; - - gl_ux[2] = gl_ux[1] = s; - s=vy[2] - vy[0]; if(s>255) s=255; - gl_vy[2] = gl_vy[3] = s; - gl_ux[0] = gl_ux[3] = gl_vy[0] = gl_vy[1] = 0; - - SetRenderState((uint32_t)0x01000000); - SetRenderMode((uint32_t)0x01000000, FALSE); // upload texture data - offsetScreenUpload(Position); - assignTextureVRAMWrite(); - - PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]); - - U+=UStep; - } - } - - bUsingMovie=FALSE; // done... - bDisplayNotSet = TRUE; -} - -//////////////////////////////////////////////////////////////////////// -// Detect next screen -//////////////////////////////////////////////////////////////////////// - -static BOOL IsCompleteInsideNextScreen(short x, short y, short xoff, short yoff) -{ - if (x > PSXDisplay.DisplayPosition.x+1) return FALSE; - if ((x + xoff) < PSXDisplay.DisplayEnd.x-1) return FALSE; - yoff+=y; - if (y >= PSXDisplay.DisplayPosition.y && - y <= PSXDisplay.DisplayEnd.y ) - { - if ((yoff) >= PSXDisplay.DisplayPosition.y && - (yoff) <= PSXDisplay.DisplayEnd.y ) return TRUE; - } - if (y > PSXDisplay.DisplayPosition.y+1) return FALSE; - if (yoff < PSXDisplay.DisplayEnd.y-1) return FALSE; - return TRUE; -} - -static BOOL IsPrimCompleteInsideNextScreen(short x, short y, short xoff, short yoff) -{ - x+=PSXDisplay.DrawOffset.x; - if (x > PSXDisplay.DisplayPosition.x+1) return FALSE; - y+=PSXDisplay.DrawOffset.y; - if (y > PSXDisplay.DisplayPosition.y+1) return FALSE; - xoff+=PSXDisplay.DrawOffset.x; - if (xoff < PSXDisplay.DisplayEnd.x-1) return FALSE; - yoff+=PSXDisplay.DrawOffset.y; - if (yoff < PSXDisplay.DisplayEnd.y-1) return FALSE; - return TRUE; -} - -#if 0 -static BOOL IsInsideNextScreen(short x, short y, short xoff, short yoff) -{ - if (x > PSXDisplay.DisplayEnd.x) return FALSE; - if (y > PSXDisplay.DisplayEnd.y) return FALSE; - if ((x + xoff) < PSXDisplay.DisplayPosition.x) return FALSE; - if ((y + yoff) < PSXDisplay.DisplayPosition.y) return FALSE; - return TRUE; -} -#endif - -//////////////////////////////////////////////////////////////////////// -// mask stuff... -//////////////////////////////////////////////////////////////////////// - -//Mask1 Set mask bit while drawing. 1 = on -//Mask2 Do not draw to mask areas. 1= on - -static void cmdSTP(unsigned char * baseAddr) -{ - uint32_t gdata = ((uint32_t*)baseAddr)[0]; - - STATUSREG&=~0x1800; // clear the necessary bits - STATUSREG|=((gdata & 0x03) << 11); // set the current bits - - if(!iUseMask) return; - - if(gdata&1) {sSetMask=0x8000;lSetMask=0x80008000;iSetMask=1;} - else {sSetMask=0; lSetMask=0; iSetMask=0;} - - if(gdata&2) - { - if(!(gdata&1)) iSetMask=2; - bCheckMask=TRUE; - if(iDepthFunc==0) return; - iDepthFunc=0; - glDepthFunc(GL_LESS); - } - else - { - bCheckMask=FALSE; - if(iDepthFunc==1) return; - glDepthFunc(GL_ALWAYS); - iDepthFunc=1; - } -} - -//////////////////////////////////////////////////////////////////////// -// cmd: Set texture page infos -//////////////////////////////////////////////////////////////////////// - -static void cmdTexturePage(unsigned char * baseAddr) -{ - uint32_t gdata = ((uint32_t *)baseAddr)[0]; - UpdateGlobalTP((unsigned short)gdata); - GlobalTextREST = (gdata&0x00ffffff)>>9; -} - -//////////////////////////////////////////////////////////////////////// -// cmd: turn on/off texture window -//////////////////////////////////////////////////////////////////////// - -static void cmdTextureWindow(unsigned char *baseAddr) -{ - uint32_t gdata = ((uint32_t *)baseAddr)[0]; - uint32_t YAlign,XAlign; - - ulGPUInfoVals[INFO_TW]=gdata&0xFFFFF; - - if(gdata & 0x020) - TWin.Position.y1 = 8; // xxxx1 - else if (gdata & 0x040) - TWin.Position.y1 = 16; // xxx10 - else if (gdata & 0x080) - TWin.Position.y1 = 32; // xx100 - else if (gdata & 0x100) - TWin.Position.y1 = 64; // x1000 - else if (gdata & 0x200) - TWin.Position.y1 = 128; // 10000 - else - TWin.Position.y1 = 256; // 00000 - - // Texture window size is determined by the least bit set of the relevant 5 bits - - if (gdata & 0x001) - TWin.Position.x1 = 8; // xxxx1 - else if (gdata & 0x002) - TWin.Position.x1 = 16; // xxx10 - else if (gdata & 0x004) - TWin.Position.x1 = 32; // xx100 - else if (gdata & 0x008) - TWin.Position.x1 = 64; // x1000 - else if (gdata & 0x010) - TWin.Position.x1 = 128; // 10000 - else - TWin.Position.x1 = 256; // 00000 - - // Re-calculate the bit field, because we can't trust what is passed in the data - - YAlign = (uint32_t)(32 - (TWin.Position.y1 >> 3)); - XAlign = (uint32_t)(32 - (TWin.Position.x1 >> 3)); - - // Absolute position of the start of the texture window - - TWin.Position.y0 = (short)(((gdata >> 15) & YAlign) << 3); - TWin.Position.x0 = (short)(((gdata >> 10) & XAlign) << 3); - - if((TWin.Position.x0 == 0 && // tw turned off - TWin.Position.y0 == 0 && - TWin.Position.x1 == 0 && - TWin.Position.y1 == 0) || - (TWin.Position.x1 == 256 && - TWin.Position.y1 == 256)) - { - bUsingTWin = FALSE; // -> just do it - -#ifdef OWNSCALE - TWin.UScaleFactor = 1.0f; - TWin.VScaleFactor = 1.0f; -#else - TWin.UScaleFactor = - TWin.VScaleFactor = 1.0f/256.0f; -#endif - } - else // tw turned on - { - bUsingTWin = TRUE; - - TWin.OPosition.y1 = TWin.Position.y1; // -> get psx sizes - TWin.OPosition.x1 = TWin.Position.x1; - - if(TWin.Position.x1<=2) TWin.Position.x1=2; // -> set OGL sizes - else - if(TWin.Position.x1<=4) TWin.Position.x1=4; - else - if(TWin.Position.x1<=8) TWin.Position.x1=8; - else - if(TWin.Position.x1<=16) TWin.Position.x1=16; - else - if(TWin.Position.x1<=32) TWin.Position.x1=32; - else - if(TWin.Position.x1<=64) TWin.Position.x1=64; - else - if(TWin.Position.x1<=128) TWin.Position.x1=128; - else - if(TWin.Position.x1<=256) TWin.Position.x1=256; - - if(TWin.Position.y1<=2) TWin.Position.y1=2; - else - if(TWin.Position.y1<=4) TWin.Position.y1=4; - else - if(TWin.Position.y1<=8) TWin.Position.y1=8; - else - if(TWin.Position.y1<=16) TWin.Position.y1=16; - else - if(TWin.Position.y1<=32) TWin.Position.y1=32; - else - if(TWin.Position.y1<=64) TWin.Position.y1=64; - else - if(TWin.Position.y1<=128) TWin.Position.y1=128; - else - if(TWin.Position.y1<=256) TWin.Position.y1=256; - -#ifdef OWNSCALE - TWin.UScaleFactor = (float)TWin.Position.x1; - TWin.VScaleFactor = (float)TWin.Position.y1; -#else - TWin.UScaleFactor = ((float)TWin.Position.x1)/256.0f; // -> set scale factor - TWin.VScaleFactor = ((float)TWin.Position.y1)/256.0f; -#endif - } -} - -//////////////////////////////////////////////////////////////////////// -// mmm, Lewpy uses that in TileS ... I don't ;) -//////////////////////////////////////////////////////////////////////// - -/* -void ClampToPSXDrawAreaOffset(short *x0, short *y0, short *x1, short *y1) -{ - if (*x0 < PSXDisplay.DrawArea.x0) - { - *x1 -= (PSXDisplay.DrawArea.x0 - *x0); - *x0 = PSXDisplay.DrawArea.x0; - } - else - if (*x0 > PSXDisplay.DrawArea.x1) - { - *x0 = PSXDisplay.DrawArea.x1; - *x1 = 0; - } - - if (*y0 < PSXDisplay.DrawArea.y0) - { - *y1 -= (PSXDisplay.DrawArea.y0 - *y0); - *y0 = PSXDisplay.DrawArea.y0; - } - else - if (*y0 > PSXDisplay.DrawArea.y1) - { - *y0 = PSXDisplay.DrawArea.y1; - *y1 = 0; - } - - if (*x1 < 0) *x1 = 0; - - if ((*x1 + *x0) > PSXDisplay.DrawArea.x1) - *x1 = (PSXDisplay.DrawArea.x1 - *x0 + 1); - - if (*y1 < 0) *y1 = 0; - - if ((*y1 + *y0) > PSXDisplay.DrawArea.y1) - *y1 = (PSXDisplay.DrawArea.y1 - *y0 + 1); -} -*/ - -//////////////////////////////////////////////////////////////////////// -// Check draw area dimensions -//////////////////////////////////////////////////////////////////////// - -static void ClampToPSXScreen(short *x0, short *y0, short *x1, short *y1) -{ - if (*x0 < 0) *x0 = 0; - else - if (*x0 > 1023) *x0 = 1023; - - if (*x1 < 0) *x1 = 0; - else - if (*x1 > 1023) *x1 = 1023; - - if (*y0 < 0) *y0 = 0; - else - if (*y0 > iGPUHeightMask) *y0 = iGPUHeightMask; - - if (*y1 < 0) *y1 = 0; - else - if (*y1 > iGPUHeightMask) *y1 = iGPUHeightMask; -} - -//////////////////////////////////////////////////////////////////////// -// Used in Load Image and Blk Fill -//////////////////////////////////////////////////////////////////////// - -static void ClampToPSXScreenOffset(short *x0, short *y0, short *x1, short *y1) -{ - if (*x0 < 0) - { *x1 += *x0; *x0 = 0; } - else - if (*x0 > 1023) - { *x0 = 1023; *x1 = 0; } - - if (*y0 < 0) - { *y1 += *y0; *y0 = 0; } - else - if (*y0 > iGPUHeightMask) - { *y0 = iGPUHeightMask; *y1 = 0; } - - if (*x1 < 0) *x1 = 0; - - if ((*x1 + *x0) > 1024) *x1 = (1024 - *x0); - - if (*y1 < 0) *y1 = 0; - - if ((*y1 + *y0) > iGPUHeight) *y1 = (iGPUHeight - *y0); -} - -//////////////////////////////////////////////////////////////////////// -// cmd: start of drawing area... primitives will be clipped inside -//////////////////////////////////////////////////////////////////////// - -static void cmdDrawAreaStart(unsigned char * baseAddr) -{ - uint32_t gdata = ((uint32_t *)baseAddr)[0]; - - drawX = gdata & 0x3ff; // for soft drawing - if(drawX>=1024) drawX=1023; - - if(dwGPUVersion==2) - { - ulGPUInfoVals[INFO_DRAWSTART]=gdata&0x3FFFFF; - drawY = (gdata>>12)&0x3ff; - } - else - { - ulGPUInfoVals[INFO_DRAWSTART]=gdata&0xFFFFF; - drawY = (gdata>>10)&0x3ff; - } - - if(drawY>=iGPUHeight) drawY=iGPUHeightMask; - - PreviousPSXDisplay.DrawArea.y0=PSXDisplay.DrawArea.y0; - PreviousPSXDisplay.DrawArea.x0=PSXDisplay.DrawArea.x0; - - PSXDisplay.DrawArea.y0 = (short)drawY; // for OGL drawing - PSXDisplay.DrawArea.x0 = (short)drawX; -} - -//////////////////////////////////////////////////////////////////////// -// cmd: end of drawing area... primitives will be clipped inside -//////////////////////////////////////////////////////////////////////// - -static void cmdDrawAreaEnd(unsigned char * baseAddr) -{ - uint32_t gdata = ((uint32_t *)baseAddr)[0]; - - drawW = gdata & 0x3ff; // for soft drawing - if(drawW>=1024) drawW=1023; - - if(dwGPUVersion==2) - { - ulGPUInfoVals[INFO_DRAWEND]=gdata&0x3FFFFF; - drawH = (gdata>>12)&0x3ff; - } - else - { - ulGPUInfoVals[INFO_DRAWEND]=gdata&0xFFFFF; - drawH = (gdata>>10)&0x3ff; - } - - if(drawH>=iGPUHeight) drawH=iGPUHeightMask; - - PSXDisplay.DrawArea.y1 = (short)drawH; // for OGL drawing - PSXDisplay.DrawArea.x1 = (short)drawW; - - ClampToPSXScreen(&PSXDisplay.DrawArea.x0, // clamp - &PSXDisplay.DrawArea.y0, - &PSXDisplay.DrawArea.x1, - &PSXDisplay.DrawArea.y1); - - bDisplayNotSet = TRUE; -} - -//////////////////////////////////////////////////////////////////////// -// cmd: draw offset... will be added to prim coords -//////////////////////////////////////////////////////////////////////// - -static void cmdDrawOffset(unsigned char * baseAddr) -{ - uint32_t gdata = ((uint32_t *)baseAddr)[0]; - - PreviousPSXDisplay.DrawOffset.x = - PSXDisplay.DrawOffset.x = (short)(gdata & 0x7ff); - - if (dwGPUVersion == 2) - { - ulGPUInfoVals[INFO_DRAWOFF] = gdata&0x7FFFFF; - PSXDisplay.DrawOffset.y = (short)((gdata>>12) & 0x7ff); - } - else - { - ulGPUInfoVals[INFO_DRAWOFF]=gdata&0x3FFFFF; - PSXDisplay.DrawOffset.y = (short)((gdata>>11) & 0x7ff); - } - - PSXDisplay.DrawOffset.x=(short)(((int)PSXDisplay.DrawOffset.x<<21)>>21); - PSXDisplay.DrawOffset.y=(short)(((int)PSXDisplay.DrawOffset.y<<21)>>21); - - PSXDisplay.CumulOffset.x = // new OGL prim offsets - PSXDisplay.DrawOffset.x - PSXDisplay.GDrawOffset.x + PreviousPSXDisplay.Range.x0; - PSXDisplay.CumulOffset.y = - PSXDisplay.DrawOffset.y - PSXDisplay.GDrawOffset.y + PreviousPSXDisplay.Range.y0; -} - -//////////////////////////////////////////////////////////////////////// -// cmd: load image to vram -//////////////////////////////////////////////////////////////////////// - -static void primLoadImage(unsigned char * baseAddr) -{ - unsigned short *sgpuData = ((unsigned short *) baseAddr); - - VRAMWrite.x = sgpuData[2]&0x03ff; - VRAMWrite.y = sgpuData[3]&iGPUHeightMask; - VRAMWrite.Width = sgpuData[4]; - VRAMWrite.Height = sgpuData[5]; - - iDataWriteMode = DR_VRAMTRANSFER; - VRAMWrite.ImagePtr = psxVuw + (VRAMWrite.y<<10) + VRAMWrite.x; - VRAMWrite.RowsRemaining = VRAMWrite.Width; - VRAMWrite.ColsRemaining = VRAMWrite.Height; - - bNeedWriteUpload=TRUE; -} - -//////////////////////////////////////////////////////////////////////// - -static void PrepareRGB24Upload(void) -{ - VRAMWrite.x=(VRAMWrite.x*2)/3; - VRAMWrite.Width=(VRAMWrite.Width*2)/3; - - if(!PSXDisplay.InterlacedTest && // NEW - CheckAgainstScreen(VRAMWrite.x, VRAMWrite.y, VRAMWrite.Width, VRAMWrite.Height)) - { - xrUploadArea.x0-=PreviousPSXDisplay.DisplayPosition.x; - xrUploadArea.x1-=PreviousPSXDisplay.DisplayPosition.x; - xrUploadArea.y0-=PreviousPSXDisplay.DisplayPosition.y; - xrUploadArea.y1-=PreviousPSXDisplay.DisplayPosition.y; - } - else - if(CheckAgainstFrontScreen(VRAMWrite.x, VRAMWrite.y, VRAMWrite.Width, VRAMWrite.Height)) - { - xrUploadArea.x0-=PSXDisplay.DisplayPosition.x; - xrUploadArea.x1-=PSXDisplay.DisplayPosition.x; - xrUploadArea.y0-=PSXDisplay.DisplayPosition.y; - xrUploadArea.y1-=PSXDisplay.DisplayPosition.y; - } - else return; - - if(bRenderFrontBuffer) - { - updateFrontDisplay(); - } - - if(bNeedRGB24Update==FALSE) - { - xrUploadAreaRGB24=xrUploadArea; - bNeedRGB24Update=TRUE; - } - else - { - xrUploadAreaRGB24.x0=min(xrUploadAreaRGB24.x0,xrUploadArea.x0); - xrUploadAreaRGB24.x1=max(xrUploadAreaRGB24.x1,xrUploadArea.x1); - xrUploadAreaRGB24.y0=min(xrUploadAreaRGB24.y0,xrUploadArea.y0); - xrUploadAreaRGB24.y1=max(xrUploadAreaRGB24.y1,xrUploadArea.y1); - } -} - -//////////////////////////////////////////////////////////////////////// - -void CheckWriteUpdate() -{ - int iX=0,iY=0; - - if(VRAMWrite.Width) iX=1; - if(VRAMWrite.Height) iY=1; - - InvalidateTextureArea(VRAMWrite.x, VRAMWrite.y, VRAMWrite.Width-iX, VRAMWrite.Height-iY); - - if(PSXDisplay.Interlaced && !iOffscreenDrawing) return; - - if(PSXDisplay.RGB24) {PrepareRGB24Upload();return;} - - if(!PSXDisplay.InterlacedTest && - CheckAgainstScreen(VRAMWrite.x, VRAMWrite.y, VRAMWrite.Width, VRAMWrite.Height)) - { - if(dwActFixes&0x800) return; - - if(bRenderFrontBuffer) - { - updateFrontDisplay(); - } - - UploadScreen(FALSE); - - bNeedUploadTest=TRUE; - } - else - if(iOffscreenDrawing) - { - if (CheckAgainstFrontScreen(VRAMWrite.x, VRAMWrite.y, VRAMWrite.Width, VRAMWrite.Height)) - { - if(PSXDisplay.InterlacedTest) - { - if(PreviousPSXDisplay.InterlacedNew) - { - PreviousPSXDisplay.InterlacedNew=FALSE; - bNeedInterlaceUpdate=TRUE; - xrUploadAreaIL.x0=PSXDisplay.DisplayPosition.x; - xrUploadAreaIL.y0=PSXDisplay.DisplayPosition.y; - xrUploadAreaIL.x1=PSXDisplay.DisplayPosition.x+PSXDisplay.DisplayModeNew.x; - xrUploadAreaIL.y1=PSXDisplay.DisplayPosition.y+PSXDisplay.DisplayModeNew.y; - if(xrUploadAreaIL.x1>1023) xrUploadAreaIL.x1=1023; - if(xrUploadAreaIL.y1>511) xrUploadAreaIL.y1=511; - } - - if(bNeedInterlaceUpdate==FALSE) - { - xrUploadAreaIL=xrUploadArea; - bNeedInterlaceUpdate=TRUE; - } - else - { - xrUploadAreaIL.x0=min(xrUploadAreaIL.x0,xrUploadArea.x0); - xrUploadAreaIL.x1=max(xrUploadAreaIL.x1,xrUploadArea.x1); - xrUploadAreaIL.y0=min(xrUploadAreaIL.y0,xrUploadArea.y0); - xrUploadAreaIL.y1=max(xrUploadAreaIL.y1,xrUploadArea.y1); - } - return; - } - - if(!bNeedUploadAfter) - { - bNeedUploadAfter = TRUE; - xrUploadArea.x0=VRAMWrite.x; - xrUploadArea.x1=VRAMWrite.x+VRAMWrite.Width; - xrUploadArea.y0=VRAMWrite.y; - xrUploadArea.y1=VRAMWrite.y+VRAMWrite.Height; - } - else - { - xrUploadArea.x0=min(xrUploadArea.x0,VRAMWrite.x); - xrUploadArea.x1=max(xrUploadArea.x1,VRAMWrite.x+VRAMWrite.Width); - xrUploadArea.y0=min(xrUploadArea.y0,VRAMWrite.y); - xrUploadArea.y1=max(xrUploadArea.y1,VRAMWrite.y+VRAMWrite.Height); - } - - if(dwActFixes&0x8000) - { - if((xrUploadArea.x1-xrUploadArea.x0)>=(PSXDisplay.DisplayMode.x-32) && - (xrUploadArea.y1-xrUploadArea.y0)>=(PSXDisplay.DisplayMode.y-32)) - { - UploadScreen(-1); - updateFrontDisplay(); - } - } - } - } -} - -//////////////////////////////////////////////////////////////////////// -// cmd: vram -> psx mem -//////////////////////////////////////////////////////////////////////// - -static void primStoreImage(unsigned char * baseAddr) -{ - unsigned short *sgpuData = ((unsigned short *) baseAddr); - - VRAMRead.x = sgpuData[2]&0x03ff; - VRAMRead.y = sgpuData[3]&iGPUHeightMask; - VRAMRead.Width = sgpuData[4]; - VRAMRead.Height = sgpuData[5]; - - VRAMRead.ImagePtr = psxVuw + (VRAMRead.y<<10) + VRAMRead.x; - VRAMRead.RowsRemaining = VRAMRead.Width; - VRAMRead.ColsRemaining = VRAMRead.Height; - - iDataReadMode = DR_VRAMTRANSFER; - - STATUSREG |= GPUSTATUS_READYFORVRAM; -} - -//////////////////////////////////////////////////////////////////////// -// cmd: blkfill - NO primitive! Doesn't care about draw areas... -//////////////////////////////////////////////////////////////////////// - -static void primBlkFill(unsigned char * baseAddr) -{ - uint32_t *gpuData = ((uint32_t *) baseAddr); - short *sgpuData = ((short *) baseAddr); - - iDrawnSomething = 1; - - sprtX = sgpuData[2]; - sprtY = sgpuData[3]; - sprtW = sgpuData[4] & 0x3ff; - sprtH = sgpuData[5] & iGPUHeightMask; - - sprtW = (sprtW + 15) & ~15; - - // Increase H & W if they are one short of full values, because they never can be full values - if (sprtH == iGPUHeightMask) sprtH=iGPUHeight; - if (sprtW == 1023) sprtW=1024; - - // x and y of start - ly0 = ly1 = sprtY; - ly2 = ly3 = (sprtY+sprtH); - lx0 = lx3 = sprtX; - lx1 = lx2 = (sprtX+sprtW); - - offsetBlk(); - - if(ClipVertexListScreen()) - { - PSXDisplay_t * pd; - if(PSXDisplay.InterlacedTest) pd=&PSXDisplay; - else pd=&PreviousPSXDisplay; - - if ((lx0 <= pd->DisplayPosition.x+16) && - (ly0 <= pd->DisplayPosition.y+16) && - (lx2 >= pd->DisplayEnd.x-16) && - (ly2 >= pd->DisplayEnd.y-16)) - { - GLclampf g,b,r; - g=((GLclampf)GREEN(gpuData[0]))/255.0f; - b=((GLclampf)BLUE(gpuData[0]))/255.0f; - r=((GLclampf)RED(gpuData[0]))/255.0f; - - glDisable(GL_SCISSOR_TEST); - glClearColor(r,g,b,1.0f); - glClear(uiBufferBits); - gl_z=0.0f; - - if(gpuData[0]!=0x02000000 && - (ly0>pd->DisplayPosition.y || - ly2<pd->DisplayEnd.y)) - { - bDrawTextured = FALSE; - bDrawSmoothShaded = FALSE; - SetRenderState((uint32_t)0x01000000); - SetRenderMode((uint32_t)0x01000000, FALSE); - vertex[0].c.lcol=0xff000000; - SETCOL(vertex[0]); - if(ly0>pd->DisplayPosition.y) - { - vertex[0].x=0;vertex[0].y=0; - vertex[1].x=pd->DisplayEnd.x-pd->DisplayPosition.x;vertex[1].y=0; - vertex[2].x=vertex[1].x;vertex[2].y=ly0-pd->DisplayPosition.y; - vertex[3].x=0;vertex[3].y=vertex[2].y; - PRIMdrawQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]); - } - if(ly2<pd->DisplayEnd.y) - { - vertex[0].x=0;vertex[0].y=(pd->DisplayEnd.y-pd->DisplayPosition.y)-(pd->DisplayEnd.y-ly2); - vertex[1].x=pd->DisplayEnd.x-pd->DisplayPosition.x;vertex[1].y=vertex[0].y; - vertex[2].x=vertex[1].x;vertex[2].y=pd->DisplayEnd.y; - vertex[3].x=0;vertex[3].y=vertex[2].y; - PRIMdrawQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]); - } - } - - glEnable(GL_SCISSOR_TEST); - } - else - { - bDrawTextured = FALSE; - bDrawSmoothShaded = FALSE; - SetRenderState((uint32_t)0x01000000); - SetRenderMode((uint32_t)0x01000000, FALSE); - vertex[0].c.lcol=gpuData[0]|0xff000000; - SETCOL(vertex[0]); - glDisable(GL_SCISSOR_TEST); - PRIMdrawQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]); - glEnable(GL_SCISSOR_TEST); - } - } - - //mmm... will clean all stuff, also if not all _should_ be cleaned... - //if (IsInsideNextScreen(sprtX, sprtY, sprtW, sprtH)) - // try this: - if (IsCompleteInsideNextScreen(sprtX, sprtY, sprtW, sprtH)) - { - lClearOnSwapColor = COLOR(gpuData[0]); - lClearOnSwap = 1; - } - - if(iOffscreenDrawing) - { - ClampToPSXScreenOffset( &sprtX, &sprtY, &sprtW, &sprtH); - if ((sprtW == 0) || (sprtH == 0)) return; - InvalidateTextureArea(sprtX, sprtY, sprtW-1, sprtH-1); - - sprtW+=sprtX; - sprtH+=sprtY; - - FillSoftwareArea(sprtX, sprtY, sprtW, sprtH, BGR24to16(gpuData[0])); - } -} - -//////////////////////////////////////////////////////////////////////// -// cmd: move image vram -> vram -//////////////////////////////////////////////////////////////////////// - -static void MoveImageWrapped(short imageX0,short imageY0, - short imageX1,short imageY1, - short imageSX,short imageSY) -{ - int i,j,imageXE,imageYE; - - if(iFrameReadType&2) - { - imageXE=imageX0+imageSX; - imageYE=imageY0+imageSY; - - if(imageYE>iGPUHeight && imageXE>1024) - { - CheckVRamRead(0,0, - (imageXE&0x3ff), - (imageY0&iGPUHeightMask), - FALSE); - } - - if(imageXE>1024) - { - CheckVRamRead(0,imageY0, - (imageXE&0x3ff), - (imageYE>iGPUHeight)?iGPUHeight:imageYE, - FALSE); - } - - if(imageYE>iGPUHeight) - { - CheckVRamRead(imageX0,0, - (imageXE>1024)?1024:imageXE, - imageYE&iGPUHeightMask, - FALSE); - } - - CheckVRamRead(imageX0,imageY0, - (imageXE>1024)?1024:imageXE, - (imageYE>iGPUHeight)?iGPUHeight:imageYE, - FALSE); - } - - for(j=0;j<imageSY;j++) - for(i=0;i<imageSX;i++) - psxVuw [(1024*((imageY1+j)&iGPUHeightMask))+((imageX1+i)&0x3ff)]= - psxVuw[(1024*((imageY0+j)&iGPUHeightMask))+((imageX0+i)&0x3ff)]; - - if(!PSXDisplay.RGB24) - { - imageXE=imageX1+imageSX; - imageYE=imageY1+imageSY; - - if(imageYE>iGPUHeight && imageXE>1024) - { - InvalidateTextureArea(0,0, - (imageXE&0x3ff)-1, - (imageYE&iGPUHeightMask)-1); - } - - if(imageXE>1024) - { - InvalidateTextureArea(0,imageY1, - (imageXE&0x3ff)-1, - ((imageYE>iGPUHeight)?iGPUHeight:imageYE)-imageY1-1); - } - - if(imageYE>iGPUHeight) - { - InvalidateTextureArea(imageX1,0, - ((imageXE>1024)?1024:imageXE)-imageX1-1, - (imageYE&iGPUHeightMask)-1); - } - - InvalidateTextureArea(imageX1,imageY1, - ((imageXE>1024)?1024:imageXE)-imageX1-1, - ((imageYE>iGPUHeight)?iGPUHeight:imageYE)-imageY1-1); - } -} - -//////////////////////////////////////////////////////////////////////// - -static void primMoveImage(unsigned char * baseAddr) -{ - short *sgpuData = ((short *) baseAddr); - short imageY0,imageX0,imageY1,imageX1,imageSX,imageSY,i,j; - - imageX0 = sgpuData[2]&0x03ff; - imageY0 = sgpuData[3]&iGPUHeightMask; - imageX1 = sgpuData[4]&0x03ff; - imageY1 = sgpuData[5]&iGPUHeightMask; - imageSX = sgpuData[6]; - imageSY = sgpuData[7]; - - if((imageX0 == imageX1) && (imageY0 == imageY1)) return; - if(imageSX<=0) return; - if(imageSY<=0) return; - - if(iGPUHeight==1024 && sgpuData[7]>1024) return; - - if((imageY0+imageSY)>iGPUHeight || - (imageX0+imageSX)>1024 || - (imageY1+imageSY)>iGPUHeight || - (imageX1+imageSX)>1024) - { - MoveImageWrapped(imageX0,imageY0,imageX1,imageY1,imageSX,imageSY); - if((imageY0+imageSY)>iGPUHeight) imageSY=iGPUHeight-imageY0; - if((imageX0+imageSX)>1024) imageSX=1024-imageX0; - if((imageY1+imageSY)>iGPUHeight) imageSY=iGPUHeight-imageY1; - if((imageX1+imageSX)>1024) imageSX=1024-imageX1; - } - - if(iFrameReadType&2) - CheckVRamRead(imageX0,imageY0, - imageX0+imageSX, - imageY0+imageSY, - FALSE); - - if(imageSX&1) - { - unsigned short *SRCPtr, *DSTPtr; - unsigned short LineOffset; - - SRCPtr = psxVuw + (1024*imageY0) + imageX0; - DSTPtr = psxVuw + (1024*imageY1) + imageX1; - - LineOffset = 1024 - imageSX; - - for(j=0;j<imageSY;j++) - { - for(i=0;i<imageSX;i++) *DSTPtr++ = *SRCPtr++; - SRCPtr += LineOffset; - DSTPtr += LineOffset; - } - } - else - { - uint32_t *SRCPtr, *DSTPtr; - unsigned short LineOffset; - int dx=imageSX>>1; - - SRCPtr = (uint32_t *)(psxVuw + (1024*imageY0) + imageX0); - DSTPtr = (uint32_t *)(psxVuw + (1024*imageY1) + imageX1); - - LineOffset = 512 - dx; - - for(j=0;j<imageSY;j++) - { - for(i=0;i<dx;i++) *DSTPtr++ = *SRCPtr++; - SRCPtr += LineOffset; - DSTPtr += LineOffset; - } - } - - if (!PSXDisplay.RGB24) - { - InvalidateTextureArea(imageX1,imageY1,imageSX-1,imageSY-1); - - if (CheckAgainstScreen(imageX1,imageY1,imageSX,imageSY)) - { - if(imageX1>=PreviousPSXDisplay.DisplayPosition.x && - imageX1<PreviousPSXDisplay.DisplayEnd.x && - imageY1>=PreviousPSXDisplay.DisplayPosition.y && - imageY1<PreviousPSXDisplay.DisplayEnd.y) - { - imageX1 += imageSX; - imageY1 += imageSY; - - if(imageX1>=PreviousPSXDisplay.DisplayPosition.x && - imageX1<=PreviousPSXDisplay.DisplayEnd.x && - imageY1>=PreviousPSXDisplay.DisplayPosition.y && - imageY1<=PreviousPSXDisplay.DisplayEnd.y) - { - if(!( - imageX0>=PSXDisplay.DisplayPosition.x && - imageX0<PSXDisplay.DisplayEnd.x && - imageY0>=PSXDisplay.DisplayPosition.y && - imageY0<PSXDisplay.DisplayEnd.y - )) - { - if(bRenderFrontBuffer) - { - updateFrontDisplay(); - } - - UploadScreen(FALSE); - } - else bFakeFrontBuffer=TRUE; - } - } - - bNeedUploadTest=TRUE; - } - else - if(iOffscreenDrawing) - { - if (CheckAgainstFrontScreen(imageX1,imageY1,imageSX,imageSY)) - { - if(!PSXDisplay.InterlacedTest && -// !bFullVRam && - (( - imageX0>=PreviousPSXDisplay.DisplayPosition.x && - imageX0<PreviousPSXDisplay.DisplayEnd.x && - imageY0>=PreviousPSXDisplay.DisplayPosition.y && - imageY0<PreviousPSXDisplay.DisplayEnd.y - ) || - ( - imageX0>=PSXDisplay.DisplayPosition.x && - imageX0<PSXDisplay.DisplayEnd.x && - imageY0>=PSXDisplay.DisplayPosition.y && - imageY0<PSXDisplay.DisplayEnd.y - ))) - return; - - bNeedUploadTest=TRUE; - - if(!bNeedUploadAfter) - { - bNeedUploadAfter = TRUE; - xrUploadArea.x0=imageX0; - xrUploadArea.x1=imageX0+imageSX; - xrUploadArea.y0=imageY0; - xrUploadArea.y1=imageY0+imageSY; - } - else - { - xrUploadArea.x0=min(xrUploadArea.x0,imageX0); - xrUploadArea.x1=max(xrUploadArea.x1,imageX0+imageSX); - xrUploadArea.y0=min(xrUploadArea.y0,imageY0); - xrUploadArea.y1=max(xrUploadArea.y1,imageY0+imageSY); - } - } - } - } -} - - -//////////////////////////////////////////////////////////////////////// -// cmd: draw free-size Tile -//////////////////////////////////////////////////////////////////////// - -static void primTileS(unsigned char * baseAddr) -{ - uint32_t *gpuData = ((uint32_t *)baseAddr); - short *sgpuData = ((short *) baseAddr); - - sprtX = sgpuData[2]; - sprtY = sgpuData[3]; - sprtW = sgpuData[4] & 0x3ff; - sprtH = sgpuData[5] & iGPUHeightMask; - - // x and y of start - - lx0 = sprtX; - ly0 = sprtY; - - offsetST(); - - if((dwActFixes&1) && // FF7 special game gix (battle cursor) - sprtX==0 && sprtY==0 && sprtW==24 && sprtH==16) - return; - - bDrawTextured = FALSE; - bDrawSmoothShaded = FALSE; - - SetRenderState(gpuData[0]); - - if(iOffscreenDrawing) - { - if(IsPrimCompleteInsideNextScreen(lx0,ly0,lx2,ly2) || - (ly0==-6 && ly2==10)) // OH MY GOD... I DIDN'T WANT TO DO IT... BUT I'VE FOUND NO OTHER WAY... HACK FOR GRADIUS SHOOTER :( - { - lClearOnSwapColor = COLOR(gpuData[0]); - lClearOnSwap = 1; - } - - offsetPSX4(); - if(bDrawOffscreen4()) - { - if(!(iTileCheat && sprtH==32 && gpuData[0]==0x60ffffff)) // special cheat for certain ZiNc games - { - InvalidateTextureAreaEx(); - FillSoftwareAreaTrans(lx0,ly0,lx2,ly2, - BGR24to16(gpuData[0])); - } - } - } - - SetRenderMode(gpuData[0], FALSE); - SetZMask4NT(); - - if(bIgnoreNextTile) {bIgnoreNextTile=FALSE;return;} - - vertex[0].c.lcol=gpuData[0]; - vertex[0].c.col[3]=ubGloColAlpha; - SETCOL(vertex[0]); - - PRIMdrawQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]); - - iDrawnSomething=1; -} - -//////////////////////////////////////////////////////////////////////// -// cmd: draw 1 dot Tile (point) -//////////////////////////////////////////////////////////////////////// - -static void primTile1(unsigned char * baseAddr) -{ - uint32_t *gpuData = ((uint32_t *)baseAddr); - short *sgpuData = ((short *)baseAddr); - - sprtX = sgpuData[2]; - sprtY = sgpuData[3]; - sprtW = 1; - sprtH = 1; - - lx0 = sprtX; - ly0 = sprtY; - - offsetST(); - - bDrawTextured = FALSE; - bDrawSmoothShaded = FALSE; - - SetRenderState(gpuData[0]); - - if(iOffscreenDrawing) - { - offsetPSX4(); - - if(bDrawOffscreen4()) - { - InvalidateTextureAreaEx(); - FillSoftwareAreaTrans(lx0,ly0,lx2,ly2, - BGR24to16(gpuData[0])); - } - } - - SetRenderMode(gpuData[0], FALSE); - SetZMask4NT(); - - vertex[0].c.lcol=gpuData[0];vertex[0].c.col[3]=ubGloColAlpha; - SETCOL(vertex[0]); - - PRIMdrawQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]); - - iDrawnSomething=1; -} - -//////////////////////////////////////////////////////////////////////// -// cmd: draw 8 dot Tile (small rect) -//////////////////////////////////////////////////////////////////////// - -static void primTile8(unsigned char * baseAddr) -{ - uint32_t *gpuData = ((uint32_t *)baseAddr); - short *sgpuData = ((short *) baseAddr); - - sprtX = sgpuData[2]; - sprtY = sgpuData[3]; - sprtW = 8; - sprtH = 8; - - lx0 = sprtX; - ly0 = sprtY; - - offsetST(); - - bDrawTextured = FALSE; - bDrawSmoothShaded = FALSE; - SetRenderState(gpuData[0]); - - if(iOffscreenDrawing) - { - offsetPSX4(); - - if(bDrawOffscreen4()) - { - InvalidateTextureAreaEx(); - FillSoftwareAreaTrans(lx0,ly0,lx2,ly2, - BGR24to16(gpuData[0])); - } - } - - SetRenderMode(gpuData[0], FALSE); - SetZMask4NT(); - - vertex[0].c.lcol=gpuData[0]; - vertex[0].c.col[3]=ubGloColAlpha; - SETCOL(vertex[0]); - - PRIMdrawQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]); - - iDrawnSomething=1; -} - -//////////////////////////////////////////////////////////////////////// -// cmd: draw 16 dot Tile (medium rect) -//////////////////////////////////////////////////////////////////////// - -static void primTile16(unsigned char * baseAddr) -{ - uint32_t *gpuData = ((uint32_t *)baseAddr); - short *sgpuData = ((short *)baseAddr); - - sprtX = sgpuData[2]; - sprtY = sgpuData[3]; - sprtW = 16; - sprtH = 16; - // x and y of start - lx0 = sprtX; - ly0 = sprtY; - - offsetST(); - - bDrawTextured = FALSE; - bDrawSmoothShaded = FALSE; - SetRenderState(gpuData[0]); - - if(iOffscreenDrawing) - { - offsetPSX4(); - - if(bDrawOffscreen4()) - { - InvalidateTextureAreaEx(); - FillSoftwareAreaTrans(lx0,ly0,lx2,ly2, - BGR24to16(gpuData[0])); - } - } - - SetRenderMode(gpuData[0], FALSE); - SetZMask4NT(); - - vertex[0].c.lcol=gpuData[0]; - vertex[0].c.col[3]=ubGloColAlpha; - SETCOL(vertex[0]); - - PRIMdrawQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]); - - iDrawnSomething=1; -} - -//////////////////////////////////////////////////////////////////////// -// helper: filter effect by multipass rendering -//////////////////////////////////////////////////////////////////////// - -void DrawMultiBlur(void) -{ - int lABR,lDST; - float fx,fy; - - lABR=GlobalTextABR; - lDST=DrawSemiTrans; - - fx=(float)PSXDisplay.DisplayMode.x/(float)(iResX); - fy=(float)PSXDisplay.DisplayMode.y/(float)(iResY); - - vertex[0].x+=fx;vertex[1].x+=fx; - vertex[2].x+=fx;vertex[3].x+=fx; - - GlobalTextABR=0; - DrawSemiTrans=1; - SetSemiTrans(); - - PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]); - - vertex[0].y+=fy;vertex[1].y+=fy; - vertex[2].y+=fy;vertex[3].y+=fy; - PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]); - - if(bDrawMultiPass) {obm1=obm2=GL_SRC_ALPHA;} - - GlobalTextABR=lABR; - DrawSemiTrans=lDST; -} - -//////////////////////////////////////////////////////////////////////// - -#define POFF 0.375f - -static void DrawMultiFilterSprite(void) -{ - int lABR,lDST; - - if(bUseMultiPass || DrawSemiTrans || ubOpaqueDraw) - { - PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]); - return; - } - - lABR=GlobalTextABR; - lDST=DrawSemiTrans; - vertex[0].c.col[3]=ubGloAlpha/2; // -> set color with - SETCOL(vertex[0]); // texture alpha - PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]); - vertex[0].x+=POFF;vertex[1].x+=POFF; - vertex[2].x+=POFF;vertex[3].x+=POFF; - vertex[0].y+=POFF;vertex[1].y+=POFF; - vertex[2].y+=POFF;vertex[3].y+=POFF; - GlobalTextABR=0; - DrawSemiTrans=1; - SetSemiTrans(); - PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]); - GlobalTextABR=lABR; - DrawSemiTrans=lDST; -} - -//////////////////////////////////////////////////////////////////////// -// cmd: small sprite (textured rect) -//////////////////////////////////////////////////////////////////////// - -static void primSprt8(unsigned char * baseAddr) -{ - uint32_t *gpuData = ((uint32_t *) baseAddr); - short *sgpuData = ((short *) baseAddr); - short s; - - iSpriteTex=1; - - sprtX = sgpuData[2]; - sprtY = sgpuData[3]; - sprtW = 8; - sprtH = 8; - - lx0 = sprtX; - ly0 = sprtY; - - offsetST(); - - // do texture stuff - gl_ux[0]=gl_ux[3]=baseAddr[8];//gpuData[2]&0xff; - - if(usMirror & 0x1000) - { - s=gl_ux[0]; - s-=sprtW-1; - if(s<0) {s=0;} - gl_ux[0]=gl_ux[3]=s; - } - - sSprite_ux2=s=gl_ux[0]+sprtW; - if(s) s--; - if(s>255) s=255; - gl_ux[1]=gl_ux[2]=s; - // Y coords - gl_vy[0]=gl_vy[1]=baseAddr[9];//(gpuData[2]>>8)&0xff; - - if(usMirror & 0x2000) - { - s=gl_vy[0]; - s-=sprtH-1; - if(s<0) {s=0;} - gl_vy[0]=gl_vy[1]=s; - } - - sSprite_vy2=s=gl_vy[0]+sprtH; - if(s) s--; - if(s>255) s=255; - gl_vy[2]=gl_vy[3]=s; - - ulClutID=(gpuData[2]>>16); - - bDrawTextured = TRUE; - bDrawSmoothShaded = FALSE; - SetRenderState(gpuData[0]); - - if(iOffscreenDrawing) - { - offsetPSX4(); - - if(bDrawOffscreen4()) - { - InvalidateTextureAreaEx(); - SetRenderColor(gpuData[0]); - lx0-=PSXDisplay.DrawOffset.x; - ly0-=PSXDisplay.DrawOffset.y; - - if(bUsingTWin) DrawSoftwareSpriteTWin(baseAddr,8,8); - else - if(usMirror) DrawSoftwareSpriteMirror(baseAddr,8,8); - else - DrawSoftwareSprite(baseAddr,8,8,baseAddr[8],baseAddr[9]); - } - } - - SetRenderMode(gpuData[0], TRUE); - SetZMask4SP(); - - sSprite_ux2=gl_ux[0]+sprtW; - sSprite_vy2=gl_vy[0]+sprtH; - - assignTextureSprite(); - - if(iFilterType>4) - DrawMultiFilterSprite(); - else - PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]); - - if(bDrawMultiPass) - { - SetSemiTransMulti(1); - PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]); - } - - if(ubOpaqueDraw) - { - SetZMask4O(); - if(bUseMultiPass) SetOpaqueColor(gpuData[0]); - DEFOPAQUEON - - if(bSmallAlpha && iFilterType<=2) - { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - SetZMask4O(); - } - - PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]); - DEFOPAQUEOFF - } - - iSpriteTex=0; - iDrawnSomething=1; -} - -//////////////////////////////////////////////////////////////////////// -// cmd: medium sprite (textured rect) -//////////////////////////////////////////////////////////////////////// - -static void primSprt16(unsigned char * baseAddr) -{ - uint32_t *gpuData = ((uint32_t *) baseAddr); - short *sgpuData = ((short *) baseAddr); - short s; - - iSpriteTex=1; - - sprtX = sgpuData[2]; - sprtY = sgpuData[3]; - sprtW = 16; - sprtH = 16; - - lx0 = sprtX; - ly0 = sprtY; - - offsetST(); - - // do texture stuff - gl_ux[0]=gl_ux[3]=baseAddr[8];//gpuData[2]&0xff; - - if(usMirror & 0x1000) - { - s=gl_ux[0]; - s-=sprtW-1; - if(s<0) {s=0;} - gl_ux[0]=gl_ux[3]=s; - } - - sSprite_ux2=s=gl_ux[0]+sprtW; - if(s) s--; - if(s>255) s=255; - gl_ux[1]=gl_ux[2]=s; - // Y coords - gl_vy[0]=gl_vy[1]=baseAddr[9];//(gpuData[2]>>8)&0xff; - - if(usMirror & 0x2000) - { - s=gl_vy[0]; - s-=sprtH-1; - if(s<0) {s=0;} - gl_vy[0]=gl_vy[1]=s; - } - - sSprite_vy2=s=gl_vy[0]+sprtH; - if(s) s--; - if(s>255) s=255; - gl_vy[2]=gl_vy[3]=s; - - ulClutID=(gpuData[2]>>16); - - bDrawTextured = TRUE; - bDrawSmoothShaded = FALSE; - SetRenderState(gpuData[0]); - - if(iOffscreenDrawing) - { - offsetPSX4(); - - if(bDrawOffscreen4()) - { - InvalidateTextureAreaEx(); - SetRenderColor(gpuData[0]); - lx0-=PSXDisplay.DrawOffset.x; - ly0-=PSXDisplay.DrawOffset.y; - if(bUsingTWin) DrawSoftwareSpriteTWin(baseAddr,16,16); - else - if(usMirror) DrawSoftwareSpriteMirror(baseAddr,16,16); - else - DrawSoftwareSprite(baseAddr,16,16,baseAddr[8],baseAddr[9]); - } - } - - SetRenderMode(gpuData[0], TRUE); - SetZMask4SP(); - - sSprite_ux2=gl_ux[0]+sprtW; - sSprite_vy2=gl_vy[0]+sprtH; - - assignTextureSprite(); - - if(iFilterType>4) - DrawMultiFilterSprite(); - else - PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]); - - if(bDrawMultiPass) - { - SetSemiTransMulti(1); - PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]); - } - - if(ubOpaqueDraw) - { - SetZMask4O(); - if(bUseMultiPass) SetOpaqueColor(gpuData[0]); - DEFOPAQUEON - - if(bSmallAlpha && iFilterType<=2) - { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - SetZMask4O(); - } - - PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]); - DEFOPAQUEOFF - } - - iSpriteTex=0; - iDrawnSomething=1; -} - -//////////////////////////////////////////////////////////////////////// -// cmd: free-size sprite (textured rect) -//////////////////////////////////////////////////////////////////////// - -static void primSprtSRest(unsigned char * baseAddr,unsigned short type) -{ - uint32_t *gpuData = ((uint32_t *)baseAddr); - short *sgpuData = ((short *) baseAddr); - short s; - unsigned short sTypeRest=0; - - sprtX = sgpuData[2]; - sprtY = sgpuData[3]; - sprtW = sgpuData[6] & 0x3ff; - sprtH = sgpuData[7] & 0x1ff; - - // do texture stuff - switch(type) - { - case 1: - gl_vy[0]=gl_vy[1]=baseAddr[9]; - s=256-baseAddr[8]; - sprtW-=s; - sprtX+=s; - gl_ux[0]=gl_ux[3]=0; - break; - case 2: - gl_ux[0]=gl_ux[3]=baseAddr[8]; - s=256-baseAddr[9]; - sprtH-=s; - sprtY+=s; - gl_vy[0]=gl_vy[1]=0; - break; - case 3: - s=256-baseAddr[8]; - sprtW-=s; - sprtX+=s; - gl_ux[0]=gl_ux[3]=0; - s=256-baseAddr[9]; - sprtH-=s; - sprtY+=s; - gl_vy[0]=gl_vy[1]=0; - break; - - case 4: - gl_vy[0]=gl_vy[1]=baseAddr[9]; - s=512-baseAddr[8]; - sprtW-=s; - sprtX+=s; - gl_ux[0]=gl_ux[3]=0; - break; - case 5: - gl_ux[0]=gl_ux[3]=baseAddr[8]; - s=512-baseAddr[9]; - sprtH-=s; - sprtY+=s; - gl_vy[0]=gl_vy[1]=0; - break; - case 6: - s=512-baseAddr[8]; - sprtW-=s; - sprtX+=s; - gl_ux[0]=gl_ux[3]=0; - s=512-baseAddr[9]; - sprtH-=s; - sprtY+=s; - gl_vy[0]=gl_vy[1]=0; - break; - - } - - if(usMirror & 0x1000) - { - s=gl_ux[0]; - s-=sprtW-1;if(s<0) s=0; - gl_ux[0]=gl_ux[3]=s; - } - if(usMirror & 0x2000) - { - s=gl_vy[0]; - s-=sprtH-1;if(s<0) {s=0;} - gl_vy[0]=gl_vy[1]=s; - } - - sSprite_ux2=s=gl_ux[0]+sprtW; - if(s>255) s=255; - gl_ux[1]=gl_ux[2]=s; - sSprite_vy2=s=gl_vy[0]+sprtH; - if(s>255) s=255; - gl_vy[2]=gl_vy[3]=s; - - if(!bUsingTWin) - { - if(sSprite_ux2>256) - {sprtW=256-gl_ux[0];sSprite_ux2=256;sTypeRest+=1;} - if(sSprite_vy2>256) - {sprtH=256-gl_vy[0];sSprite_vy2=256;sTypeRest+=2;} - } - - lx0 = sprtX; - ly0 = sprtY; - - offsetST(); - - ulClutID=(gpuData[2]>>16); - - bDrawTextured = TRUE; - bDrawSmoothShaded = FALSE; - SetRenderState(gpuData[0]); - - if(iOffscreenDrawing) - { - offsetPSX4(); - - if(bDrawOffscreen4()) - { - InvalidateTextureAreaEx(); - SetRenderColor(gpuData[0]); - lx0-=PSXDisplay.DrawOffset.x; - ly0-=PSXDisplay.DrawOffset.y; - if(bUsingTWin) DrawSoftwareSpriteTWin(baseAddr,sprtW,sprtH); - else - if(usMirror) DrawSoftwareSpriteMirror(baseAddr,sprtW,sprtH); - else - DrawSoftwareSprite(baseAddr,sprtW,sprtH,baseAddr[8],baseAddr[9]); - } - } - - SetRenderMode(gpuData[0], TRUE); - SetZMask4SP(); - - sSprite_ux2=gl_ux[0]+sprtW; - sSprite_vy2=gl_vy[0]+sprtH; - - assignTextureSprite(); - - if(iFilterType>4) - DrawMultiFilterSprite(); - else - PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]); - - if(bDrawMultiPass) - { - SetSemiTransMulti(1); - PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]); - } - - if(ubOpaqueDraw) - { - SetZMask4O(); - if(bUseMultiPass) SetOpaqueColor(gpuData[0]); - DEFOPAQUEON - - if(bSmallAlpha && iFilterType<=2) - { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - SetZMask4O(); - } - - PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]); - DEFOPAQUEOFF - } - - if(sTypeRest && type<4) - { - if(sTypeRest&1 && type==1) primSprtSRest(baseAddr,4); - if(sTypeRest&2 && type==2) primSprtSRest(baseAddr,5); - if(sTypeRest==3 && type==3) primSprtSRest(baseAddr,6); - } -} - -static void primSprtS(unsigned char * baseAddr) -{ - uint32_t *gpuData = ((uint32_t *) baseAddr); - short *sgpuData = ((short *) baseAddr); - - short s; - unsigned short sTypeRest=0; - - sprtX = sgpuData[2]; - sprtY = sgpuData[3]; - sprtW = sgpuData[6] & 0x3ff; - sprtH = sgpuData[7] & 0x1ff; - - if(!sprtH) return; - if(!sprtW) return; - - iSpriteTex=1; - - // do texture stuff - gl_ux[0]=gl_ux[3]=baseAddr[8];//gpuData[2]&0xff; - gl_vy[0]=gl_vy[1]=baseAddr[9];//(gpuData[2]>>8)&0xff; - - if(usMirror & 0x1000) - { - s=gl_ux[0]; - s-=sprtW-1; - if(s<0) {s=0;} - gl_ux[0]=gl_ux[3]=s; - } - if(usMirror & 0x2000) - { - s=gl_vy[0]; - s-=sprtH-1; - if(s<0) {s=0;} - gl_vy[0]=gl_vy[1]=s; - } - - sSprite_ux2=s=gl_ux[0]+sprtW; - if(s) s--; - if(s>255) s=255; - gl_ux[1]=gl_ux[2]=s; - sSprite_vy2=s=gl_vy[0]+sprtH; - if(s) s--; - if(s>255) s=255; - gl_vy[2]=gl_vy[3]=s; - - if(!bUsingTWin) - { - if(sSprite_ux2>256) - {sprtW=256-gl_ux[0];sSprite_ux2=256;sTypeRest+=1;} - if(sSprite_vy2>256) - {sprtH=256-gl_vy[0];sSprite_vy2=256;sTypeRest+=2;} - } - - lx0 = sprtX; - ly0 = sprtY; - - offsetST(); - - ulClutID=(gpuData[2]>>16); - - bDrawTextured = TRUE; - bDrawSmoothShaded = FALSE; - SetRenderState(gpuData[0]); - - if(iOffscreenDrawing) - { - offsetPSX4(); - - if(bDrawOffscreen4()) - { - InvalidateTextureAreaEx(); - SetRenderColor(gpuData[0]); - lx0-=PSXDisplay.DrawOffset.x; - ly0-=PSXDisplay.DrawOffset.y; - if(bUsingTWin) DrawSoftwareSpriteTWin(baseAddr,sprtW,sprtH); - else - if(usMirror) DrawSoftwareSpriteMirror(baseAddr,sprtW,sprtH); - else - DrawSoftwareSprite(baseAddr,sprtW,sprtH,baseAddr[8],baseAddr[9]); - } - } - - SetRenderMode(gpuData[0], TRUE); - SetZMask4SP(); - - if((dwActFixes&1) && gTexFrameName && gTexName==gTexFrameName) - {iSpriteTex=0;return;} - - sSprite_ux2=gl_ux[0]+sprtW; - sSprite_vy2=gl_vy[0]+sprtH; - - assignTextureSprite(); - - if(iFilterType>4) - DrawMultiFilterSprite(); - else - PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]); - - if(bDrawMultiPass) - { - SetSemiTransMulti(1); - PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]); - } - - if(ubOpaqueDraw) - { - SetZMask4O(); - if(bUseMultiPass) SetOpaqueColor(gpuData[0]); - DEFOPAQUEON - - if(bSmallAlpha && iFilterType<=2) - { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - SetZMask4O(); - } - - PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]); - DEFOPAQUEOFF - } - - if(sTypeRest) - { - if(sTypeRest&1) primSprtSRest(baseAddr,1); - if(sTypeRest&2) primSprtSRest(baseAddr,2); - if(sTypeRest==3) primSprtSRest(baseAddr,3); - } - - iSpriteTex=0; - iDrawnSomething=1; -} - -//////////////////////////////////////////////////////////////////////// -// cmd: flat shaded Poly4 -//////////////////////////////////////////////////////////////////////// - -static void primPolyF4(unsigned char *baseAddr) -{ - uint32_t *gpuData = ((uint32_t *) baseAddr); - short *sgpuData = ((short *) baseAddr); - - lx0 = sgpuData[2]; - ly0 = sgpuData[3]; - lx1 = sgpuData[4]; - ly1 = sgpuData[5]; - lx2 = sgpuData[6]; - ly2 = sgpuData[7]; - lx3 = sgpuData[8]; - ly3 = sgpuData[9]; - - if(offset4()) return; - - bDrawTextured = FALSE; - bDrawSmoothShaded = FALSE; - SetRenderState(gpuData[0]); - - if(iOffscreenDrawing) - { - offsetPSX4(); - if(bDrawOffscreen4()) - { - InvalidateTextureAreaEx(); - drawPoly4F(gpuData[0]); - } - } - - SetRenderMode(gpuData[0], FALSE); - SetZMask4NT(); - - vertex[0].c.lcol=gpuData[0];vertex[0].c.col[3]=ubGloColAlpha; - SETCOL(vertex[0]); - - PRIMdrawTri2(&vertex[0], &vertex[1], &vertex[2],&vertex[3]); - - iDrawnSomething=1; -} - -//////////////////////////////////////////////////////////////////////// -// cmd: smooth shaded Poly4 -//////////////////////////////////////////////////////////////////////// - -void primPolyG4(unsigned char * baseAddr); - -static BOOL bDrawOffscreenFrontFF9G4(void) -{ - if(lx0< PSXDisplay.DisplayPosition.x) return FALSE; // must be complete in front - if(lx0> PSXDisplay.DisplayEnd.x) return FALSE; - if(ly0< PSXDisplay.DisplayPosition.y) return FALSE; - if(ly0> PSXDisplay.DisplayEnd.y) return FALSE; - if(lx1< PSXDisplay.DisplayPosition.x) return FALSE; - if(lx1> PSXDisplay.DisplayEnd.x) return FALSE; - if(ly1< PSXDisplay.DisplayPosition.y) return FALSE; - if(ly1> PSXDisplay.DisplayEnd.y) return FALSE; - if(lx2< PSXDisplay.DisplayPosition.x) return FALSE; - if(lx2> PSXDisplay.DisplayEnd.x) return FALSE; - if(ly2< PSXDisplay.DisplayPosition.y) return FALSE; - if(ly2> PSXDisplay.DisplayEnd.y) return FALSE; - if(lx3< PSXDisplay.DisplayPosition.x) return FALSE; - if(lx3> PSXDisplay.DisplayEnd.x) return FALSE; - if(ly3< PSXDisplay.DisplayPosition.y) return FALSE; - if(ly3> PSXDisplay.DisplayEnd.y) return FALSE; - return TRUE; -} - -BOOL bCheckFF9G4(unsigned char * baseAddr) -{ - static unsigned char pFF9G4Cache[32]; - static int iFF9Fix=0; - - if(baseAddr) - { - if(iFF9Fix==0) - { - if(bDrawOffscreenFrontFF9G4()) - { - short *sgpuData = ((short *) pFF9G4Cache); - iFF9Fix=2; - memcpy(pFF9G4Cache,baseAddr,32); - - if(sgpuData[2]==142) - { - sgpuData[2] +=65; - sgpuData[10]+=65; - } - return TRUE; - } - else iFF9Fix=1; - } - return FALSE; - } - - if(iFF9Fix==2) - { - int labr=GlobalTextABR; - GlobalTextABR = 1; - primPolyG4(pFF9G4Cache); - GlobalTextABR = labr; - } - iFF9Fix = 0; - - return FALSE; -} - -//////////////////////////////////////////////////////////////////////// - -void primPolyG4(unsigned char * baseAddr) -{ - uint32_t *gpuData = (uint32_t *)baseAddr; - short *sgpuData = ((short *)baseAddr); - - lx0 = sgpuData[2]; - ly0 = sgpuData[3]; - lx1 = sgpuData[6]; - ly1 = sgpuData[7]; - lx2 = sgpuData[10]; - ly2 = sgpuData[11]; - lx3 = sgpuData[14]; - ly3 = sgpuData[15]; - - if(offset4()) return; - - bDrawTextured = FALSE; - bDrawSmoothShaded = TRUE; - SetRenderState(gpuData[0]); - - if(iOffscreenDrawing) - { - offsetPSX4(); - - if((dwActFixes&512) && bCheckFF9G4(baseAddr)) return; - - if(bDrawOffscreen4()) - { - InvalidateTextureAreaEx(); - drawPoly4G(gpuData[0], gpuData[2], gpuData[4], gpuData[6]); - } - } - - SetRenderMode(gpuData[0], FALSE); - SetZMask4NT(); - - vertex[0].c.lcol=gpuData[0]; - vertex[1].c.lcol=gpuData[2]; - vertex[2].c.lcol=gpuData[4]; - vertex[3].c.lcol=gpuData[6]; - - vertex[0].c.col[3]=vertex[1].c.col[3]=vertex[2].c.col[3]=vertex[3].c.col[3]=ubGloAlpha; - - - PRIMdrawGouraudTri2Color(&vertex[0],&vertex[1], &vertex[2], &vertex[3]); - - iDrawnSomething=1; -} - -//////////////////////////////////////////////////////////////////////// -// cmd: flat shaded Texture3 -//////////////////////////////////////////////////////////////////////// - -static BOOL DoLineCheck(uint32_t *gpuData) -{ - BOOL bQuad=FALSE;short dx,dy; - - if(lx0==lx1) - { - dx=lx0-lx2;if(dx<0) dx=-dx; - - if(ly1==ly2) - { - dy=ly1-ly0;if(dy<0) dy=-dy; - if(dx<=1) - { - vertex[3]=vertex[2]; - vertex[2]=vertex[0]; - vertex[2].x=vertex[3].x; - } - else - if(dy<=1) - { - vertex[3]=vertex[2]; - vertex[2].y=vertex[0].y; - } - else return FALSE; - - bQuad=TRUE; - } - else - if(ly0==ly2) - { - dy=ly0-ly1;if(dy<0) dy=-dy; - if(dx<=1) - { - vertex[3]=vertex[1]; - vertex[3].x=vertex[2].x; - } - else - if(dy<=1) - { - vertex[3]=vertex[2]; - vertex[3].y=vertex[1].y; - } - else return FALSE; - - bQuad=TRUE; - } - } - - if(lx0==lx2) - { - dx=lx0-lx1;if(dx<0) dx=-dx; - - if(ly2==ly1) - { - dy=ly2-ly0;if(dy<0) dy=-dy; - if(dx<=1) - { - vertex[3]=vertex[1]; - vertex[1]=vertex[0]; - vertex[1].x=vertex[3].x; - } - else - if(dy<=1) - { - vertex[3]=vertex[1]; - vertex[1].y=vertex[0].y; - } - else return FALSE; - - bQuad=TRUE; - } - else - if(ly0==ly1) - { - dy=ly2-ly0;if(dy<0) dy=-dy; - if(dx<=1) - { - vertex[3]=vertex[2]; - vertex[3].x=vertex[1].x; - } - else - if(dy<=1) - { - vertex[3]=vertex[1]; - vertex[3].y=vertex[2].y; - } - else return FALSE; - - bQuad=TRUE; - } - } - - if(lx1==lx2) - { - dx=lx1-lx0;if(dx<0) dx=-dx; - - if(ly1==ly0) - { - dy=ly1-ly2;if(dy<0) dy=-dy; - - if(dx<=1) - { - vertex[3]=vertex[2]; - vertex[2].x=vertex[0].x; - } - else - if(dy<=1) - { - vertex[3]=vertex[2]; - vertex[2]=vertex[0]; - vertex[2].y=vertex[3].y; - } - else return FALSE; - - bQuad=TRUE; - } - else - if(ly2==ly0) - { - dy=ly2-ly1;if(dy<0) dy=-dy; - - if(dx<=1) - { - vertex[3]=vertex[1]; - vertex[1].x=vertex[0].x; - } - else - if(dy<=1) - { - vertex[3]=vertex[1]; - vertex[1]=vertex[0]; - vertex[1].y=vertex[3].y; - } - else return FALSE; - - bQuad=TRUE; - } - } - - if(!bQuad) return FALSE; - - PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[3], &vertex[2]); - - if(bDrawMultiPass) - { - SetSemiTransMulti(1); - PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[3], &vertex[2]); - } - - if(ubOpaqueDraw) - { - SetZMask4O(); - if(bUseMultiPass) SetOpaqueColor(gpuData[0]); - DEFOPAQUEON - PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[3], &vertex[2]); - DEFOPAQUEOFF - } - - iDrawnSomething=1; - - return TRUE; -} - -//////////////////////////////////////////////////////////////////////// - -static void primPolyFT3(unsigned char * baseAddr) -{ - uint32_t *gpuData = ((uint32_t *) baseAddr); - short *sgpuData = ((short *) baseAddr); - - lx0 = sgpuData[2]; - ly0 = sgpuData[3]; - lx1 = sgpuData[6]; - ly1 = sgpuData[7]; - lx2 = sgpuData[10]; - ly2 = sgpuData[11]; - - if(offset3()) return; - - // do texture UV coordinates stuff - gl_ux[0]=gl_ux[3]=baseAddr[8];//gpuData[2]&0xff; - gl_vy[0]=gl_vy[3]=baseAddr[9];//(gpuData[2]>>8)&0xff; - gl_ux[1]=baseAddr[16];//gpuData[4]&0xff; - gl_vy[1]=baseAddr[17];//(gpuData[4]>>8)&0xff; - gl_ux[2]=baseAddr[24];//gpuData[6]&0xff; - gl_vy[2]=baseAddr[25];//(gpuData[6]>>8)&0xff; - - UpdateGlobalTP((unsigned short)(gpuData[4]>>16)); - ulClutID=gpuData[2]>>16; - - bDrawTextured = TRUE; - bDrawSmoothShaded = FALSE; - SetRenderState(gpuData[0]); - - if(iOffscreenDrawing) - { - offsetPSX3(); - if(bDrawOffscreen3()) - { - InvalidateTextureAreaEx(); - SetRenderColor(gpuData[0]); - drawPoly3FT(baseAddr); - } - } - - SetRenderMode(gpuData[0], TRUE); - SetZMask3(); - - assignTexture3(); - - if(!(dwActFixes&0x10)) - { - if(DoLineCheck(gpuData)) return; - } - - PRIMdrawTexturedTri(&vertex[0], &vertex[1], &vertex[2]); - - if(bDrawMultiPass) - { - SetSemiTransMulti(1); - PRIMdrawTexturedTri(&vertex[0], &vertex[1], &vertex[2]); - } - - if(ubOpaqueDraw) - { - SetZMask3O(); - if(bUseMultiPass) SetOpaqueColor(gpuData[0]); - DEFOPAQUEON - PRIMdrawTexturedTri(&vertex[0], &vertex[1], &vertex[2]); - DEFOPAQUEOFF - } - - iDrawnSomething=1; -} - -//////////////////////////////////////////////////////////////////////// -// cmd: flat shaded Texture4 -//////////////////////////////////////////////////////////////////////// - -#define ST_FAC 255.99f - -static void RectTexAlign(void) -{ - int UFlipped = FALSE; - int VFlipped = FALSE; - - if(gTexName==gTexFrameName) return; - - if(ly0==ly1) - { - if(!((lx1==lx3 && ly3==ly2 && lx2==lx0) || - (lx1==lx2 && ly2==ly3 && lx3==lx0))) - return; - - if(ly0<ly2) - { - if (vertex[0].tow > vertex[2].tow) - VFlipped = 1; - } - else - { - if (vertex[0].tow < vertex[2].tow) - VFlipped = 2; - } - } - else - if(ly0==ly2) - { - if(!((lx2==lx3 && ly3==ly1 && lx1==lx0) || - (lx2==lx1 && ly1==ly3 && lx3==lx0))) - return; - - if(ly0<ly1) - { - if (vertex[0].tow > vertex[1].tow) - VFlipped = 3; - } - else - { - if (vertex[0].tow < vertex[1].tow) - VFlipped = 4; - } - } - else - if(ly0==ly3) - { - if(!((lx3==lx2 && ly2==ly1 && lx1==lx0) || - (lx3==lx1 && ly1==ly2 && lx2==lx0))) - return; - - if(ly0<ly1) - { - if (vertex[0].tow > vertex[1].tow) - VFlipped = 5; - } - else - { - if (vertex[0].tow < vertex[1].tow) - VFlipped = 6; - } - } - else return; - - if(lx0==lx1) - { - if(lx0<lx2) - { - if (vertex[0].sow > vertex[2].sow) - UFlipped = 1; - } - else - { - if (vertex[0].sow < vertex[2].sow) - UFlipped = 2; - } - } - else - if(lx0==lx2) - { - if(lx0<lx1) - { - if (vertex[0].sow > vertex[1].sow) - UFlipped = 3; - } - else - { - if (vertex[0].sow < vertex[1].sow) - UFlipped = 4; - } - } - else - if(lx0==lx3) - { - if(lx0<lx1) - { - if (vertex[0].sow > vertex[1].sow) - UFlipped = 5; - } - else - { - if (vertex[0].sow < vertex[1].sow) - UFlipped = 6; - } - } - - if (UFlipped) - { -#ifdef OWNSCALE - if(bUsingTWin) - { - switch(UFlipped) - { - case 1: - vertex[2].sow+=0.95f/TWin.UScaleFactor; - vertex[3].sow+=0.95f/TWin.UScaleFactor; - break; - case 2: - vertex[0].sow+=0.95f/TWin.UScaleFactor; - vertex[1].sow+=0.95f/TWin.UScaleFactor; - break; - case 3: - vertex[1].sow+=0.95f/TWin.UScaleFactor; - vertex[3].sow+=0.95f/TWin.UScaleFactor; - break; - case 4: - vertex[0].sow+=0.95f/TWin.UScaleFactor; - vertex[2].sow+=0.95f/TWin.UScaleFactor; - break; - case 5: - vertex[1].sow+=0.95f/TWin.UScaleFactor; - vertex[2].sow+=0.95f/TWin.UScaleFactor; - break; - case 6: - vertex[0].sow+=0.95f/TWin.UScaleFactor; - vertex[3].sow+=0.95f/TWin.UScaleFactor; - break; - } - } - else - { - switch(UFlipped) - { - case 1: - vertex[2].sow+=1.0f/ST_FAC; - vertex[3].sow+=1.0f/ST_FAC; - break; - case 2: - vertex[0].sow+=1.0f/ST_FAC; - vertex[1].sow+=1.0f/ST_FAC; - break; - case 3: - vertex[1].sow+=1.0f/ST_FAC; - vertex[3].sow+=1.0f/ST_FAC; - break; - case 4: - vertex[0].sow+=1.0f/ST_FAC; - vertex[2].sow+=1.0f/ST_FAC; - break; - case 5: - vertex[1].sow+=1.0f/ST_FAC; - vertex[2].sow+=1.0f/ST_FAC; - break; - case 6: - vertex[0].sow+=1.0f/ST_FAC; - vertex[3].sow+=1.0f/ST_FAC; - break; - } - } -#else - if(bUsingTWin) - { - switch(UFlipped) - { - case 1: - vertex[2].sow+=1.0f/TWin.UScaleFactor; - vertex[3].sow+=1.0f/TWin.UScaleFactor; - break; - case 2: - vertex[0].sow+=1.0f/TWin.UScaleFactor; - vertex[1].sow+=1.0f/TWin.UScaleFactor; - break; - case 3: - vertex[1].sow+=1.0f/TWin.UScaleFactor; - vertex[3].sow+=1.0f/TWin.UScaleFactor; - break; - case 4: - vertex[0].sow+=1.0f/TWin.UScaleFactor; - vertex[2].sow+=1.0f/TWin.UScaleFactor; - break; - case 5: - vertex[1].sow+=1.0f/TWin.UScaleFactor; - vertex[2].sow+=1.0f/TWin.UScaleFactor; - break; - case 6: - vertex[0].sow+=1.0f/TWin.UScaleFactor; - vertex[3].sow+=1.0f/TWin.UScaleFactor; - break; - } - } - else - { - switch(UFlipped) - { - case 1: - vertex[2].sow+=1.0f; - vertex[3].sow+=1.0f; - break; - case 2: - vertex[0].sow+=1.0f; - vertex[1].sow+=1.0f; - break; - case 3: - vertex[1].sow+=1.0f; - vertex[3].sow+=1.0f; - break; - case 4: - vertex[0].sow+=1.0f; - vertex[2].sow+=1.0f; - break; - case 5: - vertex[1].sow+=1.0f; - vertex[2].sow+=1.0f; - break; - case 6: - vertex[0].sow+=1.0f; - vertex[3].sow+=1.0f; - break; - } - } -#endif - } - - if (VFlipped) - { -#ifdef OWNSCALE - if(bUsingTWin) - { - switch(VFlipped) - { - case 1: - vertex[2].tow+=0.95f/TWin.VScaleFactor; - vertex[3].tow+=0.95f/TWin.VScaleFactor; - break; - case 2: - vertex[0].tow+=0.95f/TWin.VScaleFactor; - vertex[1].tow+=0.95f/TWin.VScaleFactor; - break; - case 3: - vertex[1].tow+=0.95f/TWin.VScaleFactor; - vertex[3].tow+=0.95f/TWin.VScaleFactor; - break; - case 4: - vertex[0].tow+=0.95f/TWin.VScaleFactor; - vertex[2].tow+=0.95f/TWin.VScaleFactor; - break; - case 5: - vertex[1].tow+=0.95f/TWin.VScaleFactor; - vertex[2].tow+=0.95f/TWin.VScaleFactor; - break; - case 6: - vertex[0].tow+=0.95f/TWin.VScaleFactor; - vertex[3].tow+=0.95f/TWin.VScaleFactor; - break; - } - } - else - { - switch(VFlipped) - { - case 1: - vertex[2].tow+=1.0f/ST_FAC; - vertex[3].tow+=1.0f/ST_FAC; - break; - case 2: - vertex[0].tow+=1.0f/ST_FAC; - vertex[1].tow+=1.0f/ST_FAC; - break; - case 3: - vertex[1].tow+=1.0f/ST_FAC; - vertex[3].tow+=1.0f/ST_FAC; - break; - case 4: - vertex[0].tow+=1.0f/ST_FAC; - vertex[2].tow+=1.0f/ST_FAC; - break; - case 5: - vertex[1].tow+=1.0f/ST_FAC; - vertex[2].tow+=1.0f/ST_FAC; - break; - case 6: - vertex[0].tow+=1.0f/ST_FAC; - vertex[3].tow+=1.0f/ST_FAC; - break; - } - } -#else - if(bUsingTWin) - { - switch(VFlipped) - { - case 1: - vertex[2].tow+=1.0f/TWin.VScaleFactor; - vertex[3].tow+=1.0f/TWin.VScaleFactor; - break; - case 2: - vertex[0].tow+=1.0f/TWin.VScaleFactor; - vertex[1].tow+=1.0f/TWin.VScaleFactor; - break; - case 3: - vertex[1].tow+=1.0f/TWin.VScaleFactor; - vertex[3].tow+=1.0f/TWin.VScaleFactor; - break; - case 4: - vertex[0].tow+=1.0f/TWin.VScaleFactor; - vertex[2].tow+=1.0f/TWin.VScaleFactor; - break; - case 5: - vertex[1].tow+=1.0f/TWin.VScaleFactor; - vertex[2].tow+=1.0f/TWin.VScaleFactor; - break; - case 6: - vertex[0].tow+=1.0f/TWin.VScaleFactor; - vertex[3].tow+=1.0f/TWin.VScaleFactor; - break; - } - } - else - { - switch(VFlipped) - { - case 1: - vertex[2].tow+=1.0f; - vertex[3].tow+=1.0f; - break; - case 2: - vertex[0].tow+=1.0f; - vertex[1].tow+=1.0f; - break; - case 3: - vertex[1].tow+=1.0f; - vertex[3].tow+=1.0f; - break; - case 4: - vertex[0].tow+=1.0f; - vertex[2].tow+=1.0f; - break; - case 5: - vertex[1].tow+=1.0f; - vertex[2].tow+=1.0f; - break; - case 6: - vertex[0].tow+=1.0f; - vertex[3].tow+=1.0f; - break; - } - } -#endif - } - -} - -static void primPolyFT4(unsigned char * baseAddr) -{ - uint32_t *gpuData = ((uint32_t *)baseAddr); - short *sgpuData = ((short *) baseAddr); - - lx0 = sgpuData[2]; - ly0 = sgpuData[3]; - lx1 = sgpuData[6]; - ly1 = sgpuData[7]; - lx2 = sgpuData[10]; - ly2 = sgpuData[11]; - lx3 = sgpuData[14]; - ly3 = sgpuData[15]; - - if(offset4()) return; - - gl_vy[0]=baseAddr[9];//((gpuData[2]>>8)&0xff); - gl_vy[1]=baseAddr[17];//((gpuData[4]>>8)&0xff); - gl_vy[2]=baseAddr[25];//((gpuData[6]>>8)&0xff); - gl_vy[3]=baseAddr[33];//((gpuData[8]>>8)&0xff); - - gl_ux[0]=baseAddr[8];//(gpuData[2]&0xff); - gl_ux[1]=baseAddr[16];//(gpuData[4]&0xff); - gl_ux[2]=baseAddr[24];//(gpuData[6]&0xff); - gl_ux[3]=baseAddr[32];//(gpuData[8]&0xff); - - UpdateGlobalTP((unsigned short)(gpuData[4]>>16)); - ulClutID=(gpuData[2]>>16); - - bDrawTextured = TRUE; - bDrawSmoothShaded = FALSE; - SetRenderState(gpuData[0]); - - if(iOffscreenDrawing) - { - offsetPSX4(); - if(bDrawOffscreen4()) - { - InvalidateTextureAreaEx(); - SetRenderColor(gpuData[0]); - drawPoly4FT(baseAddr); - } - } - - SetRenderMode(gpuData[0], TRUE); - - SetZMask4(); - - assignTexture4(); - - RectTexAlign(); - - PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[3], &vertex[2]); - - if(bDrawMultiPass) - { - SetSemiTransMulti(1); - PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[3], &vertex[2]); - } - - if(ubOpaqueDraw) - { - SetZMask4O(); - if(bUseMultiPass) SetOpaqueColor(gpuData[0]); - DEFOPAQUEON - - if(bSmallAlpha && iFilterType<=2) - { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[3], &vertex[2]); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - SetZMask4O(); - } - - PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[3], &vertex[2]); - DEFOPAQUEOFF - } - - iDrawnSomething=1; -} - -//////////////////////////////////////////////////////////////////////// -// cmd: smooth shaded Texture3 -//////////////////////////////////////////////////////////////////////// - -static void primPolyGT3(unsigned char *baseAddr) -{ - uint32_t *gpuData = ((uint32_t *) baseAddr); - short *sgpuData = ((short *) baseAddr); - - lx0 = sgpuData[2]; - ly0 = sgpuData[3]; - lx1 = sgpuData[8]; - ly1 = sgpuData[9]; - lx2 = sgpuData[14]; - ly2 = sgpuData[15]; - - if(offset3()) return; - - // do texture stuff - gl_ux[0]=gl_ux[3]=baseAddr[8];//gpuData[2]&0xff; - gl_vy[0]=gl_vy[3]=baseAddr[9];//(gpuData[2]>>8)&0xff; - gl_ux[1]=baseAddr[20];//gpuData[5]&0xff; - gl_vy[1]=baseAddr[21];//(gpuData[5]>>8)&0xff; - gl_ux[2]=baseAddr[32];//gpuData[8]&0xff; - gl_vy[2]=baseAddr[33];//(gpuData[8]>>8)&0xff; - - UpdateGlobalTP((unsigned short)(gpuData[5]>>16)); - ulClutID=(gpuData[2]>>16); - - bDrawTextured = TRUE; - bDrawSmoothShaded = TRUE; - SetRenderState(gpuData[0]); - - if(iOffscreenDrawing) - { - offsetPSX3(); - if(bDrawOffscreen3()) - { - InvalidateTextureAreaEx(); - drawPoly3GT(baseAddr); - } - } - - SetRenderMode(gpuData[0], FALSE); - SetZMask3(); - - assignTexture3(); - - if(bDrawNonShaded) - { - //if(!bUseMultiPass) vertex[0].lcol=DoubleBGR2RGB(gpuData[0]); else vertex[0].lcol=gpuData[0]; - // eat this... - if(bGLBlend) vertex[0].c.lcol=0x7f7f7f; - else vertex[0].c.lcol=0xffffff; - vertex[0].c.col[3]=ubGloAlpha; - SETCOL(vertex[0]); - - PRIMdrawTexturedTri(&vertex[0], &vertex[1], &vertex[2]); - - if(ubOpaqueDraw) - { - SetZMask3O(); - DEFOPAQUEON - PRIMdrawTexturedTri(&vertex[0], &vertex[1], &vertex[2]); - DEFOPAQUEOFF - } - return; - } - - if(!bUseMultiPass && !bGLBlend) - { - vertex[0].c.lcol=DoubleBGR2RGB(gpuData[0]); - vertex[1].c.lcol=DoubleBGR2RGB(gpuData[3]); - vertex[2].c.lcol=DoubleBGR2RGB(gpuData[6]); - } - else - { - vertex[0].c.lcol=gpuData[0]; - vertex[1].c.lcol=gpuData[3]; - vertex[2].c.lcol=gpuData[6]; - } - vertex[0].c.col[3]=vertex[1].c.col[3]=vertex[2].c.col[3]=ubGloAlpha; - - PRIMdrawTexGouraudTriColor(&vertex[0], &vertex[1], &vertex[2]); - - if(bDrawMultiPass) - { - SetSemiTransMulti(1); - PRIMdrawTexGouraudTriColor(&vertex[0], &vertex[1], &vertex[2]); - } - - if(ubOpaqueDraw) - { - SetZMask3O(); - if(bUseMultiPass) - { - vertex[0].c.lcol=DoubleBGR2RGB(gpuData[0]); - vertex[1].c.lcol=DoubleBGR2RGB(gpuData[3]); - vertex[2].c.lcol=DoubleBGR2RGB(gpuData[6]); - vertex[0].c.col[3]=vertex[1].c.col[3]=vertex[2].c.col[3]=ubGloAlpha; - } - DEFOPAQUEON - PRIMdrawTexGouraudTriColor(&vertex[0], &vertex[1], &vertex[2]); - DEFOPAQUEOFF - } - - iDrawnSomething=1; -} - -//////////////////////////////////////////////////////////////////////// -// cmd: smooth shaded Poly3 -//////////////////////////////////////////////////////////////////////// - -static void primPolyG3(unsigned char *baseAddr) -{ - uint32_t *gpuData = ((uint32_t *)baseAddr); - short *sgpuData = ((short *) baseAddr); - - lx0 = sgpuData[2]; - ly0 = sgpuData[3]; - lx1 = sgpuData[6]; - ly1 = sgpuData[7]; - lx2 = sgpuData[10]; - ly2 = sgpuData[11]; - - if(offset3()) return; - - bDrawTextured = FALSE; - bDrawSmoothShaded = TRUE; - SetRenderState(gpuData[0]); - - if(iOffscreenDrawing) - { - offsetPSX3(); - if(bDrawOffscreen3()) - { - InvalidateTextureAreaEx(); - drawPoly3G(gpuData[0], gpuData[2], gpuData[4]); - } - } - - SetRenderMode(gpuData[0], FALSE); - SetZMask3NT(); - - vertex[0].c.lcol=gpuData[0]; - vertex[1].c.lcol=gpuData[2]; - vertex[2].c.lcol=gpuData[4]; - vertex[0].c.col[3]=vertex[1].c.col[3]=vertex[2].c.col[3]=ubGloColAlpha; - - PRIMdrawGouraudTriColor(&vertex[0], &vertex[1], &vertex[2]); - - iDrawnSomething=1; -} - -//////////////////////////////////////////////////////////////////////// -// cmd: smooth shaded Texture4 -//////////////////////////////////////////////////////////////////////// - -static void primPolyGT4(unsigned char *baseAddr) -{ - uint32_t *gpuData = ((uint32_t *)baseAddr); - short *sgpuData = ((short *)baseAddr); - - lx0 = sgpuData[2]; - ly0 = sgpuData[3]; - lx1 = sgpuData[8]; - ly1 = sgpuData[9]; - lx2 = sgpuData[14]; - ly2 = sgpuData[15]; - lx3 = sgpuData[20]; - ly3 = sgpuData[21]; - - if(offset4()) return; - - // do texture stuff - gl_ux[0]=baseAddr[8];//gpuData[2]&0xff; - gl_vy[0]=baseAddr[9];//(gpuData[2]>>8)&0xff; - gl_ux[1]=baseAddr[20];//gpuData[5]&0xff; - gl_vy[1]=baseAddr[21];//(gpuData[5]>>8)&0xff; - gl_ux[2]=baseAddr[32];//gpuData[8]&0xff; - gl_vy[2]=baseAddr[33];//(gpuData[8]>>8)&0xff; - gl_ux[3]=baseAddr[44];//gpuData[11]&0xff; - gl_vy[3]=baseAddr[45];//(gpuData[11]>>8)&0xff; - - UpdateGlobalTP((unsigned short)(gpuData[5]>>16)); - ulClutID=(gpuData[2]>>16); - - bDrawTextured = TRUE; - bDrawSmoothShaded = TRUE; - SetRenderState(gpuData[0]); - - if(iOffscreenDrawing) - { - offsetPSX4(); - if(bDrawOffscreen4()) - { - InvalidateTextureAreaEx(); - drawPoly4GT(baseAddr); - } - } - - SetRenderMode(gpuData[0], FALSE); - SetZMask4(); - - assignTexture4(); - - RectTexAlign(); - - if(bDrawNonShaded) - { - //if(!bUseMultiPass) vertex[0].lcol=DoubleBGR2RGB(gpuData[0]); else vertex[0].lcol=gpuData[0]; - if(bGLBlend) vertex[0].c.lcol=0x7f7f7f; - else vertex[0].c.lcol=0xffffff; - vertex[0].c.col[3]=ubGloAlpha; - SETCOL(vertex[0]); - - PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[3], &vertex[2]); - - if(ubOpaqueDraw) - { - SetZMask4O(); - ubGloAlpha=ubGloColAlpha=0xff; - DEFOPAQUEON - PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[3], &vertex[2]); - DEFOPAQUEOFF - } - return; - } - - if(!bUseMultiPass && !bGLBlend) - { - vertex[0].c.lcol=DoubleBGR2RGB(gpuData[0]); - vertex[1].c.lcol=DoubleBGR2RGB(gpuData[3]); - vertex[2].c.lcol=DoubleBGR2RGB(gpuData[6]); - vertex[3].c.lcol=DoubleBGR2RGB(gpuData[9]); - } - else - { - vertex[0].c.lcol=gpuData[0]; - vertex[1].c.lcol=gpuData[3]; - vertex[2].c.lcol=gpuData[6]; - vertex[3].c.lcol=gpuData[9]; - } - - vertex[0].c.col[3]=vertex[1].c.col[3]=vertex[2].c.col[3]=vertex[3].c.col[3]=ubGloAlpha; - - PRIMdrawTexGouraudTriColorQuad(&vertex[0], &vertex[1], &vertex[3],&vertex[2]); - - if(bDrawMultiPass) - { - SetSemiTransMulti(1); - PRIMdrawTexGouraudTriColorQuad(&vertex[0], &vertex[1], &vertex[3],&vertex[2]); - } - - if(ubOpaqueDraw) - { - SetZMask4O(); - if(bUseMultiPass) - { - vertex[0].c.lcol=DoubleBGR2RGB(gpuData[0]); - vertex[1].c.lcol=DoubleBGR2RGB(gpuData[3]); - vertex[2].c.lcol=DoubleBGR2RGB(gpuData[6]); - vertex[3].c.lcol=DoubleBGR2RGB(gpuData[9]); - vertex[0].c.col[3]=vertex[1].c.col[3]=vertex[2].c.col[3]=vertex[3].c.col[3]=ubGloAlpha; - } - ubGloAlpha=ubGloColAlpha=0xff; - DEFOPAQUEON - PRIMdrawTexGouraudTriColorQuad(&vertex[0], &vertex[1], &vertex[3],&vertex[2]); - DEFOPAQUEOFF - } - - iDrawnSomething=1; -} - -//////////////////////////////////////////////////////////////////////// -// cmd: smooth shaded Poly3 -//////////////////////////////////////////////////////////////////////// - -static void primPolyF3(unsigned char *baseAddr) -{ - uint32_t *gpuData = ((uint32_t *) baseAddr); - short *sgpuData = ((short *) baseAddr); - - lx0 = sgpuData[2]; - ly0 = sgpuData[3]; - lx1 = sgpuData[4]; - ly1 = sgpuData[5]; - lx2 = sgpuData[6]; - ly2 = sgpuData[7]; - - if(offset3()) return; - - bDrawTextured = FALSE; - bDrawSmoothShaded = FALSE; - SetRenderState(gpuData[0]); - - if(iOffscreenDrawing) - { - offsetPSX3(); - if(bDrawOffscreen3()) - { - InvalidateTextureAreaEx(); - drawPoly3F(gpuData[0]); - } - } - - SetRenderMode(gpuData[0], FALSE); - SetZMask3NT(); - - vertex[0].c.lcol=gpuData[0]; - vertex[0].c.col[3]=ubGloColAlpha; - SETCOL(vertex[0]); - - PRIMdrawTri(&vertex[0], &vertex[1], &vertex[2]); - - iDrawnSomething=1; -} - -//////////////////////////////////////////////////////////////////////// -// cmd: skipping shaded polylines -//////////////////////////////////////////////////////////////////////// - -static void primLineGSkip(unsigned char *baseAddr) -{ - uint32_t *gpuData = ((uint32_t *) baseAddr); - short *sgpuData = ((short *) baseAddr); - int iMax=255; - int i=2; - - lx1 = sgpuData[2]; - ly1 = sgpuData[3]; - - while(!(((gpuData[i] & 0xF000F000) == 0x50005000) && i>=4)) - { - i++; - - ly1 = (short)((gpuData[i]>>16) & 0xffff); - lx1 = (short)(gpuData[i] & 0xffff); - - i++;if(i>iMax) break; - } -} - -//////////////////////////////////////////////////////////////////////// -// cmd: shaded polylines -//////////////////////////////////////////////////////////////////////// - -static void primLineGEx(unsigned char *baseAddr) -{ - uint32_t *gpuData = ((uint32_t *) baseAddr); - int iMax=255; - short cx0,cx1,cy0,cy1;int i;BOOL bDraw=TRUE; - - bDrawTextured = FALSE; - bDrawSmoothShaded = TRUE; - SetRenderState(gpuData[0]); - SetRenderMode(gpuData[0], FALSE); - SetZMask4NT(); - - vertex[0].c.lcol=vertex[3].c.lcol=gpuData[0]; - vertex[0].c.col[3]=vertex[3].c.col[3]=ubGloColAlpha; - ly1 = (short)((gpuData[1]>>16) & 0xffff); - lx1 = (short)(gpuData[1] & 0xffff); - - i=2; - - //while((gpuData[i]>>24)!=0x55) - //while((gpuData[i]&0x50000000)!=0x50000000) - // currently best way to check for poly line end: - while(!(((gpuData[i] & 0xF000F000) == 0x50005000) && i>=4)) - { - ly0 = ly1;lx0=lx1; - vertex[1].c.lcol=vertex[2].c.lcol=vertex[0].c.lcol; - vertex[0].c.lcol=vertex[3].c.lcol=gpuData[i]; - vertex[0].c.col[3]=vertex[3].c.col[3]=ubGloColAlpha; - - i++; - - ly1 = (short)((gpuData[i]>>16) & 0xffff); - lx1 = (short)(gpuData[i] & 0xffff); - - if(offsetline()) bDraw=FALSE; else bDraw=TRUE; - - if (bDraw && ((lx0 != lx1) || (ly0 != ly1))) - { - if(iOffscreenDrawing) - { - cx0=lx0;cx1=lx1;cy0=ly0;cy1=ly1; - offsetPSXLine(); - if(bDrawOffscreen4()) - { - InvalidateTextureAreaEx(); - drawPoly4G(gpuData[i-3],gpuData[i-1],gpuData[i-3],gpuData[i-1]); - } - lx0=cx0;lx1=cx1;ly0=cy0;ly1=cy1; - } - - PRIMdrawGouraudLine(&vertex[0], &vertex[1], &vertex[2], &vertex[3]); - } - i++; - - if(i>iMax) break; - } - - iDrawnSomething=1; -} - -//////////////////////////////////////////////////////////////////////// -// cmd: shaded polyline2 -//////////////////////////////////////////////////////////////////////// - -static void primLineG2(unsigned char *baseAddr) -{ - uint32_t *gpuData = ((uint32_t *) baseAddr); - short *sgpuData = ((short *) baseAddr); - - lx0 = sgpuData[2]; - ly0 = sgpuData[3]; - lx1 = sgpuData[6]; - ly1 = sgpuData[7]; - - vertex[0].c.lcol=vertex[3].c.lcol=gpuData[0]; - vertex[1].c.lcol=vertex[2].c.lcol=gpuData[2]; - vertex[0].c.col[3]=vertex[1].c.col[3]=vertex[2].c.col[3]=vertex[3].c.col[3]=ubGloColAlpha; - - bDrawTextured = FALSE; - bDrawSmoothShaded = TRUE; - - if((lx0 == lx1) && (ly0 == ly1)) return; - - if(offsetline()) return; - - SetRenderState(gpuData[0]); - SetRenderMode(gpuData[0], FALSE); - SetZMask4NT(); - - if(iOffscreenDrawing) - { - offsetPSXLine(); - if(bDrawOffscreen4()) - { - InvalidateTextureAreaEx(); - drawPoly4G(gpuData[0],gpuData[2],gpuData[0],gpuData[2]); - } - } - - //if(ClipVertexList4()) - PRIMdrawGouraudLine(&vertex[0], &vertex[1], &vertex[2], &vertex[3]); - - iDrawnSomething=1; -} - -//////////////////////////////////////////////////////////////////////// -// cmd: skipping flat polylines -//////////////////////////////////////////////////////////////////////// - -static void primLineFSkip(unsigned char *baseAddr) -{ - uint32_t *gpuData = ((uint32_t *) baseAddr); - int i=2,iMax=255; - - ly1 = (short)((gpuData[1]>>16) & 0xffff); - lx1 = (short)(gpuData[1] & 0xffff); - - while(!(((gpuData[i] & 0xF000F000) == 0x50005000) && i>=3)) - { - ly1 = (short)((gpuData[i]>>16) & 0xffff); - lx1 = (short)(gpuData[i] & 0xffff); - i++;if(i>iMax) break; - } -} - -//////////////////////////////////////////////////////////////////////// -// cmd: drawing flat polylines -//////////////////////////////////////////////////////////////////////// - -static void primLineFEx(unsigned char *baseAddr) -{ - uint32_t *gpuData = ((uint32_t *) baseAddr); - int iMax; - short cx0,cx1,cy0,cy1;int i; - - iMax=255; - - bDrawTextured = FALSE; - bDrawSmoothShaded = FALSE; - SetRenderState(gpuData[0]); - SetRenderMode(gpuData[0], FALSE); - SetZMask4NT(); - - vertex[0].c.lcol=gpuData[0]; - vertex[0].c.col[3]=ubGloColAlpha; - - ly1 = (short)((gpuData[1]>>16) & 0xffff); - lx1 = (short)(gpuData[1] & 0xffff); - - i=2; - -// while(!(gpuData[i]&0x40000000)) -// while((gpuData[i]>>24)!=0x55) -// while((gpuData[i]&0x50000000)!=0x50000000) -// currently best way to check for poly line end: - while(!(((gpuData[i] & 0xF000F000) == 0x50005000) && i>=3)) - { - ly0 = ly1;lx0=lx1; - ly1 = (short)((gpuData[i]>>16) & 0xffff); - lx1 = (short)(gpuData[i] & 0xffff); - - if(!offsetline()) - { - if(iOffscreenDrawing) - { - cx0=lx0;cx1=lx1;cy0=ly0;cy1=ly1; - offsetPSXLine(); - if(bDrawOffscreen4()) - { - InvalidateTextureAreaEx(); - drawPoly4F(gpuData[0]); - } - lx0=cx0;lx1=cx1;ly0=cy0;ly1=cy1; - } - PRIMdrawFlatLine(&vertex[0], &vertex[1], &vertex[2], &vertex[3]); - } - - i++;if(i>iMax) break; - } - - iDrawnSomething=1; -} - -//////////////////////////////////////////////////////////////////////// -// cmd: drawing flat polyline2 -//////////////////////////////////////////////////////////////////////// - -static void primLineF2(unsigned char *baseAddr) -{ - uint32_t *gpuData = ((uint32_t *) baseAddr); - short *sgpuData = ((short *) baseAddr); - - lx0 = sgpuData[2]; - ly0 = sgpuData[3]; - lx1 = sgpuData[4]; - ly1 = sgpuData[5]; - - if(offsetline()) return; - - bDrawTextured = FALSE; - bDrawSmoothShaded = FALSE; - SetRenderState(gpuData[0]); - SetRenderMode(gpuData[0], FALSE); - SetZMask4NT(); - - vertex[0].c.lcol=gpuData[0]; - vertex[0].c.col[3]=ubGloColAlpha; - - if(iOffscreenDrawing) - { - offsetPSXLine(); - if(bDrawOffscreen4()) - { - InvalidateTextureAreaEx(); - drawPoly4F(gpuData[0]); - } - } - - //if(ClipVertexList4()) - PRIMdrawFlatLine(&vertex[0], &vertex[1], &vertex[2], &vertex[3]); - - iDrawnSomething=1; -} - -//////////////////////////////////////////////////////////////////////// -// cmd: well, easiest command... not implemented -//////////////////////////////////////////////////////////////////////// - -static void primNI(unsigned char *bA) -{ -} - -//////////////////////////////////////////////////////////////////////// -// cmd func ptr table -//////////////////////////////////////////////////////////////////////// - -void (*primTableJ[256])(unsigned char *) = -{ - // 00 - primNI,primNI,primBlkFill,primNI,primNI,primNI,primNI,primNI, - // 08 - primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI, - // 10 - primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI, - // 18 - primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI, - // 20 - primPolyF3,primPolyF3,primPolyF3,primPolyF3,primPolyFT3,primPolyFT3,primPolyFT3,primPolyFT3, - // 28 - primPolyF4,primPolyF4,primPolyF4,primPolyF4,primPolyFT4,primPolyFT4,primPolyFT4,primPolyFT4, - // 30 - primPolyG3,primPolyG3,primPolyG3,primPolyG3,primPolyGT3,primPolyGT3,primPolyGT3,primPolyGT3, - // 38 - primPolyG4,primPolyG4,primPolyG4,primPolyG4,primPolyGT4,primPolyGT4,primPolyGT4,primPolyGT4, - // 40 - primLineF2,primLineF2,primLineF2,primLineF2,primNI,primNI,primNI,primNI, - // 48 - primLineFEx,primLineFEx,primLineFEx,primLineFEx,primLineFEx,primLineFEx,primLineFEx,primLineFEx, - // 50 - primLineG2,primLineG2,primLineG2,primLineG2,primNI,primNI,primNI,primNI, - // 58 - primLineGEx,primLineGEx,primLineGEx,primLineGEx,primLineGEx,primLineGEx,primLineGEx,primLineGEx, - // 60 - primTileS,primTileS,primTileS,primTileS,primSprtS,primSprtS,primSprtS,primSprtS, - // 68 - primTile1,primTile1,primTile1,primTile1,primNI,primNI,primNI,primNI, - // 70 - primTile8,primTile8,primTile8,primTile8,primSprt8,primSprt8,primSprt8,primSprt8, - // 78 - primTile16,primTile16,primTile16,primTile16,primSprt16,primSprt16,primSprt16,primSprt16, - // 80 - primMoveImage,primNI,primNI,primNI,primNI,primNI,primNI,primNI, - // 88 - primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI, - // 90 - primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI, - // 98 - primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI, - // a0 - primLoadImage,primNI,primNI,primNI,primNI,primNI,primNI,primNI, - // a8 - primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI, - // b0 - primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI, - // b8 - primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI, - // c0 - primStoreImage,primNI,primNI,primNI,primNI,primNI,primNI,primNI, - // c8 - primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI, - // d0 - primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI, - // d8 - primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI, - // e0 - primNI,cmdTexturePage,cmdTextureWindow,cmdDrawAreaStart,cmdDrawAreaEnd,cmdDrawOffset,cmdSTP,primNI, - // e8 - primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI, - // f0 - primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI, - // f8 - primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI -}; - -//////////////////////////////////////////////////////////////////////// -// cmd func ptr table for skipping -//////////////////////////////////////////////////////////////////////// - -void (*primTableSkip[256])(unsigned char *) = -{ - // 00 - primNI,primNI,primBlkFill,primNI,primNI,primNI,primNI,primNI, - // 08 - primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI, - // 10 - primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI, - // 18 - primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI, - // 20 - primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI, - // 28 - primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI, - // 30 - primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI, - // 38 - primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI, - // 40 - primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI, - // 48 - primLineFSkip,primLineFSkip,primLineFSkip,primLineFSkip,primLineFSkip,primLineFSkip,primLineFSkip,primLineFSkip, - // 50 - primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI, - // 58 - primLineGSkip,primLineGSkip,primLineGSkip,primLineGSkip,primLineGSkip,primLineGSkip,primLineGSkip,primLineGSkip, - // 60 - primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI, - // 68 - primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI, - // 70 - primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI, - // 78 - primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI, - // 80 - primMoveImage,primNI,primNI,primNI,primNI,primNI,primNI,primNI, - // 88 - primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI, - // 90 - primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI, - // 98 - primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI, - // a0 - primLoadImage,primNI,primNI,primNI,primNI,primNI,primNI,primNI, - // a8 - primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI, - // b0 - primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI, - // b8 - primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI, - // c0 - primStoreImage,primNI,primNI,primNI,primNI,primNI,primNI,primNI, - // c8 - primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI, - // d0 - primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI, - // d8 - primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI, - // e0 - primNI,cmdTexturePage,cmdTextureWindow,cmdDrawAreaStart,cmdDrawAreaEnd,cmdDrawOffset,cmdSTP,primNI, - // e8 - primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI, - // f0 - primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI, - // f8 - primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI -}; +/***************************************************************************
+ prim.c - description
+ -------------------
+ begin : Sun Mar 08 2009
+ copyright : (C) 1999-2009 by Pete Bernert
+ web : www.pbernert.com
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. See also the license.txt file for *
+ * additional informations. *
+ * *
+ ***************************************************************************/
+
+#include "stdafx.h"
+
+#define _IN_PRIMDRAW
+
+#include "externals.h"
+#include "gpu.h"
+#include "draw.h"
+#include "soft.h"
+#include "texture.h"
+
+////////////////////////////////////////////////////////////////////////
+// defines
+////////////////////////////////////////////////////////////////////////
+
+#define DEFOPAQUEON glAlphaFunc(GL_EQUAL,0.0f);bBlendEnable=FALSE;glDisable(GL_BLEND);
+#define DEFOPAQUEOFF glAlphaFunc(GL_GREATER,0.49f);
+
+////////////////////////////////////////////////////////////////////////
+// globals
+////////////////////////////////////////////////////////////////////////
+
+BOOL bDrawTextured; // current active drawing states
+BOOL bDrawSmoothShaded;
+BOOL bOldSmoothShaded;
+BOOL bDrawNonShaded;
+BOOL bDrawMultiPass;
+int iOffscreenDrawing;
+int iDrawnSomething=0;
+
+BOOL bRenderFrontBuffer=FALSE; // flag for front buffer rendering
+
+GLubyte ubGloAlpha; // texture alpha
+GLubyte ubGloColAlpha; // color alpha
+int iFilterType; // type of filter
+BOOL bFullVRam=FALSE; // sign for tex win
+BOOL bDrawDither; // sign for dither
+BOOL bUseMultiPass; // sign for multi pass
+GLuint gTexName; // binded texture
+BOOL bTexEnabled; // texture enable flag
+BOOL bBlendEnable; // blend enable flag
+PSXRect_t xrUploadArea; // rect to upload
+PSXRect_t xrUploadAreaIL; // rect to upload
+PSXRect_t xrUploadAreaRGB24; // rect to upload rgb24
+int iSpriteTex=0; // flag for "hey, it's a sprite"
+unsigned short usMirror; // mirror, mirror on the wall
+
+BOOL bNeedUploadAfter=FALSE; // sign for uploading in next frame
+BOOL bNeedUploadTest=FALSE; // sign for upload test
+BOOL bUsingTWin=FALSE; // tex win active flag
+BOOL bUsingMovie=FALSE; // movie active flag
+PSXRect_t xrMovieArea; // rect for movie upload
+short sSprite_ux2; // needed for sprire adjust
+short sSprite_vy2; //
+uint32_t ulOLDCOL=0; // active color
+uint32_t ulClutID; // clut
+
+uint32_t dwCfgFixes; // game fixes
+uint32_t dwActFixes=0;
+uint32_t dwEmuFixes=0;
+BOOL bUseFixes;
+
+int drawX,drawY,drawW,drawH; // offscreen drawing checkers
+short sxmin,sxmax,symin,symax;
+
+////////////////////////////////////////////////////////////////////////
+// Update global TP infos
+////////////////////////////////////////////////////////////////////////
+
+void UpdateGlobalTP(unsigned short gdata)
+{
+ GlobalTextAddrX = (gdata << 6) & 0x3c0;
+
+ if(iGPUHeight==1024) // ZN mode
+ {
+ if(dwGPUVersion==2) // very special zn gpu
+ {
+ GlobalTextAddrY =((gdata & 0x60 ) << 3);
+ GlobalTextIL =(gdata & 0x2000) >> 13;
+ GlobalTextABR = (unsigned short)((gdata >> 7) & 0x3);
+ GlobalTextTP = (gdata >> 9) & 0x3;
+ if(GlobalTextTP==3) GlobalTextTP=2;
+ GlobalTexturePage = (GlobalTextAddrX>>6)+(GlobalTextAddrY>>4);
+ usMirror =0;
+ STATUSREG = (STATUSREG & 0xffffe000 ) | (gdata & 0x1fff );
+ return;
+ }
+ else // "enhanced" psx gpu
+ {
+ GlobalTextAddrY = (unsigned short)(((gdata << 4) & 0x100) | ((gdata >> 2) & 0x200));
+ }
+ }
+ else GlobalTextAddrY = (gdata << 4) & 0x100; // "normal" psx gpu
+
+ usMirror=gdata&0x3000;
+
+ GlobalTextTP = (gdata >> 7) & 0x3; // tex mode (4,8,15)
+ if(GlobalTextTP==3) GlobalTextTP=2; // seen in Wild9 :(
+ GlobalTextABR = (gdata >> 5) & 0x3; // blend mode
+
+ GlobalTexturePage = (GlobalTextAddrX>>6)+(GlobalTextAddrY>>4);
+
+ STATUSREG&=~0x07ff; // Clear the necessary bits
+ STATUSREG|=(gdata & 0x07ff); // set the necessary bits
+}
+
+unsigned int DoubleBGR2RGB (unsigned int BGR)
+{
+ unsigned int ebx,eax,edx;
+
+ ebx=(BGR&0x000000ff)<<1;
+ if(ebx&0x00000100) ebx=0x000000ff;
+
+ eax=(BGR&0x0000ff00)<<1;
+ if(eax&0x00010000) eax=0x0000ff00;
+
+ edx=(BGR&0x00ff0000)<<1;
+ if(edx&0x01000000) edx=0x00ff0000;
+
+ return (ebx|eax|edx);
+}
+
+unsigned short BGR24to16 (uint32_t BGR)
+{
+ return ((BGR>>3)&0x1f)|((BGR&0xf80000)>>9)|((BGR&0xf800)>>6);
+}
+
+////////////////////////////////////////////////////////////////////////
+// OpenGL primitive drawing commands
+////////////////////////////////////////////////////////////////////////
+
+__inline void PRIMdrawTexturedQuad(OGLVertex* vertex1, OGLVertex* vertex2,
+ OGLVertex* vertex3, OGLVertex* vertex4)
+{
+ glBegin(GL_TRIANGLE_STRIP);
+ glTexCoord2fv(&vertex1->sow);
+ glVertex3fv(&vertex1->x);
+
+ glTexCoord2fv(&vertex2->sow);
+ glVertex3fv(&vertex2->x);
+
+ glTexCoord2fv(&vertex4->sow);
+ glVertex3fv(&vertex4->x);
+
+ glTexCoord2fv(&vertex3->sow);
+ glVertex3fv(&vertex3->x);
+ glEnd();
+}
+
+/////////////////////////////////////////////////////////
+
+__inline void PRIMdrawTexturedTri(OGLVertex* vertex1, OGLVertex* vertex2,
+ OGLVertex* vertex3)
+{
+ glBegin(GL_TRIANGLES);
+ glTexCoord2fv(&vertex1->sow);
+ glVertex3fv(&vertex1->x);
+
+ glTexCoord2fv(&vertex2->sow);
+ glVertex3fv(&vertex2->x);
+
+ glTexCoord2fv(&vertex3->sow);
+ glVertex3fv(&vertex3->x);
+ glEnd();
+}
+
+/////////////////////////////////////////////////////////
+
+__inline void PRIMdrawTexGouraudTriColor(OGLVertex* vertex1, OGLVertex* vertex2,
+ OGLVertex* vertex3)
+{
+ glBegin(GL_TRIANGLES);
+
+ SETPCOL(vertex1);
+ glTexCoord2fv(&vertex1->sow);
+ glVertex3fv(&vertex1->x);
+
+ SETPCOL(vertex2);
+ glTexCoord2fv(&vertex2->sow);
+ glVertex3fv(&vertex2->x);
+
+ SETPCOL(vertex3);
+ glTexCoord2fv(&vertex3->sow);
+ glVertex3fv(&vertex3->x);
+ glEnd();
+}
+
+/////////////////////////////////////////////////////////
+
+__inline void PRIMdrawTexGouraudTriColorQuad(OGLVertex* vertex1, OGLVertex* vertex2,
+ OGLVertex* vertex3, OGLVertex* vertex4)
+{
+ glBegin(GL_TRIANGLE_STRIP);
+ SETPCOL(vertex1);
+ glTexCoord2fv(&vertex1->sow);
+ glVertex3fv(&vertex1->x);
+
+ SETPCOL(vertex2);
+ glTexCoord2fv(&vertex2->sow);
+ glVertex3fv(&vertex2->x);
+
+ SETPCOL(vertex4);
+ glTexCoord2fv(&vertex4->sow);
+ glVertex3fv(&vertex4->x);
+
+ SETPCOL(vertex3);
+ glTexCoord2fv(&vertex3->sow);
+ glVertex3fv(&vertex3->x);
+ glEnd();
+}
+
+/////////////////////////////////////////////////////////
+
+__inline void PRIMdrawTri(OGLVertex* vertex1, OGLVertex* vertex2, OGLVertex* vertex3)
+{
+ glBegin(GL_TRIANGLES);
+ glVertex3fv(&vertex1->x);
+ glVertex3fv(&vertex2->x);
+ glVertex3fv(&vertex3->x);
+ glEnd();
+}
+
+/////////////////////////////////////////////////////////
+
+__inline void PRIMdrawTri2(OGLVertex* vertex1, OGLVertex* vertex2,
+ OGLVertex* vertex3, OGLVertex* vertex4)
+{
+ glBegin(GL_TRIANGLE_STRIP);
+ glVertex3fv(&vertex1->x);
+ glVertex3fv(&vertex3->x);
+ glVertex3fv(&vertex2->x);
+ glVertex3fv(&vertex4->x);
+ glEnd();
+}
+
+/////////////////////////////////////////////////////////
+
+__inline void PRIMdrawGouraudTriColor(OGLVertex* vertex1, OGLVertex* vertex2,
+ OGLVertex* vertex3)
+{
+ glBegin(GL_TRIANGLES);
+ SETPCOL(vertex1);
+ glVertex3fv(&vertex1->x);
+
+ SETPCOL(vertex2);
+ glVertex3fv(&vertex2->x);
+
+ SETPCOL(vertex3);
+ glVertex3fv(&vertex3->x);
+ glEnd();
+}
+
+/////////////////////////////////////////////////////////
+
+__inline void PRIMdrawGouraudTri2Color(OGLVertex* vertex1, OGLVertex* vertex2,
+ OGLVertex* vertex3, OGLVertex* vertex4)
+{
+ glBegin(GL_TRIANGLE_STRIP);
+ SETPCOL(vertex1);
+ glVertex3fv(&vertex1->x);
+
+ SETPCOL(vertex3);
+ glVertex3fv(&vertex3->x);
+
+ SETPCOL(vertex2);
+ glVertex3fv(&vertex2->x);
+
+ SETPCOL(vertex4);
+ glVertex3fv(&vertex4->x);
+ glEnd();
+}
+
+/////////////////////////////////////////////////////////
+
+__inline void PRIMdrawFlatLine(OGLVertex* vertex1, OGLVertex* vertex2,OGLVertex* vertex3, OGLVertex* vertex4)
+{
+ glBegin(GL_QUADS);
+
+ SETPCOL(vertex1);
+
+ glVertex3fv(&vertex1->x);
+ glVertex3fv(&vertex2->x);
+ glVertex3fv(&vertex3->x);
+ glVertex3fv(&vertex4->x);
+ glEnd();
+}
+
+/////////////////////////////////////////////////////////
+
+__inline void PRIMdrawGouraudLine(OGLVertex* vertex1, OGLVertex* vertex2,OGLVertex* vertex3, OGLVertex* vertex4)
+{
+ glBegin(GL_QUADS);
+
+ SETPCOL(vertex1);
+ glVertex3fv(&vertex1->x);
+
+ SETPCOL(vertex2);
+ glVertex3fv(&vertex2->x);
+
+ SETPCOL(vertex3);
+ glVertex3fv(&vertex3->x);
+
+ SETPCOL(vertex4);
+ glVertex3fv(&vertex4->x);
+ glEnd();
+}
+
+/////////////////////////////////////////////////////////
+
+__inline void PRIMdrawQuad(OGLVertex* vertex1, OGLVertex* vertex2,
+ OGLVertex* vertex3, OGLVertex* vertex4)
+{
+ glBegin(GL_QUADS);
+ glVertex3fv(&vertex1->x);
+ glVertex3fv(&vertex2->x);
+ glVertex3fv(&vertex3->x);
+ glVertex3fv(&vertex4->x);
+ glEnd();
+}
+
+////////////////////////////////////////////////////////////////////////
+// Transparent blending settings
+////////////////////////////////////////////////////////////////////////
+
+static GLenum obm1=GL_ZERO;
+static GLenum obm2=GL_ZERO;
+
+typedef struct SEMITRANSTAG
+{
+ GLenum srcFac;
+ GLenum dstFac;
+ GLubyte alpha;
+} SemiTransParams;
+
+SemiTransParams TransSets[4]=
+{
+ {GL_SRC_ALPHA,GL_SRC_ALPHA, 127},
+ {GL_ONE, GL_ONE, 255},
+ {GL_ZERO, GL_ONE_MINUS_SRC_COLOR,255},
+ {GL_ONE_MINUS_SRC_ALPHA,GL_ONE, 192}
+};
+
+////////////////////////////////////////////////////////////////////////
+
+void SetSemiTrans(void)
+{
+/*
+* 0.5 x B + 0.5 x F
+* 1.0 x B + 1.0 x F
+* 1.0 x B - 1.0 x F
+* 1.0 x B +0.25 x F
+*/
+
+ if(!DrawSemiTrans) // no semi trans at all?
+ {
+ if(bBlendEnable)
+ {glDisable(GL_BLEND);bBlendEnable=FALSE;} // -> don't wanna blend
+ ubGloAlpha=ubGloColAlpha=255; // -> full alpha
+ return; // -> and bye
+ }
+
+ ubGloAlpha=ubGloColAlpha=TransSets[GlobalTextABR].alpha;
+
+ if(!bBlendEnable)
+ {glEnable(GL_BLEND);bBlendEnable=TRUE;} // wanna blend
+
+ if(TransSets[GlobalTextABR].srcFac!=obm1 ||
+ TransSets[GlobalTextABR].dstFac!=obm2)
+ {
+ if(glBlendEquationEXTEx==NULL)
+ {
+ obm1=TransSets[GlobalTextABR].srcFac;
+ obm2=TransSets[GlobalTextABR].dstFac;
+ glBlendFunc(obm1,obm2); // set blend func
+ }
+ else
+ if(TransSets[GlobalTextABR].dstFac !=GL_ONE_MINUS_SRC_COLOR)
+ {
+ if(obm2==GL_ONE_MINUS_SRC_COLOR)
+ glBlendEquationEXTEx(FUNC_ADD_EXT);
+ obm1=TransSets[GlobalTextABR].srcFac;
+ obm2=TransSets[GlobalTextABR].dstFac;
+ glBlendFunc(obm1,obm2); // set blend func
+ }
+ else
+ {
+ glBlendEquationEXTEx(FUNC_REVERSESUBTRACT_EXT);
+ obm1=TransSets[GlobalTextABR].srcFac;
+ obm2=TransSets[GlobalTextABR].dstFac;
+ glBlendFunc(GL_ONE,GL_ONE); // set blend func
+ }
+ }
+}
+
+void SetScanTrans(void) // blending for scan lines
+{
+ if(glBlendEquationEXTEx!=NULL)
+ {
+ if(obm2==GL_ONE_MINUS_SRC_COLOR)
+ glBlendEquationEXTEx(FUNC_ADD_EXT);
+ }
+
+ obm1=TransSets[0].srcFac;
+ obm2=TransSets[0].dstFac;
+ glBlendFunc(obm1,obm2); // set blend func
+}
+
+void SetScanTexTrans(void) // blending for scan mask texture
+{
+ if(glBlendEquationEXTEx!=NULL)
+ {
+ if(obm2==GL_ONE_MINUS_SRC_COLOR)
+ glBlendEquationEXTEx(FUNC_ADD_EXT);
+ }
+
+ obm1=TransSets[2].srcFac;
+ obm2=TransSets[2].dstFac;
+ glBlendFunc(obm1,obm2); // set blend func
+}
+
+////////////////////////////////////////////////////////////////////////
+// multi pass in old 'Advanced blending' mode... got it from Lewpy :)
+////////////////////////////////////////////////////////////////////////
+
+SemiTransParams MultiTexTransSets[4][2]=
+{
+ {
+ {GL_ONE ,GL_SRC_ALPHA, 127},
+ {GL_SRC_ALPHA,GL_ONE, 127}
+ },
+ {
+ {GL_ONE, GL_SRC_ALPHA, 255},
+ {GL_SRC_ALPHA,GL_ONE, 255}
+ },
+ {
+ {GL_ZERO, GL_ONE_MINUS_SRC_COLOR,255},
+ {GL_ZERO, GL_ONE_MINUS_SRC_COLOR,255}
+ },
+ {
+ {GL_SRC_ALPHA,GL_ONE, 127},
+ {GL_ONE_MINUS_SRC_ALPHA,GL_ONE, 255}
+ }
+};
+
+////////////////////////////////////////////////////////////////////////
+
+SemiTransParams MultiColTransSets[4]=
+{
+ {GL_ONE_MINUS_SRC_ALPHA,GL_SRC_ALPHA,127},
+ {GL_ONE, GL_ONE, 255},
+ {GL_ZERO, GL_ONE_MINUS_SRC_COLOR,255},
+ {GL_SRC_ALPHA,GL_ONE, 127}
+};
+
+////////////////////////////////////////////////////////////////////////
+
+void SetSemiTransMulti(int Pass)
+{
+ static GLenum bm1=GL_ZERO;
+ static GLenum bm2=GL_ONE;
+
+ ubGloAlpha=255;
+ ubGloColAlpha=255;
+
+ // are we enabling SemiTransparent mode?
+ if(DrawSemiTrans)
+ {
+ if(bDrawTextured)
+ {
+ bm1=MultiTexTransSets[GlobalTextABR][Pass].srcFac;
+ bm2=MultiTexTransSets[GlobalTextABR][Pass].dstFac;
+ ubGloAlpha=MultiTexTransSets[GlobalTextABR][Pass].alpha;
+ }
+ // no texture
+ else
+ {
+ bm1=MultiColTransSets[GlobalTextABR].srcFac;
+ bm2=MultiColTransSets[GlobalTextABR].dstFac;
+ ubGloColAlpha=MultiColTransSets[GlobalTextABR].alpha;
+ }
+ }
+ // no shading
+ else
+ {
+ if(Pass==0)
+ {
+ // disable blending
+ bm1=GL_ONE;bm2=GL_ZERO;
+ }
+ else
+ {
+ // disable blending, but add src col a second time
+ bm1=GL_ONE;bm2=GL_ONE;
+ }
+ }
+
+ if(!bBlendEnable)
+ {glEnable(GL_BLEND);bBlendEnable=TRUE;} // wanna blend
+
+ if(bm1!=obm1 || bm2!=obm2)
+ {
+ glBlendFunc(bm1,bm2); // set blend func
+ obm1=bm1;obm2=bm2;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+// Set several rendering stuff including blending
+////////////////////////////////////////////////////////////////////////
+
+__inline void SetZMask3O(void)
+{
+ if(iUseMask && DrawSemiTrans && !iSetMask)
+ {
+ vertex[0].z=vertex[1].z=vertex[2].z=gl_z;
+ gl_z+=0.00004f;
+ }
+}
+
+__inline void SetZMask3(void)
+{
+ if(iUseMask)
+ {
+ if(iSetMask || DrawSemiTrans)
+ {vertex[0].z=vertex[1].z=vertex[2].z=0.95f;}
+ else
+ {
+ vertex[0].z=vertex[1].z=vertex[2].z=gl_z;
+ gl_z+=0.00004f;
+ }
+ }
+}
+
+__inline void SetZMask3NT(void)
+{
+ if(iUseMask)
+ {
+ if(iSetMask)
+ {vertex[0].z=vertex[1].z=vertex[2].z=0.95f;}
+ else
+ {
+ vertex[0].z=vertex[1].z=vertex[2].z=gl_z;
+ gl_z+=0.00004f;
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+__inline void SetZMask4O(void)
+{
+ if(iUseMask && DrawSemiTrans && !iSetMask)
+ {
+ vertex[0].z=vertex[1].z=vertex[2].z=vertex[3].z=gl_z;
+ gl_z+=0.00004f;
+ }
+}
+
+__inline void SetZMask4(void)
+{
+ if(iUseMask)
+ {
+ if(iSetMask || DrawSemiTrans)
+ {vertex[0].z=vertex[1].z=vertex[2].z=vertex[3].z=0.95f;}
+ else
+ {
+ vertex[0].z=vertex[1].z=vertex[2].z=vertex[3].z=gl_z;
+ gl_z+=0.00004f;
+ }
+ }
+}
+
+__inline void SetZMask4NT(void)
+{
+ if(iUseMask)
+ {
+ if(iSetMask==1)
+ {vertex[0].z=vertex[1].z=vertex[2].z=vertex[3].z=0.95f;}
+ else
+ {
+ vertex[0].z=vertex[1].z=vertex[2].z=vertex[3].z=gl_z;
+ gl_z+=0.00004f;
+ }
+ }
+}
+
+__inline void SetZMask4SP(void)
+{
+ if(iUseMask)
+ {
+ if(iSetMask==1)
+ {vertex[0].z=vertex[1].z=vertex[2].z=vertex[3].z=0.95f;}
+ else
+ {
+ if(bCheckMask)
+ {
+ vertex[0].z=vertex[1].z=vertex[2].z=vertex[3].z=gl_z;
+ gl_z+=0.00004f;
+ }
+ else
+ {vertex[0].z=vertex[1].z=vertex[2].z=vertex[3].z=0.95f;}
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+__inline void SetRenderState(uint32_t DrawAttributes)
+{
+ bDrawNonShaded = (SHADETEXBIT(DrawAttributes)) ? TRUE : FALSE;
+ DrawSemiTrans = (SEMITRANSBIT(DrawAttributes)) ? TRUE : FALSE;
+}
+
+////////////////////////////////////////////////////////////////////////
+
+__inline void SetRenderColor(uint32_t DrawAttributes)
+{
+ if(bDrawNonShaded) {g_m1=g_m2=g_m3=128;}
+ else
+ {
+ g_m1=DrawAttributes&0xff;
+ g_m2=(DrawAttributes>>8)&0xff;
+ g_m3=(DrawAttributes>>16)&0xff;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void SetRenderMode(uint32_t DrawAttributes, BOOL bSCol)
+{
+ if((bUseMultiPass) && (bDrawTextured) && !(bDrawNonShaded))
+ {bDrawMultiPass = TRUE; SetSemiTransMulti(0);}
+ else {bDrawMultiPass = FALSE;SetSemiTrans();}
+
+ if(bDrawTextured) // texture ? build it/get it from cache
+ {
+ GLuint currTex;
+ if(bUsingTWin) currTex=LoadTextureWnd(GlobalTexturePage,GlobalTextTP, ulClutID);
+ else if(bUsingMovie) currTex=LoadTextureMovie();
+ else currTex=SelectSubTextureS(GlobalTextTP,ulClutID);
+
+ if(gTexName!=currTex)
+ {gTexName=currTex;glBindTexture(GL_TEXTURE_2D,currTex);}
+
+ if(!bTexEnabled) // -> turn texturing on
+ {bTexEnabled=TRUE;glEnable(GL_TEXTURE_2D);}
+ }
+ else // no texture ?
+ if(bTexEnabled)
+ {bTexEnabled=FALSE;glDisable(GL_TEXTURE_2D);} // -> turn texturing off
+
+ if(bSCol) // also set color ?
+ {
+ if((dwActFixes&4) && ((DrawAttributes&0x00ffffff)==0))
+ DrawAttributes|=0x007f7f7f;
+
+ if(bDrawNonShaded) // -> non shaded?
+ {
+ if(bGLBlend) vertex[0].c.lcol=0x7f7f7f; // --> solid color...
+ else vertex[0].c.lcol=0xffffff;
+ }
+ else // -> shaded?
+ {
+ if(!bUseMultiPass && !bGLBlend) // --> given color...
+ vertex[0].c.lcol=DoubleBGR2RGB(DrawAttributes);
+ else vertex[0].c.lcol=DrawAttributes;
+ }
+ vertex[0].c.col[3]=ubGloAlpha; // -> set color with
+ SETCOL(vertex[0]); // texture alpha
+ }
+
+ if(bDrawSmoothShaded!=bOldSmoothShaded) // shading changed?
+ {
+ if(bDrawSmoothShaded) glShadeModel(GL_SMOOTH); // -> set actual shading
+ else glShadeModel(GL_FLAT);
+ bOldSmoothShaded=bDrawSmoothShaded;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+// Set Opaque multipass color
+////////////////////////////////////////////////////////////////////////
+
+void SetOpaqueColor(uint32_t DrawAttributes)
+{
+ if(bDrawNonShaded) return; // no shading? bye
+
+ DrawAttributes=DoubleBGR2RGB(DrawAttributes); // multipass is just half color, so double it on opaque pass
+ vertex[0].c.lcol=DrawAttributes|0xff000000;
+ SETCOL(vertex[0]); // set color
+}
+
+////////////////////////////////////////////////////////////////////////
+// Fucking stupid screen coord checking
+////////////////////////////////////////////////////////////////////////
+
+BOOL ClipVertexListScreen(void)
+{
+ if (lx0 >= PSXDisplay.DisplayEnd.x) goto NEXTSCRTEST;
+ if (ly0 >= PSXDisplay.DisplayEnd.y) goto NEXTSCRTEST;
+ if (lx2 < PSXDisplay.DisplayPosition.x) goto NEXTSCRTEST;
+ if (ly2 < PSXDisplay.DisplayPosition.y) goto NEXTSCRTEST;
+
+ return TRUE;
+
+NEXTSCRTEST:
+ if(PSXDisplay.InterlacedTest) return FALSE;
+
+ if (lx0 >= PreviousPSXDisplay.DisplayEnd.x) return FALSE;
+ if (ly0 >= PreviousPSXDisplay.DisplayEnd.y) return FALSE;
+ if (lx2 < PreviousPSXDisplay.DisplayPosition.x) return FALSE;
+ if (ly2 < PreviousPSXDisplay.DisplayPosition.y) return FALSE;
+
+ return TRUE;
+}
+
+////////////////////////////////////////////////////////////////////////
+
+BOOL bDrawOffscreenFront(void)
+{
+ if(sxmin < PSXDisplay.DisplayPosition.x) return FALSE; // must be complete in front
+ if(symin < PSXDisplay.DisplayPosition.y) return FALSE;
+ if(sxmax > PSXDisplay.DisplayEnd.x) return FALSE;
+ if(symax > PSXDisplay.DisplayEnd.y) return FALSE;
+ return TRUE;
+}
+
+BOOL bOnePointInFront(void)
+{
+ if(sxmax< PSXDisplay.DisplayPosition.x)
+ return FALSE;
+
+ if(symax< PSXDisplay.DisplayPosition.y)
+ return FALSE;
+
+ if(sxmin>=PSXDisplay.DisplayEnd.x)
+ return FALSE;
+
+ if(symin>=PSXDisplay.DisplayEnd.y)
+ return FALSE;
+
+ return TRUE;
+}
+
+
+BOOL bOnePointInBack(void)
+{
+ if(sxmax< PreviousPSXDisplay.DisplayPosition.x)
+ return FALSE;
+
+ if(symax< PreviousPSXDisplay.DisplayPosition.y)
+ return FALSE;
+
+ if(sxmin>=PreviousPSXDisplay.DisplayEnd.x)
+ return FALSE;
+
+ if(symin>=PreviousPSXDisplay.DisplayEnd.y)
+ return FALSE;
+
+ return TRUE;
+}
+
+BOOL bDrawOffscreen4(void)
+{
+ BOOL bFront;short sW,sH;
+
+ sxmax=max(lx0,max(lx1,max(lx2,lx3)));
+ if(sxmax<drawX) return FALSE;
+ sxmin=min(lx0,min(lx1,min(lx2,lx3)));
+ if(sxmin>drawW) return FALSE;
+ symax=max(ly0,max(ly1,max(ly2,ly3)));
+ if(symax<drawY) return FALSE;
+ symin=min(ly0,min(ly1,min(ly2,ly3)));
+ if(symin>drawH) return FALSE;
+
+ if(PSXDisplay.Disabled) return TRUE; // disabled? ever
+
+ if(iOffscreenDrawing==1) return bFullVRam;
+
+ if(dwActFixes&1 && iOffscreenDrawing==4)
+ {
+ if(PreviousPSXDisplay.DisplayPosition.x==PSXDisplay.DisplayPosition.x &&
+ PreviousPSXDisplay.DisplayPosition.y==PSXDisplay.DisplayPosition.y &&
+ PreviousPSXDisplay.DisplayEnd.x==PSXDisplay.DisplayEnd.x &&
+ PreviousPSXDisplay.DisplayEnd.y==PSXDisplay.DisplayEnd.y)
+ {
+ bRenderFrontBuffer=TRUE;
+ return FALSE;
+ }
+ }
+
+ sW=drawW-1;sH=drawH-1;
+
+ sxmin=min(sW,max(sxmin,drawX));
+ sxmax=max(drawX,min(sxmax,sW));
+ symin=min(sH,max(symin,drawY));
+ symax=max(drawY,min(symax,sH));
+
+ if(bOnePointInBack()) return bFullVRam;
+
+ if(iOffscreenDrawing==2)
+ bFront=bDrawOffscreenFront();
+ else bFront=bOnePointInFront();
+
+ if(bFront)
+ {
+ if(PSXDisplay.InterlacedTest) return bFullVRam; // -> ok, no need for adjust
+
+ vertex[0].x=lx0 - PSXDisplay.DisplayPosition.x+PreviousPSXDisplay.Range.x0;
+ vertex[1].x=lx1 - PSXDisplay.DisplayPosition.x+PreviousPSXDisplay.Range.x0;
+ vertex[2].x=lx2 - PSXDisplay.DisplayPosition.x+PreviousPSXDisplay.Range.x0;
+ vertex[3].x=lx3 - PSXDisplay.DisplayPosition.x+PreviousPSXDisplay.Range.x0;
+ vertex[0].y=ly0 - PSXDisplay.DisplayPosition.y+PreviousPSXDisplay.Range.y0;
+ vertex[1].y=ly1 - PSXDisplay.DisplayPosition.y+PreviousPSXDisplay.Range.y0;
+ vertex[2].y=ly2 - PSXDisplay.DisplayPosition.y+PreviousPSXDisplay.Range.y0;
+ vertex[3].y=ly3 - PSXDisplay.DisplayPosition.y+PreviousPSXDisplay.Range.y0;
+
+ if(iOffscreenDrawing==4 && !(dwActFixes&1)) // -> frontbuffer wanted
+ {
+ bRenderFrontBuffer=TRUE;
+ //return TRUE;
+ }
+ return bFullVRam; // -> but no od
+ }
+
+ return TRUE;
+}
+
+////////////////////////////////////////////////////////////////////////
+
+BOOL bDrawOffscreen3(void)
+{
+ BOOL bFront;short sW,sH;
+
+ sxmax=max(lx0,max(lx1,lx2));
+ if(sxmax<drawX) return FALSE;
+ sxmin=min(lx0,min(lx1,lx2));
+ if(sxmin>drawW) return FALSE;
+ symax=max(ly0,max(ly1,ly2));
+ if(symax<drawY) return FALSE;
+ symin=min(ly0,min(ly1,ly2));
+ if(symin>drawH) return FALSE;
+
+ if(PSXDisplay.Disabled) return TRUE; // disabled? ever
+
+ if(iOffscreenDrawing==1) return bFullVRam;
+
+ sW=drawW-1;sH=drawH-1;
+ sxmin=min(sW,max(sxmin,drawX));
+ sxmax=max(drawX,min(sxmax,sW));
+ symin=min(sH,max(symin,drawY));
+ symax=max(drawY,min(symax,sH));
+
+ if(bOnePointInBack()) return bFullVRam;
+
+ if(iOffscreenDrawing==2)
+ bFront=bDrawOffscreenFront();
+ else bFront=bOnePointInFront();
+
+ if(bFront)
+ {
+ if(PSXDisplay.InterlacedTest) return bFullVRam; // -> ok, no need for adjust
+
+ vertex[0].x=lx0 - PSXDisplay.DisplayPosition.x+PreviousPSXDisplay.Range.x0;
+ vertex[1].x=lx1 - PSXDisplay.DisplayPosition.x+PreviousPSXDisplay.Range.x0;
+ vertex[2].x=lx2 - PSXDisplay.DisplayPosition.x+PreviousPSXDisplay.Range.x0;
+ vertex[0].y=ly0 - PSXDisplay.DisplayPosition.y+PreviousPSXDisplay.Range.y0;
+ vertex[1].y=ly1 - PSXDisplay.DisplayPosition.y+PreviousPSXDisplay.Range.y0;
+ vertex[2].y=ly2 - PSXDisplay.DisplayPosition.y+PreviousPSXDisplay.Range.y0;
+
+ if(iOffscreenDrawing==4) // -> frontbuffer wanted
+ {
+ bRenderFrontBuffer=TRUE;
+ // return TRUE;
+ }
+
+ return bFullVRam; // -> but no od
+ }
+
+ return TRUE;
+}
+
+////////////////////////////////////////////////////////////////////////
+
+BOOL FastCheckAgainstScreen(short imageX0,short imageY0,short imageX1,short imageY1)
+{
+ PSXRect_t xUploadArea;
+
+ imageX1 += imageX0;
+ imageY1 += imageY0;
+
+ if (imageX0 < PreviousPSXDisplay.DisplayPosition.x)
+ xUploadArea.x0 = PreviousPSXDisplay.DisplayPosition.x;
+ else
+ if (imageX0 > PreviousPSXDisplay.DisplayEnd.x)
+ xUploadArea.x0 = PreviousPSXDisplay.DisplayEnd.x;
+ else
+ xUploadArea.x0 = imageX0;
+
+ if(imageX1 < PreviousPSXDisplay.DisplayPosition.x)
+ xUploadArea.x1 = PreviousPSXDisplay.DisplayPosition.x;
+ else
+ if (imageX1 > PreviousPSXDisplay.DisplayEnd.x)
+ xUploadArea.x1 = PreviousPSXDisplay.DisplayEnd.x;
+ else
+ xUploadArea.x1 = imageX1;
+
+ if (imageY0 < PreviousPSXDisplay.DisplayPosition.y)
+ xUploadArea.y0 = PreviousPSXDisplay.DisplayPosition.y;
+ else
+ if (imageY0 > PreviousPSXDisplay.DisplayEnd.y)
+ xUploadArea.y0 = PreviousPSXDisplay.DisplayEnd.y;
+ else
+ xUploadArea.y0 = imageY0;
+
+ if (imageY1 < PreviousPSXDisplay.DisplayPosition.y)
+ xUploadArea.y1 = PreviousPSXDisplay.DisplayPosition.y;
+ else
+ if (imageY1 > PreviousPSXDisplay.DisplayEnd.y)
+ xUploadArea.y1 = PreviousPSXDisplay.DisplayEnd.y;
+ else
+ xUploadArea.y1 = imageY1;
+
+ if ((xUploadArea.x0 != xUploadArea.x1) && (xUploadArea.y0 != xUploadArea.y1))
+ return TRUE;
+ else return FALSE;
+}
+
+BOOL CheckAgainstScreen(short imageX0,short imageY0,short imageX1,short imageY1)
+{
+ imageX1 += imageX0;
+ imageY1 += imageY0;
+
+ if (imageX0 < PreviousPSXDisplay.DisplayPosition.x)
+ xrUploadArea.x0 = PreviousPSXDisplay.DisplayPosition.x;
+ else
+ if (imageX0 > PreviousPSXDisplay.DisplayEnd.x)
+ xrUploadArea.x0 = PreviousPSXDisplay.DisplayEnd.x;
+ else
+ xrUploadArea.x0 = imageX0;
+
+ if(imageX1 < PreviousPSXDisplay.DisplayPosition.x)
+ xrUploadArea.x1 = PreviousPSXDisplay.DisplayPosition.x;
+ else
+ if (imageX1 > PreviousPSXDisplay.DisplayEnd.x)
+ xrUploadArea.x1 = PreviousPSXDisplay.DisplayEnd.x;
+ else
+ xrUploadArea.x1 = imageX1;
+
+ if (imageY0 < PreviousPSXDisplay.DisplayPosition.y)
+ xrUploadArea.y0 = PreviousPSXDisplay.DisplayPosition.y;
+ else
+ if (imageY0 > PreviousPSXDisplay.DisplayEnd.y)
+ xrUploadArea.y0 = PreviousPSXDisplay.DisplayEnd.y;
+ else
+ xrUploadArea.y0 = imageY0;
+
+ if (imageY1 < PreviousPSXDisplay.DisplayPosition.y)
+ xrUploadArea.y1 = PreviousPSXDisplay.DisplayPosition.y;
+ else
+ if (imageY1 > PreviousPSXDisplay.DisplayEnd.y)
+ xrUploadArea.y1 = PreviousPSXDisplay.DisplayEnd.y;
+ else
+ xrUploadArea.y1 = imageY1;
+
+ if ((xrUploadArea.x0 != xrUploadArea.x1) && (xrUploadArea.y0 != xrUploadArea.y1))
+ return TRUE;
+ else return FALSE;
+}
+
+BOOL FastCheckAgainstFrontScreen(short imageX0,short imageY0,short imageX1,short imageY1)
+{
+ PSXRect_t xUploadArea;
+
+ imageX1 += imageX0;
+ imageY1 += imageY0;
+
+ if (imageX0 < PSXDisplay.DisplayPosition.x)
+ xUploadArea.x0 = PSXDisplay.DisplayPosition.x;
+ else
+ if (imageX0 > PSXDisplay.DisplayEnd.x)
+ xUploadArea.x0 = PSXDisplay.DisplayEnd.x;
+ else
+ xUploadArea.x0 = imageX0;
+
+ if(imageX1 < PSXDisplay.DisplayPosition.x)
+ xUploadArea.x1 = PSXDisplay.DisplayPosition.x;
+ else
+ if (imageX1 > PSXDisplay.DisplayEnd.x)
+ xUploadArea.x1 = PSXDisplay.DisplayEnd.x;
+ else
+ xUploadArea.x1 = imageX1;
+
+ if (imageY0 < PSXDisplay.DisplayPosition.y)
+ xUploadArea.y0 = PSXDisplay.DisplayPosition.y;
+ else
+ if (imageY0 > PSXDisplay.DisplayEnd.y)
+ xUploadArea.y0 = PSXDisplay.DisplayEnd.y;
+ else
+ xUploadArea.y0 = imageY0;
+
+ if (imageY1 < PSXDisplay.DisplayPosition.y)
+ xUploadArea.y1 = PSXDisplay.DisplayPosition.y;
+ else
+ if (imageY1 > PSXDisplay.DisplayEnd.y)
+ xUploadArea.y1 = PSXDisplay.DisplayEnd.y;
+ else
+ xUploadArea.y1 = imageY1;
+
+ if ((xUploadArea.x0 != xUploadArea.x1) && (xUploadArea.y0 != xUploadArea.y1))
+ return TRUE;
+ else return FALSE;
+}
+
+BOOL CheckAgainstFrontScreen(short imageX0,short imageY0,short imageX1,short imageY1)
+{
+ imageX1 += imageX0;
+ imageY1 += imageY0;
+
+ if (imageX0 < PSXDisplay.DisplayPosition.x)
+ xrUploadArea.x0 = PSXDisplay.DisplayPosition.x;
+ else
+ if (imageX0 > PSXDisplay.DisplayEnd.x)
+ xrUploadArea.x0 = PSXDisplay.DisplayEnd.x;
+ else
+ xrUploadArea.x0 = imageX0;
+
+ if(imageX1 < PSXDisplay.DisplayPosition.x)
+ xrUploadArea.x1 = PSXDisplay.DisplayPosition.x;
+ else
+ if (imageX1 > PSXDisplay.DisplayEnd.x)
+ xrUploadArea.x1 = PSXDisplay.DisplayEnd.x;
+ else
+ xrUploadArea.x1 = imageX1;
+
+ if (imageY0 < PSXDisplay.DisplayPosition.y)
+ xrUploadArea.y0 = PSXDisplay.DisplayPosition.y;
+ else
+ if (imageY0 > PSXDisplay.DisplayEnd.y)
+ xrUploadArea.y0 = PSXDisplay.DisplayEnd.y;
+ else
+ xrUploadArea.y0 = imageY0;
+
+ if (imageY1 < PSXDisplay.DisplayPosition.y)
+ xrUploadArea.y1 = PSXDisplay.DisplayPosition.y;
+ else
+ if (imageY1 > PSXDisplay.DisplayEnd.y)
+ xrUploadArea.y1 = PSXDisplay.DisplayEnd.y;
+ else
+ xrUploadArea.y1 = imageY1;
+
+ if ((xrUploadArea.x0 != xrUploadArea.x1) && (xrUploadArea.y0 != xrUploadArea.y1))
+ return TRUE;
+ else return FALSE;
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void PrepareFullScreenUpload (int Position)
+{
+ if (Position==-1) // rgb24
+ {
+ if(PSXDisplay.Interlaced)
+ {
+ xrUploadArea.x0 = PSXDisplay.DisplayPosition.x;
+ xrUploadArea.x1 = PSXDisplay.DisplayEnd.x;
+ xrUploadArea.y0 = PSXDisplay.DisplayPosition.y;
+ xrUploadArea.y1 = PSXDisplay.DisplayEnd.y;
+ }
+ else
+ {
+ xrUploadArea.x0 = PreviousPSXDisplay.DisplayPosition.x;
+ xrUploadArea.x1 = PreviousPSXDisplay.DisplayEnd.x;
+ xrUploadArea.y0 = PreviousPSXDisplay.DisplayPosition.y;
+ xrUploadArea.y1 = PreviousPSXDisplay.DisplayEnd.y;
+ }
+
+ if(bNeedRGB24Update)
+ {
+ if(lClearOnSwap)
+ {
+// lClearOnSwap=0;
+ }
+ else
+ if(PSXDisplay.Interlaced && PreviousPSXDisplay.RGB24<2) // in interlaced mode we upload at least two full frames (GT1 menu)
+ {
+ PreviousPSXDisplay.RGB24++;
+ }
+ else
+ {
+ xrUploadArea.y1 = min(xrUploadArea.y0+xrUploadAreaRGB24.y1,xrUploadArea.y1);
+ xrUploadArea.y0+=xrUploadAreaRGB24.y0;
+ }
+ }
+ }
+ else
+ if (Position)
+ {
+ xrUploadArea.x0 = PSXDisplay.DisplayPosition.x;
+ xrUploadArea.x1 = PSXDisplay.DisplayEnd.x;
+ xrUploadArea.y0 = PSXDisplay.DisplayPosition.y;
+ xrUploadArea.y1 = PSXDisplay.DisplayEnd.y;
+ }
+ else
+ {
+ xrUploadArea.x0 = PreviousPSXDisplay.DisplayPosition.x;
+ xrUploadArea.x1 = PreviousPSXDisplay.DisplayEnd.x;
+ xrUploadArea.y0 = PreviousPSXDisplay.DisplayPosition.y;
+ xrUploadArea.y1 = PreviousPSXDisplay.DisplayEnd.y;
+ }
+
+ if (xrUploadArea.x0 < 0) xrUploadArea.x0 = 0;
+ else
+ if (xrUploadArea.x0 > 1023) xrUploadArea.x0 = 1023;
+
+ if (xrUploadArea.x1 < 0) xrUploadArea.x1 = 0;
+ else
+ if (xrUploadArea.x1 > 1024) xrUploadArea.x1 = 1024;
+
+ if (xrUploadArea.y0 < 0) xrUploadArea.y0 = 0;
+ else
+ if (xrUploadArea.y0 > iGPUHeightMask) xrUploadArea.y0 = iGPUHeightMask;
+
+ if (xrUploadArea.y1 < 0) xrUploadArea.y1 = 0;
+ else
+ if (xrUploadArea.y1 > iGPUHeight) xrUploadArea.y1 = iGPUHeight;
+
+ if (PSXDisplay.RGB24)
+ {
+ InvalidateTextureArea(xrUploadArea.x0,xrUploadArea.y0,xrUploadArea.x1-xrUploadArea.x0,xrUploadArea.y1-xrUploadArea.y0);
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+// Upload screen (MDEC and such)
+////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////
+
+unsigned char * LoadDirectMovieFast(void);
+
+void UploadScreenEx(int Position)
+{
+ short ya,yb,xa,xb,x, y, YStep, XStep, U, UStep,ux[4],vy[4];
+
+ if(!PSXDisplay.DisplayMode.x) return;
+ if(!PSXDisplay.DisplayMode.y) return;
+
+ glDisable(GL_SCISSOR_TEST);
+ glShadeModel(GL_FLAT);
+ bOldSmoothShaded=FALSE;
+ glDisable(GL_BLEND);
+ bBlendEnable=FALSE;
+ glDisable(GL_TEXTURE_2D);
+ bTexEnabled=FALSE;
+ glDisable(GL_ALPHA_TEST);
+
+ glPixelZoom(((float)rRatioRect.right)/((float)PSXDisplay.DisplayMode.x),
+ -1.0f*(((float)rRatioRect.bottom)/((float)PSXDisplay.DisplayMode.y)));
+
+ //----------------------------------------------------//
+
+ YStep = 256; // max texture size
+ XStep = 256;
+ UStep = (PSXDisplay.RGB24 ? 128 : 0);
+ ya = xrUploadArea.y0;
+ yb = xrUploadArea.y1;
+ xa = xrUploadArea.x0;
+ xb = xrUploadArea.x1;
+
+ for(y=ya;y<=yb;y+=YStep) // loop y
+ {
+ U = 0;
+ for(x=xa;x<=xb;x+=XStep) // loop x
+ {
+ ly0 = ly1 = y; // -> get y coords
+ ly2 = y + YStep;
+ if (ly2 > yb) ly2 = yb;
+ ly3 = ly2;
+
+ lx0 = lx3 = x; // -> get x coords
+ lx1 = x + XStep;
+ if (lx1 > xb) lx1 = xb;
+
+ lx2 = lx1;
+
+ ux[0]=ux[3]=(xa - x); // -> set tex x coords
+ if (ux[0] < 0) ux[0]=ux[3]=0;
+ ux[2]=ux[1]=(xb - x);
+ if (ux[2] > 256) ux[2]=ux[1]=256;
+
+ vy[0]=vy[1]=(ya - y); // -> set tex y coords
+ if (vy[0] < 0) vy[0]=vy[1]=0;
+ vy[2]=vy[3]=(yb - y);
+ if (vy[2] > 256) vy[2]=vy[3]=256;
+
+ if ((ux[0] >= ux[2]) || // -> cheaters never win...
+ (vy[0] >= vy[2])) continue; // (but winners always cheat...)
+
+ xrMovieArea.x0=lx0+U; xrMovieArea.y0=ly0;
+ xrMovieArea.x1=lx2+U; xrMovieArea.y1=ly2;
+
+ offsetScreenUpload(Position);
+
+ glRasterPos2f(vertex[0].x,vertex[0].y);
+
+ glDrawPixels(xrMovieArea.x1-xrMovieArea.x0,
+ xrMovieArea.y1-xrMovieArea.y0,
+ GL_RGBA,GL_UNSIGNED_BYTE,
+ LoadDirectMovieFast());
+
+ U+=UStep;
+ }
+ }
+
+ //----------------------------------------------------//
+
+ glPixelZoom(1.0F,1.0F);
+
+ glEnable(GL_ALPHA_TEST);
+ glEnable(GL_SCISSOR_TEST);
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void UploadScreen(int Position)
+{
+ short x, y, YStep, XStep, U, s, UStep,ux[4],vy[4];
+ short xa,xb,ya,yb;
+
+ if(xrUploadArea.x0>1023) xrUploadArea.x0=1023;
+ if(xrUploadArea.x1>1024) xrUploadArea.x1=1024;
+ if(xrUploadArea.y0>iGPUHeightMask) xrUploadArea.y0=iGPUHeightMask;
+ if(xrUploadArea.y1>iGPUHeight) xrUploadArea.y1=iGPUHeight;
+
+ if(xrUploadArea.x0==xrUploadArea.x1) return;
+ if(xrUploadArea.y0==xrUploadArea.y1) return;
+
+ if(PSXDisplay.Disabled && iOffscreenDrawing<4) return;
+
+ iDrawnSomething = 2;
+ iLastRGB24=PSXDisplay.RGB24+1;
+
+ if(bSkipNextFrame) return;
+
+ if(dwActFixes & 2) {UploadScreenEx(Position);return;}
+
+ bUsingMovie = TRUE;
+ bDrawTextured = TRUE; // just doing textures
+ bDrawSmoothShaded = FALSE;
+
+ if(bGLBlend) vertex[0].c.lcol=0xff7f7f7f; // set solid col
+ else vertex[0].c.lcol=0xffffffff;
+ SETCOL(vertex[0]);
+
+ SetOGLDisplaySettings(0);
+
+ YStep = 256; // max texture size
+ XStep = 256;
+
+ UStep = (PSXDisplay.RGB24 ? 128 : 0);
+
+ ya=xrUploadArea.y0;
+ yb=xrUploadArea.y1;
+ xa=xrUploadArea.x0;
+ xb=xrUploadArea.x1;
+
+ for(y=ya;y<=yb;y+=YStep) // loop y
+ {
+ U = 0;
+ for(x=xa;x<=xb;x+=XStep) // loop x
+ {
+ ly0 = ly1 = y; // -> get y coords
+ ly2 = y + YStep;
+ if (ly2 > yb) ly2 = yb;
+ ly3 = ly2;
+
+ lx0 = lx3 = x; // -> get x coords
+ lx1 = x + XStep;
+ if (lx1 > xb) lx1 = xb;
+
+ lx2 = lx1;
+
+ ux[0]=ux[3]=(xa - x); // -> set tex x coords
+ if (ux[0] < 0) ux[0]=ux[3]=0;
+ ux[2]=ux[1]=(xb - x);
+ if (ux[2] > 256) ux[2]=ux[1]=256;
+
+ vy[0]=vy[1]=(ya - y); // -> set tex y coords
+ if (vy[0] < 0) vy[0]=vy[1]=0;
+ vy[2]=vy[3]=(yb - y);
+ if (vy[2] > 256) vy[2]=vy[3]=256;
+
+ if ((ux[0] >= ux[2]) || // -> cheaters never win...
+ (vy[0] >= vy[2])) continue; // (but winners always cheat...)
+
+ xrMovieArea.x0=lx0+U; xrMovieArea.y0=ly0;
+ xrMovieArea.x1=lx2+U; xrMovieArea.y1=ly2;
+
+ s=ux[2] - ux[0]; if(s>255) s=255;
+
+ gl_ux[2] = gl_ux[1] = s;
+ s=vy[2] - vy[0]; if(s>255) s=255;
+ gl_vy[2] = gl_vy[3] = s;
+ gl_ux[0] = gl_ux[3] = gl_vy[0] = gl_vy[1] = 0;
+
+ SetRenderState((uint32_t)0x01000000);
+ SetRenderMode((uint32_t)0x01000000, FALSE); // upload texture data
+ offsetScreenUpload(Position);
+ assignTextureVRAMWrite();
+
+ PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);
+
+ U+=UStep;
+ }
+ }
+
+ bUsingMovie=FALSE; // done...
+ bDisplayNotSet = TRUE;
+}
+
+////////////////////////////////////////////////////////////////////////
+// Detect next screen
+////////////////////////////////////////////////////////////////////////
+
+BOOL IsCompleteInsideNextScreen(short x, short y, short xoff, short yoff)
+{
+ if (x > PSXDisplay.DisplayPosition.x+1) return FALSE;
+ if ((x + xoff) < PSXDisplay.DisplayEnd.x-1) return FALSE;
+ yoff+=y;
+ if (y >= PSXDisplay.DisplayPosition.y &&
+ y <= PSXDisplay.DisplayEnd.y )
+ {
+ if ((yoff) >= PSXDisplay.DisplayPosition.y &&
+ (yoff) <= PSXDisplay.DisplayEnd.y ) return TRUE;
+ }
+ if (y > PSXDisplay.DisplayPosition.y+1) return FALSE;
+ if (yoff < PSXDisplay.DisplayEnd.y-1) return FALSE;
+ return TRUE;
+}
+
+BOOL IsPrimCompleteInsideNextScreen(short x, short y, short xoff, short yoff)
+{
+ x+=PSXDisplay.DrawOffset.x;
+ if (x > PSXDisplay.DisplayPosition.x+1) return FALSE;
+ y+=PSXDisplay.DrawOffset.y;
+ if (y > PSXDisplay.DisplayPosition.y+1) return FALSE;
+ xoff+=PSXDisplay.DrawOffset.x;
+ if (xoff < PSXDisplay.DisplayEnd.x-1) return FALSE;
+ yoff+=PSXDisplay.DrawOffset.y;
+ if (yoff < PSXDisplay.DisplayEnd.y-1) return FALSE;
+ return TRUE;
+}
+
+BOOL IsInsideNextScreen(short x, short y, short xoff, short yoff)
+{
+ if (x > PSXDisplay.DisplayEnd.x) return FALSE;
+ if (y > PSXDisplay.DisplayEnd.y) return FALSE;
+ if ((x + xoff) < PSXDisplay.DisplayPosition.x) return FALSE;
+ if ((y + yoff) < PSXDisplay.DisplayPosition.y) return FALSE;
+ return TRUE;
+}
+
+////////////////////////////////////////////////////////////////////////
+// mask stuff...
+////////////////////////////////////////////////////////////////////////
+
+//Mask1 Set mask bit while drawing. 1 = on
+//Mask2 Do not draw to mask areas. 1= on
+
+void cmdSTP(unsigned char * baseAddr)
+{
+ uint32_t gdata = ((uint32_t*)baseAddr)[0];
+
+ STATUSREG&=~0x1800; // clear the necessary bits
+ STATUSREG|=((gdata & 0x03) << 11); // set the current bits
+
+ if(!iUseMask) return;
+
+ if(gdata&1) {sSetMask=0x8000;lSetMask=0x80008000;iSetMask=1;}
+ else {sSetMask=0; lSetMask=0; iSetMask=0;}
+
+ if(gdata&2)
+ {
+ if(!(gdata&1)) iSetMask=2;
+ bCheckMask=TRUE;
+ if(iDepthFunc==0) return;
+ iDepthFunc=0;
+ glDepthFunc(GL_LESS);
+ }
+ else
+ {
+ bCheckMask=FALSE;
+ if(iDepthFunc==1) return;
+ glDepthFunc(GL_ALWAYS);
+ iDepthFunc=1;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+// cmd: Set texture page infos
+////////////////////////////////////////////////////////////////////////
+
+void cmdTexturePage(unsigned char * baseAddr)
+{
+ uint32_t gdata = ((uint32_t *)baseAddr)[0];
+ UpdateGlobalTP((unsigned short)gdata);
+ GlobalTextREST = (gdata&0x00ffffff)>>9;
+}
+
+////////////////////////////////////////////////////////////////////////
+// cmd: turn on/off texture window
+////////////////////////////////////////////////////////////////////////
+
+void cmdTextureWindow(unsigned char *baseAddr)
+{
+ uint32_t gdata = ((uint32_t *)baseAddr)[0];
+ uint32_t YAlign,XAlign;
+
+ ulGPUInfoVals[INFO_TW]=gdata&0xFFFFF;
+
+ if(gdata & 0x020)
+ TWin.Position.y1 = 8; // xxxx1
+ else if (gdata & 0x040)
+ TWin.Position.y1 = 16; // xxx10
+ else if (gdata & 0x080)
+ TWin.Position.y1 = 32; // xx100
+ else if (gdata & 0x100)
+ TWin.Position.y1 = 64; // x1000
+ else if (gdata & 0x200)
+ TWin.Position.y1 = 128; // 10000
+ else
+ TWin.Position.y1 = 256; // 00000
+
+ // Texture window size is determined by the least bit set of the relevant 5 bits
+
+ if (gdata & 0x001)
+ TWin.Position.x1 = 8; // xxxx1
+ else if (gdata & 0x002)
+ TWin.Position.x1 = 16; // xxx10
+ else if (gdata & 0x004)
+ TWin.Position.x1 = 32; // xx100
+ else if (gdata & 0x008)
+ TWin.Position.x1 = 64; // x1000
+ else if (gdata & 0x010)
+ TWin.Position.x1 = 128; // 10000
+ else
+ TWin.Position.x1 = 256; // 00000
+
+ // Re-calculate the bit field, because we can't trust what is passed in the data
+
+ YAlign = (uint32_t)(32 - (TWin.Position.y1 >> 3));
+ XAlign = (uint32_t)(32 - (TWin.Position.x1 >> 3));
+
+ // Absolute position of the start of the texture window
+
+ TWin.Position.y0 = (short)(((gdata >> 15) & YAlign) << 3);
+ TWin.Position.x0 = (short)(((gdata >> 10) & XAlign) << 3);
+
+ if((TWin.Position.x0 == 0 && // tw turned off
+ TWin.Position.y0 == 0 &&
+ TWin.Position.x1 == 0 &&
+ TWin.Position.y1 == 0) ||
+ (TWin.Position.x1 == 256 &&
+ TWin.Position.y1 == 256))
+ {
+ bUsingTWin = FALSE; // -> just do it
+
+#ifdef OWNSCALE
+ TWin.UScaleFactor = 1.0f;
+ TWin.VScaleFactor = 1.0f;
+#else
+ TWin.UScaleFactor =
+ TWin.VScaleFactor = 1.0f/256.0f;
+#endif
+ }
+ else // tw turned on
+ {
+ bUsingTWin = TRUE;
+
+ TWin.OPosition.y1 = TWin.Position.y1; // -> get psx sizes
+ TWin.OPosition.x1 = TWin.Position.x1;
+
+ if(TWin.Position.x1<=2) TWin.Position.x1=2; // -> set OGL sizes
+ else
+ if(TWin.Position.x1<=4) TWin.Position.x1=4;
+ else
+ if(TWin.Position.x1<=8) TWin.Position.x1=8;
+ else
+ if(TWin.Position.x1<=16) TWin.Position.x1=16;
+ else
+ if(TWin.Position.x1<=32) TWin.Position.x1=32;
+ else
+ if(TWin.Position.x1<=64) TWin.Position.x1=64;
+ else
+ if(TWin.Position.x1<=128) TWin.Position.x1=128;
+ else
+ if(TWin.Position.x1<=256) TWin.Position.x1=256;
+
+ if(TWin.Position.y1<=2) TWin.Position.y1=2;
+ else
+ if(TWin.Position.y1<=4) TWin.Position.y1=4;
+ else
+ if(TWin.Position.y1<=8) TWin.Position.y1=8;
+ else
+ if(TWin.Position.y1<=16) TWin.Position.y1=16;
+ else
+ if(TWin.Position.y1<=32) TWin.Position.y1=32;
+ else
+ if(TWin.Position.y1<=64) TWin.Position.y1=64;
+ else
+ if(TWin.Position.y1<=128) TWin.Position.y1=128;
+ else
+ if(TWin.Position.y1<=256) TWin.Position.y1=256;
+
+#ifdef OWNSCALE
+ TWin.UScaleFactor = (float)TWin.Position.x1;
+ TWin.VScaleFactor = (float)TWin.Position.y1;
+#else
+ TWin.UScaleFactor = ((float)TWin.Position.x1)/256.0f; // -> set scale factor
+ TWin.VScaleFactor = ((float)TWin.Position.y1)/256.0f;
+#endif
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+// mmm, Lewpy uses that in TileS ... I don't ;)
+////////////////////////////////////////////////////////////////////////
+
+/*
+void ClampToPSXDrawAreaOffset(short *x0, short *y0, short *x1, short *y1)
+{
+ if (*x0 < PSXDisplay.DrawArea.x0)
+ {
+ *x1 -= (PSXDisplay.DrawArea.x0 - *x0);
+ *x0 = PSXDisplay.DrawArea.x0;
+ }
+ else
+ if (*x0 > PSXDisplay.DrawArea.x1)
+ {
+ *x0 = PSXDisplay.DrawArea.x1;
+ *x1 = 0;
+ }
+
+ if (*y0 < PSXDisplay.DrawArea.y0)
+ {
+ *y1 -= (PSXDisplay.DrawArea.y0 - *y0);
+ *y0 = PSXDisplay.DrawArea.y0;
+ }
+ else
+ if (*y0 > PSXDisplay.DrawArea.y1)
+ {
+ *y0 = PSXDisplay.DrawArea.y1;
+ *y1 = 0;
+ }
+
+ if (*x1 < 0) *x1 = 0;
+
+ if ((*x1 + *x0) > PSXDisplay.DrawArea.x1)
+ *x1 = (PSXDisplay.DrawArea.x1 - *x0 + 1);
+
+ if (*y1 < 0) *y1 = 0;
+
+ if ((*y1 + *y0) > PSXDisplay.DrawArea.y1)
+ *y1 = (PSXDisplay.DrawArea.y1 - *y0 + 1);
+}
+*/
+
+////////////////////////////////////////////////////////////////////////
+// Check draw area dimensions
+////////////////////////////////////////////////////////////////////////
+
+void ClampToPSXScreen(short *x0, short *y0, short *x1, short *y1)
+{
+ if (*x0 < 0) *x0 = 0;
+ else
+ if (*x0 > 1023) *x0 = 1023;
+
+ if (*x1 < 0) *x1 = 0;
+ else
+ if (*x1 > 1023) *x1 = 1023;
+
+ if (*y0 < 0) *y0 = 0;
+ else
+ if (*y0 > iGPUHeightMask) *y0 = iGPUHeightMask;
+
+ if (*y1 < 0) *y1 = 0;
+ else
+ if (*y1 > iGPUHeightMask) *y1 = iGPUHeightMask;
+}
+
+////////////////////////////////////////////////////////////////////////
+// Used in Load Image and Blk Fill
+////////////////////////////////////////////////////////////////////////
+
+void ClampToPSXScreenOffset(short *x0, short *y0, short *x1, short *y1)
+{
+ if (*x0 < 0)
+ { *x1 += *x0; *x0 = 0; }
+ else
+ if (*x0 > 1023)
+ { *x0 = 1023; *x1 = 0; }
+
+ if (*y0 < 0)
+ { *y1 += *y0; *y0 = 0; }
+ else
+ if (*y0 > iGPUHeightMask)
+ { *y0 = iGPUHeightMask; *y1 = 0; }
+
+ if (*x1 < 0) *x1 = 0;
+
+ if ((*x1 + *x0) > 1024) *x1 = (1024 - *x0);
+
+ if (*y1 < 0) *y1 = 0;
+
+ if ((*y1 + *y0) > iGPUHeight) *y1 = (iGPUHeight - *y0);
+}
+
+////////////////////////////////////////////////////////////////////////
+// cmd: start of drawing area... primitives will be clipped inside
+////////////////////////////////////////////////////////////////////////
+
+void cmdDrawAreaStart(unsigned char * baseAddr)
+{
+ uint32_t gdata = ((uint32_t *)baseAddr)[0];
+
+ drawX = gdata & 0x3ff; // for soft drawing
+ if(drawX>=1024) drawX=1023;
+
+ if(dwGPUVersion==2)
+ {
+ ulGPUInfoVals[INFO_DRAWSTART]=gdata&0x3FFFFF;
+ drawY = (gdata>>12)&0x3ff;
+ }
+ else
+ {
+ ulGPUInfoVals[INFO_DRAWSTART]=gdata&0xFFFFF;
+ drawY = (gdata>>10)&0x3ff;
+ }
+
+ if(drawY>=iGPUHeight) drawY=iGPUHeightMask;
+
+ PreviousPSXDisplay.DrawArea.y0=PSXDisplay.DrawArea.y0;
+ PreviousPSXDisplay.DrawArea.x0=PSXDisplay.DrawArea.x0;
+
+ PSXDisplay.DrawArea.y0 = (short)drawY; // for OGL drawing
+ PSXDisplay.DrawArea.x0 = (short)drawX;
+}
+
+////////////////////////////////////////////////////////////////////////
+// cmd: end of drawing area... primitives will be clipped inside
+////////////////////////////////////////////////////////////////////////
+
+void cmdDrawAreaEnd(unsigned char * baseAddr)
+{
+ uint32_t gdata = ((uint32_t *)baseAddr)[0];
+
+ drawW = gdata & 0x3ff; // for soft drawing
+ if(drawW>=1024) drawW=1023;
+
+ if(dwGPUVersion==2)
+ {
+ ulGPUInfoVals[INFO_DRAWEND]=gdata&0x3FFFFF;
+ drawH = (gdata>>12)&0x3ff;
+ }
+ else
+ {
+ ulGPUInfoVals[INFO_DRAWEND]=gdata&0xFFFFF;
+ drawH = (gdata>>10)&0x3ff;
+ }
+
+ if(drawH>=iGPUHeight) drawH=iGPUHeightMask;
+
+ PSXDisplay.DrawArea.y1 = (short)drawH; // for OGL drawing
+ PSXDisplay.DrawArea.x1 = (short)drawW;
+
+ ClampToPSXScreen(&PSXDisplay.DrawArea.x0, // clamp
+ &PSXDisplay.DrawArea.y0,
+ &PSXDisplay.DrawArea.x1,
+ &PSXDisplay.DrawArea.y1);
+
+ bDisplayNotSet = TRUE;
+}
+
+////////////////////////////////////////////////////////////////////////
+// cmd: draw offset... will be added to prim coords
+////////////////////////////////////////////////////////////////////////
+
+void cmdDrawOffset(unsigned char * baseAddr)
+{
+ uint32_t gdata = ((uint32_t *)baseAddr)[0];
+
+ PreviousPSXDisplay.DrawOffset.x =
+ PSXDisplay.DrawOffset.x = (short)(gdata & 0x7ff);
+
+ if (dwGPUVersion == 2)
+ {
+ ulGPUInfoVals[INFO_DRAWOFF] = gdata&0x7FFFFF;
+ PSXDisplay.DrawOffset.y = (short)((gdata>>12) & 0x7ff);
+ }
+ else
+ {
+ ulGPUInfoVals[INFO_DRAWOFF]=gdata&0x3FFFFF;
+ PSXDisplay.DrawOffset.y = (short)((gdata>>11) & 0x7ff);
+ }
+
+ PSXDisplay.DrawOffset.x=(short)(((int)PSXDisplay.DrawOffset.x<<21)>>21);
+ PSXDisplay.DrawOffset.y=(short)(((int)PSXDisplay.DrawOffset.y<<21)>>21);
+
+ PSXDisplay.CumulOffset.x = // new OGL prim offsets
+ PSXDisplay.DrawOffset.x - PSXDisplay.GDrawOffset.x + PreviousPSXDisplay.Range.x0;
+ PSXDisplay.CumulOffset.y =
+ PSXDisplay.DrawOffset.y - PSXDisplay.GDrawOffset.y + PreviousPSXDisplay.Range.y0;
+}
+
+////////////////////////////////////////////////////////////////////////
+// cmd: load image to vram
+////////////////////////////////////////////////////////////////////////
+
+void primLoadImage(unsigned char * baseAddr)
+{
+ unsigned short *sgpuData = ((unsigned short *) baseAddr);
+
+ VRAMWrite.x = sgpuData[2]&0x03ff;
+ VRAMWrite.y = sgpuData[3]&iGPUHeightMask;
+ VRAMWrite.Width = sgpuData[4];
+ VRAMWrite.Height = sgpuData[5];
+
+ iDataWriteMode = DR_VRAMTRANSFER;
+ VRAMWrite.ImagePtr = psxVuw + (VRAMWrite.y<<10) + VRAMWrite.x;
+ VRAMWrite.RowsRemaining = VRAMWrite.Width;
+ VRAMWrite.ColsRemaining = VRAMWrite.Height;
+
+ bNeedWriteUpload=TRUE;
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void PrepareRGB24Upload(void)
+{
+ VRAMWrite.x=(VRAMWrite.x*2)/3;
+ VRAMWrite.Width=(VRAMWrite.Width*2)/3;
+
+ if(!PSXDisplay.InterlacedTest && // NEW
+ CheckAgainstScreen(VRAMWrite.x, VRAMWrite.y, VRAMWrite.Width, VRAMWrite.Height))
+ {
+ xrUploadArea.x0-=PreviousPSXDisplay.DisplayPosition.x;
+ xrUploadArea.x1-=PreviousPSXDisplay.DisplayPosition.x;
+ xrUploadArea.y0-=PreviousPSXDisplay.DisplayPosition.y;
+ xrUploadArea.y1-=PreviousPSXDisplay.DisplayPosition.y;
+ }
+ else
+ if(CheckAgainstFrontScreen(VRAMWrite.x, VRAMWrite.y, VRAMWrite.Width, VRAMWrite.Height))
+ {
+ xrUploadArea.x0-=PSXDisplay.DisplayPosition.x;
+ xrUploadArea.x1-=PSXDisplay.DisplayPosition.x;
+ xrUploadArea.y0-=PSXDisplay.DisplayPosition.y;
+ xrUploadArea.y1-=PSXDisplay.DisplayPosition.y;
+ }
+ else return;
+
+ if(bRenderFrontBuffer)
+ {
+ updateFrontDisplay();
+ }
+
+ if(bNeedRGB24Update==FALSE)
+ {
+ xrUploadAreaRGB24=xrUploadArea;
+ bNeedRGB24Update=TRUE;
+ }
+ else
+ {
+ xrUploadAreaRGB24.x0=min(xrUploadAreaRGB24.x0,xrUploadArea.x0);
+ xrUploadAreaRGB24.x1=max(xrUploadAreaRGB24.x1,xrUploadArea.x1);
+ xrUploadAreaRGB24.y0=min(xrUploadAreaRGB24.y0,xrUploadArea.y0);
+ xrUploadAreaRGB24.y1=max(xrUploadAreaRGB24.y1,xrUploadArea.y1);
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void CheckWriteUpdate()
+{
+ int iX=0,iY=0;
+
+ if(VRAMWrite.Width) iX=1;
+ if(VRAMWrite.Height) iY=1;
+
+ InvalidateTextureArea(VRAMWrite.x, VRAMWrite.y, VRAMWrite.Width-iX, VRAMWrite.Height-iY);
+
+ if(PSXDisplay.Interlaced && !iOffscreenDrawing) return;
+
+ if(PSXDisplay.RGB24) {PrepareRGB24Upload();return;}
+
+ if(!PSXDisplay.InterlacedTest &&
+ CheckAgainstScreen(VRAMWrite.x, VRAMWrite.y, VRAMWrite.Width, VRAMWrite.Height))
+ {
+ if(dwActFixes&0x800) return;
+
+ if(bRenderFrontBuffer)
+ {
+ updateFrontDisplay();
+ }
+
+ UploadScreen(FALSE);
+
+ bNeedUploadTest=TRUE;
+ }
+ else
+ if(iOffscreenDrawing)
+ {
+ if (CheckAgainstFrontScreen(VRAMWrite.x, VRAMWrite.y, VRAMWrite.Width, VRAMWrite.Height))
+ {
+ if(PSXDisplay.InterlacedTest)
+ {
+ if(PreviousPSXDisplay.InterlacedNew)
+ {
+ PreviousPSXDisplay.InterlacedNew=FALSE;
+ bNeedInterlaceUpdate=TRUE;
+ xrUploadAreaIL.x0=PSXDisplay.DisplayPosition.x;
+ xrUploadAreaIL.y0=PSXDisplay.DisplayPosition.y;
+ xrUploadAreaIL.x1=PSXDisplay.DisplayPosition.x+PSXDisplay.DisplayModeNew.x;
+ xrUploadAreaIL.y1=PSXDisplay.DisplayPosition.y+PSXDisplay.DisplayModeNew.y;
+ if(xrUploadAreaIL.x1>1023) xrUploadAreaIL.x1=1023;
+ if(xrUploadAreaIL.y1>511) xrUploadAreaIL.y1=511;
+ }
+
+ if(bNeedInterlaceUpdate==FALSE)
+ {
+ xrUploadAreaIL=xrUploadArea;
+ bNeedInterlaceUpdate=TRUE;
+ }
+ else
+ {
+ xrUploadAreaIL.x0=min(xrUploadAreaIL.x0,xrUploadArea.x0);
+ xrUploadAreaIL.x1=max(xrUploadAreaIL.x1,xrUploadArea.x1);
+ xrUploadAreaIL.y0=min(xrUploadAreaIL.y0,xrUploadArea.y0);
+ xrUploadAreaIL.y1=max(xrUploadAreaIL.y1,xrUploadArea.y1);
+ }
+ return;
+ }
+
+ if(!bNeedUploadAfter)
+ {
+ bNeedUploadAfter = TRUE;
+ xrUploadArea.x0=VRAMWrite.x;
+ xrUploadArea.x1=VRAMWrite.x+VRAMWrite.Width;
+ xrUploadArea.y0=VRAMWrite.y;
+ xrUploadArea.y1=VRAMWrite.y+VRAMWrite.Height;
+ }
+ else
+ {
+ xrUploadArea.x0=min(xrUploadArea.x0,VRAMWrite.x);
+ xrUploadArea.x1=max(xrUploadArea.x1,VRAMWrite.x+VRAMWrite.Width);
+ xrUploadArea.y0=min(xrUploadArea.y0,VRAMWrite.y);
+ xrUploadArea.y1=max(xrUploadArea.y1,VRAMWrite.y+VRAMWrite.Height);
+ }
+
+ if(dwActFixes&0x8000)
+ {
+ if((xrUploadArea.x1-xrUploadArea.x0)>=(PSXDisplay.DisplayMode.x-32) &&
+ (xrUploadArea.y1-xrUploadArea.y0)>=(PSXDisplay.DisplayMode.y-32))
+ {
+ UploadScreen(-1);
+ updateFrontDisplay();
+ }
+ }
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+// cmd: vram -> psx mem
+////////////////////////////////////////////////////////////////////////
+
+void primStoreImage(unsigned char * baseAddr)
+{
+ unsigned short *sgpuData = ((unsigned short *) baseAddr);
+
+ VRAMRead.x = sgpuData[2]&0x03ff;
+ VRAMRead.y = sgpuData[3]&iGPUHeightMask;
+ VRAMRead.Width = sgpuData[4];
+ VRAMRead.Height = sgpuData[5];
+
+ VRAMRead.ImagePtr = psxVuw + (VRAMRead.y<<10) + VRAMRead.x;
+ VRAMRead.RowsRemaining = VRAMRead.Width;
+ VRAMRead.ColsRemaining = VRAMRead.Height;
+
+ iDataReadMode = DR_VRAMTRANSFER;
+
+ STATUSREG |= GPUSTATUS_READYFORVRAM;
+}
+
+////////////////////////////////////////////////////////////////////////
+// cmd: blkfill - NO primitive! Doesn't care about draw areas...
+////////////////////////////////////////////////////////////////////////
+
+void primBlkFill(unsigned char * baseAddr)
+{
+ uint32_t *gpuData = ((uint32_t *) baseAddr);
+ short *sgpuData = ((short *) baseAddr);
+
+ iDrawnSomething = 1;
+
+ sprtX = sgpuData[2];
+ sprtY = sgpuData[3];
+ sprtW = sgpuData[4] & 0x3ff;
+ sprtH = sgpuData[5] & iGPUHeightMask;
+
+ sprtW = (sprtW + 15) & ~15;
+
+ // Increase H & W if they are one short of full values, because they never can be full values
+ if (sprtH == iGPUHeightMask) sprtH=iGPUHeight;
+ if (sprtW == 1023) sprtW=1024;
+
+ // x and y of start
+ ly0 = ly1 = sprtY;
+ ly2 = ly3 = (sprtY+sprtH);
+ lx0 = lx3 = sprtX;
+ lx1 = lx2 = (sprtX+sprtW);
+
+ offsetBlk();
+
+ if(ClipVertexListScreen())
+ {
+ PSXDisplay_t * pd;
+ if(PSXDisplay.InterlacedTest) pd=&PSXDisplay;
+ else pd=&PreviousPSXDisplay;
+
+ if ((lx0 <= pd->DisplayPosition.x+16) &&
+ (ly0 <= pd->DisplayPosition.y+16) &&
+ (lx2 >= pd->DisplayEnd.x-16) &&
+ (ly2 >= pd->DisplayEnd.y-16))
+ {
+ GLclampf g,b,r;
+ g=((GLclampf)GREEN(gpuData[0]))/255.0f;
+ b=((GLclampf)BLUE(gpuData[0]))/255.0f;
+ r=((GLclampf)RED(gpuData[0]))/255.0f;
+
+ glDisable(GL_SCISSOR_TEST);
+ glClearColor(r,g,b,1.0f);
+ glClear(uiBufferBits);
+ gl_z=0.0f;
+
+ if(gpuData[0]!=0x02000000 &&
+ (ly0>pd->DisplayPosition.y ||
+ ly2<pd->DisplayEnd.y))
+ {
+ bDrawTextured = FALSE;
+ bDrawSmoothShaded = FALSE;
+ SetRenderState((uint32_t)0x01000000);
+ SetRenderMode((uint32_t)0x01000000, FALSE);
+ vertex[0].c.lcol=0xff000000;
+ SETCOL(vertex[0]);
+ if(ly0>pd->DisplayPosition.y)
+ {
+ vertex[0].x=0;vertex[0].y=0;
+ vertex[1].x=pd->DisplayEnd.x-pd->DisplayPosition.x;vertex[1].y=0;
+ vertex[2].x=vertex[1].x;vertex[2].y=ly0-pd->DisplayPosition.y;
+ vertex[3].x=0;vertex[3].y=vertex[2].y;
+ PRIMdrawQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);
+ }
+ if(ly2<pd->DisplayEnd.y)
+ {
+ vertex[0].x=0;vertex[0].y=(pd->DisplayEnd.y-pd->DisplayPosition.y)-(pd->DisplayEnd.y-ly2);
+ vertex[1].x=pd->DisplayEnd.x-pd->DisplayPosition.x;vertex[1].y=vertex[0].y;
+ vertex[2].x=vertex[1].x;vertex[2].y=pd->DisplayEnd.y;
+ vertex[3].x=0;vertex[3].y=vertex[2].y;
+ PRIMdrawQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);
+ }
+ }
+
+ glEnable(GL_SCISSOR_TEST);
+ }
+ else
+ {
+ bDrawTextured = FALSE;
+ bDrawSmoothShaded = FALSE;
+ SetRenderState((uint32_t)0x01000000);
+ SetRenderMode((uint32_t)0x01000000, FALSE);
+ vertex[0].c.lcol=gpuData[0]|0xff000000;
+ SETCOL(vertex[0]);
+ glDisable(GL_SCISSOR_TEST);
+ PRIMdrawQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);
+ glEnable(GL_SCISSOR_TEST);
+ }
+ }
+
+ //mmm... will clean all stuff, also if not all _should_ be cleaned...
+ //if (IsInsideNextScreen(sprtX, sprtY, sprtW, sprtH))
+ // try this:
+ if (IsCompleteInsideNextScreen(sprtX, sprtY, sprtW, sprtH))
+ {
+ lClearOnSwapColor = COLOR(gpuData[0]);
+ lClearOnSwap = 1;
+ }
+
+ if(iOffscreenDrawing)
+ {
+ ClampToPSXScreenOffset( &sprtX, &sprtY, &sprtW, &sprtH);
+ if ((sprtW == 0) || (sprtH == 0)) return;
+ InvalidateTextureArea(sprtX, sprtY, sprtW-1, sprtH-1);
+
+ sprtW+=sprtX;
+ sprtH+=sprtY;
+
+ FillSoftwareArea(sprtX, sprtY, sprtW, sprtH, BGR24to16(gpuData[0]));
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+// cmd: move image vram -> vram
+////////////////////////////////////////////////////////////////////////
+
+void MoveImageWrapped(short imageX0,short imageY0,
+ short imageX1,short imageY1,
+ short imageSX,short imageSY)
+{
+ int i,j,imageXE,imageYE;
+
+ if(iFrameReadType&2)
+ {
+ imageXE=imageX0+imageSX;
+ imageYE=imageY0+imageSY;
+
+ if(imageYE>iGPUHeight && imageXE>1024)
+ {
+ CheckVRamRead(0,0,
+ (imageXE&0x3ff),
+ (imageY0&iGPUHeightMask),
+ FALSE);
+ }
+
+ if(imageXE>1024)
+ {
+ CheckVRamRead(0,imageY0,
+ (imageXE&0x3ff),
+ (imageYE>iGPUHeight)?iGPUHeight:imageYE,
+ FALSE);
+ }
+
+ if(imageYE>iGPUHeight)
+ {
+ CheckVRamRead(imageX0,0,
+ (imageXE>1024)?1024:imageXE,
+ imageYE&iGPUHeightMask,
+ FALSE);
+ }
+
+ CheckVRamRead(imageX0,imageY0,
+ (imageXE>1024)?1024:imageXE,
+ (imageYE>iGPUHeight)?iGPUHeight:imageYE,
+ FALSE);
+ }
+
+ for(j=0;j<imageSY;j++)
+ for(i=0;i<imageSX;i++)
+ psxVuw [(1024*((imageY1+j)&iGPUHeightMask))+((imageX1+i)&0x3ff)]=
+ psxVuw[(1024*((imageY0+j)&iGPUHeightMask))+((imageX0+i)&0x3ff)];
+
+ if(!PSXDisplay.RGB24)
+ {
+ imageXE=imageX1+imageSX;
+ imageYE=imageY1+imageSY;
+
+ if(imageYE>iGPUHeight && imageXE>1024)
+ {
+ InvalidateTextureArea(0,0,
+ (imageXE&0x3ff)-1,
+ (imageYE&iGPUHeightMask)-1);
+ }
+
+ if(imageXE>1024)
+ {
+ InvalidateTextureArea(0,imageY1,
+ (imageXE&0x3ff)-1,
+ ((imageYE>iGPUHeight)?iGPUHeight:imageYE)-imageY1-1);
+ }
+
+ if(imageYE>iGPUHeight)
+ {
+ InvalidateTextureArea(imageX1,0,
+ ((imageXE>1024)?1024:imageXE)-imageX1-1,
+ (imageYE&iGPUHeightMask)-1);
+ }
+
+ InvalidateTextureArea(imageX1,imageY1,
+ ((imageXE>1024)?1024:imageXE)-imageX1-1,
+ ((imageYE>iGPUHeight)?iGPUHeight:imageYE)-imageY1-1);
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void primMoveImage(unsigned char * baseAddr)
+{
+ short *sgpuData = ((short *) baseAddr);
+ short imageY0,imageX0,imageY1,imageX1,imageSX,imageSY,i,j;
+
+ imageX0 = sgpuData[2]&0x03ff;
+ imageY0 = sgpuData[3]&iGPUHeightMask;
+ imageX1 = sgpuData[4]&0x03ff;
+ imageY1 = sgpuData[5]&iGPUHeightMask;
+ imageSX = sgpuData[6];
+ imageSY = sgpuData[7];
+
+ if((imageX0 == imageX1) && (imageY0 == imageY1)) return;
+ if(imageSX<=0) return;
+ if(imageSY<=0) return;
+
+ if(iGPUHeight==1024 && sgpuData[7]>1024) return;
+
+ if((imageY0+imageSY)>iGPUHeight ||
+ (imageX0+imageSX)>1024 ||
+ (imageY1+imageSY)>iGPUHeight ||
+ (imageX1+imageSX)>1024)
+ {
+ MoveImageWrapped(imageX0,imageY0,imageX1,imageY1,imageSX,imageSY);
+ if((imageY0+imageSY)>iGPUHeight) imageSY=iGPUHeight-imageY0;
+ if((imageX0+imageSX)>1024) imageSX=1024-imageX0;
+ if((imageY1+imageSY)>iGPUHeight) imageSY=iGPUHeight-imageY1;
+ if((imageX1+imageSX)>1024) imageSX=1024-imageX1;
+ }
+
+ if(iFrameReadType&2)
+ CheckVRamRead(imageX0,imageY0,
+ imageX0+imageSX,
+ imageY0+imageSY,
+ FALSE);
+
+ if(imageSX&1)
+ {
+ unsigned short *SRCPtr, *DSTPtr;
+ unsigned short LineOffset;
+
+ SRCPtr = psxVuw + (1024*imageY0) + imageX0;
+ DSTPtr = psxVuw + (1024*imageY1) + imageX1;
+
+ LineOffset = 1024 - imageSX;
+
+ for(j=0;j<imageSY;j++)
+ {
+ for(i=0;i<imageSX;i++) *DSTPtr++ = *SRCPtr++;
+ SRCPtr += LineOffset;
+ DSTPtr += LineOffset;
+ }
+ }
+ else
+ {
+ uint32_t *SRCPtr, *DSTPtr;
+ unsigned short LineOffset;
+ int dx=imageSX>>1;
+
+ SRCPtr = (uint32_t *)(psxVuw + (1024*imageY0) + imageX0);
+ DSTPtr = (uint32_t *)(psxVuw + (1024*imageY1) + imageX1);
+
+ LineOffset = 512 - dx;
+
+ for(j=0;j<imageSY;j++)
+ {
+ for(i=0;i<dx;i++) *DSTPtr++ = *SRCPtr++;
+ SRCPtr += LineOffset;
+ DSTPtr += LineOffset;
+ }
+ }
+
+ if (!PSXDisplay.RGB24)
+ {
+ InvalidateTextureArea(imageX1,imageY1,imageSX-1,imageSY-1);
+
+ if (CheckAgainstScreen(imageX1,imageY1,imageSX,imageSY))
+ {
+ if(imageX1>=PreviousPSXDisplay.DisplayPosition.x &&
+ imageX1<PreviousPSXDisplay.DisplayEnd.x &&
+ imageY1>=PreviousPSXDisplay.DisplayPosition.y &&
+ imageY1<PreviousPSXDisplay.DisplayEnd.y)
+ {
+ imageX1 += imageSX;
+ imageY1 += imageSY;
+
+ if(imageX1>=PreviousPSXDisplay.DisplayPosition.x &&
+ imageX1<=PreviousPSXDisplay.DisplayEnd.x &&
+ imageY1>=PreviousPSXDisplay.DisplayPosition.y &&
+ imageY1<=PreviousPSXDisplay.DisplayEnd.y)
+ {
+ if(!(
+ imageX0>=PSXDisplay.DisplayPosition.x &&
+ imageX0<PSXDisplay.DisplayEnd.x &&
+ imageY0>=PSXDisplay.DisplayPosition.y &&
+ imageY0<PSXDisplay.DisplayEnd.y
+ ))
+ {
+ if(bRenderFrontBuffer)
+ {
+ updateFrontDisplay();
+ }
+
+ UploadScreen(FALSE);
+ }
+ else bFakeFrontBuffer=TRUE;
+ }
+ }
+
+ bNeedUploadTest=TRUE;
+ }
+ else
+ if(iOffscreenDrawing)
+ {
+ if (CheckAgainstFrontScreen(imageX1,imageY1,imageSX,imageSY))
+ {
+ if(!PSXDisplay.InterlacedTest &&
+// !bFullVRam &&
+ ((
+ imageX0>=PreviousPSXDisplay.DisplayPosition.x &&
+ imageX0<PreviousPSXDisplay.DisplayEnd.x &&
+ imageY0>=PreviousPSXDisplay.DisplayPosition.y &&
+ imageY0<PreviousPSXDisplay.DisplayEnd.y
+ ) ||
+ (
+ imageX0>=PSXDisplay.DisplayPosition.x &&
+ imageX0<PSXDisplay.DisplayEnd.x &&
+ imageY0>=PSXDisplay.DisplayPosition.y &&
+ imageY0<PSXDisplay.DisplayEnd.y
+ )))
+ return;
+
+ bNeedUploadTest=TRUE;
+
+ if(!bNeedUploadAfter)
+ {
+ bNeedUploadAfter = TRUE;
+ xrUploadArea.x0=imageX0;
+ xrUploadArea.x1=imageX0+imageSX;
+ xrUploadArea.y0=imageY0;
+ xrUploadArea.y1=imageY0+imageSY;
+ }
+ else
+ {
+ xrUploadArea.x0=min(xrUploadArea.x0,imageX0);
+ xrUploadArea.x1=max(xrUploadArea.x1,imageX0+imageSX);
+ xrUploadArea.y0=min(xrUploadArea.y0,imageY0);
+ xrUploadArea.y1=max(xrUploadArea.y1,imageY0+imageSY);
+ }
+ }
+ }
+ }
+}
+
+
+////////////////////////////////////////////////////////////////////////
+// cmd: draw free-size Tile
+////////////////////////////////////////////////////////////////////////
+
+void primTileS(unsigned char * baseAddr)
+{
+ uint32_t *gpuData = ((uint32_t *)baseAddr);
+ short *sgpuData = ((short *) baseAddr);
+
+ sprtX = sgpuData[2];
+ sprtY = sgpuData[3];
+ sprtW = sgpuData[4] & 0x3ff;
+ sprtH = sgpuData[5] & iGPUHeightMask;
+
+ // x and y of start
+
+ lx0 = sprtX;
+ ly0 = sprtY;
+
+ offsetST();
+
+ if((dwActFixes&1) && // FF7 special game gix (battle cursor)
+ sprtX==0 && sprtY==0 && sprtW==24 && sprtH==16)
+ return;
+
+ bDrawTextured = FALSE;
+ bDrawSmoothShaded = FALSE;
+
+ SetRenderState(gpuData[0]);
+
+ if(iOffscreenDrawing)
+ {
+ if(IsPrimCompleteInsideNextScreen(lx0,ly0,lx2,ly2) ||
+ (ly0==-6 && ly2==10)) // OH MY GOD... I DIDN'T WANT TO DO IT... BUT I'VE FOUND NO OTHER WAY... HACK FOR GRADIUS SHOOTER :(
+ {
+ lClearOnSwapColor = COLOR(gpuData[0]);
+ lClearOnSwap = 1;
+ }
+
+ offsetPSX4();
+ if(bDrawOffscreen4())
+ {
+ if(!(iTileCheat && sprtH==32 && gpuData[0]==0x60ffffff)) // special cheat for certain ZiNc games
+ {
+ InvalidateTextureAreaEx();
+ FillSoftwareAreaTrans(lx0,ly0,lx2,ly2,
+ BGR24to16(gpuData[0]));
+ }
+ }
+ }
+
+ SetRenderMode(gpuData[0], FALSE);
+ SetZMask4NT();
+
+ if(bIgnoreNextTile) {bIgnoreNextTile=FALSE;return;}
+
+ vertex[0].c.lcol=gpuData[0];
+ vertex[0].c.col[3]=ubGloColAlpha;
+ SETCOL(vertex[0]);
+
+ PRIMdrawQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);
+
+ iDrawnSomething=1;
+}
+
+////////////////////////////////////////////////////////////////////////
+// cmd: draw 1 dot Tile (point)
+////////////////////////////////////////////////////////////////////////
+
+void primTile1(unsigned char * baseAddr)
+{
+ uint32_t *gpuData = ((uint32_t *)baseAddr);
+ short *sgpuData = ((short *)baseAddr);
+
+ sprtX = sgpuData[2];
+ sprtY = sgpuData[3];
+ sprtW = 1;
+ sprtH = 1;
+
+ lx0 = sprtX;
+ ly0 = sprtY;
+
+ offsetST();
+
+ bDrawTextured = FALSE;
+ bDrawSmoothShaded = FALSE;
+
+ SetRenderState(gpuData[0]);
+
+ if(iOffscreenDrawing)
+ {
+ offsetPSX4();
+
+ if(bDrawOffscreen4())
+ {
+ InvalidateTextureAreaEx();
+ FillSoftwareAreaTrans(lx0,ly0,lx2,ly2,
+ BGR24to16(gpuData[0]));
+ }
+ }
+
+ SetRenderMode(gpuData[0], FALSE);
+ SetZMask4NT();
+
+ vertex[0].c.lcol=gpuData[0];vertex[0].c.col[3]=ubGloColAlpha;
+ SETCOL(vertex[0]);
+
+ PRIMdrawQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);
+
+ iDrawnSomething=1;
+}
+
+////////////////////////////////////////////////////////////////////////
+// cmd: draw 8 dot Tile (small rect)
+////////////////////////////////////////////////////////////////////////
+
+void primTile8(unsigned char * baseAddr)
+{
+ uint32_t *gpuData = ((uint32_t *)baseAddr);
+ short *sgpuData = ((short *) baseAddr);
+
+ sprtX = sgpuData[2];
+ sprtY = sgpuData[3];
+ sprtW = 8;
+ sprtH = 8;
+
+ lx0 = sprtX;
+ ly0 = sprtY;
+
+ offsetST();
+
+ bDrawTextured = FALSE;
+ bDrawSmoothShaded = FALSE;
+ SetRenderState(gpuData[0]);
+
+ if(iOffscreenDrawing)
+ {
+ offsetPSX4();
+
+ if(bDrawOffscreen4())
+ {
+ InvalidateTextureAreaEx();
+ FillSoftwareAreaTrans(lx0,ly0,lx2,ly2,
+ BGR24to16(gpuData[0]));
+ }
+ }
+
+ SetRenderMode(gpuData[0], FALSE);
+ SetZMask4NT();
+
+ vertex[0].c.lcol=gpuData[0];
+ vertex[0].c.col[3]=ubGloColAlpha;
+ SETCOL(vertex[0]);
+
+ PRIMdrawQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);
+
+ iDrawnSomething=1;
+}
+
+////////////////////////////////////////////////////////////////////////
+// cmd: draw 16 dot Tile (medium rect)
+////////////////////////////////////////////////////////////////////////
+
+void primTile16(unsigned char * baseAddr)
+{
+ uint32_t *gpuData = ((uint32_t *)baseAddr);
+ short *sgpuData = ((short *)baseAddr);
+
+ sprtX = sgpuData[2];
+ sprtY = sgpuData[3];
+ sprtW = 16;
+ sprtH = 16;
+ // x and y of start
+ lx0 = sprtX;
+ ly0 = sprtY;
+
+ offsetST();
+
+ bDrawTextured = FALSE;
+ bDrawSmoothShaded = FALSE;
+ SetRenderState(gpuData[0]);
+
+ if(iOffscreenDrawing)
+ {
+ offsetPSX4();
+
+ if(bDrawOffscreen4())
+ {
+ InvalidateTextureAreaEx();
+ FillSoftwareAreaTrans(lx0,ly0,lx2,ly2,
+ BGR24to16(gpuData[0]));
+ }
+ }
+
+ SetRenderMode(gpuData[0], FALSE);
+ SetZMask4NT();
+
+ vertex[0].c.lcol=gpuData[0];
+ vertex[0].c.col[3]=ubGloColAlpha;
+ SETCOL(vertex[0]);
+
+ PRIMdrawQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);
+
+ iDrawnSomething=1;
+}
+
+////////////////////////////////////////////////////////////////////////
+// helper: filter effect by multipass rendering
+////////////////////////////////////////////////////////////////////////
+
+void DrawMultiBlur(void)
+{
+ int lABR,lDST;
+ float fx,fy;
+
+ lABR=GlobalTextABR;
+ lDST=DrawSemiTrans;
+
+ fx=(float)PSXDisplay.DisplayMode.x/(float)(iResX);
+ fy=(float)PSXDisplay.DisplayMode.y/(float)(iResY);
+
+ vertex[0].x+=fx;vertex[1].x+=fx;
+ vertex[2].x+=fx;vertex[3].x+=fx;
+
+ GlobalTextABR=0;
+ DrawSemiTrans=1;
+ SetSemiTrans();
+
+ PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);
+
+ vertex[0].y+=fy;vertex[1].y+=fy;
+ vertex[2].y+=fy;vertex[3].y+=fy;
+ PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);
+
+ if(bDrawMultiPass) {obm1=obm2=GL_SRC_ALPHA;}
+
+ GlobalTextABR=lABR;
+ DrawSemiTrans=lDST;
+}
+
+////////////////////////////////////////////////////////////////////////
+
+#define POFF 0.375f
+
+void DrawMultiFilterSprite(void)
+{
+ int lABR,lDST;
+
+ if(bUseMultiPass || DrawSemiTrans || ubOpaqueDraw)
+ {
+ PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);
+ return;
+ }
+
+ lABR=GlobalTextABR;
+ lDST=DrawSemiTrans;
+ vertex[0].c.col[3]=ubGloAlpha/2; // -> set color with
+ SETCOL(vertex[0]); // texture alpha
+ PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);
+ vertex[0].x+=POFF;vertex[1].x+=POFF;
+ vertex[2].x+=POFF;vertex[3].x+=POFF;
+ vertex[0].y+=POFF;vertex[1].y+=POFF;
+ vertex[2].y+=POFF;vertex[3].y+=POFF;
+ GlobalTextABR=0;
+ DrawSemiTrans=1;
+ SetSemiTrans();
+ PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);
+ GlobalTextABR=lABR;
+ DrawSemiTrans=lDST;
+}
+
+////////////////////////////////////////////////////////////////////////
+// cmd: small sprite (textured rect)
+////////////////////////////////////////////////////////////////////////
+
+void primSprt8(unsigned char * baseAddr)
+{
+ uint32_t *gpuData = ((uint32_t *) baseAddr);
+ short *sgpuData = ((short *) baseAddr);
+ short s;
+
+ iSpriteTex=1;
+
+ sprtX = sgpuData[2];
+ sprtY = sgpuData[3];
+ sprtW = 8;
+ sprtH = 8;
+
+ lx0 = sprtX;
+ ly0 = sprtY;
+
+ offsetST();
+
+ // do texture stuff
+ gl_ux[0]=gl_ux[3]=baseAddr[8];//gpuData[2]&0xff;
+
+ if(usMirror & 0x1000)
+ {
+ s=gl_ux[0];
+ s-=sprtW-1;
+ if(s<0) {s=0;}
+ gl_ux[0]=gl_ux[3]=s;
+ }
+
+ sSprite_ux2=s=gl_ux[0]+sprtW;
+ if(s) s--;
+ if(s>255) s=255;
+ gl_ux[1]=gl_ux[2]=s;
+ // Y coords
+ gl_vy[0]=gl_vy[1]=baseAddr[9];//(gpuData[2]>>8)&0xff;
+
+ if(usMirror & 0x2000)
+ {
+ s=gl_vy[0];
+ s-=sprtH-1;
+ if(s<0) {s=0;}
+ gl_vy[0]=gl_vy[1]=s;
+ }
+
+ sSprite_vy2=s=gl_vy[0]+sprtH;
+ if(s) s--;
+ if(s>255) s=255;
+ gl_vy[2]=gl_vy[3]=s;
+
+ ulClutID=(gpuData[2]>>16);
+
+ bDrawTextured = TRUE;
+ bDrawSmoothShaded = FALSE;
+ SetRenderState(gpuData[0]);
+
+ if(iOffscreenDrawing)
+ {
+ offsetPSX4();
+
+ if(bDrawOffscreen4())
+ {
+ InvalidateTextureAreaEx();
+ SetRenderColor(gpuData[0]);
+ lx0-=PSXDisplay.DrawOffset.x;
+ ly0-=PSXDisplay.DrawOffset.y;
+
+ if(bUsingTWin) DrawSoftwareSpriteTWin(baseAddr,8,8);
+ else
+ if(usMirror) DrawSoftwareSpriteMirror(baseAddr,8,8);
+ else
+ DrawSoftwareSprite(baseAddr,8,8,baseAddr[8],baseAddr[9]);
+ }
+ }
+
+ SetRenderMode(gpuData[0], TRUE);
+ SetZMask4SP();
+
+ sSprite_ux2=gl_ux[0]+sprtW;
+ sSprite_vy2=gl_vy[0]+sprtH;
+
+ assignTextureSprite();
+
+ if(iFilterType>4)
+ DrawMultiFilterSprite();
+ else
+ PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);
+
+ if(bDrawMultiPass)
+ {
+ SetSemiTransMulti(1);
+ PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);
+ }
+
+ if(ubOpaqueDraw)
+ {
+ SetZMask4O();
+ if(bUseMultiPass) SetOpaqueColor(gpuData[0]);
+ DEFOPAQUEON
+
+ if(bSmallAlpha && iFilterType<=2)
+ {
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ SetZMask4O();
+ }
+
+ PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);
+ DEFOPAQUEOFF
+ }
+
+ iSpriteTex=0;
+ iDrawnSomething=1;
+}
+
+////////////////////////////////////////////////////////////////////////
+// cmd: medium sprite (textured rect)
+////////////////////////////////////////////////////////////////////////
+
+void primSprt16(unsigned char * baseAddr)
+{
+ uint32_t *gpuData = ((uint32_t *) baseAddr);
+ short *sgpuData = ((short *) baseAddr);
+ short s;
+
+ iSpriteTex=1;
+
+ sprtX = sgpuData[2];
+ sprtY = sgpuData[3];
+ sprtW = 16;
+ sprtH = 16;
+
+ lx0 = sprtX;
+ ly0 = sprtY;
+
+ offsetST();
+
+ // do texture stuff
+ gl_ux[0]=gl_ux[3]=baseAddr[8];//gpuData[2]&0xff;
+
+ if(usMirror & 0x1000)
+ {
+ s=gl_ux[0];
+ s-=sprtW-1;
+ if(s<0) {s=0;}
+ gl_ux[0]=gl_ux[3]=s;
+ }
+
+ sSprite_ux2=s=gl_ux[0]+sprtW;
+ if(s) s--;
+ if(s>255) s=255;
+ gl_ux[1]=gl_ux[2]=s;
+ // Y coords
+ gl_vy[0]=gl_vy[1]=baseAddr[9];//(gpuData[2]>>8)&0xff;
+
+ if(usMirror & 0x2000)
+ {
+ s=gl_vy[0];
+ s-=sprtH-1;
+ if(s<0) {s=0;}
+ gl_vy[0]=gl_vy[1]=s;
+ }
+
+ sSprite_vy2=s=gl_vy[0]+sprtH;
+ if(s) s--;
+ if(s>255) s=255;
+ gl_vy[2]=gl_vy[3]=s;
+
+ ulClutID=(gpuData[2]>>16);
+
+ bDrawTextured = TRUE;
+ bDrawSmoothShaded = FALSE;
+ SetRenderState(gpuData[0]);
+
+ if(iOffscreenDrawing)
+ {
+ offsetPSX4();
+
+ if(bDrawOffscreen4())
+ {
+ InvalidateTextureAreaEx();
+ SetRenderColor(gpuData[0]);
+ lx0-=PSXDisplay.DrawOffset.x;
+ ly0-=PSXDisplay.DrawOffset.y;
+ if(bUsingTWin) DrawSoftwareSpriteTWin(baseAddr,16,16);
+ else
+ if(usMirror) DrawSoftwareSpriteMirror(baseAddr,16,16);
+ else
+ DrawSoftwareSprite(baseAddr,16,16,baseAddr[8],baseAddr[9]);
+ }
+ }
+
+ SetRenderMode(gpuData[0], TRUE);
+ SetZMask4SP();
+
+ sSprite_ux2=gl_ux[0]+sprtW;
+ sSprite_vy2=gl_vy[0]+sprtH;
+
+ assignTextureSprite();
+
+ if(iFilterType>4)
+ DrawMultiFilterSprite();
+ else
+ PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);
+
+ if(bDrawMultiPass)
+ {
+ SetSemiTransMulti(1);
+ PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);
+ }
+
+ if(ubOpaqueDraw)
+ {
+ SetZMask4O();
+ if(bUseMultiPass) SetOpaqueColor(gpuData[0]);
+ DEFOPAQUEON
+
+ if(bSmallAlpha && iFilterType<=2)
+ {
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ SetZMask4O();
+ }
+
+ PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);
+ DEFOPAQUEOFF
+ }
+
+ iSpriteTex=0;
+ iDrawnSomething=1;
+}
+
+////////////////////////////////////////////////////////////////////////
+// cmd: free-size sprite (textured rect)
+////////////////////////////////////////////////////////////////////////
+
+void primSprtSRest(unsigned char * baseAddr,unsigned short type)
+{
+ uint32_t *gpuData = ((uint32_t *)baseAddr);
+ short *sgpuData = ((short *) baseAddr);
+ short s;
+ unsigned short sTypeRest=0;
+
+ sprtX = sgpuData[2];
+ sprtY = sgpuData[3];
+ sprtW = sgpuData[6] & 0x3ff;
+ sprtH = sgpuData[7] & 0x1ff;
+
+ // do texture stuff
+ switch(type)
+ {
+ case 1:
+ gl_vy[0]=gl_vy[1]=baseAddr[9];
+ s=256-baseAddr[8];
+ sprtW-=s;
+ sprtX+=s;
+ gl_ux[0]=gl_ux[3]=0;
+ break;
+ case 2:
+ gl_ux[0]=gl_ux[3]=baseAddr[8];
+ s=256-baseAddr[9];
+ sprtH-=s;
+ sprtY+=s;
+ gl_vy[0]=gl_vy[1]=0;
+ break;
+ case 3:
+ s=256-baseAddr[8];
+ sprtW-=s;
+ sprtX+=s;
+ gl_ux[0]=gl_ux[3]=0;
+ s=256-baseAddr[9];
+ sprtH-=s;
+ sprtY+=s;
+ gl_vy[0]=gl_vy[1]=0;
+ break;
+
+ case 4:
+ gl_vy[0]=gl_vy[1]=baseAddr[9];
+ s=512-baseAddr[8];
+ sprtW-=s;
+ sprtX+=s;
+ gl_ux[0]=gl_ux[3]=0;
+ break;
+ case 5:
+ gl_ux[0]=gl_ux[3]=baseAddr[8];
+ s=512-baseAddr[9];
+ sprtH-=s;
+ sprtY+=s;
+ gl_vy[0]=gl_vy[1]=0;
+ break;
+ case 6:
+ s=512-baseAddr[8];
+ sprtW-=s;
+ sprtX+=s;
+ gl_ux[0]=gl_ux[3]=0;
+ s=512-baseAddr[9];
+ sprtH-=s;
+ sprtY+=s;
+ gl_vy[0]=gl_vy[1]=0;
+ break;
+
+ }
+
+ if(usMirror & 0x1000)
+ {
+ s=gl_ux[0];
+ s-=sprtW-1;if(s<0) s=0;
+ gl_ux[0]=gl_ux[3]=s;
+ }
+ if(usMirror & 0x2000)
+ {
+ s=gl_vy[0];
+ s-=sprtH-1;if(s<0) {s=0;}
+ gl_vy[0]=gl_vy[1]=s;
+ }
+
+ sSprite_ux2=s=gl_ux[0]+sprtW;
+ if(s>255) s=255;
+ gl_ux[1]=gl_ux[2]=s;
+ sSprite_vy2=s=gl_vy[0]+sprtH;
+ if(s>255) s=255;
+ gl_vy[2]=gl_vy[3]=s;
+
+ if(!bUsingTWin)
+ {
+ if(sSprite_ux2>256)
+ {sprtW=256-gl_ux[0];sSprite_ux2=256;sTypeRest+=1;}
+ if(sSprite_vy2>256)
+ {sprtH=256-gl_vy[0];sSprite_vy2=256;sTypeRest+=2;}
+ }
+
+ lx0 = sprtX;
+ ly0 = sprtY;
+
+ offsetST();
+
+ ulClutID=(gpuData[2]>>16);
+
+ bDrawTextured = TRUE;
+ bDrawSmoothShaded = FALSE;
+ SetRenderState(gpuData[0]);
+
+ if(iOffscreenDrawing)
+ {
+ offsetPSX4();
+
+ if(bDrawOffscreen4())
+ {
+ InvalidateTextureAreaEx();
+ SetRenderColor(gpuData[0]);
+ lx0-=PSXDisplay.DrawOffset.x;
+ ly0-=PSXDisplay.DrawOffset.y;
+ if(bUsingTWin) DrawSoftwareSpriteTWin(baseAddr,sprtW,sprtH);
+ else
+ if(usMirror) DrawSoftwareSpriteMirror(baseAddr,sprtW,sprtH);
+ else
+ DrawSoftwareSprite(baseAddr,sprtW,sprtH,baseAddr[8],baseAddr[9]);
+ }
+ }
+
+ SetRenderMode(gpuData[0], TRUE);
+ SetZMask4SP();
+
+ sSprite_ux2=gl_ux[0]+sprtW;
+ sSprite_vy2=gl_vy[0]+sprtH;
+
+ assignTextureSprite();
+
+ if(iFilterType>4)
+ DrawMultiFilterSprite();
+ else
+ PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);
+
+ if(bDrawMultiPass)
+ {
+ SetSemiTransMulti(1);
+ PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);
+ }
+
+ if(ubOpaqueDraw)
+ {
+ SetZMask4O();
+ if(bUseMultiPass) SetOpaqueColor(gpuData[0]);
+ DEFOPAQUEON
+
+ if(bSmallAlpha && iFilterType<=2)
+ {
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ SetZMask4O();
+ }
+
+ PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);
+ DEFOPAQUEOFF
+ }
+
+ if(sTypeRest && type<4)
+ {
+ if(sTypeRest&1 && type==1) primSprtSRest(baseAddr,4);
+ if(sTypeRest&2 && type==2) primSprtSRest(baseAddr,5);
+ if(sTypeRest==3 && type==3) primSprtSRest(baseAddr,6);
+ }
+}
+
+void primSprtS(unsigned char * baseAddr)
+{
+ uint32_t *gpuData = ((uint32_t *) baseAddr);
+ short *sgpuData = ((short *) baseAddr);
+
+ short s;
+ unsigned short sTypeRest=0;
+
+ sprtX = sgpuData[2];
+ sprtY = sgpuData[3];
+ sprtW = sgpuData[6] & 0x3ff;
+ sprtH = sgpuData[7] & 0x1ff;
+
+ if(!sprtH) return;
+ if(!sprtW) return;
+
+ iSpriteTex=1;
+
+ // do texture stuff
+ gl_ux[0]=gl_ux[3]=baseAddr[8];//gpuData[2]&0xff;
+ gl_vy[0]=gl_vy[1]=baseAddr[9];//(gpuData[2]>>8)&0xff;
+
+ if(usMirror & 0x1000)
+ {
+ s=gl_ux[0];
+ s-=sprtW-1;
+ if(s<0) {s=0;}
+ gl_ux[0]=gl_ux[3]=s;
+ }
+ if(usMirror & 0x2000)
+ {
+ s=gl_vy[0];
+ s-=sprtH-1;
+ if(s<0) {s=0;}
+ gl_vy[0]=gl_vy[1]=s;
+ }
+
+ sSprite_ux2=s=gl_ux[0]+sprtW;
+ if(s) s--;
+ if(s>255) s=255;
+ gl_ux[1]=gl_ux[2]=s;
+ sSprite_vy2=s=gl_vy[0]+sprtH;
+ if(s) s--;
+ if(s>255) s=255;
+ gl_vy[2]=gl_vy[3]=s;
+
+ if(!bUsingTWin)
+ {
+ if(sSprite_ux2>256)
+ {sprtW=256-gl_ux[0];sSprite_ux2=256;sTypeRest+=1;}
+ if(sSprite_vy2>256)
+ {sprtH=256-gl_vy[0];sSprite_vy2=256;sTypeRest+=2;}
+ }
+
+ lx0 = sprtX;
+ ly0 = sprtY;
+
+ offsetST();
+
+ ulClutID=(gpuData[2]>>16);
+
+ bDrawTextured = TRUE;
+ bDrawSmoothShaded = FALSE;
+ SetRenderState(gpuData[0]);
+
+ if(iOffscreenDrawing)
+ {
+ offsetPSX4();
+
+ if(bDrawOffscreen4())
+ {
+ InvalidateTextureAreaEx();
+ SetRenderColor(gpuData[0]);
+ lx0-=PSXDisplay.DrawOffset.x;
+ ly0-=PSXDisplay.DrawOffset.y;
+ if(bUsingTWin) DrawSoftwareSpriteTWin(baseAddr,sprtW,sprtH);
+ else
+ if(usMirror) DrawSoftwareSpriteMirror(baseAddr,sprtW,sprtH);
+ else
+ DrawSoftwareSprite(baseAddr,sprtW,sprtH,baseAddr[8],baseAddr[9]);
+ }
+ }
+
+ SetRenderMode(gpuData[0], TRUE);
+ SetZMask4SP();
+
+ if((dwActFixes&1) && gTexFrameName && gTexName==gTexFrameName)
+ {iSpriteTex=0;return;}
+
+ sSprite_ux2=gl_ux[0]+sprtW;
+ sSprite_vy2=gl_vy[0]+sprtH;
+
+ assignTextureSprite();
+
+ if(iFilterType>4)
+ DrawMultiFilterSprite();
+ else
+ PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);
+
+ if(bDrawMultiPass)
+ {
+ SetSemiTransMulti(1);
+ PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);
+ }
+
+ if(ubOpaqueDraw)
+ {
+ SetZMask4O();
+ if(bUseMultiPass) SetOpaqueColor(gpuData[0]);
+ DEFOPAQUEON
+
+ if(bSmallAlpha && iFilterType<=2)
+ {
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ SetZMask4O();
+ }
+
+ PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);
+ DEFOPAQUEOFF
+ }
+
+ if(sTypeRest)
+ {
+ if(sTypeRest&1) primSprtSRest(baseAddr,1);
+ if(sTypeRest&2) primSprtSRest(baseAddr,2);
+ if(sTypeRest==3) primSprtSRest(baseAddr,3);
+ }
+
+ iSpriteTex=0;
+ iDrawnSomething=1;
+}
+
+////////////////////////////////////////////////////////////////////////
+// cmd: flat shaded Poly4
+////////////////////////////////////////////////////////////////////////
+
+void primPolyF4(unsigned char *baseAddr)
+{
+ uint32_t *gpuData = ((uint32_t *) baseAddr);
+ short *sgpuData = ((short *) baseAddr);
+
+ lx0 = sgpuData[2];
+ ly0 = sgpuData[3];
+ lx1 = sgpuData[4];
+ ly1 = sgpuData[5];
+ lx2 = sgpuData[6];
+ ly2 = sgpuData[7];
+ lx3 = sgpuData[8];
+ ly3 = sgpuData[9];
+
+ if(offset4()) return;
+
+ bDrawTextured = FALSE;
+ bDrawSmoothShaded = FALSE;
+ SetRenderState(gpuData[0]);
+
+ if(iOffscreenDrawing)
+ {
+ offsetPSX4();
+ if(bDrawOffscreen4())
+ {
+ InvalidateTextureAreaEx();
+ drawPoly4F(gpuData[0]);
+ }
+ }
+
+ SetRenderMode(gpuData[0], FALSE);
+ SetZMask4NT();
+
+ vertex[0].c.lcol=gpuData[0];vertex[0].c.col[3]=ubGloColAlpha;
+ SETCOL(vertex[0]);
+
+ PRIMdrawTri2(&vertex[0], &vertex[1], &vertex[2],&vertex[3]);
+
+ iDrawnSomething=1;
+}
+
+////////////////////////////////////////////////////////////////////////
+// cmd: smooth shaded Poly4
+////////////////////////////////////////////////////////////////////////
+
+void primPolyG4(unsigned char * baseAddr);
+
+BOOL bDrawOffscreenFrontFF9G4(void)
+{
+ if(lx0< PSXDisplay.DisplayPosition.x) return FALSE; // must be complete in front
+ if(lx0> PSXDisplay.DisplayEnd.x) return FALSE;
+ if(ly0< PSXDisplay.DisplayPosition.y) return FALSE;
+ if(ly0> PSXDisplay.DisplayEnd.y) return FALSE;
+ if(lx1< PSXDisplay.DisplayPosition.x) return FALSE;
+ if(lx1> PSXDisplay.DisplayEnd.x) return FALSE;
+ if(ly1< PSXDisplay.DisplayPosition.y) return FALSE;
+ if(ly1> PSXDisplay.DisplayEnd.y) return FALSE;
+ if(lx2< PSXDisplay.DisplayPosition.x) return FALSE;
+ if(lx2> PSXDisplay.DisplayEnd.x) return FALSE;
+ if(ly2< PSXDisplay.DisplayPosition.y) return FALSE;
+ if(ly2> PSXDisplay.DisplayEnd.y) return FALSE;
+ if(lx3< PSXDisplay.DisplayPosition.x) return FALSE;
+ if(lx3> PSXDisplay.DisplayEnd.x) return FALSE;
+ if(ly3< PSXDisplay.DisplayPosition.y) return FALSE;
+ if(ly3> PSXDisplay.DisplayEnd.y) return FALSE;
+ return TRUE;
+}
+
+BOOL bCheckFF9G4(unsigned char * baseAddr)
+{
+ static unsigned char pFF9G4Cache[32];
+ static int iFF9Fix=0;
+
+ if(baseAddr)
+ {
+ if(iFF9Fix==0)
+ {
+ if(bDrawOffscreenFrontFF9G4())
+ {
+ short *sgpuData = ((short *) pFF9G4Cache);
+ iFF9Fix=2;
+ memcpy(pFF9G4Cache,baseAddr,32);
+
+ if(sgpuData[2]==142)
+ {
+ sgpuData[2] +=65;
+ sgpuData[10]+=65;
+ }
+ return TRUE;
+ }
+ else iFF9Fix=1;
+ }
+ return FALSE;
+ }
+
+ if(iFF9Fix==2)
+ {
+ int labr=GlobalTextABR;
+ GlobalTextABR = 1;
+ primPolyG4(pFF9G4Cache);
+ GlobalTextABR = labr;
+ }
+ iFF9Fix = 0;
+
+ return FALSE;
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void primPolyG4(unsigned char * baseAddr)
+{
+ uint32_t *gpuData = (uint32_t *)baseAddr;
+ short *sgpuData = ((short *)baseAddr);
+
+ lx0 = sgpuData[2];
+ ly0 = sgpuData[3];
+ lx1 = sgpuData[6];
+ ly1 = sgpuData[7];
+ lx2 = sgpuData[10];
+ ly2 = sgpuData[11];
+ lx3 = sgpuData[14];
+ ly3 = sgpuData[15];
+
+ if(offset4()) return;
+
+ bDrawTextured = FALSE;
+ bDrawSmoothShaded = TRUE;
+ SetRenderState(gpuData[0]);
+
+ if(iOffscreenDrawing)
+ {
+ offsetPSX4();
+
+ if((dwActFixes&512) && bCheckFF9G4(baseAddr)) return;
+
+ if(bDrawOffscreen4())
+ {
+ InvalidateTextureAreaEx();
+ drawPoly4G(gpuData[0], gpuData[2], gpuData[4], gpuData[6]);
+ }
+ }
+
+ SetRenderMode(gpuData[0], FALSE);
+ SetZMask4NT();
+
+ vertex[0].c.lcol=gpuData[0];
+ vertex[1].c.lcol=gpuData[2];
+ vertex[2].c.lcol=gpuData[4];
+ vertex[3].c.lcol=gpuData[6];
+
+ vertex[0].c.col[3]=vertex[1].c.col[3]=vertex[2].c.col[3]=vertex[3].c.col[3]=ubGloAlpha;
+
+
+ PRIMdrawGouraudTri2Color(&vertex[0],&vertex[1], &vertex[2], &vertex[3]);
+
+ iDrawnSomething=1;
+}
+
+////////////////////////////////////////////////////////////////////////
+// cmd: flat shaded Texture3
+////////////////////////////////////////////////////////////////////////
+
+BOOL DoLineCheck(uint32_t *gpuData)
+{
+ BOOL bQuad=FALSE;short dx,dy;
+
+ if(lx0==lx1)
+ {
+ dx=lx0-lx2;if(dx<0) dx=-dx;
+
+ if(ly1==ly2)
+ {
+ dy=ly1-ly0;if(dy<0) dy=-dy;
+ if(dx<=1)
+ {
+ vertex[3]=vertex[2];
+ vertex[2]=vertex[0];
+ vertex[2].x=vertex[3].x;
+ }
+ else
+ if(dy<=1)
+ {
+ vertex[3]=vertex[2];
+ vertex[2].y=vertex[0].y;
+ }
+ else return FALSE;
+
+ bQuad=TRUE;
+ }
+ else
+ if(ly0==ly2)
+ {
+ dy=ly0-ly1;if(dy<0) dy=-dy;
+ if(dx<=1)
+ {
+ vertex[3]=vertex[1];
+ vertex[3].x=vertex[2].x;
+ }
+ else
+ if(dy<=1)
+ {
+ vertex[3]=vertex[2];
+ vertex[3].y=vertex[1].y;
+ }
+ else return FALSE;
+
+ bQuad=TRUE;
+ }
+ }
+
+ if(lx0==lx2)
+ {
+ dx=lx0-lx1;if(dx<0) dx=-dx;
+
+ if(ly2==ly1)
+ {
+ dy=ly2-ly0;if(dy<0) dy=-dy;
+ if(dx<=1)
+ {
+ vertex[3]=vertex[1];
+ vertex[1]=vertex[0];
+ vertex[1].x=vertex[3].x;
+ }
+ else
+ if(dy<=1)
+ {
+ vertex[3]=vertex[1];
+ vertex[1].y=vertex[0].y;
+ }
+ else return FALSE;
+
+ bQuad=TRUE;
+ }
+ else
+ if(ly0==ly1)
+ {
+ dy=ly2-ly0;if(dy<0) dy=-dy;
+ if(dx<=1)
+ {
+ vertex[3]=vertex[2];
+ vertex[3].x=vertex[1].x;
+ }
+ else
+ if(dy<=1)
+ {
+ vertex[3]=vertex[1];
+ vertex[3].y=vertex[2].y;
+ }
+ else return FALSE;
+
+ bQuad=TRUE;
+ }
+ }
+
+ if(lx1==lx2)
+ {
+ dx=lx1-lx0;if(dx<0) dx=-dx;
+
+ if(ly1==ly0)
+ {
+ dy=ly1-ly2;if(dy<0) dy=-dy;
+
+ if(dx<=1)
+ {
+ vertex[3]=vertex[2];
+ vertex[2].x=vertex[0].x;
+ }
+ else
+ if(dy<=1)
+ {
+ vertex[3]=vertex[2];
+ vertex[2]=vertex[0];
+ vertex[2].y=vertex[3].y;
+ }
+ else return FALSE;
+
+ bQuad=TRUE;
+ }
+ else
+ if(ly2==ly0)
+ {
+ dy=ly2-ly1;if(dy<0) dy=-dy;
+
+ if(dx<=1)
+ {
+ vertex[3]=vertex[1];
+ vertex[1].x=vertex[0].x;
+ }
+ else
+ if(dy<=1)
+ {
+ vertex[3]=vertex[1];
+ vertex[1]=vertex[0];
+ vertex[1].y=vertex[3].y;
+ }
+ else return FALSE;
+
+ bQuad=TRUE;
+ }
+ }
+
+ if(!bQuad) return FALSE;
+
+ PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[3], &vertex[2]);
+
+ if(bDrawMultiPass)
+ {
+ SetSemiTransMulti(1);
+ PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[3], &vertex[2]);
+ }
+
+ if(ubOpaqueDraw)
+ {
+ SetZMask4O();
+ if(bUseMultiPass) SetOpaqueColor(gpuData[0]);
+ DEFOPAQUEON
+ PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[3], &vertex[2]);
+ DEFOPAQUEOFF
+ }
+
+ iDrawnSomething=1;
+
+ return TRUE;
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void primPolyFT3(unsigned char * baseAddr)
+{
+ uint32_t *gpuData = ((uint32_t *) baseAddr);
+ short *sgpuData = ((short *) baseAddr);
+
+ lx0 = sgpuData[2];
+ ly0 = sgpuData[3];
+ lx1 = sgpuData[6];
+ ly1 = sgpuData[7];
+ lx2 = sgpuData[10];
+ ly2 = sgpuData[11];
+
+ if(offset3()) return;
+
+ // do texture UV coordinates stuff
+ gl_ux[0]=gl_ux[3]=baseAddr[8];//gpuData[2]&0xff;
+ gl_vy[0]=gl_vy[3]=baseAddr[9];//(gpuData[2]>>8)&0xff;
+ gl_ux[1]=baseAddr[16];//gpuData[4]&0xff;
+ gl_vy[1]=baseAddr[17];//(gpuData[4]>>8)&0xff;
+ gl_ux[2]=baseAddr[24];//gpuData[6]&0xff;
+ gl_vy[2]=baseAddr[25];//(gpuData[6]>>8)&0xff;
+
+ UpdateGlobalTP((unsigned short)(gpuData[4]>>16));
+ ulClutID=gpuData[2]>>16;
+
+ bDrawTextured = TRUE;
+ bDrawSmoothShaded = FALSE;
+ SetRenderState(gpuData[0]);
+
+ if(iOffscreenDrawing)
+ {
+ offsetPSX3();
+ if(bDrawOffscreen3())
+ {
+ InvalidateTextureAreaEx();
+ SetRenderColor(gpuData[0]);
+ drawPoly3FT(baseAddr);
+ }
+ }
+
+ SetRenderMode(gpuData[0], TRUE);
+ SetZMask3();
+
+ assignTexture3();
+
+ if(!(dwActFixes&0x10))
+ {
+ if(DoLineCheck(gpuData)) return;
+ }
+
+ PRIMdrawTexturedTri(&vertex[0], &vertex[1], &vertex[2]);
+
+ if(bDrawMultiPass)
+ {
+ SetSemiTransMulti(1);
+ PRIMdrawTexturedTri(&vertex[0], &vertex[1], &vertex[2]);
+ }
+
+ if(ubOpaqueDraw)
+ {
+ SetZMask3O();
+ if(bUseMultiPass) SetOpaqueColor(gpuData[0]);
+ DEFOPAQUEON
+ PRIMdrawTexturedTri(&vertex[0], &vertex[1], &vertex[2]);
+ DEFOPAQUEOFF
+ }
+
+ iDrawnSomething=1;
+}
+
+////////////////////////////////////////////////////////////////////////
+// cmd: flat shaded Texture4
+////////////////////////////////////////////////////////////////////////
+
+#define ST_FAC 255.99f
+
+void RectTexAlign(void)
+{
+ int UFlipped = FALSE;
+ int VFlipped = FALSE;
+
+ if(gTexName==gTexFrameName) return;
+
+ if(ly0==ly1)
+ {
+ if(!((lx1==lx3 && ly3==ly2 && lx2==lx0) ||
+ (lx1==lx2 && ly2==ly3 && lx3==lx0)))
+ return;
+
+ if(ly0<ly2)
+ {
+ if (vertex[0].tow > vertex[2].tow)
+ VFlipped = 1;
+ }
+ else
+ {
+ if (vertex[0].tow < vertex[2].tow)
+ VFlipped = 2;
+ }
+ }
+ else
+ if(ly0==ly2)
+ {
+ if(!((lx2==lx3 && ly3==ly1 && lx1==lx0) ||
+ (lx2==lx1 && ly1==ly3 && lx3==lx0)))
+ return;
+
+ if(ly0<ly1)
+ {
+ if (vertex[0].tow > vertex[1].tow)
+ VFlipped = 3;
+ }
+ else
+ {
+ if (vertex[0].tow < vertex[1].tow)
+ VFlipped = 4;
+ }
+ }
+ else
+ if(ly0==ly3)
+ {
+ if(!((lx3==lx2 && ly2==ly1 && lx1==lx0) ||
+ (lx3==lx1 && ly1==ly2 && lx2==lx0)))
+ return;
+
+ if(ly0<ly1)
+ {
+ if (vertex[0].tow > vertex[1].tow)
+ VFlipped = 5;
+ }
+ else
+ {
+ if (vertex[0].tow < vertex[1].tow)
+ VFlipped = 6;
+ }
+ }
+ else return;
+
+ if(lx0==lx1)
+ {
+ if(lx0<lx2)
+ {
+ if (vertex[0].sow > vertex[2].sow)
+ UFlipped = 1;
+ }
+ else
+ {
+ if (vertex[0].sow < vertex[2].sow)
+ UFlipped = 2;
+ }
+ }
+ else
+ if(lx0==lx2)
+ {
+ if(lx0<lx1)
+ {
+ if (vertex[0].sow > vertex[1].sow)
+ UFlipped = 3;
+ }
+ else
+ {
+ if (vertex[0].sow < vertex[1].sow)
+ UFlipped = 4;
+ }
+ }
+ else
+ if(lx0==lx3)
+ {
+ if(lx0<lx1)
+ {
+ if (vertex[0].sow > vertex[1].sow)
+ UFlipped = 5;
+ }
+ else
+ {
+ if (vertex[0].sow < vertex[1].sow)
+ UFlipped = 6;
+ }
+ }
+
+ if (UFlipped)
+ {
+#ifdef OWNSCALE
+ if(bUsingTWin)
+ {
+ switch(UFlipped)
+ {
+ case 1:
+ vertex[2].sow+=0.95f/TWin.UScaleFactor;
+ vertex[3].sow+=0.95f/TWin.UScaleFactor;
+ break;
+ case 2:
+ vertex[0].sow+=0.95f/TWin.UScaleFactor;
+ vertex[1].sow+=0.95f/TWin.UScaleFactor;
+ break;
+ case 3:
+ vertex[1].sow+=0.95f/TWin.UScaleFactor;
+ vertex[3].sow+=0.95f/TWin.UScaleFactor;
+ break;
+ case 4:
+ vertex[0].sow+=0.95f/TWin.UScaleFactor;
+ vertex[2].sow+=0.95f/TWin.UScaleFactor;
+ break;
+ case 5:
+ vertex[1].sow+=0.95f/TWin.UScaleFactor;
+ vertex[2].sow+=0.95f/TWin.UScaleFactor;
+ break;
+ case 6:
+ vertex[0].sow+=0.95f/TWin.UScaleFactor;
+ vertex[3].sow+=0.95f/TWin.UScaleFactor;
+ break;
+ }
+ }
+ else
+ {
+ switch(UFlipped)
+ {
+ case 1:
+ vertex[2].sow+=1.0f/ST_FAC;
+ vertex[3].sow+=1.0f/ST_FAC;
+ break;
+ case 2:
+ vertex[0].sow+=1.0f/ST_FAC;
+ vertex[1].sow+=1.0f/ST_FAC;
+ break;
+ case 3:
+ vertex[1].sow+=1.0f/ST_FAC;
+ vertex[3].sow+=1.0f/ST_FAC;
+ break;
+ case 4:
+ vertex[0].sow+=1.0f/ST_FAC;
+ vertex[2].sow+=1.0f/ST_FAC;
+ break;
+ case 5:
+ vertex[1].sow+=1.0f/ST_FAC;
+ vertex[2].sow+=1.0f/ST_FAC;
+ break;
+ case 6:
+ vertex[0].sow+=1.0f/ST_FAC;
+ vertex[3].sow+=1.0f/ST_FAC;
+ break;
+ }
+ }
+#else
+ if(bUsingTWin)
+ {
+ switch(UFlipped)
+ {
+ case 1:
+ vertex[2].sow+=1.0f/TWin.UScaleFactor;
+ vertex[3].sow+=1.0f/TWin.UScaleFactor;
+ break;
+ case 2:
+ vertex[0].sow+=1.0f/TWin.UScaleFactor;
+ vertex[1].sow+=1.0f/TWin.UScaleFactor;
+ break;
+ case 3:
+ vertex[1].sow+=1.0f/TWin.UScaleFactor;
+ vertex[3].sow+=1.0f/TWin.UScaleFactor;
+ break;
+ case 4:
+ vertex[0].sow+=1.0f/TWin.UScaleFactor;
+ vertex[2].sow+=1.0f/TWin.UScaleFactor;
+ break;
+ case 5:
+ vertex[1].sow+=1.0f/TWin.UScaleFactor;
+ vertex[2].sow+=1.0f/TWin.UScaleFactor;
+ break;
+ case 6:
+ vertex[0].sow+=1.0f/TWin.UScaleFactor;
+ vertex[3].sow+=1.0f/TWin.UScaleFactor;
+ break;
+ }
+ }
+ else
+ {
+ switch(UFlipped)
+ {
+ case 1:
+ vertex[2].sow+=1.0f;
+ vertex[3].sow+=1.0f;
+ break;
+ case 2:
+ vertex[0].sow+=1.0f;
+ vertex[1].sow+=1.0f;
+ break;
+ case 3:
+ vertex[1].sow+=1.0f;
+ vertex[3].sow+=1.0f;
+ break;
+ case 4:
+ vertex[0].sow+=1.0f;
+ vertex[2].sow+=1.0f;
+ break;
+ case 5:
+ vertex[1].sow+=1.0f;
+ vertex[2].sow+=1.0f;
+ break;
+ case 6:
+ vertex[0].sow+=1.0f;
+ vertex[3].sow+=1.0f;
+ break;
+ }
+ }
+#endif
+ }
+
+ if (VFlipped)
+ {
+#ifdef OWNSCALE
+ if(bUsingTWin)
+ {
+ switch(VFlipped)
+ {
+ case 1:
+ vertex[2].tow+=0.95f/TWin.VScaleFactor;
+ vertex[3].tow+=0.95f/TWin.VScaleFactor;
+ break;
+ case 2:
+ vertex[0].tow+=0.95f/TWin.VScaleFactor;
+ vertex[1].tow+=0.95f/TWin.VScaleFactor;
+ break;
+ case 3:
+ vertex[1].tow+=0.95f/TWin.VScaleFactor;
+ vertex[3].tow+=0.95f/TWin.VScaleFactor;
+ break;
+ case 4:
+ vertex[0].tow+=0.95f/TWin.VScaleFactor;
+ vertex[2].tow+=0.95f/TWin.VScaleFactor;
+ break;
+ case 5:
+ vertex[1].tow+=0.95f/TWin.VScaleFactor;
+ vertex[2].tow+=0.95f/TWin.VScaleFactor;
+ break;
+ case 6:
+ vertex[0].tow+=0.95f/TWin.VScaleFactor;
+ vertex[3].tow+=0.95f/TWin.VScaleFactor;
+ break;
+ }
+ }
+ else
+ {
+ switch(VFlipped)
+ {
+ case 1:
+ vertex[2].tow+=1.0f/ST_FAC;
+ vertex[3].tow+=1.0f/ST_FAC;
+ break;
+ case 2:
+ vertex[0].tow+=1.0f/ST_FAC;
+ vertex[1].tow+=1.0f/ST_FAC;
+ break;
+ case 3:
+ vertex[1].tow+=1.0f/ST_FAC;
+ vertex[3].tow+=1.0f/ST_FAC;
+ break;
+ case 4:
+ vertex[0].tow+=1.0f/ST_FAC;
+ vertex[2].tow+=1.0f/ST_FAC;
+ break;
+ case 5:
+ vertex[1].tow+=1.0f/ST_FAC;
+ vertex[2].tow+=1.0f/ST_FAC;
+ break;
+ case 6:
+ vertex[0].tow+=1.0f/ST_FAC;
+ vertex[3].tow+=1.0f/ST_FAC;
+ break;
+ }
+ }
+#else
+ if(bUsingTWin)
+ {
+ switch(VFlipped)
+ {
+ case 1:
+ vertex[2].tow+=1.0f/TWin.VScaleFactor;
+ vertex[3].tow+=1.0f/TWin.VScaleFactor;
+ break;
+ case 2:
+ vertex[0].tow+=1.0f/TWin.VScaleFactor;
+ vertex[1].tow+=1.0f/TWin.VScaleFactor;
+ break;
+ case 3:
+ vertex[1].tow+=1.0f/TWin.VScaleFactor;
+ vertex[3].tow+=1.0f/TWin.VScaleFactor;
+ break;
+ case 4:
+ vertex[0].tow+=1.0f/TWin.VScaleFactor;
+ vertex[2].tow+=1.0f/TWin.VScaleFactor;
+ break;
+ case 5:
+ vertex[1].tow+=1.0f/TWin.VScaleFactor;
+ vertex[2].tow+=1.0f/TWin.VScaleFactor;
+ break;
+ case 6:
+ vertex[0].tow+=1.0f/TWin.VScaleFactor;
+ vertex[3].tow+=1.0f/TWin.VScaleFactor;
+ break;
+ }
+ }
+ else
+ {
+ switch(VFlipped)
+ {
+ case 1:
+ vertex[2].tow+=1.0f;
+ vertex[3].tow+=1.0f;
+ break;
+ case 2:
+ vertex[0].tow+=1.0f;
+ vertex[1].tow+=1.0f;
+ break;
+ case 3:
+ vertex[1].tow+=1.0f;
+ vertex[3].tow+=1.0f;
+ break;
+ case 4:
+ vertex[0].tow+=1.0f;
+ vertex[2].tow+=1.0f;
+ break;
+ case 5:
+ vertex[1].tow+=1.0f;
+ vertex[2].tow+=1.0f;
+ break;
+ case 6:
+ vertex[0].tow+=1.0f;
+ vertex[3].tow+=1.0f;
+ break;
+ }
+ }
+#endif
+ }
+
+}
+
+void primPolyFT4(unsigned char * baseAddr)
+{
+ uint32_t *gpuData = ((uint32_t *)baseAddr);
+ short *sgpuData = ((short *) baseAddr);
+
+ lx0 = sgpuData[2];
+ ly0 = sgpuData[3];
+ lx1 = sgpuData[6];
+ ly1 = sgpuData[7];
+ lx2 = sgpuData[10];
+ ly2 = sgpuData[11];
+ lx3 = sgpuData[14];
+ ly3 = sgpuData[15];
+
+ if(offset4()) return;
+
+ gl_vy[0]=baseAddr[9];//((gpuData[2]>>8)&0xff);
+ gl_vy[1]=baseAddr[17];//((gpuData[4]>>8)&0xff);
+ gl_vy[2]=baseAddr[25];//((gpuData[6]>>8)&0xff);
+ gl_vy[3]=baseAddr[33];//((gpuData[8]>>8)&0xff);
+
+ gl_ux[0]=baseAddr[8];//(gpuData[2]&0xff);
+ gl_ux[1]=baseAddr[16];//(gpuData[4]&0xff);
+ gl_ux[2]=baseAddr[24];//(gpuData[6]&0xff);
+ gl_ux[3]=baseAddr[32];//(gpuData[8]&0xff);
+
+ UpdateGlobalTP((unsigned short)(gpuData[4]>>16));
+ ulClutID=(gpuData[2]>>16);
+
+ bDrawTextured = TRUE;
+ bDrawSmoothShaded = FALSE;
+ SetRenderState(gpuData[0]);
+
+ if(iOffscreenDrawing)
+ {
+ offsetPSX4();
+ if(bDrawOffscreen4())
+ {
+ InvalidateTextureAreaEx();
+ SetRenderColor(gpuData[0]);
+ drawPoly4FT(baseAddr);
+ }
+ }
+
+ SetRenderMode(gpuData[0], TRUE);
+
+ SetZMask4();
+
+ assignTexture4();
+
+ RectTexAlign();
+
+ PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[3], &vertex[2]);
+
+ if(bDrawMultiPass)
+ {
+ SetSemiTransMulti(1);
+ PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[3], &vertex[2]);
+ }
+
+ if(ubOpaqueDraw)
+ {
+ SetZMask4O();
+ if(bUseMultiPass) SetOpaqueColor(gpuData[0]);
+ DEFOPAQUEON
+
+ if(bSmallAlpha && iFilterType<=2)
+ {
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[3], &vertex[2]);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ SetZMask4O();
+ }
+
+ PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[3], &vertex[2]);
+ DEFOPAQUEOFF
+ }
+
+ iDrawnSomething=1;
+}
+
+////////////////////////////////////////////////////////////////////////
+// cmd: smooth shaded Texture3
+////////////////////////////////////////////////////////////////////////
+
+void primPolyGT3(unsigned char *baseAddr)
+{
+ uint32_t *gpuData = ((uint32_t *) baseAddr);
+ short *sgpuData = ((short *) baseAddr);
+
+ lx0 = sgpuData[2];
+ ly0 = sgpuData[3];
+ lx1 = sgpuData[8];
+ ly1 = sgpuData[9];
+ lx2 = sgpuData[14];
+ ly2 = sgpuData[15];
+
+ if(offset3()) return;
+
+ // do texture stuff
+ gl_ux[0]=gl_ux[3]=baseAddr[8];//gpuData[2]&0xff;
+ gl_vy[0]=gl_vy[3]=baseAddr[9];//(gpuData[2]>>8)&0xff;
+ gl_ux[1]=baseAddr[20];//gpuData[5]&0xff;
+ gl_vy[1]=baseAddr[21];//(gpuData[5]>>8)&0xff;
+ gl_ux[2]=baseAddr[32];//gpuData[8]&0xff;
+ gl_vy[2]=baseAddr[33];//(gpuData[8]>>8)&0xff;
+
+ UpdateGlobalTP((unsigned short)(gpuData[5]>>16));
+ ulClutID=(gpuData[2]>>16);
+
+ bDrawTextured = TRUE;
+ bDrawSmoothShaded = TRUE;
+ SetRenderState(gpuData[0]);
+
+ if(iOffscreenDrawing)
+ {
+ offsetPSX3();
+ if(bDrawOffscreen3())
+ {
+ InvalidateTextureAreaEx();
+ drawPoly3GT(baseAddr);
+ }
+ }
+
+ SetRenderMode(gpuData[0], FALSE);
+ SetZMask3();
+
+ assignTexture3();
+
+ if(bDrawNonShaded)
+ {
+ //if(!bUseMultiPass) vertex[0].lcol=DoubleBGR2RGB(gpuData[0]); else vertex[0].lcol=gpuData[0];
+ // eat this...
+ if(bGLBlend) vertex[0].c.lcol=0x7f7f7f;
+ else vertex[0].c.lcol=0xffffff;
+ vertex[0].c.col[3]=ubGloAlpha;
+ SETCOL(vertex[0]);
+
+ PRIMdrawTexturedTri(&vertex[0], &vertex[1], &vertex[2]);
+
+ if(ubOpaqueDraw)
+ {
+ SetZMask3O();
+ DEFOPAQUEON
+ PRIMdrawTexturedTri(&vertex[0], &vertex[1], &vertex[2]);
+ DEFOPAQUEOFF
+ }
+ return;
+ }
+
+ if(!bUseMultiPass && !bGLBlend)
+ {
+ vertex[0].c.lcol=DoubleBGR2RGB(gpuData[0]);
+ vertex[1].c.lcol=DoubleBGR2RGB(gpuData[3]);
+ vertex[2].c.lcol=DoubleBGR2RGB(gpuData[6]);
+ }
+ else
+ {
+ vertex[0].c.lcol=gpuData[0];
+ vertex[1].c.lcol=gpuData[3];
+ vertex[2].c.lcol=gpuData[6];
+ }
+ vertex[0].c.col[3]=vertex[1].c.col[3]=vertex[2].c.col[3]=ubGloAlpha;
+
+ PRIMdrawTexGouraudTriColor(&vertex[0], &vertex[1], &vertex[2]);
+
+ if(bDrawMultiPass)
+ {
+ SetSemiTransMulti(1);
+ PRIMdrawTexGouraudTriColor(&vertex[0], &vertex[1], &vertex[2]);
+ }
+
+ if(ubOpaqueDraw)
+ {
+ SetZMask3O();
+ if(bUseMultiPass)
+ {
+ vertex[0].c.lcol=DoubleBGR2RGB(gpuData[0]);
+ vertex[1].c.lcol=DoubleBGR2RGB(gpuData[3]);
+ vertex[2].c.lcol=DoubleBGR2RGB(gpuData[6]);
+ vertex[0].c.col[3]=vertex[1].c.col[3]=vertex[2].c.col[3]=ubGloAlpha;
+ }
+ DEFOPAQUEON
+ PRIMdrawTexGouraudTriColor(&vertex[0], &vertex[1], &vertex[2]);
+ DEFOPAQUEOFF
+ }
+
+ iDrawnSomething=1;
+}
+
+////////////////////////////////////////////////////////////////////////
+// cmd: smooth shaded Poly3
+////////////////////////////////////////////////////////////////////////
+
+void primPolyG3(unsigned char *baseAddr)
+{
+ uint32_t *gpuData = ((uint32_t *)baseAddr);
+ short *sgpuData = ((short *) baseAddr);
+
+ lx0 = sgpuData[2];
+ ly0 = sgpuData[3];
+ lx1 = sgpuData[6];
+ ly1 = sgpuData[7];
+ lx2 = sgpuData[10];
+ ly2 = sgpuData[11];
+
+ if(offset3()) return;
+
+ bDrawTextured = FALSE;
+ bDrawSmoothShaded = TRUE;
+ SetRenderState(gpuData[0]);
+
+ if(iOffscreenDrawing)
+ {
+ offsetPSX3();
+ if(bDrawOffscreen3())
+ {
+ InvalidateTextureAreaEx();
+ drawPoly3G(gpuData[0], gpuData[2], gpuData[4]);
+ }
+ }
+
+ SetRenderMode(gpuData[0], FALSE);
+ SetZMask3NT();
+
+ vertex[0].c.lcol=gpuData[0];
+ vertex[1].c.lcol=gpuData[2];
+ vertex[2].c.lcol=gpuData[4];
+ vertex[0].c.col[3]=vertex[1].c.col[3]=vertex[2].c.col[3]=ubGloColAlpha;
+
+ PRIMdrawGouraudTriColor(&vertex[0], &vertex[1], &vertex[2]);
+
+ iDrawnSomething=1;
+}
+
+////////////////////////////////////////////////////////////////////////
+// cmd: smooth shaded Texture4
+////////////////////////////////////////////////////////////////////////
+
+void primPolyGT4(unsigned char *baseAddr)
+{
+ uint32_t *gpuData = ((uint32_t *)baseAddr);
+ short *sgpuData = ((short *)baseAddr);
+
+ lx0 = sgpuData[2];
+ ly0 = sgpuData[3];
+ lx1 = sgpuData[8];
+ ly1 = sgpuData[9];
+ lx2 = sgpuData[14];
+ ly2 = sgpuData[15];
+ lx3 = sgpuData[20];
+ ly3 = sgpuData[21];
+
+ if(offset4()) return;
+
+ // do texture stuff
+ gl_ux[0]=baseAddr[8];//gpuData[2]&0xff;
+ gl_vy[0]=baseAddr[9];//(gpuData[2]>>8)&0xff;
+ gl_ux[1]=baseAddr[20];//gpuData[5]&0xff;
+ gl_vy[1]=baseAddr[21];//(gpuData[5]>>8)&0xff;
+ gl_ux[2]=baseAddr[32];//gpuData[8]&0xff;
+ gl_vy[2]=baseAddr[33];//(gpuData[8]>>8)&0xff;
+ gl_ux[3]=baseAddr[44];//gpuData[11]&0xff;
+ gl_vy[3]=baseAddr[45];//(gpuData[11]>>8)&0xff;
+
+ UpdateGlobalTP((unsigned short)(gpuData[5]>>16));
+ ulClutID=(gpuData[2]>>16);
+
+ bDrawTextured = TRUE;
+ bDrawSmoothShaded = TRUE;
+ SetRenderState(gpuData[0]);
+
+ if(iOffscreenDrawing)
+ {
+ offsetPSX4();
+ if(bDrawOffscreen4())
+ {
+ InvalidateTextureAreaEx();
+ drawPoly4GT(baseAddr);
+ }
+ }
+
+ SetRenderMode(gpuData[0], FALSE);
+ SetZMask4();
+
+ assignTexture4();
+
+ RectTexAlign();
+
+ if(bDrawNonShaded)
+ {
+ //if(!bUseMultiPass) vertex[0].lcol=DoubleBGR2RGB(gpuData[0]); else vertex[0].lcol=gpuData[0];
+ if(bGLBlend) vertex[0].c.lcol=0x7f7f7f;
+ else vertex[0].c.lcol=0xffffff;
+ vertex[0].c.col[3]=ubGloAlpha;
+ SETCOL(vertex[0]);
+
+ PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[3], &vertex[2]);
+
+ if(ubOpaqueDraw)
+ {
+ SetZMask4O();
+ ubGloAlpha=ubGloColAlpha=0xff;
+ DEFOPAQUEON
+ PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[3], &vertex[2]);
+ DEFOPAQUEOFF
+ }
+ return;
+ }
+
+ if(!bUseMultiPass && !bGLBlend)
+ {
+ vertex[0].c.lcol=DoubleBGR2RGB(gpuData[0]);
+ vertex[1].c.lcol=DoubleBGR2RGB(gpuData[3]);
+ vertex[2].c.lcol=DoubleBGR2RGB(gpuData[6]);
+ vertex[3].c.lcol=DoubleBGR2RGB(gpuData[9]);
+ }
+ else
+ {
+ vertex[0].c.lcol=gpuData[0];
+ vertex[1].c.lcol=gpuData[3];
+ vertex[2].c.lcol=gpuData[6];
+ vertex[3].c.lcol=gpuData[9];
+ }
+
+ vertex[0].c.col[3]=vertex[1].c.col[3]=vertex[2].c.col[3]=vertex[3].c.col[3]=ubGloAlpha;
+
+ PRIMdrawTexGouraudTriColorQuad(&vertex[0], &vertex[1], &vertex[3],&vertex[2]);
+
+ if(bDrawMultiPass)
+ {
+ SetSemiTransMulti(1);
+ PRIMdrawTexGouraudTriColorQuad(&vertex[0], &vertex[1], &vertex[3],&vertex[2]);
+ }
+
+ if(ubOpaqueDraw)
+ {
+ SetZMask4O();
+ if(bUseMultiPass)
+ {
+ vertex[0].c.lcol=DoubleBGR2RGB(gpuData[0]);
+ vertex[1].c.lcol=DoubleBGR2RGB(gpuData[3]);
+ vertex[2].c.lcol=DoubleBGR2RGB(gpuData[6]);
+ vertex[3].c.lcol=DoubleBGR2RGB(gpuData[9]);
+ vertex[0].c.col[3]=vertex[1].c.col[3]=vertex[2].c.col[3]=vertex[3].c.col[3]=ubGloAlpha;
+ }
+ ubGloAlpha=ubGloColAlpha=0xff;
+ DEFOPAQUEON
+ PRIMdrawTexGouraudTriColorQuad(&vertex[0], &vertex[1], &vertex[3],&vertex[2]);
+ DEFOPAQUEOFF
+ }
+
+ iDrawnSomething=1;
+}
+
+////////////////////////////////////////////////////////////////////////
+// cmd: smooth shaded Poly3
+////////////////////////////////////////////////////////////////////////
+
+void primPolyF3(unsigned char *baseAddr)
+{
+ uint32_t *gpuData = ((uint32_t *) baseAddr);
+ short *sgpuData = ((short *) baseAddr);
+
+ lx0 = sgpuData[2];
+ ly0 = sgpuData[3];
+ lx1 = sgpuData[4];
+ ly1 = sgpuData[5];
+ lx2 = sgpuData[6];
+ ly2 = sgpuData[7];
+
+ if(offset3()) return;
+
+ bDrawTextured = FALSE;
+ bDrawSmoothShaded = FALSE;
+ SetRenderState(gpuData[0]);
+
+ if(iOffscreenDrawing)
+ {
+ offsetPSX3();
+ if(bDrawOffscreen3())
+ {
+ InvalidateTextureAreaEx();
+ drawPoly3F(gpuData[0]);
+ }
+ }
+
+ SetRenderMode(gpuData[0], FALSE);
+ SetZMask3NT();
+
+ vertex[0].c.lcol=gpuData[0];
+ vertex[0].c.col[3]=ubGloColAlpha;
+ SETCOL(vertex[0]);
+
+ PRIMdrawTri(&vertex[0], &vertex[1], &vertex[2]);
+
+ iDrawnSomething=1;
+}
+
+////////////////////////////////////////////////////////////////////////
+// cmd: skipping shaded polylines
+////////////////////////////////////////////////////////////////////////
+
+void primLineGSkip(unsigned char *baseAddr)
+{
+ uint32_t *gpuData = ((uint32_t *) baseAddr);
+ short *sgpuData = ((short *) baseAddr);
+ int iMax=255;
+ int i=2;
+
+ lx1 = sgpuData[2];
+ ly1 = sgpuData[3];
+
+ while(!(((gpuData[i] & 0xF000F000) == 0x50005000) && i>=4))
+ {
+ i++;
+
+ ly1 = (short)((gpuData[i]>>16) & 0xffff);
+ lx1 = (short)(gpuData[i] & 0xffff);
+
+ i++;if(i>iMax) break;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+// cmd: shaded polylines
+////////////////////////////////////////////////////////////////////////
+
+void primLineGEx(unsigned char *baseAddr)
+{
+ uint32_t *gpuData = ((uint32_t *) baseAddr);
+ int iMax=255;
+ short cx0,cx1,cy0,cy1;int i;BOOL bDraw=TRUE;
+
+ bDrawTextured = FALSE;
+ bDrawSmoothShaded = TRUE;
+ SetRenderState(gpuData[0]);
+ SetRenderMode(gpuData[0], FALSE);
+ SetZMask4NT();
+
+ vertex[0].c.lcol=vertex[3].c.lcol=gpuData[0];
+ vertex[0].c.col[3]=vertex[3].c.col[3]=ubGloColAlpha;
+ ly1 = (short)((gpuData[1]>>16) & 0xffff);
+ lx1 = (short)(gpuData[1] & 0xffff);
+
+ i=2;
+
+ //while((gpuData[i]>>24)!=0x55)
+ //while((gpuData[i]&0x50000000)!=0x50000000)
+ // currently best way to check for poly line end:
+ while(!(((gpuData[i] & 0xF000F000) == 0x50005000) && i>=4))
+ {
+ ly0 = ly1;lx0=lx1;
+ vertex[1].c.lcol=vertex[2].c.lcol=vertex[0].c.lcol;
+ vertex[0].c.lcol=vertex[3].c.lcol=gpuData[i];
+ vertex[0].c.col[3]=vertex[3].c.col[3]=ubGloColAlpha;
+
+ i++;
+
+ ly1 = (short)((gpuData[i]>>16) & 0xffff);
+ lx1 = (short)(gpuData[i] & 0xffff);
+
+ if(offsetline()) bDraw=FALSE; else bDraw=TRUE;
+
+ if (bDraw && ((lx0 != lx1) || (ly0 != ly1)))
+ {
+ if(iOffscreenDrawing)
+ {
+ cx0=lx0;cx1=lx1;cy0=ly0;cy1=ly1;
+ offsetPSXLine();
+ if(bDrawOffscreen4())
+ {
+ InvalidateTextureAreaEx();
+ drawPoly4G(gpuData[i-3],gpuData[i-1],gpuData[i-3],gpuData[i-1]);
+ }
+ lx0=cx0;lx1=cx1;ly0=cy0;ly1=cy1;
+ }
+
+ PRIMdrawGouraudLine(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);
+ }
+ i++;
+
+ if(i>iMax) break;
+ }
+
+ iDrawnSomething=1;
+}
+
+////////////////////////////////////////////////////////////////////////
+// cmd: shaded polyline2
+////////////////////////////////////////////////////////////////////////
+
+void primLineG2(unsigned char *baseAddr)
+{
+ uint32_t *gpuData = ((uint32_t *) baseAddr);
+ short *sgpuData = ((short *) baseAddr);
+
+ lx0 = sgpuData[2];
+ ly0 = sgpuData[3];
+ lx1 = sgpuData[6];
+ ly1 = sgpuData[7];
+
+ vertex[0].c.lcol=vertex[3].c.lcol=gpuData[0];
+ vertex[1].c.lcol=vertex[2].c.lcol=gpuData[2];
+ vertex[0].c.col[3]=vertex[1].c.col[3]=vertex[2].c.col[3]=vertex[3].c.col[3]=ubGloColAlpha;
+
+ bDrawTextured = FALSE;
+ bDrawSmoothShaded = TRUE;
+
+ if((lx0 == lx1) && (ly0 == ly1)) return;
+
+ if(offsetline()) return;
+
+ SetRenderState(gpuData[0]);
+ SetRenderMode(gpuData[0], FALSE);
+ SetZMask4NT();
+
+ if(iOffscreenDrawing)
+ {
+ offsetPSXLine();
+ if(bDrawOffscreen4())
+ {
+ InvalidateTextureAreaEx();
+ drawPoly4G(gpuData[0],gpuData[2],gpuData[0],gpuData[2]);
+ }
+ }
+
+ //if(ClipVertexList4())
+ PRIMdrawGouraudLine(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);
+
+ iDrawnSomething=1;
+}
+
+////////////////////////////////////////////////////////////////////////
+// cmd: skipping flat polylines
+////////////////////////////////////////////////////////////////////////
+
+void primLineFSkip(unsigned char *baseAddr)
+{
+ uint32_t *gpuData = ((uint32_t *) baseAddr);
+ int i=2,iMax=255;
+
+ ly1 = (short)((gpuData[1]>>16) & 0xffff);
+ lx1 = (short)(gpuData[1] & 0xffff);
+
+ while(!(((gpuData[i] & 0xF000F000) == 0x50005000) && i>=3))
+ {
+ ly1 = (short)((gpuData[i]>>16) & 0xffff);
+ lx1 = (short)(gpuData[i] & 0xffff);
+ i++;if(i>iMax) break;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+// cmd: drawing flat polylines
+////////////////////////////////////////////////////////////////////////
+
+void primLineFEx(unsigned char *baseAddr)
+{
+ uint32_t *gpuData = ((uint32_t *) baseAddr);
+ int iMax;
+ short cx0,cx1,cy0,cy1;int i;
+
+ iMax=255;
+
+ bDrawTextured = FALSE;
+ bDrawSmoothShaded = FALSE;
+ SetRenderState(gpuData[0]);
+ SetRenderMode(gpuData[0], FALSE);
+ SetZMask4NT();
+
+ vertex[0].c.lcol=gpuData[0];
+ vertex[0].c.col[3]=ubGloColAlpha;
+
+ ly1 = (short)((gpuData[1]>>16) & 0xffff);
+ lx1 = (short)(gpuData[1] & 0xffff);
+
+ i=2;
+
+// while(!(gpuData[i]&0x40000000))
+// while((gpuData[i]>>24)!=0x55)
+// while((gpuData[i]&0x50000000)!=0x50000000)
+// currently best way to check for poly line end:
+ while(!(((gpuData[i] & 0xF000F000) == 0x50005000) && i>=3))
+ {
+ ly0 = ly1;lx0=lx1;
+ ly1 = (short)((gpuData[i]>>16) & 0xffff);
+ lx1 = (short)(gpuData[i] & 0xffff);
+
+ if(!offsetline())
+ {
+ if(iOffscreenDrawing)
+ {
+ cx0=lx0;cx1=lx1;cy0=ly0;cy1=ly1;
+ offsetPSXLine();
+ if(bDrawOffscreen4())
+ {
+ InvalidateTextureAreaEx();
+ drawPoly4F(gpuData[0]);
+ }
+ lx0=cx0;lx1=cx1;ly0=cy0;ly1=cy1;
+ }
+ PRIMdrawFlatLine(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);
+ }
+
+ i++;if(i>iMax) break;
+ }
+
+ iDrawnSomething=1;
+}
+
+////////////////////////////////////////////////////////////////////////
+// cmd: drawing flat polyline2
+////////////////////////////////////////////////////////////////////////
+
+void primLineF2(unsigned char *baseAddr)
+{
+ uint32_t *gpuData = ((uint32_t *) baseAddr);
+ short *sgpuData = ((short *) baseAddr);
+
+ lx0 = sgpuData[2];
+ ly0 = sgpuData[3];
+ lx1 = sgpuData[4];
+ ly1 = sgpuData[5];
+
+ if(offsetline()) return;
+
+ bDrawTextured = FALSE;
+ bDrawSmoothShaded = FALSE;
+ SetRenderState(gpuData[0]);
+ SetRenderMode(gpuData[0], FALSE);
+ SetZMask4NT();
+
+ vertex[0].c.lcol=gpuData[0];
+ vertex[0].c.col[3]=ubGloColAlpha;
+
+ if(iOffscreenDrawing)
+ {
+ offsetPSXLine();
+ if(bDrawOffscreen4())
+ {
+ InvalidateTextureAreaEx();
+ drawPoly4F(gpuData[0]);
+ }
+ }
+
+ //if(ClipVertexList4())
+ PRIMdrawFlatLine(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);
+
+ iDrawnSomething=1;
+}
+
+////////////////////////////////////////////////////////////////////////
+// cmd: well, easiest command... not implemented
+////////////////////////////////////////////////////////////////////////
+
+void primNI(unsigned char *bA)
+{
+}
+
+////////////////////////////////////////////////////////////////////////
+// cmd func ptr table
+////////////////////////////////////////////////////////////////////////
+
+void (*primTableJ[256])(unsigned char *) =
+{
+ // 00
+ primNI,primNI,primBlkFill,primNI,primNI,primNI,primNI,primNI,
+ // 08
+ primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
+ // 10
+ primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
+ // 18
+ primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
+ // 20
+ primPolyF3,primPolyF3,primPolyF3,primPolyF3,primPolyFT3,primPolyFT3,primPolyFT3,primPolyFT3,
+ // 28
+ primPolyF4,primPolyF4,primPolyF4,primPolyF4,primPolyFT4,primPolyFT4,primPolyFT4,primPolyFT4,
+ // 30
+ primPolyG3,primPolyG3,primPolyG3,primPolyG3,primPolyGT3,primPolyGT3,primPolyGT3,primPolyGT3,
+ // 38
+ primPolyG4,primPolyG4,primPolyG4,primPolyG4,primPolyGT4,primPolyGT4,primPolyGT4,primPolyGT4,
+ // 40
+ primLineF2,primLineF2,primLineF2,primLineF2,primNI,primNI,primNI,primNI,
+ // 48
+ primLineFEx,primLineFEx,primLineFEx,primLineFEx,primLineFEx,primLineFEx,primLineFEx,primLineFEx,
+ // 50
+ primLineG2,primLineG2,primLineG2,primLineG2,primNI,primNI,primNI,primNI,
+ // 58
+ primLineGEx,primLineGEx,primLineGEx,primLineGEx,primLineGEx,primLineGEx,primLineGEx,primLineGEx,
+ // 60
+ primTileS,primTileS,primTileS,primTileS,primSprtS,primSprtS,primSprtS,primSprtS,
+ // 68
+ primTile1,primTile1,primTile1,primTile1,primNI,primNI,primNI,primNI,
+ // 70
+ primTile8,primTile8,primTile8,primTile8,primSprt8,primSprt8,primSprt8,primSprt8,
+ // 78
+ primTile16,primTile16,primTile16,primTile16,primSprt16,primSprt16,primSprt16,primSprt16,
+ // 80
+ primMoveImage,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
+ // 88
+ primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
+ // 90
+ primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
+ // 98
+ primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
+ // a0
+ primLoadImage,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
+ // a8
+ primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
+ // b0
+ primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
+ // b8
+ primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
+ // c0
+ primStoreImage,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
+ // c8
+ primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
+ // d0
+ primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
+ // d8
+ primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
+ // e0
+ primNI,cmdTexturePage,cmdTextureWindow,cmdDrawAreaStart,cmdDrawAreaEnd,cmdDrawOffset,cmdSTP,primNI,
+ // e8
+ primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
+ // f0
+ primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
+ // f8
+ primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI
+};
+
+////////////////////////////////////////////////////////////////////////
+// cmd func ptr table for skipping
+////////////////////////////////////////////////////////////////////////
+
+void (*primTableSkip[256])(unsigned char *) =
+{
+ // 00
+ primNI,primNI,primBlkFill,primNI,primNI,primNI,primNI,primNI,
+ // 08
+ primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
+ // 10
+ primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
+ // 18
+ primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
+ // 20
+ primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
+ // 28
+ primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
+ // 30
+ primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
+ // 38
+ primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
+ // 40
+ primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
+ // 48
+ primLineFSkip,primLineFSkip,primLineFSkip,primLineFSkip,primLineFSkip,primLineFSkip,primLineFSkip,primLineFSkip,
+ // 50
+ primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
+ // 58
+ primLineGSkip,primLineGSkip,primLineGSkip,primLineGSkip,primLineGSkip,primLineGSkip,primLineGSkip,primLineGSkip,
+ // 60
+ primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
+ // 68
+ primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
+ // 70
+ primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
+ // 78
+ primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
+ // 80
+ primMoveImage,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
+ // 88
+ primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
+ // 90
+ primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
+ // 98
+ primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
+ // a0
+ primLoadImage,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
+ // a8
+ primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
+ // b0
+ primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
+ // b8
+ primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
+ // c0
+ primStoreImage,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
+ // c8
+ primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
+ // d0
+ primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
+ // d8
+ primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
+ // e0
+ primNI,cmdTexturePage,cmdTextureWindow,cmdDrawAreaStart,cmdDrawAreaEnd,cmdDrawOffset,cmdSTP,primNI,
+ // e8
+ primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
+ // f0
+ primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
+ // f8
+ primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI
+};
diff --git a/plugins/peopsxgl/soft.c b/plugins/peopsxgl/soft.c index 1ab93f07..9f10a2a0 100644 --- a/plugins/peopsxgl/soft.c +++ b/plugins/peopsxgl/soft.c @@ -1,8409 +1,8407 @@ -/*************************************************************************** - soft.c - description - ------------------- - begin : Sun Oct 28 2001 - copyright : (C) 2001 by Pete Bernert - web : www.pbernert.com - ***************************************************************************/ - -/*************************************************************************** - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. See also the license.txt file for * - * additional informations. * - * * - ***************************************************************************/ - -#include "stdafx.h" - -#define _IN_SOFT - -#include "externals.h" -#include "soft.h" - -int iDither = 0; - -//////////////////////////////////////////////////////////////////////////////////// -// "NO EDGE BUFFER" POLY VERSION... FUNCS BASED ON FATMAP.TXT FROM MRI / Doomsday -//////////////////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////////////////// -// defines -//////////////////////////////////////////////////////////////////////////////////// - -// switches for painting textured quads as 2 triangles (small glitches, but better shading!) -// can be toggled by game fix 0x200 in version 1.17 anyway, so let the defines enabled! - -#define POLYQUAD3 -#define POLYQUAD3GT - -// fast solid loops... a bit more additional code, of course - -#define FASTSOLID - -// psx blending mode 3 with 25% incoming color (instead 50% without the define) - -#define HALFBRIGHTMODE3 - -// color decode defines - -#define XCOL1(x) (x & 0x1f) -#define XCOL2(x) (x & 0x3e0) -#define XCOL3(x) (x & 0x7c00) - -#define XCOL1D(x) (x & 0x1f) -#define XCOL2D(x) ((x>>5) & 0x1f) -#define XCOL3D(x) ((x>>10) & 0x1f) - -#define X32TCOL1(x) ((x & 0x001f001f)<<7) -#define X32TCOL2(x) ((x & 0x03e003e0)<<2) -#define X32TCOL3(x) ((x & 0x7c007c00)>>3) - -#define X32COL1(x) (x & 0x001f001f) -#define X32COL2(x) ((x>>5) & 0x001f001f) -#define X32COL3(x) ((x>>10) & 0x001f001f) - -#define X32ACOL1(x) (x & 0x001e001e) -#define X32ACOL2(x) ((x>>5) & 0x001e001e) -#define X32ACOL3(x) ((x>>10) & 0x001e001e) - -#define X32BCOL1(x) (x & 0x001c001c) -#define X32BCOL2(x) ((x>>5) & 0x001c001c) -#define X32BCOL3(x) ((x>>10) & 0x001c001c) - -#define X32PSXCOL(r,g,b) ((g<<10)|(b<<5)|r) - -#define XPSXCOL(r,g,b) ((g&0x7c00)|(b&0x3e0)|(r&0x1f)) - -//////////////////////////////////////////////////////////////////////////////////// -// soft globals -//////////////////////////////////////////////////////////////////////////////////// - -short g_m1 = 255, g_m2 = 255, g_m3 = 255; -short DrawSemiTrans = FALSE; -short Ymin; -short Ymax; - -short ly0, lx0, ly1, lx1, ly2, lx2, ly3, lx3; // global psx vertex coords -int GlobalTextAddrX, GlobalTextAddrY, GlobalTextTP; -int GlobalTextREST, GlobalTextABR, GlobalTextPAGE; - -//////////////////////////////////////////////////////////////////////// -// POLYGON OFFSET FUNCS -//////////////////////////////////////////////////////////////////////// - -void offsetPSXLine(void) -{ - short x0,x1,y0,y1,dx,dy;float px,py; - - x0 = lx0+1+PSXDisplay.DrawOffset.x; - x1 = lx1+1+PSXDisplay.DrawOffset.x; - y0 = ly0+1+PSXDisplay.DrawOffset.y; - y1 = ly1+1+PSXDisplay.DrawOffset.y; - - dx=x1-x0; - dy=y1-y0; - - // tricky line width without sqrt - - if(dx>=0) - { - if(dy>=0) - { - px=0.5f; - if(dx>dy) py=-0.5f; - else if(dx<dy) py= 0.5f; - else py= 0.0f; - } - else - { - py=-0.5f; - dy=-dy; - if(dx>dy) px= 0.5f; - else if(dx<dy) px=-0.5f; - else px= 0.0f; - } - } - else - { - if(dy>=0) - { - py=0.5f; - dx=-dx; - if(dx>dy) px=-0.5f; - else if(dx<dy) px= 0.5f; - else px= 0.0f; - } - else - { - px=-0.5f; - if(dx>dy) py=-0.5f; - else if(dx<dy) py= 0.5f; - else py= 0.0f; - } - } - - lx0=(short)((float)x0-px); - lx3=(short)((float)x0+py); - - ly0=(short)((float)y0-py); - ly3=(short)((float)y0-px); - - lx1=(short)((float)x1-py); - lx2=(short)((float)x1+px); - - ly1=(short)((float)y1+px); - ly2=(short)((float)y1+py); -} - -void offsetPSX2(void) -{ - lx0 += PSXDisplay.DrawOffset.x; - ly0 += PSXDisplay.DrawOffset.y; - lx1 += PSXDisplay.DrawOffset.x; - ly1 += PSXDisplay.DrawOffset.y; -} - -void offsetPSX3(void) -{ - lx0 += PSXDisplay.DrawOffset.x; - ly0 += PSXDisplay.DrawOffset.y; - lx1 += PSXDisplay.DrawOffset.x; - ly1 += PSXDisplay.DrawOffset.y; - lx2 += PSXDisplay.DrawOffset.x; - ly2 += PSXDisplay.DrawOffset.y; -} - -void offsetPSX4(void) -{ - lx0 += PSXDisplay.DrawOffset.x; - ly0 += PSXDisplay.DrawOffset.y; - lx1 += PSXDisplay.DrawOffset.x; - ly1 += PSXDisplay.DrawOffset.y; - lx2 += PSXDisplay.DrawOffset.x; - ly2 += PSXDisplay.DrawOffset.y; - lx3 += PSXDisplay.DrawOffset.x; - ly3 += PSXDisplay.DrawOffset.y; -} - -///////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////// -// PER PIXEL FUNCS -//////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////// - - -unsigned char dithertable[16] = -{ - 7, 0, 6, 1, - 2, 5, 3, 4, - 1, 6, 0, 7, - 4, 3, 5, 2 -}; - -static void Dither16(unsigned short *pdest, uint32_t r, uint32_t g, uint32_t b, unsigned short sM) -{ - unsigned char coeff; - unsigned char rlow, glow, blow; - int x, y; - - x = pdest - psxVuw; - y = x >> 10; - x -= (y << 10); - - coeff = dithertable[(y&3)*4+(x&3)]; - - rlow = r&7; glow = g&7; blow = b&7; - - r>>=3; g>>=3; b>>=3; - - if ((r < 0x1F) && rlow > coeff) r++; - if ((g < 0x1F) && glow > coeff) g++; - if ((b < 0x1F) && blow > coeff) b++; - - *pdest=((unsigned short)b<<10) | - ((unsigned short)g<<5) | - (unsigned short)r | sM; -} - -///////////////////////////////////////////////////////////////// - -static __inline void GetShadeTransCol_Dither(unsigned short *pdest, int m1, int m2, int m3) -{ - int r,g,b; - - if (bCheckMask && *pdest & 0x8000) return; - - if (DrawSemiTrans) - { - r=((XCOL1D(*pdest))<<3); - b=((XCOL2D(*pdest))<<3); - g=((XCOL3D(*pdest))<<3); - - if(GlobalTextABR==0) - { - r=(r>>1)+(m1>>1); - b=(b>>1)+(m2>>1); - g=(g>>1)+(m3>>1); - } - else - if(GlobalTextABR==1) - { - r+=m1; - b+=m2; - g+=m3; - } - else - if(GlobalTextABR==2) - { - r-=m1; - b-=m2; - g-=m3; - if(r&0x80000000) r=0; - if(b&0x80000000) b=0; - if(g&0x80000000) g=0; - } - else - { -#ifdef HALFBRIGHTMODE3 - r+=(m1>>2); - b+=(m2>>2); - g+=(m3>>2); -#else - r+=(m1>>1); - b+=(m2>>1); - g+=(m3>>1); -#endif - } - } - else - { - r=m1; - b=m2; - g=m3; - } - - if(r&0x7FFFFF00) r=0xff; - if(b&0x7FFFFF00) b=0xff; - if(g&0x7FFFFF00) g=0xff; - - Dither16(pdest,r,b,g,sSetMask); -} - -//////////////////////////////////////////////////////////////////////// - -static __inline void GetShadeTransCol(unsigned short * pdest,unsigned short color) -{ - if(bCheckMask && *pdest&0x8000) return; - - if(DrawSemiTrans) - { - int r,g,b; - - if(GlobalTextABR==0) - { - *pdest=((((*pdest)&0x7bde)>>1)+(((color)&0x7bde)>>1))|sSetMask;//0x8000; - return; -/* - r=(XCOL1(*pdest)>>1)+((XCOL1(color))>>1); - b=(XCOL2(*pdest)>>1)+((XCOL2(color))>>1); - g=(XCOL3(*pdest)>>1)+((XCOL3(color))>>1); -*/ - } - else - if(GlobalTextABR==1) - { - r=(XCOL1(*pdest))+((XCOL1(color))); - b=(XCOL2(*pdest))+((XCOL2(color))); - g=(XCOL3(*pdest))+((XCOL3(color))); - } - else - if(GlobalTextABR==2) - { - r=(XCOL1(*pdest))-((XCOL1(color))); - b=(XCOL2(*pdest))-((XCOL2(color))); - g=(XCOL3(*pdest))-((XCOL3(color))); - if(r&0x80000000) r=0; - if(b&0x80000000) b=0; - if(g&0x80000000) g=0; - } - else - { -#ifdef HALFBRIGHTMODE3 - r=(XCOL1(*pdest))+((XCOL1(color))>>2); - b=(XCOL2(*pdest))+((XCOL2(color))>>2); - g=(XCOL3(*pdest))+((XCOL3(color))>>2); -#else - r=(XCOL1(*pdest))+((XCOL1(color))>>1); - b=(XCOL2(*pdest))+((XCOL2(color))>>1); - g=(XCOL3(*pdest))+((XCOL3(color))>>1); -#endif - } - - if(r&0x7FFFFFE0) r=0x1f; - if(b&0x7FFFFC00) b=0x3e0; - if(g&0x7FFF8000) g=0x7c00; - - *pdest=(XPSXCOL(r,g,b))|sSetMask;//0x8000; - } - else *pdest=color|sSetMask; -} - -//////////////////////////////////////////////////////////////////////// - -static __inline void GetShadeTransCol32(uint32_t *pdest, uint32_t color) -{ - if (DrawSemiTrans) - { - int r,g,b; - - if(GlobalTextABR==0) - { - if(!bCheckMask) - { - *pdest=((((*pdest)&0x7bde7bde)>>1)+(((color)&0x7bde7bde)>>1))|lSetMask;//0x80008000; - return; - } - r=(X32ACOL1(*pdest)>>1)+((X32ACOL1(color))>>1); - b=(X32ACOL2(*pdest)>>1)+((X32ACOL2(color))>>1); - g=(X32ACOL3(*pdest)>>1)+((X32ACOL3(color))>>1); - } - else - if(GlobalTextABR==1) - { - r=(X32COL1(*pdest))+((X32COL1(color))); - b=(X32COL2(*pdest))+((X32COL2(color))); - g=(X32COL3(*pdest))+((X32COL3(color))); - } - else - if(GlobalTextABR==2) - { - int sr,sb,sg,src,sbc,sgc,c; - src=XCOL1(color);sbc=XCOL2(color);sgc=XCOL3(color); - c=(*pdest)>>16; - sr=(XCOL1(c))-src; if(sr&0x8000) sr=0; - sb=(XCOL2(c))-sbc; if(sb&0x8000) sb=0; - sg=(XCOL3(c))-sgc; if(sg&0x8000) sg=0; - r=((int)sr)<<16;b=((int)sb)<<11;g=((int)sg)<<6; - c=LOWORD(*pdest); - sr=(XCOL1(c))-src; if(sr&0x8000) sr=0; - sb=(XCOL2(c))-sbc; if(sb&0x8000) sb=0; - sg=(XCOL3(c))-sgc; if(sg&0x8000) sg=0; - r|=sr;b|=sb>>5;g|=sg>>10; - } - else - { -#ifdef HALFBRIGHTMODE3 - r=(X32COL1(*pdest))+((X32BCOL1(color))>>2); - b=(X32COL2(*pdest))+((X32BCOL2(color))>>2); - g=(X32COL3(*pdest))+((X32BCOL3(color))>>2); -#else - r=(X32COL1(*pdest))+((X32ACOL1(color))>>1); - b=(X32COL2(*pdest))+((X32ACOL2(color))>>1); - g=(X32COL3(*pdest))+((X32ACOL3(color))>>1); -#endif - } - - if(r&0x7FE00000) r=0x1f0000|(r&0xFFFF); - if(r&0x7FE0) r=0x1f |(r&0xFFFF0000); - if(b&0x7FE00000) b=0x1f0000|(b&0xFFFF); - if(b&0x7FE0) b=0x1f |(b&0xFFFF0000); - if(g&0x7FE00000) g=0x1f0000|(g&0xFFFF); - if(g&0x7FE0) g=0x1f |(g&0xFFFF0000); - - if(bCheckMask) - { - uint32_t ma=*pdest; - *pdest=(X32PSXCOL(r,g,b))|lSetMask;//0x80008000; - if(ma&0x80000000) *pdest=(ma&0xFFFF0000)|(*pdest&0xFFFF); - if(ma&0x00008000) *pdest=(ma&0xFFFF) |(*pdest&0xFFFF0000); - return; - } - *pdest=(X32PSXCOL(r,g,b))|lSetMask;//0x80008000; - } - else - { - if(bCheckMask) - { - uint32_t ma=*pdest; - *pdest=color|lSetMask;//0x80008000; - if(ma&0x80000000) *pdest=(ma&0xFFFF0000)|(*pdest&0xFFFF); - if(ma&0x00008000) *pdest=(ma&0xFFFF) |(*pdest&0xFFFF0000); - return; - } - - *pdest=color|lSetMask;//0x80008000; - } -} - -//////////////////////////////////////////////////////////////////////// - -static __inline void GetTextureTransColG(unsigned short * pdest,unsigned short color) -{ - int r,g,b;unsigned short l; - - if(color==0) return; - - if(bCheckMask && *pdest&0x8000) return; - - l=sSetMask|(color&0x8000); - - if(DrawSemiTrans && (color&0x8000)) - { - if(GlobalTextABR==0) - { - unsigned short d; - d =((*pdest)&0x7bde)>>1; - color =((color) &0x7bde)>>1; - r=(XCOL1(d))+((((XCOL1(color)))* g_m1)>>7); - b=(XCOL2(d))+((((XCOL2(color)))* g_m2)>>7); - g=(XCOL3(d))+((((XCOL3(color)))* g_m3)>>7); - -/* - r=(XCOL1(*pdest)>>1)+((((XCOL1(color))>>1)* g_m1)>>7); - b=(XCOL2(*pdest)>>1)+((((XCOL2(color))>>1)* g_m2)>>7); - g=(XCOL3(*pdest)>>1)+((((XCOL3(color))>>1)* g_m3)>>7); -*/ - } - else - if(GlobalTextABR==1) - { - r=(XCOL1(*pdest))+((((XCOL1(color)))* g_m1)>>7); - b=(XCOL2(*pdest))+((((XCOL2(color)))* g_m2)>>7); - g=(XCOL3(*pdest))+((((XCOL3(color)))* g_m3)>>7); - } - else - if(GlobalTextABR==2) - { - r=(XCOL1(*pdest))-((((XCOL1(color)))* g_m1)>>7); - b=(XCOL2(*pdest))-((((XCOL2(color)))* g_m2)>>7); - g=(XCOL3(*pdest))-((((XCOL3(color)))* g_m3)>>7); - if(r&0x80000000) r=0; - if(b&0x80000000) b=0; - if(g&0x80000000) g=0; - } - else - { -#ifdef HALFBRIGHTMODE3 - r=(XCOL1(*pdest))+((((XCOL1(color))>>2)* g_m1)>>7); - b=(XCOL2(*pdest))+((((XCOL2(color))>>2)* g_m2)>>7); - g=(XCOL3(*pdest))+((((XCOL3(color))>>2)* g_m3)>>7); -#else - r=(XCOL1(*pdest))+((((XCOL1(color))>>1)* g_m1)>>7); - b=(XCOL2(*pdest))+((((XCOL2(color))>>1)* g_m2)>>7); - g=(XCOL3(*pdest))+((((XCOL3(color))>>1)* g_m3)>>7); -#endif - } - } - else - { - r=((XCOL1(color))* g_m1)>>7; - b=((XCOL2(color))* g_m2)>>7; - g=((XCOL3(color))* g_m3)>>7; - } - - if(r&0x7FFFFFE0) r=0x1f; - if(b&0x7FFFFC00) b=0x3e0; - if(g&0x7FFF8000) g=0x7c00; - - *pdest=(XPSXCOL(r,g,b))|l; -} - -//////////////////////////////////////////////////////////////////////// - -static __inline void GetTextureTransColG_S(unsigned short * pdest,unsigned short color) -{ - int r,g,b;unsigned short l; - - if(color==0) return; - - l=sSetMask|(color&0x8000); - - r=((XCOL1(color))* g_m1)>>7; - b=((XCOL2(color))* g_m2)>>7; - g=((XCOL3(color))* g_m3)>>7; - - if(r&0x7FFFFFE0) r=0x1f; - if(b&0x7FFFFC00) b=0x3e0; - if(g&0x7FFF8000) g=0x7c00; - - *pdest=(XPSXCOL(r,g,b))|l; -} - - -//////////////////////////////////////////////////////////////////////// - -static __inline void GetTextureTransColG_SPR(unsigned short * pdest,unsigned short color) -{ - int r,g,b;unsigned short l; - - if(color==0) return; - - if(bCheckMask && *pdest&0x8000) return; - - l=sSetMask|(color&0x8000); - - if(DrawSemiTrans && (color&0x8000)) - { - if(GlobalTextABR==0) - { - unsigned short d; - d =((*pdest)&0x7bde)>>1; - color =((color) &0x7bde)>>1; - r=(XCOL1(d))+((((XCOL1(color)))* g_m1)>>7); - b=(XCOL2(d))+((((XCOL2(color)))* g_m2)>>7); - g=(XCOL3(d))+((((XCOL3(color)))* g_m3)>>7); - -/* - r=(XCOL1(*pdest)>>1)+((((XCOL1(color))>>1)* g_m1)>>7); - b=(XCOL2(*pdest)>>1)+((((XCOL2(color))>>1)* g_m2)>>7); - g=(XCOL3(*pdest)>>1)+((((XCOL3(color))>>1)* g_m3)>>7); -*/ - } - else - if(GlobalTextABR==1) - { - r=(XCOL1(*pdest))+((((XCOL1(color)))* g_m1)>>7); - b=(XCOL2(*pdest))+((((XCOL2(color)))* g_m2)>>7); - g=(XCOL3(*pdest))+((((XCOL3(color)))* g_m3)>>7); - } - else - if(GlobalTextABR==2) - { - r=(XCOL1(*pdest))-((((XCOL1(color)))* g_m1)>>7); - b=(XCOL2(*pdest))-((((XCOL2(color)))* g_m2)>>7); - g=(XCOL3(*pdest))-((((XCOL3(color)))* g_m3)>>7); - if(r&0x80000000) r=0; - if(b&0x80000000) b=0; - if(g&0x80000000) g=0; - } - else - { -#ifdef HALFBRIGHTMODE3 - r=(XCOL1(*pdest))+((((XCOL1(color))>>2)* g_m1)>>7); - b=(XCOL2(*pdest))+((((XCOL2(color))>>2)* g_m2)>>7); - g=(XCOL3(*pdest))+((((XCOL3(color))>>2)* g_m3)>>7); -#else - r=(XCOL1(*pdest))+((((XCOL1(color))>>1)* g_m1)>>7); - b=(XCOL2(*pdest))+((((XCOL2(color))>>1)* g_m2)>>7); - g=(XCOL3(*pdest))+((((XCOL3(color))>>1)* g_m3)>>7); -#endif - } - } - else - { - r=((XCOL1(color))* g_m1)>>7; - b=((XCOL2(color))* g_m2)>>7; - g=((XCOL3(color))* g_m3)>>7; - } - - if(r&0x7FFFFFE0) r=0x1f; - if(b&0x7FFFFC00) b=0x3e0; - if(g&0x7FFF8000) g=0x7c00; - - *pdest=(XPSXCOL(r,g,b))|l; -} - -//////////////////////////////////////////////////////////////////////// - -static __inline void GetTextureTransColG32(uint32_t *pdest, uint32_t color) -{ - int r,g,b,l; - - if(color==0) return; - - l=lSetMask|(color&0x80008000); - - if(DrawSemiTrans && (color&0x80008000)) - { - if(GlobalTextABR==0) - { - r=((((X32TCOL1(*pdest))+((X32COL1(color)) * g_m1))&0xFF00FF00)>>8); - b=((((X32TCOL2(*pdest))+((X32COL2(color)) * g_m2))&0xFF00FF00)>>8); - g=((((X32TCOL3(*pdest))+((X32COL3(color)) * g_m3))&0xFF00FF00)>>8); - } - else - if(GlobalTextABR==1) - { - r=(X32COL1(*pdest))+(((((X32COL1(color)))* g_m1)&0xFF80FF80)>>7); - b=(X32COL2(*pdest))+(((((X32COL2(color)))* g_m2)&0xFF80FF80)>>7); - g=(X32COL3(*pdest))+(((((X32COL3(color)))* g_m3)&0xFF80FF80)>>7); - } - else - if(GlobalTextABR==2) - { - int t; - r=(((((X32COL1(color)))* g_m1)&0xFF80FF80)>>7); - t=(*pdest&0x001f0000)-(r&0x003f0000); if(t&0x80000000) t=0; - r=(*pdest&0x0000001f)-(r&0x0000003f); if(r&0x80000000) r=0; - r|=t; - - b=(((((X32COL2(color)))* g_m2)&0xFF80FF80)>>7); - t=((*pdest>>5)&0x001f0000)-(b&0x003f0000); if(t&0x80000000) t=0; - b=((*pdest>>5)&0x0000001f)-(b&0x0000003f); if(b&0x80000000) b=0; - b|=t; - - g=(((((X32COL3(color)))* g_m3)&0xFF80FF80)>>7); - t=((*pdest>>10)&0x001f0000)-(g&0x003f0000); if(t&0x80000000) t=0; - g=((*pdest>>10)&0x0000001f)-(g&0x0000003f); if(g&0x80000000) g=0; - g|=t; - } - else - { -#ifdef HALFBRIGHTMODE3 - r=(X32COL1(*pdest))+(((((X32BCOL1(color))>>2)* g_m1)&0xFF80FF80)>>7); - b=(X32COL2(*pdest))+(((((X32BCOL2(color))>>2)* g_m2)&0xFF80FF80)>>7); - g=(X32COL3(*pdest))+(((((X32BCOL3(color))>>2)* g_m3)&0xFF80FF80)>>7); -#else - r=(X32COL1(*pdest))+(((((X32ACOL1(color))>>1)* g_m1)&0xFF80FF80)>>7); - b=(X32COL2(*pdest))+(((((X32ACOL2(color))>>1)* g_m2)&0xFF80FF80)>>7); - g=(X32COL3(*pdest))+(((((X32ACOL3(color))>>1)* g_m3)&0xFF80FF80)>>7); -#endif - } - - if(!(color&0x8000)) - { - r=(r&0xffff0000)|((((X32COL1(color))* g_m1)&0x0000FF80)>>7); - b=(b&0xffff0000)|((((X32COL2(color))* g_m2)&0x0000FF80)>>7); - g=(g&0xffff0000)|((((X32COL3(color))* g_m3)&0x0000FF80)>>7); - } - if(!(color&0x80000000)) - { - r=(r&0xffff)|((((X32COL1(color))* g_m1)&0xFF800000)>>7); - b=(b&0xffff)|((((X32COL2(color))* g_m2)&0xFF800000)>>7); - g=(g&0xffff)|((((X32COL3(color))* g_m3)&0xFF800000)>>7); - } - - } - else - { - r=(((X32COL1(color))* g_m1)&0xFF80FF80)>>7; - b=(((X32COL2(color))* g_m2)&0xFF80FF80)>>7; - g=(((X32COL3(color))* g_m3)&0xFF80FF80)>>7; - } - - if(r&0x7FE00000) r=0x1f0000|(r&0xFFFF); - if(r&0x7FE0) r=0x1f |(r&0xFFFF0000); - if(b&0x7FE00000) b=0x1f0000|(b&0xFFFF); - if(b&0x7FE0) b=0x1f |(b&0xFFFF0000); - if(g&0x7FE00000) g=0x1f0000|(g&0xFFFF); - if(g&0x7FE0) g=0x1f |(g&0xFFFF0000); - - if(bCheckMask) - { - uint32_t ma=*pdest; - - *pdest=(X32PSXCOL(r,g,b))|l; - - if((color&0xffff)==0 ) *pdest=(ma&0xffff)|(*pdest&0xffff0000); - if((color&0xffff0000)==0) *pdest=(ma&0xffff0000)|(*pdest&0xffff); - if(ma&0x80000000) *pdest=(ma&0xFFFF0000)|(*pdest&0xFFFF); - if(ma&0x00008000) *pdest=(ma&0xFFFF) |(*pdest&0xFFFF0000); - - return; - } - if((color&0xffff)==0 ) {*pdest=(*pdest&0xffff)|(((X32PSXCOL(r,g,b))|l)&0xffff0000);return;} - if((color&0xffff0000)==0) {*pdest=(*pdest&0xffff0000)|(((X32PSXCOL(r,g,b))|l)&0xffff);return;} - - *pdest=(X32PSXCOL(r,g,b))|l; -} - -//////////////////////////////////////////////////////////////////////// - -static __inline void GetTextureTransColG32_S(uint32_t *pdest, uint32_t color) -{ - int r,g,b; - - if(color==0) return; - - r=(((X32COL1(color))* g_m1)&0xFF80FF80)>>7; - b=(((X32COL2(color))* g_m2)&0xFF80FF80)>>7; - g=(((X32COL3(color))* g_m3)&0xFF80FF80)>>7; - - if(r&0x7FE00000) r=0x1f0000|(r&0xFFFF); - if(r&0x7FE0) r=0x1f |(r&0xFFFF0000); - if(b&0x7FE00000) b=0x1f0000|(b&0xFFFF); - if(b&0x7FE0) b=0x1f |(b&0xFFFF0000); - if(g&0x7FE00000) g=0x1f0000|(g&0xFFFF); - if(g&0x7FE0) g=0x1f |(g&0xFFFF0000); - - if((color&0xffff)==0) {*pdest=(*pdest&0xffff)|(((X32PSXCOL(r,g,b))|lSetMask|(color&0x80008000))&0xffff0000);return;} - if((color&0xffff0000)==0) {*pdest=(*pdest&0xffff0000)|(((X32PSXCOL(r,g,b))|lSetMask|(color&0x80008000))&0xffff);return;} - - *pdest=(X32PSXCOL(r,g,b))|lSetMask|(color&0x80008000); -} - -//////////////////////////////////////////////////////////////////////// - -static __inline void GetTextureTransColG32_SPR(uint32_t *pdest, uint32_t color) -{ - int r,g,b; - - if(color==0) return; - - if(DrawSemiTrans && (color&0x80008000)) - { - if(GlobalTextABR==0) - { - r=((((X32TCOL1(*pdest))+((X32COL1(color)) * g_m1))&0xFF00FF00)>>8); - b=((((X32TCOL2(*pdest))+((X32COL2(color)) * g_m2))&0xFF00FF00)>>8); - g=((((X32TCOL3(*pdest))+((X32COL3(color)) * g_m3))&0xFF00FF00)>>8); - } - else - if(GlobalTextABR==1) - { - r=(X32COL1(*pdest))+(((((X32COL1(color)))* g_m1)&0xFF80FF80)>>7); - b=(X32COL2(*pdest))+(((((X32COL2(color)))* g_m2)&0xFF80FF80)>>7); - g=(X32COL3(*pdest))+(((((X32COL3(color)))* g_m3)&0xFF80FF80)>>7); - } - else - if(GlobalTextABR==2) - { - int t; - r=(((((X32COL1(color)))* g_m1)&0xFF80FF80)>>7); - t=(*pdest&0x001f0000)-(r&0x003f0000); if(t&0x80000000) t=0; - r=(*pdest&0x0000001f)-(r&0x0000003f); if(r&0x80000000) r=0; - r|=t; - - b=(((((X32COL2(color)))* g_m2)&0xFF80FF80)>>7); - t=((*pdest>>5)&0x001f0000)-(b&0x003f0000); if(t&0x80000000) t=0; - b=((*pdest>>5)&0x0000001f)-(b&0x0000003f); if(b&0x80000000) b=0; - b|=t; - - g=(((((X32COL3(color)))* g_m3)&0xFF80FF80)>>7); - t=((*pdest>>10)&0x001f0000)-(g&0x003f0000); if(t&0x80000000) t=0; - g=((*pdest>>10)&0x0000001f)-(g&0x0000003f); if(g&0x80000000) g=0; - g|=t; - } - else - { -#ifdef HALFBRIGHTMODE3 - r=(X32COL1(*pdest))+(((((X32BCOL1(color))>>2)* g_m1)&0xFF80FF80)>>7); - b=(X32COL2(*pdest))+(((((X32BCOL2(color))>>2)* g_m2)&0xFF80FF80)>>7); - g=(X32COL3(*pdest))+(((((X32BCOL3(color))>>2)* g_m3)&0xFF80FF80)>>7); -#else - r=(X32COL1(*pdest))+(((((X32ACOL1(color))>>1)* g_m1)&0xFF80FF80)>>7); - b=(X32COL2(*pdest))+(((((X32ACOL2(color))>>1)* g_m2)&0xFF80FF80)>>7); - g=(X32COL3(*pdest))+(((((X32ACOL3(color))>>1)* g_m3)&0xFF80FF80)>>7); -#endif - } - - if(!(color&0x8000)) - { - r=(r&0xffff0000)|((((X32COL1(color))* g_m1)&0x0000FF80)>>7); - b=(b&0xffff0000)|((((X32COL2(color))* g_m2)&0x0000FF80)>>7); - g=(g&0xffff0000)|((((X32COL3(color))* g_m3)&0x0000FF80)>>7); - } - if(!(color&0x80000000)) - { - r=(r&0xffff)|((((X32COL1(color))* g_m1)&0xFF800000)>>7); - b=(b&0xffff)|((((X32COL2(color))* g_m2)&0xFF800000)>>7); - g=(g&0xffff)|((((X32COL3(color))* g_m3)&0xFF800000)>>7); - } - - } - else - { - r=(((X32COL1(color))* g_m1)&0xFF80FF80)>>7; - b=(((X32COL2(color))* g_m2)&0xFF80FF80)>>7; - g=(((X32COL3(color))* g_m3)&0xFF80FF80)>>7; - } - - if(r&0x7FE00000) r=0x1f0000|(r&0xFFFF); - if(r&0x7FE0) r=0x1f |(r&0xFFFF0000); - if(b&0x7FE00000) b=0x1f0000|(b&0xFFFF); - if(b&0x7FE0) b=0x1f |(b&0xFFFF0000); - if(g&0x7FE00000) g=0x1f0000|(g&0xFFFF); - if(g&0x7FE0) g=0x1f |(g&0xFFFF0000); - - if(bCheckMask) - { - uint32_t ma=*pdest; - - *pdest=(X32PSXCOL(r,g,b))|lSetMask|(color&0x80008000); - - if((color&0xffff)==0 ) *pdest=(ma&0xffff)|(*pdest&0xffff0000); - if((color&0xffff0000)==0) *pdest=(ma&0xffff0000)|(*pdest&0xffff); - if(ma&0x80000000) *pdest=(ma&0xFFFF0000)|(*pdest&0xFFFF); - if(ma&0x00008000) *pdest=(ma&0xFFFF) |(*pdest&0xFFFF0000); - - return; - } - if((color&0xffff)==0 ) {*pdest=(*pdest&0xffff)|(((X32PSXCOL(r,g,b))|lSetMask|(color&0x80008000))&0xffff0000);return;} - if((color&0xffff0000)==0) {*pdest=(*pdest&0xffff0000)|(((X32PSXCOL(r,g,b))|lSetMask|(color&0x80008000))&0xffff);return;} - - *pdest=(X32PSXCOL(r,g,b))|lSetMask|(color&0x80008000); -} - -//////////////////////////////////////////////////////////////////////// - -static __inline void GetTextureTransColGX_Dither(unsigned short * pdest, unsigned short color, int m1, int m2, int m3) -{ - int r,g,b; - - if(color==0) return; - - if(bCheckMask && *pdest&0x8000) return; - - m1=(((XCOL1D(color)))*m1)>>4; - m2=(((XCOL2D(color)))*m2)>>4; - m3=(((XCOL3D(color)))*m3)>>4; - - if(DrawSemiTrans && (color&0x8000)) - { - r=((XCOL1D(*pdest))<<3); - b=((XCOL2D(*pdest))<<3); - g=((XCOL3D(*pdest))<<3); - - if(GlobalTextABR==0) - { - r=(r>>1)+(m1>>1); - b=(b>>1)+(m2>>1); - g=(g>>1)+(m3>>1); - } - else - if(GlobalTextABR==1) - { - r+=m1; - b+=m2; - g+=m3; - } - else - if(GlobalTextABR==2) - { - r-=m1; - b-=m2; - g-=m3; - if(r&0x80000000) r=0; - if(b&0x80000000) b=0; - if(g&0x80000000) g=0; - } - else - { -#ifdef HALFBRIGHTMODE3 - r+=(m1>>2); - b+=(m2>>2); - g+=(m3>>2); -#else - r+=(m1>>1); - b+=(m2>>1); - g+=(m3>>1); -#endif - } - } - else - { - r=m1; - b=m2; - g=m3; - } - - if(r&0x7FFFFF00) r=0xff; - if(b&0x7FFFFF00) b=0xff; - if(g&0x7FFFFF00) g=0xff; - - Dither16(pdest,r,b,g,sSetMask|(color&0x8000)); - -} - -//////////////////////////////////////////////////////////////////////// - -static __inline void GetTextureTransColGX(unsigned short * pdest,unsigned short color,short m1,short m2,short m3) -{ - int r,g,b;unsigned short l; - - if(color==0) return; - - if(bCheckMask && *pdest&0x8000) return; - - l=sSetMask|(color&0x8000); - - if(DrawSemiTrans && (color&0x8000)) - { - if(GlobalTextABR==0) - { - unsigned short d; - d =((*pdest)&0x7bde)>>1; - color =((color) &0x7bde)>>1; - r=(XCOL1(d))+((((XCOL1(color)))* m1)>>7); - b=(XCOL2(d))+((((XCOL2(color)))* m2)>>7); - g=(XCOL3(d))+((((XCOL3(color)))* m3)>>7); -/* - r=(XCOL1(*pdest)>>1)+((((XCOL1(color))>>1)* m1)>>7); - b=(XCOL2(*pdest)>>1)+((((XCOL2(color))>>1)* m2)>>7); - g=(XCOL3(*pdest)>>1)+((((XCOL3(color))>>1)* m3)>>7); -*/ - } - else - if(GlobalTextABR==1) - { - r=(XCOL1(*pdest))+((((XCOL1(color)))* m1)>>7); - b=(XCOL2(*pdest))+((((XCOL2(color)))* m2)>>7); - g=(XCOL3(*pdest))+((((XCOL3(color)))* m3)>>7); - } - else - if(GlobalTextABR==2) - { - r=(XCOL1(*pdest))-((((XCOL1(color)))* m1)>>7); - b=(XCOL2(*pdest))-((((XCOL2(color)))* m2)>>7); - g=(XCOL3(*pdest))-((((XCOL3(color)))* m3)>>7); - if(r&0x80000000) r=0; - if(b&0x80000000) b=0; - if(g&0x80000000) g=0; - } - else - { -#ifdef HALFBRIGHTMODE3 - r=(XCOL1(*pdest))+((((XCOL1(color))>>2)* m1)>>7); - b=(XCOL2(*pdest))+((((XCOL2(color))>>2)* m2)>>7); - g=(XCOL3(*pdest))+((((XCOL3(color))>>2)* m3)>>7); -#else - r=(XCOL1(*pdest))+((((XCOL1(color))>>1)* m1)>>7); - b=(XCOL2(*pdest))+((((XCOL2(color))>>1)* m2)>>7); - g=(XCOL3(*pdest))+((((XCOL3(color))>>1)* m3)>>7); -#endif - } - } - else - { - r=((XCOL1(color))* m1)>>7; - b=((XCOL2(color))* m2)>>7; - g=((XCOL3(color))* m3)>>7; - } - - if(r&0x7FFFFFE0) r=0x1f; - if(b&0x7FFFFC00) b=0x3e0; - if(g&0x7FFF8000) g=0x7c00; - - *pdest=(XPSXCOL(r,g,b))|l; -} - -//////////////////////////////////////////////////////////////////////// - -static __inline void GetTextureTransColGX_S(unsigned short * pdest,unsigned short color,short m1,short m2,short m3) -{ - int r,g,b; - - if(color==0) return; - - r=((XCOL1(color))* m1)>>7; - b=((XCOL2(color))* m2)>>7; - g=((XCOL3(color))* m3)>>7; - - if(r&0x7FFFFFE0) r=0x1f; - if(b&0x7FFFFC00) b=0x3e0; - if(g&0x7FFF8000) g=0x7c00; - - *pdest=(XPSXCOL(r,g,b))|sSetMask|(color&0x8000); -} - -//////////////////////////////////////////////////////////////////////// - -static __inline void GetTextureTransColGX32_S(uint32_t *pdest, uint32_t color, short m1, short m2, short m3) -{ - int r,g,b; - - if(color==0) return; - - r=(((X32COL1(color))* m1)&0xFF80FF80)>>7; - b=(((X32COL2(color))* m2)&0xFF80FF80)>>7; - g=(((X32COL3(color))* m3)&0xFF80FF80)>>7; - - if(r&0x7FE00000) r=0x1f0000|(r&0xFFFF); - if(r&0x7FE0) r=0x1f |(r&0xFFFF0000); - if(b&0x7FE00000) b=0x1f0000|(b&0xFFFF); - if(b&0x7FE0) b=0x1f |(b&0xFFFF0000); - if(g&0x7FE00000) g=0x1f0000|(g&0xFFFF); - if(g&0x7FE0) g=0x1f |(g&0xFFFF0000); - - if((color&0xffff)==0) {*pdest=(*pdest&0xffff)|(((X32PSXCOL(r,g,b))|lSetMask|(color&0x80008000))&0xffff0000);return;} - if((color&0xffff0000)==0) {*pdest=(*pdest&0xffff0000)|(((X32PSXCOL(r,g,b))|lSetMask|(color&0x80008000))&0xffff);return;} - - *pdest=(X32PSXCOL(r,g,b))|lSetMask|(color&0x80008000); -} - -//////////////////////////////////////////////////////////////////////// -// FILL FUNCS -//////////////////////////////////////////////////////////////////////// - -void FillSoftwareAreaTrans(short x0,short y0,short x1, // FILL AREA TRANS - short y1,unsigned short col) -{ - short j,i,dx,dy; - - if(y0>y1) return; - if(x0>x1) return; - - if(x1<drawX) return; - if(y1<drawY) return; - if(x0>drawW) return; - if(y0>drawH) return; - - x1=min(x1,drawW+1); - y1=min(y1,drawH+1); - x0=max(x0,drawX); - y0=max(y0,drawY); - - if(y0>=iGPUHeight) return; - if(x0>1023) return; - - if(y1>iGPUHeight) y1=iGPUHeight; - if(x1>1024) x1=1024; - - dx=x1-x0;dy=y1-y0; - - if(dx==1 && dy==1 && x0==1020 && y0==511) // special fix for pinball game... emu protection??? - { -/* -m->v 1020 511 1 1 -writedatamem 0x00000000 1 -tile1 newcol 7fff (orgcol 0xffffff), oldvram 0 -v->m 1020 511 1 1 -readdatamem 0x00007fff 1 -m->v 1020 511 1 1 -writedatamem 0x00000000 1 -tile1 newcol 8000 (orgcol 0xffffff), oldvram 0 -v->m 1020 511 1 1 -readdatamem 0x00008000 1 -*/ - - static int iCheat=0; - col+=iCheat; - if(iCheat==1) iCheat=0; else iCheat=1; - } - - if(dx&1) // slow fill - { - unsigned short *DSTPtr; - unsigned short LineOffset; - DSTPtr = psxVuw + (1024*y0) + x0; - LineOffset = 1024 - dx; - for(i=0;i<dy;i++) - { - for(j=0;j<dx;j++) - GetShadeTransCol(DSTPtr++,col); - DSTPtr += LineOffset; - } - } - else // fast fill - { - uint32_t *DSTPtr; - unsigned short LineOffset; - uint32_t lcol=lSetMask|(((uint32_t)(col))<<16)|col; - dx>>=1; - DSTPtr = (uint32_t *)(psxVuw + (1024*y0) + x0); - LineOffset = 512 - dx; - - if(!bCheckMask && !DrawSemiTrans) - { - for(i=0;i<dy;i++) - { - for(j=0;j<dx;j++) *DSTPtr++=lcol; - DSTPtr += LineOffset; - } - } - else - { - for(i=0;i<dy;i++) - { - for(j=0;j<dx;j++) - GetShadeTransCol32(DSTPtr++,lcol); - DSTPtr += LineOffset; - } - } - } -} - -//////////////////////////////////////////////////////////////////////// - -void FillSoftwareArea(short x0,short y0,short x1, // FILL AREA (BLK FILL) - short y1,unsigned short col) // no draw area check here! -{ - short j,i,dx,dy; - - if(y0>y1) return; - if(x0>x1) return; - - if(y0>=iGPUHeight) return; - if(x0>1023) return; - - if(y1>iGPUHeight) y1=iGPUHeight; - if(x1>1024) x1=1024; - - dx=x1-x0;dy=y1-y0; - if(dx&1) - { - unsigned short *DSTPtr; - unsigned short LineOffset; - - DSTPtr = psxVuw + (1024*y0) + x0; - LineOffset = 1024 - dx; - - for(i=0;i<dy;i++) - { - for(j=0;j<dx;j++) *DSTPtr++=col; - DSTPtr += LineOffset; - } - } - else - { - uint32_t *DSTPtr; - unsigned short LineOffset; - uint32_t lcol=(((int)col)<<16)|col; - dx>>=1; - DSTPtr = (uint32_t *)(psxVuw + (1024*y0) + x0); - LineOffset = 512 - dx; - - for(i=0;i<dy;i++) - { - for(j=0;j<dx;j++) *DSTPtr++=lcol; - DSTPtr += LineOffset; - } - } -} - -//////////////////////////////////////////////////////////////////////// -// EDGE INTERPOLATION -//////////////////////////////////////////////////////////////////////// - -typedef struct SOFTVTAG -{ - int x,y; - int u,v; - int R,G,B; -} soft_vertex; - -static soft_vertex vtx[4]; -static soft_vertex * left_array[4], * right_array[4]; -static int left_section, right_section; -static int left_section_height, right_section_height; -static int left_x, delta_left_x, right_x, delta_right_x; -static int left_u, delta_left_u, left_v, delta_left_v; -static int right_u, delta_right_u, right_v, delta_right_v; -static int left_R, delta_left_R, right_R, delta_right_R; -static int left_G, delta_left_G, right_G, delta_right_G; -static int left_B, delta_left_B, right_B, delta_right_B; - -#ifdef _MSC_VER - -#pragma warning (disable : 4035) - -static __inline int shl10idiv(int x, int y) -{ - __asm - { - mov eax,x - mov ebx,y - mov edx, eax - shl eax, 10 - sar edx, 22 - idiv ebx - // return result in eax - } -} - -#else - -static __inline int shl10idiv(int x, int y) -{ - long long int bi=x; - bi<<=10; - return bi/y; -} - -#endif - -static __inline int RightSection_F(void) -{ - soft_vertex * v1 = right_array[ right_section ]; - soft_vertex * v2 = right_array[ right_section-1 ]; - - int height = v2->y - v1->y; - if(height == 0) return 0; - delta_right_x = (v2->x - v1->x) / height; - right_x = v1->x; - - right_section_height = height; - return height; -} - -static __inline int LeftSection_F(void) -{ - soft_vertex * v1 = left_array[ left_section ]; - soft_vertex * v2 = left_array[ left_section-1 ]; - - int height = v2->y - v1->y; - if(height == 0) return 0; - delta_left_x = (v2->x - v1->x) / height; - left_x = v1->x; - - left_section_height = height; - return height; -} - -static __inline BOOL NextRow_F(void) -{ - if(--left_section_height<=0) - { - if(--left_section <= 0) {return TRUE;} - if(LeftSection_F() <= 0) {return TRUE;} - } - else - { - left_x += delta_left_x; - } - - if(--right_section_height<=0) - { - if(--right_section<=0) {return TRUE;} - if(RightSection_F() <=0) {return TRUE;} - } - else - { - right_x += delta_right_x; - } - return FALSE; -} - -static __inline BOOL SetupSections_F(short x1, short y1, short x2, short y2, short x3, short y3) -{ - soft_vertex * v1, * v2, * v3; - int height,longest; - - v1 = vtx; v1->x=x1<<16;v1->y=y1; - v2 = vtx+1; v2->x=x2<<16;v2->y=y2; - v3 = vtx+2; v3->x=x3<<16;v3->y=y3; - - if(v1->y > v2->y) { soft_vertex * v = v1; v1 = v2; v2 = v; } - if(v1->y > v3->y) { soft_vertex * v = v1; v1 = v3; v3 = v; } - if(v2->y > v3->y) { soft_vertex * v = v2; v2 = v3; v3 = v; } - - height = v3->y - v1->y; - if(height == 0) {return FALSE;} - longest = (((v2->y - v1->y) << 16) / height) * ((v3->x - v1->x)>>16) + (v1->x - v2->x); - if(longest == 0) {return FALSE;} - - if(longest < 0) - { - right_array[0] = v3; - right_array[1] = v2; - right_array[2] = v1; - right_section = 2; - left_array[0] = v3; - left_array[1] = v1; - left_section = 1; - - if(LeftSection_F() <= 0) return FALSE; - if(RightSection_F() <= 0) - { - right_section--; - if(RightSection_F() <= 0) return FALSE; - } - } - else - { - left_array[0] = v3; - left_array[1] = v2; - left_array[2] = v1; - left_section = 2; - right_array[0] = v3; - right_array[1] = v1; - right_section = 1; - - if(RightSection_F() <= 0) return FALSE; - if(LeftSection_F() <= 0) - { - left_section--; - if(LeftSection_F() <= 0) return FALSE; - } - } - - Ymin=v1->y; - Ymax=min(v3->y-1,drawH); - - return TRUE; -} - -static __inline int RightSection_G(void) -{ - soft_vertex * v1 = right_array[ right_section ]; - soft_vertex * v2 = right_array[ right_section-1 ]; - - int height = v2->y - v1->y; - if(height == 0) return 0; - delta_right_x = (v2->x - v1->x) / height; - right_x = v1->x; - - right_section_height = height; - return height; -} - -static __inline int LeftSection_G(void) -{ - soft_vertex * v1 = left_array[ left_section ]; - soft_vertex * v2 = left_array[ left_section-1 ]; - - int height = v2->y - v1->y; - if(height == 0) return 0; - delta_left_x = (v2->x - v1->x) / height; - left_x = v1->x; - - delta_left_R = ((v2->R - v1->R)) / height; - left_R = v1->R; - delta_left_G = ((v2->G - v1->G)) / height; - left_G = v1->G; - delta_left_B = ((v2->B - v1->B)) / height; - left_B = v1->B; - - left_section_height = height; - return height; -} - -static __inline BOOL NextRow_G(void) -{ - if(--left_section_height<=0) - { - if(--left_section <= 0) {return TRUE;} - if(LeftSection_G() <= 0) {return TRUE;} - } - else - { - left_x += delta_left_x; - left_R += delta_left_R; - left_G += delta_left_G; - left_B += delta_left_B; - } - - if(--right_section_height<=0) - { - if(--right_section<=0) {return TRUE;} - if(RightSection_G() <=0) {return TRUE;} - } - else - { - right_x += delta_right_x; - } - return FALSE; -} - -static __inline BOOL SetupSections_G(short x1,short y1,short x2,short y2,short x3,short y3, int rgb1, int rgb2, int rgb3){ - soft_vertex *v1, *v2, *v3; - int height, longest, temp; - - v1 = vtx; v1->x=x1<<16;v1->y=y1; - v1->R=(rgb1) & 0x00ff0000; - v1->G=(rgb1<<8) & 0x00ff0000; - v1->B=(rgb1<<16) & 0x00ff0000; - v2 = vtx+1; v2->x=x2<<16;v2->y=y2; - v2->R=(rgb2) & 0x00ff0000; - v2->G=(rgb2<<8) & 0x00ff0000; - v2->B=(rgb2<<16) & 0x00ff0000; - v3 = vtx+2; v3->x=x3<<16;v3->y=y3; - v3->R=(rgb3) & 0x00ff0000; - v3->G=(rgb3<<8) & 0x00ff0000; - v3->B=(rgb3<<16) & 0x00ff0000; - - if(v1->y > v2->y) { soft_vertex * v = v1; v1 = v2; v2 = v; } - if(v1->y > v3->y) { soft_vertex * v = v1; v1 = v3; v3 = v; } - if(v2->y > v3->y) { soft_vertex * v = v2; v2 = v3; v3 = v; } - - height = v3->y - v1->y; - if(height == 0) {return FALSE;} - temp=(((v2->y - v1->y) << 16) / height); - longest = temp * ((v3->x - v1->x)>>16) + (v1->x - v2->x); - if(longest == 0) {return FALSE;} - - if(longest < 0) - { - right_array[0] = v3; - right_array[1] = v2; - right_array[2] = v1; - right_section = 2; - left_array[0] = v3; - left_array[1] = v1; - left_section = 1; - - if(LeftSection_G() <= 0) return FALSE; - if(RightSection_G() <= 0) - { - right_section--; - if(RightSection_G() <= 0) return FALSE; - } - if(longest > -0x1000) longest = -0x1000; - } - else - { - left_array[0] = v3; - left_array[1] = v2; - left_array[2] = v1; - left_section = 2; - right_array[0] = v3; - right_array[1] = v1; - right_section = 1; - - if(RightSection_G() <= 0) return FALSE; - if(LeftSection_G() <= 0) - { - left_section--; - if(LeftSection_G() <= 0) return FALSE; - } - if(longest < 0x1000) longest = 0x1000; - } - - Ymin=v1->y; - Ymax=min(v3->y-1,drawH); - - delta_right_R=shl10idiv(temp*((v3->R - v1->R)>>10)+((v1->R - v2->R)<<6),longest); - delta_right_G=shl10idiv(temp*((v3->G - v1->G)>>10)+((v1->G - v2->G)<<6),longest); - delta_right_B=shl10idiv(temp*((v3->B - v1->B)>>10)+((v1->B - v2->B)<<6),longest); - - return TRUE; -} - -static __inline int RightSection_FT(void) -{ - soft_vertex * v1 = right_array[ right_section ]; - soft_vertex * v2 = right_array[ right_section-1 ]; - - int height = v2->y - v1->y; - if(height == 0) return 0; - delta_right_x = (v2->x - v1->x) / height; - right_x = v1->x; - - right_section_height = height; - return height; -} - -static __inline int LeftSection_FT(void) -{ - soft_vertex * v1 = left_array[ left_section ]; - soft_vertex * v2 = left_array[ left_section-1 ]; - - int height = v2->y - v1->y; - if(height == 0) return 0; - delta_left_x = (v2->x - v1->x) / height; - left_x = v1->x; - - delta_left_u = ((v2->u - v1->u)) / height; - left_u = v1->u; - delta_left_v = ((v2->v - v1->v)) / height; - left_v = v1->v; - - left_section_height = height; - return height; -} - -static __inline BOOL NextRow_FT(void) -{ - if(--left_section_height<=0) - { - if(--left_section <= 0) {return TRUE;} - if(LeftSection_FT() <= 0) {return TRUE;} - } - else - { - left_x += delta_left_x; - left_u += delta_left_u; - left_v += delta_left_v; - } - - if(--right_section_height<=0) - { - if(--right_section<=0) {return TRUE;} - if(RightSection_FT() <=0) {return TRUE;} - } - else - { - right_x += delta_right_x; - } - return FALSE; -} - -static __inline BOOL SetupSections_FT(short x1, short y1, short x2, short y2, short x3, short y3, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3) -{ - soft_vertex * v1, * v2, * v3; - int height,longest,temp; - - v1 = vtx; v1->x=x1<<16;v1->y=y1; - v1->u=tx1<<16;v1->v=ty1<<16; - v2 = vtx+1; v2->x=x2<<16;v2->y=y2; - v2->u=tx2<<16;v2->v=ty2<<16; - v3 = vtx+2; v3->x=x3<<16;v3->y=y3; - v3->u=tx3<<16;v3->v=ty3<<16; - - if(v1->y > v2->y) { soft_vertex * v = v1; v1 = v2; v2 = v; } - if(v1->y > v3->y) { soft_vertex * v = v1; v1 = v3; v3 = v; } - if(v2->y > v3->y) { soft_vertex * v = v2; v2 = v3; v3 = v; } - - height = v3->y - v1->y; - if(height == 0) {return FALSE;} - - temp=(((v2->y - v1->y) << 16) / height); - longest = temp * ((v3->x - v1->x)>>16) + (v1->x - v2->x); - - if(longest == 0) {return FALSE;} - - if(longest < 0) - { - right_array[0] = v3; - right_array[1] = v2; - right_array[2] = v1; - right_section = 2; - left_array[0] = v3; - left_array[1] = v1; - left_section = 1; - - if(LeftSection_FT() <= 0) return FALSE; - if(RightSection_FT() <= 0) - { - right_section--; - if(RightSection_FT() <= 0) return FALSE; - } - if(longest > -0x1000) longest = -0x1000; - } - else - { - left_array[0] = v3; - left_array[1] = v2; - left_array[2] = v1; - left_section = 2; - right_array[0] = v3; - right_array[1] = v1; - right_section = 1; - - if(RightSection_FT() <= 0) return FALSE; - if(LeftSection_FT() <= 0) - { - left_section--; - if(LeftSection_FT() <= 0) return FALSE; - } - if(longest < 0x1000) longest = 0x1000; - } - - Ymin=v1->y; - Ymax=min(v3->y-1,drawH); - - delta_right_u=shl10idiv(temp*((v3->u - v1->u)>>10)+((v1->u - v2->u)<<6),longest); - delta_right_v=shl10idiv(temp*((v3->v - v1->v)>>10)+((v1->v - v2->v)<<6),longest); - -/* -Mmm... adjust neg tex deltas... will sometimes cause slight -texture distortions - - longest>>=16; - if(longest) - { - if(longest<0) longest=-longest; - if(delta_right_u<0) - delta_right_u-=delta_right_u/longest; - if(delta_right_v<0) - delta_right_v-=delta_right_v/longest; - } -*/ - - return TRUE; -} - -static __inline int RightSection_GT(void) -{ - soft_vertex * v1 = right_array[ right_section ]; - soft_vertex * v2 = right_array[ right_section-1 ]; - - int height = v2->y - v1->y; - if(height == 0) return 0; - delta_right_x = (v2->x - v1->x) / height; - right_x = v1->x; - - right_section_height = height; - return height; -} - -static __inline int LeftSection_GT(void) -{ - soft_vertex * v1 = left_array[ left_section ]; - soft_vertex * v2 = left_array[ left_section-1 ]; - - int height = v2->y - v1->y; - if(height == 0) return 0; - delta_left_x = (v2->x - v1->x) / height; - left_x = v1->x; - - delta_left_u = ((v2->u - v1->u)) / height; - left_u = v1->u; - delta_left_v = ((v2->v - v1->v)) / height; - left_v = v1->v; - - delta_left_R = ((v2->R - v1->R)) / height; - left_R = v1->R; - delta_left_G = ((v2->G - v1->G)) / height; - left_G = v1->G; - delta_left_B = ((v2->B - v1->B)) / height; - left_B = v1->B; - - left_section_height = height; - return height; -} - -static __inline BOOL NextRow_GT(void) -{ - if(--left_section_height<=0) - { - if(--left_section <= 0) {return TRUE;} - if(LeftSection_GT() <= 0) {return TRUE;} - } - else - { - left_x += delta_left_x; - left_u += delta_left_u; - left_v += delta_left_v; - left_R += delta_left_R; - left_G += delta_left_G; - left_B += delta_left_B; - } - - if(--right_section_height<=0) - { - if(--right_section<=0) {return TRUE;} - if(RightSection_GT() <=0) {return TRUE;} - } - else - { - right_x += delta_right_x; - } - return FALSE; -} - -static __inline BOOL SetupSections_GT(short x1, short y1, short x2, short y2, short x3, short y3, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, int rgb1, int rgb2, int rgb3) -{ - soft_vertex * v1, * v2, * v3; - int height,longest,temp; - - v1 = vtx; v1->x=x1<<16;v1->y=y1; - v1->u=tx1<<16;v1->v=ty1<<16; - v1->R=(rgb1) & 0x00ff0000; - v1->G=(rgb1<<8) & 0x00ff0000; - v1->B=(rgb1<<16) & 0x00ff0000; - - v2 = vtx+1; v2->x=x2<<16;v2->y=y2; - v2->u=tx2<<16;v2->v=ty2<<16; - v2->R=(rgb2) & 0x00ff0000; - v2->G=(rgb2<<8) & 0x00ff0000; - v2->B=(rgb2<<16) & 0x00ff0000; - - v3 = vtx+2; v3->x=x3<<16;v3->y=y3; - v3->u=tx3<<16;v3->v=ty3<<16; - v3->R=(rgb3) & 0x00ff0000; - v3->G=(rgb3<<8) & 0x00ff0000; - v3->B=(rgb3<<16) & 0x00ff0000; - - if(v1->y > v2->y) { soft_vertex * v = v1; v1 = v2; v2 = v; } - if(v1->y > v3->y) { soft_vertex * v = v1; v1 = v3; v3 = v; } - if(v2->y > v3->y) { soft_vertex * v = v2; v2 = v3; v3 = v; } - - height = v3->y - v1->y; - if(height == 0) {return FALSE;} - - temp=(((v2->y - v1->y) << 16) / height); - longest = temp * ((v3->x - v1->x)>>16) + (v1->x - v2->x); - - if(longest == 0) {return FALSE;} - - if(longest < 0) - { - right_array[0] = v3; - right_array[1] = v2; - right_array[2] = v1; - right_section = 2; - left_array[0] = v3; - left_array[1] = v1; - left_section = 1; - - if(LeftSection_GT() <= 0) return FALSE; - if(RightSection_GT() <= 0) - { - right_section--; - if(RightSection_GT() <= 0) return FALSE; - } - - if(longest > -0x1000) longest = -0x1000; - } - else - { - left_array[0] = v3; - left_array[1] = v2; - left_array[2] = v1; - left_section = 2; - right_array[0] = v3; - right_array[1] = v1; - right_section = 1; - - if(RightSection_GT() <= 0) return FALSE; - if(LeftSection_GT() <= 0) - { - left_section--; - if(LeftSection_GT() <= 0) return FALSE; - } - if(longest < 0x1000) longest = 0x1000; - } - - Ymin=v1->y; - Ymax=min(v3->y-1,drawH); - - delta_right_R=shl10idiv(temp*((v3->R - v1->R)>>10)+((v1->R - v2->R)<<6),longest); - delta_right_G=shl10idiv(temp*((v3->G - v1->G)>>10)+((v1->G - v2->G)<<6),longest); - delta_right_B=shl10idiv(temp*((v3->B - v1->B)>>10)+((v1->B - v2->B)<<6),longest); - - delta_right_u=shl10idiv(temp*((v3->u - v1->u)>>10)+((v1->u - v2->u)<<6),longest); - delta_right_v=shl10idiv(temp*((v3->v - v1->v)>>10)+((v1->v - v2->v)<<6),longest); - - -/* -Mmm... adjust neg tex deltas... will sometimes cause slight -texture distortions - longest>>=16; - if(longest) - { - if(longest<0) longest=-longest; - if(delta_right_u<0) - delta_right_u-=delta_right_u/longest; - if(delta_right_v<0) - delta_right_v-=delta_right_v/longest; - } -*/ - - - return TRUE; -} - -static __inline int RightSection_F4(void) -{ - soft_vertex * v1 = right_array[ right_section ]; - soft_vertex * v2 = right_array[ right_section-1 ]; - - int height = v2->y - v1->y; - right_section_height = height; - right_x = v1->x; - if(height == 0) - { - return 0; - } - delta_right_x = (v2->x - v1->x) / height; - - return height; -} - -static __inline int LeftSection_F4(void) -{ - soft_vertex * v1 = left_array[ left_section ]; - soft_vertex * v2 = left_array[ left_section-1 ]; - - int height = v2->y - v1->y; - left_section_height = height; - left_x = v1->x; - if(height == 0) - { - return 0; - } - delta_left_x = (v2->x - v1->x) / height; - - return height; -} - -static __inline BOOL NextRow_F4(void) -{ - if(--left_section_height<=0) - { - if(--left_section > 0) - while(LeftSection_F4()<=0) - { - if(--left_section <= 0) break; - } - } - else - { - left_x += delta_left_x; - } - - if(--right_section_height<=0) - { - if(--right_section > 0) - while(RightSection_F4()<=0) - { - if(--right_section<=0) break; - } - } - else - { - right_x += delta_right_x; - } - return FALSE; -} - -static __inline BOOL SetupSections_F4(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4) -{ - soft_vertex * v1, * v2, * v3, * v4; - int height,width,longest1,longest2; - - v1 = vtx; v1->x=x1<<16;v1->y=y1; - v2 = vtx+1; v2->x=x2<<16;v2->y=y2; - v3 = vtx+2; v3->x=x3<<16;v3->y=y3; - v4 = vtx+3; v4->x=x4<<16;v4->y=y4; - - if(v1->y > v2->y) { soft_vertex * v = v1; v1 = v2; v2 = v; } - if(v1->y > v3->y) { soft_vertex * v = v1; v1 = v3; v3 = v; } - if(v1->y > v4->y) { soft_vertex * v = v1; v1 = v4; v4 = v; } - if(v2->y > v3->y) { soft_vertex * v = v2; v2 = v3; v3 = v; } - if(v2->y > v4->y) { soft_vertex * v = v2; v2 = v4; v4 = v; } - if(v3->y > v4->y) { soft_vertex * v = v3; v3 = v4; v4 = v; } - - height = v4->y - v1->y; if(height == 0) height =1; - width = (v4->x - v1->x)>>16; - longest1 = (((v2->y - v1->y) << 16) / height) * width + (v1->x - v2->x); - longest2 = (((v3->y - v1->y) << 16) / height) * width + (v1->x - v3->x); - - if(longest1 < 0) // 2 is right - { - if(longest2 < 0) // 3 is right - { - left_array[0] = v4; - left_array[1] = v1; - left_section = 1; - - height = v3->y - v1->y; if(height == 0) height=1; - longest1 = (((v2->y - v1->y) << 16) / height) * ((v3->x - v1->x)>>16) + (v1->x - v2->x); - if(longest1 >= 0) - { - right_array[0] = v4; // 1 - right_array[1] = v3; // 3 - right_array[2] = v1; // 4 - right_section = 2; - } - else - { - height = v4->y - v2->y; if(height == 0) height=1; - longest1 = (((v3->y - v2->y) << 16) / height) * ((v4->x - v2->x)>>16) + (v2->x - v3->x); - if(longest1 >= 0) - { - right_array[0] = v4; // 1 - right_array[1] = v2; // 2 - right_array[2] = v1; // 4 - right_section = 2; - } - else - { - right_array[0] = v4; // 1 - right_array[1] = v3; // 2 - right_array[2] = v2; // 3 - right_array[3] = v1; // 4 - right_section = 3; - } - } - } - else - { - left_array[0] = v4; - left_array[1] = v3; // 1 - left_array[2] = v1; // 2 - left_section = 2; // 3 - right_array[0] = v4; // 4 - right_array[1] = v2; - right_array[2] = v1; - right_section = 2; - } - } - else - { - if(longest2 < 0) - { - left_array[0] = v4; // 1 - left_array[1] = v2; // 2 - left_array[2] = v1; // 3 - left_section = 2; // 4 - right_array[0] = v4; - right_array[1] = v3; - right_array[2] = v1; - right_section = 2; - } - else - { - right_array[0] = v4; - right_array[1] = v1; - right_section = 1; - - height = v3->y - v1->y; if(height == 0) height=1; - longest1 = (((v2->y - v1->y) << 16) / height) * ((v3->x - v1->x)>>16) + (v1->x - v2->x); - if(longest1<0) - { - left_array[0] = v4; // 1 - left_array[1] = v3; // 3 - left_array[2] = v1; // 4 - left_section = 2; - } - else - { - height = v4->y - v2->y; if(height == 0) height=1; - longest1 = (((v3->y - v2->y) << 16) / height) * ((v4->x - v2->x)>>16) + (v2->x - v3->x); - if(longest1<0) - { - left_array[0] = v4; // 1 - left_array[1] = v2; // 2 - left_array[2] = v1; // 4 - left_section = 2; - } - else - { - left_array[0] = v4; // 1 - left_array[1] = v3; // 2 - left_array[2] = v2; // 3 - left_array[3] = v1; // 4 - left_section = 3; - } - } - } - } - - while(LeftSection_F4()<=0) - { - if(--left_section <= 0) break; - } - - while(RightSection_F4()<=0) - { - if(--right_section <= 0) break; - } - - Ymin=v1->y; - Ymax=min(v4->y-1,drawH); - - return TRUE; -} - -static __inline int RightSection_FT4(void) -{ - soft_vertex * v1 = right_array[ right_section ]; - soft_vertex * v2 = right_array[ right_section-1 ]; - - int height = v2->y - v1->y; - right_section_height = height; - right_x = v1->x; - right_u = v1->u; - right_v = v1->v; - if(height == 0) - { - return 0; - } - delta_right_x = (v2->x - v1->x) / height; - delta_right_u = (v2->u - v1->u) / height; - delta_right_v = (v2->v - v1->v) / height; - - return height; -} - -static __inline int LeftSection_FT4(void) -{ - soft_vertex * v1 = left_array[ left_section ]; - soft_vertex * v2 = left_array[ left_section-1 ]; - - int height = v2->y - v1->y; - left_section_height = height; - left_x = v1->x; - left_u = v1->u; - left_v = v1->v; - if(height == 0) - { - return 0; - } - delta_left_x = (v2->x - v1->x) / height; - delta_left_u = (v2->u - v1->u) / height; - delta_left_v = (v2->v - v1->v) / height; - - return height; -} - -static __inline BOOL NextRow_FT4(void) -{ - if(--left_section_height<=0) - { - if(--left_section > 0) - while(LeftSection_FT4()<=0) - { - if(--left_section <= 0) break; - } - } - else - { - left_x += delta_left_x; - left_u += delta_left_u; - left_v += delta_left_v; - } - - if(--right_section_height<=0) - { - if(--right_section > 0) - while(RightSection_FT4()<=0) - { - if(--right_section<=0) break; - } - } - else - { - right_x += delta_right_x; - right_u += delta_right_u; - right_v += delta_right_v; - } - return FALSE; -} - -static __inline BOOL SetupSections_FT4(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4) -{ - soft_vertex * v1, * v2, * v3, * v4; - int height,width,longest1,longest2; - - v1 = vtx; v1->x=x1<<16;v1->y=y1; - v1->u=tx1<<16;v1->v=ty1<<16; - - v2 = vtx+1; v2->x=x2<<16;v2->y=y2; - v2->u=tx2<<16;v2->v=ty2<<16; - - v3 = vtx+2; v3->x=x3<<16;v3->y=y3; - v3->u=tx3<<16;v3->v=ty3<<16; - - v4 = vtx+3; v4->x=x4<<16;v4->y=y4; - v4->u=tx4<<16;v4->v=ty4<<16; - - if(v1->y > v2->y) { soft_vertex * v = v1; v1 = v2; v2 = v; } - if(v1->y > v3->y) { soft_vertex * v = v1; v1 = v3; v3 = v; } - if(v1->y > v4->y) { soft_vertex * v = v1; v1 = v4; v4 = v; } - if(v2->y > v3->y) { soft_vertex * v = v2; v2 = v3; v3 = v; } - if(v2->y > v4->y) { soft_vertex * v = v2; v2 = v4; v4 = v; } - if(v3->y > v4->y) { soft_vertex * v = v3; v3 = v4; v4 = v; } - - height = v4->y - v1->y; if(height == 0) height =1; - width = (v4->x - v1->x)>>16; - longest1 = (((v2->y - v1->y) << 16) / height) * width + (v1->x - v2->x); - longest2 = (((v3->y - v1->y) << 16) / height) * width + (v1->x - v3->x); - - if(longest1 < 0) // 2 is right - { - if(longest2 < 0) // 3 is right - { - left_array[0] = v4; - left_array[1] = v1; - left_section = 1; - - height = v3->y - v1->y; if(height == 0) height=1; - longest1 = (((v2->y - v1->y) << 16) / height) * ((v3->x - v1->x)>>16) + (v1->x - v2->x); - if(longest1 >= 0) - { - right_array[0] = v4; // 1 - right_array[1] = v3; // 3 - right_array[2] = v1; // 4 - right_section = 2; - } - else - { - height = v4->y - v2->y; if(height == 0) height=1; - longest1 = (((v3->y - v2->y) << 16) / height) * ((v4->x - v2->x)>>16) + (v2->x - v3->x); - if(longest1 >= 0) - { - right_array[0] = v4; // 1 - right_array[1] = v2; // 2 - right_array[2] = v1; // 4 - right_section = 2; - } - else - { - right_array[0] = v4; // 1 - right_array[1] = v3; // 2 - right_array[2] = v2; // 3 - right_array[3] = v1; // 4 - right_section = 3; - } - } - } - else - { - left_array[0] = v4; - left_array[1] = v3; // 1 - left_array[2] = v1; // 2 - left_section = 2; // 3 - right_array[0] = v4; // 4 - right_array[1] = v2; - right_array[2] = v1; - right_section = 2; - } - } - else - { - if(longest2 < 0) - { - left_array[0] = v4; // 1 - left_array[1] = v2; // 2 - left_array[2] = v1; // 3 - left_section = 2; // 4 - right_array[0] = v4; - right_array[1] = v3; - right_array[2] = v1; - right_section = 2; - } - else - { - right_array[0] = v4; - right_array[1] = v1; - right_section = 1; - - height = v3->y - v1->y; if(height == 0) height=1; - longest1 = (((v2->y - v1->y) << 16) / height) * ((v3->x - v1->x)>>16) + (v1->x - v2->x); - if(longest1<0) - { - left_array[0] = v4; // 1 - left_array[1] = v3; // 3 - left_array[2] = v1; // 4 - left_section = 2; - } - else - { - height = v4->y - v2->y; if(height == 0) height=1; - longest1 = (((v3->y - v2->y) << 16) / height) * ((v4->x - v2->x)>>16) + (v2->x - v3->x); - if(longest1<0) - { - left_array[0] = v4; // 1 - left_array[1] = v2; // 2 - left_array[2] = v1; // 4 - left_section = 2; - } - else - { - left_array[0] = v4; // 1 - left_array[1] = v3; // 2 - left_array[2] = v2; // 3 - left_array[3] = v1; // 4 - left_section = 3; - } - } - } - } - - while(LeftSection_FT4()<=0) - { - if(--left_section <= 0) break; - } - - while(RightSection_FT4()<=0) - { - if(--right_section <= 0) break; - } - - Ymin=v1->y; - Ymax=min(v4->y-1,drawH); - - return TRUE; -} - -static __inline int RightSection_GT4(void) -{ - soft_vertex * v1 = right_array[ right_section ]; - soft_vertex * v2 = right_array[ right_section-1 ]; - - int height = v2->y - v1->y; - right_section_height = height; - right_x = v1->x; - right_u = v1->u; - right_v = v1->v; - right_R = v1->R; - right_G = v1->G; - right_B = v1->B; - - if(height == 0) - { - return 0; - } - delta_right_x = (v2->x - v1->x) / height; - delta_right_u = (v2->u - v1->u) / height; - delta_right_v = (v2->v - v1->v) / height; - delta_right_R = (v2->R - v1->R) / height; - delta_right_G = (v2->G - v1->G) / height; - delta_right_B = (v2->B - v1->B) / height; - - return height; -} - -static __inline int LeftSection_GT4(void) -{ - soft_vertex * v1 = left_array[ left_section ]; - soft_vertex * v2 = left_array[ left_section-1 ]; - - int height = v2->y - v1->y; - left_section_height = height; - left_x = v1->x; - left_u = v1->u; - left_v = v1->v; - left_R = v1->R; - left_G = v1->G; - left_B = v1->B; - - if(height == 0) - { - return 0; - } - delta_left_x = (v2->x - v1->x) / height; - delta_left_u = (v2->u - v1->u) / height; - delta_left_v = (v2->v - v1->v) / height; - delta_left_R = (v2->R - v1->R) / height; - delta_left_G = (v2->G - v1->G) / height; - delta_left_B = (v2->B - v1->B) / height; - - return height; -} - -static __inline BOOL NextRow_GT4(void) -{ - if(--left_section_height<=0) - { - if(--left_section > 0) - while(LeftSection_GT4()<=0) - { - if(--left_section <= 0) break; - } - } - else - { - left_x += delta_left_x; - left_u += delta_left_u; - left_v += delta_left_v; - left_R += delta_left_R; - left_G += delta_left_G; - left_B += delta_left_B; - } - - if(--right_section_height<=0) - { - if(--right_section > 0) - while(RightSection_GT4()<=0) - { - if(--right_section<=0) break; - } - } - else - { - right_x += delta_right_x; - right_u += delta_right_u; - right_v += delta_right_v; - right_R += delta_right_R; - right_G += delta_right_G; - right_B += delta_right_B; - } - return FALSE; -} - -static __inline BOOL SetupSections_GT4(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4, int rgb1, int rgb2, int rgb3, int rgb4) -{ - soft_vertex * v1, * v2, * v3, * v4; - int height,width,longest1,longest2; - - v1 = vtx; v1->x=x1<<16;v1->y=y1; - v1->u=tx1<<16;v1->v=ty1<<16; - v1->R=(rgb1) & 0x00ff0000; - v1->G=(rgb1<<8) & 0x00ff0000; - v1->B=(rgb1<<16) & 0x00ff0000; - - v2 = vtx+1; v2->x=x2<<16;v2->y=y2; - v2->u=tx2<<16;v2->v=ty2<<16; - v2->R=(rgb2) & 0x00ff0000; - v2->G=(rgb2<<8) & 0x00ff0000; - v2->B=(rgb2<<16) & 0x00ff0000; - - v3 = vtx+2; v3->x=x3<<16;v3->y=y3; - v3->u=tx3<<16;v3->v=ty3<<16; - v3->R=(rgb3) & 0x00ff0000; - v3->G=(rgb3<<8) & 0x00ff0000; - v3->B=(rgb3<<16) & 0x00ff0000; - - v4 = vtx+3; v4->x=x4<<16;v4->y=y4; - v4->u=tx4<<16;v4->v=ty4<<16; - v4->R=(rgb4) & 0x00ff0000; - v4->G=(rgb4<<8) & 0x00ff0000; - v4->B=(rgb4<<16) & 0x00ff0000; - - if(v1->y > v2->y) { soft_vertex * v = v1; v1 = v2; v2 = v; } - if(v1->y > v3->y) { soft_vertex * v = v1; v1 = v3; v3 = v; } - if(v1->y > v4->y) { soft_vertex * v = v1; v1 = v4; v4 = v; } - if(v2->y > v3->y) { soft_vertex * v = v2; v2 = v3; v3 = v; } - if(v2->y > v4->y) { soft_vertex * v = v2; v2 = v4; v4 = v; } - if(v3->y > v4->y) { soft_vertex * v = v3; v3 = v4; v4 = v; } - - height = v4->y - v1->y; if(height == 0) height =1; - width = (v4->x - v1->x)>>16; - longest1 = (((v2->y - v1->y) << 16) / height) * width + (v1->x - v2->x); - longest2 = (((v3->y - v1->y) << 16) / height) * width + (v1->x - v3->x); - - if(longest1 < 0) // 2 is right - { - if(longest2 < 0) // 3 is right - { - left_array[0] = v4; - left_array[1] = v1; - left_section = 1; - - height = v3->y - v1->y; if(height == 0) height=1; - longest1 = (((v2->y - v1->y) << 16) / height) * ((v3->x - v1->x)>>16) + (v1->x - v2->x); - if(longest1 >= 0) - { - right_array[0] = v4; // 1 - right_array[1] = v3; // 3 - right_array[2] = v1; // 4 - right_section = 2; - } - else - { - height = v4->y - v2->y; if(height == 0) height=1; - longest1 = (((v3->y - v2->y) << 16) / height) * ((v4->x - v2->x)>>16) + (v2->x - v3->x); - if(longest1 >= 0) - { - right_array[0] = v4; // 1 - right_array[1] = v2; // 2 - right_array[2] = v1; // 4 - right_section = 2; - } - else - { - right_array[0] = v4; // 1 - right_array[1] = v3; // 2 - right_array[2] = v2; // 3 - right_array[3] = v1; // 4 - right_section = 3; - } - } - } - else - { - left_array[0] = v4; - left_array[1] = v3; // 1 - left_array[2] = v1; // 2 - left_section = 2; // 3 - right_array[0] = v4; // 4 - right_array[1] = v2; - right_array[2] = v1; - right_section = 2; - } - } - else - { - if(longest2 < 0) - { - left_array[0] = v4; // 1 - left_array[1] = v2; // 2 - left_array[2] = v1; // 3 - left_section = 2; // 4 - right_array[0] = v4; - right_array[1] = v3; - right_array[2] = v1; - right_section = 2; - } - else - { - right_array[0] = v4; - right_array[1] = v1; - right_section = 1; - - height = v3->y - v1->y; if(height == 0) height=1; - longest1 = (((v2->y - v1->y) << 16) / height) * ((v3->x - v1->x)>>16) + (v1->x - v2->x); - if(longest1<0) - { - left_array[0] = v4; // 1 - left_array[1] = v3; // 3 - left_array[2] = v1; // 4 - left_section = 2; - } - else - { - height = v4->y - v2->y; if(height == 0) height=1; - longest1 = (((v3->y - v2->y) << 16) / height) * ((v4->x - v2->x)>>16) + (v2->x - v3->x); - if(longest1<0) - { - left_array[0] = v4; // 1 - left_array[1] = v2; // 2 - left_array[2] = v1; // 4 - left_section = 2; - } - else - { - left_array[0] = v4; // 1 - left_array[1] = v3; // 2 - left_array[2] = v2; // 3 - left_array[3] = v1; // 4 - left_section = 3; - } - } - } - } - - while(LeftSection_GT4()<=0) - { - if(--left_section <= 0) break; - } - - while(RightSection_GT4()<=0) - { - if(--right_section <= 0) break; - } - - Ymin=v1->y; - Ymax=min(v4->y-1,drawH); - - return TRUE; -} - -//////////////////////////////////////////////////////////////////////// -// POLY FUNCS -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -// POLY 3/4 FLAT SHADED -//////////////////////////////////////////////////////////////////////// - -static __inline void drawPoly3Fi(short x1, short y1, short x2, short y2, short x3, short y3, int rgb) -{ - int i,j,xmin,xmax,ymin,ymax; - unsigned short color; - uint32_t lcolor; - - if(x1>drawW && x2>drawW && x3>drawW) return; - if(y1>drawH && y2>drawH && y3>drawH) return; - if(x1<drawX && x2<drawX && x3<drawX) return; - if(y1<drawY && y2<drawY && y3<drawY) return; - if(drawY>=drawH) return; - if(drawX>=drawW) return; - - if(!SetupSections_F(x1,y1,x2,y2,x3,y3)) return; - - ymax=Ymax; - - color = ((rgb & 0x00f80000)>>9) | ((rgb & 0x0000f800)>>6) | ((rgb & 0x000000f8)>>3); - lcolor=lSetMask|(((uint32_t)(color))<<16)|color; - - for(ymin=Ymin;ymin<drawY;ymin++) - if(NextRow_F()) return; - -#ifdef FASTSOLID - - if(!bCheckMask && !DrawSemiTrans) - { - color |=sSetMask; - for (i=ymin;i<=ymax;i++) - { - xmin=left_x >> 16; if(drawX>xmin) xmin=drawX; - xmax=(right_x >> 16)-1; if(drawW<xmax) xmax=drawW; - - for(j=xmin;j<xmax;j+=2) - { - *((uint32_t *)&psxVuw[(i<<10)+j])=lcolor; - } - if(j==xmax) psxVuw[(i<<10)+j]=color; - - if(NextRow_F()) return; - } - return; - } - -#endif - - for (i=ymin;i<=ymax;i++) - { - xmin=left_x >> 16; if(drawX>xmin) xmin=drawX; - xmax=(right_x >> 16)-1; if(drawW<xmax) xmax=drawW; - - for(j=xmin;j<xmax;j+=2) - { - GetShadeTransCol32((uint32_t *)&psxVuw[(i<<10)+j], lcolor); - } - if(j == xmax) - GetShadeTransCol(&psxVuw[(i << 10) + j],color); - - if(NextRow_F()) return; - } -} - -//////////////////////////////////////////////////////////////////////// - -void drawPoly3F(int rgb) -{ - drawPoly3Fi(lx0,ly0,lx1,ly1,lx2,ly2,rgb); -} - -#ifdef POLYQUAD3FS - -void drawPoly4F_TRI(int rgb) -{ - drawPoly3Fi(lx1,ly1,lx3,ly3,lx2,ly2,rgb); - drawPoly3Fi(lx0,ly0,lx1,ly1,lx2,ly2,rgb); -} - -#endif - -// more exact: - -void drawPoly4F(int rgb) -{ - int i,j,xmin,xmax,ymin,ymax; - unsigned short color;unsigned int lcolor; - - if(lx0>drawW && lx1>drawW && lx2>drawW && lx3>drawW) return; - if(ly0>drawH && ly1>drawH && ly2>drawH && ly3>drawH) return; - if(lx0<drawX && lx1<drawX && lx2<drawX && lx3<drawX) return; - if(ly0<drawY && ly1<drawY && ly2<drawY && ly3<drawY) return; - if(drawY>=drawH) return; - if(drawX>=drawW) return; - - if(!SetupSections_F4(lx0,ly0,lx1,ly1,lx2,ly2,lx3,ly3)) return; - - ymax=Ymax; - - for(ymin=Ymin;ymin<drawY;ymin++) - if(NextRow_F4()) return; - - color = ((rgb & 0x00f80000)>>9) | ((rgb & 0x0000f800)>>6) | ((rgb & 0x000000f8)>>3); - lcolor= lSetMask|(((uint32_t)(color))<<16)|color; - -#ifdef FASTSOLID - - if(!bCheckMask && !DrawSemiTrans) - { - color |=sSetMask; - for (i=ymin;i<=ymax;i++) - { - xmin=left_x >> 16; if(drawX>xmin) xmin=drawX; - xmax=(right_x >> 16)-1; if(drawW<xmax) xmax=drawW; - - for(j=xmin;j<xmax;j+=2) - { - *((uint32_t *)&psxVuw[(i<<10)+j])=lcolor; - } - if(j==xmax) psxVuw[(i<<10)+j]=color; - - if(NextRow_F4()) return; - } - return; - } - -#endif - - for (i = ymin; i <= ymax; i++) - { - xmin = left_x >> 16; if(drawX > xmin) xmin = drawX; - xmax = (right_x >> 16) - 1; if(drawW < xmax) xmax = drawW; - - for(j = xmin; j < xmax; j += 2) - { - GetShadeTransCol32((uint32_t *)&psxVuw[(i<<10) + j],lcolor); - } - if(j == xmax) GetShadeTransCol(&psxVuw[(i<<10) + j],color); - - if(NextRow_F4()) return; - } -} - -//////////////////////////////////////////////////////////////////////// -// POLY 3/4 F-SHADED TEX PAL 4 -//////////////////////////////////////////////////////////////////////// - -static void drawPoly3TEx4(short x1, short y1, short x2, short y2, short x3, short y3, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3,short clX, short clY) -{ - int i,j,xmin,xmax,ymin,ymax; - int difX, difY,difX2, difY2; - int posX,posY,YAdjust,XAdjust; - int clutP; - short tC1,tC2; - - if (x1 > drawW && x2 > drawW && x3 > drawW) return; - if (y1 > drawH && y2 > drawH && y3 > drawH) return; - if (x1 < drawX && x2 < drawX && x3 < drawX) return; - if (y1 < drawY && y2 < drawY && y3 < drawY) return; - if (drawY >= drawH) return; - if (drawX >= drawW) return; - - if (!SetupSections_FT(x1,y1,x2,y2,x3,y3,tx1,ty1,tx2,ty2,tx3,ty3)) return; - - ymax = Ymax; - - for (ymin = Ymin; ymin < drawY; ymin++) - if (NextRow_FT()) return; - - clutP = (clY << 10) + clX; - - YAdjust = ((GlobalTextAddrY) << 11) + (GlobalTextAddrX << 1); - - difX = delta_right_u; difX2 = difX << 1; - difY = delta_right_v; difY2 = difY << 1; - -#ifdef FASTSOLID - - if(!bCheckMask && !DrawSemiTrans) - { - for (i=ymin;i<=ymax;i++) - { - xmin=(left_x >> 16); - xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!!!! - if(drawW<xmax) xmax=drawW; - - if(xmax>=xmin) - { - posX=left_u; - posY=left_v; - - if(xmin<drawX) - {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;} - - for(j=xmin;j<xmax;j+=2) - { - XAdjust=(posX>>16); - tC1 = psxVub[((posY>>5)&(int)0xFFFFF800)+YAdjust+(XAdjust>>1)]; - tC1=(tC1>>((XAdjust&1)<<2))&0xf; - XAdjust=((posX+difX)>>16); - tC2 = psxVub[(((posY+difY)>>5)&(int)0xFFFFF800)+YAdjust+ - (XAdjust>>1)]; - tC2=(tC2>>((XAdjust&1)<<2))&0xf; - - GetTextureTransColG32_S((uint32_t *)&psxVuw[(i<<10)+j], - psxVuw[clutP+tC1]| - ((int)psxVuw[clutP+tC2])<<16); - - posX+=difX2; - posY+=difY2; - } - if(j==xmax) - { - XAdjust=(posX>>16); - tC1 = psxVub[((posY>>5)&(int)0xFFFFF800)+YAdjust+ - (XAdjust>>1)]; - tC1=(tC1>>((XAdjust&1)<<2))&0xf; - GetTextureTransColG_S(&psxVuw[(i<<10)+j],psxVuw[clutP+tC1]); - } - } - if(NextRow_FT()) - { - return; - } - } - return; - } - -#endif - - for (i=ymin;i<=ymax;i++) - { - xmin=(left_x >> 16); - xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!!!!!! - if(drawW<xmax) xmax=drawW; - - if(xmax>=xmin) - { - posX=left_u; - posY=left_v; - - if(xmin<drawX) - {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;} - - for(j=xmin;j<xmax;j+=2) - { - XAdjust=(posX>>16); - tC1 = psxVub[((posY>>5)&(int)0xFFFFF800)+YAdjust+(XAdjust>>1)]; - tC1=(tC1>>((XAdjust&1)<<2))&0xf; - XAdjust=((posX+difX)>>16); - tC2 = psxVub[(((posY+difY)>>5)&(int)0xFFFFF800)+YAdjust+ - (XAdjust>>1)]; - tC2=(tC2>>((XAdjust&1)<<2))&0xf; - - GetTextureTransColG32((uint32_t *)&psxVuw[(i<<10)+j], - psxVuw[clutP+tC1]| - ((int)psxVuw[clutP+tC2])<<16); - - posX+=difX2; - posY+=difY2; - } - if(j==xmax) - { - XAdjust=(posX>>16); - tC1 = psxVub[((posY>>5)&(int)0xFFFFF800)+YAdjust+ - (XAdjust>>1)]; - tC1=(tC1>>((XAdjust&1)<<2))&0xf; - GetTextureTransColG(&psxVuw[(i<<10)+j],psxVuw[clutP+tC1]); - } - } - if(NextRow_FT()) - { - return; - } - } -} - -//////////////////////////////////////////////////////////////////////// - -static void drawPoly3TEx4_IL(short x1, short y1, short x2, short y2, short x3, short y3, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3,short clX, short clY) -{ - int i,j,xmin,xmax,ymin,ymax,n_xi,n_yi,TXV; - int difX, difY,difX2, difY2; - int posX,posY,YAdjust,XAdjust; - int clutP; - short tC1,tC2; - - if(x1>drawW && x2>drawW && x3>drawW) return; - if(y1>drawH && y2>drawH && y3>drawH) return; - if(x1<drawX && x2<drawX && x3<drawX) return; - if(y1<drawY && y2<drawY && y3<drawY) return; - if(drawY>=drawH) return; - if(drawX>=drawW) return; - - if(!SetupSections_FT(x1,y1,x2,y2,x3,y3,tx1,ty1,tx2,ty2,tx3,ty3)) return; - - ymax=Ymax; - - for(ymin=Ymin;ymin<drawY;ymin++) - if(NextRow_FT()) return; - - clutP=(clY<<10)+clX; - - YAdjust=(GlobalTextAddrY<<10)+GlobalTextAddrX; - - difX=delta_right_u;difX2=difX<<1; - difY=delta_right_v;difY2=difY<<1; - -#ifdef FASTSOLID - - if(!bCheckMask && !DrawSemiTrans) - { - for (i=ymin;i<=ymax;i++) - { - xmin=(left_x >> 16); - xmax=(right_x >> 16)-1; - if(drawW<xmax) xmax=drawW; - - if(xmax>=xmin) - { - posX=left_u; - posY=left_v; - - if(xmin<drawX) - {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;} - - for(j=xmin;j<xmax;j+=2) - { - XAdjust=(posX>>16); - - TXV=posY>>16; - n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c ); - n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf ); - - tC1= (psxVuw[(n_yi<<10)+YAdjust+n_xi] >> ((XAdjust & 0x03)<<2)) & 0x0f ; - - XAdjust=((posX+difX)>>16); - - TXV=(posY+difY)>>16; - n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c ); - n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf ); - - tC2= (psxVuw[(n_yi<<10)+YAdjust+n_xi] >> ((XAdjust & 0x03)<<2)) & 0x0f ; - - GetTextureTransColG32_S((uint32_t *)&psxVuw[(i<<10)+j], - psxVuw[clutP+tC1]| - ((int)psxVuw[clutP+tC2])<<16); - - posX+=difX2; - posY+=difY2; - } - if(j==xmax) - { - XAdjust=(posX>>16); - - TXV=posY>>16; - n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c ); - n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf ); - - tC1= (psxVuw[(n_yi<<10)+YAdjust+n_xi] >> ((XAdjust & 0x03)<<2)) & 0x0f ; - - GetTextureTransColG_S(&psxVuw[(i<<10)+j],psxVuw[clutP+tC1]); - } - } - if(NextRow_FT()) - { - return; - } - } - return; - } - -#endif - - for (i=ymin;i<=ymax;i++) - { - xmin=(left_x >> 16); - xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!!!!!! - if(drawW<xmax) xmax=drawW; - - if(xmax>=xmin) - { - posX=left_u; - posY=left_v; - - if(xmin<drawX) - {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;} - - for(j=xmin;j<xmax;j+=2) - { - XAdjust=(posX>>16); - - TXV=posY>>16; - n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c ); - n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf ); - - tC1= (psxVuw[(n_yi<<10)+YAdjust+n_xi] >> ((XAdjust & 0x03)<<2)) & 0x0f ; - - XAdjust=((posX+difX)>>16); - - TXV=(posY+difY)>>16; - n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c ); - n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf ); - - tC2= (psxVuw[(n_yi<<10)+YAdjust+n_xi] >> ((XAdjust & 0x03)<<2)) & 0x0f ; - - GetTextureTransColG32((uint32_t *)&psxVuw[(i<<10)+j], - psxVuw[clutP+tC1]| - ((int)psxVuw[clutP+tC2])<<16); - - posX+=difX2; - posY+=difY2; - } - if(j==xmax) - { - XAdjust=(posX>>16); - - TXV=posY>>16; - n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c ); - n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf ); - - tC1= (psxVuw[(n_yi<<10)+YAdjust+n_xi] >> ((XAdjust & 0x03)<<2)) & 0x0f ; - - GetTextureTransColG(&psxVuw[(i<<10)+j],psxVuw[clutP+tC1]); - } - } - if(NextRow_FT()) - { - return; - } - } -} - -//////////////////////////////////////////////////////////////////////// - -static void drawPoly3TEx4_TW(short x1, short y1, short x2, short y2, short x3, short y3, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3,short clX, short clY) -{ - int i,j,xmin,xmax,ymin,ymax; - int difX, difY,difX2, difY2; - int posX,posY,YAdjust,XAdjust; - int clutP; - short tC1,tC2; - - if(x1>drawW && x2>drawW && x3>drawW) return; - if(y1>drawH && y2>drawH && y3>drawH) return; - if(x1<drawX && x2<drawX && x3<drawX) return; - if(y1<drawY && y2<drawY && y3<drawY) return; - if(drawY>=drawH) return; - if(drawX>=drawW) return; - - if(!SetupSections_FT(x1,y1,x2,y2,x3,y3,tx1,ty1,tx2,ty2,tx3,ty3)) return; - - ymax=Ymax; - - for(ymin=Ymin;ymin<drawY;ymin++) - if(NextRow_FT()) return; - - clutP=(clY<<10)+clX; - - YAdjust=((GlobalTextAddrY)<<11)+(GlobalTextAddrX<<1); - YAdjust+=(TWin.Position.y0<<11)+(TWin.Position.x0>>1); - - difX=delta_right_u;difX2=difX<<1; - difY=delta_right_v;difY2=difY<<1; - -#ifdef FASTSOLID - - if(!bCheckMask && !DrawSemiTrans) - { - for (i=ymin;i<=ymax;i++) - { - xmin=(left_x >> 16); - xmax=(right_x >> 16);//-1; //!!!!!!!!!!!!!!!! - if(xmax>xmin) xmax--; - - if(drawW<xmax) xmax=drawW; - - if(xmax>=xmin) - { - posX=left_u; - posY=left_v; - - if(xmin<drawX) - {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;} - - for(j=xmin;j<xmax;j+=2) - { - XAdjust=(posX>>16)%TWin.Position.x1; - tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+ - YAdjust+(XAdjust>>1)]; - tC1=(tC1>>((XAdjust&1)<<2))&0xf; - XAdjust=((posX+difX)>>16)%TWin.Position.x1; - tC2 = psxVub[((((posY+difY)>>16)%TWin.Position.y1)<<11)+ - YAdjust+(XAdjust>>1)]; - tC2=(tC2>>((XAdjust&1)<<2))&0xf; - - GetTextureTransColG32_S((uint32_t *)&psxVuw[(i << 10) + j], - psxVuw[clutP+tC1]| - ((int)psxVuw[clutP+tC2])<<16); - - posX+=difX2; - posY+=difY2; - } - if(j==xmax) - { - XAdjust=(posX>>16)%TWin.Position.x1; - tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+ - YAdjust+(XAdjust>>1)]; - tC1=(tC1>>((XAdjust&1)<<2))&0xf; - GetTextureTransColG_S(&psxVuw[(i<<10)+j],psxVuw[clutP+tC1]); - } - } - if(NextRow_FT()) - { - return; - } - } - return; - } - -#endif - - for (i=ymin;i<=ymax;i++) - { - xmin=(left_x >> 16); - xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!!!!!! - if(drawW<xmax) xmax=drawW; - - if(xmax>=xmin) - { - posX=left_u; - posY=left_v; - - if(xmin<drawX) - {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;} - - for(j=xmin;j<xmax;j+=2) - { - XAdjust=(posX>>16)%TWin.Position.x1; - tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+ - YAdjust+(XAdjust>>1)]; - tC1=(tC1>>((XAdjust&1)<<2))&0xf; - XAdjust=((posX+difX)>>16)%TWin.Position.x1; - tC2 = psxVub[((((posY+difY)>>16)%TWin.Position.y1)<<11)+ - YAdjust+(XAdjust>>1)]; - tC2=(tC2>>((XAdjust&1)<<2))&0xf; - - GetTextureTransColG32((uint32_t *)&psxVuw[(i<<10)+j], - psxVuw[clutP+tC1]| - ((int)psxVuw[clutP+tC2])<<16); - - posX+=difX2; - posY+=difY2; - } - if(j==xmax) - { - XAdjust=(posX>>16)%TWin.Position.x1; - tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+ - YAdjust+(XAdjust>>1)]; - tC1=(tC1>>((XAdjust&1)<<2))&0xf; - GetTextureTransColG(&psxVuw[(i<<10)+j],psxVuw[clutP+tC1]); - } - } - if(NextRow_FT()) - { - return; - } - } -} - -//////////////////////////////////////////////////////////////////////// - -#ifdef POLYQUAD3 - -static void drawPoly4TEx4_TRI(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4,short clX, short clY) -{ - drawPoly3TEx4(x2,y2,x3,y3,x4,y4, - tx2,ty2,tx3,ty3,tx4,ty4, - clX,clY); - drawPoly3TEx4(x1,y1,x2,y2,x4,y4, - tx1,ty1,tx2,ty2,tx4,ty4, - clX,clY); -} - -#endif - -// more exact: - -static void drawPoly4TEx4(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4,short clX, short clY) -{ - int num; - int i,j,xmin,xmax,ymin,ymax; - int difX, difY, difX2, difY2; - int posX,posY,YAdjust,clutP,XAdjust; - short tC1,tC2; - - if(x1>drawW && x2>drawW && x3>drawW && x4>drawW) return; - if(y1>drawH && y2>drawH && y3>drawH && y4>drawH) return; - if(x1<drawX && x2<drawX && x3<drawX && x4<drawX) return; - if(y1<drawY && y2<drawY && y3<drawY && y4<drawY) return; - if(drawY>=drawH) return; - if(drawX>=drawW) return; - - if(!SetupSections_FT4(x1,y1,x2,y2,x3,y3,x4,y4,tx1,ty1,tx2,ty2,tx3,ty3,tx4,ty4)) return; - - ymax=Ymax; - - for(ymin=Ymin;ymin<drawY;ymin++) - if(NextRow_FT4()) return; - - clutP=(clY<<10)+clX; - - YAdjust=((GlobalTextAddrY)<<11)+(GlobalTextAddrX<<1); - -#ifdef FASTSOLID - - if(!bCheckMask && !DrawSemiTrans) - { - for (i=ymin;i<=ymax;i++) - { - xmin=(left_x >> 16); - xmax=(right_x >> 16); - - if(xmax>=xmin) - { - posX=left_u; - posY=left_v; - - num=(xmax-xmin); - if(num==0) num=1; - difX=(right_u-posX)/num; - difY=(right_v-posY)/num; - difX2=difX<<1; - difY2=difY<<1; - - if(xmin<drawX) - {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;} - xmax--;if(drawW<xmax) xmax=drawW; - - for(j=xmin;j<xmax;j+=2) - { - XAdjust=(posX>>16); - tC1 = psxVub[((posY>>5)&(int)0xFFFFF800)+YAdjust+(XAdjust>>1)]; - tC1=(tC1>>((XAdjust&1)<<2))&0xf; - XAdjust=((posX+difX)>>16); - tC2 = psxVub[(((posY+difY)>>5)&(int)0xFFFFF800)+YAdjust+ - (XAdjust>>1)]; - tC2=(tC2>>((XAdjust&1)<<2))&0xf; - - GetTextureTransColG32_S((uint32_t *)&psxVuw[(i<<10)+j], - psxVuw[clutP+tC1]| - ((int)psxVuw[clutP+tC2])<<16); - posX+=difX2; - posY+=difY2; - } - if(j==xmax) - { - XAdjust=(posX>>16); - tC1 = psxVub[((posY>>5)&(int)0xFFFFF800)+YAdjust+ - (XAdjust>>1)]; - tC1=(tC1>>((XAdjust&1)<<2))&0xf; - GetTextureTransColG_S(&psxVuw[(i<<10)+j],psxVuw[clutP+tC1]); - } - - } - if(NextRow_FT4()) return; - } - return; - } - -#endif - - for (i=ymin;i<=ymax;i++) - { - xmin=(left_x >> 16); - xmax=(right_x >> 16); - - if(xmax>=xmin) - { - posX=left_u; - posY=left_v; - - num=(xmax-xmin); - if(num==0) num=1; - difX=(right_u-posX)/num; - difY=(right_v-posY)/num; - difX2=difX<<1; - difY2=difY<<1; - - if(xmin<drawX) - {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;} - xmax--;if(drawW<xmax) xmax=drawW; - - for(j=xmin;j<xmax;j+=2) - { - XAdjust=(posX>>16); - tC1 = psxVub[((posY>>5)&(int)0xFFFFF800)+YAdjust+(XAdjust>>1)]; - tC1=(tC1>>((XAdjust&1)<<2))&0xf; - XAdjust=((posX+difX)>>16); - tC2 = psxVub[(((posY+difY)>>5)&(int)0xFFFFF800)+YAdjust+ - (XAdjust>>1)]; - tC2=(tC2>>((XAdjust&1)<<2))&0xf; - - GetTextureTransColG32((uint32_t *)&psxVuw[(i<<10)+j], - psxVuw[clutP+tC1]| - ((int)psxVuw[clutP+tC2])<<16); - posX+=difX2; - posY+=difY2; - } - if(j==xmax) - { - XAdjust=(posX>>16); - tC1 = psxVub[((posY>>5)&(int)0xFFFFF800)+YAdjust+ - (XAdjust>>1)]; - tC1=(tC1>>((XAdjust&1)<<2))&0xf; - GetTextureTransColG(&psxVuw[(i<<10)+j],psxVuw[clutP+tC1]); - } - } - if(NextRow_FT4()) return; - } -} - -//////////////////////////////////////////////////////////////////////// - -static void drawPoly4TEx4_IL(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4,short clX, short clY) -{ - int num; - int i,j,xmin,xmax,ymin,ymax,n_xi,n_yi,TXV; - int difX, difY, difX2, difY2; - int posX,posY,YAdjust,clutP,XAdjust; - short tC1,tC2; - - if(x1>drawW && x2>drawW && x3>drawW && x4>drawW) return; - if(y1>drawH && y2>drawH && y3>drawH && y4>drawH) return; - if(x1<drawX && x2<drawX && x3<drawX && x4<drawX) return; - if(y1<drawY && y2<drawY && y3<drawY && y4<drawY) return; - if(drawY>=drawH) return; - if(drawX>=drawW) return; - - if(!SetupSections_FT4(x1,y1,x2,y2,x3,y3,x4,y4,tx1,ty1,tx2,ty2,tx3,ty3,tx4,ty4)) return; - - ymax=Ymax; - - for(ymin=Ymin;ymin<drawY;ymin++) - if(NextRow_FT4()) return; - - clutP=(clY<<10)+clX; - - YAdjust=((GlobalTextAddrY)<<10)+GlobalTextAddrX; - -#ifdef FASTSOLID - - if(!bCheckMask && !DrawSemiTrans) - { - for (i=ymin;i<=ymax;i++) - { - xmin=(left_x >> 16); - xmax=(right_x >> 16); - - if(xmax>=xmin) - { - posX=left_u; - posY=left_v; - - num=(xmax-xmin); - if(num==0) num=1; - difX=(right_u-posX)/num; - difY=(right_v-posY)/num; - difX2=difX<<1; - difY2=difY<<1; - - if(xmin<drawX) - {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;} - xmax--;if(drawW<xmax) xmax=drawW; - - for(j=xmin;j<xmax;j+=2) - { - XAdjust=(posX>>16); - - TXV=posY>>16; - n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c ); - n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf ); - - tC1= (psxVuw[(n_yi<<10)+YAdjust+n_xi] >> ((XAdjust & 0x03)<<2)) & 0x0f ; - - XAdjust=((posX+difX)>>16); - - TXV=(posY+difY)>>16; - n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c ); - n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf ); - - tC2= (psxVuw[(n_yi<<10)+YAdjust+n_xi] >> ((XAdjust & 0x03)<<2)) & 0x0f ; - - GetTextureTransColG32_S((uint32_t *)&psxVuw[(i<<10)+j], - psxVuw[clutP+tC1]| - ((int)psxVuw[clutP+tC2])<<16); - posX+=difX2; - posY+=difY2; - } - - if(j==xmax) - { - XAdjust=(posX>>16); - TXV=posY>>16; - n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c ); - n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf ); - - tC1= (psxVuw[(n_yi<<10)+YAdjust+n_xi] >> ((XAdjust & 0x03)<<2)) & 0x0f ; - - GetTextureTransColG_S(&psxVuw[(i<<10)+j],psxVuw[clutP+tC1]); - } - - } - if(NextRow_FT4()) return; - } - return; - } - -#endif - - for (i=ymin;i<=ymax;i++) - { - xmin=(left_x >> 16); - xmax=(right_x >> 16); - - if(xmax>=xmin) - { - posX=left_u; - posY=left_v; - - num=(xmax-xmin); - if(num==0) num=1; - difX=(right_u-posX)/num; - difY=(right_v-posY)/num; - difX2=difX<<1; - difY2=difY<<1; - - if(xmin<drawX) - {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;} - xmax--;if(drawW<xmax) xmax=drawW; - - for(j=xmin;j<xmax;j+=2) - { - XAdjust=(posX>>16); - - TXV=posY>>16; - n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c ); - n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf ); - - tC1= (psxVuw[(n_yi<<10)+YAdjust+n_xi] >> ((XAdjust & 0x03)<<2)) & 0x0f ; - - XAdjust=((posX+difX)>>16); - - TXV=(posY+difY)>>16; - n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c ); - n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf ); - - tC2= (psxVuw[(n_yi<<10)+YAdjust+n_xi] >> ((XAdjust & 0x03)<<2)) & 0x0f ; - - GetTextureTransColG32((uint32_t *)&psxVuw[(i<<10)+j], - psxVuw[clutP+tC1]| - ((int)psxVuw[clutP+tC2])<<16); - posX+=difX2; - posY+=difY2; - } - if(j==xmax) - { - XAdjust=(posX>>16); - TXV=posY>>16; - n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c ); - n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf ); - - tC1= (psxVuw[(n_yi<<10)+YAdjust+n_xi] >> ((XAdjust & 0x03)<<2)) & 0x0f ; - - GetTextureTransColG(&psxVuw[(i<<10)+j],psxVuw[clutP+tC1]); - } - } - if(NextRow_FT4()) return; - } -} - -//////////////////////////////////////////////////////////////////////// - -static void drawPoly4TEx4_TW(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4,short clX, short clY) -{ - int num; - int i,j,xmin,xmax,ymin,ymax; - int difX, difY, difX2, difY2; - int posX,posY,YAdjust,clutP,XAdjust; - short tC1,tC2; - - if(x1>drawW && x2>drawW && x3>drawW && x4>drawW) return; - if(y1>drawH && y2>drawH && y3>drawH && y4>drawH) return; - if(x1<drawX && x2<drawX && x3<drawX && x4<drawX) return; - if(y1<drawY && y2<drawY && y3<drawY && y4<drawY) return; - if(drawY>=drawH) return; - if(drawX>=drawW) return; - - if(!SetupSections_FT4(x1,y1,x2,y2,x3,y3,x4,y4,tx1,ty1,tx2,ty2,tx3,ty3,tx4,ty4)) return; - - ymax=Ymax; - - for(ymin=Ymin;ymin<drawY;ymin++) - if(NextRow_FT4()) return; - - clutP=(clY<<10)+clX; - - YAdjust=((GlobalTextAddrY)<<11)+(GlobalTextAddrX<<1); - YAdjust+=(TWin.Position.y0<<11)+(TWin.Position.x0>>1); - -#ifdef FASTSOLID - - if(!bCheckMask && !DrawSemiTrans) - { - for (i=ymin;i<=ymax;i++) - { - xmin=(left_x >> 16); - xmax=(right_x >> 16); - - if(xmax>=xmin) - { - posX=left_u; - posY=left_v; - - num=(xmax-xmin); - if(num==0) num=1; - difX=(right_u-posX)/num; - difY=(right_v-posY)/num; - difX2=difX<<1; - difY2=difY<<1; - - if(xmin<drawX) - {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;} - xmax--;if(drawW<xmax) xmax=drawW; - - for(j=xmin;j<xmax;j+=2) - { - XAdjust=(posX>>16)%TWin.Position.x1; - tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+ - YAdjust+(XAdjust>>1)]; - tC1=(tC1>>((XAdjust&1)<<2))&0xf; - XAdjust=((posX+difX)>>16)%TWin.Position.x1; - tC2 = psxVub[((((posY+difY)>>16)%TWin.Position.y1)<<11)+ - YAdjust+(XAdjust>>1)]; - tC2=(tC2>>((XAdjust&1)<<2))&0xf; - - GetTextureTransColG32_S((uint32_t *)&psxVuw[(i<<10)+j], - psxVuw[clutP+tC1]| - ((int)psxVuw[clutP+tC2])<<16); - posX+=difX2; - posY+=difY2; - } - if(j==xmax) - { - XAdjust=(posX>>16)%TWin.Position.x1; - tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+ - YAdjust+(XAdjust>>1)]; - tC1=(tC1>>((XAdjust&1)<<2))&0xf; - GetTextureTransColG_S(&psxVuw[(i<<10)+j],psxVuw[clutP+tC1]); - } - } - if(NextRow_FT4()) return; - } - return; - } - -#endif - - for (i=ymin;i<=ymax;i++) - { - xmin=(left_x >> 16); - xmax=(right_x >> 16); - - if(xmax>=xmin) - { - posX=left_u; - posY=left_v; - - num=(xmax-xmin); - if(num==0) num=1; - difX=(right_u-posX)/num; - difY=(right_v-posY)/num; - difX2=difX<<1; - difY2=difY<<1; - - if(xmin<drawX) - {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;} - xmax--;if(drawW<xmax) xmax=drawW; - - for(j=xmin;j<xmax;j+=2) - { - XAdjust=(posX>>16)%TWin.Position.x1; - tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+ - YAdjust+(XAdjust>>1)]; - tC1=(tC1>>((XAdjust&1)<<2))&0xf; - XAdjust=((posX+difX)>>16)%TWin.Position.x1; - tC2 = psxVub[((((posY+difY)>>16)%TWin.Position.y1)<<11)+ - YAdjust+(XAdjust>>1)]; - tC2=(tC2>>((XAdjust&1)<<2))&0xf; - - GetTextureTransColG32((uint32_t *)&psxVuw[(i<<10)+j], - psxVuw[clutP+tC1]| - ((int)psxVuw[clutP+tC2])<<16); - posX+=difX2; - posY+=difY2; - } - if(j==xmax) - { - XAdjust=(posX>>16)%TWin.Position.x1; - tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+ - YAdjust+(XAdjust>>1)]; - tC1=(tC1>>((XAdjust&1)<<2))&0xf; - GetTextureTransColG(&psxVuw[(i<<10)+j],psxVuw[clutP+tC1]); - } - } - if(NextRow_FT4()) return; - } -} - -//////////////////////////////////////////////////////////////////////// - -static void drawPoly4TEx4_TW_S(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4,short clX, short clY) -{ - int num; - int i,j,xmin,xmax,ymin,ymax; - int difX, difY, difX2, difY2; - int posX,posY,YAdjust,clutP,XAdjust; - short tC1,tC2; - - if(x1>drawW && x2>drawW && x3>drawW && x4>drawW) return; - if(y1>drawH && y2>drawH && y3>drawH && y4>drawH) return; - if(x1<drawX && x2<drawX && x3<drawX && x4<drawX) return; - if(y1<drawY && y2<drawY && y3<drawY && y4<drawY) return; - if(drawY>=drawH) return; - if(drawX>=drawW) return; - - if(!SetupSections_FT4(x1,y1,x2,y2,x3,y3,x4,y4,tx1,ty1,tx2,ty2,tx3,ty3,tx4,ty4)) return; - - ymax=Ymax; - - for(ymin=Ymin;ymin<drawY;ymin++) - if(NextRow_FT4()) return; - - clutP=(clY<<10)+clX; - - YAdjust=((GlobalTextAddrY)<<11)+(GlobalTextAddrX<<1); - YAdjust+=(TWin.Position.y0<<11)+(TWin.Position.x0>>1); - -#ifdef FASTSOLID - - if(!bCheckMask && !DrawSemiTrans) - { - for (i=ymin;i<=ymax;i++) - { - xmin=(left_x >> 16); - xmax=(right_x >> 16); - - if(xmax>=xmin) - { - posX=left_u; - posY=left_v; - - num=(xmax-xmin); - if(num==0) num=1; - difX=(right_u-posX)/num; - difY=(right_v-posY)/num; - difX2=difX<<1; - difY2=difY<<1; - - if(xmin<drawX) - {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;} - xmax--;if(drawW<xmax) xmax=drawW; - - for(j=xmin;j<xmax;j+=2) - { - XAdjust=(posX>>16)%TWin.Position.x1; - tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+ - YAdjust+(XAdjust>>1)]; - tC1=(tC1>>((XAdjust&1)<<2))&0xf; - XAdjust=((posX+difX)>>16)%TWin.Position.x1; - tC2 = psxVub[((((posY+difY)>>16)%TWin.Position.y1)<<11)+ - YAdjust+(XAdjust>>1)]; - tC2=(tC2>>((XAdjust&1)<<2))&0xf; - - GetTextureTransColG32_S((uint32_t *)&psxVuw[(i<<10)+j], - psxVuw[clutP+tC1]| - ((int)psxVuw[clutP+tC2])<<16); - posX+=difX2; - posY+=difY2; - } - if(j==xmax) - { - XAdjust=(posX>>16)%TWin.Position.x1; - tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+ - YAdjust+(XAdjust>>1)]; - tC1=(tC1>>((XAdjust&1)<<2))&0xf; - GetTextureTransColG_S(&psxVuw[(i<<10)+j],psxVuw[clutP+tC1]); - } - } - if(NextRow_FT4()) return; - } - return; - } - -#endif - - for (i=ymin;i<=ymax;i++) - { - xmin=(left_x >> 16); - xmax=(right_x >> 16); - - if(xmax>=xmin) - { - posX=left_u; - posY=left_v; - - num=(xmax-xmin); - if(num==0) num=1; - difX=(right_u-posX)/num; - difY=(right_v-posY)/num; - difX2=difX<<1; - difY2=difY<<1; - - if(xmin<drawX) - {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;} - xmax--;if(drawW<xmax) xmax=drawW; - - for(j=xmin;j<xmax;j+=2) - { - XAdjust=(posX>>16)%TWin.Position.x1; - tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+ - YAdjust+(XAdjust>>1)]; - tC1=(tC1>>((XAdjust&1)<<2))&0xf; - XAdjust=((posX+difX)>>16)%TWin.Position.x1; - tC2 = psxVub[((((posY+difY)>>16)%TWin.Position.y1)<<11)+ - YAdjust+(XAdjust>>1)]; - tC2=(tC2>>((XAdjust&1)<<2))&0xf; - - GetTextureTransColG32_SPR((uint32_t *)&psxVuw[(i<<10)+j], - psxVuw[clutP+tC1]| - ((int)psxVuw[clutP+tC2])<<16); - posX+=difX2; - posY+=difY2; - } - if(j==xmax) - { - XAdjust=(posX>>16)%TWin.Position.x1; - tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+ - YAdjust+(XAdjust>>1)]; - tC1=(tC1>>((XAdjust&1)<<2))&0xf; - GetTextureTransColG_SPR(&psxVuw[(i<<10)+j],psxVuw[clutP+tC1]); - } - } - if(NextRow_FT4()) return; - } -} -//////////////////////////////////////////////////////////////////////// -// POLY 3 F-SHADED TEX PAL 8 -//////////////////////////////////////////////////////////////////////// - -static void drawPoly3TEx8(short x1, short y1, short x2, short y2, short x3, short y3, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3,short clX, short clY) -{ - int i,j,xmin,xmax,ymin,ymax; - int difX, difY,difX2, difY2; - int posX,posY,YAdjust,clutP; - short tC1,tC2; - - if(x1>drawW && x2>drawW && x3>drawW) return; - if(y1>drawH && y2>drawH && y3>drawH) return; - if(x1<drawX && x2<drawX && x3<drawX) return; - if(y1<drawY && y2<drawY && y3<drawY) return; - if(drawY>=drawH) return; - if(drawX>=drawW) return; - - if(!SetupSections_FT(x1,y1,x2,y2,x3,y3,tx1,ty1,tx2,ty2,tx3,ty3)) return; - - ymax=Ymax; - - for(ymin=Ymin;ymin<drawY;ymin++) - if(NextRow_FT()) return; - - clutP=(clY<<10)+clX; - - YAdjust=((GlobalTextAddrY)<<11)+(GlobalTextAddrX<<1); - - difX=delta_right_u;difX2=difX<<1; - difY=delta_right_v;difY2=difY<<1; - -#ifdef FASTSOLID - - if(!bCheckMask && !DrawSemiTrans) - { - for (i=ymin;i<=ymax;i++) - { - xmin=(left_x >> 16); - xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!!! - if(drawW<xmax) xmax=drawW; - - if(xmax>=xmin) - { - posX=left_u; - posY=left_v; - - if(xmin<drawX) - {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;} - - for(j=xmin;j<xmax;j+=2) - { - tC1 = psxVub[((posY>>5)&(int)0xFFFFF800)+YAdjust+(posX>>16)]; - tC2 = psxVub[(((posY+difY)>>5)&(int)0xFFFFF800)+YAdjust+ - ((posX+difX)>>16)]; - GetTextureTransColG32_S((uint32_t *)&psxVuw[(i<<10)+j], - psxVuw[clutP+tC1]| - ((int)psxVuw[clutP+tC2])<<16); - posX+=difX2; - posY+=difY2; - } - - if(j==xmax) - { - tC1 = psxVub[((posY>>5)&(int)0xFFFFF800)+YAdjust+(posX>>16)]; - GetTextureTransColG_S(&psxVuw[(i<<10)+j],psxVuw[clutP+tC1]); - } - } - if(NextRow_FT()) - { - return; - } - } - return; - } - -#endif - - for (i=ymin;i<=ymax;i++) - { - xmin=(left_x >> 16); - xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!!!!! - if(drawW<xmax) xmax=drawW; - - if(xmax>=xmin) - { - posX=left_u; - posY=left_v; - - if(xmin<drawX) - {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;} - - for(j=xmin;j<xmax;j+=2) - { - tC1 = psxVub[((posY>>5)&(int)0xFFFFF800)+YAdjust+(posX>>16)]; - tC2 = psxVub[(((posY+difY)>>5)&(int)0xFFFFF800)+YAdjust+ - ((posX+difX)>>16)]; - GetTextureTransColG32((uint32_t *)&psxVuw[(i<<10)+j], - psxVuw[clutP+tC1]| - ((int)psxVuw[clutP+tC2])<<16); - posX+=difX2; - posY+=difY2; - } - - if(j==xmax) - { - tC1 = psxVub[((posY>>5)&(int)0xFFFFF800)+YAdjust+(posX>>16)]; - GetTextureTransColG(&psxVuw[(i<<10)+j],psxVuw[clutP+tC1]); - } - - } - if(NextRow_FT()) - { - return; - } - } -} - -//////////////////////////////////////////////////////////////////////// - -static void drawPoly3TEx8_IL(short x1, short y1, short x2, short y2, short x3, short y3, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3,short clX, short clY) -{ - int i,j,xmin,xmax,ymin,ymax,n_xi,n_yi,TXV,TXU; - int difX, difY,difX2, difY2; - int posX,posY,YAdjust,clutP; - short tC1,tC2; - - if(x1>drawW && x2>drawW && x3>drawW) return; - if(y1>drawH && y2>drawH && y3>drawH) return; - if(x1<drawX && x2<drawX && x3<drawX) return; - if(y1<drawY && y2<drawY && y3<drawY) return; - if(drawY>=drawH) return; - if(drawX>=drawW) return; - - if(!SetupSections_FT(x1,y1,x2,y2,x3,y3,tx1,ty1,tx2,ty2,tx3,ty3)) return; - - ymax=Ymax; - - for(ymin=Ymin;ymin<drawY;ymin++) - if(NextRow_FT()) return; - - clutP=(clY<<10)+clX; - - YAdjust=(GlobalTextAddrY<<10)+GlobalTextAddrX; - - difX=delta_right_u;difX2=difX<<1; - difY=delta_right_v;difY2=difY<<1; - -#ifdef FASTSOLID - - if(!bCheckMask && !DrawSemiTrans) - { - for (i=ymin;i<=ymax;i++) - { - xmin=(left_x >> 16); - xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!!! - if(drawW<xmax) xmax=drawW; - - if(xmax>=xmin) - { - posX=left_u; - posY=left_v; - - if(xmin<drawX) - {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;} - - for(j=xmin;j<xmax;j+=2) - { - TXU=posX>>16; - TXV=posY>>16; - n_xi = ( ( TXU >> 1 ) & ~0x78 ) + ( ( TXU << 2 ) & 0x40 ) + ( ( TXV << 3 ) & 0x38 ); - n_yi = ( TXV & ~0x7 ) + ( ( TXU >> 5 ) & 0x7 ); - - tC1= (psxVuw[(n_yi<<10)+YAdjust+n_xi] >> ((TXU & 0x01)<<3)) & 0xff; - - TXU=(posX+difX)>>16; - TXV=(posY+difY)>>16; - n_xi = ( ( TXU >> 1 ) & ~0x78 ) + ( ( TXU << 2 ) & 0x40 ) + ( ( TXV << 3 ) & 0x38 ); - n_yi = ( TXV & ~0x7 ) + ( ( TXU >> 5 ) & 0x7 ); - - tC2= (psxVuw[(n_yi<<10)+YAdjust+n_xi] >> ((TXU & 0x01)<<3)) & 0xff; - - GetTextureTransColG32_S((uint32_t *)&psxVuw[(i<<10)+j], - psxVuw[clutP+tC1]| - ((int)psxVuw[clutP+tC2])<<16); - posX+=difX2; - posY+=difY2; - } - - if(j==xmax) - { - TXU=posX>>16; - TXV=posY>>16; - n_xi = ( ( TXU >> 1 ) & ~0x78 ) + ( ( TXU << 2 ) & 0x40 ) + ( ( TXV << 3 ) & 0x38 ); - n_yi = ( TXV & ~0x7 ) + ( ( TXU >> 5 ) & 0x7 ); - - tC1= (psxVuw[(n_yi<<10)+YAdjust+n_xi] >> ((TXU & 0x01)<<3)) & 0xff; - - GetTextureTransColG_S(&psxVuw[(i<<10)+j],psxVuw[clutP+tC1]); - } - } - if(NextRow_FT()) - { - return; - } - } - return; - } - -#endif - - for (i=ymin;i<=ymax;i++) - { - xmin=(left_x >> 16); - xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!!!!! - if(drawW<xmax) xmax=drawW; - - if(xmax>=xmin) - { - posX=left_u; - posY=left_v; - - if(xmin<drawX) - {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;} - - for(j=xmin;j<xmax;j+=2) - { - TXU=posX>>16; - TXV=posY>>16; - n_xi = ( ( TXU >> 1 ) & ~0x78 ) + ( ( TXU << 2 ) & 0x40 ) + ( ( TXV << 3 ) & 0x38 ); - n_yi = ( TXV & ~0x7 ) + ( ( TXU >> 5 ) & 0x7 ); - - tC1= (psxVuw[(n_yi<<10)+YAdjust+n_xi] >> ((TXU & 0x01)<<3)) & 0xff; - - TXU=(posX+difX)>>16; - TXV=(posY+difY)>>16; - n_xi = ( ( TXU >> 1 ) & ~0x78 ) + ( ( TXU << 2 ) & 0x40 ) + ( ( TXV << 3 ) & 0x38 ); - n_yi = ( TXV & ~0x7 ) + ( ( TXU >> 5 ) & 0x7 ); - - tC2= (psxVuw[(n_yi<<10)+YAdjust+n_xi] >> ((TXU & 0x01)<<3)) & 0xff; - - GetTextureTransColG32((uint32_t *)&psxVuw[(i<<10)+j], - psxVuw[clutP+tC1]| - ((int)psxVuw[clutP+tC2])<<16); - posX+=difX2; - posY+=difY2; - } - - if(j==xmax) - { - TXU=posX>>16; - TXV=posY>>16; - n_xi = ( ( TXU >> 1 ) & ~0x78 ) + ( ( TXU << 2 ) & 0x40 ) + ( ( TXV << 3 ) & 0x38 ); - n_yi = ( TXV & ~0x7 ) + ( ( TXU >> 5 ) & 0x7 ); - - tC1= (psxVuw[(n_yi<<10)+YAdjust+n_xi] >> ((TXU & 0x01)<<3)) & 0xff; - - GetTextureTransColG(&psxVuw[(i<<10)+j],psxVuw[clutP+tC1]); - } - - } - if(NextRow_FT()) - { - return; - } - } -} - -//////////////////////////////////////////////////////////////////////// - -static void drawPoly3TEx8_TW(short x1, short y1, short x2, short y2, short x3, short y3, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3,short clX, short clY) -{ - int i,j,xmin,xmax,ymin,ymax; - int difX, difY,difX2, difY2; - int posX,posY,YAdjust,clutP; - short tC1,tC2; - - if(x1>drawW && x2>drawW && x3>drawW) return; - if(y1>drawH && y2>drawH && y3>drawH) return; - if(x1<drawX && x2<drawX && x3<drawX) return; - if(y1<drawY && y2<drawY && y3<drawY) return; - if(drawY>=drawH) return; - if(drawX>=drawW) return; - - if(!SetupSections_FT(x1,y1,x2,y2,x3,y3,tx1,ty1,tx2,ty2,tx3,ty3)) return; - - ymax=Ymax; - - for(ymin=Ymin;ymin<drawY;ymin++) - if(NextRow_FT()) return; - - clutP=(clY<<10)+clX; - - YAdjust=((GlobalTextAddrY)<<11)+(GlobalTextAddrX<<1); - YAdjust+=(TWin.Position.y0<<11)+(TWin.Position.x0); - - difX=delta_right_u;difX2=difX<<1; - difY=delta_right_v;difY2=difY<<1; - -#ifdef FASTSOLID - - if(!bCheckMask && !DrawSemiTrans) - { - for (i=ymin;i<=ymax;i++) - { - xmin=(left_x >> 16); - xmax=(right_x >> 16);//-1; //!!!!!!!!!!!!!!!! - if(xmax>xmin) xmax--; - - if(drawW<xmax) xmax=drawW; - - if(xmax>=xmin) - { - posX=left_u; - posY=left_v; - - if(xmin<drawX) - {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;} - - for(j=xmin;j<xmax;j+=2) - { - tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+ - YAdjust+((posX>>16)%TWin.Position.x1)]; - tC2 = psxVub[((((posY+difY)>>16)%TWin.Position.y1)<<11)+ - YAdjust+(((posX+difX)>>16)%TWin.Position.x1)]; - GetTextureTransColG32_S((uint32_t *)&psxVuw[(i<<10)+j], - psxVuw[clutP+tC1]| - ((int)psxVuw[clutP+tC2])<<16); - posX+=difX2; - posY+=difY2; - } - - if(j==xmax) - { - tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+ - YAdjust+((posX>>16)%TWin.Position.x1)]; - GetTextureTransColG_S(&psxVuw[(i<<10)+j],psxVuw[clutP+tC1]); - } - } - if(NextRow_FT()) - { - return; - } - } - return; - } - -#endif - - for (i=ymin;i<=ymax;i++) - { - xmin=(left_x >> 16); - xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!!!!! - if(drawW<xmax) xmax=drawW; - - if(xmax>=xmin) - { - posX=left_u; - posY=left_v; - - if(xmin<drawX) - {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;} - - for(j=xmin;j<xmax;j+=2) - { - tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+ - YAdjust+((posX>>16)%TWin.Position.x1)]; - tC2 = psxVub[((((posY+difY)>>16)%TWin.Position.y1)<<11)+ - YAdjust+(((posX+difX)>>16)%TWin.Position.x1)]; - GetTextureTransColG32((uint32_t *)&psxVuw[(i<<10)+j], - psxVuw[clutP+tC1]| - ((int)psxVuw[clutP+tC2])<<16); - posX+=difX2; - posY+=difY2; - } - - if(j==xmax) - { - tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+ - YAdjust+((posX>>16)%TWin.Position.x1)]; - GetTextureTransColG(&psxVuw[(i<<10)+j],psxVuw[clutP+tC1]); - } - - } - if(NextRow_FT()) - { - return; - } - } -} - -//////////////////////////////////////////////////////////////////////// - -#ifdef POLYQUAD3 - -static void drawPoly4TEx8_TRI(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4,short clX, short clY) -{ - drawPoly3TEx8(x2,y2,x3,y3,x4,y4, - tx2,ty2,tx3,ty3,tx4,ty4, - clX,clY); - - drawPoly3TEx8(x1,y1,x2,y2,x4,y4, - tx1,ty1,tx2,ty2,tx4,ty4, - clX,clY); -} - -#endif - -// more exact: - -static void drawPoly4TEx8(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4,short clX, short clY) -{ - int num; - int i,j,xmin,xmax,ymin,ymax; - int difX, difY, difX2, difY2; - int posX,posY,YAdjust,clutP; - short tC1,tC2; - - if(x1>drawW && x2>drawW && x3>drawW && x4>drawW) return; - if(y1>drawH && y2>drawH && y3>drawH && y4>drawH) return; - if(x1<drawX && x2<drawX && x3<drawX && x4<drawX) return; - if(y1<drawY && y2<drawY && y3<drawY && y4<drawY) return; - if(drawY>=drawH) return; - if(drawX>=drawW) return; - - if(!SetupSections_FT4(x1,y1,x2,y2,x3,y3,x4,y4,tx1,ty1,tx2,ty2,tx3,ty3,tx4,ty4)) return; - - ymax=Ymax; - - for(ymin=Ymin;ymin<drawY;ymin++) - if(NextRow_FT4()) return; - - clutP=(clY<<10)+clX; - - YAdjust=((GlobalTextAddrY)<<11)+(GlobalTextAddrX<<1); - -#ifdef FASTSOLID - - if(!bCheckMask && !DrawSemiTrans) - { - for (i=ymin;i<=ymax;i++) - { - xmin=(left_x >> 16); - xmax=(right_x >> 16); - - if(xmax>=xmin) - { - posX=left_u; - posY=left_v; - - num=(xmax-xmin); - if(num==0) num=1; - difX=(right_u-posX)/num; - difY=(right_v-posY)/num; - difX2=difX<<1; - difY2=difY<<1; - - if(xmin<drawX) - {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;} - xmax--;if(drawW<xmax) xmax=drawW; - - for(j=xmin;j<xmax;j+=2) - { - tC1 = psxVub[((posY>>5)&(int)0xFFFFF800)+YAdjust+(posX>>16)]; - tC2 = psxVub[(((posY+difY)>>5)&(int)0xFFFFF800)+YAdjust+ - ((posX+difX)>>16)]; - GetTextureTransColG32_S((uint32_t *)&psxVuw[(i<<10)+j], - psxVuw[clutP+tC1]| - ((int)psxVuw[clutP+tC2])<<16); - posX+=difX2; - posY+=difY2; - } - if(j==xmax) - { - tC1 = psxVub[((posY>>5)&(int)0xFFFFF800)+YAdjust+(posX>>16)]; - GetTextureTransColG_S(&psxVuw[(i<<10)+j],psxVuw[clutP+tC1]); - } - } - if(NextRow_FT4()) return; - } - return; - } - -#endif - - for (i=ymin;i<=ymax;i++) - { - xmin=(left_x >> 16); - xmax=(right_x >> 16); - - if(xmax>=xmin) - { - posX=left_u; - posY=left_v; - - num=(xmax-xmin); - if(num==0) num=1; - difX=(right_u-posX)/num; - difY=(right_v-posY)/num; - difX2=difX<<1; - difY2=difY<<1; - - if(xmin<drawX) - {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;} - xmax--;if(drawW<xmax) xmax=drawW; - - for(j=xmin;j<xmax;j+=2) - { - tC1 = psxVub[((posY>>5)&(int)0xFFFFF800)+YAdjust+(posX>>16)]; - tC2 = psxVub[(((posY+difY)>>5)&(int)0xFFFFF800)+YAdjust+ - ((posX+difX)>>16)]; - GetTextureTransColG32((uint32_t *)&psxVuw[(i<<10)+j], - psxVuw[clutP+tC1]| - ((int)psxVuw[clutP+tC2])<<16); - posX+=difX2; - posY+=difY2; - } - if(j==xmax) - { - tC1 = psxVub[((posY>>5)&(int)0xFFFFF800)+YAdjust+(posX>>16)]; - GetTextureTransColG(&psxVuw[(i<<10)+j],psxVuw[clutP+tC1]); - } - } - if(NextRow_FT4()) return; - } -} - -//////////////////////////////////////////////////////////////////////// - -static void drawPoly4TEx8_IL(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4,short clX, short clY) -{ - int num; - int i,j,xmin,xmax,ymin,ymax,n_xi,n_yi,TXV,TXU; - int difX, difY, difX2, difY2; - int posX,posY,YAdjust,clutP; - short tC1,tC2; - - if(x1>drawW && x2>drawW && x3>drawW && x4>drawW) return; - if(y1>drawH && y2>drawH && y3>drawH && y4>drawH) return; - if(x1<drawX && x2<drawX && x3<drawX && x4<drawX) return; - if(y1<drawY && y2<drawY && y3<drawY && y4<drawY) return; - if(drawY>=drawH) return; - if(drawX>=drawW) return; - - if(!SetupSections_FT4(x1,y1,x2,y2,x3,y3,x4,y4,tx1,ty1,tx2,ty2,tx3,ty3,tx4,ty4)) return; - - ymax=Ymax; - - for(ymin=Ymin;ymin<drawY;ymin++) - if(NextRow_FT4()) return; - - clutP=(clY<<10)+clX; - - YAdjust=(GlobalTextAddrY<<10)+GlobalTextAddrX; - -#ifdef FASTSOLID - - if(!bCheckMask && !DrawSemiTrans) - { - for (i=ymin;i<=ymax;i++) - { - xmin=(left_x >> 16); - xmax=(right_x >> 16); - - if(xmax>=xmin) - { - posX=left_u; - posY=left_v; - - num=(xmax-xmin); - if(num==0) num=1; - difX=(right_u-posX)/num; - difY=(right_v-posY)/num; - difX2=difX<<1; - difY2=difY<<1; - - if(xmin<drawX) - {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;} - xmax--;if(drawW<xmax) xmax=drawW; - - for(j=xmin;j<xmax;j+=2) - { - TXU=posX>>16; - TXV=posY>>16; - n_xi = ( ( TXU >> 1 ) & ~0x78 ) + ( ( TXU << 2 ) & 0x40 ) + ( ( TXV << 3 ) & 0x38 ); - n_yi = ( TXV & ~0x7 ) + ( ( TXU >> 5 ) & 0x7 ); - - tC1= (psxVuw[(n_yi<<10)+YAdjust+n_xi] >> ((TXU & 0x01)<<3)) & 0xff; - - TXU=(posX+difX)>>16; - TXV=(posY+difY)>>16; - n_xi = ( ( TXU >> 1 ) & ~0x78 ) + ( ( TXU << 2 ) & 0x40 ) + ( ( TXV << 3 ) & 0x38 ); - n_yi = ( TXV & ~0x7 ) + ( ( TXU >> 5 ) & 0x7 ); - - tC2= (psxVuw[(n_yi<<10)+YAdjust+n_xi] >> ((TXU & 0x01)<<3)) & 0xff; - - GetTextureTransColG32_S((uint32_t *)&psxVuw[(i<<10)+j], - psxVuw[clutP+tC1]| - ((int)psxVuw[clutP+tC2])<<16); - posX+=difX2; - posY+=difY2; - } - if(j==xmax) - { - TXU=posX>>16; - TXV=posY>>16; - n_xi = ( ( TXU >> 1 ) & ~0x78 ) + ( ( TXU << 2 ) & 0x40 ) + ( ( TXV << 3 ) & 0x38 ); - n_yi = ( TXV & ~0x7 ) + ( ( TXU >> 5 ) & 0x7 ); - - tC1= (psxVuw[(n_yi<<10)+YAdjust+n_xi] >> ((TXU & 0x01)<<3)) & 0xff; - - GetTextureTransColG_S(&psxVuw[(i<<10)+j],psxVuw[clutP+tC1]); - } - } - if(NextRow_FT4()) return; - } - return; - } - -#endif - - for (i=ymin;i<=ymax;i++) - { - xmin=(left_x >> 16); - xmax=(right_x >> 16); - - if(xmax>=xmin) - { - posX=left_u; - posY=left_v; - - num=(xmax-xmin); - if(num==0) num=1; - difX=(right_u-posX)/num; - difY=(right_v-posY)/num; - difX2=difX<<1; - difY2=difY<<1; - - if(xmin<drawX) - {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;} - xmax--;if(drawW<xmax) xmax=drawW; - - for(j=xmin;j<xmax;j+=2) - { - TXU=posX>>16; - TXV=posY>>16; - n_xi = ( ( TXU >> 1 ) & ~0x78 ) + ( ( TXU << 2 ) & 0x40 ) + ( ( TXV << 3 ) & 0x38 ); - n_yi = ( TXV & ~0x7 ) + ( ( TXU >> 5 ) & 0x7 ); - - tC1= (psxVuw[(n_yi<<10)+YAdjust+n_xi] >> ((TXU & 0x01)<<3)) & 0xff; - - TXU=(posX+difX)>>16; - TXV=(posY+difY)>>16; - n_xi = ( ( TXU >> 1 ) & ~0x78 ) + ( ( TXU << 2 ) & 0x40 ) + ( ( TXV << 3 ) & 0x38 ); - n_yi = ( TXV & ~0x7 ) + ( ( TXU >> 5 ) & 0x7 ); - - tC2= (psxVuw[(n_yi<<10)+YAdjust+n_xi] >> ((TXU & 0x01)<<3)) & 0xff; - - GetTextureTransColG32((uint32_t *)&psxVuw[(i<<10)+j], - psxVuw[clutP+tC1]| - ((int)psxVuw[clutP+tC2])<<16); - posX+=difX2; - posY+=difY2; - } - if(j==xmax) - { - TXU=posX>>16; - TXV=posY>>16; - n_xi = ( ( TXU >> 1 ) & ~0x78 ) + ( ( TXU << 2 ) & 0x40 ) + ( ( TXV << 3 ) & 0x38 ); - n_yi = ( TXV & ~0x7 ) + ( ( TXU >> 5 ) & 0x7 ); - tC1= (psxVuw[(n_yi<<10)+YAdjust+n_xi] >> ((TXU & 0x01)<<3)) & 0xff; - GetTextureTransColG(&psxVuw[(i<<10)+j],psxVuw[clutP+tC1]); - } - } - if(NextRow_FT4()) return; - } -} - -//////////////////////////////////////////////////////////////////////// - -static void drawPoly4TEx8_TW(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4,short clX, short clY) -{ - int num; - int i, j, xmin, xmax, ymin, ymax; - int difX, difY, difX2, difY2; - int posX, posY, YAdjust, clutP; - short tC1, tC2; - - if(x1>drawW && x2>drawW && x3>drawW && x4>drawW) return; - if(y1>drawH && y2>drawH && y3>drawH && y4>drawH) return; - if(x1<drawX && x2<drawX && x3<drawX && x4<drawX) return; - if(y1<drawY && y2<drawY && y3<drawY && y4<drawY) return; - if(drawY>=drawH) return; - if(drawX>=drawW) return; - - if(!SetupSections_FT4(x1,y1,x2,y2,x3,y3,x4,y4,tx1,ty1,tx2,ty2,tx3,ty3,tx4,ty4)) return; - - ymax=Ymax; - - for(ymin=Ymin;ymin<drawY;ymin++) - if(NextRow_FT4()) return; - - clutP=(clY<<10)+clX; - - YAdjust=((GlobalTextAddrY)<<11)+(GlobalTextAddrX<<1); - YAdjust+=(TWin.Position.y0<<11)+(TWin.Position.x0); - -#ifdef FASTSOLID - - if(!bCheckMask && !DrawSemiTrans) - { - for (i=ymin;i<=ymax;i++) - { - xmin=(left_x >> 16); - xmax=(right_x >> 16); - - if(xmax>=xmin) - { - posX=left_u; - posY=left_v; - - num=(xmax-xmin); - if(num==0) num=1; - difX=(right_u-posX)/num; - difY=(right_v-posY)/num; - difX2=difX<<1; - difY2=difY<<1; - - if(xmin<drawX) - {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;} - xmax--;if(drawW<xmax) xmax=drawW; - - for(j=xmin;j<xmax;j+=2) - { - tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+ - YAdjust+((posX>>16)%TWin.Position.x1)]; - tC2 = psxVub[((((posY+difY)>>16)%TWin.Position.y1)<<11)+ - YAdjust+(((posX+difX)>>16)%TWin.Position.x1)]; - GetTextureTransColG32_S((uint32_t *)&psxVuw[(i<<10)+j], - psxVuw[clutP+tC1]| - ((int)psxVuw[clutP+tC2])<<16); - posX += difX2; - posY += difY2; - } - if(j==xmax) - { - tC1 = psxVub[((((posY+difY)>>16)%TWin.Position.y1)<<11)+ - YAdjust+((posX>>16)%TWin.Position.x1)]; - GetTextureTransColG_S(&psxVuw[(i<<10)+j],psxVuw[clutP+tC1]); - } - } - if(NextRow_FT4()) return; - } - return; - } - -#endif - - - for (i=ymin;i<=ymax;i++) - { - xmin=(left_x >> 16); - xmax=(right_x >> 16); - - if(xmax>=xmin) - { - posX=left_u; - posY=left_v; - - num=(xmax-xmin); - if(num==0) num=1; - difX=(right_u-posX)/num; - difY=(right_v-posY)/num; - difX2=difX<<1; - difY2=difY<<1; - - if(xmin<drawX) - {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;} - xmax--;if(drawW<xmax) xmax=drawW; - - for(j=xmin;j<xmax;j+=2) - { - tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+ - YAdjust+((posX>>16)%TWin.Position.x1)]; - tC2 = psxVub[((((posY+difY)>>16)%TWin.Position.y1)<<11)+ - YAdjust+(((posX+difX)>>16)%TWin.Position.x1)]; - GetTextureTransColG32((uint32_t *)&psxVuw[(i<<10)+j], - psxVuw[clutP+tC1]| - ((int)psxVuw[clutP+tC2])<<16); - posX+=difX2; - posY+=difY2; - } - if(j==xmax) - { - tC1 = psxVub[((((posY+difY)>>16)%TWin.Position.y1)<<11)+ - YAdjust+((posX>>16)%TWin.Position.x1)]; - GetTextureTransColG(&psxVuw[(i<<10)+j],psxVuw[clutP+tC1]); - } - } - if(NextRow_FT4()) return; - } -} - -//////////////////////////////////////////////////////////////////////// - -static void drawPoly4TEx8_TW_S(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4,short clX, short clY) -{ - int num; - int i,j,xmin,xmax,ymin,ymax; - int difX, difY, difX2, difY2; - int posX,posY,YAdjust,clutP; - short tC1,tC2; - - if(x1>drawW && x2>drawW && x3>drawW && x4>drawW) return; - if(y1>drawH && y2>drawH && y3>drawH && y4>drawH) return; - if(x1<drawX && x2<drawX && x3<drawX && x4<drawX) return; - if(y1<drawY && y2<drawY && y3<drawY && y4<drawY) return; - if(drawY>=drawH) return; - if(drawX>=drawW) return; - - if(!SetupSections_FT4(x1,y1,x2,y2,x3,y3,x4,y4,tx1,ty1,tx2,ty2,tx3,ty3,tx4,ty4)) return; - - ymax=Ymax; - - for(ymin=Ymin;ymin<drawY;ymin++) - if(NextRow_FT4()) return; - - clutP=(clY<<10)+clX; - - YAdjust=((GlobalTextAddrY)<<11)+(GlobalTextAddrX<<1); - YAdjust+=(TWin.Position.y0<<11)+(TWin.Position.x0); - -#ifdef FASTSOLID - - if(!bCheckMask && !DrawSemiTrans) - { - for (i=ymin;i<=ymax;i++) - { - xmin=(left_x >> 16); - xmax=(right_x >> 16); - - if(xmax>=xmin) - { - posX=left_u; - posY=left_v; - - num=(xmax-xmin); - if(num==0) num=1; - difX=(right_u-posX)/num; - difY=(right_v-posY)/num; - difX2=difX<<1; - difY2=difY<<1; - - if(xmin<drawX) - {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;} - xmax--;if(drawW<xmax) xmax=drawW; - - for(j=xmin;j<xmax;j+=2) - { - tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+ - YAdjust+((posX>>16)%TWin.Position.x1)]; - tC2 = psxVub[((((posY+difY)>>16)%TWin.Position.y1)<<11)+ - YAdjust+(((posX+difX)>>16)%TWin.Position.x1)]; - GetTextureTransColG32_S((uint32_t *)&psxVuw[(i<<10)+j], - psxVuw[clutP+tC1]| - ((int)psxVuw[clutP+tC2])<<16); - posX+=difX2; - posY+=difY2; - } - if(j==xmax) - { - tC1 = psxVub[((((posY+difY)>>16)%TWin.Position.y1)<<11)+ - YAdjust+((posX>>16)%TWin.Position.x1)]; - GetTextureTransColG_S(&psxVuw[(i<<10)+j],psxVuw[clutP+tC1]); - } - } - if(NextRow_FT4()) return; - } - return; - } - -#endif - - - for (i=ymin;i<=ymax;i++) - { - xmin=(left_x >> 16); - xmax=(right_x >> 16); - - if(xmax>=xmin) - { - posX=left_u; - posY=left_v; - - num=(xmax-xmin); - if(num==0) num=1; - difX=(right_u-posX)/num; - difY=(right_v-posY)/num; - difX2=difX<<1; - difY2=difY<<1; - - if(xmin<drawX) - {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;} - xmax--;if(drawW<xmax) xmax=drawW; - - for(j=xmin;j<xmax;j+=2) - { - tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+ - YAdjust+((posX>>16)%TWin.Position.x1)]; - tC2 = psxVub[((((posY+difY)>>16)%TWin.Position.y1)<<11)+ - YAdjust+(((posX+difX)>>16)%TWin.Position.x1)]; - GetTextureTransColG32_SPR((uint32_t *)&psxVuw[(i<<10)+j], - psxVuw[clutP+tC1]| - ((int)psxVuw[clutP+tC2])<<16); - posX+=difX2; - posY+=difY2; - } - if(j==xmax) - { - tC1 = psxVub[((((posY+difY)>>16)%TWin.Position.y1)<<11)+ - YAdjust+((posX>>16)%TWin.Position.x1)]; - GetTextureTransColG_SPR(&psxVuw[(i<<10)+j],psxVuw[clutP+tC1]); - } - } - if(NextRow_FT4()) return; - } -} - -//////////////////////////////////////////////////////////////////////// -// POLY 3 F-SHADED TEX 15 BIT -//////////////////////////////////////////////////////////////////////// - -static void drawPoly3TD(short x1, short y1, short x2, short y2, short x3, short y3, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3) -{ - int i,j,xmin,xmax,ymin,ymax; - int difX, difY,difX2, difY2; - int posX,posY; - - if(x1>drawW && x2>drawW && x3>drawW) return; - if(y1>drawH && y2>drawH && y3>drawH) return; - if(x1<drawX && x2<drawX && x3<drawX) return; - if(y1<drawY && y2<drawY && y3<drawY) return; - if(drawY>=drawH) return; - if(drawX>=drawW) return; - - if(!SetupSections_FT(x1,y1,x2,y2,x3,y3,tx1,ty1,tx2,ty2,tx3,ty3)) return; - - ymax=Ymax; - - for(ymin=Ymin;ymin<drawY;ymin++) - if(NextRow_FT()) return; - - difX=delta_right_u;difX2=difX<<1; - difY=delta_right_v;difY2=difY<<1; - -#ifdef FASTSOLID - - if(!bCheckMask && !DrawSemiTrans) - { - for (i=ymin;i<=ymax;i++) - { - xmin=(left_x >> 16); - xmax=(right_x >> 16)-1; //!!!!!!!!!!!!! - if(drawW<xmax) xmax=drawW; - - if(xmax>=xmin) - { - posX=left_u; - posY=left_v; - - if(xmin<drawX) - {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;} - - for(j=xmin;j<xmax;j+=2) - { - GetTextureTransColG32_S((uint32_t *)&psxVuw[(i<<10)+j], - (((int)psxVuw[((((posY+difY)>>16)+GlobalTextAddrY)<<10)+((posX+difX)>>16)+GlobalTextAddrX])<<16)| - psxVuw[(((posY>>16)+GlobalTextAddrY)<<10)+((posX)>>16)+GlobalTextAddrX]); - - posX+=difX2; - posY+=difY2; - } - if(j==xmax) - GetTextureTransColG_S(&psxVuw[(i<<10)+j], - psxVuw[(((posY>>16)+GlobalTextAddrY)<<10)+(posX>>16)+GlobalTextAddrX]); - } - if(NextRow_FT()) - { - return; - } - } - return; - } - -#endif - - for (i=ymin;i<=ymax;i++) - { - xmin=(left_x >> 16); - xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!! - if(drawW<xmax) xmax=drawW; - - if(xmax>=xmin) - { - posX=left_u; - posY=left_v; - - if(xmin<drawX) - {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;} - - for(j=xmin;j<xmax;j+=2) - { - GetTextureTransColG32((uint32_t *)&psxVuw[(i<<10)+j], - (((int)psxVuw[((((posY+difY)>>16)+GlobalTextAddrY)<<10)+((posX+difX)>>16)+GlobalTextAddrX])<<16)| - psxVuw[(((posY>>16)+GlobalTextAddrY)<<10)+((posX)>>16)+GlobalTextAddrX]); - - posX+=difX2; - posY+=difY2; - } - if(j==xmax) - GetTextureTransColG(&psxVuw[(i<<10)+j], - psxVuw[(((posY>>16)+GlobalTextAddrY)<<10)+(posX>>16)+GlobalTextAddrX]); - } - if(NextRow_FT()) - { - return; - } - } -} - -//////////////////////////////////////////////////////////////////////// - -static void drawPoly3TD_TW(short x1, short y1, short x2, short y2, short x3, short y3, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3) -{ - int i,j,xmin,xmax,ymin,ymax; - int difX, difY,difX2, difY2; - int posX,posY; - - if(x1>drawW && x2>drawW && x3>drawW) return; - if(y1>drawH && y2>drawH && y3>drawH) return; - if(x1<drawX && x2<drawX && x3<drawX) return; - if(y1<drawY && y2<drawY && y3<drawY) return; - if(drawY>=drawH) return; - if(drawX>=drawW) return; - - if(!SetupSections_FT(x1,y1,x2,y2,x3,y3,tx1,ty1,tx2,ty2,tx3,ty3)) return; - - ymax=Ymax; - - for(ymin=Ymin;ymin<drawY;ymin++) - if(NextRow_FT()) return; - - difX=delta_right_u;difX2=difX<<1; - difY=delta_right_v;difY2=difY<<1; - -#ifdef FASTSOLID - - if(!bCheckMask && !DrawSemiTrans) - { - for (i=ymin;i<=ymax;i++) - { - xmin=(left_x >> 16); - xmax=(right_x >> 16)-1; //!!!!!!!!!!!!! - if(drawW<xmax) xmax=drawW; - - if(xmax>=xmin) - { - posX=left_u; - posY=left_v; - - if(xmin<drawX) - {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;} - - for(j=xmin;j<xmax;j+=2) - { - GetTextureTransColG32_S((uint32_t *)&psxVuw[(i<<10)+j], - (((int)psxVuw[(((((posY+difY)>>16)%TWin.Position.y1)+GlobalTextAddrY+TWin.Position.y0)<<10)+ - (((posX+difX)>>16)%TWin.Position.x1)+GlobalTextAddrX+TWin.Position.x0])<<16)| - psxVuw[((((posY>>16)%TWin.Position.y1)+GlobalTextAddrY+TWin.Position.y0)<<10)+ - (((posX)>>16)%TWin.Position.x1)+GlobalTextAddrX+TWin.Position.x0]); - - posX+=difX2; - posY+=difY2; - } - if(j==xmax) - GetTextureTransColG_S(&psxVuw[(i<<10)+j], - psxVuw[((((posY>>16)%TWin.Position.y1)+GlobalTextAddrY+TWin.Position.y0)<<10)+ - ((posX>>16)%TWin.Position.x1)+GlobalTextAddrX+TWin.Position.x0]); - } - if(NextRow_FT()) - { - return; - } - } - return; - } - -#endif - - for (i=ymin;i<=ymax;i++) - { - xmin=(left_x >> 16); - xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!! - if(drawW<xmax) xmax=drawW; - - if(xmax>=xmin) - { - posX=left_u; - posY=left_v; - - if(xmin<drawX) - {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;} - - for(j=xmin;j<xmax;j+=2) - { - GetTextureTransColG32((uint32_t *)&psxVuw[(i<<10)+j], - (((int)psxVuw[(((((posY+difY)>>16)%TWin.Position.y1)+GlobalTextAddrY+TWin.Position.y0)<<10)+ - (((posX+difX)>>16)%TWin.Position.x1)+GlobalTextAddrX+TWin.Position.x0])<<16)| - psxVuw[((((posY>>16)%TWin.Position.y1)+GlobalTextAddrY+TWin.Position.y0)<<10)+ - (((posX)>>16)%TWin.Position.x1)+GlobalTextAddrX+TWin.Position.x0]); - - posX+=difX2; - posY+=difY2; - } - if(j==xmax) - GetTextureTransColG(&psxVuw[(i<<10)+j], - psxVuw[((((posY>>16)%TWin.Position.y1)+GlobalTextAddrY+TWin.Position.y0)<<10)+ - ((posX>>16)%TWin.Position.x1)+GlobalTextAddrX+TWin.Position.x0]); - } - if(NextRow_FT()) - { - return; - } - } -} - - -//////////////////////////////////////////////////////////////////////// - -#ifdef POLYQUAD3 - -static void drawPoly4TD_TRI(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4) -{ - drawPoly3TD(x2,y2,x3,y3,x4,y4, - tx2,ty2,tx3,ty3,tx4,ty4); - drawPoly3TD(x1,y1,x2,y2,x4,y4, - tx1,ty1,tx2,ty2,tx4,ty4); -} - -#endif - -// more exact: - -static void drawPoly4TD(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4) -{ - int num; - int i,j,xmin,xmax,ymin,ymax; - int difX, difY, difX2, difY2; - int posX,posY; - - if(x1>drawW && x2>drawW && x3>drawW && x4>drawW) return; - if(y1>drawH && y2>drawH && y3>drawH && y4>drawH) return; - if(x1<drawX && x2<drawX && x3<drawX && x4<drawX) return; - if(y1<drawY && y2<drawY && y3<drawY && y4<drawY) return; - if(drawY>=drawH) return; - if(drawX>=drawW) return; - - if(!SetupSections_FT4(x1,y1,x2,y2,x3,y3,x4,y4,tx1,ty1,tx2,ty2,tx3,ty3,tx4,ty4)) return; - - ymax=Ymax; - - for(ymin=Ymin;ymin<drawY;ymin++) - if(NextRow_FT4()) return; - -#ifdef FASTSOLID - - if(!bCheckMask && !DrawSemiTrans) - { - for (i=ymin;i<=ymax;i++) - { - xmin=(left_x >> 16); - xmax=(right_x >> 16); - - if(xmax>=xmin) - { - posX=left_u; - posY=left_v; - - num=(xmax-xmin); - if(num==0) num=1; - difX=(right_u-posX)/num; - difY=(right_v-posY)/num; - difX2=difX<<1; - difY2=difY<<1; - - if(xmin<drawX) - {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;} - xmax--;if(drawW<xmax) xmax=drawW; - - for(j=xmin;j<xmax;j+=2) - { - GetTextureTransColG32_S((uint32_t *)&psxVuw[(i<<10)+j], - (((int)psxVuw[((((posY+difY)>>16)+GlobalTextAddrY)<<10)+((posX+difX)>>16)+GlobalTextAddrX])<<16)| - psxVuw[(((posY>>16)+GlobalTextAddrY)<<10)+((posX)>>16)+GlobalTextAddrX]); - - posX+=difX2; - posY+=difY2; - } - if(j==xmax) - GetTextureTransColG_S(&psxVuw[(i<<10)+j], - psxVuw[(((posY>>16)+GlobalTextAddrY)<<10)+(posX>>16)+GlobalTextAddrX]); - } - if(NextRow_FT4()) return; - } - return; - } - -#endif - - for (i=ymin;i<=ymax;i++) - { - xmin=(left_x >> 16); - xmax=(right_x >> 16); - - if(xmax>=xmin) - { - posX=left_u; - posY=left_v; - - num=(xmax-xmin); - if(num==0) num=1; - difX=(right_u-posX)/num; - difY=(right_v-posY)/num; - difX2=difX<<1; - difY2=difY<<1; - - if(xmin<drawX) - {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;} - xmax--;if(drawW<xmax) xmax=drawW; - - for(j=xmin;j<xmax;j+=2) - { - GetTextureTransColG32((uint32_t *)&psxVuw[(i<<10)+j], - (((int)psxVuw[((((posY+difY)>>16)+GlobalTextAddrY)<<10)+((posX+difX)>>16)+GlobalTextAddrX])<<16)| - psxVuw[(((posY>>16)+GlobalTextAddrY)<<10)+((posX)>>16)+GlobalTextAddrX]); - - posX+=difX2; - posY+=difY2; - } - if(j==xmax) - GetTextureTransColG(&psxVuw[(i<<10)+j], - psxVuw[(((posY>>16)+GlobalTextAddrY)<<10)+(posX>>16)+GlobalTextAddrX]); - } - if(NextRow_FT4()) return; - } -} - -//////////////////////////////////////////////////////////////////////// - -static void drawPoly4TD_TW(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4) -{ - int num; - int i,j,xmin,xmax,ymin,ymax; - int difX, difY, difX2, difY2; - int posX,posY; - - if(x1>drawW && x2>drawW && x3>drawW && x4>drawW) return; - if(y1>drawH && y2>drawH && y3>drawH && y4>drawH) return; - if(x1<drawX && x2<drawX && x3<drawX && x4<drawX) return; - if(y1<drawY && y2<drawY && y3<drawY && y4<drawY) return; - if(drawY>=drawH) return; - if(drawX>=drawW) return; - - if(!SetupSections_FT4(x1,y1,x2,y2,x3,y3,x4,y4,tx1,ty1,tx2,ty2,tx3,ty3,tx4,ty4)) return; - - ymax=Ymax; - - for(ymin=Ymin;ymin<drawY;ymin++) - if(NextRow_FT4()) return; - -#ifdef FASTSOLID - - if(!bCheckMask && !DrawSemiTrans) - { - for (i=ymin;i<=ymax;i++) - { - xmin=(left_x >> 16); - xmax=(right_x >> 16); - - if(xmax>=xmin) - { - posX=left_u; - posY=left_v; - - num=(xmax-xmin); - if(num==0) num=1; - difX=(right_u-posX)/num; - difY=(right_v-posY)/num; - difX2=difX<<1; - difY2=difY<<1; - - if(xmin<drawX) - {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;} - xmax--;if(drawW<xmax) xmax=drawW; - - for(j=xmin;j<xmax;j+=2) - { - GetTextureTransColG32_S((uint32_t *)&psxVuw[(i<<10)+j], - (((int)psxVuw[(((((posY+difY)>>16)%TWin.Position.y1)+GlobalTextAddrY+TWin.Position.y0)<<10)+ - (((posX+difX)>>16)%TWin.Position.x1)+GlobalTextAddrX+TWin.Position.x0])<<16)| - psxVuw[((((posY>>16)%TWin.Position.y1)+GlobalTextAddrY)<<10)+TWin.Position.y0+ - ((posX>>16)%TWin.Position.x1)+GlobalTextAddrX+TWin.Position.x0]); - - posX+=difX2; - posY+=difY2; - } - if(j==xmax) - GetTextureTransColG_S(&psxVuw[(i<<10)+j], - psxVuw[((((posY>>16)%TWin.Position.y1)+GlobalTextAddrY+TWin.Position.y0)<<10)+ - ((posX>>16)%TWin.Position.x1)+GlobalTextAddrX+TWin.Position.x0]); - } - if(NextRow_FT4()) return; - } - return; - } - -#endif - - for (i=ymin;i<=ymax;i++) - { - xmin=(left_x >> 16); - xmax=(right_x >> 16); - - if(xmax>=xmin) - { - posX=left_u; - posY=left_v; - - num=(xmax-xmin); - if(num==0) num=1; - difX=(right_u-posX)/num; - difY=(right_v-posY)/num; - difX2=difX<<1; - difY2=difY<<1; - - if(xmin<drawX) - {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;} - xmax--;if(drawW<xmax) xmax=drawW; - - for(j=xmin;j<xmax;j+=2) - { - GetTextureTransColG32((uint32_t *)&psxVuw[(i<<10)+j], - (((int)psxVuw[(((((posY+difY)>>16)%TWin.Position.y1)+GlobalTextAddrY+TWin.Position.y0)<<10)+ - (((posX+difX)>>16)%TWin.Position.x1)+GlobalTextAddrX+TWin.Position.x0])<<16)| - psxVuw[((((posY>>16)%TWin.Position.y1)+GlobalTextAddrY+TWin.Position.y0)<<10)+ - ((posX>>16)%TWin.Position.x1)+GlobalTextAddrX+TWin.Position.x0]); - - posX+=difX2; - posY+=difY2; - } - if(j==xmax) - GetTextureTransColG(&psxVuw[(i<<10)+j], - psxVuw[((((posY>>16)%TWin.Position.y1)+GlobalTextAddrY+TWin.Position.y0)<<10)+ - ((posX>>16)%TWin.Position.x1)+GlobalTextAddrX+TWin.Position.x0]); - } - if(NextRow_FT4()) return; - } -} - -//////////////////////////////////////////////////////////////////////// - -static void drawPoly4TD_TW_S(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4) -{ - int num; - int i,j,xmin,xmax,ymin,ymax; - int difX, difY, difX2, difY2; - int posX, posY; - - if(x1>drawW && x2>drawW && x3>drawW && x4>drawW) return; - if(y1>drawH && y2>drawH && y3>drawH && y4>drawH) return; - if(x1<drawX && x2<drawX && x3<drawX && x4<drawX) return; - if(y1<drawY && y2<drawY && y3<drawY && y4<drawY) return; - if(drawY>=drawH) return; - if(drawX>=drawW) return; - - if(!SetupSections_FT4(x1,y1,x2,y2,x3,y3,x4,y4,tx1,ty1,tx2,ty2,tx3,ty3,tx4,ty4)) return; - - ymax=Ymax; - - for(ymin=Ymin;ymin<drawY;ymin++) - if(NextRow_FT4()) return; - -#ifdef FASTSOLID - - if(!bCheckMask && !DrawSemiTrans) - { - for (i=ymin;i<=ymax;i++) - { - xmin=(left_x >> 16); - xmax=(right_x >> 16); - - if(xmax>=xmin) - { - posX=left_u; - posY=left_v; - - num=(xmax-xmin); - if(num==0) num=1; - difX=(right_u-posX)/num; - difY=(right_v-posY)/num; - difX2=difX<<1; - difY2=difY<<1; - - if(xmin<drawX) - {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;} - xmax--;if(drawW<xmax) xmax=drawW; - - for(j=xmin;j<xmax;j+=2) - { - GetTextureTransColG32_S((uint32_t *)&psxVuw[(i<<10)+j], - (((int)psxVuw[(((((posY+difY)>>16)%TWin.Position.y1)+GlobalTextAddrY+TWin.Position.y0)<<10)+ - (((posX+difX)>>16)%TWin.Position.x1)+GlobalTextAddrX+TWin.Position.x0])<<16)| - psxVuw[((((posY>>16)%TWin.Position.y1)+GlobalTextAddrY)<<10)+TWin.Position.y0+ - ((posX>>16)%TWin.Position.x1)+GlobalTextAddrX+TWin.Position.x0]); - - posX+=difX2; - posY+=difY2; - } - if(j==xmax) - GetTextureTransColG_S(&psxVuw[(i<<10)+j], - psxVuw[((((posY>>16)%TWin.Position.y1)+GlobalTextAddrY+TWin.Position.y0)<<10)+ - ((posX>>16)%TWin.Position.x1)+GlobalTextAddrX+TWin.Position.x0]); - } - if(NextRow_FT4()) return; - } - return; - } - -#endif - - for (i=ymin;i<=ymax;i++) - { - xmin=(left_x >> 16); - xmax=(right_x >> 16); - - if(xmax>=xmin) - { - posX=left_u; - posY=left_v; - - num=(xmax-xmin); - if(num==0) num=1; - difX=(right_u-posX)/num; - difY=(right_v-posY)/num; - difX2=difX<<1; - difY2=difY<<1; - - if(xmin<drawX) - {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;} - xmax--;if(drawW<xmax) xmax=drawW; - - for(j=xmin;j<xmax;j+=2) - { - GetTextureTransColG32_SPR((uint32_t *)&psxVuw[(i<<10)+j], - (((int)psxVuw[(((((posY+difY)>>16)%TWin.Position.y1)+GlobalTextAddrY+TWin.Position.y0)<<10)+ - (((posX+difX)>>16)%TWin.Position.x1)+GlobalTextAddrX+TWin.Position.x0])<<16)| - psxVuw[((((posY>>16)%TWin.Position.y1)+GlobalTextAddrY+TWin.Position.y0)<<10)+ - ((posX>>16)%TWin.Position.x1)+GlobalTextAddrX+TWin.Position.x0]); - - posX+=difX2; - posY+=difY2; - } - if(j==xmax) - GetTextureTransColG_SPR(&psxVuw[(i<<10)+j], - psxVuw[((((posY>>16)%TWin.Position.y1)+GlobalTextAddrY+TWin.Position.y0)<<10)+ - ((posX>>16)%TWin.Position.x1)+GlobalTextAddrX+TWin.Position.x0]); - } - if(NextRow_FT4()) return; - } -} - -//////////////////////////////////////////////////////////////////////// -// POLY 3/4 G-SHADED -//////////////////////////////////////////////////////////////////////// - -static __inline void drawPoly3Gi(short x1,short y1,short x2,short y2,short x3,short y3, int rgb1, int rgb2, int rgb3) -{ - int i,j,xmin,xmax,ymin,ymax; - int cR1,cG1,cB1; - int difR,difB,difG,difR2,difB2,difG2; - - if(x1>drawW && x2>drawW && x3>drawW) return; - if(y1>drawH && y2>drawH && y3>drawH) return; - if(x1<drawX && x2<drawX && x3<drawX) return; - if(y1<drawY && y2<drawY && y3<drawY) return; - if(drawY>=drawH) return; - if(drawX>=drawW) return; - - if(!SetupSections_G(x1,y1,x2,y2,x3,y3,rgb1,rgb2,rgb3)) return; - - ymax=Ymax; - - for(ymin=Ymin;ymin<drawY;ymin++) - if(NextRow_G()) return; - - difR=delta_right_R; - difG=delta_right_G; - difB=delta_right_B; - difR2=difR<<1; - difG2=difG<<1; - difB2=difB<<1; - -#ifdef FASTSOLID - - if(!bCheckMask && !DrawSemiTrans && iDither!=2) - { - for (i=ymin;i<=ymax;i++) - { - xmin=(left_x >> 16); - xmax=(right_x >> 16)-1;if(drawW<xmax) xmax=drawW; - - if(xmax>=xmin) - { - cR1=left_R; - cG1=left_G; - cB1=left_B; - - if(xmin<drawX) - {j=drawX-xmin;xmin=drawX;cR1+=j*difR;cG1+=j*difG;cB1+=j*difB;} - - for(j=xmin;j<xmax;j+=2) - { - *((uint32_t *)&psxVuw[(i<<10)+j])= - ((((cR1+difR) <<7)&0x7c000000)|(((cG1+difG) << 2)&0x03e00000)|(((cB1+difB)>>3)&0x001f0000)| - (((cR1) >> 9)&0x7c00)|(((cG1) >> 14)&0x03e0)|(((cB1) >> 19)&0x001f))|lSetMask; - - cR1+=difR2; - cG1+=difG2; - cB1+=difB2; - } - if(j==xmax) - psxVuw[(i<<10)+j]=(((cR1 >> 9)&0x7c00)|((cG1 >> 14)&0x03e0)|((cB1 >> 19)&0x001f))|sSetMask; - } - if(NextRow_G()) return; - } - return; - } - -#endif - - if(iDither==2) - for (i=ymin;i<=ymax;i++) - { - xmin=(left_x >> 16); - xmax=(right_x >> 16)-1;if(drawW<xmax) xmax=drawW; - - if(xmax>=xmin) - { - cR1=left_R; - cG1=left_G; - cB1=left_B; - - if(xmin<drawX) - {j=drawX-xmin;xmin=drawX;cR1+=j*difR;cG1+=j*difG;cB1+=j*difB;} - - for(j=xmin;j<=xmax;j++) - { - GetShadeTransCol_Dither(&psxVuw[(i<<10)+j],(cB1>>16),(cG1>>16),(cR1>>16)); - - cR1+=difR; - cG1+=difG; - cB1+=difB; - } - } - if(NextRow_G()) return; - } - else - for (i=ymin;i<=ymax;i++) - { - xmin=(left_x >> 16); - xmax=(right_x >> 16)-1;if(drawW<xmax) xmax=drawW; - - if(xmax>=xmin) - { - cR1=left_R; - cG1=left_G; - cB1=left_B; - - if(xmin<drawX) - {j=drawX-xmin;xmin=drawX;cR1+=j*difR;cG1+=j*difG;cB1+=j*difB;} - - for(j=xmin;j<=xmax;j++) - { - GetShadeTransCol(&psxVuw[(i<<10)+j],((cR1 >> 9)&0x7c00)|((cG1 >> 14)&0x03e0)|((cB1 >> 19)&0x001f)); - - cR1+=difR; - cG1+=difG; - cB1+=difB; - } - } - if(NextRow_G()) return; - } - -} - -//////////////////////////////////////////////////////////////////////// - -void drawPoly3G(int rgb1, int rgb2, int rgb3) -{ - drawPoly3Gi(lx0,ly0,lx1,ly1,lx2,ly2,rgb1,rgb2,rgb3); -} - -// draw two g-shaded tris for right psx shading emulation - -void drawPoly4G(int rgb1, int rgb2, int rgb3, int rgb4) -{ - drawPoly3Gi(lx1,ly1,lx3,ly3,lx2,ly2, - rgb2,rgb4,rgb3); - drawPoly3Gi(lx0,ly0,lx1,ly1,lx2,ly2, - rgb1,rgb2,rgb3); -} - -//////////////////////////////////////////////////////////////////////// -// POLY 3/4 G-SHADED TEX PAL4 -//////////////////////////////////////////////////////////////////////// - -static void drawPoly3TGEx4(short x1, short y1, short x2, short y2, short x3, short y3, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short clX, short clY,int col1, int col2, int col3) -{ - int i,j,xmin,xmax,ymin,ymax; - int cR1,cG1,cB1; - int difR,difB,difG,difR2,difB2,difG2; - int difX, difY,difX2, difY2; - int posX,posY,YAdjust,clutP,XAdjust; - short tC1,tC2; - - if(x1>drawW && x2>drawW && x3>drawW) return; - if(y1>drawH && y2>drawH && y3>drawH) return; - if(x1<drawX && x2<drawX && x3<drawX) return; - if(y1<drawY && y2<drawY && y3<drawY) return; - if(drawY>=drawH) return; - if(drawX>=drawW) return; - - if(!SetupSections_GT(x1,y1,x2,y2,x3,y3,tx1,ty1,tx2,ty2,tx3,ty3,col1,col2,col3)) return; - - ymax=Ymax; - - for(ymin=Ymin;ymin<drawY;ymin++) - if(NextRow_GT()) return; - - clutP=(clY<<10)+clX; - - YAdjust=((GlobalTextAddrY)<<11)+(GlobalTextAddrX<<1); - - difR=delta_right_R; - difG=delta_right_G; - difB=delta_right_B; - difR2=difR<<1; - difG2=difG<<1; - difB2=difB<<1; - - difX=delta_right_u;difX2=difX<<1; - difY=delta_right_v;difY2=difY<<1; - -#ifdef FASTSOLID - - if(!bCheckMask && !DrawSemiTrans && !iDither) - { - for (i=ymin;i<=ymax;i++) - { - xmin=((left_x) >> 16); - xmax=((right_x) >> 16)-1; //!!!!!!!!!!!!! - if(drawW<xmax) xmax=drawW; - - if(xmax>=xmin) - { - posX=left_u; - posY=left_v; - cR1=left_R; - cG1=left_G; - cB1=left_B; - - if(xmin<drawX) - {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;cR1+=j*difR;cG1+=j*difG;cB1+=j*difB;} - - for(j=xmin;j<xmax;j+=2) - { - XAdjust=(posX>>16); - tC1 = psxVub[((posY>>5)&(int)0xFFFFF800)+YAdjust+(XAdjust>>1)]; - tC1=(tC1>>((XAdjust&1)<<2))&0xf; - XAdjust=((posX+difX)>>16); - tC2 = psxVub[(((posY+difY)>>5)&(int)0xFFFFF800)+YAdjust+ - (XAdjust>>1)]; - tC2=(tC2>>((XAdjust&1)<<2))&0xf; - - GetTextureTransColGX32_S((uint32_t *)&psxVuw[(i<<10)+j], - psxVuw[clutP+tC1]| - ((int)psxVuw[clutP+tC2])<<16, - (cB1>>16)|((cB1+difB)&0xff0000), - (cG1>>16)|((cG1+difG)&0xff0000), - (cR1>>16)|((cR1+difR)&0xff0000)); - posX+=difX2; - posY+=difY2; - cR1+=difR2; - cG1+=difG2; - cB1+=difB2; - } - if(j==xmax) - { - XAdjust=(posX>>16); - tC1 = psxVub[((posY>>5)&(int)0xFFFFF800)+YAdjust+(XAdjust>>1)]; - tC1=(tC1>>((XAdjust&1)<<2))&0xf; - GetTextureTransColGX_S(&psxVuw[(i<<10)+j], - psxVuw[clutP+tC1], - (cB1>>16),(cG1>>16),(cR1>>16)); - } - } - if(NextRow_GT()) - { - return; - } - } - return; - } - -#endif - - for (i=ymin;i<=ymax;i++) - { - xmin=(left_x >> 16); - xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!!!! - if(drawW<xmax) xmax=drawW; - - if(xmax>=xmin) - { - posX=left_u; - posY=left_v; - cR1=left_R; - cG1=left_G; - cB1=left_B; - - if(xmin<drawX) - {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;cR1+=j*difR;cG1+=j*difG;cB1+=j*difB;} - - for(j=xmin;j<=xmax;j++) - { - XAdjust=(posX>>16); - tC1 = psxVub[((posY>>5)&(int)0xFFFFF800)+YAdjust+(XAdjust>>1)]; - tC1=(tC1>>((XAdjust&1)<<2))&0xf; - if(iDither) - GetTextureTransColGX_Dither(&psxVuw[(i<<10)+j], - psxVuw[clutP+tC1], - (cB1>>16),(cG1>>16),(cR1>>16)); - else - GetTextureTransColGX(&psxVuw[(i<<10)+j], - psxVuw[clutP+tC1], - (cB1>>16),(cG1>>16),(cR1>>16)); - posX+=difX; - posY+=difY; - cR1+=difR; - cG1+=difG; - cB1+=difB; - } - } - if(NextRow_GT()) - { - return; - } - } -} - -//////////////////////////////////////////////////////////////////////// - -static void drawPoly3TGEx4_IL(short x1, short y1, short x2, short y2, short x3, short y3, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short clX, short clY,int col1, int col2, int col3) -{ - int i,j,xmin,xmax,ymin,ymax,n_xi,n_yi,TXV; - int cR1,cG1,cB1; - int difR,difB,difG,difR2,difB2,difG2; - int difX, difY,difX2, difY2; - int posX,posY,YAdjust,clutP,XAdjust; - short tC1,tC2; - - if(x1>drawW && x2>drawW && x3>drawW) return; - if(y1>drawH && y2>drawH && y3>drawH) return; - if(x1<drawX && x2<drawX && x3<drawX) return; - if(y1<drawY && y2<drawY && y3<drawY) return; - if(drawY>=drawH) return; - if(drawX>=drawW) return; - - if(!SetupSections_GT(x1,y1,x2,y2,x3,y3,tx1,ty1,tx2,ty2,tx3,ty3,col1,col2,col3)) return; - - ymax=Ymax; - - for(ymin=Ymin;ymin<drawY;ymin++) - if(NextRow_GT()) return; - - clutP=(clY<<10)+clX; - - YAdjust=(GlobalTextAddrY<<10)+GlobalTextAddrX; - - difR=delta_right_R; - difG=delta_right_G; - difB=delta_right_B; - difR2=difR<<1; - difG2=difG<<1; - difB2=difB<<1; - - difX=delta_right_u;difX2=difX<<1; - difY=delta_right_v;difY2=difY<<1; - -#ifdef FASTSOLID - - if(!bCheckMask && !DrawSemiTrans && !iDither) - { - for (i=ymin;i<=ymax;i++) - { - xmin=((left_x) >> 16); - xmax=((right_x) >> 16)-1; //!!!!!!!!!!!!! - if(drawW<xmax) xmax=drawW; - - if(xmax>=xmin) - { - posX=left_u; - posY=left_v; - cR1=left_R; - cG1=left_G; - cB1=left_B; - - if(xmin<drawX) - {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;cR1+=j*difR;cG1+=j*difG;cB1+=j*difB;} - - for(j=xmin;j<xmax;j+=2) - { - XAdjust=(posX>>16); - - TXV=posY>>16; - n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c ); - n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf ); - - tC1= (psxVuw[(n_yi<<10)+YAdjust+n_xi] >> ((XAdjust & 0x03)<<2)) & 0x0f ; - - XAdjust=((posX+difX)>>16); - - TXV=(posY+difY)>>16; - n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c ); - n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf ); - - tC2= (psxVuw[(n_yi<<10)+YAdjust+n_xi] >> ((XAdjust & 0x03)<<2)) & 0x0f ; - - GetTextureTransColGX32_S((uint32_t *)&psxVuw[(i<<10)+j], - psxVuw[clutP+tC1]| - ((int)psxVuw[clutP+tC2])<<16, - (cB1>>16)|((cB1+difB)&0xff0000), - (cG1>>16)|((cG1+difG)&0xff0000), - (cR1>>16)|((cR1+difR)&0xff0000)); - posX+=difX2; - posY+=difY2; - cR1+=difR2; - cG1+=difG2; - cB1+=difB2; - } - if(j==xmax) - { - XAdjust=(posX>>16); - - TXV=posY>>16; - n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c ); - n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf ); - - tC1= (psxVuw[(n_yi<<10)+YAdjust+n_xi] >> ((XAdjust & 0x03)<<2)) & 0x0f ; - - GetTextureTransColGX_S(&psxVuw[(i<<10)+j], - psxVuw[clutP+tC1], - (cB1>>16),(cG1>>16),(cR1>>16)); - } - } - if(NextRow_GT()) - { - return; - } - } - return; - } - -#endif - - for (i=ymin;i<=ymax;i++) - { - xmin=(left_x >> 16); - xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!!!! - if(drawW<xmax) xmax=drawW; - - if(xmax>=xmin) - { - posX=left_u; - posY=left_v; - cR1=left_R; - cG1=left_G; - cB1=left_B; - - if(xmin<drawX) - {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;cR1+=j*difR;cG1+=j*difG;cB1+=j*difB;} - - for(j=xmin;j<=xmax;j++) - { - XAdjust=(posX>>16); - - TXV=posY>>16; - n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c ); - n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf ); - - tC1= (psxVuw[(n_yi<<10)+YAdjust+n_xi] >> ((XAdjust & 0x03)<<2)) & 0x0f ; - - if(iDither) - GetTextureTransColGX_Dither(&psxVuw[(i<<10)+j], - psxVuw[clutP+tC1], - (cB1>>16),(cG1>>16),(cR1>>16)); - else - GetTextureTransColGX(&psxVuw[(i<<10)+j], - psxVuw[clutP+tC1], - (cB1>>16),(cG1>>16),(cR1>>16)); - posX+=difX; - posY+=difY; - cR1+=difR; - cG1+=difG; - cB1+=difB; - } - } - if(NextRow_GT()) - { - return; - } - } -} - -//////////////////////////////////////////////////////////////////////// - -static void drawPoly3TGEx4_TW(short x1, short y1, short x2, short y2, short x3, short y3, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short clX, short clY, int col1, int col2, int col3) -{ - int i, j, xmin, xmax, ymin, ymax; - int cR1, cG1, cB1; - int difR, difB, difG, difR2, difB2, difG2; - int difX, difY,difX2, difY2; - int posX, posY, YAdjust, clutP, XAdjust; - short tC1,tC2; - - if(x1>drawW && x2>drawW && x3>drawW) return; - if(y1>drawH && y2>drawH && y3>drawH) return; - if(x1<drawX && x2<drawX && x3<drawX) return; - if(y1<drawY && y2<drawY && y3<drawY) return; - if(drawY>=drawH) return; - if(drawX>=drawW) return; - - if(!SetupSections_GT(x1,y1,x2,y2,x3,y3,tx1,ty1,tx2,ty2,tx3,ty3,col1,col2,col3)) return; - - ymax=Ymax; - - for(ymin=Ymin;ymin<drawY;ymin++) - if(NextRow_GT()) return; - - clutP=(clY<<10)+clX; - - YAdjust=((GlobalTextAddrY)<<11)+(GlobalTextAddrX<<1); - YAdjust+=(TWin.Position.y0<<11)+(TWin.Position.x0>>1); - - difR=delta_right_R; - difG=delta_right_G; - difB=delta_right_B; - difR2=difR<<1; - difG2=difG<<1; - difB2=difB<<1; - - difX=delta_right_u;difX2=difX<<1; - difY=delta_right_v;difY2=difY<<1; - -#ifdef FASTSOLID - - if(!bCheckMask && !DrawSemiTrans && !iDither) - { - for (i=ymin;i<=ymax;i++) - { - xmin=((left_x) >> 16); - xmax=((right_x) >> 16)-1; //!!!!!!!!!!!!! - if(drawW<xmax) xmax=drawW; - - if(xmax>=xmin) - { - posX=left_u; - posY=left_v; - cR1=left_R; - cG1=left_G; - cB1=left_B; - - if(xmin<drawX) - {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;cR1+=j*difR;cG1+=j*difG;cB1+=j*difB;} - - for(j=xmin;j<xmax;j+=2) - { - XAdjust=(posX>>16)%TWin.Position.x1; - tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+ - YAdjust+(XAdjust>>1)]; - tC1=(tC1>>((XAdjust&1)<<2))&0xf; - XAdjust=((posX+difX)>>16)%TWin.Position.x1; - tC2 = psxVub[((((posY+difY)>>16)%TWin.Position.y1)<<11)+ - YAdjust+(XAdjust>>1)]; - tC2=(tC2>>((XAdjust&1)<<2))&0xf; - GetTextureTransColGX32_S((uint32_t *)&psxVuw[(i<<10)+j], - psxVuw[clutP+tC1]| - ((int)psxVuw[clutP+tC2])<<16, - (cB1>>16)|((cB1+difB)&0xff0000), - (cG1>>16)|((cG1+difG)&0xff0000), - (cR1>>16)|((cR1+difR)&0xff0000)); - posX+=difX2; - posY+=difY2; - cR1+=difR2; - cG1+=difG2; - cB1+=difB2; - } - if(j==xmax) - { - XAdjust=(posX>>16)%TWin.Position.x1; - tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+ - YAdjust+(XAdjust>>1)]; - tC1=(tC1>>((XAdjust&1)<<2))&0xf; - GetTextureTransColGX_S(&psxVuw[(i<<10)+j], - psxVuw[clutP+tC1], - (cB1>>16),(cG1>>16),(cR1>>16)); - } - } - if(NextRow_GT()) - { - return; - } - } - return; - } - -#endif - - for (i=ymin;i<=ymax;i++) - { - xmin=(left_x >> 16); - xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!!!! - if(drawW<xmax) xmax=drawW; - - if(xmax>=xmin) - { - posX=left_u; - posY=left_v; - cR1=left_R; - cG1=left_G; - cB1=left_B; - - if(xmin<drawX) - {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;cR1+=j*difR;cG1+=j*difG;cB1+=j*difB;} - - for(j=xmin;j<=xmax;j++) - { - XAdjust=(posX>>16)%TWin.Position.x1; - tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+ - YAdjust+(XAdjust>>1)]; - tC1=(tC1>>((XAdjust&1)<<2))&0xf; - if(iDither) - GetTextureTransColGX_Dither(&psxVuw[(i<<10)+j], - psxVuw[clutP+tC1], - (cB1>>16),(cG1>>16),(cR1>>16)); - else - GetTextureTransColGX(&psxVuw[(i<<10)+j], - psxVuw[clutP+tC1], - (cB1>>16),(cG1>>16),(cR1>>16)); - posX+=difX; - posY+=difY; - cR1+=difR; - cG1+=difG; - cB1+=difB; - } - } - if(NextRow_GT()) - { - return; - } - } -} - -//////////////////////////////////////////////////////////////////////// - -// note: the psx is doing g-shaded quads as two g-shaded tris, -// like the following func... sadly texturing is not 100% -// correct that way, so small texture distortions can -// happen... - -static void drawPoly4TGEx4_TRI_IL(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, - short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4, - short clX, short clY, - int col1, int col2, int col3, int col4) -{ - drawPoly3TGEx4_IL(x2,y2,x3,y3,x4,y4, - tx2,ty2,tx3,ty3,tx4,ty4, - clX,clY, - col2,col4,col3); - drawPoly3TGEx4_IL(x1,y1,x2,y2,x4,y4, - tx1,ty1,tx2,ty2,tx4,ty4, - clX,clY, - col1,col2,col3); -} - -#ifdef POLYQUAD3GT - -static void drawPoly4TGEx4_TRI(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, - short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4, - short clX, short clY, - int col1, int col2, int col3, int col4) -{ - drawPoly3TGEx4(x2,y2,x3,y3,x4,y4, - tx2,ty2,tx3,ty3,tx4,ty4, - clX,clY, - col2,col4,col3); - drawPoly3TGEx4(x1,y1,x2,y2,x4,y4, - tx1,ty1,tx2,ty2,tx4,ty4, - clX,clY, - col1,col2,col3); -} - -#endif - -//////////////////////////////////////////////////////////////////////// - -static void drawPoly4TGEx4(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, - short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4, - short clX, short clY, - int col1, int col2, int col4, int col3) -{ - int num; - int i,j,xmin,xmax,ymin,ymax; - int cR1,cG1,cB1; - int difR,difB,difG,difR2,difB2,difG2; - int difX, difY, difX2, difY2; - int posX,posY,YAdjust,clutP,XAdjust; - short tC1,tC2; - - if(x1>drawW && x2>drawW && x3>drawW && x4>drawW) return; - if(y1>drawH && y2>drawH && y3>drawH && y4>drawH) return; - if(x1<drawX && x2<drawX && x3<drawX && x4<drawX) return; - if(y1<drawY && y2<drawY && y3<drawY && y4<drawY) return; - if(drawY>=drawH) return; - if(drawX>=drawW) return; - - if(!SetupSections_GT4(x1,y1,x2,y2,x3,y3,x4,y4,tx1,ty1,tx2,ty2,tx3,ty3,tx4,ty4,col1,col2,col3,col4)) return; - - ymax=Ymax; - - for(ymin=Ymin;ymin<drawY;ymin++) - if(NextRow_GT4()) return; - - clutP=(clY<<10)+clX; - - YAdjust=((GlobalTextAddrY)<<11)+(GlobalTextAddrX<<1); - - -#ifdef FASTSOLID - - if(!bCheckMask && !DrawSemiTrans && !iDither) - { - for (i=ymin;i<=ymax;i++) - { - xmin=(left_x >> 16); - xmax=(right_x >> 16); - - if(xmax>=xmin) - { - posX=left_u; - posY=left_v; - - num=(xmax-xmin); - if(num==0) num=1; - difX=(right_u-posX)/num; - difY=(right_v-posY)/num; - difX2=difX<<1; - difY2=difY<<1; - - cR1=left_R; - cG1=left_G; - cB1=left_B; - difR=(right_R-cR1)/num; - difG=(right_G-cG1)/num; - difB=(right_B-cB1)/num; - difR2=difR<<1; - difG2=difG<<1; - difB2=difB<<1; - - if(xmin<drawX) - {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;cR1+=j*difR;cG1+=j*difG;cB1+=j*difB;} - xmax--;if(drawW<xmax) xmax=drawW; - - for(j=xmin;j<xmax;j+=2) - { - XAdjust=(posX>>16); - tC1 = psxVub[((posY>>5)&(int)0xFFFFF800)+YAdjust+(XAdjust>>1)]; - tC1=(tC1>>((XAdjust&1)<<2))&0xf; - XAdjust=((posX+difX)>>16); - tC2 = psxVub[(((posY+difY)>>5)&(int)0xFFFFF800)+YAdjust+ - (XAdjust>>1)]; - tC2=(tC2>>((XAdjust&1)<<2))&0xf; - - GetTextureTransColGX32_S((uint32_t *)&psxVuw[(i<<10)+j], - psxVuw[clutP+tC1]| - ((int)psxVuw[clutP+tC2])<<16, - (cB1>>16)|((cB1+difB)&0xff0000), - (cG1>>16)|((cG1+difG)&0xff0000), - (cR1>>16)|((cR1+difR)&0xff0000)); - posX+=difX2; - posY+=difY2; - cR1+=difR2; - cG1+=difG2; - cB1+=difB2; - } - if(j==xmax) - { - XAdjust=(posX>>16); - tC1 = psxVub[((posY>>5)&(int)0xFFFFF800)+YAdjust+ - (XAdjust>>1)]; - tC1=(tC1>>((XAdjust&1)<<2))&0xf; - - GetTextureTransColGX_S(&psxVuw[(i<<10)+j], - psxVuw[clutP+tC1], - (cB1>>16),(cG1>>16),(cR1>>16)); - } - } - if(NextRow_GT4()) return; - } - return; - } - -#endif - - for (i=ymin;i<=ymax;i++) - { - xmin=(left_x >> 16); - xmax=(right_x >> 16); - - if(xmax>=xmin) - { - posX=left_u; - posY=left_v; - - num=(xmax-xmin); - if(num==0) num=1; - difX=(right_u-posX)/num; - difY=(right_v-posY)/num; - difX2=difX<<1; - difY2=difY<<1; - - cR1=left_R; - cG1=left_G; - cB1=left_B; - difR=(right_R-cR1)/num; - difG=(right_G-cG1)/num; - difB=(right_B-cB1)/num; - difR2=difR<<1; - difG2=difG<<1; - difB2=difB<<1; - - if(xmin<drawX) - {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;cR1+=j*difR;cG1+=j*difG;cB1+=j*difB;} - xmax--;if(drawW<xmax) xmax=drawW; - - for(j=xmin;j<=xmax;j++) - { - XAdjust=(posX>>16); - tC1 = psxVub[((posY>>5)&(int)0xFFFFF800)+YAdjust+ - (XAdjust>>1)]; - tC1=(tC1>>((XAdjust&1)<<2))&0xf; - if(iDither) - GetTextureTransColGX_Dither(&psxVuw[(i<<10)+j], - psxVuw[clutP+tC1], - (cB1>>16),(cG1>>16),(cR1>>16)); - else - GetTextureTransColGX(&psxVuw[(i<<10)+j], - psxVuw[clutP+tC1], - (cB1>>16),(cG1>>16),(cR1>>16)); - posX+=difX; - posY+=difY; - cR1+=difR; - cG1+=difG; - cB1+=difB; - } - } - if(NextRow_GT4()) return; - } -} - -//////////////////////////////////////////////////////////////////////// - -static void drawPoly4TGEx4_TW(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, - short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4, - short clX, short clY, - int col1, int col2, int col3, int col4) -{ - drawPoly3TGEx4_TW(x2,y2,x3,y3,x4,y4, - tx2,ty2,tx3,ty3,tx4,ty4, - clX,clY, - col2,col4,col3); - - drawPoly3TGEx4_TW(x1,y1,x2,y2,x4,y4, - tx1,ty1,tx2,ty2,tx4,ty4, - clX,clY, - col1,col2,col3); -} - -//////////////////////////////////////////////////////////////////////// -// POLY 3/4 G-SHADED TEX PAL8 -//////////////////////////////////////////////////////////////////////// - -static void drawPoly3TGEx8(short x1, short y1, short x2, short y2, short x3, short y3, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short clX, short clY, int col1, int col2, int col3) -{ - int i,j,xmin,xmax,ymin,ymax; - int cR1,cG1,cB1; - int difR,difB,difG,difR2,difB2,difG2; - int difX, difY,difX2, difY2; - int posX,posY,YAdjust,clutP; - short tC1,tC2; - - if(x1>drawW && x2>drawW && x3>drawW) return; - if(y1>drawH && y2>drawH && y3>drawH) return; - if(x1<drawX && x2<drawX && x3<drawX) return; - if(y1<drawY && y2<drawY && y3<drawY) return; - if(drawY>=drawH) return; - if(drawX>=drawW) return; - - if(!SetupSections_GT(x1,y1,x2,y2,x3,y3,tx1,ty1,tx2,ty2,tx3,ty3,col1,col2,col3)) return; - - ymax=Ymax; - - for(ymin=Ymin;ymin<drawY;ymin++) - if(NextRow_GT()) return; - - clutP=(clY<<10)+clX; - - YAdjust=((GlobalTextAddrY)<<11)+(GlobalTextAddrX<<1); - - difR=delta_right_R; - difG=delta_right_G; - difB=delta_right_B; - difR2=difR<<1; - difG2=difG<<1; - difB2=difB<<1; - difX=delta_right_u;difX2=difX<<1; - difY=delta_right_v;difY2=difY<<1; - -#ifdef FASTSOLID - - if(!bCheckMask && !DrawSemiTrans && !iDither) - { - for (i=ymin;i<=ymax;i++) - { - xmin=(left_x >> 16); - xmax=(right_x >> 16)-1; // !!!!!!!!!!!!! - if(drawW<xmax) xmax=drawW; - - if(xmax>=xmin) - { - posX=left_u; - posY=left_v; - cR1=left_R; - cG1=left_G; - cB1=left_B; - - if(xmin<drawX) - {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;cR1+=j*difR;cG1+=j*difG;cB1+=j*difB;} - - for(j=xmin;j<xmax;j+=2) - { - tC1 = psxVub[((posY>>5)&(int)0xFFFFF800)+YAdjust+((posX>>16))]; - tC2 = psxVub[(((posY+difY)>>5)&(int)0xFFFFF800)+YAdjust+ - (((posX+difX)>>16))]; - GetTextureTransColGX32_S((uint32_t *)&psxVuw[(i<<10)+j], - psxVuw[clutP+tC1]| - ((int)psxVuw[clutP+tC2])<<16, - (cB1>>16)|((cB1+difB)&0xff0000), - (cG1>>16)|((cG1+difG)&0xff0000), - (cR1>>16)|((cR1+difR)&0xff0000)); - posX+=difX2; - posY+=difY2; - cR1+=difR2; - cG1+=difG2; - cB1+=difB2; - } - if(j==xmax) - { - tC1 = psxVub[((posY>>5)&(int)0xFFFFF800)+YAdjust+((posX>>16))]; - GetTextureTransColGX_S(&psxVuw[(i<<10)+j], - psxVuw[clutP+tC1], - (cB1>>16),(cG1>>16),(cR1>>16)); - } - } - if(NextRow_GT()) - { - return; - } - } - return; - } - -#endif - - for (i=ymin;i<=ymax;i++) - { - xmin=(left_x >> 16); - xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!!!!!!!!!!! - if(drawW<xmax) xmax=drawW; - - if(xmax>=xmin) - { - posX=left_u; - posY=left_v; - cR1=left_R; - cG1=left_G; - cB1=left_B; - - if(xmin<drawX) - {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;cR1+=j*difR;cG1+=j*difG;cB1+=j*difB;} - - for(j=xmin;j<=xmax;j++) - { - tC1 = psxVub[((posY>>5)&(int)0xFFFFF800)+YAdjust+((posX>>16))]; - if(iDither) - GetTextureTransColGX_Dither(&psxVuw[(i<<10)+j], - psxVuw[clutP+tC1], - (cB1>>16),(cG1>>16),(cR1>>16)); - else - GetTextureTransColGX(&psxVuw[(i<<10)+j], - psxVuw[clutP+tC1], - (cB1>>16),(cG1>>16),(cR1>>16)); - posX+=difX; - posY+=difY; - cR1+=difR; - cG1+=difG; - cB1+=difB; - } - } - if(NextRow_GT()) - { - return; - } - } -} - -//////////////////////////////////////////////////////////////////////// - -static void drawPoly3TGEx8_IL(short x1, short y1, short x2, short y2, short x3, short y3, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short clX, short clY, int col1, int col2, int col3) -{ - int i,j,xmin,xmax,ymin,ymax,n_xi,n_yi,TXV,TXU; - int cR1,cG1,cB1; - int difR,difB,difG,difR2,difB2,difG2; - int difX, difY,difX2, difY2; - int posX,posY,YAdjust,clutP; - short tC1,tC2; - - if(x1>drawW && x2>drawW && x3>drawW) return; - if(y1>drawH && y2>drawH && y3>drawH) return; - if(x1<drawX && x2<drawX && x3<drawX) return; - if(y1<drawY && y2<drawY && y3<drawY) return; - if(drawY>=drawH) return; - if(drawX>=drawW) return; - - if(!SetupSections_GT(x1,y1,x2,y2,x3,y3,tx1,ty1,tx2,ty2,tx3,ty3,col1,col2,col3)) return; - - ymax=Ymax; - - for(ymin=Ymin;ymin<drawY;ymin++) - if(NextRow_GT()) return; - - clutP=(clY<<10)+clX; - - YAdjust=(GlobalTextAddrY<<10)+GlobalTextAddrX; - - difR=delta_right_R; - difG=delta_right_G; - difB=delta_right_B; - difR2=difR<<1; - difG2=difG<<1; - difB2=difB<<1; - difX=delta_right_u;difX2=difX<<1; - difY=delta_right_v;difY2=difY<<1; - -#ifdef FASTSOLID - - if(!bCheckMask && !DrawSemiTrans && !iDither) - { - for (i=ymin;i<=ymax;i++) - { - xmin=(left_x >> 16); - xmax=(right_x >> 16)-1; // !!!!!!!!!!!!! - if(drawW<xmax) xmax=drawW; - - if(xmax>=xmin) - { - posX=left_u; - posY=left_v; - cR1=left_R; - cG1=left_G; - cB1=left_B; - - if(xmin<drawX) - {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;cR1+=j*difR;cG1+=j*difG;cB1+=j*difB;} - - for(j=xmin;j<xmax;j+=2) - { - TXU=posX>>16; - TXV=posY>>16; - n_xi = ( ( TXU >> 1 ) & ~0x78 ) + ( ( TXU << 2 ) & 0x40 ) + ( ( TXV << 3 ) & 0x38 ); - n_yi = ( TXV & ~0x7 ) + ( ( TXU >> 5 ) & 0x7 ); - - tC1= (psxVuw[(n_yi<<10)+YAdjust+n_xi] >> ((TXU & 0x01)<<3)) & 0xff; - - TXU=(posX+difX)>>16; - TXV=(posY+difY)>>16; - n_xi = ( ( TXU >> 1 ) & ~0x78 ) + ( ( TXU << 2 ) & 0x40 ) + ( ( TXV << 3 ) & 0x38 ); - n_yi = ( TXV & ~0x7 ) + ( ( TXU >> 5 ) & 0x7 ); - - tC2= (psxVuw[(n_yi<<10)+YAdjust+n_xi] >> ((TXU & 0x01)<<3)) & 0xff; - - GetTextureTransColGX32_S((uint32_t *)&psxVuw[(i<<10)+j], - psxVuw[clutP+tC1]| - ((int)psxVuw[clutP+tC2])<<16, - (cB1>>16)|((cB1+difB)&0xff0000), - (cG1>>16)|((cG1+difG)&0xff0000), - (cR1>>16)|((cR1+difR)&0xff0000)); - posX+=difX2; - posY+=difY2; - cR1+=difR2; - cG1+=difG2; - cB1+=difB2; - } - if(j==xmax) - { - TXU=posX>>16; - TXV=posY>>16; - n_xi = ( ( TXU >> 1 ) & ~0x78 ) + ( ( TXU << 2 ) & 0x40 ) + ( ( TXV << 3 ) & 0x38 ); - n_yi = ( TXV & ~0x7 ) + ( ( TXU >> 5 ) & 0x7 ); - - tC1= (psxVuw[(n_yi<<10)+YAdjust+n_xi] >> ((TXU & 0x01)<<3)) & 0xff; - - GetTextureTransColGX_S(&psxVuw[(i<<10)+j], - psxVuw[clutP+tC1], - (cB1>>16),(cG1>>16),(cR1>>16)); - } - } - if(NextRow_GT()) - { - return; - } - } - return; - } - -#endif - - for (i=ymin;i<=ymax;i++) - { - xmin=(left_x >> 16); - xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!!!!!!!!!!! - if(drawW<xmax) xmax=drawW; - - if(xmax>=xmin) - { - posX=left_u; - posY=left_v; - cR1=left_R; - cG1=left_G; - cB1=left_B; - - if(xmin<drawX) - {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;cR1+=j*difR;cG1+=j*difG;cB1+=j*difB;} - - for(j=xmin;j<=xmax;j++) - { - TXU=posX>>16; - TXV=posY>>16; - n_xi = ( ( TXU >> 1 ) & ~0x78 ) + ( ( TXU << 2 ) & 0x40 ) + ( ( TXV << 3 ) & 0x38 ); - n_yi = ( TXV & ~0x7 ) + ( ( TXU >> 5 ) & 0x7 ); - - tC1= (psxVuw[(n_yi<<10)+YAdjust+n_xi] >> ((TXU & 0x01)<<3)) & 0xff; - - if(iDither) - GetTextureTransColGX_Dither(&psxVuw[(i<<10)+j], - psxVuw[clutP+tC1], - (cB1>>16),(cG1>>16),(cR1>>16)); - else - GetTextureTransColGX(&psxVuw[(i<<10)+j], - psxVuw[clutP+tC1], - (cB1>>16),(cG1>>16),(cR1>>16)); - posX+=difX; - posY+=difY; - cR1+=difR; - cG1+=difG; - cB1+=difB; - } - } - if(NextRow_GT()) - { - return; - } - } -} - -//////////////////////////////////////////////////////////////////////// - -static void drawPoly3TGEx8_TW(short x1, short y1, short x2, short y2, short x3, short y3, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short clX, short clY, int col1, int col2, int col3) -{ - int i,j,xmin,xmax,ymin,ymax; - int cR1,cG1,cB1; - int difR,difB,difG,difR2,difB2,difG2; - int difX, difY,difX2, difY2; - int posX,posY,YAdjust,clutP; - short tC1,tC2; - - if(x1>drawW && x2>drawW && x3>drawW) return; - if(y1>drawH && y2>drawH && y3>drawH) return; - if(x1<drawX && x2<drawX && x3<drawX) return; - if(y1<drawY && y2<drawY && y3<drawY) return; - if(drawY>=drawH) return; - if(drawX>=drawW) return; - - if(!SetupSections_GT(x1,y1,x2,y2,x3,y3,tx1,ty1,tx2,ty2,tx3,ty3,col1,col2,col3)) return; - - ymax=Ymax; - - for(ymin=Ymin;ymin<drawY;ymin++) - if(NextRow_GT()) return; - - clutP=(clY<<10)+clX; - - YAdjust=((GlobalTextAddrY)<<11)+(GlobalTextAddrX<<1); - YAdjust+=(TWin.Position.y0<<11)+(TWin.Position.x0); - - difR=delta_right_R; - difG=delta_right_G; - difB=delta_right_B; - difR2=difR<<1; - difG2=difG<<1; - difB2=difB<<1; - difX=delta_right_u;difX2=difX<<1; - difY=delta_right_v;difY2=difY<<1; - -#ifdef FASTSOLID - - if(!bCheckMask && !DrawSemiTrans && !iDither) - { - for (i=ymin;i<=ymax;i++) - { - xmin=(left_x >> 16); - xmax=(right_x >> 16)-1; // !!!!!!!!!!!!! - if(drawW<xmax) xmax=drawW; - - if(xmax>=xmin) - { - posX=left_u; - posY=left_v; - cR1=left_R; - cG1=left_G; - cB1=left_B; - - if(xmin<drawX) - {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;cR1+=j*difR;cG1+=j*difG;cB1+=j*difB;} - - for(j=xmin;j<xmax;j+=2) - { - tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+ - YAdjust+((posX>>16)%TWin.Position.x1)]; - tC2 = psxVub[((((posY+difY)>>16)%TWin.Position.y1)<<11)+ - YAdjust+(((posX+difX)>>16)%TWin.Position.x1)]; - - GetTextureTransColGX32_S((uint32_t *)&psxVuw[(i<<10)+j], - psxVuw[clutP+tC1]| - ((int)psxVuw[clutP+tC2])<<16, - (cB1>>16)|((cB1+difB)&0xff0000), - (cG1>>16)|((cG1+difG)&0xff0000), - (cR1>>16)|((cR1+difR)&0xff0000)); - posX+=difX2; - posY+=difY2; - cR1+=difR2; - cG1+=difG2; - cB1+=difB2; - } - if(j==xmax) - { - tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+ - YAdjust+((posX>>16)%TWin.Position.x1)]; - GetTextureTransColGX_S(&psxVuw[(i<<10)+j], - psxVuw[clutP+tC1], - (cB1>>16),(cG1>>16),(cR1>>16)); - } - } - if(NextRow_GT()) - { - return; - } - } - return; - } - -#endif - - for (i=ymin;i<=ymax;i++) - { - xmin=(left_x >> 16); - xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!!!!!!!!!!! - if(drawW<xmax) xmax=drawW; - - if(xmax>=xmin) - { - posX=left_u; - posY=left_v; - cR1=left_R; - cG1=left_G; - cB1=left_B; - - if(xmin<drawX) - {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;cR1+=j*difR;cG1+=j*difG;cB1+=j*difB;} - - for(j=xmin;j<=xmax;j++) - { - tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+ - YAdjust+((posX>>16)%TWin.Position.x1)]; - if(iDither) - GetTextureTransColGX_Dither(&psxVuw[(i<<10)+j], - psxVuw[clutP+tC1], - (cB1>>16),(cG1>>16),(cR1>>16)); - else - GetTextureTransColGX(&psxVuw[(i<<10)+j], - psxVuw[clutP+tC1], - (cB1>>16),(cG1>>16),(cR1>>16)); - posX+=difX; - posY+=difY; - cR1+=difR; - cG1+=difG; - cB1+=difB; - } - } - if(NextRow_GT()) - { - return; - } - } -} - -//////////////////////////////////////////////////////////////////////// - -// note: two g-shaded tris: small texture distortions can happen - -static void drawPoly4TGEx8_TRI_IL(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, - short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4, - short clX, short clY, - int col1, int col2, int col3, int col4) -{ - drawPoly3TGEx8_IL(x2,y2,x3,y3,x4,y4, - tx2,ty2,tx3,ty3,tx4,ty4, - clX,clY, - col2,col4,col3); - drawPoly3TGEx8_IL(x1,y1,x2,y2,x4,y4, - tx1,ty1,tx2,ty2,tx4,ty4, - clX,clY, - col1,col2,col3); -} - -#ifdef POLYQUAD3GT - -static void drawPoly4TGEx8_TRI(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, - short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4, - short clX, short clY, - int col1, int col2, int col3, int col4) -{ - drawPoly3TGEx8(x2,y2,x3,y3,x4,y4, - tx2,ty2,tx3,ty3,tx4,ty4, - clX,clY, - col2,col4,col3); - drawPoly3TGEx8(x1,y1,x2,y2,x4,y4, - tx1,ty1,tx2,ty2,tx4,ty4, - clX,clY, - col1,col2,col3); -} - -#endif - -static void drawPoly4TGEx8(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, - short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4, - short clX, short clY, - int col1, int col2, int col4, int col3) -{ - int num; - int i,j,xmin,xmax,ymin,ymax; - int cR1,cG1,cB1; - int difR,difB,difG,difR2,difB2,difG2; - int difX, difY, difX2, difY2; - int posX,posY,YAdjust,clutP; - short tC1,tC2; - - if(x1>drawW && x2>drawW && x3>drawW && x4>drawW) return; - if(y1>drawH && y2>drawH && y3>drawH && y4>drawH) return; - if(x1<drawX && x2<drawX && x3<drawX && x4<drawX) return; - if(y1<drawY && y2<drawY && y3<drawY && y4<drawY) return; - if(drawY>=drawH) return; - if(drawX>=drawW) return; - - if(!SetupSections_GT4(x1,y1,x2,y2,x3,y3,x4,y4,tx1,ty1,tx2,ty2,tx3,ty3,tx4,ty4,col1,col2,col3,col4)) return; - - ymax=Ymax; - - for(ymin=Ymin;ymin<drawY;ymin++) - if(NextRow_GT4()) return; - - clutP=(clY<<10)+clX; - - YAdjust=((GlobalTextAddrY)<<11)+(GlobalTextAddrX<<1); - -#ifdef FASTSOLID - - if(!bCheckMask && !DrawSemiTrans && !iDither) - { - for (i=ymin;i<=ymax;i++) - { - xmin=(left_x >> 16); - xmax=(right_x >> 16); - - if(xmax>=xmin) - { - posX=left_u; - posY=left_v; - - num=(xmax-xmin); - if(num==0) num=1; - difX=(right_u-posX)/num; - difY=(right_v-posY)/num; - difX2=difX<<1; - difY2=difY<<1; - - cR1=left_R; - cG1=left_G; - cB1=left_B; - difR=(right_R-cR1)/num; - difG=(right_G-cG1)/num; - difB=(right_B-cB1)/num; - difR2=difR<<1; - difG2=difG<<1; - difB2=difB<<1; - - if(xmin<drawX) - {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;cR1+=j*difR;cG1+=j*difG;cB1+=j*difB;} - xmax--;if(drawW<xmax) xmax=drawW; - - for(j=xmin;j<xmax;j+=2) - { - tC1 = psxVub[((posY>>5)&(int)0xFFFFF800)+YAdjust+(posX>>16)]; - tC2 = psxVub[(((posY+difY)>>5)&(int)0xFFFFF800)+YAdjust+ - ((posX+difX)>>16)]; - - GetTextureTransColGX32_S((uint32_t *)&psxVuw[(i<<10)+j], - psxVuw[clutP+tC1]| - ((int)psxVuw[clutP+tC2])<<16, - (cB1>>16)|((cB1+difB)&0xff0000), - (cG1>>16)|((cG1+difG)&0xff0000), - (cR1>>16)|((cR1+difR)&0xff0000)); - posX+=difX2; - posY+=difY2; - cR1+=difR2; - cG1+=difG2; - cB1+=difB2; - } - if(j==xmax) - { - tC1 = psxVub[((posY>>5)&(int)0xFFFFF800)+YAdjust+(posX>>16)]; - GetTextureTransColGX_S(&psxVuw[(i<<10)+j], - psxVuw[clutP+tC1], - (cB1>>16),(cG1>>16),(cR1>>16)); - } - } - if(NextRow_GT4()) return; - } - return; - } - -#endif - - for (i=ymin;i<=ymax;i++) - { - xmin=(left_x >> 16); - xmax=(right_x >> 16); - - if(xmax>=xmin) - { - posX=left_u; - posY=left_v; - - num=(xmax-xmin); - if(num==0) num=1; - difX=(right_u-posX)/num; - difY=(right_v-posY)/num; - difX2=difX<<1; - difY2=difY<<1; - - cR1=left_R; - cG1=left_G; - cB1=left_B; - difR=(right_R-cR1)/num; - difG=(right_G-cG1)/num; - difB=(right_B-cB1)/num; - difR2=difR<<1; - difG2=difG<<1; - difB2=difB<<1; - - if(xmin<drawX) - {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;cR1+=j*difR;cG1+=j*difG;cB1+=j*difB;} - xmax--;if(drawW<xmax) xmax=drawW; - - for(j=xmin;j<=xmax;j++) - { - tC1 = psxVub[((posY>>5)&(int)0xFFFFF800)+YAdjust+(posX>>16)]; - if(iDither) - GetTextureTransColGX_Dither(&psxVuw[(i<<10)+j], - psxVuw[clutP+tC1], - (cB1>>16),(cG1>>16),(cR1>>16)); - else - GetTextureTransColGX(&psxVuw[(i<<10)+j], - psxVuw[clutP+tC1], - (cB1>>16),(cG1>>16),(cR1>>16)); - posX+=difX; - posY+=difY; - cR1+=difR; - cG1+=difG; - cB1+=difB; - } - } - if(NextRow_GT4()) return; - } -} - -//////////////////////////////////////////////////////////////////////// - -static void drawPoly4TGEx8_TW(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, - short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4, - short clX, short clY, - int col1, int col2, int col3, int col4) -{ - drawPoly3TGEx8_TW(x2,y2,x3,y3,x4,y4, - tx2,ty2,tx3,ty3,tx4,ty4, - clX,clY, - col2,col4,col3); - drawPoly3TGEx8_TW(x1,y1,x2,y2,x4,y4, - tx1,ty1,tx2,ty2,tx4,ty4, - clX,clY, - col1,col2,col3); -} - -//////////////////////////////////////////////////////////////////////// -// POLY 3 G-SHADED TEX 15 BIT -//////////////////////////////////////////////////////////////////////// - -static void drawPoly3TGD(short x1, short y1, short x2, short y2, short x3, short y3, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, int col1, int col2, int col3) -{ - int i,j,xmin,xmax,ymin,ymax; - int cR1,cG1,cB1; - int difR,difB,difG,difR2,difB2,difG2; - int difX, difY,difX2, difY2; - int posX,posY; - - if(x1>drawW && x2>drawW && x3>drawW) return; - if(y1>drawH && y2>drawH && y3>drawH) return; - if(x1<drawX && x2<drawX && x3<drawX) return; - if(y1<drawY && y2<drawY && y3<drawY) return; - if(drawY>=drawH) return; - if(drawX>=drawW) return; - - if(!SetupSections_GT(x1,y1,x2,y2,x3,y3,tx1,ty1,tx2,ty2,tx3,ty3,col1,col2,col3)) return; - - ymax=Ymax; - - for(ymin=Ymin;ymin<drawY;ymin++) - if(NextRow_GT()) return; - - difR=delta_right_R; - difG=delta_right_G; - difB=delta_right_B; - difR2=difR<<1; - difG2=difG<<1; - difB2=difB<<1; - difX=delta_right_u;difX2=difX<<1; - difY=delta_right_v;difY2=difY<<1; - -#ifdef FASTSOLID - - if(!bCheckMask && !DrawSemiTrans && !iDither) - { - for (i=ymin;i<=ymax;i++) - { - xmin=(left_x >> 16); - xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!!!!!!!! - if(drawW<xmax) xmax=drawW; - - if(xmax>=xmin) - { - posX=left_u; - posY=left_v; - cR1=left_R; - cG1=left_G; - cB1=left_B; - - if(xmin<drawX) - {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;cR1+=j*difR;cG1+=j*difG;cB1+=j*difB;} - - for(j=xmin;j<xmax;j+=2) - { - GetTextureTransColGX32_S((uint32_t *)&psxVuw[(i<<10)+j], - (((int)psxVuw[((((posY+difY)>>16)+GlobalTextAddrY)<<10)+((posX+difX)>>16)+GlobalTextAddrX])<<16)| - psxVuw[(((posY>>16)+GlobalTextAddrY)<<10)+((posX)>>16)+GlobalTextAddrX], - (cB1>>16)|((cB1+difB)&0xff0000), - (cG1>>16)|((cG1+difG)&0xff0000), - (cR1>>16)|((cR1+difR)&0xff0000)); - posX+=difX2; - posY+=difY2; - cR1+=difR2; - cG1+=difG2; - cB1+=difB2; - } - if(j==xmax) - GetTextureTransColGX_S(&psxVuw[(i<<10)+j], - psxVuw[(((posY>>16)+GlobalTextAddrY)<<10)+(posX>>16)+GlobalTextAddrX], - (cB1>>16),(cG1>>16),(cR1>>16)); - } - if(NextRow_GT()) - { - return; - } - } - return; - } - -#endif - - for (i=ymin;i<=ymax;i++) - { - xmin=(left_x >> 16); - xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!!!!!! - if(drawW<xmax) xmax=drawW; - - if(xmax>=xmin) - { - posX=left_u; - posY=left_v; - cR1=left_R; - cG1=left_G; - cB1=left_B; - - if(xmin<drawX) - {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;cR1+=j*difR;cG1+=j*difG;cB1+=j*difB;} - - for(j=xmin;j<=xmax;j++) - { - if(iDither) - GetTextureTransColGX_Dither(&psxVuw[(i<<10)+j], - psxVuw[(((posY>>16)+GlobalTextAddrY)<<10)+(posX>>16)+GlobalTextAddrX], - (cB1>>16),(cG1>>16),(cR1>>16)); - else - GetTextureTransColGX(&psxVuw[(i<<10)+j], - psxVuw[(((posY>>16)+GlobalTextAddrY)<<10)+(posX>>16)+GlobalTextAddrX], - (cB1>>16),(cG1>>16),(cR1>>16)); - posX+=difX; - posY+=difY; - cR1+=difR; - cG1+=difG; - cB1+=difB; - } - } - if(NextRow_GT()) - { - return; - } - } -} - -//////////////////////////////////////////////////////////////////////// - -static void drawPoly3TGD_TW(short x1, short y1, short x2, short y2, short x3, short y3, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, int col1, int col2, int col3) -{ - int i,j,xmin,xmax,ymin,ymax; - int cR1,cG1,cB1; - int difR,difB,difG,difR2,difB2,difG2; - int difX, difY,difX2, difY2; - int posX,posY; - - if (x1>drawW && x2>drawW && x3>drawW) return; - if (y1>drawH && y2>drawH && y3>drawH) return; - if (x1<drawX && x2<drawX && x3<drawX) return; - if (y1<drawY && y2<drawY && y3<drawY) return; - if (drawY >= drawH) return; - if (drawX >= drawW) return; - - if (!SetupSections_GT(x1,y1,x2,y2,x3,y3,tx1,ty1,tx2,ty2,tx3,ty3,col1,col2,col3)) return; - - ymax = Ymax; - - for(ymin = Ymin; ymin < drawY; ymin++) - if(NextRow_GT()) return; - - difR = delta_right_R; - difG = delta_right_G; - difB = delta_right_B; - difR2 = difR<<1; - difG2 = difG<<1; - difB2 = difB<<1; - difX = delta_right_u; difX2 = difX<<1; - difY = delta_right_v; difY2 = difY<<1; - -#ifdef FASTSOLID - - if (!bCheckMask && !DrawSemiTrans && !iDither) - { - for (i = ymin; i <= ymax; i++) - { - xmin = (left_x >> 16); - xmax = (right_x >> 16) - 1; //!!!!!!!!!!!!!!!!!!!! - if(drawW<xmax) xmax=drawW; - - if(xmax>=xmin) - { - posX=left_u; - posY=left_v; - cR1=left_R; - cG1=left_G; - cB1=left_B; - - if(xmin<drawX) - {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;cR1+=j*difR;cG1+=j*difG;cB1+=j*difB;} - - for(j=xmin;j<xmax;j+=2) - { - GetTextureTransColGX32_S((uint32_t *)&psxVuw[(i<<10)+j], - (((int)psxVuw[(((((posY+difY)>>16)%TWin.Position.y1)+GlobalTextAddrY+TWin.Position.y0)<<10)+ - (((posX+difX)>>16)%TWin.Position.x1)+GlobalTextAddrX+TWin.Position.x0])<<16)| - psxVuw[((((posY>>16)%TWin.Position.y1)+GlobalTextAddrY+TWin.Position.y0)<<10)+ - (((posX)>>16)%TWin.Position.x1)+GlobalTextAddrX+TWin.Position.x0], - (cB1>>16)|((cB1+difB)&0xff0000), - (cG1>>16)|((cG1+difG)&0xff0000), - (cR1>>16)|((cR1+difR)&0xff0000)); - posX+=difX2; - posY+=difY2; - cR1+=difR2; - cG1+=difG2; - cB1+=difB2; - } - if(j==xmax) - GetTextureTransColGX_S(&psxVuw[(i<<10)+j], - psxVuw[((((posY>>16)%TWin.Position.y1)+GlobalTextAddrY+TWin.Position.y0)<<10)+ - ((posX>>16)%TWin.Position.x1)+GlobalTextAddrX+TWin.Position.x0], - (cB1>>16),(cG1>>16),(cR1>>16)); - } - if(NextRow_GT()) - { - return; - } - } - return; - } - -#endif - - for (i=ymin;i<=ymax;i++) - { - xmin=(left_x >> 16); - xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!!!!!! - if(drawW<xmax) xmax=drawW; - - if(xmax>=xmin) - { - posX=left_u; - posY=left_v; - cR1=left_R; - cG1=left_G; - cB1=left_B; - - if(xmin<drawX) - {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;cR1+=j*difR;cG1+=j*difG;cB1+=j*difB;} - - for(j=xmin;j<=xmax;j++) - { - if(iDither) - GetTextureTransColGX_Dither(&psxVuw[(i<<10)+j], - psxVuw[((((posY>>16)%TWin.Position.y1)+GlobalTextAddrY+TWin.Position.y0)<<10)+ - ((posX>>16)%TWin.Position.x1)+GlobalTextAddrX+TWin.Position.x0], - (cB1>>16),(cG1>>16),(cR1>>16)); - else - GetTextureTransColGX(&psxVuw[(i<<10)+j], - psxVuw[((((posY>>16)%TWin.Position.y1)+GlobalTextAddrY+TWin.Position.y0)<<10)+ - ((posX>>16)%TWin.Position.x1)+GlobalTextAddrX+TWin.Position.x0], - (cB1>>16),(cG1>>16),(cR1>>16)); - posX+=difX; - posY+=difY; - cR1+=difR; - cG1+=difG; - cB1+=difB; - } - } - if(NextRow_GT()) - { - return; - } - } -} - -//////////////////////////////////////////////////////////////////////// - -// note: two g-shaded tris: small texture distortions can happen - -#ifdef POLYQUAD3GT - -static void drawPoly4TGD_TRI(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4, int col1, int col2, int col3, int col4) -{ - drawPoly3TGD(x2,y2,x3,y3,x4,y4, - tx2,ty2,tx3,ty3,tx4,ty4, - col2,col4,col3); - drawPoly3TGD(x1,y1,x2,y2,x4,y4, - tx1,ty1,tx2,ty2,tx4,ty4, - col1,col2,col3); -} - -#endif - -static void drawPoly4TGD(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4, int col1, int col2, int col4, int col3) -{ - int num; - int i,j,xmin,xmax,ymin,ymax; - int cR1,cG1,cB1; - int difR,difB,difG,difR2,difB2,difG2; - int difX, difY, difX2, difY2; - int posX,posY; - - if(x1>drawW && x2>drawW && x3>drawW && x4>drawW) return; - if(y1>drawH && y2>drawH && y3>drawH && y4>drawH) return; - if(x1<drawX && x2<drawX && x3<drawX && x4<drawX) return; - if(y1<drawY && y2<drawY && y3<drawY && y4<drawY) return; - if(drawY>=drawH) return; - if(drawX>=drawW) return; - - if(!SetupSections_GT4(x1,y1,x2,y2,x3,y3,x4,y4,tx1,ty1,tx2,ty2,tx3,ty3,tx4,ty4,col1,col2,col3,col4)) return; - - ymax = Ymax; - - for (ymin = Ymin; ymin < drawY; ymin++) - if (NextRow_GT4()) return; - -#ifdef FASTSOLID - - if(!bCheckMask && !DrawSemiTrans && !iDither) - { - for (i = ymin; i <= ymax; i++) - { - xmin = (left_x >> 16); - xmax = (right_x >> 16); - - if(xmax >= xmin) - { - posX = left_u; - posY = left_v; - - num = (xmax-xmin); - if(num==0) num=1; - difX=(right_u-posX)/num; - difY=(right_v-posY)/num; - difX2=difX<<1; - difY2=difY<<1; - - cR1=left_R; - cG1=left_G; - cB1=left_B; - difR=(right_R-cR1)/num; - difG=(right_G-cG1)/num; - difB=(right_B-cB1)/num; - difR2=difR<<1; - difG2=difG<<1; - difB2=difB<<1; - - if(xmin<drawX) - {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;cR1+=j*difR;cG1+=j*difG;cB1+=j*difB;} - xmax--;if(drawW<xmax) xmax=drawW; - - for(j=xmin;j<xmax;j+=2) - { - GetTextureTransColGX32_S((uint32_t *)&psxVuw[(i<<10)+j], - (((int)psxVuw[((((posY+difY)>>16)+GlobalTextAddrY)<<10)+((posX+difX)>>16)+GlobalTextAddrX])<<16)| - psxVuw[(((posY>>16)+GlobalTextAddrY)<<10)+((posX)>>16)+GlobalTextAddrX], - (cB1>>16)|((cB1+difB)&0xff0000), - (cG1>>16)|((cG1+difG)&0xff0000), - (cR1>>16)|((cR1+difR)&0xff0000)); - posX+=difX2; - posY+=difY2; - cR1+=difR2; - cG1+=difG2; - cB1+=difB2; - } - if(j==xmax) - GetTextureTransColGX_S(&psxVuw[(i<<10)+j], - psxVuw[(((posY>>16)+GlobalTextAddrY)<<10)+(posX>>16)+GlobalTextAddrX], - (cB1>>16),(cG1>>16),(cR1>>16)); - } - if(NextRow_GT4()) return; - } - return; - } - -#endif - - for (i=ymin;i<=ymax;i++) - { - xmin=(left_x >> 16); - xmax=(right_x >> 16); - - if(xmax>=xmin) - { - posX=left_u; - posY=left_v; - - num=(xmax-xmin); - if(num==0) num=1; - difX=(right_u-posX)/num; - difY=(right_v-posY)/num; - difX2=difX<<1; - difY2=difY<<1; - - cR1=left_R; - cG1=left_G; - cB1=left_B; - difR=(right_R-cR1)/num; - difG=(right_G-cG1)/num; - difB=(right_B-cB1)/num; - difR2=difR<<1; - difG2=difG<<1; - difB2=difB<<1; - - if(xmin<drawX) - {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;cR1+=j*difR;cG1+=j*difG;cB1+=j*difB;} - xmax--;if(drawW<xmax) xmax=drawW; - - for(j=xmin;j<=xmax;j++) - { - if(iDither) - GetTextureTransColGX(&psxVuw[(i<<10)+j], - psxVuw[(((posY>>16)+GlobalTextAddrY)<<10)+(posX>>16)+GlobalTextAddrX], - (cB1>>16),(cG1>>16),(cR1>>16)); - else - GetTextureTransColGX(&psxVuw[(i<<10)+j], - psxVuw[(((posY>>16)+GlobalTextAddrY)<<10)+(posX>>16)+GlobalTextAddrX], - (cB1>>16),(cG1>>16),(cR1>>16)); - posX+=difX; - posY+=difY; - cR1+=difR; - cG1+=difG; - cB1+=difB; - } - } - if(NextRow_GT4()) return; - } -} - -//////////////////////////////////////////////////////////////////////// - -static void drawPoly4TGD_TW(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4, int col1, int col2, int col3, int col4) -{ - drawPoly3TGD_TW(x2,y2,x3,y3,x4,y4, - tx2,ty2,tx3,ty3,tx4,ty4, - col2,col4,col3); - drawPoly3TGD_TW(x1,y1,x2,y2,x4,y4, - tx1,ty1,tx2,ty2,tx4,ty4, - col1,col2,col3); -} - -//////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////// - - -/* -// no real rect test, but it does its job the way I need it -__inline BOOL IsNoRect(void) -{ - if(lx0==lx1 && lx2==lx3) return FALSE; - if(lx0==lx2 && lx1==lx3) return FALSE; - if(lx0==lx3 && lx1==lx2) return FALSE; - return TRUE; -} -*/ - -// real rect test -static __inline BOOL IsNoRect(void) -{ - //if(!(dwActFixes&0x200)) return FALSE; - - if(ly0==ly1) - { - if(lx1==lx3 && ly3==ly2 && lx2==lx0) return FALSE; - if(lx1==lx2 && ly2==ly3 && lx3==lx0) return FALSE; - return TRUE; - } - - if(ly0==ly2) - { - if(lx2==lx3 && ly3==ly1 && lx1==lx0) return FALSE; - if(lx2==lx1 && ly1==ly3 && lx3==lx0) return FALSE; - return TRUE; - } - - if(ly0==ly3) - { - if(lx3==lx2 && ly2==ly1 && lx1==lx0) return FALSE; - if(lx3==lx1 && ly1==ly2 && lx2==lx0) return FALSE; - return TRUE; - } - return TRUE; -} - -//////////////////////////////////////////////////////////////////////// - -void drawPoly3FT(unsigned char *baseAddr) -{ - uint32_t *gpuData = ((uint32_t *) baseAddr); - - if(GlobalTextIL && GlobalTextTP<2) - { - if(GlobalTextTP==0) - drawPoly3TEx4_IL(lx0,ly0,lx1,ly1,lx2,ly2, - (gpuData[2] & 0x000000ff), ((gpuData[2]>>8) & 0x000000ff), (gpuData[4] & 0x000000ff), ((gpuData[4]>>8) & 0x000000ff),(gpuData[6] & 0x000000ff), ((gpuData[6]>>8) & 0x000000ff), - ((gpuData[2]>>12) & 0x3f0), ((gpuData[2]>>22) & iGPUHeightMask)); - else - drawPoly3TEx8_IL(lx0,ly0,lx1,ly1,lx2,ly2, - (gpuData[2] & 0x000000ff), ((gpuData[2]>>8) & 0x000000ff), (gpuData[4] & 0x000000ff), ((gpuData[4]>>8) & 0x000000ff),(gpuData[6] & 0x000000ff), ((gpuData[6]>>8) & 0x000000ff), - ((gpuData[2]>>12) & 0x3f0), ((gpuData[2]>>22) & iGPUHeightMask)); - return; - } - - if(!bUsingTWin)// && !(dwActFixes&0x100)) - { - switch(GlobalTextTP) // depending on texture mode - { - case 0: - drawPoly3TEx4(lx0,ly0,lx1,ly1,lx2,ly2, - (gpuData[2] & 0x000000ff), ((gpuData[2]>>8) & 0x000000ff), (gpuData[4] & 0x000000ff), ((gpuData[4]>>8) & 0x000000ff),(gpuData[6] & 0x000000ff), ((gpuData[6]>>8) & 0x000000ff), - ((gpuData[2]>>12) & 0x3f0), ((gpuData[2]>>22) & iGPUHeightMask)); - return; - case 1: - drawPoly3TEx8(lx0,ly0,lx1,ly1,lx2,ly2, - (gpuData[2] & 0x000000ff), ((gpuData[2]>>8) & 0x000000ff), (gpuData[4] & 0x000000ff), ((gpuData[4]>>8) & 0x000000ff),(gpuData[6] & 0x000000ff), ((gpuData[6]>>8) & 0x000000ff), - ((gpuData[2]>>12) & 0x3f0), ((gpuData[2]>>22) & iGPUHeightMask)); - return; - case 2: - drawPoly3TD(lx0,ly0,lx1,ly1,lx2,ly2,(gpuData[2] & 0x000000ff), ((gpuData[2]>>8) & 0x000000ff), (gpuData[4] & 0x000000ff), ((gpuData[4]>>8) & 0x000000ff),(gpuData[6] & 0x000000ff), ((gpuData[6]>>8) & 0x000000ff)); - return; - } - return; - } - - switch(GlobalTextTP) // depending on texture mode - { - case 0: - drawPoly3TEx4_TW(lx0,ly0,lx1,ly1,lx2,ly2, - (gpuData[2] & 0x000000ff), ((gpuData[2]>>8) & 0x000000ff), (gpuData[4] & 0x000000ff), ((gpuData[4]>>8) & 0x000000ff),(gpuData[6] & 0x000000ff), ((gpuData[6]>>8) & 0x000000ff), - ((gpuData[2]>>12) & 0x3f0), ((gpuData[2]>>22) & iGPUHeightMask)); - return; - case 1: - drawPoly3TEx8_TW(lx0,ly0,lx1,ly1,lx2,ly2, - (gpuData[2] & 0x000000ff), ((gpuData[2]>>8) & 0x000000ff), (gpuData[4] & 0x000000ff), ((gpuData[4]>>8) & 0x000000ff),(gpuData[6] & 0x000000ff), ((gpuData[6]>>8) & 0x000000ff), - ((gpuData[2]>>12) & 0x3f0), ((gpuData[2]>>22) & iGPUHeightMask)); - return; - case 2: - drawPoly3TD_TW(lx0,ly0,lx1,ly1,lx2,ly2,(gpuData[2] & 0x000000ff), ((gpuData[2]>>8) & 0x000000ff), (gpuData[4] & 0x000000ff), ((gpuData[4]>>8) & 0x000000ff),(gpuData[6] & 0x000000ff), ((gpuData[6]>>8) & 0x000000ff)); - return; - } -} - -//////////////////////////////////////////////////////////////////////// - -void drawPoly4FT(unsigned char *baseAddr) -{ - uint32_t *gpuData = ((uint32_t *) baseAddr); - - if(GlobalTextIL && GlobalTextTP<2) - { - if(GlobalTextTP==0) - drawPoly4TEx4_IL(lx0,ly0,lx1,ly1,lx3,ly3,lx2,ly2, - (gpuData[2] & 0x000000ff), ((gpuData[2]>>8) & 0x000000ff), (gpuData[4] & 0x000000ff), ((gpuData[4]>>8) & 0x000000ff),(gpuData[8] & 0x000000ff), ((gpuData[8]>>8) & 0x000000ff),(gpuData[6] & 0x000000ff), ((gpuData[6]>>8) & 0x000000ff), ((gpuData[2]>>12) & 0x3f0), ((gpuData[2]>>22) & iGPUHeightMask)); - else - drawPoly4TEx8_IL(lx0,ly0,lx1,ly1,lx3,ly3,lx2,ly2, - (gpuData[2] & 0x000000ff), ((gpuData[2]>>8) & 0x000000ff), (gpuData[4] & 0x000000ff), ((gpuData[4]>>8) & 0x000000ff),(gpuData[8] & 0x000000ff), ((gpuData[8]>>8) & 0x000000ff),(gpuData[6] & 0x000000ff), ((gpuData[6]>>8) & 0x000000ff), ((gpuData[2]>>12) & 0x3f0), ((gpuData[2]>>22) & iGPUHeightMask)); - return; - } - - if(!bUsingTWin) - { -#ifdef POLYQUAD3GT - if(IsNoRect()) - { - switch (GlobalTextTP) - { - case 0: - drawPoly4TEx4_TRI(lx0,ly0,lx1,ly1,lx3,ly3,lx2,ly2, - (gpuData[2] & 0x000000ff), ((gpuData[2]>>8) & 0x000000ff), (gpuData[4] & 0x000000ff), ((gpuData[4]>>8) & 0x000000ff),(gpuData[8] & 0x000000ff), ((gpuData[8]>>8) & 0x000000ff),(gpuData[6] & 0x000000ff), ((gpuData[6]>>8) & 0x000000ff), ((gpuData[2]>>12) & 0x3f0), ((gpuData[2]>>22) & iGPUHeightMask)); - return; - case 1: - drawPoly4TEx8_TRI(lx0,ly0,lx1,ly1,lx3,ly3,lx2,ly2, - (gpuData[2] & 0x000000ff), ((gpuData[2]>>8) & 0x000000ff), (gpuData[4] & 0x000000ff), ((gpuData[4]>>8) & 0x000000ff),(gpuData[8] & 0x000000ff), ((gpuData[8]>>8) & 0x000000ff),(gpuData[6] & 0x000000ff), ((gpuData[6]>>8) & 0x000000ff), ((gpuData[2]>>12) & 0x3f0), ((gpuData[2]>>22) & iGPUHeightMask)); - return; - case 2: - drawPoly4TD_TRI(lx0,ly0,lx1,ly1,lx3,ly3,lx2,ly2,(gpuData[2] & 0x000000ff), ((gpuData[2]>>8) & 0x000000ff), (gpuData[4] & 0x000000ff), ((gpuData[4]>>8) & 0x000000ff),(gpuData[8] & 0x000000ff), ((gpuData[8]>>8) & 0x000000ff),(gpuData[6] & 0x000000ff), ((gpuData[6]>>8) & 0x000000ff)); - return; - } - return; - } -#endif - - switch (GlobalTextTP) - { - case 0: // grandia investigations needed - drawPoly4TEx4(lx0,ly0,lx1,ly1,lx3,ly3,lx2,ly2, - (gpuData[2] & 0x000000ff), ((gpuData[2]>>8) & 0x000000ff), (gpuData[4] & 0x000000ff), ((gpuData[4]>>8) & 0x000000ff),(gpuData[8] & 0x000000ff), ((gpuData[8]>>8) & 0x000000ff),(gpuData[6] & 0x000000ff), ((gpuData[6]>>8) & 0x000000ff), ((gpuData[2]>>12) & 0x3f0), ((gpuData[2]>>22) & iGPUHeightMask)); - return; - case 1: - drawPoly4TEx8(lx0,ly0,lx1,ly1,lx3,ly3,lx2,ly2, - (gpuData[2] & 0x000000ff), ((gpuData[2]>>8) & 0x000000ff), (gpuData[4] & 0x000000ff), ((gpuData[4]>>8) & 0x000000ff),(gpuData[8] & 0x000000ff), ((gpuData[8]>>8) & 0x000000ff),(gpuData[6] & 0x000000ff), ((gpuData[6]>>8) & 0x000000ff), ((gpuData[2]>>12) & 0x3f0), ((gpuData[2]>>22) & iGPUHeightMask)); - return; - case 2: - drawPoly4TD(lx0,ly0,lx1,ly1,lx3,ly3,lx2,ly2,(gpuData[2] & 0x000000ff), ((gpuData[2]>>8) & 0x000000ff), (gpuData[4] & 0x000000ff), ((gpuData[4]>>8) & 0x000000ff),(gpuData[8] & 0x000000ff), ((gpuData[8]>>8) & 0x000000ff),(gpuData[6] & 0x000000ff), ((gpuData[6]>>8) & 0x000000ff)); - return; - } - return; - } - - switch (GlobalTextTP) - { - case 0: - drawPoly4TEx4_TW(lx0,ly0,lx1,ly1,lx3,ly3,lx2,ly2, - (gpuData[2] & 0x000000ff), ((gpuData[2]>>8) & 0x000000ff), (gpuData[4] & 0x000000ff), ((gpuData[4]>>8) & 0x000000ff),(gpuData[8] & 0x000000ff), ((gpuData[8]>>8) & 0x000000ff),(gpuData[6] & 0x000000ff), ((gpuData[6]>>8) & 0x000000ff), ((gpuData[2]>>12) & 0x3f0), ((gpuData[2]>>22) & iGPUHeightMask)); - return; - case 1: - drawPoly4TEx8_TW(lx0,ly0,lx1,ly1,lx3,ly3,lx2,ly2, - (gpuData[2] & 0x000000ff), ((gpuData[2]>>8) & 0x000000ff), (gpuData[4] & 0x000000ff), ((gpuData[4]>>8) & 0x000000ff),(gpuData[8] & 0x000000ff), ((gpuData[8]>>8) & 0x000000ff),(gpuData[6] & 0x000000ff), ((gpuData[6]>>8) & 0x000000ff), ((gpuData[2]>>12) & 0x3f0), ((gpuData[2]>>22) & iGPUHeightMask)); - return; - case 2: - drawPoly4TD_TW(lx0,ly0,lx1,ly1,lx3,ly3,lx2,ly2,(gpuData[2] & 0x000000ff), ((gpuData[2]>>8) & 0x000000ff), (gpuData[4] & 0x000000ff), ((gpuData[4]>>8) & 0x000000ff),(gpuData[8] & 0x000000ff), ((gpuData[8]>>8) & 0x000000ff),(gpuData[6] & 0x000000ff), ((gpuData[6]>>8) & 0x000000ff)); - return; - } -} - -//////////////////////////////////////////////////////////////////////// - -void drawPoly3GT(unsigned char * baseAddr) -{ - uint32_t *gpuData = ((uint32_t *) baseAddr); - - if(GlobalTextIL && GlobalTextTP<2) - { - if(GlobalTextTP==0) - drawPoly3TGEx4_IL(lx0,ly0,lx1,ly1,lx2,ly2, - (gpuData[2] & 0x000000ff), ((gpuData[2]>>8) & 0x000000ff), (gpuData[5] & 0x000000ff), ((gpuData[5]>>8) & 0x000000ff),(gpuData[8] & 0x000000ff), ((gpuData[8]>>8) & 0x000000ff), - ((gpuData[2]>>12) & 0x3f0), ((gpuData[2]>>22) & iGPUHeightMask), - gpuData[0],gpuData[3],gpuData[6]); - else - drawPoly3TGEx8_IL(lx0,ly0,lx1,ly1,lx2,ly2, - (gpuData[2] & 0x000000ff), ((gpuData[2]>>8) & 0x000000ff), (gpuData[5] & 0x000000ff), ((gpuData[5]>>8) & 0x000000ff),(gpuData[8] & 0x000000ff), ((gpuData[8]>>8) & 0x000000ff), - ((gpuData[2]>>12) & 0x3f0), ((gpuData[2]>>22) & iGPUHeightMask), - gpuData[0],gpuData[3],gpuData[6]); - return; - } - - if(!bUsingTWin) - { - switch (GlobalTextTP) - { - case 0: - drawPoly3TGEx4(lx0,ly0,lx1,ly1,lx2,ly2, - (gpuData[2] & 0x000000ff), ((gpuData[2]>>8) & 0x000000ff), (gpuData[5] & 0x000000ff), ((gpuData[5]>>8) & 0x000000ff),(gpuData[8] & 0x000000ff), ((gpuData[8]>>8) & 0x000000ff), - ((gpuData[2]>>12) & 0x3f0), ((gpuData[2]>>22) & iGPUHeightMask), - gpuData[0],gpuData[3],gpuData[6]); - return; - case 1: - drawPoly3TGEx8(lx0,ly0,lx1,ly1,lx2,ly2, - (gpuData[2] & 0x000000ff), ((gpuData[2]>>8) & 0x000000ff), (gpuData[5] & 0x000000ff), ((gpuData[5]>>8) & 0x000000ff),(gpuData[8] & 0x000000ff), ((gpuData[8]>>8) & 0x000000ff), - ((gpuData[2]>>12) & 0x3f0), ((gpuData[2]>>22) & iGPUHeightMask), - gpuData[0],gpuData[3],gpuData[6]); - return; - case 2: - drawPoly3TGD(lx0,ly0,lx1,ly1,lx2,ly2,(gpuData[2] & 0x000000ff), ((gpuData[2]>>8) & 0x000000ff), (gpuData[5] & 0x000000ff), ((gpuData[5]>>8) & 0x000000ff),(gpuData[8] & 0x000000ff), ((gpuData[8]>>8) & 0x000000ff),gpuData[0],gpuData[3],gpuData[6]); - return; - } - return; - } - - switch(GlobalTextTP) - { - case 0: - drawPoly3TGEx4_TW(lx0,ly0,lx1,ly1,lx2,ly2, - (gpuData[2] & 0x000000ff), ((gpuData[2]>>8) & 0x000000ff), (gpuData[5] & 0x000000ff), ((gpuData[5]>>8) & 0x000000ff),(gpuData[8] & 0x000000ff), ((gpuData[8]>>8) & 0x000000ff), - ((gpuData[2]>>12) & 0x3f0), ((gpuData[2]>>22) & iGPUHeightMask), - gpuData[0],gpuData[3],gpuData[6]); - return; - case 1: - drawPoly3TGEx8_TW(lx0,ly0,lx1,ly1,lx2,ly2, - (gpuData[2] & 0x000000ff), ((gpuData[2]>>8) & 0x000000ff), (gpuData[5] & 0x000000ff), ((gpuData[5]>>8) & 0x000000ff),(gpuData[8] & 0x000000ff), ((gpuData[8]>>8) & 0x000000ff), - ((gpuData[2]>>12) & 0x3f0), ((gpuData[2]>>22) & iGPUHeightMask), - gpuData[0],gpuData[3],gpuData[6]); - return; - case 2: - drawPoly3TGD_TW(lx0,ly0,lx1,ly1,lx2,ly2,(gpuData[2] & 0x000000ff), ((gpuData[2]>>8) & 0x000000ff), (gpuData[5] & 0x000000ff), ((gpuData[5]>>8) & 0x000000ff),(gpuData[8] & 0x000000ff), ((gpuData[8]>>8) & 0x000000ff),gpuData[0],gpuData[3],gpuData[6]); - return; - } -} - -//////////////////////////////////////////////////////////////////////// - -void drawPoly4GT(unsigned char *baseAddr) -{ - uint32_t *gpuData = ((uint32_t *) baseAddr); - - if(GlobalTextIL && GlobalTextTP<2) - { - if(GlobalTextTP==0) - drawPoly4TGEx4_TRI_IL(lx0,ly0,lx1,ly1,lx3,ly3,lx2,ly2, - (gpuData[2] & 0x000000ff), ((gpuData[2]>>8) & 0x000000ff), (gpuData[5] & 0x000000ff), ((gpuData[5]>>8) & 0x000000ff),(gpuData[11] & 0x000000ff), ((gpuData[11]>>8) & 0x000000ff),(gpuData[8] & 0x000000ff), ((gpuData[8]>>8) & 0x000000ff), - ((gpuData[2]>>12) & 0x3f0),((gpuData[2]>>22) & iGPUHeightMask), - gpuData[0],gpuData[3],gpuData[6],gpuData[9]); - else - drawPoly4TGEx8_TRI_IL(lx0,ly0,lx1,ly1,lx3,ly3,lx2,ly2, - (gpuData[2] & 0x000000ff), ((gpuData[2]>>8) & 0x000000ff), (gpuData[5] & 0x000000ff), ((gpuData[5]>>8) & 0x000000ff),(gpuData[11] & 0x000000ff), ((gpuData[11]>>8) & 0x000000ff),(gpuData[8] & 0x000000ff), ((gpuData[8]>>8) & 0x000000ff), - ((gpuData[2]>>12) & 0x3f0),((gpuData[2]>>22) & iGPUHeightMask), - gpuData[0],gpuData[3],gpuData[6],gpuData[9]); - return; - } - - if(!bUsingTWin) - { -#ifdef POLYQUAD3GT - if(IsNoRect()) - { - switch (GlobalTextTP) - { - case 0: - drawPoly4TGEx4_TRI(lx0,ly0,lx1,ly1,lx3,ly3,lx2,ly2, - (gpuData[2] & 0x000000ff), ((gpuData[2]>>8) & 0x000000ff), (gpuData[5] & 0x000000ff), ((gpuData[5]>>8) & 0x000000ff),(gpuData[11] & 0x000000ff), ((gpuData[11]>>8) & 0x000000ff),(gpuData[8] & 0x000000ff), ((gpuData[8]>>8) & 0x000000ff), - ((gpuData[2]>>12) & 0x3f0),((gpuData[2]>>22) & iGPUHeightMask), - gpuData[0],gpuData[3],gpuData[6],gpuData[9]); - - return; - case 1: - drawPoly4TGEx8_TRI(lx0,ly0,lx1,ly1,lx3,ly3,lx2,ly2, - (gpuData[2] & 0x000000ff), ((gpuData[2]>>8) & 0x000000ff), (gpuData[5] & 0x000000ff), ((gpuData[5]>>8) & 0x000000ff),(gpuData[11] & 0x000000ff), ((gpuData[11]>>8) & 0x000000ff),(gpuData[8] & 0x000000ff), ((gpuData[8]>>8) & 0x000000ff), - ((gpuData[2]>>12) & 0x3f0),((gpuData[2]>>22) & iGPUHeightMask), - gpuData[0],gpuData[3],gpuData[6],gpuData[9]); - return; - case 2: - drawPoly4TGD_TRI(lx0,ly0,lx1,ly1,lx3,ly3,lx2,ly2,(gpuData[2] & 0x000000ff),((gpuData[2]>>8) & 0x000000ff), (gpuData[5] & 0x000000ff), ((gpuData[5]>>8) & 0x000000ff),(gpuData[11] & 0x000000ff), ((gpuData[11]>>8) & 0x000000ff),(gpuData[8] & 0x000000ff), ((gpuData[8]>>8) & 0x000000ff),gpuData[0],gpuData[3],gpuData[6],gpuData[9]); - return; - } - return; - } -#endif - - switch (GlobalTextTP) - { - case 0: - drawPoly4TGEx4(lx0,ly0,lx1,ly1,lx3,ly3,lx2,ly2, - (gpuData[2] & 0x000000ff), ((gpuData[2]>>8) & 0x000000ff), (gpuData[5] & 0x000000ff), ((gpuData[5]>>8) & 0x000000ff),(gpuData[11] & 0x000000ff), ((gpuData[11]>>8) & 0x000000ff),(gpuData[8] & 0x000000ff), ((gpuData[8]>>8) & 0x000000ff), - ((gpuData[2]>>12) & 0x3f0),((gpuData[2]>>22) & iGPUHeightMask), - gpuData[0],gpuData[3],gpuData[6],gpuData[9]); - - return; - case 1: - drawPoly4TGEx8(lx0,ly0,lx1,ly1,lx3,ly3,lx2,ly2, - (gpuData[2] & 0x000000ff), ((gpuData[2]>>8) & 0x000000ff), (gpuData[5] & 0x000000ff), ((gpuData[5]>>8) & 0x000000ff),(gpuData[11] & 0x000000ff), ((gpuData[11]>>8) & 0x000000ff),(gpuData[8] & 0x000000ff), ((gpuData[8]>>8) & 0x000000ff), - ((gpuData[2]>>12) & 0x3f0),((gpuData[2]>>22) & iGPUHeightMask), - gpuData[0],gpuData[3],gpuData[6],gpuData[9]); - return; - case 2: - drawPoly4TGD(lx0,ly0,lx1,ly1,lx3,ly3,lx2,ly2,(gpuData[2] & 0x000000ff),((gpuData[2]>>8) & 0x000000ff), (gpuData[5] & 0x000000ff), ((gpuData[5]>>8) & 0x000000ff),(gpuData[11] & 0x000000ff), ((gpuData[11]>>8) & 0x000000ff),(gpuData[8] & 0x000000ff), ((gpuData[8]>>8) & 0x000000ff),gpuData[0],gpuData[3],gpuData[6],gpuData[9]); - return; - } - return; - } - - switch (GlobalTextTP) - { - case 0: - drawPoly4TGEx4_TW(lx0,ly0,lx1,ly1,lx3,ly3,lx2,ly2, - (gpuData[2] & 0x000000ff), ((gpuData[2]>>8) & 0x000000ff), (gpuData[5] & 0x000000ff), ((gpuData[5]>>8) & 0x000000ff),(gpuData[11] & 0x000000ff), ((gpuData[11]>>8) & 0x000000ff),(gpuData[8] & 0x000000ff), ((gpuData[8]>>8) & 0x000000ff), - ((gpuData[2]>>12) & 0x3f0),((gpuData[2]>>22) & iGPUHeightMask), - gpuData[0],gpuData[3],gpuData[6],gpuData[9]); - return; - case 1: - drawPoly4TGEx8_TW(lx0,ly0,lx1,ly1,lx3,ly3,lx2,ly2, - (gpuData[2] & 0x000000ff), ((gpuData[2]>>8) & 0x000000ff), (gpuData[5] & 0x000000ff), ((gpuData[5]>>8) & 0x000000ff),(gpuData[11] & 0x000000ff), ((gpuData[11]>>8) & 0x000000ff),(gpuData[8] & 0x000000ff), ((gpuData[8]>>8) & 0x000000ff), - ((gpuData[2]>>12) & 0x3f0),((gpuData[2]>>22) & iGPUHeightMask), - gpuData[0],gpuData[3],gpuData[6],gpuData[9]); - return; - case 2: - drawPoly4TGD_TW(lx0,ly0,lx1,ly1,lx3,ly3,lx2,ly2,(gpuData[2] & 0x000000ff),((gpuData[2]>>8) & 0x000000ff), (gpuData[5] & 0x000000ff), ((gpuData[5]>>8) & 0x000000ff),(gpuData[11] & 0x000000ff), ((gpuData[11]>>8) & 0x000000ff),(gpuData[8] & 0x000000ff), ((gpuData[8]>>8) & 0x000000ff),gpuData[0],gpuData[3],gpuData[6],gpuData[9]); - return; - } -} - -//////////////////////////////////////////////////////////////////////// -// SPRITE FUNCS -//////////////////////////////////////////////////////////////////////// - -void DrawSoftwareSpriteTWin(unsigned char * baseAddr, int w, int h) -{ - uint32_t *gpuData = (uint32_t *)baseAddr; - short sx0,sy0,sx1,sy1,sx2,sy2,sx3,sy3; - short tx0,ty0,tx1,ty1,tx2,ty2,tx3,ty3; - - sx0=lx0; - sy0=ly0; - - sx0=sx3=sx0+PSXDisplay.DrawOffset.x; - sx1=sx2=sx0+w; - sy0=sy1=sy0+PSXDisplay.DrawOffset.y; - sy2=sy3=sy0+h; - - tx0=tx3=gpuData[2]&0xff; - tx1=tx2=tx0+w; - ty0=ty1=(gpuData[2]>>8)&0xff; - ty2=ty3=ty0+h; - - switch (GlobalTextTP) - { - case 0: - drawPoly4TEx4_TW_S(sx0,sy0,sx1,sy1,sx2,sy2,sx3,sy3, - tx0,ty0,tx1,ty1,tx2,ty2,tx3,ty3, - ((gpuData[2]>>12) & 0x3f0), ((gpuData[2]>>22) & iGPUHeightMask)); - return; - case 1: - drawPoly4TEx8_TW_S(sx0,sy0,sx1,sy1,sx2,sy2,sx3,sy3, - tx0,ty0,tx1,ty1,tx2,ty2,tx3,ty3, - ((gpuData[2]>>12) & 0x3f0), ((gpuData[2]>>22) & iGPUHeightMask)); - return; - case 2: - drawPoly4TD_TW_S(sx0,sy0,sx1,sy1,sx2,sy2,sx3,sy3, - tx0,ty0,tx1,ty1,tx2,ty2,tx3,ty3); - return; - } -} - -//////////////////////////////////////////////////////////////////////// - -void DrawSoftwareSpriteMirror(unsigned char * baseAddr, int w, int h) -{ - int sprtY,sprtX,sprtW,sprtH,lXDir,lYDir; - int clutY0,clutX0,clutP,textX0,textY0,sprtYa,sprCY,sprCX,sprA; - short tC; - uint32_t *gpuData = (uint32_t *)baseAddr; - sprtY = ly0; - sprtX = lx0; - sprtH = h; - sprtW = w; - clutY0 = (gpuData[2]>>22) & iGPUHeightMask; - clutX0 = (gpuData[2]>>12) & 0x3f0; - clutP = (clutY0<<11) + (clutX0<<1); - textY0 = ((gpuData[2]>>8) & 0x000000ff) + GlobalTextAddrY; - textX0 = (gpuData[2] & 0x000000ff); - - sprtX+=PSXDisplay.DrawOffset.x; - sprtY+=PSXDisplay.DrawOffset.y; - -// while (sprtX>1023) sprtX-=1024; -// while (sprtY>MAXYLINESMIN1) sprtY-=MAXYLINES; - - if(sprtX>drawW) - { -// if((sprtX+sprtW)>1023) sprtX-=1024; -// else return; - return; - } - - if(sprtY>drawH) - { -// if ((sprtY+sprtH)>MAXYLINESMIN1) sprtY-=MAXYLINES; -// else return; - return; - } - - if(sprtY<drawY) - { - if((sprtY+sprtH)<drawY) return; - sprtH-=(drawY-sprtY); - textY0+=(drawY-sprtY); - sprtY=drawY; - } - - if(sprtX<drawX) - { - if((sprtX+sprtW)<drawX) return; - sprtW-=(drawX-sprtX); - textX0+=(drawX-sprtX); - sprtX=drawX; - } - - if((sprtY+sprtH)>drawH) sprtH=drawH-sprtY+1; - if((sprtX+sprtW)>drawW) sprtW=drawW-sprtX+1; - - if(usMirror&0x1000) lXDir=-1; else lXDir=1; - if(usMirror&0x2000) lYDir=-1; else lYDir=1; - - switch (GlobalTextTP) - { - case 0: // texture is 4-bit - - sprtW=sprtW/2; - textX0=(GlobalTextAddrX<<1)+(textX0>>1); - sprtYa=(sprtY<<10); - clutP=(clutY0<<10)+clutX0; - for (sprCY=0;sprCY<sprtH;sprCY++) - for (sprCX=0;sprCX<sprtW;sprCX++) - { - tC= psxVub[((textY0+(sprCY*lYDir))<<11) + textX0 +(sprCX*lXDir)]; - sprA=sprtYa+(sprCY<<10)+sprtX + (sprCX<<1); - GetTextureTransColG_SPR(&psxVuw[sprA],psxVuw[clutP+((tC>>4)&0xf)]); - GetTextureTransColG_SPR(&psxVuw[sprA+1],psxVuw[clutP+(tC&0xf)]); - } - return; - - case 1: - - clutP>>=1; - for(sprCY=0;sprCY<sprtH;sprCY++) - for(sprCX=0;sprCX<sprtW;sprCX++) - { - tC = psxVub[((textY0+(sprCY*lYDir))<<11)+(GlobalTextAddrX<<1) + textX0 + (sprCX*lXDir)] & 0xff; - GetTextureTransColG_SPR(&psxVuw[((sprtY+sprCY)<<10)+sprtX + sprCX],psxVuw[clutP+tC]); - } - return; - - - case 2: - - for (sprCY=0;sprCY<sprtH;sprCY++) - for (sprCX=0;sprCX<sprtW;sprCX++) - { - GetTextureTransColG_SPR(&psxVuw[((sprtY+sprCY)<<10)+sprtX+sprCX], - psxVuw[((textY0+(sprCY*lYDir))<<10)+GlobalTextAddrX + textX0 +(sprCX*lXDir)]); - } - return; - } -} - -//////////////////////////////////////////////////////////////////////// - -static void DrawSoftwareSprite_IL(unsigned char * baseAddr,short w,short h,int tx,int ty) -{ - int sprtY,sprtX,sprtW,sprtH,tdx,tdy; - uint32_t *gpuData = (uint32_t *)baseAddr; - - sprtY = ly0; - sprtX = lx0; - sprtH = h; - sprtW = w; - - sprtX+=PSXDisplay.DrawOffset.x; - sprtY+=PSXDisplay.DrawOffset.y; - - if(sprtX>drawW) return; - if(sprtY>drawH) return; - - tdx=tx+sprtW; - tdy=ty+sprtH; - - sprtW+=sprtX; - sprtH+=sprtY; - - // Pete is too lazy to make a faster version ;) - - if(GlobalTextTP==0) - drawPoly4TEx4_IL(sprtX,sprtY,sprtX,sprtH,sprtW,sprtH,sprtW,sprtY, - tx,ty, tx,tdy, tdx,tdy, tdx,ty, - (gpuData[2]>>12) & 0x3f0, ((gpuData[2]>>22) & iGPUHeightMask)); - - - else - drawPoly4TEx8_IL(sprtX,sprtY,sprtX,sprtH,sprtW,sprtH,sprtW,sprtY, - tx,ty, tx,tdy, tdx,tdy, tdx,ty, - (gpuData[2]>>12) & 0x3f0, ((gpuData[2]>>22) & iGPUHeightMask)); -} - -//////////////////////////////////////////////////////////////////////// - -void DrawSoftwareSprite(unsigned char *baseAddr, short w, short h, int tx, int ty) -{ - int sprtY, sprtX, sprtW, sprtH; - int clutY0, clutX0, clutP, textX0, textY0, sprtYa, sprCY, sprCX, sprA; - short tC, tC2; - uint32_t *gpuData = (uint32_t *)baseAddr; - unsigned char *pV; - BOOL bWT,bWS; - - if(GlobalTextIL && GlobalTextTP<2) - {DrawSoftwareSprite_IL(baseAddr,w,h,tx,ty);return;} - - sprtY = ly0; - sprtX = lx0; - sprtH = h; - sprtW = w; - clutY0 = (gpuData[2]>>22) & iGPUHeightMask; - clutX0 = (gpuData[2]>>12) & 0x3f0; - - clutP = (clutY0<<11) + (clutX0<<1); - - textY0 =ty+ GlobalTextAddrY; - textX0 =tx; - - sprtX+=PSXDisplay.DrawOffset.x; - sprtY+=PSXDisplay.DrawOffset.y; - - //while (sprtX>1023) sprtX-=1024; - //while (sprtY>MAXYLINESMIN1) sprtY-=MAXYLINES; - - if(sprtX>drawW) - { -// if((sprtX+sprtW)>1023) sprtX-=1024; -// else return; - return; - } - - if(sprtY>drawH) - { -// if ((sprtY+sprtH)>MAXYLINESMIN1) sprtY-=MAXYLINES; -// else return; - return; - } - - if(sprtY<drawY) - { - if((sprtY+sprtH)<drawY) return; - sprtH-=(drawY-sprtY); - textY0+=(drawY-sprtY); - sprtY=drawY; - } - - if(sprtX<drawX) - { - if((sprtX+sprtW)<drawX) return; - - sprtW-=(drawX-sprtX); - textX0+=(drawX-sprtX); - sprtX=drawX; - } - - if((sprtY+sprtH)>drawH) sprtH=drawH-sprtY+1; - if((sprtX+sprtW)>drawW) sprtW=drawW-sprtX+1; - - - bWT=FALSE; - bWS=FALSE; - - switch (GlobalTextTP) - { - case 0: - - if(textX0&1) {bWS=TRUE;sprtW--;} - if(sprtW&1) bWT=TRUE; - - sprtW=sprtW>>1; - textX0=(GlobalTextAddrX<<1)+(textX0>>1)+(textY0<<11); - sprtYa=(sprtY<<10)+sprtX; - clutP=(clutY0<<10)+clutX0; - -#ifdef FASTSOLID - - if(!bCheckMask && !DrawSemiTrans) - { - for (sprCY=0;sprCY<sprtH;sprCY++) - { - sprA=sprtYa+(sprCY<<10); - pV=&psxVub[(sprCY<<11)+textX0]; - - if(bWS) - { - tC=*pV++; - GetTextureTransColG_S(&psxVuw[sprA++],psxVuw[clutP+((tC>>4)&0xf)]); - } - - for (sprCX=0;sprCX<sprtW;sprCX++,sprA+=2) - { - tC=*pV++; - - GetTextureTransColG32_S((uint32_t *)&psxVuw[sprA], - (((int)psxVuw[clutP+((tC>>4)&0xf)])<<16)| - psxVuw[clutP+(tC&0x0f)]); - } - - if(bWT) - { - tC=*pV; - GetTextureTransColG_S(&psxVuw[sprA],psxVuw[clutP+(tC&0x0f)]); - } - } - return; - } - -#endif - - for (sprCY=0;sprCY<sprtH;sprCY++) - { - sprA=sprtYa+(sprCY<<10); - pV=&psxVub[(sprCY<<11)+textX0]; - - if(bWS) - { - tC=*pV++; - GetTextureTransColG_SPR(&psxVuw[sprA++],psxVuw[clutP+((tC>>4)&0xf)]); - } - - for (sprCX=0;sprCX<sprtW;sprCX++,sprA+=2) - { - tC=*pV++; - - GetTextureTransColG32_SPR((uint32_t *)&psxVuw[sprA], - (((int)psxVuw[clutP+((tC>>4)&0xf)])<<16)| - psxVuw[clutP+(tC&0x0f)]); - } - - if(bWT) - { - tC=*pV; - GetTextureTransColG_SPR(&psxVuw[sprA],psxVuw[clutP+(tC&0x0f)]); - } - } - return; - - case 1: - clutP>>=1;sprtW--; - textX0+=(GlobalTextAddrX<<1) + (textY0<<11); - -#ifdef FASTSOLID - - if(!bCheckMask && !DrawSemiTrans) - { - for(sprCY=0;sprCY<sprtH;sprCY++) - { - sprA=((sprtY+sprCY)<<10)+sprtX; - pV=&psxVub[(sprCY<<11)+textX0]; - for(sprCX=0;sprCX<sprtW;sprCX+=2,sprA+=2) - { - tC = *pV++;tC2 = *pV++; - GetTextureTransColG32_S((uint32_t *)&psxVuw[sprA], - (((int)psxVuw[clutP+tC2])<<16)| - psxVuw[clutP+tC]); - } - if(sprCX==sprtW) - GetTextureTransColG_S(&psxVuw[sprA],psxVuw[clutP+(*pV)]); - } - return; - } - -#endif - - for(sprCY=0;sprCY<sprtH;sprCY++) - { - sprA=((sprtY+sprCY)<<10)+sprtX; - pV=&psxVub[(sprCY<<11)+textX0]; - for(sprCX=0;sprCX<sprtW;sprCX+=2,sprA+=2) - { - tC = *pV++;tC2 = *pV++; - GetTextureTransColG32_SPR((uint32_t *)&psxVuw[sprA], - (((int)psxVuw[clutP+tC2])<<16)| - psxVuw[clutP+tC]); - } - if(sprCX==sprtW) - GetTextureTransColG_SPR(&psxVuw[sprA],psxVuw[clutP+(*pV)]); - } - return; - - case 2: - - textX0+=(GlobalTextAddrX) + (textY0<<10); - sprtW--; - -#ifdef FASTSOLID - - if(!bCheckMask && !DrawSemiTrans) - { - for (sprCY=0;sprCY<sprtH;sprCY++) - { - sprA=((sprtY+sprCY)<<10)+sprtX; - - for (sprCX=0;sprCX<sprtW;sprCX+=2,sprA+=2) - { - GetTextureTransColG32_S((uint32_t *)&psxVuw[sprA], - (((int)psxVuw[(sprCY<<10) + textX0 + sprCX +1])<<16)| - psxVuw[(sprCY<<10) + textX0 + sprCX]); - } - if(sprCX==sprtW) - GetTextureTransColG_S(&psxVuw[sprA], - psxVuw[(sprCY<<10) + textX0 + sprCX]); - - } - return; - } - -#endif - - for (sprCY=0;sprCY<sprtH;sprCY++) - { - sprA=((sprtY+sprCY)<<10)+sprtX; - - for (sprCX=0;sprCX<sprtW;sprCX+=2,sprA+=2) - { - GetTextureTransColG32_SPR((uint32_t *)&psxVuw[sprA], - (((int)psxVuw[(sprCY<<10) + textX0 + sprCX +1])<<16)| - psxVuw[(sprCY<<10) + textX0 + sprCX]); - } - if(sprCX==sprtW) - GetTextureTransColG_SPR(&psxVuw[sprA], - psxVuw[(sprCY<<10) + textX0 + sprCX]); - - } - return; - } -} - -/////////////////////////////////////////////////////////////////////// - -///////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////// -// LINE FUNCS -//////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////// - - -/////////////////////////////////////////////////////////////////////// - -#if 0 -static void Line_E_SE_Shade(int x0, int y0, int x1, int y1, uint32_t rgb0, uint32_t rgb1) -{ - int dx, dy, incrE, incrSE, d; - uint32_t r0, g0, b0, r1, g1, b1; - int dr, dg, db; - - r0 = (rgb0 & 0x00ff0000); - g0 = (rgb0 & 0x0000ff00) << 8; - b0 = (rgb0 & 0x000000ff) << 16; - r1 = (rgb1 & 0x00ff0000); - g1 = (rgb1 & 0x0000ff00) << 8; - b1 = (rgb1 & 0x000000ff) << 16; - - dx = x1 - x0; - dy = y1 - y0; - - if (dx > 0) - { - dr = ((int)r1 - (int)r0) / dx; - dg = ((int)g1 - (int)g0) / dx; - db = ((int)b1 - (int)b0) / dx; - } - else - { - dr = ((int)r1 - (int)r0); - dg = ((int)g1 - (int)g0); - db = ((int)b1 - (int)b0); - } - - d = 2*dy - dx; /* Initial value of d */ - incrE = 2*dy; /* incr. used for move to E */ - incrSE = 2*(dy - dx); /* incr. used for move to SE */ - - if ((x0>=drawX)&&(x0<drawW)&&(y0>=drawY)&&(y0<drawH)) - GetShadeTransCol(&psxVuw[(y0<<10)+x0],(unsigned short)(((r0 >> 9)&0x7c00)|((g0 >> 14)&0x03e0)|((b0 >> 19)&0x001f))); - while(x0 < x1) - { - if (d <= 0) - { - d = d + incrE; /* Choose E */ - } - else - { - d = d + incrSE; /* Choose SE */ - y0++; - } - x0++; - - r0+=dr; - g0+=dg; - b0+=db; - - if ((x0>=drawX)&&(x0<drawW)&&(y0>=drawY)&&(y0<drawH)) - GetShadeTransCol(&psxVuw[(y0<<10)+x0],(unsigned short)(((r0 >> 9)&0x7c00)|((g0 >> 14)&0x03e0)|((b0 >> 19)&0x001f))); - } -} - -/////////////////////////////////////////////////////////////////////// - -static void Line_S_SE_Shade(int x0, int y0, int x1, int y1, uint32_t rgb0, uint32_t rgb1) -{ - int dx, dy, incrS, incrSE, d; - uint32_t r0, g0, b0, r1, g1, b1; - int dr, dg, db; - - r0 = (rgb0 & 0x00ff0000); - g0 = (rgb0 & 0x0000ff00) << 8; - b0 = (rgb0 & 0x000000ff) << 16; - r1 = (rgb1 & 0x00ff0000); - g1 = (rgb1 & 0x0000ff00) << 8; - b1 = (rgb1 & 0x000000ff) << 16; - - dx = x1 - x0; - dy = y1 - y0; - - if (dy > 0) - { - dr = ((int)r1 - (int)r0) / dy; - dg = ((int)g1 - (int)g0) / dy; - db = ((int)b1 - (int)b0) / dy; - } - else - { - dr = ((int)r1 - (int)r0); - dg = ((int)g1 - (int)g0); - db = ((int)b1 - (int)b0); - } - - d = 2*dx - dy; /* Initial value of d */ - incrS = 2*dx; /* incr. used for move to S */ - incrSE = 2*(dx - dy); /* incr. used for move to SE */ - - if ((x0>=drawX)&&(x0<drawW)&&(y0>=drawY)&&(y0<drawH)) - GetShadeTransCol(&psxVuw[(y0<<10)+x0],(unsigned short)(((r0 >> 9)&0x7c00)|((g0 >> 14)&0x03e0)|((b0 >> 19)&0x001f))); - while(y0 < y1) - { - if (d <= 0) - { - d = d + incrS; /* Choose S */ - } - else - { - d = d + incrSE; /* Choose SE */ - x0++; - } - y0++; - - r0+=dr; - g0+=dg; - b0+=db; - - if ((x0>=drawX)&&(x0<drawW)&&(y0>=drawY)&&(y0<drawH)) - GetShadeTransCol(&psxVuw[(y0<<10)+x0],(unsigned short)(((r0 >> 9)&0x7c00)|((g0 >> 14)&0x03e0)|((b0 >> 19)&0x001f))); - } -} - -/////////////////////////////////////////////////////////////////////// - -static void Line_N_NE_Shade(int x0, int y0, int x1, int y1, uint32_t rgb0, uint32_t rgb1) -{ - int dx, dy, incrN, incrNE, d; - uint32_t r0, g0, b0, r1, g1, b1; - int dr, dg, db; - - r0 = (rgb0 & 0x00ff0000); - g0 = (rgb0 & 0x0000ff00) << 8; - b0 = (rgb0 & 0x000000ff) << 16; - r1 = (rgb1 & 0x00ff0000); - g1 = (rgb1 & 0x0000ff00) << 8; - b1 = (rgb1 & 0x000000ff) << 16; - - dx = x1 - x0; - dy = -(y1 - y0); - - if (dy > 0) - { - dr = ((uint32_t)r1 - (uint32_t)r0) / dy; - dg = ((uint32_t)g1 - (uint32_t)g0) / dy; - db = ((uint32_t)b1 - (uint32_t)b0) / dy; - } - else - { - dr = ((uint32_t)r1 - (uint32_t)r0); - dg = ((uint32_t)g1 - (uint32_t)g0); - db = ((uint32_t)b1 - (uint32_t)b0); - } - - d = 2*dx - dy; /* Initial value of d */ - incrN = 2*dx; /* incr. used for move to N */ - incrNE = 2*(dx - dy); /* incr. used for move to NE */ - - if ((x0>=drawX)&&(x0<drawW)&&(y0>=drawY)&&(y0<drawH)) - GetShadeTransCol(&psxVuw[(y0<<10)+x0],(unsigned short)(((r0 >> 9)&0x7c00)|((g0 >> 14)&0x03e0)|((b0 >> 19)&0x001f))); - while(y0 > y1) - { - if (d <= 0) - { - d = d + incrN; /* Choose N */ - } - else - { - d = d + incrNE; /* Choose NE */ - x0++; - } - y0--; - - r0+=dr; - g0+=dg; - b0+=db; - - if ((x0>=drawX)&&(x0<drawW)&&(y0>=drawY)&&(y0<drawH)) - GetShadeTransCol(&psxVuw[(y0<<10)+x0],(unsigned short)(((r0 >> 9)&0x7c00)|((g0 >> 14)&0x03e0)|((b0 >> 19)&0x001f))); - } -} - -/////////////////////////////////////////////////////////////////////// - -static void Line_E_NE_Shade(int x0, int y0, int x1, int y1, uint32_t rgb0, uint32_t rgb1) -{ - int dx, dy, incrE, incrNE, d; - uint32_t r0, g0, b0, r1, g1, b1; - int dr, dg, db; - - r0 = (rgb0 & 0x00ff0000); - g0 = (rgb0 & 0x0000ff00) << 8; - b0 = (rgb0 & 0x000000ff) << 16; - r1 = (rgb1 & 0x00ff0000); - g1 = (rgb1 & 0x0000ff00) << 8; - b1 = (rgb1 & 0x000000ff) << 16; - - dx = x1 - x0; - dy = -(y1 - y0); - - if (dx > 0) - { - dr = ((int)r1 - (int)r0) / dx; - dg = ((int)g1 - (int)g0) / dx; - db = ((int)b1 - (int)b0) / dx; - } - else - { - dr = ((int)r1 - (int)r0); - dg = ((int)g1 - (int)g0); - db = ((int)b1 - (int)b0); - } - - d = 2*dy - dx; /* Initial value of d */ - incrE = 2*dy; /* incr. used for move to E */ - incrNE = 2*(dy - dx); /* incr. used for move to NE */ - - if ((x0>=drawX)&&(x0<drawW)&&(y0>=drawY)&&(y0<drawH)) - GetShadeTransCol(&psxVuw[(y0<<10)+x0],(unsigned short)(((r0 >> 9)&0x7c00)|((g0 >> 14)&0x03e0)|((b0 >> 19)&0x001f))); - while(x0 < x1) - { - if (d <= 0) - { - d = d + incrE; /* Choose E */ - } - else - { - d = d + incrNE; /* Choose NE */ - y0--; - } - x0++; - - r0+=dr; - g0+=dg; - b0+=db; - - if ((x0>=drawX)&&(x0<drawW)&&(y0>=drawY)&&(y0<drawH)) - GetShadeTransCol(&psxVuw[(y0<<10)+x0],(unsigned short)(((r0 >> 9)&0x7c00)|((g0 >> 14)&0x03e0)|((b0 >> 19)&0x001f))); - } -} - -/////////////////////////////////////////////////////////////////////// - -static void VertLineShade(int x, int y0, int y1, uint32_t rgb0, uint32_t rgb1) -{ - int y, dy; - uint32_t r0, g0, b0, r1, g1, b1; - int dr, dg, db; - - r0 = (rgb0 & 0x00ff0000); - g0 = (rgb0 & 0x0000ff00) << 8; - b0 = (rgb0 & 0x000000ff) << 16; - r1 = (rgb1 & 0x00ff0000); - g1 = (rgb1 & 0x0000ff00) << 8; - b1 = (rgb1 & 0x000000ff) << 16; - - dy = (y1 - y0); - - if (dy > 0) - { - dr = ((int)r1 - (int)r0) / dy; - dg = ((int)g1 - (int)g0) / dy; - db = ((int)b1 - (int)b0) / dy; - } - else - { - dr = ((int)r1 - (int)r0); - dg = ((int)g1 - (int)g0); - db = ((int)b1 - (int)b0); - } - - if (y0 < drawY) - { - r0+=dr*(drawY - y0); - g0+=dg*(drawY - y0); - b0+=db*(drawY - y0); - y0 = drawY; - } - - if (y1 > drawH) - y1 = drawH; - - for (y = y0; y <= y1; y++) - { - GetShadeTransCol(&psxVuw[(y<<10)+x],(unsigned short)(((r0 >> 9)&0x7c00)|((g0 >> 14)&0x03e0)|((b0 >> 19)&0x001f))); - r0+=dr; - g0+=dg; - b0+=db; - } -} - -/////////////////////////////////////////////////////////////////////// - -static void HorzLineShade(int y, int x0, int x1, uint32_t rgb0, uint32_t rgb1) -{ - int x, dx; - uint32_t r0, g0, b0, r1, g1, b1; - int dr, dg, db; - - r0 = (rgb0 & 0x00ff0000); - g0 = (rgb0 & 0x0000ff00) << 8; - b0 = (rgb0 & 0x000000ff) << 16; - r1 = (rgb1 & 0x00ff0000); - g1 = (rgb1 & 0x0000ff00) << 8; - b1 = (rgb1 & 0x000000ff) << 16; - - dx = (x1 - x0); - - if (dx > 0) - { - dr = ((int)r1 - (int)r0) / dx; - dg = ((int)g1 - (int)g0) / dx; - db = ((int)b1 - (int)b0) / dx; - } - else - { - dr = ((int)r1 - (int)r0); - dg = ((int)g1 - (int)g0); - db = ((int)b1 - (int)b0); - } - - if (x0 < drawX) - { - r0+=dr*(drawX - x0); - g0+=dg*(drawX - x0); - b0+=db*(drawX - x0); - x0 = drawX; - } - - if (x1 > drawW) - x1 = drawW; - - for (x = x0; x <= x1; x++) - { - GetShadeTransCol(&psxVuw[(y<<10)+x],(unsigned short)(((r0 >> 9)&0x7c00)|((g0 >> 14)&0x03e0)|((b0 >> 19)&0x001f))); - r0+=dr; - g0+=dg; - b0+=db; - } -} - -/////////////////////////////////////////////////////////////////////// - -static void Line_E_SE_Flat(int x0, int y0, int x1, int y1, unsigned short colour) -{ - int dx, dy, incrE, incrSE, d, x, y; - - dx = x1 - x0; - dy = y1 - y0; - d = 2*dy - dx; /* Initial value of d */ - incrE = 2*dy; /* incr. used for move to E */ - incrSE = 2*(dy - dx); /* incr. used for move to SE */ - x = x0; - y = y0; - if ((x>=drawX)&&(x<drawW)&&(y>=drawY)&&(y<drawH)) - GetShadeTransCol(&psxVuw[(y<<10)+x], colour); - while(x < x1) - { - if (d <= 0) - { - d = d + incrE; /* Choose E */ - x++; - } - else - { - d = d + incrSE; /* Choose SE */ - x++; - y++; - } - if ((x>=drawX)&&(x<drawW)&&(y>=drawY)&&(y<drawH)) - GetShadeTransCol(&psxVuw[(y<<10)+x], colour); - } -} - -/////////////////////////////////////////////////////////////////////// - -static void Line_S_SE_Flat(int x0, int y0, int x1, int y1, unsigned short colour) -{ - int dx, dy, incrS, incrSE, d, x, y; - - dx = x1 - x0; - dy = y1 - y0; - d = 2*dx - dy; /* Initial value of d */ - incrS = 2*dx; /* incr. used for move to S */ - incrSE = 2*(dx - dy); /* incr. used for move to SE */ - x = x0; - y = y0; - if ((x>=drawX)&&(x<drawW)&&(y>=drawY)&&(y<drawH)) - GetShadeTransCol(&psxVuw[(y<<10)+x], colour); - while(y < y1) - { - if (d <= 0) - { - d = d + incrS; /* Choose S */ - y++; - } - else - { - d = d + incrSE; /* Choose SE */ - x++; - y++; - } - if ((x>=drawX)&&(x<drawW)&&(y>=drawY)&&(y<drawH)) - GetShadeTransCol(&psxVuw[(y<<10)+x], colour); - } -} - -/////////////////////////////////////////////////////////////////////// - -static void Line_N_NE_Flat(int x0, int y0, int x1, int y1, unsigned short colour) -{ - int dx, dy, incrN, incrNE, d, x, y; - - dx = x1 - x0; - dy = -(y1 - y0); - d = 2*dx - dy; /* Initial value of d */ - incrN = 2*dx; /* incr. used for move to N */ - incrNE = 2*(dx - dy); /* incr. used for move to NE */ - x = x0; - y = y0; - if ((x>=drawX)&&(x<drawW)&&(y>=drawY)&&(y<drawH)) - GetShadeTransCol(&psxVuw[(y<<10)+x], colour); - while(y > y1) - { - if (d <= 0) - { - d = d + incrN; /* Choose N */ - y--; - } - else - { - d = d + incrNE; /* Choose NE */ - x++; - y--; - } - if ((x>=drawX)&&(x<drawW)&&(y>=drawY)&&(y<drawH)) - GetShadeTransCol(&psxVuw[(y<<10)+x], colour); - } -} - -/////////////////////////////////////////////////////////////////////// - -static void Line_E_NE_Flat(int x0, int y0, int x1, int y1, unsigned short colour) -{ - int dx, dy, incrE, incrNE, d, x, y; - - dx = x1 - x0; - dy = -(y1 - y0); - d = 2*dy - dx; /* Initial value of d */ - incrE = 2*dy; /* incr. used for move to E */ - incrNE = 2*(dy - dx); /* incr. used for move to NE */ - x = x0; - y = y0; - if ((x>=drawX)&&(x<drawW)&&(y>=drawY)&&(y<drawH)) - GetShadeTransCol(&psxVuw[(y<<10)+x], colour); - while(x < x1) - { - if (d <= 0) - { - d = d + incrE; /* Choose E */ - x++; - } - else - { - d = d + incrNE; /* Choose NE */ - x++; - y--; - } - if ((x>=drawX)&&(x<drawW)&&(y>=drawY)&&(y<drawH)) - GetShadeTransCol(&psxVuw[(y<<10)+x], colour); - } -} - -/////////////////////////////////////////////////////////////////////// - -static void VertLineFlat(int x, int y0, int y1, unsigned short colour) -{ - int y; - - if (y0 < drawY) - y0 = drawY; - - if (y1 > drawH) - y1 = drawH; - - for (y = y0; y <= y1; y++) - GetShadeTransCol(&psxVuw[(y<<10)+x], colour); -} - -/////////////////////////////////////////////////////////////////////// - -static void HorzLineFlat(int y, int x0, int x1, unsigned short colour) -{ - int x; - - if (x0 < drawX) - x0 = drawX; - - if (x1 > drawW) - x1 = drawW; - - for (x = x0; x <= x1; x++) - GetShadeTransCol(&psxVuw[(y<<10)+x], colour); -} - -/////////////////////////////////////////////////////////////////////// - -/* Bresenham Line drawing function */ -static void DrawSoftwareLineShade(int rgb0, int rgb1) -{ - short x0, y0, x1, y1, xt, yt; - int rgbt; - double m, dy, dx; - - if(lx0>drawW && lx1>drawW) return; - if(ly0>drawH && ly1>drawH) return; - if(lx0<drawX && lx1<drawX) return; - if(ly0<drawY && ly1<drawY) return; - if(drawY>=drawH) return; - if(drawX>=drawW) return; - - x0 = lx0; - y0 = ly0; - x1 = lx1; - y1 = ly1; - - dx = x1 - x0; - dy = y1 - y0; - - if (dx == 0) - { - if (dy > 0) - VertLineShade(x0, y0, y1, rgb0, rgb1); - else - VertLineShade(x0, y1, y0, rgb1, rgb0); - } - else - if (dy == 0) - { - if (dx > 0) - HorzLineShade(y0, x0, x1, rgb0, rgb1); - else - HorzLineShade(y0, x1, x0, rgb1, rgb0); - } - else - { - if (dx < 0) - { - xt = x0; - yt = y0; - rgbt = rgb0; - x0 = x1; - y0 = y1; - rgb0 = rgb1; - x1 = xt; - y1 = yt; - rgb1 = rgbt; - - dx = x1 - x0; - dy = y1 - y0; - } - - m = dy/dx; - - if (m >= 0) - { - if (m > 1) - Line_S_SE_Shade(x0, y0, x1, y1, rgb0, rgb1); - else - Line_E_SE_Shade(x0, y0, x1, y1, rgb0, rgb1); - } - else - if (m < -1) - Line_N_NE_Shade(x0, y0, x1, y1, rgb0, rgb1); - else - Line_E_NE_Shade(x0, y0, x1, y1, rgb0, rgb1); - } -} - -/////////////////////////////////////////////////////////////////////// - -static void DrawSoftwareLineFlat(int rgb) -{ - short x0, y0, x1, y1, xt, yt; - double m, dy, dx; - unsigned short colour = 0; - - if(lx0>drawW && lx1>drawW) return; - if(ly0>drawH && ly1>drawH) return; - if(lx0<drawX && lx1<drawX) return; - if(ly0<drawY && ly1<drawY) return; - if(drawY>=drawH) return; - if(drawX>=drawW) return; - - colour = ((rgb & 0x00f80000)>>9) | ((rgb & 0x0000f800)>>6) | ((rgb & 0x000000f8)>>3); - - x0 = lx0; - y0 = ly0; - x1 = lx1; - y1 = ly1; - - dx = x1 - x0; - dy = y1 - y0; - - if (dx == 0) - { - if (dy == 0) - return; // Nothing to draw - else if (dy > 0) - VertLineFlat(x0, y0, y1, colour); - else - VertLineFlat(x0, y1, y0, colour); - } - else - if (dy == 0) - { - if (dx > 0) - HorzLineFlat(y0, x0, x1, colour); - else - HorzLineFlat(y0, x1, x0, colour); - } - else - { - if (dx < 0) - { - xt = x0; - yt = y0; - x0 = x1; - y0 = y1; - x1 = xt; - y1 = yt; - - dx = x1 - x0; - dy = y1 - y0; - } - - m = dy/dx; - - if (m >= 0) - { - if (m > 1) - Line_S_SE_Flat(x0, y0, x1, y1, colour); - else - Line_E_SE_Flat(x0, y0, x1, y1, colour); - } - else - if (m < -1) - Line_N_NE_Flat(x0, y0, x1, y1, colour); - else - Line_E_NE_Flat(x0, y0, x1, y1, colour); - } -} -#endif - -/////////////////////////////////////////////////////////////////////// +/***************************************************************************
+ soft.c - description
+ -------------------
+ begin : Sun Oct 28 2001
+ copyright : (C) 2001 by Pete Bernert
+ web : www.pbernert.com
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. See also the license.txt file for *
+ * additional informations. *
+ * *
+ ***************************************************************************/
+
+#include "stdafx.h"
+
+#define _IN_SOFT
+
+#include "externals.h"
+#include "soft.h"
+
+int iDither = 0;
+
+////////////////////////////////////////////////////////////////////////////////////
+// "NO EDGE BUFFER" POLY VERSION... FUNCS BASED ON FATMAP.TXT FROM MRI / Doomsday
+////////////////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////////////////
+// defines
+////////////////////////////////////////////////////////////////////////////////////
+
+// switches for painting textured quads as 2 triangles (small glitches, but better shading!)
+// can be toggled by game fix 0x200 in version 1.17 anyway, so let the defines enabled!
+
+#define POLYQUAD3
+#define POLYQUAD3GT
+
+// fast solid loops... a bit more additional code, of course
+
+#define FASTSOLID
+
+// psx blending mode 3 with 25% incoming color (instead 50% without the define)
+
+#define HALFBRIGHTMODE3
+
+// color decode defines
+
+#define XCOL1(x) (x & 0x1f)
+#define XCOL2(x) (x & 0x3e0)
+#define XCOL3(x) (x & 0x7c00)
+
+#define XCOL1D(x) (x & 0x1f)
+#define XCOL2D(x) ((x>>5) & 0x1f)
+#define XCOL3D(x) ((x>>10) & 0x1f)
+
+#define X32TCOL1(x) ((x & 0x001f001f)<<7)
+#define X32TCOL2(x) ((x & 0x03e003e0)<<2)
+#define X32TCOL3(x) ((x & 0x7c007c00)>>3)
+
+#define X32COL1(x) (x & 0x001f001f)
+#define X32COL2(x) ((x>>5) & 0x001f001f)
+#define X32COL3(x) ((x>>10) & 0x001f001f)
+
+#define X32ACOL1(x) (x & 0x001e001e)
+#define X32ACOL2(x) ((x>>5) & 0x001e001e)
+#define X32ACOL3(x) ((x>>10) & 0x001e001e)
+
+#define X32BCOL1(x) (x & 0x001c001c)
+#define X32BCOL2(x) ((x>>5) & 0x001c001c)
+#define X32BCOL3(x) ((x>>10) & 0x001c001c)
+
+#define X32PSXCOL(r,g,b) ((g<<10)|(b<<5)|r)
+
+#define XPSXCOL(r,g,b) ((g&0x7c00)|(b&0x3e0)|(r&0x1f))
+
+////////////////////////////////////////////////////////////////////////////////////
+// soft globals
+////////////////////////////////////////////////////////////////////////////////////
+
+short g_m1 = 255, g_m2 = 255, g_m3 = 255;
+short DrawSemiTrans = FALSE;
+short Ymin;
+short Ymax;
+
+short ly0, lx0, ly1, lx1, ly2, lx2, ly3, lx3; // global psx vertex coords
+int GlobalTextAddrX, GlobalTextAddrY, GlobalTextTP;
+int GlobalTextREST, GlobalTextABR, GlobalTextPAGE;
+
+////////////////////////////////////////////////////////////////////////
+// POLYGON OFFSET FUNCS
+////////////////////////////////////////////////////////////////////////
+
+void offsetPSXLine(void)
+{
+ short x0,x1,y0,y1,dx,dy;float px,py;
+
+ x0 = lx0+1+PSXDisplay.DrawOffset.x;
+ x1 = lx1+1+PSXDisplay.DrawOffset.x;
+ y0 = ly0+1+PSXDisplay.DrawOffset.y;
+ y1 = ly1+1+PSXDisplay.DrawOffset.y;
+
+ dx=x1-x0;
+ dy=y1-y0;
+
+ // tricky line width without sqrt
+
+ if(dx>=0)
+ {
+ if(dy>=0)
+ {
+ px=0.5f;
+ if(dx>dy) py=-0.5f;
+ else if(dx<dy) py= 0.5f;
+ else py= 0.0f;
+ }
+ else
+ {
+ py=-0.5f;
+ dy=-dy;
+ if(dx>dy) px= 0.5f;
+ else if(dx<dy) px=-0.5f;
+ else px= 0.0f;
+ }
+ }
+ else
+ {
+ if(dy>=0)
+ {
+ py=0.5f;
+ dx=-dx;
+ if(dx>dy) px=-0.5f;
+ else if(dx<dy) px= 0.5f;
+ else px= 0.0f;
+ }
+ else
+ {
+ px=-0.5f;
+ if(dx>dy) py=-0.5f;
+ else if(dx<dy) py= 0.5f;
+ else py= 0.0f;
+ }
+ }
+
+ lx0=(short)((float)x0-px);
+ lx3=(short)((float)x0+py);
+
+ ly0=(short)((float)y0-py);
+ ly3=(short)((float)y0-px);
+
+ lx1=(short)((float)x1-py);
+ lx2=(short)((float)x1+px);
+
+ ly1=(short)((float)y1+px);
+ ly2=(short)((float)y1+py);
+}
+
+void offsetPSX2(void)
+{
+ lx0 += PSXDisplay.DrawOffset.x;
+ ly0 += PSXDisplay.DrawOffset.y;
+ lx1 += PSXDisplay.DrawOffset.x;
+ ly1 += PSXDisplay.DrawOffset.y;
+}
+
+void offsetPSX3(void)
+{
+ lx0 += PSXDisplay.DrawOffset.x;
+ ly0 += PSXDisplay.DrawOffset.y;
+ lx1 += PSXDisplay.DrawOffset.x;
+ ly1 += PSXDisplay.DrawOffset.y;
+ lx2 += PSXDisplay.DrawOffset.x;
+ ly2 += PSXDisplay.DrawOffset.y;
+}
+
+void offsetPSX4(void)
+{
+ lx0 += PSXDisplay.DrawOffset.x;
+ ly0 += PSXDisplay.DrawOffset.y;
+ lx1 += PSXDisplay.DrawOffset.x;
+ ly1 += PSXDisplay.DrawOffset.y;
+ lx2 += PSXDisplay.DrawOffset.x;
+ ly2 += PSXDisplay.DrawOffset.y;
+ lx3 += PSXDisplay.DrawOffset.x;
+ ly3 += PSXDisplay.DrawOffset.y;
+}
+
+/////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////
+// PER PIXEL FUNCS
+////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////
+
+
+unsigned char dithertable[16] =
+{
+ 7, 0, 6, 1,
+ 2, 5, 3, 4,
+ 1, 6, 0, 7,
+ 4, 3, 5, 2
+};
+
+void Dither16(unsigned short *pdest, uint32_t r, uint32_t g, uint32_t b, unsigned short sM)
+{
+ unsigned char coeff;
+ unsigned char rlow, glow, blow;
+ int x, y;
+
+ x = pdest - psxVuw;
+ y = x >> 10;
+ x -= (y << 10);
+
+ coeff = dithertable[(y&3)*4+(x&3)];
+
+ rlow = r&7; glow = g&7; blow = b&7;
+
+ r>>=3; g>>=3; b>>=3;
+
+ if ((r < 0x1F) && rlow > coeff) r++;
+ if ((g < 0x1F) && glow > coeff) g++;
+ if ((b < 0x1F) && blow > coeff) b++;
+
+ *pdest=((unsigned short)b<<10) |
+ ((unsigned short)g<<5) |
+ (unsigned short)r | sM;
+}
+
+/////////////////////////////////////////////////////////////////
+
+__inline void GetShadeTransCol_Dither(unsigned short *pdest, int m1, int m2, int m3)
+{
+ int r,g,b;
+
+ if (bCheckMask && *pdest & 0x8000) return;
+
+ if (DrawSemiTrans)
+ {
+ r=((XCOL1D(*pdest))<<3);
+ b=((XCOL2D(*pdest))<<3);
+ g=((XCOL3D(*pdest))<<3);
+
+ if(GlobalTextABR==0)
+ {
+ r=(r>>1)+(m1>>1);
+ b=(b>>1)+(m2>>1);
+ g=(g>>1)+(m3>>1);
+ }
+ else
+ if(GlobalTextABR==1)
+ {
+ r+=m1;
+ b+=m2;
+ g+=m3;
+ }
+ else
+ if(GlobalTextABR==2)
+ {
+ r-=m1;
+ b-=m2;
+ g-=m3;
+ if(r&0x80000000) r=0;
+ if(b&0x80000000) b=0;
+ if(g&0x80000000) g=0;
+ }
+ else
+ {
+#ifdef HALFBRIGHTMODE3
+ r+=(m1>>2);
+ b+=(m2>>2);
+ g+=(m3>>2);
+#else
+ r+=(m1>>1);
+ b+=(m2>>1);
+ g+=(m3>>1);
+#endif
+ }
+ }
+ else
+ {
+ r=m1;
+ b=m2;
+ g=m3;
+ }
+
+ if(r&0x7FFFFF00) r=0xff;
+ if(b&0x7FFFFF00) b=0xff;
+ if(g&0x7FFFFF00) g=0xff;
+
+ Dither16(pdest,r,b,g,sSetMask);
+}
+
+////////////////////////////////////////////////////////////////////////
+
+__inline void GetShadeTransCol(unsigned short * pdest,unsigned short color)
+{
+ if(bCheckMask && *pdest&0x8000) return;
+
+ if(DrawSemiTrans)
+ {
+ int r,g,b;
+
+ if(GlobalTextABR==0)
+ {
+ *pdest=((((*pdest)&0x7bde)>>1)+(((color)&0x7bde)>>1))|sSetMask;//0x8000;
+ return;
+/*
+ r=(XCOL1(*pdest)>>1)+((XCOL1(color))>>1);
+ b=(XCOL2(*pdest)>>1)+((XCOL2(color))>>1);
+ g=(XCOL3(*pdest)>>1)+((XCOL3(color))>>1);
+*/
+ }
+ else
+ if(GlobalTextABR==1)
+ {
+ r=(XCOL1(*pdest))+((XCOL1(color)));
+ b=(XCOL2(*pdest))+((XCOL2(color)));
+ g=(XCOL3(*pdest))+((XCOL3(color)));
+ }
+ else
+ if(GlobalTextABR==2)
+ {
+ r=(XCOL1(*pdest))-((XCOL1(color)));
+ b=(XCOL2(*pdest))-((XCOL2(color)));
+ g=(XCOL3(*pdest))-((XCOL3(color)));
+ if(r&0x80000000) r=0;
+ if(b&0x80000000) b=0;
+ if(g&0x80000000) g=0;
+ }
+ else
+ {
+#ifdef HALFBRIGHTMODE3
+ r=(XCOL1(*pdest))+((XCOL1(color))>>2);
+ b=(XCOL2(*pdest))+((XCOL2(color))>>2);
+ g=(XCOL3(*pdest))+((XCOL3(color))>>2);
+#else
+ r=(XCOL1(*pdest))+((XCOL1(color))>>1);
+ b=(XCOL2(*pdest))+((XCOL2(color))>>1);
+ g=(XCOL3(*pdest))+((XCOL3(color))>>1);
+#endif
+ }
+
+ if(r&0x7FFFFFE0) r=0x1f;
+ if(b&0x7FFFFC00) b=0x3e0;
+ if(g&0x7FFF8000) g=0x7c00;
+
+ *pdest=(XPSXCOL(r,g,b))|sSetMask;//0x8000;
+ }
+ else *pdest=color|sSetMask;
+}
+
+////////////////////////////////////////////////////////////////////////
+
+__inline void GetShadeTransCol32(uint32_t *pdest, uint32_t color)
+{
+ if (DrawSemiTrans)
+ {
+ int r,g,b;
+
+ if(GlobalTextABR==0)
+ {
+ if(!bCheckMask)
+ {
+ *pdest=((((*pdest)&0x7bde7bde)>>1)+(((color)&0x7bde7bde)>>1))|lSetMask;//0x80008000;
+ return;
+ }
+ r=(X32ACOL1(*pdest)>>1)+((X32ACOL1(color))>>1);
+ b=(X32ACOL2(*pdest)>>1)+((X32ACOL2(color))>>1);
+ g=(X32ACOL3(*pdest)>>1)+((X32ACOL3(color))>>1);
+ }
+ else
+ if(GlobalTextABR==1)
+ {
+ r=(X32COL1(*pdest))+((X32COL1(color)));
+ b=(X32COL2(*pdest))+((X32COL2(color)));
+ g=(X32COL3(*pdest))+((X32COL3(color)));
+ }
+ else
+ if(GlobalTextABR==2)
+ {
+ int sr,sb,sg,src,sbc,sgc,c;
+ src=XCOL1(color);sbc=XCOL2(color);sgc=XCOL3(color);
+ c=(*pdest)>>16;
+ sr=(XCOL1(c))-src; if(sr&0x8000) sr=0;
+ sb=(XCOL2(c))-sbc; if(sb&0x8000) sb=0;
+ sg=(XCOL3(c))-sgc; if(sg&0x8000) sg=0;
+ r=((int)sr)<<16;b=((int)sb)<<11;g=((int)sg)<<6;
+ c=LOWORD(*pdest);
+ sr=(XCOL1(c))-src; if(sr&0x8000) sr=0;
+ sb=(XCOL2(c))-sbc; if(sb&0x8000) sb=0;
+ sg=(XCOL3(c))-sgc; if(sg&0x8000) sg=0;
+ r|=sr;b|=sb>>5;g|=sg>>10;
+ }
+ else
+ {
+#ifdef HALFBRIGHTMODE3
+ r=(X32COL1(*pdest))+((X32BCOL1(color))>>2);
+ b=(X32COL2(*pdest))+((X32BCOL2(color))>>2);
+ g=(X32COL3(*pdest))+((X32BCOL3(color))>>2);
+#else
+ r=(X32COL1(*pdest))+((X32ACOL1(color))>>1);
+ b=(X32COL2(*pdest))+((X32ACOL2(color))>>1);
+ g=(X32COL3(*pdest))+((X32ACOL3(color))>>1);
+#endif
+ }
+
+ if(r&0x7FE00000) r=0x1f0000|(r&0xFFFF);
+ if(r&0x7FE0) r=0x1f |(r&0xFFFF0000);
+ if(b&0x7FE00000) b=0x1f0000|(b&0xFFFF);
+ if(b&0x7FE0) b=0x1f |(b&0xFFFF0000);
+ if(g&0x7FE00000) g=0x1f0000|(g&0xFFFF);
+ if(g&0x7FE0) g=0x1f |(g&0xFFFF0000);
+
+ if(bCheckMask)
+ {
+ uint32_t ma=*pdest;
+ *pdest=(X32PSXCOL(r,g,b))|lSetMask;//0x80008000;
+ if(ma&0x80000000) *pdest=(ma&0xFFFF0000)|(*pdest&0xFFFF);
+ if(ma&0x00008000) *pdest=(ma&0xFFFF) |(*pdest&0xFFFF0000);
+ return;
+ }
+ *pdest=(X32PSXCOL(r,g,b))|lSetMask;//0x80008000;
+ }
+ else
+ {
+ if(bCheckMask)
+ {
+ uint32_t ma=*pdest;
+ *pdest=color|lSetMask;//0x80008000;
+ if(ma&0x80000000) *pdest=(ma&0xFFFF0000)|(*pdest&0xFFFF);
+ if(ma&0x00008000) *pdest=(ma&0xFFFF) |(*pdest&0xFFFF0000);
+ return;
+ }
+
+ *pdest=color|lSetMask;//0x80008000;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+__inline void GetTextureTransColG(unsigned short * pdest,unsigned short color)
+{
+ int r,g,b;unsigned short l;
+
+ if(color==0) return;
+
+ if(bCheckMask && *pdest&0x8000) return;
+
+ l=sSetMask|(color&0x8000);
+
+ if(DrawSemiTrans && (color&0x8000))
+ {
+ if(GlobalTextABR==0)
+ {
+ unsigned short d;
+ d =((*pdest)&0x7bde)>>1;
+ color =((color) &0x7bde)>>1;
+ r=(XCOL1(d))+((((XCOL1(color)))* g_m1)>>7);
+ b=(XCOL2(d))+((((XCOL2(color)))* g_m2)>>7);
+ g=(XCOL3(d))+((((XCOL3(color)))* g_m3)>>7);
+
+/*
+ r=(XCOL1(*pdest)>>1)+((((XCOL1(color))>>1)* g_m1)>>7);
+ b=(XCOL2(*pdest)>>1)+((((XCOL2(color))>>1)* g_m2)>>7);
+ g=(XCOL3(*pdest)>>1)+((((XCOL3(color))>>1)* g_m3)>>7);
+*/
+ }
+ else
+ if(GlobalTextABR==1)
+ {
+ r=(XCOL1(*pdest))+((((XCOL1(color)))* g_m1)>>7);
+ b=(XCOL2(*pdest))+((((XCOL2(color)))* g_m2)>>7);
+ g=(XCOL3(*pdest))+((((XCOL3(color)))* g_m3)>>7);
+ }
+ else
+ if(GlobalTextABR==2)
+ {
+ r=(XCOL1(*pdest))-((((XCOL1(color)))* g_m1)>>7);
+ b=(XCOL2(*pdest))-((((XCOL2(color)))* g_m2)>>7);
+ g=(XCOL3(*pdest))-((((XCOL3(color)))* g_m3)>>7);
+ if(r&0x80000000) r=0;
+ if(b&0x80000000) b=0;
+ if(g&0x80000000) g=0;
+ }
+ else
+ {
+#ifdef HALFBRIGHTMODE3
+ r=(XCOL1(*pdest))+((((XCOL1(color))>>2)* g_m1)>>7);
+ b=(XCOL2(*pdest))+((((XCOL2(color))>>2)* g_m2)>>7);
+ g=(XCOL3(*pdest))+((((XCOL3(color))>>2)* g_m3)>>7);
+#else
+ r=(XCOL1(*pdest))+((((XCOL1(color))>>1)* g_m1)>>7);
+ b=(XCOL2(*pdest))+((((XCOL2(color))>>1)* g_m2)>>7);
+ g=(XCOL3(*pdest))+((((XCOL3(color))>>1)* g_m3)>>7);
+#endif
+ }
+ }
+ else
+ {
+ r=((XCOL1(color))* g_m1)>>7;
+ b=((XCOL2(color))* g_m2)>>7;
+ g=((XCOL3(color))* g_m3)>>7;
+ }
+
+ if(r&0x7FFFFFE0) r=0x1f;
+ if(b&0x7FFFFC00) b=0x3e0;
+ if(g&0x7FFF8000) g=0x7c00;
+
+ *pdest=(XPSXCOL(r,g,b))|l;
+}
+
+////////////////////////////////////////////////////////////////////////
+
+__inline void GetTextureTransColG_S(unsigned short * pdest,unsigned short color)
+{
+ int r,g,b;unsigned short l;
+
+ if(color==0) return;
+
+ l=sSetMask|(color&0x8000);
+
+ r=((XCOL1(color))* g_m1)>>7;
+ b=((XCOL2(color))* g_m2)>>7;
+ g=((XCOL3(color))* g_m3)>>7;
+
+ if(r&0x7FFFFFE0) r=0x1f;
+ if(b&0x7FFFFC00) b=0x3e0;
+ if(g&0x7FFF8000) g=0x7c00;
+
+ *pdest=(XPSXCOL(r,g,b))|l;
+}
+
+
+////////////////////////////////////////////////////////////////////////
+
+__inline void GetTextureTransColG_SPR(unsigned short * pdest,unsigned short color)
+{
+ int r,g,b;unsigned short l;
+
+ if(color==0) return;
+
+ if(bCheckMask && *pdest&0x8000) return;
+
+ l=sSetMask|(color&0x8000);
+
+ if(DrawSemiTrans && (color&0x8000))
+ {
+ if(GlobalTextABR==0)
+ {
+ unsigned short d;
+ d =((*pdest)&0x7bde)>>1;
+ color =((color) &0x7bde)>>1;
+ r=(XCOL1(d))+((((XCOL1(color)))* g_m1)>>7);
+ b=(XCOL2(d))+((((XCOL2(color)))* g_m2)>>7);
+ g=(XCOL3(d))+((((XCOL3(color)))* g_m3)>>7);
+
+/*
+ r=(XCOL1(*pdest)>>1)+((((XCOL1(color))>>1)* g_m1)>>7);
+ b=(XCOL2(*pdest)>>1)+((((XCOL2(color))>>1)* g_m2)>>7);
+ g=(XCOL3(*pdest)>>1)+((((XCOL3(color))>>1)* g_m3)>>7);
+*/
+ }
+ else
+ if(GlobalTextABR==1)
+ {
+ r=(XCOL1(*pdest))+((((XCOL1(color)))* g_m1)>>7);
+ b=(XCOL2(*pdest))+((((XCOL2(color)))* g_m2)>>7);
+ g=(XCOL3(*pdest))+((((XCOL3(color)))* g_m3)>>7);
+ }
+ else
+ if(GlobalTextABR==2)
+ {
+ r=(XCOL1(*pdest))-((((XCOL1(color)))* g_m1)>>7);
+ b=(XCOL2(*pdest))-((((XCOL2(color)))* g_m2)>>7);
+ g=(XCOL3(*pdest))-((((XCOL3(color)))* g_m3)>>7);
+ if(r&0x80000000) r=0;
+ if(b&0x80000000) b=0;
+ if(g&0x80000000) g=0;
+ }
+ else
+ {
+#ifdef HALFBRIGHTMODE3
+ r=(XCOL1(*pdest))+((((XCOL1(color))>>2)* g_m1)>>7);
+ b=(XCOL2(*pdest))+((((XCOL2(color))>>2)* g_m2)>>7);
+ g=(XCOL3(*pdest))+((((XCOL3(color))>>2)* g_m3)>>7);
+#else
+ r=(XCOL1(*pdest))+((((XCOL1(color))>>1)* g_m1)>>7);
+ b=(XCOL2(*pdest))+((((XCOL2(color))>>1)* g_m2)>>7);
+ g=(XCOL3(*pdest))+((((XCOL3(color))>>1)* g_m3)>>7);
+#endif
+ }
+ }
+ else
+ {
+ r=((XCOL1(color))* g_m1)>>7;
+ b=((XCOL2(color))* g_m2)>>7;
+ g=((XCOL3(color))* g_m3)>>7;
+ }
+
+ if(r&0x7FFFFFE0) r=0x1f;
+ if(b&0x7FFFFC00) b=0x3e0;
+ if(g&0x7FFF8000) g=0x7c00;
+
+ *pdest=(XPSXCOL(r,g,b))|l;
+}
+
+////////////////////////////////////////////////////////////////////////
+
+__inline void GetTextureTransColG32(uint32_t *pdest, uint32_t color)
+{
+ int r,g,b,l;
+
+ if(color==0) return;
+
+ l=lSetMask|(color&0x80008000);
+
+ if(DrawSemiTrans && (color&0x80008000))
+ {
+ if(GlobalTextABR==0)
+ {
+ r=((((X32TCOL1(*pdest))+((X32COL1(color)) * g_m1))&0xFF00FF00)>>8);
+ b=((((X32TCOL2(*pdest))+((X32COL2(color)) * g_m2))&0xFF00FF00)>>8);
+ g=((((X32TCOL3(*pdest))+((X32COL3(color)) * g_m3))&0xFF00FF00)>>8);
+ }
+ else
+ if(GlobalTextABR==1)
+ {
+ r=(X32COL1(*pdest))+(((((X32COL1(color)))* g_m1)&0xFF80FF80)>>7);
+ b=(X32COL2(*pdest))+(((((X32COL2(color)))* g_m2)&0xFF80FF80)>>7);
+ g=(X32COL3(*pdest))+(((((X32COL3(color)))* g_m3)&0xFF80FF80)>>7);
+ }
+ else
+ if(GlobalTextABR==2)
+ {
+ int t;
+ r=(((((X32COL1(color)))* g_m1)&0xFF80FF80)>>7);
+ t=(*pdest&0x001f0000)-(r&0x003f0000); if(t&0x80000000) t=0;
+ r=(*pdest&0x0000001f)-(r&0x0000003f); if(r&0x80000000) r=0;
+ r|=t;
+
+ b=(((((X32COL2(color)))* g_m2)&0xFF80FF80)>>7);
+ t=((*pdest>>5)&0x001f0000)-(b&0x003f0000); if(t&0x80000000) t=0;
+ b=((*pdest>>5)&0x0000001f)-(b&0x0000003f); if(b&0x80000000) b=0;
+ b|=t;
+
+ g=(((((X32COL3(color)))* g_m3)&0xFF80FF80)>>7);
+ t=((*pdest>>10)&0x001f0000)-(g&0x003f0000); if(t&0x80000000) t=0;
+ g=((*pdest>>10)&0x0000001f)-(g&0x0000003f); if(g&0x80000000) g=0;
+ g|=t;
+ }
+ else
+ {
+#ifdef HALFBRIGHTMODE3
+ r=(X32COL1(*pdest))+(((((X32BCOL1(color))>>2)* g_m1)&0xFF80FF80)>>7);
+ b=(X32COL2(*pdest))+(((((X32BCOL2(color))>>2)* g_m2)&0xFF80FF80)>>7);
+ g=(X32COL3(*pdest))+(((((X32BCOL3(color))>>2)* g_m3)&0xFF80FF80)>>7);
+#else
+ r=(X32COL1(*pdest))+(((((X32ACOL1(color))>>1)* g_m1)&0xFF80FF80)>>7);
+ b=(X32COL2(*pdest))+(((((X32ACOL2(color))>>1)* g_m2)&0xFF80FF80)>>7);
+ g=(X32COL3(*pdest))+(((((X32ACOL3(color))>>1)* g_m3)&0xFF80FF80)>>7);
+#endif
+ }
+
+ if(!(color&0x8000))
+ {
+ r=(r&0xffff0000)|((((X32COL1(color))* g_m1)&0x0000FF80)>>7);
+ b=(b&0xffff0000)|((((X32COL2(color))* g_m2)&0x0000FF80)>>7);
+ g=(g&0xffff0000)|((((X32COL3(color))* g_m3)&0x0000FF80)>>7);
+ }
+ if(!(color&0x80000000))
+ {
+ r=(r&0xffff)|((((X32COL1(color))* g_m1)&0xFF800000)>>7);
+ b=(b&0xffff)|((((X32COL2(color))* g_m2)&0xFF800000)>>7);
+ g=(g&0xffff)|((((X32COL3(color))* g_m3)&0xFF800000)>>7);
+ }
+
+ }
+ else
+ {
+ r=(((X32COL1(color))* g_m1)&0xFF80FF80)>>7;
+ b=(((X32COL2(color))* g_m2)&0xFF80FF80)>>7;
+ g=(((X32COL3(color))* g_m3)&0xFF80FF80)>>7;
+ }
+
+ if(r&0x7FE00000) r=0x1f0000|(r&0xFFFF);
+ if(r&0x7FE0) r=0x1f |(r&0xFFFF0000);
+ if(b&0x7FE00000) b=0x1f0000|(b&0xFFFF);
+ if(b&0x7FE0) b=0x1f |(b&0xFFFF0000);
+ if(g&0x7FE00000) g=0x1f0000|(g&0xFFFF);
+ if(g&0x7FE0) g=0x1f |(g&0xFFFF0000);
+
+ if(bCheckMask)
+ {
+ uint32_t ma=*pdest;
+
+ *pdest=(X32PSXCOL(r,g,b))|l;
+
+ if((color&0xffff)==0 ) *pdest=(ma&0xffff)|(*pdest&0xffff0000);
+ if((color&0xffff0000)==0) *pdest=(ma&0xffff0000)|(*pdest&0xffff);
+ if(ma&0x80000000) *pdest=(ma&0xFFFF0000)|(*pdest&0xFFFF);
+ if(ma&0x00008000) *pdest=(ma&0xFFFF) |(*pdest&0xFFFF0000);
+
+ return;
+ }
+ if((color&0xffff)==0 ) {*pdest=(*pdest&0xffff)|(((X32PSXCOL(r,g,b))|l)&0xffff0000);return;}
+ if((color&0xffff0000)==0) {*pdest=(*pdest&0xffff0000)|(((X32PSXCOL(r,g,b))|l)&0xffff);return;}
+
+ *pdest=(X32PSXCOL(r,g,b))|l;
+}
+
+////////////////////////////////////////////////////////////////////////
+
+__inline void GetTextureTransColG32_S(uint32_t *pdest, uint32_t color)
+{
+ int r,g,b;
+
+ if(color==0) return;
+
+ r=(((X32COL1(color))* g_m1)&0xFF80FF80)>>7;
+ b=(((X32COL2(color))* g_m2)&0xFF80FF80)>>7;
+ g=(((X32COL3(color))* g_m3)&0xFF80FF80)>>7;
+
+ if(r&0x7FE00000) r=0x1f0000|(r&0xFFFF);
+ if(r&0x7FE0) r=0x1f |(r&0xFFFF0000);
+ if(b&0x7FE00000) b=0x1f0000|(b&0xFFFF);
+ if(b&0x7FE0) b=0x1f |(b&0xFFFF0000);
+ if(g&0x7FE00000) g=0x1f0000|(g&0xFFFF);
+ if(g&0x7FE0) g=0x1f |(g&0xFFFF0000);
+
+ if((color&0xffff)==0) {*pdest=(*pdest&0xffff)|(((X32PSXCOL(r,g,b))|lSetMask|(color&0x80008000))&0xffff0000);return;}
+ if((color&0xffff0000)==0) {*pdest=(*pdest&0xffff0000)|(((X32PSXCOL(r,g,b))|lSetMask|(color&0x80008000))&0xffff);return;}
+
+ *pdest=(X32PSXCOL(r,g,b))|lSetMask|(color&0x80008000);
+}
+
+////////////////////////////////////////////////////////////////////////
+
+__inline void GetTextureTransColG32_SPR(uint32_t *pdest, uint32_t color)
+{
+ int r,g,b;
+
+ if(color==0) return;
+
+ if(DrawSemiTrans && (color&0x80008000))
+ {
+ if(GlobalTextABR==0)
+ {
+ r=((((X32TCOL1(*pdest))+((X32COL1(color)) * g_m1))&0xFF00FF00)>>8);
+ b=((((X32TCOL2(*pdest))+((X32COL2(color)) * g_m2))&0xFF00FF00)>>8);
+ g=((((X32TCOL3(*pdest))+((X32COL3(color)) * g_m3))&0xFF00FF00)>>8);
+ }
+ else
+ if(GlobalTextABR==1)
+ {
+ r=(X32COL1(*pdest))+(((((X32COL1(color)))* g_m1)&0xFF80FF80)>>7);
+ b=(X32COL2(*pdest))+(((((X32COL2(color)))* g_m2)&0xFF80FF80)>>7);
+ g=(X32COL3(*pdest))+(((((X32COL3(color)))* g_m3)&0xFF80FF80)>>7);
+ }
+ else
+ if(GlobalTextABR==2)
+ {
+ int t;
+ r=(((((X32COL1(color)))* g_m1)&0xFF80FF80)>>7);
+ t=(*pdest&0x001f0000)-(r&0x003f0000); if(t&0x80000000) t=0;
+ r=(*pdest&0x0000001f)-(r&0x0000003f); if(r&0x80000000) r=0;
+ r|=t;
+
+ b=(((((X32COL2(color)))* g_m2)&0xFF80FF80)>>7);
+ t=((*pdest>>5)&0x001f0000)-(b&0x003f0000); if(t&0x80000000) t=0;
+ b=((*pdest>>5)&0x0000001f)-(b&0x0000003f); if(b&0x80000000) b=0;
+ b|=t;
+
+ g=(((((X32COL3(color)))* g_m3)&0xFF80FF80)>>7);
+ t=((*pdest>>10)&0x001f0000)-(g&0x003f0000); if(t&0x80000000) t=0;
+ g=((*pdest>>10)&0x0000001f)-(g&0x0000003f); if(g&0x80000000) g=0;
+ g|=t;
+ }
+ else
+ {
+#ifdef HALFBRIGHTMODE3
+ r=(X32COL1(*pdest))+(((((X32BCOL1(color))>>2)* g_m1)&0xFF80FF80)>>7);
+ b=(X32COL2(*pdest))+(((((X32BCOL2(color))>>2)* g_m2)&0xFF80FF80)>>7);
+ g=(X32COL3(*pdest))+(((((X32BCOL3(color))>>2)* g_m3)&0xFF80FF80)>>7);
+#else
+ r=(X32COL1(*pdest))+(((((X32ACOL1(color))>>1)* g_m1)&0xFF80FF80)>>7);
+ b=(X32COL2(*pdest))+(((((X32ACOL2(color))>>1)* g_m2)&0xFF80FF80)>>7);
+ g=(X32COL3(*pdest))+(((((X32ACOL3(color))>>1)* g_m3)&0xFF80FF80)>>7);
+#endif
+ }
+
+ if(!(color&0x8000))
+ {
+ r=(r&0xffff0000)|((((X32COL1(color))* g_m1)&0x0000FF80)>>7);
+ b=(b&0xffff0000)|((((X32COL2(color))* g_m2)&0x0000FF80)>>7);
+ g=(g&0xffff0000)|((((X32COL3(color))* g_m3)&0x0000FF80)>>7);
+ }
+ if(!(color&0x80000000))
+ {
+ r=(r&0xffff)|((((X32COL1(color))* g_m1)&0xFF800000)>>7);
+ b=(b&0xffff)|((((X32COL2(color))* g_m2)&0xFF800000)>>7);
+ g=(g&0xffff)|((((X32COL3(color))* g_m3)&0xFF800000)>>7);
+ }
+
+ }
+ else
+ {
+ r=(((X32COL1(color))* g_m1)&0xFF80FF80)>>7;
+ b=(((X32COL2(color))* g_m2)&0xFF80FF80)>>7;
+ g=(((X32COL3(color))* g_m3)&0xFF80FF80)>>7;
+ }
+
+ if(r&0x7FE00000) r=0x1f0000|(r&0xFFFF);
+ if(r&0x7FE0) r=0x1f |(r&0xFFFF0000);
+ if(b&0x7FE00000) b=0x1f0000|(b&0xFFFF);
+ if(b&0x7FE0) b=0x1f |(b&0xFFFF0000);
+ if(g&0x7FE00000) g=0x1f0000|(g&0xFFFF);
+ if(g&0x7FE0) g=0x1f |(g&0xFFFF0000);
+
+ if(bCheckMask)
+ {
+ uint32_t ma=*pdest;
+
+ *pdest=(X32PSXCOL(r,g,b))|lSetMask|(color&0x80008000);
+
+ if((color&0xffff)==0 ) *pdest=(ma&0xffff)|(*pdest&0xffff0000);
+ if((color&0xffff0000)==0) *pdest=(ma&0xffff0000)|(*pdest&0xffff);
+ if(ma&0x80000000) *pdest=(ma&0xFFFF0000)|(*pdest&0xFFFF);
+ if(ma&0x00008000) *pdest=(ma&0xFFFF) |(*pdest&0xFFFF0000);
+
+ return;
+ }
+ if((color&0xffff)==0 ) {*pdest=(*pdest&0xffff)|(((X32PSXCOL(r,g,b))|lSetMask|(color&0x80008000))&0xffff0000);return;}
+ if((color&0xffff0000)==0) {*pdest=(*pdest&0xffff0000)|(((X32PSXCOL(r,g,b))|lSetMask|(color&0x80008000))&0xffff);return;}
+
+ *pdest=(X32PSXCOL(r,g,b))|lSetMask|(color&0x80008000);
+}
+
+////////////////////////////////////////////////////////////////////////
+
+__inline void GetTextureTransColGX_Dither(unsigned short * pdest, unsigned short color, int m1, int m2, int m3)
+{
+ int r,g,b;
+
+ if(color==0) return;
+
+ if(bCheckMask && *pdest&0x8000) return;
+
+ m1=(((XCOL1D(color)))*m1)>>4;
+ m2=(((XCOL2D(color)))*m2)>>4;
+ m3=(((XCOL3D(color)))*m3)>>4;
+
+ if(DrawSemiTrans && (color&0x8000))
+ {
+ r=((XCOL1D(*pdest))<<3);
+ b=((XCOL2D(*pdest))<<3);
+ g=((XCOL3D(*pdest))<<3);
+
+ if(GlobalTextABR==0)
+ {
+ r=(r>>1)+(m1>>1);
+ b=(b>>1)+(m2>>1);
+ g=(g>>1)+(m3>>1);
+ }
+ else
+ if(GlobalTextABR==1)
+ {
+ r+=m1;
+ b+=m2;
+ g+=m3;
+ }
+ else
+ if(GlobalTextABR==2)
+ {
+ r-=m1;
+ b-=m2;
+ g-=m3;
+ if(r&0x80000000) r=0;
+ if(b&0x80000000) b=0;
+ if(g&0x80000000) g=0;
+ }
+ else
+ {
+#ifdef HALFBRIGHTMODE3
+ r+=(m1>>2);
+ b+=(m2>>2);
+ g+=(m3>>2);
+#else
+ r+=(m1>>1);
+ b+=(m2>>1);
+ g+=(m3>>1);
+#endif
+ }
+ }
+ else
+ {
+ r=m1;
+ b=m2;
+ g=m3;
+ }
+
+ if(r&0x7FFFFF00) r=0xff;
+ if(b&0x7FFFFF00) b=0xff;
+ if(g&0x7FFFFF00) g=0xff;
+
+ Dither16(pdest,r,b,g,sSetMask|(color&0x8000));
+
+}
+
+////////////////////////////////////////////////////////////////////////
+
+__inline void GetTextureTransColGX(unsigned short * pdest,unsigned short color,short m1,short m2,short m3)
+{
+ int r,g,b;unsigned short l;
+
+ if(color==0) return;
+
+ if(bCheckMask && *pdest&0x8000) return;
+
+ l=sSetMask|(color&0x8000);
+
+ if(DrawSemiTrans && (color&0x8000))
+ {
+ if(GlobalTextABR==0)
+ {
+ unsigned short d;
+ d =((*pdest)&0x7bde)>>1;
+ color =((color) &0x7bde)>>1;
+ r=(XCOL1(d))+((((XCOL1(color)))* m1)>>7);
+ b=(XCOL2(d))+((((XCOL2(color)))* m2)>>7);
+ g=(XCOL3(d))+((((XCOL3(color)))* m3)>>7);
+/*
+ r=(XCOL1(*pdest)>>1)+((((XCOL1(color))>>1)* m1)>>7);
+ b=(XCOL2(*pdest)>>1)+((((XCOL2(color))>>1)* m2)>>7);
+ g=(XCOL3(*pdest)>>1)+((((XCOL3(color))>>1)* m3)>>7);
+*/
+ }
+ else
+ if(GlobalTextABR==1)
+ {
+ r=(XCOL1(*pdest))+((((XCOL1(color)))* m1)>>7);
+ b=(XCOL2(*pdest))+((((XCOL2(color)))* m2)>>7);
+ g=(XCOL3(*pdest))+((((XCOL3(color)))* m3)>>7);
+ }
+ else
+ if(GlobalTextABR==2)
+ {
+ r=(XCOL1(*pdest))-((((XCOL1(color)))* m1)>>7);
+ b=(XCOL2(*pdest))-((((XCOL2(color)))* m2)>>7);
+ g=(XCOL3(*pdest))-((((XCOL3(color)))* m3)>>7);
+ if(r&0x80000000) r=0;
+ if(b&0x80000000) b=0;
+ if(g&0x80000000) g=0;
+ }
+ else
+ {
+#ifdef HALFBRIGHTMODE3
+ r=(XCOL1(*pdest))+((((XCOL1(color))>>2)* m1)>>7);
+ b=(XCOL2(*pdest))+((((XCOL2(color))>>2)* m2)>>7);
+ g=(XCOL3(*pdest))+((((XCOL3(color))>>2)* m3)>>7);
+#else
+ r=(XCOL1(*pdest))+((((XCOL1(color))>>1)* m1)>>7);
+ b=(XCOL2(*pdest))+((((XCOL2(color))>>1)* m2)>>7);
+ g=(XCOL3(*pdest))+((((XCOL3(color))>>1)* m3)>>7);
+#endif
+ }
+ }
+ else
+ {
+ r=((XCOL1(color))* m1)>>7;
+ b=((XCOL2(color))* m2)>>7;
+ g=((XCOL3(color))* m3)>>7;
+ }
+
+ if(r&0x7FFFFFE0) r=0x1f;
+ if(b&0x7FFFFC00) b=0x3e0;
+ if(g&0x7FFF8000) g=0x7c00;
+
+ *pdest=(XPSXCOL(r,g,b))|l;
+}
+
+////////////////////////////////////////////////////////////////////////
+
+__inline void GetTextureTransColGX_S(unsigned short * pdest,unsigned short color,short m1,short m2,short m3)
+{
+ int r,g,b;
+
+ if(color==0) return;
+
+ r=((XCOL1(color))* m1)>>7;
+ b=((XCOL2(color))* m2)>>7;
+ g=((XCOL3(color))* m3)>>7;
+
+ if(r&0x7FFFFFE0) r=0x1f;
+ if(b&0x7FFFFC00) b=0x3e0;
+ if(g&0x7FFF8000) g=0x7c00;
+
+ *pdest=(XPSXCOL(r,g,b))|sSetMask|(color&0x8000);
+}
+
+////////////////////////////////////////////////////////////////////////
+
+__inline void GetTextureTransColGX32_S(uint32_t *pdest, uint32_t color, short m1, short m2, short m3)
+{
+ int r,g,b;
+
+ if(color==0) return;
+
+ r=(((X32COL1(color))* m1)&0xFF80FF80)>>7;
+ b=(((X32COL2(color))* m2)&0xFF80FF80)>>7;
+ g=(((X32COL3(color))* m3)&0xFF80FF80)>>7;
+
+ if(r&0x7FE00000) r=0x1f0000|(r&0xFFFF);
+ if(r&0x7FE0) r=0x1f |(r&0xFFFF0000);
+ if(b&0x7FE00000) b=0x1f0000|(b&0xFFFF);
+ if(b&0x7FE0) b=0x1f |(b&0xFFFF0000);
+ if(g&0x7FE00000) g=0x1f0000|(g&0xFFFF);
+ if(g&0x7FE0) g=0x1f |(g&0xFFFF0000);
+
+ if((color&0xffff)==0) {*pdest=(*pdest&0xffff)|(((X32PSXCOL(r,g,b))|lSetMask|(color&0x80008000))&0xffff0000);return;}
+ if((color&0xffff0000)==0) {*pdest=(*pdest&0xffff0000)|(((X32PSXCOL(r,g,b))|lSetMask|(color&0x80008000))&0xffff);return;}
+
+ *pdest=(X32PSXCOL(r,g,b))|lSetMask|(color&0x80008000);
+}
+
+////////////////////////////////////////////////////////////////////////
+// FILL FUNCS
+////////////////////////////////////////////////////////////////////////
+
+void FillSoftwareAreaTrans(short x0,short y0,short x1, // FILL AREA TRANS
+ short y1,unsigned short col)
+{
+ short j,i,dx,dy;
+
+ if(y0>y1) return;
+ if(x0>x1) return;
+
+ if(x1<drawX) return;
+ if(y1<drawY) return;
+ if(x0>drawW) return;
+ if(y0>drawH) return;
+
+ x1=min(x1,drawW+1);
+ y1=min(y1,drawH+1);
+ x0=max(x0,drawX);
+ y0=max(y0,drawY);
+
+ if(y0>=iGPUHeight) return;
+ if(x0>1023) return;
+
+ if(y1>iGPUHeight) y1=iGPUHeight;
+ if(x1>1024) x1=1024;
+
+ dx=x1-x0;dy=y1-y0;
+
+ if(dx==1 && dy==1 && x0==1020 && y0==511) // special fix for pinball game... emu protection???
+ {
+/*
+m->v 1020 511 1 1
+writedatamem 0x00000000 1
+tile1 newcol 7fff (orgcol 0xffffff), oldvram 0
+v->m 1020 511 1 1
+readdatamem 0x00007fff 1
+m->v 1020 511 1 1
+writedatamem 0x00000000 1
+tile1 newcol 8000 (orgcol 0xffffff), oldvram 0
+v->m 1020 511 1 1
+readdatamem 0x00008000 1
+*/
+
+ static int iCheat=0;
+ col+=iCheat;
+ if(iCheat==1) iCheat=0; else iCheat=1;
+ }
+
+ if(dx&1) // slow fill
+ {
+ unsigned short *DSTPtr;
+ unsigned short LineOffset;
+ DSTPtr = psxVuw + (1024*y0) + x0;
+ LineOffset = 1024 - dx;
+ for(i=0;i<dy;i++)
+ {
+ for(j=0;j<dx;j++)
+ GetShadeTransCol(DSTPtr++,col);
+ DSTPtr += LineOffset;
+ }
+ }
+ else // fast fill
+ {
+ uint32_t *DSTPtr;
+ unsigned short LineOffset;
+ uint32_t lcol=lSetMask|(((uint32_t)(col))<<16)|col;
+ dx>>=1;
+ DSTPtr = (uint32_t *)(psxVuw + (1024*y0) + x0);
+ LineOffset = 512 - dx;
+
+ if(!bCheckMask && !DrawSemiTrans)
+ {
+ for(i=0;i<dy;i++)
+ {
+ for(j=0;j<dx;j++) *DSTPtr++=lcol;
+ DSTPtr += LineOffset;
+ }
+ }
+ else
+ {
+ for(i=0;i<dy;i++)
+ {
+ for(j=0;j<dx;j++)
+ GetShadeTransCol32(DSTPtr++,lcol);
+ DSTPtr += LineOffset;
+ }
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void FillSoftwareArea(short x0,short y0,short x1, // FILL AREA (BLK FILL)
+ short y1,unsigned short col) // no draw area check here!
+{
+ short j,i,dx,dy;
+
+ if(y0>y1) return;
+ if(x0>x1) return;
+
+ if(y0>=iGPUHeight) return;
+ if(x0>1023) return;
+
+ if(y1>iGPUHeight) y1=iGPUHeight;
+ if(x1>1024) x1=1024;
+
+ dx=x1-x0;dy=y1-y0;
+ if(dx&1)
+ {
+ unsigned short *DSTPtr;
+ unsigned short LineOffset;
+
+ DSTPtr = psxVuw + (1024*y0) + x0;
+ LineOffset = 1024 - dx;
+
+ for(i=0;i<dy;i++)
+ {
+ for(j=0;j<dx;j++) *DSTPtr++=col;
+ DSTPtr += LineOffset;
+ }
+ }
+ else
+ {
+ uint32_t *DSTPtr;
+ unsigned short LineOffset;
+ uint32_t lcol=(((int)col)<<16)|col;
+ dx>>=1;
+ DSTPtr = (uint32_t *)(psxVuw + (1024*y0) + x0);
+ LineOffset = 512 - dx;
+
+ for(i=0;i<dy;i++)
+ {
+ for(j=0;j<dx;j++) *DSTPtr++=lcol;
+ DSTPtr += LineOffset;
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+// EDGE INTERPOLATION
+////////////////////////////////////////////////////////////////////////
+
+typedef struct SOFTVTAG
+{
+ int x,y;
+ int u,v;
+ int R,G,B;
+} soft_vertex;
+
+static soft_vertex vtx[4];
+static soft_vertex * left_array[4], * right_array[4];
+static int left_section, right_section;
+static int left_section_height, right_section_height;
+static int left_x, delta_left_x, right_x, delta_right_x;
+static int left_u, delta_left_u, left_v, delta_left_v;
+static int right_u, delta_right_u, right_v, delta_right_v;
+static int left_R, delta_left_R, right_R, delta_right_R;
+static int left_G, delta_left_G, right_G, delta_right_G;
+static int left_B, delta_left_B, right_B, delta_right_B;
+
+#ifdef _MSC_VER
+
+#pragma warning (disable : 4035)
+
+__inline int shl10idiv(int x, int y)
+{
+ __asm
+ {
+ mov eax,x
+ mov ebx,y
+ mov edx, eax
+ shl eax, 10
+ sar edx, 22
+ idiv ebx
+ // return result in eax
+ }
+}
+
+#else
+
+__inline int shl10idiv(int x, int y)
+{
+ long long int bi=x;
+ bi<<=10;
+ return bi/y;
+}
+
+#endif
+
+__inline int RightSection_F(void)
+{
+ soft_vertex * v1 = right_array[ right_section ];
+ soft_vertex * v2 = right_array[ right_section-1 ];
+
+ int height = v2->y - v1->y;
+ if(height == 0) return 0;
+ delta_right_x = (v2->x - v1->x) / height;
+ right_x = v1->x;
+
+ right_section_height = height;
+ return height;
+}
+
+__inline int LeftSection_F(void)
+{
+ soft_vertex * v1 = left_array[ left_section ];
+ soft_vertex * v2 = left_array[ left_section-1 ];
+
+ int height = v2->y - v1->y;
+ if(height == 0) return 0;
+ delta_left_x = (v2->x - v1->x) / height;
+ left_x = v1->x;
+
+ left_section_height = height;
+ return height;
+}
+
+__inline BOOL NextRow_F(void)
+{
+ if(--left_section_height<=0)
+ {
+ if(--left_section <= 0) {return TRUE;}
+ if(LeftSection_F() <= 0) {return TRUE;}
+ }
+ else
+ {
+ left_x += delta_left_x;
+ }
+
+ if(--right_section_height<=0)
+ {
+ if(--right_section<=0) {return TRUE;}
+ if(RightSection_F() <=0) {return TRUE;}
+ }
+ else
+ {
+ right_x += delta_right_x;
+ }
+ return FALSE;
+}
+
+__inline BOOL SetupSections_F(short x1, short y1, short x2, short y2, short x3, short y3)
+{
+ soft_vertex * v1, * v2, * v3;
+ int height,longest;
+
+ v1 = vtx; v1->x=x1<<16;v1->y=y1;
+ v2 = vtx+1; v2->x=x2<<16;v2->y=y2;
+ v3 = vtx+2; v3->x=x3<<16;v3->y=y3;
+
+ if(v1->y > v2->y) { soft_vertex * v = v1; v1 = v2; v2 = v; }
+ if(v1->y > v3->y) { soft_vertex * v = v1; v1 = v3; v3 = v; }
+ if(v2->y > v3->y) { soft_vertex * v = v2; v2 = v3; v3 = v; }
+
+ height = v3->y - v1->y;
+ if(height == 0) {return FALSE;}
+ longest = (((v2->y - v1->y) << 16) / height) * ((v3->x - v1->x)>>16) + (v1->x - v2->x);
+ if(longest == 0) {return FALSE;}
+
+ if(longest < 0)
+ {
+ right_array[0] = v3;
+ right_array[1] = v2;
+ right_array[2] = v1;
+ right_section = 2;
+ left_array[0] = v3;
+ left_array[1] = v1;
+ left_section = 1;
+
+ if(LeftSection_F() <= 0) return FALSE;
+ if(RightSection_F() <= 0)
+ {
+ right_section--;
+ if(RightSection_F() <= 0) return FALSE;
+ }
+ }
+ else
+ {
+ left_array[0] = v3;
+ left_array[1] = v2;
+ left_array[2] = v1;
+ left_section = 2;
+ right_array[0] = v3;
+ right_array[1] = v1;
+ right_section = 1;
+
+ if(RightSection_F() <= 0) return FALSE;
+ if(LeftSection_F() <= 0)
+ {
+ left_section--;
+ if(LeftSection_F() <= 0) return FALSE;
+ }
+ }
+
+ Ymin=v1->y;
+ Ymax=min(v3->y-1,drawH);
+
+ return TRUE;
+}
+
+__inline int RightSection_G(void)
+{
+ soft_vertex * v1 = right_array[ right_section ];
+ soft_vertex * v2 = right_array[ right_section-1 ];
+
+ int height = v2->y - v1->y;
+ if(height == 0) return 0;
+ delta_right_x = (v2->x - v1->x) / height;
+ right_x = v1->x;
+
+ right_section_height = height;
+ return height;
+}
+
+__inline int LeftSection_G(void)
+{
+ soft_vertex * v1 = left_array[ left_section ];
+ soft_vertex * v2 = left_array[ left_section-1 ];
+
+ int height = v2->y - v1->y;
+ if(height == 0) return 0;
+ delta_left_x = (v2->x - v1->x) / height;
+ left_x = v1->x;
+
+ delta_left_R = ((v2->R - v1->R)) / height;
+ left_R = v1->R;
+ delta_left_G = ((v2->G - v1->G)) / height;
+ left_G = v1->G;
+ delta_left_B = ((v2->B - v1->B)) / height;
+ left_B = v1->B;
+
+ left_section_height = height;
+ return height;
+}
+
+__inline BOOL NextRow_G(void)
+{
+ if(--left_section_height<=0)
+ {
+ if(--left_section <= 0) {return TRUE;}
+ if(LeftSection_G() <= 0) {return TRUE;}
+ }
+ else
+ {
+ left_x += delta_left_x;
+ left_R += delta_left_R;
+ left_G += delta_left_G;
+ left_B += delta_left_B;
+ }
+
+ if(--right_section_height<=0)
+ {
+ if(--right_section<=0) {return TRUE;}
+ if(RightSection_G() <=0) {return TRUE;}
+ }
+ else
+ {
+ right_x += delta_right_x;
+ }
+ return FALSE;
+}
+
+__inline BOOL SetupSections_G(short x1,short y1,short x2,short y2,short x3,short y3, int rgb1, int rgb2, int rgb3){
+ soft_vertex *v1, *v2, *v3;
+ int height, longest, temp;
+
+ v1 = vtx; v1->x=x1<<16;v1->y=y1;
+ v1->R=(rgb1) & 0x00ff0000;
+ v1->G=(rgb1<<8) & 0x00ff0000;
+ v1->B=(rgb1<<16) & 0x00ff0000;
+ v2 = vtx+1; v2->x=x2<<16;v2->y=y2;
+ v2->R=(rgb2) & 0x00ff0000;
+ v2->G=(rgb2<<8) & 0x00ff0000;
+ v2->B=(rgb2<<16) & 0x00ff0000;
+ v3 = vtx+2; v3->x=x3<<16;v3->y=y3;
+ v3->R=(rgb3) & 0x00ff0000;
+ v3->G=(rgb3<<8) & 0x00ff0000;
+ v3->B=(rgb3<<16) & 0x00ff0000;
+
+ if(v1->y > v2->y) { soft_vertex * v = v1; v1 = v2; v2 = v; }
+ if(v1->y > v3->y) { soft_vertex * v = v1; v1 = v3; v3 = v; }
+ if(v2->y > v3->y) { soft_vertex * v = v2; v2 = v3; v3 = v; }
+
+ height = v3->y - v1->y;
+ if(height == 0) {return FALSE;}
+ temp=(((v2->y - v1->y) << 16) / height);
+ longest = temp * ((v3->x - v1->x)>>16) + (v1->x - v2->x);
+ if(longest == 0) {return FALSE;}
+
+ if(longest < 0)
+ {
+ right_array[0] = v3;
+ right_array[1] = v2;
+ right_array[2] = v1;
+ right_section = 2;
+ left_array[0] = v3;
+ left_array[1] = v1;
+ left_section = 1;
+
+ if(LeftSection_G() <= 0) return FALSE;
+ if(RightSection_G() <= 0)
+ {
+ right_section--;
+ if(RightSection_G() <= 0) return FALSE;
+ }
+ if(longest > -0x1000) longest = -0x1000;
+ }
+ else
+ {
+ left_array[0] = v3;
+ left_array[1] = v2;
+ left_array[2] = v1;
+ left_section = 2;
+ right_array[0] = v3;
+ right_array[1] = v1;
+ right_section = 1;
+
+ if(RightSection_G() <= 0) return FALSE;
+ if(LeftSection_G() <= 0)
+ {
+ left_section--;
+ if(LeftSection_G() <= 0) return FALSE;
+ }
+ if(longest < 0x1000) longest = 0x1000;
+ }
+
+ Ymin=v1->y;
+ Ymax=min(v3->y-1,drawH);
+
+ delta_right_R=shl10idiv(temp*((v3->R - v1->R)>>10)+((v1->R - v2->R)<<6),longest);
+ delta_right_G=shl10idiv(temp*((v3->G - v1->G)>>10)+((v1->G - v2->G)<<6),longest);
+ delta_right_B=shl10idiv(temp*((v3->B - v1->B)>>10)+((v1->B - v2->B)<<6),longest);
+
+ return TRUE;
+}
+
+__inline int RightSection_FT(void)
+{
+ soft_vertex * v1 = right_array[ right_section ];
+ soft_vertex * v2 = right_array[ right_section-1 ];
+
+ int height = v2->y - v1->y;
+ if(height == 0) return 0;
+ delta_right_x = (v2->x - v1->x) / height;
+ right_x = v1->x;
+
+ right_section_height = height;
+ return height;
+}
+
+__inline int LeftSection_FT(void)
+{
+ soft_vertex * v1 = left_array[ left_section ];
+ soft_vertex * v2 = left_array[ left_section-1 ];
+
+ int height = v2->y - v1->y;
+ if(height == 0) return 0;
+ delta_left_x = (v2->x - v1->x) / height;
+ left_x = v1->x;
+
+ delta_left_u = ((v2->u - v1->u)) / height;
+ left_u = v1->u;
+ delta_left_v = ((v2->v - v1->v)) / height;
+ left_v = v1->v;
+
+ left_section_height = height;
+ return height;
+}
+
+__inline BOOL NextRow_FT(void)
+{
+ if(--left_section_height<=0)
+ {
+ if(--left_section <= 0) {return TRUE;}
+ if(LeftSection_FT() <= 0) {return TRUE;}
+ }
+ else
+ {
+ left_x += delta_left_x;
+ left_u += delta_left_u;
+ left_v += delta_left_v;
+ }
+
+ if(--right_section_height<=0)
+ {
+ if(--right_section<=0) {return TRUE;}
+ if(RightSection_FT() <=0) {return TRUE;}
+ }
+ else
+ {
+ right_x += delta_right_x;
+ }
+ return FALSE;
+}
+
+__inline BOOL SetupSections_FT(short x1, short y1, short x2, short y2, short x3, short y3, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3)
+{
+ soft_vertex * v1, * v2, * v3;
+ int height,longest,temp;
+
+ v1 = vtx; v1->x=x1<<16;v1->y=y1;
+ v1->u=tx1<<16;v1->v=ty1<<16;
+ v2 = vtx+1; v2->x=x2<<16;v2->y=y2;
+ v2->u=tx2<<16;v2->v=ty2<<16;
+ v3 = vtx+2; v3->x=x3<<16;v3->y=y3;
+ v3->u=tx3<<16;v3->v=ty3<<16;
+
+ if(v1->y > v2->y) { soft_vertex * v = v1; v1 = v2; v2 = v; }
+ if(v1->y > v3->y) { soft_vertex * v = v1; v1 = v3; v3 = v; }
+ if(v2->y > v3->y) { soft_vertex * v = v2; v2 = v3; v3 = v; }
+
+ height = v3->y - v1->y;
+ if(height == 0) {return FALSE;}
+
+ temp=(((v2->y - v1->y) << 16) / height);
+ longest = temp * ((v3->x - v1->x)>>16) + (v1->x - v2->x);
+
+ if(longest == 0) {return FALSE;}
+
+ if(longest < 0)
+ {
+ right_array[0] = v3;
+ right_array[1] = v2;
+ right_array[2] = v1;
+ right_section = 2;
+ left_array[0] = v3;
+ left_array[1] = v1;
+ left_section = 1;
+
+ if(LeftSection_FT() <= 0) return FALSE;
+ if(RightSection_FT() <= 0)
+ {
+ right_section--;
+ if(RightSection_FT() <= 0) return FALSE;
+ }
+ if(longest > -0x1000) longest = -0x1000;
+ }
+ else
+ {
+ left_array[0] = v3;
+ left_array[1] = v2;
+ left_array[2] = v1;
+ left_section = 2;
+ right_array[0] = v3;
+ right_array[1] = v1;
+ right_section = 1;
+
+ if(RightSection_FT() <= 0) return FALSE;
+ if(LeftSection_FT() <= 0)
+ {
+ left_section--;
+ if(LeftSection_FT() <= 0) return FALSE;
+ }
+ if(longest < 0x1000) longest = 0x1000;
+ }
+
+ Ymin=v1->y;
+ Ymax=min(v3->y-1,drawH);
+
+ delta_right_u=shl10idiv(temp*((v3->u - v1->u)>>10)+((v1->u - v2->u)<<6),longest);
+ delta_right_v=shl10idiv(temp*((v3->v - v1->v)>>10)+((v1->v - v2->v)<<6),longest);
+
+/*
+Mmm... adjust neg tex deltas... will sometimes cause slight
+texture distortions
+
+ longest>>=16;
+ if(longest)
+ {
+ if(longest<0) longest=-longest;
+ if(delta_right_u<0)
+ delta_right_u-=delta_right_u/longest;
+ if(delta_right_v<0)
+ delta_right_v-=delta_right_v/longest;
+ }
+*/
+
+ return TRUE;
+}
+
+__inline int RightSection_GT(void)
+{
+ soft_vertex * v1 = right_array[ right_section ];
+ soft_vertex * v2 = right_array[ right_section-1 ];
+
+ int height = v2->y - v1->y;
+ if(height == 0) return 0;
+ delta_right_x = (v2->x - v1->x) / height;
+ right_x = v1->x;
+
+ right_section_height = height;
+ return height;
+}
+
+__inline int LeftSection_GT(void)
+{
+ soft_vertex * v1 = left_array[ left_section ];
+ soft_vertex * v2 = left_array[ left_section-1 ];
+
+ int height = v2->y - v1->y;
+ if(height == 0) return 0;
+ delta_left_x = (v2->x - v1->x) / height;
+ left_x = v1->x;
+
+ delta_left_u = ((v2->u - v1->u)) / height;
+ left_u = v1->u;
+ delta_left_v = ((v2->v - v1->v)) / height;
+ left_v = v1->v;
+
+ delta_left_R = ((v2->R - v1->R)) / height;
+ left_R = v1->R;
+ delta_left_G = ((v2->G - v1->G)) / height;
+ left_G = v1->G;
+ delta_left_B = ((v2->B - v1->B)) / height;
+ left_B = v1->B;
+
+ left_section_height = height;
+ return height;
+}
+
+__inline BOOL NextRow_GT(void)
+{
+ if(--left_section_height<=0)
+ {
+ if(--left_section <= 0) {return TRUE;}
+ if(LeftSection_GT() <= 0) {return TRUE;}
+ }
+ else
+ {
+ left_x += delta_left_x;
+ left_u += delta_left_u;
+ left_v += delta_left_v;
+ left_R += delta_left_R;
+ left_G += delta_left_G;
+ left_B += delta_left_B;
+ }
+
+ if(--right_section_height<=0)
+ {
+ if(--right_section<=0) {return TRUE;}
+ if(RightSection_GT() <=0) {return TRUE;}
+ }
+ else
+ {
+ right_x += delta_right_x;
+ }
+ return FALSE;
+}
+
+__inline BOOL SetupSections_GT(short x1, short y1, short x2, short y2, short x3, short y3, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, int rgb1, int rgb2, int rgb3)
+{
+ soft_vertex * v1, * v2, * v3;
+ int height,longest,temp;
+
+ v1 = vtx; v1->x=x1<<16;v1->y=y1;
+ v1->u=tx1<<16;v1->v=ty1<<16;
+ v1->R=(rgb1) & 0x00ff0000;
+ v1->G=(rgb1<<8) & 0x00ff0000;
+ v1->B=(rgb1<<16) & 0x00ff0000;
+
+ v2 = vtx+1; v2->x=x2<<16;v2->y=y2;
+ v2->u=tx2<<16;v2->v=ty2<<16;
+ v2->R=(rgb2) & 0x00ff0000;
+ v2->G=(rgb2<<8) & 0x00ff0000;
+ v2->B=(rgb2<<16) & 0x00ff0000;
+
+ v3 = vtx+2; v3->x=x3<<16;v3->y=y3;
+ v3->u=tx3<<16;v3->v=ty3<<16;
+ v3->R=(rgb3) & 0x00ff0000;
+ v3->G=(rgb3<<8) & 0x00ff0000;
+ v3->B=(rgb3<<16) & 0x00ff0000;
+
+ if(v1->y > v2->y) { soft_vertex * v = v1; v1 = v2; v2 = v; }
+ if(v1->y > v3->y) { soft_vertex * v = v1; v1 = v3; v3 = v; }
+ if(v2->y > v3->y) { soft_vertex * v = v2; v2 = v3; v3 = v; }
+
+ height = v3->y - v1->y;
+ if(height == 0) {return FALSE;}
+
+ temp=(((v2->y - v1->y) << 16) / height);
+ longest = temp * ((v3->x - v1->x)>>16) + (v1->x - v2->x);
+
+ if(longest == 0) {return FALSE;}
+
+ if(longest < 0)
+ {
+ right_array[0] = v3;
+ right_array[1] = v2;
+ right_array[2] = v1;
+ right_section = 2;
+ left_array[0] = v3;
+ left_array[1] = v1;
+ left_section = 1;
+
+ if(LeftSection_GT() <= 0) return FALSE;
+ if(RightSection_GT() <= 0)
+ {
+ right_section--;
+ if(RightSection_GT() <= 0) return FALSE;
+ }
+
+ if(longest > -0x1000) longest = -0x1000;
+ }
+ else
+ {
+ left_array[0] = v3;
+ left_array[1] = v2;
+ left_array[2] = v1;
+ left_section = 2;
+ right_array[0] = v3;
+ right_array[1] = v1;
+ right_section = 1;
+
+ if(RightSection_GT() <= 0) return FALSE;
+ if(LeftSection_GT() <= 0)
+ {
+ left_section--;
+ if(LeftSection_GT() <= 0) return FALSE;
+ }
+ if(longest < 0x1000) longest = 0x1000;
+ }
+
+ Ymin=v1->y;
+ Ymax=min(v3->y-1,drawH);
+
+ delta_right_R=shl10idiv(temp*((v3->R - v1->R)>>10)+((v1->R - v2->R)<<6),longest);
+ delta_right_G=shl10idiv(temp*((v3->G - v1->G)>>10)+((v1->G - v2->G)<<6),longest);
+ delta_right_B=shl10idiv(temp*((v3->B - v1->B)>>10)+((v1->B - v2->B)<<6),longest);
+
+ delta_right_u=shl10idiv(temp*((v3->u - v1->u)>>10)+((v1->u - v2->u)<<6),longest);
+ delta_right_v=shl10idiv(temp*((v3->v - v1->v)>>10)+((v1->v - v2->v)<<6),longest);
+
+
+/*
+Mmm... adjust neg tex deltas... will sometimes cause slight
+texture distortions
+ longest>>=16;
+ if(longest)
+ {
+ if(longest<0) longest=-longest;
+ if(delta_right_u<0)
+ delta_right_u-=delta_right_u/longest;
+ if(delta_right_v<0)
+ delta_right_v-=delta_right_v/longest;
+ }
+*/
+
+
+ return TRUE;
+}
+
+__inline int RightSection_F4(void)
+{
+ soft_vertex * v1 = right_array[ right_section ];
+ soft_vertex * v2 = right_array[ right_section-1 ];
+
+ int height = v2->y - v1->y;
+ right_section_height = height;
+ right_x = v1->x;
+ if(height == 0)
+ {
+ return 0;
+ }
+ delta_right_x = (v2->x - v1->x) / height;
+
+ return height;
+}
+
+__inline int LeftSection_F4(void)
+{
+ soft_vertex * v1 = left_array[ left_section ];
+ soft_vertex * v2 = left_array[ left_section-1 ];
+
+ int height = v2->y - v1->y;
+ left_section_height = height;
+ left_x = v1->x;
+ if(height == 0)
+ {
+ return 0;
+ }
+ delta_left_x = (v2->x - v1->x) / height;
+
+ return height;
+}
+
+__inline BOOL NextRow_F4(void)
+{
+ if(--left_section_height<=0)
+ {
+ if(--left_section > 0)
+ while(LeftSection_F4()<=0)
+ {
+ if(--left_section <= 0) break;
+ }
+ }
+ else
+ {
+ left_x += delta_left_x;
+ }
+
+ if(--right_section_height<=0)
+ {
+ if(--right_section > 0)
+ while(RightSection_F4()<=0)
+ {
+ if(--right_section<=0) break;
+ }
+ }
+ else
+ {
+ right_x += delta_right_x;
+ }
+ return FALSE;
+}
+
+__inline BOOL SetupSections_F4(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4)
+{
+ soft_vertex * v1, * v2, * v3, * v4;
+ int height,width,longest1,longest2;
+
+ v1 = vtx; v1->x=x1<<16;v1->y=y1;
+ v2 = vtx+1; v2->x=x2<<16;v2->y=y2;
+ v3 = vtx+2; v3->x=x3<<16;v3->y=y3;
+ v4 = vtx+3; v4->x=x4<<16;v4->y=y4;
+
+ if(v1->y > v2->y) { soft_vertex * v = v1; v1 = v2; v2 = v; }
+ if(v1->y > v3->y) { soft_vertex * v = v1; v1 = v3; v3 = v; }
+ if(v1->y > v4->y) { soft_vertex * v = v1; v1 = v4; v4 = v; }
+ if(v2->y > v3->y) { soft_vertex * v = v2; v2 = v3; v3 = v; }
+ if(v2->y > v4->y) { soft_vertex * v = v2; v2 = v4; v4 = v; }
+ if(v3->y > v4->y) { soft_vertex * v = v3; v3 = v4; v4 = v; }
+
+ height = v4->y - v1->y; if(height == 0) height =1;
+ width = (v4->x - v1->x)>>16;
+ longest1 = (((v2->y - v1->y) << 16) / height) * width + (v1->x - v2->x);
+ longest2 = (((v3->y - v1->y) << 16) / height) * width + (v1->x - v3->x);
+
+ if(longest1 < 0) // 2 is right
+ {
+ if(longest2 < 0) // 3 is right
+ {
+ left_array[0] = v4;
+ left_array[1] = v1;
+ left_section = 1;
+
+ height = v3->y - v1->y; if(height == 0) height=1;
+ longest1 = (((v2->y - v1->y) << 16) / height) * ((v3->x - v1->x)>>16) + (v1->x - v2->x);
+ if(longest1 >= 0)
+ {
+ right_array[0] = v4; // 1
+ right_array[1] = v3; // 3
+ right_array[2] = v1; // 4
+ right_section = 2;
+ }
+ else
+ {
+ height = v4->y - v2->y; if(height == 0) height=1;
+ longest1 = (((v3->y - v2->y) << 16) / height) * ((v4->x - v2->x)>>16) + (v2->x - v3->x);
+ if(longest1 >= 0)
+ {
+ right_array[0] = v4; // 1
+ right_array[1] = v2; // 2
+ right_array[2] = v1; // 4
+ right_section = 2;
+ }
+ else
+ {
+ right_array[0] = v4; // 1
+ right_array[1] = v3; // 2
+ right_array[2] = v2; // 3
+ right_array[3] = v1; // 4
+ right_section = 3;
+ }
+ }
+ }
+ else
+ {
+ left_array[0] = v4;
+ left_array[1] = v3; // 1
+ left_array[2] = v1; // 2
+ left_section = 2; // 3
+ right_array[0] = v4; // 4
+ right_array[1] = v2;
+ right_array[2] = v1;
+ right_section = 2;
+ }
+ }
+ else
+ {
+ if(longest2 < 0)
+ {
+ left_array[0] = v4; // 1
+ left_array[1] = v2; // 2
+ left_array[2] = v1; // 3
+ left_section = 2; // 4
+ right_array[0] = v4;
+ right_array[1] = v3;
+ right_array[2] = v1;
+ right_section = 2;
+ }
+ else
+ {
+ right_array[0] = v4;
+ right_array[1] = v1;
+ right_section = 1;
+
+ height = v3->y - v1->y; if(height == 0) height=1;
+ longest1 = (((v2->y - v1->y) << 16) / height) * ((v3->x - v1->x)>>16) + (v1->x - v2->x);
+ if(longest1<0)
+ {
+ left_array[0] = v4; // 1
+ left_array[1] = v3; // 3
+ left_array[2] = v1; // 4
+ left_section = 2;
+ }
+ else
+ {
+ height = v4->y - v2->y; if(height == 0) height=1;
+ longest1 = (((v3->y - v2->y) << 16) / height) * ((v4->x - v2->x)>>16) + (v2->x - v3->x);
+ if(longest1<0)
+ {
+ left_array[0] = v4; // 1
+ left_array[1] = v2; // 2
+ left_array[2] = v1; // 4
+ left_section = 2;
+ }
+ else
+ {
+ left_array[0] = v4; // 1
+ left_array[1] = v3; // 2
+ left_array[2] = v2; // 3
+ left_array[3] = v1; // 4
+ left_section = 3;
+ }
+ }
+ }
+ }
+
+ while(LeftSection_F4()<=0)
+ {
+ if(--left_section <= 0) break;
+ }
+
+ while(RightSection_F4()<=0)
+ {
+ if(--right_section <= 0) break;
+ }
+
+ Ymin=v1->y;
+ Ymax=min(v4->y-1,drawH);
+
+ return TRUE;
+}
+
+__inline int RightSection_FT4(void)
+{
+ soft_vertex * v1 = right_array[ right_section ];
+ soft_vertex * v2 = right_array[ right_section-1 ];
+
+ int height = v2->y - v1->y;
+ right_section_height = height;
+ right_x = v1->x;
+ right_u = v1->u;
+ right_v = v1->v;
+ if(height == 0)
+ {
+ return 0;
+ }
+ delta_right_x = (v2->x - v1->x) / height;
+ delta_right_u = (v2->u - v1->u) / height;
+ delta_right_v = (v2->v - v1->v) / height;
+
+ return height;
+}
+
+__inline int LeftSection_FT4(void)
+{
+ soft_vertex * v1 = left_array[ left_section ];
+ soft_vertex * v2 = left_array[ left_section-1 ];
+
+ int height = v2->y - v1->y;
+ left_section_height = height;
+ left_x = v1->x;
+ left_u = v1->u;
+ left_v = v1->v;
+ if(height == 0)
+ {
+ return 0;
+ }
+ delta_left_x = (v2->x - v1->x) / height;
+ delta_left_u = (v2->u - v1->u) / height;
+ delta_left_v = (v2->v - v1->v) / height;
+
+ return height;
+}
+
+__inline BOOL NextRow_FT4(void)
+{
+ if(--left_section_height<=0)
+ {
+ if(--left_section > 0)
+ while(LeftSection_FT4()<=0)
+ {
+ if(--left_section <= 0) break;
+ }
+ }
+ else
+ {
+ left_x += delta_left_x;
+ left_u += delta_left_u;
+ left_v += delta_left_v;
+ }
+
+ if(--right_section_height<=0)
+ {
+ if(--right_section > 0)
+ while(RightSection_FT4()<=0)
+ {
+ if(--right_section<=0) break;
+ }
+ }
+ else
+ {
+ right_x += delta_right_x;
+ right_u += delta_right_u;
+ right_v += delta_right_v;
+ }
+ return FALSE;
+}
+
+__inline BOOL SetupSections_FT4(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4)
+{
+ soft_vertex * v1, * v2, * v3, * v4;
+ int height,width,longest1,longest2;
+
+ v1 = vtx; v1->x=x1<<16;v1->y=y1;
+ v1->u=tx1<<16;v1->v=ty1<<16;
+
+ v2 = vtx+1; v2->x=x2<<16;v2->y=y2;
+ v2->u=tx2<<16;v2->v=ty2<<16;
+
+ v3 = vtx+2; v3->x=x3<<16;v3->y=y3;
+ v3->u=tx3<<16;v3->v=ty3<<16;
+
+ v4 = vtx+3; v4->x=x4<<16;v4->y=y4;
+ v4->u=tx4<<16;v4->v=ty4<<16;
+
+ if(v1->y > v2->y) { soft_vertex * v = v1; v1 = v2; v2 = v; }
+ if(v1->y > v3->y) { soft_vertex * v = v1; v1 = v3; v3 = v; }
+ if(v1->y > v4->y) { soft_vertex * v = v1; v1 = v4; v4 = v; }
+ if(v2->y > v3->y) { soft_vertex * v = v2; v2 = v3; v3 = v; }
+ if(v2->y > v4->y) { soft_vertex * v = v2; v2 = v4; v4 = v; }
+ if(v3->y > v4->y) { soft_vertex * v = v3; v3 = v4; v4 = v; }
+
+ height = v4->y - v1->y; if(height == 0) height =1;
+ width = (v4->x - v1->x)>>16;
+ longest1 = (((v2->y - v1->y) << 16) / height) * width + (v1->x - v2->x);
+ longest2 = (((v3->y - v1->y) << 16) / height) * width + (v1->x - v3->x);
+
+ if(longest1 < 0) // 2 is right
+ {
+ if(longest2 < 0) // 3 is right
+ {
+ left_array[0] = v4;
+ left_array[1] = v1;
+ left_section = 1;
+
+ height = v3->y - v1->y; if(height == 0) height=1;
+ longest1 = (((v2->y - v1->y) << 16) / height) * ((v3->x - v1->x)>>16) + (v1->x - v2->x);
+ if(longest1 >= 0)
+ {
+ right_array[0] = v4; // 1
+ right_array[1] = v3; // 3
+ right_array[2] = v1; // 4
+ right_section = 2;
+ }
+ else
+ {
+ height = v4->y - v2->y; if(height == 0) height=1;
+ longest1 = (((v3->y - v2->y) << 16) / height) * ((v4->x - v2->x)>>16) + (v2->x - v3->x);
+ if(longest1 >= 0)
+ {
+ right_array[0] = v4; // 1
+ right_array[1] = v2; // 2
+ right_array[2] = v1; // 4
+ right_section = 2;
+ }
+ else
+ {
+ right_array[0] = v4; // 1
+ right_array[1] = v3; // 2
+ right_array[2] = v2; // 3
+ right_array[3] = v1; // 4
+ right_section = 3;
+ }
+ }
+ }
+ else
+ {
+ left_array[0] = v4;
+ left_array[1] = v3; // 1
+ left_array[2] = v1; // 2
+ left_section = 2; // 3
+ right_array[0] = v4; // 4
+ right_array[1] = v2;
+ right_array[2] = v1;
+ right_section = 2;
+ }
+ }
+ else
+ {
+ if(longest2 < 0)
+ {
+ left_array[0] = v4; // 1
+ left_array[1] = v2; // 2
+ left_array[2] = v1; // 3
+ left_section = 2; // 4
+ right_array[0] = v4;
+ right_array[1] = v3;
+ right_array[2] = v1;
+ right_section = 2;
+ }
+ else
+ {
+ right_array[0] = v4;
+ right_array[1] = v1;
+ right_section = 1;
+
+ height = v3->y - v1->y; if(height == 0) height=1;
+ longest1 = (((v2->y - v1->y) << 16) / height) * ((v3->x - v1->x)>>16) + (v1->x - v2->x);
+ if(longest1<0)
+ {
+ left_array[0] = v4; // 1
+ left_array[1] = v3; // 3
+ left_array[2] = v1; // 4
+ left_section = 2;
+ }
+ else
+ {
+ height = v4->y - v2->y; if(height == 0) height=1;
+ longest1 = (((v3->y - v2->y) << 16) / height) * ((v4->x - v2->x)>>16) + (v2->x - v3->x);
+ if(longest1<0)
+ {
+ left_array[0] = v4; // 1
+ left_array[1] = v2; // 2
+ left_array[2] = v1; // 4
+ left_section = 2;
+ }
+ else
+ {
+ left_array[0] = v4; // 1
+ left_array[1] = v3; // 2
+ left_array[2] = v2; // 3
+ left_array[3] = v1; // 4
+ left_section = 3;
+ }
+ }
+ }
+ }
+
+ while(LeftSection_FT4()<=0)
+ {
+ if(--left_section <= 0) break;
+ }
+
+ while(RightSection_FT4()<=0)
+ {
+ if(--right_section <= 0) break;
+ }
+
+ Ymin=v1->y;
+ Ymax=min(v4->y-1,drawH);
+
+ return TRUE;
+}
+
+__inline int RightSection_GT4(void)
+{
+ soft_vertex * v1 = right_array[ right_section ];
+ soft_vertex * v2 = right_array[ right_section-1 ];
+
+ int height = v2->y - v1->y;
+ right_section_height = height;
+ right_x = v1->x;
+ right_u = v1->u;
+ right_v = v1->v;
+ right_R = v1->R;
+ right_G = v1->G;
+ right_B = v1->B;
+
+ if(height == 0)
+ {
+ return 0;
+ }
+ delta_right_x = (v2->x - v1->x) / height;
+ delta_right_u = (v2->u - v1->u) / height;
+ delta_right_v = (v2->v - v1->v) / height;
+ delta_right_R = (v2->R - v1->R) / height;
+ delta_right_G = (v2->G - v1->G) / height;
+ delta_right_B = (v2->B - v1->B) / height;
+
+ return height;
+}
+
+__inline int LeftSection_GT4(void)
+{
+ soft_vertex * v1 = left_array[ left_section ];
+ soft_vertex * v2 = left_array[ left_section-1 ];
+
+ int height = v2->y - v1->y;
+ left_section_height = height;
+ left_x = v1->x;
+ left_u = v1->u;
+ left_v = v1->v;
+ left_R = v1->R;
+ left_G = v1->G;
+ left_B = v1->B;
+
+ if(height == 0)
+ {
+ return 0;
+ }
+ delta_left_x = (v2->x - v1->x) / height;
+ delta_left_u = (v2->u - v1->u) / height;
+ delta_left_v = (v2->v - v1->v) / height;
+ delta_left_R = (v2->R - v1->R) / height;
+ delta_left_G = (v2->G - v1->G) / height;
+ delta_left_B = (v2->B - v1->B) / height;
+
+ return height;
+}
+
+__inline BOOL NextRow_GT4(void)
+{
+ if(--left_section_height<=0)
+ {
+ if(--left_section > 0)
+ while(LeftSection_GT4()<=0)
+ {
+ if(--left_section <= 0) break;
+ }
+ }
+ else
+ {
+ left_x += delta_left_x;
+ left_u += delta_left_u;
+ left_v += delta_left_v;
+ left_R += delta_left_R;
+ left_G += delta_left_G;
+ left_B += delta_left_B;
+ }
+
+ if(--right_section_height<=0)
+ {
+ if(--right_section > 0)
+ while(RightSection_GT4()<=0)
+ {
+ if(--right_section<=0) break;
+ }
+ }
+ else
+ {
+ right_x += delta_right_x;
+ right_u += delta_right_u;
+ right_v += delta_right_v;
+ right_R += delta_right_R;
+ right_G += delta_right_G;
+ right_B += delta_right_B;
+ }
+ return FALSE;
+}
+
+__inline BOOL SetupSections_GT4(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4, int rgb1, int rgb2, int rgb3, int rgb4)
+{
+ soft_vertex * v1, * v2, * v3, * v4;
+ int height,width,longest1,longest2;
+
+ v1 = vtx; v1->x=x1<<16;v1->y=y1;
+ v1->u=tx1<<16;v1->v=ty1<<16;
+ v1->R=(rgb1) & 0x00ff0000;
+ v1->G=(rgb1<<8) & 0x00ff0000;
+ v1->B=(rgb1<<16) & 0x00ff0000;
+
+ v2 = vtx+1; v2->x=x2<<16;v2->y=y2;
+ v2->u=tx2<<16;v2->v=ty2<<16;
+ v2->R=(rgb2) & 0x00ff0000;
+ v2->G=(rgb2<<8) & 0x00ff0000;
+ v2->B=(rgb2<<16) & 0x00ff0000;
+
+ v3 = vtx+2; v3->x=x3<<16;v3->y=y3;
+ v3->u=tx3<<16;v3->v=ty3<<16;
+ v3->R=(rgb3) & 0x00ff0000;
+ v3->G=(rgb3<<8) & 0x00ff0000;
+ v3->B=(rgb3<<16) & 0x00ff0000;
+
+ v4 = vtx+3; v4->x=x4<<16;v4->y=y4;
+ v4->u=tx4<<16;v4->v=ty4<<16;
+ v4->R=(rgb4) & 0x00ff0000;
+ v4->G=(rgb4<<8) & 0x00ff0000;
+ v4->B=(rgb4<<16) & 0x00ff0000;
+
+ if(v1->y > v2->y) { soft_vertex * v = v1; v1 = v2; v2 = v; }
+ if(v1->y > v3->y) { soft_vertex * v = v1; v1 = v3; v3 = v; }
+ if(v1->y > v4->y) { soft_vertex * v = v1; v1 = v4; v4 = v; }
+ if(v2->y > v3->y) { soft_vertex * v = v2; v2 = v3; v3 = v; }
+ if(v2->y > v4->y) { soft_vertex * v = v2; v2 = v4; v4 = v; }
+ if(v3->y > v4->y) { soft_vertex * v = v3; v3 = v4; v4 = v; }
+
+ height = v4->y - v1->y; if(height == 0) height =1;
+ width = (v4->x - v1->x)>>16;
+ longest1 = (((v2->y - v1->y) << 16) / height) * width + (v1->x - v2->x);
+ longest2 = (((v3->y - v1->y) << 16) / height) * width + (v1->x - v3->x);
+
+ if(longest1 < 0) // 2 is right
+ {
+ if(longest2 < 0) // 3 is right
+ {
+ left_array[0] = v4;
+ left_array[1] = v1;
+ left_section = 1;
+
+ height = v3->y - v1->y; if(height == 0) height=1;
+ longest1 = (((v2->y - v1->y) << 16) / height) * ((v3->x - v1->x)>>16) + (v1->x - v2->x);
+ if(longest1 >= 0)
+ {
+ right_array[0] = v4; // 1
+ right_array[1] = v3; // 3
+ right_array[2] = v1; // 4
+ right_section = 2;
+ }
+ else
+ {
+ height = v4->y - v2->y; if(height == 0) height=1;
+ longest1 = (((v3->y - v2->y) << 16) / height) * ((v4->x - v2->x)>>16) + (v2->x - v3->x);
+ if(longest1 >= 0)
+ {
+ right_array[0] = v4; // 1
+ right_array[1] = v2; // 2
+ right_array[2] = v1; // 4
+ right_section = 2;
+ }
+ else
+ {
+ right_array[0] = v4; // 1
+ right_array[1] = v3; // 2
+ right_array[2] = v2; // 3
+ right_array[3] = v1; // 4
+ right_section = 3;
+ }
+ }
+ }
+ else
+ {
+ left_array[0] = v4;
+ left_array[1] = v3; // 1
+ left_array[2] = v1; // 2
+ left_section = 2; // 3
+ right_array[0] = v4; // 4
+ right_array[1] = v2;
+ right_array[2] = v1;
+ right_section = 2;
+ }
+ }
+ else
+ {
+ if(longest2 < 0)
+ {
+ left_array[0] = v4; // 1
+ left_array[1] = v2; // 2
+ left_array[2] = v1; // 3
+ left_section = 2; // 4
+ right_array[0] = v4;
+ right_array[1] = v3;
+ right_array[2] = v1;
+ right_section = 2;
+ }
+ else
+ {
+ right_array[0] = v4;
+ right_array[1] = v1;
+ right_section = 1;
+
+ height = v3->y - v1->y; if(height == 0) height=1;
+ longest1 = (((v2->y - v1->y) << 16) / height) * ((v3->x - v1->x)>>16) + (v1->x - v2->x);
+ if(longest1<0)
+ {
+ left_array[0] = v4; // 1
+ left_array[1] = v3; // 3
+ left_array[2] = v1; // 4
+ left_section = 2;
+ }
+ else
+ {
+ height = v4->y - v2->y; if(height == 0) height=1;
+ longest1 = (((v3->y - v2->y) << 16) / height) * ((v4->x - v2->x)>>16) + (v2->x - v3->x);
+ if(longest1<0)
+ {
+ left_array[0] = v4; // 1
+ left_array[1] = v2; // 2
+ left_array[2] = v1; // 4
+ left_section = 2;
+ }
+ else
+ {
+ left_array[0] = v4; // 1
+ left_array[1] = v3; // 2
+ left_array[2] = v2; // 3
+ left_array[3] = v1; // 4
+ left_section = 3;
+ }
+ }
+ }
+ }
+
+ while(LeftSection_GT4()<=0)
+ {
+ if(--left_section <= 0) break;
+ }
+
+ while(RightSection_GT4()<=0)
+ {
+ if(--right_section <= 0) break;
+ }
+
+ Ymin=v1->y;
+ Ymax=min(v4->y-1,drawH);
+
+ return TRUE;
+}
+
+////////////////////////////////////////////////////////////////////////
+// POLY FUNCS
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+// POLY 3/4 FLAT SHADED
+////////////////////////////////////////////////////////////////////////
+
+__inline void drawPoly3Fi(short x1, short y1, short x2, short y2, short x3, short y3, int rgb)
+{
+ int i,j,xmin,xmax,ymin,ymax;
+ unsigned short color;
+ uint32_t lcolor;
+
+ if(x1>drawW && x2>drawW && x3>drawW) return;
+ if(y1>drawH && y2>drawH && y3>drawH) return;
+ if(x1<drawX && x2<drawX && x3<drawX) return;
+ if(y1<drawY && y2<drawY && y3<drawY) return;
+ if(drawY>=drawH) return;
+ if(drawX>=drawW) return;
+
+ if(!SetupSections_F(x1,y1,x2,y2,x3,y3)) return;
+
+ ymax=Ymax;
+
+ color = ((rgb & 0x00f80000)>>9) | ((rgb & 0x0000f800)>>6) | ((rgb & 0x000000f8)>>3);
+ lcolor=lSetMask|(((uint32_t)(color))<<16)|color;
+
+ for(ymin=Ymin;ymin<drawY;ymin++)
+ if(NextRow_F()) return;
+
+#ifdef FASTSOLID
+
+ if(!bCheckMask && !DrawSemiTrans)
+ {
+ color |=sSetMask;
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=left_x >> 16; if(drawX>xmin) xmin=drawX;
+ xmax=(right_x >> 16)-1; if(drawW<xmax) xmax=drawW;
+
+ for(j=xmin;j<xmax;j+=2)
+ {
+ *((uint32_t *)&psxVuw[(i<<10)+j])=lcolor;
+ }
+ if(j==xmax) psxVuw[(i<<10)+j]=color;
+
+ if(NextRow_F()) return;
+ }
+ return;
+ }
+
+#endif
+
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=left_x >> 16; if(drawX>xmin) xmin=drawX;
+ xmax=(right_x >> 16)-1; if(drawW<xmax) xmax=drawW;
+
+ for(j=xmin;j<xmax;j+=2)
+ {
+ GetShadeTransCol32((uint32_t *)&psxVuw[(i<<10)+j], lcolor);
+ }
+ if(j == xmax)
+ GetShadeTransCol(&psxVuw[(i << 10) + j],color);
+
+ if(NextRow_F()) return;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void drawPoly3F(int rgb)
+{
+ drawPoly3Fi(lx0,ly0,lx1,ly1,lx2,ly2,rgb);
+}
+
+#ifdef POLYQUAD3FS
+
+void drawPoly4F_TRI(int rgb)
+{
+ drawPoly3Fi(lx1,ly1,lx3,ly3,lx2,ly2,rgb);
+ drawPoly3Fi(lx0,ly0,lx1,ly1,lx2,ly2,rgb);
+}
+
+#endif
+
+// more exact:
+
+void drawPoly4F(int rgb)
+{
+ int i,j,xmin,xmax,ymin,ymax;
+ unsigned short color;unsigned int lcolor;
+
+ if(lx0>drawW && lx1>drawW && lx2>drawW && lx3>drawW) return;
+ if(ly0>drawH && ly1>drawH && ly2>drawH && ly3>drawH) return;
+ if(lx0<drawX && lx1<drawX && lx2<drawX && lx3<drawX) return;
+ if(ly0<drawY && ly1<drawY && ly2<drawY && ly3<drawY) return;
+ if(drawY>=drawH) return;
+ if(drawX>=drawW) return;
+
+ if(!SetupSections_F4(lx0,ly0,lx1,ly1,lx2,ly2,lx3,ly3)) return;
+
+ ymax=Ymax;
+
+ for(ymin=Ymin;ymin<drawY;ymin++)
+ if(NextRow_F4()) return;
+
+ color = ((rgb & 0x00f80000)>>9) | ((rgb & 0x0000f800)>>6) | ((rgb & 0x000000f8)>>3);
+ lcolor= lSetMask|(((uint32_t)(color))<<16)|color;
+
+#ifdef FASTSOLID
+
+ if(!bCheckMask && !DrawSemiTrans)
+ {
+ color |=sSetMask;
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=left_x >> 16; if(drawX>xmin) xmin=drawX;
+ xmax=(right_x >> 16)-1; if(drawW<xmax) xmax=drawW;
+
+ for(j=xmin;j<xmax;j+=2)
+ {
+ *((uint32_t *)&psxVuw[(i<<10)+j])=lcolor;
+ }
+ if(j==xmax) psxVuw[(i<<10)+j]=color;
+
+ if(NextRow_F4()) return;
+ }
+ return;
+ }
+
+#endif
+
+ for (i = ymin; i <= ymax; i++)
+ {
+ xmin = left_x >> 16; if(drawX > xmin) xmin = drawX;
+ xmax = (right_x >> 16) - 1; if(drawW < xmax) xmax = drawW;
+
+ for(j = xmin; j < xmax; j += 2)
+ {
+ GetShadeTransCol32((uint32_t *)&psxVuw[(i<<10) + j],lcolor);
+ }
+ if(j == xmax) GetShadeTransCol(&psxVuw[(i<<10) + j],color);
+
+ if(NextRow_F4()) return;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+// POLY 3/4 F-SHADED TEX PAL 4
+////////////////////////////////////////////////////////////////////////
+
+void drawPoly3TEx4(short x1, short y1, short x2, short y2, short x3, short y3, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3,short clX, short clY)
+{
+ int i,j,xmin,xmax,ymin,ymax;
+ int difX, difY,difX2, difY2;
+ int posX,posY,YAdjust,XAdjust;
+ int clutP;
+ short tC1,tC2;
+
+ if (x1 > drawW && x2 > drawW && x3 > drawW) return;
+ if (y1 > drawH && y2 > drawH && y3 > drawH) return;
+ if (x1 < drawX && x2 < drawX && x3 < drawX) return;
+ if (y1 < drawY && y2 < drawY && y3 < drawY) return;
+ if (drawY >= drawH) return;
+ if (drawX >= drawW) return;
+
+ if (!SetupSections_FT(x1,y1,x2,y2,x3,y3,tx1,ty1,tx2,ty2,tx3,ty3)) return;
+
+ ymax = Ymax;
+
+ for (ymin = Ymin; ymin < drawY; ymin++)
+ if (NextRow_FT()) return;
+
+ clutP = (clY << 10) + clX;
+
+ YAdjust = ((GlobalTextAddrY) << 11) + (GlobalTextAddrX << 1);
+
+ difX = delta_right_u; difX2 = difX << 1;
+ difY = delta_right_v; difY2 = difY << 1;
+
+#ifdef FASTSOLID
+
+ if(!bCheckMask && !DrawSemiTrans)
+ {
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=(left_x >> 16);
+ xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!!!!
+ if(drawW<xmax) xmax=drawW;
+
+ if(xmax>=xmin)
+ {
+ posX=left_u;
+ posY=left_v;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
+
+ for(j=xmin;j<xmax;j+=2)
+ {
+ XAdjust=(posX>>16);
+ tC1 = psxVub[((posY>>5)&(int)0xFFFFF800)+YAdjust+(XAdjust>>1)];
+ tC1=(tC1>>((XAdjust&1)<<2))&0xf;
+ XAdjust=((posX+difX)>>16);
+ tC2 = psxVub[(((posY+difY)>>5)&(int)0xFFFFF800)+YAdjust+
+ (XAdjust>>1)];
+ tC2=(tC2>>((XAdjust&1)<<2))&0xf;
+
+ GetTextureTransColG32_S((uint32_t *)&psxVuw[(i<<10)+j],
+ psxVuw[clutP+tC1]|
+ ((int)psxVuw[clutP+tC2])<<16);
+
+ posX+=difX2;
+ posY+=difY2;
+ }
+ if(j==xmax)
+ {
+ XAdjust=(posX>>16);
+ tC1 = psxVub[((posY>>5)&(int)0xFFFFF800)+YAdjust+
+ (XAdjust>>1)];
+ tC1=(tC1>>((XAdjust&1)<<2))&0xf;
+ GetTextureTransColG_S(&psxVuw[(i<<10)+j],psxVuw[clutP+tC1]);
+ }
+ }
+ if(NextRow_FT())
+ {
+ return;
+ }
+ }
+ return;
+ }
+
+#endif
+
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=(left_x >> 16);
+ xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!!!!!!
+ if(drawW<xmax) xmax=drawW;
+
+ if(xmax>=xmin)
+ {
+ posX=left_u;
+ posY=left_v;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
+
+ for(j=xmin;j<xmax;j+=2)
+ {
+ XAdjust=(posX>>16);
+ tC1 = psxVub[((posY>>5)&(int)0xFFFFF800)+YAdjust+(XAdjust>>1)];
+ tC1=(tC1>>((XAdjust&1)<<2))&0xf;
+ XAdjust=((posX+difX)>>16);
+ tC2 = psxVub[(((posY+difY)>>5)&(int)0xFFFFF800)+YAdjust+
+ (XAdjust>>1)];
+ tC2=(tC2>>((XAdjust&1)<<2))&0xf;
+
+ GetTextureTransColG32((uint32_t *)&psxVuw[(i<<10)+j],
+ psxVuw[clutP+tC1]|
+ ((int)psxVuw[clutP+tC2])<<16);
+
+ posX+=difX2;
+ posY+=difY2;
+ }
+ if(j==xmax)
+ {
+ XAdjust=(posX>>16);
+ tC1 = psxVub[((posY>>5)&(int)0xFFFFF800)+YAdjust+
+ (XAdjust>>1)];
+ tC1=(tC1>>((XAdjust&1)<<2))&0xf;
+ GetTextureTransColG(&psxVuw[(i<<10)+j],psxVuw[clutP+tC1]);
+ }
+ }
+ if(NextRow_FT())
+ {
+ return;
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void drawPoly3TEx4_IL(short x1, short y1, short x2, short y2, short x3, short y3, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3,short clX, short clY)
+{
+ int i,j,xmin,xmax,ymin,ymax,n_xi,n_yi,TXV;
+ int difX, difY,difX2, difY2;
+ int posX,posY,YAdjust,XAdjust;
+ int clutP;
+ short tC1,tC2;
+
+ if(x1>drawW && x2>drawW && x3>drawW) return;
+ if(y1>drawH && y2>drawH && y3>drawH) return;
+ if(x1<drawX && x2<drawX && x3<drawX) return;
+ if(y1<drawY && y2<drawY && y3<drawY) return;
+ if(drawY>=drawH) return;
+ if(drawX>=drawW) return;
+
+ if(!SetupSections_FT(x1,y1,x2,y2,x3,y3,tx1,ty1,tx2,ty2,tx3,ty3)) return;
+
+ ymax=Ymax;
+
+ for(ymin=Ymin;ymin<drawY;ymin++)
+ if(NextRow_FT()) return;
+
+ clutP=(clY<<10)+clX;
+
+ YAdjust=(GlobalTextAddrY<<10)+GlobalTextAddrX;
+
+ difX=delta_right_u;difX2=difX<<1;
+ difY=delta_right_v;difY2=difY<<1;
+
+#ifdef FASTSOLID
+
+ if(!bCheckMask && !DrawSemiTrans)
+ {
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=(left_x >> 16);
+ xmax=(right_x >> 16)-1;
+ if(drawW<xmax) xmax=drawW;
+
+ if(xmax>=xmin)
+ {
+ posX=left_u;
+ posY=left_v;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
+
+ for(j=xmin;j<xmax;j+=2)
+ {
+ XAdjust=(posX>>16);
+
+ TXV=posY>>16;
+ n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );
+ n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf );
+
+ tC1= (psxVuw[(n_yi<<10)+YAdjust+n_xi] >> ((XAdjust & 0x03)<<2)) & 0x0f ;
+
+ XAdjust=((posX+difX)>>16);
+
+ TXV=(posY+difY)>>16;
+ n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );
+ n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf );
+
+ tC2= (psxVuw[(n_yi<<10)+YAdjust+n_xi] >> ((XAdjust & 0x03)<<2)) & 0x0f ;
+
+ GetTextureTransColG32_S((uint32_t *)&psxVuw[(i<<10)+j],
+ psxVuw[clutP+tC1]|
+ ((int)psxVuw[clutP+tC2])<<16);
+
+ posX+=difX2;
+ posY+=difY2;
+ }
+ if(j==xmax)
+ {
+ XAdjust=(posX>>16);
+
+ TXV=posY>>16;
+ n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );
+ n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf );
+
+ tC1= (psxVuw[(n_yi<<10)+YAdjust+n_xi] >> ((XAdjust & 0x03)<<2)) & 0x0f ;
+
+ GetTextureTransColG_S(&psxVuw[(i<<10)+j],psxVuw[clutP+tC1]);
+ }
+ }
+ if(NextRow_FT())
+ {
+ return;
+ }
+ }
+ return;
+ }
+
+#endif
+
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=(left_x >> 16);
+ xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!!!!!!
+ if(drawW<xmax) xmax=drawW;
+
+ if(xmax>=xmin)
+ {
+ posX=left_u;
+ posY=left_v;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
+
+ for(j=xmin;j<xmax;j+=2)
+ {
+ XAdjust=(posX>>16);
+
+ TXV=posY>>16;
+ n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );
+ n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf );
+
+ tC1= (psxVuw[(n_yi<<10)+YAdjust+n_xi] >> ((XAdjust & 0x03)<<2)) & 0x0f ;
+
+ XAdjust=((posX+difX)>>16);
+
+ TXV=(posY+difY)>>16;
+ n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );
+ n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf );
+
+ tC2= (psxVuw[(n_yi<<10)+YAdjust+n_xi] >> ((XAdjust & 0x03)<<2)) & 0x0f ;
+
+ GetTextureTransColG32((uint32_t *)&psxVuw[(i<<10)+j],
+ psxVuw[clutP+tC1]|
+ ((int)psxVuw[clutP+tC2])<<16);
+
+ posX+=difX2;
+ posY+=difY2;
+ }
+ if(j==xmax)
+ {
+ XAdjust=(posX>>16);
+
+ TXV=posY>>16;
+ n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );
+ n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf );
+
+ tC1= (psxVuw[(n_yi<<10)+YAdjust+n_xi] >> ((XAdjust & 0x03)<<2)) & 0x0f ;
+
+ GetTextureTransColG(&psxVuw[(i<<10)+j],psxVuw[clutP+tC1]);
+ }
+ }
+ if(NextRow_FT())
+ {
+ return;
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void drawPoly3TEx4_TW(short x1, short y1, short x2, short y2, short x3, short y3, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3,short clX, short clY)
+{
+ int i,j,xmin,xmax,ymin,ymax;
+ int difX, difY,difX2, difY2;
+ int posX,posY,YAdjust,XAdjust;
+ int clutP;
+ short tC1,tC2;
+
+ if(x1>drawW && x2>drawW && x3>drawW) return;
+ if(y1>drawH && y2>drawH && y3>drawH) return;
+ if(x1<drawX && x2<drawX && x3<drawX) return;
+ if(y1<drawY && y2<drawY && y3<drawY) return;
+ if(drawY>=drawH) return;
+ if(drawX>=drawW) return;
+
+ if(!SetupSections_FT(x1,y1,x2,y2,x3,y3,tx1,ty1,tx2,ty2,tx3,ty3)) return;
+
+ ymax=Ymax;
+
+ for(ymin=Ymin;ymin<drawY;ymin++)
+ if(NextRow_FT()) return;
+
+ clutP=(clY<<10)+clX;
+
+ YAdjust=((GlobalTextAddrY)<<11)+(GlobalTextAddrX<<1);
+ YAdjust+=(TWin.Position.y0<<11)+(TWin.Position.x0>>1);
+
+ difX=delta_right_u;difX2=difX<<1;
+ difY=delta_right_v;difY2=difY<<1;
+
+#ifdef FASTSOLID
+
+ if(!bCheckMask && !DrawSemiTrans)
+ {
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=(left_x >> 16);
+ xmax=(right_x >> 16);//-1; //!!!!!!!!!!!!!!!!
+ if(xmax>xmin) xmax--;
+
+ if(drawW<xmax) xmax=drawW;
+
+ if(xmax>=xmin)
+ {
+ posX=left_u;
+ posY=left_v;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
+
+ for(j=xmin;j<xmax;j+=2)
+ {
+ XAdjust=(posX>>16)%TWin.Position.x1;
+ tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+
+ YAdjust+(XAdjust>>1)];
+ tC1=(tC1>>((XAdjust&1)<<2))&0xf;
+ XAdjust=((posX+difX)>>16)%TWin.Position.x1;
+ tC2 = psxVub[((((posY+difY)>>16)%TWin.Position.y1)<<11)+
+ YAdjust+(XAdjust>>1)];
+ tC2=(tC2>>((XAdjust&1)<<2))&0xf;
+
+ GetTextureTransColG32_S((uint32_t *)&psxVuw[(i << 10) + j],
+ psxVuw[clutP+tC1]|
+ ((int)psxVuw[clutP+tC2])<<16);
+
+ posX+=difX2;
+ posY+=difY2;
+ }
+ if(j==xmax)
+ {
+ XAdjust=(posX>>16)%TWin.Position.x1;
+ tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+
+ YAdjust+(XAdjust>>1)];
+ tC1=(tC1>>((XAdjust&1)<<2))&0xf;
+ GetTextureTransColG_S(&psxVuw[(i<<10)+j],psxVuw[clutP+tC1]);
+ }
+ }
+ if(NextRow_FT())
+ {
+ return;
+ }
+ }
+ return;
+ }
+
+#endif
+
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=(left_x >> 16);
+ xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!!!!!!
+ if(drawW<xmax) xmax=drawW;
+
+ if(xmax>=xmin)
+ {
+ posX=left_u;
+ posY=left_v;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
+
+ for(j=xmin;j<xmax;j+=2)
+ {
+ XAdjust=(posX>>16)%TWin.Position.x1;
+ tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+
+ YAdjust+(XAdjust>>1)];
+ tC1=(tC1>>((XAdjust&1)<<2))&0xf;
+ XAdjust=((posX+difX)>>16)%TWin.Position.x1;
+ tC2 = psxVub[((((posY+difY)>>16)%TWin.Position.y1)<<11)+
+ YAdjust+(XAdjust>>1)];
+ tC2=(tC2>>((XAdjust&1)<<2))&0xf;
+
+ GetTextureTransColG32((uint32_t *)&psxVuw[(i<<10)+j],
+ psxVuw[clutP+tC1]|
+ ((int)psxVuw[clutP+tC2])<<16);
+
+ posX+=difX2;
+ posY+=difY2;
+ }
+ if(j==xmax)
+ {
+ XAdjust=(posX>>16)%TWin.Position.x1;
+ tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+
+ YAdjust+(XAdjust>>1)];
+ tC1=(tC1>>((XAdjust&1)<<2))&0xf;
+ GetTextureTransColG(&psxVuw[(i<<10)+j],psxVuw[clutP+tC1]);
+ }
+ }
+ if(NextRow_FT())
+ {
+ return;
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+#ifdef POLYQUAD3
+
+void drawPoly4TEx4_TRI(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4,short clX, short clY)
+{
+ drawPoly3TEx4(x2,y2,x3,y3,x4,y4,
+ tx2,ty2,tx3,ty3,tx4,ty4,
+ clX,clY);
+ drawPoly3TEx4(x1,y1,x2,y2,x4,y4,
+ tx1,ty1,tx2,ty2,tx4,ty4,
+ clX,clY);
+}
+
+#endif
+
+// more exact:
+
+void drawPoly4TEx4(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4,short clX, short clY)
+{
+ int num;
+ int i,j,xmin,xmax,ymin,ymax;
+ int difX, difY, difX2, difY2;
+ int posX,posY,YAdjust,clutP,XAdjust;
+ short tC1,tC2;
+
+ if(x1>drawW && x2>drawW && x3>drawW && x4>drawW) return;
+ if(y1>drawH && y2>drawH && y3>drawH && y4>drawH) return;
+ if(x1<drawX && x2<drawX && x3<drawX && x4<drawX) return;
+ if(y1<drawY && y2<drawY && y3<drawY && y4<drawY) return;
+ if(drawY>=drawH) return;
+ if(drawX>=drawW) return;
+
+ if(!SetupSections_FT4(x1,y1,x2,y2,x3,y3,x4,y4,tx1,ty1,tx2,ty2,tx3,ty3,tx4,ty4)) return;
+
+ ymax=Ymax;
+
+ for(ymin=Ymin;ymin<drawY;ymin++)
+ if(NextRow_FT4()) return;
+
+ clutP=(clY<<10)+clX;
+
+ YAdjust=((GlobalTextAddrY)<<11)+(GlobalTextAddrX<<1);
+
+#ifdef FASTSOLID
+
+ if(!bCheckMask && !DrawSemiTrans)
+ {
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=(left_x >> 16);
+ xmax=(right_x >> 16);
+
+ if(xmax>=xmin)
+ {
+ posX=left_u;
+ posY=left_v;
+
+ num=(xmax-xmin);
+ if(num==0) num=1;
+ difX=(right_u-posX)/num;
+ difY=(right_v-posY)/num;
+ difX2=difX<<1;
+ difY2=difY<<1;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
+ xmax--;if(drawW<xmax) xmax=drawW;
+
+ for(j=xmin;j<xmax;j+=2)
+ {
+ XAdjust=(posX>>16);
+ tC1 = psxVub[((posY>>5)&(int)0xFFFFF800)+YAdjust+(XAdjust>>1)];
+ tC1=(tC1>>((XAdjust&1)<<2))&0xf;
+ XAdjust=((posX+difX)>>16);
+ tC2 = psxVub[(((posY+difY)>>5)&(int)0xFFFFF800)+YAdjust+
+ (XAdjust>>1)];
+ tC2=(tC2>>((XAdjust&1)<<2))&0xf;
+
+ GetTextureTransColG32_S((uint32_t *)&psxVuw[(i<<10)+j],
+ psxVuw[clutP+tC1]|
+ ((int)psxVuw[clutP+tC2])<<16);
+ posX+=difX2;
+ posY+=difY2;
+ }
+ if(j==xmax)
+ {
+ XAdjust=(posX>>16);
+ tC1 = psxVub[((posY>>5)&(int)0xFFFFF800)+YAdjust+
+ (XAdjust>>1)];
+ tC1=(tC1>>((XAdjust&1)<<2))&0xf;
+ GetTextureTransColG_S(&psxVuw[(i<<10)+j],psxVuw[clutP+tC1]);
+ }
+
+ }
+ if(NextRow_FT4()) return;
+ }
+ return;
+ }
+
+#endif
+
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=(left_x >> 16);
+ xmax=(right_x >> 16);
+
+ if(xmax>=xmin)
+ {
+ posX=left_u;
+ posY=left_v;
+
+ num=(xmax-xmin);
+ if(num==0) num=1;
+ difX=(right_u-posX)/num;
+ difY=(right_v-posY)/num;
+ difX2=difX<<1;
+ difY2=difY<<1;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
+ xmax--;if(drawW<xmax) xmax=drawW;
+
+ for(j=xmin;j<xmax;j+=2)
+ {
+ XAdjust=(posX>>16);
+ tC1 = psxVub[((posY>>5)&(int)0xFFFFF800)+YAdjust+(XAdjust>>1)];
+ tC1=(tC1>>((XAdjust&1)<<2))&0xf;
+ XAdjust=((posX+difX)>>16);
+ tC2 = psxVub[(((posY+difY)>>5)&(int)0xFFFFF800)+YAdjust+
+ (XAdjust>>1)];
+ tC2=(tC2>>((XAdjust&1)<<2))&0xf;
+
+ GetTextureTransColG32((uint32_t *)&psxVuw[(i<<10)+j],
+ psxVuw[clutP+tC1]|
+ ((int)psxVuw[clutP+tC2])<<16);
+ posX+=difX2;
+ posY+=difY2;
+ }
+ if(j==xmax)
+ {
+ XAdjust=(posX>>16);
+ tC1 = psxVub[((posY>>5)&(int)0xFFFFF800)+YAdjust+
+ (XAdjust>>1)];
+ tC1=(tC1>>((XAdjust&1)<<2))&0xf;
+ GetTextureTransColG(&psxVuw[(i<<10)+j],psxVuw[clutP+tC1]);
+ }
+ }
+ if(NextRow_FT4()) return;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void drawPoly4TEx4_IL(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4,short clX, short clY)
+{
+ int num;
+ int i,j,xmin,xmax,ymin,ymax,n_xi,n_yi,TXV;
+ int difX, difY, difX2, difY2;
+ int posX,posY,YAdjust,clutP,XAdjust;
+ short tC1,tC2;
+
+ if(x1>drawW && x2>drawW && x3>drawW && x4>drawW) return;
+ if(y1>drawH && y2>drawH && y3>drawH && y4>drawH) return;
+ if(x1<drawX && x2<drawX && x3<drawX && x4<drawX) return;
+ if(y1<drawY && y2<drawY && y3<drawY && y4<drawY) return;
+ if(drawY>=drawH) return;
+ if(drawX>=drawW) return;
+
+ if(!SetupSections_FT4(x1,y1,x2,y2,x3,y3,x4,y4,tx1,ty1,tx2,ty2,tx3,ty3,tx4,ty4)) return;
+
+ ymax=Ymax;
+
+ for(ymin=Ymin;ymin<drawY;ymin++)
+ if(NextRow_FT4()) return;
+
+ clutP=(clY<<10)+clX;
+
+ YAdjust=((GlobalTextAddrY)<<10)+GlobalTextAddrX;
+
+#ifdef FASTSOLID
+
+ if(!bCheckMask && !DrawSemiTrans)
+ {
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=(left_x >> 16);
+ xmax=(right_x >> 16);
+
+ if(xmax>=xmin)
+ {
+ posX=left_u;
+ posY=left_v;
+
+ num=(xmax-xmin);
+ if(num==0) num=1;
+ difX=(right_u-posX)/num;
+ difY=(right_v-posY)/num;
+ difX2=difX<<1;
+ difY2=difY<<1;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
+ xmax--;if(drawW<xmax) xmax=drawW;
+
+ for(j=xmin;j<xmax;j+=2)
+ {
+ XAdjust=(posX>>16);
+
+ TXV=posY>>16;
+ n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );
+ n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf );
+
+ tC1= (psxVuw[(n_yi<<10)+YAdjust+n_xi] >> ((XAdjust & 0x03)<<2)) & 0x0f ;
+
+ XAdjust=((posX+difX)>>16);
+
+ TXV=(posY+difY)>>16;
+ n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );
+ n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf );
+
+ tC2= (psxVuw[(n_yi<<10)+YAdjust+n_xi] >> ((XAdjust & 0x03)<<2)) & 0x0f ;
+
+ GetTextureTransColG32_S((uint32_t *)&psxVuw[(i<<10)+j],
+ psxVuw[clutP+tC1]|
+ ((int)psxVuw[clutP+tC2])<<16);
+ posX+=difX2;
+ posY+=difY2;
+ }
+
+ if(j==xmax)
+ {
+ XAdjust=(posX>>16);
+ TXV=posY>>16;
+ n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );
+ n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf );
+
+ tC1= (psxVuw[(n_yi<<10)+YAdjust+n_xi] >> ((XAdjust & 0x03)<<2)) & 0x0f ;
+
+ GetTextureTransColG_S(&psxVuw[(i<<10)+j],psxVuw[clutP+tC1]);
+ }
+
+ }
+ if(NextRow_FT4()) return;
+ }
+ return;
+ }
+
+#endif
+
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=(left_x >> 16);
+ xmax=(right_x >> 16);
+
+ if(xmax>=xmin)
+ {
+ posX=left_u;
+ posY=left_v;
+
+ num=(xmax-xmin);
+ if(num==0) num=1;
+ difX=(right_u-posX)/num;
+ difY=(right_v-posY)/num;
+ difX2=difX<<1;
+ difY2=difY<<1;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
+ xmax--;if(drawW<xmax) xmax=drawW;
+
+ for(j=xmin;j<xmax;j+=2)
+ {
+ XAdjust=(posX>>16);
+
+ TXV=posY>>16;
+ n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );
+ n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf );
+
+ tC1= (psxVuw[(n_yi<<10)+YAdjust+n_xi] >> ((XAdjust & 0x03)<<2)) & 0x0f ;
+
+ XAdjust=((posX+difX)>>16);
+
+ TXV=(posY+difY)>>16;
+ n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );
+ n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf );
+
+ tC2= (psxVuw[(n_yi<<10)+YAdjust+n_xi] >> ((XAdjust & 0x03)<<2)) & 0x0f ;
+
+ GetTextureTransColG32((uint32_t *)&psxVuw[(i<<10)+j],
+ psxVuw[clutP+tC1]|
+ ((int)psxVuw[clutP+tC2])<<16);
+ posX+=difX2;
+ posY+=difY2;
+ }
+ if(j==xmax)
+ {
+ XAdjust=(posX>>16);
+ TXV=posY>>16;
+ n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );
+ n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf );
+
+ tC1= (psxVuw[(n_yi<<10)+YAdjust+n_xi] >> ((XAdjust & 0x03)<<2)) & 0x0f ;
+
+ GetTextureTransColG(&psxVuw[(i<<10)+j],psxVuw[clutP+tC1]);
+ }
+ }
+ if(NextRow_FT4()) return;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void drawPoly4TEx4_TW(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4,short clX, short clY)
+{
+ int num;
+ int i,j,xmin,xmax,ymin,ymax;
+ int difX, difY, difX2, difY2;
+ int posX,posY,YAdjust,clutP,XAdjust;
+ short tC1,tC2;
+
+ if(x1>drawW && x2>drawW && x3>drawW && x4>drawW) return;
+ if(y1>drawH && y2>drawH && y3>drawH && y4>drawH) return;
+ if(x1<drawX && x2<drawX && x3<drawX && x4<drawX) return;
+ if(y1<drawY && y2<drawY && y3<drawY && y4<drawY) return;
+ if(drawY>=drawH) return;
+ if(drawX>=drawW) return;
+
+ if(!SetupSections_FT4(x1,y1,x2,y2,x3,y3,x4,y4,tx1,ty1,tx2,ty2,tx3,ty3,tx4,ty4)) return;
+
+ ymax=Ymax;
+
+ for(ymin=Ymin;ymin<drawY;ymin++)
+ if(NextRow_FT4()) return;
+
+ clutP=(clY<<10)+clX;
+
+ YAdjust=((GlobalTextAddrY)<<11)+(GlobalTextAddrX<<1);
+ YAdjust+=(TWin.Position.y0<<11)+(TWin.Position.x0>>1);
+
+#ifdef FASTSOLID
+
+ if(!bCheckMask && !DrawSemiTrans)
+ {
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=(left_x >> 16);
+ xmax=(right_x >> 16);
+
+ if(xmax>=xmin)
+ {
+ posX=left_u;
+ posY=left_v;
+
+ num=(xmax-xmin);
+ if(num==0) num=1;
+ difX=(right_u-posX)/num;
+ difY=(right_v-posY)/num;
+ difX2=difX<<1;
+ difY2=difY<<1;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
+ xmax--;if(drawW<xmax) xmax=drawW;
+
+ for(j=xmin;j<xmax;j+=2)
+ {
+ XAdjust=(posX>>16)%TWin.Position.x1;
+ tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+
+ YAdjust+(XAdjust>>1)];
+ tC1=(tC1>>((XAdjust&1)<<2))&0xf;
+ XAdjust=((posX+difX)>>16)%TWin.Position.x1;
+ tC2 = psxVub[((((posY+difY)>>16)%TWin.Position.y1)<<11)+
+ YAdjust+(XAdjust>>1)];
+ tC2=(tC2>>((XAdjust&1)<<2))&0xf;
+
+ GetTextureTransColG32_S((uint32_t *)&psxVuw[(i<<10)+j],
+ psxVuw[clutP+tC1]|
+ ((int)psxVuw[clutP+tC2])<<16);
+ posX+=difX2;
+ posY+=difY2;
+ }
+ if(j==xmax)
+ {
+ XAdjust=(posX>>16)%TWin.Position.x1;
+ tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+
+ YAdjust+(XAdjust>>1)];
+ tC1=(tC1>>((XAdjust&1)<<2))&0xf;
+ GetTextureTransColG_S(&psxVuw[(i<<10)+j],psxVuw[clutP+tC1]);
+ }
+ }
+ if(NextRow_FT4()) return;
+ }
+ return;
+ }
+
+#endif
+
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=(left_x >> 16);
+ xmax=(right_x >> 16);
+
+ if(xmax>=xmin)
+ {
+ posX=left_u;
+ posY=left_v;
+
+ num=(xmax-xmin);
+ if(num==0) num=1;
+ difX=(right_u-posX)/num;
+ difY=(right_v-posY)/num;
+ difX2=difX<<1;
+ difY2=difY<<1;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
+ xmax--;if(drawW<xmax) xmax=drawW;
+
+ for(j=xmin;j<xmax;j+=2)
+ {
+ XAdjust=(posX>>16)%TWin.Position.x1;
+ tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+
+ YAdjust+(XAdjust>>1)];
+ tC1=(tC1>>((XAdjust&1)<<2))&0xf;
+ XAdjust=((posX+difX)>>16)%TWin.Position.x1;
+ tC2 = psxVub[((((posY+difY)>>16)%TWin.Position.y1)<<11)+
+ YAdjust+(XAdjust>>1)];
+ tC2=(tC2>>((XAdjust&1)<<2))&0xf;
+
+ GetTextureTransColG32((uint32_t *)&psxVuw[(i<<10)+j],
+ psxVuw[clutP+tC1]|
+ ((int)psxVuw[clutP+tC2])<<16);
+ posX+=difX2;
+ posY+=difY2;
+ }
+ if(j==xmax)
+ {
+ XAdjust=(posX>>16)%TWin.Position.x1;
+ tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+
+ YAdjust+(XAdjust>>1)];
+ tC1=(tC1>>((XAdjust&1)<<2))&0xf;
+ GetTextureTransColG(&psxVuw[(i<<10)+j],psxVuw[clutP+tC1]);
+ }
+ }
+ if(NextRow_FT4()) return;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void drawPoly4TEx4_TW_S(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4,short clX, short clY)
+{
+ int num;
+ int i,j,xmin,xmax,ymin,ymax;
+ int difX, difY, difX2, difY2;
+ int posX,posY,YAdjust,clutP,XAdjust;
+ short tC1,tC2;
+
+ if(x1>drawW && x2>drawW && x3>drawW && x4>drawW) return;
+ if(y1>drawH && y2>drawH && y3>drawH && y4>drawH) return;
+ if(x1<drawX && x2<drawX && x3<drawX && x4<drawX) return;
+ if(y1<drawY && y2<drawY && y3<drawY && y4<drawY) return;
+ if(drawY>=drawH) return;
+ if(drawX>=drawW) return;
+
+ if(!SetupSections_FT4(x1,y1,x2,y2,x3,y3,x4,y4,tx1,ty1,tx2,ty2,tx3,ty3,tx4,ty4)) return;
+
+ ymax=Ymax;
+
+ for(ymin=Ymin;ymin<drawY;ymin++)
+ if(NextRow_FT4()) return;
+
+ clutP=(clY<<10)+clX;
+
+ YAdjust=((GlobalTextAddrY)<<11)+(GlobalTextAddrX<<1);
+ YAdjust+=(TWin.Position.y0<<11)+(TWin.Position.x0>>1);
+
+#ifdef FASTSOLID
+
+ if(!bCheckMask && !DrawSemiTrans)
+ {
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=(left_x >> 16);
+ xmax=(right_x >> 16);
+
+ if(xmax>=xmin)
+ {
+ posX=left_u;
+ posY=left_v;
+
+ num=(xmax-xmin);
+ if(num==0) num=1;
+ difX=(right_u-posX)/num;
+ difY=(right_v-posY)/num;
+ difX2=difX<<1;
+ difY2=difY<<1;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
+ xmax--;if(drawW<xmax) xmax=drawW;
+
+ for(j=xmin;j<xmax;j+=2)
+ {
+ XAdjust=(posX>>16)%TWin.Position.x1;
+ tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+
+ YAdjust+(XAdjust>>1)];
+ tC1=(tC1>>((XAdjust&1)<<2))&0xf;
+ XAdjust=((posX+difX)>>16)%TWin.Position.x1;
+ tC2 = psxVub[((((posY+difY)>>16)%TWin.Position.y1)<<11)+
+ YAdjust+(XAdjust>>1)];
+ tC2=(tC2>>((XAdjust&1)<<2))&0xf;
+
+ GetTextureTransColG32_S((uint32_t *)&psxVuw[(i<<10)+j],
+ psxVuw[clutP+tC1]|
+ ((int)psxVuw[clutP+tC2])<<16);
+ posX+=difX2;
+ posY+=difY2;
+ }
+ if(j==xmax)
+ {
+ XAdjust=(posX>>16)%TWin.Position.x1;
+ tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+
+ YAdjust+(XAdjust>>1)];
+ tC1=(tC1>>((XAdjust&1)<<2))&0xf;
+ GetTextureTransColG_S(&psxVuw[(i<<10)+j],psxVuw[clutP+tC1]);
+ }
+ }
+ if(NextRow_FT4()) return;
+ }
+ return;
+ }
+
+#endif
+
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=(left_x >> 16);
+ xmax=(right_x >> 16);
+
+ if(xmax>=xmin)
+ {
+ posX=left_u;
+ posY=left_v;
+
+ num=(xmax-xmin);
+ if(num==0) num=1;
+ difX=(right_u-posX)/num;
+ difY=(right_v-posY)/num;
+ difX2=difX<<1;
+ difY2=difY<<1;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
+ xmax--;if(drawW<xmax) xmax=drawW;
+
+ for(j=xmin;j<xmax;j+=2)
+ {
+ XAdjust=(posX>>16)%TWin.Position.x1;
+ tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+
+ YAdjust+(XAdjust>>1)];
+ tC1=(tC1>>((XAdjust&1)<<2))&0xf;
+ XAdjust=((posX+difX)>>16)%TWin.Position.x1;
+ tC2 = psxVub[((((posY+difY)>>16)%TWin.Position.y1)<<11)+
+ YAdjust+(XAdjust>>1)];
+ tC2=(tC2>>((XAdjust&1)<<2))&0xf;
+
+ GetTextureTransColG32_SPR((uint32_t *)&psxVuw[(i<<10)+j],
+ psxVuw[clutP+tC1]|
+ ((int)psxVuw[clutP+tC2])<<16);
+ posX+=difX2;
+ posY+=difY2;
+ }
+ if(j==xmax)
+ {
+ XAdjust=(posX>>16)%TWin.Position.x1;
+ tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+
+ YAdjust+(XAdjust>>1)];
+ tC1=(tC1>>((XAdjust&1)<<2))&0xf;
+ GetTextureTransColG_SPR(&psxVuw[(i<<10)+j],psxVuw[clutP+tC1]);
+ }
+ }
+ if(NextRow_FT4()) return;
+ }
+}
+////////////////////////////////////////////////////////////////////////
+// POLY 3 F-SHADED TEX PAL 8
+////////////////////////////////////////////////////////////////////////
+
+void drawPoly3TEx8(short x1, short y1, short x2, short y2, short x3, short y3, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3,short clX, short clY)
+{
+ int i,j,xmin,xmax,ymin,ymax;
+ int difX, difY,difX2, difY2;
+ int posX,posY,YAdjust,clutP;
+ short tC1,tC2;
+
+ if(x1>drawW && x2>drawW && x3>drawW) return;
+ if(y1>drawH && y2>drawH && y3>drawH) return;
+ if(x1<drawX && x2<drawX && x3<drawX) return;
+ if(y1<drawY && y2<drawY && y3<drawY) return;
+ if(drawY>=drawH) return;
+ if(drawX>=drawW) return;
+
+ if(!SetupSections_FT(x1,y1,x2,y2,x3,y3,tx1,ty1,tx2,ty2,tx3,ty3)) return;
+
+ ymax=Ymax;
+
+ for(ymin=Ymin;ymin<drawY;ymin++)
+ if(NextRow_FT()) return;
+
+ clutP=(clY<<10)+clX;
+
+ YAdjust=((GlobalTextAddrY)<<11)+(GlobalTextAddrX<<1);
+
+ difX=delta_right_u;difX2=difX<<1;
+ difY=delta_right_v;difY2=difY<<1;
+
+#ifdef FASTSOLID
+
+ if(!bCheckMask && !DrawSemiTrans)
+ {
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=(left_x >> 16);
+ xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!!!
+ if(drawW<xmax) xmax=drawW;
+
+ if(xmax>=xmin)
+ {
+ posX=left_u;
+ posY=left_v;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
+
+ for(j=xmin;j<xmax;j+=2)
+ {
+ tC1 = psxVub[((posY>>5)&(int)0xFFFFF800)+YAdjust+(posX>>16)];
+ tC2 = psxVub[(((posY+difY)>>5)&(int)0xFFFFF800)+YAdjust+
+ ((posX+difX)>>16)];
+ GetTextureTransColG32_S((uint32_t *)&psxVuw[(i<<10)+j],
+ psxVuw[clutP+tC1]|
+ ((int)psxVuw[clutP+tC2])<<16);
+ posX+=difX2;
+ posY+=difY2;
+ }
+
+ if(j==xmax)
+ {
+ tC1 = psxVub[((posY>>5)&(int)0xFFFFF800)+YAdjust+(posX>>16)];
+ GetTextureTransColG_S(&psxVuw[(i<<10)+j],psxVuw[clutP+tC1]);
+ }
+ }
+ if(NextRow_FT())
+ {
+ return;
+ }
+ }
+ return;
+ }
+
+#endif
+
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=(left_x >> 16);
+ xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!!!!!
+ if(drawW<xmax) xmax=drawW;
+
+ if(xmax>=xmin)
+ {
+ posX=left_u;
+ posY=left_v;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
+
+ for(j=xmin;j<xmax;j+=2)
+ {
+ tC1 = psxVub[((posY>>5)&(int)0xFFFFF800)+YAdjust+(posX>>16)];
+ tC2 = psxVub[(((posY+difY)>>5)&(int)0xFFFFF800)+YAdjust+
+ ((posX+difX)>>16)];
+ GetTextureTransColG32((uint32_t *)&psxVuw[(i<<10)+j],
+ psxVuw[clutP+tC1]|
+ ((int)psxVuw[clutP+tC2])<<16);
+ posX+=difX2;
+ posY+=difY2;
+ }
+
+ if(j==xmax)
+ {
+ tC1 = psxVub[((posY>>5)&(int)0xFFFFF800)+YAdjust+(posX>>16)];
+ GetTextureTransColG(&psxVuw[(i<<10)+j],psxVuw[clutP+tC1]);
+ }
+
+ }
+ if(NextRow_FT())
+ {
+ return;
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void drawPoly3TEx8_IL(short x1, short y1, short x2, short y2, short x3, short y3, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3,short clX, short clY)
+{
+ int i,j,xmin,xmax,ymin,ymax,n_xi,n_yi,TXV,TXU;
+ int difX, difY,difX2, difY2;
+ int posX,posY,YAdjust,clutP;
+ short tC1,tC2;
+
+ if(x1>drawW && x2>drawW && x3>drawW) return;
+ if(y1>drawH && y2>drawH && y3>drawH) return;
+ if(x1<drawX && x2<drawX && x3<drawX) return;
+ if(y1<drawY && y2<drawY && y3<drawY) return;
+ if(drawY>=drawH) return;
+ if(drawX>=drawW) return;
+
+ if(!SetupSections_FT(x1,y1,x2,y2,x3,y3,tx1,ty1,tx2,ty2,tx3,ty3)) return;
+
+ ymax=Ymax;
+
+ for(ymin=Ymin;ymin<drawY;ymin++)
+ if(NextRow_FT()) return;
+
+ clutP=(clY<<10)+clX;
+
+ YAdjust=(GlobalTextAddrY<<10)+GlobalTextAddrX;
+
+ difX=delta_right_u;difX2=difX<<1;
+ difY=delta_right_v;difY2=difY<<1;
+
+#ifdef FASTSOLID
+
+ if(!bCheckMask && !DrawSemiTrans)
+ {
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=(left_x >> 16);
+ xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!!!
+ if(drawW<xmax) xmax=drawW;
+
+ if(xmax>=xmin)
+ {
+ posX=left_u;
+ posY=left_v;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
+
+ for(j=xmin;j<xmax;j+=2)
+ {
+ TXU=posX>>16;
+ TXV=posY>>16;
+ n_xi = ( ( TXU >> 1 ) & ~0x78 ) + ( ( TXU << 2 ) & 0x40 ) + ( ( TXV << 3 ) & 0x38 );
+ n_yi = ( TXV & ~0x7 ) + ( ( TXU >> 5 ) & 0x7 );
+
+ tC1= (psxVuw[(n_yi<<10)+YAdjust+n_xi] >> ((TXU & 0x01)<<3)) & 0xff;
+
+ TXU=(posX+difX)>>16;
+ TXV=(posY+difY)>>16;
+ n_xi = ( ( TXU >> 1 ) & ~0x78 ) + ( ( TXU << 2 ) & 0x40 ) + ( ( TXV << 3 ) & 0x38 );
+ n_yi = ( TXV & ~0x7 ) + ( ( TXU >> 5 ) & 0x7 );
+
+ tC2= (psxVuw[(n_yi<<10)+YAdjust+n_xi] >> ((TXU & 0x01)<<3)) & 0xff;
+
+ GetTextureTransColG32_S((uint32_t *)&psxVuw[(i<<10)+j],
+ psxVuw[clutP+tC1]|
+ ((int)psxVuw[clutP+tC2])<<16);
+ posX+=difX2;
+ posY+=difY2;
+ }
+
+ if(j==xmax)
+ {
+ TXU=posX>>16;
+ TXV=posY>>16;
+ n_xi = ( ( TXU >> 1 ) & ~0x78 ) + ( ( TXU << 2 ) & 0x40 ) + ( ( TXV << 3 ) & 0x38 );
+ n_yi = ( TXV & ~0x7 ) + ( ( TXU >> 5 ) & 0x7 );
+
+ tC1= (psxVuw[(n_yi<<10)+YAdjust+n_xi] >> ((TXU & 0x01)<<3)) & 0xff;
+
+ GetTextureTransColG_S(&psxVuw[(i<<10)+j],psxVuw[clutP+tC1]);
+ }
+ }
+ if(NextRow_FT())
+ {
+ return;
+ }
+ }
+ return;
+ }
+
+#endif
+
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=(left_x >> 16);
+ xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!!!!!
+ if(drawW<xmax) xmax=drawW;
+
+ if(xmax>=xmin)
+ {
+ posX=left_u;
+ posY=left_v;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
+
+ for(j=xmin;j<xmax;j+=2)
+ {
+ TXU=posX>>16;
+ TXV=posY>>16;
+ n_xi = ( ( TXU >> 1 ) & ~0x78 ) + ( ( TXU << 2 ) & 0x40 ) + ( ( TXV << 3 ) & 0x38 );
+ n_yi = ( TXV & ~0x7 ) + ( ( TXU >> 5 ) & 0x7 );
+
+ tC1= (psxVuw[(n_yi<<10)+YAdjust+n_xi] >> ((TXU & 0x01)<<3)) & 0xff;
+
+ TXU=(posX+difX)>>16;
+ TXV=(posY+difY)>>16;
+ n_xi = ( ( TXU >> 1 ) & ~0x78 ) + ( ( TXU << 2 ) & 0x40 ) + ( ( TXV << 3 ) & 0x38 );
+ n_yi = ( TXV & ~0x7 ) + ( ( TXU >> 5 ) & 0x7 );
+
+ tC2= (psxVuw[(n_yi<<10)+YAdjust+n_xi] >> ((TXU & 0x01)<<3)) & 0xff;
+
+ GetTextureTransColG32((uint32_t *)&psxVuw[(i<<10)+j],
+ psxVuw[clutP+tC1]|
+ ((int)psxVuw[clutP+tC2])<<16);
+ posX+=difX2;
+ posY+=difY2;
+ }
+
+ if(j==xmax)
+ {
+ TXU=posX>>16;
+ TXV=posY>>16;
+ n_xi = ( ( TXU >> 1 ) & ~0x78 ) + ( ( TXU << 2 ) & 0x40 ) + ( ( TXV << 3 ) & 0x38 );
+ n_yi = ( TXV & ~0x7 ) + ( ( TXU >> 5 ) & 0x7 );
+
+ tC1= (psxVuw[(n_yi<<10)+YAdjust+n_xi] >> ((TXU & 0x01)<<3)) & 0xff;
+
+ GetTextureTransColG(&psxVuw[(i<<10)+j],psxVuw[clutP+tC1]);
+ }
+
+ }
+ if(NextRow_FT())
+ {
+ return;
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void drawPoly3TEx8_TW(short x1, short y1, short x2, short y2, short x3, short y3, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3,short clX, short clY)
+{
+ int i,j,xmin,xmax,ymin,ymax;
+ int difX, difY,difX2, difY2;
+ int posX,posY,YAdjust,clutP;
+ short tC1,tC2;
+
+ if(x1>drawW && x2>drawW && x3>drawW) return;
+ if(y1>drawH && y2>drawH && y3>drawH) return;
+ if(x1<drawX && x2<drawX && x3<drawX) return;
+ if(y1<drawY && y2<drawY && y3<drawY) return;
+ if(drawY>=drawH) return;
+ if(drawX>=drawW) return;
+
+ if(!SetupSections_FT(x1,y1,x2,y2,x3,y3,tx1,ty1,tx2,ty2,tx3,ty3)) return;
+
+ ymax=Ymax;
+
+ for(ymin=Ymin;ymin<drawY;ymin++)
+ if(NextRow_FT()) return;
+
+ clutP=(clY<<10)+clX;
+
+ YAdjust=((GlobalTextAddrY)<<11)+(GlobalTextAddrX<<1);
+ YAdjust+=(TWin.Position.y0<<11)+(TWin.Position.x0);
+
+ difX=delta_right_u;difX2=difX<<1;
+ difY=delta_right_v;difY2=difY<<1;
+
+#ifdef FASTSOLID
+
+ if(!bCheckMask && !DrawSemiTrans)
+ {
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=(left_x >> 16);
+ xmax=(right_x >> 16);//-1; //!!!!!!!!!!!!!!!!
+ if(xmax>xmin) xmax--;
+
+ if(drawW<xmax) xmax=drawW;
+
+ if(xmax>=xmin)
+ {
+ posX=left_u;
+ posY=left_v;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
+
+ for(j=xmin;j<xmax;j+=2)
+ {
+ tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+
+ YAdjust+((posX>>16)%TWin.Position.x1)];
+ tC2 = psxVub[((((posY+difY)>>16)%TWin.Position.y1)<<11)+
+ YAdjust+(((posX+difX)>>16)%TWin.Position.x1)];
+ GetTextureTransColG32_S((uint32_t *)&psxVuw[(i<<10)+j],
+ psxVuw[clutP+tC1]|
+ ((int)psxVuw[clutP+tC2])<<16);
+ posX+=difX2;
+ posY+=difY2;
+ }
+
+ if(j==xmax)
+ {
+ tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+
+ YAdjust+((posX>>16)%TWin.Position.x1)];
+ GetTextureTransColG_S(&psxVuw[(i<<10)+j],psxVuw[clutP+tC1]);
+ }
+ }
+ if(NextRow_FT())
+ {
+ return;
+ }
+ }
+ return;
+ }
+
+#endif
+
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=(left_x >> 16);
+ xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!!!!!
+ if(drawW<xmax) xmax=drawW;
+
+ if(xmax>=xmin)
+ {
+ posX=left_u;
+ posY=left_v;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
+
+ for(j=xmin;j<xmax;j+=2)
+ {
+ tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+
+ YAdjust+((posX>>16)%TWin.Position.x1)];
+ tC2 = psxVub[((((posY+difY)>>16)%TWin.Position.y1)<<11)+
+ YAdjust+(((posX+difX)>>16)%TWin.Position.x1)];
+ GetTextureTransColG32((uint32_t *)&psxVuw[(i<<10)+j],
+ psxVuw[clutP+tC1]|
+ ((int)psxVuw[clutP+tC2])<<16);
+ posX+=difX2;
+ posY+=difY2;
+ }
+
+ if(j==xmax)
+ {
+ tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+
+ YAdjust+((posX>>16)%TWin.Position.x1)];
+ GetTextureTransColG(&psxVuw[(i<<10)+j],psxVuw[clutP+tC1]);
+ }
+
+ }
+ if(NextRow_FT())
+ {
+ return;
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+#ifdef POLYQUAD3
+
+void drawPoly4TEx8_TRI(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4,short clX, short clY)
+{
+ drawPoly3TEx8(x2,y2,x3,y3,x4,y4,
+ tx2,ty2,tx3,ty3,tx4,ty4,
+ clX,clY);
+
+ drawPoly3TEx8(x1,y1,x2,y2,x4,y4,
+ tx1,ty1,tx2,ty2,tx4,ty4,
+ clX,clY);
+}
+
+#endif
+
+// more exact:
+
+void drawPoly4TEx8(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4,short clX, short clY)
+{
+ int num;
+ int i,j,xmin,xmax,ymin,ymax;
+ int difX, difY, difX2, difY2;
+ int posX,posY,YAdjust,clutP;
+ short tC1,tC2;
+
+ if(x1>drawW && x2>drawW && x3>drawW && x4>drawW) return;
+ if(y1>drawH && y2>drawH && y3>drawH && y4>drawH) return;
+ if(x1<drawX && x2<drawX && x3<drawX && x4<drawX) return;
+ if(y1<drawY && y2<drawY && y3<drawY && y4<drawY) return;
+ if(drawY>=drawH) return;
+ if(drawX>=drawW) return;
+
+ if(!SetupSections_FT4(x1,y1,x2,y2,x3,y3,x4,y4,tx1,ty1,tx2,ty2,tx3,ty3,tx4,ty4)) return;
+
+ ymax=Ymax;
+
+ for(ymin=Ymin;ymin<drawY;ymin++)
+ if(NextRow_FT4()) return;
+
+ clutP=(clY<<10)+clX;
+
+ YAdjust=((GlobalTextAddrY)<<11)+(GlobalTextAddrX<<1);
+
+#ifdef FASTSOLID
+
+ if(!bCheckMask && !DrawSemiTrans)
+ {
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=(left_x >> 16);
+ xmax=(right_x >> 16);
+
+ if(xmax>=xmin)
+ {
+ posX=left_u;
+ posY=left_v;
+
+ num=(xmax-xmin);
+ if(num==0) num=1;
+ difX=(right_u-posX)/num;
+ difY=(right_v-posY)/num;
+ difX2=difX<<1;
+ difY2=difY<<1;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
+ xmax--;if(drawW<xmax) xmax=drawW;
+
+ for(j=xmin;j<xmax;j+=2)
+ {
+ tC1 = psxVub[((posY>>5)&(int)0xFFFFF800)+YAdjust+(posX>>16)];
+ tC2 = psxVub[(((posY+difY)>>5)&(int)0xFFFFF800)+YAdjust+
+ ((posX+difX)>>16)];
+ GetTextureTransColG32_S((uint32_t *)&psxVuw[(i<<10)+j],
+ psxVuw[clutP+tC1]|
+ ((int)psxVuw[clutP+tC2])<<16);
+ posX+=difX2;
+ posY+=difY2;
+ }
+ if(j==xmax)
+ {
+ tC1 = psxVub[((posY>>5)&(int)0xFFFFF800)+YAdjust+(posX>>16)];
+ GetTextureTransColG_S(&psxVuw[(i<<10)+j],psxVuw[clutP+tC1]);
+ }
+ }
+ if(NextRow_FT4()) return;
+ }
+ return;
+ }
+
+#endif
+
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=(left_x >> 16);
+ xmax=(right_x >> 16);
+
+ if(xmax>=xmin)
+ {
+ posX=left_u;
+ posY=left_v;
+
+ num=(xmax-xmin);
+ if(num==0) num=1;
+ difX=(right_u-posX)/num;
+ difY=(right_v-posY)/num;
+ difX2=difX<<1;
+ difY2=difY<<1;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
+ xmax--;if(drawW<xmax) xmax=drawW;
+
+ for(j=xmin;j<xmax;j+=2)
+ {
+ tC1 = psxVub[((posY>>5)&(int)0xFFFFF800)+YAdjust+(posX>>16)];
+ tC2 = psxVub[(((posY+difY)>>5)&(int)0xFFFFF800)+YAdjust+
+ ((posX+difX)>>16)];
+ GetTextureTransColG32((uint32_t *)&psxVuw[(i<<10)+j],
+ psxVuw[clutP+tC1]|
+ ((int)psxVuw[clutP+tC2])<<16);
+ posX+=difX2;
+ posY+=difY2;
+ }
+ if(j==xmax)
+ {
+ tC1 = psxVub[((posY>>5)&(int)0xFFFFF800)+YAdjust+(posX>>16)];
+ GetTextureTransColG(&psxVuw[(i<<10)+j],psxVuw[clutP+tC1]);
+ }
+ }
+ if(NextRow_FT4()) return;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void drawPoly4TEx8_IL(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4,short clX, short clY)
+{
+ int num;
+ int i,j,xmin,xmax,ymin,ymax,n_xi,n_yi,TXV,TXU;
+ int difX, difY, difX2, difY2;
+ int posX,posY,YAdjust,clutP;
+ short tC1,tC2;
+
+ if(x1>drawW && x2>drawW && x3>drawW && x4>drawW) return;
+ if(y1>drawH && y2>drawH && y3>drawH && y4>drawH) return;
+ if(x1<drawX && x2<drawX && x3<drawX && x4<drawX) return;
+ if(y1<drawY && y2<drawY && y3<drawY && y4<drawY) return;
+ if(drawY>=drawH) return;
+ if(drawX>=drawW) return;
+
+ if(!SetupSections_FT4(x1,y1,x2,y2,x3,y3,x4,y4,tx1,ty1,tx2,ty2,tx3,ty3,tx4,ty4)) return;
+
+ ymax=Ymax;
+
+ for(ymin=Ymin;ymin<drawY;ymin++)
+ if(NextRow_FT4()) return;
+
+ clutP=(clY<<10)+clX;
+
+ YAdjust=(GlobalTextAddrY<<10)+GlobalTextAddrX;
+
+#ifdef FASTSOLID
+
+ if(!bCheckMask && !DrawSemiTrans)
+ {
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=(left_x >> 16);
+ xmax=(right_x >> 16);
+
+ if(xmax>=xmin)
+ {
+ posX=left_u;
+ posY=left_v;
+
+ num=(xmax-xmin);
+ if(num==0) num=1;
+ difX=(right_u-posX)/num;
+ difY=(right_v-posY)/num;
+ difX2=difX<<1;
+ difY2=difY<<1;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
+ xmax--;if(drawW<xmax) xmax=drawW;
+
+ for(j=xmin;j<xmax;j+=2)
+ {
+ TXU=posX>>16;
+ TXV=posY>>16;
+ n_xi = ( ( TXU >> 1 ) & ~0x78 ) + ( ( TXU << 2 ) & 0x40 ) + ( ( TXV << 3 ) & 0x38 );
+ n_yi = ( TXV & ~0x7 ) + ( ( TXU >> 5 ) & 0x7 );
+
+ tC1= (psxVuw[(n_yi<<10)+YAdjust+n_xi] >> ((TXU & 0x01)<<3)) & 0xff;
+
+ TXU=(posX+difX)>>16;
+ TXV=(posY+difY)>>16;
+ n_xi = ( ( TXU >> 1 ) & ~0x78 ) + ( ( TXU << 2 ) & 0x40 ) + ( ( TXV << 3 ) & 0x38 );
+ n_yi = ( TXV & ~0x7 ) + ( ( TXU >> 5 ) & 0x7 );
+
+ tC2= (psxVuw[(n_yi<<10)+YAdjust+n_xi] >> ((TXU & 0x01)<<3)) & 0xff;
+
+ GetTextureTransColG32_S((uint32_t *)&psxVuw[(i<<10)+j],
+ psxVuw[clutP+tC1]|
+ ((int)psxVuw[clutP+tC2])<<16);
+ posX+=difX2;
+ posY+=difY2;
+ }
+ if(j==xmax)
+ {
+ TXU=posX>>16;
+ TXV=posY>>16;
+ n_xi = ( ( TXU >> 1 ) & ~0x78 ) + ( ( TXU << 2 ) & 0x40 ) + ( ( TXV << 3 ) & 0x38 );
+ n_yi = ( TXV & ~0x7 ) + ( ( TXU >> 5 ) & 0x7 );
+
+ tC1= (psxVuw[(n_yi<<10)+YAdjust+n_xi] >> ((TXU & 0x01)<<3)) & 0xff;
+
+ GetTextureTransColG_S(&psxVuw[(i<<10)+j],psxVuw[clutP+tC1]);
+ }
+ }
+ if(NextRow_FT4()) return;
+ }
+ return;
+ }
+
+#endif
+
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=(left_x >> 16);
+ xmax=(right_x >> 16);
+
+ if(xmax>=xmin)
+ {
+ posX=left_u;
+ posY=left_v;
+
+ num=(xmax-xmin);
+ if(num==0) num=1;
+ difX=(right_u-posX)/num;
+ difY=(right_v-posY)/num;
+ difX2=difX<<1;
+ difY2=difY<<1;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
+ xmax--;if(drawW<xmax) xmax=drawW;
+
+ for(j=xmin;j<xmax;j+=2)
+ {
+ TXU=posX>>16;
+ TXV=posY>>16;
+ n_xi = ( ( TXU >> 1 ) & ~0x78 ) + ( ( TXU << 2 ) & 0x40 ) + ( ( TXV << 3 ) & 0x38 );
+ n_yi = ( TXV & ~0x7 ) + ( ( TXU >> 5 ) & 0x7 );
+
+ tC1= (psxVuw[(n_yi<<10)+YAdjust+n_xi] >> ((TXU & 0x01)<<3)) & 0xff;
+
+ TXU=(posX+difX)>>16;
+ TXV=(posY+difY)>>16;
+ n_xi = ( ( TXU >> 1 ) & ~0x78 ) + ( ( TXU << 2 ) & 0x40 ) + ( ( TXV << 3 ) & 0x38 );
+ n_yi = ( TXV & ~0x7 ) + ( ( TXU >> 5 ) & 0x7 );
+
+ tC2= (psxVuw[(n_yi<<10)+YAdjust+n_xi] >> ((TXU & 0x01)<<3)) & 0xff;
+
+ GetTextureTransColG32((uint32_t *)&psxVuw[(i<<10)+j],
+ psxVuw[clutP+tC1]|
+ ((int)psxVuw[clutP+tC2])<<16);
+ posX+=difX2;
+ posY+=difY2;
+ }
+ if(j==xmax)
+ {
+ TXU=posX>>16;
+ TXV=posY>>16;
+ n_xi = ( ( TXU >> 1 ) & ~0x78 ) + ( ( TXU << 2 ) & 0x40 ) + ( ( TXV << 3 ) & 0x38 );
+ n_yi = ( TXV & ~0x7 ) + ( ( TXU >> 5 ) & 0x7 );
+ tC1= (psxVuw[(n_yi<<10)+YAdjust+n_xi] >> ((TXU & 0x01)<<3)) & 0xff;
+ GetTextureTransColG(&psxVuw[(i<<10)+j],psxVuw[clutP+tC1]);
+ }
+ }
+ if(NextRow_FT4()) return;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void drawPoly4TEx8_TW(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4,short clX, short clY)
+{
+ int num;
+ int i, j, xmin, xmax, ymin, ymax;
+ int difX, difY, difX2, difY2;
+ int posX, posY, YAdjust, clutP;
+ short tC1, tC2;
+
+ if(x1>drawW && x2>drawW && x3>drawW && x4>drawW) return;
+ if(y1>drawH && y2>drawH && y3>drawH && y4>drawH) return;
+ if(x1<drawX && x2<drawX && x3<drawX && x4<drawX) return;
+ if(y1<drawY && y2<drawY && y3<drawY && y4<drawY) return;
+ if(drawY>=drawH) return;
+ if(drawX>=drawW) return;
+
+ if(!SetupSections_FT4(x1,y1,x2,y2,x3,y3,x4,y4,tx1,ty1,tx2,ty2,tx3,ty3,tx4,ty4)) return;
+
+ ymax=Ymax;
+
+ for(ymin=Ymin;ymin<drawY;ymin++)
+ if(NextRow_FT4()) return;
+
+ clutP=(clY<<10)+clX;
+
+ YAdjust=((GlobalTextAddrY)<<11)+(GlobalTextAddrX<<1);
+ YAdjust+=(TWin.Position.y0<<11)+(TWin.Position.x0);
+
+#ifdef FASTSOLID
+
+ if(!bCheckMask && !DrawSemiTrans)
+ {
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=(left_x >> 16);
+ xmax=(right_x >> 16);
+
+ if(xmax>=xmin)
+ {
+ posX=left_u;
+ posY=left_v;
+
+ num=(xmax-xmin);
+ if(num==0) num=1;
+ difX=(right_u-posX)/num;
+ difY=(right_v-posY)/num;
+ difX2=difX<<1;
+ difY2=difY<<1;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
+ xmax--;if(drawW<xmax) xmax=drawW;
+
+ for(j=xmin;j<xmax;j+=2)
+ {
+ tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+
+ YAdjust+((posX>>16)%TWin.Position.x1)];
+ tC2 = psxVub[((((posY+difY)>>16)%TWin.Position.y1)<<11)+
+ YAdjust+(((posX+difX)>>16)%TWin.Position.x1)];
+ GetTextureTransColG32_S((uint32_t *)&psxVuw[(i<<10)+j],
+ psxVuw[clutP+tC1]|
+ ((int)psxVuw[clutP+tC2])<<16);
+ posX += difX2;
+ posY += difY2;
+ }
+ if(j==xmax)
+ {
+ tC1 = psxVub[((((posY+difY)>>16)%TWin.Position.y1)<<11)+
+ YAdjust+((posX>>16)%TWin.Position.x1)];
+ GetTextureTransColG_S(&psxVuw[(i<<10)+j],psxVuw[clutP+tC1]);
+ }
+ }
+ if(NextRow_FT4()) return;
+ }
+ return;
+ }
+
+#endif
+
+
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=(left_x >> 16);
+ xmax=(right_x >> 16);
+
+ if(xmax>=xmin)
+ {
+ posX=left_u;
+ posY=left_v;
+
+ num=(xmax-xmin);
+ if(num==0) num=1;
+ difX=(right_u-posX)/num;
+ difY=(right_v-posY)/num;
+ difX2=difX<<1;
+ difY2=difY<<1;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
+ xmax--;if(drawW<xmax) xmax=drawW;
+
+ for(j=xmin;j<xmax;j+=2)
+ {
+ tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+
+ YAdjust+((posX>>16)%TWin.Position.x1)];
+ tC2 = psxVub[((((posY+difY)>>16)%TWin.Position.y1)<<11)+
+ YAdjust+(((posX+difX)>>16)%TWin.Position.x1)];
+ GetTextureTransColG32((uint32_t *)&psxVuw[(i<<10)+j],
+ psxVuw[clutP+tC1]|
+ ((int)psxVuw[clutP+tC2])<<16);
+ posX+=difX2;
+ posY+=difY2;
+ }
+ if(j==xmax)
+ {
+ tC1 = psxVub[((((posY+difY)>>16)%TWin.Position.y1)<<11)+
+ YAdjust+((posX>>16)%TWin.Position.x1)];
+ GetTextureTransColG(&psxVuw[(i<<10)+j],psxVuw[clutP+tC1]);
+ }
+ }
+ if(NextRow_FT4()) return;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void drawPoly4TEx8_TW_S(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4,short clX, short clY)
+{
+ int num;
+ int i,j,xmin,xmax,ymin,ymax;
+ int difX, difY, difX2, difY2;
+ int posX,posY,YAdjust,clutP;
+ short tC1,tC2;
+
+ if(x1>drawW && x2>drawW && x3>drawW && x4>drawW) return;
+ if(y1>drawH && y2>drawH && y3>drawH && y4>drawH) return;
+ if(x1<drawX && x2<drawX && x3<drawX && x4<drawX) return;
+ if(y1<drawY && y2<drawY && y3<drawY && y4<drawY) return;
+ if(drawY>=drawH) return;
+ if(drawX>=drawW) return;
+
+ if(!SetupSections_FT4(x1,y1,x2,y2,x3,y3,x4,y4,tx1,ty1,tx2,ty2,tx3,ty3,tx4,ty4)) return;
+
+ ymax=Ymax;
+
+ for(ymin=Ymin;ymin<drawY;ymin++)
+ if(NextRow_FT4()) return;
+
+ clutP=(clY<<10)+clX;
+
+ YAdjust=((GlobalTextAddrY)<<11)+(GlobalTextAddrX<<1);
+ YAdjust+=(TWin.Position.y0<<11)+(TWin.Position.x0);
+
+#ifdef FASTSOLID
+
+ if(!bCheckMask && !DrawSemiTrans)
+ {
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=(left_x >> 16);
+ xmax=(right_x >> 16);
+
+ if(xmax>=xmin)
+ {
+ posX=left_u;
+ posY=left_v;
+
+ num=(xmax-xmin);
+ if(num==0) num=1;
+ difX=(right_u-posX)/num;
+ difY=(right_v-posY)/num;
+ difX2=difX<<1;
+ difY2=difY<<1;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
+ xmax--;if(drawW<xmax) xmax=drawW;
+
+ for(j=xmin;j<xmax;j+=2)
+ {
+ tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+
+ YAdjust+((posX>>16)%TWin.Position.x1)];
+ tC2 = psxVub[((((posY+difY)>>16)%TWin.Position.y1)<<11)+
+ YAdjust+(((posX+difX)>>16)%TWin.Position.x1)];
+ GetTextureTransColG32_S((uint32_t *)&psxVuw[(i<<10)+j],
+ psxVuw[clutP+tC1]|
+ ((int)psxVuw[clutP+tC2])<<16);
+ posX+=difX2;
+ posY+=difY2;
+ }
+ if(j==xmax)
+ {
+ tC1 = psxVub[((((posY+difY)>>16)%TWin.Position.y1)<<11)+
+ YAdjust+((posX>>16)%TWin.Position.x1)];
+ GetTextureTransColG_S(&psxVuw[(i<<10)+j],psxVuw[clutP+tC1]);
+ }
+ }
+ if(NextRow_FT4()) return;
+ }
+ return;
+ }
+
+#endif
+
+
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=(left_x >> 16);
+ xmax=(right_x >> 16);
+
+ if(xmax>=xmin)
+ {
+ posX=left_u;
+ posY=left_v;
+
+ num=(xmax-xmin);
+ if(num==0) num=1;
+ difX=(right_u-posX)/num;
+ difY=(right_v-posY)/num;
+ difX2=difX<<1;
+ difY2=difY<<1;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
+ xmax--;if(drawW<xmax) xmax=drawW;
+
+ for(j=xmin;j<xmax;j+=2)
+ {
+ tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+
+ YAdjust+((posX>>16)%TWin.Position.x1)];
+ tC2 = psxVub[((((posY+difY)>>16)%TWin.Position.y1)<<11)+
+ YAdjust+(((posX+difX)>>16)%TWin.Position.x1)];
+ GetTextureTransColG32_SPR((uint32_t *)&psxVuw[(i<<10)+j],
+ psxVuw[clutP+tC1]|
+ ((int)psxVuw[clutP+tC2])<<16);
+ posX+=difX2;
+ posY+=difY2;
+ }
+ if(j==xmax)
+ {
+ tC1 = psxVub[((((posY+difY)>>16)%TWin.Position.y1)<<11)+
+ YAdjust+((posX>>16)%TWin.Position.x1)];
+ GetTextureTransColG_SPR(&psxVuw[(i<<10)+j],psxVuw[clutP+tC1]);
+ }
+ }
+ if(NextRow_FT4()) return;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+// POLY 3 F-SHADED TEX 15 BIT
+////////////////////////////////////////////////////////////////////////
+
+void drawPoly3TD(short x1, short y1, short x2, short y2, short x3, short y3, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3)
+{
+ int i,j,xmin,xmax,ymin,ymax;
+ int difX, difY,difX2, difY2;
+ int posX,posY;
+
+ if(x1>drawW && x2>drawW && x3>drawW) return;
+ if(y1>drawH && y2>drawH && y3>drawH) return;
+ if(x1<drawX && x2<drawX && x3<drawX) return;
+ if(y1<drawY && y2<drawY && y3<drawY) return;
+ if(drawY>=drawH) return;
+ if(drawX>=drawW) return;
+
+ if(!SetupSections_FT(x1,y1,x2,y2,x3,y3,tx1,ty1,tx2,ty2,tx3,ty3)) return;
+
+ ymax=Ymax;
+
+ for(ymin=Ymin;ymin<drawY;ymin++)
+ if(NextRow_FT()) return;
+
+ difX=delta_right_u;difX2=difX<<1;
+ difY=delta_right_v;difY2=difY<<1;
+
+#ifdef FASTSOLID
+
+ if(!bCheckMask && !DrawSemiTrans)
+ {
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=(left_x >> 16);
+ xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!
+ if(drawW<xmax) xmax=drawW;
+
+ if(xmax>=xmin)
+ {
+ posX=left_u;
+ posY=left_v;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
+
+ for(j=xmin;j<xmax;j+=2)
+ {
+ GetTextureTransColG32_S((uint32_t *)&psxVuw[(i<<10)+j],
+ (((int)psxVuw[((((posY+difY)>>16)+GlobalTextAddrY)<<10)+((posX+difX)>>16)+GlobalTextAddrX])<<16)|
+ psxVuw[(((posY>>16)+GlobalTextAddrY)<<10)+((posX)>>16)+GlobalTextAddrX]);
+
+ posX+=difX2;
+ posY+=difY2;
+ }
+ if(j==xmax)
+ GetTextureTransColG_S(&psxVuw[(i<<10)+j],
+ psxVuw[(((posY>>16)+GlobalTextAddrY)<<10)+(posX>>16)+GlobalTextAddrX]);
+ }
+ if(NextRow_FT())
+ {
+ return;
+ }
+ }
+ return;
+ }
+
+#endif
+
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=(left_x >> 16);
+ xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!!
+ if(drawW<xmax) xmax=drawW;
+
+ if(xmax>=xmin)
+ {
+ posX=left_u;
+ posY=left_v;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
+
+ for(j=xmin;j<xmax;j+=2)
+ {
+ GetTextureTransColG32((uint32_t *)&psxVuw[(i<<10)+j],
+ (((int)psxVuw[((((posY+difY)>>16)+GlobalTextAddrY)<<10)+((posX+difX)>>16)+GlobalTextAddrX])<<16)|
+ psxVuw[(((posY>>16)+GlobalTextAddrY)<<10)+((posX)>>16)+GlobalTextAddrX]);
+
+ posX+=difX2;
+ posY+=difY2;
+ }
+ if(j==xmax)
+ GetTextureTransColG(&psxVuw[(i<<10)+j],
+ psxVuw[(((posY>>16)+GlobalTextAddrY)<<10)+(posX>>16)+GlobalTextAddrX]);
+ }
+ if(NextRow_FT())
+ {
+ return;
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void drawPoly3TD_TW(short x1, short y1, short x2, short y2, short x3, short y3, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3)
+{
+ int i,j,xmin,xmax,ymin,ymax;
+ int difX, difY,difX2, difY2;
+ int posX,posY;
+
+ if(x1>drawW && x2>drawW && x3>drawW) return;
+ if(y1>drawH && y2>drawH && y3>drawH) return;
+ if(x1<drawX && x2<drawX && x3<drawX) return;
+ if(y1<drawY && y2<drawY && y3<drawY) return;
+ if(drawY>=drawH) return;
+ if(drawX>=drawW) return;
+
+ if(!SetupSections_FT(x1,y1,x2,y2,x3,y3,tx1,ty1,tx2,ty2,tx3,ty3)) return;
+
+ ymax=Ymax;
+
+ for(ymin=Ymin;ymin<drawY;ymin++)
+ if(NextRow_FT()) return;
+
+ difX=delta_right_u;difX2=difX<<1;
+ difY=delta_right_v;difY2=difY<<1;
+
+#ifdef FASTSOLID
+
+ if(!bCheckMask && !DrawSemiTrans)
+ {
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=(left_x >> 16);
+ xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!
+ if(drawW<xmax) xmax=drawW;
+
+ if(xmax>=xmin)
+ {
+ posX=left_u;
+ posY=left_v;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
+
+ for(j=xmin;j<xmax;j+=2)
+ {
+ GetTextureTransColG32_S((uint32_t *)&psxVuw[(i<<10)+j],
+ (((int)psxVuw[(((((posY+difY)>>16)%TWin.Position.y1)+GlobalTextAddrY+TWin.Position.y0)<<10)+
+ (((posX+difX)>>16)%TWin.Position.x1)+GlobalTextAddrX+TWin.Position.x0])<<16)|
+ psxVuw[((((posY>>16)%TWin.Position.y1)+GlobalTextAddrY+TWin.Position.y0)<<10)+
+ (((posX)>>16)%TWin.Position.x1)+GlobalTextAddrX+TWin.Position.x0]);
+
+ posX+=difX2;
+ posY+=difY2;
+ }
+ if(j==xmax)
+ GetTextureTransColG_S(&psxVuw[(i<<10)+j],
+ psxVuw[((((posY>>16)%TWin.Position.y1)+GlobalTextAddrY+TWin.Position.y0)<<10)+
+ ((posX>>16)%TWin.Position.x1)+GlobalTextAddrX+TWin.Position.x0]);
+ }
+ if(NextRow_FT())
+ {
+ return;
+ }
+ }
+ return;
+ }
+
+#endif
+
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=(left_x >> 16);
+ xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!!
+ if(drawW<xmax) xmax=drawW;
+
+ if(xmax>=xmin)
+ {
+ posX=left_u;
+ posY=left_v;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
+
+ for(j=xmin;j<xmax;j+=2)
+ {
+ GetTextureTransColG32((uint32_t *)&psxVuw[(i<<10)+j],
+ (((int)psxVuw[(((((posY+difY)>>16)%TWin.Position.y1)+GlobalTextAddrY+TWin.Position.y0)<<10)+
+ (((posX+difX)>>16)%TWin.Position.x1)+GlobalTextAddrX+TWin.Position.x0])<<16)|
+ psxVuw[((((posY>>16)%TWin.Position.y1)+GlobalTextAddrY+TWin.Position.y0)<<10)+
+ (((posX)>>16)%TWin.Position.x1)+GlobalTextAddrX+TWin.Position.x0]);
+
+ posX+=difX2;
+ posY+=difY2;
+ }
+ if(j==xmax)
+ GetTextureTransColG(&psxVuw[(i<<10)+j],
+ psxVuw[((((posY>>16)%TWin.Position.y1)+GlobalTextAddrY+TWin.Position.y0)<<10)+
+ ((posX>>16)%TWin.Position.x1)+GlobalTextAddrX+TWin.Position.x0]);
+ }
+ if(NextRow_FT())
+ {
+ return;
+ }
+ }
+}
+
+
+////////////////////////////////////////////////////////////////////////
+
+#ifdef POLYQUAD3
+
+void drawPoly4TD_TRI(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4)
+{
+ drawPoly3TD(x2,y2,x3,y3,x4,y4,
+ tx2,ty2,tx3,ty3,tx4,ty4);
+ drawPoly3TD(x1,y1,x2,y2,x4,y4,
+ tx1,ty1,tx2,ty2,tx4,ty4);
+}
+
+#endif
+
+// more exact:
+
+void drawPoly4TD(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4)
+{
+ int num;
+ int i,j,xmin,xmax,ymin,ymax;
+ int difX, difY, difX2, difY2;
+ int posX,posY;
+
+ if(x1>drawW && x2>drawW && x3>drawW && x4>drawW) return;
+ if(y1>drawH && y2>drawH && y3>drawH && y4>drawH) return;
+ if(x1<drawX && x2<drawX && x3<drawX && x4<drawX) return;
+ if(y1<drawY && y2<drawY && y3<drawY && y4<drawY) return;
+ if(drawY>=drawH) return;
+ if(drawX>=drawW) return;
+
+ if(!SetupSections_FT4(x1,y1,x2,y2,x3,y3,x4,y4,tx1,ty1,tx2,ty2,tx3,ty3,tx4,ty4)) return;
+
+ ymax=Ymax;
+
+ for(ymin=Ymin;ymin<drawY;ymin++)
+ if(NextRow_FT4()) return;
+
+#ifdef FASTSOLID
+
+ if(!bCheckMask && !DrawSemiTrans)
+ {
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=(left_x >> 16);
+ xmax=(right_x >> 16);
+
+ if(xmax>=xmin)
+ {
+ posX=left_u;
+ posY=left_v;
+
+ num=(xmax-xmin);
+ if(num==0) num=1;
+ difX=(right_u-posX)/num;
+ difY=(right_v-posY)/num;
+ difX2=difX<<1;
+ difY2=difY<<1;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
+ xmax--;if(drawW<xmax) xmax=drawW;
+
+ for(j=xmin;j<xmax;j+=2)
+ {
+ GetTextureTransColG32_S((uint32_t *)&psxVuw[(i<<10)+j],
+ (((int)psxVuw[((((posY+difY)>>16)+GlobalTextAddrY)<<10)+((posX+difX)>>16)+GlobalTextAddrX])<<16)|
+ psxVuw[(((posY>>16)+GlobalTextAddrY)<<10)+((posX)>>16)+GlobalTextAddrX]);
+
+ posX+=difX2;
+ posY+=difY2;
+ }
+ if(j==xmax)
+ GetTextureTransColG_S(&psxVuw[(i<<10)+j],
+ psxVuw[(((posY>>16)+GlobalTextAddrY)<<10)+(posX>>16)+GlobalTextAddrX]);
+ }
+ if(NextRow_FT4()) return;
+ }
+ return;
+ }
+
+#endif
+
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=(left_x >> 16);
+ xmax=(right_x >> 16);
+
+ if(xmax>=xmin)
+ {
+ posX=left_u;
+ posY=left_v;
+
+ num=(xmax-xmin);
+ if(num==0) num=1;
+ difX=(right_u-posX)/num;
+ difY=(right_v-posY)/num;
+ difX2=difX<<1;
+ difY2=difY<<1;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
+ xmax--;if(drawW<xmax) xmax=drawW;
+
+ for(j=xmin;j<xmax;j+=2)
+ {
+ GetTextureTransColG32((uint32_t *)&psxVuw[(i<<10)+j],
+ (((int)psxVuw[((((posY+difY)>>16)+GlobalTextAddrY)<<10)+((posX+difX)>>16)+GlobalTextAddrX])<<16)|
+ psxVuw[(((posY>>16)+GlobalTextAddrY)<<10)+((posX)>>16)+GlobalTextAddrX]);
+
+ posX+=difX2;
+ posY+=difY2;
+ }
+ if(j==xmax)
+ GetTextureTransColG(&psxVuw[(i<<10)+j],
+ psxVuw[(((posY>>16)+GlobalTextAddrY)<<10)+(posX>>16)+GlobalTextAddrX]);
+ }
+ if(NextRow_FT4()) return;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void drawPoly4TD_TW(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4)
+{
+ int num;
+ int i,j,xmin,xmax,ymin,ymax;
+ int difX, difY, difX2, difY2;
+ int posX,posY;
+
+ if(x1>drawW && x2>drawW && x3>drawW && x4>drawW) return;
+ if(y1>drawH && y2>drawH && y3>drawH && y4>drawH) return;
+ if(x1<drawX && x2<drawX && x3<drawX && x4<drawX) return;
+ if(y1<drawY && y2<drawY && y3<drawY && y4<drawY) return;
+ if(drawY>=drawH) return;
+ if(drawX>=drawW) return;
+
+ if(!SetupSections_FT4(x1,y1,x2,y2,x3,y3,x4,y4,tx1,ty1,tx2,ty2,tx3,ty3,tx4,ty4)) return;
+
+ ymax=Ymax;
+
+ for(ymin=Ymin;ymin<drawY;ymin++)
+ if(NextRow_FT4()) return;
+
+#ifdef FASTSOLID
+
+ if(!bCheckMask && !DrawSemiTrans)
+ {
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=(left_x >> 16);
+ xmax=(right_x >> 16);
+
+ if(xmax>=xmin)
+ {
+ posX=left_u;
+ posY=left_v;
+
+ num=(xmax-xmin);
+ if(num==0) num=1;
+ difX=(right_u-posX)/num;
+ difY=(right_v-posY)/num;
+ difX2=difX<<1;
+ difY2=difY<<1;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
+ xmax--;if(drawW<xmax) xmax=drawW;
+
+ for(j=xmin;j<xmax;j+=2)
+ {
+ GetTextureTransColG32_S((uint32_t *)&psxVuw[(i<<10)+j],
+ (((int)psxVuw[(((((posY+difY)>>16)%TWin.Position.y1)+GlobalTextAddrY+TWin.Position.y0)<<10)+
+ (((posX+difX)>>16)%TWin.Position.x1)+GlobalTextAddrX+TWin.Position.x0])<<16)|
+ psxVuw[((((posY>>16)%TWin.Position.y1)+GlobalTextAddrY)<<10)+TWin.Position.y0+
+ ((posX>>16)%TWin.Position.x1)+GlobalTextAddrX+TWin.Position.x0]);
+
+ posX+=difX2;
+ posY+=difY2;
+ }
+ if(j==xmax)
+ GetTextureTransColG_S(&psxVuw[(i<<10)+j],
+ psxVuw[((((posY>>16)%TWin.Position.y1)+GlobalTextAddrY+TWin.Position.y0)<<10)+
+ ((posX>>16)%TWin.Position.x1)+GlobalTextAddrX+TWin.Position.x0]);
+ }
+ if(NextRow_FT4()) return;
+ }
+ return;
+ }
+
+#endif
+
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=(left_x >> 16);
+ xmax=(right_x >> 16);
+
+ if(xmax>=xmin)
+ {
+ posX=left_u;
+ posY=left_v;
+
+ num=(xmax-xmin);
+ if(num==0) num=1;
+ difX=(right_u-posX)/num;
+ difY=(right_v-posY)/num;
+ difX2=difX<<1;
+ difY2=difY<<1;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
+ xmax--;if(drawW<xmax) xmax=drawW;
+
+ for(j=xmin;j<xmax;j+=2)
+ {
+ GetTextureTransColG32((uint32_t *)&psxVuw[(i<<10)+j],
+ (((int)psxVuw[(((((posY+difY)>>16)%TWin.Position.y1)+GlobalTextAddrY+TWin.Position.y0)<<10)+
+ (((posX+difX)>>16)%TWin.Position.x1)+GlobalTextAddrX+TWin.Position.x0])<<16)|
+ psxVuw[((((posY>>16)%TWin.Position.y1)+GlobalTextAddrY+TWin.Position.y0)<<10)+
+ ((posX>>16)%TWin.Position.x1)+GlobalTextAddrX+TWin.Position.x0]);
+
+ posX+=difX2;
+ posY+=difY2;
+ }
+ if(j==xmax)
+ GetTextureTransColG(&psxVuw[(i<<10)+j],
+ psxVuw[((((posY>>16)%TWin.Position.y1)+GlobalTextAddrY+TWin.Position.y0)<<10)+
+ ((posX>>16)%TWin.Position.x1)+GlobalTextAddrX+TWin.Position.x0]);
+ }
+ if(NextRow_FT4()) return;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void drawPoly4TD_TW_S(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4)
+{
+ int num;
+ int i,j,xmin,xmax,ymin,ymax;
+ int difX, difY, difX2, difY2;
+ int posX, posY;
+
+ if(x1>drawW && x2>drawW && x3>drawW && x4>drawW) return;
+ if(y1>drawH && y2>drawH && y3>drawH && y4>drawH) return;
+ if(x1<drawX && x2<drawX && x3<drawX && x4<drawX) return;
+ if(y1<drawY && y2<drawY && y3<drawY && y4<drawY) return;
+ if(drawY>=drawH) return;
+ if(drawX>=drawW) return;
+
+ if(!SetupSections_FT4(x1,y1,x2,y2,x3,y3,x4,y4,tx1,ty1,tx2,ty2,tx3,ty3,tx4,ty4)) return;
+
+ ymax=Ymax;
+
+ for(ymin=Ymin;ymin<drawY;ymin++)
+ if(NextRow_FT4()) return;
+
+#ifdef FASTSOLID
+
+ if(!bCheckMask && !DrawSemiTrans)
+ {
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=(left_x >> 16);
+ xmax=(right_x >> 16);
+
+ if(xmax>=xmin)
+ {
+ posX=left_u;
+ posY=left_v;
+
+ num=(xmax-xmin);
+ if(num==0) num=1;
+ difX=(right_u-posX)/num;
+ difY=(right_v-posY)/num;
+ difX2=difX<<1;
+ difY2=difY<<1;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
+ xmax--;if(drawW<xmax) xmax=drawW;
+
+ for(j=xmin;j<xmax;j+=2)
+ {
+ GetTextureTransColG32_S((uint32_t *)&psxVuw[(i<<10)+j],
+ (((int)psxVuw[(((((posY+difY)>>16)%TWin.Position.y1)+GlobalTextAddrY+TWin.Position.y0)<<10)+
+ (((posX+difX)>>16)%TWin.Position.x1)+GlobalTextAddrX+TWin.Position.x0])<<16)|
+ psxVuw[((((posY>>16)%TWin.Position.y1)+GlobalTextAddrY)<<10)+TWin.Position.y0+
+ ((posX>>16)%TWin.Position.x1)+GlobalTextAddrX+TWin.Position.x0]);
+
+ posX+=difX2;
+ posY+=difY2;
+ }
+ if(j==xmax)
+ GetTextureTransColG_S(&psxVuw[(i<<10)+j],
+ psxVuw[((((posY>>16)%TWin.Position.y1)+GlobalTextAddrY+TWin.Position.y0)<<10)+
+ ((posX>>16)%TWin.Position.x1)+GlobalTextAddrX+TWin.Position.x0]);
+ }
+ if(NextRow_FT4()) return;
+ }
+ return;
+ }
+
+#endif
+
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=(left_x >> 16);
+ xmax=(right_x >> 16);
+
+ if(xmax>=xmin)
+ {
+ posX=left_u;
+ posY=left_v;
+
+ num=(xmax-xmin);
+ if(num==0) num=1;
+ difX=(right_u-posX)/num;
+ difY=(right_v-posY)/num;
+ difX2=difX<<1;
+ difY2=difY<<1;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
+ xmax--;if(drawW<xmax) xmax=drawW;
+
+ for(j=xmin;j<xmax;j+=2)
+ {
+ GetTextureTransColG32_SPR((uint32_t *)&psxVuw[(i<<10)+j],
+ (((int)psxVuw[(((((posY+difY)>>16)%TWin.Position.y1)+GlobalTextAddrY+TWin.Position.y0)<<10)+
+ (((posX+difX)>>16)%TWin.Position.x1)+GlobalTextAddrX+TWin.Position.x0])<<16)|
+ psxVuw[((((posY>>16)%TWin.Position.y1)+GlobalTextAddrY+TWin.Position.y0)<<10)+
+ ((posX>>16)%TWin.Position.x1)+GlobalTextAddrX+TWin.Position.x0]);
+
+ posX+=difX2;
+ posY+=difY2;
+ }
+ if(j==xmax)
+ GetTextureTransColG_SPR(&psxVuw[(i<<10)+j],
+ psxVuw[((((posY>>16)%TWin.Position.y1)+GlobalTextAddrY+TWin.Position.y0)<<10)+
+ ((posX>>16)%TWin.Position.x1)+GlobalTextAddrX+TWin.Position.x0]);
+ }
+ if(NextRow_FT4()) return;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+// POLY 3/4 G-SHADED
+////////////////////////////////////////////////////////////////////////
+
+__inline void drawPoly3Gi(short x1,short y1,short x2,short y2,short x3,short y3, int rgb1, int rgb2, int rgb3)
+{
+ int i,j,xmin,xmax,ymin,ymax;
+ int cR1,cG1,cB1;
+ int difR,difB,difG,difR2,difB2,difG2;
+
+ if(x1>drawW && x2>drawW && x3>drawW) return;
+ if(y1>drawH && y2>drawH && y3>drawH) return;
+ if(x1<drawX && x2<drawX && x3<drawX) return;
+ if(y1<drawY && y2<drawY && y3<drawY) return;
+ if(drawY>=drawH) return;
+ if(drawX>=drawW) return;
+
+ if(!SetupSections_G(x1,y1,x2,y2,x3,y3,rgb1,rgb2,rgb3)) return;
+
+ ymax=Ymax;
+
+ for(ymin=Ymin;ymin<drawY;ymin++)
+ if(NextRow_G()) return;
+
+ difR=delta_right_R;
+ difG=delta_right_G;
+ difB=delta_right_B;
+ difR2=difR<<1;
+ difG2=difG<<1;
+ difB2=difB<<1;
+
+#ifdef FASTSOLID
+
+ if(!bCheckMask && !DrawSemiTrans && iDither!=2)
+ {
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=(left_x >> 16);
+ xmax=(right_x >> 16)-1;if(drawW<xmax) xmax=drawW;
+
+ if(xmax>=xmin)
+ {
+ cR1=left_R;
+ cG1=left_G;
+ cB1=left_B;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;cR1+=j*difR;cG1+=j*difG;cB1+=j*difB;}
+
+ for(j=xmin;j<xmax;j+=2)
+ {
+ *((uint32_t *)&psxVuw[(i<<10)+j])=
+ ((((cR1+difR) <<7)&0x7c000000)|(((cG1+difG) << 2)&0x03e00000)|(((cB1+difB)>>3)&0x001f0000)|
+ (((cR1) >> 9)&0x7c00)|(((cG1) >> 14)&0x03e0)|(((cB1) >> 19)&0x001f))|lSetMask;
+
+ cR1+=difR2;
+ cG1+=difG2;
+ cB1+=difB2;
+ }
+ if(j==xmax)
+ psxVuw[(i<<10)+j]=(((cR1 >> 9)&0x7c00)|((cG1 >> 14)&0x03e0)|((cB1 >> 19)&0x001f))|sSetMask;
+ }
+ if(NextRow_G()) return;
+ }
+ return;
+ }
+
+#endif
+
+ if(iDither==2)
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=(left_x >> 16);
+ xmax=(right_x >> 16)-1;if(drawW<xmax) xmax=drawW;
+
+ if(xmax>=xmin)
+ {
+ cR1=left_R;
+ cG1=left_G;
+ cB1=left_B;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;cR1+=j*difR;cG1+=j*difG;cB1+=j*difB;}
+
+ for(j=xmin;j<=xmax;j++)
+ {
+ GetShadeTransCol_Dither(&psxVuw[(i<<10)+j],(cB1>>16),(cG1>>16),(cR1>>16));
+
+ cR1+=difR;
+ cG1+=difG;
+ cB1+=difB;
+ }
+ }
+ if(NextRow_G()) return;
+ }
+ else
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=(left_x >> 16);
+ xmax=(right_x >> 16)-1;if(drawW<xmax) xmax=drawW;
+
+ if(xmax>=xmin)
+ {
+ cR1=left_R;
+ cG1=left_G;
+ cB1=left_B;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;cR1+=j*difR;cG1+=j*difG;cB1+=j*difB;}
+
+ for(j=xmin;j<=xmax;j++)
+ {
+ GetShadeTransCol(&psxVuw[(i<<10)+j],((cR1 >> 9)&0x7c00)|((cG1 >> 14)&0x03e0)|((cB1 >> 19)&0x001f));
+
+ cR1+=difR;
+ cG1+=difG;
+ cB1+=difB;
+ }
+ }
+ if(NextRow_G()) return;
+ }
+
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void drawPoly3G(int rgb1, int rgb2, int rgb3)
+{
+ drawPoly3Gi(lx0,ly0,lx1,ly1,lx2,ly2,rgb1,rgb2,rgb3);
+}
+
+// draw two g-shaded tris for right psx shading emulation
+
+void drawPoly4G(int rgb1, int rgb2, int rgb3, int rgb4)
+{
+ drawPoly3Gi(lx1,ly1,lx3,ly3,lx2,ly2,
+ rgb2,rgb4,rgb3);
+ drawPoly3Gi(lx0,ly0,lx1,ly1,lx2,ly2,
+ rgb1,rgb2,rgb3);
+}
+
+////////////////////////////////////////////////////////////////////////
+// POLY 3/4 G-SHADED TEX PAL4
+////////////////////////////////////////////////////////////////////////
+
+void drawPoly3TGEx4(short x1, short y1, short x2, short y2, short x3, short y3, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short clX, short clY,int col1, int col2, int col3)
+{
+ int i,j,xmin,xmax,ymin,ymax;
+ int cR1,cG1,cB1;
+ int difR,difB,difG,difR2,difB2,difG2;
+ int difX, difY,difX2, difY2;
+ int posX,posY,YAdjust,clutP,XAdjust;
+ short tC1,tC2;
+
+ if(x1>drawW && x2>drawW && x3>drawW) return;
+ if(y1>drawH && y2>drawH && y3>drawH) return;
+ if(x1<drawX && x2<drawX && x3<drawX) return;
+ if(y1<drawY && y2<drawY && y3<drawY) return;
+ if(drawY>=drawH) return;
+ if(drawX>=drawW) return;
+
+ if(!SetupSections_GT(x1,y1,x2,y2,x3,y3,tx1,ty1,tx2,ty2,tx3,ty3,col1,col2,col3)) return;
+
+ ymax=Ymax;
+
+ for(ymin=Ymin;ymin<drawY;ymin++)
+ if(NextRow_GT()) return;
+
+ clutP=(clY<<10)+clX;
+
+ YAdjust=((GlobalTextAddrY)<<11)+(GlobalTextAddrX<<1);
+
+ difR=delta_right_R;
+ difG=delta_right_G;
+ difB=delta_right_B;
+ difR2=difR<<1;
+ difG2=difG<<1;
+ difB2=difB<<1;
+
+ difX=delta_right_u;difX2=difX<<1;
+ difY=delta_right_v;difY2=difY<<1;
+
+#ifdef FASTSOLID
+
+ if(!bCheckMask && !DrawSemiTrans && !iDither)
+ {
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=((left_x) >> 16);
+ xmax=((right_x) >> 16)-1; //!!!!!!!!!!!!!
+ if(drawW<xmax) xmax=drawW;
+
+ if(xmax>=xmin)
+ {
+ posX=left_u;
+ posY=left_v;
+ cR1=left_R;
+ cG1=left_G;
+ cB1=left_B;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;cR1+=j*difR;cG1+=j*difG;cB1+=j*difB;}
+
+ for(j=xmin;j<xmax;j+=2)
+ {
+ XAdjust=(posX>>16);
+ tC1 = psxVub[((posY>>5)&(int)0xFFFFF800)+YAdjust+(XAdjust>>1)];
+ tC1=(tC1>>((XAdjust&1)<<2))&0xf;
+ XAdjust=((posX+difX)>>16);
+ tC2 = psxVub[(((posY+difY)>>5)&(int)0xFFFFF800)+YAdjust+
+ (XAdjust>>1)];
+ tC2=(tC2>>((XAdjust&1)<<2))&0xf;
+
+ GetTextureTransColGX32_S((uint32_t *)&psxVuw[(i<<10)+j],
+ psxVuw[clutP+tC1]|
+ ((int)psxVuw[clutP+tC2])<<16,
+ (cB1>>16)|((cB1+difB)&0xff0000),
+ (cG1>>16)|((cG1+difG)&0xff0000),
+ (cR1>>16)|((cR1+difR)&0xff0000));
+ posX+=difX2;
+ posY+=difY2;
+ cR1+=difR2;
+ cG1+=difG2;
+ cB1+=difB2;
+ }
+ if(j==xmax)
+ {
+ XAdjust=(posX>>16);
+ tC1 = psxVub[((posY>>5)&(int)0xFFFFF800)+YAdjust+(XAdjust>>1)];
+ tC1=(tC1>>((XAdjust&1)<<2))&0xf;
+ GetTextureTransColGX_S(&psxVuw[(i<<10)+j],
+ psxVuw[clutP+tC1],
+ (cB1>>16),(cG1>>16),(cR1>>16));
+ }
+ }
+ if(NextRow_GT())
+ {
+ return;
+ }
+ }
+ return;
+ }
+
+#endif
+
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=(left_x >> 16);
+ xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!!!!
+ if(drawW<xmax) xmax=drawW;
+
+ if(xmax>=xmin)
+ {
+ posX=left_u;
+ posY=left_v;
+ cR1=left_R;
+ cG1=left_G;
+ cB1=left_B;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;cR1+=j*difR;cG1+=j*difG;cB1+=j*difB;}
+
+ for(j=xmin;j<=xmax;j++)
+ {
+ XAdjust=(posX>>16);
+ tC1 = psxVub[((posY>>5)&(int)0xFFFFF800)+YAdjust+(XAdjust>>1)];
+ tC1=(tC1>>((XAdjust&1)<<2))&0xf;
+ if(iDither)
+ GetTextureTransColGX_Dither(&psxVuw[(i<<10)+j],
+ psxVuw[clutP+tC1],
+ (cB1>>16),(cG1>>16),(cR1>>16));
+ else
+ GetTextureTransColGX(&psxVuw[(i<<10)+j],
+ psxVuw[clutP+tC1],
+ (cB1>>16),(cG1>>16),(cR1>>16));
+ posX+=difX;
+ posY+=difY;
+ cR1+=difR;
+ cG1+=difG;
+ cB1+=difB;
+ }
+ }
+ if(NextRow_GT())
+ {
+ return;
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void drawPoly3TGEx4_IL(short x1, short y1, short x2, short y2, short x3, short y3, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short clX, short clY,int col1, int col2, int col3)
+{
+ int i,j,xmin,xmax,ymin,ymax,n_xi,n_yi,TXV;
+ int cR1,cG1,cB1;
+ int difR,difB,difG,difR2,difB2,difG2;
+ int difX, difY,difX2, difY2;
+ int posX,posY,YAdjust,clutP,XAdjust;
+ short tC1,tC2;
+
+ if(x1>drawW && x2>drawW && x3>drawW) return;
+ if(y1>drawH && y2>drawH && y3>drawH) return;
+ if(x1<drawX && x2<drawX && x3<drawX) return;
+ if(y1<drawY && y2<drawY && y3<drawY) return;
+ if(drawY>=drawH) return;
+ if(drawX>=drawW) return;
+
+ if(!SetupSections_GT(x1,y1,x2,y2,x3,y3,tx1,ty1,tx2,ty2,tx3,ty3,col1,col2,col3)) return;
+
+ ymax=Ymax;
+
+ for(ymin=Ymin;ymin<drawY;ymin++)
+ if(NextRow_GT()) return;
+
+ clutP=(clY<<10)+clX;
+
+ YAdjust=(GlobalTextAddrY<<10)+GlobalTextAddrX;
+
+ difR=delta_right_R;
+ difG=delta_right_G;
+ difB=delta_right_B;
+ difR2=difR<<1;
+ difG2=difG<<1;
+ difB2=difB<<1;
+
+ difX=delta_right_u;difX2=difX<<1;
+ difY=delta_right_v;difY2=difY<<1;
+
+#ifdef FASTSOLID
+
+ if(!bCheckMask && !DrawSemiTrans && !iDither)
+ {
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=((left_x) >> 16);
+ xmax=((right_x) >> 16)-1; //!!!!!!!!!!!!!
+ if(drawW<xmax) xmax=drawW;
+
+ if(xmax>=xmin)
+ {
+ posX=left_u;
+ posY=left_v;
+ cR1=left_R;
+ cG1=left_G;
+ cB1=left_B;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;cR1+=j*difR;cG1+=j*difG;cB1+=j*difB;}
+
+ for(j=xmin;j<xmax;j+=2)
+ {
+ XAdjust=(posX>>16);
+
+ TXV=posY>>16;
+ n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );
+ n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf );
+
+ tC1= (psxVuw[(n_yi<<10)+YAdjust+n_xi] >> ((XAdjust & 0x03)<<2)) & 0x0f ;
+
+ XAdjust=((posX+difX)>>16);
+
+ TXV=(posY+difY)>>16;
+ n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );
+ n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf );
+
+ tC2= (psxVuw[(n_yi<<10)+YAdjust+n_xi] >> ((XAdjust & 0x03)<<2)) & 0x0f ;
+
+ GetTextureTransColGX32_S((uint32_t *)&psxVuw[(i<<10)+j],
+ psxVuw[clutP+tC1]|
+ ((int)psxVuw[clutP+tC2])<<16,
+ (cB1>>16)|((cB1+difB)&0xff0000),
+ (cG1>>16)|((cG1+difG)&0xff0000),
+ (cR1>>16)|((cR1+difR)&0xff0000));
+ posX+=difX2;
+ posY+=difY2;
+ cR1+=difR2;
+ cG1+=difG2;
+ cB1+=difB2;
+ }
+ if(j==xmax)
+ {
+ XAdjust=(posX>>16);
+
+ TXV=posY>>16;
+ n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );
+ n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf );
+
+ tC1= (psxVuw[(n_yi<<10)+YAdjust+n_xi] >> ((XAdjust & 0x03)<<2)) & 0x0f ;
+
+ GetTextureTransColGX_S(&psxVuw[(i<<10)+j],
+ psxVuw[clutP+tC1],
+ (cB1>>16),(cG1>>16),(cR1>>16));
+ }
+ }
+ if(NextRow_GT())
+ {
+ return;
+ }
+ }
+ return;
+ }
+
+#endif
+
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=(left_x >> 16);
+ xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!!!!
+ if(drawW<xmax) xmax=drawW;
+
+ if(xmax>=xmin)
+ {
+ posX=left_u;
+ posY=left_v;
+ cR1=left_R;
+ cG1=left_G;
+ cB1=left_B;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;cR1+=j*difR;cG1+=j*difG;cB1+=j*difB;}
+
+ for(j=xmin;j<=xmax;j++)
+ {
+ XAdjust=(posX>>16);
+
+ TXV=posY>>16;
+ n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );
+ n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf );
+
+ tC1= (psxVuw[(n_yi<<10)+YAdjust+n_xi] >> ((XAdjust & 0x03)<<2)) & 0x0f ;
+
+ if(iDither)
+ GetTextureTransColGX_Dither(&psxVuw[(i<<10)+j],
+ psxVuw[clutP+tC1],
+ (cB1>>16),(cG1>>16),(cR1>>16));
+ else
+ GetTextureTransColGX(&psxVuw[(i<<10)+j],
+ psxVuw[clutP+tC1],
+ (cB1>>16),(cG1>>16),(cR1>>16));
+ posX+=difX;
+ posY+=difY;
+ cR1+=difR;
+ cG1+=difG;
+ cB1+=difB;
+ }
+ }
+ if(NextRow_GT())
+ {
+ return;
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void drawPoly3TGEx4_TW(short x1, short y1, short x2, short y2, short x3, short y3, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short clX, short clY, int col1, int col2, int col3)
+{
+ int i, j, xmin, xmax, ymin, ymax;
+ int cR1, cG1, cB1;
+ int difR, difB, difG, difR2, difB2, difG2;
+ int difX, difY,difX2, difY2;
+ int posX, posY, YAdjust, clutP, XAdjust;
+ short tC1,tC2;
+
+ if(x1>drawW && x2>drawW && x3>drawW) return;
+ if(y1>drawH && y2>drawH && y3>drawH) return;
+ if(x1<drawX && x2<drawX && x3<drawX) return;
+ if(y1<drawY && y2<drawY && y3<drawY) return;
+ if(drawY>=drawH) return;
+ if(drawX>=drawW) return;
+
+ if(!SetupSections_GT(x1,y1,x2,y2,x3,y3,tx1,ty1,tx2,ty2,tx3,ty3,col1,col2,col3)) return;
+
+ ymax=Ymax;
+
+ for(ymin=Ymin;ymin<drawY;ymin++)
+ if(NextRow_GT()) return;
+
+ clutP=(clY<<10)+clX;
+
+ YAdjust=((GlobalTextAddrY)<<11)+(GlobalTextAddrX<<1);
+ YAdjust+=(TWin.Position.y0<<11)+(TWin.Position.x0>>1);
+
+ difR=delta_right_R;
+ difG=delta_right_G;
+ difB=delta_right_B;
+ difR2=difR<<1;
+ difG2=difG<<1;
+ difB2=difB<<1;
+
+ difX=delta_right_u;difX2=difX<<1;
+ difY=delta_right_v;difY2=difY<<1;
+
+#ifdef FASTSOLID
+
+ if(!bCheckMask && !DrawSemiTrans && !iDither)
+ {
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=((left_x) >> 16);
+ xmax=((right_x) >> 16)-1; //!!!!!!!!!!!!!
+ if(drawW<xmax) xmax=drawW;
+
+ if(xmax>=xmin)
+ {
+ posX=left_u;
+ posY=left_v;
+ cR1=left_R;
+ cG1=left_G;
+ cB1=left_B;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;cR1+=j*difR;cG1+=j*difG;cB1+=j*difB;}
+
+ for(j=xmin;j<xmax;j+=2)
+ {
+ XAdjust=(posX>>16)%TWin.Position.x1;
+ tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+
+ YAdjust+(XAdjust>>1)];
+ tC1=(tC1>>((XAdjust&1)<<2))&0xf;
+ XAdjust=((posX+difX)>>16)%TWin.Position.x1;
+ tC2 = psxVub[((((posY+difY)>>16)%TWin.Position.y1)<<11)+
+ YAdjust+(XAdjust>>1)];
+ tC2=(tC2>>((XAdjust&1)<<2))&0xf;
+ GetTextureTransColGX32_S((uint32_t *)&psxVuw[(i<<10)+j],
+ psxVuw[clutP+tC1]|
+ ((int)psxVuw[clutP+tC2])<<16,
+ (cB1>>16)|((cB1+difB)&0xff0000),
+ (cG1>>16)|((cG1+difG)&0xff0000),
+ (cR1>>16)|((cR1+difR)&0xff0000));
+ posX+=difX2;
+ posY+=difY2;
+ cR1+=difR2;
+ cG1+=difG2;
+ cB1+=difB2;
+ }
+ if(j==xmax)
+ {
+ XAdjust=(posX>>16)%TWin.Position.x1;
+ tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+
+ YAdjust+(XAdjust>>1)];
+ tC1=(tC1>>((XAdjust&1)<<2))&0xf;
+ GetTextureTransColGX_S(&psxVuw[(i<<10)+j],
+ psxVuw[clutP+tC1],
+ (cB1>>16),(cG1>>16),(cR1>>16));
+ }
+ }
+ if(NextRow_GT())
+ {
+ return;
+ }
+ }
+ return;
+ }
+
+#endif
+
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=(left_x >> 16);
+ xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!!!!
+ if(drawW<xmax) xmax=drawW;
+
+ if(xmax>=xmin)
+ {
+ posX=left_u;
+ posY=left_v;
+ cR1=left_R;
+ cG1=left_G;
+ cB1=left_B;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;cR1+=j*difR;cG1+=j*difG;cB1+=j*difB;}
+
+ for(j=xmin;j<=xmax;j++)
+ {
+ XAdjust=(posX>>16)%TWin.Position.x1;
+ tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+
+ YAdjust+(XAdjust>>1)];
+ tC1=(tC1>>((XAdjust&1)<<2))&0xf;
+ if(iDither)
+ GetTextureTransColGX_Dither(&psxVuw[(i<<10)+j],
+ psxVuw[clutP+tC1],
+ (cB1>>16),(cG1>>16),(cR1>>16));
+ else
+ GetTextureTransColGX(&psxVuw[(i<<10)+j],
+ psxVuw[clutP+tC1],
+ (cB1>>16),(cG1>>16),(cR1>>16));
+ posX+=difX;
+ posY+=difY;
+ cR1+=difR;
+ cG1+=difG;
+ cB1+=difB;
+ }
+ }
+ if(NextRow_GT())
+ {
+ return;
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+// note: the psx is doing g-shaded quads as two g-shaded tris,
+// like the following func... sadly texturing is not 100%
+// correct that way, so small texture distortions can
+// happen...
+
+void drawPoly4TGEx4_TRI_IL(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4,
+ short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4,
+ short clX, short clY,
+ int col1, int col2, int col3, int col4)
+{
+ drawPoly3TGEx4_IL(x2,y2,x3,y3,x4,y4,
+ tx2,ty2,tx3,ty3,tx4,ty4,
+ clX,clY,
+ col2,col4,col3);
+ drawPoly3TGEx4_IL(x1,y1,x2,y2,x4,y4,
+ tx1,ty1,tx2,ty2,tx4,ty4,
+ clX,clY,
+ col1,col2,col3);
+}
+
+#ifdef POLYQUAD3GT
+
+void drawPoly4TGEx4_TRI(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4,
+ short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4,
+ short clX, short clY,
+ int col1, int col2, int col3, int col4)
+{
+ drawPoly3TGEx4(x2,y2,x3,y3,x4,y4,
+ tx2,ty2,tx3,ty3,tx4,ty4,
+ clX,clY,
+ col2,col4,col3);
+ drawPoly3TGEx4(x1,y1,x2,y2,x4,y4,
+ tx1,ty1,tx2,ty2,tx4,ty4,
+ clX,clY,
+ col1,col2,col3);
+}
+
+#endif
+
+////////////////////////////////////////////////////////////////////////
+
+void drawPoly4TGEx4(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4,
+ short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4,
+ short clX, short clY,
+ int col1, int col2, int col4, int col3)
+{
+ int num;
+ int i,j,xmin,xmax,ymin,ymax;
+ int cR1,cG1,cB1;
+ int difR,difB,difG,difR2,difB2,difG2;
+ int difX, difY, difX2, difY2;
+ int posX,posY,YAdjust,clutP,XAdjust;
+ short tC1,tC2;
+
+ if(x1>drawW && x2>drawW && x3>drawW && x4>drawW) return;
+ if(y1>drawH && y2>drawH && y3>drawH && y4>drawH) return;
+ if(x1<drawX && x2<drawX && x3<drawX && x4<drawX) return;
+ if(y1<drawY && y2<drawY && y3<drawY && y4<drawY) return;
+ if(drawY>=drawH) return;
+ if(drawX>=drawW) return;
+
+ if(!SetupSections_GT4(x1,y1,x2,y2,x3,y3,x4,y4,tx1,ty1,tx2,ty2,tx3,ty3,tx4,ty4,col1,col2,col3,col4)) return;
+
+ ymax=Ymax;
+
+ for(ymin=Ymin;ymin<drawY;ymin++)
+ if(NextRow_GT4()) return;
+
+ clutP=(clY<<10)+clX;
+
+ YAdjust=((GlobalTextAddrY)<<11)+(GlobalTextAddrX<<1);
+
+
+#ifdef FASTSOLID
+
+ if(!bCheckMask && !DrawSemiTrans && !iDither)
+ {
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=(left_x >> 16);
+ xmax=(right_x >> 16);
+
+ if(xmax>=xmin)
+ {
+ posX=left_u;
+ posY=left_v;
+
+ num=(xmax-xmin);
+ if(num==0) num=1;
+ difX=(right_u-posX)/num;
+ difY=(right_v-posY)/num;
+ difX2=difX<<1;
+ difY2=difY<<1;
+
+ cR1=left_R;
+ cG1=left_G;
+ cB1=left_B;
+ difR=(right_R-cR1)/num;
+ difG=(right_G-cG1)/num;
+ difB=(right_B-cB1)/num;
+ difR2=difR<<1;
+ difG2=difG<<1;
+ difB2=difB<<1;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;cR1+=j*difR;cG1+=j*difG;cB1+=j*difB;}
+ xmax--;if(drawW<xmax) xmax=drawW;
+
+ for(j=xmin;j<xmax;j+=2)
+ {
+ XAdjust=(posX>>16);
+ tC1 = psxVub[((posY>>5)&(int)0xFFFFF800)+YAdjust+(XAdjust>>1)];
+ tC1=(tC1>>((XAdjust&1)<<2))&0xf;
+ XAdjust=((posX+difX)>>16);
+ tC2 = psxVub[(((posY+difY)>>5)&(int)0xFFFFF800)+YAdjust+
+ (XAdjust>>1)];
+ tC2=(tC2>>((XAdjust&1)<<2))&0xf;
+
+ GetTextureTransColGX32_S((uint32_t *)&psxVuw[(i<<10)+j],
+ psxVuw[clutP+tC1]|
+ ((int)psxVuw[clutP+tC2])<<16,
+ (cB1>>16)|((cB1+difB)&0xff0000),
+ (cG1>>16)|((cG1+difG)&0xff0000),
+ (cR1>>16)|((cR1+difR)&0xff0000));
+ posX+=difX2;
+ posY+=difY2;
+ cR1+=difR2;
+ cG1+=difG2;
+ cB1+=difB2;
+ }
+ if(j==xmax)
+ {
+ XAdjust=(posX>>16);
+ tC1 = psxVub[((posY>>5)&(int)0xFFFFF800)+YAdjust+
+ (XAdjust>>1)];
+ tC1=(tC1>>((XAdjust&1)<<2))&0xf;
+
+ GetTextureTransColGX_S(&psxVuw[(i<<10)+j],
+ psxVuw[clutP+tC1],
+ (cB1>>16),(cG1>>16),(cR1>>16));
+ }
+ }
+ if(NextRow_GT4()) return;
+ }
+ return;
+ }
+
+#endif
+
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=(left_x >> 16);
+ xmax=(right_x >> 16);
+
+ if(xmax>=xmin)
+ {
+ posX=left_u;
+ posY=left_v;
+
+ num=(xmax-xmin);
+ if(num==0) num=1;
+ difX=(right_u-posX)/num;
+ difY=(right_v-posY)/num;
+ difX2=difX<<1;
+ difY2=difY<<1;
+
+ cR1=left_R;
+ cG1=left_G;
+ cB1=left_B;
+ difR=(right_R-cR1)/num;
+ difG=(right_G-cG1)/num;
+ difB=(right_B-cB1)/num;
+ difR2=difR<<1;
+ difG2=difG<<1;
+ difB2=difB<<1;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;cR1+=j*difR;cG1+=j*difG;cB1+=j*difB;}
+ xmax--;if(drawW<xmax) xmax=drawW;
+
+ for(j=xmin;j<=xmax;j++)
+ {
+ XAdjust=(posX>>16);
+ tC1 = psxVub[((posY>>5)&(int)0xFFFFF800)+YAdjust+
+ (XAdjust>>1)];
+ tC1=(tC1>>((XAdjust&1)<<2))&0xf;
+ if(iDither)
+ GetTextureTransColGX_Dither(&psxVuw[(i<<10)+j],
+ psxVuw[clutP+tC1],
+ (cB1>>16),(cG1>>16),(cR1>>16));
+ else
+ GetTextureTransColGX(&psxVuw[(i<<10)+j],
+ psxVuw[clutP+tC1],
+ (cB1>>16),(cG1>>16),(cR1>>16));
+ posX+=difX;
+ posY+=difY;
+ cR1+=difR;
+ cG1+=difG;
+ cB1+=difB;
+ }
+ }
+ if(NextRow_GT4()) return;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void drawPoly4TGEx4_TW(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4,
+ short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4,
+ short clX, short clY,
+ int col1, int col2, int col3, int col4)
+{
+ drawPoly3TGEx4_TW(x2,y2,x3,y3,x4,y4,
+ tx2,ty2,tx3,ty3,tx4,ty4,
+ clX,clY,
+ col2,col4,col3);
+
+ drawPoly3TGEx4_TW(x1,y1,x2,y2,x4,y4,
+ tx1,ty1,tx2,ty2,tx4,ty4,
+ clX,clY,
+ col1,col2,col3);
+}
+
+////////////////////////////////////////////////////////////////////////
+// POLY 3/4 G-SHADED TEX PAL8
+////////////////////////////////////////////////////////////////////////
+
+void drawPoly3TGEx8(short x1, short y1, short x2, short y2, short x3, short y3, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short clX, short clY, int col1, int col2, int col3)
+{
+ int i,j,xmin,xmax,ymin,ymax;
+ int cR1,cG1,cB1;
+ int difR,difB,difG,difR2,difB2,difG2;
+ int difX, difY,difX2, difY2;
+ int posX,posY,YAdjust,clutP;
+ short tC1,tC2;
+
+ if(x1>drawW && x2>drawW && x3>drawW) return;
+ if(y1>drawH && y2>drawH && y3>drawH) return;
+ if(x1<drawX && x2<drawX && x3<drawX) return;
+ if(y1<drawY && y2<drawY && y3<drawY) return;
+ if(drawY>=drawH) return;
+ if(drawX>=drawW) return;
+
+ if(!SetupSections_GT(x1,y1,x2,y2,x3,y3,tx1,ty1,tx2,ty2,tx3,ty3,col1,col2,col3)) return;
+
+ ymax=Ymax;
+
+ for(ymin=Ymin;ymin<drawY;ymin++)
+ if(NextRow_GT()) return;
+
+ clutP=(clY<<10)+clX;
+
+ YAdjust=((GlobalTextAddrY)<<11)+(GlobalTextAddrX<<1);
+
+ difR=delta_right_R;
+ difG=delta_right_G;
+ difB=delta_right_B;
+ difR2=difR<<1;
+ difG2=difG<<1;
+ difB2=difB<<1;
+ difX=delta_right_u;difX2=difX<<1;
+ difY=delta_right_v;difY2=difY<<1;
+
+#ifdef FASTSOLID
+
+ if(!bCheckMask && !DrawSemiTrans && !iDither)
+ {
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=(left_x >> 16);
+ xmax=(right_x >> 16)-1; // !!!!!!!!!!!!!
+ if(drawW<xmax) xmax=drawW;
+
+ if(xmax>=xmin)
+ {
+ posX=left_u;
+ posY=left_v;
+ cR1=left_R;
+ cG1=left_G;
+ cB1=left_B;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;cR1+=j*difR;cG1+=j*difG;cB1+=j*difB;}
+
+ for(j=xmin;j<xmax;j+=2)
+ {
+ tC1 = psxVub[((posY>>5)&(int)0xFFFFF800)+YAdjust+((posX>>16))];
+ tC2 = psxVub[(((posY+difY)>>5)&(int)0xFFFFF800)+YAdjust+
+ (((posX+difX)>>16))];
+ GetTextureTransColGX32_S((uint32_t *)&psxVuw[(i<<10)+j],
+ psxVuw[clutP+tC1]|
+ ((int)psxVuw[clutP+tC2])<<16,
+ (cB1>>16)|((cB1+difB)&0xff0000),
+ (cG1>>16)|((cG1+difG)&0xff0000),
+ (cR1>>16)|((cR1+difR)&0xff0000));
+ posX+=difX2;
+ posY+=difY2;
+ cR1+=difR2;
+ cG1+=difG2;
+ cB1+=difB2;
+ }
+ if(j==xmax)
+ {
+ tC1 = psxVub[((posY>>5)&(int)0xFFFFF800)+YAdjust+((posX>>16))];
+ GetTextureTransColGX_S(&psxVuw[(i<<10)+j],
+ psxVuw[clutP+tC1],
+ (cB1>>16),(cG1>>16),(cR1>>16));
+ }
+ }
+ if(NextRow_GT())
+ {
+ return;
+ }
+ }
+ return;
+ }
+
+#endif
+
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=(left_x >> 16);
+ xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!!!!!!!!!!!
+ if(drawW<xmax) xmax=drawW;
+
+ if(xmax>=xmin)
+ {
+ posX=left_u;
+ posY=left_v;
+ cR1=left_R;
+ cG1=left_G;
+ cB1=left_B;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;cR1+=j*difR;cG1+=j*difG;cB1+=j*difB;}
+
+ for(j=xmin;j<=xmax;j++)
+ {
+ tC1 = psxVub[((posY>>5)&(int)0xFFFFF800)+YAdjust+((posX>>16))];
+ if(iDither)
+ GetTextureTransColGX_Dither(&psxVuw[(i<<10)+j],
+ psxVuw[clutP+tC1],
+ (cB1>>16),(cG1>>16),(cR1>>16));
+ else
+ GetTextureTransColGX(&psxVuw[(i<<10)+j],
+ psxVuw[clutP+tC1],
+ (cB1>>16),(cG1>>16),(cR1>>16));
+ posX+=difX;
+ posY+=difY;
+ cR1+=difR;
+ cG1+=difG;
+ cB1+=difB;
+ }
+ }
+ if(NextRow_GT())
+ {
+ return;
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void drawPoly3TGEx8_IL(short x1, short y1, short x2, short y2, short x3, short y3, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short clX, short clY, int col1, int col2, int col3)
+{
+ int i,j,xmin,xmax,ymin,ymax,n_xi,n_yi,TXV,TXU;
+ int cR1,cG1,cB1;
+ int difR,difB,difG,difR2,difB2,difG2;
+ int difX, difY,difX2, difY2;
+ int posX,posY,YAdjust,clutP;
+ short tC1,tC2;
+
+ if(x1>drawW && x2>drawW && x3>drawW) return;
+ if(y1>drawH && y2>drawH && y3>drawH) return;
+ if(x1<drawX && x2<drawX && x3<drawX) return;
+ if(y1<drawY && y2<drawY && y3<drawY) return;
+ if(drawY>=drawH) return;
+ if(drawX>=drawW) return;
+
+ if(!SetupSections_GT(x1,y1,x2,y2,x3,y3,tx1,ty1,tx2,ty2,tx3,ty3,col1,col2,col3)) return;
+
+ ymax=Ymax;
+
+ for(ymin=Ymin;ymin<drawY;ymin++)
+ if(NextRow_GT()) return;
+
+ clutP=(clY<<10)+clX;
+
+ YAdjust=(GlobalTextAddrY<<10)+GlobalTextAddrX;
+
+ difR=delta_right_R;
+ difG=delta_right_G;
+ difB=delta_right_B;
+ difR2=difR<<1;
+ difG2=difG<<1;
+ difB2=difB<<1;
+ difX=delta_right_u;difX2=difX<<1;
+ difY=delta_right_v;difY2=difY<<1;
+
+#ifdef FASTSOLID
+
+ if(!bCheckMask && !DrawSemiTrans && !iDither)
+ {
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=(left_x >> 16);
+ xmax=(right_x >> 16)-1; // !!!!!!!!!!!!!
+ if(drawW<xmax) xmax=drawW;
+
+ if(xmax>=xmin)
+ {
+ posX=left_u;
+ posY=left_v;
+ cR1=left_R;
+ cG1=left_G;
+ cB1=left_B;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;cR1+=j*difR;cG1+=j*difG;cB1+=j*difB;}
+
+ for(j=xmin;j<xmax;j+=2)
+ {
+ TXU=posX>>16;
+ TXV=posY>>16;
+ n_xi = ( ( TXU >> 1 ) & ~0x78 ) + ( ( TXU << 2 ) & 0x40 ) + ( ( TXV << 3 ) & 0x38 );
+ n_yi = ( TXV & ~0x7 ) + ( ( TXU >> 5 ) & 0x7 );
+
+ tC1= (psxVuw[(n_yi<<10)+YAdjust+n_xi] >> ((TXU & 0x01)<<3)) & 0xff;
+
+ TXU=(posX+difX)>>16;
+ TXV=(posY+difY)>>16;
+ n_xi = ( ( TXU >> 1 ) & ~0x78 ) + ( ( TXU << 2 ) & 0x40 ) + ( ( TXV << 3 ) & 0x38 );
+ n_yi = ( TXV & ~0x7 ) + ( ( TXU >> 5 ) & 0x7 );
+
+ tC2= (psxVuw[(n_yi<<10)+YAdjust+n_xi] >> ((TXU & 0x01)<<3)) & 0xff;
+
+ GetTextureTransColGX32_S((uint32_t *)&psxVuw[(i<<10)+j],
+ psxVuw[clutP+tC1]|
+ ((int)psxVuw[clutP+tC2])<<16,
+ (cB1>>16)|((cB1+difB)&0xff0000),
+ (cG1>>16)|((cG1+difG)&0xff0000),
+ (cR1>>16)|((cR1+difR)&0xff0000));
+ posX+=difX2;
+ posY+=difY2;
+ cR1+=difR2;
+ cG1+=difG2;
+ cB1+=difB2;
+ }
+ if(j==xmax)
+ {
+ TXU=posX>>16;
+ TXV=posY>>16;
+ n_xi = ( ( TXU >> 1 ) & ~0x78 ) + ( ( TXU << 2 ) & 0x40 ) + ( ( TXV << 3 ) & 0x38 );
+ n_yi = ( TXV & ~0x7 ) + ( ( TXU >> 5 ) & 0x7 );
+
+ tC1= (psxVuw[(n_yi<<10)+YAdjust+n_xi] >> ((TXU & 0x01)<<3)) & 0xff;
+
+ GetTextureTransColGX_S(&psxVuw[(i<<10)+j],
+ psxVuw[clutP+tC1],
+ (cB1>>16),(cG1>>16),(cR1>>16));
+ }
+ }
+ if(NextRow_GT())
+ {
+ return;
+ }
+ }
+ return;
+ }
+
+#endif
+
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=(left_x >> 16);
+ xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!!!!!!!!!!!
+ if(drawW<xmax) xmax=drawW;
+
+ if(xmax>=xmin)
+ {
+ posX=left_u;
+ posY=left_v;
+ cR1=left_R;
+ cG1=left_G;
+ cB1=left_B;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;cR1+=j*difR;cG1+=j*difG;cB1+=j*difB;}
+
+ for(j=xmin;j<=xmax;j++)
+ {
+ TXU=posX>>16;
+ TXV=posY>>16;
+ n_xi = ( ( TXU >> 1 ) & ~0x78 ) + ( ( TXU << 2 ) & 0x40 ) + ( ( TXV << 3 ) & 0x38 );
+ n_yi = ( TXV & ~0x7 ) + ( ( TXU >> 5 ) & 0x7 );
+
+ tC1= (psxVuw[(n_yi<<10)+YAdjust+n_xi] >> ((TXU & 0x01)<<3)) & 0xff;
+
+ if(iDither)
+ GetTextureTransColGX_Dither(&psxVuw[(i<<10)+j],
+ psxVuw[clutP+tC1],
+ (cB1>>16),(cG1>>16),(cR1>>16));
+ else
+ GetTextureTransColGX(&psxVuw[(i<<10)+j],
+ psxVuw[clutP+tC1],
+ (cB1>>16),(cG1>>16),(cR1>>16));
+ posX+=difX;
+ posY+=difY;
+ cR1+=difR;
+ cG1+=difG;
+ cB1+=difB;
+ }
+ }
+ if(NextRow_GT())
+ {
+ return;
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void drawPoly3TGEx8_TW(short x1, short y1, short x2, short y2, short x3, short y3, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short clX, short clY, int col1, int col2, int col3)
+{
+ int i,j,xmin,xmax,ymin,ymax;
+ int cR1,cG1,cB1;
+ int difR,difB,difG,difR2,difB2,difG2;
+ int difX, difY,difX2, difY2;
+ int posX,posY,YAdjust,clutP;
+ short tC1,tC2;
+
+ if(x1>drawW && x2>drawW && x3>drawW) return;
+ if(y1>drawH && y2>drawH && y3>drawH) return;
+ if(x1<drawX && x2<drawX && x3<drawX) return;
+ if(y1<drawY && y2<drawY && y3<drawY) return;
+ if(drawY>=drawH) return;
+ if(drawX>=drawW) return;
+
+ if(!SetupSections_GT(x1,y1,x2,y2,x3,y3,tx1,ty1,tx2,ty2,tx3,ty3,col1,col2,col3)) return;
+
+ ymax=Ymax;
+
+ for(ymin=Ymin;ymin<drawY;ymin++)
+ if(NextRow_GT()) return;
+
+ clutP=(clY<<10)+clX;
+
+ YAdjust=((GlobalTextAddrY)<<11)+(GlobalTextAddrX<<1);
+ YAdjust+=(TWin.Position.y0<<11)+(TWin.Position.x0);
+
+ difR=delta_right_R;
+ difG=delta_right_G;
+ difB=delta_right_B;
+ difR2=difR<<1;
+ difG2=difG<<1;
+ difB2=difB<<1;
+ difX=delta_right_u;difX2=difX<<1;
+ difY=delta_right_v;difY2=difY<<1;
+
+#ifdef FASTSOLID
+
+ if(!bCheckMask && !DrawSemiTrans && !iDither)
+ {
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=(left_x >> 16);
+ xmax=(right_x >> 16)-1; // !!!!!!!!!!!!!
+ if(drawW<xmax) xmax=drawW;
+
+ if(xmax>=xmin)
+ {
+ posX=left_u;
+ posY=left_v;
+ cR1=left_R;
+ cG1=left_G;
+ cB1=left_B;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;cR1+=j*difR;cG1+=j*difG;cB1+=j*difB;}
+
+ for(j=xmin;j<xmax;j+=2)
+ {
+ tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+
+ YAdjust+((posX>>16)%TWin.Position.x1)];
+ tC2 = psxVub[((((posY+difY)>>16)%TWin.Position.y1)<<11)+
+ YAdjust+(((posX+difX)>>16)%TWin.Position.x1)];
+
+ GetTextureTransColGX32_S((uint32_t *)&psxVuw[(i<<10)+j],
+ psxVuw[clutP+tC1]|
+ ((int)psxVuw[clutP+tC2])<<16,
+ (cB1>>16)|((cB1+difB)&0xff0000),
+ (cG1>>16)|((cG1+difG)&0xff0000),
+ (cR1>>16)|((cR1+difR)&0xff0000));
+ posX+=difX2;
+ posY+=difY2;
+ cR1+=difR2;
+ cG1+=difG2;
+ cB1+=difB2;
+ }
+ if(j==xmax)
+ {
+ tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+
+ YAdjust+((posX>>16)%TWin.Position.x1)];
+ GetTextureTransColGX_S(&psxVuw[(i<<10)+j],
+ psxVuw[clutP+tC1],
+ (cB1>>16),(cG1>>16),(cR1>>16));
+ }
+ }
+ if(NextRow_GT())
+ {
+ return;
+ }
+ }
+ return;
+ }
+
+#endif
+
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=(left_x >> 16);
+ xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!!!!!!!!!!!
+ if(drawW<xmax) xmax=drawW;
+
+ if(xmax>=xmin)
+ {
+ posX=left_u;
+ posY=left_v;
+ cR1=left_R;
+ cG1=left_G;
+ cB1=left_B;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;cR1+=j*difR;cG1+=j*difG;cB1+=j*difB;}
+
+ for(j=xmin;j<=xmax;j++)
+ {
+ tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+
+ YAdjust+((posX>>16)%TWin.Position.x1)];
+ if(iDither)
+ GetTextureTransColGX_Dither(&psxVuw[(i<<10)+j],
+ psxVuw[clutP+tC1],
+ (cB1>>16),(cG1>>16),(cR1>>16));
+ else
+ GetTextureTransColGX(&psxVuw[(i<<10)+j],
+ psxVuw[clutP+tC1],
+ (cB1>>16),(cG1>>16),(cR1>>16));
+ posX+=difX;
+ posY+=difY;
+ cR1+=difR;
+ cG1+=difG;
+ cB1+=difB;
+ }
+ }
+ if(NextRow_GT())
+ {
+ return;
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+// note: two g-shaded tris: small texture distortions can happen
+
+void drawPoly4TGEx8_TRI_IL(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4,
+ short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4,
+ short clX, short clY,
+ int col1, int col2, int col3, int col4)
+{
+ drawPoly3TGEx8_IL(x2,y2,x3,y3,x4,y4,
+ tx2,ty2,tx3,ty3,tx4,ty4,
+ clX,clY,
+ col2,col4,col3);
+ drawPoly3TGEx8_IL(x1,y1,x2,y2,x4,y4,
+ tx1,ty1,tx2,ty2,tx4,ty4,
+ clX,clY,
+ col1,col2,col3);
+}
+
+#ifdef POLYQUAD3GT
+
+void drawPoly4TGEx8_TRI(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4,
+ short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4,
+ short clX, short clY,
+ int col1, int col2, int col3, int col4)
+{
+ drawPoly3TGEx8(x2,y2,x3,y3,x4,y4,
+ tx2,ty2,tx3,ty3,tx4,ty4,
+ clX,clY,
+ col2,col4,col3);
+ drawPoly3TGEx8(x1,y1,x2,y2,x4,y4,
+ tx1,ty1,tx2,ty2,tx4,ty4,
+ clX,clY,
+ col1,col2,col3);
+}
+
+#endif
+
+void drawPoly4TGEx8(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4,
+ short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4,
+ short clX, short clY,
+ int col1, int col2, int col4, int col3)
+{
+ int num;
+ int i,j,xmin,xmax,ymin,ymax;
+ int cR1,cG1,cB1;
+ int difR,difB,difG,difR2,difB2,difG2;
+ int difX, difY, difX2, difY2;
+ int posX,posY,YAdjust,clutP;
+ short tC1,tC2;
+
+ if(x1>drawW && x2>drawW && x3>drawW && x4>drawW) return;
+ if(y1>drawH && y2>drawH && y3>drawH && y4>drawH) return;
+ if(x1<drawX && x2<drawX && x3<drawX && x4<drawX) return;
+ if(y1<drawY && y2<drawY && y3<drawY && y4<drawY) return;
+ if(drawY>=drawH) return;
+ if(drawX>=drawW) return;
+
+ if(!SetupSections_GT4(x1,y1,x2,y2,x3,y3,x4,y4,tx1,ty1,tx2,ty2,tx3,ty3,tx4,ty4,col1,col2,col3,col4)) return;
+
+ ymax=Ymax;
+
+ for(ymin=Ymin;ymin<drawY;ymin++)
+ if(NextRow_GT4()) return;
+
+ clutP=(clY<<10)+clX;
+
+ YAdjust=((GlobalTextAddrY)<<11)+(GlobalTextAddrX<<1);
+
+#ifdef FASTSOLID
+
+ if(!bCheckMask && !DrawSemiTrans && !iDither)
+ {
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=(left_x >> 16);
+ xmax=(right_x >> 16);
+
+ if(xmax>=xmin)
+ {
+ posX=left_u;
+ posY=left_v;
+
+ num=(xmax-xmin);
+ if(num==0) num=1;
+ difX=(right_u-posX)/num;
+ difY=(right_v-posY)/num;
+ difX2=difX<<1;
+ difY2=difY<<1;
+
+ cR1=left_R;
+ cG1=left_G;
+ cB1=left_B;
+ difR=(right_R-cR1)/num;
+ difG=(right_G-cG1)/num;
+ difB=(right_B-cB1)/num;
+ difR2=difR<<1;
+ difG2=difG<<1;
+ difB2=difB<<1;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;cR1+=j*difR;cG1+=j*difG;cB1+=j*difB;}
+ xmax--;if(drawW<xmax) xmax=drawW;
+
+ for(j=xmin;j<xmax;j+=2)
+ {
+ tC1 = psxVub[((posY>>5)&(int)0xFFFFF800)+YAdjust+(posX>>16)];
+ tC2 = psxVub[(((posY+difY)>>5)&(int)0xFFFFF800)+YAdjust+
+ ((posX+difX)>>16)];
+
+ GetTextureTransColGX32_S((uint32_t *)&psxVuw[(i<<10)+j],
+ psxVuw[clutP+tC1]|
+ ((int)psxVuw[clutP+tC2])<<16,
+ (cB1>>16)|((cB1+difB)&0xff0000),
+ (cG1>>16)|((cG1+difG)&0xff0000),
+ (cR1>>16)|((cR1+difR)&0xff0000));
+ posX+=difX2;
+ posY+=difY2;
+ cR1+=difR2;
+ cG1+=difG2;
+ cB1+=difB2;
+ }
+ if(j==xmax)
+ {
+ tC1 = psxVub[((posY>>5)&(int)0xFFFFF800)+YAdjust+(posX>>16)];
+ GetTextureTransColGX_S(&psxVuw[(i<<10)+j],
+ psxVuw[clutP+tC1],
+ (cB1>>16),(cG1>>16),(cR1>>16));
+ }
+ }
+ if(NextRow_GT4()) return;
+ }
+ return;
+ }
+
+#endif
+
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=(left_x >> 16);
+ xmax=(right_x >> 16);
+
+ if(xmax>=xmin)
+ {
+ posX=left_u;
+ posY=left_v;
+
+ num=(xmax-xmin);
+ if(num==0) num=1;
+ difX=(right_u-posX)/num;
+ difY=(right_v-posY)/num;
+ difX2=difX<<1;
+ difY2=difY<<1;
+
+ cR1=left_R;
+ cG1=left_G;
+ cB1=left_B;
+ difR=(right_R-cR1)/num;
+ difG=(right_G-cG1)/num;
+ difB=(right_B-cB1)/num;
+ difR2=difR<<1;
+ difG2=difG<<1;
+ difB2=difB<<1;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;cR1+=j*difR;cG1+=j*difG;cB1+=j*difB;}
+ xmax--;if(drawW<xmax) xmax=drawW;
+
+ for(j=xmin;j<=xmax;j++)
+ {
+ tC1 = psxVub[((posY>>5)&(int)0xFFFFF800)+YAdjust+(posX>>16)];
+ if(iDither)
+ GetTextureTransColGX_Dither(&psxVuw[(i<<10)+j],
+ psxVuw[clutP+tC1],
+ (cB1>>16),(cG1>>16),(cR1>>16));
+ else
+ GetTextureTransColGX(&psxVuw[(i<<10)+j],
+ psxVuw[clutP+tC1],
+ (cB1>>16),(cG1>>16),(cR1>>16));
+ posX+=difX;
+ posY+=difY;
+ cR1+=difR;
+ cG1+=difG;
+ cB1+=difB;
+ }
+ }
+ if(NextRow_GT4()) return;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void drawPoly4TGEx8_TW(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4,
+ short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4,
+ short clX, short clY,
+ int col1, int col2, int col3, int col4)
+{
+ drawPoly3TGEx8_TW(x2,y2,x3,y3,x4,y4,
+ tx2,ty2,tx3,ty3,tx4,ty4,
+ clX,clY,
+ col2,col4,col3);
+ drawPoly3TGEx8_TW(x1,y1,x2,y2,x4,y4,
+ tx1,ty1,tx2,ty2,tx4,ty4,
+ clX,clY,
+ col1,col2,col3);
+}
+
+////////////////////////////////////////////////////////////////////////
+// POLY 3 G-SHADED TEX 15 BIT
+////////////////////////////////////////////////////////////////////////
+
+void drawPoly3TGD(short x1, short y1, short x2, short y2, short x3, short y3, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, int col1, int col2, int col3)
+{
+ int i,j,xmin,xmax,ymin,ymax;
+ int cR1,cG1,cB1;
+ int difR,difB,difG,difR2,difB2,difG2;
+ int difX, difY,difX2, difY2;
+ int posX,posY;
+
+ if(x1>drawW && x2>drawW && x3>drawW) return;
+ if(y1>drawH && y2>drawH && y3>drawH) return;
+ if(x1<drawX && x2<drawX && x3<drawX) return;
+ if(y1<drawY && y2<drawY && y3<drawY) return;
+ if(drawY>=drawH) return;
+ if(drawX>=drawW) return;
+
+ if(!SetupSections_GT(x1,y1,x2,y2,x3,y3,tx1,ty1,tx2,ty2,tx3,ty3,col1,col2,col3)) return;
+
+ ymax=Ymax;
+
+ for(ymin=Ymin;ymin<drawY;ymin++)
+ if(NextRow_GT()) return;
+
+ difR=delta_right_R;
+ difG=delta_right_G;
+ difB=delta_right_B;
+ difR2=difR<<1;
+ difG2=difG<<1;
+ difB2=difB<<1;
+ difX=delta_right_u;difX2=difX<<1;
+ difY=delta_right_v;difY2=difY<<1;
+
+#ifdef FASTSOLID
+
+ if(!bCheckMask && !DrawSemiTrans && !iDither)
+ {
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=(left_x >> 16);
+ xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!!!!!!!!
+ if(drawW<xmax) xmax=drawW;
+
+ if(xmax>=xmin)
+ {
+ posX=left_u;
+ posY=left_v;
+ cR1=left_R;
+ cG1=left_G;
+ cB1=left_B;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;cR1+=j*difR;cG1+=j*difG;cB1+=j*difB;}
+
+ for(j=xmin;j<xmax;j+=2)
+ {
+ GetTextureTransColGX32_S((uint32_t *)&psxVuw[(i<<10)+j],
+ (((int)psxVuw[((((posY+difY)>>16)+GlobalTextAddrY)<<10)+((posX+difX)>>16)+GlobalTextAddrX])<<16)|
+ psxVuw[(((posY>>16)+GlobalTextAddrY)<<10)+((posX)>>16)+GlobalTextAddrX],
+ (cB1>>16)|((cB1+difB)&0xff0000),
+ (cG1>>16)|((cG1+difG)&0xff0000),
+ (cR1>>16)|((cR1+difR)&0xff0000));
+ posX+=difX2;
+ posY+=difY2;
+ cR1+=difR2;
+ cG1+=difG2;
+ cB1+=difB2;
+ }
+ if(j==xmax)
+ GetTextureTransColGX_S(&psxVuw[(i<<10)+j],
+ psxVuw[(((posY>>16)+GlobalTextAddrY)<<10)+(posX>>16)+GlobalTextAddrX],
+ (cB1>>16),(cG1>>16),(cR1>>16));
+ }
+ if(NextRow_GT())
+ {
+ return;
+ }
+ }
+ return;
+ }
+
+#endif
+
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=(left_x >> 16);
+ xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!!!!!!
+ if(drawW<xmax) xmax=drawW;
+
+ if(xmax>=xmin)
+ {
+ posX=left_u;
+ posY=left_v;
+ cR1=left_R;
+ cG1=left_G;
+ cB1=left_B;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;cR1+=j*difR;cG1+=j*difG;cB1+=j*difB;}
+
+ for(j=xmin;j<=xmax;j++)
+ {
+ if(iDither)
+ GetTextureTransColGX_Dither(&psxVuw[(i<<10)+j],
+ psxVuw[(((posY>>16)+GlobalTextAddrY)<<10)+(posX>>16)+GlobalTextAddrX],
+ (cB1>>16),(cG1>>16),(cR1>>16));
+ else
+ GetTextureTransColGX(&psxVuw[(i<<10)+j],
+ psxVuw[(((posY>>16)+GlobalTextAddrY)<<10)+(posX>>16)+GlobalTextAddrX],
+ (cB1>>16),(cG1>>16),(cR1>>16));
+ posX+=difX;
+ posY+=difY;
+ cR1+=difR;
+ cG1+=difG;
+ cB1+=difB;
+ }
+ }
+ if(NextRow_GT())
+ {
+ return;
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void drawPoly3TGD_TW(short x1, short y1, short x2, short y2, short x3, short y3, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, int col1, int col2, int col3)
+{
+ int i,j,xmin,xmax,ymin,ymax;
+ int cR1,cG1,cB1;
+ int difR,difB,difG,difR2,difB2,difG2;
+ int difX, difY,difX2, difY2;
+ int posX,posY;
+
+ if (x1>drawW && x2>drawW && x3>drawW) return;
+ if (y1>drawH && y2>drawH && y3>drawH) return;
+ if (x1<drawX && x2<drawX && x3<drawX) return;
+ if (y1<drawY && y2<drawY && y3<drawY) return;
+ if (drawY >= drawH) return;
+ if (drawX >= drawW) return;
+
+ if (!SetupSections_GT(x1,y1,x2,y2,x3,y3,tx1,ty1,tx2,ty2,tx3,ty3,col1,col2,col3)) return;
+
+ ymax = Ymax;
+
+ for(ymin = Ymin; ymin < drawY; ymin++)
+ if(NextRow_GT()) return;
+
+ difR = delta_right_R;
+ difG = delta_right_G;
+ difB = delta_right_B;
+ difR2 = difR<<1;
+ difG2 = difG<<1;
+ difB2 = difB<<1;
+ difX = delta_right_u; difX2 = difX<<1;
+ difY = delta_right_v; difY2 = difY<<1;
+
+#ifdef FASTSOLID
+
+ if (!bCheckMask && !DrawSemiTrans && !iDither)
+ {
+ for (i = ymin; i <= ymax; i++)
+ {
+ xmin = (left_x >> 16);
+ xmax = (right_x >> 16) - 1; //!!!!!!!!!!!!!!!!!!!!
+ if(drawW<xmax) xmax=drawW;
+
+ if(xmax>=xmin)
+ {
+ posX=left_u;
+ posY=left_v;
+ cR1=left_R;
+ cG1=left_G;
+ cB1=left_B;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;cR1+=j*difR;cG1+=j*difG;cB1+=j*difB;}
+
+ for(j=xmin;j<xmax;j+=2)
+ {
+ GetTextureTransColGX32_S((uint32_t *)&psxVuw[(i<<10)+j],
+ (((int)psxVuw[(((((posY+difY)>>16)%TWin.Position.y1)+GlobalTextAddrY+TWin.Position.y0)<<10)+
+ (((posX+difX)>>16)%TWin.Position.x1)+GlobalTextAddrX+TWin.Position.x0])<<16)|
+ psxVuw[((((posY>>16)%TWin.Position.y1)+GlobalTextAddrY+TWin.Position.y0)<<10)+
+ (((posX)>>16)%TWin.Position.x1)+GlobalTextAddrX+TWin.Position.x0],
+ (cB1>>16)|((cB1+difB)&0xff0000),
+ (cG1>>16)|((cG1+difG)&0xff0000),
+ (cR1>>16)|((cR1+difR)&0xff0000));
+ posX+=difX2;
+ posY+=difY2;
+ cR1+=difR2;
+ cG1+=difG2;
+ cB1+=difB2;
+ }
+ if(j==xmax)
+ GetTextureTransColGX_S(&psxVuw[(i<<10)+j],
+ psxVuw[((((posY>>16)%TWin.Position.y1)+GlobalTextAddrY+TWin.Position.y0)<<10)+
+ ((posX>>16)%TWin.Position.x1)+GlobalTextAddrX+TWin.Position.x0],
+ (cB1>>16),(cG1>>16),(cR1>>16));
+ }
+ if(NextRow_GT())
+ {
+ return;
+ }
+ }
+ return;
+ }
+
+#endif
+
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=(left_x >> 16);
+ xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!!!!!!
+ if(drawW<xmax) xmax=drawW;
+
+ if(xmax>=xmin)
+ {
+ posX=left_u;
+ posY=left_v;
+ cR1=left_R;
+ cG1=left_G;
+ cB1=left_B;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;cR1+=j*difR;cG1+=j*difG;cB1+=j*difB;}
+
+ for(j=xmin;j<=xmax;j++)
+ {
+ if(iDither)
+ GetTextureTransColGX_Dither(&psxVuw[(i<<10)+j],
+ psxVuw[((((posY>>16)%TWin.Position.y1)+GlobalTextAddrY+TWin.Position.y0)<<10)+
+ ((posX>>16)%TWin.Position.x1)+GlobalTextAddrX+TWin.Position.x0],
+ (cB1>>16),(cG1>>16),(cR1>>16));
+ else
+ GetTextureTransColGX(&psxVuw[(i<<10)+j],
+ psxVuw[((((posY>>16)%TWin.Position.y1)+GlobalTextAddrY+TWin.Position.y0)<<10)+
+ ((posX>>16)%TWin.Position.x1)+GlobalTextAddrX+TWin.Position.x0],
+ (cB1>>16),(cG1>>16),(cR1>>16));
+ posX+=difX;
+ posY+=difY;
+ cR1+=difR;
+ cG1+=difG;
+ cB1+=difB;
+ }
+ }
+ if(NextRow_GT())
+ {
+ return;
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+// note: two g-shaded tris: small texture distortions can happen
+
+#ifdef POLYQUAD3GT
+
+void drawPoly4TGD_TRI(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4, int col1, int col2, int col3, int col4)
+{
+ drawPoly3TGD(x2,y2,x3,y3,x4,y4,
+ tx2,ty2,tx3,ty3,tx4,ty4,
+ col2,col4,col3);
+ drawPoly3TGD(x1,y1,x2,y2,x4,y4,
+ tx1,ty1,tx2,ty2,tx4,ty4,
+ col1,col2,col3);
+}
+
+#endif
+
+void drawPoly4TGD(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4, int col1, int col2, int col4, int col3)
+{
+ int num;
+ int i,j,xmin,xmax,ymin,ymax;
+ int cR1,cG1,cB1;
+ int difR,difB,difG,difR2,difB2,difG2;
+ int difX, difY, difX2, difY2;
+ int posX,posY;
+
+ if(x1>drawW && x2>drawW && x3>drawW && x4>drawW) return;
+ if(y1>drawH && y2>drawH && y3>drawH && y4>drawH) return;
+ if(x1<drawX && x2<drawX && x3<drawX && x4<drawX) return;
+ if(y1<drawY && y2<drawY && y3<drawY && y4<drawY) return;
+ if(drawY>=drawH) return;
+ if(drawX>=drawW) return;
+
+ if(!SetupSections_GT4(x1,y1,x2,y2,x3,y3,x4,y4,tx1,ty1,tx2,ty2,tx3,ty3,tx4,ty4,col1,col2,col3,col4)) return;
+
+ ymax = Ymax;
+
+ for (ymin = Ymin; ymin < drawY; ymin++)
+ if (NextRow_GT4()) return;
+
+#ifdef FASTSOLID
+
+ if(!bCheckMask && !DrawSemiTrans && !iDither)
+ {
+ for (i = ymin; i <= ymax; i++)
+ {
+ xmin = (left_x >> 16);
+ xmax = (right_x >> 16);
+
+ if(xmax >= xmin)
+ {
+ posX = left_u;
+ posY = left_v;
+
+ num = (xmax-xmin);
+ if(num==0) num=1;
+ difX=(right_u-posX)/num;
+ difY=(right_v-posY)/num;
+ difX2=difX<<1;
+ difY2=difY<<1;
+
+ cR1=left_R;
+ cG1=left_G;
+ cB1=left_B;
+ difR=(right_R-cR1)/num;
+ difG=(right_G-cG1)/num;
+ difB=(right_B-cB1)/num;
+ difR2=difR<<1;
+ difG2=difG<<1;
+ difB2=difB<<1;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;cR1+=j*difR;cG1+=j*difG;cB1+=j*difB;}
+ xmax--;if(drawW<xmax) xmax=drawW;
+
+ for(j=xmin;j<xmax;j+=2)
+ {
+ GetTextureTransColGX32_S((uint32_t *)&psxVuw[(i<<10)+j],
+ (((int)psxVuw[((((posY+difY)>>16)+GlobalTextAddrY)<<10)+((posX+difX)>>16)+GlobalTextAddrX])<<16)|
+ psxVuw[(((posY>>16)+GlobalTextAddrY)<<10)+((posX)>>16)+GlobalTextAddrX],
+ (cB1>>16)|((cB1+difB)&0xff0000),
+ (cG1>>16)|((cG1+difG)&0xff0000),
+ (cR1>>16)|((cR1+difR)&0xff0000));
+ posX+=difX2;
+ posY+=difY2;
+ cR1+=difR2;
+ cG1+=difG2;
+ cB1+=difB2;
+ }
+ if(j==xmax)
+ GetTextureTransColGX_S(&psxVuw[(i<<10)+j],
+ psxVuw[(((posY>>16)+GlobalTextAddrY)<<10)+(posX>>16)+GlobalTextAddrX],
+ (cB1>>16),(cG1>>16),(cR1>>16));
+ }
+ if(NextRow_GT4()) return;
+ }
+ return;
+ }
+
+#endif
+
+ for (i=ymin;i<=ymax;i++)
+ {
+ xmin=(left_x >> 16);
+ xmax=(right_x >> 16);
+
+ if(xmax>=xmin)
+ {
+ posX=left_u;
+ posY=left_v;
+
+ num=(xmax-xmin);
+ if(num==0) num=1;
+ difX=(right_u-posX)/num;
+ difY=(right_v-posY)/num;
+ difX2=difX<<1;
+ difY2=difY<<1;
+
+ cR1=left_R;
+ cG1=left_G;
+ cB1=left_B;
+ difR=(right_R-cR1)/num;
+ difG=(right_G-cG1)/num;
+ difB=(right_B-cB1)/num;
+ difR2=difR<<1;
+ difG2=difG<<1;
+ difB2=difB<<1;
+
+ if(xmin<drawX)
+ {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;cR1+=j*difR;cG1+=j*difG;cB1+=j*difB;}
+ xmax--;if(drawW<xmax) xmax=drawW;
+
+ for(j=xmin;j<=xmax;j++)
+ {
+ if(iDither)
+ GetTextureTransColGX(&psxVuw[(i<<10)+j],
+ psxVuw[(((posY>>16)+GlobalTextAddrY)<<10)+(posX>>16)+GlobalTextAddrX],
+ (cB1>>16),(cG1>>16),(cR1>>16));
+ else
+ GetTextureTransColGX(&psxVuw[(i<<10)+j],
+ psxVuw[(((posY>>16)+GlobalTextAddrY)<<10)+(posX>>16)+GlobalTextAddrX],
+ (cB1>>16),(cG1>>16),(cR1>>16));
+ posX+=difX;
+ posY+=difY;
+ cR1+=difR;
+ cG1+=difG;
+ cB1+=difB;
+ }
+ }
+ if(NextRow_GT4()) return;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void drawPoly4TGD_TW(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4, int col1, int col2, int col3, int col4)
+{
+ drawPoly3TGD_TW(x2,y2,x3,y3,x4,y4,
+ tx2,ty2,tx3,ty3,tx4,ty4,
+ col2,col4,col3);
+ drawPoly3TGD_TW(x1,y1,x2,y2,x4,y4,
+ tx1,ty1,tx2,ty2,tx4,ty4,
+ col1,col2,col3);
+}
+
+////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////
+
+
+/*
+// no real rect test, but it does its job the way I need it
+__inline BOOL IsNoRect(void)
+{
+ if(lx0==lx1 && lx2==lx3) return FALSE;
+ if(lx0==lx2 && lx1==lx3) return FALSE;
+ if(lx0==lx3 && lx1==lx2) return FALSE;
+ return TRUE;
+}
+*/
+
+// real rect test
+__inline BOOL IsNoRect(void)
+{
+ //if(!(dwActFixes&0x200)) return FALSE;
+
+ if(ly0==ly1)
+ {
+ if(lx1==lx3 && ly3==ly2 && lx2==lx0) return FALSE;
+ if(lx1==lx2 && ly2==ly3 && lx3==lx0) return FALSE;
+ return TRUE;
+ }
+
+ if(ly0==ly2)
+ {
+ if(lx2==lx3 && ly3==ly1 && lx1==lx0) return FALSE;
+ if(lx2==lx1 && ly1==ly3 && lx3==lx0) return FALSE;
+ return TRUE;
+ }
+
+ if(ly0==ly3)
+ {
+ if(lx3==lx2 && ly2==ly1 && lx1==lx0) return FALSE;
+ if(lx3==lx1 && ly1==ly2 && lx2==lx0) return FALSE;
+ return TRUE;
+ }
+ return TRUE;
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void drawPoly3FT(unsigned char *baseAddr)
+{
+ uint32_t *gpuData = ((uint32_t *) baseAddr);
+
+ if(GlobalTextIL && GlobalTextTP<2)
+ {
+ if(GlobalTextTP==0)
+ drawPoly3TEx4_IL(lx0,ly0,lx1,ly1,lx2,ly2,
+ (gpuData[2] & 0x000000ff), ((gpuData[2]>>8) & 0x000000ff), (gpuData[4] & 0x000000ff), ((gpuData[4]>>8) & 0x000000ff),(gpuData[6] & 0x000000ff), ((gpuData[6]>>8) & 0x000000ff),
+ ((gpuData[2]>>12) & 0x3f0), ((gpuData[2]>>22) & iGPUHeightMask));
+ else
+ drawPoly3TEx8_IL(lx0,ly0,lx1,ly1,lx2,ly2,
+ (gpuData[2] & 0x000000ff), ((gpuData[2]>>8) & 0x000000ff), (gpuData[4] & 0x000000ff), ((gpuData[4]>>8) & 0x000000ff),(gpuData[6] & 0x000000ff), ((gpuData[6]>>8) & 0x000000ff),
+ ((gpuData[2]>>12) & 0x3f0), ((gpuData[2]>>22) & iGPUHeightMask));
+ return;
+ }
+
+ if(!bUsingTWin)// && !(dwActFixes&0x100))
+ {
+ switch(GlobalTextTP) // depending on texture mode
+ {
+ case 0:
+ drawPoly3TEx4(lx0,ly0,lx1,ly1,lx2,ly2,
+ (gpuData[2] & 0x000000ff), ((gpuData[2]>>8) & 0x000000ff), (gpuData[4] & 0x000000ff), ((gpuData[4]>>8) & 0x000000ff),(gpuData[6] & 0x000000ff), ((gpuData[6]>>8) & 0x000000ff),
+ ((gpuData[2]>>12) & 0x3f0), ((gpuData[2]>>22) & iGPUHeightMask));
+ return;
+ case 1:
+ drawPoly3TEx8(lx0,ly0,lx1,ly1,lx2,ly2,
+ (gpuData[2] & 0x000000ff), ((gpuData[2]>>8) & 0x000000ff), (gpuData[4] & 0x000000ff), ((gpuData[4]>>8) & 0x000000ff),(gpuData[6] & 0x000000ff), ((gpuData[6]>>8) & 0x000000ff),
+ ((gpuData[2]>>12) & 0x3f0), ((gpuData[2]>>22) & iGPUHeightMask));
+ return;
+ case 2:
+ drawPoly3TD(lx0,ly0,lx1,ly1,lx2,ly2,(gpuData[2] & 0x000000ff), ((gpuData[2]>>8) & 0x000000ff), (gpuData[4] & 0x000000ff), ((gpuData[4]>>8) & 0x000000ff),(gpuData[6] & 0x000000ff), ((gpuData[6]>>8) & 0x000000ff));
+ return;
+ }
+ return;
+ }
+
+ switch(GlobalTextTP) // depending on texture mode
+ {
+ case 0:
+ drawPoly3TEx4_TW(lx0,ly0,lx1,ly1,lx2,ly2,
+ (gpuData[2] & 0x000000ff), ((gpuData[2]>>8) & 0x000000ff), (gpuData[4] & 0x000000ff), ((gpuData[4]>>8) & 0x000000ff),(gpuData[6] & 0x000000ff), ((gpuData[6]>>8) & 0x000000ff),
+ ((gpuData[2]>>12) & 0x3f0), ((gpuData[2]>>22) & iGPUHeightMask));
+ return;
+ case 1:
+ drawPoly3TEx8_TW(lx0,ly0,lx1,ly1,lx2,ly2,
+ (gpuData[2] & 0x000000ff), ((gpuData[2]>>8) & 0x000000ff), (gpuData[4] & 0x000000ff), ((gpuData[4]>>8) & 0x000000ff),(gpuData[6] & 0x000000ff), ((gpuData[6]>>8) & 0x000000ff),
+ ((gpuData[2]>>12) & 0x3f0), ((gpuData[2]>>22) & iGPUHeightMask));
+ return;
+ case 2:
+ drawPoly3TD_TW(lx0,ly0,lx1,ly1,lx2,ly2,(gpuData[2] & 0x000000ff), ((gpuData[2]>>8) & 0x000000ff), (gpuData[4] & 0x000000ff), ((gpuData[4]>>8) & 0x000000ff),(gpuData[6] & 0x000000ff), ((gpuData[6]>>8) & 0x000000ff));
+ return;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void drawPoly4FT(unsigned char *baseAddr)
+{
+ uint32_t *gpuData = ((uint32_t *) baseAddr);
+
+ if(GlobalTextIL && GlobalTextTP<2)
+ {
+ if(GlobalTextTP==0)
+ drawPoly4TEx4_IL(lx0,ly0,lx1,ly1,lx3,ly3,lx2,ly2,
+ (gpuData[2] & 0x000000ff), ((gpuData[2]>>8) & 0x000000ff), (gpuData[4] & 0x000000ff), ((gpuData[4]>>8) & 0x000000ff),(gpuData[8] & 0x000000ff), ((gpuData[8]>>8) & 0x000000ff),(gpuData[6] & 0x000000ff), ((gpuData[6]>>8) & 0x000000ff), ((gpuData[2]>>12) & 0x3f0), ((gpuData[2]>>22) & iGPUHeightMask));
+ else
+ drawPoly4TEx8_IL(lx0,ly0,lx1,ly1,lx3,ly3,lx2,ly2,
+ (gpuData[2] & 0x000000ff), ((gpuData[2]>>8) & 0x000000ff), (gpuData[4] & 0x000000ff), ((gpuData[4]>>8) & 0x000000ff),(gpuData[8] & 0x000000ff), ((gpuData[8]>>8) & 0x000000ff),(gpuData[6] & 0x000000ff), ((gpuData[6]>>8) & 0x000000ff), ((gpuData[2]>>12) & 0x3f0), ((gpuData[2]>>22) & iGPUHeightMask));
+ return;
+ }
+
+ if(!bUsingTWin)
+ {
+#ifdef POLYQUAD3GT
+ if(IsNoRect())
+ {
+ switch (GlobalTextTP)
+ {
+ case 0:
+ drawPoly4TEx4_TRI(lx0,ly0,lx1,ly1,lx3,ly3,lx2,ly2,
+ (gpuData[2] & 0x000000ff), ((gpuData[2]>>8) & 0x000000ff), (gpuData[4] & 0x000000ff), ((gpuData[4]>>8) & 0x000000ff),(gpuData[8] & 0x000000ff), ((gpuData[8]>>8) & 0x000000ff),(gpuData[6] & 0x000000ff), ((gpuData[6]>>8) & 0x000000ff), ((gpuData[2]>>12) & 0x3f0), ((gpuData[2]>>22) & iGPUHeightMask));
+ return;
+ case 1:
+ drawPoly4TEx8_TRI(lx0,ly0,lx1,ly1,lx3,ly3,lx2,ly2,
+ (gpuData[2] & 0x000000ff), ((gpuData[2]>>8) & 0x000000ff), (gpuData[4] & 0x000000ff), ((gpuData[4]>>8) & 0x000000ff),(gpuData[8] & 0x000000ff), ((gpuData[8]>>8) & 0x000000ff),(gpuData[6] & 0x000000ff), ((gpuData[6]>>8) & 0x000000ff), ((gpuData[2]>>12) & 0x3f0), ((gpuData[2]>>22) & iGPUHeightMask));
+ return;
+ case 2:
+ drawPoly4TD_TRI(lx0,ly0,lx1,ly1,lx3,ly3,lx2,ly2,(gpuData[2] & 0x000000ff), ((gpuData[2]>>8) & 0x000000ff), (gpuData[4] & 0x000000ff), ((gpuData[4]>>8) & 0x000000ff),(gpuData[8] & 0x000000ff), ((gpuData[8]>>8) & 0x000000ff),(gpuData[6] & 0x000000ff), ((gpuData[6]>>8) & 0x000000ff));
+ return;
+ }
+ return;
+ }
+#endif
+
+ switch (GlobalTextTP)
+ {
+ case 0: // grandia investigations needed
+ drawPoly4TEx4(lx0,ly0,lx1,ly1,lx3,ly3,lx2,ly2,
+ (gpuData[2] & 0x000000ff), ((gpuData[2]>>8) & 0x000000ff), (gpuData[4] & 0x000000ff), ((gpuData[4]>>8) & 0x000000ff),(gpuData[8] & 0x000000ff), ((gpuData[8]>>8) & 0x000000ff),(gpuData[6] & 0x000000ff), ((gpuData[6]>>8) & 0x000000ff), ((gpuData[2]>>12) & 0x3f0), ((gpuData[2]>>22) & iGPUHeightMask));
+ return;
+ case 1:
+ drawPoly4TEx8(lx0,ly0,lx1,ly1,lx3,ly3,lx2,ly2,
+ (gpuData[2] & 0x000000ff), ((gpuData[2]>>8) & 0x000000ff), (gpuData[4] & 0x000000ff), ((gpuData[4]>>8) & 0x000000ff),(gpuData[8] & 0x000000ff), ((gpuData[8]>>8) & 0x000000ff),(gpuData[6] & 0x000000ff), ((gpuData[6]>>8) & 0x000000ff), ((gpuData[2]>>12) & 0x3f0), ((gpuData[2]>>22) & iGPUHeightMask));
+ return;
+ case 2:
+ drawPoly4TD(lx0,ly0,lx1,ly1,lx3,ly3,lx2,ly2,(gpuData[2] & 0x000000ff), ((gpuData[2]>>8) & 0x000000ff), (gpuData[4] & 0x000000ff), ((gpuData[4]>>8) & 0x000000ff),(gpuData[8] & 0x000000ff), ((gpuData[8]>>8) & 0x000000ff),(gpuData[6] & 0x000000ff), ((gpuData[6]>>8) & 0x000000ff));
+ return;
+ }
+ return;
+ }
+
+ switch (GlobalTextTP)
+ {
+ case 0:
+ drawPoly4TEx4_TW(lx0,ly0,lx1,ly1,lx3,ly3,lx2,ly2,
+ (gpuData[2] & 0x000000ff), ((gpuData[2]>>8) & 0x000000ff), (gpuData[4] & 0x000000ff), ((gpuData[4]>>8) & 0x000000ff),(gpuData[8] & 0x000000ff), ((gpuData[8]>>8) & 0x000000ff),(gpuData[6] & 0x000000ff), ((gpuData[6]>>8) & 0x000000ff), ((gpuData[2]>>12) & 0x3f0), ((gpuData[2]>>22) & iGPUHeightMask));
+ return;
+ case 1:
+ drawPoly4TEx8_TW(lx0,ly0,lx1,ly1,lx3,ly3,lx2,ly2,
+ (gpuData[2] & 0x000000ff), ((gpuData[2]>>8) & 0x000000ff), (gpuData[4] & 0x000000ff), ((gpuData[4]>>8) & 0x000000ff),(gpuData[8] & 0x000000ff), ((gpuData[8]>>8) & 0x000000ff),(gpuData[6] & 0x000000ff), ((gpuData[6]>>8) & 0x000000ff), ((gpuData[2]>>12) & 0x3f0), ((gpuData[2]>>22) & iGPUHeightMask));
+ return;
+ case 2:
+ drawPoly4TD_TW(lx0,ly0,lx1,ly1,lx3,ly3,lx2,ly2,(gpuData[2] & 0x000000ff), ((gpuData[2]>>8) & 0x000000ff), (gpuData[4] & 0x000000ff), ((gpuData[4]>>8) & 0x000000ff),(gpuData[8] & 0x000000ff), ((gpuData[8]>>8) & 0x000000ff),(gpuData[6] & 0x000000ff), ((gpuData[6]>>8) & 0x000000ff));
+ return;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void drawPoly3GT(unsigned char * baseAddr)
+{
+ uint32_t *gpuData = ((uint32_t *) baseAddr);
+
+ if(GlobalTextIL && GlobalTextTP<2)
+ {
+ if(GlobalTextTP==0)
+ drawPoly3TGEx4_IL(lx0,ly0,lx1,ly1,lx2,ly2,
+ (gpuData[2] & 0x000000ff), ((gpuData[2]>>8) & 0x000000ff), (gpuData[5] & 0x000000ff), ((gpuData[5]>>8) & 0x000000ff),(gpuData[8] & 0x000000ff), ((gpuData[8]>>8) & 0x000000ff),
+ ((gpuData[2]>>12) & 0x3f0), ((gpuData[2]>>22) & iGPUHeightMask),
+ gpuData[0],gpuData[3],gpuData[6]);
+ else
+ drawPoly3TGEx8_IL(lx0,ly0,lx1,ly1,lx2,ly2,
+ (gpuData[2] & 0x000000ff), ((gpuData[2]>>8) & 0x000000ff), (gpuData[5] & 0x000000ff), ((gpuData[5]>>8) & 0x000000ff),(gpuData[8] & 0x000000ff), ((gpuData[8]>>8) & 0x000000ff),
+ ((gpuData[2]>>12) & 0x3f0), ((gpuData[2]>>22) & iGPUHeightMask),
+ gpuData[0],gpuData[3],gpuData[6]);
+ return;
+ }
+
+ if(!bUsingTWin)
+ {
+ switch (GlobalTextTP)
+ {
+ case 0:
+ drawPoly3TGEx4(lx0,ly0,lx1,ly1,lx2,ly2,
+ (gpuData[2] & 0x000000ff), ((gpuData[2]>>8) & 0x000000ff), (gpuData[5] & 0x000000ff), ((gpuData[5]>>8) & 0x000000ff),(gpuData[8] & 0x000000ff), ((gpuData[8]>>8) & 0x000000ff),
+ ((gpuData[2]>>12) & 0x3f0), ((gpuData[2]>>22) & iGPUHeightMask),
+ gpuData[0],gpuData[3],gpuData[6]);
+ return;
+ case 1:
+ drawPoly3TGEx8(lx0,ly0,lx1,ly1,lx2,ly2,
+ (gpuData[2] & 0x000000ff), ((gpuData[2]>>8) & 0x000000ff), (gpuData[5] & 0x000000ff), ((gpuData[5]>>8) & 0x000000ff),(gpuData[8] & 0x000000ff), ((gpuData[8]>>8) & 0x000000ff),
+ ((gpuData[2]>>12) & 0x3f0), ((gpuData[2]>>22) & iGPUHeightMask),
+ gpuData[0],gpuData[3],gpuData[6]);
+ return;
+ case 2:
+ drawPoly3TGD(lx0,ly0,lx1,ly1,lx2,ly2,(gpuData[2] & 0x000000ff), ((gpuData[2]>>8) & 0x000000ff), (gpuData[5] & 0x000000ff), ((gpuData[5]>>8) & 0x000000ff),(gpuData[8] & 0x000000ff), ((gpuData[8]>>8) & 0x000000ff),gpuData[0],gpuData[3],gpuData[6]);
+ return;
+ }
+ return;
+ }
+
+ switch(GlobalTextTP)
+ {
+ case 0:
+ drawPoly3TGEx4_TW(lx0,ly0,lx1,ly1,lx2,ly2,
+ (gpuData[2] & 0x000000ff), ((gpuData[2]>>8) & 0x000000ff), (gpuData[5] & 0x000000ff), ((gpuData[5]>>8) & 0x000000ff),(gpuData[8] & 0x000000ff), ((gpuData[8]>>8) & 0x000000ff),
+ ((gpuData[2]>>12) & 0x3f0), ((gpuData[2]>>22) & iGPUHeightMask),
+ gpuData[0],gpuData[3],gpuData[6]);
+ return;
+ case 1:
+ drawPoly3TGEx8_TW(lx0,ly0,lx1,ly1,lx2,ly2,
+ (gpuData[2] & 0x000000ff), ((gpuData[2]>>8) & 0x000000ff), (gpuData[5] & 0x000000ff), ((gpuData[5]>>8) & 0x000000ff),(gpuData[8] & 0x000000ff), ((gpuData[8]>>8) & 0x000000ff),
+ ((gpuData[2]>>12) & 0x3f0), ((gpuData[2]>>22) & iGPUHeightMask),
+ gpuData[0],gpuData[3],gpuData[6]);
+ return;
+ case 2:
+ drawPoly3TGD_TW(lx0,ly0,lx1,ly1,lx2,ly2,(gpuData[2] & 0x000000ff), ((gpuData[2]>>8) & 0x000000ff), (gpuData[5] & 0x000000ff), ((gpuData[5]>>8) & 0x000000ff),(gpuData[8] & 0x000000ff), ((gpuData[8]>>8) & 0x000000ff),gpuData[0],gpuData[3],gpuData[6]);
+ return;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void drawPoly4GT(unsigned char *baseAddr)
+{
+ uint32_t *gpuData = ((uint32_t *) baseAddr);
+
+ if(GlobalTextIL && GlobalTextTP<2)
+ {
+ if(GlobalTextTP==0)
+ drawPoly4TGEx4_TRI_IL(lx0,ly0,lx1,ly1,lx3,ly3,lx2,ly2,
+ (gpuData[2] & 0x000000ff), ((gpuData[2]>>8) & 0x000000ff), (gpuData[5] & 0x000000ff), ((gpuData[5]>>8) & 0x000000ff),(gpuData[11] & 0x000000ff), ((gpuData[11]>>8) & 0x000000ff),(gpuData[8] & 0x000000ff), ((gpuData[8]>>8) & 0x000000ff),
+ ((gpuData[2]>>12) & 0x3f0),((gpuData[2]>>22) & iGPUHeightMask),
+ gpuData[0],gpuData[3],gpuData[6],gpuData[9]);
+ else
+ drawPoly4TGEx8_TRI_IL(lx0,ly0,lx1,ly1,lx3,ly3,lx2,ly2,
+ (gpuData[2] & 0x000000ff), ((gpuData[2]>>8) & 0x000000ff), (gpuData[5] & 0x000000ff), ((gpuData[5]>>8) & 0x000000ff),(gpuData[11] & 0x000000ff), ((gpuData[11]>>8) & 0x000000ff),(gpuData[8] & 0x000000ff), ((gpuData[8]>>8) & 0x000000ff),
+ ((gpuData[2]>>12) & 0x3f0),((gpuData[2]>>22) & iGPUHeightMask),
+ gpuData[0],gpuData[3],gpuData[6],gpuData[9]);
+ return;
+ }
+
+ if(!bUsingTWin)
+ {
+#ifdef POLYQUAD3GT
+ if(IsNoRect())
+ {
+ switch (GlobalTextTP)
+ {
+ case 0:
+ drawPoly4TGEx4_TRI(lx0,ly0,lx1,ly1,lx3,ly3,lx2,ly2,
+ (gpuData[2] & 0x000000ff), ((gpuData[2]>>8) & 0x000000ff), (gpuData[5] & 0x000000ff), ((gpuData[5]>>8) & 0x000000ff),(gpuData[11] & 0x000000ff), ((gpuData[11]>>8) & 0x000000ff),(gpuData[8] & 0x000000ff), ((gpuData[8]>>8) & 0x000000ff),
+ ((gpuData[2]>>12) & 0x3f0),((gpuData[2]>>22) & iGPUHeightMask),
+ gpuData[0],gpuData[3],gpuData[6],gpuData[9]);
+
+ return;
+ case 1:
+ drawPoly4TGEx8_TRI(lx0,ly0,lx1,ly1,lx3,ly3,lx2,ly2,
+ (gpuData[2] & 0x000000ff), ((gpuData[2]>>8) & 0x000000ff), (gpuData[5] & 0x000000ff), ((gpuData[5]>>8) & 0x000000ff),(gpuData[11] & 0x000000ff), ((gpuData[11]>>8) & 0x000000ff),(gpuData[8] & 0x000000ff), ((gpuData[8]>>8) & 0x000000ff),
+ ((gpuData[2]>>12) & 0x3f0),((gpuData[2]>>22) & iGPUHeightMask),
+ gpuData[0],gpuData[3],gpuData[6],gpuData[9]);
+ return;
+ case 2:
+ drawPoly4TGD_TRI(lx0,ly0,lx1,ly1,lx3,ly3,lx2,ly2,(gpuData[2] & 0x000000ff),((gpuData[2]>>8) & 0x000000ff), (gpuData[5] & 0x000000ff), ((gpuData[5]>>8) & 0x000000ff),(gpuData[11] & 0x000000ff), ((gpuData[11]>>8) & 0x000000ff),(gpuData[8] & 0x000000ff), ((gpuData[8]>>8) & 0x000000ff),gpuData[0],gpuData[3],gpuData[6],gpuData[9]);
+ return;
+ }
+ return;
+ }
+#endif
+
+ switch (GlobalTextTP)
+ {
+ case 0:
+ drawPoly4TGEx4(lx0,ly0,lx1,ly1,lx3,ly3,lx2,ly2,
+ (gpuData[2] & 0x000000ff), ((gpuData[2]>>8) & 0x000000ff), (gpuData[5] & 0x000000ff), ((gpuData[5]>>8) & 0x000000ff),(gpuData[11] & 0x000000ff), ((gpuData[11]>>8) & 0x000000ff),(gpuData[8] & 0x000000ff), ((gpuData[8]>>8) & 0x000000ff),
+ ((gpuData[2]>>12) & 0x3f0),((gpuData[2]>>22) & iGPUHeightMask),
+ gpuData[0],gpuData[3],gpuData[6],gpuData[9]);
+
+ return;
+ case 1:
+ drawPoly4TGEx8(lx0,ly0,lx1,ly1,lx3,ly3,lx2,ly2,
+ (gpuData[2] & 0x000000ff), ((gpuData[2]>>8) & 0x000000ff), (gpuData[5] & 0x000000ff), ((gpuData[5]>>8) & 0x000000ff),(gpuData[11] & 0x000000ff), ((gpuData[11]>>8) & 0x000000ff),(gpuData[8] & 0x000000ff), ((gpuData[8]>>8) & 0x000000ff),
+ ((gpuData[2]>>12) & 0x3f0),((gpuData[2]>>22) & iGPUHeightMask),
+ gpuData[0],gpuData[3],gpuData[6],gpuData[9]);
+ return;
+ case 2:
+ drawPoly4TGD(lx0,ly0,lx1,ly1,lx3,ly3,lx2,ly2,(gpuData[2] & 0x000000ff),((gpuData[2]>>8) & 0x000000ff), (gpuData[5] & 0x000000ff), ((gpuData[5]>>8) & 0x000000ff),(gpuData[11] & 0x000000ff), ((gpuData[11]>>8) & 0x000000ff),(gpuData[8] & 0x000000ff), ((gpuData[8]>>8) & 0x000000ff),gpuData[0],gpuData[3],gpuData[6],gpuData[9]);
+ return;
+ }
+ return;
+ }
+
+ switch (GlobalTextTP)
+ {
+ case 0:
+ drawPoly4TGEx4_TW(lx0,ly0,lx1,ly1,lx3,ly3,lx2,ly2,
+ (gpuData[2] & 0x000000ff), ((gpuData[2]>>8) & 0x000000ff), (gpuData[5] & 0x000000ff), ((gpuData[5]>>8) & 0x000000ff),(gpuData[11] & 0x000000ff), ((gpuData[11]>>8) & 0x000000ff),(gpuData[8] & 0x000000ff), ((gpuData[8]>>8) & 0x000000ff),
+ ((gpuData[2]>>12) & 0x3f0),((gpuData[2]>>22) & iGPUHeightMask),
+ gpuData[0],gpuData[3],gpuData[6],gpuData[9]);
+ return;
+ case 1:
+ drawPoly4TGEx8_TW(lx0,ly0,lx1,ly1,lx3,ly3,lx2,ly2,
+ (gpuData[2] & 0x000000ff), ((gpuData[2]>>8) & 0x000000ff), (gpuData[5] & 0x000000ff), ((gpuData[5]>>8) & 0x000000ff),(gpuData[11] & 0x000000ff), ((gpuData[11]>>8) & 0x000000ff),(gpuData[8] & 0x000000ff), ((gpuData[8]>>8) & 0x000000ff),
+ ((gpuData[2]>>12) & 0x3f0),((gpuData[2]>>22) & iGPUHeightMask),
+ gpuData[0],gpuData[3],gpuData[6],gpuData[9]);
+ return;
+ case 2:
+ drawPoly4TGD_TW(lx0,ly0,lx1,ly1,lx3,ly3,lx2,ly2,(gpuData[2] & 0x000000ff),((gpuData[2]>>8) & 0x000000ff), (gpuData[5] & 0x000000ff), ((gpuData[5]>>8) & 0x000000ff),(gpuData[11] & 0x000000ff), ((gpuData[11]>>8) & 0x000000ff),(gpuData[8] & 0x000000ff), ((gpuData[8]>>8) & 0x000000ff),gpuData[0],gpuData[3],gpuData[6],gpuData[9]);
+ return;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+// SPRITE FUNCS
+////////////////////////////////////////////////////////////////////////
+
+void DrawSoftwareSpriteTWin(unsigned char * baseAddr, int w, int h)
+{
+ uint32_t *gpuData = (uint32_t *)baseAddr;
+ short sx0,sy0,sx1,sy1,sx2,sy2,sx3,sy3;
+ short tx0,ty0,tx1,ty1,tx2,ty2,tx3,ty3;
+
+ sx0=lx0;
+ sy0=ly0;
+
+ sx0=sx3=sx0+PSXDisplay.DrawOffset.x;
+ sx1=sx2=sx0+w;
+ sy0=sy1=sy0+PSXDisplay.DrawOffset.y;
+ sy2=sy3=sy0+h;
+
+ tx0=tx3=gpuData[2]&0xff;
+ tx1=tx2=tx0+w;
+ ty0=ty1=(gpuData[2]>>8)&0xff;
+ ty2=ty3=ty0+h;
+
+ switch (GlobalTextTP)
+ {
+ case 0:
+ drawPoly4TEx4_TW_S(sx0,sy0,sx1,sy1,sx2,sy2,sx3,sy3,
+ tx0,ty0,tx1,ty1,tx2,ty2,tx3,ty3,
+ ((gpuData[2]>>12) & 0x3f0), ((gpuData[2]>>22) & iGPUHeightMask));
+ return;
+ case 1:
+ drawPoly4TEx8_TW_S(sx0,sy0,sx1,sy1,sx2,sy2,sx3,sy3,
+ tx0,ty0,tx1,ty1,tx2,ty2,tx3,ty3,
+ ((gpuData[2]>>12) & 0x3f0), ((gpuData[2]>>22) & iGPUHeightMask));
+ return;
+ case 2:
+ drawPoly4TD_TW_S(sx0,sy0,sx1,sy1,sx2,sy2,sx3,sy3,
+ tx0,ty0,tx1,ty1,tx2,ty2,tx3,ty3);
+ return;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void DrawSoftwareSpriteMirror(unsigned char * baseAddr, int w, int h)
+{
+ int sprtY,sprtX,sprtW,sprtH,lXDir,lYDir;
+ int clutY0,clutX0,clutP,textX0,textY0,sprtYa,sprCY,sprCX,sprA;
+ short tC;
+ uint32_t *gpuData = (uint32_t *)baseAddr;
+ sprtY = ly0;
+ sprtX = lx0;
+ sprtH = h;
+ sprtW = w;
+ clutY0 = (gpuData[2]>>22) & iGPUHeightMask;
+ clutX0 = (gpuData[2]>>12) & 0x3f0;
+ clutP = (clutY0<<11) + (clutX0<<1);
+ textY0 = ((gpuData[2]>>8) & 0x000000ff) + GlobalTextAddrY;
+ textX0 = (gpuData[2] & 0x000000ff);
+
+ sprtX+=PSXDisplay.DrawOffset.x;
+ sprtY+=PSXDisplay.DrawOffset.y;
+
+// while (sprtX>1023) sprtX-=1024;
+// while (sprtY>MAXYLINESMIN1) sprtY-=MAXYLINES;
+
+ if(sprtX>drawW)
+ {
+// if((sprtX+sprtW)>1023) sprtX-=1024;
+// else return;
+ return;
+ }
+
+ if(sprtY>drawH)
+ {
+// if ((sprtY+sprtH)>MAXYLINESMIN1) sprtY-=MAXYLINES;
+// else return;
+ return;
+ }
+
+ if(sprtY<drawY)
+ {
+ if((sprtY+sprtH)<drawY) return;
+ sprtH-=(drawY-sprtY);
+ textY0+=(drawY-sprtY);
+ sprtY=drawY;
+ }
+
+ if(sprtX<drawX)
+ {
+ if((sprtX+sprtW)<drawX) return;
+ sprtW-=(drawX-sprtX);
+ textX0+=(drawX-sprtX);
+ sprtX=drawX;
+ }
+
+ if((sprtY+sprtH)>drawH) sprtH=drawH-sprtY+1;
+ if((sprtX+sprtW)>drawW) sprtW=drawW-sprtX+1;
+
+ if(usMirror&0x1000) lXDir=-1; else lXDir=1;
+ if(usMirror&0x2000) lYDir=-1; else lYDir=1;
+
+ switch (GlobalTextTP)
+ {
+ case 0: // texture is 4-bit
+
+ sprtW=sprtW/2;
+ textX0=(GlobalTextAddrX<<1)+(textX0>>1);
+ sprtYa=(sprtY<<10);
+ clutP=(clutY0<<10)+clutX0;
+ for (sprCY=0;sprCY<sprtH;sprCY++)
+ for (sprCX=0;sprCX<sprtW;sprCX++)
+ {
+ tC= psxVub[((textY0+(sprCY*lYDir))<<11) + textX0 +(sprCX*lXDir)];
+ sprA=sprtYa+(sprCY<<10)+sprtX + (sprCX<<1);
+ GetTextureTransColG_SPR(&psxVuw[sprA],psxVuw[clutP+((tC>>4)&0xf)]);
+ GetTextureTransColG_SPR(&psxVuw[sprA+1],psxVuw[clutP+(tC&0xf)]);
+ }
+ return;
+
+ case 1:
+
+ clutP>>=1;
+ for(sprCY=0;sprCY<sprtH;sprCY++)
+ for(sprCX=0;sprCX<sprtW;sprCX++)
+ {
+ tC = psxVub[((textY0+(sprCY*lYDir))<<11)+(GlobalTextAddrX<<1) + textX0 + (sprCX*lXDir)] & 0xff;
+ GetTextureTransColG_SPR(&psxVuw[((sprtY+sprCY)<<10)+sprtX + sprCX],psxVuw[clutP+tC]);
+ }
+ return;
+
+
+ case 2:
+
+ for (sprCY=0;sprCY<sprtH;sprCY++)
+ for (sprCX=0;sprCX<sprtW;sprCX++)
+ {
+ GetTextureTransColG_SPR(&psxVuw[((sprtY+sprCY)<<10)+sprtX+sprCX],
+ psxVuw[((textY0+(sprCY*lYDir))<<10)+GlobalTextAddrX + textX0 +(sprCX*lXDir)]);
+ }
+ return;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void DrawSoftwareSprite_IL(unsigned char * baseAddr,short w,short h,int tx,int ty)
+{
+ int sprtY,sprtX,sprtW,sprtH,tdx,tdy;
+ uint32_t *gpuData = (uint32_t *)baseAddr;
+
+ sprtY = ly0;
+ sprtX = lx0;
+ sprtH = h;
+ sprtW = w;
+
+ sprtX+=PSXDisplay.DrawOffset.x;
+ sprtY+=PSXDisplay.DrawOffset.y;
+
+ if(sprtX>drawW) return;
+ if(sprtY>drawH) return;
+
+ tdx=tx+sprtW;
+ tdy=ty+sprtH;
+
+ sprtW+=sprtX;
+ sprtH+=sprtY;
+
+ // Pete is too lazy to make a faster version ;)
+
+ if(GlobalTextTP==0)
+ drawPoly4TEx4_IL(sprtX,sprtY,sprtX,sprtH,sprtW,sprtH,sprtW,sprtY,
+ tx,ty, tx,tdy, tdx,tdy, tdx,ty,
+ (gpuData[2]>>12) & 0x3f0, ((gpuData[2]>>22) & iGPUHeightMask));
+
+
+ else
+ drawPoly4TEx8_IL(sprtX,sprtY,sprtX,sprtH,sprtW,sprtH,sprtW,sprtY,
+ tx,ty, tx,tdy, tdx,tdy, tdx,ty,
+ (gpuData[2]>>12) & 0x3f0, ((gpuData[2]>>22) & iGPUHeightMask));
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void DrawSoftwareSprite(unsigned char *baseAddr, short w, short h, int tx, int ty)
+{
+ int sprtY, sprtX, sprtW, sprtH;
+ int clutY0, clutX0, clutP, textX0, textY0, sprtYa, sprCY, sprCX, sprA;
+ short tC, tC2;
+ uint32_t *gpuData = (uint32_t *)baseAddr;
+ unsigned char *pV;
+ BOOL bWT,bWS;
+
+ if(GlobalTextIL && GlobalTextTP<2)
+ {DrawSoftwareSprite_IL(baseAddr,w,h,tx,ty);return;}
+
+ sprtY = ly0;
+ sprtX = lx0;
+ sprtH = h;
+ sprtW = w;
+ clutY0 = (gpuData[2]>>22) & iGPUHeightMask;
+ clutX0 = (gpuData[2]>>12) & 0x3f0;
+
+ clutP = (clutY0<<11) + (clutX0<<1);
+
+ textY0 =ty+ GlobalTextAddrY;
+ textX0 =tx;
+
+ sprtX+=PSXDisplay.DrawOffset.x;
+ sprtY+=PSXDisplay.DrawOffset.y;
+
+ //while (sprtX>1023) sprtX-=1024;
+ //while (sprtY>MAXYLINESMIN1) sprtY-=MAXYLINES;
+
+ if(sprtX>drawW)
+ {
+// if((sprtX+sprtW)>1023) sprtX-=1024;
+// else return;
+ return;
+ }
+
+ if(sprtY>drawH)
+ {
+// if ((sprtY+sprtH)>MAXYLINESMIN1) sprtY-=MAXYLINES;
+// else return;
+ return;
+ }
+
+ if(sprtY<drawY)
+ {
+ if((sprtY+sprtH)<drawY) return;
+ sprtH-=(drawY-sprtY);
+ textY0+=(drawY-sprtY);
+ sprtY=drawY;
+ }
+
+ if(sprtX<drawX)
+ {
+ if((sprtX+sprtW)<drawX) return;
+
+ sprtW-=(drawX-sprtX);
+ textX0+=(drawX-sprtX);
+ sprtX=drawX;
+ }
+
+ if((sprtY+sprtH)>drawH) sprtH=drawH-sprtY+1;
+ if((sprtX+sprtW)>drawW) sprtW=drawW-sprtX+1;
+
+
+ bWT=FALSE;
+ bWS=FALSE;
+
+ switch (GlobalTextTP)
+ {
+ case 0:
+
+ if(textX0&1) {bWS=TRUE;sprtW--;}
+ if(sprtW&1) bWT=TRUE;
+
+ sprtW=sprtW>>1;
+ textX0=(GlobalTextAddrX<<1)+(textX0>>1)+(textY0<<11);
+ sprtYa=(sprtY<<10)+sprtX;
+ clutP=(clutY0<<10)+clutX0;
+
+#ifdef FASTSOLID
+
+ if(!bCheckMask && !DrawSemiTrans)
+ {
+ for (sprCY=0;sprCY<sprtH;sprCY++)
+ {
+ sprA=sprtYa+(sprCY<<10);
+ pV=&psxVub[(sprCY<<11)+textX0];
+
+ if(bWS)
+ {
+ tC=*pV++;
+ GetTextureTransColG_S(&psxVuw[sprA++],psxVuw[clutP+((tC>>4)&0xf)]);
+ }
+
+ for (sprCX=0;sprCX<sprtW;sprCX++,sprA+=2)
+ {
+ tC=*pV++;
+
+ GetTextureTransColG32_S((uint32_t *)&psxVuw[sprA],
+ (((int)psxVuw[clutP+((tC>>4)&0xf)])<<16)|
+ psxVuw[clutP+(tC&0x0f)]);
+ }
+
+ if(bWT)
+ {
+ tC=*pV;
+ GetTextureTransColG_S(&psxVuw[sprA],psxVuw[clutP+(tC&0x0f)]);
+ }
+ }
+ return;
+ }
+
+#endif
+
+ for (sprCY=0;sprCY<sprtH;sprCY++)
+ {
+ sprA=sprtYa+(sprCY<<10);
+ pV=&psxVub[(sprCY<<11)+textX0];
+
+ if(bWS)
+ {
+ tC=*pV++;
+ GetTextureTransColG_SPR(&psxVuw[sprA++],psxVuw[clutP+((tC>>4)&0xf)]);
+ }
+
+ for (sprCX=0;sprCX<sprtW;sprCX++,sprA+=2)
+ {
+ tC=*pV++;
+
+ GetTextureTransColG32_SPR((uint32_t *)&psxVuw[sprA],
+ (((int)psxVuw[clutP+((tC>>4)&0xf)])<<16)|
+ psxVuw[clutP+(tC&0x0f)]);
+ }
+
+ if(bWT)
+ {
+ tC=*pV;
+ GetTextureTransColG_SPR(&psxVuw[sprA],psxVuw[clutP+(tC&0x0f)]);
+ }
+ }
+ return;
+
+ case 1:
+ clutP>>=1;sprtW--;
+ textX0+=(GlobalTextAddrX<<1) + (textY0<<11);
+
+#ifdef FASTSOLID
+
+ if(!bCheckMask && !DrawSemiTrans)
+ {
+ for(sprCY=0;sprCY<sprtH;sprCY++)
+ {
+ sprA=((sprtY+sprCY)<<10)+sprtX;
+ pV=&psxVub[(sprCY<<11)+textX0];
+ for(sprCX=0;sprCX<sprtW;sprCX+=2,sprA+=2)
+ {
+ tC = *pV++;tC2 = *pV++;
+ GetTextureTransColG32_S((uint32_t *)&psxVuw[sprA],
+ (((int)psxVuw[clutP+tC2])<<16)|
+ psxVuw[clutP+tC]);
+ }
+ if(sprCX==sprtW)
+ GetTextureTransColG_S(&psxVuw[sprA],psxVuw[clutP+(*pV)]);
+ }
+ return;
+ }
+
+#endif
+
+ for(sprCY=0;sprCY<sprtH;sprCY++)
+ {
+ sprA=((sprtY+sprCY)<<10)+sprtX;
+ pV=&psxVub[(sprCY<<11)+textX0];
+ for(sprCX=0;sprCX<sprtW;sprCX+=2,sprA+=2)
+ {
+ tC = *pV++;tC2 = *pV++;
+ GetTextureTransColG32_SPR((uint32_t *)&psxVuw[sprA],
+ (((int)psxVuw[clutP+tC2])<<16)|
+ psxVuw[clutP+tC]);
+ }
+ if(sprCX==sprtW)
+ GetTextureTransColG_SPR(&psxVuw[sprA],psxVuw[clutP+(*pV)]);
+ }
+ return;
+
+ case 2:
+
+ textX0+=(GlobalTextAddrX) + (textY0<<10);
+ sprtW--;
+
+#ifdef FASTSOLID
+
+ if(!bCheckMask && !DrawSemiTrans)
+ {
+ for (sprCY=0;sprCY<sprtH;sprCY++)
+ {
+ sprA=((sprtY+sprCY)<<10)+sprtX;
+
+ for (sprCX=0;sprCX<sprtW;sprCX+=2,sprA+=2)
+ {
+ GetTextureTransColG32_S((uint32_t *)&psxVuw[sprA],
+ (((int)psxVuw[(sprCY<<10) + textX0 + sprCX +1])<<16)|
+ psxVuw[(sprCY<<10) + textX0 + sprCX]);
+ }
+ if(sprCX==sprtW)
+ GetTextureTransColG_S(&psxVuw[sprA],
+ psxVuw[(sprCY<<10) + textX0 + sprCX]);
+
+ }
+ return;
+ }
+
+#endif
+
+ for (sprCY=0;sprCY<sprtH;sprCY++)
+ {
+ sprA=((sprtY+sprCY)<<10)+sprtX;
+
+ for (sprCX=0;sprCX<sprtW;sprCX+=2,sprA+=2)
+ {
+ GetTextureTransColG32_SPR((uint32_t *)&psxVuw[sprA],
+ (((int)psxVuw[(sprCY<<10) + textX0 + sprCX +1])<<16)|
+ psxVuw[(sprCY<<10) + textX0 + sprCX]);
+ }
+ if(sprCX==sprtW)
+ GetTextureTransColG_SPR(&psxVuw[sprA],
+ psxVuw[(sprCY<<10) + textX0 + sprCX]);
+
+ }
+ return;
+ }
+}
+
+///////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////
+// LINE FUNCS
+////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////
+
+
+///////////////////////////////////////////////////////////////////////
+
+void Line_E_SE_Shade(int x0, int y0, int x1, int y1, uint32_t rgb0, uint32_t rgb1)
+{
+ int dx, dy, incrE, incrSE, d;
+ uint32_t r0, g0, b0, r1, g1, b1;
+ int dr, dg, db;
+
+ r0 = (rgb0 & 0x00ff0000);
+ g0 = (rgb0 & 0x0000ff00) << 8;
+ b0 = (rgb0 & 0x000000ff) << 16;
+ r1 = (rgb1 & 0x00ff0000);
+ g1 = (rgb1 & 0x0000ff00) << 8;
+ b1 = (rgb1 & 0x000000ff) << 16;
+
+ dx = x1 - x0;
+ dy = y1 - y0;
+
+ if (dx > 0)
+ {
+ dr = ((int)r1 - (int)r0) / dx;
+ dg = ((int)g1 - (int)g0) / dx;
+ db = ((int)b1 - (int)b0) / dx;
+ }
+ else
+ {
+ dr = ((int)r1 - (int)r0);
+ dg = ((int)g1 - (int)g0);
+ db = ((int)b1 - (int)b0);
+ }
+
+ d = 2*dy - dx; /* Initial value of d */
+ incrE = 2*dy; /* incr. used for move to E */
+ incrSE = 2*(dy - dx); /* incr. used for move to SE */
+
+ if ((x0>=drawX)&&(x0<drawW)&&(y0>=drawY)&&(y0<drawH))
+ GetShadeTransCol(&psxVuw[(y0<<10)+x0],(unsigned short)(((r0 >> 9)&0x7c00)|((g0 >> 14)&0x03e0)|((b0 >> 19)&0x001f)));
+ while(x0 < x1)
+ {
+ if (d <= 0)
+ {
+ d = d + incrE; /* Choose E */
+ }
+ else
+ {
+ d = d + incrSE; /* Choose SE */
+ y0++;
+ }
+ x0++;
+
+ r0+=dr;
+ g0+=dg;
+ b0+=db;
+
+ if ((x0>=drawX)&&(x0<drawW)&&(y0>=drawY)&&(y0<drawH))
+ GetShadeTransCol(&psxVuw[(y0<<10)+x0],(unsigned short)(((r0 >> 9)&0x7c00)|((g0 >> 14)&0x03e0)|((b0 >> 19)&0x001f)));
+ }
+}
+
+///////////////////////////////////////////////////////////////////////
+
+void Line_S_SE_Shade(int x0, int y0, int x1, int y1, uint32_t rgb0, uint32_t rgb1)
+{
+ int dx, dy, incrS, incrSE, d;
+ uint32_t r0, g0, b0, r1, g1, b1;
+ int dr, dg, db;
+
+ r0 = (rgb0 & 0x00ff0000);
+ g0 = (rgb0 & 0x0000ff00) << 8;
+ b0 = (rgb0 & 0x000000ff) << 16;
+ r1 = (rgb1 & 0x00ff0000);
+ g1 = (rgb1 & 0x0000ff00) << 8;
+ b1 = (rgb1 & 0x000000ff) << 16;
+
+ dx = x1 - x0;
+ dy = y1 - y0;
+
+ if (dy > 0)
+ {
+ dr = ((int)r1 - (int)r0) / dy;
+ dg = ((int)g1 - (int)g0) / dy;
+ db = ((int)b1 - (int)b0) / dy;
+ }
+ else
+ {
+ dr = ((int)r1 - (int)r0);
+ dg = ((int)g1 - (int)g0);
+ db = ((int)b1 - (int)b0);
+ }
+
+ d = 2*dx - dy; /* Initial value of d */
+ incrS = 2*dx; /* incr. used for move to S */
+ incrSE = 2*(dx - dy); /* incr. used for move to SE */
+
+ if ((x0>=drawX)&&(x0<drawW)&&(y0>=drawY)&&(y0<drawH))
+ GetShadeTransCol(&psxVuw[(y0<<10)+x0],(unsigned short)(((r0 >> 9)&0x7c00)|((g0 >> 14)&0x03e0)|((b0 >> 19)&0x001f)));
+ while(y0 < y1)
+ {
+ if (d <= 0)
+ {
+ d = d + incrS; /* Choose S */
+ }
+ else
+ {
+ d = d + incrSE; /* Choose SE */
+ x0++;
+ }
+ y0++;
+
+ r0+=dr;
+ g0+=dg;
+ b0+=db;
+
+ if ((x0>=drawX)&&(x0<drawW)&&(y0>=drawY)&&(y0<drawH))
+ GetShadeTransCol(&psxVuw[(y0<<10)+x0],(unsigned short)(((r0 >> 9)&0x7c00)|((g0 >> 14)&0x03e0)|((b0 >> 19)&0x001f)));
+ }
+}
+
+///////////////////////////////////////////////////////////////////////
+
+void Line_N_NE_Shade(int x0, int y0, int x1, int y1, uint32_t rgb0, uint32_t rgb1)
+{
+ int dx, dy, incrN, incrNE, d;
+ uint32_t r0, g0, b0, r1, g1, b1;
+ int dr, dg, db;
+
+ r0 = (rgb0 & 0x00ff0000);
+ g0 = (rgb0 & 0x0000ff00) << 8;
+ b0 = (rgb0 & 0x000000ff) << 16;
+ r1 = (rgb1 & 0x00ff0000);
+ g1 = (rgb1 & 0x0000ff00) << 8;
+ b1 = (rgb1 & 0x000000ff) << 16;
+
+ dx = x1 - x0;
+ dy = -(y1 - y0);
+
+ if (dy > 0)
+ {
+ dr = ((uint32_t)r1 - (uint32_t)r0) / dy;
+ dg = ((uint32_t)g1 - (uint32_t)g0) / dy;
+ db = ((uint32_t)b1 - (uint32_t)b0) / dy;
+ }
+ else
+ {
+ dr = ((uint32_t)r1 - (uint32_t)r0);
+ dg = ((uint32_t)g1 - (uint32_t)g0);
+ db = ((uint32_t)b1 - (uint32_t)b0);
+ }
+
+ d = 2*dx - dy; /* Initial value of d */
+ incrN = 2*dx; /* incr. used for move to N */
+ incrNE = 2*(dx - dy); /* incr. used for move to NE */
+
+ if ((x0>=drawX)&&(x0<drawW)&&(y0>=drawY)&&(y0<drawH))
+ GetShadeTransCol(&psxVuw[(y0<<10)+x0],(unsigned short)(((r0 >> 9)&0x7c00)|((g0 >> 14)&0x03e0)|((b0 >> 19)&0x001f)));
+ while(y0 > y1)
+ {
+ if (d <= 0)
+ {
+ d = d + incrN; /* Choose N */
+ }
+ else
+ {
+ d = d + incrNE; /* Choose NE */
+ x0++;
+ }
+ y0--;
+
+ r0+=dr;
+ g0+=dg;
+ b0+=db;
+
+ if ((x0>=drawX)&&(x0<drawW)&&(y0>=drawY)&&(y0<drawH))
+ GetShadeTransCol(&psxVuw[(y0<<10)+x0],(unsigned short)(((r0 >> 9)&0x7c00)|((g0 >> 14)&0x03e0)|((b0 >> 19)&0x001f)));
+ }
+}
+
+///////////////////////////////////////////////////////////////////////
+
+void Line_E_NE_Shade(int x0, int y0, int x1, int y1, uint32_t rgb0, uint32_t rgb1)
+{
+ int dx, dy, incrE, incrNE, d;
+ uint32_t r0, g0, b0, r1, g1, b1;
+ int dr, dg, db;
+
+ r0 = (rgb0 & 0x00ff0000);
+ g0 = (rgb0 & 0x0000ff00) << 8;
+ b0 = (rgb0 & 0x000000ff) << 16;
+ r1 = (rgb1 & 0x00ff0000);
+ g1 = (rgb1 & 0x0000ff00) << 8;
+ b1 = (rgb1 & 0x000000ff) << 16;
+
+ dx = x1 - x0;
+ dy = -(y1 - y0);
+
+ if (dx > 0)
+ {
+ dr = ((int)r1 - (int)r0) / dx;
+ dg = ((int)g1 - (int)g0) / dx;
+ db = ((int)b1 - (int)b0) / dx;
+ }
+ else
+ {
+ dr = ((int)r1 - (int)r0);
+ dg = ((int)g1 - (int)g0);
+ db = ((int)b1 - (int)b0);
+ }
+
+ d = 2*dy - dx; /* Initial value of d */
+ incrE = 2*dy; /* incr. used for move to E */
+ incrNE = 2*(dy - dx); /* incr. used for move to NE */
+
+ if ((x0>=drawX)&&(x0<drawW)&&(y0>=drawY)&&(y0<drawH))
+ GetShadeTransCol(&psxVuw[(y0<<10)+x0],(unsigned short)(((r0 >> 9)&0x7c00)|((g0 >> 14)&0x03e0)|((b0 >> 19)&0x001f)));
+ while(x0 < x1)
+ {
+ if (d <= 0)
+ {
+ d = d + incrE; /* Choose E */
+ }
+ else
+ {
+ d = d + incrNE; /* Choose NE */
+ y0--;
+ }
+ x0++;
+
+ r0+=dr;
+ g0+=dg;
+ b0+=db;
+
+ if ((x0>=drawX)&&(x0<drawW)&&(y0>=drawY)&&(y0<drawH))
+ GetShadeTransCol(&psxVuw[(y0<<10)+x0],(unsigned short)(((r0 >> 9)&0x7c00)|((g0 >> 14)&0x03e0)|((b0 >> 19)&0x001f)));
+ }
+}
+
+///////////////////////////////////////////////////////////////////////
+
+void VertLineShade(int x, int y0, int y1, uint32_t rgb0, uint32_t rgb1)
+{
+ int y, dy;
+ uint32_t r0, g0, b0, r1, g1, b1;
+ int dr, dg, db;
+
+ r0 = (rgb0 & 0x00ff0000);
+ g0 = (rgb0 & 0x0000ff00) << 8;
+ b0 = (rgb0 & 0x000000ff) << 16;
+ r1 = (rgb1 & 0x00ff0000);
+ g1 = (rgb1 & 0x0000ff00) << 8;
+ b1 = (rgb1 & 0x000000ff) << 16;
+
+ dy = (y1 - y0);
+
+ if (dy > 0)
+ {
+ dr = ((int)r1 - (int)r0) / dy;
+ dg = ((int)g1 - (int)g0) / dy;
+ db = ((int)b1 - (int)b0) / dy;
+ }
+ else
+ {
+ dr = ((int)r1 - (int)r0);
+ dg = ((int)g1 - (int)g0);
+ db = ((int)b1 - (int)b0);
+ }
+
+ if (y0 < drawY)
+ {
+ r0+=dr*(drawY - y0);
+ g0+=dg*(drawY - y0);
+ b0+=db*(drawY - y0);
+ y0 = drawY;
+ }
+
+ if (y1 > drawH)
+ y1 = drawH;
+
+ for (y = y0; y <= y1; y++)
+ {
+ GetShadeTransCol(&psxVuw[(y<<10)+x],(unsigned short)(((r0 >> 9)&0x7c00)|((g0 >> 14)&0x03e0)|((b0 >> 19)&0x001f)));
+ r0+=dr;
+ g0+=dg;
+ b0+=db;
+ }
+}
+
+///////////////////////////////////////////////////////////////////////
+
+void HorzLineShade(int y, int x0, int x1, uint32_t rgb0, uint32_t rgb1)
+{
+ int x, dx;
+ uint32_t r0, g0, b0, r1, g1, b1;
+ int dr, dg, db;
+
+ r0 = (rgb0 & 0x00ff0000);
+ g0 = (rgb0 & 0x0000ff00) << 8;
+ b0 = (rgb0 & 0x000000ff) << 16;
+ r1 = (rgb1 & 0x00ff0000);
+ g1 = (rgb1 & 0x0000ff00) << 8;
+ b1 = (rgb1 & 0x000000ff) << 16;
+
+ dx = (x1 - x0);
+
+ if (dx > 0)
+ {
+ dr = ((int)r1 - (int)r0) / dx;
+ dg = ((int)g1 - (int)g0) / dx;
+ db = ((int)b1 - (int)b0) / dx;
+ }
+ else
+ {
+ dr = ((int)r1 - (int)r0);
+ dg = ((int)g1 - (int)g0);
+ db = ((int)b1 - (int)b0);
+ }
+
+ if (x0 < drawX)
+ {
+ r0+=dr*(drawX - x0);
+ g0+=dg*(drawX - x0);
+ b0+=db*(drawX - x0);
+ x0 = drawX;
+ }
+
+ if (x1 > drawW)
+ x1 = drawW;
+
+ for (x = x0; x <= x1; x++)
+ {
+ GetShadeTransCol(&psxVuw[(y<<10)+x],(unsigned short)(((r0 >> 9)&0x7c00)|((g0 >> 14)&0x03e0)|((b0 >> 19)&0x001f)));
+ r0+=dr;
+ g0+=dg;
+ b0+=db;
+ }
+}
+
+///////////////////////////////////////////////////////////////////////
+
+void Line_E_SE_Flat(int x0, int y0, int x1, int y1, unsigned short colour)
+{
+ int dx, dy, incrE, incrSE, d, x, y;
+
+ dx = x1 - x0;
+ dy = y1 - y0;
+ d = 2*dy - dx; /* Initial value of d */
+ incrE = 2*dy; /* incr. used for move to E */
+ incrSE = 2*(dy - dx); /* incr. used for move to SE */
+ x = x0;
+ y = y0;
+ if ((x>=drawX)&&(x<drawW)&&(y>=drawY)&&(y<drawH))
+ GetShadeTransCol(&psxVuw[(y<<10)+x], colour);
+ while(x < x1)
+ {
+ if (d <= 0)
+ {
+ d = d + incrE; /* Choose E */
+ x++;
+ }
+ else
+ {
+ d = d + incrSE; /* Choose SE */
+ x++;
+ y++;
+ }
+ if ((x>=drawX)&&(x<drawW)&&(y>=drawY)&&(y<drawH))
+ GetShadeTransCol(&psxVuw[(y<<10)+x], colour);
+ }
+}
+
+///////////////////////////////////////////////////////////////////////
+
+void Line_S_SE_Flat(int x0, int y0, int x1, int y1, unsigned short colour)
+{
+ int dx, dy, incrS, incrSE, d, x, y;
+
+ dx = x1 - x0;
+ dy = y1 - y0;
+ d = 2*dx - dy; /* Initial value of d */
+ incrS = 2*dx; /* incr. used for move to S */
+ incrSE = 2*(dx - dy); /* incr. used for move to SE */
+ x = x0;
+ y = y0;
+ if ((x>=drawX)&&(x<drawW)&&(y>=drawY)&&(y<drawH))
+ GetShadeTransCol(&psxVuw[(y<<10)+x], colour);
+ while(y < y1)
+ {
+ if (d <= 0)
+ {
+ d = d + incrS; /* Choose S */
+ y++;
+ }
+ else
+ {
+ d = d + incrSE; /* Choose SE */
+ x++;
+ y++;
+ }
+ if ((x>=drawX)&&(x<drawW)&&(y>=drawY)&&(y<drawH))
+ GetShadeTransCol(&psxVuw[(y<<10)+x], colour);
+ }
+}
+
+///////////////////////////////////////////////////////////////////////
+
+void Line_N_NE_Flat(int x0, int y0, int x1, int y1, unsigned short colour)
+{
+ int dx, dy, incrN, incrNE, d, x, y;
+
+ dx = x1 - x0;
+ dy = -(y1 - y0);
+ d = 2*dx - dy; /* Initial value of d */
+ incrN = 2*dx; /* incr. used for move to N */
+ incrNE = 2*(dx - dy); /* incr. used for move to NE */
+ x = x0;
+ y = y0;
+ if ((x>=drawX)&&(x<drawW)&&(y>=drawY)&&(y<drawH))
+ GetShadeTransCol(&psxVuw[(y<<10)+x], colour);
+ while(y > y1)
+ {
+ if (d <= 0)
+ {
+ d = d + incrN; /* Choose N */
+ y--;
+ }
+ else
+ {
+ d = d + incrNE; /* Choose NE */
+ x++;
+ y--;
+ }
+ if ((x>=drawX)&&(x<drawW)&&(y>=drawY)&&(y<drawH))
+ GetShadeTransCol(&psxVuw[(y<<10)+x], colour);
+ }
+}
+
+///////////////////////////////////////////////////////////////////////
+
+void Line_E_NE_Flat(int x0, int y0, int x1, int y1, unsigned short colour)
+{
+ int dx, dy, incrE, incrNE, d, x, y;
+
+ dx = x1 - x0;
+ dy = -(y1 - y0);
+ d = 2*dy - dx; /* Initial value of d */
+ incrE = 2*dy; /* incr. used for move to E */
+ incrNE = 2*(dy - dx); /* incr. used for move to NE */
+ x = x0;
+ y = y0;
+ if ((x>=drawX)&&(x<drawW)&&(y>=drawY)&&(y<drawH))
+ GetShadeTransCol(&psxVuw[(y<<10)+x], colour);
+ while(x < x1)
+ {
+ if (d <= 0)
+ {
+ d = d + incrE; /* Choose E */
+ x++;
+ }
+ else
+ {
+ d = d + incrNE; /* Choose NE */
+ x++;
+ y--;
+ }
+ if ((x>=drawX)&&(x<drawW)&&(y>=drawY)&&(y<drawH))
+ GetShadeTransCol(&psxVuw[(y<<10)+x], colour);
+ }
+}
+
+///////////////////////////////////////////////////////////////////////
+
+void VertLineFlat(int x, int y0, int y1, unsigned short colour)
+{
+ int y;
+
+ if (y0 < drawY)
+ y0 = drawY;
+
+ if (y1 > drawH)
+ y1 = drawH;
+
+ for (y = y0; y <= y1; y++)
+ GetShadeTransCol(&psxVuw[(y<<10)+x], colour);
+}
+
+///////////////////////////////////////////////////////////////////////
+
+void HorzLineFlat(int y, int x0, int x1, unsigned short colour)
+{
+ int x;
+
+ if (x0 < drawX)
+ x0 = drawX;
+
+ if (x1 > drawW)
+ x1 = drawW;
+
+ for (x = x0; x <= x1; x++)
+ GetShadeTransCol(&psxVuw[(y<<10)+x], colour);
+}
+
+///////////////////////////////////////////////////////////////////////
+
+/* Bresenham Line drawing function */
+void DrawSoftwareLineShade(int rgb0, int rgb1)
+{
+ short x0, y0, x1, y1, xt, yt;
+ int rgbt;
+ double m, dy, dx;
+
+ if(lx0>drawW && lx1>drawW) return;
+ if(ly0>drawH && ly1>drawH) return;
+ if(lx0<drawX && lx1<drawX) return;
+ if(ly0<drawY && ly1<drawY) return;
+ if(drawY>=drawH) return;
+ if(drawX>=drawW) return;
+
+ x0 = lx0;
+ y0 = ly0;
+ x1 = lx1;
+ y1 = ly1;
+
+ dx = x1 - x0;
+ dy = y1 - y0;
+
+ if (dx == 0)
+ {
+ if (dy > 0)
+ VertLineShade(x0, y0, y1, rgb0, rgb1);
+ else
+ VertLineShade(x0, y1, y0, rgb1, rgb0);
+ }
+ else
+ if (dy == 0)
+ {
+ if (dx > 0)
+ HorzLineShade(y0, x0, x1, rgb0, rgb1);
+ else
+ HorzLineShade(y0, x1, x0, rgb1, rgb0);
+ }
+ else
+ {
+ if (dx < 0)
+ {
+ xt = x0;
+ yt = y0;
+ rgbt = rgb0;
+ x0 = x1;
+ y0 = y1;
+ rgb0 = rgb1;
+ x1 = xt;
+ y1 = yt;
+ rgb1 = rgbt;
+
+ dx = x1 - x0;
+ dy = y1 - y0;
+ }
+
+ m = dy/dx;
+
+ if (m >= 0)
+ {
+ if (m > 1)
+ Line_S_SE_Shade(x0, y0, x1, y1, rgb0, rgb1);
+ else
+ Line_E_SE_Shade(x0, y0, x1, y1, rgb0, rgb1);
+ }
+ else
+ if (m < -1)
+ Line_N_NE_Shade(x0, y0, x1, y1, rgb0, rgb1);
+ else
+ Line_E_NE_Shade(x0, y0, x1, y1, rgb0, rgb1);
+ }
+}
+
+///////////////////////////////////////////////////////////////////////
+
+void DrawSoftwareLineFlat(int rgb)
+{
+ short x0, y0, x1, y1, xt, yt;
+ double m, dy, dx;
+ unsigned short colour = 0;
+
+ if(lx0>drawW && lx1>drawW) return;
+ if(ly0>drawH && ly1>drawH) return;
+ if(lx0<drawX && lx1<drawX) return;
+ if(ly0<drawY && ly1<drawY) return;
+ if(drawY>=drawH) return;
+ if(drawX>=drawW) return;
+
+ colour = ((rgb & 0x00f80000)>>9) | ((rgb & 0x0000f800)>>6) | ((rgb & 0x000000f8)>>3);
+
+ x0 = lx0;
+ y0 = ly0;
+ x1 = lx1;
+ y1 = ly1;
+
+ dx = x1 - x0;
+ dy = y1 - y0;
+
+ if (dx == 0)
+ {
+ if (dy == 0)
+ return; // Nothing to draw
+ else if (dy > 0)
+ VertLineFlat(x0, y0, y1, colour);
+ else
+ VertLineFlat(x0, y1, y0, colour);
+ }
+ else
+ if (dy == 0)
+ {
+ if (dx > 0)
+ HorzLineFlat(y0, x0, x1, colour);
+ else
+ HorzLineFlat(y0, x1, x0, colour);
+ }
+ else
+ {
+ if (dx < 0)
+ {
+ xt = x0;
+ yt = y0;
+ x0 = x1;
+ y0 = y1;
+ x1 = xt;
+ y1 = yt;
+
+ dx = x1 - x0;
+ dy = y1 - y0;
+ }
+
+ m = dy/dx;
+
+ if (m >= 0)
+ {
+ if (m > 1)
+ Line_S_SE_Flat(x0, y0, x1, y1, colour);
+ else
+ Line_E_SE_Flat(x0, y0, x1, y1, colour);
+ }
+ else
+ if (m < -1)
+ Line_N_NE_Flat(x0, y0, x1, y1, colour);
+ else
+ Line_E_NE_Flat(x0, y0, x1, y1, colour);
+ }
+}
+
+///////////////////////////////////////////////////////////////////////
diff --git a/plugins/peopsxgl/texture.c b/plugins/peopsxgl/texture.c index f247175a..90344d58 100644 --- a/plugins/peopsxgl/texture.c +++ b/plugins/peopsxgl/texture.c @@ -1,4925 +1,4917 @@ -/*************************************************************************** - texture.c - description - ------------------- - begin : Sun Mar 08 2009 - copyright : (C) 1999-2009 by Pete Bernert - web : www.pbernert.com - ***************************************************************************/ - -/*************************************************************************** - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. See also the license.txt file for * - * additional informations. * - * * - ***************************************************************************/ - -#include "stdafx.h" - -//////////////////////////////////////////////////////////////////////////////////// -// Texture related functions are here ! -// -// The texture handling is heart and soul of this gpu. The plugin was developed -// 1999, by this time no shaders were available. Since the psx gpu is making -// heavy use of CLUT (="color lookup tables", aka palettized textures), it was -// an interesting task to get those emulated at good speed on NV TNT cards -// (which was my major goal when I created the first "gpuPeteTNT"). Later cards -// (Geforce256) supported texture palettes by an OGL extension, but at some point -// this support was dropped again by gfx card vendors. -// Well, at least there is a certain advatage, if no texture palettes extension can -// be used: it is possible to modify the textures in any way, allowing "hi-res" -// textures and other tweaks. -// -// My main texture caching is kinda complex: the plugin is allocating "n" 256x256 textures, -// and it places small psx texture parts inside them. The plugin keeps track what -// part (with what palette) it had placed in which texture, so it can re-use this -// part again. The more ogl textures it can use, the better (of course the managing/ -// searching will be slower, but everything is faster than uploading textures again -// and again to a gfx card). My first card (TNT1) had 16 MB Vram, and it worked -// well with many games, but I recommend nowadays 64 MB Vram to get a good speed. -// -// Sadly, there is also a second kind of texture cache needed, for "psx texture windows". -// Those are "repeated" textures, so a psx "texture window" needs to be put in -// a whole texture to use the GL_TEXTURE_WRAP_ features. This cache can get full very -// fast in games which are having an heavy "texture window" usage, like RRT4. As an -// alternative, this plugin can use the OGL "palette" extension on texture windows, -// if available. Nowadays also a fragment shader can easily be used to emulate -// texture wrapping in a texture atlas, so the main cache could hold the texture -// windows as well (that's what I am doing in the OGL2 plugin). But currently the -// OGL1 plugin is a "shader-free" zone, so heavy "texture window" games will cause -// much texture uploads. -// -// Some final advice: take care if you change things in here. I've removed my ASM -// handlers (they didn't cause much speed gain anyway) for readability/portability, -// but still the functions/data structures used here are easy to mess up. I guess it -// can be a pain in the ass to port the plugin to another byte order :) -// -//////////////////////////////////////////////////////////////////////////////////// - -#define _IN_TEXTURE - -#include "externals.h" -#include "texture.h" -#include "gpu.h" -#include "prim.h" - -#define CLUTCHK 0x00060000 -#define CLUTSHIFT 17 - -//////////////////////////////////////////////////////////////////////// -// texture conversion buffer .. -//////////////////////////////////////////////////////////////////////// - -int iHiResTextures=0; -GLubyte ubPaletteBuffer[256][4]; -GLuint gTexMovieName=0; -GLuint gTexBlurName=0; -GLuint gTexFrameName=0; -int iTexGarbageCollection=1; -uint32_t dwTexPageComp=0; -int iVRamSize=0; -int iClampType=GL_CLAMP; - -void (*LoadSubTexFn) (int,int,short,short); -uint32_t (*PalTexturedColourFn) (uint32_t); - -//////////////////////////////////////////////////////////////////////// -// defines -//////////////////////////////////////////////////////////////////////// - -#define PALCOL(x) PalTexturedColourFn (x) - -#define CSUBSIZE 2048 -#define CSUBSIZEA 8192 -#define CSUBSIZES 4096 - -#define OFFA 0 -#define OFFB 2048 -#define OFFC 4096 -#define OFFD 6144 - -#define XOFFA 0 -#define XOFFB 512 -#define XOFFC 1024 -#define XOFFD 1536 - -#define SOFFA 0 -#define SOFFB 1024 -#define SOFFC 2048 -#define SOFFD 3072 - -#define MAXWNDTEXCACHE 128 - -#define XCHECK(pos1,pos2) ((pos1.c[0]>=pos2.c[1])&&(pos1.c[1]<=pos2.c[0])&&(pos1.c[2]>=pos2.c[3])&&(pos1.c[3]<=pos2.c[2])) -#define INCHECK(pos2,pos1) ((pos1.c[0]<=pos2.c[0]) && (pos1.c[1]>=pos2.c[1]) && (pos1.c[2]<=pos2.c[2]) && (pos1.c[3]>=pos2.c[3])) - -//////////////////////////////////////////////////////////////////////// - -unsigned char * CheckTextureInSubSCache(int TextureMode, uint32_t GivenClutId, unsigned short *pCache); -void LoadSubTexturePageSort(int pageid, int mode, short cx, short cy); -void LoadPackedSubTexturePageSort(int pageid, int mode, short cx, short cy); -void DefineSubTextureSort(void); - -//////////////////////////////////////////////////////////////////////// -// some globals -//////////////////////////////////////////////////////////////////////// - -GLint giWantedRGBA=4; -GLint giWantedFMT=GL_RGBA; -GLint giWantedTYPE=GL_UNSIGNED_BYTE; -int GlobalTexturePage; -GLint XTexS; -GLint YTexS; -GLint DXTexS; -GLint DYTexS; -int iSortTexCnt=32; -BOOL bUseFastMdec=FALSE; -BOOL bUse15bitMdec=FALSE; -int iFrameTexType=0; -int iFrameReadType=0; - -uint32_t (*TCF[2]) (uint32_t); -unsigned short (*PTCF[2]) (unsigned short); - -//////////////////////////////////////////////////////////////////////// -// texture cache implementation -//////////////////////////////////////////////////////////////////////// - -#ifdef _WINDOWS -#pragma pack(1) -#endif - -// "texture window" cache entry - -typedef struct textureWndCacheEntryTag -{ - uint32_t ClutID; - short pageid; - short textureMode; - short Opaque; - short used; - EXLong pos; - GLuint texname; -} textureWndCacheEntry; - -// "standard texture" cache entry (12 byte per entry, as small as possible... we need lots of them) - -typedef struct textureSubCacheEntryTagS -{ - uint32_t ClutID; - EXLong pos; - unsigned char posTX; - unsigned char posTY; - unsigned char cTexID; - unsigned char Opaque; -} textureSubCacheEntryS; - -#ifdef _WINDOWS -#pragma pack() -#endif - -//--------------------------------------------- - -#define MAXTPAGES_MAX 64 -#define MAXSORTTEX_MAX 196 - -//--------------------------------------------- - -textureWndCacheEntry wcWndtexStore[MAXWNDTEXCACHE]; -textureSubCacheEntryS * pscSubtexStore[3][MAXTPAGES_MAX]; -EXLong * pxSsubtexLeft [MAXSORTTEX_MAX]; -GLuint uiStexturePage[MAXSORTTEX_MAX]; - -unsigned short usLRUTexPage = 0; - -int iMaxTexWnds = 0; -int iTexWndTurn = 0; -int iTexWndLimit = MAXWNDTEXCACHE/2; - -GLubyte * texturepart = NULL; -GLubyte * texturebuffer = NULL; -uint32_t g_x1,g_y1,g_x2,g_y2; -unsigned char ubOpaqueDraw = 0; - -unsigned short MAXTPAGES = 32; -unsigned short CLUTMASK = 0x7fff; -unsigned short CLUTYMASK = 0x1ff; -unsigned short MAXSORTTEX = 196; - -//////////////////////////////////////////////////////////////////////// -// Texture color conversions... all my ASM funcs are removed for easier -// porting... and honestly: nowadays the speed gain would be pointless -//////////////////////////////////////////////////////////////////////// - -uint32_t XP8RGBA(uint32_t BGR) -{ - if(!(BGR&0xffff)) return 0x50000000; - if(DrawSemiTrans && !(BGR&0x8000)) - {ubOpaqueDraw=1;return ((((BGR<<3)&0xf8)|((BGR<<6)&0xf800)|((BGR<<9)&0xf80000))&0xffffff);} - return ((((BGR<<3)&0xf8)|((BGR<<6)&0xf800)|((BGR<<9)&0xf80000))&0xffffff)|0xff000000; -} - -uint32_t XP8RGBAEx(uint32_t BGR) -{ - if(!(BGR&0xffff)) return 0x03000000; - if(DrawSemiTrans && !(BGR&0x8000)) - {ubOpaqueDraw=1;return ((((BGR<<3)&0xf8)|((BGR<<6)&0xf800)|((BGR<<9)&0xf80000))&0xffffff);} - return ((((BGR<<3)&0xf8)|((BGR<<6)&0xf800)|((BGR<<9)&0xf80000))&0xffffff)|0xff000000; -} - -uint32_t CP8RGBA(uint32_t BGR) -{ - uint32_t l; - if(!(BGR&0xffff)) return 0x50000000; - if(DrawSemiTrans && !(BGR&0x8000)) - {ubOpaqueDraw=1;return ((((BGR<<3)&0xf8)|((BGR<<6)&0xf800)|((BGR<<9)&0xf80000))&0xffffff);} - l=((((BGR<<3)&0xf8)|((BGR<<6)&0xf800)|((BGR<<9)&0xf80000))&0xffffff)|0xff000000; - if(l==0xffffff00) l=0xff000000; - return l; -} - -uint32_t CP8RGBAEx(uint32_t BGR) -{ - uint32_t l; - if(!(BGR&0xffff)) return 0x03000000; - if(DrawSemiTrans && !(BGR&0x8000)) - {ubOpaqueDraw=1;return ((((BGR<<3)&0xf8)|((BGR<<6)&0xf800)|((BGR<<9)&0xf80000))&0xffffff);} - l=((((BGR<<3)&0xf8)|((BGR<<6)&0xf800)|((BGR<<9)&0xf80000))&0xffffff)|0xff000000; - if(l==0xffffff00) l=0xff000000; - return l; -} - -uint32_t XP8RGBA_0(uint32_t BGR) -{ - if(!(BGR&0xffff)) return 0x50000000; - return ((((BGR<<3)&0xf8)|((BGR<<6)&0xf800)|((BGR<<9)&0xf80000))&0xffffff)|0xff000000; -} - -uint32_t XP8RGBAEx_0(uint32_t BGR) -{ - if(!(BGR&0xffff)) return 0x03000000; - return ((((BGR<<3)&0xf8)|((BGR<<6)&0xf800)|((BGR<<9)&0xf80000))&0xffffff)|0xff000000; -} - -uint32_t XP8BGRA_0(uint32_t BGR) -{ - if(!(BGR&0xffff)) return 0x50000000; - return ((((BGR>>7)&0xf8)|((BGR<<6)&0xf800)|((BGR<<19)&0xf80000))&0xffffff)|0xff000000; -} - -uint32_t XP8BGRAEx_0(uint32_t BGR) -{ - if(!(BGR&0xffff)) return 0x03000000; - return ((((BGR>>7)&0xf8)|((BGR<<6)&0xf800)|((BGR<<19)&0xf80000))&0xffffff)|0xff000000; -} - -uint32_t CP8RGBA_0(uint32_t BGR) -{ - uint32_t l; - - if(!(BGR&0xffff)) return 0x50000000; - l=((((BGR<<3)&0xf8)|((BGR<<6)&0xf800)|((BGR<<9)&0xf80000))&0xffffff)|0xff000000; - if(l==0xfff8f800) l=0xff000000; - return l; -} - -uint32_t CP8RGBAEx_0(uint32_t BGR) -{ - uint32_t l; - - if(!(BGR&0xffff)) return 0x03000000; - l=((((BGR<<3)&0xf8)|((BGR<<6)&0xf800)|((BGR<<9)&0xf80000))&0xffffff)|0xff000000; - if(l==0xfff8f800) l=0xff000000; - return l; -} - -uint32_t CP8BGRA_0(uint32_t BGR) -{ - uint32_t l; - - if(!(BGR&0xffff)) return 0x50000000; - l=((((BGR>>7)&0xf8)|((BGR<<6)&0xf800)|((BGR<<19)&0xf80000))&0xffffff)|0xff000000; - if(l==0xff00f8f8) l=0xff000000; - return l; -} - -uint32_t CP8BGRAEx_0(uint32_t BGR) -{ - uint32_t l; - - if(!(BGR&0xffff)) return 0x03000000; - l=((((BGR>>7)&0xf8)|((BGR<<6)&0xf800)|((BGR<<19)&0xf80000))&0xffffff)|0xff000000; - if(l==0xff00f8f8) l=0xff000000; - return l; -} - -uint32_t XP8RGBA_1(uint32_t BGR) -{ - if(!(BGR&0xffff)) return 0x50000000; - if(!(BGR&0x8000)) {ubOpaqueDraw=1;return ((((BGR<<3)&0xf8)|((BGR<<6)&0xf800)|((BGR<<9)&0xf80000))&0xffffff);} - return ((((BGR<<3)&0xf8)|((BGR<<6)&0xf800)|((BGR<<9)&0xf80000))&0xffffff)|0xff000000; -} - -uint32_t XP8RGBAEx_1(uint32_t BGR) -{ - if(!(BGR&0xffff)) return 0x03000000; - if(!(BGR&0x8000)) {ubOpaqueDraw=1;return ((((BGR<<3)&0xf8)|((BGR<<6)&0xf800)|((BGR<<9)&0xf80000))&0xffffff);} - return ((((BGR<<3)&0xf8)|((BGR<<6)&0xf800)|((BGR<<9)&0xf80000))&0xffffff)|0xff000000; -} - -uint32_t XP8BGRA_1(uint32_t BGR) -{ - if(!(BGR&0xffff)) return 0x50000000; - if(!(BGR&0x8000)) {ubOpaqueDraw=1;return ((((BGR>>7)&0xf8)|((BGR<<6)&0xf800)|((BGR<<19)&0xf80000))&0xffffff);} - return ((((BGR>>7)&0xf8)|((BGR<<6)&0xf800)|((BGR<<19)&0xf80000))&0xffffff)|0xff000000; -} - -uint32_t XP8BGRAEx_1(uint32_t BGR) -{ - if(!(BGR&0xffff)) return 0x03000000; - if(!(BGR&0x8000)) {ubOpaqueDraw=1;return ((((BGR>>7)&0xf8)|((BGR<<6)&0xf800)|((BGR<<19)&0xf80000))&0xffffff);} - return ((((BGR>>7)&0xf8)|((BGR<<6)&0xf800)|((BGR<<19)&0xf80000))&0xffffff)|0xff000000; -} - -uint32_t P8RGBA(uint32_t BGR) -{ - if(!(BGR&0xffff)) return 0; - return ((((BGR<<3)&0xf8)|((BGR<<6)&0xf800)|((BGR<<9)&0xf80000))&0xffffff)|0xff000000; -} - -uint32_t P8BGRA(uint32_t BGR) -{ - if(!(BGR&0xffff)) return 0; - return ((((BGR>>7)&0xf8)|((BGR<<6)&0xf800)|((BGR<<19)&0xf80000))&0xffffff)|0xff000000; -} - -unsigned short XP5RGBA(unsigned short BGR) -{ - if(!BGR) return 0; - if(DrawSemiTrans && !(BGR&0x8000)) - {ubOpaqueDraw=1;return ((((BGR<<11))|((BGR>>9)&0x3e)|((BGR<<1)&0x7c0)));} - return ((((BGR<<11))|((BGR>>9)&0x3e)|((BGR<<1)&0x7c0)))|1; -} - -unsigned short XP5RGBA_0 (unsigned short BGR) -{ - if(!BGR) return 0; - - return ((((BGR<<11))|((BGR>>9)&0x3e)|((BGR<<1)&0x7c0)))|1; -} - -unsigned short CP5RGBA_0 (unsigned short BGR) -{ - unsigned short s; - - if(!BGR) return 0; - - s=((((BGR<<11))|((BGR>>9)&0x3e)|((BGR<<1)&0x7c0)))|1; - if(s==0x07ff) s=1; - return s; -} - -unsigned short XP5RGBA_1(unsigned short BGR) -{ - if(!BGR) return 0; - if(!(BGR&0x8000)) - {ubOpaqueDraw=1;return ((((BGR<<11))|((BGR>>9)&0x3e)|((BGR<<1)&0x7c0)));} - return ((((BGR<<11))|((BGR>>9)&0x3e)|((BGR<<1)&0x7c0)))|1; -} - -unsigned short P5RGBA(unsigned short BGR) -{ - if(!BGR) return 0; - return ((((BGR<<11))|((BGR>>9)&0x3e)|((BGR<<1)&0x7c0)))|1; -} - -unsigned short XP4RGBA(unsigned short BGR) -{ - if(!BGR) return 6; - if(DrawSemiTrans && !(BGR&0x8000)) - {ubOpaqueDraw=1;return ((((BGR<<11))|((BGR>>9)&0x3e)|((BGR<<1)&0x7c0)));} - return (((((BGR&0x1e)<<11))|((BGR&0x7800)>>7)|((BGR&0x3c0)<<2)))|0xf; -} - -unsigned short XP4RGBA_0 (unsigned short BGR) -{ - if(!BGR) return 6; - return (((((BGR&0x1e)<<11))|((BGR&0x7800)>>7)|((BGR&0x3c0)<<2)))|0xf; -} - -unsigned short CP4RGBA_0 (unsigned short BGR) -{ - unsigned short s; - if(!BGR) return 6; - s=(((((BGR&0x1e)<<11))|((BGR&0x7800)>>7)|((BGR&0x3c0)<<2)))|0xf; - if(s==0x0fff) s=0x000f; - return s; -} - -unsigned short XP4RGBA_1(unsigned short BGR) -{ - if(!BGR) return 6; - if(!(BGR&0x8000)) - {ubOpaqueDraw=1;return ((((BGR<<11))|((BGR>>9)&0x3e)|((BGR<<1)&0x7c0)));} - return (((((BGR&0x1e)<<11))|((BGR&0x7800)>>7)|((BGR&0x3c0)<<2)))|0xf; -} - -unsigned short P4RGBA(unsigned short BGR) -{ - if(!BGR) return 0; - return (((((BGR&0x1e)<<11))|((BGR&0x7800)>>7)|((BGR&0x3c0)<<2)))|0xf; -} - -//////////////////////////////////////////////////////////////////////// -// CHECK TEXTURE MEM (on plugin startup) -//////////////////////////////////////////////////////////////////////// - -int iFTexA=512; -int iFTexB=512; - -void CheckTextureMemory(void) -{ - GLboolean b;GLboolean * bDetail; - int i,iCnt,iRam=iVRamSize*1024*1024; - int iTSize;char * p; - - if(iBlurBuffer) - { - char * p; - - if(iResX>1024) iFTexA=2048; - else - if(iResX>512) iFTexA=1024; - else iFTexA=512; - if(iResY>1024) iFTexB=2048; - else - if(iResY>512) iFTexB=1024; - else iFTexB=512; - - glGenTextures(1, &gTexBlurName); - gTexName=gTexBlurName; - glBindTexture(GL_TEXTURE_2D, gTexName); - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - - p=(char *)malloc(iFTexA*iFTexB*4); - memset(p,0,iFTexA*iFTexB*4); - glTexImage2D(GL_TEXTURE_2D, 0, 3, iFTexA, iFTexB, 0, GL_RGB, GL_UNSIGNED_BYTE, p); - free(p); - glGetError(); - iRam-=iFTexA*iFTexB*3; - iFTexA=(iResX*256)/iFTexA; - iFTexB=(iResY*256)/iFTexB; - } - - if(iVRamSize) - { - int ts; - - iRam-=(iResX*iResY*8); - iRam-=(iResX*iResY*(iZBufferDepth/8)); - - if(iTexQuality==0 || iTexQuality==3) ts=4; - else ts=2; - - if(iHiResTextures) - iSortTexCnt=iRam/(512*512*ts); - else iSortTexCnt=iRam/(256*256*ts); - - if(iSortTexCnt>MAXSORTTEX) - { - iSortTexCnt=MAXSORTTEX-min(1,iHiResTextures); - } - else - { - iSortTexCnt-=3+min(1,iHiResTextures); - if(iSortTexCnt<8) iSortTexCnt=8; - } - - for(i=0;i<MAXSORTTEX;i++) - uiStexturePage[i]=0; - - return; - } - - - if(iHiResTextures) iTSize=512; - else iTSize=256; - p=(char *)malloc(iTSize*iTSize*4); - - iCnt=0; - glGenTextures(MAXSORTTEX,uiStexturePage); - for(i=0;i<MAXSORTTEX;i++) - { - glBindTexture(GL_TEXTURE_2D,uiStexturePage[i]); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, iClampType); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, iClampType); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexImage2D(GL_TEXTURE_2D, 0, giWantedRGBA, iTSize, iTSize, 0,GL_RGBA, giWantedTYPE, p); - } - glBindTexture(GL_TEXTURE_2D,0); - - free(p); - - bDetail=malloc(MAXSORTTEX*sizeof(GLboolean)); - memset(bDetail,0,MAXSORTTEX*sizeof(GLboolean)); - b=glAreTexturesResident(MAXSORTTEX,uiStexturePage,bDetail); - - glDeleteTextures(MAXSORTTEX,uiStexturePage); - - for(i=0;i<MAXSORTTEX;i++) - { - if(bDetail[i]) iCnt++; - uiStexturePage[i]=0; - } - - free(bDetail); - - if(b) iSortTexCnt=MAXSORTTEX-min(1,iHiResTextures); - else iSortTexCnt=iCnt-3+min(1,iHiResTextures); // place for menu&texwnd - - if(iSortTexCnt<8) iSortTexCnt=8; -} - -//////////////////////////////////////////////////////////////////////// -// Main init of textures -//////////////////////////////////////////////////////////////////////// - -void InitializeTextureStore() -{ - int i,j; - - if(iGPUHeight==1024) - { - MAXTPAGES = 64; - CLUTMASK = 0xffff; - CLUTYMASK = 0x3ff; - MAXSORTTEX = 128; - iTexGarbageCollection=0; - } - else - { - MAXTPAGES = 32; - CLUTMASK = 0x7fff; - CLUTYMASK = 0x1ff; - MAXSORTTEX = 196; - } - - memset(vertex,0,4*sizeof(OGLVertex)); // init vertices - - gTexName=0; // init main tex name - - iTexWndLimit=MAXWNDTEXCACHE; - if(!iUsePalTextures) iTexWndLimit/=2; - - memset(wcWndtexStore,0,sizeof(textureWndCacheEntry)* - MAXWNDTEXCACHE); - texturepart=(GLubyte *)malloc(256*256*4); - memset(texturepart,0,256*256*4); - if(iHiResTextures) - texturebuffer=(GLubyte *)malloc(512*512*4); - else texturebuffer=NULL; - - for(i=0;i<3;i++) // -> info for 32*3 - for(j=0;j<MAXTPAGES;j++) - { - pscSubtexStore[i][j]=(textureSubCacheEntryS *)malloc(CSUBSIZES*sizeof(textureSubCacheEntryS)); - memset(pscSubtexStore[i][j],0,CSUBSIZES*sizeof(textureSubCacheEntryS)); - } - for(i=0;i<MAXSORTTEX;i++) // -> info 0..511 - { - pxSsubtexLeft[i]=(EXLong *)malloc(CSUBSIZE*sizeof(EXLong)); - memset(pxSsubtexLeft[i],0,CSUBSIZE*sizeof(EXLong)); - uiStexturePage[i]=0; - } -} - -//////////////////////////////////////////////////////////////////////// -// Clean up on exit -//////////////////////////////////////////////////////////////////////// - -void CleanupTextureStore() -{ - int i,j;textureWndCacheEntry * tsx; - //----------------------------------------------------// - glBindTexture(GL_TEXTURE_2D,0); - //----------------------------------------------------// - free(texturepart); // free tex part - texturepart=0; - if(texturebuffer) - { - free(texturebuffer); - texturebuffer=0; - } - //----------------------------------------------------// - tsx=wcWndtexStore; // loop tex window cache - for(i=0;i<MAXWNDTEXCACHE;i++,tsx++) - { - if(tsx->texname) // -> some tex? - glDeleteTextures(1,&tsx->texname); // --> delete it - } - iMaxTexWnds=0; // no more tex wnds - //----------------------------------------------------// - if(gTexMovieName!=0) // some movie tex? - glDeleteTextures(1, &gTexMovieName); // -> delete it - gTexMovieName=0; // no more movie tex - //----------------------------------------------------// - if(gTexFrameName!=0) // some 15bit framebuffer tex? - glDeleteTextures(1, &gTexFrameName); // -> delete it - gTexFrameName=0; // no more movie tex - //----------------------------------------------------// - if(gTexBlurName!=0) // some 15bit framebuffer tex? - glDeleteTextures(1, &gTexBlurName); // -> delete it - gTexBlurName=0; // no more movie tex - //----------------------------------------------------// - for(i=0;i<3;i++) // -> loop - for(j=0;j<MAXTPAGES;j++) // loop tex pages - { - free(pscSubtexStore[i][j]); // -> clean mem - } - for(i=0;i<MAXSORTTEX;i++) - { - if(uiStexturePage[i]) // --> tex used ? - { - glDeleteTextures(1,&uiStexturePage[i]); - uiStexturePage[i]=0; // --> delete it - } - free(pxSsubtexLeft[i]); // -> clean mem - } - //----------------------------------------------------// -} - -//////////////////////////////////////////////////////////////////////// -// Reset textures in game... -//////////////////////////////////////////////////////////////////////// - -void ResetTextureArea(BOOL bDelTex) -{ - int i,j;textureSubCacheEntryS * tss;EXLong * lu; - textureWndCacheEntry * tsx; - //----------------------------------------------------// - - dwTexPageComp=0; - - //----------------------------------------------------// - if(bDelTex) {glBindTexture(GL_TEXTURE_2D,0);gTexName=0;} - //----------------------------------------------------// - tsx=wcWndtexStore; - for(i=0;i<MAXWNDTEXCACHE;i++,tsx++) - { - tsx->used=0; - if(bDelTex && tsx->texname) - { - glDeleteTextures(1,&tsx->texname); - tsx->texname=0; - } - } - iMaxTexWnds=0; - //----------------------------------------------------// - - for(i=0;i<3;i++) - for(j=0;j<MAXTPAGES;j++) - { - tss=pscSubtexStore[i][j]; - (tss+SOFFA)->pos.l=0; - (tss+SOFFB)->pos.l=0; - (tss+SOFFC)->pos.l=0; - (tss+SOFFD)->pos.l=0; - } - - for(i=0;i<iSortTexCnt;i++) - { - lu=pxSsubtexLeft[i]; - lu->l=0; - if(bDelTex && uiStexturePage[i]) - {glDeleteTextures(1,&uiStexturePage[i]);uiStexturePage[i]=0;} - } -} - - -//////////////////////////////////////////////////////////////////////// -// Invalidate tex windows -//////////////////////////////////////////////////////////////////////// - -static void InvalidateWndTextureArea(int X, int Y, int W, int H) -{ - int i,px1,px2,py1,py2,iYM=1; - textureWndCacheEntry * tsw=wcWndtexStore; - - W+=X-1; - H+=Y-1; - if(X<0) X=0;if(X>1023) X=1023; - if(W<0) W=0;if(W>1023) W=1023; - if(Y<0) Y=0;if(Y>iGPUHeightMask) Y=iGPUHeightMask; - if(H<0) H=0;if(H>iGPUHeightMask) H=iGPUHeightMask; - W++;H++; - - if(iGPUHeight==1024) iYM=3; - - py1=min(iYM,Y>>8); - py2=min(iYM,H>>8); // y: 0 or 1 - - px1=max(0,(X>>6)); - px2=min(15,(W>>6)); - - if(py1==py2) - { - py1=py1<<4;px1+=py1;px2+=py1; // change to 0-31 - for(i=0;i<iMaxTexWnds;i++,tsw++) - { - if(tsw->used) - { - if(tsw->pageid>=px1 && tsw->pageid<=px2) - { - tsw->used=0; - } - } - } - } - else - { - py1=px1+16;py2=px2+16; - for(i=0;i<iMaxTexWnds;i++,tsw++) - { - if(tsw->used) - { - if((tsw->pageid>=px1 && tsw->pageid<=px2) || - (tsw->pageid>=py1 && tsw->pageid<=py2)) - { - tsw->used=0; - } - } - } - } - - // adjust tex window count - tsw=wcWndtexStore+iMaxTexWnds-1; - while(iMaxTexWnds && !tsw->used) {iMaxTexWnds--;tsw--;} -} - - - -//////////////////////////////////////////////////////////////////////// -// same for sort textures -//////////////////////////////////////////////////////////////////////// - -static void MarkFree(textureSubCacheEntryS * tsx) -{ - EXLong * ul, * uls; - int j,iMax;unsigned char x1,y1,dx,dy; - - uls=pxSsubtexLeft[tsx->cTexID]; - iMax=uls->l;ul=uls+1; - - if(!iMax) return; - - for(j=0;j<iMax;j++,ul++) - if(ul->l==0xffffffff) break; - - if(j<CSUBSIZE-2) - { - if(j==iMax) uls->l=uls->l+1; - - x1=tsx->posTX;dx=tsx->pos.c[2]-tsx->pos.c[3]; - if(tsx->posTX) {x1--;dx+=3;} - y1=tsx->posTY;dy=tsx->pos.c[0]-tsx->pos.c[1]; - if(tsx->posTY) {y1--;dy+=3;} - - ul->c[3]=x1; - ul->c[2]=dx; - ul->c[1]=y1; - ul->c[0]=dy; - } -} - -static void InvalidateSubSTextureArea(int X, int Y, int W, int H) -{ - int i,j,k,iMax,px,py,px1,px2,py1,py2,iYM = 1; - EXLong npos; - textureSubCacheEntryS *tsb; - int x1,x2,y1,y2,xa,sw; - - W+=X-1; - H+=Y-1; - if(X<0) X=0;if(X>1023) X=1023; - if(W<0) W=0;if(W>1023) W=1023; - if(Y<0) Y=0;if(Y>iGPUHeightMask) Y=iGPUHeightMask; - if(H<0) H=0;if(H>iGPUHeightMask) H=iGPUHeightMask; - W++;H++; - - if(iGPUHeight==1024) iYM=3; - - py1=min(iYM,Y>>8); - py2=min(iYM,H>>8); // y: 0 or 1 - px1=max(0,(X>>6)-3); - px2=min(15,(W>>6)+3); // x: 0-15 - - for(py=py1;py<=py2;py++) - { - j=(py<<4)+px1; // get page - - y1=py*256;y2=y1+255; - - if(H<y1) continue; - if(Y>y2) continue; - - if(Y>y1) y1=Y; - if(H<y2) y2=H; - if(y2<y1) {sw=y1;y1=y2;y2=sw;} - y1=((y1%256)<<8); - y2=(y2%256); - - for(px=px1;px<=px2;px++,j++) - { - for(k=0;k<3;k++) - { - xa=x1=px<<6; - if(W<x1) continue; - x2=x1+(64<<k)-1; - if(X>x2) continue; - - if(X>x1) x1=X; - if(W<x2) x2=W; - if(x2<x1) {sw=x1;x1=x2;x2=sw;} - - if (dwGPUVersion == 2) - npos.l=0x00ff00ff; - else - npos.l=((x1-xa)<<(26-k))|((x2-xa)<<(18-k))|y1|y2; - - { - tsb=pscSubtexStore[k][j]+SOFFA;iMax=tsb->pos.l;tsb++; - for(i=0;i<iMax;i++,tsb++) - if(tsb->ClutID && XCHECK(tsb->pos,npos)) {tsb->ClutID=0;MarkFree(tsb);} - -// if(npos.l & 0x00800000) - { - tsb=pscSubtexStore[k][j]+SOFFB;iMax=tsb->pos.l;tsb++; - for(i=0;i<iMax;i++,tsb++) - if(tsb->ClutID && XCHECK(tsb->pos,npos)) {tsb->ClutID=0;MarkFree(tsb);} - } - -// if(npos.l & 0x00000080) - { - tsb=pscSubtexStore[k][j]+SOFFC;iMax=tsb->pos.l;tsb++; - for(i=0;i<iMax;i++,tsb++) - if(tsb->ClutID && XCHECK(tsb->pos,npos)) {tsb->ClutID=0;MarkFree(tsb);} - } - -// if(npos.l & 0x00800080) - { - tsb=pscSubtexStore[k][j]+SOFFD;iMax=tsb->pos.l;tsb++; - for(i=0;i<iMax;i++,tsb++) - if(tsb->ClutID && XCHECK(tsb->pos,npos)) {tsb->ClutID=0;MarkFree(tsb);} - } - } - } - } - } -} - -//////////////////////////////////////////////////////////////////////// -// Invalidate some parts of cache: main routine -//////////////////////////////////////////////////////////////////////// - -void InvalidateTextureAreaEx(void) -{ - short W=sxmax-sxmin; - short H=symax-symin; - - if (W == 0 && H == 0) return; - - if (iMaxTexWnds) - InvalidateWndTextureArea(sxmin,symin,W,H); - - InvalidateSubSTextureArea(sxmin,symin,W,H); -} - -//////////////////////////////////////////////////////////////////////// - -void InvalidateTextureArea(int X, int Y, int W, int H) -{ - if (W == 0 && H == 0) return; - - if (iMaxTexWnds) InvalidateWndTextureArea(X, Y, W, H); - - InvalidateSubSTextureArea(X, Y, W, H); -} - - -//////////////////////////////////////////////////////////////////////// -// tex window: define -//////////////////////////////////////////////////////////////////////// - -static void DefineTextureWnd(void) -{ - if (gTexName == 0) - glGenTextures(1, &gTexName); - - glBindTexture(GL_TEXTURE_2D, gTexName); - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); - - if(iFilterType && iFilterType<3 && iHiResTextures!=2) - { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - } - else - { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - } - - glTexImage2D(GL_TEXTURE_2D, 0,giWantedRGBA, - TWin.Position.x1, - TWin.Position.y1, - 0, giWantedFMT, giWantedTYPE, texturepart); -} - -//////////////////////////////////////////////////////////////////////// -// tex window: load packed stretch -//////////////////////////////////////////////////////////////////////// - -static void LoadStretchPackedWndTexturePage(int pageid, int mode, short cx, short cy) -{ - uint32_t start, row, column, j, sxh, sxm, ldx, ldy, ldxo; - unsigned int palstart; - unsigned short *px, *pa, *ta; - unsigned char *cSRCPtr,*cOSRCPtr; - unsigned short *wSRCPtr,*wOSRCPtr; - uint32_t LineOffset; - unsigned short s; - int pmult = pageid / 16; - unsigned short (*LPTCOL)(unsigned short); - - LPTCOL = PTCF[DrawSemiTrans]; - - ldxo = TWin.Position.x1-TWin.OPosition.x1; - ldy = TWin.Position.y1-TWin.OPosition.y1; - - pa = px = (unsigned short *)ubPaletteBuffer; - ta = (unsigned short *)texturepart; - palstart = cx + (cy * 1024); - - ubOpaqueDraw = 0; - - switch (mode) - { - //--------------------------------------------------// - // 4bit texture load .. - case 0: - if(GlobalTextIL) - { - unsigned int TXV,TXU,n_xi,n_yi; - - wSRCPtr=psxVuw+palstart; - for(row=0;row<16;row++) - *px++=LPTCOL(*wSRCPtr++); - - column=g_y2-ldy; - for(TXV=g_y1;TXV<=column;TXV++) - { - ldx=ldxo; - for(TXU=g_x1;TXU<=g_x2-ldxo;TXU++) - { - n_xi = ( ( TXU >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c ); - n_yi = ( TXV & ~0xf ) + ( ( TXU >> 4 ) & 0xf ); - - s=*(pa+((*( psxVuw + ((GlobalTextAddrY + n_yi)*1024) + GlobalTextAddrX + n_xi ) >> ( ( TXU & 0x03 ) << 2 ) ) & 0x0f )); - *ta++=s; - - if(ldx) {*ta++=s;ldx--;} - } - - if(ldy) - {ldy--; - for(TXU=g_x1;TXU<=g_x2;TXU++,ta++) - *ta=*(ta-(g_x2-g_x1)); - } - } - - DefineTextureWnd(); - - break; - } - - - start=((pageid-16*pmult)*128)+256*2048*pmult; - - // convert CLUT to 32bits .. and then use THAT as a lookup table - - wSRCPtr=psxVuw+palstart; - for(row=0;row<16;row++) - *px++=LPTCOL(*wSRCPtr++); - - sxm=g_x1&1;sxh=g_x1>>1; - if(sxm) j=g_x1+1; else j=g_x1; - cSRCPtr = psxVub + start + (2048*g_y1) + sxh; - for(column=g_y1;column<=g_y2;column++) - { - cOSRCPtr=cSRCPtr;ldx=ldxo; - if(sxm) *ta++=*(pa+((*cSRCPtr++ >> 4) & 0xF)); - - for(row=j;row<=g_x2-ldxo;row++) - { - s=*(pa+(*cSRCPtr & 0xF)); - *ta++=s; - if(ldx) {*ta++=s;ldx--;} - row++; - if(row<=g_x2-ldxo) - { - s=*(pa+((*cSRCPtr >> 4) & 0xF)); - *ta++=s; - if(ldx) {*ta++=s;ldx--;} - } - cSRCPtr++; - } - - if(ldy && column&1) - {ldy--;cSRCPtr = cOSRCPtr;} - else cSRCPtr = psxVub + start + (2048*(column+1)) + sxh; - } - - DefineTextureWnd(); - break; - //--------------------------------------------------// - // 8bit texture load .. - case 1: - if(GlobalTextIL) - { - unsigned int TXV,TXU,n_xi,n_yi; - - wSRCPtr=psxVuw+palstart; - for(row=0;row<256;row++) - *px++=LPTCOL(*wSRCPtr++); - - column=g_y2-ldy; - for(TXV=g_y1;TXV<=column;TXV++) - { - ldx=ldxo; - for(TXU=g_x1;TXU<=g_x2-ldxo;TXU++) - { - n_xi = ( ( TXU >> 1 ) & ~0x78 ) + ( ( TXU << 2 ) & 0x40 ) + ( ( TXV << 3 ) & 0x38 ); - n_yi = ( TXV & ~0x7 ) + ( ( TXU >> 5 ) & 0x7 ); - - s=*(pa+((*( psxVuw + ((GlobalTextAddrY + n_yi)*1024) + GlobalTextAddrX + n_xi ) >> ( ( TXU & 0x01 ) << 3 ) ) & 0xff)); - - *ta++=s; - if(ldx) {*ta++=s;ldx--;} - } - - if(ldy) - {ldy--; - for(TXU=g_x1;TXU<=g_x2;TXU++,ta++) - *ta=*(ta-(g_x2-g_x1)); - } - - } - - DefineTextureWnd(); - - break; - } - - start=((pageid-16*pmult)*128)+256*2048*pmult; - - // not using a lookup table here... speeds up smaller texture areas - cSRCPtr = psxVub + start + (2048*g_y1) + g_x1; - LineOffset = 2048 - (g_x2-g_x1+1) +ldxo; - - for(column=g_y1;column<=g_y2;column++) - { - cOSRCPtr=cSRCPtr;ldx=ldxo; - for(row=g_x1;row<=g_x2-ldxo;row++) - { - s=LPTCOL(psxVuw[palstart+ *cSRCPtr++]); - *ta++=s; - if(ldx) {*ta++=s;ldx--;} - } - if(ldy && column&1) {ldy--;cSRCPtr=cOSRCPtr;} - else cSRCPtr+=LineOffset; - } - - DefineTextureWnd(); - break; - //--------------------------------------------------// - // 16bit texture load .. - case 2: - start=((pageid-16*pmult)*64)+256*1024*pmult; - wSRCPtr = psxVuw + start + (1024*g_y1) + g_x1; - LineOffset = 1024 - (g_x2-g_x1+1) +ldxo; - - for(column=g_y1;column<=g_y2;column++) - { - wOSRCPtr=wSRCPtr;ldx=ldxo; - for(row=g_x1;row<=g_x2-ldxo;row++) - { - s=LPTCOL(*wSRCPtr++); - *ta++=s; - if(ldx) {*ta++=s;ldx--;} - } - if(ldy && column&1) {ldy--;wSRCPtr=wOSRCPtr;} - else wSRCPtr+=LineOffset; - } - - DefineTextureWnd(); - break; - //--------------------------------------------------// - // others are not possible ! - } -} - -//////////////////////////////////////////////////////////////////////// -// tex window: load stretched -//////////////////////////////////////////////////////////////////////// - -static void LoadStretchWndTexturePage(int pageid, int mode, short cx, short cy) -{ - uint32_t start,row,column,j,sxh,sxm,ldx,ldy,ldxo,s; - unsigned int palstart; - uint32_t *px,*pa,*ta; - unsigned char *cSRCPtr,*cOSRCPtr; - unsigned short *wSRCPtr,*wOSRCPtr; - uint32_t LineOffset; - int pmult = pageid / 16; - uint32_t (*LTCOL)(uint32_t); - - LTCOL = TCF[DrawSemiTrans]; - - ldxo=TWin.Position.x1-TWin.OPosition.x1; - ldy =TWin.Position.y1-TWin.OPosition.y1; - - pa = px = (uint32_t *)ubPaletteBuffer; - ta = (uint32_t *)texturepart; - palstart = cx + (cy * 1024); - - ubOpaqueDraw = 0; - - switch (mode) - { - //--------------------------------------------------// - // 4bit texture load .. - case 0: - //------------------- ZN STUFF - - if(GlobalTextIL) - { - unsigned int TXV,TXU,n_xi,n_yi; - - wSRCPtr=psxVuw+palstart; - - row=4;do - { - *px =LTCOL(*wSRCPtr); - *(px+1)=LTCOL(*(wSRCPtr+1)); - *(px+2)=LTCOL(*(wSRCPtr+2)); - *(px+3)=LTCOL(*(wSRCPtr+3)); - row--;px+=4;wSRCPtr+=4; - } - while (row); - - column=g_y2-ldy; - for(TXV=g_y1;TXV<=column;TXV++) - { - ldx=ldxo; - for(TXU=g_x1;TXU<=g_x2-ldxo;TXU++) - { - n_xi = ( ( TXU >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c ); - n_yi = ( TXV & ~0xf ) + ( ( TXU >> 4 ) & 0xf ); - - s=*(pa+((*( psxVuw + ((GlobalTextAddrY + n_yi)*1024) + GlobalTextAddrX + n_xi ) >> ( ( TXU & 0x03 ) << 2 ) ) & 0x0f )); - *ta++=s; - - if(ldx) {*ta++=s;ldx--;} - } - - if(ldy) - {ldy--; - for(TXU=g_x1;TXU<=g_x2;TXU++,ta++) - *ta=*(ta-(g_x2-g_x1)); - } - } - - DefineTextureWnd(); - - break; - } - - //------------------- - - start=((pageid-16*pmult)*128)+256*2048*pmult; - // convert CLUT to 32bits .. and then use THAT as a lookup table - - wSRCPtr=psxVuw+palstart; - for(row=0;row<16;row++) - *px++=LTCOL(*wSRCPtr++); - - sxm=g_x1&1;sxh=g_x1>>1; - if(sxm) j=g_x1+1; else j=g_x1; - cSRCPtr = psxVub + start + (2048*g_y1) + sxh; - for(column=g_y1;column<=g_y2;column++) - { - cOSRCPtr=cSRCPtr;ldx=ldxo; - if(sxm) *ta++=*(pa+((*cSRCPtr++ >> 4) & 0xF)); - - for(row=j;row<=g_x2-ldxo;row++) - { - s=*(pa+(*cSRCPtr & 0xF)); - *ta++=s; - if(ldx) {*ta++=s;ldx--;} - row++; - if(row<=g_x2-ldxo) - { - s=*(pa+((*cSRCPtr >> 4) & 0xF)); - *ta++=s; - if(ldx) {*ta++=s;ldx--;} - } - cSRCPtr++; - } - if(ldy && column&1) - {ldy--;cSRCPtr = cOSRCPtr;} - else cSRCPtr = psxVub + start + (2048*(column+1)) + sxh; - } - - DefineTextureWnd(); - break; - //--------------------------------------------------// - // 8bit texture load .. - case 1: - //------------ ZN STUFF - if(GlobalTextIL) - { - unsigned int TXV,TXU,n_xi,n_yi; - - wSRCPtr=psxVuw+palstart; - - row=64;do - { - *px =LTCOL(*wSRCPtr); - *(px+1)=LTCOL(*(wSRCPtr+1)); - *(px+2)=LTCOL(*(wSRCPtr+2)); - *(px+3)=LTCOL(*(wSRCPtr+3)); - row--;px+=4;wSRCPtr+=4; - } - while (row); - - column=g_y2-ldy; - for(TXV=g_y1;TXV<=column;TXV++) - { - ldx=ldxo; - for(TXU=g_x1;TXU<=g_x2-ldxo;TXU++) - { - n_xi = ( ( TXU >> 1 ) & ~0x78 ) + ( ( TXU << 2 ) & 0x40 ) + ( ( TXV << 3 ) & 0x38 ); - n_yi = ( TXV & ~0x7 ) + ( ( TXU >> 5 ) & 0x7 ); - - s=*(pa+((*( psxVuw + ((GlobalTextAddrY + n_yi)*1024) + GlobalTextAddrX + n_xi ) >> ( ( TXU & 0x01 ) << 3 ) ) & 0xff)); - *ta++=s; - if(ldx) {*ta++=s;ldx--;} - } - - if(ldy) - {ldy--; - for(TXU=g_x1;TXU<=g_x2;TXU++,ta++) - *ta=*(ta-(g_x2-g_x1)); - } - - } - - DefineTextureWnd(); - - break; - } - //------------ - - start=((pageid-16*pmult)*128)+256*2048*pmult; - - // not using a lookup table here... speeds up smaller texture areas - cSRCPtr = psxVub + start + (2048*g_y1) + g_x1; - LineOffset = 2048 - (g_x2-g_x1+1) +ldxo; - - for(column=g_y1;column<=g_y2;column++) - { - cOSRCPtr=cSRCPtr;ldx=ldxo; - for(row=g_x1;row<=g_x2-ldxo;row++) - { - s=LTCOL(psxVuw[palstart+ *cSRCPtr++]); - *ta++=s; - if(ldx) {*ta++=s;ldx--;} - } - if(ldy && column&1) {ldy--;cSRCPtr=cOSRCPtr;} - else cSRCPtr+=LineOffset; - } - - DefineTextureWnd(); - break; - //--------------------------------------------------// - // 16bit texture load .. - case 2: - start=((pageid-16*pmult)*64)+256*1024*pmult; - - wSRCPtr = psxVuw + start + (1024*g_y1) + g_x1; - LineOffset = 1024 - (g_x2-g_x1+1) +ldxo; - - for(column=g_y1;column<=g_y2;column++) - { - wOSRCPtr=wSRCPtr;ldx=ldxo; - for(row=g_x1;row<=g_x2-ldxo;row++) - { - s=LTCOL(*wSRCPtr++); - *ta++=s; - if(ldx) {*ta++=s;ldx--;} - } - if(ldy && column&1) {ldy--;wSRCPtr=wOSRCPtr;} - else wSRCPtr+=LineOffset; - } - - DefineTextureWnd(); - break; - //--------------------------------------------------// - // others are not possible ! - } -} - -//////////////////////////////////////////////////////////////////////// -// tex window: load packed simple -//////////////////////////////////////////////////////////////////////// - -static void LoadPackedWndTexturePage(int pageid, int mode, short cx, short cy) -{ - uint32_t start,row,column,j,sxh,sxm; - unsigned int palstart; - unsigned short *px,*pa,*ta; - unsigned char *cSRCPtr; - unsigned short *wSRCPtr; - uint32_t LineOffset; - int pmult=pageid/16; - unsigned short (*LPTCOL)(unsigned short); - - LPTCOL=PTCF[DrawSemiTrans]; - - pa=px=(unsigned short *)ubPaletteBuffer; - ta=(unsigned short *)texturepart; - palstart=cx+(cy*1024); - - ubOpaqueDraw=0; - - switch(mode) - { - //--------------------------------------------------// - // 4bit texture load .. - case 0: - if(GlobalTextIL) - { - unsigned int TXV,TXU,n_xi,n_yi; - - wSRCPtr=psxVuw+palstart; - for(row=0;row<16;row++) - *px++=LPTCOL(*wSRCPtr++); - - for(TXV=g_y1;TXV<=g_y2;TXV++) - { - for(TXU=g_x1;TXU<=g_x2;TXU++) - { - n_xi = ( ( TXU >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c ); - n_yi = ( TXV & ~0xf ) + ( ( TXU >> 4 ) & 0xf ); - - *ta++=*(pa+((*( psxVuw + ((GlobalTextAddrY + n_yi)*1024) + GlobalTextAddrX + n_xi ) >> ( ( TXU & 0x03 ) << 2 ) ) & 0x0f )); - } - } - - DefineTextureWnd(); - - break; - } - - start=((pageid-16*pmult)*128)+256*2048*pmult; - - // convert CLUT to 32bits .. and then use THAT as a lookup table - - wSRCPtr=psxVuw+palstart; - for(row=0;row<16;row++) - *px++=LPTCOL(*wSRCPtr++); - - sxm=g_x1&1;sxh=g_x1>>1; - if(sxm) j=g_x1+1; else j=g_x1; - cSRCPtr = psxVub + start + (2048*g_y1) + sxh; - for(column=g_y1;column<=g_y2;column++) - { - cSRCPtr = psxVub + start + (2048*column) + sxh; - - if(sxm) *ta++=*(pa+((*cSRCPtr++ >> 4) & 0xF)); - - for(row=j;row<=g_x2;row++) - { - *ta++=*(pa+(*cSRCPtr & 0xF)); row++; - if(row<=g_x2) *ta++=*(pa+((*cSRCPtr >> 4) & 0xF)); - cSRCPtr++; - } - } - - DefineTextureWnd(); - break; - //--------------------------------------------------// - // 8bit texture load .. - case 1: - if(GlobalTextIL) - { - unsigned int TXV,TXU,n_xi,n_yi; - - wSRCPtr=psxVuw+palstart; - for(row=0;row<256;row++) - *px++=LPTCOL(*wSRCPtr++); - - for(TXV=g_y1;TXV<=g_y2;TXV++) - { - for(TXU=g_x1;TXU<=g_x2;TXU++) - { - n_xi = ( ( TXU >> 1 ) & ~0x78 ) + ( ( TXU << 2 ) & 0x40 ) + ( ( TXV << 3 ) & 0x38 ); - n_yi = ( TXV & ~0x7 ) + ( ( TXU >> 5 ) & 0x7 ); - - *ta++=*(pa+((*( psxVuw + ((GlobalTextAddrY + n_yi)*1024) + GlobalTextAddrX + n_xi ) >> ( ( TXU & 0x01 ) << 3 ) ) & 0xff)); - } - } - - DefineTextureWnd(); - - break; - } - - start=((pageid-16*pmult)*128)+256*2048*pmult; - - // not using a lookup table here... speeds up smaller texture areas - cSRCPtr = psxVub + start + (2048*g_y1) + g_x1; - LineOffset = 2048 - (g_x2-g_x1+1); - - for(column=g_y1;column<=g_y2;column++) - { - for(row=g_x1;row<=g_x2;row++) - *ta++=LPTCOL(psxVuw[palstart+ *cSRCPtr++]); - cSRCPtr+=LineOffset; - } - - DefineTextureWnd(); - break; - //--------------------------------------------------// - // 16bit texture load .. - case 2: - start=((pageid-16*pmult)*64)+256*1024*pmult; - wSRCPtr = psxVuw + start + (1024*g_y1) + g_x1; - LineOffset = 1024 - (g_x2-g_x1+1); - - for(column=g_y1;column<=g_y2;column++) - { - for(row=g_x1;row<=g_x2;row++) - *ta++=LPTCOL(*wSRCPtr++); - wSRCPtr+=LineOffset; - } - - DefineTextureWnd(); - break; - //--------------------------------------------------// - // others are not possible ! - } -} - -//////////////////////////////////////////////////////////////////////// -// tex window: load simple -//////////////////////////////////////////////////////////////////////// - -static void LoadWndTexturePage(int pageid, int mode, short cx, short cy) -{ - uint32_t start,row,column,j,sxh,sxm; - unsigned int palstart; - uint32_t *px,*pa,*ta; - unsigned char *cSRCPtr; - unsigned short *wSRCPtr; - uint32_t LineOffset; - int pmult = pageid / 16; - uint32_t (*LTCOL)(uint32_t); - - LTCOL=TCF[DrawSemiTrans]; - - pa = px = (uint32_t *)ubPaletteBuffer; - ta = (uint32_t *)texturepart; - palstart = cx + (cy * 1024); - - ubOpaqueDraw = 0; - - switch (mode) - { - //--------------------------------------------------// - // 4bit texture load .. - case 0: - if(GlobalTextIL) - { - unsigned int TXV,TXU,n_xi,n_yi; - - wSRCPtr=psxVuw+palstart; - - row=4;do - { - *px =LTCOL(*wSRCPtr); - *(px+1)=LTCOL(*(wSRCPtr+1)); - *(px+2)=LTCOL(*(wSRCPtr+2)); - *(px+3)=LTCOL(*(wSRCPtr+3)); - row--;px+=4;wSRCPtr+=4; - } - while (row); - - for(TXV=g_y1;TXV<=g_y2;TXV++) - { - for(TXU=g_x1;TXU<=g_x2;TXU++) - { - n_xi = ( ( TXU >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c ); - n_yi = ( TXV & ~0xf ) + ( ( TXU >> 4 ) & 0xf ); - - *ta++=*(pa+((*( psxVuw + ((GlobalTextAddrY + n_yi)*1024) + GlobalTextAddrX + n_xi ) >> ( ( TXU & 0x03 ) << 2 ) ) & 0x0f )); - } - } - - DefineTextureWnd(); - - break; - } - - start=((pageid-16*pmult)*128)+256*2048*pmult; - - // convert CLUT to 32bits .. and then use THAT as a lookup table - - wSRCPtr=psxVuw+palstart; - for(row=0;row<16;row++) - *px++=LTCOL(*wSRCPtr++); - - sxm=g_x1&1;sxh=g_x1>>1; - if(sxm) j=g_x1+1; else j=g_x1; - cSRCPtr = psxVub + start + (2048*g_y1) + sxh; - for(column=g_y1;column<=g_y2;column++) - { - cSRCPtr = psxVub + start + (2048*column) + sxh; - - if(sxm) *ta++=*(pa+((*cSRCPtr++ >> 4) & 0xF)); - - for(row=j;row<=g_x2;row++) - { - *ta++=*(pa+(*cSRCPtr & 0xF)); row++; - if(row<=g_x2) *ta++=*(pa+((*cSRCPtr >> 4) & 0xF)); - cSRCPtr++; - } - } - - DefineTextureWnd(); - break; - //--------------------------------------------------// - // 8bit texture load .. - case 1: - if(GlobalTextIL) - { - unsigned int TXV,TXU,n_xi,n_yi; - - wSRCPtr=psxVuw+palstart; - - row=64;do - { - *px =LTCOL(*wSRCPtr); - *(px+1)=LTCOL(*(wSRCPtr+1)); - *(px+2)=LTCOL(*(wSRCPtr+2)); - *(px+3)=LTCOL(*(wSRCPtr+3)); - row--;px+=4;wSRCPtr+=4; - } - while (row); - - for(TXV=g_y1;TXV<=g_y2;TXV++) - { - for(TXU=g_x1;TXU<=g_x2;TXU++) - { - n_xi = ( ( TXU >> 1 ) & ~0x78 ) + ( ( TXU << 2 ) & 0x40 ) + ( ( TXV << 3 ) & 0x38 ); - n_yi = ( TXV & ~0x7 ) + ( ( TXU >> 5 ) & 0x7 ); - - *ta++=*(pa+((*( psxVuw + ((GlobalTextAddrY + n_yi)*1024) + GlobalTextAddrX + n_xi ) >> ( ( TXU & 0x01 ) << 3 ) ) & 0xff)); - } - } - - DefineTextureWnd(); - - break; - } - - start=((pageid-16*pmult)*128)+256*2048*pmult; - - // not using a lookup table here... speeds up smaller texture areas - cSRCPtr = psxVub + start + (2048*g_y1) + g_x1; - LineOffset = 2048 - (g_x2-g_x1+1); - - for(column=g_y1;column<=g_y2;column++) - { - for(row=g_x1;row<=g_x2;row++) - *ta++=LTCOL(psxVuw[palstart+ *cSRCPtr++]); - cSRCPtr+=LineOffset; - } - - DefineTextureWnd(); - break; - //--------------------------------------------------// - // 16bit texture load .. - case 2: - start=((pageid-16*pmult)*64)+256*1024*pmult; - - wSRCPtr = psxVuw + start + (1024*g_y1) + g_x1; - LineOffset = 1024 - (g_x2-g_x1+1); - - for(column=g_y1;column<=g_y2;column++) - { - for(row=g_x1;row<=g_x2;row++) - *ta++=LTCOL(*wSRCPtr++); - wSRCPtr+=LineOffset; - } - - DefineTextureWnd(); - break; - //--------------------------------------------------// - // others are not possible ! - } -} - -//////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////// - -static void UploadTexWndPal(int mode,short cx,short cy) -{ - unsigned int i,iSize; - unsigned short *wSrcPtr; - uint32_t *ta = (uint32_t *)texturepart; - - wSrcPtr = psxVuw + cx + (cy * 1024); - if (mode == 0) i = 4; else i = 64; - iSize = i << 2; - ubOpaqueDraw = 0; - - do - { - *ta =PALCOL(*wSrcPtr); - *(ta+1)=PALCOL(*(wSrcPtr+1)); - *(ta+2)=PALCOL(*(wSrcPtr+2)); - *(ta+3)=PALCOL(*(wSrcPtr+3)); - ta+=4;wSrcPtr+=4;i--; - } - while(i); - - (*glColorTableEXTEx)(GL_TEXTURE_2D,GL_RGBA8,iSize, - GL_RGBA,GL_UNSIGNED_BYTE,texturepart); -} - -//////////////////////////////////////////////////////////////////////// - -static void DefinePalTextureWnd(void) -{ - if(gTexName==0) - glGenTextures(1, &gTexName); - - glBindTexture(GL_TEXTURE_2D, gTexName); - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); - - if(iFilterType && iFilterType<3 && iHiResTextures!=2) - { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - } - else - { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - } - - glTexImage2D(GL_TEXTURE_2D, 0,GL_COLOR_INDEX8_EXT, - TWin.Position.x1, - TWin.Position.y1, - 0, GL_COLOR_INDEX, GL_UNSIGNED_BYTE,texturepart); -} - -/////////////////////////////////////////////////////// - -static void LoadPalWndTexturePage(int pageid, int mode, short cx, short cy) -{ - uint32_t start,row,column,j,sxh,sxm; - unsigned char *ta; - unsigned char *cSRCPtr; - uint32_t LineOffset; - int pmult = pageid / 16; - - ta = (unsigned char *)texturepart; - - switch (mode) - { - //--------------------------------------------------// - // 4bit texture load .. - case 0: - start=((pageid-16*pmult)*128)+256*2048*pmult; - - sxm=g_x1&1;sxh=g_x1>>1; - if(sxm) j=g_x1+1; else j=g_x1; - cSRCPtr = psxVub + start + (2048*g_y1) + sxh; - for(column=g_y1;column<=g_y2;column++) - { - cSRCPtr = psxVub + start + (2048*column) + sxh; - - if(sxm) *ta++=((*cSRCPtr++ >> 4) & 0xF); - - for(row=j;row<=g_x2;row++) - { - *ta++=(*cSRCPtr & 0xF); row++; - if(row<=g_x2) *ta++=((*cSRCPtr >> 4) & 0xF); - cSRCPtr++; - } - } - - DefinePalTextureWnd(); - break; - //--------------------------------------------------// - // 8bit texture load .. - case 1: - start=((pageid-16*pmult)*128)+256*2048*pmult; - - // not using a lookup table here... speeds up smaller texture areas - cSRCPtr = psxVub + start + (2048*g_y1) + g_x1; - LineOffset = 2048 - (g_x2-g_x1+1); - - for(column=g_y1;column<=g_y2;column++) - { - for(row=g_x1;row<=g_x2;row++) - *ta++=*cSRCPtr++; - cSRCPtr+=LineOffset; - } - - DefinePalTextureWnd(); - break; - } - UploadTexWndPal(mode,cx,cy); -} - -//////////////////////////////////////////////////////////////////////// - -static void LoadStretchPalWndTexturePage(int pageid, int mode, short cx, short cy) -{ - uint32_t start,row,column,j,sxh,sxm,ldx,ldy,ldxo; - unsigned char *ta,s; - unsigned char *cSRCPtr,*cOSRCPtr; - uint32_t LineOffset; - int pmult = pageid / 16; - - ldxo = TWin.Position.x1-TWin.OPosition.x1; - ldy = TWin.Position.y1-TWin.OPosition.y1; - - ta = (unsigned char *)texturepart; - - switch (mode) - { - //--------------------------------------------------// - // 4bit texture load .. - case 0: - start=((pageid-16*pmult)*128)+256*2048*pmult; - - sxm=g_x1&1;sxh=g_x1>>1; - if(sxm) j=g_x1+1; else j=g_x1; - cSRCPtr = psxVub + start + (2048*g_y1) + sxh; - for(column=g_y1;column<=g_y2;column++) - { - cOSRCPtr=cSRCPtr;ldx=ldxo; - if(sxm) *ta++=((*cSRCPtr++ >> 4) & 0xF); - - for(row=j;row<=g_x2-ldxo;row++) - { - s=(*cSRCPtr & 0xF); - *ta++=s; - if(ldx) {*ta++=s;ldx--;} - row++; - if(row<=g_x2-ldxo) - { - s=((*cSRCPtr >> 4) & 0xF); - *ta++=s; - if(ldx) {*ta++=s;ldx--;} - } - cSRCPtr++; - } - if(ldy && column&1) - {ldy--;cSRCPtr = cOSRCPtr;} - else cSRCPtr = psxVub + start + (2048*(column+1)) + sxh; - } - - DefinePalTextureWnd(); - break; - //--------------------------------------------------// - // 8bit texture load .. - case 1: - start=((pageid-16*pmult)*128)+256*2048*pmult; - - cSRCPtr = psxVub + start + (2048*g_y1) + g_x1; - LineOffset = 2048 - (g_x2-g_x1+1) +ldxo; - - for(column=g_y1;column<=g_y2;column++) - { - cOSRCPtr=cSRCPtr;ldx=ldxo; - for(row=g_x1;row<=g_x2-ldxo;row++) - { - s=*cSRCPtr++; - *ta++=s; - if(ldx) {*ta++=s;ldx--;} - } - if(ldy && column&1) {ldy--;cSRCPtr=cOSRCPtr;} - else cSRCPtr+=LineOffset; - } - - DefinePalTextureWnd(); - break; - } - UploadTexWndPal(mode,cx,cy); -} - -//////////////////////////////////////////////////////////////////////// -// tex window: main selecting, cache handler included -//////////////////////////////////////////////////////////////////////// - -GLuint LoadTextureWnd(int pageid, int TextureMode, uint32_t GivenClutId) -{ - textureWndCacheEntry *ts, *tsx = NULL; - int i; - short cx,cy; - EXLong npos; - - npos.c[3] = TWin.Position.x0; - npos.c[2] = TWin.OPosition.x1; - npos.c[1] = TWin.Position.y0; - npos.c[0] = TWin.OPosition.y1; - - g_x1 = TWin.Position.x0; g_x2 = g_x1 + TWin.Position.x1 - 1; - g_y1 = TWin.Position.y0; g_y2 = g_y1 + TWin.Position.y1 - 1; - - if (TextureMode == 2) { GivenClutId = 0; cx = cy = 0; } - else - { - cx = ((GivenClutId << 4) & 0x3F0); - cy = ((GivenClutId >> 6) & CLUTYMASK); - GivenClutId = (GivenClutId & CLUTMASK) | (DrawSemiTrans << 30); - - // palette check sum - { - uint32_t l = 0,row; - uint32_t *lSRCPtr = (uint32_t *)(psxVuw + cx + (cy * 1024)); - if(TextureMode==1) for(row=1;row<129;row++) l+=((*lSRCPtr++)-1)*row; - else for(row=1;row<9;row++) l+=((*lSRCPtr++)-1)<<row; - l=(l+HIWORD(l))&0x3fffL; - GivenClutId|=(l<<16); - } - - } - - ts=wcWndtexStore; - - for(i=0;i<iMaxTexWnds;i++,ts++) - { - if(ts->used) - { - if(ts->pos.l==npos.l && - ts->pageid==pageid && - ts->textureMode==TextureMode) - { - if(ts->ClutID==GivenClutId) - { - ubOpaqueDraw=ts->Opaque; - return ts->texname; - } - else if(glColorTableEXTEx && TextureMode!=2) - { - ts->ClutID=GivenClutId; - if(ts->texname!=gTexName) - { - gTexName=ts->texname; - glBindTexture(GL_TEXTURE_2D, gTexName); - } - UploadTexWndPal(TextureMode,cx,cy); - ts->Opaque=ubOpaqueDraw; - return gTexName; - } - } - } - else tsx=ts; - } - - if(!tsx) - { - if(iMaxTexWnds==iTexWndLimit) - { - tsx=wcWndtexStore+iTexWndTurn; - iTexWndTurn++; - if(iTexWndTurn==iTexWndLimit) iTexWndTurn=0; - } - else - { - tsx=wcWndtexStore+iMaxTexWnds; - iMaxTexWnds++; - } - } - - gTexName=tsx->texname; - - if(TWin.OPosition.y1==TWin.Position.y1 && - TWin.OPosition.x1==TWin.Position.x1) - { - if(glColorTableEXTEx && TextureMode!=2) - LoadPalWndTexturePage(pageid,TextureMode,cx,cy); - else - if(bGLExt) - LoadPackedWndTexturePage(pageid,TextureMode,cx,cy); - else - LoadWndTexturePage(pageid,TextureMode,cx,cy); - } - else - { - if(glColorTableEXTEx && TextureMode!=2) - LoadStretchPalWndTexturePage(pageid,TextureMode,cx,cy); - else - if(bGLExt) - LoadStretchPackedWndTexturePage(pageid,TextureMode,cx,cy); - else - LoadStretchWndTexturePage(pageid,TextureMode,cx,cy); - } - - tsx->Opaque=ubOpaqueDraw; - tsx->pos.l=npos.l; - tsx->ClutID=GivenClutId; - tsx->pageid=pageid; - tsx->textureMode=TextureMode; - tsx->texname=gTexName; - tsx->used=1; - - return gTexName; -} - -///////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -// movie texture: define -//////////////////////////////////////////////////////////////////////// - -static void DefinePackedTextureMovie(void) -{ - if(gTexMovieName==0) - { - glGenTextures(1, &gTexMovieName); - gTexName=gTexMovieName; - glBindTexture(GL_TEXTURE_2D, gTexName); - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, iClampType); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, iClampType); - - if(!bUseFastMdec) - { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - } - else - { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - } - - glTexImage2D(GL_TEXTURE_2D, 0, //giWantedRGBA, - GL_RGB5_A1, - 256, 256, 0, GL_RGBA, giWantedTYPE, texturepart); - } - else - { - gTexName=gTexMovieName;glBindTexture(GL_TEXTURE_2D, gTexName); - } - - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, - (xrMovieArea.x1-xrMovieArea.x0), - (xrMovieArea.y1-xrMovieArea.y0), - GL_RGBA, - GL_UNSIGNED_SHORT_5_5_5_1_EXT, - texturepart); -} - -//////////////////////////////////////////////////////////////////////// - -static void DefineTextureMovie(void) -{ - if(gTexMovieName==0) - { - glGenTextures(1, &gTexMovieName); - gTexName=gTexMovieName; - glBindTexture(GL_TEXTURE_2D, gTexName); - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, iClampType); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, iClampType); - - if(!bUseFastMdec) - { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - } - else - { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - } - - glTexImage2D(GL_TEXTURE_2D, 0, giWantedRGBA, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, texturepart); - } - else - { - gTexName=gTexMovieName;glBindTexture(GL_TEXTURE_2D, gTexName); - } - - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, - (xrMovieArea.x1-xrMovieArea.x0), - (xrMovieArea.y1-xrMovieArea.y0), - GL_RGBA, GL_UNSIGNED_BYTE, texturepart); -} - -//////////////////////////////////////////////////////////////////////// -// movie texture: load -//////////////////////////////////////////////////////////////////////// - -#define MRED(x) ((x>>3) & 0x1f) -#define MGREEN(x) ((x>>6) & 0x3e0) -#define MBLUE(x) ((x>>9) & 0x7c00) - -#define XMGREEN(x) ((x>>5) & 0x07c0) -#define XMRED(x) ((x<<8) & 0xf800) -#define XMBLUE(x) ((x>>18) & 0x003e) - -//////////////////////////////////////////////////////////////////////// -// movie texture: load -//////////////////////////////////////////////////////////////////////// - -unsigned char * LoadDirectMovieFast(void) -{ - int row,column; - unsigned int startxy; - - uint32_t *ta=(uint32_t *)texturepart; - - if(PSXDisplay.RGB24) - { - unsigned char * pD; - - startxy=((1024)*xrMovieArea.y0)+xrMovieArea.x0; - - for(column=xrMovieArea.y0;column<xrMovieArea.y1;column++,startxy+=1024) - { - pD=(unsigned char *)&psxVuw[startxy]; - for(row=xrMovieArea.x0;row<xrMovieArea.x1;row++) - { - *ta++=*((uint32_t *)pD)|0xff000000; - pD+=3; - } - } - } - else - { - uint32_t (*LTCOL)(uint32_t); - - LTCOL=XP8RGBA_0;//TCF[0]; - - ubOpaqueDraw=0; - - for(column=xrMovieArea.y0;column<xrMovieArea.y1;column++) - { - startxy=((1024)*column)+xrMovieArea.x0; - for(row=xrMovieArea.x0;row<xrMovieArea.x1;row++) - *ta++=LTCOL(psxVuw[startxy++]|0x8000); - } - } - - return texturepart; -} - -//////////////////////////////////////////////////////////////////////// - -static GLuint LoadTextureMovieFast(void) -{ - int row,column; - unsigned int start,startxy; - - if(bGLFastMovie) - { - if(PSXDisplay.RGB24) - { - unsigned char * pD; uint32_t lu1,lu2; - unsigned short * ta=(unsigned short *)texturepart; - short sx0=xrMovieArea.x1-1; - - start=0; - - startxy=((1024)*xrMovieArea.y0)+xrMovieArea.x0; - for(column=xrMovieArea.y0;column<xrMovieArea.y1;column++) - { - pD=(unsigned char *)&psxVuw[startxy]; - startxy+=1024; - - for(row=xrMovieArea.x0;row<sx0;row+=2) - { - lu1=*((uint32_t *)pD);pD+=3; - lu2=*((uint32_t *)pD);pD+=3; - - *((uint32_t *)ta)= - (XMBLUE(lu1)|XMGREEN(lu1)|XMRED(lu1)|1)| - ((XMBLUE(lu2)|XMGREEN(lu2)|XMRED(lu2)|1)<<16); - ta+=2; - } - if(row==sx0) - { - lu1=*((uint32_t *)pD); - *ta++=XMBLUE(lu1)|XMGREEN(lu1)|XMRED(lu1)|1; - } - } - } - else - { - unsigned short *ta=(unsigned short *)texturepart; - uint32_t lc; - short sx0=xrMovieArea.x1-1; - - for(column=xrMovieArea.y0;column<xrMovieArea.y1;column++) - { - startxy=((1024)*column)+xrMovieArea.x0; - for(row=xrMovieArea.x0;row<sx0;row+=2) - { - lc=*((uint32_t *)&psxVuw[startxy]); - *((uint32_t *)ta)= - ((lc&0x001f001f)<<11)|((lc&0x03e003e0)<<1)|((lc&0x7c007c00)>>9)|0x00010001; - ta+=2;startxy+=2; - } - if(row==sx0) *ta++=(psxVuw[startxy]<<1)|1; - } - } - DefinePackedTextureMovie(); - } - else - { - if(PSXDisplay.RGB24) - { - unsigned char *pD; - uint32_t *ta = (uint32_t *)texturepart; - - startxy=((1024)*xrMovieArea.y0)+xrMovieArea.x0; - - for(column=xrMovieArea.y0;column<xrMovieArea.y1;column++,startxy+=1024) - { - //startxy=((1024)*column)+xrMovieArea.x0; - pD = (unsigned char *)&psxVuw[startxy]; - for(row=xrMovieArea.x0;row<xrMovieArea.x1;row++) - { - *ta++=*((uint32_t *)pD)|0xff000000; - pD+=3; - } - } - } - else - { - uint32_t (*LTCOL)(uint32_t); - uint32_t *ta; - - LTCOL = XP8RGBA_0;//TCF[0]; - - ubOpaqueDraw = 0; - ta = (uint32_t *)texturepart; - - for (column = xrMovieArea.y0; column < xrMovieArea.y1; column++) - { - startxy = (1024 * column) + xrMovieArea.x0; - for (row = xrMovieArea.x0; row < xrMovieArea.x1; row++) - *ta++=LTCOL(psxVuw[startxy++]|0x8000); - } - } - DefineTextureMovie(); - } - return gTexName; -} - -//////////////////////////////////////////////////////////////////////// - -GLuint LoadTextureMovie(void) -{ - short row,column,dx; - unsigned int startxy; - BOOL b_X,b_Y; - - if(bUseFastMdec) return LoadTextureMovieFast(); - - b_X=FALSE;b_Y=FALSE; - - if((xrMovieArea.x1-xrMovieArea.x0)<255) b_X=TRUE; - if((xrMovieArea.y1-xrMovieArea.y0)<255) b_Y=TRUE; - - if(bGLFastMovie) - { - unsigned short c; - - if(PSXDisplay.RGB24) - { - unsigned char * pD; - uint32_t lu; - unsigned short * ta=(unsigned short *)texturepart; - - if(b_X) - { - for(column=xrMovieArea.y0;column<xrMovieArea.y1;column++) - { - startxy=((1024)*column)+xrMovieArea.x0; - pD=(unsigned char *)&psxVuw[startxy]; - for(row=xrMovieArea.x0;row<xrMovieArea.x1;row++) - { - lu=*((uint32_t *)pD);pD+=3; - *ta++=XMBLUE(lu)|XMGREEN(lu)|XMRED(lu)|1; - } - *ta=*(ta-1); - ta++; - } - if(b_Y) - { - dx=xrMovieArea.x1-xrMovieArea.x0+1; - for(row=xrMovieArea.x0;row<xrMovieArea.x1;row++,ta++) - *ta=*(ta-dx); - *ta=*(ta-1); - ta++; - } - } - else - { - for(column=xrMovieArea.y0;column<xrMovieArea.y1;column++) - { - startxy=((1024)*column)+xrMovieArea.x0; - pD=(unsigned char *)&psxVuw[startxy]; - for(row=xrMovieArea.x0;row<xrMovieArea.x1;row++) - { - lu=*((uint32_t *)pD);pD+=3; - *ta++=XMBLUE(lu)|XMGREEN(lu)|XMRED(lu)|1; - } - } - if(b_Y) - { - dx=xrMovieArea.x1-xrMovieArea.x0; - for(row=xrMovieArea.x0;row<xrMovieArea.x1;row++,ta++) - *ta=*(ta-dx); - } - } - } - else - { - unsigned short *ta; - - ubOpaqueDraw=0; - - ta=(unsigned short *)texturepart; - - if(b_X) - { - for(column=xrMovieArea.y0;column<xrMovieArea.y1;column++) - { - startxy=((1024)*column)+xrMovieArea.x0; - for(row=xrMovieArea.x0;row<xrMovieArea.x1;row++) - { - c=psxVuw[startxy++]; - *ta++=((c&0x1f)<<11)|((c&0x3e0)<<1)|((c&0x7c00)>>9)|1; - } - - *ta=*(ta-1); - ta++; - } - if(b_Y) - { - dx=xrMovieArea.x1-xrMovieArea.x0+1; - for(row=xrMovieArea.x0;row<xrMovieArea.x1;row++,ta++) - *ta=*(ta-dx); - *ta=*(ta-1); - ta++; - } - } - else - { - for(column=xrMovieArea.y0;column<xrMovieArea.y1;column++) - { - startxy=((1024)*column)+xrMovieArea.x0; - for(row=xrMovieArea.x0;row<xrMovieArea.x1;row++) - { - c=psxVuw[startxy++]; - *ta++=((c&0x1f)<<11)|((c&0x3e0)<<1)|((c&0x7c00)>>9)|1; - } - } - if(b_Y) - { - dx=xrMovieArea.x1-xrMovieArea.x0; - for(row=xrMovieArea.x0;row<xrMovieArea.x1;row++,ta++) - *ta=*(ta-dx); - } - } - } - xrMovieArea.x1+=b_X;xrMovieArea.y1+=b_Y; - DefinePackedTextureMovie(); - xrMovieArea.x1-=b_X;xrMovieArea.y1-=b_Y; - } - else - { - if(PSXDisplay.RGB24) - { - unsigned char * pD; - uint32_t * ta=(uint32_t *)texturepart; - - if(b_X) - { - for(column=xrMovieArea.y0;column<xrMovieArea.y1;column++) - { - startxy=((1024)*column)+xrMovieArea.x0; - pD=(unsigned char *)&psxVuw[startxy]; - for(row=xrMovieArea.x0;row<xrMovieArea.x1;row++) - { - *ta++=*((uint32_t *)pD)|0xff000000; - pD+=3; - } - *ta=*(ta-1); - ta++; - } - if(b_Y) - { - dx=xrMovieArea.x1-xrMovieArea.x0+1; - for(row=xrMovieArea.x0;row<xrMovieArea.x1;row++,ta++) - *ta=*(ta-dx); - *ta=*(ta-1); - ta++; - } - } - else - { - for(column=xrMovieArea.y0;column<xrMovieArea.y1;column++) - { - startxy=((1024)*column)+xrMovieArea.x0; - pD=(unsigned char *)&psxVuw[startxy]; - for(row=xrMovieArea.x0;row<xrMovieArea.x1;row++) - { - *ta++=*((uint32_t *)pD)|0xff000000; - pD+=3; - } - } - if(b_Y) - { - dx=xrMovieArea.x1-xrMovieArea.x0; - for(row=xrMovieArea.x0;row<xrMovieArea.x1;row++,ta++) - *ta=*(ta-dx); - } - } - } - else - { - uint32_t (*LTCOL)(uint32_t); - uint32_t *ta; - - LTCOL=XP8RGBA_0;//TCF[0]; - - ubOpaqueDraw=0; - ta=(uint32_t *)texturepart; - - if(b_X) - { - for(column=xrMovieArea.y0;column<xrMovieArea.y1;column++) - { - startxy=((1024)*column)+xrMovieArea.x0; - for(row=xrMovieArea.x0;row<xrMovieArea.x1;row++,ta++) - *ta=LTCOL(psxVuw[startxy++]|0x8000); - *ta=*(ta-1); - ta++; - } - - if(b_Y) - { - dx=xrMovieArea.x1-xrMovieArea.x0+1; - for(row=xrMovieArea.x0;row<xrMovieArea.x1;row++,ta++) - *ta=*(ta-dx); - *ta=*(ta-1); - ta++; - } - } - else - { - for(column=xrMovieArea.y0;column<xrMovieArea.y1;column++) - { - startxy=((1024)*column)+xrMovieArea.x0; - for(row=xrMovieArea.x0;row<xrMovieArea.x1;row++) - *ta++=LTCOL(psxVuw[startxy++]|0x8000); - } - - if(b_Y) - { - dx=xrMovieArea.x1-xrMovieArea.x0; - for(row=xrMovieArea.x0;row<xrMovieArea.x1;row++,ta++) - *ta=*(ta-dx); - } - } - } - - xrMovieArea.x1+=b_X;xrMovieArea.y1+=b_Y; - DefineTextureMovie(); - xrMovieArea.x1-=b_X;xrMovieArea.y1-=b_Y; - } - return gTexName; -} - -///////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////// - -static GLuint BlackFake15BitTexture(void) -{ - int pmult;short x1,x2,y1,y2; - - if(PSXDisplay.InterlacedTest) return 0; - - pmult=GlobalTexturePage/16; - x1=gl_ux[7]; - x2=gl_ux[6]-gl_ux[7]; - y1=gl_ux[5]; - y2=gl_ux[4]-gl_ux[5]; - - if(iSpriteTex) - { - if(x2<255) x2++; - if(y2<255) y2++; - } - - y1+=pmult*256; - x1+=((GlobalTexturePage-16*pmult)<<6); - - if( FastCheckAgainstFrontScreen(x1,y1,x2,y2) - || FastCheckAgainstScreen(x1,y1,x2,y2)) - { - if(!gTexFrameName) - { - glGenTextures(1, &gTexFrameName); - gTexName=gTexFrameName; - glBindTexture(GL_TEXTURE_2D, gTexName); - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, iClampType); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, iClampType); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - - if(bGLExt) - { - unsigned short s;unsigned short * ta; - - if(giWantedTYPE==GL_UNSIGNED_SHORT_4_4_4_4_EXT) - s=0x000f; - else s=0x0001; - - ta=(unsigned short *)texturepart; - for(y1=0;y1<=4;y1++) - for(x1=0;x1<=4;x1++) - *ta++=s; - } - else - { - uint32_t *ta=(uint32_t *)texturepart; - for(y1=0;y1<=4;y1++) - for(x1=0;x1<=4;x1++) - *ta++=0xff000000; - } - glTexImage2D(GL_TEXTURE_2D, 0, giWantedRGBA, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, texturepart); - } - else - { - gTexName=gTexFrameName; - glBindTexture(GL_TEXTURE_2D, gTexName); - } - - ubOpaqueDraw=0; - - return (GLuint)gTexName; - } - return 0; -} - -///////////////////////////////////////////////////////////////////////////// - -BOOL bFakeFrontBuffer=FALSE; -BOOL bIgnoreNextTile =FALSE; - -int iFTex=512; - -static GLuint Fake15BitTexture(void) -{ - int pmult;short x1,x2,y1,y2;int iYAdjust; - float ScaleX,ScaleY;RECT rSrc; - - if(iFrameTexType==1) return BlackFake15BitTexture(); - if(PSXDisplay.InterlacedTest) return 0; - - pmult=GlobalTexturePage/16; - x1=gl_ux[7]; - x2=gl_ux[6]-gl_ux[7]; - y1=gl_ux[5]; - y2=gl_ux[4]-gl_ux[5]; - - y1+=pmult*256; - x1+=((GlobalTexturePage-16*pmult)<<6); - - if(iFrameTexType==3) - { - if(iFrameReadType==4) return 0; - - if(!FastCheckAgainstFrontScreen(x1,y1,x2,y2) && - !FastCheckAgainstScreen(x1,y1,x2,y2)) - return 0; - - if(bFakeFrontBuffer) bIgnoreNextTile=TRUE; - CheckVRamReadEx(x1,y1,x1+x2,y1+y2); - return 0; - } - - ///////////////////////// - - if(FastCheckAgainstFrontScreen(x1,y1,x2,y2)) - { - x1-=PSXDisplay.DisplayPosition.x; - y1-=PSXDisplay.DisplayPosition.y; - } - else - if(FastCheckAgainstScreen(x1,y1,x2,y2)) - { - x1-=PreviousPSXDisplay.DisplayPosition.x; - y1-=PreviousPSXDisplay.DisplayPosition.y; - } - else return 0; - - bDrawMultiPass = FALSE; - - if(!gTexFrameName) - { - char * p; - - if(iResX>1280 || iResY>1024) iFTex=2048; - else - if(iResX>640 || iResY>480) iFTex=1024; - else iFTex=512; - - glGenTextures(1, &gTexFrameName); - gTexName=gTexFrameName; - glBindTexture(GL_TEXTURE_2D, gTexName); - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, iClampType); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, iClampType); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - - p=(char *)malloc(iFTex*iFTex*4); - memset(p,0,iFTex*iFTex*4); - glTexImage2D(GL_TEXTURE_2D, 0, 3, iFTex, iFTex, 0, GL_RGB, GL_UNSIGNED_BYTE, p); - free(p); - - glGetError(); - } - else - { - gTexName=gTexFrameName; - glBindTexture(GL_TEXTURE_2D, gTexName); - } - - x1+=PreviousPSXDisplay.Range.x0; - y1+=PreviousPSXDisplay.Range.y0; - - if(PSXDisplay.DisplayMode.x) - ScaleX=(float)rRatioRect.right/(float)PSXDisplay.DisplayMode.x; - else ScaleX=1.0f; - if(PSXDisplay.DisplayMode.y) - ScaleY=(float)rRatioRect.bottom/(float)PSXDisplay.DisplayMode.y; - else ScaleY=1.0f; - - rSrc.left =max(x1*ScaleX,0); - rSrc.right =min((x1+x2)*ScaleX+0.99f,iResX-1); - rSrc.top =max(y1*ScaleY,0); - rSrc.bottom=min((y1+y2)*ScaleY+0.99f,iResY-1); - - iYAdjust=(y1+y2)-PSXDisplay.DisplayMode.y; - if(iYAdjust>0) - iYAdjust=(int)((float)iYAdjust*ScaleY)+1; - else iYAdjust=0; - - gl_vy[0]=255-gl_vy[0]; - gl_vy[1]=255-gl_vy[1]; - gl_vy[2]=255-gl_vy[2]; - gl_vy[3]=255-gl_vy[3]; - - y1=min(gl_vy[0],min(gl_vy[1],min(gl_vy[2],gl_vy[3]))); - - gl_vy[0]-=y1; - gl_vy[1]-=y1; - gl_vy[2]-=y1; - gl_vy[3]-=y1; - gl_ux[0]-=gl_ux[7]; - gl_ux[1]-=gl_ux[7]; - gl_ux[2]-=gl_ux[7]; - gl_ux[3]-=gl_ux[7]; - - ScaleX*=256.0f/((float)(iFTex)); - ScaleY*=256.0f/((float)(iFTex)); - - y1=((float)gl_vy[0]*ScaleY); if(y1>255) y1=255; - gl_vy[0]=y1; - y1=((float)gl_vy[1]*ScaleY); if(y1>255) y1=255; - gl_vy[1]=y1; - y1=((float)gl_vy[2]*ScaleY); if(y1>255) y1=255; - gl_vy[2]=y1; - y1=((float)gl_vy[3]*ScaleY); if(y1>255) y1=255; - gl_vy[3]=y1; - - x1=((float)gl_ux[0]*ScaleX); if(x1>255) x1=255; - gl_ux[0]=x1; - x1=((float)gl_ux[1]*ScaleX); if(x1>255) x1=255; - gl_ux[1]=x1; - x1=((float)gl_ux[2]*ScaleX); if(x1>255) x1=255; - gl_ux[2]=x1; - x1=((float)gl_ux[3]*ScaleX); if(x1>255) x1=255; - gl_ux[3]=x1; - - x1=rSrc.right-rSrc.left; - if(x1<=0) x1=1; - if(x1>iFTex) x1=iFTex; - - y1=rSrc.bottom-rSrc.top; - if(y1<=0) y1=1; - if(y1+iYAdjust>iFTex) y1=iFTex-iYAdjust; - - if(bFakeFrontBuffer) glReadBuffer(GL_FRONT); - - glCopyTexSubImage2D( GL_TEXTURE_2D, 0, - 0, - iYAdjust, - rSrc.left+rRatioRect.left, - iResY-rSrc.bottom-rRatioRect.top, - x1,y1); - - if(glGetError()) - { - char * p=(char *)malloc(iFTex*iFTex*4); - memset(p,0,iFTex*iFTex*4); - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, iFTex, iFTex, - GL_RGB, GL_UNSIGNED_BYTE, p); - free(p); - } - - if(bFakeFrontBuffer) - {glReadBuffer(GL_BACK);bIgnoreNextTile=TRUE;} - - ubOpaqueDraw=0; - - if(iSpriteTex) - { - sprtW=gl_ux[1]-gl_ux[0]; - sprtH=-(gl_vy[0]-gl_vy[2]); - } - - return (GLuint)gTexName; -} - -///////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////// -// -// load texture part (unpacked) -// -///////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////// - -void LoadSubTexturePageSort(int pageid, int mode, short cx, short cy) -{ - uint32_t start,row,column,j,sxh,sxm; - unsigned int palstart; - uint32_t *px,*pa,*ta; - unsigned char *cSRCPtr; - unsigned short *wSRCPtr; - uint32_t LineOffset; - uint32_t x2a,xalign=0; - uint32_t x1=gl_ux[7]; - uint32_t x2=gl_ux[6]; - uint32_t y1=gl_ux[5]; - uint32_t y2=gl_ux[4]; - uint32_t dx=x2-x1+1; - uint32_t dy=y2-y1+1; - int pmult=pageid/16; - uint32_t (*LTCOL)(uint32_t); - unsigned int a,r,g,b,cnt,h; - uint32_t scol[8]; - - LTCOL=TCF[DrawSemiTrans]; - - pa=px=(uint32_t *)ubPaletteBuffer; - ta=(uint32_t *)texturepart; - palstart=cx+(cy<<10); - - ubOpaqueDraw=0; - - if(YTexS) {ta+=dx;if(XTexS) ta+=2;} - if(XTexS) {ta+=1;xalign=2;} - - switch(mode) - { - //--------------------------------------------------// - // 4bit texture load .. - case 0: - if(GlobalTextIL) - { - unsigned int TXV,TXU,n_xi,n_yi; - - wSRCPtr=psxVuw+palstart; - - row=4;do - { - *px =LTCOL(*wSRCPtr); - *(px+1)=LTCOL(*(wSRCPtr+1)); - *(px+2)=LTCOL(*(wSRCPtr+2)); - *(px+3)=LTCOL(*(wSRCPtr+3)); - row--;px+=4;wSRCPtr+=4; - } - while (row); - - for(TXV=y1;TXV<=y2;TXV++) - { - for(TXU=x1;TXU<=x2;TXU++) - { - n_xi = ( ( TXU >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c ); - n_yi = ( TXV & ~0xf ) + ( ( TXU >> 4 ) & 0xf ); - - *ta++=*(pa+((*( psxVuw + ((GlobalTextAddrY + n_yi)*1024) + GlobalTextAddrX + n_xi ) >> ( ( TXU & 0x03 ) << 2 ) ) & 0x0f )); - } - ta+=xalign; - } - break; - } - - start=((pageid-16*pmult)<<7)+524288*pmult; - // convert CLUT to 32bits .. and then use THAT as a lookup table - - wSRCPtr=psxVuw+palstart; - - row=4;do - { - *px =LTCOL(*wSRCPtr); - *(px+1)=LTCOL(*(wSRCPtr+1)); - *(px+2)=LTCOL(*(wSRCPtr+2)); - *(px+3)=LTCOL(*(wSRCPtr+3)); - row--;px+=4;wSRCPtr+=4; - } - while (row); - - x2a=x2?(x2-1):0;//if(x2) x2a=x2-1; else x2a=0; - sxm=x1&1;sxh=x1>>1; - j=sxm?(x1+1):x1;//if(sxm) j=x1+1; else j=x1; - for(column=y1;column<=y2;column++) - { - cSRCPtr = psxVub + start + (column<<11) + sxh; - - if(sxm) *ta++=*(pa+((*cSRCPtr++ >> 4) & 0xF)); - - for(row=j;row<x2a;row+=2) - { - *ta =*(pa+(*cSRCPtr & 0xF)); - *(ta+1)=*(pa+((*cSRCPtr >> 4) & 0xF)); - cSRCPtr++;ta+=2; - } - - if(row<=x2) - { - *ta++=*(pa+(*cSRCPtr & 0xF)); row++; - if(row<=x2) *ta++=*(pa+((*cSRCPtr >> 4) & 0xF)); - } - - ta+=xalign; - } - - break; - //--------------------------------------------------// - // 8bit texture load .. - case 1: - if(GlobalTextIL) - { - unsigned int TXV,TXU,n_xi,n_yi; - - wSRCPtr=psxVuw+palstart; - - row=64;do - { - *px =LTCOL(*wSRCPtr); - *(px+1)=LTCOL(*(wSRCPtr+1)); - *(px+2)=LTCOL(*(wSRCPtr+2)); - *(px+3)=LTCOL(*(wSRCPtr+3)); - row--;px+=4;wSRCPtr+=4; - } - while (row); - - for(TXV=y1;TXV<=y2;TXV++) - { - for(TXU=x1;TXU<=x2;TXU++) - { - n_xi = ( ( TXU >> 1 ) & ~0x78 ) + ( ( TXU << 2 ) & 0x40 ) + ( ( TXV << 3 ) & 0x38 ); - n_yi = ( TXV & ~0x7 ) + ( ( TXU >> 5 ) & 0x7 ); - - *ta++=*(pa+((*( psxVuw + ((GlobalTextAddrY + n_yi)*1024) + GlobalTextAddrX + n_xi ) >> ( ( TXU & 0x01 ) << 3 ) ) & 0xff)); - } - ta+=xalign; - } - - break; - } - - start=((pageid-16*pmult)<<7)+524288*pmult; - - cSRCPtr = psxVub + start + (y1<<11) + x1; - LineOffset = 2048 - dx; - - if(dy*dx>384) - { - wSRCPtr=psxVuw+palstart; - - row=64;do - { - *px =LTCOL(*wSRCPtr); - *(px+1)=LTCOL(*(wSRCPtr+1)); - *(px+2)=LTCOL(*(wSRCPtr+2)); - *(px+3)=LTCOL(*(wSRCPtr+3)); - row--;px+=4;wSRCPtr+=4; - } - while (row); - - column=dy;do - { - row=dx; - do {*ta++=*(pa+(*cSRCPtr++));row--;} while(row); - ta+=xalign; - cSRCPtr+=LineOffset;column--; - } - while(column); - } - else - { - wSRCPtr=psxVuw+palstart; - - column=dy;do - { - row=dx; - do {*ta++=LTCOL(*(wSRCPtr+*cSRCPtr++));row--;} while(row); - ta+=xalign; - cSRCPtr+=LineOffset;column--; - } - while(column); - } - - break; - //--------------------------------------------------// - // 16bit texture load .. - case 2: - start=((pageid-16*pmult)<<6)+262144*pmult; - - wSRCPtr = psxVuw + start + (y1<<10) + x1; - LineOffset = 1024 - dx; - - column=dy;do - { - row=dx; - do {*ta++=LTCOL(*wSRCPtr++);row--;} while(row); - ta+=xalign; - wSRCPtr+=LineOffset;column--; - } - while(column); - - break; - //--------------------------------------------------// - // others are not possible ! - } - - x2a=dx+xalign; - - if(YTexS) - { - ta=(uint32_t *)texturepart; - pa=(uint32_t *)texturepart+x2a; - row=x2a;do {*ta++=*pa++;row--;} while(row); - pa=(uint32_t *)texturepart+dy*x2a; - ta=pa+x2a; - row=x2a;do {*ta++=*pa++;row--;} while(row); - YTexS--; - dy+=2; - } - - if(XTexS) - { - ta=(uint32_t *)texturepart; - pa=ta+1; - row=dy;do {*ta=*pa;ta+=x2a;pa+=x2a;row--;} while(row); - pa=(uint32_t *)texturepart+dx; - ta=pa+1; - row=dy;do {*ta=*pa;ta+=x2a;pa+=x2a;row--;} while(row); - XTexS--; - dx+=2; - } - - DXTexS=dx;DYTexS=dy; - - if(!iFilterType) {DefineSubTextureSort();return;} - if(iFilterType!=2 && iFilterType!=4 && iFilterType!=6) {DefineSubTextureSort();return;} - if((iFilterType==4 || iFilterType==6) && ly0==ly1 && ly2==ly3 && lx0==lx3 && lx1==lx2) - {DefineSubTextureSort();return;} - - ta=(uint32_t *)texturepart; - x1=dx-1; - y1=dy-1; - - if(bOpaquePass) - { - if(bSmallAlpha) - { - for(column=0;column<dy;column++) - { - for(row=0;row<dx;row++) - { - if(*ta==0x03000000) - { - cnt=0; - - if( column && *(ta-dx) >>24 !=0x03) scol[cnt++]=*(ta-dx); - if(row && *(ta-1) >>24 !=0x03) scol[cnt++]=*(ta-1); - if(row!=x1 && *(ta+1) >>24 !=0x03) scol[cnt++]=*(ta+1); - if( column!=y1 && *(ta+dx) >>24 !=0x03) scol[cnt++]=*(ta+dx); - - if(row && column && *(ta-dx-1)>>24 !=0x03) scol[cnt++]=*(ta-dx-1); - if(row!=x1 && column && *(ta-dx+1)>>24 !=0x03) scol[cnt++]=*(ta-dx+1); - if(row && column!=y1 && *(ta+dx-1)>>24 !=0x03) scol[cnt++]=*(ta+dx-1); - if(row!=x1 && column!=y1 && *(ta+dx+1)>>24 !=0x03) scol[cnt++]=*(ta+dx+1); - - if(cnt) - { - r=g=b=a=0; - for(h=0;h<cnt;h++) - { - r+=(scol[h]>>16)&0xff; - g+=(scol[h]>>8)&0xff; - b+=scol[h]&0xff; - } - r/=cnt;b/=cnt;g/=cnt; - - *ta=(r<<16)|(g<<8)|b; - *ta|=0x03000000; - } - } - ta++; - } - } - } - else - { - for(column=0;column<dy;column++) - { - for(row=0;row<dx;row++) - { - if(*ta==0x50000000) - { - cnt=0; - - if( column && *(ta-dx) !=0x50000000 && *(ta-dx)>>24!=1) scol[cnt++]=*(ta-dx); - if(row && *(ta-1) !=0x50000000 && *(ta-1)>>24!=1) scol[cnt++]=*(ta-1); - if(row!=x1 && *(ta+1) !=0x50000000 && *(ta+1)>>24!=1) scol[cnt++]=*(ta+1); - if( column!=y1 && *(ta+dx) !=0x50000000 && *(ta+dx)>>24!=1) scol[cnt++]=*(ta+dx); - - if(row && column && *(ta-dx-1)!=0x50000000 && *(ta-dx-1)>>24!=1) scol[cnt++]=*(ta-dx-1); - if(row!=x1 && column && *(ta-dx+1)!=0x50000000 && *(ta-dx+1)>>24!=1) scol[cnt++]=*(ta-dx+1); - if(row && column!=y1 && *(ta+dx-1)!=0x50000000 && *(ta+dx-1)>>24!=1) scol[cnt++]=*(ta+dx-1); - if(row!=x1 && column!=y1 && *(ta+dx+1)!=0x50000000 && *(ta+dx+1)>>24!=1) scol[cnt++]=*(ta+dx+1); - - if(cnt) - { - r=g=b=a=0; - for(h=0;h<cnt;h++) - { - a+=(scol[h]>>24); - r+=(scol[h]>>16)&0xff; - g+=(scol[h]>>8)&0xff; - b+=scol[h]&0xff; - } - r/=cnt;b/=cnt;g/=cnt; - - *ta=(r<<16)|(g<<8)|b; - if(a) *ta|=0x50000000; - else *ta|=0x01000000; - } - } - ta++; - } - } - } - } - else - for(column=0;column<dy;column++) - { - for(row=0;row<dx;row++) - { - if(*ta==0x00000000) - { - cnt=0; - - if(row!=x1 && *(ta+1) !=0x00000000) scol[cnt++]=*(ta+1); - if( column!=y1 && *(ta+dx) !=0x00000000) scol[cnt++]=*(ta+dx); - - if(cnt) - { - r=g=b=0; - for(h=0;h<cnt;h++) - { - r+=(scol[h]>>16)&0xff; - g+=(scol[h]>>8)&0xff; - b+=scol[h]&0xff; - } - r/=cnt;b/=cnt;g/=cnt; - *ta=(r<<16)|(g<<8)|b; - } - } - ta++; - } - } - - DefineSubTextureSort(); -} - -///////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////// -// -// load texture part (packed) -// -///////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////// - -void LoadPackedSubTexturePageSort(int pageid, int mode, short cx, short cy) -{ - uint32_t start,row,column,j,sxh,sxm; - unsigned int palstart; - unsigned short *px,*pa,*ta; - unsigned char *cSRCPtr; - unsigned short *wSRCPtr; - uint32_t LineOffset; - uint32_t x2a,xalign=0; - uint32_t x1=gl_ux[7]; - uint32_t x2=gl_ux[6]; - uint32_t y1=gl_ux[5]; - uint32_t y2=gl_ux[4]; - uint32_t dx=x2-x1+1; - uint32_t dy=y2-y1+1; - int pmult=pageid/16; - unsigned short (*LPTCOL)(unsigned short); - unsigned int a,r,g,b,cnt,h; - unsigned short scol[8]; - - LPTCOL=PTCF[DrawSemiTrans]; - - pa=px=(unsigned short *)ubPaletteBuffer; - ta=(unsigned short *)texturepart; - palstart=cx+(cy<<10); - - ubOpaqueDraw=0; - - if(YTexS) {ta+=dx;if(XTexS) ta+=2;} - if(XTexS) {ta+=1;xalign=2;} - - switch(mode) - { - //--------------------------------------------------// - // 4bit texture load .. - case 0: - if(GlobalTextIL) - { - unsigned int TXV,TXU,n_xi,n_yi; - - wSRCPtr=psxVuw+palstart; - row=4;do - { - *px =LPTCOL(*wSRCPtr); - *(px+1)=LPTCOL(*(wSRCPtr+1)); - *(px+2)=LPTCOL(*(wSRCPtr+2)); - *(px+3)=LPTCOL(*(wSRCPtr+3)); - row--;px+=4;wSRCPtr+=4; - } - while (row); - - for(TXV=y1;TXV<=y2;TXV++) - { - for(TXU=x1;TXU<=x2;TXU++) - { - n_xi = ( ( TXU >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c ); - n_yi = ( TXV & ~0xf ) + ( ( TXU >> 4 ) & 0xf ); - - *ta++=*(pa+((*( psxVuw + ((GlobalTextAddrY + n_yi)*1024) + GlobalTextAddrX + n_xi ) >> ( ( TXU & 0x03 ) << 2 ) ) & 0x0f )); - } - ta+=xalign; - } - break; - } - - start=((pageid-16*pmult)<<7)+524288*pmult; - - wSRCPtr=psxVuw+palstart; - row=4;do - { - *px =LPTCOL(*wSRCPtr); - *(px+1)=LPTCOL(*(wSRCPtr+1)); - *(px+2)=LPTCOL(*(wSRCPtr+2)); - *(px+3)=LPTCOL(*(wSRCPtr+3)); - row--;px+=4;wSRCPtr+=4; - } - while (row); - - x2a=x2?(x2-1):0;//if(x2) x2a=x2-1; else x2a=0; - sxm=x1&1;sxh=x1>>1; - j=sxm?(x1+1):x1;//if(sxm) j=x1+1; else j=x1; - - for(column=y1;column<=y2;column++) - { - cSRCPtr = psxVub + start + (column<<11) + sxh; - - if(sxm) *ta++=*(pa+((*cSRCPtr++ >> 4) & 0xF)); - - for(row=j;row<x2a;row+=2) - { - *ta =*(pa+(*cSRCPtr & 0xF)); - *(ta+1)=*(pa+((*cSRCPtr >> 4) & 0xF)); - cSRCPtr++;ta+=2; - } - - if(row<=x2) - { - *ta++=*(pa+(*cSRCPtr & 0xF));row++; - if(row<=x2) *ta++=*(pa+((*cSRCPtr >> 4) & 0xF)); - } - - ta+=xalign; - } - break; - //--------------------------------------------------// - // 8bit texture load .. - case 1: - if(GlobalTextIL) - { - unsigned int TXV,TXU,n_xi,n_yi; - - wSRCPtr=psxVuw+palstart; - - row=64;do - { - *px =LPTCOL(*wSRCPtr); - *(px+1)=LPTCOL(*(wSRCPtr+1)); - *(px+2)=LPTCOL(*(wSRCPtr+2)); - *(px+3)=LPTCOL(*(wSRCPtr+3)); - row--;px+=4;wSRCPtr+=4; - } - while (row); - - for(TXV=y1;TXV<=y2;TXV++) - { - for(TXU=x1;TXU<=x2;TXU++) - { - n_xi = ( ( TXU >> 1 ) & ~0x78 ) + ( ( TXU << 2 ) & 0x40 ) + ( ( TXV << 3 ) & 0x38 ); - n_yi = ( TXV & ~0x7 ) + ( ( TXU >> 5 ) & 0x7 ); - - *ta++=*(pa+((*( psxVuw + ((GlobalTextAddrY + n_yi)*1024) + GlobalTextAddrX + n_xi ) >> ( ( TXU & 0x01 ) << 3 ) ) & 0xff)); - } - ta+=xalign; - } - - break; - } - - start=((pageid-16*pmult)<<7)+524288*pmult; - - cSRCPtr = psxVub + start + (y1<<11) + x1; - LineOffset = 2048 - dx; - - if(dy*dx>384) // more pix? use lut - { - wSRCPtr=psxVuw+palstart; - - row=64;do - { - *px =LPTCOL(*wSRCPtr); - *(px+1)=LPTCOL(*(wSRCPtr+1)); - *(px+2)=LPTCOL(*(wSRCPtr+2)); - *(px+3)=LPTCOL(*(wSRCPtr+3)); - row--;px+=4;wSRCPtr+=4; - } - while (row); - - column=dy;do - { - row=dx; - do {*ta++=*(pa+(*cSRCPtr++));row--;} while(row); - - ta+=xalign; - - cSRCPtr+=LineOffset;column--; - } - while(column); - } - else // small area? no lut - { - wSRCPtr=psxVuw+palstart; - - column=dy;do - { - row=dx; - do {*ta++=LPTCOL(*(wSRCPtr+*cSRCPtr++));row--;} while(row); - - ta+=xalign; - - cSRCPtr+=LineOffset;column--; - } - while(column); - } - break; - //--------------------------------------------------// - // 16bit texture load .. - case 2: - start=((pageid-16*pmult)<<6)+262144*pmult; - - wSRCPtr = psxVuw + start + (y1<<10) + x1; - LineOffset = 1024 - dx; - - column=dy;do - { - row=dx; - do {*ta++=LPTCOL(*wSRCPtr++);row--;} while(row); - - ta+=xalign; - - wSRCPtr+=LineOffset;column--; - } - while(column); - break; - //--------------------------------------------------// - // others are not possible ! - } - - //////////////////////////////////////////////////////// - - x2a=dx+xalign; - - if(YTexS) - { - ta=(unsigned short *)texturepart; - pa=(unsigned short *)texturepart+x2a; - row=x2a;do {*ta++=*pa++;row--;} while(row); - - pa=(unsigned short *)texturepart+dy*x2a; - ta=pa+x2a; - row=x2a;do {*ta++=*pa++;row--;} while(row); - - YTexS--; - dy+=2; - } - - if(XTexS) - { - ta=(unsigned short *)texturepart; - pa=ta+1; - row=dy;do {*ta=*pa;ta+=x2a;pa+=x2a;row--;} while(row); - - pa=(unsigned short *)texturepart+dx; - ta=pa+1; - row=dy;do {*ta=*pa;ta+=x2a;pa+=x2a;row--;} while(row); - - XTexS--; - dx+=2; - } - - DXTexS=dx;DYTexS=dy; - - if(!iFilterType) {DefineSubTextureSort();return;} - if(iFilterType!=2 && iFilterType!=4 && iFilterType!=6) {DefineSubTextureSort();return;} - if((iFilterType==4 || iFilterType==6) && ly0==ly1 && ly2==ly3 && lx0==lx3 && lx1==lx2) - {DefineSubTextureSort();return;} - - ta=(unsigned short *)texturepart; - x1=dx-1; - y1=dy-1; - - if(iTexQuality==1) - - { - if(bOpaquePass) - for(column=0;column<dy;column++) - { - for(row=0;row<dx;row++) - { - if(*ta==0x0006) - { - cnt=0; - - if( column && *(ta-dx) != 0x0006 && *(ta-dx)!=0) scol[cnt++]=*(ta-dx); - if(row && *(ta-1) != 0x0006 && *(ta-1) !=0) scol[cnt++]=*(ta-1); - if(row!=x1 && *(ta+1) != 0x0006 && *(ta+1) !=0) scol[cnt++]=*(ta+1); - if( column!=y1 && *(ta+dx) != 0x0006 && *(ta+dx)!=0) scol[cnt++]=*(ta+dx); - - if(row && column && *(ta-dx-1)!= 0x0006 && *(ta-dx-1)!=0) scol[cnt++]=*(ta-dx-1); - if(row!=x1 && column && *(ta-dx+1)!= 0x0006 && *(ta-dx+1)!=0) scol[cnt++]=*(ta-dx+1); - if(row && column!=y1 && *(ta+dx-1)!= 0x0006 && *(ta+dx-1)!=0) scol[cnt++]=*(ta+dx-1); - if(row!=x1 && column!=y1 && *(ta+dx+1)!= 0x0006 && *(ta+dx+1)!=0) scol[cnt++]=*(ta+dx+1); - - if(cnt) - { - r=g=b=a=0; - for(h=0;h<cnt;h++) - { - a+=scol[h]&0xf; - r+=scol[h]>>12; - g+=(scol[h]>>8)&0xf; - b+=(scol[h]>>4)&0xf; - } - r/=cnt;b/=cnt;g/=cnt; - *ta=(r<<12)|(g<<8)|(b<<4); - if(a) *ta|=6; - else *ta=0; - } - } - ta++; - } - } - else - for(column=0;column<dy;column++) - { - for(row=0;row<dx;row++) - { - if(*ta==0x0000) - { - cnt=0; - - if( column && *(ta-dx) != 0x0000) scol[cnt++]=*(ta-dx); - if(row && *(ta-1) != 0x0000) scol[cnt++]=*(ta-1); - if(row!=x1 && *(ta+1) != 0x0000) scol[cnt++]=*(ta+1); - if( column!=y1 && *(ta+dx) != 0x0000) scol[cnt++]=*(ta+dx); - - if(row && column && *(ta-dx-1)!= 0x0000) scol[cnt++]=*(ta-dx-1); - if(row!=x1 && column && *(ta-dx+1)!= 0x0000) scol[cnt++]=*(ta-dx+1); - if(row && column!=y1 && *(ta+dx-1)!= 0x0000) scol[cnt++]=*(ta+dx-1); - if(row!=x1 && column!=y1 && *(ta+dx+1)!= 0x0000) scol[cnt++]=*(ta+dx+1); - - if(cnt) - { - r=g=b=0; - for(h=0;h<cnt;h++) - { - r+=scol[h]>>12; - g+=(scol[h]>>8)&0xf; - b+=(scol[h]>>4)&0xf; - } - r/=cnt;b/=cnt;g/=cnt; - *ta=(r<<12)|(g<<8)|(b<<4); - } - } - ta++; - } - } - } - else - { - for(column=0;column<dy;column++) - { - for(row=0;row<dx;row++) - { - if(*ta==0) - { - cnt=0; - - if( column && *(ta-dx) &1) scol[cnt++]=*(ta-dx); - if(row && *(ta-1) &1) scol[cnt++]=*(ta-1); - if(row!=x1 && *(ta+1) &1) scol[cnt++]=*(ta+1); - if( column!=y1 && *(ta+dx) &1) scol[cnt++]=*(ta+dx); - - if(row && column && *(ta-dx-1)&1) scol[cnt++]=*(ta-dx-1); - if(row!=x1 && column && *(ta-dx+1)&1) scol[cnt++]=*(ta-dx+1); - if(row && column!=y1 && *(ta+dx-1)&1) scol[cnt++]=*(ta+dx-1); - if(row!=x1 && column!=y1 && *(ta+dx+1)&1) scol[cnt++]=*(ta+dx+1); - - if(cnt) - { - r=g=b=0; - for(h=0;h<cnt;h++) - { - r+=scol[h]>>11; - g+=(scol[h]>>6)&0x1f; - b+=(scol[h]>>1)&0x1f; - } - r/=cnt;b/=cnt;g/=cnt; - *ta=(r<<11)|(g<<6)|(b<<1); - } - } - ta++; - } - } - } - - DefineSubTextureSort(); -} - -///////////////////////////////////////////////////////////////////////////// - -///////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////// -// -// hires texture funcs -// -///////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////// - - -#define GET_RESULT(A, B, C, D) ((A != C || A != D) - (B != C || B != D)) - -//////////////////////////////////////////////////////////////////////// - -#define colorMask8 0x00FEFEFE -#define lowPixelMask8 0x00010101 -#define qcolorMask8 0x00FCFCFC -#define qlowpixelMask8 0x00030303 - - -#define INTERPOLATE8_02(A, B) (((((A & colorMask8) >> 1) + ((B & colorMask8) >> 1) + (A & B & lowPixelMask8))|((((A&0xFF000000)==0x03000000)?0x03000000:(((B&0xFF000000)==0x03000000)?0x03000000:(((A&0xFF000000)==0x00000000)?0x00000000:(((B&0xFF000000)==0x00000000)?0x00000000:0xFF000000))))))) - -#define Q_INTERPOLATE8_02(A, B, C, D) (((((A & qcolorMask8) >> 2) + ((B & qcolorMask8) >> 2) + ((C & qcolorMask8) >> 2) + ((D & qcolorMask8) >> 2) + ((((A & qlowpixelMask8) + (B & qlowpixelMask8) + (C & qlowpixelMask8) + (D & qlowpixelMask8)) >> 2) & qlowpixelMask8))|((((A&0xFF000000)==0x03000000)?0x03000000:(((B&0xFF000000)==0x03000000)?0x03000000:(((C&0xFF000000)==0x03000000)?0x03000000:(((D&0xFF000000)==0x03000000)?0x03000000:(((A&0xFF000000)==0x00000000)?0x00000000:(((B&0xFF000000)==0x00000000)?0x00000000:(((C&0xFF000000)==0x00000000)?0x00000000:(((D&0xFF000000)==0x00000000)?0x00000000:0xFF000000))))))))))) - -#define INTERPOLATE8(A, B) (((((A & colorMask8) >> 1) + ((B & colorMask8) >> 1) + (A & B & lowPixelMask8))|((((A&0xFF000000)==0x50000000)?0x50000000:(((B&0xFF000000)==0x50000000)?0x50000000:(((A&0xFF000000)==0x00000000)?0x00000000:(((B&0xFF000000)==0x00000000)?0x00000000:0xFF000000))))))) - -#define Q_INTERPOLATE8(A, B, C, D) (((((A & qcolorMask8) >> 2) + ((B & qcolorMask8) >> 2) + ((C & qcolorMask8) >> 2) + ((D & qcolorMask8) >> 2) + ((((A & qlowpixelMask8) + (B & qlowpixelMask8) + (C & qlowpixelMask8) + (D & qlowpixelMask8)) >> 2) & qlowpixelMask8))|((((A&0xFF000000)==0x50000000)?0x50000000:(((B&0xFF000000)==0x50000000)?0x50000000:(((C&0xFF000000)==0x50000000)?0x50000000:(((D&0xFF000000)==0x50000000)?0x50000000:(((A&0xFF000000)==0x00000000)?0x00000000:(((B&0xFF000000)==0x00000000)?0x00000000:(((C&0xFF000000)==0x00000000)?0x00000000:(((D&0xFF000000)==0x00000000)?0x00000000:0xFF000000))))))))))) - -static void Super2xSaI_ex8_Ex(unsigned char *srcPtr, DWORD srcPitch, - unsigned char *dstBitmap, int width, int height) -{ - DWORD dstPitch = srcPitch * 2; - DWORD line; - DWORD *dP; - DWORD *bP; - int width2 = width*2; - int iXA,iXB,iXC,iYA,iYB,iYC,finish; - DWORD color4, color5, color6; - DWORD color1, color2, color3; - DWORD colorA0, colorA1, colorA2, colorA3, - colorB0, colorB1, colorB2, colorB3, - colorS1, colorS2; - DWORD product1a, product1b, - product2a, product2b; - - line = 0; - - { - for (; height; height-=1) - { - bP = (DWORD *)srcPtr; - dP = (DWORD *)(dstBitmap + line*dstPitch); - for (finish = width; finish; finish -= 1 ) - { -//--------------------------------------- B1 B2 -// 4 5 6 S2 -// 1 2 3 S1 -// A1 A2 - if(finish==width) iXA=0; - else iXA=1; - if(finish>4) {iXB=1;iXC=2;} - else - if(finish>3) {iXB=1;iXC=1;} - else {iXB=0;iXC=0;} - if(line==0) iYA=0; - else iYA=width; - if(height>4) {iYB=width;iYC=width2;} - else - if(height>3) {iYB=width;iYC=width;} - else {iYB=0;iYC=0;} - - - colorB0 = *(bP- iYA - iXA); - colorB1 = *(bP- iYA); - colorB2 = *(bP- iYA + iXB); - colorB3 = *(bP- iYA + iXC); - - color4 = *(bP - iXA); - color5 = *(bP); - color6 = *(bP + iXB); - colorS2 = *(bP + iXC); - - color1 = *(bP + iYB - iXA); - color2 = *(bP + iYB); - color3 = *(bP + iYB + iXB); - colorS1= *(bP + iYB + iXC); - - colorA0 = *(bP + iYC - iXA); - colorA1 = *(bP + iYC); - colorA2 = *(bP + iYC + iXB); - colorA3 = *(bP + iYC + iXC); - -//-------------------------------------- - if (color2 == color6 && color5 != color3) - { - product2b = product1b = color2; - } - else - if (color5 == color3 && color2 != color6) - { - product2b = product1b = color5; - } - else - if (color5 == color3 && color2 == color6) - { - register int r = 0; - - r += GET_RESULT ((color6&0x00ffffff), (color5&0x00ffffff), (color1&0x00ffffff), (colorA1&0x00ffffff)); - r += GET_RESULT ((color6&0x00ffffff), (color5&0x00ffffff), (color4&0x00ffffff), (colorB1&0x00ffffff)); - r += GET_RESULT ((color6&0x00ffffff), (color5&0x00ffffff), (colorA2&0x00ffffff), (colorS1&0x00ffffff)); - r += GET_RESULT ((color6&0x00ffffff), (color5&0x00ffffff), (colorB2&0x00ffffff), (colorS2&0x00ffffff)); - - if (r > 0) - product2b = product1b = color6; - else - if (r < 0) - product2b = product1b = color5; - else - { - product2b = product1b = INTERPOLATE8_02(color5, color6); - } - } - else - { - if (color6 == color3 && color3 == colorA1 && color2 != colorA2 && color3 != colorA0) - product2b = Q_INTERPOLATE8_02 (color3, color3, color3, color2); - else - if (color5 == color2 && color2 == colorA2 && colorA1 != color3 && color2 != colorA3) - product2b = Q_INTERPOLATE8_02 (color2, color2, color2, color3); - else - product2b = INTERPOLATE8_02 (color2, color3); - - if (color6 == color3 && color6 == colorB1 && color5 != colorB2 && color6 != colorB0) - product1b = Q_INTERPOLATE8_02 (color6, color6, color6, color5); - else - if (color5 == color2 && color5 == colorB2 && colorB1 != color6 && color5 != colorB3) - product1b = Q_INTERPOLATE8_02 (color6, color5, color5, color5); - else - product1b = INTERPOLATE8_02 (color5, color6); - } - - if (color5 == color3 && color2 != color6 && color4 == color5 && color5 != colorA2) - product2a = INTERPOLATE8_02(color2, color5); - else - if (color5 == color1 && color6 == color5 && color4 != color2 && color5 != colorA0) - product2a = INTERPOLATE8_02(color2, color5); - else - product2a = color2; - - if (color2 == color6 && color5 != color3 && color1 == color2 && color2 != colorB2) - product1a = INTERPOLATE8_02(color2, color5); - else - if (color4 == color2 && color3 == color2 && color1 != color5 && color2 != colorB0) - product1a = INTERPOLATE8_02(color2, color5); - else - product1a = color5; - - *dP=product1a; - *(dP+1)=product1b; - *(dP+(width2))=product2a; - *(dP+1+(width2))=product2b; - - bP += 1; - dP += 2; - }//end of for ( finish= width etc..) - - line += 2; - srcPtr += srcPitch; - }; //endof: for (; height; height--) - } -} - - -static void Super2xSaI_ex8(unsigned char *srcPtr, DWORD srcPitch, - unsigned char *dstBitmap, int width, int height) -{ - DWORD dstPitch = srcPitch * 2; - DWORD line; - DWORD *dP; - DWORD *bP; - int width2 = width*2; - int iXA,iXB,iXC,iYA,iYB,iYC,finish; - DWORD color4, color5, color6; - DWORD color1, color2, color3; - DWORD colorA0, colorA1, colorA2, colorA3, - colorB0, colorB1, colorB2, colorB3, - colorS1, colorS2; - DWORD product1a, product1b, - product2a, product2b; - - line = 0; - - { - for (; height; height-=1) - { - bP = (DWORD *)srcPtr; - dP = (DWORD *)(dstBitmap + line*dstPitch); - for (finish = width; finish; finish -= 1 ) - { -//--------------------------------------- B1 B2 -// 4 5 6 S2 -// 1 2 3 S1 -// A1 A2 - if(finish==width) iXA=0; - else iXA=1; - if(finish>4) {iXB=1;iXC=2;} - else - if(finish>3) {iXB=1;iXC=1;} - else {iXB=0;iXC=0;} - if(line==0) iYA=0; - else iYA=width; - if(height>4) {iYB=width;iYC=width2;} - else - if(height>3) {iYB=width;iYC=width;} - else {iYB=0;iYC=0;} - - - colorB0 = *(bP- iYA - iXA); - colorB1 = *(bP- iYA); - colorB2 = *(bP- iYA + iXB); - colorB3 = *(bP- iYA + iXC); - - color4 = *(bP - iXA); - color5 = *(bP); - color6 = *(bP + iXB); - colorS2 = *(bP + iXC); - - color1 = *(bP + iYB - iXA); - color2 = *(bP + iYB); - color3 = *(bP + iYB + iXB); - colorS1= *(bP + iYB + iXC); - - colorA0 = *(bP + iYC - iXA); - colorA1 = *(bP + iYC); - colorA2 = *(bP + iYC + iXB); - colorA3 = *(bP + iYC + iXC); - -//-------------------------------------- - if (color2 == color6 && color5 != color3) - { - product2b = product1b = color2; - } - else - if (color5 == color3 && color2 != color6) - { - product2b = product1b = color5; - } - else - if (color5 == color3 && color2 == color6) - { - register int r = 0; - - r += GET_RESULT ((color6&0x00ffffff), (color5&0x00ffffff), (color1&0x00ffffff), (colorA1&0x00ffffff)); - r += GET_RESULT ((color6&0x00ffffff), (color5&0x00ffffff), (color4&0x00ffffff), (colorB1&0x00ffffff)); - r += GET_RESULT ((color6&0x00ffffff), (color5&0x00ffffff), (colorA2&0x00ffffff), (colorS1&0x00ffffff)); - r += GET_RESULT ((color6&0x00ffffff), (color5&0x00ffffff), (colorB2&0x00ffffff), (colorS2&0x00ffffff)); - - if (r > 0) - product2b = product1b = color6; - else - if (r < 0) - product2b = product1b = color5; - else - { - product2b = product1b = INTERPOLATE8(color5, color6); - } - } - else - { - if (color6 == color3 && color3 == colorA1 && color2 != colorA2 && color3 != colorA0) - product2b = Q_INTERPOLATE8 (color3, color3, color3, color2); - else - if (color5 == color2 && color2 == colorA2 && colorA1 != color3 && color2 != colorA3) - product2b = Q_INTERPOLATE8 (color2, color2, color2, color3); - else - product2b = INTERPOLATE8 (color2, color3); - - if (color6 == color3 && color6 == colorB1 && color5 != colorB2 && color6 != colorB0) - product1b = Q_INTERPOLATE8 (color6, color6, color6, color5); - else - if (color5 == color2 && color5 == colorB2 && colorB1 != color6 && color5 != colorB3) - product1b = Q_INTERPOLATE8 (color6, color5, color5, color5); - else - product1b = INTERPOLATE8 (color5, color6); - } - - if (color5 == color3 && color2 != color6 && color4 == color5 && color5 != colorA2) - product2a = INTERPOLATE8(color2, color5); - else - if (color5 == color1 && color6 == color5 && color4 != color2 && color5 != colorA0) - product2a = INTERPOLATE8(color2, color5); - else - product2a = color2; - - if (color2 == color6 && color5 != color3 && color1 == color2 && color2 != colorB2) - product1a = INTERPOLATE8(color2, color5); - else - if (color4 == color2 && color3 == color2 && color1 != color5 && color2 != colorB0) - product1a = INTERPOLATE8(color2, color5); - else - product1a = color5; - - *dP=product1a; - *(dP+1)=product1b; - *(dP+(width2))=product2a; - *(dP+1+(width2))=product2b; - - bP += 1; - dP += 2; - }//end of for ( finish= width etc..) - - line += 2; - srcPtr += srcPitch; - }; //endof: for (; height; height--) - } -} -///////////////////////////////////////////////////////////////////////////// - -#define colorMask4 0x0000EEE0 -#define lowPixelMask4 0x00001110 -#define qcolorMask4 0x0000CCC0 -#define qlowpixelMask4 0x00003330 - -#define INTERPOLATE4(A, B) ((((A & colorMask4) >> 1) + ((B & colorMask4) >> 1) + (A & B & lowPixelMask4))|((((A&0x0000000F)==0x00000006)?0x00000006:(((B&0x0000000F)==0x00000006)?0x00000006:(((A&0x0000000F)==0x00000000)?0x00000000:(((B&0x0000000F)==0x00000000)?0x00000000:0x0000000F)))))) - -#define Q_INTERPOLATE4(A, B, C, D) ((((A & qcolorMask4) >> 2) + ((B & qcolorMask4) >> 2) + ((C & qcolorMask4) >> 2) + ((D & qcolorMask4) >> 2) + ((((A & qlowpixelMask4) + (B & qlowpixelMask4) + (C & qlowpixelMask4) + (D & qlowpixelMask4)) >> 2) & qlowpixelMask4))| ((((A&0x0000000F)==0x00000006)?0x00000006:(((B&0x0000000F)==0x00000006)?0x00000006:(((C&0x0000000F)==0x00000006)?0x00000006:(((D&0x0000000F)==0x00000006)?0x00000006:(((A&0x0000000F)==0x00000000)?0x00000000:(((B&0x0000000F)==0x00000000)?0x00000000:(((C&0x0000000F)==0x00000000)?0x00000000:(((D&0x0000000F)==0x00000000)?0x00000000:0x0000000F)))))))))) - -static void Super2xSaI_ex4(unsigned char *srcPtr, DWORD srcPitch, - unsigned char *dstBitmap, int width, int height) -{ - DWORD dstPitch = srcPitch * 2; - DWORD line; - unsigned short *dP; - unsigned short *bP; - int width2 = width*2; - int iXA,iXB,iXC,iYA,iYB,iYC,finish; - DWORD color4, color5, color6; - DWORD color1, color2, color3; - DWORD colorA0, colorA1, colorA2, colorA3, - colorB0, colorB1, colorB2, colorB3, - colorS1, colorS2; - DWORD product1a, product1b, - product2a, product2b; - - line = 0; - - { - for (; height; height-=1) - { - bP = (unsigned short *)srcPtr; - dP = (unsigned short *)(dstBitmap + line*dstPitch); - for (finish = width; finish; finish -= 1 ) - { -//--------------------------------------- B1 B2 -// 4 5 6 S2 -// 1 2 3 S1 -// A1 A2 - if(finish==width) iXA=0; - else iXA=1; - if(finish>4) {iXB=1;iXC=2;} - else - if(finish>3) {iXB=1;iXC=1;} - else {iXB=0;iXC=0;} - if(line==0) iYA=0; - else iYA=width; - if(height>4) {iYB=width;iYC=width2;} - else - if(height>3) {iYB=width;iYC=width;} - else {iYB=0;iYC=0;} - - - colorB0 = *(bP- iYA - iXA); - colorB1 = *(bP- iYA); - colorB2 = *(bP- iYA + iXB); - colorB3 = *(bP- iYA + iXC); - - color4 = *(bP - iXA); - color5 = *(bP); - color6 = *(bP + iXB); - colorS2 = *(bP + iXC); - - color1 = *(bP + iYB - iXA); - color2 = *(bP + iYB); - color3 = *(bP + iYB + iXB); - colorS1= *(bP + iYB + iXC); - - colorA0 = *(bP + iYC - iXA); - colorA1 = *(bP + iYC); - colorA2 = *(bP + iYC + iXB); - colorA3 = *(bP + iYC + iXC); - -//-------------------------------------- - if (color2 == color6 && color5 != color3) - { - product2b = product1b = color2; - } - else - if (color5 == color3 && color2 != color6) - { - product2b = product1b = color5; - } - else - if (color5 == color3 && color2 == color6) - { - register int r = 0; - - r += GET_RESULT ((color6&0xfffffff0), (color5&0xfffffff0), (color1&0xfffffff0), (colorA1&0xfffffff0)); - r += GET_RESULT ((color6&0xfffffff0), (color5&0xfffffff0), (color4&0xfffffff0), (colorB1&0xfffffff0)); - r += GET_RESULT ((color6&0xfffffff0), (color5&0xfffffff0), (colorA2&0xfffffff0), (colorS1&0xfffffff0)); - r += GET_RESULT ((color6&0xfffffff0), (color5&0xfffffff0), (colorB2&0xfffffff0), (colorS2&0xfffffff0)); - - if (r > 0) - product2b = product1b = color6; - else - if (r < 0) - product2b = product1b = color5; - else - { - product2b = product1b = INTERPOLATE4 (color5, color6); - } - } - else - { - if (color6 == color3 && color3 == colorA1 && color2 != colorA2 && color3 != colorA0) - product2b = Q_INTERPOLATE4 (color3, color3, color3, color2); - else - if (color5 == color2 && color2 == colorA2 && colorA1 != color3 && color2 != colorA3) - product2b = Q_INTERPOLATE4 (color2, color2, color2, color3); - else - product2b = INTERPOLATE4 (color2, color3); - - if (color6 == color3 && color6 == colorB1 && color5 != colorB2 && color6 != colorB0) - product1b = Q_INTERPOLATE4 (color6, color6, color6, color5); - else - if (color5 == color2 && color5 == colorB2 && colorB1 != color6 && color5 != colorB3) - product1b = Q_INTERPOLATE4 (color6, color5, color5, color5); - else - product1b = INTERPOLATE4 (color5, color6); - } - - if (color5 == color3 && color2 != color6 && color4 == color5 && color5 != colorA2) - product2a = INTERPOLATE4 (color2, color5); - else - if (color5 == color1 && color6 == color5 && color4 != color2 && color5 != colorA0) - product2a = INTERPOLATE4(color2, color5); - else - product2a = color2; - - if (color2 == color6 && color5 != color3 && color1 == color2 && color2 != colorB2) - product1a = INTERPOLATE4 (color2, color5); - else - if (color4 == color2 && color3 == color2 && color1 != color5 && color2 != colorB0) - product1a = INTERPOLATE4(color2, color5); - else - product1a = color5; - - *dP=product1a; - *(dP+1)=product1b; - *(dP+(width2))=product2a; - *(dP+1+(width2))=product2b; - - bP += 1; - dP += 2; - }//end of for ( finish= width etc..) - - line += 2; - srcPtr += srcPitch; - }; //endof: for (; height; height--) - } -} - -///////////////////////////////////////////////////////////////////////////// - -#define colorMask5 0x0000F7BC -#define lowPixelMask5 0x00000842 -#define qcolorMask5 0x0000E738 -#define qlowpixelMask5 0x000018C6 - -#define INTERPOLATE5(A, B) ((((A & colorMask5) >> 1) + ((B & colorMask5) >> 1) + (A & B & lowPixelMask5))|((((A&0x00000001)==0x00000000)?0x00000000:(((B&0x00000001)==0x00000000)?0x00000000:0x00000001)))) - -#define Q_INTERPOLATE5(A, B, C, D) ((((A & qcolorMask5) >> 2) + ((B & qcolorMask5) >> 2) + ((C & qcolorMask5) >> 2) + ((D & qcolorMask5) >> 2) + ((((A & qlowpixelMask5) + (B & qlowpixelMask5) + (C & qlowpixelMask5) + (D & qlowpixelMask5)) >> 2) & qlowpixelMask5))| ((((A&0x00000001)==0x00000000)?0x00000000:(((B&0x00000001)==0x00000000)?0x00000000:(((C&0x00000001)==0x00000000)?0x00000000:(((D&0x00000001)==0x00000000)?0x00000000:0x00000001)))))) - -static void Super2xSaI_ex5(unsigned char *srcPtr, DWORD srcPitch, - unsigned char *dstBitmap, int width, int height) -{ - DWORD dstPitch = srcPitch * 2; - DWORD line; - unsigned short *dP; - unsigned short *bP; - int width2 = width*2; - int iXA,iXB,iXC,iYA,iYB,iYC,finish; - DWORD color4, color5, color6; - DWORD color1, color2, color3; - DWORD colorA0, colorA1, colorA2, colorA3, - colorB0, colorB1, colorB2, colorB3, - colorS1, colorS2; - DWORD product1a, product1b, - product2a, product2b; - - line = 0; - - { - for (; height; height-=1) - { - bP = (unsigned short *)srcPtr; - dP = (unsigned short *)(dstBitmap + line*dstPitch); - for (finish = width; finish; finish -= 1 ) - { -//--------------------------------------- B1 B2 -// 4 5 6 S2 -// 1 2 3 S1 -// A1 A2 - if(finish==width) iXA=0; - else iXA=1; - if(finish>4) {iXB=1;iXC=2;} - else - if(finish>3) {iXB=1;iXC=1;} - else {iXB=0;iXC=0;} - if(line==0) iYA=0; - else iYA=width; - if(height>4) {iYB=width;iYC=width2;} - else - if(height>3) {iYB=width;iYC=width;} - else {iYB=0;iYC=0;} - - - colorB0 = *(bP- iYA - iXA); - colorB1 = *(bP- iYA); - colorB2 = *(bP- iYA + iXB); - colorB3 = *(bP- iYA + iXC); - - color4 = *(bP - iXA); - color5 = *(bP); - color6 = *(bP + iXB); - colorS2 = *(bP + iXC); - - color1 = *(bP + iYB - iXA); - color2 = *(bP + iYB); - color3 = *(bP + iYB + iXB); - colorS1= *(bP + iYB + iXC); - - colorA0 = *(bP + iYC - iXA); - colorA1 = *(bP + iYC); - colorA2 = *(bP + iYC + iXB); - colorA3 = *(bP + iYC + iXC); - -//-------------------------------------- - if (color2 == color6 && color5 != color3) - { - product2b = product1b = color2; - } - else - if (color5 == color3 && color2 != color6) - { - product2b = product1b = color5; - } - else - if (color5 == color3 && color2 == color6) - { - register int r = 0; - - r += GET_RESULT ((color6&0xfffffffe), (color5&0xfffffffe), (color1&0xfffffffe), (colorA1&0xfffffffe)); - r += GET_RESULT ((color6&0xfffffffe), (color5&0xfffffffe), (color4&0xfffffffe), (colorB1&0xfffffffe)); - r += GET_RESULT ((color6&0xfffffffe), (color5&0xfffffffe), (colorA2&0xfffffffe), (colorS1&0xfffffffe)); - r += GET_RESULT ((color6&0xfffffffe), (color5&0xfffffffe), (colorB2&0xfffffffe), (colorS2&0xfffffffe)); - - if (r > 0) - product2b = product1b = color6; - else - if (r < 0) - product2b = product1b = color5; - else - { - product2b = product1b = INTERPOLATE5 (color5, color6); - } - } - else - { - if (color6 == color3 && color3 == colorA1 && color2 != colorA2 && color3 != colorA0) - product2b = Q_INTERPOLATE5 (color3, color3, color3, color2); - else - if (color5 == color2 && color2 == colorA2 && colorA1 != color3 && color2 != colorA3) - product2b = Q_INTERPOLATE5 (color2, color2, color2, color3); - else - product2b = INTERPOLATE5 (color2, color3); - - if (color6 == color3 && color6 == colorB1 && color5 != colorB2 && color6 != colorB0) - product1b = Q_INTERPOLATE5 (color6, color6, color6, color5); - else - if (color5 == color2 && color5 == colorB2 && colorB1 != color6 && color5 != colorB3) - product1b = Q_INTERPOLATE5 (color6, color5, color5, color5); - else - product1b = INTERPOLATE5 (color5, color6); - } - - if (color5 == color3 && color2 != color6 && color4 == color5 && color5 != colorA2) - product2a = INTERPOLATE5 (color2, color5); - else - if (color5 == color1 && color6 == color5 && color4 != color2 && color5 != colorA0) - product2a = INTERPOLATE5(color2, color5); - else - product2a = color2; - - if (color2 == color6 && color5 != color3 && color1 == color2 && color2 != colorB2) - product1a = INTERPOLATE5(color2, color5); - else - if (color4 == color2 && color3 == color2 && color1 != color5 && color2 != colorB0) - product1a = INTERPOLATE5(color2, color5); - else - product1a = color5; - - *dP=product1a; - *(dP+1)=product1b; - *(dP+(width2))=product2a; - *(dP+1+(width2))=product2b; - - bP += 1; - dP += 2; - }//end of for ( finish= width etc..) - - line += 2; - srcPtr += srcPitch; - }; //endof: for (; height; height--) - } -} - -///////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////// -// -// ogl texture defines -// -///////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////// - -static void DefineSubTextureSortHiRes(void) -{ - int x,y,dx2; - - if(!gTexName) - { - glGenTextures(1, &gTexName); - glBindTexture(GL_TEXTURE_2D, gTexName); - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, iClampType); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, iClampType); - - if(iFilterType) - { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - } - else - { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - } - glTexImage2D(GL_TEXTURE_2D, 0, giWantedRGBA, 512, 512, 0, giWantedFMT, giWantedTYPE, texturebuffer); - } - else glBindTexture(GL_TEXTURE_2D, gTexName); - - if(bGLExt && (iTexQuality==1 || iTexQuality==2)) - { - if(DXTexS < 4 || DYTexS < 4 || iHiResTextures==2) - { - unsigned short * pS,*pD1,*pD2; - dx2=(DXTexS<<1); - pS=(unsigned short *)texturepart; - pD1=(unsigned short *)texturebuffer; - pD2=(unsigned short *)texturebuffer; - pD2+=dx2; - for(y=0;y<DYTexS;y++) - { - for(x=0;x<DXTexS;x++) - { - *(pD2+1)=*pD2=*(pD1+1)=*pD1=*pS; - pS++; - pD1+=2; - pD2+=2; - } - pD1+=dx2; - pD2+=dx2; - } - } - else - { - if(iTexQuality==1) - Super2xSaI_ex4(texturepart, DXTexS<<1, texturebuffer, DXTexS, DYTexS); - else - Super2xSaI_ex5(texturepart, DXTexS<<1, texturebuffer, DXTexS, DYTexS); - } - } - else - { - if(DXTexS < 4 || DYTexS < 4 || iHiResTextures==2) - { - uint32_t * pS,*pD1,*pD2; - dx2=(DXTexS<<1); - pS=(uint32_t *)texturepart; - pD1=(uint32_t *)texturebuffer; - pD2=(uint32_t *)texturebuffer; - pD2+=dx2; - for(y=0;y<DYTexS;y++) - { - for(x=0;x<DXTexS;x++) - { - *(pD2+1)=*pD2=*(pD1+1)=*pD1=*pS; - pS++; - pD1+=2; - pD2+=2; - } - pD1+=dx2; - pD2+=dx2; - } - } - else - if(bSmallAlpha) - Super2xSaI_ex8_Ex(texturepart, DXTexS*4, texturebuffer, DXTexS, DYTexS); - else - Super2xSaI_ex8(texturepart, DXTexS*4, texturebuffer, DXTexS, DYTexS); - } - - glTexSubImage2D(GL_TEXTURE_2D, 0, XTexS<<1, YTexS<<1, - DXTexS<<1, DYTexS<<1, - giWantedFMT, giWantedTYPE, texturebuffer); -} - -///////////////////////////////////////////////////////////////////////////// - -void DefineSubTextureSort(void) -{ - if(iHiResTextures) - { - DefineSubTextureSortHiRes(); - return; - } - - if(!gTexName) - { - glGenTextures(1, &gTexName); - glBindTexture(GL_TEXTURE_2D, gTexName); - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, iClampType); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, iClampType); - - if(iFilterType) - { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - } - else - { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - } - glTexImage2D(GL_TEXTURE_2D, 0, giWantedRGBA, 256, 256, 0,giWantedFMT, giWantedTYPE, texturepart); - } - else glBindTexture(GL_TEXTURE_2D, gTexName); - - glTexSubImage2D(GL_TEXTURE_2D, 0, XTexS, YTexS, - DXTexS, DYTexS, - giWantedFMT, giWantedTYPE, texturepart); -} - -///////////////////////////////////////////////////////////////////////////// - -///////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////// -// -// texture cache garbage collection -// -///////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////// - -static void DoTexGarbageCollection(void) -{ - static unsigned short LRUCleaned=0; - unsigned short iC,iC1,iC2; - int i,j,iMax;textureSubCacheEntryS * tsb; - - iC=4;//=iSortTexCnt/2, - LRUCleaned+=iC; // we clean different textures each time - if((LRUCleaned+iC)>=iSortTexCnt) LRUCleaned=0; // wrap? wrap! - iC1=LRUCleaned; // range of textures to clean - iC2=LRUCleaned+iC; - - for(iC=iC1;iC<iC2;iC++) // make some textures available - { - pxSsubtexLeft[iC]->l=0; - } - - for(i=0;i<3;i++) // remove all references to that textures - for(j=0;j<MAXTPAGES;j++) - for(iC=0;iC<4;iC++) // loop all texture rect info areas - { - tsb=pscSubtexStore[i][j]+(iC*SOFFB); - iMax=tsb->pos.l; - if(iMax) - do - { - tsb++; - if(tsb->cTexID>=iC1 && tsb->cTexID<iC2) // info uses the cleaned textures? remove info - tsb->ClutID=0; - } - while(--iMax); - } - - usLRUTexPage=LRUCleaned; -} - -///////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////// -// -// search cache for existing (already used) parts -// -///////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////// - -unsigned char * CheckTextureInSubSCache(int TextureMode, uint32_t GivenClutId, unsigned short * pCache) -{ - textureSubCacheEntryS * tsx, * tsb, *tsg;//, *tse=NULL; - int i,iMax;EXLong npos; - unsigned char cx,cy; - int iC,j,k;uint32_t rx,ry,mx,my; - EXLong * ul=0, * uls; - EXLong rfree; - unsigned char cXAdj,cYAdj; - - npos.l=*((uint32_t *)&gl_ux[4]); - - //--------------------------------------------------------------// - // find matching texturepart first... speed up... - //--------------------------------------------------------------// - - tsg=pscSubtexStore[TextureMode][GlobalTexturePage]; - tsg+=((GivenClutId&CLUTCHK)>>CLUTSHIFT)*SOFFB; - - iMax=tsg->pos.l; - if(iMax) - { - i=iMax; - tsb=tsg+1; - do - { - if(GivenClutId==tsb->ClutID && - (INCHECK(tsb->pos,npos))) - { - { - cx=tsb->pos.c[3]-tsb->posTX; - cy=tsb->pos.c[1]-tsb->posTY; - - gl_ux[0]-=cx; - gl_ux[1]-=cx; - gl_ux[2]-=cx; - gl_ux[3]-=cx; - gl_vy[0]-=cy; - gl_vy[1]-=cy; - gl_vy[2]-=cy; - gl_vy[3]-=cy; - - ubOpaqueDraw=tsb->Opaque; - *pCache=tsb->cTexID; - return NULL; - } - } - tsb++; - } - while(--i); - } - - //----------------------------------------------------// - - cXAdj=1;cYAdj=1; - - rx=(int)gl_ux[6]-(int)gl_ux[7]; - ry=(int)gl_ux[4]-(int)gl_ux[5]; - - tsx=NULL;tsb=tsg+1; - for(i=0;i<iMax;i++,tsb++) - { - if(!tsb->ClutID) {tsx=tsb;break;} - } - - if(!tsx) - { - iMax++; - if(iMax>=SOFFB-2) - { - if(iTexGarbageCollection) // gc mode? - { - if(*pCache==0) - { - dwTexPageComp|=(1<<GlobalTexturePage); - *pCache=0xffff; - return 0; - } - - iMax--; - tsb=tsg+1; - - for(i=0;i<iMax;i++,tsb++) // 1. search other slots with same cluts, and unite the area - if(GivenClutId==tsb->ClutID) - { - if(!tsx) {tsx=tsb;rfree.l=npos.l;} // - else tsb->ClutID=0; - rfree.c[3]=min(rfree.c[3],tsb->pos.c[3]); - rfree.c[2]=max(rfree.c[2],tsb->pos.c[2]); - rfree.c[1]=min(rfree.c[1],tsb->pos.c[1]); - rfree.c[0]=max(rfree.c[0],tsb->pos.c[0]); - MarkFree(tsb); - } - - if(tsx) // 3. if one or more found, create a new rect with bigger size - { - *((uint32_t *)&gl_ux[4])=npos.l=rfree.l; - rx=(int)rfree.c[2]-(int)rfree.c[3]; - ry=(int)rfree.c[0]-(int)rfree.c[1]; - DoTexGarbageCollection(); - - goto ENDLOOP3; - } - } - - iMax=1; - } - tsx=tsg+iMax; - tsg->pos.l=iMax; - } - - //----------------------------------------------------// - // now get a free texture space - //----------------------------------------------------// - - if(iTexGarbageCollection) usLRUTexPage=0; - -ENDLOOP3: - - rx+=3;if(rx>255) {cXAdj=0;rx=255;} - ry+=3;if(ry>255) {cYAdj=0;ry=255;} - - iC=usLRUTexPage; - - for(k=0;k<iSortTexCnt;k++) - { - uls=pxSsubtexLeft[iC]; - iMax=uls->l;ul=uls+1; - - //--------------------------------------------------// - // first time - - if(!iMax) - { - rfree.l=0; - - if(rx>252 && ry>252) - {uls->l=1;ul->l=0xffffffff;ul=0;goto ENDLOOP;} - - if(rx<253) - { - uls->l=uls->l+1; - ul->c[3]=rx; - ul->c[2]=255-rx; - ul->c[1]=0; - ul->c[0]=ry; - ul++; - } - - if(ry<253) - { - uls->l=uls->l+1; - ul->c[3]=0; - ul->c[2]=255; - ul->c[1]=ry; - ul->c[0]=255-ry; - } - ul=0; - goto ENDLOOP; - } - - //--------------------------------------------------// - for(i=0;i<iMax;i++,ul++) - { - if(ul->l!=0xffffffff && - ry<=ul->c[0] && - rx<=ul->c[2]) - { - rfree=*ul; - mx=ul->c[2]-2; - my=ul->c[0]-2; - if(rx<mx && ry<my) - { - ul->c[3]+=rx; - ul->c[2]-=rx; - ul->c[0]=ry; - - for(ul=uls+1,j=0;j<iMax;j++,ul++) - if(ul->l==0xffffffff) break; - - if(j<CSUBSIZE-2) - { - if(j==iMax) uls->l=uls->l+1; - - ul->c[3]=rfree.c[3]; - ul->c[2]=rfree.c[2]; - ul->c[1]=rfree.c[1]+ry; - ul->c[0]=rfree.c[0]-ry; - } - } - else if(rx<mx) - { - ul->c[3]+=rx; - ul->c[2]-=rx; - } - else if(ry<my) - { - ul->c[1]+=ry; - ul->c[0]-=ry; - } - else - { - ul->l=0xffffffff; - } - ul=0; - goto ENDLOOP; - } - } - - //--------------------------------------------------// - - iC++; if(iC>=iSortTexCnt) iC=0; - } - - //----------------------------------------------------// - // check, if free space got - //----------------------------------------------------// - -ENDLOOP: - if(ul) - { - ////////////////////////////////////////////////////// - - { - dwTexPageComp=0; - - for(i=0;i<3;i++) // cleaning up - for(j=0;j<MAXTPAGES;j++) - { - tsb=pscSubtexStore[i][j]; - (tsb+SOFFA)->pos.l=0; - (tsb+SOFFB)->pos.l=0; - (tsb+SOFFC)->pos.l=0; - (tsb+SOFFD)->pos.l=0; - } - for(i=0;i<iSortTexCnt;i++) - {ul=pxSsubtexLeft[i];ul->l=0;} - usLRUTexPage=0; - } - - ////////////////////////////////////////////////////// - iC=usLRUTexPage; - uls=pxSsubtexLeft[usLRUTexPage]; - uls->l=0;ul=uls+1; - rfree.l=0; - - if(rx>252 && ry>252) - {uls->l=1;ul->l=0xffffffff;} - else - { - if(rx<253) - { - uls->l=uls->l+1; - ul->c[3]=rx; - ul->c[2]=255-rx; - ul->c[1]=0; - ul->c[0]=ry; - ul++; - } - if(ry<253) - { - uls->l=uls->l+1; - ul->c[3]=0; - ul->c[2]=255; - ul->c[1]=ry; - ul->c[0]=255-ry; - } - } - tsg->pos.l=1;tsx=tsg+1; - } - - rfree.c[3]+=cXAdj; - rfree.c[1]+=cYAdj; - - tsx->cTexID =*pCache=iC; - tsx->pos = npos; - tsx->ClutID = GivenClutId; - tsx->posTX = rfree.c[3]; - tsx->posTY = rfree.c[1]; - - cx=gl_ux[7]-rfree.c[3]; - cy=gl_ux[5]-rfree.c[1]; - - gl_ux[0]-=cx; - gl_ux[1]-=cx; - gl_ux[2]-=cx; - gl_ux[3]-=cx; - gl_vy[0]-=cy; - gl_vy[1]-=cy; - gl_vy[2]-=cy; - gl_vy[3]-=cy; - - XTexS=rfree.c[3]; - YTexS=rfree.c[1]; - - return &tsx->Opaque; -} - -///////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////// -// -// search cache for free place (on compress) -// -///////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////// - -static BOOL GetCompressTexturePlace(textureSubCacheEntryS * tsx) -{ - int i,j,k,iMax,iC;uint32_t rx,ry,mx,my; - EXLong * ul=0, * uls, rfree; - unsigned char cXAdj=1,cYAdj=1; - - rx=(int)tsx->pos.c[2]-(int)tsx->pos.c[3]; - ry=(int)tsx->pos.c[0]-(int)tsx->pos.c[1]; - - rx+=3;if(rx>255) {cXAdj=0;rx=255;} - ry+=3;if(ry>255) {cYAdj=0;ry=255;} - - iC=usLRUTexPage; - - for(k=0;k<iSortTexCnt;k++) - { - uls=pxSsubtexLeft[iC]; - iMax=uls->l;ul=uls+1; - - //--------------------------------------------------// - // first time - - if(!iMax) - { - rfree.l=0; - - if(rx>252 && ry>252) - {uls->l=1;ul->l=0xffffffff;ul=0;goto TENDLOOP;} - - if(rx<253) - { - uls->l=uls->l+1; - ul->c[3]=rx; - ul->c[2]=255-rx; - ul->c[1]=0; - ul->c[0]=ry; - ul++; - } - - if(ry<253) - { - uls->l=uls->l+1; - ul->c[3]=0; - ul->c[2]=255; - ul->c[1]=ry; - ul->c[0]=255-ry; - } - ul=0; - goto TENDLOOP; - } - - //--------------------------------------------------// - for(i=0;i<iMax;i++,ul++) - { - if(ul->l!=0xffffffff && - ry<=ul->c[0] && - rx<=ul->c[2]) - { - rfree=*ul; - mx=ul->c[2]-2; - my=ul->c[0]-2; - - if(rx<mx && ry<my) - { - ul->c[3]+=rx; - ul->c[2]-=rx; - ul->c[0]=ry; - - for(ul=uls+1,j=0;j<iMax;j++,ul++) - if(ul->l==0xffffffff) break; - - if(j<CSUBSIZE-2) - { - if(j==iMax) uls->l=uls->l+1; - - ul->c[3]=rfree.c[3]; - ul->c[2]=rfree.c[2]; - ul->c[1]=rfree.c[1]+ry; - ul->c[0]=rfree.c[0]-ry; - } - } - else if(rx<mx) - { - ul->c[3]+=rx; - ul->c[2]-=rx; - } - else if(ry<my) - { - ul->c[1]+=ry; - ul->c[0]-=ry; - } - else - { - ul->l=0xffffffff; - } - ul=0; - goto TENDLOOP; - } - } - - //--------------------------------------------------// - - iC++; if(iC>=iSortTexCnt) iC=0; - } - - //----------------------------------------------------// - // check, if free space got - //----------------------------------------------------// - -TENDLOOP: - if(ul) return FALSE; - - rfree.c[3]+=cXAdj; - rfree.c[1]+=cYAdj; - - tsx->cTexID = iC; - tsx->posTX = rfree.c[3]; - tsx->posTY = rfree.c[1]; - - XTexS=rfree.c[3]; - YTexS=rfree.c[1]; - - return TRUE; -} - -///////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////// -// -// compress texture cache (to make place for new texture part, if needed) -// -///////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////// - -static void CompressTextureSpace(void) -{ - textureSubCacheEntryS * tsx, * tsg, * tsb; - int i,j,k,m,n,iMax;EXLong * ul, r,opos; - short sOldDST=DrawSemiTrans,cx,cy; - int lOGTP=GlobalTexturePage; - uint32_t l,row; - uint32_t *lSRCPtr; - - opos.l=*((uint32_t *)&gl_ux[4]); - - // 1. mark all textures as free - for(i=0;i<iSortTexCnt;i++) - {ul=pxSsubtexLeft[i];ul->l=0;} - usLRUTexPage=0; - - // 2. compress - for(j=0;j<3;j++) - { - for(k=0;k<MAXTPAGES;k++) - { - tsg=pscSubtexStore[j][k]; - - if((!(dwTexPageComp&(1<<k)))) - { - (tsg+SOFFA)->pos.l=0; - (tsg+SOFFB)->pos.l=0; - (tsg+SOFFC)->pos.l=0; - (tsg+SOFFD)->pos.l=0; - continue; - } - - for(m=0;m<4;m++,tsg+=SOFFB) - { - iMax=tsg->pos.l; - - tsx=tsg+1; - for(i=0;i<iMax;i++,tsx++) - { - if(tsx->ClutID) - { - r.l=tsx->pos.l; - for(n=i+1,tsb=tsx+1;n<iMax;n++,tsb++) - { - if(tsx->ClutID==tsb->ClutID) - { - r.c[3]=min(r.c[3],tsb->pos.c[3]); - r.c[2]=max(r.c[2],tsb->pos.c[2]); - r.c[1]=min(r.c[1],tsb->pos.c[1]); - r.c[0]=max(r.c[0],tsb->pos.c[0]); - tsb->ClutID=0; - } - } - -// if(r.l!=tsx->pos.l) - { - cx=((tsx->ClutID << 4) & 0x3F0); - cy=((tsx->ClutID >> 6) & CLUTYMASK); - - if(j!=2) - { - // palette check sum - l=0;lSRCPtr=(uint32_t *)(psxVuw+cx+(cy*1024)); - if(j==1) for(row=1;row<129;row++) l+=((*lSRCPtr++)-1)*row; - else for(row=1;row<9;row++) l+=((*lSRCPtr++)-1)<<row; - l=((l+HIWORD(l))&0x3fffL)<<16; - if(l!=(tsx->ClutID&(0x00003fff<<16))) - { - tsx->ClutID=0;continue; - } - } - - tsx->pos.l=r.l; - if(!GetCompressTexturePlace(tsx)) // no place? - { - for(i=0;i<3;i++) // -> clean up everything - for(j=0;j<MAXTPAGES;j++) - { - tsb=pscSubtexStore[i][j]; - (tsb+SOFFA)->pos.l=0; - (tsb+SOFFB)->pos.l=0; - (tsb+SOFFC)->pos.l=0; - (tsb+SOFFD)->pos.l=0; - } - for(i=0;i<iSortTexCnt;i++) - {ul=pxSsubtexLeft[i];ul->l=0;} - usLRUTexPage=0; - DrawSemiTrans=sOldDST; - GlobalTexturePage=lOGTP; - *((uint32_t *)&gl_ux[4])=opos.l; - dwTexPageComp=0; - - return; - } - - if(tsx->ClutID&(1<<30)) DrawSemiTrans=1; - else DrawSemiTrans=0; - *((uint32_t *)&gl_ux[4])=r.l; - - gTexName=uiStexturePage[tsx->cTexID]; - LoadSubTexFn(k,j,cx,cy); - uiStexturePage[tsx->cTexID]=gTexName; - tsx->Opaque=ubOpaqueDraw; - } - } - } - - if(iMax) - { - tsx=tsg+iMax; - while(!tsx->ClutID && iMax) {tsx--;iMax--;} - tsg->pos.l=iMax; - } - - } - } - } - - if(dwTexPageComp==0xffffffff) dwTexPageComp=0; - - *((uint32_t *)&gl_ux[4])=opos.l; - GlobalTexturePage=lOGTP; - DrawSemiTrans=sOldDST; -} - -///////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////// -// -// main entry for searching/creating textures, called from prim.c -// -///////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////// - -GLuint SelectSubTextureS(int TextureMode, uint32_t GivenClutId) -{ - unsigned char * OPtr;unsigned short iCache;short cx,cy; - - // sort sow/tow infos for fast access - - unsigned char ma1,ma2,mi1,mi2; - if(gl_ux[0]>gl_ux[1]) {mi1=gl_ux[1];ma1=gl_ux[0];} - else {mi1=gl_ux[0];ma1=gl_ux[1];} - if(gl_ux[2]>gl_ux[3]) {mi2=gl_ux[3];ma2=gl_ux[2];} - else {mi2=gl_ux[2];ma2=gl_ux[3];} - if(mi1>mi2) gl_ux[7]=mi2; - else gl_ux[7]=mi1; - if(ma1>ma2) gl_ux[6]=ma1; - else gl_ux[6]=ma2; - - if(gl_vy[0]>gl_vy[1]) {mi1=gl_vy[1];ma1=gl_vy[0];} - else {mi1=gl_vy[0];ma1=gl_vy[1];} - if(gl_vy[2]>gl_vy[3]) {mi2=gl_vy[3];ma2=gl_vy[2];} - else {mi2=gl_vy[2];ma2=gl_vy[3];} - if(mi1>mi2) gl_ux[5]=mi2; - else gl_ux[5]=mi1; - if(ma1>ma2) gl_ux[4]=ma1; - else gl_ux[4]=ma2; - - // get clut infos in one 32 bit val - - if(TextureMode==2) // no clut here - { - GivenClutId=CLUTUSED|(DrawSemiTrans<<30);cx=cy=0; - - if(iFrameTexType && Fake15BitTexture()) - return (GLuint)gTexName; - } - else - { - cx=((GivenClutId << 4) & 0x3F0); // but here - cy=((GivenClutId >> 6) & CLUTYMASK); - GivenClutId=(GivenClutId&CLUTMASK)|(DrawSemiTrans<<30)|CLUTUSED; - - // palette check sum.. removed MMX asm, this easy func works as well - { - uint32_t l=0,row; - - uint32_t *lSRCPtr = (uint32_t *)(psxVuw+cx+(cy*1024)); - if(TextureMode==1) for(row=1;row<129;row++) l+=((*lSRCPtr++)-1)*row; - else for(row=1;row<9;row++) l+=((*lSRCPtr++)-1)<<row; - l=(l+HIWORD(l))&0x3fffL; - GivenClutId|=(l<<16); - } - - } - - // search cache - iCache=0; - OPtr=CheckTextureInSubSCache(TextureMode,GivenClutId,&iCache); - - // cache full? compress and try again - if(iCache==0xffff) - { - CompressTextureSpace(); - OPtr=CheckTextureInSubSCache(TextureMode,GivenClutId,&iCache); - } - - // found? fine - usLRUTexPage=iCache; - if(!OPtr) return uiStexturePage[iCache]; - - // not found? upload texture and store infos in cache - gTexName=uiStexturePage[iCache]; - LoadSubTexFn(GlobalTexturePage,TextureMode,cx,cy); - uiStexturePage[iCache]=gTexName; - *OPtr=ubOpaqueDraw; - return (GLuint) gTexName; -} - -///////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////// +/***************************************************************************
+ texture.c - description
+ -------------------
+ begin : Sun Mar 08 2009
+ copyright : (C) 1999-2009 by Pete Bernert
+ web : www.pbernert.com
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. See also the license.txt file for *
+ * additional informations. *
+ * *
+ ***************************************************************************/
+
+#include "stdafx.h"
+
+////////////////////////////////////////////////////////////////////////////////////
+// Texture related functions are here !
+//
+// The texture handling is heart and soul of this gpu. The plugin was developed
+// 1999, by this time no shaders were available. Since the psx gpu is making
+// heavy use of CLUT (="color lookup tables", aka palettized textures), it was
+// an interesting task to get those emulated at good speed on NV TNT cards
+// (which was my major goal when I created the first "gpuPeteTNT"). Later cards
+// (Geforce256) supported texture palettes by an OGL extension, but at some point
+// this support was dropped again by gfx card vendors.
+// Well, at least there is a certain advatage, if no texture palettes extension can
+// be used: it is possible to modify the textures in any way, allowing "hi-res"
+// textures and other tweaks.
+//
+// My main texture caching is kinda complex: the plugin is allocating "n" 256x256 textures,
+// and it places small psx texture parts inside them. The plugin keeps track what
+// part (with what palette) it had placed in which texture, so it can re-use this
+// part again. The more ogl textures it can use, the better (of course the managing/
+// searching will be slower, but everything is faster than uploading textures again
+// and again to a gfx card). My first card (TNT1) had 16 MB Vram, and it worked
+// well with many games, but I recommend nowadays 64 MB Vram to get a good speed.
+//
+// Sadly, there is also a second kind of texture cache needed, for "psx texture windows".
+// Those are "repeated" textures, so a psx "texture window" needs to be put in
+// a whole texture to use the GL_TEXTURE_WRAP_ features. This cache can get full very
+// fast in games which are having an heavy "texture window" usage, like RRT4. As an
+// alternative, this plugin can use the OGL "palette" extension on texture windows,
+// if available. Nowadays also a fragment shader can easily be used to emulate
+// texture wrapping in a texture atlas, so the main cache could hold the texture
+// windows as well (that's what I am doing in the OGL2 plugin). But currently the
+// OGL1 plugin is a "shader-free" zone, so heavy "texture window" games will cause
+// much texture uploads.
+//
+// Some final advice: take care if you change things in here. I've removed my ASM
+// handlers (they didn't cause much speed gain anyway) for readability/portability,
+// but still the functions/data structures used here are easy to mess up. I guess it
+// can be a pain in the ass to port the plugin to another byte order :)
+//
+////////////////////////////////////////////////////////////////////////////////////
+
+#define _IN_TEXTURE
+
+#include "externals.h"
+#include "texture.h"
+#include "gpu.h"
+#include "prim.h"
+
+#define CLUTCHK 0x00060000
+#define CLUTSHIFT 17
+
+////////////////////////////////////////////////////////////////////////
+// texture conversion buffer ..
+////////////////////////////////////////////////////////////////////////
+
+int iHiResTextures=0;
+GLubyte ubPaletteBuffer[256][4];
+GLuint gTexMovieName=0;
+GLuint gTexBlurName=0;
+GLuint gTexFrameName=0;
+int iTexGarbageCollection=1;
+uint32_t dwTexPageComp=0;
+int iVRamSize=0;
+int iClampType=GL_CLAMP;
+
+void (*LoadSubTexFn) (int,int,short,short);
+uint32_t (*PalTexturedColourFn) (uint32_t);
+
+////////////////////////////////////////////////////////////////////////
+// defines
+////////////////////////////////////////////////////////////////////////
+
+#define PALCOL(x) PalTexturedColourFn (x)
+
+#define CSUBSIZE 2048
+#define CSUBSIZEA 8192
+#define CSUBSIZES 4096
+
+#define OFFA 0
+#define OFFB 2048
+#define OFFC 4096
+#define OFFD 6144
+
+#define XOFFA 0
+#define XOFFB 512
+#define XOFFC 1024
+#define XOFFD 1536
+
+#define SOFFA 0
+#define SOFFB 1024
+#define SOFFC 2048
+#define SOFFD 3072
+
+#define MAXWNDTEXCACHE 128
+
+#define XCHECK(pos1,pos2) ((pos1.c[0]>=pos2.c[1])&&(pos1.c[1]<=pos2.c[0])&&(pos1.c[2]>=pos2.c[3])&&(pos1.c[3]<=pos2.c[2]))
+#define INCHECK(pos2,pos1) ((pos1.c[0]<=pos2.c[0]) && (pos1.c[1]>=pos2.c[1]) && (pos1.c[2]<=pos2.c[2]) && (pos1.c[3]>=pos2.c[3]))
+
+////////////////////////////////////////////////////////////////////////
+
+unsigned char * CheckTextureInSubSCache(int TextureMode, uint32_t GivenClutId, unsigned short *pCache);
+void LoadSubTexturePageSort(int pageid, int mode, short cx, short cy);
+void LoadPackedSubTexturePageSort(int pageid, int mode, short cx, short cy);
+void DefineSubTextureSort(void);
+
+////////////////////////////////////////////////////////////////////////
+// some globals
+////////////////////////////////////////////////////////////////////////
+
+GLint giWantedRGBA=4;
+GLint giWantedFMT=GL_RGBA;
+GLint giWantedTYPE=GL_UNSIGNED_BYTE;
+int GlobalTexturePage;
+GLint XTexS;
+GLint YTexS;
+GLint DXTexS;
+GLint DYTexS;
+int iSortTexCnt=32;
+BOOL bUseFastMdec=FALSE;
+BOOL bUse15bitMdec=FALSE;
+int iFrameTexType=0;
+int iFrameReadType=0;
+
+uint32_t (*TCF[2]) (uint32_t);
+unsigned short (*PTCF[2]) (unsigned short);
+
+////////////////////////////////////////////////////////////////////////
+// texture cache implementation
+////////////////////////////////////////////////////////////////////////
+
+#ifdef _WINDOWS
+#pragma pack(1)
+#endif
+
+// "texture window" cache entry
+
+typedef struct textureWndCacheEntryTag
+{
+ uint32_t ClutID;
+ short pageid;
+ short textureMode;
+ short Opaque;
+ short used;
+ EXLong pos;
+ GLuint texname;
+} textureWndCacheEntry;
+
+// "standard texture" cache entry (12 byte per entry, as small as possible... we need lots of them)
+
+typedef struct textureSubCacheEntryTagS
+{
+ uint32_t ClutID;
+ EXLong pos;
+ unsigned char posTX;
+ unsigned char posTY;
+ unsigned char cTexID;
+ unsigned char Opaque;
+} textureSubCacheEntryS;
+
+#ifdef _WINDOWS
+#pragma pack()
+#endif
+
+//---------------------------------------------
+
+#define MAXTPAGES_MAX 64
+#define MAXSORTTEX_MAX 196
+
+//---------------------------------------------
+
+textureWndCacheEntry wcWndtexStore[MAXWNDTEXCACHE];
+textureSubCacheEntryS * pscSubtexStore[3][MAXTPAGES_MAX];
+EXLong * pxSsubtexLeft [MAXSORTTEX_MAX];
+GLuint uiStexturePage[MAXSORTTEX_MAX];
+
+unsigned short usLRUTexPage = 0;
+
+int iMaxTexWnds = 0;
+int iTexWndTurn = 0;
+int iTexWndLimit = MAXWNDTEXCACHE/2;
+
+GLubyte * texturepart = NULL;
+GLubyte * texturebuffer = NULL;
+uint32_t g_x1,g_y1,g_x2,g_y2;
+unsigned char ubOpaqueDraw = 0;
+
+unsigned short MAXTPAGES = 32;
+unsigned short CLUTMASK = 0x7fff;
+unsigned short CLUTYMASK = 0x1ff;
+unsigned short MAXSORTTEX = 196;
+
+////////////////////////////////////////////////////////////////////////
+// Texture color conversions... all my ASM funcs are removed for easier
+// porting... and honestly: nowadays the speed gain would be pointless
+////////////////////////////////////////////////////////////////////////
+
+uint32_t XP8RGBA(uint32_t BGR)
+{
+ if(!(BGR&0xffff)) return 0x50000000;
+ if(DrawSemiTrans && !(BGR&0x8000))
+ {ubOpaqueDraw=1;return ((((BGR<<3)&0xf8)|((BGR<<6)&0xf800)|((BGR<<9)&0xf80000))&0xffffff);}
+ return ((((BGR<<3)&0xf8)|((BGR<<6)&0xf800)|((BGR<<9)&0xf80000))&0xffffff)|0xff000000;
+}
+
+uint32_t XP8RGBAEx(uint32_t BGR)
+{
+ if(!(BGR&0xffff)) return 0x03000000;
+ if(DrawSemiTrans && !(BGR&0x8000))
+ {ubOpaqueDraw=1;return ((((BGR<<3)&0xf8)|((BGR<<6)&0xf800)|((BGR<<9)&0xf80000))&0xffffff);}
+ return ((((BGR<<3)&0xf8)|((BGR<<6)&0xf800)|((BGR<<9)&0xf80000))&0xffffff)|0xff000000;
+}
+
+uint32_t CP8RGBA(uint32_t BGR)
+{
+ uint32_t l;
+ if(!(BGR&0xffff)) return 0x50000000;
+ if(DrawSemiTrans && !(BGR&0x8000))
+ {ubOpaqueDraw=1;return ((((BGR<<3)&0xf8)|((BGR<<6)&0xf800)|((BGR<<9)&0xf80000))&0xffffff);}
+ l=((((BGR<<3)&0xf8)|((BGR<<6)&0xf800)|((BGR<<9)&0xf80000))&0xffffff)|0xff000000;
+ if(l==0xffffff00) l=0xff000000;
+ return l;
+}
+
+uint32_t CP8RGBAEx(uint32_t BGR)
+{
+ uint32_t l;
+ if(!(BGR&0xffff)) return 0x03000000;
+ if(DrawSemiTrans && !(BGR&0x8000))
+ {ubOpaqueDraw=1;return ((((BGR<<3)&0xf8)|((BGR<<6)&0xf800)|((BGR<<9)&0xf80000))&0xffffff);}
+ l=((((BGR<<3)&0xf8)|((BGR<<6)&0xf800)|((BGR<<9)&0xf80000))&0xffffff)|0xff000000;
+ if(l==0xffffff00) l=0xff000000;
+ return l;
+}
+
+uint32_t XP8RGBA_0(uint32_t BGR)
+{
+ if(!(BGR&0xffff)) return 0x50000000;
+ return ((((BGR<<3)&0xf8)|((BGR<<6)&0xf800)|((BGR<<9)&0xf80000))&0xffffff)|0xff000000;
+}
+
+uint32_t XP8RGBAEx_0(uint32_t BGR)
+{
+ if(!(BGR&0xffff)) return 0x03000000;
+ return ((((BGR<<3)&0xf8)|((BGR<<6)&0xf800)|((BGR<<9)&0xf80000))&0xffffff)|0xff000000;
+}
+
+uint32_t XP8BGRA_0(uint32_t BGR)
+{
+ if(!(BGR&0xffff)) return 0x50000000;
+ return ((((BGR>>7)&0xf8)|((BGR<<6)&0xf800)|((BGR<<19)&0xf80000))&0xffffff)|0xff000000;
+}
+
+uint32_t XP8BGRAEx_0(uint32_t BGR)
+{
+ if(!(BGR&0xffff)) return 0x03000000;
+ return ((((BGR>>7)&0xf8)|((BGR<<6)&0xf800)|((BGR<<19)&0xf80000))&0xffffff)|0xff000000;
+}
+
+uint32_t CP8RGBA_0(uint32_t BGR)
+{
+ uint32_t l;
+
+ if(!(BGR&0xffff)) return 0x50000000;
+ l=((((BGR<<3)&0xf8)|((BGR<<6)&0xf800)|((BGR<<9)&0xf80000))&0xffffff)|0xff000000;
+ if(l==0xfff8f800) l=0xff000000;
+ return l;
+}
+
+uint32_t CP8RGBAEx_0(uint32_t BGR)
+{
+ uint32_t l;
+
+ if(!(BGR&0xffff)) return 0x03000000;
+ l=((((BGR<<3)&0xf8)|((BGR<<6)&0xf800)|((BGR<<9)&0xf80000))&0xffffff)|0xff000000;
+ if(l==0xfff8f800) l=0xff000000;
+ return l;
+}
+
+uint32_t CP8BGRA_0(uint32_t BGR)
+{
+ uint32_t l;
+
+ if(!(BGR&0xffff)) return 0x50000000;
+ l=((((BGR>>7)&0xf8)|((BGR<<6)&0xf800)|((BGR<<19)&0xf80000))&0xffffff)|0xff000000;
+ if(l==0xff00f8f8) l=0xff000000;
+ return l;
+}
+
+uint32_t CP8BGRAEx_0(uint32_t BGR)
+{
+ uint32_t l;
+
+ if(!(BGR&0xffff)) return 0x03000000;
+ l=((((BGR>>7)&0xf8)|((BGR<<6)&0xf800)|((BGR<<19)&0xf80000))&0xffffff)|0xff000000;
+ if(l==0xff00f8f8) l=0xff000000;
+ return l;
+}
+
+uint32_t XP8RGBA_1(uint32_t BGR)
+{
+ if(!(BGR&0xffff)) return 0x50000000;
+ if(!(BGR&0x8000)) {ubOpaqueDraw=1;return ((((BGR<<3)&0xf8)|((BGR<<6)&0xf800)|((BGR<<9)&0xf80000))&0xffffff);}
+ return ((((BGR<<3)&0xf8)|((BGR<<6)&0xf800)|((BGR<<9)&0xf80000))&0xffffff)|0xff000000;
+}
+
+uint32_t XP8RGBAEx_1(uint32_t BGR)
+{
+ if(!(BGR&0xffff)) return 0x03000000;
+ if(!(BGR&0x8000)) {ubOpaqueDraw=1;return ((((BGR<<3)&0xf8)|((BGR<<6)&0xf800)|((BGR<<9)&0xf80000))&0xffffff);}
+ return ((((BGR<<3)&0xf8)|((BGR<<6)&0xf800)|((BGR<<9)&0xf80000))&0xffffff)|0xff000000;
+}
+
+uint32_t XP8BGRA_1(uint32_t BGR)
+{
+ if(!(BGR&0xffff)) return 0x50000000;
+ if(!(BGR&0x8000)) {ubOpaqueDraw=1;return ((((BGR>>7)&0xf8)|((BGR<<6)&0xf800)|((BGR<<19)&0xf80000))&0xffffff);}
+ return ((((BGR>>7)&0xf8)|((BGR<<6)&0xf800)|((BGR<<19)&0xf80000))&0xffffff)|0xff000000;
+}
+
+uint32_t XP8BGRAEx_1(uint32_t BGR)
+{
+ if(!(BGR&0xffff)) return 0x03000000;
+ if(!(BGR&0x8000)) {ubOpaqueDraw=1;return ((((BGR>>7)&0xf8)|((BGR<<6)&0xf800)|((BGR<<19)&0xf80000))&0xffffff);}
+ return ((((BGR>>7)&0xf8)|((BGR<<6)&0xf800)|((BGR<<19)&0xf80000))&0xffffff)|0xff000000;
+}
+
+uint32_t P8RGBA(uint32_t BGR)
+{
+ if(!(BGR&0xffff)) return 0;
+ return ((((BGR<<3)&0xf8)|((BGR<<6)&0xf800)|((BGR<<9)&0xf80000))&0xffffff)|0xff000000;
+}
+
+uint32_t P8BGRA(uint32_t BGR)
+{
+ if(!(BGR&0xffff)) return 0;
+ return ((((BGR>>7)&0xf8)|((BGR<<6)&0xf800)|((BGR<<19)&0xf80000))&0xffffff)|0xff000000;
+}
+
+unsigned short XP5RGBA(unsigned short BGR)
+{
+ if(!BGR) return 0;
+ if(DrawSemiTrans && !(BGR&0x8000))
+ {ubOpaqueDraw=1;return ((((BGR<<11))|((BGR>>9)&0x3e)|((BGR<<1)&0x7c0)));}
+ return ((((BGR<<11))|((BGR>>9)&0x3e)|((BGR<<1)&0x7c0)))|1;
+}
+
+unsigned short XP5RGBA_0 (unsigned short BGR)
+{
+ if(!BGR) return 0;
+
+ return ((((BGR<<11))|((BGR>>9)&0x3e)|((BGR<<1)&0x7c0)))|1;
+}
+
+unsigned short CP5RGBA_0 (unsigned short BGR)
+{
+ unsigned short s;
+
+ if(!BGR) return 0;
+
+ s=((((BGR<<11))|((BGR>>9)&0x3e)|((BGR<<1)&0x7c0)))|1;
+ if(s==0x07ff) s=1;
+ return s;
+}
+
+unsigned short XP5RGBA_1(unsigned short BGR)
+{
+ if(!BGR) return 0;
+ if(!(BGR&0x8000))
+ {ubOpaqueDraw=1;return ((((BGR<<11))|((BGR>>9)&0x3e)|((BGR<<1)&0x7c0)));}
+ return ((((BGR<<11))|((BGR>>9)&0x3e)|((BGR<<1)&0x7c0)))|1;
+}
+
+unsigned short P5RGBA(unsigned short BGR)
+{
+ if(!BGR) return 0;
+ return ((((BGR<<11))|((BGR>>9)&0x3e)|((BGR<<1)&0x7c0)))|1;
+}
+
+unsigned short XP4RGBA(unsigned short BGR)
+{
+ if(!BGR) return 6;
+ if(DrawSemiTrans && !(BGR&0x8000))
+ {ubOpaqueDraw=1;return ((((BGR<<11))|((BGR>>9)&0x3e)|((BGR<<1)&0x7c0)));}
+ return (((((BGR&0x1e)<<11))|((BGR&0x7800)>>7)|((BGR&0x3c0)<<2)))|0xf;
+}
+
+unsigned short XP4RGBA_0 (unsigned short BGR)
+{
+ if(!BGR) return 6;
+ return (((((BGR&0x1e)<<11))|((BGR&0x7800)>>7)|((BGR&0x3c0)<<2)))|0xf;
+}
+
+unsigned short CP4RGBA_0 (unsigned short BGR)
+{
+ unsigned short s;
+ if(!BGR) return 6;
+ s=(((((BGR&0x1e)<<11))|((BGR&0x7800)>>7)|((BGR&0x3c0)<<2)))|0xf;
+ if(s==0x0fff) s=0x000f;
+ return s;
+}
+
+unsigned short XP4RGBA_1(unsigned short BGR)
+{
+ if(!BGR) return 6;
+ if(!(BGR&0x8000))
+ {ubOpaqueDraw=1;return ((((BGR<<11))|((BGR>>9)&0x3e)|((BGR<<1)&0x7c0)));}
+ return (((((BGR&0x1e)<<11))|((BGR&0x7800)>>7)|((BGR&0x3c0)<<2)))|0xf;
+}
+
+unsigned short P4RGBA(unsigned short BGR)
+{
+ if(!BGR) return 0;
+ return (((((BGR&0x1e)<<11))|((BGR&0x7800)>>7)|((BGR&0x3c0)<<2)))|0xf;
+}
+
+////////////////////////////////////////////////////////////////////////
+// CHECK TEXTURE MEM (on plugin startup)
+////////////////////////////////////////////////////////////////////////
+
+int iFTexA=512;
+int iFTexB=512;
+
+void CheckTextureMemory(void)
+{
+ GLboolean b;GLboolean * bDetail;
+ int i,iCnt,iRam=iVRamSize*1024*1024;
+ int iTSize;char * p;
+
+ if(iBlurBuffer)
+ {
+ char * p;
+
+ if(iResX>1024) iFTexA=2048;
+ else
+ if(iResX>512) iFTexA=1024;
+ else iFTexA=512;
+ if(iResY>1024) iFTexB=2048;
+ else
+ if(iResY>512) iFTexB=1024;
+ else iFTexB=512;
+
+ glGenTextures(1, &gTexBlurName);
+ gTexName=gTexBlurName;
+ glBindTexture(GL_TEXTURE_2D, gTexName);
+
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+
+ p=(char *)malloc(iFTexA*iFTexB*4);
+ memset(p,0,iFTexA*iFTexB*4);
+ glTexImage2D(GL_TEXTURE_2D, 0, 3, iFTexA, iFTexB, 0, GL_RGB, GL_UNSIGNED_BYTE, p);
+ free(p);
+ glGetError();
+ iRam-=iFTexA*iFTexB*3;
+ iFTexA=(iResX*256)/iFTexA;
+ iFTexB=(iResY*256)/iFTexB;
+ }
+
+ if(iVRamSize)
+ {
+ int ts;
+
+ iRam-=(iResX*iResY*8);
+ iRam-=(iResX*iResY*(iZBufferDepth/8));
+
+ if(iTexQuality==0 || iTexQuality==3) ts=4;
+ else ts=2;
+
+ if(iHiResTextures)
+ iSortTexCnt=iRam/(512*512*ts);
+ else iSortTexCnt=iRam/(256*256*ts);
+
+ if(iSortTexCnt>MAXSORTTEX)
+ {
+ iSortTexCnt=MAXSORTTEX-min(1,iHiResTextures);
+ }
+ else
+ {
+ iSortTexCnt-=3+min(1,iHiResTextures);
+ if(iSortTexCnt<8) iSortTexCnt=8;
+ }
+
+ for(i=0;i<MAXSORTTEX;i++)
+ uiStexturePage[i]=0;
+
+ return;
+ }
+
+
+ if(iHiResTextures) iTSize=512;
+ else iTSize=256;
+ p=(char *)malloc(iTSize*iTSize*4);
+
+ iCnt=0;
+ glGenTextures(MAXSORTTEX,uiStexturePage);
+ for(i=0;i<MAXSORTTEX;i++)
+ {
+ glBindTexture(GL_TEXTURE_2D,uiStexturePage[i]);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, iClampType);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, iClampType);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexImage2D(GL_TEXTURE_2D, 0, giWantedRGBA, iTSize, iTSize, 0,GL_RGBA, giWantedTYPE, p);
+ }
+ glBindTexture(GL_TEXTURE_2D,0);
+
+ free(p);
+
+ bDetail=malloc(MAXSORTTEX*sizeof(GLboolean));
+ memset(bDetail,0,MAXSORTTEX*sizeof(GLboolean));
+ b=glAreTexturesResident(MAXSORTTEX,uiStexturePage,bDetail);
+
+ glDeleteTextures(MAXSORTTEX,uiStexturePage);
+
+ for(i=0;i<MAXSORTTEX;i++)
+ {
+ if(bDetail[i]) iCnt++;
+ uiStexturePage[i]=0;
+ }
+
+ free(bDetail);
+
+ if(b) iSortTexCnt=MAXSORTTEX-min(1,iHiResTextures);
+ else iSortTexCnt=iCnt-3+min(1,iHiResTextures); // place for menu&texwnd
+
+ if(iSortTexCnt<8) iSortTexCnt=8;
+}
+
+////////////////////////////////////////////////////////////////////////
+// Main init of textures
+////////////////////////////////////////////////////////////////////////
+
+void InitializeTextureStore()
+{
+ int i,j;
+
+ if(iGPUHeight==1024)
+ {
+ MAXTPAGES = 64;
+ CLUTMASK = 0xffff;
+ CLUTYMASK = 0x3ff;
+ MAXSORTTEX = 128;
+ iTexGarbageCollection=0;
+ }
+ else
+ {
+ MAXTPAGES = 32;
+ CLUTMASK = 0x7fff;
+ CLUTYMASK = 0x1ff;
+ MAXSORTTEX = 196;
+ }
+
+ memset(vertex,0,4*sizeof(OGLVertex)); // init vertices
+
+ gTexName=0; // init main tex name
+
+ iTexWndLimit=MAXWNDTEXCACHE;
+ if(!iUsePalTextures) iTexWndLimit/=2;
+
+ memset(wcWndtexStore,0,sizeof(textureWndCacheEntry)*
+ MAXWNDTEXCACHE);
+ texturepart=(GLubyte *)malloc(256*256*4);
+ memset(texturepart,0,256*256*4);
+ if(iHiResTextures)
+ texturebuffer=(GLubyte *)malloc(512*512*4);
+ else texturebuffer=NULL;
+
+ for(i=0;i<3;i++) // -> info for 32*3
+ for(j=0;j<MAXTPAGES;j++)
+ {
+ pscSubtexStore[i][j]=(textureSubCacheEntryS *)malloc(CSUBSIZES*sizeof(textureSubCacheEntryS));
+ memset(pscSubtexStore[i][j],0,CSUBSIZES*sizeof(textureSubCacheEntryS));
+ }
+ for(i=0;i<MAXSORTTEX;i++) // -> info 0..511
+ {
+ pxSsubtexLeft[i]=(EXLong *)malloc(CSUBSIZE*sizeof(EXLong));
+ memset(pxSsubtexLeft[i],0,CSUBSIZE*sizeof(EXLong));
+ uiStexturePage[i]=0;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+// Clean up on exit
+////////////////////////////////////////////////////////////////////////
+
+void CleanupTextureStore()
+{
+ int i,j;textureWndCacheEntry * tsx;
+ //----------------------------------------------------//
+ glBindTexture(GL_TEXTURE_2D,0);
+ //----------------------------------------------------//
+ free(texturepart); // free tex part
+ texturepart=0;
+ if(texturebuffer)
+ {
+ free(texturebuffer);
+ texturebuffer=0;
+ }
+ //----------------------------------------------------//
+ tsx=wcWndtexStore; // loop tex window cache
+ for(i=0;i<MAXWNDTEXCACHE;i++,tsx++)
+ {
+ if(tsx->texname) // -> some tex?
+ glDeleteTextures(1,&tsx->texname); // --> delete it
+ }
+ iMaxTexWnds=0; // no more tex wnds
+ //----------------------------------------------------//
+ if(gTexMovieName!=0) // some movie tex?
+ glDeleteTextures(1, &gTexMovieName); // -> delete it
+ gTexMovieName=0; // no more movie tex
+ //----------------------------------------------------//
+ if(gTexFrameName!=0) // some 15bit framebuffer tex?
+ glDeleteTextures(1, &gTexFrameName); // -> delete it
+ gTexFrameName=0; // no more movie tex
+ //----------------------------------------------------//
+ if(gTexBlurName!=0) // some 15bit framebuffer tex?
+ glDeleteTextures(1, &gTexBlurName); // -> delete it
+ gTexBlurName=0; // no more movie tex
+ //----------------------------------------------------//
+ for(i=0;i<3;i++) // -> loop
+ for(j=0;j<MAXTPAGES;j++) // loop tex pages
+ {
+ free(pscSubtexStore[i][j]); // -> clean mem
+ }
+ for(i=0;i<MAXSORTTEX;i++)
+ {
+ if(uiStexturePage[i]) // --> tex used ?
+ {
+ glDeleteTextures(1,&uiStexturePage[i]);
+ uiStexturePage[i]=0; // --> delete it
+ }
+ free(pxSsubtexLeft[i]); // -> clean mem
+ }
+ //----------------------------------------------------//
+}
+
+////////////////////////////////////////////////////////////////////////
+// Reset textures in game...
+////////////////////////////////////////////////////////////////////////
+
+void ResetTextureArea(BOOL bDelTex)
+{
+ int i,j;textureSubCacheEntryS * tss;EXLong * lu;
+ textureWndCacheEntry * tsx;
+ //----------------------------------------------------//
+
+ dwTexPageComp=0;
+
+ //----------------------------------------------------//
+ if(bDelTex) {glBindTexture(GL_TEXTURE_2D,0);gTexName=0;}
+ //----------------------------------------------------//
+ tsx=wcWndtexStore;
+ for(i=0;i<MAXWNDTEXCACHE;i++,tsx++)
+ {
+ tsx->used=0;
+ if(bDelTex && tsx->texname)
+ {
+ glDeleteTextures(1,&tsx->texname);
+ tsx->texname=0;
+ }
+ }
+ iMaxTexWnds=0;
+ //----------------------------------------------------//
+
+ for(i=0;i<3;i++)
+ for(j=0;j<MAXTPAGES;j++)
+ {
+ tss=pscSubtexStore[i][j];
+ (tss+SOFFA)->pos.l=0;
+ (tss+SOFFB)->pos.l=0;
+ (tss+SOFFC)->pos.l=0;
+ (tss+SOFFD)->pos.l=0;
+ }
+
+ for(i=0;i<iSortTexCnt;i++)
+ {
+ lu=pxSsubtexLeft[i];
+ lu->l=0;
+ if(bDelTex && uiStexturePage[i])
+ {glDeleteTextures(1,&uiStexturePage[i]);uiStexturePage[i]=0;}
+ }
+}
+
+
+////////////////////////////////////////////////////////////////////////
+// Invalidate tex windows
+////////////////////////////////////////////////////////////////////////
+
+void InvalidateWndTextureArea(int X, int Y, int W, int H)
+{
+ int i,px1,px2,py1,py2,iYM=1;
+ textureWndCacheEntry * tsw=wcWndtexStore;
+
+ W+=X-1;
+ H+=Y-1;
+ if(X<0) X=0;if(X>1023) X=1023;
+ if(W<0) W=0;if(W>1023) W=1023;
+ if(Y<0) Y=0;if(Y>iGPUHeightMask) Y=iGPUHeightMask;
+ if(H<0) H=0;if(H>iGPUHeightMask) H=iGPUHeightMask;
+ W++;H++;
+
+ if(iGPUHeight==1024) iYM=3;
+
+ py1=min(iYM,Y>>8);
+ py2=min(iYM,H>>8); // y: 0 or 1
+
+ px1=max(0,(X>>6));
+ px2=min(15,(W>>6));
+
+ if(py1==py2)
+ {
+ py1=py1<<4;px1+=py1;px2+=py1; // change to 0-31
+ for(i=0;i<iMaxTexWnds;i++,tsw++)
+ {
+ if(tsw->used)
+ {
+ if(tsw->pageid>=px1 && tsw->pageid<=px2)
+ {
+ tsw->used=0;
+ }
+ }
+ }
+ }
+ else
+ {
+ py1=px1+16;py2=px2+16;
+ for(i=0;i<iMaxTexWnds;i++,tsw++)
+ {
+ if(tsw->used)
+ {
+ if((tsw->pageid>=px1 && tsw->pageid<=px2) ||
+ (tsw->pageid>=py1 && tsw->pageid<=py2))
+ {
+ tsw->used=0;
+ }
+ }
+ }
+ }
+
+ // adjust tex window count
+ tsw=wcWndtexStore+iMaxTexWnds-1;
+ while(iMaxTexWnds && !tsw->used) {iMaxTexWnds--;tsw--;}
+}
+
+
+
+////////////////////////////////////////////////////////////////////////
+// same for sort textures
+////////////////////////////////////////////////////////////////////////
+
+void MarkFree(textureSubCacheEntryS * tsx)
+{
+ EXLong * ul, * uls;
+ int j,iMax;unsigned char x1,y1,dx,dy;
+
+ uls=pxSsubtexLeft[tsx->cTexID];
+ iMax=uls->l;ul=uls+1;
+
+ if(!iMax) return;
+
+ for(j=0;j<iMax;j++,ul++)
+ if(ul->l==0xffffffff) break;
+
+ if(j<CSUBSIZE-2)
+ {
+ if(j==iMax) uls->l=uls->l+1;
+
+ x1=tsx->posTX;dx=tsx->pos.c[2]-tsx->pos.c[3];
+ if(tsx->posTX) {x1--;dx+=3;}
+ y1=tsx->posTY;dy=tsx->pos.c[0]-tsx->pos.c[1];
+ if(tsx->posTY) {y1--;dy+=3;}
+
+ ul->c[3]=x1;
+ ul->c[2]=dx;
+ ul->c[1]=y1;
+ ul->c[0]=dy;
+ }
+}
+
+void InvalidateSubSTextureArea(int X, int Y, int W, int H)
+{
+ int i,j,k,iMax,px,py,px1,px2,py1,py2,iYM = 1;
+ EXLong npos;
+ textureSubCacheEntryS *tsb;
+ int x1,x2,y1,y2,xa,sw;
+
+ W+=X-1;
+ H+=Y-1;
+ if(X<0) X=0;if(X>1023) X=1023;
+ if(W<0) W=0;if(W>1023) W=1023;
+ if(Y<0) Y=0;if(Y>iGPUHeightMask) Y=iGPUHeightMask;
+ if(H<0) H=0;if(H>iGPUHeightMask) H=iGPUHeightMask;
+ W++;H++;
+
+ if(iGPUHeight==1024) iYM=3;
+
+ py1=min(iYM,Y>>8);
+ py2=min(iYM,H>>8); // y: 0 or 1
+ px1=max(0,(X>>6)-3);
+ px2=min(15,(W>>6)+3); // x: 0-15
+
+ for(py=py1;py<=py2;py++)
+ {
+ j=(py<<4)+px1; // get page
+
+ y1=py*256;y2=y1+255;
+
+ if(H<y1) continue;
+ if(Y>y2) continue;
+
+ if(Y>y1) y1=Y;
+ if(H<y2) y2=H;
+ if(y2<y1) {sw=y1;y1=y2;y2=sw;}
+ y1=((y1%256)<<8);
+ y2=(y2%256);
+
+ for(px=px1;px<=px2;px++,j++)
+ {
+ for(k=0;k<3;k++)
+ {
+ xa=x1=px<<6;
+ if(W<x1) continue;
+ x2=x1+(64<<k)-1;
+ if(X>x2) continue;
+
+ if(X>x1) x1=X;
+ if(W<x2) x2=W;
+ if(x2<x1) {sw=x1;x1=x2;x2=sw;}
+
+ if (dwGPUVersion == 2)
+ npos.l=0x00ff00ff;
+ else
+ npos.l=((x1-xa)<<(26-k))|((x2-xa)<<(18-k))|y1|y2;
+
+ {
+ tsb=pscSubtexStore[k][j]+SOFFA;iMax=tsb->pos.l;tsb++;
+ for(i=0;i<iMax;i++,tsb++)
+ if(tsb->ClutID && XCHECK(tsb->pos,npos)) {tsb->ClutID=0;MarkFree(tsb);}
+
+// if(npos.l & 0x00800000)
+ {
+ tsb=pscSubtexStore[k][j]+SOFFB;iMax=tsb->pos.l;tsb++;
+ for(i=0;i<iMax;i++,tsb++)
+ if(tsb->ClutID && XCHECK(tsb->pos,npos)) {tsb->ClutID=0;MarkFree(tsb);}
+ }
+
+// if(npos.l & 0x00000080)
+ {
+ tsb=pscSubtexStore[k][j]+SOFFC;iMax=tsb->pos.l;tsb++;
+ for(i=0;i<iMax;i++,tsb++)
+ if(tsb->ClutID && XCHECK(tsb->pos,npos)) {tsb->ClutID=0;MarkFree(tsb);}
+ }
+
+// if(npos.l & 0x00800080)
+ {
+ tsb=pscSubtexStore[k][j]+SOFFD;iMax=tsb->pos.l;tsb++;
+ for(i=0;i<iMax;i++,tsb++)
+ if(tsb->ClutID && XCHECK(tsb->pos,npos)) {tsb->ClutID=0;MarkFree(tsb);}
+ }
+ }
+ }
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+// Invalidate some parts of cache: main routine
+////////////////////////////////////////////////////////////////////////
+
+void InvalidateTextureAreaEx(void)
+{
+ short W=sxmax-sxmin;
+ short H=symax-symin;
+
+ if (W == 0 && H == 0) return;
+
+ if (iMaxTexWnds)
+ InvalidateWndTextureArea(sxmin,symin,W,H);
+
+ InvalidateSubSTextureArea(sxmin,symin,W,H);
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void InvalidateTextureArea(int X, int Y, int W, int H)
+{
+ if (W == 0 && H == 0) return;
+
+ if (iMaxTexWnds) InvalidateWndTextureArea(X, Y, W, H);
+
+ InvalidateSubSTextureArea(X, Y, W, H);
+}
+
+
+////////////////////////////////////////////////////////////////////////
+// tex window: define
+////////////////////////////////////////////////////////////////////////
+
+void DefineTextureWnd(void)
+{
+ if (gTexName == 0)
+ glGenTextures(1, &gTexName);
+
+ glBindTexture(GL_TEXTURE_2D, gTexName);
+
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+
+ if(iFilterType && iFilterType<3 && iHiResTextures!=2)
+ {
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ }
+ else
+ {
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ }
+
+ glTexImage2D(GL_TEXTURE_2D, 0,giWantedRGBA,
+ TWin.Position.x1,
+ TWin.Position.y1,
+ 0, giWantedFMT, giWantedTYPE, texturepart);
+}
+
+////////////////////////////////////////////////////////////////////////
+// tex window: load packed stretch
+////////////////////////////////////////////////////////////////////////
+
+void LoadStretchPackedWndTexturePage(int pageid, int mode, short cx, short cy)
+{
+ uint32_t start, row, column, j, sxh, sxm, ldx, ldy, ldxo;
+ unsigned int palstart;
+ unsigned short *px, *pa, *ta;
+ unsigned char *cSRCPtr,*cOSRCPtr;
+ unsigned short *wSRCPtr,*wOSRCPtr;
+ uint32_t LineOffset;
+ unsigned short s;
+ int pmult = pageid / 16;
+ unsigned short (*LPTCOL)(unsigned short);
+
+ LPTCOL = PTCF[DrawSemiTrans];
+
+ ldxo = TWin.Position.x1-TWin.OPosition.x1;
+ ldy = TWin.Position.y1-TWin.OPosition.y1;
+
+ pa = px = (unsigned short *)ubPaletteBuffer;
+ ta = (unsigned short *)texturepart;
+ palstart = cx + (cy * 1024);
+
+ ubOpaqueDraw = 0;
+
+ switch (mode)
+ {
+ //--------------------------------------------------//
+ // 4bit texture load ..
+ case 0:
+ if(GlobalTextIL)
+ {
+ unsigned int TXV,TXU,n_xi,n_yi;
+
+ wSRCPtr=psxVuw+palstart;
+ for(row=0;row<16;row++)
+ *px++=LPTCOL(*wSRCPtr++);
+
+ column=g_y2-ldy;
+ for(TXV=g_y1;TXV<=column;TXV++)
+ {
+ ldx=ldxo;
+ for(TXU=g_x1;TXU<=g_x2-ldxo;TXU++)
+ {
+ n_xi = ( ( TXU >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );
+ n_yi = ( TXV & ~0xf ) + ( ( TXU >> 4 ) & 0xf );
+
+ s=*(pa+((*( psxVuw + ((GlobalTextAddrY + n_yi)*1024) + GlobalTextAddrX + n_xi ) >> ( ( TXU & 0x03 ) << 2 ) ) & 0x0f ));
+ *ta++=s;
+
+ if(ldx) {*ta++=s;ldx--;}
+ }
+
+ if(ldy)
+ {ldy--;
+ for(TXU=g_x1;TXU<=g_x2;TXU++)
+ *ta++=*(ta-(g_x2-g_x1));
+ }
+ }
+
+ DefineTextureWnd();
+
+ break;
+ }
+
+
+ start=((pageid-16*pmult)*128)+256*2048*pmult;
+
+ // convert CLUT to 32bits .. and then use THAT as a lookup table
+
+ wSRCPtr=psxVuw+palstart;
+ for(row=0;row<16;row++)
+ *px++=LPTCOL(*wSRCPtr++);
+
+ sxm=g_x1&1;sxh=g_x1>>1;
+ if(sxm) j=g_x1+1; else j=g_x1;
+ cSRCPtr = psxVub + start + (2048*g_y1) + sxh;
+ for(column=g_y1;column<=g_y2;column++)
+ {
+ cOSRCPtr=cSRCPtr;ldx=ldxo;
+ if(sxm) *ta++=*(pa+((*cSRCPtr++ >> 4) & 0xF));
+
+ for(row=j;row<=g_x2-ldxo;row++)
+ {
+ s=*(pa+(*cSRCPtr & 0xF));
+ *ta++=s;
+ if(ldx) {*ta++=s;ldx--;}
+ row++;
+ if(row<=g_x2-ldxo)
+ {
+ s=*(pa+((*cSRCPtr >> 4) & 0xF));
+ *ta++=s;
+ if(ldx) {*ta++=s;ldx--;}
+ }
+ cSRCPtr++;
+ }
+
+ if(ldy && column&1)
+ {ldy--;cSRCPtr = cOSRCPtr;}
+ else cSRCPtr = psxVub + start + (2048*(column+1)) + sxh;
+ }
+
+ DefineTextureWnd();
+ break;
+ //--------------------------------------------------//
+ // 8bit texture load ..
+ case 1:
+ if(GlobalTextIL)
+ {
+ unsigned int TXV,TXU,n_xi,n_yi;
+
+ wSRCPtr=psxVuw+palstart;
+ for(row=0;row<256;row++)
+ *px++=LPTCOL(*wSRCPtr++);
+
+ column=g_y2-ldy;
+ for(TXV=g_y1;TXV<=column;TXV++)
+ {
+ ldx=ldxo;
+ for(TXU=g_x1;TXU<=g_x2-ldxo;TXU++)
+ {
+ n_xi = ( ( TXU >> 1 ) & ~0x78 ) + ( ( TXU << 2 ) & 0x40 ) + ( ( TXV << 3 ) & 0x38 );
+ n_yi = ( TXV & ~0x7 ) + ( ( TXU >> 5 ) & 0x7 );
+
+ s=*(pa+((*( psxVuw + ((GlobalTextAddrY + n_yi)*1024) + GlobalTextAddrX + n_xi ) >> ( ( TXU & 0x01 ) << 3 ) ) & 0xff));
+
+ *ta++=s;
+ if(ldx) {*ta++=s;ldx--;}
+ }
+
+ if(ldy)
+ {ldy--;
+ for(TXU=g_x1;TXU<=g_x2;TXU++)
+ *ta++=*(ta-(g_x2-g_x1));
+ }
+
+ }
+
+ DefineTextureWnd();
+
+ break;
+ }
+
+ start=((pageid-16*pmult)*128)+256*2048*pmult;
+
+ // not using a lookup table here... speeds up smaller texture areas
+ cSRCPtr = psxVub + start + (2048*g_y1) + g_x1;
+ LineOffset = 2048 - (g_x2-g_x1+1) +ldxo;
+
+ for(column=g_y1;column<=g_y2;column++)
+ {
+ cOSRCPtr=cSRCPtr;ldx=ldxo;
+ for(row=g_x1;row<=g_x2-ldxo;row++)
+ {
+ s=LPTCOL(psxVuw[palstart+ *cSRCPtr++]);
+ *ta++=s;
+ if(ldx) {*ta++=s;ldx--;}
+ }
+ if(ldy && column&1) {ldy--;cSRCPtr=cOSRCPtr;}
+ else cSRCPtr+=LineOffset;
+ }
+
+ DefineTextureWnd();
+ break;
+ //--------------------------------------------------//
+ // 16bit texture load ..
+ case 2:
+ start=((pageid-16*pmult)*64)+256*1024*pmult;
+ wSRCPtr = psxVuw + start + (1024*g_y1) + g_x1;
+ LineOffset = 1024 - (g_x2-g_x1+1) +ldxo;
+
+ for(column=g_y1;column<=g_y2;column++)
+ {
+ wOSRCPtr=wSRCPtr;ldx=ldxo;
+ for(row=g_x1;row<=g_x2-ldxo;row++)
+ {
+ s=LPTCOL(*wSRCPtr++);
+ *ta++=s;
+ if(ldx) {*ta++=s;ldx--;}
+ }
+ if(ldy && column&1) {ldy--;wSRCPtr=wOSRCPtr;}
+ else wSRCPtr+=LineOffset;
+ }
+
+ DefineTextureWnd();
+ break;
+ //--------------------------------------------------//
+ // others are not possible !
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+// tex window: load stretched
+////////////////////////////////////////////////////////////////////////
+
+void LoadStretchWndTexturePage(int pageid, int mode, short cx, short cy)
+{
+ uint32_t start,row,column,j,sxh,sxm,ldx,ldy,ldxo,s;
+ unsigned int palstart;
+ uint32_t *px,*pa,*ta;
+ unsigned char *cSRCPtr,*cOSRCPtr;
+ unsigned short *wSRCPtr,*wOSRCPtr;
+ uint32_t LineOffset;
+ int pmult = pageid / 16;
+ uint32_t (*LTCOL)(uint32_t);
+
+ LTCOL = TCF[DrawSemiTrans];
+
+ ldxo=TWin.Position.x1-TWin.OPosition.x1;
+ ldy =TWin.Position.y1-TWin.OPosition.y1;
+
+ pa = px = (uint32_t *)ubPaletteBuffer;
+ ta = (uint32_t *)texturepart;
+ palstart = cx + (cy * 1024);
+
+ ubOpaqueDraw = 0;
+
+ switch (mode)
+ {
+ //--------------------------------------------------//
+ // 4bit texture load ..
+ case 0:
+ //------------------- ZN STUFF
+
+ if(GlobalTextIL)
+ {
+ unsigned int TXV,TXU,n_xi,n_yi;
+
+ wSRCPtr=psxVuw+palstart;
+
+ row=4;do
+ {
+ *px =LTCOL(*wSRCPtr);
+ *(px+1)=LTCOL(*(wSRCPtr+1));
+ *(px+2)=LTCOL(*(wSRCPtr+2));
+ *(px+3)=LTCOL(*(wSRCPtr+3));
+ row--;px+=4;wSRCPtr+=4;
+ }
+ while (row);
+
+ column=g_y2-ldy;
+ for(TXV=g_y1;TXV<=column;TXV++)
+ {
+ ldx=ldxo;
+ for(TXU=g_x1;TXU<=g_x2-ldxo;TXU++)
+ {
+ n_xi = ( ( TXU >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );
+ n_yi = ( TXV & ~0xf ) + ( ( TXU >> 4 ) & 0xf );
+
+ s=*(pa+((*( psxVuw + ((GlobalTextAddrY + n_yi)*1024) + GlobalTextAddrX + n_xi ) >> ( ( TXU & 0x03 ) << 2 ) ) & 0x0f ));
+ *ta++=s;
+
+ if(ldx) {*ta++=s;ldx--;}
+ }
+
+ if(ldy)
+ {ldy--;
+ for(TXU=g_x1;TXU<=g_x2;TXU++)
+ *ta++=*(ta-(g_x2-g_x1));
+ }
+ }
+
+ DefineTextureWnd();
+
+ break;
+ }
+
+ //-------------------
+
+ start=((pageid-16*pmult)*128)+256*2048*pmult;
+ // convert CLUT to 32bits .. and then use THAT as a lookup table
+
+ wSRCPtr=psxVuw+palstart;
+ for(row=0;row<16;row++)
+ *px++=LTCOL(*wSRCPtr++);
+
+ sxm=g_x1&1;sxh=g_x1>>1;
+ if(sxm) j=g_x1+1; else j=g_x1;
+ cSRCPtr = psxVub + start + (2048*g_y1) + sxh;
+ for(column=g_y1;column<=g_y2;column++)
+ {
+ cOSRCPtr=cSRCPtr;ldx=ldxo;
+ if(sxm) *ta++=*(pa+((*cSRCPtr++ >> 4) & 0xF));
+
+ for(row=j;row<=g_x2-ldxo;row++)
+ {
+ s=*(pa+(*cSRCPtr & 0xF));
+ *ta++=s;
+ if(ldx) {*ta++=s;ldx--;}
+ row++;
+ if(row<=g_x2-ldxo)
+ {
+ s=*(pa+((*cSRCPtr >> 4) & 0xF));
+ *ta++=s;
+ if(ldx) {*ta++=s;ldx--;}
+ }
+ cSRCPtr++;
+ }
+ if(ldy && column&1)
+ {ldy--;cSRCPtr = cOSRCPtr;}
+ else cSRCPtr = psxVub + start + (2048*(column+1)) + sxh;
+ }
+
+ DefineTextureWnd();
+ break;
+ //--------------------------------------------------//
+ // 8bit texture load ..
+ case 1:
+ //------------ ZN STUFF
+ if(GlobalTextIL)
+ {
+ unsigned int TXV,TXU,n_xi,n_yi;
+
+ wSRCPtr=psxVuw+palstart;
+
+ row=64;do
+ {
+ *px =LTCOL(*wSRCPtr);
+ *(px+1)=LTCOL(*(wSRCPtr+1));
+ *(px+2)=LTCOL(*(wSRCPtr+2));
+ *(px+3)=LTCOL(*(wSRCPtr+3));
+ row--;px+=4;wSRCPtr+=4;
+ }
+ while (row);
+
+ column=g_y2-ldy;
+ for(TXV=g_y1;TXV<=column;TXV++)
+ {
+ ldx=ldxo;
+ for(TXU=g_x1;TXU<=g_x2-ldxo;TXU++)
+ {
+ n_xi = ( ( TXU >> 1 ) & ~0x78 ) + ( ( TXU << 2 ) & 0x40 ) + ( ( TXV << 3 ) & 0x38 );
+ n_yi = ( TXV & ~0x7 ) + ( ( TXU >> 5 ) & 0x7 );
+
+ s=*(pa+((*( psxVuw + ((GlobalTextAddrY + n_yi)*1024) + GlobalTextAddrX + n_xi ) >> ( ( TXU & 0x01 ) << 3 ) ) & 0xff));
+ *ta++=s;
+ if(ldx) {*ta++=s;ldx--;}
+ }
+
+ if(ldy)
+ {ldy--;
+ for(TXU=g_x1;TXU<=g_x2;TXU++)
+ *ta++=*(ta-(g_x2-g_x1));
+ }
+
+ }
+
+ DefineTextureWnd();
+
+ break;
+ }
+ //------------
+
+ start=((pageid-16*pmult)*128)+256*2048*pmult;
+
+ // not using a lookup table here... speeds up smaller texture areas
+ cSRCPtr = psxVub + start + (2048*g_y1) + g_x1;
+ LineOffset = 2048 - (g_x2-g_x1+1) +ldxo;
+
+ for(column=g_y1;column<=g_y2;column++)
+ {
+ cOSRCPtr=cSRCPtr;ldx=ldxo;
+ for(row=g_x1;row<=g_x2-ldxo;row++)
+ {
+ s=LTCOL(psxVuw[palstart+ *cSRCPtr++]);
+ *ta++=s;
+ if(ldx) {*ta++=s;ldx--;}
+ }
+ if(ldy && column&1) {ldy--;cSRCPtr=cOSRCPtr;}
+ else cSRCPtr+=LineOffset;
+ }
+
+ DefineTextureWnd();
+ break;
+ //--------------------------------------------------//
+ // 16bit texture load ..
+ case 2:
+ start=((pageid-16*pmult)*64)+256*1024*pmult;
+
+ wSRCPtr = psxVuw + start + (1024*g_y1) + g_x1;
+ LineOffset = 1024 - (g_x2-g_x1+1) +ldxo;
+
+ for(column=g_y1;column<=g_y2;column++)
+ {
+ wOSRCPtr=wSRCPtr;ldx=ldxo;
+ for(row=g_x1;row<=g_x2-ldxo;row++)
+ {
+ s=LTCOL(*wSRCPtr++);
+ *ta++=s;
+ if(ldx) {*ta++=s;ldx--;}
+ }
+ if(ldy && column&1) {ldy--;wSRCPtr=wOSRCPtr;}
+ else wSRCPtr+=LineOffset;
+ }
+
+ DefineTextureWnd();
+ break;
+ //--------------------------------------------------//
+ // others are not possible !
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+// tex window: load packed simple
+////////////////////////////////////////////////////////////////////////
+
+void LoadPackedWndTexturePage(int pageid, int mode, short cx, short cy)
+{
+ uint32_t start,row,column,j,sxh,sxm;
+ unsigned int palstart;
+ unsigned short *px,*pa,*ta;
+ unsigned char *cSRCPtr;
+ unsigned short *wSRCPtr;
+ uint32_t LineOffset;
+ int pmult=pageid/16;
+ unsigned short (*LPTCOL)(unsigned short);
+
+ LPTCOL=PTCF[DrawSemiTrans];
+
+ pa=px=(unsigned short *)ubPaletteBuffer;
+ ta=(unsigned short *)texturepart;
+ palstart=cx+(cy*1024);
+
+ ubOpaqueDraw=0;
+
+ switch(mode)
+ {
+ //--------------------------------------------------//
+ // 4bit texture load ..
+ case 0:
+ if(GlobalTextIL)
+ {
+ unsigned int TXV,TXU,n_xi,n_yi;
+
+ wSRCPtr=psxVuw+palstart;
+ for(row=0;row<16;row++)
+ *px++=LPTCOL(*wSRCPtr++);
+
+ for(TXV=g_y1;TXV<=g_y2;TXV++)
+ {
+ for(TXU=g_x1;TXU<=g_x2;TXU++)
+ {
+ n_xi = ( ( TXU >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );
+ n_yi = ( TXV & ~0xf ) + ( ( TXU >> 4 ) & 0xf );
+
+ *ta++=*(pa+((*( psxVuw + ((GlobalTextAddrY + n_yi)*1024) + GlobalTextAddrX + n_xi ) >> ( ( TXU & 0x03 ) << 2 ) ) & 0x0f ));
+ }
+ }
+
+ DefineTextureWnd();
+
+ break;
+ }
+
+ start=((pageid-16*pmult)*128)+256*2048*pmult;
+
+ // convert CLUT to 32bits .. and then use THAT as a lookup table
+
+ wSRCPtr=psxVuw+palstart;
+ for(row=0;row<16;row++)
+ *px++=LPTCOL(*wSRCPtr++);
+
+ sxm=g_x1&1;sxh=g_x1>>1;
+ if(sxm) j=g_x1+1; else j=g_x1;
+ cSRCPtr = psxVub + start + (2048*g_y1) + sxh;
+ for(column=g_y1;column<=g_y2;column++)
+ {
+ cSRCPtr = psxVub + start + (2048*column) + sxh;
+
+ if(sxm) *ta++=*(pa+((*cSRCPtr++ >> 4) & 0xF));
+
+ for(row=j;row<=g_x2;row++)
+ {
+ *ta++=*(pa+(*cSRCPtr & 0xF)); row++;
+ if(row<=g_x2) *ta++=*(pa+((*cSRCPtr >> 4) & 0xF));
+ cSRCPtr++;
+ }
+ }
+
+ DefineTextureWnd();
+ break;
+ //--------------------------------------------------//
+ // 8bit texture load ..
+ case 1:
+ if(GlobalTextIL)
+ {
+ unsigned int TXV,TXU,n_xi,n_yi;
+
+ wSRCPtr=psxVuw+palstart;
+ for(row=0;row<256;row++)
+ *px++=LPTCOL(*wSRCPtr++);
+
+ for(TXV=g_y1;TXV<=g_y2;TXV++)
+ {
+ for(TXU=g_x1;TXU<=g_x2;TXU++)
+ {
+ n_xi = ( ( TXU >> 1 ) & ~0x78 ) + ( ( TXU << 2 ) & 0x40 ) + ( ( TXV << 3 ) & 0x38 );
+ n_yi = ( TXV & ~0x7 ) + ( ( TXU >> 5 ) & 0x7 );
+
+ *ta++=*(pa+((*( psxVuw + ((GlobalTextAddrY + n_yi)*1024) + GlobalTextAddrX + n_xi ) >> ( ( TXU & 0x01 ) << 3 ) ) & 0xff));
+ }
+ }
+
+ DefineTextureWnd();
+
+ break;
+ }
+
+ start=((pageid-16*pmult)*128)+256*2048*pmult;
+
+ // not using a lookup table here... speeds up smaller texture areas
+ cSRCPtr = psxVub + start + (2048*g_y1) + g_x1;
+ LineOffset = 2048 - (g_x2-g_x1+1);
+
+ for(column=g_y1;column<=g_y2;column++)
+ {
+ for(row=g_x1;row<=g_x2;row++)
+ *ta++=LPTCOL(psxVuw[palstart+ *cSRCPtr++]);
+ cSRCPtr+=LineOffset;
+ }
+
+ DefineTextureWnd();
+ break;
+ //--------------------------------------------------//
+ // 16bit texture load ..
+ case 2:
+ start=((pageid-16*pmult)*64)+256*1024*pmult;
+ wSRCPtr = psxVuw + start + (1024*g_y1) + g_x1;
+ LineOffset = 1024 - (g_x2-g_x1+1);
+
+ for(column=g_y1;column<=g_y2;column++)
+ {
+ for(row=g_x1;row<=g_x2;row++)
+ *ta++=LPTCOL(*wSRCPtr++);
+ wSRCPtr+=LineOffset;
+ }
+
+ DefineTextureWnd();
+ break;
+ //--------------------------------------------------//
+ // others are not possible !
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+// tex window: load simple
+////////////////////////////////////////////////////////////////////////
+
+void LoadWndTexturePage(int pageid, int mode, short cx, short cy)
+{
+ uint32_t start,row,column,j,sxh,sxm;
+ unsigned int palstart;
+ uint32_t *px,*pa,*ta;
+ unsigned char *cSRCPtr;
+ unsigned short *wSRCPtr;
+ uint32_t LineOffset;
+ int pmult = pageid / 16;
+ uint32_t (*LTCOL)(uint32_t);
+
+ LTCOL=TCF[DrawSemiTrans];
+
+ pa = px = (uint32_t *)ubPaletteBuffer;
+ ta = (uint32_t *)texturepart;
+ palstart = cx + (cy * 1024);
+
+ ubOpaqueDraw = 0;
+
+ switch (mode)
+ {
+ //--------------------------------------------------//
+ // 4bit texture load ..
+ case 0:
+ if(GlobalTextIL)
+ {
+ unsigned int TXV,TXU,n_xi,n_yi;
+
+ wSRCPtr=psxVuw+palstart;
+
+ row=4;do
+ {
+ *px =LTCOL(*wSRCPtr);
+ *(px+1)=LTCOL(*(wSRCPtr+1));
+ *(px+2)=LTCOL(*(wSRCPtr+2));
+ *(px+3)=LTCOL(*(wSRCPtr+3));
+ row--;px+=4;wSRCPtr+=4;
+ }
+ while (row);
+
+ for(TXV=g_y1;TXV<=g_y2;TXV++)
+ {
+ for(TXU=g_x1;TXU<=g_x2;TXU++)
+ {
+ n_xi = ( ( TXU >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );
+ n_yi = ( TXV & ~0xf ) + ( ( TXU >> 4 ) & 0xf );
+
+ *ta++=*(pa+((*( psxVuw + ((GlobalTextAddrY + n_yi)*1024) + GlobalTextAddrX + n_xi ) >> ( ( TXU & 0x03 ) << 2 ) ) & 0x0f ));
+ }
+ }
+
+ DefineTextureWnd();
+
+ break;
+ }
+
+ start=((pageid-16*pmult)*128)+256*2048*pmult;
+
+ // convert CLUT to 32bits .. and then use THAT as a lookup table
+
+ wSRCPtr=psxVuw+palstart;
+ for(row=0;row<16;row++)
+ *px++=LTCOL(*wSRCPtr++);
+
+ sxm=g_x1&1;sxh=g_x1>>1;
+ if(sxm) j=g_x1+1; else j=g_x1;
+ cSRCPtr = psxVub + start + (2048*g_y1) + sxh;
+ for(column=g_y1;column<=g_y2;column++)
+ {
+ cSRCPtr = psxVub + start + (2048*column) + sxh;
+
+ if(sxm) *ta++=*(pa+((*cSRCPtr++ >> 4) & 0xF));
+
+ for(row=j;row<=g_x2;row++)
+ {
+ *ta++=*(pa+(*cSRCPtr & 0xF)); row++;
+ if(row<=g_x2) *ta++=*(pa+((*cSRCPtr >> 4) & 0xF));
+ cSRCPtr++;
+ }
+ }
+
+ DefineTextureWnd();
+ break;
+ //--------------------------------------------------//
+ // 8bit texture load ..
+ case 1:
+ if(GlobalTextIL)
+ {
+ unsigned int TXV,TXU,n_xi,n_yi;
+
+ wSRCPtr=psxVuw+palstart;
+
+ row=64;do
+ {
+ *px =LTCOL(*wSRCPtr);
+ *(px+1)=LTCOL(*(wSRCPtr+1));
+ *(px+2)=LTCOL(*(wSRCPtr+2));
+ *(px+3)=LTCOL(*(wSRCPtr+3));
+ row--;px+=4;wSRCPtr+=4;
+ }
+ while (row);
+
+ for(TXV=g_y1;TXV<=g_y2;TXV++)
+ {
+ for(TXU=g_x1;TXU<=g_x2;TXU++)
+ {
+ n_xi = ( ( TXU >> 1 ) & ~0x78 ) + ( ( TXU << 2 ) & 0x40 ) + ( ( TXV << 3 ) & 0x38 );
+ n_yi = ( TXV & ~0x7 ) + ( ( TXU >> 5 ) & 0x7 );
+
+ *ta++=*(pa+((*( psxVuw + ((GlobalTextAddrY + n_yi)*1024) + GlobalTextAddrX + n_xi ) >> ( ( TXU & 0x01 ) << 3 ) ) & 0xff));
+ }
+ }
+
+ DefineTextureWnd();
+
+ break;
+ }
+
+ start=((pageid-16*pmult)*128)+256*2048*pmult;
+
+ // not using a lookup table here... speeds up smaller texture areas
+ cSRCPtr = psxVub + start + (2048*g_y1) + g_x1;
+ LineOffset = 2048 - (g_x2-g_x1+1);
+
+ for(column=g_y1;column<=g_y2;column++)
+ {
+ for(row=g_x1;row<=g_x2;row++)
+ *ta++=LTCOL(psxVuw[palstart+ *cSRCPtr++]);
+ cSRCPtr+=LineOffset;
+ }
+
+ DefineTextureWnd();
+ break;
+ //--------------------------------------------------//
+ // 16bit texture load ..
+ case 2:
+ start=((pageid-16*pmult)*64)+256*1024*pmult;
+
+ wSRCPtr = psxVuw + start + (1024*g_y1) + g_x1;
+ LineOffset = 1024 - (g_x2-g_x1+1);
+
+ for(column=g_y1;column<=g_y2;column++)
+ {
+ for(row=g_x1;row<=g_x2;row++)
+ *ta++=LTCOL(*wSRCPtr++);
+ wSRCPtr+=LineOffset;
+ }
+
+ DefineTextureWnd();
+ break;
+ //--------------------------------------------------//
+ // others are not possible !
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////
+
+void UploadTexWndPal(int mode,short cx,short cy)
+{
+ unsigned int i,iSize;
+ unsigned short *wSrcPtr;
+ uint32_t *ta = (uint32_t *)texturepart;
+
+ wSrcPtr = psxVuw + cx + (cy * 1024);
+ if (mode == 0) i = 4; else i = 64;
+ iSize = i << 2;
+ ubOpaqueDraw = 0;
+
+ do
+ {
+ *ta =PALCOL(*wSrcPtr);
+ *(ta+1)=PALCOL(*(wSrcPtr+1));
+ *(ta+2)=PALCOL(*(wSrcPtr+2));
+ *(ta+3)=PALCOL(*(wSrcPtr+3));
+ ta+=4;wSrcPtr+=4;i--;
+ }
+ while(i);
+
+ (*glColorTableEXTEx)(GL_TEXTURE_2D,GL_RGBA8,iSize,
+ GL_RGBA,GL_UNSIGNED_BYTE,texturepart);
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void DefinePalTextureWnd(void)
+{
+ if(gTexName==0)
+ glGenTextures(1, &gTexName);
+
+ glBindTexture(GL_TEXTURE_2D, gTexName);
+
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+
+ if(iFilterType && iFilterType<3 && iHiResTextures!=2)
+ {
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ }
+ else
+ {
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ }
+
+ glTexImage2D(GL_TEXTURE_2D, 0,GL_COLOR_INDEX8_EXT,
+ TWin.Position.x1,
+ TWin.Position.y1,
+ 0, GL_COLOR_INDEX, GL_UNSIGNED_BYTE,texturepart);
+}
+
+///////////////////////////////////////////////////////
+
+void LoadPalWndTexturePage(int pageid, int mode, short cx, short cy)
+{
+ uint32_t start,row,column,j,sxh,sxm;
+ unsigned char *ta;
+ unsigned char *cSRCPtr;
+ uint32_t LineOffset;
+ int pmult = pageid / 16;
+
+ ta = (unsigned char *)texturepart;
+
+ switch (mode)
+ {
+ //--------------------------------------------------//
+ // 4bit texture load ..
+ case 0:
+ start=((pageid-16*pmult)*128)+256*2048*pmult;
+
+ sxm=g_x1&1;sxh=g_x1>>1;
+ if(sxm) j=g_x1+1; else j=g_x1;
+ cSRCPtr = psxVub + start + (2048*g_y1) + sxh;
+ for(column=g_y1;column<=g_y2;column++)
+ {
+ cSRCPtr = psxVub + start + (2048*column) + sxh;
+
+ if(sxm) *ta++=((*cSRCPtr++ >> 4) & 0xF);
+
+ for(row=j;row<=g_x2;row++)
+ {
+ *ta++=(*cSRCPtr & 0xF); row++;
+ if(row<=g_x2) *ta++=((*cSRCPtr >> 4) & 0xF);
+ cSRCPtr++;
+ }
+ }
+
+ DefinePalTextureWnd();
+ break;
+ //--------------------------------------------------//
+ // 8bit texture load ..
+ case 1:
+ start=((pageid-16*pmult)*128)+256*2048*pmult;
+
+ // not using a lookup table here... speeds up smaller texture areas
+ cSRCPtr = psxVub + start + (2048*g_y1) + g_x1;
+ LineOffset = 2048 - (g_x2-g_x1+1);
+
+ for(column=g_y1;column<=g_y2;column++)
+ {
+ for(row=g_x1;row<=g_x2;row++)
+ *ta++=*cSRCPtr++;
+ cSRCPtr+=LineOffset;
+ }
+
+ DefinePalTextureWnd();
+ break;
+ }
+ UploadTexWndPal(mode,cx,cy);
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void LoadStretchPalWndTexturePage(int pageid, int mode, short cx, short cy)
+{
+ uint32_t start,row,column,j,sxh,sxm,ldx,ldy,ldxo;
+ unsigned char *ta,s;
+ unsigned char *cSRCPtr,*cOSRCPtr;
+ uint32_t LineOffset;
+ int pmult = pageid / 16;
+
+ ldxo = TWin.Position.x1-TWin.OPosition.x1;
+ ldy = TWin.Position.y1-TWin.OPosition.y1;
+
+ ta = (unsigned char *)texturepart;
+
+ switch (mode)
+ {
+ //--------------------------------------------------//
+ // 4bit texture load ..
+ case 0:
+ start=((pageid-16*pmult)*128)+256*2048*pmult;
+
+ sxm=g_x1&1;sxh=g_x1>>1;
+ if(sxm) j=g_x1+1; else j=g_x1;
+ cSRCPtr = psxVub + start + (2048*g_y1) + sxh;
+ for(column=g_y1;column<=g_y2;column++)
+ {
+ cOSRCPtr=cSRCPtr;ldx=ldxo;
+ if(sxm) *ta++=((*cSRCPtr++ >> 4) & 0xF);
+
+ for(row=j;row<=g_x2-ldxo;row++)
+ {
+ s=(*cSRCPtr & 0xF);
+ *ta++=s;
+ if(ldx) {*ta++=s;ldx--;}
+ row++;
+ if(row<=g_x2-ldxo)
+ {
+ s=((*cSRCPtr >> 4) & 0xF);
+ *ta++=s;
+ if(ldx) {*ta++=s;ldx--;}
+ }
+ cSRCPtr++;
+ }
+ if(ldy && column&1)
+ {ldy--;cSRCPtr = cOSRCPtr;}
+ else cSRCPtr = psxVub + start + (2048*(column+1)) + sxh;
+ }
+
+ DefinePalTextureWnd();
+ break;
+ //--------------------------------------------------//
+ // 8bit texture load ..
+ case 1:
+ start=((pageid-16*pmult)*128)+256*2048*pmult;
+
+ cSRCPtr = psxVub + start + (2048*g_y1) + g_x1;
+ LineOffset = 2048 - (g_x2-g_x1+1) +ldxo;
+
+ for(column=g_y1;column<=g_y2;column++)
+ {
+ cOSRCPtr=cSRCPtr;ldx=ldxo;
+ for(row=g_x1;row<=g_x2-ldxo;row++)
+ {
+ s=*cSRCPtr++;
+ *ta++=s;
+ if(ldx) {*ta++=s;ldx--;}
+ }
+ if(ldy && column&1) {ldy--;cSRCPtr=cOSRCPtr;}
+ else cSRCPtr+=LineOffset;
+ }
+
+ DefinePalTextureWnd();
+ break;
+ }
+ UploadTexWndPal(mode,cx,cy);
+}
+
+////////////////////////////////////////////////////////////////////////
+// tex window: main selecting, cache handler included
+////////////////////////////////////////////////////////////////////////
+
+GLuint LoadTextureWnd(int pageid, int TextureMode, uint32_t GivenClutId)
+{
+ textureWndCacheEntry *ts, *tsx = NULL;
+ int i;
+ short cx,cy;
+ EXLong npos;
+
+ npos.c[3] = TWin.Position.x0;
+ npos.c[2] = TWin.OPosition.x1;
+ npos.c[1] = TWin.Position.y0;
+ npos.c[0] = TWin.OPosition.y1;
+
+ g_x1 = TWin.Position.x0; g_x2 = g_x1 + TWin.Position.x1 - 1;
+ g_y1 = TWin.Position.y0; g_y2 = g_y1 + TWin.Position.y1 - 1;
+
+ if (TextureMode == 2) { GivenClutId = 0; cx = cy = 0; }
+ else
+ {
+ cx = ((GivenClutId << 4) & 0x3F0);
+ cy = ((GivenClutId >> 6) & CLUTYMASK);
+ GivenClutId = (GivenClutId & CLUTMASK) | (DrawSemiTrans << 30);
+
+ // palette check sum
+ {
+ uint32_t l = 0,row;
+ uint32_t *lSRCPtr = (uint32_t *)(psxVuw + cx + (cy * 1024));
+ if(TextureMode==1) for(row=1;row<129;row++) l+=((*lSRCPtr++)-1)*row;
+ else for(row=1;row<9;row++) l+=((*lSRCPtr++)-1)<<row;
+ l=(l+HIWORD(l))&0x3fffL;
+ GivenClutId|=(l<<16);
+ }
+
+ }
+
+ ts=wcWndtexStore;
+
+ for(i=0;i<iMaxTexWnds;i++,ts++)
+ {
+ if(ts->used)
+ {
+ if(ts->pos.l==npos.l &&
+ ts->pageid==pageid &&
+ ts->textureMode==TextureMode)
+ {
+ if(ts->ClutID==GivenClutId)
+ {
+ ubOpaqueDraw=ts->Opaque;
+ return ts->texname;
+ }
+ else if(glColorTableEXTEx && TextureMode!=2)
+ {
+ ts->ClutID=GivenClutId;
+ if(ts->texname!=gTexName)
+ {
+ gTexName=ts->texname;
+ glBindTexture(GL_TEXTURE_2D, gTexName);
+ }
+ UploadTexWndPal(TextureMode,cx,cy);
+ ts->Opaque=ubOpaqueDraw;
+ return gTexName;
+ }
+ }
+ }
+ else tsx=ts;
+ }
+
+ if(!tsx)
+ {
+ if(iMaxTexWnds==iTexWndLimit)
+ {
+ tsx=wcWndtexStore+iTexWndTurn;
+ iTexWndTurn++;
+ if(iTexWndTurn==iTexWndLimit) iTexWndTurn=0;
+ }
+ else
+ {
+ tsx=wcWndtexStore+iMaxTexWnds;
+ iMaxTexWnds++;
+ }
+ }
+
+ gTexName=tsx->texname;
+
+ if(TWin.OPosition.y1==TWin.Position.y1 &&
+ TWin.OPosition.x1==TWin.Position.x1)
+ {
+ if(glColorTableEXTEx && TextureMode!=2)
+ LoadPalWndTexturePage(pageid,TextureMode,cx,cy);
+ else
+ if(bGLExt)
+ LoadPackedWndTexturePage(pageid,TextureMode,cx,cy);
+ else
+ LoadWndTexturePage(pageid,TextureMode,cx,cy);
+ }
+ else
+ {
+ if(glColorTableEXTEx && TextureMode!=2)
+ LoadStretchPalWndTexturePage(pageid,TextureMode,cx,cy);
+ else
+ if(bGLExt)
+ LoadStretchPackedWndTexturePage(pageid,TextureMode,cx,cy);
+ else
+ LoadStretchWndTexturePage(pageid,TextureMode,cx,cy);
+ }
+
+ tsx->Opaque=ubOpaqueDraw;
+ tsx->pos.l=npos.l;
+ tsx->ClutID=GivenClutId;
+ tsx->pageid=pageid;
+ tsx->textureMode=TextureMode;
+ tsx->texname=gTexName;
+ tsx->used=1;
+
+ return gTexName;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+// movie texture: define
+////////////////////////////////////////////////////////////////////////
+
+void DefinePackedTextureMovie(void)
+{
+ if(gTexMovieName==0)
+ {
+ glGenTextures(1, &gTexMovieName);
+ gTexName=gTexMovieName;
+ glBindTexture(GL_TEXTURE_2D, gTexName);
+
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, iClampType);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, iClampType);
+
+ if(!bUseFastMdec)
+ {
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ }
+ else
+ {
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ }
+
+ glTexImage2D(GL_TEXTURE_2D, 0, //giWantedRGBA,
+ GL_RGB5_A1,
+ 256, 256, 0, GL_RGBA, giWantedTYPE, texturepart);
+ }
+ else
+ {
+ gTexName=gTexMovieName;glBindTexture(GL_TEXTURE_2D, gTexName);
+ }
+
+ glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0,
+ (xrMovieArea.x1-xrMovieArea.x0),
+ (xrMovieArea.y1-xrMovieArea.y0),
+ GL_RGBA,
+ GL_UNSIGNED_SHORT_5_5_5_1_EXT,
+ texturepart);
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void DefineTextureMovie(void)
+{
+ if(gTexMovieName==0)
+ {
+ glGenTextures(1, &gTexMovieName);
+ gTexName=gTexMovieName;
+ glBindTexture(GL_TEXTURE_2D, gTexName);
+
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, iClampType);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, iClampType);
+
+ if(!bUseFastMdec)
+ {
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ }
+ else
+ {
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ }
+
+ glTexImage2D(GL_TEXTURE_2D, 0, giWantedRGBA, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, texturepart);
+ }
+ else
+ {
+ gTexName=gTexMovieName;glBindTexture(GL_TEXTURE_2D, gTexName);
+ }
+
+ glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0,
+ (xrMovieArea.x1-xrMovieArea.x0),
+ (xrMovieArea.y1-xrMovieArea.y0),
+ GL_RGBA, GL_UNSIGNED_BYTE, texturepart);
+}
+
+////////////////////////////////////////////////////////////////////////
+// movie texture: load
+////////////////////////////////////////////////////////////////////////
+
+#define MRED(x) ((x>>3) & 0x1f)
+#define MGREEN(x) ((x>>6) & 0x3e0)
+#define MBLUE(x) ((x>>9) & 0x7c00)
+
+#define XMGREEN(x) ((x>>5) & 0x07c0)
+#define XMRED(x) ((x<<8) & 0xf800)
+#define XMBLUE(x) ((x>>18) & 0x003e)
+
+////////////////////////////////////////////////////////////////////////
+// movie texture: load
+////////////////////////////////////////////////////////////////////////
+
+unsigned char * LoadDirectMovieFast(void)
+{
+ int row,column;
+ unsigned int startxy;
+
+ uint32_t *ta=(uint32_t *)texturepart;
+
+ if(PSXDisplay.RGB24)
+ {
+ unsigned char * pD;
+
+ startxy=((1024)*xrMovieArea.y0)+xrMovieArea.x0;
+
+ for(column=xrMovieArea.y0;column<xrMovieArea.y1;column++,startxy+=1024)
+ {
+ pD=(unsigned char *)&psxVuw[startxy];
+ for(row=xrMovieArea.x0;row<xrMovieArea.x1;row++)
+ {
+ *ta++=*((uint32_t *)pD)|0xff000000;
+ pD+=3;
+ }
+ }
+ }
+ else
+ {
+ uint32_t (*LTCOL)(uint32_t);
+
+ LTCOL=XP8RGBA_0;//TCF[0];
+
+ ubOpaqueDraw=0;
+
+ for(column=xrMovieArea.y0;column<xrMovieArea.y1;column++)
+ {
+ startxy=((1024)*column)+xrMovieArea.x0;
+ for(row=xrMovieArea.x0;row<xrMovieArea.x1;row++)
+ *ta++=LTCOL(psxVuw[startxy++]|0x8000);
+ }
+ }
+
+ return texturepart;
+}
+
+////////////////////////////////////////////////////////////////////////
+
+GLuint LoadTextureMovieFast(void)
+{
+ int row,column;
+ unsigned int start,startxy;
+
+ if(bGLFastMovie)
+ {
+ if(PSXDisplay.RGB24)
+ {
+ unsigned char * pD; uint32_t lu1,lu2;
+ unsigned short * ta=(unsigned short *)texturepart;
+ short sx0=xrMovieArea.x1-1;
+
+ start=0;
+
+ startxy=((1024)*xrMovieArea.y0)+xrMovieArea.x0;
+ for(column=xrMovieArea.y0;column<xrMovieArea.y1;column++)
+ {
+ pD=(unsigned char *)&psxVuw[startxy];
+ startxy+=1024;
+
+ for(row=xrMovieArea.x0;row<sx0;row+=2)
+ {
+ lu1=*((uint32_t *)pD);pD+=3;
+ lu2=*((uint32_t *)pD);pD+=3;
+
+ *((uint32_t *)ta)=
+ (XMBLUE(lu1)|XMGREEN(lu1)|XMRED(lu1)|1)|
+ ((XMBLUE(lu2)|XMGREEN(lu2)|XMRED(lu2)|1)<<16);
+ ta+=2;
+ }
+ if(row==sx0)
+ {
+ lu1=*((uint32_t *)pD);
+ *ta++=XMBLUE(lu1)|XMGREEN(lu1)|XMRED(lu1)|1;
+ }
+ }
+ }
+ else
+ {
+ unsigned short *ta=(unsigned short *)texturepart;
+ uint32_t lc;
+ short sx0=xrMovieArea.x1-1;
+
+ for(column=xrMovieArea.y0;column<xrMovieArea.y1;column++)
+ {
+ startxy=((1024)*column)+xrMovieArea.x0;
+ for(row=xrMovieArea.x0;row<sx0;row+=2)
+ {
+ lc=*((uint32_t *)&psxVuw[startxy]);
+ *((uint32_t *)ta)=
+ ((lc&0x001f001f)<<11)|((lc&0x03e003e0)<<1)|((lc&0x7c007c00)>>9)|0x00010001;
+ ta+=2;startxy+=2;
+ }
+ if(row==sx0) *ta++=(psxVuw[startxy]<<1)|1;
+ }
+ }
+ DefinePackedTextureMovie();
+ }
+ else
+ {
+ if(PSXDisplay.RGB24)
+ {
+ unsigned char *pD;
+ uint32_t *ta = (uint32_t *)texturepart;
+
+ startxy=((1024)*xrMovieArea.y0)+xrMovieArea.x0;
+
+ for(column=xrMovieArea.y0;column<xrMovieArea.y1;column++,startxy+=1024)
+ {
+ //startxy=((1024)*column)+xrMovieArea.x0;
+ pD = (unsigned char *)&psxVuw[startxy];
+ for(row=xrMovieArea.x0;row<xrMovieArea.x1;row++)
+ {
+ *ta++=*((uint32_t *)pD)|0xff000000;
+ pD+=3;
+ }
+ }
+ }
+ else
+ {
+ uint32_t (*LTCOL)(uint32_t);
+ uint32_t *ta;
+
+ LTCOL = XP8RGBA_0;//TCF[0];
+
+ ubOpaqueDraw = 0;
+ ta = (uint32_t *)texturepart;
+
+ for (column = xrMovieArea.y0; column < xrMovieArea.y1; column++)
+ {
+ startxy = (1024 * column) + xrMovieArea.x0;
+ for (row = xrMovieArea.x0; row < xrMovieArea.x1; row++)
+ *ta++=LTCOL(psxVuw[startxy++]|0x8000);
+ }
+ }
+ DefineTextureMovie();
+ }
+ return gTexName;
+}
+
+////////////////////////////////////////////////////////////////////////
+
+GLuint LoadTextureMovie(void)
+{
+ short row,column,dx;
+ unsigned int startxy;
+ BOOL b_X,b_Y;
+
+ if(bUseFastMdec) return LoadTextureMovieFast();
+
+ b_X=FALSE;b_Y=FALSE;
+
+ if((xrMovieArea.x1-xrMovieArea.x0)<255) b_X=TRUE;
+ if((xrMovieArea.y1-xrMovieArea.y0)<255) b_Y=TRUE;
+
+ if(bGLFastMovie)
+ {
+ unsigned short c;
+
+ if(PSXDisplay.RGB24)
+ {
+ unsigned char * pD;
+ uint32_t lu;
+ unsigned short * ta=(unsigned short *)texturepart;
+
+ if(b_X)
+ {
+ for(column=xrMovieArea.y0;column<xrMovieArea.y1;column++)
+ {
+ startxy=((1024)*column)+xrMovieArea.x0;
+ pD=(unsigned char *)&psxVuw[startxy];
+ for(row=xrMovieArea.x0;row<xrMovieArea.x1;row++)
+ {
+ lu=*((uint32_t *)pD);pD+=3;
+ *ta++=XMBLUE(lu)|XMGREEN(lu)|XMRED(lu)|1;
+ }
+ *ta++=*(ta-1);
+ }
+ if(b_Y)
+ {
+ dx=xrMovieArea.x1-xrMovieArea.x0+1;
+ for(row=xrMovieArea.x0;row<xrMovieArea.x1;row++)
+ *ta++=*(ta-dx);
+ *ta++=*(ta-1);
+ }
+ }
+ else
+ {
+ for(column=xrMovieArea.y0;column<xrMovieArea.y1;column++)
+ {
+ startxy=((1024)*column)+xrMovieArea.x0;
+ pD=(unsigned char *)&psxVuw[startxy];
+ for(row=xrMovieArea.x0;row<xrMovieArea.x1;row++)
+ {
+ lu=*((uint32_t *)pD);pD+=3;
+ *ta++=XMBLUE(lu)|XMGREEN(lu)|XMRED(lu)|1;
+ }
+ }
+ if(b_Y)
+ {
+ dx=xrMovieArea.x1-xrMovieArea.x0;
+ for(row=xrMovieArea.x0;row<xrMovieArea.x1;row++)
+ *ta++=*(ta-dx);
+ }
+ }
+ }
+ else
+ {
+ unsigned short *ta;
+
+ ubOpaqueDraw=0;
+
+ ta=(unsigned short *)texturepart;
+
+ if(b_X)
+ {
+ for(column=xrMovieArea.y0;column<xrMovieArea.y1;column++)
+ {
+ startxy=((1024)*column)+xrMovieArea.x0;
+ for(row=xrMovieArea.x0;row<xrMovieArea.x1;row++)
+ {
+ c=psxVuw[startxy++];
+ *ta++=((c&0x1f)<<11)|((c&0x3e0)<<1)|((c&0x7c00)>>9)|1;
+ }
+
+ *ta++=*(ta-1);
+ }
+ if(b_Y)
+ {
+ dx=xrMovieArea.x1-xrMovieArea.x0+1;
+ for(row=xrMovieArea.x0;row<xrMovieArea.x1;row++)
+ *ta++=*(ta-dx);
+ *ta++=*(ta-1);
+ }
+ }
+ else
+ {
+ for(column=xrMovieArea.y0;column<xrMovieArea.y1;column++)
+ {
+ startxy=((1024)*column)+xrMovieArea.x0;
+ for(row=xrMovieArea.x0;row<xrMovieArea.x1;row++)
+ {
+ c=psxVuw[startxy++];
+ *ta++=((c&0x1f)<<11)|((c&0x3e0)<<1)|((c&0x7c00)>>9)|1;
+ }
+ }
+ if(b_Y)
+ {
+ dx=xrMovieArea.x1-xrMovieArea.x0;
+ for(row=xrMovieArea.x0;row<xrMovieArea.x1;row++)
+ *ta++=*(ta-dx);
+ }
+ }
+ }
+ xrMovieArea.x1+=b_X;xrMovieArea.y1+=b_Y;
+ DefinePackedTextureMovie();
+ xrMovieArea.x1-=b_X;xrMovieArea.y1-=b_Y;
+ }
+ else
+ {
+ if(PSXDisplay.RGB24)
+ {
+ unsigned char * pD;
+ uint32_t * ta=(uint32_t *)texturepart;
+
+ if(b_X)
+ {
+ for(column=xrMovieArea.y0;column<xrMovieArea.y1;column++)
+ {
+ startxy=((1024)*column)+xrMovieArea.x0;
+ pD=(unsigned char *)&psxVuw[startxy];
+ for(row=xrMovieArea.x0;row<xrMovieArea.x1;row++)
+ {
+ *ta++=*((uint32_t *)pD)|0xff000000;
+ pD+=3;
+ }
+ *ta++=*(ta-1);
+ }
+ if(b_Y)
+ {
+ dx=xrMovieArea.x1-xrMovieArea.x0+1;
+ for(row=xrMovieArea.x0;row<xrMovieArea.x1;row++)
+ *ta++=*(ta-dx);
+ *ta++=*(ta-1);
+ }
+ }
+ else
+ {
+ for(column=xrMovieArea.y0;column<xrMovieArea.y1;column++)
+ {
+ startxy=((1024)*column)+xrMovieArea.x0;
+ pD=(unsigned char *)&psxVuw[startxy];
+ for(row=xrMovieArea.x0;row<xrMovieArea.x1;row++)
+ {
+ *ta++=*((uint32_t *)pD)|0xff000000;
+ pD+=3;
+ }
+ }
+ if(b_Y)
+ {
+ dx=xrMovieArea.x1-xrMovieArea.x0;
+ for(row=xrMovieArea.x0;row<xrMovieArea.x1;row++)
+ *ta++=*(ta-dx);
+ }
+ }
+ }
+ else
+ {
+ uint32_t (*LTCOL)(uint32_t);
+ uint32_t *ta;
+
+ LTCOL=XP8RGBA_0;//TCF[0];
+
+ ubOpaqueDraw=0;
+ ta=(uint32_t *)texturepart;
+
+ if(b_X)
+ {
+ for(column=xrMovieArea.y0;column<xrMovieArea.y1;column++)
+ {
+ startxy=((1024)*column)+xrMovieArea.x0;
+ for(row=xrMovieArea.x0;row<xrMovieArea.x1;row++)
+ *ta++=LTCOL(psxVuw[startxy++]|0x8000);
+ *ta++=*(ta-1);
+ }
+
+ if(b_Y)
+ {
+ dx=xrMovieArea.x1-xrMovieArea.x0+1;
+ for(row=xrMovieArea.x0;row<xrMovieArea.x1;row++)
+ *ta++=*(ta-dx);
+ *ta++=*(ta-1);
+ }
+ }
+ else
+ {
+ for(column=xrMovieArea.y0;column<xrMovieArea.y1;column++)
+ {
+ startxy=((1024)*column)+xrMovieArea.x0;
+ for(row=xrMovieArea.x0;row<xrMovieArea.x1;row++)
+ *ta++=LTCOL(psxVuw[startxy++]|0x8000);
+ }
+
+ if(b_Y)
+ {
+ dx=xrMovieArea.x1-xrMovieArea.x0;
+ for(row=xrMovieArea.x0;row<xrMovieArea.x1;row++)
+ *ta++=*(ta-dx);
+ }
+ }
+ }
+
+ xrMovieArea.x1+=b_X;xrMovieArea.y1+=b_Y;
+ DefineTextureMovie();
+ xrMovieArea.x1-=b_X;xrMovieArea.y1-=b_Y;
+ }
+ return gTexName;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+
+GLuint BlackFake15BitTexture(void)
+{
+ int pmult;short x1,x2,y1,y2;
+
+ if(PSXDisplay.InterlacedTest) return 0;
+
+ pmult=GlobalTexturePage/16;
+ x1=gl_ux[7];
+ x2=gl_ux[6]-gl_ux[7];
+ y1=gl_ux[5];
+ y2=gl_ux[4]-gl_ux[5];
+
+ if(iSpriteTex)
+ {
+ if(x2<255) x2++;
+ if(y2<255) y2++;
+ }
+
+ y1+=pmult*256;
+ x1+=((GlobalTexturePage-16*pmult)<<6);
+
+ if( FastCheckAgainstFrontScreen(x1,y1,x2,y2)
+ || FastCheckAgainstScreen(x1,y1,x2,y2))
+ {
+ if(!gTexFrameName)
+ {
+ glGenTextures(1, &gTexFrameName);
+ gTexName=gTexFrameName;
+ glBindTexture(GL_TEXTURE_2D, gTexName);
+
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, iClampType);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, iClampType);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+
+ if(bGLExt)
+ {
+ unsigned short s;unsigned short * ta;
+
+ if(giWantedTYPE==GL_UNSIGNED_SHORT_4_4_4_4_EXT)
+ s=0x000f;
+ else s=0x0001;
+
+ ta=(unsigned short *)texturepart;
+ for(y1=0;y1<=4;y1++)
+ for(x1=0;x1<=4;x1++)
+ *ta++=s;
+ }
+ else
+ {
+ uint32_t *ta=(uint32_t *)texturepart;
+ for(y1=0;y1<=4;y1++)
+ for(x1=0;x1<=4;x1++)
+ *ta++=0xff000000;
+ }
+ glTexImage2D(GL_TEXTURE_2D, 0, giWantedRGBA, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, texturepart);
+ }
+ else
+ {
+ gTexName=gTexFrameName;
+ glBindTexture(GL_TEXTURE_2D, gTexName);
+ }
+
+ ubOpaqueDraw=0;
+
+ return (GLuint)gTexName;
+ }
+ return 0;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+BOOL bFakeFrontBuffer=FALSE;
+BOOL bIgnoreNextTile =FALSE;
+
+int iFTex=512;
+
+GLuint Fake15BitTexture(void)
+{
+ int pmult;short x1,x2,y1,y2;int iYAdjust;
+ float ScaleX,ScaleY;RECT rSrc;
+
+ if(iFrameTexType==1) return BlackFake15BitTexture();
+ if(PSXDisplay.InterlacedTest) return 0;
+
+ pmult=GlobalTexturePage/16;
+ x1=gl_ux[7];
+ x2=gl_ux[6]-gl_ux[7];
+ y1=gl_ux[5];
+ y2=gl_ux[4]-gl_ux[5];
+
+ y1+=pmult*256;
+ x1+=((GlobalTexturePage-16*pmult)<<6);
+
+ if(iFrameTexType==3)
+ {
+ if(iFrameReadType==4) return 0;
+
+ if(!FastCheckAgainstFrontScreen(x1,y1,x2,y2) &&
+ !FastCheckAgainstScreen(x1,y1,x2,y2))
+ return 0;
+
+ if(bFakeFrontBuffer) bIgnoreNextTile=TRUE;
+ CheckVRamReadEx(x1,y1,x1+x2,y1+y2);
+ return 0;
+ }
+
+ /////////////////////////
+
+ if(FastCheckAgainstFrontScreen(x1,y1,x2,y2))
+ {
+ x1-=PSXDisplay.DisplayPosition.x;
+ y1-=PSXDisplay.DisplayPosition.y;
+ }
+ else
+ if(FastCheckAgainstScreen(x1,y1,x2,y2))
+ {
+ x1-=PreviousPSXDisplay.DisplayPosition.x;
+ y1-=PreviousPSXDisplay.DisplayPosition.y;
+ }
+ else return 0;
+
+ bDrawMultiPass = FALSE;
+
+ if(!gTexFrameName)
+ {
+ char * p;
+
+ if(iResX>1280 || iResY>1024) iFTex=2048;
+ else
+ if(iResX>640 || iResY>480) iFTex=1024;
+ else iFTex=512;
+
+ glGenTextures(1, &gTexFrameName);
+ gTexName=gTexFrameName;
+ glBindTexture(GL_TEXTURE_2D, gTexName);
+
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, iClampType);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, iClampType);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+
+ p=(char *)malloc(iFTex*iFTex*4);
+ memset(p,0,iFTex*iFTex*4);
+ glTexImage2D(GL_TEXTURE_2D, 0, 3, iFTex, iFTex, 0, GL_RGB, GL_UNSIGNED_BYTE, p);
+ free(p);
+
+ glGetError();
+ }
+ else
+ {
+ gTexName=gTexFrameName;
+ glBindTexture(GL_TEXTURE_2D, gTexName);
+ }
+
+ x1+=PreviousPSXDisplay.Range.x0;
+ y1+=PreviousPSXDisplay.Range.y0;
+
+ if(PSXDisplay.DisplayMode.x)
+ ScaleX=(float)rRatioRect.right/(float)PSXDisplay.DisplayMode.x;
+ else ScaleX=1.0f;
+ if(PSXDisplay.DisplayMode.y)
+ ScaleY=(float)rRatioRect.bottom/(float)PSXDisplay.DisplayMode.y;
+ else ScaleY=1.0f;
+
+ rSrc.left =max(x1*ScaleX,0);
+ rSrc.right =min((x1+x2)*ScaleX+0.99f,iResX-1);
+ rSrc.top =max(y1*ScaleY,0);
+ rSrc.bottom=min((y1+y2)*ScaleY+0.99f,iResY-1);
+
+ iYAdjust=(y1+y2)-PSXDisplay.DisplayMode.y;
+ if(iYAdjust>0)
+ iYAdjust=(int)((float)iYAdjust*ScaleY)+1;
+ else iYAdjust=0;
+
+ gl_vy[0]=255-gl_vy[0];
+ gl_vy[1]=255-gl_vy[1];
+ gl_vy[2]=255-gl_vy[2];
+ gl_vy[3]=255-gl_vy[3];
+
+ y1=min(gl_vy[0],min(gl_vy[1],min(gl_vy[2],gl_vy[3])));
+
+ gl_vy[0]-=y1;
+ gl_vy[1]-=y1;
+ gl_vy[2]-=y1;
+ gl_vy[3]-=y1;
+ gl_ux[0]-=gl_ux[7];
+ gl_ux[1]-=gl_ux[7];
+ gl_ux[2]-=gl_ux[7];
+ gl_ux[3]-=gl_ux[7];
+
+ ScaleX*=256.0f/((float)(iFTex));
+ ScaleY*=256.0f/((float)(iFTex));
+
+ y1=((float)gl_vy[0]*ScaleY); if(y1>255) y1=255;
+ gl_vy[0]=y1;
+ y1=((float)gl_vy[1]*ScaleY); if(y1>255) y1=255;
+ gl_vy[1]=y1;
+ y1=((float)gl_vy[2]*ScaleY); if(y1>255) y1=255;
+ gl_vy[2]=y1;
+ y1=((float)gl_vy[3]*ScaleY); if(y1>255) y1=255;
+ gl_vy[3]=y1;
+
+ x1=((float)gl_ux[0]*ScaleX); if(x1>255) x1=255;
+ gl_ux[0]=x1;
+ x1=((float)gl_ux[1]*ScaleX); if(x1>255) x1=255;
+ gl_ux[1]=x1;
+ x1=((float)gl_ux[2]*ScaleX); if(x1>255) x1=255;
+ gl_ux[2]=x1;
+ x1=((float)gl_ux[3]*ScaleX); if(x1>255) x1=255;
+ gl_ux[3]=x1;
+
+ x1=rSrc.right-rSrc.left;
+ if(x1<=0) x1=1;
+ if(x1>iFTex) x1=iFTex;
+
+ y1=rSrc.bottom-rSrc.top;
+ if(y1<=0) y1=1;
+ if(y1+iYAdjust>iFTex) y1=iFTex-iYAdjust;
+
+ if(bFakeFrontBuffer) glReadBuffer(GL_FRONT);
+
+ glCopyTexSubImage2D( GL_TEXTURE_2D, 0,
+ 0,
+ iYAdjust,
+ rSrc.left+rRatioRect.left,
+ iResY-rSrc.bottom-rRatioRect.top,
+ x1,y1);
+
+ if(glGetError())
+ {
+ char * p=(char *)malloc(iFTex*iFTex*4);
+ memset(p,0,iFTex*iFTex*4);
+ glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, iFTex, iFTex,
+ GL_RGB, GL_UNSIGNED_BYTE, p);
+ free(p);
+ }
+
+ if(bFakeFrontBuffer)
+ {glReadBuffer(GL_BACK);bIgnoreNextTile=TRUE;}
+
+ ubOpaqueDraw=0;
+
+ if(iSpriteTex)
+ {
+ sprtW=gl_ux[1]-gl_ux[0];
+ sprtH=-(gl_vy[0]-gl_vy[2]);
+ }
+
+ return (GLuint)gTexName;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+//
+// load texture part (unpacked)
+//
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+
+void LoadSubTexturePageSort(int pageid, int mode, short cx, short cy)
+{
+ uint32_t start,row,column,j,sxh,sxm;
+ unsigned int palstart;
+ uint32_t *px,*pa,*ta;
+ unsigned char *cSRCPtr;
+ unsigned short *wSRCPtr;
+ uint32_t LineOffset;
+ uint32_t x2a,xalign=0;
+ uint32_t x1=gl_ux[7];
+ uint32_t x2=gl_ux[6];
+ uint32_t y1=gl_ux[5];
+ uint32_t y2=gl_ux[4];
+ uint32_t dx=x2-x1+1;
+ uint32_t dy=y2-y1+1;
+ int pmult=pageid/16;
+ uint32_t (*LTCOL)(uint32_t);
+ unsigned int a,r,g,b,cnt,h;
+ uint32_t scol[8];
+
+ LTCOL=TCF[DrawSemiTrans];
+
+ pa=px=(uint32_t *)ubPaletteBuffer;
+ ta=(uint32_t *)texturepart;
+ palstart=cx+(cy<<10);
+
+ ubOpaqueDraw=0;
+
+ if(YTexS) {ta+=dx;if(XTexS) ta+=2;}
+ if(XTexS) {ta+=1;xalign=2;}
+
+ switch(mode)
+ {
+ //--------------------------------------------------//
+ // 4bit texture load ..
+ case 0:
+ if(GlobalTextIL)
+ {
+ unsigned int TXV,TXU,n_xi,n_yi;
+
+ wSRCPtr=psxVuw+palstart;
+
+ row=4;do
+ {
+ *px =LTCOL(*wSRCPtr);
+ *(px+1)=LTCOL(*(wSRCPtr+1));
+ *(px+2)=LTCOL(*(wSRCPtr+2));
+ *(px+3)=LTCOL(*(wSRCPtr+3));
+ row--;px+=4;wSRCPtr+=4;
+ }
+ while (row);
+
+ for(TXV=y1;TXV<=y2;TXV++)
+ {
+ for(TXU=x1;TXU<=x2;TXU++)
+ {
+ n_xi = ( ( TXU >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );
+ n_yi = ( TXV & ~0xf ) + ( ( TXU >> 4 ) & 0xf );
+
+ *ta++=*(pa+((*( psxVuw + ((GlobalTextAddrY + n_yi)*1024) + GlobalTextAddrX + n_xi ) >> ( ( TXU & 0x03 ) << 2 ) ) & 0x0f ));
+ }
+ ta+=xalign;
+ }
+ break;
+ }
+
+ start=((pageid-16*pmult)<<7)+524288*pmult;
+ // convert CLUT to 32bits .. and then use THAT as a lookup table
+
+ wSRCPtr=psxVuw+palstart;
+
+ row=4;do
+ {
+ *px =LTCOL(*wSRCPtr);
+ *(px+1)=LTCOL(*(wSRCPtr+1));
+ *(px+2)=LTCOL(*(wSRCPtr+2));
+ *(px+3)=LTCOL(*(wSRCPtr+3));
+ row--;px+=4;wSRCPtr+=4;
+ }
+ while (row);
+
+ x2a=x2?(x2-1):0;//if(x2) x2a=x2-1; else x2a=0;
+ sxm=x1&1;sxh=x1>>1;
+ j=sxm?(x1+1):x1;//if(sxm) j=x1+1; else j=x1;
+ for(column=y1;column<=y2;column++)
+ {
+ cSRCPtr = psxVub + start + (column<<11) + sxh;
+
+ if(sxm) *ta++=*(pa+((*cSRCPtr++ >> 4) & 0xF));
+
+ for(row=j;row<x2a;row+=2)
+ {
+ *ta =*(pa+(*cSRCPtr & 0xF));
+ *(ta+1)=*(pa+((*cSRCPtr >> 4) & 0xF));
+ cSRCPtr++;ta+=2;
+ }
+
+ if(row<=x2)
+ {
+ *ta++=*(pa+(*cSRCPtr & 0xF)); row++;
+ if(row<=x2) *ta++=*(pa+((*cSRCPtr >> 4) & 0xF));
+ }
+
+ ta+=xalign;
+ }
+
+ break;
+ //--------------------------------------------------//
+ // 8bit texture load ..
+ case 1:
+ if(GlobalTextIL)
+ {
+ unsigned int TXV,TXU,n_xi,n_yi;
+
+ wSRCPtr=psxVuw+palstart;
+
+ row=64;do
+ {
+ *px =LTCOL(*wSRCPtr);
+ *(px+1)=LTCOL(*(wSRCPtr+1));
+ *(px+2)=LTCOL(*(wSRCPtr+2));
+ *(px+3)=LTCOL(*(wSRCPtr+3));
+ row--;px+=4;wSRCPtr+=4;
+ }
+ while (row);
+
+ for(TXV=y1;TXV<=y2;TXV++)
+ {
+ for(TXU=x1;TXU<=x2;TXU++)
+ {
+ n_xi = ( ( TXU >> 1 ) & ~0x78 ) + ( ( TXU << 2 ) & 0x40 ) + ( ( TXV << 3 ) & 0x38 );
+ n_yi = ( TXV & ~0x7 ) + ( ( TXU >> 5 ) & 0x7 );
+
+ *ta++=*(pa+((*( psxVuw + ((GlobalTextAddrY + n_yi)*1024) + GlobalTextAddrX + n_xi ) >> ( ( TXU & 0x01 ) << 3 ) ) & 0xff));
+ }
+ ta+=xalign;
+ }
+
+ break;
+ }
+
+ start=((pageid-16*pmult)<<7)+524288*pmult;
+
+ cSRCPtr = psxVub + start + (y1<<11) + x1;
+ LineOffset = 2048 - dx;
+
+ if(dy*dx>384)
+ {
+ wSRCPtr=psxVuw+palstart;
+
+ row=64;do
+ {
+ *px =LTCOL(*wSRCPtr);
+ *(px+1)=LTCOL(*(wSRCPtr+1));
+ *(px+2)=LTCOL(*(wSRCPtr+2));
+ *(px+3)=LTCOL(*(wSRCPtr+3));
+ row--;px+=4;wSRCPtr+=4;
+ }
+ while (row);
+
+ column=dy;do
+ {
+ row=dx;
+ do {*ta++=*(pa+(*cSRCPtr++));row--;} while(row);
+ ta+=xalign;
+ cSRCPtr+=LineOffset;column--;
+ }
+ while(column);
+ }
+ else
+ {
+ wSRCPtr=psxVuw+palstart;
+
+ column=dy;do
+ {
+ row=dx;
+ do {*ta++=LTCOL(*(wSRCPtr+*cSRCPtr++));row--;} while(row);
+ ta+=xalign;
+ cSRCPtr+=LineOffset;column--;
+ }
+ while(column);
+ }
+
+ break;
+ //--------------------------------------------------//
+ // 16bit texture load ..
+ case 2:
+ start=((pageid-16*pmult)<<6)+262144*pmult;
+
+ wSRCPtr = psxVuw + start + (y1<<10) + x1;
+ LineOffset = 1024 - dx;
+
+ column=dy;do
+ {
+ row=dx;
+ do {*ta++=LTCOL(*wSRCPtr++);row--;} while(row);
+ ta+=xalign;
+ wSRCPtr+=LineOffset;column--;
+ }
+ while(column);
+
+ break;
+ //--------------------------------------------------//
+ // others are not possible !
+ }
+
+ x2a=dx+xalign;
+
+ if(YTexS)
+ {
+ ta=(uint32_t *)texturepart;
+ pa=(uint32_t *)texturepart+x2a;
+ row=x2a;do {*ta++=*pa++;row--;} while(row);
+ pa=(uint32_t *)texturepart+dy*x2a;
+ ta=pa+x2a;
+ row=x2a;do {*ta++=*pa++;row--;} while(row);
+ YTexS--;
+ dy+=2;
+ }
+
+ if(XTexS)
+ {
+ ta=(uint32_t *)texturepart;
+ pa=ta+1;
+ row=dy;do {*ta=*pa;ta+=x2a;pa+=x2a;row--;} while(row);
+ pa=(uint32_t *)texturepart+dx;
+ ta=pa+1;
+ row=dy;do {*ta=*pa;ta+=x2a;pa+=x2a;row--;} while(row);
+ XTexS--;
+ dx+=2;
+ }
+
+ DXTexS=dx;DYTexS=dy;
+
+ if(!iFilterType) {DefineSubTextureSort();return;}
+ if(iFilterType!=2 && iFilterType!=4 && iFilterType!=6) {DefineSubTextureSort();return;}
+ if((iFilterType==4 || iFilterType==6) && ly0==ly1 && ly2==ly3 && lx0==lx3 && lx1==lx2)
+ {DefineSubTextureSort();return;}
+
+ ta=(uint32_t *)texturepart;
+ x1=dx-1;
+ y1=dy-1;
+
+ if(bOpaquePass)
+ {
+ if(bSmallAlpha)
+ {
+ for(column=0;column<dy;column++)
+ {
+ for(row=0;row<dx;row++)
+ {
+ if(*ta==0x03000000)
+ {
+ cnt=0;
+
+ if( column && *(ta-dx) >>24 !=0x03) scol[cnt++]=*(ta-dx);
+ if(row && *(ta-1) >>24 !=0x03) scol[cnt++]=*(ta-1);
+ if(row!=x1 && *(ta+1) >>24 !=0x03) scol[cnt++]=*(ta+1);
+ if( column!=y1 && *(ta+dx) >>24 !=0x03) scol[cnt++]=*(ta+dx);
+
+ if(row && column && *(ta-dx-1)>>24 !=0x03) scol[cnt++]=*(ta-dx-1);
+ if(row!=x1 && column && *(ta-dx+1)>>24 !=0x03) scol[cnt++]=*(ta-dx+1);
+ if(row && column!=y1 && *(ta+dx-1)>>24 !=0x03) scol[cnt++]=*(ta+dx-1);
+ if(row!=x1 && column!=y1 && *(ta+dx+1)>>24 !=0x03) scol[cnt++]=*(ta+dx+1);
+
+ if(cnt)
+ {
+ r=g=b=a=0;
+ for(h=0;h<cnt;h++)
+ {
+ r+=(scol[h]>>16)&0xff;
+ g+=(scol[h]>>8)&0xff;
+ b+=scol[h]&0xff;
+ }
+ r/=cnt;b/=cnt;g/=cnt;
+
+ *ta=(r<<16)|(g<<8)|b;
+ *ta|=0x03000000;
+ }
+ }
+ ta++;
+ }
+ }
+ }
+ else
+ {
+ for(column=0;column<dy;column++)
+ {
+ for(row=0;row<dx;row++)
+ {
+ if(*ta==0x50000000)
+ {
+ cnt=0;
+
+ if( column && *(ta-dx) !=0x50000000 && *(ta-dx)>>24!=1) scol[cnt++]=*(ta-dx);
+ if(row && *(ta-1) !=0x50000000 && *(ta-1)>>24!=1) scol[cnt++]=*(ta-1);
+ if(row!=x1 && *(ta+1) !=0x50000000 && *(ta+1)>>24!=1) scol[cnt++]=*(ta+1);
+ if( column!=y1 && *(ta+dx) !=0x50000000 && *(ta+dx)>>24!=1) scol[cnt++]=*(ta+dx);
+
+ if(row && column && *(ta-dx-1)!=0x50000000 && *(ta-dx-1)>>24!=1) scol[cnt++]=*(ta-dx-1);
+ if(row!=x1 && column && *(ta-dx+1)!=0x50000000 && *(ta-dx+1)>>24!=1) scol[cnt++]=*(ta-dx+1);
+ if(row && column!=y1 && *(ta+dx-1)!=0x50000000 && *(ta+dx-1)>>24!=1) scol[cnt++]=*(ta+dx-1);
+ if(row!=x1 && column!=y1 && *(ta+dx+1)!=0x50000000 && *(ta+dx+1)>>24!=1) scol[cnt++]=*(ta+dx+1);
+
+ if(cnt)
+ {
+ r=g=b=a=0;
+ for(h=0;h<cnt;h++)
+ {
+ a+=(scol[h]>>24);
+ r+=(scol[h]>>16)&0xff;
+ g+=(scol[h]>>8)&0xff;
+ b+=scol[h]&0xff;
+ }
+ r/=cnt;b/=cnt;g/=cnt;
+
+ *ta=(r<<16)|(g<<8)|b;
+ if(a) *ta|=0x50000000;
+ else *ta|=0x01000000;
+ }
+ }
+ ta++;
+ }
+ }
+ }
+ }
+ else
+ for(column=0;column<dy;column++)
+ {
+ for(row=0;row<dx;row++)
+ {
+ if(*ta==0x00000000)
+ {
+ cnt=0;
+
+ if(row!=x1 && *(ta+1) !=0x00000000) scol[cnt++]=*(ta+1);
+ if( column!=y1 && *(ta+dx) !=0x00000000) scol[cnt++]=*(ta+dx);
+
+ if(cnt)
+ {
+ r=g=b=0;
+ for(h=0;h<cnt;h++)
+ {
+ r+=(scol[h]>>16)&0xff;
+ g+=(scol[h]>>8)&0xff;
+ b+=scol[h]&0xff;
+ }
+ r/=cnt;b/=cnt;g/=cnt;
+ *ta=(r<<16)|(g<<8)|b;
+ }
+ }
+ ta++;
+ }
+ }
+
+ DefineSubTextureSort();
+}
+
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+//
+// load texture part (packed)
+//
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+
+void LoadPackedSubTexturePageSort(int pageid, int mode, short cx, short cy)
+{
+ uint32_t start,row,column,j,sxh,sxm;
+ unsigned int palstart;
+ unsigned short *px,*pa,*ta;
+ unsigned char *cSRCPtr;
+ unsigned short *wSRCPtr;
+ uint32_t LineOffset;
+ uint32_t x2a,xalign=0;
+ uint32_t x1=gl_ux[7];
+ uint32_t x2=gl_ux[6];
+ uint32_t y1=gl_ux[5];
+ uint32_t y2=gl_ux[4];
+ uint32_t dx=x2-x1+1;
+ uint32_t dy=y2-y1+1;
+ int pmult=pageid/16;
+ unsigned short (*LPTCOL)(unsigned short);
+ unsigned int a,r,g,b,cnt,h;
+ unsigned short scol[8];
+
+ LPTCOL=PTCF[DrawSemiTrans];
+
+ pa=px=(unsigned short *)ubPaletteBuffer;
+ ta=(unsigned short *)texturepart;
+ palstart=cx+(cy<<10);
+
+ ubOpaqueDraw=0;
+
+ if(YTexS) {ta+=dx;if(XTexS) ta+=2;}
+ if(XTexS) {ta+=1;xalign=2;}
+
+ switch(mode)
+ {
+ //--------------------------------------------------//
+ // 4bit texture load ..
+ case 0:
+ if(GlobalTextIL)
+ {
+ unsigned int TXV,TXU,n_xi,n_yi;
+
+ wSRCPtr=psxVuw+palstart;
+ row=4;do
+ {
+ *px =LPTCOL(*wSRCPtr);
+ *(px+1)=LPTCOL(*(wSRCPtr+1));
+ *(px+2)=LPTCOL(*(wSRCPtr+2));
+ *(px+3)=LPTCOL(*(wSRCPtr+3));
+ row--;px+=4;wSRCPtr+=4;
+ }
+ while (row);
+
+ for(TXV=y1;TXV<=y2;TXV++)
+ {
+ for(TXU=x1;TXU<=x2;TXU++)
+ {
+ n_xi = ( ( TXU >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );
+ n_yi = ( TXV & ~0xf ) + ( ( TXU >> 4 ) & 0xf );
+
+ *ta++=*(pa+((*( psxVuw + ((GlobalTextAddrY + n_yi)*1024) + GlobalTextAddrX + n_xi ) >> ( ( TXU & 0x03 ) << 2 ) ) & 0x0f ));
+ }
+ ta+=xalign;
+ }
+ break;
+ }
+
+ start=((pageid-16*pmult)<<7)+524288*pmult;
+
+ wSRCPtr=psxVuw+palstart;
+ row=4;do
+ {
+ *px =LPTCOL(*wSRCPtr);
+ *(px+1)=LPTCOL(*(wSRCPtr+1));
+ *(px+2)=LPTCOL(*(wSRCPtr+2));
+ *(px+3)=LPTCOL(*(wSRCPtr+3));
+ row--;px+=4;wSRCPtr+=4;
+ }
+ while (row);
+
+ x2a=x2?(x2-1):0;//if(x2) x2a=x2-1; else x2a=0;
+ sxm=x1&1;sxh=x1>>1;
+ j=sxm?(x1+1):x1;//if(sxm) j=x1+1; else j=x1;
+
+ for(column=y1;column<=y2;column++)
+ {
+ cSRCPtr = psxVub + start + (column<<11) + sxh;
+
+ if(sxm) *ta++=*(pa+((*cSRCPtr++ >> 4) & 0xF));
+
+ for(row=j;row<x2a;row+=2)
+ {
+ *ta =*(pa+(*cSRCPtr & 0xF));
+ *(ta+1)=*(pa+((*cSRCPtr >> 4) & 0xF));
+ cSRCPtr++;ta+=2;
+ }
+
+ if(row<=x2)
+ {
+ *ta++=*(pa+(*cSRCPtr & 0xF));row++;
+ if(row<=x2) *ta++=*(pa+((*cSRCPtr >> 4) & 0xF));
+ }
+
+ ta+=xalign;
+ }
+ break;
+ //--------------------------------------------------//
+ // 8bit texture load ..
+ case 1:
+ if(GlobalTextIL)
+ {
+ unsigned int TXV,TXU,n_xi,n_yi;
+
+ wSRCPtr=psxVuw+palstart;
+
+ row=64;do
+ {
+ *px =LPTCOL(*wSRCPtr);
+ *(px+1)=LPTCOL(*(wSRCPtr+1));
+ *(px+2)=LPTCOL(*(wSRCPtr+2));
+ *(px+3)=LPTCOL(*(wSRCPtr+3));
+ row--;px+=4;wSRCPtr+=4;
+ }
+ while (row);
+
+ for(TXV=y1;TXV<=y2;TXV++)
+ {
+ for(TXU=x1;TXU<=x2;TXU++)
+ {
+ n_xi = ( ( TXU >> 1 ) & ~0x78 ) + ( ( TXU << 2 ) & 0x40 ) + ( ( TXV << 3 ) & 0x38 );
+ n_yi = ( TXV & ~0x7 ) + ( ( TXU >> 5 ) & 0x7 );
+
+ *ta++=*(pa+((*( psxVuw + ((GlobalTextAddrY + n_yi)*1024) + GlobalTextAddrX + n_xi ) >> ( ( TXU & 0x01 ) << 3 ) ) & 0xff));
+ }
+ ta+=xalign;
+ }
+
+ break;
+ }
+
+ start=((pageid-16*pmult)<<7)+524288*pmult;
+
+ cSRCPtr = psxVub + start + (y1<<11) + x1;
+ LineOffset = 2048 - dx;
+
+ if(dy*dx>384) // more pix? use lut
+ {
+ wSRCPtr=psxVuw+palstart;
+
+ row=64;do
+ {
+ *px =LPTCOL(*wSRCPtr);
+ *(px+1)=LPTCOL(*(wSRCPtr+1));
+ *(px+2)=LPTCOL(*(wSRCPtr+2));
+ *(px+3)=LPTCOL(*(wSRCPtr+3));
+ row--;px+=4;wSRCPtr+=4;
+ }
+ while (row);
+
+ column=dy;do
+ {
+ row=dx;
+ do {*ta++=*(pa+(*cSRCPtr++));row--;} while(row);
+
+ ta+=xalign;
+
+ cSRCPtr+=LineOffset;column--;
+ }
+ while(column);
+ }
+ else // small area? no lut
+ {
+ wSRCPtr=psxVuw+palstart;
+
+ column=dy;do
+ {
+ row=dx;
+ do {*ta++=LPTCOL(*(wSRCPtr+*cSRCPtr++));row--;} while(row);
+
+ ta+=xalign;
+
+ cSRCPtr+=LineOffset;column--;
+ }
+ while(column);
+ }
+ break;
+ //--------------------------------------------------//
+ // 16bit texture load ..
+ case 2:
+ start=((pageid-16*pmult)<<6)+262144*pmult;
+
+ wSRCPtr = psxVuw + start + (y1<<10) + x1;
+ LineOffset = 1024 - dx;
+
+ column=dy;do
+ {
+ row=dx;
+ do {*ta++=LPTCOL(*wSRCPtr++);row--;} while(row);
+
+ ta+=xalign;
+
+ wSRCPtr+=LineOffset;column--;
+ }
+ while(column);
+ break;
+ //--------------------------------------------------//
+ // others are not possible !
+ }
+
+ ////////////////////////////////////////////////////////
+
+ x2a=dx+xalign;
+
+ if(YTexS)
+ {
+ ta=(unsigned short *)texturepart;
+ pa=(unsigned short *)texturepart+x2a;
+ row=x2a;do {*ta++=*pa++;row--;} while(row);
+
+ pa=(unsigned short *)texturepart+dy*x2a;
+ ta=pa+x2a;
+ row=x2a;do {*ta++=*pa++;row--;} while(row);
+
+ YTexS--;
+ dy+=2;
+ }
+
+ if(XTexS)
+ {
+ ta=(unsigned short *)texturepart;
+ pa=ta+1;
+ row=dy;do {*ta=*pa;ta+=x2a;pa+=x2a;row--;} while(row);
+
+ pa=(unsigned short *)texturepart+dx;
+ ta=pa+1;
+ row=dy;do {*ta=*pa;ta+=x2a;pa+=x2a;row--;} while(row);
+
+ XTexS--;
+ dx+=2;
+ }
+
+ DXTexS=dx;DYTexS=dy;
+
+ if(!iFilterType) {DefineSubTextureSort();return;}
+ if(iFilterType!=2 && iFilterType!=4 && iFilterType!=6) {DefineSubTextureSort();return;}
+ if((iFilterType==4 || iFilterType==6) && ly0==ly1 && ly2==ly3 && lx0==lx3 && lx1==lx2)
+ {DefineSubTextureSort();return;}
+
+ ta=(unsigned short *)texturepart;
+ x1=dx-1;
+ y1=dy-1;
+
+ if(iTexQuality==1)
+
+ {
+ if(bOpaquePass)
+ for(column=0;column<dy;column++)
+ {
+ for(row=0;row<dx;row++)
+ {
+ if(*ta==0x0006)
+ {
+ cnt=0;
+
+ if( column && *(ta-dx) != 0x0006 && *(ta-dx)!=0) scol[cnt++]=*(ta-dx);
+ if(row && *(ta-1) != 0x0006 && *(ta-1) !=0) scol[cnt++]=*(ta-1);
+ if(row!=x1 && *(ta+1) != 0x0006 && *(ta+1) !=0) scol[cnt++]=*(ta+1);
+ if( column!=y1 && *(ta+dx) != 0x0006 && *(ta+dx)!=0) scol[cnt++]=*(ta+dx);
+
+ if(row && column && *(ta-dx-1)!= 0x0006 && *(ta-dx-1)!=0) scol[cnt++]=*(ta-dx-1);
+ if(row!=x1 && column && *(ta-dx+1)!= 0x0006 && *(ta-dx+1)!=0) scol[cnt++]=*(ta-dx+1);
+ if(row && column!=y1 && *(ta+dx-1)!= 0x0006 && *(ta+dx-1)!=0) scol[cnt++]=*(ta+dx-1);
+ if(row!=x1 && column!=y1 && *(ta+dx+1)!= 0x0006 && *(ta+dx+1)!=0) scol[cnt++]=*(ta+dx+1);
+
+ if(cnt)
+ {
+ r=g=b=a=0;
+ for(h=0;h<cnt;h++)
+ {
+ a+=scol[h]&0xf;
+ r+=scol[h]>>12;
+ g+=(scol[h]>>8)&0xf;
+ b+=(scol[h]>>4)&0xf;
+ }
+ r/=cnt;b/=cnt;g/=cnt;
+ *ta=(r<<12)|(g<<8)|(b<<4);
+ if(a) *ta|=6;
+ else *ta=0;
+ }
+ }
+ ta++;
+ }
+ }
+ else
+ for(column=0;column<dy;column++)
+ {
+ for(row=0;row<dx;row++)
+ {
+ if(*ta==0x0000)
+ {
+ cnt=0;
+
+ if( column && *(ta-dx) != 0x0000) scol[cnt++]=*(ta-dx);
+ if(row && *(ta-1) != 0x0000) scol[cnt++]=*(ta-1);
+ if(row!=x1 && *(ta+1) != 0x0000) scol[cnt++]=*(ta+1);
+ if( column!=y1 && *(ta+dx) != 0x0000) scol[cnt++]=*(ta+dx);
+
+ if(row && column && *(ta-dx-1)!= 0x0000) scol[cnt++]=*(ta-dx-1);
+ if(row!=x1 && column && *(ta-dx+1)!= 0x0000) scol[cnt++]=*(ta-dx+1);
+ if(row && column!=y1 && *(ta+dx-1)!= 0x0000) scol[cnt++]=*(ta+dx-1);
+ if(row!=x1 && column!=y1 && *(ta+dx+1)!= 0x0000) scol[cnt++]=*(ta+dx+1);
+
+ if(cnt)
+ {
+ r=g=b=0;
+ for(h=0;h<cnt;h++)
+ {
+ r+=scol[h]>>12;
+ g+=(scol[h]>>8)&0xf;
+ b+=(scol[h]>>4)&0xf;
+ }
+ r/=cnt;b/=cnt;g/=cnt;
+ *ta=(r<<12)|(g<<8)|(b<<4);
+ }
+ }
+ ta++;
+ }
+ }
+ }
+ else
+ {
+ for(column=0;column<dy;column++)
+ {
+ for(row=0;row<dx;row++)
+ {
+ if(*ta==0)
+ {
+ cnt=0;
+
+ if( column && *(ta-dx) &1) scol[cnt++]=*(ta-dx);
+ if(row && *(ta-1) &1) scol[cnt++]=*(ta-1);
+ if(row!=x1 && *(ta+1) &1) scol[cnt++]=*(ta+1);
+ if( column!=y1 && *(ta+dx) &1) scol[cnt++]=*(ta+dx);
+
+ if(row && column && *(ta-dx-1)&1) scol[cnt++]=*(ta-dx-1);
+ if(row!=x1 && column && *(ta-dx+1)&1) scol[cnt++]=*(ta-dx+1);
+ if(row && column!=y1 && *(ta+dx-1)&1) scol[cnt++]=*(ta+dx-1);
+ if(row!=x1 && column!=y1 && *(ta+dx+1)&1) scol[cnt++]=*(ta+dx+1);
+
+ if(cnt)
+ {
+ r=g=b=0;
+ for(h=0;h<cnt;h++)
+ {
+ r+=scol[h]>>11;
+ g+=(scol[h]>>6)&0x1f;
+ b+=(scol[h]>>1)&0x1f;
+ }
+ r/=cnt;b/=cnt;g/=cnt;
+ *ta=(r<<11)|(g<<6)|(b<<1);
+ }
+ }
+ ta++;
+ }
+ }
+ }
+
+ DefineSubTextureSort();
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+//
+// hires texture funcs
+//
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+
+
+#define GET_RESULT(A, B, C, D) ((A != C || A != D) - (B != C || B != D))
+
+////////////////////////////////////////////////////////////////////////
+
+#define colorMask8 0x00FEFEFE
+#define lowPixelMask8 0x00010101
+#define qcolorMask8 0x00FCFCFC
+#define qlowpixelMask8 0x00030303
+
+
+#define INTERPOLATE8_02(A, B) (((((A & colorMask8) >> 1) + ((B & colorMask8) >> 1) + (A & B & lowPixelMask8))|((((A&0xFF000000)==0x03000000)?0x03000000:(((B&0xFF000000)==0x03000000)?0x03000000:(((A&0xFF000000)==0x00000000)?0x00000000:(((B&0xFF000000)==0x00000000)?0x00000000:0xFF000000)))))))
+
+#define Q_INTERPOLATE8_02(A, B, C, D) (((((A & qcolorMask8) >> 2) + ((B & qcolorMask8) >> 2) + ((C & qcolorMask8) >> 2) + ((D & qcolorMask8) >> 2) + ((((A & qlowpixelMask8) + (B & qlowpixelMask8) + (C & qlowpixelMask8) + (D & qlowpixelMask8)) >> 2) & qlowpixelMask8))|((((A&0xFF000000)==0x03000000)?0x03000000:(((B&0xFF000000)==0x03000000)?0x03000000:(((C&0xFF000000)==0x03000000)?0x03000000:(((D&0xFF000000)==0x03000000)?0x03000000:(((A&0xFF000000)==0x00000000)?0x00000000:(((B&0xFF000000)==0x00000000)?0x00000000:(((C&0xFF000000)==0x00000000)?0x00000000:(((D&0xFF000000)==0x00000000)?0x00000000:0xFF000000)))))))))))
+
+#define INTERPOLATE8(A, B) (((((A & colorMask8) >> 1) + ((B & colorMask8) >> 1) + (A & B & lowPixelMask8))|((((A&0xFF000000)==0x50000000)?0x50000000:(((B&0xFF000000)==0x50000000)?0x50000000:(((A&0xFF000000)==0x00000000)?0x00000000:(((B&0xFF000000)==0x00000000)?0x00000000:0xFF000000)))))))
+
+#define Q_INTERPOLATE8(A, B, C, D) (((((A & qcolorMask8) >> 2) + ((B & qcolorMask8) >> 2) + ((C & qcolorMask8) >> 2) + ((D & qcolorMask8) >> 2) + ((((A & qlowpixelMask8) + (B & qlowpixelMask8) + (C & qlowpixelMask8) + (D & qlowpixelMask8)) >> 2) & qlowpixelMask8))|((((A&0xFF000000)==0x50000000)?0x50000000:(((B&0xFF000000)==0x50000000)?0x50000000:(((C&0xFF000000)==0x50000000)?0x50000000:(((D&0xFF000000)==0x50000000)?0x50000000:(((A&0xFF000000)==0x00000000)?0x00000000:(((B&0xFF000000)==0x00000000)?0x00000000:(((C&0xFF000000)==0x00000000)?0x00000000:(((D&0xFF000000)==0x00000000)?0x00000000:0xFF000000)))))))))))
+
+void Super2xSaI_ex8_Ex(unsigned char *srcPtr, DWORD srcPitch,
+ unsigned char *dstBitmap, int width, int height)
+{
+ DWORD dstPitch = srcPitch * 2;
+ DWORD line;
+ DWORD *dP;
+ DWORD *bP;
+ int width2 = width*2;
+ int iXA,iXB,iXC,iYA,iYB,iYC,finish;
+ DWORD color4, color5, color6;
+ DWORD color1, color2, color3;
+ DWORD colorA0, colorA1, colorA2, colorA3,
+ colorB0, colorB1, colorB2, colorB3,
+ colorS1, colorS2;
+ DWORD product1a, product1b,
+ product2a, product2b;
+
+ line = 0;
+
+ {
+ for (; height; height-=1)
+ {
+ bP = (DWORD *)srcPtr;
+ dP = (DWORD *)(dstBitmap + line*dstPitch);
+ for (finish = width; finish; finish -= 1 )
+ {
+//--------------------------------------- B1 B2
+// 4 5 6 S2
+// 1 2 3 S1
+// A1 A2
+ if(finish==width) iXA=0;
+ else iXA=1;
+ if(finish>4) {iXB=1;iXC=2;}
+ else
+ if(finish>3) {iXB=1;iXC=1;}
+ else {iXB=0;iXC=0;}
+ if(line==0) iYA=0;
+ else iYA=width;
+ if(height>4) {iYB=width;iYC=width2;}
+ else
+ if(height>3) {iYB=width;iYC=width;}
+ else {iYB=0;iYC=0;}
+
+
+ colorB0 = *(bP- iYA - iXA);
+ colorB1 = *(bP- iYA);
+ colorB2 = *(bP- iYA + iXB);
+ colorB3 = *(bP- iYA + iXC);
+
+ color4 = *(bP - iXA);
+ color5 = *(bP);
+ color6 = *(bP + iXB);
+ colorS2 = *(bP + iXC);
+
+ color1 = *(bP + iYB - iXA);
+ color2 = *(bP + iYB);
+ color3 = *(bP + iYB + iXB);
+ colorS1= *(bP + iYB + iXC);
+
+ colorA0 = *(bP + iYC - iXA);
+ colorA1 = *(bP + iYC);
+ colorA2 = *(bP + iYC + iXB);
+ colorA3 = *(bP + iYC + iXC);
+
+//--------------------------------------
+ if (color2 == color6 && color5 != color3)
+ {
+ product2b = product1b = color2;
+ }
+ else
+ if (color5 == color3 && color2 != color6)
+ {
+ product2b = product1b = color5;
+ }
+ else
+ if (color5 == color3 && color2 == color6)
+ {
+ register int r = 0;
+
+ r += GET_RESULT ((color6&0x00ffffff), (color5&0x00ffffff), (color1&0x00ffffff), (colorA1&0x00ffffff));
+ r += GET_RESULT ((color6&0x00ffffff), (color5&0x00ffffff), (color4&0x00ffffff), (colorB1&0x00ffffff));
+ r += GET_RESULT ((color6&0x00ffffff), (color5&0x00ffffff), (colorA2&0x00ffffff), (colorS1&0x00ffffff));
+ r += GET_RESULT ((color6&0x00ffffff), (color5&0x00ffffff), (colorB2&0x00ffffff), (colorS2&0x00ffffff));
+
+ if (r > 0)
+ product2b = product1b = color6;
+ else
+ if (r < 0)
+ product2b = product1b = color5;
+ else
+ {
+ product2b = product1b = INTERPOLATE8_02(color5, color6);
+ }
+ }
+ else
+ {
+ if (color6 == color3 && color3 == colorA1 && color2 != colorA2 && color3 != colorA0)
+ product2b = Q_INTERPOLATE8_02 (color3, color3, color3, color2);
+ else
+ if (color5 == color2 && color2 == colorA2 && colorA1 != color3 && color2 != colorA3)
+ product2b = Q_INTERPOLATE8_02 (color2, color2, color2, color3);
+ else
+ product2b = INTERPOLATE8_02 (color2, color3);
+
+ if (color6 == color3 && color6 == colorB1 && color5 != colorB2 && color6 != colorB0)
+ product1b = Q_INTERPOLATE8_02 (color6, color6, color6, color5);
+ else
+ if (color5 == color2 && color5 == colorB2 && colorB1 != color6 && color5 != colorB3)
+ product1b = Q_INTERPOLATE8_02 (color6, color5, color5, color5);
+ else
+ product1b = INTERPOLATE8_02 (color5, color6);
+ }
+
+ if (color5 == color3 && color2 != color6 && color4 == color5 && color5 != colorA2)
+ product2a = INTERPOLATE8_02(color2, color5);
+ else
+ if (color5 == color1 && color6 == color5 && color4 != color2 && color5 != colorA0)
+ product2a = INTERPOLATE8_02(color2, color5);
+ else
+ product2a = color2;
+
+ if (color2 == color6 && color5 != color3 && color1 == color2 && color2 != colorB2)
+ product1a = INTERPOLATE8_02(color2, color5);
+ else
+ if (color4 == color2 && color3 == color2 && color1 != color5 && color2 != colorB0)
+ product1a = INTERPOLATE8_02(color2, color5);
+ else
+ product1a = color5;
+
+ *dP=product1a;
+ *(dP+1)=product1b;
+ *(dP+(width2))=product2a;
+ *(dP+1+(width2))=product2b;
+
+ bP += 1;
+ dP += 2;
+ }//end of for ( finish= width etc..)
+
+ line += 2;
+ srcPtr += srcPitch;
+ }; //endof: for (; height; height--)
+ }
+}
+
+
+void Super2xSaI_ex8(unsigned char *srcPtr, DWORD srcPitch,
+ unsigned char *dstBitmap, int width, int height)
+{
+ DWORD dstPitch = srcPitch * 2;
+ DWORD line;
+ DWORD *dP;
+ DWORD *bP;
+ int width2 = width*2;
+ int iXA,iXB,iXC,iYA,iYB,iYC,finish;
+ DWORD color4, color5, color6;
+ DWORD color1, color2, color3;
+ DWORD colorA0, colorA1, colorA2, colorA3,
+ colorB0, colorB1, colorB2, colorB3,
+ colorS1, colorS2;
+ DWORD product1a, product1b,
+ product2a, product2b;
+
+ line = 0;
+
+ {
+ for (; height; height-=1)
+ {
+ bP = (DWORD *)srcPtr;
+ dP = (DWORD *)(dstBitmap + line*dstPitch);
+ for (finish = width; finish; finish -= 1 )
+ {
+//--------------------------------------- B1 B2
+// 4 5 6 S2
+// 1 2 3 S1
+// A1 A2
+ if(finish==width) iXA=0;
+ else iXA=1;
+ if(finish>4) {iXB=1;iXC=2;}
+ else
+ if(finish>3) {iXB=1;iXC=1;}
+ else {iXB=0;iXC=0;}
+ if(line==0) iYA=0;
+ else iYA=width;
+ if(height>4) {iYB=width;iYC=width2;}
+ else
+ if(height>3) {iYB=width;iYC=width;}
+ else {iYB=0;iYC=0;}
+
+
+ colorB0 = *(bP- iYA - iXA);
+ colorB1 = *(bP- iYA);
+ colorB2 = *(bP- iYA + iXB);
+ colorB3 = *(bP- iYA + iXC);
+
+ color4 = *(bP - iXA);
+ color5 = *(bP);
+ color6 = *(bP + iXB);
+ colorS2 = *(bP + iXC);
+
+ color1 = *(bP + iYB - iXA);
+ color2 = *(bP + iYB);
+ color3 = *(bP + iYB + iXB);
+ colorS1= *(bP + iYB + iXC);
+
+ colorA0 = *(bP + iYC - iXA);
+ colorA1 = *(bP + iYC);
+ colorA2 = *(bP + iYC + iXB);
+ colorA3 = *(bP + iYC + iXC);
+
+//--------------------------------------
+ if (color2 == color6 && color5 != color3)
+ {
+ product2b = product1b = color2;
+ }
+ else
+ if (color5 == color3 && color2 != color6)
+ {
+ product2b = product1b = color5;
+ }
+ else
+ if (color5 == color3 && color2 == color6)
+ {
+ register int r = 0;
+
+ r += GET_RESULT ((color6&0x00ffffff), (color5&0x00ffffff), (color1&0x00ffffff), (colorA1&0x00ffffff));
+ r += GET_RESULT ((color6&0x00ffffff), (color5&0x00ffffff), (color4&0x00ffffff), (colorB1&0x00ffffff));
+ r += GET_RESULT ((color6&0x00ffffff), (color5&0x00ffffff), (colorA2&0x00ffffff), (colorS1&0x00ffffff));
+ r += GET_RESULT ((color6&0x00ffffff), (color5&0x00ffffff), (colorB2&0x00ffffff), (colorS2&0x00ffffff));
+
+ if (r > 0)
+ product2b = product1b = color6;
+ else
+ if (r < 0)
+ product2b = product1b = color5;
+ else
+ {
+ product2b = product1b = INTERPOLATE8(color5, color6);
+ }
+ }
+ else
+ {
+ if (color6 == color3 && color3 == colorA1 && color2 != colorA2 && color3 != colorA0)
+ product2b = Q_INTERPOLATE8 (color3, color3, color3, color2);
+ else
+ if (color5 == color2 && color2 == colorA2 && colorA1 != color3 && color2 != colorA3)
+ product2b = Q_INTERPOLATE8 (color2, color2, color2, color3);
+ else
+ product2b = INTERPOLATE8 (color2, color3);
+
+ if (color6 == color3 && color6 == colorB1 && color5 != colorB2 && color6 != colorB0)
+ product1b = Q_INTERPOLATE8 (color6, color6, color6, color5);
+ else
+ if (color5 == color2 && color5 == colorB2 && colorB1 != color6 && color5 != colorB3)
+ product1b = Q_INTERPOLATE8 (color6, color5, color5, color5);
+ else
+ product1b = INTERPOLATE8 (color5, color6);
+ }
+
+ if (color5 == color3 && color2 != color6 && color4 == color5 && color5 != colorA2)
+ product2a = INTERPOLATE8(color2, color5);
+ else
+ if (color5 == color1 && color6 == color5 && color4 != color2 && color5 != colorA0)
+ product2a = INTERPOLATE8(color2, color5);
+ else
+ product2a = color2;
+
+ if (color2 == color6 && color5 != color3 && color1 == color2 && color2 != colorB2)
+ product1a = INTERPOLATE8(color2, color5);
+ else
+ if (color4 == color2 && color3 == color2 && color1 != color5 && color2 != colorB0)
+ product1a = INTERPOLATE8(color2, color5);
+ else
+ product1a = color5;
+
+ *dP=product1a;
+ *(dP+1)=product1b;
+ *(dP+(width2))=product2a;
+ *(dP+1+(width2))=product2b;
+
+ bP += 1;
+ dP += 2;
+ }//end of for ( finish= width etc..)
+
+ line += 2;
+ srcPtr += srcPitch;
+ }; //endof: for (; height; height--)
+ }
+}
+/////////////////////////////////////////////////////////////////////////////
+
+#define colorMask4 0x0000EEE0
+#define lowPixelMask4 0x00001110
+#define qcolorMask4 0x0000CCC0
+#define qlowpixelMask4 0x00003330
+
+#define INTERPOLATE4(A, B) ((((A & colorMask4) >> 1) + ((B & colorMask4) >> 1) + (A & B & lowPixelMask4))|((((A&0x0000000F)==0x00000006)?0x00000006:(((B&0x0000000F)==0x00000006)?0x00000006:(((A&0x0000000F)==0x00000000)?0x00000000:(((B&0x0000000F)==0x00000000)?0x00000000:0x0000000F))))))
+
+#define Q_INTERPOLATE4(A, B, C, D) ((((A & qcolorMask4) >> 2) + ((B & qcolorMask4) >> 2) + ((C & qcolorMask4) >> 2) + ((D & qcolorMask4) >> 2) + ((((A & qlowpixelMask4) + (B & qlowpixelMask4) + (C & qlowpixelMask4) + (D & qlowpixelMask4)) >> 2) & qlowpixelMask4))| ((((A&0x0000000F)==0x00000006)?0x00000006:(((B&0x0000000F)==0x00000006)?0x00000006:(((C&0x0000000F)==0x00000006)?0x00000006:(((D&0x0000000F)==0x00000006)?0x00000006:(((A&0x0000000F)==0x00000000)?0x00000000:(((B&0x0000000F)==0x00000000)?0x00000000:(((C&0x0000000F)==0x00000000)?0x00000000:(((D&0x0000000F)==0x00000000)?0x00000000:0x0000000F))))))))))
+
+void Super2xSaI_ex4(unsigned char *srcPtr, DWORD srcPitch,
+ unsigned char *dstBitmap, int width, int height)
+{
+ DWORD dstPitch = srcPitch * 2;
+ DWORD line;
+ unsigned short *dP;
+ unsigned short *bP;
+ int width2 = width*2;
+ int iXA,iXB,iXC,iYA,iYB,iYC,finish;
+ DWORD color4, color5, color6;
+ DWORD color1, color2, color3;
+ DWORD colorA0, colorA1, colorA2, colorA3,
+ colorB0, colorB1, colorB2, colorB3,
+ colorS1, colorS2;
+ DWORD product1a, product1b,
+ product2a, product2b;
+
+ line = 0;
+
+ {
+ for (; height; height-=1)
+ {
+ bP = (unsigned short *)srcPtr;
+ dP = (unsigned short *)(dstBitmap + line*dstPitch);
+ for (finish = width; finish; finish -= 1 )
+ {
+//--------------------------------------- B1 B2
+// 4 5 6 S2
+// 1 2 3 S1
+// A1 A2
+ if(finish==width) iXA=0;
+ else iXA=1;
+ if(finish>4) {iXB=1;iXC=2;}
+ else
+ if(finish>3) {iXB=1;iXC=1;}
+ else {iXB=0;iXC=0;}
+ if(line==0) iYA=0;
+ else iYA=width;
+ if(height>4) {iYB=width;iYC=width2;}
+ else
+ if(height>3) {iYB=width;iYC=width;}
+ else {iYB=0;iYC=0;}
+
+
+ colorB0 = *(bP- iYA - iXA);
+ colorB1 = *(bP- iYA);
+ colorB2 = *(bP- iYA + iXB);
+ colorB3 = *(bP- iYA + iXC);
+
+ color4 = *(bP - iXA);
+ color5 = *(bP);
+ color6 = *(bP + iXB);
+ colorS2 = *(bP + iXC);
+
+ color1 = *(bP + iYB - iXA);
+ color2 = *(bP + iYB);
+ color3 = *(bP + iYB + iXB);
+ colorS1= *(bP + iYB + iXC);
+
+ colorA0 = *(bP + iYC - iXA);
+ colorA1 = *(bP + iYC);
+ colorA2 = *(bP + iYC + iXB);
+ colorA3 = *(bP + iYC + iXC);
+
+//--------------------------------------
+ if (color2 == color6 && color5 != color3)
+ {
+ product2b = product1b = color2;
+ }
+ else
+ if (color5 == color3 && color2 != color6)
+ {
+ product2b = product1b = color5;
+ }
+ else
+ if (color5 == color3 && color2 == color6)
+ {
+ register int r = 0;
+
+ r += GET_RESULT ((color6&0xfffffff0), (color5&0xfffffff0), (color1&0xfffffff0), (colorA1&0xfffffff0));
+ r += GET_RESULT ((color6&0xfffffff0), (color5&0xfffffff0), (color4&0xfffffff0), (colorB1&0xfffffff0));
+ r += GET_RESULT ((color6&0xfffffff0), (color5&0xfffffff0), (colorA2&0xfffffff0), (colorS1&0xfffffff0));
+ r += GET_RESULT ((color6&0xfffffff0), (color5&0xfffffff0), (colorB2&0xfffffff0), (colorS2&0xfffffff0));
+
+ if (r > 0)
+ product2b = product1b = color6;
+ else
+ if (r < 0)
+ product2b = product1b = color5;
+ else
+ {
+ product2b = product1b = INTERPOLATE4 (color5, color6);
+ }
+ }
+ else
+ {
+ if (color6 == color3 && color3 == colorA1 && color2 != colorA2 && color3 != colorA0)
+ product2b = Q_INTERPOLATE4 (color3, color3, color3, color2);
+ else
+ if (color5 == color2 && color2 == colorA2 && colorA1 != color3 && color2 != colorA3)
+ product2b = Q_INTERPOLATE4 (color2, color2, color2, color3);
+ else
+ product2b = INTERPOLATE4 (color2, color3);
+
+ if (color6 == color3 && color6 == colorB1 && color5 != colorB2 && color6 != colorB0)
+ product1b = Q_INTERPOLATE4 (color6, color6, color6, color5);
+ else
+ if (color5 == color2 && color5 == colorB2 && colorB1 != color6 && color5 != colorB3)
+ product1b = Q_INTERPOLATE4 (color6, color5, color5, color5);
+ else
+ product1b = INTERPOLATE4 (color5, color6);
+ }
+
+ if (color5 == color3 && color2 != color6 && color4 == color5 && color5 != colorA2)
+ product2a = INTERPOLATE4 (color2, color5);
+ else
+ if (color5 == color1 && color6 == color5 && color4 != color2 && color5 != colorA0)
+ product2a = INTERPOLATE4(color2, color5);
+ else
+ product2a = color2;
+
+ if (color2 == color6 && color5 != color3 && color1 == color2 && color2 != colorB2)
+ product1a = INTERPOLATE4 (color2, color5);
+ else
+ if (color4 == color2 && color3 == color2 && color1 != color5 && color2 != colorB0)
+ product1a = INTERPOLATE4(color2, color5);
+ else
+ product1a = color5;
+
+ *dP=product1a;
+ *(dP+1)=product1b;
+ *(dP+(width2))=product2a;
+ *(dP+1+(width2))=product2b;
+
+ bP += 1;
+ dP += 2;
+ }//end of for ( finish= width etc..)
+
+ line += 2;
+ srcPtr += srcPitch;
+ }; //endof: for (; height; height--)
+ }
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+#define colorMask5 0x0000F7BC
+#define lowPixelMask5 0x00000842
+#define qcolorMask5 0x0000E738
+#define qlowpixelMask5 0x000018C6
+
+#define INTERPOLATE5(A, B) ((((A & colorMask5) >> 1) + ((B & colorMask5) >> 1) + (A & B & lowPixelMask5))|((((A&0x00000001)==0x00000000)?0x00000000:(((B&0x00000001)==0x00000000)?0x00000000:0x00000001))))
+
+#define Q_INTERPOLATE5(A, B, C, D) ((((A & qcolorMask5) >> 2) + ((B & qcolorMask5) >> 2) + ((C & qcolorMask5) >> 2) + ((D & qcolorMask5) >> 2) + ((((A & qlowpixelMask5) + (B & qlowpixelMask5) + (C & qlowpixelMask5) + (D & qlowpixelMask5)) >> 2) & qlowpixelMask5))| ((((A&0x00000001)==0x00000000)?0x00000000:(((B&0x00000001)==0x00000000)?0x00000000:(((C&0x00000001)==0x00000000)?0x00000000:(((D&0x00000001)==0x00000000)?0x00000000:0x00000001))))))
+
+void Super2xSaI_ex5(unsigned char *srcPtr, DWORD srcPitch,
+ unsigned char *dstBitmap, int width, int height)
+{
+ DWORD dstPitch = srcPitch * 2;
+ DWORD line;
+ unsigned short *dP;
+ unsigned short *bP;
+ int width2 = width*2;
+ int iXA,iXB,iXC,iYA,iYB,iYC,finish;
+ DWORD color4, color5, color6;
+ DWORD color1, color2, color3;
+ DWORD colorA0, colorA1, colorA2, colorA3,
+ colorB0, colorB1, colorB2, colorB3,
+ colorS1, colorS2;
+ DWORD product1a, product1b,
+ product2a, product2b;
+
+ line = 0;
+
+ {
+ for (; height; height-=1)
+ {
+ bP = (unsigned short *)srcPtr;
+ dP = (unsigned short *)(dstBitmap + line*dstPitch);
+ for (finish = width; finish; finish -= 1 )
+ {
+//--------------------------------------- B1 B2
+// 4 5 6 S2
+// 1 2 3 S1
+// A1 A2
+ if(finish==width) iXA=0;
+ else iXA=1;
+ if(finish>4) {iXB=1;iXC=2;}
+ else
+ if(finish>3) {iXB=1;iXC=1;}
+ else {iXB=0;iXC=0;}
+ if(line==0) iYA=0;
+ else iYA=width;
+ if(height>4) {iYB=width;iYC=width2;}
+ else
+ if(height>3) {iYB=width;iYC=width;}
+ else {iYB=0;iYC=0;}
+
+
+ colorB0 = *(bP- iYA - iXA);
+ colorB1 = *(bP- iYA);
+ colorB2 = *(bP- iYA + iXB);
+ colorB3 = *(bP- iYA + iXC);
+
+ color4 = *(bP - iXA);
+ color5 = *(bP);
+ color6 = *(bP + iXB);
+ colorS2 = *(bP + iXC);
+
+ color1 = *(bP + iYB - iXA);
+ color2 = *(bP + iYB);
+ color3 = *(bP + iYB + iXB);
+ colorS1= *(bP + iYB + iXC);
+
+ colorA0 = *(bP + iYC - iXA);
+ colorA1 = *(bP + iYC);
+ colorA2 = *(bP + iYC + iXB);
+ colorA3 = *(bP + iYC + iXC);
+
+//--------------------------------------
+ if (color2 == color6 && color5 != color3)
+ {
+ product2b = product1b = color2;
+ }
+ else
+ if (color5 == color3 && color2 != color6)
+ {
+ product2b = product1b = color5;
+ }
+ else
+ if (color5 == color3 && color2 == color6)
+ {
+ register int r = 0;
+
+ r += GET_RESULT ((color6&0xfffffffe), (color5&0xfffffffe), (color1&0xfffffffe), (colorA1&0xfffffffe));
+ r += GET_RESULT ((color6&0xfffffffe), (color5&0xfffffffe), (color4&0xfffffffe), (colorB1&0xfffffffe));
+ r += GET_RESULT ((color6&0xfffffffe), (color5&0xfffffffe), (colorA2&0xfffffffe), (colorS1&0xfffffffe));
+ r += GET_RESULT ((color6&0xfffffffe), (color5&0xfffffffe), (colorB2&0xfffffffe), (colorS2&0xfffffffe));
+
+ if (r > 0)
+ product2b = product1b = color6;
+ else
+ if (r < 0)
+ product2b = product1b = color5;
+ else
+ {
+ product2b = product1b = INTERPOLATE5 (color5, color6);
+ }
+ }
+ else
+ {
+ if (color6 == color3 && color3 == colorA1 && color2 != colorA2 && color3 != colorA0)
+ product2b = Q_INTERPOLATE5 (color3, color3, color3, color2);
+ else
+ if (color5 == color2 && color2 == colorA2 && colorA1 != color3 && color2 != colorA3)
+ product2b = Q_INTERPOLATE5 (color2, color2, color2, color3);
+ else
+ product2b = INTERPOLATE5 (color2, color3);
+
+ if (color6 == color3 && color6 == colorB1 && color5 != colorB2 && color6 != colorB0)
+ product1b = Q_INTERPOLATE5 (color6, color6, color6, color5);
+ else
+ if (color5 == color2 && color5 == colorB2 && colorB1 != color6 && color5 != colorB3)
+ product1b = Q_INTERPOLATE5 (color6, color5, color5, color5);
+ else
+ product1b = INTERPOLATE5 (color5, color6);
+ }
+
+ if (color5 == color3 && color2 != color6 && color4 == color5 && color5 != colorA2)
+ product2a = INTERPOLATE5 (color2, color5);
+ else
+ if (color5 == color1 && color6 == color5 && color4 != color2 && color5 != colorA0)
+ product2a = INTERPOLATE5(color2, color5);
+ else
+ product2a = color2;
+
+ if (color2 == color6 && color5 != color3 && color1 == color2 && color2 != colorB2)
+ product1a = INTERPOLATE5(color2, color5);
+ else
+ if (color4 == color2 && color3 == color2 && color1 != color5 && color2 != colorB0)
+ product1a = INTERPOLATE5(color2, color5);
+ else
+ product1a = color5;
+
+ *dP=product1a;
+ *(dP+1)=product1b;
+ *(dP+(width2))=product2a;
+ *(dP+1+(width2))=product2b;
+
+ bP += 1;
+ dP += 2;
+ }//end of for ( finish= width etc..)
+
+ line += 2;
+ srcPtr += srcPitch;
+ }; //endof: for (; height; height--)
+ }
+}
+
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+//
+// ogl texture defines
+//
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+
+void DefineSubTextureSortHiRes(void)
+{
+ int x,y,dx2;
+
+ if(!gTexName)
+ {
+ glGenTextures(1, &gTexName);
+ glBindTexture(GL_TEXTURE_2D, gTexName);
+
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, iClampType);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, iClampType);
+
+ if(iFilterType)
+ {
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ }
+ else
+ {
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ }
+ glTexImage2D(GL_TEXTURE_2D, 0, giWantedRGBA, 512, 512, 0, giWantedFMT, giWantedTYPE, texturebuffer);
+ }
+ else glBindTexture(GL_TEXTURE_2D, gTexName);
+
+ if(bGLExt && (iTexQuality==1 || iTexQuality==2))
+ {
+ if(DXTexS < 4 || DYTexS < 4 || iHiResTextures==2)
+ {
+ unsigned short * pS,*pD1,*pD2;
+ dx2=(DXTexS<<1);
+ pS=(unsigned short *)texturepart;
+ pD1=(unsigned short *)texturebuffer;
+ pD2=(unsigned short *)texturebuffer;
+ pD2+=dx2;
+ for(y=0;y<DYTexS;y++)
+ {
+ for(x=0;x<DXTexS;x++)
+ {
+ *(pD2+1)=*pD2=*(pD1+1)=*pD1=*pS;
+ pS++;
+ pD1+=2;
+ pD2+=2;
+ }
+ pD1+=dx2;
+ pD2+=dx2;
+ }
+ }
+ else
+ {
+ if(iTexQuality==1)
+ Super2xSaI_ex4(texturepart, DXTexS<<1, texturebuffer, DXTexS, DYTexS);
+ else
+ Super2xSaI_ex5(texturepart, DXTexS<<1, texturebuffer, DXTexS, DYTexS);
+ }
+ }
+ else
+ {
+ if(DXTexS < 4 || DYTexS < 4 || iHiResTextures==2)
+ {
+ uint32_t * pS,*pD1,*pD2;
+ dx2=(DXTexS<<1);
+ pS=(uint32_t *)texturepart;
+ pD1=(uint32_t *)texturebuffer;
+ pD2=(uint32_t *)texturebuffer;
+ pD2+=dx2;
+ for(y=0;y<DYTexS;y++)
+ {
+ for(x=0;x<DXTexS;x++)
+ {
+ *(pD2+1)=*pD2=*(pD1+1)=*pD1=*pS;
+ pS++;
+ pD1+=2;
+ pD2+=2;
+ }
+ pD1+=dx2;
+ pD2+=dx2;
+ }
+ }
+ else
+ if(bSmallAlpha)
+ Super2xSaI_ex8_Ex(texturepart, DXTexS*4, texturebuffer, DXTexS, DYTexS);
+ else
+ Super2xSaI_ex8(texturepart, DXTexS*4, texturebuffer, DXTexS, DYTexS);
+ }
+
+ glTexSubImage2D(GL_TEXTURE_2D, 0, XTexS<<1, YTexS<<1,
+ DXTexS<<1, DYTexS<<1,
+ giWantedFMT, giWantedTYPE, texturebuffer);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+void DefineSubTextureSort(void)
+{
+ if(iHiResTextures)
+ {
+ DefineSubTextureSortHiRes();
+ return;
+ }
+
+ if(!gTexName)
+ {
+ glGenTextures(1, &gTexName);
+ glBindTexture(GL_TEXTURE_2D, gTexName);
+
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, iClampType);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, iClampType);
+
+ if(iFilterType)
+ {
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ }
+ else
+ {
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ }
+ glTexImage2D(GL_TEXTURE_2D, 0, giWantedRGBA, 256, 256, 0,giWantedFMT, giWantedTYPE, texturepart);
+ }
+ else glBindTexture(GL_TEXTURE_2D, gTexName);
+
+ glTexSubImage2D(GL_TEXTURE_2D, 0, XTexS, YTexS,
+ DXTexS, DYTexS,
+ giWantedFMT, giWantedTYPE, texturepart);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+//
+// texture cache garbage collection
+//
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+
+void DoTexGarbageCollection(void)
+{
+ static unsigned short LRUCleaned=0;
+ unsigned short iC,iC1,iC2;
+ int i,j,iMax;textureSubCacheEntryS * tsb;
+
+ iC=4;//=iSortTexCnt/2,
+ LRUCleaned+=iC; // we clean different textures each time
+ if((LRUCleaned+iC)>=iSortTexCnt) LRUCleaned=0; // wrap? wrap!
+ iC1=LRUCleaned; // range of textures to clean
+ iC2=LRUCleaned+iC;
+
+ for(iC=iC1;iC<iC2;iC++) // make some textures available
+ {
+ pxSsubtexLeft[iC]->l=0;
+ }
+
+ for(i=0;i<3;i++) // remove all references to that textures
+ for(j=0;j<MAXTPAGES;j++)
+ for(iC=0;iC<4;iC++) // loop all texture rect info areas
+ {
+ tsb=pscSubtexStore[i][j]+(iC*SOFFB);
+ iMax=tsb->pos.l;
+ if(iMax)
+ do
+ {
+ tsb++;
+ if(tsb->cTexID>=iC1 && tsb->cTexID<iC2) // info uses the cleaned textures? remove info
+ tsb->ClutID=0;
+ }
+ while(--iMax);
+ }
+
+ usLRUTexPage=LRUCleaned;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+//
+// search cache for existing (already used) parts
+//
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+
+unsigned char * CheckTextureInSubSCache(int TextureMode, uint32_t GivenClutId, unsigned short * pCache)
+{
+ textureSubCacheEntryS * tsx, * tsb, *tsg;//, *tse=NULL;
+ int i,iMax;EXLong npos;
+ unsigned char cx,cy;
+ int iC,j,k;uint32_t rx,ry,mx,my;
+ EXLong * ul=0, * uls;
+ EXLong rfree;
+ unsigned char cXAdj,cYAdj;
+
+ npos.l=*((uint32_t *)&gl_ux[4]);
+
+ //--------------------------------------------------------------//
+ // find matching texturepart first... speed up...
+ //--------------------------------------------------------------//
+
+ tsg=pscSubtexStore[TextureMode][GlobalTexturePage];
+ tsg+=((GivenClutId&CLUTCHK)>>CLUTSHIFT)*SOFFB;
+
+ iMax=tsg->pos.l;
+ if(iMax)
+ {
+ i=iMax;
+ tsb=tsg+1;
+ do
+ {
+ if(GivenClutId==tsb->ClutID &&
+ (INCHECK(tsb->pos,npos)))
+ {
+ {
+ cx=tsb->pos.c[3]-tsb->posTX;
+ cy=tsb->pos.c[1]-tsb->posTY;
+
+ gl_ux[0]-=cx;
+ gl_ux[1]-=cx;
+ gl_ux[2]-=cx;
+ gl_ux[3]-=cx;
+ gl_vy[0]-=cy;
+ gl_vy[1]-=cy;
+ gl_vy[2]-=cy;
+ gl_vy[3]-=cy;
+
+ ubOpaqueDraw=tsb->Opaque;
+ *pCache=tsb->cTexID;
+ return NULL;
+ }
+ }
+ tsb++;
+ }
+ while(--i);
+ }
+
+ //----------------------------------------------------//
+
+ cXAdj=1;cYAdj=1;
+
+ rx=(int)gl_ux[6]-(int)gl_ux[7];
+ ry=(int)gl_ux[4]-(int)gl_ux[5];
+
+ tsx=NULL;tsb=tsg+1;
+ for(i=0;i<iMax;i++,tsb++)
+ {
+ if(!tsb->ClutID) {tsx=tsb;break;}
+ }
+
+ if(!tsx)
+ {
+ iMax++;
+ if(iMax>=SOFFB-2)
+ {
+ if(iTexGarbageCollection) // gc mode?
+ {
+ if(*pCache==0)
+ {
+ dwTexPageComp|=(1<<GlobalTexturePage);
+ *pCache=0xffff;
+ return 0;
+ }
+
+ iMax--;
+ tsb=tsg+1;
+
+ for(i=0;i<iMax;i++,tsb++) // 1. search other slots with same cluts, and unite the area
+ if(GivenClutId==tsb->ClutID)
+ {
+ if(!tsx) {tsx=tsb;rfree.l=npos.l;} //
+ else tsb->ClutID=0;
+ rfree.c[3]=min(rfree.c[3],tsb->pos.c[3]);
+ rfree.c[2]=max(rfree.c[2],tsb->pos.c[2]);
+ rfree.c[1]=min(rfree.c[1],tsb->pos.c[1]);
+ rfree.c[0]=max(rfree.c[0],tsb->pos.c[0]);
+ MarkFree(tsb);
+ }
+
+ if(tsx) // 3. if one or more found, create a new rect with bigger size
+ {
+ *((uint32_t *)&gl_ux[4])=npos.l=rfree.l;
+ rx=(int)rfree.c[2]-(int)rfree.c[3];
+ ry=(int)rfree.c[0]-(int)rfree.c[1];
+ DoTexGarbageCollection();
+
+ goto ENDLOOP3;
+ }
+ }
+
+ iMax=1;
+ }
+ tsx=tsg+iMax;
+ tsg->pos.l=iMax;
+ }
+
+ //----------------------------------------------------//
+ // now get a free texture space
+ //----------------------------------------------------//
+
+ if(iTexGarbageCollection) usLRUTexPage=0;
+
+ENDLOOP3:
+
+ rx+=3;if(rx>255) {cXAdj=0;rx=255;}
+ ry+=3;if(ry>255) {cYAdj=0;ry=255;}
+
+ iC=usLRUTexPage;
+
+ for(k=0;k<iSortTexCnt;k++)
+ {
+ uls=pxSsubtexLeft[iC];
+ iMax=uls->l;ul=uls+1;
+
+ //--------------------------------------------------//
+ // first time
+
+ if(!iMax)
+ {
+ rfree.l=0;
+
+ if(rx>252 && ry>252)
+ {uls->l=1;ul->l=0xffffffff;ul=0;goto ENDLOOP;}
+
+ if(rx<253)
+ {
+ uls->l=uls->l+1;
+ ul->c[3]=rx;
+ ul->c[2]=255-rx;
+ ul->c[1]=0;
+ ul->c[0]=ry;
+ ul++;
+ }
+
+ if(ry<253)
+ {
+ uls->l=uls->l+1;
+ ul->c[3]=0;
+ ul->c[2]=255;
+ ul->c[1]=ry;
+ ul->c[0]=255-ry;
+ }
+ ul=0;
+ goto ENDLOOP;
+ }
+
+ //--------------------------------------------------//
+ for(i=0;i<iMax;i++,ul++)
+ {
+ if(ul->l!=0xffffffff &&
+ ry<=ul->c[0] &&
+ rx<=ul->c[2])
+ {
+ rfree=*ul;
+ mx=ul->c[2]-2;
+ my=ul->c[0]-2;
+ if(rx<mx && ry<my)
+ {
+ ul->c[3]+=rx;
+ ul->c[2]-=rx;
+ ul->c[0]=ry;
+
+ for(ul=uls+1,j=0;j<iMax;j++,ul++)
+ if(ul->l==0xffffffff) break;
+
+ if(j<CSUBSIZE-2)
+ {
+ if(j==iMax) uls->l=uls->l+1;
+
+ ul->c[3]=rfree.c[3];
+ ul->c[2]=rfree.c[2];
+ ul->c[1]=rfree.c[1]+ry;
+ ul->c[0]=rfree.c[0]-ry;
+ }
+ }
+ else if(rx<mx)
+ {
+ ul->c[3]+=rx;
+ ul->c[2]-=rx;
+ }
+ else if(ry<my)
+ {
+ ul->c[1]+=ry;
+ ul->c[0]-=ry;
+ }
+ else
+ {
+ ul->l=0xffffffff;
+ }
+ ul=0;
+ goto ENDLOOP;
+ }
+ }
+
+ //--------------------------------------------------//
+
+ iC++; if(iC>=iSortTexCnt) iC=0;
+ }
+
+ //----------------------------------------------------//
+ // check, if free space got
+ //----------------------------------------------------//
+
+ENDLOOP:
+ if(ul)
+ {
+ //////////////////////////////////////////////////////
+
+ {
+ dwTexPageComp=0;
+
+ for(i=0;i<3;i++) // cleaning up
+ for(j=0;j<MAXTPAGES;j++)
+ {
+ tsb=pscSubtexStore[i][j];
+ (tsb+SOFFA)->pos.l=0;
+ (tsb+SOFFB)->pos.l=0;
+ (tsb+SOFFC)->pos.l=0;
+ (tsb+SOFFD)->pos.l=0;
+ }
+ for(i=0;i<iSortTexCnt;i++)
+ {ul=pxSsubtexLeft[i];ul->l=0;}
+ usLRUTexPage=0;
+ }
+
+ //////////////////////////////////////////////////////
+ iC=usLRUTexPage;
+ uls=pxSsubtexLeft[usLRUTexPage];
+ uls->l=0;ul=uls+1;
+ rfree.l=0;
+
+ if(rx>252 && ry>252)
+ {uls->l=1;ul->l=0xffffffff;}
+ else
+ {
+ if(rx<253)
+ {
+ uls->l=uls->l+1;
+ ul->c[3]=rx;
+ ul->c[2]=255-rx;
+ ul->c[1]=0;
+ ul->c[0]=ry;
+ ul++;
+ }
+ if(ry<253)
+ {
+ uls->l=uls->l+1;
+ ul->c[3]=0;
+ ul->c[2]=255;
+ ul->c[1]=ry;
+ ul->c[0]=255-ry;
+ }
+ }
+ tsg->pos.l=1;tsx=tsg+1;
+ }
+
+ rfree.c[3]+=cXAdj;
+ rfree.c[1]+=cYAdj;
+
+ tsx->cTexID =*pCache=iC;
+ tsx->pos = npos;
+ tsx->ClutID = GivenClutId;
+ tsx->posTX = rfree.c[3];
+ tsx->posTY = rfree.c[1];
+
+ cx=gl_ux[7]-rfree.c[3];
+ cy=gl_ux[5]-rfree.c[1];
+
+ gl_ux[0]-=cx;
+ gl_ux[1]-=cx;
+ gl_ux[2]-=cx;
+ gl_ux[3]-=cx;
+ gl_vy[0]-=cy;
+ gl_vy[1]-=cy;
+ gl_vy[2]-=cy;
+ gl_vy[3]-=cy;
+
+ XTexS=rfree.c[3];
+ YTexS=rfree.c[1];
+
+ return &tsx->Opaque;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+//
+// search cache for free place (on compress)
+//
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+
+BOOL GetCompressTexturePlace(textureSubCacheEntryS * tsx)
+{
+ int i,j,k,iMax,iC;uint32_t rx,ry,mx,my;
+ EXLong * ul=0, * uls, rfree;
+ unsigned char cXAdj=1,cYAdj=1;
+
+ rx=(int)tsx->pos.c[2]-(int)tsx->pos.c[3];
+ ry=(int)tsx->pos.c[0]-(int)tsx->pos.c[1];
+
+ rx+=3;if(rx>255) {cXAdj=0;rx=255;}
+ ry+=3;if(ry>255) {cYAdj=0;ry=255;}
+
+ iC=usLRUTexPage;
+
+ for(k=0;k<iSortTexCnt;k++)
+ {
+ uls=pxSsubtexLeft[iC];
+ iMax=uls->l;ul=uls+1;
+
+ //--------------------------------------------------//
+ // first time
+
+ if(!iMax)
+ {
+ rfree.l=0;
+
+ if(rx>252 && ry>252)
+ {uls->l=1;ul->l=0xffffffff;ul=0;goto TENDLOOP;}
+
+ if(rx<253)
+ {
+ uls->l=uls->l+1;
+ ul->c[3]=rx;
+ ul->c[2]=255-rx;
+ ul->c[1]=0;
+ ul->c[0]=ry;
+ ul++;
+ }
+
+ if(ry<253)
+ {
+ uls->l=uls->l+1;
+ ul->c[3]=0;
+ ul->c[2]=255;
+ ul->c[1]=ry;
+ ul->c[0]=255-ry;
+ }
+ ul=0;
+ goto TENDLOOP;
+ }
+
+ //--------------------------------------------------//
+ for(i=0;i<iMax;i++,ul++)
+ {
+ if(ul->l!=0xffffffff &&
+ ry<=ul->c[0] &&
+ rx<=ul->c[2])
+ {
+ rfree=*ul;
+ mx=ul->c[2]-2;
+ my=ul->c[0]-2;
+
+ if(rx<mx && ry<my)
+ {
+ ul->c[3]+=rx;
+ ul->c[2]-=rx;
+ ul->c[0]=ry;
+
+ for(ul=uls+1,j=0;j<iMax;j++,ul++)
+ if(ul->l==0xffffffff) break;
+
+ if(j<CSUBSIZE-2)
+ {
+ if(j==iMax) uls->l=uls->l+1;
+
+ ul->c[3]=rfree.c[3];
+ ul->c[2]=rfree.c[2];
+ ul->c[1]=rfree.c[1]+ry;
+ ul->c[0]=rfree.c[0]-ry;
+ }
+ }
+ else if(rx<mx)
+ {
+ ul->c[3]+=rx;
+ ul->c[2]-=rx;
+ }
+ else if(ry<my)
+ {
+ ul->c[1]+=ry;
+ ul->c[0]-=ry;
+ }
+ else
+ {
+ ul->l=0xffffffff;
+ }
+ ul=0;
+ goto TENDLOOP;
+ }
+ }
+
+ //--------------------------------------------------//
+
+ iC++; if(iC>=iSortTexCnt) iC=0;
+ }
+
+ //----------------------------------------------------//
+ // check, if free space got
+ //----------------------------------------------------//
+
+TENDLOOP:
+ if(ul) return FALSE;
+
+ rfree.c[3]+=cXAdj;
+ rfree.c[1]+=cYAdj;
+
+ tsx->cTexID = iC;
+ tsx->posTX = rfree.c[3];
+ tsx->posTY = rfree.c[1];
+
+ XTexS=rfree.c[3];
+ YTexS=rfree.c[1];
+
+ return TRUE;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+//
+// compress texture cache (to make place for new texture part, if needed)
+//
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+
+void CompressTextureSpace(void)
+{
+ textureSubCacheEntryS * tsx, * tsg, * tsb;
+ int i,j,k,m,n,iMax;EXLong * ul, r,opos;
+ short sOldDST=DrawSemiTrans,cx,cy;
+ int lOGTP=GlobalTexturePage;
+ uint32_t l,row;
+ uint32_t *lSRCPtr;
+
+ opos.l=*((uint32_t *)&gl_ux[4]);
+
+ // 1. mark all textures as free
+ for(i=0;i<iSortTexCnt;i++)
+ {ul=pxSsubtexLeft[i];ul->l=0;}
+ usLRUTexPage=0;
+
+ // 2. compress
+ for(j=0;j<3;j++)
+ {
+ for(k=0;k<MAXTPAGES;k++)
+ {
+ tsg=pscSubtexStore[j][k];
+
+ if((!(dwTexPageComp&(1<<k))))
+ {
+ (tsg+SOFFA)->pos.l=0;
+ (tsg+SOFFB)->pos.l=0;
+ (tsg+SOFFC)->pos.l=0;
+ (tsg+SOFFD)->pos.l=0;
+ continue;
+ }
+
+ for(m=0;m<4;m++,tsg+=SOFFB)
+ {
+ iMax=tsg->pos.l;
+
+ tsx=tsg+1;
+ for(i=0;i<iMax;i++,tsx++)
+ {
+ if(tsx->ClutID)
+ {
+ r.l=tsx->pos.l;
+ for(n=i+1,tsb=tsx+1;n<iMax;n++,tsb++)
+ {
+ if(tsx->ClutID==tsb->ClutID)
+ {
+ r.c[3]=min(r.c[3],tsb->pos.c[3]);
+ r.c[2]=max(r.c[2],tsb->pos.c[2]);
+ r.c[1]=min(r.c[1],tsb->pos.c[1]);
+ r.c[0]=max(r.c[0],tsb->pos.c[0]);
+ tsb->ClutID=0;
+ }
+ }
+
+// if(r.l!=tsx->pos.l)
+ {
+ cx=((tsx->ClutID << 4) & 0x3F0);
+ cy=((tsx->ClutID >> 6) & CLUTYMASK);
+
+ if(j!=2)
+ {
+ // palette check sum
+ l=0;lSRCPtr=(uint32_t *)(psxVuw+cx+(cy*1024));
+ if(j==1) for(row=1;row<129;row++) l+=((*lSRCPtr++)-1)*row;
+ else for(row=1;row<9;row++) l+=((*lSRCPtr++)-1)<<row;
+ l=((l+HIWORD(l))&0x3fffL)<<16;
+ if(l!=(tsx->ClutID&(0x00003fff<<16)))
+ {
+ tsx->ClutID=0;continue;
+ }
+ }
+
+ tsx->pos.l=r.l;
+ if(!GetCompressTexturePlace(tsx)) // no place?
+ {
+ for(i=0;i<3;i++) // -> clean up everything
+ for(j=0;j<MAXTPAGES;j++)
+ {
+ tsb=pscSubtexStore[i][j];
+ (tsb+SOFFA)->pos.l=0;
+ (tsb+SOFFB)->pos.l=0;
+ (tsb+SOFFC)->pos.l=0;
+ (tsb+SOFFD)->pos.l=0;
+ }
+ for(i=0;i<iSortTexCnt;i++)
+ {ul=pxSsubtexLeft[i];ul->l=0;}
+ usLRUTexPage=0;
+ DrawSemiTrans=sOldDST;
+ GlobalTexturePage=lOGTP;
+ *((uint32_t *)&gl_ux[4])=opos.l;
+ dwTexPageComp=0;
+
+ return;
+ }
+
+ if(tsx->ClutID&(1<<30)) DrawSemiTrans=1;
+ else DrawSemiTrans=0;
+ *((uint32_t *)&gl_ux[4])=r.l;
+
+ gTexName=uiStexturePage[tsx->cTexID];
+ LoadSubTexFn(k,j,cx,cy);
+ uiStexturePage[tsx->cTexID]=gTexName;
+ tsx->Opaque=ubOpaqueDraw;
+ }
+ }
+ }
+
+ if(iMax)
+ {
+ tsx=tsg+iMax;
+ while(!tsx->ClutID && iMax) {tsx--;iMax--;}
+ tsg->pos.l=iMax;
+ }
+
+ }
+ }
+ }
+
+ if(dwTexPageComp==0xffffffff) dwTexPageComp=0;
+
+ *((uint32_t *)&gl_ux[4])=opos.l;
+ GlobalTexturePage=lOGTP;
+ DrawSemiTrans=sOldDST;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+//
+// main entry for searching/creating textures, called from prim.c
+//
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+
+GLuint SelectSubTextureS(int TextureMode, uint32_t GivenClutId)
+{
+ unsigned char * OPtr;unsigned short iCache;short cx,cy;
+
+ // sort sow/tow infos for fast access
+
+ unsigned char ma1,ma2,mi1,mi2;
+ if(gl_ux[0]>gl_ux[1]) {mi1=gl_ux[1];ma1=gl_ux[0];}
+ else {mi1=gl_ux[0];ma1=gl_ux[1];}
+ if(gl_ux[2]>gl_ux[3]) {mi2=gl_ux[3];ma2=gl_ux[2];}
+ else {mi2=gl_ux[2];ma2=gl_ux[3];}
+ if(mi1>mi2) gl_ux[7]=mi2;
+ else gl_ux[7]=mi1;
+ if(ma1>ma2) gl_ux[6]=ma1;
+ else gl_ux[6]=ma2;
+
+ if(gl_vy[0]>gl_vy[1]) {mi1=gl_vy[1];ma1=gl_vy[0];}
+ else {mi1=gl_vy[0];ma1=gl_vy[1];}
+ if(gl_vy[2]>gl_vy[3]) {mi2=gl_vy[3];ma2=gl_vy[2];}
+ else {mi2=gl_vy[2];ma2=gl_vy[3];}
+ if(mi1>mi2) gl_ux[5]=mi2;
+ else gl_ux[5]=mi1;
+ if(ma1>ma2) gl_ux[4]=ma1;
+ else gl_ux[4]=ma2;
+
+ // get clut infos in one 32 bit val
+
+ if(TextureMode==2) // no clut here
+ {
+ GivenClutId=CLUTUSED|(DrawSemiTrans<<30);cx=cy=0;
+
+ if(iFrameTexType && Fake15BitTexture())
+ return (GLuint)gTexName;
+ }
+ else
+ {
+ cx=((GivenClutId << 4) & 0x3F0); // but here
+ cy=((GivenClutId >> 6) & CLUTYMASK);
+ GivenClutId=(GivenClutId&CLUTMASK)|(DrawSemiTrans<<30)|CLUTUSED;
+
+ // palette check sum.. removed MMX asm, this easy func works as well
+ {
+ uint32_t l=0,row;
+
+ uint32_t *lSRCPtr = (uint32_t *)(psxVuw+cx+(cy*1024));
+ if(TextureMode==1) for(row=1;row<129;row++) l+=((*lSRCPtr++)-1)*row;
+ else for(row=1;row<9;row++) l+=((*lSRCPtr++)-1)<<row;
+ l=(l+HIWORD(l))&0x3fffL;
+ GivenClutId|=(l<<16);
+ }
+
+ }
+
+ // search cache
+ iCache=0;
+ OPtr=CheckTextureInSubSCache(TextureMode,GivenClutId,&iCache);
+
+ // cache full? compress and try again
+ if(iCache==0xffff)
+ {
+ CompressTextureSpace();
+ OPtr=CheckTextureInSubSCache(TextureMode,GivenClutId,&iCache);
+ }
+
+ // found? fine
+ usLRUTexPage=iCache;
+ if(!OPtr) return uiStexturePage[iCache];
+
+ // not found? upload texture and store infos in cache
+ gTexName=uiStexturePage[iCache];
+ LoadSubTexFn(GlobalTexturePage,TextureMode,cx,cy);
+ uiStexturePage[iCache]=gTexName;
+ *OPtr=ubOpaqueDraw;
+ return (GLuint) gTexName;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
diff --git a/plugins/peopsxgl/texture.h b/plugins/peopsxgl/texture.h index b4a69049..b646af7c 100644 --- a/plugins/peopsxgl/texture.h +++ b/plugins/peopsxgl/texture.h @@ -1,69 +1,68 @@ -/*************************************************************************** - texture.h - description - ------------------- - begin : Sun Mar 08 2009 - copyright : (C) 1999-2009 by Pete Bernert - web : www.pbernert.com - ***************************************************************************/ - -/*************************************************************************** - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. See also the license.txt file for * - * additional informations. * - * * - ***************************************************************************/ - -#ifndef _GPU_TEXTURE_H_ -#define _GPU_TEXTURE_H_ - -#define TEXTUREPAGESIZE 256 * 256 - -void InitializeTextureStore(); -void CleanupTextureStore(); -GLuint LoadTextureWnd(int pageid, int TextureMode, uint32_t GivenClutId); -GLuint LoadTextureMovie(void); -void InvalidateTextureArea(int imageX0, int imageY0, int imageX1, int imageY1); -void InvalidateTextureAreaEx(void); -void LoadTexturePage(int pageid, int mode, short cx, short cy); -void ResetTextureArea(BOOL bDelTex); -GLuint SelectSubTextureS(int TextureMode, uint32_t GivenClutId); -void CheckTextureMemory(void); - -void LoadSubTexturePage(int pageid, int mode, short cx, short cy); -void LoadSubTexturePageSort(int pageid, int mode, short cx, short cy); -void LoadPackedSubTexturePage(int pageid, int mode, short cx, short cy); -void LoadPackedSubTexturePageSort(int pageid, int mode, short cx, short cy); -uint32_t XP8RGBA(uint32_t BGR); -uint32_t XP8RGBAEx(uint32_t BGR); -uint32_t XP8RGBA_0(uint32_t BGR); -uint32_t XP8RGBAEx_0(uint32_t BGR); -uint32_t XP8BGRA_0(uint32_t BGR); -uint32_t XP8BGRAEx_0(uint32_t BGR); -uint32_t XP8RGBA_1(uint32_t BGR); -uint32_t XP8RGBAEx_1(uint32_t BGR); -uint32_t XP8BGRA_1(uint32_t BGR); -uint32_t XP8BGRAEx_1(uint32_t BGR); -uint32_t P8RGBA(uint32_t BGR); -uint32_t P8BGRA(uint32_t BGR); -uint32_t CP8RGBA_0(uint32_t BGR); -uint32_t CP8RGBAEx_0(uint32_t BGR); -uint32_t CP8BGRA_0(uint32_t BGR); -uint32_t CP8BGRAEx_0(uint32_t BGR); -uint32_t CP8RGBA(uint32_t BGR); -uint32_t CP8RGBAEx(uint32_t BGR); -unsigned short XP5RGBA (unsigned short BGR); -unsigned short XP5RGBA_0 (unsigned short BGR); -unsigned short XP5RGBA_1 (unsigned short BGR); -unsigned short P5RGBA (unsigned short BGR); -unsigned short CP5RGBA_0 (unsigned short BGR); -unsigned short XP4RGBA (unsigned short BGR); -unsigned short XP4RGBA_0 (unsigned short BGR); -unsigned short XP4RGBA_1 (unsigned short BGR); -unsigned short P4RGBA (unsigned short BGR); -unsigned short CP4RGBA_0 (unsigned short BGR); -unsigned char * LoadDirectMovieFast(void); - -#endif // _TEXTURE_H_ +/***************************************************************************
+ texture.h - description
+ -------------------
+ begin : Sun Mar 08 2009
+ copyright : (C) 1999-2009 by Pete Bernert
+ web : www.pbernert.com
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. See also the license.txt file for *
+ * additional informations. *
+ * *
+ ***************************************************************************/
+
+#ifndef _GPU_TEXTURE_H_
+#define _GPU_TEXTURE_H_
+
+#define TEXTUREPAGESIZE 256 * 256
+
+void InitializeTextureStore();
+void CleanupTextureStore();
+GLuint LoadTextureWnd(int pageid, int TextureMode, uint32_t GivenClutId);
+GLuint LoadTextureMovie(void);
+void InvalidateTextureArea(int imageX0, int imageY0, int imageX1, int imageY1);
+void InvalidateTextureAreaEx(void);
+void LoadTexturePage(int pageid, int mode, short cx, short cy);
+void ResetTextureArea(BOOL bDelTex);
+GLuint SelectSubTextureS(int TextureMode, uint32_t GivenClutId);
+void CheckTextureMemory(void);
+
+void LoadSubTexturePage(int pageid, int mode, short cx, short cy);
+void LoadSubTexturePageSort(int pageid, int mode, short cx, short cy);
+void LoadPackedSubTexturePage(int pageid, int mode, short cx, short cy);
+void LoadPackedSubTexturePageSort(int pageid, int mode, short cx, short cy);
+uint32_t XP8RGBA(uint32_t BGR);
+uint32_t XP8RGBAEx(uint32_t BGR);
+uint32_t XP8RGBA_0(uint32_t BGR);
+uint32_t XP8RGBAEx_0(uint32_t BGR);
+uint32_t XP8BGRA_0(uint32_t BGR);
+uint32_t XP8BGRAEx_0(uint32_t BGR);
+uint32_t XP8RGBA_1(uint32_t BGR);
+uint32_t XP8RGBAEx_1(uint32_t BGR);
+uint32_t XP8BGRA_1(uint32_t BGR);
+uint32_t XP8BGRAEx_1(uint32_t BGR);
+uint32_t P8RGBA(uint32_t BGR);
+uint32_t P8BGRA(uint32_t BGR);
+uint32_t CP8RGBA_0(uint32_t BGR);
+uint32_t CP8RGBAEx_0(uint32_t BGR);
+uint32_t CP8BGRA_0(uint32_t BGR);
+uint32_t CP8BGRAEx_0(uint32_t BGR);
+uint32_t CP8RGBA(uint32_t BGR);
+uint32_t CP8RGBAEx(uint32_t BGR);
+unsigned short XP5RGBA (unsigned short BGR);
+unsigned short XP5RGBA_0 (unsigned short BGR);
+unsigned short XP5RGBA_1 (unsigned short BGR);
+unsigned short P5RGBA (unsigned short BGR);
+unsigned short CP5RGBA_0 (unsigned short BGR);
+unsigned short XP4RGBA (unsigned short BGR);
+unsigned short XP4RGBA_0 (unsigned short BGR);
+unsigned short XP4RGBA_1 (unsigned short BGR);
+unsigned short P4RGBA (unsigned short BGR);
+unsigned short CP4RGBA_0 (unsigned short BGR);
+
+#endif // _TEXTURE_H_
|
