+++ /dev/null
-/***************************************************************************
- gpu.c - description
- -------------------
- begin : Sun Oct 28 2001
- copyright : (C) 2001 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. *
- * *
- ***************************************************************************/
-
-#include "gpu.h"
-#include "stdint.h"
-#include "psemu_plugin_defs.h"
-
-////////////////////////////////////////////////////////////////////////
-// memory image of the PSX vram
-////////////////////////////////////////////////////////////////////////
-
-unsigned char *psxVub;
-unsigned short *psxVuw;
-unsigned short *psxVuw_eom;
-
-////////////////////////////////////////////////////////////////////////
-// GPU globals
-////////////////////////////////////////////////////////////////////////
-
-static long lGPUdataRet;
-long lGPUstatusRet;
-uint32_t ulStatusControl[256];
-
-static uint32_t gpuDataM[256];
-static unsigned char gpuCommand = 0;
-static long gpuDataC = 0;
-static long gpuDataP = 0;
-
-VRAMLoad_t VRAMWrite;
-VRAMLoad_t VRAMRead;
-DATAREGISTERMODES DataWriteMode;
-DATAREGISTERMODES DataReadMode;
-
-BOOL bSkipNextFrame = FALSE;
-BOOL fskip_frameReady;
-DWORD lace_count_since_flip;
-DWORD dwLaceCnt=0;
-short sDispWidths[8] = {256,320,512,640,368,384,512,640};
-PSXDisplay_t PSXDisplay;
-PSXDisplay_t PreviousPSXDisplay;
-long lSelectedSlot=0;
-BOOL bDoLazyUpdate=FALSE;
-uint32_t lGPUInfoVals[16];
-static int iFakePrimBusy=0;
-static const int *skip_advice;
-
-////////////////////////////////////////////////////////////////////////
-// some misc external display funcs
-////////////////////////////////////////////////////////////////////////
-
-#include <time.h>
-
-// FPS library
-#include "fps.c"
-
-
-////////////////////////////////////////////////////////////////////////
-// sets all kind of act fixes
-////////////////////////////////////////////////////////////////////////
-
-static void SetFixes(void)
- {
- if(dwActFixes&0x02) sDispWidths[4]=384;
- else sDispWidths[4]=368;
- }
-
-////////////////////////////////////////////////////////////////////////
-// INIT, will be called after lib load... well, just do some var init...
-////////////////////////////////////////////////////////////////////////
-
-// one extra MB for soft drawing funcs security
-static unsigned char vram[1024*512*2 + 1024*1024] __attribute__((aligned(2048)));
-
-long CALLBACK GPUinit(void) // GPU INIT
-{
- memset(ulStatusControl,0,256*sizeof(uint32_t)); // init save state scontrol field
-
- //!!! ATTENTION !!!
- psxVub=vram + 512 * 1024; // security offset into double sized psx vram!
-
- psxVuw=(unsigned short *)psxVub;
- psxVuw_eom=psxVuw+1024*512; // pre-calc of end of vram
-
- memset(vram,0x00,(512*2)*1024 + (1024*1024));
- memset(lGPUInfoVals,0x00,16*sizeof(uint32_t));
-
- PSXDisplay.RGB24 = FALSE; // init some stuff
- PSXDisplay.Interlaced = FALSE;
- PSXDisplay.DrawOffset.x = 0;
- PSXDisplay.DrawOffset.y = 0;
- PSXDisplay.DisplayMode.x= 320;
- PSXDisplay.DisplayMode.y= 240;
- PreviousPSXDisplay.DisplayMode.x= 320;
- PreviousPSXDisplay.DisplayMode.y= 240;
- PSXDisplay.Disabled = FALSE;
- PreviousPSXDisplay.Range.x0 =0;
- PreviousPSXDisplay.Range.y0 =0;
- PSXDisplay.Range.x0=0;
- PSXDisplay.Range.x1=0;
- PreviousPSXDisplay.DisplayModeNew.y=0;
- PSXDisplay.Double = 1;
- lGPUdataRet = 0x400;
-
- DataWriteMode = 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 = 0x14802000;
- GPUIsIdle;
- GPUIsReadyForCommands;
- bDoVSyncUpdate = TRUE;
-
- return 0;
-}
-
-////////////////////////////////////////////////////////////////////////
-// Here starts all...
-////////////////////////////////////////////////////////////////////////
-
-
-long GPUopen(unsigned long * disp,char * CapText,char * CfgFile)
-{
- unsigned long d;
-
- SetFixes();
-
- InitFPS();
-
- bDoVSyncUpdate = TRUE;
-
- d=ulInitDisplay(); // setup x
-
- if(disp)
- *disp=d; // wanna x pointer? ok
-
- if(d) return 0;
- return -1;
-}
-
-
-////////////////////////////////////////////////////////////////////////
-// time to leave...
-////////////////////////////////////////////////////////////////////////
-
-long CALLBACK GPUclose() // GPU CLOSE
-{
- CloseDisplay(); // shutdown direct draw
-
- return 0;
-}
-
-////////////////////////////////////////////////////////////////////////
-// I shot the sheriff
-////////////////////////////////////////////////////////////////////////
-
-long CALLBACK GPUshutdown(void) // GPU SHUTDOWN
-{
- CloseDisplay(); // shutdown direct draw
- return 0; // nothinh to do
-}
-
-////////////////////////////////////////////////////////////////////////
-// Update display (swap buffers)
-////////////////////////////////////////////////////////////////////////
-
-static void updateDisplay(void) // UPDATE DISPLAY
-{
- if(PSXDisplay.Disabled) // disable?
- {
- return; // -> and bye
- }
-
- if(dwActFixes&32) // pc fps calculation fix
- {
- if(UseFrameLimit) PCFrameCap(); // -> brake
- if(UseFrameSkip) PCcalcfps();
- }
-
- if(UseFrameSkip) // skip ?
- {
- if(fskip_frameReady)
- {
- DoBufferSwap(); // -> to skip or not to skip
- fskip_frameReady=FALSE;
- bDoVSyncUpdate=FALSE; // vsync done
- }
- }
- else // no skip ?
- {
- bSkipNextFrame = FALSE;
- DoBufferSwap(); // -> swap
- bDoVSyncUpdate=FALSE; // vsync done
- }
-}
-
-static void decideSkip(void)
-{
- if(!bDoVSyncUpdate)
- return;
-
- lace_count_since_flip=0;
- fskip_frameReady=!bSkipNextFrame;
-
- if(dwActFixes&0xa0) // -> pc fps calculation fix/old skipping fix
- {
- int skip = (skip_advice && *skip_advice) || UseFrameSkip == 1 || fps_skip < fFrameRateHz;
- if(skip && !bSkipNextFrame) // -> skip max one in a row
- {bSkipNextFrame = TRUE; fps_skip=fFrameRateHz;}
- else bSkipNextFrame = FALSE;
- }
- else FrameSkip();
-}
-
-////////////////////////////////////////////////////////////////////////
-// roughly emulated screen centering bits... not complete !!!
-////////////////////////////////////////////////////////////////////////
-
-void ChangeDispOffsetsX(void) // X CENTER
-{
- long lx,l;
-
- if(!PSXDisplay.Range.x1) return;
-
- l=PreviousPSXDisplay.DisplayMode.x;
-
- l*=(long)PSXDisplay.Range.x1;
- l/=2560;lx=l;l&=0xfffffff8;
-
- if(l==PreviousPSXDisplay.Range.y1) return; // abusing range.y1 for
- PreviousPSXDisplay.Range.y1=(short)l; // storing last x range and test
-
- if(lx>=PreviousPSXDisplay.DisplayMode.x)
- {
- PreviousPSXDisplay.Range.x1=
- (short)PreviousPSXDisplay.DisplayMode.x;
- PreviousPSXDisplay.Range.x0=0;
- }
- else
- {
- PreviousPSXDisplay.Range.x1=(short)l;
-
- PreviousPSXDisplay.Range.x0=
- (PSXDisplay.Range.x0-500)/8;
-
- if(PreviousPSXDisplay.Range.x0<0)
- PreviousPSXDisplay.Range.x0=0;
-
- if((PreviousPSXDisplay.Range.x0+lx)>
- PreviousPSXDisplay.DisplayMode.x)
- {
- PreviousPSXDisplay.Range.x0=
- (short)(PreviousPSXDisplay.DisplayMode.x-lx);
- PreviousPSXDisplay.Range.x0+=2; //???
-
- PreviousPSXDisplay.Range.x1+=(short)(lx-l);
-
- PreviousPSXDisplay.Range.x1-=2; // makes linux stretching easier
-
- }
-
- // some linux alignment security
- PreviousPSXDisplay.Range.x0=PreviousPSXDisplay.Range.x0>>1;
- PreviousPSXDisplay.Range.x0=PreviousPSXDisplay.Range.x0<<1;
- PreviousPSXDisplay.Range.x1=PreviousPSXDisplay.Range.x1>>1;
- PreviousPSXDisplay.Range.x1=PreviousPSXDisplay.Range.x1<<1;
-
- DoClearScreenBuffer();
- }
-
- bDoVSyncUpdate=TRUE;
-}
-
-////////////////////////////////////////////////////////////////////////
-
-void ChangeDispOffsetsY(void) // Y CENTER
-{
- int iT,iO=PreviousPSXDisplay.Range.y0;
- int iOldYOffset=PreviousPSXDisplay.DisplayModeNew.y;
-
-// new
-
- if((PreviousPSXDisplay.DisplayModeNew.x+PSXDisplay.DisplayModeNew.y)>512)
- {
- int dy1=512-PreviousPSXDisplay.DisplayModeNew.x;
- int dy2=(PreviousPSXDisplay.DisplayModeNew.x+PSXDisplay.DisplayModeNew.y)-512;
-
- if(dy1>=dy2)
- {
- PreviousPSXDisplay.DisplayModeNew.y=-dy2;
- }
- else
- {
- PSXDisplay.DisplayPosition.y=0;
- PreviousPSXDisplay.DisplayModeNew.y=-dy1;
- }
- }
- else PreviousPSXDisplay.DisplayModeNew.y=0;
-
-// eon
-
- if(PreviousPSXDisplay.DisplayModeNew.y!=iOldYOffset) // if old offset!=new offset: recalc height
- {
- PSXDisplay.Height = PSXDisplay.Range.y1 -
- PSXDisplay.Range.y0 +
- PreviousPSXDisplay.DisplayModeNew.y;
- PSXDisplay.DisplayModeNew.y=PSXDisplay.Height*PSXDisplay.Double;
- }
-
-//
-
- if(PSXDisplay.PAL) iT=48; else iT=28;
-
- if(PSXDisplay.Range.y0>=iT)
- {
- PreviousPSXDisplay.Range.y0=
- (short)((PSXDisplay.Range.y0-iT-4)*PSXDisplay.Double);
- if(PreviousPSXDisplay.Range.y0<0)
- PreviousPSXDisplay.Range.y0=0;
- PSXDisplay.DisplayModeNew.y+=
- PreviousPSXDisplay.Range.y0;
- }
- else
- PreviousPSXDisplay.Range.y0=0;
-
- if(iO!=PreviousPSXDisplay.Range.y0)
- {
- DoClearScreenBuffer();
- }
-}
-
-////////////////////////////////////////////////////////////////////////
-// check if update needed
-////////////////////////////////////////////////////////////////////////
-
-static void updateDisplayIfChanged(void) // UPDATE DISPLAY IF CHANGED
-{
- if ((PSXDisplay.DisplayMode.y == PSXDisplay.DisplayModeNew.y) &&
- (PSXDisplay.DisplayMode.x == PSXDisplay.DisplayModeNew.x))
- {
- if((PSXDisplay.RGB24 == PSXDisplay.RGB24New) &&
- (PSXDisplay.Interlaced == PSXDisplay.InterlacedNew)) return;
- }
-
- PSXDisplay.RGB24 = PSXDisplay.RGB24New; // get new infos
-
- PSXDisplay.DisplayMode.y = PSXDisplay.DisplayModeNew.y;
- PSXDisplay.DisplayMode.x = PSXDisplay.DisplayModeNew.x;
- PreviousPSXDisplay.DisplayMode.x= // previous will hold
- min(640,PSXDisplay.DisplayMode.x); // max 640x512... that's
- PreviousPSXDisplay.DisplayMode.y= // the size of my
- min(512,PSXDisplay.DisplayMode.y); // back buffer surface
- PSXDisplay.Interlaced = PSXDisplay.InterlacedNew;
-
- PSXDisplay.DisplayEnd.x= // calc end of display
- 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 it
-
- if(UseFrameSkip) decideSkip(); // stupid stuff when frame skipping enabled
-}
-
-////////////////////////////////////////////////////////////////////////
-// update lace is called evry VSync
-////////////////////////////////////////////////////////////////////////
-
-void CALLBACK GPUupdateLace(void) // VSYNC
-{
- //if(!(dwActFixes&1))
- // lGPUstatusRet^=0x80000000; // odd/even bit
-
- //pcsx-rearmed: removed, this is handled by core
- //if(!(dwActFixes&32)) // std fps limitation?
- // CheckFrameRate();
-
- if(PSXDisplay.Interlaced) // interlaced mode?
- {
- lGPUstatusRet^=0x80000000; // odd/even bit?
-
- if(bDoVSyncUpdate && PSXDisplay.DisplayMode.x>0 && PSXDisplay.DisplayMode.y>0)
- {
- updateDisplay();
- }
- }
- else // non-interlaced?
- {
- if(dwActFixes&64) // lazy screen update fix
- {
- if(bDoLazyUpdate)
- updateDisplay();
- bDoLazyUpdate=FALSE;
- }
- else
- {
- if(bDoVSyncUpdate) // some primitives drawn?
- updateDisplay(); // -> update display
- }
- }
-
- if(UseFrameSkip) { // frame over-skip guard
- lace_count_since_flip++;
- if(lace_count_since_flip > 8) {
- bSkipNextFrame=FALSE;
- fskip_frameReady=TRUE;
- }
- }
-}
-
-////////////////////////////////////////////////////////////////////////
-// process read request from GPU status register
-////////////////////////////////////////////////////////////////////////
-
-
-uint32_t CALLBACK GPUreadStatus(void) // READ STATUS
-{
- if(dwActFixes&1)
- {
- static int iNumRead=0; // odd/even hack
- if((iNumRead++)==2)
- {
- iNumRead=0;
- lGPUstatusRet^=0x80000000; // interlaced bit toggle... we do it on every 3 read status... needed by some games (like ChronoCross) with old epsxe versions (1.5.2 and older)
- }
- }
-
- if(iFakePrimBusy) // 27.10.2007 - PETE : emulating some 'busy' while drawing... pfff
- {
- iFakePrimBusy--;
-
- if(iFakePrimBusy&1) // we do a busy-idle-busy-idle sequence after/while drawing prims
- {
- GPUIsBusy;
- GPUIsNotReadyForCommands;
- }
- else
- {
- GPUIsIdle;
- GPUIsReadyForCommands;
- }
- }
- return lGPUstatusRet;
-}
-
-////////////////////////////////////////////////////////////////////////
-// processes data send to GPU status register
-// these are always single packet commands.
-////////////////////////////////////////////////////////////////////////
-
-void CALLBACK GPUwriteStatus(uint32_t gdata) // WRITE STATUS
-{
- uint32_t lCommand=(gdata>>24)&0xff;
-
- ulStatusControl[lCommand]=gdata; // store command for freezing
-
- switch(lCommand)
- {
- //--------------------------------------------------//
- // reset gpu
- case 0x00:
- memset(lGPUInfoVals,0x00,16*sizeof(uint32_t));
- lGPUstatusRet=0x14802000;
- PSXDisplay.Disabled=1;
- DataWriteMode=DataReadMode=DR_NORMAL;
- PSXDisplay.DrawOffset.x=PSXDisplay.DrawOffset.y=0;
- drawX=drawY=0;drawW=drawH=0;
- sSetMask=0;lSetMask=0;bCheckMask=FALSE;
- 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)
- lGPUstatusRet|=GPUSTATUS_DISPLAYDISABLED;
- else lGPUstatusRet&=~GPUSTATUS_DISPLAYDISABLED;
- return;
-
- //--------------------------------------------------//
- // setting transfer mode
- case 0x04:
- gdata &= 0x03; // Only want the lower two bits
-
- DataWriteMode=DataReadMode=DR_NORMAL;
- if(gdata==0x02) DataWriteMode=DR_VRAMTRANSFER;
- if(gdata==0x03) DataReadMode =DR_VRAMTRANSFER;
- lGPUstatusRet&=~GPUSTATUS_DMABITS; // Clear the current settings of the DMA bits
- lGPUstatusRet|=(gdata << 29); // Set the DMA bits according to the received data
-
- return;
- //--------------------------------------------------//
- // setting display position
- case 0x05:
- {
- PreviousPSXDisplay.DisplayPosition.x = PSXDisplay.DisplayPosition.x;
- PreviousPSXDisplay.DisplayPosition.y = PSXDisplay.DisplayPosition.y;
-
-// new
- PSXDisplay.DisplayPosition.y = (short)((gdata>>10)&0x1ff);
-
- // store the same val in some helper var, we need it on later compares
- PreviousPSXDisplay.DisplayModeNew.x=PSXDisplay.DisplayPosition.y;
-
- if((PSXDisplay.DisplayPosition.y+PSXDisplay.DisplayMode.y)>512)
- {
- int dy1=512-PSXDisplay.DisplayPosition.y;
- int dy2=(PSXDisplay.DisplayPosition.y+PSXDisplay.DisplayMode.y)-512;
-
- if(dy1>=dy2)
- {
- PreviousPSXDisplay.DisplayModeNew.y=-dy2;
- }
- else
- {
- PSXDisplay.DisplayPosition.y=0;
- PreviousPSXDisplay.DisplayModeNew.y=-dy1;
- }
- }
- else PreviousPSXDisplay.DisplayModeNew.y=0;
-// eon
-
- PSXDisplay.DisplayPosition.x = (short)(gdata & 0x3ff);
- 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;
-
- bDoVSyncUpdate=TRUE;
-
- if (!(PSXDisplay.Interlaced)) // stupid frame skipping option
- {
- if(dwActFixes&64) bDoLazyUpdate=TRUE;
- }
- if(UseFrameSkip) decideSkip();
- }return;
- //--------------------------------------------------//
- // setting width
- case 0x06:
-
- PSXDisplay.Range.x0=(short)(gdata & 0x7ff);
- PSXDisplay.Range.x1=(short)((gdata>>12) & 0xfff);
-
- PSXDisplay.Range.x1-=PSXDisplay.Range.x0;
-
- ChangeDispOffsetsX();
-
- return;
- //--------------------------------------------------//
- // setting height
- case 0x07:
- {
-
- PSXDisplay.Range.y0=(short)(gdata & 0x3ff);
- PSXDisplay.Range.y1=(short)((gdata>>10) & 0x3ff);
-
- PreviousPSXDisplay.Height = PSXDisplay.Height;
-
- 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 =
- sDispWidths[(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
-
- lGPUstatusRet&=~GPUSTATUS_WIDTHBITS; // Clear the width bits
- lGPUstatusRet|=
- (((gdata & 0x03) << 17) |
- ((gdata & 0x40) << 10)); // Set the width bits
-
- if(PSXDisplay.InterlacedNew)
- {
- if(!PSXDisplay.Interlaced)
- {
- PreviousPSXDisplay.DisplayPosition.x = PSXDisplay.DisplayPosition.x;
- PreviousPSXDisplay.DisplayPosition.y = PSXDisplay.DisplayPosition.y;
- }
- lGPUstatusRet|=GPUSTATUS_INTERLACED;
- }
- else lGPUstatusRet&=~(GPUSTATUS_INTERLACED|0x80000000);
-
- if (PSXDisplay.PAL)
- lGPUstatusRet|=GPUSTATUS_PAL;
- else lGPUstatusRet&=~GPUSTATUS_PAL;
-
- if (PSXDisplay.Double==2)
- lGPUstatusRet|=GPUSTATUS_DOUBLEHEIGHT;
- else lGPUstatusRet&=~GPUSTATUS_DOUBLEHEIGHT;
-
- if (PSXDisplay.RGB24New)
- lGPUstatusRet|=GPUSTATUS_RGB24;
- else lGPUstatusRet&=~GPUSTATUS_RGB24;
-
- updateDisplayIfChanged();
-
- return;
- //--------------------------------------------------//
- // ask about GPU version and other stuff
- case 0x10:
-
- gdata&=0xff;
-
- switch(gdata)
- {
- case 0x02:
- lGPUdataRet=lGPUInfoVals[INFO_TW]; // tw infos
- return;
- case 0x03:
- lGPUdataRet=lGPUInfoVals[INFO_DRAWSTART]; // draw start
- return;
- case 0x04:
- lGPUdataRet=lGPUInfoVals[INFO_DRAWEND]; // draw end
- return;
- case 0x05:
- case 0x06:
- lGPUdataRet=lGPUInfoVals[INFO_DRAWOFF]; // draw offset
- return;
- case 0x07:
- lGPUdataRet=0x02; // gpu type
- return;
- case 0x08:
- case 0x0F: // some bios addr?
- lGPUdataRet=0xBFC03720;
- return;
- }
- return;
- //--------------------------------------------------//
- }
-}
-
-////////////////////////////////////////////////////////////////////////
-// vram read/write helpers, needed by LEWPY's optimized vram read/write :)
-////////////////////////////////////////////////////////////////////////
-
-static inline void FinishedVRAMWrite(void)
-{
- // Set register to NORMAL operation
- DataWriteMode = DR_NORMAL;
- // Reset transfer values, to prevent mis-transfer of data
- VRAMWrite.x = 0;
- VRAMWrite.y = 0;
- VRAMWrite.Width = 0;
- VRAMWrite.Height = 0;
- VRAMWrite.ColsRemaining = 0;
- VRAMWrite.RowsRemaining = 0;
-}
-
-static inline void FinishedVRAMRead(void)
-{
- // Set register to NORMAL operation
- DataReadMode = 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
- lGPUstatusRet&=~GPUSTATUS_READYFORVRAM;
-}
-
-////////////////////////////////////////////////////////////////////////
-// core read from vram
-////////////////////////////////////////////////////////////////////////
-
-void CALLBACK GPUreadDataMem(uint32_t * pMem, int iSize)
-{
- int i;
-
- if(DataReadMode!=DR_VRAMTRANSFER) return;
-
- GPUIsBusy;
-
- // adjust read ptr, if necessary
- while(VRAMRead.ImagePtr>=psxVuw_eom)
- VRAMRead.ImagePtr-=512*1024;
- while(VRAMRead.ImagePtr<psxVuw)
- VRAMRead.ImagePtr+=512*1024;
-
- 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
- lGPUdataRet=(uint32_t)GETLE16(VRAMRead.ImagePtr);
-
- VRAMRead.ImagePtr++;
- if(VRAMRead.ImagePtr>=psxVuw_eom) VRAMRead.ImagePtr-=512*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-=512*1024;
- }
-
- // higher 16 bit (always, even if it's an odd width)
- lGPUdataRet|=(uint32_t)GETLE16(VRAMRead.ImagePtr)<<16;
- PUTLE32(pMem, lGPUdataRet); pMem++;
-
- if(VRAMRead.ColsRemaining <= 0)
- {FinishedVRAMRead();goto ENDREAD;}
-
- VRAMRead.ImagePtr++;
- if(VRAMRead.ImagePtr>=psxVuw_eom) VRAMRead.ImagePtr-=512*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-=512*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 lGPUdataRet;
-}
-
-// Software drawing function
-#include "soft.c"
-
-// PSX drawing primitives
-#include "prim.c"
-
-////////////////////////////////////////////////////////////////////////
-// processes data send to GPU data register
-// extra table entries for fixing polyline troubles
-////////////////////////////////////////////////////////////////////////
-
-static 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, // GLINE
- 255,255,255,255,255,255,255,255,
- // 60
- 3,3,3,3,4,4,4,4,
- // 68
- 2,2,2,2,3,3,3,3, // 3=SPRITE1???
- // 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
-};
-
-void CALLBACK GPUwriteDataMem(uint32_t * pMem, int iSize)
-{
- unsigned char command;
- uint32_t gdata=0;
- int i=0;
- GPUIsBusy;
- GPUIsNotReadyForCommands;
-
-STARTVRAM:
-
- if(DataWriteMode==DR_VRAMTRANSFER)
- {
- BOOL bFinished=FALSE;
-
- // make sure we are in vram
- while(VRAMWrite.ImagePtr>=psxVuw_eom)
- VRAMWrite.ImagePtr-=512*1024;
- while(VRAMWrite.ImagePtr<psxVuw)
- VRAMWrite.ImagePtr+=512*1024;
-
- // now do the loop
- while(VRAMWrite.ColsRemaining>0)
- {
- while(VRAMWrite.RowsRemaining>0)
- {
- if(i>=iSize) {goto ENDVRAM;}
- i++;
-
- gdata=GETLE32(pMem); pMem++;
-
- PUTLE16(VRAMWrite.ImagePtr, (unsigned short)gdata); VRAMWrite.ImagePtr++;
- if(VRAMWrite.ImagePtr>=psxVuw_eom) VRAMWrite.ImagePtr-=512*1024;
- VRAMWrite.RowsRemaining --;
-
- if(VRAMWrite.RowsRemaining <= 0)
- {
- VRAMWrite.ColsRemaining--;
- if (VRAMWrite.ColsRemaining <= 0) // last pixel is odd width
- {
- gdata=(gdata&0xFFFF)|(((uint32_t)GETLE16(VRAMWrite.ImagePtr))<<16);
- FinishedVRAMWrite();
- bDoVSyncUpdate=TRUE;
- goto ENDVRAM;
- }
- VRAMWrite.RowsRemaining = VRAMWrite.Width;
- VRAMWrite.ImagePtr += 1024 - VRAMWrite.Width;
- }
-
- PUTLE16(VRAMWrite.ImagePtr, (unsigned short)(gdata>>16)); VRAMWrite.ImagePtr++;
- if(VRAMWrite.ImagePtr>=psxVuw_eom) VRAMWrite.ImagePtr-=512*1024;
- VRAMWrite.RowsRemaining --;
- }
-
- VRAMWrite.RowsRemaining = VRAMWrite.Width;
- VRAMWrite.ColsRemaining--;
- VRAMWrite.ImagePtr += 1024 - VRAMWrite.Width;
- bFinished=TRUE;
- }
-
- FinishedVRAMWrite();
- if(bFinished) bDoVSyncUpdate=TRUE;
- }
-
-ENDVRAM:
-
- if(DataWriteMode==DR_NORMAL)
- {
- void (* *primFunc)(unsigned char *);
- if(bSkipNextFrame) primFunc=primTableSkip;
- else primFunc=primTableJ;
-
- for(;i<iSize;)
- {
- if(DataWriteMode==DR_VRAMTRANSFER) goto STARTVRAM;
-
- gdata=GETLE32(pMem); pMem++; i++;
-
- if(gpuDataC == 0)
- {
- command = (unsigned char)((gdata>>24) & 0xff);
-
-//if(command>=0xb0 && command<0xc0) auxprintf("b0 %x!!!!!!!!!\n",command);
-
- if(primTableCX[command])
- {
- gpuDataC = primTableCX[command];
- gpuCommand = command;
- PUTLE32_(&gpuDataM[0], gdata);
- gpuDataP = 1;
- }
- else continue;
- }
- else
- {
- PUTLE32_(&gpuDataM[gpuDataP], gdata);
- if(gpuDataC>128)
- {
- if((gpuDataC==254 && gpuDataP>=3) ||
- (gpuDataC==255 && gpuDataP>=4 && !(gpuDataP&1)))
- {
- if((gpuDataM[gpuDataP] & HOST2LE32(0xF000F000)) == HOST2LE32(0x50005000))
- gpuDataP=gpuDataC-1;
- }
- }
- gpuDataP++;
- }
-
- if(gpuDataP == gpuDataC)
- {
- gpuDataC=gpuDataP=0;
- primFunc[gpuCommand]((unsigned char *)gpuDataM);
- if(dwActFixes&0x0400) // hack for emulating "gpu busy" in some games
- iFakePrimBusy=4;
- }
- }
- }
-
- lGPUdataRet=gdata;
-
- GPUIsReadyForCommands;
- GPUIsIdle;
-}
-
-////////////////////////////////////////////////////////////////////////
-
-void CALLBACK GPUwriteData(uint32_t gdata)
-{
- PUTLE32_(&gdata, gdata);
- GPUwriteDataMem(&gdata,1);
-}
-
-////////////////////////////////////////////////////////////////////////
-// process gpu commands
-////////////////////////////////////////////////////////////////////////
-
-unsigned long lUsedAddr[3];
-
-static inline BOOL CheckForEndlessLoop(unsigned long 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;
-}
-
-long CALLBACK GPUdmaChain(uint32_t * baseAddrL, uint32_t addr)
-{
- uint32_t dmaMem;
- unsigned char * baseAddrB;
- short count;unsigned int DMACommandCounter = 0;
- long dmaWords = 0;
-
- GPUIsBusy;
-
- lUsedAddr[0]=lUsedAddr[1]=lUsedAddr[2]=0xffffff;
-
- baseAddrB = (unsigned char*) baseAddrL;
-
- do
- {
- addr&=0x1FFFFC;
- if(DMACommandCounter++ > 2000000) break;
- if(CheckForEndlessLoop(addr)) break;
-
- count = baseAddrB[addr+3];
- dmaWords += 1 + count;
-
- dmaMem=addr+4;
-
- if(count>0) GPUwriteDataMem(&baseAddrL[dmaMem>>2],count);
-
- addr = GETLE32(&baseAddrL[addr>>2])&0xffffff;
- } while (!(addr & 0x800000)); // contrary to some documentation, the end-of-linked-list marker is not actually 0xFF'FFFF
- // any pointer with bit 23 set will do.
-
- GPUIsIdle;
-
- return dmaWords;
-}
-
-////////////////////////////////////////////////////////////////////////
-// Freeze
-////////////////////////////////////////////////////////////////////////
-
-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) // 2: info, which save slot is selected? (just for display)
- {
- long lSlotNum=*((long *)pF);
- if(lSlotNum<0) return 0;
- if(lSlotNum>8) return 0;
- lSelectedSlot=lSlotNum+1;
- return 1;
- }
- //----------------------------------------------------//
- if(!pF) return 0; // some checks
- if(pF->ulFreezeVersion!=1) return 0;
-
- if(ulGetFreezeData==1) // 1: get data
- {
- pF->ulStatus=lGPUstatusRet;
- memcpy(pF->ulControl,ulStatusControl,256*sizeof(uint32_t));
- memcpy(pF->psxVRam, psxVub, 1024*512*2);
-
- return 1;
- }
-
- if(ulGetFreezeData!=0) return 0; // 0: set data
-
- lGPUstatusRet=pF->ulStatus;
- memcpy(ulStatusControl,pF->ulControl,256*sizeof(uint32_t));
- memcpy(psxVub, pF->psxVRam, 1024*512*2);
-
-// RESET TEXTURE STORE HERE, IF YOU USE SOMETHING LIKE THAT
-
- PreviousPSXDisplay.Height = 0;
- GPUwriteStatus(ulStatusControl[0]);
- GPUwriteStatus(ulStatusControl[1]);
- GPUwriteStatus(ulStatusControl[2]);
- GPUwriteStatus(ulStatusControl[3]);
- GPUwriteStatus(ulStatusControl[8]); // try to repair things
- GPUwriteStatus(ulStatusControl[6]);
- GPUwriteStatus(ulStatusControl[7]);
- GPUwriteStatus(ulStatusControl[5]);
- GPUwriteStatus(ulStatusControl[4]);
-
- return 1;
-}
-
-// rearmed thing
-#include "../../frontend/plugin_lib.h"
-
-const struct rearmed_cbs *rcbs;
-
-void GPUrearmedCallbacks(const struct rearmed_cbs *cbs)
-{
- // sync config
- UseFrameSkip = cbs->frameskip;
- iUseDither = cbs->gpu_peops.iUseDither;
- dwActFixes = cbs->gpu_peops.dwActFixes;
- fFrameRateHz = cbs->gpu_peops.fFrameRateHz;
- dwFrameRateTicks = cbs->gpu_peops.dwFrameRateTicks;
- if (cbs->pl_vout_set_raw_vram)
- cbs->pl_vout_set_raw_vram(psxVub);
- if (cbs->pl_set_gpu_caps)
- cbs->pl_set_gpu_caps(0);
-
- skip_advice = &cbs->fskip_advice;
- fps_skip = 100.0f;
- rcbs = cbs;
-}
+++ /dev/null
-/***************************************************************************\r
- gpu.c - description\r
- -------------------\r
- begin : Sun Mar 08 2009\r
- copyright : (C) 1999-2009 by Pete Bernert\r
- email : BlackDove@addcom.de\r
- ***************************************************************************/\r
-\r
-/***************************************************************************\r
- * *\r
- * This program is free software; you can redistribute it and/or modify *\r
- * it under the terms of the GNU General Public License as published by *\r
- * the Free Software Foundation; either version 2 of the License, or *\r
- * (at your option) any later version. See also the license.txt file for *\r
- * additional informations. *\r
- * *\r
- ***************************************************************************/\r
-\r
-//*************************************************************************// \r
-// History of changes:\r
-//\r
-// 2009/03/08 - Pete \r
-// - generic cleanup for the Peops release\r
-//\r
-//*************************************************************************// \r
-\r
-//#include "gpuStdafx.h"\r
-\r
-//#include <mmsystem.h>\r
-#define _IN_GPU\r
-\r
-#include <stdlib.h>\r
-#include <stdio.h>\r
-#include <stdarg.h>\r
-#include <string.h>\r
-#include "gpuExternals.h"\r
-#include "gpuPlugin.h"\r
-#include "gpuDraw.h"\r
-#include "gpuTexture.h"\r
-#include "gpuFps.h"\r
-#include "gpuPrim.h"\r
-\r
-//#include "NoPic.h"\r
-\r
-#include "gpuStdafx.h"\r
-\r
-short g_m1=255,g_m2=255,g_m3=255;\r
-short DrawSemiTrans=FALSE;\r
-short Ymin;\r
-short Ymax;\r
-\r
-short ly0,lx0,ly1,lx1,ly2,lx2,ly3,lx3; // global psx vertex coords\r
-long GlobalTextAddrX,GlobalTextAddrY,GlobalTextTP;\r
-long GlobalTextREST,GlobalTextABR,GlobalTextPAGE;\r
-\r
-unsigned long dwGPUVersion=0;\r
-int iGPUHeight=512;\r
-int iGPUHeightMask=511;\r
-int GlobalTextIL=0;\r
-int iTileCheat=0;\r
-\r
-////////////////////////////////////////////////////////////////////////\r
-// memory image of the PSX vram\r
-////////////////////////////////////////////////////////////////////////\r
-\r
-unsigned char *psxVSecure;\r
-unsigned char *psxVub;\r
-signed char *psxVsb;\r
-unsigned short *psxVuw;\r
-unsigned short *psxVuw_eom;\r
-signed short *psxVsw;\r
-unsigned long *psxVul;\r
-signed long *psxVsl;\r
-\r
-// macro for easy access to packet information\r
-#define GPUCOMMAND(x) ((x>>24) & 0xff)\r
-\r
-GLfloat gl_z=0.0f;\r
-BOOL bNeedInterlaceUpdate=FALSE;\r
-BOOL bNeedRGB24Update=FALSE;\r
-BOOL bChangeWinMode=FALSE;\r
-\r
-unsigned long ulStatusControl[256];\r
-\r
-////////////////////////////////////////////////////////////////////////\r
-// global GPU vars\r
-////////////////////////////////////////////////////////////////////////\r
-\r
-static long GPUdataRet;\r
-long lGPUstatusRet;\r
-char szDispBuf[64];\r
-\r
-static unsigned long gpuDataM[256];\r
-static unsigned char gpuCommand = 0;\r
-static long gpuDataC = 0;\r
-static long gpuDataP = 0;\r
-\r
-VRAMLoad_t VRAMWrite;\r
-VRAMLoad_t VRAMRead;\r
-int iDataWriteMode;\r
-int iDataReadMode;\r
-\r
-long lClearOnSwap;\r
-long lClearOnSwapColor;\r
-BOOL bSkipNextFrame = FALSE;\r
-int iColDepth;\r
-BOOL bChangeRes;\r
-BOOL bWindowMode;\r
-int iWinSize;\r
-\r
-// possible psx display widths\r
-short dispWidths[8] = {256,320,512,640,368,384,512,640};\r
-\r
-PSXDisplay_t PSXDisplay;\r
-PSXDisplay_t PreviousPSXDisplay;\r
-TWin_t TWin;\r
-short imageX0,imageX1;\r
-short imageY0,imageY1;\r
-BOOL bDisplayNotSet = TRUE;\r
-GLuint uiScanLine=0;\r
-int iUseScanLines=0;\r
-long lSelectedSlot=0;\r
-unsigned char * pGfxCardScreen=0;\r
-int iBlurBuffer=0;\r
-int iScanBlend=0;\r
-int iRenderFVR=0;\r
-int iNoScreenSaver=0;\r
-unsigned long ulGPUInfoVals[16];\r
-int iFakePrimBusy = 0;\r
-int iRumbleVal = 0;\r
-int iRumbleTime = 0;\r
-\r
-static void (*rearmed_get_layer_pos)(int *x, int *y, int *w, int *h);\r
-static void flipEGL(void);\r
-\r
-////////////////////////////////////////////////////////////////////////\r
-// stuff to make this a true PDK module\r
-////////////////////////////////////////////////////////////////////////\r
-\r
-////////////////////////////////////////////////////////////////////////\r
-// snapshot funcs (saves screen to bitmap / text infos into file)\r
-////////////////////////////////////////////////////////////////////////\r
-\r
-void ResizeWindow()\r
-{\r
- rRatioRect.left = rRatioRect.top=0;\r
- rRatioRect.right = iResX;\r
- rRatioRect.bottom = iResY;\r
- glViewport(rRatioRect.left, // init viewport by ratio rect\r
- iResY-(rRatioRect.top+rRatioRect.bottom),\r
- rRatioRect.right, \r
- rRatioRect.bottom); glError();\r
- \r
- glScissor(0, 0, iResX, iResY); glError(); // init clipping (fullscreen)\r
- glEnable(GL_SCISSOR_TEST); glError();\r
-\r
-#ifndef OWNSCALE\r
- glMatrixMode(GL_TEXTURE); // init psx tex sow and tow if not "ownscale"\r
- glLoadIdentity();\r
- glScalef(1.0f/255.99f,1.0f/255.99f,1.0f); // geforce precision hack\r
-#endif \r
-\r
- glMatrixMode(GL_PROJECTION); glError(); // init projection with psx resolution\r
- glLoadIdentity(); glError();\r
- glOrtho(0,PSXDisplay.DisplayMode.x,\r
- PSXDisplay.DisplayMode.y, 0, -1, 1); glError();\r
- if (bKeepRatio)\r
- SetAspectRatio();\r
-}\r
-\r
-char * GetConfigInfos(int hW)\r
-{\r
- char szO[2][4]={"off","on "};\r
- char szTxt[256];\r
- char * pB=(char *)malloc(32767);\r
-/*\r
- if(!pB) return NULL;\r
- *pB=0;\r
- //----------------------------------------------------//\r
- strcat(pB,szTxt);\r
- strcat(pB,szTxt);\r
-#ifdef _WINDOWS\r
- if(hW)\r
- {\r
- hdc = GetDC(hW);\r
- bSetupPixelFormat(hdc);\r
- hglrc = wglCreateContext(hdc);\r
- wglMakeCurrent(hdc, hglrc);\r
- }\r
-#endif\r
- sprintf(szTxt,"Card vendor: %s\r\n",(char *)glGetString(GL_VENDOR));\r
- strcat(pB,szTxt);\r
- sprintf(szTxt,"GFX card: %s\r\n",(char *)glGetString(GL_RENDERER));\r
- strcat(pB,szTxt);\r
- sprintf(szTxt,"OGL version: %s\r\n\r\n",(char *)glGetString(GL_VERSION));\r
- strcat(pB,szTxt);\r
- //strcat(pB,(char *)glGetString(GL_EXTENSIONS));\r
- //strcat(pB,"\r\n\r\n");\r
-\r
-#ifdef _WINDOWS\r
- if(hW)\r
- {\r
- wglMakeCurrent(NULL, NULL);\r
- wglDeleteContext(hglrc);\r
- ReleaseDC(hW,hdc);\r
- }\r
- //----------------------------------------------------//\r
-#endif\r
- if(hW && bWindowMode)\r
- sprintf(szTxt,"Resolution/Color:\r\n- %dx%d ",LOWORD(iWinSize),HIWORD(iWinSize));\r
- else\r
- sprintf(szTxt,"Resolution/Color:\r\n- %dx%d ",iResX,iResY);\r
- strcat(pB,szTxt);\r
- if(bWindowMode) sprintf(szTxt,"Window mode\r\n");\r
- else\r
- {\r
- sprintf(szTxt,"Fullscreen ");\r
- strcat(pB,szTxt);\r
- if(bChangeRes) sprintf(szTxt,"- Desktop changing [%d Bit]\r\n",iColDepth);\r
- else sprintf(szTxt,"- NO desktop changing\r\n");\r
- } \r
- strcat(pB,szTxt);\r
-\r
-// if(iForceVSync>=0) sprintf(szTxt,"- V-Sync: %s\r\n",szO[iForceVSync]);\r
-// else strcpy(szTxt,"- V-Sync: Driver\r\n");\r
- strcat(pB,szTxt); \r
- sprintf(szTxt,"- Keep psx aspect ratio: %s\r\n\r\n",szO[bKeepRatio]);\r
- strcat(pB,szTxt);\r
- //----------------------------------------------------//\r
- strcpy(szTxt,"Textures:\r\n- ");\r
-/*! if(iTexQuality==0) strcat(szTxt,"Default");\r
- else if(iTexQuality==1) strcat(szTxt,"R4G4B4A4");\r
- else if(iTexQuality==2) strcat(szTxt,"R5G5B5A1");\r
- else if(iTexQuality==3) strcat(szTxt,"R8G8A8A8");\r
- else if(iTexQuality==4) strcat(szTxt,"B8G8R8A8");\r
- if(!hW && bGLExt) strcat(szTxt," (packed pixels)\r\n");\r
- else strcat(szTxt,"\r\n");\r
- strcat(pB,szTxt);\r
- if(!hW)\r
- {\r
- sprintf(szTxt,"- Filtering: %d - edge clamping ",iFilterType);\r
- if(iClampType==GL_TO_EDGE_CLAMP) strcat(szTxt,"supported\r\n");\r
- else strcat(szTxt,"NOT supported\r\n");\r
- }\r
- else sprintf(szTxt,"- iFiltering: %d\r\n",iFilterType);\r
- strcat(pB,szTxt);\r
- sprintf(szTxt,"- Hi-Res textures: %d\r\n",iHiResTextures);\r
- strcat(pB,szTxt); \r
- if(!hW)\r
- {\r
- sprintf(szTxt,"- Palettized tex windows: %s\r\n",szO[iUsePalTextures]);\r
- strcat(pB,szTxt); \r
- }\r
- !*/\r
- /*sprintf(szTxt,"- VRam size: %d MBytes",iVRamSize);\r
- if(!hW)\r
- sprintf(szTxt+strlen(szTxt)," - %d textures usable\r\n\r\n",iSortTexCnt);\r
- else strcat(szTxt,"\r\n\r\n");\r
- strcat(pB,szTxt);\r
- //----------------------------------------------------//\r
- sprintf(szTxt,"Framerate:\r\n- FPS limitation: %s\r\n",szO[bUseFrameLimit]);\r
- strcat(pB,szTxt);\r
- sprintf(szTxt,"- Frame skipping: %s\r\n",szO[bUseFrameSkip]);\r
- strcat(pB,szTxt);\r
- if(iFrameLimit==2)\r
- strcpy(szTxt,"- FPS limit: Auto\r\n\r\n");\r
- else sprintf(szTxt,"- FPS limit: %.1f\r\n\r\n",fFrameRate);\r
- strcat(pB,szTxt);\r
- //----------------------------------------------------//\r
- sprintf(szTxt,"Compatibility:\r\n- Offscreen drawing: %d\r\n",iOffscreenDrawing);\r
- strcat(pB,szTxt);\r
- sprintf(szTxt,"- Framebuffer texture: %d",iFrameTexType);\r
- if(!hW && iFrameTexType==2)\r
- {\r
- if(gTexFrameName) strcat(szTxt," - texture created\r\n");\r
- else strcat(szTxt," - not used yet\r\n");\r
- }\r
- else strcat(szTxt,"\r\n");\r
- strcat(pB,szTxt);\r
- sprintf(szTxt,"- Framebuffer access: %d\r\n",iFrameReadType);\r
- strcat(pB,szTxt);\r
-// sprintf(szTxt,"- Alpha multipass: %s\r\n",szO[bOpaquePass]);\r
- strcat(pB,szTxt);\r
- sprintf(szTxt,"- Mask bit: %s\r\n",szO[iUseMask]);\r
- strcat(pB,szTxt);\r
- //sprintf(szTxt,"- Advanced blending: %s",szO[bAdvancedBlend]);\r
- //if(!hW && bAdvancedBlend)\r
-// {\r
-// if(bGLBlend) strcat(szTxt," (hardware)\r\n");\r
-// else strcat(szTxt," (software)\r\n");\r
-// }\r
- strcat(szTxt,"\r\n");\r
- strcat(pB,szTxt);\r
-\r
- if(!hW)\r
- {\r
- strcpy(szTxt,"- Subtractive blending: ");\r
-// if(glBlendEquationEXTEx)\r
-// {\r
-// if(bUseMultiPass) strcat(szTxt,"supported, but not used!");\r
-// else strcat(szTxt,"activated");\r
-// }\r
- strcat(szTxt," NOT supported!");\r
- strcat(szTxt,"\r\n\r\n");\r
- }\r
- else strcpy(szTxt,"\r\n");\r
- \r
- strcat(pB,szTxt); \r
- //----------------------------------------------------//\r
- sprintf(szTxt,"Misc:\r\n- Scanlines: %s",szO[iUseScanLines]);\r
- strcat(pB,szTxt);\r
- if(iUseScanLines) sprintf(szTxt," [%d]\r\n",iScanBlend);\r
- else strcpy(szTxt,"\r\n");\r
- strcat(pB,szTxt);\r
-// sprintf(szTxt,"- Line mode: %s\r\n",szO[bUseLines]);\r
- strcat(pB,szTxt);\r
-// sprintf(szTxt,"- Line AA: %s\r\n",szO[bUseAntiAlias]);\r
-// fwrite(szTxt,lstrlen(szTxt),1,txtfile);\r
- sprintf(szTxt,"- Unfiltered FB: %s\r\n",szO[bUseFastMdec]);\r
- strcat(pB,szTxt);\r
- sprintf(szTxt,"- 15 bit FB: %s\r\n",szO[bUse15bitMdec]);\r
- strcat(pB,szTxt);\r
- sprintf(szTxt,"- Dithering: %s\r\n",szO[bDrawDither]);\r
- strcat(pB,szTxt);\r
- sprintf(szTxt,"- Screen smoothing: %s",szO[iBlurBuffer]);\r
- strcat(pB,szTxt);\r
- if(!hW && iBlurBuffer) \r
- {\r
- if(gTexBlurName) strcat(pB," - supported\r\n");\r
- else strcat(pB," - not supported\r\n");\r
- }\r
- else strcat(pB,"\r\n");\r
- sprintf(szTxt,"- Game fixes: %s [%08lx]\r\n",szO[bUseFixes],dwCfgFixes);\r
- strcat(pB,szTxt);\r
- //----------------------------------------------------//\r
-*/ return pB;\r
-}\r
-\r
-////////////////////////////////////////////////////////////////////////\r
-// save text infos to file\r
-////////////////////////////////////////////////////////////////////////\r
-\r
-void DoTextSnapShot(int iNum)\r
-{\r
-}\r
-\r
-////////////////////////////////////////////////////////////////////////\r
-// saves screen bitmap to file\r
-////////////////////////////////////////////////////////////////////////\r
-\r
-void DoSnapShot(void)\r
-{\r
-} \r
-\r
-void CALLBACK GPUmakeSnapshot(void)\r
-{\r
- //bSnapShot = TRUE;\r
-} \r
-\r
-////////////////////////////////////////////////////////////////////////\r
-// GPU INIT... here starts it all (first func called by emu)\r
-////////////////////////////////////////////////////////////////////////\r
-\r
-long CALLBACK GPUinit()\r
-{\r
-memset(ulStatusControl,0,256*sizeof(unsigned long));\r
-\r
-bChangeRes=FALSE;\r
-bWindowMode=FALSE;\r
-\r
-bKeepRatio = TRUE;\r
-// different ways of accessing PSX VRAM\r
-\r
-psxVSecure=(unsigned char *)malloc((iGPUHeight*2)*1024 + (1024*1024)); // always alloc one extra MB for soft drawing funcs security\r
-if(!psxVSecure) return -1;\r
-\r
-psxVub=psxVSecure+512*1024; // security offset into double sized psx vram!\r
-psxVsb=(signed char *)psxVub;\r
-psxVsw=(signed short *)psxVub;\r
-psxVsl=(signed long *)psxVub;\r
-psxVuw=(unsigned short *)psxVub;\r
-psxVul=(unsigned long *)psxVub;\r
-\r
-psxVuw_eom=psxVuw+1024*iGPUHeight; // pre-calc of end of vram\r
-\r
-memset(psxVSecure,0x00,(iGPUHeight*2)*1024 + (1024*1024));\r
-memset(ulGPUInfoVals,0x00,16*sizeof(unsigned long));\r
-\r
-InitFrameCap(); // init frame rate stuff\r
-\r
-PSXDisplay.RGB24 = 0; // init vars\r
-PreviousPSXDisplay.RGB24= 0;\r
-PSXDisplay.Interlaced = 0;\r
-PSXDisplay.InterlacedTest=0;\r
-PSXDisplay.DrawOffset.x = 0;\r
-PSXDisplay.DrawOffset.y = 0;\r
-PSXDisplay.DrawArea.x0 = 0;\r
-PSXDisplay.DrawArea.y0 = 0;\r
-PSXDisplay.DrawArea.x1 = 320;\r
-PSXDisplay.DrawArea.y1 = 240;\r
-PSXDisplay.DisplayMode.x= 320;\r
-PSXDisplay.DisplayMode.y= 240;\r
-PSXDisplay.Disabled = FALSE;\r
-PreviousPSXDisplay.Range.x0 =0;\r
-PreviousPSXDisplay.Range.x1 =0;\r
-PreviousPSXDisplay.Range.y0 =0;\r
-PreviousPSXDisplay.Range.y1 =0;\r
-PSXDisplay.Range.x0=0;\r
-PSXDisplay.Range.x1=0;\r
-PSXDisplay.Range.y0=0;\r
-PSXDisplay.Range.y1=0;\r
-PreviousPSXDisplay.DisplayPosition.x = 1;\r
-PreviousPSXDisplay.DisplayPosition.y = 1;\r
-PSXDisplay.DisplayPosition.x = 1;\r
-PSXDisplay.DisplayPosition.y = 1;\r
-PreviousPSXDisplay.DisplayModeNew.y=0;\r
-PSXDisplay.Double=1;\r
-GPUdataRet=0x400;\r
-\r
-PSXDisplay.DisplayModeNew.x=0;\r
-PSXDisplay.DisplayModeNew.y=0;\r
-\r
-//PreviousPSXDisplay.Height = PSXDisplay.Height = 239;\r
-\r
-iDataWriteMode = DR_NORMAL;\r
-\r
-// Reset transfer values, to prevent mis-transfer of data\r
-memset(&VRAMWrite,0,sizeof(VRAMLoad_t));\r
-memset(&VRAMRead,0,sizeof(VRAMLoad_t));\r
-\r
-// device initialised already !\r
-//lGPUstatusRet = 0x74000000;\r
-\r
-STATUSREG = 0x14802000;\r
-GPUIsIdle;\r
-GPUIsReadyForCommands;\r
-\r
-return 0;\r
-} \r
-\r
-\r
-////////////////////////////////////////////////////////////////////////\r
-// OPEN interface func: attention! \r
-// some emus are calling this func in their main Window thread,\r
-// but all other interface funcs (to draw stuff) in a different thread!\r
-// that's a problem, since OGL is thread safe! Therefore we cannot \r
-// initialize the OGL stuff right here, we simply set a "bIsFirstFrame = TRUE"\r
-// flag, to initialize OGL on the first real draw call.\r
-// btw, we also call this open func ourselfes, each time when the user \r
-// is changing between fullscreen/window mode (ENTER key)\r
-// btw part 2: in windows the plugin gets the window handle from the\r
-// main emu, and doesn't create it's own window (if it would do it,\r
-// some PAD or SPU plugins would not work anymore)\r
-////////////////////////////////////////////////////////////////////////\r
-\r
-long CALLBACK GPUopen(unsigned long *disp, char *cap, char *cfg)\r
-{\r
- iResX=800;iResY=480;\r
- iColDepth=8;\r
- bChangeRes=FALSE;\r
- bWindowMode=FALSE;\r
- bFullVRam=FALSE;\r
- iFilterType=0;\r
- // bAdvancedBlend=FALSE;\r
- bDrawDither=FALSE;\r
- // bUseLines=FALSE;\r
- bUseFrameLimit=FALSE;\r
- bUseFrameSkip=FALSE;\r
- iFrameLimit=0;\r
- fFrameRate=50.0f;\r
- iOffscreenDrawing=0;\r
- //bOpaquePass=FALSE;\r
- //bUseAntiAlias=FALSE;\r
- //iTexQuality=0;\r
- iUseMask=0;\r
- iZBufferDepth=0;\r
- bUseFastMdec=FALSE;\r
- bUse15bitMdec=FALSE;\r
- dwCfgFixes=0;\r
- bUseFixes=FALSE;\r
- // iUseScanLines=0;\r
- iFrameTexType=0;\r
- iFrameReadType=0;\r
- //iShowFPS=0;\r
- bKeepRatio=TRUE;\r
- iScanBlend=0;\r
- iVRamSize=0;\r
- iTexGarbageCollection=0;\r
- iBlurBuffer=0; \r
- //iHiResTextures=0;\r
- iNoScreenSaver=0;\r
- //iForceVSync=0;\r
-\r
-\r
-\r
- bIsFirstFrame = TRUE; // flag: we have to init OGL later in windows!\r
-\r
- rRatioRect.left = rRatioRect.top=0;\r
- rRatioRect.right = iResX;\r
- rRatioRect.bottom = iResY;\r
-\r
- bDisplayNotSet = TRUE; \r
- bSetClip=TRUE;\r
-\r
- SetFixes(); // setup game fixes\r
-\r
- InitializeTextureStore(); // init texture mem\r
-\r
- CSTEXTURE = CSVERTEX = CSCOLOR = 0;\r
-\r
-// lGPUstatusRet = 0x74000000;\r
-\r
-// with some emus, we could do the OGL init right here... oh my\r
- if(bIsFirstFrame) GLinitialize(NULL, NULL);\r
-\r
- return 0;\r
-}\r
-\r
-////////////////////////////////////////////////////////////////////////\r
-// close\r
-////////////////////////////////////////////////////////////////////////\r
-\r
-\r
-long GPUclose() // LINUX CLOSE\r
-{\r
- GLcleanup(); // close OGL\r
-\r
- if(pGfxCardScreen) free(pGfxCardScreen); // free helper memory\r
- pGfxCardScreen=0;\r
-\r
-// osd_close_display(); // destroy display\r
-\r
- return 0;\r
-}\r
-\r
-////////////////////////////////////////////////////////////////////////\r
-// I shot the sheriff... last function called from emu \r
-////////////////////////////////////////////////////////////////////////\r
-\r
-long CALLBACK GPUshutdown()\r
-{\r
- if(psxVSecure) free(psxVSecure); // kill emulated vram memory\r
- psxVSecure=0;\r
-\r
- return 0;\r
-}\r
-\r
-////////////////////////////////////////////////////////////////////////\r
-// paint it black: simple func to clean up optical border garbage\r
-////////////////////////////////////////////////////////////////////////\r
-\r
-void PaintBlackBorders(void)\r
-{\r
- short s;\r
- glDisable(GL_SCISSOR_TEST); glError();\r
- if(bTexEnabled) {glDisable(GL_TEXTURE_2D);bTexEnabled=FALSE;} glError();\r
- if(bOldSmoothShaded) {glShadeModel(GL_FLAT);bOldSmoothShaded=FALSE;} glError();\r
- if(bBlendEnable) {glDisable(GL_BLEND);bBlendEnable=FALSE;} glError();\r
- glDisable(GL_ALPHA_TEST); glError();\r
-\r
- glEnable(GL_ALPHA_TEST); glError();\r
- glEnable(GL_SCISSOR_TEST); glError();\r
-\r
-}\r
-\r
-////////////////////////////////////////////////////////////////////////\r
-// helper to draw scanlines\r
-////////////////////////////////////////////////////////////////////////\r
-\r
-__inline void XPRIMdrawTexturedQuad(OGLVertex* vertex1, OGLVertex* vertex2, \r
- OGLVertex* vertex3, OGLVertex* vertex4) \r
-{\r
-\r
-}\r
-\r
-////////////////////////////////////////////////////////////////////////\r
-// scanlines\r
-////////////////////////////////////////////////////////////////////////\r
-\r
-void SetScanLines(void)\r
-{\r
-}\r
-\r
-////////////////////////////////////////////////////////////////////////\r
-// blur, babe, blur (heavy performance hit for a so-so fullscreen effect)\r
-////////////////////////////////////////////////////////////////////////\r
-\r
-\r
-////////////////////////////////////////////////////////////////////////\r
-// Update display (swap buffers)... called in interlaced mode on \r
-// every emulated vsync, otherwise whenever the displayed screen region\r
-// has been changed\r
-////////////////////////////////////////////////////////////////////////\r
-\r
-int iLastRGB24=0; // special vars for checking when to skip two display updates\r
-int iSkipTwo=0;\r
-void GPUvSinc(void){\r
-updateDisplay();\r
-}\r
-void updateDisplay(void) // UPDATE DISPLAY\r
-{\r
-BOOL bBlur=FALSE;\r
-\r
-\r
-bFakeFrontBuffer=FALSE;\r
-bRenderFrontBuffer=FALSE;\r
-\r
-if(iRenderFVR) // frame buffer read fix mode still active?\r
- {\r
- iRenderFVR--; // -> if some frames in a row without read access: turn off mode\r
- if(!iRenderFVR) bFullVRam=FALSE;\r
- }\r
-\r
-if(iLastRGB24 && iLastRGB24!=PSXDisplay.RGB24+1) // (mdec) garbage check\r
- {\r
- iSkipTwo=2; // -> skip two frames to avoid garbage if color mode changes\r
- }\r
-iLastRGB24=0;\r
-\r
-if(PSXDisplay.RGB24)// && !bNeedUploadAfter) // (mdec) upload wanted?\r
- {\r
- PrepareFullScreenUpload(-1);\r
- UploadScreen(PSXDisplay.Interlaced); // -> upload whole screen from psx vram\r
- bNeedUploadTest=FALSE;\r
- bNeedInterlaceUpdate=FALSE;\r
- bNeedUploadAfter=FALSE;\r
- bNeedRGB24Update=FALSE;\r
- }\r
-else\r
-if(bNeedInterlaceUpdate) // smaller upload?\r
- {\r
- bNeedInterlaceUpdate=FALSE;\r
- xrUploadArea=xrUploadAreaIL; // -> upload this rect\r
- UploadScreen(TRUE);\r
- }\r
-\r
-if(dwActFixes&512) bCheckFF9G4(NULL); // special game fix for FF9 \r
-\r
-if(PreviousPSXDisplay.Range.x0|| // paint black borders around display area, if needed\r
- PreviousPSXDisplay.Range.y0)\r
- PaintBlackBorders();\r
-\r
-if(PSXDisplay.Disabled) // display disabled?\r
- {\r
- //LOGE("PSXDisplay.Disabled");\r
-\r
- // moved here\r
- glDisable(GL_SCISSOR_TEST); glError(); \r
- glClearColor(0,0,0,128); glError(); // -> clear whole backbuffer\r
- glClear(uiBufferBits); glError();\r
- glEnable(GL_SCISSOR_TEST); glError(); \r
- gl_z=0.0f;\r
- bDisplayNotSet = TRUE;\r
- }\r
-\r
-if(iSkipTwo) // we are in skipping mood?\r
- {\r
- iSkipTwo--;\r
- iDrawnSomething=0; // -> simply lie about something drawn\r
- }\r
-\r
-//if(iBlurBuffer && !bSkipNextFrame) // "blur display" activated?\r
-// {BlurBackBuffer();bBlur=TRUE;} // -> blur it\r
-\r
-// if(iUseScanLines) SetScanLines(); // "scan lines" activated? do it\r
-\r
-// if(usCursorActive) ShowGunCursor(); // "gun cursor" wanted? show 'em\r
-\r
-if(dwActFixes&128) // special FPS limitation mode?\r
- {\r
- if(bUseFrameLimit) PCFrameCap(); // -> ok, do it\r
-// if(bUseFrameSkip || ulKeybits&KEY_SHOWFPS) \r
- PCcalcfps(); \r
- }\r
-\r
-// if(gTexPicName) DisplayPic(); // some gpu info picture active? display it\r
-\r
-// if(bSnapShot) DoSnapShot(); // snapshot key pressed? cheeeese :)\r
-\r
-// if(ulKeybits&KEY_SHOWFPS) // wanna see FPS?\r
- {\r
-// sprintf(szDispBuf,"%06.1f",fps_cur);\r
-// DisplayText(); // -> show it\r
- }\r
-\r
-//----------------------------------------------------//\r
-// main buffer swapping (well, or skip it)\r
-\r
-if(bUseFrameSkip) // frame skipping active ?\r
- {\r
- if(!bSkipNextFrame) \r
- {\r
- if(iDrawnSomething) flipEGL();\r
- }\r
- if((fps_skip < fFrameRateHz) && !(bSkipNextFrame)) \r
- {bSkipNextFrame = TRUE; fps_skip=fFrameRateHz;}\r
- else bSkipNextFrame = FALSE;\r
-\r
- }\r
-else // no skip ?\r
- {\r
- if(iDrawnSomething) flipEGL();\r
- }\r
-\r
-iDrawnSomething=0;\r
-\r
-//----------------------------------------------------//\r
-\r
-if(lClearOnSwap) // clear buffer after swap?\r
- {\r
- GLclampf g,b,r;\r
-\r
- if(bDisplayNotSet) // -> set new vals\r
- SetOGLDisplaySettings(1);\r
-\r
- g=((GLclampf)GREEN(lClearOnSwapColor))/255.0f; // -> get col\r
- b=((GLclampf)BLUE(lClearOnSwapColor))/255.0f;\r
- r=((GLclampf)RED(lClearOnSwapColor))/255.0f;\r
- glDisable(GL_SCISSOR_TEST); glError(); \r
- glClearColor(r,g,b,128); glError(); // -> clear \r
- glClear(uiBufferBits); glError();\r
- glEnable(GL_SCISSOR_TEST); glError(); \r
- lClearOnSwap=0; // -> done\r
- }\r
-else \r
- {\r
-// if(bBlur) UnBlurBackBuffer(); // unblur buff, if blurred before\r
-\r
- if(iZBufferDepth) // clear zbuffer as well (if activated)\r
- {\r
- glDisable(GL_SCISSOR_TEST); glError();\r
- glClear(GL_DEPTH_BUFFER_BIT); glError();\r
- glEnable(GL_SCISSOR_TEST); glError();\r
- }\r
- }\r
-\r
-gl_z=0.0f;\r
-\r
-//----------------------------------------------------//\r
-// additional uploads immediatly after swapping\r
-\r
-if(bNeedUploadAfter) // upload wanted?\r
- {\r
- bNeedUploadAfter=FALSE; \r
- bNeedUploadTest=FALSE;\r
- UploadScreen(-1); // -> upload\r
- }\r
-\r
-if(bNeedUploadTest)\r
- {\r
- bNeedUploadTest=FALSE;\r
- if(PSXDisplay.InterlacedTest &&\r
- //iOffscreenDrawing>2 &&\r
- PreviousPSXDisplay.DisplayPosition.x==PSXDisplay.DisplayPosition.x &&\r
- PreviousPSXDisplay.DisplayEnd.x==PSXDisplay.DisplayEnd.x &&\r
- PreviousPSXDisplay.DisplayPosition.y==PSXDisplay.DisplayPosition.y &&\r
- PreviousPSXDisplay.DisplayEnd.y==PSXDisplay.DisplayEnd.y)\r
- {\r
- PrepareFullScreenUpload(TRUE);\r
- UploadScreen(TRUE);\r
- }\r
- }\r
-\r
-//----------------------------------------------------//\r
-// rumbling (main emu pad effect)\r
-\r
-if(iRumbleTime) // shake screen by modifying view port\r
- {\r
- int i1=0,i2=0,i3=0,i4=0;\r
-\r
- iRumbleTime--;\r
- if(iRumbleTime) \r
- {\r
- i1=((rand()*iRumbleVal)/RAND_MAX)-(iRumbleVal/2); \r
- i2=((rand()*iRumbleVal)/RAND_MAX)-(iRumbleVal/2); \r
- i3=((rand()*iRumbleVal)/RAND_MAX)-(iRumbleVal/2); \r
- i4=((rand()*iRumbleVal)/RAND_MAX)-(iRumbleVal/2); \r
- }\r
-\r
- glViewport(rRatioRect.left+i1, \r
- iResY-(rRatioRect.top+rRatioRect.bottom)+i2,\r
- rRatioRect.right+i3, \r
- rRatioRect.bottom+i4); glError();\r
- }\r
-\r
-//----------------------------------------------------//\r
-\r
-\r
-\r
-// if(ulKeybits&KEY_RESETTEXSTORE) ResetStuff(); // reset on gpu mode changes? do it before next frame is filled\r
-}\r
-\r
-////////////////////////////////////////////////////////////////////////\r
-// update front display: smaller update func, if something has changed \r
-// in the frontbuffer... dirty, but hey... real men know no pain\r
-////////////////////////////////////////////////////////////////////////\r
-\r
-void updateFrontDisplay(void)\r
-{\r
-if(PreviousPSXDisplay.Range.x0||\r
- PreviousPSXDisplay.Range.y0)\r
- PaintBlackBorders();\r
-\r
-//if(iBlurBuffer) BlurBackBuffer();\r
-\r
-//if(iUseScanLines) SetScanLines();\r
-\r
-// if(usCursorActive) ShowGunCursor();\r
-\r
-bFakeFrontBuffer=FALSE;\r
-bRenderFrontBuffer=FALSE;\r
-\r
-// if(gTexPicName) DisplayPic();\r
-// if(ulKeybits&KEY_SHOWFPS) DisplayText();\r
-\r
-if(iDrawnSomething) // linux:\r
- flipEGL();\r
-\r
-\r
-//if(iBlurBuffer) UnBlurBackBuffer();\r
-}\r
- \r
-////////////////////////////////////////////////////////////////////////\r
-// check if update needed\r
-////////////////////////////////////////////////////////////////////////\r
-void ChangeDispOffsetsX(void) // CENTER X\r
-{\r
-long lx,l;short sO;\r
-\r
-if(!PSXDisplay.Range.x1) return; // some range given?\r
-\r
-l=PSXDisplay.DisplayMode.x;\r
-\r
-l*=(long)PSXDisplay.Range.x1; // some funky calculation\r
-l/=2560;lx=l;l&=0xfffffff8;\r
-\r
-if(l==PreviousPSXDisplay.Range.x1) return; // some change?\r
-\r
-sO=PreviousPSXDisplay.Range.x0; // store old\r
-\r
-if(lx>=PSXDisplay.DisplayMode.x) // range bigger?\r
- {\r
- PreviousPSXDisplay.Range.x1= // -> take display width\r
- PSXDisplay.DisplayMode.x;\r
- PreviousPSXDisplay.Range.x0=0; // -> start pos is 0\r
- }\r
-else // range smaller? center it\r
- {\r
- PreviousPSXDisplay.Range.x1=l; // -> store width (8 pixel aligned)\r
- PreviousPSXDisplay.Range.x0= // -> calc start pos\r
- (PSXDisplay.Range.x0-500)/8;\r
- if(PreviousPSXDisplay.Range.x0<0) // -> we don't support neg. values yet\r
- PreviousPSXDisplay.Range.x0=0;\r
-\r
- if((PreviousPSXDisplay.Range.x0+lx)> // -> uhuu... that's too much\r
- PSXDisplay.DisplayMode.x)\r
- {\r
- PreviousPSXDisplay.Range.x0= // -> adjust start\r
- PSXDisplay.DisplayMode.x-lx;\r
- PreviousPSXDisplay.Range.x1+=lx-l; // -> adjust width\r
- } \r
- }\r
-\r
-if(sO!=PreviousPSXDisplay.Range.x0) // something changed?\r
- {\r
- bDisplayNotSet=TRUE; // -> recalc display stuff\r
- }\r
-}\r
-\r
-////////////////////////////////////////////////////////////////////////\r
-\r
-void ChangeDispOffsetsY(void) // CENTER Y\r
-{\r
-int iT;short sO; // store previous y size\r
-\r
-if(PSXDisplay.PAL) iT=48; else iT=28; // different offsets on PAL/NTSC\r
-\r
-if(PSXDisplay.Range.y0>=iT) // crossed the security line? :)\r
- {\r
- PreviousPSXDisplay.Range.y1= // -> store width\r
- PSXDisplay.DisplayModeNew.y;\r
- \r
- sO=(PSXDisplay.Range.y0-iT-4)*PSXDisplay.Double; // -> calc offset\r
- if(sO<0) sO=0;\r
-\r
- PSXDisplay.DisplayModeNew.y+=sO; // -> add offset to y size, too\r
- }\r
-else sO=0; // else no offset\r
-\r
-if(sO!=PreviousPSXDisplay.Range.y0) // something changed?\r
- {\r
- PreviousPSXDisplay.Range.y0=sO;\r
- bDisplayNotSet=TRUE; // -> recalc display stuff\r
- }\r
-}\r
-\r
-////////////////////////////////////////////////////////////////////////\r
-// Aspect ratio of ogl screen: simply adjusting ogl view port\r
-////////////////////////////////////////////////////////////////////////\r
-\r
-void SetAspectRatio(void)\r
-{\r
-float xs,ys,s;RECT r;\r
-\r
-if(!PSXDisplay.DisplayModeNew.x) return;\r
-if(!PSXDisplay.DisplayModeNew.y) return;\r
-\r
-#if 0\r
-xs=(float)iResX/(float)PSXDisplay.DisplayModeNew.x;\r
-ys=(float)iResY/(float)PSXDisplay.DisplayModeNew.y;\r
-\r
-s=min(xs,ys);\r
-r.right =(int)((float)PSXDisplay.DisplayModeNew.x*s);\r
-r.bottom=(int)((float)PSXDisplay.DisplayModeNew.y*s);\r
-if(r.right > iResX) r.right = iResX;\r
-if(r.bottom > iResY) r.bottom = iResY;\r
-if(r.right < 1) r.right = 1;\r
-if(r.bottom < 1) r.bottom = 1;\r
-\r
-r.left = (iResX-r.right)/2;\r
-r.top = (iResY-r.bottom)/2;\r
-if(r.bottom<rRatioRect.bottom ||\r
- r.right <rRatioRect.right)\r
- {\r
- RECT rC;\r
- glClearColor(0,0,0,128); glError();\r
-\r
- if(r.right <rRatioRect.right)\r
- {\r
- rC.left=0;\r
- rC.top=0;\r
- rC.right=r.left;\r
- rC.bottom=iResY;\r
- glScissor(rC.left,rC.top,rC.right,rC.bottom); glError();\r
- glClear(uiBufferBits); glError();\r
- rC.left=iResX-rC.right;\r
- glScissor(rC.left,rC.top,rC.right,rC.bottom); glError();\r
- \r
- glClear(uiBufferBits); glError();\r
- }\r
-\r
- if(r.bottom <rRatioRect.bottom)\r
- {\r
- rC.left=0;\r
- rC.top=0;\r
- rC.right=iResX;\r
- rC.bottom=r.top;\r
- glScissor(rC.left,rC.top,rC.right,rC.bottom); glError();\r
-\r
- glClear(uiBufferBits); glError();\r
- rC.top=iResY-rC.bottom;\r
- glScissor(rC.left,rC.top,rC.right,rC.bottom); glError();\r
- glClear(uiBufferBits); glError();\r
- }\r
- \r
- bSetClip=TRUE;\r
- bDisplayNotSet=TRUE;\r
- }\r
-\r
-rRatioRect=r;\r
-#else\r
- // pcsx-rearmed hack\r
- if (rearmed_get_layer_pos != NULL)\r
- rearmed_get_layer_pos(&rRatioRect.left, &rRatioRect.top, &rRatioRect.right, &rRatioRect.bottom);\r
-#endif\r
-\r
-glViewport(rRatioRect.left,\r
- iResY-(rRatioRect.top+rRatioRect.bottom),\r
- rRatioRect.right,\r
- rRatioRect.bottom); glError(); // init viewport\r
-}\r
-\r
-////////////////////////////////////////////////////////////////////////\r
-// big ass check, if an ogl swap buffer is needed\r
-////////////////////////////////////////////////////////////////////////\r
-\r
-void updateDisplayIfChanged(void)\r
-{\r
-BOOL bUp;\r
-\r
-if ((PSXDisplay.DisplayMode.y == PSXDisplay.DisplayModeNew.y) && \r
- (PSXDisplay.DisplayMode.x == PSXDisplay.DisplayModeNew.x))\r
- {\r
- if((PSXDisplay.RGB24 == PSXDisplay.RGB24New) && \r
- (PSXDisplay.Interlaced == PSXDisplay.InterlacedNew)) \r
- return; // nothing has changed? fine, no swap buffer needed\r
- }\r
-else // some res change?\r
- {\r
- glLoadIdentity(); glError();\r
- glOrtho(0,PSXDisplay.DisplayModeNew.x, // -> new psx resolution\r
- PSXDisplay.DisplayModeNew.y, 0, -1, 1); glError();\r
- if(bKeepRatio) SetAspectRatio();\r
- }\r
-\r
-bDisplayNotSet = TRUE; // re-calc offsets/display area\r
-\r
-bUp=FALSE;\r
-if(PSXDisplay.RGB24!=PSXDisplay.RGB24New) // clean up textures, if rgb mode change (usually mdec on/off)\r
- {\r
- PreviousPSXDisplay.RGB24=0; // no full 24 frame uploaded yet\r
- ResetTextureArea(FALSE);\r
- bUp=TRUE;\r
- }\r
-\r
-PSXDisplay.RGB24 = PSXDisplay.RGB24New; // get new infos\r
-PSXDisplay.DisplayMode.y = PSXDisplay.DisplayModeNew.y;\r
-PSXDisplay.DisplayMode.x = PSXDisplay.DisplayModeNew.x;\r
-PSXDisplay.Interlaced = PSXDisplay.InterlacedNew;\r
- \r
-PSXDisplay.DisplayEnd.x= // calc new ends\r
- PSXDisplay.DisplayPosition.x+ PSXDisplay.DisplayMode.x;\r
-PSXDisplay.DisplayEnd.y=\r
- PSXDisplay.DisplayPosition.y+ PSXDisplay.DisplayMode.y+PreviousPSXDisplay.DisplayModeNew.y;\r
-PreviousPSXDisplay.DisplayEnd.x=\r
- PreviousPSXDisplay.DisplayPosition.x+ PSXDisplay.DisplayMode.x;\r
-PreviousPSXDisplay.DisplayEnd.y=\r
- PreviousPSXDisplay.DisplayPosition.y+ PSXDisplay.DisplayMode.y+PreviousPSXDisplay.DisplayModeNew.y;\r
-\r
-ChangeDispOffsetsX();\r
-\r
-if(iFrameLimit==2) SetAutoFrameCap(); // set new fps limit vals (depends on interlace)\r
-\r
-if(bUp) updateDisplay(); // yeah, real update (swap buffer)\r
-}\r
-\r
-////////////////////////////////////////////////////////////////////////\r
-// window mode <-> fullscreen mode (windows)\r
-////////////////////////////////////////////////////////////////////////\r
-\r
-\r
-////////////////////////////////////////////////////////////////////////\r
-// swap update check (called by psx vsync function)\r
-////////////////////////////////////////////////////////////////////////\r
-\r
-BOOL bSwapCheck(void)\r
-{\r
-static int iPosCheck=0;\r
-static PSXPoint_t pO;\r
-static PSXPoint_t pD;\r
-static int iDoAgain=0;\r
-\r
-if(PSXDisplay.DisplayPosition.x==pO.x &&\r
- PSXDisplay.DisplayPosition.y==pO.y &&\r
- PSXDisplay.DisplayEnd.x==pD.x &&\r
- PSXDisplay.DisplayEnd.y==pD.y)\r
- iPosCheck++;\r
-else iPosCheck=0;\r
-\r
-pO=PSXDisplay.DisplayPosition;\r
-pD=PSXDisplay.DisplayEnd;\r
-\r
-if(iPosCheck<=4) return FALSE;\r
-\r
-iPosCheck=4;\r
-\r
-if(PSXDisplay.Interlaced) return FALSE;\r
-\r
-if (bNeedInterlaceUpdate||\r
- bNeedRGB24Update ||\r
- bNeedUploadAfter|| \r
- bNeedUploadTest || \r
- iDoAgain\r
- )\r
- {\r
- iDoAgain=0;\r
- if(bNeedUploadAfter) \r
- iDoAgain=1;\r
- if(bNeedUploadTest && PSXDisplay.InterlacedTest)\r
- iDoAgain=1;\r
-\r
- bDisplayNotSet = TRUE;\r
- updateDisplay();\r
-\r
- PreviousPSXDisplay.DisplayPosition.x=PSXDisplay.DisplayPosition.x;\r
- PreviousPSXDisplay.DisplayPosition.y=PSXDisplay.DisplayPosition.y;\r
- PreviousPSXDisplay.DisplayEnd.x=PSXDisplay.DisplayEnd.x;\r
- PreviousPSXDisplay.DisplayEnd.y=PSXDisplay.DisplayEnd.y;\r
- pO=PSXDisplay.DisplayPosition;\r
- pD=PSXDisplay.DisplayEnd;\r
-\r
- return TRUE;\r
- }\r
-\r
-return FALSE;\r
-} \r
-////////////////////////////////////////////////////////////////////////\r
-// gun cursor func: player=0-7, x=0-511, y=0-255\r
-////////////////////////////////////////////////////////////////////////\r
-\r
-////////////////////////////////////////////////////////////////////////\r
-// update lace is called every VSync. Basically we limit frame rate \r
-// here, and in interlaced mode we swap ogl display buffers.\r
-////////////////////////////////////////////////////////////////////////\r
-\r
-static unsigned short usFirstPos=2;\r
-\r
-void CALLBACK GPUupdateLace(void)\r
-{\r
-if(!(dwActFixes&0x1000)) \r
- STATUSREG^=0x80000000; // interlaced bit toggle, if the CC game fix is not active (see gpuReadStatus)\r
-\r
-if(!(dwActFixes&128)) // normal frame limit func\r
- CheckFrameRate();\r
-\r
-if(iOffscreenDrawing==4) // special check if high offscreen drawing is on\r
- {\r
- if(bSwapCheck()) return;\r
- }\r
-\r
-if(PSXDisplay.Interlaced) // interlaced mode?\r
- {\r
- if(PSXDisplay.DisplayMode.x>0 && PSXDisplay.DisplayMode.y>0)\r
- {\r
- updateDisplay(); // -> swap buffers (new frame)\r
- }\r
- }\r
-else if(bRenderFrontBuffer) // no interlace mode? and some stuff in front has changed?\r
- {\r
- updateFrontDisplay(); // -> update front buffer\r
- }\r
-else if(usFirstPos==1) // initial updates (after startup)\r
- {\r
- updateDisplay();\r
- }\r
-\r
-}\r
-\r
-////////////////////////////////////////////////////////////////////////\r
-// process read request from GPU status register\r
-////////////////////////////////////////////////////////////////////////\r
-\r
-unsigned long CALLBACK GPUreadStatus(void)\r
-{\r
-if(dwActFixes&0x1000) // CC game fix\r
- {\r
- static int iNumRead=0;\r
- if((iNumRead++)==2)\r
- {\r
- iNumRead=0;\r
- STATUSREG^=0x80000000; // interlaced bit toggle... we do it on every second read status... needed by some games (like ChronoCross)\r
- }\r
- }\r
-\r
-if(iFakePrimBusy) // 27.10.2007 - emulating some 'busy' while drawing... pfff... not perfect, but since our emulated dma is not done in an extra thread...\r
- {\r
- iFakePrimBusy--;\r
-\r
- if(iFakePrimBusy&1) // we do a busy-idle-busy-idle sequence after/while drawing prims\r
- {\r
- GPUIsBusy;\r
- GPUIsNotReadyForCommands;\r
- }\r
- else\r
- {\r
- GPUIsIdle;\r
- GPUIsReadyForCommands;\r
- }\r
- }\r
-\r
-return STATUSREG;\r
-}\r
-\r
-////////////////////////////////////////////////////////////////////////\r
-// processes data send to GPU status register\r
-// these are always single packet commands.\r
-////////////////////////////////////////////////////////////////////////\r
-\r
-void CALLBACK GPUwriteStatus(unsigned long gdata)\r
-{\r
-unsigned long lCommand=(gdata>>24)&0xff;\r
-\r
-if(bIsFirstFrame) GLinitialize(NULL, NULL); // real ogl startup (needed by some emus)\r
-\r
-ulStatusControl[lCommand]=gdata;\r
-\r
-switch(lCommand)\r
- {\r
- //--------------------------------------------------//\r
- // reset gpu\r
- case 0x00:\r
- memset(ulGPUInfoVals,0x00,16*sizeof(unsigned long));\r
- lGPUstatusRet=0x14802000;\r
- PSXDisplay.Disabled=1;\r
- iDataWriteMode=iDataReadMode=DR_NORMAL;\r
- PSXDisplay.DrawOffset.x=PSXDisplay.DrawOffset.y=0;\r
- drawX=drawY=0;drawW=drawH=0;\r
- sSetMask=0;lSetMask=0;bCheckMask=FALSE;iSetMask=0;\r
- usMirror=0;\r
- GlobalTextAddrX=0;GlobalTextAddrY=0;\r
- GlobalTextTP=0;GlobalTextABR=0;\r
- PSXDisplay.RGB24=FALSE;\r
- PSXDisplay.Interlaced=FALSE;\r
- bUsingTWin = FALSE;\r
- return;\r
-\r
- // dis/enable display\r
- case 0x03: \r
- PreviousPSXDisplay.Disabled = PSXDisplay.Disabled;\r
- PSXDisplay.Disabled = (gdata & 1);\r
-\r
- if(PSXDisplay.Disabled) \r
- STATUSREG|=GPUSTATUS_DISPLAYDISABLED;\r
- else STATUSREG&=~GPUSTATUS_DISPLAYDISABLED;\r
-\r
- if (iOffscreenDrawing==4 &&\r
- PreviousPSXDisplay.Disabled && \r
- !(PSXDisplay.Disabled))\r
- {\r
-\r
- if(!PSXDisplay.RGB24)\r
- {\r
- PrepareFullScreenUpload(TRUE);\r
- UploadScreen(TRUE); \r
- updateDisplay();\r
- }\r
- }\r
-\r
- return;\r
-\r
- // setting transfer mode\r
- case 0x04:\r
- gdata &= 0x03; // only want the lower two bits\r
-\r
- iDataWriteMode=iDataReadMode=DR_NORMAL;\r
- if(gdata==0x02) iDataWriteMode=DR_VRAMTRANSFER;\r
- if(gdata==0x03) iDataReadMode =DR_VRAMTRANSFER;\r
-\r
- STATUSREG&=~GPUSTATUS_DMABITS; // clear the current settings of the DMA bits\r
- STATUSREG|=(gdata << 29); // set the DMA bits according to the received data\r
-\r
- return;\r
-\r
- // setting display position\r
- case 0x05: \r
- {\r
- short sx=(short)(gdata & 0x3ff);\r
- short sy;\r
-\r
- if(iGPUHeight==1024)\r
- {\r
- if(dwGPUVersion==2) \r
- sy = (short)((gdata>>12)&0x3ff);\r
- else sy = (short)((gdata>>10)&0x3ff);\r
- }\r
- else sy = (short)((gdata>>10)&0x3ff); // really: 0x1ff, but we adjust it later\r
-\r
- if (sy & 0x200) \r
- {\r
- sy|=0xfc00;\r
- PreviousPSXDisplay.DisplayModeNew.y=sy/PSXDisplay.Double;\r
- sy=0;\r
- }\r
- else PreviousPSXDisplay.DisplayModeNew.y=0;\r
-\r
- if(sx>1000) sx=0;\r
-\r
- if(usFirstPos)\r
- {\r
- usFirstPos--;\r
- if(usFirstPos)\r
- {\r
- PreviousPSXDisplay.DisplayPosition.x = sx;\r
- PreviousPSXDisplay.DisplayPosition.y = sy;\r
- PSXDisplay.DisplayPosition.x = sx;\r
- PSXDisplay.DisplayPosition.y = sy;\r
- }\r
- }\r
-\r
- if(dwActFixes&8) \r
- {\r
- if((!PSXDisplay.Interlaced) &&\r
- PreviousPSXDisplay.DisplayPosition.x == sx &&\r
- PreviousPSXDisplay.DisplayPosition.y == sy)\r
- return;\r
-\r
- PSXDisplay.DisplayPosition.x = PreviousPSXDisplay.DisplayPosition.x;\r
- PSXDisplay.DisplayPosition.y = PreviousPSXDisplay.DisplayPosition.y;\r
- PreviousPSXDisplay.DisplayPosition.x = sx;\r
- PreviousPSXDisplay.DisplayPosition.y = sy;\r
- }\r
- else\r
- {\r
- if((!PSXDisplay.Interlaced) &&\r
- PSXDisplay.DisplayPosition.x == sx &&\r
- PSXDisplay.DisplayPosition.y == sy)\r
- return;\r
- PreviousPSXDisplay.DisplayPosition.x = PSXDisplay.DisplayPosition.x;\r
- PreviousPSXDisplay.DisplayPosition.y = PSXDisplay.DisplayPosition.y;\r
- PSXDisplay.DisplayPosition.x = sx;\r
- PSXDisplay.DisplayPosition.y = sy;\r
- }\r
-\r
- PSXDisplay.DisplayEnd.x=\r
- PSXDisplay.DisplayPosition.x+ PSXDisplay.DisplayMode.x;\r
- PSXDisplay.DisplayEnd.y=\r
- PSXDisplay.DisplayPosition.y+ PSXDisplay.DisplayMode.y+PreviousPSXDisplay.DisplayModeNew.y;\r
-\r
- PreviousPSXDisplay.DisplayEnd.x=\r
- PreviousPSXDisplay.DisplayPosition.x+ PSXDisplay.DisplayMode.x;\r
- PreviousPSXDisplay.DisplayEnd.y=\r
- PreviousPSXDisplay.DisplayPosition.y+ PSXDisplay.DisplayMode.y+PreviousPSXDisplay.DisplayModeNew.y;\r
-\r
- bDisplayNotSet = TRUE;\r
-\r
- if (!(PSXDisplay.Interlaced))\r
- {\r
- updateDisplay();\r
- }\r
- else\r
- if(PSXDisplay.InterlacedTest && \r
- ((PreviousPSXDisplay.DisplayPosition.x != PSXDisplay.DisplayPosition.x)||\r
- (PreviousPSXDisplay.DisplayPosition.y != PSXDisplay.DisplayPosition.y)))\r
- PSXDisplay.InterlacedTest--;\r
-\r
- return;\r
- }\r
-\r
- // setting width\r
- case 0x06:\r
-\r
- PSXDisplay.Range.x0=gdata & 0x7ff; //0x3ff;\r
- PSXDisplay.Range.x1=(gdata>>12) & 0xfff;//0x7ff;\r
-\r
- PSXDisplay.Range.x1-=PSXDisplay.Range.x0;\r
-\r
- ChangeDispOffsetsX();\r
-\r
- return;\r
-\r
- // setting height\r
- case 0x07:\r
-\r
- PreviousPSXDisplay.Height = PSXDisplay.Height;\r
-\r
- PSXDisplay.Range.y0=gdata & 0x3ff;\r
- PSXDisplay.Range.y1=(gdata>>10) & 0x3ff;\r
-\r
- PSXDisplay.Height = PSXDisplay.Range.y1 - \r
- PSXDisplay.Range.y0 +\r
- PreviousPSXDisplay.DisplayModeNew.y;\r
-\r
- if (PreviousPSXDisplay.Height != PSXDisplay.Height)\r
- {\r
- PSXDisplay.DisplayModeNew.y=PSXDisplay.Height*PSXDisplay.Double;\r
- ChangeDispOffsetsY();\r
- updateDisplayIfChanged();\r
- }\r
- return;\r
-\r
- // setting display infos\r
- case 0x08:\r
-\r
- PSXDisplay.DisplayModeNew.x = dispWidths[(gdata & 0x03) | ((gdata & 0x40) >> 4)];\r
-\r
- if (gdata&0x04) PSXDisplay.Double=2;\r
- else PSXDisplay.Double=1;\r
- PSXDisplay.DisplayModeNew.y = PSXDisplay.Height*PSXDisplay.Double;\r
-\r
- ChangeDispOffsetsY();\r
- \r
- PSXDisplay.PAL = (gdata & 0x08)?TRUE:FALSE; // if 1 - PAL mode, else NTSC\r
- PSXDisplay.RGB24New = (gdata & 0x10)?TRUE:FALSE; // if 1 - TrueColor\r
- PSXDisplay.InterlacedNew = (gdata & 0x20)?TRUE:FALSE; // if 1 - Interlace\r
-\r
- STATUSREG&=~GPUSTATUS_WIDTHBITS; // clear the width bits\r
-\r
- STATUSREG|=\r
- (((gdata & 0x03) << 17) | \r
- ((gdata & 0x40) << 10)); // set the width bits\r
-\r
- PreviousPSXDisplay.InterlacedNew=FALSE;\r
- if (PSXDisplay.InterlacedNew)\r
- {\r
- if(!PSXDisplay.Interlaced)\r
- {\r
- PSXDisplay.InterlacedTest=2;\r
- PreviousPSXDisplay.DisplayPosition.x = PSXDisplay.DisplayPosition.x;\r
- PreviousPSXDisplay.DisplayPosition.y = PSXDisplay.DisplayPosition.y;\r
- PreviousPSXDisplay.InterlacedNew=TRUE;\r
- }\r
-\r
- STATUSREG|=GPUSTATUS_INTERLACED;\r
- }\r
- else \r
- {\r
- PSXDisplay.InterlacedTest=0;\r
- STATUSREG&=~GPUSTATUS_INTERLACED;\r
- }\r
-\r
- if (PSXDisplay.PAL)\r
- STATUSREG|=GPUSTATUS_PAL;\r
- else STATUSREG&=~GPUSTATUS_PAL;\r
-\r
- if (PSXDisplay.Double==2)\r
- STATUSREG|=GPUSTATUS_DOUBLEHEIGHT;\r
- else STATUSREG&=~GPUSTATUS_DOUBLEHEIGHT;\r
-\r
- if (PSXDisplay.RGB24New)\r
- STATUSREG|=GPUSTATUS_RGB24;\r
- else STATUSREG&=~GPUSTATUS_RGB24;\r
-\r
- updateDisplayIfChanged();\r
-\r
- return;\r
-\r
- //--------------------------------------------------//\r
- // ask about GPU version and other stuff\r
- case 0x10: \r
-\r
- gdata&=0xff;\r
-\r
- switch(gdata) \r
- {\r
- case 0x02:\r
- GPUdataRet=ulGPUInfoVals[INFO_TW]; // tw infos\r
- return;\r
- case 0x03:\r
- GPUdataRet=ulGPUInfoVals[INFO_DRAWSTART]; // draw start\r
- return;\r
- case 0x04:\r
- GPUdataRet=ulGPUInfoVals[INFO_DRAWEND]; // draw end\r
- return;\r
- case 0x05:\r
- case 0x06:\r
- GPUdataRet=ulGPUInfoVals[INFO_DRAWOFF]; // draw offset\r
- return;\r
- case 0x07:\r
- if(dwGPUVersion==2)\r
- GPUdataRet=0x01;\r
- else GPUdataRet=0x02; // gpu type\r
- return;\r
- case 0x08:\r
- case 0x0F: // some bios addr?\r
- GPUdataRet=0xBFC03720;\r
- return;\r
- }\r
- return;\r
- //--------------------------------------------------//\r
- }\r
-}\r
-\r
-////////////////////////////////////////////////////////////////////////\r
-// vram read/write helpers\r
-////////////////////////////////////////////////////////////////////////\r
-\r
-BOOL bNeedWriteUpload=FALSE;\r
-\r
-__inline void FinishedVRAMWrite(void)\r
-{\r
- if(bNeedWriteUpload)\r
- {\r
- bNeedWriteUpload=FALSE;\r
- CheckWriteUpdate();\r
- }\r
-\r
- // set register to NORMAL operation\r
- iDataWriteMode = DR_NORMAL;\r
-\r
- // reset transfer values, to prevent mis-transfer of data\r
- VRAMWrite.ColsRemaining = 0;\r
- VRAMWrite.RowsRemaining = 0;\r
-}\r
-\r
-__inline void FinishedVRAMRead(void)\r
-{\r
- // set register to NORMAL operation\r
- iDataReadMode = DR_NORMAL;\r
- // reset transfer values, to prevent mis-transfer of data\r
- VRAMRead.x = 0;\r
- VRAMRead.y = 0;\r
- VRAMRead.Width = 0;\r
- VRAMRead.Height = 0;\r
- VRAMRead.ColsRemaining = 0;\r
- VRAMRead.RowsRemaining = 0;\r
-\r
- // indicate GPU is no longer ready for VRAM data in the STATUS REGISTER\r
- STATUSREG&=~GPUSTATUS_READYFORVRAM;\r
-}\r
-\r
-////////////////////////////////////////////////////////////////////////\r
-// vram read check ex (reading from card's back/frontbuffer if needed...\r
-// slow!)\r
-////////////////////////////////////////////////////////////////////////\r
-\r
-void CheckVRamReadEx(int x, int y, int dx, int dy)\r
-{\r
- unsigned short sArea;\r
- int ux,uy,udx,udy,wx,wy;\r
- unsigned short * p1, *p2;\r
- float XS,YS;\r
- unsigned char * ps;\r
- unsigned char * px;\r
- unsigned short s,sx;\r
-\r
- if(STATUSREG&GPUSTATUS_RGB24) return;\r
-\r
- if(((dx > PSXDisplay.DisplayPosition.x) &&\r
- (x < PSXDisplay.DisplayEnd.x) &&\r
- (dy > PSXDisplay.DisplayPosition.y) &&\r
- (y < PSXDisplay.DisplayEnd.y)))\r
- sArea=0;\r
- else\r
- if((!(PSXDisplay.InterlacedTest) &&\r
- (dx > PreviousPSXDisplay.DisplayPosition.x) &&\r
- (x < PreviousPSXDisplay.DisplayEnd.x) &&\r
- (dy > PreviousPSXDisplay.DisplayPosition.y) &&\r
- (y < PreviousPSXDisplay.DisplayEnd.y)))\r
- sArea=1;\r
- else \r
- {\r
- return;\r
- }\r
-\r
- //////////////\r
-\r
- if(iRenderFVR)\r
- {\r
- bFullVRam=TRUE;iRenderFVR=2;return;\r
- }\r
- bFullVRam=TRUE;iRenderFVR=2;\r
-\r
- //////////////\r
-\r
- p2=0;\r
-\r
- if(sArea==0)\r
- {\r
- ux=PSXDisplay.DisplayPosition.x;\r
- uy=PSXDisplay.DisplayPosition.y;\r
- udx=PSXDisplay.DisplayEnd.x-ux;\r
- udy=PSXDisplay.DisplayEnd.y-uy;\r
- if((PreviousPSXDisplay.DisplayEnd.x-\r
- PreviousPSXDisplay.DisplayPosition.x)==udx &&\r
- (PreviousPSXDisplay.DisplayEnd.y-\r
- PreviousPSXDisplay.DisplayPosition.y)==udy)\r
- p2=(psxVuw + (1024*PreviousPSXDisplay.DisplayPosition.y) + \r
- PreviousPSXDisplay.DisplayPosition.x);\r
- }\r
- else\r
- {\r
- ux=PreviousPSXDisplay.DisplayPosition.x;\r
- uy=PreviousPSXDisplay.DisplayPosition.y;\r
- udx=PreviousPSXDisplay.DisplayEnd.x-ux;\r
- udy=PreviousPSXDisplay.DisplayEnd.y-uy;\r
- if((PSXDisplay.DisplayEnd.x-\r
- PSXDisplay.DisplayPosition.x)==udx &&\r
- (PSXDisplay.DisplayEnd.y-\r
- PSXDisplay.DisplayPosition.y)==udy)\r
- p2=(psxVuw + (1024*PSXDisplay.DisplayPosition.y) + \r
- PSXDisplay.DisplayPosition.x);\r
- }\r
-\r
- p1=(psxVuw + (1024*uy) + ux);\r
- if(p1==p2) p2=0;\r
-\r
- x=0;y=0;\r
- wx=dx=udx;wy=dy=udy;\r
-\r
- if(udx<=0) return;\r
- if(udy<=0) return;\r
- if(dx<=0) return;\r
- if(dy<=0) return;\r
- if(wx<=0) return;\r
- if(wy<=0) return;\r
-\r
- XS=(float)rRatioRect.right/(float)wx;\r
- YS=(float)rRatioRect.bottom/(float)wy;\r
-\r
- dx=(int)((float)(dx)*XS);\r
- dy=(int)((float)(dy)*YS);\r
-\r
- if(dx>iResX) dx=iResX;\r
- if(dy>iResY) dy=iResY;\r
-\r
- if(dx<=0) return;\r
- if(dy<=0) return;\r
-\r
- // ogl y adjust\r
- y=iResY-y-dy;\r
-\r
- x+=rRatioRect.left;\r
- y-=rRatioRect.top;\r
-\r
- if(y<0) y=0; if((y+dy)>iResY) dy=iResY-y;\r
-\r
- if(!pGfxCardScreen)\r
- {\r
- glPixelStorei(GL_PACK_ALIGNMENT,1); glError();\r
- pGfxCardScreen=(unsigned char *)malloc(iResX*iResY*4);\r
- }\r
-\r
- ps=pGfxCardScreen;\r
- \r
- //if(!sArea) glReadBuffer(GL_FRONT);\r
-\r
- glReadPixels(x,y,dx,dy,GL_RGB,GL_UNSIGNED_BYTE,ps); glError();\r
- //if(!sArea) glReadBuffer(GL_BACK);\r
-\r
- s=0;\r
-\r
- XS=(float)dx/(float)(udx);\r
- YS=(float)dy/(float)(udy+1);\r
- \r
- for(y=udy;y>0;y--)\r
- {\r
- for(x=0;x<udx;x++)\r
- {\r
- if(p1>=psxVuw && p1<psxVuw_eom)\r
- {\r
- px=ps+(3*((int)((float)x * XS))+\r
- (3*dx)*((int)((float)y*YS)));\r
- sx=(*px)>>3;px++;\r
- s=sx;\r
- sx=(*px)>>3;px++;\r
- s|=sx<<5;\r
- sx=(*px)>>3;\r
- s|=sx<<10;\r
- s&=~0x8000;\r
- *p1=s;\r
- }\r
- if(p2>=psxVuw && p2<psxVuw_eom) *p2=s;\r
-\r
- p1++;\r
- if(p2) p2++;\r
- }\r
-\r
- p1 += 1024 - udx;\r
- if(p2) p2 += 1024 - udx;\r
- }\r
-}\r
-\r
-////////////////////////////////////////////////////////////////////////\r
-// vram read check (reading from card's back/frontbuffer if needed... \r
-// slow!)\r
-////////////////////////////////////////////////////////////////////////\r
-\r
-void CheckVRamRead(int x, int y, int dx, int dy, bool bFront)\r
-{\r
- unsigned short sArea;unsigned short * p;\r
- int ux,uy,udx,udy,wx,wy;float XS,YS;\r
- unsigned char * ps, * px;\r
- unsigned short s=0,sx;\r
-\r
- if(STATUSREG&GPUSTATUS_RGB24) return;\r
-\r
- if(((dx > PSXDisplay.DisplayPosition.x) &&\r
- (x < PSXDisplay.DisplayEnd.x) &&\r
- (dy > PSXDisplay.DisplayPosition.y) &&\r
- (y < PSXDisplay.DisplayEnd.y)))\r
- sArea=0;\r
- else\r
- if((!(PSXDisplay.InterlacedTest) &&\r
- (dx > PreviousPSXDisplay.DisplayPosition.x) &&\r
- (x < PreviousPSXDisplay.DisplayEnd.x) &&\r
- (dy > PreviousPSXDisplay.DisplayPosition.y) &&\r
- (y < PreviousPSXDisplay.DisplayEnd.y)))\r
- sArea=1;\r
- else \r
- {\r
- return;\r
- }\r
-\r
- if(dwActFixes&0x40)\r
- {\r
- if(iRenderFVR)\r
- {\r
- bFullVRam=TRUE;iRenderFVR=2;return;\r
- }\r
- bFullVRam=TRUE;iRenderFVR=2;\r
- }\r
-\r
- ux=x;uy=y;udx=dx;udy=dy;\r
-\r
- if(sArea==0)\r
- {\r
- x -=PSXDisplay.DisplayPosition.x;\r
- dx-=PSXDisplay.DisplayPosition.x;\r
- y -=PSXDisplay.DisplayPosition.y;\r
- dy-=PSXDisplay.DisplayPosition.y;\r
- wx=PSXDisplay.DisplayEnd.x-PSXDisplay.DisplayPosition.x;\r
- wy=PSXDisplay.DisplayEnd.y-PSXDisplay.DisplayPosition.y;\r
- }\r
- else\r
- {\r
- x -=PreviousPSXDisplay.DisplayPosition.x;\r
- dx-=PreviousPSXDisplay.DisplayPosition.x;\r
- y -=PreviousPSXDisplay.DisplayPosition.y;\r
- dy-=PreviousPSXDisplay.DisplayPosition.y;\r
- wx=PreviousPSXDisplay.DisplayEnd.x-PreviousPSXDisplay.DisplayPosition.x;\r
- wy=PreviousPSXDisplay.DisplayEnd.y-PreviousPSXDisplay.DisplayPosition.y;\r
- }\r
- if(x<0) {ux-=x;x=0;}\r
- if(y<0) {uy-=y;y=0;}\r
- if(dx>wx) {udx-=(dx-wx);dx=wx;}\r
- if(dy>wy) {udy-=(dy-wy);dy=wy;}\r
- udx-=ux;\r
- udy-=uy;\r
- \r
- p=(psxVuw + (1024*uy) + ux);\r
-\r
- if(udx<=0) return;\r
- if(udy<=0) return;\r
- if(dx<=0) return;\r
- if(dy<=0) return;\r
- if(wx<=0) return;\r
- if(wy<=0) return;\r
-\r
- XS=(float)rRatioRect.right/(float)wx;\r
- YS=(float)rRatioRect.bottom/(float)wy;\r
-\r
- dx=(int)((float)(dx)*XS);\r
- dy=(int)((float)(dy)*YS);\r
- x=(int)((float)x*XS);\r
- y=(int)((float)y*YS);\r
-\r
- dx-=x;\r
- dy-=y;\r
-\r
- if(dx>iResX) dx=iResX;\r
- if(dy>iResY) dy=iResY;\r
-\r
- if(dx<=0) return;\r
- if(dy<=0) return;\r
-\r
- // ogl y adjust\r
- y=iResY-y-dy;\r
-\r
- x+=rRatioRect.left;\r
- y-=rRatioRect.top;\r
-\r
- if(y<0) y=0; if((y+dy)>iResY) dy=iResY-y;\r
-\r
- if(!pGfxCardScreen)\r
- {\r
- glPixelStorei(GL_PACK_ALIGNMENT,1); glError();\r
- pGfxCardScreen=(unsigned char *)malloc(iResX*iResY*4);\r
- }\r
-\r
- ps=pGfxCardScreen;\r
- \r
-// if(bFront) glReadBuffer(GL_FRONT);\r
-\r
- glReadPixels(x,y,dx,dy,GL_RGB,GL_UNSIGNED_BYTE,ps); glError(); glError();\r
-// if(bFront) glReadBuffer(GL_BACK);\r
-\r
- XS=(float)dx/(float)(udx);\r
- YS=(float)dy/(float)(udy+1);\r
- \r
- for(y=udy;y>0;y--)\r
- {\r
- for(x=0;x<udx;x++)\r
- {\r
- if(p>=psxVuw && p<psxVuw_eom)\r
- {\r
- px=ps+(3*((int)((float)x * XS))+\r
- (3*dx)*((int)((float)y*YS)));\r
- sx=(*px)>>3;px++;\r
- s=sx;\r
- sx=(*px)>>3;px++;\r
- s|=sx<<5;\r
- sx=(*px)>>3;\r
- s|=sx<<10;\r
- s&=~0x8000;\r
- *p=s;\r
- }\r
- p++;\r
- }\r
- p += 1024 - udx;\r
- }\r
-}\r
-\r
-////////////////////////////////////////////////////////////////////////\r
-// core read from vram\r
-////////////////////////////////////////////////////////////////////////\r
-\r
-void CALLBACK GPUreadDataMem(unsigned long * pMem, int iSize)\r
-{\r
-int i;\r
-\r
-if(iDataReadMode!=DR_VRAMTRANSFER) return;\r
-\r
-GPUIsBusy;\r
-\r
-// adjust read ptr, if necessary\r
-while(VRAMRead.ImagePtr>=psxVuw_eom)\r
- VRAMRead.ImagePtr-=iGPUHeight*1024;\r
-while(VRAMRead.ImagePtr<psxVuw)\r
- VRAMRead.ImagePtr+=iGPUHeight*1024;\r
-\r
-if((iFrameReadType&1 && iSize>1) &&\r
- !(iDrawnSomething==2 &&\r
- VRAMRead.x == VRAMWrite.x &&\r
- VRAMRead.y == VRAMWrite.y &&\r
- VRAMRead.Width == VRAMWrite.Width &&\r
- VRAMRead.Height == VRAMWrite.Height))\r
- CheckVRamRead(VRAMRead.x,VRAMRead.y,\r
- VRAMRead.x+VRAMRead.RowsRemaining,\r
- VRAMRead.y+VRAMRead.ColsRemaining,\r
- TRUE);\r
-\r
-for(i=0;i<iSize;i++)\r
- {\r
- // do 2 seperate 16bit reads for compatibility (wrap issues)\r
- if ((VRAMRead.ColsRemaining > 0) && (VRAMRead.RowsRemaining > 0))\r
- {\r
- // lower 16 bit\r
- GPUdataRet=(unsigned long)*VRAMRead.ImagePtr;\r
-\r
- VRAMRead.ImagePtr++;\r
- if(VRAMRead.ImagePtr>=psxVuw_eom) VRAMRead.ImagePtr-=iGPUHeight*1024;\r
- VRAMRead.RowsRemaining --;\r
-\r
- if(VRAMRead.RowsRemaining<=0)\r
- {\r
- VRAMRead.RowsRemaining = VRAMRead.Width;\r
- VRAMRead.ColsRemaining--;\r
- VRAMRead.ImagePtr += 1024 - VRAMRead.Width;\r
- if(VRAMRead.ImagePtr>=psxVuw_eom) VRAMRead.ImagePtr-=iGPUHeight*1024;\r
- }\r
-\r
- // higher 16 bit (always, even if it's an odd width)\r
- GPUdataRet|=(unsigned long)(*VRAMRead.ImagePtr)<<16;\r
- *pMem++=GPUdataRet;\r
-\r
- if(VRAMRead.ColsRemaining <= 0)\r
- {FinishedVRAMRead();goto ENDREAD;}\r
-\r
- VRAMRead.ImagePtr++;\r
- if(VRAMRead.ImagePtr>=psxVuw_eom) VRAMRead.ImagePtr-=iGPUHeight*1024;\r
- VRAMRead.RowsRemaining--;\r
- if(VRAMRead.RowsRemaining<=0)\r
- {\r
- VRAMRead.RowsRemaining = VRAMRead.Width;\r
- VRAMRead.ColsRemaining--;\r
- VRAMRead.ImagePtr += 1024 - VRAMRead.Width;\r
- if(VRAMRead.ImagePtr>=psxVuw_eom) VRAMRead.ImagePtr-=iGPUHeight*1024;\r
- }\r
- if(VRAMRead.ColsRemaining <= 0)\r
- {FinishedVRAMRead();goto ENDREAD;}\r
- }\r
- else {FinishedVRAMRead();goto ENDREAD;}\r
- }\r
-\r
-ENDREAD:\r
-GPUIsIdle;\r
-}\r
-\r
-unsigned long CALLBACK GPUreadData(void)\r
-{\r
- unsigned long l;\r
- GPUreadDataMem(&l,1);\r
- return GPUdataRet;\r
-}\r
-\r
-////////////////////////////////////////////////////////////////////////\r
-// helper table to know how much data is used by drawing commands\r
-////////////////////////////////////////////////////////////////////////\r
-\r
-const unsigned char primTableCX[256] =\r
-{\r
- // 00\r
- 0,0,3,0,0,0,0,0,\r
- // 08\r
- 0,0,0,0,0,0,0,0,\r
- // 10\r
- 0,0,0,0,0,0,0,0,\r
- // 18\r
- 0,0,0,0,0,0,0,0,\r
- // 20\r
- 4,4,4,4,7,7,7,7,\r
- // 28\r
- 5,5,5,5,9,9,9,9,\r
- // 30\r
- 6,6,6,6,9,9,9,9,\r
- // 38\r
- 8,8,8,8,12,12,12,12,\r
- // 40\r
- 3,3,3,3,0,0,0,0,\r
- // 48\r
-// 5,5,5,5,6,6,6,6, //FLINE\r
- 254,254,254,254,254,254,254,254,\r
- // 50\r
- 4,4,4,4,0,0,0,0,\r
- // 58\r
-// 7,7,7,7,9,9,9,9, // LINEG3 LINEG4\r
- 255,255,255,255,255,255,255,255,\r
- // 60\r
- 3,3,3,3,4,4,4,4, // TILE SPRT\r
- // 68\r
- 2,2,2,2,3,3,3,3, // TILE1\r
- // 70\r
- 2,2,2,2,3,3,3,3,\r
- // 78\r
- 2,2,2,2,3,3,3,3,\r
- // 80\r
- 4,0,0,0,0,0,0,0,\r
- // 88\r
- 0,0,0,0,0,0,0,0,\r
- // 90\r
- 0,0,0,0,0,0,0,0,\r
- // 98\r
- 0,0,0,0,0,0,0,0,\r
- // a0\r
- 3,0,0,0,0,0,0,0,\r
- // a8\r
- 0,0,0,0,0,0,0,0,\r
- // b0\r
- 0,0,0,0,0,0,0,0,\r
- // b8\r
- 0,0,0,0,0,0,0,0,\r
- // c0\r
- 3,0,0,0,0,0,0,0,\r
- // c8\r
- 0,0,0,0,0,0,0,0,\r
- // d0\r
- 0,0,0,0,0,0,0,0,\r
- // d8\r
- 0,0,0,0,0,0,0,0,\r
- // e0\r
- 0,1,1,1,1,1,1,0,\r
- // e8\r
- 0,0,0,0,0,0,0,0,\r
- // f0\r
- 0,0,0,0,0,0,0,0,\r
- // f8\r
- 0,0,0,0,0,0,0,0\r
-};\r
-\r
-////////////////////////////////////////////////////////////////////////\r
-// processes data send to GPU data register\r
-////////////////////////////////////////////////////////////////////////\r
-\r
-void CALLBACK GPUwriteDataMem(unsigned long * pMem, int iSize)\r
-{\r
-unsigned char command;\r
-unsigned long gdata=0;\r
-int i=0;\r
-GPUIsBusy;\r
-GPUIsNotReadyForCommands;\r
-\r
-STARTVRAM:\r
-\r
-if(iDataWriteMode==DR_VRAMTRANSFER)\r
- {\r
- // make sure we are in vram\r
- while(VRAMWrite.ImagePtr>=psxVuw_eom)\r
- VRAMWrite.ImagePtr-=iGPUHeight*1024;\r
- while(VRAMWrite.ImagePtr<psxVuw)\r
- VRAMWrite.ImagePtr+=iGPUHeight*1024;\r
-\r
- // now do the loop\r
- while(VRAMWrite.ColsRemaining>0)\r
- {\r
- while(VRAMWrite.RowsRemaining>0)\r
- {\r
- if(i>=iSize) {goto ENDVRAM;}\r
- i++;\r
-\r
- gdata=*pMem++;\r
-\r
- *VRAMWrite.ImagePtr++ = (unsigned short)gdata;\r
- if(VRAMWrite.ImagePtr>=psxVuw_eom) VRAMWrite.ImagePtr-=iGPUHeight*1024;\r
- VRAMWrite.RowsRemaining --;\r
-\r
- if(VRAMWrite.RowsRemaining <= 0)\r
- {\r
- VRAMWrite.ColsRemaining--;\r
- if (VRAMWrite.ColsRemaining <= 0) // last pixel is odd width\r
- {\r
- gdata=(gdata&0xFFFF)|(((unsigned long)(*VRAMWrite.ImagePtr))<<16);\r
- FinishedVRAMWrite();\r
- goto ENDVRAM;\r
- }\r
- VRAMWrite.RowsRemaining = VRAMWrite.Width;\r
- VRAMWrite.ImagePtr += 1024 - VRAMWrite.Width;\r
- }\r
-\r
- *VRAMWrite.ImagePtr++ = (unsigned short)(gdata>>16);\r
- if(VRAMWrite.ImagePtr>=psxVuw_eom) VRAMWrite.ImagePtr-=iGPUHeight*1024;\r
- VRAMWrite.RowsRemaining --;\r
- }\r
-\r
- VRAMWrite.RowsRemaining = VRAMWrite.Width;\r
- VRAMWrite.ColsRemaining--;\r
- VRAMWrite.ImagePtr += 1024 - VRAMWrite.Width;\r
- }\r
-\r
- FinishedVRAMWrite();\r
- }\r
-\r
-ENDVRAM:\r
-\r
-if(iDataWriteMode==DR_NORMAL)\r
- {\r
- void (* *primFunc)(unsigned char *);\r
- if(bSkipNextFrame) primFunc=primTableSkip;\r
- else primFunc=primTableJ;\r
-\r
- for(;i<iSize;)\r
- {\r
- if(iDataWriteMode==DR_VRAMTRANSFER) goto STARTVRAM;\r
-\r
- gdata=*pMem++;i++;\r
-\r
- if(gpuDataC == 0)\r
- {\r
- command = (unsigned char)((gdata>>24) & 0xff);\r
-\r
- if(primTableCX[command])\r
- {\r
- gpuDataC = primTableCX[command];\r
- gpuCommand = command;\r
- gpuDataM[0] = gdata;\r
- gpuDataP = 1;\r
- }\r
- else continue;\r
- }\r
- else\r
- {\r
- gpuDataM[gpuDataP] = gdata;\r
- if(gpuDataC>128)\r
- {\r
- if((gpuDataC==254 && gpuDataP>=3) ||\r
- (gpuDataC==255 && gpuDataP>=4 && !(gpuDataP&1)))\r
- {\r
- if((gpuDataM[gpuDataP] & 0xF000F000) == 0x50005000)\r
- gpuDataP=gpuDataC-1;\r
- }\r
- }\r
- gpuDataP++;\r
- }\r
-\r
- if(gpuDataP == gpuDataC)\r
- {\r
- gpuDataC=gpuDataP=0;\r
- primFunc[gpuCommand]((unsigned char *)gpuDataM);\r
-\r
- if(dwEmuFixes&0x0001 || dwActFixes&0x20000) // hack for emulating "gpu busy" in some games\r
- iFakePrimBusy=4;\r
- }\r
- } \r
- }\r
-\r
-GPUdataRet=gdata;\r
-\r
-GPUIsReadyForCommands;\r
-GPUIsIdle; \r
-}\r
-\r
-////////////////////////////////////////////////////////////////////////\r
-\r
-void CALLBACK GPUwriteData(unsigned long gdata)\r
-{\r
- GPUwriteDataMem(&gdata,1);\r
-}\r
-\r
-////////////////////////////////////////////////////////////////////////\r
-// this function will be removed soon (or 'soonish') (or never)\r
-////////////////////////////////////////////////////////////////////////\r
-\r
-void CALLBACK GPUsetMode(unsigned int gdata)\r
-{\r
- // ignore old psemu setmode:\r
-\r
- // imageTransfer = gdata;\r
- // iDataWriteMode=(gdata&1)?DR_VRAMTRANSFER:DR_NORMAL;\r
- // iDataReadMode =(gdata&2)?DR_VRAMTRANSFER:DR_NORMAL;\r
-}\r
-\r
-// and this function will be removed soon as well, hehehe...\r
-long CALLBACK GPUgetMode(void)\r
-{\r
- // ignore old psemu setmode\r
- // return imageTransfer;\r
-\r
-long iT=0;\r
-\r
-if(iDataWriteMode==DR_VRAMTRANSFER) iT|=0x1;\r
-if(iDataReadMode ==DR_VRAMTRANSFER) iT|=0x2;\r
-\r
-return iT;\r
-}\r
-\r
-////////////////////////////////////////////////////////////////////////\r
-// call config dlg (Windows + Linux)\r
-////////////////////////////////////////////////////////////////////////\r
-\r
-#ifndef _WINDOWS\r
-\r
-/*#include <unistd.h>\r
-\r
-void StartCfgTool(char * pCmdLine) // linux: start external cfg tool\r
-{\r
- FILE * cf;char filename[255],t[255];\r
-\r
- strcpy(filename,"cfg/cfgPeopsMesaGL"); // look in cfg sub folder first\r
- cf=fopen(filename,"rb");\r
- if(cf!=NULL)\r
- {\r
- fclose(cf);\r
- getcwd(t,255);\r
- chdir("cfg");\r
- sprintf(filename,"./cfgPeopsMesaGL %s",pCmdLine);\r
- system(filename);\r
- chdir(t);\r
- }\r
- else\r
- {\r
- strcpy(filename,"cfgPeopsMesaGL"); // look in current folder\r
- cf=fopen(filename,"rb");\r
- if(cf!=NULL)\r
- {\r
- fclose(cf);\r
- sprintf(filename,"./cfgPeopsMesaGL %s",pCmdLine);\r
- system(filename);\r
- }\r
- else\r
- {\r
- sprintf(filename,"%s/cfgPeopsMesaGL",getenv("HOME")); // look in home folder\r
- cf=fopen(filename,"rb");\r
- if(cf!=NULL)\r
- {\r
- fclose(cf);\r
- getcwd(t,255);\r
- chdir(getenv("HOME"));\r
- sprintf(filename,"./cfgPeopsMesaGL %s",pCmdLine);\r
- system(filename);\r
- chdir(t);\r
- }\r
- else printf("cfgPeopsMesaGL not found!\n");\r
- }\r
- }\r
-}\r
-*/\r
-#endif\r
-\r
-\r
-long CALLBACK GPUconfigure(void)\r
-{\r
-\r
-\r
- return 0;\r
-}\r
-\r
-////////////////////////////////////////////////////////////////////////\r
-// sets all kind of act fixes\r
-////////////////////////////////////////////////////////////////////////\r
-\r
-void SetFixes(void)\r
-{\r
- ReInitFrameCap();\r
-\r
- if(dwActFixes & 0x2000) \r
- dispWidths[4]=384;\r
- else dispWidths[4]=368;\r
-}\r
-\r
-////////////////////////////////////////////////////////////////////////\r
-// Pete Special: make an 'intelligent' dma chain check (<-Tekken3)\r
-////////////////////////////////////////////////////////////////////////\r
-\r
-unsigned long lUsedAddr[3];\r
-\r
-__inline BOOL CheckForEndlessLoop(unsigned long laddr)\r
-{\r
-if(laddr==lUsedAddr[1]) return TRUE;\r
-if(laddr==lUsedAddr[2]) return TRUE;\r
-\r
-if(laddr<lUsedAddr[0]) lUsedAddr[1]=laddr;\r
-else lUsedAddr[2]=laddr;\r
-lUsedAddr[0]=laddr;\r
-return FALSE;\r
-}\r
-\r
-////////////////////////////////////////////////////////////////////////\r
-// core gives a dma chain to gpu: same as the gpuwrite interface funcs\r
-////////////////////////////////////////////////////////////////////////\r
-\r
-long CALLBACK GPUdmaChain(unsigned long * baseAddrL, unsigned long addr)\r
-{\r
-unsigned long dmaMem;\r
-unsigned char * baseAddrB;\r
-short count;unsigned int DMACommandCounter = 0;\r
-\r
-if(bIsFirstFrame) GLinitialize(NULL, NULL);\r
-\r
-GPUIsBusy;\r
-\r
-lUsedAddr[0]=lUsedAddr[1]=lUsedAddr[2]=0xffffff;\r
-\r
-baseAddrB = (unsigned char*) baseAddrL;\r
-\r
-do\r
- {\r
- if(iGPUHeight==512) addr&=0x1FFFFC;\r
-\r
- if(DMACommandCounter++ > 2000000) break;\r
- if(CheckForEndlessLoop(addr)) break;\r
-\r
- count = baseAddrB[addr+3];\r
-\r
- dmaMem=addr+4;\r
-\r
- if(count>0) GPUwriteDataMem(&baseAddrL[dmaMem>>2],count);\r
- \r
- addr = baseAddrL[addr>>2]&0xffffff;\r
- } while (!(addr & 0x800000)); // contrary to some documentation, the end-of-linked-list marker is not actually 0xFF'FFFF\r
- // any pointer with bit 23 set will do.\r
-GPUIsIdle;\r
-\r
-return 0;\r
-}\r
- \r
-////////////////////////////////////////////////////////////////////////\r
-// show about dlg\r
-////////////////////////////////////////////////////////////////////////\r
-\r
-void CALLBACK GPUabout(void)\r
-{\r
-\r
-}\r
-\r
-////////////////////////////////////////////////////////////////////////\r
-// We are ever fine ;)\r
-////////////////////////////////////////////////////////////////////////\r
-\r
-long CALLBACK GPUtest(void)\r
-{\r
- // if test fails this function should return negative value for error (unable to continue)\r
- // and positive value for warning (can continue but output might be crappy)\r
-\r
- return 0;\r
-}\r
-\r
-////////////////////////////////////////////////////////////////////////\r
-// save state funcs\r
-////////////////////////////////////////////////////////////////////////\r
-\r
-////////////////////////////////////////////////////////////////////////\r
-\r
-long CALLBACK GPUfreeze(unsigned long ulGetFreezeData,GPUFreeze_t * pF)\r
-{\r
-if(ulGetFreezeData==2) \r
- {\r
- long lSlotNum=*((long *)pF);\r
- if(lSlotNum<0) return 0;\r
- if(lSlotNum>8) return 0;\r
- lSelectedSlot=lSlotNum+1;\r
- return 1;\r
- }\r
-\r
-if(!pF) return 0; \r
-if(pF->ulFreezeVersion!=1) return 0;\r
-\r
-if(ulGetFreezeData==1)\r
- {\r
- pF->ulStatus=STATUSREG;\r
- memcpy(pF->ulControl,ulStatusControl,256*sizeof(unsigned long));\r
- memcpy(pF->psxVRam, psxVub, 1024*iGPUHeight*2);\r
-\r
- return 1;\r
- }\r
-\r
-if(ulGetFreezeData!=0) return 0;\r
-\r
-STATUSREG=pF->ulStatus;\r
-memcpy(ulStatusControl,pF->ulControl,256*sizeof(unsigned long));\r
-memcpy(psxVub, pF->psxVRam, 1024*iGPUHeight*2);\r
-\r
-ResetTextureArea(TRUE);\r
-\r
- GPUwriteStatus(ulStatusControl[0]);\r
- GPUwriteStatus(ulStatusControl[1]);\r
- GPUwriteStatus(ulStatusControl[2]);\r
- GPUwriteStatus(ulStatusControl[3]);\r
- GPUwriteStatus(ulStatusControl[8]);\r
- GPUwriteStatus(ulStatusControl[6]);\r
- GPUwriteStatus(ulStatusControl[7]);\r
- GPUwriteStatus(ulStatusControl[5]);\r
- GPUwriteStatus(ulStatusControl[4]);\r
- return 1;\r
-}\r
-\r
-////////////////////////////////////////////////////////////////////////\r
-// special "emu infos" / "emu effects" functions\r
-////////////////////////////////////////////////////////////////////////\r
-\r
-//00 = black\r
-//01 = white\r
-//10 = red\r
-//11 = transparent\r
-\r
-unsigned char cFont[10][120]=\r
-{\r
-// 0\r
-{0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,\r
- 0x80,0x00,0x00,0x00,0x00,0x00,\r
- 0x80,0x00,0x00,0x00,0x00,0x00,\r
- 0x80,0x00,0x00,0x00,0x00,0x00,\r
- 0x80,0x00,0x00,0x00,0x00,0x00,\r
- 0x80,0x00,0x05,0x54,0x00,0x00,\r
- 0x80,0x00,0x14,0x05,0x00,0x00,\r
- 0x80,0x00,0x14,0x05,0x00,0x00,\r
- 0x80,0x00,0x14,0x05,0x00,0x00,\r
- 0x80,0x00,0x14,0x05,0x00,0x00,\r
- 0x80,0x00,0x14,0x05,0x00,0x00,\r
- 0x80,0x00,0x14,0x05,0x00,0x00,\r
- 0x80,0x00,0x14,0x05,0x00,0x00,\r
- 0x80,0x00,0x14,0x05,0x00,0x00,\r
- 0x80,0x00,0x05,0x54,0x00,0x00,\r
- 0x80,0x00,0x00,0x00,0x00,0x00,\r
- 0x80,0x00,0x00,0x00,0x00,0x00,\r
- 0x80,0x00,0x00,0x00,0x00,0x00,\r
- 0x80,0x00,0x00,0x00,0x00,0x00,\r
- 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa\r
-},\r
-// 1\r
-{0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,\r
- 0x80,0x00,0x00,0x00,0x00,0x00,\r
- 0x80,0x00,0x00,0x00,0x00,0x00,\r
- 0x80,0x00,0x00,0x00,0x00,0x00,\r
- 0x80,0x00,0x00,0x00,0x00,0x00,\r
- 0x80,0x00,0x00,0x50,0x00,0x00,\r
- 0x80,0x00,0x05,0x50,0x00,0x00,\r
- 0x80,0x00,0x00,0x50,0x00,0x00,\r
- 0x80,0x00,0x00,0x50,0x00,0x00,\r
- 0x80,0x00,0x00,0x50,0x00,0x00,\r
- 0x80,0x00,0x00,0x50,0x00,0x00,\r
- 0x80,0x00,0x00,0x50,0x00,0x00,\r
- 0x80,0x00,0x00,0x50,0x00,0x00,\r
- 0x80,0x00,0x00,0x50,0x00,0x00,\r
- 0x80,0x00,0x05,0x55,0x00,0x00,\r
- 0x80,0x00,0x00,0x00,0x00,0x00,\r
- 0x80,0x00,0x00,0x00,0x00,0x00,\r
- 0x80,0x00,0x00,0x00,0x00,0x00,\r
- 0x80,0x00,0x00,0x00,0x00,0x00,\r
- 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa\r
-},\r
-// 2\r
-{0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,\r
- 0x80,0x00,0x00,0x00,0x00,0x00,\r
- 0x80,0x00,0x00,0x00,0x00,0x00,\r
- 0x80,0x00,0x00,0x00,0x00,0x00,\r
- 0x80,0x00,0x00,0x00,0x00,0x00,\r
- 0x80,0x00,0x05,0x54,0x00,0x00,\r
- 0x80,0x00,0x14,0x05,0x00,0x00,\r
- 0x80,0x00,0x00,0x05,0x00,0x00,\r
- 0x80,0x00,0x00,0x05,0x00,0x00,\r
- 0x80,0x00,0x00,0x14,0x00,0x00,\r
- 0x80,0x00,0x00,0x50,0x00,0x00,\r
- 0x80,0x00,0x01,0x40,0x00,0x00,\r
- 0x80,0x00,0x05,0x00,0x00,0x00,\r
- 0x80,0x00,0x14,0x00,0x00,0x00,\r
- 0x80,0x00,0x15,0x55,0x00,0x00,\r
- 0x80,0x00,0x00,0x00,0x00,0x00,\r
- 0x80,0x00,0x00,0x00,0x00,0x00,\r
- 0x80,0x00,0x00,0x00,0x00,0x00,\r
- 0x80,0x00,0x00,0x00,0x00,0x00,\r
- 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa\r
-},\r
-// 3\r
-{0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,\r
- 0x80,0x00,0x00,0x00,0x00,0x00,\r
- 0x80,0x00,0x00,0x00,0x00,0x00,\r
- 0x80,0x00,0x00,0x00,0x00,0x00,\r
- 0x80,0x00,0x00,0x00,0x00,0x00,\r
- 0x80,0x00,0x05,0x54,0x00,0x00,\r
- 0x80,0x00,0x14,0x05,0x00,0x00,\r
- 0x80,0x00,0x00,0x05,0x00,0x00,\r
- 0x80,0x00,0x00,0x05,0x00,0x00,\r
- 0x80,0x00,0x01,0x54,0x00,0x00,\r
- 0x80,0x00,0x00,0x05,0x00,0x00,\r
- 0x80,0x00,0x00,0x05,0x00,0x00,\r
- 0x80,0x00,0x00,0x05,0x00,0x00,\r
- 0x80,0x00,0x14,0x05,0x00,0x00,\r
- 0x80,0x00,0x05,0x54,0x00,0x00,\r
- 0x80,0x00,0x00,0x00,0x00,0x00,\r
- 0x80,0x00,0x00,0x00,0x00,0x00,\r
- 0x80,0x00,0x00,0x00,0x00,0x00,\r
- 0x80,0x00,0x00,0x00,0x00,0x00,\r
- 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa\r
-},\r
-// 4\r
-{0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,\r
- 0x80,0x00,0x00,0x00,0x00,0x00,\r
- 0x80,0x00,0x00,0x00,0x00,0x00,\r
- 0x80,0x00,0x00,0x00,0x00,0x00,\r
- 0x80,0x00,0x00,0x00,0x00,0x00,\r
- 0x80,0x00,0x00,0x14,0x00,0x00,\r
- 0x80,0x00,0x00,0x54,0x00,0x00,\r
- 0x80,0x00,0x01,0x54,0x00,0x00,\r
- 0x80,0x00,0x01,0x54,0x00,0x00,\r
- 0x80,0x00,0x05,0x14,0x00,0x00,\r
- 0x80,0x00,0x14,0x14,0x00,0x00,\r
- 0x80,0x00,0x15,0x55,0x00,0x00,\r
- 0x80,0x00,0x00,0x14,0x00,0x00,\r
- 0x80,0x00,0x00,0x14,0x00,0x00,\r
- 0x80,0x00,0x00,0x55,0x00,0x00,\r
- 0x80,0x00,0x00,0x00,0x00,0x00,\r
- 0x80,0x00,0x00,0x00,0x00,0x00,\r
- 0x80,0x00,0x00,0x00,0x00,0x00,\r
- 0x80,0x00,0x00,0x00,0x00,0x00,\r
- 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa\r
-},\r
-// 5\r
-{0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,\r
- 0x80,0x00,0x00,0x00,0x00,0x00,\r
- 0x80,0x00,0x00,0x00,0x00,0x00,\r
- 0x80,0x00,0x00,0x00,0x00,0x00,\r
- 0x80,0x00,0x00,0x00,0x00,0x00,\r
- 0x80,0x00,0x15,0x55,0x00,0x00,\r
- 0x80,0x00,0x14,0x00,0x00,0x00,\r
- 0x80,0x00,0x14,0x00,0x00,0x00,\r
- 0x80,0x00,0x14,0x00,0x00,0x00,\r
- 0x80,0x00,0x15,0x54,0x00,0x00,\r
- 0x80,0x00,0x00,0x05,0x00,0x00,\r
- 0x80,0x00,0x00,0x05,0x00,0x00,\r
- 0x80,0x00,0x00,0x05,0x00,0x00,\r
- 0x80,0x00,0x14,0x05,0x00,0x00,\r
- 0x80,0x00,0x05,0x54,0x00,0x00,\r
- 0x80,0x00,0x00,0x00,0x00,0x00,\r
- 0x80,0x00,0x00,0x00,0x00,0x00,\r
- 0x80,0x00,0x00,0x00,0x00,0x00,\r
- 0x80,0x00,0x00,0x00,0x00,0x00,\r
- 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa\r
-},\r
-// 6\r
-{0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,\r
- 0x80,0x00,0x00,0x00,0x00,0x00,\r
- 0x80,0x00,0x00,0x00,0x00,0x00,\r
- 0x80,0x00,0x00,0x00,0x00,0x00,\r
- 0x80,0x00,0x00,0x00,0x00,0x00,\r
- 0x80,0x00,0x01,0x54,0x00,0x00,\r
- 0x80,0x00,0x05,0x00,0x00,0x00,\r
- 0x80,0x00,0x14,0x00,0x00,0x00,\r
- 0x80,0x00,0x14,0x00,0x00,0x00,\r
- 0x80,0x00,0x15,0x54,0x00,0x00,\r
- 0x80,0x00,0x15,0x05,0x00,0x00,\r
- 0x80,0x00,0x14,0x05,0x00,0x00,\r
- 0x80,0x00,0x14,0x05,0x00,0x00,\r
- 0x80,0x00,0x14,0x05,0x00,0x00,\r
- 0x80,0x00,0x05,0x54,0x00,0x00,\r
- 0x80,0x00,0x00,0x00,0x00,0x00,\r
- 0x80,0x00,0x00,0x00,0x00,0x00,\r
- 0x80,0x00,0x00,0x00,0x00,0x00,\r
- 0x80,0x00,0x00,0x00,0x00,0x00,\r
- 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa\r
-},\r
-// 7\r
-{0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,\r
- 0x80,0x00,0x00,0x00,0x00,0x00,\r
- 0x80,0x00,0x00,0x00,0x00,0x00,\r
- 0x80,0x00,0x00,0x00,0x00,0x00,\r
- 0x80,0x00,0x00,0x00,0x00,0x00,\r
- 0x80,0x00,0x15,0x55,0x00,0x00,\r
- 0x80,0x00,0x14,0x05,0x00,0x00,\r
- 0x80,0x00,0x00,0x14,0x00,0x00,\r
- 0x80,0x00,0x00,0x14,0x00,0x00,\r
- 0x80,0x00,0x00,0x50,0x00,0x00,\r
- 0x80,0x00,0x00,0x50,0x00,0x00,\r
- 0x80,0x00,0x01,0x40,0x00,0x00,\r
- 0x80,0x00,0x01,0x40,0x00,0x00,\r
- 0x80,0x00,0x05,0x00,0x00,0x00,\r
- 0x80,0x00,0x05,0x00,0x00,0x00,\r
- 0x80,0x00,0x00,0x00,0x00,0x00,\r
- 0x80,0x00,0x00,0x00,0x00,0x00,\r
- 0x80,0x00,0x00,0x00,0x00,0x00,\r
- 0x80,0x00,0x00,0x00,0x00,0x00,\r
- 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa\r
-},\r
-// 8\r
-{0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,\r
- 0x80,0x00,0x00,0x00,0x00,0x00,\r
- 0x80,0x00,0x00,0x00,0x00,0x00,\r
- 0x80,0x00,0x00,0x00,0x00,0x00,\r
- 0x80,0x00,0x00,0x00,0x00,0x00,\r
- 0x80,0x00,0x05,0x54,0x00,0x00,\r
- 0x80,0x00,0x14,0x05,0x00,0x00,\r
- 0x80,0x00,0x14,0x05,0x00,0x00,\r
- 0x80,0x00,0x14,0x05,0x00,0x00,\r
- 0x80,0x00,0x05,0x54,0x00,0x00,\r
- 0x80,0x00,0x14,0x05,0x00,0x00,\r
- 0x80,0x00,0x14,0x05,0x00,0x00,\r
- 0x80,0x00,0x14,0x05,0x00,0x00,\r
- 0x80,0x00,0x14,0x05,0x00,0x00,\r
- 0x80,0x00,0x05,0x54,0x00,0x00,\r
- 0x80,0x00,0x00,0x00,0x00,0x00,\r
- 0x80,0x00,0x00,0x00,0x00,0x00,\r
- 0x80,0x00,0x00,0x00,0x00,0x00,\r
- 0x80,0x00,0x00,0x00,0x00,0x00,\r
- 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa\r
-},\r
-// 9\r
-{0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,\r
- 0x80,0x00,0x00,0x00,0x00,0x00,\r
- 0x80,0x00,0x00,0x00,0x00,0x00,\r
- 0x80,0x00,0x00,0x00,0x00,0x00,\r
- 0x80,0x00,0x00,0x00,0x00,0x00,\r
- 0x80,0x00,0x05,0x54,0x00,0x00,\r
- 0x80,0x00,0x14,0x05,0x00,0x00,\r
- 0x80,0x00,0x14,0x05,0x00,0x00,\r
- 0x80,0x00,0x14,0x05,0x00,0x00,\r
- 0x80,0x00,0x14,0x15,0x00,0x00,\r
- 0x80,0x00,0x05,0x55,0x00,0x00,\r
- 0x80,0x00,0x00,0x05,0x00,0x00,\r
- 0x80,0x00,0x00,0x05,0x00,0x00,\r
- 0x80,0x00,0x00,0x14,0x00,0x00,\r
- 0x80,0x00,0x05,0x50,0x00,0x00,\r
- 0x80,0x00,0x00,0x00,0x00,0x00,\r
- 0x80,0x00,0x00,0x00,0x00,0x00,\r
- 0x80,0x00,0x00,0x00,0x00,0x00,\r
- 0x80,0x00,0x00,0x00,0x00,0x00,\r
- 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa\r
-}\r
-};\r
-\r
-////////////////////////////////////////////////////////////////////////\r
-\r
-void PaintPicDot(unsigned char * p,unsigned char c)\r
-{\r
- if(c==0) {*p++=0x00;*p++=0x00;*p=0x00;return;}\r
- if(c==1) {*p++=0xff;*p++=0xff;*p=0xff;return;}\r
- if(c==2) {*p++=0x00;*p++=0x00;*p=0xff;return;}\r
-}\r
-\r
-////////////////////////////////////////////////////////////////////////\r
-\r
-long CALLBACK GPUgetScreenPic(unsigned char * pMem)\r
-{\r
- float XS,YS;int x,y,v;\r
- unsigned char * ps, * px, * pf;\r
- unsigned char c;\r
-\r
- if(!pGfxCardScreen)\r
- {\r
- glPixelStorei(GL_PACK_ALIGNMENT,1); glError();\r
- pGfxCardScreen=(unsigned char *)malloc(iResX*iResY*4);\r
- }\r
-\r
- ps=pGfxCardScreen;\r
-\r
-// glReadBuffer(GL_FRONT);\r
-\r
- glReadPixels(0,0,iResX,iResY,GL_RGB,GL_UNSIGNED_BYTE,ps); glError();\r
- \r
-// glReadBuffer(GL_BACK);\r
-\r
- XS=(float)iResX/128;\r
- YS=(float)iResY/96;\r
- pf=pMem;\r
-\r
- for(y=96;y>0;y--)\r
- {\r
- for(x=0;x<128;x++)\r
- {\r
- px=ps+(3*((int)((float)x * XS))+\r
- (3*iResX)*((int)((float)y*YS)));\r
- *(pf+0)=*(px+2);\r
- *(pf+1)=*(px+1);\r
- *(pf+2)=*(px+0);\r
- pf+=3;\r
- }\r
- }\r
-\r
- /////////////////////////////////////////////////////////////////////\r
- // generic number/border painter\r
-\r
- pf=pMem+(103*3);\r
-\r
- for(y=0;y<20;y++)\r
- {\r
- for(x=0;x<6;x++)\r
- {\r
- c=cFont[lSelectedSlot][x+y*6];\r
- v=(c&0xc0)>>6;\r
- PaintPicDot(pf,(unsigned char)v);pf+=3; // paint the dots into the rect\r
- v=(c&0x30)>>4;\r
- PaintPicDot(pf,(unsigned char)v);pf+=3;\r
- v=(c&0x0c)>>2;\r
- PaintPicDot(pf,(unsigned char)v);pf+=3;\r
- v=c&0x03;\r
- PaintPicDot(pf,(unsigned char)v);pf+=3;\r
- }\r
- pf+=104*3;\r
- }\r
-\r
- pf=pMem;\r
- for(x=0;x<128;x++)\r
- {\r
- *(pf+(95*128*3))=0x00;*pf++=0x00;\r
- *(pf+(95*128*3))=0x00;*pf++=0x00;\r
- *(pf+(95*128*3))=0xff;*pf++=0xff;\r
- }\r
- pf=pMem;\r
- for(y=0;y<96;y++)\r
- {\r
- *(pf+(127*3))=0x00;*pf++=0x00;\r
- *(pf+(127*3))=0x00;*pf++=0x00;\r
- *(pf+(127*3))=0xff;*pf++=0xff;\r
- pf+=127*3;\r
- }\r
-\r
-}\r
-\r
-////////////////////////////////////////////////////////////////////////\r
-\r
-long CALLBACK GPUshowScreenPic(unsigned char * pMem)\r
-{\r
-// DestroyPic();\r
-// if(pMem==0) return;\r
-// CreatePic(pMem);\r
-}\r
-\r
-////////////////////////////////////////////////////////////////////////\r
-\r
-void CALLBACK GPUsetfix(unsigned long dwFixBits)\r
-{\r
- dwEmuFixes=dwFixBits;\r
-}\r
-\r
-////////////////////////////////////////////////////////////////////////\r
- \r
-void CALLBACK GPUvisualVibration(unsigned long iSmall, unsigned long iBig)\r
-{\r
- int iVibVal;\r
-\r
- if(PSXDisplay.DisplayModeNew.x) // calc min "shake pixel" from screen width\r
- iVibVal=max(1,iResX/PSXDisplay.DisplayModeNew.x);\r
- else iVibVal=1;\r
- // big rumble: 4...15 sp ; small rumble 1...3 sp\r
- if(iBig) iRumbleVal=max(4*iVibVal,min(15*iVibVal,((int)iBig *iVibVal)/10));\r
- else iRumbleVal=max(1*iVibVal,min( 3*iVibVal,((int)iSmall*iVibVal)/10));\r
-\r
- srand(timeGetTime()); // init rand (will be used in BufferSwap)\r
-\r
- iRumbleTime=15; // let the rumble last 16 buffer swaps\r
-}\r
- \r
-////////////////////////////////////////////////////////////////////////\r
-// main emu can set display infos (A/M/G/D) \r
-////////////////////////////////////////////////////////////////////////\r
-\r
-void CALLBACK GPUdisplayFlags(unsigned long dwFlags)\r
-{\r
-// dwCoreFlags=dwFlags;\r
-}\r
-\r
-// pcsx-rearmed callbacks\r
-void CALLBACK GPUrearmedCallbacks(const void **cbs)\r
-{\r
- rearmed_get_layer_pos = cbs[0];\r
-}\r
-\r
-static void flipEGL(void)\r
-{\r
- eglSwapBuffers(display, surface);\r
-}\r
+++ /dev/null
-/***************************************************************************
-* Copyright (C) 2010 PCSX4ALL Team *
-* Copyright (C) 2010 Unai *
-* Copyright (C) 2016 Senquack (dansilsby <AT> gmail <DOT> com) *
-* *
-* This program is free software; you can redistribute it and/or modify *
-* it under the terms of the GNU General Public License as published by *
-* the Free Software Foundation; either version 2 of the License, or *
-* (at your option) any later version. *
-* *
-* This program is distributed in the hope that it will be useful, *
-* but WITHOUT ANY WARRANTY; without even the implied warranty of *
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
-* GNU General Public License for more details. *
-* *
-* You should have received a copy of the GNU General Public License *
-* along with this program; if not, write to the *
-* Free Software Foundation, Inc., *
-* 51 Franklin Street, Fifth Floor, Boston, MA 02111-1307 USA. *
-***************************************************************************/
-
-#include <stddef.h>
-#include "plugins.h"
-#include "psxcommon.h"
-//#include "port.h"
-#include "gpu_unai.h"
-
-#define VIDEO_WIDTH 320
-
-#ifdef TIME_IN_MSEC
-#define TPS 1000
-#else
-#define TPS 1000000
-#endif
-
-#define IS_PAL (gpu_unai.GPU_GP1&(0x08<<17))
-
-//senquack - Original 512KB of guard space seems not to be enough, as Xenogears
-// accesses outside this range and crashes in town intro fight sequence.
-// Increased to 2MB total (double PSX VRAM) and Xenogears no longer
-// crashes, but some textures are still messed up. Also note that alignment min
-// is 16 bytes, needed for pixel-skipping rendering/blitting in high horiz res.
-// Extra 4KB is for guard room at beginning.
-// TODO: Determine cause of out-of-bounds write/reads. <-- Note: this is largely
-// solved by adoption of PCSX Rearmed's 'gpulib' in gpulib_if.cpp, which
-// replaces this file (gpu.cpp)
-//u16 GPU_FrameBuffer[(FRAME_BUFFER_SIZE+512*1024)/2] __attribute__((aligned(32)));
-static u16 GPU_FrameBuffer[(FRAME_BUFFER_SIZE*2 + 4096)/2] __attribute__((aligned(32)));
-
-///////////////////////////////////////////////////////////////////////////////
-// GPU fixed point math
-#include "gpu_fixedpoint.h"
-
-///////////////////////////////////////////////////////////////////////////////
-// Inner loop driver instantiation file
-#include "gpu_inner.h"
-
-///////////////////////////////////////////////////////////////////////////////
-// GPU internal image drawing functions
-#include "gpu_raster_image.h"
-
-///////////////////////////////////////////////////////////////////////////////
-// GPU internal line drawing functions
-#include "gpu_raster_line.h"
-
-///////////////////////////////////////////////////////////////////////////////
-// GPU internal polygon drawing functions
-#include "gpu_raster_polygon.h"
-
-///////////////////////////////////////////////////////////////////////////////
-// GPU internal sprite drawing functions
-#include "gpu_raster_sprite.h"
-
-///////////////////////////////////////////////////////////////////////////////
-// GPU command buffer execution/store
-#include "gpu_command.h"
-
-///////////////////////////////////////////////////////////////////////////////
-static void gpuReset(void)
-{
- memset((void*)&gpu_unai, 0, sizeof(gpu_unai));
- gpu_unai.vram = (u16*)GPU_FrameBuffer + (4096/2); //4kb guard room in front
- gpu_unai.GPU_GP1 = 0x14802000;
- gpu_unai.DrawingArea[2] = 256;
- gpu_unai.DrawingArea[3] = 240;
- gpu_unai.DisplayArea[2] = 256;
- gpu_unai.DisplayArea[3] = 240;
- gpu_unai.DisplayArea[5] = 240;
- gpu_unai.TextureWindow[0] = 0;
- gpu_unai.TextureWindow[1] = 0;
- gpu_unai.TextureWindow[2] = 255;
- gpu_unai.TextureWindow[3] = 255;
- //senquack - new vars must be updated whenever texture window is changed:
- // (used for polygon-drawing in gpu_inner.h, gpu_raster_polygon.h)
- const u32 fb = FIXED_BITS; // # of fractional fixed-pt bits of u4/v4
- gpu_unai.u_msk = (((u32)gpu_unai.TextureWindow[2]) << fb) | ((1 << fb) - 1);
- gpu_unai.v_msk = (((u32)gpu_unai.TextureWindow[3]) << fb) | ((1 << fb) - 1);
-
- // Configuration options
- gpu_unai.config = gpu_unai_config_ext;
- gpu_unai.ilace_mask = gpu_unai.config.ilace_force;
- gpu_unai.frameskip.skipCount = gpu_unai.config.frameskip_count;
-
- SetupLightLUT();
- SetupDitheringConstants();
-}
-
-///////////////////////////////////////////////////////////////////////////////
-long GPU_init(void)
-{
- gpuReset();
-
-#ifdef GPU_UNAI_USE_INT_DIV_MULTINV
- // s_invTable
- for(unsigned int i=1;i<=(1<<TABLE_BITS);++i)
- {
- s_invTable[i-1]=0x7fffffff/i;
- }
-#endif
-
- gpu_unai.fb_dirty = true;
- gpu_unai.dma.last_dma = NULL;
- return (0);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-long GPU_shutdown(void)
-{
- return 0;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-long GPU_freeze(u32 bWrite, GPUFreeze_t* p2)
-{
- if (!p2) return (0);
- if (p2->ulFreezeVersion != 1) return (0);
-
- if (bWrite)
- {
- p2->ulStatus = gpu_unai.GPU_GP1;
- memset(p2->ulControl, 0, sizeof(p2->ulControl));
- // save resolution and registers for P.E.Op.S. compatibility
- p2->ulControl[3] = (3 << 24) | ((gpu_unai.GPU_GP1 >> 23) & 1);
- p2->ulControl[4] = (4 << 24) | ((gpu_unai.GPU_GP1 >> 29) & 3);
- p2->ulControl[5] = (5 << 24) | (gpu_unai.DisplayArea[0] | (gpu_unai.DisplayArea[1] << 10));
- p2->ulControl[6] = (6 << 24) | (2560 << 12);
- p2->ulControl[7] = (7 << 24) | (gpu_unai.DisplayArea[4] | (gpu_unai.DisplayArea[5] << 10));
- p2->ulControl[8] = (8 << 24) | ((gpu_unai.GPU_GP1 >> 17) & 0x3f) | ((gpu_unai.GPU_GP1 >> 10) & 0x40);
- memcpy((void*)p2->psxVRam, (void*)gpu_unai.vram, FRAME_BUFFER_SIZE);
- return (1);
- }
- else
- {
- extern void GPU_writeStatus(u32 data);
- gpu_unai.GPU_GP1 = p2->ulStatus;
- memcpy((void*)gpu_unai.vram, (void*)p2->psxVRam, FRAME_BUFFER_SIZE);
- GPU_writeStatus((5 << 24) | p2->ulControl[5]);
- GPU_writeStatus((7 << 24) | p2->ulControl[7]);
- GPU_writeStatus((8 << 24) | p2->ulControl[8]);
- gpuSetTexture(gpu_unai.GPU_GP1);
- return (1);
- }
- return (0);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// GPU DMA comunication
-
-///////////////////////////////////////////////////////////////////////////////
-u8 PacketSize[256] =
-{
- 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0-15
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 16-31
- 3, 3, 3, 3, 6, 6, 6, 6, 4, 4, 4, 4, 8, 8, 8, 8, // 32-47
- 5, 5, 5, 5, 8, 8, 8, 8, 7, 7, 7, 7, 11, 11, 11, 11, // 48-63
- 2, 2, 2, 2, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3, // 64-79
- 3, 3, 3, 3, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, // 80-95
- 2, 2, 2, 2, 3, 3, 3, 3, 1, 1, 1, 1, 2, 2, 2, 2, // 96-111
- 1, 1, 1, 1, 2, 2, 2, 2, 1, 1, 1, 1, 2, 2, 2, 2, // 112-127
- 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 128-
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 144
- 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 160
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //
- 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 //
-};
-
-///////////////////////////////////////////////////////////////////////////////
-INLINE void gpuSendPacket()
-{
- gpuSendPacketFunction(gpu_unai.PacketBuffer.U4[0]>>24);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-INLINE void gpuCheckPacket(u32 uData)
-{
- if (gpu_unai.PacketCount)
- {
- gpu_unai.PacketBuffer.U4[gpu_unai.PacketIndex++] = uData;
- --gpu_unai.PacketCount;
- }
- else
- {
- gpu_unai.PacketBuffer.U4[0] = uData;
- gpu_unai.PacketCount = PacketSize[uData >> 24];
- gpu_unai.PacketIndex = 1;
- }
- if (!gpu_unai.PacketCount) gpuSendPacket();
-}
-
-///////////////////////////////////////////////////////////////////////////////
-void GPU_writeDataMem(u32* dmaAddress, int dmaCount)
-{
- #ifdef ENABLE_GPU_LOG_SUPPORT
- fprintf(stdout,"GPU_writeDataMem(%d)\n",dmaCount);
- #endif
- u32 data;
- const u16 *VIDEO_END = (u16*)gpu_unai.vram+(FRAME_BUFFER_SIZE/2)-1;
- gpu_unai.GPU_GP1 &= ~0x14000000;
-
- while (dmaCount)
- {
- if (gpu_unai.dma.FrameToWrite)
- {
- while (dmaCount)
- {
- dmaCount--;
- data = *dmaAddress++;
- if ((&gpu_unai.dma.pvram[gpu_unai.dma.px])>(VIDEO_END)) gpu_unai.dma.pvram-=512*1024;
- gpu_unai.dma.pvram[gpu_unai.dma.px] = data;
- if (++gpu_unai.dma.px >= gpu_unai.dma.x_end)
- {
- gpu_unai.dma.px = 0;
- gpu_unai.dma.pvram += 1024;
- if (++gpu_unai.dma.py >= gpu_unai.dma.y_end)
- {
- gpu_unai.dma.FrameToWrite = false;
- gpu_unai.GPU_GP1 &= ~0x08000000;
- gpu_unai.fb_dirty = true;
- break;
- }
- }
- if ((&gpu_unai.dma.pvram[gpu_unai.dma.px])>(VIDEO_END)) gpu_unai.dma.pvram-=512*1024;
- gpu_unai.dma.pvram[gpu_unai.dma.px] = data>>16;
- if (++gpu_unai.dma.px >= gpu_unai.dma.x_end)
- {
- gpu_unai.dma.px = 0;
- gpu_unai.dma.pvram += 1024;
- if (++gpu_unai.dma.py >= gpu_unai.dma.y_end)
- {
- gpu_unai.dma.FrameToWrite = false;
- gpu_unai.GPU_GP1 &= ~0x08000000;
- gpu_unai.fb_dirty = true;
- break;
- }
- }
- }
- }
- else
- {
- data = *dmaAddress++;
- dmaCount--;
- gpuCheckPacket(data);
- }
- }
-
- gpu_unai.GPU_GP1 = (gpu_unai.GPU_GP1 | 0x14000000) & ~0x60000000;
-}
-
-long GPU_dmaChain(u32 *rambase, u32 start_addr)
-{
- #ifdef ENABLE_GPU_LOG_SUPPORT
- fprintf(stdout,"GPU_dmaChain(0x%x)\n",start_addr);
- #endif
-
- u32 addr, *list;
- u32 len, count;
- long dma_words = 0;
-
- if (gpu_unai.dma.last_dma) *gpu_unai.dma.last_dma |= 0x800000;
-
- gpu_unai.GPU_GP1 &= ~0x14000000;
-
- addr = start_addr & 0xffffff;
- for (count = 0; addr != 0xffffff; count++)
- {
- list = rambase + (addr & 0x1fffff) / 4;
- len = list[0] >> 24;
- addr = list[0] & 0xffffff;
-
- dma_words += 1 + len;
-
- // add loop detection marker
- list[0] |= 0x800000;
-
- if (len) GPU_writeDataMem(list + 1, len);
-
- if (addr & 0x800000)
- {
- #ifdef ENABLE_GPU_LOG_SUPPORT
- fprintf(stdout,"GPU_dmaChain(LOOP)\n");
- #endif
- break;
- }
- }
-
- // remove loop detection markers
- addr = start_addr & 0x1fffff;
- while (count-- > 0)
- {
- list = rambase + addr / 4;
- addr = list[0] & 0x1fffff;
- list[0] &= ~0x800000;
- }
-
- if (gpu_unai.dma.last_dma) *gpu_unai.dma.last_dma &= ~0x800000;
- gpu_unai.dma.last_dma = rambase + (start_addr & 0x1fffff) / 4;
-
- gpu_unai.GPU_GP1 = (gpu_unai.GPU_GP1 | 0x14000000) & ~0x60000000;
-
- return dma_words;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-void GPU_writeData(u32 data)
-{
- const u16 *VIDEO_END = (u16*)gpu_unai.vram+(FRAME_BUFFER_SIZE/2)-1;
- #ifdef ENABLE_GPU_LOG_SUPPORT
- fprintf(stdout,"GPU_writeData()\n");
- #endif
- gpu_unai.GPU_GP1 &= ~0x14000000;
-
- if (gpu_unai.dma.FrameToWrite)
- {
- if ((&gpu_unai.dma.pvram[gpu_unai.dma.px])>(VIDEO_END)) gpu_unai.dma.pvram-=512*1024;
- gpu_unai.dma.pvram[gpu_unai.dma.px]=(u16)data;
- if (++gpu_unai.dma.px >= gpu_unai.dma.x_end)
- {
- gpu_unai.dma.px = 0;
- gpu_unai.dma.pvram += 1024;
- if (++gpu_unai.dma.py >= gpu_unai.dma.y_end)
- {
- gpu_unai.dma.FrameToWrite = false;
- gpu_unai.GPU_GP1 &= ~0x08000000;
- gpu_unai.fb_dirty = true;
- }
- }
- if (gpu_unai.dma.FrameToWrite)
- {
- if ((&gpu_unai.dma.pvram[gpu_unai.dma.px])>(VIDEO_END)) gpu_unai.dma.pvram-=512*1024;
- gpu_unai.dma.pvram[gpu_unai.dma.px]=data>>16;
- if (++gpu_unai.dma.px >= gpu_unai.dma.x_end)
- {
- gpu_unai.dma.px = 0;
- gpu_unai.dma.pvram += 1024;
- if (++gpu_unai.dma.py >= gpu_unai.dma.y_end)
- {
- gpu_unai.dma.FrameToWrite = false;
- gpu_unai.GPU_GP1 &= ~0x08000000;
- gpu_unai.fb_dirty = true;
- }
- }
- }
- }
- else
- {
- gpuCheckPacket(data);
- }
- gpu_unai.GPU_GP1 |= 0x14000000;
-}
-
-
-///////////////////////////////////////////////////////////////////////////////
-void GPU_readDataMem(u32* dmaAddress, int dmaCount)
-{
- const u16 *VIDEO_END = (u16*)gpu_unai.vram+(FRAME_BUFFER_SIZE/2)-1;
- #ifdef ENABLE_GPU_LOG_SUPPORT
- fprintf(stdout,"GPU_readDataMem(%d)\n",dmaCount);
- #endif
- if(!gpu_unai.dma.FrameToRead) return;
-
- gpu_unai.GPU_GP1 &= ~0x14000000;
- do
- {
- if ((&gpu_unai.dma.pvram[gpu_unai.dma.px])>(VIDEO_END)) gpu_unai.dma.pvram-=512*1024;
- // lower 16 bit
- //senquack - 64-bit fix (from notaz)
- //u32 data = (unsigned long)gpu_unai.dma.pvram[gpu_unai.dma.px];
- u32 data = (u32)gpu_unai.dma.pvram[gpu_unai.dma.px];
-
- if (++gpu_unai.dma.px >= gpu_unai.dma.x_end)
- {
- gpu_unai.dma.px = 0;
- gpu_unai.dma.pvram += 1024;
- }
-
- if ((&gpu_unai.dma.pvram[gpu_unai.dma.px])>(VIDEO_END)) gpu_unai.dma.pvram-=512*1024;
- // higher 16 bit (always, even if it's an odd width)
- //senquack - 64-bit fix (from notaz)
- //data |= (unsigned long)(gpu_unai.dma.pvram[gpu_unai.dma.px])<<16;
- data |= (u32)(gpu_unai.dma.pvram[gpu_unai.dma.px])<<16;
-
- *dmaAddress++ = data;
-
- if (++gpu_unai.dma.px >= gpu_unai.dma.x_end)
- {
- gpu_unai.dma.px = 0;
- gpu_unai.dma.pvram += 1024;
- if (++gpu_unai.dma.py >= gpu_unai.dma.y_end)
- {
- gpu_unai.dma.FrameToRead = false;
- gpu_unai.GPU_GP1 &= ~0x08000000;
- break;
- }
- }
- } while (--dmaCount);
-
- gpu_unai.GPU_GP1 = (gpu_unai.GPU_GP1 | 0x14000000) & ~0x60000000;
-}
-
-
-
-///////////////////////////////////////////////////////////////////////////////
-u32 GPU_readData(void)
-{
- const u16 *VIDEO_END = (u16*)gpu_unai.vram+(FRAME_BUFFER_SIZE/2)-1;
- #ifdef ENABLE_GPU_LOG_SUPPORT
- fprintf(stdout,"GPU_readData()\n");
- #endif
- gpu_unai.GPU_GP1 &= ~0x14000000;
- if (gpu_unai.dma.FrameToRead)
- {
- if ((&gpu_unai.dma.pvram[gpu_unai.dma.px])>(VIDEO_END)) gpu_unai.dma.pvram-=512*1024;
- gpu_unai.GPU_GP0 = gpu_unai.dma.pvram[gpu_unai.dma.px];
- if (++gpu_unai.dma.px >= gpu_unai.dma.x_end)
- {
- gpu_unai.dma.px = 0;
- gpu_unai.dma.pvram += 1024;
- if (++gpu_unai.dma.py >= gpu_unai.dma.y_end)
- {
- gpu_unai.dma.FrameToRead = false;
- gpu_unai.GPU_GP1 &= ~0x08000000;
- }
- }
- if ((&gpu_unai.dma.pvram[gpu_unai.dma.px])>(VIDEO_END)) gpu_unai.dma.pvram-=512*1024;
- gpu_unai.GPU_GP0 |= gpu_unai.dma.pvram[gpu_unai.dma.px]<<16;
- if (++gpu_unai.dma.px >= gpu_unai.dma.x_end)
- {
- gpu_unai.dma.px = 0;
- gpu_unai.dma.pvram += 1024;
- if (++gpu_unai.dma.py >= gpu_unai.dma.y_end)
- {
- gpu_unai.dma.FrameToRead = false;
- gpu_unai.GPU_GP1 &= ~0x08000000;
- }
- }
-
- }
- gpu_unai.GPU_GP1 |= 0x14000000;
-
- return (gpu_unai.GPU_GP0);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-u32 GPU_readStatus(void)
-{
- return gpu_unai.GPU_GP1;
-}
-
-INLINE void GPU_NoSkip(void)
-{
- #ifdef ENABLE_GPU_LOG_SUPPORT
- fprintf(stdout,"GPU_NoSkip()\n");
- #endif
- gpu_unai.frameskip.wasSkip = gpu_unai.frameskip.isSkip;
- if (gpu_unai.frameskip.isSkip)
- {
- gpu_unai.frameskip.isSkip = false;
- gpu_unai.frameskip.skipGPU = false;
- }
- else
- {
- gpu_unai.frameskip.isSkip = gpu_unai.frameskip.skipFrame;
- gpu_unai.frameskip.skipGPU = gpu_unai.frameskip.skipFrame;
- }
-}
-
-///////////////////////////////////////////////////////////////////////////////
-void GPU_writeStatus(u32 data)
-{
- #ifdef ENABLE_GPU_LOG_SUPPORT
- fprintf(stdout,"GPU_writeStatus(%d,%d)\n",data>>24,data & 0xff);
- #endif
- switch (data >> 24) {
- case 0x00:
- gpuReset();
- break;
- case 0x01:
- gpu_unai.GPU_GP1 &= ~0x08000000;
- gpu_unai.PacketCount = 0;
- gpu_unai.dma.FrameToRead = gpu_unai.dma.FrameToWrite = false;
- break;
- case 0x02:
- gpu_unai.GPU_GP1 &= ~0x08000000;
- gpu_unai.PacketCount = 0;
- gpu_unai.dma.FrameToRead = gpu_unai.dma.FrameToWrite = false;
- break;
- case 0x03:
- gpu_unai.GPU_GP1 = (gpu_unai.GPU_GP1 & ~0x00800000) | ((data & 1) << 23);
- break;
- case 0x04:
- if (data == 0x04000000) gpu_unai.PacketCount = 0;
- gpu_unai.GPU_GP1 = (gpu_unai.GPU_GP1 & ~0x60000000) | ((data & 3) << 29);
- break;
- case 0x05:
- // Start of Display Area in VRAM
- gpu_unai.DisplayArea[0] = data & 0x3ff; // X (0..1023)
- gpu_unai.DisplayArea[1] = (data >> 10) & 0x1ff; // Y (0..511)
- GPU_NoSkip();
- break;
- case 0x06:
- // GP1(06h) - Horizontal Display range (on Screen)
- // 0-11 X1 (260h+0) ;12bit ;\counted in 53.222400MHz units,
- // 12-23 X2 (260h+320*8) ;12bit ;/relative to HSYNC
-
- // senquack - gpu_unai completely ignores GP1(0x06) command and
- // lacks even a place in DisplayArea[] array to store the values.
- // It seems to have been concerned only with vertical display range
- // and centering top/bottom. I will not add support here, and
- // focus instead on the gpulib version (gpulib_if.cpp) which uses
- // gpulib for its PS1->host framebuffer blitting.
- break;
- case 0x07:
- // GP1(07h) - Vertical Display range (on Screen)
- // 0-9 Y1 (NTSC=88h-(224/2), (PAL=A3h-(264/2)) ;\scanline numbers on screen,
- // 10-19 Y2 (NTSC=88h+(224/2), (PAL=A3h+(264/2)) ;/relative to VSYNC
- // 20-23 Not used (zero)
- {
- u32 v1=data & 0x000003FF; //(short)(data & 0x3ff);
- u32 v2=(data & 0x000FFC00) >> 10; //(short)((data>>10) & 0x3ff);
- if ((gpu_unai.DisplayArea[4]!=v1)||(gpu_unai.DisplayArea[5]!=v2))
- {
- gpu_unai.DisplayArea[4] = v1;
- gpu_unai.DisplayArea[5] = v2;
- #ifdef ENABLE_GPU_LOG_SUPPORT
- fprintf(stdout,"video_clear(CHANGE_Y)\n");
- #endif
- video_clear();
- }
- }
- break;
- case 0x08:
- {
- static const u32 HorizontalResolution[8] = { 256, 368, 320, 384, 512, 512, 640, 640 };
- static const u32 VerticalResolution[4] = { 240, 480, 256, 480 };
- gpu_unai.GPU_GP1 = (gpu_unai.GPU_GP1 & ~0x007F0000) | ((data & 0x3F) << 17) | ((data & 0x40) << 10);
- #ifdef ENABLE_GPU_LOG_SUPPORT
- fprintf(stdout,"GPU_writeStatus(RES=%dx%d,BITS=%d,PAL=%d)\n",HorizontalResolution[(gpu_unai.GPU_GP1 >> 16) & 7],
- VerticalResolution[(gpu_unai.GPU_GP1 >> 19) & 3],(gpu_unai.GPU_GP1&0x00200000?24:15),(IS_PAL?1:0));
- #endif
- // Video mode change
- u32 new_width = HorizontalResolution[(gpu_unai.GPU_GP1 >> 16) & 7];
- u32 new_height = VerticalResolution[(gpu_unai.GPU_GP1 >> 19) & 3];
-
- if (gpu_unai.DisplayArea[2] != new_width || gpu_unai.DisplayArea[3] != new_height)
- {
- // Update width
- gpu_unai.DisplayArea[2] = new_width;
-
- if (PixelSkipEnabled()) {
- // Set blit_mask for high horizontal resolutions. This allows skipping
- // rendering pixels that would never get displayed on low-resolution
- // platforms that use simple pixel-dropping scaler.
- switch (gpu_unai.DisplayArea[2])
- {
- case 512: gpu_unai.blit_mask = 0xa4; break; // GPU_BlitWWSWWSWS
- case 640: gpu_unai.blit_mask = 0xaa; break; // GPU_BlitWS
- default: gpu_unai.blit_mask = 0; break;
- }
- } else {
- gpu_unai.blit_mask = 0;
- }
-
- // Update height
- gpu_unai.DisplayArea[3] = new_height;
-
- if (LineSkipEnabled()) {
- // Set rendering line-skip (only render every other line in high-res
- // 480 vertical mode, or, optionally, force it for all video modes)
-
- if (gpu_unai.DisplayArea[3] == 480) {
- if (gpu_unai.config.ilace_force) {
- gpu_unai.ilace_mask = 3; // Only need 1/4 of lines
- } else {
- gpu_unai.ilace_mask = 1; // Only need 1/2 of lines
- }
- } else {
- // Vert resolution changed from 480 to lower one
- gpu_unai.ilace_mask = gpu_unai.config.ilace_force;
- }
- } else {
- gpu_unai.ilace_mask = 0;
- }
-
- #ifdef ENABLE_GPU_LOG_SUPPORT
- fprintf(stdout,"video_clear(CHANGE_RES)\n");
- #endif
- video_clear();
- }
-
- }
- break;
- case 0x10:
- switch (data & 0xff) {
- case 2: gpu_unai.GPU_GP0 = gpu_unai.tex_window; break;
- case 3: gpu_unai.GPU_GP0 = (gpu_unai.DrawingArea[1] << 10) | gpu_unai.DrawingArea[0]; break;
- case 4: gpu_unai.GPU_GP0 = ((gpu_unai.DrawingArea[3]-1) << 10) | (gpu_unai.DrawingArea[2]-1); break;
- case 5: case 6: gpu_unai.GPU_GP0 = (((u32)gpu_unai.DrawingOffset[1] & 0x7ff) << 11) | ((u32)gpu_unai.DrawingOffset[0] & 0x7ff); break;
- case 7: gpu_unai.GPU_GP0 = 2; break;
- case 8: case 15: gpu_unai.GPU_GP0 = 0xBFC03720; break;
- }
- break;
- }
-}
-
-// Blitting functions
-#include "gpu_blit.h"
-
-static void gpuVideoOutput(void)
-{
- int h0, x0, y0, w0, h1;
-
- x0 = gpu_unai.DisplayArea[0];
- y0 = gpu_unai.DisplayArea[1];
-
- w0 = gpu_unai.DisplayArea[2];
- h0 = gpu_unai.DisplayArea[3]; // video mode
-
- h1 = gpu_unai.DisplayArea[5] - gpu_unai.DisplayArea[4]; // display needed
- if (h0 == 480) h1 = Min2(h1*2,480);
-
- bool isRGB24 = (gpu_unai.GPU_GP1 & 0x00200000 ? true : false);
- u16* dst16 = SCREEN;
- u16* src16 = (u16*)gpu_unai.vram;
-
- // PS1 fb read wraps around (fixes black screen in 'Tobal no. 1')
- unsigned int src16_offs_msk = 1024*512-1;
- unsigned int src16_offs = (x0 + y0*1024) & src16_offs_msk;
-
- // Height centering
- int sizeShift = 1;
- if (h0 == 256) {
- h0 = 240;
- } else if (h0 == 480) {
- sizeShift = 2;
- }
- if (h1 > h0) {
- src16_offs = (src16_offs + (((h1-h0) / 2) * 1024)) & src16_offs_msk;
- h1 = h0;
- } else if (h1<h0) {
- dst16 += ((h0-h1) >> sizeShift) * VIDEO_WIDTH;
- }
-
-
- /* Main blitter */
- int incY = (h0==480) ? 2 : 1;
- h0=(h0==480 ? 2048 : 1024);
-
- {
- const int li=gpu_unai.ilace_mask;
- bool pi = ProgressiveInterlaceEnabled();
- bool pif = gpu_unai.prog_ilace_flag;
- switch ( w0 )
- {
- case 256:
- for(int y1=y0+h1; y0<y1; y0+=incY)
- {
- if (( 0 == (y0&li) ) && ((!pi) || (pif=!pif)))
- GPU_BlitWWDWW(src16 + src16_offs, dst16, isRGB24);
- dst16 += VIDEO_WIDTH;
- src16_offs = (src16_offs + h0) & src16_offs_msk;
- }
- break;
- case 368:
- for(int y1=y0+h1; y0<y1; y0+=incY)
- {
- if (( 0 == (y0&li) ) && ((!pi) || (pif=!pif)))
- GPU_BlitWWWWWWWWS(src16 + src16_offs, dst16, isRGB24, 4);
- dst16 += VIDEO_WIDTH;
- src16_offs = (src16_offs + h0) & src16_offs_msk;
- }
- break;
- case 320:
- // Ensure 32-bit alignment for GPU_BlitWW() blitter:
- src16_offs &= ~1;
- for(int y1=y0+h1; y0<y1; y0+=incY)
- {
- if (( 0 == (y0&li) ) && ((!pi) || (pif=!pif)))
- GPU_BlitWW(src16 + src16_offs, dst16, isRGB24);
- dst16 += VIDEO_WIDTH;
- src16_offs = (src16_offs + h0) & src16_offs_msk;
- }
- break;
- case 384:
- for(int y1=y0+h1; y0<y1; y0+=incY)
- {
- if (( 0 == (y0&li) ) && ((!pi) || (pif=!pif)))
- GPU_BlitWWWWWS(src16 + src16_offs, dst16, isRGB24);
- dst16 += VIDEO_WIDTH;
- src16_offs = (src16_offs + h0) & src16_offs_msk;
- }
- break;
- case 512:
- for(int y1=y0+h1; y0<y1; y0+=incY)
- {
- if (( 0 == (y0&li) ) && ((!pi) || (pif=!pif)))
- GPU_BlitWWSWWSWS(src16 + src16_offs, dst16, isRGB24);
- dst16 += VIDEO_WIDTH;
- src16_offs = (src16_offs + h0) & src16_offs_msk;
- }
- break;
- case 640:
- for(int y1=y0+h1; y0<y1; y0+=incY)
- {
- if (( 0 == (y0&li) ) && ((!pi) || (pif=!pif)))
- GPU_BlitWS(src16 + src16_offs, dst16, isRGB24);
- dst16 += VIDEO_WIDTH;
- src16_offs = (src16_offs + h0) & src16_offs_msk;
- }
- break;
- }
- gpu_unai.prog_ilace_flag = !gpu_unai.prog_ilace_flag;
- }
- video_flip();
-}
-
-// Update frames-skip each second>>3 (8 times per second)
-#define GPU_FRAMESKIP_UPDATE 3
-
-static void GPU_frameskip (bool show)
-{
- u32 now=get_ticks(); // current frame
-
- // Update frameskip
- if (gpu_unai.frameskip.skipCount==0) gpu_unai.frameskip.skipFrame=false; // frameskip off
- else if (gpu_unai.frameskip.skipCount==7) { if (show) gpu_unai.frameskip.skipFrame=!gpu_unai.frameskip.skipFrame; } // frameskip medium
- else if (gpu_unai.frameskip.skipCount==8) gpu_unai.frameskip.skipFrame=true; // frameskip maximum
- else
- {
- static u32 spd=100; // speed %
- static u32 frames=0; // frames counter
- static u32 prev=now; // previous fps calculation
- frames++;
- if ((now-prev)>=(TPS>>GPU_FRAMESKIP_UPDATE))
- {
- if (IS_PAL) spd=(frames<<1);
- else spd=((frames*1001)/600);
- spd<<=GPU_FRAMESKIP_UPDATE;
- frames=0;
- prev=now;
- }
- switch(gpu_unai.frameskip.skipCount)
- {
- case 1: if (spd<50) gpu_unai.frameskip.skipFrame=true; else gpu_unai.frameskip.skipFrame=false; break; // frameskip on (spd<50%)
- case 2: if (spd<60) gpu_unai.frameskip.skipFrame=true; else gpu_unai.frameskip.skipFrame=false; break; // frameskip on (spd<60%)
- case 3: if (spd<70) gpu_unai.frameskip.skipFrame=true; else gpu_unai.frameskip.skipFrame=false; break; // frameskip on (spd<70%)
- case 4: if (spd<80) gpu_unai.frameskip.skipFrame=true; else gpu_unai.frameskip.skipFrame=false; break; // frameskip on (spd<80%)
- case 5: if (spd<90) gpu_unai.frameskip.skipFrame=true; else gpu_unai.frameskip.skipFrame=false; break; // frameskip on (spd<90%)
- }
- }
-}
-
-///////////////////////////////////////////////////////////////////////////////
-void GPU_updateLace(void)
-{
- // Interlace bit toggle
- gpu_unai.GPU_GP1 ^= 0x80000000;
-
- // Update display?
- if ((gpu_unai.fb_dirty) && (!gpu_unai.frameskip.wasSkip) && (!(gpu_unai.GPU_GP1&0x00800000)))
- {
- // Display updated
- gpuVideoOutput();
- GPU_frameskip(true);
- #ifdef ENABLE_GPU_LOG_SUPPORT
- fprintf(stdout,"GPU_updateLace(UPDATE)\n");
- #endif
- } else {
- GPU_frameskip(false);
- #ifdef ENABLE_GPU_LOG_SUPPORT
- fprintf(stdout,"GPU_updateLace(SKIP)\n");
- #endif
- }
-
- if ((!gpu_unai.frameskip.skipCount) && (gpu_unai.DisplayArea[3] == 480)) gpu_unai.frameskip.skipGPU=true; // Tekken 3 hack
-
- gpu_unai.fb_dirty=false;
- gpu_unai.dma.last_dma = NULL;
-}
-
-// Allows frontend to signal plugin to redraw screen after returning to emu
-void GPU_requestScreenRedraw()
-{
- gpu_unai.fb_dirty = true;
-}
-
-void GPU_getScreenInfo(GPUScreenInfo_t *sinfo)
-{
- bool depth24 = (gpu_unai.GPU_GP1 & 0x00200000 ? true : false);
- int16_t hres = (uint16_t)gpu_unai.DisplayArea[2];
- int16_t vres = (uint16_t)gpu_unai.DisplayArea[3];
- int16_t w = hres; // Original gpu_unai doesn't support width < 100%
- int16_t h = gpu_unai.DisplayArea[5] - gpu_unai.DisplayArea[4];
- if (vres == 480)
- h *= 2;
- if (h <= 0 || h > vres)
- h = vres;
-
- sinfo->vram = (uint8_t*)gpu_unai.vram;
- sinfo->x = (uint16_t)gpu_unai.DisplayArea[0];
- sinfo->y = (uint16_t)gpu_unai.DisplayArea[1];
- sinfo->w = w;
- sinfo->h = h;
- sinfo->hres = hres;
- sinfo->vres = vres;
- sinfo->depth24 = depth24;
- sinfo->pal = IS_PAL;
-}
+++ /dev/null
-/***************************************************************************
-* Copyright (C) 2010 PCSX4ALL Team *
-* Copyright (C) 2010 Unai *
-* *
-* This program is free software; you can redistribute it and/or modify *
-* it under the terms of the GNU General Public License as published by *
-* the Free Software Foundation; either version 2 of the License, or *
-* (at your option) any later version. *
-* *
-* This program is distributed in the hope that it will be useful, *
-* but WITHOUT ANY WARRANTY; without even the implied warranty of *
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
-* GNU General Public License for more details. *
-* *
-* You should have received a copy of the GNU General Public License *
-* along with this program; if not, write to the *
-* Free Software Foundation, Inc., *
-* 51 Franklin Street, Fifth Floor, Boston, MA 02111-1307 USA. *
-***************************************************************************/
-
-#include "port.h"
-#include "gpu.h"
-#include "profiler.h"
-#include "debug.h"
-
-int skipCount = 2; /* frame skip (0,1,2,3...) */
-int skCount = 0; /* internal frame skip */
-int linesInterlace = 0; /* internal lines interlace */
-int linesInterlace_user = 0; /* Lines interlace */
-
-bool isSkip = false; /* skip frame (info coming from GPU) */
-bool wasSkip = false;
-bool skipFrame = false; /* skip frame (according to frame skip) */
-bool alt_fps = false; /* Alternative FPS algorithm */
-bool show_fps = false; /* Show FPS statistics */
-
-bool isPAL = false; /* PAL video timing */
-bool progressInterlace_flag = false; /* Progressive interlace flag */
-bool progressInterlace = false; /* Progressive interlace option*/
-bool frameLimit = false; /* frames to wait */
-
-bool light = true; /* lighting */
-bool blend = true; /* blending */
-bool FrameToRead = false; /* load image in progress */
-bool FrameToWrite = false; /* store image in progress */
-bool fb_dirty = false;
-
-bool enableAbbeyHack = false; /* Abe's Odyssey hack */
-
-u8 BLEND_MODE;
-u8 TEXT_MODE;
-u8 Masking;
-
-u16 PixelMSB;
-u16 PixelData;
-
-///////////////////////////////////////////////////////////////////////////////
-// GPU Global data
-///////////////////////////////////////////////////////////////////////////////
-
-///////////////////////////////////////////////////////////////////////////////
-// Dma Transfers info
-s32 px,py;
-s32 x_end,y_end;
-u16* pvram;
-
-u32 GP0;
-s32 PacketCount;
-s32 PacketIndex;
-
-///////////////////////////////////////////////////////////////////////////////
-// Display status
-u32 DisplayArea [6];
-
-///////////////////////////////////////////////////////////////////////////////
-// Rasterizer status
-u32 TextureWindow [4];
-u32 DrawingArea [4];
-u32 DrawingOffset [2];
-
-///////////////////////////////////////////////////////////////////////////////
-// Rasterizer status
-
-u16* TBA;
-u16* CBA;
-
-///////////////////////////////////////////////////////////////////////////////
-// Inner Loops
-s32 u4, du4;
-s32 v4, dv4;
-s32 r4, dr4;
-s32 g4, dg4;
-s32 b4, db4;
-u32 lInc;
-u32 tInc, tMsk;
-
-GPUPacket PacketBuffer;
-// FRAME_BUFFER_SIZE is defined in bytes; 512K is guard memory for out of range reads
-u16 GPU_FrameBuffer[(FRAME_BUFFER_SIZE+512*1024)/2] __attribute__((aligned(2048)));
-u32 GPU_GP1;
-
-///////////////////////////////////////////////////////////////////////////////
-// Inner loop driver instanciation file
-#include "gpu_inner.h"
-
-///////////////////////////////////////////////////////////////////////////////
-// GPU Raster Macros
-#define GPU_RGB16(rgb) ((((rgb)&0xF80000)>>9)|(((rgb)&0xF800)>>6)|(((rgb)&0xF8)>>3))
-
-#define GPU_EXPANDSIGN(x) (((s32)(x)<<21)>>21)
-
-#define CHKMAX_X 1024
-#define CHKMAX_Y 512
-
-#define GPU_SWAP(a,b,t) {(t)=(a);(a)=(b);(b)=(t);}
-
-///////////////////////////////////////////////////////////////////////////////
-// GPU internal image drawing functions
-#include "gpu_raster_image.h"
-
-///////////////////////////////////////////////////////////////////////////////
-// GPU internal line drawing functions
-#include "gpu_raster_line.h"
-
-///////////////////////////////////////////////////////////////////////////////
-// GPU internal polygon drawing functions
-#include "gpu_raster_polygon.h"
-
-///////////////////////////////////////////////////////////////////////////////
-// GPU internal sprite drawing functions
-#include "gpu_raster_sprite.h"
-
-///////////////////////////////////////////////////////////////////////////////
-// GPU command buffer execution/store
-#include "gpu_command.h"
-
-///////////////////////////////////////////////////////////////////////////////
-INLINE void gpuReset(void)
-{
- GPU_GP1 = 0x14802000;
- TextureWindow[0] = 0;
- TextureWindow[1] = 0;
- TextureWindow[2] = 255;
- TextureWindow[3] = 255;
- DrawingArea[2] = 256;
- DrawingArea[3] = 240;
- DisplayArea[2] = 256;
- DisplayArea[3] = 240;
- DisplayArea[5] = 240;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-bool GPU_init(void)
-{
- gpuReset();
-
- // s_invTable
- for(int i=1;i<=(1<<TABLE_BITS);++i)
- {
- double v = 1.0 / double(i);
- #ifdef GPU_TABLE_10_BITS
- v *= double(0xffffffff>>1);
- #else
- v *= double(0x80000000);
- #endif
- s_invTable[i-1]=s32(v);
- }
- return (0);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-void GPU_shutdown(void)
-{
-}
-
-///////////////////////////////////////////////////////////////////////////////
-long GPU_freeze(unsigned int bWrite, GPUFreeze_t* p2)
-{
- if (!p2) return (0);
- if (p2->Version != 1) return (0);
-
- if (bWrite)
- {
- p2->GPU_gp1 = GPU_GP1;
- memset(p2->Control, 0, sizeof(p2->Control));
- // save resolution and registers for P.E.Op.S. compatibility
- p2->Control[3] = (3 << 24) | ((GPU_GP1 >> 23) & 1);
- p2->Control[4] = (4 << 24) | ((GPU_GP1 >> 29) & 3);
- p2->Control[5] = (5 << 24) | (DisplayArea[0] | (DisplayArea[1] << 10));
- p2->Control[6] = (6 << 24) | (2560 << 12);
- p2->Control[7] = (7 << 24) | (DisplayArea[4] | (DisplayArea[5] << 10));
- p2->Control[8] = (8 << 24) | ((GPU_GP1 >> 17) & 0x3f) | ((GPU_GP1 >> 10) & 0x40);
- memcpy(p2->FrameBuffer, (u16*)GPU_FrameBuffer, FRAME_BUFFER_SIZE);
- return (1);
- }
- else
- {
- GPU_GP1 = p2->GPU_gp1;
- memcpy((u16*)GPU_FrameBuffer, p2->FrameBuffer, FRAME_BUFFER_SIZE);
- GPU_writeStatus((5 << 24) | p2->Control[5]);
- GPU_writeStatus((7 << 24) | p2->Control[7]);
- GPU_writeStatus((8 << 24) | p2->Control[8]);
- gpuSetTexture(GPU_GP1);
- return (1);
- }
- return (0);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// GPU DMA comunication
-
-///////////////////////////////////////////////////////////////////////////////
-u8 PacketSize[256] =
-{
- 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0-15
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 16-31
- 3, 3, 3, 3, 6, 6, 6, 6, 4, 4, 4, 4, 8, 8, 8, 8, // 32-47
- 5, 5, 5, 5, 8, 8, 8, 8, 7, 7, 7, 7, 11, 11, 11, 11, // 48-63
- 2, 2, 2, 2, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3, // 64-79
- 3, 3, 3, 3, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, // 80-95
- 2, 2, 2, 2, 3, 3, 3, 3, 1, 1, 1, 1, 2, 2, 2, 2, // 96-111
- 1, 1, 1, 1, 2, 2, 2, 2, 1, 1, 1, 1, 2, 2, 2, 2, // 112-127
- 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 128-
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 144
- 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 160
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //
- 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 //
-};
-
-///////////////////////////////////////////////////////////////////////////////
-INLINE void gpuSendPacket()
-{
-#ifdef DEBUG_ANALYSIS
- dbg_anacnt_GPU_sendPacket++;
-#endif
- gpuSendPacketFunction(PacketBuffer.U4[0]>>24);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-INLINE void gpuCheckPacket(u32 uData)
-{
- if (PacketCount)
- {
- PacketBuffer.U4[PacketIndex++] = uData;
- --PacketCount;
- }
- else
- {
- PacketBuffer.U4[0] = uData;
- PacketCount = PacketSize[uData >> 24];
- PacketIndex = 1;
- }
- if (!PacketCount) gpuSendPacket();
-}
-
-///////////////////////////////////////////////////////////////////////////////
-void GPU_writeDataMem(u32* dmaAddress, s32 dmaCount)
-{
-#ifdef DEBUG_ANALYSIS
- dbg_anacnt_GPU_writeDataMem++;
-#endif
- pcsx4all_prof_pause(PCSX4ALL_PROF_CPU);
- pcsx4all_prof_start_with_pause(PCSX4ALL_PROF_GPU,PCSX4ALL_PROF_HW_WRITE);
- u32 data;
- const u16 *VIDEO_END=(GPU_FrameBuffer+(FRAME_BUFFER_SIZE/2)-1);
- GPU_GP1 &= ~0x14000000;
-
- while (dmaCount)
- {
- if (FrameToWrite)
- {
- while (dmaCount)
- {
- dmaCount--;
- data = *dmaAddress++;
- if ((&pvram[px])>(VIDEO_END)) pvram-=512*1024;
- pvram[px] = data;
- if (++px>=x_end)
- {
- px = 0;
- pvram += 1024;
- if (++py>=y_end)
- {
- FrameToWrite = false;
- GPU_GP1 &= ~0x08000000;
- break;
- }
- }
- if ((&pvram[px])>(VIDEO_END)) pvram-=512*1024;
- pvram[px] = data>>16;
- if (++px>=x_end)
- {
- px = 0;
- pvram += 1024;
- if (++py>=y_end)
- {
- FrameToWrite = false;
- GPU_GP1 &= ~0x08000000;
- break;
- }
- }
- }
- }
- else
- {
- data = *dmaAddress++;
- dmaCount--;
- gpuCheckPacket(data);
- }
- }
-
- GPU_GP1 = (GPU_GP1 | 0x14000000) & ~0x60000000;
- fb_dirty = true;
- pcsx4all_prof_end_with_resume(PCSX4ALL_PROF_GPU,PCSX4ALL_PROF_HW_WRITE);
- pcsx4all_prof_resume(PCSX4ALL_PROF_CPU);
-}
-
-u32 *lUsedAddr[3];
-INLINE int CheckForEndlessLoop(u32 *laddr)
-{
- if(laddr==lUsedAddr[1]) return 1;
- if(laddr==lUsedAddr[2]) return 1;
-
- if(laddr<lUsedAddr[0]) lUsedAddr[1]=laddr;
- else lUsedAddr[2]=laddr;
- lUsedAddr[0]=laddr;
- return 0;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-long GPU_dmaChain(u32* baseAddr, u32 dmaVAddr)
-{
-#ifdef DEBUG_ANALYSIS
- dbg_anacnt_GPU_dmaChain++;
-#endif
- pcsx4all_prof_start_with_pause(PCSX4ALL_PROF_GPU,PCSX4ALL_PROF_HW_WRITE);
- u32 data, *address, count, offset;
- unsigned int DMACommandCounter = 0;
- long dma_words = 0;
-
- GPU_GP1 &= ~0x14000000;
- lUsedAddr[0]=lUsedAddr[1]=lUsedAddr[2]=(u32*)0x1fffff;
- dmaVAddr &= 0x001FFFFF;
- while (dmaVAddr != 0x1FFFFF)
- {
- address = (baseAddr + (dmaVAddr >> 2));
- if(DMACommandCounter++ > 2000000) break;
- if(CheckForEndlessLoop(address)) break;
- data = *address++;
- count = (data >> 24);
- offset = data & 0x001FFFFF;
- if (dmaVAddr != offset) dmaVAddr = offset;
- else dmaVAddr = 0x1FFFFF;
-
- if(count>0) GPU_writeDataMem(address,count);
- dma_words += 1 + count;
- }
- GPU_GP1 = (GPU_GP1 | 0x14000000) & ~0x60000000;
- pcsx4all_prof_end_with_resume(PCSX4ALL_PROF_GPU,PCSX4ALL_PROF_HW_WRITE);
-
- return dma_words;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-void GPU_writeData(u32 data)
-{
- const u16 *VIDEO_END=(GPU_FrameBuffer+(FRAME_BUFFER_SIZE/2)-1);
-#ifdef DEBUG_ANALYSIS
- dbg_anacnt_GPU_writeData++;
-#endif
- pcsx4all_prof_pause(PCSX4ALL_PROF_CPU);
- pcsx4all_prof_start_with_pause(PCSX4ALL_PROF_GPU,PCSX4ALL_PROF_HW_WRITE);
- GPU_GP1 &= ~0x14000000;
-
- if (FrameToWrite)
- {
- if ((&pvram[px])>(VIDEO_END)) pvram-=512*1024;
- pvram[px]=(u16)data;
- if (++px>=x_end)
- {
- px = 0;
- pvram += 1024;
- if (++py>=y_end)
- {
- FrameToWrite = false;
- GPU_GP1 &= ~0x08000000;
- }
- }
- if (FrameToWrite)
- {
- if ((&pvram[px])>(VIDEO_END)) pvram-=512*1024;
- pvram[px]=data>>16;
- if (++px>=x_end)
- {
- px = 0;
- pvram += 1024;
- if (++py>=y_end)
- {
- FrameToWrite = false;
- GPU_GP1 &= ~0x08000000;
- }
- }
- }
- }
- else
- {
- gpuCheckPacket(data);
- }
- GPU_GP1 |= 0x14000000;
- fb_dirty = true;
- pcsx4all_prof_end_with_resume(PCSX4ALL_PROF_GPU,PCSX4ALL_PROF_HW_WRITE);
- pcsx4all_prof_resume(PCSX4ALL_PROF_CPU);
-
-}
-
-
-///////////////////////////////////////////////////////////////////////////////
-void GPU_readDataMem(u32* dmaAddress, s32 dmaCount)
-{
- const u16 *VIDEO_END=(GPU_FrameBuffer+(FRAME_BUFFER_SIZE/2)-1);
-#ifdef DEBUG_ANALYSIS
- dbg_anacnt_GPU_readDataMem++;
-#endif
- if(!FrameToRead) return;
-
- pcsx4all_prof_start_with_pause(PCSX4ALL_PROF_GPU,PCSX4ALL_PROF_HW_WRITE);
- GPU_GP1 &= ~0x14000000;
- do
- {
- if ((&pvram[px])>(VIDEO_END)) pvram-=512*1024;
- // lower 16 bit
- u32 data = pvram[px];
-
- if (++px>=x_end)
- {
- px = 0;
- pvram += 1024;
- }
-
- if ((&pvram[px])>(VIDEO_END)) pvram-=512*1024;
- // higher 16 bit (always, even if it's an odd width)
- data |= (u32)(pvram[px])<<16;
-
- *dmaAddress++ = data;
-
- if (++px>=x_end)
- {
- px = 0;
- pvram += 1024;
- if (++py>=y_end)
- {
- FrameToRead = false;
- GPU_GP1 &= ~0x08000000;
- break;
- }
- }
- } while (--dmaCount);
-
- GPU_GP1 = (GPU_GP1 | 0x14000000) & ~0x60000000;
- pcsx4all_prof_end_with_resume(PCSX4ALL_PROF_GPU,PCSX4ALL_PROF_HW_WRITE);
-}
-
-
-
-///////////////////////////////////////////////////////////////////////////////
-u32 GPU_readData(void)
-{
- const u16 *VIDEO_END=(GPU_FrameBuffer+(FRAME_BUFFER_SIZE/2)-1);
-#ifdef DEBUG_ANALYSIS
- dbg_anacnt_GPU_readData++;
-#endif
- pcsx4all_prof_pause(PCSX4ALL_PROF_CPU);
- pcsx4all_prof_start_with_pause(PCSX4ALL_PROF_GPU,PCSX4ALL_PROF_HW_READ);
- GPU_GP1 &= ~0x14000000;
- if (FrameToRead)
- {
- if ((&pvram[px])>(VIDEO_END)) pvram-=512*1024;
- GP0 = pvram[px];
- if (++px>=x_end)
- {
- px = 0;
- pvram += 1024;
- if (++py>=y_end)
- {
- FrameToRead = false;
- GPU_GP1 &= ~0x08000000;
- }
- }
- if ((&pvram[px])>(VIDEO_END)) pvram-=512*1024;
- GP0 |= pvram[px]<<16;
- if (++px>=x_end)
- {
- px = 0;
- pvram +=1024;
- if (++py>=y_end)
- {
- FrameToRead = false;
- GPU_GP1 &= ~0x08000000;
- }
- }
-
- }
- GPU_GP1 |= 0x14000000;
-
- pcsx4all_prof_end_with_resume(PCSX4ALL_PROF_GPU,PCSX4ALL_PROF_HW_READ);
- pcsx4all_prof_resume(PCSX4ALL_PROF_CPU);
- return (GP0);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-u32 GPU_readStatus(void)
-{
-#ifdef DEBUG_ANALYSIS
- dbg_anacnt_GPU_readStatus++;
-#endif
- return GPU_GP1;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-void GPU_writeStatus(u32 data)
-{
-#ifdef DEBUG_ANALYSIS
- dbg_anacnt_GPU_writeStatus++;
-#endif
- pcsx4all_prof_pause(PCSX4ALL_PROF_CPU);
- pcsx4all_prof_start_with_pause(PCSX4ALL_PROF_GPU,PCSX4ALL_PROF_HW_WRITE);
- switch (data >> 24) {
- case 0x00:
- gpuReset();
- break;
- case 0x01:
- GPU_GP1 &= ~0x08000000;
- PacketCount = 0; FrameToRead = FrameToWrite = false;
- break;
- case 0x02:
- GPU_GP1 &= ~0x08000000;
- PacketCount = 0; FrameToRead = FrameToWrite = false;
- break;
- case 0x03:
- GPU_GP1 = (GPU_GP1 & ~0x00800000) | ((data & 1) << 23);
- break;
- case 0x04:
- if (data == 0x04000000)
- PacketCount = 0;
- GPU_GP1 = (GPU_GP1 & ~0x60000000) | ((data & 3) << 29);
- break;
- case 0x05:
- DisplayArea[0] = (data & 0x000003FF); //(short)(data & 0x3ff);
- DisplayArea[1] = ((data & 0x0007FC00)>>10); //(data & 0x000FFC00) >> 10; //(short)((data>>10)&0x1ff);
- fb_dirty = true;
- wasSkip = isSkip;
- if (isSkip)
- isSkip = false;
- else
- isSkip = skipFrame;
- break;
- case 0x07:
- DisplayArea[4] = data & 0x000003FF; //(short)(data & 0x3ff);
- DisplayArea[5] = (data & 0x000FFC00) >> 10; //(short)((data>>10) & 0x3ff);
- fb_dirty = true;
- break;
- case 0x08:
- {
- GPU_GP1 = (GPU_GP1 & ~0x007F0000) | ((data & 0x3F) << 17) | ((data & 0x40) << 10);
- static u32 HorizontalResolution[8] = { 256, 368, 320, 384, 512, 512, 640, 640 };
- DisplayArea[2] = HorizontalResolution[(GPU_GP1 >> 16) & 7];
- static u32 VerticalResolution[4] = { 240, 480, 256, 480 };
- DisplayArea[3] = VerticalResolution[(GPU_GP1 >> 19) & 3];
- isPAL = (data & 0x08) ? true : false; // if 1 - PAL mode, else NTSC
- }
- fb_dirty = true;
- break;
- case 0x10:
- switch (data & 0xffff) {
- case 0:
- case 1:
- case 3:
- GP0 = (DrawingArea[1] << 10) | DrawingArea[0];
- break;
- case 4:
- GP0 = ((DrawingArea[3]-1) << 10) | (DrawingArea[2]-1);
- break;
- case 6:
- case 5:
- GP0 = (DrawingOffset[1] << 11) | DrawingOffset[0];
- break;
- case 7:
- GP0 = 2;
- break;
- default:
- GP0 = 0;
- }
- break;
- }
- pcsx4all_prof_end_with_resume(PCSX4ALL_PROF_GPU,PCSX4ALL_PROF_HW_WRITE);
- pcsx4all_prof_resume(PCSX4ALL_PROF_CPU);
-}
-
-#ifndef REARMED
-
-// Blitting functions
-#include "gpu_blit.h"
-
-INLINE void gpuVideoOutput(void)
-{
- static s16 old_res_horz, old_res_vert, old_rgb24;
- s16 h0, x0, y0, w0, h1;
-
- x0 = DisplayArea[0];
- y0 = DisplayArea[1];
-
- w0 = DisplayArea[2];
- h0 = DisplayArea[3]; // video mode
-
- h1 = DisplayArea[5] - DisplayArea[4]; // display needed
- if (h0 == 480) h1 = Min2(h1*2,480);
-
- u16* dest_screen16 = SCREEN;
- u16* src_screen16 = &((u16*)GPU_FrameBuffer)[FRAME_OFFSET(x0,y0)];
- u32 isRGB24 = (GPU_GP1 & 0x00200000 ? 32 : 0);
-
- /* Clear the screen if resolution changed to prevent interlacing and clipping to clash */
- if( (w0 != old_res_horz || h1 != old_res_vert || (s16)isRGB24 != old_rgb24) )
- {
- // Update old resolution
- old_res_horz = w0;
- old_res_vert = h1;
- old_rgb24 = (s16)isRGB24;
- // Finally, clear the screen for this special case
- video_clear();
- }
-
- // Height centering
- int sizeShift = 1;
- if(h0==256) h0 = 240; else if(h0==480) sizeShift = 2;
- if(h1>h0) { src_screen16 += ((h1-h0)>>sizeShift)*1024; h1 = h0; }
- else if(h1<h0) dest_screen16 += ((h0-h1)>>sizeShift)*VIDEO_WIDTH;
-
- /* Main blitter */
- int incY = (h0==480) ? 2 : 1;
- h0=(h0==480 ? 2048 : 1024);
-
- {
- const int li=linesInterlace;
- bool pi=progressInterlace;
- bool pif=progressInterlace_flag;
- switch ( w0 )
- {
- case 256:
- for(int y1=y0+h1; y0<y1; y0+=incY)
- {
- if(( 0 == (y0&li) ) && ((!pi) || (pif=!pif))) GPU_BlitWWDWW( src_screen16, dest_screen16, isRGB24);
- dest_screen16 += VIDEO_WIDTH;
- src_screen16 += h0;
- }
- break;
- case 368:
- for(int y1=y0+h1; y0<y1; y0+=incY)
- {
- if(( 0 == (y0&li) ) && ((!pi) || (pif=!pif))) GPU_BlitWWWWWWWWS( src_screen16, dest_screen16, isRGB24, 4);
- dest_screen16 += VIDEO_WIDTH;
- src_screen16 += h0;
- }
- break;
- case 320:
- for(int y1=y0+h1; y0<y1; y0+=incY)
- {
- if(( 0 == (y0&li) ) && ((!pi) || (pif=!pif))) GPU_BlitWW( src_screen16, dest_screen16, isRGB24);
- dest_screen16 += VIDEO_WIDTH;
- src_screen16 += h0;
- }
- break;
- case 384:
- for(int y1=y0+h1; y0<y1; y0+=incY)
- {
- if(( 0 == (y0&li) ) && ((!pi) || (pif=!pif))) GPU_BlitWWWWWS( src_screen16, dest_screen16, isRGB24);
- dest_screen16 += VIDEO_WIDTH;
- src_screen16 += h0;
- }
- break;
- case 512:
- for(int y1=y0+h1; y0<y1; y0+=incY)
- {
- if(( 0 == (y0&li) ) && ((!pi) || (pif=!pif))) GPU_BlitWWSWWSWS( src_screen16, dest_screen16, isRGB24);
- dest_screen16 += VIDEO_WIDTH;
- src_screen16 += h0;
- }
- break;
- case 640:
- for(int y1=y0+h1; y0<y1; y0+=incY)
- {
- if(( 0 == (y0&li) ) && ((!pi) || (pif=!pif))) GPU_BlitWS( src_screen16, dest_screen16, isRGB24);
- dest_screen16 += VIDEO_WIDTH;
- src_screen16 += h0;
- }
- break;
- }
- progressInterlace_flag=!progressInterlace_flag;
- }
- video_flip();
-}
-
-///////////////////////////////////////////////////////////////////////////////
-void GPU_updateLace(void)
-{
-#ifdef ENABLE_GPU_LOG_SUPPORT
- fprintf(stdout,"GPU_updateLace()\n");
-#endif
-#ifdef DEBUG_ANALYSIS
- dbg_anacnt_GPU_updateLace++;
-#endif
- pcsx4all_prof_start_with_pause(PCSX4ALL_PROF_GPU,PCSX4ALL_PROF_COUNTERS);
-#ifdef PROFILER_PCSX4ALL
- pcsx4all_prof_frames++;
-#endif
-#ifdef DEBUG_FRAME
- if(isdbg_frame())
- {
- static int passed=0;
- if (!passed) dbg_enable();
- else pcsx4all_exit();
- passed++;
- }
-#endif
-
- // Frame skip table
- static const unsigned char skipTable[12][12] =
- {
- { 0,0,0,0,0,0,0,0,0,0,0,0 },
- { 0,0,0,0,0,0,0,0,0,0,0,1 },
- { 0,0,0,0,0,1,0,0,0,0,0,1 },
- { 0,0,0,1,0,0,0,1,0,0,0,1 },
- { 0,0,1,0,0,1,0,0,1,0,0,1 },
- { 0,1,0,0,1,0,1,0,0,1,0,1 },
- { 0,1,0,1,0,1,0,1,0,1,0,1 },
- { 0,1,0,1,1,0,1,0,1,1,0,1 },
- { 0,1,1,0,1,1,0,1,1,0,1,1 },
- { 0,1,1,1,0,1,1,1,0,1,1,1 },
- { 0,1,1,1,1,1,0,1,1,1,1,1 },
- { 0,1,1,1,1,1,1,1,1,1,1,1 }
- };
-
- // Interlace bit toggle
- GPU_GP1 ^= 0x80000000;
-
- // Update display
- if ((!skipFrame) && (!isSkip) && (fb_dirty) && (!(((GPU_GP1&0x08000000))||((GPU_GP1&0x00800000)))))
- {
- gpuVideoOutput(); // Display updated
-
- if (DisplayArea[3] == 480)
- {
- if (linesInterlace_user) linesInterlace = 3; // 1/4 of lines
- else linesInterlace = 1; // if 480 we only need half of lines
- }
- else if (linesInterlace != linesInterlace_user)
- {
- linesInterlace = linesInterlace_user; // resolution changed from 480 to lower one
- video_clear();
- }
- }
-
- // Limit FPS
- if (frameLimit)
- {
- static unsigned next=get_ticks();
- if (!skipFrame)
- {
- unsigned now=get_ticks();
- if (now<next) wait_ticks(next-now);
- }
- next+=(isPAL?(1000000/50):((unsigned)(1000000.0/59.94)));
- }
-
- // Show FPS statistics
- if (show_fps)
- {
- static u32 real_fps=0;
- static u32 prev=get_ticks();
- static char msg[32]="FPS=000/00 SPD=000%";
- u32 now=get_ticks();
- real_fps++;
- if ((now-prev)>=1000000)
- {
- u32 expected_fps=(isPAL?50:60);
- sprintf(msg,"FPS=%3d/%2d SPD=%3d%%",((real_fps*(12-skipCount))/12),((expected_fps*(12-skipCount))/12),((real_fps*100)/expected_fps));
- prev=now;
- real_fps=0;
- }
- port_printf(5,5,msg);
- }
-
- // Update frame-skip
- if (!alt_fps)
- {
- // Video frame-skip
- skipFrame=skipTable[skipCount][skCount];
- skCount--; if (skCount<0) skCount=11;
- isSkip=skipFrame;
- }
- else
- {
- // Game frame-skip
- if (!isSkip)
- {
- skipFrame=skipTable[skipCount][skCount];
- skCount--; if (skCount<0) skCount=11;
- isSkip=true;
- }
- }
- fb_dirty=false;
-
- pcsx4all_prof_end_with_resume(PCSX4ALL_PROF_GPU,PCSX4ALL_PROF_COUNTERS);
-}
-
-#else
-
-#include "../../frontend/plugin_lib.h"
-
-extern "C" {
-
-static const struct rearmed_cbs *cbs;
-static s16 old_res_horz, old_res_vert, old_rgb24;
-
-static void blit(void)
-{
- u16 *base = (u16 *)GPU_FrameBuffer;
- s16 isRGB24 = (GPU_GP1 & 0x00200000) ? 1 : 0;
- s16 h0, x0, y0, w0, h1;
-
- x0 = DisplayArea[0] & ~1; // alignment needed by blitter
- y0 = DisplayArea[1];
- base += FRAME_OFFSET(x0, y0);
-
- w0 = DisplayArea[2];
- h0 = DisplayArea[3]; // video mode
-
- h1 = DisplayArea[5] - DisplayArea[4]; // display needed
- if (h0 == 480) h1 = Min2(h1*2,480);
-
- if (h1 <= 0)
- return;
-
- if (w0 != old_res_horz || h1 != old_res_vert || isRGB24 != old_rgb24)
- {
- old_res_horz = w0;
- old_res_vert = h1;
- old_rgb24 = (s16)isRGB24;
- cbs->pl_vout_set_mode(w0, h1, w0, h1, isRGB24 ? 24 : 16);
- }
-
-#error out of date
- cbs->pl_vout_flip(base, 1024, isRGB24, w0, h1);
-}
-
-void GPU_updateLace(void)
-{
- // Interlace bit toggle
- GPU_GP1 ^= 0x80000000;
-
- if (!fb_dirty || (GPU_GP1&0x08800000))
- return;
-
- if (!wasSkip) {
- blit();
- fb_dirty = false;
- skCount = 0;
- }
- else {
- skCount++;
- if (skCount >= 8)
- wasSkip = isSkip = 0;
- }
-
- skipFrame = cbs->fskip_advice || cbs->frameskip == 1;
-}
-
-long GPUopen(unsigned long *, char *, char *)
-{
- cbs->pl_vout_open();
- return 0;
-}
-
-long GPUclose(void)
-{
- cbs->pl_vout_close();
- return 0;
-}
-
-long GPUfreeze(unsigned int ulGetFreezeData, GPUFreeze_t* p2)
-{
- if (ulGetFreezeData > 1)
- return 0;
-
- return GPU_freeze(ulGetFreezeData, p2);
-}
-
-void GPUrearmedCallbacks(const struct rearmed_cbs *cbs_)
-{
- enableAbbeyHack = cbs_->gpu_unai.abe_hack;
- light = !cbs_->gpu_unai.no_light;
- blend = !cbs_->gpu_unai.no_blend;
- if (cbs_->pl_vout_set_raw_vram)
- cbs_->pl_vout_set_raw_vram((void *)GPU_FrameBuffer);
-
- cbs = cbs_;
- if (cbs->pl_set_gpu_caps)
- cbs->pl_set_gpu_caps(0);
-}
-
-} /* extern "C" */
-
-#endif