summaryrefslogtreecommitdiff
path: root/plugins/gxvideo
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/gxvideo')
-rw-r--r--plugins/gxvideo/cfg.c522
-rw-r--r--plugins/gxvideo/draw.c1518
-rw-r--r--plugins/gxvideo/fps.c138
-rw-r--r--plugins/gxvideo/gpu.c3104
-rw-r--r--plugins/gxvideo/gpucfg/main.c714
-rw-r--r--plugins/gxvideo/key.c87
-rw-r--r--plugins/gxvideo/menu.c113
-rw-r--r--plugins/gxvideo/prim.c3234
-rw-r--r--plugins/gxvideo/soft.c19862
9 files changed, 14655 insertions, 14637 deletions
diff --git a/plugins/gxvideo/cfg.c b/plugins/gxvideo/cfg.c
index 2274c529..7b18327a 100644
--- a/plugins/gxvideo/cfg.c
+++ b/plugins/gxvideo/cfg.c
@@ -1,261 +1,261 @@
-/*
- * Copyright (C) 2010 Benoit Gschwind
- * Inspired by original author : Pete Bernert
- *
- * 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 3 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., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#include <sys/stat.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-
-#include "globals.h"
-#include "cfg.h"
-
-#define DEFAULT_CFG_NAME "gxvideo.cfg"
-
-static int get_int_value (char const * file_buffer, char const * name, int dflt) {
- char * p = strstr(file_buffer, name);
- if (p != NULL) {
- p += strlen(name);
- while ((*p == ' ') || (*p == '='))
- ++p;
- if (*p != '\n')
- return atoi(p);
- }
- return dflt;
-}
-
-static double get_double_value(char const * file_buffer, char const * name,
- double dflt) {
- char * p = strstr(file_buffer, name);
- if (p != NULL) {
- p += strlen(name);
- while ((*p == ' ') || (*p == '='))
- ++p;
- if (*p != '\n')
- return atof(p);
- }
- return dflt;
-}
-
-static void write_int_value (FILE * f, char const * name, int val) {
- fprintf(f, "%s = %d\n", name, val);
-}
-
-static void write_double_value (FILE * f, char const * name, double val) {
- fprintf(f, "%s = %.1f\n", name, val);
-}
-
-static void ReadConfigFile() {
- struct stat buf;
- FILE * f_in;
- char cfg_file_name[256];
- int len, size;
- char * file_buffer;
-
- if (g_file_name)
- strcpy(cfg_file_name, g_file_name);
- else {
- strcpy(cfg_file_name, DEFAULT_CFG_NAME);
- f_in = fopen(cfg_file_name, "rb");
- if (!f_in) {
- strcpy(cfg_file_name, "cfg/" DEFAULT_CFG_NAME);
- f_in = fopen(cfg_file_name, "rb");
- if (!f_in)
- snprintf(cfg_file_name, 255, "%s/.pcsx/plugins/" DEFAULT_CFG_NAME, getenv("HOME"));
- else
- fclose(f_in);
- } else
- fclose(f_in);
- }
-
- if (stat(cfg_file_name, &buf) == -1)
- return;
- size = buf.st_size;
-
- f_in = fopen(cfg_file_name, "rb");
- if (!f_in)
- return;
-
- file_buffer = (char *) malloc(size + 1);
- len = fread(file_buffer, 1, size, f_in);
- /* ensure end_of_string */
- file_buffer[len] = 0;
- fclose(f_in);
-
- g_cfg.ResX = get_int_value(file_buffer, "ResX", g_cfg.ResX);
- if (g_cfg.ResX < 20)
- g_cfg.ResX = 20;
- g_cfg.ResX = (g_cfg.ResX / 4) * 4;
- g_cfg.ResY = get_int_value(file_buffer, "ResY", g_cfg.ResY);
- if (g_cfg.ResY < 20)
- g_cfg.ResY = 20;
- g_cfg.ResY = (g_cfg.ResY / 4) * 4;
- g_cfg.Dithering = get_int_value(file_buffer, "Dithering", g_cfg.Dithering);
- g_cfg.FullScreen = get_int_value(file_buffer, "FullScreen", g_cfg.FullScreen);
- g_cfg.ShowFPS = get_int_value(file_buffer, "ShowFPS", g_cfg.ShowFPS);
- if (g_cfg.ShowFPS < 0)
- g_cfg.ShowFPS = 0;
- if (g_cfg.ShowFPS > 1)
- g_cfg.ShowFPS = 1;
-
- g_cfg.Maintain43 = get_int_value(file_buffer, "Maintain43", g_cfg.Maintain43);
- if (g_cfg.Maintain43 < 0)
- g_cfg.Maintain43 = 0;
- if (g_cfg.Maintain43 > 1)
- g_cfg.Maintain43 = 1;
-
- g_cfg.UseFrameLimit = get_int_value(file_buffer, "UseFrameLimit", g_cfg.UseFrameLimit);
- if (g_cfg.UseFrameLimit < 0)
- g_cfg.UseFrameLimit = 0;
- if (g_cfg.UseFrameLimit > 1)
- g_cfg.UseFrameLimit = 1;
-
- g_cfg.UseFrameSkip = 0;
-
- g_cfg.FPSDetection = get_int_value(file_buffer, "FPSDetection", g_cfg.FPSDetection);
- if (g_cfg.FPSDetection < 1)
- g_cfg.FPSDetection = 1;
- if (g_cfg.FPSDetection > 2)
- g_cfg.FPSDetection = 2;
-
- g_cfg.FrameRate = get_double_value(file_buffer, "FrameRate", g_cfg.FrameRate);
- g_cfg.FrameRate /= 10;
- if (g_cfg.FrameRate < 10.0f)
- g_cfg.FrameRate = 10.0f;
- if (g_cfg.FrameRate > 1000.0f)
- g_cfg.FrameRate = 1000.0f;
-
- g_cfg.CfgFixes = get_int_value(file_buffer, "CfgFixes", g_cfg.CfgFixes);
-
- g_cfg.UseFixes = get_int_value(file_buffer, "UseFixes", g_cfg.UseFixes);
- if (g_cfg.UseFixes < 0)
- g_cfg.UseFixes = 0;
- if (g_cfg.UseFixes > 1)
- g_cfg.UseFixes = 1;
-
- free(file_buffer);
-}
-
-static void ExecCfg(char const * arg) {
- char cfg[256];
- struct stat buf;
-
- strcpy(cfg, "./cfgGXVideo");
- if (stat(cfg, &buf) != -1) {
- if (fork() == 0) {
- execl(cfg, "cfgGXVideo", arg, NULL);
- exit(0);
- }
- return;
- }
-
- strcpy(cfg, "./cfg/cfgGXVideo");
- if (stat(cfg, &buf) != -1) {
- if (fork() == 0) {
- execl(cfg, "cfgGXVideo", arg, NULL);
- exit(0);
- }
- return;
- }
-
- sprintf(cfg, "%s/.pcsx/plugins/cfg/cfgGXVideo", getenv("HOME"));
- if (stat(cfg, &buf) != -1) {
- if (fork() == 0) {
- execl(cfg, "cfgGXVideo", arg, NULL);
- exit(0);
- }
- return;
- }
-
- printf("ERROR: cfgGXVideo file not found!\n");
-}
-
-void SoftDlgProc(void) {
- ExecCfg("CFG");
-}
-
-void AboutDlgProc(void) {
- char args[256];
- sprintf(args, "ABOUT");
- ExecCfg(args);
-}
-
-void ReadConfig(void) {
- /* set defaults */
- g_cfg.ResX = 640;
- g_cfg.ResY = 480;
- g_cfg.NoStretch = 0;
- g_cfg.Dithering = 0;
- g_cfg.FullScreen = 0;
- g_cfg.ShowFPS = 0;
- g_cfg.Maintain43 = 0;
- g_cfg.UseFrameLimit = 1;
- g_cfg.UseFrameSkip = 0;
- g_cfg.FPSDetection = 1;
- g_cfg.FrameRate = 200.0;
- g_cfg.CfgFixes = 0;
- g_cfg.UseFixes = 0;
-
- // read sets
- ReadConfigFile();
-}
-
-void WriteConfig(void) {
- FILE *f_out;
- char cfg_file_name[256];
-
- if (g_file_name)
- strcpy(cfg_file_name, g_file_name);
- else {
- strcpy(cfg_file_name, DEFAULT_CFG_NAME);
- f_out = fopen(cfg_file_name, "rb");
- if (!f_out) {
- strcpy(cfg_file_name, "cfg/" DEFAULT_CFG_NAME);
- f_out = fopen(cfg_file_name, "rb");
- if (!f_out)
- snprintf(cfg_file_name, 255, "%s/.pcsx/plugins/" DEFAULT_CFG_NAME, getenv("HOME"));
- else
- fclose(f_out);
- } else
- fclose(f_out);
- }
-
- f_out = fopen(cfg_file_name, "wb");
- if (!f_out)
- return;
-
-#define WRITE_VALUE(type, name) write_##type##_value(f_out, #name, g_cfg.name)
-
- WRITE_VALUE(int, ResX);
- WRITE_VALUE(int, ResY);
- WRITE_VALUE(int, NoStretch);
- WRITE_VALUE(int, Dithering);
- WRITE_VALUE(int, FullScreen);
- WRITE_VALUE(int, ShowFPS);
- WRITE_VALUE(int, Maintain43);
- WRITE_VALUE(int, UseFrameLimit);
- WRITE_VALUE(int, UseFrameSkip);
- WRITE_VALUE(int, FPSDetection);
- WRITE_VALUE(double, FrameRate);
- WRITE_VALUE(int, CfgFixes);
- WRITE_VALUE(int, UseFixes);
-
- fclose(f_out);
-}
+/*
+ * Copyright (C) 2010 Benoit Gschwind
+ * Inspired by original author : Pete Bernert
+ *
+ * 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 3 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., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#include <sys/stat.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "globals.h"
+#include "cfg.h"
+
+#define DEFAULT_CFG_NAME "gxvideo.cfg"
+
+int get_int_value (char const * file_buffer, char const * name, int dflt) {
+ char * p = strstr(file_buffer, name);
+ if (p != NULL) {
+ p += strlen(name);
+ while ((*p == ' ') || (*p == '='))
+ ++p;
+ if (*p != '\n')
+ return atoi(p);
+ }
+ return dflt;
+}
+
+double get_double_value(char const * file_buffer, char const * name,
+ double dflt) {
+ char * p = strstr(file_buffer, name);
+ if (p != NULL) {
+ p += strlen(name);
+ while ((*p == ' ') || (*p == '='))
+ ++p;
+ if (*p != '\n')
+ return atof(p);
+ }
+ return dflt;
+}
+
+void write_int_value (FILE * f, char const * name, int val) {
+ fprintf(f, "%s = %d\n", name, val);
+}
+
+void write_double_value (FILE * f, char const * name, double val) {
+ fprintf(f, "%s = %.1f\n", name, val);
+}
+
+void ReadConfigFile() {
+ struct stat buf;
+ FILE * f_in;
+ char cfg_file_name[256];
+ int len, size;
+ char * file_buffer;
+
+ if (g_file_name)
+ strcpy(cfg_file_name, g_file_name);
+ else {
+ strcpy(cfg_file_name, DEFAULT_CFG_NAME);
+ f_in = fopen(cfg_file_name, "rb");
+ if (!f_in) {
+ strcpy(cfg_file_name, "cfg/" DEFAULT_CFG_NAME);
+ f_in = fopen(cfg_file_name, "rb");
+ if (!f_in)
+ snprintf(cfg_file_name, 255, "%s/.pcsx/plugins/" DEFAULT_CFG_NAME, getenv("HOME"));
+ else
+ fclose(f_in);
+ } else
+ fclose(f_in);
+ }
+
+ if (stat(cfg_file_name, &buf) == -1)
+ return;
+ size = buf.st_size;
+
+ f_in = fopen(cfg_file_name, "rb");
+ if (!f_in)
+ return;
+
+ file_buffer = (char *) malloc(size + 1);
+ len = fread(file_buffer, 1, size, f_in);
+ /* ensure end_of_string */
+ file_buffer[len] = 0;
+ fclose(f_in);
+
+ g_cfg.ResX = get_int_value(file_buffer, "ResX", g_cfg.ResX);
+ if (g_cfg.ResX < 20)
+ g_cfg.ResX = 20;
+ g_cfg.ResX = (g_cfg.ResX / 4) * 4;
+ g_cfg.ResY = get_int_value(file_buffer, "ResY", g_cfg.ResY);
+ if (g_cfg.ResY < 20)
+ g_cfg.ResY = 20;
+ g_cfg.ResY = (g_cfg.ResY / 4) * 4;
+ g_cfg.Dithering = get_int_value(file_buffer, "Dithering", g_cfg.Dithering);
+ g_cfg.FullScreen = get_int_value(file_buffer, "FullScreen", g_cfg.FullScreen);
+ g_cfg.ShowFPS = get_int_value(file_buffer, "ShowFPS", g_cfg.ShowFPS);
+ if (g_cfg.ShowFPS < 0)
+ g_cfg.ShowFPS = 0;
+ if (g_cfg.ShowFPS > 1)
+ g_cfg.ShowFPS = 1;
+
+ g_cfg.Maintain43 = get_int_value(file_buffer, "Maintain43", g_cfg.Maintain43);
+ if (g_cfg.Maintain43 < 0)
+ g_cfg.Maintain43 = 0;
+ if (g_cfg.Maintain43 > 1)
+ g_cfg.Maintain43 = 1;
+
+ g_cfg.UseFrameLimit = get_int_value(file_buffer, "UseFrameLimit", g_cfg.UseFrameLimit);
+ if (g_cfg.UseFrameLimit < 0)
+ g_cfg.UseFrameLimit = 0;
+ if (g_cfg.UseFrameLimit > 1)
+ g_cfg.UseFrameLimit = 1;
+
+ g_cfg.UseFrameSkip = 0;
+
+ g_cfg.FPSDetection = get_int_value(file_buffer, "FPSDetection", g_cfg.FPSDetection);
+ if (g_cfg.FPSDetection < 1)
+ g_cfg.FPSDetection = 1;
+ if (g_cfg.FPSDetection > 2)
+ g_cfg.FPSDetection = 2;
+
+ g_cfg.FrameRate = get_double_value(file_buffer, "FrameRate", g_cfg.FrameRate);
+ g_cfg.FrameRate /= 10;
+ if (g_cfg.FrameRate < 10.0f)
+ g_cfg.FrameRate = 10.0f;
+ if (g_cfg.FrameRate > 1000.0f)
+ g_cfg.FrameRate = 1000.0f;
+
+ g_cfg.CfgFixes = get_int_value(file_buffer, "CfgFixes", g_cfg.CfgFixes);
+
+ g_cfg.UseFixes = get_int_value(file_buffer, "UseFixes", g_cfg.UseFixes);
+ if (g_cfg.UseFixes < 0)
+ g_cfg.UseFixes = 0;
+ if (g_cfg.UseFixes > 1)
+ g_cfg.UseFixes = 1;
+
+ free(file_buffer);
+}
+
+void ExecCfg(char const * arg) {
+ char cfg[256];
+ struct stat buf;
+
+ strcpy(cfg, "./cfgGXVideo");
+ if (stat(cfg, &buf) != -1) {
+ if (fork() == 0) {
+ execl(cfg, "cfgGXVideo", arg, NULL);
+ exit(0);
+ }
+ return;
+ }
+
+ strcpy(cfg, "./cfg/cfgGXVideo");
+ if (stat(cfg, &buf) != -1) {
+ if (fork() == 0) {
+ execl(cfg, "cfgGXVideo", arg, NULL);
+ exit(0);
+ }
+ return;
+ }
+
+ sprintf(cfg, "%s/.pcsx/plugins/cfg/cfgGXVideo", getenv("HOME"));
+ if (stat(cfg, &buf) != -1) {
+ if (fork() == 0) {
+ execl(cfg, "cfgGXVideo", arg, NULL);
+ exit(0);
+ }
+ return;
+ }
+
+ printf("ERROR: cfgGXVideo file not found!\n");
+}
+
+void SoftDlgProc(void) {
+ ExecCfg("CFG");
+}
+
+void AboutDlgProc(void) {
+ char args[256];
+ sprintf(args, "ABOUT");
+ ExecCfg(args);
+}
+
+void ReadConfig(void) {
+ /* set defaults */
+ g_cfg.ResX = 640;
+ g_cfg.ResY = 480;
+ g_cfg.NoStretch = 0;
+ g_cfg.Dithering = 0;
+ g_cfg.FullScreen = 0;
+ g_cfg.ShowFPS = 0;
+ g_cfg.Maintain43 = 0;
+ g_cfg.UseFrameLimit = 1;
+ g_cfg.UseFrameSkip = 0;
+ g_cfg.FPSDetection = 1;
+ g_cfg.FrameRate = 200.0;
+ g_cfg.CfgFixes = 0;
+ g_cfg.UseFixes = 0;
+
+ // read sets
+ ReadConfigFile();
+}
+
+void WriteConfig(void) {
+ FILE *f_out;
+ char cfg_file_name[256];
+
+ if (g_file_name)
+ strcpy(cfg_file_name, g_file_name);
+ else {
+ strcpy(cfg_file_name, DEFAULT_CFG_NAME);
+ f_out = fopen(cfg_file_name, "rb");
+ if (!f_out) {
+ strcpy(cfg_file_name, "cfg/" DEFAULT_CFG_NAME);
+ f_out = fopen(cfg_file_name, "rb");
+ if (!f_out)
+ snprintf(cfg_file_name, 255, "%s/.pcsx/plugins/" DEFAULT_CFG_NAME, getenv("HOME"));
+ else
+ fclose(f_out);
+ } else
+ fclose(f_out);
+ }
+
+ f_out = fopen(cfg_file_name, "wb");
+ if (!f_out)
+ return;
+
+#define WRITE_VALUE(type, name) write_##type##_value(f_out, #name, g_cfg.name)
+
+ WRITE_VALUE(int, ResX);
+ WRITE_VALUE(int, ResY);
+ WRITE_VALUE(int, NoStretch);
+ WRITE_VALUE(int, Dithering);
+ WRITE_VALUE(int, FullScreen);
+ WRITE_VALUE(int, ShowFPS);
+ WRITE_VALUE(int, Maintain43);
+ WRITE_VALUE(int, UseFrameLimit);
+ WRITE_VALUE(int, UseFrameSkip);
+ WRITE_VALUE(int, FPSDetection);
+ WRITE_VALUE(double, FrameRate);
+ WRITE_VALUE(int, CfgFixes);
+ WRITE_VALUE(int, UseFixes);
+
+ fclose(f_out);
+}
diff --git a/plugins/gxvideo/draw.c b/plugins/gxvideo/draw.c
index a83e429b..5e3b31ad 100644
--- a/plugins/gxvideo/draw.c
+++ b/plugins/gxvideo/draw.c
@@ -1,761 +1,757 @@
-/*
- * Copyright (C) 2010 Benoit Gschwind
- * Inspired by original author : Pete Bernert
- *
- * 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 3 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., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <math.h>
-#include <sys/shm.h>
-#include <X11/cursorfont.h>
-
-#include "globals.h"
-#include "swap.h"
-
-#define MAX(a,b) (((a) > (b)) ? (a) : (b))
-#define MIN(a,b) (((a) < (b)) ? (a) : (b))
-
-enum {
- GXV_YUV_PORT = 0, GXV_RGB_PORT = 1, GXV_MAX_PORT = 2,
-};
-
-gxv_blit_t available_port[GXV_MAX_PORT];
-
-/* Convert RGB to YUV */
-static inline uint32_t rgb_to_yuv(uint8_t R, uint8_t G, uint8_t B) {
- uint8_t Y, U, V;
- Y = abs(R * 2104 + G * 4130 + B * 802 + 4096 + 131072) >> 13;
- Y = MIN(Y, 235);
- U = abs(R * -1214 + G * -2384 + B * 3598 + 4096 + 1048576) >> 13;
- U = MIN(U, 240);
- V = abs(R * 3598 + G * -3013 + B * -585 + 4096 + 1048576) >> 13;
- V = MIN(V, 240);
- return Y << 24 | V << 16 | Y << 8 | U;
-}
-
-static inline uint32_t rgb_to_yuv2(uint8_t R0, uint8_t G0, uint8_t B0, uint8_t R1,
- uint8_t G1, uint8_t B1) {
- int32_t Y0, U0, V0;
- int32_t Y1, U1, V1;
- int32_t U, V;
- Y0 = abs(R0 * 2104 + G0 * 4130 + B0 * 802 + 4096 + 131072) >> 13;
- Y0 = MIN(Y0, 235);
- U0 = abs(R0 * -1214 + G0 * -2384 + B0 * 3598 + 4096 + 1048576) >> 13;
- U0 = MIN(U0, 240);
- V0 = abs(R0 * 3598 + G0 * -3013 + B0 * -585 + 4096 + 1048576) >> 13;
- V0 = MIN(V0, 240);
- Y1 = abs(R1 * 2104 + G1 * 4130 + B1 * 802 + 4096 + 131072) >> 13;
- Y1 = MIN(Y1, 235);
- U1 = abs(R1 * -1214 + G1 * -2384 + B1 * 3598 + 4096 + 1048576) >> 13;
- U1 = MIN(U1, 240);
- V1 = abs(R1 * 3598 + G1 * -3013 + B1 * -585 + 4096 + 1048576) >> 13;
- V1 = MIN(V1, 240);
- U = (U0 + U1) / 2;
- V = (V0 + V1) / 2;
- return Y1 << 24 | V << 16 | Y0 << 8 | U;
-}
-
-#define colorMask8 0x00FEFEFE
-#define lowPixelMask8 0x00010101
-#define qcolorMask8 0x00FCFCFC
-#define qlowpixelMask8 0x00030303
-
-static Atom xv_intern_atom_if_exists(Display *display, char const * atom_name) {
- XvAttribute * attributes;
- int attrib_count, i;
- Atom xv_atom = None;
-
- attributes = XvQueryPortAttributes(display, g_draw.xv_port, &attrib_count);
- if (attributes != NULL) {
- for (i = 0; i < attrib_count; ++i) {
- if (strcmp(attributes[i].name, atom_name) == 0) {
- xv_atom = XInternAtom(display, atom_name, False);
- break; // found what we want, break out
- }
- }
- XFree(attributes);
- }
-
- return xv_atom;
-}
-
-// close display
-
-static void DestroyDisplay(void) {
- if (g_draw.display) {
- XFreeColormap(g_draw.display, g_draw.colormap);
- if (g_draw.hGC) {
- XFreeGC(g_draw.display, g_draw.hGC);
- g_draw.hGC = 0;
- }
- if (g_draw.Ximage) {
- XDestroyImage(g_draw.Ximage);
- g_draw.Ximage = 0;
- }
- if (g_draw.XCimage) {
- XFree(g_draw.XCimage);
- g_draw.XCimage = 0;
- }
- if (g_draw.XFimage) {
- XDestroyImage(g_draw.XFimage);
- g_draw.XFimage = 0;
- }
-
- XShmDetach(g_draw.display, &g_draw.shminfo);
- shmdt(g_draw.shminfo.shmaddr);
- shmctl(g_draw.shminfo.shmid, IPC_RMID, NULL);
-
- Atom atom_vsync = xv_intern_atom_if_exists(g_draw.display,
- "XV_SYNC_TO_VBLANK");
- if (atom_vsync != None) {
- XvSetPortAttribute(g_draw.display, g_draw.xv_port, atom_vsync,
- g_draw.xv_vsync);
- }
-
- XSync(g_draw.display, False);
-
- XCloseDisplay(g_draw.display);
- }
-}
-
-// Create display
-
-static void create_display(void) {
- //fprintf(stderr, "Entering %s\n", __FUNCTION__);
- XSetWindowAttributes winattr;
- int myscreen;
- Screen * screen;
- XEvent event;
- XSizeHints hints;
- XWMHints wm_hints;
- MotifWmHints mwmhints;
- Atom mwmatom;
-
- Atom delwindow;
-
- XGCValues gcv;
- int i;
-
- int ret, j, p;
- int formats;
- unsigned int p_num_adaptors = 0, p_num_ports = 0;
-
- XvAdaptorInfo *ai;
- XvImageFormatValues *fo;
-
- // Open display
- g_draw.display = XOpenDisplay(NULL);
-
- if (!g_draw.display) {
- fprintf(stderr, "Failed to open display!!!\n");
- DestroyDisplay();
- return;
- }
-
- myscreen = DefaultScreen(g_draw.display);
-
- // desktop fullscreen switch
- if (g_cfg.FullScreen)
- g_draw.fx = 1;
-
- screen = DefaultScreenOfDisplay(g_draw.display);
-
- g_draw.root_window_id = RootWindow(g_draw.display, myscreen);
-
- //Look for an Xvideo RGB port
- ret = XvQueryAdaptors(g_draw.display, g_draw.root_window_id,
- &p_num_adaptors, &ai);
- if (ret != Success) {
- if (ret == XvBadExtension)
- fprintf(stderr, "XvBadExtension returned at XvQueryExtension.\n");
- else if (ret == XvBadAlloc)
- fprintf(stderr, "XvBadAlloc returned at XvQueryExtension.\n");
- else
- fprintf(stderr, "other error happaned at XvQueryAdaptors.\n");
- exit(EXIT_FAILURE);
- }
-
- g_draw.depth = DefaultDepth(g_draw.display, myscreen);
-
- g_draw.xv_id = -1;
- g_draw.xv_port = -1;
- g_draw.xv = -1;
-
- for (i = 0; i < p_num_adaptors; i++) {
- p_num_ports = ai[i].base_id + ai[i].num_ports;
- for (p = ai[i].base_id; p < p_num_ports; p++) {
- fo = XvListImageFormats(g_draw.display, p, &formats);
- for (j = 0; j < formats; ++j) {
-
- if (fo[j].type == XvYUV && fo[j].bits_per_pixel == 16
- && fo[j].format == XvPacked && strncmp("UYVY",
- fo[j].component_order, 4) == 0) {
- g_draw.xv_port = p;
- g_draw.xv_id = fo[j].id;
-
- g_draw.xv = GXV_YUV_PORT;
- j = formats;
- p = p_num_ports;
- i = p_num_adaptors;
- break;
- }
-
- if (fo[j].type == XvRGB && fo[j].bits_per_pixel == 32) {
- g_draw.xv_port = p;
- g_draw.xv_id = fo[j].id;
- printf("RGB mode found. id: %x\n", g_draw.xv_id);
- g_draw.xv = GXV_RGB_PORT;
- //break out of loops
- j = formats;
- p = p_num_ports;
- i = p_num_adaptors;
- }
- }
-
- if (fo)
- XFree(fo);
- }
- }
-
- if (p_num_adaptors > 0)
- XvFreeAdaptorInfo(ai);
-
- if (g_draw.xv < 0) {
- fprintf(stderr, "RGB & YUV not found. Quitting.\n");
- exit(EXIT_FAILURE);
- }
-
- Atom atom_vsync = xv_intern_atom_if_exists(g_draw.display,
- "XV_SYNC_TO_VBLANK");
- if (atom_vsync != None) {
- XvGetPortAttribute(g_draw.display, g_draw.xv_port, atom_vsync,
- &g_draw.xv_vsync);
- XvSetPortAttribute(g_draw.display, g_draw.xv_port, atom_vsync, 0);
- }
-
- g_draw.myvisual = 0;
-
- if (XMatchVisualInfo(g_draw.display, myscreen, g_draw.depth, TrueColor,
- &g_draw.vi))
- g_draw.myvisual = &g_draw.vi;
-
- if (!g_draw.myvisual) {
- fprintf(stderr, "Failed to obtain visual!\n");
- DestroyDisplay();
- return;
- }
-
- if (!g_cfg.FullScreen)
- g_draw.cursor = XCreateFontCursor(g_draw.display, XC_trek);
- else {
- g_draw.cursor = None;
- }
-
- g_draw.colormap = XCreateColormap(g_draw.display, g_draw.root_window_id,
- g_draw.myvisual->visual, AllocNone);
-
- winattr.background_pixel = BlackPixelOfScreen(screen);
- winattr.border_pixel = WhitePixelOfScreen(screen);
- winattr.bit_gravity = ForgetGravity;
- winattr.win_gravity = NorthWestGravity;
- winattr.backing_store = NotUseful;
-
- winattr.override_redirect = False;
- winattr.save_under = False;
- winattr.event_mask = 0;
- winattr.do_not_propagate_mask = 0;
- winattr.colormap = g_draw.colormap;
- winattr.cursor = None;
-
- g_draw.window = XCreateWindow(g_draw.display, g_draw.root_window_id, 0, 0,
- g_cfg.ResX, g_cfg.ResY, 0, g_draw.myvisual->depth, InputOutput,
- g_draw.myvisual->visual, CWBorderPixel | CWBackPixel | CWEventMask
- | CWDontPropagate | CWColormap | CWCursor, &winattr);
-
- if (!g_draw.window) {
- fprintf(stderr, "Failed in XCreateWindow()!!!\n");
- DestroyDisplay();
- return;
- }
-
- delwindow = XInternAtom(g_draw.display, "WM_DELETE_WINDOW", 0);
- XSetWMProtocols(g_draw.display, g_draw.window, &delwindow, 1);
-
- hints.flags = USPosition | USSize;
- hints.base_width = g_cfg.ResX;
- hints.base_height = g_cfg.ResY;
-
- wm_hints.input = 1;
- wm_hints.flags = InputHint;
-
- XSetWMHints(g_draw.display, g_draw.window, &wm_hints);
- XSetWMNormalHints(g_draw.display, g_draw.window, &hints);
- //if (pCaptionText)
- // XStoreName(draw_ctx.display, draw_ctx.window, pCaptionText);
- //else
- XStoreName(g_draw.display, g_draw.window, "GXVideo GPU");
-
- XDefineCursor(g_draw.display, g_draw.window, g_draw.cursor);
-
- // hack to get rid of window title bar
- if (g_draw.fx) {
- mwmhints.flags = MWM_HINTS_DECORATIONS;
- mwmhints.decorations = 0;
- mwmatom = XInternAtom(g_draw.display, "_MOTIF_WM_HINTS", 0);
- XChangeProperty(g_draw.display, g_draw.window, mwmatom, mwmatom, 32,
- PropModeReplace, (unsigned char *) &mwmhints, 4);
- }
-
- // key stuff
- XSelectInput(g_draw.display, g_draw.window, FocusChangeMask | ExposureMask
- | KeyPressMask | KeyReleaseMask);
-
- XMapRaised(g_draw.display, g_draw.window);
- XClearWindow(g_draw.display, g_draw.window);
- XWindowEvent(g_draw.display, g_draw.window, ExposureMask, &event);
-
- if (g_draw.fx) {
- XResizeWindow(g_draw.display, g_draw.window, screen->width,
- screen->height);
-
- hints.min_width = hints.max_width = hints.base_width = screen->width;
- hints.min_height = hints.max_height = hints.base_height
- = screen->height;
-
- XSetWMNormalHints(g_draw.display, g_draw.window, &hints);
-
- // set the window layer for GNOME
- {
- XEvent xev;
-
- memset(&xev, 0, sizeof(xev));
- xev.xclient.type = ClientMessage;
- xev.xclient.serial = 0;
- xev.xclient.send_event = 1;
- xev.xclient.message_type = XInternAtom(g_draw.display,
- "_NET_WM_STATE", 0);
- xev.xclient.window = g_draw.window;
- xev.xclient.format = 32;
- xev.xclient.data.l[0] = 1;
- xev.xclient.data.l[1] = XInternAtom(g_draw.display,
- "_NET_WM_STATE_FULLSCREEN", 0);
- xev.xclient.data.l[2] = 0;
- xev.xclient.data.l[3] = 0;
- xev.xclient.data.l[4] = 0;
-
- XSendEvent(g_draw.display, g_draw.root_window_id, 0,
- SubstructureRedirectMask | SubstructureNotifyMask, &xev);
- }
- }
-
- gcv.graphics_exposures = False;
- gcv.foreground = WhitePixelOfScreen(screen);
- gcv.background = BlackPixelOfScreen(screen);
- g_draw.hGC = XCreateGC(g_draw.display, g_draw.window, GCGraphicsExposures
- |GCForeground | GCBackground, &gcv);
- if (!g_draw.hGC) {
- fprintf(stderr, "No gfx context!!!\n");
- DestroyDisplay();
- }
-
- g_draw.Xpixels = (char *) malloc(600 * 15 * 4);
-
- uint32_t color;
- if (g_draw.xv == GXV_YUV_PORT)
- color = rgb_to_yuv(0x00, 0x00, 0xff);
- else
- color = 0x0000ff;
-
- for (i = 0; i < 600 * 15; ++i)
- ((uint32_t *) g_draw.Xpixels)[i] = color;
-
- g_draw.XFimage = XCreateImage(g_draw.display, g_draw.myvisual->visual,
- g_draw.depth, ZPixmap, 0, (char *) g_draw.Xpixels, 600, 15,
- g_draw.depth > 16 ? 32 : 16, 0);
-
- /* fix the green back ground in YUV mode */
- if (g_draw.xv == GXV_YUV_PORT)
- color = rgb_to_yuv(0x00, 0x00, 0x00);
- else
- color = 0;
-
- g_draw.Xpixels = (char *) malloc(8 * 8 * 4);
- for (i = 0; i < 8 * 8; ++i)
- ((uint32_t *) g_draw.Xpixels)[i] = color;
-
- g_draw.XCimage = XvCreateImage(g_draw.display, g_draw.xv_port,
- g_draw.xv_id, (char *) g_draw.Xpixels, 8, 8);
-
- /*
- Allocate max that could be needed:
- Big(est?) PSX res: 640x512
- 32bpp (times 4)
- 2xsai func= 3xwidth,3xheight
- = approx 11.8mb
- */
- g_draw.shminfo.shmid
- = shmget(IPC_PRIVATE, 1024 * 512 * 4, IPC_CREAT | 0777);
- g_draw.shminfo.shmaddr = shmat(g_draw.shminfo.shmid, 0, 0);
- g_draw.shminfo.readOnly = 0;
-
- if (!XShmAttach(g_draw.display, &g_draw.shminfo)) {
- printf("XShmAttach failed !\n");
- exit(-1);
- }
-
- uint32_t *pShmaddr = (uint32_t *) g_draw.shminfo.shmaddr;
- for (i = 0; i < 1024 * 512; ++i)
- pShmaddr[i] = color;
-
- //fprintf(stderr, "Return %s\n", __FUNCTION__);
- return;
-}
-
-#if 0
-static int rgb_check_port(XvImageFormatValues const * fo) {
- if (fo->type == XvRGB && fo->bits_per_pixel == 32) {
- g_draw.xv_id = fo->id;
- return 1;
- }
- return 0;
-}
-#endif
-
-static void rgb_blit_16(int8_t * buff, int32_t x, int32_t y, int32_t w, int32_t h) {
- //fprintf(stderr, "BlitToYUV\n");
- int16_t * src_pxl;
- int8_t * dst_pxl;
- int32_t startxy;
- int32_t _x, _y;
-
- startxy = 0;
- dst_pxl = buff;
- for (_y = y; _y < h; ++_y) {
- src_pxl = &g_gpu.psx_vram.s16[startxy];
- for (_x = x; _x < w; ++_x) {
- dst_pxl[0] = ((*src_pxl) << 3) & 0xf8;
- dst_pxl[1] = ((*src_pxl) >> 2) & 0xf8;
- dst_pxl[2] = ((*src_pxl) >> 7) & 0xf8;
- dst_pxl += 3;
- src_pxl += 1;
- }
- startxy += 2048;
- }
-}
-
-static void rgb_blit_24(int8_t * buff, int32_t x, int32_t y, int32_t w, int32_t h) {
- //fprintf(stderr, "BlitToYUV\n");
- int8_t * src_pxl;
- int8_t * dst_pxl;
- int32_t startxy;
- int32_t _x, _y;
-
- dst_pxl = buff;
- startxy = 0;
- for (_y = y; _y < h; ++_y) {
- src_pxl = &g_gpu.psx_vram.s8[startxy];
- for (_x = x; _x < w; ++_x) {
- dst_pxl[0] = src_pxl[0];
- dst_pxl[1] = src_pxl[1];
- dst_pxl[2] = src_pxl[2];
- dst_pxl += 3;
- src_pxl += 3;
- }
- startxy += 2048;
- }
-}
-
-#if 0
-static int yuyv_check_port(XvImageFormatValues * fo) {
- if (fo->type == XvYUV && fo->bits_per_pixel == 16 && fo->format == XvPacked
- && strncmp("UYVY", fo->component_order, 4) == 0) {
- g_draw.xv_id = fo->id;
- return 1;
- }
- return 0;
-}
-#endif
-
-static void yuyv_blit_24(int8_t * buff, int32_t x, int32_t y, int32_t w, int32_t h) {
- //fprintf(stderr, "yuyv_blit_24 %d %d %d %d\n", x, y, w, h);
- uint8_t * src_pxl;
- int8_t R0, G0, B0;
- int8_t R1, G1, B1;
- uint32_t * dst_pxl;
- int32_t _x, _y;
-
- /* x and w should be multiple of 2 to be align */
- x = x & 0xfffffffe;
- w = (w + 1) & 0xfffffffe;
-
- dst_pxl = (uint32_t *) (buff);
- for (_y = y; _y < (y + h); _y += 1) {
- src_pxl = &g_gpu.psx_vram.u8[x * 3 + (_y * 2048)];
- for (_x = 0; _x < (w / 2); ++_x) {
- R0 = src_pxl[0];
- G0 = src_pxl[1];
- B0 = src_pxl[2];
- R1 = src_pxl[3];
- G1 = src_pxl[4];
- B1 = src_pxl[5];
- *dst_pxl++ = rgb_to_yuv2(R0, G0, B0, R1, G1, B1);
- src_pxl += 6;
- }
- }
-}
-
-static void yuyv_blit_16(int8_t * buff, int32_t x, int32_t y, int32_t w, int32_t h) {
- //fprintf(stderr, "yuyv_blit_16 %d %d %d %d\n", x, y, w, h);
- int8_t R0, G0, B0;
- int8_t R1, G1, B1;
- uint32_t * dst_pxl;
- int32_t _x, _y;
- int32_t s;
- uint16_t * src_pxl;
-
- /* x must be a multiple of 2 */
- /* x and w must be a multiple of 2 */
- x = x & 0xfffffffe;
- w = (w + 1) & 0xfffffffe;
-
- dst_pxl = (uint32_t *) (buff);
- for (_y = y; _y < (y + h); _y += 1) {
- src_pxl = &g_gpu.psx_vram.u16[x + (_y * 1024)];
- for (_x = 0; _x < (w / 2); ++_x) {
- s = GETLE16(src_pxl++);
- R0 = (s << 3) & 0xf8;
- G0 = (s >> 2) & 0xf8;
- B0 = (s >> 7) & 0xf8;
- s = GETLE16(src_pxl++);
- R1 = (s << 3) & 0xf8;
- G1 = (s >> 2) & 0xf8;
- B1 = (s >> 7) & 0xf8;
- *dst_pxl++ = rgb_to_yuv2(R0, G0, B0, R1, G1, B1);
- }
- }
-}
-
-/**
- * compute the position and the size of output screen
- * The aspect of the psx output mode is preserved.
- * Note: dest dx,dy,dw,dh are both input and output variables
- */
-static inline void maintain_aspect(uint32_t * dx, uint32_t * dy, uint32_t * dw,
- uint32_t * dh, int32_t w, int32_t h) {
-
- double ratio_x = ((double) *dw) / ((double) w);
- double ratio_y = ((double) *dh) / ((double) h);
-
- double ratio;
- if (ratio_x < ratio_y) {
- ratio = ratio_x;
- } else {
- ratio = ratio_y;
- }
-
- uint32_t tw = (uint32_t) floor(w * ratio);
- uint32_t th = (uint32_t) floor(h * ratio);
-
- *dx += (uint32_t) floor((*dw - tw) / 2.0);
- *dy += (uint32_t) floor((*dh - th) / 2.0);
- *dw = tw;
- *dh = th;
-}
-
-void do_buffer_swap(void) {
- //Screen *screen;
- Window _dw;
- XvImage *xvi;
- unsigned int dstx, dsty;
- unsigned int _d, _w, _h; //don't care about _d
-
- dstx = 0;
- dsty = 0;
-
- XSync(g_draw.display, False);
-
- XGetGeometry(g_draw.display, g_draw.window, &_dw, (int *) &_d, (int *) &_d,
- &_w, &_h, &_d, &_d);
-
- if (g_cfg.ShowFPS) {
- dsty += 15;
- _h -= 15;
- compute_fps();
- snprintf(g_draw.msg, 511, "FPS : %f", g_draw.fps);
- XDrawImageString(g_draw.display, g_draw.window, g_draw.hGC, 0, 12,
- g_draw.msg, strlen(g_draw.msg));
- }
-
- uint32_t _x_, _y_, _w_, _h_;
-
- /* if video mode is valid */
- if (g_gpu.dsp.mode.x) {
-
- if (g_gpu.status_reg & STATUS_RGB24) {
- _x_ = (g_gpu.dsp.position.x * 2) / 3;
- } else {
- _x_ = g_gpu.dsp.position.x;
- }
- _y_ = g_gpu.dsp.position.y;
- _w_ = (g_gpu.dsp.range.x1 - g_gpu.dsp.range.x0) / g_gpu.dsp.mode.x;
- _h_ = (g_gpu.dsp.range.y1 - g_gpu.dsp.range.y0) * g_gpu.dsp.mode.y;
-
- if (g_gpu.status_reg & STATUS_RGB24) {
- available_port[g_draw.xv].blit_24_bits(
- (int8_t *) g_draw.shminfo.shmaddr, _x_, _y_, _w_, _h_);
- } else {
- available_port[GXV_YUV_PORT].blit_16_bits(
- (int8_t *) g_draw.shminfo.shmaddr, _x_, _y_, _w_, _h_);
- }
-
- xvi = XvShmCreateImage(g_draw.display, g_draw.xv_port, g_draw.xv_id, 0,
- _w_, _h_, &g_draw.shminfo);
-
- xvi->data = g_draw.shminfo.shmaddr;
-
- //screen = DefaultScreenOfDisplay(g_draw.display);
- //screennum = DefaultScreen(display);
-
- // if (g_cfg.FullScreen) {
- // _w = screen->width;
- // _h = screen->height;
- // }
-
- if (g_cfg.Maintain43)
- maintain_aspect(&dstx, &dsty, &_w, &_h, _w_, (g_gpu.dsp.range.y1
- - g_gpu.dsp.range.y0));
-
- // int _i;
- // int32_t * dst_pxl;
- // dst_pxl = (int32_t *) &g_draw.shminfo.shmaddr[2048 * _y_];
- // for (_i = _x_ / 2; _i < (_x_ + _w_) / 2; ++_i)
- // dst_pxl[_i] = rgb_to_yuv2(255, 0, 0, 255, 0, 0);
- // dst_pxl = (int32_t *) &g_draw.shminfo.shmaddr[2048 * (_y_ + _h_)];
- // for (_i = _x_ / 2; _i < (_x_ + _w_) / 2; ++_i)
- // dst_pxl[_i] = rgb_to_yuv2(255, 0, 0, 255, 0, 0);
- // dst_pxl = (int32_t *) &g_draw.shminfo.shmaddr[4 * (_x_ / 2)];
- // for (_i = _y_; _i < (_y_ + _h_); ++_i)
- // dst_pxl[_i * 512] = rgb_to_yuv2(255, 0, 0, 255, 0, 0);
- // dst_pxl = (int32_t *) &g_draw.shminfo.shmaddr[4 * ((_x_ + _w_) / 2)];
- // for (_i = _y_; _i < (_y_ + _h_); ++_i)
- // dst_pxl[_i * 512] = rgb_to_yuv2(255, 0, 0, 255, 0, 0);
-
- //fprintf(stderr, "From %d,%d,%d,%d\n", _x_, _y_, _w_, _h_);
- XvShmPutImage(g_draw.display, g_draw.xv_port, g_draw.window,
- g_draw.hGC, xvi, 0, 0, _w_, _h_,
- //0, 0, 1024, 512,
- /* dst */
- dstx, dsty, _w, _h, 1);
- XFree(xvi);
- }
-}
-
-void do_clear_screen_buffer(void) // CLEAR DX BUFFER
-{
- XClearWindow(g_draw.display, g_draw.window);
-}
-
-static void Xcleanup() // X CLEANUP
-{
- //CloseMenu();
-}
-
-/**
- * Call on GPUopen
- * Return the current display.
- **/
-unsigned long init_display() {
-
- available_port[GXV_YUV_PORT].blit_24_bits = yuyv_blit_24;
- available_port[GXV_YUV_PORT].blit_16_bits = yuyv_blit_16;
-
- available_port[GXV_RGB_PORT].blit_24_bits = rgb_blit_24;
- available_port[GXV_RGB_PORT].blit_16_bits = rgb_blit_16;
-
- create_display(); // x stuff
- g_draw.bIsFirstFrame = 0;
- return (unsigned long) g_draw.display;
-}
-
-void CloseDisplay(void) {
- Xcleanup(); // cleanup dx
- DestroyDisplay();
-}
-
-void CreatePic(unsigned char * pMem) {
- unsigned char * p = (unsigned char *) malloc(128 * 96 * 4);
- unsigned char * ps;
- //int x, y;
-
- ps = p;
-
- // if (iDesktopCol == 16) {
- // unsigned short s;
- // for (y = 0; y < 96; y++) {
- // for (x = 0; x < 128; x++) {
- // s = (*(pMem + 0)) >> 3;
- // s |= ((*(pMem + 1)) & 0xfc) << 3;
- // s |= ((*(pMem + 2)) & 0xf8) << 8;
- // pMem += 3;
- // *((unsigned short *) (ps + y * 256 + x * 2)) = s;
- // }
- // }
- // } else if (iDesktopCol == 15) {
- // unsigned short s;
- // for (y = 0; y < 96; y++) {
- // for (x = 0; x < 128; x++) {
- // s = (*(pMem + 0)) >> 3;
- // s |= ((*(pMem + 1)) & 0xfc) << 2;
- // s |= ((*(pMem + 2)) & 0xf8) << 7;
- // pMem += 3;
- // *((unsigned short *) (ps + y * 256 + x * 2)) = s;
- // }
- // }
- // } else if (iDesktopCol == 32) {
- // uint32_t l;
- // for (y = 0; y < 96; y++) {
- // for (x = 0; x < 128; x++) {
- // l = *(pMem + 0);
- // l |= (*(pMem + 1)) << 8;
- // l |= (*(pMem + 2)) << 16;
- // pMem += 3;
- // *((uint32_t *) (ps + y * 512 + x * 4)) = l;
- // }
- // }
- // }
-
- g_draw.XPimage = XCreateImage(g_draw.display, g_draw.myvisual->visual,
- g_draw.depth, ZPixmap, 0, (char *) p, 128, 96,
- g_draw.depth > 16 ? 32 : 16, 0);
-}
-
-void DestroyPic(void) {
- if (g_draw.XPimage) { /*
- XPutImage(display,window,hGC, XCimage,
- 0, 0, 0, 0, iResX, iResY);*/
- XDestroyImage(g_draw.XPimage);
- g_draw.XPimage = 0;
- }
-}
-
-void ShowGpuPic(void) {
-}
-
-void ShowTextGpuPic(void) {
-}
+/*
+ * Copyright (C) 2010 Benoit Gschwind
+ * Inspired by original author : Pete Bernert
+ *
+ * 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 3 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., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <math.h>
+#include <sys/shm.h>
+#include <X11/cursorfont.h>
+
+#include "globals.h"
+#include "swap.h"
+
+#define MAX(a,b) (((a) > (b)) ? (a) : (b))
+#define MIN(a,b) (((a) < (b)) ? (a) : (b))
+
+enum {
+ GXV_YUV_PORT = 0, GXV_RGB_PORT = 1, GXV_MAX_PORT = 2,
+};
+
+gxv_blit_t available_port[GXV_MAX_PORT];
+
+/* Convert RGB to YUV */
+inline uint32_t rgb_to_yuv(uint8_t R, uint8_t G, uint8_t B) {
+ uint8_t Y, U, V;
+ Y = abs(R * 2104 + G * 4130 + B * 802 + 4096 + 131072) >> 13;
+ Y = MIN(Y, 235);
+ U = abs(R * -1214 + G * -2384 + B * 3598 + 4096 + 1048576) >> 13;
+ U = MIN(U, 240);
+ V = abs(R * 3598 + G * -3013 + B * -585 + 4096 + 1048576) >> 13;
+ V = MIN(V, 240);
+ return Y << 24 | V << 16 | Y << 8 | U;
+}
+
+inline uint32_t rgb_to_yuv2(uint8_t R0, uint8_t G0, uint8_t B0, uint8_t R1,
+ uint8_t G1, uint8_t B1) {
+ int32_t Y0, U0, V0;
+ int32_t Y1, U1, V1;
+ int32_t U, V;
+ Y0 = abs(R0 * 2104 + G0 * 4130 + B0 * 802 + 4096 + 131072) >> 13;
+ Y0 = MIN(Y0, 235);
+ U0 = abs(R0 * -1214 + G0 * -2384 + B0 * 3598 + 4096 + 1048576) >> 13;
+ U0 = MIN(U0, 240);
+ V0 = abs(R0 * 3598 + G0 * -3013 + B0 * -585 + 4096 + 1048576) >> 13;
+ V0 = MIN(V0, 240);
+ Y1 = abs(R1 * 2104 + G1 * 4130 + B1 * 802 + 4096 + 131072) >> 13;
+ Y1 = MIN(Y1, 235);
+ U1 = abs(R1 * -1214 + G1 * -2384 + B1 * 3598 + 4096 + 1048576) >> 13;
+ U1 = MIN(U1, 240);
+ V1 = abs(R1 * 3598 + G1 * -3013 + B1 * -585 + 4096 + 1048576) >> 13;
+ V1 = MIN(V1, 240);
+ U = (U0 + U1) / 2;
+ V = (V0 + V1) / 2;
+ return Y1 << 24 | V << 16 | Y0 << 8 | U;
+}
+
+#define colorMask8 0x00FEFEFE
+#define lowPixelMask8 0x00010101
+#define qcolorMask8 0x00FCFCFC
+#define qlowpixelMask8 0x00030303
+
+static Atom xv_intern_atom_if_exists(Display *display, char const * atom_name) {
+ XvAttribute * attributes;
+ int attrib_count, i;
+ Atom xv_atom = None;
+
+ attributes = XvQueryPortAttributes(display, g_draw.xv_port, &attrib_count);
+ if (attributes != NULL) {
+ for (i = 0; i < attrib_count; ++i) {
+ if (strcmp(attributes[i].name, atom_name) == 0) {
+ xv_atom = XInternAtom(display, atom_name, False);
+ break; // found what we want, break out
+ }
+ }
+ XFree(attributes);
+ }
+
+ return xv_atom;
+}
+
+// close display
+
+void DestroyDisplay(void) {
+ if (g_draw.display) {
+ XFreeColormap(g_draw.display, g_draw.colormap);
+ if (g_draw.hGC) {
+ XFreeGC(g_draw.display, g_draw.hGC);
+ g_draw.hGC = 0;
+ }
+ if (g_draw.Ximage) {
+ XDestroyImage(g_draw.Ximage);
+ g_draw.Ximage = 0;
+ }
+ if (g_draw.XCimage) {
+ XFree(g_draw.XCimage);
+ g_draw.XCimage = 0;
+ }
+ if (g_draw.XFimage) {
+ XDestroyImage(g_draw.XFimage);
+ g_draw.XFimage = 0;
+ }
+
+ XShmDetach(g_draw.display, &g_draw.shminfo);
+ shmdt(g_draw.shminfo.shmaddr);
+ shmctl(g_draw.shminfo.shmid, IPC_RMID, NULL);
+
+ Atom atom_vsync = xv_intern_atom_if_exists(g_draw.display,
+ "XV_SYNC_TO_VBLANK");
+ if (atom_vsync != None) {
+ XvSetPortAttribute(g_draw.display, g_draw.xv_port, atom_vsync,
+ g_draw.xv_vsync);
+ }
+
+ XSync(g_draw.display, False);
+
+ XCloseDisplay(g_draw.display);
+ }
+}
+
+// Create display
+
+void create_display(void) {
+ //fprintf(stderr, "Entering %s\n", __FUNCTION__);
+ XSetWindowAttributes winattr;
+ int myscreen;
+ Screen * screen;
+ XEvent event;
+ XSizeHints hints;
+ XWMHints wm_hints;
+ MotifWmHints mwmhints;
+ Atom mwmatom;
+
+ Atom delwindow;
+
+ XGCValues gcv;
+ int i;
+
+ int ret, j, p;
+ int formats;
+ unsigned int p_num_adaptors = 0, p_num_ports = 0;
+
+ XvAdaptorInfo *ai;
+ XvImageFormatValues *fo;
+
+ // Open display
+ g_draw.display = XOpenDisplay(NULL);
+
+ if (!g_draw.display) {
+ fprintf(stderr, "Failed to open display!!!\n");
+ DestroyDisplay();
+ return;
+ }
+
+ myscreen = DefaultScreen(g_draw.display);
+
+ // desktop fullscreen switch
+ if (g_cfg.FullScreen)
+ g_draw.fx = 1;
+
+ screen = DefaultScreenOfDisplay(g_draw.display);
+
+ g_draw.root_window_id = RootWindow(g_draw.display, myscreen);
+
+ //Look for an Xvideo RGB port
+ ret = XvQueryAdaptors(g_draw.display, g_draw.root_window_id,
+ &p_num_adaptors, &ai);
+ if (ret != Success) {
+ if (ret == XvBadExtension)
+ fprintf(stderr, "XvBadExtension returned at XvQueryExtension.\n");
+ else if (ret == XvBadAlloc)
+ fprintf(stderr, "XvBadAlloc returned at XvQueryExtension.\n");
+ else
+ fprintf(stderr, "other error happaned at XvQueryAdaptors.\n");
+ exit(EXIT_FAILURE);
+ }
+
+ g_draw.depth = DefaultDepth(g_draw.display, myscreen);
+
+ g_draw.xv_id = -1;
+ g_draw.xv_port = -1;
+ g_draw.xv = -1;
+
+ for (i = 0; i < p_num_adaptors; i++) {
+ p_num_ports = ai[i].base_id + ai[i].num_ports;
+ for (p = ai[i].base_id; p < p_num_ports; p++) {
+ fo = XvListImageFormats(g_draw.display, p, &formats);
+ for (j = 0; j < formats; ++j) {
+
+ if (fo[j].type == XvYUV && fo[j].bits_per_pixel == 16
+ && fo[j].format == XvPacked && strncmp("UYVY",
+ fo[j].component_order, 4) == 0) {
+ g_draw.xv_port = p;
+ g_draw.xv_id = fo[j].id;
+
+ g_draw.xv = GXV_YUV_PORT;
+ j = formats;
+ p = p_num_ports;
+ i = p_num_adaptors;
+ break;
+ }
+
+ if (fo[j].type == XvRGB && fo[j].bits_per_pixel == 32) {
+ g_draw.xv_port = p;
+ g_draw.xv_id = fo[j].id;
+ printf("RGB mode found. id: %x\n", g_draw.xv_id);
+ g_draw.xv = GXV_RGB_PORT;
+ //break out of loops
+ j = formats;
+ p = p_num_ports;
+ i = p_num_adaptors;
+ }
+ }
+
+ if (fo)
+ XFree(fo);
+ }
+ }
+
+ if (p_num_adaptors > 0)
+ XvFreeAdaptorInfo(ai);
+
+ if (g_draw.xv < 0) {
+ fprintf(stderr, "RGB & YUV not found. Quitting.\n");
+ exit(EXIT_FAILURE);
+ }
+
+ Atom atom_vsync = xv_intern_atom_if_exists(g_draw.display,
+ "XV_SYNC_TO_VBLANK");
+ if (atom_vsync != None) {
+ XvGetPortAttribute(g_draw.display, g_draw.xv_port, atom_vsync,
+ &g_draw.xv_vsync);
+ XvSetPortAttribute(g_draw.display, g_draw.xv_port, atom_vsync, 0);
+ }
+
+ g_draw.myvisual = 0;
+
+ if (XMatchVisualInfo(g_draw.display, myscreen, g_draw.depth, TrueColor,
+ &g_draw.vi))
+ g_draw.myvisual = &g_draw.vi;
+
+ if (!g_draw.myvisual) {
+ fprintf(stderr, "Failed to obtain visual!\n");
+ DestroyDisplay();
+ return;
+ }
+
+ if (!g_cfg.FullScreen)
+ g_draw.cursor = XCreateFontCursor(g_draw.display, XC_trek);
+ else {
+ g_draw.cursor = None;
+ }
+
+ g_draw.colormap = XCreateColormap(g_draw.display, g_draw.root_window_id,
+ g_draw.myvisual->visual, AllocNone);
+
+ winattr.background_pixel = BlackPixelOfScreen(screen);
+ winattr.border_pixel = WhitePixelOfScreen(screen);
+ winattr.bit_gravity = ForgetGravity;
+ winattr.win_gravity = NorthWestGravity;
+ winattr.backing_store = NotUseful;
+
+ winattr.override_redirect = False;
+ winattr.save_under = False;
+ winattr.event_mask = 0;
+ winattr.do_not_propagate_mask = 0;
+ winattr.colormap = g_draw.colormap;
+ winattr.cursor = None;
+
+ g_draw.window = XCreateWindow(g_draw.display, g_draw.root_window_id, 0, 0,
+ g_cfg.ResX, g_cfg.ResY, 0, g_draw.myvisual->depth, InputOutput,
+ g_draw.myvisual->visual, CWBorderPixel | CWBackPixel | CWEventMask
+ | CWDontPropagate | CWColormap | CWCursor, &winattr);
+
+ if (!g_draw.window) {
+ fprintf(stderr, "Failed in XCreateWindow()!!!\n");
+ DestroyDisplay();
+ return;
+ }
+
+ delwindow = XInternAtom(g_draw.display, "WM_DELETE_WINDOW", 0);
+ XSetWMProtocols(g_draw.display, g_draw.window, &delwindow, 1);
+
+ hints.flags = USPosition | USSize;
+ hints.base_width = g_cfg.ResX;
+ hints.base_height = g_cfg.ResY;
+
+ wm_hints.input = 1;
+ wm_hints.flags = InputHint;
+
+ XSetWMHints(g_draw.display, g_draw.window, &wm_hints);
+ XSetWMNormalHints(g_draw.display, g_draw.window, &hints);
+ //if (pCaptionText)
+ // XStoreName(draw_ctx.display, draw_ctx.window, pCaptionText);
+ //else
+ XStoreName(g_draw.display, g_draw.window, "GXVideo GPU");
+
+ XDefineCursor(g_draw.display, g_draw.window, g_draw.cursor);
+
+ // hack to get rid of window title bar
+ if (g_draw.fx) {
+ mwmhints.flags = MWM_HINTS_DECORATIONS;
+ mwmhints.decorations = 0;
+ mwmatom = XInternAtom(g_draw.display, "_MOTIF_WM_HINTS", 0);
+ XChangeProperty(g_draw.display, g_draw.window, mwmatom, mwmatom, 32,
+ PropModeReplace, (unsigned char *) &mwmhints, 4);
+ }
+
+ // key stuff
+ XSelectInput(g_draw.display, g_draw.window, FocusChangeMask | ExposureMask
+ | KeyPressMask | KeyReleaseMask);
+
+ XMapRaised(g_draw.display, g_draw.window);
+ XClearWindow(g_draw.display, g_draw.window);
+ XWindowEvent(g_draw.display, g_draw.window, ExposureMask, &event);
+
+ if (g_draw.fx) {
+ XResizeWindow(g_draw.display, g_draw.window, screen->width,
+ screen->height);
+
+ hints.min_width = hints.max_width = hints.base_width = screen->width;
+ hints.min_height = hints.max_height = hints.base_height
+ = screen->height;
+
+ XSetWMNormalHints(g_draw.display, g_draw.window, &hints);
+
+ // set the window layer for GNOME
+ {
+ XEvent xev;
+
+ memset(&xev, 0, sizeof(xev));
+ xev.xclient.type = ClientMessage;
+ xev.xclient.serial = 0;
+ xev.xclient.send_event = 1;
+ xev.xclient.message_type = XInternAtom(g_draw.display,
+ "_NET_WM_STATE", 0);
+ xev.xclient.window = g_draw.window;
+ xev.xclient.format = 32;
+ xev.xclient.data.l[0] = 1;
+ xev.xclient.data.l[1] = XInternAtom(g_draw.display,
+ "_NET_WM_STATE_FULLSCREEN", 0);
+ xev.xclient.data.l[2] = 0;
+ xev.xclient.data.l[3] = 0;
+ xev.xclient.data.l[4] = 0;
+
+ XSendEvent(g_draw.display, g_draw.root_window_id, 0,
+ SubstructureRedirectMask | SubstructureNotifyMask, &xev);
+ }
+ }
+
+ gcv.graphics_exposures = False;
+ gcv.foreground = WhitePixelOfScreen(screen);
+ gcv.background = BlackPixelOfScreen(screen);
+ g_draw.hGC = XCreateGC(g_draw.display, g_draw.window, GCGraphicsExposures
+ |GCForeground | GCBackground, &gcv);
+ if (!g_draw.hGC) {
+ fprintf(stderr, "No gfx context!!!\n");
+ DestroyDisplay();
+ }
+
+ g_draw.Xpixels = (char *) malloc(600 * 15 * 4);
+
+ uint32_t color;
+ if (g_draw.xv == GXV_YUV_PORT)
+ color = rgb_to_yuv(0x00, 0x00, 0xff);
+ else
+ color = 0x0000ff;
+
+ for (i = 0; i < 600 * 15; ++i)
+ ((uint32_t *) g_draw.Xpixels)[i] = color;
+
+ g_draw.XFimage = XCreateImage(g_draw.display, g_draw.myvisual->visual,
+ g_draw.depth, ZPixmap, 0, (char *) g_draw.Xpixels, 600, 15,
+ g_draw.depth > 16 ? 32 : 16, 0);
+
+ /* fix the green back ground in YUV mode */
+ if (g_draw.xv == GXV_YUV_PORT)
+ color = rgb_to_yuv(0x00, 0x00, 0x00);
+ else
+ color = 0;
+
+ g_draw.Xpixels = (char *) malloc(8 * 8 * 4);
+ for (i = 0; i < 8 * 8; ++i)
+ ((uint32_t *) g_draw.Xpixels)[i] = color;
+
+ g_draw.XCimage = XvCreateImage(g_draw.display, g_draw.xv_port,
+ g_draw.xv_id, (char *) g_draw.Xpixels, 8, 8);
+
+ /*
+ Allocate max that could be needed:
+ Big(est?) PSX res: 640x512
+ 32bpp (times 4)
+ 2xsai func= 3xwidth,3xheight
+ = approx 11.8mb
+ */
+ g_draw.shminfo.shmid
+ = shmget(IPC_PRIVATE, 1024 * 512 * 4, IPC_CREAT | 0777);
+ g_draw.shminfo.shmaddr = shmat(g_draw.shminfo.shmid, 0, 0);
+ g_draw.shminfo.readOnly = 0;
+
+ if (!XShmAttach(g_draw.display, &g_draw.shminfo)) {
+ printf("XShmAttach failed !\n");
+ exit(-1);
+ }
+
+ uint32_t *pShmaddr = (uint32_t *) g_draw.shminfo.shmaddr;
+ for (i = 0; i < 1024 * 512; ++i)
+ pShmaddr[i] = color;
+
+ //fprintf(stderr, "Return %s\n", __FUNCTION__);
+ return;
+}
+
+int rgb_check_port(XvImageFormatValues const * fo) {
+ if (fo->type == XvRGB && fo->bits_per_pixel == 32) {
+ g_draw.xv_id = fo->id;
+ return 1;
+ }
+ return 0;
+}
+
+void rgb_blit_16(int8_t * buff, int32_t x, int32_t y, int32_t w, int32_t h) {
+ //fprintf(stderr, "BlitToYUV\n");
+ int16_t * src_pxl;
+ int8_t * dst_pxl;
+ int32_t startxy;
+ int32_t _x, _y;
+
+ startxy = 0;
+ dst_pxl = buff;
+ for (_y = y; _y < h; ++_y) {
+ src_pxl = &g_gpu.psx_vram.s16[startxy];
+ for (_x = x; _x < w; ++_x) {
+ dst_pxl[0] = ((*src_pxl) << 3) & 0xf8;
+ dst_pxl[1] = ((*src_pxl) >> 2) & 0xf8;
+ dst_pxl[2] = ((*src_pxl) >> 7) & 0xf8;
+ dst_pxl += 3;
+ src_pxl += 1;
+ }
+ startxy += 2048;
+ }
+}
+
+void rgb_blit_24(int8_t * buff, int32_t x, int32_t y, int32_t w, int32_t h) {
+ //fprintf(stderr, "BlitToYUV\n");
+ int8_t * src_pxl;
+ int8_t * dst_pxl;
+ int32_t startxy;
+ int32_t _x, _y;
+
+ dst_pxl = buff;
+ startxy = 0;
+ for (_y = y; _y < h; ++_y) {
+ src_pxl = &g_gpu.psx_vram.s8[startxy];
+ for (_x = x; _x < w; ++_x) {
+ dst_pxl[0] = src_pxl[0];
+ dst_pxl[1] = src_pxl[1];
+ dst_pxl[2] = src_pxl[2];
+ dst_pxl += 3;
+ src_pxl += 3;
+ }
+ startxy += 2048;
+ }
+}
+
+int yuyv_check_port(XvImageFormatValues * fo) {
+ if (fo->type == XvYUV && fo->bits_per_pixel == 16 && fo->format == XvPacked
+ && strncmp("UYVY", fo->component_order, 4) == 0) {
+ g_draw.xv_id = fo->id;
+ return 1;
+ }
+ return 0;
+}
+
+void yuyv_blit_24(int8_t * buff, int32_t x, int32_t y, int32_t w, int32_t h) {
+ //fprintf(stderr, "yuyv_blit_24 %d %d %d %d\n", x, y, w, h);
+ uint8_t * src_pxl;
+ int8_t R0, G0, B0;
+ int8_t R1, G1, B1;
+ uint32_t * dst_pxl;
+ int32_t _x, _y;
+
+ /* x and w should be multiple of 2 to be align */
+ x = x & 0xfffffffe;
+ w = (w + 1) & 0xfffffffe;
+
+ dst_pxl = (uint32_t *) (buff);
+ for (_y = y; _y < (y + h); _y += 1) {
+ src_pxl = &g_gpu.psx_vram.u8[x * 3 + (_y * 2048)];
+ for (_x = 0; _x < (w / 2); ++_x) {
+ R0 = src_pxl[0];
+ G0 = src_pxl[1];
+ B0 = src_pxl[2];
+ R1 = src_pxl[3];
+ G1 = src_pxl[4];
+ B1 = src_pxl[5];
+ *dst_pxl++ = rgb_to_yuv2(R0, G0, B0, R1, G1, B1);
+ src_pxl += 6;
+ }
+ }
+}
+
+void yuyv_blit_16(int8_t * buff, int32_t x, int32_t y, int32_t w, int32_t h) {
+ //fprintf(stderr, "yuyv_blit_16 %d %d %d %d\n", x, y, w, h);
+ int8_t R0, G0, B0;
+ int8_t R1, G1, B1;
+ uint32_t * dst_pxl;
+ int32_t _x, _y;
+ int32_t s;
+ uint16_t * src_pxl;
+
+ /* x must be a multiple of 2 */
+ /* x and w must be a multiple of 2 */
+ x = x & 0xfffffffe;
+ w = (w + 1) & 0xfffffffe;
+
+ dst_pxl = (uint32_t *) (buff);
+ for (_y = y; _y < (y + h); _y += 1) {
+ src_pxl = &g_gpu.psx_vram.u16[x + (_y * 1024)];
+ for (_x = 0; _x < (w / 2); ++_x) {
+ s = GETLE16(src_pxl++);
+ R0 = (s << 3) & 0xf8;
+ G0 = (s >> 2) & 0xf8;
+ B0 = (s >> 7) & 0xf8;
+ s = GETLE16(src_pxl++);
+ R1 = (s << 3) & 0xf8;
+ G1 = (s >> 2) & 0xf8;
+ B1 = (s >> 7) & 0xf8;
+ *dst_pxl++ = rgb_to_yuv2(R0, G0, B0, R1, G1, B1);
+ }
+ }
+}
+
+/**
+ * compute the position and the size of output screen
+ * The aspect of the psx output mode is preserved.
+ * Note: dest dx,dy,dw,dh are both input and output variables
+ */
+inline void maintain_aspect(uint32_t * dx, uint32_t * dy, uint32_t * dw,
+ uint32_t * dh, int32_t w, int32_t h) {
+
+ double ratio_x = ((double) *dw) / ((double) w);
+ double ratio_y = ((double) *dh) / ((double) h);
+
+ double ratio;
+ if (ratio_x < ratio_y) {
+ ratio = ratio_x;
+ } else {
+ ratio = ratio_y;
+ }
+
+ uint32_t tw = (uint32_t) floor(w * ratio);
+ uint32_t th = (uint32_t) floor(h * ratio);
+
+ *dx += (uint32_t) floor((*dw - tw) / 2.0);
+ *dy += (uint32_t) floor((*dh - th) / 2.0);
+ *dw = tw;
+ *dh = th;
+}
+
+void do_buffer_swap(void) {
+ //Screen *screen;
+ Window _dw;
+ XvImage *xvi;
+ unsigned int dstx, dsty;
+ unsigned int _d, _w, _h; //don't care about _d
+
+ dstx = 0;
+ dsty = 0;
+
+ XSync(g_draw.display, False);
+
+ XGetGeometry(g_draw.display, g_draw.window, &_dw, (int *) &_d, (int *) &_d,
+ &_w, &_h, &_d, &_d);
+
+ if (g_cfg.ShowFPS) {
+ dsty += 15;
+ _h -= 15;
+ compute_fps();
+ snprintf(g_draw.msg, 511, "FPS : %f", g_draw.fps);
+ XDrawImageString(g_draw.display, g_draw.window, g_draw.hGC, 0, 12,
+ g_draw.msg, strlen(g_draw.msg));
+ }
+
+ uint32_t _x_, _y_, _w_, _h_;
+
+ /* if video mode is valid */
+ if (g_gpu.dsp.mode.x) {
+
+ if (g_gpu.status_reg & STATUS_RGB24) {
+ _x_ = (g_gpu.dsp.position.x * 2) / 3;
+ } else {
+ _x_ = g_gpu.dsp.position.x;
+ }
+ _y_ = g_gpu.dsp.position.y;
+ _w_ = (g_gpu.dsp.range.x1 - g_gpu.dsp.range.x0) / g_gpu.dsp.mode.x;
+ _h_ = (g_gpu.dsp.range.y1 - g_gpu.dsp.range.y0) * g_gpu.dsp.mode.y;
+
+ if (g_gpu.status_reg & STATUS_RGB24) {
+ available_port[g_draw.xv].blit_24_bits(
+ (int8_t *) g_draw.shminfo.shmaddr, _x_, _y_, _w_, _h_);
+ } else {
+ available_port[GXV_YUV_PORT].blit_16_bits(
+ (int8_t *) g_draw.shminfo.shmaddr, _x_, _y_, _w_, _h_);
+ }
+
+ xvi = XvShmCreateImage(g_draw.display, g_draw.xv_port, g_draw.xv_id, 0,
+ _w_, _h_, &g_draw.shminfo);
+
+ xvi->data = g_draw.shminfo.shmaddr;
+
+ //screen = DefaultScreenOfDisplay(g_draw.display);
+ //screennum = DefaultScreen(display);
+
+ // if (g_cfg.FullScreen) {
+ // _w = screen->width;
+ // _h = screen->height;
+ // }
+
+ if (g_cfg.Maintain43)
+ maintain_aspect(&dstx, &dsty, &_w, &_h, _w_, (g_gpu.dsp.range.y1
+ - g_gpu.dsp.range.y0));
+
+ // int _i;
+ // int32_t * dst_pxl;
+ // dst_pxl = (int32_t *) &g_draw.shminfo.shmaddr[2048 * _y_];
+ // for (_i = _x_ / 2; _i < (_x_ + _w_) / 2; ++_i)
+ // dst_pxl[_i] = rgb_to_yuv2(255, 0, 0, 255, 0, 0);
+ // dst_pxl = (int32_t *) &g_draw.shminfo.shmaddr[2048 * (_y_ + _h_)];
+ // for (_i = _x_ / 2; _i < (_x_ + _w_) / 2; ++_i)
+ // dst_pxl[_i] = rgb_to_yuv2(255, 0, 0, 255, 0, 0);
+ // dst_pxl = (int32_t *) &g_draw.shminfo.shmaddr[4 * (_x_ / 2)];
+ // for (_i = _y_; _i < (_y_ + _h_); ++_i)
+ // dst_pxl[_i * 512] = rgb_to_yuv2(255, 0, 0, 255, 0, 0);
+ // dst_pxl = (int32_t *) &g_draw.shminfo.shmaddr[4 * ((_x_ + _w_) / 2)];
+ // for (_i = _y_; _i < (_y_ + _h_); ++_i)
+ // dst_pxl[_i * 512] = rgb_to_yuv2(255, 0, 0, 255, 0, 0);
+
+ //fprintf(stderr, "From %d,%d,%d,%d\n", _x_, _y_, _w_, _h_);
+ XvShmPutImage(g_draw.display, g_draw.xv_port, g_draw.window,
+ g_draw.hGC, xvi, 0, 0, _w_, _h_,
+ //0, 0, 1024, 512,
+ /* dst */
+ dstx, dsty, _w, _h, 1);
+ XFree(xvi);
+ }
+}
+
+void do_clear_screen_buffer(void) // CLEAR DX BUFFER
+{
+ XClearWindow(g_draw.display, g_draw.window);
+}
+
+void Xcleanup() // X CLEANUP
+{
+ //CloseMenu();
+}
+
+/**
+ * Call on GPUopen
+ * Return the current display.
+ **/
+unsigned long init_display() {
+
+ available_port[GXV_YUV_PORT].blit_24_bits = yuyv_blit_24;
+ available_port[GXV_YUV_PORT].blit_16_bits = yuyv_blit_16;
+
+ available_port[GXV_RGB_PORT].blit_24_bits = rgb_blit_24;
+ available_port[GXV_RGB_PORT].blit_16_bits = rgb_blit_16;
+
+ create_display(); // x stuff
+ g_draw.bIsFirstFrame = 0;
+ return (unsigned long) g_draw.display;
+}
+
+void CloseDisplay(void) {
+ Xcleanup(); // cleanup dx
+ DestroyDisplay();
+}
+
+void CreatePic(unsigned char * pMem) {
+ unsigned char * p = (unsigned char *) malloc(128 * 96 * 4);
+ unsigned char * ps;
+ //int x, y;
+
+ ps = p;
+
+ // if (iDesktopCol == 16) {
+ // unsigned short s;
+ // for (y = 0; y < 96; y++) {
+ // for (x = 0; x < 128; x++) {
+ // s = (*(pMem + 0)) >> 3;
+ // s |= ((*(pMem + 1)) & 0xfc) << 3;
+ // s |= ((*(pMem + 2)) & 0xf8) << 8;
+ // pMem += 3;
+ // *((unsigned short *) (ps + y * 256 + x * 2)) = s;
+ // }
+ // }
+ // } else if (iDesktopCol == 15) {
+ // unsigned short s;
+ // for (y = 0; y < 96; y++) {
+ // for (x = 0; x < 128; x++) {
+ // s = (*(pMem + 0)) >> 3;
+ // s |= ((*(pMem + 1)) & 0xfc) << 2;
+ // s |= ((*(pMem + 2)) & 0xf8) << 7;
+ // pMem += 3;
+ // *((unsigned short *) (ps + y * 256 + x * 2)) = s;
+ // }
+ // }
+ // } else if (iDesktopCol == 32) {
+ // uint32_t l;
+ // for (y = 0; y < 96; y++) {
+ // for (x = 0; x < 128; x++) {
+ // l = *(pMem + 0);
+ // l |= (*(pMem + 1)) << 8;
+ // l |= (*(pMem + 2)) << 16;
+ // pMem += 3;
+ // *((uint32_t *) (ps + y * 512 + x * 4)) = l;
+ // }
+ // }
+ // }
+
+ g_draw.XPimage = XCreateImage(g_draw.display, g_draw.myvisual->visual,
+ g_draw.depth, ZPixmap, 0, (char *) p, 128, 96,
+ g_draw.depth > 16 ? 32 : 16, 0);
+}
+
+void DestroyPic(void) {
+ if (g_draw.XPimage) { /*
+ XPutImage(display,window,hGC, XCimage,
+ 0, 0, 0, 0, iResX, iResY);*/
+ XDestroyImage(g_draw.XPimage);
+ g_draw.XPimage = 0;
+ }
+}
+
+void ShowGpuPic(void) {
+}
+
+void ShowTextGpuPic(void) {
+}
diff --git a/plugins/gxvideo/fps.c b/plugins/gxvideo/fps.c
index f53800ff..3603dad1 100644
--- a/plugins/gxvideo/fps.c
+++ b/plugins/gxvideo/fps.c
@@ -1,69 +1,69 @@
-/*
- * Copyright (C) 2010 Benoit Gschwind
- * Inspired by original author : Pete Bernert
- *
- * 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 3 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., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#include <unistd.h>
-#include <sys/time.h>
-
-#include "globals.h"
-#include "fps.h"
-#include "gpu.h"
-
-#define TIMEBASE 100000
-
-static unsigned long time_get_time() {
- struct timeval tv;
- gettimeofday(&tv, 0); // well, maybe there are better ways
- return tv.tv_sec * 100000 + tv.tv_usec / 10; // to do that, but at least it works
-}
-
-void frame_cap(int fps) {
- static unsigned int last_time = 0;
- unsigned int c = time_get_time();
-
- if (!fps) {
- last_time = c;
- return;
- }
-
- if (last_time + (100000/fps) < c) {
- last_time = c;
- return;
- }
-
- while (last_time + (100000/fps) - 20 > c) {
- usleep(((100000/fps) - 20 - (c - last_time)) * 10 );
- c = time_get_time();
- }
-
- last_time = c;
-
-}
-
-void compute_fps() {
- static int count = 0;
- static unsigned int last_time = 0;
- unsigned int c = time_get_time();
- ++count;
- if((c - last_time) > 100000) {
- g_draw.fps = ((double)count) / ((double)(c - last_time)) * 100000;
- count = 0;
- last_time = c;
- }
-}
+/*
+ * Copyright (C) 2010 Benoit Gschwind
+ * Inspired by original author : Pete Bernert
+ *
+ * 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 3 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., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#include <unistd.h>
+#include <sys/time.h>
+
+#include "globals.h"
+#include "fps.h"
+#include "gpu.h"
+
+#define TIMEBASE 100000
+
+unsigned long time_get_time() {
+ struct timeval tv;
+ gettimeofday(&tv, 0); // well, maybe there are better ways
+ return tv.tv_sec * 100000 + tv.tv_usec / 10; // to do that, but at least it works
+}
+
+void frame_cap(int fps) {
+ static unsigned int last_time = 0;
+ unsigned int c = time_get_time();
+
+ if (!fps) {
+ last_time = c;
+ return;
+ }
+
+ if (last_time + (100000/fps) < c) {
+ last_time = c;
+ return;
+ }
+
+ while (last_time + (100000/fps) - 20 > c) {
+ usleep(((100000/fps) - 20 - (c - last_time)) * 10 );
+ c = time_get_time();
+ }
+
+ last_time = c;
+
+}
+
+void compute_fps() {
+ static int count = 0;
+ static unsigned int last_time = 0;
+ unsigned int c = time_get_time();
+ ++count;
+ if((c - last_time) > 100000) {
+ g_draw.fps = ((double)count) / ((double)(c - last_time)) * 100000;
+ count = 0;
+ last_time = c;
+ }
+}
diff --git a/plugins/gxvideo/gpu.c b/plugins/gxvideo/gpu.c
index 85b003bd..22544950 100644
--- a/plugins/gxvideo/gpu.c
+++ b/plugins/gxvideo/gpu.c
@@ -1,1549 +1,1555 @@
-/*
- * Copyright (C) 2010 Benoit Gschwind
- * Inspired by original author : Pete Bernert
- *
- * 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 3 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., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#include "config.h"
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-
-#include "globals.h"
-#include "gpu.h"
-#include "swap.h"
-#include "psemu_plugin_defs.h"
-
-#define CALLBACK
-
-#define INFO_TW 0
-#define INFO_DRAWSTART 1
-#define INFO_DRAWEND 2
-#define INFO_DRAWOFF 3
-
-#define SHADETEXBIT(x) ((x>>24) & 0x1)
-#define SEMITRANSBIT(x) ((x>>25) & 0x1)
-#define PSXRGB(r,g,b) ((g<<10)|(b<<5)|r)
-
-#define DATAREGISTERMODES unsigned short
-
-#define DR_NORMAL 0
-#define DR_VRAMTRANSFER 1
-
-#define MIN(a,b) ((a) > (b) ? (b) : (a))
-#define MAX(a,b) ((a) < (b) ? (b) : (a))
-
-////////////////////////////////////////////////////////////////////////
-// PPDK developer must change libraryName field and can change revision and build
-////////////////////////////////////////////////////////////////////////
-
-unsigned char const version = 1; // do not touch - library for PSEmu 1.x
-unsigned char const revision = 0;
-unsigned char const build = 0; // increase that with each version
-
-static char const * libraryName = N_("GXVideo Driver");
-#if 0
-static char const * libraryInfo = N_("GXvideo Driver v1.00");
-#endif
-//static char const * PluginAuthor =
-// N_("gschwind (rewrite from Pete Bernert and the P.E.Op.S. team)");
-
-////////////////////////////////////////////////////////////////////////
-// some misc external display funcs
-////////////////////////////////////////////////////////////////////////
-
-#include <time.h>
-
-//void CALLBACK GPUdisplayText(char * pText) {
-//
-//}
-
-////////////////////////////////////////////////////////////////////////
-
-//void CALLBACK GPUdisplayFlags(unsigned long dwFlags) // some info func
-//{
-//dwCoreFlags = dwFlags;
-//BuildDispMenu(0);
-//}
-
-////////////////////////////////////////////////////////////////////////
-// stuff to make this a true PDK module
-////////////////////////////////////////////////////////////////////////
-
-char * CALLBACK PSEgetLibName(void) {
- return _(libraryName);
-}
-
-unsigned long CALLBACK PSEgetLibType(void) {
- //return PSE_LT_GPU;
- return 2; /* GPU plugin */
-}
-
-unsigned long CALLBACK PSEgetLibVersion(void) {
- return version << 16 | revision << 8 | build;
-}
-
-#if 0
-char * GPUgetLibInfos(void) {
- return _(libraryInfo);
-}
-#endif
-
-////////////////////////////////////////////////////////////////////////
-// Snapshot func
-////////////////////////////////////////////////////////////////////////
-
-//char * pGetConfigInfos(int iCfg) {
-// char szO[2][4] = { "off", "on " };
-// char szTxt[256];
-// char * pB = (char *) malloc(32767);
-//
-// if (!pB)
-// return NULL;
-// *pB = 0;
-// //----------------------------------------------------//
-// sprintf(szTxt, "Plugin: %s %d.%d.%d\r\n", libraryName, version, revision,
-// build);
-// strcat(pB, szTxt);
-// sprintf(szTxt, "Author: %s\r\n\r\n", PluginAuthor);
-// strcat(pB, szTxt);
-// //----------------------------------------------------//
-//
-// sprintf(szTxt, "Resolution/Color:\r\n- %dx%d ", g_cfg.ResX, g_cfg.ResY);
-//
-// strcat(pB, szTxt);
-// if (iWindowMode && iCfg)
-// strcpy(szTxt, "Window mode\r\n");
-// else if (iWindowMode)
-// sprintf(szTxt, "Window mode - [%d Bit]\r\n", iDesktopCol);
-// else
-// sprintf(szTxt, "Fullscreen - [%d Bit]\r\n", iColDepth);
-// strcat(pB, szTxt);
-//
-// sprintf(szTxt, "Stretch mode: %d\r\n", iUseNoStretchBlt);
-// strcat(pB, szTxt);
-// sprintf(szTxt, "Dither mode: %d\r\n\r\n", iUseDither);
-// strcat(pB, szTxt);
-// //----------------------------------------------------//
-// sprintf(szTxt, "Framerate:\r\n- FPS limit: %s\r\n", szO[UseFrameLimit]);
-// strcat(pB, szTxt);
-// sprintf(szTxt, "- Frame skipping: %s", szO[UseFrameSkip]);
-// strcat(pB, szTxt);
-// if (iFastFwd)
-// strcat(pB, " (fast forward)");
-// strcat(pB, "\r\n");
-// if (iFrameLimit == 2)
-// strcpy(szTxt, "- FPS limit: Auto\r\n\r\n");
-// else
-// sprintf(szTxt, "- FPS limit: %.1f\r\n\r\n", fFrameRate);
-// strcat(pB, szTxt);
-// //----------------------------------------------------//
-//#if !defined (_MACGL) && !defined (_WINDOWS)
-// strcpy(szTxt, "Misc:\r\n- MaintainAspect: ");
-// if (iMaintainAspect == 0)
-// strcat(szTxt, "disabled");
-// else if (iMaintainAspect == 1)
-// strcat(szTxt, "enabled");
-// strcat(szTxt, "\r\n");
-// strcat(pB, szTxt);
-//#endif
-// sprintf(szTxt, "- Game fixes: %s [%08x]\r\n", szO[iUseFixes], dwCfgFixes);
-// strcat(pB, szTxt);
-// //----------------------------------------------------//
-// return pB;
-// return 0;
-//}
-
-void CALLBACK GPUmakeSnapshot(void) {
- // FILE *bmpfile;
- // char filename[256];
- // unsigned char header[0x36];
- // long size, height;
- // unsigned char line[1024 * 3];
- // short i, j;
- // unsigned char empty[2] = { 0, 0 };
- // unsigned short color;
- // unsigned long snapshotnr = 0;
- // unsigned char *pD;
- //
- // height = gpu_ctx.PreviousPSXDisplay.DisplayMode.y;
- //
- // size = height * PreviousPSXDisplay.Range.x1 * 3 + 0x38;
- //
- // // fill in proper values for BMP
- //
- // // hardcoded BMP header
- // memset(header, 0, 0x36);
- // header[0] = 'B';
- // header[1] = 'M';
- // header[2] = size & 0xff;
- // header[3] = (size >> 8) & 0xff;
- // header[4] = (size >> 16) & 0xff;
- // header[5] = (size >> 24) & 0xff;
- // header[0x0a] = 0x36;
- // header[0x0e] = 0x28;
- // header[0x12] = gpu_ctx.PreviousPSXDisplay.Range.x1 % 256;
- // header[0x13] = gpu_ctx.PreviousPSXDisplay.Range.x1 / 256;
- // header[0x16] = height % 256;
- // header[0x17] = height / 256;
- // header[0x1a] = 0x01;
- // header[0x1c] = 0x18;
- // header[0x26] = 0x12;
- // header[0x27] = 0x0B;
- // header[0x2A] = 0x12;
- // header[0x2B] = 0x0B;
- //
- // // increment snapshot value & try to get filename
- // do {
- // snapshotnr++;
- //#ifdef _WINDOWS
- // sprintf(filename,"snap\\pcsx%04ld.bmp",snapshotnr);
- //#else
- // sprintf(filename, "%s/pcsx%04ld.bmp", getenv("HOME"), snapshotnr);
- //#endif
- //
- // bmpfile = fopen(filename, "rb");
- // if (bmpfile == NULL)
- // break;
- //
- // fclose(bmpfile);
- // } while (TRUE);
- //
- // // try opening new snapshot file
- // if ((bmpfile = fopen(filename, "wb")) == NULL)
- // return;
- //
- // fwrite(header, 0x36, 1, bmpfile);
- // for (i = height + PSXDisplay.DisplayPosition.y - 1; i
- // >= PSXDisplay.DisplayPosition.y; i--) {
- // pD = (unsigned char *) &psxVuw[i * 1024 + PSXDisplay.DisplayPosition.x];
- // for (j = 0; j < PreviousPSXDisplay.Range.x1; j++) {
- // if (PSXDisplay.RGB24) {
- // uint32_t lu = *(uint32_t *) pD;
- // line[j * 3 + 2] = (unsigned char) RED(lu);
- // line[j * 3 + 1] = (unsigned char) GREEN(lu);
- // line[j * 3 + 0] = (unsigned char) BLUE(lu);
- // pD += 3;
- // } else {
- // color = GETLE16(pD);
- // line[j * 3 + 2] = (color << 3) & 0xf1;
- // line[j * 3 + 1] = (color >> 2) & 0xf1;
- // line[j * 3 + 0] = (color >> 7) & 0xf1;
- // pD += 2;
- // }
- // }
- // fwrite(line, PreviousPSXDisplay.Range.x1 * 3, 1, bmpfile);
- // }
- // fwrite(empty, 0x2, 1, bmpfile);
- // fclose(bmpfile);
- //
- // DoTextSnapShot(snapshotnr);
-}
-
-////////////////////////////////////////////////////////////////////////
-// INIT, will be called after lib load... well, just do some var init...
-////////////////////////////////////////////////////////////////////////
-
-long CALLBACK GPUinit() {
- fprintf(stderr, "%s\n", __FUNCTION__);
- memset(g_gpu.ulStatusControl, 0, 256 * sizeof(uint32_t)); // init save state scontrol field
- g_gpu.psxVSecure.u8 = (uint8_t *) malloc((512 * 2) * 1024 + (1024 * 1024)); // always alloc one extra MB for soft drawing funcs security
- if (!g_gpu.psxVSecure.u8)
- return -1;
-
- //!!! ATTENTION !!!
- g_gpu.psx_vram.u8 = g_gpu.psxVSecure.u8 + 512 * 1024; // security offset into double sized psx vram!
-
- g_gpu.psxVuw_eom.u16 = g_gpu.psx_vram.u16 + 1024 * 512; // pre-calc of end of vram
-
- memset(g_gpu.psxVSecure.s8, 0x00, (512 * 2) * 1024 + (1024 * 1024));
- memset(g_gpu.lGPUInfoVals, 0x00, 16 * sizeof(uint32_t));
-
- g_gpu.dsp.range.x0 = 0;
- g_gpu.dsp.range.x1 = 0;
- g_gpu.lGPUdataRet = 0x400;
-
- g_gpu.DataWriteMode = DR_NORMAL;
-
- // Reset transfer values, to prevent mis-transfer of data
- memset(&g_gpu.VRAMWrite, 0, sizeof(gxv_vram_load_t));
- memset(&g_gpu.VRAMRead, 0, sizeof(gxv_vram_load_t));
-
- // device initialised already !
- g_gpu.status_reg = 0x14802000;
- return 0;
-}
-
-/* Here starts all... */
-long GPUopen(unsigned long * disp, char * CapText, char * CfgFile) {
- unsigned long d;
-
- ReadConfig();
-
- g_draw.bIsFirstFrame = 1;
-
- d = init_display(); // setup x
-
- if (disp)
- *disp = d; // wanna x pointer? ok
-
- if (d)
- return 0;
- return -1;
-}
-
-////////////////////////////////////////////////////////////////////////
-// time to leave...
-////////////////////////////////////////////////////////////////////////
-
-long CALLBACK GPUclose() {
- fprintf(stderr, "%s\n", __FUNCTION__);
- //ReleaseKeyHandler(); // de-subclass window
- CloseDisplay(); // shutdown direct draw
- return 0;
-}
-
-////////////////////////////////////////////////////////////////////////
-// I shot the sheriff
-////////////////////////////////////////////////////////////////////////
-
-long CALLBACK GPUshutdown() {
- free(g_gpu.psxVSecure.s8);
- return 0;
-}
-
-////////////////////////////////////////////////////////////////////////
-// roughly emulated screen centering bits... not complete !!!
-////////////////////////////////////////////////////////////////////////
-//
-//void ChangeDispOffsetsX(void) // X CENTER
-//{
-// long lx, l;
-//
-// if (!g_gpu.dsp.range.x1)
-// return;
-//
-// l = g_gpu.prev_dsp.DisplayMode.x;
-//
-// l *= (long) g_gpu.dsp.range.x1;
-// l /= 2560;
-// lx = l;
-// l &= 0xfffffff8;
-//
-// if (l == g_gpu.prev_dsp.range.y1)
-// return; // abusing range.y1 for
-// g_gpu.prev_dsp.range.y1 = (short) l; // storing last x range and test
-//
-// if (lx >= g_gpu.prev_dsp.DisplayMode.x) {
-// g_gpu.prev_dsp.range.x1 = (short) g_gpu.prev_dsp.DisplayMode.x;
-// g_gpu.prev_dsp.range.x0 = 0;
-// } else {
-// g_gpu.prev_dsp.range.x1 = (short) l;
-//
-// g_gpu.prev_dsp.range.x0 = (g_gpu.dsp.range.x0 - 500) / 8;
-//
-// if (g_gpu.prev_dsp.range.x0 < 0)
-// g_gpu.prev_dsp.range.x0 = 0;
-//
-// if ((g_gpu.prev_dsp.range.x0 + lx) > g_gpu.prev_dsp.DisplayMode.x) {
-// g_gpu.prev_dsp.range.x0 = (short) (g_gpu.prev_dsp.DisplayMode.x
-// - lx);
-// g_gpu.prev_dsp.range.x0 += 2; //???
-//
-// g_gpu.prev_dsp.range.x1 += (short) (lx - l);
-//
-// g_gpu.prev_dsp.range.x1 -= 2; // makes linux stretching easier
-// }
-//
-// // some linux alignment security
-// g_gpu.prev_dsp.range.x0 = g_gpu.prev_dsp.range.x0 >> 1;
-// g_gpu.prev_dsp.range.x0 = g_gpu.prev_dsp.range.x0 << 1;
-// g_gpu.prev_dsp.range.x1 = g_gpu.prev_dsp.range.x1 >> 1;
-// g_gpu.prev_dsp.range.x1 = g_gpu.prev_dsp.range.x1 << 1;
-//
-// DoClearScreenBuffer();
-// }
-//
-// g_prim.bDoVSyncUpdate = 1;
-//}
-
-////////////////////////////////////////////////////////////////////////
-
-//void ChangeDispOffsetsY(void) // Y CENTER
-//{
-// int iT, iO = g_gpu.prev_dsp.range.y0;
-// int iOldYOffset = g_gpu.prev_dsp.DisplayModeNew.y;
-//
-// // new
-//
-// if ((g_gpu.prev_dsp.DisplayModeNew.x + g_gpu.dsp.DisplayModeNew.y) > 512) {
-// int dy1 = 512 - g_gpu.prev_dsp.DisplayModeNew.x;
-// int dy2 =
-// (g_gpu.prev_dsp.DisplayModeNew.x + g_gpu.dsp.DisplayModeNew.y)
-// - 512;
-//
-// if (dy1 >= dy2) {
-// g_gpu.prev_dsp.DisplayModeNew.y = -dy2;
-// } else {
-// g_gpu.dsp.position.y = 0;
-// g_gpu.prev_dsp.DisplayModeNew.y = -dy1;
-// }
-// } else
-// g_gpu.prev_dsp.DisplayModeNew.y = 0;
-//
-// // eon
-//
-// if (g_gpu.prev_dsp.DisplayModeNew.y != iOldYOffset) // if old offset!=new offset: recalc height
-// {
-// g_gpu.dsp.Height = g_gpu.dsp.range.y1 - g_gpu.dsp.range.y0
-// + g_gpu.prev_dsp.DisplayModeNew.y;
-// g_gpu.dsp.DisplayModeNew.y = g_gpu.dsp.Height * g_gpu.dsp.Double;
-// }
-//
-// //
-//
-// if (g_gpu.dsp.PAL)
-// iT = 48;
-// else
-// iT = 28;
-//
-// if (g_gpu.dsp.range.y0 >= iT) {
-// g_gpu.prev_dsp.range.y0 = (short) ((g_gpu.dsp.range.y0 - iT - 4)
-// * g_gpu.dsp.Double);
-// if (g_gpu.prev_dsp.range.y0 < 0)
-// g_gpu.prev_dsp.range.y0 = 0;
-// g_gpu.dsp.DisplayModeNew.y += g_gpu.prev_dsp.range.y0;
-// } else
-// g_gpu.prev_dsp.range.y0 = 0;
-//
-// if (iO != g_gpu.prev_dsp.range.y0) {
-// DoClearScreenBuffer();
-// }
-//}
-
-////////////////////////////////////////////////////////////////////////
-// check if update needed
-////////////////////////////////////////////////////////////////////////
-
-
-////////////////////////////////////////////////////////////////////////
-
-// TOGGLE FULLSCREEN - WINDOW DISABLED
-//void ChangeWindowMode(void) {
-// extern Display *display;
-// extern Window window;
-// extern int root_window_id;
-// Screen *screen;
-// XSizeHints hints;
-// MotifWmHints mwmhints;
-// Atom mwmatom;
-//
-// screen = DefaultScreenOfDisplay(display);
-// iWindowMode = !iWindowMode;
-//
-// if (!iWindowMode) // fullscreen
-// {
-// mwmhints.flags = MWM_HINTS_DECORATIONS;
-// mwmhints.functions = 0;
-// mwmhints.decorations = 0;
-// mwmhints.input_mode = 0;
-// mwmatom = XInternAtom(display, "_MOTIF_WM_HINTS", 0);
-// XChangeProperty(display, window, mwmatom, mwmatom, 32, PropModeReplace,
-// (unsigned char *) &mwmhints, 5);
-//
-// XResizeWindow(display, window, screen->width, screen->height);
-//
-// hints.min_width = hints.max_width = hints.base_width = screen->width;
-// hints.min_height = hints.max_height = hints.base_height
-// = screen->height;
-//
-// XSetWMNormalHints(display, window, &hints);
-//
-// {
-// XEvent xev;
-//
-// memset(&xev, 0, sizeof(xev));
-// xev.xclient.type = ClientMessage;
-// xev.xclient.serial = 0;
-// xev.xclient.send_event = 1;
-// xev.xclient.message_type = XInternAtom(display, "_NET_WM_STATE", 0);
-// xev.xclient.window = window;
-// xev.xclient.format = 32;
-// xev.xclient.data.l[0] = 1;
-// xev.xclient.data.l[1] = XInternAtom(display,
-// "_NET_WM_STATE_FULLSCREEN", 0);
-// xev.xclient.data.l[2] = 0;
-// xev.xclient.data.l[3] = 0;
-// xev.xclient.data.l[4] = 0;
-//
-// XSendEvent(display, root_window_id, 0, SubstructureRedirectMask
-// | SubstructureNotifyMask, &xev);
-// }
-// } else {
-// {
-// XEvent xev;
-//
-// memset(&xev, 0, sizeof(xev));
-// xev.xclient.type = ClientMessage;
-// xev.xclient.serial = 0;
-// xev.xclient.send_event = 1;
-// xev.xclient.message_type = XInternAtom(display, "_NET_WM_STATE", 0);
-// xev.xclient.window = window;
-// xev.xclient.format = 32;
-// xev.xclient.data.l[0] = 0;
-// xev.xclient.data.l[1] = XInternAtom(display,
-// "_NET_WM_STATE_FULLSCREEN", 0);
-// xev.xclient.data.l[2] = 0;
-// xev.xclient.data.l[3] = 0;
-// xev.xclient.data.l[4] = 0;
-//
-// XSendEvent(display, root_window_id, 0, SubstructureRedirectMask
-// | SubstructureNotifyMask, &xev);
-// }
-//
-// mwmhints.flags = MWM_HINTS_DECORATIONS;
-// mwmhints.functions = 0;
-// mwmhints.decorations = 1;
-// mwmhints.input_mode = 0;
-// mwmatom = XInternAtom(display, "_MOTIF_WM_HINTS", 0);
-//
-// //This shouldn't work on 64 bit longs, but it does...in fact, it breaks when I change all the mwmhints to int.
-// //I don't pretend to understand it.
-// XChangeProperty(display, window, mwmatom, mwmatom, 32, PropModeReplace,
-// (unsigned char *) &mwmhints, 5);
-//
-// hints.flags = USPosition | USSize;
-// hints.base_width = iResX;
-// hints.base_height = iResY;
-// XSetWMNormalHints(display, window, &hints);
-//
-// XResizeWindow(display, window, iResX, iResY);
-// }
-//
-// DoClearScreenBuffer();
-//
-// bChangeWinMode = 0;
-// bDoVSyncUpdate = 1;
-//}
-
-////////////////////////////////////////////////////////////////////////
-// gun cursor func: player=0-7, x=0-511, y=0-255
-////////////////////////////////////////////////////////////////////////
-
-/* disabled */
-void CALLBACK GPUcursor(int iPlayer, int x, int y) {
- // if (iPlayer < 0)
- // return;
- // if (iPlayer > 7)
- // return;
- //
- // usCursorActive |= (1 << iPlayer);
- //
- // if (x < 0)
- // x = 0;
- // if (x > 511)
- // x = 511;
- // if (y < 0)
- // y = 0;
- // if (y > 255)
- // y = 255;
- //
- // ptCursorPoint[iPlayer].x = x;
- // ptCursorPoint[iPlayer].y = y;
-}
-
-////////////////////////////////////////////////////////////////////////
-// update lace is called evry VSync
-////////////////////////////////////////////////////////////////////////
-
-void CALLBACK GPUupdateLace(void) // VSYNC
-{
-
- g_gpu.status_reg ^= STATUS_ODDLINES;
-
- if (g_gpu.status_reg & STATUS_DISPLAYDISABLED) {
- do_clear_screen_buffer();
- return;
- }
-
- /* I do not roughly emulate interlace, I just draw 1/2 frame
- * to save CPU, and improve render */
- if (!(g_gpu.status_reg & STATUS_INTERLACED) || (g_gpu.status_reg
- & STATUS_ODDLINES))
- do_buffer_swap();
-
- frame_cap(g_gpu.fps);
-}
-
-////////////////////////////////////////////////////////////////////////
-// process read request from GPU status register
-////////////////////////////////////////////////////////////////////////
-
-
-uint32_t CALLBACK GPUreadStatus(void) // READ STATUS
-{
- return g_gpu.status_reg;
-}
-
-////////////////////////////////////////////////////////////////////////
-// processes data send to GPU status register
-// these are always single packet commands.
-////////////////////////////////////////////////////////////////////////
-
-void CALLBACK GPUwriteStatus(uint32_t gdata) {
- uint32_t lCommand = (gdata >> 24) & 0xff;
- g_gpu.ulStatusControl[lCommand] = gdata; // store command for freezing
- switch (lCommand) {
- case 0x00:
- /* reset GPU */
- memset(g_gpu.lGPUInfoVals, 0x00, 16 * sizeof(uint32_t));
- /* STATUS_READYFORCOMMANDS | STATUS_IDLE | STATUS_DISPLAYDISABLED | UNKNOW13 */
- g_gpu.status_reg = 0x14802000;
- g_gpu.DataWriteMode = DR_NORMAL;
- g_gpu.DataReadMode = DR_NORMAL;
- g_prim.drawX = 0;
- g_prim.drawY = 0;
- g_prim.drawW = 0;
- g_prim.drawH = 0;
- g_draw.sSetMask = 0;
- g_draw.lSetMask = 0;
- g_draw.bCheckMask = 0;
- g_prim.usMirror = 0;
- g_soft.GlobalTextAddrX = 0;
- g_soft.GlobalTextAddrY = 0;
- g_soft.GlobalTextTP = 0;
- g_soft.GlobalTextABR = 0;
- g_prim.bUsingTWin = 0;
- return;
- case 0x01:
- /* reset command buffer */
- //fprintf(stderr, "Reset command buffer not implemented\n");
- return;
- case 0x02:
- /* reset IRQ */
- //fprintf(stderr, "Reset IRQ not implemented\n");
- return;
- case 0x03:
- /* Enable or disable the display */
- if (gdata & 0x01)
- g_gpu.status_reg |= STATUS_DISPLAYDISABLED;
- else
- g_gpu.status_reg &= ~STATUS_DISPLAYDISABLED;
- return;
- case 0x04:
- /* Set the transfering mode */
- gdata &= 0x03; // Only want the lower two bits
- g_gpu.DataWriteMode = DR_NORMAL;
- g_gpu.DataReadMode = DR_NORMAL;
- if (gdata == 0x02)
- g_gpu.DataWriteMode = DR_VRAMTRANSFER;
- if (gdata == 0x03)
- g_gpu.DataReadMode = DR_VRAMTRANSFER;
- g_gpu.status_reg &= ~STATUS_DMABITS; // Clear the current settings of the DMA bits
- g_gpu.status_reg |= (gdata << 29); // Set the DMA bits according to the received data
- return;
- case 0x05:
- /* setting display position */
- g_gpu.dsp.position.y = (short) ((gdata >> 10) & 0x1ff);
- g_gpu.dsp.position.x = (short) (gdata & 0x3ff);
- //fprintf(stderr, "Update display position X=%d,Y=%d\n",
- // g_gpu.dsp.position.x, g_gpu.dsp.position.y);
- return;
- case 0x06:
- /* Set width */
- g_gpu.dsp.range.x0 = (short) (gdata & 0x03ff);
- g_gpu.dsp.range.x1 = (short) ((gdata >> 12) & 0x0fff);
- //fprintf(stderr, "Setrange x0 : %d, x1 : %d\n", g_gpu.dsp.range.x0,
- // g_gpu.dsp.range.x1);
- return;
- case 0x07:
- /* Set height */
- g_gpu.dsp.range.y0 = (short) (gdata & 0x3ff);
- g_gpu.dsp.range.y1 = (short) ((gdata >> 10) & 0x3ff);
- //fprintf(stderr, "Setrange y0 : %d, y1 : %d\n", g_gpu.dsp.range.y0,
- // g_gpu.dsp.range.y1);
- return;
- case 0x08:
- /* setting display infos */
- //fprintf(stderr, "command %x\n", gdata&0x000043);
- switch (gdata & 0x000043) {
- case 0x00:
- g_gpu.dsp.mode.x = 10;
- break;
- case 0x01:
- g_gpu.dsp.mode.x = 8;
- break;
- case 0x02:
- g_gpu.dsp.mode.x = 5;
- break;
- case 0x03:
- g_gpu.dsp.mode.x = 4;
- break;
- case 0x40:
- g_gpu.dsp.mode.x = 7;
- break;
- default:
- g_gpu.dsp.mode.x = 0;
- }
-
- /* clear width status */
- g_gpu.status_reg &= ~STATUS_WIDTHBITS;
- /* update status reg */
- g_gpu.status_reg |= ((gdata & 0x00000003) << 17)
- | ((gdata & 0x00000040) << 10);
-
- switch (gdata & 0x000004) {
- case 0x00:
- g_gpu.status_reg &= ~STATUS_DOUBLEHEIGHT;
- g_gpu.dsp.mode.y = 1;
- break;
- case 0x04:
- g_gpu.status_reg |= STATUS_DOUBLEHEIGHT;
- g_gpu.dsp.mode.y = 2;
- break;
- }
-
- switch (gdata & 0x08) {
- case 0x00:
- g_gpu.status_reg &= ~STATUS_PAL;
- g_gpu.fps = 60;
- break;
- case 0x08:
- g_gpu.status_reg |= STATUS_PAL;
- g_gpu.fps = 50;
- break;
- }
- //fprintf(stderr, "video mode %dx%d\n", g_gpu.dsp.mode.x, g_gpu.dsp.mode.y);
-
- if ((gdata & 0x10)) {
- g_gpu.status_reg |= STATUS_RGB24;
- } else {
- g_gpu.status_reg &= ~STATUS_RGB24;
- }
-
- if ((gdata & 0x20)) {
- g_gpu.status_reg |= STATUS_INTERLACED;
- } else {
- g_gpu.status_reg &= ~STATUS_INTERLACED;
- }
- return;
- case 0x10:
- /* ask about GPU version and other stuff */
- gdata &= 0xff;
- switch (gdata) {
- case 0x02:
- g_gpu.lGPUdataRet = g_gpu.lGPUInfoVals[INFO_TW]; // tw infos
- return;
- case 0x03:
- g_gpu.lGPUdataRet = g_gpu.lGPUInfoVals[INFO_DRAWSTART]; // draw start
- return;
- case 0x04:
- g_gpu.lGPUdataRet = g_gpu.lGPUInfoVals[INFO_DRAWEND]; // draw end
- return;
- case 0x05:
- case 0x06:
- g_gpu.lGPUdataRet = g_gpu.lGPUInfoVals[INFO_DRAWOFF]; // draw offset
- return;
- case 0x07:
- if (0)
- g_gpu.lGPUdataRet = 0x01;
- else
- g_gpu.lGPUdataRet = 0x02; // gpu type
- return;
- case 0x08:
- case 0x0F: // some bios addr?
- g_gpu.lGPUdataRet = 0xBFC03720;
- return;
- }
- return;
- default:
- fprintf(stderr, "Unknow command %02x\n", lCommand);
- }
-}
-
-////////////////////////////////////////////////////////////////////////
-// vram read/write helpers, needed by LEWPY's optimized vram read/write :)
-////////////////////////////////////////////////////////////////////////
-
-static inline void FinishedVRAMWrite(void) {
- // Set register to NORMAL operation
- g_gpu.DataWriteMode = DR_NORMAL;
- // Reset transfer values, to prevent mis-transfer of data
- g_gpu.VRAMWrite.x = 0;
- g_gpu.VRAMWrite.y = 0;
- g_gpu.VRAMWrite.Width = 0;
- g_gpu.VRAMWrite.Height = 0;
- g_gpu.VRAMWrite.ColsRemaining = 0;
- g_gpu.VRAMWrite.RowsRemaining = 0;
-}
-
-static inline void FinishedVRAMRead(void) {
- // Set register to NORMAL operation
- g_gpu.DataReadMode = DR_NORMAL;
- // Reset transfer values, to prevent mis-transfer of data
- g_gpu.VRAMRead.x = 0;
- g_gpu.VRAMRead.y = 0;
- g_gpu.VRAMRead.Width = 0;
- g_gpu.VRAMRead.Height = 0;
- g_gpu.VRAMRead.ColsRemaining = 0;
- g_gpu.VRAMRead.RowsRemaining = 0;
-
- // Indicate GPU is no longer ready for VRAM data in the STATUS REGISTER
- g_gpu.status_reg &= ~STATUS_READYFORVRAM;
-}
-
-////////////////////////////////////////////////////////////////////////
-// core read from vram
-////////////////////////////////////////////////////////////////////////
-
-void CALLBACK GPUreadDataMem(uint32_t * pMem, int iSize) {
- int i;
-
- if (g_gpu.DataReadMode != DR_VRAMTRANSFER)
- return;
-
- g_gpu.status_reg &= ~STATUS_IDLE;
-
- // adjust read ptr, if necessary
-
- while (g_gpu.VRAMRead.ImagePtr >= g_gpu.psxVuw_eom.u16)
- g_gpu.VRAMRead.ImagePtr -= 512 * 1024;
- while (g_gpu.VRAMRead.ImagePtr < g_gpu.psx_vram.u16)
- g_gpu.VRAMRead.ImagePtr += 512 * 1024;
-
- for (i = 0; i < iSize; i++) {
- // do 2 seperate 16bit reads for compatibility (wrap issues)
- if ((g_gpu.VRAMRead.ColsRemaining > 0) && (g_gpu.VRAMRead.RowsRemaining
- > 0)) {
- // lower 16 bit
- g_gpu.lGPUdataRet = (uint32_t) GETLE16(g_gpu.VRAMRead.ImagePtr);
-
- g_gpu.VRAMRead.ImagePtr++;
- if (g_gpu.VRAMRead.ImagePtr >= g_gpu.psxVuw_eom.u16)
- g_gpu.VRAMRead.ImagePtr -= 512 * 1024;
- g_gpu.VRAMRead.RowsRemaining--;
-
- if (g_gpu.VRAMRead.RowsRemaining <= 0) {
- g_gpu.VRAMRead.RowsRemaining = g_gpu.VRAMRead.Width;
- g_gpu.VRAMRead.ColsRemaining--;
- g_gpu.VRAMRead.ImagePtr += 1024 - g_gpu.VRAMRead.Width;
- if (g_gpu.VRAMRead.ImagePtr >= g_gpu.psxVuw_eom.u16)
- g_gpu.VRAMRead.ImagePtr -= 512 * 1024;
- }
-
- // higher 16 bit (always, even if it's an odd width)
- g_gpu.lGPUdataRet |= (uint32_t) GETLE16(g_gpu.VRAMRead.ImagePtr)
- << 16;
- PUTLE32(pMem, g_gpu.lGPUdataRet);
- pMem++;
-
- if (g_gpu.VRAMRead.ColsRemaining <= 0) {
- FinishedVRAMRead();
- goto ENDREAD;
- }
-
- g_gpu.VRAMRead.ImagePtr++;
- if (g_gpu.VRAMRead.ImagePtr >= g_gpu.psxVuw_eom.u16)
- g_gpu.VRAMRead.ImagePtr -= 512 * 1024;
- g_gpu.VRAMRead.RowsRemaining--;
- if (g_gpu.VRAMRead.RowsRemaining <= 0) {
- g_gpu.VRAMRead.RowsRemaining = g_gpu.VRAMRead.Width;
- g_gpu.VRAMRead.ColsRemaining--;
- g_gpu.VRAMRead.ImagePtr += 1024 - g_gpu.VRAMRead.Width;
- if (g_gpu.VRAMRead.ImagePtr >= g_gpu.psxVuw_eom.u16)
- g_gpu.VRAMRead.ImagePtr -= 512 * 1024;
- }
- if (g_gpu.VRAMRead.ColsRemaining <= 0) {
- FinishedVRAMRead();
- goto ENDREAD;
- }
- } else {
- FinishedVRAMRead();
- goto ENDREAD;
- }
- }
-
- ENDREAD: g_gpu.status_reg |= STATUS_IDLE;
-}
-
-////////////////////////////////////////////////////////////////////////
-
-uint32_t CALLBACK GPUreadData(void) {
- uint32_t l;
- GPUreadDataMem(&l, 1);
- return g_gpu.lGPUdataRet;
-}
-
-////////////////////////////////////////////////////////////////////////
-// processes data send to GPU data register
-// extra table entries for fixing polyline troubles
-////////////////////////////////////////////////////////////////////////
-
-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;
-
- g_gpu.status_reg &= ~STATUS_IDLE;
- g_gpu.status_reg &= ~STATUS_READYFORCOMMANDS;
-
- STARTVRAM:
-
- if (g_gpu.DataWriteMode == DR_VRAMTRANSFER) {
- char bFinished = 0;
-
- // make sure we are in vram
- while (g_gpu.VRAMWrite.ImagePtr >= g_gpu.psxVuw_eom.u16)
- g_gpu.VRAMWrite.ImagePtr -= 512 * 1024;
- while (g_gpu.VRAMWrite.ImagePtr < g_gpu.psx_vram.u16)
- g_gpu.VRAMWrite.ImagePtr += 512 * 1024;
-
- // now do the loop
- while (g_gpu.VRAMWrite.ColsRemaining > 0) {
- while (g_gpu.VRAMWrite.RowsRemaining > 0) {
- if (i >= iSize) {
- goto ENDVRAM;
- }
- i++;
-
- gdata = GETLE32(pMem);
- pMem++;
-
- PUTLE16(g_gpu.VRAMWrite.ImagePtr, (unsigned short)gdata);
- g_gpu.VRAMWrite.ImagePtr++;
- if (g_gpu.VRAMWrite.ImagePtr >= g_gpu.psxVuw_eom.u16)
- g_gpu.VRAMWrite.ImagePtr -= 512 * 1024;
- g_gpu.VRAMWrite.RowsRemaining--;
-
- if (g_gpu.VRAMWrite.RowsRemaining <= 0) {
- g_gpu.VRAMWrite.ColsRemaining--;
- if (g_gpu.VRAMWrite.ColsRemaining <= 0) // last pixel is odd width
- {
- gdata
- = (gdata & 0xFFFF)
- | (((uint32_t) GETLE16(g_gpu.VRAMWrite.ImagePtr))
- << 16);
- FinishedVRAMWrite();
- goto ENDVRAM;
- }
- g_gpu.VRAMWrite.RowsRemaining = g_gpu.VRAMWrite.Width;
- g_gpu.VRAMWrite.ImagePtr += 1024 - g_gpu.VRAMWrite.Width;
- }
-
- PUTLE16(g_gpu.VRAMWrite.ImagePtr, (unsigned short)(gdata>>16));
- g_gpu.VRAMWrite.ImagePtr++;
- if (g_gpu.VRAMWrite.ImagePtr >= g_gpu.psxVuw_eom.u16)
- g_gpu.VRAMWrite.ImagePtr -= 512 * 1024;
- g_gpu.VRAMWrite.RowsRemaining--;
- }
-
- g_gpu.VRAMWrite.RowsRemaining = g_gpu.VRAMWrite.Width;
- g_gpu.VRAMWrite.ColsRemaining--;
- g_gpu.VRAMWrite.ImagePtr += 1024 - g_gpu.VRAMWrite.Width;
- bFinished = 1;
- }
-
- FinishedVRAMWrite();
- }
-
- ENDVRAM:
-
- if (g_gpu.DataWriteMode == DR_NORMAL) {
- void (* *primFunc)(unsigned char *);
- primFunc = primTableJ;
-
- for (; i < iSize;) {
- if (g_gpu.DataWriteMode == DR_VRAMTRANSFER)
- goto STARTVRAM;
-
- gdata = GETLE32(pMem);
- pMem++;
- i++;
-
- if (g_gpu.gpuDataC == 0) {
- command = (unsigned char) ((gdata >> 24) & 0xff);
-
- //if(command>=0xb0 && command<0xc0) auxprintf("b0 %x!!!!!!!!!\n",command);
-
- if (primTableCX[command]) {
- g_gpu.gpuDataC = primTableCX[command];
- g_gpu.gpuCommand = command;
- PUTLE32(&g_gpu.gpuDataM[0], gdata);
- g_gpu.gpuDataP = 1;
- } else {
- //fprintf(stderr, "unknow command %02x \n", command);
- continue;
- }
- } else {
- PUTLE32(&g_gpu.gpuDataM[g_gpu.gpuDataP], gdata);
- if (g_gpu.gpuDataC > 128) {
- if ((g_gpu.gpuDataC == 254 && g_gpu.gpuDataP >= 3)
- || (g_gpu.gpuDataC == 255 && g_gpu.gpuDataP >= 4
- && !(g_gpu.gpuDataP & 1))) {
- if ((g_gpu.gpuDataM[g_gpu.gpuDataP] & 0xF000F000)
- == 0x50005000)
- g_gpu.gpuDataP = g_gpu.gpuDataC - 1;
- }
- }
- g_gpu.gpuDataP++;
- }
-
- if (g_gpu.gpuDataP == g_gpu.gpuDataC) {
- g_gpu.gpuDataC = g_gpu.gpuDataP = 0;
- primFunc[g_gpu.gpuCommand]((unsigned char *) g_gpu.gpuDataM);
- }
- }
- }
-
- g_gpu.lGPUdataRet = gdata;
-
- g_gpu.status_reg |= STATUS_READYFORCOMMANDS;
- g_gpu.status_reg |= STATUS_IDLE;
-}
-
-////////////////////////////////////////////////////////////////////////
-
-void CALLBACK GPUwriteData(uint32_t gdata) {
- PUTLE32(&gdata, gdata);
- GPUwriteDataMem(&gdata, 1);
-}
-
-////////////////////////////////////////////////////////////////////////
-// this functions will be removed soon (or 'soonish')... not really needed, but some emus want them
-////////////////////////////////////////////////////////////////////////
-
-#if 0
-void CALLBACK GPUsetMode(unsigned long gdata) {
- // Peops does nothing here...
- // DataWriteMode=(gdata&1)?DR_VRAMTRANSFER:DR_NORMAL;
- // DataReadMode =(gdata&2)?DR_VRAMTRANSFER:DR_NORMAL;
-}
-
-long CALLBACK GPUgetMode(void) {
- long iT = 0;
-
- if (g_gpu.DataWriteMode == DR_VRAMTRANSFER)
- iT |= 0x1;
- if (g_gpu.DataReadMode == DR_VRAMTRANSFER)
- iT |= 0x2;
- return iT;
-}
-#endif
-
-////////////////////////////////////////////////////////////////////////
-// call config dlg
-////////////////////////////////////////////////////////////////////////
-
-long CALLBACK GPUconfigure(void) {
- SoftDlgProc();
- return 0;
-}
-
-////////////////////////////////////////////////////////////////////////
-// sets all kind of act fixes
-////////////////////////////////////////////////////////////////////////
-
-#if 0
-void SetFixes(void) {
-
-}
-#endif
-
-////////////////////////////////////////////////////////////////////////
-// process gpu commands
-////////////////////////////////////////////////////////////////////////
-
-unsigned long lUsedAddr[3];
-
-static inline char CheckForEndlessLoop(unsigned long 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 CALLBACK GPUdmaChain(uint32_t * baseAddrL, uint32_t addr) {
- uint32_t dmaMem;
- unsigned char * baseAddrB;
- short count;
- unsigned int DMACommandCounter = 0;
-
- g_gpu.status_reg &= ~STATUS_IDLE;
-
- lUsedAddr[0] = lUsedAddr[1] = lUsedAddr[2] = 0xffffff;
-
- baseAddrB = (unsigned char*) baseAddrL;
-
- do {
- if (1)
- addr &= 0x1FFFFC;
- if (DMACommandCounter++ > 2000000)
- break;
- if (CheckForEndlessLoop(addr))
- break;
-
- count = baseAddrB[addr + 3];
-
- dmaMem = addr + 4;
-
- if (count > 0)
- GPUwriteDataMem(&baseAddrL[dmaMem >> 2], count);
-
- addr = GETLE32(&baseAddrL[addr>>2]) & 0xffffff;
- } while (addr != 0xffffff);
-
- g_gpu.status_reg |= STATUS_IDLE;
- return 0;
-}
-
-////////////////////////////////////////////////////////////////////////
-// show about dlg
-////////////////////////////////////////////////////////////////////////
-
-
-void CALLBACK GPUabout(void) // ABOUT
-{
- AboutDlgProc();
- return;
-}
-
-////////////////////////////////////////////////////////////////////////
-// We are ever fine ;)
-////////////////////////////////////////////////////////////////////////
-
-long CALLBACK GPUtest(void) {
- // if test fails this function should return negative value for error (unable to continue)
- // and positive value for warning (can continue but output might be crappy)
- return 0;
-}
-
-////////////////////////////////////////////////////////////////////////
-// Freeze
-////////////////////////////////////////////////////////////////////////
-
-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;
- //g_gpu.lSelectedSlot = lSlotNum + 1;
- //BuildDispMenu(0);
- return 1;
- }
- //----------------------------------------------------//
- if (!pF)
- return 0; // some checks
- if (pF->ulFreezeVersion != 1)
- return 0;
-
- if (ulGetFreezeData == 1) // 1: get data
- {
- pF->ulStatus = g_gpu.status_reg;
- memcpy(pF->ulControl, g_gpu.ulStatusControl, 256 * sizeof(uint32_t));
- memcpy(pF->psxVRam, g_gpu.psx_vram.u8, 1024 * 512 * 2);
-
- return 1;
- }
-
- if (ulGetFreezeData != 0)
- return 0; // 0: set data
-
- g_gpu.status_reg = pF->ulStatus;
- memcpy(g_gpu.ulStatusControl, pF->ulControl, 256 * sizeof(uint32_t));
- memcpy(g_gpu.psx_vram.u8, pF->psxVRam, 1024 * 512 * 2);
-
- // RESET TEXTURE STORE HERE, IF YOU USE SOMETHING LIKE THAT
-
- GPUwriteStatus(g_gpu.ulStatusControl[0]);
- GPUwriteStatus(g_gpu.ulStatusControl[1]);
- GPUwriteStatus(g_gpu.ulStatusControl[2]);
- GPUwriteStatus(g_gpu.ulStatusControl[3]);
- GPUwriteStatus(g_gpu.ulStatusControl[8]); // try to repair things
- GPUwriteStatus(g_gpu.ulStatusControl[6]);
- GPUwriteStatus(g_gpu.ulStatusControl[7]);
- GPUwriteStatus(g_gpu.ulStatusControl[5]);
- GPUwriteStatus(g_gpu.ulStatusControl[4]);
-
- return 1;
-}
-
-////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////
-
-////////////////////////////////////////////////////////////////////////
-// SAVE STATE DISPLAY STUFF
-////////////////////////////////////////////////////////////////////////
-
-// font 0-9, 24x20 pixels, 1 byte = 4 dots
-// 00 = black
-// 01 = white
-// 10 = red
-// 11 = transparent
-
-unsigned char cFont[10][120] = {
-// 0
- { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x80, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
- 0x00, 0x05, 0x54, 0x00, 0x00, 0x80, 0x00, 0x14, 0x05, 0x00,
- 0x00, 0x80, 0x00, 0x14, 0x05, 0x00, 0x00, 0x80, 0x00, 0x14,
- 0x05, 0x00, 0x00, 0x80, 0x00, 0x14, 0x05, 0x00, 0x00, 0x80,
- 0x00, 0x14, 0x05, 0x00, 0x00, 0x80, 0x00, 0x14, 0x05, 0x00,
- 0x00, 0x80, 0x00, 0x14, 0x05, 0x00, 0x00, 0x80, 0x00, 0x14,
- 0x05, 0x00, 0x00, 0x80, 0x00, 0x05, 0x54, 0x00, 0x00, 0x80,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa },
- // 1
- { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x80, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
- 0x00, 0x00, 0x50, 0x00, 0x00, 0x80, 0x00, 0x05, 0x50, 0x00,
- 0x00, 0x80, 0x00, 0x00, 0x50, 0x00, 0x00, 0x80, 0x00, 0x00,
- 0x50, 0x00, 0x00, 0x80, 0x00, 0x00, 0x50, 0x00, 0x00, 0x80,
- 0x00, 0x00, 0x50, 0x00, 0x00, 0x80, 0x00, 0x00, 0x50, 0x00,
- 0x00, 0x80, 0x00, 0x00, 0x50, 0x00, 0x00, 0x80, 0x00, 0x00,
- 0x50, 0x00, 0x00, 0x80, 0x00, 0x05, 0x55, 0x00, 0x00, 0x80,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa },
- // 2
- { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x80, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
- 0x00, 0x05, 0x54, 0x00, 0x00, 0x80, 0x00, 0x14, 0x05, 0x00,
- 0x00, 0x80, 0x00, 0x00, 0x05, 0x00, 0x00, 0x80, 0x00, 0x00,
- 0x05, 0x00, 0x00, 0x80, 0x00, 0x00, 0x14, 0x00, 0x00, 0x80,
- 0x00, 0x00, 0x50, 0x00, 0x00, 0x80, 0x00, 0x01, 0x40, 0x00,
- 0x00, 0x80, 0x00, 0x05, 0x00, 0x00, 0x00, 0x80, 0x00, 0x14,
- 0x00, 0x00, 0x00, 0x80, 0x00, 0x15, 0x55, 0x00, 0x00, 0x80,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa },
- // 3
- { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x80, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
- 0x00, 0x05, 0x54, 0x00, 0x00, 0x80, 0x00, 0x14, 0x05, 0x00,
- 0x00, 0x80, 0x00, 0x00, 0x05, 0x00, 0x00, 0x80, 0x00, 0x00,
- 0x05, 0x00, 0x00, 0x80, 0x00, 0x01, 0x54, 0x00, 0x00, 0x80,
- 0x00, 0x00, 0x05, 0x00, 0x00, 0x80, 0x00, 0x00, 0x05, 0x00,
- 0x00, 0x80, 0x00, 0x00, 0x05, 0x00, 0x00, 0x80, 0x00, 0x14,
- 0x05, 0x00, 0x00, 0x80, 0x00, 0x05, 0x54, 0x00, 0x00, 0x80,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa },
- // 4
- { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x80, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
- 0x00, 0x00, 0x14, 0x00, 0x00, 0x80, 0x00, 0x00, 0x54, 0x00,
- 0x00, 0x80, 0x00, 0x01, 0x54, 0x00, 0x00, 0x80, 0x00, 0x01,
- 0x54, 0x00, 0x00, 0x80, 0x00, 0x05, 0x14, 0x00, 0x00, 0x80,
- 0x00, 0x14, 0x14, 0x00, 0x00, 0x80, 0x00, 0x15, 0x55, 0x00,
- 0x00, 0x80, 0x00, 0x00, 0x14, 0x00, 0x00, 0x80, 0x00, 0x00,
- 0x14, 0x00, 0x00, 0x80, 0x00, 0x00, 0x55, 0x00, 0x00, 0x80,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa },
- // 5
- { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x80, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
- 0x00, 0x15, 0x55, 0x00, 0x00, 0x80, 0x00, 0x14, 0x00, 0x00,
- 0x00, 0x80, 0x00, 0x14, 0x00, 0x00, 0x00, 0x80, 0x00, 0x14,
- 0x00, 0x00, 0x00, 0x80, 0x00, 0x15, 0x54, 0x00, 0x00, 0x80,
- 0x00, 0x00, 0x05, 0x00, 0x00, 0x80, 0x00, 0x00, 0x05, 0x00,
- 0x00, 0x80, 0x00, 0x00, 0x05, 0x00, 0x00, 0x80, 0x00, 0x14,
- 0x05, 0x00, 0x00, 0x80, 0x00, 0x05, 0x54, 0x00, 0x00, 0x80,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa },
- // 6
- { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x80, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
- 0x00, 0x01, 0x54, 0x00, 0x00, 0x80, 0x00, 0x05, 0x00, 0x00,
- 0x00, 0x80, 0x00, 0x14, 0x00, 0x00, 0x00, 0x80, 0x00, 0x14,
- 0x00, 0x00, 0x00, 0x80, 0x00, 0x15, 0x54, 0x00, 0x00, 0x80,
- 0x00, 0x15, 0x05, 0x00, 0x00, 0x80, 0x00, 0x14, 0x05, 0x00,
- 0x00, 0x80, 0x00, 0x14, 0x05, 0x00, 0x00, 0x80, 0x00, 0x14,
- 0x05, 0x00, 0x00, 0x80, 0x00, 0x05, 0x54, 0x00, 0x00, 0x80,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa },
- // 7
- { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x80, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
- 0x00, 0x15, 0x55, 0x00, 0x00, 0x80, 0x00, 0x14, 0x05, 0x00,
- 0x00, 0x80, 0x00, 0x00, 0x14, 0x00, 0x00, 0x80, 0x00, 0x00,
- 0x14, 0x00, 0x00, 0x80, 0x00, 0x00, 0x50, 0x00, 0x00, 0x80,
- 0x00, 0x00, 0x50, 0x00, 0x00, 0x80, 0x00, 0x01, 0x40, 0x00,
- 0x00, 0x80, 0x00, 0x01, 0x40, 0x00, 0x00, 0x80, 0x00, 0x05,
- 0x00, 0x00, 0x00, 0x80, 0x00, 0x05, 0x00, 0x00, 0x00, 0x80,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa },
- // 8
- { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x80, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
- 0x00, 0x05, 0x54, 0x00, 0x00, 0x80, 0x00, 0x14, 0x05, 0x00,
- 0x00, 0x80, 0x00, 0x14, 0x05, 0x00, 0x00, 0x80, 0x00, 0x14,
- 0x05, 0x00, 0x00, 0x80, 0x00, 0x05, 0x54, 0x00, 0x00, 0x80,
- 0x00, 0x14, 0x05, 0x00, 0x00, 0x80, 0x00, 0x14, 0x05, 0x00,
- 0x00, 0x80, 0x00, 0x14, 0x05, 0x00, 0x00, 0x80, 0x00, 0x14,
- 0x05, 0x00, 0x00, 0x80, 0x00, 0x05, 0x54, 0x00, 0x00, 0x80,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa },
- // 9
- { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x80, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
- 0x00, 0x05, 0x54, 0x00, 0x00, 0x80, 0x00, 0x14, 0x05, 0x00,
- 0x00, 0x80, 0x00, 0x14, 0x05, 0x00, 0x00, 0x80, 0x00, 0x14,
- 0x05, 0x00, 0x00, 0x80, 0x00, 0x14, 0x15, 0x00, 0x00, 0x80,
- 0x00, 0x05, 0x55, 0x00, 0x00, 0x80, 0x00, 0x00, 0x05, 0x00,
- 0x00, 0x80, 0x00, 0x00, 0x05, 0x00, 0x00, 0x80, 0x00, 0x00,
- 0x14, 0x00, 0x00, 0x80, 0x00, 0x05, 0x50, 0x00, 0x00, 0x80,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa } };
-
-////////////////////////////////////////////////////////////////////////
-
-#if 0
-static void PaintPicDot(unsigned char * p, unsigned char c) {
-
- if (c == 0) {
- *p++ = 0x00;
- *p++ = 0x00;
- *p = 0x00;
- return;
- } // black
- if (c == 1) {
- *p++ = 0xff;
- *p++ = 0xff;
- *p = 0xff;
- return;
- } // white
- if (c == 2) {
- *p++ = 0x00;
- *p++ = 0x00;
- *p = 0xff;
- return;
- } // red
- // transparent
-}
-#endif
-
-////////////////////////////////////////////////////////////////////////
-// the main emu allocs 128x96x3 bytes, and passes a ptr
-// to it in pMem... the plugin has to fill it with
-// 8-8-8 bit BGR screen data (Win 24 bit BMP format
-// without header).
-// Beware: the func can be called at any time,
-// so you have to use the frontbuffer to get a fully
-// rendered picture
-// LINUX version:
-
-long GPUgetScreenPic(unsigned char * pMem) {
- /*
- unsigned short c;unsigned char * pf;int x,y;
-
- float XS=(float)iResX/128;
- float YS=(float)iResY/96;
-
- pf=pMem;
- memset(pMem, 0, 128*96*3);
-
- if(Xpixels)
- {
- unsigned char * ps=(unsigned char *)Xpixels;
- {
- long lPitch=iResX<<2;
- uint32_t sx;
-
- for(y=0;y<96;y++)
- {
- for(x=0;x<128;x++)
- {
- sx=*((uint32_t *)((ps)+
- (((int)((float)y*YS))*lPitch)+
- ((int)((float)x*XS))*4));
- *(pf+0)=(sx&0xff);
- *(pf+1)=(sx&0xff00)>>8;
- *(pf+2)=(sx&0xff0000)>>16;
- pf+=3;
- }
- }
- }
- }
-
-
- /////////////////////////////////////////////////////////////////////
- // generic number/border painter
-
- pf=pMem+(103*3); // offset to number rect
-
- for(y=0;y<20;y++) // loop the number rect pixel
- {
- for(x=0;x<6;x++)
- {
- c=cFont[lSelectedSlot][x+y*6]; // get 4 char dot infos at once (number depends on selected slot)
- PaintPicDot(pf,(c&0xc0)>>6);pf+=3; // paint the dots into the rect
- PaintPicDot(pf,(c&0x30)>>4);pf+=3;
- PaintPicDot(pf,(c&0x0c)>>2);pf+=3;
- PaintPicDot(pf,(c&0x03)); pf+=3;
- }
- pf+=104*3; // next rect y line
- }
-
- pf=pMem; // ptr to first pos in 128x96 pic
- for(x=0;x<128;x++) // loop top/bottom line
- {
- *(pf+(95*128*3))=0x00;*pf++=0x00;
- *(pf+(95*128*3))=0x00;*pf++=0x00; // paint it red
- *(pf+(95*128*3))=0xff;*pf++=0xff;
- }
- pf=pMem; // ptr to first pos
- for(y=0;y<96;y++) // loop left/right line
- {
- *(pf+(127*3))=0x00;*pf++=0x00;
- *(pf+(127*3))=0x00;*pf++=0x00; // paint it red
- *(pf+(127*3))=0xff;*pf++=0xff;
- pf+=127*3; // offset to next line
- }
- */
- return -1;
-}
-
-////////////////////////////////////////////////////////////////////////
-// func will be called with 128x96x3 BGR data.
-// the plugin has to store the data and display
-// it in the upper right corner.
-// If the func is called with a NULL ptr, you can
-// release your picture data and stop displaying
-// the screen pic
-
-long CALLBACK GPUshowScreenPic(unsigned char * pMem) {
- DestroyPic(); // destroy old pic data
- if (pMem == 0)
- return 0; // done
- CreatePic(pMem); // create new pic... don't free pMem or something like that... just read from it
- return 0;
-}
-
-#if 0
-void CALLBACK GPUsetfix(uint32_t dwFixBits) {
- g_prim.dwEmuFixes = dwFixBits;
-}
-#endif
-
-void CALLBACK GPUvBlank(int val) {
- //fprintf(stderr, "Vblanc %d\n", val);
- //if(val)
- // g_gpu.status_reg |= STATUS_ODDLINES;
- //else
- // g_gpu.status_reg &= ~STATUS_ODDLINES;
-}
+/*
+ * Copyright (C) 2010 Benoit Gschwind
+ * Inspired by original author : Pete Bernert
+ *
+ * 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 3 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., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "globals.h"
+#include "gpu.h"
+#include "swap.h"
+
+#define CALLBACK
+
+#define INFO_TW 0
+#define INFO_DRAWSTART 1
+#define INFO_DRAWEND 2
+#define INFO_DRAWOFF 3
+
+#define SHADETEXBIT(x) ((x>>24) & 0x1)
+#define SEMITRANSBIT(x) ((x>>25) & 0x1)
+#define PSXRGB(r,g,b) ((g<<10)|(b<<5)|r)
+
+#define DATAREGISTERMODES unsigned short
+
+#define DR_NORMAL 0
+#define DR_VRAMTRANSFER 1
+
+#define MIN(a,b) ((a) > (b) ? (b) : (a))
+#define MAX(a,b) ((a) < (b) ? (b) : (a))
+
+#ifdef ENABLE_NLS
+#include <libintl.h>
+#include <locale.h>
+#define _(x) gettext(x)
+#define N_(x) (x)
+#else
+#define _(x) (x)
+#define N_(x) (x)
+#endif
+
+////////////////////////////////////////////////////////////////////////
+// PPDK developer must change libraryName field and can change revision and build
+////////////////////////////////////////////////////////////////////////
+
+unsigned char const version = 1; // do not touch - library for PSEmu 1.x
+unsigned char const revision = 0;
+unsigned char const build = 0; // increase that with each version
+
+static char const * libraryName = N_("GXVideo Driver");
+static char const * libraryInfo = N_("GXvideo Driver v1.00");
+//static char const * PluginAuthor =
+// N_("gschwind (rewrite from Pete Bernert and the P.E.Op.S. team)");
+
+////////////////////////////////////////////////////////////////////////
+// some misc external display funcs
+////////////////////////////////////////////////////////////////////////
+
+#include <time.h>
+
+//void CALLBACK GPUdisplayText(char * pText) {
+//
+//}
+
+////////////////////////////////////////////////////////////////////////
+
+//void CALLBACK GPUdisplayFlags(unsigned long dwFlags) // some info func
+//{
+//dwCoreFlags = dwFlags;
+//BuildDispMenu(0);
+//}
+
+////////////////////////////////////////////////////////////////////////
+// stuff to make this a true PDK module
+////////////////////////////////////////////////////////////////////////
+
+char * CALLBACK PSEgetLibName(void) {
+ return _(libraryName);
+}
+
+unsigned long CALLBACK PSEgetLibType(void) {
+ //return PSE_LT_GPU;
+ return 2; /* GPU plugin */
+}
+
+unsigned long CALLBACK PSEgetLibVersion(void) {
+ return version << 16 | revision << 8 | build;
+}
+
+char * GPUgetLibInfos(void) {
+ return _(libraryInfo);
+}
+
+////////////////////////////////////////////////////////////////////////
+// Snapshot func
+////////////////////////////////////////////////////////////////////////
+
+//char * pGetConfigInfos(int iCfg) {
+// char szO[2][4] = { "off", "on " };
+// char szTxt[256];
+// char * pB = (char *) malloc(32767);
+//
+// if (!pB)
+// return NULL;
+// *pB = 0;
+// //----------------------------------------------------//
+// sprintf(szTxt, "Plugin: %s %d.%d.%d\r\n", libraryName, version, revision,
+// build);
+// strcat(pB, szTxt);
+// sprintf(szTxt, "Author: %s\r\n\r\n", PluginAuthor);
+// strcat(pB, szTxt);
+// //----------------------------------------------------//
+//
+// sprintf(szTxt, "Resolution/Color:\r\n- %dx%d ", g_cfg.ResX, g_cfg.ResY);
+//
+// strcat(pB, szTxt);
+// if (iWindowMode && iCfg)
+// strcpy(szTxt, "Window mode\r\n");
+// else if (iWindowMode)
+// sprintf(szTxt, "Window mode - [%d Bit]\r\n", iDesktopCol);
+// else
+// sprintf(szTxt, "Fullscreen - [%d Bit]\r\n", iColDepth);
+// strcat(pB, szTxt);
+//
+// sprintf(szTxt, "Stretch mode: %d\r\n", iUseNoStretchBlt);
+// strcat(pB, szTxt);
+// sprintf(szTxt, "Dither mode: %d\r\n\r\n", iUseDither);
+// strcat(pB, szTxt);
+// //----------------------------------------------------//
+// sprintf(szTxt, "Framerate:\r\n- FPS limit: %s\r\n", szO[UseFrameLimit]);
+// strcat(pB, szTxt);
+// sprintf(szTxt, "- Frame skipping: %s", szO[UseFrameSkip]);
+// strcat(pB, szTxt);
+// if (iFastFwd)
+// strcat(pB, " (fast forward)");
+// strcat(pB, "\r\n");
+// if (iFrameLimit == 2)
+// strcpy(szTxt, "- FPS limit: Auto\r\n\r\n");
+// else
+// sprintf(szTxt, "- FPS limit: %.1f\r\n\r\n", fFrameRate);
+// strcat(pB, szTxt);
+// //----------------------------------------------------//
+//#if !defined (_MACGL) && !defined (_WINDOWS)
+// strcpy(szTxt, "Misc:\r\n- MaintainAspect: ");
+// if (iMaintainAspect == 0)
+// strcat(szTxt, "disabled");
+// else if (iMaintainAspect == 1)
+// strcat(szTxt, "enabled");
+// strcat(szTxt, "\r\n");
+// strcat(pB, szTxt);
+//#endif
+// sprintf(szTxt, "- Game fixes: %s [%08x]\r\n", szO[iUseFixes], dwCfgFixes);
+// strcat(pB, szTxt);
+// //----------------------------------------------------//
+// return pB;
+// return 0;
+//}
+
+void CALLBACK GPUmakeSnapshot(void) {
+ // FILE *bmpfile;
+ // char filename[256];
+ // unsigned char header[0x36];
+ // long size, height;
+ // unsigned char line[1024 * 3];
+ // short i, j;
+ // unsigned char empty[2] = { 0, 0 };
+ // unsigned short color;
+ // unsigned long snapshotnr = 0;
+ // unsigned char *pD;
+ //
+ // height = gpu_ctx.PreviousPSXDisplay.DisplayMode.y;
+ //
+ // size = height * PreviousPSXDisplay.Range.x1 * 3 + 0x38;
+ //
+ // // fill in proper values for BMP
+ //
+ // // hardcoded BMP header
+ // memset(header, 0, 0x36);
+ // header[0] = 'B';
+ // header[1] = 'M';
+ // header[2] = size & 0xff;
+ // header[3] = (size >> 8) & 0xff;
+ // header[4] = (size >> 16) & 0xff;
+ // header[5] = (size >> 24) & 0xff;
+ // header[0x0a] = 0x36;
+ // header[0x0e] = 0x28;
+ // header[0x12] = gpu_ctx.PreviousPSXDisplay.Range.x1 % 256;
+ // header[0x13] = gpu_ctx.PreviousPSXDisplay.Range.x1 / 256;
+ // header[0x16] = height % 256;
+ // header[0x17] = height / 256;
+ // header[0x1a] = 0x01;
+ // header[0x1c] = 0x18;
+ // header[0x26] = 0x12;
+ // header[0x27] = 0x0B;
+ // header[0x2A] = 0x12;
+ // header[0x2B] = 0x0B;
+ //
+ // // increment snapshot value & try to get filename
+ // do {
+ // snapshotnr++;
+ //#ifdef _WINDOWS
+ // sprintf(filename,"snap\\pcsx%04ld.bmp",snapshotnr);
+ //#else
+ // sprintf(filename, "%s/pcsx%04ld.bmp", getenv("HOME"), snapshotnr);
+ //#endif
+ //
+ // bmpfile = fopen(filename, "rb");
+ // if (bmpfile == NULL)
+ // break;
+ //
+ // fclose(bmpfile);
+ // } while (TRUE);
+ //
+ // // try opening new snapshot file
+ // if ((bmpfile = fopen(filename, "wb")) == NULL)
+ // return;
+ //
+ // fwrite(header, 0x36, 1, bmpfile);
+ // for (i = height + PSXDisplay.DisplayPosition.y - 1; i
+ // >= PSXDisplay.DisplayPosition.y; i--) {
+ // pD = (unsigned char *) &psxVuw[i * 1024 + PSXDisplay.DisplayPosition.x];
+ // for (j = 0; j < PreviousPSXDisplay.Range.x1; j++) {
+ // if (PSXDisplay.RGB24) {
+ // uint32_t lu = *(uint32_t *) pD;
+ // line[j * 3 + 2] = (unsigned char) RED(lu);
+ // line[j * 3 + 1] = (unsigned char) GREEN(lu);
+ // line[j * 3 + 0] = (unsigned char) BLUE(lu);
+ // pD += 3;
+ // } else {
+ // color = GETLE16(pD);
+ // line[j * 3 + 2] = (color << 3) & 0xf1;
+ // line[j * 3 + 1] = (color >> 2) & 0xf1;
+ // line[j * 3 + 0] = (color >> 7) & 0xf1;
+ // pD += 2;
+ // }
+ // }
+ // fwrite(line, PreviousPSXDisplay.Range.x1 * 3, 1, bmpfile);
+ // }
+ // fwrite(empty, 0x2, 1, bmpfile);
+ // fclose(bmpfile);
+ //
+ // DoTextSnapShot(snapshotnr);
+}
+
+////////////////////////////////////////////////////////////////////////
+// INIT, will be called after lib load... well, just do some var init...
+////////////////////////////////////////////////////////////////////////
+
+long CALLBACK GPUinit() {
+ fprintf(stderr, "%s\n", __FUNCTION__);
+ memset(g_gpu.ulStatusControl, 0, 256 * sizeof(uint32_t)); // init save state scontrol field
+ g_gpu.psxVSecure.u8 = (uint8_t *) malloc((512 * 2) * 1024 + (1024 * 1024)); // always alloc one extra MB for soft drawing funcs security
+ if (!g_gpu.psxVSecure.u8)
+ return -1;
+
+ //!!! ATTENTION !!!
+ g_gpu.psx_vram.u8 = g_gpu.psxVSecure.u8 + 512 * 1024; // security offset into double sized psx vram!
+
+ g_gpu.psxVuw_eom.u16 = g_gpu.psx_vram.u16 + 1024 * 512; // pre-calc of end of vram
+
+ memset(g_gpu.psxVSecure.s8, 0x00, (512 * 2) * 1024 + (1024 * 1024));
+ memset(g_gpu.lGPUInfoVals, 0x00, 16 * sizeof(uint32_t));
+
+ g_gpu.dsp.range.x0 = 0;
+ g_gpu.dsp.range.x1 = 0;
+ g_gpu.lGPUdataRet = 0x400;
+
+ g_gpu.DataWriteMode = DR_NORMAL;
+
+ // Reset transfer values, to prevent mis-transfer of data
+ memset(&g_gpu.VRAMWrite, 0, sizeof(gxv_vram_load_t));
+ memset(&g_gpu.VRAMRead, 0, sizeof(gxv_vram_load_t));
+
+ // device initialised already !
+ g_gpu.status_reg = 0x14802000;
+ return 0;
+}
+
+/* Here starts all... */
+long GPUopen(unsigned long * disp, char * CapText, char * CfgFile) {
+ unsigned long d;
+
+ ReadConfig();
+
+ g_draw.bIsFirstFrame = 1;
+
+ d = init_display(); // setup x
+
+ if (disp)
+ *disp = d; // wanna x pointer? ok
+
+ if (d)
+ return 0;
+ return -1;
+}
+
+////////////////////////////////////////////////////////////////////////
+// time to leave...
+////////////////////////////////////////////////////////////////////////
+
+long CALLBACK GPUclose() {
+ fprintf(stderr, "%s\n", __FUNCTION__);
+ //ReleaseKeyHandler(); // de-subclass window
+ CloseDisplay(); // shutdown direct draw
+ return 0;
+}
+
+////////////////////////////////////////////////////////////////////////
+// I shot the sheriff
+////////////////////////////////////////////////////////////////////////
+
+long CALLBACK GPUshutdown() {
+ free(g_gpu.psxVSecure.s8);
+ return 0;
+}
+
+////////////////////////////////////////////////////////////////////////
+// roughly emulated screen centering bits... not complete !!!
+////////////////////////////////////////////////////////////////////////
+//
+//void ChangeDispOffsetsX(void) // X CENTER
+//{
+// long lx, l;
+//
+// if (!g_gpu.dsp.range.x1)
+// return;
+//
+// l = g_gpu.prev_dsp.DisplayMode.x;
+//
+// l *= (long) g_gpu.dsp.range.x1;
+// l /= 2560;
+// lx = l;
+// l &= 0xfffffff8;
+//
+// if (l == g_gpu.prev_dsp.range.y1)
+// return; // abusing range.y1 for
+// g_gpu.prev_dsp.range.y1 = (short) l; // storing last x range and test
+//
+// if (lx >= g_gpu.prev_dsp.DisplayMode.x) {
+// g_gpu.prev_dsp.range.x1 = (short) g_gpu.prev_dsp.DisplayMode.x;
+// g_gpu.prev_dsp.range.x0 = 0;
+// } else {
+// g_gpu.prev_dsp.range.x1 = (short) l;
+//
+// g_gpu.prev_dsp.range.x0 = (g_gpu.dsp.range.x0 - 500) / 8;
+//
+// if (g_gpu.prev_dsp.range.x0 < 0)
+// g_gpu.prev_dsp.range.x0 = 0;
+//
+// if ((g_gpu.prev_dsp.range.x0 + lx) > g_gpu.prev_dsp.DisplayMode.x) {
+// g_gpu.prev_dsp.range.x0 = (short) (g_gpu.prev_dsp.DisplayMode.x
+// - lx);
+// g_gpu.prev_dsp.range.x0 += 2; //???
+//
+// g_gpu.prev_dsp.range.x1 += (short) (lx - l);
+//
+// g_gpu.prev_dsp.range.x1 -= 2; // makes linux stretching easier
+// }
+//
+// // some linux alignment security
+// g_gpu.prev_dsp.range.x0 = g_gpu.prev_dsp.range.x0 >> 1;
+// g_gpu.prev_dsp.range.x0 = g_gpu.prev_dsp.range.x0 << 1;
+// g_gpu.prev_dsp.range.x1 = g_gpu.prev_dsp.range.x1 >> 1;
+// g_gpu.prev_dsp.range.x1 = g_gpu.prev_dsp.range.x1 << 1;
+//
+// DoClearScreenBuffer();
+// }
+//
+// g_prim.bDoVSyncUpdate = 1;
+//}
+
+////////////////////////////////////////////////////////////////////////
+
+//void ChangeDispOffsetsY(void) // Y CENTER
+//{
+// int iT, iO = g_gpu.prev_dsp.range.y0;
+// int iOldYOffset = g_gpu.prev_dsp.DisplayModeNew.y;
+//
+// // new
+//
+// if ((g_gpu.prev_dsp.DisplayModeNew.x + g_gpu.dsp.DisplayModeNew.y) > 512) {
+// int dy1 = 512 - g_gpu.prev_dsp.DisplayModeNew.x;
+// int dy2 =
+// (g_gpu.prev_dsp.DisplayModeNew.x + g_gpu.dsp.DisplayModeNew.y)
+// - 512;
+//
+// if (dy1 >= dy2) {
+// g_gpu.prev_dsp.DisplayModeNew.y = -dy2;
+// } else {
+// g_gpu.dsp.position.y = 0;
+// g_gpu.prev_dsp.DisplayModeNew.y = -dy1;
+// }
+// } else
+// g_gpu.prev_dsp.DisplayModeNew.y = 0;
+//
+// // eon
+//
+// if (g_gpu.prev_dsp.DisplayModeNew.y != iOldYOffset) // if old offset!=new offset: recalc height
+// {
+// g_gpu.dsp.Height = g_gpu.dsp.range.y1 - g_gpu.dsp.range.y0
+// + g_gpu.prev_dsp.DisplayModeNew.y;
+// g_gpu.dsp.DisplayModeNew.y = g_gpu.dsp.Height * g_gpu.dsp.Double;
+// }
+//
+// //
+//
+// if (g_gpu.dsp.PAL)
+// iT = 48;
+// else
+// iT = 28;
+//
+// if (g_gpu.dsp.range.y0 >= iT) {
+// g_gpu.prev_dsp.range.y0 = (short) ((g_gpu.dsp.range.y0 - iT - 4)
+// * g_gpu.dsp.Double);
+// if (g_gpu.prev_dsp.range.y0 < 0)
+// g_gpu.prev_dsp.range.y0 = 0;
+// g_gpu.dsp.DisplayModeNew.y += g_gpu.prev_dsp.range.y0;
+// } else
+// g_gpu.prev_dsp.range.y0 = 0;
+//
+// if (iO != g_gpu.prev_dsp.range.y0) {
+// DoClearScreenBuffer();
+// }
+//}
+
+////////////////////////////////////////////////////////////////////////
+// check if update needed
+////////////////////////////////////////////////////////////////////////
+
+
+////////////////////////////////////////////////////////////////////////
+
+// TOGGLE FULLSCREEN - WINDOW DISABLED
+//void ChangeWindowMode(void) {
+// extern Display *display;
+// extern Window window;
+// extern int root_window_id;
+// Screen *screen;
+// XSizeHints hints;
+// MotifWmHints mwmhints;
+// Atom mwmatom;
+//
+// screen = DefaultScreenOfDisplay(display);
+// iWindowMode = !iWindowMode;
+//
+// if (!iWindowMode) // fullscreen
+// {
+// mwmhints.flags = MWM_HINTS_DECORATIONS;
+// mwmhints.functions = 0;
+// mwmhints.decorations = 0;
+// mwmhints.input_mode = 0;
+// mwmatom = XInternAtom(display, "_MOTIF_WM_HINTS", 0);
+// XChangeProperty(display, window, mwmatom, mwmatom, 32, PropModeReplace,
+// (unsigned char *) &mwmhints, 5);
+//
+// XResizeWindow(display, window, screen->width, screen->height);
+//
+// hints.min_width = hints.max_width = hints.base_width = screen->width;
+// hints.min_height = hints.max_height = hints.base_height
+// = screen->height;
+//
+// XSetWMNormalHints(display, window, &hints);
+//
+// {
+// XEvent xev;
+//
+// memset(&xev, 0, sizeof(xev));
+// xev.xclient.type = ClientMessage;
+// xev.xclient.serial = 0;
+// xev.xclient.send_event = 1;
+// xev.xclient.message_type = XInternAtom(display, "_NET_WM_STATE", 0);
+// xev.xclient.window = window;
+// xev.xclient.format = 32;
+// xev.xclient.data.l[0] = 1;
+// xev.xclient.data.l[1] = XInternAtom(display,
+// "_NET_WM_STATE_FULLSCREEN", 0);
+// xev.xclient.data.l[2] = 0;
+// xev.xclient.data.l[3] = 0;
+// xev.xclient.data.l[4] = 0;
+//
+// XSendEvent(display, root_window_id, 0, SubstructureRedirectMask
+// | SubstructureNotifyMask, &xev);
+// }
+// } else {
+// {
+// XEvent xev;
+//
+// memset(&xev, 0, sizeof(xev));
+// xev.xclient.type = ClientMessage;
+// xev.xclient.serial = 0;
+// xev.xclient.send_event = 1;
+// xev.xclient.message_type = XInternAtom(display, "_NET_WM_STATE", 0);
+// xev.xclient.window = window;
+// xev.xclient.format = 32;
+// xev.xclient.data.l[0] = 0;
+// xev.xclient.data.l[1] = XInternAtom(display,
+// "_NET_WM_STATE_FULLSCREEN", 0);
+// xev.xclient.data.l[2] = 0;
+// xev.xclient.data.l[3] = 0;
+// xev.xclient.data.l[4] = 0;
+//
+// XSendEvent(display, root_window_id, 0, SubstructureRedirectMask
+// | SubstructureNotifyMask, &xev);
+// }
+//
+// mwmhints.flags = MWM_HINTS_DECORATIONS;
+// mwmhints.functions = 0;
+// mwmhints.decorations = 1;
+// mwmhints.input_mode = 0;
+// mwmatom = XInternAtom(display, "_MOTIF_WM_HINTS", 0);
+//
+// //This shouldn't work on 64 bit longs, but it does...in fact, it breaks when I change all the mwmhints to int.
+// //I don't pretend to understand it.
+// XChangeProperty(display, window, mwmatom, mwmatom, 32, PropModeReplace,
+// (unsigned char *) &mwmhints, 5);
+//
+// hints.flags = USPosition | USSize;
+// hints.base_width = iResX;
+// hints.base_height = iResY;
+// XSetWMNormalHints(display, window, &hints);
+//
+// XResizeWindow(display, window, iResX, iResY);
+// }
+//
+// DoClearScreenBuffer();
+//
+// bChangeWinMode = 0;
+// bDoVSyncUpdate = 1;
+//}
+
+////////////////////////////////////////////////////////////////////////
+// gun cursor func: player=0-7, x=0-511, y=0-255
+////////////////////////////////////////////////////////////////////////
+
+/* disabled */
+void CALLBACK GPUcursor(int iPlayer, int x, int y) {
+ // if (iPlayer < 0)
+ // return;
+ // if (iPlayer > 7)
+ // return;
+ //
+ // usCursorActive |= (1 << iPlayer);
+ //
+ // if (x < 0)
+ // x = 0;
+ // if (x > 511)
+ // x = 511;
+ // if (y < 0)
+ // y = 0;
+ // if (y > 255)
+ // y = 255;
+ //
+ // ptCursorPoint[iPlayer].x = x;
+ // ptCursorPoint[iPlayer].y = y;
+}
+
+////////////////////////////////////////////////////////////////////////
+// update lace is called evry VSync
+////////////////////////////////////////////////////////////////////////
+
+void CALLBACK GPUupdateLace(void) // VSYNC
+{
+
+ g_gpu.status_reg ^= STATUS_ODDLINES;
+
+ if (g_gpu.status_reg & STATUS_DISPLAYDISABLED) {
+ do_clear_screen_buffer();
+ return;
+ }
+
+ /* I do not roughly emulate interlace, I just draw 1/2 frame
+ * to save CPU, and improve render */
+ if (!(g_gpu.status_reg & STATUS_INTERLACED) || (g_gpu.status_reg
+ & STATUS_ODDLINES))
+ do_buffer_swap();
+
+ frame_cap(g_gpu.fps);
+}
+
+////////////////////////////////////////////////////////////////////////
+// process read request from GPU status register
+////////////////////////////////////////////////////////////////////////
+
+
+uint32_t CALLBACK GPUreadStatus(void) // READ STATUS
+{
+ return g_gpu.status_reg;
+}
+
+////////////////////////////////////////////////////////////////////////
+// processes data send to GPU status register
+// these are always single packet commands.
+////////////////////////////////////////////////////////////////////////
+
+void CALLBACK GPUwriteStatus(uint32_t gdata) {
+ uint32_t lCommand = (gdata >> 24) & 0xff;
+ g_gpu.ulStatusControl[lCommand] = gdata; // store command for freezing
+ switch (lCommand) {
+ case 0x00:
+ /* reset GPU */
+ memset(g_gpu.lGPUInfoVals, 0x00, 16 * sizeof(uint32_t));
+ /* STATUS_READYFORCOMMANDS | STATUS_IDLE | STATUS_DISPLAYDISABLED | UNKNOW13 */
+ g_gpu.status_reg = 0x14802000;
+ g_gpu.DataWriteMode = DR_NORMAL;
+ g_gpu.DataReadMode = DR_NORMAL;
+ g_prim.drawX = 0;
+ g_prim.drawY = 0;
+ g_prim.drawW = 0;
+ g_prim.drawH = 0;
+ g_draw.sSetMask = 0;
+ g_draw.lSetMask = 0;
+ g_draw.bCheckMask = 0;
+ g_prim.usMirror = 0;
+ g_soft.GlobalTextAddrX = 0;
+ g_soft.GlobalTextAddrY = 0;
+ g_soft.GlobalTextTP = 0;
+ g_soft.GlobalTextABR = 0;
+ g_prim.bUsingTWin = 0;
+ return;
+ case 0x01:
+ /* reset command buffer */
+ //fprintf(stderr, "Reset command buffer not implemented\n");
+ return;
+ case 0x02:
+ /* reset IRQ */
+ //fprintf(stderr, "Reset IRQ not implemented\n");
+ return;
+ case 0x03:
+ /* Enable or disable the display */
+ if (gdata & 0x01)
+ g_gpu.status_reg |= STATUS_DISPLAYDISABLED;
+ else
+ g_gpu.status_reg &= ~STATUS_DISPLAYDISABLED;
+ return;
+ case 0x04:
+ /* Set the transfering mode */
+ gdata &= 0x03; // Only want the lower two bits
+ g_gpu.DataWriteMode = DR_NORMAL;
+ g_gpu.DataReadMode = DR_NORMAL;
+ if (gdata == 0x02)
+ g_gpu.DataWriteMode = DR_VRAMTRANSFER;
+ if (gdata == 0x03)
+ g_gpu.DataReadMode = DR_VRAMTRANSFER;
+ g_gpu.status_reg &= ~STATUS_DMABITS; // Clear the current settings of the DMA bits
+ g_gpu.status_reg |= (gdata << 29); // Set the DMA bits according to the received data
+ return;
+ case 0x05:
+ /* setting display position */
+ g_gpu.dsp.position.y = (short) ((gdata >> 10) & 0x1ff);
+ g_gpu.dsp.position.x = (short) (gdata & 0x3ff);
+ //fprintf(stderr, "Update display position X=%d,Y=%d\n",
+ // g_gpu.dsp.position.x, g_gpu.dsp.position.y);
+ return;
+ case 0x06:
+ /* Set width */
+ g_gpu.dsp.range.x0 = (short) (gdata & 0x03ff);
+ g_gpu.dsp.range.x1 = (short) ((gdata >> 12) & 0x0fff);
+ //fprintf(stderr, "Setrange x0 : %d, x1 : %d\n", g_gpu.dsp.range.x0,
+ // g_gpu.dsp.range.x1);
+ return;
+ case 0x07:
+ /* Set height */
+ g_gpu.dsp.range.y0 = (short) (gdata & 0x3ff);
+ g_gpu.dsp.range.y1 = (short) ((gdata >> 10) & 0x3ff);
+ //fprintf(stderr, "Setrange y0 : %d, y1 : %d\n", g_gpu.dsp.range.y0,
+ // g_gpu.dsp.range.y1);
+ return;
+ case 0x08:
+ /* setting display infos */
+ //fprintf(stderr, "command %x\n", gdata&0x000043);
+ switch (gdata & 0x000043) {
+ case 0x00:
+ g_gpu.dsp.mode.x = 10;
+ break;
+ case 0x01:
+ g_gpu.dsp.mode.x = 8;
+ break;
+ case 0x02:
+ g_gpu.dsp.mode.x = 5;
+ break;
+ case 0x03:
+ g_gpu.dsp.mode.x = 4;
+ break;
+ case 0x40:
+ g_gpu.dsp.mode.x = 7;
+ break;
+ default:
+ g_gpu.dsp.mode.x = 0;
+ }
+
+ /* clear width status */
+ g_gpu.status_reg &= ~STATUS_WIDTHBITS;
+ /* update status reg */
+ g_gpu.status_reg |= ((gdata & 0x00000003) << 17)
+ | ((gdata & 0x00000040) << 10);
+
+ switch (gdata & 0x000004) {
+ case 0x00:
+ g_gpu.status_reg &= ~STATUS_DOUBLEHEIGHT;
+ g_gpu.dsp.mode.y = 1;
+ break;
+ case 0x04:
+ g_gpu.status_reg |= STATUS_DOUBLEHEIGHT;
+ g_gpu.dsp.mode.y = 2;
+ break;
+ }
+
+ switch (gdata & 0x08) {
+ case 0x00:
+ g_gpu.status_reg &= ~STATUS_PAL;
+ g_gpu.fps = 60;
+ break;
+ case 0x08:
+ g_gpu.status_reg |= STATUS_PAL;
+ g_gpu.fps = 50;
+ break;
+ }
+ //fprintf(stderr, "video mode %dx%d\n", g_gpu.dsp.mode.x, g_gpu.dsp.mode.y);
+
+ if ((gdata & 0x10)) {
+ g_gpu.status_reg |= STATUS_RGB24;
+ } else {
+ g_gpu.status_reg &= ~STATUS_RGB24;
+ }
+
+ if ((gdata & 0x20)) {
+ g_gpu.status_reg |= STATUS_INTERLACED;
+ } else {
+ g_gpu.status_reg &= ~STATUS_INTERLACED;
+ }
+ return;
+ case 0x10:
+ /* ask about GPU version and other stuff */
+ gdata &= 0xff;
+ switch (gdata) {
+ case 0x02:
+ g_gpu.lGPUdataRet = g_gpu.lGPUInfoVals[INFO_TW]; // tw infos
+ return;
+ case 0x03:
+ g_gpu.lGPUdataRet = g_gpu.lGPUInfoVals[INFO_DRAWSTART]; // draw start
+ return;
+ case 0x04:
+ g_gpu.lGPUdataRet = g_gpu.lGPUInfoVals[INFO_DRAWEND]; // draw end
+ return;
+ case 0x05:
+ case 0x06:
+ g_gpu.lGPUdataRet = g_gpu.lGPUInfoVals[INFO_DRAWOFF]; // draw offset
+ return;
+ case 0x07:
+ if (0)
+ g_gpu.lGPUdataRet = 0x01;
+ else
+ g_gpu.lGPUdataRet = 0x02; // gpu type
+ return;
+ case 0x08:
+ case 0x0F: // some bios addr?
+ g_gpu.lGPUdataRet = 0xBFC03720;
+ return;
+ }
+ return;
+ default:
+ fprintf(stderr, "Unknow command %02x\n", lCommand);
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+// vram read/write helpers, needed by LEWPY's optimized vram read/write :)
+////////////////////////////////////////////////////////////////////////
+
+inline void FinishedVRAMWrite(void) {
+ // Set register to NORMAL operation
+ g_gpu.DataWriteMode = DR_NORMAL;
+ // Reset transfer values, to prevent mis-transfer of data
+ g_gpu.VRAMWrite.x = 0;
+ g_gpu.VRAMWrite.y = 0;
+ g_gpu.VRAMWrite.Width = 0;
+ g_gpu.VRAMWrite.Height = 0;
+ g_gpu.VRAMWrite.ColsRemaining = 0;
+ g_gpu.VRAMWrite.RowsRemaining = 0;
+}
+
+inline void FinishedVRAMRead(void) {
+ // Set register to NORMAL operation
+ g_gpu.DataReadMode = DR_NORMAL;
+ // Reset transfer values, to prevent mis-transfer of data
+ g_gpu.VRAMRead.x = 0;
+ g_gpu.VRAMRead.y = 0;
+ g_gpu.VRAMRead.Width = 0;
+ g_gpu.VRAMRead.Height = 0;
+ g_gpu.VRAMRead.ColsRemaining = 0;
+ g_gpu.VRAMRead.RowsRemaining = 0;
+
+ // Indicate GPU is no longer ready for VRAM data in the STATUS REGISTER
+ g_gpu.status_reg &= ~STATUS_READYFORVRAM;
+}
+
+////////////////////////////////////////////////////////////////////////
+// core read from vram
+////////////////////////////////////////////////////////////////////////
+
+void CALLBACK GPUreadDataMem(uint32_t * pMem, int iSize) {
+ int i;
+
+ if (g_gpu.DataReadMode != DR_VRAMTRANSFER)
+ return;
+
+ g_gpu.status_reg &= ~STATUS_IDLE;
+
+ // adjust read ptr, if necessary
+
+ while (g_gpu.VRAMRead.ImagePtr >= g_gpu.psxVuw_eom.u16)
+ g_gpu.VRAMRead.ImagePtr -= 512 * 1024;
+ while (g_gpu.VRAMRead.ImagePtr < g_gpu.psx_vram.u16)
+ g_gpu.VRAMRead.ImagePtr += 512 * 1024;
+
+ for (i = 0; i < iSize; i++) {
+ // do 2 seperate 16bit reads for compatibility (wrap issues)
+ if ((g_gpu.VRAMRead.ColsRemaining > 0) && (g_gpu.VRAMRead.RowsRemaining
+ > 0)) {
+ // lower 16 bit
+ g_gpu.lGPUdataRet = (uint32_t) GETLE16(g_gpu.VRAMRead.ImagePtr);
+
+ g_gpu.VRAMRead.ImagePtr++;
+ if (g_gpu.VRAMRead.ImagePtr >= g_gpu.psxVuw_eom.u16)
+ g_gpu.VRAMRead.ImagePtr -= 512 * 1024;
+ g_gpu.VRAMRead.RowsRemaining--;
+
+ if (g_gpu.VRAMRead.RowsRemaining <= 0) {
+ g_gpu.VRAMRead.RowsRemaining = g_gpu.VRAMRead.Width;
+ g_gpu.VRAMRead.ColsRemaining--;
+ g_gpu.VRAMRead.ImagePtr += 1024 - g_gpu.VRAMRead.Width;
+ if (g_gpu.VRAMRead.ImagePtr >= g_gpu.psxVuw_eom.u16)
+ g_gpu.VRAMRead.ImagePtr -= 512 * 1024;
+ }
+
+ // higher 16 bit (always, even if it's an odd width)
+ g_gpu.lGPUdataRet |= (uint32_t) GETLE16(g_gpu.VRAMRead.ImagePtr)
+ << 16;
+ PUTLE32(pMem, g_gpu.lGPUdataRet);
+ pMem++;
+
+ if (g_gpu.VRAMRead.ColsRemaining <= 0) {
+ FinishedVRAMRead();
+ goto ENDREAD;
+ }
+
+ g_gpu.VRAMRead.ImagePtr++;
+ if (g_gpu.VRAMRead.ImagePtr >= g_gpu.psxVuw_eom.u16)
+ g_gpu.VRAMRead.ImagePtr -= 512 * 1024;
+ g_gpu.VRAMRead.RowsRemaining--;
+ if (g_gpu.VRAMRead.RowsRemaining <= 0) {
+ g_gpu.VRAMRead.RowsRemaining = g_gpu.VRAMRead.Width;
+ g_gpu.VRAMRead.ColsRemaining--;
+ g_gpu.VRAMRead.ImagePtr += 1024 - g_gpu.VRAMRead.Width;
+ if (g_gpu.VRAMRead.ImagePtr >= g_gpu.psxVuw_eom.u16)
+ g_gpu.VRAMRead.ImagePtr -= 512 * 1024;
+ }
+ if (g_gpu.VRAMRead.ColsRemaining <= 0) {
+ FinishedVRAMRead();
+ goto ENDREAD;
+ }
+ } else {
+ FinishedVRAMRead();
+ goto ENDREAD;
+ }
+ }
+
+ ENDREAD: g_gpu.status_reg |= STATUS_IDLE;
+}
+
+////////////////////////////////////////////////////////////////////////
+
+uint32_t CALLBACK GPUreadData(void) {
+ uint32_t l;
+ GPUreadDataMem(&l, 1);
+ return g_gpu.lGPUdataRet;
+}
+
+////////////////////////////////////////////////////////////////////////
+// processes data send to GPU data register
+// extra table entries for fixing polyline troubles
+////////////////////////////////////////////////////////////////////////
+
+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;
+
+ g_gpu.status_reg &= ~STATUS_IDLE;
+ g_gpu.status_reg &= ~STATUS_READYFORCOMMANDS;
+
+ STARTVRAM:
+
+ if (g_gpu.DataWriteMode == DR_VRAMTRANSFER) {
+ char bFinished = 0;
+
+ // make sure we are in vram
+ while (g_gpu.VRAMWrite.ImagePtr >= g_gpu.psxVuw_eom.u16)
+ g_gpu.VRAMWrite.ImagePtr -= 512 * 1024;
+ while (g_gpu.VRAMWrite.ImagePtr < g_gpu.psx_vram.u16)
+ g_gpu.VRAMWrite.ImagePtr += 512 * 1024;
+
+ // now do the loop
+ while (g_gpu.VRAMWrite.ColsRemaining > 0) {
+ while (g_gpu.VRAMWrite.RowsRemaining > 0) {
+ if (i >= iSize) {
+ goto ENDVRAM;
+ }
+ i++;
+
+ gdata = GETLE32(pMem);
+ pMem++;
+
+ PUTLE16(g_gpu.VRAMWrite.ImagePtr, (unsigned short)gdata);
+ g_gpu.VRAMWrite.ImagePtr++;
+ if (g_gpu.VRAMWrite.ImagePtr >= g_gpu.psxVuw_eom.u16)
+ g_gpu.VRAMWrite.ImagePtr -= 512 * 1024;
+ g_gpu.VRAMWrite.RowsRemaining--;
+
+ if (g_gpu.VRAMWrite.RowsRemaining <= 0) {
+ g_gpu.VRAMWrite.ColsRemaining--;
+ if (g_gpu.VRAMWrite.ColsRemaining <= 0) // last pixel is odd width
+ {
+ gdata
+ = (gdata & 0xFFFF)
+ | (((uint32_t) GETLE16(g_gpu.VRAMWrite.ImagePtr))
+ << 16);
+ FinishedVRAMWrite();
+ goto ENDVRAM;
+ }
+ g_gpu.VRAMWrite.RowsRemaining = g_gpu.VRAMWrite.Width;
+ g_gpu.VRAMWrite.ImagePtr += 1024 - g_gpu.VRAMWrite.Width;
+ }
+
+ PUTLE16(g_gpu.VRAMWrite.ImagePtr, (unsigned short)(gdata>>16));
+ g_gpu.VRAMWrite.ImagePtr++;
+ if (g_gpu.VRAMWrite.ImagePtr >= g_gpu.psxVuw_eom.u16)
+ g_gpu.VRAMWrite.ImagePtr -= 512 * 1024;
+ g_gpu.VRAMWrite.RowsRemaining--;
+ }
+
+ g_gpu.VRAMWrite.RowsRemaining = g_gpu.VRAMWrite.Width;
+ g_gpu.VRAMWrite.ColsRemaining--;
+ g_gpu.VRAMWrite.ImagePtr += 1024 - g_gpu.VRAMWrite.Width;
+ bFinished = 1;
+ }
+
+ FinishedVRAMWrite();
+ }
+
+ ENDVRAM:
+
+ if (g_gpu.DataWriteMode == DR_NORMAL) {
+ void (* *primFunc)(unsigned char *);
+ primFunc = primTableJ;
+
+ for (; i < iSize;) {
+ if (g_gpu.DataWriteMode == DR_VRAMTRANSFER)
+ goto STARTVRAM;
+
+ gdata = GETLE32(pMem);
+ pMem++;
+ i++;
+
+ if (g_gpu.gpuDataC == 0) {
+ command = (unsigned char) ((gdata >> 24) & 0xff);
+
+ //if(command>=0xb0 && command<0xc0) auxprintf("b0 %x!!!!!!!!!\n",command);
+
+ if (primTableCX[command]) {
+ g_gpu.gpuDataC = primTableCX[command];
+ g_gpu.gpuCommand = command;
+ PUTLE32(&g_gpu.gpuDataM[0], gdata);
+ g_gpu.gpuDataP = 1;
+ } else {
+ //fprintf(stderr, "unknow command %02x \n", command);
+ continue;
+ }
+ } else {
+ PUTLE32(&g_gpu.gpuDataM[g_gpu.gpuDataP], gdata);
+ if (g_gpu.gpuDataC > 128) {
+ if ((g_gpu.gpuDataC == 254 && g_gpu.gpuDataP >= 3)
+ || (g_gpu.gpuDataC == 255 && g_gpu.gpuDataP >= 4
+ && !(g_gpu.gpuDataP & 1))) {
+ if ((g_gpu.gpuDataM[g_gpu.gpuDataP] & 0xF000F000)
+ == 0x50005000)
+ g_gpu.gpuDataP = g_gpu.gpuDataC - 1;
+ }
+ }
+ g_gpu.gpuDataP++;
+ }
+
+ if (g_gpu.gpuDataP == g_gpu.gpuDataC) {
+ g_gpu.gpuDataC = g_gpu.gpuDataP = 0;
+ primFunc[g_gpu.gpuCommand]((unsigned char *) g_gpu.gpuDataM);
+ }
+ }
+ }
+
+ g_gpu.lGPUdataRet = gdata;
+
+ g_gpu.status_reg |= STATUS_READYFORCOMMANDS;
+ g_gpu.status_reg |= STATUS_IDLE;
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void CALLBACK GPUwriteData(uint32_t gdata) {
+ PUTLE32(&gdata, gdata);
+ GPUwriteDataMem(&gdata, 1);
+}
+
+////////////////////////////////////////////////////////////////////////
+// this functions will be removed soon (or 'soonish')... not really needed, but some emus want them
+////////////////////////////////////////////////////////////////////////
+
+void CALLBACK GPUsetMode(unsigned long gdata) {
+ // Peops does nothing here...
+ // DataWriteMode=(gdata&1)?DR_VRAMTRANSFER:DR_NORMAL;
+ // DataReadMode =(gdata&2)?DR_VRAMTRANSFER:DR_NORMAL;
+}
+
+long CALLBACK GPUgetMode(void) {
+ long iT = 0;
+
+ if (g_gpu.DataWriteMode == DR_VRAMTRANSFER)
+ iT |= 0x1;
+ if (g_gpu.DataReadMode == DR_VRAMTRANSFER)
+ iT |= 0x2;
+ return iT;
+}
+
+////////////////////////////////////////////////////////////////////////
+// call config dlg
+////////////////////////////////////////////////////////////////////////
+
+long CALLBACK GPUconfigure(void) {
+ SoftDlgProc();
+ return 0;
+}
+
+////////////////////////////////////////////////////////////////////////
+// sets all kind of act fixes
+////////////////////////////////////////////////////////////////////////
+
+void SetFixes(void) {
+
+}
+
+////////////////////////////////////////////////////////////////////////
+// process gpu commands
+////////////////////////////////////////////////////////////////////////
+
+unsigned long lUsedAddr[3];
+
+inline char CheckForEndlessLoop(unsigned long 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 CALLBACK GPUdmaChain(uint32_t * baseAddrL, uint32_t addr) {
+ uint32_t dmaMem;
+ unsigned char * baseAddrB;
+ short count;
+ unsigned int DMACommandCounter = 0;
+
+ g_gpu.status_reg &= ~STATUS_IDLE;
+
+ lUsedAddr[0] = lUsedAddr[1] = lUsedAddr[2] = 0xffffff;
+
+ baseAddrB = (unsigned char*) baseAddrL;
+
+ do {
+ if (1)
+ addr &= 0x1FFFFC;
+ if (DMACommandCounter++ > 2000000)
+ break;
+ if (CheckForEndlessLoop(addr))
+ break;
+
+ count = baseAddrB[addr + 3];
+
+ dmaMem = addr + 4;
+
+ if (count > 0)
+ GPUwriteDataMem(&baseAddrL[dmaMem >> 2], count);
+
+ addr = GETLE32(&baseAddrL[addr>>2]) & 0xffffff;
+ } while (addr != 0xffffff);
+
+ g_gpu.status_reg |= STATUS_IDLE;
+ return 0;
+}
+
+////////////////////////////////////////////////////////////////////////
+// show about dlg
+////////////////////////////////////////////////////////////////////////
+
+
+void CALLBACK GPUabout(void) // ABOUT
+{
+ AboutDlgProc();
+ return;
+}
+
+////////////////////////////////////////////////////////////////////////
+// We are ever fine ;)
+////////////////////////////////////////////////////////////////////////
+
+long CALLBACK GPUtest(void) {
+ // if test fails this function should return negative value for error (unable to continue)
+ // and positive value for warning (can continue but output might be crappy)
+ return 0;
+}
+
+////////////////////////////////////////////////////////////////////////
+// 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;
+ //g_gpu.lSelectedSlot = lSlotNum + 1;
+ //BuildDispMenu(0);
+ return 1;
+ }
+ //----------------------------------------------------//
+ if (!pF)
+ return 0; // some checks
+ if (pF->ulFreezeVersion != 1)
+ return 0;
+
+ if (ulGetFreezeData == 1) // 1: get data
+ {
+ pF->ulStatus = g_gpu.status_reg;
+ memcpy(pF->ulControl, g_gpu.ulStatusControl, 256 * sizeof(uint32_t));
+ memcpy(pF->psxVRam, g_gpu.psx_vram.u8, 1024 * 512 * 2);
+
+ return 1;
+ }
+
+ if (ulGetFreezeData != 0)
+ return 0; // 0: set data
+
+ g_gpu.status_reg = pF->ulStatus;
+ memcpy(g_gpu.ulStatusControl, pF->ulControl, 256 * sizeof(uint32_t));
+ memcpy(g_gpu.psx_vram.u8, pF->psxVRam, 1024 * 512 * 2);
+
+ // RESET TEXTURE STORE HERE, IF YOU USE SOMETHING LIKE THAT
+
+ GPUwriteStatus(g_gpu.ulStatusControl[0]);
+ GPUwriteStatus(g_gpu.ulStatusControl[1]);
+ GPUwriteStatus(g_gpu.ulStatusControl[2]);
+ GPUwriteStatus(g_gpu.ulStatusControl[3]);
+ GPUwriteStatus(g_gpu.ulStatusControl[8]); // try to repair things
+ GPUwriteStatus(g_gpu.ulStatusControl[6]);
+ GPUwriteStatus(g_gpu.ulStatusControl[7]);
+ GPUwriteStatus(g_gpu.ulStatusControl[5]);
+ GPUwriteStatus(g_gpu.ulStatusControl[4]);
+
+ return 1;
+}
+
+////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+// SAVE STATE DISPLAY STUFF
+////////////////////////////////////////////////////////////////////////
+
+// font 0-9, 24x20 pixels, 1 byte = 4 dots
+// 00 = black
+// 01 = white
+// 10 = red
+// 11 = transparent
+
+unsigned char cFont[10][120] = {
+// 0
+ { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x80, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x00, 0x05, 0x54, 0x00, 0x00, 0x80, 0x00, 0x14, 0x05, 0x00,
+ 0x00, 0x80, 0x00, 0x14, 0x05, 0x00, 0x00, 0x80, 0x00, 0x14,
+ 0x05, 0x00, 0x00, 0x80, 0x00, 0x14, 0x05, 0x00, 0x00, 0x80,
+ 0x00, 0x14, 0x05, 0x00, 0x00, 0x80, 0x00, 0x14, 0x05, 0x00,
+ 0x00, 0x80, 0x00, 0x14, 0x05, 0x00, 0x00, 0x80, 0x00, 0x14,
+ 0x05, 0x00, 0x00, 0x80, 0x00, 0x05, 0x54, 0x00, 0x00, 0x80,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa },
+ // 1
+ { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x80, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x00, 0x00, 0x50, 0x00, 0x00, 0x80, 0x00, 0x05, 0x50, 0x00,
+ 0x00, 0x80, 0x00, 0x00, 0x50, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0x50, 0x00, 0x00, 0x80, 0x00, 0x00, 0x50, 0x00, 0x00, 0x80,
+ 0x00, 0x00, 0x50, 0x00, 0x00, 0x80, 0x00, 0x00, 0x50, 0x00,
+ 0x00, 0x80, 0x00, 0x00, 0x50, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0x50, 0x00, 0x00, 0x80, 0x00, 0x05, 0x55, 0x00, 0x00, 0x80,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa },
+ // 2
+ { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x80, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x00, 0x05, 0x54, 0x00, 0x00, 0x80, 0x00, 0x14, 0x05, 0x00,
+ 0x00, 0x80, 0x00, 0x00, 0x05, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0x05, 0x00, 0x00, 0x80, 0x00, 0x00, 0x14, 0x00, 0x00, 0x80,
+ 0x00, 0x00, 0x50, 0x00, 0x00, 0x80, 0x00, 0x01, 0x40, 0x00,
+ 0x00, 0x80, 0x00, 0x05, 0x00, 0x00, 0x00, 0x80, 0x00, 0x14,
+ 0x00, 0x00, 0x00, 0x80, 0x00, 0x15, 0x55, 0x00, 0x00, 0x80,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa },
+ // 3
+ { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x80, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x00, 0x05, 0x54, 0x00, 0x00, 0x80, 0x00, 0x14, 0x05, 0x00,
+ 0x00, 0x80, 0x00, 0x00, 0x05, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0x05, 0x00, 0x00, 0x80, 0x00, 0x01, 0x54, 0x00, 0x00, 0x80,
+ 0x00, 0x00, 0x05, 0x00, 0x00, 0x80, 0x00, 0x00, 0x05, 0x00,
+ 0x00, 0x80, 0x00, 0x00, 0x05, 0x00, 0x00, 0x80, 0x00, 0x14,
+ 0x05, 0x00, 0x00, 0x80, 0x00, 0x05, 0x54, 0x00, 0x00, 0x80,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa },
+ // 4
+ { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x80, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x00, 0x00, 0x14, 0x00, 0x00, 0x80, 0x00, 0x00, 0x54, 0x00,
+ 0x00, 0x80, 0x00, 0x01, 0x54, 0x00, 0x00, 0x80, 0x00, 0x01,
+ 0x54, 0x00, 0x00, 0x80, 0x00, 0x05, 0x14, 0x00, 0x00, 0x80,
+ 0x00, 0x14, 0x14, 0x00, 0x00, 0x80, 0x00, 0x15, 0x55, 0x00,
+ 0x00, 0x80, 0x00, 0x00, 0x14, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0x14, 0x00, 0x00, 0x80, 0x00, 0x00, 0x55, 0x00, 0x00, 0x80,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa },
+ // 5
+ { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x80, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x00, 0x15, 0x55, 0x00, 0x00, 0x80, 0x00, 0x14, 0x00, 0x00,
+ 0x00, 0x80, 0x00, 0x14, 0x00, 0x00, 0x00, 0x80, 0x00, 0x14,
+ 0x00, 0x00, 0x00, 0x80, 0x00, 0x15, 0x54, 0x00, 0x00, 0x80,
+ 0x00, 0x00, 0x05, 0x00, 0x00, 0x80, 0x00, 0x00, 0x05, 0x00,
+ 0x00, 0x80, 0x00, 0x00, 0x05, 0x00, 0x00, 0x80, 0x00, 0x14,
+ 0x05, 0x00, 0x00, 0x80, 0x00, 0x05, 0x54, 0x00, 0x00, 0x80,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa },
+ // 6
+ { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x80, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x00, 0x01, 0x54, 0x00, 0x00, 0x80, 0x00, 0x05, 0x00, 0x00,
+ 0x00, 0x80, 0x00, 0x14, 0x00, 0x00, 0x00, 0x80, 0x00, 0x14,
+ 0x00, 0x00, 0x00, 0x80, 0x00, 0x15, 0x54, 0x00, 0x00, 0x80,
+ 0x00, 0x15, 0x05, 0x00, 0x00, 0x80, 0x00, 0x14, 0x05, 0x00,
+ 0x00, 0x80, 0x00, 0x14, 0x05, 0x00, 0x00, 0x80, 0x00, 0x14,
+ 0x05, 0x00, 0x00, 0x80, 0x00, 0x05, 0x54, 0x00, 0x00, 0x80,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa },
+ // 7
+ { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x80, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x00, 0x15, 0x55, 0x00, 0x00, 0x80, 0x00, 0x14, 0x05, 0x00,
+ 0x00, 0x80, 0x00, 0x00, 0x14, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0x14, 0x00, 0x00, 0x80, 0x00, 0x00, 0x50, 0x00, 0x00, 0x80,
+ 0x00, 0x00, 0x50, 0x00, 0x00, 0x80, 0x00, 0x01, 0x40, 0x00,
+ 0x00, 0x80, 0x00, 0x01, 0x40, 0x00, 0x00, 0x80, 0x00, 0x05,
+ 0x00, 0x00, 0x00, 0x80, 0x00, 0x05, 0x00, 0x00, 0x00, 0x80,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa },
+ // 8
+ { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x80, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x00, 0x05, 0x54, 0x00, 0x00, 0x80, 0x00, 0x14, 0x05, 0x00,
+ 0x00, 0x80, 0x00, 0x14, 0x05, 0x00, 0x00, 0x80, 0x00, 0x14,
+ 0x05, 0x00, 0x00, 0x80, 0x00, 0x05, 0x54, 0x00, 0x00, 0x80,
+ 0x00, 0x14, 0x05, 0x00, 0x00, 0x80, 0x00, 0x14, 0x05, 0x00,
+ 0x00, 0x80, 0x00, 0x14, 0x05, 0x00, 0x00, 0x80, 0x00, 0x14,
+ 0x05, 0x00, 0x00, 0x80, 0x00, 0x05, 0x54, 0x00, 0x00, 0x80,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa },
+ // 9
+ { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x80, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x00, 0x05, 0x54, 0x00, 0x00, 0x80, 0x00, 0x14, 0x05, 0x00,
+ 0x00, 0x80, 0x00, 0x14, 0x05, 0x00, 0x00, 0x80, 0x00, 0x14,
+ 0x05, 0x00, 0x00, 0x80, 0x00, 0x14, 0x15, 0x00, 0x00, 0x80,
+ 0x00, 0x05, 0x55, 0x00, 0x00, 0x80, 0x00, 0x00, 0x05, 0x00,
+ 0x00, 0x80, 0x00, 0x00, 0x05, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0x14, 0x00, 0x00, 0x80, 0x00, 0x05, 0x50, 0x00, 0x00, 0x80,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa } };
+
+////////////////////////////////////////////////////////////////////////
+
+void PaintPicDot(unsigned char * p, unsigned char c) {
+
+ if (c == 0) {
+ *p++ = 0x00;
+ *p++ = 0x00;
+ *p = 0x00;
+ return;
+ } // black
+ if (c == 1) {
+ *p++ = 0xff;
+ *p++ = 0xff;
+ *p = 0xff;
+ return;
+ } // white
+ if (c == 2) {
+ *p++ = 0x00;
+ *p++ = 0x00;
+ *p = 0xff;
+ return;
+ } // red
+ // transparent
+}
+
+////////////////////////////////////////////////////////////////////////
+// the main emu allocs 128x96x3 bytes, and passes a ptr
+// to it in pMem... the plugin has to fill it with
+// 8-8-8 bit BGR screen data (Win 24 bit BMP format
+// without header).
+// Beware: the func can be called at any time,
+// so you have to use the frontbuffer to get a fully
+// rendered picture
+// LINUX version:
+
+//extern char * Xpixels;
+
+void GPUgetScreenPic(unsigned char * pMem) {
+ /*
+ unsigned short c;unsigned char * pf;int x,y;
+
+ float XS=(float)iResX/128;
+ float YS=(float)iResY/96;
+
+ pf=pMem;
+ memset(pMem, 0, 128*96*3);
+
+ if(Xpixels)
+ {
+ unsigned char * ps=(unsigned char *)Xpixels;
+ {
+ long lPitch=iResX<<2;
+ uint32_t sx;
+
+ for(y=0;y<96;y++)
+ {
+ for(x=0;x<128;x++)
+ {
+ sx=*((uint32_t *)((ps)+
+ (((int)((float)y*YS))*lPitch)+
+ ((int)((float)x*XS))*4));
+ *(pf+0)=(sx&0xff);
+ *(pf+1)=(sx&0xff00)>>8;
+ *(pf+2)=(sx&0xff0000)>>16;
+ pf+=3;
+ }
+ }
+ }
+ }
+
+
+ /////////////////////////////////////////////////////////////////////
+ // generic number/border painter
+
+ pf=pMem+(103*3); // offset to number rect
+
+ for(y=0;y<20;y++) // loop the number rect pixel
+ {
+ for(x=0;x<6;x++)
+ {
+ c=cFont[lSelectedSlot][x+y*6]; // get 4 char dot infos at once (number depends on selected slot)
+ PaintPicDot(pf,(c&0xc0)>>6);pf+=3; // paint the dots into the rect
+ PaintPicDot(pf,(c&0x30)>>4);pf+=3;
+ PaintPicDot(pf,(c&0x0c)>>2);pf+=3;
+ PaintPicDot(pf,(c&0x03)); pf+=3;
+ }
+ pf+=104*3; // next rect y line
+ }
+
+ pf=pMem; // ptr to first pos in 128x96 pic
+ for(x=0;x<128;x++) // loop top/bottom line
+ {
+ *(pf+(95*128*3))=0x00;*pf++=0x00;
+ *(pf+(95*128*3))=0x00;*pf++=0x00; // paint it red
+ *(pf+(95*128*3))=0xff;*pf++=0xff;
+ }
+ pf=pMem; // ptr to first pos
+ for(y=0;y<96;y++) // loop left/right line
+ {
+ *(pf+(127*3))=0x00;*pf++=0x00;
+ *(pf+(127*3))=0x00;*pf++=0x00; // paint it red
+ *(pf+(127*3))=0xff;*pf++=0xff;
+ pf+=127*3; // offset to next line
+ }
+ */
+}
+
+////////////////////////////////////////////////////////////////////////
+// func will be called with 128x96x3 BGR data.
+// the plugin has to store the data and display
+// it in the upper right corner.
+// If the func is called with a NULL ptr, you can
+// release your picture data and stop displaying
+// the screen pic
+
+void CALLBACK GPUshowScreenPic(unsigned char * pMem) {
+ DestroyPic(); // destroy old pic data
+ if (pMem == 0)
+ return; // done
+ CreatePic(pMem); // create new pic... don't free pMem or something like that... just read from it
+}
+
+void CALLBACK GPUsetfix(uint32_t dwFixBits) {
+ g_prim.dwEmuFixes = dwFixBits;
+}
+
+void CALLBACK GPUvBlank(int val) {
+ //fprintf(stderr, "Vblanc %d\n", val);
+ //if(val)
+ // g_gpu.status_reg |= STATUS_ODDLINES;
+ //else
+ // g_gpu.status_reg &= ~STATUS_ODDLINES;
+}
diff --git a/plugins/gxvideo/gpucfg/main.c b/plugins/gxvideo/gpucfg/main.c
index 326eb1d8..64691e56 100644
--- a/plugins/gxvideo/gpucfg/main.c
+++ b/plugins/gxvideo/gpucfg/main.c
@@ -1,347 +1,367 @@
-/*
- * Copyright (C) 2010 Benoit Gschwind
- *
- * 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 3 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., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#include <gtk/gtk.h>
-#include <glade/glade.h>
-
-#include "globals.h"
-#include "config.h"
-
-#ifdef ENABLE_NLS
-#include <libintl.h>
-#include <locale.h>
-#endif
-
-#include <unistd.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/stat.h>
-
-#define READBINARY "rb"
-#define WRITEBINARY "wb"
-#define CONFIG_FILENAME "dfxvideo.cfg"
-
-enum {
- VIDMODE_320x200 = 0,
- VIDMODE_640x480,
- VIDMODE_800x600,
- VIDMODE_1024x768,
- VIDMODE_1152x864,
- VIDMODE_1280x960,
- VIDMODE_1600x1200
-}; /* Video_modes */
-
-typedef struct {
- GtkWidget * config_window;
- GtkWidget * resolution_combobox;
- GtkWidget * dithering_combobox;
- GtkWidget * maintain_ratio_checkbutton;
- GtkWidget * fullscreen_checkbutton;
- GtkWidget * show_fps_checkbutton;
- GtkWidget * set_fps_checkbutton;
- GtkWidget * auto_fps_limit_checkbutton;
- GtkWidget * fps_entry;
- GtkWidget * use_game_fixes_checkbutton;
- GtkWidget * save_button;
- GtkWidget * cancel_button;
- GtkWidget * fixes_table;
- GtkWidget * fix_checkbutton[11];
-} cfg_window_t;
-
-void save_config(cfg_window_t *);
-
-static void on_about_clicked(GtkWidget * widget, gpointer user_data) {
- gtk_widget_destroy(widget);
- exit(0);
-}
-
-static void on_fullscreen_toggled(GtkWidget * widget, cfg_window_t * w) {
- gtk_widget_set_sensitive(w->resolution_combobox,
- !gtk_toggle_button_get_active(
- GTK_TOGGLE_BUTTON(w->fullscreen_checkbutton)));
-}
-
-static void update_fixes_stase(GtkWidget * ths, GtkWidget * w) {
- gtk_widget_set_sensitive(ths, gtk_toggle_button_get_active(
- GTK_TOGGLE_BUTTON(w)));
-}
-
-static void on_use_fixes_toggled(GtkWidget * widget, cfg_window_t * w) {
- /* Set the state of each of the fixes to the value of the use fixes toggle */
- gtk_container_foreach(GTK_CONTAINER (w->fixes_table),
- (GtkCallback) update_fixes_stase, w->use_game_fixes_checkbutton);
-}
-
-static void on_fps_toggled(GtkWidget * widget, cfg_window_t * w) {
- gboolean state_set_fps = gtk_toggle_button_get_active(
- GTK_TOGGLE_BUTTON(w->set_fps_checkbutton));
- gboolean state_auto_fps_limit = gtk_toggle_button_get_active(
- GTK_TOGGLE_BUTTON(w->auto_fps_limit_checkbutton));
- gtk_widget_set_sensitive(w->fps_entry, state_set_fps
- && !state_auto_fps_limit);
- gtk_widget_set_sensitive(w->auto_fps_limit_checkbutton, state_set_fps);
-}
-
-static void on_destroy_window(GtkWidget * widget, cfg_window_t * w) {
- free(w);
-}
-
-static void on_click_save_button(GtkWidget * widget, cfg_window_t * w) {
- save_config(w);
- gtk_widget_destroy(GTK_WIDGET(w->config_window));
- gtk_exit(0);
-}
-
-static void on_click_cancel_button(GtkWidget * widget, cfg_window_t * w) {
- gtk_widget_destroy(GTK_WIDGET(w->config_window));
- gtk_exit(0);
-}
-
-int main(int argc, char *argv[]) {
- cfg_window_t * w = 0;
- GtkWidget * widget;
- GtkBuilder * builder;
- int i, val;
- char tempstr[50];
-
-#ifdef ENABLE_NLS
- setlocale(LC_ALL, "");
- bindtextdomain(GETTEXT_PACKAGE, LOCALE_DIR);
- bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
- textdomain(GETTEXT_PACKAGE);
-#endif
-
- if (argc != 2) {
- printf("Usage: cfgGXVideo {ABOUT | CFG}\n");
- return 0;
- }
- if (strcmp(argv[1], "CFG") != 0 && strcmp(argv[1], "ABOUT") != 0) {
- printf("Usage: cfgGXVideo {ABOUT | CFG}\n");
- return 0;
- }
-
- gtk_set_locale();
- gtk_init(&argc, &argv);
-
- if (strcmp(argv[1], "ABOUT") == 0) {
- const char *authors[] = { "Pete Bernert and the P.E.Op.S. team",
- "Ryan Schultz", "Andrew Burton", NULL };
- widget = gtk_about_dialog_new();
- gtk_about_dialog_set_name(GTK_ABOUT_DIALOG (widget),
- "P.E.Op.S PCSX Video Plugin");
- gtk_about_dialog_set_version(GTK_ABOUT_DIALOG (widget), "1.17");
- gtk_about_dialog_set_authors(GTK_ABOUT_DIALOG (widget), authors);
- gtk_about_dialog_set_website(GTK_ABOUT_DIALOG (widget),
- "http://pcsx-df.sourceforge.net/");
-
- g_signal_connect_data(GTK_OBJECT(widget), "response",
- G_CALLBACK(on_about_clicked), NULL, NULL, G_CONNECT_AFTER);
-
- gtk_widget_show(widget);
- gtk_main();
-
- return 0;
- }
-
- builder = gtk_builder_new();
- if (!builder) {
- g_warning("We could not load the interface!");
- return -1;
- }
-
- gtk_builder_add_from_file(builder, DATADIR "gxvideo.glade", NULL);
- w = (cfg_window_t *) malloc(sizeof(cfg_window_t));
-#define CFG_GET_WIDGET(name) w->name = GTK_WIDGET(gtk_builder_get_object(builder, #name))
- CFG_GET_WIDGET(config_window);
- CFG_GET_WIDGET(config_window);
- CFG_GET_WIDGET(resolution_combobox);
- CFG_GET_WIDGET(dithering_combobox);
- CFG_GET_WIDGET(maintain_ratio_checkbutton);
- CFG_GET_WIDGET(fullscreen_checkbutton);
- CFG_GET_WIDGET(show_fps_checkbutton);
- CFG_GET_WIDGET(set_fps_checkbutton);
- CFG_GET_WIDGET(auto_fps_limit_checkbutton);
- CFG_GET_WIDGET(fps_entry);
- CFG_GET_WIDGET(use_game_fixes_checkbutton);
- CFG_GET_WIDGET(save_button);
- CFG_GET_WIDGET(cancel_button);
- CFG_GET_WIDGET(fixes_table);
-
- for (i = 0; i < 11; ++i) {
- sprintf(tempstr, "fix%d_checkbutton", i);
- w->fix_checkbutton[i]
- = GTK_WIDGET(gtk_builder_get_object(builder, tempstr));
- }
-
- ReadConfig();
-
- switch (g_cfg.ResX) {
- case 1600:
- val = VIDMODE_1600x1200;
- break;
- case 1280:
- val = VIDMODE_1280x960;
- break;
- case 1152:
- val = VIDMODE_1152x864;
- break;
- case 1024:
- val = VIDMODE_1024x768;
- break;
- case 800:
- val = VIDMODE_800x600;
- break;
- case 640:
- val = VIDMODE_640x480;
- break;
- default:
- val = VIDMODE_320x200;
- }
-
- gtk_combo_box_set_active(GTK_COMBO_BOX (w->resolution_combobox), val);
- gtk_combo_box_set_active(GTK_COMBO_BOX (w->dithering_combobox),
- g_cfg.Dithering);
- gtk_toggle_button_set_active(
- GTK_TOGGLE_BUTTON (w->maintain_ratio_checkbutton), g_cfg.Maintain43);
-
- gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON (w->fullscreen_checkbutton),
- g_cfg.FullScreen);
-
- gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON (w->show_fps_checkbutton),
- g_cfg.ShowFPS);
-
- gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON (w->set_fps_checkbutton),
- g_cfg.UseFrameLimit);
-
- gtk_toggle_button_set_active(
- GTK_TOGGLE_BUTTON (w->auto_fps_limit_checkbutton),
- g_cfg.FPSDetection);
-
- sprintf(tempstr, "%.1f", g_cfg.FrameRate);
- gtk_entry_set_text(GTK_ENTRY(w->fps_entry), tempstr);
-
- gtk_toggle_button_set_active(
- GTK_TOGGLE_BUTTON (w->use_game_fixes_checkbutton), g_cfg.UseFixes);
-
- for (i = 0; i < 11; ++i) {
- gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON (w->fix_checkbutton[i]),
- (g_cfg.CfgFixes >> i) & 1);
- }
-
- g_signal_connect_data(GTK_OBJECT(w->config_window), "destroy",
- G_CALLBACK(on_destroy_window), w, NULL, 0);
- g_signal_connect_data(GTK_OBJECT(w->save_button), "clicked",
- G_CALLBACK(on_click_save_button), w, NULL, G_CONNECT_AFTER);
- g_signal_connect_data(GTK_OBJECT(w->cancel_button), "clicked",
- G_CALLBACK(on_click_cancel_button), w, NULL, G_CONNECT_AFTER);
-
- g_signal_connect_data(GTK_OBJECT(w->fullscreen_checkbutton), "clicked",
- G_CALLBACK(on_fullscreen_toggled), w, NULL, G_CONNECT_AFTER);
-
- g_signal_connect_data(GTK_OBJECT(w->use_game_fixes_checkbutton), "clicked",
- G_CALLBACK(on_use_fixes_toggled), w, NULL, G_CONNECT_AFTER);
- g_signal_connect_data(GTK_OBJECT(w->set_fps_checkbutton), "clicked",
- G_CALLBACK(on_fps_toggled), w, NULL, G_CONNECT_AFTER);
-
- g_signal_connect_data(GTK_OBJECT(w->auto_fps_limit_checkbutton), "clicked",
- G_CALLBACK(on_fps_toggled), w, NULL, G_CONNECT_AFTER);
-
- on_fullscreen_toggled(0, w);
- on_fps_toggled(0, w);
- on_use_fixes_toggled(0, w);
-
- gtk_widget_show_all(w->config_window);
- gtk_main();
- return 0;
-}
-
-void save_config(cfg_window_t * w) {
- int val;
-
- val = gtk_combo_box_get_active(GTK_COMBO_BOX (w->resolution_combobox));
-
- if (val == VIDMODE_320x200) {
- g_cfg.ResX = 320;
- g_cfg.ResY = 240;
- } else if (val == VIDMODE_640x480) {
- g_cfg.ResX = 640;
- g_cfg.ResY = 480;
- } else if (val == VIDMODE_800x600) {
- g_cfg.ResX = 800;
- g_cfg.ResY = 600;
- } else if (val == VIDMODE_1024x768) {
- g_cfg.ResX = 1024;
- g_cfg.ResY = 768;
- } else if (val == VIDMODE_1152x864) {
- g_cfg.ResX = 1152;
- g_cfg.ResY = 864;
- } else if (val == VIDMODE_1280x960) {
- g_cfg.ResX = 1280;
- g_cfg.ResY = 960;
- } else if (val == VIDMODE_1600x1200) {
- g_cfg.ResX = 1600;
- g_cfg.ResY = 1200;
- }
-
- val = gtk_combo_box_get_active(GTK_COMBO_BOX (w->dithering_combobox));
- g_cfg.Dithering = val;
-
- val = gtk_toggle_button_get_active(
- GTK_TOGGLE_BUTTON (w->maintain_ratio_checkbutton));
- g_cfg.Maintain43 = val;
-
- val = gtk_toggle_button_get_active(
- GTK_TOGGLE_BUTTON (w->fullscreen_checkbutton));
- g_cfg.FullScreen = val;
-
- val = gtk_toggle_button_get_active(
- GTK_TOGGLE_BUTTON(w->show_fps_checkbutton));
- g_cfg.ShowFPS = val;
-
- val = gtk_toggle_button_get_active(
- GTK_TOGGLE_BUTTON (w->set_fps_checkbutton));
- g_cfg.UseFrameLimit = val;
-
- val = gtk_toggle_button_get_active(
- GTK_TOGGLE_BUTTON (w->auto_fps_limit_checkbutton));
- g_cfg.FPSDetection = val;
-
- //Framerate stored *10
- val = atof(gtk_entry_get_text(GTK_ENTRY(w->fps_entry))) * 10;
- g_cfg.FrameRate = val;
-
- val = gtk_toggle_button_get_active(
- GTK_TOGGLE_BUTTON (w->use_game_fixes_checkbutton));
- g_cfg.UseFixes = val;
-
- val = 0;
- int i;
- for (i = 0; i < 11; ++i) {
- if (gtk_toggle_button_get_active(
- GTK_TOGGLE_BUTTON (w->fix_checkbutton[i])))
- val |= 1 << i;
- }
- g_cfg.CfgFixes = val;
-
- WriteConfig();
- free(w);
- // Close the window and exit control from the plugin
- gtk_exit(0);
-}
+/*
+ * Copyright (C) 2010 Benoit Gschwind
+ *
+ * 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 3 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., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#include <gtk/gtk.h>
+#include <glade/glade.h>
+
+#include "globals.h"
+#include "config.h"
+
+#ifdef ENABLE_NLS
+#include <libintl.h>
+#include <locale.h>
+#endif
+
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+
+#define READBINARY "rb"
+#define WRITEBINARY "wb"
+#define CONFIG_FILENAME "dfxvideo.cfg"
+
+enum {
+ VIDMODE_320x200 = 0,
+ VIDMODE_640x480,
+ VIDMODE_800x600,
+ VIDMODE_1024x768,
+ VIDMODE_1152x864,
+ VIDMODE_1280x960,
+ VIDMODE_1600x1200
+}; /* Video_modes */
+
+typedef struct {
+ GtkWidget * config_window;
+ GtkWidget * resolution_combobox;
+ GtkWidget * dithering_combobox;
+ GtkWidget * maintain_ratio_checkbutton;
+ GtkWidget * fullscreen_checkbutton;
+ GtkWidget * show_fps_checkbutton;
+ GtkWidget * set_fps_checkbutton;
+ GtkWidget * auto_fps_limit_checkbutton;
+ GtkWidget * fps_entry;
+ GtkWidget * use_game_fixes_checkbutton;
+ GtkWidget * save_button;
+ GtkWidget * cancel_button;
+ GtkWidget * fixes_table;
+ GtkWidget * fix_checkbutton[11];
+} cfg_window_t;
+
+void save_config(cfg_window_t *);
+
+/* This function checks for the value being outside the accepted range,
+ and returns the appropriate boundary value */
+int set_limit(char *p, int len, int lower, int upper) {
+ int val = 0;
+
+ if (p)
+ val = atoi(p + len);
+ /* printf("Checking for val %d greater than %d and lower than %d, ", val, lower, upper);*/
+ if (val < lower)
+ val = lower;
+ if (val > upper)
+ val = upper;
+ /* printf ("val is now %d\n", val);*/
+ return val;
+}
+
+void on_about_clicked(GtkWidget * widget, gpointer user_data) {
+ gtk_widget_destroy(widget);
+ exit(0);
+}
+
+void set_widget_sensitive(GtkWidget * widget, gboolean * state) {
+ gtk_widget_set_sensitive(widget, *state);
+}
+
+void on_fullscreen_toggled(GtkWidget * widget, cfg_window_t * w) {
+ gtk_widget_set_sensitive(w->resolution_combobox,
+ !gtk_toggle_button_get_active(
+ GTK_TOGGLE_BUTTON(w->fullscreen_checkbutton)));
+}
+
+void update_fixes_stase(GtkWidget * ths, GtkWidget * w) {
+ gtk_widget_set_sensitive(ths, gtk_toggle_button_get_active(
+ GTK_TOGGLE_BUTTON(w)));
+}
+
+void on_use_fixes_toggled(GtkWidget * widget, cfg_window_t * w) {
+ /* Set the state of each of the fixes to the value of the use fixes toggle */
+ gtk_container_foreach(GTK_CONTAINER (w->fixes_table),
+ (GtkCallback) update_fixes_stase, w->use_game_fixes_checkbutton);
+}
+
+void on_fps_toggled(GtkWidget * widget, cfg_window_t * w) {
+ gboolean state_set_fps = gtk_toggle_button_get_active(
+ GTK_TOGGLE_BUTTON(w->set_fps_checkbutton));
+ gboolean state_auto_fps_limit = gtk_toggle_button_get_active(
+ GTK_TOGGLE_BUTTON(w->auto_fps_limit_checkbutton));
+ gtk_widget_set_sensitive(w->fps_entry, state_set_fps
+ && !state_auto_fps_limit);
+ gtk_widget_set_sensitive(w->auto_fps_limit_checkbutton, state_set_fps);
+}
+
+void on_destroy_window(GtkWidget * widget, cfg_window_t * w) {
+ free(w);
+}
+
+void on_click_save_button(GtkWidget * widget, cfg_window_t * w) {
+ save_config(w);
+ gtk_widget_destroy(GTK_WIDGET(w->config_window));
+ gtk_exit(0);
+}
+
+void on_click_cancel_button(GtkWidget * widget, cfg_window_t * w) {
+ gtk_widget_destroy(GTK_WIDGET(w->config_window));
+ gtk_exit(0);
+}
+
+int main(int argc, char *argv[]) {
+ cfg_window_t * w = 0;
+ GtkWidget * widget;
+ GtkBuilder * builder;
+ int i, val;
+ char tempstr[50];
+
+#ifdef ENABLE_NLS
+ setlocale(LC_ALL, "");
+ bindtextdomain(GETTEXT_PACKAGE, LOCALE_DIR);
+ bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
+ textdomain(GETTEXT_PACKAGE);
+#endif
+
+ if (argc != 2) {
+ printf("Usage: cfgGXVideo {ABOUT | CFG}\n");
+ return 0;
+ }
+ if (strcmp(argv[1], "CFG") != 0 && strcmp(argv[1], "ABOUT") != 0) {
+ printf("Usage: cfgGXVideo {ABOUT | CFG}\n");
+ return 0;
+ }
+
+ gtk_set_locale();
+ gtk_init(&argc, &argv);
+
+ if (strcmp(argv[1], "ABOUT") == 0) {
+ const char *authors[] = { "Pete Bernert and the P.E.Op.S. team",
+ "Ryan Schultz", "Andrew Burton", NULL };
+ widget = gtk_about_dialog_new();
+ gtk_about_dialog_set_name(GTK_ABOUT_DIALOG (widget),
+ "P.E.Op.S PCSX Video Plugin");
+ gtk_about_dialog_set_version(GTK_ABOUT_DIALOG (widget), "1.17");
+ gtk_about_dialog_set_authors(GTK_ABOUT_DIALOG (widget), authors);
+ gtk_about_dialog_set_website(GTK_ABOUT_DIALOG (widget),
+ "http://pcsx-df.sourceforge.net/");
+
+ g_signal_connect_data(GTK_OBJECT(widget), "response",
+ G_CALLBACK(on_about_clicked), NULL, NULL, G_CONNECT_AFTER);
+
+ gtk_widget_show(widget);
+ gtk_main();
+
+ return 0;
+ }
+
+ builder = gtk_builder_new();
+ if (!builder) {
+ g_warning("We could not load the interface!");
+ return -1;
+ }
+
+ gtk_builder_add_from_file(builder, DATADIR "gxvideo.glade", NULL);
+ w = (cfg_window_t *) malloc(sizeof(cfg_window_t));
+#define CFG_GET_WIDGET(name) w->name = GTK_WIDGET(gtk_builder_get_object(builder, #name))
+ CFG_GET_WIDGET(config_window);
+ CFG_GET_WIDGET(config_window);
+ CFG_GET_WIDGET(resolution_combobox);
+ CFG_GET_WIDGET(dithering_combobox);
+ CFG_GET_WIDGET(maintain_ratio_checkbutton);
+ CFG_GET_WIDGET(fullscreen_checkbutton);
+ CFG_GET_WIDGET(show_fps_checkbutton);
+ CFG_GET_WIDGET(set_fps_checkbutton);
+ CFG_GET_WIDGET(auto_fps_limit_checkbutton);
+ CFG_GET_WIDGET(fps_entry);
+ CFG_GET_WIDGET(use_game_fixes_checkbutton);
+ CFG_GET_WIDGET(save_button);
+ CFG_GET_WIDGET(cancel_button);
+ CFG_GET_WIDGET(fixes_table);
+
+ for (i = 0; i < 11; ++i) {
+ sprintf(tempstr, "fix%d_checkbutton", i);
+ w->fix_checkbutton[i]
+ = GTK_WIDGET(gtk_builder_get_object(builder, tempstr));
+ }
+
+ ReadConfig();
+
+ switch (g_cfg.ResX) {
+ case 1600:
+ val = VIDMODE_1600x1200;
+ break;
+ case 1280:
+ val = VIDMODE_1280x960;
+ break;
+ case 1152:
+ val = VIDMODE_1152x864;
+ break;
+ case 1024:
+ val = VIDMODE_1024x768;
+ break;
+ case 800:
+ val = VIDMODE_800x600;
+ break;
+ case 640:
+ val = VIDMODE_640x480;
+ break;
+ default:
+ val = VIDMODE_320x200;
+ }
+
+ gtk_combo_box_set_active(GTK_COMBO_BOX (w->resolution_combobox), val);
+ gtk_combo_box_set_active(GTK_COMBO_BOX (w->dithering_combobox),
+ g_cfg.Dithering);
+ gtk_toggle_button_set_active(
+ GTK_TOGGLE_BUTTON (w->maintain_ratio_checkbutton), g_cfg.Maintain43);
+
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON (w->fullscreen_checkbutton),
+ g_cfg.FullScreen);
+
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON (w->show_fps_checkbutton),
+ g_cfg.ShowFPS);
+
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON (w->set_fps_checkbutton),
+ g_cfg.UseFrameLimit);
+
+ gtk_toggle_button_set_active(
+ GTK_TOGGLE_BUTTON (w->auto_fps_limit_checkbutton),
+ g_cfg.FPSDetection);
+
+ sprintf(tempstr, "%.1f", g_cfg.FrameRate);
+ gtk_entry_set_text(GTK_ENTRY(w->fps_entry), tempstr);
+
+ gtk_toggle_button_set_active(
+ GTK_TOGGLE_BUTTON (w->use_game_fixes_checkbutton), g_cfg.UseFixes);
+
+ for (i = 0; i < 11; ++i) {
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON (w->fix_checkbutton[i]),
+ (g_cfg.CfgFixes >> i) & 1);
+ }
+
+ g_signal_connect_data(GTK_OBJECT(w->config_window), "destroy",
+ G_CALLBACK(on_destroy_window), w, NULL, 0);
+ g_signal_connect_data(GTK_OBJECT(w->save_button), "clicked",
+ G_CALLBACK(on_click_save_button), w, NULL, G_CONNECT_AFTER);
+ g_signal_connect_data(GTK_OBJECT(w->cancel_button), "clicked",
+ G_CALLBACK(on_click_cancel_button), w, NULL, G_CONNECT_AFTER);
+
+ g_signal_connect_data(GTK_OBJECT(w->fullscreen_checkbutton), "clicked",
+ G_CALLBACK(on_fullscreen_toggled), w, NULL, G_CONNECT_AFTER);
+
+ g_signal_connect_data(GTK_OBJECT(w->use_game_fixes_checkbutton), "clicked",
+ G_CALLBACK(on_use_fixes_toggled), w, NULL, G_CONNECT_AFTER);
+ g_signal_connect_data(GTK_OBJECT(w->set_fps_checkbutton), "clicked",
+ G_CALLBACK(on_fps_toggled), w, NULL, G_CONNECT_AFTER);
+
+ g_signal_connect_data(GTK_OBJECT(w->auto_fps_limit_checkbutton), "clicked",
+ G_CALLBACK(on_fps_toggled), w, NULL, G_CONNECT_AFTER);
+
+ on_fullscreen_toggled(0, w);
+ on_fps_toggled(0, w);
+ on_use_fixes_toggled(0, w);
+
+ gtk_widget_show_all(w->config_window);
+ gtk_main();
+ return 0;
+}
+
+void save_config(cfg_window_t * w) {
+ int val;
+
+ val = gtk_combo_box_get_active(GTK_COMBO_BOX (w->resolution_combobox));
+
+ if (val == VIDMODE_320x200) {
+ g_cfg.ResX = 320;
+ g_cfg.ResY = 240;
+ } else if (val == VIDMODE_640x480) {
+ g_cfg.ResX = 640;
+ g_cfg.ResY = 480;
+ } else if (val == VIDMODE_800x600) {
+ g_cfg.ResX = 800;
+ g_cfg.ResY = 600;
+ } else if (val == VIDMODE_1024x768) {
+ g_cfg.ResX = 1024;
+ g_cfg.ResY = 768;
+ } else if (val == VIDMODE_1152x864) {
+ g_cfg.ResX = 1152;
+ g_cfg.ResY = 864;
+ } else if (val == VIDMODE_1280x960) {
+ g_cfg.ResX = 1280;
+ g_cfg.ResY = 960;
+ } else if (val == VIDMODE_1600x1200) {
+ g_cfg.ResX = 1600;
+ g_cfg.ResY = 1200;
+ }
+
+ val = gtk_combo_box_get_active(GTK_COMBO_BOX (w->dithering_combobox));
+ g_cfg.Dithering = val;
+
+ val = gtk_toggle_button_get_active(
+ GTK_TOGGLE_BUTTON (w->maintain_ratio_checkbutton));
+ g_cfg.Maintain43 = val;
+
+ val = gtk_toggle_button_get_active(
+ GTK_TOGGLE_BUTTON (w->fullscreen_checkbutton));
+ g_cfg.FullScreen = val;
+
+ val = gtk_toggle_button_get_active(
+ GTK_TOGGLE_BUTTON(w->show_fps_checkbutton));
+ g_cfg.ShowFPS = val;
+
+ val = gtk_toggle_button_get_active(
+ GTK_TOGGLE_BUTTON (w->set_fps_checkbutton));
+ g_cfg.UseFrameLimit = val;
+
+ val = gtk_toggle_button_get_active(
+ GTK_TOGGLE_BUTTON (w->auto_fps_limit_checkbutton));
+ g_cfg.FPSDetection = val;
+
+ //Framerate stored *10
+ val = atof(gtk_entry_get_text(GTK_ENTRY(w->fps_entry))) * 10;
+ g_cfg.FrameRate = val;
+
+ val = gtk_toggle_button_get_active(
+ GTK_TOGGLE_BUTTON (w->use_game_fixes_checkbutton));
+ g_cfg.UseFixes = val;
+
+ val = 0;
+ int i;
+ for (i = 0; i < 11; ++i) {
+ if (gtk_toggle_button_get_active(
+ GTK_TOGGLE_BUTTON (w->fix_checkbutton[i])))
+ val |= 1 << i;
+ }
+ g_cfg.CfgFixes = val;
+
+ WriteConfig();
+ free(w);
+ // Close the window and exit control from the plugin
+ gtk_exit(0);
+}
diff --git a/plugins/gxvideo/key.c b/plugins/gxvideo/key.c
index c8a9b288..2175cc9c 100644
--- a/plugins/gxvideo/key.c
+++ b/plugins/gxvideo/key.c
@@ -1,44 +1,43 @@
-/***************************************************************************
- key.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 "menu.h"
-#include "gpu.h"
-#include "draw.h"
-#include "key.h"
-#include "psemu_plugin_defs.h"
-
-#define VK_INSERT 65379
-#define VK_HOME 65360
-#define VK_PRIOR 65365
-#define VK_NEXT 65366
-#define VK_END 65367
-#define VK_DEL 65535
-#define VK_F5 65474
-
-void GPUmakeSnapshot(void);
-
-unsigned long ulKeybits = 0;
-
-void GPUkeypressed(int keycode) {
-
-}
-
-void SetKeyHandler(void) {
-}
-
-void ReleaseKeyHandler(void) {
-}
+/***************************************************************************
+ key.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 "menu.h"
+#include "gpu.h"
+#include "draw.h"
+#include "key.h"
+
+#define VK_INSERT 65379
+#define VK_HOME 65360
+#define VK_PRIOR 65365
+#define VK_NEXT 65366
+#define VK_END 65367
+#define VK_DEL 65535
+#define VK_F5 65474
+
+void GPUmakeSnapshot(void);
+
+unsigned long ulKeybits = 0;
+
+void GPUkeypressed(int keycode) {
+
+}
+
+void SetKeyHandler(void) {
+}
+
+void ReleaseKeyHandler(void) {
+}
diff --git a/plugins/gxvideo/menu.c b/plugins/gxvideo/menu.c
index babe2446..0ced33ef 100644
--- a/plugins/gxvideo/menu.c
+++ b/plugins/gxvideo/menu.c
@@ -1,56 +1,57 @@
-/***************************************************************************
- menu.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 "draw.h"
-#include "menu.h"
-#include "gpu.h"
-
-unsigned long dwCoreFlags = 0;
-
-// create lists/stuff for fonts (actually there are no more lists, but I am too lazy to change the func names ;)
-void InitMenu(void)
-{
-}
-
-// kill existing lists/fonts
-void CloseMenu(void)
-{
- DestroyPic();
-}
-
-// DISPLAY FPS/MENU TEXT
-
-#include <time.h>
-
-int iMPos=0; // menu arrow pos
-
-void DisplayText(void) // DISPLAY TEXT
-{
-
-}
-
-// Build Menu buffer (== Dispbuffer without FPS)...
-void BuildDispMenu(int iInc)
-{
-
-}
-
-// Some menu action...
-void SwitchDispMenu(int iStep) // SWITCH DISP MENU
-{
- // update info
-}
+/***************************************************************************
+ menu.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 "draw.h"
+#include "menu.h"
+#include "gpu.h"
+
+unsigned long dwCoreFlags = 0;
+
+// create lists/stuff for fonts (actually there are no more lists, but I am too lazy to change the func names ;)
+void InitMenu(void)
+{
+}
+
+// kill existing lists/fonts
+void CloseMenu(void)
+{
+ DestroyPic();
+}
+
+// DISPLAY FPS/MENU TEXT
+
+#include <time.h>
+//extern time_t tStart;
+
+int iMPos=0; // menu arrow pos
+
+void DisplayText(void) // DISPLAY TEXT
+{
+
+}
+
+// Build Menu buffer (== Dispbuffer without FPS)...
+void BuildDispMenu(int iInc)
+{
+
+}
+
+// Some menu action...
+void SwitchDispMenu(int iStep) // SWITCH DISP MENU
+{
+ // update info
+}
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 };
+
diff --git a/plugins/gxvideo/soft.c b/plugins/gxvideo/soft.c
index d7e3a5c7..023073d3 100644
--- a/plugins/gxvideo/soft.c
+++ b/plugins/gxvideo/soft.c
@@ -1,9931 +1,9931 @@
-/***************************************************************************
- soft.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 "globals.h"
-#include "soft.h"
-#include "swap.h"
-
-#define MIN(a,b) ((a) > (b) ? (b) : (a))
-#define MAX(a,b) ((a) < (b) ? (b) : (a))
-
-#define LOWORD(l) ((unsigned short)(l))
-#define HIWORD(l) ((unsigned short)(((uint32_t)(l) >> 16) & 0xFFFF))
-
-////////////////////////////////////////////////////////////////////////////////////
-// "NO EDGE BUFFER" POLY VERSION... FUNCS BASED ON FATMAP.TXT FROM MRI / Doomsday
-////////////////////////////////////////////////////////////////////////////////////
-
-////////////////////////////////////////////////////////////////////////////////////
-// defines
-////////////////////////////////////////////////////////////////////////////////////
-
-// switches for painting textured quads as 2 triangles (small glitches, but better shading!)
-// can be toggled by game fix 0x200 in version 1.17 anyway, so let the defines enabled!
-
-#define POLYQUAD3
-#define POLYQUAD3GT
-
-// fast solid loops... a bit more additional code, of course
-
-#define FASTSOLID
-
-// psx blending mode 3 with 25% incoming color (instead 50% without the define)
-
-#define HALFBRIGHTMODE3
-
-// color decode defines
-
-#define XCOL1(x) (x & 0x1f)
-#define XCOL2(x) (x & 0x3e0)
-#define XCOL3(x) (x & 0x7c00)
-
-#define XCOL1D(x) (x & 0x1f)
-#define XCOL2D(x) ((x>>5) & 0x1f)
-#define XCOL3D(x) ((x>>10) & 0x1f)
-
-#define X32TCOL1(x) ((x & 0x001f001f)<<7)
-#define X32TCOL2(x) ((x & 0x03e003e0)<<2)
-#define X32TCOL3(x) ((x & 0x7c007c00)>>3)
-
-#define X32COL1(x) (x & 0x001f001f)
-#define X32COL2(x) ((x>>5) & 0x001f001f)
-#define X32COL3(x) ((x>>10) & 0x001f001f)
-
-#define X32ACOL1(x) (x & 0x001e001e)
-#define X32ACOL2(x) ((x>>5) & 0x001e001e)
-#define X32ACOL3(x) ((x>>10) & 0x001e001e)
-
-#define X32BCOL1(x) (x & 0x001c001c)
-#define X32BCOL2(x) ((x>>5) & 0x001c001c)
-#define X32BCOL3(x) ((x>>10) & 0x001c001c)
-
-#define X32PSXCOL(r,g,b) ((g<<10)|(b<<5)|r)
-
-#define XPSXCOL(r,g,b) ((g&0x7c00)|(b&0x3e0)|(r&0x1f))
-
-////////////////////////////////////////////////////////////////////////////////////
-// soft globals
-////////////////////////////////////////////////////////////////////////////////////
-
-
-////////////////////////////////////////////////////////////////////////
-// POLYGON OFFSET FUNCS
-////////////////////////////////////////////////////////////////////////
-
-void offsetPSXLine(void) {
- short x0, x1, y0, y1, dx, dy;
- float px, py;
-
- x0 = g_soft.lx0 + 1 + g_gpu.dsp.DrawOffset.x;
- x1 = g_soft.lx1 + 1 + g_gpu.dsp.DrawOffset.x;
- y0 = g_soft.ly0 + 1 + g_gpu.dsp.DrawOffset.y;
- y1 = g_soft.ly1 + 1 + g_gpu.dsp.DrawOffset.y;
-
- dx = x1 - x0;
- dy = y1 - y0;
-
- // tricky line width without sqrt
-
- if (dx >= 0) {
- if (dy >= 0) {
- px = 0.5f;
- if (dx > dy)
- py = -0.5f;
- else if (dx < dy)
- py = 0.5f;
- else
- py = 0.0f;
- } else {
- py = -0.5f;
- dy = -dy;
- if (dx > dy)
- px = 0.5f;
- else if (dx < dy)
- px = -0.5f;
- else
- px = 0.0f;
- }
- } else {
- if (dy >= 0) {
- py = 0.5f;
- dx = -dx;
- if (dx > dy)
- px = -0.5f;
- else if (dx < dy)
- px = 0.5f;
- else
- px = 0.0f;
- } else {
- px = -0.5f;
- if (dx > dy)
- py = -0.5f;
- else if (dx < dy)
- py = 0.5f;
- else
- py = 0.0f;
- }
- }
-
- g_soft.lx0 = (short) ((float) x0 - px);
- g_soft.lx3 = (short) ((float) x0 + py);
-
- g_soft.ly0 = (short) ((float) y0 - py);
- g_soft.ly3 = (short) ((float) y0 - px);
-
- g_soft.lx1 = (short) ((float) x1 - py);
- g_soft.lx2 = (short) ((float) x1 + px);
-
- g_soft.ly1 = (short) ((float) y1 + px);
- g_soft.ly2 = (short) ((float) y1 + py);
-}
-
-void offsetPSX2(void) {
- g_soft.lx0 += g_gpu.dsp.DrawOffset.x;
- g_soft.ly0 += g_gpu.dsp.DrawOffset.y;
- g_soft.lx1 += g_gpu.dsp.DrawOffset.x;
- g_soft.ly1 += g_gpu.dsp.DrawOffset.y;
-}
-
-void offsetPSX3(void) {
- g_soft.lx0 += g_gpu.dsp.DrawOffset.x;
- g_soft.ly0 += g_gpu.dsp.DrawOffset.y;
- g_soft.lx1 += g_gpu.dsp.DrawOffset.x;
- g_soft.ly1 += g_gpu.dsp.DrawOffset.y;
- g_soft.lx2 += g_gpu.dsp.DrawOffset.x;
- g_soft.ly2 += g_gpu.dsp.DrawOffset.y;
-}
-
-void offsetPSX4(void) {
- g_soft.lx0 += g_gpu.dsp.DrawOffset.x;
- g_soft.ly0 += g_gpu.dsp.DrawOffset.y;
- g_soft.lx1 += g_gpu.dsp.DrawOffset.x;
- g_soft.ly1 += g_gpu.dsp.DrawOffset.y;
- g_soft.lx2 += g_gpu.dsp.DrawOffset.x;
- g_soft.ly2 += g_gpu.dsp.DrawOffset.y;
- g_soft.lx3 += g_gpu.dsp.DrawOffset.x;
- g_soft.ly3 += g_gpu.dsp.DrawOffset.y;
-}
-
-/////////////////////////////////////////////////////////////////
-/////////////////////////////////////////////////////////////////
-/////////////////////////////////////////////////////////////////
-// PER PIXEL FUNCS
-////////////////////////////////////////////////////////////////////////
-/////////////////////////////////////////////////////////////////
-/////////////////////////////////////////////////////////////////
-
-
-uint8_t const dithertable[16] = { 7, 0, 6, 1, 2, 5, 3, 4, 1, 6, 0, 7, 4, 3, 5,
- 2 };
-
-static void Dither16(uint16_t * pdest, uint32_t r, uint32_t g, uint32_t b, uint16_t sM) {
- uint8_t coeff;
- uint8_t rlow, glow, blow;
- int x, y;
-
- x = pdest - g_gpu.psx_vram.u16;
- y = x >> 10;
- x -= (y << 10);
-
- coeff = dithertable[(y & 3) * 4 + (x & 3)];
-
- rlow = r & 7;
- glow = g & 7;
- blow = b & 7;
-
- r >>= 3;
- g >>= 3;
- b >>= 3;
-
- if ((r < 0x1F) && rlow > coeff)
- r++;
- if ((g < 0x1F) && glow > coeff)
- g++;
- if ((b < 0x1F) && blow > coeff)
- b++;
-
- PUTLE16(pdest, (b<<10) | (g<<5) | r | sM);
-}
-
-/////////////////////////////////////////////////////////////////
-/////////////////////////////////////////////////////////////////
-/////////////////////////////////////////////////////////////////
-
-static inline void GetShadeTransCol_Dither(uint16_t * pdest, int32_t m1,
- int32_t m2, int32_t m3) {
- int32_t r, g, b;
-
- if (g_draw.bCheckMask && (*pdest & HOST2LE16(0x8000)))
- return;
-
- if (g_soft.DrawSemiTrans) {
- r = ((XCOL1D(GETLE16(pdest))) << 3);
- b = ((XCOL2D(GETLE16(pdest))) << 3);
- g = ((XCOL3D(GETLE16(pdest))) << 3);
-
- if (g_soft.GlobalTextABR == 0) {
- r = (r >> 1) + (m1 >> 1);
- b = (b >> 1) + (m2 >> 1);
- g = (g >> 1) + (m3 >> 1);
- } else if (g_soft.GlobalTextABR == 1) {
- r += m1;
- b += m2;
- g += m3;
- } else if (g_soft.GlobalTextABR == 2) {
- r -= m1;
- b -= m2;
- g -= m3;
- if (r & 0x80000000)
- r = 0;
- if (b & 0x80000000)
- b = 0;
- if (g & 0x80000000)
- g = 0;
- } else {
-#ifdef HALFBRIGHTMODE3
- r += (m1 >> 2);
- b += (m2 >> 2);
- g += (m3 >> 2);
-#else
- r+=(m1>>1);
- b+=(m2>>1);
- g+=(m3>>1);
-#endif
- }
- } else {
- r = m1;
- b = m2;
- g = m3;
- }
-
- if (r & 0x7FFFFF00)
- r = 0xff;
- if (b & 0x7FFFFF00)
- b = 0xff;
- if (g & 0x7FFFFF00)
- g = 0xff;
-
- Dither16(pdest, r, b, g, g_draw.sSetMask);
-}
-
-////////////////////////////////////////////////////////////////////////
-
-static inline void GetShadeTransCol(unsigned short * pdest, unsigned short color) {
- if (g_draw.bCheckMask && (*pdest & HOST2LE16(0x8000)))
- return;
-
- if (g_soft.DrawSemiTrans) {
- int32_t r, g, b;
-
- if (g_soft.GlobalTextABR == 0) {
- PUTLE16(pdest, (((GETLE16(pdest)&0x7bde)>>1)+(((color)&0x7bde)>>1))|g_draw.sSetMask);//0x8000;
- return;
- /*
- r=(XCOL1(*pdest)>>1)+((XCOL1(color))>>1);
- b=(XCOL2(*pdest)>>1)+((XCOL2(color))>>1);
- g=(XCOL3(*pdest)>>1)+((XCOL3(color))>>1);
- */
- } else if (g_soft.GlobalTextABR == 1) {
- r = (XCOL1(GETLE16(pdest))) + ((XCOL1(color)));
- b = (XCOL2(GETLE16(pdest))) + ((XCOL2(color)));
- g = (XCOL3(GETLE16(pdest))) + ((XCOL3(color)));
- } else if (g_soft.GlobalTextABR == 2) {
- r = (XCOL1(GETLE16(pdest))) - ((XCOL1(color)));
- b = (XCOL2(GETLE16(pdest))) - ((XCOL2(color)));
- g = (XCOL3(GETLE16(pdest))) - ((XCOL3(color)));
- if (r & 0x80000000)
- r = 0;
- if (b & 0x80000000)
- b = 0;
- if (g & 0x80000000)
- g = 0;
- } else {
-#ifdef HALFBRIGHTMODE3
- r = (XCOL1(GETLE16(pdest))) + ((XCOL1(color)) >> 2);
- b = (XCOL2(GETLE16(pdest))) + ((XCOL2(color)) >> 2);
- g = (XCOL3(GETLE16(pdest))) + ((XCOL3(color)) >> 2);
-#else
- r=(XCOL1(GETLE16(pdest)))+((XCOL1(color))>>1);
- b=(XCOL2(GETLE16(pdest)))+((XCOL2(color))>>1);
- g=(XCOL3(GETLE16(pdest)))+((XCOL3(color))>>1);
-#endif
- }
-
- if (r & 0x7FFFFFE0)
- r = 0x1f;
- if (b & 0x7FFFFC00)
- b = 0x3e0;
- if (g & 0x7FFF8000)
- g = 0x7c00;
-
- PUTLE16(pdest, (XPSXCOL(r,g,b))|g_draw.sSetMask);//0x8000;
- }
-else PUTLE16(pdest, color|g_draw.sSetMask);
- }
-
- ////////////////////////////////////////////////////////////////////////
-
-static inline void GetShadeTransCol32(uint32_t * pdest, uint32_t color) {
- if (g_soft.DrawSemiTrans) {
- int32_t r, g, b;
-
- if (g_soft.GlobalTextABR == 0) {
- if (!g_draw.bCheckMask) {
- PUTLE32(pdest, (((GETLE32(pdest)&0x7bde7bde)>>1)+(((color)&0x7bde7bde)>>1))|g_draw.lSetMask);//0x80008000;
- return;
- }
- r = (X32ACOL1(GETLE32(pdest)) >> 1) + ((X32ACOL1(color)) >> 1);
- b = (X32ACOL2(GETLE32(pdest)) >> 1) + ((X32ACOL2(color)) >> 1);
- g = (X32ACOL3(GETLE32(pdest)) >> 1) + ((X32ACOL3(color)) >> 1);
- } else if (g_soft.GlobalTextABR == 1) {
- r = (X32COL1(GETLE32(pdest))) + ((X32COL1(color)));
- b = (X32COL2(GETLE32(pdest))) + ((X32COL2(color)));
- g = (X32COL3(GETLE32(pdest))) + ((X32COL3(color)));
- } else if (g_soft.GlobalTextABR == 2) {
- int32_t sr, sb, sg, src, sbc, sgc, c;
- src = XCOL1(color);
- sbc = XCOL2(color);
- sgc = XCOL3(color);
- c = GETLE32(pdest) >> 16;
- sr = (XCOL1(c)) - src;
- if (sr & 0x8000)
- sr = 0;
- sb = (XCOL2(c)) - sbc;
- if (sb & 0x8000)
- sb = 0;
- sg = (XCOL3(c)) - sgc;
- if (sg & 0x8000)
- sg = 0;
- r = ((int32_t) sr) << 16;
- b = ((int32_t) sb) << 11;
- g = ((int32_t) sg) << 6;
- c = LOWORD(GETLE32(pdest));
- sr = (XCOL1(c)) - src;
- if (sr & 0x8000)
- sr = 0;
- sb = (XCOL2(c)) - sbc;
- if (sb & 0x8000)
- sb = 0;
- sg = (XCOL3(c)) - sgc;
- if (sg & 0x8000)
- sg = 0;
- r |= sr;
- b |= sb >> 5;
- g |= sg >> 10;
- } else {
-#ifdef HALFBRIGHTMODE3
- r = (X32COL1(GETLE32(pdest))) + ((X32BCOL1(color)) >> 2);
- b = (X32COL2(GETLE32(pdest))) + ((X32BCOL2(color)) >> 2);
- g = (X32COL3(GETLE32(pdest))) + ((X32BCOL3(color)) >> 2);
-#else
- r=(X32COL1(GETLE32(pdest)))+((X32ACOL1(color))>>1);
- b=(X32COL2(GETLE32(pdest)))+((X32ACOL2(color))>>1);
- g=(X32COL3(GETLE32(pdest)))+((X32ACOL3(color))>>1);
-#endif
- }
-
- if (r & 0x7FE00000)
- r = 0x1f0000 | (r & 0xFFFF);
- if (r & 0x7FE0)
- r = 0x1f | (r & 0xFFFF0000);
- if (b & 0x7FE00000)
- b = 0x1f0000 | (b & 0xFFFF);
- if (b & 0x7FE0)
- b = 0x1f | (b & 0xFFFF0000);
- if (g & 0x7FE00000)
- g = 0x1f0000 | (g & 0xFFFF);
- if (g & 0x7FE0)
- g = 0x1f | (g & 0xFFFF0000);
-
- if (g_draw.bCheckMask) {
- uint32_t ma = GETLE32(pdest);
- PUTLE32(pdest, (X32PSXCOL(r,g,b))|g_draw.lSetMask);//0x80008000;
- if (ma & 0x80000000)
- PUTLE32(pdest, (ma&0xFFFF0000)|(*pdest&0xFFFF));
- if (ma & 0x00008000)
- PUTLE32(pdest, (ma&0xFFFF) |(*pdest&0xFFFF0000));
- return;
- }
- PUTLE32(pdest, (X32PSXCOL(r,g,b))|g_draw.lSetMask);//0x80008000;
- } else {
- if (g_draw.bCheckMask) {
- uint32_t ma = GETLE32(pdest);
- PUTLE32(pdest, color|g_draw.lSetMask);//0x80008000;
- if (ma & 0x80000000)
- PUTLE32(pdest, (ma&0xFFFF0000)|(GETLE32(pdest)&0xFFFF));
- if (ma & 0x00008000)
- PUTLE32(pdest, (ma&0xFFFF) |(GETLE32(pdest)&0xFFFF0000));
- return;
- }
-
- PUTLE32(pdest, color|g_draw.lSetMask);//0x80008000;
- }
-}
-
-////////////////////////////////////////////////////////////////////////
-
-static inline void GetTextureTransColG(unsigned short * pdest, unsigned short color) {
- int32_t r, g, b;
- unsigned short l;
-
- if (color == 0)
- return;
-
- if (g_draw.bCheckMask && (*pdest & HOST2LE16(0x8000)))
- return;
-
- l = g_draw.sSetMask | (color & 0x8000);
-
- if (g_soft.DrawSemiTrans && (color & 0x8000)) {
- if (g_soft.GlobalTextABR == 0) {
- unsigned short d;
- d = (GETLE16(pdest) & 0x7bde) >> 1;
- color = ((color) & 0x7bde) >> 1;
- r = (XCOL1(d)) + ((((XCOL1(color))) * g_soft.g_m1) >> 7);
- b = (XCOL2(d)) + ((((XCOL2(color))) * g_soft.g_m2) >> 7);
- g = (XCOL3(d)) + ((((XCOL3(color))) * g_soft.g_m3) >> 7);
-
- /*
- r=(XCOL1(*pdest)>>1)+((((XCOL1(color))>>1)* g_soft.g_m1)>>7);
- b=(XCOL2(*pdest)>>1)+((((XCOL2(color))>>1)* g_soft.g_m2)>>7);
- g=(XCOL3(*pdest)>>1)+((((XCOL3(color))>>1)* g_soft.g_m3)>>7);
- */
- } else if (g_soft.GlobalTextABR == 1) {
- r = (XCOL1(GETLE16(pdest))) + ((((XCOL1(color))) * g_soft.g_m1)
- >> 7);
- b = (XCOL2(GETLE16(pdest))) + ((((XCOL2(color))) * g_soft.g_m2)
- >> 7);
- g = (XCOL3(GETLE16(pdest))) + ((((XCOL3(color))) * g_soft.g_m3)
- >> 7);
- } else if (g_soft.GlobalTextABR == 2) {
- r = (XCOL1(GETLE16(pdest))) - ((((XCOL1(color))) * g_soft.g_m1)
- >> 7);
- b = (XCOL2(GETLE16(pdest))) - ((((XCOL2(color))) * g_soft.g_m2)
- >> 7);
- g = (XCOL3(GETLE16(pdest))) - ((((XCOL3(color))) * g_soft.g_m3)
- >> 7);
- if (r & 0x80000000)
- r = 0;
- if (b & 0x80000000)
- b = 0;
- if (g & 0x80000000)
- g = 0;
- } else {
-#ifdef HALFBRIGHTMODE3
- r = (XCOL1(GETLE16(pdest)))
- + ((((XCOL1(color)) >> 2) * g_soft.g_m1) >> 7);
- b = (XCOL2(GETLE16(pdest)))
- + ((((XCOL2(color)) >> 2) * g_soft.g_m2) >> 7);
- g = (XCOL3(GETLE16(pdest)))
- + ((((XCOL3(color)) >> 2) * g_soft.g_m3) >> 7);
-#else
- r=(XCOL1(GETLE16(pdest)))+((((XCOL1(color))>>1)* g_soft.g_m1)>>7);
- b=(XCOL2(GETLE16(pdest)))+((((XCOL2(color))>>1)* g_soft.g_m2)>>7);
- g=(XCOL3(GETLE16(pdest)))+((((XCOL3(color))>>1)* g_soft.g_m3)>>7);
-#endif
- }
- } else {
- r = ((XCOL1(color)) * g_soft.g_m1) >> 7;
- b = ((XCOL2(color)) * g_soft.g_m2) >> 7;
- g = ((XCOL3(color)) * g_soft.g_m3) >> 7;
- }
-
- if (r & 0x7FFFFFE0)
- r = 0x1f;
- if (b & 0x7FFFFC00)
- b = 0x3e0;
- if (g & 0x7FFF8000)
- g = 0x7c00;
-
- PUTLE16(pdest, (XPSXCOL(r,g,b))|l);
-}
-
-////////////////////////////////////////////////////////////////////////
-
-static inline void GetTextureTransColG_S(unsigned short * pdest, unsigned short color) {
- int32_t r, g, b;
- unsigned short l;
-
- if (color == 0)
- return;
-
- l = g_draw.sSetMask | (color & 0x8000);
-
- r = ((XCOL1(color)) * g_soft.g_m1) >> 7;
- b = ((XCOL2(color)) * g_soft.g_m2) >> 7;
- g = ((XCOL3(color)) * g_soft.g_m3) >> 7;
-
- if (r & 0x7FFFFFE0)
- r = 0x1f;
- if (b & 0x7FFFFC00)
- b = 0x3e0;
- if (g & 0x7FFF8000)
- g = 0x7c00;
-
- PUTLE16(pdest, (XPSXCOL(r,g,b))|l);
-}
-
-////////////////////////////////////////////////////////////////////////
-
-static inline void GetTextureTransColG_SPR(unsigned short * pdest,
- unsigned short color) {
- int32_t r, g, b;
- unsigned short l;
-
- if (color == 0)
- return;
-
- if (g_draw.bCheckMask && (GETLE16(pdest) & 0x8000))
- return;
-
- l = g_draw.sSetMask | (color & 0x8000);
-
- if (g_soft.DrawSemiTrans && (color & 0x8000)) {
- if (g_soft.GlobalTextABR == 0) {
- unsigned short d;
- d = (GETLE16(pdest) & 0x7bde) >> 1;
- color = ((color) & 0x7bde) >> 1;
- r = (XCOL1(d)) + ((((XCOL1(color))) * g_soft.g_m1) >> 7);
- b = (XCOL2(d)) + ((((XCOL2(color))) * g_soft.g_m2) >> 7);
- g = (XCOL3(d)) + ((((XCOL3(color))) * g_soft.g_m3) >> 7);
-
- /*
- r=(XCOL1(*pdest)>>1)+((((XCOL1(color))>>1)* g_soft.g_m1)>>7);
- b=(XCOL2(*pdest)>>1)+((((XCOL2(color))>>1)* g_soft.g_m2)>>7);
- g=(XCOL3(*pdest)>>1)+((((XCOL3(color))>>1)* g_soft.g_m3)>>7);
- */
- } else if (g_soft.GlobalTextABR == 1) {
- r = (XCOL1(GETLE16(pdest))) + ((((XCOL1(color))) * g_soft.g_m1)
- >> 7);
- b = (XCOL2(GETLE16(pdest))) + ((((XCOL2(color))) * g_soft.g_m2)
- >> 7);
- g = (XCOL3(GETLE16(pdest))) + ((((XCOL3(color))) * g_soft.g_m3)
- >> 7);
- } else if (g_soft.GlobalTextABR == 2) {
- r = (XCOL1(GETLE16(pdest))) - ((((XCOL1(color))) * g_soft.g_m1)
- >> 7);
- b = (XCOL2(GETLE16(pdest))) - ((((XCOL2(color))) * g_soft.g_m2)
- >> 7);
- g = (XCOL3(GETLE16(pdest))) - ((((XCOL3(color))) * g_soft.g_m3)
- >> 7);
- if (r & 0x80000000)
- r = 0;
- if (b & 0x80000000)
- b = 0;
- if (g & 0x80000000)
- g = 0;
- } else {
-#ifdef HALFBRIGHTMODE3
- r = (XCOL1(GETLE16(pdest)))
- + ((((XCOL1(color)) >> 2) * g_soft.g_m1) >> 7);
- b = (XCOL2(GETLE16(pdest)))
- + ((((XCOL2(color)) >> 2) * g_soft.g_m2) >> 7);
- g = (XCOL3(GETLE16(pdest)))
- + ((((XCOL3(color)) >> 2) * g_soft.g_m3) >> 7);
-#else
- r=(XCOL1(GETLE16(pdest)))+((((XCOL1(color))>>1)* g_soft.g_m1)>>7);
- b=(XCOL2(GETLE16(pdest)))+((((XCOL2(color))>>1)* g_soft.g_m2)>>7);
- g=(XCOL3(GETLE16(pdest)))+((((XCOL3(color))>>1)* g_soft.g_m3)>>7);
-#endif
- }
- } else {
- r = ((XCOL1(color)) * g_soft.g_m1) >> 7;
- b = ((XCOL2(color)) * g_soft.g_m2) >> 7;
- g = ((XCOL3(color)) * g_soft.g_m3) >> 7;
- }
-
- if (r & 0x7FFFFFE0)
- r = 0x1f;
- if (b & 0x7FFFFC00)
- b = 0x3e0;
- if (g & 0x7FFF8000)
- g = 0x7c00;
-
- PUTLE16(pdest, (XPSXCOL(r,g,b))|l);
-}
-
-////////////////////////////////////////////////////////////////////////
-
-static inline void GetTextureTransColG32(uint32_t * pdest, uint32_t color) {
- int32_t r, g, b, l;
-
- if (color == 0)
- return;
-
- l = g_draw.lSetMask | (color & 0x80008000);
-
- if (g_soft.DrawSemiTrans && (color & 0x80008000)) {
- if (g_soft.GlobalTextABR == 0) {
- r = ((((X32TCOL1(GETLE32(pdest)))
- + ((X32COL1(color)) * g_soft.g_m1)) & 0xFF00FF00) >> 8);
- b = ((((X32TCOL2(GETLE32(pdest)))
- + ((X32COL2(color)) * g_soft.g_m2)) & 0xFF00FF00) >> 8);
- g = ((((X32TCOL3(GETLE32(pdest)))
- + ((X32COL3(color)) * g_soft.g_m3)) & 0xFF00FF00) >> 8);
- } else if (g_soft.GlobalTextABR == 1) {
- r = (X32COL1(GETLE32(pdest)))
- + (((((X32COL1(color))) * g_soft.g_m1) & 0xFF80FF80) >> 7);
- b = (X32COL2(GETLE32(pdest)))
- + (((((X32COL2(color))) * g_soft.g_m2) & 0xFF80FF80) >> 7);
- g = (X32COL3(GETLE32(pdest)))
- + (((((X32COL3(color))) * g_soft.g_m3) & 0xFF80FF80) >> 7);
- } else if (g_soft.GlobalTextABR == 2) {
- int32_t t;
- r = (((((X32COL1(color))) * g_soft.g_m1) & 0xFF80FF80) >> 7);
- t = (GETLE32(pdest) & 0x001f0000) - (r & 0x003f0000);
- if (t & 0x80000000)
- t = 0;
- r = (GETLE32(pdest) & 0x0000001f) - (r & 0x0000003f);
- if (r & 0x80000000)
- r = 0;
- r |= t;
-
- b = (((((X32COL2(color))) * g_soft.g_m2) & 0xFF80FF80) >> 7);
- t = ((GETLE32(pdest) >> 5) & 0x001f0000) - (b & 0x003f0000);
- if (t & 0x80000000)
- t = 0;
- b = ((GETLE32(pdest) >> 5) & 0x0000001f) - (b & 0x0000003f);
- if (b & 0x80000000)
- b = 0;
- b |= t;
-
- g = (((((X32COL3(color))) * g_soft.g_m3) & 0xFF80FF80) >> 7);
- t = ((GETLE32(pdest) >> 10) & 0x001f0000) - (g & 0x003f0000);
- if (t & 0x80000000)
- t = 0;
- g = ((GETLE32(pdest) >> 10) & 0x0000001f) - (g & 0x0000003f);
- if (g & 0x80000000)
- g = 0;
- g |= t;
- } else {
-#ifdef HALFBRIGHTMODE3
- r = (X32COL1(GETLE32(pdest))) + (((((X32BCOL1(color)) >> 2)
- * g_soft.g_m1) & 0xFF80FF80) >> 7);
- b = (X32COL2(GETLE32(pdest))) + (((((X32BCOL2(color)) >> 2)
- * g_soft.g_m2) & 0xFF80FF80) >> 7);
- g = (X32COL3(GETLE32(pdest))) + (((((X32BCOL3(color)) >> 2)
- * g_soft.g_m3) & 0xFF80FF80) >> 7);
-#else
- r=(X32COL1(GETLE32(pdest)))+(((((X32ACOL1(color))>>1)* g_soft.g_m1)&0xFF80FF80)>>7);
- b=(X32COL2(GETLE32(pdest)))+(((((X32ACOL2(color))>>1)* g_soft.g_m2)&0xFF80FF80)>>7);
- g=(X32COL3(GETLE32(pdest)))+(((((X32ACOL3(color))>>1)* g_soft.g_m3)&0xFF80FF80)>>7);
-#endif
- }
-
- if (!(color & 0x8000)) {
- r = (r & 0xffff0000) | ((((X32COL1(color)) * g_soft.g_m1)
- & 0x0000FF80) >> 7);
- b = (b & 0xffff0000) | ((((X32COL2(color)) * g_soft.g_m2)
- & 0x0000FF80) >> 7);
- g = (g & 0xffff0000) | ((((X32COL3(color)) * g_soft.g_m3)
- & 0x0000FF80) >> 7);
- }
- if (!(color & 0x80000000)) {
- r = (r & 0xffff) | ((((X32COL1(color)) * g_soft.g_m1) & 0xFF800000)
- >> 7);
- b = (b & 0xffff) | ((((X32COL2(color)) * g_soft.g_m2) & 0xFF800000)
- >> 7);
- g = (g & 0xffff) | ((((X32COL3(color)) * g_soft.g_m3) & 0xFF800000)
- >> 7);
- }
-
- } else {
- r = (((X32COL1(color)) * g_soft.g_m1) & 0xFF80FF80) >> 7;
- b = (((X32COL2(color)) * g_soft.g_m2) & 0xFF80FF80) >> 7;
- g = (((X32COL3(color)) * g_soft.g_m3) & 0xFF80FF80) >> 7;
- }
-
- if (r & 0x7FE00000)
- r = 0x1f0000 | (r & 0xFFFF);
- if (r & 0x7FE0)
- r = 0x1f | (r & 0xFFFF0000);
- if (b & 0x7FE00000)
- b = 0x1f0000 | (b & 0xFFFF);
- if (b & 0x7FE0)
- b = 0x1f | (b & 0xFFFF0000);
- if (g & 0x7FE00000)
- g = 0x1f0000 | (g & 0xFFFF);
- if (g & 0x7FE0)
- g = 0x1f | (g & 0xFFFF0000);
-
- if (g_draw.bCheckMask) {
- uint32_t ma = GETLE32(pdest);
-
- PUTLE32(pdest, (X32PSXCOL(r,g,b))|l);
-
- if ((color & 0xffff) == 0)
- PUTLE32(pdest, (ma&0xffff)|(GETLE32(pdest)&0xffff0000));
- if ((color & 0xffff0000) == 0)
- PUTLE32(pdest, (ma&0xffff0000)|(GETLE32(pdest)&0xffff));
- if (ma & 0x80000000)
- PUTLE32(pdest, (ma&0xFFFF0000)|(GETLE32(pdest)&0xFFFF));
- if (ma & 0x00008000)
- PUTLE32(pdest, (ma&0xFFFF) |(GETLE32(pdest)&0xFFFF0000));
-
- return;
- }
- if ((color & 0xffff) == 0) {
- PUTLE32(pdest, (GETLE32(pdest)&0xffff)|(((X32PSXCOL(r,g,b))|l)&0xffff0000));
- return;
- }
- if ((color & 0xffff0000) == 0) {
- PUTLE32(pdest, (GETLE32(pdest)&0xffff0000)|(((X32PSXCOL(r,g,b))|l)&0xffff));
- return;
- }
-
- PUTLE32(pdest, (X32PSXCOL(r,g,b))|l);
-}
-
-////////////////////////////////////////////////////////////////////////
-
-static inline void GetTextureTransColG32_S(uint32_t * pdest, uint32_t color) {
- int32_t r, g, b;
-
- if (color == 0)
- return;
-
- r = (((X32COL1(color)) * g_soft.g_m1) & 0xFF80FF80) >> 7;
- b = (((X32COL2(color)) * g_soft.g_m2) & 0xFF80FF80) >> 7;
- g = (((X32COL3(color)) * g_soft.g_m3) & 0xFF80FF80) >> 7;
-
- if (r & 0x7FE00000)
- r = 0x1f0000 | (r & 0xFFFF);
- if (r & 0x7FE0)
- r = 0x1f | (r & 0xFFFF0000);
- if (b & 0x7FE00000)
- b = 0x1f0000 | (b & 0xFFFF);
- if (b & 0x7FE0)
- b = 0x1f | (b & 0xFFFF0000);
- if (g & 0x7FE00000)
- g = 0x1f0000 | (g & 0xFFFF);
- if (g & 0x7FE0)
- g = 0x1f | (g & 0xFFFF0000);
-
- if ((color & 0xffff) == 0) {
- PUTLE32(pdest, (GETLE32(pdest)&0xffff)|(((X32PSXCOL(r,g,b))|g_draw.lSetMask|(color&0x80008000))&0xffff0000));
- return;
- }
- if ((color & 0xffff0000) == 0) {
- PUTLE32(pdest, (GETLE32(pdest)&0xffff0000)|(((X32PSXCOL(r,g,b))|g_draw.lSetMask|(color&0x80008000))&0xffff));
- return;
- }
-
- PUTLE32(pdest, (X32PSXCOL(r,g,b))|g_draw.lSetMask|(color&0x80008000));
-}
-
-////////////////////////////////////////////////////////////////////////
-
-static inline void GetTextureTransColG32_SPR(uint32_t * pdest, uint32_t color) {
- int32_t r, g, b;
-
- if (color == 0)
- return;
-
- if (g_soft.DrawSemiTrans && (color & 0x80008000)) {
- if (g_soft.GlobalTextABR == 0) {
- r = ((((X32TCOL1(GETLE32(pdest)))
- + ((X32COL1(color)) * g_soft.g_m1)) & 0xFF00FF00) >> 8);
- b = ((((X32TCOL2(GETLE32(pdest)))
- + ((X32COL2(color)) * g_soft.g_m2)) & 0xFF00FF00) >> 8);
- g = ((((X32TCOL3(GETLE32(pdest)))
- + ((X32COL3(color)) * g_soft.g_m3)) & 0xFF00FF00) >> 8);
- } else if (g_soft.GlobalTextABR == 1) {
- r = (X32COL1(GETLE32(pdest)))
- + (((((X32COL1(color))) * g_soft.g_m1) & 0xFF80FF80) >> 7);
- b = (X32COL2(GETLE32(pdest)))
- + (((((X32COL2(color))) * g_soft.g_m2) & 0xFF80FF80) >> 7);
- g = (X32COL3(GETLE32(pdest)))
- + (((((X32COL3(color))) * g_soft.g_m3) & 0xFF80FF80) >> 7);
- } else if (g_soft.GlobalTextABR == 2) {
- int32_t t;
- r = (((((X32COL1(color))) * g_soft.g_m1) & 0xFF80FF80) >> 7);
- t = (GETLE32(pdest) & 0x001f0000) - (r & 0x003f0000);
- if (t & 0x80000000)
- t = 0;
- r = (GETLE32(pdest) & 0x0000001f) - (r & 0x0000003f);
- if (r & 0x80000000)
- r = 0;
- r |= t;
-
- b = (((((X32COL2(color))) * g_soft.g_m2) & 0xFF80FF80) >> 7);
- t = ((GETLE32(pdest) >> 5) & 0x001f0000) - (b & 0x003f0000);
- if (t & 0x80000000)
- t = 0;
- b = ((GETLE32(pdest) >> 5) & 0x0000001f) - (b & 0x0000003f);
- if (b & 0x80000000)
- b = 0;
- b |= t;
-
- g = (((((X32COL3(color))) * g_soft.g_m3) & 0xFF80FF80) >> 7);
- t = ((GETLE32(pdest) >> 10) & 0x001f0000) - (g & 0x003f0000);
- if (t & 0x80000000)
- t = 0;
- g = ((GETLE32(pdest) >> 10) & 0x0000001f) - (g & 0x0000003f);
- if (g & 0x80000000)
- g = 0;
- g |= t;
- } else {
-#ifdef HALFBRIGHTMODE3
- r = (X32COL1(GETLE32(pdest))) + (((((X32BCOL1(color)) >> 2)
- * g_soft.g_m1) & 0xFF80FF80) >> 7);
- b = (X32COL2(GETLE32(pdest))) + (((((X32BCOL2(color)) >> 2)
- * g_soft.g_m2) & 0xFF80FF80) >> 7);
- g = (X32COL3(GETLE32(pdest))) + (((((X32BCOL3(color)) >> 2)
- * g_soft.g_m3) & 0xFF80FF80) >> 7);
-#else
- r=(X32COL1(GETLE32(pdest)))+(((((X32ACOL1(color))>>1)* g_soft.g_m1)&0xFF80FF80)>>7);
- b=(X32COL2(GETLE32(pdest)))+(((((X32ACOL2(color))>>1)* g_soft.g_m2)&0xFF80FF80)>>7);
- g=(X32COL3(GETLE32(pdest)))+(((((X32ACOL3(color))>>1)* g_soft.g_m3)&0xFF80FF80)>>7);
-#endif
- }
-
- if (!(color & 0x8000)) {
- r = (r & 0xffff0000) | ((((X32COL1(color)) * g_soft.g_m1)
- & 0x0000FF80) >> 7);
- b = (b & 0xffff0000) | ((((X32COL2(color)) * g_soft.g_m2)
- & 0x0000FF80) >> 7);
- g = (g & 0xffff0000) | ((((X32COL3(color)) * g_soft.g_m3)
- & 0x0000FF80) >> 7);
- }
- if (!(color & 0x80000000)) {
- r = (r & 0xffff) | ((((X32COL1(color)) * g_soft.g_m1) & 0xFF800000)
- >> 7);
- b = (b & 0xffff) | ((((X32COL2(color)) * g_soft.g_m2) & 0xFF800000)
- >> 7);
- g = (g & 0xffff) | ((((X32COL3(color)) * g_soft.g_m3) & 0xFF800000)
- >> 7);
- }
-
- } else {
- r = (((X32COL1(color)) * g_soft.g_m1) & 0xFF80FF80) >> 7;
- b = (((X32COL2(color)) * g_soft.g_m2) & 0xFF80FF80) >> 7;
- g = (((X32COL3(color)) * g_soft.g_m3) & 0xFF80FF80) >> 7;
- }
-
- if (r & 0x7FE00000)
- r = 0x1f0000 | (r & 0xFFFF);
- if (r & 0x7FE0)
- r = 0x1f | (r & 0xFFFF0000);
- if (b & 0x7FE00000)
- b = 0x1f0000 | (b & 0xFFFF);
- if (b & 0x7FE0)
- b = 0x1f | (b & 0xFFFF0000);
- if (g & 0x7FE00000)
- g = 0x1f0000 | (g & 0xFFFF);
- if (g & 0x7FE0)
- g = 0x1f | (g & 0xFFFF0000);
-
- if (g_draw.bCheckMask) {
- uint32_t ma = GETLE32(pdest);
-
- PUTLE32(pdest, (X32PSXCOL(r,g,b))|g_draw.lSetMask|(color&0x80008000));
-
- if ((color & 0xffff) == 0)
- PUTLE32(pdest, (ma&0xffff)|(GETLE32(pdest)&0xffff0000));
- if ((color & 0xffff0000) == 0)
- PUTLE32(pdest, (ma&0xffff0000)|(GETLE32(pdest)&0xffff));
- if (ma & 0x80000000)
- PUTLE32(pdest, (ma&0xFFFF0000)|(GETLE32(pdest)&0xFFFF));
- if (ma & 0x00008000)
- PUTLE32(pdest, (ma&0xFFFF) |(GETLE32(pdest)&0xFFFF0000));
-
- return;
- }
- if ((color & 0xffff) == 0) {
- PUTLE32(pdest, (GETLE32(pdest)&0xffff)|(((X32PSXCOL(r,g,b))|g_draw.lSetMask|(color&0x80008000))&0xffff0000));
- return;
- }
- if ((color & 0xffff0000) == 0) {
- PUTLE32(pdest, (GETLE32(pdest)&0xffff0000)|(((X32PSXCOL(r,g,b))|g_draw.lSetMask|(color&0x80008000))&0xffff));
- return;
- }
-
- PUTLE32(pdest, (X32PSXCOL(r,g,b))|g_draw.lSetMask|(color&0x80008000));
-}
-
-////////////////////////////////////////////////////////////////////////
-
-static inline void GetTextureTransColGX_Dither(unsigned short * pdest,
- unsigned short color, int32_t m1, int32_t m2, int32_t m3) {
- int32_t r, g, b;
-
- if (color == 0)
- return;
-
- if (g_draw.bCheckMask && (*pdest & HOST2LE16(0x8000)))
- return;
-
- m1 = (((XCOL1D(color))) * m1) >> 4;
- m2 = (((XCOL2D(color))) * m2) >> 4;
- m3 = (((XCOL3D(color))) * m3) >> 4;
-
- if (g_soft.DrawSemiTrans && (color & 0x8000)) {
- r = ((XCOL1D(GETLE16(pdest))) << 3);
- b = ((XCOL2D(GETLE16(pdest))) << 3);
- g = ((XCOL3D(GETLE16(pdest))) << 3);
-
- if (g_soft.GlobalTextABR == 0) {
- r = (r >> 1) + (m1 >> 1);
- b = (b >> 1) + (m2 >> 1);
- g = (g >> 1) + (m3 >> 1);
- } else if (g_soft.GlobalTextABR == 1) {
- r += m1;
- b += m2;
- g += m3;
- } else if (g_soft.GlobalTextABR == 2) {
- r -= m1;
- b -= m2;
- g -= m3;
- if (r & 0x80000000)
- r = 0;
- if (b & 0x80000000)
- b = 0;
- if (g & 0x80000000)
- g = 0;
- } else {
-#ifdef HALFBRIGHTMODE3
- r += (m1 >> 2);
- b += (m2 >> 2);
- g += (m3 >> 2);
-#else
- r+=(m1>>1);
- b+=(m2>>1);
- g+=(m3>>1);
-#endif
- }
- } else {
- r = m1;
- b = m2;
- g = m3;
- }
-
- if (r & 0x7FFFFF00)
- r = 0xff;
- if (b & 0x7FFFFF00)
- b = 0xff;
- if (g & 0x7FFFFF00)
- g = 0xff;
-
- Dither16(pdest, r, b, g, g_draw.sSetMask | (color & 0x8000));
-
-}
-
-////////////////////////////////////////////////////////////////////////
-
-static inline void GetTextureTransColGX(unsigned short * pdest, unsigned short color,
- short m1, short m2, short m3) {
- int32_t r, g, b;
- unsigned short l;
-
- if (color == 0)
- return;
-
- if (g_draw.bCheckMask && (*pdest & HOST2LE16(0x8000)))
- return;
-
- l = g_draw.sSetMask | (color & 0x8000);
-
- if (g_soft.DrawSemiTrans && (color & 0x8000)) {
- if (g_soft.GlobalTextABR == 0) {
- unsigned short d;
- d = (GETLE16(pdest) & 0x7bde) >> 1;
- color = ((color) & 0x7bde) >> 1;
- r = (XCOL1(d)) + ((((XCOL1(color))) * m1) >> 7);
- b = (XCOL2(d)) + ((((XCOL2(color))) * m2) >> 7);
- g = (XCOL3(d)) + ((((XCOL3(color))) * m3) >> 7);
- /*
- r=(XCOL1(*pdest)>>1)+((((XCOL1(color))>>1)* m1)>>7);
- b=(XCOL2(*pdest)>>1)+((((XCOL2(color))>>1)* m2)>>7);
- g=(XCOL3(*pdest)>>1)+((((XCOL3(color))>>1)* m3)>>7);
- */
- } else if (g_soft.GlobalTextABR == 1) {
- r = (XCOL1(GETLE16(pdest))) + ((((XCOL1(color))) * m1) >> 7);
- b = (XCOL2(GETLE16(pdest))) + ((((XCOL2(color))) * m2) >> 7);
- g = (XCOL3(GETLE16(pdest))) + ((((XCOL3(color))) * m3) >> 7);
- } else if (g_soft.GlobalTextABR == 2) {
- r = (XCOL1(GETLE16(pdest))) - ((((XCOL1(color))) * m1) >> 7);
- b = (XCOL2(GETLE16(pdest))) - ((((XCOL2(color))) * m2) >> 7);
- g = (XCOL3(GETLE16(pdest))) - ((((XCOL3(color))) * m3) >> 7);
- if (r & 0x80000000)
- r = 0;
- if (b & 0x80000000)
- b = 0;
- if (g & 0x80000000)
- g = 0;
- } else {
-#ifdef HALFBRIGHTMODE3
- r = (XCOL1(GETLE16(pdest))) + ((((XCOL1(color)) >> 2) * m1) >> 7);
- b = (XCOL2(GETLE16(pdest))) + ((((XCOL2(color)) >> 2) * m2) >> 7);
- g = (XCOL3(GETLE16(pdest))) + ((((XCOL3(color)) >> 2) * m3) >> 7);
-#else
- r=(XCOL1(GETLE16(pdest)))+((((XCOL1(color))>>1)* m1)>>7);
- b=(XCOL2(GETLE16(pdest)))+((((XCOL2(color))>>1)* m2)>>7);
- g=(XCOL3(GETLE16(pdest)))+((((XCOL3(color))>>1)* m3)>>7);
-#endif
- }
- } else {
- r = ((XCOL1(color)) * m1) >> 7;
- b = ((XCOL2(color)) * m2) >> 7;
- g = ((XCOL3(color)) * m3) >> 7;
- }
-
- if (r & 0x7FFFFFE0)
- r = 0x1f;
- if (b & 0x7FFFFC00)
- b = 0x3e0;
- if (g & 0x7FFF8000)
- g = 0x7c00;
-
- PUTLE16(pdest, (XPSXCOL(r,g,b))|l);
-}
-
-////////////////////////////////////////////////////////////////////////
-
-static inline void GetTextureTransColGX_S(unsigned short * pdest,
- unsigned short color, short m1, short m2, short m3) {
- int32_t r, g, b;
-
- if (color == 0)
- return;
-
- r = ((XCOL1(color)) * m1) >> 7;
- b = ((XCOL2(color)) * m2) >> 7;
- g = ((XCOL3(color)) * m3) >> 7;
-
- if (r & 0x7FFFFFE0)
- r = 0x1f;
- if (b & 0x7FFFFC00)
- b = 0x3e0;
- if (g & 0x7FFF8000)
- g = 0x7c00;
-
- PUTLE16(pdest, (XPSXCOL(r,g,b))|g_draw.sSetMask|(color&0x8000));
-}
-
-////////////////////////////////////////////////////////////////////////
-
-static inline void GetTextureTransColGX32_S(uint32_t * pdest, uint32_t color,
- short m1, short m2, short m3) {
- int32_t r, g, b;
-
- if (color == 0)
- return;
-
- r = (((X32COL1(color)) * m1) & 0xFF80FF80) >> 7;
- b = (((X32COL2(color)) * m2) & 0xFF80FF80) >> 7;
- g = (((X32COL3(color)) * m3) & 0xFF80FF80) >> 7;
-
- if (r & 0x7FE00000)
- r = 0x1f0000 | (r & 0xFFFF);
- if (r & 0x7FE0)
- r = 0x1f | (r & 0xFFFF0000);
- if (b & 0x7FE00000)
- b = 0x1f0000 | (b & 0xFFFF);
- if (b & 0x7FE0)
- b = 0x1f | (b & 0xFFFF0000);
- if (g & 0x7FE00000)
- g = 0x1f0000 | (g & 0xFFFF);
- if (g & 0x7FE0)
- g = 0x1f | (g & 0xFFFF0000);
-
- if ((color & 0xffff) == 0) {
- PUTLE32(pdest, (GETLE32(pdest)&0xffff)|(((X32PSXCOL(r,g,b))|g_draw.lSetMask|(color&0x80008000))&0xffff0000));
- return;
- }
- if ((color & 0xffff0000) == 0) {
- PUTLE32(pdest, (GETLE32(pdest)&0xffff0000)|(((X32PSXCOL(r,g,b))|g_draw.lSetMask|(color&0x80008000))&0xffff));
- return;
- }
-
- PUTLE32(pdest, (X32PSXCOL(r,g,b))|g_draw.lSetMask|(color&0x80008000));
-}
-
-////////////////////////////////////////////////////////////////////////
-// FILL FUNCS
-////////////////////////////////////////////////////////////////////////
-
-void FillSoftwareAreaTrans(short x0, short y0, short x1, // FILL AREA TRANS
- short y1, unsigned short col) {
- short j, i, dx, dy;
-
- if (y0 > y1)
- return;
- if (x0 > x1)
- return;
-
- if (x1 < g_prim.drawX)
- return;
- if (y1 < g_prim.drawY)
- return;
- if (x0 > g_prim.drawW)
- return;
- if (y0 > g_prim.drawH)
- return;
-
- x1 = MIN(x1, g_prim.drawW + 1);
- y1 = MIN(y1, g_prim.drawH + 1);
- x0 = MAX(x0, g_prim.drawX);
- y0 = MAX(y0, g_prim.drawY);
-
- if (y0 >= 512)
- return;
- if (x0 > 1023)
- return;
-
- if (y1 > 512)
- y1 = 512;
- if (x1 > 1024)
- x1 = 1024;
-
- dx = x1 - x0;
- dy = y1 - y0;
-
- if (dx == 1 && dy == 1 && x0 == 1020 && y0 == 511) // special fix for pinball game... emu protection???
- {
- /*
- m->v 1020 511 1 1
- writedatamem 0x00000000 1
- tile1 newcol 7fff (orgcol 0xffffff), oldvram 0
- v->m 1020 511 1 1
- readdatamem 0x00007fff 1
- m->v 1020 511 1 1
- writedatamem 0x00000000 1
- tile1 newcol 8000 (orgcol 0xffffff), oldvram 0
- v->m 1020 511 1 1
- readdatamem 0x00008000 1
- */
-
- static int iCheat = 0;
- col += iCheat;
- if (iCheat == 1)
- iCheat = 0;
- else
- iCheat = 1;
- }
-
- if (dx & 1) // slow fill
- {
- unsigned short *DSTPtr;
- unsigned short LineOffset;
- DSTPtr = g_gpu.psx_vram.u16 + (1024 * y0) + x0;
- LineOffset = 1024 - dx;
- for (i = 0; i < dy; i++) {
- for (j = 0; j < dx; j++)
- GetShadeTransCol(DSTPtr++, col);
- DSTPtr += LineOffset;
- }
- } else // fast fill
- {
- uint32_t *DSTPtr;
- unsigned short LineOffset;
- uint32_t lcol = g_draw.lSetMask | (((uint32_t) (col)) << 16) | col;
- dx >>= 1;
- DSTPtr = (uint32_t *) (g_gpu.psx_vram.u16 + (1024 * y0) + x0);
- LineOffset = 512 - dx;
-
- if (!g_draw.bCheckMask && !g_soft.DrawSemiTrans) {
- for (i = 0; i < dy; i++) {
- for (j = 0; j < dx; j++) {
- PUTLE32(DSTPtr, lcol);
- DSTPtr++;
- }
- DSTPtr += LineOffset;
- }
- } else {
- for (i = 0; i < dy; i++) {
- for (j = 0; j < dx; j++)
- GetShadeTransCol32(DSTPtr++, lcol);
- DSTPtr += LineOffset;
- }
- }
- }
-}
-
-////////////////////////////////////////////////////////////////////////
-
-void FillSoftwareArea(short x0, short y0, short x1, // FILL AREA (BLK FILL)
- short y1, unsigned short col) // no draw area check here!
-{
- short j, i, dx, dy;
-
- if (y0 > y1)
- return;
- if (x0 > x1)
- return;
-
- if (y0 >= 512)
- return;
- if (x0 > 1023)
- return;
-
- if (y1 > 512)
- y1 = 512;
- if (x1 > 1024)
- x1 = 1024;
-
- dx = x1 - x0;
- dy = y1 - y0;
- if (dx & 1) {
- unsigned short *DSTPtr;
- unsigned short LineOffset;
-
- DSTPtr = g_gpu.psx_vram.u16 + (1024 * y0) + x0;
- LineOffset = 1024 - dx;
-
- for (i = 0; i < dy; i++) {
- for (j = 0; j < dx; j++) {
- PUTLE16(DSTPtr, col);
- DSTPtr++;
- }
- DSTPtr += LineOffset;
- }
- } else {
- uint32_t *DSTPtr;
- unsigned short LineOffset;
- uint32_t lcol = (((int32_t) col) << 16) | col;
- dx >>= 1;
- DSTPtr = (uint32_t *) (g_gpu.psx_vram.u16 + (1024 * y0) + x0);
- LineOffset = 512 - dx;
-
- for (i = 0; i < dy; i++) {
- for (j = 0; j < dx; j++) {
- PUTLE32(DSTPtr, lcol);
- DSTPtr++;
- }
- DSTPtr += LineOffset;
- }
- }
-}
-
-////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////
-// EDGE INTERPOLATION
-////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////
-
-typedef struct SOFTVTAG {
- int x, y;
- int u, v;
- int32_t R, G, B;
-} soft_vertex;
-
-static soft_vertex vtx[4];
-static soft_vertex * left_array[4], *right_array[4];
-static int left_section, right_section;
-static int left_section_height, right_section_height;
-static int left_x, delta_left_x, right_x, delta_right_x;
-static int left_u, delta_left_u, left_v, delta_left_v;
-static int right_u, delta_right_u, right_v, delta_right_v;
-static int left_R, delta_left_R, right_R, delta_right_R;
-static int left_G, delta_left_G, right_G, delta_right_G;
-static int left_B, delta_left_B, right_B, delta_right_B;
-
-#ifdef USE_NASM
-
-// NASM version (external):
-#define shl10idiv i386_shl10idiv
-
-static inline int shl10idiv(int x, int y);
-
-#else
-
-static inline int shl10idiv(int x, int y) {
- int64_t bi = x;
- bi <<= 10;
- return bi / y;
-}
-
-#endif
-
-#if 0
-
-// GNUC long long int version:
-
-static inline int shl10idiv(int x, int y)
-{
- long long int bi=x;
- bi<<=10;
- return bi/y;
-}
-
-#endif
-
-////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////
-
-static inline int RightSection_F(void) {
- soft_vertex * v1 = right_array[right_section];
- soft_vertex * v2 = right_array[right_section - 1];
-
- int height = v2->y - v1->y;
- if (height == 0)
- return 0;
- delta_right_x = (v2->x - v1->x) / height;
- right_x = v1->x;
-
- right_section_height = height;
- return height;
-}
-
-////////////////////////////////////////////////////////////////////////
-
-static inline int LeftSection_F(void) {
- soft_vertex * v1 = left_array[left_section];
- soft_vertex * v2 = left_array[left_section - 1];
-
- int height = v2->y - v1->y;
- if (height == 0)
- return 0;
- delta_left_x = (v2->x - v1->x) / height;
- left_x = v1->x;
-
- left_section_height = height;
- return height;
-}
-
-////////////////////////////////////////////////////////////////////////
-
-static inline char NextRow_F(void) {
- if (--left_section_height <= 0) {
- if (--left_section <= 0) {
- return 1;
- }
- if (LeftSection_F() <= 0) {
- return 1;
- }
- } else {
- left_x += delta_left_x;
- }
-
- if (--right_section_height <= 0) {
- if (--right_section <= 0) {
- return 1;
- }
- if (RightSection_F() <= 0) {
- return 1;
- }
- } else {
- right_x += delta_right_x;
- }
- return 0;
-}
-
-////////////////////////////////////////////////////////////////////////
-
-static inline char SetupSections_F(short x1, short y1, short x2, short y2, short x3,
- short y3) {
- soft_vertex * v1, *v2, *v3;
- int height, longest;
-
- v1 = vtx;
- v1->x = x1 << 16;
- v1->y = y1;
- v2 = vtx + 1;
- v2->x = x2 << 16;
- v2->y = y2;
- v3 = vtx + 2;
- v3->x = x3 << 16;
- v3->y = y3;
-
- if (v1->y > v2->y) {
- soft_vertex * v = v1;
- v1 = v2;
- v2 = v;
- }
- if (v1->y > v3->y) {
- soft_vertex * v = v1;
- v1 = v3;
- v3 = v;
- }
- if (v2->y > v3->y) {
- soft_vertex * v = v2;
- v2 = v3;
- v3 = v;
- }
-
- height = v3->y - v1->y;
- if (height == 0) {
- return 0;
- }
- longest = (((v2->y - v1->y) << 16) / height) * ((v3->x - v1->x) >> 16)
- + (v1->x - v2->x);
- if (longest == 0) {
- return 0;
- }
-
- if (longest < 0) {
- right_array[0] = v3;
- right_array[1] = v2;
- right_array[2] = v1;
- right_section = 2;
- left_array[0] = v3;
- left_array[1] = v1;
- left_section = 1;
-
- if (LeftSection_F() <= 0)
- return 0;
- if (RightSection_F() <= 0) {
- right_section--;
- if (RightSection_F() <= 0)
- return 0;
- }
- } else {
- left_array[0] = v3;
- left_array[1] = v2;
- left_array[2] = v1;
- left_section = 2;
- right_array[0] = v3;
- right_array[1] = v1;
- right_section = 1;
-
- if (RightSection_F() <= 0)
- return 0;
- if (LeftSection_F() <= 0) {
- left_section--;
- if (LeftSection_F() <= 0)
- return 0;
- }
- }
-
- g_soft.Ymin = v1->y;
- g_soft.Ymax = MIN(v3->y - 1, g_prim.drawH);
-
- return 1;
-}
-
-////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////
-
-static inline int RightSection_G(void) {
- soft_vertex * v1 = right_array[right_section];
- soft_vertex * v2 = right_array[right_section - 1];
-
- int height = v2->y - v1->y;
- if (height == 0)
- return 0;
- delta_right_x = (v2->x - v1->x) / height;
- right_x = v1->x;
-
- right_section_height = height;
- return height;
-}
-
-////////////////////////////////////////////////////////////////////////
-
-static inline int LeftSection_G(void) {
- soft_vertex * v1 = left_array[left_section];
- soft_vertex * v2 = left_array[left_section - 1];
-
- int height = v2->y - v1->y;
- if (height == 0)
- return 0;
- delta_left_x = (v2->x - v1->x) / height;
- left_x = v1->x;
-
- delta_left_R = ((v2->R - v1->R)) / height;
- left_R = v1->R;
- delta_left_G = ((v2->G - v1->G)) / height;
- left_G = v1->G;
- delta_left_B = ((v2->B - v1->B)) / height;
- left_B = v1->B;
-
- left_section_height = height;
- return height;
-}
-
-////////////////////////////////////////////////////////////////////////
-
-static inline char NextRow_G(void) {
- if (--left_section_height <= 0) {
- if (--left_section <= 0) {
- return 1;
- }
- if (LeftSection_G() <= 0) {
- return 1;
- }
- } else {
- left_x += delta_left_x;
- left_R += delta_left_R;
- left_G += delta_left_G;
- left_B += delta_left_B;
- }
-
- if (--right_section_height <= 0) {
- if (--right_section <= 0) {
- return 1;
- }
- if (RightSection_G() <= 0) {
- return 1;
- }
- } else {
- right_x += delta_right_x;
- }
- return 0;
-}
-
-////////////////////////////////////////////////////////////////////////
-
-static inline char SetupSections_G(short x1, short y1, short x2, short y2, short x3,
- short y3, int32_t rgb1, int32_t rgb2, int32_t rgb3) {
- soft_vertex * v1, *v2, *v3;
- int height, longest, temp;
-
- v1 = vtx;
- v1->x = x1 << 16;
- v1->y = y1;
- v1->R = (rgb1) & 0x00ff0000;
- v1->G = (rgb1 << 8) & 0x00ff0000;
- v1->B = (rgb1 << 16) & 0x00ff0000;
- v2 = vtx + 1;
- v2->x = x2 << 16;
- v2->y = y2;
- v2->R = (rgb2) & 0x00ff0000;
- v2->G = (rgb2 << 8) & 0x00ff0000;
- v2->B = (rgb2 << 16) & 0x00ff0000;
- v3 = vtx + 2;
- v3->x = x3 << 16;
- v3->y = y3;
- v3->R = (rgb3) & 0x00ff0000;
- v3->G = (rgb3 << 8) & 0x00ff0000;
- v3->B = (rgb3 << 16) & 0x00ff0000;
-
- if (v1->y > v2->y) {
- soft_vertex * v = v1;
- v1 = v2;
- v2 = v;
- }
- if (v1->y > v3->y) {
- soft_vertex * v = v1;
- v1 = v3;
- v3 = v;
- }
- if (v2->y > v3->y) {
- soft_vertex * v = v2;
- v2 = v3;
- v3 = v;
- }
-
- height = v3->y - v1->y;
- if (height == 0) {
- return 0;
- }
- temp = (((v2->y - v1->y) << 16) / height);
- longest = temp * ((v3->x - v1->x) >> 16) + (v1->x - v2->x);
- if (longest == 0) {
- return 0;
- }
-
- if (longest < 0) {
- right_array[0] = v3;
- right_array[1] = v2;
- right_array[2] = v1;
- right_section = 2;
- left_array[0] = v3;
- left_array[1] = v1;
- left_section = 1;
-
- if (LeftSection_G() <= 0)
- return 0;
- if (RightSection_G() <= 0) {
- right_section--;
- if (RightSection_G() <= 0)
- return 0;
- }
- if (longest > -0x1000)
- longest = -0x1000;
- } else {
- left_array[0] = v3;
- left_array[1] = v2;
- left_array[2] = v1;
- left_section = 2;
- right_array[0] = v3;
- right_array[1] = v1;
- right_section = 1;
-
- if (RightSection_G() <= 0)
- return 0;
- if (LeftSection_G() <= 0) {
- left_section--;
- if (LeftSection_G() <= 0)
- return 0;
- }
- if (longest < 0x1000)
- longest = 0x1000;
- }
-
- g_soft.Ymin = v1->y;
- g_soft.Ymax = MIN(v3->y - 1, g_prim.drawH);
-
- delta_right_R = shl10idiv(temp * ((v3->R - v1->R) >> 10) + ((v1->R - v2->R)
- << 6), longest);
- delta_right_G = shl10idiv(temp * ((v3->G - v1->G) >> 10) + ((v1->G - v2->G)
- << 6), longest);
- delta_right_B = shl10idiv(temp * ((v3->B - v1->B) >> 10) + ((v1->B - v2->B)
- << 6), longest);
-
- return 1;
-}
-
-////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////
-
-static inline int RightSection_FT(void) {
- soft_vertex * v1 = right_array[right_section];
- soft_vertex * v2 = right_array[right_section - 1];
-
- int height = v2->y - v1->y;
- if (height == 0)
- return 0;
- delta_right_x = (v2->x - v1->x) / height;
- right_x = v1->x;
-
- right_section_height = height;
- return height;
-}
-
-////////////////////////////////////////////////////////////////////////
-
-static inline int LeftSection_FT(void) {
- soft_vertex * v1 = left_array[left_section];
- soft_vertex * v2 = left_array[left_section - 1];
-
- int height = v2->y - v1->y;
- if (height == 0)
- return 0;
- delta_left_x = (v2->x - v1->x) / height;
- left_x = v1->x;
-
- delta_left_u = ((v2->u - v1->u)) / height;
- left_u = v1->u;
- delta_left_v = ((v2->v - v1->v)) / height;
- left_v = v1->v;
-
- left_section_height = height;
- return height;
-}
-
-////////////////////////////////////////////////////////////////////////
-
-static inline char NextRow_FT(void) {
- if (--left_section_height <= 0) {
- if (--left_section <= 0) {
- return 1;
- }
- if (LeftSection_FT() <= 0) {
- return 1;
- }
- } else {
- left_x += delta_left_x;
- left_u += delta_left_u;
- left_v += delta_left_v;
- }
-
- if (--right_section_height <= 0) {
- if (--right_section <= 0) {
- return 1;
- }
- if (RightSection_FT() <= 0) {
- return 1;
- }
- } else {
- right_x += delta_right_x;
- }
- return 0;
-}
-
-////////////////////////////////////////////////////////////////////////
-
-static inline char SetupSections_FT(short x1, short y1, short x2, short y2, short x3,
- short y3, short tx1, short ty1, short tx2, short ty2, short tx3,
- short ty3) {
- soft_vertex * v1, *v2, *v3;
- int height, longest, temp;
-
- v1 = vtx;
- v1->x = x1 << 16;
- v1->y = y1;
- v1->u = tx1 << 16;
- v1->v = ty1 << 16;
- v2 = vtx + 1;
- v2->x = x2 << 16;
- v2->y = y2;
- v2->u = tx2 << 16;
- v2->v = ty2 << 16;
- v3 = vtx + 2;
- v3->x = x3 << 16;
- v3->y = y3;
- v3->u = tx3 << 16;
- v3->v = ty3 << 16;
-
- if (v1->y > v2->y) {
- soft_vertex * v = v1;
- v1 = v2;
- v2 = v;
- }
- if (v1->y > v3->y) {
- soft_vertex * v = v1;
- v1 = v3;
- v3 = v;
- }
- if (v2->y > v3->y) {
- soft_vertex * v = v2;
- v2 = v3;
- v3 = v;
- }
-
- height = v3->y - v1->y;
- if (height == 0) {
- return 0;
- }
-
- temp = (((v2->y - v1->y) << 16) / height);
- longest = temp * ((v3->x - v1->x) >> 16) + (v1->x - v2->x);
-
- if (longest == 0) {
- return 0;
- }
-
- if (longest < 0) {
- right_array[0] = v3;
- right_array[1] = v2;
- right_array[2] = v1;
- right_section = 2;
- left_array[0] = v3;
- left_array[1] = v1;
- left_section = 1;
-
- if (LeftSection_FT() <= 0)
- return 0;
- if (RightSection_FT() <= 0) {
- right_section--;
- if (RightSection_FT() <= 0)
- return 0;
- }
- if (longest > -0x1000)
- longest = -0x1000;
- } else {
- left_array[0] = v3;
- left_array[1] = v2;
- left_array[2] = v1;
- left_section = 2;
- right_array[0] = v3;
- right_array[1] = v1;
- right_section = 1;
-
- if (RightSection_FT() <= 0)
- return 0;
- if (LeftSection_FT() <= 0) {
- left_section--;
- if (LeftSection_FT() <= 0)
- return 0;
- }
- if (longest < 0x1000)
- longest = 0x1000;
- }
-
- g_soft.Ymin = v1->y;
- g_soft.Ymax = MIN(v3->y - 1, g_prim.drawH);
-
- delta_right_u = shl10idiv(temp * ((v3->u - v1->u) >> 10) + ((v1->u - v2->u)
- << 6), longest);
- delta_right_v = shl10idiv(temp * ((v3->v - v1->v) >> 10) + ((v1->v - v2->v)
- << 6), longest);
-
- /*
- Mmm... adjust neg tex deltas... will sometimes cause slight
- texture distortions
-
- longest>>=16;
- if(longest)
- {
- if(longest<0) longest=-longest;
- if(delta_right_u<0)
- delta_right_u-=delta_right_u/longest;
- if(delta_right_v<0)
- delta_right_v-=delta_right_v/longest;
- }
- */
-
- return 1;
-}
-
-////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////
-
-static inline int RightSection_GT(void) {
- soft_vertex * v1 = right_array[right_section];
- soft_vertex * v2 = right_array[right_section - 1];
-
- int height = v2->y - v1->y;
- if (height == 0)
- return 0;
- delta_right_x = (v2->x - v1->x) / height;
- right_x = v1->x;
-
- right_section_height = height;
- return height;
-}
-
-////////////////////////////////////////////////////////////////////////
-
-static inline int LeftSection_GT(void) {
- soft_vertex * v1 = left_array[left_section];
- soft_vertex * v2 = left_array[left_section - 1];
-
- int height = v2->y - v1->y;
- if (height == 0)
- return 0;
- delta_left_x = (v2->x - v1->x) / height;
- left_x = v1->x;
-
- delta_left_u = ((v2->u - v1->u)) / height;
- left_u = v1->u;
- delta_left_v = ((v2->v - v1->v)) / height;
- left_v = v1->v;
-
- delta_left_R = ((v2->R - v1->R)) / height;
- left_R = v1->R;
- delta_left_G = ((v2->G - v1->G)) / height;
- left_G = v1->G;
- delta_left_B = ((v2->B - v1->B)) / height;
- left_B = v1->B;
-
- left_section_height = height;
- return height;
-}
-
-////////////////////////////////////////////////////////////////////////
-
-static inline char NextRow_GT(void) {
- if (--left_section_height <= 0) {
- if (--left_section <= 0) {
- return 1;
- }
- if (LeftSection_GT() <= 0) {
- return 1;
- }
- } else {
- left_x += delta_left_x;
- left_u += delta_left_u;
- left_v += delta_left_v;
- left_R += delta_left_R;
- left_G += delta_left_G;
- left_B += delta_left_B;
- }
-
- if (--right_section_height <= 0) {
- if (--right_section <= 0) {
- return 1;
- }
- if (RightSection_GT() <= 0) {
- return 1;
- }
- } else {
- right_x += delta_right_x;
- }
- return 0;
-}
-
-////////////////////////////////////////////////////////////////////////
-
-static inline char SetupSections_GT(short x1, short y1, short x2, short y2, short x3,
- short y3, short tx1, short ty1, short tx2, short ty2, short tx3,
- short ty3, int32_t rgb1, int32_t rgb2, int32_t rgb3) {
- soft_vertex * v1, *v2, *v3;
- int height, longest, temp;
-
- v1 = vtx;
- v1->x = x1 << 16;
- v1->y = y1;
- v1->u = tx1 << 16;
- v1->v = ty1 << 16;
- v1->R = (rgb1) & 0x00ff0000;
- v1->G = (rgb1 << 8) & 0x00ff0000;
- v1->B = (rgb1 << 16) & 0x00ff0000;
-
- v2 = vtx + 1;
- v2->x = x2 << 16;
- v2->y = y2;
- v2->u = tx2 << 16;
- v2->v = ty2 << 16;
- v2->R = (rgb2) & 0x00ff0000;
- v2->G = (rgb2 << 8) & 0x00ff0000;
- v2->B = (rgb2 << 16) & 0x00ff0000;
-
- v3 = vtx + 2;
- v3->x = x3 << 16;
- v3->y = y3;
- v3->u = tx3 << 16;
- v3->v = ty3 << 16;
- v3->R = (rgb3) & 0x00ff0000;
- v3->G = (rgb3 << 8) & 0x00ff0000;
- v3->B = (rgb3 << 16) & 0x00ff0000;
-
- if (v1->y > v2->y) {
- soft_vertex * v = v1;
- v1 = v2;
- v2 = v;
- }
- if (v1->y > v3->y) {
- soft_vertex * v = v1;
- v1 = v3;
- v3 = v;
- }
- if (v2->y > v3->y) {
- soft_vertex * v = v2;
- v2 = v3;
- v3 = v;
- }
-
- height = v3->y - v1->y;
- if (height == 0) {
- return 0;
- }
-
- temp = (((v2->y - v1->y) << 16) / height);
- longest = temp * ((v3->x - v1->x) >> 16) + (v1->x - v2->x);
-
- if (longest == 0) {
- return 0;
- }
-
- if (longest < 0) {
- right_array[0] = v3;
- right_array[1] = v2;
- right_array[2] = v1;
- right_section = 2;
- left_array[0] = v3;
- left_array[1] = v1;
- left_section = 1;
-
- if (LeftSection_GT() <= 0)
- return 0;
- if (RightSection_GT() <= 0) {
- right_section--;
- if (RightSection_GT() <= 0)
- return 0;
- }
-
- if (longest > -0x1000)
- longest = -0x1000;
- } else {
- left_array[0] = v3;
- left_array[1] = v2;
- left_array[2] = v1;
- left_section = 2;
- right_array[0] = v3;
- right_array[1] = v1;
- right_section = 1;
-
- if (RightSection_GT() <= 0)
- return 0;
- if (LeftSection_GT() <= 0) {
- left_section--;
- if (LeftSection_GT() <= 0)
- return 0;
- }
- if (longest < 0x1000)
- longest = 0x1000;
- }
-
- g_soft.Ymin = v1->y;
- g_soft.Ymax = MIN(v3->y - 1, g_prim.drawH);
-
- delta_right_R = shl10idiv(temp * ((v3->R - v1->R) >> 10) + ((v1->R - v2->R)
- << 6), longest);
- delta_right_G = shl10idiv(temp * ((v3->G - v1->G) >> 10) + ((v1->G - v2->G)
- << 6), longest);
- delta_right_B = shl10idiv(temp * ((v3->B - v1->B) >> 10) + ((v1->B - v2->B)
- << 6), longest);
-
- delta_right_u = shl10idiv(temp * ((v3->u - v1->u) >> 10) + ((v1->u - v2->u)
- << 6), longest);
- delta_right_v = shl10idiv(temp * ((v3->v - v1->v) >> 10) + ((v1->v - v2->v)
- << 6), longest);
-
- /*
- Mmm... adjust neg tex deltas... will sometimes cause slight
- texture distortions
- longest>>=16;
- if(longest)
- {
- if(longest<0) longest=-longest;
- if(delta_right_u<0)
- delta_right_u-=delta_right_u/longest;
- if(delta_right_v<0)
- delta_right_v-=delta_right_v/longest;
- }
- */
-
- return 1;
-}
-
-////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////
-
-static inline int RightSection_F4(void) {
- soft_vertex * v1 = right_array[right_section];
- soft_vertex * v2 = right_array[right_section - 1];
-
- int height = v2->y - v1->y;
- right_section_height = height;
- right_x = v1->x;
- if (height == 0) {
- return 0;
- }
- delta_right_x = (v2->x - v1->x) / height;
-
- return height;
-}
-
-////////////////////////////////////////////////////////////////////////
-
-static inline int LeftSection_F4(void) {
- soft_vertex * v1 = left_array[left_section];
- soft_vertex * v2 = left_array[left_section - 1];
-
- int height = v2->y - v1->y;
- left_section_height = height;
- left_x = v1->x;
- if (height == 0) {
- return 0;
- }
- delta_left_x = (v2->x - v1->x) / height;
-
- return height;
-}
-
-////////////////////////////////////////////////////////////////////////
-
-static inline char NextRow_F4(void) {
- if (--left_section_height <= 0) {
- if (--left_section > 0)
- while (LeftSection_F4() <= 0) {
- if (--left_section <= 0)
- break;
- }
- } else {
- left_x += delta_left_x;
- }
-
- if (--right_section_height <= 0) {
- if (--right_section > 0)
- while (RightSection_F4() <= 0) {
- if (--right_section <= 0)
- break;
- }
- } else {
- right_x += delta_right_x;
- }
- return 0;
-}
-
-////////////////////////////////////////////////////////////////////////
-
-static inline char SetupSections_F4(short x1, short y1, short x2, short y2, short x3,
- short y3, short x4, short y4) {
- soft_vertex * v1, *v2, *v3, *v4;
- int height, width, longest1, longest2;
-
- v1 = vtx;
- v1->x = x1 << 16;
- v1->y = y1;
- v2 = vtx + 1;
- v2->x = x2 << 16;
- v2->y = y2;
- v3 = vtx + 2;
- v3->x = x3 << 16;
- v3->y = y3;
- v4 = vtx + 3;
- v4->x = x4 << 16;
- v4->y = y4;
-
- if (v1->y > v2->y) {
- soft_vertex * v = v1;
- v1 = v2;
- v2 = v;
- }
- if (v1->y > v3->y) {
- soft_vertex * v = v1;
- v1 = v3;
- v3 = v;
- }
- if (v1->y > v4->y) {
- soft_vertex * v = v1;
- v1 = v4;
- v4 = v;
- }
- if (v2->y > v3->y) {
- soft_vertex * v = v2;
- v2 = v3;
- v3 = v;
- }
- if (v2->y > v4->y) {
- soft_vertex * v = v2;
- v2 = v4;
- v4 = v;
- }
- if (v3->y > v4->y) {
- soft_vertex * v = v3;
- v3 = v4;
- v4 = v;
- }
-
- height = v4->y - v1->y;
- if (height == 0)
- height = 1;
- width = (v4->x - v1->x) >> 16;
- longest1 = (((v2->y - v1->y) << 16) / height) * width + (v1->x - v2->x);
- longest2 = (((v3->y - v1->y) << 16) / height) * width + (v1->x - v3->x);
-
- if (longest1 < 0) // 2 is right
- {
- if (longest2 < 0) // 3 is right
- {
- left_array[0] = v4;
- left_array[1] = v1;
- left_section = 1;
-
- height = v3->y - v1->y;
- if (height == 0)
- height = 1;
- longest1 = (((v2->y - v1->y) << 16) / height) * ((v3->x - v1->x)
- >> 16) + (v1->x - v2->x);
- if (longest1 >= 0) {
- right_array[0] = v4; // 1
- right_array[1] = v3; // 3
- right_array[2] = v1; // 4
- right_section = 2;
- } else {
- height = v4->y - v2->y;
- if (height == 0)
- height = 1;
- longest1 = (((v3->y - v2->y) << 16) / height)
- * ((v4->x - v2->x) >> 16) + (v2->x - v3->x);
- if (longest1 >= 0) {
- right_array[0] = v4; // 1
- right_array[1] = v2; // 2
- right_array[2] = v1; // 4
- right_section = 2;
- } else {
- right_array[0] = v4; // 1
- right_array[1] = v3; // 2
- right_array[2] = v2; // 3
- right_array[3] = v1; // 4
- right_section = 3;
- }
- }
- } else {
- left_array[0] = v4;
- left_array[1] = v3; // 1
- left_array[2] = v1; // 2
- left_section = 2; // 3
- right_array[0] = v4; // 4
- right_array[1] = v2;
- right_array[2] = v1;
- right_section = 2;
- }
- } else {
- if (longest2 < 0) {
- left_array[0] = v4; // 1
- left_array[1] = v2; // 2
- left_array[2] = v1; // 3
- left_section = 2; // 4
- right_array[0] = v4;
- right_array[1] = v3;
- right_array[2] = v1;
- right_section = 2;
- } else {
- right_array[0] = v4;
- right_array[1] = v1;
- right_section = 1;
-
- height = v3->y - v1->y;
- if (height == 0)
- height = 1;
- longest1 = (((v2->y - v1->y) << 16) / height) * ((v3->x - v1->x)
- >> 16) + (v1->x - v2->x);
- if (longest1 < 0) {
- left_array[0] = v4; // 1
- left_array[1] = v3; // 3
- left_array[2] = v1; // 4
- left_section = 2;
- } else {
- height = v4->y - v2->y;
- if (height == 0)
- height = 1;
- longest1 = (((v3->y - v2->y) << 16) / height)
- * ((v4->x - v2->x) >> 16) + (v2->x - v3->x);
- if (longest1 < 0) {
- left_array[0] = v4; // 1
- left_array[1] = v2; // 2
- left_array[2] = v1; // 4
- left_section = 2;
- } else {
- left_array[0] = v4; // 1
- left_array[1] = v3; // 2
- left_array[2] = v2; // 3
- left_array[3] = v1; // 4
- left_section = 3;
- }
- }
- }
- }
-
- while (LeftSection_F4() <= 0) {
- if (--left_section <= 0)
- break;
- }
-
- while (RightSection_F4() <= 0) {
- if (--right_section <= 0)
- break;
- }
-
- g_soft.Ymin = v1->y;
- g_soft.Ymax = MIN(v4->y - 1, g_prim.drawH);
-
- return 1;
-}
-
-////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////
-
-static inline int RightSection_FT4(void) {
- soft_vertex * v1 = right_array[right_section];
- soft_vertex * v2 = right_array[right_section - 1];
-
- int height = v2->y - v1->y;
- right_section_height = height;
- right_x = v1->x;
- right_u = v1->u;
- right_v = v1->v;
- if (height == 0) {
- return 0;
- }
- delta_right_x = (v2->x - v1->x) / height;
- delta_right_u = (v2->u - v1->u) / height;
- delta_right_v = (v2->v - v1->v) / height;
-
- return height;
-}
-
-////////////////////////////////////////////////////////////////////////
-
-static inline int LeftSection_FT4(void) {
- soft_vertex * v1 = left_array[left_section];
- soft_vertex * v2 = left_array[left_section - 1];
-
- int height = v2->y - v1->y;
- left_section_height = height;
- left_x = v1->x;
- left_u = v1->u;
- left_v = v1->v;
- if (height == 0) {
- return 0;
- }
- delta_left_x = (v2->x - v1->x) / height;
- delta_left_u = (v2->u - v1->u) / height;
- delta_left_v = (v2->v - v1->v) / height;
-
- return height;
-}
-
-////////////////////////////////////////////////////////////////////////
-
-static inline char NextRow_FT4(void) {
- if (--left_section_height <= 0) {
- if (--left_section > 0)
- while (LeftSection_FT4() <= 0) {
- if (--left_section <= 0)
- break;
- }
- } else {
- left_x += delta_left_x;
- left_u += delta_left_u;
- left_v += delta_left_v;
- }
-
- if (--right_section_height <= 0) {
- if (--right_section > 0)
- while (RightSection_FT4() <= 0) {
- if (--right_section <= 0)
- break;
- }
- } else {
- right_x += delta_right_x;
- right_u += delta_right_u;
- right_v += delta_right_v;
- }
- return 0;
-}
-
-////////////////////////////////////////////////////////////////////////
-
-static inline char SetupSections_FT4(short x1, short y1, short x2, short y2, short x3,
- short y3, short x4, short y4, short tx1, short ty1, short tx2,
- short ty2, short tx3, short ty3, short tx4, short ty4) {
- soft_vertex * v1, *v2, *v3, *v4;
- int height, width, longest1, longest2;
-
- v1 = vtx;
- v1->x = x1 << 16;
- v1->y = y1;
- v1->u = tx1 << 16;
- v1->v = ty1 << 16;
-
- v2 = vtx + 1;
- v2->x = x2 << 16;
- v2->y = y2;
- v2->u = tx2 << 16;
- v2->v = ty2 << 16;
-
- v3 = vtx + 2;
- v3->x = x3 << 16;
- v3->y = y3;
- v3->u = tx3 << 16;
- v3->v = ty3 << 16;
-
- v4 = vtx + 3;
- v4->x = x4 << 16;
- v4->y = y4;
- v4->u = tx4 << 16;
- v4->v = ty4 << 16;
-
- if (v1->y > v2->y) {
- soft_vertex * v = v1;
- v1 = v2;
- v2 = v;
- }
- if (v1->y > v3->y) {
- soft_vertex * v = v1;
- v1 = v3;
- v3 = v;
- }
- if (v1->y > v4->y) {
- soft_vertex * v = v1;
- v1 = v4;
- v4 = v;
- }
- if (v2->y > v3->y) {
- soft_vertex * v = v2;
- v2 = v3;
- v3 = v;
- }
- if (v2->y > v4->y) {
- soft_vertex * v = v2;
- v2 = v4;
- v4 = v;
- }
- if (v3->y > v4->y) {
- soft_vertex * v = v3;
- v3 = v4;
- v4 = v;
- }
-
- height = v4->y - v1->y;
- if (height == 0)
- height = 1;
- width = (v4->x - v1->x) >> 16;
- longest1 = (((v2->y - v1->y) << 16) / height) * width + (v1->x - v2->x);
- longest2 = (((v3->y - v1->y) << 16) / height) * width + (v1->x - v3->x);
-
- if (longest1 < 0) // 2 is right
- {
- if (longest2 < 0) // 3 is right
- {
- left_array[0] = v4;
- left_array[1] = v1;
- left_section = 1;
-
- height = v3->y - v1->y;
- if (height == 0)
- height = 1;
- longest1 = (((v2->y - v1->y) << 16) / height) * ((v3->x - v1->x)
- >> 16) + (v1->x - v2->x);
- if (longest1 >= 0) {
- right_array[0] = v4; // 1
- right_array[1] = v3; // 3
- right_array[2] = v1; // 4
- right_section = 2;
- } else {
- height = v4->y - v2->y;
- if (height == 0)
- height = 1;
- longest1 = (((v3->y - v2->y) << 16) / height)
- * ((v4->x - v2->x) >> 16) + (v2->x - v3->x);
- if (longest1 >= 0) {
- right_array[0] = v4; // 1
- right_array[1] = v2; // 2
- right_array[2] = v1; // 4
- right_section = 2;
- } else {
- right_array[0] = v4; // 1
- right_array[1] = v3; // 2
- right_array[2] = v2; // 3
- right_array[3] = v1; // 4
- right_section = 3;
- }
- }
- } else {
- left_array[0] = v4;
- left_array[1] = v3; // 1
- left_array[2] = v1; // 2
- left_section = 2; // 3
- right_array[0] = v4; // 4
- right_array[1] = v2;
- right_array[2] = v1;
- right_section = 2;
- }
- } else {
- if (longest2 < 0) {
- left_array[0] = v4; // 1
- left_array[1] = v2; // 2
- left_array[2] = v1; // 3
- left_section = 2; // 4
- right_array[0] = v4;
- right_array[1] = v3;
- right_array[2] = v1;
- right_section = 2;
- } else {
- right_array[0] = v4;
- right_array[1] = v1;
- right_section = 1;
-
- height = v3->y - v1->y;
- if (height == 0)
- height = 1;
- longest1 = (((v2->y - v1->y) << 16) / height) * ((v3->x - v1->x)
- >> 16) + (v1->x - v2->x);
- if (longest1 < 0) {
- left_array[0] = v4; // 1
- left_array[1] = v3; // 3
- left_array[2] = v1; // 4
- left_section = 2;
- } else {
- height = v4->y - v2->y;
- if (height == 0)
- height = 1;
- longest1 = (((v3->y - v2->y) << 16) / height)
- * ((v4->x - v2->x) >> 16) + (v2->x - v3->x);
- if (longest1 < 0) {
- left_array[0] = v4; // 1
- left_array[1] = v2; // 2
- left_array[2] = v1; // 4
- left_section = 2;
- } else {
- left_array[0] = v4; // 1
- left_array[1] = v3; // 2
- left_array[2] = v2; // 3
- left_array[3] = v1; // 4
- left_section = 3;
- }
- }
- }
- }
-
- while (LeftSection_FT4() <= 0) {
- if (--left_section <= 0)
- break;
- }
-
- while (RightSection_FT4() <= 0) {
- if (--right_section <= 0)
- break;
- }
-
- g_soft.Ymin = v1->y;
- g_soft.Ymax = MIN(v4->y - 1, g_prim.drawH);
-
- return 1;
-}
-
-////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////
-
-static inline int RightSection_GT4(void) {
- soft_vertex * v1 = right_array[right_section];
- soft_vertex * v2 = right_array[right_section - 1];
-
- int height = v2->y - v1->y;
- right_section_height = height;
- right_x = v1->x;
- right_u = v1->u;
- right_v = v1->v;
- right_R = v1->R;
- right_G = v1->G;
- right_B = v1->B;
-
- if (height == 0) {
- return 0;
- }
- delta_right_x = (v2->x - v1->x) / height;
- delta_right_u = (v2->u - v1->u) / height;
- delta_right_v = (v2->v - v1->v) / height;
- delta_right_R = (v2->R - v1->R) / height;
- delta_right_G = (v2->G - v1->G) / height;
- delta_right_B = (v2->B - v1->B) / height;
-
- return height;
-}
-
-////////////////////////////////////////////////////////////////////////
-
-static inline int LeftSection_GT4(void) {
- soft_vertex * v1 = left_array[left_section];
- soft_vertex * v2 = left_array[left_section - 1];
-
- int height = v2->y - v1->y;
- left_section_height = height;
- left_x = v1->x;
- left_u = v1->u;
- left_v = v1->v;
- left_R = v1->R;
- left_G = v1->G;
- left_B = v1->B;
-
- if (height == 0) {
- return 0;
- }
- delta_left_x = (v2->x - v1->x) / height;
- delta_left_u = (v2->u - v1->u) / height;
- delta_left_v = (v2->v - v1->v) / height;
- delta_left_R = (v2->R - v1->R) / height;
- delta_left_G = (v2->G - v1->G) / height;
- delta_left_B = (v2->B - v1->B) / height;
-
- return height;
-}
-
-////////////////////////////////////////////////////////////////////////
-
-static inline char NextRow_GT4(void) {
- if (--left_section_height <= 0) {
- if (--left_section > 0)
- while (LeftSection_GT4() <= 0) {
- if (--left_section <= 0)
- break;
- }
- } else {
- left_x += delta_left_x;
- left_u += delta_left_u;
- left_v += delta_left_v;
- left_R += delta_left_R;
- left_G += delta_left_G;
- left_B += delta_left_B;
- }
-
- if (--right_section_height <= 0) {
- if (--right_section > 0)
- while (RightSection_GT4() <= 0) {
- if (--right_section <= 0)
- break;
- }
- } else {
- right_x += delta_right_x;
- right_u += delta_right_u;
- right_v += delta_right_v;
- right_R += delta_right_R;
- right_G += delta_right_G;
- right_B += delta_right_B;
- }
- return 0;
-}
-
-////////////////////////////////////////////////////////////////////////
-
-static inline char SetupSections_GT4(short x1, short y1, short x2, short y2, short x3,
- short y3, short x4, short y4, short tx1, short ty1, short tx2,
- short ty2, short tx3, short ty3, short tx4, short ty4, int32_t rgb1,
- int32_t rgb2, int32_t rgb3, int32_t rgb4) {
- soft_vertex * v1, *v2, *v3, *v4;
- int height, width, longest1, longest2;
-
- v1 = vtx;
- v1->x = x1 << 16;
- v1->y = y1;
- v1->u = tx1 << 16;
- v1->v = ty1 << 16;
- v1->R = (rgb1) & 0x00ff0000;
- v1->G = (rgb1 << 8) & 0x00ff0000;
- v1->B = (rgb1 << 16) & 0x00ff0000;
-
- v2 = vtx + 1;
- v2->x = x2 << 16;
- v2->y = y2;
- v2->u = tx2 << 16;
- v2->v = ty2 << 16;
- v2->R = (rgb2) & 0x00ff0000;
- v2->G = (rgb2 << 8) & 0x00ff0000;
- v2->B = (rgb2 << 16) & 0x00ff0000;
-
- v3 = vtx + 2;
- v3->x = x3 << 16;
- v3->y = y3;
- v3->u = tx3 << 16;
- v3->v = ty3 << 16;
- v3->R = (rgb3) & 0x00ff0000;
- v3->G = (rgb3 << 8) & 0x00ff0000;
- v3->B = (rgb3 << 16) & 0x00ff0000;
-
- v4 = vtx + 3;
- v4->x = x4 << 16;
- v4->y = y4;
- v4->u = tx4 << 16;
- v4->v = ty4 << 16;
- v4->R = (rgb4) & 0x00ff0000;
- v4->G = (rgb4 << 8) & 0x00ff0000;
- v4->B = (rgb4 << 16) & 0x00ff0000;
-
- if (v1->y > v2->y) {
- soft_vertex * v = v1;
- v1 = v2;
- v2 = v;
- }
- if (v1->y > v3->y) {
- soft_vertex * v = v1;
- v1 = v3;
- v3 = v;
- }
- if (v1->y > v4->y) {
- soft_vertex * v = v1;
- v1 = v4;
- v4 = v;
- }
- if (v2->y > v3->y) {
- soft_vertex * v = v2;
- v2 = v3;
- v3 = v;
- }
- if (v2->y > v4->y) {
- soft_vertex * v = v2;
- v2 = v4;
- v4 = v;
- }
- if (v3->y > v4->y) {
- soft_vertex * v = v3;
- v3 = v4;
- v4 = v;
- }
-
- height = v4->y - v1->y;
- if (height == 0)
- height = 1;
- width = (v4->x - v1->x) >> 16;
- longest1 = (((v2->y - v1->y) << 16) / height) * width + (v1->x - v2->x);
- longest2 = (((v3->y - v1->y) << 16) / height) * width + (v1->x - v3->x);
-
- if (longest1 < 0) // 2 is right
- {
- if (longest2 < 0) // 3 is right
- {
- left_array[0] = v4;
- left_array[1] = v1;
- left_section = 1;
-
- height = v3->y - v1->y;
- if (height == 0)
- height = 1;
- longest1 = (((v2->y - v1->y) << 16) / height) * ((v3->x - v1->x)
- >> 16) + (v1->x - v2->x);
- if (longest1 >= 0) {
- right_array[0] = v4; // 1
- right_array[1] = v3; // 3
- right_array[2] = v1; // 4
- right_section = 2;
- } else {
- height = v4->y - v2->y;
- if (height == 0)
- height = 1;
- longest1 = (((v3->y - v2->y) << 16) / height)
- * ((v4->x - v2->x) >> 16) + (v2->x - v3->x);
- if (longest1 >= 0) {
- right_array[0] = v4; // 1
- right_array[1] = v2; // 2
- right_array[2] = v1; // 4
- right_section = 2;
- } else {
- right_array[0] = v4; // 1
- right_array[1] = v3; // 2
- right_array[2] = v2; // 3
- right_array[3] = v1; // 4
- right_section = 3;
- }
- }
- } else {
- left_array[0] = v4;
- left_array[1] = v3; // 1
- left_array[2] = v1; // 2
- left_section = 2; // 3
- right_array[0] = v4; // 4
- right_array[1] = v2;
- right_array[2] = v1;
- right_section = 2;
- }
- } else {
- if (longest2 < 0) {
- left_array[0] = v4; // 1
- left_array[1] = v2; // 2
- left_array[2] = v1; // 3
- left_section = 2; // 4
- right_array[0] = v4;
- right_array[1] = v3;
- right_array[2] = v1;
- right_section = 2;
- } else {
- right_array[0] = v4;
- right_array[1] = v1;
- right_section = 1;
-
- height = v3->y - v1->y;
- if (height == 0)
- height = 1;
- longest1 = (((v2->y - v1->y) << 16) / height) * ((v3->x - v1->x)
- >> 16) + (v1->x - v2->x);
- if (longest1 < 0) {
- left_array[0] = v4; // 1
- left_array[1] = v3; // 3
- left_array[2] = v1; // 4
- left_section = 2;
- } else {
- height = v4->y - v2->y;
- if (height == 0)
- height = 1;
- longest1 = (((v3->y - v2->y) << 16) / height)
- * ((v4->x - v2->x) >> 16) + (v2->x - v3->x);
- if (longest1 < 0) {
- left_array[0] = v4; // 1
- left_array[1] = v2; // 2
- left_array[2] = v1; // 4
- left_section = 2;
- } else {
- left_array[0] = v4; // 1
- left_array[1] = v3; // 2
- left_array[2] = v2; // 3
- left_array[3] = v1; // 4
- left_section = 3;
- }
- }
- }
- }
-
- while (LeftSection_GT4() <= 0) {
- if (--left_section <= 0)
- break;
- }
-
- while (RightSection_GT4() <= 0) {
- if (--right_section <= 0)
- break;
- }
-
- g_soft.Ymin = v1->y;
- g_soft.Ymax = MIN(v4->y - 1, g_prim.drawH);
-
- return 1;
-}
-
-////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////
-// POLY FUNCS
-////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////
-
-////////////////////////////////////////////////////////////////////////
-// POLY 3/4 FLAT SHADED
-////////////////////////////////////////////////////////////////////////
-
-static inline void drawPoly3Fi(short x1, short y1, short x2, short y2, short x3,
- short y3, int32_t rgb) {
- int i, j, xmin, xmax, ymin, ymax;
- unsigned short color;
- uint32_t lcolor;
-
- if (x1 > g_prim.drawW && x2 > g_prim.drawW && x3 > g_prim.drawW)
- return;
- if (y1 > g_prim.drawH && y2 > g_prim.drawH && y3 > g_prim.drawH)
- return;
- if (x1 < g_prim.drawX && x2 < g_prim.drawX && x3 < g_prim.drawX)
- return;
- if (y1 < g_prim.drawY && y2 < g_prim.drawY && y3 < g_prim.drawY)
- return;
- if (g_prim.drawY >= g_prim.drawH)
- return;
- if (g_prim.drawX >= g_prim.drawW)
- return;
-
- if (!SetupSections_F(x1, y1, x2, y2, x3, y3))
- return;
-
- ymax = g_soft.Ymax;
-
- color = ((rgb & 0x00f80000) >> 9) | ((rgb & 0x0000f800) >> 6) | ((rgb
- & 0x000000f8) >> 3);
- lcolor = g_draw.lSetMask | (((uint32_t) (color)) << 16) | color;
-
- for (ymin = g_soft.Ymin; ymin < g_prim.drawY; ymin++)
- if (NextRow_F())
- return;
-
-#ifdef FASTSOLID
-
- if (!g_draw.bCheckMask && !g_soft.DrawSemiTrans) {
- color |= g_draw.sSetMask;
- for (i = ymin; i <= ymax; i++) {
- xmin = left_x >> 16;
- if (g_prim.drawX > xmin)
- xmin = g_prim.drawX;
- xmax = (right_x >> 16) - 1;
- if (g_prim.drawW < xmax)
- xmax = g_prim.drawW;
-
- for (j = xmin; j < xmax; j += 2) {
- PUTLE32(((uint32_t *)&g_gpu.psx_vram.u16[(i<<10)+j]), lcolor);
- }
- if (j == xmax)
- PUTLE16(&g_gpu.psx_vram.u16[(i<<10)+j], color);
-
- if (NextRow_F())
- return;
- }
- return;
- }
-
-#endif
-
- for (i = ymin; i <= ymax; i++) {
- xmin = left_x >> 16;
- if (g_prim.drawX > xmin)
- xmin = g_prim.drawX;
- xmax = (right_x >> 16) - 1;
- if (g_prim.drawW < xmax)
- xmax = g_prim.drawW;
-
- for (j = xmin; j < xmax; j += 2) {
- GetShadeTransCol32((uint32_t *) &g_gpu.psx_vram.u16[(i << 10) + j],
- lcolor);
- }
- if (j == xmax)
- GetShadeTransCol(&g_gpu.psx_vram.u16[(i << 10) + j], color);
-
- if (NextRow_F())
- return;
- }
-}
-
-////////////////////////////////////////////////////////////////////////
-
-void drawPoly3F(int32_t rgb) {
- drawPoly3Fi(g_soft.lx0, g_soft.ly0, g_soft.lx1, g_soft.ly1, g_soft.lx2,
- g_soft.ly2, rgb);
-}
-
-#ifdef POLYQUAD3FS
-
-void drawPoly4F_TRI(int32_t rgb)
-{
- drawPog_soft.ly3Fi(g_soft.lx1,g_soft.ly1,g_soft.lx3,g_soft.ly3,g_soft.lx2,g_soft.ly2,rgb);
- drawPog_soft.ly3Fi(g_soft.lx0,g_soft.ly0,g_soft.lx1,g_soft.ly1,g_soft.lx2,g_soft.ly2,rgb);
-}
-
-#endif
-
-// more exact:
-
-void drawPoly4F(int32_t rgb) {
- int i, j, xmin, xmax, ymin, ymax;
- unsigned short color;
- uint32_t lcolor;
-
- if (g_soft.lx0 > g_prim.drawW && g_soft.lx1 > g_prim.drawW && g_soft.lx2
- > g_prim.drawW && g_soft.lx3 > g_prim.drawW)
- return;
- if (g_soft.ly0 > g_prim.drawH && g_soft.ly1 > g_prim.drawH && g_soft.ly2
- > g_prim.drawH && g_soft.ly3 > g_prim.drawH)
- return;
- if (g_soft.lx0 < g_prim.drawX && g_soft.lx1 < g_prim.drawX && g_soft.lx2
- < g_prim.drawX && g_soft.lx3 < g_prim.drawX)
- return;
- if (g_soft.ly0 < g_prim.drawY && g_soft.ly1 < g_prim.drawY && g_soft.ly2
- < g_prim.drawY && g_soft.ly3 < g_prim.drawY)
- return;
- if (g_prim.drawY >= g_prim.drawH)
- return;
- if (g_prim.drawX >= g_prim.drawW)
- return;
-
- if (!SetupSections_F4(g_soft.lx0, g_soft.ly0, g_soft.lx1, g_soft.ly1,
- g_soft.lx2, g_soft.ly2, g_soft.lx3, g_soft.ly3))
- return;
-
- ymax = g_soft.Ymax;
-
- for (ymin = g_soft.Ymin; ymin < g_prim.drawY; ymin++)
- if (NextRow_F4())
- return;
-
- color = ((rgb & 0x00f80000) >> 9) | ((rgb & 0x0000f800) >> 6) | ((rgb
- & 0x000000f8) >> 3);
- lcolor = g_draw.lSetMask | (((uint32_t) (color)) << 16) | color;
-
-#ifdef FASTSOLID
-
- if (!g_draw.bCheckMask && !g_soft.DrawSemiTrans) {
- color |= g_draw.sSetMask;
- for (i = ymin; i <= ymax; i++) {
- xmin = left_x >> 16;
- if (g_prim.drawX > xmin)
- xmin = g_prim.drawX;
- xmax = (right_x >> 16) - 1;
- if (g_prim.drawW < xmax)
- xmax = g_prim.drawW;
-
- for (j = xmin; j < xmax; j += 2) {
- PUTLE32(((uint32_t *)&g_gpu.psx_vram.u16[(i<<10)+j]), lcolor);
- }
- if (j == xmax)
- PUTLE16(&g_gpu.psx_vram.u16[(i<<10)+j], color);
-
- if (NextRow_F4())
- return;
- }
- return;
- }
-
-#endif
-
- for (i = ymin; i <= ymax; i++) {
- xmin = left_x >> 16;
- if (g_prim.drawX > xmin)
- xmin = g_prim.drawX;
- xmax = (right_x >> 16) - 1;
- if (g_prim.drawW < xmax)
- xmax = g_prim.drawW;
-
- for (j = xmin; j < xmax; j += 2) {
- GetShadeTransCol32((uint32_t *) &g_gpu.psx_vram.u16[(i << 10) + j],
- lcolor);
- }
- if (j == xmax)
- GetShadeTransCol(&g_gpu.psx_vram.u16[(i << 10) + j], color);
-
- if (NextRow_F4())
- return;
- }
-}
-
-////////////////////////////////////////////////////////////////////////
-// POLY 3/4 F-SHADED TEX PAL 4
-////////////////////////////////////////////////////////////////////////
-
-static void drawPoly3TEx4(short x1, short y1, short x2, short y2, short x3, short y3,
- short tx1, short ty1, short tx2, short ty2, short tx3, short ty3,
- short clX, short clY) {
- int i, j, xmin, xmax, ymin, ymax;
- int32_t difX, difY, difX2, difY2;
- int32_t posX, posY, YAdjust, XAdjust;
- int32_t clutP;
- short tC1, tC2;
-
- if (x1 > g_prim.drawW && x2 > g_prim.drawW && x3 > g_prim.drawW)
- return;
- if (y1 > g_prim.drawH && y2 > g_prim.drawH && y3 > g_prim.drawH)
- return;
- if (x1 < g_prim.drawX && x2 < g_prim.drawX && x3 < g_prim.drawX)
- return;
- if (y1 < g_prim.drawY && y2 < g_prim.drawY && y3 < g_prim.drawY)
- return;
- if (g_prim.drawY >= g_prim.drawH)
- return;
- if (g_prim.drawX >= g_prim.drawW)
- return;
-
- if (!SetupSections_FT(x1, y1, x2, y2, x3, y3, tx1, ty1, tx2, ty2, tx3, ty3))
- return;
-
- ymax = g_soft.Ymax;
-
- for (ymin = g_soft.Ymin; ymin < g_prim.drawY; ymin++)
- if (NextRow_FT())
- return;
-
- clutP = (clY << 10) + clX;
-
- YAdjust = ((g_soft.GlobalTextAddrY) << 11) + (g_soft.GlobalTextAddrX << 1);
-
- difX = delta_right_u;
- difX2 = difX << 1;
- difY = delta_right_v;
- difY2 = difY << 1;
-
-#ifdef FASTSOLID
-
- if (!g_draw.bCheckMask && !g_soft.DrawSemiTrans) {
- for (i = ymin; i <= ymax; i++) {
- xmin = (left_x >> 16);
- xmax = (right_x >> 16) - 1; //!!!!!!!!!!!!!!!!
- if (g_prim.drawW < xmax)
- xmax = g_prim.drawW;
-
- if (xmax >= xmin) {
- posX = left_u;
- posY = left_v;
-
- if (xmin < g_prim.drawX) {
- j = g_prim.drawX - xmin;
- xmin = g_prim.drawX;
- posX += j * difX;
- posY += j * difY;
- }
-
- for (j = xmin; j < xmax; j += 2) {
- XAdjust = (posX >> 16);
- tC1
- = g_gpu.psx_vram.u8[((posY >> 5)
- & (int32_t) 0xFFFFF800) + YAdjust
- + (XAdjust >> 1)];
- tC1 = (tC1 >> ((XAdjust & 1) << 2)) & 0xf;
- XAdjust = ((posX + difX) >> 16);
- tC2 = g_gpu.psx_vram.u8[(((posY + difY) >> 5)
- & (int32_t) 0xFFFFF800) + YAdjust + (XAdjust >> 1)];
- tC2 = (tC2 >> ((XAdjust & 1) << 2)) & 0xf;
-
- GetTextureTransColG32_S(
- (uint32_t *) &g_gpu.psx_vram.u16[(i << 10) + j],
- GETLE16(&g_gpu.psx_vram.u16[clutP+tC1])
- | ((int32_t) GETLE16(&g_gpu.psx_vram.u16[clutP+tC2]))
- << 16);
-
- posX += difX2;
- posY += difY2;
- }
- if (j == xmax) {
- XAdjust = (posX >> 16);
- tC1
- = g_gpu.psx_vram.u8[((posY >> 5)
- & (int32_t) 0xFFFFF800) + YAdjust
- + (XAdjust >> 1)];
- tC1 = (tC1 >> ((XAdjust & 1) << 2)) & 0xf;
- GetTextureTransColG_S(&g_gpu.psx_vram.u16[(i << 10) + j],
- GETLE16(&g_gpu.psx_vram.u16[clutP+tC1]));
- }
- }
- if (NextRow_FT()) {
- return;
- }
- }
- return;
- }
-
-#endif
-
- for (i = ymin; i <= ymax; i++) {
- xmin = (left_x >> 16);
- xmax = (right_x >> 16) - 1; //!!!!!!!!!!!!!!!!!!
- if (g_prim.drawW < xmax)
- xmax = g_prim.drawW;
-
- if (xmax >= xmin) {
- posX = left_u;
- posY = left_v;
-
- if (xmin < g_prim.drawX) {
- j = g_prim.drawX - xmin;
- xmin = g_prim.drawX;
- posX += j * difX;
- posY += j * difY;
- }
-
- for (j = xmin; j < xmax; j += 2) {
- XAdjust = (posX >> 16);
- tC1 = g_gpu.psx_vram.u8[((posY >> 5) & (int32_t) 0xFFFFF800)
- + YAdjust + (XAdjust >> 1)];
- tC1 = (tC1 >> ((XAdjust & 1) << 2)) & 0xf;
- XAdjust = ((posX + difX) >> 16);
- tC2 = g_gpu.psx_vram.u8[(((posY + difY) >> 5)
- & (int32_t) 0xFFFFF800) + YAdjust + (XAdjust >> 1)];
- tC2 = (tC2 >> ((XAdjust & 1) << 2)) & 0xf;
-
- GetTextureTransColG32(
- (uint32_t *) &g_gpu.psx_vram.u16[(i << 10) + j],
- GETLE16(&g_gpu.psx_vram.u16[clutP+tC1])
- | ((int32_t) GETLE16(&g_gpu.psx_vram.u16[clutP+tC2]))
- << 16);
-
- posX += difX2;
- posY += difY2;
- }
- if (j == xmax) {
- XAdjust = (posX >> 16);
- tC1 = g_gpu.psx_vram.u8[((posY >> 5) & (int32_t) 0xFFFFF800)
- + YAdjust + (XAdjust >> 1)];
- tC1 = (tC1 >> ((XAdjust & 1) << 2)) & 0xf;
- GetTextureTransColG(&g_gpu.psx_vram.u16[(i << 10) + j],
- GETLE16(&g_gpu.psx_vram.u16[clutP+tC1]));
- }
- }
- if (NextRow_FT()) {
- return;
- }
- }
-}
-
-////////////////////////////////////////////////////////////////////////
-
-static void drawPoly3TEx4_IL(short x1, short y1, short x2, short y2, short x3,
- short y3, short tx1, short ty1, short tx2, short ty2, short tx3,
- short ty3, short clX, short clY) {
- int i, j, xmin, xmax, ymin, ymax, n_xi, n_yi, TXV;
- int32_t difX, difY, difX2, difY2;
- int32_t posX, posY, YAdjust, XAdjust;
- int32_t clutP;
- short tC1, tC2;
-
- if (x1 > g_prim.drawW && x2 > g_prim.drawW && x3 > g_prim.drawW)
- return;
- if (y1 > g_prim.drawH && y2 > g_prim.drawH && y3 > g_prim.drawH)
- return;
- if (x1 < g_prim.drawX && x2 < g_prim.drawX && x3 < g_prim.drawX)
- return;
- if (y1 < g_prim.drawY && y2 < g_prim.drawY && y3 < g_prim.drawY)
- return;
- if (g_prim.drawY >= g_prim.drawH)
- return;
- if (g_prim.drawX >= g_prim.drawW)
- return;
-
- if (!SetupSections_FT(x1, y1, x2, y2, x3, y3, tx1, ty1, tx2, ty2, tx3, ty3))
- return;
-
- ymax = g_soft.Ymax;
-
- for (ymin = g_soft.Ymin; ymin < g_prim.drawY; ymin++)
- if (NextRow_FT())
- return;
-
- clutP = (clY << 10) + clX;
-
- YAdjust = (g_soft.GlobalTextAddrY << 10) + g_soft.GlobalTextAddrX;
-
- difX = delta_right_u;
- difX2 = difX << 1;
- difY = delta_right_v;
- difY2 = difY << 1;
-
-#ifdef FASTSOLID
-
- if (!g_draw.bCheckMask && !g_soft.DrawSemiTrans) {
- for (i = ymin; i <= ymax; i++) {
- xmin = (left_x >> 16);
- xmax = (right_x >> 16) - 1;
- if (g_prim.drawW < xmax)
- xmax = g_prim.drawW;
-
- if (xmax >= xmin) {
- posX = left_u;
- posY = left_v;
-
- if (xmin < g_prim.drawX) {
- j = g_prim.drawX - xmin;
- xmin = g_prim.drawX;
- posX += j * difX;
- posY += j * difY;
- }
-
- for (j = xmin; j < xmax; j += 2) {
- XAdjust = (posX >> 16);
-
- TXV = posY >> 16;
- n_xi = ((XAdjust >> 2) & ~0x3c) + ((TXV << 2) & 0x3c);
- n_yi = (TXV & ~0xf) + ((XAdjust >> 4) & 0xf);
-
- tC1
- = (GETLE16(&g_gpu.psx_vram.u16[(n_yi<<10)+YAdjust+n_xi])
- >> ((XAdjust & 0x03) << 2)) & 0x0f;
-
- XAdjust = ((posX + difX) >> 16);
-
- TXV = (posY + difY) >> 16;
- n_xi = ((XAdjust >> 2) & ~0x3c) + ((TXV << 2) & 0x3c);
- n_yi = (TXV & ~0xf) + ((XAdjust >> 4) & 0xf);
-
- tC2
- = (GETLE16(&g_gpu.psx_vram.u16[(n_yi<<10)+YAdjust+n_xi])
- >> ((XAdjust & 0x03) << 2)) & 0x0f;
-
- GetTextureTransColG32_S(
- (uint32_t *) &g_gpu.psx_vram.u16[(i << 10) + j],
- GETLE16(&g_gpu.psx_vram.u16[clutP+tC1])
- | ((int32_t) GETLE16(&g_gpu.psx_vram.u16[clutP+tC2]))
- << 16);
-
- posX += difX2;
- posY += difY2;
- }
- if (j == xmax) {
- XAdjust = (posX >> 16);
-
- TXV = posY >> 16;
- n_xi = ((XAdjust >> 2) & ~0x3c) + ((TXV << 2) & 0x3c);
- n_yi = (TXV & ~0xf) + ((XAdjust >> 4) & 0xf);
-
- tC1
- = (GETLE16(&g_gpu.psx_vram.u16[(n_yi<<10)+YAdjust+n_xi])
- >> ((XAdjust & 0x03) << 2)) & 0x0f;
-
- GetTextureTransColG_S(&g_gpu.psx_vram.u16[(i << 10) + j],
- GETLE16(&g_gpu.psx_vram.u16[clutP+tC1]));
- }
- }
- if (NextRow_FT()) {
- return;
- }
- }
- return;
- }
-
-#endif
-
- for (i = ymin; i <= ymax; i++) {
- xmin = (left_x >> 16);
- xmax = (right_x >> 16) - 1; //!!!!!!!!!!!!!!!!!!
- if (g_prim.drawW < xmax)
- xmax = g_prim.drawW;
-
- if (xmax >= xmin) {
- posX = left_u;
- posY = left_v;
-
- if (xmin < g_prim.drawX) {
- j = g_prim.drawX - xmin;
- xmin = g_prim.drawX;
- posX += j * difX;
- posY += j * difY;
- }
-
- for (j = xmin; j < xmax; j += 2) {
- XAdjust = (posX >> 16);
-
- TXV = posY >> 16;
- n_xi = ((XAdjust >> 2) & ~0x3c) + ((TXV << 2) & 0x3c);
- n_yi = (TXV & ~0xf) + ((XAdjust >> 4) & 0xf);
-
- tC1 = (GETLE16(&g_gpu.psx_vram.u16[(n_yi<<10)+YAdjust+n_xi])
- >> ((XAdjust & 0x03) << 2)) & 0x0f;
-
- XAdjust = ((posX + difX) >> 16);
-
- TXV = (posY + difY) >> 16;
- n_xi = ((XAdjust >> 2) & ~0x3c) + ((TXV << 2) & 0x3c);
- n_yi = (TXV & ~0xf) + ((XAdjust >> 4) & 0xf);
-
- tC2 = (GETLE16(&g_gpu.psx_vram.u16[(n_yi<<10)+YAdjust+n_xi])
- >> ((XAdjust & 0x03) << 2)) & 0x0f;
-
- GetTextureTransColG32(
- (uint32_t *) &g_gpu.psx_vram.u16[(i << 10) + j],
- GETLE16(&g_gpu.psx_vram.u16[clutP+tC1])
- | ((int32_t) GETLE16(&g_gpu.psx_vram.u16[clutP+tC2]))
- << 16);
-
- posX += difX2;
- posY += difY2;
- }
- if (j == xmax) {
- XAdjust = (posX >> 16);
-
- TXV = posY >> 16;
- n_xi = ((XAdjust >> 2) & ~0x3c) + ((TXV << 2) & 0x3c);
- n_yi = (TXV & ~0xf) + ((XAdjust >> 4) & 0xf);
-
- tC1 = (GETLE16(&g_gpu.psx_vram.u16[(n_yi<<10)+YAdjust+n_xi])
- >> ((XAdjust & 0x03) << 2)) & 0x0f;
-
- GetTextureTransColG(&g_gpu.psx_vram.u16[(i << 10) + j],
- GETLE16(&g_gpu.psx_vram.u16[clutP+tC1]));
- }
- }
- if (NextRow_FT()) {
- return;
- }
- }
-}
-
-////////////////////////////////////////////////////////////////////////
-
-static void drawPoly3TEx4_TW(short x1, short y1, short x2, short y2, short x3,
- short y3, short tx1, short ty1, short tx2, short ty2, short tx3,
- short ty3, short clX, short clY) {
- int i, j, xmin, xmax, ymin, ymax;
- int32_t difX, difY, difX2, difY2;
- int32_t posX, posY, YAdjust, XAdjust;
- int32_t clutP;
- short tC1, tC2;
-
- if (x1 > g_prim.drawW && x2 > g_prim.drawW && x3 > g_prim.drawW)
- return;
- if (y1 > g_prim.drawH && y2 > g_prim.drawH && y3 > g_prim.drawH)
- return;
- if (x1 < g_prim.drawX && x2 < g_prim.drawX && x3 < g_prim.drawX)
- return;
- if (y1 < g_prim.drawY && y2 < g_prim.drawY && y3 < g_prim.drawY)
- return;
- if (g_prim.drawY >= g_prim.drawH)
- return;
- if (g_prim.drawX >= g_prim.drawW)
- return;
-
- if (!SetupSections_FT(x1, y1, x2, y2, x3, y3, tx1, ty1, tx2, ty2, tx3, ty3))
- return;
-
- ymax = g_soft.Ymax;
-
- for (ymin = g_soft.Ymin; ymin < g_prim.drawY; ymin++)
- if (NextRow_FT())
- return;
-
- clutP = (clY << 10) + clX;
-
- YAdjust = ((g_soft.GlobalTextAddrY) << 11) + (g_soft.GlobalTextAddrX << 1);
- YAdjust += (g_prim.TWin.Position.y0 << 11) + (g_prim.TWin.Position.x0 >> 1);
-
- difX = delta_right_u;
- difX2 = difX << 1;
- difY = delta_right_v;
- difY2 = difY << 1;
-
-#ifdef FASTSOLID
-
- if (!g_draw.bCheckMask && !g_soft.DrawSemiTrans) {
- for (i = ymin; i <= ymax; i++) {
- xmin = (left_x >> 16);
- xmax = (right_x >> 16);//-1; //!!!!!!!!!!!!!!!!
- if (xmax > xmin)
- xmax--;
-
- if (g_prim.drawW < xmax)
- xmax = g_prim.drawW;
-
- if (xmax >= xmin) {
- posX = left_u;
- posY = left_v;
-
- if (xmin < g_prim.drawX) {
- j = g_prim.drawX - xmin;
- xmin = g_prim.drawX;
- posX += j * difX;
- posY += j * difY;
- }
-
- for (j = xmin; j < xmax; j += 2) {
- XAdjust = (posX >> 16) % g_prim.TWin.Position.x1;
- tC1 = g_gpu.psx_vram.u8[(((posY >> 16)
- % g_prim.TWin.Position.y1) << 11) + YAdjust
- + (XAdjust >> 1)];
- tC1 = (tC1 >> ((XAdjust & 1) << 2)) & 0xf;
- XAdjust = ((posX + difX) >> 16) % g_prim.TWin.Position.x1;
- tC2 = g_gpu.psx_vram.u8[((((posY + difY) >> 16)
- % g_prim.TWin.Position.y1) << 11) + YAdjust
- + (XAdjust >> 1)];
- tC2 = (tC2 >> ((XAdjust & 1) << 2)) & 0xf;
-
- GetTextureTransColG32_S(
- (uint32_t *) &g_gpu.psx_vram.u16[(i << 10) + j],
- GETLE16(&g_gpu.psx_vram.u16[clutP+tC1])
- | ((int32_t) GETLE16(&g_gpu.psx_vram.u16[clutP+tC2]))
- << 16);
-
- posX += difX2;
- posY += difY2;
- }
- if (j == xmax) {
- XAdjust = (posX >> 16) % g_prim.TWin.Position.x1;
- tC1 = g_gpu.psx_vram.u8[(((posY >> 16)
- % g_prim.TWin.Position.y1) << 11) + YAdjust
- + (XAdjust >> 1)];
- tC1 = (tC1 >> ((XAdjust & 1) << 2)) & 0xf;
- GetTextureTransColG_S(&g_gpu.psx_vram.u16[(i << 10) + j],
- GETLE16(&g_gpu.psx_vram.u16[clutP+tC1]));
- }
- }
- if (NextRow_FT()) {
- return;
- }
- }
- return;
- }
-
-#endif
-
- for (i = ymin; i <= ymax; i++) {
- xmin = (left_x >> 16);
- xmax = (right_x >> 16) - 1; //!!!!!!!!!!!!!!!!!!
- if (g_prim.drawW < xmax)
- xmax = g_prim.drawW;
-
- if (xmax >= xmin) {
- posX = left_u;
- posY = left_v;
-
- if (xmin < g_prim.drawX) {
- j = g_prim.drawX - xmin;
- xmin = g_prim.drawX;
- posX += j * difX;
- posY += j * difY;
- }
-
- for (j = xmin; j < xmax; j += 2) {
- XAdjust = (posX >> 16) % g_prim.TWin.Position.x1;
- tC1 = g_gpu.psx_vram.u8[(((posY >> 16)
- % g_prim.TWin.Position.y1) << 11) + YAdjust + (XAdjust
- >> 1)];
- tC1 = (tC1 >> ((XAdjust & 1) << 2)) & 0xf;
- XAdjust = ((posX + difX) >> 16) % g_prim.TWin.Position.x1;
- tC2 = g_gpu.psx_vram.u8[((((posY + difY) >> 16)
- % g_prim.TWin.Position.y1) << 11) + YAdjust + (XAdjust
- >> 1)];
- tC2 = (tC2 >> ((XAdjust & 1) << 2)) & 0xf;
-
- GetTextureTransColG32(
- (uint32_t *) &g_gpu.psx_vram.u16[(i << 10) + j],
- GETLE16(&g_gpu.psx_vram.u16[clutP+tC1])
- | ((int32_t) GETLE16(&g_gpu.psx_vram.u16[clutP+tC2]))
- << 16);
-
- posX += difX2;
- posY += difY2;
- }
- if (j == xmax) {
- XAdjust = (posX >> 16) % g_prim.TWin.Position.x1;
- tC1 = g_gpu.psx_vram.u8[(((posY >> 16)
- % g_prim.TWin.Position.y1) << 11) + YAdjust + (XAdjust
- >> 1)];
- tC1 = (tC1 >> ((XAdjust & 1) << 2)) & 0xf;
- GetTextureTransColG(&g_gpu.psx_vram.u16[(i << 10) + j],
- GETLE16(&g_gpu.psx_vram.u16[clutP+tC1]));
- }
- }
- if (NextRow_FT()) {
- return;
- }
- }
-}
-
-////////////////////////////////////////////////////////////////////////
-
-#ifdef POLYQUAD3
-
-static void drawPoly4TEx4_TRI(short x1, short y1, short x2, short y2, short x3,
- short y3, short x4, short y4, short tx1, short ty1, short tx2,
- short ty2, short tx3, short ty3, short tx4, short ty4, short clX,
- short clY) {
- drawPoly3TEx4(x2, y2, x3, y3, x4, y4, tx2, ty2, tx3, ty3, tx4, ty4, clX,
- clY);
- drawPoly3TEx4(x1, y1, x2, y2, x4, y4, tx1, ty1, tx2, ty2, tx4, ty4, clX,
- clY);
-}
-
-#endif
-
-// more exact:
-
-static void drawPoly4TEx4(short x1, short y1, short x2, short y2, short x3, short y3,
- short x4, short y4, short tx1, short ty1, short tx2, short ty2,
- short tx3, short ty3, short tx4, short ty4, short clX, short clY) {
- int32_t num;
- int32_t i, j, xmin, xmax, ymin, ymax;
- int32_t difX, difY, difX2, difY2;
- int32_t posX, posY, YAdjust, clutP, XAdjust;
- short tC1, tC2;
-
- if (x1 > g_prim.drawW && x2 > g_prim.drawW && x3 > g_prim.drawW && x4
- > g_prim.drawW)
- return;
- if (y1 > g_prim.drawH && y2 > g_prim.drawH && y3 > g_prim.drawH && y4
- > g_prim.drawH)
- return;
- if (x1 < g_prim.drawX && x2 < g_prim.drawX && x3 < g_prim.drawX && x4
- < g_prim.drawX)
- return;
- if (y1 < g_prim.drawY && y2 < g_prim.drawY && y3 < g_prim.drawY && y4
- < g_prim.drawY)
- return;
- if (g_prim.drawY >= g_prim.drawH)
- return;
- if (g_prim.drawX >= g_prim.drawW)
- return;
-
- if (!SetupSections_FT4(x1, y1, x2, y2, x3, y3, x4, y4, tx1, ty1, tx2, ty2,
- tx3, ty3, tx4, ty4))
- return;
-
- ymax = g_soft.Ymax;
-
- for (ymin = g_soft.Ymin; ymin < g_prim.drawY; ymin++)
- if (NextRow_FT4())
- return;
-
- clutP = (clY << 10) + clX;
-
- YAdjust = ((g_soft.GlobalTextAddrY) << 11) + (g_soft.GlobalTextAddrX << 1);
-
-#ifdef FASTSOLID
-
- if (!g_draw.bCheckMask && !g_soft.DrawSemiTrans) {
- for (i = ymin; i <= ymax; i++) {
- xmin = (left_x >> 16);
- xmax = (right_x >> 16);
-
- if (xmax >= xmin) {
- posX = left_u;
- posY = left_v;
-
- num = (xmax - xmin);
- if (num == 0)
- num = 1;
- difX = (right_u - posX) / num;
- difY = (right_v - posY) / num;
- difX2 = difX << 1;
- difY2 = difY << 1;
-
- if (xmin < g_prim.drawX) {
- j = g_prim.drawX - xmin;
- xmin = g_prim.drawX;
- posX += j * difX;
- posY += j * difY;
- }
- xmax--;
- if (g_prim.drawW < xmax)
- xmax = g_prim.drawW;
-
- for (j = xmin; j < xmax; j += 2) {
- XAdjust = (posX >> 16);
- tC1
- = g_gpu.psx_vram.u8[((posY >> 5)
- & (int32_t) 0xFFFFF800) + YAdjust
- + (XAdjust >> 1)];
- tC1 = (tC1 >> ((XAdjust & 1) << 2)) & 0xf;
- XAdjust = ((posX + difX) >> 16);
- tC2 = g_gpu.psx_vram.u8[(((posY + difY) >> 5)
- & (int32_t) 0xFFFFF800) + YAdjust + (XAdjust >> 1)];
- tC2 = (tC2 >> ((XAdjust & 1) << 2)) & 0xf;
-
- GetTextureTransColG32_S(
- (uint32_t *) &g_gpu.psx_vram.u16[(i << 10) + j],
- GETLE16(&g_gpu.psx_vram.u16[clutP+tC1])
- | ((int32_t) GETLE16(&g_gpu.psx_vram.u16[clutP+tC2]))
- << 16);
- posX += difX2;
- posY += difY2;
- }
- if (j == xmax) {
- XAdjust = (posX >> 16);
- tC1
- = g_gpu.psx_vram.u8[((posY >> 5)
- & (int32_t) 0xFFFFF800) + YAdjust
- + (XAdjust >> 1)];
- tC1 = (tC1 >> ((XAdjust & 1) << 2)) & 0xf;
- GetTextureTransColG_S(&g_gpu.psx_vram.u16[(i << 10) + j],
- GETLE16(&g_gpu.psx_vram.u16[clutP+tC1]));
- }
-
- }
- if (NextRow_FT4())
- return;
- }
- return;
- }
-
-#endif
-
- for (i = ymin; i <= ymax; i++) {
- xmin = (left_x >> 16);
- xmax = (right_x >> 16);
-
- if (xmax >= xmin) {
- posX = left_u;
- posY = left_v;
-
- num = (xmax - xmin);
- if (num == 0)
- num = 1;
- difX = (right_u - posX) / num;
- difY = (right_v - posY) / num;
- difX2 = difX << 1;
- difY2 = difY << 1;
-
- if (xmin < g_prim.drawX) {
- j = g_prim.drawX - xmin;
- xmin = g_prim.drawX;
- posX += j * difX;
- posY += j * difY;
- }
- xmax--;
- if (g_prim.drawW < xmax)
- xmax = g_prim.drawW;
-
- for (j = xmin; j < xmax; j += 2) {
- XAdjust = (posX >> 16);
- tC1 = g_gpu.psx_vram.u8[((posY >> 5) & (int32_t) 0xFFFFF800)
- + YAdjust + (XAdjust >> 1)];
- tC1 = (tC1 >> ((XAdjust & 1) << 2)) & 0xf;
- XAdjust = ((posX + difX) >> 16);
- tC2 = g_gpu.psx_vram.u8[(((posY + difY) >> 5)
- & (int32_t) 0xFFFFF800) + YAdjust + (XAdjust >> 1)];
- tC2 = (tC2 >> ((XAdjust & 1) << 2)) & 0xf;
-
- GetTextureTransColG32(
- (uint32_t *) &g_gpu.psx_vram.u16[(i << 10) + j],
- GETLE16(&g_gpu.psx_vram.u16[clutP+tC1])
- | ((int32_t) GETLE16(&g_gpu.psx_vram.u16[clutP+tC2]))
- << 16);
- posX += difX2;
- posY += difY2;
- }
- if (j == xmax) {
- XAdjust = (posX >> 16);
- tC1 = g_gpu.psx_vram.u8[((posY >> 5) & (int32_t) 0xFFFFF800)
- + YAdjust + (XAdjust >> 1)];
- tC1 = (tC1 >> ((XAdjust & 1) << 2)) & 0xf;
- GetTextureTransColG(&g_gpu.psx_vram.u16[(i << 10) + j],
- GETLE16(&g_gpu.psx_vram.u16[clutP+tC1]));
- }
- }
- if (NextRow_FT4())
- return;
- }
-}
-
-////////////////////////////////////////////////////////////////////////
-
-static void drawPoly4TEx4_IL(short x1, short y1, short x2, short y2, short x3,
- short y3, short x4, short y4, short tx1, short ty1, short tx2,
- short ty2, short tx3, short ty3, short tx4, short ty4, short clX,
- short clY) {
- int32_t num;
- int32_t i, j = 0, xmin, xmax, ymin, ymax, n_xi, n_yi, TXV;
- int32_t difX, difY, difX2, difY2;
- int32_t posX = 0, posY = 0, YAdjust, clutP, XAdjust;
- short tC1, tC2;
-
- if (x1 > g_prim.drawW && x2 > g_prim.drawW && x3 > g_prim.drawW && x4
- > g_prim.drawW)
- return;
- if (y1 > g_prim.drawH && y2 > g_prim.drawH && y3 > g_prim.drawH && y4
- > g_prim.drawH)
- return;
- if (x1 < g_prim.drawX && x2 < g_prim.drawX && x3 < g_prim.drawX && x4
- < g_prim.drawX)
- return;
- if (y1 < g_prim.drawY && y2 < g_prim.drawY && y3 < g_prim.drawY && y4
- < g_prim.drawY)
- return;
- if (g_prim.drawY >= g_prim.drawH)
- return;
- if (g_prim.drawX >= g_prim.drawW)
- return;
-
- if (!SetupSections_FT4(x1, y1, x2, y2, x3, y3, x4, y4, tx1, ty1, tx2, ty2,
- tx3, ty3, tx4, ty4))
- return;
-
- ymax = g_soft.Ymax;
-
- for (ymin = g_soft.Ymin; ymin < g_prim.drawY; ymin++)
- if (NextRow_FT4())
- return;
-
- clutP = (clY << 10) + clX;
-
- YAdjust = ((g_soft.GlobalTextAddrY) << 10) + g_soft.GlobalTextAddrX;
-
-#ifdef FASTSOLID
-
- if (!g_draw.bCheckMask && !g_soft.DrawSemiTrans) {
- for (i = ymin; i <= ymax; i++) {
- xmin = (left_x >> 16);
- xmax = (right_x >> 16);
-
- if (xmax >= xmin) {
- posX = left_u;
- posY = left_v;
-
- num = (xmax - xmin);
- if (num == 0)
- num = 1;
- difX = (right_u - posX) / num;
- difY = (right_v - posY) / num;
- difX2 = difX << 1;
- difY2 = difY << 1;
-
- if (xmin < g_prim.drawX) {
- j = g_prim.drawX - xmin;
- xmin = g_prim.drawX;
- posX += j * difX;
- posY += j * difY;
- }
- xmax--;
- if (g_prim.drawW < xmax)
- xmax = g_prim.drawW;
-
- for (j = xmin; j < xmax; j += 2) {
- XAdjust = (posX >> 16);
-
- TXV = posY >> 16;
- n_xi = ((XAdjust >> 2) & ~0x3c) + ((TXV << 2) & 0x3c);
- n_yi = (TXV & ~0xf) + ((XAdjust >> 4) & 0xf);
-
- tC1
- = (GETLE16(&g_gpu.psx_vram.u16[(n_yi<<10)+YAdjust+n_xi])
- >> ((XAdjust & 0x03) << 2)) & 0x0f;
-
- XAdjust = ((posX + difX) >> 16);
-
- TXV = (posY + difY) >> 16;
- n_xi = ((XAdjust >> 2) & ~0x3c) + ((TXV << 2) & 0x3c);
- n_yi = (TXV & ~0xf) + ((XAdjust >> 4) & 0xf);
-
- tC2
- = (GETLE16(&g_gpu.psx_vram.u16[(n_yi<<10)+YAdjust+n_xi])
- >> ((XAdjust & 0x03) << 2)) & 0x0f;
-
- GetTextureTransColG32_S(
- (uint32_t *) &g_gpu.psx_vram.u16[(i << 10) + j],
- GETLE16(&g_gpu.psx_vram.u16[clutP+tC1])
- | ((int32_t) GETLE16(&g_gpu.psx_vram.u16[clutP+tC2]))
- << 16);
- posX += difX2;
- posY += difY2;
- }
- posX += difX2;
- posY += difY2;
- }
-
- if (j == xmax) {
- XAdjust = (posX >> 16);
- TXV = posY >> 16;
- n_xi = ((XAdjust >> 2) & ~0x3c) + ((TXV << 2) & 0x3c);
- n_yi = (TXV & ~0xf) + ((XAdjust >> 4) & 0xf);
-
- tC1 = (GETLE16(&g_gpu.psx_vram.u16[(n_yi<<10)+YAdjust+n_xi])
- >> ((XAdjust & 0x03) << 2)) & 0x0f;
-
- GetTextureTransColG_S(&g_gpu.psx_vram.u16[(i << 10) + j],
- GETLE16(&g_gpu.psx_vram.u16[clutP+tC1]));
- }
-
- }
- if (NextRow_FT4())
- return;
- }
-#endif
-
- for (i = ymin; i <= ymax; i++) {
- xmin = (left_x >> 16);
- xmax = (right_x >> 16);
-
- if (xmax >= xmin) {
- posX = left_u;
- posY = left_v;
-
- num = (xmax - xmin);
- if (num == 0)
- num = 1;
- difX = (right_u - posX) / num;
- difY = (right_v - posY) / num;
- difX2 = difX << 1;
- difY2 = difY << 1;
-
- if (xmin < g_prim.drawX) {
- j = g_prim.drawX - xmin;
- xmin = g_prim.drawX;
- posX += j * difX;
- posY += j * difY;
- }
- xmax--;
- if (g_prim.drawW < xmax)
- xmax = g_prim.drawW;
-
- for (j = xmin; j < xmax; j += 2) {
- XAdjust = (posX >> 16);
-
- TXV = posY >> 16;
- n_xi = ((XAdjust >> 2) & ~0x3c) + ((TXV << 2) & 0x3c);
- n_yi = (TXV & ~0xf) + ((XAdjust >> 4) & 0xf);
-
- tC1 = (GETLE16(&g_gpu.psx_vram.u16[(n_yi<<10)+YAdjust+n_xi])
- >> ((XAdjust & 0x03) << 2)) & 0x0f;
-
- XAdjust = ((posX + difX) >> 16);
-
- TXV = (posY + difY) >> 16;
- n_xi = ((XAdjust >> 2) & ~0x3c) + ((TXV << 2) & 0x3c);
- n_yi = (TXV & ~0xf) + ((XAdjust >> 4) & 0xf);
-
- tC2 = (GETLE16(&g_gpu.psx_vram.u16[(n_yi<<10)+YAdjust+n_xi])
- >> ((XAdjust & 0x03) << 2)) & 0x0f;
-
- GetTextureTransColG32(
- (uint32_t *) &g_gpu.psx_vram.u16[(i << 10) + j],
- GETLE16(&g_gpu.psx_vram.u16[clutP+tC1])
- | ((int32_t) GETLE16(&g_gpu.psx_vram.u16[clutP+tC2]))
- << 16);
- posX += difX2;
- posY += difY2;
- }
- if (j == xmax) {
- XAdjust = (posX >> 16);
- TXV = posY >> 16;
- n_xi = ((XAdjust >> 2) & ~0x3c) + ((TXV << 2) & 0x3c);
- n_yi = (TXV & ~0xf) + ((XAdjust >> 4) & 0xf);
-
- tC1 = (GETLE16(&g_gpu.psx_vram.u16[(n_yi<<10)+YAdjust+n_xi])
- >> ((XAdjust & 0x03) << 2)) & 0x0f;
-
- GetTextureTransColG(&g_gpu.psx_vram.u16[(i << 10) + j],
- GETLE16(&g_gpu.psx_vram.u16[clutP+tC1]));
- }
- }
- if (NextRow_FT4())
- return;
- }
-}
-
-////////////////////////////////////////////////////////////////////////
-
-static void drawPoly4TEx4_TW(short x1, short y1, short x2, short y2, short x3,
- short y3, short x4, short y4, short tx1, short ty1, short tx2,
- short ty2, short tx3, short ty3, short tx4, short ty4, short clX,
- short clY) {
- int32_t num;
- int32_t i, j, xmin, xmax, ymin, ymax;
- int32_t difX, difY, difX2, difY2;
- int32_t posX, posY, YAdjust, clutP, XAdjust;
- short tC1, tC2;
-
- if (x1 > g_prim.drawW && x2 > g_prim.drawW && x3 > g_prim.drawW && x4
- > g_prim.drawW)
- return;
- if (y1 > g_prim.drawH && y2 > g_prim.drawH && y3 > g_prim.drawH && y4
- > g_prim.drawH)
- return;
- if (x1 < g_prim.drawX && x2 < g_prim.drawX && x3 < g_prim.drawX && x4
- < g_prim.drawX)
- return;
- if (y1 < g_prim.drawY && y2 < g_prim.drawY && y3 < g_prim.drawY && y4
- < g_prim.drawY)
- return;
- if (g_prim.drawY >= g_prim.drawH)
- return;
- if (g_prim.drawX >= g_prim.drawW)
- return;
-
- if (!SetupSections_FT4(x1, y1, x2, y2, x3, y3, x4, y4, tx1, ty1, tx2, ty2,
- tx3, ty3, tx4, ty4))
- return;
-
- ymax = g_soft.Ymax;
-
- for (ymin = g_soft.Ymin; ymin < g_prim.drawY; ymin++)
- if (NextRow_FT4())
- return;
-
- clutP = (clY << 10) + clX;
-
- YAdjust = ((g_soft.GlobalTextAddrY) << 11) + (g_soft.GlobalTextAddrX << 1);
- YAdjust += (g_prim.TWin.Position.y0 << 11) + (g_prim.TWin.Position.x0 >> 1);
-
-#ifdef FASTSOLID
-
- if (!g_draw.bCheckMask && !g_soft.DrawSemiTrans) {
- for (i = ymin; i <= ymax; i++) {
- xmin = (left_x >> 16);
- xmax = (right_x >> 16);
-
- if (xmax >= xmin) {
- posX = left_u;
- posY = left_v;
-
- num = (xmax - xmin);
- if (num == 0)
- num = 1;
- difX = (right_u - posX) / num;
- difY = (right_v - posY) / num;
- difX2 = difX << 1;
- difY2 = difY << 1;
-
- if (xmin < g_prim.drawX) {
- j = g_prim.drawX - xmin;
- xmin = g_prim.drawX;
- posX += j * difX;
- posY += j * difY;
- }
- xmax--;
- if (g_prim.drawW < xmax)
- xmax = g_prim.drawW;
-
- for (j = xmin; j < xmax; j += 2) {
- XAdjust = (posX >> 16) % g_prim.TWin.Position.x1;
- tC1 = g_gpu.psx_vram.u8[(((posY >> 16)
- % g_prim.TWin.Position.y1) << 11) + YAdjust
- + (XAdjust >> 1)];
- tC1 = (tC1 >> ((XAdjust & 1) << 2)) & 0xf;
- XAdjust = ((posX + difX) >> 16) % g_prim.TWin.Position.x1;
- tC2 = g_gpu.psx_vram.u8[((((posY + difY) >> 16)
- % g_prim.TWin.Position.y1) << 11) + YAdjust
- + (XAdjust >> 1)];
- tC2 = (tC2 >> ((XAdjust & 1) << 2)) & 0xf;
-
- GetTextureTransColG32_S(
- (uint32_t *) &g_gpu.psx_vram.u16[(i << 10) + j],
- GETLE16(&g_gpu.psx_vram.u16[clutP+tC1])
- | ((int32_t) GETLE16(&g_gpu.psx_vram.u16[clutP+tC2]))
- << 16);
- posX += difX2;
- posY += difY2;
- }
- if (j == xmax) {
- XAdjust = (posX >> 16) % g_prim.TWin.Position.x1;
- tC1 = g_gpu.psx_vram.u8[(((posY >> 16)
- % g_prim.TWin.Position.y1) << 11) + YAdjust
- + (XAdjust >> 1)];
- tC1 = (tC1 >> ((XAdjust & 1) << 2)) & 0xf;
- GetTextureTransColG_S(&g_gpu.psx_vram.u16[(i << 10) + j],
- GETLE16(&g_gpu.psx_vram.u16[clutP+tC1]));
- }
- }
- if (NextRow_FT4())
- return;
- }
- return;
- }
-
-#endif
-
- for (i = ymin; i <= ymax; i++) {
- xmin = (left_x >> 16);
- xmax = (right_x >> 16);
-
- if (xmax >= xmin) {
- posX = left_u;
- posY = left_v;
-
- num = (xmax - xmin);
- if (num == 0)
- num = 1;
- difX = (right_u - posX) / num;
- difY = (right_v - posY) / num;
- difX2 = difX << 1;
- difY2 = difY << 1;
-
- if (xmin < g_prim.drawX) {
- j = g_prim.drawX - xmin;
- xmin = g_prim.drawX;
- posX += j * difX;
- posY += j * difY;
- }
- xmax--;
- if (g_prim.drawW < xmax)
- xmax = g_prim.drawW;
-
- for (j = xmin; j < xmax; j += 2) {
- XAdjust = (posX >> 16) % g_prim.TWin.Position.x1;
- tC1 = g_gpu.psx_vram.u8[(((posY >> 16)
- % g_prim.TWin.Position.y1) << 11) + YAdjust + (XAdjust
- >> 1)];
- tC1 = (tC1 >> ((XAdjust & 1) << 2)) & 0xf;
- XAdjust = ((posX + difX) >> 16) % g_prim.TWin.Position.x1;
- tC2 = g_gpu.psx_vram.u8[((((posY + difY) >> 16)
- % g_prim.TWin.Position.y1) << 11) + YAdjust + (XAdjust
- >> 1)];
- tC2 = (tC2 >> ((XAdjust & 1) << 2)) & 0xf;
-
- GetTextureTransColG32(
- (uint32_t *) &g_gpu.psx_vram.u16[(i << 10) + j],
- GETLE16(&g_gpu.psx_vram.u16[clutP+tC1])
- | ((int32_t) GETLE16(&g_gpu.psx_vram.u16[clutP+tC2]))
- << 16);
- posX += difX2;
- posY += difY2;
- }
- if (j == xmax) {
- XAdjust = (posX >> 16) % g_prim.TWin.Position.x1;
- tC1 = g_gpu.psx_vram.u8[(((posY >> 16)
- % g_prim.TWin.Position.y1) << 11) + YAdjust + (XAdjust
- >> 1)];
- tC1 = (tC1 >> ((XAdjust & 1) << 2)) & 0xf;
- GetTextureTransColG(&g_gpu.psx_vram.u16[(i << 10) + j],
- GETLE16(&g_gpu.psx_vram.u16[clutP+tC1]));
- }
- }
- if (NextRow_FT4())
- return;
- }
-}
-
-////////////////////////////////////////////////////////////////////////
-
-static void drawPoly4TEx4_TW_S(short x1, short y1, short x2, short y2, short x3,
- short y3, short x4, short y4, short tx1, short ty1, short tx2,
- short ty2, short tx3, short ty3, short tx4, short ty4, short clX,
- short clY) {
- int32_t num;
- int32_t i, j, xmin, xmax, ymin, ymax;
- int32_t difX, difY, difX2, difY2;
- int32_t posX, posY, YAdjust, clutP, XAdjust;
- short tC1, tC2;
-
- if (x1 > g_prim.drawW && x2 > g_prim.drawW && x3 > g_prim.drawW && x4
- > g_prim.drawW)
- return;
- if (y1 > g_prim.drawH && y2 > g_prim.drawH && y3 > g_prim.drawH && y4
- > g_prim.drawH)
- return;
- if (x1 < g_prim.drawX && x2 < g_prim.drawX && x3 < g_prim.drawX && x4
- < g_prim.drawX)
- return;
- if (y1 < g_prim.drawY && y2 < g_prim.drawY && y3 < g_prim.drawY && y4
- < g_prim.drawY)
- return;
- if (g_prim.drawY >= g_prim.drawH)
- return;
- if (g_prim.drawX >= g_prim.drawW)
- return;
-
- if (!SetupSections_FT4(x1, y1, x2, y2, x3, y3, x4, y4, tx1, ty1, tx2, ty2,
- tx3, ty3, tx4, ty4))
- return;
-
- ymax = g_soft.Ymax;
-
- for (ymin = g_soft.Ymin; ymin < g_prim.drawY; ymin++)
- if (NextRow_FT4())
- return;
-
- clutP = (clY << 10) + clX;
-
- YAdjust = ((g_soft.GlobalTextAddrY) << 11) + (g_soft.GlobalTextAddrX << 1);
- YAdjust += (g_prim.TWin.Position.y0 << 11) + (g_prim.TWin.Position.x0 >> 1);
-
-#ifdef FASTSOLID
-
- if (!g_draw.bCheckMask && !g_soft.DrawSemiTrans) {
- for (i = ymin; i <= ymax; i++) {
- xmin = (left_x >> 16);
- xmax = (right_x >> 16);
-
- if (xmax >= xmin) {
- posX = left_u;
- posY = left_v;
-
- num = (xmax - xmin);
- if (num == 0)
- num = 1;
- difX = (right_u - posX) / num;
- difY = (right_v - posY) / num;
- difX2 = difX << 1;
- difY2 = difY << 1;
-
- if (xmin < g_prim.drawX) {
- j = g_prim.drawX - xmin;
- xmin = g_prim.drawX;
- posX += j * difX;
- posY += j * difY;
- }
- xmax--;
- if (g_prim.drawW < xmax)
- xmax = g_prim.drawW;
-
- for (j = xmin; j < xmax; j += 2) {
- XAdjust = (posX >> 16) % g_prim.TWin.Position.x1;
- tC1 = g_gpu.psx_vram.u8[(((posY >> 16)
- % g_prim.TWin.Position.y1) << 11) + YAdjust
- + (XAdjust >> 1)];
- tC1 = (tC1 >> ((XAdjust & 1) << 2)) & 0xf;
- XAdjust = ((posX + difX) >> 16) % g_prim.TWin.Position.x1;
- tC2 = g_gpu.psx_vram.u8[((((posY + difY) >> 16)
- % g_prim.TWin.Position.y1) << 11) + YAdjust
- + (XAdjust >> 1)];
- tC2 = (tC2 >> ((XAdjust & 1) << 2)) & 0xf;
-
- GetTextureTransColG32_S(
- (uint32_t *) &g_gpu.psx_vram.u16[(i << 10) + j],
- GETLE16(&g_gpu.psx_vram.u16[clutP+tC1])
- | ((int32_t) GETLE16(&g_gpu.psx_vram.u16[clutP+tC2]))
- << 16);
- posX += difX2;
- posY += difY2;
- }
- if (j == xmax) {
- XAdjust = (posX >> 16) % g_prim.TWin.Position.x1;
- tC1 = g_gpu.psx_vram.u8[(((posY >> 16)
- % g_prim.TWin.Position.y1) << 11) + YAdjust
- + (XAdjust >> 1)];
- tC1 = (tC1 >> ((XAdjust & 1) << 2)) & 0xf;
- GetTextureTransColG_S(&g_gpu.psx_vram.u16[(i << 10) + j],
- GETLE16(&g_gpu.psx_vram.u16[clutP+tC1]));
- }
- }
- if (NextRow_FT4())
- return;
- }
- return;
- }
-
-#endif
-
- for (i = ymin; i <= ymax; i++) {
- xmin = (left_x >> 16);
- xmax = (right_x >> 16);
-
- if (xmax >= xmin) {
- posX = left_u;
- posY = left_v;
-
- num = (xmax - xmin);
- if (num == 0)
- num = 1;
- difX = (right_u - posX) / num;
- difY = (right_v - posY) / num;
- difX2 = difX << 1;
- difY2 = difY << 1;
-
- if (xmin < g_prim.drawX) {
- j = g_prim.drawX - xmin;
- xmin = g_prim.drawX;
- posX += j * difX;
- posY += j * difY;
- }
- xmax--;
- if (g_prim.drawW < xmax)
- xmax = g_prim.drawW;
-
- for (j = xmin; j < xmax; j += 2) {
- XAdjust = (posX >> 16) % g_prim.TWin.Position.x1;
- tC1 = g_gpu.psx_vram.u8[(((posY >> 16)
- % g_prim.TWin.Position.y1) << 11) + YAdjust + (XAdjust
- >> 1)];
- tC1 = (tC1 >> ((XAdjust & 1) << 2)) & 0xf;
- XAdjust = ((posX + difX) >> 16) % g_prim.TWin.Position.x1;
- tC2 = g_gpu.psx_vram.u8[((((posY + difY) >> 16)
- % g_prim.TWin.Position.y1) << 11) + YAdjust + (XAdjust
- >> 1)];
- tC2 = (tC2 >> ((XAdjust & 1) << 2)) & 0xf;
-
- GetTextureTransColG32_SPR((uint32_t *) &g_gpu.psx_vram.u16[(i
- << 10) + j], GETLE16(&g_gpu.psx_vram.u16[clutP+tC1])
- | ((int32_t) GETLE16(&g_gpu.psx_vram.u16[clutP+tC2]))
- << 16);
- posX += difX2;
- posY += difY2;
- }
- if (j == xmax) {
- XAdjust = (posX >> 16) % g_prim.TWin.Position.x1;
- tC1 = g_gpu.psx_vram.u8[(((posY >> 16)
- % g_prim.TWin.Position.y1) << 11) + YAdjust + (XAdjust
- >> 1)];
- tC1 = (tC1 >> ((XAdjust & 1) << 2)) & 0xf;
- GetTextureTransColG_SPR(&g_gpu.psx_vram.u16[(i << 10) + j],
- GETLE16(&g_gpu.psx_vram.u16[clutP+tC1]));
- }
- }
- if (NextRow_FT4())
- return;
- }
-}
-////////////////////////////////////////////////////////////////////////
-// POLY 3 F-SHADED TEX PAL 8
-////////////////////////////////////////////////////////////////////////
-
-static void drawPoly3TEx8(short x1, short y1, short x2, short y2, short x3, short y3,
- short tx1, short ty1, short tx2, short ty2, short tx3, short ty3,
- short clX, short clY) {
- int i, j, xmin, xmax, ymin, ymax;
- int32_t difX, difY, difX2, difY2;
- int32_t posX, posY, YAdjust, clutP;
- short tC1, tC2;
-
- if (x1 > g_prim.drawW && x2 > g_prim.drawW && x3 > g_prim.drawW)
- return;
- if (y1 > g_prim.drawH && y2 > g_prim.drawH && y3 > g_prim.drawH)
- return;
- if (x1 < g_prim.drawX && x2 < g_prim.drawX && x3 < g_prim.drawX)
- return;
- if (y1 < g_prim.drawY && y2 < g_prim.drawY && y3 < g_prim.drawY)
- return;
- if (g_prim.drawY >= g_prim.drawH)
- return;
- if (g_prim.drawX >= g_prim.drawW)
- return;
-
- if (!SetupSections_FT(x1, y1, x2, y2, x3, y3, tx1, ty1, tx2, ty2, tx3, ty3))
- return;
-
- ymax = g_soft.Ymax;
-
- for (ymin = g_soft.Ymin; ymin < g_prim.drawY; ymin++)
- if (NextRow_FT())
- return;
-
- clutP = (clY << 10) + clX;
-
- YAdjust = ((g_soft.GlobalTextAddrY) << 11) + (g_soft.GlobalTextAddrX << 1);
-
- difX = delta_right_u;
- difX2 = difX << 1;
- difY = delta_right_v;
- difY2 = difY << 1;
-
-#ifdef FASTSOLID
-
- if (!g_draw.bCheckMask && !g_soft.DrawSemiTrans) {
- for (i = ymin; i <= ymax; i++) {
- xmin = (left_x >> 16);
- xmax = (right_x >> 16) - 1; //!!!!!!!!!!!!!!!
- if (g_prim.drawW < xmax)
- xmax = g_prim.drawW;
-
- if (xmax >= xmin) {
- posX = left_u;
- posY = left_v;
-
- if (xmin < g_prim.drawX) {
- j = g_prim.drawX - xmin;
- xmin = g_prim.drawX;
- posX += j * difX;
- posY += j * difY;
- }
-
- for (j = xmin; j < xmax; j += 2) {
- tC1
- = g_gpu.psx_vram.u8[((posY >> 5)
- & (int32_t) 0xFFFFF800) + YAdjust + (posX
- >> 16)];
- tC2 = g_gpu.psx_vram.u8[(((posY + difY) >> 5)
- & (int32_t) 0xFFFFF800) + YAdjust + ((posX + difX)
- >> 16)];
- GetTextureTransColG32_S(
- (uint32_t *) &g_gpu.psx_vram.u16[(i << 10) + j],
- GETLE16(&g_gpu.psx_vram.u16[clutP+tC1])
- | ((int32_t) GETLE16(&g_gpu.psx_vram.u16[clutP+tC2]))
- << 16);
- posX += difX2;
- posY += difY2;
- }
-
- if (j == xmax) {
- tC1
- = g_gpu.psx_vram.u8[((posY >> 5)
- & (int32_t) 0xFFFFF800) + YAdjust + (posX
- >> 16)];
- GetTextureTransColG_S(&g_gpu.psx_vram.u16[(i << 10) + j],
- GETLE16(&g_gpu.psx_vram.u16[clutP+tC1]));
- }
- }
- if (NextRow_FT()) {
- return;
- }
- }
- return;
- }
-
-#endif
-
- for (i = ymin; i <= ymax; i++) {
- xmin = (left_x >> 16);
- xmax = (right_x >> 16) - 1; //!!!!!!!!!!!!!!!!!
- if (g_prim.drawW < xmax)
- xmax = g_prim.drawW;
-
- if (xmax >= xmin) {
- posX = left_u;
- posY = left_v;
-
- if (xmin < g_prim.drawX) {
- j = g_prim.drawX - xmin;
- xmin = g_prim.drawX;
- posX += j * difX;
- posY += j * difY;
- }
-
- for (j = xmin; j < xmax; j += 2) {
- tC1 = g_gpu.psx_vram.u8[((posY >> 5) & (int32_t) 0xFFFFF800)
- + YAdjust + (posX >> 16)];
- tC2 = g_gpu.psx_vram.u8[(((posY + difY) >> 5)
- & (int32_t) 0xFFFFF800) + YAdjust + ((posX + difX)
- >> 16)];
- GetTextureTransColG32(
- (uint32_t *) &g_gpu.psx_vram.u16[(i << 10) + j],
- GETLE16(&g_gpu.psx_vram.u16[clutP+tC1])
- | ((int32_t) GETLE16(&g_gpu.psx_vram.u16[clutP+tC2]))
- << 16);
- posX += difX2;
- posY += difY2;
- }
-
- if (j == xmax) {
- tC1 = g_gpu.psx_vram.u8[((posY >> 5) & (int32_t) 0xFFFFF800)
- + YAdjust + (posX >> 16)];
- GetTextureTransColG(&g_gpu.psx_vram.u16[(i << 10) + j],
- GETLE16(&g_gpu.psx_vram.u16[clutP+tC1]));
- }
-
- }
- if (NextRow_FT()) {
- return;
- }
- }
-}
-
-////////////////////////////////////////////////////////////////////////
-
-static void drawPoly3TEx8_IL(short x1, short y1, short x2, short y2, short x3,
- short y3, short tx1, short ty1, short tx2, short ty2, short tx3,
- short ty3, short clX, short clY) {
- int i, j, xmin, xmax, ymin, ymax, n_xi, n_yi, TXV, TXU;
- int32_t difX, difY, difX2, difY2;
- int32_t posX, posY, YAdjust, clutP;
- short tC1, tC2;
-
- if (x1 > g_prim.drawW && x2 > g_prim.drawW && x3 > g_prim.drawW)
- return;
- if (y1 > g_prim.drawH && y2 > g_prim.drawH && y3 > g_prim.drawH)
- return;
- if (x1 < g_prim.drawX && x2 < g_prim.drawX && x3 < g_prim.drawX)
- return;
- if (y1 < g_prim.drawY && y2 < g_prim.drawY && y3 < g_prim.drawY)
- return;
- if (g_prim.drawY >= g_prim.drawH)
- return;
- if (g_prim.drawX >= g_prim.drawW)
- return;
-
- if (!SetupSections_FT(x1, y1, x2, y2, x3, y3, tx1, ty1, tx2, ty2, tx3, ty3))
- return;
-
- ymax = g_soft.Ymax;
-
- for (ymin = g_soft.Ymin; ymin < g_prim.drawY; ymin++)
- if (NextRow_FT())
- return;
-
- clutP = (clY << 10) + clX;
-
- YAdjust = (g_soft.GlobalTextAddrY << 10) + g_soft.GlobalTextAddrX;
-
- difX = delta_right_u;
- difX2 = difX << 1;
- difY = delta_right_v;
- difY2 = difY << 1;
-
-#ifdef FASTSOLID
-
- if (!g_draw.bCheckMask && !g_soft.DrawSemiTrans) {
- for (i = ymin; i <= ymax; i++) {
- xmin = (left_x >> 16);
- xmax = (right_x >> 16) - 1; //!!!!!!!!!!!!!!!
- if (g_prim.drawW < xmax)
- xmax = g_prim.drawW;
-
- if (xmax >= xmin) {
- posX = left_u;
- posY = left_v;
-
- if (xmin < g_prim.drawX) {
- j = g_prim.drawX - xmin;
- xmin = g_prim.drawX;
- posX += j * difX;
- posY += j * difY;
- }
-
- for (j = xmin; j < xmax; j += 2) {
- TXU = posX >> 16;
- TXV = posY >> 16;
- n_xi = ((TXU >> 1) & ~0x78) + ((TXU << 2) & 0x40) + ((TXV
- << 3) & 0x38);
- n_yi = (TXV & ~0x7) + ((TXU >> 5) & 0x7);
-
- tC1
- = (GETLE16(&g_gpu.psx_vram.u16[(n_yi<<10)+YAdjust+n_xi])
- >> ((TXU & 0x01) << 3)) & 0xff;
-
- TXU = (posX + difX) >> 16;
- TXV = (posY + difY) >> 16;
- n_xi = ((TXU >> 1) & ~0x78) + ((TXU << 2) & 0x40) + ((TXV
- << 3) & 0x38);
- n_yi = (TXV & ~0x7) + ((TXU >> 5) & 0x7);
-
- tC2
- = (GETLE16(&g_gpu.psx_vram.u16[(n_yi<<10)+YAdjust+n_xi])
- >> ((TXU & 0x01) << 3)) & 0xff;
-
- GetTextureTransColG32_S(
- (uint32_t *) &g_gpu.psx_vram.u16[(i << 10) + j],
- GETLE16(&g_gpu.psx_vram.u16[clutP+tC1])
- | ((int32_t) GETLE16(&g_gpu.psx_vram.u16[clutP+tC2]))
- << 16);
- posX += difX2;
- posY += difY2;
- }
-
- if (j == xmax) {
- TXU = posX >> 16;
- TXV = posY >> 16;
- n_xi = ((TXU >> 1) & ~0x78) + ((TXU << 2) & 0x40) + ((TXV
- << 3) & 0x38);
- n_yi = (TXV & ~0x7) + ((TXU >> 5) & 0x7);
-
- tC1
- = (GETLE16(&g_gpu.psx_vram.u16[(n_yi<<10)+YAdjust+n_xi])
- >> ((TXU & 0x01) << 3)) & 0xff;
-
- GetTextureTransColG_S(&g_gpu.psx_vram.u16[(i << 10) + j],
- GETLE16(&g_gpu.psx_vram.u16[clutP+tC1]));
- }
- }
- if (NextRow_FT()) {
- return;
- }
- }
- return;
- }
-
-#endif
-
- for (i = ymin; i <= ymax; i++) {
- xmin = (left_x >> 16);
- xmax = (right_x >> 16) - 1; //!!!!!!!!!!!!!!!!!
- if (g_prim.drawW < xmax)
- xmax = g_prim.drawW;
-
- if (xmax >= xmin) {
- posX = left_u;
- posY = left_v;
-
- if (xmin < g_prim.drawX) {
- j = g_prim.drawX - xmin;
- xmin = g_prim.drawX;
- posX += j * difX;
- posY += j * difY;
- }
-
- for (j = xmin; j < xmax; j += 2) {
- TXU = posX >> 16;
- TXV = posY >> 16;
- n_xi = ((TXU >> 1) & ~0x78) + ((TXU << 2) & 0x40) + ((TXV << 3)
- & 0x38);
- n_yi = (TXV & ~0x7) + ((TXU >> 5) & 0x7);
-
- tC1 = (GETLE16(&g_gpu.psx_vram.u16[(n_yi<<10)+YAdjust+n_xi])
- >> ((TXU & 0x01) << 3)) & 0xff;
-
- TXU = (posX + difX) >> 16;
- TXV = (posY + difY) >> 16;
- n_xi = ((TXU >> 1) & ~0x78) + ((TXU << 2) & 0x40) + ((TXV << 3)
- & 0x38);
- n_yi = (TXV & ~0x7) + ((TXU >> 5) & 0x7);
-
- tC2 = (GETLE16(&g_gpu.psx_vram.u16[(n_yi<<10)+YAdjust+n_xi])
- >> ((TXU & 0x01) << 3)) & 0xff;
-
- GetTextureTransColG32(
- (uint32_t *) &g_gpu.psx_vram.u16[(i << 10) + j],
- GETLE16(&g_gpu.psx_vram.u16[clutP+tC1])
- | ((int32_t) GETLE16(&g_gpu.psx_vram.u16[clutP+tC2]))
- << 16);
- posX += difX2;
- posY += difY2;
- }
-
- if (j == xmax) {
- TXU = posX >> 16;
- TXV = posY >> 16;
- n_xi = ((TXU >> 1) & ~0x78) + ((TXU << 2) & 0x40) + ((TXV << 3)
- & 0x38);
- n_yi = (TXV & ~0x7) + ((TXU >> 5) & 0x7);
-
- tC1 = (GETLE16(&g_gpu.psx_vram.u16[(n_yi<<10)+YAdjust+n_xi])
- >> ((TXU & 0x01) << 3)) & 0xff;
-
- GetTextureTransColG(&g_gpu.psx_vram.u16[(i << 10) + j],
- GETLE16(&g_gpu.psx_vram.u16[clutP+tC1]));
- }
-
- }
- if (NextRow_FT()) {
- return;
- }
- }
-}
-
-////////////////////////////////////////////////////////////////////////
-
-static void drawPoly3TEx8_TW(short x1, short y1, short x2, short y2, short x3,
- short y3, short tx1, short ty1, short tx2, short ty2, short tx3,
- short ty3, short clX, short clY) {
- int i, j, xmin, xmax, ymin, ymax;
- int32_t difX, difY, difX2, difY2;
- int32_t posX, posY, YAdjust, clutP;
- short tC1, tC2;
-
- if (x1 > g_prim.drawW && x2 > g_prim.drawW && x3 > g_prim.drawW)
- return;
- if (y1 > g_prim.drawH && y2 > g_prim.drawH && y3 > g_prim.drawH)
- return;
- if (x1 < g_prim.drawX && x2 < g_prim.drawX && x3 < g_prim.drawX)
- return;
- if (y1 < g_prim.drawY && y2 < g_prim.drawY && y3 < g_prim.drawY)
- return;
- if (g_prim.drawY >= g_prim.drawH)
- return;
- if (g_prim.drawX >= g_prim.drawW)
- return;
-
- if (!SetupSections_FT(x1, y1, x2, y2, x3, y3, tx1, ty1, tx2, ty2, tx3, ty3))
- return;
-
- ymax = g_soft.Ymax;
-
- for (ymin = g_soft.Ymin; ymin < g_prim.drawY; ymin++)
- if (NextRow_FT())
- return;
-
- clutP = (clY << 10) + clX;
-
- YAdjust = ((g_soft.GlobalTextAddrY) << 11) + (g_soft.GlobalTextAddrX << 1);
- YAdjust += (g_prim.TWin.Position.y0 << 11) + (g_prim.TWin.Position.x0);
-
- difX = delta_right_u;
- difX2 = difX << 1;
- difY = delta_right_v;
- difY2 = difY << 1;
-
-#ifdef FASTSOLID
-
- if (!g_draw.bCheckMask && !g_soft.DrawSemiTrans) {
- for (i = ymin; i <= ymax; i++) {
- xmin = (left_x >> 16);
- xmax = (right_x >> 16);//-1; //!!!!!!!!!!!!!!!!
- if (xmax > xmin)
- xmax--;
-
- if (g_prim.drawW < xmax)
- xmax = g_prim.drawW;
-
- if (xmax >= xmin) {
- posX = left_u;
- posY = left_v;
-
- if (xmin < g_prim.drawX) {
- j = g_prim.drawX - xmin;
- xmin = g_prim.drawX;
- posX += j * difX;
- posY += j * difY;
- }
-
- for (j = xmin; j < xmax; j += 2) {
- tC1 = g_gpu.psx_vram.u8[(((posY >> 16)
- % g_prim.TWin.Position.y1) << 11) + YAdjust
- + ((posX >> 16) % g_prim.TWin.Position.x1)];
- tC2
- = g_gpu.psx_vram.u8[((((posY + difY) >> 16)
- % g_prim.TWin.Position.y1) << 11) + YAdjust
- + (((posX + difX) >> 16)
- % g_prim.TWin.Position.x1)];
- GetTextureTransColG32_S(
- (uint32_t *) &g_gpu.psx_vram.u16[(i << 10) + j],
- GETLE16(&g_gpu.psx_vram.u16[clutP+tC1])
- | ((int32_t) GETLE16(&g_gpu.psx_vram.u16[clutP+tC2]))
- << 16);
- posX += difX2;
- posY += difY2;
- }
-
- if (j == xmax) {
- tC1 = g_gpu.psx_vram.u8[(((posY >> 16)
- % g_prim.TWin.Position.y1) << 11) + YAdjust
- + ((posX >> 16) % g_prim.TWin.Position.x1)];
- GetTextureTransColG_S(&g_gpu.psx_vram.u16[(i << 10) + j],
- GETLE16(&g_gpu.psx_vram.u16[clutP+tC1]));
- }
- }
- if (NextRow_FT()) {
- return;
- }
- }
- return;
- }
-
-#endif
-
- for (i = ymin; i <= ymax; i++) {
- xmin = (left_x >> 16);
- xmax = (right_x >> 16) - 1; //!!!!!!!!!!!!!!!!!
- if (g_prim.drawW < xmax)
- xmax = g_prim.drawW;
-
- if (xmax >= xmin) {
- posX = left_u;
- posY = left_v;
-
- if (xmin < g_prim.drawX) {
- j = g_prim.drawX - xmin;
- xmin = g_prim.drawX;
- posX += j * difX;
- posY += j * difY;
- }
-
- for (j = xmin; j < xmax; j += 2) {
- tC1 = g_gpu.psx_vram.u8[(((posY >> 16)
- % g_prim.TWin.Position.y1) << 11) + YAdjust + ((posX
- >> 16) % g_prim.TWin.Position.x1)];
- tC2 = g_gpu.psx_vram.u8[((((posY + difY) >> 16)
- % g_prim.TWin.Position.y1) << 11) + YAdjust + (((posX
- + difX) >> 16) % g_prim.TWin.Position.x1)];
- GetTextureTransColG32(
- (uint32_t *) &g_gpu.psx_vram.u16[(i << 10) + j],
- GETLE16(&g_gpu.psx_vram.u16[clutP+tC1])
- | ((int32_t) GETLE16(&g_gpu.psx_vram.u16[clutP+tC2]))
- << 16);
- posX += difX2;
- posY += difY2;
- }
-
- if (j == xmax) {
- tC1 = g_gpu.psx_vram.u8[(((posY >> 16)
- % g_prim.TWin.Position.y1) << 11) + YAdjust + ((posX
- >> 16) % g_prim.TWin.Position.x1)];
- GetTextureTransColG(&g_gpu.psx_vram.u16[(i << 10) + j],
- GETLE16(&g_gpu.psx_vram.u16[clutP+tC1]));
- }
-
- }
- if (NextRow_FT()) {
- return;
- }
- }
-}
-
-////////////////////////////////////////////////////////////////////////
-
-#ifdef POLYQUAD3
-
-static void drawPoly4TEx8_TRI(short x1, short y1, short x2, short y2, short x3,
- short y3, short x4, short y4, short tx1, short ty1, short tx2,
- short ty2, short tx3, short ty3, short tx4, short ty4, short clX,
- short clY) {
- drawPoly3TEx8(x2, y2, x3, y3, x4, y4, tx2, ty2, tx3, ty3, tx4, ty4, clX,
- clY);
-
- drawPoly3TEx8(x1, y1, x2, y2, x4, y4, tx1, ty1, tx2, ty2, tx4, ty4, clX,
- clY);
-}
-
-#endif
-
-// more exact:
-
-static void drawPoly4TEx8(short x1, short y1, short x2, short y2, short x3, short y3,
- short x4, short y4, short tx1, short ty1, short tx2, short ty2,
- short tx3, short ty3, short tx4, short ty4, short clX, short clY) {
- int32_t num;
- int32_t i, j, xmin, xmax, ymin, ymax;
- int32_t difX, difY, difX2, difY2;
- int32_t posX, posY, YAdjust, clutP;
- short tC1, tC2;
-
- if (x1 > g_prim.drawW && x2 > g_prim.drawW && x3 > g_prim.drawW && x4
- > g_prim.drawW)
- return;
- if (y1 > g_prim.drawH && y2 > g_prim.drawH && y3 > g_prim.drawH && y4
- > g_prim.drawH)
- return;
- if (x1 < g_prim.drawX && x2 < g_prim.drawX && x3 < g_prim.drawX && x4
- < g_prim.drawX)
- return;
- if (y1 < g_prim.drawY && y2 < g_prim.drawY && y3 < g_prim.drawY && y4
- < g_prim.drawY)
- return;
- if (g_prim.drawY >= g_prim.drawH)
- return;
- if (g_prim.drawX >= g_prim.drawW)
- return;
-
- if (!SetupSections_FT4(x1, y1, x2, y2, x3, y3, x4, y4, tx1, ty1, tx2, ty2,
- tx3, ty3, tx4, ty4))
- return;
-
- ymax = g_soft.Ymax;
-
- for (ymin = g_soft.Ymin; ymin < g_prim.drawY; ymin++)
- if (NextRow_FT4())
- return;
-
- clutP = (clY << 10) + clX;
-
- YAdjust = ((g_soft.GlobalTextAddrY) << 11) + (g_soft.GlobalTextAddrX << 1);
-
-#ifdef FASTSOLID
-
- if (!g_draw.bCheckMask && !g_soft.DrawSemiTrans) {
- for (i = ymin; i <= ymax; i++) {
- xmin = (left_x >> 16);
- xmax = (right_x >> 16);
-
- if (xmax >= xmin) {
- posX = left_u;
- posY = left_v;
-
- num = (xmax - xmin);
- if (num == 0)
- num = 1;
- difX = (right_u - posX) / num;
- difY = (right_v - posY) / num;
- difX2 = difX << 1;
- difY2 = difY << 1;
-
- if (xmin < g_prim.drawX) {
- j = g_prim.drawX - xmin;
- xmin = g_prim.drawX;
- posX += j * difX;
- posY += j * difY;
- }
- xmax--;
- if (g_prim.drawW < xmax)
- xmax = g_prim.drawW;
-
- for (j = xmin; j < xmax; j += 2) {
- tC1
- = g_gpu.psx_vram.u8[((posY >> 5)
- & (int32_t) 0xFFFFF800) + YAdjust + (posX
- >> 16)];
- tC2 = g_gpu.psx_vram.u8[(((posY + difY) >> 5)
- & (int32_t) 0xFFFFF800) + YAdjust + ((posX + difX)
- >> 16)];
- GetTextureTransColG32_S(
- (uint32_t *) &g_gpu.psx_vram.u16[(i << 10) + j],
- GETLE16(&g_gpu.psx_vram.u16[clutP+tC1])
- | ((int32_t) GETLE16(&g_gpu.psx_vram.u16[clutP+tC2]))
- << 16);
- posX += difX2;
- posY += difY2;
- }
- if (j == xmax) {
- tC1
- = g_gpu.psx_vram.u8[((posY >> 5)
- & (int32_t) 0xFFFFF800) + YAdjust + (posX
- >> 16)];
- GetTextureTransColG_S(&g_gpu.psx_vram.u16[(i << 10) + j],
- GETLE16(&g_gpu.psx_vram.u16[clutP+tC1]));
- }
- }
- if (NextRow_FT4())
- return;
- }
- return;
- }
-
-#endif
-
- for (i = ymin; i <= ymax; i++) {
- xmin = (left_x >> 16);
- xmax = (right_x >> 16);
-
- if (xmax >= xmin) {
- posX = left_u;
- posY = left_v;
-
- num = (xmax - xmin);
- if (num == 0)
- num = 1;
- difX = (right_u - posX) / num;
- difY = (right_v - posY) / num;
- difX2 = difX << 1;
- difY2 = difY << 1;
-
- if (xmin < g_prim.drawX) {
- j = g_prim.drawX - xmin;
- xmin = g_prim.drawX;
- posX += j * difX;
- posY += j * difY;
- }
- xmax--;
- if (g_prim.drawW < xmax)
- xmax = g_prim.drawW;
-
- for (j = xmin; j < xmax; j += 2) {
- tC1 = g_gpu.psx_vram.u8[((posY >> 5) & (int32_t) 0xFFFFF800)
- + YAdjust + (posX >> 16)];
- tC2 = g_gpu.psx_vram.u8[(((posY + difY) >> 5)
- & (int32_t) 0xFFFFF800) + YAdjust + ((posX + difX)
- >> 16)];
- GetTextureTransColG32(
- (uint32_t *) &g_gpu.psx_vram.u16[(i << 10) + j],
- GETLE16(&g_gpu.psx_vram.u16[clutP+tC1])
- | ((int32_t) GETLE16(&g_gpu.psx_vram.u16[clutP+tC2]))
- << 16);
- posX += difX2;
- posY += difY2;
- }
- if (j == xmax) {
- tC1 = g_gpu.psx_vram.u8[((posY >> 5) & (int32_t) 0xFFFFF800)
- + YAdjust + (posX >> 16)];
- GetTextureTransColG(&g_gpu.psx_vram.u16[(i << 10) + j],
- GETLE16(&g_gpu.psx_vram.u16[clutP+tC1]));
- }
- }
- if (NextRow_FT4())
- return;
- }
-}
-
-////////////////////////////////////////////////////////////////////////
-
-static void drawPoly4TEx8_IL(short x1, short y1, short x2, short y2, short x3,
- short y3, short x4, short y4, short tx1, short ty1, short tx2,
- short ty2, short tx3, short ty3, short tx4, short ty4, short clX,
- short clY) {
- int32_t num;
- int32_t i, j, xmin, xmax, ymin, ymax, n_xi, n_yi, TXV, TXU;
- int32_t difX, difY, difX2, difY2;
- int32_t posX, posY, YAdjust, clutP;
- short tC1, tC2;
-
- if (x1 > g_prim.drawW && x2 > g_prim.drawW && x3 > g_prim.drawW && x4
- > g_prim.drawW)
- return;
- if (y1 > g_prim.drawH && y2 > g_prim.drawH && y3 > g_prim.drawH && y4
- > g_prim.drawH)
- return;
- if (x1 < g_prim.drawX && x2 < g_prim.drawX && x3 < g_prim.drawX && x4
- < g_prim.drawX)
- return;
- if (y1 < g_prim.drawY && y2 < g_prim.drawY && y3 < g_prim.drawY && y4
- < g_prim.drawY)
- return;
- if (g_prim.drawY >= g_prim.drawH)
- return;
- if (g_prim.drawX >= g_prim.drawW)
- return;
-
- if (!SetupSections_FT4(x1, y1, x2, y2, x3, y3, x4, y4, tx1, ty1, tx2, ty2,
- tx3, ty3, tx4, ty4))
- return;
-
- ymax = g_soft.Ymax;
-
- for (ymin = g_soft.Ymin; ymin < g_prim.drawY; ymin++)
- if (NextRow_FT4())
- return;
-
- clutP = (clY << 10) + clX;
-
- YAdjust = (g_soft.GlobalTextAddrY << 10) + g_soft.GlobalTextAddrX;
-
-#ifdef FASTSOLID
-
- if (!g_draw.bCheckMask && !g_soft.DrawSemiTrans) {
- for (i = ymin; i <= ymax; i++) {
- xmin = (left_x >> 16);
- xmax = (right_x >> 16);
-
- if (xmax >= xmin) {
- posX = left_u;
- posY = left_v;
-
- num = (xmax - xmin);
- if (num == 0)
- num = 1;
- difX = (right_u - posX) / num;
- difY = (right_v - posY) / num;
- difX2 = difX << 1;
- difY2 = difY << 1;
-
- if (xmin < g_prim.drawX) {
- j = g_prim.drawX - xmin;
- xmin = g_prim.drawX;
- posX += j * difX;
- posY += j * difY;
- }
- xmax--;
- if (g_prim.drawW < xmax)
- xmax = g_prim.drawW;
-
- for (j = xmin; j < xmax; j += 2) {
- TXU = posX >> 16;
- TXV = posY >> 16;
- n_xi = ((TXU >> 1) & ~0x78) + ((TXU << 2) & 0x40) + ((TXV
- << 3) & 0x38);
- n_yi = (TXV & ~0x7) + ((TXU >> 5) & 0x7);
-
- tC1
- = (GETLE16(&g_gpu.psx_vram.u16[(n_yi<<10)+YAdjust+n_xi])
- >> ((TXU & 0x01) << 3)) & 0xff;
-
- TXU = (posX + difX) >> 16;
- TXV = (posY + difY) >> 16;
- n_xi = ((TXU >> 1) & ~0x78) + ((TXU << 2) & 0x40) + ((TXV
- << 3) & 0x38);
- n_yi = (TXV & ~0x7) + ((TXU >> 5) & 0x7);
-
- tC2
- = (GETLE16(&g_gpu.psx_vram.u16[(n_yi<<10)+YAdjust+n_xi])
- >> ((TXU & 0x01) << 3)) & 0xff;
-
- GetTextureTransColG32_S(
- (uint32_t *) &g_gpu.psx_vram.u16[(i << 10) + j],
- GETLE16(&g_gpu.psx_vram.u16[clutP+tC1])
- | ((int32_t) GETLE16(&g_gpu.psx_vram.u16[clutP+tC2]))
- << 16);
- posX += difX2;
- posY += difY2;
- }
- if (j == xmax) {
- TXU = posX >> 16;
- TXV = posY >> 16;
- n_xi = ((TXU >> 1) & ~0x78) + ((TXU << 2) & 0x40) + ((TXV
- << 3) & 0x38);
- n_yi = (TXV & ~0x7) + ((TXU >> 5) & 0x7);
-
- tC1
- = (GETLE16(&g_gpu.psx_vram.u16[(n_yi<<10)+YAdjust+n_xi])
- >> ((TXU & 0x01) << 3)) & 0xff;
-
- GetTextureTransColG_S(&g_gpu.psx_vram.u16[(i << 10) + j],
- GETLE16(&g_gpu.psx_vram.u16[clutP+tC1]));
- }
- }
- if (NextRow_FT4())
- return;
- }
- return;
- }
-
-#endif
-
- for (i = ymin; i <= ymax; i++) {
- xmin = (left_x >> 16);
- xmax = (right_x >> 16);
-
- if (xmax >= xmin) {
- posX = left_u;
- posY = left_v;
-
- num = (xmax - xmin);
- if (num == 0)
- num = 1;
- difX = (right_u - posX) / num;
- difY = (right_v - posY) / num;
- difX2 = difX << 1;
- difY2 = difY << 1;
-
- if (xmin < g_prim.drawX) {
- j = g_prim.drawX - xmin;
- xmin = g_prim.drawX;
- posX += j * difX;
- posY += j * difY;
- }
- xmax--;
- if (g_prim.drawW < xmax)
- xmax = g_prim.drawW;
-
- for (j = xmin; j < xmax; j += 2) {
- TXU = posX >> 16;
- TXV = posY >> 16;
- n_xi = ((TXU >> 1) & ~0x78) + ((TXU << 2) & 0x40) + ((TXV << 3)
- & 0x38);
- n_yi = (TXV & ~0x7) + ((TXU >> 5) & 0x7);
-
- tC1 = (GETLE16(&g_gpu.psx_vram.u16[(n_yi<<10)+YAdjust+n_xi])
- >> ((TXU & 0x01) << 3)) & 0xff;
-
- TXU = (posX + difX) >> 16;
- TXV = (posY + difY) >> 16;
- n_xi = ((TXU >> 1) & ~0x78) + ((TXU << 2) & 0x40) + ((TXV << 3)
- & 0x38);
- n_yi = (TXV & ~0x7) + ((TXU >> 5) & 0x7);
-
- tC2 = (GETLE16(&g_gpu.psx_vram.u16[(n_yi<<10)+YAdjust+n_xi])
- >> ((TXU & 0x01) << 3)) & 0xff;
-
- GetTextureTransColG32(
- (uint32_t *) &g_gpu.psx_vram.u16[(i << 10) + j],
- GETLE16(&g_gpu.psx_vram.u16[clutP+tC1])
- | ((int32_t) GETLE16(&g_gpu.psx_vram.u16[clutP+tC2]))
- << 16);
- posX += difX2;
- posY += difY2;
- }
- if (j == xmax) {
- TXU = posX >> 16;
- TXV = posY >> 16;
- n_xi = ((TXU >> 1) & ~0x78) + ((TXU << 2) & 0x40) + ((TXV << 3)
- & 0x38);
- n_yi = (TXV & ~0x7) + ((TXU >> 5) & 0x7);
- tC1 = (GETLE16(&g_gpu.psx_vram.u16[(n_yi<<10)+YAdjust+n_xi])
- >> ((TXU & 0x01) << 3)) & 0xff;
- GetTextureTransColG(&g_gpu.psx_vram.u16[(i << 10) + j],
- GETLE16(&g_gpu.psx_vram.u16[clutP+tC1]));
- }
- }
- if (NextRow_FT4())
- return;
- }
-}
-
-////////////////////////////////////////////////////////////////////////
-
-static void drawPoly4TEx8_TW(short x1, short y1, short x2, short y2, short x3,
- short y3, short x4, short y4, short tx1, short ty1, short tx2,
- short ty2, short tx3, short ty3, short tx4, short ty4, short clX,
- short clY) {
- int32_t num;
- int32_t i, j, xmin, xmax, ymin, ymax;
- int32_t difX, difY, difX2, difY2;
- int32_t posX, posY, YAdjust, clutP;
- short tC1, tC2;
-
- if (x1 > g_prim.drawW && x2 > g_prim.drawW && x3 > g_prim.drawW && x4
- > g_prim.drawW)
- return;
- if (y1 > g_prim.drawH && y2 > g_prim.drawH && y3 > g_prim.drawH && y4
- > g_prim.drawH)
- return;
- if (x1 < g_prim.drawX && x2 < g_prim.drawX && x3 < g_prim.drawX && x4
- < g_prim.drawX)
- return;
- if (y1 < g_prim.drawY && y2 < g_prim.drawY && y3 < g_prim.drawY && y4
- < g_prim.drawY)
- return;
- if (g_prim.drawY >= g_prim.drawH)
- return;
- if (g_prim.drawX >= g_prim.drawW)
- return;
-
- if (!SetupSections_FT4(x1, y1, x2, y2, x3, y3, x4, y4, tx1, ty1, tx2, ty2,
- tx3, ty3, tx4, ty4))
- return;
-
- ymax = g_soft.Ymax;
-
- for (ymin = g_soft.Ymin; ymin < g_prim.drawY; ymin++)
- if (NextRow_FT4())
- return;
-
- clutP = (clY << 10) + clX;
-
- YAdjust = ((g_soft.GlobalTextAddrY) << 11) + (g_soft.GlobalTextAddrX << 1);
- YAdjust += (g_prim.TWin.Position.y0 << 11) + (g_prim.TWin.Position.x0);
-
-#ifdef FASTSOLID
-
- if (!g_draw.bCheckMask && !g_soft.DrawSemiTrans) {
- for (i = ymin; i <= ymax; i++) {
- xmin = (left_x >> 16);
- xmax = (right_x >> 16);
-
- if (xmax >= xmin) {
- posX = left_u;
- posY = left_v;
-
- num = (xmax - xmin);
- if (num == 0)
- num = 1;
- difX = (right_u - posX) / num;
- difY = (right_v - posY) / num;
- difX2 = difX << 1;
- difY2 = difY << 1;
-
- if (xmin < g_prim.drawX) {
- j = g_prim.drawX - xmin;
- xmin = g_prim.drawX;
- posX += j * difX;
- posY += j * difY;
- }
- xmax--;
- if (g_prim.drawW < xmax)
- xmax = g_prim.drawW;
-
- for (j = xmin; j < xmax; j += 2) {
- tC1 = g_gpu.psx_vram.u8[(((posY >> 16)
- % g_prim.TWin.Position.y1) << 11) + YAdjust
- + ((posX >> 16) % g_prim.TWin.Position.x1)];
- tC2
- = g_gpu.psx_vram.u8[((((posY + difY) >> 16)
- % g_prim.TWin.Position.y1) << 11) + YAdjust
- + (((posX + difX) >> 16)
- % g_prim.TWin.Position.x1)];
- GetTextureTransColG32_S(
- (uint32_t *) &g_gpu.psx_vram.u16[(i << 10) + j],
- GETLE16(&g_gpu.psx_vram.u16[clutP+tC1])
- | ((int32_t) GETLE16(&g_gpu.psx_vram.u16[clutP+tC2]))
- << 16);
- posX += difX2;
- posY += difY2;
- }
- if (j == xmax) {
- tC1 = g_gpu.psx_vram.u8[((((posY + difY) >> 16)
- % g_prim.TWin.Position.y1) << 11) + YAdjust
- + ((posX >> 16) % g_prim.TWin.Position.x1)];
- GetTextureTransColG_S(&g_gpu.psx_vram.u16[(i << 10) + j],
- GETLE16(&g_gpu.psx_vram.u16[clutP+tC1]));
- }
- }
- if (NextRow_FT4())
- return;
- }
- return;
- }
-
-#endif
-
- for (i = ymin; i <= ymax; i++) {
- xmin = (left_x >> 16);
- xmax = (right_x >> 16);
-
- if (xmax >= xmin) {
- posX = left_u;
- posY = left_v;
-
- num = (xmax - xmin);
- if (num == 0)
- num = 1;
- difX = (right_u - posX) / num;
- difY = (right_v - posY) / num;
- difX2 = difX << 1;
- difY2 = difY << 1;
-
- if (xmin < g_prim.drawX) {
- j = g_prim.drawX - xmin;
- xmin = g_prim.drawX;
- posX += j * difX;
- posY += j * difY;
- }
- xmax--;
- if (g_prim.drawW < xmax)
- xmax = g_prim.drawW;
-
- for (j = xmin; j < xmax; j += 2) {
- tC1 = g_gpu.psx_vram.u8[(((posY >> 16)
- % g_prim.TWin.Position.y1) << 11) + YAdjust + ((posX
- >> 16) % g_prim.TWin.Position.x1)];
- tC2 = g_gpu.psx_vram.u8[((((posY + difY) >> 16)
- % g_prim.TWin.Position.y1) << 11) + YAdjust + (((posX
- + difX) >> 16) % g_prim.TWin.Position.x1)];
- GetTextureTransColG32(
- (uint32_t *) &g_gpu.psx_vram.u16[(i << 10) + j],
- GETLE16(&g_gpu.psx_vram.u16[clutP+tC1])
- | ((int32_t) GETLE16(&g_gpu.psx_vram.u16[clutP+tC2]))
- << 16);
- posX += difX2;
- posY += difY2;
- }
- if (j == xmax) {
- tC1 = g_gpu.psx_vram.u8[((((posY + difY) >> 16)
- % g_prim.TWin.Position.y1) << 11) + YAdjust + ((posX
- >> 16) % g_prim.TWin.Position.x1)];
- GetTextureTransColG(&g_gpu.psx_vram.u16[(i << 10) + j],
- GETLE16(&g_gpu.psx_vram.u16[clutP+tC1]));
- }
- }
- if (NextRow_FT4())
- return;
- }
-}
-
-////////////////////////////////////////////////////////////////////////
-
-static void drawPoly4TEx8_TW_S(short x1, short y1, short x2, short y2, short x3,
- short y3, short x4, short y4, short tx1, short ty1, short tx2,
- short ty2, short tx3, short ty3, short tx4, short ty4, short clX,
- short clY) {
- int32_t num;
- int32_t i, j, xmin, xmax, ymin, ymax;
- int32_t difX, difY, difX2, difY2;
- int32_t posX, posY, YAdjust, clutP;
- short tC1, tC2;
-
- if (x1 > g_prim.drawW && x2 > g_prim.drawW && x3 > g_prim.drawW && x4
- > g_prim.drawW)
- return;
- if (y1 > g_prim.drawH && y2 > g_prim.drawH && y3 > g_prim.drawH && y4
- > g_prim.drawH)
- return;
- if (x1 < g_prim.drawX && x2 < g_prim.drawX && x3 < g_prim.drawX && x4
- < g_prim.drawX)
- return;
- if (y1 < g_prim.drawY && y2 < g_prim.drawY && y3 < g_prim.drawY && y4
- < g_prim.drawY)
- return;
- if (g_prim.drawY >= g_prim.drawH)
- return;
- if (g_prim.drawX >= g_prim.drawW)
- return;
-
- if (!SetupSections_FT4(x1, y1, x2, y2, x3, y3, x4, y4, tx1, ty1, tx2, ty2,
- tx3, ty3, tx4, ty4))
- return;
-
- ymax = g_soft.Ymax;
-
- for (ymin = g_soft.Ymin; ymin < g_prim.drawY; ymin++)
- if (NextRow_FT4())
- return;
-
- clutP = (clY << 10) + clX;
-
- YAdjust = ((g_soft.GlobalTextAddrY) << 11) + (g_soft.GlobalTextAddrX << 1);
- YAdjust += (g_prim.TWin.Position.y0 << 11) + (g_prim.TWin.Position.x0);
-
-#ifdef FASTSOLID
-
- if (!g_draw.bCheckMask && !g_soft.DrawSemiTrans) {
- for (i = ymin; i <= ymax; i++) {
- xmin = (left_x >> 16);
- xmax = (right_x >> 16);
-
- if (xmax >= xmin) {
- posX = left_u;
- posY = left_v;
-
- num = (xmax - xmin);
- if (num == 0)
- num = 1;
- difX = (right_u - posX) / num;
- difY = (right_v - posY) / num;
- difX2 = difX << 1;
- difY2 = difY << 1;
-
- if (xmin < g_prim.drawX) {
- j = g_prim.drawX - xmin;
- xmin = g_prim.drawX;
- posX += j * difX;
- posY += j * difY;
- }
- xmax--;
- if (g_prim.drawW < xmax)
- xmax = g_prim.drawW;
-
- for (j = xmin; j < xmax; j += 2) {
- tC1 = g_gpu.psx_vram.u8[(((posY >> 16)
- % g_prim.TWin.Position.y1) << 11) + YAdjust
- + ((posX >> 16) % g_prim.TWin.Position.x1)];
- tC2
- = g_gpu.psx_vram.u8[((((posY + difY) >> 16)
- % g_prim.TWin.Position.y1) << 11) + YAdjust
- + (((posX + difX) >> 16)
- % g_prim.TWin.Position.x1)];
- GetTextureTransColG32_S(
- (uint32_t *) &g_gpu.psx_vram.u16[(i << 10) + j],
- GETLE16(&g_gpu.psx_vram.u16[clutP+tC1])
- | ((int32_t) GETLE16(&g_gpu.psx_vram.u16[clutP+tC2]))
- << 16);
- posX += difX2;
- posY += difY2;
- }
- if (j == xmax) {
- tC1 = g_gpu.psx_vram.u8[((((posY + difY) >> 16)
- % g_prim.TWin.Position.y1) << 11) + YAdjust
- + ((posX >> 16) % g_prim.TWin.Position.x1)];
- GetTextureTransColG_S(&g_gpu.psx_vram.u16[(i << 10) + j],
- GETLE16(&g_gpu.psx_vram.u16[clutP+tC1]));
- }
- }
- if (NextRow_FT4())
- return;
- }
- return;
- }
-
-#endif
-
- for (i = ymin; i <= ymax; i++) {
- xmin = (left_x >> 16);
- xmax = (right_x >> 16);
-
- if (xmax >= xmin) {
- posX = left_u;
- posY = left_v;
-
- num = (xmax - xmin);
- if (num == 0)
- num = 1;
- difX = (right_u - posX) / num;
- difY = (right_v - posY) / num;
- difX2 = difX << 1;
- difY2 = difY << 1;
-
- if (xmin < g_prim.drawX) {
- j = g_prim.drawX - xmin;
- xmin = g_prim.drawX;
- posX += j * difX;
- posY += j * difY;
- }
- xmax--;
- if (g_prim.drawW < xmax)
- xmax = g_prim.drawW;
-
- for (j = xmin; j < xmax; j += 2) {
- tC1 = g_gpu.psx_vram.u8[(((posY >> 16)
- % g_prim.TWin.Position.y1) << 11) + YAdjust + ((posX
- >> 16) % g_prim.TWin.Position.x1)];
- tC2 = g_gpu.psx_vram.u8[((((posY + difY) >> 16)
- % g_prim.TWin.Position.y1) << 11) + YAdjust + (((posX
- + difX) >> 16) % g_prim.TWin.Position.x1)];
- GetTextureTransColG32_SPR((uint32_t *) &g_gpu.psx_vram.u16[(i
- << 10) + j], GETLE16(&g_gpu.psx_vram.u16[clutP+tC1])
- | ((int32_t) GETLE16(&g_gpu.psx_vram.u16[clutP+tC2]))
- << 16);
- posX += difX2;
- posY += difY2;
- }
- if (j == xmax) {
- tC1 = g_gpu.psx_vram.u8[((((posY + difY) >> 16)
- % g_prim.TWin.Position.y1) << 11) + YAdjust + ((posX
- >> 16) % g_prim.TWin.Position.x1)];
- GetTextureTransColG_SPR(&g_gpu.psx_vram.u16[(i << 10) + j],
- GETLE16(&g_gpu.psx_vram.u16[clutP+tC1]));
- }
- }
- if (NextRow_FT4())
- return;
- }
-}
-
-////////////////////////////////////////////////////////////////////////
-// POLY 3 F-SHADED TEX 15 BIT
-////////////////////////////////////////////////////////////////////////
-
-static void drawPoly3TD(short x1, short y1, short x2, short y2, short x3, short y3,
- short tx1, short ty1, short tx2, short ty2, short tx3, short ty3) {
- int i, j, xmin, xmax, ymin, ymax;
- int32_t difX, difY, difX2, difY2;
- int32_t posX, posY;
-
- if (x1 > g_prim.drawW && x2 > g_prim.drawW && x3 > g_prim.drawW)
- return;
- if (y1 > g_prim.drawH && y2 > g_prim.drawH && y3 > g_prim.drawH)
- return;
- if (x1 < g_prim.drawX && x2 < g_prim.drawX && x3 < g_prim.drawX)
- return;
- if (y1 < g_prim.drawY && y2 < g_prim.drawY && y3 < g_prim.drawY)
- return;
- if (g_prim.drawY >= g_prim.drawH)
- return;
- if (g_prim.drawX >= g_prim.drawW)
- return;
-
- if (!SetupSections_FT(x1, y1, x2, y2, x3, y3, tx1, ty1, tx2, ty2, tx3, ty3))
- return;
-
- ymax = g_soft.Ymax;
-
- for (ymin = g_soft.Ymin; ymin < g_prim.drawY; ymin++)
- if (NextRow_FT())
- return;
-
- difX = delta_right_u;
- difX2 = difX << 1;
- difY = delta_right_v;
- difY2 = difY << 1;
-
-#ifdef FASTSOLID
-
- if (!g_draw.bCheckMask && !g_soft.DrawSemiTrans) {
- for (i = ymin; i <= ymax; i++) {
- xmin = (left_x >> 16);
- xmax = (right_x >> 16) - 1; //!!!!!!!!!!!!!
- if (g_prim.drawW < xmax)
- xmax = g_prim.drawW;
-
- if (xmax >= xmin) {
- posX = left_u;
- posY = left_v;
-
- if (xmin < g_prim.drawX) {
- j = g_prim.drawX - xmin;
- xmin = g_prim.drawX;
- posX += j * difX;
- posY += j * difY;
- }
-
- for (j = xmin; j < xmax; j += 2) {
- GetTextureTransColG32_S(
- (uint32_t *) &g_gpu.psx_vram.u16[(i << 10) + j],
- (((int32_t) GETLE16(&g_gpu.psx_vram.u16[((((posY+difY)>>16)+g_soft.GlobalTextAddrY)<<10)+((posX+difX)>>16)+g_soft.GlobalTextAddrX]))
- << 16)
- | GETLE16(&g_gpu.psx_vram.u16[(((posY>>16)+g_soft.GlobalTextAddrY)<<10)+((posX)>>16)+g_soft.GlobalTextAddrX]));
-
- posX += difX2;
- posY += difY2;
- }
- if (j == xmax)
- GetTextureTransColG_S(
- &g_gpu.psx_vram.u16[(i << 10) + j],
- GETLE16(&g_gpu.psx_vram.u16[(((posY>>16)+g_soft.GlobalTextAddrY)<<10)+(posX>>16)+g_soft.GlobalTextAddrX]));
- }
- if (NextRow_FT()) {
- return;
- }
- }
- return;
- }
-
-#endif
-
- for (i = ymin; i <= ymax; i++) {
- xmin = (left_x >> 16);
- xmax = (right_x >> 16) - 1; //!!!!!!!!!!!!!!
- if (g_prim.drawW < xmax)
- xmax = g_prim.drawW;
-
- if (xmax >= xmin) {
- posX = left_u;
- posY = left_v;
-
- if (xmin < g_prim.drawX) {
- j = g_prim.drawX - xmin;
- xmin = g_prim.drawX;
- posX += j * difX;
- posY += j * difY;
- }
-
- for (j = xmin; j < xmax; j += 2) {
- GetTextureTransColG32(
- (uint32_t *) &g_gpu.psx_vram.u16[(i << 10) + j],
- (((int32_t) GETLE16(&g_gpu.psx_vram.u16[((((posY+difY)>>16)+g_soft.GlobalTextAddrY)<<10)+((posX+difX)>>16)+g_soft.GlobalTextAddrX]))
- << 16)
- | GETLE16(&g_gpu.psx_vram.u16[(((posY>>16)+g_soft.GlobalTextAddrY)<<10)+((posX)>>16)+g_soft.GlobalTextAddrX]));
-
- posX += difX2;
- posY += difY2;
- }
- if (j == xmax)
- GetTextureTransColG(
- &g_gpu.psx_vram.u16[(i << 10) + j],
- GETLE16(&g_gpu.psx_vram.u16[(((posY>>16)+g_soft.GlobalTextAddrY)<<10)+(posX>>16)+g_soft.GlobalTextAddrX]));
- }
- if (NextRow_FT()) {
- return;
- }
- }
-}
-
-////////////////////////////////////////////////////////////////////////
-
-static void drawPoly3TD_TW(short x1, short y1, short x2, short y2, short x3, short y3,
- short tx1, short ty1, short tx2, short ty2, short tx3, short ty3) {
- int i, j, xmin, xmax, ymin, ymax;
- int32_t difX, difY, difX2, difY2;
- int32_t posX, posY;
-
- if (x1 > g_prim.drawW && x2 > g_prim.drawW && x3 > g_prim.drawW)
- return;
- if (y1 > g_prim.drawH && y2 > g_prim.drawH && y3 > g_prim.drawH)
- return;
- if (x1 < g_prim.drawX && x2 < g_prim.drawX && x3 < g_prim.drawX)
- return;
- if (y1 < g_prim.drawY && y2 < g_prim.drawY && y3 < g_prim.drawY)
- return;
- if (g_prim.drawY >= g_prim.drawH)
- return;
- if (g_prim.drawX >= g_prim.drawW)
- return;
-
- if (!SetupSections_FT(x1, y1, x2, y2, x3, y3, tx1, ty1, tx2, ty2, tx3, ty3))
- return;
-
- ymax = g_soft.Ymax;
-
- for (ymin = g_soft.Ymin; ymin < g_prim.drawY; ymin++)
- if (NextRow_FT())
- return;
-
- difX = delta_right_u;
- difX2 = difX << 1;
- difY = delta_right_v;
- difY2 = difY << 1;
-
-#ifdef FASTSOLID
-
- if (!g_draw.bCheckMask && !g_soft.DrawSemiTrans) {
- for (i = ymin; i <= ymax; i++) {
- xmin = (left_x >> 16);
- xmax = (right_x >> 16) - 1; //!!!!!!!!!!!!!
- if (g_prim.drawW < xmax)
- xmax = g_prim.drawW;
-
- if (xmax >= xmin) {
- posX = left_u;
- posY = left_v;
-
- if (xmin < g_prim.drawX) {
- j = g_prim.drawX - xmin;
- xmin = g_prim.drawX;
- posX += j * difX;
- posY += j * difY;
- }
-
- for (j = xmin; j < xmax; j += 2) {
- GetTextureTransColG32_S(
- (uint32_t *) &g_gpu.psx_vram.u16[(i << 10) + j],
- (((int32_t) GETLE16(&g_gpu.psx_vram.u16[(((((posY+difY)>>16)%g_prim.TWin.Position.y1)+g_soft.GlobalTextAddrY+g_prim.TWin.Position.y0)<<10)+
- (((posX+difX)>>16)%g_prim.TWin.Position.x1)+g_soft.GlobalTextAddrX+g_prim.TWin.Position.x0]))
- << 16)
- | GETLE16(&g_gpu.psx_vram.u16[((((posY>>16)%g_prim.TWin.Position.y1)+g_soft.GlobalTextAddrY+g_prim.TWin.Position.y0)<<10)+
- (((posX)>>16)%g_prim.TWin.Position.x1)+g_soft.GlobalTextAddrX+g_prim.TWin.Position.x0]));
-
- posX += difX2;
- posY += difY2;
- }
- if (j == xmax)
- GetTextureTransColG_S(
- &g_gpu.psx_vram.u16[(i << 10) + j],
- GETLE16(&g_gpu.psx_vram.u16[((((posY>>16)%g_prim.TWin.Position.y1)+g_soft.GlobalTextAddrY+g_prim.TWin.Position.y0)<<10)+
- ((posX>>16)%g_prim.TWin.Position.x1)+g_soft.GlobalTextAddrX+g_prim.TWin.Position.x0]));
- }
- if (NextRow_FT()) {
- return;
- }
- }
- return;
- }
-
-#endif
-
- for (i = ymin; i <= ymax; i++) {
- xmin = (left_x >> 16);
- xmax = (right_x >> 16) - 1; //!!!!!!!!!!!!!!
- if (g_prim.drawW < xmax)
- xmax = g_prim.drawW;
-
- if (xmax >= xmin) {
- posX = left_u;
- posY = left_v;
-
- if (xmin < g_prim.drawX) {
- j = g_prim.drawX - xmin;
- xmin = g_prim.drawX;
- posX += j * difX;
- posY += j * difY;
- }
-
- for (j = xmin; j < xmax; j += 2) {
- GetTextureTransColG32(
- (uint32_t *) &g_gpu.psx_vram.u16[(i << 10) + j],
- (((int32_t) GETLE16(&g_gpu.psx_vram.u16[(((((posY+difY)>>16)%g_prim.TWin.Position.y1)+g_soft.GlobalTextAddrY+g_prim.TWin.Position.y0)<<10)+
- (((posX+difX)>>16)%g_prim.TWin.Position.x1)+g_soft.GlobalTextAddrX+g_prim.TWin.Position.x0]))
- << 16)
- | GETLE16(&g_gpu.psx_vram.u16[((((posY>>16)%g_prim.TWin.Position.y1)+g_soft.GlobalTextAddrY+g_prim.TWin.Position.y0)<<10)+
- (((posX)>>16)%g_prim.TWin.Position.x1)+g_soft.GlobalTextAddrX+g_prim.TWin.Position.x0]));
-
- posX += difX2;
- posY += difY2;
- }
- if (j == xmax)
- GetTextureTransColG(
- &g_gpu.psx_vram.u16[(i << 10) + j],
- GETLE16(&g_gpu.psx_vram.u16[((((posY>>16)%g_prim.TWin.Position.y1)+g_soft.GlobalTextAddrY+g_prim.TWin.Position.y0)<<10)+
- ((posX>>16)%g_prim.TWin.Position.x1)+g_soft.GlobalTextAddrX+g_prim.TWin.Position.x0]));
- }
- if (NextRow_FT()) {
- return;
- }
- }
-}
-
-////////////////////////////////////////////////////////////////////////
-
-#ifdef POLYQUAD3
-
-static void drawPoly4TD_TRI(short x1, short y1, short x2, short y2, short x3,
- short y3, short x4, short y4, short tx1, short ty1, short tx2,
- short ty2, short tx3, short ty3, short tx4, short ty4) {
- drawPoly3TD(x2, y2, x3, y3, x4, y4, tx2, ty2, tx3, ty3, tx4, ty4);
- drawPoly3TD(x1, y1, x2, y2, x4, y4, tx1, ty1, tx2, ty2, tx4, ty4);
-}
-
-#endif
-
-// more exact:
-
-static void drawPoly4TD(short x1, short y1, short x2, short y2, short x3, short y3,
- short x4, short y4, short tx1, short ty1, short tx2, short ty2,
- short tx3, short ty3, short tx4, short ty4) {
- int32_t num;
- int32_t i, j, xmin, xmax, ymin, ymax;
- int32_t difX, difY, difX2, difY2;
- int32_t posX, posY;
-
- if (x1 > g_prim.drawW && x2 > g_prim.drawW && x3 > g_prim.drawW && x4
- > g_prim.drawW)
- return;
- if (y1 > g_prim.drawH && y2 > g_prim.drawH && y3 > g_prim.drawH && y4
- > g_prim.drawH)
- return;
- if (x1 < g_prim.drawX && x2 < g_prim.drawX && x3 < g_prim.drawX && x4
- < g_prim.drawX)
- return;
- if (y1 < g_prim.drawY && y2 < g_prim.drawY && y3 < g_prim.drawY && y4
- < g_prim.drawY)
- return;
- if (g_prim.drawY >= g_prim.drawH)
- return;
- if (g_prim.drawX >= g_prim.drawW)
- return;
-
- if (!SetupSections_FT4(x1, y1, x2, y2, x3, y3, x4, y4, tx1, ty1, tx2, ty2,
- tx3, ty3, tx4, ty4))
- return;
-
- ymax = g_soft.Ymax;
-
- for (ymin = g_soft.Ymin; ymin < g_prim.drawY; ymin++)
- if (NextRow_FT4())
- return;
-
-#ifdef FASTSOLID
-
- if (!g_draw.bCheckMask && !g_soft.DrawSemiTrans) {
- for (i = ymin; i <= ymax; i++) {
- xmin = (left_x >> 16);
- xmax = (right_x >> 16);
-
- if (xmax >= xmin) {
- posX = left_u;
- posY = left_v;
-
- num = (xmax - xmin);
- if (num == 0)
- num = 1;
- difX = (right_u - posX) / num;
- difY = (right_v - posY) / num;
- difX2 = difX << 1;
- difY2 = difY << 1;
-
- if (xmin < g_prim.drawX) {
- j = g_prim.drawX - xmin;
- xmin = g_prim.drawX;
- posX += j * difX;
- posY += j * difY;
- }
- xmax--;
- if (g_prim.drawW < xmax)
- xmax = g_prim.drawW;
-
- for (j = xmin; j < xmax; j += 2) {
- GetTextureTransColG32_S(
- (uint32_t *) &g_gpu.psx_vram.u16[(i << 10) + j],
- (((int32_t) GETLE16(&g_gpu.psx_vram.u16[((((posY+difY)>>16)+g_soft.GlobalTextAddrY)<<10)+((posX+difX)>>16)+g_soft.GlobalTextAddrX]))
- << 16)
- | GETLE16(&g_gpu.psx_vram.u16[(((posY>>16)+g_soft.GlobalTextAddrY)<<10)+((posX)>>16)+g_soft.GlobalTextAddrX]));
-
- posX += difX2;
- posY += difY2;
- }
- if (j == xmax)
- GetTextureTransColG_S(
- &g_gpu.psx_vram.u16[(i << 10) + j],
- GETLE16(&g_gpu.psx_vram.u16[(((posY>>16)+g_soft.GlobalTextAddrY)<<10)+(posX>>16)+g_soft.GlobalTextAddrX]));
- }
- if (NextRow_FT4())
- return;
- }
- return;
- }
-
-#endif
-
- for (i = ymin; i <= ymax; i++) {
- xmin = (left_x >> 16);
- xmax = (right_x >> 16);
-
- if (xmax >= xmin) {
- posX = left_u;
- posY = left_v;
-
- num = (xmax - xmin);
- if (num == 0)
- num = 1;
- difX = (right_u - posX) / num;
- difY = (right_v - posY) / num;
- difX2 = difX << 1;
- difY2 = difY << 1;
-
- if (xmin < g_prim.drawX) {
- j = g_prim.drawX - xmin;
- xmin = g_prim.drawX;
- posX += j * difX;
- posY += j * difY;
- }
- xmax--;
- if (g_prim.drawW < xmax)
- xmax = g_prim.drawW;
-
- for (j = xmin; j < xmax; j += 2) {
- GetTextureTransColG32(
- (uint32_t *) &g_gpu.psx_vram.u16[(i << 10) + j],
- (((int32_t) GETLE16(&g_gpu.psx_vram.u16[((((posY+difY)>>16)+g_soft.GlobalTextAddrY)<<10)+((posX+difX)>>16)+g_soft.GlobalTextAddrX]))
- << 16)
- | GETLE16(&g_gpu.psx_vram.u16[(((posY>>16)+g_soft.GlobalTextAddrY)<<10)+((posX)>>16)+g_soft.GlobalTextAddrX]));
-
- posX += difX2;
- posY += difY2;
- }
- if (j == xmax)
- GetTextureTransColG(
- &g_gpu.psx_vram.u16[(i << 10) + j],
- GETLE16(&g_gpu.psx_vram.u16[(((posY>>16)+g_soft.GlobalTextAddrY)<<10)+(posX>>16)+g_soft.GlobalTextAddrX]));
- }
- if (NextRow_FT4())
- return;
- }
-}
-
-////////////////////////////////////////////////////////////////////////
-
-static void drawPoly4TD_TW(short x1, short y1, short x2, short y2, short x3, short y3,
- short x4, short y4, short tx1, short ty1, short tx2, short ty2,
- short tx3, short ty3, short tx4, short ty4) {
- int32_t num;
- int32_t i, j, xmin, xmax, ymin, ymax;
- int32_t difX, difY, difX2, difY2;
- int32_t posX, posY;
-
- if (x1 > g_prim.drawW && x2 > g_prim.drawW && x3 > g_prim.drawW && x4
- > g_prim.drawW)
- return;
- if (y1 > g_prim.drawH && y2 > g_prim.drawH && y3 > g_prim.drawH && y4
- > g_prim.drawH)
- return;
- if (x1 < g_prim.drawX && x2 < g_prim.drawX && x3 < g_prim.drawX && x4
- < g_prim.drawX)
- return;
- if (y1 < g_prim.drawY && y2 < g_prim.drawY && y3 < g_prim.drawY && y4
- < g_prim.drawY)
- return;
- if (g_prim.drawY >= g_prim.drawH)
- return;
- if (g_prim.drawX >= g_prim.drawW)
- return;
-
- if (!SetupSections_FT4(x1, y1, x2, y2, x3, y3, x4, y4, tx1, ty1, tx2, ty2,
- tx3, ty3, tx4, ty4))
- return;
-
- ymax = g_soft.Ymax;
-
- for (ymin = g_soft.Ymin; ymin < g_prim.drawY; ymin++)
- if (NextRow_FT4())
- return;
-
-#ifdef FASTSOLID
-
- if (!g_draw.bCheckMask && !g_soft.DrawSemiTrans) {
- for (i = ymin; i <= ymax; i++) {
- xmin = (left_x >> 16);
- xmax = (right_x >> 16);
-
- if (xmax >= xmin) {
- posX = left_u;
- posY = left_v;
-
- num = (xmax - xmin);
- if (num == 0)
- num = 1;
- difX = (right_u - posX) / num;
- difY = (right_v - posY) / num;
- difX2 = difX << 1;
- difY2 = difY << 1;
-
- if (xmin < g_prim.drawX) {
- j = g_prim.drawX - xmin;
- xmin = g_prim.drawX;
- posX += j * difX;
- posY += j * difY;
- }
- xmax--;
- if (g_prim.drawW < xmax)
- xmax = g_prim.drawW;
-
- for (j = xmin; j < xmax; j += 2) {
- GetTextureTransColG32_S(
- (uint32_t *) &g_gpu.psx_vram.u16[(i << 10) + j],
- (((int32_t) GETLE16(&g_gpu.psx_vram.u16[(((((posY+difY)>>16)%g_prim.TWin.Position.y1)+g_soft.GlobalTextAddrY+g_prim.TWin.Position.y0)<<10)+
- (((posX+difX)>>16)%g_prim.TWin.Position.x1)+g_soft.GlobalTextAddrX+g_prim.TWin.Position.x0]))
- << 16)
- | GETLE16(&g_gpu.psx_vram.u16[((((posY>>16)%g_prim.TWin.Position.y1)+g_soft.GlobalTextAddrY)<<10)+g_prim.TWin.Position.y0+
- ((posX>>16)%g_prim.TWin.Position.x1)+g_soft.GlobalTextAddrX+g_prim.TWin.Position.x0]));
-
- posX += difX2;
- posY += difY2;
- }
- if (j == xmax)
- GetTextureTransColG_S(
- &g_gpu.psx_vram.u16[(i << 10) + j],
- GETLE16(&g_gpu.psx_vram.u16[((((posY>>16)%g_prim.TWin.Position.y1)+g_soft.GlobalTextAddrY+g_prim.TWin.Position.y0)<<10)+
- ((posX>>16)%g_prim.TWin.Position.x1)+g_soft.GlobalTextAddrX+g_prim.TWin.Position.x0]));
- }
- if (NextRow_FT4())
- return;
- }
- return;
- }
-
-#endif
-
- for (i = ymin; i <= ymax; i++) {
- xmin = (left_x >> 16);
- xmax = (right_x >> 16);
-
- if (xmax >= xmin) {
- posX = left_u;
- posY = left_v;
-
- num = (xmax - xmin);
- if (num == 0)
- num = 1;
- difX = (right_u - posX) / num;
- difY = (right_v - posY) / num;
- difX2 = difX << 1;
- difY2 = difY << 1;
-
- if (xmin < g_prim.drawX) {
- j = g_prim.drawX - xmin;
- xmin = g_prim.drawX;
- posX += j * difX;
- posY += j * difY;
- }
- xmax--;
- if (g_prim.drawW < xmax)
- xmax = g_prim.drawW;
-
- for (j = xmin; j < xmax; j += 2) {
- GetTextureTransColG32(
- (uint32_t *) &g_gpu.psx_vram.u16[(i << 10) + j],
- (((int32_t) GETLE16(&g_gpu.psx_vram.u16[(((((posY+difY)>>16)%g_prim.TWin.Position.y1)+g_soft.GlobalTextAddrY+g_prim.TWin.Position.y0)<<10)+
- (((posX+difX)>>16)%g_prim.TWin.Position.x1)+g_soft.GlobalTextAddrX+g_prim.TWin.Position.x0]))
- << 16)
- | GETLE16(&g_gpu.psx_vram.u16[((((posY>>16)%g_prim.TWin.Position.y1)+g_soft.GlobalTextAddrY+g_prim.TWin.Position.y0)<<10)+
- ((posX>>16)%g_prim.TWin.Position.x1)+g_soft.GlobalTextAddrX+g_prim.TWin.Position.x0]));
-
- posX += difX2;
- posY += difY2;
- }
- if (j == xmax)
- GetTextureTransColG(
- &g_gpu.psx_vram.u16[(i << 10) + j],
- GETLE16(&g_gpu.psx_vram.u16[((((posY>>16)%g_prim.TWin.Position.y1)+g_soft.GlobalTextAddrY+g_prim.TWin.Position.y0)<<10)+
- ((posX>>16)%g_prim.TWin.Position.x1)+g_soft.GlobalTextAddrX+g_prim.TWin.Position.x0]));
- }
- if (NextRow_FT4())
- return;
- }
-}
-
-////////////////////////////////////////////////////////////////////////
-
-static void drawPoly4TD_TW_S(short x1, short y1, short x2, short y2, short x3,
- short y3, short x4, short y4, short tx1, short ty1, short tx2,
- short ty2, short tx3, short ty3, short tx4, short ty4) {
- int32_t num;
- int32_t i, j, xmin, xmax, ymin, ymax;
- int32_t difX, difY, difX2, difY2;
- int32_t posX, posY;
-
- if (x1 > g_prim.drawW && x2 > g_prim.drawW && x3 > g_prim.drawW && x4
- > g_prim.drawW)
- return;
- if (y1 > g_prim.drawH && y2 > g_prim.drawH && y3 > g_prim.drawH && y4
- > g_prim.drawH)
- return;
- if (x1 < g_prim.drawX && x2 < g_prim.drawX && x3 < g_prim.drawX && x4
- < g_prim.drawX)
- return;
- if (y1 < g_prim.drawY && y2 < g_prim.drawY && y3 < g_prim.drawY && y4
- < g_prim.drawY)
- return;
- if (g_prim.drawY >= g_prim.drawH)
- return;
- if (g_prim.drawX >= g_prim.drawW)
- return;
-
- if (!SetupSections_FT4(x1, y1, x2, y2, x3, y3, x4, y4, tx1, ty1, tx2, ty2,
- tx3, ty3, tx4, ty4))
- return;
-
- ymax = g_soft.Ymax;
-
- for (ymin = g_soft.Ymin; ymin < g_prim.drawY; ymin++)
- if (NextRow_FT4())
- return;
-
-#ifdef FASTSOLID
-
- if (!g_draw.bCheckMask && !g_soft.DrawSemiTrans) {
- for (i = ymin; i <= ymax; i++) {
- xmin = (left_x >> 16);
- xmax = (right_x >> 16);
-
- if (xmax >= xmin) {
- posX = left_u;
- posY = left_v;
-
- num = (xmax - xmin);
- if (num == 0)
- num = 1;
- difX = (right_u - posX) / num;
- difY = (right_v - posY) / num;
- difX2 = difX << 1;
- difY2 = difY << 1;
-
- if (xmin < g_prim.drawX) {
- j = g_prim.drawX - xmin;
- xmin = g_prim.drawX;
- posX += j * difX;
- posY += j * difY;
- }
- xmax--;
- if (g_prim.drawW < xmax)
- xmax = g_prim.drawW;
-
- for (j = xmin; j < xmax; j += 2) {
- GetTextureTransColG32_S(
- (uint32_t *) &g_gpu.psx_vram.u16[(i << 10) + j],
- (((int32_t) GETLE16(&g_gpu.psx_vram.u16[(((((posY+difY)>>16)%g_prim.TWin.Position.y1)+g_soft.GlobalTextAddrY+g_prim.TWin.Position.y0)<<10)+
- (((posX+difX)>>16)%g_prim.TWin.Position.x1)+g_soft.GlobalTextAddrX+g_prim.TWin.Position.x0]))
- << 16)
- | GETLE16(&g_gpu.psx_vram.u16[((((posY>>16)%g_prim.TWin.Position.y1)+g_soft.GlobalTextAddrY)<<10)+g_prim.TWin.Position.y0+
- ((posX>>16)%g_prim.TWin.Position.x1)+g_soft.GlobalTextAddrX+g_prim.TWin.Position.x0]));
-
- posX += difX2;
- posY += difY2;
- }
- if (j == xmax)
- GetTextureTransColG_S(
- &g_gpu.psx_vram.u16[(i << 10) + j],
- GETLE16(&g_gpu.psx_vram.u16[((((posY>>16)%g_prim.TWin.Position.y1)+g_soft.GlobalTextAddrY+g_prim.TWin.Position.y0)<<10)+
- ((posX>>16)%g_prim.TWin.Position.x1)+g_soft.GlobalTextAddrX+g_prim.TWin.Position.x0]));
- }
- if (NextRow_FT4())
- return;
- }
- return;
- }
-
-#endif
-
- for (i = ymin; i <= ymax; i++) {
- xmin = (left_x >> 16);
- xmax = (right_x >> 16);
-
- if (xmax >= xmin) {
- posX = left_u;
- posY = left_v;
-
- num = (xmax - xmin);
- if (num == 0)
- num = 1;
- difX = (right_u - posX) / num;
- difY = (right_v - posY) / num;
- difX2 = difX << 1;
- difY2 = difY << 1;
-
- if (xmin < g_prim.drawX) {
- j = g_prim.drawX - xmin;
- xmin = g_prim.drawX;
- posX += j * difX;
- posY += j * difY;
- }
- xmax--;
- if (g_prim.drawW < xmax)
- xmax = g_prim.drawW;
-
- for (j = xmin; j < xmax; j += 2) {
- GetTextureTransColG32_SPR(
- (uint32_t *) &g_gpu.psx_vram.u16[(i << 10) + j],
- (((int32_t) GETLE16(&g_gpu.psx_vram.u16[(((((posY+difY)>>16)%g_prim.TWin.Position.y1)+g_soft.GlobalTextAddrY+g_prim.TWin.Position.y0)<<10)+
- (((posX+difX)>>16)%g_prim.TWin.Position.x1)+g_soft.GlobalTextAddrX+g_prim.TWin.Position.x0]))
- << 16)
- | GETLE16(&g_gpu.psx_vram.u16[((((posY>>16)%g_prim.TWin.Position.y1)+g_soft.GlobalTextAddrY+g_prim.TWin.Position.y0)<<10)+
- ((posX>>16)%g_prim.TWin.Position.x1)+g_soft.GlobalTextAddrX+g_prim.TWin.Position.x0]));
-
- posX += difX2;
- posY += difY2;
- }
- if (j == xmax)
- GetTextureTransColG_SPR(
- &g_gpu.psx_vram.u16[(i << 10) + j],
- GETLE16(&g_gpu.psx_vram.u16[((((posY>>16)%g_prim.TWin.Position.y1)+g_soft.GlobalTextAddrY+g_prim.TWin.Position.y0)<<10)+
- ((posX>>16)%g_prim.TWin.Position.x1)+g_soft.GlobalTextAddrX+g_prim.TWin.Position.x0]));
- }
- if (NextRow_FT4())
- return;
- }
-}
-
-////////////////////////////////////////////////////////////////////////
-// POLY 3/4 G-SHADED
-////////////////////////////////////////////////////////////////////////
-
-static inline void drawPoly3Gi(short x1, short y1, short x2, short y2, short x3,
- short y3, int32_t rgb1, int32_t rgb2, int32_t rgb3) {
- int i, j, xmin, xmax, ymin, ymax;
- int32_t cR1, cG1, cB1;
- int32_t difR, difB, difG, difR2, difB2, difG2;
-
- if (x1 > g_prim.drawW && x2 > g_prim.drawW && x3 > g_prim.drawW)
- return;
- if (y1 > g_prim.drawH && y2 > g_prim.drawH && y3 > g_prim.drawH)
- return;
- if (x1 < g_prim.drawX && x2 < g_prim.drawX && x3 < g_prim.drawX)
- return;
- if (y1 < g_prim.drawY && y2 < g_prim.drawY && y3 < g_prim.drawY)
- return;
- if (g_prim.drawY >= g_prim.drawH)
- return;
- if (g_prim.drawX >= g_prim.drawW)
- return;
-
- if (!SetupSections_G(x1, y1, x2, y2, x3, y3, rgb1, rgb2, rgb3))
- return;
-
- ymax = g_soft.Ymax;
-
- for (ymin = g_soft.Ymin; ymin < g_prim.drawY; ymin++)
- if (NextRow_G())
- return;
-
- difR = delta_right_R;
- difG = delta_right_G;
- difB = delta_right_B;
- difR2 = difR << 1;
- difG2 = difG << 1;
- difB2 = difB << 1;
-
-#ifdef FASTSOLID
-
- if (!g_draw.bCheckMask && !g_soft.DrawSemiTrans && g_prim.iDither != 2) {
- for (i = ymin; i <= ymax; i++) {
- xmin = (left_x >> 16);
- xmax = (right_x >> 16) - 1;
- if (g_prim.drawW < xmax)
- xmax = g_prim.drawW;
-
- if (xmax >= xmin) {
- cR1 = left_R;
- cG1 = left_G;
- cB1 = left_B;
-
- if (xmin < g_prim.drawX) {
- j = g_prim.drawX - xmin;
- xmin = g_prim.drawX;
- cR1 += j * difR;
- cG1 += j * difG;
- cB1 += j * difB;
- }
-
- for (j = xmin; j < xmax; j += 2) {
- PUTLE32(((uint32_t *)&g_gpu.psx_vram.u16[(i<<10)+j]),
- ((((cR1+difR) <<7)&0x7c000000)|(((cG1+difG) << 2)&0x03e00000)|(((cB1+difB)>>3)&0x001f0000)|
- (((cR1) >> 9)&0x7c00)|(((cG1) >> 14)&0x03e0)|(((cB1) >> 19)&0x001f))|g_draw.lSetMask);
-
- cR1 += difR2;
- cG1 += difG2;
- cB1 += difB2;
- }
- if (j == xmax)
- PUTLE16(&g_gpu.psx_vram.u16[(i<<10)+j], (((cR1 >> 9)&0x7c00)|((cG1 >> 14)&0x03e0)|((cB1 >> 19)&0x001f))|g_draw.sSetMask);
- }
- if (NextRow_G())
- return;
- }
- return;
- }
-
-#endif
-
- if (g_prim.iDither == 2)
- for (i = ymin; i <= ymax; i++) {
- xmin = (left_x >> 16);
- xmax = (right_x >> 16) - 1;
- if (g_prim.drawW < xmax)
- xmax = g_prim.drawW;
-
- if (xmax >= xmin) {
- cR1 = left_R;
- cG1 = left_G;
- cB1 = left_B;
-
- if (xmin < g_prim.drawX) {
- j = g_prim.drawX - xmin;
- xmin = g_prim.drawX;
- cR1 += j * difR;
- cG1 += j * difG;
- cB1 += j * difB;
- }
-
- for (j = xmin; j <= xmax; j++) {
- GetShadeTransCol_Dither(&g_gpu.psx_vram.u16[(i << 10) + j],
- (cB1 >> 16), (cG1 >> 16), (cR1 >> 16));
-
- cR1 += difR;
- cG1 += difG;
- cB1 += difB;
- }
- }
- if (NextRow_G())
- return;
- }
- else
- for (i = ymin; i <= ymax; i++) {
- xmin = (left_x >> 16);
- xmax = (right_x >> 16) - 1;
- if (g_prim.drawW < xmax)
- xmax = g_prim.drawW;
-
- if (xmax >= xmin) {
- cR1 = left_R;
- cG1 = left_G;
- cB1 = left_B;
-
- if (xmin < g_prim.drawX) {
- j = g_prim.drawX - xmin;
- xmin = g_prim.drawX;
- cR1 += j * difR;
- cG1 += j * difG;
- cB1 += j * difB;
- }
-
- for (j = xmin; j <= xmax; j++) {
- GetShadeTransCol(&g_gpu.psx_vram.u16[(i << 10) + j], ((cR1
- >> 9) & 0x7c00) | ((cG1 >> 14) & 0x03e0) | ((cB1
- >> 19) & 0x001f));
-
- cR1 += difR;
- cG1 += difG;
- cB1 += difB;
- }
- }
- if (NextRow_G())
- return;
- }
-
-}
-
-////////////////////////////////////////////////////////////////////////
-
-void drawPoly3G(int32_t rgb1, int32_t rgb2, int32_t rgb3) {
- drawPoly3Gi(g_soft.lx0, g_soft.ly0, g_soft.lx1, g_soft.ly1, g_soft.lx2,
- g_soft.ly2, rgb1, rgb2, rgb3);
-}
-
-// draw two g-shaded tris for right psx shading emulation
-
-void drawPoly4G(int32_t rgb1, int32_t rgb2, int32_t rgb3, int32_t rgb4) {
- drawPoly3Gi(g_soft.lx1, g_soft.ly1, g_soft.lx3, g_soft.ly3, g_soft.lx2,
- g_soft.ly2, rgb2, rgb4, rgb3);
- drawPoly3Gi(g_soft.lx0, g_soft.ly0, g_soft.lx1, g_soft.ly1, g_soft.lx2,
- g_soft.ly2, rgb1, rgb2, rgb3);
-}
-
-////////////////////////////////////////////////////////////////////////
-// POLY 3/4 G-SHADED TEX PAL4
-////////////////////////////////////////////////////////////////////////
-
-static void drawPoly3TGEx4(short x1, short y1, short x2, short y2, short x3, short y3,
- short tx1, short ty1, short tx2, short ty2, short tx3, short ty3,
- short clX, short clY, int32_t col1, int32_t col2, int32_t col3) {
- int i, j, xmin, xmax, ymin, ymax;
- int32_t cR1, cG1, cB1;
- int32_t difR, difB, difG, difR2, difB2, difG2;
- int32_t difX, difY, difX2, difY2;
- int32_t posX, posY, YAdjust, clutP, XAdjust;
- short tC1, tC2;
-
- if (x1 > g_prim.drawW && x2 > g_prim.drawW && x3 > g_prim.drawW)
- return;
- if (y1 > g_prim.drawH && y2 > g_prim.drawH && y3 > g_prim.drawH)
- return;
- if (x1 < g_prim.drawX && x2 < g_prim.drawX && x3 < g_prim.drawX)
- return;
- if (y1 < g_prim.drawY && y2 < g_prim.drawY && y3 < g_prim.drawY)
- return;
- if (g_prim.drawY >= g_prim.drawH)
- return;
- if (g_prim.drawX >= g_prim.drawW)
- return;
-
- if (!SetupSections_GT(x1, y1, x2, y2, x3, y3, tx1, ty1, tx2, ty2, tx3, ty3,
- col1, col2, col3))
- return;
-
- ymax = g_soft.Ymax;
-
- for (ymin = g_soft.Ymin; ymin < g_prim.drawY; ymin++)
- if (NextRow_GT())
- return;
-
- clutP = (clY << 10) + clX;
-
- YAdjust = ((g_soft.GlobalTextAddrY) << 11) + (g_soft.GlobalTextAddrX << 1);
-
- difR = delta_right_R;
- difG = delta_right_G;
- difB = delta_right_B;
- difR2 = difR << 1;
- difG2 = difG << 1;
- difB2 = difB << 1;
-
- difX = delta_right_u;
- difX2 = difX << 1;
- difY = delta_right_v;
- difY2 = difY << 1;
-
-#ifdef FASTSOLID
-
- if (!g_draw.bCheckMask && !g_soft.DrawSemiTrans && !g_prim.iDither) {
- for (i = ymin; i <= ymax; i++) {
- xmin = ((left_x) >> 16);
- xmax = ((right_x) >> 16) - 1; //!!!!!!!!!!!!!
- if (g_prim.drawW < xmax)
- xmax = g_prim.drawW;
-
- if (xmax >= xmin) {
- posX = left_u;
- posY = left_v;
- cR1 = left_R;
- cG1 = left_G;
- cB1 = left_B;
-
- if (xmin < g_prim.drawX) {
- j = g_prim.drawX - xmin;
- xmin = g_prim.drawX;
- posX += j * difX;
- posY += j * difY;
- cR1 += j * difR;
- cG1 += j * difG;
- cB1 += j * difB;
- }
-
- for (j = xmin; j < xmax; j += 2) {
- XAdjust = (posX >> 16);
- tC1 = g_gpu.psx_vram.u8[((posY >> 5) & 0xFFFFF800)
- + YAdjust + (XAdjust >> 1)];
- tC1 = (tC1 >> ((XAdjust & 1) << 2)) & 0xf;
- XAdjust = ((posX + difX) >> 16);
- tC2 = g_gpu.psx_vram.u8[(((posY + difY) >> 5)
- & (int32_t) 0xFFFFF800) + YAdjust + (XAdjust >> 1)];
- tC2 = (tC2 >> ((XAdjust & 1) << 2)) & 0xf;
-
- GetTextureTransColGX32_S(
- (uint32_t *) &g_gpu.psx_vram.u16[(i << 10) + j],
- GETLE16(&g_gpu.psx_vram.u16[clutP+tC1])
- | ((int32_t) GETLE16(&g_gpu.psx_vram.u16[clutP+tC2]))
- << 16, (cB1 >> 16) | ((cB1 + difB)
- & 0xff0000), (cG1 >> 16) | ((cG1 + difG)
- & 0xff0000), (cR1 >> 16) | ((cR1 + difR)
- & 0xff0000));
- posX += difX2;
- posY += difY2;
- cR1 += difR2;
- cG1 += difG2;
- cB1 += difB2;
- }
- if (j == xmax) {
- XAdjust = (posX >> 16);
- tC1
- = g_gpu.psx_vram.u8[((posY >> 5)
- & (int32_t) 0xFFFFF800) + YAdjust
- + (XAdjust >> 1)];
- tC1 = (tC1 >> ((XAdjust & 1) << 2)) & 0xf;
- GetTextureTransColGX_S(&g_gpu.psx_vram.u16[(i << 10) + j],
- GETLE16(&g_gpu.psx_vram.u16[clutP+tC1]),
- (cB1 >> 16), (cG1 >> 16), (cR1 >> 16));
- }
- }
- if (NextRow_GT()) {
- return;
- }
- }
- return;
- }
-
-#endif
-
- for (i = ymin; i <= ymax; i++) {
- xmin = (left_x >> 16);
- xmax = (right_x >> 16) - 1; //!!!!!!!!!!!!!!!!
- if (g_prim.drawW < xmax)
- xmax = g_prim.drawW;
-
- if (xmax >= xmin) {
- posX = left_u;
- posY = left_v;
- cR1 = left_R;
- cG1 = left_G;
- cB1 = left_B;
-
- if (xmin < g_prim.drawX) {
- j = g_prim.drawX - xmin;
- xmin = g_prim.drawX;
- posX += j * difX;
- posY += j * difY;
- cR1 += j * difR;
- cG1 += j * difG;
- cB1 += j * difB;
- }
-
- for (j = xmin; j <= xmax; j++) {
- XAdjust = (posX >> 16);
- tC1 = g_gpu.psx_vram.u8[((posY >> 5) & (int32_t) 0xFFFFF800)
- + YAdjust + (XAdjust >> 1)];
- tC1 = (tC1 >> ((XAdjust & 1) << 2)) & 0xf;
- if (g_prim.iDither)
- GetTextureTransColGX_Dither(&g_gpu.psx_vram.u16[(i << 10)
- + j], GETLE16(&g_gpu.psx_vram.u16[clutP+tC1]), (cB1
- >> 16), (cG1 >> 16), (cR1 >> 16));
- else
- GetTextureTransColGX(&g_gpu.psx_vram.u16[(i << 10) + j],
- GETLE16(&g_gpu.psx_vram.u16[clutP+tC1]),
- (cB1 >> 16), (cG1 >> 16), (cR1 >> 16));
- posX += difX;
- posY += difY;
- cR1 += difR;
- cG1 += difG;
- cB1 += difB;
- }
- }
- if (NextRow_GT()) {
- return;
- }
- }
-}
-
-////////////////////////////////////////////////////////////////////////
-
-static void drawPoly3TGEx4_IL(short x1, short y1, short x2, short y2, short x3,
- short y3, short tx1, short ty1, short tx2, short ty2, short tx3,
- short ty3, short clX, short clY, int32_t col1, int32_t col2,
- int32_t col3) {
- int i, j, xmin, xmax, ymin, ymax, n_xi, n_yi, TXV;
- int32_t cR1, cG1, cB1;
- int32_t difR, difB, difG, difR2, difB2, difG2;
- int32_t difX, difY, difX2, difY2;
- int32_t posX, posY, YAdjust, clutP, XAdjust;
- short tC1, tC2;
-
- if (x1 > g_prim.drawW && x2 > g_prim.drawW && x3 > g_prim.drawW)
- return;
- if (y1 > g_prim.drawH && y2 > g_prim.drawH && y3 > g_prim.drawH)
- return;
- if (x1 < g_prim.drawX && x2 < g_prim.drawX && x3 < g_prim.drawX)
- return;
- if (y1 < g_prim.drawY && y2 < g_prim.drawY && y3 < g_prim.drawY)
- return;
- if (g_prim.drawY >= g_prim.drawH)
- return;
- if (g_prim.drawX >= g_prim.drawW)
- return;
-
- if (!SetupSections_GT(x1, y1, x2, y2, x3, y3, tx1, ty1, tx2, ty2, tx3, ty3,
- col1, col2, col3))
- return;
-
- ymax = g_soft.Ymax;
-
- for (ymin = g_soft.Ymin; ymin < g_prim.drawY; ymin++)
- if (NextRow_GT())
- return;
-
- clutP = (clY << 10) + clX;
-
- YAdjust = (g_soft.GlobalTextAddrY << 10) + g_soft.GlobalTextAddrX;
-
- difR = delta_right_R;
- difG = delta_right_G;
- difB = delta_right_B;
- difR2 = difR << 1;
- difG2 = difG << 1;
- difB2 = difB << 1;
-
- difX = delta_right_u;
- difX2 = difX << 1;
- difY = delta_right_v;
- difY2 = difY << 1;
-
-#ifdef FASTSOLID
-
- if (!g_draw.bCheckMask && !g_soft.DrawSemiTrans && !g_prim.iDither) {
- for (i = ymin; i <= ymax; i++) {
- xmin = ((left_x) >> 16);
- xmax = ((right_x) >> 16) - 1; //!!!!!!!!!!!!!
- if (g_prim.drawW < xmax)
- xmax = g_prim.drawW;
-
- if (xmax >= xmin) {
- posX = left_u;
- posY = left_v;
- cR1 = left_R;
- cG1 = left_G;
- cB1 = left_B;
-
- if (xmin < g_prim.drawX) {
- j = g_prim.drawX - xmin;
- xmin = g_prim.drawX;
- posX += j * difX;
- posY += j * difY;
- cR1 += j * difR;
- cG1 += j * difG;
- cB1 += j * difB;
- }
-
- for (j = xmin; j < xmax; j += 2) {
- XAdjust = (posX >> 16);
-
- TXV = posY >> 16;
- n_xi = ((XAdjust >> 2) & ~0x3c) + ((TXV << 2) & 0x3c);
- n_yi = (TXV & ~0xf) + ((XAdjust >> 4) & 0xf);
-
- tC1
- = (GETLE16(&g_gpu.psx_vram.u16[(n_yi<<10)+YAdjust+n_xi])
- >> ((XAdjust & 0x03) << 2)) & 0x0f;
-
- XAdjust = ((posX + difX) >> 16);
-
- TXV = (posY + difY) >> 16;
- n_xi = ((XAdjust >> 2) & ~0x3c) + ((TXV << 2) & 0x3c);
- n_yi = (TXV & ~0xf) + ((XAdjust >> 4) & 0xf);
-
- tC2
- = (GETLE16(&g_gpu.psx_vram.u16[(n_yi<<10)+YAdjust+n_xi])
- >> ((XAdjust & 0x03) << 2)) & 0x0f;
-
- GetTextureTransColGX32_S(
- (uint32_t *) &g_gpu.psx_vram.u16[(i << 10) + j],
- GETLE16(&g_gpu.psx_vram.u16[clutP+tC1])
- | ((int32_t) GETLE16(&g_gpu.psx_vram.u16[clutP+tC2]))
- << 16, (cB1 >> 16) | ((cB1 + difB)
- & 0xff0000), (cG1 >> 16) | ((cG1 + difG)
- & 0xff0000), (cR1 >> 16) | ((cR1 + difR)
- & 0xff0000));
- posX += difX2;
- posY += difY2;
- cR1 += difR2;
- cG1 += difG2;
- cB1 += difB2;
- }
- if (j == xmax) {
- XAdjust = (posX >> 16);
-
- TXV = posY >> 16;
- n_xi = ((XAdjust >> 2) & ~0x3c) + ((TXV << 2) & 0x3c);
- n_yi = (TXV & ~0xf) + ((XAdjust >> 4) & 0xf);
-
- tC1
- = (GETLE16(&g_gpu.psx_vram.u16[(n_yi<<10)+YAdjust+n_xi])
- >> ((XAdjust & 0x03) << 2)) & 0x0f;
-
- GetTextureTransColGX_S(&g_gpu.psx_vram.u16[(i << 10) + j],
- GETLE16(&g_gpu.psx_vram.u16[clutP+tC1]),
- (cB1 >> 16), (cG1 >> 16), (cR1 >> 16));
- }
- }
- if (NextRow_GT()) {
- return;
- }
- }
- return;
- }
-
-#endif
-
- for (i = ymin; i <= ymax; i++) {
- xmin = (left_x >> 16);
- xmax = (right_x >> 16) - 1; //!!!!!!!!!!!!!!!!
- if (g_prim.drawW < xmax)
- xmax = g_prim.drawW;
-
- if (xmax >= xmin) {
- posX = left_u;
- posY = left_v;
- cR1 = left_R;
- cG1 = left_G;
- cB1 = left_B;
-
- if (xmin < g_prim.drawX) {
- j = g_prim.drawX - xmin;
- xmin = g_prim.drawX;
- posX += j * difX;
- posY += j * difY;
- cR1 += j * difR;
- cG1 += j * difG;
- cB1 += j * difB;
- }
-
- for (j = xmin; j <= xmax; j++) {
- XAdjust = (posX >> 16);
-
- TXV = posY >> 16;
- n_xi = ((XAdjust >> 2) & ~0x3c) + ((TXV << 2) & 0x3c);
- n_yi = (TXV & ~0xf) + ((XAdjust >> 4) & 0xf);
-
- tC1 = (GETLE16(&g_gpu.psx_vram.u16[(n_yi<<10)+YAdjust+n_xi])
- >> ((XAdjust & 0x03) << 2)) & 0x0f;
-
- if (g_prim.iDither)
- GetTextureTransColGX_Dither(&g_gpu.psx_vram.u16[(i << 10)
- + j], GETLE16(&g_gpu.psx_vram.u16[clutP+tC1]), (cB1
- >> 16), (cG1 >> 16), (cR1 >> 16));
- else
- GetTextureTransColGX(&g_gpu.psx_vram.u16[(i << 10) + j],
- GETLE16(&g_gpu.psx_vram.u16[clutP+tC1]),
- (cB1 >> 16), (cG1 >> 16), (cR1 >> 16));
- posX += difX;
- posY += difY;
- cR1 += difR;
- cG1 += difG;
- cB1 += difB;
- }
- }
- if (NextRow_GT()) {
- return;
- }
- }
-}
-
-////////////////////////////////////////////////////////////////////////
-
-static void drawPoly3TGEx4_TW(short x1, short y1, short x2, short y2, short x3,
- short y3, short tx1, short ty1, short tx2, short ty2, short tx3,
- short ty3, short clX, short clY, int32_t col1, int32_t col2,
- int32_t col3) {
- int i, j, xmin, xmax, ymin, ymax;
- int32_t cR1, cG1, cB1;
- int32_t difR, difB, difG, difR2, difB2, difG2;
- int32_t difX, difY, difX2, difY2;
- int32_t posX, posY, YAdjust, clutP, XAdjust;
- short tC1, tC2;
-
- if (x1 > g_prim.drawW && x2 > g_prim.drawW && x3 > g_prim.drawW)
- return;
- if (y1 > g_prim.drawH && y2 > g_prim.drawH && y3 > g_prim.drawH)
- return;
- if (x1 < g_prim.drawX && x2 < g_prim.drawX && x3 < g_prim.drawX)
- return;
- if (y1 < g_prim.drawY && y2 < g_prim.drawY && y3 < g_prim.drawY)
- return;
- if (g_prim.drawY >= g_prim.drawH)
- return;
- if (g_prim.drawX >= g_prim.drawW)
- return;
-
- if (!SetupSections_GT(x1, y1, x2, y2, x3, y3, tx1, ty1, tx2, ty2, tx3, ty3,
- col1, col2, col3))
- return;
-
- ymax = g_soft.Ymax;
-
- for (ymin = g_soft.Ymin; ymin < g_prim.drawY; ymin++)
- if (NextRow_GT())
- return;
-
- clutP = (clY << 10) + clX;
-
- YAdjust = ((g_soft.GlobalTextAddrY) << 11) + (g_soft.GlobalTextAddrX << 1);
- YAdjust += (g_prim.TWin.Position.y0 << 11) + (g_prim.TWin.Position.x0 >> 1);
-
- difR = delta_right_R;
- difG = delta_right_G;
- difB = delta_right_B;
- difR2 = difR << 1;
- difG2 = difG << 1;
- difB2 = difB << 1;
-
- difX = delta_right_u;
- difX2 = difX << 1;
- difY = delta_right_v;
- difY2 = difY << 1;
-
-#ifdef FASTSOLID
-
- if (!g_draw.bCheckMask && !g_soft.DrawSemiTrans && !g_prim.iDither) {
- for (i = ymin; i <= ymax; i++) {
- xmin = ((left_x) >> 16);
- xmax = ((right_x) >> 16) - 1; //!!!!!!!!!!!!!
- if (g_prim.drawW < xmax)
- xmax = g_prim.drawW;
-
- if (xmax >= xmin) {
- posX = left_u;
- posY = left_v;
- cR1 = left_R;
- cG1 = left_G;
- cB1 = left_B;
-
- if (xmin < g_prim.drawX) {
- j = g_prim.drawX - xmin;
- xmin = g_prim.drawX;
- posX += j * difX;
- posY += j * difY;
- cR1 += j * difR;
- cG1 += j * difG;
- cB1 += j * difB;
- }
-
- for (j = xmin; j < xmax; j += 2) {
- XAdjust = (posX >> 16) % g_prim.TWin.Position.x1;
- tC1 = g_gpu.psx_vram.u8[(((posY >> 16)
- % g_prim.TWin.Position.y1) << 11) + YAdjust
- + (XAdjust >> 1)];
- tC1 = (tC1 >> ((XAdjust & 1) << 2)) & 0xf;
- XAdjust = ((posX + difX) >> 16) % g_prim.TWin.Position.x1;
- tC2 = g_gpu.psx_vram.u8[((((posY + difY) >> 16)
- % g_prim.TWin.Position.y1) << 11) + YAdjust
- + (XAdjust >> 1)];
- tC2 = (tC2 >> ((XAdjust & 1) << 2)) & 0xf;
- GetTextureTransColGX32_S(
- (uint32_t *) &g_gpu.psx_vram.u16[(i << 10) + j],
- GETLE16(&g_gpu.psx_vram.u16[clutP+tC1])
- | ((int32_t) GETLE16(&g_gpu.psx_vram.u16[clutP+tC2]))
- << 16, (cB1 >> 16) | ((cB1 + difB)
- & 0xff0000), (cG1 >> 16) | ((cG1 + difG)
- & 0xff0000), (cR1 >> 16) | ((cR1 + difR)
- & 0xff0000));
- posX += difX2;
- posY += difY2;
- cR1 += difR2;
- cG1 += difG2;
- cB1 += difB2;
- }
- if (j == xmax) {
- XAdjust = (posX >> 16) % g_prim.TWin.Position.x1;
- tC1 = g_gpu.psx_vram.u8[(((posY >> 16)
- % g_prim.TWin.Position.y1) << 11) + YAdjust
- + (XAdjust >> 1)];
- tC1 = (tC1 >> ((XAdjust & 1) << 2)) & 0xf;
- GetTextureTransColGX_S(&g_gpu.psx_vram.u16[(i << 10) + j],
- GETLE16(&g_gpu.psx_vram.u16[clutP+tC1]),
- (cB1 >> 16), (cG1 >> 16), (cR1 >> 16));
- }
- }
- if (NextRow_GT()) {
- return;
- }
- }
- return;
- }
-
-#endif
-
- for (i = ymin; i <= ymax; i++) {
- xmin = (left_x >> 16);
- xmax = (right_x >> 16) - 1; //!!!!!!!!!!!!!!!!
- if (g_prim.drawW < xmax)
- xmax = g_prim.drawW;
-
- if (xmax >= xmin) {
- posX = left_u;
- posY = left_v;
- cR1 = left_R;
- cG1 = left_G;
- cB1 = left_B;
-
- if (xmin < g_prim.drawX) {
- j = g_prim.drawX - xmin;
- xmin = g_prim.drawX;
- posX += j * difX;
- posY += j * difY;
- cR1 += j * difR;
- cG1 += j * difG;
- cB1 += j * difB;
- }
-
- for (j = xmin; j <= xmax; j++) {
- XAdjust = (posX >> 16) % g_prim.TWin.Position.x1;
- tC1 = g_gpu.psx_vram.u8[(((posY >> 16)
- % g_prim.TWin.Position.y1) << 11) + YAdjust + (XAdjust
- >> 1)];
- tC1 = (tC1 >> ((XAdjust & 1) << 2)) & 0xf;
- if (g_prim.iDither)
- GetTextureTransColGX_Dither(&g_gpu.psx_vram.u16[(i << 10)
- + j], GETLE16(&g_gpu.psx_vram.u16[clutP+tC1]), (cB1
- >> 16), (cG1 >> 16), (cR1 >> 16));
- else
- GetTextureTransColGX(&g_gpu.psx_vram.u16[(i << 10) + j],
- GETLE16(&g_gpu.psx_vram.u16[clutP+tC1]),
- (cB1 >> 16), (cG1 >> 16), (cR1 >> 16));
- posX += difX;
- posY += difY;
- cR1 += difR;
- cG1 += difG;
- cB1 += difB;
- }
- }
- if (NextRow_GT()) {
- return;
- }
- }
-}
-
-////////////////////////////////////////////////////////////////////////
-
-// note: the psx is doing g-shaded quads as two g-shaded tris,
-// like the following func... sadly texturing is not 100%
-// correct that way, so small texture distortions can
-// happen...
-
-static void drawPoly4TGEx4_TRI_IL(short x1, short y1, short x2, short y2, short x3,
- short y3, short x4, short y4, short tx1, short ty1, short tx2,
- short ty2, short tx3, short ty3, short tx4, short ty4, short clX,
- short clY, int32_t col1, int32_t col2, int32_t col3, int32_t col4) {
- drawPoly3TGEx4_IL(x2, y2, x3, y3, x4, y4, tx2, ty2, tx3, ty3, tx4, ty4,
- clX, clY, col2, col4, col3);
- drawPoly3TGEx4_IL(x1, y1, x2, y2, x4, y4, tx1, ty1, tx2, ty2, tx4, ty4,
- clX, clY, col1, col2, col3);
-}
-
-#ifdef POLYQUAD3GT
-
-static void drawPoly4TGEx4_TRI(short x1, short y1, short x2, short y2, short x3,
- short y3, short x4, short y4, short tx1, short ty1, short tx2,
- short ty2, short tx3, short ty3, short tx4, short ty4, short clX,
- short clY, int32_t col1, int32_t col2, int32_t col3, int32_t col4) {
- drawPoly3TGEx4(x2, y2, x3, y3, x4, y4, tx2, ty2, tx3, ty3, tx4, ty4, clX,
- clY, col2, col4, col3);
- drawPoly3TGEx4(x1, y1, x2, y2, x4, y4, tx1, ty1, tx2, ty2, tx4, ty4, clX,
- clY, col1, col2, col3);
-}
-
-#endif
-
-////////////////////////////////////////////////////////////////////////
-
-static void drawPoly4TGEx4(short x1, short y1, short x2, short y2, short x3, short y3,
- short x4, short y4, short tx1, short ty1, short tx2, short ty2,
- short tx3, short ty3, short tx4, short ty4, short clX, short clY,
- int32_t col1, int32_t col2, int32_t col4, int32_t col3) {
- int32_t num;
- int32_t i, j, xmin, xmax, ymin, ymax;
- int32_t cR1, cG1, cB1;
- int32_t difR, difB, difG, difR2, difB2, difG2;
- int32_t difX, difY, difX2, difY2;
- int32_t posX, posY, YAdjust, clutP, XAdjust;
- short tC1, tC2;
-
- if (x1 > g_prim.drawW && x2 > g_prim.drawW && x3 > g_prim.drawW && x4
- > g_prim.drawW)
- return;
- if (y1 > g_prim.drawH && y2 > g_prim.drawH && y3 > g_prim.drawH && y4
- > g_prim.drawH)
- return;
- if (x1 < g_prim.drawX && x2 < g_prim.drawX && x3 < g_prim.drawX && x4
- < g_prim.drawX)
- return;
- if (y1 < g_prim.drawY && y2 < g_prim.drawY && y3 < g_prim.drawY && y4
- < g_prim.drawY)
- return;
- if (g_prim.drawY >= g_prim.drawH)
- return;
- if (g_prim.drawX >= g_prim.drawW)
- return;
-
- if (!SetupSections_GT4(x1, y1, x2, y2, x3, y3, x4, y4, tx1, ty1, tx2, ty2,
- tx3, ty3, tx4, ty4, col1, col2, col3, col4))
- return;
-
- ymax = g_soft.Ymax;
-
- for (ymin = g_soft.Ymin; ymin < g_prim.drawY; ymin++)
- if (NextRow_GT4())
- return;
-
- clutP = (clY << 10) + clX;
-
- YAdjust = ((g_soft.GlobalTextAddrY) << 11) + (g_soft.GlobalTextAddrX << 1);
-
-#ifdef FASTSOLID
-
- if (!g_draw.bCheckMask && !g_soft.DrawSemiTrans && !g_prim.iDither) {
- for (i = ymin; i <= ymax; i++) {
- xmin = (left_x >> 16);
- xmax = (right_x >> 16);
-
- if (xmax >= xmin) {
- posX = left_u;
- posY = left_v;
-
- num = (xmax - xmin);
- if (num == 0)
- num = 1;
- difX = (right_u - posX) / num;
- difY = (right_v - posY) / num;
- difX2 = difX << 1;
- difY2 = difY << 1;
-
- cR1 = left_R;
- cG1 = left_G;
- cB1 = left_B;
- difR = (right_R - cR1) / num;
- difG = (right_G - cG1) / num;
- difB = (right_B - cB1) / num;
- difR2 = difR << 1;
- difG2 = difG << 1;
- difB2 = difB << 1;
-
- if (xmin < g_prim.drawX) {
- j = g_prim.drawX - xmin;
- xmin = g_prim.drawX;
- posX += j * difX;
- posY += j * difY;
- cR1 += j * difR;
- cG1 += j * difG;
- cB1 += j * difB;
- }
- xmax--;
- if (g_prim.drawW < xmax)
- xmax = g_prim.drawW;
-
- for (j = xmin; j < xmax; j += 2) {
- XAdjust = (posX >> 16);
- tC1
- = g_gpu.psx_vram.u8[((posY >> 5)
- & (int32_t) 0xFFFFF800) + YAdjust
- + (XAdjust >> 1)];
- tC1 = (tC1 >> ((XAdjust & 1) << 2)) & 0xf;
- XAdjust = ((posX + difX) >> 16);
- tC2 = g_gpu.psx_vram.u8[(((posY + difY) >> 5)
- & (int32_t) 0xFFFFF800) + YAdjust + (XAdjust >> 1)];
- tC2 = (tC2 >> ((XAdjust & 1) << 2)) & 0xf;
-
- GetTextureTransColGX32_S(
- (uint32_t *) &g_gpu.psx_vram.u16[(i << 10) + j],
- GETLE16(&g_gpu.psx_vram.u16[clutP+tC1])
- | ((int32_t) GETLE16(&g_gpu.psx_vram.u16[clutP+tC2]))
- << 16, (cB1 >> 16) | ((cB1 + difB)
- & 0xff0000), (cG1 >> 16) | ((cG1 + difG)
- & 0xff0000), (cR1 >> 16) | ((cR1 + difR)
- & 0xff0000));
- posX += difX2;
- posY += difY2;
- cR1 += difR2;
- cG1 += difG2;
- cB1 += difB2;
- }
- if (j == xmax) {
- XAdjust = (posX >> 16);
- tC1
- = g_gpu.psx_vram.u8[((posY >> 5)
- & (int32_t) 0xFFFFF800) + YAdjust
- + (XAdjust >> 1)];
- tC1 = (tC1 >> ((XAdjust & 1) << 2)) & 0xf;
-
- GetTextureTransColGX_S(&g_gpu.psx_vram.u16[(i << 10) + j],
- GETLE16(&g_gpu.psx_vram.u16[clutP+tC1]),
- (cB1 >> 16), (cG1 >> 16), (cR1 >> 16));
- }
- }
- if (NextRow_GT4())
- return;
- }
- return;
- }
-
-#endif
-
- for (i = ymin; i <= ymax; i++) {
- xmin = (left_x >> 16);
- xmax = (right_x >> 16);
-
- if (xmax >= xmin) {
- posX = left_u;
- posY = left_v;
-
- num = (xmax - xmin);
- if (num == 0)
- num = 1;
- difX = (right_u - posX) / num;
- difY = (right_v - posY) / num;
- difX2 = difX << 1;
- difY2 = difY << 1;
-
- cR1 = left_R;
- cG1 = left_G;
- cB1 = left_B;
- difR = (right_R - cR1) / num;
- difG = (right_G - cG1) / num;
- difB = (right_B - cB1) / num;
- difR2 = difR << 1;
- difG2 = difG << 1;
- difB2 = difB << 1;
-
- if (xmin < g_prim.drawX) {
- j = g_prim.drawX - xmin;
- xmin = g_prim.drawX;
- posX += j * difX;
- posY += j * difY;
- cR1 += j * difR;
- cG1 += j * difG;
- cB1 += j * difB;
- }
- xmax--;
- if (g_prim.drawW < xmax)
- xmax = g_prim.drawW;
-
- for (j = xmin; j <= xmax; j++) {
- XAdjust = (posX >> 16);
- tC1 = g_gpu.psx_vram.u8[((posY >> 5) & (int32_t) 0xFFFFF800)
- + YAdjust + (XAdjust >> 1)];
- tC1 = (tC1 >> ((XAdjust & 1) << 2)) & 0xf;
- if (g_prim.iDither)
- GetTextureTransColGX_Dither(&g_gpu.psx_vram.u16[(i << 10)
- + j], GETLE16(&g_gpu.psx_vram.u16[clutP+tC1]), (cB1
- >> 16), (cG1 >> 16), (cR1 >> 16));
- else
- GetTextureTransColGX(&g_gpu.psx_vram.u16[(i << 10) + j],
- GETLE16(&g_gpu.psx_vram.u16[clutP+tC1]),
- (cB1 >> 16), (cG1 >> 16), (cR1 >> 16));
- posX += difX;
- posY += difY;
- cR1 += difR;
- cG1 += difG;
- cB1 += difB;
- }
- }
- if (NextRow_GT4())
- return;
- }
-}
-
-////////////////////////////////////////////////////////////////////////
-
-static void drawPoly4TGEx4_TW(short x1, short y1, short x2, short y2, short x3,
- short y3, short x4, short y4, short tx1, short ty1, short tx2,
- short ty2, short tx3, short ty3, short tx4, short ty4, short clX,
- short clY, int32_t col1, int32_t col2, int32_t col3, int32_t col4) {
- drawPoly3TGEx4_TW(x2, y2, x3, y3, x4, y4, tx2, ty2, tx3, ty3, tx4, ty4,
- clX, clY, col2, col4, col3);
-
- drawPoly3TGEx4_TW(x1, y1, x2, y2, x4, y4, tx1, ty1, tx2, ty2, tx4, ty4,
- clX, clY, col1, col2, col3);
-}
-
-////////////////////////////////////////////////////////////////////////
-// POLY 3/4 G-SHADED TEX PAL8
-////////////////////////////////////////////////////////////////////////
-
-static void drawPoly3TGEx8(short x1, short y1, short x2, short y2, short x3, short y3,
- short tx1, short ty1, short tx2, short ty2, short tx3, short ty3,
- short clX, short clY, int32_t col1, int32_t col2, int32_t col3) {
- int i, j, xmin, xmax, ymin, ymax;
- int32_t cR1, cG1, cB1;
- int32_t difR, difB, difG, difR2, difB2, difG2;
- int32_t difX, difY, difX2, difY2;
- int32_t posX, posY, YAdjust, clutP;
- short tC1, tC2;
-
- if (x1 > g_prim.drawW && x2 > g_prim.drawW && x3 > g_prim.drawW)
- return;
- if (y1 > g_prim.drawH && y2 > g_prim.drawH && y3 > g_prim.drawH)
- return;
- if (x1 < g_prim.drawX && x2 < g_prim.drawX && x3 < g_prim.drawX)
- return;
- if (y1 < g_prim.drawY && y2 < g_prim.drawY && y3 < g_prim.drawY)
- return;
- if (g_prim.drawY >= g_prim.drawH)
- return;
- if (g_prim.drawX >= g_prim.drawW)
- return;
-
- if (!SetupSections_GT(x1, y1, x2, y2, x3, y3, tx1, ty1, tx2, ty2, tx3, ty3,
- col1, col2, col3))
- return;
-
- ymax = g_soft.Ymax;
-
- for (ymin = g_soft.Ymin; ymin < g_prim.drawY; ymin++)
- if (NextRow_GT())
- return;
-
- clutP = (clY << 10) + clX;
-
- YAdjust = ((g_soft.GlobalTextAddrY) << 11) + (g_soft.GlobalTextAddrX << 1);
-
- difR = delta_right_R;
- difG = delta_right_G;
- difB = delta_right_B;
- difR2 = difR << 1;
- difG2 = difG << 1;
- difB2 = difB << 1;
- difX = delta_right_u;
- difX2 = difX << 1;
- difY = delta_right_v;
- difY2 = difY << 1;
-
-#ifdef FASTSOLID
-
- if (!g_draw.bCheckMask && !g_soft.DrawSemiTrans && !g_prim.iDither) {
- for (i = ymin; i <= ymax; i++) {
- xmin = (left_x >> 16);
- xmax = (right_x >> 16) - 1; // !!!!!!!!!!!!!
- if (g_prim.drawW < xmax)
- xmax = g_prim.drawW;
-
- if (xmax >= xmin) {
- posX = left_u;
- posY = left_v;
- cR1 = left_R;
- cG1 = left_G;
- cB1 = left_B;
-
- if (xmin < g_prim.drawX) {
- j = g_prim.drawX - xmin;
- xmin = g_prim.drawX;
- posX += j * difX;
- posY += j * difY;
- cR1 += j * difR;
- cG1 += j * difG;
- cB1 += j * difB;
- }
-
- for (j = xmin; j < xmax; j += 2) {
- tC1
- = g_gpu.psx_vram.u8[((posY >> 5)
- & (int32_t) 0xFFFFF800) + YAdjust + ((posX
- >> 16))];
- tC2 = g_gpu.psx_vram.u8[(((posY + difY) >> 5)
- & (int32_t) 0xFFFFF800) + YAdjust + (((posX + difX)
- >> 16))];
- GetTextureTransColGX32_S(
- (uint32_t *) &g_gpu.psx_vram.u16[(i << 10) + j],
- GETLE16(&g_gpu.psx_vram.u16[clutP+tC1])
- | ((int32_t) GETLE16(&g_gpu.psx_vram.u16[clutP+tC2]))
- << 16, (cB1 >> 16) | ((cB1 + difB)
- & 0xff0000), (cG1 >> 16) | ((cG1 + difG)
- & 0xff0000), (cR1 >> 16) | ((cR1 + difR)
- & 0xff0000));
- posX += difX2;
- posY += difY2;
- cR1 += difR2;
- cG1 += difG2;
- cB1 += difB2;
- }
- if (j == xmax) {
- tC1
- = g_gpu.psx_vram.u8[((posY >> 5)
- & (int32_t) 0xFFFFF800) + YAdjust + ((posX
- >> 16))];
- GetTextureTransColGX_S(&g_gpu.psx_vram.u16[(i << 10) + j],
- GETLE16(&g_gpu.psx_vram.u16[clutP+tC1]),
- (cB1 >> 16), (cG1 >> 16), (cR1 >> 16));
- }
- }
- if (NextRow_GT()) {
- return;
- }
- }
- return;
- }
-
-#endif
-
- for (i = ymin; i <= ymax; i++) {
- xmin = (left_x >> 16);
- xmax = (right_x >> 16) - 1; //!!!!!!!!!!!!!!!!!!!!!!!
- if (g_prim.drawW < xmax)
- xmax = g_prim.drawW;
-
- if (xmax >= xmin) {
- posX = left_u;
- posY = left_v;
- cR1 = left_R;
- cG1 = left_G;
- cB1 = left_B;
-
- if (xmin < g_prim.drawX) {
- j = g_prim.drawX - xmin;
- xmin = g_prim.drawX;
- posX += j * difX;
- posY += j * difY;
- cR1 += j * difR;
- cG1 += j * difG;
- cB1 += j * difB;
- }
-
- for (j = xmin; j <= xmax; j++) {
- tC1 = g_gpu.psx_vram.u8[((posY >> 5) & (int32_t) 0xFFFFF800)
- + YAdjust + ((posX >> 16))];
- if (g_prim.iDither)
- GetTextureTransColGX_Dither(&g_gpu.psx_vram.u16[(i << 10)
- + j], GETLE16(&g_gpu.psx_vram.u16[clutP+tC1]), (cB1
- >> 16), (cG1 >> 16), (cR1 >> 16));
- else
- GetTextureTransColGX(&g_gpu.psx_vram.u16[(i << 10) + j],
- GETLE16(&g_gpu.psx_vram.u16[clutP+tC1]),
- (cB1 >> 16), (cG1 >> 16), (cR1 >> 16));
- posX += difX;
- posY += difY;
- cR1 += difR;
- cG1 += difG;
- cB1 += difB;
- }
- }
- if (NextRow_GT()) {
- return;
- }
- }
-}
-
-////////////////////////////////////////////////////////////////////////
-
-static void drawPoly3TGEx8_IL(short x1, short y1, short x2, short y2, short x3,
- short y3, short tx1, short ty1, short tx2, short ty2, short tx3,
- short ty3, short clX, short clY, int32_t col1, int32_t col2,
- int32_t col3) {
- int i, j, xmin, xmax, ymin, ymax, n_xi, n_yi, TXV, TXU;
- int32_t cR1, cG1, cB1;
- int32_t difR, difB, difG, difR2, difB2, difG2;
- int32_t difX, difY, difX2, difY2;
- int32_t posX, posY, YAdjust, clutP;
- short tC1, tC2;
-
- if (x1 > g_prim.drawW && x2 > g_prim.drawW && x3 > g_prim.drawW)
- return;
- if (y1 > g_prim.drawH && y2 > g_prim.drawH && y3 > g_prim.drawH)
- return;
- if (x1 < g_prim.drawX && x2 < g_prim.drawX && x3 < g_prim.drawX)
- return;
- if (y1 < g_prim.drawY && y2 < g_prim.drawY && y3 < g_prim.drawY)
- return;
- if (g_prim.drawY >= g_prim.drawH)
- return;
- if (g_prim.drawX >= g_prim.drawW)
- return;
-
- if (!SetupSections_GT(x1, y1, x2, y2, x3, y3, tx1, ty1, tx2, ty2, tx3, ty3,
- col1, col2, col3))
- return;
-
- ymax = g_soft.Ymax;
-
- for (ymin = g_soft.Ymin; ymin < g_prim.drawY; ymin++)
- if (NextRow_GT())
- return;
-
- clutP = (clY << 10) + clX;
-
- YAdjust = (g_soft.GlobalTextAddrY << 10) + g_soft.GlobalTextAddrX;
-
- difR = delta_right_R;
- difG = delta_right_G;
- difB = delta_right_B;
- difR2 = difR << 1;
- difG2 = difG << 1;
- difB2 = difB << 1;
- difX = delta_right_u;
- difX2 = difX << 1;
- difY = delta_right_v;
- difY2 = difY << 1;
-
-#ifdef FASTSOLID
-
- if (!g_draw.bCheckMask && !g_soft.DrawSemiTrans && !g_prim.iDither) {
- for (i = ymin; i <= ymax; i++) {
- xmin = (left_x >> 16);
- xmax = (right_x >> 16) - 1; // !!!!!!!!!!!!!
- if (g_prim.drawW < xmax)
- xmax = g_prim.drawW;
-
- if (xmax >= xmin) {
- posX = left_u;
- posY = left_v;
- cR1 = left_R;
- cG1 = left_G;
- cB1 = left_B;
-
- if (xmin < g_prim.drawX) {
- j = g_prim.drawX - xmin;
- xmin = g_prim.drawX;
- posX += j * difX;
- posY += j * difY;
- cR1 += j * difR;
- cG1 += j * difG;
- cB1 += j * difB;
- }
-
- for (j = xmin; j < xmax; j += 2) {
- TXU = posX >> 16;
- TXV = posY >> 16;
- n_xi = ((TXU >> 1) & ~0x78) + ((TXU << 2) & 0x40) + ((TXV
- << 3) & 0x38);
- n_yi = (TXV & ~0x7) + ((TXU >> 5) & 0x7);
-
- tC1
- = (GETLE16(&g_gpu.psx_vram.u16[(n_yi<<10)+YAdjust+n_xi])
- >> ((TXU & 0x01) << 3)) & 0xff;
-
- TXU = (posX + difX) >> 16;
- TXV = (posY + difY) >> 16;
- n_xi = ((TXU >> 1) & ~0x78) + ((TXU << 2) & 0x40) + ((TXV
- << 3) & 0x38);
- n_yi = (TXV & ~0x7) + ((TXU >> 5) & 0x7);
-
- tC2
- = (GETLE16(&g_gpu.psx_vram.u16[(n_yi<<10)+YAdjust+n_xi])
- >> ((TXU & 0x01) << 3)) & 0xff;
-
- GetTextureTransColGX32_S(
- (uint32_t *) &g_gpu.psx_vram.u16[(i << 10) + j],
- GETLE16(&g_gpu.psx_vram.u16[clutP+tC1])
- | ((int32_t) GETLE16(&g_gpu.psx_vram.u16[clutP+tC2]))
- << 16, (cB1 >> 16) | ((cB1 + difB)
- & 0xff0000), (cG1 >> 16) | ((cG1 + difG)
- & 0xff0000), (cR1 >> 16) | ((cR1 + difR)
- & 0xff0000));
- posX += difX2;
- posY += difY2;
- cR1 += difR2;
- cG1 += difG2;
- cB1 += difB2;
- }
- if (j == xmax) {
- TXU = posX >> 16;
- TXV = posY >> 16;
- n_xi = ((TXU >> 1) & ~0x78) + ((TXU << 2) & 0x40) + ((TXV
- << 3) & 0x38);
- n_yi = (TXV & ~0x7) + ((TXU >> 5) & 0x7);
-
- tC1
- = (GETLE16(&g_gpu.psx_vram.u16[(n_yi<<10)+YAdjust+n_xi])
- >> ((TXU & 0x01) << 3)) & 0xff;
-
- GetTextureTransColGX_S(&g_gpu.psx_vram.u16[(i << 10) + j],
- GETLE16(&g_gpu.psx_vram.u16[clutP+tC1]),
- (cB1 >> 16), (cG1 >> 16), (cR1 >> 16));
- }
- }
- if (NextRow_GT()) {
- return;
- }
- }
- return;
- }
-
-#endif
-
- for (i = ymin; i <= ymax; i++) {
- xmin = (left_x >> 16);
- xmax = (right_x >> 16) - 1; //!!!!!!!!!!!!!!!!!!!!!!!
- if (g_prim.drawW < xmax)
- xmax = g_prim.drawW;
-
- if (xmax >= xmin) {
- posX = left_u;
- posY = left_v;
- cR1 = left_R;
- cG1 = left_G;
- cB1 = left_B;
-
- if (xmin < g_prim.drawX) {
- j = g_prim.drawX - xmin;
- xmin = g_prim.drawX;
- posX += j * difX;
- posY += j * difY;
- cR1 += j * difR;
- cG1 += j * difG;
- cB1 += j * difB;
- }
-
- for (j = xmin; j <= xmax; j++) {
- TXU = posX >> 16;
- TXV = posY >> 16;
- n_xi = ((TXU >> 1) & ~0x78) + ((TXU << 2) & 0x40) + ((TXV << 3)
- & 0x38);
- n_yi = (TXV & ~0x7) + ((TXU >> 5) & 0x7);
-
- tC1 = (GETLE16(&g_gpu.psx_vram.u16[(n_yi<<10)+YAdjust+n_xi])
- >> ((TXU & 0x01) << 3)) & 0xff;
-
- if (g_prim.iDither)
- GetTextureTransColGX_Dither(&g_gpu.psx_vram.u16[(i << 10)
- + j], GETLE16(&g_gpu.psx_vram.u16[clutP+tC1]), (cB1
- >> 16), (cG1 >> 16), (cR1 >> 16));
- else
- GetTextureTransColGX(&g_gpu.psx_vram.u16[(i << 10) + j],
- GETLE16(&g_gpu.psx_vram.u16[clutP+tC1]),
- (cB1 >> 16), (cG1 >> 16), (cR1 >> 16));
- posX += difX;
- posY += difY;
- cR1 += difR;
- cG1 += difG;
- cB1 += difB;
- }
- }
- if (NextRow_GT()) {
- return;
- }
- }
-}
-
-////////////////////////////////////////////////////////////////////////
-
-static void drawPoly3TGEx8_TW(short x1, short y1, short x2, short y2, short x3,
- short y3, short tx1, short ty1, short tx2, short ty2, short tx3,
- short ty3, short clX, short clY, int32_t col1, int32_t col2,
- int32_t col3) {
- int i, j, xmin, xmax, ymin, ymax;
- int32_t cR1, cG1, cB1;
- int32_t difR, difB, difG, difR2, difB2, difG2;
- int32_t difX, difY, difX2, difY2;
- int32_t posX, posY, YAdjust, clutP;
- short tC1, tC2;
-
- if (x1 > g_prim.drawW && x2 > g_prim.drawW && x3 > g_prim.drawW)
- return;
- if (y1 > g_prim.drawH && y2 > g_prim.drawH && y3 > g_prim.drawH)
- return;
- if (x1 < g_prim.drawX && x2 < g_prim.drawX && x3 < g_prim.drawX)
- return;
- if (y1 < g_prim.drawY && y2 < g_prim.drawY && y3 < g_prim.drawY)
- return;
- if (g_prim.drawY >= g_prim.drawH)
- return;
- if (g_prim.drawX >= g_prim.drawW)
- return;
-
- if (!SetupSections_GT(x1, y1, x2, y2, x3, y3, tx1, ty1, tx2, ty2, tx3, ty3,
- col1, col2, col3))
- return;
-
- ymax = g_soft.Ymax;
-
- for (ymin = g_soft.Ymin; ymin < g_prim.drawY; ymin++)
- if (NextRow_GT())
- return;
-
- clutP = (clY << 10) + clX;
-
- YAdjust = ((g_soft.GlobalTextAddrY) << 11) + (g_soft.GlobalTextAddrX << 1);
- YAdjust += (g_prim.TWin.Position.y0 << 11) + (g_prim.TWin.Position.x0);
-
- difR = delta_right_R;
- difG = delta_right_G;
- difB = delta_right_B;
- difR2 = difR << 1;
- difG2 = difG << 1;
- difB2 = difB << 1;
- difX = delta_right_u;
- difX2 = difX << 1;
- difY = delta_right_v;
- difY2 = difY << 1;
-
-#ifdef FASTSOLID
-
- if (!g_draw.bCheckMask && !g_soft.DrawSemiTrans && !g_prim.iDither) {
- for (i = ymin; i <= ymax; i++) {
- xmin = (left_x >> 16);
- xmax = (right_x >> 16) - 1; // !!!!!!!!!!!!!
- if (g_prim.drawW < xmax)
- xmax = g_prim.drawW;
-
- if (xmax >= xmin) {
- posX = left_u;
- posY = left_v;
- cR1 = left_R;
- cG1 = left_G;
- cB1 = left_B;
-
- if (xmin < g_prim.drawX) {
- j = g_prim.drawX - xmin;
- xmin = g_prim.drawX;
- posX += j * difX;
- posY += j * difY;
- cR1 += j * difR;
- cG1 += j * difG;
- cB1 += j * difB;
- }
-
- for (j = xmin; j < xmax; j += 2) {
- tC1 = g_gpu.psx_vram.u8[(((posY >> 16)
- % g_prim.TWin.Position.y1) << 11) + YAdjust
- + ((posX >> 16) % g_prim.TWin.Position.x1)];
- tC2
- = g_gpu.psx_vram.u8[((((posY + difY) >> 16)
- % g_prim.TWin.Position.y1) << 11) + YAdjust
- + (((posX + difX) >> 16)
- % g_prim.TWin.Position.x1)];
-
- GetTextureTransColGX32_S(
- (uint32_t *) &g_gpu.psx_vram.u16[(i << 10) + j],
- GETLE16(&g_gpu.psx_vram.u16[clutP+tC1])
- | ((int32_t) GETLE16(&g_gpu.psx_vram.u16[clutP+tC2]))
- << 16, (cB1 >> 16) | ((cB1 + difB)
- & 0xff0000), (cG1 >> 16) | ((cG1 + difG)
- & 0xff0000), (cR1 >> 16) | ((cR1 + difR)
- & 0xff0000));
- posX += difX2;
- posY += difY2;
- cR1 += difR2;
- cG1 += difG2;
- cB1 += difB2;
- }
- if (j == xmax) {
- tC1 = g_gpu.psx_vram.u8[(((posY >> 16)
- % g_prim.TWin.Position.y1) << 11) + YAdjust
- + ((posX >> 16) % g_prim.TWin.Position.x1)];
- GetTextureTransColGX_S(&g_gpu.psx_vram.u16[(i << 10) + j],
- GETLE16(&g_gpu.psx_vram.u16[clutP+tC1]),
- (cB1 >> 16), (cG1 >> 16), (cR1 >> 16));
- }
- }
- if (NextRow_GT()) {
- return;
- }
- }
- return;
- }
-
-#endif
-
- for (i = ymin; i <= ymax; i++) {
- xmin = (left_x >> 16);
- xmax = (right_x >> 16) - 1; //!!!!!!!!!!!!!!!!!!!!!!!
- if (g_prim.drawW < xmax)
- xmax = g_prim.drawW;
-
- if (xmax >= xmin) {
- posX = left_u;
- posY = left_v;
- cR1 = left_R;
- cG1 = left_G;
- cB1 = left_B;
-
- if (xmin < g_prim.drawX) {
- j = g_prim.drawX - xmin;
- xmin = g_prim.drawX;
- posX += j * difX;
- posY += j * difY;
- cR1 += j * difR;
- cG1 += j * difG;
- cB1 += j * difB;
- }
-
- for (j = xmin; j <= xmax; j++) {
- tC1 = g_gpu.psx_vram.u8[(((posY >> 16)
- % g_prim.TWin.Position.y1) << 11) + YAdjust + ((posX
- >> 16) % g_prim.TWin.Position.x1)];
- if (g_prim.iDither)
- GetTextureTransColGX_Dither(&g_gpu.psx_vram.u16[(i << 10)
- + j], GETLE16(&g_gpu.psx_vram.u16[clutP+tC1]), (cB1
- >> 16), (cG1 >> 16), (cR1 >> 16));
- else
- GetTextureTransColGX(&g_gpu.psx_vram.u16[(i << 10) + j],
- GETLE16(&g_gpu.psx_vram.u16[clutP+tC1]),
- (cB1 >> 16), (cG1 >> 16), (cR1 >> 16));
- posX += difX;
- posY += difY;
- cR1 += difR;
- cG1 += difG;
- cB1 += difB;
- }
- }
- if (NextRow_GT()) {
- return;
- }
- }
-}
-
-////////////////////////////////////////////////////////////////////////
-
-// note: two g-shaded tris: small texture distortions can happen
-
-static void drawPoly4TGEx8_TRI_IL(short x1, short y1, short x2, short y2, short x3,
- short y3, short x4, short y4, short tx1, short ty1, short tx2,
- short ty2, short tx3, short ty3, short tx4, short ty4, short clX,
- short clY, int32_t col1, int32_t col2, int32_t col3, int32_t col4) {
- drawPoly3TGEx8_IL(x2, y2, x3, y3, x4, y4, tx2, ty2, tx3, ty3, tx4, ty4,
- clX, clY, col2, col4, col3);
- drawPoly3TGEx8_IL(x1, y1, x2, y2, x4, y4, tx1, ty1, tx2, ty2, tx4, ty4,
- clX, clY, col1, col2, col3);
-}
-
-#ifdef POLYQUAD3GT
-
-static void drawPoly4TGEx8_TRI(short x1, short y1, short x2, short y2, short x3,
- short y3, short x4, short y4, short tx1, short ty1, short tx2,
- short ty2, short tx3, short ty3, short tx4, short ty4, short clX,
- short clY, int32_t col1, int32_t col2, int32_t col3, int32_t col4) {
- drawPoly3TGEx8(x2, y2, x3, y3, x4, y4, tx2, ty2, tx3, ty3, tx4, ty4, clX,
- clY, col2, col4, col3);
- drawPoly3TGEx8(x1, y1, x2, y2, x4, y4, tx1, ty1, tx2, ty2, tx4, ty4, clX,
- clY, col1, col2, col3);
-}
-
-#endif
-
-static void drawPoly4TGEx8(short x1, short y1, short x2, short y2, short x3, short y3,
- short x4, short y4, short tx1, short ty1, short tx2, short ty2,
- short tx3, short ty3, short tx4, short ty4, short clX, short clY,
- int32_t col1, int32_t col2, int32_t col4, int32_t col3) {
- int32_t num;
- int32_t i, j, xmin, xmax, ymin, ymax;
- int32_t cR1, cG1, cB1;
- int32_t difR, difB, difG, difR2, difB2, difG2;
- int32_t difX, difY, difX2, difY2;
- int32_t posX, posY, YAdjust, clutP;
- short tC1, tC2;
-
- if (x1 > g_prim.drawW && x2 > g_prim.drawW && x3 > g_prim.drawW && x4
- > g_prim.drawW)
- return;
- if (y1 > g_prim.drawH && y2 > g_prim.drawH && y3 > g_prim.drawH && y4
- > g_prim.drawH)
- return;
- if (x1 < g_prim.drawX && x2 < g_prim.drawX && x3 < g_prim.drawX && x4
- < g_prim.drawX)
- return;
- if (y1 < g_prim.drawY && y2 < g_prim.drawY && y3 < g_prim.drawY && y4
- < g_prim.drawY)
- return;
- if (g_prim.drawY >= g_prim.drawH)
- return;
- if (g_prim.drawX >= g_prim.drawW)
- return;
-
- if (!SetupSections_GT4(x1, y1, x2, y2, x3, y3, x4, y4, tx1, ty1, tx2, ty2,
- tx3, ty3, tx4, ty4, col1, col2, col3, col4))
- return;
-
- ymax = g_soft.Ymax;
-
- for (ymin = g_soft.Ymin; ymin < g_prim.drawY; ymin++)
- if (NextRow_GT4())
- return;
-
- clutP = (clY << 10) + clX;
-
- YAdjust = ((g_soft.GlobalTextAddrY) << 11) + (g_soft.GlobalTextAddrX << 1);
-
-#ifdef FASTSOLID
-
- if (!g_draw.bCheckMask && !g_soft.DrawSemiTrans && !g_prim.iDither) {
- for (i = ymin; i <= ymax; i++) {
- xmin = (left_x >> 16);
- xmax = (right_x >> 16);
-
- if (xmax >= xmin) {
- posX = left_u;
- posY = left_v;
-
- num = (xmax - xmin);
- if (num == 0)
- num = 1;
- difX = (right_u - posX) / num;
- difY = (right_v - posY) / num;
- difX2 = difX << 1;
- difY2 = difY << 1;
-
- cR1 = left_R;
- cG1 = left_G;
- cB1 = left_B;
- difR = (right_R - cR1) / num;
- difG = (right_G - cG1) / num;
- difB = (right_B - cB1) / num;
- difR2 = difR << 1;
- difG2 = difG << 1;
- difB2 = difB << 1;
-
- if (xmin < g_prim.drawX) {
- j = g_prim.drawX - xmin;
- xmin = g_prim.drawX;
- posX += j * difX;
- posY += j * difY;
- cR1 += j * difR;
- cG1 += j * difG;
- cB1 += j * difB;
- }
- xmax--;
- if (g_prim.drawW < xmax)
- xmax = g_prim.drawW;
-
- for (j = xmin; j < xmax; j += 2) {
- tC1
- = g_gpu.psx_vram.u8[((posY >> 5)
- & (int32_t) 0xFFFFF800) + YAdjust + (posX
- >> 16)];
- tC2 = g_gpu.psx_vram.u8[(((posY + difY) >> 5)
- & (int32_t) 0xFFFFF800) + YAdjust + ((posX + difX)
- >> 16)];
-
- GetTextureTransColGX32_S(
- (uint32_t *) &g_gpu.psx_vram.u16[(i << 10) + j],
- GETLE16(&g_gpu.psx_vram.u16[clutP+tC1])
- | ((int32_t) GETLE16(&g_gpu.psx_vram.u16[clutP+tC2]))
- << 16, (cB1 >> 16) | ((cB1 + difB)
- & 0xff0000), (cG1 >> 16) | ((cG1 + difG)
- & 0xff0000), (cR1 >> 16) | ((cR1 + difR)
- & 0xff0000));
- posX += difX2;
- posY += difY2;
- cR1 += difR2;
- cG1 += difG2;
- cB1 += difB2;
- }
- if (j == xmax) {
- tC1
- = g_gpu.psx_vram.u8[((posY >> 5)
- & (int32_t) 0xFFFFF800) + YAdjust + (posX
- >> 16)];
- GetTextureTransColGX_S(&g_gpu.psx_vram.u16[(i << 10) + j],
- GETLE16(&g_gpu.psx_vram.u16[clutP+tC1]),
- (cB1 >> 16), (cG1 >> 16), (cR1 >> 16));
- }
- }
- if (NextRow_GT4())
- return;
- }
- return;
- }
-
-#endif
-
- for (i = ymin; i <= ymax; i++) {
- xmin = (left_x >> 16);
- xmax = (right_x >> 16);
-
- if (xmax >= xmin) {
- posX = left_u;
- posY = left_v;
-
- num = (xmax - xmin);
- if (num == 0)
- num = 1;
- difX = (right_u - posX) / num;
- difY = (right_v - posY) / num;
- difX2 = difX << 1;
- difY2 = difY << 1;
-
- cR1 = left_R;
- cG1 = left_G;
- cB1 = left_B;
- difR = (right_R - cR1) / num;
- difG = (right_G - cG1) / num;
- difB = (right_B - cB1) / num;
- difR2 = difR << 1;
- difG2 = difG << 1;
- difB2 = difB << 1;
-
- if (xmin < g_prim.drawX) {
- j = g_prim.drawX - xmin;
- xmin = g_prim.drawX;
- posX += j * difX;
- posY += j * difY;
- cR1 += j * difR;
- cG1 += j * difG;
- cB1 += j * difB;
- }
- xmax--;
- if (g_prim.drawW < xmax)
- xmax = g_prim.drawW;
-
- for (j = xmin; j <= xmax; j++) {
- tC1 = g_gpu.psx_vram.u8[((posY >> 5) & (int32_t) 0xFFFFF800)
- + YAdjust + (posX >> 16)];
- if (g_prim.iDither)
- GetTextureTransColGX_Dither(&g_gpu.psx_vram.u16[(i << 10)
- + j], GETLE16(&g_gpu.psx_vram.u16[clutP+tC1]), (cB1
- >> 16), (cG1 >> 16), (cR1 >> 16));
- else
- GetTextureTransColGX(&g_gpu.psx_vram.u16[(i << 10) + j],
- GETLE16(&g_gpu.psx_vram.u16[clutP+tC1]),
- (cB1 >> 16), (cG1 >> 16), (cR1 >> 16));
- posX += difX;
- posY += difY;
- cR1 += difR;
- cG1 += difG;
- cB1 += difB;
- }
- }
- if (NextRow_GT4())
- return;
- }
-}
-
-////////////////////////////////////////////////////////////////////////
-
-static void drawPoly4TGEx8_TW(short x1, short y1, short x2, short y2, short x3,
- short y3, short x4, short y4, short tx1, short ty1, short tx2,
- short ty2, short tx3, short ty3, short tx4, short ty4, short clX,
- short clY, int32_t col1, int32_t col2, int32_t col3, int32_t col4) {
- drawPoly3TGEx8_TW(x2, y2, x3, y3, x4, y4, tx2, ty2, tx3, ty3, tx4, ty4,
- clX, clY, col2, col4, col3);
- drawPoly3TGEx8_TW(x1, y1, x2, y2, x4, y4, tx1, ty1, tx2, ty2, tx4, ty4,
- clX, clY, col1, col2, col3);
-}
-
-////////////////////////////////////////////////////////////////////////
-// POLY 3 G-SHADED TEX 15 BIT
-////////////////////////////////////////////////////////////////////////
-
-static void drawPoly3TGD(short x1, short y1, short x2, short y2, short x3, short y3,
- short tx1, short ty1, short tx2, short ty2, short tx3, short ty3,
- int32_t col1, int32_t col2, int32_t col3) {
- int i, j, xmin, xmax, ymin, ymax;
- int32_t cR1, cG1, cB1;
- int32_t difR, difB, difG, difR2, difB2, difG2;
- int32_t difX, difY, difX2, difY2;
- int32_t posX, posY;
-
- if (x1 > g_prim.drawW && x2 > g_prim.drawW && x3 > g_prim.drawW)
- return;
- if (y1 > g_prim.drawH && y2 > g_prim.drawH && y3 > g_prim.drawH)
- return;
- if (x1 < g_prim.drawX && x2 < g_prim.drawX && x3 < g_prim.drawX)
- return;
- if (y1 < g_prim.drawY && y2 < g_prim.drawY && y3 < g_prim.drawY)
- return;
- if (g_prim.drawY >= g_prim.drawH)
- return;
- if (g_prim.drawX >= g_prim.drawW)
- return;
-
- if (!SetupSections_GT(x1, y1, x2, y2, x3, y3, tx1, ty1, tx2, ty2, tx3, ty3,
- col1, col2, col3))
- return;
-
- ymax = g_soft.Ymax;
-
- for (ymin = g_soft.Ymin; ymin < g_prim.drawY; ymin++)
- if (NextRow_GT())
- return;
-
- difR = delta_right_R;
- difG = delta_right_G;
- difB = delta_right_B;
- difR2 = difR << 1;
- difG2 = difG << 1;
- difB2 = difB << 1;
- difX = delta_right_u;
- difX2 = difX << 1;
- difY = delta_right_v;
- difY2 = difY << 1;
-
-#ifdef FASTSOLID
-
- if (!g_draw.bCheckMask && !g_soft.DrawSemiTrans && !g_prim.iDither) {
- for (i = ymin; i <= ymax; i++) {
- xmin = (left_x >> 16);
- xmax = (right_x >> 16) - 1; //!!!!!!!!!!!!!!!!!!!!
- if (g_prim.drawW < xmax)
- xmax = g_prim.drawW;
-
- if (xmax >= xmin) {
- posX = left_u;
- posY = left_v;
- cR1 = left_R;
- cG1 = left_G;
- cB1 = left_B;
-
- if (xmin < g_prim.drawX) {
- j = g_prim.drawX - xmin;
- xmin = g_prim.drawX;
- posX += j * difX;
- posY += j * difY;
- cR1 += j * difR;
- cG1 += j * difG;
- cB1 += j * difB;
- }
-
- for (j = xmin; j < xmax; j += 2) {
- GetTextureTransColGX32_S(
- (uint32_t *) &g_gpu.psx_vram.u16[(i << 10) + j],
- (((int32_t) GETLE16(&g_gpu.psx_vram.u16[((((posY+difY)>>16)+g_soft.GlobalTextAddrY)<<10)+((posX+difX)>>16)+g_soft.GlobalTextAddrX]))
- << 16)
- | GETLE16(&g_gpu.psx_vram.u16[(((posY>>16)+g_soft.GlobalTextAddrY)<<10)+((posX)>>16)+g_soft.GlobalTextAddrX]),
- (cB1 >> 16) | ((cB1 + difB) & 0xff0000),
- (cG1 >> 16) | ((cG1 + difG) & 0xff0000),
- (cR1 >> 16) | ((cR1 + difR) & 0xff0000));
- posX += difX2;
- posY += difY2;
- cR1 += difR2;
- cG1 += difG2;
- cB1 += difB2;
- }
- if (j == xmax)
- GetTextureTransColGX_S(
- &g_gpu.psx_vram.u16[(i << 10) + j],
- GETLE16(&g_gpu.psx_vram.u16[(((posY>>16)+g_soft.GlobalTextAddrY)<<10)+(posX>>16)+g_soft.GlobalTextAddrX]),
- (cB1 >> 16), (cG1 >> 16), (cR1 >> 16));
- }
- if (NextRow_GT()) {
- return;
- }
- }
- return;
- }
-
-#endif
-
- for (i = ymin; i <= ymax; i++) {
- xmin = (left_x >> 16);
- xmax = (right_x >> 16) - 1; //!!!!!!!!!!!!!!!!!!
- if (g_prim.drawW < xmax)
- xmax = g_prim.drawW;
-
- if (xmax >= xmin) {
- posX = left_u;
- posY = left_v;
- cR1 = left_R;
- cG1 = left_G;
- cB1 = left_B;
-
- if (xmin < g_prim.drawX) {
- j = g_prim.drawX - xmin;
- xmin = g_prim.drawX;
- posX += j * difX;
- posY += j * difY;
- cR1 += j * difR;
- cG1 += j * difG;
- cB1 += j * difB;
- }
-
- for (j = xmin; j <= xmax; j++) {
- if (g_prim.iDither)
- GetTextureTransColGX_Dither(
- &g_gpu.psx_vram.u16[(i << 10) + j],
- GETLE16(&g_gpu.psx_vram.u16[(((posY>>16)+g_soft.GlobalTextAddrY)<<10)+(posX>>16)+g_soft.GlobalTextAddrX]),
- (cB1 >> 16), (cG1 >> 16), (cR1 >> 16));
- else
- GetTextureTransColGX(
- &g_gpu.psx_vram.u16[(i << 10) + j],
- GETLE16(&g_gpu.psx_vram.u16[(((posY>>16)+g_soft.GlobalTextAddrY)<<10)+(posX>>16)+g_soft.GlobalTextAddrX]),
- (cB1 >> 16), (cG1 >> 16), (cR1 >> 16));
- posX += difX;
- posY += difY;
- cR1 += difR;
- cG1 += difG;
- cB1 += difB;
- }
- }
- if (NextRow_GT()) {
- return;
- }
- }
-}
-
-////////////////////////////////////////////////////////////////////////
-
-static void drawPoly3TGD_TW(short x1, short y1, short x2, short y2, short x3,
- short y3, short tx1, short ty1, short tx2, short ty2, short tx3,
- short ty3, int32_t col1, int32_t col2, int32_t col3) {
- int i, j, xmin, xmax, ymin, ymax;
- int32_t cR1, cG1, cB1;
- int32_t difR, difB, difG, difR2, difB2, difG2;
- int32_t difX, difY, difX2, difY2;
- int32_t posX, posY;
-
- if (x1 > g_prim.drawW && x2 > g_prim.drawW && x3 > g_prim.drawW)
- return;
- if (y1 > g_prim.drawH && y2 > g_prim.drawH && y3 > g_prim.drawH)
- return;
- if (x1 < g_prim.drawX && x2 < g_prim.drawX && x3 < g_prim.drawX)
- return;
- if (y1 < g_prim.drawY && y2 < g_prim.drawY && y3 < g_prim.drawY)
- return;
- if (g_prim.drawY >= g_prim.drawH)
- return;
- if (g_prim.drawX >= g_prim.drawW)
- return;
-
- if (!SetupSections_GT(x1, y1, x2, y2, x3, y3, tx1, ty1, tx2, ty2, tx3, ty3,
- col1, col2, col3))
- return;
-
- ymax = g_soft.Ymax;
-
- for (ymin = g_soft.Ymin; ymin < g_prim.drawY; ymin++)
- if (NextRow_GT())
- return;
-
- difR = delta_right_R;
- difG = delta_right_G;
- difB = delta_right_B;
- difR2 = difR << 1;
- difG2 = difG << 1;
- difB2 = difB << 1;
- difX = delta_right_u;
- difX2 = difX << 1;
- difY = delta_right_v;
- difY2 = difY << 1;
-
-#ifdef FASTSOLID
-
- if (!g_draw.bCheckMask && !g_soft.DrawSemiTrans && !g_prim.iDither) {
- for (i = ymin; i <= ymax; i++) {
- xmin = (left_x >> 16);
- xmax = (right_x >> 16) - 1; //!!!!!!!!!!!!!!!!!!!!
- if (g_prim.drawW < xmax)
- xmax = g_prim.drawW;
-
- if (xmax >= xmin) {
- posX = left_u;
- posY = left_v;
- cR1 = left_R;
- cG1 = left_G;
- cB1 = left_B;
-
- if (xmin < g_prim.drawX) {
- j = g_prim.drawX - xmin;
- xmin = g_prim.drawX;
- posX += j * difX;
- posY += j * difY;
- cR1 += j * difR;
- cG1 += j * difG;
- cB1 += j * difB;
- }
-
- for (j = xmin; j < xmax; j += 2) {
- GetTextureTransColGX32_S(
- (uint32_t *) &g_gpu.psx_vram.u16[(i << 10) + j],
- (((int32_t) GETLE16(&g_gpu.psx_vram.u16[(((((posY+difY)>>16)%g_prim.TWin.Position.y1)+g_soft.GlobalTextAddrY+g_prim.TWin.Position.y0)<<10)+
- (((posX+difX)>>16)%g_prim.TWin.Position.x1)+g_soft.GlobalTextAddrX+g_prim.TWin.Position.x0]))
- << 16)
- | GETLE16(&g_gpu.psx_vram.u16[((((posY>>16)%g_prim.TWin.Position.y1)+g_soft.GlobalTextAddrY+g_prim.TWin.Position.y0)<<10)+
- (((posX)>>16)%g_prim.TWin.Position.x1)+g_soft.GlobalTextAddrX+g_prim.TWin.Position.x0]),
- (cB1 >> 16) | ((cB1 + difB) & 0xff0000),
- (cG1 >> 16) | ((cG1 + difG) & 0xff0000),
- (cR1 >> 16) | ((cR1 + difR) & 0xff0000));
- posX += difX2;
- posY += difY2;
- cR1 += difR2;
- cG1 += difG2;
- cB1 += difB2;
- }
- if (j == xmax)
- GetTextureTransColGX_S(
- &g_gpu.psx_vram.u16[(i << 10) + j],
- GETLE16(&g_gpu.psx_vram.u16[((((posY>>16)%g_prim.TWin.Position.y1)+g_soft.GlobalTextAddrY+g_prim.TWin.Position.y0)<<10)+
- ((posX>>16)%g_prim.TWin.Position.x1)+g_soft.GlobalTextAddrX+g_prim.TWin.Position.x0]),
- (cB1 >> 16), (cG1 >> 16), (cR1 >> 16));
- }
- if (NextRow_GT()) {
- return;
- }
- }
- return;
- }
-
-#endif
-
- for (i = ymin; i <= ymax; i++) {
- xmin = (left_x >> 16);
- xmax = (right_x >> 16) - 1; //!!!!!!!!!!!!!!!!!!
- if (g_prim.drawW < xmax)
- xmax = g_prim.drawW;
-
- if (xmax >= xmin) {
- posX = left_u;
- posY = left_v;
- cR1 = left_R;
- cG1 = left_G;
- cB1 = left_B;
-
- if (xmin < g_prim.drawX) {
- j = g_prim.drawX - xmin;
- xmin = g_prim.drawX;
- posX += j * difX;
- posY += j * difY;
- cR1 += j * difR;
- cG1 += j * difG;
- cB1 += j * difB;
- }
-
- for (j = xmin; j <= xmax; j++) {
- if (g_prim.iDither)
- GetTextureTransColGX_Dither(
- &g_gpu.psx_vram.u16[(i << 10) + j],
- GETLE16(&g_gpu.psx_vram.u16[((((posY>>16)%g_prim.TWin.Position.y1)+g_soft.GlobalTextAddrY+g_prim.TWin.Position.y0)<<10)+
- ((posX>>16)%g_prim.TWin.Position.x1)+g_soft.GlobalTextAddrX+g_prim.TWin.Position.x0]),
- (cB1 >> 16), (cG1 >> 16), (cR1 >> 16));
- else
- GetTextureTransColGX(
- &g_gpu.psx_vram.u16[(i << 10) + j],
- GETLE16(&g_gpu.psx_vram.u16[((((posY>>16)%g_prim.TWin.Position.y1)+g_soft.GlobalTextAddrY+g_prim.TWin.Position.y0)<<10)+
- ((posX>>16)%g_prim.TWin.Position.x1)+g_soft.GlobalTextAddrX+g_prim.TWin.Position.x0]),
- (cB1 >> 16), (cG1 >> 16), (cR1 >> 16));
- posX += difX;
- posY += difY;
- cR1 += difR;
- cG1 += difG;
- cB1 += difB;
- }
- }
- if (NextRow_GT()) {
- return;
- }
- }
-}
-
-////////////////////////////////////////////////////////////////////////
-
-// note: two g-shaded tris: small texture distortions can happen
-
-#ifdef POLYQUAD3GT
-
-static void drawPoly4TGD_TRI(short x1, short y1, short x2, short y2, short x3,
- short y3, short x4, short y4, short tx1, short ty1, short tx2,
- short ty2, short tx3, short ty3, short tx4, short ty4, int32_t col1,
- int32_t col2, int32_t col3, int32_t col4) {
- drawPoly3TGD(x2, y2, x3, y3, x4, y4, tx2, ty2, tx3, ty3, tx4, ty4, col2,
- col4, col3);
- drawPoly3TGD(x1, y1, x2, y2, x4, y4, tx1, ty1, tx2, ty2, tx4, ty4, col1,
- col2, col3);
-}
-
-#endif
-
-static void drawPoly4TGD(short x1, short y1, short x2, short y2, short x3, short y3,
- short x4, short y4, short tx1, short ty1, short tx2, short ty2,
- short tx3, short ty3, short tx4, short ty4, int32_t col1, int32_t col2,
- int32_t col4, int32_t col3) {
- int32_t num;
- int32_t i, j, xmin, xmax, ymin, ymax;
- int32_t cR1, cG1, cB1;
- int32_t difR, difB, difG, difR2, difB2, difG2;
- int32_t difX, difY, difX2, difY2;
- int32_t posX, posY;
-
- if (x1 > g_prim.drawW && x2 > g_prim.drawW && x3 > g_prim.drawW && x4
- > g_prim.drawW)
- return;
- if (y1 > g_prim.drawH && y2 > g_prim.drawH && y3 > g_prim.drawH && y4
- > g_prim.drawH)
- return;
- if (x1 < g_prim.drawX && x2 < g_prim.drawX && x3 < g_prim.drawX && x4
- < g_prim.drawX)
- return;
- if (y1 < g_prim.drawY && y2 < g_prim.drawY && y3 < g_prim.drawY && y4
- < g_prim.drawY)
- return;
- if (g_prim.drawY >= g_prim.drawH)
- return;
- if (g_prim.drawX >= g_prim.drawW)
- return;
-
- if (!SetupSections_GT4(x1, y1, x2, y2, x3, y3, x4, y4, tx1, ty1, tx2, ty2,
- tx3, ty3, tx4, ty4, col1, col2, col3, col4))
- return;
-
- ymax = g_soft.Ymax;
-
- for (ymin = g_soft.Ymin; ymin < g_prim.drawY; ymin++)
- if (NextRow_GT4())
- return;
-
-#ifdef FASTSOLID
-
- if (!g_draw.bCheckMask && !g_soft.DrawSemiTrans && !g_prim.iDither) {
- for (i = ymin; i <= ymax; i++) {
- xmin = (left_x >> 16);
- xmax = (right_x >> 16);
-
- if (xmax >= xmin) {
- posX = left_u;
- posY = left_v;
-
- num = (xmax - xmin);
- if (num == 0)
- num = 1;
- difX = (right_u - posX) / num;
- difY = (right_v - posY) / num;
- difX2 = difX << 1;
- difY2 = difY << 1;
-
- cR1 = left_R;
- cG1 = left_G;
- cB1 = left_B;
- difR = (right_R - cR1) / num;
- difG = (right_G - cG1) / num;
- difB = (right_B - cB1) / num;
- difR2 = difR << 1;
- difG2 = difG << 1;
- difB2 = difB << 1;
-
- if (xmin < g_prim.drawX) {
- j = g_prim.drawX - xmin;
- xmin = g_prim.drawX;
- posX += j * difX;
- posY += j * difY;
- cR1 += j * difR;
- cG1 += j * difG;
- cB1 += j * difB;
- }
- xmax--;
- if (g_prim.drawW < xmax)
- xmax = g_prim.drawW;
-
- for (j = xmin; j < xmax; j += 2) {
- GetTextureTransColGX32_S(
- (uint32_t *) &g_gpu.psx_vram.u16[(i << 10) + j],
- (((int32_t) GETLE16(&g_gpu.psx_vram.u16[((((posY+difY)>>16)+g_soft.GlobalTextAddrY)<<10)+((posX+difX)>>16)+g_soft.GlobalTextAddrX]))
- << 16)
- | GETLE16(&g_gpu.psx_vram.u16[(((posY>>16)+g_soft.GlobalTextAddrY)<<10)+((posX)>>16)+g_soft.GlobalTextAddrX]),
- (cB1 >> 16) | ((cB1 + difB) & 0xff0000),
- (cG1 >> 16) | ((cG1 + difG) & 0xff0000),
- (cR1 >> 16) | ((cR1 + difR) & 0xff0000));
- posX += difX2;
- posY += difY2;
- cR1 += difR2;
- cG1 += difG2;
- cB1 += difB2;
- }
- if (j == xmax)
- GetTextureTransColGX_S(
- &g_gpu.psx_vram.u16[(i << 10) + j],
- GETLE16(&g_gpu.psx_vram.u16[(((posY>>16)+g_soft.GlobalTextAddrY)<<10)+(posX>>16)+g_soft.GlobalTextAddrX]),
- (cB1 >> 16), (cG1 >> 16), (cR1 >> 16));
- }
- if (NextRow_GT4())
- return;
- }
- return;
- }
-
-#endif
-
- for (i = ymin; i <= ymax; i++) {
- xmin = (left_x >> 16);
- xmax = (right_x >> 16);
-
- if (xmax >= xmin) {
- posX = left_u;
- posY = left_v;
-
- num = (xmax - xmin);
- if (num == 0)
- num = 1;
- difX = (right_u - posX) / num;
- difY = (right_v - posY) / num;
- difX2 = difX << 1;
- difY2 = difY << 1;
-
- cR1 = left_R;
- cG1 = left_G;
- cB1 = left_B;
- difR = (right_R - cR1) / num;
- difG = (right_G - cG1) / num;
- difB = (right_B - cB1) / num;
- difR2 = difR << 1;
- difG2 = difG << 1;
- difB2 = difB << 1;
-
- if (xmin < g_prim.drawX) {
- j = g_prim.drawX - xmin;
- xmin = g_prim.drawX;
- posX += j * difX;
- posY += j * difY;
- cR1 += j * difR;
- cG1 += j * difG;
- cB1 += j * difB;
- }
- xmax--;
- if (g_prim.drawW < xmax)
- xmax = g_prim.drawW;
-
- for (j = xmin; j <= xmax; j++) {
- if (g_prim.iDither)
- GetTextureTransColGX(
- &g_gpu.psx_vram.u16[(i << 10) + j],
- GETLE16(&g_gpu.psx_vram.u16[(((posY>>16)+g_soft.GlobalTextAddrY)<<10)+(posX>>16)+g_soft.GlobalTextAddrX]),
- (cB1 >> 16), (cG1 >> 16), (cR1 >> 16));
- else
- GetTextureTransColGX(
- &g_gpu.psx_vram.u16[(i << 10) + j],
- GETLE16(&g_gpu.psx_vram.u16[(((posY>>16)+g_soft.GlobalTextAddrY)<<10)+(posX>>16)+g_soft.GlobalTextAddrX]),
- (cB1 >> 16), (cG1 >> 16), (cR1 >> 16));
- posX += difX;
- posY += difY;
- cR1 += difR;
- cG1 += difG;
- cB1 += difB;
- }
- }
- if (NextRow_GT4())
- return;
- }
-}
-
-////////////////////////////////////////////////////////////////////////
-
-static void drawPoly4TGD_TW(short x1, short y1, short x2, short y2, short x3,
- short y3, short x4, short y4, short tx1, short ty1, short tx2,
- short ty2, short tx3, short ty3, short tx4, short ty4, int32_t col1,
- int32_t col2, int32_t col3, int32_t col4) {
- drawPoly3TGD_TW(x2, y2, x3, y3, x4, y4, tx2, ty2, tx3, ty3, tx4, ty4, col2,
- col4, col3);
- drawPoly3TGD_TW(x1, y1, x2, y2, x4, y4, tx1, ty1, tx2, ty2, tx4, ty4, col1,
- col2, col3);
-}
-
-////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////
-
-
-/*
- // no real rect test, but it does its job the way I need it
- inline char IsNoRect(void)
- {
- if(g_soft.lx0==g_soft.lx1 && g_soft.lx2==g_soft.lx3) return 0;
- if(g_soft.lx0==g_soft.lx2 && g_soft.lx1==g_soft.lx3) return 0;
- if(g_soft.lx0==g_soft.lx3 && g_soft.lx1==g_soft.lx2) return 0;
- return 1;
- }
- */
-
-// real rect test
-static inline char IsNoRect(void) {
- if (!(g_prim.dwActFixes & 0x200))
- return 0;
-
- if (g_soft.ly0 == g_soft.ly1) {
- if (g_soft.lx1 == g_soft.lx3 && g_soft.ly3 == g_soft.ly2 && g_soft.lx2
- == g_soft.lx0)
- return 0;
- if (g_soft.lx1 == g_soft.lx2 && g_soft.ly2 == g_soft.ly3 && g_soft.lx3
- == g_soft.lx0)
- return 0;
- return 1;
- }
-
- if (g_soft.ly0 == g_soft.ly2) {
- if (g_soft.lx2 == g_soft.lx3 && g_soft.ly3 == g_soft.ly1 && g_soft.lx1
- == g_soft.lx0)
- return 0;
- if (g_soft.lx2 == g_soft.lx1 && g_soft.ly1 == g_soft.ly3 && g_soft.lx3
- == g_soft.lx0)
- return 0;
- return 1;
- }
-
- if (g_soft.ly0 == g_soft.ly3) {
- if (g_soft.lx3 == g_soft.lx2 && g_soft.ly2 == g_soft.ly1 && g_soft.lx1
- == g_soft.lx0)
- return 0;
- if (g_soft.lx3 == g_soft.lx1 && g_soft.ly1 == g_soft.ly2 && g_soft.lx2
- == g_soft.lx0)
- return 0;
- return 1;
- }
- return 1;
-}
-
-////////////////////////////////////////////////////////////////////////
-
-void drawPoly3FT(unsigned char * baseAddr) {
- uint32_t *gpuData = ((uint32_t *) baseAddr);
-
- if (0 && g_soft.GlobalTextTP < 2) {
- if (g_soft.GlobalTextTP == 0)
- drawPoly3TEx4_IL(g_soft.lx0, g_soft.ly0, g_soft.lx1, g_soft.ly1,
- g_soft.lx2, g_soft.ly2,
- (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])
- >> 8) & 0x000000ff), (GETLE32(&gpuData[4])
- & 0x000000ff), ((GETLE32(&gpuData[4]) >> 8)
- & 0x000000ff), (GETLE32(&gpuData[6]) & 0x000000ff),
- ((GETLE32(&gpuData[6]) >> 8) & 0x000000ff),
- ((GETLE32(&gpuData[2]) >> 12) & 0x3f0),
- ((GETLE32(&gpuData[2]) >> 22) & 0x01ff));
- else
- drawPoly3TEx8_IL(g_soft.lx0, g_soft.ly0, g_soft.lx1, g_soft.ly1,
- g_soft.lx2, g_soft.ly2,
- (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])
- >> 8) & 0x000000ff), (GETLE32(&gpuData[4])
- & 0x000000ff), ((GETLE32(&gpuData[4]) >> 8)
- & 0x000000ff), (GETLE32(&gpuData[6]) & 0x000000ff),
- ((GETLE32(&gpuData[6]) >> 8) & 0x000000ff),
- ((GETLE32(&gpuData[2]) >> 12) & 0x3f0),
- ((GETLE32(&gpuData[2]) >> 22) & 0x01ff));
- return;
- }
-
- if (!g_prim.bUsingTWin && !(g_prim.dwActFixes & 0x100)) {
- switch (g_soft.GlobalTextTP) // depending on texture mode
- {
- case 0:
- drawPoly3TEx4(g_soft.lx0, g_soft.ly0, g_soft.lx1, g_soft.ly1,
- g_soft.lx2, g_soft.ly2,
- (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])
- >> 8) & 0x000000ff), (GETLE32(&gpuData[4])
- & 0x000000ff), ((GETLE32(&gpuData[4]) >> 8)
- & 0x000000ff), (GETLE32(&gpuData[6]) & 0x000000ff),
- ((GETLE32(&gpuData[6]) >> 8) & 0x000000ff),
- ((GETLE32(&gpuData[2]) >> 12) & 0x3f0),
- ((GETLE32(&gpuData[2]) >> 22) & 0x01ff));
- return;
- case 1:
- drawPoly3TEx8(g_soft.lx0, g_soft.ly0, g_soft.lx1, g_soft.ly1,
- g_soft.lx2, g_soft.ly2,
- (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])
- >> 8) & 0x000000ff), (GETLE32(&gpuData[4])
- & 0x000000ff), ((GETLE32(&gpuData[4]) >> 8)
- & 0x000000ff), (GETLE32(&gpuData[6]) & 0x000000ff),
- ((GETLE32(&gpuData[6]) >> 8) & 0x000000ff),
- ((GETLE32(&gpuData[2]) >> 12) & 0x3f0),
- ((GETLE32(&gpuData[2]) >> 22) & 0x01ff));
- return;
- case 2:
- drawPoly3TD(g_soft.lx0, g_soft.ly0, g_soft.lx1, g_soft.ly1,
- g_soft.lx2, g_soft.ly2,
- (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])
- >> 8) & 0x000000ff), (GETLE32(&gpuData[4])
- & 0x000000ff), ((GETLE32(&gpuData[4]) >> 8)
- & 0x000000ff), (GETLE32(&gpuData[6]) & 0x000000ff),
- ((GETLE32(&gpuData[6]) >> 8) & 0x000000ff));
- return;
- }
- return;
- }
-
- switch (g_soft.GlobalTextTP) // depending on texture mode
- {
- case 0:
- drawPoly3TEx4_TW(g_soft.lx0, g_soft.ly0, g_soft.lx1, g_soft.ly1,
- g_soft.lx2, g_soft.ly2, (GETLE32(&gpuData[2]) & 0x000000ff),
- ((GETLE32(&gpuData[2]) >> 8) & 0x000000ff),
- (GETLE32(&gpuData[4]) & 0x000000ff), ((GETLE32(&gpuData[4])
- >> 8) & 0x000000ff),
- (GETLE32(&gpuData[6]) & 0x000000ff), ((GETLE32(&gpuData[6])
- >> 8) & 0x000000ff), ((GETLE32(&gpuData[2]) >> 12)
- & 0x3f0), ((GETLE32(&gpuData[2]) >> 22) & 0x01ff));
- return;
- case 1:
- drawPoly3TEx8_TW(g_soft.lx0, g_soft.ly0, g_soft.lx1, g_soft.ly1,
- g_soft.lx2, g_soft.ly2, (GETLE32(&gpuData[2]) & 0x000000ff),
- ((GETLE32(&gpuData[2]) >> 8) & 0x000000ff),
- (GETLE32(&gpuData[4]) & 0x000000ff), ((GETLE32(&gpuData[4])
- >> 8) & 0x000000ff),
- (GETLE32(&gpuData[6]) & 0x000000ff), ((GETLE32(&gpuData[6])
- >> 8) & 0x000000ff), ((GETLE32(&gpuData[2]) >> 12)
- & 0x3f0), ((GETLE32(&gpuData[2]) >> 22) & 0x01ff));
- return;
- case 2:
- drawPoly3TD_TW(g_soft.lx0, g_soft.ly0, g_soft.lx1, g_soft.ly1,
- g_soft.lx2, g_soft.ly2, (GETLE32(&gpuData[2]) & 0x000000ff),
- ((GETLE32(&gpuData[2]) >> 8) & 0x000000ff),
- (GETLE32(&gpuData[4]) & 0x000000ff), ((GETLE32(&gpuData[4])
- >> 8) & 0x000000ff),
- (GETLE32(&gpuData[6]) & 0x000000ff), ((GETLE32(&gpuData[6])
- >> 8) & 0x000000ff));
- return;
- }
-}
-
-////////////////////////////////////////////////////////////////////////
-
-void drawPoly4FT(unsigned char * baseAddr) {
- uint32_t *gpuData = ((uint32_t *) baseAddr);
-
- if (0 && g_soft.GlobalTextTP < 2) {
- if (g_soft.GlobalTextTP == 0)
- drawPoly4TEx4_IL(g_soft.lx0, g_soft.ly0, g_soft.lx1, g_soft.ly1,
- g_soft.lx3, g_soft.ly3, g_soft.lx2, g_soft.ly2,
- (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])
- >> 8) & 0x000000ff), (GETLE32(&gpuData[4])
- & 0x000000ff), ((GETLE32(&gpuData[4]) >> 8)
- & 0x000000ff), (GETLE32(&gpuData[8]) & 0x000000ff),
- ((GETLE32(&gpuData[8]) >> 8) & 0x000000ff),
- (GETLE32(&gpuData[6]) & 0x000000ff), ((GETLE32(&gpuData[6])
- >> 8) & 0x000000ff), ((GETLE32(&gpuData[2]) >> 12)
- & 0x3f0), ((GETLE32(&gpuData[2]) >> 22) & 0x01ff));
- else
- drawPoly4TEx8_IL(g_soft.lx0, g_soft.ly0, g_soft.lx1, g_soft.ly1,
- g_soft.lx3, g_soft.ly3, g_soft.lx2, g_soft.ly2,
- (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])
- >> 8) & 0x000000ff), (GETLE32(&gpuData[4])
- & 0x000000ff), ((GETLE32(&gpuData[4]) >> 8)
- & 0x000000ff), (GETLE32(&gpuData[8]) & 0x000000ff),
- ((GETLE32(&gpuData[8]) >> 8) & 0x000000ff),
- (GETLE32(&gpuData[6]) & 0x000000ff), ((GETLE32(&gpuData[6])
- >> 8) & 0x000000ff), ((GETLE32(&gpuData[2]) >> 12)
- & 0x3f0), ((GETLE32(&gpuData[2]) >> 22) & 0x01ff));
- return;
- }
-
- if (!g_prim.bUsingTWin) {
-#ifdef POLYQUAD3GT
- if (IsNoRect()) {
- switch (g_soft.GlobalTextTP) {
- case 0:
- drawPoly4TEx4_TRI(g_soft.lx0, g_soft.ly0, g_soft.lx1,
- g_soft.ly1, g_soft.lx3, g_soft.ly3, g_soft.lx2,
- g_soft.ly2, (GETLE32(&gpuData[2]) & 0x000000ff),
- ((GETLE32(&gpuData[2]) >> 8) & 0x000000ff),
- (GETLE32(&gpuData[4]) & 0x000000ff),
- ((GETLE32(&gpuData[4]) >> 8) & 0x000000ff),
- (GETLE32(&gpuData[8]) & 0x000000ff),
- ((GETLE32(&gpuData[8]) >> 8) & 0x000000ff),
- (GETLE32(&gpuData[6]) & 0x000000ff),
- ((GETLE32(&gpuData[6]) >> 8) & 0x000000ff),
- ((GETLE32(&gpuData[2]) >> 12) & 0x3f0),
- ((GETLE32(&gpuData[2]) >> 22) & 0x01ff));
- return;
- case 1:
- drawPoly4TEx8_TRI(g_soft.lx0, g_soft.ly0, g_soft.lx1,
- g_soft.ly1, g_soft.lx3, g_soft.ly3, g_soft.lx2,
- g_soft.ly2, (GETLE32(&gpuData[2]) & 0x000000ff),
- ((GETLE32(&gpuData[2]) >> 8) & 0x000000ff),
- (GETLE32(&gpuData[4]) & 0x000000ff),
- ((GETLE32(&gpuData[4]) >> 8) & 0x000000ff),
- (GETLE32(&gpuData[8]) & 0x000000ff),
- ((GETLE32(&gpuData[8]) >> 8) & 0x000000ff),
- (GETLE32(&gpuData[6]) & 0x000000ff),
- ((GETLE32(&gpuData[6]) >> 8) & 0x000000ff),
- ((GETLE32(&gpuData[2]) >> 12) & 0x3f0),
- ((GETLE32(&gpuData[2]) >> 22) & 0x01ff));
- return;
- case 2:
- drawPoly4TD_TRI(g_soft.lx0, g_soft.ly0, g_soft.lx1, g_soft.ly1,
- g_soft.lx3, g_soft.ly3, g_soft.lx2, g_soft.ly2,
- (GETLE32(&gpuData[2]) & 0x000000ff),
- ((GETLE32(&gpuData[2]) >> 8) & 0x000000ff),
- (GETLE32(&gpuData[4]) & 0x000000ff),
- ((GETLE32(&gpuData[4]) >> 8) & 0x000000ff),
- (GETLE32(&gpuData[8]) & 0x000000ff),
- ((GETLE32(&gpuData[8]) >> 8) & 0x000000ff),
- (GETLE32(&gpuData[6]) & 0x000000ff),
- ((GETLE32(&gpuData[6]) >> 8) & 0x000000ff));
- return;
- }
- return;
- }
-#endif
-
- switch (g_soft.GlobalTextTP) {
- case 0: // grandia investigations needed
- drawPoly4TEx4(g_soft.lx0, g_soft.ly0, g_soft.lx1, g_soft.ly1,
- g_soft.lx3, g_soft.ly3, g_soft.lx2, g_soft.ly2,
- (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])
- >> 8) & 0x000000ff), (GETLE32(&gpuData[4])
- & 0x000000ff), ((GETLE32(&gpuData[4]) >> 8)
- & 0x000000ff), (GETLE32(&gpuData[8]) & 0x000000ff),
- ((GETLE32(&gpuData[8]) >> 8) & 0x000000ff),
- (GETLE32(&gpuData[6]) & 0x000000ff), ((GETLE32(&gpuData[6])
- >> 8) & 0x000000ff), ((GETLE32(&gpuData[2]) >> 12)
- & 0x3f0), ((GETLE32(&gpuData[2]) >> 22) & 0x01ff));
- return;
- case 1:
- drawPoly4TEx8(g_soft.lx0, g_soft.ly0, g_soft.lx1, g_soft.ly1,
- g_soft.lx3, g_soft.ly3, g_soft.lx2, g_soft.ly2,
- (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])
- >> 8) & 0x000000ff), (GETLE32(&gpuData[4])
- & 0x000000ff), ((GETLE32(&gpuData[4]) >> 8)
- & 0x000000ff), (GETLE32(&gpuData[8]) & 0x000000ff),
- ((GETLE32(&gpuData[8]) >> 8) & 0x000000ff),
- (GETLE32(&gpuData[6]) & 0x000000ff), ((GETLE32(&gpuData[6])
- >> 8) & 0x000000ff), ((GETLE32(&gpuData[2]) >> 12)
- & 0x3f0), ((GETLE32(&gpuData[2]) >> 22) & 0x01ff));
- return;
- case 2:
- drawPoly4TD(g_soft.lx0, g_soft.ly0, g_soft.lx1, g_soft.ly1,
- g_soft.lx3, g_soft.ly3, g_soft.lx2, g_soft.ly2,
- (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])
- >> 8) & 0x000000ff), (GETLE32(&gpuData[4])
- & 0x000000ff), ((GETLE32(&gpuData[4]) >> 8)
- & 0x000000ff), (GETLE32(&gpuData[8]) & 0x000000ff),
- ((GETLE32(&gpuData[8]) >> 8) & 0x000000ff),
- (GETLE32(&gpuData[6]) & 0x000000ff), ((GETLE32(&gpuData[6])
- >> 8) & 0x000000ff));
- return;
- }
- return;
- }
-
- switch (g_soft.GlobalTextTP) {
- case 0:
- drawPoly4TEx4_TW(g_soft.lx0, g_soft.ly0, g_soft.lx1, g_soft.ly1,
- g_soft.lx3, g_soft.ly3, g_soft.lx2, g_soft.ly2,
- (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])
- >> 8) & 0x000000ff),
- (GETLE32(&gpuData[4]) & 0x000000ff), ((GETLE32(&gpuData[4])
- >> 8) & 0x000000ff),
- (GETLE32(&gpuData[8]) & 0x000000ff), ((GETLE32(&gpuData[8])
- >> 8) & 0x000000ff),
- (GETLE32(&gpuData[6]) & 0x000000ff), ((GETLE32(&gpuData[6])
- >> 8) & 0x000000ff), ((GETLE32(&gpuData[2]) >> 12)
- & 0x3f0), ((GETLE32(&gpuData[2]) >> 22) & 0x01ff));
- return;
- case 1:
- drawPoly4TEx8_TW(g_soft.lx0, g_soft.ly0, g_soft.lx1, g_soft.ly1,
- g_soft.lx3, g_soft.ly3, g_soft.lx2, g_soft.ly2,
- (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])
- >> 8) & 0x000000ff),
- (GETLE32(&gpuData[4]) & 0x000000ff), ((GETLE32(&gpuData[4])
- >> 8) & 0x000000ff),
- (GETLE32(&gpuData[8]) & 0x000000ff), ((GETLE32(&gpuData[8])
- >> 8) & 0x000000ff),
- (GETLE32(&gpuData[6]) & 0x000000ff), ((GETLE32(&gpuData[6])
- >> 8) & 0x000000ff), ((GETLE32(&gpuData[2]) >> 12)
- & 0x3f0), ((GETLE32(&gpuData[2]) >> 22) & 0x01ff));
- return;
- case 2:
- drawPoly4TD_TW(g_soft.lx0, g_soft.ly0, g_soft.lx1, g_soft.ly1,
- g_soft.lx3, g_soft.ly3, g_soft.lx2, g_soft.ly2,
- (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])
- >> 8) & 0x000000ff),
- (GETLE32(&gpuData[4]) & 0x000000ff), ((GETLE32(&gpuData[4])
- >> 8) & 0x000000ff),
- (GETLE32(&gpuData[8]) & 0x000000ff), ((GETLE32(&gpuData[8])
- >> 8) & 0x000000ff),
- (GETLE32(&gpuData[6]) & 0x000000ff), ((GETLE32(&gpuData[6])
- >> 8) & 0x000000ff));
- return;
- }
-}
-
-////////////////////////////////////////////////////////////////////////
-
-void drawPoly3GT(unsigned char * baseAddr) {
- uint32_t *gpuData = ((uint32_t *) baseAddr);
-
- if (0 && g_soft.GlobalTextTP < 2) {
- if (g_soft.GlobalTextTP == 0)
- drawPoly3TGEx4_IL(g_soft.lx0, g_soft.ly0, g_soft.lx1, g_soft.ly1,
- g_soft.lx2, g_soft.ly2,
- (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])
- >> 8) & 0x000000ff), (GETLE32(&gpuData[5])
- & 0x000000ff), ((GETLE32(&gpuData[5]) >> 8)
- & 0x000000ff), (GETLE32(&gpuData[8]) & 0x000000ff),
- ((GETLE32(&gpuData[8]) >> 8) & 0x000000ff),
- ((GETLE32(&gpuData[2]) >> 12) & 0x3f0),
- ((GETLE32(&gpuData[2]) >> 22) & 0x01ff),
- GETLE32(&gpuData[0]), GETLE32(&gpuData[3]),
- GETLE32(&gpuData[6]));
- else
- drawPoly3TGEx8_IL(g_soft.lx0, g_soft.ly0, g_soft.lx1, g_soft.ly1,
- g_soft.lx2, g_soft.ly2,
- (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])
- >> 8) & 0x000000ff), (GETLE32(&gpuData[5])
- & 0x000000ff), ((GETLE32(&gpuData[5]) >> 8)
- & 0x000000ff), (GETLE32(&gpuData[8]) & 0x000000ff),
- ((GETLE32(&gpuData[8]) >> 8) & 0x000000ff),
- ((GETLE32(&gpuData[2]) >> 12) & 0x3f0),
- ((GETLE32(&gpuData[2]) >> 22) & 0x01ff),
- GETLE32(&gpuData[0]), GETLE32(&gpuData[3]),
- GETLE32(&gpuData[6]));
- return;
- }
-
- if (!g_prim.bUsingTWin) {
- switch (g_soft.GlobalTextTP) {
- case 0:
- drawPoly3TGEx4(g_soft.lx0, g_soft.ly0, g_soft.lx1, g_soft.ly1,
- g_soft.lx2, g_soft.ly2,
- (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])
- >> 8) & 0x000000ff), (GETLE32(&gpuData[5])
- & 0x000000ff), ((GETLE32(&gpuData[5]) >> 8)
- & 0x000000ff), (GETLE32(&gpuData[8]) & 0x000000ff),
- ((GETLE32(&gpuData[8]) >> 8) & 0x000000ff),
- ((GETLE32(&gpuData[2]) >> 12) & 0x3f0),
- ((GETLE32(&gpuData[2]) >> 22) & 0x01ff),
- GETLE32(&gpuData[0]), GETLE32(&gpuData[3]),
- GETLE32(&gpuData[6]));
- return;
- case 1:
- drawPoly3TGEx8(g_soft.lx0, g_soft.ly0, g_soft.lx1, g_soft.ly1,
- g_soft.lx2, g_soft.ly2,
- (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])
- >> 8) & 0x000000ff), (GETLE32(&gpuData[5])
- & 0x000000ff), ((GETLE32(&gpuData[5]) >> 8)
- & 0x000000ff), (GETLE32(&gpuData[8]) & 0x000000ff),
- ((GETLE32(&gpuData[8]) >> 8) & 0x000000ff),
- ((GETLE32(&gpuData[2]) >> 12) & 0x3f0),
- ((GETLE32(&gpuData[2]) >> 22) & 0x01ff),
- GETLE32(&gpuData[0]), GETLE32(&gpuData[3]),
- GETLE32(&gpuData[6]));
- return;
- case 2:
- drawPoly3TGD(g_soft.lx0, g_soft.ly0, g_soft.lx1, g_soft.ly1,
- g_soft.lx2, g_soft.ly2,
- (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])
- >> 8) & 0x000000ff), (GETLE32(&gpuData[5])
- & 0x000000ff), ((GETLE32(&gpuData[5]) >> 8)
- & 0x000000ff), (GETLE32(&gpuData[8]) & 0x000000ff),
- ((GETLE32(&gpuData[8]) >> 8) & 0x000000ff),
- GETLE32(&gpuData[0]), GETLE32(&gpuData[3]),
- GETLE32(&gpuData[6]));
- return;
- }
- return;
- }
-
- switch (g_soft.GlobalTextTP) {
- case 0:
- drawPoly3TGEx4_TW(g_soft.lx0, g_soft.ly0, g_soft.lx1, g_soft.ly1,
- g_soft.lx2, g_soft.ly2, (GETLE32(&gpuData[2]) & 0x000000ff),
- ((GETLE32(&gpuData[2]) >> 8) & 0x000000ff),
- (GETLE32(&gpuData[5]) & 0x000000ff), ((GETLE32(&gpuData[5])
- >> 8) & 0x000000ff),
- (GETLE32(&gpuData[8]) & 0x000000ff), ((GETLE32(&gpuData[8])
- >> 8) & 0x000000ff), ((GETLE32(&gpuData[2]) >> 12)
- & 0x3f0), ((GETLE32(&gpuData[2]) >> 22) & 0x01ff),
- GETLE32(&gpuData[0]), GETLE32(&gpuData[3]),
- GETLE32(&gpuData[6]));
- return;
- case 1:
- drawPoly3TGEx8_TW(g_soft.lx0, g_soft.ly0, g_soft.lx1, g_soft.ly1,
- g_soft.lx2, g_soft.ly2, (GETLE32(&gpuData[2]) & 0x000000ff),
- ((GETLE32(&gpuData[2]) >> 8) & 0x000000ff),
- (GETLE32(&gpuData[5]) & 0x000000ff), ((GETLE32(&gpuData[5])
- >> 8) & 0x000000ff),
- (GETLE32(&gpuData[8]) & 0x000000ff), ((GETLE32(&gpuData[8])
- >> 8) & 0x000000ff), ((GETLE32(&gpuData[2]) >> 12)
- & 0x3f0), ((GETLE32(&gpuData[2]) >> 22) & 0x01ff),
- GETLE32(&gpuData[0]), GETLE32(&gpuData[3]),
- GETLE32(&gpuData[6]));
- return;
- case 2:
- drawPoly3TGD_TW(g_soft.lx0, g_soft.ly0, g_soft.lx1, g_soft.ly1,
- g_soft.lx2, g_soft.ly2, (GETLE32(&gpuData[2]) & 0x000000ff),
- ((GETLE32(&gpuData[2]) >> 8) & 0x000000ff),
- (GETLE32(&gpuData[5]) & 0x000000ff), ((GETLE32(&gpuData[5])
- >> 8) & 0x000000ff),
- (GETLE32(&gpuData[8]) & 0x000000ff), ((GETLE32(&gpuData[8])
- >> 8) & 0x000000ff), GETLE32(&gpuData[0]),
- GETLE32(&gpuData[3]), GETLE32(&gpuData[6]));
- return;
- }
-}
-
-////////////////////////////////////////////////////////////////////////
-
-void drawPoly4GT(unsigned char *baseAddr) {
- uint32_t *gpuData = ((uint32_t *) baseAddr);
-
- if (0 && g_soft.GlobalTextTP < 2) {
- if (g_soft.GlobalTextTP == 0)
- drawPoly4TGEx4_TRI_IL(g_soft.lx0, g_soft.ly0, g_soft.lx1,
- g_soft.ly1, g_soft.lx3, g_soft.ly3, g_soft.lx2, g_soft.ly2,
- (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])
- >> 8) & 0x000000ff), (GETLE32(&gpuData[5])
- & 0x000000ff), ((GETLE32(&gpuData[5]) >> 8)
- & 0x000000ff),
- (GETLE32(&gpuData[11]) & 0x000000ff),
- ((GETLE32(&gpuData[11]) >> 8) & 0x000000ff),
- (GETLE32(&gpuData[8]) & 0x000000ff), ((GETLE32(&gpuData[8])
- >> 8) & 0x000000ff), ((GETLE32(&gpuData[2]) >> 12)
- & 0x3f0), ((GETLE32(&gpuData[2]) >> 22) & 0x01ff),
- GETLE32(&gpuData[0]), GETLE32(&gpuData[3]),
- GETLE32(&gpuData[6]), GETLE32(&gpuData[9]));
- else
- drawPoly4TGEx8_TRI_IL(g_soft.lx0, g_soft.ly0, g_soft.lx1,
- g_soft.ly1, g_soft.lx3, g_soft.ly3, g_soft.lx2, g_soft.ly2,
- (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])
- >> 8) & 0x000000ff), (GETLE32(&gpuData[5])
- & 0x000000ff), ((GETLE32(&gpuData[5]) >> 8)
- & 0x000000ff),
- (GETLE32(&gpuData[11]) & 0x000000ff),
- ((GETLE32(&gpuData[11]) >> 8) & 0x000000ff),
- (GETLE32(&gpuData[8]) & 0x000000ff), ((GETLE32(&gpuData[8])
- >> 8) & 0x000000ff), ((GETLE32(&gpuData[2]) >> 12)
- & 0x3f0), ((GETLE32(&gpuData[2]) >> 22) & 0x01ff),
- GETLE32(&gpuData[0]), GETLE32(&gpuData[3]),
- GETLE32(&gpuData[6]), GETLE32(&gpuData[9]));
- return;
- }
-
- if (!g_prim.bUsingTWin) {
-#ifdef POLYQUAD3GT
- if (IsNoRect()) {
- switch (g_soft.GlobalTextTP) {
- case 0:
- drawPoly4TGEx4_TRI(g_soft.lx0, g_soft.ly0, g_soft.lx1,
- g_soft.ly1, g_soft.lx3, g_soft.ly3, g_soft.lx2,
- g_soft.ly2, (GETLE32(&gpuData[2]) & 0x000000ff),
- ((GETLE32(&gpuData[2]) >> 8) & 0x000000ff),
- (GETLE32(&gpuData[5]) & 0x000000ff),
- ((GETLE32(&gpuData[5]) >> 8) & 0x000000ff),
- (GETLE32(&gpuData[11]) & 0x000000ff),
- ((GETLE32(&gpuData[11]) >> 8) & 0x000000ff),
- (GETLE32(&gpuData[8]) & 0x000000ff),
- ((GETLE32(&gpuData[8]) >> 8) & 0x000000ff),
- ((GETLE32(&gpuData[2]) >> 12) & 0x3f0),
- ((GETLE32(&gpuData[2]) >> 22) & 0x01ff),
- GETLE32(&gpuData[0]), GETLE32(&gpuData[3]),
- GETLE32(&gpuData[6]), GETLE32(&gpuData[9]));
-
- return;
- case 1:
- drawPoly4TGEx8_TRI(g_soft.lx0, g_soft.ly0, g_soft.lx1,
- g_soft.ly1, g_soft.lx3, g_soft.ly3, g_soft.lx2,
- g_soft.ly2, (GETLE32(&gpuData[2]) & 0x000000ff),
- ((GETLE32(&gpuData[2]) >> 8) & 0x000000ff),
- (GETLE32(&gpuData[5]) & 0x000000ff),
- ((GETLE32(&gpuData[5]) >> 8) & 0x000000ff),
- (GETLE32(&gpuData[11]) & 0x000000ff),
- ((GETLE32(&gpuData[11]) >> 8) & 0x000000ff),
- (GETLE32(&gpuData[8]) & 0x000000ff),
- ((GETLE32(&gpuData[8]) >> 8) & 0x000000ff),
- ((GETLE32(&gpuData[2]) >> 12) & 0x3f0),
- ((GETLE32(&gpuData[2]) >> 22) & 0x01ff),
- GETLE32(&gpuData[0]), GETLE32(&gpuData[3]),
- GETLE32(&gpuData[6]), GETLE32(&gpuData[9]));
- return;
- case 2:
- drawPoly4TGD_TRI(g_soft.lx0, g_soft.ly0, g_soft.lx1,
- g_soft.ly1, g_soft.lx3, g_soft.ly3, g_soft.lx2,
- g_soft.ly2, (GETLE32(&gpuData[2]) & 0x000000ff),
- ((GETLE32(&gpuData[2]) >> 8) & 0x000000ff),
- (GETLE32(&gpuData[5]) & 0x000000ff),
- ((GETLE32(&gpuData[5]) >> 8) & 0x000000ff),
- (GETLE32(&gpuData[11]) & 0x000000ff),
- ((GETLE32(&gpuData[11]) >> 8) & 0x000000ff),
- (GETLE32(&gpuData[8]) & 0x000000ff),
- ((GETLE32(&gpuData[8]) >> 8) & 0x000000ff),
- GETLE32(&gpuData[0]), GETLE32(&gpuData[3]),
- GETLE32(&gpuData[6]), GETLE32(&gpuData[9]));
- return;
- }
- return;
- }
-#endif
-
- switch (g_soft.GlobalTextTP) {
- case 0:
- drawPoly4TGEx4(g_soft.lx0, g_soft.ly0, g_soft.lx1, g_soft.ly1,
- g_soft.lx3, g_soft.ly3, g_soft.lx2, g_soft.ly2,
- (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])
- >> 8) & 0x000000ff), (GETLE32(&gpuData[5])
- & 0x000000ff), ((GETLE32(&gpuData[5]) >> 8)
- & 0x000000ff),
- (GETLE32(&gpuData[11]) & 0x000000ff),
- ((GETLE32(&gpuData[11]) >> 8) & 0x000000ff),
- (GETLE32(&gpuData[8]) & 0x000000ff), ((GETLE32(&gpuData[8])
- >> 8) & 0x000000ff), ((GETLE32(&gpuData[2]) >> 12)
- & 0x3f0), ((GETLE32(&gpuData[2]) >> 22) & 0x01ff),
- GETLE32(&gpuData[0]), GETLE32(&gpuData[3]),
- GETLE32(&gpuData[6]), GETLE32(&gpuData[9]));
-
- return;
- case 1:
- drawPoly4TGEx8(g_soft.lx0, g_soft.ly0, g_soft.lx1, g_soft.ly1,
- g_soft.lx3, g_soft.ly3, g_soft.lx2, g_soft.ly2,
- (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])
- >> 8) & 0x000000ff), (GETLE32(&gpuData[5])
- & 0x000000ff), ((GETLE32(&gpuData[5]) >> 8)
- & 0x000000ff),
- (GETLE32(&gpuData[11]) & 0x000000ff),
- ((GETLE32(&gpuData[11]) >> 8) & 0x000000ff),
- (GETLE32(&gpuData[8]) & 0x000000ff), ((GETLE32(&gpuData[8])
- >> 8) & 0x000000ff), ((GETLE32(&gpuData[2]) >> 12)
- & 0x3f0), ((GETLE32(&gpuData[2]) >> 22) & 0x01ff),
- GETLE32(&gpuData[0]), GETLE32(&gpuData[3]),
- GETLE32(&gpuData[6]), GETLE32(&gpuData[9]));
- return;
- case 2:
- drawPoly4TGD(g_soft.lx0, g_soft.ly0, g_soft.lx1, g_soft.ly1,
- g_soft.lx3, g_soft.ly3, g_soft.lx2, g_soft.ly2,
- (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])
- >> 8) & 0x000000ff), (GETLE32(&gpuData[5])
- & 0x000000ff), ((GETLE32(&gpuData[5]) >> 8)
- & 0x000000ff),
- (GETLE32(&gpuData[11]) & 0x000000ff),
- ((GETLE32(&gpuData[11]) >> 8) & 0x000000ff),
- (GETLE32(&gpuData[8]) & 0x000000ff), ((GETLE32(&gpuData[8])
- >> 8) & 0x000000ff), GETLE32(&gpuData[0]),
- GETLE32(&gpuData[3]), GETLE32(&gpuData[6]),
- GETLE32(&gpuData[9]));
- return;
- }
- return;
- }
-
- switch (g_soft.GlobalTextTP) {
- case 0:
- drawPoly4TGEx4_TW(g_soft.lx0, g_soft.ly0, g_soft.lx1, g_soft.ly1,
- g_soft.lx3, g_soft.ly3, g_soft.lx2, g_soft.ly2,
- (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])
- >> 8) & 0x000000ff),
- (GETLE32(&gpuData[5]) & 0x000000ff), ((GETLE32(&gpuData[5])
- >> 8) & 0x000000ff), (GETLE32(&gpuData[11])
- & 0x000000ff), ((GETLE32(&gpuData[11]) >> 8)
- & 0x000000ff), (GETLE32(&gpuData[8]) & 0x000000ff),
- ((GETLE32(&gpuData[8]) >> 8) & 0x000000ff),
- ((GETLE32(&gpuData[2]) >> 12) & 0x3f0), ((GETLE32(&gpuData[2])
- >> 22) & 0x01ff), GETLE32(&gpuData[0]),
- GETLE32(&gpuData[3]), GETLE32(&gpuData[6]),
- GETLE32(&gpuData[9]));
- return;
- case 1:
- drawPoly4TGEx8_TW(g_soft.lx0, g_soft.ly0, g_soft.lx1, g_soft.ly1,
- g_soft.lx3, g_soft.ly3, g_soft.lx2, g_soft.ly2,
- (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])
- >> 8) & 0x000000ff),
- (GETLE32(&gpuData[5]) & 0x000000ff), ((GETLE32(&gpuData[5])
- >> 8) & 0x000000ff), (GETLE32(&gpuData[11])
- & 0x000000ff), ((GETLE32(&gpuData[11]) >> 8)
- & 0x000000ff), (GETLE32(&gpuData[8]) & 0x000000ff),
- ((GETLE32(&gpuData[8]) >> 8) & 0x000000ff),
- ((GETLE32(&gpuData[2]) >> 12) & 0x3f0), ((GETLE32(&gpuData[2])
- >> 22) & 0x01ff), GETLE32(&gpuData[0]),
- GETLE32(&gpuData[3]), GETLE32(&gpuData[6]),
- GETLE32(&gpuData[9]));
- return;
- case 2:
- drawPoly4TGD_TW(g_soft.lx0, g_soft.ly0, g_soft.lx1, g_soft.ly1,
- g_soft.lx3, g_soft.ly3, g_soft.lx2, g_soft.ly2,
- (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])
- >> 8) & 0x000000ff),
- (GETLE32(&gpuData[5]) & 0x000000ff), ((GETLE32(&gpuData[5])
- >> 8) & 0x000000ff), (GETLE32(&gpuData[11])
- & 0x000000ff), ((GETLE32(&gpuData[11]) >> 8)
- & 0x000000ff), (GETLE32(&gpuData[8]) & 0x000000ff),
- ((GETLE32(&gpuData[8]) >> 8) & 0x000000ff),
- GETLE32(&gpuData[0]), GETLE32(&gpuData[3]),
- GETLE32(&gpuData[6]), GETLE32(&gpuData[9]));
- return;
- }
-}
-
-////////////////////////////////////////////////////////////////////////
-// SPRITE FUNCS
-////////////////////////////////////////////////////////////////////////
-
-void DrawSoftwareSpriteTWin(unsigned char * baseAddr, int32_t w, int32_t h) {
- uint32_t *gpuData = (uint32_t *) baseAddr;
- short sx0, sy0, sx1, sy1, sx2, sy2, sx3, sy3;
- short tx0, ty0, tx1, ty1, tx2, ty2, tx3, ty3;
-
- sx0 = g_soft.lx0;
- sy0 = g_soft.ly0;
-
- sx0 = sx3 = sx0 + g_gpu.dsp.DrawOffset.x;
- sx1 = sx2 = sx0 + w;
- sy0 = sy1 = sy0 + g_gpu.dsp.DrawOffset.y;
- sy2 = sy3 = sy0 + h;
-
- tx0 = tx3 = GETLE32(&gpuData[2]) & 0xff;
- tx1 = tx2 = tx0 + w;
- ty0 = ty1 = (GETLE32(&gpuData[2]) >> 8) & 0xff;
- ty2 = ty3 = ty0 + h;
-
- switch (g_soft.GlobalTextTP) {
- case 0:
- drawPoly4TEx4_TW_S(sx0, sy0, sx1, sy1, sx2, sy2, sx3, sy3, tx0, ty0,
- tx1, ty1, tx2, ty2, tx3, ty3, ((GETLE32(&gpuData[2]) >> 12)
- & 0x3f0), ((GETLE32(&gpuData[2]) >> 22) & 0x01ff));
- return;
- case 1:
- drawPoly4TEx8_TW_S(sx0, sy0, sx1, sy1, sx2, sy2, sx3, sy3, tx0, ty0,
- tx1, ty1, tx2, ty2, tx3, ty3, ((GETLE32(&gpuData[2]) >> 12)
- & 0x3f0), ((GETLE32(&gpuData[2]) >> 22) & 0x01ff));
- return;
- case 2:
- drawPoly4TD_TW_S(sx0, sy0, sx1, sy1, sx2, sy2, sx3, sy3, tx0, ty0, tx1,
- ty1, tx2, ty2, tx3, ty3);
- return;
- }
-}
-
-////////////////////////////////////////////////////////////////////////
-
-void DrawSoftwareSpriteMirror(unsigned char * baseAddr, int32_t w, int32_t h) {
- int32_t sprtY, sprtX, sprtW, sprtH, lXDir, lYDir;
- int32_t clutY0, clutX0, clutP, textX0, textY0, sprtYa, sprCY, sprCX, sprA;
- short tC;
- uint32_t *gpuData = (uint32_t *) baseAddr;
- sprtY = g_soft.ly0;
- sprtX = g_soft.lx0;
- sprtH = h;
- sprtW = w;
- clutY0 = (GETLE32(&gpuData[2]) >> 22) & 0x01ff;
- clutX0 = (GETLE32(&gpuData[2]) >> 12) & 0x3f0;
- clutP = (clutY0 << 11) + (clutX0 << 1);
- textY0 = ((GETLE32(&gpuData[2]) >> 8) & 0x000000ff)
- + g_soft.GlobalTextAddrY;
- textX0 = (GETLE32(&gpuData[2]) & 0x000000ff);
-
- sprtX += g_gpu.dsp.DrawOffset.x;
- sprtY += g_gpu.dsp.DrawOffset.y;
-
- // while (sprtX>1023) sprtX-=1024;
- // while (sprtY>MAXYLINESMIN1) sprtY-=MAXYLINES;
-
- if (sprtX > g_prim.drawW) {
- // if((sprtX+sprtW)>1023) sprtX-=1024;
- // else return;
- return;
- }
-
- if (sprtY > g_prim.drawH) {
- // if ((sprtY+sprtH)>MAXYLINESMIN1) sprtY-=MAXYLINES;
- // else return;
- return;
- }
-
- if (sprtY < g_prim.drawY) {
- if ((sprtY + sprtH) < g_prim.drawY)
- return;
- sprtH -= (g_prim.drawY - sprtY);
- textY0 += (g_prim.drawY - sprtY);
- sprtY = g_prim.drawY;
- }
-
- if (sprtX < g_prim.drawX) {
- if ((sprtX + sprtW) < g_prim.drawX)
- return;
- sprtW -= (g_prim.drawX - sprtX);
- textX0 += (g_prim.drawX - sprtX);
- sprtX = g_prim.drawX;
- }
-
- if ((sprtY + sprtH) > g_prim.drawH)
- sprtH = g_prim.drawH - sprtY + 1;
- if ((sprtX + sprtW) > g_prim.drawW)
- sprtW = g_prim.drawW - sprtX + 1;
-
- if (g_prim.usMirror & 0x1000)
- lXDir = -1;
- else
- lXDir = 1;
- if (g_prim.usMirror & 0x2000)
- lYDir = -1;
- else
- lYDir = 1;
-
- switch (g_soft.GlobalTextTP) {
- case 0: // texture is 4-bit
-
- sprtW = sprtW / 2;
- textX0 = (g_soft.GlobalTextAddrX << 1) + (textX0 >> 1);
- sprtYa = (sprtY << 10);
- clutP = (clutY0 << 10) + clutX0;
- for (sprCY = 0; sprCY < sprtH; sprCY++)
- for (sprCX = 0; sprCX < sprtW; sprCX++) {
- tC = g_gpu.psx_vram.u8[((textY0 + (sprCY * lYDir)) << 11)
- + textX0 + (sprCX * lXDir)];
- sprA = sprtYa + (sprCY << 10) + sprtX + (sprCX << 1);
- GetTextureTransColG_SPR(&g_gpu.psx_vram.u16[sprA],
- GETLE16(&g_gpu.psx_vram.u16[clutP+((tC>>4)&0xf)]));
- GetTextureTransColG_SPR(&g_gpu.psx_vram.u16[sprA + 1],
- GETLE16(&g_gpu.psx_vram.u16[clutP+(tC&0xf)]));
- }
- return;
-
- case 1:
-
- clutP >>= 1;
- for (sprCY = 0; sprCY < sprtH; sprCY++)
- for (sprCX = 0; sprCX < sprtW; sprCX++) {
- tC = g_gpu.psx_vram.u8[((textY0 + (sprCY * lYDir)) << 11)
- + (g_soft.GlobalTextAddrX << 1) + textX0 + (sprCX
- * lXDir)] & 0xff;
- GetTextureTransColG_SPR(&g_gpu.psx_vram.u16[((sprtY + sprCY)
- << 10) + sprtX + sprCX], g_gpu.psx_vram.u16[clutP + tC]);
- }
- return;
-
- case 2:
-
- for (sprCY = 0; sprCY < sprtH; sprCY++)
- for (sprCX = 0; sprCX < sprtW; sprCX++) {
- GetTextureTransColG_SPR(
- &g_gpu.psx_vram.u16[((sprtY + sprCY) << 10) + sprtX
- + sprCX],
- GETLE16(&g_gpu.psx_vram.u16[((textY0+(sprCY*lYDir))<<10)+g_soft.GlobalTextAddrX + textX0 +(sprCX*lXDir)]));
- }
- return;
- }
-}
-
-////////////////////////////////////////////////////////////////////////
-
-static void DrawSoftwareSprite_IL(unsigned char * baseAddr, short w, short h,
- int32_t tx, int32_t ty) {
- int32_t sprtY, sprtX, sprtW, sprtH, tdx, tdy;
- uint32_t *gpuData = (uint32_t *) baseAddr;
-
- sprtY = g_soft.ly0;
- sprtX = g_soft.lx0;
- sprtH = h;
- sprtW = w;
-
- sprtX += g_gpu.dsp.DrawOffset.x;
- sprtY += g_gpu.dsp.DrawOffset.y;
-
- if (sprtX > g_prim.drawW)
- return;
- if (sprtY > g_prim.drawH)
- return;
-
- tdx = tx + sprtW;
- tdy = ty + sprtH;
-
- sprtW += sprtX;
- sprtH += sprtY;
-
- // Pete is too lazy to make a faster version ;)
-
- if (g_soft.GlobalTextTP == 0)
- drawPoly4TEx4_IL(sprtX, sprtY, sprtX, sprtH, sprtW, sprtH, sprtW,
- sprtY, tx, ty, tx, tdy, tdx, tdy, tdx, ty,
- (GETLE32(&gpuData[2]) >> 12) & 0x3f0, ((GETLE32(&gpuData[2])
- >> 22) & 0x01ff));
-
- else
- drawPoly4TEx8_IL(sprtX, sprtY, sprtX, sprtH, sprtW, sprtH, sprtW,
- sprtY, tx, ty, tx, tdy, tdx, tdy, tdx, ty,
- (GETLE32(&gpuData[2]) >> 12) & 0x3f0, ((GETLE32(&gpuData[2])
- >> 22) & 0x01ff));
-}
-
-////////////////////////////////////////////////////////////////////////
-
-void DrawSoftwareSprite(unsigned char * baseAddr, short w, short h, int32_t tx,
- int32_t ty) {
- int32_t sprtY, sprtX, sprtW, sprtH;
- int32_t clutY0, clutX0, clutP, textX0, textY0, sprtYa, sprCY, sprCX, sprA;
- short tC, tC2;
- uint32_t *gpuData = (uint32_t *) baseAddr;
- unsigned char * pV;
- char bWT, bWS;
-
- if (0 && g_soft.GlobalTextTP < 2) {
- DrawSoftwareSprite_IL(baseAddr, w, h, tx, ty);
- return;
- }
-
- sprtY = g_soft.ly0;
- sprtX = g_soft.lx0;
- sprtH = h;
- sprtW = w;
- clutY0 = (GETLE32(&gpuData[2]) >> 22) & 0x01ff;
- clutX0 = (GETLE32(&gpuData[2]) >> 12) & 0x3f0;
-
- clutP = (clutY0 << 11) + (clutX0 << 1);
-
- textY0 = ty + g_soft.GlobalTextAddrY;
- textX0 = tx;
-
- sprtX += g_gpu.dsp.DrawOffset.x;
- sprtY += g_gpu.dsp.DrawOffset.y;
-
- //while (sprtX>1023) sprtX-=1024;
- //while (sprtY>MAXYLINESMIN1) sprtY-=MAXYLINES;
-
- if (sprtX > g_prim.drawW) {
- // if((sprtX+sprtW)>1023) sprtX-=1024;
- // else return;
- return;
- }
-
- if (sprtY > g_prim.drawH) {
- // if ((sprtY+sprtH)>MAXYLINESMIN1) sprtY-=MAXYLINES;
- // else return;
- return;
- }
-
- if (sprtY < g_prim.drawY) {
- if ((sprtY + sprtH) < g_prim.drawY)
- return;
- sprtH -= (g_prim.drawY - sprtY);
- textY0 += (g_prim.drawY - sprtY);
- sprtY = g_prim.drawY;
- }
-
- if (sprtX < g_prim.drawX) {
- if ((sprtX + sprtW) < g_prim.drawX)
- return;
-
- sprtW -= (g_prim.drawX - sprtX);
- textX0 += (g_prim.drawX - sprtX);
- sprtX = g_prim.drawX;
- }
-
- if ((sprtY + sprtH) > g_prim.drawH)
- sprtH = g_prim.drawH - sprtY + 1;
- if ((sprtX + sprtW) > g_prim.drawW)
- sprtW = g_prim.drawW - sprtX + 1;
-
- bWT = 0;
- bWS = 0;
-
- switch (g_soft.GlobalTextTP) {
- case 0:
-
- if (textX0 & 1) {
- bWS = 1;
- sprtW--;
- }
- if (sprtW & 1)
- bWT = 1;
-
- sprtW = sprtW >> 1;
- textX0 = (g_soft.GlobalTextAddrX << 1) + (textX0 >> 1) + (textY0 << 11);
- sprtYa = (sprtY << 10) + sprtX;
- clutP = (clutY0 << 10) + clutX0;
-
-#ifdef FASTSOLID
-
- if (!g_draw.bCheckMask && !g_soft.DrawSemiTrans) {
- for (sprCY = 0; sprCY < sprtH; sprCY++) {
- sprA = sprtYa + (sprCY << 10);
- pV = &g_gpu.psx_vram.u8[(sprCY << 11) + textX0];
-
- if (bWS) {
- tC = *pV++;
- GetTextureTransColG_S(&g_gpu.psx_vram.u16[sprA++],
- GETLE16(&g_gpu.psx_vram.u16[clutP+((tC>>4)&0xf)]));
- }
-
- for (sprCX = 0; sprCX < sprtW; sprCX++, sprA += 2) {
- tC = *pV++;
-
- GetTextureTransColG32_S(
- (uint32_t *) &g_gpu.psx_vram.u16[sprA],
- (((int32_t) GETLE16(&g_gpu.psx_vram.u16[clutP+((tC>>4)&0xf)]))
- << 16)
- | GETLE16(&g_gpu.psx_vram.u16[clutP+(tC&0x0f)]));
- }
-
- if (bWT) {
- tC = *pV;
- GetTextureTransColG_S(&g_gpu.psx_vram.u16[sprA],
- GETLE16(&g_gpu.psx_vram.u16[clutP+(tC&0x0f)]));
- }
- }
- return;
- }
-
-#endif
-
- for (sprCY = 0; sprCY < sprtH; sprCY++) {
- sprA = sprtYa + (sprCY << 10);
- pV = &g_gpu.psx_vram.u8[(sprCY << 11) + textX0];
-
- if (bWS) {
- tC = *pV++;
- GetTextureTransColG_SPR(&g_gpu.psx_vram.u16[sprA++],
- GETLE16(&g_gpu.psx_vram.u16[clutP+((tC>>4)&0xf)]));
- }
-
- for (sprCX = 0; sprCX < sprtW; sprCX++, sprA += 2) {
- tC = *pV++;
-
- GetTextureTransColG32_SPR(
- (uint32_t *) &g_gpu.psx_vram.u16[sprA],
- (((int32_t) GETLE16(&g_gpu.psx_vram.u16[clutP+((tC>>4)&0xf)])
- << 16))
- | GETLE16(&g_gpu.psx_vram.u16[clutP+(tC&0x0f)]));
- }
-
- if (bWT) {
- tC = *pV;
- GetTextureTransColG_SPR(&g_gpu.psx_vram.u16[sprA],
- GETLE16(&g_gpu.psx_vram.u16[clutP+(tC&0x0f)]));
- }
- }
- return;
-
- case 1:
- clutP >>= 1;
- sprtW--;
- textX0 += (g_soft.GlobalTextAddrX << 1) + (textY0 << 11);
-
-#ifdef FASTSOLID
-
- if (!g_draw.bCheckMask && !g_soft.DrawSemiTrans) {
- for (sprCY = 0; sprCY < sprtH; sprCY++) {
- sprA = ((sprtY + sprCY) << 10) + sprtX;
- pV = &g_gpu.psx_vram.u8[(sprCY << 11) + textX0];
- for (sprCX = 0; sprCX < sprtW; sprCX += 2, sprA += 2) {
- tC = *pV++;
- tC2 = *pV++;
- GetTextureTransColG32_S(
- (uint32_t *) &g_gpu.psx_vram.u16[sprA],
- (((int32_t) GETLE16(&g_gpu.psx_vram.u16[clutP+tC2]))
- << 16)
- | GETLE16(&g_gpu.psx_vram.u16[clutP+tC]));
- }
- if (sprCX == sprtW)
- GetTextureTransColG_S(&g_gpu.psx_vram.u16[sprA],
- GETLE16(&g_gpu.psx_vram.u16[clutP+(*pV)]));
- }
- return;
- }
-
-#endif
-
- for (sprCY = 0; sprCY < sprtH; sprCY++) {
- sprA = ((sprtY + sprCY) << 10) + sprtX;
- pV = &g_gpu.psx_vram.u8[(sprCY << 11) + textX0];
- for (sprCX = 0; sprCX < sprtW; sprCX += 2, sprA += 2) {
- tC = *pV++;
- tC2 = *pV++;
- GetTextureTransColG32_SPR(
- (uint32_t *) &g_gpu.psx_vram.u16[sprA],
- (((int32_t) GETLE16(&g_gpu.psx_vram.u16[clutP+tC2]))
- << 16) | GETLE16(&g_gpu.psx_vram.u16[clutP+tC]));
- }
- if (sprCX == sprtW)
- GetTextureTransColG_SPR(&g_gpu.psx_vram.u16[sprA],
- GETLE16(&g_gpu.psx_vram.u16[clutP+(*pV)]));
- }
- return;
-
- case 2:
-
- textX0 += (g_soft.GlobalTextAddrX) + (textY0 << 10);
- sprtW--;
-
-#ifdef FASTSOLID
-
- if (!g_draw.bCheckMask && !g_soft.DrawSemiTrans) {
- for (sprCY = 0; sprCY < sprtH; sprCY++) {
- sprA = ((sprtY + sprCY) << 10) + sprtX;
-
- for (sprCX = 0; sprCX < sprtW; sprCX += 2, sprA += 2) {
- GetTextureTransColG32_S(
- (uint32_t *) &g_gpu.psx_vram.u16[sprA],
- (((int32_t) GETLE16(&g_gpu.psx_vram.u16[(sprCY<<10) + textX0 + sprCX +1]))
- << 16)
- | GETLE16(&g_gpu.psx_vram.u16[(sprCY<<10) + textX0 + sprCX]));
- }
- if (sprCX == sprtW)
- GetTextureTransColG_S(
- &g_gpu.psx_vram.u16[sprA],
- GETLE16(&g_gpu.psx_vram.u16[(sprCY<<10) + textX0 + sprCX]));
-
- }
- return;
- }
-
-#endif
-
- for (sprCY = 0; sprCY < sprtH; sprCY++) {
- sprA = ((sprtY + sprCY) << 10) + sprtX;
-
- for (sprCX = 0; sprCX < sprtW; sprCX += 2, sprA += 2) {
- GetTextureTransColG32_SPR(
- (uint32_t *) &g_gpu.psx_vram.u16[sprA],
- (((int32_t) GETLE16(&g_gpu.psx_vram.u16[(sprCY<<10) + textX0 + sprCX +1]))
- << 16)
- | GETLE16(&g_gpu.psx_vram.u16[(sprCY<<10) + textX0 + sprCX]));
- }
- if (sprCX == sprtW)
- GetTextureTransColG_SPR(
- &g_gpu.psx_vram.u16[sprA],
- GETLE16(&g_gpu.psx_vram.u16[(sprCY<<10) + textX0 + sprCX]));
-
- }
- return;
- }
-}
-
-///////////////////////////////////////////////////////////////////////
-
-/////////////////////////////////////////////////////////////////
-/////////////////////////////////////////////////////////////////
-/////////////////////////////////////////////////////////////////
-// LINE FUNCS
-////////////////////////////////////////////////////////////////////////
-/////////////////////////////////////////////////////////////////
-/////////////////////////////////////////////////////////////////
-
-
-///////////////////////////////////////////////////////////////////////
-
-static void Line_E_SE_Shade(int x0, int y0, int x1, int y1, uint32_t rgb0,
- uint32_t rgb1) {
- int dx, dy, incrE, incrSE, d;
- uint32_t r0, g0, b0, r1, g1, b1;
- int32_t dr, dg, db;
-
- r0 = (rgb0 & 0x00ff0000);
- g0 = (rgb0 & 0x0000ff00) << 8;
- b0 = (rgb0 & 0x000000ff) << 16;
- r1 = (rgb1 & 0x00ff0000);
- g1 = (rgb1 & 0x0000ff00) << 8;
- b1 = (rgb1 & 0x000000ff) << 16;
-
- dx = x1 - x0;
- dy = y1 - y0;
-
- if (dx > 0) {
- dr = ((int32_t) r1 - (int32_t) r0) / dx;
- dg = ((int32_t) g1 - (int32_t) g0) / dx;
- db = ((int32_t) b1 - (int32_t) b0) / dx;
- } else {
- dr = ((int32_t) r1 - (int32_t) r0);
- dg = ((int32_t) g1 - (int32_t) g0);
- db = ((int32_t) b1 - (int32_t) b0);
- }
-
- d = 2 * dy - dx; /* Initial value of d */
- incrE = 2 * dy; /* incr. used for move to E */
- incrSE = 2 * (dy - dx); /* incr. used for move to SE */
-
- if ((x0 >= g_prim.drawX) && (x0 < g_prim.drawW) && (y0 >= g_prim.drawY)
- && (y0 < g_prim.drawH))
- GetShadeTransCol(&g_gpu.psx_vram.u16[(y0 << 10) + x0],
- (unsigned short) (((r0 >> 9) & 0x7c00) | ((g0 >> 14) & 0x03e0)
- | ((b0 >> 19) & 0x001f)));
- while (x0 < x1) {
- if (d <= 0) {
- d = d + incrE; /* Choose E */
- } else {
- d = d + incrSE; /* Choose SE */
- y0++;
- }
- x0++;
-
- r0 += dr;
- g0 += dg;
- b0 += db;
-
- if ((x0 >= g_prim.drawX) && (x0 < g_prim.drawW) && (y0 >= g_prim.drawY)
- && (y0 < g_prim.drawH))
- GetShadeTransCol(&g_gpu.psx_vram.u16[(y0 << 10) + x0],
- (unsigned short) (((r0 >> 9) & 0x7c00) | ((g0 >> 14)
- & 0x03e0) | ((b0 >> 19) & 0x001f)));
- }
-}
-
-///////////////////////////////////////////////////////////////////////
-
-static void Line_S_SE_Shade(int x0, int y0, int x1, int y1, uint32_t rgb0,
- uint32_t rgb1) {
- int dx, dy, incrS, incrSE, d;
- uint32_t r0, g0, b0, r1, g1, b1;
- int32_t dr, dg, db;
-
- r0 = (rgb0 & 0x00ff0000);
- g0 = (rgb0 & 0x0000ff00) << 8;
- b0 = (rgb0 & 0x000000ff) << 16;
- r1 = (rgb1 & 0x00ff0000);
- g1 = (rgb1 & 0x0000ff00) << 8;
- b1 = (rgb1 & 0x000000ff) << 16;
-
- dx = x1 - x0;
- dy = y1 - y0;
-
- if (dy > 0) {
- dr = ((int32_t) r1 - (int32_t) r0) / dy;
- dg = ((int32_t) g1 - (int32_t) g0) / dy;
- db = ((int32_t) b1 - (int32_t) b0) / dy;
- } else {
- dr = ((int32_t) r1 - (int32_t) r0);
- dg = ((int32_t) g1 - (int32_t) g0);
- db = ((int32_t) b1 - (int32_t) b0);
- }
-
- d = 2 * dx - dy; /* Initial value of d */
- incrS = 2 * dx; /* incr. used for move to S */
- incrSE = 2 * (dx - dy); /* incr. used for move to SE */
-
- if ((x0 >= g_prim.drawX) && (x0 < g_prim.drawW) && (y0 >= g_prim.drawY)
- && (y0 < g_prim.drawH))
- GetShadeTransCol(&g_gpu.psx_vram.u16[(y0 << 10) + x0],
- (unsigned short) (((r0 >> 9) & 0x7c00) | ((g0 >> 14) & 0x03e0)
- | ((b0 >> 19) & 0x001f)));
- while (y0 < y1) {
- if (d <= 0) {
- d = d + incrS; /* Choose S */
- } else {
- d = d + incrSE; /* Choose SE */
- x0++;
- }
- y0++;
-
- r0 += dr;
- g0 += dg;
- b0 += db;
-
- if ((x0 >= g_prim.drawX) && (x0 < g_prim.drawW) && (y0 >= g_prim.drawY)
- && (y0 < g_prim.drawH))
- GetShadeTransCol(&g_gpu.psx_vram.u16[(y0 << 10) + x0],
- (unsigned short) (((r0 >> 9) & 0x7c00) | ((g0 >> 14)
- & 0x03e0) | ((b0 >> 19) & 0x001f)));
- }
-}
-
-///////////////////////////////////////////////////////////////////////
-
-static void Line_N_NE_Shade(int x0, int y0, int x1, int y1, uint32_t rgb0,
- uint32_t rgb1) {
- int dx, dy, incrN, incrNE, d;
- uint32_t r0, g0, b0, r1, g1, b1;
- int32_t dr, dg, db;
-
- r0 = (rgb0 & 0x00ff0000);
- g0 = (rgb0 & 0x0000ff00) << 8;
- b0 = (rgb0 & 0x000000ff) << 16;
- r1 = (rgb1 & 0x00ff0000);
- g1 = (rgb1 & 0x0000ff00) << 8;
- b1 = (rgb1 & 0x000000ff) << 16;
-
- dx = x1 - x0;
- dy = -(y1 - y0);
-
- if (dy > 0) {
- dr = ((int32_t) r1 - (int32_t) r0) / dy;
- dg = ((int32_t) g1 - (int32_t) g0) / dy;
- db = ((int32_t) b1 - (int32_t) b0) / dy;
- } else {
- dr = ((int32_t) r1 - (int32_t) r0);
- dg = ((int32_t) g1 - (int32_t) g0);
- db = ((int32_t) b1 - (int32_t) b0);
- }
-
- d = 2 * dx - dy; /* Initial value of d */
- incrN = 2 * dx; /* incr. used for move to N */
- incrNE = 2 * (dx - dy); /* incr. used for move to NE */
-
- if ((x0 >= g_prim.drawX) && (x0 < g_prim.drawW) && (y0 >= g_prim.drawY)
- && (y0 < g_prim.drawH))
- GetShadeTransCol(&g_gpu.psx_vram.u16[(y0 << 10) + x0],
- (unsigned short) (((r0 >> 9) & 0x7c00) | ((g0 >> 14) & 0x03e0)
- | ((b0 >> 19) & 0x001f)));
- while (y0 > y1) {
- if (d <= 0) {
- d = d + incrN; /* Choose N */
- } else {
- d = d + incrNE; /* Choose NE */
- x0++;
- }
- y0--;
-
- r0 += dr;
- g0 += dg;
- b0 += db;
-
- if ((x0 >= g_prim.drawX) && (x0 < g_prim.drawW) && (y0 >= g_prim.drawY)
- && (y0 < g_prim.drawH))
- GetShadeTransCol(&g_gpu.psx_vram.u16[(y0 << 10) + x0],
- (unsigned short) (((r0 >> 9) & 0x7c00) | ((g0 >> 14)
- & 0x03e0) | ((b0 >> 19) & 0x001f)));
- }
-}
-
-///////////////////////////////////////////////////////////////////////
-
-static void Line_E_NE_Shade(int x0, int y0, int x1, int y1, uint32_t rgb0,
- uint32_t rgb1) {
- int dx, dy, incrE, incrNE, d;
- uint32_t r0, g0, b0, r1, g1, b1;
- int32_t dr, dg, db;
-
- r0 = (rgb0 & 0x00ff0000);
- g0 = (rgb0 & 0x0000ff00) << 8;
- b0 = (rgb0 & 0x000000ff) << 16;
- r1 = (rgb1 & 0x00ff0000);
- g1 = (rgb1 & 0x0000ff00) << 8;
- b1 = (rgb1 & 0x000000ff) << 16;
-
- dx = x1 - x0;
- dy = -(y1 - y0);
-
- if (dx > 0) {
- dr = ((int32_t) r1 - (int32_t) r0) / dx;
- dg = ((int32_t) g1 - (int32_t) g0) / dx;
- db = ((int32_t) b1 - (int32_t) b0) / dx;
- } else {
- dr = ((int32_t) r1 - (int32_t) r0);
- dg = ((int32_t) g1 - (int32_t) g0);
- db = ((int32_t) b1 - (int32_t) b0);
- }
-
- d = 2 * dy - dx; /* Initial value of d */
- incrE = 2 * dy; /* incr. used for move to E */
- incrNE = 2 * (dy - dx); /* incr. used for move to NE */
-
- if ((x0 >= g_prim.drawX) && (x0 < g_prim.drawW) && (y0 >= g_prim.drawY)
- && (y0 < g_prim.drawH))
- GetShadeTransCol(&g_gpu.psx_vram.u16[(y0 << 10) + x0],
- (unsigned short) (((r0 >> 9) & 0x7c00) | ((g0 >> 14) & 0x03e0)
- | ((b0 >> 19) & 0x001f)));
- while (x0 < x1) {
- if (d <= 0) {
- d = d + incrE; /* Choose E */
- } else {
- d = d + incrNE; /* Choose NE */
- y0--;
- }
- x0++;
-
- r0 += dr;
- g0 += dg;
- b0 += db;
-
- if ((x0 >= g_prim.drawX) && (x0 < g_prim.drawW) && (y0 >= g_prim.drawY)
- && (y0 < g_prim.drawH))
- GetShadeTransCol(&g_gpu.psx_vram.u16[(y0 << 10) + x0],
- (unsigned short) (((r0 >> 9) & 0x7c00) | ((g0 >> 14)
- & 0x03e0) | ((b0 >> 19) & 0x001f)));
- }
-}
-
-///////////////////////////////////////////////////////////////////////
-
-static void VertLineShade(int x, int y0, int y1, uint32_t rgb0, uint32_t rgb1) {
- int y, dy;
- uint32_t r0, g0, b0, r1, g1, b1;
- int32_t dr, dg, db;
-
- r0 = (rgb0 & 0x00ff0000);
- g0 = (rgb0 & 0x0000ff00) << 8;
- b0 = (rgb0 & 0x000000ff) << 16;
- r1 = (rgb1 & 0x00ff0000);
- g1 = (rgb1 & 0x0000ff00) << 8;
- b1 = (rgb1 & 0x000000ff) << 16;
-
- dy = (y1 - y0);
-
- if (dy > 0) {
- dr = ((int32_t) r1 - (int32_t) r0) / dy;
- dg = ((int32_t) g1 - (int32_t) g0) / dy;
- db = ((int32_t) b1 - (int32_t) b0) / dy;
- } else {
- dr = ((int32_t) r1 - (int32_t) r0);
- dg = ((int32_t) g1 - (int32_t) g0);
- db = ((int32_t) b1 - (int32_t) b0);
- }
-
- if (y0 < g_prim.drawY) {
- r0 += dr * (g_prim.drawY - y0);
- g0 += dg * (g_prim.drawY - y0);
- b0 += db * (g_prim.drawY - y0);
- y0 = g_prim.drawY;
- }
-
- if (y1 > g_prim.drawH)
- y1 = g_prim.drawH;
-
- for (y = y0; y <= y1; y++) {
- GetShadeTransCol(&g_gpu.psx_vram.u16[(y << 10) + x],
- (unsigned short) (((r0 >> 9) & 0x7c00) | ((g0 >> 14) & 0x03e0)
- | ((b0 >> 19) & 0x001f)));
- r0 += dr;
- g0 += dg;
- b0 += db;
- }
-}
-
-///////////////////////////////////////////////////////////////////////
-
-static void HorzLineShade(int y, int x0, int x1, uint32_t rgb0, uint32_t rgb1) {
- int x, dx;
- uint32_t r0, g0, b0, r1, g1, b1;
- int32_t dr, dg, db;
-
- r0 = (rgb0 & 0x00ff0000);
- g0 = (rgb0 & 0x0000ff00) << 8;
- b0 = (rgb0 & 0x000000ff) << 16;
- r1 = (rgb1 & 0x00ff0000);
- g1 = (rgb1 & 0x0000ff00) << 8;
- b1 = (rgb1 & 0x000000ff) << 16;
-
- dx = (x1 - x0);
-
- if (dx > 0) {
- dr = ((int32_t) r1 - (int32_t) r0) / dx;
- dg = ((int32_t) g1 - (int32_t) g0) / dx;
- db = ((int32_t) b1 - (int32_t) b0) / dx;
- } else {
- dr = ((int32_t) r1 - (int32_t) r0);
- dg = ((int32_t) g1 - (int32_t) g0);
- db = ((int32_t) b1 - (int32_t) b0);
- }
-
- if (x0 < g_prim.drawX) {
- r0 += dr * (g_prim.drawX - x0);
- g0 += dg * (g_prim.drawX - x0);
- b0 += db * (g_prim.drawX - x0);
- x0 = g_prim.drawX;
- }
-
- if (x1 > g_prim.drawW)
- x1 = g_prim.drawW;
-
- for (x = x0; x <= x1; x++) {
- GetShadeTransCol(&g_gpu.psx_vram.u16[(y << 10) + x],
- (unsigned short) (((r0 >> 9) & 0x7c00) | ((g0 >> 14) & 0x03e0)
- | ((b0 >> 19) & 0x001f)));
- r0 += dr;
- g0 += dg;
- b0 += db;
- }
-}
-
-///////////////////////////////////////////////////////////////////////
-
-static void Line_E_SE_Flat(int x0, int y0, int x1, int y1, unsigned short colour) {
- int dx, dy, incrE, incrSE, d, x, y;
-
- dx = x1 - x0;
- dy = y1 - y0;
- d = 2 * dy - dx; /* Initial value of d */
- incrE = 2 * dy; /* incr. used for move to E */
- incrSE = 2 * (dy - dx); /* incr. used for move to SE */
- x = x0;
- y = y0;
- if ((x >= g_prim.drawX) && (x < g_prim.drawW) && (y >= g_prim.drawY) && (y
- < g_prim.drawH))
- GetShadeTransCol(&g_gpu.psx_vram.u16[(y << 10) + x], colour);
- while (x < x1) {
- if (d <= 0) {
- d = d + incrE; /* Choose E */
- x++;
- } else {
- d = d + incrSE; /* Choose SE */
- x++;
- y++;
- }
- if ((x >= g_prim.drawX) && (x < g_prim.drawW) && (y >= g_prim.drawY)
- && (y < g_prim.drawH))
- GetShadeTransCol(&g_gpu.psx_vram.u16[(y << 10) + x], colour);
- }
-}
-
-///////////////////////////////////////////////////////////////////////
-
-static void Line_S_SE_Flat(int x0, int y0, int x1, int y1, unsigned short colour) {
- int dx, dy, incrS, incrSE, d, x, y;
-
- dx = x1 - x0;
- dy = y1 - y0;
- d = 2 * dx - dy; /* Initial value of d */
- incrS = 2 * dx; /* incr. used for move to S */
- incrSE = 2 * (dx - dy); /* incr. used for move to SE */
- x = x0;
- y = y0;
- if ((x >= g_prim.drawX) && (x < g_prim.drawW) && (y >= g_prim.drawY) && (y
- < g_prim.drawH))
- GetShadeTransCol(&g_gpu.psx_vram.u16[(y << 10) + x], colour);
- while (y < y1) {
- if (d <= 0) {
- d = d + incrS; /* Choose S */
- y++;
- } else {
- d = d + incrSE; /* Choose SE */
- x++;
- y++;
- }
- if ((x >= g_prim.drawX) && (x < g_prim.drawW) && (y >= g_prim.drawY)
- && (y < g_prim.drawH))
- GetShadeTransCol(&g_gpu.psx_vram.u16[(y << 10) + x], colour);
- }
-}
-
-///////////////////////////////////////////////////////////////////////
-
-static void Line_N_NE_Flat(int x0, int y0, int x1, int y1, unsigned short colour) {
- int dx, dy, incrN, incrNE, d, x, y;
-
- dx = x1 - x0;
- dy = -(y1 - y0);
- d = 2 * dx - dy; /* Initial value of d */
- incrN = 2 * dx; /* incr. used for move to N */
- incrNE = 2 * (dx - dy); /* incr. used for move to NE */
- x = x0;
- y = y0;
- if ((x >= g_prim.drawX) && (x < g_prim.drawW) && (y >= g_prim.drawY) && (y
- < g_prim.drawH))
- GetShadeTransCol(&g_gpu.psx_vram.u16[(y << 10) + x], colour);
- while (y > y1) {
- if (d <= 0) {
- d = d + incrN; /* Choose N */
- y--;
- } else {
- d = d + incrNE; /* Choose NE */
- x++;
- y--;
- }
- if ((x >= g_prim.drawX) && (x < g_prim.drawW) && (y >= g_prim.drawY)
- && (y < g_prim.drawH))
- GetShadeTransCol(&g_gpu.psx_vram.u16[(y << 10) + x], colour);
- }
-}
-
-///////////////////////////////////////////////////////////////////////
-
-static void Line_E_NE_Flat(int x0, int y0, int x1, int y1, unsigned short colour) {
- int dx, dy, incrE, incrNE, d, x, y;
-
- dx = x1 - x0;
- dy = -(y1 - y0);
- d = 2 * dy - dx; /* Initial value of d */
- incrE = 2 * dy; /* incr. used for move to E */
- incrNE = 2 * (dy - dx); /* incr. used for move to NE */
- x = x0;
- y = y0;
- if ((x >= g_prim.drawX) && (x < g_prim.drawW) && (y >= g_prim.drawY) && (y
- < g_prim.drawH))
- GetShadeTransCol(&g_gpu.psx_vram.u16[(y << 10) + x], colour);
- while (x < x1) {
- if (d <= 0) {
- d = d + incrE; /* Choose E */
- x++;
- } else {
- d = d + incrNE; /* Choose NE */
- x++;
- y--;
- }
- if ((x >= g_prim.drawX) && (x < g_prim.drawW) && (y >= g_prim.drawY)
- && (y < g_prim.drawH))
- GetShadeTransCol(&g_gpu.psx_vram.u16[(y << 10) + x], colour);
- }
-}
-
-///////////////////////////////////////////////////////////////////////
-
-static void VertLineFlat(int x, int y0, int y1, unsigned short colour) {
- int y;
-
- if (y0 < g_prim.drawY)
- y0 = g_prim.drawY;
-
- if (y1 > g_prim.drawH)
- y1 = g_prim.drawH;
-
- for (y = y0; y <= y1; y++)
- GetShadeTransCol(&g_gpu.psx_vram.u16[(y << 10) + x], colour);
-}
-
-///////////////////////////////////////////////////////////////////////
-
-static void HorzLineFlat(int y, int x0, int x1, unsigned short colour) {
- int x;
-
- if (x0 < g_prim.drawX)
- x0 = g_prim.drawX;
-
- if (x1 > g_prim.drawW)
- x1 = g_prim.drawW;
-
- for (x = x0; x <= x1; x++)
- GetShadeTransCol(&g_gpu.psx_vram.u16[(y << 10) + x], colour);
-}
-
-///////////////////////////////////////////////////////////////////////
-
-/* Bresenham Line drawing function */
-void DrawSoftwareLineShade(int32_t rgb0, int32_t rgb1) {
- short x0, y0, x1, y1, xt, yt;
- int32_t rgbt;
- double m, dy, dx;
-
- if (g_soft.lx0 > g_prim.drawW && g_soft.lx1 > g_prim.drawW)
- return;
- if (g_soft.ly0 > g_prim.drawH && g_soft.ly1 > g_prim.drawH)
- return;
- if (g_soft.lx0 < g_prim.drawX && g_soft.lx1 < g_prim.drawX)
- return;
- if (g_soft.ly0 < g_prim.drawY && g_soft.ly1 < g_prim.drawY)
- return;
- if (g_prim.drawY >= g_prim.drawH)
- return;
- if (g_prim.drawX >= g_prim.drawW)
- return;
-
- x0 = g_soft.lx0;
- y0 = g_soft.ly0;
- x1 = g_soft.lx1;
- y1 = g_soft.ly1;
-
- dx = x1 - x0;
- dy = y1 - y0;
-
- if (dx == 0) {
- if (dy > 0)
- VertLineShade(x0, y0, y1, rgb0, rgb1);
- else
- VertLineShade(x0, y1, y0, rgb1, rgb0);
- } else if (dy == 0) {
- if (dx > 0)
- HorzLineShade(y0, x0, x1, rgb0, rgb1);
- else
- HorzLineShade(y0, x1, x0, rgb1, rgb0);
- } else {
- if (dx < 0) {
- xt = x0;
- yt = y0;
- rgbt = rgb0;
- x0 = x1;
- y0 = y1;
- rgb0 = rgb1;
- x1 = xt;
- y1 = yt;
- rgb1 = rgbt;
-
- dx = x1 - x0;
- dy = y1 - y0;
- }
-
- m = dy / dx;
-
- if (m >= 0) {
- if (m > 1)
- Line_S_SE_Shade(x0, y0, x1, y1, rgb0, rgb1);
- else
- Line_E_SE_Shade(x0, y0, x1, y1, rgb0, rgb1);
- } else if (m < -1)
- Line_N_NE_Shade(x0, y0, x1, y1, rgb0, rgb1);
- else
- Line_E_NE_Shade(x0, y0, x1, y1, rgb0, rgb1);
- }
-}
-
-///////////////////////////////////////////////////////////////////////
-
-void DrawSoftwareLineFlat(int32_t rgb) {
- short x0, y0, x1, y1, xt, yt;
- double m, dy, dx;
- unsigned short colour = 0;
-
- if (g_soft.lx0 > g_prim.drawW && g_soft.lx1 > g_prim.drawW)
- return;
- if (g_soft.ly0 > g_prim.drawH && g_soft.ly1 > g_prim.drawH)
- return;
- if (g_soft.lx0 < g_prim.drawX && g_soft.lx1 < g_prim.drawX)
- return;
- if (g_soft.ly0 < g_prim.drawY && g_soft.ly1 < g_prim.drawY)
- return;
- if (g_prim.drawY >= g_prim.drawH)
- return;
- if (g_prim.drawX >= g_prim.drawW)
- return;
-
- colour = ((rgb & 0x00f80000) >> 9) | ((rgb & 0x0000f800) >> 6) | ((rgb
- & 0x000000f8) >> 3);
-
- x0 = g_soft.lx0;
- y0 = g_soft.ly0;
- x1 = g_soft.lx1;
- y1 = g_soft.ly1;
-
- dx = x1 - x0;
- dy = y1 - y0;
-
- if (dx == 0) {
- if (dy == 0)
- return; // Nothing to draw
- else if (dy > 0)
- VertLineFlat(x0, y0, y1, colour);
- else
- VertLineFlat(x0, y1, y0, colour);
- } else if (dy == 0) {
- if (dx > 0)
- HorzLineFlat(y0, x0, x1, colour);
- else
- HorzLineFlat(y0, x1, x0, colour);
- } else {
- if (dx < 0) {
- xt = x0;
- yt = y0;
- x0 = x1;
- y0 = y1;
- x1 = xt;
- y1 = yt;
-
- dx = x1 - x0;
- dy = y1 - y0;
- }
-
- m = dy / dx;
-
- if (m >= 0) {
- if (m > 1)
- Line_S_SE_Flat(x0, y0, x1, y1, colour);
- else
- Line_E_SE_Flat(x0, y0, x1, y1, colour);
- } else if (m < -1)
- Line_N_NE_Flat(x0, y0, x1, y1, colour);
- else
- Line_E_NE_Flat(x0, y0, x1, y1, colour);
- }
-}
-
-///////////////////////////////////////////////////////////////////////
+/***************************************************************************
+ soft.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 "globals.h"
+#include "soft.h"
+#include "swap.h"
+
+#define MIN(a,b) ((a) > (b) ? (b) : (a))
+#define MAX(a,b) ((a) < (b) ? (b) : (a))
+
+#define LOWORD(l) ((unsigned short)(l))
+#define HIWORD(l) ((unsigned short)(((uint32_t)(l) >> 16) & 0xFFFF))
+
+////////////////////////////////////////////////////////////////////////////////////
+// "NO EDGE BUFFER" POLY VERSION... FUNCS BASED ON FATMAP.TXT FROM MRI / Doomsday
+////////////////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////////////////
+// defines
+////////////////////////////////////////////////////////////////////////////////////
+
+// switches for painting textured quads as 2 triangles (small glitches, but better shading!)
+// can be toggled by game fix 0x200 in version 1.17 anyway, so let the defines enabled!
+
+#define POLYQUAD3
+#define POLYQUAD3GT
+
+// fast solid loops... a bit more additional code, of course
+
+#define FASTSOLID
+
+// psx blending mode 3 with 25% incoming color (instead 50% without the define)
+
+#define HALFBRIGHTMODE3
+
+// color decode defines
+
+#define XCOL1(x) (x & 0x1f)
+#define XCOL2(x) (x & 0x3e0)
+#define XCOL3(x) (x & 0x7c00)
+
+#define XCOL1D(x) (x & 0x1f)
+#define XCOL2D(x) ((x>>5) & 0x1f)
+#define XCOL3D(x) ((x>>10) & 0x1f)
+
+#define X32TCOL1(x) ((x & 0x001f001f)<<7)
+#define X32TCOL2(x) ((x & 0x03e003e0)<<2)
+#define X32TCOL3(x) ((x & 0x7c007c00)>>3)
+
+#define X32COL1(x) (x & 0x001f001f)
+#define X32COL2(x) ((x>>5) & 0x001f001f)
+#define X32COL3(x) ((x>>10) & 0x001f001f)
+
+#define X32ACOL1(x) (x & 0x001e001e)
+#define X32ACOL2(x) ((x>>5) & 0x001e001e)
+#define X32ACOL3(x) ((x>>10) & 0x001e001e)
+
+#define X32BCOL1(x) (x & 0x001c001c)
+#define X32BCOL2(x) ((x>>5) & 0x001c001c)
+#define X32BCOL3(x) ((x>>10) & 0x001c001c)
+
+#define X32PSXCOL(r,g,b) ((g<<10)|(b<<5)|r)
+
+#define XPSXCOL(r,g,b) ((g&0x7c00)|(b&0x3e0)|(r&0x1f))
+
+////////////////////////////////////////////////////////////////////////////////////
+// soft globals
+////////////////////////////////////////////////////////////////////////////////////
+
+
+////////////////////////////////////////////////////////////////////////
+// POLYGON OFFSET FUNCS
+////////////////////////////////////////////////////////////////////////
+
+void offsetPSXLine(void) {
+ short x0, x1, y0, y1, dx, dy;
+ float px, py;
+
+ x0 = g_soft.lx0 + 1 + g_gpu.dsp.DrawOffset.x;
+ x1 = g_soft.lx1 + 1 + g_gpu.dsp.DrawOffset.x;
+ y0 = g_soft.ly0 + 1 + g_gpu.dsp.DrawOffset.y;
+ y1 = g_soft.ly1 + 1 + g_gpu.dsp.DrawOffset.y;
+
+ dx = x1 - x0;
+ dy = y1 - y0;
+
+ // tricky line width without sqrt
+
+ if (dx >= 0) {
+ if (dy >= 0) {
+ px = 0.5f;
+ if (dx > dy)
+ py = -0.5f;
+ else if (dx < dy)
+ py = 0.5f;
+ else
+ py = 0.0f;
+ } else {
+ py = -0.5f;
+ dy = -dy;
+ if (dx > dy)
+ px = 0.5f;
+ else if (dx < dy)
+ px = -0.5f;
+ else
+ px = 0.0f;
+ }
+ } else {
+ if (dy >= 0) {
+ py = 0.5f;
+ dx = -dx;
+ if (dx > dy)
+ px = -0.5f;
+ else if (dx < dy)
+ px = 0.5f;
+ else
+ px = 0.0f;
+ } else {
+ px = -0.5f;
+ if (dx > dy)
+ py = -0.5f;
+ else if (dx < dy)
+ py = 0.5f;
+ else
+ py = 0.0f;
+ }
+ }
+
+ g_soft.lx0 = (short) ((float) x0 - px);
+ g_soft.lx3 = (short) ((float) x0 + py);
+
+ g_soft.ly0 = (short) ((float) y0 - py);
+ g_soft.ly3 = (short) ((float) y0 - px);
+
+ g_soft.lx1 = (short) ((float) x1 - py);
+ g_soft.lx2 = (short) ((float) x1 + px);
+
+ g_soft.ly1 = (short) ((float) y1 + px);
+ g_soft.ly2 = (short) ((float) y1 + py);
+}
+
+void offsetPSX2(void) {
+ g_soft.lx0 += g_gpu.dsp.DrawOffset.x;
+ g_soft.ly0 += g_gpu.dsp.DrawOffset.y;
+ g_soft.lx1 += g_gpu.dsp.DrawOffset.x;
+ g_soft.ly1 += g_gpu.dsp.DrawOffset.y;
+}
+
+void offsetPSX3(void) {
+ g_soft.lx0 += g_gpu.dsp.DrawOffset.x;
+ g_soft.ly0 += g_gpu.dsp.DrawOffset.y;
+ g_soft.lx1 += g_gpu.dsp.DrawOffset.x;
+ g_soft.ly1 += g_gpu.dsp.DrawOffset.y;
+ g_soft.lx2 += g_gpu.dsp.DrawOffset.x;
+ g_soft.ly2 += g_gpu.dsp.DrawOffset.y;
+}
+
+void offsetPSX4(void) {
+ g_soft.lx0 += g_gpu.dsp.DrawOffset.x;
+ g_soft.ly0 += g_gpu.dsp.DrawOffset.y;
+ g_soft.lx1 += g_gpu.dsp.DrawOffset.x;
+ g_soft.ly1 += g_gpu.dsp.DrawOffset.y;
+ g_soft.lx2 += g_gpu.dsp.DrawOffset.x;
+ g_soft.ly2 += g_gpu.dsp.DrawOffset.y;
+ g_soft.lx3 += g_gpu.dsp.DrawOffset.x;
+ g_soft.ly3 += g_gpu.dsp.DrawOffset.y;
+}
+
+/////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////
+// PER PIXEL FUNCS
+////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////
+
+
+uint8_t const dithertable[16] = { 7, 0, 6, 1, 2, 5, 3, 4, 1, 6, 0, 7, 4, 3, 5,
+ 2 };
+
+void Dither16(uint16_t * pdest, uint32_t r, uint32_t g, uint32_t b, uint16_t sM) {
+ uint8_t coeff;
+ uint8_t rlow, glow, blow;
+ int x, y;
+
+ x = pdest - g_gpu.psx_vram.u16;
+ y = x >> 10;
+ x -= (y << 10);
+
+ coeff = dithertable[(y & 3) * 4 + (x & 3)];
+
+ rlow = r & 7;
+ glow = g & 7;
+ blow = b & 7;
+
+ r >>= 3;
+ g >>= 3;
+ b >>= 3;
+
+ if ((r < 0x1F) && rlow > coeff)
+ r++;
+ if ((g < 0x1F) && glow > coeff)
+ g++;
+ if ((b < 0x1F) && blow > coeff)
+ b++;
+
+ PUTLE16(pdest, (b<<10) | (g<<5) | r | sM);
+}
+
+/////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////
+
+inline void GetShadeTransCol_Dither(uint16_t * pdest, int32_t m1,
+ int32_t m2, int32_t m3) {
+ int32_t r, g, b;
+
+ if (g_draw.bCheckMask && (*pdest & HOST2LE16(0x8000)))
+ return;
+
+ if (g_soft.DrawSemiTrans) {
+ r = ((XCOL1D(GETLE16(pdest))) << 3);
+ b = ((XCOL2D(GETLE16(pdest))) << 3);
+ g = ((XCOL3D(GETLE16(pdest))) << 3);
+
+ if (g_soft.GlobalTextABR == 0) {
+ r = (r >> 1) + (m1 >> 1);
+ b = (b >> 1) + (m2 >> 1);
+ g = (g >> 1) + (m3 >> 1);
+ } else if (g_soft.GlobalTextABR == 1) {
+ r += m1;
+ b += m2;
+ g += m3;
+ } else if (g_soft.GlobalTextABR == 2) {
+ r -= m1;
+ b -= m2;
+ g -= m3;
+ if (r & 0x80000000)
+ r = 0;
+ if (b & 0x80000000)
+ b = 0;
+ if (g & 0x80000000)
+ g = 0;
+ } else {
+#ifdef HALFBRIGHTMODE3
+ r += (m1 >> 2);
+ b += (m2 >> 2);
+ g += (m3 >> 2);
+#else
+ r+=(m1>>1);
+ b+=(m2>>1);
+ g+=(m3>>1);
+#endif
+ }
+ } else {
+ r = m1;
+ b = m2;
+ g = m3;
+ }
+
+ if (r & 0x7FFFFF00)
+ r = 0xff;
+ if (b & 0x7FFFFF00)
+ b = 0xff;
+ if (g & 0x7FFFFF00)
+ g = 0xff;
+
+ Dither16(pdest, r, b, g, g_draw.sSetMask);
+}
+
+////////////////////////////////////////////////////////////////////////
+
+inline void GetShadeTransCol(unsigned short * pdest, unsigned short color) {
+ if (g_draw.bCheckMask && (*pdest & HOST2LE16(0x8000)))
+ return;
+
+ if (g_soft.DrawSemiTrans) {
+ int32_t r, g, b;
+
+ if (g_soft.GlobalTextABR == 0) {
+ PUTLE16(pdest, (((GETLE16(pdest)&0x7bde)>>1)+(((color)&0x7bde)>>1))|g_draw.sSetMask);//0x8000;
+ return;
+ /*
+ r=(XCOL1(*pdest)>>1)+((XCOL1(color))>>1);
+ b=(XCOL2(*pdest)>>1)+((XCOL2(color))>>1);
+ g=(XCOL3(*pdest)>>1)+((XCOL3(color))>>1);
+ */
+ } else if (g_soft.GlobalTextABR == 1) {
+ r = (XCOL1(GETLE16(pdest))) + ((XCOL1(color)));
+ b = (XCOL2(GETLE16(pdest))) + ((XCOL2(color)));
+ g = (XCOL3(GETLE16(pdest))) + ((XCOL3(color)));
+ } else if (g_soft.GlobalTextABR == 2) {
+ r = (XCOL1(GETLE16(pdest))) - ((XCOL1(color)));
+ b = (XCOL2(GETLE16(pdest))) - ((XCOL2(color)));
+ g = (XCOL3(GETLE16(pdest))) - ((XCOL3(color)));
+ if (r & 0x80000000)
+ r = 0;
+ if (b & 0x80000000)
+ b = 0;
+ if (g & 0x80000000)
+ g = 0;
+ } else {
+#ifdef HALFBRIGHTMODE3
+ r = (XCOL1(GETLE16(pdest))) + ((XCOL1(color)) >> 2);
+ b = (XCOL2(GETLE16(pdest))) + ((XCOL2(color)) >> 2);
+ g = (XCOL3(GETLE16(pdest))) + ((XCOL3(color)) >> 2);
+#else
+ r=(XCOL1(GETLE16(pdest)))+((XCOL1(color))>>1);
+ b=(XCOL2(GETLE16(pdest)))+((XCOL2(color))>>1);
+ g=(XCOL3(GETLE16(pdest)))+((XCOL3(color))>>1);
+#endif
+ }
+
+ if (r & 0x7FFFFFE0)
+ r = 0x1f;
+ if (b & 0x7FFFFC00)
+ b = 0x3e0;
+ if (g & 0x7FFF8000)
+ g = 0x7c00;
+
+ PUTLE16(pdest, (XPSXCOL(r,g,b))|g_draw.sSetMask);//0x8000;
+ }
+else PUTLE16(pdest, color|g_draw.sSetMask);
+ }
+
+ ////////////////////////////////////////////////////////////////////////
+
+inline void GetShadeTransCol32(uint32_t * pdest, uint32_t color) {
+ if (g_soft.DrawSemiTrans) {
+ int32_t r, g, b;
+
+ if (g_soft.GlobalTextABR == 0) {
+ if (!g_draw.bCheckMask) {
+ PUTLE32(pdest, (((GETLE32(pdest)&0x7bde7bde)>>1)+(((color)&0x7bde7bde)>>1))|g_draw.lSetMask);//0x80008000;
+ return;
+ }
+ r = (X32ACOL1(GETLE32(pdest)) >> 1) + ((X32ACOL1(color)) >> 1);
+ b = (X32ACOL2(GETLE32(pdest)) >> 1) + ((X32ACOL2(color)) >> 1);
+ g = (X32ACOL3(GETLE32(pdest)) >> 1) + ((X32ACOL3(color)) >> 1);
+ } else if (g_soft.GlobalTextABR == 1) {
+ r = (X32COL1(GETLE32(pdest))) + ((X32COL1(color)));
+ b = (X32COL2(GETLE32(pdest))) + ((X32COL2(color)));
+ g = (X32COL3(GETLE32(pdest))) + ((X32COL3(color)));
+ } else if (g_soft.GlobalTextABR == 2) {
+ int32_t sr, sb, sg, src, sbc, sgc, c;
+ src = XCOL1(color);
+ sbc = XCOL2(color);
+ sgc = XCOL3(color);
+ c = GETLE32(pdest) >> 16;
+ sr = (XCOL1(c)) - src;
+ if (sr & 0x8000)
+ sr = 0;
+ sb = (XCOL2(c)) - sbc;
+ if (sb & 0x8000)
+ sb = 0;
+ sg = (XCOL3(c)) - sgc;
+ if (sg & 0x8000)
+ sg = 0;
+ r = ((int32_t) sr) << 16;
+ b = ((int32_t) sb) << 11;
+ g = ((int32_t) sg) << 6;
+ c = LOWORD(GETLE32(pdest));
+ sr = (XCOL1(c)) - src;
+ if (sr & 0x8000)
+ sr = 0;
+ sb = (XCOL2(c)) - sbc;
+ if (sb & 0x8000)
+ sb = 0;
+ sg = (XCOL3(c)) - sgc;
+ if (sg & 0x8000)
+ sg = 0;
+ r |= sr;
+ b |= sb >> 5;
+ g |= sg >> 10;
+ } else {
+#ifdef HALFBRIGHTMODE3
+ r = (X32COL1(GETLE32(pdest))) + ((X32BCOL1(color)) >> 2);
+ b = (X32COL2(GETLE32(pdest))) + ((X32BCOL2(color)) >> 2);
+ g = (X32COL3(GETLE32(pdest))) + ((X32BCOL3(color)) >> 2);
+#else
+ r=(X32COL1(GETLE32(pdest)))+((X32ACOL1(color))>>1);
+ b=(X32COL2(GETLE32(pdest)))+((X32ACOL2(color))>>1);
+ g=(X32COL3(GETLE32(pdest)))+((X32ACOL3(color))>>1);
+#endif
+ }
+
+ if (r & 0x7FE00000)
+ r = 0x1f0000 | (r & 0xFFFF);
+ if (r & 0x7FE0)
+ r = 0x1f | (r & 0xFFFF0000);
+ if (b & 0x7FE00000)
+ b = 0x1f0000 | (b & 0xFFFF);
+ if (b & 0x7FE0)
+ b = 0x1f | (b & 0xFFFF0000);
+ if (g & 0x7FE00000)
+ g = 0x1f0000 | (g & 0xFFFF);
+ if (g & 0x7FE0)
+ g = 0x1f | (g & 0xFFFF0000);
+
+ if (g_draw.bCheckMask) {
+ uint32_t ma = GETLE32(pdest);
+ PUTLE32(pdest, (X32PSXCOL(r,g,b))|g_draw.lSetMask);//0x80008000;
+ if (ma & 0x80000000)
+ PUTLE32(pdest, (ma&0xFFFF0000)|(*pdest&0xFFFF));
+ if (ma & 0x00008000)
+ PUTLE32(pdest, (ma&0xFFFF) |(*pdest&0xFFFF0000));
+ return;
+ }
+ PUTLE32(pdest, (X32PSXCOL(r,g,b))|g_draw.lSetMask);//0x80008000;
+ } else {
+ if (g_draw.bCheckMask) {
+ uint32_t ma = GETLE32(pdest);
+ PUTLE32(pdest, color|g_draw.lSetMask);//0x80008000;
+ if (ma & 0x80000000)
+ PUTLE32(pdest, (ma&0xFFFF0000)|(GETLE32(pdest)&0xFFFF));
+ if (ma & 0x00008000)
+ PUTLE32(pdest, (ma&0xFFFF) |(GETLE32(pdest)&0xFFFF0000));
+ return;
+ }
+
+ PUTLE32(pdest, color|g_draw.lSetMask);//0x80008000;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+inline void GetTextureTransColG(unsigned short * pdest, unsigned short color) {
+ int32_t r, g, b;
+ unsigned short l;
+
+ if (color == 0)
+ return;
+
+ if (g_draw.bCheckMask && (*pdest & HOST2LE16(0x8000)))
+ return;
+
+ l = g_draw.sSetMask | (color & 0x8000);
+
+ if (g_soft.DrawSemiTrans && (color & 0x8000)) {
+ if (g_soft.GlobalTextABR == 0) {
+ unsigned short d;
+ d = (GETLE16(pdest) & 0x7bde) >> 1;
+ color = ((color) & 0x7bde) >> 1;
+ r = (XCOL1(d)) + ((((XCOL1(color))) * g_soft.g_m1) >> 7);
+ b = (XCOL2(d)) + ((((XCOL2(color))) * g_soft.g_m2) >> 7);
+ g = (XCOL3(d)) + ((((XCOL3(color))) * g_soft.g_m3) >> 7);
+
+ /*
+ r=(XCOL1(*pdest)>>1)+((((XCOL1(color))>>1)* g_soft.g_m1)>>7);
+ b=(XCOL2(*pdest)>>1)+((((XCOL2(color))>>1)* g_soft.g_m2)>>7);
+ g=(XCOL3(*pdest)>>1)+((((XCOL3(color))>>1)* g_soft.g_m3)>>7);
+ */
+ } else if (g_soft.GlobalTextABR == 1) {
+ r = (XCOL1(GETLE16(pdest))) + ((((XCOL1(color))) * g_soft.g_m1)
+ >> 7);
+ b = (XCOL2(GETLE16(pdest))) + ((((XCOL2(color))) * g_soft.g_m2)
+ >> 7);
+ g = (XCOL3(GETLE16(pdest))) + ((((XCOL3(color))) * g_soft.g_m3)
+ >> 7);
+ } else if (g_soft.GlobalTextABR == 2) {
+ r = (XCOL1(GETLE16(pdest))) - ((((XCOL1(color))) * g_soft.g_m1)
+ >> 7);
+ b = (XCOL2(GETLE16(pdest))) - ((((XCOL2(color))) * g_soft.g_m2)
+ >> 7);
+ g = (XCOL3(GETLE16(pdest))) - ((((XCOL3(color))) * g_soft.g_m3)
+ >> 7);
+ if (r & 0x80000000)
+ r = 0;
+ if (b & 0x80000000)
+ b = 0;
+ if (g & 0x80000000)
+ g = 0;
+ } else {
+#ifdef HALFBRIGHTMODE3
+ r = (XCOL1(GETLE16(pdest)))
+ + ((((XCOL1(color)) >> 2) * g_soft.g_m1) >> 7);
+ b = (XCOL2(GETLE16(pdest)))
+ + ((((XCOL2(color)) >> 2) * g_soft.g_m2) >> 7);
+ g = (XCOL3(GETLE16(pdest)))
+ + ((((XCOL3(color)) >> 2) * g_soft.g_m3) >> 7);
+#else
+ r=(XCOL1(GETLE16(pdest)))+((((XCOL1(color))>>1)* g_soft.g_m1)>>7);
+ b=(XCOL2(GETLE16(pdest)))+((((XCOL2(color))>>1)* g_soft.g_m2)>>7);
+ g=(XCOL3(GETLE16(pdest)))+((((XCOL3(color))>>1)* g_soft.g_m3)>>7);
+#endif
+ }
+ } else {
+ r = ((XCOL1(color)) * g_soft.g_m1) >> 7;
+ b = ((XCOL2(color)) * g_soft.g_m2) >> 7;
+ g = ((XCOL3(color)) * g_soft.g_m3) >> 7;
+ }
+
+ if (r & 0x7FFFFFE0)
+ r = 0x1f;
+ if (b & 0x7FFFFC00)
+ b = 0x3e0;
+ if (g & 0x7FFF8000)
+ g = 0x7c00;
+
+ PUTLE16(pdest, (XPSXCOL(r,g,b))|l);
+}
+
+////////////////////////////////////////////////////////////////////////
+
+inline void GetTextureTransColG_S(unsigned short * pdest, unsigned short color) {
+ int32_t r, g, b;
+ unsigned short l;
+
+ if (color == 0)
+ return;
+
+ l = g_draw.sSetMask | (color & 0x8000);
+
+ r = ((XCOL1(color)) * g_soft.g_m1) >> 7;
+ b = ((XCOL2(color)) * g_soft.g_m2) >> 7;
+ g = ((XCOL3(color)) * g_soft.g_m3) >> 7;
+
+ if (r & 0x7FFFFFE0)
+ r = 0x1f;
+ if (b & 0x7FFFFC00)
+ b = 0x3e0;
+ if (g & 0x7FFF8000)
+ g = 0x7c00;
+
+ PUTLE16(pdest, (XPSXCOL(r,g,b))|l);
+}
+
+////////////////////////////////////////////////////////////////////////
+
+inline void GetTextureTransColG_SPR(unsigned short * pdest,
+ unsigned short color) {
+ int32_t r, g, b;
+ unsigned short l;
+
+ if (color == 0)
+ return;
+
+ if (g_draw.bCheckMask && (GETLE16(pdest) & 0x8000))
+ return;
+
+ l = g_draw.sSetMask | (color & 0x8000);
+
+ if (g_soft.DrawSemiTrans && (color & 0x8000)) {
+ if (g_soft.GlobalTextABR == 0) {
+ unsigned short d;
+ d = (GETLE16(pdest) & 0x7bde) >> 1;
+ color = ((color) & 0x7bde) >> 1;
+ r = (XCOL1(d)) + ((((XCOL1(color))) * g_soft.g_m1) >> 7);
+ b = (XCOL2(d)) + ((((XCOL2(color))) * g_soft.g_m2) >> 7);
+ g = (XCOL3(d)) + ((((XCOL3(color))) * g_soft.g_m3) >> 7);
+
+ /*
+ r=(XCOL1(*pdest)>>1)+((((XCOL1(color))>>1)* g_soft.g_m1)>>7);
+ b=(XCOL2(*pdest)>>1)+((((XCOL2(color))>>1)* g_soft.g_m2)>>7);
+ g=(XCOL3(*pdest)>>1)+((((XCOL3(color))>>1)* g_soft.g_m3)>>7);
+ */
+ } else if (g_soft.GlobalTextABR == 1) {
+ r = (XCOL1(GETLE16(pdest))) + ((((XCOL1(color))) * g_soft.g_m1)
+ >> 7);
+ b = (XCOL2(GETLE16(pdest))) + ((((XCOL2(color))) * g_soft.g_m2)
+ >> 7);
+ g = (XCOL3(GETLE16(pdest))) + ((((XCOL3(color))) * g_soft.g_m3)
+ >> 7);
+ } else if (g_soft.GlobalTextABR == 2) {
+ r = (XCOL1(GETLE16(pdest))) - ((((XCOL1(color))) * g_soft.g_m1)
+ >> 7);
+ b = (XCOL2(GETLE16(pdest))) - ((((XCOL2(color))) * g_soft.g_m2)
+ >> 7);
+ g = (XCOL3(GETLE16(pdest))) - ((((XCOL3(color))) * g_soft.g_m3)
+ >> 7);
+ if (r & 0x80000000)
+ r = 0;
+ if (b & 0x80000000)
+ b = 0;
+ if (g & 0x80000000)
+ g = 0;
+ } else {
+#ifdef HALFBRIGHTMODE3
+ r = (XCOL1(GETLE16(pdest)))
+ + ((((XCOL1(color)) >> 2) * g_soft.g_m1) >> 7);
+ b = (XCOL2(GETLE16(pdest)))
+ + ((((XCOL2(color)) >> 2) * g_soft.g_m2) >> 7);
+ g = (XCOL3(GETLE16(pdest)))
+ + ((((XCOL3(color)) >> 2) * g_soft.g_m3) >> 7);
+#else
+ r=(XCOL1(GETLE16(pdest)))+((((XCOL1(color))>>1)* g_soft.g_m1)>>7);
+ b=(XCOL2(GETLE16(pdest)))+((((XCOL2(color))>>1)* g_soft.g_m2)>>7);
+ g=(XCOL3(GETLE16(pdest)))+((((XCOL3(color))>>1)* g_soft.g_m3)>>7);
+#endif
+ }
+ } else {
+ r = ((XCOL1(color)) * g_soft.g_m1) >> 7;
+ b = ((XCOL2(color)) * g_soft.g_m2) >> 7;
+ g = ((XCOL3(color)) * g_soft.g_m3) >> 7;
+ }
+
+ if (r & 0x7FFFFFE0)
+ r = 0x1f;
+ if (b & 0x7FFFFC00)
+ b = 0x3e0;
+ if (g & 0x7FFF8000)
+ g = 0x7c00;
+
+ PUTLE16(pdest, (XPSXCOL(r,g,b))|l);
+}
+
+////////////////////////////////////////////////////////////////////////
+
+inline void GetTextureTransColG32(uint32_t * pdest, uint32_t color) {
+ int32_t r, g, b, l;
+
+ if (color == 0)
+ return;
+
+ l = g_draw.lSetMask | (color & 0x80008000);
+
+ if (g_soft.DrawSemiTrans && (color & 0x80008000)) {
+ if (g_soft.GlobalTextABR == 0) {
+ r = ((((X32TCOL1(GETLE32(pdest)))
+ + ((X32COL1(color)) * g_soft.g_m1)) & 0xFF00FF00) >> 8);
+ b = ((((X32TCOL2(GETLE32(pdest)))
+ + ((X32COL2(color)) * g_soft.g_m2)) & 0xFF00FF00) >> 8);
+ g = ((((X32TCOL3(GETLE32(pdest)))
+ + ((X32COL3(color)) * g_soft.g_m3)) & 0xFF00FF00) >> 8);
+ } else if (g_soft.GlobalTextABR == 1) {
+ r = (X32COL1(GETLE32(pdest)))
+ + (((((X32COL1(color))) * g_soft.g_m1) & 0xFF80FF80) >> 7);
+ b = (X32COL2(GETLE32(pdest)))
+ + (((((X32COL2(color))) * g_soft.g_m2) & 0xFF80FF80) >> 7);
+ g = (X32COL3(GETLE32(pdest)))
+ + (((((X32COL3(color))) * g_soft.g_m3) & 0xFF80FF80) >> 7);
+ } else if (g_soft.GlobalTextABR == 2) {
+ int32_t t;
+ r = (((((X32COL1(color))) * g_soft.g_m1) & 0xFF80FF80) >> 7);
+ t = (GETLE32(pdest) & 0x001f0000) - (r & 0x003f0000);
+ if (t & 0x80000000)
+ t = 0;
+ r = (GETLE32(pdest) & 0x0000001f) - (r & 0x0000003f);
+ if (r & 0x80000000)
+ r = 0;
+ r |= t;
+
+ b = (((((X32COL2(color))) * g_soft.g_m2) & 0xFF80FF80) >> 7);
+ t = ((GETLE32(pdest) >> 5) & 0x001f0000) - (b & 0x003f0000);
+ if (t & 0x80000000)
+ t = 0;
+ b = ((GETLE32(pdest) >> 5) & 0x0000001f) - (b & 0x0000003f);
+ if (b & 0x80000000)
+ b = 0;
+ b |= t;
+
+ g = (((((X32COL3(color))) * g_soft.g_m3) & 0xFF80FF80) >> 7);
+ t = ((GETLE32(pdest) >> 10) & 0x001f0000) - (g & 0x003f0000);
+ if (t & 0x80000000)
+ t = 0;
+ g = ((GETLE32(pdest) >> 10) & 0x0000001f) - (g & 0x0000003f);
+ if (g & 0x80000000)
+ g = 0;
+ g |= t;
+ } else {
+#ifdef HALFBRIGHTMODE3
+ r = (X32COL1(GETLE32(pdest))) + (((((X32BCOL1(color)) >> 2)
+ * g_soft.g_m1) & 0xFF80FF80) >> 7);
+ b = (X32COL2(GETLE32(pdest))) + (((((X32BCOL2(color)) >> 2)
+ * g_soft.g_m2) & 0xFF80FF80) >> 7);
+ g = (X32COL3(GETLE32(pdest))) + (((((X32BCOL3(color)) >> 2)
+ * g_soft.g_m3) & 0xFF80FF80) >> 7);
+#else
+ r=(X32COL1(GETLE32(pdest)))+(((((X32ACOL1(color))>>1)* g_soft.g_m1)&0xFF80FF80)>>7);
+ b=(X32COL2(GETLE32(pdest)))+(((((X32ACOL2(color))>>1)* g_soft.g_m2)&0xFF80FF80)>>7);
+ g=(X32COL3(GETLE32(pdest)))+(((((X32ACOL3(color))>>1)* g_soft.g_m3)&0xFF80FF80)>>7);
+#endif
+ }
+
+ if (!(color & 0x8000)) {
+ r = (r & 0xffff0000) | ((((X32COL1(color)) * g_soft.g_m1)
+ & 0x0000FF80) >> 7);
+ b = (b & 0xffff0000) | ((((X32COL2(color)) * g_soft.g_m2)
+ & 0x0000FF80) >> 7);
+ g = (g & 0xffff0000) | ((((X32COL3(color)) * g_soft.g_m3)
+ & 0x0000FF80) >> 7);
+ }
+ if (!(color & 0x80000000)) {
+ r = (r & 0xffff) | ((((X32COL1(color)) * g_soft.g_m1) & 0xFF800000)
+ >> 7);
+ b = (b & 0xffff) | ((((X32COL2(color)) * g_soft.g_m2) & 0xFF800000)
+ >> 7);
+ g = (g & 0xffff) | ((((X32COL3(color)) * g_soft.g_m3) & 0xFF800000)
+ >> 7);
+ }
+
+ } else {
+ r = (((X32COL1(color)) * g_soft.g_m1) & 0xFF80FF80) >> 7;
+ b = (((X32COL2(color)) * g_soft.g_m2) & 0xFF80FF80) >> 7;
+ g = (((X32COL3(color)) * g_soft.g_m3) & 0xFF80FF80) >> 7;
+ }
+
+ if (r & 0x7FE00000)
+ r = 0x1f0000 | (r & 0xFFFF);
+ if (r & 0x7FE0)
+ r = 0x1f | (r & 0xFFFF0000);
+ if (b & 0x7FE00000)
+ b = 0x1f0000 | (b & 0xFFFF);
+ if (b & 0x7FE0)
+ b = 0x1f | (b & 0xFFFF0000);
+ if (g & 0x7FE00000)
+ g = 0x1f0000 | (g & 0xFFFF);
+ if (g & 0x7FE0)
+ g = 0x1f | (g & 0xFFFF0000);
+
+ if (g_draw.bCheckMask) {
+ uint32_t ma = GETLE32(pdest);
+
+ PUTLE32(pdest, (X32PSXCOL(r,g,b))|l);
+
+ if ((color & 0xffff) == 0)
+ PUTLE32(pdest, (ma&0xffff)|(GETLE32(pdest)&0xffff0000));
+ if ((color & 0xffff0000) == 0)
+ PUTLE32(pdest, (ma&0xffff0000)|(GETLE32(pdest)&0xffff));
+ if (ma & 0x80000000)
+ PUTLE32(pdest, (ma&0xFFFF0000)|(GETLE32(pdest)&0xFFFF));
+ if (ma & 0x00008000)
+ PUTLE32(pdest, (ma&0xFFFF) |(GETLE32(pdest)&0xFFFF0000));
+
+ return;
+ }
+ if ((color & 0xffff) == 0) {
+ PUTLE32(pdest, (GETLE32(pdest)&0xffff)|(((X32PSXCOL(r,g,b))|l)&0xffff0000));
+ return;
+ }
+ if ((color & 0xffff0000) == 0) {
+ PUTLE32(pdest, (GETLE32(pdest)&0xffff0000)|(((X32PSXCOL(r,g,b))|l)&0xffff));
+ return;
+ }
+
+ PUTLE32(pdest, (X32PSXCOL(r,g,b))|l);
+}
+
+////////////////////////////////////////////////////////////////////////
+
+inline void GetTextureTransColG32_S(uint32_t * pdest, uint32_t color) {
+ int32_t r, g, b;
+
+ if (color == 0)
+ return;
+
+ r = (((X32COL1(color)) * g_soft.g_m1) & 0xFF80FF80) >> 7;
+ b = (((X32COL2(color)) * g_soft.g_m2) & 0xFF80FF80) >> 7;
+ g = (((X32COL3(color)) * g_soft.g_m3) & 0xFF80FF80) >> 7;
+
+ if (r & 0x7FE00000)
+ r = 0x1f0000 | (r & 0xFFFF);
+ if (r & 0x7FE0)
+ r = 0x1f | (r & 0xFFFF0000);
+ if (b & 0x7FE00000)
+ b = 0x1f0000 | (b & 0xFFFF);
+ if (b & 0x7FE0)
+ b = 0x1f | (b & 0xFFFF0000);
+ if (g & 0x7FE00000)
+ g = 0x1f0000 | (g & 0xFFFF);
+ if (g & 0x7FE0)
+ g = 0x1f | (g & 0xFFFF0000);
+
+ if ((color & 0xffff) == 0) {
+ PUTLE32(pdest, (GETLE32(pdest)&0xffff)|(((X32PSXCOL(r,g,b))|g_draw.lSetMask|(color&0x80008000))&0xffff0000));
+ return;
+ }
+ if ((color & 0xffff0000) == 0) {
+ PUTLE32(pdest, (GETLE32(pdest)&0xffff0000)|(((X32PSXCOL(r,g,b))|g_draw.lSetMask|(color&0x80008000))&0xffff));
+ return;
+ }
+
+ PUTLE32(pdest, (X32PSXCOL(r,g,b))|g_draw.lSetMask|(color&0x80008000));
+}
+
+////////////////////////////////////////////////////////////////////////
+
+inline void GetTextureTransColG32_SPR(uint32_t * pdest, uint32_t color) {
+ int32_t r, g, b;
+
+ if (color == 0)
+ return;
+
+ if (g_soft.DrawSemiTrans && (color & 0x80008000)) {
+ if (g_soft.GlobalTextABR == 0) {
+ r = ((((X32TCOL1(GETLE32(pdest)))
+ + ((X32COL1(color)) * g_soft.g_m1)) & 0xFF00FF00) >> 8);
+ b = ((((X32TCOL2(GETLE32(pdest)))
+ + ((X32COL2(color)) * g_soft.g_m2)) & 0xFF00FF00) >> 8);
+ g = ((((X32TCOL3(GETLE32(pdest)))
+ + ((X32COL3(color)) * g_soft.g_m3)) & 0xFF00FF00) >> 8);
+ } else if (g_soft.GlobalTextABR == 1) {
+ r = (X32COL1(GETLE32(pdest)))
+ + (((((X32COL1(color))) * g_soft.g_m1) & 0xFF80FF80) >> 7);
+ b = (X32COL2(GETLE32(pdest)))
+ + (((((X32COL2(color))) * g_soft.g_m2) & 0xFF80FF80) >> 7);
+ g = (X32COL3(GETLE32(pdest)))
+ + (((((X32COL3(color))) * g_soft.g_m3) & 0xFF80FF80) >> 7);
+ } else if (g_soft.GlobalTextABR == 2) {
+ int32_t t;
+ r = (((((X32COL1(color))) * g_soft.g_m1) & 0xFF80FF80) >> 7);
+ t = (GETLE32(pdest) & 0x001f0000) - (r & 0x003f0000);
+ if (t & 0x80000000)
+ t = 0;
+ r = (GETLE32(pdest) & 0x0000001f) - (r & 0x0000003f);
+ if (r & 0x80000000)
+ r = 0;
+ r |= t;
+
+ b = (((((X32COL2(color))) * g_soft.g_m2) & 0xFF80FF80) >> 7);
+ t = ((GETLE32(pdest) >> 5) & 0x001f0000) - (b & 0x003f0000);
+ if (t & 0x80000000)
+ t = 0;
+ b = ((GETLE32(pdest) >> 5) & 0x0000001f) - (b & 0x0000003f);
+ if (b & 0x80000000)
+ b = 0;
+ b |= t;
+
+ g = (((((X32COL3(color))) * g_soft.g_m3) & 0xFF80FF80) >> 7);
+ t = ((GETLE32(pdest) >> 10) & 0x001f0000) - (g & 0x003f0000);
+ if (t & 0x80000000)
+ t = 0;
+ g = ((GETLE32(pdest) >> 10) & 0x0000001f) - (g & 0x0000003f);
+ if (g & 0x80000000)
+ g = 0;
+ g |= t;
+ } else {
+#ifdef HALFBRIGHTMODE3
+ r = (X32COL1(GETLE32(pdest))) + (((((X32BCOL1(color)) >> 2)
+ * g_soft.g_m1) & 0xFF80FF80) >> 7);
+ b = (X32COL2(GETLE32(pdest))) + (((((X32BCOL2(color)) >> 2)
+ * g_soft.g_m2) & 0xFF80FF80) >> 7);
+ g = (X32COL3(GETLE32(pdest))) + (((((X32BCOL3(color)) >> 2)
+ * g_soft.g_m3) & 0xFF80FF80) >> 7);
+#else
+ r=(X32COL1(GETLE32(pdest)))+(((((X32ACOL1(color))>>1)* g_soft.g_m1)&0xFF80FF80)>>7);
+ b=(X32COL2(GETLE32(pdest)))+(((((X32ACOL2(color))>>1)* g_soft.g_m2)&0xFF80FF80)>>7);
+ g=(X32COL3(GETLE32(pdest)))+(((((X32ACOL3(color))>>1)* g_soft.g_m3)&0xFF80FF80)>>7);
+#endif
+ }
+
+ if (!(color & 0x8000)) {
+ r = (r & 0xffff0000) | ((((X32COL1(color)) * g_soft.g_m1)
+ & 0x0000FF80) >> 7);
+ b = (b & 0xffff0000) | ((((X32COL2(color)) * g_soft.g_m2)
+ & 0x0000FF80) >> 7);
+ g = (g & 0xffff0000) | ((((X32COL3(color)) * g_soft.g_m3)
+ & 0x0000FF80) >> 7);
+ }
+ if (!(color & 0x80000000)) {
+ r = (r & 0xffff) | ((((X32COL1(color)) * g_soft.g_m1) & 0xFF800000)
+ >> 7);
+ b = (b & 0xffff) | ((((X32COL2(color)) * g_soft.g_m2) & 0xFF800000)
+ >> 7);
+ g = (g & 0xffff) | ((((X32COL3(color)) * g_soft.g_m3) & 0xFF800000)
+ >> 7);
+ }
+
+ } else {
+ r = (((X32COL1(color)) * g_soft.g_m1) & 0xFF80FF80) >> 7;
+ b = (((X32COL2(color)) * g_soft.g_m2) & 0xFF80FF80) >> 7;
+ g = (((X32COL3(color)) * g_soft.g_m3) & 0xFF80FF80) >> 7;
+ }
+
+ if (r & 0x7FE00000)
+ r = 0x1f0000 | (r & 0xFFFF);
+ if (r & 0x7FE0)
+ r = 0x1f | (r & 0xFFFF0000);
+ if (b & 0x7FE00000)
+ b = 0x1f0000 | (b & 0xFFFF);
+ if (b & 0x7FE0)
+ b = 0x1f | (b & 0xFFFF0000);
+ if (g & 0x7FE00000)
+ g = 0x1f0000 | (g & 0xFFFF);
+ if (g & 0x7FE0)
+ g = 0x1f | (g & 0xFFFF0000);
+
+ if (g_draw.bCheckMask) {
+ uint32_t ma = GETLE32(pdest);
+
+ PUTLE32(pdest, (X32PSXCOL(r,g,b))|g_draw.lSetMask|(color&0x80008000));
+
+ if ((color & 0xffff) == 0)
+ PUTLE32(pdest, (ma&0xffff)|(GETLE32(pdest)&0xffff0000));
+ if ((color & 0xffff0000) == 0)
+ PUTLE32(pdest, (ma&0xffff0000)|(GETLE32(pdest)&0xffff));
+ if (ma & 0x80000000)
+ PUTLE32(pdest, (ma&0xFFFF0000)|(GETLE32(pdest)&0xFFFF));
+ if (ma & 0x00008000)
+ PUTLE32(pdest, (ma&0xFFFF) |(GETLE32(pdest)&0xFFFF0000));
+
+ return;
+ }
+ if ((color & 0xffff) == 0) {
+ PUTLE32(pdest, (GETLE32(pdest)&0xffff)|(((X32PSXCOL(r,g,b))|g_draw.lSetMask|(color&0x80008000))&0xffff0000));
+ return;
+ }
+ if ((color & 0xffff0000) == 0) {
+ PUTLE32(pdest, (GETLE32(pdest)&0xffff0000)|(((X32PSXCOL(r,g,b))|g_draw.lSetMask|(color&0x80008000))&0xffff));
+ return;
+ }
+
+ PUTLE32(pdest, (X32PSXCOL(r,g,b))|g_draw.lSetMask|(color&0x80008000));
+}
+
+////////////////////////////////////////////////////////////////////////
+
+inline void GetTextureTransColGX_Dither(unsigned short * pdest,
+ unsigned short color, int32_t m1, int32_t m2, int32_t m3) {
+ int32_t r, g, b;
+
+ if (color == 0)
+ return;
+
+ if (g_draw.bCheckMask && (*pdest & HOST2LE16(0x8000)))
+ return;
+
+ m1 = (((XCOL1D(color))) * m1) >> 4;
+ m2 = (((XCOL2D(color))) * m2) >> 4;
+ m3 = (((XCOL3D(color))) * m3) >> 4;
+
+ if (g_soft.DrawSemiTrans && (color & 0x8000)) {
+ r = ((XCOL1D(GETLE16(pdest))) << 3);
+ b = ((XCOL2D(GETLE16(pdest))) << 3);
+ g = ((XCOL3D(GETLE16(pdest))) << 3);
+
+ if (g_soft.GlobalTextABR == 0) {
+ r = (r >> 1) + (m1 >> 1);
+ b = (b >> 1) + (m2 >> 1);
+ g = (g >> 1) + (m3 >> 1);
+ } else if (g_soft.GlobalTextABR == 1) {
+ r += m1;
+ b += m2;
+ g += m3;
+ } else if (g_soft.GlobalTextABR == 2) {
+ r -= m1;
+ b -= m2;
+ g -= m3;
+ if (r & 0x80000000)
+ r = 0;
+ if (b & 0x80000000)
+ b = 0;
+ if (g & 0x80000000)
+ g = 0;
+ } else {
+#ifdef HALFBRIGHTMODE3
+ r += (m1 >> 2);
+ b += (m2 >> 2);
+ g += (m3 >> 2);
+#else
+ r+=(m1>>1);
+ b+=(m2>>1);
+ g+=(m3>>1);
+#endif
+ }
+ } else {
+ r = m1;
+ b = m2;
+ g = m3;
+ }
+
+ if (r & 0x7FFFFF00)
+ r = 0xff;
+ if (b & 0x7FFFFF00)
+ b = 0xff;
+ if (g & 0x7FFFFF00)
+ g = 0xff;
+
+ Dither16(pdest, r, b, g, g_draw.sSetMask | (color & 0x8000));
+
+}
+
+////////////////////////////////////////////////////////////////////////
+
+inline void GetTextureTransColGX(unsigned short * pdest, unsigned short color,
+ short m1, short m2, short m3) {
+ int32_t r, g, b;
+ unsigned short l;
+
+ if (color == 0)
+ return;
+
+ if (g_draw.bCheckMask && (*pdest & HOST2LE16(0x8000)))
+ return;
+
+ l = g_draw.sSetMask | (color & 0x8000);
+
+ if (g_soft.DrawSemiTrans && (color & 0x8000)) {
+ if (g_soft.GlobalTextABR == 0) {
+ unsigned short d;
+ d = (GETLE16(pdest) & 0x7bde) >> 1;
+ color = ((color) & 0x7bde) >> 1;
+ r = (XCOL1(d)) + ((((XCOL1(color))) * m1) >> 7);
+ b = (XCOL2(d)) + ((((XCOL2(color))) * m2) >> 7);
+ g = (XCOL3(d)) + ((((XCOL3(color))) * m3) >> 7);
+ /*
+ r=(XCOL1(*pdest)>>1)+((((XCOL1(color))>>1)* m1)>>7);
+ b=(XCOL2(*pdest)>>1)+((((XCOL2(color))>>1)* m2)>>7);
+ g=(XCOL3(*pdest)>>1)+((((XCOL3(color))>>1)* m3)>>7);
+ */
+ } else if (g_soft.GlobalTextABR == 1) {
+ r = (XCOL1(GETLE16(pdest))) + ((((XCOL1(color))) * m1) >> 7);
+ b = (XCOL2(GETLE16(pdest))) + ((((XCOL2(color))) * m2) >> 7);
+ g = (XCOL3(GETLE16(pdest))) + ((((XCOL3(color))) * m3) >> 7);
+ } else if (g_soft.GlobalTextABR == 2) {
+ r = (XCOL1(GETLE16(pdest))) - ((((XCOL1(color))) * m1) >> 7);
+ b = (XCOL2(GETLE16(pdest))) - ((((XCOL2(color))) * m2) >> 7);
+ g = (XCOL3(GETLE16(pdest))) - ((((XCOL3(color))) * m3) >> 7);
+ if (r & 0x80000000)
+ r = 0;
+ if (b & 0x80000000)
+ b = 0;
+ if (g & 0x80000000)
+ g = 0;
+ } else {
+#ifdef HALFBRIGHTMODE3
+ r = (XCOL1(GETLE16(pdest))) + ((((XCOL1(color)) >> 2) * m1) >> 7);
+ b = (XCOL2(GETLE16(pdest))) + ((((XCOL2(color)) >> 2) * m2) >> 7);
+ g = (XCOL3(GETLE16(pdest))) + ((((XCOL3(color)) >> 2) * m3) >> 7);
+#else
+ r=(XCOL1(GETLE16(pdest)))+((((XCOL1(color))>>1)* m1)>>7);
+ b=(XCOL2(GETLE16(pdest)))+((((XCOL2(color))>>1)* m2)>>7);
+ g=(XCOL3(GETLE16(pdest)))+((((XCOL3(color))>>1)* m3)>>7);
+#endif
+ }
+ } else {
+ r = ((XCOL1(color)) * m1) >> 7;
+ b = ((XCOL2(color)) * m2) >> 7;
+ g = ((XCOL3(color)) * m3) >> 7;
+ }
+
+ if (r & 0x7FFFFFE0)
+ r = 0x1f;
+ if (b & 0x7FFFFC00)
+ b = 0x3e0;
+ if (g & 0x7FFF8000)
+ g = 0x7c00;
+
+ PUTLE16(pdest, (XPSXCOL(r,g,b))|l);
+}
+
+////////////////////////////////////////////////////////////////////////
+
+inline void GetTextureTransColGX_S(unsigned short * pdest,
+ unsigned short color, short m1, short m2, short m3) {
+ int32_t r, g, b;
+
+ if (color == 0)
+ return;
+
+ r = ((XCOL1(color)) * m1) >> 7;
+ b = ((XCOL2(color)) * m2) >> 7;
+ g = ((XCOL3(color)) * m3) >> 7;
+
+ if (r & 0x7FFFFFE0)
+ r = 0x1f;
+ if (b & 0x7FFFFC00)
+ b = 0x3e0;
+ if (g & 0x7FFF8000)
+ g = 0x7c00;
+
+ PUTLE16(pdest, (XPSXCOL(r,g,b))|g_draw.sSetMask|(color&0x8000));
+}
+
+////////////////////////////////////////////////////////////////////////
+
+inline void GetTextureTransColGX32_S(uint32_t * pdest, uint32_t color,
+ short m1, short m2, short m3) {
+ int32_t r, g, b;
+
+ if (color == 0)
+ return;
+
+ r = (((X32COL1(color)) * m1) & 0xFF80FF80) >> 7;
+ b = (((X32COL2(color)) * m2) & 0xFF80FF80) >> 7;
+ g = (((X32COL3(color)) * m3) & 0xFF80FF80) >> 7;
+
+ if (r & 0x7FE00000)
+ r = 0x1f0000 | (r & 0xFFFF);
+ if (r & 0x7FE0)
+ r = 0x1f | (r & 0xFFFF0000);
+ if (b & 0x7FE00000)
+ b = 0x1f0000 | (b & 0xFFFF);
+ if (b & 0x7FE0)
+ b = 0x1f | (b & 0xFFFF0000);
+ if (g & 0x7FE00000)
+ g = 0x1f0000 | (g & 0xFFFF);
+ if (g & 0x7FE0)
+ g = 0x1f | (g & 0xFFFF0000);
+
+ if ((color & 0xffff) == 0) {
+ PUTLE32(pdest, (GETLE32(pdest)&0xffff)|(((X32PSXCOL(r,g,b))|g_draw.lSetMask|(color&0x80008000))&0xffff0000));
+ return;
+ }
+ if ((color & 0xffff0000) == 0) {
+ PUTLE32(pdest, (GETLE32(pdest)&0xffff0000)|(((X32PSXCOL(r,g,b))|g_draw.lSetMask|(color&0x80008000))&0xffff));
+ return;
+ }
+
+ PUTLE32(pdest, (X32PSXCOL(r,g,b))|g_draw.lSetMask|(color&0x80008000));
+}
+
+////////////////////////////////////////////////////////////////////////
+// FILL FUNCS
+////////////////////////////////////////////////////////////////////////
+
+void FillSoftwareAreaTrans(short x0, short y0, short x1, // FILL AREA TRANS
+ short y1, unsigned short col) {
+ short j, i, dx, dy;
+
+ if (y0 > y1)
+ return;
+ if (x0 > x1)
+ return;
+
+ if (x1 < g_prim.drawX)
+ return;
+ if (y1 < g_prim.drawY)
+ return;
+ if (x0 > g_prim.drawW)
+ return;
+ if (y0 > g_prim.drawH)
+ return;
+
+ x1 = MIN(x1, g_prim.drawW + 1);
+ y1 = MIN(y1, g_prim.drawH + 1);
+ x0 = MAX(x0, g_prim.drawX);
+ y0 = MAX(y0, g_prim.drawY);
+
+ if (y0 >= 512)
+ return;
+ if (x0 > 1023)
+ return;
+
+ if (y1 > 512)
+ y1 = 512;
+ if (x1 > 1024)
+ x1 = 1024;
+
+ dx = x1 - x0;
+ dy = y1 - y0;
+
+ if (dx == 1 && dy == 1 && x0 == 1020 && y0 == 511) // special fix for pinball game... emu protection???
+ {
+ /*
+ m->v 1020 511 1 1
+ writedatamem 0x00000000 1
+ tile1 newcol 7fff (orgcol 0xffffff), oldvram 0
+ v->m 1020 511 1 1
+ readdatamem 0x00007fff 1
+ m->v 1020 511 1 1
+ writedatamem 0x00000000 1
+ tile1 newcol 8000 (orgcol 0xffffff), oldvram 0
+ v->m 1020 511 1 1
+ readdatamem 0x00008000 1
+ */
+
+ static int iCheat = 0;
+ col += iCheat;
+ if (iCheat == 1)
+ iCheat = 0;
+ else
+ iCheat = 1;
+ }
+
+ if (dx & 1) // slow fill
+ {
+ unsigned short *DSTPtr;
+ unsigned short LineOffset;
+ DSTPtr = g_gpu.psx_vram.u16 + (1024 * y0) + x0;
+ LineOffset = 1024 - dx;
+ for (i = 0; i < dy; i++) {
+ for (j = 0; j < dx; j++)
+ GetShadeTransCol(DSTPtr++, col);
+ DSTPtr += LineOffset;
+ }
+ } else // fast fill
+ {
+ uint32_t *DSTPtr;
+ unsigned short LineOffset;
+ uint32_t lcol = g_draw.lSetMask | (((uint32_t) (col)) << 16) | col;
+ dx >>= 1;
+ DSTPtr = (uint32_t *) (g_gpu.psx_vram.u16 + (1024 * y0) + x0);
+ LineOffset = 512 - dx;
+
+ if (!g_draw.bCheckMask && !g_soft.DrawSemiTrans) {
+ for (i = 0; i < dy; i++) {
+ for (j = 0; j < dx; j++) {
+ PUTLE32(DSTPtr, lcol);
+ DSTPtr++;
+ }
+ DSTPtr += LineOffset;
+ }
+ } else {
+ for (i = 0; i < dy; i++) {
+ for (j = 0; j < dx; j++)
+ GetShadeTransCol32(DSTPtr++, lcol);
+ DSTPtr += LineOffset;
+ }
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void FillSoftwareArea(short x0, short y0, short x1, // FILL AREA (BLK FILL)
+ short y1, unsigned short col) // no draw area check here!
+{
+ short j, i, dx, dy;
+
+ if (y0 > y1)
+ return;
+ if (x0 > x1)
+ return;
+
+ if (y0 >= 512)
+ return;
+ if (x0 > 1023)
+ return;
+
+ if (y1 > 512)
+ y1 = 512;
+ if (x1 > 1024)
+ x1 = 1024;
+
+ dx = x1 - x0;
+ dy = y1 - y0;
+ if (dx & 1) {
+ unsigned short *DSTPtr;
+ unsigned short LineOffset;
+
+ DSTPtr = g_gpu.psx_vram.u16 + (1024 * y0) + x0;
+ LineOffset = 1024 - dx;
+
+ for (i = 0; i < dy; i++) {
+ for (j = 0; j < dx; j++) {
+ PUTLE16(DSTPtr, col);
+ DSTPtr++;
+ }
+ DSTPtr += LineOffset;
+ }
+ } else {
+ uint32_t *DSTPtr;
+ unsigned short LineOffset;
+ uint32_t lcol = (((int32_t) col) << 16) | col;
+ dx >>= 1;
+ DSTPtr = (uint32_t *) (g_gpu.psx_vram.u16 + (1024 * y0) + x0);
+ LineOffset = 512 - dx;
+
+ for (i = 0; i < dy; i++) {
+ for (j = 0; j < dx; j++) {
+ PUTLE32(DSTPtr, lcol);
+ DSTPtr++;
+ }
+ DSTPtr += LineOffset;
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////
+// EDGE INTERPOLATION
+////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////
+
+typedef struct SOFTVTAG {
+ int x, y;
+ int u, v;
+ int32_t R, G, B;
+} soft_vertex;
+
+static soft_vertex vtx[4];
+static soft_vertex * left_array[4], *right_array[4];
+static int left_section, right_section;
+static int left_section_height, right_section_height;
+static int left_x, delta_left_x, right_x, delta_right_x;
+static int left_u, delta_left_u, left_v, delta_left_v;
+static int right_u, delta_right_u, right_v, delta_right_v;
+static int left_R, delta_left_R, right_R, delta_right_R;
+static int left_G, delta_left_G, right_G, delta_right_G;
+static int left_B, delta_left_B, right_B, delta_right_B;
+
+#ifdef USE_NASM
+
+// NASM version (external):
+#define shl10idiv i386_shl10idiv
+
+inline int shl10idiv(int x, int y);
+
+#else
+
+inline int shl10idiv(int x, int y) {
+ int64_t bi = x;
+ bi <<= 10;
+ return bi / y;
+}
+
+#endif
+
+#if 0
+
+// GNUC long long int version:
+
+inline int shl10idiv(int x, int y)
+{
+ long long int bi=x;
+ bi<<=10;
+ return bi/y;
+}
+
+#endif
+
+////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////
+
+inline int RightSection_F(void) {
+ soft_vertex * v1 = right_array[right_section];
+ soft_vertex * v2 = right_array[right_section - 1];
+
+ int height = v2->y - v1->y;
+ if (height == 0)
+ return 0;
+ delta_right_x = (v2->x - v1->x) / height;
+ right_x = v1->x;
+
+ right_section_height = height;
+ return height;
+}
+
+////////////////////////////////////////////////////////////////////////
+
+inline int LeftSection_F(void) {
+ soft_vertex * v1 = left_array[left_section];
+ soft_vertex * v2 = left_array[left_section - 1];
+
+ int height = v2->y - v1->y;
+ if (height == 0)
+ return 0;
+ delta_left_x = (v2->x - v1->x) / height;
+ left_x = v1->x;
+
+ left_section_height = height;
+ return height;
+}
+
+////////////////////////////////////////////////////////////////////////
+
+inline char NextRow_F(void) {
+ if (--left_section_height <= 0) {
+ if (--left_section <= 0) {
+ return 1;
+ }
+ if (LeftSection_F() <= 0) {
+ return 1;
+ }
+ } else {
+ left_x += delta_left_x;
+ }
+
+ if (--right_section_height <= 0) {
+ if (--right_section <= 0) {
+ return 1;
+ }
+ if (RightSection_F() <= 0) {
+ return 1;
+ }
+ } else {
+ right_x += delta_right_x;
+ }
+ return 0;
+}
+
+////////////////////////////////////////////////////////////////////////
+
+inline char SetupSections_F(short x1, short y1, short x2, short y2, short x3,
+ short y3) {
+ soft_vertex * v1, *v2, *v3;
+ int height, longest;
+
+ v1 = vtx;
+ v1->x = x1 << 16;
+ v1->y = y1;
+ v2 = vtx + 1;
+ v2->x = x2 << 16;
+ v2->y = y2;
+ v3 = vtx + 2;
+ v3->x = x3 << 16;
+ v3->y = y3;
+
+ if (v1->y > v2->y) {
+ soft_vertex * v = v1;
+ v1 = v2;
+ v2 = v;
+ }
+ if (v1->y > v3->y) {
+ soft_vertex * v = v1;
+ v1 = v3;
+ v3 = v;
+ }
+ if (v2->y > v3->y) {
+ soft_vertex * v = v2;
+ v2 = v3;
+ v3 = v;
+ }
+
+ height = v3->y - v1->y;
+ if (height == 0) {
+ return 0;
+ }
+ longest = (((v2->y - v1->y) << 16) / height) * ((v3->x - v1->x) >> 16)
+ + (v1->x - v2->x);
+ if (longest == 0) {
+ return 0;
+ }
+
+ if (longest < 0) {
+ right_array[0] = v3;
+ right_array[1] = v2;
+ right_array[2] = v1;
+ right_section = 2;
+ left_array[0] = v3;
+ left_array[1] = v1;
+ left_section = 1;
+
+ if (LeftSection_F() <= 0)
+ return 0;
+ if (RightSection_F() <= 0) {
+ right_section--;
+ if (RightSection_F() <= 0)
+ return 0;
+ }
+ } else {
+ left_array[0] = v3;
+ left_array[1] = v2;
+ left_array[2] = v1;
+ left_section = 2;
+ right_array[0] = v3;
+ right_array[1] = v1;
+ right_section = 1;
+
+ if (RightSection_F() <= 0)
+ return 0;
+ if (LeftSection_F() <= 0) {
+ left_section--;
+ if (LeftSection_F() <= 0)
+ return 0;
+ }
+ }
+
+ g_soft.Ymin = v1->y;
+ g_soft.Ymax = MIN(v3->y - 1, g_prim.drawH);
+
+ return 1;
+}
+
+////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////
+
+inline int RightSection_G(void) {
+ soft_vertex * v1 = right_array[right_section];
+ soft_vertex * v2 = right_array[right_section - 1];
+
+ int height = v2->y - v1->y;
+ if (height == 0)
+ return 0;
+ delta_right_x = (v2->x - v1->x) / height;
+ right_x = v1->x;
+
+ right_section_height = height;
+ return height;
+}
+
+////////////////////////////////////////////////////////////////////////
+
+inline int LeftSection_G(void) {
+ soft_vertex * v1 = left_array[left_section];
+ soft_vertex * v2 = left_array[left_section - 1];
+
+ int height = v2->y - v1->y;
+ if (height == 0)
+ return 0;
+ delta_left_x = (v2->x - v1->x) / height;
+ left_x = v1->x;
+
+ delta_left_R = ((v2->R - v1->R)) / height;
+ left_R = v1->R;
+ delta_left_G = ((v2->G - v1->G)) / height;
+ left_G = v1->G;
+ delta_left_B = ((v2->B - v1->B)) / height;
+ left_B = v1->B;
+
+ left_section_height = height;
+ return height;
+}
+
+////////////////////////////////////////////////////////////////////////
+
+inline char NextRow_G(void) {
+ if (--left_section_height <= 0) {
+ if (--left_section <= 0) {
+ return 1;
+ }
+ if (LeftSection_G() <= 0) {
+ return 1;
+ }
+ } else {
+ left_x += delta_left_x;
+ left_R += delta_left_R;
+ left_G += delta_left_G;
+ left_B += delta_left_B;
+ }
+
+ if (--right_section_height <= 0) {
+ if (--right_section <= 0) {
+ return 1;
+ }
+ if (RightSection_G() <= 0) {
+ return 1;
+ }
+ } else {
+ right_x += delta_right_x;
+ }
+ return 0;
+}
+
+////////////////////////////////////////////////////////////////////////
+
+inline char SetupSections_G(short x1, short y1, short x2, short y2, short x3,
+ short y3, int32_t rgb1, int32_t rgb2, int32_t rgb3) {
+ soft_vertex * v1, *v2, *v3;
+ int height, longest, temp;
+
+ v1 = vtx;
+ v1->x = x1 << 16;
+ v1->y = y1;
+ v1->R = (rgb1) & 0x00ff0000;
+ v1->G = (rgb1 << 8) & 0x00ff0000;
+ v1->B = (rgb1 << 16) & 0x00ff0000;
+ v2 = vtx + 1;
+ v2->x = x2 << 16;
+ v2->y = y2;
+ v2->R = (rgb2) & 0x00ff0000;
+ v2->G = (rgb2 << 8) & 0x00ff0000;
+ v2->B = (rgb2 << 16) & 0x00ff0000;
+ v3 = vtx + 2;
+ v3->x = x3 << 16;
+ v3->y = y3;
+ v3->R = (rgb3) & 0x00ff0000;
+ v3->G = (rgb3 << 8) & 0x00ff0000;
+ v3->B = (rgb3 << 16) & 0x00ff0000;
+
+ if (v1->y > v2->y) {
+ soft_vertex * v = v1;
+ v1 = v2;
+ v2 = v;
+ }
+ if (v1->y > v3->y) {
+ soft_vertex * v = v1;
+ v1 = v3;
+ v3 = v;
+ }
+ if (v2->y > v3->y) {
+ soft_vertex * v = v2;
+ v2 = v3;
+ v3 = v;
+ }
+
+ height = v3->y - v1->y;
+ if (height == 0) {
+ return 0;
+ }
+ temp = (((v2->y - v1->y) << 16) / height);
+ longest = temp * ((v3->x - v1->x) >> 16) + (v1->x - v2->x);
+ if (longest == 0) {
+ return 0;
+ }
+
+ if (longest < 0) {
+ right_array[0] = v3;
+ right_array[1] = v2;
+ right_array[2] = v1;
+ right_section = 2;
+ left_array[0] = v3;
+ left_array[1] = v1;
+ left_section = 1;
+
+ if (LeftSection_G() <= 0)
+ return 0;
+ if (RightSection_G() <= 0) {
+ right_section--;
+ if (RightSection_G() <= 0)
+ return 0;
+ }
+ if (longest > -0x1000)
+ longest = -0x1000;
+ } else {
+ left_array[0] = v3;
+ left_array[1] = v2;
+ left_array[2] = v1;
+ left_section = 2;
+ right_array[0] = v3;
+ right_array[1] = v1;
+ right_section = 1;
+
+ if (RightSection_G() <= 0)
+ return 0;
+ if (LeftSection_G() <= 0) {
+ left_section--;
+ if (LeftSection_G() <= 0)
+ return 0;
+ }
+ if (longest < 0x1000)
+ longest = 0x1000;
+ }
+
+ g_soft.Ymin = v1->y;
+ g_soft.Ymax = MIN(v3->y - 1, g_prim.drawH);
+
+ delta_right_R = shl10idiv(temp * ((v3->R - v1->R) >> 10) + ((v1->R - v2->R)
+ << 6), longest);
+ delta_right_G = shl10idiv(temp * ((v3->G - v1->G) >> 10) + ((v1->G - v2->G)
+ << 6), longest);
+ delta_right_B = shl10idiv(temp * ((v3->B - v1->B) >> 10) + ((v1->B - v2->B)
+ << 6), longest);
+
+ return 1;
+}
+
+////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////
+
+inline int RightSection_FT(void) {
+ soft_vertex * v1 = right_array[right_section];
+ soft_vertex * v2 = right_array[right_section - 1];
+
+ int height = v2->y - v1->y;
+ if (height == 0)
+ return 0;
+ delta_right_x = (v2->x - v1->x) / height;
+ right_x = v1->x;
+
+ right_section_height = height;
+ return height;
+}
+
+////////////////////////////////////////////////////////////////////////
+
+inline int LeftSection_FT(void) {
+ soft_vertex * v1 = left_array[left_section];
+ soft_vertex * v2 = left_array[left_section - 1];
+
+ int height = v2->y - v1->y;
+ if (height == 0)
+ return 0;
+ delta_left_x = (v2->x - v1->x) / height;
+ left_x = v1->x;
+
+ delta_left_u = ((v2->u - v1->u)) / height;
+ left_u = v1->u;
+ delta_left_v = ((v2->v - v1->v)) / height;
+ left_v = v1->v;
+
+ left_section_height = height;
+ return height;
+}
+
+////////////////////////////////////////////////////////////////////////
+
+inline char NextRow_FT(void) {
+ if (--left_section_height <= 0) {
+ if (--left_section <= 0) {
+ return 1;
+ }
+ if (LeftSection_FT() <= 0) {
+ return 1;
+ }
+ } else {
+ left_x += delta_left_x;
+ left_u += delta_left_u;
+ left_v += delta_left_v;
+ }
+
+ if (--right_section_height <= 0) {
+ if (--right_section <= 0) {
+ return 1;
+ }
+ if (RightSection_FT() <= 0) {
+ return 1;
+ }
+ } else {
+ right_x += delta_right_x;
+ }
+ return 0;
+}
+
+////////////////////////////////////////////////////////////////////////
+
+inline char SetupSections_FT(short x1, short y1, short x2, short y2, short x3,
+ short y3, short tx1, short ty1, short tx2, short ty2, short tx3,
+ short ty3) {
+ soft_vertex * v1, *v2, *v3;
+ int height, longest, temp;
+
+ v1 = vtx;
+ v1->x = x1 << 16;
+ v1->y = y1;
+ v1->u = tx1 << 16;
+ v1->v = ty1 << 16;
+ v2 = vtx + 1;
+ v2->x = x2 << 16;
+ v2->y = y2;
+ v2->u = tx2 << 16;
+ v2->v = ty2 << 16;
+ v3 = vtx + 2;
+ v3->x = x3 << 16;
+ v3->y = y3;
+ v3->u = tx3 << 16;
+ v3->v = ty3 << 16;
+
+ if (v1->y > v2->y) {
+ soft_vertex * v = v1;
+ v1 = v2;
+ v2 = v;
+ }
+ if (v1->y > v3->y) {
+ soft_vertex * v = v1;
+ v1 = v3;
+ v3 = v;
+ }
+ if (v2->y > v3->y) {
+ soft_vertex * v = v2;
+ v2 = v3;
+ v3 = v;
+ }
+
+ height = v3->y - v1->y;
+ if (height == 0) {
+ return 0;
+ }
+
+ temp = (((v2->y - v1->y) << 16) / height);
+ longest = temp * ((v3->x - v1->x) >> 16) + (v1->x - v2->x);
+
+ if (longest == 0) {
+ return 0;
+ }
+
+ if (longest < 0) {
+ right_array[0] = v3;
+ right_array[1] = v2;
+ right_array[2] = v1;
+ right_section = 2;
+ left_array[0] = v3;
+ left_array[1] = v1;
+ left_section = 1;
+
+ if (LeftSection_FT() <= 0)
+ return 0;
+ if (RightSection_FT() <= 0) {
+ right_section--;
+ if (RightSection_FT() <= 0)
+ return 0;
+ }
+ if (longest > -0x1000)
+ longest = -0x1000;
+ } else {
+ left_array[0] = v3;
+ left_array[1] = v2;
+ left_array[2] = v1;
+ left_section = 2;
+ right_array[0] = v3;
+ right_array[1] = v1;
+ right_section = 1;
+
+ if (RightSection_FT() <= 0)
+ return 0;
+ if (LeftSection_FT() <= 0) {
+ left_section--;
+ if (LeftSection_FT() <= 0)
+ return 0;
+ }
+ if (longest < 0x1000)
+ longest = 0x1000;
+ }
+
+ g_soft.Ymin = v1->y;
+ g_soft.Ymax = MIN(v3->y - 1, g_prim.drawH);
+
+ delta_right_u = shl10idiv(temp * ((v3->u - v1->u) >> 10) + ((v1->u - v2->u)
+ << 6), longest);
+ delta_right_v = shl10idiv(temp * ((v3->v - v1->v) >> 10) + ((v1->v - v2->v)
+ << 6), longest);
+
+ /*
+ Mmm... adjust neg tex deltas... will sometimes cause slight
+ texture distortions
+
+ longest>>=16;
+ if(longest)
+ {
+ if(longest<0) longest=-longest;
+ if(delta_right_u<0)
+ delta_right_u-=delta_right_u/longest;
+ if(delta_right_v<0)
+ delta_right_v-=delta_right_v/longest;
+ }
+ */
+
+ return 1;
+}
+
+////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////
+
+inline int RightSection_GT(void) {
+ soft_vertex * v1 = right_array[right_section];
+ soft_vertex * v2 = right_array[right_section - 1];
+
+ int height = v2->y - v1->y;
+ if (height == 0)
+ return 0;
+ delta_right_x = (v2->x - v1->x) / height;
+ right_x = v1->x;
+
+ right_section_height = height;
+ return height;
+}
+
+////////////////////////////////////////////////////////////////////////
+
+inline int LeftSection_GT(void) {
+ soft_vertex * v1 = left_array[left_section];
+ soft_vertex * v2 = left_array[left_section - 1];
+
+ int height = v2->y - v1->y;
+ if (height == 0)
+ return 0;
+ delta_left_x = (v2->x - v1->x) / height;
+ left_x = v1->x;
+
+ delta_left_u = ((v2->u - v1->u)) / height;
+ left_u = v1->u;
+ delta_left_v = ((v2->v - v1->v)) / height;
+ left_v = v1->v;
+
+ delta_left_R = ((v2->R - v1->R)) / height;
+ left_R = v1->R;
+ delta_left_G = ((v2->G - v1->G)) / height;
+ left_G = v1->G;
+ delta_left_B = ((v2->B - v1->B)) / height;
+ left_B = v1->B;
+
+ left_section_height = height;
+ return height;
+}
+
+////////////////////////////////////////////////////////////////////////
+
+inline char NextRow_GT(void) {
+ if (--left_section_height <= 0) {
+ if (--left_section <= 0) {
+ return 1;
+ }
+ if (LeftSection_GT() <= 0) {
+ return 1;
+ }
+ } else {
+ left_x += delta_left_x;
+ left_u += delta_left_u;
+ left_v += delta_left_v;
+ left_R += delta_left_R;
+ left_G += delta_left_G;
+ left_B += delta_left_B;
+ }
+
+ if (--right_section_height <= 0) {
+ if (--right_section <= 0) {
+ return 1;
+ }
+ if (RightSection_GT() <= 0) {
+ return 1;
+ }
+ } else {
+ right_x += delta_right_x;
+ }
+ return 0;
+}
+
+////////////////////////////////////////////////////////////////////////
+
+inline char SetupSections_GT(short x1, short y1, short x2, short y2, short x3,
+ short y3, short tx1, short ty1, short tx2, short ty2, short tx3,
+ short ty3, int32_t rgb1, int32_t rgb2, int32_t rgb3) {
+ soft_vertex * v1, *v2, *v3;
+ int height, longest, temp;
+
+ v1 = vtx;
+ v1->x = x1 << 16;
+ v1->y = y1;
+ v1->u = tx1 << 16;
+ v1->v = ty1 << 16;
+ v1->R = (rgb1) & 0x00ff0000;
+ v1->G = (rgb1 << 8) & 0x00ff0000;
+ v1->B = (rgb1 << 16) & 0x00ff0000;
+
+ v2 = vtx + 1;
+ v2->x = x2 << 16;
+ v2->y = y2;
+ v2->u = tx2 << 16;
+ v2->v = ty2 << 16;
+ v2->R = (rgb2) & 0x00ff0000;
+ v2->G = (rgb2 << 8) & 0x00ff0000;
+ v2->B = (rgb2 << 16) & 0x00ff0000;
+
+ v3 = vtx + 2;
+ v3->x = x3 << 16;
+ v3->y = y3;
+ v3->u = tx3 << 16;
+ v3->v = ty3 << 16;
+ v3->R = (rgb3) & 0x00ff0000;
+ v3->G = (rgb3 << 8) & 0x00ff0000;
+ v3->B = (rgb3 << 16) & 0x00ff0000;
+
+ if (v1->y > v2->y) {
+ soft_vertex * v = v1;
+ v1 = v2;
+ v2 = v;
+ }
+ if (v1->y > v3->y) {
+ soft_vertex * v = v1;
+ v1 = v3;
+ v3 = v;
+ }
+ if (v2->y > v3->y) {
+ soft_vertex * v = v2;
+ v2 = v3;
+ v3 = v;
+ }
+
+ height = v3->y - v1->y;
+ if (height == 0) {
+ return 0;
+ }
+
+ temp = (((v2->y - v1->y) << 16) / height);
+ longest = temp * ((v3->x - v1->x) >> 16) + (v1->x - v2->x);
+
+ if (longest == 0) {
+ return 0;
+ }
+
+ if (longest < 0) {
+ right_array[0] = v3;
+ right_array[1] = v2;
+ right_array[2] = v1;
+ right_section = 2;
+ left_array[0] = v3;
+ left_array[1] = v1;
+ left_section = 1;
+
+ if (LeftSection_GT() <= 0)
+ return 0;
+ if (RightSection_GT() <= 0) {
+ right_section--;
+ if (RightSection_GT() <= 0)
+ return 0;
+ }
+
+ if (longest > -0x1000)
+ longest = -0x1000;
+ } else {
+ left_array[0] = v3;
+ left_array[1] = v2;
+ left_array[2] = v1;
+ left_section = 2;
+ right_array[0] = v3;
+ right_array[1] = v1;
+ right_section = 1;
+
+ if (RightSection_GT() <= 0)
+ return 0;
+ if (LeftSection_GT() <= 0) {
+ left_section--;
+ if (LeftSection_GT() <= 0)
+ return 0;
+ }
+ if (longest < 0x1000)
+ longest = 0x1000;
+ }
+
+ g_soft.Ymin = v1->y;
+ g_soft.Ymax = MIN(v3->y - 1, g_prim.drawH);
+
+ delta_right_R = shl10idiv(temp * ((v3->R - v1->R) >> 10) + ((v1->R - v2->R)
+ << 6), longest);
+ delta_right_G = shl10idiv(temp * ((v3->G - v1->G) >> 10) + ((v1->G - v2->G)
+ << 6), longest);
+ delta_right_B = shl10idiv(temp * ((v3->B - v1->B) >> 10) + ((v1->B - v2->B)
+ << 6), longest);
+
+ delta_right_u = shl10idiv(temp * ((v3->u - v1->u) >> 10) + ((v1->u - v2->u)
+ << 6), longest);
+ delta_right_v = shl10idiv(temp * ((v3->v - v1->v) >> 10) + ((v1->v - v2->v)
+ << 6), longest);
+
+ /*
+ Mmm... adjust neg tex deltas... will sometimes cause slight
+ texture distortions
+ longest>>=16;
+ if(longest)
+ {
+ if(longest<0) longest=-longest;
+ if(delta_right_u<0)
+ delta_right_u-=delta_right_u/longest;
+ if(delta_right_v<0)
+ delta_right_v-=delta_right_v/longest;
+ }
+ */
+
+ return 1;
+}
+
+////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////
+
+inline int RightSection_F4(void) {
+ soft_vertex * v1 = right_array[right_section];
+ soft_vertex * v2 = right_array[right_section - 1];
+
+ int height = v2->y - v1->y;
+ right_section_height = height;
+ right_x = v1->x;
+ if (height == 0) {
+ return 0;
+ }
+ delta_right_x = (v2->x - v1->x) / height;
+
+ return height;
+}
+
+////////////////////////////////////////////////////////////////////////
+
+inline int LeftSection_F4(void) {
+ soft_vertex * v1 = left_array[left_section];
+ soft_vertex * v2 = left_array[left_section - 1];
+
+ int height = v2->y - v1->y;
+ left_section_height = height;
+ left_x = v1->x;
+ if (height == 0) {
+ return 0;
+ }
+ delta_left_x = (v2->x - v1->x) / height;
+
+ return height;
+}
+
+////////////////////////////////////////////////////////////////////////
+
+inline char NextRow_F4(void) {
+ if (--left_section_height <= 0) {
+ if (--left_section > 0)
+ while (LeftSection_F4() <= 0) {
+ if (--left_section <= 0)
+ break;
+ }
+ } else {
+ left_x += delta_left_x;
+ }
+
+ if (--right_section_height <= 0) {
+ if (--right_section > 0)
+ while (RightSection_F4() <= 0) {
+ if (--right_section <= 0)
+ break;
+ }
+ } else {
+ right_x += delta_right_x;
+ }
+ return 0;
+}
+
+////////////////////////////////////////////////////////////////////////
+
+inline char SetupSections_F4(short x1, short y1, short x2, short y2, short x3,
+ short y3, short x4, short y4) {
+ soft_vertex * v1, *v2, *v3, *v4;
+ int height, width, longest1, longest2;
+
+ v1 = vtx;
+ v1->x = x1 << 16;
+ v1->y = y1;
+ v2 = vtx + 1;
+ v2->x = x2 << 16;
+ v2->y = y2;
+ v3 = vtx + 2;
+ v3->x = x3 << 16;
+ v3->y = y3;
+ v4 = vtx + 3;
+ v4->x = x4 << 16;
+ v4->y = y4;
+
+ if (v1->y > v2->y) {
+ soft_vertex * v = v1;
+ v1 = v2;
+ v2 = v;
+ }
+ if (v1->y > v3->y) {
+ soft_vertex * v = v1;
+ v1 = v3;
+ v3 = v;
+ }
+ if (v1->y > v4->y) {
+ soft_vertex * v = v1;
+ v1 = v4;
+ v4 = v;
+ }
+ if (v2->y > v3->y) {
+ soft_vertex * v = v2;
+ v2 = v3;
+ v3 = v;
+ }
+ if (v2->y > v4->y) {
+ soft_vertex * v = v2;
+ v2 = v4;
+ v4 = v;
+ }
+ if (v3->y > v4->y) {
+ soft_vertex * v = v3;
+ v3 = v4;
+ v4 = v;
+ }
+
+ height = v4->y - v1->y;
+ if (height == 0)
+ height = 1;
+ width = (v4->x - v1->x) >> 16;
+ longest1 = (((v2->y - v1->y) << 16) / height) * width + (v1->x - v2->x);
+ longest2 = (((v3->y - v1->y) << 16) / height) * width + (v1->x - v3->x);
+
+ if (longest1 < 0) // 2 is right
+ {
+ if (longest2 < 0) // 3 is right
+ {
+ left_array[0] = v4;
+ left_array[1] = v1;
+ left_section = 1;
+
+ height = v3->y - v1->y;
+ if (height == 0)
+ height = 1;
+ longest1 = (((v2->y - v1->y) << 16) / height) * ((v3->x - v1->x)
+ >> 16) + (v1->x - v2->x);
+ if (longest1 >= 0) {
+ right_array[0] = v4; // 1
+ right_array[1] = v3; // 3
+ right_array[2] = v1; // 4
+ right_section = 2;
+ } else {
+ height = v4->y - v2->y;
+ if (height == 0)
+ height = 1;
+ longest1 = (((v3->y - v2->y) << 16) / height)
+ * ((v4->x - v2->x) >> 16) + (v2->x - v3->x);
+ if (longest1 >= 0) {
+ right_array[0] = v4; // 1
+ right_array[1] = v2; // 2
+ right_array[2] = v1; // 4
+ right_section = 2;
+ } else {
+ right_array[0] = v4; // 1
+ right_array[1] = v3; // 2
+ right_array[2] = v2; // 3
+ right_array[3] = v1; // 4
+ right_section = 3;
+ }
+ }
+ } else {
+ left_array[0] = v4;
+ left_array[1] = v3; // 1
+ left_array[2] = v1; // 2
+ left_section = 2; // 3
+ right_array[0] = v4; // 4
+ right_array[1] = v2;
+ right_array[2] = v1;
+ right_section = 2;
+ }
+ } else {
+ if (longest2 < 0) {
+ left_array[0] = v4; // 1
+ left_array[1] = v2; // 2
+ left_array[2] = v1; // 3
+ left_section = 2; // 4
+ right_array[0] = v4;
+ right_array[1] = v3;
+ right_array[2] = v1;
+ right_section = 2;
+ } else {
+ right_array[0] = v4;
+ right_array[1] = v1;
+ right_section = 1;
+
+ height = v3->y - v1->y;
+ if (height == 0)
+ height = 1;
+ longest1 = (((v2->y - v1->y) << 16) / height) * ((v3->x - v1->x)
+ >> 16) + (v1->x - v2->x);
+ if (longest1 < 0) {
+ left_array[0] = v4; // 1
+ left_array[1] = v3; // 3
+ left_array[2] = v1; // 4
+ left_section = 2;
+ } else {
+ height = v4->y - v2->y;
+ if (height == 0)
+ height = 1;
+ longest1 = (((v3->y - v2->y) << 16) / height)
+ * ((v4->x - v2->x) >> 16) + (v2->x - v3->x);
+ if (longest1 < 0) {
+ left_array[0] = v4; // 1
+ left_array[1] = v2; // 2
+ left_array[2] = v1; // 4
+ left_section = 2;
+ } else {
+ left_array[0] = v4; // 1
+ left_array[1] = v3; // 2
+ left_array[2] = v2; // 3
+ left_array[3] = v1; // 4
+ left_section = 3;
+ }
+ }
+ }
+ }
+
+ while (LeftSection_F4() <= 0) {
+ if (--left_section <= 0)
+ break;
+ }
+
+ while (RightSection_F4() <= 0) {
+ if (--right_section <= 0)
+ break;
+ }
+
+ g_soft.Ymin = v1->y;
+ g_soft.Ymax = MIN(v4->y - 1, g_prim.drawH);
+
+ return 1;
+}
+
+////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////
+
+inline int RightSection_FT4(void) {
+ soft_vertex * v1 = right_array[right_section];
+ soft_vertex * v2 = right_array[right_section - 1];
+
+ int height = v2->y - v1->y;
+ right_section_height = height;
+ right_x = v1->x;
+ right_u = v1->u;
+ right_v = v1->v;
+ if (height == 0) {
+ return 0;
+ }
+ delta_right_x = (v2->x - v1->x) / height;
+ delta_right_u = (v2->u - v1->u) / height;
+ delta_right_v = (v2->v - v1->v) / height;
+
+ return height;
+}
+
+////////////////////////////////////////////////////////////////////////
+
+inline int LeftSection_FT4(void) {
+ soft_vertex * v1 = left_array[left_section];
+ soft_vertex * v2 = left_array[left_section - 1];
+
+ int height = v2->y - v1->y;
+ left_section_height = height;
+ left_x = v1->x;
+ left_u = v1->u;
+ left_v = v1->v;
+ if (height == 0) {
+ return 0;
+ }
+ delta_left_x = (v2->x - v1->x) / height;
+ delta_left_u = (v2->u - v1->u) / height;
+ delta_left_v = (v2->v - v1->v) / height;
+
+ return height;
+}
+
+////////////////////////////////////////////////////////////////////////
+
+inline char NextRow_FT4(void) {
+ if (--left_section_height <= 0) {
+ if (--left_section > 0)
+ while (LeftSection_FT4() <= 0) {
+ if (--left_section <= 0)
+ break;
+ }
+ } else {
+ left_x += delta_left_x;
+ left_u += delta_left_u;
+ left_v += delta_left_v;
+ }
+
+ if (--right_section_height <= 0) {
+ if (--right_section > 0)
+ while (RightSection_FT4() <= 0) {
+ if (--right_section <= 0)
+ break;
+ }
+ } else {
+ right_x += delta_right_x;
+ right_u += delta_right_u;
+ right_v += delta_right_v;
+ }
+ return 0;
+}
+
+////////////////////////////////////////////////////////////////////////
+
+inline char SetupSections_FT4(short x1, short y1, short x2, short y2, short x3,
+ short y3, short x4, short y4, short tx1, short ty1, short tx2,
+ short ty2, short tx3, short ty3, short tx4, short ty4) {
+ soft_vertex * v1, *v2, *v3, *v4;
+ int height, width, longest1, longest2;
+
+ v1 = vtx;
+ v1->x = x1 << 16;
+ v1->y = y1;
+ v1->u = tx1 << 16;
+ v1->v = ty1 << 16;
+
+ v2 = vtx + 1;
+ v2->x = x2 << 16;
+ v2->y = y2;
+ v2->u = tx2 << 16;
+ v2->v = ty2 << 16;
+
+ v3 = vtx + 2;
+ v3->x = x3 << 16;
+ v3->y = y3;
+ v3->u = tx3 << 16;
+ v3->v = ty3 << 16;
+
+ v4 = vtx + 3;
+ v4->x = x4 << 16;
+ v4->y = y4;
+ v4->u = tx4 << 16;
+ v4->v = ty4 << 16;
+
+ if (v1->y > v2->y) {
+ soft_vertex * v = v1;
+ v1 = v2;
+ v2 = v;
+ }
+ if (v1->y > v3->y) {
+ soft_vertex * v = v1;
+ v1 = v3;
+ v3 = v;
+ }
+ if (v1->y > v4->y) {
+ soft_vertex * v = v1;
+ v1 = v4;
+ v4 = v;
+ }
+ if (v2->y > v3->y) {
+ soft_vertex * v = v2;
+ v2 = v3;
+ v3 = v;
+ }
+ if (v2->y > v4->y) {
+ soft_vertex * v = v2;
+ v2 = v4;
+ v4 = v;
+ }
+ if (v3->y > v4->y) {
+ soft_vertex * v = v3;
+ v3 = v4;
+ v4 = v;
+ }
+
+ height = v4->y - v1->y;
+ if (height == 0)
+ height = 1;
+ width = (v4->x - v1->x) >> 16;
+ longest1 = (((v2->y - v1->y) << 16) / height) * width + (v1->x - v2->x);
+ longest2 = (((v3->y - v1->y) << 16) / height) * width + (v1->x - v3->x);
+
+ if (longest1 < 0) // 2 is right
+ {
+ if (longest2 < 0) // 3 is right
+ {
+ left_array[0] = v4;
+ left_array[1] = v1;
+ left_section = 1;
+
+ height = v3->y - v1->y;
+ if (height == 0)
+ height = 1;
+ longest1 = (((v2->y - v1->y) << 16) / height) * ((v3->x - v1->x)
+ >> 16) + (v1->x - v2->x);
+ if (longest1 >= 0) {
+ right_array[0] = v4; // 1
+ right_array[1] = v3; // 3
+ right_array[2] = v1; // 4
+ right_section = 2;
+ } else {
+ height = v4->y - v2->y;
+ if (height == 0)
+ height = 1;
+ longest1 = (((v3->y - v2->y) << 16) / height)
+ * ((v4->x - v2->x) >> 16) + (v2->x - v3->x);
+ if (longest1 >= 0) {
+ right_array[0] = v4; // 1
+ right_array[1] = v2; // 2
+ right_array[2] = v1; // 4
+ right_section = 2;
+ } else {
+ right_array[0] = v4; // 1
+ right_array[1] = v3; // 2
+ right_array[2] = v2; // 3
+ right_array[3] = v1; // 4
+ right_section = 3;
+ }
+ }
+ } else {
+ left_array[0] = v4;
+ left_array[1] = v3; // 1
+ left_array[2] = v1; // 2
+ left_section = 2; // 3
+ right_array[0] = v4; // 4
+ right_array[1] = v2;
+ right_array[2] = v1;
+ right_section = 2;
+ }
+ } else {
+ if (longest2 < 0) {
+ left_array[0] = v4; // 1
+ left_array[1] = v2; // 2
+ left_array[2] = v1; // 3
+ left_section = 2; // 4
+ right_array[0] = v4;
+ right_array[1] = v3;
+ right_array[2] = v1;
+ right_section = 2;
+ } else {
+ right_array[0] = v4;
+ right_array[1] = v1;
+ right_section = 1;
+
+ height = v3->y - v1->y;
+ if (height == 0)
+ height = 1;
+ longest1 = (((v2->y - v1->y) << 16) / height) * ((v3->x - v1->x)
+ >> 16) + (v1->x - v2->x);
+ if (longest1 < 0) {
+ left_array[0] = v4; // 1
+ left_array[1] = v3; // 3
+ left_array[2] = v1; // 4
+ left_section = 2;
+ } else {
+ height = v4->y - v2->y;
+ if (height == 0)
+ height = 1;
+ longest1 = (((v3->y - v2->y) << 16) / height)
+ * ((v4->x - v2->x) >> 16) + (v2->x - v3->x);
+ if (longest1 < 0) {
+ left_array[0] = v4; // 1
+ left_array[1] = v2; // 2
+ left_array[2] = v1; // 4
+ left_section = 2;
+ } else {
+ left_array[0] = v4; // 1
+ left_array[1] = v3; // 2
+ left_array[2] = v2; // 3
+ left_array[3] = v1; // 4
+ left_section = 3;
+ }
+ }
+ }
+ }
+
+ while (LeftSection_FT4() <= 0) {
+ if (--left_section <= 0)
+ break;
+ }
+
+ while (RightSection_FT4() <= 0) {
+ if (--right_section <= 0)
+ break;
+ }
+
+ g_soft.Ymin = v1->y;
+ g_soft.Ymax = MIN(v4->y - 1, g_prim.drawH);
+
+ return 1;
+}
+
+////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////
+
+inline int RightSection_GT4(void) {
+ soft_vertex * v1 = right_array[right_section];
+ soft_vertex * v2 = right_array[right_section - 1];
+
+ int height = v2->y - v1->y;
+ right_section_height = height;
+ right_x = v1->x;
+ right_u = v1->u;
+ right_v = v1->v;
+ right_R = v1->R;
+ right_G = v1->G;
+ right_B = v1->B;
+
+ if (height == 0) {
+ return 0;
+ }
+ delta_right_x = (v2->x - v1->x) / height;
+ delta_right_u = (v2->u - v1->u) / height;
+ delta_right_v = (v2->v - v1->v) / height;
+ delta_right_R = (v2->R - v1->R) / height;
+ delta_right_G = (v2->G - v1->G) / height;
+ delta_right_B = (v2->B - v1->B) / height;
+
+ return height;
+}
+
+////////////////////////////////////////////////////////////////////////
+
+inline int LeftSection_GT4(void) {
+ soft_vertex * v1 = left_array[left_section];
+ soft_vertex * v2 = left_array[left_section - 1];
+
+ int height = v2->y - v1->y;
+ left_section_height = height;
+ left_x = v1->x;
+ left_u = v1->u;
+ left_v = v1->v;
+ left_R = v1->R;
+ left_G = v1->G;
+ left_B = v1->B;
+
+ if (height == 0) {
+ return 0;
+ }
+ delta_left_x = (v2->x - v1->x) / height;
+ delta_left_u = (v2->u - v1->u) / height;
+ delta_left_v = (v2->v - v1->v) / height;
+ delta_left_R = (v2->R - v1->R) / height;
+ delta_left_G = (v2->G - v1->G) / height;
+ delta_left_B = (v2->B - v1->B) / height;
+
+ return height;
+}
+
+////////////////////////////////////////////////////////////////////////
+
+inline char NextRow_GT4(void) {
+ if (--left_section_height <= 0) {
+ if (--left_section > 0)
+ while (LeftSection_GT4() <= 0) {
+ if (--left_section <= 0)
+ break;
+ }
+ } else {
+ left_x += delta_left_x;
+ left_u += delta_left_u;
+ left_v += delta_left_v;
+ left_R += delta_left_R;
+ left_G += delta_left_G;
+ left_B += delta_left_B;
+ }
+
+ if (--right_section_height <= 0) {
+ if (--right_section > 0)
+ while (RightSection_GT4() <= 0) {
+ if (--right_section <= 0)
+ break;
+ }
+ } else {
+ right_x += delta_right_x;
+ right_u += delta_right_u;
+ right_v += delta_right_v;
+ right_R += delta_right_R;
+ right_G += delta_right_G;
+ right_B += delta_right_B;
+ }
+ return 0;
+}
+
+////////////////////////////////////////////////////////////////////////
+
+inline char SetupSections_GT4(short x1, short y1, short x2, short y2, short x3,
+ short y3, short x4, short y4, short tx1, short ty1, short tx2,
+ short ty2, short tx3, short ty3, short tx4, short ty4, int32_t rgb1,
+ int32_t rgb2, int32_t rgb3, int32_t rgb4) {
+ soft_vertex * v1, *v2, *v3, *v4;
+ int height, width, longest1, longest2;
+
+ v1 = vtx;
+ v1->x = x1 << 16;
+ v1->y = y1;
+ v1->u = tx1 << 16;
+ v1->v = ty1 << 16;
+ v1->R = (rgb1) & 0x00ff0000;
+ v1->G = (rgb1 << 8) & 0x00ff0000;
+ v1->B = (rgb1 << 16) & 0x00ff0000;
+
+ v2 = vtx + 1;
+ v2->x = x2 << 16;
+ v2->y = y2;
+ v2->u = tx2 << 16;
+ v2->v = ty2 << 16;
+ v2->R = (rgb2) & 0x00ff0000;
+ v2->G = (rgb2 << 8) & 0x00ff0000;
+ v2->B = (rgb2 << 16) & 0x00ff0000;
+
+ v3 = vtx + 2;
+ v3->x = x3 << 16;
+ v3->y = y3;
+ v3->u = tx3 << 16;
+ v3->v = ty3 << 16;
+ v3->R = (rgb3) & 0x00ff0000;
+ v3->G = (rgb3 << 8) & 0x00ff0000;
+ v3->B = (rgb3 << 16) & 0x00ff0000;
+
+ v4 = vtx + 3;
+ v4->x = x4 << 16;
+ v4->y = y4;
+ v4->u = tx4 << 16;
+ v4->v = ty4 << 16;
+ v4->R = (rgb4) & 0x00ff0000;
+ v4->G = (rgb4 << 8) & 0x00ff0000;
+ v4->B = (rgb4 << 16) & 0x00ff0000;
+
+ if (v1->y > v2->y) {
+ soft_vertex * v = v1;
+ v1 = v2;
+ v2 = v;
+ }
+ if (v1->y > v3->y) {
+ soft_vertex * v = v1;
+ v1 = v3;
+ v3 = v;
+ }
+ if (v1->y > v4->y) {
+ soft_vertex * v = v1;
+ v1 = v4;
+ v4 = v;
+ }
+ if (v2->y > v3->y) {
+ soft_vertex * v = v2;
+ v2 = v3;
+ v3 = v;
+ }
+ if (v2->y > v4->y) {
+ soft_vertex * v = v2;
+ v2 = v4;
+ v4 = v;
+ }
+ if (v3->y > v4->y) {
+ soft_vertex * v = v3;
+ v3 = v4;
+ v4 = v;
+ }
+
+ height = v4->y - v1->y;
+ if (height == 0)
+ height = 1;
+ width = (v4->x - v1->x) >> 16;
+ longest1 = (((v2->y - v1->y) << 16) / height) * width + (v1->x - v2->x);
+ longest2 = (((v3->y - v1->y) << 16) / height) * width + (v1->x - v3->x);
+
+ if (longest1 < 0) // 2 is right
+ {
+ if (longest2 < 0) // 3 is right
+ {
+ left_array[0] = v4;
+ left_array[1] = v1;
+ left_section = 1;
+
+ height = v3->y - v1->y;
+ if (height == 0)
+ height = 1;
+ longest1 = (((v2->y - v1->y) << 16) / height) * ((v3->x - v1->x)
+ >> 16) + (v1->x - v2->x);
+ if (longest1 >= 0) {
+ right_array[0] = v4; // 1
+ right_array[1] = v3; // 3
+ right_array[2] = v1; // 4
+ right_section = 2;
+ } else {
+ height = v4->y - v2->y;
+ if (height == 0)
+ height = 1;
+ longest1 = (((v3->y - v2->y) << 16) / height)
+ * ((v4->x - v2->x) >> 16) + (v2->x - v3->x);
+ if (longest1 >= 0) {
+ right_array[0] = v4; // 1
+ right_array[1] = v2; // 2
+ right_array[2] = v1; // 4
+ right_section = 2;
+ } else {
+ right_array[0] = v4; // 1
+ right_array[1] = v3; // 2
+ right_array[2] = v2; // 3
+ right_array[3] = v1; // 4
+ right_section = 3;
+ }
+ }
+ } else {
+ left_array[0] = v4;
+ left_array[1] = v3; // 1
+ left_array[2] = v1; // 2
+ left_section = 2; // 3
+ right_array[0] = v4; // 4
+ right_array[1] = v2;
+ right_array[2] = v1;
+ right_section = 2;
+ }
+ } else {
+ if (longest2 < 0) {
+ left_array[0] = v4; // 1
+ left_array[1] = v2; // 2
+ left_array[2] = v1; // 3
+ left_section = 2; // 4
+ right_array[0] = v4;
+ right_array[1] = v3;
+ right_array[2] = v1;
+ right_section = 2;
+ } else {
+ right_array[0] = v4;
+ right_array[1] = v1;
+ right_section = 1;
+
+ height = v3->y - v1->y;
+ if (height == 0)
+ height = 1;
+ longest1 = (((v2->y - v1->y) << 16) / height) * ((v3->x - v1->x)
+ >> 16) + (v1->x - v2->x);
+ if (longest1 < 0) {
+ left_array[0] = v4; // 1
+ left_array[1] = v3; // 3
+ left_array[2] = v1; // 4
+ left_section = 2;
+ } else {
+ height = v4->y - v2->y;
+ if (height == 0)
+ height = 1;
+ longest1 = (((v3->y - v2->y) << 16) / height)
+ * ((v4->x - v2->x) >> 16) + (v2->x - v3->x);
+ if (longest1 < 0) {
+ left_array[0] = v4; // 1
+ left_array[1] = v2; // 2
+ left_array[2] = v1; // 4
+ left_section = 2;
+ } else {
+ left_array[0] = v4; // 1
+ left_array[1] = v3; // 2
+ left_array[2] = v2; // 3
+ left_array[3] = v1; // 4
+ left_section = 3;
+ }
+ }
+ }
+ }
+
+ while (LeftSection_GT4() <= 0) {
+ if (--left_section <= 0)
+ break;
+ }
+
+ while (RightSection_GT4() <= 0) {
+ if (--right_section <= 0)
+ break;
+ }
+
+ g_soft.Ymin = v1->y;
+ g_soft.Ymax = MIN(v4->y - 1, g_prim.drawH);
+
+ return 1;
+}
+
+////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////
+// POLY FUNCS
+////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+// POLY 3/4 FLAT SHADED
+////////////////////////////////////////////////////////////////////////
+
+inline void drawPoly3Fi(short x1, short y1, short x2, short y2, short x3,
+ short y3, int32_t rgb) {
+ int i, j, xmin, xmax, ymin, ymax;
+ unsigned short color;
+ uint32_t lcolor;
+
+ if (x1 > g_prim.drawW && x2 > g_prim.drawW && x3 > g_prim.drawW)
+ return;
+ if (y1 > g_prim.drawH && y2 > g_prim.drawH && y3 > g_prim.drawH)
+ return;
+ if (x1 < g_prim.drawX && x2 < g_prim.drawX && x3 < g_prim.drawX)
+ return;
+ if (y1 < g_prim.drawY && y2 < g_prim.drawY && y3 < g_prim.drawY)
+ return;
+ if (g_prim.drawY >= g_prim.drawH)
+ return;
+ if (g_prim.drawX >= g_prim.drawW)
+ return;
+
+ if (!SetupSections_F(x1, y1, x2, y2, x3, y3))
+ return;
+
+ ymax = g_soft.Ymax;
+
+ color = ((rgb & 0x00f80000) >> 9) | ((rgb & 0x0000f800) >> 6) | ((rgb
+ & 0x000000f8) >> 3);
+ lcolor = g_draw.lSetMask | (((uint32_t) (color)) << 16) | color;
+
+ for (ymin = g_soft.Ymin; ymin < g_prim.drawY; ymin++)
+ if (NextRow_F())
+ return;
+
+#ifdef FASTSOLID
+
+ if (!g_draw.bCheckMask && !g_soft.DrawSemiTrans) {
+ color |= g_draw.sSetMask;
+ for (i = ymin; i <= ymax; i++) {
+ xmin = left_x >> 16;
+ if (g_prim.drawX > xmin)
+ xmin = g_prim.drawX;
+ xmax = (right_x >> 16) - 1;
+ if (g_prim.drawW < xmax)
+ xmax = g_prim.drawW;
+
+ for (j = xmin; j < xmax; j += 2) {
+ PUTLE32(((uint32_t *)&g_gpu.psx_vram.u16[(i<<10)+j]), lcolor);
+ }
+ if (j == xmax)
+ PUTLE16(&g_gpu.psx_vram.u16[(i<<10)+j], color);
+
+ if (NextRow_F())
+ return;
+ }
+ return;
+ }
+
+#endif
+
+ for (i = ymin; i <= ymax; i++) {
+ xmin = left_x >> 16;
+ if (g_prim.drawX > xmin)
+ xmin = g_prim.drawX;
+ xmax = (right_x >> 16) - 1;
+ if (g_prim.drawW < xmax)
+ xmax = g_prim.drawW;
+
+ for (j = xmin; j < xmax; j += 2) {
+ GetShadeTransCol32((uint32_t *) &g_gpu.psx_vram.u16[(i << 10) + j],
+ lcolor);
+ }
+ if (j == xmax)
+ GetShadeTransCol(&g_gpu.psx_vram.u16[(i << 10) + j], color);
+
+ if (NextRow_F())
+ return;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void drawPoly3F(int32_t rgb) {
+ drawPoly3Fi(g_soft.lx0, g_soft.ly0, g_soft.lx1, g_soft.ly1, g_soft.lx2,
+ g_soft.ly2, rgb);
+}
+
+#ifdef POLYQUAD3FS
+
+void drawPoly4F_TRI(int32_t rgb)
+{
+ drawPog_soft.ly3Fi(g_soft.lx1,g_soft.ly1,g_soft.lx3,g_soft.ly3,g_soft.lx2,g_soft.ly2,rgb);
+ drawPog_soft.ly3Fi(g_soft.lx0,g_soft.ly0,g_soft.lx1,g_soft.ly1,g_soft.lx2,g_soft.ly2,rgb);
+}
+
+#endif
+
+// more exact:
+
+void drawPoly4F(int32_t rgb) {
+ int i, j, xmin, xmax, ymin, ymax;
+ unsigned short color;
+ uint32_t lcolor;
+
+ if (g_soft.lx0 > g_prim.drawW && g_soft.lx1 > g_prim.drawW && g_soft.lx2
+ > g_prim.drawW && g_soft.lx3 > g_prim.drawW)
+ return;
+ if (g_soft.ly0 > g_prim.drawH && g_soft.ly1 > g_prim.drawH && g_soft.ly2
+ > g_prim.drawH && g_soft.ly3 > g_prim.drawH)
+ return;
+ if (g_soft.lx0 < g_prim.drawX && g_soft.lx1 < g_prim.drawX && g_soft.lx2
+ < g_prim.drawX && g_soft.lx3 < g_prim.drawX)
+ return;
+ if (g_soft.ly0 < g_prim.drawY && g_soft.ly1 < g_prim.drawY && g_soft.ly2
+ < g_prim.drawY && g_soft.ly3 < g_prim.drawY)
+ return;
+ if (g_prim.drawY >= g_prim.drawH)
+ return;
+ if (g_prim.drawX >= g_prim.drawW)
+ return;
+
+ if (!SetupSections_F4(g_soft.lx0, g_soft.ly0, g_soft.lx1, g_soft.ly1,
+ g_soft.lx2, g_soft.ly2, g_soft.lx3, g_soft.ly3))
+ return;
+
+ ymax = g_soft.Ymax;
+
+ for (ymin = g_soft.Ymin; ymin < g_prim.drawY; ymin++)
+ if (NextRow_F4())
+ return;
+
+ color = ((rgb & 0x00f80000) >> 9) | ((rgb & 0x0000f800) >> 6) | ((rgb
+ & 0x000000f8) >> 3);
+ lcolor = g_draw.lSetMask | (((uint32_t) (color)) << 16) | color;
+
+#ifdef FASTSOLID
+
+ if (!g_draw.bCheckMask && !g_soft.DrawSemiTrans) {
+ color |= g_draw.sSetMask;
+ for (i = ymin; i <= ymax; i++) {
+ xmin = left_x >> 16;
+ if (g_prim.drawX > xmin)
+ xmin = g_prim.drawX;
+ xmax = (right_x >> 16) - 1;
+ if (g_prim.drawW < xmax)
+ xmax = g_prim.drawW;
+
+ for (j = xmin; j < xmax; j += 2) {
+ PUTLE32(((uint32_t *)&g_gpu.psx_vram.u16[(i<<10)+j]), lcolor);
+ }
+ if (j == xmax)
+ PUTLE16(&g_gpu.psx_vram.u16[(i<<10)+j], color);
+
+ if (NextRow_F4())
+ return;
+ }
+ return;
+ }
+
+#endif
+
+ for (i = ymin; i <= ymax; i++) {
+ xmin = left_x >> 16;
+ if (g_prim.drawX > xmin)
+ xmin = g_prim.drawX;
+ xmax = (right_x >> 16) - 1;
+ if (g_prim.drawW < xmax)
+ xmax = g_prim.drawW;
+
+ for (j = xmin; j < xmax; j += 2) {
+ GetShadeTransCol32((uint32_t *) &g_gpu.psx_vram.u16[(i << 10) + j],
+ lcolor);
+ }
+ if (j == xmax)
+ GetShadeTransCol(&g_gpu.psx_vram.u16[(i << 10) + j], color);
+
+ if (NextRow_F4())
+ return;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+// POLY 3/4 F-SHADED TEX PAL 4
+////////////////////////////////////////////////////////////////////////
+
+void drawPoly3TEx4(short x1, short y1, short x2, short y2, short x3, short y3,
+ short tx1, short ty1, short tx2, short ty2, short tx3, short ty3,
+ short clX, short clY) {
+ int i, j, xmin, xmax, ymin, ymax;
+ int32_t difX, difY, difX2, difY2;
+ int32_t posX, posY, YAdjust, XAdjust;
+ int32_t clutP;
+ short tC1, tC2;
+
+ if (x1 > g_prim.drawW && x2 > g_prim.drawW && x3 > g_prim.drawW)
+ return;
+ if (y1 > g_prim.drawH && y2 > g_prim.drawH && y3 > g_prim.drawH)
+ return;
+ if (x1 < g_prim.drawX && x2 < g_prim.drawX && x3 < g_prim.drawX)
+ return;
+ if (y1 < g_prim.drawY && y2 < g_prim.drawY && y3 < g_prim.drawY)
+ return;
+ if (g_prim.drawY >= g_prim.drawH)
+ return;
+ if (g_prim.drawX >= g_prim.drawW)
+ return;
+
+ if (!SetupSections_FT(x1, y1, x2, y2, x3, y3, tx1, ty1, tx2, ty2, tx3, ty3))
+ return;
+
+ ymax = g_soft.Ymax;
+
+ for (ymin = g_soft.Ymin; ymin < g_prim.drawY; ymin++)
+ if (NextRow_FT())
+ return;
+
+ clutP = (clY << 10) + clX;
+
+ YAdjust = ((g_soft.GlobalTextAddrY) << 11) + (g_soft.GlobalTextAddrX << 1);
+
+ difX = delta_right_u;
+ difX2 = difX << 1;
+ difY = delta_right_v;
+ difY2 = difY << 1;
+
+#ifdef FASTSOLID
+
+ if (!g_draw.bCheckMask && !g_soft.DrawSemiTrans) {
+ for (i = ymin; i <= ymax; i++) {
+ xmin = (left_x >> 16);
+ xmax = (right_x >> 16) - 1; //!!!!!!!!!!!!!!!!
+ if (g_prim.drawW < xmax)
+ xmax = g_prim.drawW;
+
+ if (xmax >= xmin) {
+ posX = left_u;
+ posY = left_v;
+
+ if (xmin < g_prim.drawX) {
+ j = g_prim.drawX - xmin;
+ xmin = g_prim.drawX;
+ posX += j * difX;
+ posY += j * difY;
+ }
+
+ for (j = xmin; j < xmax; j += 2) {
+ XAdjust = (posX >> 16);
+ tC1
+ = g_gpu.psx_vram.u8[((posY >> 5)
+ & (int32_t) 0xFFFFF800) + YAdjust
+ + (XAdjust >> 1)];
+ tC1 = (tC1 >> ((XAdjust & 1) << 2)) & 0xf;
+ XAdjust = ((posX + difX) >> 16);
+ tC2 = g_gpu.psx_vram.u8[(((posY + difY) >> 5)
+ & (int32_t) 0xFFFFF800) + YAdjust + (XAdjust >> 1)];
+ tC2 = (tC2 >> ((XAdjust & 1) << 2)) & 0xf;
+
+ GetTextureTransColG32_S(
+ (uint32_t *) &g_gpu.psx_vram.u16[(i << 10) + j],
+ GETLE16(&g_gpu.psx_vram.u16[clutP+tC1])
+ | ((int32_t) GETLE16(&g_gpu.psx_vram.u16[clutP+tC2]))
+ << 16);
+
+ posX += difX2;
+ posY += difY2;
+ }
+ if (j == xmax) {
+ XAdjust = (posX >> 16);
+ tC1
+ = g_gpu.psx_vram.u8[((posY >> 5)
+ & (int32_t) 0xFFFFF800) + YAdjust
+ + (XAdjust >> 1)];
+ tC1 = (tC1 >> ((XAdjust & 1) << 2)) & 0xf;
+ GetTextureTransColG_S(&g_gpu.psx_vram.u16[(i << 10) + j],
+ GETLE16(&g_gpu.psx_vram.u16[clutP+tC1]));
+ }
+ }
+ if (NextRow_FT()) {
+ return;
+ }
+ }
+ return;
+ }
+
+#endif
+
+ for (i = ymin; i <= ymax; i++) {
+ xmin = (left_x >> 16);
+ xmax = (right_x >> 16) - 1; //!!!!!!!!!!!!!!!!!!
+ if (g_prim.drawW < xmax)
+ xmax = g_prim.drawW;
+
+ if (xmax >= xmin) {
+ posX = left_u;
+ posY = left_v;
+
+ if (xmin < g_prim.drawX) {
+ j = g_prim.drawX - xmin;
+ xmin = g_prim.drawX;
+ posX += j * difX;
+ posY += j * difY;
+ }
+
+ for (j = xmin; j < xmax; j += 2) {
+ XAdjust = (posX >> 16);
+ tC1 = g_gpu.psx_vram.u8[((posY >> 5) & (int32_t) 0xFFFFF800)
+ + YAdjust + (XAdjust >> 1)];
+ tC1 = (tC1 >> ((XAdjust & 1) << 2)) & 0xf;
+ XAdjust = ((posX + difX) >> 16);
+ tC2 = g_gpu.psx_vram.u8[(((posY + difY) >> 5)
+ & (int32_t) 0xFFFFF800) + YAdjust + (XAdjust >> 1)];
+ tC2 = (tC2 >> ((XAdjust & 1) << 2)) & 0xf;
+
+ GetTextureTransColG32(
+ (uint32_t *) &g_gpu.psx_vram.u16[(i << 10) + j],
+ GETLE16(&g_gpu.psx_vram.u16[clutP+tC1])
+ | ((int32_t) GETLE16(&g_gpu.psx_vram.u16[clutP+tC2]))
+ << 16);
+
+ posX += difX2;
+ posY += difY2;
+ }
+ if (j == xmax) {
+ XAdjust = (posX >> 16);
+ tC1 = g_gpu.psx_vram.u8[((posY >> 5) & (int32_t) 0xFFFFF800)
+ + YAdjust + (XAdjust >> 1)];
+ tC1 = (tC1 >> ((XAdjust & 1) << 2)) & 0xf;
+ GetTextureTransColG(&g_gpu.psx_vram.u16[(i << 10) + j],
+ GETLE16(&g_gpu.psx_vram.u16[clutP+tC1]));
+ }
+ }
+ if (NextRow_FT()) {
+ return;
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void drawPoly3TEx4_IL(short x1, short y1, short x2, short y2, short x3,
+ short y3, short tx1, short ty1, short tx2, short ty2, short tx3,
+ short ty3, short clX, short clY) {
+ int i, j, xmin, xmax, ymin, ymax, n_xi, n_yi, TXV;
+ int32_t difX, difY, difX2, difY2;
+ int32_t posX, posY, YAdjust, XAdjust;
+ int32_t clutP;
+ short tC1, tC2;
+
+ if (x1 > g_prim.drawW && x2 > g_prim.drawW && x3 > g_prim.drawW)
+ return;
+ if (y1 > g_prim.drawH && y2 > g_prim.drawH && y3 > g_prim.drawH)
+ return;
+ if (x1 < g_prim.drawX && x2 < g_prim.drawX && x3 < g_prim.drawX)
+ return;
+ if (y1 < g_prim.drawY && y2 < g_prim.drawY && y3 < g_prim.drawY)
+ return;
+ if (g_prim.drawY >= g_prim.drawH)
+ return;
+ if (g_prim.drawX >= g_prim.drawW)
+ return;
+
+ if (!SetupSections_FT(x1, y1, x2, y2, x3, y3, tx1, ty1, tx2, ty2, tx3, ty3))
+ return;
+
+ ymax = g_soft.Ymax;
+
+ for (ymin = g_soft.Ymin; ymin < g_prim.drawY; ymin++)
+ if (NextRow_FT())
+ return;
+
+ clutP = (clY << 10) + clX;
+
+ YAdjust = (g_soft.GlobalTextAddrY << 10) + g_soft.GlobalTextAddrX;
+
+ difX = delta_right_u;
+ difX2 = difX << 1;
+ difY = delta_right_v;
+ difY2 = difY << 1;
+
+#ifdef FASTSOLID
+
+ if (!g_draw.bCheckMask && !g_soft.DrawSemiTrans) {
+ for (i = ymin; i <= ymax; i++) {
+ xmin = (left_x >> 16);
+ xmax = (right_x >> 16) - 1;
+ if (g_prim.drawW < xmax)
+ xmax = g_prim.drawW;
+
+ if (xmax >= xmin) {
+ posX = left_u;
+ posY = left_v;
+
+ if (xmin < g_prim.drawX) {
+ j = g_prim.drawX - xmin;
+ xmin = g_prim.drawX;
+ posX += j * difX;
+ posY += j * difY;
+ }
+
+ for (j = xmin; j < xmax; j += 2) {
+ XAdjust = (posX >> 16);
+
+ TXV = posY >> 16;
+ n_xi = ((XAdjust >> 2) & ~0x3c) + ((TXV << 2) & 0x3c);
+ n_yi = (TXV & ~0xf) + ((XAdjust >> 4) & 0xf);
+
+ tC1
+ = (GETLE16(&g_gpu.psx_vram.u16[(n_yi<<10)+YAdjust+n_xi])
+ >> ((XAdjust & 0x03) << 2)) & 0x0f;
+
+ XAdjust = ((posX + difX) >> 16);
+
+ TXV = (posY + difY) >> 16;
+ n_xi = ((XAdjust >> 2) & ~0x3c) + ((TXV << 2) & 0x3c);
+ n_yi = (TXV & ~0xf) + ((XAdjust >> 4) & 0xf);
+
+ tC2
+ = (GETLE16(&g_gpu.psx_vram.u16[(n_yi<<10)+YAdjust+n_xi])
+ >> ((XAdjust & 0x03) << 2)) & 0x0f;
+
+ GetTextureTransColG32_S(
+ (uint32_t *) &g_gpu.psx_vram.u16[(i << 10) + j],
+ GETLE16(&g_gpu.psx_vram.u16[clutP+tC1])
+ | ((int32_t) GETLE16(&g_gpu.psx_vram.u16[clutP+tC2]))
+ << 16);
+
+ posX += difX2;
+ posY += difY2;
+ }
+ if (j == xmax) {
+ XAdjust = (posX >> 16);
+
+ TXV = posY >> 16;
+ n_xi = ((XAdjust >> 2) & ~0x3c) + ((TXV << 2) & 0x3c);
+ n_yi = (TXV & ~0xf) + ((XAdjust >> 4) & 0xf);
+
+ tC1
+ = (GETLE16(&g_gpu.psx_vram.u16[(n_yi<<10)+YAdjust+n_xi])
+ >> ((XAdjust & 0x03) << 2)) & 0x0f;
+
+ GetTextureTransColG_S(&g_gpu.psx_vram.u16[(i << 10) + j],
+ GETLE16(&g_gpu.psx_vram.u16[clutP+tC1]));
+ }
+ }
+ if (NextRow_FT()) {
+ return;
+ }
+ }
+ return;
+ }
+
+#endif
+
+ for (i = ymin; i <= ymax; i++) {
+ xmin = (left_x >> 16);
+ xmax = (right_x >> 16) - 1; //!!!!!!!!!!!!!!!!!!
+ if (g_prim.drawW < xmax)
+ xmax = g_prim.drawW;
+
+ if (xmax >= xmin) {
+ posX = left_u;
+ posY = left_v;
+
+ if (xmin < g_prim.drawX) {
+ j = g_prim.drawX - xmin;
+ xmin = g_prim.drawX;
+ posX += j * difX;
+ posY += j * difY;
+ }
+
+ for (j = xmin; j < xmax; j += 2) {
+ XAdjust = (posX >> 16);
+
+ TXV = posY >> 16;
+ n_xi = ((XAdjust >> 2) & ~0x3c) + ((TXV << 2) & 0x3c);
+ n_yi = (TXV & ~0xf) + ((XAdjust >> 4) & 0xf);
+
+ tC1 = (GETLE16(&g_gpu.psx_vram.u16[(n_yi<<10)+YAdjust+n_xi])
+ >> ((XAdjust & 0x03) << 2)) & 0x0f;
+
+ XAdjust = ((posX + difX) >> 16);
+
+ TXV = (posY + difY) >> 16;
+ n_xi = ((XAdjust >> 2) & ~0x3c) + ((TXV << 2) & 0x3c);
+ n_yi = (TXV & ~0xf) + ((XAdjust >> 4) & 0xf);
+
+ tC2 = (GETLE16(&g_gpu.psx_vram.u16[(n_yi<<10)+YAdjust+n_xi])
+ >> ((XAdjust & 0x03) << 2)) & 0x0f;
+
+ GetTextureTransColG32(
+ (uint32_t *) &g_gpu.psx_vram.u16[(i << 10) + j],
+ GETLE16(&g_gpu.psx_vram.u16[clutP+tC1])
+ | ((int32_t) GETLE16(&g_gpu.psx_vram.u16[clutP+tC2]))
+ << 16);
+
+ posX += difX2;
+ posY += difY2;
+ }
+ if (j == xmax) {
+ XAdjust = (posX >> 16);
+
+ TXV = posY >> 16;
+ n_xi = ((XAdjust >> 2) & ~0x3c) + ((TXV << 2) & 0x3c);
+ n_yi = (TXV & ~0xf) + ((XAdjust >> 4) & 0xf);
+
+ tC1 = (GETLE16(&g_gpu.psx_vram.u16[(n_yi<<10)+YAdjust+n_xi])
+ >> ((XAdjust & 0x03) << 2)) & 0x0f;
+
+ GetTextureTransColG(&g_gpu.psx_vram.u16[(i << 10) + j],
+ GETLE16(&g_gpu.psx_vram.u16[clutP+tC1]));
+ }
+ }
+ if (NextRow_FT()) {
+ return;
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void drawPoly3TEx4_TW(short x1, short y1, short x2, short y2, short x3,
+ short y3, short tx1, short ty1, short tx2, short ty2, short tx3,
+ short ty3, short clX, short clY) {
+ int i, j, xmin, xmax, ymin, ymax;
+ int32_t difX, difY, difX2, difY2;
+ int32_t posX, posY, YAdjust, XAdjust;
+ int32_t clutP;
+ short tC1, tC2;
+
+ if (x1 > g_prim.drawW && x2 > g_prim.drawW && x3 > g_prim.drawW)
+ return;
+ if (y1 > g_prim.drawH && y2 > g_prim.drawH && y3 > g_prim.drawH)
+ return;
+ if (x1 < g_prim.drawX && x2 < g_prim.drawX && x3 < g_prim.drawX)
+ return;
+ if (y1 < g_prim.drawY && y2 < g_prim.drawY && y3 < g_prim.drawY)
+ return;
+ if (g_prim.drawY >= g_prim.drawH)
+ return;
+ if (g_prim.drawX >= g_prim.drawW)
+ return;
+
+ if (!SetupSections_FT(x1, y1, x2, y2, x3, y3, tx1, ty1, tx2, ty2, tx3, ty3))
+ return;
+
+ ymax = g_soft.Ymax;
+
+ for (ymin = g_soft.Ymin; ymin < g_prim.drawY; ymin++)
+ if (NextRow_FT())
+ return;
+
+ clutP = (clY << 10) + clX;
+
+ YAdjust = ((g_soft.GlobalTextAddrY) << 11) + (g_soft.GlobalTextAddrX << 1);
+ YAdjust += (g_prim.TWin.Position.y0 << 11) + (g_prim.TWin.Position.x0 >> 1);
+
+ difX = delta_right_u;
+ difX2 = difX << 1;
+ difY = delta_right_v;
+ difY2 = difY << 1;
+
+#ifdef FASTSOLID
+
+ if (!g_draw.bCheckMask && !g_soft.DrawSemiTrans) {
+ for (i = ymin; i <= ymax; i++) {
+ xmin = (left_x >> 16);
+ xmax = (right_x >> 16);//-1; //!!!!!!!!!!!!!!!!
+ if (xmax > xmin)
+ xmax--;
+
+ if (g_prim.drawW < xmax)
+ xmax = g_prim.drawW;
+
+ if (xmax >= xmin) {
+ posX = left_u;
+ posY = left_v;
+
+ if (xmin < g_prim.drawX) {
+ j = g_prim.drawX - xmin;
+ xmin = g_prim.drawX;
+ posX += j * difX;
+ posY += j * difY;
+ }
+
+ for (j = xmin; j < xmax; j += 2) {
+ XAdjust = (posX >> 16) % g_prim.TWin.Position.x1;
+ tC1 = g_gpu.psx_vram.u8[(((posY >> 16)
+ % g_prim.TWin.Position.y1) << 11) + YAdjust
+ + (XAdjust >> 1)];
+ tC1 = (tC1 >> ((XAdjust & 1) << 2)) & 0xf;
+ XAdjust = ((posX + difX) >> 16) % g_prim.TWin.Position.x1;
+ tC2 = g_gpu.psx_vram.u8[((((posY + difY) >> 16)
+ % g_prim.TWin.Position.y1) << 11) + YAdjust
+ + (XAdjust >> 1)];
+ tC2 = (tC2 >> ((XAdjust & 1) << 2)) & 0xf;
+
+ GetTextureTransColG32_S(
+ (uint32_t *) &g_gpu.psx_vram.u16[(i << 10) + j],
+ GETLE16(&g_gpu.psx_vram.u16[clutP+tC1])
+ | ((int32_t) GETLE16(&g_gpu.psx_vram.u16[clutP+tC2]))
+ << 16);
+
+ posX += difX2;
+ posY += difY2;
+ }
+ if (j == xmax) {
+ XAdjust = (posX >> 16) % g_prim.TWin.Position.x1;
+ tC1 = g_gpu.psx_vram.u8[(((posY >> 16)
+ % g_prim.TWin.Position.y1) << 11) + YAdjust
+ + (XAdjust >> 1)];
+ tC1 = (tC1 >> ((XAdjust & 1) << 2)) & 0xf;
+ GetTextureTransColG_S(&g_gpu.psx_vram.u16[(i << 10) + j],
+ GETLE16(&g_gpu.psx_vram.u16[clutP+tC1]));
+ }
+ }
+ if (NextRow_FT()) {
+ return;
+ }
+ }
+ return;
+ }
+
+#endif
+
+ for (i = ymin; i <= ymax; i++) {
+ xmin = (left_x >> 16);
+ xmax = (right_x >> 16) - 1; //!!!!!!!!!!!!!!!!!!
+ if (g_prim.drawW < xmax)
+ xmax = g_prim.drawW;
+
+ if (xmax >= xmin) {
+ posX = left_u;
+ posY = left_v;
+
+ if (xmin < g_prim.drawX) {
+ j = g_prim.drawX - xmin;
+ xmin = g_prim.drawX;
+ posX += j * difX;
+ posY += j * difY;
+ }
+
+ for (j = xmin; j < xmax; j += 2) {
+ XAdjust = (posX >> 16) % g_prim.TWin.Position.x1;
+ tC1 = g_gpu.psx_vram.u8[(((posY >> 16)
+ % g_prim.TWin.Position.y1) << 11) + YAdjust + (XAdjust
+ >> 1)];
+ tC1 = (tC1 >> ((XAdjust & 1) << 2)) & 0xf;
+ XAdjust = ((posX + difX) >> 16) % g_prim.TWin.Position.x1;
+ tC2 = g_gpu.psx_vram.u8[((((posY + difY) >> 16)
+ % g_prim.TWin.Position.y1) << 11) + YAdjust + (XAdjust
+ >> 1)];
+ tC2 = (tC2 >> ((XAdjust & 1) << 2)) & 0xf;
+
+ GetTextureTransColG32(
+ (uint32_t *) &g_gpu.psx_vram.u16[(i << 10) + j],
+ GETLE16(&g_gpu.psx_vram.u16[clutP+tC1])
+ | ((int32_t) GETLE16(&g_gpu.psx_vram.u16[clutP+tC2]))
+ << 16);
+
+ posX += difX2;
+ posY += difY2;
+ }
+ if (j == xmax) {
+ XAdjust = (posX >> 16) % g_prim.TWin.Position.x1;
+ tC1 = g_gpu.psx_vram.u8[(((posY >> 16)
+ % g_prim.TWin.Position.y1) << 11) + YAdjust + (XAdjust
+ >> 1)];
+ tC1 = (tC1 >> ((XAdjust & 1) << 2)) & 0xf;
+ GetTextureTransColG(&g_gpu.psx_vram.u16[(i << 10) + j],
+ GETLE16(&g_gpu.psx_vram.u16[clutP+tC1]));
+ }
+ }
+ if (NextRow_FT()) {
+ return;
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+#ifdef POLYQUAD3
+
+void drawPoly4TEx4_TRI(short x1, short y1, short x2, short y2, short x3,
+ short y3, short x4, short y4, short tx1, short ty1, short tx2,
+ short ty2, short tx3, short ty3, short tx4, short ty4, short clX,
+ short clY) {
+ drawPoly3TEx4(x2, y2, x3, y3, x4, y4, tx2, ty2, tx3, ty3, tx4, ty4, clX,
+ clY);
+ drawPoly3TEx4(x1, y1, x2, y2, x4, y4, tx1, ty1, tx2, ty2, tx4, ty4, clX,
+ clY);
+}
+
+#endif
+
+// more exact:
+
+void drawPoly4TEx4(short x1, short y1, short x2, short y2, short x3, short y3,
+ short x4, short y4, short tx1, short ty1, short tx2, short ty2,
+ short tx3, short ty3, short tx4, short ty4, short clX, short clY) {
+ int32_t num;
+ int32_t i, j, xmin, xmax, ymin, ymax;
+ int32_t difX, difY, difX2, difY2;
+ int32_t posX, posY, YAdjust, clutP, XAdjust;
+ short tC1, tC2;
+
+ if (x1 > g_prim.drawW && x2 > g_prim.drawW && x3 > g_prim.drawW && x4
+ > g_prim.drawW)
+ return;
+ if (y1 > g_prim.drawH && y2 > g_prim.drawH && y3 > g_prim.drawH && y4
+ > g_prim.drawH)
+ return;
+ if (x1 < g_prim.drawX && x2 < g_prim.drawX && x3 < g_prim.drawX && x4
+ < g_prim.drawX)
+ return;
+ if (y1 < g_prim.drawY && y2 < g_prim.drawY && y3 < g_prim.drawY && y4
+ < g_prim.drawY)
+ return;
+ if (g_prim.drawY >= g_prim.drawH)
+ return;
+ if (g_prim.drawX >= g_prim.drawW)
+ return;
+
+ if (!SetupSections_FT4(x1, y1, x2, y2, x3, y3, x4, y4, tx1, ty1, tx2, ty2,
+ tx3, ty3, tx4, ty4))
+ return;
+
+ ymax = g_soft.Ymax;
+
+ for (ymin = g_soft.Ymin; ymin < g_prim.drawY; ymin++)
+ if (NextRow_FT4())
+ return;
+
+ clutP = (clY << 10) + clX;
+
+ YAdjust = ((g_soft.GlobalTextAddrY) << 11) + (g_soft.GlobalTextAddrX << 1);
+
+#ifdef FASTSOLID
+
+ if (!g_draw.bCheckMask && !g_soft.DrawSemiTrans) {
+ for (i = ymin; i <= ymax; i++) {
+ xmin = (left_x >> 16);
+ xmax = (right_x >> 16);
+
+ if (xmax >= xmin) {
+ posX = left_u;
+ posY = left_v;
+
+ num = (xmax - xmin);
+ if (num == 0)
+ num = 1;
+ difX = (right_u - posX) / num;
+ difY = (right_v - posY) / num;
+ difX2 = difX << 1;
+ difY2 = difY << 1;
+
+ if (xmin < g_prim.drawX) {
+ j = g_prim.drawX - xmin;
+ xmin = g_prim.drawX;
+ posX += j * difX;
+ posY += j * difY;
+ }
+ xmax--;
+ if (g_prim.drawW < xmax)
+ xmax = g_prim.drawW;
+
+ for (j = xmin; j < xmax; j += 2) {
+ XAdjust = (posX >> 16);
+ tC1
+ = g_gpu.psx_vram.u8[((posY >> 5)
+ & (int32_t) 0xFFFFF800) + YAdjust
+ + (XAdjust >> 1)];
+ tC1 = (tC1 >> ((XAdjust & 1) << 2)) & 0xf;
+ XAdjust = ((posX + difX) >> 16);
+ tC2 = g_gpu.psx_vram.u8[(((posY + difY) >> 5)
+ & (int32_t) 0xFFFFF800) + YAdjust + (XAdjust >> 1)];
+ tC2 = (tC2 >> ((XAdjust & 1) << 2)) & 0xf;
+
+ GetTextureTransColG32_S(
+ (uint32_t *) &g_gpu.psx_vram.u16[(i << 10) + j],
+ GETLE16(&g_gpu.psx_vram.u16[clutP+tC1])
+ | ((int32_t) GETLE16(&g_gpu.psx_vram.u16[clutP+tC2]))
+ << 16);
+ posX += difX2;
+ posY += difY2;
+ }
+ if (j == xmax) {
+ XAdjust = (posX >> 16);
+ tC1
+ = g_gpu.psx_vram.u8[((posY >> 5)
+ & (int32_t) 0xFFFFF800) + YAdjust
+ + (XAdjust >> 1)];
+ tC1 = (tC1 >> ((XAdjust & 1) << 2)) & 0xf;
+ GetTextureTransColG_S(&g_gpu.psx_vram.u16[(i << 10) + j],
+ GETLE16(&g_gpu.psx_vram.u16[clutP+tC1]));
+ }
+
+ }
+ if (NextRow_FT4())
+ return;
+ }
+ return;
+ }
+
+#endif
+
+ for (i = ymin; i <= ymax; i++) {
+ xmin = (left_x >> 16);
+ xmax = (right_x >> 16);
+
+ if (xmax >= xmin) {
+ posX = left_u;
+ posY = left_v;
+
+ num = (xmax - xmin);
+ if (num == 0)
+ num = 1;
+ difX = (right_u - posX) / num;
+ difY = (right_v - posY) / num;
+ difX2 = difX << 1;
+ difY2 = difY << 1;
+
+ if (xmin < g_prim.drawX) {
+ j = g_prim.drawX - xmin;
+ xmin = g_prim.drawX;
+ posX += j * difX;
+ posY += j * difY;
+ }
+ xmax--;
+ if (g_prim.drawW < xmax)
+ xmax = g_prim.drawW;
+
+ for (j = xmin; j < xmax; j += 2) {
+ XAdjust = (posX >> 16);
+ tC1 = g_gpu.psx_vram.u8[((posY >> 5) & (int32_t) 0xFFFFF800)
+ + YAdjust + (XAdjust >> 1)];
+ tC1 = (tC1 >> ((XAdjust & 1) << 2)) & 0xf;
+ XAdjust = ((posX + difX) >> 16);
+ tC2 = g_gpu.psx_vram.u8[(((posY + difY) >> 5)
+ & (int32_t) 0xFFFFF800) + YAdjust + (XAdjust >> 1)];
+ tC2 = (tC2 >> ((XAdjust & 1) << 2)) & 0xf;
+
+ GetTextureTransColG32(
+ (uint32_t *) &g_gpu.psx_vram.u16[(i << 10) + j],
+ GETLE16(&g_gpu.psx_vram.u16[clutP+tC1])
+ | ((int32_t) GETLE16(&g_gpu.psx_vram.u16[clutP+tC2]))
+ << 16);
+ posX += difX2;
+ posY += difY2;
+ }
+ if (j == xmax) {
+ XAdjust = (posX >> 16);
+ tC1 = g_gpu.psx_vram.u8[((posY >> 5) & (int32_t) 0xFFFFF800)
+ + YAdjust + (XAdjust >> 1)];
+ tC1 = (tC1 >> ((XAdjust & 1) << 2)) & 0xf;
+ GetTextureTransColG(&g_gpu.psx_vram.u16[(i << 10) + j],
+ GETLE16(&g_gpu.psx_vram.u16[clutP+tC1]));
+ }
+ }
+ if (NextRow_FT4())
+ return;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void drawPoly4TEx4_IL(short x1, short y1, short x2, short y2, short x3,
+ short y3, short x4, short y4, short tx1, short ty1, short tx2,
+ short ty2, short tx3, short ty3, short tx4, short ty4, short clX,
+ short clY) {
+ int32_t num;
+ int32_t i, j = 0, xmin, xmax, ymin, ymax, n_xi, n_yi, TXV;
+ int32_t difX, difY, difX2, difY2;
+ int32_t posX = 0, posY = 0, YAdjust, clutP, XAdjust;
+ short tC1, tC2;
+
+ if (x1 > g_prim.drawW && x2 > g_prim.drawW && x3 > g_prim.drawW && x4
+ > g_prim.drawW)
+ return;
+ if (y1 > g_prim.drawH && y2 > g_prim.drawH && y3 > g_prim.drawH && y4
+ > g_prim.drawH)
+ return;
+ if (x1 < g_prim.drawX && x2 < g_prim.drawX && x3 < g_prim.drawX && x4
+ < g_prim.drawX)
+ return;
+ if (y1 < g_prim.drawY && y2 < g_prim.drawY && y3 < g_prim.drawY && y4
+ < g_prim.drawY)
+ return;
+ if (g_prim.drawY >= g_prim.drawH)
+ return;
+ if (g_prim.drawX >= g_prim.drawW)
+ return;
+
+ if (!SetupSections_FT4(x1, y1, x2, y2, x3, y3, x4, y4, tx1, ty1, tx2, ty2,
+ tx3, ty3, tx4, ty4))
+ return;
+
+ ymax = g_soft.Ymax;
+
+ for (ymin = g_soft.Ymin; ymin < g_prim.drawY; ymin++)
+ if (NextRow_FT4())
+ return;
+
+ clutP = (clY << 10) + clX;
+
+ YAdjust = ((g_soft.GlobalTextAddrY) << 10) + g_soft.GlobalTextAddrX;
+
+#ifdef FASTSOLID
+
+ if (!g_draw.bCheckMask && !g_soft.DrawSemiTrans) {
+ for (i = ymin; i <= ymax; i++) {
+ xmin = (left_x >> 16);
+ xmax = (right_x >> 16);
+
+ if (xmax >= xmin) {
+ posX = left_u;
+ posY = left_v;
+
+ num = (xmax - xmin);
+ if (num == 0)
+ num = 1;
+ difX = (right_u - posX) / num;
+ difY = (right_v - posY) / num;
+ difX2 = difX << 1;
+ difY2 = difY << 1;
+
+ if (xmin < g_prim.drawX) {
+ j = g_prim.drawX - xmin;
+ xmin = g_prim.drawX;
+ posX += j * difX;
+ posY += j * difY;
+ }
+ xmax--;
+ if (g_prim.drawW < xmax)
+ xmax = g_prim.drawW;
+
+ for (j = xmin; j < xmax; j += 2) {
+ XAdjust = (posX >> 16);
+
+ TXV = posY >> 16;
+ n_xi = ((XAdjust >> 2) & ~0x3c) + ((TXV << 2) & 0x3c);
+ n_yi = (TXV & ~0xf) + ((XAdjust >> 4) & 0xf);
+
+ tC1
+ = (GETLE16(&g_gpu.psx_vram.u16[(n_yi<<10)+YAdjust+n_xi])
+ >> ((XAdjust & 0x03) << 2)) & 0x0f;
+
+ XAdjust = ((posX + difX) >> 16);
+
+ TXV = (posY + difY) >> 16;
+ n_xi = ((XAdjust >> 2) & ~0x3c) + ((TXV << 2) & 0x3c);
+ n_yi = (TXV & ~0xf) + ((XAdjust >> 4) & 0xf);
+
+ tC2
+ = (GETLE16(&g_gpu.psx_vram.u16[(n_yi<<10)+YAdjust+n_xi])
+ >> ((XAdjust & 0x03) << 2)) & 0x0f;
+
+ GetTextureTransColG32_S(
+ (uint32_t *) &g_gpu.psx_vram.u16[(i << 10) + j],
+ GETLE16(&g_gpu.psx_vram.u16[clutP+tC1])
+ | ((int32_t) GETLE16(&g_gpu.psx_vram.u16[clutP+tC2]))
+ << 16);
+ posX += difX2;
+ posY += difY2;
+ }
+ posX += difX2;
+ posY += difY2;
+ }
+
+ if (j == xmax) {
+ XAdjust = (posX >> 16);
+ TXV = posY >> 16;
+ n_xi = ((XAdjust >> 2) & ~0x3c) + ((TXV << 2) & 0x3c);
+ n_yi = (TXV & ~0xf) + ((XAdjust >> 4) & 0xf);
+
+ tC1 = (GETLE16(&g_gpu.psx_vram.u16[(n_yi<<10)+YAdjust+n_xi])
+ >> ((XAdjust & 0x03) << 2)) & 0x0f;
+
+ GetTextureTransColG_S(&g_gpu.psx_vram.u16[(i << 10) + j],
+ GETLE16(&g_gpu.psx_vram.u16[clutP+tC1]));
+ }
+
+ }
+ if (NextRow_FT4())
+ return;
+ }
+#endif
+
+ for (i = ymin; i <= ymax; i++) {
+ xmin = (left_x >> 16);
+ xmax = (right_x >> 16);
+
+ if (xmax >= xmin) {
+ posX = left_u;
+ posY = left_v;
+
+ num = (xmax - xmin);
+ if (num == 0)
+ num = 1;
+ difX = (right_u - posX) / num;
+ difY = (right_v - posY) / num;
+ difX2 = difX << 1;
+ difY2 = difY << 1;
+
+ if (xmin < g_prim.drawX) {
+ j = g_prim.drawX - xmin;
+ xmin = g_prim.drawX;
+ posX += j * difX;
+ posY += j * difY;
+ }
+ xmax--;
+ if (g_prim.drawW < xmax)
+ xmax = g_prim.drawW;
+
+ for (j = xmin; j < xmax; j += 2) {
+ XAdjust = (posX >> 16);
+
+ TXV = posY >> 16;
+ n_xi = ((XAdjust >> 2) & ~0x3c) + ((TXV << 2) & 0x3c);
+ n_yi = (TXV & ~0xf) + ((XAdjust >> 4) & 0xf);
+
+ tC1 = (GETLE16(&g_gpu.psx_vram.u16[(n_yi<<10)+YAdjust+n_xi])
+ >> ((XAdjust & 0x03) << 2)) & 0x0f;
+
+ XAdjust = ((posX + difX) >> 16);
+
+ TXV = (posY + difY) >> 16;
+ n_xi = ((XAdjust >> 2) & ~0x3c) + ((TXV << 2) & 0x3c);
+ n_yi = (TXV & ~0xf) + ((XAdjust >> 4) & 0xf);
+
+ tC2 = (GETLE16(&g_gpu.psx_vram.u16[(n_yi<<10)+YAdjust+n_xi])
+ >> ((XAdjust & 0x03) << 2)) & 0x0f;
+
+ GetTextureTransColG32(
+ (uint32_t *) &g_gpu.psx_vram.u16[(i << 10) + j],
+ GETLE16(&g_gpu.psx_vram.u16[clutP+tC1])
+ | ((int32_t) GETLE16(&g_gpu.psx_vram.u16[clutP+tC2]))
+ << 16);
+ posX += difX2;
+ posY += difY2;
+ }
+ if (j == xmax) {
+ XAdjust = (posX >> 16);
+ TXV = posY >> 16;
+ n_xi = ((XAdjust >> 2) & ~0x3c) + ((TXV << 2) & 0x3c);
+ n_yi = (TXV & ~0xf) + ((XAdjust >> 4) & 0xf);
+
+ tC1 = (GETLE16(&g_gpu.psx_vram.u16[(n_yi<<10)+YAdjust+n_xi])
+ >> ((XAdjust & 0x03) << 2)) & 0x0f;
+
+ GetTextureTransColG(&g_gpu.psx_vram.u16[(i << 10) + j],
+ GETLE16(&g_gpu.psx_vram.u16[clutP+tC1]));
+ }
+ }
+ if (NextRow_FT4())
+ return;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void drawPoly4TEx4_TW(short x1, short y1, short x2, short y2, short x3,
+ short y3, short x4, short y4, short tx1, short ty1, short tx2,
+ short ty2, short tx3, short ty3, short tx4, short ty4, short clX,
+ short clY) {
+ int32_t num;
+ int32_t i, j, xmin, xmax, ymin, ymax;
+ int32_t difX, difY, difX2, difY2;
+ int32_t posX, posY, YAdjust, clutP, XAdjust;
+ short tC1, tC2;
+
+ if (x1 > g_prim.drawW && x2 > g_prim.drawW && x3 > g_prim.drawW && x4
+ > g_prim.drawW)
+ return;
+ if (y1 > g_prim.drawH && y2 > g_prim.drawH && y3 > g_prim.drawH && y4
+ > g_prim.drawH)
+ return;
+ if (x1 < g_prim.drawX && x2 < g_prim.drawX && x3 < g_prim.drawX && x4
+ < g_prim.drawX)
+ return;
+ if (y1 < g_prim.drawY && y2 < g_prim.drawY && y3 < g_prim.drawY && y4
+ < g_prim.drawY)
+ return;
+ if (g_prim.drawY >= g_prim.drawH)
+ return;
+ if (g_prim.drawX >= g_prim.drawW)
+ return;
+
+ if (!SetupSections_FT4(x1, y1, x2, y2, x3, y3, x4, y4, tx1, ty1, tx2, ty2,
+ tx3, ty3, tx4, ty4))
+ return;
+
+ ymax = g_soft.Ymax;
+
+ for (ymin = g_soft.Ymin; ymin < g_prim.drawY; ymin++)
+ if (NextRow_FT4())
+ return;
+
+ clutP = (clY << 10) + clX;
+
+ YAdjust = ((g_soft.GlobalTextAddrY) << 11) + (g_soft.GlobalTextAddrX << 1);
+ YAdjust += (g_prim.TWin.Position.y0 << 11) + (g_prim.TWin.Position.x0 >> 1);
+
+#ifdef FASTSOLID
+
+ if (!g_draw.bCheckMask && !g_soft.DrawSemiTrans) {
+ for (i = ymin; i <= ymax; i++) {
+ xmin = (left_x >> 16);
+ xmax = (right_x >> 16);
+
+ if (xmax >= xmin) {
+ posX = left_u;
+ posY = left_v;
+
+ num = (xmax - xmin);
+ if (num == 0)
+ num = 1;
+ difX = (right_u - posX) / num;
+ difY = (right_v - posY) / num;
+ difX2 = difX << 1;
+ difY2 = difY << 1;
+
+ if (xmin < g_prim.drawX) {
+ j = g_prim.drawX - xmin;
+ xmin = g_prim.drawX;
+ posX += j * difX;
+ posY += j * difY;
+ }
+ xmax--;
+ if (g_prim.drawW < xmax)
+ xmax = g_prim.drawW;
+
+ for (j = xmin; j < xmax; j += 2) {
+ XAdjust = (posX >> 16) % g_prim.TWin.Position.x1;
+ tC1 = g_gpu.psx_vram.u8[(((posY >> 16)
+ % g_prim.TWin.Position.y1) << 11) + YAdjust
+ + (XAdjust >> 1)];
+ tC1 = (tC1 >> ((XAdjust & 1) << 2)) & 0xf;
+ XAdjust = ((posX + difX) >> 16) % g_prim.TWin.Position.x1;
+ tC2 = g_gpu.psx_vram.u8[((((posY + difY) >> 16)
+ % g_prim.TWin.Position.y1) << 11) + YAdjust
+ + (XAdjust >> 1)];
+ tC2 = (tC2 >> ((XAdjust & 1) << 2)) & 0xf;
+
+ GetTextureTransColG32_S(
+ (uint32_t *) &g_gpu.psx_vram.u16[(i << 10) + j],
+ GETLE16(&g_gpu.psx_vram.u16[clutP+tC1])
+ | ((int32_t) GETLE16(&g_gpu.psx_vram.u16[clutP+tC2]))
+ << 16);
+ posX += difX2;
+ posY += difY2;
+ }
+ if (j == xmax) {
+ XAdjust = (posX >> 16) % g_prim.TWin.Position.x1;
+ tC1 = g_gpu.psx_vram.u8[(((posY >> 16)
+ % g_prim.TWin.Position.y1) << 11) + YAdjust
+ + (XAdjust >> 1)];
+ tC1 = (tC1 >> ((XAdjust & 1) << 2)) & 0xf;
+ GetTextureTransColG_S(&g_gpu.psx_vram.u16[(i << 10) + j],
+ GETLE16(&g_gpu.psx_vram.u16[clutP+tC1]));
+ }
+ }
+ if (NextRow_FT4())
+ return;
+ }
+ return;
+ }
+
+#endif
+
+ for (i = ymin; i <= ymax; i++) {
+ xmin = (left_x >> 16);
+ xmax = (right_x >> 16);
+
+ if (xmax >= xmin) {
+ posX = left_u;
+ posY = left_v;
+
+ num = (xmax - xmin);
+ if (num == 0)
+ num = 1;
+ difX = (right_u - posX) / num;
+ difY = (right_v - posY) / num;
+ difX2 = difX << 1;
+ difY2 = difY << 1;
+
+ if (xmin < g_prim.drawX) {
+ j = g_prim.drawX - xmin;
+ xmin = g_prim.drawX;
+ posX += j * difX;
+ posY += j * difY;
+ }
+ xmax--;
+ if (g_prim.drawW < xmax)
+ xmax = g_prim.drawW;
+
+ for (j = xmin; j < xmax; j += 2) {
+ XAdjust = (posX >> 16) % g_prim.TWin.Position.x1;
+ tC1 = g_gpu.psx_vram.u8[(((posY >> 16)
+ % g_prim.TWin.Position.y1) << 11) + YAdjust + (XAdjust
+ >> 1)];
+ tC1 = (tC1 >> ((XAdjust & 1) << 2)) & 0xf;
+ XAdjust = ((posX + difX) >> 16) % g_prim.TWin.Position.x1;
+ tC2 = g_gpu.psx_vram.u8[((((posY + difY) >> 16)
+ % g_prim.TWin.Position.y1) << 11) + YAdjust + (XAdjust
+ >> 1)];
+ tC2 = (tC2 >> ((XAdjust & 1) << 2)) & 0xf;
+
+ GetTextureTransColG32(
+ (uint32_t *) &g_gpu.psx_vram.u16[(i << 10) + j],
+ GETLE16(&g_gpu.psx_vram.u16[clutP+tC1])
+ | ((int32_t) GETLE16(&g_gpu.psx_vram.u16[clutP+tC2]))
+ << 16);
+ posX += difX2;
+ posY += difY2;
+ }
+ if (j == xmax) {
+ XAdjust = (posX >> 16) % g_prim.TWin.Position.x1;
+ tC1 = g_gpu.psx_vram.u8[(((posY >> 16)
+ % g_prim.TWin.Position.y1) << 11) + YAdjust + (XAdjust
+ >> 1)];
+ tC1 = (tC1 >> ((XAdjust & 1) << 2)) & 0xf;
+ GetTextureTransColG(&g_gpu.psx_vram.u16[(i << 10) + j],
+ GETLE16(&g_gpu.psx_vram.u16[clutP+tC1]));
+ }
+ }
+ if (NextRow_FT4())
+ return;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void drawPoly4TEx4_TW_S(short x1, short y1, short x2, short y2, short x3,
+ short y3, short x4, short y4, short tx1, short ty1, short tx2,
+ short ty2, short tx3, short ty3, short tx4, short ty4, short clX,
+ short clY) {
+ int32_t num;
+ int32_t i, j, xmin, xmax, ymin, ymax;
+ int32_t difX, difY, difX2, difY2;
+ int32_t posX, posY, YAdjust, clutP, XAdjust;
+ short tC1, tC2;
+
+ if (x1 > g_prim.drawW && x2 > g_prim.drawW && x3 > g_prim.drawW && x4
+ > g_prim.drawW)
+ return;
+ if (y1 > g_prim.drawH && y2 > g_prim.drawH && y3 > g_prim.drawH && y4
+ > g_prim.drawH)
+ return;
+ if (x1 < g_prim.drawX && x2 < g_prim.drawX && x3 < g_prim.drawX && x4
+ < g_prim.drawX)
+ return;
+ if (y1 < g_prim.drawY && y2 < g_prim.drawY && y3 < g_prim.drawY && y4
+ < g_prim.drawY)
+ return;
+ if (g_prim.drawY >= g_prim.drawH)
+ return;
+ if (g_prim.drawX >= g_prim.drawW)
+ return;
+
+ if (!SetupSections_FT4(x1, y1, x2, y2, x3, y3, x4, y4, tx1, ty1, tx2, ty2,
+ tx3, ty3, tx4, ty4))
+ return;
+
+ ymax = g_soft.Ymax;
+
+ for (ymin = g_soft.Ymin; ymin < g_prim.drawY; ymin++)
+ if (NextRow_FT4())
+ return;
+
+ clutP = (clY << 10) + clX;
+
+ YAdjust = ((g_soft.GlobalTextAddrY) << 11) + (g_soft.GlobalTextAddrX << 1);
+ YAdjust += (g_prim.TWin.Position.y0 << 11) + (g_prim.TWin.Position.x0 >> 1);
+
+#ifdef FASTSOLID
+
+ if (!g_draw.bCheckMask && !g_soft.DrawSemiTrans) {
+ for (i = ymin; i <= ymax; i++) {
+ xmin = (left_x >> 16);
+ xmax = (right_x >> 16);
+
+ if (xmax >= xmin) {
+ posX = left_u;
+ posY = left_v;
+
+ num = (xmax - xmin);
+ if (num == 0)
+ num = 1;
+ difX = (right_u - posX) / num;
+ difY = (right_v - posY) / num;
+ difX2 = difX << 1;
+ difY2 = difY << 1;
+
+ if (xmin < g_prim.drawX) {
+ j = g_prim.drawX - xmin;
+ xmin = g_prim.drawX;
+ posX += j * difX;
+ posY += j * difY;
+ }
+ xmax--;
+ if (g_prim.drawW < xmax)
+ xmax = g_prim.drawW;
+
+ for (j = xmin; j < xmax; j += 2) {
+ XAdjust = (posX >> 16) % g_prim.TWin.Position.x1;
+ tC1 = g_gpu.psx_vram.u8[(((posY >> 16)
+ % g_prim.TWin.Position.y1) << 11) + YAdjust
+ + (XAdjust >> 1)];
+ tC1 = (tC1 >> ((XAdjust & 1) << 2)) & 0xf;
+ XAdjust = ((posX + difX) >> 16) % g_prim.TWin.Position.x1;
+ tC2 = g_gpu.psx_vram.u8[((((posY + difY) >> 16)
+ % g_prim.TWin.Position.y1) << 11) + YAdjust
+ + (XAdjust >> 1)];
+ tC2 = (tC2 >> ((XAdjust & 1) << 2)) & 0xf;
+
+ GetTextureTransColG32_S(
+ (uint32_t *) &g_gpu.psx_vram.u16[(i << 10) + j],
+ GETLE16(&g_gpu.psx_vram.u16[clutP+tC1])
+ | ((int32_t) GETLE16(&g_gpu.psx_vram.u16[clutP+tC2]))
+ << 16);
+ posX += difX2;
+ posY += difY2;
+ }
+ if (j == xmax) {
+ XAdjust = (posX >> 16) % g_prim.TWin.Position.x1;
+ tC1 = g_gpu.psx_vram.u8[(((posY >> 16)
+ % g_prim.TWin.Position.y1) << 11) + YAdjust
+ + (XAdjust >> 1)];
+ tC1 = (tC1 >> ((XAdjust & 1) << 2)) & 0xf;
+ GetTextureTransColG_S(&g_gpu.psx_vram.u16[(i << 10) + j],
+ GETLE16(&g_gpu.psx_vram.u16[clutP+tC1]));
+ }
+ }
+ if (NextRow_FT4())
+ return;
+ }
+ return;
+ }
+
+#endif
+
+ for (i = ymin; i <= ymax; i++) {
+ xmin = (left_x >> 16);
+ xmax = (right_x >> 16);
+
+ if (xmax >= xmin) {
+ posX = left_u;
+ posY = left_v;
+
+ num = (xmax - xmin);
+ if (num == 0)
+ num = 1;
+ difX = (right_u - posX) / num;
+ difY = (right_v - posY) / num;
+ difX2 = difX << 1;
+ difY2 = difY << 1;
+
+ if (xmin < g_prim.drawX) {
+ j = g_prim.drawX - xmin;
+ xmin = g_prim.drawX;
+ posX += j * difX;
+ posY += j * difY;
+ }
+ xmax--;
+ if (g_prim.drawW < xmax)
+ xmax = g_prim.drawW;
+
+ for (j = xmin; j < xmax; j += 2) {
+ XAdjust = (posX >> 16) % g_prim.TWin.Position.x1;
+ tC1 = g_gpu.psx_vram.u8[(((posY >> 16)
+ % g_prim.TWin.Position.y1) << 11) + YAdjust + (XAdjust
+ >> 1)];
+ tC1 = (tC1 >> ((XAdjust & 1) << 2)) & 0xf;
+ XAdjust = ((posX + difX) >> 16) % g_prim.TWin.Position.x1;
+ tC2 = g_gpu.psx_vram.u8[((((posY + difY) >> 16)
+ % g_prim.TWin.Position.y1) << 11) + YAdjust + (XAdjust
+ >> 1)];
+ tC2 = (tC2 >> ((XAdjust & 1) << 2)) & 0xf;
+
+ GetTextureTransColG32_SPR((uint32_t *) &g_gpu.psx_vram.u16[(i
+ << 10) + j], GETLE16(&g_gpu.psx_vram.u16[clutP+tC1])
+ | ((int32_t) GETLE16(&g_gpu.psx_vram.u16[clutP+tC2]))
+ << 16);
+ posX += difX2;
+ posY += difY2;
+ }
+ if (j == xmax) {
+ XAdjust = (posX >> 16) % g_prim.TWin.Position.x1;
+ tC1 = g_gpu.psx_vram.u8[(((posY >> 16)
+ % g_prim.TWin.Position.y1) << 11) + YAdjust + (XAdjust
+ >> 1)];
+ tC1 = (tC1 >> ((XAdjust & 1) << 2)) & 0xf;
+ GetTextureTransColG_SPR(&g_gpu.psx_vram.u16[(i << 10) + j],
+ GETLE16(&g_gpu.psx_vram.u16[clutP+tC1]));
+ }
+ }
+ if (NextRow_FT4())
+ return;
+ }
+}
+////////////////////////////////////////////////////////////////////////
+// POLY 3 F-SHADED TEX PAL 8
+////////////////////////////////////////////////////////////////////////
+
+void drawPoly3TEx8(short x1, short y1, short x2, short y2, short x3, short y3,
+ short tx1, short ty1, short tx2, short ty2, short tx3, short ty3,
+ short clX, short clY) {
+ int i, j, xmin, xmax, ymin, ymax;
+ int32_t difX, difY, difX2, difY2;
+ int32_t posX, posY, YAdjust, clutP;
+ short tC1, tC2;
+
+ if (x1 > g_prim.drawW && x2 > g_prim.drawW && x3 > g_prim.drawW)
+ return;
+ if (y1 > g_prim.drawH && y2 > g_prim.drawH && y3 > g_prim.drawH)
+ return;
+ if (x1 < g_prim.drawX && x2 < g_prim.drawX && x3 < g_prim.drawX)
+ return;
+ if (y1 < g_prim.drawY && y2 < g_prim.drawY && y3 < g_prim.drawY)
+ return;
+ if (g_prim.drawY >= g_prim.drawH)
+ return;
+ if (g_prim.drawX >= g_prim.drawW)
+ return;
+
+ if (!SetupSections_FT(x1, y1, x2, y2, x3, y3, tx1, ty1, tx2, ty2, tx3, ty3))
+ return;
+
+ ymax = g_soft.Ymax;
+
+ for (ymin = g_soft.Ymin; ymin < g_prim.drawY; ymin++)
+ if (NextRow_FT())
+ return;
+
+ clutP = (clY << 10) + clX;
+
+ YAdjust = ((g_soft.GlobalTextAddrY) << 11) + (g_soft.GlobalTextAddrX << 1);
+
+ difX = delta_right_u;
+ difX2 = difX << 1;
+ difY = delta_right_v;
+ difY2 = difY << 1;
+
+#ifdef FASTSOLID
+
+ if (!g_draw.bCheckMask && !g_soft.DrawSemiTrans) {
+ for (i = ymin; i <= ymax; i++) {
+ xmin = (left_x >> 16);
+ xmax = (right_x >> 16) - 1; //!!!!!!!!!!!!!!!
+ if (g_prim.drawW < xmax)
+ xmax = g_prim.drawW;
+
+ if (xmax >= xmin) {
+ posX = left_u;
+ posY = left_v;
+
+ if (xmin < g_prim.drawX) {
+ j = g_prim.drawX - xmin;
+ xmin = g_prim.drawX;
+ posX += j * difX;
+ posY += j * difY;
+ }
+
+ for (j = xmin; j < xmax; j += 2) {
+ tC1
+ = g_gpu.psx_vram.u8[((posY >> 5)
+ & (int32_t) 0xFFFFF800) + YAdjust + (posX
+ >> 16)];
+ tC2 = g_gpu.psx_vram.u8[(((posY + difY) >> 5)
+ & (int32_t) 0xFFFFF800) + YAdjust + ((posX + difX)
+ >> 16)];
+ GetTextureTransColG32_S(
+ (uint32_t *) &g_gpu.psx_vram.u16[(i << 10) + j],
+ GETLE16(&g_gpu.psx_vram.u16[clutP+tC1])
+ | ((int32_t) GETLE16(&g_gpu.psx_vram.u16[clutP+tC2]))
+ << 16);
+ posX += difX2;
+ posY += difY2;
+ }
+
+ if (j == xmax) {
+ tC1
+ = g_gpu.psx_vram.u8[((posY >> 5)
+ & (int32_t) 0xFFFFF800) + YAdjust + (posX
+ >> 16)];
+ GetTextureTransColG_S(&g_gpu.psx_vram.u16[(i << 10) + j],
+ GETLE16(&g_gpu.psx_vram.u16[clutP+tC1]));
+ }
+ }
+ if (NextRow_FT()) {
+ return;
+ }
+ }
+ return;
+ }
+
+#endif
+
+ for (i = ymin; i <= ymax; i++) {
+ xmin = (left_x >> 16);
+ xmax = (right_x >> 16) - 1; //!!!!!!!!!!!!!!!!!
+ if (g_prim.drawW < xmax)
+ xmax = g_prim.drawW;
+
+ if (xmax >= xmin) {
+ posX = left_u;
+ posY = left_v;
+
+ if (xmin < g_prim.drawX) {
+ j = g_prim.drawX - xmin;
+ xmin = g_prim.drawX;
+ posX += j * difX;
+ posY += j * difY;
+ }
+
+ for (j = xmin; j < xmax; j += 2) {
+ tC1 = g_gpu.psx_vram.u8[((posY >> 5) & (int32_t) 0xFFFFF800)
+ + YAdjust + (posX >> 16)];
+ tC2 = g_gpu.psx_vram.u8[(((posY + difY) >> 5)
+ & (int32_t) 0xFFFFF800) + YAdjust + ((posX + difX)
+ >> 16)];
+ GetTextureTransColG32(
+ (uint32_t *) &g_gpu.psx_vram.u16[(i << 10) + j],
+ GETLE16(&g_gpu.psx_vram.u16[clutP+tC1])
+ | ((int32_t) GETLE16(&g_gpu.psx_vram.u16[clutP+tC2]))
+ << 16);
+ posX += difX2;
+ posY += difY2;
+ }
+
+ if (j == xmax) {
+ tC1 = g_gpu.psx_vram.u8[((posY >> 5) & (int32_t) 0xFFFFF800)
+ + YAdjust + (posX >> 16)];
+ GetTextureTransColG(&g_gpu.psx_vram.u16[(i << 10) + j],
+ GETLE16(&g_gpu.psx_vram.u16[clutP+tC1]));
+ }
+
+ }
+ if (NextRow_FT()) {
+ return;
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void drawPoly3TEx8_IL(short x1, short y1, short x2, short y2, short x3,
+ short y3, short tx1, short ty1, short tx2, short ty2, short tx3,
+ short ty3, short clX, short clY) {
+ int i, j, xmin, xmax, ymin, ymax, n_xi, n_yi, TXV, TXU;
+ int32_t difX, difY, difX2, difY2;
+ int32_t posX, posY, YAdjust, clutP;
+ short tC1, tC2;
+
+ if (x1 > g_prim.drawW && x2 > g_prim.drawW && x3 > g_prim.drawW)
+ return;
+ if (y1 > g_prim.drawH && y2 > g_prim.drawH && y3 > g_prim.drawH)
+ return;
+ if (x1 < g_prim.drawX && x2 < g_prim.drawX && x3 < g_prim.drawX)
+ return;
+ if (y1 < g_prim.drawY && y2 < g_prim.drawY && y3 < g_prim.drawY)
+ return;
+ if (g_prim.drawY >= g_prim.drawH)
+ return;
+ if (g_prim.drawX >= g_prim.drawW)
+ return;
+
+ if (!SetupSections_FT(x1, y1, x2, y2, x3, y3, tx1, ty1, tx2, ty2, tx3, ty3))
+ return;
+
+ ymax = g_soft.Ymax;
+
+ for (ymin = g_soft.Ymin; ymin < g_prim.drawY; ymin++)
+ if (NextRow_FT())
+ return;
+
+ clutP = (clY << 10) + clX;
+
+ YAdjust = (g_soft.GlobalTextAddrY << 10) + g_soft.GlobalTextAddrX;
+
+ difX = delta_right_u;
+ difX2 = difX << 1;
+ difY = delta_right_v;
+ difY2 = difY << 1;
+
+#ifdef FASTSOLID
+
+ if (!g_draw.bCheckMask && !g_soft.DrawSemiTrans) {
+ for (i = ymin; i <= ymax; i++) {
+ xmin = (left_x >> 16);
+ xmax = (right_x >> 16) - 1; //!!!!!!!!!!!!!!!
+ if (g_prim.drawW < xmax)
+ xmax = g_prim.drawW;
+
+ if (xmax >= xmin) {
+ posX = left_u;
+ posY = left_v;
+
+ if (xmin < g_prim.drawX) {
+ j = g_prim.drawX - xmin;
+ xmin = g_prim.drawX;
+ posX += j * difX;
+ posY += j * difY;
+ }
+
+ for (j = xmin; j < xmax; j += 2) {
+ TXU = posX >> 16;
+ TXV = posY >> 16;
+ n_xi = ((TXU >> 1) & ~0x78) + ((TXU << 2) & 0x40) + ((TXV
+ << 3) & 0x38);
+ n_yi = (TXV & ~0x7) + ((TXU >> 5) & 0x7);
+
+ tC1
+ = (GETLE16(&g_gpu.psx_vram.u16[(n_yi<<10)+YAdjust+n_xi])
+ >> ((TXU & 0x01) << 3)) & 0xff;
+
+ TXU = (posX + difX) >> 16;
+ TXV = (posY + difY) >> 16;
+ n_xi = ((TXU >> 1) & ~0x78) + ((TXU << 2) & 0x40) + ((TXV
+ << 3) & 0x38);
+ n_yi = (TXV & ~0x7) + ((TXU >> 5) & 0x7);
+
+ tC2
+ = (GETLE16(&g_gpu.psx_vram.u16[(n_yi<<10)+YAdjust+n_xi])
+ >> ((TXU & 0x01) << 3)) & 0xff;
+
+ GetTextureTransColG32_S(
+ (uint32_t *) &g_gpu.psx_vram.u16[(i << 10) + j],
+ GETLE16(&g_gpu.psx_vram.u16[clutP+tC1])
+ | ((int32_t) GETLE16(&g_gpu.psx_vram.u16[clutP+tC2]))
+ << 16);
+ posX += difX2;
+ posY += difY2;
+ }
+
+ if (j == xmax) {
+ TXU = posX >> 16;
+ TXV = posY >> 16;
+ n_xi = ((TXU >> 1) & ~0x78) + ((TXU << 2) & 0x40) + ((TXV
+ << 3) & 0x38);
+ n_yi = (TXV & ~0x7) + ((TXU >> 5) & 0x7);
+
+ tC1
+ = (GETLE16(&g_gpu.psx_vram.u16[(n_yi<<10)+YAdjust+n_xi])
+ >> ((TXU & 0x01) << 3)) & 0xff;
+
+ GetTextureTransColG_S(&g_gpu.psx_vram.u16[(i << 10) + j],
+ GETLE16(&g_gpu.psx_vram.u16[clutP+tC1]));
+ }
+ }
+ if (NextRow_FT()) {
+ return;
+ }
+ }
+ return;
+ }
+
+#endif
+
+ for (i = ymin; i <= ymax; i++) {
+ xmin = (left_x >> 16);
+ xmax = (right_x >> 16) - 1; //!!!!!!!!!!!!!!!!!
+ if (g_prim.drawW < xmax)
+ xmax = g_prim.drawW;
+
+ if (xmax >= xmin) {
+ posX = left_u;
+ posY = left_v;
+
+ if (xmin < g_prim.drawX) {
+ j = g_prim.drawX - xmin;
+ xmin = g_prim.drawX;
+ posX += j * difX;
+ posY += j * difY;
+ }
+
+ for (j = xmin; j < xmax; j += 2) {
+ TXU = posX >> 16;
+ TXV = posY >> 16;
+ n_xi = ((TXU >> 1) & ~0x78) + ((TXU << 2) & 0x40) + ((TXV << 3)
+ & 0x38);
+ n_yi = (TXV & ~0x7) + ((TXU >> 5) & 0x7);
+
+ tC1 = (GETLE16(&g_gpu.psx_vram.u16[(n_yi<<10)+YAdjust+n_xi])
+ >> ((TXU & 0x01) << 3)) & 0xff;
+
+ TXU = (posX + difX) >> 16;
+ TXV = (posY + difY) >> 16;
+ n_xi = ((TXU >> 1) & ~0x78) + ((TXU << 2) & 0x40) + ((TXV << 3)
+ & 0x38);
+ n_yi = (TXV & ~0x7) + ((TXU >> 5) & 0x7);
+
+ tC2 = (GETLE16(&g_gpu.psx_vram.u16[(n_yi<<10)+YAdjust+n_xi])
+ >> ((TXU & 0x01) << 3)) & 0xff;
+
+ GetTextureTransColG32(
+ (uint32_t *) &g_gpu.psx_vram.u16[(i << 10) + j],
+ GETLE16(&g_gpu.psx_vram.u16[clutP+tC1])
+ | ((int32_t) GETLE16(&g_gpu.psx_vram.u16[clutP+tC2]))
+ << 16);
+ posX += difX2;
+ posY += difY2;
+ }
+
+ if (j == xmax) {
+ TXU = posX >> 16;
+ TXV = posY >> 16;
+ n_xi = ((TXU >> 1) & ~0x78) + ((TXU << 2) & 0x40) + ((TXV << 3)
+ & 0x38);
+ n_yi = (TXV & ~0x7) + ((TXU >> 5) & 0x7);
+
+ tC1 = (GETLE16(&g_gpu.psx_vram.u16[(n_yi<<10)+YAdjust+n_xi])
+ >> ((TXU & 0x01) << 3)) & 0xff;
+
+ GetTextureTransColG(&g_gpu.psx_vram.u16[(i << 10) + j],
+ GETLE16(&g_gpu.psx_vram.u16[clutP+tC1]));
+ }
+
+ }
+ if (NextRow_FT()) {
+ return;
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void drawPoly3TEx8_TW(short x1, short y1, short x2, short y2, short x3,
+ short y3, short tx1, short ty1, short tx2, short ty2, short tx3,
+ short ty3, short clX, short clY) {
+ int i, j, xmin, xmax, ymin, ymax;
+ int32_t difX, difY, difX2, difY2;
+ int32_t posX, posY, YAdjust, clutP;
+ short tC1, tC2;
+
+ if (x1 > g_prim.drawW && x2 > g_prim.drawW && x3 > g_prim.drawW)
+ return;
+ if (y1 > g_prim.drawH && y2 > g_prim.drawH && y3 > g_prim.drawH)
+ return;
+ if (x1 < g_prim.drawX && x2 < g_prim.drawX && x3 < g_prim.drawX)
+ return;
+ if (y1 < g_prim.drawY && y2 < g_prim.drawY && y3 < g_prim.drawY)
+ return;
+ if (g_prim.drawY >= g_prim.drawH)
+ return;
+ if (g_prim.drawX >= g_prim.drawW)
+ return;
+
+ if (!SetupSections_FT(x1, y1, x2, y2, x3, y3, tx1, ty1, tx2, ty2, tx3, ty3))
+ return;
+
+ ymax = g_soft.Ymax;
+
+ for (ymin = g_soft.Ymin; ymin < g_prim.drawY; ymin++)
+ if (NextRow_FT())
+ return;
+
+ clutP = (clY << 10) + clX;
+
+ YAdjust = ((g_soft.GlobalTextAddrY) << 11) + (g_soft.GlobalTextAddrX << 1);
+ YAdjust += (g_prim.TWin.Position.y0 << 11) + (g_prim.TWin.Position.x0);
+
+ difX = delta_right_u;
+ difX2 = difX << 1;
+ difY = delta_right_v;
+ difY2 = difY << 1;
+
+#ifdef FASTSOLID
+
+ if (!g_draw.bCheckMask && !g_soft.DrawSemiTrans) {
+ for (i = ymin; i <= ymax; i++) {
+ xmin = (left_x >> 16);
+ xmax = (right_x >> 16);//-1; //!!!!!!!!!!!!!!!!
+ if (xmax > xmin)
+ xmax--;
+
+ if (g_prim.drawW < xmax)
+ xmax = g_prim.drawW;
+
+ if (xmax >= xmin) {
+ posX = left_u;
+ posY = left_v;
+
+ if (xmin < g_prim.drawX) {
+ j = g_prim.drawX - xmin;
+ xmin = g_prim.drawX;
+ posX += j * difX;
+ posY += j * difY;
+ }
+
+ for (j = xmin; j < xmax; j += 2) {
+ tC1 = g_gpu.psx_vram.u8[(((posY >> 16)
+ % g_prim.TWin.Position.y1) << 11) + YAdjust
+ + ((posX >> 16) % g_prim.TWin.Position.x1)];
+ tC2
+ = g_gpu.psx_vram.u8[((((posY + difY) >> 16)
+ % g_prim.TWin.Position.y1) << 11) + YAdjust
+ + (((posX + difX) >> 16)
+ % g_prim.TWin.Position.x1)];
+ GetTextureTransColG32_S(
+ (uint32_t *) &g_gpu.psx_vram.u16[(i << 10) + j],
+ GETLE16(&g_gpu.psx_vram.u16[clutP+tC1])
+ | ((int32_t) GETLE16(&g_gpu.psx_vram.u16[clutP+tC2]))
+ << 16);
+ posX += difX2;
+ posY += difY2;
+ }
+
+ if (j == xmax) {
+ tC1 = g_gpu.psx_vram.u8[(((posY >> 16)
+ % g_prim.TWin.Position.y1) << 11) + YAdjust
+ + ((posX >> 16) % g_prim.TWin.Position.x1)];
+ GetTextureTransColG_S(&g_gpu.psx_vram.u16[(i << 10) + j],
+ GETLE16(&g_gpu.psx_vram.u16[clutP+tC1]));
+ }
+ }
+ if (NextRow_FT()) {
+ return;
+ }
+ }
+ return;
+ }
+
+#endif
+
+ for (i = ymin; i <= ymax; i++) {
+ xmin = (left_x >> 16);
+ xmax = (right_x >> 16) - 1; //!!!!!!!!!!!!!!!!!
+ if (g_prim.drawW < xmax)
+ xmax = g_prim.drawW;
+
+ if (xmax >= xmin) {
+ posX = left_u;
+ posY = left_v;
+
+ if (xmin < g_prim.drawX) {
+ j = g_prim.drawX - xmin;
+ xmin = g_prim.drawX;
+ posX += j * difX;
+ posY += j * difY;
+ }
+
+ for (j = xmin; j < xmax; j += 2) {
+ tC1 = g_gpu.psx_vram.u8[(((posY >> 16)
+ % g_prim.TWin.Position.y1) << 11) + YAdjust + ((posX
+ >> 16) % g_prim.TWin.Position.x1)];
+ tC2 = g_gpu.psx_vram.u8[((((posY + difY) >> 16)
+ % g_prim.TWin.Position.y1) << 11) + YAdjust + (((posX
+ + difX) >> 16) % g_prim.TWin.Position.x1)];
+ GetTextureTransColG32(
+ (uint32_t *) &g_gpu.psx_vram.u16[(i << 10) + j],
+ GETLE16(&g_gpu.psx_vram.u16[clutP+tC1])
+ | ((int32_t) GETLE16(&g_gpu.psx_vram.u16[clutP+tC2]))
+ << 16);
+ posX += difX2;
+ posY += difY2;
+ }
+
+ if (j == xmax) {
+ tC1 = g_gpu.psx_vram.u8[(((posY >> 16)
+ % g_prim.TWin.Position.y1) << 11) + YAdjust + ((posX
+ >> 16) % g_prim.TWin.Position.x1)];
+ GetTextureTransColG(&g_gpu.psx_vram.u16[(i << 10) + j],
+ GETLE16(&g_gpu.psx_vram.u16[clutP+tC1]));
+ }
+
+ }
+ if (NextRow_FT()) {
+ return;
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+#ifdef POLYQUAD3
+
+void drawPoly4TEx8_TRI(short x1, short y1, short x2, short y2, short x3,
+ short y3, short x4, short y4, short tx1, short ty1, short tx2,
+ short ty2, short tx3, short ty3, short tx4, short ty4, short clX,
+ short clY) {
+ drawPoly3TEx8(x2, y2, x3, y3, x4, y4, tx2, ty2, tx3, ty3, tx4, ty4, clX,
+ clY);
+
+ drawPoly3TEx8(x1, y1, x2, y2, x4, y4, tx1, ty1, tx2, ty2, tx4, ty4, clX,
+ clY);
+}
+
+#endif
+
+// more exact:
+
+void drawPoly4TEx8(short x1, short y1, short x2, short y2, short x3, short y3,
+ short x4, short y4, short tx1, short ty1, short tx2, short ty2,
+ short tx3, short ty3, short tx4, short ty4, short clX, short clY) {
+ int32_t num;
+ int32_t i, j, xmin, xmax, ymin, ymax;
+ int32_t difX, difY, difX2, difY2;
+ int32_t posX, posY, YAdjust, clutP;
+ short tC1, tC2;
+
+ if (x1 > g_prim.drawW && x2 > g_prim.drawW && x3 > g_prim.drawW && x4
+ > g_prim.drawW)
+ return;
+ if (y1 > g_prim.drawH && y2 > g_prim.drawH && y3 > g_prim.drawH && y4
+ > g_prim.drawH)
+ return;
+ if (x1 < g_prim.drawX && x2 < g_prim.drawX && x3 < g_prim.drawX && x4
+ < g_prim.drawX)
+ return;
+ if (y1 < g_prim.drawY && y2 < g_prim.drawY && y3 < g_prim.drawY && y4
+ < g_prim.drawY)
+ return;
+ if (g_prim.drawY >= g_prim.drawH)
+ return;
+ if (g_prim.drawX >= g_prim.drawW)
+ return;
+
+ if (!SetupSections_FT4(x1, y1, x2, y2, x3, y3, x4, y4, tx1, ty1, tx2, ty2,
+ tx3, ty3, tx4, ty4))
+ return;
+
+ ymax = g_soft.Ymax;
+
+ for (ymin = g_soft.Ymin; ymin < g_prim.drawY; ymin++)
+ if (NextRow_FT4())
+ return;
+
+ clutP = (clY << 10) + clX;
+
+ YAdjust = ((g_soft.GlobalTextAddrY) << 11) + (g_soft.GlobalTextAddrX << 1);
+
+#ifdef FASTSOLID
+
+ if (!g_draw.bCheckMask && !g_soft.DrawSemiTrans) {
+ for (i = ymin; i <= ymax; i++) {
+ xmin = (left_x >> 16);
+ xmax = (right_x >> 16);
+
+ if (xmax >= xmin) {
+ posX = left_u;
+ posY = left_v;
+
+ num = (xmax - xmin);
+ if (num == 0)
+ num = 1;
+ difX = (right_u - posX) / num;
+ difY = (right_v - posY) / num;
+ difX2 = difX << 1;
+ difY2 = difY << 1;
+
+ if (xmin < g_prim.drawX) {
+ j = g_prim.drawX - xmin;
+ xmin = g_prim.drawX;
+ posX += j * difX;
+ posY += j * difY;
+ }
+ xmax--;
+ if (g_prim.drawW < xmax)
+ xmax = g_prim.drawW;
+
+ for (j = xmin; j < xmax; j += 2) {
+ tC1
+ = g_gpu.psx_vram.u8[((posY >> 5)
+ & (int32_t) 0xFFFFF800) + YAdjust + (posX
+ >> 16)];
+ tC2 = g_gpu.psx_vram.u8[(((posY + difY) >> 5)
+ & (int32_t) 0xFFFFF800) + YAdjust + ((posX + difX)
+ >> 16)];
+ GetTextureTransColG32_S(
+ (uint32_t *) &g_gpu.psx_vram.u16[(i << 10) + j],
+ GETLE16(&g_gpu.psx_vram.u16[clutP+tC1])
+ | ((int32_t) GETLE16(&g_gpu.psx_vram.u16[clutP+tC2]))
+ << 16);
+ posX += difX2;
+ posY += difY2;
+ }
+ if (j == xmax) {
+ tC1
+ = g_gpu.psx_vram.u8[((posY >> 5)
+ & (int32_t) 0xFFFFF800) + YAdjust + (posX
+ >> 16)];
+ GetTextureTransColG_S(&g_gpu.psx_vram.u16[(i << 10) + j],
+ GETLE16(&g_gpu.psx_vram.u16[clutP+tC1]));
+ }
+ }
+ if (NextRow_FT4())
+ return;
+ }
+ return;
+ }
+
+#endif
+
+ for (i = ymin; i <= ymax; i++) {
+ xmin = (left_x >> 16);
+ xmax = (right_x >> 16);
+
+ if (xmax >= xmin) {
+ posX = left_u;
+ posY = left_v;
+
+ num = (xmax - xmin);
+ if (num == 0)
+ num = 1;
+ difX = (right_u - posX) / num;
+ difY = (right_v - posY) / num;
+ difX2 = difX << 1;
+ difY2 = difY << 1;
+
+ if (xmin < g_prim.drawX) {
+ j = g_prim.drawX - xmin;
+ xmin = g_prim.drawX;
+ posX += j * difX;
+ posY += j * difY;
+ }
+ xmax--;
+ if (g_prim.drawW < xmax)
+ xmax = g_prim.drawW;
+
+ for (j = xmin; j < xmax; j += 2) {
+ tC1 = g_gpu.psx_vram.u8[((posY >> 5) & (int32_t) 0xFFFFF800)
+ + YAdjust + (posX >> 16)];
+ tC2 = g_gpu.psx_vram.u8[(((posY + difY) >> 5)
+ & (int32_t) 0xFFFFF800) + YAdjust + ((posX + difX)
+ >> 16)];
+ GetTextureTransColG32(
+ (uint32_t *) &g_gpu.psx_vram.u16[(i << 10) + j],
+ GETLE16(&g_gpu.psx_vram.u16[clutP+tC1])
+ | ((int32_t) GETLE16(&g_gpu.psx_vram.u16[clutP+tC2]))
+ << 16);
+ posX += difX2;
+ posY += difY2;
+ }
+ if (j == xmax) {
+ tC1 = g_gpu.psx_vram.u8[((posY >> 5) & (int32_t) 0xFFFFF800)
+ + YAdjust + (posX >> 16)];
+ GetTextureTransColG(&g_gpu.psx_vram.u16[(i << 10) + j],
+ GETLE16(&g_gpu.psx_vram.u16[clutP+tC1]));
+ }
+ }
+ if (NextRow_FT4())
+ return;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void drawPoly4TEx8_IL(short x1, short y1, short x2, short y2, short x3,
+ short y3, short x4, short y4, short tx1, short ty1, short tx2,
+ short ty2, short tx3, short ty3, short tx4, short ty4, short clX,
+ short clY) {
+ int32_t num;
+ int32_t i, j, xmin, xmax, ymin, ymax, n_xi, n_yi, TXV, TXU;
+ int32_t difX, difY, difX2, difY2;
+ int32_t posX, posY, YAdjust, clutP;
+ short tC1, tC2;
+
+ if (x1 > g_prim.drawW && x2 > g_prim.drawW && x3 > g_prim.drawW && x4
+ > g_prim.drawW)
+ return;
+ if (y1 > g_prim.drawH && y2 > g_prim.drawH && y3 > g_prim.drawH && y4
+ > g_prim.drawH)
+ return;
+ if (x1 < g_prim.drawX && x2 < g_prim.drawX && x3 < g_prim.drawX && x4
+ < g_prim.drawX)
+ return;
+ if (y1 < g_prim.drawY && y2 < g_prim.drawY && y3 < g_prim.drawY && y4
+ < g_prim.drawY)
+ return;
+ if (g_prim.drawY >= g_prim.drawH)
+ return;
+ if (g_prim.drawX >= g_prim.drawW)
+ return;
+
+ if (!SetupSections_FT4(x1, y1, x2, y2, x3, y3, x4, y4, tx1, ty1, tx2, ty2,
+ tx3, ty3, tx4, ty4))
+ return;
+
+ ymax = g_soft.Ymax;
+
+ for (ymin = g_soft.Ymin; ymin < g_prim.drawY; ymin++)
+ if (NextRow_FT4())
+ return;
+
+ clutP = (clY << 10) + clX;
+
+ YAdjust = (g_soft.GlobalTextAddrY << 10) + g_soft.GlobalTextAddrX;
+
+#ifdef FASTSOLID
+
+ if (!g_draw.bCheckMask && !g_soft.DrawSemiTrans) {
+ for (i = ymin; i <= ymax; i++) {
+ xmin = (left_x >> 16);
+ xmax = (right_x >> 16);
+
+ if (xmax >= xmin) {
+ posX = left_u;
+ posY = left_v;
+
+ num = (xmax - xmin);
+ if (num == 0)
+ num = 1;
+ difX = (right_u - posX) / num;
+ difY = (right_v - posY) / num;
+ difX2 = difX << 1;
+ difY2 = difY << 1;
+
+ if (xmin < g_prim.drawX) {
+ j = g_prim.drawX - xmin;
+ xmin = g_prim.drawX;
+ posX += j * difX;
+ posY += j * difY;
+ }
+ xmax--;
+ if (g_prim.drawW < xmax)
+ xmax = g_prim.drawW;
+
+ for (j = xmin; j < xmax; j += 2) {
+ TXU = posX >> 16;
+ TXV = posY >> 16;
+ n_xi = ((TXU >> 1) & ~0x78) + ((TXU << 2) & 0x40) + ((TXV
+ << 3) & 0x38);
+ n_yi = (TXV & ~0x7) + ((TXU >> 5) & 0x7);
+
+ tC1
+ = (GETLE16(&g_gpu.psx_vram.u16[(n_yi<<10)+YAdjust+n_xi])
+ >> ((TXU & 0x01) << 3)) & 0xff;
+
+ TXU = (posX + difX) >> 16;
+ TXV = (posY + difY) >> 16;
+ n_xi = ((TXU >> 1) & ~0x78) + ((TXU << 2) & 0x40) + ((TXV
+ << 3) & 0x38);
+ n_yi = (TXV & ~0x7) + ((TXU >> 5) & 0x7);
+
+ tC2
+ = (GETLE16(&g_gpu.psx_vram.u16[(n_yi<<10)+YAdjust+n_xi])
+ >> ((TXU & 0x01) << 3)) & 0xff;
+
+ GetTextureTransColG32_S(
+ (uint32_t *) &g_gpu.psx_vram.u16[(i << 10) + j],
+ GETLE16(&g_gpu.psx_vram.u16[clutP+tC1])
+ | ((int32_t) GETLE16(&g_gpu.psx_vram.u16[clutP+tC2]))
+ << 16);
+ posX += difX2;
+ posY += difY2;
+ }
+ if (j == xmax) {
+ TXU = posX >> 16;
+ TXV = posY >> 16;
+ n_xi = ((TXU >> 1) & ~0x78) + ((TXU << 2) & 0x40) + ((TXV
+ << 3) & 0x38);
+ n_yi = (TXV & ~0x7) + ((TXU >> 5) & 0x7);
+
+ tC1
+ = (GETLE16(&g_gpu.psx_vram.u16[(n_yi<<10)+YAdjust+n_xi])
+ >> ((TXU & 0x01) << 3)) & 0xff;
+
+ GetTextureTransColG_S(&g_gpu.psx_vram.u16[(i << 10) + j],
+ GETLE16(&g_gpu.psx_vram.u16[clutP+tC1]));
+ }
+ }
+ if (NextRow_FT4())
+ return;
+ }
+ return;
+ }
+
+#endif
+
+ for (i = ymin; i <= ymax; i++) {
+ xmin = (left_x >> 16);
+ xmax = (right_x >> 16);
+
+ if (xmax >= xmin) {
+ posX = left_u;
+ posY = left_v;
+
+ num = (xmax - xmin);
+ if (num == 0)
+ num = 1;
+ difX = (right_u - posX) / num;
+ difY = (right_v - posY) / num;
+ difX2 = difX << 1;
+ difY2 = difY << 1;
+
+ if (xmin < g_prim.drawX) {
+ j = g_prim.drawX - xmin;
+ xmin = g_prim.drawX;
+ posX += j * difX;
+ posY += j * difY;
+ }
+ xmax--;
+ if (g_prim.drawW < xmax)
+ xmax = g_prim.drawW;
+
+ for (j = xmin; j < xmax; j += 2) {
+ TXU = posX >> 16;
+ TXV = posY >> 16;
+ n_xi = ((TXU >> 1) & ~0x78) + ((TXU << 2) & 0x40) + ((TXV << 3)
+ & 0x38);
+ n_yi = (TXV & ~0x7) + ((TXU >> 5) & 0x7);
+
+ tC1 = (GETLE16(&g_gpu.psx_vram.u16[(n_yi<<10)+YAdjust+n_xi])
+ >> ((TXU & 0x01) << 3)) & 0xff;
+
+ TXU = (posX + difX) >> 16;
+ TXV = (posY + difY) >> 16;
+ n_xi = ((TXU >> 1) & ~0x78) + ((TXU << 2) & 0x40) + ((TXV << 3)
+ & 0x38);
+ n_yi = (TXV & ~0x7) + ((TXU >> 5) & 0x7);
+
+ tC2 = (GETLE16(&g_gpu.psx_vram.u16[(n_yi<<10)+YAdjust+n_xi])
+ >> ((TXU & 0x01) << 3)) & 0xff;
+
+ GetTextureTransColG32(
+ (uint32_t *) &g_gpu.psx_vram.u16[(i << 10) + j],
+ GETLE16(&g_gpu.psx_vram.u16[clutP+tC1])
+ | ((int32_t) GETLE16(&g_gpu.psx_vram.u16[clutP+tC2]))
+ << 16);
+ posX += difX2;
+ posY += difY2;
+ }
+ if (j == xmax) {
+ TXU = posX >> 16;
+ TXV = posY >> 16;
+ n_xi = ((TXU >> 1) & ~0x78) + ((TXU << 2) & 0x40) + ((TXV << 3)
+ & 0x38);
+ n_yi = (TXV & ~0x7) + ((TXU >> 5) & 0x7);
+ tC1 = (GETLE16(&g_gpu.psx_vram.u16[(n_yi<<10)+YAdjust+n_xi])
+ >> ((TXU & 0x01) << 3)) & 0xff;
+ GetTextureTransColG(&g_gpu.psx_vram.u16[(i << 10) + j],
+ GETLE16(&g_gpu.psx_vram.u16[clutP+tC1]));
+ }
+ }
+ if (NextRow_FT4())
+ return;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void drawPoly4TEx8_TW(short x1, short y1, short x2, short y2, short x3,
+ short y3, short x4, short y4, short tx1, short ty1, short tx2,
+ short ty2, short tx3, short ty3, short tx4, short ty4, short clX,
+ short clY) {
+ int32_t num;
+ int32_t i, j, xmin, xmax, ymin, ymax;
+ int32_t difX, difY, difX2, difY2;
+ int32_t posX, posY, YAdjust, clutP;
+ short tC1, tC2;
+
+ if (x1 > g_prim.drawW && x2 > g_prim.drawW && x3 > g_prim.drawW && x4
+ > g_prim.drawW)
+ return;
+ if (y1 > g_prim.drawH && y2 > g_prim.drawH && y3 > g_prim.drawH && y4
+ > g_prim.drawH)
+ return;
+ if (x1 < g_prim.drawX && x2 < g_prim.drawX && x3 < g_prim.drawX && x4
+ < g_prim.drawX)
+ return;
+ if (y1 < g_prim.drawY && y2 < g_prim.drawY && y3 < g_prim.drawY && y4
+ < g_prim.drawY)
+ return;
+ if (g_prim.drawY >= g_prim.drawH)
+ return;
+ if (g_prim.drawX >= g_prim.drawW)
+ return;
+
+ if (!SetupSections_FT4(x1, y1, x2, y2, x3, y3, x4, y4, tx1, ty1, tx2, ty2,
+ tx3, ty3, tx4, ty4))
+ return;
+
+ ymax = g_soft.Ymax;
+
+ for (ymin = g_soft.Ymin; ymin < g_prim.drawY; ymin++)
+ if (NextRow_FT4())
+ return;
+
+ clutP = (clY << 10) + clX;
+
+ YAdjust = ((g_soft.GlobalTextAddrY) << 11) + (g_soft.GlobalTextAddrX << 1);
+ YAdjust += (g_prim.TWin.Position.y0 << 11) + (g_prim.TWin.Position.x0);
+
+#ifdef FASTSOLID
+
+ if (!g_draw.bCheckMask && !g_soft.DrawSemiTrans) {
+ for (i = ymin; i <= ymax; i++) {
+ xmin = (left_x >> 16);
+ xmax = (right_x >> 16);
+
+ if (xmax >= xmin) {
+ posX = left_u;
+ posY = left_v;
+
+ num = (xmax - xmin);
+ if (num == 0)
+ num = 1;
+ difX = (right_u - posX) / num;
+ difY = (right_v - posY) / num;
+ difX2 = difX << 1;
+ difY2 = difY << 1;
+
+ if (xmin < g_prim.drawX) {
+ j = g_prim.drawX - xmin;
+ xmin = g_prim.drawX;
+ posX += j * difX;
+ posY += j * difY;
+ }
+ xmax--;
+ if (g_prim.drawW < xmax)
+ xmax = g_prim.drawW;
+
+ for (j = xmin; j < xmax; j += 2) {
+ tC1 = g_gpu.psx_vram.u8[(((posY >> 16)
+ % g_prim.TWin.Position.y1) << 11) + YAdjust
+ + ((posX >> 16) % g_prim.TWin.Position.x1)];
+ tC2
+ = g_gpu.psx_vram.u8[((((posY + difY) >> 16)
+ % g_prim.TWin.Position.y1) << 11) + YAdjust
+ + (((posX + difX) >> 16)
+ % g_prim.TWin.Position.x1)];
+ GetTextureTransColG32_S(
+ (uint32_t *) &g_gpu.psx_vram.u16[(i << 10) + j],
+ GETLE16(&g_gpu.psx_vram.u16[clutP+tC1])
+ | ((int32_t) GETLE16(&g_gpu.psx_vram.u16[clutP+tC2]))
+ << 16);
+ posX += difX2;
+ posY += difY2;
+ }
+ if (j == xmax) {
+ tC1 = g_gpu.psx_vram.u8[((((posY + difY) >> 16)
+ % g_prim.TWin.Position.y1) << 11) + YAdjust
+ + ((posX >> 16) % g_prim.TWin.Position.x1)];
+ GetTextureTransColG_S(&g_gpu.psx_vram.u16[(i << 10) + j],
+ GETLE16(&g_gpu.psx_vram.u16[clutP+tC1]));
+ }
+ }
+ if (NextRow_FT4())
+ return;
+ }
+ return;
+ }
+
+#endif
+
+ for (i = ymin; i <= ymax; i++) {
+ xmin = (left_x >> 16);
+ xmax = (right_x >> 16);
+
+ if (xmax >= xmin) {
+ posX = left_u;
+ posY = left_v;
+
+ num = (xmax - xmin);
+ if (num == 0)
+ num = 1;
+ difX = (right_u - posX) / num;
+ difY = (right_v - posY) / num;
+ difX2 = difX << 1;
+ difY2 = difY << 1;
+
+ if (xmin < g_prim.drawX) {
+ j = g_prim.drawX - xmin;
+ xmin = g_prim.drawX;
+ posX += j * difX;
+ posY += j * difY;
+ }
+ xmax--;
+ if (g_prim.drawW < xmax)
+ xmax = g_prim.drawW;
+
+ for (j = xmin; j < xmax; j += 2) {
+ tC1 = g_gpu.psx_vram.u8[(((posY >> 16)
+ % g_prim.TWin.Position.y1) << 11) + YAdjust + ((posX
+ >> 16) % g_prim.TWin.Position.x1)];
+ tC2 = g_gpu.psx_vram.u8[((((posY + difY) >> 16)
+ % g_prim.TWin.Position.y1) << 11) + YAdjust + (((posX
+ + difX) >> 16) % g_prim.TWin.Position.x1)];
+ GetTextureTransColG32(
+ (uint32_t *) &g_gpu.psx_vram.u16[(i << 10) + j],
+ GETLE16(&g_gpu.psx_vram.u16[clutP+tC1])
+ | ((int32_t) GETLE16(&g_gpu.psx_vram.u16[clutP+tC2]))
+ << 16);
+ posX += difX2;
+ posY += difY2;
+ }
+ if (j == xmax) {
+ tC1 = g_gpu.psx_vram.u8[((((posY + difY) >> 16)
+ % g_prim.TWin.Position.y1) << 11) + YAdjust + ((posX
+ >> 16) % g_prim.TWin.Position.x1)];
+ GetTextureTransColG(&g_gpu.psx_vram.u16[(i << 10) + j],
+ GETLE16(&g_gpu.psx_vram.u16[clutP+tC1]));
+ }
+ }
+ if (NextRow_FT4())
+ return;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void drawPoly4TEx8_TW_S(short x1, short y1, short x2, short y2, short x3,
+ short y3, short x4, short y4, short tx1, short ty1, short tx2,
+ short ty2, short tx3, short ty3, short tx4, short ty4, short clX,
+ short clY) {
+ int32_t num;
+ int32_t i, j, xmin, xmax, ymin, ymax;
+ int32_t difX, difY, difX2, difY2;
+ int32_t posX, posY, YAdjust, clutP;
+ short tC1, tC2;
+
+ if (x1 > g_prim.drawW && x2 > g_prim.drawW && x3 > g_prim.drawW && x4
+ > g_prim.drawW)
+ return;
+ if (y1 > g_prim.drawH && y2 > g_prim.drawH && y3 > g_prim.drawH && y4
+ > g_prim.drawH)
+ return;
+ if (x1 < g_prim.drawX && x2 < g_prim.drawX && x3 < g_prim.drawX && x4
+ < g_prim.drawX)
+ return;
+ if (y1 < g_prim.drawY && y2 < g_prim.drawY && y3 < g_prim.drawY && y4
+ < g_prim.drawY)
+ return;
+ if (g_prim.drawY >= g_prim.drawH)
+ return;
+ if (g_prim.drawX >= g_prim.drawW)
+ return;
+
+ if (!SetupSections_FT4(x1, y1, x2, y2, x3, y3, x4, y4, tx1, ty1, tx2, ty2,
+ tx3, ty3, tx4, ty4))
+ return;
+
+ ymax = g_soft.Ymax;
+
+ for (ymin = g_soft.Ymin; ymin < g_prim.drawY; ymin++)
+ if (NextRow_FT4())
+ return;
+
+ clutP = (clY << 10) + clX;
+
+ YAdjust = ((g_soft.GlobalTextAddrY) << 11) + (g_soft.GlobalTextAddrX << 1);
+ YAdjust += (g_prim.TWin.Position.y0 << 11) + (g_prim.TWin.Position.x0);
+
+#ifdef FASTSOLID
+
+ if (!g_draw.bCheckMask && !g_soft.DrawSemiTrans) {
+ for (i = ymin; i <= ymax; i++) {
+ xmin = (left_x >> 16);
+ xmax = (right_x >> 16);
+
+ if (xmax >= xmin) {
+ posX = left_u;
+ posY = left_v;
+
+ num = (xmax - xmin);
+ if (num == 0)
+ num = 1;
+ difX = (right_u - posX) / num;
+ difY = (right_v - posY) / num;
+ difX2 = difX << 1;
+ difY2 = difY << 1;
+
+ if (xmin < g_prim.drawX) {
+ j = g_prim.drawX - xmin;
+ xmin = g_prim.drawX;
+ posX += j * difX;
+ posY += j * difY;
+ }
+ xmax--;
+ if (g_prim.drawW < xmax)
+ xmax = g_prim.drawW;
+
+ for (j = xmin; j < xmax; j += 2) {
+ tC1 = g_gpu.psx_vram.u8[(((posY >> 16)
+ % g_prim.TWin.Position.y1) << 11) + YAdjust
+ + ((posX >> 16) % g_prim.TWin.Position.x1)];
+ tC2
+ = g_gpu.psx_vram.u8[((((posY + difY) >> 16)
+ % g_prim.TWin.Position.y1) << 11) + YAdjust
+ + (((posX + difX) >> 16)
+ % g_prim.TWin.Position.x1)];
+ GetTextureTransColG32_S(
+ (uint32_t *) &g_gpu.psx_vram.u16[(i << 10) + j],
+ GETLE16(&g_gpu.psx_vram.u16[clutP+tC1])
+ | ((int32_t) GETLE16(&g_gpu.psx_vram.u16[clutP+tC2]))
+ << 16);
+ posX += difX2;
+ posY += difY2;
+ }
+ if (j == xmax) {
+ tC1 = g_gpu.psx_vram.u8[((((posY + difY) >> 16)
+ % g_prim.TWin.Position.y1) << 11) + YAdjust
+ + ((posX >> 16) % g_prim.TWin.Position.x1)];
+ GetTextureTransColG_S(&g_gpu.psx_vram.u16[(i << 10) + j],
+ GETLE16(&g_gpu.psx_vram.u16[clutP+tC1]));
+ }
+ }
+ if (NextRow_FT4())
+ return;
+ }
+ return;
+ }
+
+#endif
+
+ for (i = ymin; i <= ymax; i++) {
+ xmin = (left_x >> 16);
+ xmax = (right_x >> 16);
+
+ if (xmax >= xmin) {
+ posX = left_u;
+ posY = left_v;
+
+ num = (xmax - xmin);
+ if (num == 0)
+ num = 1;
+ difX = (right_u - posX) / num;
+ difY = (right_v - posY) / num;
+ difX2 = difX << 1;
+ difY2 = difY << 1;
+
+ if (xmin < g_prim.drawX) {
+ j = g_prim.drawX - xmin;
+ xmin = g_prim.drawX;
+ posX += j * difX;
+ posY += j * difY;
+ }
+ xmax--;
+ if (g_prim.drawW < xmax)
+ xmax = g_prim.drawW;
+
+ for (j = xmin; j < xmax; j += 2) {
+ tC1 = g_gpu.psx_vram.u8[(((posY >> 16)
+ % g_prim.TWin.Position.y1) << 11) + YAdjust + ((posX
+ >> 16) % g_prim.TWin.Position.x1)];
+ tC2 = g_gpu.psx_vram.u8[((((posY + difY) >> 16)
+ % g_prim.TWin.Position.y1) << 11) + YAdjust + (((posX
+ + difX) >> 16) % g_prim.TWin.Position.x1)];
+ GetTextureTransColG32_SPR((uint32_t *) &g_gpu.psx_vram.u16[(i
+ << 10) + j], GETLE16(&g_gpu.psx_vram.u16[clutP+tC1])
+ | ((int32_t) GETLE16(&g_gpu.psx_vram.u16[clutP+tC2]))
+ << 16);
+ posX += difX2;
+ posY += difY2;
+ }
+ if (j == xmax) {
+ tC1 = g_gpu.psx_vram.u8[((((posY + difY) >> 16)
+ % g_prim.TWin.Position.y1) << 11) + YAdjust + ((posX
+ >> 16) % g_prim.TWin.Position.x1)];
+ GetTextureTransColG_SPR(&g_gpu.psx_vram.u16[(i << 10) + j],
+ GETLE16(&g_gpu.psx_vram.u16[clutP+tC1]));
+ }
+ }
+ if (NextRow_FT4())
+ return;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+// POLY 3 F-SHADED TEX 15 BIT
+////////////////////////////////////////////////////////////////////////
+
+void drawPoly3TD(short x1, short y1, short x2, short y2, short x3, short y3,
+ short tx1, short ty1, short tx2, short ty2, short tx3, short ty3) {
+ int i, j, xmin, xmax, ymin, ymax;
+ int32_t difX, difY, difX2, difY2;
+ int32_t posX, posY;
+
+ if (x1 > g_prim.drawW && x2 > g_prim.drawW && x3 > g_prim.drawW)
+ return;
+ if (y1 > g_prim.drawH && y2 > g_prim.drawH && y3 > g_prim.drawH)
+ return;
+ if (x1 < g_prim.drawX && x2 < g_prim.drawX && x3 < g_prim.drawX)
+ return;
+ if (y1 < g_prim.drawY && y2 < g_prim.drawY && y3 < g_prim.drawY)
+ return;
+ if (g_prim.drawY >= g_prim.drawH)
+ return;
+ if (g_prim.drawX >= g_prim.drawW)
+ return;
+
+ if (!SetupSections_FT(x1, y1, x2, y2, x3, y3, tx1, ty1, tx2, ty2, tx3, ty3))
+ return;
+
+ ymax = g_soft.Ymax;
+
+ for (ymin = g_soft.Ymin; ymin < g_prim.drawY; ymin++)
+ if (NextRow_FT())
+ return;
+
+ difX = delta_right_u;
+ difX2 = difX << 1;
+ difY = delta_right_v;
+ difY2 = difY << 1;
+
+#ifdef FASTSOLID
+
+ if (!g_draw.bCheckMask && !g_soft.DrawSemiTrans) {
+ for (i = ymin; i <= ymax; i++) {
+ xmin = (left_x >> 16);
+ xmax = (right_x >> 16) - 1; //!!!!!!!!!!!!!
+ if (g_prim.drawW < xmax)
+ xmax = g_prim.drawW;
+
+ if (xmax >= xmin) {
+ posX = left_u;
+ posY = left_v;
+
+ if (xmin < g_prim.drawX) {
+ j = g_prim.drawX - xmin;
+ xmin = g_prim.drawX;
+ posX += j * difX;
+ posY += j * difY;
+ }
+
+ for (j = xmin; j < xmax; j += 2) {
+ GetTextureTransColG32_S(
+ (uint32_t *) &g_gpu.psx_vram.u16[(i << 10) + j],
+ (((int32_t) GETLE16(&g_gpu.psx_vram.u16[((((posY+difY)>>16)+g_soft.GlobalTextAddrY)<<10)+((posX+difX)>>16)+g_soft.GlobalTextAddrX]))
+ << 16)
+ | GETLE16(&g_gpu.psx_vram.u16[(((posY>>16)+g_soft.GlobalTextAddrY)<<10)+((posX)>>16)+g_soft.GlobalTextAddrX]));
+
+ posX += difX2;
+ posY += difY2;
+ }
+ if (j == xmax)
+ GetTextureTransColG_S(
+ &g_gpu.psx_vram.u16[(i << 10) + j],
+ GETLE16(&g_gpu.psx_vram.u16[(((posY>>16)+g_soft.GlobalTextAddrY)<<10)+(posX>>16)+g_soft.GlobalTextAddrX]));
+ }
+ if (NextRow_FT()) {
+ return;
+ }
+ }
+ return;
+ }
+
+#endif
+
+ for (i = ymin; i <= ymax; i++) {
+ xmin = (left_x >> 16);
+ xmax = (right_x >> 16) - 1; //!!!!!!!!!!!!!!
+ if (g_prim.drawW < xmax)
+ xmax = g_prim.drawW;
+
+ if (xmax >= xmin) {
+ posX = left_u;
+ posY = left_v;
+
+ if (xmin < g_prim.drawX) {
+ j = g_prim.drawX - xmin;
+ xmin = g_prim.drawX;
+ posX += j * difX;
+ posY += j * difY;
+ }
+
+ for (j = xmin; j < xmax; j += 2) {
+ GetTextureTransColG32(
+ (uint32_t *) &g_gpu.psx_vram.u16[(i << 10) + j],
+ (((int32_t) GETLE16(&g_gpu.psx_vram.u16[((((posY+difY)>>16)+g_soft.GlobalTextAddrY)<<10)+((posX+difX)>>16)+g_soft.GlobalTextAddrX]))
+ << 16)
+ | GETLE16(&g_gpu.psx_vram.u16[(((posY>>16)+g_soft.GlobalTextAddrY)<<10)+((posX)>>16)+g_soft.GlobalTextAddrX]));
+
+ posX += difX2;
+ posY += difY2;
+ }
+ if (j == xmax)
+ GetTextureTransColG(
+ &g_gpu.psx_vram.u16[(i << 10) + j],
+ GETLE16(&g_gpu.psx_vram.u16[(((posY>>16)+g_soft.GlobalTextAddrY)<<10)+(posX>>16)+g_soft.GlobalTextAddrX]));
+ }
+ if (NextRow_FT()) {
+ return;
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void drawPoly3TD_TW(short x1, short y1, short x2, short y2, short x3, short y3,
+ short tx1, short ty1, short tx2, short ty2, short tx3, short ty3) {
+ int i, j, xmin, xmax, ymin, ymax;
+ int32_t difX, difY, difX2, difY2;
+ int32_t posX, posY;
+
+ if (x1 > g_prim.drawW && x2 > g_prim.drawW && x3 > g_prim.drawW)
+ return;
+ if (y1 > g_prim.drawH && y2 > g_prim.drawH && y3 > g_prim.drawH)
+ return;
+ if (x1 < g_prim.drawX && x2 < g_prim.drawX && x3 < g_prim.drawX)
+ return;
+ if (y1 < g_prim.drawY && y2 < g_prim.drawY && y3 < g_prim.drawY)
+ return;
+ if (g_prim.drawY >= g_prim.drawH)
+ return;
+ if (g_prim.drawX >= g_prim.drawW)
+ return;
+
+ if (!SetupSections_FT(x1, y1, x2, y2, x3, y3, tx1, ty1, tx2, ty2, tx3, ty3))
+ return;
+
+ ymax = g_soft.Ymax;
+
+ for (ymin = g_soft.Ymin; ymin < g_prim.drawY; ymin++)
+ if (NextRow_FT())
+ return;
+
+ difX = delta_right_u;
+ difX2 = difX << 1;
+ difY = delta_right_v;
+ difY2 = difY << 1;
+
+#ifdef FASTSOLID
+
+ if (!g_draw.bCheckMask && !g_soft.DrawSemiTrans) {
+ for (i = ymin; i <= ymax; i++) {
+ xmin = (left_x >> 16);
+ xmax = (right_x >> 16) - 1; //!!!!!!!!!!!!!
+ if (g_prim.drawW < xmax)
+ xmax = g_prim.drawW;
+
+ if (xmax >= xmin) {
+ posX = left_u;
+ posY = left_v;
+
+ if (xmin < g_prim.drawX) {
+ j = g_prim.drawX - xmin;
+ xmin = g_prim.drawX;
+ posX += j * difX;
+ posY += j * difY;
+ }
+
+ for (j = xmin; j < xmax; j += 2) {
+ GetTextureTransColG32_S(
+ (uint32_t *) &g_gpu.psx_vram.u16[(i << 10) + j],
+ (((int32_t) GETLE16(&g_gpu.psx_vram.u16[(((((posY+difY)>>16)%g_prim.TWin.Position.y1)+g_soft.GlobalTextAddrY+g_prim.TWin.Position.y0)<<10)+
+ (((posX+difX)>>16)%g_prim.TWin.Position.x1)+g_soft.GlobalTextAddrX+g_prim.TWin.Position.x0]))
+ << 16)
+ | GETLE16(&g_gpu.psx_vram.u16[((((posY>>16)%g_prim.TWin.Position.y1)+g_soft.GlobalTextAddrY+g_prim.TWin.Position.y0)<<10)+
+ (((posX)>>16)%g_prim.TWin.Position.x1)+g_soft.GlobalTextAddrX+g_prim.TWin.Position.x0]));
+
+ posX += difX2;
+ posY += difY2;
+ }
+ if (j == xmax)
+ GetTextureTransColG_S(
+ &g_gpu.psx_vram.u16[(i << 10) + j],
+ GETLE16(&g_gpu.psx_vram.u16[((((posY>>16)%g_prim.TWin.Position.y1)+g_soft.GlobalTextAddrY+g_prim.TWin.Position.y0)<<10)+
+ ((posX>>16)%g_prim.TWin.Position.x1)+g_soft.GlobalTextAddrX+g_prim.TWin.Position.x0]));
+ }
+ if (NextRow_FT()) {
+ return;
+ }
+ }
+ return;
+ }
+
+#endif
+
+ for (i = ymin; i <= ymax; i++) {
+ xmin = (left_x >> 16);
+ xmax = (right_x >> 16) - 1; //!!!!!!!!!!!!!!
+ if (g_prim.drawW < xmax)
+ xmax = g_prim.drawW;
+
+ if (xmax >= xmin) {
+ posX = left_u;
+ posY = left_v;
+
+ if (xmin < g_prim.drawX) {
+ j = g_prim.drawX - xmin;
+ xmin = g_prim.drawX;
+ posX += j * difX;
+ posY += j * difY;
+ }
+
+ for (j = xmin; j < xmax; j += 2) {
+ GetTextureTransColG32(
+ (uint32_t *) &g_gpu.psx_vram.u16[(i << 10) + j],
+ (((int32_t) GETLE16(&g_gpu.psx_vram.u16[(((((posY+difY)>>16)%g_prim.TWin.Position.y1)+g_soft.GlobalTextAddrY+g_prim.TWin.Position.y0)<<10)+
+ (((posX+difX)>>16)%g_prim.TWin.Position.x1)+g_soft.GlobalTextAddrX+g_prim.TWin.Position.x0]))
+ << 16)
+ | GETLE16(&g_gpu.psx_vram.u16[((((posY>>16)%g_prim.TWin.Position.y1)+g_soft.GlobalTextAddrY+g_prim.TWin.Position.y0)<<10)+
+ (((posX)>>16)%g_prim.TWin.Position.x1)+g_soft.GlobalTextAddrX+g_prim.TWin.Position.x0]));
+
+ posX += difX2;
+ posY += difY2;
+ }
+ if (j == xmax)
+ GetTextureTransColG(
+ &g_gpu.psx_vram.u16[(i << 10) + j],
+ GETLE16(&g_gpu.psx_vram.u16[((((posY>>16)%g_prim.TWin.Position.y1)+g_soft.GlobalTextAddrY+g_prim.TWin.Position.y0)<<10)+
+ ((posX>>16)%g_prim.TWin.Position.x1)+g_soft.GlobalTextAddrX+g_prim.TWin.Position.x0]));
+ }
+ if (NextRow_FT()) {
+ return;
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+#ifdef POLYQUAD3
+
+void drawPoly4TD_TRI(short x1, short y1, short x2, short y2, short x3,
+ short y3, short x4, short y4, short tx1, short ty1, short tx2,
+ short ty2, short tx3, short ty3, short tx4, short ty4) {
+ drawPoly3TD(x2, y2, x3, y3, x4, y4, tx2, ty2, tx3, ty3, tx4, ty4);
+ drawPoly3TD(x1, y1, x2, y2, x4, y4, tx1, ty1, tx2, ty2, tx4, ty4);
+}
+
+#endif
+
+// more exact:
+
+void drawPoly4TD(short x1, short y1, short x2, short y2, short x3, short y3,
+ short x4, short y4, short tx1, short ty1, short tx2, short ty2,
+ short tx3, short ty3, short tx4, short ty4) {
+ int32_t num;
+ int32_t i, j, xmin, xmax, ymin, ymax;
+ int32_t difX, difY, difX2, difY2;
+ int32_t posX, posY;
+
+ if (x1 > g_prim.drawW && x2 > g_prim.drawW && x3 > g_prim.drawW && x4
+ > g_prim.drawW)
+ return;
+ if (y1 > g_prim.drawH && y2 > g_prim.drawH && y3 > g_prim.drawH && y4
+ > g_prim.drawH)
+ return;
+ if (x1 < g_prim.drawX && x2 < g_prim.drawX && x3 < g_prim.drawX && x4
+ < g_prim.drawX)
+ return;
+ if (y1 < g_prim.drawY && y2 < g_prim.drawY && y3 < g_prim.drawY && y4
+ < g_prim.drawY)
+ return;
+ if (g_prim.drawY >= g_prim.drawH)
+ return;
+ if (g_prim.drawX >= g_prim.drawW)
+ return;
+
+ if (!SetupSections_FT4(x1, y1, x2, y2, x3, y3, x4, y4, tx1, ty1, tx2, ty2,
+ tx3, ty3, tx4, ty4))
+ return;
+
+ ymax = g_soft.Ymax;
+
+ for (ymin = g_soft.Ymin; ymin < g_prim.drawY; ymin++)
+ if (NextRow_FT4())
+ return;
+
+#ifdef FASTSOLID
+
+ if (!g_draw.bCheckMask && !g_soft.DrawSemiTrans) {
+ for (i = ymin; i <= ymax; i++) {
+ xmin = (left_x >> 16);
+ xmax = (right_x >> 16);
+
+ if (xmax >= xmin) {
+ posX = left_u;
+ posY = left_v;
+
+ num = (xmax - xmin);
+ if (num == 0)
+ num = 1;
+ difX = (right_u - posX) / num;
+ difY = (right_v - posY) / num;
+ difX2 = difX << 1;
+ difY2 = difY << 1;
+
+ if (xmin < g_prim.drawX) {
+ j = g_prim.drawX - xmin;
+ xmin = g_prim.drawX;
+ posX += j * difX;
+ posY += j * difY;
+ }
+ xmax--;
+ if (g_prim.drawW < xmax)
+ xmax = g_prim.drawW;
+
+ for (j = xmin; j < xmax; j += 2) {
+ GetTextureTransColG32_S(
+ (uint32_t *) &g_gpu.psx_vram.u16[(i << 10) + j],
+ (((int32_t) GETLE16(&g_gpu.psx_vram.u16[((((posY+difY)>>16)+g_soft.GlobalTextAddrY)<<10)+((posX+difX)>>16)+g_soft.GlobalTextAddrX]))
+ << 16)
+ | GETLE16(&g_gpu.psx_vram.u16[(((posY>>16)+g_soft.GlobalTextAddrY)<<10)+((posX)>>16)+g_soft.GlobalTextAddrX]));
+
+ posX += difX2;
+ posY += difY2;
+ }
+ if (j == xmax)
+ GetTextureTransColG_S(
+ &g_gpu.psx_vram.u16[(i << 10) + j],
+ GETLE16(&g_gpu.psx_vram.u16[(((posY>>16)+g_soft.GlobalTextAddrY)<<10)+(posX>>16)+g_soft.GlobalTextAddrX]));
+ }
+ if (NextRow_FT4())
+ return;
+ }
+ return;
+ }
+
+#endif
+
+ for (i = ymin; i <= ymax; i++) {
+ xmin = (left_x >> 16);
+ xmax = (right_x >> 16);
+
+ if (xmax >= xmin) {
+ posX = left_u;
+ posY = left_v;
+
+ num = (xmax - xmin);
+ if (num == 0)
+ num = 1;
+ difX = (right_u - posX) / num;
+ difY = (right_v - posY) / num;
+ difX2 = difX << 1;
+ difY2 = difY << 1;
+
+ if (xmin < g_prim.drawX) {
+ j = g_prim.drawX - xmin;
+ xmin = g_prim.drawX;
+ posX += j * difX;
+ posY += j * difY;
+ }
+ xmax--;
+ if (g_prim.drawW < xmax)
+ xmax = g_prim.drawW;
+
+ for (j = xmin; j < xmax; j += 2) {
+ GetTextureTransColG32(
+ (uint32_t *) &g_gpu.psx_vram.u16[(i << 10) + j],
+ (((int32_t) GETLE16(&g_gpu.psx_vram.u16[((((posY+difY)>>16)+g_soft.GlobalTextAddrY)<<10)+((posX+difX)>>16)+g_soft.GlobalTextAddrX]))
+ << 16)
+ | GETLE16(&g_gpu.psx_vram.u16[(((posY>>16)+g_soft.GlobalTextAddrY)<<10)+((posX)>>16)+g_soft.GlobalTextAddrX]));
+
+ posX += difX2;
+ posY += difY2;
+ }
+ if (j == xmax)
+ GetTextureTransColG(
+ &g_gpu.psx_vram.u16[(i << 10) + j],
+ GETLE16(&g_gpu.psx_vram.u16[(((posY>>16)+g_soft.GlobalTextAddrY)<<10)+(posX>>16)+g_soft.GlobalTextAddrX]));
+ }
+ if (NextRow_FT4())
+ return;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void drawPoly4TD_TW(short x1, short y1, short x2, short y2, short x3, short y3,
+ short x4, short y4, short tx1, short ty1, short tx2, short ty2,
+ short tx3, short ty3, short tx4, short ty4) {
+ int32_t num;
+ int32_t i, j, xmin, xmax, ymin, ymax;
+ int32_t difX, difY, difX2, difY2;
+ int32_t posX, posY;
+
+ if (x1 > g_prim.drawW && x2 > g_prim.drawW && x3 > g_prim.drawW && x4
+ > g_prim.drawW)
+ return;
+ if (y1 > g_prim.drawH && y2 > g_prim.drawH && y3 > g_prim.drawH && y4
+ > g_prim.drawH)
+ return;
+ if (x1 < g_prim.drawX && x2 < g_prim.drawX && x3 < g_prim.drawX && x4
+ < g_prim.drawX)
+ return;
+ if (y1 < g_prim.drawY && y2 < g_prim.drawY && y3 < g_prim.drawY && y4
+ < g_prim.drawY)
+ return;
+ if (g_prim.drawY >= g_prim.drawH)
+ return;
+ if (g_prim.drawX >= g_prim.drawW)
+ return;
+
+ if (!SetupSections_FT4(x1, y1, x2, y2, x3, y3, x4, y4, tx1, ty1, tx2, ty2,
+ tx3, ty3, tx4, ty4))
+ return;
+
+ ymax = g_soft.Ymax;
+
+ for (ymin = g_soft.Ymin; ymin < g_prim.drawY; ymin++)
+ if (NextRow_FT4())
+ return;
+
+#ifdef FASTSOLID
+
+ if (!g_draw.bCheckMask && !g_soft.DrawSemiTrans) {
+ for (i = ymin; i <= ymax; i++) {
+ xmin = (left_x >> 16);
+ xmax = (right_x >> 16);
+
+ if (xmax >= xmin) {
+ posX = left_u;
+ posY = left_v;
+
+ num = (xmax - xmin);
+ if (num == 0)
+ num = 1;
+ difX = (right_u - posX) / num;
+ difY = (right_v - posY) / num;
+ difX2 = difX << 1;
+ difY2 = difY << 1;
+
+ if (xmin < g_prim.drawX) {
+ j = g_prim.drawX - xmin;
+ xmin = g_prim.drawX;
+ posX += j * difX;
+ posY += j * difY;
+ }
+ xmax--;
+ if (g_prim.drawW < xmax)
+ xmax = g_prim.drawW;
+
+ for (j = xmin; j < xmax; j += 2) {
+ GetTextureTransColG32_S(
+ (uint32_t *) &g_gpu.psx_vram.u16[(i << 10) + j],
+ (((int32_t) GETLE16(&g_gpu.psx_vram.u16[(((((posY+difY)>>16)%g_prim.TWin.Position.y1)+g_soft.GlobalTextAddrY+g_prim.TWin.Position.y0)<<10)+
+ (((posX+difX)>>16)%g_prim.TWin.Position.x1)+g_soft.GlobalTextAddrX+g_prim.TWin.Position.x0]))
+ << 16)
+ | GETLE16(&g_gpu.psx_vram.u16[((((posY>>16)%g_prim.TWin.Position.y1)+g_soft.GlobalTextAddrY)<<10)+g_prim.TWin.Position.y0+
+ ((posX>>16)%g_prim.TWin.Position.x1)+g_soft.GlobalTextAddrX+g_prim.TWin.Position.x0]));
+
+ posX += difX2;
+ posY += difY2;
+ }
+ if (j == xmax)
+ GetTextureTransColG_S(
+ &g_gpu.psx_vram.u16[(i << 10) + j],
+ GETLE16(&g_gpu.psx_vram.u16[((((posY>>16)%g_prim.TWin.Position.y1)+g_soft.GlobalTextAddrY+g_prim.TWin.Position.y0)<<10)+
+ ((posX>>16)%g_prim.TWin.Position.x1)+g_soft.GlobalTextAddrX+g_prim.TWin.Position.x0]));
+ }
+ if (NextRow_FT4())
+ return;
+ }
+ return;
+ }
+
+#endif
+
+ for (i = ymin; i <= ymax; i++) {
+ xmin = (left_x >> 16);
+ xmax = (right_x >> 16);
+
+ if (xmax >= xmin) {
+ posX = left_u;
+ posY = left_v;
+
+ num = (xmax - xmin);
+ if (num == 0)
+ num = 1;
+ difX = (right_u - posX) / num;
+ difY = (right_v - posY) / num;
+ difX2 = difX << 1;
+ difY2 = difY << 1;
+
+ if (xmin < g_prim.drawX) {
+ j = g_prim.drawX - xmin;
+ xmin = g_prim.drawX;
+ posX += j * difX;
+ posY += j * difY;
+ }
+ xmax--;
+ if (g_prim.drawW < xmax)
+ xmax = g_prim.drawW;
+
+ for (j = xmin; j < xmax; j += 2) {
+ GetTextureTransColG32(
+ (uint32_t *) &g_gpu.psx_vram.u16[(i << 10) + j],
+ (((int32_t) GETLE16(&g_gpu.psx_vram.u16[(((((posY+difY)>>16)%g_prim.TWin.Position.y1)+g_soft.GlobalTextAddrY+g_prim.TWin.Position.y0)<<10)+
+ (((posX+difX)>>16)%g_prim.TWin.Position.x1)+g_soft.GlobalTextAddrX+g_prim.TWin.Position.x0]))
+ << 16)
+ | GETLE16(&g_gpu.psx_vram.u16[((((posY>>16)%g_prim.TWin.Position.y1)+g_soft.GlobalTextAddrY+g_prim.TWin.Position.y0)<<10)+
+ ((posX>>16)%g_prim.TWin.Position.x1)+g_soft.GlobalTextAddrX+g_prim.TWin.Position.x0]));
+
+ posX += difX2;
+ posY += difY2;
+ }
+ if (j == xmax)
+ GetTextureTransColG(
+ &g_gpu.psx_vram.u16[(i << 10) + j],
+ GETLE16(&g_gpu.psx_vram.u16[((((posY>>16)%g_prim.TWin.Position.y1)+g_soft.GlobalTextAddrY+g_prim.TWin.Position.y0)<<10)+
+ ((posX>>16)%g_prim.TWin.Position.x1)+g_soft.GlobalTextAddrX+g_prim.TWin.Position.x0]));
+ }
+ if (NextRow_FT4())
+ return;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void drawPoly4TD_TW_S(short x1, short y1, short x2, short y2, short x3,
+ short y3, short x4, short y4, short tx1, short ty1, short tx2,
+ short ty2, short tx3, short ty3, short tx4, short ty4) {
+ int32_t num;
+ int32_t i, j, xmin, xmax, ymin, ymax;
+ int32_t difX, difY, difX2, difY2;
+ int32_t posX, posY;
+
+ if (x1 > g_prim.drawW && x2 > g_prim.drawW && x3 > g_prim.drawW && x4
+ > g_prim.drawW)
+ return;
+ if (y1 > g_prim.drawH && y2 > g_prim.drawH && y3 > g_prim.drawH && y4
+ > g_prim.drawH)
+ return;
+ if (x1 < g_prim.drawX && x2 < g_prim.drawX && x3 < g_prim.drawX && x4
+ < g_prim.drawX)
+ return;
+ if (y1 < g_prim.drawY && y2 < g_prim.drawY && y3 < g_prim.drawY && y4
+ < g_prim.drawY)
+ return;
+ if (g_prim.drawY >= g_prim.drawH)
+ return;
+ if (g_prim.drawX >= g_prim.drawW)
+ return;
+
+ if (!SetupSections_FT4(x1, y1, x2, y2, x3, y3, x4, y4, tx1, ty1, tx2, ty2,
+ tx3, ty3, tx4, ty4))
+ return;
+
+ ymax = g_soft.Ymax;
+
+ for (ymin = g_soft.Ymin; ymin < g_prim.drawY; ymin++)
+ if (NextRow_FT4())
+ return;
+
+#ifdef FASTSOLID
+
+ if (!g_draw.bCheckMask && !g_soft.DrawSemiTrans) {
+ for (i = ymin; i <= ymax; i++) {
+ xmin = (left_x >> 16);
+ xmax = (right_x >> 16);
+
+ if (xmax >= xmin) {
+ posX = left_u;
+ posY = left_v;
+
+ num = (xmax - xmin);
+ if (num == 0)
+ num = 1;
+ difX = (right_u - posX) / num;
+ difY = (right_v - posY) / num;
+ difX2 = difX << 1;
+ difY2 = difY << 1;
+
+ if (xmin < g_prim.drawX) {
+ j = g_prim.drawX - xmin;
+ xmin = g_prim.drawX;
+ posX += j * difX;
+ posY += j * difY;
+ }
+ xmax--;
+ if (g_prim.drawW < xmax)
+ xmax = g_prim.drawW;
+
+ for (j = xmin; j < xmax; j += 2) {
+ GetTextureTransColG32_S(
+ (uint32_t *) &g_gpu.psx_vram.u16[(i << 10) + j],
+ (((int32_t) GETLE16(&g_gpu.psx_vram.u16[(((((posY+difY)>>16)%g_prim.TWin.Position.y1)+g_soft.GlobalTextAddrY+g_prim.TWin.Position.y0)<<10)+
+ (((posX+difX)>>16)%g_prim.TWin.Position.x1)+g_soft.GlobalTextAddrX+g_prim.TWin.Position.x0]))
+ << 16)
+ | GETLE16(&g_gpu.psx_vram.u16[((((posY>>16)%g_prim.TWin.Position.y1)+g_soft.GlobalTextAddrY)<<10)+g_prim.TWin.Position.y0+
+ ((posX>>16)%g_prim.TWin.Position.x1)+g_soft.GlobalTextAddrX+g_prim.TWin.Position.x0]));
+
+ posX += difX2;
+ posY += difY2;
+ }
+ if (j == xmax)
+ GetTextureTransColG_S(
+ &g_gpu.psx_vram.u16[(i << 10) + j],
+ GETLE16(&g_gpu.psx_vram.u16[((((posY>>16)%g_prim.TWin.Position.y1)+g_soft.GlobalTextAddrY+g_prim.TWin.Position.y0)<<10)+
+ ((posX>>16)%g_prim.TWin.Position.x1)+g_soft.GlobalTextAddrX+g_prim.TWin.Position.x0]));
+ }
+ if (NextRow_FT4())
+ return;
+ }
+ return;
+ }
+
+#endif
+
+ for (i = ymin; i <= ymax; i++) {
+ xmin = (left_x >> 16);
+ xmax = (right_x >> 16);
+
+ if (xmax >= xmin) {
+ posX = left_u;
+ posY = left_v;
+
+ num = (xmax - xmin);
+ if (num == 0)
+ num = 1;
+ difX = (right_u - posX) / num;
+ difY = (right_v - posY) / num;
+ difX2 = difX << 1;
+ difY2 = difY << 1;
+
+ if (xmin < g_prim.drawX) {
+ j = g_prim.drawX - xmin;
+ xmin = g_prim.drawX;
+ posX += j * difX;
+ posY += j * difY;
+ }
+ xmax--;
+ if (g_prim.drawW < xmax)
+ xmax = g_prim.drawW;
+
+ for (j = xmin; j < xmax; j += 2) {
+ GetTextureTransColG32_SPR(
+ (uint32_t *) &g_gpu.psx_vram.u16[(i << 10) + j],
+ (((int32_t) GETLE16(&g_gpu.psx_vram.u16[(((((posY+difY)>>16)%g_prim.TWin.Position.y1)+g_soft.GlobalTextAddrY+g_prim.TWin.Position.y0)<<10)+
+ (((posX+difX)>>16)%g_prim.TWin.Position.x1)+g_soft.GlobalTextAddrX+g_prim.TWin.Position.x0]))
+ << 16)
+ | GETLE16(&g_gpu.psx_vram.u16[((((posY>>16)%g_prim.TWin.Position.y1)+g_soft.GlobalTextAddrY+g_prim.TWin.Position.y0)<<10)+
+ ((posX>>16)%g_prim.TWin.Position.x1)+g_soft.GlobalTextAddrX+g_prim.TWin.Position.x0]));
+
+ posX += difX2;
+ posY += difY2;
+ }
+ if (j == xmax)
+ GetTextureTransColG_SPR(
+ &g_gpu.psx_vram.u16[(i << 10) + j],
+ GETLE16(&g_gpu.psx_vram.u16[((((posY>>16)%g_prim.TWin.Position.y1)+g_soft.GlobalTextAddrY+g_prim.TWin.Position.y0)<<10)+
+ ((posX>>16)%g_prim.TWin.Position.x1)+g_soft.GlobalTextAddrX+g_prim.TWin.Position.x0]));
+ }
+ if (NextRow_FT4())
+ return;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+// POLY 3/4 G-SHADED
+////////////////////////////////////////////////////////////////////////
+
+inline void drawPoly3Gi(short x1, short y1, short x2, short y2, short x3,
+ short y3, int32_t rgb1, int32_t rgb2, int32_t rgb3) {
+ int i, j, xmin, xmax, ymin, ymax;
+ int32_t cR1, cG1, cB1;
+ int32_t difR, difB, difG, difR2, difB2, difG2;
+
+ if (x1 > g_prim.drawW && x2 > g_prim.drawW && x3 > g_prim.drawW)
+ return;
+ if (y1 > g_prim.drawH && y2 > g_prim.drawH && y3 > g_prim.drawH)
+ return;
+ if (x1 < g_prim.drawX && x2 < g_prim.drawX && x3 < g_prim.drawX)
+ return;
+ if (y1 < g_prim.drawY && y2 < g_prim.drawY && y3 < g_prim.drawY)
+ return;
+ if (g_prim.drawY >= g_prim.drawH)
+ return;
+ if (g_prim.drawX >= g_prim.drawW)
+ return;
+
+ if (!SetupSections_G(x1, y1, x2, y2, x3, y3, rgb1, rgb2, rgb3))
+ return;
+
+ ymax = g_soft.Ymax;
+
+ for (ymin = g_soft.Ymin; ymin < g_prim.drawY; ymin++)
+ if (NextRow_G())
+ return;
+
+ difR = delta_right_R;
+ difG = delta_right_G;
+ difB = delta_right_B;
+ difR2 = difR << 1;
+ difG2 = difG << 1;
+ difB2 = difB << 1;
+
+#ifdef FASTSOLID
+
+ if (!g_draw.bCheckMask && !g_soft.DrawSemiTrans && g_prim.iDither != 2) {
+ for (i = ymin; i <= ymax; i++) {
+ xmin = (left_x >> 16);
+ xmax = (right_x >> 16) - 1;
+ if (g_prim.drawW < xmax)
+ xmax = g_prim.drawW;
+
+ if (xmax >= xmin) {
+ cR1 = left_R;
+ cG1 = left_G;
+ cB1 = left_B;
+
+ if (xmin < g_prim.drawX) {
+ j = g_prim.drawX - xmin;
+ xmin = g_prim.drawX;
+ cR1 += j * difR;
+ cG1 += j * difG;
+ cB1 += j * difB;
+ }
+
+ for (j = xmin; j < xmax; j += 2) {
+ PUTLE32(((uint32_t *)&g_gpu.psx_vram.u16[(i<<10)+j]),
+ ((((cR1+difR) <<7)&0x7c000000)|(((cG1+difG) << 2)&0x03e00000)|(((cB1+difB)>>3)&0x001f0000)|
+ (((cR1) >> 9)&0x7c00)|(((cG1) >> 14)&0x03e0)|(((cB1) >> 19)&0x001f))|g_draw.lSetMask);
+
+ cR1 += difR2;
+ cG1 += difG2;
+ cB1 += difB2;
+ }
+ if (j == xmax)
+ PUTLE16(&g_gpu.psx_vram.u16[(i<<10)+j], (((cR1 >> 9)&0x7c00)|((cG1 >> 14)&0x03e0)|((cB1 >> 19)&0x001f))|g_draw.sSetMask);
+ }
+ if (NextRow_G())
+ return;
+ }
+ return;
+ }
+
+#endif
+
+ if (g_prim.iDither == 2)
+ for (i = ymin; i <= ymax; i++) {
+ xmin = (left_x >> 16);
+ xmax = (right_x >> 16) - 1;
+ if (g_prim.drawW < xmax)
+ xmax = g_prim.drawW;
+
+ if (xmax >= xmin) {
+ cR1 = left_R;
+ cG1 = left_G;
+ cB1 = left_B;
+
+ if (xmin < g_prim.drawX) {
+ j = g_prim.drawX - xmin;
+ xmin = g_prim.drawX;
+ cR1 += j * difR;
+ cG1 += j * difG;
+ cB1 += j * difB;
+ }
+
+ for (j = xmin; j <= xmax; j++) {
+ GetShadeTransCol_Dither(&g_gpu.psx_vram.u16[(i << 10) + j],
+ (cB1 >> 16), (cG1 >> 16), (cR1 >> 16));
+
+ cR1 += difR;
+ cG1 += difG;
+ cB1 += difB;
+ }
+ }
+ if (NextRow_G())
+ return;
+ }
+ else
+ for (i = ymin; i <= ymax; i++) {
+ xmin = (left_x >> 16);
+ xmax = (right_x >> 16) - 1;
+ if (g_prim.drawW < xmax)
+ xmax = g_prim.drawW;
+
+ if (xmax >= xmin) {
+ cR1 = left_R;
+ cG1 = left_G;
+ cB1 = left_B;
+
+ if (xmin < g_prim.drawX) {
+ j = g_prim.drawX - xmin;
+ xmin = g_prim.drawX;
+ cR1 += j * difR;
+ cG1 += j * difG;
+ cB1 += j * difB;
+ }
+
+ for (j = xmin; j <= xmax; j++) {
+ GetShadeTransCol(&g_gpu.psx_vram.u16[(i << 10) + j], ((cR1
+ >> 9) & 0x7c00) | ((cG1 >> 14) & 0x03e0) | ((cB1
+ >> 19) & 0x001f));
+
+ cR1 += difR;
+ cG1 += difG;
+ cB1 += difB;
+ }
+ }
+ if (NextRow_G())
+ return;
+ }
+
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void drawPoly3G(int32_t rgb1, int32_t rgb2, int32_t rgb3) {
+ drawPoly3Gi(g_soft.lx0, g_soft.ly0, g_soft.lx1, g_soft.ly1, g_soft.lx2,
+ g_soft.ly2, rgb1, rgb2, rgb3);
+}
+
+// draw two g-shaded tris for right psx shading emulation
+
+void drawPoly4G(int32_t rgb1, int32_t rgb2, int32_t rgb3, int32_t rgb4) {
+ drawPoly3Gi(g_soft.lx1, g_soft.ly1, g_soft.lx3, g_soft.ly3, g_soft.lx2,
+ g_soft.ly2, rgb2, rgb4, rgb3);
+ drawPoly3Gi(g_soft.lx0, g_soft.ly0, g_soft.lx1, g_soft.ly1, g_soft.lx2,
+ g_soft.ly2, rgb1, rgb2, rgb3);
+}
+
+////////////////////////////////////////////////////////////////////////
+// POLY 3/4 G-SHADED TEX PAL4
+////////////////////////////////////////////////////////////////////////
+
+void drawPoly3TGEx4(short x1, short y1, short x2, short y2, short x3, short y3,
+ short tx1, short ty1, short tx2, short ty2, short tx3, short ty3,
+ short clX, short clY, int32_t col1, int32_t col2, int32_t col3) {
+ int i, j, xmin, xmax, ymin, ymax;
+ int32_t cR1, cG1, cB1;
+ int32_t difR, difB, difG, difR2, difB2, difG2;
+ int32_t difX, difY, difX2, difY2;
+ int32_t posX, posY, YAdjust, clutP, XAdjust;
+ short tC1, tC2;
+
+ if (x1 > g_prim.drawW && x2 > g_prim.drawW && x3 > g_prim.drawW)
+ return;
+ if (y1 > g_prim.drawH && y2 > g_prim.drawH && y3 > g_prim.drawH)
+ return;
+ if (x1 < g_prim.drawX && x2 < g_prim.drawX && x3 < g_prim.drawX)
+ return;
+ if (y1 < g_prim.drawY && y2 < g_prim.drawY && y3 < g_prim.drawY)
+ return;
+ if (g_prim.drawY >= g_prim.drawH)
+ return;
+ if (g_prim.drawX >= g_prim.drawW)
+ return;
+
+ if (!SetupSections_GT(x1, y1, x2, y2, x3, y3, tx1, ty1, tx2, ty2, tx3, ty3,
+ col1, col2, col3))
+ return;
+
+ ymax = g_soft.Ymax;
+
+ for (ymin = g_soft.Ymin; ymin < g_prim.drawY; ymin++)
+ if (NextRow_GT())
+ return;
+
+ clutP = (clY << 10) + clX;
+
+ YAdjust = ((g_soft.GlobalTextAddrY) << 11) + (g_soft.GlobalTextAddrX << 1);
+
+ difR = delta_right_R;
+ difG = delta_right_G;
+ difB = delta_right_B;
+ difR2 = difR << 1;
+ difG2 = difG << 1;
+ difB2 = difB << 1;
+
+ difX = delta_right_u;
+ difX2 = difX << 1;
+ difY = delta_right_v;
+ difY2 = difY << 1;
+
+#ifdef FASTSOLID
+
+ if (!g_draw.bCheckMask && !g_soft.DrawSemiTrans && !g_prim.iDither) {
+ for (i = ymin; i <= ymax; i++) {
+ xmin = ((left_x) >> 16);
+ xmax = ((right_x) >> 16) - 1; //!!!!!!!!!!!!!
+ if (g_prim.drawW < xmax)
+ xmax = g_prim.drawW;
+
+ if (xmax >= xmin) {
+ posX = left_u;
+ posY = left_v;
+ cR1 = left_R;
+ cG1 = left_G;
+ cB1 = left_B;
+
+ if (xmin < g_prim.drawX) {
+ j = g_prim.drawX - xmin;
+ xmin = g_prim.drawX;
+ posX += j * difX;
+ posY += j * difY;
+ cR1 += j * difR;
+ cG1 += j * difG;
+ cB1 += j * difB;
+ }
+
+ for (j = xmin; j < xmax; j += 2) {
+ XAdjust = (posX >> 16);
+ tC1 = g_gpu.psx_vram.u8[((posY >> 5) & 0xFFFFF800)
+ + YAdjust + (XAdjust >> 1)];
+ tC1 = (tC1 >> ((XAdjust & 1) << 2)) & 0xf;
+ XAdjust = ((posX + difX) >> 16);
+ tC2 = g_gpu.psx_vram.u8[(((posY + difY) >> 5)
+ & (int32_t) 0xFFFFF800) + YAdjust + (XAdjust >> 1)];
+ tC2 = (tC2 >> ((XAdjust & 1) << 2)) & 0xf;
+
+ GetTextureTransColGX32_S(
+ (uint32_t *) &g_gpu.psx_vram.u16[(i << 10) + j],
+ GETLE16(&g_gpu.psx_vram.u16[clutP+tC1])
+ | ((int32_t) GETLE16(&g_gpu.psx_vram.u16[clutP+tC2]))
+ << 16, (cB1 >> 16) | ((cB1 + difB)
+ & 0xff0000), (cG1 >> 16) | ((cG1 + difG)
+ & 0xff0000), (cR1 >> 16) | ((cR1 + difR)
+ & 0xff0000));
+ posX += difX2;
+ posY += difY2;
+ cR1 += difR2;
+ cG1 += difG2;
+ cB1 += difB2;
+ }
+ if (j == xmax) {
+ XAdjust = (posX >> 16);
+ tC1
+ = g_gpu.psx_vram.u8[((posY >> 5)
+ & (int32_t) 0xFFFFF800) + YAdjust
+ + (XAdjust >> 1)];
+ tC1 = (tC1 >> ((XAdjust & 1) << 2)) & 0xf;
+ GetTextureTransColGX_S(&g_gpu.psx_vram.u16[(i << 10) + j],
+ GETLE16(&g_gpu.psx_vram.u16[clutP+tC1]),
+ (cB1 >> 16), (cG1 >> 16), (cR1 >> 16));
+ }
+ }
+ if (NextRow_GT()) {
+ return;
+ }
+ }
+ return;
+ }
+
+#endif
+
+ for (i = ymin; i <= ymax; i++) {
+ xmin = (left_x >> 16);
+ xmax = (right_x >> 16) - 1; //!!!!!!!!!!!!!!!!
+ if (g_prim.drawW < xmax)
+ xmax = g_prim.drawW;
+
+ if (xmax >= xmin) {
+ posX = left_u;
+ posY = left_v;
+ cR1 = left_R;
+ cG1 = left_G;
+ cB1 = left_B;
+
+ if (xmin < g_prim.drawX) {
+ j = g_prim.drawX - xmin;
+ xmin = g_prim.drawX;
+ posX += j * difX;
+ posY += j * difY;
+ cR1 += j * difR;
+ cG1 += j * difG;
+ cB1 += j * difB;
+ }
+
+ for (j = xmin; j <= xmax; j++) {
+ XAdjust = (posX >> 16);
+ tC1 = g_gpu.psx_vram.u8[((posY >> 5) & (int32_t) 0xFFFFF800)
+ + YAdjust + (XAdjust >> 1)];
+ tC1 = (tC1 >> ((XAdjust & 1) << 2)) & 0xf;
+ if (g_prim.iDither)
+ GetTextureTransColGX_Dither(&g_gpu.psx_vram.u16[(i << 10)
+ + j], GETLE16(&g_gpu.psx_vram.u16[clutP+tC1]), (cB1
+ >> 16), (cG1 >> 16), (cR1 >> 16));
+ else
+ GetTextureTransColGX(&g_gpu.psx_vram.u16[(i << 10) + j],
+ GETLE16(&g_gpu.psx_vram.u16[clutP+tC1]),
+ (cB1 >> 16), (cG1 >> 16), (cR1 >> 16));
+ posX += difX;
+ posY += difY;
+ cR1 += difR;
+ cG1 += difG;
+ cB1 += difB;
+ }
+ }
+ if (NextRow_GT()) {
+ return;
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void drawPoly3TGEx4_IL(short x1, short y1, short x2, short y2, short x3,
+ short y3, short tx1, short ty1, short tx2, short ty2, short tx3,
+ short ty3, short clX, short clY, int32_t col1, int32_t col2,
+ int32_t col3) {
+ int i, j, xmin, xmax, ymin, ymax, n_xi, n_yi, TXV;
+ int32_t cR1, cG1, cB1;
+ int32_t difR, difB, difG, difR2, difB2, difG2;
+ int32_t difX, difY, difX2, difY2;
+ int32_t posX, posY, YAdjust, clutP, XAdjust;
+ short tC1, tC2;
+
+ if (x1 > g_prim.drawW && x2 > g_prim.drawW && x3 > g_prim.drawW)
+ return;
+ if (y1 > g_prim.drawH && y2 > g_prim.drawH && y3 > g_prim.drawH)
+ return;
+ if (x1 < g_prim.drawX && x2 < g_prim.drawX && x3 < g_prim.drawX)
+ return;
+ if (y1 < g_prim.drawY && y2 < g_prim.drawY && y3 < g_prim.drawY)
+ return;
+ if (g_prim.drawY >= g_prim.drawH)
+ return;
+ if (g_prim.drawX >= g_prim.drawW)
+ return;
+
+ if (!SetupSections_GT(x1, y1, x2, y2, x3, y3, tx1, ty1, tx2, ty2, tx3, ty3,
+ col1, col2, col3))
+ return;
+
+ ymax = g_soft.Ymax;
+
+ for (ymin = g_soft.Ymin; ymin < g_prim.drawY; ymin++)
+ if (NextRow_GT())
+ return;
+
+ clutP = (clY << 10) + clX;
+
+ YAdjust = (g_soft.GlobalTextAddrY << 10) + g_soft.GlobalTextAddrX;
+
+ difR = delta_right_R;
+ difG = delta_right_G;
+ difB = delta_right_B;
+ difR2 = difR << 1;
+ difG2 = difG << 1;
+ difB2 = difB << 1;
+
+ difX = delta_right_u;
+ difX2 = difX << 1;
+ difY = delta_right_v;
+ difY2 = difY << 1;
+
+#ifdef FASTSOLID
+
+ if (!g_draw.bCheckMask && !g_soft.DrawSemiTrans && !g_prim.iDither) {
+ for (i = ymin; i <= ymax; i++) {
+ xmin = ((left_x) >> 16);
+ xmax = ((right_x) >> 16) - 1; //!!!!!!!!!!!!!
+ if (g_prim.drawW < xmax)
+ xmax = g_prim.drawW;
+
+ if (xmax >= xmin) {
+ posX = left_u;
+ posY = left_v;
+ cR1 = left_R;
+ cG1 = left_G;
+ cB1 = left_B;
+
+ if (xmin < g_prim.drawX) {
+ j = g_prim.drawX - xmin;
+ xmin = g_prim.drawX;
+ posX += j * difX;
+ posY += j * difY;
+ cR1 += j * difR;
+ cG1 += j * difG;
+ cB1 += j * difB;
+ }
+
+ for (j = xmin; j < xmax; j += 2) {
+ XAdjust = (posX >> 16);
+
+ TXV = posY >> 16;
+ n_xi = ((XAdjust >> 2) & ~0x3c) + ((TXV << 2) & 0x3c);
+ n_yi = (TXV & ~0xf) + ((XAdjust >> 4) & 0xf);
+
+ tC1
+ = (GETLE16(&g_gpu.psx_vram.u16[(n_yi<<10)+YAdjust+n_xi])
+ >> ((XAdjust & 0x03) << 2)) & 0x0f;
+
+ XAdjust = ((posX + difX) >> 16);
+
+ TXV = (posY + difY) >> 16;
+ n_xi = ((XAdjust >> 2) & ~0x3c) + ((TXV << 2) & 0x3c);
+ n_yi = (TXV & ~0xf) + ((XAdjust >> 4) & 0xf);
+
+ tC2
+ = (GETLE16(&g_gpu.psx_vram.u16[(n_yi<<10)+YAdjust+n_xi])
+ >> ((XAdjust & 0x03) << 2)) & 0x0f;
+
+ GetTextureTransColGX32_S(
+ (uint32_t *) &g_gpu.psx_vram.u16[(i << 10) + j],
+ GETLE16(&g_gpu.psx_vram.u16[clutP+tC1])
+ | ((int32_t) GETLE16(&g_gpu.psx_vram.u16[clutP+tC2]))
+ << 16, (cB1 >> 16) | ((cB1 + difB)
+ & 0xff0000), (cG1 >> 16) | ((cG1 + difG)
+ & 0xff0000), (cR1 >> 16) | ((cR1 + difR)
+ & 0xff0000));
+ posX += difX2;
+ posY += difY2;
+ cR1 += difR2;
+ cG1 += difG2;
+ cB1 += difB2;
+ }
+ if (j == xmax) {
+ XAdjust = (posX >> 16);
+
+ TXV = posY >> 16;
+ n_xi = ((XAdjust >> 2) & ~0x3c) + ((TXV << 2) & 0x3c);
+ n_yi = (TXV & ~0xf) + ((XAdjust >> 4) & 0xf);
+
+ tC1
+ = (GETLE16(&g_gpu.psx_vram.u16[(n_yi<<10)+YAdjust+n_xi])
+ >> ((XAdjust & 0x03) << 2)) & 0x0f;
+
+ GetTextureTransColGX_S(&g_gpu.psx_vram.u16[(i << 10) + j],
+ GETLE16(&g_gpu.psx_vram.u16[clutP+tC1]),
+ (cB1 >> 16), (cG1 >> 16), (cR1 >> 16));
+ }
+ }
+ if (NextRow_GT()) {
+ return;
+ }
+ }
+ return;
+ }
+
+#endif
+
+ for (i = ymin; i <= ymax; i++) {
+ xmin = (left_x >> 16);
+ xmax = (right_x >> 16) - 1; //!!!!!!!!!!!!!!!!
+ if (g_prim.drawW < xmax)
+ xmax = g_prim.drawW;
+
+ if (xmax >= xmin) {
+ posX = left_u;
+ posY = left_v;
+ cR1 = left_R;
+ cG1 = left_G;
+ cB1 = left_B;
+
+ if (xmin < g_prim.drawX) {
+ j = g_prim.drawX - xmin;
+ xmin = g_prim.drawX;
+ posX += j * difX;
+ posY += j * difY;
+ cR1 += j * difR;
+ cG1 += j * difG;
+ cB1 += j * difB;
+ }
+
+ for (j = xmin; j <= xmax; j++) {
+ XAdjust = (posX >> 16);
+
+ TXV = posY >> 16;
+ n_xi = ((XAdjust >> 2) & ~0x3c) + ((TXV << 2) & 0x3c);
+ n_yi = (TXV & ~0xf) + ((XAdjust >> 4) & 0xf);
+
+ tC1 = (GETLE16(&g_gpu.psx_vram.u16[(n_yi<<10)+YAdjust+n_xi])
+ >> ((XAdjust & 0x03) << 2)) & 0x0f;
+
+ if (g_prim.iDither)
+ GetTextureTransColGX_Dither(&g_gpu.psx_vram.u16[(i << 10)
+ + j], GETLE16(&g_gpu.psx_vram.u16[clutP+tC1]), (cB1
+ >> 16), (cG1 >> 16), (cR1 >> 16));
+ else
+ GetTextureTransColGX(&g_gpu.psx_vram.u16[(i << 10) + j],
+ GETLE16(&g_gpu.psx_vram.u16[clutP+tC1]),
+ (cB1 >> 16), (cG1 >> 16), (cR1 >> 16));
+ posX += difX;
+ posY += difY;
+ cR1 += difR;
+ cG1 += difG;
+ cB1 += difB;
+ }
+ }
+ if (NextRow_GT()) {
+ return;
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void drawPoly3TGEx4_TW(short x1, short y1, short x2, short y2, short x3,
+ short y3, short tx1, short ty1, short tx2, short ty2, short tx3,
+ short ty3, short clX, short clY, int32_t col1, int32_t col2,
+ int32_t col3) {
+ int i, j, xmin, xmax, ymin, ymax;
+ int32_t cR1, cG1, cB1;
+ int32_t difR, difB, difG, difR2, difB2, difG2;
+ int32_t difX, difY, difX2, difY2;
+ int32_t posX, posY, YAdjust, clutP, XAdjust;
+ short tC1, tC2;
+
+ if (x1 > g_prim.drawW && x2 > g_prim.drawW && x3 > g_prim.drawW)
+ return;
+ if (y1 > g_prim.drawH && y2 > g_prim.drawH && y3 > g_prim.drawH)
+ return;
+ if (x1 < g_prim.drawX && x2 < g_prim.drawX && x3 < g_prim.drawX)
+ return;
+ if (y1 < g_prim.drawY && y2 < g_prim.drawY && y3 < g_prim.drawY)
+ return;
+ if (g_prim.drawY >= g_prim.drawH)
+ return;
+ if (g_prim.drawX >= g_prim.drawW)
+ return;
+
+ if (!SetupSections_GT(x1, y1, x2, y2, x3, y3, tx1, ty1, tx2, ty2, tx3, ty3,
+ col1, col2, col3))
+ return;
+
+ ymax = g_soft.Ymax;
+
+ for (ymin = g_soft.Ymin; ymin < g_prim.drawY; ymin++)
+ if (NextRow_GT())
+ return;
+
+ clutP = (clY << 10) + clX;
+
+ YAdjust = ((g_soft.GlobalTextAddrY) << 11) + (g_soft.GlobalTextAddrX << 1);
+ YAdjust += (g_prim.TWin.Position.y0 << 11) + (g_prim.TWin.Position.x0 >> 1);
+
+ difR = delta_right_R;
+ difG = delta_right_G;
+ difB = delta_right_B;
+ difR2 = difR << 1;
+ difG2 = difG << 1;
+ difB2 = difB << 1;
+
+ difX = delta_right_u;
+ difX2 = difX << 1;
+ difY = delta_right_v;
+ difY2 = difY << 1;
+
+#ifdef FASTSOLID
+
+ if (!g_draw.bCheckMask && !g_soft.DrawSemiTrans && !g_prim.iDither) {
+ for (i = ymin; i <= ymax; i++) {
+ xmin = ((left_x) >> 16);
+ xmax = ((right_x) >> 16) - 1; //!!!!!!!!!!!!!
+ if (g_prim.drawW < xmax)
+ xmax = g_prim.drawW;
+
+ if (xmax >= xmin) {
+ posX = left_u;
+ posY = left_v;
+ cR1 = left_R;
+ cG1 = left_G;
+ cB1 = left_B;
+
+ if (xmin < g_prim.drawX) {
+ j = g_prim.drawX - xmin;
+ xmin = g_prim.drawX;
+ posX += j * difX;
+ posY += j * difY;
+ cR1 += j * difR;
+ cG1 += j * difG;
+ cB1 += j * difB;
+ }
+
+ for (j = xmin; j < xmax; j += 2) {
+ XAdjust = (posX >> 16) % g_prim.TWin.Position.x1;
+ tC1 = g_gpu.psx_vram.u8[(((posY >> 16)
+ % g_prim.TWin.Position.y1) << 11) + YAdjust
+ + (XAdjust >> 1)];
+ tC1 = (tC1 >> ((XAdjust & 1) << 2)) & 0xf;
+ XAdjust = ((posX + difX) >> 16) % g_prim.TWin.Position.x1;
+ tC2 = g_gpu.psx_vram.u8[((((posY + difY) >> 16)
+ % g_prim.TWin.Position.y1) << 11) + YAdjust
+ + (XAdjust >> 1)];
+ tC2 = (tC2 >> ((XAdjust & 1) << 2)) & 0xf;
+ GetTextureTransColGX32_S(
+ (uint32_t *) &g_gpu.psx_vram.u16[(i << 10) + j],
+ GETLE16(&g_gpu.psx_vram.u16[clutP+tC1])
+ | ((int32_t) GETLE16(&g_gpu.psx_vram.u16[clutP+tC2]))
+ << 16, (cB1 >> 16) | ((cB1 + difB)
+ & 0xff0000), (cG1 >> 16) | ((cG1 + difG)
+ & 0xff0000), (cR1 >> 16) | ((cR1 + difR)
+ & 0xff0000));
+ posX += difX2;
+ posY += difY2;
+ cR1 += difR2;
+ cG1 += difG2;
+ cB1 += difB2;
+ }
+ if (j == xmax) {
+ XAdjust = (posX >> 16) % g_prim.TWin.Position.x1;
+ tC1 = g_gpu.psx_vram.u8[(((posY >> 16)
+ % g_prim.TWin.Position.y1) << 11) + YAdjust
+ + (XAdjust >> 1)];
+ tC1 = (tC1 >> ((XAdjust & 1) << 2)) & 0xf;
+ GetTextureTransColGX_S(&g_gpu.psx_vram.u16[(i << 10) + j],
+ GETLE16(&g_gpu.psx_vram.u16[clutP+tC1]),
+ (cB1 >> 16), (cG1 >> 16), (cR1 >> 16));
+ }
+ }
+ if (NextRow_GT()) {
+ return;
+ }
+ }
+ return;
+ }
+
+#endif
+
+ for (i = ymin; i <= ymax; i++) {
+ xmin = (left_x >> 16);
+ xmax = (right_x >> 16) - 1; //!!!!!!!!!!!!!!!!
+ if (g_prim.drawW < xmax)
+ xmax = g_prim.drawW;
+
+ if (xmax >= xmin) {
+ posX = left_u;
+ posY = left_v;
+ cR1 = left_R;
+ cG1 = left_G;
+ cB1 = left_B;
+
+ if (xmin < g_prim.drawX) {
+ j = g_prim.drawX - xmin;
+ xmin = g_prim.drawX;
+ posX += j * difX;
+ posY += j * difY;
+ cR1 += j * difR;
+ cG1 += j * difG;
+ cB1 += j * difB;
+ }
+
+ for (j = xmin; j <= xmax; j++) {
+ XAdjust = (posX >> 16) % g_prim.TWin.Position.x1;
+ tC1 = g_gpu.psx_vram.u8[(((posY >> 16)
+ % g_prim.TWin.Position.y1) << 11) + YAdjust + (XAdjust
+ >> 1)];
+ tC1 = (tC1 >> ((XAdjust & 1) << 2)) & 0xf;
+ if (g_prim.iDither)
+ GetTextureTransColGX_Dither(&g_gpu.psx_vram.u16[(i << 10)
+ + j], GETLE16(&g_gpu.psx_vram.u16[clutP+tC1]), (cB1
+ >> 16), (cG1 >> 16), (cR1 >> 16));
+ else
+ GetTextureTransColGX(&g_gpu.psx_vram.u16[(i << 10) + j],
+ GETLE16(&g_gpu.psx_vram.u16[clutP+tC1]),
+ (cB1 >> 16), (cG1 >> 16), (cR1 >> 16));
+ posX += difX;
+ posY += difY;
+ cR1 += difR;
+ cG1 += difG;
+ cB1 += difB;
+ }
+ }
+ if (NextRow_GT()) {
+ return;
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+// note: the psx is doing g-shaded quads as two g-shaded tris,
+// like the following func... sadly texturing is not 100%
+// correct that way, so small texture distortions can
+// happen...
+
+void drawPoly4TGEx4_TRI_IL(short x1, short y1, short x2, short y2, short x3,
+ short y3, short x4, short y4, short tx1, short ty1, short tx2,
+ short ty2, short tx3, short ty3, short tx4, short ty4, short clX,
+ short clY, int32_t col1, int32_t col2, int32_t col3, int32_t col4) {
+ drawPoly3TGEx4_IL(x2, y2, x3, y3, x4, y4, tx2, ty2, tx3, ty3, tx4, ty4,
+ clX, clY, col2, col4, col3);
+ drawPoly3TGEx4_IL(x1, y1, x2, y2, x4, y4, tx1, ty1, tx2, ty2, tx4, ty4,
+ clX, clY, col1, col2, col3);
+}
+
+#ifdef POLYQUAD3GT
+
+void drawPoly4TGEx4_TRI(short x1, short y1, short x2, short y2, short x3,
+ short y3, short x4, short y4, short tx1, short ty1, short tx2,
+ short ty2, short tx3, short ty3, short tx4, short ty4, short clX,
+ short clY, int32_t col1, int32_t col2, int32_t col3, int32_t col4) {
+ drawPoly3TGEx4(x2, y2, x3, y3, x4, y4, tx2, ty2, tx3, ty3, tx4, ty4, clX,
+ clY, col2, col4, col3);
+ drawPoly3TGEx4(x1, y1, x2, y2, x4, y4, tx1, ty1, tx2, ty2, tx4, ty4, clX,
+ clY, col1, col2, col3);
+}
+
+#endif
+
+////////////////////////////////////////////////////////////////////////
+
+void drawPoly4TGEx4(short x1, short y1, short x2, short y2, short x3, short y3,
+ short x4, short y4, short tx1, short ty1, short tx2, short ty2,
+ short tx3, short ty3, short tx4, short ty4, short clX, short clY,
+ int32_t col1, int32_t col2, int32_t col4, int32_t col3) {
+ int32_t num;
+ int32_t i, j, xmin, xmax, ymin, ymax;
+ int32_t cR1, cG1, cB1;
+ int32_t difR, difB, difG, difR2, difB2, difG2;
+ int32_t difX, difY, difX2, difY2;
+ int32_t posX, posY, YAdjust, clutP, XAdjust;
+ short tC1, tC2;
+
+ if (x1 > g_prim.drawW && x2 > g_prim.drawW && x3 > g_prim.drawW && x4
+ > g_prim.drawW)
+ return;
+ if (y1 > g_prim.drawH && y2 > g_prim.drawH && y3 > g_prim.drawH && y4
+ > g_prim.drawH)
+ return;
+ if (x1 < g_prim.drawX && x2 < g_prim.drawX && x3 < g_prim.drawX && x4
+ < g_prim.drawX)
+ return;
+ if (y1 < g_prim.drawY && y2 < g_prim.drawY && y3 < g_prim.drawY && y4
+ < g_prim.drawY)
+ return;
+ if (g_prim.drawY >= g_prim.drawH)
+ return;
+ if (g_prim.drawX >= g_prim.drawW)
+ return;
+
+ if (!SetupSections_GT4(x1, y1, x2, y2, x3, y3, x4, y4, tx1, ty1, tx2, ty2,
+ tx3, ty3, tx4, ty4, col1, col2, col3, col4))
+ return;
+
+ ymax = g_soft.Ymax;
+
+ for (ymin = g_soft.Ymin; ymin < g_prim.drawY; ymin++)
+ if (NextRow_GT4())
+ return;
+
+ clutP = (clY << 10) + clX;
+
+ YAdjust = ((g_soft.GlobalTextAddrY) << 11) + (g_soft.GlobalTextAddrX << 1);
+
+#ifdef FASTSOLID
+
+ if (!g_draw.bCheckMask && !g_soft.DrawSemiTrans && !g_prim.iDither) {
+ for (i = ymin; i <= ymax; i++) {
+ xmin = (left_x >> 16);
+ xmax = (right_x >> 16);
+
+ if (xmax >= xmin) {
+ posX = left_u;
+ posY = left_v;
+
+ num = (xmax - xmin);
+ if (num == 0)
+ num = 1;
+ difX = (right_u - posX) / num;
+ difY = (right_v - posY) / num;
+ difX2 = difX << 1;
+ difY2 = difY << 1;
+
+ cR1 = left_R;
+ cG1 = left_G;
+ cB1 = left_B;
+ difR = (right_R - cR1) / num;
+ difG = (right_G - cG1) / num;
+ difB = (right_B - cB1) / num;
+ difR2 = difR << 1;
+ difG2 = difG << 1;
+ difB2 = difB << 1;
+
+ if (xmin < g_prim.drawX) {
+ j = g_prim.drawX - xmin;
+ xmin = g_prim.drawX;
+ posX += j * difX;
+ posY += j * difY;
+ cR1 += j * difR;
+ cG1 += j * difG;
+ cB1 += j * difB;
+ }
+ xmax--;
+ if (g_prim.drawW < xmax)
+ xmax = g_prim.drawW;
+
+ for (j = xmin; j < xmax; j += 2) {
+ XAdjust = (posX >> 16);
+ tC1
+ = g_gpu.psx_vram.u8[((posY >> 5)
+ & (int32_t) 0xFFFFF800) + YAdjust
+ + (XAdjust >> 1)];
+ tC1 = (tC1 >> ((XAdjust & 1) << 2)) & 0xf;
+ XAdjust = ((posX + difX) >> 16);
+ tC2 = g_gpu.psx_vram.u8[(((posY + difY) >> 5)
+ & (int32_t) 0xFFFFF800) + YAdjust + (XAdjust >> 1)];
+ tC2 = (tC2 >> ((XAdjust & 1) << 2)) & 0xf;
+
+ GetTextureTransColGX32_S(
+ (uint32_t *) &g_gpu.psx_vram.u16[(i << 10) + j],
+ GETLE16(&g_gpu.psx_vram.u16[clutP+tC1])
+ | ((int32_t) GETLE16(&g_gpu.psx_vram.u16[clutP+tC2]))
+ << 16, (cB1 >> 16) | ((cB1 + difB)
+ & 0xff0000), (cG1 >> 16) | ((cG1 + difG)
+ & 0xff0000), (cR1 >> 16) | ((cR1 + difR)
+ & 0xff0000));
+ posX += difX2;
+ posY += difY2;
+ cR1 += difR2;
+ cG1 += difG2;
+ cB1 += difB2;
+ }
+ if (j == xmax) {
+ XAdjust = (posX >> 16);
+ tC1
+ = g_gpu.psx_vram.u8[((posY >> 5)
+ & (int32_t) 0xFFFFF800) + YAdjust
+ + (XAdjust >> 1)];
+ tC1 = (tC1 >> ((XAdjust & 1) << 2)) & 0xf;
+
+ GetTextureTransColGX_S(&g_gpu.psx_vram.u16[(i << 10) + j],
+ GETLE16(&g_gpu.psx_vram.u16[clutP+tC1]),
+ (cB1 >> 16), (cG1 >> 16), (cR1 >> 16));
+ }
+ }
+ if (NextRow_GT4())
+ return;
+ }
+ return;
+ }
+
+#endif
+
+ for (i = ymin; i <= ymax; i++) {
+ xmin = (left_x >> 16);
+ xmax = (right_x >> 16);
+
+ if (xmax >= xmin) {
+ posX = left_u;
+ posY = left_v;
+
+ num = (xmax - xmin);
+ if (num == 0)
+ num = 1;
+ difX = (right_u - posX) / num;
+ difY = (right_v - posY) / num;
+ difX2 = difX << 1;
+ difY2 = difY << 1;
+
+ cR1 = left_R;
+ cG1 = left_G;
+ cB1 = left_B;
+ difR = (right_R - cR1) / num;
+ difG = (right_G - cG1) / num;
+ difB = (right_B - cB1) / num;
+ difR2 = difR << 1;
+ difG2 = difG << 1;
+ difB2 = difB << 1;
+
+ if (xmin < g_prim.drawX) {
+ j = g_prim.drawX - xmin;
+ xmin = g_prim.drawX;
+ posX += j * difX;
+ posY += j * difY;
+ cR1 += j * difR;
+ cG1 += j * difG;
+ cB1 += j * difB;
+ }
+ xmax--;
+ if (g_prim.drawW < xmax)
+ xmax = g_prim.drawW;
+
+ for (j = xmin; j <= xmax; j++) {
+ XAdjust = (posX >> 16);
+ tC1 = g_gpu.psx_vram.u8[((posY >> 5) & (int32_t) 0xFFFFF800)
+ + YAdjust + (XAdjust >> 1)];
+ tC1 = (tC1 >> ((XAdjust & 1) << 2)) & 0xf;
+ if (g_prim.iDither)
+ GetTextureTransColGX_Dither(&g_gpu.psx_vram.u16[(i << 10)
+ + j], GETLE16(&g_gpu.psx_vram.u16[clutP+tC1]), (cB1
+ >> 16), (cG1 >> 16), (cR1 >> 16));
+ else
+ GetTextureTransColGX(&g_gpu.psx_vram.u16[(i << 10) + j],
+ GETLE16(&g_gpu.psx_vram.u16[clutP+tC1]),
+ (cB1 >> 16), (cG1 >> 16), (cR1 >> 16));
+ posX += difX;
+ posY += difY;
+ cR1 += difR;
+ cG1 += difG;
+ cB1 += difB;
+ }
+ }
+ if (NextRow_GT4())
+ return;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void drawPoly4TGEx4_TW(short x1, short y1, short x2, short y2, short x3,
+ short y3, short x4, short y4, short tx1, short ty1, short tx2,
+ short ty2, short tx3, short ty3, short tx4, short ty4, short clX,
+ short clY, int32_t col1, int32_t col2, int32_t col3, int32_t col4) {
+ drawPoly3TGEx4_TW(x2, y2, x3, y3, x4, y4, tx2, ty2, tx3, ty3, tx4, ty4,
+ clX, clY, col2, col4, col3);
+
+ drawPoly3TGEx4_TW(x1, y1, x2, y2, x4, y4, tx1, ty1, tx2, ty2, tx4, ty4,
+ clX, clY, col1, col2, col3);
+}
+
+////////////////////////////////////////////////////////////////////////
+// POLY 3/4 G-SHADED TEX PAL8
+////////////////////////////////////////////////////////////////////////
+
+void drawPoly3TGEx8(short x1, short y1, short x2, short y2, short x3, short y3,
+ short tx1, short ty1, short tx2, short ty2, short tx3, short ty3,
+ short clX, short clY, int32_t col1, int32_t col2, int32_t col3) {
+ int i, j, xmin, xmax, ymin, ymax;
+ int32_t cR1, cG1, cB1;
+ int32_t difR, difB, difG, difR2, difB2, difG2;
+ int32_t difX, difY, difX2, difY2;
+ int32_t posX, posY, YAdjust, clutP;
+ short tC1, tC2;
+
+ if (x1 > g_prim.drawW && x2 > g_prim.drawW && x3 > g_prim.drawW)
+ return;
+ if (y1 > g_prim.drawH && y2 > g_prim.drawH && y3 > g_prim.drawH)
+ return;
+ if (x1 < g_prim.drawX && x2 < g_prim.drawX && x3 < g_prim.drawX)
+ return;
+ if (y1 < g_prim.drawY && y2 < g_prim.drawY && y3 < g_prim.drawY)
+ return;
+ if (g_prim.drawY >= g_prim.drawH)
+ return;
+ if (g_prim.drawX >= g_prim.drawW)
+ return;
+
+ if (!SetupSections_GT(x1, y1, x2, y2, x3, y3, tx1, ty1, tx2, ty2, tx3, ty3,
+ col1, col2, col3))
+ return;
+
+ ymax = g_soft.Ymax;
+
+ for (ymin = g_soft.Ymin; ymin < g_prim.drawY; ymin++)
+ if (NextRow_GT())
+ return;
+
+ clutP = (clY << 10) + clX;
+
+ YAdjust = ((g_soft.GlobalTextAddrY) << 11) + (g_soft.GlobalTextAddrX << 1);
+
+ difR = delta_right_R;
+ difG = delta_right_G;
+ difB = delta_right_B;
+ difR2 = difR << 1;
+ difG2 = difG << 1;
+ difB2 = difB << 1;
+ difX = delta_right_u;
+ difX2 = difX << 1;
+ difY = delta_right_v;
+ difY2 = difY << 1;
+
+#ifdef FASTSOLID
+
+ if (!g_draw.bCheckMask && !g_soft.DrawSemiTrans && !g_prim.iDither) {
+ for (i = ymin; i <= ymax; i++) {
+ xmin = (left_x >> 16);
+ xmax = (right_x >> 16) - 1; // !!!!!!!!!!!!!
+ if (g_prim.drawW < xmax)
+ xmax = g_prim.drawW;
+
+ if (xmax >= xmin) {
+ posX = left_u;
+ posY = left_v;
+ cR1 = left_R;
+ cG1 = left_G;
+ cB1 = left_B;
+
+ if (xmin < g_prim.drawX) {
+ j = g_prim.drawX - xmin;
+ xmin = g_prim.drawX;
+ posX += j * difX;
+ posY += j * difY;
+ cR1 += j * difR;
+ cG1 += j * difG;
+ cB1 += j * difB;
+ }
+
+ for (j = xmin; j < xmax; j += 2) {
+ tC1
+ = g_gpu.psx_vram.u8[((posY >> 5)
+ & (int32_t) 0xFFFFF800) + YAdjust + ((posX
+ >> 16))];
+ tC2 = g_gpu.psx_vram.u8[(((posY + difY) >> 5)
+ & (int32_t) 0xFFFFF800) + YAdjust + (((posX + difX)
+ >> 16))];
+ GetTextureTransColGX32_S(
+ (uint32_t *) &g_gpu.psx_vram.u16[(i << 10) + j],
+ GETLE16(&g_gpu.psx_vram.u16[clutP+tC1])
+ | ((int32_t) GETLE16(&g_gpu.psx_vram.u16[clutP+tC2]))
+ << 16, (cB1 >> 16) | ((cB1 + difB)
+ & 0xff0000), (cG1 >> 16) | ((cG1 + difG)
+ & 0xff0000), (cR1 >> 16) | ((cR1 + difR)
+ & 0xff0000));
+ posX += difX2;
+ posY += difY2;
+ cR1 += difR2;
+ cG1 += difG2;
+ cB1 += difB2;
+ }
+ if (j == xmax) {
+ tC1
+ = g_gpu.psx_vram.u8[((posY >> 5)
+ & (int32_t) 0xFFFFF800) + YAdjust + ((posX
+ >> 16))];
+ GetTextureTransColGX_S(&g_gpu.psx_vram.u16[(i << 10) + j],
+ GETLE16(&g_gpu.psx_vram.u16[clutP+tC1]),
+ (cB1 >> 16), (cG1 >> 16), (cR1 >> 16));
+ }
+ }
+ if (NextRow_GT()) {
+ return;
+ }
+ }
+ return;
+ }
+
+#endif
+
+ for (i = ymin; i <= ymax; i++) {
+ xmin = (left_x >> 16);
+ xmax = (right_x >> 16) - 1; //!!!!!!!!!!!!!!!!!!!!!!!
+ if (g_prim.drawW < xmax)
+ xmax = g_prim.drawW;
+
+ if (xmax >= xmin) {
+ posX = left_u;
+ posY = left_v;
+ cR1 = left_R;
+ cG1 = left_G;
+ cB1 = left_B;
+
+ if (xmin < g_prim.drawX) {
+ j = g_prim.drawX - xmin;
+ xmin = g_prim.drawX;
+ posX += j * difX;
+ posY += j * difY;
+ cR1 += j * difR;
+ cG1 += j * difG;
+ cB1 += j * difB;
+ }
+
+ for (j = xmin; j <= xmax; j++) {
+ tC1 = g_gpu.psx_vram.u8[((posY >> 5) & (int32_t) 0xFFFFF800)
+ + YAdjust + ((posX >> 16))];
+ if (g_prim.iDither)
+ GetTextureTransColGX_Dither(&g_gpu.psx_vram.u16[(i << 10)
+ + j], GETLE16(&g_gpu.psx_vram.u16[clutP+tC1]), (cB1
+ >> 16), (cG1 >> 16), (cR1 >> 16));
+ else
+ GetTextureTransColGX(&g_gpu.psx_vram.u16[(i << 10) + j],
+ GETLE16(&g_gpu.psx_vram.u16[clutP+tC1]),
+ (cB1 >> 16), (cG1 >> 16), (cR1 >> 16));
+ posX += difX;
+ posY += difY;
+ cR1 += difR;
+ cG1 += difG;
+ cB1 += difB;
+ }
+ }
+ if (NextRow_GT()) {
+ return;
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void drawPoly3TGEx8_IL(short x1, short y1, short x2, short y2, short x3,
+ short y3, short tx1, short ty1, short tx2, short ty2, short tx3,
+ short ty3, short clX, short clY, int32_t col1, int32_t col2,
+ int32_t col3) {
+ int i, j, xmin, xmax, ymin, ymax, n_xi, n_yi, TXV, TXU;
+ int32_t cR1, cG1, cB1;
+ int32_t difR, difB, difG, difR2, difB2, difG2;
+ int32_t difX, difY, difX2, difY2;
+ int32_t posX, posY, YAdjust, clutP;
+ short tC1, tC2;
+
+ if (x1 > g_prim.drawW && x2 > g_prim.drawW && x3 > g_prim.drawW)
+ return;
+ if (y1 > g_prim.drawH && y2 > g_prim.drawH && y3 > g_prim.drawH)
+ return;
+ if (x1 < g_prim.drawX && x2 < g_prim.drawX && x3 < g_prim.drawX)
+ return;
+ if (y1 < g_prim.drawY && y2 < g_prim.drawY && y3 < g_prim.drawY)
+ return;
+ if (g_prim.drawY >= g_prim.drawH)
+ return;
+ if (g_prim.drawX >= g_prim.drawW)
+ return;
+
+ if (!SetupSections_GT(x1, y1, x2, y2, x3, y3, tx1, ty1, tx2, ty2, tx3, ty3,
+ col1, col2, col3))
+ return;
+
+ ymax = g_soft.Ymax;
+
+ for (ymin = g_soft.Ymin; ymin < g_prim.drawY; ymin++)
+ if (NextRow_GT())
+ return;
+
+ clutP = (clY << 10) + clX;
+
+ YAdjust = (g_soft.GlobalTextAddrY << 10) + g_soft.GlobalTextAddrX;
+
+ difR = delta_right_R;
+ difG = delta_right_G;
+ difB = delta_right_B;
+ difR2 = difR << 1;
+ difG2 = difG << 1;
+ difB2 = difB << 1;
+ difX = delta_right_u;
+ difX2 = difX << 1;
+ difY = delta_right_v;
+ difY2 = difY << 1;
+
+#ifdef FASTSOLID
+
+ if (!g_draw.bCheckMask && !g_soft.DrawSemiTrans && !g_prim.iDither) {
+ for (i = ymin; i <= ymax; i++) {
+ xmin = (left_x >> 16);
+ xmax = (right_x >> 16) - 1; // !!!!!!!!!!!!!
+ if (g_prim.drawW < xmax)
+ xmax = g_prim.drawW;
+
+ if (xmax >= xmin) {
+ posX = left_u;
+ posY = left_v;
+ cR1 = left_R;
+ cG1 = left_G;
+ cB1 = left_B;
+
+ if (xmin < g_prim.drawX) {
+ j = g_prim.drawX - xmin;
+ xmin = g_prim.drawX;
+ posX += j * difX;
+ posY += j * difY;
+ cR1 += j * difR;
+ cG1 += j * difG;
+ cB1 += j * difB;
+ }
+
+ for (j = xmin; j < xmax; j += 2) {
+ TXU = posX >> 16;
+ TXV = posY >> 16;
+ n_xi = ((TXU >> 1) & ~0x78) + ((TXU << 2) & 0x40) + ((TXV
+ << 3) & 0x38);
+ n_yi = (TXV & ~0x7) + ((TXU >> 5) & 0x7);
+
+ tC1
+ = (GETLE16(&g_gpu.psx_vram.u16[(n_yi<<10)+YAdjust+n_xi])
+ >> ((TXU & 0x01) << 3)) & 0xff;
+
+ TXU = (posX + difX) >> 16;
+ TXV = (posY + difY) >> 16;
+ n_xi = ((TXU >> 1) & ~0x78) + ((TXU << 2) & 0x40) + ((TXV
+ << 3) & 0x38);
+ n_yi = (TXV & ~0x7) + ((TXU >> 5) & 0x7);
+
+ tC2
+ = (GETLE16(&g_gpu.psx_vram.u16[(n_yi<<10)+YAdjust+n_xi])
+ >> ((TXU & 0x01) << 3)) & 0xff;
+
+ GetTextureTransColGX32_S(
+ (uint32_t *) &g_gpu.psx_vram.u16[(i << 10) + j],
+ GETLE16(&g_gpu.psx_vram.u16[clutP+tC1])
+ | ((int32_t) GETLE16(&g_gpu.psx_vram.u16[clutP+tC2]))
+ << 16, (cB1 >> 16) | ((cB1 + difB)
+ & 0xff0000), (cG1 >> 16) | ((cG1 + difG)
+ & 0xff0000), (cR1 >> 16) | ((cR1 + difR)
+ & 0xff0000));
+ posX += difX2;
+ posY += difY2;
+ cR1 += difR2;
+ cG1 += difG2;
+ cB1 += difB2;
+ }
+ if (j == xmax) {
+ TXU = posX >> 16;
+ TXV = posY >> 16;
+ n_xi = ((TXU >> 1) & ~0x78) + ((TXU << 2) & 0x40) + ((TXV
+ << 3) & 0x38);
+ n_yi = (TXV & ~0x7) + ((TXU >> 5) & 0x7);
+
+ tC1
+ = (GETLE16(&g_gpu.psx_vram.u16[(n_yi<<10)+YAdjust+n_xi])
+ >> ((TXU & 0x01) << 3)) & 0xff;
+
+ GetTextureTransColGX_S(&g_gpu.psx_vram.u16[(i << 10) + j],
+ GETLE16(&g_gpu.psx_vram.u16[clutP+tC1]),
+ (cB1 >> 16), (cG1 >> 16), (cR1 >> 16));
+ }
+ }
+ if (NextRow_GT()) {
+ return;
+ }
+ }
+ return;
+ }
+
+#endif
+
+ for (i = ymin; i <= ymax; i++) {
+ xmin = (left_x >> 16);
+ xmax = (right_x >> 16) - 1; //!!!!!!!!!!!!!!!!!!!!!!!
+ if (g_prim.drawW < xmax)
+ xmax = g_prim.drawW;
+
+ if (xmax >= xmin) {
+ posX = left_u;
+ posY = left_v;
+ cR1 = left_R;
+ cG1 = left_G;
+ cB1 = left_B;
+
+ if (xmin < g_prim.drawX) {
+ j = g_prim.drawX - xmin;
+ xmin = g_prim.drawX;
+ posX += j * difX;
+ posY += j * difY;
+ cR1 += j * difR;
+ cG1 += j * difG;
+ cB1 += j * difB;
+ }
+
+ for (j = xmin; j <= xmax; j++) {
+ TXU = posX >> 16;
+ TXV = posY >> 16;
+ n_xi = ((TXU >> 1) & ~0x78) + ((TXU << 2) & 0x40) + ((TXV << 3)
+ & 0x38);
+ n_yi = (TXV & ~0x7) + ((TXU >> 5) & 0x7);
+
+ tC1 = (GETLE16(&g_gpu.psx_vram.u16[(n_yi<<10)+YAdjust+n_xi])
+ >> ((TXU & 0x01) << 3)) & 0xff;
+
+ if (g_prim.iDither)
+ GetTextureTransColGX_Dither(&g_gpu.psx_vram.u16[(i << 10)
+ + j], GETLE16(&g_gpu.psx_vram.u16[clutP+tC1]), (cB1
+ >> 16), (cG1 >> 16), (cR1 >> 16));
+ else
+ GetTextureTransColGX(&g_gpu.psx_vram.u16[(i << 10) + j],
+ GETLE16(&g_gpu.psx_vram.u16[clutP+tC1]),
+ (cB1 >> 16), (cG1 >> 16), (cR1 >> 16));
+ posX += difX;
+ posY += difY;
+ cR1 += difR;
+ cG1 += difG;
+ cB1 += difB;
+ }
+ }
+ if (NextRow_GT()) {
+ return;
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void drawPoly3TGEx8_TW(short x1, short y1, short x2, short y2, short x3,
+ short y3, short tx1, short ty1, short tx2, short ty2, short tx3,
+ short ty3, short clX, short clY, int32_t col1, int32_t col2,
+ int32_t col3) {
+ int i, j, xmin, xmax, ymin, ymax;
+ int32_t cR1, cG1, cB1;
+ int32_t difR, difB, difG, difR2, difB2, difG2;
+ int32_t difX, difY, difX2, difY2;
+ int32_t posX, posY, YAdjust, clutP;
+ short tC1, tC2;
+
+ if (x1 > g_prim.drawW && x2 > g_prim.drawW && x3 > g_prim.drawW)
+ return;
+ if (y1 > g_prim.drawH && y2 > g_prim.drawH && y3 > g_prim.drawH)
+ return;
+ if (x1 < g_prim.drawX && x2 < g_prim.drawX && x3 < g_prim.drawX)
+ return;
+ if (y1 < g_prim.drawY && y2 < g_prim.drawY && y3 < g_prim.drawY)
+ return;
+ if (g_prim.drawY >= g_prim.drawH)
+ return;
+ if (g_prim.drawX >= g_prim.drawW)
+ return;
+
+ if (!SetupSections_GT(x1, y1, x2, y2, x3, y3, tx1, ty1, tx2, ty2, tx3, ty3,
+ col1, col2, col3))
+ return;
+
+ ymax = g_soft.Ymax;
+
+ for (ymin = g_soft.Ymin; ymin < g_prim.drawY; ymin++)
+ if (NextRow_GT())
+ return;
+
+ clutP = (clY << 10) + clX;
+
+ YAdjust = ((g_soft.GlobalTextAddrY) << 11) + (g_soft.GlobalTextAddrX << 1);
+ YAdjust += (g_prim.TWin.Position.y0 << 11) + (g_prim.TWin.Position.x0);
+
+ difR = delta_right_R;
+ difG = delta_right_G;
+ difB = delta_right_B;
+ difR2 = difR << 1;
+ difG2 = difG << 1;
+ difB2 = difB << 1;
+ difX = delta_right_u;
+ difX2 = difX << 1;
+ difY = delta_right_v;
+ difY2 = difY << 1;
+
+#ifdef FASTSOLID
+
+ if (!g_draw.bCheckMask && !g_soft.DrawSemiTrans && !g_prim.iDither) {
+ for (i = ymin; i <= ymax; i++) {
+ xmin = (left_x >> 16);
+ xmax = (right_x >> 16) - 1; // !!!!!!!!!!!!!
+ if (g_prim.drawW < xmax)
+ xmax = g_prim.drawW;
+
+ if (xmax >= xmin) {
+ posX = left_u;
+ posY = left_v;
+ cR1 = left_R;
+ cG1 = left_G;
+ cB1 = left_B;
+
+ if (xmin < g_prim.drawX) {
+ j = g_prim.drawX - xmin;
+ xmin = g_prim.drawX;
+ posX += j * difX;
+ posY += j * difY;
+ cR1 += j * difR;
+ cG1 += j * difG;
+ cB1 += j * difB;
+ }
+
+ for (j = xmin; j < xmax; j += 2) {
+ tC1 = g_gpu.psx_vram.u8[(((posY >> 16)
+ % g_prim.TWin.Position.y1) << 11) + YAdjust
+ + ((posX >> 16) % g_prim.TWin.Position.x1)];
+ tC2
+ = g_gpu.psx_vram.u8[((((posY + difY) >> 16)
+ % g_prim.TWin.Position.y1) << 11) + YAdjust
+ + (((posX + difX) >> 16)
+ % g_prim.TWin.Position.x1)];
+
+ GetTextureTransColGX32_S(
+ (uint32_t *) &g_gpu.psx_vram.u16[(i << 10) + j],
+ GETLE16(&g_gpu.psx_vram.u16[clutP+tC1])
+ | ((int32_t) GETLE16(&g_gpu.psx_vram.u16[clutP+tC2]))
+ << 16, (cB1 >> 16) | ((cB1 + difB)
+ & 0xff0000), (cG1 >> 16) | ((cG1 + difG)
+ & 0xff0000), (cR1 >> 16) | ((cR1 + difR)
+ & 0xff0000));
+ posX += difX2;
+ posY += difY2;
+ cR1 += difR2;
+ cG1 += difG2;
+ cB1 += difB2;
+ }
+ if (j == xmax) {
+ tC1 = g_gpu.psx_vram.u8[(((posY >> 16)
+ % g_prim.TWin.Position.y1) << 11) + YAdjust
+ + ((posX >> 16) % g_prim.TWin.Position.x1)];
+ GetTextureTransColGX_S(&g_gpu.psx_vram.u16[(i << 10) + j],
+ GETLE16(&g_gpu.psx_vram.u16[clutP+tC1]),
+ (cB1 >> 16), (cG1 >> 16), (cR1 >> 16));
+ }
+ }
+ if (NextRow_GT()) {
+ return;
+ }
+ }
+ return;
+ }
+
+#endif
+
+ for (i = ymin; i <= ymax; i++) {
+ xmin = (left_x >> 16);
+ xmax = (right_x >> 16) - 1; //!!!!!!!!!!!!!!!!!!!!!!!
+ if (g_prim.drawW < xmax)
+ xmax = g_prim.drawW;
+
+ if (xmax >= xmin) {
+ posX = left_u;
+ posY = left_v;
+ cR1 = left_R;
+ cG1 = left_G;
+ cB1 = left_B;
+
+ if (xmin < g_prim.drawX) {
+ j = g_prim.drawX - xmin;
+ xmin = g_prim.drawX;
+ posX += j * difX;
+ posY += j * difY;
+ cR1 += j * difR;
+ cG1 += j * difG;
+ cB1 += j * difB;
+ }
+
+ for (j = xmin; j <= xmax; j++) {
+ tC1 = g_gpu.psx_vram.u8[(((posY >> 16)
+ % g_prim.TWin.Position.y1) << 11) + YAdjust + ((posX
+ >> 16) % g_prim.TWin.Position.x1)];
+ if (g_prim.iDither)
+ GetTextureTransColGX_Dither(&g_gpu.psx_vram.u16[(i << 10)
+ + j], GETLE16(&g_gpu.psx_vram.u16[clutP+tC1]), (cB1
+ >> 16), (cG1 >> 16), (cR1 >> 16));
+ else
+ GetTextureTransColGX(&g_gpu.psx_vram.u16[(i << 10) + j],
+ GETLE16(&g_gpu.psx_vram.u16[clutP+tC1]),
+ (cB1 >> 16), (cG1 >> 16), (cR1 >> 16));
+ posX += difX;
+ posY += difY;
+ cR1 += difR;
+ cG1 += difG;
+ cB1 += difB;
+ }
+ }
+ if (NextRow_GT()) {
+ return;
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+// note: two g-shaded tris: small texture distortions can happen
+
+void drawPoly4TGEx8_TRI_IL(short x1, short y1, short x2, short y2, short x3,
+ short y3, short x4, short y4, short tx1, short ty1, short tx2,
+ short ty2, short tx3, short ty3, short tx4, short ty4, short clX,
+ short clY, int32_t col1, int32_t col2, int32_t col3, int32_t col4) {
+ drawPoly3TGEx8_IL(x2, y2, x3, y3, x4, y4, tx2, ty2, tx3, ty3, tx4, ty4,
+ clX, clY, col2, col4, col3);
+ drawPoly3TGEx8_IL(x1, y1, x2, y2, x4, y4, tx1, ty1, tx2, ty2, tx4, ty4,
+ clX, clY, col1, col2, col3);
+}
+
+#ifdef POLYQUAD3GT
+
+void drawPoly4TGEx8_TRI(short x1, short y1, short x2, short y2, short x3,
+ short y3, short x4, short y4, short tx1, short ty1, short tx2,
+ short ty2, short tx3, short ty3, short tx4, short ty4, short clX,
+ short clY, int32_t col1, int32_t col2, int32_t col3, int32_t col4) {
+ drawPoly3TGEx8(x2, y2, x3, y3, x4, y4, tx2, ty2, tx3, ty3, tx4, ty4, clX,
+ clY, col2, col4, col3);
+ drawPoly3TGEx8(x1, y1, x2, y2, x4, y4, tx1, ty1, tx2, ty2, tx4, ty4, clX,
+ clY, col1, col2, col3);
+}
+
+#endif
+
+void drawPoly4TGEx8(short x1, short y1, short x2, short y2, short x3, short y3,
+ short x4, short y4, short tx1, short ty1, short tx2, short ty2,
+ short tx3, short ty3, short tx4, short ty4, short clX, short clY,
+ int32_t col1, int32_t col2, int32_t col4, int32_t col3) {
+ int32_t num;
+ int32_t i, j, xmin, xmax, ymin, ymax;
+ int32_t cR1, cG1, cB1;
+ int32_t difR, difB, difG, difR2, difB2, difG2;
+ int32_t difX, difY, difX2, difY2;
+ int32_t posX, posY, YAdjust, clutP;
+ short tC1, tC2;
+
+ if (x1 > g_prim.drawW && x2 > g_prim.drawW && x3 > g_prim.drawW && x4
+ > g_prim.drawW)
+ return;
+ if (y1 > g_prim.drawH && y2 > g_prim.drawH && y3 > g_prim.drawH && y4
+ > g_prim.drawH)
+ return;
+ if (x1 < g_prim.drawX && x2 < g_prim.drawX && x3 < g_prim.drawX && x4
+ < g_prim.drawX)
+ return;
+ if (y1 < g_prim.drawY && y2 < g_prim.drawY && y3 < g_prim.drawY && y4
+ < g_prim.drawY)
+ return;
+ if (g_prim.drawY >= g_prim.drawH)
+ return;
+ if (g_prim.drawX >= g_prim.drawW)
+ return;
+
+ if (!SetupSections_GT4(x1, y1, x2, y2, x3, y3, x4, y4, tx1, ty1, tx2, ty2,
+ tx3, ty3, tx4, ty4, col1, col2, col3, col4))
+ return;
+
+ ymax = g_soft.Ymax;
+
+ for (ymin = g_soft.Ymin; ymin < g_prim.drawY; ymin++)
+ if (NextRow_GT4())
+ return;
+
+ clutP = (clY << 10) + clX;
+
+ YAdjust = ((g_soft.GlobalTextAddrY) << 11) + (g_soft.GlobalTextAddrX << 1);
+
+#ifdef FASTSOLID
+
+ if (!g_draw.bCheckMask && !g_soft.DrawSemiTrans && !g_prim.iDither) {
+ for (i = ymin; i <= ymax; i++) {
+ xmin = (left_x >> 16);
+ xmax = (right_x >> 16);
+
+ if (xmax >= xmin) {
+ posX = left_u;
+ posY = left_v;
+
+ num = (xmax - xmin);
+ if (num == 0)
+ num = 1;
+ difX = (right_u - posX) / num;
+ difY = (right_v - posY) / num;
+ difX2 = difX << 1;
+ difY2 = difY << 1;
+
+ cR1 = left_R;
+ cG1 = left_G;
+ cB1 = left_B;
+ difR = (right_R - cR1) / num;
+ difG = (right_G - cG1) / num;
+ difB = (right_B - cB1) / num;
+ difR2 = difR << 1;
+ difG2 = difG << 1;
+ difB2 = difB << 1;
+
+ if (xmin < g_prim.drawX) {
+ j = g_prim.drawX - xmin;
+ xmin = g_prim.drawX;
+ posX += j * difX;
+ posY += j * difY;
+ cR1 += j * difR;
+ cG1 += j * difG;
+ cB1 += j * difB;
+ }
+ xmax--;
+ if (g_prim.drawW < xmax)
+ xmax = g_prim.drawW;
+
+ for (j = xmin; j < xmax; j += 2) {
+ tC1
+ = g_gpu.psx_vram.u8[((posY >> 5)
+ & (int32_t) 0xFFFFF800) + YAdjust + (posX
+ >> 16)];
+ tC2 = g_gpu.psx_vram.u8[(((posY + difY) >> 5)
+ & (int32_t) 0xFFFFF800) + YAdjust + ((posX + difX)
+ >> 16)];
+
+ GetTextureTransColGX32_S(
+ (uint32_t *) &g_gpu.psx_vram.u16[(i << 10) + j],
+ GETLE16(&g_gpu.psx_vram.u16[clutP+tC1])
+ | ((int32_t) GETLE16(&g_gpu.psx_vram.u16[clutP+tC2]))
+ << 16, (cB1 >> 16) | ((cB1 + difB)
+ & 0xff0000), (cG1 >> 16) | ((cG1 + difG)
+ & 0xff0000), (cR1 >> 16) | ((cR1 + difR)
+ & 0xff0000));
+ posX += difX2;
+ posY += difY2;
+ cR1 += difR2;
+ cG1 += difG2;
+ cB1 += difB2;
+ }
+ if (j == xmax) {
+ tC1
+ = g_gpu.psx_vram.u8[((posY >> 5)
+ & (int32_t) 0xFFFFF800) + YAdjust + (posX
+ >> 16)];
+ GetTextureTransColGX_S(&g_gpu.psx_vram.u16[(i << 10) + j],
+ GETLE16(&g_gpu.psx_vram.u16[clutP+tC1]),
+ (cB1 >> 16), (cG1 >> 16), (cR1 >> 16));
+ }
+ }
+ if (NextRow_GT4())
+ return;
+ }
+ return;
+ }
+
+#endif
+
+ for (i = ymin; i <= ymax; i++) {
+ xmin = (left_x >> 16);
+ xmax = (right_x >> 16);
+
+ if (xmax >= xmin) {
+ posX = left_u;
+ posY = left_v;
+
+ num = (xmax - xmin);
+ if (num == 0)
+ num = 1;
+ difX = (right_u - posX) / num;
+ difY = (right_v - posY) / num;
+ difX2 = difX << 1;
+ difY2 = difY << 1;
+
+ cR1 = left_R;
+ cG1 = left_G;
+ cB1 = left_B;
+ difR = (right_R - cR1) / num;
+ difG = (right_G - cG1) / num;
+ difB = (right_B - cB1) / num;
+ difR2 = difR << 1;
+ difG2 = difG << 1;
+ difB2 = difB << 1;
+
+ if (xmin < g_prim.drawX) {
+ j = g_prim.drawX - xmin;
+ xmin = g_prim.drawX;
+ posX += j * difX;
+ posY += j * difY;
+ cR1 += j * difR;
+ cG1 += j * difG;
+ cB1 += j * difB;
+ }
+ xmax--;
+ if (g_prim.drawW < xmax)
+ xmax = g_prim.drawW;
+
+ for (j = xmin; j <= xmax; j++) {
+ tC1 = g_gpu.psx_vram.u8[((posY >> 5) & (int32_t) 0xFFFFF800)
+ + YAdjust + (posX >> 16)];
+ if (g_prim.iDither)
+ GetTextureTransColGX_Dither(&g_gpu.psx_vram.u16[(i << 10)
+ + j], GETLE16(&g_gpu.psx_vram.u16[clutP+tC1]), (cB1
+ >> 16), (cG1 >> 16), (cR1 >> 16));
+ else
+ GetTextureTransColGX(&g_gpu.psx_vram.u16[(i << 10) + j],
+ GETLE16(&g_gpu.psx_vram.u16[clutP+tC1]),
+ (cB1 >> 16), (cG1 >> 16), (cR1 >> 16));
+ posX += difX;
+ posY += difY;
+ cR1 += difR;
+ cG1 += difG;
+ cB1 += difB;
+ }
+ }
+ if (NextRow_GT4())
+ return;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void drawPoly4TGEx8_TW(short x1, short y1, short x2, short y2, short x3,
+ short y3, short x4, short y4, short tx1, short ty1, short tx2,
+ short ty2, short tx3, short ty3, short tx4, short ty4, short clX,
+ short clY, int32_t col1, int32_t col2, int32_t col3, int32_t col4) {
+ drawPoly3TGEx8_TW(x2, y2, x3, y3, x4, y4, tx2, ty2, tx3, ty3, tx4, ty4,
+ clX, clY, col2, col4, col3);
+ drawPoly3TGEx8_TW(x1, y1, x2, y2, x4, y4, tx1, ty1, tx2, ty2, tx4, ty4,
+ clX, clY, col1, col2, col3);
+}
+
+////////////////////////////////////////////////////////////////////////
+// POLY 3 G-SHADED TEX 15 BIT
+////////////////////////////////////////////////////////////////////////
+
+void drawPoly3TGD(short x1, short y1, short x2, short y2, short x3, short y3,
+ short tx1, short ty1, short tx2, short ty2, short tx3, short ty3,
+ int32_t col1, int32_t col2, int32_t col3) {
+ int i, j, xmin, xmax, ymin, ymax;
+ int32_t cR1, cG1, cB1;
+ int32_t difR, difB, difG, difR2, difB2, difG2;
+ int32_t difX, difY, difX2, difY2;
+ int32_t posX, posY;
+
+ if (x1 > g_prim.drawW && x2 > g_prim.drawW && x3 > g_prim.drawW)
+ return;
+ if (y1 > g_prim.drawH && y2 > g_prim.drawH && y3 > g_prim.drawH)
+ return;
+ if (x1 < g_prim.drawX && x2 < g_prim.drawX && x3 < g_prim.drawX)
+ return;
+ if (y1 < g_prim.drawY && y2 < g_prim.drawY && y3 < g_prim.drawY)
+ return;
+ if (g_prim.drawY >= g_prim.drawH)
+ return;
+ if (g_prim.drawX >= g_prim.drawW)
+ return;
+
+ if (!SetupSections_GT(x1, y1, x2, y2, x3, y3, tx1, ty1, tx2, ty2, tx3, ty3,
+ col1, col2, col3))
+ return;
+
+ ymax = g_soft.Ymax;
+
+ for (ymin = g_soft.Ymin; ymin < g_prim.drawY; ymin++)
+ if (NextRow_GT())
+ return;
+
+ difR = delta_right_R;
+ difG = delta_right_G;
+ difB = delta_right_B;
+ difR2 = difR << 1;
+ difG2 = difG << 1;
+ difB2 = difB << 1;
+ difX = delta_right_u;
+ difX2 = difX << 1;
+ difY = delta_right_v;
+ difY2 = difY << 1;
+
+#ifdef FASTSOLID
+
+ if (!g_draw.bCheckMask && !g_soft.DrawSemiTrans && !g_prim.iDither) {
+ for (i = ymin; i <= ymax; i++) {
+ xmin = (left_x >> 16);
+ xmax = (right_x >> 16) - 1; //!!!!!!!!!!!!!!!!!!!!
+ if (g_prim.drawW < xmax)
+ xmax = g_prim.drawW;
+
+ if (xmax >= xmin) {
+ posX = left_u;
+ posY = left_v;
+ cR1 = left_R;
+ cG1 = left_G;
+ cB1 = left_B;
+
+ if (xmin < g_prim.drawX) {
+ j = g_prim.drawX - xmin;
+ xmin = g_prim.drawX;
+ posX += j * difX;
+ posY += j * difY;
+ cR1 += j * difR;
+ cG1 += j * difG;
+ cB1 += j * difB;
+ }
+
+ for (j = xmin; j < xmax; j += 2) {
+ GetTextureTransColGX32_S(
+ (uint32_t *) &g_gpu.psx_vram.u16[(i << 10) + j],
+ (((int32_t) GETLE16(&g_gpu.psx_vram.u16[((((posY+difY)>>16)+g_soft.GlobalTextAddrY)<<10)+((posX+difX)>>16)+g_soft.GlobalTextAddrX]))
+ << 16)
+ | GETLE16(&g_gpu.psx_vram.u16[(((posY>>16)+g_soft.GlobalTextAddrY)<<10)+((posX)>>16)+g_soft.GlobalTextAddrX]),
+ (cB1 >> 16) | ((cB1 + difB) & 0xff0000),
+ (cG1 >> 16) | ((cG1 + difG) & 0xff0000),
+ (cR1 >> 16) | ((cR1 + difR) & 0xff0000));
+ posX += difX2;
+ posY += difY2;
+ cR1 += difR2;
+ cG1 += difG2;
+ cB1 += difB2;
+ }
+ if (j == xmax)
+ GetTextureTransColGX_S(
+ &g_gpu.psx_vram.u16[(i << 10) + j],
+ GETLE16(&g_gpu.psx_vram.u16[(((posY>>16)+g_soft.GlobalTextAddrY)<<10)+(posX>>16)+g_soft.GlobalTextAddrX]),
+ (cB1 >> 16), (cG1 >> 16), (cR1 >> 16));
+ }
+ if (NextRow_GT()) {
+ return;
+ }
+ }
+ return;
+ }
+
+#endif
+
+ for (i = ymin; i <= ymax; i++) {
+ xmin = (left_x >> 16);
+ xmax = (right_x >> 16) - 1; //!!!!!!!!!!!!!!!!!!
+ if (g_prim.drawW < xmax)
+ xmax = g_prim.drawW;
+
+ if (xmax >= xmin) {
+ posX = left_u;
+ posY = left_v;
+ cR1 = left_R;
+ cG1 = left_G;
+ cB1 = left_B;
+
+ if (xmin < g_prim.drawX) {
+ j = g_prim.drawX - xmin;
+ xmin = g_prim.drawX;
+ posX += j * difX;
+ posY += j * difY;
+ cR1 += j * difR;
+ cG1 += j * difG;
+ cB1 += j * difB;
+ }
+
+ for (j = xmin; j <= xmax; j++) {
+ if (g_prim.iDither)
+ GetTextureTransColGX_Dither(
+ &g_gpu.psx_vram.u16[(i << 10) + j],
+ GETLE16(&g_gpu.psx_vram.u16[(((posY>>16)+g_soft.GlobalTextAddrY)<<10)+(posX>>16)+g_soft.GlobalTextAddrX]),
+ (cB1 >> 16), (cG1 >> 16), (cR1 >> 16));
+ else
+ GetTextureTransColGX(
+ &g_gpu.psx_vram.u16[(i << 10) + j],
+ GETLE16(&g_gpu.psx_vram.u16[(((posY>>16)+g_soft.GlobalTextAddrY)<<10)+(posX>>16)+g_soft.GlobalTextAddrX]),
+ (cB1 >> 16), (cG1 >> 16), (cR1 >> 16));
+ posX += difX;
+ posY += difY;
+ cR1 += difR;
+ cG1 += difG;
+ cB1 += difB;
+ }
+ }
+ if (NextRow_GT()) {
+ return;
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void drawPoly3TGD_TW(short x1, short y1, short x2, short y2, short x3,
+ short y3, short tx1, short ty1, short tx2, short ty2, short tx3,
+ short ty3, int32_t col1, int32_t col2, int32_t col3) {
+ int i, j, xmin, xmax, ymin, ymax;
+ int32_t cR1, cG1, cB1;
+ int32_t difR, difB, difG, difR2, difB2, difG2;
+ int32_t difX, difY, difX2, difY2;
+ int32_t posX, posY;
+
+ if (x1 > g_prim.drawW && x2 > g_prim.drawW && x3 > g_prim.drawW)
+ return;
+ if (y1 > g_prim.drawH && y2 > g_prim.drawH && y3 > g_prim.drawH)
+ return;
+ if (x1 < g_prim.drawX && x2 < g_prim.drawX && x3 < g_prim.drawX)
+ return;
+ if (y1 < g_prim.drawY && y2 < g_prim.drawY && y3 < g_prim.drawY)
+ return;
+ if (g_prim.drawY >= g_prim.drawH)
+ return;
+ if (g_prim.drawX >= g_prim.drawW)
+ return;
+
+ if (!SetupSections_GT(x1, y1, x2, y2, x3, y3, tx1, ty1, tx2, ty2, tx3, ty3,
+ col1, col2, col3))
+ return;
+
+ ymax = g_soft.Ymax;
+
+ for (ymin = g_soft.Ymin; ymin < g_prim.drawY; ymin++)
+ if (NextRow_GT())
+ return;
+
+ difR = delta_right_R;
+ difG = delta_right_G;
+ difB = delta_right_B;
+ difR2 = difR << 1;
+ difG2 = difG << 1;
+ difB2 = difB << 1;
+ difX = delta_right_u;
+ difX2 = difX << 1;
+ difY = delta_right_v;
+ difY2 = difY << 1;
+
+#ifdef FASTSOLID
+
+ if (!g_draw.bCheckMask && !g_soft.DrawSemiTrans && !g_prim.iDither) {
+ for (i = ymin; i <= ymax; i++) {
+ xmin = (left_x >> 16);
+ xmax = (right_x >> 16) - 1; //!!!!!!!!!!!!!!!!!!!!
+ if (g_prim.drawW < xmax)
+ xmax = g_prim.drawW;
+
+ if (xmax >= xmin) {
+ posX = left_u;
+ posY = left_v;
+ cR1 = left_R;
+ cG1 = left_G;
+ cB1 = left_B;
+
+ if (xmin < g_prim.drawX) {
+ j = g_prim.drawX - xmin;
+ xmin = g_prim.drawX;
+ posX += j * difX;
+ posY += j * difY;
+ cR1 += j * difR;
+ cG1 += j * difG;
+ cB1 += j * difB;
+ }
+
+ for (j = xmin; j < xmax; j += 2) {
+ GetTextureTransColGX32_S(
+ (uint32_t *) &g_gpu.psx_vram.u16[(i << 10) + j],
+ (((int32_t) GETLE16(&g_gpu.psx_vram.u16[(((((posY+difY)>>16)%g_prim.TWin.Position.y1)+g_soft.GlobalTextAddrY+g_prim.TWin.Position.y0)<<10)+
+ (((posX+difX)>>16)%g_prim.TWin.Position.x1)+g_soft.GlobalTextAddrX+g_prim.TWin.Position.x0]))
+ << 16)
+ | GETLE16(&g_gpu.psx_vram.u16[((((posY>>16)%g_prim.TWin.Position.y1)+g_soft.GlobalTextAddrY+g_prim.TWin.Position.y0)<<10)+
+ (((posX)>>16)%g_prim.TWin.Position.x1)+g_soft.GlobalTextAddrX+g_prim.TWin.Position.x0]),
+ (cB1 >> 16) | ((cB1 + difB) & 0xff0000),
+ (cG1 >> 16) | ((cG1 + difG) & 0xff0000),
+ (cR1 >> 16) | ((cR1 + difR) & 0xff0000));
+ posX += difX2;
+ posY += difY2;
+ cR1 += difR2;
+ cG1 += difG2;
+ cB1 += difB2;
+ }
+ if (j == xmax)
+ GetTextureTransColGX_S(
+ &g_gpu.psx_vram.u16[(i << 10) + j],
+ GETLE16(&g_gpu.psx_vram.u16[((((posY>>16)%g_prim.TWin.Position.y1)+g_soft.GlobalTextAddrY+g_prim.TWin.Position.y0)<<10)+
+ ((posX>>16)%g_prim.TWin.Position.x1)+g_soft.GlobalTextAddrX+g_prim.TWin.Position.x0]),
+ (cB1 >> 16), (cG1 >> 16), (cR1 >> 16));
+ }
+ if (NextRow_GT()) {
+ return;
+ }
+ }
+ return;
+ }
+
+#endif
+
+ for (i = ymin; i <= ymax; i++) {
+ xmin = (left_x >> 16);
+ xmax = (right_x >> 16) - 1; //!!!!!!!!!!!!!!!!!!
+ if (g_prim.drawW < xmax)
+ xmax = g_prim.drawW;
+
+ if (xmax >= xmin) {
+ posX = left_u;
+ posY = left_v;
+ cR1 = left_R;
+ cG1 = left_G;
+ cB1 = left_B;
+
+ if (xmin < g_prim.drawX) {
+ j = g_prim.drawX - xmin;
+ xmin = g_prim.drawX;
+ posX += j * difX;
+ posY += j * difY;
+ cR1 += j * difR;
+ cG1 += j * difG;
+ cB1 += j * difB;
+ }
+
+ for (j = xmin; j <= xmax; j++) {
+ if (g_prim.iDither)
+ GetTextureTransColGX_Dither(
+ &g_gpu.psx_vram.u16[(i << 10) + j],
+ GETLE16(&g_gpu.psx_vram.u16[((((posY>>16)%g_prim.TWin.Position.y1)+g_soft.GlobalTextAddrY+g_prim.TWin.Position.y0)<<10)+
+ ((posX>>16)%g_prim.TWin.Position.x1)+g_soft.GlobalTextAddrX+g_prim.TWin.Position.x0]),
+ (cB1 >> 16), (cG1 >> 16), (cR1 >> 16));
+ else
+ GetTextureTransColGX(
+ &g_gpu.psx_vram.u16[(i << 10) + j],
+ GETLE16(&g_gpu.psx_vram.u16[((((posY>>16)%g_prim.TWin.Position.y1)+g_soft.GlobalTextAddrY+g_prim.TWin.Position.y0)<<10)+
+ ((posX>>16)%g_prim.TWin.Position.x1)+g_soft.GlobalTextAddrX+g_prim.TWin.Position.x0]),
+ (cB1 >> 16), (cG1 >> 16), (cR1 >> 16));
+ posX += difX;
+ posY += difY;
+ cR1 += difR;
+ cG1 += difG;
+ cB1 += difB;
+ }
+ }
+ if (NextRow_GT()) {
+ return;
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+// note: two g-shaded tris: small texture distortions can happen
+
+#ifdef POLYQUAD3GT
+
+void drawPoly4TGD_TRI(short x1, short y1, short x2, short y2, short x3,
+ short y3, short x4, short y4, short tx1, short ty1, short tx2,
+ short ty2, short tx3, short ty3, short tx4, short ty4, int32_t col1,
+ int32_t col2, int32_t col3, int32_t col4) {
+ drawPoly3TGD(x2, y2, x3, y3, x4, y4, tx2, ty2, tx3, ty3, tx4, ty4, col2,
+ col4, col3);
+ drawPoly3TGD(x1, y1, x2, y2, x4, y4, tx1, ty1, tx2, ty2, tx4, ty4, col1,
+ col2, col3);
+}
+
+#endif
+
+void drawPoly4TGD(short x1, short y1, short x2, short y2, short x3, short y3,
+ short x4, short y4, short tx1, short ty1, short tx2, short ty2,
+ short tx3, short ty3, short tx4, short ty4, int32_t col1, int32_t col2,
+ int32_t col4, int32_t col3) {
+ int32_t num;
+ int32_t i, j, xmin, xmax, ymin, ymax;
+ int32_t cR1, cG1, cB1;
+ int32_t difR, difB, difG, difR2, difB2, difG2;
+ int32_t difX, difY, difX2, difY2;
+ int32_t posX, posY;
+
+ if (x1 > g_prim.drawW && x2 > g_prim.drawW && x3 > g_prim.drawW && x4
+ > g_prim.drawW)
+ return;
+ if (y1 > g_prim.drawH && y2 > g_prim.drawH && y3 > g_prim.drawH && y4
+ > g_prim.drawH)
+ return;
+ if (x1 < g_prim.drawX && x2 < g_prim.drawX && x3 < g_prim.drawX && x4
+ < g_prim.drawX)
+ return;
+ if (y1 < g_prim.drawY && y2 < g_prim.drawY && y3 < g_prim.drawY && y4
+ < g_prim.drawY)
+ return;
+ if (g_prim.drawY >= g_prim.drawH)
+ return;
+ if (g_prim.drawX >= g_prim.drawW)
+ return;
+
+ if (!SetupSections_GT4(x1, y1, x2, y2, x3, y3, x4, y4, tx1, ty1, tx2, ty2,
+ tx3, ty3, tx4, ty4, col1, col2, col3, col4))
+ return;
+
+ ymax = g_soft.Ymax;
+
+ for (ymin = g_soft.Ymin; ymin < g_prim.drawY; ymin++)
+ if (NextRow_GT4())
+ return;
+
+#ifdef FASTSOLID
+
+ if (!g_draw.bCheckMask && !g_soft.DrawSemiTrans && !g_prim.iDither) {
+ for (i = ymin; i <= ymax; i++) {
+ xmin = (left_x >> 16);
+ xmax = (right_x >> 16);
+
+ if (xmax >= xmin) {
+ posX = left_u;
+ posY = left_v;
+
+ num = (xmax - xmin);
+ if (num == 0)
+ num = 1;
+ difX = (right_u - posX) / num;
+ difY = (right_v - posY) / num;
+ difX2 = difX << 1;
+ difY2 = difY << 1;
+
+ cR1 = left_R;
+ cG1 = left_G;
+ cB1 = left_B;
+ difR = (right_R - cR1) / num;
+ difG = (right_G - cG1) / num;
+ difB = (right_B - cB1) / num;
+ difR2 = difR << 1;
+ difG2 = difG << 1;
+ difB2 = difB << 1;
+
+ if (xmin < g_prim.drawX) {
+ j = g_prim.drawX - xmin;
+ xmin = g_prim.drawX;
+ posX += j * difX;
+ posY += j * difY;
+ cR1 += j * difR;
+ cG1 += j * difG;
+ cB1 += j * difB;
+ }
+ xmax--;
+ if (g_prim.drawW < xmax)
+ xmax = g_prim.drawW;
+
+ for (j = xmin; j < xmax; j += 2) {
+ GetTextureTransColGX32_S(
+ (uint32_t *) &g_gpu.psx_vram.u16[(i << 10) + j],
+ (((int32_t) GETLE16(&g_gpu.psx_vram.u16[((((posY+difY)>>16)+g_soft.GlobalTextAddrY)<<10)+((posX+difX)>>16)+g_soft.GlobalTextAddrX]))
+ << 16)
+ | GETLE16(&g_gpu.psx_vram.u16[(((posY>>16)+g_soft.GlobalTextAddrY)<<10)+((posX)>>16)+g_soft.GlobalTextAddrX]),
+ (cB1 >> 16) | ((cB1 + difB) & 0xff0000),
+ (cG1 >> 16) | ((cG1 + difG) & 0xff0000),
+ (cR1 >> 16) | ((cR1 + difR) & 0xff0000));
+ posX += difX2;
+ posY += difY2;
+ cR1 += difR2;
+ cG1 += difG2;
+ cB1 += difB2;
+ }
+ if (j == xmax)
+ GetTextureTransColGX_S(
+ &g_gpu.psx_vram.u16[(i << 10) + j],
+ GETLE16(&g_gpu.psx_vram.u16[(((posY>>16)+g_soft.GlobalTextAddrY)<<10)+(posX>>16)+g_soft.GlobalTextAddrX]),
+ (cB1 >> 16), (cG1 >> 16), (cR1 >> 16));
+ }
+ if (NextRow_GT4())
+ return;
+ }
+ return;
+ }
+
+#endif
+
+ for (i = ymin; i <= ymax; i++) {
+ xmin = (left_x >> 16);
+ xmax = (right_x >> 16);
+
+ if (xmax >= xmin) {
+ posX = left_u;
+ posY = left_v;
+
+ num = (xmax - xmin);
+ if (num == 0)
+ num = 1;
+ difX = (right_u - posX) / num;
+ difY = (right_v - posY) / num;
+ difX2 = difX << 1;
+ difY2 = difY << 1;
+
+ cR1 = left_R;
+ cG1 = left_G;
+ cB1 = left_B;
+ difR = (right_R - cR1) / num;
+ difG = (right_G - cG1) / num;
+ difB = (right_B - cB1) / num;
+ difR2 = difR << 1;
+ difG2 = difG << 1;
+ difB2 = difB << 1;
+
+ if (xmin < g_prim.drawX) {
+ j = g_prim.drawX - xmin;
+ xmin = g_prim.drawX;
+ posX += j * difX;
+ posY += j * difY;
+ cR1 += j * difR;
+ cG1 += j * difG;
+ cB1 += j * difB;
+ }
+ xmax--;
+ if (g_prim.drawW < xmax)
+ xmax = g_prim.drawW;
+
+ for (j = xmin; j <= xmax; j++) {
+ if (g_prim.iDither)
+ GetTextureTransColGX(
+ &g_gpu.psx_vram.u16[(i << 10) + j],
+ GETLE16(&g_gpu.psx_vram.u16[(((posY>>16)+g_soft.GlobalTextAddrY)<<10)+(posX>>16)+g_soft.GlobalTextAddrX]),
+ (cB1 >> 16), (cG1 >> 16), (cR1 >> 16));
+ else
+ GetTextureTransColGX(
+ &g_gpu.psx_vram.u16[(i << 10) + j],
+ GETLE16(&g_gpu.psx_vram.u16[(((posY>>16)+g_soft.GlobalTextAddrY)<<10)+(posX>>16)+g_soft.GlobalTextAddrX]),
+ (cB1 >> 16), (cG1 >> 16), (cR1 >> 16));
+ posX += difX;
+ posY += difY;
+ cR1 += difR;
+ cG1 += difG;
+ cB1 += difB;
+ }
+ }
+ if (NextRow_GT4())
+ return;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void drawPoly4TGD_TW(short x1, short y1, short x2, short y2, short x3,
+ short y3, short x4, short y4, short tx1, short ty1, short tx2,
+ short ty2, short tx3, short ty3, short tx4, short ty4, int32_t col1,
+ int32_t col2, int32_t col3, int32_t col4) {
+ drawPoly3TGD_TW(x2, y2, x3, y3, x4, y4, tx2, ty2, tx3, ty3, tx4, ty4, col2,
+ col4, col3);
+ drawPoly3TGD_TW(x1, y1, x2, y2, x4, y4, tx1, ty1, tx2, ty2, tx4, ty4, col1,
+ col2, col3);
+}
+
+////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////
+
+
+/*
+ // no real rect test, but it does its job the way I need it
+ inline char IsNoRect(void)
+ {
+ if(g_soft.lx0==g_soft.lx1 && g_soft.lx2==g_soft.lx3) return 0;
+ if(g_soft.lx0==g_soft.lx2 && g_soft.lx1==g_soft.lx3) return 0;
+ if(g_soft.lx0==g_soft.lx3 && g_soft.lx1==g_soft.lx2) return 0;
+ return 1;
+ }
+ */
+
+// real rect test
+inline char IsNoRect(void) {
+ if (!(g_prim.dwActFixes & 0x200))
+ return 0;
+
+ if (g_soft.ly0 == g_soft.ly1) {
+ if (g_soft.lx1 == g_soft.lx3 && g_soft.ly3 == g_soft.ly2 && g_soft.lx2
+ == g_soft.lx0)
+ return 0;
+ if (g_soft.lx1 == g_soft.lx2 && g_soft.ly2 == g_soft.ly3 && g_soft.lx3
+ == g_soft.lx0)
+ return 0;
+ return 1;
+ }
+
+ if (g_soft.ly0 == g_soft.ly2) {
+ if (g_soft.lx2 == g_soft.lx3 && g_soft.ly3 == g_soft.ly1 && g_soft.lx1
+ == g_soft.lx0)
+ return 0;
+ if (g_soft.lx2 == g_soft.lx1 && g_soft.ly1 == g_soft.ly3 && g_soft.lx3
+ == g_soft.lx0)
+ return 0;
+ return 1;
+ }
+
+ if (g_soft.ly0 == g_soft.ly3) {
+ if (g_soft.lx3 == g_soft.lx2 && g_soft.ly2 == g_soft.ly1 && g_soft.lx1
+ == g_soft.lx0)
+ return 0;
+ if (g_soft.lx3 == g_soft.lx1 && g_soft.ly1 == g_soft.ly2 && g_soft.lx2
+ == g_soft.lx0)
+ return 0;
+ return 1;
+ }
+ return 1;
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void drawPoly3FT(unsigned char * baseAddr) {
+ uint32_t *gpuData = ((uint32_t *) baseAddr);
+
+ if (0 && g_soft.GlobalTextTP < 2) {
+ if (g_soft.GlobalTextTP == 0)
+ drawPoly3TEx4_IL(g_soft.lx0, g_soft.ly0, g_soft.lx1, g_soft.ly1,
+ g_soft.lx2, g_soft.ly2,
+ (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])
+ >> 8) & 0x000000ff), (GETLE32(&gpuData[4])
+ & 0x000000ff), ((GETLE32(&gpuData[4]) >> 8)
+ & 0x000000ff), (GETLE32(&gpuData[6]) & 0x000000ff),
+ ((GETLE32(&gpuData[6]) >> 8) & 0x000000ff),
+ ((GETLE32(&gpuData[2]) >> 12) & 0x3f0),
+ ((GETLE32(&gpuData[2]) >> 22) & 0x01ff));
+ else
+ drawPoly3TEx8_IL(g_soft.lx0, g_soft.ly0, g_soft.lx1, g_soft.ly1,
+ g_soft.lx2, g_soft.ly2,
+ (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])
+ >> 8) & 0x000000ff), (GETLE32(&gpuData[4])
+ & 0x000000ff), ((GETLE32(&gpuData[4]) >> 8)
+ & 0x000000ff), (GETLE32(&gpuData[6]) & 0x000000ff),
+ ((GETLE32(&gpuData[6]) >> 8) & 0x000000ff),
+ ((GETLE32(&gpuData[2]) >> 12) & 0x3f0),
+ ((GETLE32(&gpuData[2]) >> 22) & 0x01ff));
+ return;
+ }
+
+ if (!g_prim.bUsingTWin && !(g_prim.dwActFixes & 0x100)) {
+ switch (g_soft.GlobalTextTP) // depending on texture mode
+ {
+ case 0:
+ drawPoly3TEx4(g_soft.lx0, g_soft.ly0, g_soft.lx1, g_soft.ly1,
+ g_soft.lx2, g_soft.ly2,
+ (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])
+ >> 8) & 0x000000ff), (GETLE32(&gpuData[4])
+ & 0x000000ff), ((GETLE32(&gpuData[4]) >> 8)
+ & 0x000000ff), (GETLE32(&gpuData[6]) & 0x000000ff),
+ ((GETLE32(&gpuData[6]) >> 8) & 0x000000ff),
+ ((GETLE32(&gpuData[2]) >> 12) & 0x3f0),
+ ((GETLE32(&gpuData[2]) >> 22) & 0x01ff));
+ return;
+ case 1:
+ drawPoly3TEx8(g_soft.lx0, g_soft.ly0, g_soft.lx1, g_soft.ly1,
+ g_soft.lx2, g_soft.ly2,
+ (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])
+ >> 8) & 0x000000ff), (GETLE32(&gpuData[4])
+ & 0x000000ff), ((GETLE32(&gpuData[4]) >> 8)
+ & 0x000000ff), (GETLE32(&gpuData[6]) & 0x000000ff),
+ ((GETLE32(&gpuData[6]) >> 8) & 0x000000ff),
+ ((GETLE32(&gpuData[2]) >> 12) & 0x3f0),
+ ((GETLE32(&gpuData[2]) >> 22) & 0x01ff));
+ return;
+ case 2:
+ drawPoly3TD(g_soft.lx0, g_soft.ly0, g_soft.lx1, g_soft.ly1,
+ g_soft.lx2, g_soft.ly2,
+ (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])
+ >> 8) & 0x000000ff), (GETLE32(&gpuData[4])
+ & 0x000000ff), ((GETLE32(&gpuData[4]) >> 8)
+ & 0x000000ff), (GETLE32(&gpuData[6]) & 0x000000ff),
+ ((GETLE32(&gpuData[6]) >> 8) & 0x000000ff));
+ return;
+ }
+ return;
+ }
+
+ switch (g_soft.GlobalTextTP) // depending on texture mode
+ {
+ case 0:
+ drawPoly3TEx4_TW(g_soft.lx0, g_soft.ly0, g_soft.lx1, g_soft.ly1,
+ g_soft.lx2, g_soft.ly2, (GETLE32(&gpuData[2]) & 0x000000ff),
+ ((GETLE32(&gpuData[2]) >> 8) & 0x000000ff),
+ (GETLE32(&gpuData[4]) & 0x000000ff), ((GETLE32(&gpuData[4])
+ >> 8) & 0x000000ff),
+ (GETLE32(&gpuData[6]) & 0x000000ff), ((GETLE32(&gpuData[6])
+ >> 8) & 0x000000ff), ((GETLE32(&gpuData[2]) >> 12)
+ & 0x3f0), ((GETLE32(&gpuData[2]) >> 22) & 0x01ff));
+ return;
+ case 1:
+ drawPoly3TEx8_TW(g_soft.lx0, g_soft.ly0, g_soft.lx1, g_soft.ly1,
+ g_soft.lx2, g_soft.ly2, (GETLE32(&gpuData[2]) & 0x000000ff),
+ ((GETLE32(&gpuData[2]) >> 8) & 0x000000ff),
+ (GETLE32(&gpuData[4]) & 0x000000ff), ((GETLE32(&gpuData[4])
+ >> 8) & 0x000000ff),
+ (GETLE32(&gpuData[6]) & 0x000000ff), ((GETLE32(&gpuData[6])
+ >> 8) & 0x000000ff), ((GETLE32(&gpuData[2]) >> 12)
+ & 0x3f0), ((GETLE32(&gpuData[2]) >> 22) & 0x01ff));
+ return;
+ case 2:
+ drawPoly3TD_TW(g_soft.lx0, g_soft.ly0, g_soft.lx1, g_soft.ly1,
+ g_soft.lx2, g_soft.ly2, (GETLE32(&gpuData[2]) & 0x000000ff),
+ ((GETLE32(&gpuData[2]) >> 8) & 0x000000ff),
+ (GETLE32(&gpuData[4]) & 0x000000ff), ((GETLE32(&gpuData[4])
+ >> 8) & 0x000000ff),
+ (GETLE32(&gpuData[6]) & 0x000000ff), ((GETLE32(&gpuData[6])
+ >> 8) & 0x000000ff));
+ return;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void drawPoly4FT(unsigned char * baseAddr) {
+ uint32_t *gpuData = ((uint32_t *) baseAddr);
+
+ if (0 && g_soft.GlobalTextTP < 2) {
+ if (g_soft.GlobalTextTP == 0)
+ drawPoly4TEx4_IL(g_soft.lx0, g_soft.ly0, g_soft.lx1, g_soft.ly1,
+ g_soft.lx3, g_soft.ly3, g_soft.lx2, g_soft.ly2,
+ (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])
+ >> 8) & 0x000000ff), (GETLE32(&gpuData[4])
+ & 0x000000ff), ((GETLE32(&gpuData[4]) >> 8)
+ & 0x000000ff), (GETLE32(&gpuData[8]) & 0x000000ff),
+ ((GETLE32(&gpuData[8]) >> 8) & 0x000000ff),
+ (GETLE32(&gpuData[6]) & 0x000000ff), ((GETLE32(&gpuData[6])
+ >> 8) & 0x000000ff), ((GETLE32(&gpuData[2]) >> 12)
+ & 0x3f0), ((GETLE32(&gpuData[2]) >> 22) & 0x01ff));
+ else
+ drawPoly4TEx8_IL(g_soft.lx0, g_soft.ly0, g_soft.lx1, g_soft.ly1,
+ g_soft.lx3, g_soft.ly3, g_soft.lx2, g_soft.ly2,
+ (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])
+ >> 8) & 0x000000ff), (GETLE32(&gpuData[4])
+ & 0x000000ff), ((GETLE32(&gpuData[4]) >> 8)
+ & 0x000000ff), (GETLE32(&gpuData[8]) & 0x000000ff),
+ ((GETLE32(&gpuData[8]) >> 8) & 0x000000ff),
+ (GETLE32(&gpuData[6]) & 0x000000ff), ((GETLE32(&gpuData[6])
+ >> 8) & 0x000000ff), ((GETLE32(&gpuData[2]) >> 12)
+ & 0x3f0), ((GETLE32(&gpuData[2]) >> 22) & 0x01ff));
+ return;
+ }
+
+ if (!g_prim.bUsingTWin) {
+#ifdef POLYQUAD3GT
+ if (IsNoRect()) {
+ switch (g_soft.GlobalTextTP) {
+ case 0:
+ drawPoly4TEx4_TRI(g_soft.lx0, g_soft.ly0, g_soft.lx1,
+ g_soft.ly1, g_soft.lx3, g_soft.ly3, g_soft.lx2,
+ g_soft.ly2, (GETLE32(&gpuData[2]) & 0x000000ff),
+ ((GETLE32(&gpuData[2]) >> 8) & 0x000000ff),
+ (GETLE32(&gpuData[4]) & 0x000000ff),
+ ((GETLE32(&gpuData[4]) >> 8) & 0x000000ff),
+ (GETLE32(&gpuData[8]) & 0x000000ff),
+ ((GETLE32(&gpuData[8]) >> 8) & 0x000000ff),
+ (GETLE32(&gpuData[6]) & 0x000000ff),
+ ((GETLE32(&gpuData[6]) >> 8) & 0x000000ff),
+ ((GETLE32(&gpuData[2]) >> 12) & 0x3f0),
+ ((GETLE32(&gpuData[2]) >> 22) & 0x01ff));
+ return;
+ case 1:
+ drawPoly4TEx8_TRI(g_soft.lx0, g_soft.ly0, g_soft.lx1,
+ g_soft.ly1, g_soft.lx3, g_soft.ly3, g_soft.lx2,
+ g_soft.ly2, (GETLE32(&gpuData[2]) & 0x000000ff),
+ ((GETLE32(&gpuData[2]) >> 8) & 0x000000ff),
+ (GETLE32(&gpuData[4]) & 0x000000ff),
+ ((GETLE32(&gpuData[4]) >> 8) & 0x000000ff),
+ (GETLE32(&gpuData[8]) & 0x000000ff),
+ ((GETLE32(&gpuData[8]) >> 8) & 0x000000ff),
+ (GETLE32(&gpuData[6]) & 0x000000ff),
+ ((GETLE32(&gpuData[6]) >> 8) & 0x000000ff),
+ ((GETLE32(&gpuData[2]) >> 12) & 0x3f0),
+ ((GETLE32(&gpuData[2]) >> 22) & 0x01ff));
+ return;
+ case 2:
+ drawPoly4TD_TRI(g_soft.lx0, g_soft.ly0, g_soft.lx1, g_soft.ly1,
+ g_soft.lx3, g_soft.ly3, g_soft.lx2, g_soft.ly2,
+ (GETLE32(&gpuData[2]) & 0x000000ff),
+ ((GETLE32(&gpuData[2]) >> 8) & 0x000000ff),
+ (GETLE32(&gpuData[4]) & 0x000000ff),
+ ((GETLE32(&gpuData[4]) >> 8) & 0x000000ff),
+ (GETLE32(&gpuData[8]) & 0x000000ff),
+ ((GETLE32(&gpuData[8]) >> 8) & 0x000000ff),
+ (GETLE32(&gpuData[6]) & 0x000000ff),
+ ((GETLE32(&gpuData[6]) >> 8) & 0x000000ff));
+ return;
+ }
+ return;
+ }
+#endif
+
+ switch (g_soft.GlobalTextTP) {
+ case 0: // grandia investigations needed
+ drawPoly4TEx4(g_soft.lx0, g_soft.ly0, g_soft.lx1, g_soft.ly1,
+ g_soft.lx3, g_soft.ly3, g_soft.lx2, g_soft.ly2,
+ (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])
+ >> 8) & 0x000000ff), (GETLE32(&gpuData[4])
+ & 0x000000ff), ((GETLE32(&gpuData[4]) >> 8)
+ & 0x000000ff), (GETLE32(&gpuData[8]) & 0x000000ff),
+ ((GETLE32(&gpuData[8]) >> 8) & 0x000000ff),
+ (GETLE32(&gpuData[6]) & 0x000000ff), ((GETLE32(&gpuData[6])
+ >> 8) & 0x000000ff), ((GETLE32(&gpuData[2]) >> 12)
+ & 0x3f0), ((GETLE32(&gpuData[2]) >> 22) & 0x01ff));
+ return;
+ case 1:
+ drawPoly4TEx8(g_soft.lx0, g_soft.ly0, g_soft.lx1, g_soft.ly1,
+ g_soft.lx3, g_soft.ly3, g_soft.lx2, g_soft.ly2,
+ (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])
+ >> 8) & 0x000000ff), (GETLE32(&gpuData[4])
+ & 0x000000ff), ((GETLE32(&gpuData[4]) >> 8)
+ & 0x000000ff), (GETLE32(&gpuData[8]) & 0x000000ff),
+ ((GETLE32(&gpuData[8]) >> 8) & 0x000000ff),
+ (GETLE32(&gpuData[6]) & 0x000000ff), ((GETLE32(&gpuData[6])
+ >> 8) & 0x000000ff), ((GETLE32(&gpuData[2]) >> 12)
+ & 0x3f0), ((GETLE32(&gpuData[2]) >> 22) & 0x01ff));
+ return;
+ case 2:
+ drawPoly4TD(g_soft.lx0, g_soft.ly0, g_soft.lx1, g_soft.ly1,
+ g_soft.lx3, g_soft.ly3, g_soft.lx2, g_soft.ly2,
+ (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])
+ >> 8) & 0x000000ff), (GETLE32(&gpuData[4])
+ & 0x000000ff), ((GETLE32(&gpuData[4]) >> 8)
+ & 0x000000ff), (GETLE32(&gpuData[8]) & 0x000000ff),
+ ((GETLE32(&gpuData[8]) >> 8) & 0x000000ff),
+ (GETLE32(&gpuData[6]) & 0x000000ff), ((GETLE32(&gpuData[6])
+ >> 8) & 0x000000ff));
+ return;
+ }
+ return;
+ }
+
+ switch (g_soft.GlobalTextTP) {
+ case 0:
+ drawPoly4TEx4_TW(g_soft.lx0, g_soft.ly0, g_soft.lx1, g_soft.ly1,
+ g_soft.lx3, g_soft.ly3, g_soft.lx2, g_soft.ly2,
+ (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])
+ >> 8) & 0x000000ff),
+ (GETLE32(&gpuData[4]) & 0x000000ff), ((GETLE32(&gpuData[4])
+ >> 8) & 0x000000ff),
+ (GETLE32(&gpuData[8]) & 0x000000ff), ((GETLE32(&gpuData[8])
+ >> 8) & 0x000000ff),
+ (GETLE32(&gpuData[6]) & 0x000000ff), ((GETLE32(&gpuData[6])
+ >> 8) & 0x000000ff), ((GETLE32(&gpuData[2]) >> 12)
+ & 0x3f0), ((GETLE32(&gpuData[2]) >> 22) & 0x01ff));
+ return;
+ case 1:
+ drawPoly4TEx8_TW(g_soft.lx0, g_soft.ly0, g_soft.lx1, g_soft.ly1,
+ g_soft.lx3, g_soft.ly3, g_soft.lx2, g_soft.ly2,
+ (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])
+ >> 8) & 0x000000ff),
+ (GETLE32(&gpuData[4]) & 0x000000ff), ((GETLE32(&gpuData[4])
+ >> 8) & 0x000000ff),
+ (GETLE32(&gpuData[8]) & 0x000000ff), ((GETLE32(&gpuData[8])
+ >> 8) & 0x000000ff),
+ (GETLE32(&gpuData[6]) & 0x000000ff), ((GETLE32(&gpuData[6])
+ >> 8) & 0x000000ff), ((GETLE32(&gpuData[2]) >> 12)
+ & 0x3f0), ((GETLE32(&gpuData[2]) >> 22) & 0x01ff));
+ return;
+ case 2:
+ drawPoly4TD_TW(g_soft.lx0, g_soft.ly0, g_soft.lx1, g_soft.ly1,
+ g_soft.lx3, g_soft.ly3, g_soft.lx2, g_soft.ly2,
+ (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])
+ >> 8) & 0x000000ff),
+ (GETLE32(&gpuData[4]) & 0x000000ff), ((GETLE32(&gpuData[4])
+ >> 8) & 0x000000ff),
+ (GETLE32(&gpuData[8]) & 0x000000ff), ((GETLE32(&gpuData[8])
+ >> 8) & 0x000000ff),
+ (GETLE32(&gpuData[6]) & 0x000000ff), ((GETLE32(&gpuData[6])
+ >> 8) & 0x000000ff));
+ return;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void drawPoly3GT(unsigned char * baseAddr) {
+ uint32_t *gpuData = ((uint32_t *) baseAddr);
+
+ if (0 && g_soft.GlobalTextTP < 2) {
+ if (g_soft.GlobalTextTP == 0)
+ drawPoly3TGEx4_IL(g_soft.lx0, g_soft.ly0, g_soft.lx1, g_soft.ly1,
+ g_soft.lx2, g_soft.ly2,
+ (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])
+ >> 8) & 0x000000ff), (GETLE32(&gpuData[5])
+ & 0x000000ff), ((GETLE32(&gpuData[5]) >> 8)
+ & 0x000000ff), (GETLE32(&gpuData[8]) & 0x000000ff),
+ ((GETLE32(&gpuData[8]) >> 8) & 0x000000ff),
+ ((GETLE32(&gpuData[2]) >> 12) & 0x3f0),
+ ((GETLE32(&gpuData[2]) >> 22) & 0x01ff),
+ GETLE32(&gpuData[0]), GETLE32(&gpuData[3]),
+ GETLE32(&gpuData[6]));
+ else
+ drawPoly3TGEx8_IL(g_soft.lx0, g_soft.ly0, g_soft.lx1, g_soft.ly1,
+ g_soft.lx2, g_soft.ly2,
+ (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])
+ >> 8) & 0x000000ff), (GETLE32(&gpuData[5])
+ & 0x000000ff), ((GETLE32(&gpuData[5]) >> 8)
+ & 0x000000ff), (GETLE32(&gpuData[8]) & 0x000000ff),
+ ((GETLE32(&gpuData[8]) >> 8) & 0x000000ff),
+ ((GETLE32(&gpuData[2]) >> 12) & 0x3f0),
+ ((GETLE32(&gpuData[2]) >> 22) & 0x01ff),
+ GETLE32(&gpuData[0]), GETLE32(&gpuData[3]),
+ GETLE32(&gpuData[6]));
+ return;
+ }
+
+ if (!g_prim.bUsingTWin) {
+ switch (g_soft.GlobalTextTP) {
+ case 0:
+ drawPoly3TGEx4(g_soft.lx0, g_soft.ly0, g_soft.lx1, g_soft.ly1,
+ g_soft.lx2, g_soft.ly2,
+ (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])
+ >> 8) & 0x000000ff), (GETLE32(&gpuData[5])
+ & 0x000000ff), ((GETLE32(&gpuData[5]) >> 8)
+ & 0x000000ff), (GETLE32(&gpuData[8]) & 0x000000ff),
+ ((GETLE32(&gpuData[8]) >> 8) & 0x000000ff),
+ ((GETLE32(&gpuData[2]) >> 12) & 0x3f0),
+ ((GETLE32(&gpuData[2]) >> 22) & 0x01ff),
+ GETLE32(&gpuData[0]), GETLE32(&gpuData[3]),
+ GETLE32(&gpuData[6]));
+ return;
+ case 1:
+ drawPoly3TGEx8(g_soft.lx0, g_soft.ly0, g_soft.lx1, g_soft.ly1,
+ g_soft.lx2, g_soft.ly2,
+ (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])
+ >> 8) & 0x000000ff), (GETLE32(&gpuData[5])
+ & 0x000000ff), ((GETLE32(&gpuData[5]) >> 8)
+ & 0x000000ff), (GETLE32(&gpuData[8]) & 0x000000ff),
+ ((GETLE32(&gpuData[8]) >> 8) & 0x000000ff),
+ ((GETLE32(&gpuData[2]) >> 12) & 0x3f0),
+ ((GETLE32(&gpuData[2]) >> 22) & 0x01ff),
+ GETLE32(&gpuData[0]), GETLE32(&gpuData[3]),
+ GETLE32(&gpuData[6]));
+ return;
+ case 2:
+ drawPoly3TGD(g_soft.lx0, g_soft.ly0, g_soft.lx1, g_soft.ly1,
+ g_soft.lx2, g_soft.ly2,
+ (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])
+ >> 8) & 0x000000ff), (GETLE32(&gpuData[5])
+ & 0x000000ff), ((GETLE32(&gpuData[5]) >> 8)
+ & 0x000000ff), (GETLE32(&gpuData[8]) & 0x000000ff),
+ ((GETLE32(&gpuData[8]) >> 8) & 0x000000ff),
+ GETLE32(&gpuData[0]), GETLE32(&gpuData[3]),
+ GETLE32(&gpuData[6]));
+ return;
+ }
+ return;
+ }
+
+ switch (g_soft.GlobalTextTP) {
+ case 0:
+ drawPoly3TGEx4_TW(g_soft.lx0, g_soft.ly0, g_soft.lx1, g_soft.ly1,
+ g_soft.lx2, g_soft.ly2, (GETLE32(&gpuData[2]) & 0x000000ff),
+ ((GETLE32(&gpuData[2]) >> 8) & 0x000000ff),
+ (GETLE32(&gpuData[5]) & 0x000000ff), ((GETLE32(&gpuData[5])
+ >> 8) & 0x000000ff),
+ (GETLE32(&gpuData[8]) & 0x000000ff), ((GETLE32(&gpuData[8])
+ >> 8) & 0x000000ff), ((GETLE32(&gpuData[2]) >> 12)
+ & 0x3f0), ((GETLE32(&gpuData[2]) >> 22) & 0x01ff),
+ GETLE32(&gpuData[0]), GETLE32(&gpuData[3]),
+ GETLE32(&gpuData[6]));
+ return;
+ case 1:
+ drawPoly3TGEx8_TW(g_soft.lx0, g_soft.ly0, g_soft.lx1, g_soft.ly1,
+ g_soft.lx2, g_soft.ly2, (GETLE32(&gpuData[2]) & 0x000000ff),
+ ((GETLE32(&gpuData[2]) >> 8) & 0x000000ff),
+ (GETLE32(&gpuData[5]) & 0x000000ff), ((GETLE32(&gpuData[5])
+ >> 8) & 0x000000ff),
+ (GETLE32(&gpuData[8]) & 0x000000ff), ((GETLE32(&gpuData[8])
+ >> 8) & 0x000000ff), ((GETLE32(&gpuData[2]) >> 12)
+ & 0x3f0), ((GETLE32(&gpuData[2]) >> 22) & 0x01ff),
+ GETLE32(&gpuData[0]), GETLE32(&gpuData[3]),
+ GETLE32(&gpuData[6]));
+ return;
+ case 2:
+ drawPoly3TGD_TW(g_soft.lx0, g_soft.ly0, g_soft.lx1, g_soft.ly1,
+ g_soft.lx2, g_soft.ly2, (GETLE32(&gpuData[2]) & 0x000000ff),
+ ((GETLE32(&gpuData[2]) >> 8) & 0x000000ff),
+ (GETLE32(&gpuData[5]) & 0x000000ff), ((GETLE32(&gpuData[5])
+ >> 8) & 0x000000ff),
+ (GETLE32(&gpuData[8]) & 0x000000ff), ((GETLE32(&gpuData[8])
+ >> 8) & 0x000000ff), GETLE32(&gpuData[0]),
+ GETLE32(&gpuData[3]), GETLE32(&gpuData[6]));
+ return;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void drawPoly4GT(unsigned char *baseAddr) {
+ uint32_t *gpuData = ((uint32_t *) baseAddr);
+
+ if (0 && g_soft.GlobalTextTP < 2) {
+ if (g_soft.GlobalTextTP == 0)
+ drawPoly4TGEx4_TRI_IL(g_soft.lx0, g_soft.ly0, g_soft.lx1,
+ g_soft.ly1, g_soft.lx3, g_soft.ly3, g_soft.lx2, g_soft.ly2,
+ (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])
+ >> 8) & 0x000000ff), (GETLE32(&gpuData[5])
+ & 0x000000ff), ((GETLE32(&gpuData[5]) >> 8)
+ & 0x000000ff),
+ (GETLE32(&gpuData[11]) & 0x000000ff),
+ ((GETLE32(&gpuData[11]) >> 8) & 0x000000ff),
+ (GETLE32(&gpuData[8]) & 0x000000ff), ((GETLE32(&gpuData[8])
+ >> 8) & 0x000000ff), ((GETLE32(&gpuData[2]) >> 12)
+ & 0x3f0), ((GETLE32(&gpuData[2]) >> 22) & 0x01ff),
+ GETLE32(&gpuData[0]), GETLE32(&gpuData[3]),
+ GETLE32(&gpuData[6]), GETLE32(&gpuData[9]));
+ else
+ drawPoly4TGEx8_TRI_IL(g_soft.lx0, g_soft.ly0, g_soft.lx1,
+ g_soft.ly1, g_soft.lx3, g_soft.ly3, g_soft.lx2, g_soft.ly2,
+ (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])
+ >> 8) & 0x000000ff), (GETLE32(&gpuData[5])
+ & 0x000000ff), ((GETLE32(&gpuData[5]) >> 8)
+ & 0x000000ff),
+ (GETLE32(&gpuData[11]) & 0x000000ff),
+ ((GETLE32(&gpuData[11]) >> 8) & 0x000000ff),
+ (GETLE32(&gpuData[8]) & 0x000000ff), ((GETLE32(&gpuData[8])
+ >> 8) & 0x000000ff), ((GETLE32(&gpuData[2]) >> 12)
+ & 0x3f0), ((GETLE32(&gpuData[2]) >> 22) & 0x01ff),
+ GETLE32(&gpuData[0]), GETLE32(&gpuData[3]),
+ GETLE32(&gpuData[6]), GETLE32(&gpuData[9]));
+ return;
+ }
+
+ if (!g_prim.bUsingTWin) {
+#ifdef POLYQUAD3GT
+ if (IsNoRect()) {
+ switch (g_soft.GlobalTextTP) {
+ case 0:
+ drawPoly4TGEx4_TRI(g_soft.lx0, g_soft.ly0, g_soft.lx1,
+ g_soft.ly1, g_soft.lx3, g_soft.ly3, g_soft.lx2,
+ g_soft.ly2, (GETLE32(&gpuData[2]) & 0x000000ff),
+ ((GETLE32(&gpuData[2]) >> 8) & 0x000000ff),
+ (GETLE32(&gpuData[5]) & 0x000000ff),
+ ((GETLE32(&gpuData[5]) >> 8) & 0x000000ff),
+ (GETLE32(&gpuData[11]) & 0x000000ff),
+ ((GETLE32(&gpuData[11]) >> 8) & 0x000000ff),
+ (GETLE32(&gpuData[8]) & 0x000000ff),
+ ((GETLE32(&gpuData[8]) >> 8) & 0x000000ff),
+ ((GETLE32(&gpuData[2]) >> 12) & 0x3f0),
+ ((GETLE32(&gpuData[2]) >> 22) & 0x01ff),
+ GETLE32(&gpuData[0]), GETLE32(&gpuData[3]),
+ GETLE32(&gpuData[6]), GETLE32(&gpuData[9]));
+
+ return;
+ case 1:
+ drawPoly4TGEx8_TRI(g_soft.lx0, g_soft.ly0, g_soft.lx1,
+ g_soft.ly1, g_soft.lx3, g_soft.ly3, g_soft.lx2,
+ g_soft.ly2, (GETLE32(&gpuData[2]) & 0x000000ff),
+ ((GETLE32(&gpuData[2]) >> 8) & 0x000000ff),
+ (GETLE32(&gpuData[5]) & 0x000000ff),
+ ((GETLE32(&gpuData[5]) >> 8) & 0x000000ff),
+ (GETLE32(&gpuData[11]) & 0x000000ff),
+ ((GETLE32(&gpuData[11]) >> 8) & 0x000000ff),
+ (GETLE32(&gpuData[8]) & 0x000000ff),
+ ((GETLE32(&gpuData[8]) >> 8) & 0x000000ff),
+ ((GETLE32(&gpuData[2]) >> 12) & 0x3f0),
+ ((GETLE32(&gpuData[2]) >> 22) & 0x01ff),
+ GETLE32(&gpuData[0]), GETLE32(&gpuData[3]),
+ GETLE32(&gpuData[6]), GETLE32(&gpuData[9]));
+ return;
+ case 2:
+ drawPoly4TGD_TRI(g_soft.lx0, g_soft.ly0, g_soft.lx1,
+ g_soft.ly1, g_soft.lx3, g_soft.ly3, g_soft.lx2,
+ g_soft.ly2, (GETLE32(&gpuData[2]) & 0x000000ff),
+ ((GETLE32(&gpuData[2]) >> 8) & 0x000000ff),
+ (GETLE32(&gpuData[5]) & 0x000000ff),
+ ((GETLE32(&gpuData[5]) >> 8) & 0x000000ff),
+ (GETLE32(&gpuData[11]) & 0x000000ff),
+ ((GETLE32(&gpuData[11]) >> 8) & 0x000000ff),
+ (GETLE32(&gpuData[8]) & 0x000000ff),
+ ((GETLE32(&gpuData[8]) >> 8) & 0x000000ff),
+ GETLE32(&gpuData[0]), GETLE32(&gpuData[3]),
+ GETLE32(&gpuData[6]), GETLE32(&gpuData[9]));
+ return;
+ }
+ return;
+ }
+#endif
+
+ switch (g_soft.GlobalTextTP) {
+ case 0:
+ drawPoly4TGEx4(g_soft.lx0, g_soft.ly0, g_soft.lx1, g_soft.ly1,
+ g_soft.lx3, g_soft.ly3, g_soft.lx2, g_soft.ly2,
+ (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])
+ >> 8) & 0x000000ff), (GETLE32(&gpuData[5])
+ & 0x000000ff), ((GETLE32(&gpuData[5]) >> 8)
+ & 0x000000ff),
+ (GETLE32(&gpuData[11]) & 0x000000ff),
+ ((GETLE32(&gpuData[11]) >> 8) & 0x000000ff),
+ (GETLE32(&gpuData[8]) & 0x000000ff), ((GETLE32(&gpuData[8])
+ >> 8) & 0x000000ff), ((GETLE32(&gpuData[2]) >> 12)
+ & 0x3f0), ((GETLE32(&gpuData[2]) >> 22) & 0x01ff),
+ GETLE32(&gpuData[0]), GETLE32(&gpuData[3]),
+ GETLE32(&gpuData[6]), GETLE32(&gpuData[9]));
+
+ return;
+ case 1:
+ drawPoly4TGEx8(g_soft.lx0, g_soft.ly0, g_soft.lx1, g_soft.ly1,
+ g_soft.lx3, g_soft.ly3, g_soft.lx2, g_soft.ly2,
+ (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])
+ >> 8) & 0x000000ff), (GETLE32(&gpuData[5])
+ & 0x000000ff), ((GETLE32(&gpuData[5]) >> 8)
+ & 0x000000ff),
+ (GETLE32(&gpuData[11]) & 0x000000ff),
+ ((GETLE32(&gpuData[11]) >> 8) & 0x000000ff),
+ (GETLE32(&gpuData[8]) & 0x000000ff), ((GETLE32(&gpuData[8])
+ >> 8) & 0x000000ff), ((GETLE32(&gpuData[2]) >> 12)
+ & 0x3f0), ((GETLE32(&gpuData[2]) >> 22) & 0x01ff),
+ GETLE32(&gpuData[0]), GETLE32(&gpuData[3]),
+ GETLE32(&gpuData[6]), GETLE32(&gpuData[9]));
+ return;
+ case 2:
+ drawPoly4TGD(g_soft.lx0, g_soft.ly0, g_soft.lx1, g_soft.ly1,
+ g_soft.lx3, g_soft.ly3, g_soft.lx2, g_soft.ly2,
+ (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])
+ >> 8) & 0x000000ff), (GETLE32(&gpuData[5])
+ & 0x000000ff), ((GETLE32(&gpuData[5]) >> 8)
+ & 0x000000ff),
+ (GETLE32(&gpuData[11]) & 0x000000ff),
+ ((GETLE32(&gpuData[11]) >> 8) & 0x000000ff),
+ (GETLE32(&gpuData[8]) & 0x000000ff), ((GETLE32(&gpuData[8])
+ >> 8) & 0x000000ff), GETLE32(&gpuData[0]),
+ GETLE32(&gpuData[3]), GETLE32(&gpuData[6]),
+ GETLE32(&gpuData[9]));
+ return;
+ }
+ return;
+ }
+
+ switch (g_soft.GlobalTextTP) {
+ case 0:
+ drawPoly4TGEx4_TW(g_soft.lx0, g_soft.ly0, g_soft.lx1, g_soft.ly1,
+ g_soft.lx3, g_soft.ly3, g_soft.lx2, g_soft.ly2,
+ (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])
+ >> 8) & 0x000000ff),
+ (GETLE32(&gpuData[5]) & 0x000000ff), ((GETLE32(&gpuData[5])
+ >> 8) & 0x000000ff), (GETLE32(&gpuData[11])
+ & 0x000000ff), ((GETLE32(&gpuData[11]) >> 8)
+ & 0x000000ff), (GETLE32(&gpuData[8]) & 0x000000ff),
+ ((GETLE32(&gpuData[8]) >> 8) & 0x000000ff),
+ ((GETLE32(&gpuData[2]) >> 12) & 0x3f0), ((GETLE32(&gpuData[2])
+ >> 22) & 0x01ff), GETLE32(&gpuData[0]),
+ GETLE32(&gpuData[3]), GETLE32(&gpuData[6]),
+ GETLE32(&gpuData[9]));
+ return;
+ case 1:
+ drawPoly4TGEx8_TW(g_soft.lx0, g_soft.ly0, g_soft.lx1, g_soft.ly1,
+ g_soft.lx3, g_soft.ly3, g_soft.lx2, g_soft.ly2,
+ (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])
+ >> 8) & 0x000000ff),
+ (GETLE32(&gpuData[5]) & 0x000000ff), ((GETLE32(&gpuData[5])
+ >> 8) & 0x000000ff), (GETLE32(&gpuData[11])
+ & 0x000000ff), ((GETLE32(&gpuData[11]) >> 8)
+ & 0x000000ff), (GETLE32(&gpuData[8]) & 0x000000ff),
+ ((GETLE32(&gpuData[8]) >> 8) & 0x000000ff),
+ ((GETLE32(&gpuData[2]) >> 12) & 0x3f0), ((GETLE32(&gpuData[2])
+ >> 22) & 0x01ff), GETLE32(&gpuData[0]),
+ GETLE32(&gpuData[3]), GETLE32(&gpuData[6]),
+ GETLE32(&gpuData[9]));
+ return;
+ case 2:
+ drawPoly4TGD_TW(g_soft.lx0, g_soft.ly0, g_soft.lx1, g_soft.ly1,
+ g_soft.lx3, g_soft.ly3, g_soft.lx2, g_soft.ly2,
+ (GETLE32(&gpuData[2]) & 0x000000ff), ((GETLE32(&gpuData[2])
+ >> 8) & 0x000000ff),
+ (GETLE32(&gpuData[5]) & 0x000000ff), ((GETLE32(&gpuData[5])
+ >> 8) & 0x000000ff), (GETLE32(&gpuData[11])
+ & 0x000000ff), ((GETLE32(&gpuData[11]) >> 8)
+ & 0x000000ff), (GETLE32(&gpuData[8]) & 0x000000ff),
+ ((GETLE32(&gpuData[8]) >> 8) & 0x000000ff),
+ GETLE32(&gpuData[0]), GETLE32(&gpuData[3]),
+ GETLE32(&gpuData[6]), GETLE32(&gpuData[9]));
+ return;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+// SPRITE FUNCS
+////////////////////////////////////////////////////////////////////////
+
+void DrawSoftwareSpriteTWin(unsigned char * baseAddr, int32_t w, int32_t h) {
+ uint32_t *gpuData = (uint32_t *) baseAddr;
+ short sx0, sy0, sx1, sy1, sx2, sy2, sx3, sy3;
+ short tx0, ty0, tx1, ty1, tx2, ty2, tx3, ty3;
+
+ sx0 = g_soft.lx0;
+ sy0 = g_soft.ly0;
+
+ sx0 = sx3 = sx0 + g_gpu.dsp.DrawOffset.x;
+ sx1 = sx2 = sx0 + w;
+ sy0 = sy1 = sy0 + g_gpu.dsp.DrawOffset.y;
+ sy2 = sy3 = sy0 + h;
+
+ tx0 = tx3 = GETLE32(&gpuData[2]) & 0xff;
+ tx1 = tx2 = tx0 + w;
+ ty0 = ty1 = (GETLE32(&gpuData[2]) >> 8) & 0xff;
+ ty2 = ty3 = ty0 + h;
+
+ switch (g_soft.GlobalTextTP) {
+ case 0:
+ drawPoly4TEx4_TW_S(sx0, sy0, sx1, sy1, sx2, sy2, sx3, sy3, tx0, ty0,
+ tx1, ty1, tx2, ty2, tx3, ty3, ((GETLE32(&gpuData[2]) >> 12)
+ & 0x3f0), ((GETLE32(&gpuData[2]) >> 22) & 0x01ff));
+ return;
+ case 1:
+ drawPoly4TEx8_TW_S(sx0, sy0, sx1, sy1, sx2, sy2, sx3, sy3, tx0, ty0,
+ tx1, ty1, tx2, ty2, tx3, ty3, ((GETLE32(&gpuData[2]) >> 12)
+ & 0x3f0), ((GETLE32(&gpuData[2]) >> 22) & 0x01ff));
+ return;
+ case 2:
+ drawPoly4TD_TW_S(sx0, sy0, sx1, sy1, sx2, sy2, sx3, sy3, tx0, ty0, tx1,
+ ty1, tx2, ty2, tx3, ty3);
+ return;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void DrawSoftwareSpriteMirror(unsigned char * baseAddr, int32_t w, int32_t h) {
+ int32_t sprtY, sprtX, sprtW, sprtH, lXDir, lYDir;
+ int32_t clutY0, clutX0, clutP, textX0, textY0, sprtYa, sprCY, sprCX, sprA;
+ short tC;
+ uint32_t *gpuData = (uint32_t *) baseAddr;
+ sprtY = g_soft.ly0;
+ sprtX = g_soft.lx0;
+ sprtH = h;
+ sprtW = w;
+ clutY0 = (GETLE32(&gpuData[2]) >> 22) & 0x01ff;
+ clutX0 = (GETLE32(&gpuData[2]) >> 12) & 0x3f0;
+ clutP = (clutY0 << 11) + (clutX0 << 1);
+ textY0 = ((GETLE32(&gpuData[2]) >> 8) & 0x000000ff)
+ + g_soft.GlobalTextAddrY;
+ textX0 = (GETLE32(&gpuData[2]) & 0x000000ff);
+
+ sprtX += g_gpu.dsp.DrawOffset.x;
+ sprtY += g_gpu.dsp.DrawOffset.y;
+
+ // while (sprtX>1023) sprtX-=1024;
+ // while (sprtY>MAXYLINESMIN1) sprtY-=MAXYLINES;
+
+ if (sprtX > g_prim.drawW) {
+ // if((sprtX+sprtW)>1023) sprtX-=1024;
+ // else return;
+ return;
+ }
+
+ if (sprtY > g_prim.drawH) {
+ // if ((sprtY+sprtH)>MAXYLINESMIN1) sprtY-=MAXYLINES;
+ // else return;
+ return;
+ }
+
+ if (sprtY < g_prim.drawY) {
+ if ((sprtY + sprtH) < g_prim.drawY)
+ return;
+ sprtH -= (g_prim.drawY - sprtY);
+ textY0 += (g_prim.drawY - sprtY);
+ sprtY = g_prim.drawY;
+ }
+
+ if (sprtX < g_prim.drawX) {
+ if ((sprtX + sprtW) < g_prim.drawX)
+ return;
+ sprtW -= (g_prim.drawX - sprtX);
+ textX0 += (g_prim.drawX - sprtX);
+ sprtX = g_prim.drawX;
+ }
+
+ if ((sprtY + sprtH) > g_prim.drawH)
+ sprtH = g_prim.drawH - sprtY + 1;
+ if ((sprtX + sprtW) > g_prim.drawW)
+ sprtW = g_prim.drawW - sprtX + 1;
+
+ if (g_prim.usMirror & 0x1000)
+ lXDir = -1;
+ else
+ lXDir = 1;
+ if (g_prim.usMirror & 0x2000)
+ lYDir = -1;
+ else
+ lYDir = 1;
+
+ switch (g_soft.GlobalTextTP) {
+ case 0: // texture is 4-bit
+
+ sprtW = sprtW / 2;
+ textX0 = (g_soft.GlobalTextAddrX << 1) + (textX0 >> 1);
+ sprtYa = (sprtY << 10);
+ clutP = (clutY0 << 10) + clutX0;
+ for (sprCY = 0; sprCY < sprtH; sprCY++)
+ for (sprCX = 0; sprCX < sprtW; sprCX++) {
+ tC = g_gpu.psx_vram.u8[((textY0 + (sprCY * lYDir)) << 11)
+ + textX0 + (sprCX * lXDir)];
+ sprA = sprtYa + (sprCY << 10) + sprtX + (sprCX << 1);
+ GetTextureTransColG_SPR(&g_gpu.psx_vram.u16[sprA],
+ GETLE16(&g_gpu.psx_vram.u16[clutP+((tC>>4)&0xf)]));
+ GetTextureTransColG_SPR(&g_gpu.psx_vram.u16[sprA + 1],
+ GETLE16(&g_gpu.psx_vram.u16[clutP+(tC&0xf)]));
+ }
+ return;
+
+ case 1:
+
+ clutP >>= 1;
+ for (sprCY = 0; sprCY < sprtH; sprCY++)
+ for (sprCX = 0; sprCX < sprtW; sprCX++) {
+ tC = g_gpu.psx_vram.u8[((textY0 + (sprCY * lYDir)) << 11)
+ + (g_soft.GlobalTextAddrX << 1) + textX0 + (sprCX
+ * lXDir)] & 0xff;
+ GetTextureTransColG_SPR(&g_gpu.psx_vram.u16[((sprtY + sprCY)
+ << 10) + sprtX + sprCX], g_gpu.psx_vram.u16[clutP + tC]);
+ }
+ return;
+
+ case 2:
+
+ for (sprCY = 0; sprCY < sprtH; sprCY++)
+ for (sprCX = 0; sprCX < sprtW; sprCX++) {
+ GetTextureTransColG_SPR(
+ &g_gpu.psx_vram.u16[((sprtY + sprCY) << 10) + sprtX
+ + sprCX],
+ GETLE16(&g_gpu.psx_vram.u16[((textY0+(sprCY*lYDir))<<10)+g_soft.GlobalTextAddrX + textX0 +(sprCX*lXDir)]));
+ }
+ return;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void DrawSoftwareSprite_IL(unsigned char * baseAddr, short w, short h,
+ int32_t tx, int32_t ty) {
+ int32_t sprtY, sprtX, sprtW, sprtH, tdx, tdy;
+ uint32_t *gpuData = (uint32_t *) baseAddr;
+
+ sprtY = g_soft.ly0;
+ sprtX = g_soft.lx0;
+ sprtH = h;
+ sprtW = w;
+
+ sprtX += g_gpu.dsp.DrawOffset.x;
+ sprtY += g_gpu.dsp.DrawOffset.y;
+
+ if (sprtX > g_prim.drawW)
+ return;
+ if (sprtY > g_prim.drawH)
+ return;
+
+ tdx = tx + sprtW;
+ tdy = ty + sprtH;
+
+ sprtW += sprtX;
+ sprtH += sprtY;
+
+ // Pete is too lazy to make a faster version ;)
+
+ if (g_soft.GlobalTextTP == 0)
+ drawPoly4TEx4_IL(sprtX, sprtY, sprtX, sprtH, sprtW, sprtH, sprtW,
+ sprtY, tx, ty, tx, tdy, tdx, tdy, tdx, ty,
+ (GETLE32(&gpuData[2]) >> 12) & 0x3f0, ((GETLE32(&gpuData[2])
+ >> 22) & 0x01ff));
+
+ else
+ drawPoly4TEx8_IL(sprtX, sprtY, sprtX, sprtH, sprtW, sprtH, sprtW,
+ sprtY, tx, ty, tx, tdy, tdx, tdy, tdx, ty,
+ (GETLE32(&gpuData[2]) >> 12) & 0x3f0, ((GETLE32(&gpuData[2])
+ >> 22) & 0x01ff));
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void DrawSoftwareSprite(unsigned char * baseAddr, short w, short h, int32_t tx,
+ int32_t ty) {
+ int32_t sprtY, sprtX, sprtW, sprtH;
+ int32_t clutY0, clutX0, clutP, textX0, textY0, sprtYa, sprCY, sprCX, sprA;
+ short tC, tC2;
+ uint32_t *gpuData = (uint32_t *) baseAddr;
+ unsigned char * pV;
+ char bWT, bWS;
+
+ if (0 && g_soft.GlobalTextTP < 2) {
+ DrawSoftwareSprite_IL(baseAddr, w, h, tx, ty);
+ return;
+ }
+
+ sprtY = g_soft.ly0;
+ sprtX = g_soft.lx0;
+ sprtH = h;
+ sprtW = w;
+ clutY0 = (GETLE32(&gpuData[2]) >> 22) & 0x01ff;
+ clutX0 = (GETLE32(&gpuData[2]) >> 12) & 0x3f0;
+
+ clutP = (clutY0 << 11) + (clutX0 << 1);
+
+ textY0 = ty + g_soft.GlobalTextAddrY;
+ textX0 = tx;
+
+ sprtX += g_gpu.dsp.DrawOffset.x;
+ sprtY += g_gpu.dsp.DrawOffset.y;
+
+ //while (sprtX>1023) sprtX-=1024;
+ //while (sprtY>MAXYLINESMIN1) sprtY-=MAXYLINES;
+
+ if (sprtX > g_prim.drawW) {
+ // if((sprtX+sprtW)>1023) sprtX-=1024;
+ // else return;
+ return;
+ }
+
+ if (sprtY > g_prim.drawH) {
+ // if ((sprtY+sprtH)>MAXYLINESMIN1) sprtY-=MAXYLINES;
+ // else return;
+ return;
+ }
+
+ if (sprtY < g_prim.drawY) {
+ if ((sprtY + sprtH) < g_prim.drawY)
+ return;
+ sprtH -= (g_prim.drawY - sprtY);
+ textY0 += (g_prim.drawY - sprtY);
+ sprtY = g_prim.drawY;
+ }
+
+ if (sprtX < g_prim.drawX) {
+ if ((sprtX + sprtW) < g_prim.drawX)
+ return;
+
+ sprtW -= (g_prim.drawX - sprtX);
+ textX0 += (g_prim.drawX - sprtX);
+ sprtX = g_prim.drawX;
+ }
+
+ if ((sprtY + sprtH) > g_prim.drawH)
+ sprtH = g_prim.drawH - sprtY + 1;
+ if ((sprtX + sprtW) > g_prim.drawW)
+ sprtW = g_prim.drawW - sprtX + 1;
+
+ bWT = 0;
+ bWS = 0;
+
+ switch (g_soft.GlobalTextTP) {
+ case 0:
+
+ if (textX0 & 1) {
+ bWS = 1;
+ sprtW--;
+ }
+ if (sprtW & 1)
+ bWT = 1;
+
+ sprtW = sprtW >> 1;
+ textX0 = (g_soft.GlobalTextAddrX << 1) + (textX0 >> 1) + (textY0 << 11);
+ sprtYa = (sprtY << 10) + sprtX;
+ clutP = (clutY0 << 10) + clutX0;
+
+#ifdef FASTSOLID
+
+ if (!g_draw.bCheckMask && !g_soft.DrawSemiTrans) {
+ for (sprCY = 0; sprCY < sprtH; sprCY++) {
+ sprA = sprtYa + (sprCY << 10);
+ pV = &g_gpu.psx_vram.u8[(sprCY << 11) + textX0];
+
+ if (bWS) {
+ tC = *pV++;
+ GetTextureTransColG_S(&g_gpu.psx_vram.u16[sprA++],
+ GETLE16(&g_gpu.psx_vram.u16[clutP+((tC>>4)&0xf)]));
+ }
+
+ for (sprCX = 0; sprCX < sprtW; sprCX++, sprA += 2) {
+ tC = *pV++;
+
+ GetTextureTransColG32_S(
+ (uint32_t *) &g_gpu.psx_vram.u16[sprA],
+ (((int32_t) GETLE16(&g_gpu.psx_vram.u16[clutP+((tC>>4)&0xf)]))
+ << 16)
+ | GETLE16(&g_gpu.psx_vram.u16[clutP+(tC&0x0f)]));
+ }
+
+ if (bWT) {
+ tC = *pV;
+ GetTextureTransColG_S(&g_gpu.psx_vram.u16[sprA],
+ GETLE16(&g_gpu.psx_vram.u16[clutP+(tC&0x0f)]));
+ }
+ }
+ return;
+ }
+
+#endif
+
+ for (sprCY = 0; sprCY < sprtH; sprCY++) {
+ sprA = sprtYa + (sprCY << 10);
+ pV = &g_gpu.psx_vram.u8[(sprCY << 11) + textX0];
+
+ if (bWS) {
+ tC = *pV++;
+ GetTextureTransColG_SPR(&g_gpu.psx_vram.u16[sprA++],
+ GETLE16(&g_gpu.psx_vram.u16[clutP+((tC>>4)&0xf)]));
+ }
+
+ for (sprCX = 0; sprCX < sprtW; sprCX++, sprA += 2) {
+ tC = *pV++;
+
+ GetTextureTransColG32_SPR(
+ (uint32_t *) &g_gpu.psx_vram.u16[sprA],
+ (((int32_t) GETLE16(&g_gpu.psx_vram.u16[clutP+((tC>>4)&0xf)])
+ << 16))
+ | GETLE16(&g_gpu.psx_vram.u16[clutP+(tC&0x0f)]));
+ }
+
+ if (bWT) {
+ tC = *pV;
+ GetTextureTransColG_SPR(&g_gpu.psx_vram.u16[sprA],
+ GETLE16(&g_gpu.psx_vram.u16[clutP+(tC&0x0f)]));
+ }
+ }
+ return;
+
+ case 1:
+ clutP >>= 1;
+ sprtW--;
+ textX0 += (g_soft.GlobalTextAddrX << 1) + (textY0 << 11);
+
+#ifdef FASTSOLID
+
+ if (!g_draw.bCheckMask && !g_soft.DrawSemiTrans) {
+ for (sprCY = 0; sprCY < sprtH; sprCY++) {
+ sprA = ((sprtY + sprCY) << 10) + sprtX;
+ pV = &g_gpu.psx_vram.u8[(sprCY << 11) + textX0];
+ for (sprCX = 0; sprCX < sprtW; sprCX += 2, sprA += 2) {
+ tC = *pV++;
+ tC2 = *pV++;
+ GetTextureTransColG32_S(
+ (uint32_t *) &g_gpu.psx_vram.u16[sprA],
+ (((int32_t) GETLE16(&g_gpu.psx_vram.u16[clutP+tC2]))
+ << 16)
+ | GETLE16(&g_gpu.psx_vram.u16[clutP+tC]));
+ }
+ if (sprCX == sprtW)
+ GetTextureTransColG_S(&g_gpu.psx_vram.u16[sprA],
+ GETLE16(&g_gpu.psx_vram.u16[clutP+(*pV)]));
+ }
+ return;
+ }
+
+#endif
+
+ for (sprCY = 0; sprCY < sprtH; sprCY++) {
+ sprA = ((sprtY + sprCY) << 10) + sprtX;
+ pV = &g_gpu.psx_vram.u8[(sprCY << 11) + textX0];
+ for (sprCX = 0; sprCX < sprtW; sprCX += 2, sprA += 2) {
+ tC = *pV++;
+ tC2 = *pV++;
+ GetTextureTransColG32_SPR(
+ (uint32_t *) &g_gpu.psx_vram.u16[sprA],
+ (((int32_t) GETLE16(&g_gpu.psx_vram.u16[clutP+tC2]))
+ << 16) | GETLE16(&g_gpu.psx_vram.u16[clutP+tC]));
+ }
+ if (sprCX == sprtW)
+ GetTextureTransColG_SPR(&g_gpu.psx_vram.u16[sprA],
+ GETLE16(&g_gpu.psx_vram.u16[clutP+(*pV)]));
+ }
+ return;
+
+ case 2:
+
+ textX0 += (g_soft.GlobalTextAddrX) + (textY0 << 10);
+ sprtW--;
+
+#ifdef FASTSOLID
+
+ if (!g_draw.bCheckMask && !g_soft.DrawSemiTrans) {
+ for (sprCY = 0; sprCY < sprtH; sprCY++) {
+ sprA = ((sprtY + sprCY) << 10) + sprtX;
+
+ for (sprCX = 0; sprCX < sprtW; sprCX += 2, sprA += 2) {
+ GetTextureTransColG32_S(
+ (uint32_t *) &g_gpu.psx_vram.u16[sprA],
+ (((int32_t) GETLE16(&g_gpu.psx_vram.u16[(sprCY<<10) + textX0 + sprCX +1]))
+ << 16)
+ | GETLE16(&g_gpu.psx_vram.u16[(sprCY<<10) + textX0 + sprCX]));
+ }
+ if (sprCX == sprtW)
+ GetTextureTransColG_S(
+ &g_gpu.psx_vram.u16[sprA],
+ GETLE16(&g_gpu.psx_vram.u16[(sprCY<<10) + textX0 + sprCX]));
+
+ }
+ return;
+ }
+
+#endif
+
+ for (sprCY = 0; sprCY < sprtH; sprCY++) {
+ sprA = ((sprtY + sprCY) << 10) + sprtX;
+
+ for (sprCX = 0; sprCX < sprtW; sprCX += 2, sprA += 2) {
+ GetTextureTransColG32_SPR(
+ (uint32_t *) &g_gpu.psx_vram.u16[sprA],
+ (((int32_t) GETLE16(&g_gpu.psx_vram.u16[(sprCY<<10) + textX0 + sprCX +1]))
+ << 16)
+ | GETLE16(&g_gpu.psx_vram.u16[(sprCY<<10) + textX0 + sprCX]));
+ }
+ if (sprCX == sprtW)
+ GetTextureTransColG_SPR(
+ &g_gpu.psx_vram.u16[sprA],
+ GETLE16(&g_gpu.psx_vram.u16[(sprCY<<10) + textX0 + sprCX]));
+
+ }
+ return;
+ }
+}
+
+///////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////
+// LINE FUNCS
+////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////
+
+
+///////////////////////////////////////////////////////////////////////
+
+void Line_E_SE_Shade(int x0, int y0, int x1, int y1, uint32_t rgb0,
+ uint32_t rgb1) {
+ int dx, dy, incrE, incrSE, d;
+ uint32_t r0, g0, b0, r1, g1, b1;
+ int32_t dr, dg, db;
+
+ r0 = (rgb0 & 0x00ff0000);
+ g0 = (rgb0 & 0x0000ff00) << 8;
+ b0 = (rgb0 & 0x000000ff) << 16;
+ r1 = (rgb1 & 0x00ff0000);
+ g1 = (rgb1 & 0x0000ff00) << 8;
+ b1 = (rgb1 & 0x000000ff) << 16;
+
+ dx = x1 - x0;
+ dy = y1 - y0;
+
+ if (dx > 0) {
+ dr = ((int32_t) r1 - (int32_t) r0) / dx;
+ dg = ((int32_t) g1 - (int32_t) g0) / dx;
+ db = ((int32_t) b1 - (int32_t) b0) / dx;
+ } else {
+ dr = ((int32_t) r1 - (int32_t) r0);
+ dg = ((int32_t) g1 - (int32_t) g0);
+ db = ((int32_t) b1 - (int32_t) b0);
+ }
+
+ d = 2 * dy - dx; /* Initial value of d */
+ incrE = 2 * dy; /* incr. used for move to E */
+ incrSE = 2 * (dy - dx); /* incr. used for move to SE */
+
+ if ((x0 >= g_prim.drawX) && (x0 < g_prim.drawW) && (y0 >= g_prim.drawY)
+ && (y0 < g_prim.drawH))
+ GetShadeTransCol(&g_gpu.psx_vram.u16[(y0 << 10) + x0],
+ (unsigned short) (((r0 >> 9) & 0x7c00) | ((g0 >> 14) & 0x03e0)
+ | ((b0 >> 19) & 0x001f)));
+ while (x0 < x1) {
+ if (d <= 0) {
+ d = d + incrE; /* Choose E */
+ } else {
+ d = d + incrSE; /* Choose SE */
+ y0++;
+ }
+ x0++;
+
+ r0 += dr;
+ g0 += dg;
+ b0 += db;
+
+ if ((x0 >= g_prim.drawX) && (x0 < g_prim.drawW) && (y0 >= g_prim.drawY)
+ && (y0 < g_prim.drawH))
+ GetShadeTransCol(&g_gpu.psx_vram.u16[(y0 << 10) + x0],
+ (unsigned short) (((r0 >> 9) & 0x7c00) | ((g0 >> 14)
+ & 0x03e0) | ((b0 >> 19) & 0x001f)));
+ }
+}
+
+///////////////////////////////////////////////////////////////////////
+
+void Line_S_SE_Shade(int x0, int y0, int x1, int y1, uint32_t rgb0,
+ uint32_t rgb1) {
+ int dx, dy, incrS, incrSE, d;
+ uint32_t r0, g0, b0, r1, g1, b1;
+ int32_t dr, dg, db;
+
+ r0 = (rgb0 & 0x00ff0000);
+ g0 = (rgb0 & 0x0000ff00) << 8;
+ b0 = (rgb0 & 0x000000ff) << 16;
+ r1 = (rgb1 & 0x00ff0000);
+ g1 = (rgb1 & 0x0000ff00) << 8;
+ b1 = (rgb1 & 0x000000ff) << 16;
+
+ dx = x1 - x0;
+ dy = y1 - y0;
+
+ if (dy > 0) {
+ dr = ((int32_t) r1 - (int32_t) r0) / dy;
+ dg = ((int32_t) g1 - (int32_t) g0) / dy;
+ db = ((int32_t) b1 - (int32_t) b0) / dy;
+ } else {
+ dr = ((int32_t) r1 - (int32_t) r0);
+ dg = ((int32_t) g1 - (int32_t) g0);
+ db = ((int32_t) b1 - (int32_t) b0);
+ }
+
+ d = 2 * dx - dy; /* Initial value of d */
+ incrS = 2 * dx; /* incr. used for move to S */
+ incrSE = 2 * (dx - dy); /* incr. used for move to SE */
+
+ if ((x0 >= g_prim.drawX) && (x0 < g_prim.drawW) && (y0 >= g_prim.drawY)
+ && (y0 < g_prim.drawH))
+ GetShadeTransCol(&g_gpu.psx_vram.u16[(y0 << 10) + x0],
+ (unsigned short) (((r0 >> 9) & 0x7c00) | ((g0 >> 14) & 0x03e0)
+ | ((b0 >> 19) & 0x001f)));
+ while (y0 < y1) {
+ if (d <= 0) {
+ d = d + incrS; /* Choose S */
+ } else {
+ d = d + incrSE; /* Choose SE */
+ x0++;
+ }
+ y0++;
+
+ r0 += dr;
+ g0 += dg;
+ b0 += db;
+
+ if ((x0 >= g_prim.drawX) && (x0 < g_prim.drawW) && (y0 >= g_prim.drawY)
+ && (y0 < g_prim.drawH))
+ GetShadeTransCol(&g_gpu.psx_vram.u16[(y0 << 10) + x0],
+ (unsigned short) (((r0 >> 9) & 0x7c00) | ((g0 >> 14)
+ & 0x03e0) | ((b0 >> 19) & 0x001f)));
+ }
+}
+
+///////////////////////////////////////////////////////////////////////
+
+void Line_N_NE_Shade(int x0, int y0, int x1, int y1, uint32_t rgb0,
+ uint32_t rgb1) {
+ int dx, dy, incrN, incrNE, d;
+ uint32_t r0, g0, b0, r1, g1, b1;
+ int32_t dr, dg, db;
+
+ r0 = (rgb0 & 0x00ff0000);
+ g0 = (rgb0 & 0x0000ff00) << 8;
+ b0 = (rgb0 & 0x000000ff) << 16;
+ r1 = (rgb1 & 0x00ff0000);
+ g1 = (rgb1 & 0x0000ff00) << 8;
+ b1 = (rgb1 & 0x000000ff) << 16;
+
+ dx = x1 - x0;
+ dy = -(y1 - y0);
+
+ if (dy > 0) {
+ dr = ((int32_t) r1 - (int32_t) r0) / dy;
+ dg = ((int32_t) g1 - (int32_t) g0) / dy;
+ db = ((int32_t) b1 - (int32_t) b0) / dy;
+ } else {
+ dr = ((int32_t) r1 - (int32_t) r0);
+ dg = ((int32_t) g1 - (int32_t) g0);
+ db = ((int32_t) b1 - (int32_t) b0);
+ }
+
+ d = 2 * dx - dy; /* Initial value of d */
+ incrN = 2 * dx; /* incr. used for move to N */
+ incrNE = 2 * (dx - dy); /* incr. used for move to NE */
+
+ if ((x0 >= g_prim.drawX) && (x0 < g_prim.drawW) && (y0 >= g_prim.drawY)
+ && (y0 < g_prim.drawH))
+ GetShadeTransCol(&g_gpu.psx_vram.u16[(y0 << 10) + x0],
+ (unsigned short) (((r0 >> 9) & 0x7c00) | ((g0 >> 14) & 0x03e0)
+ | ((b0 >> 19) & 0x001f)));
+ while (y0 > y1) {
+ if (d <= 0) {
+ d = d + incrN; /* Choose N */
+ } else {
+ d = d + incrNE; /* Choose NE */
+ x0++;
+ }
+ y0--;
+
+ r0 += dr;
+ g0 += dg;
+ b0 += db;
+
+ if ((x0 >= g_prim.drawX) && (x0 < g_prim.drawW) && (y0 >= g_prim.drawY)
+ && (y0 < g_prim.drawH))
+ GetShadeTransCol(&g_gpu.psx_vram.u16[(y0 << 10) + x0],
+ (unsigned short) (((r0 >> 9) & 0x7c00) | ((g0 >> 14)
+ & 0x03e0) | ((b0 >> 19) & 0x001f)));
+ }
+}
+
+///////////////////////////////////////////////////////////////////////
+
+void Line_E_NE_Shade(int x0, int y0, int x1, int y1, uint32_t rgb0,
+ uint32_t rgb1) {
+ int dx, dy, incrE, incrNE, d;
+ uint32_t r0, g0, b0, r1, g1, b1;
+ int32_t dr, dg, db;
+
+ r0 = (rgb0 & 0x00ff0000);
+ g0 = (rgb0 & 0x0000ff00) << 8;
+ b0 = (rgb0 & 0x000000ff) << 16;
+ r1 = (rgb1 & 0x00ff0000);
+ g1 = (rgb1 & 0x0000ff00) << 8;
+ b1 = (rgb1 & 0x000000ff) << 16;
+
+ dx = x1 - x0;
+ dy = -(y1 - y0);
+
+ if (dx > 0) {
+ dr = ((int32_t) r1 - (int32_t) r0) / dx;
+ dg = ((int32_t) g1 - (int32_t) g0) / dx;
+ db = ((int32_t) b1 - (int32_t) b0) / dx;
+ } else {
+ dr = ((int32_t) r1 - (int32_t) r0);
+ dg = ((int32_t) g1 - (int32_t) g0);
+ db = ((int32_t) b1 - (int32_t) b0);
+ }
+
+ d = 2 * dy - dx; /* Initial value of d */
+ incrE = 2 * dy; /* incr. used for move to E */
+ incrNE = 2 * (dy - dx); /* incr. used for move to NE */
+
+ if ((x0 >= g_prim.drawX) && (x0 < g_prim.drawW) && (y0 >= g_prim.drawY)
+ && (y0 < g_prim.drawH))
+ GetShadeTransCol(&g_gpu.psx_vram.u16[(y0 << 10) + x0],
+ (unsigned short) (((r0 >> 9) & 0x7c00) | ((g0 >> 14) & 0x03e0)
+ | ((b0 >> 19) & 0x001f)));
+ while (x0 < x1) {
+ if (d <= 0) {
+ d = d + incrE; /* Choose E */
+ } else {
+ d = d + incrNE; /* Choose NE */
+ y0--;
+ }
+ x0++;
+
+ r0 += dr;
+ g0 += dg;
+ b0 += db;
+
+ if ((x0 >= g_prim.drawX) && (x0 < g_prim.drawW) && (y0 >= g_prim.drawY)
+ && (y0 < g_prim.drawH))
+ GetShadeTransCol(&g_gpu.psx_vram.u16[(y0 << 10) + x0],
+ (unsigned short) (((r0 >> 9) & 0x7c00) | ((g0 >> 14)
+ & 0x03e0) | ((b0 >> 19) & 0x001f)));
+ }
+}
+
+///////////////////////////////////////////////////////////////////////
+
+void VertLineShade(int x, int y0, int y1, uint32_t rgb0, uint32_t rgb1) {
+ int y, dy;
+ uint32_t r0, g0, b0, r1, g1, b1;
+ int32_t dr, dg, db;
+
+ r0 = (rgb0 & 0x00ff0000);
+ g0 = (rgb0 & 0x0000ff00) << 8;
+ b0 = (rgb0 & 0x000000ff) << 16;
+ r1 = (rgb1 & 0x00ff0000);
+ g1 = (rgb1 & 0x0000ff00) << 8;
+ b1 = (rgb1 & 0x000000ff) << 16;
+
+ dy = (y1 - y0);
+
+ if (dy > 0) {
+ dr = ((int32_t) r1 - (int32_t) r0) / dy;
+ dg = ((int32_t) g1 - (int32_t) g0) / dy;
+ db = ((int32_t) b1 - (int32_t) b0) / dy;
+ } else {
+ dr = ((int32_t) r1 - (int32_t) r0);
+ dg = ((int32_t) g1 - (int32_t) g0);
+ db = ((int32_t) b1 - (int32_t) b0);
+ }
+
+ if (y0 < g_prim.drawY) {
+ r0 += dr * (g_prim.drawY - y0);
+ g0 += dg * (g_prim.drawY - y0);
+ b0 += db * (g_prim.drawY - y0);
+ y0 = g_prim.drawY;
+ }
+
+ if (y1 > g_prim.drawH)
+ y1 = g_prim.drawH;
+
+ for (y = y0; y <= y1; y++) {
+ GetShadeTransCol(&g_gpu.psx_vram.u16[(y << 10) + x],
+ (unsigned short) (((r0 >> 9) & 0x7c00) | ((g0 >> 14) & 0x03e0)
+ | ((b0 >> 19) & 0x001f)));
+ r0 += dr;
+ g0 += dg;
+ b0 += db;
+ }
+}
+
+///////////////////////////////////////////////////////////////////////
+
+void HorzLineShade(int y, int x0, int x1, uint32_t rgb0, uint32_t rgb1) {
+ int x, dx;
+ uint32_t r0, g0, b0, r1, g1, b1;
+ int32_t dr, dg, db;
+
+ r0 = (rgb0 & 0x00ff0000);
+ g0 = (rgb0 & 0x0000ff00) << 8;
+ b0 = (rgb0 & 0x000000ff) << 16;
+ r1 = (rgb1 & 0x00ff0000);
+ g1 = (rgb1 & 0x0000ff00) << 8;
+ b1 = (rgb1 & 0x000000ff) << 16;
+
+ dx = (x1 - x0);
+
+ if (dx > 0) {
+ dr = ((int32_t) r1 - (int32_t) r0) / dx;
+ dg = ((int32_t) g1 - (int32_t) g0) / dx;
+ db = ((int32_t) b1 - (int32_t) b0) / dx;
+ } else {
+ dr = ((int32_t) r1 - (int32_t) r0);
+ dg = ((int32_t) g1 - (int32_t) g0);
+ db = ((int32_t) b1 - (int32_t) b0);
+ }
+
+ if (x0 < g_prim.drawX) {
+ r0 += dr * (g_prim.drawX - x0);
+ g0 += dg * (g_prim.drawX - x0);
+ b0 += db * (g_prim.drawX - x0);
+ x0 = g_prim.drawX;
+ }
+
+ if (x1 > g_prim.drawW)
+ x1 = g_prim.drawW;
+
+ for (x = x0; x <= x1; x++) {
+ GetShadeTransCol(&g_gpu.psx_vram.u16[(y << 10) + x],
+ (unsigned short) (((r0 >> 9) & 0x7c00) | ((g0 >> 14) & 0x03e0)
+ | ((b0 >> 19) & 0x001f)));
+ r0 += dr;
+ g0 += dg;
+ b0 += db;
+ }
+}
+
+///////////////////////////////////////////////////////////////////////
+
+void Line_E_SE_Flat(int x0, int y0, int x1, int y1, unsigned short colour) {
+ int dx, dy, incrE, incrSE, d, x, y;
+
+ dx = x1 - x0;
+ dy = y1 - y0;
+ d = 2 * dy - dx; /* Initial value of d */
+ incrE = 2 * dy; /* incr. used for move to E */
+ incrSE = 2 * (dy - dx); /* incr. used for move to SE */
+ x = x0;
+ y = y0;
+ if ((x >= g_prim.drawX) && (x < g_prim.drawW) && (y >= g_prim.drawY) && (y
+ < g_prim.drawH))
+ GetShadeTransCol(&g_gpu.psx_vram.u16[(y << 10) + x], colour);
+ while (x < x1) {
+ if (d <= 0) {
+ d = d + incrE; /* Choose E */
+ x++;
+ } else {
+ d = d + incrSE; /* Choose SE */
+ x++;
+ y++;
+ }
+ if ((x >= g_prim.drawX) && (x < g_prim.drawW) && (y >= g_prim.drawY)
+ && (y < g_prim.drawH))
+ GetShadeTransCol(&g_gpu.psx_vram.u16[(y << 10) + x], colour);
+ }
+}
+
+///////////////////////////////////////////////////////////////////////
+
+void Line_S_SE_Flat(int x0, int y0, int x1, int y1, unsigned short colour) {
+ int dx, dy, incrS, incrSE, d, x, y;
+
+ dx = x1 - x0;
+ dy = y1 - y0;
+ d = 2 * dx - dy; /* Initial value of d */
+ incrS = 2 * dx; /* incr. used for move to S */
+ incrSE = 2 * (dx - dy); /* incr. used for move to SE */
+ x = x0;
+ y = y0;
+ if ((x >= g_prim.drawX) && (x < g_prim.drawW) && (y >= g_prim.drawY) && (y
+ < g_prim.drawH))
+ GetShadeTransCol(&g_gpu.psx_vram.u16[(y << 10) + x], colour);
+ while (y < y1) {
+ if (d <= 0) {
+ d = d + incrS; /* Choose S */
+ y++;
+ } else {
+ d = d + incrSE; /* Choose SE */
+ x++;
+ y++;
+ }
+ if ((x >= g_prim.drawX) && (x < g_prim.drawW) && (y >= g_prim.drawY)
+ && (y < g_prim.drawH))
+ GetShadeTransCol(&g_gpu.psx_vram.u16[(y << 10) + x], colour);
+ }
+}
+
+///////////////////////////////////////////////////////////////////////
+
+void Line_N_NE_Flat(int x0, int y0, int x1, int y1, unsigned short colour) {
+ int dx, dy, incrN, incrNE, d, x, y;
+
+ dx = x1 - x0;
+ dy = -(y1 - y0);
+ d = 2 * dx - dy; /* Initial value of d */
+ incrN = 2 * dx; /* incr. used for move to N */
+ incrNE = 2 * (dx - dy); /* incr. used for move to NE */
+ x = x0;
+ y = y0;
+ if ((x >= g_prim.drawX) && (x < g_prim.drawW) && (y >= g_prim.drawY) && (y
+ < g_prim.drawH))
+ GetShadeTransCol(&g_gpu.psx_vram.u16[(y << 10) + x], colour);
+ while (y > y1) {
+ if (d <= 0) {
+ d = d + incrN; /* Choose N */
+ y--;
+ } else {
+ d = d + incrNE; /* Choose NE */
+ x++;
+ y--;
+ }
+ if ((x >= g_prim.drawX) && (x < g_prim.drawW) && (y >= g_prim.drawY)
+ && (y < g_prim.drawH))
+ GetShadeTransCol(&g_gpu.psx_vram.u16[(y << 10) + x], colour);
+ }
+}
+
+///////////////////////////////////////////////////////////////////////
+
+void Line_E_NE_Flat(int x0, int y0, int x1, int y1, unsigned short colour) {
+ int dx, dy, incrE, incrNE, d, x, y;
+
+ dx = x1 - x0;
+ dy = -(y1 - y0);
+ d = 2 * dy - dx; /* Initial value of d */
+ incrE = 2 * dy; /* incr. used for move to E */
+ incrNE = 2 * (dy - dx); /* incr. used for move to NE */
+ x = x0;
+ y = y0;
+ if ((x >= g_prim.drawX) && (x < g_prim.drawW) && (y >= g_prim.drawY) && (y
+ < g_prim.drawH))
+ GetShadeTransCol(&g_gpu.psx_vram.u16[(y << 10) + x], colour);
+ while (x < x1) {
+ if (d <= 0) {
+ d = d + incrE; /* Choose E */
+ x++;
+ } else {
+ d = d + incrNE; /* Choose NE */
+ x++;
+ y--;
+ }
+ if ((x >= g_prim.drawX) && (x < g_prim.drawW) && (y >= g_prim.drawY)
+ && (y < g_prim.drawH))
+ GetShadeTransCol(&g_gpu.psx_vram.u16[(y << 10) + x], colour);
+ }
+}
+
+///////////////////////////////////////////////////////////////////////
+
+void VertLineFlat(int x, int y0, int y1, unsigned short colour) {
+ int y;
+
+ if (y0 < g_prim.drawY)
+ y0 = g_prim.drawY;
+
+ if (y1 > g_prim.drawH)
+ y1 = g_prim.drawH;
+
+ for (y = y0; y <= y1; y++)
+ GetShadeTransCol(&g_gpu.psx_vram.u16[(y << 10) + x], colour);
+}
+
+///////////////////////////////////////////////////////////////////////
+
+void HorzLineFlat(int y, int x0, int x1, unsigned short colour) {
+ int x;
+
+ if (x0 < g_prim.drawX)
+ x0 = g_prim.drawX;
+
+ if (x1 > g_prim.drawW)
+ x1 = g_prim.drawW;
+
+ for (x = x0; x <= x1; x++)
+ GetShadeTransCol(&g_gpu.psx_vram.u16[(y << 10) + x], colour);
+}
+
+///////////////////////////////////////////////////////////////////////
+
+/* Bresenham Line drawing function */
+void DrawSoftwareLineShade(int32_t rgb0, int32_t rgb1) {
+ short x0, y0, x1, y1, xt, yt;
+ int32_t rgbt;
+ double m, dy, dx;
+
+ if (g_soft.lx0 > g_prim.drawW && g_soft.lx1 > g_prim.drawW)
+ return;
+ if (g_soft.ly0 > g_prim.drawH && g_soft.ly1 > g_prim.drawH)
+ return;
+ if (g_soft.lx0 < g_prim.drawX && g_soft.lx1 < g_prim.drawX)
+ return;
+ if (g_soft.ly0 < g_prim.drawY && g_soft.ly1 < g_prim.drawY)
+ return;
+ if (g_prim.drawY >= g_prim.drawH)
+ return;
+ if (g_prim.drawX >= g_prim.drawW)
+ return;
+
+ x0 = g_soft.lx0;
+ y0 = g_soft.ly0;
+ x1 = g_soft.lx1;
+ y1 = g_soft.ly1;
+
+ dx = x1 - x0;
+ dy = y1 - y0;
+
+ if (dx == 0) {
+ if (dy > 0)
+ VertLineShade(x0, y0, y1, rgb0, rgb1);
+ else
+ VertLineShade(x0, y1, y0, rgb1, rgb0);
+ } else if (dy == 0) {
+ if (dx > 0)
+ HorzLineShade(y0, x0, x1, rgb0, rgb1);
+ else
+ HorzLineShade(y0, x1, x0, rgb1, rgb0);
+ } else {
+ if (dx < 0) {
+ xt = x0;
+ yt = y0;
+ rgbt = rgb0;
+ x0 = x1;
+ y0 = y1;
+ rgb0 = rgb1;
+ x1 = xt;
+ y1 = yt;
+ rgb1 = rgbt;
+
+ dx = x1 - x0;
+ dy = y1 - y0;
+ }
+
+ m = dy / dx;
+
+ if (m >= 0) {
+ if (m > 1)
+ Line_S_SE_Shade(x0, y0, x1, y1, rgb0, rgb1);
+ else
+ Line_E_SE_Shade(x0, y0, x1, y1, rgb0, rgb1);
+ } else if (m < -1)
+ Line_N_NE_Shade(x0, y0, x1, y1, rgb0, rgb1);
+ else
+ Line_E_NE_Shade(x0, y0, x1, y1, rgb0, rgb1);
+ }
+}
+
+///////////////////////////////////////////////////////////////////////
+
+void DrawSoftwareLineFlat(int32_t rgb) {
+ short x0, y0, x1, y1, xt, yt;
+ double m, dy, dx;
+ unsigned short colour = 0;
+
+ if (g_soft.lx0 > g_prim.drawW && g_soft.lx1 > g_prim.drawW)
+ return;
+ if (g_soft.ly0 > g_prim.drawH && g_soft.ly1 > g_prim.drawH)
+ return;
+ if (g_soft.lx0 < g_prim.drawX && g_soft.lx1 < g_prim.drawX)
+ return;
+ if (g_soft.ly0 < g_prim.drawY && g_soft.ly1 < g_prim.drawY)
+ return;
+ if (g_prim.drawY >= g_prim.drawH)
+ return;
+ if (g_prim.drawX >= g_prim.drawW)
+ return;
+
+ colour = ((rgb & 0x00f80000) >> 9) | ((rgb & 0x0000f800) >> 6) | ((rgb
+ & 0x000000f8) >> 3);
+
+ x0 = g_soft.lx0;
+ y0 = g_soft.ly0;
+ x1 = g_soft.lx1;
+ y1 = g_soft.ly1;
+
+ dx = x1 - x0;
+ dy = y1 - y0;
+
+ if (dx == 0) {
+ if (dy == 0)
+ return; // Nothing to draw
+ else if (dy > 0)
+ VertLineFlat(x0, y0, y1, colour);
+ else
+ VertLineFlat(x0, y1, y0, colour);
+ } else if (dy == 0) {
+ if (dx > 0)
+ HorzLineFlat(y0, x0, x1, colour);
+ else
+ HorzLineFlat(y0, x1, x0, colour);
+ } else {
+ if (dx < 0) {
+ xt = x0;
+ yt = y0;
+ x0 = x1;
+ y0 = y1;
+ x1 = xt;
+ y1 = yt;
+
+ dx = x1 - x0;
+ dy = y1 - y0;
+ }
+
+ m = dy / dx;
+
+ if (m >= 0) {
+ if (m > 1)
+ Line_S_SE_Flat(x0, y0, x1, y1, colour);
+ else
+ Line_E_SE_Flat(x0, y0, x1, y1, colour);
+ } else if (m < -1)
+ Line_N_NE_Flat(x0, y0, x1, y1, colour);
+ else
+ Line_E_NE_Flat(x0, y0, x1, y1, colour);
+ }
+}
+
+///////////////////////////////////////////////////////////////////////