summaryrefslogtreecommitdiff
path: root/plugins/gxvideo/prim.c
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/gxvideo/prim.c')
-rw-r--r--plugins/gxvideo/prim.c3234
1 files changed, 1615 insertions, 1619 deletions
diff --git a/plugins/gxvideo/prim.c b/plugins/gxvideo/prim.c
index 6a8d8cba..368edcb4 100644
--- a/plugins/gxvideo/prim.c
+++ b/plugins/gxvideo/prim.c
@@ -1,1619 +1,1615 @@
-/***************************************************************************
- prim.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 <stdio.h>
-
-#include "globals.h"
-#include "swap.h"
-
-#define INFO_TW 0
-#define INFO_DRAWSTART 1
-#define INFO_DRAWEND 2
-#define INFO_DRAWOFF 3
-
-////////////////////////////////////////////////////////////////////////
-// globals
-////////////////////////////////////////////////////////////////////////
-
-////////////////////////////////////////////////////////////////////////
-// Some ASM color convertion by LEWPY
-////////////////////////////////////////////////////////////////////////
-
-#ifdef USE_NASM
-
-#define BGR24to16 i386_BGR24to16
-__inline unsigned short BGR24to16 (uint32_t BGR);
-
-#else
-
-static inline unsigned short BGR24to16(uint32_t BGR) {
- return (unsigned short) (((BGR >> 3) & 0x1f) | ((BGR & 0xf80000) >> 9)
- | ((BGR & 0xf800) >> 6));
-}
-
-#endif
-
-////////////////////////////////////////////////////////////////////////
-// Update global TP infos
-////////////////////////////////////////////////////////////////////////
-
-static inline void UpdateGlobalTP(unsigned short gdata) {
- g_soft.GlobalTextAddrX = (gdata << 6) & 0x3c0; // texture addr
-
- if (512 == 1024) {
- if (1 == 2) {
- g_soft.GlobalTextAddrY = ((gdata & 0x60) << 3);
- //g_zn.GlobalTextIL = (gdata & 0x2000) >> 13;
- g_soft.GlobalTextABR = (unsigned short) ((gdata >> 7) & 0x3);
- g_soft.GlobalTextTP = (gdata >> 9) & 0x3;
- if (g_soft.GlobalTextTP == 3)
- g_soft.GlobalTextTP = 2;
- g_prim.usMirror = 0;
- g_gpu.status_reg = (g_gpu.status_reg & 0xffffe000) | (gdata
- & 0x1fff);
-
- // tekken dithering? right now only if dithering is forced by user
- if (g_cfg.Dithering == 2)
- g_prim.iDither = 2;
- else
- g_prim.iDither = 0;
-
- return;
- } else {
- g_soft.GlobalTextAddrY = (unsigned short) (((gdata << 4) & 0x100)
- | ((gdata >> 2) & 0x200));
- }
- } else
- g_soft.GlobalTextAddrY = (gdata << 4) & 0x100;
-
- g_soft.GlobalTextTP = (gdata >> 7) & 0x3; // tex mode (4,8,15)
-
- if (g_soft.GlobalTextTP == 3)
- g_soft.GlobalTextTP = 2; // seen in Wild9 :(
-
- g_soft.GlobalTextABR = (gdata >> 5) & 0x3; // blend mode
-
- g_gpu.status_reg &= ~0x000001ff; // Clear the necessary bits
- g_gpu.status_reg |= (gdata & 0x01ff); // set the necessary bits
-
- switch (g_cfg.Dithering) {
- case 0:
- g_prim.iDither = 0;
- break;
- case 1:
- if (g_gpu.status_reg & 0x0200)
- g_prim.iDither = 2;
- else
- g_prim.iDither = 0;
- break;
- case 2:
- g_prim.iDither = 2;
- break;
- }
-}
-
-////////////////////////////////////////////////////////////////////////
-
-static inline void SetRenderMode(uint32_t DrawAttributes) {
- g_soft.DrawSemiTrans = (SEMITRANSBIT(DrawAttributes)) ? 1 : 0;
-
- if (SHADETEXBIT(DrawAttributes)) {
- g_soft.g_m1 = g_soft.g_m2 = g_soft.g_m3 = 128;
- } else {
- if ((g_prim.dwActFixes & 4) && ((DrawAttributes & 0x00ffffff) == 0))
- DrawAttributes |= 0x007f7f7f;
-
- g_soft.g_m1 = (short) (DrawAttributes & 0xff);
- g_soft.g_m2 = (short) ((DrawAttributes >> 8) & 0xff);
- g_soft.g_m3 = (short) ((DrawAttributes >> 16) & 0xff);
- }
-}
-
-////////////////////////////////////////////////////////////////////////
-
-// oki, here are the psx gpu coord rules: poly coords are
-// 11 bit signed values (-1024...1023). If the x or y distance
-// exceeds 1024, the polygon will not be drawn.
-// Since quads are treated as two triangles by the real gpu,
-// this 'discard rule' applies to each of the quad's triangle
-// (so one triangle can be drawn, the other one discarded).
-// Also, y drawing is wrapped at 512 one time,
-// then it will get negative (and therefore not drawn). The
-// 'CheckCoord' funcs are a simple (not comlete!) approach to
-// do things right, I will add a better detection soon... the
-// current approach will be easier to do in hw/accel plugins, imho
-
-// 11 bit signed
-#define SIGNSHIFT 21
-#define CHKMAX_X 1024
-#define CHKMAX_Y 512
-
-static void AdjustCoord4() {
- g_soft.lx0 = (short) (((int) g_soft.lx0 << SIGNSHIFT) >> SIGNSHIFT);
- g_soft.lx1 = (short) (((int) g_soft.lx1 << SIGNSHIFT) >> SIGNSHIFT);
- g_soft.lx2 = (short) (((int) g_soft.lx2 << SIGNSHIFT) >> SIGNSHIFT);
- g_soft.lx3 = (short) (((int) g_soft.lx3 << SIGNSHIFT) >> SIGNSHIFT);
- g_soft.ly0 = (short) (((int) g_soft.ly0 << SIGNSHIFT) >> SIGNSHIFT);
- g_soft.ly1 = (short) (((int) g_soft.ly1 << SIGNSHIFT) >> SIGNSHIFT);
- g_soft.ly2 = (short) (((int) g_soft.ly2 << SIGNSHIFT) >> SIGNSHIFT);
- g_soft.ly3 = (short) (((int) g_soft.ly3 << SIGNSHIFT) >> SIGNSHIFT);
-}
-
-static void AdjustCoord3() {
- g_soft.lx0 = (short) (((int) g_soft.lx0 << SIGNSHIFT) >> SIGNSHIFT);
- g_soft.lx1 = (short) (((int) g_soft.lx1 << SIGNSHIFT) >> SIGNSHIFT);
- g_soft.lx2 = (short) (((int) g_soft.lx2 << SIGNSHIFT) >> SIGNSHIFT);
- g_soft.ly0 = (short) (((int) g_soft.ly0 << SIGNSHIFT) >> SIGNSHIFT);
- g_soft.ly1 = (short) (((int) g_soft.ly1 << SIGNSHIFT) >> SIGNSHIFT);
- g_soft.ly2 = (short) (((int) g_soft.ly2 << SIGNSHIFT) >> SIGNSHIFT);
-}
-
-static void AdjustCoord2() {
- g_soft.lx0 = (short) (((int) g_soft.lx0 << SIGNSHIFT) >> SIGNSHIFT);
- g_soft.lx1 = (short) (((int) g_soft.lx1 << SIGNSHIFT) >> SIGNSHIFT);
- g_soft.ly0 = (short) (((int) g_soft.ly0 << SIGNSHIFT) >> SIGNSHIFT);
- g_soft.ly1 = (short) (((int) g_soft.ly1 << SIGNSHIFT) >> SIGNSHIFT);
-}
-
-static void AdjustCoord1() {
- g_soft.lx0 = (short) (((int) g_soft.lx0 << SIGNSHIFT) >> SIGNSHIFT);
- g_soft.ly0 = (short) (((int) g_soft.ly0 << SIGNSHIFT) >> SIGNSHIFT);
-
- if (g_soft.lx0 < -512 && g_gpu.dsp.DrawOffset.x <= -512)
- g_soft.lx0 += 2048;
-
- if (g_soft.ly0 < -512 && g_gpu.dsp.DrawOffset.y <= -512)
- g_soft.ly0 += 2048;
-}
-
-/*
- ////////////////////////////////////////////////////////////////////////
- // special checks... nascar, syphon filter 2, mgs
- ////////////////////////////////////////////////////////////////////////
-
- // xenogears FT4: not removed correctly right now... the tri 0,1,2
- // should get removed, the tri 1,2,3 should stay... pfff
-
- // x -466 1023 180 1023
- // y 20 -228 222 -100
-
- // 0 __1
- // \ / \
- // 2___3
- */
-static inline char CheckCoord4() {
- if (g_soft.lx0 < 0) {
- if (((g_soft.lx1 - g_soft.lx0) > CHKMAX_X)
- || ((g_soft.lx2 - g_soft.lx0) > CHKMAX_X)) {
- if (g_soft.lx3 < 0) {
- if ((g_soft.lx1 - g_soft.lx3) > CHKMAX_X)
- return 1;
- if ((g_soft.lx2 - g_soft.lx3) > CHKMAX_X)
- return 1;
- }
- }
- }
- if (g_soft.lx1 < 0) {
- if ((g_soft.lx0 - g_soft.lx1) > CHKMAX_X)
- return 1;
- if ((g_soft.lx2 - g_soft.lx1) > CHKMAX_X)
- return 1;
- if ((g_soft.lx3 - g_soft.lx1) > CHKMAX_X)
- return 1;
- }
- if (g_soft.lx2 < 0) {
- if ((g_soft.lx0 - g_soft.lx2) > CHKMAX_X)
- return 1;
- if ((g_soft.lx1 - g_soft.lx2) > CHKMAX_X)
- return 1;
- if ((g_soft.lx3 - g_soft.lx2) > CHKMAX_X)
- return 1;
- }
- if (g_soft.lx3 < 0) {
- if (((g_soft.lx1 - g_soft.lx3) > CHKMAX_X)
- || ((g_soft.lx2 - g_soft.lx3) > CHKMAX_X)) {
- if (g_soft.lx0 < 0) {
- if ((g_soft.lx1 - g_soft.lx0) > CHKMAX_X)
- return 1;
- if ((g_soft.lx2 - g_soft.lx0) > CHKMAX_X)
- return 1;
- }
- }
- }
-
- if (g_soft.ly0 < 0) {
- if ((g_soft.ly1 - g_soft.ly0) > CHKMAX_Y)
- return 1;
- if ((g_soft.ly2 - g_soft.ly0) > CHKMAX_Y)
- return 1;
- }
- if (g_soft.ly1 < 0) {
- if ((g_soft.ly0 - g_soft.ly1) > CHKMAX_Y)
- return 1;
- if ((g_soft.ly2 - g_soft.ly1) > CHKMAX_Y)
- return 1;
- if ((g_soft.ly3 - g_soft.ly1) > CHKMAX_Y)
- return 1;
- }
- if (g_soft.ly2 < 0) {
- if ((g_soft.ly0 - g_soft.ly2) > CHKMAX_Y)
- return 1;
- if ((g_soft.ly1 - g_soft.ly2) > CHKMAX_Y)
- return 1;
- if ((g_soft.ly3 - g_soft.ly2) > CHKMAX_Y)
- return 1;
- }
- if (g_soft.ly3 < 0) {
- if ((g_soft.ly1 - g_soft.ly3) > CHKMAX_Y)
- return 1;
- if ((g_soft.ly2 - g_soft.ly3) > CHKMAX_Y)
- return 1;
- }
-
- return 0;
-}
-
-static inline char CheckCoord3() {
- if (g_soft.lx0 < 0) {
- if ((g_soft.lx1 - g_soft.lx0) > CHKMAX_X)
- return 1;
- if ((g_soft.lx2 - g_soft.lx0) > CHKMAX_X)
- return 1;
- }
- if (g_soft.lx1 < 0) {
- if ((g_soft.lx0 - g_soft.lx1) > CHKMAX_X)
- return 1;
- if ((g_soft.lx2 - g_soft.lx1) > CHKMAX_X)
- return 1;
- }
- if (g_soft.lx2 < 0) {
- if ((g_soft.lx0 - g_soft.lx2) > CHKMAX_X)
- return 1;
- if ((g_soft.lx1 - g_soft.lx2) > CHKMAX_X)
- return 1;
- }
- if (g_soft.ly0 < 0) {
- if ((g_soft.ly1 - g_soft.ly0) > CHKMAX_Y)
- return 1;
- if ((g_soft.ly2 - g_soft.ly0) > CHKMAX_Y)
- return 1;
- }
- if (g_soft.ly1 < 0) {
- if ((g_soft.ly0 - g_soft.ly1) > CHKMAX_Y)
- return 1;
- if ((g_soft.ly2 - g_soft.ly1) > CHKMAX_Y)
- return 1;
- }
- if (g_soft.ly2 < 0) {
- if ((g_soft.ly0 - g_soft.ly2) > CHKMAX_Y)
- return 1;
- if ((g_soft.ly1 - g_soft.ly2) > CHKMAX_Y)
- return 1;
- }
-
- return 0;
-}
-
-static inline char CheckCoord2() {
- if (g_soft.lx0 < 0) {
- if ((g_soft.lx1 - g_soft.lx0) > CHKMAX_X)
- return 1;
- }
- if (g_soft.lx1 < 0) {
- if ((g_soft.lx0 - g_soft.lx1) > CHKMAX_X)
- return 1;
- }
- if (g_soft.ly0 < 0) {
- if ((g_soft.ly1 - g_soft.ly0) > CHKMAX_Y)
- return 1;
- }
- if (g_soft.ly1 < 0) {
- if ((g_soft.ly0 - g_soft.ly1) > CHKMAX_Y)
- return 1;
- }
-
- return 0;
-}
-
-static inline char CheckCoordL(short slx0, short sly0, short slx1, short sly1) {
- if (slx0 < 0) {
- if ((slx1 - slx0) > CHKMAX_X)
- return 1;
- }
- if (slx1 < 0) {
- if ((slx0 - slx1) > CHKMAX_X)
- return 1;
- }
- if (sly0 < 0) {
- if ((sly1 - sly0) > CHKMAX_Y)
- return 1;
- }
- if (sly1 < 0) {
- if ((sly0 - sly1) > CHKMAX_Y)
- return 1;
- }
-
- return 0;
-}
-
-////////////////////////////////////////////////////////////////////////
-// mask stuff... used in silent hill
-////////////////////////////////////////////////////////////////////////
-
-static void cmdSTP(unsigned char * baseAddr) {
- uint32_t gdata = GETLE32(&((uint32_t*)baseAddr)[0]);
-
- g_gpu.status_reg &= ~0x1800; // Clear the necessary bits
- g_gpu.status_reg |= ((gdata & 0x03) << 11); // Set the necessary bits
-
- if (gdata & 1) {
- g_draw.sSetMask = 0x8000;
- g_draw.lSetMask = 0x80008000;
- } else {
- g_draw.sSetMask = 0;
- g_draw.lSetMask = 0;
- }
-
- if (gdata & 2)
- g_draw.bCheckMask = 1;
- else
- g_draw.bCheckMask = 0;
-}
-
-////////////////////////////////////////////////////////////////////////
-// cmd: Set texture page infos
-////////////////////////////////////////////////////////////////////////
-
-static void cmdTexturePage(unsigned char * baseAddr) {
- uint32_t gdata = GETLE32(&((uint32_t*)baseAddr)[0]);
-
- g_gpu.status_reg &= ~0x000007ff;
- g_gpu.status_reg |= (gdata & 0x07ff);
-
- g_prim.usMirror = (unsigned short) (gdata & 0x3000);
-
- UpdateGlobalTP((unsigned short) gdata);
- g_soft.GlobalTextREST = (gdata & 0x00ffffff) >> 9;
-}
-
-////////////////////////////////////////////////////////////////////////
-// cmd: turn on/off texture window
-////////////////////////////////////////////////////////////////////////
-
-static void cmdTextureWindow(unsigned char *baseAddr) {
- uint32_t gdata = GETLE32(&((uint32_t*)baseAddr)[0]);
-
- uint32_t YAlign, XAlign;
-
- g_gpu.lGPUInfoVals[INFO_TW] = gdata & 0xFFFFF;
-
- if (gdata & 0x020)
- g_prim.TWin.Position.y1 = 8; // xxxx1
- else if (gdata & 0x040)
- g_prim.TWin.Position.y1 = 16; // xxx10
- else if (gdata & 0x080)
- g_prim.TWin.Position.y1 = 32; // xx100
- else if (gdata & 0x100)
- g_prim.TWin.Position.y1 = 64; // x1000
- else if (gdata & 0x200)
- g_prim.TWin.Position.y1 = 128; // 10000
- else
- g_prim.TWin.Position.y1 = 256; // 00000
-
- // Texture window size is determined by the least bit set of the relevant 5 bits
-
- if (gdata & 0x001)
- g_prim.TWin.Position.x1 = 8; // xxxx1
- else if (gdata & 0x002)
- g_prim.TWin.Position.x1 = 16; // xxx10
- else if (gdata & 0x004)
- g_prim.TWin.Position.x1 = 32; // xx100
- else if (gdata & 0x008)
- g_prim.TWin.Position.x1 = 64; // x1000
- else if (gdata & 0x010)
- g_prim.TWin.Position.x1 = 128; // 10000
- else
- g_prim.TWin.Position.x1 = 256; // 00000
-
- // Re-calculate the bit field, because we can't trust what is passed in the data
-
-
- YAlign = (uint32_t) (32 - (g_prim.TWin.Position.y1 >> 3));
- XAlign = (uint32_t) (32 - (g_prim.TWin.Position.x1 >> 3));
-
- // Absolute position of the start of the texture window
-
- g_prim.TWin.Position.y0 = (short) (((gdata >> 15) & YAlign) << 3);
- g_prim.TWin.Position.x0 = (short) (((gdata >> 10) & XAlign) << 3);
-
- if ((g_prim.TWin.Position.x0 == 0 && // tw turned off
- g_prim.TWin.Position.y0 == 0 && g_prim.TWin.Position.x1 == 0
- && g_prim.TWin.Position.y1 == 0) || (g_prim.TWin.Position.x1 == 256
- && g_prim.TWin.Position.y1 == 256)) {
- g_prim.bUsingTWin = 0; // -> just do it
- } else // otherwise
- {
- g_prim.bUsingTWin = 1; // -> tw turned on
- }
-}
-
-////////////////////////////////////////////////////////////////////////
-// cmd: start of drawing area... primitives will be clipped inside
-////////////////////////////////////////////////////////////////////////
-
-
-static void cmdDrawAreaStart(unsigned char * baseAddr) {
- uint32_t gdata = GETLE32(&((uint32_t*)baseAddr)[0]);
- g_prim.drawX = gdata & 0x3ff; // for soft drawing
- g_gpu.lGPUInfoVals[INFO_DRAWSTART] = gdata & 0xFFFFF;
- g_prim.drawY = (gdata >> 10) & 0x3ff;
- if (g_prim.drawY >= 512)
- g_prim.drawY = 511; // some security
-}
-
-////////////////////////////////////////////////////////////////////////
-// cmd: end of drawing area... primitives will be clipped inside
-////////////////////////////////////////////////////////////////////////
-
-static void cmdDrawAreaEnd(unsigned char * baseAddr) {
- uint32_t gdata = GETLE32(&((uint32_t*)baseAddr)[0]);
-
- g_prim.drawW = gdata & 0x3ff; // for soft drawing
-
- g_gpu.lGPUInfoVals[INFO_DRAWEND] = gdata & 0xFFFFF;
- g_prim.drawH = (gdata >> 10) & 0x3ff;
- if (g_prim.drawH >= 512)
- g_prim.drawH = 511; // some security
-}
-
-////////////////////////////////////////////////////////////////////////
-// cmd: draw offset... will be added to prim coords
-////////////////////////////////////////////////////////////////////////
-
-static void cmdDrawOffset(unsigned char * baseAddr) {
- uint32_t gdata = GETLE32(&((uint32_t*)baseAddr)[0]);
-
- g_gpu.dsp.DrawOffset.x = (short) (gdata & 0x7ff);
-
- g_gpu.lGPUInfoVals[INFO_DRAWOFF] = gdata & 0x3FFFFF;
- g_gpu.dsp.DrawOffset.y = (short) ((gdata >> 11) & 0x7ff);
-
- g_gpu.dsp.DrawOffset.y = (short) (((int) g_gpu.dsp.DrawOffset.y << 21)
- >> 21);
- g_gpu.dsp.DrawOffset.x = (short) (((int) g_gpu.dsp.DrawOffset.x << 21)
- >> 21);
-}
-
-////////////////////////////////////////////////////////////////////////
-// cmd: load image to vram
-////////////////////////////////////////////////////////////////////////
-
-static void primLoadImage(unsigned char * baseAddr) {
- unsigned short *sgpuData = ((unsigned short *) baseAddr);
-
- g_gpu.VRAMWrite.x = GETLEs16(&sgpuData[2]) & 0x3ff;
- g_gpu.VRAMWrite.y = GETLEs16(&sgpuData[3]) & 0x1ff;
- g_gpu.VRAMWrite.Width = GETLEs16(&sgpuData[4]);
- g_gpu.VRAMWrite.Height = GETLEs16(&sgpuData[5]);
-
- g_gpu.DataWriteMode = DR_VRAMTRANSFER;
-
- g_gpu.VRAMWrite.ImagePtr = g_gpu.psx_vram.u16 + (g_gpu.VRAMWrite.y << 10)
- + g_gpu.VRAMWrite.x;
- g_gpu.VRAMWrite.RowsRemaining = g_gpu.VRAMWrite.Width;
- g_gpu.VRAMWrite.ColsRemaining = g_gpu.VRAMWrite.Height;
-}
-
-////////////////////////////////////////////////////////////////////////
-// cmd: vram -> psx mem
-////////////////////////////////////////////////////////////////////////
-
-static void primStoreImage(unsigned char * baseAddr) {
- unsigned short *sgpuData = ((unsigned short *) baseAddr);
-
- g_gpu.VRAMRead.x = GETLEs16(&sgpuData[2]) & 0x03ff;
- g_gpu.VRAMRead.y = GETLEs16(&sgpuData[3]) & 0x01ff;
- g_gpu.VRAMRead.Width = GETLEs16(&sgpuData[4]);
- g_gpu.VRAMRead.Height = GETLEs16(&sgpuData[5]);
-
- g_gpu.VRAMRead.ImagePtr = g_gpu.psx_vram.u16 + (g_gpu.VRAMRead.y << 10)
- + g_gpu.VRAMRead.x;
- g_gpu.VRAMRead.RowsRemaining = g_gpu.VRAMRead.Width;
- g_gpu.VRAMRead.ColsRemaining = g_gpu.VRAMRead.Height;
-
- g_gpu.DataReadMode = DR_VRAMTRANSFER;
-
- g_gpu.status_reg |= STATUS_READYFORVRAM;
-}
-
-////////////////////////////////////////////////////////////////////////
-// cmd: blkfill - NO primitive! Doesn't care about draw areas...
-////////////////////////////////////////////////////////////////////////
-
-static void primBlkFill(unsigned char * baseAddr) {
- uint32_t *gpuData = ((uint32_t *) baseAddr);
- short *sgpuData = ((short *) baseAddr);
-
- short sX = GETLEs16(&sgpuData[2]);
- short sY = GETLEs16(&sgpuData[3]);
- short sW = GETLEs16(&sgpuData[4]) & 0x3ff;
- short sH = GETLEs16(&sgpuData[5]) & 0x3ff;
-
- sW = (sW + 15) & ~15;
-
- // Increase H & W if they are one short of full values, because they never can be full values
- if (sH >= 1023)
- sH = 1024;
- if (sW >= 1023)
- sW = 1024;
-
- // x and y of end pos
- sW += sX;
- sH += sY;
-
- FillSoftwareArea(sX, sY, sW, sH, BGR24to16(GETLE32(&gpuData[0])));
-
-}
-
-////////////////////////////////////////////////////////////////////////
-// cmd: move image vram -> vram
-////////////////////////////////////////////////////////////////////////
-
-static void primMoveImage(unsigned char * baseAddr) {
- short *sgpuData = ((short *) baseAddr);
-
- short imageY0, imageX0, imageY1, imageX1, imageSX, imageSY, i, j;
-
- imageX0 = GETLEs16(&sgpuData[2]) & 0x03ff;
- imageY0 = GETLEs16(&sgpuData[3]) & 0x01ff;
- imageX1 = GETLEs16(&sgpuData[4]) & 0x03ff;
- imageY1 = GETLEs16(&sgpuData[5]) & 0x01ff;
- imageSX = GETLEs16(&sgpuData[6]);
- imageSY = GETLEs16(&sgpuData[7]);
-
- if ((imageX0 == imageX1) && (imageY0 == imageY1))
- return;
- if (imageSX <= 0)
- return;
- if (imageSY <= 0)
- return;
-
- if ((imageY0 + imageSY) > 512 || (imageX0 + imageSX) > 1024 || (imageY1
- + imageSY) > 512 || (imageX1 + imageSX) > 1024) {
- int i, j;
- for (j = 0; j < imageSY; j++)
- for (i = 0; i < imageSX; i++)
- g_gpu.psx_vram.u16[(1024 * ((imageY1 + j) & 0x01ff))
- + ((imageX1 + i) & 0x3ff)] = g_gpu.psx_vram.u16[(1024
- * ((imageY0 + j) & 0x01ff)) + ((imageX0 + i) & 0x3ff)];
-
- return;
- }
-
- if (imageSX & 1) // not dword aligned? slower func
- {
- unsigned short *SRCPtr, *DSTPtr;
- unsigned short LineOffset;
-
- SRCPtr = g_gpu.psx_vram.u16 + (1024 * imageY0) + imageX0;
- DSTPtr = g_gpu.psx_vram.u16 + (1024 * imageY1) + imageX1;
-
- LineOffset = 1024 - imageSX;
-
- for (j = 0; j < imageSY; j++) {
- for (i = 0; i < imageSX; i++)
- *DSTPtr++ = *SRCPtr++;
- SRCPtr += LineOffset;
- DSTPtr += LineOffset;
- }
- } else // dword aligned
- {
- uint32_t *SRCPtr, *DSTPtr;
- unsigned short LineOffset;
- int dx = imageSX >> 1;
-
- SRCPtr = (uint32_t *) (g_gpu.psx_vram.u16 + (1024 * imageY0) + imageX0);
- DSTPtr = (uint32_t *) (g_gpu.psx_vram.u16 + (1024 * imageY1) + imageX1);
-
- LineOffset = 512 - dx;
-
- for (j = 0; j < imageSY; j++) {
- for (i = 0; i < dx; i++)
- *DSTPtr++ = *SRCPtr++;
- SRCPtr += LineOffset;
- DSTPtr += LineOffset;
- }
- }
-
- imageSX += imageX1;
- imageSY += imageY1;
-
-}
-
-////////////////////////////////////////////////////////////////////////
-// cmd: draw free-size Tile
-////////////////////////////////////////////////////////////////////////
-static void primTileS(unsigned char * baseAddr) {
- uint32_t *gpuData = ((uint32_t*) baseAddr);
- short *sgpuData = ((short *) baseAddr);
- short sW = GETLEs16(&sgpuData[4]) & 0x3ff;
- short sH = GETLEs16(&sgpuData[5]) & 0x01ff; // mmm... limit tiles to 0x1ff or height?
-
- g_soft.lx0 = GETLEs16(&sgpuData[2]);
- g_soft.ly0 = GETLEs16(&sgpuData[3]);
-
- if (!(g_prim.dwActFixes & 8))
- AdjustCoord1();
-
- // x and y of start
- g_soft.ly2 = g_soft.ly3 = g_soft.ly0 + sH + g_gpu.dsp.DrawOffset.y;
- g_soft.ly0 = g_soft.ly1 = g_soft.ly0 + g_gpu.dsp.DrawOffset.y;
- g_soft.lx1 = g_soft.lx2 = g_soft.lx0 + sW + g_gpu.dsp.DrawOffset.x;
- g_soft.lx0 = g_soft.lx3 = g_soft.lx0 + g_gpu.dsp.DrawOffset.x;
-
- g_soft.DrawSemiTrans = (SEMITRANSBIT(GETLE32(&gpuData[0]))) ? 1 : 0;
-
- if (!(0 && sH == 32 && GETLE32(&gpuData[0]) == 0x60ffffff)) // special cheat for certain ZiNc games
- FillSoftwareAreaTrans(g_soft.lx0, g_soft.ly0, g_soft.lx2, g_soft.ly2,
- BGR24to16(GETLE32(&gpuData[0])));
-
-}
-
-////////////////////////////////////////////////////////////////////////
-// cmd: draw 1 dot Tile (point)
-////////////////////////////////////////////////////////////////////////
-
-static void primTile1(unsigned char * baseAddr) {
- uint32_t *gpuData = ((uint32_t*) baseAddr);
- short *sgpuData = ((short *) baseAddr);
- short sH = 1;
- short sW = 1;
-
- g_soft.lx0 = GETLEs16(&sgpuData[2]);
- g_soft.ly0 = GETLEs16(&sgpuData[3]);
-
- if (!(g_prim.dwActFixes & 8))
- AdjustCoord1();
-
- // x and y of start
- g_soft.ly2 = g_soft.ly3 = g_soft.ly0 + sH + g_gpu.dsp.DrawOffset.y;
- g_soft.ly0 = g_soft.ly1 = g_soft.ly0 + g_gpu.dsp.DrawOffset.y;
- g_soft.lx1 = g_soft.lx2 = g_soft.lx0 + sW + g_gpu.dsp.DrawOffset.x;
- g_soft.lx0 = g_soft.lx3 = g_soft.lx0 + g_gpu.dsp.DrawOffset.x;
-
- g_soft.DrawSemiTrans = (SEMITRANSBIT(GETLE32(&gpuData[0]))) ? 1 : 0;
-
- FillSoftwareAreaTrans(g_soft.lx0, g_soft.ly0, g_soft.lx2, g_soft.ly2,
- BGR24to16(GETLE32(&gpuData[0]))); // Takes Start and Offset
-
-}
-
-////////////////////////////////////////////////////////////////////////
-// cmd: draw 8 dot Tile (small rect)
-////////////////////////////////////////////////////////////////////////
-
-static void primTile8(unsigned char * baseAddr) {
- uint32_t *gpuData = ((uint32_t*) baseAddr);
- short *sgpuData = ((short *) baseAddr);
- short sH = 8;
- short sW = 8;
-
- g_soft.lx0 = GETLEs16(&sgpuData[2]);
- g_soft.ly0 = GETLEs16(&sgpuData[3]);
-
- if (!(g_prim.dwActFixes & 8))
- AdjustCoord1();
-
- // x and y of start
- g_soft.ly2 = g_soft.ly3 = g_soft.ly0 + sH + g_gpu.dsp.DrawOffset.y;
- g_soft.ly0 = g_soft.ly1 = g_soft.ly0 + g_gpu.dsp.DrawOffset.y;
- g_soft.lx1 = g_soft.lx2 = g_soft.lx0 + sW + g_gpu.dsp.DrawOffset.x;
- g_soft.lx0 = g_soft.lx3 = g_soft.lx0 + g_gpu.dsp.DrawOffset.x;
-
- g_soft.DrawSemiTrans = (SEMITRANSBIT(GETLE32(&gpuData[0]))) ? 1 : 0;
-
- FillSoftwareAreaTrans(g_soft.lx0, g_soft.ly0, g_soft.lx2, g_soft.ly2,
- BGR24to16(GETLE32(&gpuData[0]))); // Takes Start and Offset
-
-}
-
-////////////////////////////////////////////////////////////////////////
-// cmd: draw 16 dot Tile (medium rect)
-////////////////////////////////////////////////////////////////////////
-
-static void primTile16(unsigned char * baseAddr) {
- uint32_t *gpuData = ((uint32_t*) baseAddr);
- short *sgpuData = ((short *) baseAddr);
- short sH = 16;
- short sW = 16;
-
- g_soft.lx0 = GETLEs16(&sgpuData[2]);
- g_soft.ly0 = GETLEs16(&sgpuData[3]);
-
- if (!(g_prim.dwActFixes & 8))
- AdjustCoord1();
-
- // x and y of start
- g_soft.ly2 = g_soft.ly3 = g_soft.ly0 + sH + g_gpu.dsp.DrawOffset.y;
- g_soft.ly0 = g_soft.ly1 = g_soft.ly0 + g_gpu.dsp.DrawOffset.y;
- g_soft.lx1 = g_soft.lx2 = g_soft.lx0 + sW + g_gpu.dsp.DrawOffset.x;
- g_soft.lx0 = g_soft.lx3 = g_soft.lx0 + g_gpu.dsp.DrawOffset.x;
-
- g_soft.DrawSemiTrans = (SEMITRANSBIT(GETLE32(&gpuData[0]))) ? 1 : 0;
-
- FillSoftwareAreaTrans(g_soft.lx0, g_soft.ly0, g_soft.lx2, g_soft.ly2,
- BGR24to16(GETLE32(&gpuData[0]))); // Takes Start and Offset
-
-}
-
-////////////////////////////////////////////////////////////////////////
-// cmd: small sprite (textured rect)
-////////////////////////////////////////////////////////////////////////
-
-static void primSprt8(unsigned char * baseAddr) {
- uint32_t *gpuData = ((uint32_t *) baseAddr);
- short *sgpuData = ((short *) baseAddr);
-
- g_soft.lx0 = GETLEs16(&sgpuData[2]);
- g_soft.ly0 = GETLEs16(&sgpuData[3]);
-
- if (!(g_prim.dwActFixes & 8))
- AdjustCoord1();
-
- SetRenderMode(GETLE32(&gpuData[0]));
-
- if (g_prim.bUsingTWin)
- DrawSoftwareSpriteTWin(baseAddr, 8, 8);
- else if (g_prim.usMirror)
- DrawSoftwareSpriteMirror(baseAddr, 8, 8);
- else
- DrawSoftwareSprite(baseAddr, 8, 8, baseAddr[8], baseAddr[9]);
-
-}
-
-////////////////////////////////////////////////////////////////////////
-// cmd: medium sprite (textured rect)
-////////////////////////////////////////////////////////////////////////
-
-static void primSprt16(unsigned char * baseAddr) {
- uint32_t *gpuData = ((uint32_t *) baseAddr);
- short *sgpuData = ((short *) baseAddr);
-
- g_soft.lx0 = GETLEs16(&sgpuData[2]);
- g_soft.ly0 = GETLEs16(&sgpuData[3]);
-
- if (!(g_prim.dwActFixes & 8))
- AdjustCoord1();
-
- SetRenderMode(GETLE32(&gpuData[0]));
-
- if (g_prim.bUsingTWin)
- DrawSoftwareSpriteTWin(baseAddr, 16, 16);
- else if (g_prim.usMirror)
- DrawSoftwareSpriteMirror(baseAddr, 16, 16);
- else
- DrawSoftwareSprite(baseAddr, 16, 16, baseAddr[8], baseAddr[9]);
-
-}
-
-////////////////////////////////////////////////////////////////////////
-// cmd: free-size sprite (textured rect)
-////////////////////////////////////////////////////////////////////////
-
-// func used on texture coord wrap
-static void primSprtSRest(unsigned char * baseAddr, unsigned short type) {
- uint32_t *gpuData = ((uint32_t *) baseAddr);
- short *sgpuData = ((short *) baseAddr);
- unsigned short sTypeRest = 0;
-
- short s;
- short sX = GETLEs16(&sgpuData[2]);
- short sY = GETLEs16(&sgpuData[3]);
- short sW = GETLEs16(&sgpuData[6]) & 0x3ff;
- short sH = GETLEs16(&sgpuData[7]) & 0x1ff;
- short tX = baseAddr[8];
- short tY = baseAddr[9];
-
- switch (type) {
- case 1:
- s = 256 - baseAddr[8];
- sW -= s;
- sX += s;
- tX = 0;
- break;
- case 2:
- s = 256 - baseAddr[9];
- sH -= s;
- sY += s;
- tY = 0;
- break;
- case 3:
- s = 256 - baseAddr[8];
- sW -= s;
- sX += s;
- tX = 0;
- s = 256 - baseAddr[9];
- sH -= s;
- sY += s;
- tY = 0;
- break;
- case 4:
- s = 512 - baseAddr[8];
- sW -= s;
- sX += s;
- tX = 0;
- break;
- case 5:
- s = 512 - baseAddr[9];
- sH -= s;
- sY += s;
- tY = 0;
- break;
- case 6:
- s = 512 - baseAddr[8];
- sW -= s;
- sX += s;
- tX = 0;
- s = 512 - baseAddr[9];
- sH -= s;
- sY += s;
- tY = 0;
- break;
- }
-
- SetRenderMode(GETLE32(&gpuData[0]));
-
- if (tX + sW > 256) {
- sW = 256 - tX;
- sTypeRest += 1;
- }
- if (tY + sH > 256) {
- sH = 256 - tY;
- sTypeRest += 2;
- }
-
- g_soft.lx0 = sX;
- g_soft.ly0 = sY;
-
- if (!(g_prim.dwActFixes & 8))
- AdjustCoord1();
-
- DrawSoftwareSprite(baseAddr, sW, sH, tX, tY);
-
- if (sTypeRest && type < 4) {
- if (sTypeRest & 1 && type == 1)
- primSprtSRest(baseAddr, 4);
- if (sTypeRest & 2 && type == 2)
- primSprtSRest(baseAddr, 5);
- if (sTypeRest == 3 && type == 3)
- primSprtSRest(baseAddr, 6);
- }
-
-}
-
-////////////////////////////////////////////////////////////////////////
-
-static void primSprtS(unsigned char * baseAddr) {
- uint32_t *gpuData = ((uint32_t *) baseAddr);
- short *sgpuData = ((short *) baseAddr);
- short sW, sH;
-
- g_soft.lx0 = GETLEs16(&sgpuData[2]);
- g_soft.ly0 = GETLEs16(&sgpuData[3]);
-
- if (!(g_prim.dwActFixes & 8))
- AdjustCoord1();
-
- sW = GETLEs16(&sgpuData[6]) & 0x3ff;
- sH = GETLEs16(&sgpuData[7]) & 0x1ff;
-
- SetRenderMode(GETLE32(&gpuData[0]));
-
- if (g_prim.bUsingTWin)
- DrawSoftwareSpriteTWin(baseAddr, sW, sH);
- else if (g_prim.usMirror)
- DrawSoftwareSpriteMirror(baseAddr, sW, sH);
- else {
- unsigned short sTypeRest = 0;
- short tX = baseAddr[8];
- short tY = baseAddr[9];
-
- if (tX + sW > 256) {
- sW = 256 - tX;
- sTypeRest += 1;
- }
- if (tY + sH > 256) {
- sH = 256 - tY;
- sTypeRest += 2;
- }
-
- DrawSoftwareSprite(baseAddr, sW, sH, tX, tY);
-
- if (sTypeRest) {
- if (sTypeRest & 1)
- primSprtSRest(baseAddr, 1);
- if (sTypeRest & 2)
- primSprtSRest(baseAddr, 2);
- if (sTypeRest == 3)
- primSprtSRest(baseAddr, 3);
- }
-
- }
-
-}
-
-////////////////////////////////////////////////////////////////////////
-// cmd: flat shaded Poly4
-////////////////////////////////////////////////////////////////////////
-
-static void primPolyF4(unsigned char *baseAddr) {
- uint32_t *gpuData = ((uint32_t *) baseAddr);
- short *sgpuData = ((short *) baseAddr);
-
- g_soft.lx0 = GETLEs16(&sgpuData[2]);
- g_soft.ly0 = GETLEs16(&sgpuData[3]);
- g_soft.lx1 = GETLEs16(&sgpuData[4]);
- g_soft.ly1 = GETLEs16(&sgpuData[5]);
- g_soft.lx2 = GETLEs16(&sgpuData[6]);
- g_soft.ly2 = GETLEs16(&sgpuData[7]);
- g_soft.lx3 = GETLEs16(&sgpuData[8]);
- g_soft.ly3 = GETLEs16(&sgpuData[9]);
-
- if (!(g_prim.dwActFixes & 8)) {
- AdjustCoord4();
- if (CheckCoord4())
- return;
- }
-
- offsetPSX4();
- g_soft.DrawSemiTrans = (SEMITRANSBIT(GETLE32(&gpuData[0]))) ? 1 : 0;
-
- drawPoly4F(GETLE32(&gpuData[0]));
-
-}
-
-////////////////////////////////////////////////////////////////////////
-// cmd: smooth shaded Poly4
-////////////////////////////////////////////////////////////////////////
-
-static void primPolyG4(unsigned char * baseAddr) {
- uint32_t *gpuData = (uint32_t *) baseAddr;
- short *sgpuData = ((short *) baseAddr);
-
- g_soft.lx0 = GETLEs16(&sgpuData[2]);
- g_soft.ly0 = GETLEs16(&sgpuData[3]);
- g_soft.lx1 = GETLEs16(&sgpuData[6]);
- g_soft.ly1 = GETLEs16(&sgpuData[7]);
- g_soft.lx2 = GETLEs16(&sgpuData[10]);
- g_soft.ly2 = GETLEs16(&sgpuData[11]);
- g_soft.lx3 = GETLEs16(&sgpuData[14]);
- g_soft.ly3 = GETLEs16(&sgpuData[15]);
-
- if (!(g_prim.dwActFixes & 8)) {
- AdjustCoord4();
- if (CheckCoord4())
- return;
- }
-
- offsetPSX4();
- g_soft.DrawSemiTrans = (SEMITRANSBIT(GETLE32(&gpuData[0]))) ? 1 : 0;
-
- drawPoly4G(GETLE32(&gpuData[0]), GETLE32(&gpuData[2]),
- GETLE32(&gpuData[4]), GETLE32(&gpuData[6]));
-
-}
-
-////////////////////////////////////////////////////////////////////////
-// cmd: flat shaded Texture3
-////////////////////////////////////////////////////////////////////////
-
-static void primPolyFT3(unsigned char * baseAddr) {
- uint32_t *gpuData = ((uint32_t *) baseAddr);
- short *sgpuData = ((short *) baseAddr);
-
- g_soft.lx0 = GETLEs16(&sgpuData[2]);
- g_soft.ly0 = GETLEs16(&sgpuData[3]);
- g_soft.lx1 = GETLEs16(&sgpuData[6]);
- g_soft.ly1 = GETLEs16(&sgpuData[7]);
- g_soft.lx2 = GETLEs16(&sgpuData[10]);
- g_soft.ly2 = GETLEs16(&sgpuData[11]);
-
- g_draw.lLowerpart = GETLE32(&gpuData[4]) >> 16;
- UpdateGlobalTP((unsigned short) g_draw.lLowerpart);
-
- if (!(g_prim.dwActFixes & 8)) {
- AdjustCoord3();
- if (CheckCoord3())
- return;
- }
-
- offsetPSX3();
- SetRenderMode(GETLE32(&gpuData[0]));
-
- drawPoly3FT(baseAddr);
-
-}
-
-////////////////////////////////////////////////////////////////////////
-// cmd: flat shaded Texture4
-////////////////////////////////////////////////////////////////////////
-
-static void primPolyFT4(unsigned char * baseAddr) {
- uint32_t *gpuData = ((uint32_t *) baseAddr);
- short *sgpuData = ((short *) baseAddr);
-
- g_soft.lx0 = GETLEs16(&sgpuData[2]);
- g_soft.ly0 = GETLEs16(&sgpuData[3]);
- g_soft.lx1 = GETLEs16(&sgpuData[6]);
- g_soft.ly1 = GETLEs16(&sgpuData[7]);
- g_soft.lx2 = GETLEs16(&sgpuData[10]);
- g_soft.ly2 = GETLEs16(&sgpuData[11]);
- g_soft.lx3 = GETLEs16(&sgpuData[14]);
- g_soft.ly3 = GETLEs16(&sgpuData[15]);
-
- g_draw.lLowerpart = GETLE32(&gpuData[4]) >> 16;
- UpdateGlobalTP((unsigned short) g_draw.lLowerpart);
-
- if (!(g_prim.dwActFixes & 8)) {
- AdjustCoord4();
- if (CheckCoord4())
- return;
- }
-
- offsetPSX4();
-
- SetRenderMode(GETLE32(&gpuData[0]));
-
- drawPoly4FT(baseAddr);
-
-}
-
-////////////////////////////////////////////////////////////////////////
-// cmd: smooth shaded Texture3
-////////////////////////////////////////////////////////////////////////
-
-static void primPolyGT3(unsigned char *baseAddr) {
- uint32_t *gpuData = ((uint32_t *) baseAddr);
- short *sgpuData = ((short *) baseAddr);
-
- g_soft.lx0 = GETLEs16(&sgpuData[2]);
- g_soft.ly0 = GETLEs16(&sgpuData[3]);
- g_soft.lx1 = GETLEs16(&sgpuData[8]);
- g_soft.ly1 = GETLEs16(&sgpuData[9]);
- g_soft.lx2 = GETLEs16(&sgpuData[14]);
- g_soft.ly2 = GETLEs16(&sgpuData[15]);
-
- g_draw.lLowerpart = GETLE32(&gpuData[5]) >> 16;
- UpdateGlobalTP((unsigned short) g_draw.lLowerpart);
-
- if (!(g_prim.dwActFixes & 8)) {
- AdjustCoord3();
- if (CheckCoord3())
- return;
- }
-
- offsetPSX3();
- g_soft.DrawSemiTrans = (SEMITRANSBIT(GETLE32(&gpuData[0]))) ? 1 : 0;
-
- if (SHADETEXBIT(GETLE32(&gpuData[0]))) {
- gpuData[0] = (gpuData[0] & HOST2LE32(0xff000000))
- |HOST2LE32(0x00808080);
- gpuData[3] = (gpuData[3] & HOST2LE32(0xff000000))
- |HOST2LE32(0x00808080);
- gpuData[6] = (gpuData[6] & HOST2LE32(0xff000000))
- |HOST2LE32(0x00808080);
- }
-
- drawPoly3GT(baseAddr);
-
-}
-
-////////////////////////////////////////////////////////////////////////
-// cmd: smooth shaded Poly3
-////////////////////////////////////////////////////////////////////////
-
-static void primPolyG3(unsigned char *baseAddr) {
- uint32_t *gpuData = ((uint32_t *) baseAddr);
- short *sgpuData = ((short *) baseAddr);
-
- g_soft.lx0 = GETLEs16(&sgpuData[2]);
- g_soft.ly0 = GETLEs16(&sgpuData[3]);
- g_soft.lx1 = GETLEs16(&sgpuData[6]);
- g_soft.ly1 = GETLEs16(&sgpuData[7]);
- g_soft.lx2 = GETLEs16(&sgpuData[10]);
- g_soft.ly2 = GETLEs16(&sgpuData[11]);
-
- if (!(g_prim.dwActFixes & 8)) {
- AdjustCoord3();
- if (CheckCoord3())
- return;
- }
-
- offsetPSX3();
- g_soft.DrawSemiTrans = (SEMITRANSBIT(GETLE32(&gpuData[0]))) ? 1 : 0;
-
- drawPoly3G(GETLE32(&gpuData[0]), GETLE32(&gpuData[2]), GETLE32(&gpuData[4]));
-
-}
-
-////////////////////////////////////////////////////////////////////////
-// cmd: smooth shaded Texture4
-////////////////////////////////////////////////////////////////////////
-
-static void primPolyGT4(unsigned char *baseAddr) {
- uint32_t *gpuData = ((uint32_t *) baseAddr);
- short *sgpuData = ((short *) baseAddr);
-
- g_soft.lx0 = GETLEs16(&sgpuData[2]);
- g_soft.ly0 = GETLEs16(&sgpuData[3]);
- g_soft.lx1 = GETLEs16(&sgpuData[8]);
- g_soft.ly1 = GETLEs16(&sgpuData[9]);
- g_soft.lx2 = GETLEs16(&sgpuData[14]);
- g_soft.ly2 = GETLEs16(&sgpuData[15]);
- g_soft.lx3 = GETLEs16(&sgpuData[20]);
- g_soft.ly3 = GETLEs16(&sgpuData[21]);
-
- g_draw.lLowerpart = GETLE32(&gpuData[5]) >> 16;
- UpdateGlobalTP((unsigned short) g_draw.lLowerpart);
-
- if (!(g_prim.dwActFixes & 8)) {
- AdjustCoord4();
- if (CheckCoord4())
- return;
- }
-
- offsetPSX4();
- g_soft.DrawSemiTrans = (SEMITRANSBIT(GETLE32(&gpuData[0]))) ? 1 : 0;
-
- if (SHADETEXBIT(GETLE32(&gpuData[0]))) {
- gpuData[0] = (gpuData[0] & HOST2LE32(0xff000000))
- |HOST2LE32(0x00808080);
- gpuData[3] = (gpuData[3] & HOST2LE32(0xff000000))
- |HOST2LE32(0x00808080);
- gpuData[6] = (gpuData[6] & HOST2LE32(0xff000000))
- |HOST2LE32(0x00808080);
- gpuData[9] = (gpuData[9] & HOST2LE32(0xff000000))
- |HOST2LE32(0x00808080);
- }
-
- drawPoly4GT(baseAddr);
-
-}
-
-////////////////////////////////////////////////////////////////////////
-// cmd: smooth shaded Poly3
-////////////////////////////////////////////////////////////////////////
-
-static void primPolyF3(unsigned char *baseAddr) {
- uint32_t *gpuData = ((uint32_t *) baseAddr);
- short *sgpuData = ((short *) baseAddr);
-
- g_soft.lx0 = GETLEs16(&sgpuData[2]);
- g_soft.ly0 = GETLEs16(&sgpuData[3]);
- g_soft.lx1 = GETLEs16(&sgpuData[4]);
- g_soft.ly1 = GETLEs16(&sgpuData[5]);
- g_soft.lx2 = GETLEs16(&sgpuData[6]);
- g_soft.ly2 = GETLEs16(&sgpuData[7]);
-
- if (!(g_prim.dwActFixes & 8)) {
- AdjustCoord3();
- if (CheckCoord3())
- return;
- }
-
- offsetPSX3();
- SetRenderMode(GETLE32(&gpuData[0]));
-
- drawPoly3F(GETLE32(&gpuData[0]));
-
-}
-
-////////////////////////////////////////////////////////////////////////
-// cmd: skipping shaded polylines
-////////////////////////////////////////////////////////////////////////
-
-#if 0
-static void primLineGSkip(unsigned char *baseAddr) {
- uint32_t *gpuData = ((uint32_t *) baseAddr);
- int iMax = 255;
- int i = 2;
-
- g_soft.ly1 = (short) ((GETLE32(&gpuData[1]) >> 16) & 0xffff);
- g_soft.lx1 = (short) (GETLE32(&gpuData[1]) & 0xffff);
-
- while (!(((GETLE32(&gpuData[i]) & 0xF000F000) == 0x50005000) && i >= 4)) {
- i++;
- g_soft.ly1 = (short) ((GETLE32(&gpuData[i]) >> 16) & 0xffff);
- g_soft.lx1 = (short) (GETLE32(&gpuData[i]) & 0xffff);
- i++;
- if (i > iMax)
- break;
- }
-}
-#endif
-
-////////////////////////////////////////////////////////////////////////
-// cmd: shaded polylines
-////////////////////////////////////////////////////////////////////////
-
-static void primLineGEx(unsigned char *baseAddr) {
- uint32_t *gpuData = ((uint32_t *) baseAddr);
- int iMax = 255;
- uint32_t lc0, lc1;
- short slx0, slx1, sly0, sly1;
- int i = 2;
- char bDraw = 1;
-
- sly1 = (short) ((GETLE32(&gpuData[1]) >> 16) & 0xffff);
- slx1 = (short) (GETLE32(&gpuData[1]) & 0xffff);
-
- if (!(g_prim.dwActFixes & 8)) {
- slx1 = (short) (((int) slx1 << SIGNSHIFT) >> SIGNSHIFT);
- sly1 = (short) (((int) sly1 << SIGNSHIFT) >> SIGNSHIFT);
- }
-
- lc1 = gpuData[0] & 0xffffff;
-
- g_soft.DrawSemiTrans = (SEMITRANSBIT(GETLE32(&gpuData[0]))) ? 1 : 0;
-
- while (!(((GETLE32(&gpuData[i]) & 0xF000F000) == 0x50005000) && i >= 4)) {
- sly0 = sly1;
- slx0 = slx1;
- lc0 = lc1;
- lc1 = GETLE32(&gpuData[i]) & 0xffffff;
-
- i++;
-
- // no check needed on gshaded polyline positions
- // if((gpuData[i] & 0xF000F000) == 0x50005000) break;
-
- sly1 = (short) ((GETLE32(&gpuData[i]) >> 16) & 0xffff);
- slx1 = (short) (GETLE32(&gpuData[i]) & 0xffff);
-
- if (!(g_prim.dwActFixes & 8)) {
- slx1 = (short) (((int) slx1 << SIGNSHIFT) >> SIGNSHIFT);
- sly1 = (short) (((int) sly1 << SIGNSHIFT) >> SIGNSHIFT);
- if (CheckCoordL(slx0, sly0, slx1, sly1))
- bDraw = 0;
- else
- bDraw = 1;
- }
-
- if ((g_soft.lx0 != g_soft.lx1) || (g_soft.ly0 != g_soft.ly1)) {
- g_soft.ly0 = sly0;
- g_soft.lx0 = slx0;
- g_soft.ly1 = sly1;
- g_soft.lx1 = slx1;
-
- offsetPSX2();
- if (bDraw)
- DrawSoftwareLineShade(lc0, lc1);
- }
- i++;
- if (i > iMax)
- break;
- }
-
-}
-
-////////////////////////////////////////////////////////////////////////
-// cmd: shaded polyline2
-////////////////////////////////////////////////////////////////////////
-
-static void primLineG2(unsigned char *baseAddr) {
- uint32_t *gpuData = ((uint32_t *) baseAddr);
- short *sgpuData = ((short *) baseAddr);
-
- g_soft.lx0 = GETLEs16(&sgpuData[2]);
- g_soft.ly0 = GETLEs16(&sgpuData[3]);
- g_soft.lx1 = GETLEs16(&sgpuData[6]);
- g_soft.ly1 = GETLEs16(&sgpuData[7]);
-
- if (!(g_prim.dwActFixes & 8)) {
- AdjustCoord2();
- if (CheckCoord2())
- return;
- }
-
- if ((g_soft.lx0 == g_soft.lx1) && (g_soft.ly0 == g_soft.ly1)) {
- g_soft.lx1++;
- g_soft.ly1++;
- }
-
- g_soft.DrawSemiTrans = (SEMITRANSBIT(GETLE32(&gpuData[0]))) ? 1 : 0;
- offsetPSX2();
- DrawSoftwareLineShade(GETLE32(&gpuData[0]), GETLE32(&gpuData[2]));
-
-}
-
-////////////////////////////////////////////////////////////////////////
-// cmd: skipping flat polylines
-////////////////////////////////////////////////////////////////////////
-
-#if 0
-static void primLineFSkip(unsigned char *baseAddr) {
- uint32_t *gpuData = ((uint32_t *) baseAddr);
- int i = 2, iMax = 255;
-
- g_soft.ly1 = (short) ((GETLE32(&gpuData[1]) >> 16) & 0xffff);
- g_soft.lx1 = (short) (GETLE32(&gpuData[1]) & 0xffff);
-
- while (!(((GETLE32(&gpuData[i]) & 0xF000F000) == 0x50005000) && i >= 3)) {
- g_soft.ly1 = (short) ((GETLE32(&gpuData[i]) >> 16) & 0xffff);
- g_soft.lx1 = (short) (GETLE32(&gpuData[i]) & 0xffff);
- i++;
- if (i > iMax)
- break;
- }
-}
-#endif
-
-////////////////////////////////////////////////////////////////////////
-// cmd: drawing flat polylines
-////////////////////////////////////////////////////////////////////////
-
-static void primLineFEx(unsigned char *baseAddr) {
- uint32_t *gpuData = ((uint32_t *) baseAddr);
- int iMax;
- short slx0, slx1, sly0, sly1;
- int i = 2;
- char bDraw = 1;
-
- iMax = 255;
-
- sly1 = (short) ((GETLE32(&gpuData[1]) >> 16) & 0xffff);
- slx1 = (short) (GETLE32(&gpuData[1]) & 0xffff);
- if (!(g_prim.dwActFixes & 8)) {
- slx1 = (short) (((int) slx1 << SIGNSHIFT) >> SIGNSHIFT);
- sly1 = (short) (((int) sly1 << SIGNSHIFT) >> SIGNSHIFT);
- }
-
- SetRenderMode(GETLE32(&gpuData[0]));
-
- while (!(((GETLE32(&gpuData[i]) & 0xF000F000) == 0x50005000) && i >= 3)) {
- sly0 = sly1;
- slx0 = slx1;
- sly1 = (short) ((GETLE32(&gpuData[i]) >> 16) & 0xffff);
- slx1 = (short) (GETLE32(&gpuData[i]) & 0xffff);
- if (!(g_prim.dwActFixes & 8)) {
- slx1 = (short) (((int) slx1 << SIGNSHIFT) >> SIGNSHIFT);
- sly1 = (short) (((int) sly1 << SIGNSHIFT) >> SIGNSHIFT);
-
- if (CheckCoordL(slx0, sly0, slx1, sly1))
- bDraw = 0;
- else
- bDraw = 1;
- }
-
- g_soft.ly0 = sly0;
- g_soft.lx0 = slx0;
- g_soft.ly1 = sly1;
- g_soft.lx1 = slx1;
-
- offsetPSX2();
- if (bDraw)
- DrawSoftwareLineFlat(GETLE32(&gpuData[0]));
-
- i++;
- if (i > iMax)
- break;
- }
-
-}
-
-////////////////////////////////////////////////////////////////////////
-// cmd: drawing flat polyline2
-////////////////////////////////////////////////////////////////////////
-
-static void primLineF2(unsigned char *baseAddr) {
- uint32_t *gpuData = ((uint32_t *) baseAddr);
- short *sgpuData = ((short *) baseAddr);
-
- g_soft.lx0 = GETLEs16(&sgpuData[2]);
- g_soft.ly0 = GETLEs16(&sgpuData[3]);
- g_soft.lx1 = GETLEs16(&sgpuData[4]);
- g_soft.ly1 = GETLEs16(&sgpuData[5]);
-
- if (!(g_prim.dwActFixes & 8)) {
- AdjustCoord2();
- if (CheckCoord2())
- return;
- }
-
- if ((g_soft.lx0 == g_soft.lx1) && (g_soft.ly0 == g_soft.ly1)) {
- g_soft.lx1++;
- g_soft.ly1++;
- }
-
- offsetPSX2();
- SetRenderMode(GETLE32(&gpuData[0]));
-
- DrawSoftwareLineFlat(GETLE32(&gpuData[0]));
-
-}
-
-////////////////////////////////////////////////////////////////////////
-// cmd: well, easiest command... not implemented
-////////////////////////////////////////////////////////////////////////
-
-static void primNI(unsigned char *bA) {
- fprintf(stderr, "Unknow GPU func \n");
-}
-
-////////////////////////////////////////////////////////////////////////
-// cmd func ptr table
-////////////////////////////////////////////////////////////////////////
-
-
-void (*primTableJ[256])(unsigned char *) = {
- /* 00 */
- primNI,
- primNI,
- primBlkFill,
- primNI,
- /* 04 */
- primNI,
- primNI,
- primNI,
- primNI,
- /* 08 */
- primNI,
- primNI,
- primNI,
- primNI,
- primNI,
- primNI,
- primNI,
- primNI,
- // 10
- primNI,
- primNI,
- primNI,
- primNI,
- primNI,
- primNI,
- primNI,
- primNI,
- // 18
- primNI,
- primNI,
- primNI,
- primNI,
- primNI,
- primNI,
- primNI,
- primNI,
- // 20
- primPolyF3,
- primPolyF3,
- primPolyF3,
- primPolyF3,
- primPolyFT3,
- primPolyFT3,
- primPolyFT3,
- primPolyFT3,
- // 28
- primPolyF4,
- primPolyF4,
- primPolyF4,
- primPolyF4,
- primPolyFT4,
- primPolyFT4,
- primPolyFT4,
- primPolyFT4,
- // 30
- primPolyG3,
- primPolyG3,
- primPolyG3,
- primPolyG3,
- primPolyGT3,
- primPolyGT3,
- primPolyGT3,
- primPolyGT3,
- // 38
- primPolyG4,
- primPolyG4,
- primPolyG4,
- primPolyG4,
- primPolyGT4,
- primPolyGT4,
- primPolyGT4,
- primPolyGT4,
- // 40
- primLineF2,
- primLineF2,
- primLineF2,
- primLineF2,
- primNI,
- primNI,
- primNI,
- primNI,
- // 48
- primLineFEx,
- primLineFEx,
- primLineFEx,
- primLineFEx,
- primLineFEx,
- primLineFEx,
- primLineFEx,
- primLineFEx,
- // 50
- primLineG2, primLineG2,
- primLineG2,
- primLineG2,
- primNI,
- primNI,
- primNI,
- primNI,
- // 58
- primLineGEx, primLineGEx, primLineGEx,
- primLineGEx,
- primLineGEx,
- primLineGEx,
- primLineGEx,
- primLineGEx,
- // 60
- primTileS, primTileS, primTileS, primTileS,
- primSprtS,
- primSprtS,
- primSprtS,
- primSprtS,
- // 68
- primTile1, primTile1, primTile1, primTile1, primNI,
- primNI,
- primNI,
- primNI,
- // 70
- primTile8, primTile8, primTile8, primTile8, primSprt8, primSprt8,
- primSprt8,
- primSprt8,
- // 78
- primTile16, primTile16, primTile16, primTile16, primSprt16, primSprt16,
- primSprt16, primSprt16,
- // 80
- primMoveImage, primNI, primNI, primNI, primNI, primNI, primNI, primNI,
- // 88
- primNI, primNI, primNI, primNI, primNI, primNI, primNI, primNI,
- // 90
- primNI, primNI, primNI, primNI, primNI, primNI, primNI, primNI,
- // 98
- primNI, primNI, primNI, primNI, primNI, primNI, primNI, primNI,
- // a0
- primLoadImage, primNI, primNI, primNI, primNI, primNI, primNI, primNI,
- // a8
- primNI, primNI, primNI, primNI, primNI, primNI, primNI, primNI,
- // b0
- primNI, primNI, primNI, primNI, primNI, primNI, primNI, primNI,
- // b8
- primNI, primNI, primNI, primNI, primNI, primNI, primNI, primNI,
- // c0
- primStoreImage, primNI, primNI, primNI, primNI, primNI, primNI, primNI,
- // c8
- primNI, primNI, primNI, primNI, primNI, primNI, primNI, primNI,
- // d0
- primNI, primNI, primNI, primNI, primNI, primNI, primNI, primNI,
- // d8
- primNI, primNI, primNI, primNI, primNI, primNI, primNI, primNI,
- // e0
- primNI, cmdTexturePage, cmdTextureWindow, cmdDrawAreaStart,
- cmdDrawAreaEnd, cmdDrawOffset, cmdSTP, primNI,
- // e8
- primNI, primNI, primNI, primNI, primNI, primNI, primNI, primNI,
- // f0
- primNI, primNI, primNI, primNI, primNI, primNI, primNI, primNI,
- // f8
- primNI, primNI, primNI, primNI, primNI, primNI, primNI, primNI };
-
+/***************************************************************************
+ prim.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 <stdio.h>
+
+#include "globals.h"
+#include "swap.h"
+
+#define INFO_TW 0
+#define INFO_DRAWSTART 1
+#define INFO_DRAWEND 2
+#define INFO_DRAWOFF 3
+
+////////////////////////////////////////////////////////////////////////
+// globals
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+// Some ASM color convertion by LEWPY
+////////////////////////////////////////////////////////////////////////
+
+#ifdef USE_NASM
+
+#define BGR24to16 i386_BGR24to16
+__inline unsigned short BGR24to16 (uint32_t BGR);
+
+#else
+
+inline unsigned short BGR24to16(uint32_t BGR) {
+ return (unsigned short) (((BGR >> 3) & 0x1f) | ((BGR & 0xf80000) >> 9)
+ | ((BGR & 0xf800) >> 6));
+}
+
+#endif
+
+////////////////////////////////////////////////////////////////////////
+// Update global TP infos
+////////////////////////////////////////////////////////////////////////
+
+inline void UpdateGlobalTP(unsigned short gdata) {
+ g_soft.GlobalTextAddrX = (gdata << 6) & 0x3c0; // texture addr
+
+ if (512 == 1024) {
+ if (1 == 2) {
+ g_soft.GlobalTextAddrY = ((gdata & 0x60) << 3);
+ //g_zn.GlobalTextIL = (gdata & 0x2000) >> 13;
+ g_soft.GlobalTextABR = (unsigned short) ((gdata >> 7) & 0x3);
+ g_soft.GlobalTextTP = (gdata >> 9) & 0x3;
+ if (g_soft.GlobalTextTP == 3)
+ g_soft.GlobalTextTP = 2;
+ g_prim.usMirror = 0;
+ g_gpu.status_reg = (g_gpu.status_reg & 0xffffe000) | (gdata
+ & 0x1fff);
+
+ // tekken dithering? right now only if dithering is forced by user
+ if (g_cfg.Dithering == 2)
+ g_prim.iDither = 2;
+ else
+ g_prim.iDither = 0;
+
+ return;
+ } else {
+ g_soft.GlobalTextAddrY = (unsigned short) (((gdata << 4) & 0x100)
+ | ((gdata >> 2) & 0x200));
+ }
+ } else
+ g_soft.GlobalTextAddrY = (gdata << 4) & 0x100;
+
+ g_soft.GlobalTextTP = (gdata >> 7) & 0x3; // tex mode (4,8,15)
+
+ if (g_soft.GlobalTextTP == 3)
+ g_soft.GlobalTextTP = 2; // seen in Wild9 :(
+
+ g_soft.GlobalTextABR = (gdata >> 5) & 0x3; // blend mode
+
+ g_gpu.status_reg &= ~0x000001ff; // Clear the necessary bits
+ g_gpu.status_reg |= (gdata & 0x01ff); // set the necessary bits
+
+ switch (g_cfg.Dithering) {
+ case 0:
+ g_prim.iDither = 0;
+ break;
+ case 1:
+ if (g_gpu.status_reg & 0x0200)
+ g_prim.iDither = 2;
+ else
+ g_prim.iDither = 0;
+ break;
+ case 2:
+ g_prim.iDither = 2;
+ break;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+inline void SetRenderMode(uint32_t DrawAttributes) {
+ g_soft.DrawSemiTrans = (SEMITRANSBIT(DrawAttributes)) ? 1 : 0;
+
+ if (SHADETEXBIT(DrawAttributes)) {
+ g_soft.g_m1 = g_soft.g_m2 = g_soft.g_m3 = 128;
+ } else {
+ if ((g_prim.dwActFixes & 4) && ((DrawAttributes & 0x00ffffff) == 0))
+ DrawAttributes |= 0x007f7f7f;
+
+ g_soft.g_m1 = (short) (DrawAttributes & 0xff);
+ g_soft.g_m2 = (short) ((DrawAttributes >> 8) & 0xff);
+ g_soft.g_m3 = (short) ((DrawAttributes >> 16) & 0xff);
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+// oki, here are the psx gpu coord rules: poly coords are
+// 11 bit signed values (-1024...1023). If the x or y distance
+// exceeds 1024, the polygon will not be drawn.
+// Since quads are treated as two triangles by the real gpu,
+// this 'discard rule' applies to each of the quad's triangle
+// (so one triangle can be drawn, the other one discarded).
+// Also, y drawing is wrapped at 512 one time,
+// then it will get negative (and therefore not drawn). The
+// 'CheckCoord' funcs are a simple (not comlete!) approach to
+// do things right, I will add a better detection soon... the
+// current approach will be easier to do in hw/accel plugins, imho
+
+// 11 bit signed
+#define SIGNSHIFT 21
+#define CHKMAX_X 1024
+#define CHKMAX_Y 512
+
+void AdjustCoord4() {
+ g_soft.lx0 = (short) (((int) g_soft.lx0 << SIGNSHIFT) >> SIGNSHIFT);
+ g_soft.lx1 = (short) (((int) g_soft.lx1 << SIGNSHIFT) >> SIGNSHIFT);
+ g_soft.lx2 = (short) (((int) g_soft.lx2 << SIGNSHIFT) >> SIGNSHIFT);
+ g_soft.lx3 = (short) (((int) g_soft.lx3 << SIGNSHIFT) >> SIGNSHIFT);
+ g_soft.ly0 = (short) (((int) g_soft.ly0 << SIGNSHIFT) >> SIGNSHIFT);
+ g_soft.ly1 = (short) (((int) g_soft.ly1 << SIGNSHIFT) >> SIGNSHIFT);
+ g_soft.ly2 = (short) (((int) g_soft.ly2 << SIGNSHIFT) >> SIGNSHIFT);
+ g_soft.ly3 = (short) (((int) g_soft.ly3 << SIGNSHIFT) >> SIGNSHIFT);
+}
+
+void AdjustCoord3() {
+ g_soft.lx0 = (short) (((int) g_soft.lx0 << SIGNSHIFT) >> SIGNSHIFT);
+ g_soft.lx1 = (short) (((int) g_soft.lx1 << SIGNSHIFT) >> SIGNSHIFT);
+ g_soft.lx2 = (short) (((int) g_soft.lx2 << SIGNSHIFT) >> SIGNSHIFT);
+ g_soft.ly0 = (short) (((int) g_soft.ly0 << SIGNSHIFT) >> SIGNSHIFT);
+ g_soft.ly1 = (short) (((int) g_soft.ly1 << SIGNSHIFT) >> SIGNSHIFT);
+ g_soft.ly2 = (short) (((int) g_soft.ly2 << SIGNSHIFT) >> SIGNSHIFT);
+}
+
+void AdjustCoord2() {
+ g_soft.lx0 = (short) (((int) g_soft.lx0 << SIGNSHIFT) >> SIGNSHIFT);
+ g_soft.lx1 = (short) (((int) g_soft.lx1 << SIGNSHIFT) >> SIGNSHIFT);
+ g_soft.ly0 = (short) (((int) g_soft.ly0 << SIGNSHIFT) >> SIGNSHIFT);
+ g_soft.ly1 = (short) (((int) g_soft.ly1 << SIGNSHIFT) >> SIGNSHIFT);
+}
+
+void AdjustCoord1() {
+ g_soft.lx0 = (short) (((int) g_soft.lx0 << SIGNSHIFT) >> SIGNSHIFT);
+ g_soft.ly0 = (short) (((int) g_soft.ly0 << SIGNSHIFT) >> SIGNSHIFT);
+
+ if (g_soft.lx0 < -512 && g_gpu.dsp.DrawOffset.x <= -512)
+ g_soft.lx0 += 2048;
+
+ if (g_soft.ly0 < -512 && g_gpu.dsp.DrawOffset.y <= -512)
+ g_soft.ly0 += 2048;
+}
+
+/*
+ ////////////////////////////////////////////////////////////////////////
+ // special checks... nascar, syphon filter 2, mgs
+ ////////////////////////////////////////////////////////////////////////
+
+ // xenogears FT4: not removed correctly right now... the tri 0,1,2
+ // should get removed, the tri 1,2,3 should stay... pfff
+
+ // x -466 1023 180 1023
+ // y 20 -228 222 -100
+
+ // 0 __1
+ // \ / \
+ // 2___3
+ */
+inline char CheckCoord4() {
+ if (g_soft.lx0 < 0) {
+ if (((g_soft.lx1 - g_soft.lx0) > CHKMAX_X)
+ || ((g_soft.lx2 - g_soft.lx0) > CHKMAX_X)) {
+ if (g_soft.lx3 < 0) {
+ if ((g_soft.lx1 - g_soft.lx3) > CHKMAX_X)
+ return 1;
+ if ((g_soft.lx2 - g_soft.lx3) > CHKMAX_X)
+ return 1;
+ }
+ }
+ }
+ if (g_soft.lx1 < 0) {
+ if ((g_soft.lx0 - g_soft.lx1) > CHKMAX_X)
+ return 1;
+ if ((g_soft.lx2 - g_soft.lx1) > CHKMAX_X)
+ return 1;
+ if ((g_soft.lx3 - g_soft.lx1) > CHKMAX_X)
+ return 1;
+ }
+ if (g_soft.lx2 < 0) {
+ if ((g_soft.lx0 - g_soft.lx2) > CHKMAX_X)
+ return 1;
+ if ((g_soft.lx1 - g_soft.lx2) > CHKMAX_X)
+ return 1;
+ if ((g_soft.lx3 - g_soft.lx2) > CHKMAX_X)
+ return 1;
+ }
+ if (g_soft.lx3 < 0) {
+ if (((g_soft.lx1 - g_soft.lx3) > CHKMAX_X)
+ || ((g_soft.lx2 - g_soft.lx3) > CHKMAX_X)) {
+ if (g_soft.lx0 < 0) {
+ if ((g_soft.lx1 - g_soft.lx0) > CHKMAX_X)
+ return 1;
+ if ((g_soft.lx2 - g_soft.lx0) > CHKMAX_X)
+ return 1;
+ }
+ }
+ }
+
+ if (g_soft.ly0 < 0) {
+ if ((g_soft.ly1 - g_soft.ly0) > CHKMAX_Y)
+ return 1;
+ if ((g_soft.ly2 - g_soft.ly0) > CHKMAX_Y)
+ return 1;
+ }
+ if (g_soft.ly1 < 0) {
+ if ((g_soft.ly0 - g_soft.ly1) > CHKMAX_Y)
+ return 1;
+ if ((g_soft.ly2 - g_soft.ly1) > CHKMAX_Y)
+ return 1;
+ if ((g_soft.ly3 - g_soft.ly1) > CHKMAX_Y)
+ return 1;
+ }
+ if (g_soft.ly2 < 0) {
+ if ((g_soft.ly0 - g_soft.ly2) > CHKMAX_Y)
+ return 1;
+ if ((g_soft.ly1 - g_soft.ly2) > CHKMAX_Y)
+ return 1;
+ if ((g_soft.ly3 - g_soft.ly2) > CHKMAX_Y)
+ return 1;
+ }
+ if (g_soft.ly3 < 0) {
+ if ((g_soft.ly1 - g_soft.ly3) > CHKMAX_Y)
+ return 1;
+ if ((g_soft.ly2 - g_soft.ly3) > CHKMAX_Y)
+ return 1;
+ }
+
+ return 0;
+}
+
+inline char CheckCoord3() {
+ if (g_soft.lx0 < 0) {
+ if ((g_soft.lx1 - g_soft.lx0) > CHKMAX_X)
+ return 1;
+ if ((g_soft.lx2 - g_soft.lx0) > CHKMAX_X)
+ return 1;
+ }
+ if (g_soft.lx1 < 0) {
+ if ((g_soft.lx0 - g_soft.lx1) > CHKMAX_X)
+ return 1;
+ if ((g_soft.lx2 - g_soft.lx1) > CHKMAX_X)
+ return 1;
+ }
+ if (g_soft.lx2 < 0) {
+ if ((g_soft.lx0 - g_soft.lx2) > CHKMAX_X)
+ return 1;
+ if ((g_soft.lx1 - g_soft.lx2) > CHKMAX_X)
+ return 1;
+ }
+ if (g_soft.ly0 < 0) {
+ if ((g_soft.ly1 - g_soft.ly0) > CHKMAX_Y)
+ return 1;
+ if ((g_soft.ly2 - g_soft.ly0) > CHKMAX_Y)
+ return 1;
+ }
+ if (g_soft.ly1 < 0) {
+ if ((g_soft.ly0 - g_soft.ly1) > CHKMAX_Y)
+ return 1;
+ if ((g_soft.ly2 - g_soft.ly1) > CHKMAX_Y)
+ return 1;
+ }
+ if (g_soft.ly2 < 0) {
+ if ((g_soft.ly0 - g_soft.ly2) > CHKMAX_Y)
+ return 1;
+ if ((g_soft.ly1 - g_soft.ly2) > CHKMAX_Y)
+ return 1;
+ }
+
+ return 0;
+}
+
+inline char CheckCoord2() {
+ if (g_soft.lx0 < 0) {
+ if ((g_soft.lx1 - g_soft.lx0) > CHKMAX_X)
+ return 1;
+ }
+ if (g_soft.lx1 < 0) {
+ if ((g_soft.lx0 - g_soft.lx1) > CHKMAX_X)
+ return 1;
+ }
+ if (g_soft.ly0 < 0) {
+ if ((g_soft.ly1 - g_soft.ly0) > CHKMAX_Y)
+ return 1;
+ }
+ if (g_soft.ly1 < 0) {
+ if ((g_soft.ly0 - g_soft.ly1) > CHKMAX_Y)
+ return 1;
+ }
+
+ return 0;
+}
+
+inline char CheckCoordL(short slx0, short sly0, short slx1, short sly1) {
+ if (slx0 < 0) {
+ if ((slx1 - slx0) > CHKMAX_X)
+ return 1;
+ }
+ if (slx1 < 0) {
+ if ((slx0 - slx1) > CHKMAX_X)
+ return 1;
+ }
+ if (sly0 < 0) {
+ if ((sly1 - sly0) > CHKMAX_Y)
+ return 1;
+ }
+ if (sly1 < 0) {
+ if ((sly0 - sly1) > CHKMAX_Y)
+ return 1;
+ }
+
+ return 0;
+}
+
+////////////////////////////////////////////////////////////////////////
+// mask stuff... used in silent hill
+////////////////////////////////////////////////////////////////////////
+
+void cmdSTP(unsigned char * baseAddr) {
+ uint32_t gdata = GETLE32(&((uint32_t*)baseAddr)[0]);
+
+ g_gpu.status_reg &= ~0x1800; // Clear the necessary bits
+ g_gpu.status_reg |= ((gdata & 0x03) << 11); // Set the necessary bits
+
+ if (gdata & 1) {
+ g_draw.sSetMask = 0x8000;
+ g_draw.lSetMask = 0x80008000;
+ } else {
+ g_draw.sSetMask = 0;
+ g_draw.lSetMask = 0;
+ }
+
+ if (gdata & 2)
+ g_draw.bCheckMask = 1;
+ else
+ g_draw.bCheckMask = 0;
+}
+
+////////////////////////////////////////////////////////////////////////
+// cmd: Set texture page infos
+////////////////////////////////////////////////////////////////////////
+
+void cmdTexturePage(unsigned char * baseAddr) {
+ uint32_t gdata = GETLE32(&((uint32_t*)baseAddr)[0]);
+
+ g_gpu.status_reg &= ~0x000007ff;
+ g_gpu.status_reg |= (gdata & 0x07ff);
+
+ g_prim.usMirror = (unsigned short) (gdata & 0x3000);
+
+ UpdateGlobalTP((unsigned short) gdata);
+ g_soft.GlobalTextREST = (gdata & 0x00ffffff) >> 9;
+}
+
+////////////////////////////////////////////////////////////////////////
+// cmd: turn on/off texture window
+////////////////////////////////////////////////////////////////////////
+
+void cmdTextureWindow(unsigned char *baseAddr) {
+ uint32_t gdata = GETLE32(&((uint32_t*)baseAddr)[0]);
+
+ uint32_t YAlign, XAlign;
+
+ g_gpu.lGPUInfoVals[INFO_TW] = gdata & 0xFFFFF;
+
+ if (gdata & 0x020)
+ g_prim.TWin.Position.y1 = 8; // xxxx1
+ else if (gdata & 0x040)
+ g_prim.TWin.Position.y1 = 16; // xxx10
+ else if (gdata & 0x080)
+ g_prim.TWin.Position.y1 = 32; // xx100
+ else if (gdata & 0x100)
+ g_prim.TWin.Position.y1 = 64; // x1000
+ else if (gdata & 0x200)
+ g_prim.TWin.Position.y1 = 128; // 10000
+ else
+ g_prim.TWin.Position.y1 = 256; // 00000
+
+ // Texture window size is determined by the least bit set of the relevant 5 bits
+
+ if (gdata & 0x001)
+ g_prim.TWin.Position.x1 = 8; // xxxx1
+ else if (gdata & 0x002)
+ g_prim.TWin.Position.x1 = 16; // xxx10
+ else if (gdata & 0x004)
+ g_prim.TWin.Position.x1 = 32; // xx100
+ else if (gdata & 0x008)
+ g_prim.TWin.Position.x1 = 64; // x1000
+ else if (gdata & 0x010)
+ g_prim.TWin.Position.x1 = 128; // 10000
+ else
+ g_prim.TWin.Position.x1 = 256; // 00000
+
+ // Re-calculate the bit field, because we can't trust what is passed in the data
+
+
+ YAlign = (uint32_t) (32 - (g_prim.TWin.Position.y1 >> 3));
+ XAlign = (uint32_t) (32 - (g_prim.TWin.Position.x1 >> 3));
+
+ // Absolute position of the start of the texture window
+
+ g_prim.TWin.Position.y0 = (short) (((gdata >> 15) & YAlign) << 3);
+ g_prim.TWin.Position.x0 = (short) (((gdata >> 10) & XAlign) << 3);
+
+ if ((g_prim.TWin.Position.x0 == 0 && // tw turned off
+ g_prim.TWin.Position.y0 == 0 && g_prim.TWin.Position.x1 == 0
+ && g_prim.TWin.Position.y1 == 0) || (g_prim.TWin.Position.x1 == 256
+ && g_prim.TWin.Position.y1 == 256)) {
+ g_prim.bUsingTWin = 0; // -> just do it
+ } else // otherwise
+ {
+ g_prim.bUsingTWin = 1; // -> tw turned on
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+// cmd: start of drawing area... primitives will be clipped inside
+////////////////////////////////////////////////////////////////////////
+
+
+void cmdDrawAreaStart(unsigned char * baseAddr) {
+ uint32_t gdata = GETLE32(&((uint32_t*)baseAddr)[0]);
+ g_prim.drawX = gdata & 0x3ff; // for soft drawing
+ g_gpu.lGPUInfoVals[INFO_DRAWSTART] = gdata & 0xFFFFF;
+ g_prim.drawY = (gdata >> 10) & 0x3ff;
+ if (g_prim.drawY >= 512)
+ g_prim.drawY = 511; // some security
+}
+
+////////////////////////////////////////////////////////////////////////
+// cmd: end of drawing area... primitives will be clipped inside
+////////////////////////////////////////////////////////////////////////
+
+void cmdDrawAreaEnd(unsigned char * baseAddr) {
+ uint32_t gdata = GETLE32(&((uint32_t*)baseAddr)[0]);
+
+ g_prim.drawW = gdata & 0x3ff; // for soft drawing
+
+ g_gpu.lGPUInfoVals[INFO_DRAWEND] = gdata & 0xFFFFF;
+ g_prim.drawH = (gdata >> 10) & 0x3ff;
+ if (g_prim.drawH >= 512)
+ g_prim.drawH = 511; // some security
+}
+
+////////////////////////////////////////////////////////////////////////
+// cmd: draw offset... will be added to prim coords
+////////////////////////////////////////////////////////////////////////
+
+void cmdDrawOffset(unsigned char * baseAddr) {
+ uint32_t gdata = GETLE32(&((uint32_t*)baseAddr)[0]);
+
+ g_gpu.dsp.DrawOffset.x = (short) (gdata & 0x7ff);
+
+ g_gpu.lGPUInfoVals[INFO_DRAWOFF] = gdata & 0x3FFFFF;
+ g_gpu.dsp.DrawOffset.y = (short) ((gdata >> 11) & 0x7ff);
+
+ g_gpu.dsp.DrawOffset.y = (short) (((int) g_gpu.dsp.DrawOffset.y << 21)
+ >> 21);
+ g_gpu.dsp.DrawOffset.x = (short) (((int) g_gpu.dsp.DrawOffset.x << 21)
+ >> 21);
+}
+
+////////////////////////////////////////////////////////////////////////
+// cmd: load image to vram
+////////////////////////////////////////////////////////////////////////
+
+void primLoadImage(unsigned char * baseAddr) {
+ unsigned short *sgpuData = ((unsigned short *) baseAddr);
+
+ g_gpu.VRAMWrite.x = GETLEs16(&sgpuData[2]) & 0x3ff;
+ g_gpu.VRAMWrite.y = GETLEs16(&sgpuData[3]) & 0x1ff;
+ g_gpu.VRAMWrite.Width = GETLEs16(&sgpuData[4]);
+ g_gpu.VRAMWrite.Height = GETLEs16(&sgpuData[5]);
+
+ g_gpu.DataWriteMode = DR_VRAMTRANSFER;
+
+ g_gpu.VRAMWrite.ImagePtr = g_gpu.psx_vram.u16 + (g_gpu.VRAMWrite.y << 10)
+ + g_gpu.VRAMWrite.x;
+ g_gpu.VRAMWrite.RowsRemaining = g_gpu.VRAMWrite.Width;
+ g_gpu.VRAMWrite.ColsRemaining = g_gpu.VRAMWrite.Height;
+}
+
+////////////////////////////////////////////////////////////////////////
+// cmd: vram -> psx mem
+////////////////////////////////////////////////////////////////////////
+
+void primStoreImage(unsigned char * baseAddr) {
+ unsigned short *sgpuData = ((unsigned short *) baseAddr);
+
+ g_gpu.VRAMRead.x = GETLEs16(&sgpuData[2]) & 0x03ff;
+ g_gpu.VRAMRead.y = GETLEs16(&sgpuData[3]) & 0x01ff;
+ g_gpu.VRAMRead.Width = GETLEs16(&sgpuData[4]);
+ g_gpu.VRAMRead.Height = GETLEs16(&sgpuData[5]);
+
+ g_gpu.VRAMRead.ImagePtr = g_gpu.psx_vram.u16 + (g_gpu.VRAMRead.y << 10)
+ + g_gpu.VRAMRead.x;
+ g_gpu.VRAMRead.RowsRemaining = g_gpu.VRAMRead.Width;
+ g_gpu.VRAMRead.ColsRemaining = g_gpu.VRAMRead.Height;
+
+ g_gpu.DataReadMode = DR_VRAMTRANSFER;
+
+ g_gpu.status_reg |= STATUS_READYFORVRAM;
+}
+
+////////////////////////////////////////////////////////////////////////
+// cmd: blkfill - NO primitive! Doesn't care about draw areas...
+////////////////////////////////////////////////////////////////////////
+
+void primBlkFill(unsigned char * baseAddr) {
+ uint32_t *gpuData = ((uint32_t *) baseAddr);
+ short *sgpuData = ((short *) baseAddr);
+
+ short sX = GETLEs16(&sgpuData[2]);
+ short sY = GETLEs16(&sgpuData[3]);
+ short sW = GETLEs16(&sgpuData[4]) & 0x3ff;
+ short sH = GETLEs16(&sgpuData[5]) & 0x3ff;
+
+ sW = (sW + 15) & ~15;
+
+ // Increase H & W if they are one short of full values, because they never can be full values
+ if (sH >= 1023)
+ sH = 1024;
+ if (sW >= 1023)
+ sW = 1024;
+
+ // x and y of end pos
+ sW += sX;
+ sH += sY;
+
+ FillSoftwareArea(sX, sY, sW, sH, BGR24to16(GETLE32(&gpuData[0])));
+
+}
+
+////////////////////////////////////////////////////////////////////////
+// cmd: move image vram -> vram
+////////////////////////////////////////////////////////////////////////
+
+void primMoveImage(unsigned char * baseAddr) {
+ short *sgpuData = ((short *) baseAddr);
+
+ short imageY0, imageX0, imageY1, imageX1, imageSX, imageSY, i, j;
+
+ imageX0 = GETLEs16(&sgpuData[2]) & 0x03ff;
+ imageY0 = GETLEs16(&sgpuData[3]) & 0x01ff;
+ imageX1 = GETLEs16(&sgpuData[4]) & 0x03ff;
+ imageY1 = GETLEs16(&sgpuData[5]) & 0x01ff;
+ imageSX = GETLEs16(&sgpuData[6]);
+ imageSY = GETLEs16(&sgpuData[7]);
+
+ if ((imageX0 == imageX1) && (imageY0 == imageY1))
+ return;
+ if (imageSX <= 0)
+ return;
+ if (imageSY <= 0)
+ return;
+
+ if ((imageY0 + imageSY) > 512 || (imageX0 + imageSX) > 1024 || (imageY1
+ + imageSY) > 512 || (imageX1 + imageSX) > 1024) {
+ int i, j;
+ for (j = 0; j < imageSY; j++)
+ for (i = 0; i < imageSX; i++)
+ g_gpu.psx_vram.u16[(1024 * ((imageY1 + j) & 0x01ff))
+ + ((imageX1 + i) & 0x3ff)] = g_gpu.psx_vram.u16[(1024
+ * ((imageY0 + j) & 0x01ff)) + ((imageX0 + i) & 0x3ff)];
+
+ return;
+ }
+
+ if (imageSX & 1) // not dword aligned? slower func
+ {
+ unsigned short *SRCPtr, *DSTPtr;
+ unsigned short LineOffset;
+
+ SRCPtr = g_gpu.psx_vram.u16 + (1024 * imageY0) + imageX0;
+ DSTPtr = g_gpu.psx_vram.u16 + (1024 * imageY1) + imageX1;
+
+ LineOffset = 1024 - imageSX;
+
+ for (j = 0; j < imageSY; j++) {
+ for (i = 0; i < imageSX; i++)
+ *DSTPtr++ = *SRCPtr++;
+ SRCPtr += LineOffset;
+ DSTPtr += LineOffset;
+ }
+ } else // dword aligned
+ {
+ uint32_t *SRCPtr, *DSTPtr;
+ unsigned short LineOffset;
+ int dx = imageSX >> 1;
+
+ SRCPtr = (uint32_t *) (g_gpu.psx_vram.u16 + (1024 * imageY0) + imageX0);
+ DSTPtr = (uint32_t *) (g_gpu.psx_vram.u16 + (1024 * imageY1) + imageX1);
+
+ LineOffset = 512 - dx;
+
+ for (j = 0; j < imageSY; j++) {
+ for (i = 0; i < dx; i++)
+ *DSTPtr++ = *SRCPtr++;
+ SRCPtr += LineOffset;
+ DSTPtr += LineOffset;
+ }
+ }
+
+ imageSX += imageX1;
+ imageSY += imageY1;
+
+}
+
+////////////////////////////////////////////////////////////////////////
+// cmd: draw free-size Tile
+////////////////////////////////////////////////////////////////////////
+void primTileS(unsigned char * baseAddr) {
+ uint32_t *gpuData = ((uint32_t*) baseAddr);
+ short *sgpuData = ((short *) baseAddr);
+ short sW = GETLEs16(&sgpuData[4]) & 0x3ff;
+ short sH = GETLEs16(&sgpuData[5]) & 0x01ff; // mmm... limit tiles to 0x1ff or height?
+
+ g_soft.lx0 = GETLEs16(&sgpuData[2]);
+ g_soft.ly0 = GETLEs16(&sgpuData[3]);
+
+ if (!(g_prim.dwActFixes & 8))
+ AdjustCoord1();
+
+ // x and y of start
+ g_soft.ly2 = g_soft.ly3 = g_soft.ly0 + sH + g_gpu.dsp.DrawOffset.y;
+ g_soft.ly0 = g_soft.ly1 = g_soft.ly0 + g_gpu.dsp.DrawOffset.y;
+ g_soft.lx1 = g_soft.lx2 = g_soft.lx0 + sW + g_gpu.dsp.DrawOffset.x;
+ g_soft.lx0 = g_soft.lx3 = g_soft.lx0 + g_gpu.dsp.DrawOffset.x;
+
+ g_soft.DrawSemiTrans = (SEMITRANSBIT(GETLE32(&gpuData[0]))) ? 1 : 0;
+
+ if (!(0 && sH == 32 && GETLE32(&gpuData[0]) == 0x60ffffff)) // special cheat for certain ZiNc games
+ FillSoftwareAreaTrans(g_soft.lx0, g_soft.ly0, g_soft.lx2, g_soft.ly2,
+ BGR24to16(GETLE32(&gpuData[0])));
+
+}
+
+////////////////////////////////////////////////////////////////////////
+// cmd: draw 1 dot Tile (point)
+////////////////////////////////////////////////////////////////////////
+
+void primTile1(unsigned char * baseAddr) {
+ uint32_t *gpuData = ((uint32_t*) baseAddr);
+ short *sgpuData = ((short *) baseAddr);
+ short sH = 1;
+ short sW = 1;
+
+ g_soft.lx0 = GETLEs16(&sgpuData[2]);
+ g_soft.ly0 = GETLEs16(&sgpuData[3]);
+
+ if (!(g_prim.dwActFixes & 8))
+ AdjustCoord1();
+
+ // x and y of start
+ g_soft.ly2 = g_soft.ly3 = g_soft.ly0 + sH + g_gpu.dsp.DrawOffset.y;
+ g_soft.ly0 = g_soft.ly1 = g_soft.ly0 + g_gpu.dsp.DrawOffset.y;
+ g_soft.lx1 = g_soft.lx2 = g_soft.lx0 + sW + g_gpu.dsp.DrawOffset.x;
+ g_soft.lx0 = g_soft.lx3 = g_soft.lx0 + g_gpu.dsp.DrawOffset.x;
+
+ g_soft.DrawSemiTrans = (SEMITRANSBIT(GETLE32(&gpuData[0]))) ? 1 : 0;
+
+ FillSoftwareAreaTrans(g_soft.lx0, g_soft.ly0, g_soft.lx2, g_soft.ly2,
+ BGR24to16(GETLE32(&gpuData[0]))); // Takes Start and Offset
+
+}
+
+////////////////////////////////////////////////////////////////////////
+// cmd: draw 8 dot Tile (small rect)
+////////////////////////////////////////////////////////////////////////
+
+void primTile8(unsigned char * baseAddr) {
+ uint32_t *gpuData = ((uint32_t*) baseAddr);
+ short *sgpuData = ((short *) baseAddr);
+ short sH = 8;
+ short sW = 8;
+
+ g_soft.lx0 = GETLEs16(&sgpuData[2]);
+ g_soft.ly0 = GETLEs16(&sgpuData[3]);
+
+ if (!(g_prim.dwActFixes & 8))
+ AdjustCoord1();
+
+ // x and y of start
+ g_soft.ly2 = g_soft.ly3 = g_soft.ly0 + sH + g_gpu.dsp.DrawOffset.y;
+ g_soft.ly0 = g_soft.ly1 = g_soft.ly0 + g_gpu.dsp.DrawOffset.y;
+ g_soft.lx1 = g_soft.lx2 = g_soft.lx0 + sW + g_gpu.dsp.DrawOffset.x;
+ g_soft.lx0 = g_soft.lx3 = g_soft.lx0 + g_gpu.dsp.DrawOffset.x;
+
+ g_soft.DrawSemiTrans = (SEMITRANSBIT(GETLE32(&gpuData[0]))) ? 1 : 0;
+
+ FillSoftwareAreaTrans(g_soft.lx0, g_soft.ly0, g_soft.lx2, g_soft.ly2,
+ BGR24to16(GETLE32(&gpuData[0]))); // Takes Start and Offset
+
+}
+
+////////////////////////////////////////////////////////////////////////
+// cmd: draw 16 dot Tile (medium rect)
+////////////////////////////////////////////////////////////////////////
+
+void primTile16(unsigned char * baseAddr) {
+ uint32_t *gpuData = ((uint32_t*) baseAddr);
+ short *sgpuData = ((short *) baseAddr);
+ short sH = 16;
+ short sW = 16;
+
+ g_soft.lx0 = GETLEs16(&sgpuData[2]);
+ g_soft.ly0 = GETLEs16(&sgpuData[3]);
+
+ if (!(g_prim.dwActFixes & 8))
+ AdjustCoord1();
+
+ // x and y of start
+ g_soft.ly2 = g_soft.ly3 = g_soft.ly0 + sH + g_gpu.dsp.DrawOffset.y;
+ g_soft.ly0 = g_soft.ly1 = g_soft.ly0 + g_gpu.dsp.DrawOffset.y;
+ g_soft.lx1 = g_soft.lx2 = g_soft.lx0 + sW + g_gpu.dsp.DrawOffset.x;
+ g_soft.lx0 = g_soft.lx3 = g_soft.lx0 + g_gpu.dsp.DrawOffset.x;
+
+ g_soft.DrawSemiTrans = (SEMITRANSBIT(GETLE32(&gpuData[0]))) ? 1 : 0;
+
+ FillSoftwareAreaTrans(g_soft.lx0, g_soft.ly0, g_soft.lx2, g_soft.ly2,
+ BGR24to16(GETLE32(&gpuData[0]))); // Takes Start and Offset
+
+}
+
+////////////////////////////////////////////////////////////////////////
+// cmd: small sprite (textured rect)
+////////////////////////////////////////////////////////////////////////
+
+void primSprt8(unsigned char * baseAddr) {
+ uint32_t *gpuData = ((uint32_t *) baseAddr);
+ short *sgpuData = ((short *) baseAddr);
+
+ g_soft.lx0 = GETLEs16(&sgpuData[2]);
+ g_soft.ly0 = GETLEs16(&sgpuData[3]);
+
+ if (!(g_prim.dwActFixes & 8))
+ AdjustCoord1();
+
+ SetRenderMode(GETLE32(&gpuData[0]));
+
+ if (g_prim.bUsingTWin)
+ DrawSoftwareSpriteTWin(baseAddr, 8, 8);
+ else if (g_prim.usMirror)
+ DrawSoftwareSpriteMirror(baseAddr, 8, 8);
+ else
+ DrawSoftwareSprite(baseAddr, 8, 8, baseAddr[8], baseAddr[9]);
+
+}
+
+////////////////////////////////////////////////////////////////////////
+// cmd: medium sprite (textured rect)
+////////////////////////////////////////////////////////////////////////
+
+void primSprt16(unsigned char * baseAddr) {
+ uint32_t *gpuData = ((uint32_t *) baseAddr);
+ short *sgpuData = ((short *) baseAddr);
+
+ g_soft.lx0 = GETLEs16(&sgpuData[2]);
+ g_soft.ly0 = GETLEs16(&sgpuData[3]);
+
+ if (!(g_prim.dwActFixes & 8))
+ AdjustCoord1();
+
+ SetRenderMode(GETLE32(&gpuData[0]));
+
+ if (g_prim.bUsingTWin)
+ DrawSoftwareSpriteTWin(baseAddr, 16, 16);
+ else if (g_prim.usMirror)
+ DrawSoftwareSpriteMirror(baseAddr, 16, 16);
+ else
+ DrawSoftwareSprite(baseAddr, 16, 16, baseAddr[8], baseAddr[9]);
+
+}
+
+////////////////////////////////////////////////////////////////////////
+// cmd: free-size sprite (textured rect)
+////////////////////////////////////////////////////////////////////////
+
+// func used on texture coord wrap
+void primSprtSRest(unsigned char * baseAddr, unsigned short type) {
+ uint32_t *gpuData = ((uint32_t *) baseAddr);
+ short *sgpuData = ((short *) baseAddr);
+ unsigned short sTypeRest = 0;
+
+ short s;
+ short sX = GETLEs16(&sgpuData[2]);
+ short sY = GETLEs16(&sgpuData[3]);
+ short sW = GETLEs16(&sgpuData[6]) & 0x3ff;
+ short sH = GETLEs16(&sgpuData[7]) & 0x1ff;
+ short tX = baseAddr[8];
+ short tY = baseAddr[9];
+
+ switch (type) {
+ case 1:
+ s = 256 - baseAddr[8];
+ sW -= s;
+ sX += s;
+ tX = 0;
+ break;
+ case 2:
+ s = 256 - baseAddr[9];
+ sH -= s;
+ sY += s;
+ tY = 0;
+ break;
+ case 3:
+ s = 256 - baseAddr[8];
+ sW -= s;
+ sX += s;
+ tX = 0;
+ s = 256 - baseAddr[9];
+ sH -= s;
+ sY += s;
+ tY = 0;
+ break;
+ case 4:
+ s = 512 - baseAddr[8];
+ sW -= s;
+ sX += s;
+ tX = 0;
+ break;
+ case 5:
+ s = 512 - baseAddr[9];
+ sH -= s;
+ sY += s;
+ tY = 0;
+ break;
+ case 6:
+ s = 512 - baseAddr[8];
+ sW -= s;
+ sX += s;
+ tX = 0;
+ s = 512 - baseAddr[9];
+ sH -= s;
+ sY += s;
+ tY = 0;
+ break;
+ }
+
+ SetRenderMode(GETLE32(&gpuData[0]));
+
+ if (tX + sW > 256) {
+ sW = 256 - tX;
+ sTypeRest += 1;
+ }
+ if (tY + sH > 256) {
+ sH = 256 - tY;
+ sTypeRest += 2;
+ }
+
+ g_soft.lx0 = sX;
+ g_soft.ly0 = sY;
+
+ if (!(g_prim.dwActFixes & 8))
+ AdjustCoord1();
+
+ DrawSoftwareSprite(baseAddr, sW, sH, tX, tY);
+
+ if (sTypeRest && type < 4) {
+ if (sTypeRest & 1 && type == 1)
+ primSprtSRest(baseAddr, 4);
+ if (sTypeRest & 2 && type == 2)
+ primSprtSRest(baseAddr, 5);
+ if (sTypeRest == 3 && type == 3)
+ primSprtSRest(baseAddr, 6);
+ }
+
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void primSprtS(unsigned char * baseAddr) {
+ uint32_t *gpuData = ((uint32_t *) baseAddr);
+ short *sgpuData = ((short *) baseAddr);
+ short sW, sH;
+
+ g_soft.lx0 = GETLEs16(&sgpuData[2]);
+ g_soft.ly0 = GETLEs16(&sgpuData[3]);
+
+ if (!(g_prim.dwActFixes & 8))
+ AdjustCoord1();
+
+ sW = GETLEs16(&sgpuData[6]) & 0x3ff;
+ sH = GETLEs16(&sgpuData[7]) & 0x1ff;
+
+ SetRenderMode(GETLE32(&gpuData[0]));
+
+ if (g_prim.bUsingTWin)
+ DrawSoftwareSpriteTWin(baseAddr, sW, sH);
+ else if (g_prim.usMirror)
+ DrawSoftwareSpriteMirror(baseAddr, sW, sH);
+ else {
+ unsigned short sTypeRest = 0;
+ short tX = baseAddr[8];
+ short tY = baseAddr[9];
+
+ if (tX + sW > 256) {
+ sW = 256 - tX;
+ sTypeRest += 1;
+ }
+ if (tY + sH > 256) {
+ sH = 256 - tY;
+ sTypeRest += 2;
+ }
+
+ DrawSoftwareSprite(baseAddr, sW, sH, tX, tY);
+
+ if (sTypeRest) {
+ if (sTypeRest & 1)
+ primSprtSRest(baseAddr, 1);
+ if (sTypeRest & 2)
+ primSprtSRest(baseAddr, 2);
+ if (sTypeRest == 3)
+ primSprtSRest(baseAddr, 3);
+ }
+
+ }
+
+}
+
+////////////////////////////////////////////////////////////////////////
+// cmd: flat shaded Poly4
+////////////////////////////////////////////////////////////////////////
+
+void primPolyF4(unsigned char *baseAddr) {
+ uint32_t *gpuData = ((uint32_t *) baseAddr);
+ short *sgpuData = ((short *) baseAddr);
+
+ g_soft.lx0 = GETLEs16(&sgpuData[2]);
+ g_soft.ly0 = GETLEs16(&sgpuData[3]);
+ g_soft.lx1 = GETLEs16(&sgpuData[4]);
+ g_soft.ly1 = GETLEs16(&sgpuData[5]);
+ g_soft.lx2 = GETLEs16(&sgpuData[6]);
+ g_soft.ly2 = GETLEs16(&sgpuData[7]);
+ g_soft.lx3 = GETLEs16(&sgpuData[8]);
+ g_soft.ly3 = GETLEs16(&sgpuData[9]);
+
+ if (!(g_prim.dwActFixes & 8)) {
+ AdjustCoord4();
+ if (CheckCoord4())
+ return;
+ }
+
+ offsetPSX4();
+ g_soft.DrawSemiTrans = (SEMITRANSBIT(GETLE32(&gpuData[0]))) ? 1 : 0;
+
+ drawPoly4F(GETLE32(&gpuData[0]));
+
+}
+
+////////////////////////////////////////////////////////////////////////
+// cmd: smooth shaded Poly4
+////////////////////////////////////////////////////////////////////////
+
+void primPolyG4(unsigned char * baseAddr) {
+ uint32_t *gpuData = (uint32_t *) baseAddr;
+ short *sgpuData = ((short *) baseAddr);
+
+ g_soft.lx0 = GETLEs16(&sgpuData[2]);
+ g_soft.ly0 = GETLEs16(&sgpuData[3]);
+ g_soft.lx1 = GETLEs16(&sgpuData[6]);
+ g_soft.ly1 = GETLEs16(&sgpuData[7]);
+ g_soft.lx2 = GETLEs16(&sgpuData[10]);
+ g_soft.ly2 = GETLEs16(&sgpuData[11]);
+ g_soft.lx3 = GETLEs16(&sgpuData[14]);
+ g_soft.ly3 = GETLEs16(&sgpuData[15]);
+
+ if (!(g_prim.dwActFixes & 8)) {
+ AdjustCoord4();
+ if (CheckCoord4())
+ return;
+ }
+
+ offsetPSX4();
+ g_soft.DrawSemiTrans = (SEMITRANSBIT(GETLE32(&gpuData[0]))) ? 1 : 0;
+
+ drawPoly4G(GETLE32(&gpuData[0]), GETLE32(&gpuData[2]),
+ GETLE32(&gpuData[4]), GETLE32(&gpuData[6]));
+
+}
+
+////////////////////////////////////////////////////////////////////////
+// cmd: flat shaded Texture3
+////////////////////////////////////////////////////////////////////////
+
+void primPolyFT3(unsigned char * baseAddr) {
+ uint32_t *gpuData = ((uint32_t *) baseAddr);
+ short *sgpuData = ((short *) baseAddr);
+
+ g_soft.lx0 = GETLEs16(&sgpuData[2]);
+ g_soft.ly0 = GETLEs16(&sgpuData[3]);
+ g_soft.lx1 = GETLEs16(&sgpuData[6]);
+ g_soft.ly1 = GETLEs16(&sgpuData[7]);
+ g_soft.lx2 = GETLEs16(&sgpuData[10]);
+ g_soft.ly2 = GETLEs16(&sgpuData[11]);
+
+ g_draw.lLowerpart = GETLE32(&gpuData[4]) >> 16;
+ UpdateGlobalTP((unsigned short) g_draw.lLowerpart);
+
+ if (!(g_prim.dwActFixes & 8)) {
+ AdjustCoord3();
+ if (CheckCoord3())
+ return;
+ }
+
+ offsetPSX3();
+ SetRenderMode(GETLE32(&gpuData[0]));
+
+ drawPoly3FT(baseAddr);
+
+}
+
+////////////////////////////////////////////////////////////////////////
+// cmd: flat shaded Texture4
+////////////////////////////////////////////////////////////////////////
+
+void primPolyFT4(unsigned char * baseAddr) {
+ uint32_t *gpuData = ((uint32_t *) baseAddr);
+ short *sgpuData = ((short *) baseAddr);
+
+ g_soft.lx0 = GETLEs16(&sgpuData[2]);
+ g_soft.ly0 = GETLEs16(&sgpuData[3]);
+ g_soft.lx1 = GETLEs16(&sgpuData[6]);
+ g_soft.ly1 = GETLEs16(&sgpuData[7]);
+ g_soft.lx2 = GETLEs16(&sgpuData[10]);
+ g_soft.ly2 = GETLEs16(&sgpuData[11]);
+ g_soft.lx3 = GETLEs16(&sgpuData[14]);
+ g_soft.ly3 = GETLEs16(&sgpuData[15]);
+
+ g_draw.lLowerpart = GETLE32(&gpuData[4]) >> 16;
+ UpdateGlobalTP((unsigned short) g_draw.lLowerpart);
+
+ if (!(g_prim.dwActFixes & 8)) {
+ AdjustCoord4();
+ if (CheckCoord4())
+ return;
+ }
+
+ offsetPSX4();
+
+ SetRenderMode(GETLE32(&gpuData[0]));
+
+ drawPoly4FT(baseAddr);
+
+}
+
+////////////////////////////////////////////////////////////////////////
+// cmd: smooth shaded Texture3
+////////////////////////////////////////////////////////////////////////
+
+void primPolyGT3(unsigned char *baseAddr) {
+ uint32_t *gpuData = ((uint32_t *) baseAddr);
+ short *sgpuData = ((short *) baseAddr);
+
+ g_soft.lx0 = GETLEs16(&sgpuData[2]);
+ g_soft.ly0 = GETLEs16(&sgpuData[3]);
+ g_soft.lx1 = GETLEs16(&sgpuData[8]);
+ g_soft.ly1 = GETLEs16(&sgpuData[9]);
+ g_soft.lx2 = GETLEs16(&sgpuData[14]);
+ g_soft.ly2 = GETLEs16(&sgpuData[15]);
+
+ g_draw.lLowerpart = GETLE32(&gpuData[5]) >> 16;
+ UpdateGlobalTP((unsigned short) g_draw.lLowerpart);
+
+ if (!(g_prim.dwActFixes & 8)) {
+ AdjustCoord3();
+ if (CheckCoord3())
+ return;
+ }
+
+ offsetPSX3();
+ g_soft.DrawSemiTrans = (SEMITRANSBIT(GETLE32(&gpuData[0]))) ? 1 : 0;
+
+ if (SHADETEXBIT(GETLE32(&gpuData[0]))) {
+ gpuData[0] = (gpuData[0] & HOST2LE32(0xff000000))
+ |HOST2LE32(0x00808080);
+ gpuData[3] = (gpuData[3] & HOST2LE32(0xff000000))
+ |HOST2LE32(0x00808080);
+ gpuData[6] = (gpuData[6] & HOST2LE32(0xff000000))
+ |HOST2LE32(0x00808080);
+ }
+
+ drawPoly3GT(baseAddr);
+
+}
+
+////////////////////////////////////////////////////////////////////////
+// cmd: smooth shaded Poly3
+////////////////////////////////////////////////////////////////////////
+
+void primPolyG3(unsigned char *baseAddr) {
+ uint32_t *gpuData = ((uint32_t *) baseAddr);
+ short *sgpuData = ((short *) baseAddr);
+
+ g_soft.lx0 = GETLEs16(&sgpuData[2]);
+ g_soft.ly0 = GETLEs16(&sgpuData[3]);
+ g_soft.lx1 = GETLEs16(&sgpuData[6]);
+ g_soft.ly1 = GETLEs16(&sgpuData[7]);
+ g_soft.lx2 = GETLEs16(&sgpuData[10]);
+ g_soft.ly2 = GETLEs16(&sgpuData[11]);
+
+ if (!(g_prim.dwActFixes & 8)) {
+ AdjustCoord3();
+ if (CheckCoord3())
+ return;
+ }
+
+ offsetPSX3();
+ g_soft.DrawSemiTrans = (SEMITRANSBIT(GETLE32(&gpuData[0]))) ? 1 : 0;
+
+ drawPoly3G(GETLE32(&gpuData[0]), GETLE32(&gpuData[2]), GETLE32(&gpuData[4]));
+
+}
+
+////////////////////////////////////////////////////////////////////////
+// cmd: smooth shaded Texture4
+////////////////////////////////////////////////////////////////////////
+
+void primPolyGT4(unsigned char *baseAddr) {
+ uint32_t *gpuData = ((uint32_t *) baseAddr);
+ short *sgpuData = ((short *) baseAddr);
+
+ g_soft.lx0 = GETLEs16(&sgpuData[2]);
+ g_soft.ly0 = GETLEs16(&sgpuData[3]);
+ g_soft.lx1 = GETLEs16(&sgpuData[8]);
+ g_soft.ly1 = GETLEs16(&sgpuData[9]);
+ g_soft.lx2 = GETLEs16(&sgpuData[14]);
+ g_soft.ly2 = GETLEs16(&sgpuData[15]);
+ g_soft.lx3 = GETLEs16(&sgpuData[20]);
+ g_soft.ly3 = GETLEs16(&sgpuData[21]);
+
+ g_draw.lLowerpart = GETLE32(&gpuData[5]) >> 16;
+ UpdateGlobalTP((unsigned short) g_draw.lLowerpart);
+
+ if (!(g_prim.dwActFixes & 8)) {
+ AdjustCoord4();
+ if (CheckCoord4())
+ return;
+ }
+
+ offsetPSX4();
+ g_soft.DrawSemiTrans = (SEMITRANSBIT(GETLE32(&gpuData[0]))) ? 1 : 0;
+
+ if (SHADETEXBIT(GETLE32(&gpuData[0]))) {
+ gpuData[0] = (gpuData[0] & HOST2LE32(0xff000000))
+ |HOST2LE32(0x00808080);
+ gpuData[3] = (gpuData[3] & HOST2LE32(0xff000000))
+ |HOST2LE32(0x00808080);
+ gpuData[6] = (gpuData[6] & HOST2LE32(0xff000000))
+ |HOST2LE32(0x00808080);
+ gpuData[9] = (gpuData[9] & HOST2LE32(0xff000000))
+ |HOST2LE32(0x00808080);
+ }
+
+ drawPoly4GT(baseAddr);
+
+}
+
+////////////////////////////////////////////////////////////////////////
+// cmd: smooth shaded Poly3
+////////////////////////////////////////////////////////////////////////
+
+void primPolyF3(unsigned char *baseAddr) {
+ uint32_t *gpuData = ((uint32_t *) baseAddr);
+ short *sgpuData = ((short *) baseAddr);
+
+ g_soft.lx0 = GETLEs16(&sgpuData[2]);
+ g_soft.ly0 = GETLEs16(&sgpuData[3]);
+ g_soft.lx1 = GETLEs16(&sgpuData[4]);
+ g_soft.ly1 = GETLEs16(&sgpuData[5]);
+ g_soft.lx2 = GETLEs16(&sgpuData[6]);
+ g_soft.ly2 = GETLEs16(&sgpuData[7]);
+
+ if (!(g_prim.dwActFixes & 8)) {
+ AdjustCoord3();
+ if (CheckCoord3())
+ return;
+ }
+
+ offsetPSX3();
+ SetRenderMode(GETLE32(&gpuData[0]));
+
+ drawPoly3F(GETLE32(&gpuData[0]));
+
+}
+
+////////////////////////////////////////////////////////////////////////
+// cmd: skipping shaded polylines
+////////////////////////////////////////////////////////////////////////
+
+void primLineGSkip(unsigned char *baseAddr) {
+ uint32_t *gpuData = ((uint32_t *) baseAddr);
+ int iMax = 255;
+ int i = 2;
+
+ g_soft.ly1 = (short) ((GETLE32(&gpuData[1]) >> 16) & 0xffff);
+ g_soft.lx1 = (short) (GETLE32(&gpuData[1]) & 0xffff);
+
+ while (!(((GETLE32(&gpuData[i]) & 0xF000F000) == 0x50005000) && i >= 4)) {
+ i++;
+ g_soft.ly1 = (short) ((GETLE32(&gpuData[i]) >> 16) & 0xffff);
+ g_soft.lx1 = (short) (GETLE32(&gpuData[i]) & 0xffff);
+ i++;
+ if (i > iMax)
+ break;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+// cmd: shaded polylines
+////////////////////////////////////////////////////////////////////////
+
+void primLineGEx(unsigned char *baseAddr) {
+ uint32_t *gpuData = ((uint32_t *) baseAddr);
+ int iMax = 255;
+ uint32_t lc0, lc1;
+ short slx0, slx1, sly0, sly1;
+ int i = 2;
+ char bDraw = 1;
+
+ sly1 = (short) ((GETLE32(&gpuData[1]) >> 16) & 0xffff);
+ slx1 = (short) (GETLE32(&gpuData[1]) & 0xffff);
+
+ if (!(g_prim.dwActFixes & 8)) {
+ slx1 = (short) (((int) slx1 << SIGNSHIFT) >> SIGNSHIFT);
+ sly1 = (short) (((int) sly1 << SIGNSHIFT) >> SIGNSHIFT);
+ }
+
+ lc1 = gpuData[0] & 0xffffff;
+
+ g_soft.DrawSemiTrans = (SEMITRANSBIT(GETLE32(&gpuData[0]))) ? 1 : 0;
+
+ while (!(((GETLE32(&gpuData[i]) & 0xF000F000) == 0x50005000) && i >= 4)) {
+ sly0 = sly1;
+ slx0 = slx1;
+ lc0 = lc1;
+ lc1 = GETLE32(&gpuData[i]) & 0xffffff;
+
+ i++;
+
+ // no check needed on gshaded polyline positions
+ // if((gpuData[i] & 0xF000F000) == 0x50005000) break;
+
+ sly1 = (short) ((GETLE32(&gpuData[i]) >> 16) & 0xffff);
+ slx1 = (short) (GETLE32(&gpuData[i]) & 0xffff);
+
+ if (!(g_prim.dwActFixes & 8)) {
+ slx1 = (short) (((int) slx1 << SIGNSHIFT) >> SIGNSHIFT);
+ sly1 = (short) (((int) sly1 << SIGNSHIFT) >> SIGNSHIFT);
+ if (CheckCoordL(slx0, sly0, slx1, sly1))
+ bDraw = 0;
+ else
+ bDraw = 1;
+ }
+
+ if ((g_soft.lx0 != g_soft.lx1) || (g_soft.ly0 != g_soft.ly1)) {
+ g_soft.ly0 = sly0;
+ g_soft.lx0 = slx0;
+ g_soft.ly1 = sly1;
+ g_soft.lx1 = slx1;
+
+ offsetPSX2();
+ if (bDraw)
+ DrawSoftwareLineShade(lc0, lc1);
+ }
+ i++;
+ if (i > iMax)
+ break;
+ }
+
+}
+
+////////////////////////////////////////////////////////////////////////
+// cmd: shaded polyline2
+////////////////////////////////////////////////////////////////////////
+
+void primLineG2(unsigned char *baseAddr) {
+ uint32_t *gpuData = ((uint32_t *) baseAddr);
+ short *sgpuData = ((short *) baseAddr);
+
+ g_soft.lx0 = GETLEs16(&sgpuData[2]);
+ g_soft.ly0 = GETLEs16(&sgpuData[3]);
+ g_soft.lx1 = GETLEs16(&sgpuData[6]);
+ g_soft.ly1 = GETLEs16(&sgpuData[7]);
+
+ if (!(g_prim.dwActFixes & 8)) {
+ AdjustCoord2();
+ if (CheckCoord2())
+ return;
+ }
+
+ if ((g_soft.lx0 == g_soft.lx1) && (g_soft.ly0 == g_soft.ly1)) {
+ g_soft.lx1++;
+ g_soft.ly1++;
+ }
+
+ g_soft.DrawSemiTrans = (SEMITRANSBIT(GETLE32(&gpuData[0]))) ? 1 : 0;
+ offsetPSX2();
+ DrawSoftwareLineShade(GETLE32(&gpuData[0]), GETLE32(&gpuData[2]));
+
+}
+
+////////////////////////////////////////////////////////////////////////
+// cmd: skipping flat polylines
+////////////////////////////////////////////////////////////////////////
+
+void primLineFSkip(unsigned char *baseAddr) {
+ uint32_t *gpuData = ((uint32_t *) baseAddr);
+ int i = 2, iMax = 255;
+
+ g_soft.ly1 = (short) ((GETLE32(&gpuData[1]) >> 16) & 0xffff);
+ g_soft.lx1 = (short) (GETLE32(&gpuData[1]) & 0xffff);
+
+ while (!(((GETLE32(&gpuData[i]) & 0xF000F000) == 0x50005000) && i >= 3)) {
+ g_soft.ly1 = (short) ((GETLE32(&gpuData[i]) >> 16) & 0xffff);
+ g_soft.lx1 = (short) (GETLE32(&gpuData[i]) & 0xffff);
+ i++;
+ if (i > iMax)
+ break;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+// cmd: drawing flat polylines
+////////////////////////////////////////////////////////////////////////
+
+void primLineFEx(unsigned char *baseAddr) {
+ uint32_t *gpuData = ((uint32_t *) baseAddr);
+ int iMax;
+ short slx0, slx1, sly0, sly1;
+ int i = 2;
+ char bDraw = 1;
+
+ iMax = 255;
+
+ sly1 = (short) ((GETLE32(&gpuData[1]) >> 16) & 0xffff);
+ slx1 = (short) (GETLE32(&gpuData[1]) & 0xffff);
+ if (!(g_prim.dwActFixes & 8)) {
+ slx1 = (short) (((int) slx1 << SIGNSHIFT) >> SIGNSHIFT);
+ sly1 = (short) (((int) sly1 << SIGNSHIFT) >> SIGNSHIFT);
+ }
+
+ SetRenderMode(GETLE32(&gpuData[0]));
+
+ while (!(((GETLE32(&gpuData[i]) & 0xF000F000) == 0x50005000) && i >= 3)) {
+ sly0 = sly1;
+ slx0 = slx1;
+ sly1 = (short) ((GETLE32(&gpuData[i]) >> 16) & 0xffff);
+ slx1 = (short) (GETLE32(&gpuData[i]) & 0xffff);
+ if (!(g_prim.dwActFixes & 8)) {
+ slx1 = (short) (((int) slx1 << SIGNSHIFT) >> SIGNSHIFT);
+ sly1 = (short) (((int) sly1 << SIGNSHIFT) >> SIGNSHIFT);
+
+ if (CheckCoordL(slx0, sly0, slx1, sly1))
+ bDraw = 0;
+ else
+ bDraw = 1;
+ }
+
+ g_soft.ly0 = sly0;
+ g_soft.lx0 = slx0;
+ g_soft.ly1 = sly1;
+ g_soft.lx1 = slx1;
+
+ offsetPSX2();
+ if (bDraw)
+ DrawSoftwareLineFlat(GETLE32(&gpuData[0]));
+
+ i++;
+ if (i > iMax)
+ break;
+ }
+
+}
+
+////////////////////////////////////////////////////////////////////////
+// cmd: drawing flat polyline2
+////////////////////////////////////////////////////////////////////////
+
+void primLineF2(unsigned char *baseAddr) {
+ uint32_t *gpuData = ((uint32_t *) baseAddr);
+ short *sgpuData = ((short *) baseAddr);
+
+ g_soft.lx0 = GETLEs16(&sgpuData[2]);
+ g_soft.ly0 = GETLEs16(&sgpuData[3]);
+ g_soft.lx1 = GETLEs16(&sgpuData[4]);
+ g_soft.ly1 = GETLEs16(&sgpuData[5]);
+
+ if (!(g_prim.dwActFixes & 8)) {
+ AdjustCoord2();
+ if (CheckCoord2())
+ return;
+ }
+
+ if ((g_soft.lx0 == g_soft.lx1) && (g_soft.ly0 == g_soft.ly1)) {
+ g_soft.lx1++;
+ g_soft.ly1++;
+ }
+
+ offsetPSX2();
+ SetRenderMode(GETLE32(&gpuData[0]));
+
+ DrawSoftwareLineFlat(GETLE32(&gpuData[0]));
+
+}
+
+////////////////////////////////////////////////////////////////////////
+// cmd: well, easiest command... not implemented
+////////////////////////////////////////////////////////////////////////
+
+void primNI(unsigned char *bA) {
+ fprintf(stderr, "Unknow GPU func \n");
+}
+
+////////////////////////////////////////////////////////////////////////
+// cmd func ptr table
+////////////////////////////////////////////////////////////////////////
+
+
+void (*primTableJ[256])(unsigned char *) = {
+ /* 00 */
+ primNI,
+ primNI,
+ primBlkFill,
+ primNI,
+ /* 04 */
+ primNI,
+ primNI,
+ primNI,
+ primNI,
+ /* 08 */
+ primNI,
+ primNI,
+ primNI,
+ primNI,
+ primNI,
+ primNI,
+ primNI,
+ primNI,
+ // 10
+ primNI,
+ primNI,
+ primNI,
+ primNI,
+ primNI,
+ primNI,
+ primNI,
+ primNI,
+ // 18
+ primNI,
+ primNI,
+ primNI,
+ primNI,
+ primNI,
+ primNI,
+ primNI,
+ primNI,
+ // 20
+ primPolyF3,
+ primPolyF3,
+ primPolyF3,
+ primPolyF3,
+ primPolyFT3,
+ primPolyFT3,
+ primPolyFT3,
+ primPolyFT3,
+ // 28
+ primPolyF4,
+ primPolyF4,
+ primPolyF4,
+ primPolyF4,
+ primPolyFT4,
+ primPolyFT4,
+ primPolyFT4,
+ primPolyFT4,
+ // 30
+ primPolyG3,
+ primPolyG3,
+ primPolyG3,
+ primPolyG3,
+ primPolyGT3,
+ primPolyGT3,
+ primPolyGT3,
+ primPolyGT3,
+ // 38
+ primPolyG4,
+ primPolyG4,
+ primPolyG4,
+ primPolyG4,
+ primPolyGT4,
+ primPolyGT4,
+ primPolyGT4,
+ primPolyGT4,
+ // 40
+ primLineF2,
+ primLineF2,
+ primLineF2,
+ primLineF2,
+ primNI,
+ primNI,
+ primNI,
+ primNI,
+ // 48
+ primLineFEx,
+ primLineFEx,
+ primLineFEx,
+ primLineFEx,
+ primLineFEx,
+ primLineFEx,
+ primLineFEx,
+ primLineFEx,
+ // 50
+ primLineG2, primLineG2,
+ primLineG2,
+ primLineG2,
+ primNI,
+ primNI,
+ primNI,
+ primNI,
+ // 58
+ primLineGEx, primLineGEx, primLineGEx,
+ primLineGEx,
+ primLineGEx,
+ primLineGEx,
+ primLineGEx,
+ primLineGEx,
+ // 60
+ primTileS, primTileS, primTileS, primTileS,
+ primSprtS,
+ primSprtS,
+ primSprtS,
+ primSprtS,
+ // 68
+ primTile1, primTile1, primTile1, primTile1, primNI,
+ primNI,
+ primNI,
+ primNI,
+ // 70
+ primTile8, primTile8, primTile8, primTile8, primSprt8, primSprt8,
+ primSprt8,
+ primSprt8,
+ // 78
+ primTile16, primTile16, primTile16, primTile16, primSprt16, primSprt16,
+ primSprt16, primSprt16,
+ // 80
+ primMoveImage, primNI, primNI, primNI, primNI, primNI, primNI, primNI,
+ // 88
+ primNI, primNI, primNI, primNI, primNI, primNI, primNI, primNI,
+ // 90
+ primNI, primNI, primNI, primNI, primNI, primNI, primNI, primNI,
+ // 98
+ primNI, primNI, primNI, primNI, primNI, primNI, primNI, primNI,
+ // a0
+ primLoadImage, primNI, primNI, primNI, primNI, primNI, primNI, primNI,
+ // a8
+ primNI, primNI, primNI, primNI, primNI, primNI, primNI, primNI,
+ // b0
+ primNI, primNI, primNI, primNI, primNI, primNI, primNI, primNI,
+ // b8
+ primNI, primNI, primNI, primNI, primNI, primNI, primNI, primNI,
+ // c0
+ primStoreImage, primNI, primNI, primNI, primNI, primNI, primNI, primNI,
+ // c8
+ primNI, primNI, primNI, primNI, primNI, primNI, primNI, primNI,
+ // d0
+ primNI, primNI, primNI, primNI, primNI, primNI, primNI, primNI,
+ // d8
+ primNI, primNI, primNI, primNI, primNI, primNI, primNI, primNI,
+ // e0
+ primNI, cmdTexturePage, cmdTextureWindow, cmdDrawAreaStart,
+ cmdDrawAreaEnd, cmdDrawOffset, cmdSTP, primNI,
+ // e8
+ primNI, primNI, primNI, primNI, primNI, primNI, primNI, primNI,
+ // f0
+ primNI, primNI, primNI, primNI, primNI, primNI, primNI, primNI,
+ // f8
+ primNI, primNI, primNI, primNI, primNI, primNI, primNI, primNI };
+