From 5d4340d2e54f9712c299ab70e645a2cd490c62c3 Mon Sep 17 00:00:00 2001 From: zilmar Date: Fri, 5 Apr 2013 08:22:19 +1100 Subject: [PATCH] Add Glide64 plugin --- Source/Glide64/3dmath.cpp | 269 + Source/Glide64/3dmath.h | 54 + Source/Glide64/3dmathSIMD.asm | 497 + Source/Glide64/CB/Glide64.cbp | 198 + Source/Glide64/CRC.cpp | 142 + Source/Glide64/CRC.h | 48 + Source/Glide64/Combine.cpp | 16654 ++++++++++++++++ Source/Glide64/Combine.h | 120 + Source/Glide64/Config.cpp | 1430 ++ Source/Glide64/Config.h | 264 + Source/Glide64/Debugger.cpp | 1020 + Source/Glide64/Debugger.h | 137 + Source/Glide64/DepthBufferRender.cpp | 300 + Source/Glide64/DepthBufferRender.h | 60 + Source/Glide64/Ext_TxFilter.cpp | 164 + Source/Glide64/Ext_TxFilter.h | 211 + Source/Glide64/FBtoScreen.cpp | 663 + Source/Glide64/FBtoScreen.h | 63 + Source/Glide64/FixedPoint.asm | 81 + Source/Glide64/Gfx #1.3.h | 700 + Source/Glide64/GlideExtensions.h | 45 + Source/Glide64/Help/Glide64 Help.chm | Bin 0 -> 119621 bytes Source/Glide64/Help/Glide64 Known Issues.html | 1399 ++ Source/Glide64/Help/Glide64 Readme.html | 311 + .../Help/Glide64 compatibility list.html | 6153 ++++++ .../Glide64/Internalization/Glide64_de_DE.po | 1284 ++ Source/Glide64/Internalization/Glide64_en.pot | 1118 ++ .../Glide64/Internalization/Glide64_fr_FR.po | 1336 ++ .../Glide64/Internalization/Glide64_ja_JP.po | 1258 ++ .../Glide64/Internalization/Glide64_ru_RU.po | 1315 ++ .../Glide64/Internalization/Glide64_zh_CN.po | 1419 ++ .../Glide64/Internalization/Glide64_zh_TW.po | 1419 ++ Source/Glide64/Keys.cpp | 113 + Source/Glide64/Keys.h | 93 + Source/Glide64/MSVS/Debug/BuildLog.htm | Bin 0 -> 12958 bytes Source/Glide64/MSVS/Debug/CRC.obj | Bin 0 -> 5208 bytes Source/Glide64/MSVS/Debug/Ext_TxFilter.obj | Bin 0 -> 30078 bytes .../MSVS/Debug/Glide64.dll.embed.manifest | 1 + Source/Glide64/MSVS/Debug/vc90.idb | Bin 0 -> 142336 bytes Source/Glide64/MSVS/Debug/vc90.pdb | Bin 0 -> 102400 bytes Source/Glide64/MSVS/Glide64.vcproj | 518 + Source/Glide64/Main.cpp | 2435 +++ Source/Glide64/Makefile.gcc | 189 + Source/Glide64/MiClWr16b.h | 167 + Source/Glide64/MiClWr32b.h | 171 + Source/Glide64/MiClWr8b.h | 166 + Source/Glide64/TexBuffer.cpp | 752 + Source/Glide64/TexBuffer.h | 60 + Source/Glide64/TexCache.cpp | 1807 ++ Source/Glide64/TexCache.h | 49 + Source/Glide64/TexConv.h | 75 + Source/Glide64/TexLoad.h | 76 + Source/Glide64/TexLoad16b.h | 136 + Source/Glide64/TexLoad32b.h | 177 + Source/Glide64/TexLoad4b.h | 114 + Source/Glide64/TexLoad8b.h | 103 + Source/Glide64/TexMod.h | 581 + Source/Glide64/TexModCI.h | 437 + Source/Glide64/Texture.asm | 3836 ++++ Source/Glide64/Util.cpp | 2182 ++ Source/Glide64/Util.h | 93 + Source/Glide64/australia.xpm | 34 + Source/Glide64/brazil.xpm | 40 + Source/Glide64/build_asm.bat | 3 + Source/Glide64/config/Glide64.ini | 1774 ++ Source/Glide64/cursor.h | 2049 ++ Source/Glide64/font.h | 2049 ++ Source/Glide64/france.xpm | 28 + Source/Glide64/gpl.txt | 340 + Source/Glide64/inc/3dfx.h | 130 + Source/Glide64/inc/c32.mac | 52 + Source/Glide64/inc/glide.h | 946 + Source/Glide64/inc/glidesys.h | 160 + Source/Glide64/inc/glideutl.h | 153 + Source/Glide64/inc/sst1vid.h | 148 + Source/Glide64/japan.xpm | 27 + Source/Glide64/lib/glide3x.lib | Bin 0 -> 77030 bytes Source/Glide64/logo.xpm | 360 + Source/Glide64/rdp.cpp | 4025 ++++ Source/Glide64/rdp.h | 912 + Source/Glide64/russia.xpm | 35 + Source/Glide64/turbo3D.h | 276 + Source/Glide64/ucode.h | 792 + Source/Glide64/ucode00.h | 1156 ++ Source/Glide64/ucode01.h | 163 + Source/Glide64/ucode02.h | 815 + Source/Glide64/ucode03.h | 114 + Source/Glide64/ucode04.h | 82 + Source/Glide64/ucode05.h | 375 + Source/Glide64/ucode06.h | 1720 ++ Source/Glide64/ucode07.h | 179 + Source/Glide64/ucode08.h | 546 + Source/Glide64/ucode09.h | 687 + Source/Glide64/ucode09rdp.h | 70 + Source/Glide64/ucodeFB.h | 1110 + Source/Glide64/usa.xpm | 35 + 96 files changed, 75848 insertions(+) create mode 100644 Source/Glide64/3dmath.cpp create mode 100644 Source/Glide64/3dmath.h create mode 100644 Source/Glide64/3dmathSIMD.asm create mode 100644 Source/Glide64/CB/Glide64.cbp create mode 100644 Source/Glide64/CRC.cpp create mode 100644 Source/Glide64/CRC.h create mode 100644 Source/Glide64/Combine.cpp create mode 100644 Source/Glide64/Combine.h create mode 100644 Source/Glide64/Config.cpp create mode 100644 Source/Glide64/Config.h create mode 100644 Source/Glide64/Debugger.cpp create mode 100644 Source/Glide64/Debugger.h create mode 100644 Source/Glide64/DepthBufferRender.cpp create mode 100644 Source/Glide64/DepthBufferRender.h create mode 100644 Source/Glide64/Ext_TxFilter.cpp create mode 100644 Source/Glide64/Ext_TxFilter.h create mode 100644 Source/Glide64/FBtoScreen.cpp create mode 100644 Source/Glide64/FBtoScreen.h create mode 100644 Source/Glide64/FixedPoint.asm create mode 100644 Source/Glide64/Gfx #1.3.h create mode 100644 Source/Glide64/GlideExtensions.h create mode 100644 Source/Glide64/Help/Glide64 Help.chm create mode 100644 Source/Glide64/Help/Glide64 Known Issues.html create mode 100644 Source/Glide64/Help/Glide64 Readme.html create mode 100644 Source/Glide64/Help/Glide64 compatibility list.html create mode 100644 Source/Glide64/Internalization/Glide64_de_DE.po create mode 100644 Source/Glide64/Internalization/Glide64_en.pot create mode 100644 Source/Glide64/Internalization/Glide64_fr_FR.po create mode 100644 Source/Glide64/Internalization/Glide64_ja_JP.po create mode 100644 Source/Glide64/Internalization/Glide64_ru_RU.po create mode 100644 Source/Glide64/Internalization/Glide64_zh_CN.po create mode 100644 Source/Glide64/Internalization/Glide64_zh_TW.po create mode 100644 Source/Glide64/Keys.cpp create mode 100644 Source/Glide64/Keys.h create mode 100644 Source/Glide64/MSVS/Debug/BuildLog.htm create mode 100644 Source/Glide64/MSVS/Debug/CRC.obj create mode 100644 Source/Glide64/MSVS/Debug/Ext_TxFilter.obj create mode 100644 Source/Glide64/MSVS/Debug/Glide64.dll.embed.manifest create mode 100644 Source/Glide64/MSVS/Debug/vc90.idb create mode 100644 Source/Glide64/MSVS/Debug/vc90.pdb create mode 100644 Source/Glide64/MSVS/Glide64.vcproj create mode 100644 Source/Glide64/Main.cpp create mode 100644 Source/Glide64/Makefile.gcc create mode 100644 Source/Glide64/MiClWr16b.h create mode 100644 Source/Glide64/MiClWr32b.h create mode 100644 Source/Glide64/MiClWr8b.h create mode 100644 Source/Glide64/TexBuffer.cpp create mode 100644 Source/Glide64/TexBuffer.h create mode 100644 Source/Glide64/TexCache.cpp create mode 100644 Source/Glide64/TexCache.h create mode 100644 Source/Glide64/TexConv.h create mode 100644 Source/Glide64/TexLoad.h create mode 100644 Source/Glide64/TexLoad16b.h create mode 100644 Source/Glide64/TexLoad32b.h create mode 100644 Source/Glide64/TexLoad4b.h create mode 100644 Source/Glide64/TexLoad8b.h create mode 100644 Source/Glide64/TexMod.h create mode 100644 Source/Glide64/TexModCI.h create mode 100644 Source/Glide64/Texture.asm create mode 100644 Source/Glide64/Util.cpp create mode 100644 Source/Glide64/Util.h create mode 100644 Source/Glide64/australia.xpm create mode 100644 Source/Glide64/brazil.xpm create mode 100644 Source/Glide64/build_asm.bat create mode 100644 Source/Glide64/config/Glide64.ini create mode 100644 Source/Glide64/cursor.h create mode 100644 Source/Glide64/font.h create mode 100644 Source/Glide64/france.xpm create mode 100644 Source/Glide64/gpl.txt create mode 100644 Source/Glide64/inc/3dfx.h create mode 100644 Source/Glide64/inc/c32.mac create mode 100644 Source/Glide64/inc/glide.h create mode 100644 Source/Glide64/inc/glidesys.h create mode 100644 Source/Glide64/inc/glideutl.h create mode 100644 Source/Glide64/inc/sst1vid.h create mode 100644 Source/Glide64/japan.xpm create mode 100644 Source/Glide64/lib/glide3x.lib create mode 100644 Source/Glide64/logo.xpm create mode 100644 Source/Glide64/rdp.cpp create mode 100644 Source/Glide64/rdp.h create mode 100644 Source/Glide64/russia.xpm create mode 100644 Source/Glide64/turbo3D.h create mode 100644 Source/Glide64/ucode.h create mode 100644 Source/Glide64/ucode00.h create mode 100644 Source/Glide64/ucode01.h create mode 100644 Source/Glide64/ucode02.h create mode 100644 Source/Glide64/ucode03.h create mode 100644 Source/Glide64/ucode04.h create mode 100644 Source/Glide64/ucode05.h create mode 100644 Source/Glide64/ucode06.h create mode 100644 Source/Glide64/ucode07.h create mode 100644 Source/Glide64/ucode08.h create mode 100644 Source/Glide64/ucode09.h create mode 100644 Source/Glide64/ucode09rdp.h create mode 100644 Source/Glide64/ucodeFB.h create mode 100644 Source/Glide64/usa.xpm diff --git a/Source/Glide64/3dmath.cpp b/Source/Glide64/3dmath.cpp new file mode 100644 index 000000000..79e1fb985 --- /dev/null +++ b/Source/Glide64/3dmath.cpp @@ -0,0 +1,269 @@ +/* +* Glide64 - Glide video plugin for Nintendo 64 emulators. +* Copyright (c) 2002 Dave2001 +* Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski +* +* 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 +* 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 +*/ + +//**************************************************************** +// +// Glide64 - Glide Plugin for Nintendo 64 emulators +// Project started on December 29th, 2001 +// +// Authors: +// Dave2001, original author, founded the project in 2001, left it in 2002 +// Gugaman, joined the project in 2002, left it in 2002 +// Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002 +// Hiroshi 'KoolSmoky' Morii, joined the project in 2007 +// +//**************************************************************** +// +// To modify Glide64: +// * Write your name and (optional)email, commented by your work, so I know who did it, and so that you can find which parts you modified when it comes time to send it to me. +// * Do NOT send me the whole project or file that you modified. Take out your modified code sections, and tell me where to put them. If people sent the whole thing, I would have many different versions, but no idea how to combine them all. +// +//**************************************************************** + +#include "Gfx #1.3.h" +#include "3dmath.h" + +void calc_light (VERTEX *v) +{ + float light_intensity = 0.0f; + register float color[3] = {rdp.light[rdp.num_lights].r, rdp.light[rdp.num_lights].g, rdp.light[rdp.num_lights].b}; + for (wxUint32 l=0; lvec); + + if (light_intensity > 0.0f) + { + color[0] += rdp.light[l].r * light_intensity; + color[1] += rdp.light[l].g * light_intensity; + color[2] += rdp.light[l].b * light_intensity; + } + } + + if (color[0] > 1.0f) color[0] = 1.0f; + if (color[1] > 1.0f) color[1] = 1.0f; + if (color[2] > 1.0f) color[2] = 1.0f; + + v->r = (wxUint8)(color[0]*255.0f); + v->g = (wxUint8)(color[1]*255.0f); + v->b = (wxUint8)(color[2]*255.0f); +} + +//* +void calc_linear (VERTEX *v) +{ + if (settings.force_calc_sphere) + { + calc_sphere(v); + return; + } + DECLAREALIGN16VAR(vec[3]); + + TransformVector (v->vec, vec, rdp.model); + // TransformVector (v->vec, vec, rdp.combined); + NormalizeVector (vec); + float x, y; + if (!rdp.use_lookat) + { + x = vec[0]; + y = vec[1]; + } + else + { + x = DotProduct (rdp.lookat[0], vec); + y = DotProduct (rdp.lookat[1], vec); + } + + if (x > 1.0f) + x = 1.0f; + else if (x < -1.0f) + x = -1.0f; + if (y > 1.0f) + y = 1.0f; + else if (y < -1.0f) + y = -1.0f; + + if (rdp.cur_cache[0]) + { + // scale >> 6 is size to map to + v->ou = (acosf(x)/3.141592654f) * (rdp.tiles[rdp.cur_tile].org_s_scale >> 6); + v->ov = (acosf(y)/3.141592654f) * (rdp.tiles[rdp.cur_tile].org_t_scale >> 6); + } + v->uv_scaled = 1; +#ifdef EXTREME_LOGGING + FRDP ("calc linear u: %f, v: %f\n", v->ou, v->ov); +#endif +} + +void calc_sphere (VERTEX *v) +{ +// LRDP("calc_sphere\n"); + DECLAREALIGN16VAR(vec[3]); + int s_scale, t_scale; + if (settings.hacks&hack_Chopper) + { + s_scale = min(rdp.tiles[rdp.cur_tile].org_s_scale >> 6, rdp.tiles[rdp.cur_tile].lr_s); + t_scale = min(rdp.tiles[rdp.cur_tile].org_t_scale >> 6, rdp.tiles[rdp.cur_tile].lr_t); + } + else + { + s_scale = rdp.tiles[rdp.cur_tile].org_s_scale >> 6; + t_scale = rdp.tiles[rdp.cur_tile].org_t_scale >> 6; + } + TransformVector (v->vec, vec, rdp.model); + // TransformVector (v->vec, vec, rdp.combined); + NormalizeVector (vec); + float x, y; + if (!rdp.use_lookat) + { + x = vec[0]; + y = vec[1]; + } + else + { + x = DotProduct (rdp.lookat[0], vec); + y = DotProduct (rdp.lookat[1], vec); + } + v->ou = (x * 0.5f + 0.5f) * s_scale; + v->ov = (y * 0.5f + 0.5f) * t_scale; + v->uv_scaled = 1; +#ifdef EXTREME_LOGGING + FRDP ("calc sphere u: %f, v: %f\n", v->ou, v->ov); +#endif +} + +float DotProductC(register float *v1, register float *v2) +{ + register float result; + result = v1[0]*v2[0] + v1[1]*v2[1] + v1[2]*v2[2]; + return(result); +} + +void NormalizeVectorC(float *v) +{ + register float len; + len = sqrtf(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]); + if (len > 0.0f) + { + v[0] /= len; + v[1] /= len; + v[2] /= len; + } +} + +void TransformVectorC(float *src, float *dst, float mat[4][4]) +{ + dst[0] = mat[0][0]*src[0] + mat[1][0]*src[1] + mat[2][0]*src[2]; + dst[1] = mat[0][1]*src[0] + mat[1][1]*src[1] + mat[2][1]*src[2]; + dst[2] = mat[0][2]*src[0] + mat[1][2]*src[1] + mat[2][2]*src[2]; +} + +void InverseTransformVectorC (float *src, float *dst, float mat[4][4]) +{ + dst[0] = mat[0][0]*src[0] + mat[0][1]*src[1] + mat[0][2]*src[2]; + dst[1] = mat[1][0]*src[0] + mat[1][1]*src[1] + mat[1][2]*src[2]; + dst[2] = mat[2][0]*src[0] + mat[2][1]*src[1] + mat[2][2]*src[2]; +} + +void MulMatricesC(float m1[4][4],float m2[4][4],float r[4][4]) +{ + for (int i=0; i<4; i++) + { + for (int j=0; j<4; j++) + { + r[i][j] = m1[i][0] * m2[0][j] + + m1[i][1] * m2[1][j] + + m1[i][2] * m2[2][j] + + m1[i][3] * m2[3][j]; + } + } +} + +// 2008.03.29 H.Morii - added SSE 3DNOW! 3x3 1x3 matrix multiplication +// and 3DNOW! 4x4 4x4 matrix multiplication +MULMATRIX MulMatrices = MulMatricesC; +TRANSFORMVECTOR TransformVector = TransformVectorC; +TRANSFORMVECTOR InverseTransformVector = InverseTransformVectorC; +DOTPRODUCT DotProduct = DotProductC; +NORMALIZEVECTOR NormalizeVector = NormalizeVectorC; + +extern "C" void TransformVectorSSE(float *src, float *dst, float mat[4][4]); +extern "C" void TransformVector3DNOW(float *src, float *dst, float mat[4][4]); +extern "C" void InverseTransformVector3DNOW(float *src, float *dst, float mat[4][4]); +extern "C" void MulMatricesSSE(float m1[4][4],float m2[4][4],float r[4][4]); +extern "C" void MulMatrices3DNOW(float m1[4][4],float m2[4][4],float r[4][4]); +extern "C" float DotProductSSE3(register float *v1, register float *v2); +extern "C" float DotProduct3DNOW(register float *v1, register float *v2); +extern "C" void NormalizeVectorSSE(float *v); +extern "C" void NormalizeVector3DNOW(float *v); + +extern "C" void DetectSIMD(int function, int * iedx, int * iecx); + +void math_init() +{ +#ifndef _DEBUG + int iecx = 0, iedx = 0; + + GLIDE64_TRY + { + DetectSIMD(0x0000001, &iedx, &iecx); + } + GLIDE64_CATCH + { + return; + } + if (iedx & 0x2000000) //SSE + { + MulMatrices = MulMatricesSSE; + TransformVector = TransformVectorSSE; + //InverseTransformVector = InverseTransformVectorSSE; + //NormalizeVector = NormalizeVectorSSE; /* not ready yet */ + LOG("SSE detected.\n"); + } + if (iedx & 0x4000000) // SSE2 + { + LOG("SSE2 detected.\n"); + } + if (iecx & 0x1) // SSE3 + { + //DotProduct = DotProductSSE3; /* not ready yet */ + LOG("SSE3 detected.\n"); + } + // the 3dnow version is faster than sse + iecx = 0; + iedx = 0; + GLIDE64_TRY + { + DetectSIMD(0x80000001, &iedx, &iecx); + } + GLIDE64_CATCH + { + return; + } + if (iedx & 0x80000000) //3DNow! + { + MulMatrices = MulMatrices3DNOW; + TransformVector = TransformVector3DNOW; + InverseTransformVector = InverseTransformVector3DNOW; + //DotProduct = DotProduct3DNOW; //not ready yet + NormalizeVector = NormalizeVector3DNOW; // not ready yet + LOG("3DNOW! detected.\n"); + } +#endif //_DEBUG +} diff --git a/Source/Glide64/3dmath.h b/Source/Glide64/3dmath.h new file mode 100644 index 000000000..502bd5a99 --- /dev/null +++ b/Source/Glide64/3dmath.h @@ -0,0 +1,54 @@ +/* +* Glide64 - Glide video plugin for Nintendo 64 emulators. +* Copyright (c) 2002 Dave2001 +* Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski +* +* 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 +* 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 +*/ + +//**************************************************************** +// +// Glide64 - Glide Plugin for Nintendo 64 emulators +// Project started on December 29th, 2001 +// +// Authors: +// Dave2001, original author, founded the project in 2001, left it in 2002 +// Gugaman, joined the project in 2002, left it in 2002 +// Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002 +// Hiroshi 'KoolSmoky' Morii, joined the project in 2007 +// +//**************************************************************** +// +// To modify Glide64: +// * Write your name and (optional)email, commented by your work, so I know who did it, and so that you can find which parts you modified when it comes time to send it to me. +// * Do NOT send me the whole project or file that you modified. Take out your modified code sections, and tell me where to put them. If people sent the whole thing, I would have many different versions, but no idea how to combine them all. +// +//**************************************************************** + +void calc_light (VERTEX *v); +void calc_linear (VERTEX *v); +void calc_sphere (VERTEX *v); + +void math_init(); + +typedef void (*MULMATRIX)(float m1[4][4],float m2[4][4],float r[4][4]); +extern MULMATRIX MulMatrices; +typedef void (*TRANSFORMVECTOR)(float *src,float *dst,float mat[4][4]); +extern TRANSFORMVECTOR TransformVector; +extern TRANSFORMVECTOR InverseTransformVector; +typedef float (*DOTPRODUCT)(register float *v1, register float *v2); +extern DOTPRODUCT DotProduct; +typedef void (*NORMALIZEVECTOR)(float *v); +extern NORMALIZEVECTOR NormalizeVector; diff --git a/Source/Glide64/3dmathSIMD.asm b/Source/Glide64/3dmathSIMD.asm new file mode 100644 index 000000000..31fefde62 --- /dev/null +++ b/Source/Glide64/3dmathSIMD.asm @@ -0,0 +1,497 @@ +;/* +;* Glide64 - Glide video plugin for Nintendo 64 emulators. +;* +;* 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 +;* 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 +;*/ +; +;**************************************************************** +; +; Glide64 - Glide Plugin for Nintendo 64 emulators +; Project started on December 29th, 2001 +; +; Authors: +; Dave2001, original author, founded the project in 2001, left it in 2002 +; Gugaman, joined the project in 2002, left it in 2002 +; Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002 +; Hiroshi 'KoolSmoky' Morii, joined the project in 2007 +; +;**************************************************************** +; +; To modify Glide64: +; * Write your name and (optional)email, commented by your work, so I know who did it, and so that you can find which parts you modified when it comes time to send it to me. +; * Do NOT send me the whole project or file that you modified. Take out your modified code sections, and tell me where to put them. If people sent the whole thing, I would have many different versions, but no idea how to combine them all. +; +;**************************************************************** + +%include "inc/c32.mac" + +segment .text + +proc DetectSIMD + %$func arg + %$iedx arg + %$iecx arg + mov eax,[ebp + %$func] + cpuid + mov eax,[ebp + %$iedx] + mov [eax],edx + mov eax,[ebp + %$iecx] + mov [eax],ecx +endproc ;DetectSIMD + +;**************************************************************** +; +; ******** SSE ******** +; +;**************************************************************** + +proc TransformVectorSSE +CPU P3 + %$src arg ; float *src + %$dst arg ; float *dst + %$mat arg ; float mat[4][4] + + mov ecx,[ebp + %$src] + mov eax,[ebp + %$dst] + mov edx,[ebp + %$mat] + + movss xmm0,[ecx] ; 0 0 0 src[0] + movss xmm5,[edx] ; 0 0 0 mat[0][0] + movhps xmm5,[edx+4] ; mat[0][2] mat[0][1] 0 mat[0][0] + shufps xmm0,xmm0, 0 ; src[0] src[0] src[0] src[0] + movss xmm1,[ecx+4] ; 0 0 0 src[1] + movss xmm3,[edx+16] ; 0 0 0 mat[1][0] + movhps xmm3,[edx+20] ; mat[1][2] mat[1][1] 0 mat[1][0] + shufps xmm1,xmm1, 0 ; src[1] src[1] src[1] src[1] + mulps xmm0,xmm5 ; mat[0][2]*src[0] mat[0][1]*src[0] 0 mat[0][0]*src[0] + mulps xmm1,xmm3 ; mat[1][2]*src[1] mat[1][1]*src[1] 0 mat[1][0]*src[1] + movss xmm2,[ecx+8] ; 0 0 0 src[2] + shufps xmm2,xmm2, 0 ; src[2] src[2] src[2] src[2] + movss xmm4,[edx+32] ; 0 0 0 mat[2][0] + movhps xmm4,[edx+36] ; mat[2][2] mat[2][1] 0 mat[2][0] + addps xmm0,xmm1 ; mat[0][2]*src[0]+mat[1][2]*src[1] mat[0][1]*src[0]+mat[1][1]*src[1] 0 mat[0][0]*src[0]+mat[1][0]*src[1] + mulps xmm2,xmm4 ; mat[2][2]*src[2] mat[2][1]*src[2] 0 mat[2][0]*src[2] + addps xmm0,xmm2 ; mat[0][2]*src[0]+mat[1][2]*src[1]+mat[2][2]*src[2] mat[0][1]*src[0]+mat[1][1]*src[1]+mat[2][1]*src[2] 0 mat[0][0]*src[0]+mat[1][0]*src[1]+mat[2][0]*src[2] + movss [eax],xmm0 ; mat[0][0]*src[0]+mat[1][0]*src[1]+mat[2][0]*src[2] + movhps [eax+4],xmm0 ; mat[0][2]*src[0]+mat[1][2]*src[1]+mat[2][2]*src[2] mat[0][1]*src[0]+mat[1][1]*src[1]+mat[2][1]*src[2] + +endproc ;TransformVectorSSE + +proc MulMatricesSSE +CPU P3 + %$m1 arg ; float m1[4][4] + %$m2 arg ; float m2[4][4] + %$r arg ; float r[4][4] + + mov eax,[ebp + %$r] + mov ecx,[ebp + %$m1] + mov edx,[ebp + %$m2] + + movaps xmm0,[edx] + movaps xmm1,[edx+16] + movaps xmm2,[edx+32] + movaps xmm3,[edx+48] + + ; r[0][0],r[0][1],r[0][2],r[0][3] + + movaps xmm4,[ecx] + movaps xmm5,xmm4 + movaps xmm6,xmm4 + movaps xmm7,xmm4 + + shufps xmm4,xmm4,00000000b + shufps xmm5,xmm5,01010101b + shufps xmm6,xmm6,10101010b + shufps xmm7,xmm7,11111111b + + mulps xmm4,xmm0 + mulps xmm5,xmm1 + mulps xmm6,xmm2 + mulps xmm7,xmm3 + + addps xmm4,xmm5 + addps xmm4,xmm6 + addps xmm4,xmm7 + + movaps [eax],xmm4 + + ; r[1][0],r[1][1],r[1][2],r[1][3] + + movaps xmm4,[ecx+16] + movaps xmm5,xmm4 + movaps xmm6,xmm4 + movaps xmm7,xmm4 + + shufps xmm4,xmm4,00000000b + shufps xmm5,xmm5,01010101b + shufps xmm6,xmm6,10101010b + shufps xmm7,xmm7,11111111b + + mulps xmm4,xmm0 + mulps xmm5,xmm1 + mulps xmm6,xmm2 + mulps xmm7,xmm3 + + addps xmm4,xmm5 + addps xmm4,xmm6 + addps xmm4,xmm7 + + movaps [eax+16],xmm4 + + + ; r[2][0],r[2][1],r[2][2],r[2][3] + + movaps xmm4,[ecx+32] + movaps xmm5,xmm4 + movaps xmm6,xmm4 + movaps xmm7,xmm4 + + shufps xmm4,xmm4,00000000b + shufps xmm5,xmm5,01010101b + shufps xmm6,xmm6,10101010b + shufps xmm7,xmm7,11111111b + + mulps xmm4,xmm0 + mulps xmm5,xmm1 + mulps xmm6,xmm2 + mulps xmm7,xmm3 + + addps xmm4,xmm5 + addps xmm4,xmm6 + addps xmm4,xmm7 + + movaps [eax+32],xmm4 + + ; r[3][0],r[3][1],r[3][2],r[3][3] + + movaps xmm4,[ecx+48] + movaps xmm5,xmm4 + movaps xmm6,xmm4 + movaps xmm7,xmm4 + + shufps xmm4,xmm4,00000000b + shufps xmm5,xmm5,01010101b + shufps xmm6,xmm6,10101010b + shufps xmm7,xmm7,11111111b + + mulps xmm4,xmm0 + mulps xmm5,xmm1 + mulps xmm6,xmm2 + mulps xmm7,xmm3 + + addps xmm4,xmm5 + addps xmm4,xmm6 + addps xmm4,xmm7 + + movaps [eax+48],xmm4 + +endproc ;MulMatricesSSE + +proc NormalizeVectorSSE +CPU P3 + %$v arg + + mov edx, [ebp + %$v] + movaps xmm0, [edx] ; x y z 0 + movaps xmm2, xmm0 ; x y z 0 + mulps xmm0, xmm0 ; x*x y*y z*z 0 + movaps xmm1, xmm0 ; x*x y*y z*z 0 + shufps xmm0, xmm1, 0x4e ; z*z 0 x*x y*y + addps xmm0, xmm1 ; x*x+z*z y*y z*z+x*x y*y + movaps xmm1, xmm0 ; x*x+z*z y*y z*z+x*x y*y + shufps xmm1, xmm1, 0x11 ; y*y z*z+x*x y*y z*z+x*x + addps xmm0, xmm1 ; x*x+z*z+y*y + rsqrtps xmm0, xmm0 ; 1.0/sqrt(x*x+z*z+y*y) + mulps xmm2, xmm0 ; x/sqrt(x*x+z*z+y*y) y/sqrt(x*x+z*z+y*y) z/sqrt(x*x+z*z+y*y) 0 + movaps [edx], xmm2 + +endproc ;NormalizeVectorSSE + +;**************************************************************** +; +; ******** SSE3 ******** +; +;**************************************************************** + +proc DotProductSSE3 +CPU PRESCOTT + %$v1 arg + %$v2 arg + + mov eax,[ebp + %$v1] + mov edx,[ebp + %$v2] + movaps xmm0, [eax] + mulps xmm0, [edx] + haddps xmm0, xmm0 + haddps xmm0, xmm0 +; movss eax, xmm0 + +endproc ;DotProductSSE3 + +;**************************************************************** +; +; ******** 3DNOW ******** +; +;**************************************************************** + +proc TransformVector3DNOW +CPU 586 + %$src arg ; float *src + %$dst arg ; float *dst + %$mat arg ; float mat[4][4] + + femms + mov ecx,[ebp + %$src] + mov eax,[ebp + %$dst] + mov edx,[ebp + %$mat] + movq mm0,[ecx] ; src[1] src[0] + movd mm2,[ecx+8] ; 0 src[2] + movq mm1,mm0 ; src[1] src[0] + punpckldq mm0,mm0 ; src[0] src[0] + punpckhdq mm1,mm1 ; src[1] src[1] + punpckldq mm2,mm2 ; src[2] src[2] + movq mm3,mm0 ; src[0] src[0] + movq mm4,mm1 ; src[1] src[1] + movq mm5,mm2 ; src[2] src[2] + pfmul mm0,[edx] ; src[0]*mat[0][1] src[0]*mat[0][0] + pfmul mm3,[edx+8] ; 0 src[0]*mat[0][2] + pfmul mm1,[edx+16] ; src[1]*mat[1][1] src[1]*mat[1][0] + pfmul mm4,[edx+24] ; 0 src[1]*mat[1][2] + pfmul mm2,[edx+32] ; src[2]*mat[2][1] src[2]*mat[2][0] + pfmul mm5,[edx+40] ; 0 src[2]*mat[2][2] + pfadd mm0,mm1 ; src[0]*mat[0][1]+src[1]*mat[1][1] src[0]*mat[0][0]+src[1]*mat[1][0] + pfadd mm3,mm4 ; 0 src[0]*mat[0][2]+src[1]*mat[1][2] + pfadd mm0,mm2 ; src[0]*mat[0][1]+src[1]*mat[1][1]+src[2]*mat[2][1] src[0]*mat[0][0]+src[1]*mat[1][0]+src[2]*mat[2][0] + pfadd mm3,mm5 ; 0 src[0]*mat[0][2]+src[1]*mat[1][2]+src[2]*mat[2][2] + movq [eax],mm0 ; mat[0][1]*src[0]+mat[1][1]*src[1]+mat[2][1]*src[2] mat[0][0]*src[0]+mat[1][0]*src[1]+mat[2][0]*src[2] + movd [eax+8],mm3 ; mat[0][2]*src[0]+mat[1][2]*src[1]+mat[2][2]*src[2] + femms + +endproc ;TransformVector3DNOW + +proc InverseTransformVector3DNOW +CPU 586 + %$src arg ; float *src + %$dst arg ; float *dst + %$mat arg ; float mat[4][4] + + femms + mov ecx,[ebp + %$src] + mov eax,[ebp + %$dst] + mov edx,[ebp + %$mat] + movq mm0,[ecx] ; src[1] src[0] + movd mm4,[ecx+8] ; 0 src[2] + movq mm1,mm0 ; src[1] src[0] + pfmul mm0,[edx] ; src[1]*mat[0][1] src[0]*mat[0][0] + movq mm5,mm4 ; 0 src[2] + pfmul mm4,[edx+8] ; 0 src[2]*mat[0][2] + movq mm2,mm1 ; src[1] src[0] + pfmul mm1,[edx+16] ; src[1]*mat[1][1] src[0]*mat[1][0] + movq mm6,mm5 ; 0 src[2] + pfmul mm5,[edx+24] ; 0 src[2]*mat[1][2] + movq mm3,mm2 ; src[1] src[0] + pfmul mm2,[edx+32] ; src[1]*mat[2][1] src[0]*mat[2][0] + movq mm7,mm6 ; 0 src[2] + pfmul mm6,[edx+40] ; 0 src[2]*mat[2][2] + pfacc mm0,mm4 ; src[2]*mat[0][2] src[1]*mat[0][1]+src[0]*mat[0][0] + pfacc mm1,mm5 ; src[2]*mat[1][2] src[1]*mat[1][1]+src[0]*mat[1][0] + pfacc mm2,mm6 ; src[2]*mat[2][2] src[1]*mat[2][1]+src[0]*mat[2][0] + pfacc mm0,mm1 ; src[2]*mat[1][2]+src[1]*mat[1][1]+src[0]*mat[1][0] src[2]*mat[0][2]+src[1]*mat[0][1]+src[0]*mat[0][0] + pfacc mm2,mm3 ; 0 src[2]*mat[2][2]+src[1]*mat[2][1]+src[0]*mat[2][0] + movq [eax],mm0 ; mat[1][0]*src[0]+mat[1][1]*src[1]+mat[1][2]*src[2] mat[0][0]*src[0]+mat[0][1]*src[1]+mat[0][2]*src[2] + movd [eax+8],mm2 ; mat[2][0]*src[0]+mat[2][1]*src[1]+mat[2][2]*src[2] + femms + +endproc ;InverseTransformVector3DNOW + +proc MulMatrices3DNOW +CPU 586 + %$m1 arg ; float m1[4][4] + %$m2 arg ; float m2[4][4] + %$r arg ; float r[4][4] + + femms + mov ecx,[ebp + %$m1] + mov eax,[ebp + %$r] + mov edx,[ebp + %$m2] + + movq mm0,[ecx] + movq mm1,[ecx+8] + movq mm4,[edx] + punpckhdq mm2,mm0 + movq mm5,[edx+16] + punpckhdq mm3,mm1 + movq mm6,[edx+32] + punpckldq mm0,mm0 + punpckldq mm1,mm1 + pfmul mm4,mm0 + punpckhdq mm2,mm2 + pfmul mm0,[edx+8] + movq mm7,[edx+48] + pfmul mm5,mm2 + punpckhdq mm3,mm3 + pfmul mm2,[edx+24] + pfmul mm6,mm1 + pfadd mm5,mm4 + pfmul mm1,[edx+40] + pfadd mm2,mm0 + pfmul mm7,mm3 + pfadd mm6,mm5 + pfmul mm3,[edx+56] + pfadd mm2,mm1 + pfadd mm7,mm6 + movq mm0,[ecx+16] + pfadd mm3,mm2 + movq mm1,[ecx+24] + movq [eax],mm7 + movq mm4,[edx] + movq [eax+8],mm3 + + punpckhdq mm2,mm0 + movq mm5,[edx+16] + punpckhdq mm3,mm1 + movq mm6,[edx+32] + punpckldq mm0,mm0 + punpckldq mm1,mm1 + pfmul mm4,mm0 + punpckhdq mm2,mm2 + pfmul mm0,[edx+8] + movq mm7,[edx+48] + pfmul mm5,mm2 + punpckhdq mm3,mm3 + pfmul mm2,[edx+24] + pfmul mm6,mm1 + pfadd mm5,mm4 + pfmul mm1,[edx+40] + pfadd mm2,mm0 + pfmul mm7,mm3 + pfadd mm6,mm5 + pfmul mm3,[edx+56] + pfadd mm2,mm1 + pfadd mm7,mm6 + movq mm0,[ecx+32] + pfadd mm3,mm2 + movq mm1,[ecx+40] + movq [eax+16],mm7 + movq mm4,[edx] + movq [eax+24],mm3 + + punpckhdq mm2,mm0 + movq mm5,[edx+16] + punpckhdq mm3,mm1 + movq mm6,[edx+32] + punpckldq mm0,mm0 + punpckldq mm1,mm1 + pfmul mm4,mm0 + punpckhdq mm2,mm2 + pfmul mm0,[edx+8] + movq mm7,[edx+48] + pfmul mm5,mm2 + punpckhdq mm3,mm3 + pfmul mm2,[edx+24] + pfmul mm6,mm1 + pfadd mm5,mm4 + pfmul mm1,[edx+40] + pfadd mm2,mm0 + pfmul mm7,mm3 + pfadd mm6,mm5 + pfmul mm3,[edx+56] + pfadd mm2,mm1 + pfadd mm7,mm6 + movq mm0,[ecx+48] + pfadd mm3,mm2 + movq mm1,[ecx+56] + movq [eax+32],mm7 + movq mm4,[edx] + movq [eax+40],mm3 + + punpckhdq mm2,mm0 + movq mm5,[edx+16] + punpckhdq mm3,mm1 + movq mm6,[edx+32] + punpckldq mm0,mm0 + punpckldq mm1,mm1 + pfmul mm4,mm0 + punpckhdq mm2,mm2 + pfmul mm0,[edx+8] + movq mm7,[edx+48] + pfmul mm5,mm2 + punpckhdq mm3,mm3 + pfmul mm2,[edx+24] + pfmul mm6,mm1 + pfadd mm5,mm4 + pfmul mm1,[edx+40] + pfadd mm2,mm0 + pfmul mm7,mm3 + pfadd mm6,mm5 + pfmul mm3,[edx+56] + pfadd mm2,mm1 + pfadd mm7,mm6 + pfadd mm3,mm2 + movq [eax+48],mm7 + movq [eax+56],mm3 + femms + +endproc ;MulMatrices3DNOW + +proc DotProduct3DNOW +CPU 586 + %$v1 arg + %$v2 arg + + femms + mov edx,[ebp + %$v1] + mov eax,[ebp + %$v2] + movq mm0,[edx] + movq mm3,[eax] + pfmul mm0,mm3 + movq mm2,[edx+8] + movq mm1,[eax+8] + pfacc mm0,mm0 + pfmul mm1,mm2 + pfadd mm0,mm1 + movd eax,mm0 + femms + +endproc ;DotProduct3DNOW + +proc NormalizeVector3DNOW +CPU 586 + %$v arg + + femms + mov edx,[ebp + %$v] + movq mm0,[edx] + movq mm3,[edx+8] + movq mm1,mm0 + movq mm2,mm3 + pfmul mm0,mm0 + pfmul mm3,mm3 + pfacc mm0,mm0 + pfadd mm0,mm3 + ;movq mm4,mm0 ; prepare for 24bit precision + ;punpckldq mm4,mm4 ; prepare for 24bit precision + pfrsqrt mm0,mm0 ; 15bit precision 1/sqrtf(v) + ;movq mm3,mm0 + ;pfmul mm0,mm0 + ;pfrsqit1 mm0,mm4 + ;pfrcpit2 mm0,mm3 ; 24bit precision 1/sqrtf(v) + pfmul mm1,mm0 + pfmul mm2,mm0 + movq [edx],mm1 + movq [edx+8],mm2 + femms + +endproc ;NormalizeVector3DNOW diff --git a/Source/Glide64/CB/Glide64.cbp b/Source/Glide64/CB/Glide64.cbp new file mode 100644 index 000000000..9ad22babf --- /dev/null +++ b/Source/Glide64/CB/Glide64.cbp @@ -0,0 +1,198 @@ + + + + + + diff --git a/Source/Glide64/CRC.cpp b/Source/Glide64/CRC.cpp new file mode 100644 index 000000000..1d95df436 --- /dev/null +++ b/Source/Glide64/CRC.cpp @@ -0,0 +1,142 @@ +/* +* Glide64 - Glide video plugin for Nintendo 64 emulators. +* Copyright (c) 2002 Dave2001 +* Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski +* +* 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 +* 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 +*/ + +//**************************************************************** +// +// Glide64 - Glide Plugin for Nintendo 64 emulators +// Project started on December 29th, 2001 +// +// Authors: +// Dave2001, original author, founded the project in 2001, left it in 2002 +// Gugaman, joined the project in 2002, left it in 2002 +// Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002 +// Hiroshi 'KoolSmoky' Morii, joined the project in 2007 +// +//**************************************************************** +// +// To modify Glide64: +// * Write your name and (optional)email, commented by your work, so I know who did it, and so that you can find which parts you modified when it comes time to send it to me. +// * Do NOT send me the whole project or file that you modified. Take out your modified code sections, and tell me where to put them. If people sent the whole thing, I would have many different versions, but no idea how to combine them all. +// +//**************************************************************** +// +// CRC32 calculation functions +// +// Created by Gonetz, 2004 +// +//**************************************************************** +//* +#define CRC32_POLYNOMIAL 0x04C11DB7 + +unsigned int CRCTable[ 256 ]; + +unsigned int Reflect( unsigned int ref, char ch ) +{ + unsigned int value = 0; + + // Swap bit 0 for bit 7 + // bit 1 for bit 6, etc. + for (char i = 1; i < (ch + 1); i++) + { + if(ref & 1) + value |= 1 << (ch - i); + ref >>= 1; + } + return value; +} + +void CRC_BuildTable() +{ + unsigned int crc; + + for (unsigned i = 0; i <= 255; i++) + { + crc = Reflect( i, 8 ) << 24; + for (unsigned j = 0; j < 8; j++) + crc = (crc << 1) ^ (crc & (1 << 31) ? CRC32_POLYNOMIAL : 0); + + CRCTable[i] = Reflect( crc, 32 ); + } +} +//*/ +//* +unsigned int CRC32( unsigned int crc, void *buffer, unsigned int count ) +{ + unsigned int orig = crc; + unsigned char * p = reinterpret_cast(buffer); + while (count--) + crc = (crc >> 8) ^ CRCTable[(crc & 0xFF) ^ *p++]; + return crc ^ orig; +} +//*/ + +/* +wxUint32 CRC_Calculate( wxUint32 crc, void *buffer, wxUint32 count ) +{ + wxUint32 Crc32=crc; + __asm { + mov esi, buffer + mov ecx, count + mov edx, crc + xor eax, eax + +loop1: + inc esi + mov al, dl + xor al, byte ptr [esi] + shr edx, 8 + mov ebx, [CRCTable+eax*4] + xor edx, ebx + + loop loop1 + + xor Crc32, edx + } + return Crc32; +} +*/ + +/* +unsigned int CRC_Calculate( unsigned int crc, void *buffer, unsigned int count ) +{ + unsigned int Crc32=crc; + __asm { + mov esi, buffer + mov edx, count + add edx, esi + mov ecx, crc + +loop1: + mov bl, byte ptr [esi] + movzx eax, cl + inc esi + xor al, bl + shr ecx, 8 + mov ebx, [CRCTable+eax*4] + xor ecx, ebx + + cmp edx, esi + jne loop1 + + xor Crc32, ecx + } + return Crc32; +} +//*/ diff --git a/Source/Glide64/CRC.h b/Source/Glide64/CRC.h new file mode 100644 index 000000000..4daa929ca --- /dev/null +++ b/Source/Glide64/CRC.h @@ -0,0 +1,48 @@ +/* +* Glide64 - Glide video plugin for Nintendo 64 emulators. +* Copyright (c) 2002 Dave2001 +* Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski +* +* 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 +* 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 +*/ + +//**************************************************************** +// +// Glide64 - Glide Plugin for Nintendo 64 emulators +// Project started on December 29th, 2001 +// +// Authors: +// Dave2001, original author, founded the project in 2001, left it in 2002 +// Gugaman, joined the project in 2002, left it in 2002 +// Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002 +// Hiroshi 'KoolSmoky' Morii, joined the project in 2007 +// +//**************************************************************** +// +// To modify Glide64: +// * Write your name and (optional)email, commented by your work, so I know who did it, and so that you can find which parts you modified when it comes time to send it to me. +// * Do NOT send me the whole project or file that you modified. Take out your modified code sections, and tell me where to put them. If people sent the whole thing, I would have many different versions, but no idea how to combine them all. +// +//**************************************************************** +// +// CRC32 calculation functions +// +// Created by Gonetz, 2004 +// +//**************************************************************** + +void CRC_BuildTable(); + +unsigned int CRC32( unsigned int crc, void *buffer, unsigned int count ); diff --git a/Source/Glide64/Combine.cpp b/Source/Glide64/Combine.cpp new file mode 100644 index 000000000..7bf6c617a --- /dev/null +++ b/Source/Glide64/Combine.cpp @@ -0,0 +1,16654 @@ +/* +* Glide64 - Glide video plugin for Nintendo 64 emulators. +* Copyright (c) 2002 Dave2001 +* Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski +* +* 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 +* 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 +*/ + +//**************************************************************** +// +// Glide64 - Glide Plugin for Nintendo 64 emulators +// Project started on December 29th, 2001 +// +// Authors: +// Dave2001, original author, founded the project in 2001, left it in 2002 +// Gugaman, joined the project in 2002, left it in 2002 +// Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002 +// Hiroshi 'KoolSmoky' Morii, joined the project in 2007 +// +//**************************************************************** +// +// To modify Glide64: +// * Write your name and (optional)email, commented by your work, so I know who did it, and so that you can find which parts you modified when it comes time to send it to me. +// * Do NOT send me the whole project or file that you modified. Take out your modified code sections, and tell me where to put them. If people sent the whole thing, I would have many different versions, but no idea how to combine them all. +// +//**************************************************************** + +#include "Gfx #1.3.h" +#include "Util.h" +#include "Combine.h" + +#define FASTSEARCH // Enable fast combine mode searching algorithm + +float percent_org, percent, r, g, b; +wxUint32 lod_frac; + +wxUint32 cc_lookup[257]; +wxUint32 ac_lookup[257]; +COMBINE cmb; + +//**************************************************************** +// Macros +//**************************************************************** + +#define MOD_0(mode) cmb.mod_0 = mode +#define MOD_0_COL(color) cmb.modcolor_0 = color +#define MOD_0_COL1(color) cmb.modcolor1_0 = color +#define MOD_0_COL2(color) cmb.modcolor2_0 = color +#define MOD_0_FAC(factor) cmb.modfactor_0 = factor +#define MOD_1(mode) cmb.mod_1 = mode +#define MOD_1_COL(color) cmb.modcolor_1 = color +#define MOD_1_COL1(color) cmb.modcolor1_1 = color +#define MOD_1_COL2(color) cmb.modcolor2_1 = color +#define MOD_1_FAC(factor) cmb.modfactor_1 = factor + +#define A_BLEND(f1,f2) cmb.abf1=f1,cmb.abf2=f2 + +// To make a color or alpha combine +#define CCMB(fnc,fac,loc,oth) \ + cmb.c_fnc = fnc, \ + cmb.c_fac = fac, \ + cmb.c_loc = loc, \ + cmb.c_oth = oth +#define ACMB(fnc,fac,loc,oth) \ + cmb.a_fnc = fnc, \ + cmb.a_fac = fac, \ + cmb.a_loc = loc, \ + cmb.a_oth = oth +#define CCMBEXT(a,a_mode,b,b_mode,c,c_invert,d,d_invert) \ + cmb.c_ext_a = a, \ + cmb.c_ext_a_mode = a_mode, \ + cmb.c_ext_b = b, \ + cmb.c_ext_b_mode = b_mode, \ + cmb.c_ext_c = c, \ + cmb.c_ext_c_invert = c_invert, \ + cmb.c_ext_d= d, \ + cmb.c_ext_d_invert = d_invert, \ + cmb.cmb_ext_use |= COMBINE_EXT_COLOR +#define ACMBEXT(a,a_mode,b,b_mode,c,c_invert,d,d_invert) \ + cmb.a_ext_a = a, \ + cmb.a_ext_a_mode = a_mode, \ + cmb.a_ext_b = b, \ + cmb.a_ext_b_mode = b_mode, \ + cmb.a_ext_c = c, \ + cmb.a_ext_c_invert = c_invert, \ + cmb.a_ext_d= d, \ + cmb.a_ext_d_invert = d_invert, \ + cmb.cmb_ext_use |= COMBINE_EXT_ALPHA +#define T0CCMBEXT(a,a_mode,b,b_mode,c,c_invert,d,d_invert) \ + cmb.t0c_ext_a = a, \ + cmb.t0c_ext_a_mode = a_mode, \ + cmb.t0c_ext_b = b, \ + cmb.t0c_ext_b_mode = b_mode, \ + cmb.t0c_ext_c = c, \ + cmb.t0c_ext_c_invert = c_invert, \ + cmb.t0c_ext_d= d, \ + cmb.t0c_ext_d_invert = d_invert, \ + cmb.tex_cmb_ext_use |= TEX_COMBINE_EXT_COLOR +#define T0ACMBEXT(a,a_mode,b,b_mode,c,c_invert,d,d_invert) \ + cmb.t0a_ext_a = a, \ + cmb.t0a_ext_a_mode = a_mode, \ + cmb.t0a_ext_b = b, \ + cmb.t0a_ext_b_mode = b_mode, \ + cmb.t0a_ext_c = c, \ + cmb.t0a_ext_c_invert = c_invert, \ + cmb.t0a_ext_d= d, \ + cmb.t0a_ext_d_invert = d_invert, \ + cmb.tex_cmb_ext_use |= TEX_COMBINE_EXT_ALPHA +#define T1CCMBEXT(a,a_mode,b,b_mode,c,c_invert,d,d_invert) \ + cmb.t1c_ext_a = a, \ + cmb.t1c_ext_a_mode = a_mode, \ + cmb.t1c_ext_b = b, \ + cmb.t1c_ext_b_mode = b_mode, \ + cmb.t1c_ext_c = c, \ + cmb.t1c_ext_c_invert = c_invert, \ + cmb.t1c_ext_d= d, \ + cmb.t1c_ext_d_invert = d_invert, \ + cmb.tex_cmb_ext_use |= TEX_COMBINE_EXT_COLOR +#define T1ACMBEXT(a,a_mode,b,b_mode,c,c_invert,d,d_invert) \ + cmb.t1a_ext_a = a, \ + cmb.t1a_ext_a_mode = a_mode, \ + cmb.t1a_ext_b = b, \ + cmb.t1a_ext_b_mode = b_mode, \ + cmb.t1a_ext_c = c, \ + cmb.t1a_ext_c_invert = c_invert, \ + cmb.t1a_ext_d= d, \ + cmb.t1a_ext_d_invert = d_invert, \ + cmb.tex_cmb_ext_use |= TEX_COMBINE_EXT_ALPHA + +// To use textures +#define USE_T0() \ + rdp.best_tex = 0; \ + cmb.tex |= 1, \ + cmb.tmu0_func = GR_COMBINE_FUNCTION_LOCAL +#define USE_T1() \ + if (voodoo.num_tmu > 1) { \ + rdp.best_tex = 1; \ + cmb.tex |= 2, \ + cmb.tmu1_func = GR_COMBINE_FUNCTION_LOCAL, \ + cmb.tmu0_func = GR_COMBINE_FUNCTION_SCALE_OTHER, \ + cmb.tmu0_fac = GR_COMBINE_FACTOR_ONE; \ + } \ + else { \ + USE_T0(); \ +} +#define T0_ADD_T1() \ + rdp.best_tex = 0; \ + cmb.tex |= 3, \ + cmb.tmu1_func = GR_COMBINE_FUNCTION_LOCAL, \ + cmb.tmu0_func = GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, \ + cmb.tmu0_fac = GR_COMBINE_FACTOR_ONE +#define T0_MUL_T1() \ + rdp.best_tex = 0; \ + cmb.tex |= 3, \ + cmb.tmu1_func = GR_COMBINE_FUNCTION_LOCAL, \ + cmb.tmu0_func = GR_COMBINE_FUNCTION_SCALE_OTHER, \ + cmb.tmu0_fac = GR_COMBINE_FACTOR_LOCAL +#define T0_MUL_T1_ADD_T0() \ + rdp.best_tex = 0; \ + cmb.tex |= 3, \ + cmb.tmu1_func = GR_COMBINE_FUNCTION_LOCAL, \ + cmb.tmu0_func = GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, \ + cmb.tmu0_fac = GR_COMBINE_FACTOR_LOCAL +#define T0A_MUL_T1() \ + rdp.best_tex = 1; \ + cmb.tex |= 3, \ + cmb.tmu1_func = GR_COMBINE_FUNCTION_LOCAL, \ + cmb.tmu0_func = GR_COMBINE_FUNCTION_SCALE_OTHER, \ + cmb.tmu0_fac = GR_COMBINE_FACTOR_LOCAL_ALPHA +#define T0_MUL_T1A() \ + rdp.best_tex = 1; \ + cmb.tex |= 3, \ + cmb.tmu1_func = GR_COMBINE_FUNCTION_LOCAL_ALPHA, \ + cmb.tmu0_func = GR_COMBINE_FUNCTION_SCALE_OTHER, \ + cmb.tmu0_fac = GR_COMBINE_FACTOR_LOCAL +#define T0_INTER_T1_USING_FACTOR(factor) \ + if (factor == 0xFF) { \ + USE_T1(); \ + } \ + else if (factor == 0x00) { \ + USE_T0(); \ +}\ + else {\ + if (factor <= 0x80) rdp.best_tex = 0; \ + else rdp.best_tex = 1; \ + cmb.tex |= 3, \ + cmb.tmu1_func = GR_COMBINE_FUNCTION_LOCAL, \ + cmb.tmu0_func = GR_COMBINE_FUNCTION_BLEND, \ + cmb.tmu0_fac = GR_COMBINE_FACTOR_DETAIL_FACTOR, \ + percent = (float)factor / 255.0f, \ + cmb.dc0_detailmax = cmb.dc1_detailmax = percent; \ +} +#define T1_INTER_T0_USING_FACTOR(factor) /* inverse of above */\ + if (factor == 0xFF) { \ + USE_T0(); \ + } \ + else if (factor == 0x00) { \ + USE_T1(); \ +}\ + else {\ + if (factor <= 0x80) rdp.best_tex = 0; \ + else rdp.best_tex = 1; \ + cmb.tex |= 3, \ + cmb.tmu1_func = GR_COMBINE_FUNCTION_LOCAL, \ + cmb.tmu0_func = GR_COMBINE_FUNCTION_BLEND, \ + cmb.tmu0_fac = GR_COMBINE_FACTOR_DETAIL_FACTOR, \ + percent = (255 - factor) / 255.0f, \ + cmb.dc0_detailmax = cmb.dc1_detailmax = percent; \ +} +#define T0_INTER_T1_USING_T0() \ + rdp.best_tex = 0; \ + cmb.tex |= 3, \ + cmb.tmu1_func = GR_COMBINE_FUNCTION_LOCAL, \ + cmb.tmu0_func = GR_COMBINE_FUNCTION_BLEND, \ + cmb.tmu0_fac = GR_COMBINE_FACTOR_LOCAL +#define T1_INTER_T0_USING_T0() \ + rdp.best_tex = 0; \ + cmb.tex |= 3, \ + cmb.tmu1_func = GR_COMBINE_FUNCTION_LOCAL, \ + cmb.tmu0_func = GR_COMBINE_FUNCTION_BLEND, \ + cmb.tmu0_fac = GR_COMBINE_FACTOR_ONE_MINUS_LOCAL +#define T0_INTER_T1_USING_T1() \ + if (!cmb.combine_ext) { \ + T0_INTER_T1_USING_FACTOR(0x7F); \ + }\ + else {\ + rdp.best_tex = 0; \ + cmb.tex |= 3, \ + cmb.t1c_ext_a = GR_CMBX_LOCAL_TEXTURE_RGB, \ + cmb.t1c_ext_a_mode = GR_FUNC_MODE_ZERO, \ + cmb.t1c_ext_b = GR_CMBX_LOCAL_TEXTURE_RGB, \ + cmb.t1c_ext_b_mode = GR_FUNC_MODE_ZERO, \ + cmb.t1c_ext_c = GR_CMBX_ZERO, \ + cmb.t1c_ext_c_invert = 0, \ + cmb.t1c_ext_d= GR_CMBX_B, \ + cmb.t1c_ext_d_invert = 0, \ + cmb.t0c_ext_a = GR_CMBX_OTHER_TEXTURE_RGB, \ + cmb.t0c_ext_a_mode = GR_FUNC_MODE_X, \ + cmb.t0c_ext_b = GR_CMBX_LOCAL_TEXTURE_RGB, \ + cmb.t0c_ext_b_mode = GR_FUNC_MODE_NEGATIVE_X, \ + cmb.t0c_ext_c = GR_CMBX_OTHER_TEXTURE_RGB, \ + cmb.t0c_ext_c_invert = 0, \ + cmb.t0c_ext_d= GR_CMBX_B, \ + cmb.t0c_ext_d_invert = 0, \ + cmb.tex_cmb_ext_use |= TEX_COMBINE_EXT_COLOR; \ +} +#define T0_INTER_T1_USING_T1A() \ + rdp.best_tex = 0; \ + cmb.tex |= 3, \ + cmb.tmu1_func = GR_COMBINE_FUNCTION_LOCAL, \ + cmb.tmu0_func = GR_COMBINE_FUNCTION_BLEND, \ + cmb.tmu0_fac = GR_COMBINE_FACTOR_OTHER_ALPHA +#define T0_INTER_T1_USING_PRIM() \ + if (!cmb.combine_ext) { \ + T0_INTER_T1_USING_FACTOR ((rdp.prim_color&0xFF)); \ + }\ + else {\ + rdp.best_tex = 0; \ + cmb.tex |= 3, \ + cmb.t1c_ext_a = GR_CMBX_LOCAL_TEXTURE_RGB, \ + cmb.t1c_ext_a_mode = GR_FUNC_MODE_ZERO, \ + cmb.t1c_ext_b = GR_CMBX_LOCAL_TEXTURE_RGB, \ + cmb.t1c_ext_b_mode = GR_FUNC_MODE_ZERO, \ + cmb.t1c_ext_c = GR_CMBX_ZERO, \ + cmb.t1c_ext_c_invert = 0, \ + cmb.t1c_ext_d= GR_CMBX_B, \ + cmb.t1c_ext_d_invert = 0, \ + cmb.t0c_ext_a = GR_CMBX_OTHER_TEXTURE_RGB, \ + cmb.t0c_ext_a_mode = GR_FUNC_MODE_X, \ + cmb.t0c_ext_b = GR_CMBX_LOCAL_TEXTURE_RGB, \ + cmb.t0c_ext_b_mode = GR_FUNC_MODE_NEGATIVE_X, \ + cmb.t0c_ext_c = GR_CMBX_TMU_CCOLOR, \ + cmb.t0c_ext_c_invert = 0, \ + cmb.t0c_ext_d= GR_CMBX_B, \ + cmb.t0c_ext_d_invert = 0, \ + cmb.tex_ccolor = rdp.prim_color, \ + cmb.tex_cmb_ext_use |= TEX_COMBINE_EXT_COLOR; \ +} +#define T1_INTER_T0_USING_PRIM() /* inverse of above */\ + if (!cmb.combine_ext) { \ + T1_INTER_T0_USING_FACTOR ((rdp.prim_color&0xFF)); \ + }\ + else {\ + rdp.best_tex = 0; \ + cmb.tex |= 3, \ + cmb.t1c_ext_a = GR_CMBX_LOCAL_TEXTURE_RGB, \ + cmb.t1c_ext_a_mode = GR_FUNC_MODE_ZERO, \ + cmb.t1c_ext_b = GR_CMBX_LOCAL_TEXTURE_RGB, \ + cmb.t1c_ext_b_mode = GR_FUNC_MODE_ZERO, \ + cmb.t1c_ext_c = GR_CMBX_ZERO, \ + cmb.t1c_ext_c_invert = 0, \ + cmb.t1c_ext_d= GR_CMBX_B, \ + cmb.t1c_ext_d_invert = 0, \ + cmb.t0c_ext_a = GR_CMBX_LOCAL_TEXTURE_RGB, \ + cmb.t0c_ext_a_mode = GR_FUNC_MODE_X, \ + cmb.t0c_ext_b = GR_CMBX_OTHER_TEXTURE_RGB, \ + cmb.t0c_ext_b_mode = GR_FUNC_MODE_NEGATIVE_X, \ + cmb.t0c_ext_c = GR_CMBX_TMU_CCOLOR, \ + cmb.t0c_ext_c_invert = 0, \ + cmb.t0c_ext_d= GR_CMBX_B, \ + cmb.t0c_ext_d_invert = 0, \ + cmb.tex_ccolor = rdp.prim_color, \ + cmb.tex_cmb_ext_use |= TEX_COMBINE_EXT_COLOR; \ +} +#define T0_INTER_T1_USING_ENV() \ + if (!cmb.combine_ext) { \ + T0_INTER_T1_USING_FACTOR ((rdp.env_color&0xFF)); \ + }\ + else {\ + rdp.best_tex = 0; \ + cmb.tex |= 3, \ + cmb.t1c_ext_a = GR_CMBX_LOCAL_TEXTURE_RGB, \ + cmb.t1c_ext_a_mode = GR_FUNC_MODE_ZERO, \ + cmb.t1c_ext_b = GR_CMBX_LOCAL_TEXTURE_RGB, \ + cmb.t1c_ext_b_mode = GR_FUNC_MODE_ZERO, \ + cmb.t1c_ext_c = GR_CMBX_ZERO, \ + cmb.t1c_ext_c_invert = 0, \ + cmb.t1c_ext_d= GR_CMBX_B, \ + cmb.t1c_ext_d_invert = 0, \ + cmb.t0c_ext_a = GR_CMBX_OTHER_TEXTURE_RGB, \ + cmb.t0c_ext_a_mode = GR_FUNC_MODE_X, \ + cmb.t0c_ext_b = GR_CMBX_LOCAL_TEXTURE_RGB, \ + cmb.t0c_ext_b_mode = GR_FUNC_MODE_NEGATIVE_X, \ + cmb.t0c_ext_c = GR_CMBX_TMU_CCOLOR, \ + cmb.t0c_ext_c_invert = 0, \ + cmb.t0c_ext_d= GR_CMBX_B, \ + cmb.t0c_ext_d_invert = 0, \ + cmb.tex_ccolor = rdp.env_color, \ + cmb.tex_cmb_ext_use |= TEX_COMBINE_EXT_COLOR; \ +} +#define T1_INTER_T0_USING_ENV() /* inverse of above */\ + if (!cmb.combine_ext) { \ + T1_INTER_T0_USING_FACTOR ((rdp.env_color&0xFF)); \ + }\ + else {\ + rdp.best_tex = 0; \ + cmb.tex |= 3, \ + cmb.t1c_ext_a = GR_CMBX_LOCAL_TEXTURE_RGB, \ + cmb.t1c_ext_a_mode = GR_FUNC_MODE_ZERO, \ + cmb.t1c_ext_b = GR_CMBX_LOCAL_TEXTURE_RGB, \ + cmb.t1c_ext_b_mode = GR_FUNC_MODE_ZERO, \ + cmb.t1c_ext_c = GR_CMBX_ZERO, \ + cmb.t1c_ext_c_invert = 0, \ + cmb.t1c_ext_d= GR_CMBX_B, \ + cmb.t1c_ext_d_invert = 0, \ + cmb.t0c_ext_a = GR_CMBX_LOCAL_TEXTURE_RGB, \ + cmb.t0c_ext_a_mode = GR_FUNC_MODE_X, \ + cmb.t0c_ext_b = GR_CMBX_OTHER_TEXTURE_RGB, \ + cmb.t0c_ext_b_mode = GR_FUNC_MODE_NEGATIVE_X, \ + cmb.t0c_ext_c = GR_CMBX_TMU_CCOLOR, \ + cmb.t0c_ext_c_invert = 0, \ + cmb.t0c_ext_d= GR_CMBX_B, \ + cmb.t0c_ext_d_invert = 0, \ + cmb.tex_ccolor = rdp.env_color, \ + cmb.tex_cmb_ext_use |= TEX_COMBINE_EXT_COLOR; \ +} +#define T0_INTER_T1_USING_SHADEA() \ + if (!cmb.combine_ext) { \ + T0_INTER_T1_USING_FACTOR (0x7F); \ + }\ + else {\ + rdp.best_tex = 0; \ + cmb.tex |= 3, \ + cmb.t1c_ext_a = GR_CMBX_LOCAL_TEXTURE_RGB, \ + cmb.t1c_ext_a_mode = GR_FUNC_MODE_ZERO, \ + cmb.t1c_ext_b = GR_CMBX_LOCAL_TEXTURE_RGB, \ + cmb.t1c_ext_b_mode = GR_FUNC_MODE_ZERO, \ + cmb.t1c_ext_c = GR_CMBX_ZERO, \ + cmb.t1c_ext_c_invert = 0, \ + cmb.t1c_ext_d= GR_CMBX_B, \ + cmb.t1c_ext_d_invert = 0, \ + cmb.t0c_ext_a = GR_CMBX_OTHER_TEXTURE_RGB, \ + cmb.t0c_ext_a_mode = GR_FUNC_MODE_X, \ + cmb.t0c_ext_b = GR_CMBX_LOCAL_TEXTURE_RGB, \ + cmb.t0c_ext_b_mode = GR_FUNC_MODE_NEGATIVE_X, \ + cmb.t0c_ext_c = GR_CMBX_ITALPHA, \ + cmb.t0c_ext_c_invert = 0, \ + cmb.t0c_ext_d= GR_CMBX_B, \ + cmb.t0c_ext_d_invert = 0, \ + cmb.tex_cmb_ext_use |= TEX_COMBINE_EXT_COLOR; \ +} +#define T1_INTER_T0_USING_SHADEA() \ + if (!cmb.combine_ext) { \ + T0_INTER_T1_USING_FACTOR (0x7F); \ + }\ + else {\ + rdp.best_tex = 0; \ + cmb.tex |= 3, \ + cmb.t1c_ext_a = GR_CMBX_LOCAL_TEXTURE_RGB, \ + cmb.t1c_ext_a_mode = GR_FUNC_MODE_ZERO, \ + cmb.t1c_ext_b = GR_CMBX_LOCAL_TEXTURE_RGB, \ + cmb.t1c_ext_b_mode = GR_FUNC_MODE_ZERO, \ + cmb.t1c_ext_c = GR_CMBX_ZERO, \ + cmb.t1c_ext_c_invert = 0, \ + cmb.t1c_ext_d= GR_CMBX_B, \ + cmb.t1c_ext_d_invert = 0, \ + cmb.t0c_ext_a = GR_CMBX_LOCAL_TEXTURE_RGB, \ + cmb.t0c_ext_a_mode = GR_FUNC_MODE_X, \ + cmb.t0c_ext_b = GR_CMBX_OTHER_TEXTURE_RGB, \ + cmb.t0c_ext_b_mode = GR_FUNC_MODE_NEGATIVE_X, \ + cmb.t0c_ext_c = GR_CMBX_ITALPHA, \ + cmb.t0c_ext_c_invert = 0, \ + cmb.t0c_ext_d= GR_CMBX_B, \ + cmb.t0c_ext_d_invert = 0, \ + cmb.tex_cmb_ext_use |= TEX_COMBINE_EXT_COLOR; \ +} +#define T1_SUB_T0() \ + rdp.best_tex = 0; \ + cmb.tex |= 3, \ + cmb.tmu1_func = GR_COMBINE_FUNCTION_LOCAL, \ + cmb.tmu0_func = GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL, \ + cmb.tmu0_fac = GR_COMBINE_FACTOR_ONE +#define T1_SUB_T0_MUL_T0() \ + rdp.best_tex = 0; \ + cmb.tex |= 3, \ + cmb.tmu1_func = GR_COMBINE_FUNCTION_LOCAL, \ + cmb.tmu0_func = GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL, \ + cmb.tmu0_fac = GR_COMBINE_FACTOR_LOCAL +#define T1_MUL_PRIMLOD_ADD_T0() \ + rdp.best_tex = 0; \ + cmb.tex |= 3, \ + cmb.tmu1_func = GR_COMBINE_FUNCTION_LOCAL, \ + cmb.tmu0_func = GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, \ + cmb.tmu0_fac = GR_COMBINE_FACTOR_DETAIL_FACTOR, \ + percent = (float)(lod_frac) / 255.0f, \ + cmb.dc0_detailmax = cmb.dc1_detailmax = percent +#define T1_MUL_PRIMA_ADD_T0() \ + rdp.best_tex = 0; \ + cmb.tex |= 3, \ + cmb.tmu1_func = GR_COMBINE_FUNCTION_LOCAL, \ + cmb.tmu0_func = GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, \ + cmb.tmu0_fac = GR_COMBINE_FACTOR_DETAIL_FACTOR, \ + percent = (float)(rdp.prim_color&0xFF) / 255.0f, \ + cmb.dc0_detailmax = cmb.dc1_detailmax = percent +#define T1_MUL_ENVA_ADD_T0() \ + rdp.best_tex = 0; \ + cmb.tex |= 3, \ + cmb.tmu1_func = GR_COMBINE_FUNCTION_LOCAL, \ + cmb.tmu0_func = GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, \ + cmb.tmu0_fac = GR_COMBINE_FACTOR_DETAIL_FACTOR, \ + percent = (float)(rdp.env_color&0xFF) / 255.0f, \ + cmb.dc0_detailmax = cmb.dc1_detailmax = percent +#define T0_SUB_PRIM_MUL_PRIMLOD_ADD_T1() \ + T0_ADD_T1 (); \ + MOD_0 (TMOD_TEX_SUB_COL_MUL_FAC); \ + MOD_0_COL (rdp.prim_color & 0xFFFFFF00); \ + MOD_0_FAC (lod_frac & 0xFF); +#define T1_SUB_PRIM_MUL_PRIMLOD_ADD_T0() \ + if (cmb.combine_ext) \ +{ \ + T1CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, \ + GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_NEGATIVE_X, \ + GR_CMBX_DETAIL_FACTOR, 0, \ + GR_CMBX_ZERO, 0); \ + T0CCMBEXT(GR_CMBX_OTHER_TEXTURE_RGB, GR_FUNC_MODE_X, \ + GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, \ + GR_CMBX_ZERO, 1, \ + GR_CMBX_ZERO, 0); \ + cmb.tex_ccolor = rdp.prim_color; \ + cmb.tex |= 3; \ + percent = (float)(lod_frac) / 255.0f; \ + cmb.dc0_detailmax = cmb.dc1_detailmax = percent; \ +} \ + else \ +{ \ + T0_ADD_T1 (); \ + MOD_1 (TMOD_TEX_SUB_COL_MUL_FAC); \ + MOD_1_COL (rdp.prim_color & 0xFFFFFF00); \ + MOD_1_FAC (lod_frac & 0xFF); \ +} +#define PRIM_INTER_T0_USING_SHADEA() \ + if (!cmb.combine_ext) { \ + USE_T0 (); \ + }\ + else {\ + rdp.best_tex = 0; \ + cmb.tex |= 1, \ + cmb.t0c_ext_a = GR_CMBX_LOCAL_TEXTURE_RGB, \ + cmb.t0c_ext_a_mode = GR_FUNC_MODE_X, \ + cmb.t0c_ext_b = GR_CMBX_TMU_CCOLOR, \ + cmb.t0c_ext_b_mode = GR_FUNC_MODE_NEGATIVE_X, \ + cmb.t0c_ext_c = GR_CMBX_ITALPHA, \ + cmb.t0c_ext_c_invert = 0, \ + cmb.t0c_ext_d= GR_CMBX_B, \ + cmb.t0c_ext_d_invert = 0, \ + cmb.tex_ccolor = rdp.prim_color, \ + cmb.tex_cmb_ext_use |= TEX_COMBINE_EXT_COLOR; \ +} + +#define A_USE_T0() \ + cmb.tex |= 1, \ + cmb.tmu0_a_func = GR_COMBINE_FUNCTION_LOCAL +#define A_USE_T1() \ + if (voodoo.num_tmu > 1) { \ + cmb.tex |= 2, \ + cmb.tmu1_a_func = GR_COMBINE_FUNCTION_LOCAL, \ + cmb.tmu0_a_func = GR_COMBINE_FUNCTION_SCALE_OTHER, \ + cmb.tmu0_a_fac = GR_COMBINE_FACTOR_ONE; \ + } \ + else { \ + A_USE_T0(); \ +} +#define A_T0_ADD_T1() \ + cmb.tex |= 3, \ + cmb.tmu1_a_func = GR_COMBINE_FUNCTION_LOCAL, \ + cmb.tmu0_a_func = GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, \ + cmb.tmu0_a_fac = GR_COMBINE_FACTOR_ONE +#define A_T1_SUB_T0() \ + cmb.tex |= 3, \ + cmb.tmu1_a_func = GR_COMBINE_FUNCTION_LOCAL, \ + cmb.tmu0_a_func = GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL, \ + cmb.tmu0_a_fac = GR_COMBINE_FACTOR_ONE +#define A_T0_SUB_T1() \ + cmb.tex |= 3, \ + cmb.tmu1_a_func = GR_COMBINE_FUNCTION_LOCAL, \ + cmb.tmu0_a_func = GR_COMBINE_FUNCTION_BLEND_LOCAL, \ + cmb.tmu0_a_fac = GR_COMBINE_FACTOR_OTHER_ALPHA +#define A_T0_MUL_T1() \ + cmb.tex |= 3, \ + cmb.tmu1_a_func = GR_COMBINE_FUNCTION_LOCAL, \ + cmb.tmu0_a_func = GR_COMBINE_FUNCTION_SCALE_OTHER, \ + cmb.tmu0_a_fac = GR_COMBINE_FACTOR_LOCAL +#define A_T0_INTER_T1_USING_T0A() \ + rdp.best_tex = 0; \ + cmb.tex |= 3, \ + cmb.tmu1_a_func = GR_COMBINE_FUNCTION_LOCAL, \ + cmb.tmu0_a_func = GR_COMBINE_FUNCTION_BLEND, \ + cmb.tmu0_a_fac = GR_COMBINE_FACTOR_LOCAL_ALPHA +#define A_T1_INTER_T0_USING_T0A() \ + rdp.best_tex = 0; \ + cmb.tex |= 3, \ + cmb.tmu1_a_func = GR_COMBINE_FUNCTION_LOCAL, \ + cmb.tmu0_a_func = GR_COMBINE_FUNCTION_BLEND, \ + cmb.tmu0_a_fac = GR_COMBINE_FACTOR_ONE_MINUS_LOCAL_ALPHA +#define A_T0_INTER_T1_USING_T1A() \ + rdp.best_tex = 0; \ + cmb.tex |= 3, \ + cmb.tmu1_a_func = GR_COMBINE_FUNCTION_LOCAL, \ + cmb.tmu0_a_func = GR_COMBINE_FUNCTION_BLEND, \ + cmb.tmu0_a_fac = GR_COMBINE_FACTOR_OTHER_ALPHA +#define A_T0_INTER_T1_USING_FACTOR(factor) \ + if (factor == 0xFF) { \ + A_USE_T1(); \ + } \ + else if (factor == 0x00) { \ + A_USE_T0(); \ +}\ + else { \ + cmb.tex |= 3, \ + cmb.tmu1_a_func = GR_COMBINE_FUNCTION_LOCAL, \ + cmb.tmu0_a_func = GR_COMBINE_FUNCTION_BLEND, \ + cmb.tmu0_a_fac = GR_COMBINE_FACTOR_DETAIL_FACTOR, \ + percent = (float)factor / 255.0f, \ + cmb.dc0_detailmax = cmb.dc1_detailmax = percent; \ +} +#define A_T1_INTER_T0_USING_FACTOR(factor) /* inverse of above */\ + if (factor == 0xFF) { \ + A_USE_T0(); \ + } \ + else if (factor == 0x00) { \ + A_USE_T1(); \ +}\ + else { \ + cmb.tex |= 3, \ + cmb.tmu1_a_func = GR_COMBINE_FUNCTION_LOCAL, \ + cmb.tmu0_a_func = GR_COMBINE_FUNCTION_BLEND, \ + cmb.tmu0_a_fac = GR_COMBINE_FACTOR_DETAIL_FACTOR, \ + percent = (255 - factor) / 255.0f, \ + cmb.dc0_detailmax = cmb.dc1_detailmax = percent; \ +} +#define A_T0_INTER_T1_USING_SHADEA() \ + if (!cmb.combine_ext) { \ + A_T0_INTER_T1_USING_FACTOR (0x7F); \ + }\ + else {\ + rdp.best_tex = 0; \ + cmb.tex |= 3, \ + cmb.t1a_ext_a = GR_CMBX_LOCAL_TEXTURE_ALPHA, \ + cmb.t1a_ext_a_mode = GR_FUNC_MODE_ZERO, \ + cmb.t1a_ext_b = GR_CMBX_LOCAL_TEXTURE_ALPHA, \ + cmb.t1a_ext_b_mode = GR_FUNC_MODE_ZERO, \ + cmb.t1a_ext_c = GR_CMBX_ZERO, \ + cmb.t1a_ext_c_invert = 0, \ + cmb.t1a_ext_d= GR_CMBX_B, \ + cmb.t1a_ext_d_invert = 0, \ + cmb.t0a_ext_a = GR_CMBX_OTHER_TEXTURE_ALPHA, \ + cmb.t0a_ext_a_mode = GR_FUNC_MODE_X, \ + cmb.t0a_ext_b = GR_CMBX_LOCAL_TEXTURE_ALPHA, \ + cmb.t0a_ext_b_mode = GR_FUNC_MODE_NEGATIVE_X, \ + cmb.t0a_ext_c = GR_CMBX_ITALPHA, \ + cmb.t0a_ext_c_invert = 0, \ + cmb.t0a_ext_d= GR_CMBX_B, \ + cmb.t0a_ext_d_invert = 0, \ + cmb.tex_cmb_ext_use |= TEX_COMBINE_EXT_ALPHA; \ +} +#define A_T1_MUL_PRIMLOD_ADD_T0() \ + rdp.best_tex = 0; \ + cmb.tex |= 3, \ + cmb.tmu1_a_func = GR_COMBINE_FUNCTION_LOCAL, \ + cmb.tmu0_a_func = GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, \ + cmb.tmu0_a_fac = GR_COMBINE_FACTOR_DETAIL_FACTOR, \ + percent = (float)(lod_frac) / 255.0f, \ + cmb.dc0_detailmax = cmb.dc1_detailmax = percent +#define A_T1_MUL_PRIMA_ADD_T0() \ + rdp.best_tex = 0; \ + cmb.tex |= 3, \ + cmb.tmu1_a_func = GR_COMBINE_FUNCTION_LOCAL, \ + cmb.tmu0_a_func = GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, \ + cmb.tmu0_a_fac = GR_COMBINE_FACTOR_DETAIL_FACTOR, \ + percent = (float)(rdp.prim_color&0xFF) / 255.0f, \ + cmb.dc0_detailmax = cmb.dc1_detailmax = percent +#define A_T1_MUL_ENVA_ADD_T0() \ + rdp.best_tex = 0; \ + cmb.tex |= 3, \ + cmb.tmu1_a_func = GR_COMBINE_FUNCTION_LOCAL, \ + cmb.tmu0_a_func = GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, \ + cmb.tmu0_a_fac = GR_COMBINE_FACTOR_DETAIL_FACTOR, \ + percent = (float)(rdp.env_color&0xFF) / 255.0f, \ + cmb.dc0_detailmax = cmb.dc1_detailmax = percent + + +// UNIMP - writes to the unimplemented log, if it's enabled +#ifdef UNIMP_LOG +#define UNIMPMODE() { \ + std::ofstream unimp; \ + unimp.open("unimp.txt", std::ios::app); \ + unimp << out_buf; \ + unimp.close(); \ +} +#else +#define UNIMPMODE() +#endif + +// Bright red, sets up a bright red combine +#ifdef BRIGHT_RED +// Bright red, sets up a bright red combine during the alpha stage +#define BrightRed() { \ + CCMB (GR_COMBINE_FUNCTION_LOCAL, \ + GR_COMBINE_FACTOR_NONE, \ + GR_COMBINE_LOCAL_CONSTANT, \ + GR_COMBINE_OTHER_NONE); \ + ACMB (GR_COMBINE_FUNCTION_LOCAL, \ + GR_COMBINE_FACTOR_NONE, \ + GR_COMBINE_LOCAL_CONSTANT, \ + GR_COMBINE_OTHER_NONE); \ + cmb.ccolor = 0xFF0000FF; \ +} +#else +#define BrightRed() +#endif + +#define CC(color) cmb.ccolor=(color)&0xFFFFFF00 +#define CC_BYTE(byte) { cmb.ccolor=(byte<<8)|(byte<<16)|(byte<<24); } +#define CC_C1MULC2(color1, color2) { \ + cmb.ccolor=(wxUint8)( ((color1 & 0xFF000000) >> 24) * (((color2 & 0xFF000000) >> 24) /255.0f) ) << 24 | \ + (wxUint8)( ((color1 & 0x00FF0000) >> 16) * (((color2 & 0x00FF0000) >> 16) /255.0f) ) << 16 | \ + (wxUint8)( ((color1 & 0x0000FF00) >> 8) * (((color2 & 0x0000FF00) >> 8) /255.0f) ) << 8 ; \ +} +#define CC_C1SUBC2(color1, color2) { \ + cmb.ccolor=(wxUint8)( max(0, (int)((color1 & 0xFF000000) >> 24) - (int)((color2 & 0xFF000000) >> 24)) ) << 24 | \ + (wxUint8)( max(0, (int)((color1 & 0x00FF0000) >> 16) - (int)((color2 & 0x00FF0000) >> 16)) ) << 16 | \ + (wxUint8)( max(0, (int)((color1 & 0x0000FF00) >> 8) - (int)((color2 & 0x0000FF00) >> 8)) ) << 8 ; \ +} +#define CC_COLMULBYTE(color, byte) { \ + float factor = byte/255.0f; \ + cmb.ccolor = (wxUint8)( ((color & 0xFF000000) >> 24) * factor ) << 24 | \ + (wxUint8)( ((color & 0x00FF0000) >> 16) * factor ) << 16 | \ + (wxUint8)( ((color & 0x0000FF00) >> 8) * factor ) << 8 ; \ +} +#define CC_PRIM() CC(rdp.prim_color) +#define CC_ENV() CC(rdp.env_color) +#define CC_1SUBPRIM() CC((~rdp.prim_color)) +#define CC_1SUBENV() CC((~rdp.env_color)) +#define CC_PRIMA() CC_BYTE((rdp.prim_color&0xFF)) +#define CC_ENVA() CC_BYTE((rdp.env_color&0xFF)) +#define CC_1SUBPRIMA() CC_BYTE(((~rdp.prim_color)&0xFF)) +#define CC_1SUBENVA() CC_BYTE(((~rdp.env_color)&0xFF)) +#define CC_PRIMLOD() CC_BYTE(rdp.prim_lodfrac) +#define CC_K5() CC_BYTE(rdp.K5) +#define CC_PRIMMULENV() CC_C1MULC2(rdp.prim_color, rdp.env_color) +#define CC_PRIMSUBENV() CC_C1SUBC2(rdp.prim_color, rdp.env_color) + +#define XSHADE(color, flag) { \ + rdp.col[0] *= (float)((color & 0xFF000000) >> 24) / 255.0f; \ + rdp.col[1] *= (float)((color & 0x00FF0000) >> 16) / 255.0f; \ + rdp.col[2] *= (float)((color & 0x0000FF00) >> 8) / 255.0f; \ + rdp.cmb_flags |= flag; \ +} +#define XSHADE1M(color, flag) { \ + rdp.col[0] *= 1.0f-((float)((color & 0xFF000000) >> 24)/255.0f); \ + rdp.col[1] *= 1.0f-((float)((color & 0x00FF0000) >> 16)/255.0f); \ + rdp.col[2] *= 1.0f-((float)((color & 0x0000FF00) >> 8)/255.0f); \ + rdp.cmb_flags |= flag; \ +} +#define XSHADEC1MC2(color1, color2, flag) { \ + rdp.col[0] *= (float)( max(0, (int)((color1 & 0xFF000000) >> 24) - (int)((color2 & 0xFF000000) >> 24)) )/255.0f; \ + rdp.col[1] *= (float)( max(0, (int)((color1 & 0x00FF0000) >> 16) - (int)((color2 & 0x00FF0000) >> 16)) )/255.0f; \ + rdp.col[2] *= (float)( max(0, (int)((color1 & 0x0000FF00) >> 8) - (int)((color2 & 0x0000FF00) >> 8)) )/255.0f; \ + rdp.cmb_flags |= flag; \ +} +#define XSHADE_BYTE(byte, flag) { \ + float tmpcol = (float)byte / 255.0f; \ + rdp.col[0] *= tmpcol; \ + rdp.col[1] *= tmpcol; \ + rdp.col[2] *= tmpcol; \ + rdp.cmb_flags |= flag; \ +} +#define MULSHADE(color) XSHADE(color, CMB_MULT) +#define MULSHADE_PRIM() MULSHADE(rdp.prim_color) +#define MULSHADE_ENV() MULSHADE(rdp.env_color) +#define MULSHADE_1MPRIM() XSHADE1M(rdp.prim_color, CMB_MULT) +#define MULSHADE_1MENV() XSHADE1M(rdp.env_color, CMB_MULT) +#define MULSHADE_PRIMSUBENV() XSHADEC1MC2(rdp.prim_color, rdp.env_color, CMB_MULT) +#define MULSHADE_ENVSUBPRIM() XSHADEC1MC2(rdp.env_color, rdp.prim_color, CMB_MULT) +#define MULSHADE_BYTE(byte) XSHADE_BYTE(byte, CMB_MULT) +#define MULSHADE_PRIMA() MULSHADE_BYTE((rdp.prim_color & 0xFF)) +#define MULSHADE_ENVA() MULSHADE_BYTE((rdp.env_color & 0xFF)) +#define MULSHADE_1MENVA() MULSHADE_BYTE(((~rdp.env_color) & 0xFF)) +#define MULSHADE_PRIMLOD() MULSHADE_BYTE((rdp.prim_lodfrac & 0xFF)) +#define MULSHADE_K5() MULSHADE_BYTE(rdp.K5) + +#define SETSHADE(color) XSHADE(color, CMB_SET) +#define SETSHADE_PRIM() SETSHADE(rdp.prim_color) +#define SETSHADE_ENV() SETSHADE(rdp.env_color) +#define SETSHADE_BYTE(byte) XSHADE_BYTE(byte, CMB_SET) +#define SETSHADE_PRIMA() SETSHADE_BYTE((rdp.prim_color & 0xFF)) +#define SETSHADE_ENVA() SETSHADE_BYTE((rdp.env_color & 0xFF)) +#define SETSHADE_1MPRIMA() SETSHADE_BYTE(((~rdp.prim_color) & 0xFF)) +#define SETSHADE_PRIMLOD() SETSHADE_BYTE((rdp.prim_lodfrac & 0xFF)) +#define SETSHADE_1MPRIMLOD() SETSHADE_BYTE(((~rdp.prim_lodfrac) & 0xFF)) + +#define SETSHADE_1MPRIM() XSHADE1M(rdp.prim_color, CMB_SET) +#define SETSHADE_1MENV() XSHADE1M(rdp.env_color, CMB_SET) +#define SETSHADE_PRIMSUBENV() XSHADEC1MC2(rdp.prim_color, rdp.env_color, CMB_SET) +#define SETSHADE_ENVSUBPRIM() XSHADEC1MC2(rdp.env_color, rdp.prim_color, CMB_SET) +#define SETSHADE_SHADE_A() { \ + rdp.cmb_flags = CMB_SETSHADE_SHADEALPHA; \ +} + +#define XSHADEADD(color, flag) { \ + rdp.coladd[0] *= (float)((color & 0xFF000000) >> 24) / 255.0f; \ + rdp.coladd[1] *= (float)((color & 0x00FF0000) >> 16) / 255.0f; \ + rdp.coladd[2] *= (float)((color & 0x0000FF00) >> 8) / 255.0f; \ + rdp.cmb_flags |= flag; \ +} +#define XSHADEC1MC2ADD(color1, color2, flag) { \ + rdp.coladd[0] *= (float)( max(0, (int)((color1 & 0xFF000000) >> 24) - (int)((color2 & 0xFF000000) >> 24)) )/255.0f; \ + rdp.coladd[1] *= (float)( max(0, (int)((color1 & 0x00FF0000) >> 16) - (int)((color2 & 0x00FF0000) >> 16)) )/255.0f; \ + rdp.coladd[2] *= (float)( max(0, (int)((color1 & 0x0000FF00) >> 8) - (int)((color2 & 0x0000FF00) >> 8)) )/255.0f; \ + rdp.cmb_flags |= flag; \ +} +#define SUBSHADE_PRIM() XSHADEADD(rdp.prim_color, CMB_SUB) +#define SUBSHADE_ENV() XSHADEADD(rdp.env_color, CMB_SUB) +#define SUBSHADE_PRIMSUBENV() XSHADEC1MC2ADD(rdp.prim_color, rdp.env_color, CMB_SUB) +#define ADDSHADE_PRIM() XSHADEADD(rdp.prim_color, CMB_ADD) +#define ADDSHADE_ENV() XSHADEADD(rdp.env_color, CMB_ADD) +#define ADDSHADE_PRIMSUBENV() XSHADEC1MC2ADD(rdp.prim_color, rdp.env_color, CMB_ADD) +#define SUBSHADE_PRIMMULENV() { \ + rdp.coladd[0] *= (float)( ((rdp.prim_color & 0xFF000000) >> 24) * ((rdp.env_color & 0xFF000000) >> 24) )/255.0f/255.0f; \ + rdp.coladd[1] *= (float)( ((rdp.prim_color & 0x00FF0000) >> 16) * ((rdp.env_color & 0x00FF0000) >> 16) )/255.0f/255.0f; \ + rdp.coladd[2] *= (float)( ((rdp.prim_color & 0x0000FF00) >> 8) * ((rdp.env_color & 0x0000FF00) >> 8) )/255.0f/255.0f; \ + rdp.cmb_flags |= CMB_SUB; \ +} + +#define COLSUBSHADE_PRIM() { \ + rdp.coladd[0] *= (float)((rdp.prim_color & 0xFF000000) >> 24) / 255.0f; \ + rdp.coladd[1] *= (float)((rdp.prim_color & 0x00FF0000) >> 16) / 255.0f; \ + rdp.coladd[2] *= (float)((rdp.prim_color & 0x0000FF00) >> 8) / 255.0f; \ + rdp.cmb_flags |= CMB_COL_SUB_OWN; \ +} + +#define INTERSHADE_2(color,factor) { \ + rdp.col_2[0] = (((color) >> 24) & 0xFF) / 255.0f; \ + rdp.col_2[1] = (((color) >> 16) & 0xFF) / 255.0f; \ + rdp.col_2[2] = (((color) >> 8) & 0xFF) / 255.0f; \ + rdp.shade_factor = (factor) / 255.0f; \ + rdp.cmb_flags_2 = CMB_INTER; \ +} + +#define MULSHADE_SHADEA() rdp.cmb_flags |= CMB_MULT_OWN_ALPHA; + +#define CA(color) cmb.ccolor|=(color)&0xFF +#define CA_PRIM() CA(rdp.prim_color) +#define CA_ENV() CA(rdp.env_color) +#define CA_INVPRIM() cmb.ccolor|=0xFF-(rdp.prim_color&0xFF) +#define CA_INVENV() cmb.ccolor|=0xFF-(rdp.env_color&0xFF) +#define CA_ENV1MPRIM() cmb.ccolor|= (wxUint32)(((rdp.env_color&0xFF)/255.0f) * (((~(rdp.prim_color&0xFF)) & 0xff)/255.0f) * 255.0f); +#define CA_PRIMENV() cmb.ccolor |= (wxUint32)(((rdp.env_color&0xFF)/255.0f) * ((rdp.prim_color&0xFF)/255.0f) * 255.0f); +#define CA_PRIMLOD() cmb.ccolor |= rdp.prim_lodfrac; +#define CA_PRIM_MUL_PRIMLOD() cmb.ccolor |= (int)(((rdp.prim_color&0xFF) * rdp.prim_lodfrac) / 255.0f); +#define CA_ENV_MUL_PRIMLOD() cmb.ccolor |= (int)(((rdp.env_color&0xFF) * rdp.prim_lodfrac) / 255.0f); + +#define XSHADE_A(color, flag) { \ + rdp.col[3] *= (float)(color & 0xFF) / 255.0f; \ + rdp.cmb_flags |= flag; \ +} +#define XSHADE1M_A(color, flag) { \ + rdp.col[3] *= 1.0f-((float)(color & 0xFF) / 255.0f); \ + rdp.cmb_flags |= flag; \ +} +#define XSHADEC1MC2_A(color1, color2, flag) { \ + rdp.col[3] *= (float)( max(0, (int)(color1 & 0xFF) - (int)(color2 & 0xFF)) ) / 255.0f; \ + rdp.cmb_flags |= flag; \ +} +#define MULSHADE_A_PRIM() XSHADE_A(rdp.prim_color, CMB_A_MULT) +#define MULSHADE_A_1MPRIM() XSHADE1M_A(rdp.prim_color, CMB_A_MULT) +#define MULSHADE_A_ENV() XSHADE_A(rdp.env_color, CMB_A_MULT) +#define MULSHADE_A_PRIMSUBENV() XSHADEC1MC2_A(rdp.prim_color, rdp.env_color, CMB_A_MULT) +#define MULSHADE_A_ENVSUBPRIM() XSHADEC1MC2_A(rdp.env_color, rdp.prim_color, CMB_A_MULT) +#define SETSHADE_A(color) XSHADE_A(color, CMB_A_SET) +#define SETSHADE_A_PRIM() SETSHADE_A(rdp.prim_color) +#define SETSHADE_A_ENV() SETSHADE_A(rdp.env_color) +#define SETSHADE_A_PRIMSUBENV() XSHADEC1MC2_A(rdp.prim_color, rdp.env_color, CMB_A_SET) +#define SETSHADE_A_INVENV() XSHADE1M_A(rdp.env_color, CMB_A_SET) + +#define XSHADEADD_A(color, flag) { \ + rdp.coladd[3] *= (float)(color & 0xFF) / 255.0f; \ + rdp.cmb_flags |= flag; \ +} +#define SUBSHADE_A_PRIM() XSHADEADD_A(rdp.prim_color, CMB_A_SUB) +#define SUBSHADE_A_ENV() XSHADEADD_A(rdp.env_color, CMB_A_SUB) +#define ADDSHADE_A_PRIM() XSHADEADD_A(rdp.prim_color, CMB_A_ADD) +#define ADDSHADE_A_ENV() XSHADEADD_A(rdp.env_color, CMB_A_ADD) + +//**************************************************************** +// Combine Functions +//**************************************************************** + +// These are in a somewhat ordered way, using the A constants below. T0 comes before +// T1 comes before PRIM, ... except for CMB, which always comes at the end, where +// the CMB comes first in the name. T0 and T1 are always interleaved, because they use the +// same function. +// Keep going in alphabetical order, but do not break the order of variables! +// ex: A*C + B*C -> T0_MUL_PRIM_ADD_ENV_MUL_PRIM, +// Although prim comes before env, we have already used prim as C, so it must stay as C +// and would NOT become T0_MUL_PRIM_ADD_PRIM_MUL_ENV +// +// New version ordered by: +// t0 +// prim +// env +// shade + +static void cc_one () +{ + CCMB (GR_COMBINE_FUNCTION_LOCAL, + GR_COMBINE_FACTOR_NONE, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_NONE); + // CC (0xFFFFFF00); + CC (0xFFFFFF00); +} + +static void cc_zero () +{ + CCMB (GR_COMBINE_FUNCTION_LOCAL, + GR_COMBINE_FACTOR_NONE, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_NONE); + CC (0x00000000); +} + +static void cc_t0 () +{ + if ((rdp.othermode_l & 0x4000) && (rdp.cycle_mode < 2)) + { + wxUint32 blend_mode = (rdp.othermode_l >> 16); + if (blend_mode == 0xa500) + { + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + float fog = (rdp.fog_color&0xFF)/255.0f; + wxUint32 R = (wxUint32)(((rdp.blend_color>>24)&0xFF)*fog); + wxUint32 G = (wxUint32)(((rdp.blend_color>>16)&0xFF)*fog); + wxUint32 B = (wxUint32)(((rdp.blend_color>> 8)&0xFF)*fog); + CC((R<<24)|(G<<16)|(B<<8)); + } + else if (blend_mode == 0x55f0) //cmem*afog + cfog*1ma + { + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_ONE_MINUS_TEXTURE_ALPHA, + GR_COMBINE_LOCAL_NONE, + GR_COMBINE_OTHER_CONSTANT); + CC(rdp.fog_color); + A_USE_T0 (); + } + else + { + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_NONE, + GR_COMBINE_OTHER_TEXTURE); + } + } + else + { + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_NONE, + GR_COMBINE_OTHER_TEXTURE); + } + USE_T0 (); +} + +static void cc_t0a () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_TEXTURE_ALPHA, + GR_COMBINE_LOCAL_NONE, + GR_COMBINE_OTHER_CONSTANT); + USE_T0 (); + A_USE_T0 (); + CC (0xFFFFFF00); +} + +static void cc_t1 () //Added by Gonetz +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_NONE, + GR_COMBINE_OTHER_TEXTURE); + USE_T1 (); +} + +static void cc_t0_mul_t1 () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_NONE, + GR_COMBINE_OTHER_TEXTURE); + T0_MUL_T1 (); +} + +static void cc_t0_mul_t1_add_t0 () //Added by Gonetz +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_NONE, + GR_COMBINE_OTHER_TEXTURE); + T0_MUL_T1_ADD_T0 (); +} + +/* +static void cc_t1_inter__env_inter_t0_using_k5__using_t1a () +{ +CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, +GR_COMBINE_FACTOR_ONE, +GR_COMBINE_LOCAL_NONE, +GR_COMBINE_OTHER_TEXTURE); +wxUint32 col1 = (rdp.K5<<24) | (rdp.K5<<16) | (rdp.K5<<8); +MOD_0 (TMOD_COL_INTER_TEX_USING_COL1); +MOD_0_COL (rdp.env_color & 0xFFFFFF00); +MOD_0_COL1 (col1 & 0xFFFFFF00); +rdp.best_tex = 0; +cmb.tex |= 3; +cmb.tmu1_func = GR_COMBINE_FUNCTION_LOCAL; +cmb.tmu1_a_func = GR_COMBINE_FUNCTION_LOCAL; +cmb.tmu0_func = GR_COMBINE_FUNCTION_BLEND; +cmb.tmu0_fac = GR_COMBINE_FACTOR_ONE_MINUS_OTHER_ALPHA; +} +*/ + +static void cc_t1_inter_t0_using_env () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_NONE, + GR_COMBINE_OTHER_TEXTURE); + T1_INTER_T0_USING_ENV (); +} + +static void cc_prim () +{ + CCMB (GR_COMBINE_FUNCTION_LOCAL, + GR_COMBINE_FACTOR_NONE, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_NONE); + CC_PRIM (); +} + +static void cc_env () +{ + CCMB (GR_COMBINE_FUNCTION_LOCAL, + GR_COMBINE_FACTOR_NONE, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_NONE); + CC_ENV (); +} + +static void cc_scale () +{ + CCMB (GR_COMBINE_FUNCTION_LOCAL, + GR_COMBINE_FACTOR_NONE, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_NONE); + CC (rdp.SCALE); +} + +static void cc_shade () +{ + CCMB (GR_COMBINE_FUNCTION_LOCAL, + GR_COMBINE_FACTOR_NONE, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_NONE); +} + +static void cc_one_mul_shade () +{ + if ((settings.hacks&hack_Knockout) && (rdp.aTBuffTex[0] || rdp.aTBuffTex[1] || rdp.cur_image)) //hack for boxer shadow + { + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + CC (0x20202000); + USE_T0 (); + } + else + { + cc_shade (); + } +} + +static void cc_shadea () +{ + CCMB (GR_COMBINE_FUNCTION_LOCAL_ALPHA, + GR_COMBINE_FACTOR_NONE, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_NONE); +} + +static void cc_t0_mul_prim () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + CC_PRIM (); + USE_T0 (); +} + +static void cc_t0_mul_prima () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + CC_PRIMA (); + USE_T0 (); +} + +static void cc_t1_mul_prim () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + CC_PRIM (); + if ((rdp.cycle1 & 0xFFFF) == (rdp.cycle2 & 0xFFFF)) // 1 cycle, use t0 + { + USE_T0 (); + } + else + { + USE_T1 (); + } +} + +static void cc_t0a_mul_prim () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_TEXTURE_ALPHA, + GR_COMBINE_LOCAL_NONE, + GR_COMBINE_OTHER_CONSTANT); + CC_PRIM (); + A_USE_T0 (); +} + +//Added by Gonetz +static void cc__t1_inter_t0_using_enva__mul_prim () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + CC_PRIM (); + wxUint8 factor = (wxUint8)(rdp.env_color&0xFF); + T1_INTER_T0_USING_FACTOR (factor); +} + +static void cc__t0_inter_one_using_t1__mul_prim () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + CC_PRIM (); + rdp.best_tex = 0; + cmb.tex |= 3; + cmb.tmu1_func = GR_COMBINE_FUNCTION_LOCAL; + cmb.tmu0_func = GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL; + cmb.tmu0_fac = GR_COMBINE_FACTOR_ONE_MINUS_LOCAL; +} + +static void cc__t0_inter_one_using_primlod__mul_prim () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + CC_PRIM (); + if (cmb.combine_ext) + { + T0CCMBEXT(GR_CMBX_OTHER_TEXTURE_RGB, GR_FUNC_MODE_ZERO, + GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ONE_MINUS_X, + GR_CMBX_DETAIL_FACTOR, 0, + GR_CMBX_B, 0); + cmb.tex |= 1; + percent = (float)lod_frac / 255.0f; + cmb.dc0_detailmax = cmb.dc1_detailmax = percent; + } + else + { + MOD_0 (TMOD_TEX_INTER_COLOR_USING_FACTOR); + MOD_0_COL (0xFFFFFF00); + MOD_0_FAC (lod_frac); + USE_T0 (); + } +} + +static void cc__t1_inter_one_using_env__mul_prim () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + CC_PRIM (); + if (cmb.combine_ext) + { + T1CCMBEXT(GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_X, + GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, + GR_CMBX_LOCAL_TEXTURE_RGB, 1, + GR_CMBX_B, 0); + T0CCMBEXT(GR_CMBX_OTHER_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, + GR_CMBX_ZERO, 1, + GR_CMBX_ZERO, 0); + cmb.tex |= 2; + cmb.tex_ccolor = rdp.env_color; + } + else + { + USE_T1 (); + } +} + +static void cc__t1_inter_one_using_enva__mul_t0 () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_NONE, + GR_COMBINE_OTHER_TEXTURE); + if (cmb.combine_ext) + { + T1CCMBEXT(GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_X, + GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_TMU_CALPHA, 0, + GR_CMBX_B, 0); + T0CCMBEXT(GR_CMBX_OTHER_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, + GR_CMBX_LOCAL_TEXTURE_RGB, 0, + GR_CMBX_ZERO, 0); + cmb.tex |= 3; + cmb.tex_ccolor = 0xFFFFFF00 | (rdp.env_color&0xFF); + } + else + { + if ((rdp.env_color&0xFF) == 0xFF) + { + USE_T0 (); + } + else + { + T0_MUL_T1 (); + } + } +} + +//Added by Gonetz +static void cc_prim_mul_prim () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + CC_PRIM (); + SETSHADE_PRIM (); +} + +static void cc_prim_mul_prima () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + CC_PRIM (); + SETSHADE_PRIMA (); +} + +static void cc_t1_mul_prima () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + CC_PRIMA (); + USE_T1 (); +} + +static void cc_t1_mul_enva () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + CC_ENVA (); + USE_T1 (); +} + +static void cc_t0_mul_env () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + CC_ENV (); + USE_T0 (); +} + +static void cc_t1_mul_env () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + CC_ENV (); + USE_T1 (); +} + +//Added by Gonetz +static void cc_t0_mul_enva () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + CC_ENVA (); + USE_T0 (); +} + +static void cc_t0_mul_scale () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + CC (rdp.SCALE); + USE_T0 (); +} + +static void cc_t0_mul_enva_add_prim () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + SETSHADE_PRIM (); + CC_ENVA (); + USE_T0 (); +} + +static void cc_t0_mul_shade () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + USE_T0 (); +} + +static void cc_f1_sky () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_ALPHA, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + MULSHADE_SHADEA (); + MULSHADE_ENVSUBPRIM (); + ADDSHADE_PRIM(); + CC(0xFFFFFFFF); +} + +static void cc_t0_mul_shadea () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + SETSHADE_SHADE_A (); + USE_T0 (); +} + +static void cc_t0_mul_k5 () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + CC_K5 (); + USE_T0 (); +} + +static void cc_t1_mul_shade () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + USE_T1 (); +} + +//Added by Gonetz +static void cc__t0_add_t1__mul_shade () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + T0_ADD_T1 (); +} + +static void cc__t0_mul_shade__add__t1_mul_shade () +{ + //combiner is used in Spiderman. It seems that t0 is used instead of t1 + if (cmb.combine_ext) + { + T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, + GR_CMBX_ITRGB, 0, + GR_CMBX_ZERO, 0); + cmb.tex |= 1; + CCMBEXT(GR_CMBX_ITRGB, GR_FUNC_MODE_ZERO, + GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_ZERO, 1, + GR_CMBX_B, 0); + } + else + { + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + USE_T0 (); + } +} + +static void cc__t0_mul_prim__inter_env_using_enva () +{ + wxUint32 enva = rdp.env_color&0xFF; + if (enva == 0xFF) + cc_env (); + else if (enva == 0) + cc_t0_mul_prim (); + else if (cmb.combine_ext) + { + T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_ZERO, + GR_CMBX_TMU_CCOLOR, 0, + GR_CMBX_ZERO, 0); + cmb.tex |= 1; + cmb.tex_ccolor = rdp.prim_color; + CCMBEXT(GR_CMBX_ITRGB, GR_FUNC_MODE_X, + GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_CONSTANT_COLOR, 0, + GR_CMBX_B, 0); + SETSHADE_ENV(); + CC_ENVA(); + } + else + { + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + SETSHADE_PRIM(); + INTERSHADE_2 (rdp.env_color & 0xFFFFFF00, rdp.env_color & 0xFF); + USE_T0 (); + MOD_0 (TMOD_TEX_INTER_COLOR_USING_FACTOR); + MOD_0_COL (rdp.env_color & 0xFFFFFF00); + MOD_0_FAC (rdp.env_color & 0xFF); + } +} + + +static void cc__t1_inter_t0_using_t1__mul_shade () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + if (cmb.combine_ext) + { + T1CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, + GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, + GR_CMBX_ZERO, 0, + GR_CMBX_B, 0); + T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_OTHER_TEXTURE_RGB, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_B, 0, + GR_CMBX_B, 0); + cmb.tex |= 3; + } + else + { + T0_INTER_T1_USING_FACTOR (0x7F); + } +} + +//Added by Gonetz +static void cc__t1_inter_t0_using_enva__mul_shade () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + wxUint8 factor = (wxUint8)(rdp.env_color&0xFF); + T1_INTER_T0_USING_FACTOR (factor); +} + +//Added by Gonetz +static void cc__t1_inter_t0_using_shadea__mul_shade () +{ + if (!cmb.combine_ext) { + cc_t0_mul_shade (); + return; + } + CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_ITALPHA, GR_FUNC_MODE_ZERO, + GR_CMBX_ITRGB, 0, + GR_CMBX_ZERO, 0); + T1_INTER_T0_USING_SHADEA (); +} + +//Added by Gonetz +static void cc__t0_inter_one_using_prim__mul_shade () +{ + // (1-t0)*prim+t0, (cmb-0)*shade+0 + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + if (cmb.combine_ext) + { + T0CCMBEXT(GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_ZERO, + GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_ONE_MINUS_X, + GR_CMBX_LOCAL_TEXTURE_RGB, 0, + GR_CMBX_B, 0); + cmb.tex |= 1; + cmb.tex_ccolor = rdp.prim_color; + } + else + { + USE_T0 (); + MOD_0 (TMOD_TEX_INTER_COL_USING_COL1); + MOD_0_COL (0xFFFFFF00); + MOD_0_COL1 (rdp.prim_color & 0xFFFFFF00); + } +} + +static void cc__t0_inter_one_using_primlod__mul_shade () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + if (cmb.combine_ext) + { + T0CCMBEXT(GR_CMBX_OTHER_TEXTURE_RGB, GR_FUNC_MODE_ZERO, + GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ONE_MINUS_X, + GR_CMBX_DETAIL_FACTOR, 0, + GR_CMBX_B, 0); + cmb.tex |= 1; + percent = (float)lod_frac / 255.0f; + cmb.dc0_detailmax = cmb.dc1_detailmax = percent; + } + else + { + MOD_0 (TMOD_TEX_INTER_COLOR_USING_FACTOR); + MOD_0_COL (0xFFFFFF00); + MOD_0_FAC (lod_frac); + USE_T0 (); + } +} + +//Added by Gonetz +static void cc__t0_inter_env_using_enva__mul_shade () +{ + // (env-t0)*env_a+t0, (cmb-0)*shade+0 + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + if (cmb.combine_ext) + { + T0CCMBEXT(GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_X, + GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_TMU_CALPHA, 0, + GR_CMBX_B, 0); + cmb.tex |= 1; + cmb.tex_ccolor = rdp.env_color; + } + else + { + USE_T0 (); + MOD_0 (TMOD_TEX_INTER_COLOR_USING_FACTOR); + MOD_0_COL (rdp.env_color & 0xFFFFFF00); + MOD_0_FAC (rdp.env_color&0xFF); + } +} + +//Added by Gonetz +static void cc__t0_inter_env_using_shadea__mul_shade () +{ + // (env-t0)*shade_a+t0, (cmb-0)*shade+0 + if (cmb.combine_ext) + { + T0CCMBEXT(GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_X, + GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_ITALPHA, 0, + GR_CMBX_B, 0); + cmb.tex |= 1; + cmb.tex_ccolor = rdp.env_color; + CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_ITALPHA, GR_FUNC_MODE_ZERO, + GR_CMBX_ITRGB, 0, + GR_CMBX_ZERO, 0); + } + else + { + cc_t0_mul_shade (); + } +} + +static void cc__t0_mul_prim_add_env__mul_shade () +{ + if (cmb.combine_ext) + { + T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, + GR_CMBX_TMU_CCOLOR, 0, + GR_CMBX_ZERO, 0); + cmb.tex |= 1; + cmb.tex_ccolor = rdp.prim_color; + CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_CONSTANT_COLOR, GR_FUNC_MODE_X, + GR_CMBX_ITRGB, 0, + GR_CMBX_ZERO, 0); + CC_ENV (); + } + else + { + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + MOD_0 (TMOD_TEX_SCALE_COL_ADD_COL); + MOD_0_COL (rdp.prim_color & 0xFFFFFF00); + MOD_0_COL1 (rdp.env_color & 0xFFFFFF00); + USE_T0 (); + } +} + +static void cc__t1_sub_t0_mul_primlod_add_prim__mul_shade () +{ + if (cmb.combine_ext) + { + T1CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, + GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, + GR_CMBX_ZERO, 0, + GR_CMBX_B, 0); + T0CCMBEXT(GR_CMBX_OTHER_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_DETAIL_FACTOR, 0, + GR_CMBX_ZERO, 0); + cmb.tex |= 3; + percent = (float)lod_frac / 255.0f; + cmb.dc0_detailmax = cmb.dc1_detailmax = percent; + CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_CONSTANT_COLOR, GR_FUNC_MODE_X, + GR_CMBX_ITRGB, 0, + GR_CMBX_ZERO, 0); + CC_PRIM (); + } + else + { + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + T0_INTER_T1_USING_FACTOR (lod_frac); + } +} + +static void cc__t1_sub_prim_mul_t0__mul_shade () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + if (cmb.combine_ext) + { + T1CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, + GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, + GR_CMBX_ZERO, 0, + GR_CMBX_B, 0); + T0CCMBEXT(GR_CMBX_OTHER_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_LOCAL_TEXTURE_RGB, 0, + GR_CMBX_ZERO, 0); + cmb.tex_ccolor = rdp.prim_color; + cmb.tex |= 3; + } + else + { + T0_MUL_T1 (); + } +} + +static void cc__t1_sub_t0_mul_t0_add_shade__mul_shade () //Aded by Gonetz +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + if (cmb.combine_ext) + { + T1CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, + GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, + GR_CMBX_ZERO, 0, + GR_CMBX_B, 0); + T0CCMBEXT(GR_CMBX_OTHER_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_LOCAL_TEXTURE_RGB, 0, + GR_CMBX_ITRGB, 0); + cmb.tex |= 3; + } + else + { + T1_SUB_T0_MUL_T0 (); + } +} + +static void cc__one_sub_shade_mul_t0_add_shade__mul_shade () +{ + if (cmb.combine_ext) + { + T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, + GR_CMBX_ITRGB, GR_FUNC_MODE_ONE_MINUS_X, + GR_CMBX_LOCAL_TEXTURE_RGB, 0, + GR_CMBX_B, 0); + cmb.tex |= 1; + CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_ZERO, GR_FUNC_MODE_ZERO, + GR_CMBX_ITRGB, 0, + GR_CMBX_ZERO, 0); + } + else + { + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_ONE_MINUS_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + USE_T0 (); + } +} + +static void cc__t0_sub_prim_mul_t1_add_t1__mul_shade () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + if (rdp.prim_color & 0xFFFFFF00) + { + MOD_0 (TMOD_TEX_SUB_COL); + MOD_0_COL (rdp.prim_color & 0xFFFFFF00); + } + if (cmb.combine_ext) + { + T1CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, + GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, + GR_CMBX_ZERO, 0, + GR_CMBX_B, 0); + T0CCMBEXT(GR_CMBX_OTHER_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_OTHER_TEXTURE_RGB, GR_FUNC_MODE_ZERO, + GR_CMBX_LOCAL_TEXTURE_RGB, 0, + GR_CMBX_B, 0); + cmb.tex |= 3; + } + else + { + T0_MUL_T1 (); + } +} + +static void cc__t1_sub_env_mul_t0_add_t0__mul_shade () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + if (cmb.combine_ext) + { + T1CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_ZERO, 1, + GR_CMBX_ZERO, 0); + T0CCMBEXT(GR_CMBX_OTHER_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, + GR_CMBX_LOCAL_TEXTURE_RGB, 0, + GR_CMBX_B, 0); + cmb.tex_ccolor = rdp.env_color; + cmb.tex |= 3; + } + else + { + MOD_1 (TMOD_TEX_SUB_COL); + MOD_1_COL (rdp.env_color & 0xFFFFFF00); + T0_MUL_T1_ADD_T0 (); + } +} + +static void cc__t0_mul_prima_add_prim_mul__shade () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + if (cmb.combine_ext) + { + T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_ZERO, + GR_CMBX_TMU_CALPHA, 0, + GR_CMBX_B, 0); + cmb.tex_ccolor = rdp.prim_color; + cmb.tex |= 1; + } + else + { + MOD_0 (TMOD_TEX_SCALE_FAC_ADD_COL); + MOD_0_COL (rdp.prim_color & 0xFFFFFF00); + MOD_0_FAC (rdp.prim_color & 0xFF); + USE_T0 (); + } +} + +static void cc__t0_inter_prim_using_prima__inter_env_using_enva () +{ + if (cmb.combine_ext) + { + T0CCMBEXT(GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_X, + GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_TMU_CALPHA, 0, + GR_CMBX_B, 0); + cmb.tex_ccolor = rdp.prim_color; + cmb.tex |= 1; + CCMBEXT(GR_CMBX_ITRGB, GR_FUNC_MODE_X, + GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_CONSTANT_COLOR, 0, + GR_CMBX_B, 0); + CC_ENVA (); + SETSHADE_ENV (); + } + else + { + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + CC_1SUBENVA (); + SETSHADE_ENV (); + SETSHADE_ENVA (); + MOD_0 (TMOD_TEX_INTER_COLOR_USING_FACTOR); + MOD_0_COL (rdp.prim_color & 0xFFFFFF00); + MOD_0_FAC (rdp.prim_color & 0xFF); + USE_T0 (); + } +} + +static void cc_prim_inter_t1_mul_shade_using_texa () +{ + if (cmb.combine_ext) + { + T1CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, + GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, + GR_CMBX_ZERO, 0, + GR_CMBX_B, 0); + T0CCMBEXT(GR_CMBX_OTHER_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, + GR_CMBX_ITRGB, 0, + GR_CMBX_ZERO, 0); + cmb.tex |= 3; + CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_CONSTANT_COLOR, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_TEXTURE_ALPHA, 0, + GR_CMBX_B, 0); + } + else + { + cc_t1_mul_shade (); + } +} + +static void cc__prim_inter_t0_using_t0a__mul_shade () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + if (cmb.combine_ext) + { + T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_LOCAL_TEXTURE_ALPHA, 0, + GR_CMBX_B, 0); + cmb.tex_ccolor = rdp.prim_color; + cmb.tex |= 1; + } + else + { + MOD_0 (TMOD_COL_INTER_TEX_USING_TEXA); + MOD_0_COL (rdp.prim_color & 0xFFFFFF00); + USE_T0 (); + } +} + +static void cc__prim_inter_t0_using_t0a__inter_env_using_enva () +{ + if (cmb.combine_ext) + { + T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_LOCAL_TEXTURE_ALPHA, 0, + GR_CMBX_B, 0); + cmb.tex_ccolor = rdp.prim_color; + cmb.tex |= 1; + CCMBEXT(GR_CMBX_ITRGB, GR_FUNC_MODE_X, + GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_CONSTANT_COLOR, 0, + GR_CMBX_B, 0); + CC_ENVA (); + SETSHADE_ENV (); + } + else + { + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + CC_1SUBENVA (); + SETSHADE_ENV (); + SETSHADE_ENVA (); + MOD_0 (TMOD_COL_INTER_TEX_USING_TEXA); + MOD_0_COL (rdp.prim_color & 0xFFFFFF00); + USE_T0 (); + } +} + +// ** A*B ** + +static void cc__prim_inter_t0_using_shadea__mul_shade () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + PRIM_INTER_T0_USING_SHADEA (); +} + +static void cc_t0_sub_shade_mul_shadea_add_shade (); +static void cc__shade_inter_t0_using_shadea__mul_shade () +{ + if (cmb.combine_ext) + { + T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_ITRGB, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_ITALPHA, 0, + GR_CMBX_B, 0); + cmb.tex |= 1; + CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_ITALPHA, GR_FUNC_MODE_ZERO, + GR_CMBX_ITRGB, 0, + GR_CMBX_ZERO, 0); + } + else + { + cc_t0_sub_shade_mul_shadea_add_shade (); + } +} + +static void cc__prim_inter_env_using_enva__mul_shade () +{ + const float ea = ((float)(rdp.env_color&0xFF)) / 255.0f; + const float ea_i = 1.0f - ea; + wxUint32 pr = (rdp.prim_color >> 24)&0xFF; + wxUint32 pg = (rdp.prim_color >> 16)&0xFF; + wxUint32 pb = (rdp.prim_color >> 8)&0xFF; + wxUint32 er = (rdp.env_color >> 24)&0xFF; + wxUint32 eg = (rdp.env_color >> 16)&0xFF; + wxUint32 eb = (rdp.env_color >> 8)&0xFF; + wxUint32 r = min(255, (wxUint32)(er*ea + pr*ea_i)); + wxUint32 g = min(255, (wxUint32)(eg*ea + pg*ea_i)); + wxUint32 b = min(255, (wxUint32)(eb*ea + pb*ea_i)); + wxUint32 col = (r << 24) | (g << 16) | (b << 8) | 0xFF; + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + CC (col); +} + +//Added by Gonetz +static void cc_prim_mul_env () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + CC_PRIM (); + SETSHADE_ENV (); +} + +static void cc_prim_mul_shade () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + CC_PRIM (); +} + +static void cc_prim_mul_shadea () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + SETSHADE_SHADE_A (); + CC_PRIM (); +} + +static void cc_env_mul_shade () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + CC_ENV (); +} + +static void cc_env_mul_enva () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_OTHER_ALPHA, + GR_COMBINE_LOCAL_NONE, + GR_COMBINE_OTHER_CONSTANT); + CC_ENV (); + CA_ENV (); +} + +static void cc_scale_mul_shade () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + CC (rdp.SCALE); +} + +// ** A+B ** + +static void cc_t0_add_prim () //Aded by Gonetz +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + CC_PRIM (); + USE_T0 (); +} + +static void cc__t0_mul_t1__add_prim () //Aded by Gonetz +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + CC_PRIM (); + T0_MUL_T1 (); +} + +static void cc_t0_add_env () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + CC_ENV (); + USE_T0 (); +} + +//Added by Gonetz +static void cc__t0_mul_t1__add_env () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + CC_ENV (); + T0_MUL_T1 (); +} + +static void cc__t0_mul_t1__add_env_mul__t0_mul_t1__add_env () +{ + if (cmb.combine_ext) + { + T1CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, + GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, + GR_CMBX_ZERO, 0, + GR_CMBX_B, 0); + T0CCMBEXT(GR_CMBX_OTHER_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_ZERO, + GR_CMBX_LOCAL_TEXTURE_RGB, 0, + GR_CMBX_B, 0); + cmb.tex_ccolor = rdp.env_color; + cmb.tex |= 3; + CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_ZERO, GR_FUNC_MODE_ZERO, + GR_CMBX_TEXTURE_RGB, 0, + GR_CMBX_ZERO, 0); + } + else + cc__t0_mul_t1__add_env(); +} + +static void cc_t0_add_shade () //Aded by Gonetz +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + USE_T0 (); +} + +static void cc__t0_mul_t1__add_shade () //Aded by Gonetz +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + T0_MUL_T1 (); +} + +static void cc_prim_add_env () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + CC_ENV (); + SETSHADE_PRIM (); +} + +static void cc_t0_add_prim_mul_one_sub_t0_add_t0 () //Aded by Gonetz +{ + if (cmb.combine_ext) + { + T0CCMBEXT(GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_X, + GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_LOCAL_TEXTURE_RGB, 1, + GR_CMBX_B, 0); + CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_ZERO, GR_FUNC_MODE_ZERO, + GR_CMBX_ZERO, 1, + GR_CMBX_ZERO, 0); + cmb.tex_ccolor = rdp.prim_color; + cmb.tex |= 1; + } + else + { + cc_t0_add_prim (); + } +} + +static void cc_one_sub_prim_mul_t0_add_prim(); +static void cc__one_sub_prim_mul_t0_add_prim__mul_prima_add__one_sub_prim_mul_t0_add_prim () //Aded by Gonetz +{ + if (cmb.combine_ext) + { + T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_ZERO, + GR_CMBX_TMU_CCOLOR, 1, + GR_CMBX_B, 0); + CCMBEXT(GR_CMBX_ZERO, GR_FUNC_MODE_ZERO, + GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_CONSTANT_COLOR, 0, + GR_CMBX_B, 0); + cmb.tex_ccolor = rdp.prim_color; + CC_PRIMA(); + cmb.tex |= 3; //hw frame buffer allocated as tile1, but not used in combiner + } + else + { + cc_one_sub_prim_mul_t0_add_prim(); + // cc_t0 (); + } +} + +static void cc_prim_add_shade () //Aded by Gonetz +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + CC_PRIM (); +} + +static void cc_env_add_shade () //Aded by Gonetz +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + CC_ENV (); +} + +static void cc_shade_add_shade () //Aded by Gonetz +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_ITERATED); +} + +// ** A-B ** +static void cc__t0_inter_t1_using_enva__sub_env () //Aded by Gonetz +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + CC_ENV (); + wxUint8 factor = (wxUint8)(rdp.env_color&0xFF); + T0_INTER_T1_USING_FACTOR (factor); +} + +static void cc_t0_sub__shade_mul_center () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + MULSHADE(rdp.CENTER); + USE_T0 (); +} + +// ** A-B*C ** +static void cc_env_sub__t0_sub_t1_mul_primlod__mul_prim () //Aded by Gonetz +{ + if (cmb.combine_ext) + { + T1CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, + GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, + GR_CMBX_ZERO, 0, + GR_CMBX_B, 0); + T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_OTHER_TEXTURE_RGB, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_ITRGB, 0, + GR_CMBX_ZERO, 0); + cmb.tex |= 3; + CCMBEXT(GR_CMBX_CONSTANT_COLOR, GR_FUNC_MODE_X, + GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_ZERO, 1, + GR_CMBX_ZERO, 0); + SETSHADE_PRIM (); + SETSHADE_PRIMLOD (); + CC_ENV (); + } + else + { + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + SETSHADE_PRIM (); + CC_ENV (); + T1_INTER_T0_USING_FACTOR (lod_frac); + } +} + +static void cc_env_sub__t0_mul_scale_add_env__mul_prim () +{ + if (cmb.combine_ext) + { + T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_ITRGB, GR_FUNC_MODE_ZERO, + GR_CMBX_TMU_CCOLOR, 0, + GR_CMBX_B, 0); + cmb.tex_ccolor = rdp.SCALE; + cmb.tex |= 1; + CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_ITRGB, GR_FUNC_MODE_ZERO, + GR_CMBX_CONSTANT_COLOR, 0, + GR_CMBX_B, 0); + SETSHADE_ENV (); + CC_PRIM (); + } + else + cc_t0_add_env (); +} + +static void cc_one_sub__one_sub_t0_mul_enva_add_prim__mul_prim () //Aded by Gonetz +{ + if (cmb.combine_ext) + { + T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ONE_MINUS_X, + GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_ZERO, + GR_CMBX_DETAIL_FACTOR, 0, + GR_CMBX_B, 0); + cmb.tex_ccolor = rdp.prim_color; + cmb.tex |= 1; + percent = (float)(rdp.env_color&0xFF) / 255.0f; + cmb.dc0_detailmax = cmb.dc1_detailmax = percent; + CCMBEXT(GR_CMBX_ZERO, GR_FUNC_MODE_X, + GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_CONSTANT_COLOR, 0, + GR_CMBX_ZERO, 1); + CC_PRIM (); + } + else + { + cc_one (); + } +} + +// ** A+B*C ** +//Aded by Gonetz +static void cc_t0_add_env_mul_k5 () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + float scale = rdp.K5 / 255.0f; + wxUint8 r = (wxUint8)(rdp.env_color >> 24) & 0xFF; + r = (wxUint8)(r*scale); + wxUint8 g = (wxUint8)(rdp.env_color >> 16) & 0xFF; + g = (wxUint8)(g*scale); + wxUint8 b = (wxUint8)(rdp.env_color >> 8) & 0xFF; + b = (wxUint8)(b*scale); + CC((r<<24)|(g<<16)|(b<<8)); + USE_T0 (); +} + +static void cc_t0_add_shade_mul_env () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + MULSHADE_ENV (); + USE_T0 (); +} + +static void cc__t1_mul_t0_add_t0__add_prim_mul_shade () //Aded by Gonetz +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + MULSHADE_PRIM (); + rdp.best_tex = 0; + cmb.tex |= 3; + cmb.tmu1_func = GR_COMBINE_FUNCTION_LOCAL; + cmb.tmu0_func = GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL; + cmb.tmu0_fac = GR_COMBINE_FACTOR_LOCAL; +} + +static void cc__t0_sub_env_mul_enva__add_prim_mul_shade () +{ + if (cmb.combine_ext) + { + T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_DETAIL_FACTOR, 0, + GR_CMBX_ZERO, 0); + cmb.tex_ccolor = rdp.env_color; + cmb.tex |= 1; + percent = (float)(rdp.env_color&0xFF) / 255.0f; + cmb.dc0_detailmax = cmb.dc1_detailmax = percent; + + CCMBEXT(GR_CMBX_ITRGB, GR_FUNC_MODE_X, + GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_ZERO, + GR_CMBX_CONSTANT_COLOR, 0, + GR_CMBX_B, 0); + CC_PRIM (); + } + else { + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + MULSHADE_PRIM (); + MOD_0 (TMOD_TEX_SUB_COL_MUL_FAC); + MOD_0_COL (rdp.env_color & 0xFFFFFF00); + MOD_0_FAC (rdp.env_color & 0xFF); + USE_T0 (); + } +} + +// ** A*B+C ** +//Added by Gonetz +static void cc_t0_mul_prim_add_t1 () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_NONE, + GR_COMBINE_OTHER_TEXTURE); + if (cmb.combine_ext) + { + T1CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, + GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, + GR_CMBX_ZERO, 0, + GR_CMBX_B, 0); + T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_OTHER_TEXTURE_RGB, GR_FUNC_MODE_ZERO, + GR_CMBX_TMU_CCOLOR, 0, + GR_CMBX_B, 0); + cmb.tex |= 3; + cmb.tex_ccolor = rdp.prim_color; + } + else + { + MOD_0 (TMOD_TEX_MUL_COL); + MOD_0_COL (rdp.prim_color & 0xFFFFFF00); + T0_ADD_T1 (); + } +} + +static void cc_shirt () +{ + // (t1-0)*prim+0, (1-t0)*t1+cmb + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_NONE, + GR_COMBINE_OTHER_TEXTURE); + if (cmb.combine_ext) + { + /* + T1CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, + GR_CMBX_TMU_CCOLOR, 0, + GR_CMBX_ZERO, 0); + //*/ + //* + T1CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, + GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, + GR_CMBX_ZERO, 0, + GR_CMBX_B, 0); + //*/ + T0CCMBEXT(GR_CMBX_OTHER_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, + GR_CMBX_LOCAL_TEXTURE_RGB, 1, + GR_CMBX_B, 0); + cmb.tex |= 3; + cmb.tex_ccolor = rdp.prim_color; + } + else + { + MOD_1 (TMOD_TEX_MUL_COL); + MOD_1_COL (rdp.prim_color & 0xFFFFFF00); + T0_ADD_T1 (); + } +} + +static void cc_t1_mul_prim_add_prim () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + SETSHADE_PRIM (); + CC_PRIM (); + USE_T0 (); +} + +//Added by Gonetz +static void cc_t0_mul_prim_add_env () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + SETSHADE_PRIM (); + CC_ENV (); + USE_T0 (); +} + +//Added by Gonetz +static void cc_t1_mul_prim_add_env () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + SETSHADE_PRIM (); + CC_ENV (); + USE_T1 (); +} + +static void cc__t0_add_primlod__mul_prim_add_env () +{ + if (cmb.combine_ext) + { + T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_X, + GR_CMBX_ZERO, 1, + GR_CMBX_ZERO, 0); + CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_CONSTANT_COLOR, GR_FUNC_MODE_ZERO, + GR_CMBX_ITRGB, 0, + GR_CMBX_B, 0); + CC_PRIMLOD (); + cmb.tex_ccolor = cmb.ccolor; + CC_ENV (); + SETSHADE_PRIM (); + cmb.tex |= 1; + } + else + { + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + CC_PRIMLOD (); + MOD_0 (TMOD_TEX_ADD_COL); + MOD_0_COL (cmb.ccolor & 0xFFFFFF00); + SETSHADE_PRIM (); + CC_ENV (); + USE_T0 (); + } +} + +//Added by Gonetz +static void cc_t0_mul_prim_mul_shade_add_prim_mul_shade () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + MULSHADE_PRIM (); + USE_T0 (); +} + +//Added by Gonetz +static void cc__t0_inter_t1_using_primlod__mul_prim_add_env () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + SETSHADE_PRIM (); + CC_ENV (); + T0_INTER_T1_USING_FACTOR (lod_frac); +} + +static void cc__t1_sub_prim_mul_enva_add_t0__mul_prim_add_env () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + CC_PRIM (); + SETSHADE_ENV (); + if (cmb.combine_ext) + { + T1CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_DETAIL_FACTOR, 0, + GR_CMBX_ZERO, 0); + T0CCMBEXT(GR_CMBX_OTHER_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_ZERO, 1, + GR_CMBX_ZERO, 0); + cmb.tex_ccolor = rdp.prim_color; + cmb.tex |= 3; + percent = (float)(rdp.env_color&0xFF) / 255.0f; + cmb.dc0_detailmax = cmb.dc1_detailmax = percent; + } + else + { + MOD_1 (TMOD_TEX_SUB_COL_MUL_FAC); + MOD_1_COL (rdp.prim_color & 0xFFFFFF00); + MOD_1_FAC (rdp.env_color & 0xFF); + T0_ADD_T1 (); + } +} + +//Added by Gonetz +static void cc__t0_inter_t1_using_primlod__mul_shade_add_env () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + CC_ENV (); + T0_INTER_T1_USING_FACTOR (lod_frac); +} + +//Added by Gonetz +static void cc__t1_sub_prim_mul_primlod_add_t0__mul_prim_add_env () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + SETSHADE_PRIM (); + CC_ENV (); + T1_SUB_PRIM_MUL_PRIMLOD_ADD_T0 (); +} + +//Aded by Gonetz +static void cc__t0_mul_t1__mul_prim_add_env () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + CC_ENV (); + MULSHADE_PRIM (); + T0_MUL_T1 (); +} + +//Aded by Gonetz +static void cc__t0_mul_t1__sub_prim_mul_env_add_shade () +{ + if (cmb.combine_ext) + { + T1CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, + GR_CMBX_TMU_CCOLOR, 0, + GR_CMBX_ZERO, 0); + T0CCMBEXT(GR_CMBX_OTHER_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_ITRGB, GR_FUNC_MODE_ZERO, + GR_CMBX_LOCAL_TEXTURE_RGB, 0, + GR_CMBX_B, 0); + cmb.tex_ccolor = rdp.env_color; + cmb.tex |= 3; + CCMBEXT(GR_CMBX_ITRGB, GR_FUNC_MODE_ZERO, + GR_CMBX_CONSTANT_COLOR, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_ZERO, 1, + GR_CMBX_TEXTURE_RGB, 0); + CC_PRIMMULENV (); + } + else + { + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + CC_ENV (); + T0_MUL_T1 (); + } +} + +static void cc__t0_sub_prim_mul_t1_add_t1__mul_env_add_shade () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + CC_ENV (); + if (rdp.prim_color & 0xFFFFFF00) + { + MOD_0 (TMOD_TEX_SUB_COL); + MOD_0_COL (rdp.prim_color & 0xFFFFFF00); + } + if (cmb.combine_ext) + { + T1CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, + GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, + GR_CMBX_ZERO, 0, + GR_CMBX_B, 0); + T0CCMBEXT(GR_CMBX_OTHER_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_OTHER_TEXTURE_RGB, GR_FUNC_MODE_ZERO, + GR_CMBX_LOCAL_TEXTURE_RGB, 0, + GR_CMBX_B, 0); + cmb.tex |= 3; + } + else + { + T0_MUL_T1 (); + } +} + +static void cc__t0_mul_t1__mul_shade_add_prim () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + CC_PRIM (); + T0_MUL_T1 (); +} + +static void cc__t0_mul_shadea_add_env__mul_shade_add_prim () +{ + if (cmb.combine_ext) + { + T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_ZERO, + GR_CMBX_ITALPHA, 0, + GR_CMBX_B, 0); + cmb.tex_ccolor = rdp.env_color; + cmb.tex |= 1; + CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_CONSTANT_COLOR, GR_FUNC_MODE_ZERO, + GR_CMBX_ITRGB, 0, + GR_CMBX_B, 0); + CC_PRIM (); + } + else + { + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + MULSHADE_SHADEA (); + CC_PRIM (); + USE_T0 (); + } +} + +static void cc__t0_mul_t1__mul_shade_add_env () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + CC_ENV (); + T0_MUL_T1 (); +} + +//Added by Gonetz +static void cc__t0_add_t1__mul_shade_add_env () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + CC_ENV (); + T0_ADD_T1 (); +} + +static void cc__t1_mul_prima_add_t0__mul_shade_add_env () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + CC_ENV (); + T1_MUL_PRIMA_ADD_T0 (); +} + +static void cc__t0_inter_t1_using_enva__mul_shade_add_prim () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + CC_PRIM (); + wxUint8 factor = (wxUint8)(rdp.env_color&0xFF); + T0_INTER_T1_USING_FACTOR (factor); +} + +static void cc__t0_inter_t1_using_enva__mul_shade_add_env () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + CC_ENV (); + wxUint8 factor = (wxUint8)(rdp.env_color&0xFF); + T0_INTER_T1_USING_FACTOR (factor); +} + +//Added by Gonetz +static void cc_t0_mul_primlod_add_prim () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + SETSHADE_PRIM (); + CC_PRIMLOD (); + USE_T0 (); +} + +static void cc__t0_mul_primlod__add__prim_mul_shade () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + MULSHADE_PRIM (); + CC_PRIMLOD (); + USE_T0 (); +} + +//Added by Gonetz +static void cc_t0_mul_primlod_add_prim_mul_shade_add_env () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + MULSHADE_PRIM (); + ADDSHADE_ENV (); + CC_PRIMLOD (); + USE_T0 (); +} + +//Added by Gonetz +static void cc_t1_mul_primlod_add_prim_mul_shade_add_env () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + MULSHADE_PRIM (); + ADDSHADE_ENV (); + CC_PRIMLOD (); + USE_T1 (); +} + +static void cc__t0_inter_t1_using_primlod__mul_shade_add_prim () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + CC_PRIM (); + T0_INTER_T1_USING_FACTOR (lod_frac); +} + +static void cc__t1_inter_t0_using_primlod__mul_shade_add_prim () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + CC_PRIM (); + T1_INTER_T0_USING_FACTOR (lod_frac); +} + +//Added by Gonetz +static void cc__t1_sub_t0_mul_primlod_add_prim__mul_shade_add_shade () +{ + if (cmb.combine_ext) + { + T1CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, + GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, + GR_CMBX_ZERO, 0, + GR_CMBX_B, 0); + T0CCMBEXT(GR_CMBX_OTHER_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_DETAIL_FACTOR, 0, + GR_CMBX_ZERO, 0); + cmb.tex |= 3; + percent = (float)lod_frac / 255.0f; + cmb.dc0_detailmax = cmb.dc1_detailmax = percent; + CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_CONSTANT_COLOR, GR_FUNC_MODE_X, + GR_CMBX_ITRGB, 0, + GR_CMBX_ITRGB, 0); + CC_PRIM (); + } + else + { + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + T0_INTER_T1_USING_FACTOR (lod_frac); + } +} + +//Added by Gonetz +static void cc__t0_inter_t1_using_half__mul_prim_add_env () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + SETSHADE_PRIM (); + CC_ENV (); + T0_INTER_T1_USING_FACTOR (0x7F); +} + +//Added by Gonetz +static void cc__t0_inter_t1_using_t1__mul_prim_add_shade () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + CC_PRIM (); + T0_INTER_T1_USING_T1 (); +} + +//Added by Gonetz +static void cc_one_sub_t1_mul_t0a_add_t0_mul_env_add_prim () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + CC_PRIM (); + MOD_0 (TMOD_TEX_MUL_COL); + MOD_0_COL (rdp.env_color & 0xFFFFFF00); + rdp.best_tex = 0; + cmb.tex |= 3; + cmb.tmu1_func = GR_COMBINE_FUNCTION_LOCAL; + cmb.tmu1_invert = 1; + cmb.tmu0_func = GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL; + cmb.tmu0_fac = GR_COMBINE_FACTOR_LOCAL_ALPHA; +} + +//Added by Gonetz +static void cc__t0_inter_t1_using_t1__mul_shade_add_prim () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + CC_PRIM (); + T0_INTER_T1_USING_T1 (); +} + +//Added by Gonetz +static void cc_t0_mul_prim_add_shade () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + CC_PRIM (); + USE_T0 (); +} + +static void cc_t1_mul_prim_add_shade () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + CC_PRIM (); + USE_T1 (); +} + +//Added by Gonetz +static void cc_t0_mul_env_add_prim () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + SETSHADE_ENV (); + CC_PRIM (); + USE_T0 (); +} + +//Added by Gonetz +static void cc_t1_mul_env_add_prim () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + SETSHADE_ENV (); + CC_PRIM (); + USE_T1 (); +} + +static void cc_t0_mul_scale_add_prim () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + SETSHADE (rdp.SCALE); + CC_PRIM (); + USE_T0 (); +} + +//Added by Gonetz +static void cc__t0_mul_t1__mul_env_add_prim () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + SETSHADE_ENV (); + CC_PRIM (); + T0_MUL_T1 (); +} + +//Added by Gonetz +static void cc__t0_add__t1_mul_scale__mul_env_sub_center_add_prim () +{ + // (t1-0)*scale+t0, (env-center)*cmb+prim + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + CC_C1SUBC2(rdp.env_color, rdp.CENTER); + SETSHADE_PRIM (); + MOD_1 (TMOD_TEX_MUL_COL); + MOD_1_COL (rdp.SCALE & 0xFFFFFF00); + T0_ADD_T1 (); +} + +//Added by Gonetz +static void cc__t1_sub_t0__mul_env_add_prim () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + SETSHADE_ENV (); + CC_PRIM (); + T1_SUB_T0 (); +} + +//Added by Gonetz +static void cc_t0_mul_env_add_shade () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + CC_ENV (); + USE_T0 (); +} + +static void cc_t0_mul_shade_add_prim () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + CC_PRIM (); + USE_T0 (); +} + +static void cc__t0_mul_enva_add_t1__mul_shade_add_prim () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + CC_PRIM (); + if (cmb.combine_ext) + { + T1CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, + GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_ZERO, 1, + GR_CMBX_ZERO, 0); + T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_OTHER_TEXTURE_RGB, GR_FUNC_MODE_ZERO, + GR_CMBX_DETAIL_FACTOR, 0, + GR_CMBX_B, 0); + cmb.tex |= 3; + percent = (float)(rdp.env_color&0xFF) / 255.0f; + cmb.dc0_detailmax = cmb.dc1_detailmax = percent; + } + else + { + T0_ADD_T1 (); + } +} + +static void cc_t0_mul_shade_add_prima () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + CC_PRIMA (); + USE_T0 (); +} + +static void cc_t1_mul_shade_add_prim () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + CC_PRIM (); + USE_T1 (); +} + +static void cc_t0_mul_shade_add_env () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + CC_ENV (); + USE_T0 (); +} + +static void cc__t0_add_prim__mul_shade_add_t0 () +{ + if (cmb.combine_ext) + { + CCMBEXT(GR_CMBX_CONSTANT_COLOR, GR_FUNC_MODE_X, + GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_ITRGB, 0, + GR_CMBX_B, 0); + CC_PRIM (); + } + else + { + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + // MOD_0 (TMOD_TEX_ADD_COL); + // MOD_0_COL (rdp.prim_color & 0xFFFFFF00); + } + USE_T0 (); +} + +static void cc__t0_add_prim__mul_shade_add_t1 () +{ + if (cmb.combine_ext) + { + T1CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, + GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, + GR_CMBX_ZERO, 0, + GR_CMBX_B, 0); + T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_OTHER_TEXTURE_RGB, GR_FUNC_MODE_ZERO, + GR_CMBX_ITRGB, 0, + GR_CMBX_B, 0); + cmb.tex |= 3; + CCMBEXT(GR_CMBX_CONSTANT_COLOR, GR_FUNC_MODE_X, + GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_ZERO, + GR_CMBX_ITRGB, 0, + GR_CMBX_B, 0); + CC_PRIM (); + } + else + { + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + MULSHADE_PRIM (); + T0_ADD_T1 (); + } +} + +static void cc__t0_add_primlod__mul_shade_add_env () +{ + if (cmb.combine_ext) + { + T1CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_X, + GR_CMBX_ZERO, 1, + GR_CMBX_ZERO, 0); + T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_X, + GR_CMBX_ZERO, 1, + GR_CMBX_ZERO, 0); + CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_CONSTANT_COLOR, GR_FUNC_MODE_ZERO, + GR_CMBX_ITRGB, 0, + GR_CMBX_B, 0); + CC_PRIMLOD (); + cmb.tex_ccolor = cmb.ccolor; + CC_ENV (); + cmb.tex |= 1; + } + else + { + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + wxUint32 color = (lod_frac<<24) | (lod_frac<<16) | (lod_frac<<8); + MOD_0 (TMOD_TEX_ADD_COL); + MOD_0_COL (color & 0xFFFFFF00); + CC_ENV (); + USE_T0 (); + } +} + +static void cc__t0_mul_prima_add_prim_mul__shade_add_env () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + CC_ENV (); + if (cmb.combine_ext) + { + T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_ZERO, + GR_CMBX_TMU_CALPHA, 0, + GR_CMBX_B, 0); + cmb.tex_ccolor = rdp.prim_color; + cmb.tex |= 1; + } + else + { + MOD_0 (TMOD_TEX_SCALE_FAC_ADD_COL); + MOD_0_COL (rdp.prim_color & 0xFFFFFF00); + MOD_0_FAC (rdp.prim_color & 0xFF); + USE_T0 (); + } +} + +//Added by Gonetz +static void cc_t0_mul_shadea_add_shade () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_LOCAL_ALPHA, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + USE_T0 (); +} + +static void cc_prim_mul_prima_add_prim () //Added by Gonetz +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_LOCAL_ALPHA, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + CC_PRIM (); + CA_PRIM (); + SETSHADE_PRIM (); +} + +static void cc_prim_mul_prima_add_t0 () //Added by Gonetz +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + SETSHADE_PRIM (); + SETSHADE_PRIMA (); + USE_T0 (); +} + +static void cc_prim_mul_env_add_t0 () //Added by Gonetz +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + SETSHADE_PRIM (); + SETSHADE_ENV (); + USE_T0 (); +} + +static void cc_prim_mul_shade_add_t0 () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + MULSHADE_PRIM (); + USE_T0 (); +} + +static void cc_prim_mul_shade_add_env () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + CC_ENV (); + MULSHADE_PRIM (); +} + +static void cc_env_mul_shade_add_env () //Added by Gonetz +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + CC_ENV (); + MULSHADE_ENV (); +} + +// ** A*B+C*D ** +static void cc_t0_mul_prim_add_one_sub_prim_mul_shade () //Added by Gonetz +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + CC_PRIM (); + MULSHADE_1MPRIM (); + USE_T0 (); +} + +static void cc_t0_mul_prim_add_shade_sub_env_mul_prim () //Added by Gonetz +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + CC_PRIM (); + SUBSHADE_ENV () + MULSHADE_PRIM (); + USE_T0 (); +} + +static void cc_t0_mul_prim_add_shade_mul_shadea_mul_prim () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + CC_PRIM (); + MULSHADE_PRIM (); + MULSHADE_SHADEA (); + USE_T0 (); +} + +static void cc__t0_mul_t1__mul_prim_add_prim_mul_shade () //Added by Gonetz +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + MULSHADE_PRIM (); + CC_PRIM (); + T0_MUL_T1 (); +} + +static void cc_t0_mul_env_add_prim_mul_shade () //Added by Gonetz +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + MULSHADE_PRIM (); + CC_ENV (); + USE_T0 (); +} + +static void cc_t0_mul_enva_add_prim_mul_shade () //Added by Gonetz +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + MULSHADE_PRIM (); + CC_ENVA (); + USE_T0 (); +} + +static void cc_t0_mul_shade_add_prim_mul_env () //Added by Gonetz +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + CC_PRIMMULENV (); + USE_T0 (); +} + +static void cc_prim_mul_env_add_one_sub_prim_mul_shade () //Added by Gonetz +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + MULSHADE_1MPRIM (); + CC_PRIMMULENV (); +} + +// ** A*B*C ** + +static void cc_t0_mul_prim_mul_prim () //Added by Gonetz +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + SETSHADE_PRIM (); + SETSHADE_PRIM (); + USE_T0 (); +} + +static void cc_t0_mul_prim_mul_prima () //Added by Gonetz +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + SETSHADE_PRIM (); + SETSHADE_PRIMA (); + USE_T0 (); +} + +static void cc_t0_mul_enva_mul_shade () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + MULSHADE_ENVA (); + USE_T0 (); +} + +static void cc_t0_mul_primlod_mul_prim () //Added by Gonetz +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + CC_COLMULBYTE (rdp.prim_color, rdp.prim_lodfrac); + USE_T0 (); +} + +static void cc_t0_mul_primlod_mul_shade () //Added by Gonetz +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + MULSHADE_PRIMLOD (); + USE_T0 (); +} + +static void cc__t0_mul_t1__mul_prim () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + CC_PRIM (); + T0_MUL_T1 (); +} + +static void cc__t1_mul_t1_add_t0__mul_prim () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + CC_PRIM (); + if (cmb.combine_ext) + { + T1CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, + GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, + GR_CMBX_ZERO, 0, + GR_CMBX_B, 0); + T0CCMBEXT(GR_CMBX_OTHER_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, + GR_CMBX_OTHER_TEXTURE_RGB, 0, + GR_CMBX_B, 0); + cmb.tex |= 3; + } + else + { + T0_ADD_T1 (); + } +} + +static void cc__t0_mul_t1__mul_prima () //Added by Gonetz +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + CC_PRIMA (); + T0_MUL_T1 (); +} + +static void cc__t0_mul_t1__mul_env () //Added by Gonetz +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + CC_ENV (); + T0_MUL_T1 (); +} + +static void cc__t0_mul_t1__mul_enva () //Added by Gonetz +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + CC_ENVA (); + T0_MUL_T1 (); +} + +static void cc__t0_mul_t1__mul_shade () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + T0_MUL_T1 (); +} + +static void cc__t0a_mul_t1__mul_prim () //Added by Gonetz +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + CC_PRIM (); + T0A_MUL_T1 (); +} + +static void cc__t0_mul_t1a__mul_shade () //Added by Gonetz +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + T0_MUL_T1A (); +} + +static void cc__t0a_mul_t1__mul_shade () //Added by Gonetz +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + T0A_MUL_T1 (); +} + +static void cc_t0_mul_prim_mul_env () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + SETSHADE_PRIM (); + SETSHADE_ENV (); // notice that setshade multiplies + USE_T0 (); +} + +static void cc_t0_mul_prim_mul_shade () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + MULSHADE_PRIM (); + USE_T0 (); +} + +static void cc_t0_mul_prim_mul_shadea () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + SETSHADE_PRIM (); + MULSHADE_SHADEA(); + USE_T0 (); +} + +static void cc_t0_mul_prima_mul_shade () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + MULSHADE_PRIMA (); + USE_T0 (); +} + +static void cc_t1_mul__one_sub_prim_mul_shade_add_prim () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + MULSHADE_1MPRIM (); + ADDSHADE_PRIM (); + USE_T1 (); +} + +static void cc_t0_mul_one_sub_env_mul_shade () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + MULSHADE_1MENV (); + USE_T0 (); +} + +static void cc_t1_mul_prim_mul_shade () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + MULSHADE_PRIM (); + USE_T1 (); +} + +//Added by Gonetz +static void cc_t0_mul_1mprim_mul_shade () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + MULSHADE_1MPRIM (); + USE_T0 (); +} + +static void cc_t0_mul_env_mul_shade () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + MULSHADE_ENV (); + USE_T0 (); +} + +static void cc_t0_mul_scale_mul_shade () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + MULSHADE (rdp.SCALE); + USE_T0 (); +} + +static void cc_t0_mul_shade_mul_shadea () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + MULSHADE_SHADEA (); + USE_T0 (); +} + +static void cc_prim_mul_env_mul_shade () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + CC_ENV (); + MULSHADE_PRIM (); +} + +static void cc_prim_mul_one_sub_env_mul_shade () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + CC_1SUBENV (); + MULSHADE_PRIM (); +} + +// ** A*B*C+D ** +static void cc_t0_mul_prim_mul_shade_add_env () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + CC_ENV (); + MULSHADE_PRIM (); + USE_T0 (); +} + +//Added by Gonetz +static void cc_t0_mul_prim_mul_shadea_add_env () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_LOCAL_ALPHA, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + CC_ENV (); + SETSHADE_ENV (); + MULSHADE_A_PRIM (); + USE_T0 (); +} + +// (A*B+C)*D +static void cc__t0_mul_prim_add_shade__mul_env () +{ + if (cmb.combine_ext) + { + T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_ITRGB, GR_FUNC_MODE_ZERO, + GR_CMBX_TMU_CCOLOR, 0, + GR_CMBX_B, 0); + cmb.tex |= 1; + cmb.tex_ccolor = rdp.prim_color; + CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_ITRGB, GR_FUNC_MODE_ZERO, + GR_CMBX_CONSTANT_COLOR, 0, + GR_CMBX_ZERO, 0); + CC_ENV (); + } + else + { + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + MULSHADE_ENV (); + MOD_0 (TMOD_TEX_MUL_COL); + CC_PRIMMULENV (); + MOD_0_COL (cmb.ccolor & 0xFFFFFF00); + USE_T0 (); + } +} + +static void cc__t0a_mul_prim_add_t0__mul_shade () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + MOD_0 (TMOD_COL_MUL_TEXA_ADD_TEX); + MOD_0_COL (rdp.prim_color & 0xFFFFFF00); + USE_T0 (); +} + +static void cc__t0a_mul_env_add_t0__mul_shade () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + MOD_0 (TMOD_COL_MUL_TEXA_ADD_TEX); + MOD_0_COL (rdp.env_color & 0xFFFFFF00); + USE_T0 (); +} + +static void cc__prim_mul_shade_add_env__mul_shade () //Aded by Gonetz +{ + if (!cmb.combine_ext) + { + cc_prim_mul_shade_add_env (); + return; + } + T0CCMBEXT(GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_X, + GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, + GR_CMBX_ITRGB, 0, + GR_CMBX_ZERO, 0); + cmb.tex |= 1; + cmb.tex_ccolor = rdp.prim_color; + CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_CONSTANT_COLOR, GR_FUNC_MODE_X, + GR_CMBX_ITRGB, 0, + GR_CMBX_ZERO, 0); + CC_ENV (); +} + +// ** A*B*C+D*E ** +//Added by Gonetz +static void cc__t0_sub_t1__mul_prim_mul_shade_add_prim_mul_env () +{ + if (cmb.combine_ext) + { + T1CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, + GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, + GR_CMBX_ZERO, 0, + GR_CMBX_B, 0); + T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_OTHER_TEXTURE_RGB, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_ZERO, 1, + GR_CMBX_ZERO, 0); + cmb.tex |= 3; + } + else + { + USE_T0 (); + } + + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + CC_PRIMMULENV (); + MULSHADE_PRIM (); +} + +static void cc__t0_mul_prim_mul_env__add__prim_mul_shade () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + CC_PRIMMULENV (); + MULSHADE_PRIM (); + USE_T0 (); +} + +static void cc__t1_mul_prim_mul_env__add__prim_mul_shade () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + CC_PRIMMULENV (); + MULSHADE_PRIM (); + USE_T1 (); +} + +//Added by Gonetz +static void cc_t0_mul_one_sub_prim_mul_shade_add_prim_mul_env () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + CC_PRIMMULENV (); + MULSHADE_1MPRIM (); + USE_T0 (); +} + +//Added by Gonetz +static void cc_t0_mul_one_sub_prim_mul_shadea_add_prim_mul_env () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + CC_PRIMMULENV (); + SETSHADE_1MPRIM (); + MULSHADE_SHADEA (); + USE_T0 (); +} + +//Added by Gonetz +static void cc_t0_mul_one_sub_env_mul_shade_add_env () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + CC_ENV (); + MULSHADE_1MENV (); + USE_T0 (); +} + +static void cc_t0_mul_prima_mul_shade_add_prim_mul_one_sub_prima () //Aded by Gonetz +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + MULSHADE_PRIMA (); + USE_T0 (); + wxUint8 fac = 255 - (wxUint8)(rdp.prim_color&0xFF); + float col[3]; + col[0] = (float)((rdp.prim_color & 0xFF000000) >> 24) / 255.0f; + col[1] = (float)((rdp.prim_color & 0x00FF0000) >> 16) / 255.0f; + col[2] = (float)((rdp.prim_color & 0x0000FF00) >> 8) / 255.0f; + CC ( ((wxUint8)(col[0]*fac))<<24 | ((wxUint8)(col[1]*fac))<<16 | ((wxUint8)(col[2]*fac))<<8 | fac ); +} + +// ** A*(1-B)+C ** +static void cc_t0_mul_1menv_add_prim () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + CC_PRIM (); + SETSHADE_1MENV (); + USE_T0 (); +} + +// ** (A+B)*C ** +static void cc_t0_mul_scale_add_prim__mul_shade () //Aded by Gonetz +{ + if (cmb.combine_ext) + { + T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, + GR_CMBX_TMU_CCOLOR, 0, + GR_CMBX_ZERO, 0); + cmb.tex |= 1; + cmb.tex_ccolor = rdp.SCALE; + CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_CONSTANT_COLOR, GR_FUNC_MODE_X, + GR_CMBX_ITRGB, 0, + GR_CMBX_ZERO, 0); + CC_PRIM (); + } + else + { + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + MOD_0 (TMOD_TEX_ADD_COL); + MOD_0_COL (rdp.prim_color & 0xFFFFFF00); + USE_T0 (); + } +} + +static void cc__t0_mul_t1_add_prim__mul_shade () //Aded by Gonetz +{ + if (cmb.combine_ext) + { + CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_CONSTANT_COLOR, GR_FUNC_MODE_X, + GR_CMBX_ITRGB, 0, + GR_CMBX_ZERO, 0); + CC_PRIM (); + } + else + { + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + MULSHADE_PRIM (); + } + T0_MUL_T1 (); +} + +static void cc_t0_mul__prim_add_env () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + SETSHADE_PRIM (); + ADDSHADE_ENV (); + USE_T0 (); +} + +static void cc_t0_mul__prim_mul_primlod_add_env () //Aded by Gonetz +{ + // forest behind window, Dobutsu no Mori. + // (prim-0)*prim_lod+env, (t1-0)*cmb+0 + //actually, the game uses t0 instead of t1 here. t1 does not set at all this moment. + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + float prim_lod = rdp.prim_lodfrac / 65025.0f; + rdp.col[0] *= ((rdp.prim_color & 0xFF000000) >> 24) * prim_lod; + rdp.col[1] *= ((rdp.prim_color & 0x00FF0000) >> 16) * prim_lod; + rdp.col[2] *= ((rdp.prim_color & 0x0000FF00) >> 8) * prim_lod; + rdp.cmb_flags = CMB_SET; + ADDSHADE_ENV (); + USE_T0 (); +} + +// ** (A-B)*C ** +static void cc__t0_mul_prim_add_shade__sub_env_mul_shade () +{ + if (cmb.combine_ext) + { + T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_ITRGB, GR_FUNC_MODE_ZERO, + GR_CMBX_TMU_CCOLOR, 0, + GR_CMBX_B, 0); + cmb.tex_ccolor = rdp.prim_color; + cmb.tex |= 1; + CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_CONSTANT_COLOR, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_ITRGB, 0, + GR_CMBX_ZERO, 0); + CC_ENV (); + } + else + { + cc_t0_mul_prim_mul_shade (); + } +} + +static void cc_t0_sub_prim_mul_shadea () //Aded by Gonetz +{ + // * not guaranteed to work if another iterated alpha is set + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL, + GR_COMBINE_FACTOR_LOCAL_ALPHA, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + SETSHADE_PRIM (); + USE_T0 (); +} + +static void cc__t0_sub_env_mul_shade__sub_prim_mul_shade () +{ + if (cmb.combine_ext) + { + T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_ITRGB, 0, + GR_CMBX_ZERO, 0); + cmb.tex_ccolor = rdp.env_color; + cmb.tex |= 1; + CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_CONSTANT_COLOR, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_ITRGB, 0, + GR_CMBX_ITRGB, 0); + CC_PRIM (); + } + else + { + cc_t0_mul_shade (); + } +} + +static void cc_t0_sub_prim_mul_shade () +{ + if (cmb.combine_ext) + { + CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_CONSTANT_COLOR, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_ITRGB, 0, + GR_CMBX_ZERO, 0); + CC_PRIM (); + } + else + { + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + if (rdp.prim_color & 0xFFFFFF00) + { + MOD_0 (TMOD_TEX_SUB_COL); + MOD_0_COL (rdp.prim_color & 0xFFFFFF00); + } + } + USE_T0 (); +} + +static void cc__t0_mul_t1__sub_prim_mul_shade () +{ + if (cmb.combine_ext) + { + CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_CONSTANT_COLOR, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_ITRGB, 0, + GR_CMBX_ZERO, 0); + CC_PRIM (); + } + else + { + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + } + T0_MUL_T1 (); +} + +static void cc_t0_sub_env_mul_shade () +{ + if (cmb.combine_ext) + { + CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_CONSTANT_COLOR, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_ITRGB, 0, + GR_CMBX_ZERO, 0); + CC_ENV (); + } + else + { + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + if (rdp.env_color & 0xFFFFFF00) + { + MOD_0 (TMOD_TEX_SUB_COL); + MOD_0_COL (rdp.env_color & 0xFFFFFF00); + } + } + USE_T0 (); +} + +static void cc__t0_mul_prima_add_t0__sub_center_mul_scale () +{ + if (cmb.combine_ext) + { + T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, + GR_CMBX_TMU_CCOLOR, 0, + GR_CMBX_B, 0); + wxUint32 prima = rdp.prim_color&0xFF; + cmb.tex_ccolor = (prima<<24)|(prima<<16)|(prima<<8)|prima; + cmb.tex |= 1; + CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_CONSTANT_COLOR, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_ITRGB, 0, + GR_CMBX_ZERO, 0); + CC(rdp.CENTER); + SETSHADE(rdp.SCALE); + } + else + { + cc_t0_mul_prima(); + } +} + +static void cc__t1_inter_t0_using_primlod__sub_shade_mul_prim () +{ + if (cmb.combine_ext) + { + CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_ITRGB, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_CONSTANT_COLOR, 0, + GR_CMBX_ZERO, 0); + CC_PRIM (); + } + else + { + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + MULSHADE_PRIM (); + } + T1_INTER_T0_USING_FACTOR (lod_frac); +} + +static void cc__t0_inter_t1_using_enva__sub_shade_mul_prim () +{ + if (cmb.combine_ext) + { + CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_ITRGB, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_CONSTANT_COLOR, 0, + GR_CMBX_ZERO, 0); + CC_PRIM (); + } + else + { + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + MULSHADE_PRIM (); + } + wxUint8 factor = (wxUint8)(rdp.env_color&0xFF); + T0_INTER_T1_USING_FACTOR (factor); +} + +static void cc_t0_sub_shade_mul_shadea () //Aded by Gonetz +{ + // * not guaranteed to work if another iterated alpha is set + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL, + GR_COMBINE_FACTOR_LOCAL_ALPHA, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + USE_T0 (); +} + +static void cc_one_sub_t0_mul_prim () //Added by Gonetz +{ + CCMB (GR_COMBINE_FUNCTION_BLEND_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_NONE); + CC_PRIM (); + USE_T0 (); +} + +static void cc_one_sub_prim_mul_prima () //Added by Gonetz +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + CC (~rdp.prim_color); + SETSHADE_PRIMA (); +} + +static void cc_shade_sub_prim_mul_t0 () //Aded by Gonetz +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + CC_PRIM (); + USE_T0 (); +} + +static void cc_shade_sub_prim_mul_env () //Aded by Gonetz +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + CC_ENV (); + SUBSHADE_PRIM (); +} + +static void cc_shade_sub_env_mul_t0 () //Aded by Gonetz +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + CC_ENV (); + USE_T0 (); +} + +static void cc_shade_sub_prim_mul__t0_inter_t1_using_primlod () //Aded by Gonetz +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + CC_PRIM (); + T0_INTER_T1_USING_FACTOR (lod_frac); +} + +static void cc_shade_sub_env_mul__t0_inter_t1_using_primlod () //Aded by Gonetz +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + CC_ENV (); + T0_INTER_T1_USING_FACTOR (lod_frac); +} + +static void cc_shade_sub_env_mul_prim () //Aded by Gonetz +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + CC_PRIM(); + SUBSHADE_ENV (); +} + +static void cc_shade_sub__prim_mul_prima () //Aded by Gonetz +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + CC_C1MULC2 (rdp.prim_color, (rdp.prim_color&0xFF)); +} + +static void cc_one_sub__t0_mul_t1__mul_shade () //Aded by Gonetz +{ + CCMB (GR_COMBINE_FUNCTION_BLEND, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + CC (0); + T0_MUL_T1 (); +} + +static void cc_one_sub__t0_mul_shadea__mul_shade () //Aded by Gonetz +{ + if (cmb.combine_ext) + { + T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, + GR_CMBX_ITALPHA, 0, + GR_CMBX_ZERO, 0); + cmb.tex |= 1; + + CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_ONE_MINUS_X, + GR_CMBX_ITALPHA, GR_FUNC_MODE_ZERO, + GR_CMBX_ITRGB, 0, + GR_CMBX_ZERO, 0); + } + else + { + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + USE_T0 (); + cmb.tmu0_invert = TRUE; + } +} + +static void cc_one_sub_env_mul_t0 () //Aded by Gonetz +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_ONE_MINUS_LOCAL, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + CC_ENV (); + USE_T0 (); +} + +static void cc_one_sub_env_mul__t0_inter_t1_using_primlod () //Aded by Gonetz +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_ONE_MINUS_LOCAL, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + CC_ENV (); + T0_INTER_T1_USING_FACTOR (lod_frac); +} + +static void cc_one_sub_env_mul_prim () //Aded by Gonetz +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_ONE_MINUS_LOCAL, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + CC_ENV (); + SETSHADE_PRIM (); +} + +static void cc_one_sub_env_mul_shade () //Aded by Gonetz +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_ONE_MINUS_LOCAL, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + CC_ENV (); +} + +// ** (1-A)*B + A*C ** +static void cc_t0_mul_env_add_1mt0_mul_shade () +{ + CCMB (GR_COMBINE_FUNCTION_BLEND, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + CC_ENV (); + USE_T0 (); +} + +// ** (1-A)*B+C ** +static void cc_one_sub_shade_mul__t1_sub_prim_mul_primlod_add_t0__add_shade () //Added by Gonetz +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_ONE_MINUS_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + T1_SUB_PRIM_MUL_PRIMLOD_ADD_T0 (); +} + +// ** (1-A)*B*C ** +static void cc_one_sub_t0_mul_prim_mul_shade () //Added by Gonetz +{ + CCMB (GR_COMBINE_FUNCTION_BLEND_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_NONE); + MULSHADE_PRIM (); + USE_T0 (); +} + +// ** (A-B)*C*D ** +static void cc_prim_sub_env_mul_t0_mul_shade () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_NONE, + GR_COMBINE_OTHER_ITERATED); + MULSHADE_PRIMSUBENV (); + USE_T0 (); +} + +// ** (A-B)*C+D ** +static void cc_t0_sub_t1_mul_prim_mul_shade_add_t1 () //Aded by Gonetz +{ + if (cmb.combine_ext) + { + T1CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, + GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, + GR_CMBX_ZERO, 0, + GR_CMBX_B, 0); + T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_OTHER_TEXTURE_RGB, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_ITRGB, 0, + GR_CMBX_B, 0); + cmb.tex |= 3; + CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_ITRGB, GR_FUNC_MODE_ZERO, + GR_CMBX_ZERO, 1, + GR_CMBX_ZERO, 0); + MULSHADE_PRIM (); + } + else + { + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + CC_PRIM (); + T0_ADD_T1 (); + } +} + +static void cc_t0_sub_prim_mul_t0a_add_prim () //Aded by Gonetz +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_ALPHA, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + CC_PRIM (); + USE_T0 (); +} + +static void cc_t0_sub_prim_mul_t1_add_shade () //Aded by Gonetz +{ + if (cmb.combine_ext) + { + T1CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, + GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, + GR_CMBX_ZERO, 0, + GR_CMBX_B, 0); + T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_OTHER_TEXTURE_RGB, 0, + GR_CMBX_ZERO, 0); + cmb.tex |= 3; + cmb.tex_ccolor = rdp.prim_color; + CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_ITRGB, GR_FUNC_MODE_ZERO, + GR_CMBX_ZERO, 1, + GR_CMBX_B, 0); + } + else + { + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + MOD_0 (TMOD_TEX_SUB_COL); + MOD_0_COL (rdp.prim_color & 0xFFFFFF00); + T0_MUL_T1 (); + } +} + +static void cc_t0_sub_prim_mul_primlod_add_prim () //Aded by Gonetz +{ + if (cmb.combine_ext) + { + CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_ITRGB, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_CONSTANT_COLOR, 0, + GR_CMBX_B, 0); + SETSHADE_PRIM (); + CC_PRIMLOD (); + } + else + { + // * not guaranteed to work if another iterated alpha is set + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + SETSHADE_PRIM (); + SETSHADE_1MPRIMLOD (); + CC_PRIMLOD (); + } + USE_T0 (); +} + +static void cc_t0_sub_prim_mul_prima_add_prim () //Aded by Gonetz +{ + // * not guaranteed to work if another iterated alpha is set + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + SETSHADE_PRIM (); + SETSHADE_1MPRIMA (); + CC_PRIMA (); + USE_T0 (); +} + +static void cc_t0_sub_prim_mul_shadea_add_prim () //Aded by Gonetz +{ + // * not guaranteed to work if another iterated alpha is set + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, + GR_COMBINE_FACTOR_LOCAL_ALPHA, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + SETSHADE_PRIM (); + USE_T0 (); +} + +static void cc_t0_sub_prim_mul_env_add_shade () //Aded by Gonetz +{ + if (cmb.combine_ext) + { + T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_ZERO, 1, + GR_CMBX_ZERO, 0); + cmb.tex |= 1; + cmb.tex_ccolor = rdp.prim_color; + CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_ITRGB, GR_FUNC_MODE_ZERO, + GR_CMBX_CONSTANT_COLOR, 0, + GR_CMBX_B, 0); + CC_ENV (); + } + else + { + cc_t0_mul_env_add_shade (); + } +} + +static void cc__t0_inter_t1_using_shadea__sub_prim_mul_env_add_shade () //Aded by Gonetz +{ + if (cmb.combine_ext) + { + CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_ITRGB, GR_FUNC_MODE_ZERO, + GR_CMBX_CONSTANT_COLOR, 0, + GR_CMBX_B, 0); + //have to pass shade alpha to combiner + ACMBEXT(GR_CMBX_TEXTURE_ALPHA, GR_FUNC_MODE_ZERO, + GR_CMBX_ITALPHA, GR_FUNC_MODE_ZERO, + GR_CMBX_ZERO, 0, + GR_CMBX_ZERO, 0); + } + else + { + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + } + CC_ENV (); + SUBSHADE_PRIMMULENV (); + T0_INTER_T1_USING_SHADEA (); +} + + +static void cc_t0_sub_prim_mul_env_add_prim () //Aded by Gonetz +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + CC_ENV (); + SETSHADE_PRIM (); + SETSHADE_1MENV (); + USE_T0 (); +} + +static void cc_t0_sub_prim_mul_enva_add_prim () //Aded by Gonetz41 +{ + if (cmb.combine_ext) + { + CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_ITRGB, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_CONSTANT_COLOR, 0, + GR_CMBX_B, 0); + SETSHADE_PRIM (); + CC_ENVA (); + } + else + { + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + CC_PRIM (); + MOD_0 (TMOD_TEX_SUB_COL_MUL_FAC); + MOD_0_COL (rdp.prim_color & 0xFFFFFF00); + MOD_0_FAC (rdp.env_color & 0xFF); + } + USE_T0 (); +} + +static void cc_t0_sub_prim_mul_primlod_add_env () //Aded by Gonetz +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + CC_ENV (); + MOD_0 (TMOD_TEX_SUB_COL_MUL_FAC); + MOD_0_COL (rdp.prim_color & 0xFFFFFF00); + MOD_0_FAC (lod_frac & 0xFF); + USE_T0 (); +} + +static void cc_t0_sub__prim_mul_env () //Aded by Gonetz +{ + if ( (rdp.prim_color & 0xFFFFFF00) == 0xFFFFFF00 && (rdp.env_color & 0xFFFFFF00) == 0xFFFFFF00) + { + CCMB (GR_COMBINE_FUNCTION_BLEND_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_NONE); + CC_PRIM (); + } + else + { + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + SETSHADE_PRIM (); + SETSHADE_ENV (); + } + USE_T0 (); +} + +static void cc__t0_mul_t1__sub_prim_mul__t0t1a__add_prim () //Aded by Gonetz +{ + // * not guaranteed to work if another iterated alpha is set + CCMB (GR_COMBINE_FUNCTION_BLEND, + GR_COMBINE_FACTOR_TEXTURE_ALPHA, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + CC_PRIM (); + T0_MUL_T1 (); + A_T0_MUL_T1 (); +} + +static void cc__t1_inter_t0_using_enva__sub_prim_mul_prima_add_prim () //Aded by Gonetz +{ + // * not guaranteed to work if another iterated alpha is set + CCMB (GR_COMBINE_FUNCTION_BLEND, + GR_COMBINE_FACTOR_LOCAL_ALPHA, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + CC_PRIM (); + CA_PRIM (); + wxUint8 factor = (wxUint8)(rdp.env_color&0xFF); + T1_INTER_T0_USING_FACTOR (factor); +} + +static void cc_t0_sub_prim_mul_shade_add_env () +{ + if (cmb.combine_ext) + { + T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_ZERO, 1, + GR_CMBX_ZERO, 0); + cmb.tex |= 1; + cmb.tex_ccolor = rdp.prim_color; + CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_CONSTANT_COLOR, GR_FUNC_MODE_ZERO, + GR_CMBX_ITRGB, 0, + GR_CMBX_B, 0); + CC_ENV (); + } + else + { + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + CC_ENV (); + MOD_0 (TMOD_TEX_SUB_COL); + MOD_0_COL (rdp.prim_color & 0xFFFFFF00); + USE_T0 (); + } +} + +static void cc_t1_sub_prim_mul_shade_add_env () +{ + if (cmb.combine_ext) + { + T1CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, + GR_CMBX_ZERO, 1, + GR_CMBX_ZERO, 0); + T0CCMBEXT(GR_CMBX_OTHER_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_ZERO, 1, + GR_CMBX_ZERO, 0); + cmb.tex |= 2; + cmb.tex_ccolor = rdp.prim_color; + CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_CONSTANT_COLOR, GR_FUNC_MODE_ZERO, + GR_CMBX_ITRGB, 0, + GR_CMBX_B, 0); + CC_ENV (); + } + else + { + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + CC_ENV (); + MOD_1 (TMOD_TEX_SUB_COL); + MOD_1_COL (rdp.prim_color & 0xFFFFFF00); + USE_T1 (); + } +} + +static void cc_t1_sub_k4_mul_prima_add_t0 () +{ + if (cmb.combine_ext) + { + T1CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_DETAIL_FACTOR, 1, + GR_CMBX_ZERO, 0); + T0CCMBEXT(GR_CMBX_OTHER_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_ZERO, 1, + GR_CMBX_ZERO, 0); + cmb.tex |= 3; + CC_BYTE (rdp.K4); + cmb.tex_ccolor = cmb.ccolor; + percent = (float)(rdp.prim_color&0xFF) / 255.0f; + cmb.dc0_detailmax = cmb.dc1_detailmax = percent; + CCMBEXT(GR_CMBX_TEXTURE_ALPHA, GR_FUNC_MODE_X, + GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_ZERO, + GR_CMBX_CONSTANT_COLOR, 0, + GR_CMBX_B, 0); + } + else + { + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_NONE, + GR_COMBINE_OTHER_TEXTURE); + T0_ADD_T1 (); + } +} + +static void cc__t0_sub_prim_mul_shade_add_env__mul_shade () +{ + if (cmb.combine_ext) + { + T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_ITRGB, 0, + GR_CMBX_ZERO, 0); + cmb.tex |= 1; + cmb.tex_ccolor = rdp.prim_color; + CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_CONSTANT_COLOR, GR_FUNC_MODE_X, + GR_CMBX_ITRGB, 0, + GR_CMBX_ZERO, 0); + CC_ENV (); + } + else + { + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + CC_ENV (); + MOD_0 (TMOD_TEX_SUB_COL); + MOD_0_COL (rdp.prim_color & 0xFFFFFF00); + USE_T0 (); + } +} + +static void cc__t0_sub_prim_mul_shade_add_env__mul_shadea () +{ + if (cmb.combine_ext) + { + T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_ITRGB, 0, + GR_CMBX_ZERO, 0); + cmb.tex |= 1; + cmb.tex_ccolor = rdp.prim_color; + CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_CONSTANT_COLOR, GR_FUNC_MODE_X, + GR_CMBX_ITALPHA, 0, + GR_CMBX_ZERO, 0); + CC_ENV (); + } + else + { + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + MULSHADE_SHADEA(); + CC_ENV (); + MOD_0 (TMOD_TEX_SUB_COL); + MOD_0_COL (rdp.prim_color & 0xFFFFFF00); + USE_T0 (); + } +} + +static void cc__t0_mul_shade__sub_env_mul_shadea_add_env () //Aded by Gonetz +{ + if (rdp.tiles[rdp.cur_tile].format == 4) + { + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, + GR_COMBINE_FACTOR_OTHER_ALPHA, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + CC_ENV (); + } + else if (rdp.tiles[rdp.cur_tile].format == 2) + { + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + USE_T0 (); + } + else + { + cc_t0 (); + } +} + +static void cc_t0_sub_env_mul_k5_add_prim () //Aded by Gonetz +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + CC_PRIM (); + MOD_0 (TMOD_TEX_SUB_COL_MUL_FAC); + MOD_0_COL (rdp.env_color & 0xFFFFFF00); + MOD_0_FAC (rdp.K5); + USE_T0 (); +} + +static void cc_t0_sub_k4_mul_k5_add_t0 () //Aded by Gonetz +{ + if (cmb.combine_ext) + { + CCMBEXT(GR_CMBX_ITRGB, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_CONSTANT_COLOR, 0, + GR_CMBX_B, 0); + wxUint32 temp = rdp.prim_lodfrac; + rdp.prim_lodfrac = rdp.K4; + SETSHADE_PRIMLOD (); + rdp.prim_lodfrac = temp; + CC_K5 (); + USE_T0 (); + } + else + { + cc_t0 (); + } +} + +static void cc__t0_inter_t1_using_t0__sub_shade_mul_prima_add_shade () //Aded by Gonetz +{ + if (cmb.combine_ext) + { + cmb.tex |= 3; + CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_ITRGB, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_CONSTANT_COLOR, 0, + GR_CMBX_B, 0); + CC_PRIMA(); + T0_INTER_T1_USING_T0 (); + } + else + { + // * not guaranteed to work if another iterated alpha is set + CCMB (GR_COMBINE_FUNCTION_BLEND, + GR_COMBINE_FACTOR_LOCAL_ALPHA, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + SETSHADE_A_PRIM (); + T1_INTER_T0_USING_T0 (); //strange, but this one looks better + } +} + +static void cc_t0_sub__prim_mul_shade__mul_enva_add__prim_mul_shade () //Aded by Gonetz +{ + // * not guaranteed to work if another iterated alpha is set + CCMB (GR_COMBINE_FUNCTION_BLEND, + GR_COMBINE_FACTOR_LOCAL_ALPHA, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + MULSHADE_PRIM (); + SETSHADE_A_ENV (); + USE_T0 (); +} + +static void cc_t0_sub_env_mul_t0_add_env () //Aded by Gonetz +{ + CCMB (GR_COMBINE_FUNCTION_BLEND, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + CC_ENV (); + USE_T0 (); + //(t0-env)*t0+env = t0*t0 + (1-t0)*env +} + +static void cc_t0_sub_env_mul_prima_add_env () //Aded by Gonetz +{ + if (cmb.combine_ext) + { + T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_DETAIL_FACTOR, 0, + GR_CMBX_B, 0); + cmb.tex |= 1; + percent = (rdp.prim_color&0xFF) / 255.0f; + cmb.dc0_detailmax = cmb.dc1_detailmax = percent; + } + else + { + MOD_0 (TMOD_COL_INTER_TEX_USING_COL1); + MOD_0_COL (rdp.env_color & 0xFFFFFF00); + wxUint32 prima = rdp.prim_color & 0xFF; + MOD_0_COL1 ((prima<<24)|(prima|16)|(prima<<8)); + USE_T0 (); + } + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_NONE, + GR_COMBINE_OTHER_TEXTURE); +} + +static void cc_t0_sub_env_mul_k5_add_env () //Aded by Gonetz +{ + CCMB (GR_COMBINE_FUNCTION_BLEND, + GR_COMBINE_FACTOR_LOCAL_ALPHA, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + cmb.ccolor = (rdp.env_color&0xFFFFFF00) | rdp.K5; + USE_T0 (); +} + +static void cc_t0_sub_env_mul_prim_add_shade () //Aded by Gonetz +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + CC_PRIM (); + MOD_0 (TMOD_TEX_SUB_COL); + MOD_0_COL (rdp.env_color & 0xFFFFFF00); + USE_T0 (); +} + +static void cc_t0_sub_env_mul_shade_add_prim () //Aded by Gonetz +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + CC_PRIM (); + if (cmb.combine_ext) + { + T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_ZERO, 1, + GR_CMBX_ZERO, 0); + cmb.tex |= 1; + cmb.tex_ccolor = rdp.env_color; + } + else + { + MOD_0 (TMOD_TEX_SUB_COL); + MOD_0_COL (rdp.env_color & 0xFFFFFF00); + USE_T0 (); + } +} + +static void cc__t0_sub_t1_mul_enva_add_shade__sub_env_mul_prim () +// (t0-t1)*env_a+shade, (cmb-env)*prim+0 +{ + if (cmb.combine_ext) + { + T1CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, + GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, + GR_CMBX_ZERO, 0, + GR_CMBX_B, 0); + T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_OTHER_TEXTURE_RGB, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_TMU_CCOLOR, 0, + GR_CMBX_ITRGB, 0); + cmb.tex |= 3; + CC_COLMULBYTE(rdp.prim_color, (rdp.env_color&0xFF)); + cmb.tex_ccolor = cmb.ccolor; + CCMBEXT(GR_CMBX_CONSTANT_COLOR, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_ITRGB, GR_FUNC_MODE_ZERO, + GR_CMBX_ZERO, 1, + GR_CMBX_TEXTURE_RGB, 0); + MULSHADE_PRIM (); + CC_PRIMMULENV (); + } + else + { + cc_t0_sub_env_mul_prim_add_shade(); + } +} + +static void cc__t0_inter_t1_using_primlod__sub_env_mul_shade_add_prim () //Aded by Gonetz +{ + if (!(rdp.env_color&0xFFFFFF00)) + { + cc__t0_inter_t1_using_primlod__mul_shade_add_prim (); + return; + } + if (!(rdp.prim_color&0xFFFFFF00)) + { + if (!cmb.combine_ext) + { + cc_t0_sub_env_mul_shade (); + return; + } + CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_CONSTANT_COLOR, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_ITRGB, 0, + GR_CMBX_ZERO, 0); + CC_ENV (); + T0_INTER_T1_USING_FACTOR (lod_frac); + return; + } + cc__t0_inter_t1_using_primlod__mul_shade_add_prim (); +} + +static void cc__t0_sub_env_mul_shade_add_prim__mul_shade () //Aded by Gonetz +{ + if (!cmb.combine_ext) + { + cc_t0_sub_env_mul_shade_add_prim (); + return; + } + T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_ITRGB, 0, + GR_CMBX_ZERO, 0); + cmb.tex_ccolor = rdp.env_color; + cmb.tex |= 1; + CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_CONSTANT_COLOR, GR_FUNC_MODE_X, + GR_CMBX_ITRGB, 0, + GR_CMBX_ZERO, 0); + CC_PRIM (); +} + +static void cc__t0_sub_env_mul_shade_add_prim__mul_shadea () //Aded by Gonetz +{ + if (!cmb.combine_ext) + { + cc_t0_sub_env_mul_shade_add_prim (); + return; + } + T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_ZERO, + GR_CMBX_ITRGB, 0, + GR_CMBX_B, 0); + cmb.tex_ccolor = rdp.prim_color; + cmb.tex |= 1; + MOD_0 (TMOD_TEX_SUB_COL); + MOD_0_COL (rdp.env_color & 0xFFFFFF00); + + CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_ITRGB, GR_FUNC_MODE_ZERO, + GR_CMBX_ITALPHA, 0, + GR_CMBX_ZERO, 0); +} + +static void cc__t0_inter_t1_using_primlod__sub_env_mul_shade_add_env () +{ + // (t1-t0)*primlod+t0, (cmb-env)*shade+env + if (cmb.combine_ext) + { + CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_CONSTANT_COLOR, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_ITRGB, 0, + GR_CMBX_B, 0); + } + else + { + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + } + CC_ENV (); + T0_INTER_T1_USING_FACTOR (lod_frac); +} + + +static void cc_t0_sub_env_mul_enva_add_prim () //Aded by Gonetz +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + CC_PRIM (); + MOD_0 (TMOD_TEX_SUB_COL_MUL_FAC); + MOD_0_COL (rdp.env_color & 0xFFFFFF00); + MOD_0_FAC (rdp.env_color & 0xFF); + USE_T0 (); +} + +static void cc_one_sub_t0_mul_prim_add_t0 () //Aded by Gonetz +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_ONE_MINUS_LOCAL, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + CC_PRIM (); + USE_T0 (); + //(1-t)*prim+t == (1-prim)*t+prim +} + +static void cc_one_sub_t1_mul_prim_add_t1 () //Aded by Gonetz +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_ONE_MINUS_LOCAL, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + CC_PRIM (); + USE_T1 (); + //(1-t)*prim+t == (1-prim)*t+prim +} + +static void cc_one_sub_t1_mul_env_add_t1 () //Aded by Gonetz +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_ONE_MINUS_LOCAL, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + CC_ENV (); + USE_T1 (); + //(1-t)*env+t == (1-env)*t+env +} + +static void cc_one_sub_t0_mul_primlod_add_t0 () //Aded by Gonetz +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_ONE_MINUS_LOCAL, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + CC_PRIMLOD (); + USE_T0 (); + //(1-t)*primlod+t == (1-primlod)*t+primlod +} + +static void cc_one_sub_t0_mul_prima_add_t0 () //Aded by Gonetz +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_ONE_MINUS_LOCAL_ALPHA, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + CA_PRIM (); + USE_T0 (); + //(1-t)*prima+t == (1-prima)*t+prima +} + +static void cc_one_sub__t0_inter_t1_using_enva__mul_prim_add__t0_inter_t1_using_enva () //Aded by Gonetz +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_ONE_MINUS_LOCAL, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + CC_PRIM (); + wxUint8 factor = (wxUint8)(rdp.env_color&0xFF); + T0_INTER_T1_USING_FACTOR (factor); + //(1-t)*prim+t == (1-prim)*t+prim +} + +static void cc_one_sub_t0_mul_shade_add_t0 () +{ + CCMB (GR_COMBINE_FUNCTION_BLEND, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + CC (0xFFFFFFFF); + USE_T0 (); +} + +static void cc_one_sub_prim_mul_t0_add_prim () //Aded by Gonetz +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_ONE_MINUS_LOCAL, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + CC_PRIM (); + USE_T0 (); +} + +static void cc_one_sub_prim_mul_t0a_add_prim () +{ + if (cmb.combine_ext) + { + CCMBEXT(GR_CMBX_CONSTANT_COLOR, GR_FUNC_MODE_ONE_MINUS_X, + GR_CMBX_CONSTANT_COLOR, GR_FUNC_MODE_ZERO, + GR_CMBX_TEXTURE_ALPHA, 0, + GR_CMBX_B, 0); + CC_PRIM (); + } else { + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_NONE, + GR_COMBINE_OTHER_TEXTURE); + MOD_0 (TMOD_COL_INTER_COL1_USING_TEXA); + MOD_0_COL (rdp.prim_color & 0xFFFFFF00); + MOD_0_COL1 (0xFFFFFF00); + } + USE_T0 (); +} + +static void cc_one_sub_prim_mul__t0_inter_t1_using_primlod__add_prim () //Aded by Gonetz +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_ONE_MINUS_LOCAL, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + CC_PRIM (); + T0_INTER_T1_USING_FACTOR (lod_frac); +} + +static void cc__one_sub_prim_mul_shade__mul_t0_add__prim_mul_shade () //Aded by Gonetz +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_ONE_MINUS_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + MULSHADE_PRIM (); + USE_T0 (); +} + +static void cc_one_sub_shade_mul__t0_inter_t1_using_primlod__add_shade () //Aded by Gonetz +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_ONE_MINUS_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + T0_INTER_T1_USING_FACTOR (lod_frac); +} + +static void cc_one_sub_prim_mul_t1_add_prim () //Aded by Gonetz +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_ONE_MINUS_LOCAL, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + CC_PRIM (); + USE_T1 (); +} + +static void cc_one_sub_prim_mul_env_add_prim () //Aded by Gonetz +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_ONE_MINUS_LOCAL, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + CC_PRIM (); + SETSHADE_ENV (); +} + +static void cc_t0_sub_prim_mul_shade_add_shade () //Aded by Gonetz +{ + if (cmb.combine_ext) + { + CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_CONSTANT_COLOR, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_ITRGB, 0, + GR_CMBX_ITRGB, 0); + CC_PRIM (); + } + else + { + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + if (rdp.prim_color & 0xFFFFFF00) + { + MOD_0 (TMOD_TEX_SUB_COL); + MOD_0_COL (rdp.prim_color & 0xFFFFFF00); + } + } + USE_T0 (); +} + +static void cc__t0_mul_t0__sub_prim_mul_shade_add_shade () //Aded by Gonetz +{ + if (cmb.combine_ext) + { + T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, + GR_CMBX_LOCAL_TEXTURE_RGB, 0, + GR_CMBX_ZERO, 0); + cmb.tex |= 1; + CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_CONSTANT_COLOR, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_ITRGB, 0, + GR_CMBX_ITRGB, 0); + CC_PRIM (); + } + else + cc_t0_sub_prim_mul_shade_add_shade(); +} + +static void cc__t0_mul_t1__sub_prim_mul_shade_add_shade () //Aded by Gonetz +{ + if (cmb.combine_ext) + { + CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_CONSTANT_COLOR, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_ITRGB, 0, + GR_CMBX_ITRGB, 0); + CC_PRIM (); + } + else + { + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + } + T0_MUL_T1 (); +} + +static void cc__t0_mul_t1__sub_env_mul_shade_add_shade () //Aded by Gonetz +{ + if (cmb.combine_ext) + { + CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_CONSTANT_COLOR, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_ITRGB, 0, + GR_CMBX_ITRGB, 0); + CC_ENV (); + } + else + { + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + } + T0_MUL_T1 (); +} + +static void cc_one_sub_prim_mul_shade_add_shade () //Aded by Gonetz +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + CC_1SUBPRIM (); +} + +static void cc_t0_inter_env_using_prima () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_NONE, + GR_COMBINE_OTHER_TEXTURE); + USE_T0 (); + + MOD_0 (TMOD_TEX_INTER_COLOR_USING_FACTOR); + MOD_0_COL (rdp.env_color & 0xFFFFFF00); + MOD_0_FAC (rdp.prim_color & 0xFF); +} + +static void cc_t0_inter_env_using_enva () +{ + //(env-t0)*env_a+t0 + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_NONE, + GR_COMBINE_OTHER_TEXTURE); + if (cmb.combine_ext) + { + T0CCMBEXT(GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_X, + GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_TMU_CALPHA, 0, + GR_CMBX_B, 0); + cmb.tex_ccolor = rdp.env_color; + cmb.tex |= 1; + } + else + { + USE_T0 (); + MOD_0 (TMOD_TEX_INTER_COLOR_USING_FACTOR); + MOD_0_COL (rdp.env_color & 0xFFFFFFFF); + MOD_0_FAC (rdp.env_color & 0xFF); + } +} + +static void cc_t0_inter_noise_using_prim () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_NONE, + GR_COMBINE_OTHER_TEXTURE); + USE_T0 (); + + MOD_0 (TMOD_TEX_INTER_NOISE_USING_COL); + MOD_0_COL (rdp.prim_color); + rdp.noise = RDP::noise_texture; +} + +static void cc_t0_inter_noise_using_env () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_NONE, + GR_COMBINE_OTHER_TEXTURE); + USE_T0 (); + + MOD_0 (TMOD_TEX_INTER_NOISE_USING_COL); + MOD_0_COL (rdp.env_color); + rdp.noise = RDP::noise_texture; +} + +static void cc_t0_sub_env_mul_enva_add_env () +{ + CCMB (GR_COMBINE_FUNCTION_BLEND, + GR_COMBINE_FACTOR_LOCAL_ALPHA, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + CC_ENV (); + CA_ENV (); + USE_T0 (); +} + +//Added by Gonetz +static void cc_one_sub_prim_mul__t0_mul_t1__add__prim_mul_env () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + CC_1SUBPRIM (); + SETSHADE_PRIM (); + SETSHADE_ENV (); + T0_MUL_T1 (); +} + +//Added by Gonetz +static void cc_one_sub_prim_mul__t0_mul_t1__add__prim_mul_shade () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + CC_1SUBPRIM (); + MULSHADE_PRIM (); + T0_MUL_T1 (); +} + +//Added by Gonetz +static void cc_one_sub_prim_mul__t0_inter_t1_using_enva__add_prim () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + CC_1SUBPRIM (); + SETSHADE_PRIM (); + wxUint8 factor = (wxUint8)(rdp.env_color&0xFF); + T0_INTER_T1_USING_FACTOR (factor); +} + +static void cc_one_sub_env_mul__t0_inter_t1_using_primlod__add_env () //Aded by Gonetz +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_ONE_MINUS_LOCAL, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + CC_ENV (); + T0_INTER_T1_USING_FACTOR (lod_frac); +} + +static void cc_one_sub_env_mul__t1_sub_prim_mul_primlod_add_t0__add_env () //Aded by Gonetz +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_ONE_MINUS_LOCAL, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + CC_ENV (); + T1_SUB_PRIM_MUL_PRIMLOD_ADD_T0 (); +} + +static void cc_one_sub_env_mul_t0_add_prim_mul_env () //Aded by Gonetz +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + CC_1SUBENV (); + SETSHADE_PRIM (); + SETSHADE_ENV (); + USE_T0 (); +} + +static void cc_one_sub_env_mul_t0_add_env () //Aded by Gonetz +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_ONE_MINUS_LOCAL, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + CC_ENV (); + USE_T0 (); +} + +static void cc_one_sub_env_mul_t0_add_shade () //Aded by Gonetz +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + CC_1SUBENV (); + USE_T0 (); +} + +static void cc_one_sub_env_mul_prim_add_env () //Aded by Gonetz +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_ONE_MINUS_LOCAL, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + CC_ENV (); + SETSHADE_PRIM (); +} + +static void cc_one_sub_env_mul_prim_add_shade () //Aded by Gonetz +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + CC_1SUBENV (); + CC_C1MULC2 (rdp.prim_color, cmb.ccolor); +} + +static void cc_one_sub_env_mul_shade_add_env () //Aded by Gonetz +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_ONE_MINUS_LOCAL, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + CC_ENV (); +} + +static void cc_one_sub_env_mul_prim_add__t0_inter_t1_using_env () //Aded by Gonetz +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + SETSHADE_PRIM (); + SETSHADE_1MENV (); + T0_INTER_T1_USING_ENV (); +} + +static void cc_one_sub_shade_mul_t0_add_shade () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_ONE_MINUS_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + USE_T0 (); +} + +static void cc_one_sub_shade_mul__t0_mul_shadea__add_shade () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_ONE_MINUS_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + if (cmb.combine_ext) + { + T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, + GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_ITALPHA, 0, + GR_CMBX_ZERO, 0); + cmb.tex |= 1; + } + else + { + USE_T0 (); + } +} + +static void cc_one_sub_shade_mul_env_add_shade () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_ONE_MINUS_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + CC_ENV (); +} + +static void cc_one_sub_shade_mul_shadea_add_shade () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, + GR_COMBINE_FACTOR_LOCAL_ALPHA, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + CC (0xFFFFFFFF); +} + +///* +static void cc_t0_sub_env_mul_prim_add_env () //Aded by Gonetz +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + SETSHADE_1MPRIM(); + SETSHADE_ENV(); + CC_PRIM (); + USE_T0 (); + //(t0-env)*prim+env == t0*prim + env*(1-prim) +} +//*/ +static void cc__t0_inter_t1_using_t1a__sub_env_mul_enva_add_env () //Aded by Gonetz +{ + CCMB (GR_COMBINE_FUNCTION_BLEND, + GR_COMBINE_FACTOR_LOCAL_ALPHA, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + cmb.ccolor = rdp.env_color; + T0_INTER_T1_USING_T1A (); +} + +static void cc_t0_sub_shade_mul_t0a_add_shade () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_ALPHA, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + USE_T0 (); + A_USE_T0 (); +} + +static void cc_t0_sub_shade_mul_prima_add_shade () //Aded by Gonetz +{ + // * not guaranteed to work if another iterated alpha is set + CCMB (GR_COMBINE_FUNCTION_BLEND, + GR_COMBINE_FACTOR_LOCAL_ALPHA, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + SETSHADE_A_PRIM (); + USE_T0 (); +} + +static void cc_t0_sub_shade_mul_shadea_add_shade () //Aded by Gonetz +{ + // * not guaranteed to work if another iterated alpha is set + CCMB (GR_COMBINE_FUNCTION_BLEND, + GR_COMBINE_FACTOR_LOCAL_ALPHA, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + USE_T0 (); +} + +static void cc__t0_mul_t1_add_env__mul_shadea_add_shade () +{ + if (cmb.combine_ext) + { + T1CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, + GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, + GR_CMBX_ZERO, 0, + GR_CMBX_B, 0); + T0CCMBEXT(GR_CMBX_OTHER_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_ZERO, + GR_CMBX_LOCAL_TEXTURE_RGB, 0, + GR_CMBX_B, 0); + cmb.tex_ccolor = rdp.env_color; + cmb.tex |= 3; + } + else + { + T0_MUL_T1 (); + } + // * not guaranteed to work if another iterated alpha is set + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_LOCAL_ALPHA, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); +} + +static void cc_prim_sub_t0_mul_env_add_t0 () //Aded by Gonetz +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + CC_1SUBENV (); + SETSHADE_PRIM (); + SETSHADE_ENV (); + USE_T0 (); + //(prim-t0)*env+t0 == prim*env + t0*(1-env) +} + +static void cc_prim_sub_t0_mul_t1_add_t0 () //Aded by Gonetz +{ + if (!cmb.combine_ext) + { + cc_t0_mul_t1 (); + return; + } + T1CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, + GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, + GR_CMBX_ZERO, 0, + GR_CMBX_B, 0); + T0CCMBEXT(GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_X, + GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_OTHER_TEXTURE_RGB, 0, + GR_CMBX_B, 0); + cmb.tex_ccolor = rdp.prim_color; + cmb.tex |= 3; + CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_ZERO, + GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_ZERO, + GR_CMBX_ZERO, 0, + GR_CMBX_B, 0); +} + +static void cc_env_sub_t0_mul_prim_add_t0 () //Aded by Gonetz +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + CC_1SUBPRIM (); + SETSHADE_PRIM (); + SETSHADE_ENV (); + USE_T0 (); + //(env-t0)*prim+t0 == prim*env + t0*(1-prim) +} + +static void cc_env_sub_t0_mul_shade_add_t0 () //Aded by Gonetz +{ + if (!cmb.combine_ext) + { + cc_t0_mul_shade (); + return; + } + CCMBEXT(GR_CMBX_CONSTANT_COLOR, GR_FUNC_MODE_X, + GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_ITRGB, 0, + GR_CMBX_B, 0); + CC_ENV (); + USE_T0 (); +} + +static void cc_prim_sub_env_mul_t0_add_prim () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + CC_PRIM (); + SETSHADE_PRIMSUBENV (); + USE_T0 (); +} + +static void cc_prim_sub_env_mul_t0_add_env () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + CC_PRIM (); + SETSHADE_ENV (); + USE_T0 (); +} + +static void cc__prim_sub_env_mul_t0_add_env__add_primlod () +{ + if (!cmb.combine_ext) + { + cc_prim_sub_env_mul_t0_add_env (); + return; + } + T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_ZERO, + GR_CMBX_ITRGB, 0, + GR_CMBX_B, 0); + cmb.tex_ccolor = rdp.env_color; + cmb.tex |= 1; + SETSHADE_PRIMSUBENV (); + CCMBEXT(GR_CMBX_CONSTANT_COLOR, GR_FUNC_MODE_X, + GR_CMBX_ITRGB, GR_FUNC_MODE_ZERO, + GR_CMBX_ZERO, 1, + GR_CMBX_TEXTURE_RGB, 0); + CC_PRIMLOD (); +} + +static void cc__prim_sub_env_mul_t0_add_env__add_shadea () +{ + if (!cmb.combine_ext) + { + cc_prim_sub_env_mul_t0_add_env (); + return; + } + T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_ZERO, + GR_CMBX_ITRGB, 0, + GR_CMBX_B, 0); + cmb.tex_ccolor = rdp.env_color; + cmb.tex |= 1; + SETSHADE_PRIMSUBENV (); + CCMBEXT(GR_CMBX_ITALPHA, GR_FUNC_MODE_X, + GR_CMBX_ITRGB, GR_FUNC_MODE_ZERO, + GR_CMBX_ZERO, 1, + GR_CMBX_TEXTURE_RGB, 0); +} + +static void cc_prim_sub_env_mul__t0_mul_t1a__add_env () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + CC_PRIM (); + SETSHADE_ENV (); + T0_MUL_T1A (); +} + +static void cc_prim_sub_env_mul__t0_mul_prim__add_env () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + CC_PRIM (); + SETSHADE_ENV (); + if (cmb.combine_ext) + { + T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, + GR_CMBX_TMU_CCOLOR, 0, + GR_CMBX_ZERO, 0); + cmb.tex_ccolor = rdp.prim_color; + cmb.tex |= 1; + } + else + { + USE_T0 (); + } +} + +static void cc_prim_sub_env_mul_t0_mul_shade_add_env () +{ + if (cmb.combine_ext) + { + T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, + GR_CMBX_TMU_CCOLOR, 0, + GR_CMBX_ZERO, 0); + CC_PRIMSUBENV (); + cmb.tex_ccolor = cmb.ccolor; + cmb.tex |= 1; + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + CC_ENV (); + } + else + { + cc_t0_mul_prim_mul_shade (); + } +} + +static void cc_prim_sub_env_mul__t0_sub_t0_mul_prima__add_env () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + CC_PRIM (); + SETSHADE_ENV (); + rdp.best_tex = 0; + cmb.tex |= 1; + cmb.tmu0_func = GR_COMBINE_FUNCTION_BLEND_LOCAL; + cmb.tmu0_fac = GR_COMBINE_FACTOR_DETAIL_FACTOR; + percent = (float)(rdp.prim_color&0xFF) / 255.0f; + cmb.dc0_detailmax = cmb.dc1_detailmax = percent; +} + +static void cc_prim_sub_env_mul__one_sub_t0_mul_primlod_add_prim__add_env () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + CC_ENV (); + SETSHADE_PRIM (); + if (cmb.combine_ext) + { + T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ONE_MINUS_X, + GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_ZERO, + GR_CMBX_DETAIL_FACTOR, 0, + GR_CMBX_B, 0); + cmb.tex_ccolor = rdp.prim_color; + cmb.tex |= 1; + cmb.dc0_detailmax = cmb.dc1_detailmax = (float)lod_frac / 255.0f; + } + else + { + USE_T0 (); + } +} + +static void cc_prim_sub_env_mul__t0_add_t1a__add_env () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + CC_PRIM (); + SETSHADE_ENV (); + rdp.best_tex = 0; + cmb.tex |= 3; + cmb.tmu1_func = GR_COMBINE_FUNCTION_LOCAL_ALPHA; + cmb.tmu0_func = GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL; + cmb.tmu0_fac = GR_COMBINE_FACTOR_ONE; +} + +static void cc_prim_sub_env_mul__t0_sub_prim_mul_enva_add_t0__add_env () +{ + // (t0-prim)*env_a+t0, (prim-env)*cmb+env + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + CC_ENV (); + SETSHADE_PRIM (); + USE_T0 (); + + MOD_0 (TMOD_TEX_SUB_COL_MUL_FAC_ADD_TEX); + MOD_0_COL (rdp.prim_color & 0xFFFFFF00); + MOD_0_FAC (rdp.env_color & 0xFF); +} + +static void cc_prim_sub_env_mul__t1_sub_prim_mul_enva_add_t0__add_env () +{ + //(t1-prim)*env_a+t0, (prim-env)*cmb+env + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + CC_ENV (); + SETSHADE_PRIM (); + if (cmb.combine_ext) + { + if (rdp.tiles[rdp.cur_tile].format > 2) + { + T1CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, + GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, + GR_CMBX_ZERO, 0, + GR_CMBX_B, 0); + T0CCMBEXT(GR_CMBX_OTHER_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_DETAIL_FACTOR, 0, + GR_CMBX_LOCAL_TEXTURE_ALPHA, 0); + } + else + { + T1CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_DETAIL_FACTOR, 0, + GR_CMBX_ZERO, 0); + T0CCMBEXT(GR_CMBX_OTHER_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_ZERO, 1, + GR_CMBX_ZERO, 0); + } + cmb.tex_ccolor = rdp.prim_color; + cmb.tex |= 3; + cmb.dc0_detailmax = cmb.dc1_detailmax = (float)(rdp.env_color&0xFF) / 255.0f; + } + else + { + MOD_1 (TMOD_TEX_SUB_COL_MUL_FAC); + MOD_1_COL (rdp.prim_color & 0xFFFFFF00); + MOD_1_FAC (rdp.env_color & 0xFF); + T0_ADD_T1 (); + } +} + +static void cc_prim_sub_env_mul__t1_sub_prim_mul_prima_add_t0__add_env () +{ + // (t1-prim)*prim_a+t0, (prim-env)*cmb+env + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + CC_ENV (); + SETSHADE_PRIM (); + if (cmb.combine_ext) + { + T1CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_ZERO, 1, + GR_CMBX_ZERO, 0); + T0CCMBEXT(GR_CMBX_OTHER_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, + GR_CMBX_DETAIL_FACTOR, 0, + GR_CMBX_B, 0); + cmb.tex_ccolor = rdp.prim_color; + cmb.tex |= 3; + cmb.dc0_detailmax = cmb.dc1_detailmax = (float)(rdp.prim_color&0xFF) / 255.0f; + } + else + { + MOD_1 (TMOD_TEX_SUB_COL_MUL_FAC); + MOD_1_COL (rdp.prim_color & 0xFFFFFF00); + MOD_1_FAC (rdp.prim_color & 0xFF); + T0_ADD_T1 (); + } +} + +static void cc__prim_sub_env_mul_t0_add_env__mul_primlod () +{ + CCMB (GR_COMBINE_FUNCTION_BLEND, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + float factor = (float)rdp.prim_lodfrac / 255.0f; + wxUint8 r = (wxUint8)((rdp.prim_color >> 24) & 0xFF); + r = (wxUint8)((float)r * factor); + wxUint8 g = (wxUint8)((rdp.prim_color >> 16) & 0xFF); + g = (wxUint8)((float)g * factor); + wxUint8 b = (wxUint8)((rdp.prim_color >> 8) & 0xFF); + b = (wxUint8)((float)b * factor); + CC ((r<<24) | (g<<16) | (b<<8)); + SETSHADE_ENV (); + MULSHADE_PRIMLOD (); + USE_T0 (); +} + +static void cc__prim_sub_env_mul_t0_add_env__mul_k5 () +{ + CCMB (GR_COMBINE_FUNCTION_BLEND, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + float factor = (float)rdp.K5 / 255.0f; + wxUint8 r = (wxUint8)((rdp.prim_color >> 24) & 0xFF); + r = (wxUint8)((float)r * factor); + wxUint8 g = (wxUint8)((rdp.prim_color >> 16) & 0xFF); + g = (wxUint8)((float)g * factor); + wxUint8 b = (wxUint8)((rdp.prim_color >> 8) & 0xFF); + b = (wxUint8)((float)b * factor); + CC ((r<<24) | (g<<16) | (b<<8)); + SETSHADE_ENV (); + MULSHADE_K5 (); + USE_T0 (); +} + +static void cc_prim_sub_env_mul_t1_add_env () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + CC_PRIM (); + SETSHADE_ENV (); + if (rdp.cycle_mode == 0 || ((settings.hacks&hack_KI) && (rdp.cycle2 & 0x0FFFFFFF) == 0x01FF1FFF)) + { + USE_T0 (); + } + else + { + USE_T1 (); + } +} + +static void cc_prim_sub_env_mul_t1_add_env_mul_t0 () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_NONE, + GR_COMBINE_OTHER_TEXTURE); + MOD_1 (TMOD_COL_INTER_COL1_USING_TEX); + MOD_1_COL (rdp.env_color & 0xFFFFFF00); + MOD_1_COL1 (rdp.prim_color & 0xFFFFFF00); + T0_MUL_T1 (); +} + +static void cc_prim_sub_env_mul_t0a_add_t0 () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_NONE, + GR_COMBINE_OTHER_TEXTURE); + CC_PRIMSUBENV (); + if (cmb.combine_ext) + { + T0CCMBEXT(GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_X, + GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, + GR_CMBX_LOCAL_TEXTURE_ALPHA, 0, + GR_CMBX_B, 0); + cmb.tex_ccolor = cmb.ccolor; + cmb.tex |= 1; + } + else + { + MOD_0 (TMOD_COL_MUL_TEXA_ADD_TEX); + MOD_0_COL (cmb.ccolor & 0xFFFFFF00); + USE_T0 (); + } +} + +//Added by Gonetz +static void cc_prim_sub_env_mul_t0a_add_env () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_ALPHA, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + CC_ENV (); + SETSHADE_PRIM (); + USE_T0 (); +} + +//Added by Gonetz +static void cc_prim_sub_env_mul_t1a_add_env () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_ALPHA, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + CC_ENV (); + SETSHADE_PRIM (); + USE_T1 (); +} + +//Added by Gonetz +static void cc_prim_sub_env_mul__t0_mul_t1__add_env () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + CC_PRIM (); + SETSHADE_ENV (); + T0_MUL_T1 (); +} + +//Added by Gonetz +static void cc_prim_sub_env_mul__t0_add_t1__add_env () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + CC_PRIM (); + SETSHADE_ENV (); + T0_ADD_T1 (); +} + +//Added by Gonetz +static void cc_prim_sub_env_mul__t0_mul_enva__add_env () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + CC_ENV (); + SETSHADE_PRIMSUBENV (); + SETSHADE_ENVA (); + USE_T0 (); +} + +//Added by Gonetz +static void cc_prim_sub_env_mul__t0_mul_shade__add_env () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + CC_ENV (); + MULSHADE_PRIMSUBENV (); + USE_T0 (); +} + +//Added by Gonetz +static void cc_prim_sub_env_mul__prim_inter_t0_using_shadea__add_env () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + CC_ENV (); + if (cmb.combine_ext) + { + SETSHADE_PRIM (); + PRIM_INTER_T0_USING_SHADEA (); + } + else + { + SETSHADE_PRIMSUBENV (); + MULSHADE_SHADEA (); + USE_T0 (); + } +} + +//Added by Gonetz +static void cc_prim_sub_env_mul__t0_sub_prim_mul_primlod_add_t0__add_env () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + CC_PRIM (); + SETSHADE_ENV (); + if (cmb.combine_ext) + { + T0CCMBEXT(GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_DETAIL_FACTOR, 0, + GR_CMBX_B, 0); + cmb.tex_ccolor = rdp.prim_color; + cmb.tex |= 1; + percent = (float)(lod_frac) / 255.0f; + cmb.dc0_detailmax = cmb.dc1_detailmax = percent; + } + else + { + USE_T0 (); + MOD_0 (TMOD_TEX_SUB_COL_MUL_FAC_ADD_TEX); + MOD_0_COL (rdp.prim_color & 0xFFFFFF00); + MOD_0_FAC (lod_frac & 0xFF); + } +} + +static void cc_prim_sub_env_mul__t0_sub_prim_mul_primlod_add_shade__add_env () +{ + if (!cmb.combine_ext) + { + cc_prim_sub_env_mul_t0_add_env (); + return; + } + T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_DETAIL_FACTOR, 0, + GR_CMBX_ITRGB, 0); + CCMBEXT(GR_CMBX_CONSTANT_COLOR, GR_FUNC_MODE_X, + GR_CMBX_ITRGB, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_TEXTURE_RGB, 0, + GR_CMBX_B, 0); + cmb.tex_ccolor = rdp.prim_color; + CC_PRIM (); + SETSHADE_ENV (); + cmb.tex |= 1; + percent = (float)(lod_frac) / 255.0f; + cmb.dc0_detailmax = cmb.dc1_detailmax = percent; +} + +static void cc_prim_sub_env_mul__t0_sub_shade_mul_primlod_add_shade__add_env () +{ + if (!cmb.combine_ext) + { + cc_prim_sub_env_mul_t0_add_env (); + return; + } + T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_ITRGB, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_DETAIL_FACTOR, 0, + GR_CMBX_B, 0); + CCMBEXT(GR_CMBX_CONSTANT_COLOR, GR_FUNC_MODE_X, + GR_CMBX_ITRGB, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_TEXTURE_RGB, 0, + GR_CMBX_B, 0); + CC_PRIM (); + SETSHADE_ENV (); + cmb.tex |= 1; + percent = (float)(lod_frac) / 255.0f; + cmb.dc0_detailmax = cmb.dc1_detailmax = percent; +} + +//Added by Gonetz +static void cc_lavatex_sub_prim_mul_shade_add_lavatex () +{ + if (cmb.combine_ext) + { + CCMBEXT(GR_CMBX_CONSTANT_COLOR, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_ITRGB, 0, + GR_CMBX_B, 0); + CC_PRIM (); + T0_SUB_PRIM_MUL_PRIMLOD_ADD_T1 (); + } + else + { + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_NONE, + GR_COMBINE_OTHER_TEXTURE); + T0_ADD_T1 (); + } +} + +//Added by Gonetz +static void cc_prim_sub_env_mul__t0_sub_prim_mul_primlod_add_t1__add_env () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + CC_PRIM (); + SETSHADE_ENV (); + T0_SUB_PRIM_MUL_PRIMLOD_ADD_T1 (); +} + +//Added by Gonetz +static void cc_prim_sub_env_mul__t1_sub_prim_mul_primlod_add_t0__add_env () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + CC_PRIM (); + SETSHADE_ENV (); + T1_SUB_PRIM_MUL_PRIMLOD_ADD_T0 (); +} + +//Added by Gonetz +static void cc_prim_sub_env_mul__t0_inter_t1_using_t1__add_env () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + CC_PRIM (); + SETSHADE_ENV (); + T0_INTER_T1_USING_T1 (); +} + +//Added by Gonetz +static void cc_prim_sub_env_mul__t0_inter_t1_using_enva_alpha__add_env () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_ALPHA, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + CC_PRIM (); + SETSHADE_ENV (); + wxUint8 factor = (wxUint8)(rdp.env_color&0xFF); + T0_INTER_T1_USING_FACTOR (factor); + A_T0_INTER_T1_USING_FACTOR (factor); +} + +//Added by Gonetz +static void cc__env_inter_prim_using_t0__sub_shade_mul_t0a_add_shade () +{ + if (!cmb.combine_ext) + { + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_ALPHA, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + MOD_0 (TMOD_COL_INTER_COL1_USING_TEX); + MOD_0_COL (rdp.env_color & 0xFFFFFF00); + MOD_0_COL1 (rdp.prim_color & 0xFFFFFF00); + USE_T0 (); + A_USE_T0 (); + } + else + { + T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_ZERO, + GR_CMBX_DETAIL_FACTOR, 0, + GR_CMBX_B, 0); + CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_ITRGB, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_TEXTURE_ALPHA, 0, + GR_CMBX_B, 0); + cmb.tex_ccolor = rdp.env_color; + cmb.tex |= 1; + wxUint32 pse = (rdp.prim_color>>24) - (rdp.env_color>>24); + percent = (float)(pse) / 255.0f; + cmb.dc0_detailmax = cmb.dc1_detailmax = percent; + } +} + +//Added by Gonetz +static void cc_prim_sub_env_mul_shade_add_t0 () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + MULSHADE_PRIMSUBENV (); + USE_T0 (); +} + +//Added by Gonetz +static void cc_prim_sub_env_mul_prima_add_t0 () +{ + if (rdp.prim_color != 0x000000ff) + { + if (cmb.combine_ext) + { + CCMBEXT(GR_CMBX_CONSTANT_COLOR, GR_FUNC_MODE_X, + GR_CMBX_ITRGB, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_CONSTANT_ALPHA, 0, + GR_CMBX_TEXTURE_RGB, 0); + CC_PRIM (); + SETSHADE_ENV (); + } + else + { + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + SETSHADE_PRIMSUBENV (); + SETSHADE_PRIMA (); + } + } + else if ((rdp.prim_color&0xFFFFFF00) - (rdp.env_color&0xFFFFFF00) == 0) + { + cc_t0 (); + return; + } + else + { + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + CC_ENV (); + } + USE_T0 (); +} + +//Added by Gonetz +static void cc_prim_sub_env_mul_shade_add_env () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + CC_ENV (); + MULSHADE_PRIMSUBENV (); +} + +static void cc_prim_sub_env_mul_shadea_add_env () +{ + // * not guaranteed to work if another iterated alpha is set + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, + GR_COMBINE_FACTOR_OTHER_ALPHA, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + CC_ENV (); + SETSHADE_PRIM (); +} + +//Added by Gonetz +static void cc_prim_sub_env_mul__t0_inter_t1_using_prima__add_env () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + CC_ENV (); + SETSHADE_PRIM (); + wxUint8 factor = (wxUint8)(rdp.prim_color&0xFF); + T0_INTER_T1_USING_FACTOR (factor); +} + +//Added by Gonetz +static void cc_prim_sub_env_mul__t1_inter_t0_using_prima__add_env () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + CC_ENV (); + SETSHADE_PRIM (); + wxUint8 factor = (wxUint8)(rdp.prim_color&0xFF); + T1_INTER_T0_USING_FACTOR (factor); +} + +static void cc_prim_sub_env_mul__t0_inter_t1_using_enva__add_env () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + CC_ENV (); + SETSHADE_PRIM (); + wxUint8 factor = (wxUint8)(rdp.env_color&0xFF); + T0_INTER_T1_USING_FACTOR (factor); +} + +static void cc_prim_sub_center_mul__t0_inter_t1_using_enva__add_env () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + CC_C1SUBC2 (rdp.prim_color, rdp.CENTER); + SETSHADE_ENV (); + wxUint8 factor = (wxUint8)(rdp.env_color&0xFF); + T0_INTER_T1_USING_FACTOR (factor); +} + +static void cc_prim_sub_env_mul__t1_inter_t0_using_enva__add_env () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + CC_ENV (); + SETSHADE_PRIM (); + wxUint8 factor = (wxUint8)(rdp.env_color&0xFF); + T1_INTER_T0_USING_FACTOR (factor); +} + +static void cc_prim_sub_env_mul__t0_mul_enva_add_t1__add_env () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + CC_ENV (); + SETSHADE_PRIM (); + if (cmb.combine_ext) + { + T1CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, + GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_ZERO, 1, + GR_CMBX_ZERO, 0); + T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_OTHER_TEXTURE_RGB, GR_FUNC_MODE_ZERO, + GR_CMBX_DETAIL_FACTOR, 0, + GR_CMBX_B, 0); + cmb.tex |= 3; + percent = (float)(rdp.env_color&0xFF) / 255.0f; + cmb.dc0_detailmax = cmb.dc1_detailmax = percent; + } + else + { + T0_ADD_T1 (); + } +} + +static void cc_prim_sub_env_mul__t1_mul_enva_add_t0__add_env () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + CC_ENV (); + SETSHADE_PRIM (); + T1_MUL_ENVA_ADD_T0 (); +} + +//Added by Gonetz +static void cc_prim_sub_env_mul_primlod_add__t0_inter_t1_using_primlod () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + CC_PRIMSUBENV(); + CC_COLMULBYTE(cmb.ccolor, rdp.prim_lodfrac); + T0_INTER_T1_USING_FACTOR (lod_frac); +} + +static void cc_prim_sub_env_mul__t0_inter_t1_using_primlod__add_env () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + CC_ENV (); + SETSHADE_PRIM (); + T0_INTER_T1_USING_FACTOR (lod_frac); +} + +static void cc_prim_sub_env_mul__t1_inter_t0_using_primlod__add_env () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + CC_ENV (); + SETSHADE_PRIM (); + T1_INTER_T0_USING_FACTOR (lod_frac); +} + +static void cc_prim_sub_env_mul__t1_mul_primlod_add_t0__add_env () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + CC_ENV (); + SETSHADE_PRIM (); + T1_MUL_PRIMLOD_ADD_T0 (); +} + +static void cc_prim_sub_env_mul__t1_sub_prim_mul_t0_add_t0__add_env () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + CC_ENV (); + SETSHADE_PRIM (); + if (cmb.combine_ext) + { + T1CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_ZERO, 1, + GR_CMBX_ZERO, 0); + T0CCMBEXT(GR_CMBX_OTHER_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, + GR_CMBX_LOCAL_TEXTURE_RGB, 0, + GR_CMBX_B, 0); + cmb.tex_ccolor = rdp.prim_color; + cmb.tex |= 3; + } + else + { + MOD_1 (TMOD_TEX_SUB_COL); + MOD_1_COL (rdp.prim_color & 0xFFFFFF00); + T0_MUL_T1_ADD_T0 (); + } +} + +//Added by Gonetz +static void cc__prim_sub_env_mul_prim_add_t0__mul_prim () +{ + if (cmb.combine_ext) + { + T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_ITRGB, GR_FUNC_MODE_X, + GR_CMBX_ZERO, 1, + GR_CMBX_ZERO, 0); + cmb.tex |= 1; + SETSHADE_PRIMSUBENV (); + SETSHADE_PRIM (); + CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_ITRGB, GR_FUNC_MODE_ZERO, + GR_CMBX_CONSTANT_COLOR, 0, + GR_CMBX_ZERO, 0); + CC_PRIM() ; + } + else + { + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + SETSHADE_PRIMSUBENV (); + SETSHADE_PRIM (); + USE_T0 (); + } +} + +//Added by Gonetz +static void cc_prim_sub_env_mul_prim_add_env () +{ + if (cmb.combine_ext) + { + CCMBEXT(GR_CMBX_CONSTANT_COLOR, GR_FUNC_MODE_X, + GR_CMBX_ITRGB, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_CONSTANT_COLOR, 0, + GR_CMBX_B, 0); + SETSHADE_ENV(); + CC_PRIM (); + } + else + { + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + SETSHADE_PRIMSUBENV (); + SETSHADE_PRIM (); + CC_ENV (); + } +} + +static void cc_prim_sub_env_mul_primlod_add_env () +{ + if (cmb.combine_ext) + { + T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, + GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_ZERO, + GR_CMBX_ZERO, 0, + GR_CMBX_B, 0); + cmb.tex |= 1; + CC_PRIMLOD (); + cmb.tex_ccolor = cmb.ccolor; + CCMBEXT(GR_CMBX_ITRGB, GR_FUNC_MODE_X, + GR_CMBX_CONSTANT_COLOR, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_TEXTURE_RGB, 0, + GR_CMBX_B, 0); + SETSHADE_PRIM(); + CC_ENV (); + } + else + { + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + SETSHADE_PRIMSUBENV (); + SETSHADE_PRIMLOD (); + CC_ENV (); + } +} + +//Added by Gonetz +static void cc_prim_sub_env_mul_enva_add_t0 () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + SETSHADE_PRIMSUBENV (); + SETSHADE_ENVA (); + USE_T0 (); +} + +static void cc_prim_sub_env_mul_enva_add_env () +{ + if (cmb.combine_ext) + { + T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, + GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_ZERO, + GR_CMBX_ZERO, 0, + GR_CMBX_B, 0); + cmb.tex |= 1; + CC_ENVA (); + cmb.tex_ccolor = cmb.ccolor; + CCMBEXT(GR_CMBX_ITRGB, GR_FUNC_MODE_X, + GR_CMBX_CONSTANT_COLOR, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_TEXTURE_RGB, 0, + GR_CMBX_B, 0); + SETSHADE_PRIM(); + CC_ENV (); + } + else + { + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + SETSHADE_PRIMSUBENV (); + SETSHADE_ENVA (); + CC_ENV (); + } +} + +//Added by Gonetz +static void cc_prim_sub_shade_mul_t0_add_env () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + CC_ENV (); + COLSUBSHADE_PRIM (); + USE_T0 (); +} + +//Added by Gonetz +static void cc_prim_sub_shade_mul__t1_sub_prim_mul_primlod_add_t0__add_shade () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + CC_PRIM (); + T1_SUB_PRIM_MUL_PRIMLOD_ADD_T0 (); +} + +static void cc_prim_sub_shade_mul_t1a_add_shade () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_ALPHA, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + CC_PRIM (); + USE_T1 (); +} + +//Added by Gonetz +static void cc_prim_sub_shade_mul_t0_add_shade () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + CC_PRIM (); + USE_T0 (); +} + +//Added by Gonetz +static void cc_prim_sub_shade_mul_t1_add_shade () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + CC_PRIM (); + USE_T1 (); +} + +//Added by Gonetz +static void cc_prim_sub_shade_mul__t0a_mul_t1__add_shade () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + CC_PRIM (); + T0A_MUL_T1(); +} + +//Added by Gonetz +static void cc_prim_sub_shade_mul__t0_inter_t1_using_enva__add_shade () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + CC_PRIM (); + wxUint8 factor = (wxUint8)(rdp.env_color&0xFF); + T0_INTER_T1_USING_FACTOR (factor); +} + +//Added by Gonetz +static void cc_prim_sub_shade_mul__t0_inter_t1_using_shadea__add_shade () +{ + if (cmb.combine_ext) + { + CCMBEXT(GR_CMBX_CONSTANT_COLOR, GR_FUNC_MODE_X, + GR_CMBX_ITRGB, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_TEXTURE_RGB, 0, + GR_CMBX_B, 0); + } + else + { + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + } + CC_PRIM (); + T0_INTER_T1_USING_SHADEA (); +} + +//Added by Gonetz +static void cc_prim_sub_shade_mul_prima_add_shade () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, + GR_COMBINE_FACTOR_OTHER_ALPHA, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + CC_PRIM (); + CA_PRIM (); +} + +//Added by Gonetz +static void cc_prim_sub_shade_mul_env_add_shade () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + CC_PRIMMULENV (); + MULSHADE_1MENV (); +} + +//Added by Gonetz +static void cc_prim_sub_shade_mul_shadea_add_shade () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, + GR_COMBINE_FACTOR_LOCAL_ALPHA, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + CC_PRIM (); +} + +static void cc_env_sub_prim_mul_t0_add_prim () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + CC_ENV (); + SETSHADE_PRIM (); + USE_T0 (); +} + +static void cc_env_sub_prim_mul_t1_add_prim () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + CC_ENV (); + SETSHADE_PRIM (); + USE_T1 (); +} + +static void cc_env_sub_prim_mul_t0a_add_prim () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_ALPHA, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + CC_ENV (); + SETSHADE_PRIM (); + A_USE_T0 (); +} + +static void cc_env_sub_prim_mul_t1a_add_prim () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_ALPHA, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + CC_ENV (); + SETSHADE_PRIM (); + A_USE_T1 (); +} + +static void cc_env_sub_prim_mul__t0_add_t1__add_prim () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + CC_ENV (); + SETSHADE_PRIM (); + T0_ADD_T1 (); +} + +static void cc_env_sub_prim_mul__t0_mul_t1__add_prim () //Added by Gonetz +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + CC_ENV (); + SETSHADE_PRIM (); + T0_MUL_T1 (); +} + +static void cc_env_sub_prim_mul__t0t1a__add_prim () //Added by Gonetz +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_ALPHA, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + CC_ENV (); + SETSHADE_PRIM (); + A_T0_MUL_T1 (); +} + +static void cc_env_sub_prim_mul__t0_inter_t1_using_t1__add_prim () //Added by Gonetz +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + CC_ENV (); + SETSHADE_PRIM (); + T0_INTER_T1_USING_T1 (); +} + +static void cc_env_sub_prim_mul__t0_inter_t1_using_half__add_prim () //Added by Gonetz +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + CC_ENV (); + SETSHADE_PRIM (); + T0_INTER_T1_USING_FACTOR (0x7F); +} + +static void cc_env_sub_prim_mul__t1_inter_t0_using_t0__add_prim () //Added by Gonetz +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + CC_ENV (); + SETSHADE_PRIM (); + T1_INTER_T0_USING_T0 (); +} + +static void cc_env_sub_shade_mul__t0_mul_t1__add_shade () //Added by Gonetz +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + CC_ENV (); + T0_MUL_T1 (); +} + +static void cc_env_sub_prim_mul__t0a_mul_t1a__add_prim () +{ + CCMB (GR_COMBINE_FUNCTION_BLEND, + GR_COMBINE_FACTOR_TEXTURE_ALPHA, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + CC_PRIM (); + SETSHADE_ENV (); + A_T0_MUL_T1 (); +} + + +static void cc_env_sub_prim_mul_prima_add_prim () //Aded by Gonetz +{ + // * not guaranteed to work if another iterated alpha is set + CCMB (GR_COMBINE_FUNCTION_BLEND, + GR_COMBINE_FACTOR_LOCAL_ALPHA, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + CC_PRIM (); + CA_PRIM (); + SETSHADE_ENV (); +} + +static void cc_env_sub_prim_mul_enva_add_prim () //Aded by Gonetz +{ + // * not guaranteed to work if another iterated alpha is set + CCMB (GR_COMBINE_FUNCTION_BLEND, + GR_COMBINE_FACTOR_OTHER_ALPHA, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + CC_ENV (); + CA_ENV (); + SETSHADE_PRIM (); +} + +static void cc__t0_sub_env_mul_shade__sub_prim_mul_shade_add_prim () +{ + if (cmb.combine_ext) + { + T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_ITRGB, 0, + GR_CMBX_ZERO, 0); + cmb.tex_ccolor = rdp.env_color; + cmb.tex |= 1; + CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_CONSTANT_COLOR, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_ITRGB, 0, + GR_CMBX_B, 0); + CC_PRIM (); + } + else + { + cc_t0_mul_shade (); + } +} + +static void cc_env_sub_prim_mul_shade_add_prim () //Added by Gonetz +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + CC_PRIM (); + MULSHADE_ENVSUBPRIM (); +} + +static void cc_env_sub_prim_mul_shadea_add_prim () //Added by Gonetz +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + CC_PRIM (); + SETSHADE_ENVSUBPRIM (); + MULSHADE_SHADEA (); +} + +static void cc_env_sub_prim_mul__t0_inter_t1_using_prima__add_prim () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + CC_ENV (); + SETSHADE_PRIM (); + wxUint8 factor = (wxUint8)(rdp.prim_color&0xFF); + T0_INTER_T1_USING_FACTOR (factor); +} + +static void cc_env_sub_prim_mul__t0_inter_t1_using_primlod__add_prim () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + CC_ENV (); + SETSHADE_PRIM (); + T0_INTER_T1_USING_FACTOR (lod_frac); +} + +static void cc_env_sub_primshade_mul_t0_add_primshade () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + CC_ENV (); + MULSHADE_PRIM (); + USE_T0 (); +} + +static void cc_env_sub_primshade_mul_t1_add_primshade () +{ + // cc_prim_mul_shade(); + // return; + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + CC_ENV (); + MULSHADE_PRIM (); + USE_T0 (); +} + +static void cc_env_sub_shade_mul_t0_add_shade () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + CC_ENV (); + USE_T0 (); +} + +static void cc__env_sub_shade_mul_t0_add_shade__mul_prim () +{ + if (cmb.combine_ext) + { + T0CCMBEXT(GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_X, + GR_CMBX_ITRGB, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_LOCAL_TEXTURE_RGB, 0, + GR_CMBX_B, 0); + cmb.tex |= 1; + cmb.tex_ccolor = rdp.prim_color; + CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_ITRGB, GR_FUNC_MODE_ZERO, + GR_CMBX_CONSTANT_COLOR, 0, + GR_CMBX_ZERO, 0); + CC_PRIM() ; + } + else + { + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + CC_ENV (); + MULSHADE_PRIM (); + USE_T0 (); + } +} + +static void cc_env_sub_shade_mul_t1_add_shade () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + CC_ENV (); + USE_T1 (); +} + +//Added by Gonetz +static void cc_env_sub_shade_mul__t0_inter_t1_using_shadea__add_shade () +{ + if (cmb.combine_ext) + { + CCMBEXT(GR_CMBX_CONSTANT_COLOR, GR_FUNC_MODE_X, + GR_CMBX_ITRGB, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_TEXTURE_RGB, 0, + GR_CMBX_B, 0); + } + else + { + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + } + CC_ENV (); + T0_INTER_T1_USING_SHADEA (); +} + +//Added by Gonetz +static void cc_env_sub_shade_mul_enva_add_shade () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, + GR_COMBINE_FACTOR_OTHER_ALPHA, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + cmb.ccolor = rdp.env_color; +} + +//Added by Gonetz +static void cc_shade_sub_t0_mul_shadea_add_t0 () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_ONE_MINUS_LOCAL_ALPHA, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + MULSHADE_SHADEA (); + USE_T0 (); +} + + +static void cc__t0_mul_shade_mul_shadea__add__t1_mul_one_sub_shadea () +{ + // (t0-0)*shade+0, (cmb-t0)*shadea+t0 + if (cmb.combine_ext) + { + T1CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, + GR_CMBX_ITALPHA, 1, + GR_CMBX_ZERO, 0); + T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_OTHER_TEXTURE_RGB, GR_FUNC_MODE_ZERO, + GR_CMBX_ITRGB, 0, + GR_CMBX_B, 0); + MULSHADE_SHADEA (); + cmb.tex |= 3; + CCMBEXT(GR_CMBX_ITRGB, GR_FUNC_MODE_ZERO, + GR_CMBX_ITALPHA, GR_FUNC_MODE_ZERO, + GR_CMBX_ZERO, 0, + GR_CMBX_TEXTURE_RGB, 0); + } + else + { + cc_t0_mul_shade (); + } +} + +static void cc_shade_sub_prim_mul__t0_inter_t1_using_primlod__add_prim () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + CC_PRIM (); + T0_INTER_T1_USING_FACTOR (lod_frac); +} + +static void cc_shade_sub_prim_mul_t0_add_prim () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + CC_PRIM (); + USE_T0 (); +} + +//Added by Gonetz +static void cc_shade_sub_prim_mul_t1_add_prim () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + CC_PRIM (); + USE_T1 (); +} + +//Added by Gonetz +static void cc_shade_sub_env_mul__t0_mul_t1__add__t0_mul_t1 () +{ + if (cmb.combine_ext) + { + CCMBEXT(GR_CMBX_ITRGB, GR_FUNC_MODE_X, + GR_CMBX_CONSTANT_COLOR, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_TEXTURE_RGB, 0, + GR_CMBX_TEXTURE_RGB, 0); + CC_ENV (); + T0_MUL_T1 (); + } + else + { + cc_t0_mul_t1 (); + } +} + +//Added by Gonetz +static void cc_shade_sub_env_mul_t0_add_prim () +{ + if (rdp.cur_image && (rdp.cur_image->format != 0)) + { + cc_prim (); + return; + } + + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + CC_PRIM (); + SUBSHADE_ENV (); + USE_T0 (); +} + +//Added by Gonetz +static void cc_shade_sub_env_mul__t0_inter_t1_using_primlod__add_prim () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + CC_PRIM (); + SUBSHADE_ENV (); + T0_INTER_T1_USING_FACTOR (lod_frac); +} + +//Added by Gonetz +static void cc_shade_sub_env_mul__t0_inter_t1_using_primlod__add_env () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + CC_ENV (); + T0_INTER_T1_USING_FACTOR (lod_frac); +} + +//Added by Gonetz +static void cc_shade_sub_env_mul__t0_mul_t1__add_env () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + CC_ENV (); + T0_MUL_T1 (); +} + +//Added by Gonetz +static void cc_shade_sub_env_mul__t1_sub_prim_mul_primlod_add_t0__add_env () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + CC_ENV (); + SETSHADE_ENV (); + T1_SUB_PRIM_MUL_PRIMLOD_ADD_T0 (); +} + +//Added by Gonetz +static void cc_shade_sub_env_mul_t0_add_env () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + CC_ENV (); + USE_T0 (); +} + +//Added by Gonetz +static void cc_shade_sub_env_mul_t0_mul_prim_add_prim_mul_env () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + CC_PRIMMULENV (); + SUBSHADE_ENV (); + MULSHADE_PRIM() + USE_T0 (); +} + +//Added by Gonetz +static void cc_shade_sub_env_mul_t1_add_env () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + CC_ENV (); + USE_T1 (); +} + +//Added by Gonetz +static void cc_shade_sub_env_mul_prim_add_t0 () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + SUBSHADE_ENV (); + MULSHADE_PRIM (); + USE_T0 (); +} + +static void cc__t0_add_prim_mul_shade__mul_shade_add_env () +{ + if (!cmb.combine_ext) + { + cc_shade_sub_env_mul_prim_add_t0 (); + return; + } + T1CCMBEXT(GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_X, + GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, + GR_CMBX_ITRGB, 0, + GR_CMBX_B, 0); + T0CCMBEXT(GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_X, + GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, + GR_CMBX_ITRGB, 0, + GR_CMBX_B, 0); + CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_CONSTANT_COLOR, GR_FUNC_MODE_ZERO, + GR_CMBX_ITRGB, 0, + GR_CMBX_B, 0); + cmb.tex_ccolor = rdp.prim_color; + CC_ENV (); + cmb.tex |= 1; +} + +static void cc__t0_add_prim_mul_shade__mul_shade () +{ + if (!cmb.combine_ext) + { + cc_shade_sub_env_mul_prim_add_t0 (); + return; + } + T0CCMBEXT(GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_X, + GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, + GR_CMBX_ITRGB, 0, + GR_CMBX_B, 0); + CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_ZERO, GR_FUNC_MODE_ZERO, + GR_CMBX_ITRGB, 0, + GR_CMBX_ZERO, 0); + cmb.tex_ccolor = rdp.prim_color; + cmb.tex |= 1; +} + +//Added by Gonetz +static void cc_shade_sub_env_mul_prim_add_env () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + SUBSHADE_ENV (); + MULSHADE_PRIM (); + CC_ENV (); +} + +//Added by Gonetz +static void cc_shade_sub_env_mul_prima_add_prim () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + SUBSHADE_ENV (); + MULSHADE_PRIMA (); + CC_PRIM (); +} + +static void cc_shade_sub_env_mul_k5_add_prim () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + SUBSHADE_ENV (); + wxUint32 temp = rdp.prim_color; + rdp.prim_color = rdp.K5; + MULSHADE_PRIMA (); + rdp.prim_color = temp; + CC_PRIM (); +} + +// ** A inter B using C ** +static void cc_t0_inter_t1_using_t1a () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_NONE, + GR_COMBINE_OTHER_TEXTURE); + T0_INTER_T1_USING_T1A (); +} + +static void cc_t0_inter_t1_using_prima () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_NONE, + GR_COMBINE_OTHER_TEXTURE); + wxUint8 factor = (wxUint8)(rdp.prim_color&0xFF); + T0_INTER_T1_USING_FACTOR (factor); +} + +static void cc_t1_inter_t0_using_prima () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_NONE, + GR_COMBINE_OTHER_TEXTURE); + wxUint8 factor = (wxUint8)(rdp.prim_color&0xFF); + T1_INTER_T0_USING_FACTOR (factor); +} + +static void cc_t1_inter_t0_using_prim () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_NONE, + GR_COMBINE_OTHER_TEXTURE); + T1_INTER_T0_USING_PRIM (); +} + +static void cc_t0_inter_t1_using_env () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_NONE, + GR_COMBINE_OTHER_TEXTURE); + T0_INTER_T1_USING_ENV (); +} + +static void cc_t0_inter_t1_using_enva () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_NONE, + GR_COMBINE_OTHER_TEXTURE); + wxUint8 factor = (wxUint8)(rdp.env_color&0xFF); + T0_INTER_T1_USING_FACTOR (factor); +} + +static void cc__t0_inter_t1_using_prim__inter_env_using_enva () +{ + // (t1-t0)*prim+t0, (env-cmb)*env_a+cmb + if (!cmb.combine_ext) + { + cc_t0_inter_t1_using_prima (); + return; + } + T1CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, + GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, + GR_CMBX_ZERO, 0, + GR_CMBX_B, 0); + T0CCMBEXT(GR_CMBX_OTHER_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_TMU_CCOLOR, 0, + GR_CMBX_B, 0); + cmb.tex_ccolor = rdp.prim_color; + cmb.tex |= 3; + CCMBEXT(GR_CMBX_CONSTANT_COLOR, GR_FUNC_MODE_X, + GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_CONSTANT_ALPHA, 0, + GR_CMBX_B, 0); + cmb.ccolor = rdp.env_color; +} + +static void cc__t0_inter_t1_using_shade__inter_env_using_enva () +{ + // (t1-t0)*shade+t0, (env-cmb)*env_a+cmb + if (!cmb.combine_ext) + { + cc_t0_inter_t1_using_enva (); + return; + } + T1CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, + GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, + GR_CMBX_ZERO, 0, + GR_CMBX_B, 0); + T0CCMBEXT(GR_CMBX_OTHER_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_ITRGB, 0, + GR_CMBX_B, 0); + cmb.tex |= 3; + CCMBEXT(GR_CMBX_CONSTANT_COLOR, GR_FUNC_MODE_X, + GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_CONSTANT_ALPHA, 0, + GR_CMBX_B, 0); + cmb.ccolor = rdp.env_color; +} + +//Added by Gonetz +static void cc_t0_inter_t1_using_shade () +{ + if (cmb.combine_ext) + { + T1CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, + GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, + GR_CMBX_ZERO, 0, + GR_CMBX_B, 0); + T0CCMBEXT(GR_CMBX_OTHER_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_ITRGB, 0, + GR_CMBX_B, 0); + cmb.tex |= 3; + CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_ITRGB, GR_FUNC_MODE_ZERO, + GR_CMBX_ZERO, 1, + GR_CMBX_ZERO, 0); + } + else + { + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_NONE, + GR_COMBINE_OTHER_TEXTURE); + T0_INTER_T1_USING_FACTOR (0x7F); + } +} + +//Added by Gonetz +static void cc_t1_inter_t0_using_shade () +{ + if (cmb.combine_ext) + { + T1CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, + GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, + GR_CMBX_ZERO, 0, + GR_CMBX_B, 0); + T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_OTHER_TEXTURE_RGB, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_ITRGB, 0, + GR_CMBX_B, 0); + cmb.tex |= 3; + CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_ITRGB, GR_FUNC_MODE_ZERO, + GR_CMBX_ZERO, 1, + GR_CMBX_ZERO, 0); + } + else + { + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_NONE, + GR_COMBINE_OTHER_TEXTURE); + T0_INTER_T1_USING_FACTOR (0x7F); + } +} + +//Added by Gonetz +static void cc_t1_inter_t0_using_shadea () +{ + if (cmb.combine_ext) + { + CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_ITALPHA, GR_FUNC_MODE_ZERO, + GR_CMBX_ZERO, 1, + GR_CMBX_ZERO, 0); + } + else + { + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_NONE, + GR_COMBINE_OTHER_TEXTURE); + } + T1_INTER_T0_USING_SHADEA (); +} + +//Added by Gonetz +static void cc_t0_inter_t1_using_primlod () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_NONE, + GR_COMBINE_OTHER_TEXTURE); + T0_INTER_T1_USING_FACTOR (lod_frac); +} + +//Added by Gonetz +static void cc_t1_inter_t0_using_primlod () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_NONE, + GR_COMBINE_OTHER_TEXTURE); + T1_INTER_T0_USING_FACTOR (lod_frac); +} + +//Added by Gonetz +static void cc_t1_inter_t0_using_t0 () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_NONE, + GR_COMBINE_OTHER_TEXTURE); + T1_INTER_T0_USING_T0 (); +} + +//Added by Gonetz +static void cc_t0_inter_t1_using_k5 () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_NONE, + GR_COMBINE_OTHER_TEXTURE); + T0_INTER_T1_USING_FACTOR (rdp.K5); +} + +static void cc_t0_inter_env_using_prim () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_NONE, + GR_COMBINE_OTHER_TEXTURE); + USE_T0 (); + + MOD_0 (TMOD_TEX_INTER_COL_USING_COL1); + MOD_0_COL (rdp.env_color & 0xFFFFFF00); + MOD_0_COL1 (rdp.prim_color & 0xFFFFFF00); +} + +//Added by Gonetz +static void cc_t0_inter_prim_using_primlod () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_NONE, + GR_COMBINE_OTHER_TEXTURE); + USE_T0 (); + + MOD_0 (TMOD_TEX_INTER_COLOR_USING_FACTOR); + MOD_0_COL (rdp.prim_color & 0xFFFFFF00); + MOD_0_FAC (lod_frac & 0xFF); +} + +static void cc_t0_inter_shade_using_t0a () +{ + if (cmb.combine_ext) + { + CCMBEXT(GR_CMBX_ITRGB, GR_FUNC_MODE_X, + GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_TEXTURE_ALPHA, 0, + GR_CMBX_B, 0); + USE_T0(); + A_USE_T0(); + } + else + { + //(shade-t0)*t0a+t0 = t0*(1-t0a)+shade*t0a + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + rdp.best_tex = 1; + cmb.tex = 1; + cmb.tmu0_func = GR_COMBINE_FUNCTION_BLEND_LOCAL; + cmb.tmu0_fac = GR_COMBINE_FACTOR_LOCAL_ALPHA; + } +} + +static void cc_t0_inter_shade_using_primlod () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + CC_PRIMLOD(); + cmb.ccolor=(~cmb.ccolor)&0xFFFFFF00; + MULSHADE_PRIMLOD (); + USE_T0 (); + //(shade-t0)*primlod+t0 = t0*(1-primlod)+shade*primlod +} + +//Added by Gonetz +static void cc__env_inter_t0_using_primlod__mul_prim () +{ + //((t0-env)*primlod+env)*prim = t0*prim*primlod+env*prim*(1-primlod); + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + CC_PRIM (); + cmb.ccolor = ((((cmb.ccolor & 0xFF000000) >> 24) * (lod_frac & 0xFF))<<24) | ((((cmb.ccolor & 0x00FF0000) >> 16) * (lod_frac & 0xFF))<<16) | ((((cmb.ccolor & 0x0000FF00) >> 8) * (lod_frac & 0xFF))<<8); + SETSHADE_PRIM (); + SETSHADE_ENV (); + SETSHADE_1MPRIMLOD (); + USE_T0 (); +} + +//Added by Gonetz +static void cc__env_inter_t0_using_shadea__mul_shade () +{ + //((t0-env)*shadea+env)*shade + if (!cmb.combine_ext) + { + cc_t0_mul_shade (); + return; + } + T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_ITALPHA, 0, + GR_CMBX_B, 0); + cmb.tex_ccolor = rdp.env_color; + cmb.tex |= 1; + CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_ZERO, GR_FUNC_MODE_ZERO, + GR_CMBX_ITRGB, 0, + GR_CMBX_ZERO, 0); +} + +//Added by Gonetz +static void cc_env_inter_prim_using_primlod () +{ + if (rdp.prim_color&0xFFFFFF00) + { + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + SETSHADE_PRIMSUBENV (); + SETSHADE_PRIMLOD (); + CC_ENV (); + } + else + { + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + SETSHADE_ENV (); + SETSHADE_PRIMLOD (); + CC_ENV (); + } +} + +static void cc_prim_inter__t0_mul_t1_add_env__using_shadea () +{ + if (cmb.combine_ext) + { + T1CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, + GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, + GR_CMBX_ZERO, 0, + GR_CMBX_B, 0); + T0CCMBEXT(GR_CMBX_OTHER_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_ZERO, + GR_CMBX_LOCAL_TEXTURE_RGB, 0, + GR_CMBX_B, 0); + cmb.tex_ccolor = rdp.env_color; + cmb.tex |= 3; + } + else + { + T0_MUL_T1 (); + } + // * not guaranteed to work if another iterated alpha is set + CCMB (GR_COMBINE_FUNCTION_BLEND, + GR_COMBINE_FACTOR_LOCAL_ALPHA, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + SETSHADE_PRIM (); +} + +static void cc_env_inter__prim_inter_shade_using_t0__using_shadea () +{ + if (!cmb.combine_ext) + { + cc_shade_sub_prim_mul_t0_add_prim (); + return; + } + T0CCMBEXT(GR_CMBX_ITRGB, GR_FUNC_MODE_X, + GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_LOCAL_TEXTURE_RGB, 0, + GR_CMBX_B, 0); + cmb.tex_ccolor = rdp.prim_color; + cmb.tex |= 1; + CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_CONSTANT_COLOR, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_ITALPHA, 0, + GR_CMBX_B, 0); + CC_ENV (); +} + +static void cc_shade_inter__prim_inter_shade_using_t0__using_shadea () +{ + if (!cmb.combine_ext) + { + cc_shade_sub_prim_mul_t0_add_prim (); + return; + } + T0CCMBEXT(GR_CMBX_ITRGB, GR_FUNC_MODE_X, + GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_LOCAL_TEXTURE_RGB, 0, + GR_CMBX_B, 0); + cmb.tex_ccolor = rdp.prim_color; + cmb.tex |= 1; + CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_ITRGB, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_ITALPHA, 0, + GR_CMBX_B, 0); +} + +// ** (A-B)*C+D*E ** +static void cc_one_sub_env_mul_prim_add__t0_mul_env () //Aded by Gonetz +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + CC_ENV (); + SETSHADE_1MENV (); + SETSHADE_PRIM (); + USE_T0 (); +} + +// ** ((A-B)*C+D)*E ** +static void cc_t0_sub_env_mul_prim_mul_shade_add_prim_mul_shade () //Aded by Gonetz +{ + //(t0-env)*shade+shade, (cmb-0)*prim+0 + if (cmb.combine_ext) + { + T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_ITRGB, 0, + GR_CMBX_ZERO, 0); + cmb.tex_ccolor = rdp.env_color; + cmb.tex |= 1; + CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_ITRGB, GR_FUNC_MODE_X, + GR_CMBX_CONSTANT_COLOR, 0, + GR_CMBX_ZERO, 0); + CC_PRIM (); + } + else + { + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + if (rdp.env_color & 0xFFFFFF00) + { + MOD_0 (TMOD_TEX_SUB_COL); + MOD_0_COL (rdp.env_color & 0xFFFFFF00); + } + MULSHADE_PRIM (); + USE_T0 (); + } +} + +static void cc__t1_sub_prim_mul_t0_add_env__mul_shade () //Aded by Gonetz +{ + // (t1-prim)*t0+env, (cmb-0)*shade+0 + if (cmb.combine_ext) + { + T1CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, + GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, + GR_CMBX_ZERO, 0, + GR_CMBX_B, 0); + T0CCMBEXT(GR_CMBX_OTHER_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_LOCAL_TEXTURE_RGB, 0, + GR_CMBX_ZERO, 0); + cmb.tex_ccolor = rdp.prim_color; + cmb.tex |= 3; + CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_CONSTANT_COLOR, GR_FUNC_MODE_X, + GR_CMBX_ITRGB, 0, + GR_CMBX_ZERO, 0); + CC_ENV (); + } + else + { + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + if (rdp.prim_color & 0xFFFFFF00) + { + MOD_1 (TMOD_TEX_SUB_COL); + MOD_1_COL (rdp.prim_color & 0xFFFFFF00); + } + T0_MUL_T1 (); + } +} + +// ** (A inter B using C) * D ** +//Added by Gonetz +static void cc__t0_inter_t1_using_prima__mul_prim () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + wxUint8 factor = (wxUint8)(rdp.prim_color&0xFF); + T0_INTER_T1_USING_FACTOR (factor); + CC_PRIM (); +} + +//Added by Gonetz +static void cc__t1_inter_t0_using_prima__mul_prim () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + wxUint8 factor = (wxUint8)(rdp.prim_color&0xFF); + T1_INTER_T0_USING_FACTOR (factor); + CC_PRIM (); +} + +//Added by Gonetz +static void cc__t0_inter_t1_using_prim__mul_shade () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + T0_INTER_T1_USING_PRIM (); +} + +//Added by Gonetz +static void cc__t0_inter_t1_using_prima__mul_shade () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + wxUint8 factor = (wxUint8)(rdp.prim_color&0xFF); + T0_INTER_T1_USING_FACTOR (factor); +} + +//Added by Gonetz +static void cc__t1_inter_t0_using_prima__mul_shade () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + wxUint8 factor = (wxUint8)(rdp.prim_color&0xFF); + T1_INTER_T0_USING_FACTOR (factor); +} + +static void cc__t0_inter_t1_using_env__mul_shade () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + T0_INTER_T1_USING_ENV (); +} + +static void cc__t0_inter_t1_using_enva__mul_shade () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + wxUint8 factor = (wxUint8)(rdp.env_color&0xFF); + T0_INTER_T1_USING_FACTOR (factor); +} + +static void cc__t0_inter_t1_using_enva__mul_prim () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + CC_PRIM (); + wxUint8 factor = (wxUint8)(rdp.env_color&0xFF); + T0_INTER_T1_USING_FACTOR (factor); +} + +//Added by Gonetz +static void cc__t0_inter_t1_using_enva__mul_env () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + CC_ENV (); + wxUint8 factor = (wxUint8)(rdp.env_color&0xFF); + T0_INTER_T1_USING_FACTOR (factor); +} + +//Added by Gonetz +static void cc__t0_inter_t1_using_primlod__mul_prim () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + CC_PRIM (); + T0_INTER_T1_USING_FACTOR (lod_frac); +} + +//Added by Gonetz +static void cc__t0_inter_t1_using_primlod__mul_prima () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + CC_PRIMA (); + T0_INTER_T1_USING_FACTOR (lod_frac); +} + +//Added by Gonetz +static void cc__t1_mul_primlod_add_t0__mul_prim () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + CC_PRIM (); + T1_MUL_PRIMLOD_ADD_T0 (); +} + +//Added by Gonetz +static void cc__t0_inter_t1_using_primlod__mul_env () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + CC_ENV (); + T0_INTER_T1_USING_FACTOR (lod_frac); +} + +//Added by Gonetz +static void cc__t1_mul_primlod_add_t0__mul_env () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + CC_ENV (); + T1_MUL_PRIMLOD_ADD_T0 (); +} + +//Added by Gonetz +static void cc__t1_inter_t0_using_prim__mul_env () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + CC_ENV (); + T1_INTER_T0_USING_PRIM (); +} + +static void cc__one_sub_shade_mul_t0_add_shade__mul_prim () +{ + if (cmb.combine_ext) + { + T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, + GR_CMBX_ITRGB, GR_FUNC_MODE_ONE_MINUS_X, + GR_CMBX_LOCAL_TEXTURE_RGB, 0, + GR_CMBX_B, 0); + cmb.tex |= 1; + CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_ZERO, GR_FUNC_MODE_ZERO, + GR_CMBX_CONSTANT_COLOR, 0, + GR_CMBX_ZERO, 0); + CC_PRIM (); + } + else + { + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_ONE_MINUS_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + USE_T0 (); + } +} + +static void cc__one_sub_shade_mul_t0_add_shade__mul_env () +{ + if (cmb.combine_ext) + { + T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, + GR_CMBX_ITRGB, GR_FUNC_MODE_ONE_MINUS_X, + GR_CMBX_LOCAL_TEXTURE_RGB, 0, + GR_CMBX_B, 0); + cmb.tex |= 1; + CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_ZERO, GR_FUNC_MODE_ZERO, + GR_CMBX_CONSTANT_COLOR, 0, + GR_CMBX_ZERO, 0); + CC_ENV (); + } + else + { + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_ONE_MINUS_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + USE_T0 (); + } +} + +static void cc__t1_inter_t0_using_prim__mul_shade () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + T1_INTER_T0_USING_PRIM (); +} + +static void cc__t0_inter_t1_using_primlod__mul_shade () +{ + //* + if (rdp.LOD_en && (rdp.mipmap_level == 0) && !(settings.hacks&hack_Fifa98)) + { + cc_t0_mul_shade (); + return; + } + //*/ + if (settings.ucode == 7) + lod_frac = rdp.prim_lodfrac; + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + T0_INTER_T1_USING_FACTOR (lod_frac); +} + +static void cc__t1_inter_t0_using_primlod__mul_shade () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + T1_INTER_T0_USING_FACTOR (lod_frac); +} + +static void cc__t0_inter_t1_using_half__mul_shade () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + T0_INTER_T1_USING_FACTOR (0x7F); +} + +static void cc__t0_inter_t1_using_t0__mul_shade () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + T0_INTER_T1_USING_T0(); +} + +static void cc__t0_inter_t1_using_t1a__mul_shade () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + T0_INTER_T1_USING_T1A(); +} + +static void cc__t0_inter_t1_using_shadea__mul_shade () +{ + if (cmb.combine_ext) + { + CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_ITALPHA, GR_FUNC_MODE_ZERO, + GR_CMBX_ITRGB, 0, + GR_CMBX_ZERO, 0); + } + else + { + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + } + T0_INTER_T1_USING_SHADEA (); +} + +static void cc__t0_inter_t1_using_k5__mul_shade () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + T0_INTER_T1_USING_FACTOR (rdp.K5); +} + +static void cc__t1_inter_t0_using_k5__mul_shade () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + T1_INTER_T0_USING_FACTOR (rdp.K5); +} + +static void cc_t0_inter_prim_using_prima () +{ + if (cmb.combine_ext) + { + T0CCMBEXT(GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_X, + GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_TMU_CALPHA, 0, + GR_CMBX_B, 0); + cmb.tex_ccolor = rdp.prim_color; + cmb.tex |= 1; + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_NONE, + GR_COMBINE_OTHER_TEXTURE); + } + else + { + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + CC_1SUBPRIMA (); + SETSHADE_PRIM (); + SETSHADE_PRIMA (); + USE_T0 (); + } +} + +static void cc__t0_inter_prim_using_t0a__mul_shade () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + MOD_0 (TMOD_TEX_INTER_COL_USING_TEXA); + MOD_0_COL (rdp.prim_color & 0xFFFFFF00); + USE_T0 (); +} + +static void cc__env_inter_prim_using_t0__mul_prim () +{ + // (prim-env)*t0+env, (cmb-0)*prim+0 + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + CC_PRIM (); + MOD_0 (TMOD_COL_INTER_COL1_USING_TEX); + MOD_0_COL (rdp.env_color & 0xFFFFFF00); + MOD_0_COL1 (rdp.prim_color & 0xFFFFFF00); + USE_T0 (); +} + +static void cc__env_inter_prim_using_t0__mul_shade () +{ + // amazing... mace actually uses the blender as part of the combine + if ((rdp.othermode_l & 0xFFFF0000) == 0x03820000 || + (rdp.othermode_l & 0xFFFF0000) == 0x00910000) + { + // blender: + // 1ST = CLR_IN * A_IN + CLR_BL * 1MA + // OUT = 1ST * 0 + 1ST * 1 + + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + MOD_0 (TMOD_COL2_INTER__COL_INTER_COL1_USING_TEX__USING_TEXA); + MOD_0_COL (rdp.env_color & 0xFFFFFF00); + MOD_0_COL1 (rdp.prim_color & 0xFFFFFF00); + MOD_0_COL2 (rdp.blend_color & 0xFFFFFF00); + USE_T0 (); + return; + } + //(prim-env)*t0+env, (shade-0)*cmb+0 + MOD_0 (TMOD_COL_INTER_COL1_USING_TEX); + MOD_0_COL (rdp.env_color & 0xFFFFFF00); + MOD_0_COL1 (rdp.prim_color & 0xFFFFFF00); + USE_T0 (); + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); +} + +static void cc__env_inter_one_using_t0__mul_shade () +{ + //(one-env)*t0+env, (cmb-0)*shade+0 + if (cmb.combine_ext) + { + T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, + GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_ONE_MINUS_X, + GR_CMBX_LOCAL_TEXTURE_RGB, 0, + GR_CMBX_B, 0); + cmb.tex_ccolor = rdp.env_color&0xFFFFFF00; + cmb.tex |= 1; + } + else + { + MOD_0 (TMOD_COL_INTER_COL1_USING_TEX); + MOD_0_COL (rdp.env_color & 0xFFFFFF00); + MOD_0_COL1 (0xFFFFFF00); + USE_T0 (); + } + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); +} + +static void cc_env_inter_one_using__one_sub_t0_mul_primlod () +{ + if (cmb.combine_ext) + { + // (noise-t0)*primlod+0, (1-env)*cmb+env + T0CCMBEXT(GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_X, + GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_DETAIL_FACTOR, 0, + GR_CMBX_ZERO, 0); + cmb.tex_ccolor = rand()&0xFFFFFF00; + cmb.tex |= 1; + percent = (float)(lod_frac) / 255.0f; + cmb.dc0_detailmax = cmb.dc1_detailmax = percent; + cmb.tex |= 1; + } + else + { + USE_T0 (); + } + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_ONE_MINUS_LOCAL, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + CC_ENV (); +} + +static void cc__env_inter_prim_using_prima__mul_shade () +{ + int primr = (rdp.prim_color>>24)&0xFF; + int primg = (rdp.prim_color>>16)&0xFF; + int primb = (rdp.prim_color>>8)&0xFF; + int prima = rdp.prim_color&0xFF; + int envr = (rdp.env_color>>24)&0xFF; + int envg = (rdp.env_color>>16)&0xFF; + int envb = (rdp.env_color>>8)&0xFF; + int r = (((primr-envr)*prima)/256)+envr; + int g = (((primg-envg)*prima)/256)+envg; + int b = (((primb-envb)*prima)/256)+envb; + cmb.ccolor = (r<<24) | (g<<16) | (b<<8); + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); +} + +static void cc__prim_inter_t0_using_env__mul_shade () +{ + // (t0-prim)*env+prim, (cmb-0)*shade+0 + if ((rdp.prim_color & 0xFFFFFF00) == 0) + { + cc_t0_mul_env_mul_shade (); + } + else if (cmb.combine_ext) + { + T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, + GR_CMBX_TMU_CCOLOR, 0, + GR_CMBX_ZERO, 0); + cmb.tex_ccolor = rdp.env_color & 0xFFFFFF00; + cmb.tex |= 1; + CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_CONSTANT_COLOR, GR_FUNC_MODE_X, + GR_CMBX_ITRGB, 0, + GR_CMBX_ZERO, 0); + wxUint32 onesubenv = ~rdp.env_color; + CC_C1MULC2(rdp.prim_color, onesubenv); + } + else + { + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + MOD_0 (TMOD_COL_INTER_TEX_USING_COL1); + MOD_0_COL (rdp.prim_color & 0xFFFFFF00); + MOD_0_COL1 (rdp.env_color & 0xFFFFFF00); + USE_T0 (); + } +} + +static void cc__one_inter_prim_using_t1__mul_shade () +{ + if (cmb.combine_ext) + { + if ((settings.hacks&hack_BAR) && rdp.cur_tile == 1) + { + T0CCMBEXT(GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_X, + GR_CMBX_TMU_CALPHA, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_LOCAL_TEXTURE_RGB, 0, + GR_CMBX_ZERO, 1); + cmb.tex |= 1; + } + else + { + T1CCMBEXT(GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_X, + GR_CMBX_TMU_CALPHA, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_LOCAL_TEXTURE_RGB, 0, + GR_CMBX_ZERO, 1); + T0CCMBEXT(GR_CMBX_OTHER_TEXTURE_RGB, GR_FUNC_MODE_ZERO, + GR_CMBX_OTHER_TEXTURE_RGB, GR_FUNC_MODE_ZERO, + GR_CMBX_ZERO, 0, + GR_CMBX_B, 0); + cmb.tex |= 2; + } + cmb.tex_ccolor = rdp.prim_color | 0xFF; + CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_ITRGB, GR_FUNC_MODE_ZERO, + GR_CMBX_ITRGB, 0, + GR_CMBX_ZERO, 0); + } + else + { + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + if ((settings.hacks&hack_BAR) && rdp.cur_tile == 1) + { + MOD_0 (TMOD_COL_INTER_COL1_USING_TEX); + MOD_0_COL (0xFFFFFF00); + MOD_0_COL1 (rdp.prim_color & 0xFFFFFF00); + USE_T0 (); + } + else + { + MOD_1 (TMOD_COL_INTER_COL1_USING_TEX); + MOD_1_COL (0xFFFFFF00); + MOD_1_COL1 (rdp.prim_color & 0xFFFFFF00); + USE_T1 (); + } + } +} + +static void cc_prim_sub__prim_sub_t0_mul_prima__mul_shade () +{ + // (prim-t0)*prim_a+0, (prim-cmb)*shade+0 + if (cmb.combine_ext) + { + T0CCMBEXT(GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_X, + GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_TMU_CALPHA, 0, + GR_CMBX_ZERO, 0); + cmb.tex_ccolor = rdp.prim_color; + cmb.tex |= 1; + CCMBEXT(GR_CMBX_CONSTANT_COLOR, GR_FUNC_MODE_X, + GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_ITRGB, 0, + GR_CMBX_ZERO, 0); + CC_PRIM(); + } + else + { + if ((rdp.prim_color & 0xFFFFFF00) == 0) + { + cc_t0_mul_prima_mul_shade (); + return; + } + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + MOD_0 (TMOD_COL_INTER_TEX_USING_COL1); + MOD_0_COL (rdp.prim_color & 0xFFFFFF00); + wxUint8 prima = (wxUint8)(rdp.prim_color&0xFF); + MOD_0_COL1 ((prima<<24)|(prima<<16)|(prima<<8)); + USE_T0 (); + } +} + +static void cc__prim_inter_env_using_t0__mul_shade () +{ + // (env-prim)*t0+prim, (cmb-0)*shade+0 + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + MOD_0 (TMOD_COL_INTER_COL1_USING_TEX); + MOD_0_COL (rdp.prim_color & 0xFFFFFF00); + MOD_0_COL1 (rdp.env_color & 0xFFFFFF00); + USE_T0 (); +} + +static void cc__prim_inter_one_using_env__mul_shade () +{ + // (one-prim)*env+prim, (cmb-0)*shade+0 + if ((rdp.prim_color&0xFFFFFF00) == 0) + { + cc_env_mul_shade (); + return; + } + if ((rdp.env_color&0xFFFFFF00) == 0) + { + cc_prim_mul_shade (); + return; + } + if ((rdp.prim_color&0xFFFFFF00) == 0xFFFFFF00 || (rdp.env_color&0xFFFFFF00) == 0xFFFFFF00) + { + cc_shade (); + return; + } + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + CC_1SUBPRIM (); + CC_C1MULC2 (cmb.ccolor, rdp.env_color); + cmb.ccolor=(wxUint8)( min(255, (int)((cmb.ccolor & 0xFF000000) >> 24) + (int)((rdp.prim_color & 0xFF000000) >> 24)) ) << 24 | + (wxUint8)( min(255, (int)((cmb.ccolor & 0x00FF0000) >> 16) + (int)((rdp.prim_color & 0x00FF0000) >> 16)) ) << 16 | + (wxUint8)( min(255, (int)((cmb.ccolor & 0x0000FF00) >> 8) + (int)((rdp.prim_color & 0x0000FF00) >> 8)) ) << 8 ; +} + +static void cc__env_inter_prim_using_t0a__mul_t0 () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_NONE, + GR_COMBINE_OTHER_TEXTURE); + MOD_0 (TMOD_COL_INTER_COL1_USING_TEXA__MUL_TEX); + MOD_0_COL (rdp.env_color & 0xFFFFFF00); + MOD_0_COL1 (rdp.prim_color & 0xFFFFFF00); + USE_T0 (); +} + +static void cc__env_inter_prim_using_t0a__mul_prim () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + CC_PRIM (); + MOD_0 (TMOD_COL_INTER_COL1_USING_TEXA); + MOD_0_COL (rdp.env_color & 0xFFFFFF00); + MOD_0_COL1 (rdp.prim_color & 0xFFFFFF00); + USE_T0 (); +} + +static void cc__env_inter_prim_using__t0_sub_shade_mul_primlod_add_env () +{ + // (t0-shade)*lodf+env, (prim-env)*cmb+env + if (cmb.combine_ext) + { + T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_ZERO, + GR_CMBX_DETAIL_FACTOR, 0, + GR_CMBX_B, 0); + cmb.tex_ccolor = rdp.env_color; + percent = (float)lod_frac / 255.0f; + cmb.dc0_detailmax = cmb.dc1_detailmax = percent; + cmb.tex |= 1; + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + CC_PRIM (); + SETSHADE_ENV (); + } + else + { + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL, + GR_COMBINE_FACTOR_ONE,//TEXTURE_RGB, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE);//CONSTANT); + MOD_0 (TMOD_COL_INTER_COL1_USING_TEX); + MOD_0_COL (rdp.env_color & 0xFFFFFF00); + MOD_0_COL1 (rdp.prim_color & 0xFFFFFF00); + USE_T0 (); + MULSHADE_PRIMSUBENV (); + MULSHADE_PRIMLOD(); + SUBSHADE_PRIMSUBENV (); + } +} + +static void cc__prim_inter_t0_using_t0__mul_shade () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + MOD_0 (TMOD_COL_INTER_TEX_USING_TEX); + MOD_0_COL (rdp.prim_color & 0xFFFFFF00); + USE_T0 (); +} + +static void cc__env_inter_t0_using_t0a__mul_shade () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + MOD_0 (TMOD_COL_INTER_TEX_USING_TEXA); + MOD_0_COL (rdp.env_color & 0xFFFFFF00); + USE_T0 (); +} + +static void cc__env_inter_t0_using_prima__mul_shade () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + MOD_0 (TMOD_COL_INTER_TEX_USING_COL1); + MOD_0_COL (rdp.env_color & 0xFFFFFF00); + wxUint32 prima = rdp.prim_color & 0xFF; + MOD_0_COL1 ((prima<<24)|(prima|16)|(prima<<8)); + USE_T0 (); +} + +static void cc_shade_mul_prima () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_NONE, + GR_COMBINE_OTHER_ITERATED); + MULSHADE_PRIMA (); +} + +static void cc_shade_mul_shadea () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_NONE, + GR_COMBINE_OTHER_ITERATED); + MULSHADE_SHADEA (); +} + +static void cc__t0_mul_shade__inter_env_using_enva () +{ + // (t0-0)*shade+0, (env-cmb)*env_a+cmb ** INC ** + wxUint32 enva = rdp.env_color&0xFF; + if (enva == 0xFF) + cc_env (); + else if (enva == 0) + cc_t0_mul_shade (); + else if (cmb.combine_ext) + { + T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_TMU_CCOLOR, GR_FUNC_MODE_ZERO, + GR_CMBX_ITRGB, 0, + GR_CMBX_B, 0); + cmb.tex |= 1; + CCMBEXT(GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_ITRGB, GR_FUNC_MODE_ZERO, + GR_CMBX_ZERO, 1, + GR_CMBX_ZERO, 0); + MULSHADE_1MENVA (); + CC_COLMULBYTE(rdp.env_color, (rdp.env_color&0xFF)); + cmb.tex_ccolor = cmb.ccolor; + } + else + { + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + INTERSHADE_2 (rdp.env_color & 0xFFFFFF00, rdp.env_color & 0xFF); + USE_T0 (); + MOD_0 (TMOD_TEX_INTER_COLOR_USING_FACTOR); + MOD_0_COL (rdp.env_color & 0xFFFFFF00); + MOD_0_FAC (rdp.env_color & 0xFF); + } +} + +static void cc__t0_mul_shade__inter_one_using_enva () +{ + CCMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_RGB, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + CC_ENVA (); + MULSHADE_1MENVA (); + USE_T0 (); +} + +static void cc__t0_mul_shade__inter_one_using_shadea () +{ + if (cmb.combine_ext) + { + T0CCMBEXT(GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_ZERO, + GR_CMBX_LOCAL_TEXTURE_RGB, GR_FUNC_MODE_X, + GR_CMBX_ITRGB, 0, + GR_CMBX_ZERO, 0); + cmb.tex |= 1; + CCMBEXT(GR_CMBX_ZERO, GR_FUNC_MODE_X, + GR_CMBX_TEXTURE_RGB, GR_FUNC_MODE_ONE_MINUS_X, + GR_CMBX_ITALPHA, 0, + GR_CMBX_B, 0); + } + else + { + cc_t0_mul_shade (); + } +} + +static void cc__prim_mul_shade__inter_env_using_enva () +{ + CCMB (GR_COMBINE_FUNCTION_BLEND, + GR_COMBINE_FACTOR_LOCAL_ALPHA, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + CC_ENV (); + MULSHADE_PRIM (); + SETSHADE_A_ENV (); +} + +static void cc__prim_mul_shade__inter_env_using__prim_mul_shade_alpha () +{ + CCMB (GR_COMBINE_FUNCTION_BLEND, + GR_COMBINE_FACTOR_LOCAL_ALPHA, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + CC_ENV (); + MULSHADE_PRIM (); + MULSHADE_A_PRIM (); +} + + +//**************************************************************** + +static void ac_one () +{ + ACMB (GR_COMBINE_FUNCTION_LOCAL, + GR_COMBINE_FACTOR_NONE, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_NONE); + cmb.ccolor |= 0xFF; +} + +static void ac_t0 () +{ + if ((rdp.othermode_l & 0x4000) && (rdp.cycle_mode < 2)) + { + wxUint32 blend_mode = (rdp.othermode_l >> 16); + if (blend_mode == 0x0550) + { + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + CA(rdp.fog_color); + } + else if (blend_mode == 0x55f0) //cmem*afog + cfog*1ma + { + ACMB (GR_COMBINE_FUNCTION_LOCAL, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_NONE); + CA(~rdp.fog_color); + } + else + { + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_NONE, + GR_COMBINE_OTHER_TEXTURE); + } + } + else + { + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_NONE, + GR_COMBINE_OTHER_TEXTURE); + } + A_USE_T0 (); +} + +static void ac_zero () +{ + if (cmb.tex > 0) + { + ac_t0 (); + return; + } + ACMB (GR_COMBINE_FUNCTION_LOCAL, + GR_COMBINE_FACTOR_NONE, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_NONE); + cmb.ccolor &= 0xFFFFFF00; +} + +static void ac_t1 () +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_NONE, + GR_COMBINE_OTHER_TEXTURE); + if ((settings.hacks&hack_BAR) && rdp.tiles[rdp.cur_tile].format == 3) + A_USE_T0 (); + else + A_USE_T1 (); +} + +static void ac_prim () +{ + ACMB (GR_COMBINE_FUNCTION_LOCAL, + GR_COMBINE_FACTOR_NONE, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_NONE); + CA_PRIM (); +} + +static void ac_primlod () +{ + ACMB (GR_COMBINE_FUNCTION_LOCAL, + GR_COMBINE_FACTOR_NONE, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_NONE); + CA_PRIMLOD (); +} + +static void ac_one_sub_t0 () +{ + ACMB (GR_COMBINE_FUNCTION_BLEND_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_ALPHA, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_NONE); + CA (0xFF); + A_USE_T0 (); +} + +static void ac_one_sub_prim () +{ + ACMB (GR_COMBINE_FUNCTION_LOCAL, + GR_COMBINE_FACTOR_NONE, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_NONE); + CA_INVPRIM (); +} + +static void ac_env () +{ + ACMB (GR_COMBINE_FUNCTION_LOCAL, + GR_COMBINE_FACTOR_NONE, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_NONE); + CA_ENV (); +} + +static void ac_shade () +{ + ACMB (GR_COMBINE_FUNCTION_LOCAL, + GR_COMBINE_FACTOR_NONE, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_NONE); +} + +// ** A+B ** +static void ac_t0_add_t1 () //Aded by Gonetz +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_NONE, + GR_COMBINE_OTHER_TEXTURE); + A_T0_ADD_T1 (); +} + +static void ac__t0_mul_prim__add__t1_mul_primlod () //Aded by Gonetz +{ + if (lod_frac == 0) + { + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + CA_PRIM (); + A_USE_T0 (); + } + else if ((rdp.prim_color&0xFF) == 0) + { + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + CA_PRIMLOD (); + A_USE_T1 (); + } + else if ((rdp.prim_color&0xFF) == 0xFF) + { + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_NONE, + GR_COMBINE_OTHER_TEXTURE); + A_T1_MUL_PRIMLOD_ADD_T0(); + } + else + { + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + CA_PRIM (); + A_T0_ADD_T1 (); + } +} + +static void ac_t0_add_prim () //Aded by Gonetz +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + CA_PRIM (); + A_USE_T0 (); +} + +static void ac_t0_add_env () //Aded by Gonetz +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + CA_ENV (); + A_USE_T0 (); +} + +static void ac_t1_add_env () //Added by Gonetz +{ +ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, +GR_COMBINE_FACTOR_ONE, +GR_COMBINE_LOCAL_CONSTANT, +GR_COMBINE_OTHER_TEXTURE); +CA_ENV (); +A_USE_T1 (); +} + +static void ac__t0_add_t1__add_prim () //Aded by Gonetz +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + CA_PRIM (); + A_T0_ADD_T1 (); +} + +static void ac_prim_add_shade () //Aded by Gonetz +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + CA_PRIM (); +} + +static void ac_env_add_shade () //Aded by Gonetz +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + CA_ENV (); +} + +// ** A*B ** +static void ac_t0_mul_t0 () //Added by Gonetz +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_TEXTURE_ALPHA, + GR_COMBINE_LOCAL_NONE, + GR_COMBINE_OTHER_TEXTURE); + A_USE_T0 (); +} + +static void ac_t0_mul_t1 () +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_NONE, + GR_COMBINE_OTHER_TEXTURE); + A_T0_MUL_T1 (); +} + +static void ac_t0_mul_t1_add_t1 () +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_NONE, + GR_COMBINE_OTHER_TEXTURE); + if (cmb.combine_ext) + { + T1ACMBEXT(GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_ZERO, + GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_ZERO, + GR_CMBX_ZERO, 0, + GR_CMBX_LOCAL_TEXTURE_ALPHA, 0); + T0ACMBEXT(GR_CMBX_OTHER_TEXTURE_ALPHA, GR_FUNC_MODE_ZERO, + GR_CMBX_OTHER_TEXTURE_ALPHA, GR_FUNC_MODE_X, + GR_CMBX_LOCAL_TEXTURE_ALPHA, 0, + GR_CMBX_B, 0); + cmb.tex |= 3; + } + else + { + A_T0_MUL_T1 (); + } +} + +static void ac_t0_mul_t1_add_prim () +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + CA_PRIM (); + A_T0_MUL_T1 (); +} + +static void ac_t0_mul_prim () +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + CA_PRIM (); + A_USE_T0 (); +} + +static void ac_t0_mul_prim_mul_primlod () +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + CA_PRIM_MUL_PRIMLOD (); + A_USE_T0 (); +} + +static void ac_t1_mul_prim () +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + CA_PRIM (); + if (rdp.cycle_mode == 0) + A_USE_T0 (); + else + A_USE_T1 (); +} + +//Added by Gonetz +static void ac__t1_sub_one_mul_primlod_add_t0__mul_prim () +{ + if (cmb.combine_ext) + { + T1ACMBEXT(GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_ZERO, + GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_ZERO, + GR_CMBX_ZERO, 0, + GR_CMBX_LOCAL_TEXTURE_ALPHA, 0); + T0ACMBEXT(GR_CMBX_OTHER_TEXTURE_ALPHA, GR_FUNC_MODE_X, + GR_CMBX_TMU_CALPHA, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_DETAIL_FACTOR, 0, + GR_CMBX_LOCAL_TEXTURE_ALPHA, 0); + cmb.tex_ccolor = (cmb.tex_ccolor&0xFFFFFF00) | (0xFF) ; + percent = (float)lod_frac / 255.0f; + } + else + { + cmb.tmu1_a_func = GR_COMBINE_FUNCTION_BLEND_LOCAL; + cmb.tmu1_a_fac = GR_COMBINE_FACTOR_DETAIL_FACTOR; + percent = (255 - lod_frac) / 255.0f; + cmb.tmu0_a_func = GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL_ALPHA; + cmb.tmu0_a_fac = GR_COMBINE_FACTOR_OTHER_ALPHA; + } + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + CA_PRIM (); + cmb.dc0_detailmax = cmb.dc1_detailmax = percent; + cmb.tex |= 3; +} + +static void ac__t0_sub_t1_mul_enva_add_t0__mul_prim () +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + CA_PRIM (); + if (cmb.combine_ext) + { + T1ACMBEXT(GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_ZERO, + GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_ZERO, + GR_CMBX_ZERO, 0, + GR_CMBX_LOCAL_TEXTURE_ALPHA, 0); + T0ACMBEXT(GR_CMBX_OTHER_TEXTURE_ALPHA, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_X, + GR_CMBX_TMU_CALPHA, 0, + GR_CMBX_LOCAL_TEXTURE_ALPHA, 0); + cmb.tex_ccolor = (cmb.tex_ccolor&0xFFFFFF00) | (rdp.env_color&0xFF) ; + cmb.tex |= 3; + } + else + { + A_T0_MUL_T1 (); + } +} + +static void ac__t0_sub_one_mul_enva_add_t0__mul_prim () +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + CA_PRIM (); + if (cmb.combine_ext) + { + T0ACMBEXT(GR_CMBX_ITALPHA, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_X, + GR_CMBX_TMU_CALPHA, 0, + GR_CMBX_LOCAL_TEXTURE_ALPHA, 0); + SETSHADE_A(0xFF); + cmb.tex_ccolor = (cmb.tex_ccolor&0xFFFFFF00) | (rdp.env_color&0xFF) ; + cmb.tex |= 1; + } + else + { + A_USE_T0 (); + } +} + +static void ac__t0_sub_t1_mul_primlod_add_t0__mul_prim () +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + CA_PRIM (); + if (cmb.combine_ext) + { + T1ACMBEXT(GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_ZERO, + GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_ZERO, + GR_CMBX_ZERO, 0, + GR_CMBX_LOCAL_TEXTURE_ALPHA, 0); + T0ACMBEXT(GR_CMBX_OTHER_TEXTURE_ALPHA, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_X, + GR_CMBX_DETAIL_FACTOR, 0, + GR_CMBX_LOCAL_TEXTURE_ALPHA, 0); + cmb.tex |= 3; + percent = (float)lod_frac / 255.0f; + cmb.dc0_detailmax = cmb.dc1_detailmax = percent; + } + else + { + A_T0_INTER_T1_USING_FACTOR (lod_frac); + } +} + +static void ac__t1_sub_prim_mul_primlod_add_t0__mul_prim () +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + CA_PRIM (); + if (cmb.combine_ext) + { + T1ACMBEXT(GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_ZERO, + GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_ZERO, + GR_CMBX_ZERO, 0, + GR_CMBX_LOCAL_TEXTURE_ALPHA, 0); + T0ACMBEXT(GR_CMBX_OTHER_TEXTURE_ALPHA, GR_FUNC_MODE_X, + GR_CMBX_TMU_CALPHA, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_DETAIL_FACTOR, 0, + GR_CMBX_LOCAL_TEXTURE_ALPHA, 0); + cmb.tex |= 3; + cmb.tex_ccolor = (cmb.tex_ccolor&0xFFFFFF00) | (rdp.prim_color&0xFF); + percent = (float)lod_frac / 255.0f; + cmb.dc0_detailmax = cmb.dc1_detailmax = percent; + } + else + { + A_T0_INTER_T1_USING_FACTOR (lod_frac); + } +} + +static void ac__t1_sub_t0_mul_enva_add_t1__mul_prim () +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + CA_PRIM (); + if (cmb.combine_ext) + { + T1ACMBEXT(GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_ZERO, + GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_ZERO, + GR_CMBX_ZERO, 0, + GR_CMBX_LOCAL_TEXTURE_ALPHA, 0); + T0ACMBEXT(GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_OTHER_TEXTURE_ALPHA, GR_FUNC_MODE_X, + GR_CMBX_TMU_CALPHA, 0, + GR_CMBX_B, 0); + cmb.tex |= 3; + cmb.tex_ccolor = (cmb.tex_ccolor&0xFFFFFF00) | (rdp.env_color&0xFF); + } + else + { + wxUint8 factor = (wxUint8)(rdp.env_color&0xFF); + A_T0_INTER_T1_USING_FACTOR (factor); + } +} + +static void ac__t1_sub_t0_mul_primlod__mul_env_add_prim () +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + CA_PRIM (); + if (cmb.combine_ext) + { + T1ACMBEXT(GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_ZERO, + GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_ZERO, + GR_CMBX_ZERO, 0, + GR_CMBX_LOCAL_TEXTURE_ALPHA, 0); + T0ACMBEXT(GR_CMBX_OTHER_TEXTURE_ALPHA, GR_FUNC_MODE_X, + GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_TMU_CALPHA, 0, + GR_CMBX_ZERO, 0); + cmb.tex_ccolor = (cmb.tex_ccolor&0xFFFFFF00) | (wxUint32)((float)(rdp.env_color&0xFF)*(float)rdp.prim_lodfrac/255.0f); + } + else + { + cmb.tmu1_a_func = GR_COMBINE_FUNCTION_LOCAL; + cmb.tmu0_a_func = GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL; + cmb.tmu0_a_fac = GR_COMBINE_FACTOR_DETAIL_FACTOR; + percent = (rdp.prim_lodfrac * (rdp.env_color&0xFF)) / 65025.0f; + cmb.dc0_detailmax = cmb.dc1_detailmax = percent; \ + } + cmb.tex |= 3; +} + +static void ac__t0_sub_one_mul_enva_add_t1__mul_prim () +{ + if (cmb.combine_ext) + { + T1ACMBEXT(GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_ZERO, + GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_ZERO, + GR_CMBX_ZERO, 0, + GR_CMBX_LOCAL_TEXTURE_ALPHA, 0); + T0ACMBEXT(GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_X, + GR_CMBX_OTHER_TEXTURE_ALPHA, GR_FUNC_MODE_ZERO, + GR_CMBX_TMU_CALPHA, 0, + GR_CMBX_B, 0); + cmb.tex_ccolor = (cmb.tex_ccolor&0xFFFFFF00) | (rdp.env_color&0xFF) ; + cmb.tex |= 3; + ACMBEXT(GR_CMBX_TEXTURE_ALPHA, GR_FUNC_MODE_X, + GR_CMBX_CONSTANT_ALPHA, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_ITALPHA, 0, + GR_CMBX_ZERO, 0); + CA_ENV (); + SETSHADE_A_PRIM (); + } + else + { + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + SETSHADE_A_PRIM (); + SETSHADE_A_ENV (); + A_T0_MUL_T1 (); + } +} + +static void ac__t1_mul_prima_add_t0__mul_env () +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + CA_ENV (); + A_T1_MUL_PRIMA_ADD_T0 (); +} + +static void ac__t1_mul_enva_add_t0__mul_prim () +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + CA_PRIM (); + A_T1_MUL_ENVA_ADD_T0 (); +} + +static void ac_t0_mul_primlod () +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + CA_PRIMLOD (); + A_USE_T0 (); +} + +static void ac_t1_mul_primlod () +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + CA_PRIMLOD (); + A_USE_T1 (); +} + +//Added by Gonetz +static void ac__t0_add_t1__mul_prim () +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + CA_PRIM (); + A_T0_ADD_T1 (); +} + +//Added by Gonetz +static void ac__t0_add_t1__mul_primlod () +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + CA_PRIMLOD (); + A_T0_ADD_T1 (); +} + +//Added by Gonetz +static void ac__t0_mul_t1__mul_primlod () +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + CA_PRIMLOD (); + A_T0_MUL_T1 (); +} + +static void ac_t0_mul_env () +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + CA_ENV (); + A_USE_T0 (); +} + +static void ac_t0_mul_env_mul_primlod () +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + CA_ENV_MUL_PRIMLOD (); + A_USE_T0 (); +} + +static void ac_t1_mul_env () //Added by Gonetz +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + CA_ENV (); + // if ((settings.hacks&hack_Powerpuff) && (rdp.last_tile == 0)) + if (rdp.cycle_mode == 0) + A_USE_T0 (); + else + A_USE_T1 (); +} + +static void ac__t1_sub_one_mul_primlod_add_t0__mul_env () +{ + if (cmb.combine_ext) + { + T1ACMBEXT(GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_ZERO, + GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_ZERO, + GR_CMBX_ZERO, 0, + GR_CMBX_LOCAL_TEXTURE_ALPHA, 0); + T0ACMBEXT(GR_CMBX_OTHER_TEXTURE_ALPHA, GR_FUNC_MODE_X, + GR_CMBX_TMU_CALPHA, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_DETAIL_FACTOR, 0, + GR_CMBX_LOCAL_TEXTURE_ALPHA, 0); + cmb.tex_ccolor = (cmb.tex_ccolor&0xFFFFFF00) | (0xFF) ; + percent = (float)lod_frac / 255.0f; + } + else + { + cmb.tmu1_a_func = GR_COMBINE_FUNCTION_BLEND_LOCAL; + cmb.tmu1_a_fac = GR_COMBINE_FACTOR_DETAIL_FACTOR; + percent = (255 - lod_frac) / 255.0f; + cmb.tmu0_a_func = GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL_ALPHA; + cmb.tmu0_a_fac = GR_COMBINE_FACTOR_OTHER_ALPHA; + } + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + CA_ENV (); + cmb.dc0_detailmax = cmb.dc1_detailmax = percent; + cmb.tex |= 3; +} + +static void ac_t0_mul_shade () +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + A_USE_T0 (); +} + +static void ac_t1_mul_shade () +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + A_USE_T1 (); +} + +//Added by Gonetz +static void ac__t0_add_t1__mul_shade () +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + A_T0_ADD_T1 (); +} + +static void ac__t0_mul_primlod_add_t0__mul_shade () +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + if (cmb.combine_ext) + { + T0ACMBEXT(GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_ZERO, + GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_X, + GR_CMBX_DETAIL_FACTOR, 0, + GR_CMBX_LOCAL_TEXTURE_ALPHA, 0); + cmb.tex |= 1; + percent = (float)lod_frac / 255.0f; + cmb.dc0_detailmax = cmb.dc1_detailmax = percent; + } + else + { + A_USE_T0 (); + } +} + +static void ac__t1_mul_prima_add_t0__mul_shade () +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + A_T1_MUL_PRIMA_ADD_T0 (); +} + +//Added by Gonetz +static void ac__t0_sub_t1__mul_shade () +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + if (cmb.combine_ext) + { + T1ACMBEXT(GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_ZERO, + GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_ZERO, + GR_CMBX_ZERO, 0, + GR_CMBX_B, 0); + T0ACMBEXT(GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_X, + GR_CMBX_OTHER_TEXTURE_ALPHA, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_ZERO, 1, + GR_CMBX_ZERO, 0); + cmb.tex |= 3; + } + else + { + A_T0_SUB_T1 (); + } +} + +static void ac__t1_mul_t1_add_t1__mul_shade () +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + if (cmb.combine_ext) + { + T1ACMBEXT(GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_ZERO, + GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_X, + GR_CMBX_LOCAL_TEXTURE_ALPHA, 0, + GR_CMBX_LOCAL_TEXTURE_ALPHA, 0); + T0ACMBEXT(GR_CMBX_OTHER_TEXTURE_ALPHA, GR_FUNC_MODE_X, + GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_ZERO, + GR_CMBX_ZERO, 1, + GR_CMBX_ZERO, 0); + cmb.tex |= 2; + } + else + { + A_USE_T1 (); + } +} + +static void ac__t1_mul_enva_add_t0__mul_shade () +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + A_T1_MUL_ENVA_ADD_T0 (); +} + +static void ac__t1_sub_one_mul_primlod_add_t0__mul_shade () +{ + if (cmb.combine_ext) + { + T1ACMBEXT(GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_ZERO, + GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_ZERO, + GR_CMBX_ZERO, 0, + GR_CMBX_LOCAL_TEXTURE_ALPHA, 0); + T0ACMBEXT(GR_CMBX_OTHER_TEXTURE_ALPHA, GR_FUNC_MODE_X, + GR_CMBX_TMU_CALPHA, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_DETAIL_FACTOR, 0, + GR_CMBX_LOCAL_TEXTURE_ALPHA, 0); + cmb.tex_ccolor = (cmb.tex_ccolor&0xFFFFFF00) | (0xFF) ; + percent = (float)lod_frac / 255.0f; + } + else + { + cmb.tmu1_a_func = GR_COMBINE_FUNCTION_BLEND_LOCAL; + cmb.tmu1_a_fac = GR_COMBINE_FACTOR_DETAIL_FACTOR; + percent = (255 - lod_frac) / 255.0f; + cmb.tmu0_a_func = GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL_ALPHA; + cmb.tmu0_a_fac = GR_COMBINE_FACTOR_OTHER_ALPHA; + } + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + cmb.dc0_detailmax = cmb.dc1_detailmax = percent; + cmb.tex |= 3; +} + +static void ac__t1_sub_shade_mul_primlod_add_t0__mul_shade () +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + CA_PRIM (); + if (cmb.combine_ext) + { + T1ACMBEXT(GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_ZERO, + GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_ZERO, + GR_CMBX_ZERO, 0, + GR_CMBX_LOCAL_TEXTURE_ALPHA, 0); + T0ACMBEXT(GR_CMBX_OTHER_TEXTURE_ALPHA, GR_FUNC_MODE_X, + GR_CMBX_ITALPHA, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_DETAIL_FACTOR, 0, + GR_CMBX_LOCAL_TEXTURE_ALPHA, 0); + cmb.tex |= 3; + percent = (float)lod_frac / 255.0f; + cmb.dc0_detailmax = cmb.dc1_detailmax = percent; + } + else + { + A_T0_INTER_T1_USING_FACTOR (lod_frac); + } +} + +//Added by Gonetz +static void ac_prim_mul_prim () +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + CA_PRIM (); + SETSHADE_A_PRIM (); +} + +//Added by Gonetz +static void ac_prim_mul_primlod () +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + CA_PRIMLOD (); + SETSHADE_A_PRIM (); +} + +static void ac_prim_mul_env () +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + CA_ENV (); + SETSHADE_A_PRIM (); +} + +static void ac__prim_sub_one_mul_primlod_add_t0__mul_env () +{ + if (cmb.combine_ext) + { + T0ACMBEXT(GR_CMBX_ITALPHA, GR_FUNC_MODE_X, + GR_CMBX_TMU_CALPHA, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_DETAIL_FACTOR, 0, + GR_CMBX_LOCAL_TEXTURE_ALPHA, 0); + SETSHADE_A_PRIM (); + cmb.tex_ccolor = (cmb.tex_ccolor&0xFFFFFF00) | (0xFF) ; + percent = (float)lod_frac / 255.0f; + cmb.dc0_detailmax = cmb.dc1_detailmax = percent; + cmb.tex |= 1; + } + else + { + A_USE_T0 (); + } + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + CA_ENV (); +} + +static void ac_prim_mul_shade () +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + CA_PRIM (); +} + +static void ac_env_mul_shade () +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + CA_ENV (); +} + +static void ac_primlod_mul_shade () +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + CA_PRIMLOD (); +} + +// ** A-B ** +static void ac_prim_sub_t0 () +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_NONE, + GR_COMBINE_OTHER_TEXTURE); + A_USE_T0 (); + + MOD_0 (TMOD_FULL_COLOR_SUB_TEX); + MOD_0_COL (rdp.prim_color); +} + +// ** A*B+C ** +static void ac_t0_mul_prim_add_t0 () +{ + if (cmb.combine_ext) + { + ACMBEXT(GR_CMBX_TEXTURE_ALPHA, GR_FUNC_MODE_X, + GR_CMBX_TEXTURE_ALPHA, GR_FUNC_MODE_ZERO, + GR_CMBX_CONSTANT_ALPHA, 0, + GR_CMBX_B, 0); + CA_PRIM (); + A_USE_T0 (); + } + else + ac_t0(); +} + +static void ac_t1_mul_prim_add_t0 () +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_NONE, + GR_COMBINE_OTHER_TEXTURE); + A_T1_MUL_PRIMA_ADD_T0 (); +} + +static void ac__t0_inter_t1_using_t1a__mul_prim_add__t0_inter_t1_using_t1a () +{ + if (cmb.combine_ext) + { + ACMBEXT(GR_CMBX_TEXTURE_ALPHA, GR_FUNC_MODE_X, + GR_CMBX_TEXTURE_ALPHA, GR_FUNC_MODE_ZERO, + GR_CMBX_CONSTANT_ALPHA, 0, + GR_CMBX_B, 0); + CA_PRIM (); + } + else + { + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + CA_PRIM (); + } + A_T0_INTER_T1_USING_T1A (); +} + +static void ac__t1_inter_t0_using_t0a__mul_prim_add__t1_inter_t0_using_t0a () +{ + if (cmb.combine_ext) + { + ACMBEXT(GR_CMBX_TEXTURE_ALPHA, GR_FUNC_MODE_X, + GR_CMBX_TEXTURE_ALPHA, GR_FUNC_MODE_ZERO, + GR_CMBX_CONSTANT_ALPHA, 0, + GR_CMBX_B, 0); + CA_PRIM (); + } + else + { + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + CA_PRIM (); + } + A_T1_INTER_T0_USING_T0A (); +} + +//Added by Gonetz +static void ac_t0_mul_prim_add_env () +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_ALPHA, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + SETSHADE_A_PRIM (); + CA_ENV (); + A_USE_T0 (); +} + +//Added by Gonetz +static void ac__t0_add_t1__mul_prim_add_env () +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_ALPHA, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + SETSHADE_A_PRIM (); + CA_ENV (); + A_T0_ADD_T1 (); +} + +//Aded by Gonetz +static void ac__t0_inter_t1_using_enva__mul_prim_add_env () +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_ALPHA, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + SETSHADE_A_PRIM (); + CA_ENV (); + wxUint8 factor = (wxUint8)(rdp.env_color&0xFF); + A_T0_INTER_T1_USING_FACTOR (factor); +} + +//Aded by Gonetz +static void ac_t0_mul_primlod_add_t0 () +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_NONE, + GR_COMBINE_OTHER_TEXTURE); + if (cmb.combine_ext) + { + T0ACMBEXT(GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_ZERO, + GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_X, + GR_CMBX_DETAIL_FACTOR, 0, + GR_CMBX_LOCAL_TEXTURE_ALPHA, 0); + cmb.tex |= 1; + percent = (float)lod_frac / 255.0f; + cmb.dc0_detailmax = cmb.dc1_detailmax = percent; + } + else + { + A_USE_T0 (); + } +} + +//Aded by Gonetz +static void ac_t1_mul_primlod_add_t0 () +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_NONE, + GR_COMBINE_OTHER_TEXTURE); + A_T1_MUL_PRIMLOD_ADD_T0 (); +} + +//Aded by Gonetz +static void ac_t0_mul_primlod_add_prim () +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_ALPHA, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + CA_PRIMLOD (); + SETSHADE_A_PRIM (); + A_USE_T0 (); +} + +static void ac_t0_mul_primlod_add_env () +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_ALPHA, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + CA_PRIMLOD (); + SETSHADE_A_ENV (); + A_USE_T0 (); +} + +//Aded by Gonetz +static void ac__t0_add_t1__mul_primlod_add_prim () +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_ALPHA, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + CA_PRIMLOD (); + SETSHADE_A_PRIM (); + A_T0_ADD_T1 (); +} + +//Added by Gonetz +static void ac_t0_mul_env_add_prim () +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_ALPHA, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + SETSHADE_A_ENV (); + CA_PRIM (); + A_USE_T0 (); +} + +//Added by Gonetz +static void ac_t1_mul_prim_add_prim () +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_ALPHA, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + SETSHADE_A_PRIM (); + CA_PRIM (); + A_USE_T1 (); +} + +//Added by Gonetz +static void ac_prim_mul_shade_add_shade () +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + CA_PRIM (); +} + +//Added by Gonetz +static void ac_t0_mul_shade_add_prim () +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_ALPHA, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + CA_PRIM (); + A_USE_T0 (); +} + +static void ac_t0_mul_shade_add_env () +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_ALPHA, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + CA_ENV (); + A_USE_T0 (); +} + +static void ac_one_sub_prim_mul__t0_mul_t1__add__prim_mul_shade () +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_ALPHA, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + CA_INVPRIM (); + MULSHADE_A_PRIM (); + A_T0_MUL_T1 (); +} + +// ** A*B+C*D ** +static void ac_t0_mul_prim_add_shade_mul_one_minus_prim () +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_ALPHA, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + MULSHADE_A_1MPRIM (); + CA_PRIM (); + A_USE_T0 (); +} + +// ** (A*B+C)*D ** +static void ac__t0_mul_primlod_add_shade__mul_shade () +{ + if (cmb.combine_ext) + { + T0ACMBEXT(GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_X, + GR_CMBX_ITALPHA, GR_FUNC_MODE_ZERO, + GR_CMBX_DETAIL_FACTOR, 0, + GR_CMBX_B, 0); + cmb.tex |= 1; + percent = (float)lod_frac / 255.0f; + cmb.dc0_detailmax = cmb.dc1_detailmax = percent; + ACMBEXT(GR_CMBX_TEXTURE_ALPHA, GR_FUNC_MODE_X, + GR_CMBX_ZERO, GR_FUNC_MODE_ZERO, + GR_CMBX_ITALPHA, 0, + GR_CMBX_ZERO, 0); + } + else + { + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + A_USE_T0 (); + } +} + +static void ac__t1_mul_primlod_add_shade__mul_shade () +{ + if (cmb.combine_ext) + { + T1ACMBEXT(GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_ZERO, + GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_ZERO, + GR_CMBX_ZERO, 0, + GR_CMBX_B, 0); + T0ACMBEXT(GR_CMBX_OTHER_TEXTURE_ALPHA, GR_FUNC_MODE_X, + GR_CMBX_ITALPHA, GR_FUNC_MODE_ZERO, + GR_CMBX_DETAIL_FACTOR, 0, + GR_CMBX_B, 0); + cmb.tex |= 2; + percent = (float)lod_frac / 255.0f; + cmb.dc0_detailmax = cmb.dc1_detailmax = percent; + ACMBEXT(GR_CMBX_TEXTURE_ALPHA, GR_FUNC_MODE_X, + GR_CMBX_ZERO, GR_FUNC_MODE_ZERO, + GR_CMBX_ITALPHA, 0, + GR_CMBX_ZERO, 0); + } + else + { + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + A_USE_T1 (); + } +} + +// ** ((A-B)*C+D)+E ** +static void ac__t0_sub_t1_mul_prim_add_shade__mul_shade () + //(t0-t1)*prim+shade, (cmb-0)*shade+0 +{ + if (cmb.combine_ext) + { + T1ACMBEXT(GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_ZERO, + GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_ZERO, + GR_CMBX_ZERO, 0, + GR_CMBX_B, 0); + T0ACMBEXT(GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_X, + GR_CMBX_OTHER_TEXTURE_ALPHA, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_TMU_CALPHA, 0, + GR_CMBX_ZERO, 0); + cmb.tex |= 3; + cmb.tex_ccolor = (cmb.tex_ccolor&0xFFFFFF00) | (rdp.prim_color&0xFF); + ACMBEXT(GR_CMBX_TEXTURE_ALPHA, GR_FUNC_MODE_X, + GR_CMBX_ITALPHA, GR_FUNC_MODE_X, + GR_CMBX_ITALPHA, 0, + GR_CMBX_ZERO, 0); + } + else + { + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL_ALPHA, + GR_COMBINE_FACTOR_TEXTURE_ALPHA, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + CA_PRIM (); + A_T1_SUB_T0 (); + } +} + +static void ac__t1_sub_t0_mul_prim_add_shade__mul_shade () + //(t1-t0)*prim+shade, (cmb-0)*shade+0 +{ + if (cmb.combine_ext) + { + T1ACMBEXT(GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_ZERO, + GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_ZERO, + GR_CMBX_ZERO, 0, + GR_CMBX_B, 0); + T0ACMBEXT(GR_CMBX_OTHER_TEXTURE_ALPHA, GR_FUNC_MODE_X, + GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_TMU_CALPHA, 0, + GR_CMBX_ZERO, 0); + cmb.tex |= 3; + cmb.tex_ccolor = (cmb.tex_ccolor&0xFFFFFF00) | (rdp.prim_color&0xFF); + ACMBEXT(GR_CMBX_TEXTURE_ALPHA, GR_FUNC_MODE_X, + GR_CMBX_ITALPHA, GR_FUNC_MODE_X, + GR_CMBX_ITALPHA, 0, + GR_CMBX_ZERO, 0); + } + else + { + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL_ALPHA, + GR_COMBINE_FACTOR_TEXTURE_ALPHA, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + CA_PRIM (); + A_T1_SUB_T0 (); + } +} + +// ** A*B*C ** +static void ac__t0_mul_t1__mul_prim () +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + CA_PRIM (); + if (voodoo.sup_large_tex || rdp.tiles[1].lr_s < 256) //hack for RR64 pause screen + { + A_T0_MUL_T1 (); + } + else + { + A_USE_T0 (); + } +} + +static void ac__t0_mul_t1__mul_env () +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + CA_ENV (); + A_T0_MUL_T1 (); +} + +static void ac__t0_mul_t1__mul_env_mul_shade () +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + MULSHADE_A_ENV (); + A_T0_MUL_T1 (); +} + +static void ac__t0_mul_t1__mul_prim_mul_shade () +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + MULSHADE_A_PRIM (); + A_T0_MUL_T1 (); +} + +static void ac__t0_mul_t1__mul_shade () +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + A_T0_MUL_T1 (); +} + +static void ac__t0_add_prim_mul_shade__mul_shade () +{ + // (shade-0)*prim+t0, (cmb-0)*shade+0 + if (cmb.combine_ext) + { + T0ACMBEXT(GR_CMBX_ITALPHA, GR_FUNC_MODE_X, + GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_ZERO, + GR_CMBX_TMU_CALPHA, 0, + GR_CMBX_B, 0); + cmb.tex |= 1; + cmb.tex_ccolor = (cmb.tex_ccolor&0xFFFFFF00) | (rdp.prim_color&0xFF); + ACMBEXT(GR_CMBX_TEXTURE_ALPHA, GR_FUNC_MODE_X, + GR_CMBX_ZERO, GR_FUNC_MODE_ZERO, + GR_CMBX_ITALPHA, 0, + GR_CMBX_ZERO, 0); + } + else + { + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + MULSHADE_A_PRIM (); + A_USE_T0(); + } +} + +//Added by Gonetz +static void ac_t0_mul_prim_mul_prim () +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + SETSHADE_A_PRIM (); + SETSHADE_A_PRIM (); + A_USE_T0 (); +} + +static void ac_t0_mul_prim_mul_env () +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + CA_PRIMENV(); + A_USE_T0 (); +} + +static void ac_t0_mul_prim_mul_shade () +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + MULSHADE_A_PRIM (); + A_USE_T0 (); +} + +static void ac_t1_mul_prim_mul_shade () +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + MULSHADE_A_PRIM (); + A_USE_T1 (); +} + +static void ac_t0_mul_env_mul_shade () +{ + if (rdp.cur_image && (rdp.cur_image->format != 0)) + { + ac_shade (); + return; + } + + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + MULSHADE_A_ENV (); + A_USE_T0 (); +} + +static void ac_t1_mul_env_mul_shade () +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + MULSHADE_A_ENV (); + A_USE_T1 (); +} + +static void ac_t0_mul_primlod_mul_prim () //Aded by Gonetz +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + cmb.ccolor |= (wxUint32)(lod_frac * (rdp.prim_color&0xFF) / 255); + A_USE_T0 (); +} + +// ** (A+B)*C ** +static void ac_prim_add_env_mul_t0 () //Aded by Gonetz +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + SETSHADE_A_PRIM (); + ADDSHADE_A_ENV (); + A_USE_T0 (); +} + +static void ac_t1_add_prim_mul_env () //Aded by Gonetz +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_ALPHA, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + CA_ENV (); + SETSHADE_A_PRIM (); + SETSHADE_A_ENV (); + A_USE_T1 (); + //(t1+prim)*env = t1*env + prim*env +} + +// ** (A-B)*C ** +static void ac_t0_sub_prim_mul_shade () +{ + if (cmb.combine_ext) + { + T0ACMBEXT(GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_X, + GR_CMBX_TMU_CALPHA, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_ITALPHA, 0, + GR_CMBX_ZERO, 0); + cmb.tex |= 1; + cmb.tex_ccolor = (cmb.tex_ccolor&0xFFFFFF00) | (rdp.prim_color&0xFF); + ACMBEXT(GR_CMBX_TEXTURE_ALPHA, GR_FUNC_MODE_X, + GR_CMBX_ITALPHA, GR_FUNC_MODE_ZERO, + GR_CMBX_ZERO, 1, + GR_CMBX_ZERO, 0); + } else { + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + MULSHADE_A_PRIM (); + A_USE_T0 (); + } +} + +static void ac_t0_sub_prim_mul_shade_mul_env () +{ + if (cmb.combine_ext) + { + T0ACMBEXT(GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_X, + GR_CMBX_TMU_CALPHA, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_ITALPHA, 0, + GR_CMBX_ZERO, 0); + cmb.tex |= 1; + cmb.tex_ccolor = (cmb.tex_ccolor&0xFFFFFF00) | (rdp.prim_color&0xFF); + ACMBEXT(GR_CMBX_TEXTURE_ALPHA, GR_FUNC_MODE_X, + GR_CMBX_ITALPHA, GR_FUNC_MODE_ZERO, + GR_CMBX_CONSTANT_ALPHA, 0, + GR_CMBX_ZERO, 0); + CA_ENV (); + } else { + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + MULSHADE_A_PRIM (); + MULSHADE_A_ENV (); + A_USE_T0 (); + } +} + +static void ac_t0_sub_shade_mul_prim () +{ + if (cmb.combine_ext) + { + T0ACMBEXT(GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_X, + GR_CMBX_ITALPHA, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_TMU_CALPHA, 0, + GR_CMBX_ZERO, 0); + cmb.tex |= 1; + cmb.tex_ccolor = (cmb.tex_ccolor&0xFFFFFF00) | (rdp.prim_color&0xFF); + ACMBEXT(GR_CMBX_TEXTURE_ALPHA, GR_FUNC_MODE_X, + GR_CMBX_ITALPHA, GR_FUNC_MODE_ZERO, + GR_CMBX_ZERO, 1, + GR_CMBX_ZERO, 0); + } else { + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + MULSHADE_A_PRIM (); + A_USE_T0 (); + } +} + +static void ac__t0_mul_t1__sub_prim_mul_shade () //Aded by Gonetz +{ + if (cmb.combine_ext) + { + ACMBEXT(GR_CMBX_TEXTURE_ALPHA, GR_FUNC_MODE_X, + GR_CMBX_CONSTANT_ALPHA, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_ITALPHA, 0, + GR_CMBX_ZERO, 0); + CA_PRIM(); + } + else + { + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + } + A_T0_MUL_T1 (); +} + +static void ac__one_sub_t1_mul_t0_add_shade__sub_prim_mul_shade () //Aded by Gonetz +{ + // (1-t1)*t0+shade, (cmb-prim)*shade+0 + if (cmb.combine_ext) + { + T1ACMBEXT(GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_ZERO, + GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_ZERO, + GR_CMBX_ZERO, 0, + GR_CMBX_B, 0); + T0ACMBEXT(GR_CMBX_OTHER_TEXTURE_ALPHA, GR_FUNC_MODE_ONE_MINUS_X, + GR_CMBX_ITALPHA, GR_FUNC_MODE_ZERO, + GR_CMBX_LOCAL_TEXTURE_ALPHA, 0, + GR_CMBX_B, 0); + cmb.tex |= 3; + ACMBEXT(GR_CMBX_TEXTURE_ALPHA, GR_FUNC_MODE_X, + GR_CMBX_CONSTANT_ALPHA, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_ITALPHA, 0, + GR_CMBX_ZERO, 0); + CA_PRIM(); + } + else + { + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + A_T0_MUL_T1 (); + } +} + +static void ac__t1_mul_primlod_add_t0__sub_prim_mul_shade () +{ + if (cmb.combine_ext) + { + ACMBEXT(GR_CMBX_TEXTURE_ALPHA, GR_FUNC_MODE_X, + GR_CMBX_CONSTANT_ALPHA, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_ITALPHA, 0, + GR_CMBX_ZERO, 0); + CA_PRIM (); + } + else + { + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + } + A_T1_MUL_PRIMLOD_ADD_T0 (); +} + +static void ac__t1_mul_primlod_add_t0__sub_env_mul_prim () //Aded by Gonetz +{ + if (cmb.combine_ext) + { + ACMBEXT(GR_CMBX_TEXTURE_ALPHA, GR_FUNC_MODE_X, + GR_CMBX_CONSTANT_ALPHA, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_ITALPHA, 0, + GR_CMBX_ZERO, 0); + CA_ENV (); + SETSHADE_A_PRIM (); + } + else + { + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + CA_PRIM (); + } + A_T1_MUL_PRIMLOD_ADD_T0 (); +} + +static void ac__t1_mul_prima_add_t0__sub_env_mul_shade () //Aded by Gonetz +{ + if (cmb.combine_ext) + { + ACMBEXT(GR_CMBX_TEXTURE_ALPHA, GR_FUNC_MODE_X, + GR_CMBX_CONSTANT_ALPHA, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_ITALPHA, 0, + GR_CMBX_ZERO, 0); + CA_ENV (); + } + else + { + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + } + A_T1_MUL_PRIMA_ADD_T0 (); +} + +static void ac_one_sub_t0_mul_prim () //Aded by Gonetz +{ + ACMB (GR_COMBINE_FUNCTION_BLEND_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_ALPHA, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_NONE); + CA_PRIM (); + A_USE_T0 (); +} + +static void ac_one_sub_t0_mul_shade () //Aded by Gonetz +{ + if (rdp.aTBuffTex[0] || rdp.aTBuffTex[1]) + { + ACMB (GR_COMBINE_FUNCTION_BLEND_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_ALPHA, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_NONE); + A_USE_T0 (); + } + else + ac_zero(); +} + +static void ac_one_sub_prim_mul_t0 () //Aded by Gonetz +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_ONE_MINUS_LOCAL, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + CA_PRIM (); + A_USE_T0 (); +} + +static void ac_one_sub_env_mul_t0 () //Aded by Gonetz +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_ONE_MINUS_LOCAL, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + CA_ENV (); + A_USE_T0 (); +} + +static void ac_one_sub_shade_mul_t0 () //Aded by Gonetz +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_ONE_MINUS_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + A_USE_T0 (); +} + +static void ac_one_sub_shade_mul_env () //Aded by Gonetz +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_ONE_MINUS_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + CA_ENV (); +} + +static void ac_prim_sub_shade_mul_t0 () //Aded by Gonetz +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_ALPHA, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + CA_PRIM (); + A_USE_T0 (); +} + +static void ac_prim_sub_shade_mul_prim () //Aded by Gonetz +{ + if (cmb.combine_ext) + { + ACMBEXT(GR_CMBX_CONSTANT_ALPHA, GR_FUNC_MODE_X, + GR_CMBX_ITALPHA, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_CONSTANT_ALPHA, 0, + GR_CMBX_ZERO, 0); + CA_PRIM(); + } + else + { + if (!(rdp.prim_color & 0xFF)) + { + ac_zero(); + } + else + { + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + CA_PRIM(); + } + } +} + +static void ac_shade_sub_env_mul_t0 () //Aded by Gonetz +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_ALPHA, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + CA_ENV (); + A_USE_T0 (); +} + +// ** (A-B)*C*D ** +static void ac_one_sub_t0_mul_prim_mul_shade () //Aded by Gonetz +{ + ACMB (GR_COMBINE_FUNCTION_BLEND_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_ALPHA, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_NONE); + MULSHADE_A_PRIM (); + A_USE_T0 (); +} + +// ** (A+B)*C*D ** +static void ac_one_plus_env_mul_prim_mul_shade () +{ + if (cmb.combine_ext) + { + ACMBEXT(GR_CMBX_ZERO, GR_FUNC_MODE_ONE_MINUS_X, + GR_CMBX_CONSTANT_ALPHA, GR_FUNC_MODE_X, + GR_CMBX_ITALPHA, 0, + GR_CMBX_ZERO, 0); + MULSHADE_A_PRIM (); + CA_ENV(); + } + else + ac_prim_mul_shade (); +} + +// ** (A-B)*C+A ** +static void ac__t0_mul_t1__sub_env_mul_prim_add__t0_mul_t1 () //Aded by Gonetz +{ + if (cmb.combine_ext) + { + ACMBEXT(GR_CMBX_TEXTURE_ALPHA, GR_FUNC_MODE_X, + GR_CMBX_CONSTANT_ALPHA, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_ITALPHA, 0, + GR_CMBX_TEXTURE_ALPHA, 0); + CA_ENV(); + SETSHADE_A_PRIM (); + } + else + { + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_NONE, + GR_COMBINE_OTHER_TEXTURE); + } + A_T0_MUL_T1 (); +} + +// ** (A-B)*C+D ** +static void ac__t0_sub_prim_mul_shade_add_shade__mul_env () //Aded by Gonetz +{ + if (cmb.combine_ext) + { + T0ACMBEXT(GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_X, + GR_CMBX_TMU_CALPHA, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_ITALPHA, 0, + GR_CMBX_ITALPHA, 0); + cmb.tex_ccolor = (cmb.tex_ccolor&0xFFFFFF00) | (rdp.prim_color&0xFF) ; + cmb.tex |= 1; + ACMBEXT(GR_CMBX_ZERO, GR_FUNC_MODE_ZERO, + GR_CMBX_TEXTURE_ALPHA, GR_FUNC_MODE_X, + GR_CMBX_CONSTANT_ALPHA, 0, + GR_CMBX_ZERO, 0); + CA_ENV(); + } + else + { + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + MULSHADE_A_ENV (); + MOD_0 (TMOD_TEX_SUB_COL); + MOD_0_COL (rdp.prim_color & 0xFF); + A_USE_T0 (); + } +} + +static void ac_t0_sub_t1_mul_env_add_env () //Aded by Gonetz +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + CA_ENV(); + A_T0_SUB_T1 (); +} + +static void ac_t0_sub_one_mul_enva_add_t1 () //Aded by Gonetz +{ + if (cmb.combine_ext) + { + T1ACMBEXT(GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_ZERO, + GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_ZERO, + GR_CMBX_ZERO, 0, + GR_CMBX_LOCAL_TEXTURE_ALPHA, 0); + T0ACMBEXT(GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_X, + GR_CMBX_OTHER_TEXTURE_ALPHA, GR_FUNC_MODE_ZERO, + GR_CMBX_TMU_CALPHA, 0, + GR_CMBX_B, 0); + cmb.tex_ccolor = (cmb.tex_ccolor&0xFFFFFF00) | (rdp.env_color&0xFF) ; + cmb.tex |= 3; + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + CA_ENV(); + } + else + { + ac__t0_mul_t1__mul_env (); + } +} + +static void ac_t1_sub_one_mul_enva_add_t0 () //Aded by Gonetz +{ + if (cmb.combine_ext) + { + T1ACMBEXT(GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_ZERO, + GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_ZERO, + GR_CMBX_ZERO, 0, + GR_CMBX_B, 0); + T0ACMBEXT(GR_CMBX_OTHER_TEXTURE_ALPHA, GR_FUNC_MODE_X, + GR_CMBX_ITALPHA, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_TMU_CALPHA, 0, + GR_CMBX_LOCAL_TEXTURE_ALPHA, 0); + cmb.tex_ccolor = (cmb.tex_ccolor&0xFFFFFF00) | (rdp.env_color&0xFF) ; + SETSHADE_A (0xFF); + cmb.tex |= 3; + ACMBEXT(GR_CMBX_TEXTURE_ALPHA, GR_FUNC_MODE_X, + GR_CMBX_ITALPHA, GR_FUNC_MODE_ZERO, + GR_CMBX_ZERO, 1, + GR_CMBX_ZERO, 0); + } + else + { + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_NONE, + GR_COMBINE_OTHER_TEXTURE); + A_USE_T0 (); + } +} + +static void ac_t1_sub_one_mul_primlod_add_t0 () //Aded by Gonetz +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_NONE, + GR_COMBINE_OTHER_TEXTURE); + if (cmb.combine_ext) + { + T1ACMBEXT(GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_ZERO, + GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_ZERO, + GR_CMBX_ZERO, 0, + GR_CMBX_LOCAL_TEXTURE_ALPHA, 0); + T0ACMBEXT(GR_CMBX_OTHER_TEXTURE_ALPHA, GR_FUNC_MODE_X, + GR_CMBX_TMU_CALPHA, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_DETAIL_FACTOR, 0, + GR_CMBX_LOCAL_TEXTURE_ALPHA, 0); + cmb.tex_ccolor = (cmb.tex_ccolor&0xFFFFFF00) | (0xFF) ; + percent = (float)lod_frac / 255.0f; + cmb.dc0_detailmax = cmb.dc1_detailmax = percent; + cmb.tex |= 3; + } + else + { + // A_T0_MUL_T1 (); + // A_T1_MUL_PRIMLOD_ADD_T0 (); + cmb.tmu1_a_func = GR_COMBINE_FUNCTION_BLEND_LOCAL; + cmb.tmu1_a_fac = GR_COMBINE_FACTOR_DETAIL_FACTOR; + percent = (255 - lod_frac) / 255.0f; + cmb.tmu0_a_func = GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL_ALPHA; + cmb.tmu0_a_fac = GR_COMBINE_FACTOR_OTHER_ALPHA; + cmb.dc0_detailmax = cmb.dc1_detailmax = percent; + cmb.tex |= 3; + } +} + +static void ac_t1_sub_prim_mul_shade_add_prim () //Aded by Gonetz +{ + if (cmb.combine_ext) + { + T1ACMBEXT(GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_ZERO, + GR_CMBX_TMU_CALPHA, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_ITALPHA, 0, + GR_CMBX_B, 0); + T0ACMBEXT(GR_CMBX_OTHER_TEXTURE_ALPHA, GR_FUNC_MODE_X, + GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_ZERO, + GR_CMBX_ZERO, 1, + GR_CMBX_ZERO, 0); + cmb.tex_ccolor = (cmb.tex_ccolor&0xFFFFFF00) | (rdp.prim_color&0xFF) ; + cmb.tex |= 2; + ACMBEXT(GR_CMBX_TEXTURE_ALPHA, GR_FUNC_MODE_X, + GR_CMBX_ZERO, GR_FUNC_MODE_X, + GR_CMBX_ZERO, 1, + GR_CMBX_ZERO, 0); + } + else + { + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_ALPHA, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + CA_PRIM (); + MOD_1 (TMOD_TEX_SUB_COL); + MOD_1_COL (rdp.prim_color & 0xFF); + A_USE_T1 (); + } +} + +static void ac_t0_sub_env_mul_prim_add_env () //Aded by Gonetz +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_ALPHA, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + SETSHADE_A_PRIM (); + CA_ENV1MPRIM (); + A_USE_T0 (); + //(t0-env)*prim+env == t0*prim + env*(1-prim) +} + +static void ac_t0_sub_env_mul_shadea_add_env () //Aded by Gonetz +{ + if (!cmb.combine_ext) + { + ac_t0_mul_shade (); + return; + } + T0ACMBEXT(GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_X, + GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_ZERO, + GR_CMBX_ZERO, 1, + GR_CMBX_ZERO, 0); + cmb.tex |= 1; + ACMBEXT(GR_CMBX_TEXTURE_ALPHA, GR_FUNC_MODE_X, + GR_CMBX_CONSTANT_ALPHA, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_ITALPHA, 0, + GR_CMBX_B, 0); + CA_ENV (); +} + +static void ac__one_sub_t0_mul_t1_add_t0__mul_prim () //Aded by Gonetz +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + CA_PRIM (); + rdp.best_tex = 0; + cmb.tex |= 3; + cmb.tmu1_a_func = GR_COMBINE_FUNCTION_LOCAL; + cmb.tmu0_a_func = GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL; + cmb.tmu0_a_fac = GR_COMBINE_FACTOR_ONE_MINUS_LOCAL_ALPHA; +} + +static void ac_one_sub_t0_mul_prim_add_t0 () //Aded by Gonetz +{ + ACMB (GR_COMBINE_FUNCTION_BLEND, + GR_COMBINE_FACTOR_TEXTURE_ALPHA, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + SETSHADE_A_PRIM (); + CA (0xFF); + A_USE_T0 (); +} + +static void ac_one_sub_t0_mul_env_add_t0 () //Aded by Gonetz +{ + ACMB (GR_COMBINE_FUNCTION_BLEND, + GR_COMBINE_FACTOR_TEXTURE_ALPHA, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + SETSHADE_A_ENV (); + CA (0xFF); + A_USE_T0 (); +} + +static void ac_one_sub_t0_mul_primlod_add_prim () //Aded by Gonetz +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_ONE_MINUS_TEXTURE_ALPHA, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + SETSHADE_A_PRIM (); + CA_PRIMLOD(); + A_USE_T0 (); +} + +static void ac_prim_sub_t0_mul_env_add_t0 () //Aded by Gonetz +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_ALPHA, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + CA_INVENV (); + SETSHADE_A_PRIM (); + SETSHADE_A_ENV (); + A_USE_T0 (); + //(prim-t0)*env+t0 = prim*env + t0*(1-env) +} + +static void ac_prim_sub_env_mul_t0_add_env () +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_ALPHA, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + CA_PRIM (); + SETSHADE_A_ENV (); + A_USE_T0 (); +} + +static void ac_prim_sub_env_mul_t1_add_env () +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_ALPHA, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + CA_PRIM (); + SETSHADE_A_ENV (); + A_USE_T1 (); +} + +static void ac_prim_sub_env_mul_t0_add_one () +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_ALPHA, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + CA (0xFF); + SETSHADE_A_PRIMSUBENV (); + A_USE_T0 (); +} + +//Added by Gonetz +static void ac_prim_sub_env_mul_shade_add_env () +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + CA_ENV (); + MULSHADE_A_PRIMSUBENV (); +} + +//Added by Gonetz +static void ac_prim_sub_env_mul_shade_add_env_mul_t1 () +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_ALPHA, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + CA_ENV (); + MULSHADE_A_PRIMSUBENV (); + A_USE_T1 (); +} + +//Added by Gonetz +static void ac_prim_sub_shade_mul_t0_add_shade () +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_ALPHA, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + CA_PRIM (); + A_USE_T0 (); +} + +//Added by Gonetz +static void ac_one_sub_shade_mul_t1_add_shade () +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_ONE_MINUS_LOCAL_ALPHA, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + A_USE_T1 (); +} + +//Added by Gonetz +static void ac_one_sub_env_mul_shade_add_env () +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_ONE_MINUS_LOCAL_ALPHA, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + CA_ENV (); +} + +//Added by Gonetz +static void ac_env_sub_prim_mul_t0_add_prim () +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_ALPHA, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + CA_ENV (); + SETSHADE_A_PRIM (); + A_USE_T0 (); +} + +static void ac_one_sub_t1_add_t0_mul_env () +{ + if (cmb.combine_ext) + { + T1ACMBEXT(GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_ZERO, + GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_ZERO, + GR_CMBX_ZERO, 0, + GR_CMBX_LOCAL_TEXTURE_ALPHA, 0); + T0ACMBEXT(GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_X, + GR_CMBX_OTHER_TEXTURE_ALPHA, GR_FUNC_MODE_ZERO, + GR_CMBX_TMU_CALPHA, 0, + GR_CMBX_B, 1); + cmb.tex_ccolor = (cmb.tex_ccolor&0xFFFFFF00) | (rdp.env_color&0xFF); + cmb.tex |= 3; + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_NONE, + GR_COMBINE_OTHER_TEXTURE); + } + else + { + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + CA_ENV (); + A_T0_ADD_T1(); + cmb.tmu1_a_invert = FXTRUE; + } +} + +static void ac_env_sub_prim_mul_shade_add_prim () //Added by Gonetz +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + CA_PRIM (); + MULSHADE_A_ENVSUBPRIM (); +} + +static void ac_env_sub_primshade_mul_t1_add_primshade () +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_ALPHA, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + CA_ENV (); + MULSHADE_A_PRIM (); + A_USE_T1 (); +} + +static void ac_one_sub_prim_mul_t0_add_prim () +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_ALPHA, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + CA (0xFF); + SETSHADE_A_PRIM (); + A_USE_T0 (); +} + +static void ac_one_sub_prim_mul_t0_add__prim_mul_env () +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_ALPHA, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_CONSTANT); + CA_INVPRIM (); + SETSHADE_A_PRIM (); + SETSHADE_A_ENV (); + A_USE_T0 (); +} + +static void ac_shade_sub_t0_mul_primlod_add_prim () +{ + if (cmb.combine_ext) + { + T0ACMBEXT(GR_CMBX_ITALPHA, GR_FUNC_MODE_X, + GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_TMU_CALPHA, 0, + GR_CMBX_ZERO, 0); + cmb.tex_ccolor = (cmb.tex_ccolor&0xFFFFFF00) | (lod_frac&0xFF); + cmb.tex |= 1; + ACMBEXT(GR_CMBX_CONSTANT_ALPHA, GR_FUNC_MODE_X, + GR_CMBX_ITALPHA, GR_FUNC_MODE_ZERO, + GR_CMBX_ZERO, 1, + GR_CMBX_TEXTURE_ALPHA, 0); + CA_PRIM (); + } + else + ac_t0(); +} + +static void ac_shade_sub_env_mul_t0_add_prim () +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_ALPHA, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + SUBSHADE_A_ENV (); + CA_PRIM (); + A_USE_T0 (); +} + +// ** A inter B using C ** +static void ac_t0_inter_t1_using_prima () +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_NONE, + GR_COMBINE_OTHER_TEXTURE); + wxUint8 factor = (wxUint8)(rdp.prim_color&0xFF); + A_T0_INTER_T1_USING_FACTOR (factor); +} + +static void ac_t1_inter_t0_using_prima () +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_NONE, + GR_COMBINE_OTHER_TEXTURE); + wxUint8 factor = (wxUint8)(rdp.prim_color&0xFF); + A_T1_INTER_T0_USING_FACTOR (factor); +} + +static void ac_t0_inter_t1_using_primlod () +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_NONE, + GR_COMBINE_OTHER_TEXTURE); + A_T0_INTER_T1_USING_FACTOR (lod_frac); +} + +static void ac_t0_inter_t1_using_enva () +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_NONE, + GR_COMBINE_OTHER_TEXTURE); + wxUint8 factor = (wxUint8)(rdp.env_color&0xFF); + A_T0_INTER_T1_USING_FACTOR (factor); +} + +static void ac_t1_inter_t0_using_enva () +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_NONE, + GR_COMBINE_OTHER_TEXTURE); + wxUint8 factor = (wxUint8)(rdp.env_color&0xFF); + A_T1_INTER_T0_USING_FACTOR (factor); +} + +//Added by Gonetz +static void ac_t0_inter_t1_using_t0a () +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_NONE, + GR_COMBINE_OTHER_TEXTURE); + A_T0_INTER_T1_USING_T0A (); +} + +//Added by Gonetz +static void ac_t0_inter_t1_using_t1a () +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_NONE, + GR_COMBINE_OTHER_TEXTURE); + A_T0_INTER_T1_USING_T1A (); +} + +//Added by Gonetz +static void ac_t0_inter_t1_using_shadea () +{ + if (cmb.combine_ext) + { + ACMBEXT(GR_CMBX_TEXTURE_ALPHA, GR_FUNC_MODE_X, + GR_CMBX_ITALPHA, GR_FUNC_MODE_ZERO, + GR_CMBX_ZERO, 1, + GR_CMBX_ZERO, 0); + } + else + { + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_NONE, + GR_COMBINE_OTHER_TEXTURE); + } + A_T0_INTER_T1_USING_SHADEA (); +} + +// ** (A inter B using C) * D ** + +static void ac__t0_inter_t1_using_primlod__mul_prim () +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + CA_PRIM (); + A_T0_INTER_T1_USING_FACTOR (lod_frac); +} + +static void ac__t1_mul_primlod_add_t0__mul_prim () +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + CA_PRIM (); + A_T1_MUL_PRIMLOD_ADD_T0 (); +} + +static void ac__t0_inter_t1_using_primlod__mul_env () +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + CA_ENV (); + A_T0_INTER_T1_USING_FACTOR (lod_frac); +} + +static void ac__t1_mul_primlod_add_t0__mul_env () +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + CA_ENV (); + A_T1_MUL_PRIMLOD_ADD_T0 (); +} + +static void ac__t0_inter_t1_using_primlod__mul_shade () +{ + if (settings.hacks & hack_Makers) + { + //rolling rock issue - it has zero shade alpha and thus rejected by alpha compare + ac_t0_inter_t1_using_primlod(); + return; + } + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + A_T0_INTER_T1_USING_FACTOR (lod_frac); +} + +static void ac__t1_mul_primlod_add_t0__mul_shade () +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + A_T1_MUL_PRIMLOD_ADD_T0 (); +} + +//Added by Gonetz +static void ac__t0_inter_t1_using_prima__mul_env () +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + CA_ENV (); + wxUint8 factor = (wxUint8)(rdp.prim_color&0xFF); + A_T0_INTER_T1_USING_FACTOR (factor); +} + +//Added by Gonetz +static void ac__t1_inter_t0_using_t0a__mul_prim () +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + CA_PRIM (); + A_T1_INTER_T0_USING_T0A (); +} + +static void ac__t1_inter_t0_using_primlod__mul_prim () +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + CA_PRIM (); + A_T0_INTER_T1_USING_FACTOR (lod_frac); +} + +static void ac__t1_inter_t0_using_prima__mul_env () +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + CA_ENV (); + wxUint8 factor = (wxUint8)(rdp.prim_color&0xFF); + A_T1_INTER_T0_USING_FACTOR (factor); +} + +//Added by Gonetz +static void ac__t0_inter_t1_using_prima__mul_shade () +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + wxUint8 factor = (wxUint8)(rdp.prim_color&0xFF); + A_T0_INTER_T1_USING_FACTOR (factor); +} + +static void ac__t1_inter_t0_using_prima__mul_shade () +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + wxUint8 factor = (wxUint8)(rdp.prim_color&0xFF); + A_T1_INTER_T0_USING_FACTOR (factor); +} + +static void ac__t0_inter_t1_using_enva__mul_prim () +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + CA_PRIM (); + wxUint8 factor = (wxUint8)(rdp.env_color&0xFF); + A_T0_INTER_T1_USING_FACTOR (factor); +} + +static void ac__env_sub_one_mul_t1_add_t0__mul_prim () +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + CA_PRIM (); + if (cmb.combine_ext) + { + T1ACMBEXT(GR_CMBX_TMU_CALPHA, GR_FUNC_MODE_X, + GR_CMBX_ITALPHA, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_LOCAL_TEXTURE_ALPHA, 0, + GR_CMBX_ZERO, 0); + T0ACMBEXT(GR_CMBX_OTHER_TEXTURE_ALPHA, GR_FUNC_MODE_X, + GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_X, + GR_CMBX_ZERO, 1, + GR_CMBX_ZERO, 0); + SETSHADE_A(0xFF); + cmb.tex_ccolor = (cmb.tex_ccolor&0xFFFFFF00) | (rdp.env_color&0xFF) ; + cmb.tex |= 3; + } + else + { + wxUint8 factor = (wxUint8)(rdp.env_color&0xFF); + A_T0_INTER_T1_USING_FACTOR (factor); + } +} + +static void ac__t0_inter_t1_using_enva__mul_primlod () +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + CA_PRIMLOD (); + wxUint8 factor = (wxUint8)(rdp.env_color&0xFF); + A_T0_INTER_T1_USING_FACTOR (factor); +} + +static void ac__t1_mul_enva_add_t0__sub_prim_mul_shade () +{ + if (cmb.combine_ext) + { + ACMBEXT(GR_CMBX_TEXTURE_ALPHA, GR_FUNC_MODE_X, + GR_CMBX_CONSTANT_ALPHA, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_ITALPHA, 0, + GR_CMBX_ZERO, 0); + CA_PRIM (); + } + else + { + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + MULSHADE_A_PRIM (); + } + A_T1_MUL_ENVA_ADD_T0 (); +} + +//Added by Gonetz +static void ac__t0_inter_t1_using_t0a__mul_prim () +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + CA_PRIM (); + A_T0_INTER_T1_USING_T0A (); +} + +//Added by Gonetz +static void ac__t0_inter_t1_using_t1a__mul_prim () +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + CA_PRIM (); + A_T0_INTER_T1_USING_T1A (); +} + +static void ac__t0_inter_t1_using_t1a__mul_shade () +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + A_T0_INTER_T1_USING_T1A (); +} + +//Added by Gonetz +static void ac__t0_inter_t1_using_shadea__mul_prim () +{ + if (cmb.combine_ext) + { + ACMBEXT(GR_CMBX_TEXTURE_ALPHA, GR_FUNC_MODE_X, + GR_CMBX_ITALPHA, GR_FUNC_MODE_ZERO, + GR_CMBX_CONSTANT_ALPHA, 0, + GR_CMBX_ZERO, 0); + A_T0_INTER_T1_USING_SHADEA (); + } + else + { + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + A_T0_INTER_T1_USING_FACTOR (0x7F); + } + CA_PRIM (); +} + +//Added by Gonetz +static void ac__t0_inter_t1_using_shadea__mul_env () +{ + if (cmb.combine_ext) + { + ACMBEXT(GR_CMBX_TEXTURE_ALPHA, GR_FUNC_MODE_X, + GR_CMBX_ITALPHA, GR_FUNC_MODE_ZERO, + GR_CMBX_CONSTANT_ALPHA, 0, + GR_CMBX_ZERO, 0); + A_T0_INTER_T1_USING_SHADEA (); + } + else + { + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + A_T0_INTER_T1_USING_FACTOR (0x7F); + } + CA_ENV (); +} + +static void ac__t0_inter_t1_using_primlod__sub_env_mul_shade_add_shade () +{ + if (cmb.combine_ext) + { + ACMBEXT(GR_CMBX_TEXTURE_ALPHA, GR_FUNC_MODE_X, + GR_CMBX_CONSTANT_ALPHA, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_ITALPHA, 0, + GR_CMBX_ALOCAL, 0); + CA_ENV (); + A_T0_INTER_T1_USING_FACTOR (lod_frac); + } + else + ac__t0_inter_t1_using_primlod__mul_shade (); +} + +//Added by Gonetz +static void ac__t0_inter_t1_using_enva__mul_shade () +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + wxUint8 factor = (wxUint8)(rdp.env_color&0xFF); + A_T0_INTER_T1_USING_FACTOR (factor); +} + +static void ac__t0_inter_t1_using_primlod__mul_prim_add_env () +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_ALPHA, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + CA_ENV (); + SETSHADE_A_PRIM (); + A_T0_INTER_T1_USING_FACTOR (lod_frac); +} + +//Added by Gonetz +static void ac__t0_inter_t1_using_primlod__mul_shade_add_prim () +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_ALPHA, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + CA_PRIM (); + A_T0_INTER_T1_USING_FACTOR (lod_frac); +} + +//Added by Gonetz +static void ac__t0_inter_t1_using_primlod__mul_env_add__t0_inter_t1_using_primlod () +{ + if (cmb.combine_ext) + { + ACMBEXT(GR_CMBX_ZERO, GR_FUNC_MODE_ZERO, + GR_CMBX_TEXTURE_ALPHA, GR_FUNC_MODE_X, + GR_CMBX_CONSTANT_ALPHA, 0, + GR_CMBX_B, 0); + CA_ENV (); + } + else + { + ACMB (GR_COMBINE_FUNCTION_BLEND, + GR_COMBINE_FACTOR_TEXTURE_ALPHA, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + SETSHADE_A_ENV (); + CA (0xFF); + } + A_T0_INTER_T1_USING_FACTOR (lod_frac); +} + +static void ac__t1_sub_one_mul_enva_add_t0__mul_prim () +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_TEXTURE); + CA_PRIM (); + if (cmb.combine_ext) + { + T1ACMBEXT(GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_ZERO, + GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_ZERO, + GR_CMBX_ZERO, 0, + GR_CMBX_LOCAL_TEXTURE_ALPHA, 0); + T0ACMBEXT(GR_CMBX_OTHER_TEXTURE_ALPHA, GR_FUNC_MODE_X, + GR_CMBX_TMU_CALPHA, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_DETAIL_FACTOR, 0, + GR_CMBX_LOCAL_TEXTURE_ALPHA, 0); + cmb.tex_ccolor = (cmb.tex_ccolor&0xFFFFFF00) | (0xFF) ; + cmb.tex |= 3; + cmb.dc0_detailmax = cmb.dc1_detailmax = (float)(rdp.env_color&0xFF) / 255.0f; + } + else + { + // (t1-1)*env+t0, (cmb-0)*prim+0 + A_T0_MUL_T1 (); + + MOD_1 (TMOD_TEX_SCALE_FAC_ADD_FAC); + MOD_1_FAC (rdp.env_color & 0xFF); + } +} + +static void ac__one_inter_t0_using_prim__mul_env () +{ + if (cmb.combine_ext) + { + T0ACMBEXT(GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_X, + GR_CMBX_TMU_CALPHA, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_DETAIL_FACTOR, 0, + GR_CMBX_B, 0); + cmb.tex_ccolor = (cmb.tex_ccolor&0xFFFFFF00) | (0xFF) ; + cmb.tex |= 1; + cmb.dc0_detailmax = cmb.dc1_detailmax = (float)(rdp.prim_color&0xFF) / 255.0f; + ACMBEXT(GR_CMBX_TEXTURE_ALPHA, GR_FUNC_MODE_X, + GR_CMBX_CONSTANT_ALPHA, GR_FUNC_MODE_ZERO, + GR_CMBX_CONSTANT_ALPHA, 0, + GR_CMBX_ZERO, 0); + CA_ENV (); + } + else + { + ac_t0_mul_prim_add_env (); + } +} + +static void ac__t1_sub_one_mul_enva_add_t0__mul_shade () +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_LOCAL, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_TEXTURE); + CA_PRIM (); + if (cmb.combine_ext) + { + T1ACMBEXT(GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_ZERO, + GR_CMBX_LOCAL_TEXTURE_ALPHA, GR_FUNC_MODE_ZERO, + GR_CMBX_ZERO, 0, + GR_CMBX_LOCAL_TEXTURE_ALPHA, 0); + T0ACMBEXT(GR_CMBX_OTHER_TEXTURE_ALPHA, GR_FUNC_MODE_X, + GR_CMBX_TMU_CALPHA, GR_FUNC_MODE_NEGATIVE_X, + GR_CMBX_DETAIL_FACTOR, 0, + GR_CMBX_LOCAL_TEXTURE_ALPHA, 0); + cmb.tex_ccolor = (cmb.tex_ccolor&0xFFFFFF00) | 0xFF ; + percent = (rdp.env_color&0xFF) / 255.0f; + cmb.dc0_detailmax = cmb.dc1_detailmax = percent; + cmb.tex |= 3; + } + else + { + wxUint8 factor = (wxUint8)(rdp.env_color&0xFF); + A_T0_INTER_T1_USING_FACTOR (factor); + } +} + +static void ac_zero_sub_prim_mul_t0_add_prim () +{ + ACMB (GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_ALPHA, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_ITERATED); + SETSHADE_A (0); + CA_PRIM (); + A_USE_T0 (); +} + +static void ac_one_sub_t0_mul_primshade () +{ + ACMB (GR_COMBINE_FUNCTION_BLEND_LOCAL, + GR_COMBINE_FACTOR_TEXTURE_ALPHA, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_NONE); + MULSHADE_A_PRIM (); + A_USE_T0 (); +} + +//**************************************************************** +// Combine List +// +// 3/13/02: I have converted the combine descriptions, now using +// the correct values for each slot, instead of a one-for-all- +// slot version. All of the descriptions marked with 'z' have +// not yet been converted or checked. I have not totally redone +// the modes, because they should be for the most part correct +// as they are, even with the wrong descriptions. [Dave2001] +//**************************************************************** + +typedef void (*cmb_func)(); +typedef struct { + wxUint32 key; + cmb_func func; +} COMBINER; + +static COMBINER color_cmb_list[] = { + // { #CCSTART } + // intro, Aidyn Chronicles. Added by Gonetz + // (0-cmb)*env+cmb, (t1-t0)*0+t0 + {0x05083812, cc_t0}, + //terminal, Spacestation Silicon Valley. Added by Gonetz + // (0-0)*0+cmb, (0-0)*0+prim + {0x1fff7fff, cc_prim}, + //chip in Spacestation Silicon Valley intro. Added by Gonetz + // (0-0)*0+cmb, (prim-0)*shade+0 + {0x1fffe4f3, cc_prim_mul_shade}, + // car, beetle adventure racing. Added by Gonetz + // (t1-t0)*t0+t0, (cmb-shade)*prima+shade **can work incorrect** + {0x21128a40, cc__t0_inter_t1_using_t0__sub_shade_mul_prima_add_shade}, + // Treasure opening, zelda + // (t1-prim)*t0+t0, (prim-env)*cmb+env + {0x2132a053, cc_prim_sub_env_mul__t1_sub_prim_mul_t0_add_t0__add_env}, + // yellow carpet, Pokemon Stadium 2 + // (t1-env)*t0+t0, (cmb-0)*shade+0 + {0x2152e4f0, cc__t1_sub_env_mul_t0_add_t0__mul_shade}, + // Water, doubut no mori + // (t1-0)*t0+t0, (prim-0)*shade+cmb + {0x21f204f3, cc__t1_mul_t0_add_t0__add_prim_mul_shade}, + // enemy transparent, paper mario. Addd by Gonetz + // (t1-t0)*t1+t0, (env-prim)*cmb+prim + {0x22126035, cc_env_sub_prim_mul__t0_inter_t1_using_t1__add_prim}, + // snowhead temple, zelda 2. Addd by Gonetz + // (t1-t0)*t1+t0, (cmb-0)*shade+prim + {0x221264f0, cc__t0_inter_t1_using_t1__mul_shade_add_prim}, + // snowhead temple entrance, zelda 2. Addd by Gonetz + // (t1-t0)*t1+t0, (cmb-0)*prim+shade + {0x221283f0, cc__t0_inter_t1_using_t1__mul_prim_add_shade}, + // teleportation, Spacestation Silicon Valley. Added by Gonetz + // (t1-t0)*t1+t0, (prim-env)*cmb+env + {0x2212a053, cc_prim_sub_env_mul__t0_inter_t1_using_t1__add_env}, + // pokemon fainted, Pokemon Stadium 2 + // (prim-t0)*t1+t0 + {0x22132213, cc_prim_sub_t0_mul_t1_add_t0}, + // attack, Ogre Battle 64 + // (1-t0)*t1+t0, (cmb-0)*prim+0 + {0x2216e3f0, cc__t0_inter_one_using_t1__mul_prim}, + // Some gannon spell, zelda + // (t1-0)*t1+t0, (prim-0)*cmb+0 + {0x22f2e0f3, cc__t1_mul_t1_add_t0__mul_prim}, + // battle tanks 2 [Ogy] + // (1-0)*t1+t0, (env-prim)*cmb+prim + {0x22f66035, cc_env_sub_prim_mul__t0_add_t1__add_prim}, + // GASP Fighters + // (1-0)*t1+t0, (shade-0)*cmb+0 + {0x22f6e0f4, cc__t0_add_t1__mul_shade}, + // parts of a car, F1 World Grand Prix. Added by Gonetz + // (1-0)*t1+t0, (cmb-0)*shade+0 + {0x22f6e4f0, cc__t0_add_t1__mul_shade}, + // ???, zelda + // (noise-0)*t1+t0, (prim-env)*cmb+env + {0x22f7a053, cc_prim_sub_env_mul__t0_add_t1__add_env}, + // flashing arrow over buoy, wave race. Added by Gonetz + // (t1-t0)*prim+t0, (env-cmb)*enva+cmb ** INC ** + {0x23120c05, cc__t0_inter_t1_using_prim__inter_env_using_enva}, + // ground, zelda2. Added by Gonetz + // (t1-t0)*prim+t0, (cmb-0)*shade+0 + {0x2312e4f0, cc__t0_inter_t1_using_prim__mul_shade}, + // wwf rules + // (env-t0)*prim+t0 + {0x23152315, cc_t0_inter_env_using_prim}, + // Paper Mario + // (1-t0)*prim+t0, (1-t0)*t0+cmb ** INC ** + {0x23160116, cc_t0_add_prim_mul_one_sub_t0_add_t0}, + // intro, castlevania. Added by Gonetz + // (1-t0)*prim+t0 + {0x23162316, cc_one_sub_t0_mul_prim_add_t0}, + // Explosions, aerofighter's assault + // (1-t0)*prim+t0, (shade-0)*cmb+0 + {0x2316e0f4, cc_t0_mul_shade}, + //beetle adventure racing. Added by Gonetz + // (1-t0)*prim+t0, (cmb-0)*shade+0 **INC** + {0x2316e4f0, cc__t0_inter_one_using_prim__mul_shade}, + // Unknown player background, smash bros + // (noise-t0)*prim+t0 ** INC ** + // {0x23172317, cc_t0}, + {0x23172317, cc_t0_inter_noise_using_prim}, + // paper mario. Added by Gonetz + // (noise-prim)*prim+t0 ** INC ** + {0x23372337, cc_t0_add_prim}, + // strange mirror in stone temple, zelda 2. Added by Gonetz + // (prim-env)*prim+t0, (cmb-0)*prim+0 ** INC ** + {0x2353e3f0, cc__prim_sub_env_mul_prim_add_t0__mul_prim}, + // Gilded sword, zelda 2. Added by Gonetz + // (shade-env)*prim+t0, (cmb-0)*shade+env ** INC ** + {0x2354a4f0, cc__t0_add_prim_mul_shade__mul_shade_add_env}, + // Razor sword, zelda 2. Added by Gonetz + // (shade-env)*prim+t0, (cmb-0)*shade+0 ** INC ** + {0x2354e4f0, cc__t0_add_prim_mul_shade__mul_shade}, + // menu, Mischief Makers. Added by Gonetz + // (0-env)*prim+t0, (cmb-0)*shade+0 + {0x235f235f, cc_t0_sub__prim_mul_env}, + // Deadly Arts logo. Added by Gonetz + // (t0-0)*prim+t0 + {0x23f123f1, cc_t0_mul_prim}, + // pokemon attack, Pokemon Stadium 2. Added by Gonetz + // (shade-0)*prim+t0, (cmb-0)*shade+0 ** INC ** + {0x23f4e4f0, cc_t0_mul_shade}, + // Mischief Makers logo. Added by Gonetz + // (env-0)*prim+t0 + {0x23f523f5, cc_prim_mul_env_add_t0}, + // Taken out bomb, zelda + // (1-0)*prim+t0 + {0x23f623f6, cc_t0_add_prim}, + // waterfall, Dobutsu_no_Mori + // (1-0)*prim+t0, (cmb-0)*shade+t0 + {0x23f624f0, cc__t0_add_prim__mul_shade_add_t0}, + // waterfall, Dobutsu_no_Mori + // (1-0)*prim+t0, (cmb-0)*shade+t1 + {0x23f644f0, cc__t0_add_prim__mul_shade_add_t1}, + // Jabu-Jabu's Belly, zelda + // (noise-0)*prim+t0 + {0x23f723f7, cc_t0_add_prim}, + // carmagedon + // (0-0)*prim+t0 + {0x23ff23ff, cc_t0}, + // water, diddy kong racing. Added by Gonetz + // (t1-t0)*shade+t0, (env-cmb)*env_a+cmb **INC** + {0x24120c05, cc__t0_inter_t1_using_shade__inter_env_using_enva}, + // Advertisement hoarding, Mia Soccer. Added by Gonetz + // (t1-t0)*shade+t0, (1-0)*cmb+0 + {0x2412e0f6, cc_t0_inter_t1_using_shade}, + // ground, f-zero x + // (prim-t0)*shade+t0 ** INC ** + {0x24132413, cc__one_sub_prim_mul_shade__mul_t0_add__prim_mul_shade}, + // intro, F1 Racing Championship. Added by Gonetz + // (env-t0)*shade+t0 ** INC * + {0x24152415, cc_one_sub_t0_mul_shade_add_t0}, + // Sky, pilotwings + // (1-t0)*shade+t0 + {0x24162416, cc_one_sub_t0_mul_shade_add_t0}, + // zelda 2 [Ogy]. Added by Gonetz + // (prim-env)*shade+t0, (prim-prim)*shade+cmb ** INC ** ? + {0x24530433, cc_prim_sub_env_mul_shade_add_t0}, + // waves, Dr. Mario + // (0-center)*shade+t0 + {0x246f246f, cc_t0_sub__shade_mul_center}, + // lums, Rayman2. Added by Gonetz + // (t0-0)*shade+t0 ** INC ** + {0x24f124f1, cc_t0}, //this one works better + // {0x24f124f1, cc_t0_mul_shade}, + // Goemon, mystical ninja. Added by Gonetz + // (prim-0)*shade+t0 + {0x24f324f3, cc_prim_mul_shade_add_t0}, + // Sky, waverace + //z (t1-t0)*env+t0 ** INC ** + {0x25122512, cc_t0_inter_t1_using_env}, + // Rare logo, Jet Force. Added by Gonetz + // (t1-t0)*env+t0, (cmb-0)*prim+0 ** INC ** + {0x2512e3f0, cc__t0_inter_t1_using_enva__mul_prim}, + // ridge recer, unimp log. Added by Gonetz + // (t1-t0)*env+t0, (cmb-0)*shade+0 ** INC ** + {0x2512e4f0, cc__t0_inter_t1_using_env__mul_shade}, + // menu, Mischief Makers. Added by Gonetz + //(prim-t0)*env+t0 ** INC ** + {0x25132513, cc_one_sub_env_mul_t0_add_prim_mul_env}, + // Battle border, quest64 + // (1-t0)*env+t0 + {0x25162516, cc_one_sub_env_mul_t0_add_env}, + // Paper Mario + // (noise-t0)*env+t0 + {0x25172517, cc_t0_inter_noise_using_env}, + // the lamp in the bomb shop in town, zelda 2 [Ogy]. Added by Gonetz + // (t0-t1)*env+t0, (1-env)*prim+cmb ** INC ** + {0x25210356, cc_one_sub_env_mul_prim_add__t0_inter_t1_using_env}, + // Darmani's necklace, zelda 2 [Ogy]. Added by Gonetz + // (prim-shade)*env+t0, (cmb-0)*shade+0 ** INC ** + {0x2543e4f0, cc_t0_mul_shade_add_prim_mul_env}, + // {0x2543e4f0, cc_t0_mul_shade}, + // mystical ninja. Added by Gonetz + // (1-0)*env+t0 + {0x25f625f6, cc_t0_add_env}, + // smoke, Starshot. Added by Gonetz + // (1-0)*env+t0, (1-0)*cmb+0 + {0x25f6e0f6, cc_t0_add_env}, + // mega shock, Paper Mario. Added by Gonetz + // (t1-0)*scale+t0, (env-center)*cmb+prim + {0x26f26065, cc__t0_add__t1_mul_scale__mul_env_sub_center_add_prim}, + // character select, Duck Dodgers. Added by Gonetz + // (prim-t0)*t0_alpha+t0, (cmb-0)*shade+0 **INC** + {0x2813e4f0, cc__t0_inter_prim_using_t0a__mul_shade}, + // intro, Duck Dodgers. Added by Gonetz + // (shade-t0)*t0_alpha+t0 **INC** + {0x28142814, cc_t0_inter_shade_using_t0a}, + // vermilion gym torches, Pokemon Stadium 2. + // (prim-env)*t0_a+t0, (cmb-cmb)*cmb+cmb + {0x28530000, cc_prim_sub_env_mul_t0a_add_t0}, + // F1 World Grand Prix. Added by Gonetz + // (prim-0)*t0_a+t0, (cmb-0)*shade+0 ** INC ** + {0x28f3e4f0, cc__t0a_mul_prim_add_t0__mul_shade}, + // battle tanks 2 [Ogy] + // (env-0)*t0_a+t0, (cmb-0)*shade+0 + {0x28f5e4f0, cc__t0a_mul_env_add_t0__mul_shade}, + // blastcorps, unimp log. Added by Gonetz + // (t1-t0)*t1_alpha+t0 + {0x29122912, cc_t0_inter_t1_using_t1a}, + // paper mario. Added by Gonetz + // (t1-t0)*t1_alpha+t0, (cmb-env)*env_a+env + {0x2912ac50, cc__t0_inter_t1_using_t1a__sub_env_mul_enva_add_env}, + // Rally 2000. Added by Gonetz + // (t1-t0)*t1_alpha+t0, (cmb-0)*shade+0 + {0x2912e4f0, cc__t0_inter_t1_using_t1a__mul_shade}, + // ??? in zelda ending, zelda + // (1-0)*t1_alpha+t0, (prim-env)*cmb+env + {0x29f6a053, cc_prim_sub_env_mul__t0_add_t1a__add_env}, + // Sky, zelda + //z (t1-t0)*prim_a+t0 + {0x2a122a12, cc_t0_inter_t1_using_prima}, + // battle tanks [Ogy] + // (t1-t0)*prim_a+t0, (env-prim)*cmb+prim + {0x2a126035, cc_env_sub_prim_mul__t0_inter_t1_using_prima__add_prim}, + // clothes, zelda 2. Added by Gonetz + // (t1-t0)*prim_a+t0, (prim-env)*cmb+env + {0x2a12a053, cc_prim_sub_env_mul__t0_inter_t1_using_prima__add_env}, + // N64 BIOS + // (t1-t0)*prim_a+t0, (cmb-0)*shade+0 + {0x2a12e0f4, cc__t0_inter_t1_using_prima__mul_shade}, + // flame, Doraemon 2. Added by Gonetz + // (t1-t0)*prim_a+t0, (cmb-0)*prim+0 + {0x2a12e3f0, cc__t0_inter_t1_using_prima__mul_prim}, + // logo, PD. Added by Gonetz + // (t1-t0)*prim_a+t0, (cmb-0)*shade+0 + {0x2a12e4f0, cc__t0_inter_t1_using_prima__mul_shade}, + // Pikachu + // (prim-t0)*prim_a+t0, (env-cmb)*enva+cmb + {0x2a130c05, cc__t0_inter_prim_using_prima__inter_env_using_enva}, + // 1080 snowboarding [Ogy] - 7/03/02 fixed by Dave2001. 15 Mar 2005 fixed by Gonetz. + // (prim-t0)*prim_a+t0 + {0x2a132a13, cc_t0_inter_prim_using_prima}, + // menu background, Paper Mario + // (prim-t0)*prim_a+t0, (prim-t1)*prim_a+t1 + {0x2a134a23, cc_t0_inter_prim_using_prima}, + // {0x2a134a23, cc_t0}, + // Mickey USA + // (prim-t0)*prim_a+t0, (cmb-0)*shade+0 ** INC ** + {0x2a13e4f0, cc_t0_mul_shade}, + // gunfire, Sin and Punishmen. Added by Gonetz + // (env-t0)*prima+t0 **INC** + {0x2a152a15, cc_t0_inter_env_using_prima}, + // Mystical Ninja + // (0-t0)*prima+t0, (prim-env)*cmb+env ** INC ** + {0x2a1fa053, cc_prim_sub_env_mul__t0_sub_t0_mul_prima__add_env}, + // foresight attack, Pokemon Stadium 2. + // (t1-prim)*prim_a+t0, (prim-env)*cmb+env + {0x2a32a053, cc_prim_sub_env_mul__t1_sub_prim_mul_prima_add_t0__add_env}, + // arena, Pokemon Stadium 2. Added by Gonetz + // (shade-prim)*prim_a+t0 ** INC ** + {0x2a342a34, cc_t0_mul_shade}, + // Torches, Paper Mario + // (t1-k4)*prim_a+t0, (t1-k4)*cmb_a+cmb ** INC ** + {0x2a720772, cc_t1_sub_k4_mul_prima_add_t0}, + // GASP Fighters. Added by Gonetz + // (t0-0)*prim_a+t0, (cmb-center)*scale+0 ** INC ** + {0x2af1e660, cc__t0_mul_prima_add_t0__sub_center_mul_scale}, + // F1 World Grand Prix. Added by Gonetz + // (t1-0)*prim_a+t0, (cmb-0)*shade+env + {0x2af2a4f0, cc__t1_mul_prima_add_t0__mul_shade_add_env}, + // tidal wave, Paper Mario. Added by Gonetz + // (prim-0)*prim_a+t0 + {0x2af32af3, cc_prim_mul_prima_add_t0}, + //Spacestation Silicon Valley intro. Added by Gonetz + // (t1-t0)*shade_alpha+t0, (prim-shade)*cmb+shade ** INC ** + {0x2b128043, cc_prim_sub_shade_mul__t0_inter_t1_using_shadea__add_shade}, + // water, Rocket Robot in Wheels + // (t1-t0)*shade_alpha+t0, (env-shade)*cmb+shade ** INC ** + {0x2b128045, cc_env_sub_shade_mul__t0_inter_t1_using_shadea__add_shade}, + // arena, Pokemon Stadium 2 + // (t1-t0)*shade_alpha+t0, (cmb-prim)*env+shade ** INC ** + {0x2b128530, cc__t0_inter_t1_using_shadea__sub_prim_mul_env_add_shade}, + // Rocket Robot in Wheels intro + // (t1-t0)*shade_a+t0, (shade-0)*cmb+0 ** INC ** + {0x2b12e0f4, cc__t0_inter_t1_using_shadea__mul_shade}, + // water, Mickey USA + // (t1-t0)*shade_a+t0, (cmb-0)*shade+0 ** INC ** + {0x2b12e4f0, cc__t0_inter_t1_using_shadea__mul_shade}, + // Extreme G. Added by Gonetz + // (shade-t0)*shade_alpha+t0 + {0x2b142b14, cc_shade_sub_t0_mul_shadea_add_t0}, + // Jet Force Gemini. Added by Gonetz + // (shade-t0)*shade_alpha+t0, (cmb-0)*prim+0 ** INC ** + {0x2b14e3f0, cc_t0_mul_prim_add_shade_mul_shadea_mul_prim}, + // V8-2 + // (env-t0)*shade_alpha+t0, (cmb-0)*shade+0 ** INC ** + {0x2b15e4f0, cc__t0_inter_env_using_shadea__mul_shade}, + // Earthquake pokemon attack, Pokemon Stadium 2 [gokuss4]. Added by Gonetz + // (t1-0)*shade_alpha+t0, (prim-env)*cmb+env ** INC ** + {0x2bf2a053, cc_prim_sub_env_mul__t0_add_t1__add_env}, + // pads, Pokemon Stadium 2. Added by Gonetz + // (0-0)*shade_alpha+t0, (prim-env)*cmba+env + {0x2bffa753, cc_prim_sub_env_mul_t0a_add_env}, + // paper mario. Added by Gonetz + // (t1-t0)*env_a+t0, (1-cmb)*prim+cmb + {0x2c120306, cc_one_sub__t0_inter_t1_using_enva__mul_prim_add__t0_inter_t1_using_enva}, + // Amoeba boss, water temple, zelda + // (t1-t0)*env_a+t0, (cmb-env)*prim+t0 ** INC ** + {0x2c122350, cc__t0_inter_t1_using_enva__sub_env}, + // paper mario. Added by Gonetz + // (t1-t0)*env_a+t0 + {0x2c122c12, cc_t0_inter_t1_using_enva}, + // paper mario. Added by Gonetz + // (t1-t0)*env_a+t0, (1-prim)*cmb+prim + {0x2c126036, cc_one_sub_prim_mul__t0_inter_t1_using_enva__add_prim}, + //Arena, Pokemon Stadium 2 + // (t1-t0)*env_a+t0, (cmb-0)*shade+prim + {0x2c1264f0, cc__t0_inter_t1_using_enva__mul_shade_add_prim}, + // water, jet force. Added by Gonetz + // (t1-t0)*env_a+t0, (prim-shade)*cmb+shade + {0x2c128043, cc_prim_sub_shade_mul__t0_inter_t1_using_enva__add_shade}, + // Faries, zelda + //z (t1-t0)*env_a+t0, (prim-env)*cmb+env + {0x2c12a053, cc_prim_sub_env_mul__t0_inter_t1_using_enva__add_env}, + // paper mario. Added by Gonetz + // (t1-t0)*env_a+t0, (prim-center)*cmb+env + {0x2c12a063, cc_prim_sub_center_mul__t0_inter_t1_using_enva__add_env}, + // pads, Pokemon Stadium 2. Added by Gonetz + // (t1-t0)*env_a+t0, (cmb-prim)*shade+env ** INC ** + {0x2c12a430, cc__t0_inter_t1_using_enva__mul_shade_add_env}, + // Scary dead thing boss, zelda + // (t1-t0)*env_a+t0, (cmb-t1)*cmb_a+env + {0x2c12a720, cc__t0_inter_t1_using_enva__mul_env}, + // something in a menu, PokemonStadium2, [Raziel64] + // (t1-t0)*env_a+t0, (prim-env)*cmb_a+env + {0x2c12a753, cc_prim_sub_env_mul__t0_inter_t1_using_enva_alpha__add_env}, + // Arena, pokemon Stadium + // (t1-t0)*env_a+t0, (cmb-shade)*prim+0 + {0x2c12e340, cc__t0_inter_t1_using_enva__sub_shade_mul_prim}, + // Water in zora's place, zelda + // (t1-t0)*env_a+t0, (cmb-0)*prim+0 + {0x2c12e3f0, cc__t0_inter_t1_using_enva__mul_prim}, + // Ground, zelda + //z (t1-t0)*env_a+t0, (cmb-k5)*shade+cmb_a + {0x2c12e4f0, cc__t0_inter_t1_using_enva__mul_shade}, + // zelda, uninmp log. Added by Gonetz + //(t1-t0)*env_a+t0, (cmb-0)*env+0 + {0x2c12e5f0, cc__t0_inter_t1_using_enva__mul_env}, + // Spheres, waverace + //z (env-t0)*env_a+t0 + {0x2c152c15, cc_t0_inter_env_using_enva},//cc_t0}, + // backgrounds, Mario Golf. Added by Gonetz + // (env-t0)*env_a+t0, (shade-0)*cmb+0 + {0x2c15e0f4, cc__t0_inter_env_using_enva__mul_shade}, + // ground on Volcano level, DKR, [Raziel64] + // (env-t0)*env_a+t0, (cmb-0)*shade+0 + {0x2c15e4f0, cc__t0_inter_env_using_enva__mul_shade}, + // Nintendo 'N', zelda + //z (t0-prim)*env_a+t0, (prim-env)*cmb+env + {0x2c31a053, cc_prim_sub_env_mul__t0_sub_prim_mul_enva_add_t0__add_env}, + // Nintendo title & saria's song, zelda + //z (t1-prim)*env_a+t0, (prim-env)*cmb+env + {0x2c32a053, cc_prim_sub_env_mul__t1_sub_prim_mul_enva_add_t0__add_env}, + // Hover boots flying, zelda + // (t1-prim)*env_a+t0, (prim-0)*cmb+env + {0x2c32a0f3, cc__t1_sub_prim_mul_enva_add_t0__mul_prim_add_env}, + // star beam, paper mario + // (prim-env)*env_a+t0 + {0x2c532c53, cc_prim_sub_env_mul_enva_add_t0}, + // Kotake & koume's hair, zelda + // (t1-0)*env_a+t0, (prim-env)*cmb+env + {0x2cf2a053, cc_prim_sub_env_mul__t1_mul_enva_add_t0__add_env}, + //Goldeneye, [Jeremy]. Added by Gonetz + // (t0-t0)*lodf+t0, (cmb-0)*prim+0 + {0x2d11e3f0, cc_t0_mul_prim}, + // Pilot wings + // (t1-t0)*lodf+t0, (one-cmb)*prim+cmb + {0x2d120306, cc_one_sub_prim_mul__t0_inter_t1_using_primlod__add_prim}, + // Pilot wings + // (t1-t0)*lodf+t0, (one-cmb)*shade+cmb + {0x2d120406, cc_one_sub_shade_mul__t0_inter_t1_using_primlod__add_shade}, + // Indy Racing 2000. Added by Gonetz + // (t1-t0)*lodf+t0, (env-cmb)*prima+cmb ** INC ** + {0x2d120a05, cc_t0_inter_t1_using_primlod}, + // (t1-t0)*lodf+t0 + {0x2d122d12, cc_t0_inter_t1_using_primlod}, + //broken wall, beetle adventure racing. Added by Gonetz + // (t1-t0)*lodf+t0, (shade-prim)*cmb+prim + {0x2d126034, cc_shade_sub_prim_mul__t0_inter_t1_using_primlod__add_prim}, + //Intro, CBFD. Added by Gonetz + // (t1-t0)*lodf+t0, (shade-env)*cmb+prim + // {0x2d126054, cc_shade_sub_env_mul_t0_add_prim}, + {0x2d126054, cc_shade_sub_env_mul__t0_inter_t1_using_primlod__add_prim}, + // bassmasters 2000 [Ogy] + // (t1-t0)*lodf+t0, (env-0)*cmb+prim ** INC ** + {0x2d1260f5, cc_t0_mul_env_add_prim}, + // sign, CBFD. Added by Gonetz + // (t1-t0)*lodf+t0, (cmb-env)*shade+prim ** INC ** + {0x2d126450, cc__t0_inter_t1_using_primlod__sub_env_mul_shade_add_prim}, + // {0x2d126450, cc_t0_sub_env_mul_shade_add_prim}, + // landscape, Cruis'n Exotica. Added by Gonetz + // (t1-t0)*lodf+t0, (cmb-0)*shade+prim + {0x2d1264f0, cc__t0_inter_t1_using_primlod__mul_shade_add_prim}, + // blast corps [Ogy] + // (t1-t0)*lodf+t0, (0-0)*0+shade + {0x2d129fff, cc__t0_inter_t1_using_primlod__mul_shade}, + // End of level, zelda + // (t1-t0)*lodf+t0, (prim-env)*cmb+env + {0x2d12a053, cc_prim_sub_env_mul__t0_inter_t1_using_primlod__add_env}, + // Rocket Robot in Wheels intro + // (t1-t0)*lodf+t0, (shade-env)*cmb+env + {0x2d12a054, cc_shade_sub_env_mul__t0_inter_t1_using_primlod__add_env}, + // basket, Fox Sport + // (t1-t0)*lodf+t0, (prim-env)*t0+env + {0x2d12a153, cc_prim_sub_env_mul__t0_inter_t1_using_primlod__add_env}, + // paper mario. Added by Gonetz + // (t1-t0)*lodf+t0, (cmb-0)*prim+env ** INC ** + {0x2d12a3f0, cc__t0_inter_t1_using_primlod__mul_prim_add_env}, + // Tony Hawk Pro Skater + // (t1-t0)*lodf+t0, (cmb-0)*shade+env + {0x2d12a4f0, cc__t0_inter_t1_using_primlod__mul_shade_add_env}, + // part of a building, Spiderman. Added by Gonetz + // (t1-t0)*lodf+t0, (cmb-env)*cmba+env ** INC ** + {0x2d12a750, cc_t0_inter_t1_using_primlod}, + // Mike Piazza's Strike Zone + // (t1-t0)*lodf+t0, (shade-prim)*cmb+0 + {0x2d12e034, cc_shade_sub_prim_mul__t0_inter_t1_using_primlod}, + // intro, F1 Racing Championship. Added by Gonetz + // (t1-t0)*lodf+t0, (shade-env)*cmb+0 + {0x2d12e054, cc_shade_sub_env_mul__t0_inter_t1_using_primlod}, + // stands, F1 Racing Championship. Added by Gonetz + // (t1-t0)*lodf+t0, (1-env)*cmb+0 + {0x2d12e056, cc_one_sub_env_mul__t0_inter_t1_using_primlod}, + // court, Mario Tennis. Added by Gonetz + // (t1-t0)*lodf+t0, (prim-0)*cmb+0 + {0x2d12e0f3, cc__t0_inter_t1_using_primlod__mul_prim}, + // Rocket Robot in Wheels intro + // (t1-t0)*lodf+t0, (shade-0)*cmb+0 + {0x2d12e0f4, cc__t0_inter_t1_using_primlod__mul_shade}, + // Pilot wings + // (t1-t0)*lodf+t0, (cmb-0)*t0+0 ** INC ** + {0x2d12e1f0, cc_t0_inter_t1_using_primlod}, + // cars wheels, SF Rush 2049. Added by Gonetz + // (t1-t0)*lodf+t0, (cmb-0)*prim+0 + {0x2d12e3f0, cc__t0_inter_t1_using_primlod__mul_prim}, + // Bridge, sf rush + // (t1-t0)*lodf+t0, (cmb-0)*shade+0 + // {0x2d12e4f0, cc_t0_mul_shade}, + {0x2d12e4f0, cc__t0_inter_t1_using_primlod__mul_shade}, + // blast corps [Ogy] + // (t1-t0)*lodf+t0, (t0-0)*shade+0 + {0x2d12e4f1, cc_t0_mul_shade}, + // field, Mike Piazza's Strike Zone + // (t1-t0)*lodf+t0, (cmb-prim)*env+0 ** INC ** + {0x2d12e530, cc__t0_inter_t1_using_primlod__mul_env}, + // radar, Perfect Dark + // (t1-t0)*lodf+t0, (cmb-0)*env+0 + {0x2d12e5f0, cc__t0_inter_t1_using_primlod__mul_env}, + // planet, Blast Corps + // (t1-t0)*lodf+t0, (cmb-0)*prima+0 + {0x2d12eaf0, cc__t0_inter_t1_using_primlod__mul_prima}, + // zelda 2. Added by Gonetz + // (t0-t0)*primlod+t0, (prim-env)*cmb+env + {0x2e11a053, cc_prim_sub_env_mul_t0_add_env}, + // zelda 2. Added by Gonetz + // (t1-t0)*primlod+t0, (0-0)*shade+cmb + {0x2e1204ff, cc_t0_inter_t1_using_primlod}, + // zelda 2. Added by Gonetz + // (t1-t0)*primlod+t0, (env-prim)*primlod+cmb + {0x2e120d35, cc_prim_sub_env_mul_primlod_add__t0_inter_t1_using_primlod}, + // lamppost, Ridge Racer. Added by Gonetz + // (t1-t0)*primlod+t0 + {0x2e122e12, cc_t0_inter_t1_using_primlod}, + // Hearts, zelda + //z (t1-t0)*primlod+t0, (shade-prim)*cmb+prim + {0x2e126034, cc_shade_sub_prim_mul__t0_inter_t1_using_primlod__add_prim}, + // Sunny Day, Pokemon Stadium 2 [gokuss4]. Added by Gonetz + // (t1-t0)*primlod+t0, (env-prim)*cmb+prim + {0x2e126035, cc_env_sub_prim_mul__t0_inter_t1_using_primlod__add_prim}, + // snowhead temple, zelda 2. Added by Gonetz + // (t1-t0)*primlod+t0, (cmb-env)*shade+prim ** INC ** + {0x2e126450, cc__t0_inter_t1_using_primlod__mul_shade_add_prim}, + // snow on a wall, snowhead temple, zelda 2. Added by Gonetz + // (t1-t0)*primlod+t0, (cmb-0)*shade+prim + {0x2e1264f0, cc__t0_inter_t1_using_primlod__mul_shade_add_prim}, + // Morning Sun, Pokemon Stadium 2 [gokuss4]. Added by Gonetz + // (t1-t0)*primlod+t0, (cmb-0)*0+prim + {0x2e127ff0, cc_prim}, + // arena, Pokemon Stadium 2. Added by Gonetz + // (t1-t0)*primlod+t0, (cmb-prim)*shade+shade ** INC ** + {0x2e128430, cc__t0_inter_t1_using_primlod__mul_shade}, + // Pokemon Stadium 2. Added by Gonetz + // (t1-t0)*primlod+t0, (cmb-env)*cmb+env ** INC ** + {0x2e12a050, cc_t0_inter_t1_using_primlod}, + // End of level heart, zelda + // (t1-t0)*primlod+t0, (prim-env)*cmb+env + {0x2e12a053, cc_prim_sub_env_mul__t0_inter_t1_using_primlod__add_env}, + // Huge turtle appearance, zelda 2. Added by Gonetz + // (t1-t0)*primlod+t0, (1-env)*cmb+env + {0x2e12a056, cc_one_sub_env_mul__t0_inter_t1_using_primlod__add_env}, + // frozen octorok, zelda 2. Added by Gonetz + // (t1-t0)*primlod+t0, (prim-env)*t1+env + {0x2e12a253, cc_prim_sub_env_mul_t1_add_env}, + // fall headwaters, zelda 2. Added by Gonetz + // (t1-t0)*primlod+t0, (cmb-env)*shade+env ** INC ** + {0x2e12a450, cc__t0_inter_t1_using_primlod__sub_env_mul_shade_add_env}, + // Fissure attack, pokemon stadium 2 + // (t1-t0)*primlod+t0, (prim-env)*cmb_a+env + {0x2e12a753, cc_prim_sub_env_mul__t0_inter_t1_using_primlod__add_env}, + // zelda 2. Added by Gonetz + // (t1-t0)*primlod+t0, (cmb-0)*t1+0 ** INC ** ? + {0x2e12e2f0, cc_t0_inter_t1_using_primlod}, + // zelda 2. Added by Gonetz + // (t1-t0)*primlod+t0, (cmb-0)*prim+0 + {0x2e12e3f0, cc__t0_inter_t1_using_primlod__mul_prim}, + // sky, PGA European Tour + // (t1-t0)*primlod+t0, (cmb-env)*shade+0 ** INC ** + {0x2e12e450, cc__t0_inter_t1_using_primlod__mul_shade}, + // Kirby's pool, smash bros + // (t1-t0)*primlod+t0, (cmb-0)*shade+0 + {0x2e12e4f0, cc__t0_inter_t1_using_primlod__mul_shade}, + //Spacestation Silicon Valley intro. Added by Gonetz + // (prim-t0)*primlod+t0, (cmb-0)*shade+0 **INC** + {0x2e132e13, cc_t0_inter_prim_using_primlod}, + // explosions, daikatana. Added by Gonetz + // (prim-t0)*primlod+t0, (cmb-0)*shade+0 **INC** + {0x2e13e4f0, cc_t0_mul_shade}, + //Mike Piazza's Strike Zone logo. Added by Gonetz + // (shade-t0)*primlod+t0 + {0x2e142e14, cc_t0_inter_shade_using_primlod}, + // Cartridge color (transfer pak}, Pokemon Stadium 2 [gokuss4]. Added by Gonetz + // (1-t0)*primlod+t0 + {0x2e162e16, cc_one_sub_t0_mul_primlod_add_t0}, + // pokemon attack, Pokemon Stadium 2. Added by Gonetz + // (1-t0)*primlod+t0, (prim-0)*cmb+0 + {0x2e16e0f3, cc__t0_inter_one_using_primlod__mul_prim}, + // Spider Web attack, Pokemon Stadium 2. + // (1-t0)*primlod+t0, (cmb-0)*prim+0 + {0x2e16e3f0, cc__t0_inter_one_using_primlod__mul_prim}, + // pokemon attack, Pokemon Stadium 2. Added by Gonetz + // (1-t0)*primlod+t0, (cmb-0)*shade+0 + {0x2e16e4f0, cc__t0_inter_one_using_primlod__mul_shade}, + // zelda 2. Added by Gonetz + // (t1-t1)*primlod+t0, (prim-env)*cmb+env + {0x2e22a053, cc_prim_sub_env_mul_t0_add_env}, + // Shadow Ball, Pokemon Stadium 2 [gokuss4]. Added by Gonetz + // (0-t1)*primlod+t0, (prim-env)*cmb+env ** INC ** + {0x2e2fa053, cc_prim_sub_env_mul_t0_add_env}, + // Skulltula coin solid, zelda + // (t0-prim)*primlod+t0, (prim-env)*cmb+env + {0x2e31a053, cc_prim_sub_env_mul__t0_sub_prim_mul_primlod_add_t0__add_env}, + // Triforce lines, zelda + // (t1-prim)*primlod+t0, (prim-shade)*cmb+shade + {0x2e328043, cc_prim_sub_shade_mul__t1_sub_prim_mul_primlod_add_t0__add_shade}, + // moon when majora defeated, zelda 2. Added by Gonetz + // (t1-prim)*primlod+t0, (1-shade)*cmb+shade + {0x2e328046, cc_one_sub_shade_mul__t1_sub_prim_mul_primlod_add_t0__add_shade}, + // Fire, zelda + //z (t1-prim)*primlod+t0, (prim-env)*cmb+env ** INC ** + {0x2e32a053, cc_prim_sub_env_mul__t1_sub_prim_mul_primlod_add_t0__add_env}, + // zelda 2 [Ogy]. Added by Gonetz + // (t1-prim)*primlod+t0, (shade-env)*cmb+env + {0x2e32a054, cc_shade_sub_env_mul__t1_sub_prim_mul_primlod_add_t0__add_env}, + // Scary face, pokemon stadium 2 + // (t1-prim)*primlod+t0, (1-env)*cmb+env + {0x2e32a056, cc_one_sub_env_mul__t1_sub_prim_mul_primlod_add_t0__add_env}, + // zelda 2. Added by Gonetz + // (t1-prim)*primlod+t0, (prim-0)*cmb+env + {0x2e32a0f3, cc__t1_sub_prim_mul_primlod_add_t0__mul_prim_add_env}, + // zelda 2. Added by Gonetz + // (t1-0)*primlod+t0, (prim-env)*cmb+env + {0x2ef2a053, cc_prim_sub_env_mul__t1_mul_primlod_add_t0__add_env}, + // zelda 2. Added by Gonetz + // (t1-0)*primlod+t0, (cmb-0)*prim+0 + {0x2ef2e3f0, cc__t1_mul_primlod_add_t0__mul_prim}, + // zelda 2. Added by Gonetz + // (t1-0)*primlod+t0, (cmb-0)*env+0 + {0x2ef2e5f0, cc__t1_mul_primlod_add_t0__mul_env}, + // gun, Doom64. Added by Gonetz + // (1-0)*primlod+t0, (cmb-0)*prim+env + {0x2ef6a3f0, cc__t0_add_primlod__mul_prim_add_env}, + // walls, Doom64. Added by Gonetz + // (1-0)*primlod+t0, (cmb-0)*shade+env + {0x2ef6a4f0, cc__t0_add_primlod__mul_shade_add_env}, + // Pokemon Stadium 2. Added by Gonetz + // (noise-0)*primlod+t0, (prim-env)*cmb+env ** INC ** + {0x2ef7a053, cc_prim_sub_env_mul_t0_add_env}, + // Tony Hawk's Pro Skater. Added by Gonetz + // (t1-t0)*k5+t0 + {0x2f122f12, cc_t0_inter_t1_using_k5}, + // F1 World Grand Prix. Added by Gonetz + // (t1-t0)*k5+t0, (cmb-0)*shade+0 **INC** + {0x2f12e4f0, cc__t0_inter_t1_using_k5__mul_shade}, + // Turok 3 [scorpiove]. Added by Gonetz + // (t0-k4)*k5+t0 + {0x2f712f71, cc_t0}, + // THPS 3 + // (env-0)*k5+t0, + {0x2ff52ff5, cc_t0_add_env_mul_k5}, + // super bowling + // (0-0)*k5+t0, + {0x2fff0000, cc_t0}, + // super bowling + // (0-0)*k5+t0 + {0x2fff2fff, cc_t0}, + // Moonlight attack, pokemon stadium 2 + // (t1-t0)*0+t0, (prim-env)*cmb+env + {0x3f12a053, cc_prim_sub_env_mul_t0_add_env}, + //C&C shadows + //(1-env)*0+t0 + {0x3f563f56, cc_t0}, + // RARE logo, blast corps. Added by Gonetz + // (t0-0)*0+t0 + {0x3ff13ff1, cc_t0}, + // the ground below the scarecrow in the trading post in town, zelda 2 [Ogy]. Added by Gonetz + // (t1-0)*0+t0, (cmb-0)*shade+0 + {0x3ff2e4f0, cc_t0_mul_shade}, + // intro, background, Dezaemon 3D + // (1-0)*0+t0 + {0x3ff63ff6, cc_t0}, + // intro of WWF WrestleMania 2000 + // ((0-0)*0+t0, (env-cmb)*prim+cmb + {0x3fff0305, cc_env_sub_t0_mul_prim_add_t0}, + // pistol fire, Turok + // ((0-0)*0+t0, (env-cmb)*shade+cmb + {0x3fff0405, cc_env_sub_t0_mul_shade_add_t0}, + // Tony Hawk's Pro Skater. Added by Gonetz + // ((0-0)*0+t0, (t1-0)*shade+cmb ** INC ** + {0x3fff04f2, cc_t0}, + // Dr. Mario [Ogy]. Added by Gonetz + // ((0-0)*0+t0, (prim-cmb)*env+cmb + {0x3fff0503, cc_prim_sub_t0_mul_env_add_t0}, + // Stained glass, quest64 + // (0-0)*0+t0, (1-0)*env+cmb + {0x3fff05f6, cc_t0_add_env}, + // Health bar, killer instinct gold + // (0-0)*0+t0, (prim-env)*prim_a+cmb + {0x3fff0a53, cc_prim_sub_env_mul_prima_add_t0}, + // Runes, Turok - Dinosaur Hunter. Added by Gonetz + // (0-0)*0+t0, (env-cmb)*env_a+cmb + {0x3fff0c05, cc_t0_inter_env_using_enva}, + // intro, Mission Impossible. Added by Gonetz + // (k5-k5)*0+t0, (0-0)*scale+t0 + {0x3fff26ff, cc_t0}, + // V8-2 + // (0-0)*0+t0, (t0-k4)*k5+t0 + {0x3fff2f71, cc_t0_sub_k4_mul_k5_add_t0}, + // TM, mario + //z (k5-k5)*0+t0 + {0x3fff3fff, cc_t0}, + // Intro, CBFD. Added by Gonetz + // ((0-0)*0+t0, (shade-env)*cmb+prim + {0x3fff6054, cc_shade_sub_env_mul_t0_add_prim}, + // Text, Mia Soccer. Added by Gonetz + // ((0-0)*0+t0, (0-0)*0+prim + {0x3fff7fff, cc_t0}, + // paper mario. Added by Gonetz + // ((0-0)*0+t0, (prim-env)*cmb+env + {0x3fffa053, cc_prim_sub_env_mul_t0_add_env}, + // Objects in arena, pokemon stadium 2 + // (0-0)*0+t0, (cmb-prim)*shade+env + {0x3fffa430, cc_t0_mul_prim}, + // intro, F1 Racing Championship. Added by Gonetz + // (0-0)*0+t0, (shade-env)*cmb+0 + {0x3fffe054, cc_shade_sub_env_mul_t0}, + // stands, F1 Racing Championship. Added by Gonetz + // (0-0)*0+t0, (1-env)*cmb+0 + {0x3fffe056, cc_one_sub_env_mul_t0}, + // ? (from log) + // (0-0)*0+t0, (prim-0)*cmb+0 + {0x3fffe0f3, cc_t0_mul_prim}, + // background, GASP Fighters + // (0-0)*0+t0, (shade-0)*cmb+0 + {0x3fffe0f4, cc_t0_mul_shade}, + // zelda 2 [Ogy]. Added by Gonetz + // (0-0)*0+t0, (env-0)*cmb+0 + {0x3fffe0f5, cc_t0_mul_env}, + // logo, v-rally 99 + // (0-0)*0+t0, (prim-0)*t0+0 + {0x3fffe1f3, cc_t0_mul_prim}, + // target hit, zelda 2. Added by Gonetz + // (0-0)*0+t0, (cmb-0)*prim+0 + {0x3fffe3f0, cc_t0_mul_prim}, + // Ms. Pac-Man intro background. Added by Gonetz + // (0-0)*0+t0, (cmb-0)*shade+0 + {0x3fffe4f0, cc_t0_mul_shade}, + // Wonder Project J2 logo. Added by Gonetz + // (0-0)*0+t0, (t0-0)*shade+0 + {0x3fffe4f1, cc_t0_mul_shade}, + // tire trace, Monster truck madness. Added by Gonetz + // (0-0)*0+t0, (cmb-0)*env+0 + {0x3fffe5f0, cc_t0_mul_env}, + // Gauntlet Legends intro. Added by Gonetz + // (0-0)*0+t0, (cmb-0)*ecale+0 + {0x3fffe6f0, cc_t0}, + // tire trace, beetle adventure racing. Added by Gonetz + // (t1-t0)*t0+t1, (cmb-t0)*shade+t1 **INC** + {0x41124410, cc__t0_inter_t1_using_t0__mul_shade}, + // Paper Mario. Added by Gonetz + // (t0-t1)*t0+t1 **INC** + {0x41214121, cc_t1_inter_t0_using_t0}, + // Powered Star Beam, Paper Mario. Added by Gonetz + // (t0-t1)*t0+t1, (env-prim)*cmb+prim **INC** + {0x41216035, cc_env_sub_prim_mul__t1_inter_t0_using_t0__add_prim}, + // wetrix raiseland [Raziel64]. Added by Gonetz + // (prim-t1)*t0+t1, (env-t0)*cmb+cmb **INC** + {0x41230015, cc_env_sub_prim_mul__t0_mul_t1__add_prim}, + // SCARS. Added by Gonetz + // (t1-t0)*t0+t1, (cmb-t0)*shade+t1 **INC** + {0x41250b03, cc__t0_inter_t1_using_half__mul_shade}, + //beetle adventure racing. Added by Gonetz + //(t0-t1)*t1+t1, (cmb-0)*shade+0 **INC** + {0x4221e4f0, cc__t1_inter_t0_using_t1__mul_shade}, + // cianwood gym walls, pokemon stadium 2 + //(t0-prim)*t1+t1, (cmb-0)*env+shade + {0x423185f0, cc__t0_sub_prim_mul_t1_add_t1__mul_env_add_shade}, + // cianwood gym walls, pokemon stadium 2 + //(t0-prim)*t1+t1, (cmb-0)*shade+0 + {0x4231e4f0, cc__t0_sub_prim_mul_t1_add_t1__mul_shade}, + // paper mario. Added by Gonetz + // (t0-t0)*prim+t1, (t1-cmb)*cmb+env **INC** weird + {0x4311a002, cc_env}, + // background, Wetrix level 1, [Raziel64]. Added by Gonetz + // (t0-t1)*prim+t1 + {0x43214321, cc_t1_inter_t0_using_prim}, + // Mario Party3 Tidal Toss + // (t0-t1)*prim+t1, (cmb-0)*shade+0 **INC** + {0x4321e4f0, cc__t1_inter_t0_using_prim__mul_shade}, + // grass, ISS 2k. Added by Gonetz + // (t0-t1)*prim+t1, (cmb-0)*env+0 **INC** + {0x4321e5f0, cc__t1_inter_t0_using_prim__mul_env}, + // intro, Paper Mario + // (t0-0)*prim+t1 + {0x43f143f1, cc_t0_mul_prim_add_t1}, + // F1 World Grand Prix. Added by Gonetz + // (t0-0)*prim+t1, (cmb-0)*shade+env **INC** + {0x43f1a4f0, cc__t0_add_t1__mul_shade_add_env}, + // field, ISS64. Added by Gonetz + // (t0-t1)*shade+t1, (cmb-t1)*prim+t1 ** INC ** + {0x44214320, cc_t0_sub_t1_mul_prim_mul_shade_add_t1}, + // {0x44214320, cc__t0_add_t1__mul_prim}, + // field, Top gear hyper-bike + // (t0-t1)*shade+t1 + {0x44214421, cc_t1_inter_t0_using_shade}, + // water, goemon great adventure + // (t0-t1)*env+t1 ** INC ** + {0x45214521, cc_t1_inter_t0_using_env}, + // characters, Ogre Battle. Added by Gonetz + // (1-t1)*env+t1, (1-cmb)*prim+cmb ** INC ** + {0x45260306, cc_one_sub_t1_mul_prim_add_t1}, + // characters, Ogre Battle. Added by Gonetz + // (1-t1)*env+t1 + {0x45264526, cc_one_sub_t1_mul_env_add_t1}, + // characters, Ogre Battle. Added by Gonetz + // (1-t1)*env+t1, (cmb-0)*prim+0 ** INC ** + {0x4526e3f0, cc__t1_inter_one_using_env__mul_prim}, + // explosion, body harvest. Added by Gonetz + // (t0-t1)*scale+t1, (env-prim)*cmb+prim ** INC ** + {0x46216035, cc_env_sub_prim_mul__t0_inter_t1_using_half__add_prim}, + // Water, AeroGauge. Added by Gonetz + // (t0-t1)*prima+t1, (0-0)*0+cmb + {0x4a214a21, cc_t1_inter_t0_using_prima}, + // flame, castlevania 2. Added by Gonetz + // (t0-t1)*prima+t1, (prim-env)*cmb+env + {0x4a21a053, cc_prim_sub_env_mul__t1_inter_t0_using_prima__add_env}, + // shadows, Mario Tennis. Added by Gonetz + // (t0-t1)*prima+t1, (prim-0)*cmb+0 + {0x4a21e0f3, cc__t1_inter_t0_using_prima__mul_prim}, + // menu, Mario Golf. Added by Gonetz + // (t0-t1)*prima+t1, (shade-0)*cmb+0 + {0x4a21e0f4, cc__t1_inter_t0_using_prima__mul_shade}, + // intro, castlevania 2. Added by Gonetz + // (t0-t1)*prima+t1, (cmb-0)*prim+0 + {0x4a21e3f0, cc__t1_inter_t0_using_prima__mul_prim}, + // water on map, Ogre Battle64. Added by Gonetz + // (t0-t1)*prima+t1, (cmb-0)*shade+0 + {0x4a21e4f0, cc__t1_inter_t0_using_prima__mul_shade}, + // Ice, Paper Mario + // (t0-t1)*shade_a+t1 + {0x4b214b21, cc_t1_inter_t0_using_shadea}, + // Grass, Beetle Adventure Racing + // (t0-t1)*shade_a+t1, (cmb-0)*shade+0 + {0x4b21e4f0, cc__t1_inter_t0_using_shadea__mul_shade}, + // Ground at kotake & koume, zelda + // (t1-t0)*env_a+t0, (prim-env)*cmb+env + {0x4c12a053, cc_prim_sub_env_mul__t0_inter_t1_using_enva__add_env}, + // Tony Hawk's Pro Skater. Added by Gonetz + // (t0-t1)*env_a+t1, (cmb-0)*shade+cmb ** INC ** + {0x4c2104f0, cc__t1_inter_t0_using_enva__mul_shade}, + // bikes, xg2. Added by Gonetz + // (t0-t1)*env_a+t1, (cmb-prim)*prima+prim + {0x4c216a30, cc__t1_inter_t0_using_enva__sub_prim_mul_prima_add_prim}, + // Yoshi Story + // (t0-t1)*env_a+t1, (prim-env)*cmb+env + {0x4c21a053, cc_prim_sub_env_mul__t1_inter_t0_using_enva__add_env}, + // arena, Pokemon Stadium 1. Added by Gonetz + // (t0-t1)*env_a+t1, (cmb-0)*prim+0 + {0x4c21e3f0, cc__t1_inter_t0_using_enva__mul_prim}, + // "end of chapter" text, paper mario. Added by Gonetz + // (1-t1)*env_a+t1, (cmb-0)*t1+0 + {0x4c26e2f0, cc__t1_inter_one_using_enva__mul_t0}, + // Zelda opening door, zelda + // (t0-prim)*env_a+t1, (prim-env)*t0+env + {0x4c31a053, cc_prim_sub_env_mul_t0_add_env}, + // arena, Pokemon Stadium 2 + // (t0-0)*env_a+t1, (cmb-0)*shade+prim + {0x4cf164f0, cc__t0_mul_enva_add_t1__mul_shade_add_prim}, + // Kotake & koume magic poof, zelda + // (t0-0)*env_a+t1, (prim-env)*cmb+env + {0x4cf1a053, cc_prim_sub_env_mul__t0_mul_enva_add_t1__add_env}, + // ground in stone temple, zelda 2. Added by Gonetz + // (t1-t0)*primlod+t1, (cmb-0)*prim+0 + {0x4e12e3f0, cc__t0_inter_t1_using_primlod__mul_prim}, + // pokemon attack, Pokemon Stadium 2. Added by Gonetz + // (noise-t0)*primlod+t1, (prim-env)*cmb+env ** INC ** + {0x4e17a053, cc_prim_sub_env_mul__t0_inter_t1_using_primlod__add_env}, + // menu, pokemon stadium 1, [Raziel64] + // (t0-t1)*lodf+t1, (prim-env)*cmb+env + {0x4e214e21, cc_t1_inter_t0_using_primlod}, + // Pokemon backgrounds, pokemon stadium 2 + // (t0-t1)*primlod+t1, (cmb-0)*shade+prim + {0x4e2164f0, cc__t1_inter_t0_using_primlod__mul_shade_add_prim}, + // Pokemon backgrounds, pokemon stadium 2 + // (t0-t1)*lodf+t1, (prim-env)*cmb+env + {0x4e21a053, cc_prim_sub_env_mul__t1_inter_t0_using_primlod__add_env}, + // zelda 2 [Ogy]. Added by Gonetz + // (t0-t1)*primlod+t1, (t1-cmb)*prim+env ** INC ** + {0x4e21a302, cc_env_sub__t0_sub_t1_mul_primlod__mul_prim}, + // Magnitude, pokemon stadium 2 + // (t0-t1)*primlod+t1, (prim-env)*cmb_a+env + {0x4e21a753, cc_prim_sub_env_mul__t1_inter_t0_using_primlod__add_env}, + // Arena, pokemon stadium 2 + // (t0-t1)*primlod+t1, (cmb-shade)*prim+0 + {0x4e21e340, cc__t1_inter_t0_using_primlod__sub_shade_mul_prim}, + // zelda 2 [Ogy]. Added by Gonetz + // (t0-t1)*primlod+t1, (cmb-0)*shade+0 + {0x4e21e4f0, cc__t1_inter_t0_using_primlod__mul_shade}, + // lava in snowhead temple, zelda 2. Added by Gonetz + // (t0-prim)*primlod+t1, (cmb-prim)*shade+cmb ** INC ** + {0x4e310430, cc_lavatex_sub_prim_mul_shade_add_lavatex}, + // Skulltula coin, zelda + // (t0-prim)*primlod+t1, (prim-env)*cmb+env + {0x4e31a053, cc_prim_sub_env_mul__t0_sub_prim_mul_primlod_add_t1__add_env}, + // Pokemon background, pokemon stadium 2 + // (noise-shade)*primlod+t1, (prim-env)*cmb+env + {0x4e47a053, cc_prim_sub_env_mul_t1_add_env}, + // Reflect, Pokemon Stadium 2 [gokuss4]. Added by Gonetz + // (t0-0)*primlod+t1, (prim-env)*cmb+env + {0x4ef1a053, cc_prim_sub_env_mul__t0_add_t1__add_env}, + //beetle adventure racing. Added by Gonetz + //(t0-t1)*k5+t1, (cmb-0)*shade+0 + {0x4f21e4f0, cc__t1_inter_t0_using_k5__mul_shade}, + // Spiderman. Added by Gonetz + //(t0-t1)*k5+t1, (cmb-0)*env+0 + {0x4f21e5f0, cc_t1_mul_env}, + // N64 logo, Ogre Battle. Added by Gonetz + //(0-0)*0+t1 + {0x5fff5fff, cc_t1}, + // reversing light, Monster truck madness. Added by Gonetz + //(0-0)*0+t0, (0-0)*0+prim + {0x5fff7fff, cc_prim}, + // battle tanks [Ogy] + // (0-0)*0+t1, (env-shade)*cmb+shade + {0x5fff8045, cc_env_sub_shade_mul_t1_add_shade}, + // minigame, pokemon stadium 1. Added by Gonetz + // (0-0)*0+t1, (prim-env)*cmb+env + {0x5fffa053, cc_prim_sub_env_mul_t1_add_env}, + // F1 World Grand Prix. Added by Gonetz + // (t0-prim)*t0+prim, (cmb-0)*shade + {0x6131e4f0, cc__prim_inter_t0_using_t0__mul_shade}, + // aerofighter's assault [Ogy] + // (shade-prim)*t0+prim + {0x61346134, cc_shade_sub_prim_mul_t0_add_prim}, + // pilot wings + // (shade-prim)*t0+prim, (cmb-shade)*shadea+shade + {0x61348b40, cc_shade_inter__prim_inter_shade_using_t0__using_shadea}, + // club blow, Fushigi no Dungeon - Furai no Shiren 2. Added by Gonetz + // (shade-prim)*t0+prim, (cmb-env)*cmb_a+env ** INC ** + {0x6134a750, cc_shade_sub_prim_mul_t0_add_prim}, + // sky, Killer Instinct + // (shade-prim)*t0+prim, (cmb-env)*shade_a+env ** INC ** + {0x6134ab50, cc_env_inter__prim_inter_shade_using_t0__using_shadea}, + // lava, beetle adventure racing + // (shade-prim)*t0+prim, (cmb-0)*t1+0 ** INC ** + {0x6134e2f0, cc_shade_sub_prim_mul_t0_add_prim}, + // Monster truck madness intro. Added by Gonetz + // (env-prim)*t0+prim, (cmb-0)*scale+cmb ** INC ** + {0x613506f0, cc_env_sub_prim_mul_t0_add_prim}, + // pokemon attack, Pokemon stadium 1 + // (env-prim)*t0+prim, (cmb-0)*0+cmb + {0x61351ff0, cc_env_sub_prim_mul_t0_add_prim}, + // Paper Mario, fortune teller spheres + // (env-prim)*t0+prim, (cmb-0)*t1+t0 ** INC ** + {0x613522f0, cc_t0_mul_t1_add_t0}, + // Later hearts, zelda + // (env-prim)*t0+prim + {0x61356135, cc_env_sub_prim_mul_t0_add_prim}, + // Mission Impossible. Added by Gonetz + // (env-prim)*t0+prim, (shade-0)*cmb+0 ** INC ** + {0x6135e0f4, cc__prim_inter_env_using_t0__mul_shade}, + // crashing other vehicle, Monster truck madness [Raziel64]. Added by Gonetz + // (env-prim)*t0+prim, (cmb-0)*t0+0 ** INC ** + {0x6135e1f0, cc_env_sub_prim_mul_t0_add_prim}, + // Tony Hawk's Pro Skater. Added by Gonetz + // (env-prim)*t0+prim, (cmb-0)*t1+0 ** INC ** + {0x6135e2f0, cc_env_sub_prim_mul_t0_add_prim}, + // aerofighter's assault [Ogy] + // (env-prim)*t0+prim, (cmb-0)*shade+0 ** INC ** + {0x6135e4f0, cc__prim_inter_env_using_t0__mul_shade}, + // "time out", paper mario. Added by Gonetz + // (1-prim)*t0+prim, (1-cmb)*enva+cmb ** INC ** + {0x61360c06, cc_one_sub_prim_mul_t0_add_prim}, + // intro, paper mario. Added by Gonetz + // (1-prim)*t0+prim, (cmb-0)*prima+t0 ** INC ** + {0x61362af0, cc__one_sub_prim_mul_t0_add_prim__mul_prima_add__one_sub_prim_mul_t0_add_prim}, + // paper mario. Added by Gonetz + // (1-prim)*t0+prim + {0x61366136, cc_one_sub_prim_mul_t0_add_prim}, + // arena, Pokemon Stadium 2. Added by Gonetz + // (1-prim)*t0+prim, (cmb-env)*shade+shade ** INC ** + {0x61368450, cc_t0_mul_shade}, + // F1 World Grand Prix. Added by Gonetz + // (1-prim)*t0+prim, (cmb-0)*shade+0 ** INC ** + {0x6136e4f0, cc_t0_mul_shade}, + // Xena. Added by Gonetz + // (0-prim)*t0+prim + {0x613f613f, cc_one_sub_t0_mul_prim}, + // Kirby64 end [Raziel64]. Added by Gonetz + // (prim-env)*t0+prim + {0x61536153, cc_prim_sub_env_mul_t0_add_prim}, + // Xena. Added by Gonetz + // (shade-env)*t0+prim + {0x61546154, cc_shade_sub_env_mul_t0_add_prim}, + // Karts, mario kart + //z (one-env)*t0+prim + {0x61566156, cc_t0_mul_1menv_add_prim}, + // Famista64. Added by Gonetz + //(t0-0)*t0+prim + {0x61f161f1, cc_t0_mul_prim}, + // Pokemon Stadium 2. Added by Gonetz + //(shade-0)*t0+prim + {0x61f461f4, cc_t0_mul_shade_add_prim}, + // Doom. Added by Gonetz + //(1-0)*t0+prim + {0x61f661f6, cc_t0_add_prim}, + // tire trace, beetle adventure racing. Added by Gonetz + // (shade-prim)*t1+prim, (cmb-0)*t1+0 **INC** + {0x6234e2f0, cc_shade_sub_prim_mul_t1_add_prim}, + // Text, turok + // (env-prim)*t1+prim + {0x62356235, cc_env_sub_prim_mul_t1_add_prim}, + // Pokemon Stadium 2, [gokuss4]. Added by Gonetz + // (env-prim)*t1+prim, (cmb-0)*t1+0 + // Hack alert! + {0x6235e2f0, cc_t1}, + // bike trace, xg2 intro. Added by Gonetz + // (1-prim)*t1+prim + {0x62366236, cc_one_sub_prim_mul_t1_add_prim}, + // aerofighter's assault [Ogy] + // (1-prim)*t1+prim, (cmb-0)*0+env + {0x6236bff0, cc_one_sub_prim_mul_t1_add_prim}, + // Tennis court, mario tennis + // (t0-0)*t1+prim + {0x62f162f1, cc__t0_mul_t1__add_prim}, + // Arena, Pokemon Stadium 2 + // (t0-0)*t1+prim, (cmb-0)*shade+0 + {0x62f1e4f0, cc__t0_mul_t1_add_prim__mul_shade}, + // Rush2. Added by Gonetz + // (prim-prim)*prim+prim + {0x63336333, cc_prim}, + //Bowser in final battle, Paper Mario. Added by Gonetz + // (t1-0)*prim+prim + {0x63f263f2, cc_t1_mul_prim_add_prim}, + // wetrix, icelayer, [Raziel64]. Added by Gonetz + // (t0-prim)*shade+prim ** INC ** + {0x64316431, cc_t0_mul_shade}, + // KI. Added by Gonetz + // (env-prim)*shade+prim + {0x64356435, cc_env_sub_prim_mul_shade_add_prim}, + // xg2. Added by Gonetz + // (1-prim)*shade+prim, (t0-0)*cmb+0 ** INC ** + {0x6436e0f1, cc_t1_mul__one_sub_prim_mul_shade_add_prim}, + // Intro, CBFD. Added by Gonetz + // (t0-env)*shade+prim + {0x64516451, cc_t0_sub_env_mul_shade_add_prim}, + // sword in final battle, zelda 2. Added by Gonetz + // (t0-env)*shade+prim, (cmb-0)*shade+0 ** INC ** + {0x6451e4f0, cc__t0_sub_env_mul_shade_add_prim__mul_shade}, + // attack, Pokemon Stadium 2. + // (t0-env)*shade+prim, (cmb-0)*shade_a+0 ** INC ** + {0x6451ebf0, cc__t0_sub_env_mul_shade_add_prim__mul_shadea}, + // Road Rush. Added by Gonetz + // (t0-0)*shade+prim + {0x64f164f1, cc_t0_mul_shade_add_prim}, + // paper mario. Added by Gonetz + // (1-0)*shade+prim + {0x64f664f6, cc_prim_add_shade}, + // Character select, smash bros + // (t0-prim)*env+prim + {0x65316531, cc_t0_sub_prim_mul_env_add_prim}, + // Clear screen intro, banjo kazooie + // (t0-prim)*env+prim, (cmb-0)*shade+0 + // {0x6531e4f0, cc_t0_mul_env_mul_shade}, + {0x6531e4f0, cc__prim_inter_t0_using_env__mul_shade}, + // Dragonfly feet, banjo kazooie + // (1-prim)*env+prim, (cmb-0)*shade+0 + {0x6536e4f0, cc__prim_inter_one_using_env__mul_shade}, + // Lava piranha atack, Paper Mario + // (t1-k4)*env+prim ** INC ** + {0x65726572, cc_t1_mul_env_add_prim}, + // zelda 2 [Ogy]. Added by Gonetz + // (t0-0)*env+prim, (1-t1)*t0a+cmb ** INC ** + {0x65f10826, cc_one_sub_t1_mul_t0a_add_t0_mul_env_add_prim}, + // clocks while warping through time, zelda 2 + // (t0-0)*env+prim, (cmb-0)*0+cmb + {0x65f11ff0, cc_t0_mul_env_add_prim}, + // Helicopter, Nuclear Strike. Added by Gonetz + // (t0-0)*env+prim + {0x65f165f1, cc_t0_mul_env_add_prim}, + // Mystical Ninja + // (1-0)*env+prim + {0x65f665f6, cc_prim_add_env}, + // duke nukem: zero hour [Ogy] + // (noise-0)*env+prim ** INC ** + {0x65f765f7, cc_prim_add_env}, + // "terminator", CBFD + // (0-0)*env+prim + {0x65ff65ff, cc_prim}, + // Cliffs, Taz express. Added by Gonetz + // (t0-0)*scale+prim + {0x66f166f1, cc_t0_mul_scale_add_prim}, + // Taz express. Added by Gonetz + // (t0-0)*scale+prim, (cmb-0)*shade+0 + {0x66f1e4f0, cc_t0_mul_scale_add_prim__mul_shade}, + // NFL Quarterback Club 98 Menu [CpUMasteR] + // (prim-0)*scale+prim + {0x66f366f3, cc_prim}, + // Pikachu + // (t0-prim)*t0_a+prim, (env-cmb)*enva+cmb + {0x68310c05, cc__prim_inter_t0_using_t0a__inter_env_using_enva}, + // Character, dual heroes + // (t0-prim)*t0_a+prim + {0x68316831, cc_t0_sub_prim_mul_t0a_add_prim}, + // Indy Racing 2000. Added by Gonetz + // (t0-prim)*t0_a+prim, (cmb-0)*shade+0 ** INC ** + {0x6831e4f0, cc__prim_inter_t0_using_t0a__mul_shade}, + // text, Sin and Punishmen. Added by Gonetz + // (env-prim)*t0_a+prim ** INC ** + {0x68356835, cc_env_sub_prim_mul_t0a_add_prim}, + // arena, Pokemon Stadium 2 + // (1-prim)*t0_a+prim + {0x68366836, cc_one_sub_prim_mul_t0a_add_prim}, + // menu, PD. Added by Gonetz + // (env-prim)*t1_a+prim + {0x69356935, cc_env_sub_prim_mul_t1a_add_prim}, + // {0x69356935, cc_t1}, + //xg2. Added by Gonetz + // (t0-prim)*prima+prim + {0x6a316a31, cc_t0_sub_prim_mul_prima_add_prim}, + // menu, battle phoenix 64. Added by Gonetz + // (env-prim)*prima+prim + {0x6a356a35, cc_env_sub_prim_mul_prima_add_prim}, + // ground, KI. Added by Gonetz + // (shade-env)*prima+prim + {0x6a546a54, cc_shade_sub_env_mul_prima_add_prim}, + // F1 World Grand Prix. Added by Gonetz + // (t0-0)*prima+prim, (shade-0)*cmb+env **INC** + {0x6af1a0f4, cc__t0_mul_prima_add_prim_mul__shade_add_env}, + //broken wall, beetle adventure racing. Added by Gonetz + // (t0-0)*prima+prim, (cmb-0)*shade+0 **INC** + {0x6af1e4f0, cc__t0_mul_prima_add_prim_mul__shade}, + // Genie, diddy kong racing + // (t0-prim)*shade_alpha+prim, (env-cmb)*shade+cmb + // {0x6b310405, cc_env_sub__prim_inter_t0_using_shadea__mul_shade_add_env}, + {0x6b310405, cc_t0_mul_shadea}, + // Extreme G. Added by Gonetz + // (t0-prim)*shade_alpha+prim ** INC ** + {0x6b316b31, cc_t0_sub_prim_mul_shadea_add_prim}, + // water block, Paper Mario. Added by Gonetz + // (t0-prim)*shade_alpha+prim, (prim-env)*cmb+env ** INC ** + {0x6b31a053, cc_prim_sub_env_mul__prim_inter_t0_using_shadea__add_env}, + // water, Fushigi no Dungeon - Furai no Shiren 2. Added by Gonetz + // (t0-prim)*shade_alpha+prim, (cmb-0)*shade+0 ** INC ** + {0x6b31e4f0, cc__prim_inter_t0_using_shadea__mul_shade}, + // F1 World Grand Prix sky. Added by Gonetz + // (env-prim)*shade_alpha+prim, (shade-cmb)*cmb_a+cmb ** INC ** + {0x6b350704, cc_f1_sky}, + // lullaby, Paper Mario. Added by Gonetz + // (env-prim)*shade_alpha+prim + {0x6b356b35, cc_env_sub_prim_mul_shadea_add_prim}, + // Some gannon spell, zelda + // (noise-t0)*env_a+prim, (0-prim)*cmb+1 ** INC ** + {0x6c17c03f, cc_one_sub__one_sub_t0_mul_enva_add_prim__mul_prim}, + //Goldeneye, [Jeremy]. Added by Gonetz + // (t0-prim)*env_a+prim + {0x6c316c31, cc_t0_sub_prim_mul_enva_add_prim}, + // button, Sin and Punishmen. Added by Gonetz + // (env-prim)*env_a+prim + {0x6c356c35, cc_env_sub_prim_mul_enva_add_prim}, + // frame buffer effect, Glover2 + // (env-prim)*env_a+prim, (cmb-0)*shade+0 + {0x6c35e4f0, cc__prim_inter_env_using_enva__mul_shade}, + // fallen stars at star summit, Paper Mario. Added by Gonetz + // (t0-env)*env_a+prim, (1-0)*primlod+cmb + {0x6c510ef6, cc_t0_sub_env_mul_enva_add_prim}, + // focus, Paper Mario. Added by Gonetz + // (t0-env)*env_a+prim, (cmb-shade)*shadea+shade ** INC ** + {0x6c518b40, cc_t0_sub_shade_mul_shadea_add_shade}, + // Ring, pokemon stadium 2 + // (t0-0)*env_a+prim, (1-0)*cmb+0 + {0x6cf1e0f6, cc_t0_mul_enva_add_prim}, + // Jet Force + // (noise-0)*env_a+prim + {0x6cf76cf7, cc_prim}, + // snowhead temple, zelda 2. Added by Gonetz + // (t1-t0)*primlod+prim, (cmb-0)*shade+shade + {0x6e1284f0, cc__t1_sub_t0_mul_primlod_add_prim__mul_shade_add_shade}, + // zelda 2. Added by Gonetz + // (t1-t0)*primlod+prim, (cmb-0)*shade+0 ** INC ** + {0x6e12e4f0, cc__t1_sub_t0_mul_primlod_add_prim__mul_shade}, + // mini games quiz monitor backround, Pokemon Stadium 2 + // (noise-t0)*primlod+prim, (prim-env)*cmb+env ** INC ** + {0x6e17a053, cc_prim_sub_env_mul__one_sub_t0_mul_primlod_add_prim__add_env}, + // Morning Sun attack, pokemon stadium 2 + // (t0-prim)*primlod+prim, (prim-env)*0+cmb + {0x6e311f53, cc_t0_sub_prim_mul_primlod_add_prim}, + // sky, daikatana. Added by Gonetz + // (t0-prim)*primlod+prim, (cmb-0)*shade+0 + {0x6e31e4f0, cc_t0_mul_shade}, + // ball's track, NFL Blitz. Added by Gonetz + // (t0-0)*primlod+prim + {0x6ef16ef1, cc_t0_mul_primlod_add_prim}, + // Earthquake pokemon attack, Pokemon Stadium 2 [gokuss4]. Added by Gonetz + // (t0-0)*primlod+prim, (cmb-env)*cmb_a+env ** INC ** + {0x6ef1a750, cc_t0_mul_primlod_add_prim}, + // mini games quiz monitor backround, Pokemon Stadium 2 + // (noise-0)*primlod+prim, (env-cmb)*cmb_a+cmb ** INC ** + // use cmb_a which is ac_t0_mul_t1 + {0x6ef70705, cc_env_sub_prim_mul__t0a_mul_t1a__add_prim}, + // rope, CBFD + // (t0-env)*k5+prim + {0x6f516f51, cc_t0_sub_env_mul_k5_add_prim}, + // super bowling + // (0-0)*k5+prim + {0x6fff6fff, cc_prim}, + // intro, Aidyn Chronicles. Added by Gonetz + // (0-0)*0+prim, (0-0)*0+prim + {0x79fb7788, cc_prim}, + // Encore attack, Pokemon Stadium 2 + // (t0-0)*0+prim, (cmb-0)*shade+0 + {0x7ff1e4f0, cc_prim_mul_shade}, + // Menu, megaman + // (1-0)*0+prim + {0x7ff67ff6, cc_prim}, + // sky, PGA European Tour + // (0-0)*0+prim, (env-0)*t0+cmb + {0x7fff01f5, cc_t1_mul_env_add_prim}, + // WWF No Mercy? + // ((0-0)*0+prim, (env-cmb)*shade+cmb + {0x7fff0405, cc_env_sub_prim_mul_shade_add_prim}, + // sky, Spiderman. Added by Gonetz + // (0-0)*0+prim, (t1-0)*shade+cmb + {0x7fff04f2, cc_t1_mul_shade_add_prim}, + // ball's shadow, ISS 2k. Added by Gonetz + // (0-0)*0+prim, (1-cmb)*env+cmb + {0x7fff0506, cc_one_sub_prim_mul_env_add_prim}, + // Necklace, quest64 + // (0-0)*0+prim, (1-0)*env+cmb + {0x7fff05f6, cc_prim_add_env}, + // Fushigi no Dungeon - Furai no Shiren 2. Added by Gonetz + // (0-0)*0+prim, (1-cmb)*cmba+cmb ** INC ** + {0x7fff0706, cc_prim}, + // Dobutsu no Mori. Added by Gonetz + //(k5-k5)*0+prim, (cmb-0)*0+cmb + {0x7fff1ff0, cc_prim}, + // Intro background, starfox + //z (k5-k5)*0+prim + {0x7fff7fff, cc_prim}, + // train smoke, Dobutsu No Mori. Added by Gonetz + //(0-0)*0+prim, (shade-0)*cmb+0 + {0x7fffe0f4, cc_prim_mul_shade}, + // Donald Duck intro. Added by Gonetz + //(0-0)*0+prim, (cmb-0)*prim+0 + {0x7fffe3f0, cc_prim_mul_prim}, + // Ms. Pac-Man intro. Added by Gonetz + //(0-0)*0+prim, (cmb-0)*shade+0 + {0x7fffe4f0, cc_prim_mul_shade}, + // zelda 2. Added by Gonetz + //(t1-t0)*t0+shade, (cmb-0)*shade+0 + {0x8112e4f0, cc__t1_sub_t0_mul_t0_add_shade__mul_shade}, + // branches, Beetle Adventure Racing + //(t0-shade)*t0+shade, (t0-cmb)*prim+cmb **INC** + {0x81410301, cc_t0_mul_prim}, + // Namco logo, Famista 64 + //(prim-shade)*t0+shade, (env-cmb)*t0+cmb **INC** + {0x81430105, cc_prim_sub_shade_mul_t0_add_shade}, + // pikachu, hey you pikachu + //(prim-shade)*t0+shade, (env-cmb)*enva+cmb **INC** + {0x81430c05, cc_prim_sub_shade_mul_t0_add_shade}, + // Mario's head, mario //Added by Gonetz + //(prim-shade)*t0+shade + {0x81438143, cc_prim_sub_shade_mul_t0_add_shade}, + // Iguana background, turok + // (env-shade)*t0+shade + {0x81458145, cc_env_sub_shade_mul_t0_add_shade}, + //attack, Pokemon Stadium 2 + // (env-shade)*t0+shade, (cmb-0)*prim+0 + {0x8145e3f0, cc__env_sub_shade_mul_t0_add_shade__mul_prim}, + // Bubbles in Jabu-Jabu's belly, zelda + // (1-shade)*t0+shade + {0x81468146, cc_one_sub_shade_mul_t0_add_shade}, + // saffron city, Pokemon Stadium 2 + // (1-shade)*t0+shade, (cmb-0)*prim+0 + {0x8146e3f0, cc__one_sub_shade_mul_t0_add_shade__mul_prim}, + // duck dodgers intro. Added by Gonetz + // (1-shade)*t0+shade, (cmb-0)*shade+0 + {0x8146e4f0, cc__one_sub_shade_mul_t0_add_shade__mul_shade}, + // saffron city, Pokemon Stadium 2 + // (1-shade)*t0+shade, (cmb-0)*prima+0 + {0x8146eaf0, cc__one_sub_shade_mul_t0_add_shade__mul_env}, + // intro, Madden Footbal + // (1-env)*t0+shade + {0x81568156, cc_one_sub_env_mul_t0_add_shade}, + // sky in doom. Added by Gonetz + // (prim-0)*t0+shade, (cmb-0)*primlod+env **INC** + {0x81f3aef0, cc_t0_mul_prim_add_shade}, + // commercial? in IIS98. Added by Gonetz + // (1-0)*t0+shade + {0x81f681f6, cc_t0_add_shade}, + //attack, Pokemon Stadium 2 + //(t0-prim)*t1+shade + {0x82318231, cc_t0_sub_prim_mul_t1_add_shade}, + //beetle adventure racing. Added by Gonetz + //(prim-shade)*t1+shade, (cmb-0)*t1+0 **INC** + {0x8243e2f0, cc_prim_sub_shade_mul_t1_add_shade}, + //Arena, Pokemon Stadium 2 + //(t0-0)*t1+shade + {0x82f182f1, cc__t0_mul_t1__add_shade}, + //Arena, Pokemon Stadium 2 + //(t0-0)*t1+shade, (cmb-0)*prim+0 + {0x82f1e3f0, cc__t0_mul_t1__mul_prim_add_prim_mul_shade}, + // Scorpion fire breath, MK4 [Jeremy]. Added by Gonetz + // (t0-shade)*prim+shade + {0x83418341, cc_t0_mul_prim_add_one_sub_prim_mul_shade}, + // Menu background, wwf no mercy + // (env-shade)*prim+shade + {0x83458345, cc_prim_mul_env_add_one_sub_prim_mul_shade}, + // Pokemon selection window background, pokemon stadium 2 + // (noise-shade)*prim+shade + {0x83478347, cc_shade}, + // crown of king of ikana, zelda 2. Added by Gonetz + // (t0-env)*prim+shade + {0x83518351, cc_t0_sub_env_mul_prim_add_shade}, + // crown of king of ikana, zelda 2. Added by Gonetz + // (t0-env)*prim+shade, (cmb-0)*cmb+0 ** INC ** + {0x8351e0f0, cc_t0_sub_env_mul_prim_add_shade}, + // salesman's shirt in the bomb shop in town, zelda 2 [Ogy]. Added by Gonetz + // (t0-env)*prim+shade, (cmb-0)*shade+0 ** INC ** + {0x8351e4f0, cc_t0_mul_prim_mul_shade}, + // intro, Madden Footbal + // (1-env)*prim+shade + {0x83568356, cc_one_sub_env_mul_prim_add_shade}, + // Buss hunter 64. Added by Gonetz + // (t0-0)*prim+shade + {0x83f183f1, cc_t0_mul_prim_add_shade}, + // huge water lilies, zelda 2 [Ogy]. Added by Gonetz + // (t0-0)*prim+shade, (cmb-env)*shade+0 ** INC ** + {0x83f1e450, cc__t0_mul_prim_add_shade__sub_env_mul_shade}, + // cynnabar gym fire shield, pokemon stadium 2 + // (t0-0)*prim+shade, (cmb-0)*env+0 ** INC ** + {0x83f1e5f0, cc__t0_mul_prim_add_shade__mul_env}, + // Objects in arena, pokemon stadium 2 + // (t1-0)*prim+shade, (cmb-0)*prim_a+0 - not going to bother with prim_a since it is FF + {0x83f2eaf0, cc_t1_mul_prim_add_shade}, + // Pokemon Stadium 2. Added by Gonetz + // (t0-prim)*shade+shade ** INC ** + {0x84318431, cc_t0_mul_shade}, + // big N, Pokemon Stadium 2. Added by Gonetz + // (1-prim)*shade+shade ** INC ** + {0x84368436, cc_one_sub_prim_mul_shade_add_shade}, + //Arena, Pokemon Stadium 2 + //(t0-env)*shade+shade + {0x84518451, cc_t0_sub_prim_mul_shade_add_shade}, + //Arena, Pokemon Stadium 2 + //(t0-env)*shade+shade, (cmb-0)*prim+0 + {0x8451e3f0, cc_t0_sub_env_mul_prim_mul_shade_add_prim_mul_shade}, + // arena, PokemonStadium2, [Raziel64] + // (t0-0)*shade+shade, (cmb-0)*prim+0 + {0x84f1e3f0, cc_t0_mul_prim_mul_shade_add_prim_mul_shade}, + // Spiderman. Added by Gonetz + // (1-0)*shade+shade + {0x84f684f6, cc_shade_add_shade}, + // the "gekko" ( a monster in a room above the 3rd room of woodfall temple }, zelda 2 [Ogy]. Added by Gonetz + // (t0-prim)*env+shade ** INC ** + {0x85318531, cc_t0_sub_prim_mul_env_add_shade}, + // flower, zelda 2. Added by Gonetz + // (t0-prim)*env+shade, (cmb-0)*shade+0 ** INC ** + {0x8531e4f0, cc_t0_sub_prim_mul_env_add_shade}, + // Robotron 64, [scorpiove] + // (env-shade)*env+shade ** INC ** + {0x85458545, cc_one_sub_env_mul_shade_add_env}, + // Enemy dying, quest64 + // (1-shade)*env+shade **changed by Gonetz + {0x85468546, cc_one_sub_shade_mul_env_add_shade}, + // Arena, Pokemon Stadium + // (t0-0)*env+shade, (cmb-0)*prim+0 + {0x85f1e3f0, cc__t0_mul_prim_mul_env__add__prim_mul_shade}, + // Clouds, Pokemon Stadium + // (t1-0)*env+shade, (cmb-0)*prim+0 + {0x85f2e3f0, cc__t1_mul_prim_mul_env__add__prim_mul_shade}, + // Sky, Beetle Adventure Racing ** INC ** + //(t0-shade)*t0_a+shade, (env-cmb)*enva+cmb + {0x88410c05, cc_t0_sub_shade_mul_t0a_add_shade}, + // Mario's eyes, mario + //z (t0-shade)*t0_a+shade + {0x88418841, cc_t0_sub_shade_mul_t0a_add_shade}, + //beetle adventure racing. Added by Gonetz + // (prim-shade)*t0_a+shade, (t1-0)*cmb+0 **INC** + {0x8843e0f2, cc_prim_sub_shade_mul__t0a_mul_t1__add_shade}, + // blast corps [Ogy] + // (prim-shade)*t1_a+shade + {0x89438943, cc_prim_sub_shade_mul_t1a_add_shade}, + //broken wall, beetle adventure racing. Added by Gonetz + // (t0-shade)*prima+shade, (1-0)*0+cmb + {0x8a411ff6, cc_t0_sub_shade_mul_prima_add_shade}, + // menu, battle phoenix 64. Added by Gonetz + // (t0-shade)*prima+shade + {0x8a418a41, cc_t0_add_shade}, + // intro, castlevania 2. Added by Gonetz + // (prim-shade)*prim_a+shade + {0x8a438a43, cc_prim_sub_shade_mul_prima_add_shade}, + // Pilot wings + // (t0-shade)*shade_a+shade, (cmb-0)*shade+0 + {0x8b41e4f0, cc__shade_inter_t0_using_shadea__mul_shade}, + // ? + // (1-shade)*shade_a+shade + {0x8b468b46, cc_one_sub_shade_mul_shadea_add_shade}, + // Pilot wings, sky in congratulations + // (t0-0)*shade_a+shade, + {0x8bf18bf1, cc_t0_mul_shadea_add_shade}, + // arena, Pokemon Stadium. Added by Gonetz + // (t0-t1)*env_a+shade, (cmb-env)*prim+0 ** INC ** + {0x8c21e350, cc__t0_sub_t1_mul_enva_add_shade__sub_env_mul_prim}, + //diddy kong racing background fill. Added by Gonetz ** Modified by Dave2001 + // (env-shade)*env_a+shade, (cmb-0)*prim+0 + {0x8c458c45, cc_shade}, // note: previous combiner used other_alpha; doesn't work + //diddy kong racing. Added by Gonetz + // (env-shade)*env_a+shade, (cmb-0)*prim+0 ** INC ** + {0x8c45e3f0, cc_prim_mul_shade}, + // sky, Pokemon Stadium, [Raziel64] + // (t0-0)*env_a+shade, (cmb-env)*prim+0 ** INC ** + {0x8cf1e350, cc_t0_mul_prim_add_shade_sub_env_mul_prim}, + // zelda 2 [Ogy]. Added by Gonetz + // (t0-prim)*primlod+shade, (prim-env)*cmb+env ** INC ** + {0x8e31a053, cc_prim_sub_env_mul__t0_sub_prim_mul_primlod_add_shade__add_env}, + // fallen leaves, Dobutsu no Mori. Added by Gonetz + // (t0-shade)*primlod+shade, (prim-env)*cmb+env ** INC ** + {0x8e41a053, cc_prim_sub_env_mul__t0_sub_shade_mul_primlod_add_shade__add_env}, + // the icicle above the part just before the entrance to the mountain village, zelda 2 [Ogy]. Added by Gonetz + // (t0-prim)*0+shade, (prim-env)*cmb+env ** INC ** ? + {0x9f31a053, cc_prim_sub_env_mul_shade_add_env}, + // background on level 3-1, kirby 64 [Raziel64]. Added by Gonetz + // (0-env)*0+shade + {0x9f5f9f5f, cc_shade}, + // Spotlight, smash bros + // (1-0)*0+shade + {0x9ff69ff6, cc_shade}, + // water, Fushigi no Dungeon - Furai no Shiren 2. Added by Gonetz + // (0-0)*0+shade, (cmb-cmb)*cmb+cmb + {0x9fff0000, cc_shade}, + // menu, Dr.Mario. Added by Gonetz + // (0-0)*0+shade, (prim-cmb)*env+cmb + {0x9fff0503, cc_prim_sub_shade_mul_env_add_shade}, + // pikachu, hey you pikachu. Added by Gonetz + // (0-0)*0+shade, (env-cmb)*enva+cmb + {0x9fff0c05, cc_env_sub_shade_mul_enva_add_shade}, + // mega shock, paper mario + //(0-0)*0+shade, (env-prim)*cmb+prim + {0x9fff6035, cc_env_sub_prim_mul_shade_add_prim}, + // Super Mario 64 logo background + //z (k5-k5)*0+shade + {0x9fff9fff, cc_shade}, + // Zelda 2 final movie. Added by Gonetz + // (0-0)*0+shade, (prim-0)*cmb+0 + {0x9fffe0f3, cc_prim_mul_shade}, + // tree shadow, Fushigi no Dungeon - Furai no Shiren 2. Added by Gonetz + // (0-0)*0+shade, (env-0)*cmb+0 + {0x9fffe0f5, cc_env_mul_shade}, + // N64 logo, Aidyn Chronicles. Added by Gonetz + // (0-0)*0+shade, (cmb-0)*prim+0 + {0x9fffe3f0, cc_prim_mul_shade}, + // Hand, smash bros + // (0-0)*0+shade, (cmb-0)*env+0 + {0x9fffe5f0, cc_env_mul_shade}, + // Lave piranha atack, Paper Mario + // (t1-t0)*t0+env, (cmb-t1)*t0+prim ** INC ** + {0xa1126120, cc__t0_mul_t1__mul_env_add_prim}, + //Arena, Pokemon Stadium 2 + // (t1-prim)*t0+env, (cmb-0)*shade+0 + {0xa132e4f0, cc__t1_sub_prim_mul_t0_add_env__mul_shade}, + // Kirby64 end [Raziel64]. Added by Gonetz + // (prim-shade)*t0+env + {0xa143a143, cc_prim_sub_shade_mul_t0_add_env}, + // Superman [scorpiove]. Added by Gonetz + // (t0-env)*t0+env + {0xa151a151, cc_t0_sub_env_mul_t0_add_env}, + // powder keg, zelda 2. Added by Gonetz + // (prim-env)*t0+env, (0-0)*shade_a+cmb + {0xa1530bff, cc__prim_sub_env_mul_t0_add_env__add_shadea}, + // pokemon attack, Pokemon Stadium 2. Added by Gonetz + // (prim-env)*t0+env, (0-0)*prim_lod+cmb + {0xa1530ef6, cc__prim_sub_env_mul_t0_add_env__add_primlod}, + //attack, Pokemon Stadium 2 + // (prim-env)*t0+env, (0-0)*prim_lod+cmb + {0xa1530eff, cc_prim_sub_env_mul_t0_add_env}, + // Kotake & koume defeated, going into sky, zelda + // (prim-env)*t0+env, (prim-env)*0+cmb + {0xa1531f53, cc_prim_sub_env_mul_t0_add_env}, + // water, Dobutsu no Mori. Added by Gonetz + // (prim-env)*t0+env, (cmb-0)*shade+t0 + {0xa15324f0, cc_t0_add_shade_mul_env}, + //sky, beetle adventure racing. Added by Gonetz + // (prim-env)*t0+env, (cmb-shade)*t1+shade **INC** can't be done in one step + {0xa1538240, cc__env_inter_prim_using_t0__sub_shade_mul_t0a_add_shade}, + //couple's mask, zelda2. Added by Gonetz + // (prim-env)*t0+env, (prim-cmb)*shade+shade **INC** can't be done in one step + {0xa1538403, cc_t0_mul_shade}, + // stadium, Pokemon Stadium 2. Added by Gonetz + // (prim-env)*t0+env, (cmb-0)*shade+shade **INC** can't be done in one step + {0xa15384f0, cc_t0_mul_shade}, + //clothes on girl in inn, zelda2. Added by Gonetz + // (prim-env)*t0+env, (cmb-prim)*env+shade **INC** can't be done in one step + {0xa1538530, cc_t0_mul_env_add_shade}, + // Getting light arrows for the first time, zelda + // (prim-env)*t0+env, (prim-env)*cmb+env ** INC ** + {0xa153a053, cc_prim_sub_env_mul_t0_add_env}, + // Fire, starfox + // (prim-env)*t0+env + {0xa153a153, cc_prim_sub_env_mul_t0_add_env}, + // a spell, Fushigi no Dungeon: Fuurai no Shiren 2 + // (prim-env)*t0+env, (cmb-env)*enva+env + {0xa153ac50, cc_prim_sub_env_mul__t0_mul_enva__add_env}, + // wizrobe's attack, zelda 2. Added by Gonetz. + // (prim-env)*t0+env, (cmb-0)*cmb+0 + {0xa153e0f0, cc_prim_sub_env_mul_t0_add_env}, + // dress, zelda 2. Added by Gonetz. + // also for Great Farie's hair - changed to use texture mod by Dave2001. + // (prim-env)*t0+env, (shade-0)*cmb+0 + {0xa153e0f4, cc__env_inter_prim_using_t0__mul_shade}, + // Start menu, paper mario + // (prim-env)*t0+env, (cmb-0)*t0+0 + {0xa153e1f0, cc_prim_sub_env_mul_t0_add_env}, + // {0xa153e0f4, cc_prim_sub_env_mul_t0_add_env}, + // Jellyfish tentacles in Jabu-Jabu's belly, zelda + // (prim-env)*t0+env, (cmb-0)*prim+0 + {0xa153e3f0, cc__env_inter_prim_using_t0__mul_prim}, + // Dust, zelda + //z (prim-env)*t0+env, (cmb-0)*shade+0 ** INC ** + {0xa153e4f0, cc__env_inter_prim_using_t0__mul_shade}, + //{0xa153e4f0, cc_prim_sub_env_mul_t0_add_env}, + // roof, Kirby 64. Added by Gonetz + // (prim-env)*t0+env, (cmb-0)*env+0 ** INC ** + {0xa153e5f0, cc_prim_sub_env_mul_t0_add_env}, + // hall of fame, Pokemon Stadium + // (prim-env)*t0+env, (cmb-0)*primlod+0 + {0xa153eef0, cc__prim_sub_env_mul_t0_add_env__mul_primlod}, + // Something weird in intro, monster truck madness + // (prim-env)*t0+env, (cmb-0)*k5+0 + {0xa153eff0, cc__prim_sub_env_mul_t0_add_env__mul_k5}, + // clothes, kirby 64. Added by Gonetz + // (shade-env)*t0+env + {0xa154a154, cc_shade_sub_env_mul_t0_add_env}, + // field, Derby Stallion + // (shade-env)*t0+env, (cmb-0)*prim+0 ** INC ** + {0xa154e3f0, cc_shade_sub_env_mul_t0_mul_prim_add_prim_mul_env}, + // background, level 3-5, kirby 64, [Raziel64] + // (shade-env)*t0+env, (cmb-0)*shade+0 ** INC ** + {0xa154e4f0, cc_shade_sub_env_mul_t0_add_env}, + // pokemon attack, Pokemon Stadium 2. Added by Gonetz + // (one-env)*t0+env + {0xa156a156, cc_one_sub_env_mul_t0_add_env}, + // Arena, Pokemon Stadium 2. + // (one-env)*t0+env, (cmb-0)*shade+0 + {0xa156e4f0, cc__env_inter_one_using_t0__mul_shade}, + //Arena, Pokemon Stadium 2 + // (t1-0)*t0+env, (cmb-0)*cmb+0 ** INC ** + {0xa1f2e0f0, cc__t0_mul_t1__add_env_mul__t0_mul_t1__add_env}, + // quake 2 intro + // (prim-0)*t0+env, (prim-0)*primlod+cmb ** INC ** + {0xa1f30ef3, cc_t0_mul_prim_add_env}, + // Kotake or koume's hair, zelda + // (prim-0)*t0+env + {0xa1f3a1f3, cc_t0_mul_prim_add_env}, + // track, ridge racer. Added by Gonetz + // (t0-env)*t1+env, (cmb-0)*shade+0 ** INC ** + {0xa251e4f0, cc__t0_mul_t1__mul_shade}, + // lava, beetle adventure racing + // (t0-env)*t1+env, (cmb-0)*enva+0 ** INC ** + {0xa251ecf0, cc__t0_mul_t1__mul_enva}, + // Ded Moroz, Paper Mario + // (prim-env)*t1+env, (1-cmb)*t1+cmb ** INC ** + {0xa2530206, cc_prim_sub_env_mul_t1_add_env}, + // text, monster truck madness + // (prim-env)*t1+env + {0xa253a253, cc_prim_sub_env_mul_t1_add_env}, + // car position, Top Gear Rally. Added by Gonetz + // (prim-env)*t1+env, (cmb-t0)*t1+0 ** INC ** + {0xa253e210, cc_prim_sub_env_mul_t1_add_env_mul_t0}, + // text, Top Gear Rally. Added by Gonetz + // (prim-env)*t1+env, (cmb-0)*t1+0 ** INC ** + {0xa253e2f0, cc_prim_sub_env_mul_t1_add_env_mul_t0}, + // {0xa253e2f0, cc_prim_sub_env_mul_t1_add_env}, + // a pole in the cut-scene that appears after you receive odolwa's mask, zelda 2 [Ogy]. Added by Gonetz + // (prim-env)*t1+env, (cmb-0)*shade+0 ** INC ** + {0xa253e4f0, cc_t1_mul_prim_mul_shade}, + // Quake 2 intro. Added by Gonetz + // (t0-0)*t1+env, (t0-0)*primlod+cmb ** INC ** + {0xa2f10ef1, cc__t0_mul_t1__add_env}, + // silver cave, pokemon stadium 2 + // (t0-0)*t1+env, (cmb-prim)*shadea+prim + {0xa2f16b30, cc_prim_inter__t0_mul_t1_add_env__using_shadea}, + // silver cave, pokemon stadium 2 + // (t0-0)*t1+env, (cmb-0)*shadea+shade + {0xa2f18bf0, cc__t0_mul_t1_add_env__mul_shadea_add_shade}, + // Quake64. Added by Gonetz + // (t0-0)*t1+env + {0xa2f1a2f1, cc__t0_mul_t1__add_env}, + // Quake II. Added by Gonetz ** INC ** + // (t0-0)*t1+env, (cmb-0)*prim+env + {0xa2f1a3f0, cc__t0_mul_t1__mul_prim_add_env}, + // Dr Mario [Ogy]. Added by Gonetz + // (t0-env)*prim+env + // {0xa351a351, cc_t0_mul_prim_add_env}, + {0xa351a351, cc_t0_sub_env_mul_prim_add_env}, + // menu, Dr.Mario. Added by Gonetz + // (prim-env)*prim+env + {0xa353a353, cc_prim_sub_env_mul_prim_add_env}, + // Razor sword, zelda 2. Added by Gonetz + // (shade-env)*prim+env, (cmb-0)*shade+0 ** INC ** + {0xa354e4f0, cc_shade_sub_env_mul_prim_add_env}, + // bomberman 64-2 intro. Added by Gonetz + // (1-env)*prim+env + {0xa356a356, cc_one_sub_env_mul_prim_add_env}, + // thing that escapes from the well, zelda + // (noise-env)*prim+env + {0xa357a357, cc_prim_add_env}, + // Bongo Bongo, zelda + // (noise-env)*prim+env, (cmb-0)*shade+0 + {0xa357e4f0, cc_env_mul_shade}, + // paper mario. Added by Gonetz + // (t0-0)*prim+env + {0xa3f1a3f1, cc_t0_mul_prim_add_env}, + // paper mario. Added by Gonetz + // (t0-0)*prim+env, (t0-env)*prim+0 + {0xa3f1e351, cc_t0_mul_prim_add_env}, + // paper mario. Added by Gonetz + // (t0-0)*prim+env, (t0-0)*prim+0 + {0xa3f1e3f1, cc_t0_mul_prim}, + // mahogany town statue, Pokemon Stadium 2 + // (t0-0)*prim+env, (cmb-0)*shade+0 + {0xa3f1e4f0, cc__t0_mul_prim_add_env__mul_shade}, + // squirt, paper mario. Added by Gonetz + // (t1-0)*prim+env, (1-cmb)*t1+cmb + {0xa3f20206, cc_t1_mul_prim_add_env}, + // paper mario. Added by Gonetz + // (shade-0)*prim+env + {0xa3f4a3f4, cc_prim_mul_shade_add_env}, + // Sharpen attack, pokemon stadium 2 + // (shade-0)*prim+env, (cmb-0)*shade+0 + {0xa3f4e4f0, cc__prim_mul_shade_add_env__mul_shade}, + // Doraemon 2. Added by Gonetz + // (1-0)*prim+env + {0xa3f6a3f6, cc_prim_add_env}, + // Pokemon Stadium 2, [Jeremy]. Added by Gonetz + // (noise-0)*prim+env ** INC ** ? + {0xa3f7a3f7, cc_prim_add_env}, + // monsters, Pokemon Stadium. Added by Gonetz + // (t0-t1)*shade+env, (cmb-0)*prim+0 ** INC ** + {0xa421e3f0, cc__t0_sub_t1__mul_prim_mul_shade_add_prim_mul_env}, + // background, pokemon stadium 2 + // (t0-prim)*shade+env + {0xa431a431, cc_t0_sub_prim_mul_shade_add_env}, + // Arena, pokemon stadium 2 + // (t0-prim)*shade+env, (cmb-0)*shade+0 + {0xa431e4f0, cc__t0_sub_prim_mul_shade_add_env__mul_shade}, + // Trophy, pokemon stadium 2 + // (t0-prim)*shade+env, (cmb-0)*shade_a+0 + {0xa431ebf0, cc__t0_sub_prim_mul_shade_add_env__mul_shadea}, + // Buildings, pokemon stadium 2 + // (t1-prim)*shade+env + {0xa432a432, cc_t1_sub_prim_mul_shade_add_env}, + // bomberman 64 [Ogy] + // (t0-env)*shade+env + {0xa451a451, cc_t0_mul_shade_add_env}, + // kirby drill, kirby 64. Added by Gonetz + // (prim-env)*shade+env + {0xa453a453, cc_prim_sub_env_mul_shade_add_env}, + // ball, ISS98 intro. Added by Gonetz + // (t0-0)*shade+env + {0xa4f1a4f1, cc_t0_mul_shade_add_env}, + // waterfall, Dobutsu_no_Mori + // (prim-0)*shade+env, (t0-0)*primlod+cmb + {0xa4f30ef1, cc_t0_mul_primlod_add_prim_mul_shade_add_env}, + // waterfall, Dobutsu_no_Mori + // (prim-0)*shade+env, (t1-0)*primlod+cmb + {0xa4f30ef2, cc_t1_mul_primlod_add_prim_mul_shade_add_env}, + // score, ISS98 intro. Added by Gonetz + // (prim-0)*shade+env + {0xa4f3a4f3, cc_prim_mul_shade_add_env}, + // magic fist, Rayman2. Added by Gonetz + // (env-0)*shade+env + {0xa4f5a4f5, cc_env_mul_shade_add_env}, + // gunfire, Quake64. Added by Gonetz + // (1-0)*shade+env + {0xa4f6a4f6, cc_env_add_shade}, + // flame, Paper Mario. Added by Gonetz + // (t0-center)*scale+env, (0-prim)*cmb+env + {0xa661a03f, cc_env_sub__t0_mul_scale_add_env__mul_prim}, + // N64 BIOS + // (t0-env)*t0_a+env, cmb*shade + {0xa851e0f4, cc__env_inter_t0_using_t0a__mul_shade}, + // pink car, f-zero x + // (t0-env)*t0_a+env, cmb*shade + {0xa851e4f0, cc__env_inter_t0_using_t0a__mul_shade}, + // PokemonStadium1, [Raziel64] + // (prim-env)*t0_a+env, (cmb-cmb)*cmb+cmb + {0xa8530000, cc_prim_sub_env_mul_t0a_add_env}, + // N64 logo, Ogre Battle + // (prim-env)*t0_a+env + {0xa853a853, cc_prim_sub_env_mul_t0a_add_env}, + // Mud Slap, Pokemon Stadium 2 [gokuss4]. Added by Gonetz + // (prim-env)*t0_a+env, (cmb-0)*cmb+0 + {0xa853e0f0, cc_prim_sub_env_mul_t0a_add_env}, + // Tree background, mace + // (prim-env)*t0_a+env, (cmb-0)*t0+0 + {0xa853e1f0, cc__env_inter_prim_using_t0a__mul_t0}, + //attack, Pokemon Stadium 2 + // (prim-env)*t0_a+env, (cmb-0)*prim+0 + {0xa853e3f0, cc__env_inter_prim_using_t0a__mul_prim}, + // logo, Deadly Arts. Added by Gonetz + // (prim-env)*t1_a+env + {0xa953a953, cc_prim_sub_env_mul_t1a_add_env}, + // MarioGolf text "Birdie Put" + // (t0-env)*prim_a+env + {0xaa51aa51, cc_t0_sub_env_mul_prima_add_env}, + // N64 BIOS + // (t0-env)*prim_a+env, (shade-0)*cmb+0 + {0xaa51e0f4, cc__env_inter_t0_using_prima__mul_shade}, + // N64 BIOS + // (prim-env)*prima+env, (shade-0)*cmb+0 + {0xaa53e0f4, cc__env_inter_prim_using_prima__mul_shade}, + // Girl, PD intro. Added by Gonetz + // (t0-env)*shade_alpha+env, (cmb-0)*shade+0 ** INC ** + {0xab51e4f0, cc__env_inter_t0_using_shadea__mul_shade}, + // Some gannon spell, zelda + // (prim-env)*shade_alpha+env + {0xab53ab53, cc_prim_sub_env_mul_shadea_add_env}, + //Arena, Pokemon Stadium 2 + // (t0-0)*shade_alpha+env, (cmb-0)*shade+prim + {0xabf164f0, cc__t0_mul_shadea_add_env__mul_shade_add_prim}, + // Boxes, Taz express. Added by Gonetz + // (t0-env)*env_a+env + {0xac51ac51, cc_t0_sub_env_mul_enva_add_env}, + // paper mario. Added by Gonetz + // (t0-env)*env_a+env, (cmb-0)*shade+0 **INC** + {0xac51e4f0, cc_t0_mul_env_mul_shade}, + // goal, Monster Truck Madness 64 + // (noise-0)*env_a+env, (cmb-0)*t1+0 **INC** + {0xacf7e2f0, cc_t1_mul_env}, + // sword on forge, zelda 2. Added by Gonetz + // (t1-t1)*lodf+env, (t1-t0)*cmb+prim + {0xae226012, cc__t1_sub_t0__mul_env_add_prim}, + // menu background, Pokemon Stadium 2, [Raziel64] + // (t0-prim)*lodf+env + {0xae31ae31, cc_t0_sub_prim_mul_primlod_add_env}, + // odd mushroom, zelda oot. Added by Gonetz + // (t0-shade)*lodf+env, (prim-env)*cmb+env ** INC ** + {0xae41a053, cc__env_inter_prim_using__t0_sub_shade_mul_primlod_add_env}, + // {0xae41a053, cc_prim_sub_env_mul__t0_mul_shade__add_env}, + // Morning Sun, Pokemon Stadium 2 [gokuss4]. Added by Gonetz + // (t0-env)*lodf+env, (cmb-0)*prim+0 + {0xae51e3f0, cc__env_inter_t0_using_primlod__mul_prim}, + //Spacestation Silicon Valley intro. Added by Gonetz + // (prim-env)*lodf+env + {0xae53ae53, cc_env_inter_prim_using_primlod}, + // Doom, intro. Added by Gonetz + // (t0-0)*lodf+env, (t0-0)*lodf+env + {0xaef1aef1, cc_t0_add_env}, + // Dobutsu no Mori. Added by Gonetz + // (prim-0)*lodf+env + {0xaef3aef3, cc_prim_add_env}, + // forest behind window, Dobutsu no Mori. Added by Gonetz + // (prim-0)*prim_lod+env, (t1-0)*cmb+0 + {0xaef3e0f2, cc_t0_mul__prim_mul_primlod_add_env }, + // tony hawks 2 menu + // (t0-rnv)*k5+env, (cmb-t1)*t1_a+t1 ** INC ** (correct combiner does not work because of black t1) + {0xaf514920, cc_t0_sub_env_mul_k5_add_env}, + // intro, Mission Impossible. Added by Gonetz + // (k5-k5)*0+env, (0-0)*scale+env + {0xbfffa6ff, cc_env}, + // Something blocking the screen, waverace + //z (k5-k5)*0+env + {0xbfffbfff, cc_env}, + // Derby Stallion . Added by Gonetz + // (0-0)*0+env, (cmb-0)*prim+0 + {0xbfffe3f0, cc_prim_mul_env}, + // zelda 2 [Ogy]. Added by Gonetz + // (k5-k5)*0+env, ((cmb-0)*shade+0 + {0xbfffe4f0, cc_env_mul_shade}, + // flame, paper mario. Added by Gonetz + // (t0-t1)*t0+1, (0-prim)*cmb+env **INC** weird + {0xc121a03f, cc__t0_inter_t1_using_half__mul_prim_add_env}, + // tube near big monster on level 5, Kirby64 [Raziel64] + // (prim-env)*t0+1, (cmb-0)*shade+0 ** INC ** + {0xc153e4f0, cc_prim_sub_env_mul_t0_mul_shade}, + // paper mario. Added by Gonetz + // (0-env)*t0+1, (prim-cmb)*t0+prim **INC** + {0xc15f6103, cc_env_sub_prim_mul_t0_add_prim}, + // HAL, smash bros + // (0-0)*0+1 + {0xdfffdfff, cc_one}, + // arena, Pokemon Stadium 1, [Raziel64] + // (0-0)*0+1, (cmb-0)*prim+0 + {0xdfffe3f0, cc_prim}, + // skis, Spacestation Silicon Valley. Added by Gonetz + // (shade-0)*cmb+0, (t1-t0)*primlod+t0 + {0xe0f42d12, cc_t0_inter_t1_using_primlod}, + // paper mario. Added by Gonetz + // (1-t1)*t0+0, (env-prim)*cmb+prim ** INC ** + {0xe1266035, cc_env_sub_prim_mul__t0_mul_t1__add_prim}, + // ground, zelda 2. Added by Gonetz. + // (t1-prim)*t0+0, (cmb-0)*shade+0 + {0xe132e4f0, cc__t1_sub_prim_mul_t0__mul_shade}, + // carmagedon + // (shade-prim)*t0+0 + {0xe134e134, cc_shade_sub_prim_mul_t0}, + // skeleton, castlevania 2. Added by Gonetz + // (1-prim)*t0+0, (cmb-0)*shade+0 + {0xe136e4f0, cc_t0_mul_1mprim_mul_shade}, + // Starshot logo. Added by Gonetz + // (shade-env)*t0+0, (1-0)*cmb+cmb + {0xe15400f6, cc_shade_sub_env_mul_t0}, + // Kirby morfing, smash bros. Added by Gonetz + // (shade-env)*t0+0 + {0xe154e154, cc_shade_sub_env_mul_t0}, + // menu, PGA euro tour. Added by Gonetz + // (1-env)*t0+0 + {0xe156e156, cc_one_sub_env_mul_t0}, + // paper mario. Added by Gonetz + // (t0-0)*t0+0, (1-cmb)*prim+cmb + {0xe1f10306, cc_one_sub_t0_mul_prim_add_t0}, + // F1 World Grand Prix. Added by Gonetz + // (t0-0)*t0+0, (shade-prim)*cmb+prim + {0xe1f16034, cc_shade_sub_prim_mul_t0_add_prim}, + // paper mario. Added by Gonetz + // (t0-0)*t0+0, (env-prim)*cmb+prim + {0xe1f16035, cc_env_sub_prim_mul_t0_add_prim}, + // sparkles, F1 World Grand Prix. Added by Gonetz + // (t0-0)*t0+0, (1-prim)*cmb+prim + {0xe1f16036, cc_one_sub_prim_mul_t0_add_prim}, + // rocket team basket, Pokemon Stadium 2 + // (t0-0)*t0+0, (cmb-prim)*shade+shade + {0xe1f18430, cc__t0_mul_t0__sub_prim_mul_shade_add_shade}, + // Tony Hawk's Pro Skater. Added by Gonetz + // (t0-0)*t0+0, (cmb-0)*t0+0 + {0xe1f1e1f0, cc_t0}, + // something in upper left corner, mario tennis + // (t0-0)*t0+0 + {0xe1f1e1f1, cc_t0}, + // zelda 2. Added by Gonetz + // (t0-0)*t0+0, (cmb-0)*prim+0 + {0xe1f1e3f0, cc_t0_mul_prim}, + // zelda 2 final movie. Added by Gonetz + // (t0-0)*t0+0, (cmb-0)*shade+0 + {0xe1f1e4f0, cc_t0_mul_shade}, + // paper mario. Added by Gonetz + // (t0-t1)*t0+1, (env-cmb)*prima+cmb ** INC ** + {0xe1f20a05, cc_t1_mul_prima}, + // terrain, SCARS. Added by Gonetz + // (t1-0)*t0+0, (env-prim)*cmb+prim + {0xe1f26035, cc_env_sub_prim_mul__t0_mul_t1__add_prim}, + // Trees, Zelda 2 + // (t1-0)*t0+0, (cmb-0)*shade+prim + {0xe1f264f0, cc__t0_mul_t1__mul_shade_add_prim}, + // terrain, SCARS. Added by Gonetz + // (t1-0)*t0+0, (env-shade)*cmb+shade + {0xe1f28045, cc_env_sub_shade_mul__t0_mul_t1__add_shade}, + // arena, Pokemon Stadium 2. Added by Gonetz + // (t1-0)*t0+0, (cmb-prim)*shade+shade ** INC ** + {0xe1f28430, cc__t0_mul_t1__sub_prim_mul_shade_add_shade}, + // arena, Pokemon Stadium 2 + // (t1-0)*t0+0, (cmb-env)*shade+shade + {0xe1f28450, cc__t0_mul_t1__sub_env_mul_shade_add_shade}, + // Zelda 2, [Ogy]. Added by Gonetz + // (t1-0)*t0+0, (cmb-prim)*env+shade ** INC ** + {0xe1f28530, cc__t0_mul_t1__sub_prim_mul_env_add_shade}, + // pokemon attack, Pokemon Stadium 2. Added by Gonetz + // (t1-0)*t0+0, (prim-env)*cmb+env + {0xe1f2a053, cc_prim_sub_env_mul__t0_mul_t1__add_env}, + // paper mario. Added by Gonetz + // (t1-0)*t0+0, (cmb-0)*prim+env + {0xe1f2a3f0, cc__t0_mul_t1__mul_prim_add_env}, + // Sand, pokemon stadium 2 + // (t1-0)*t0+0, (cmb-prim)*shade+env ** INC ** + {0xe1f2a430, cc__t0_mul_t1__mul_shade}, + // grass, Mission Impossible. Added by Gonetz + // (t1-0)*t0+0, (shade-0)*cmb+0 + {0xe1f2e0f4, cc__t0_mul_t1__mul_shade}, + // flag, Monako Grand Prix + // (t1-0)*t0+0 + {0xe1f2e1f2, cc_t0_mul_t1}, + // lighthouse's beam, zelda 2. Added by Gonetz + // (t1-0)*t0+0, (cmb-0)*prim+0 + {0xe1f2e3f0, cc__t0_mul_t1__mul_prim}, + // Bottom of wings, pilotwings + // (t1-0)*t0+0, (cmb-0)*shade+0 + {0xe1f2e4f0, cc__t0_mul_t1__mul_shade}, + // zelda 2. Added by Gonetz + // (t1-0)*t0+0, (cmb-0)*prima+0 + {0xe1f2eaf0, cc__t0_mul_t1__mul_prima}, + // lava, Roadsters. Added by Gonetz + // (prim-0)*t0+0, (1-prim)*t0+cmb + {0xe1f30136, cc_t0}, + // sky, Pokemon Stadium 2. Added by Gonetz + // (prim-0)*t0+0, (cmb-0)*shadea+env + {0xe1f3abf0, cc_t0_mul_prim_mul_shadea_add_env}, + // cars, Indy Racing 2000. Added by Gonetz + // (prim-0)*t0+0, (shade-0)*cmb+0 + {0xe1f3e0f4, cc_t0_mul_prim_mul_shade}, + // Sign shadows, zelda + //z (prim-k5)*t0+cmb_a + {0xe1f3e1f3, cc_t0_mul_prim}, + // Table, mace + // (prim-0)*t0+0, (cmb-0)*shade+0 + {0xe1f3e4f0, cc_t0_mul_prim_mul_shade}, + // Gauntlet Legends intro + // (prim-0)*t0+0, (cmb-0)*prima+0 + {0xe1f3eaf0, cc_t0_mul_prim_mul_prima}, + // walls, beetle adventure racing. Added by Gonetz + // (shade-0)*t0+0, (prim-0)*t0+cmb + {0xe1f401f3, cc_t0_mul_shade}, + // cars, ridge racer. Added by Gonetz + // (shade-0)*t0+0, (prim-cmb)*cmb_a+cmb **INC** + {0xe1f40703, cc_t0_mul_shade}, + // water block, Paper Mario. Added by Gonetz + // (shade-0)*t0+0, (prim-env)*cmb+env + {0xe1f4a053, cc_prim_sub_env_mul__t0_mul_shade__add_env}, + // a lot in TWINE. Added by Gonetz + // (shade-0)*t0+0, (cmb-0)*prim+env + {0xe1f4a3f0, cc_t0_mul_prim_mul_shade_add_env}, + // Xena. Added by Gonetz + // (shade-0)*t0+0, (env-0)*cmb+0 + {0xe1f4e0f5, cc_t0_mul_env_mul_shade}, + // Starshot logo. Added by Gonetz + // (shade-0)*t0+0, (1-0)*cmb+0 + {0xe1f4e0f6, cc_t0_mul_shade}, + // Duck Dodgers intro. Added by Gonetz + // (shade-0)*t0+0 + {0xe1f4e1f4, cc_t0_mul_shade}, + // shadow, Mission Impossible. Added by Gonetz + // (shade-0)*t0+0, (cmb-0)*prim+0 + {0xe1f4e3f0, cc_t0_mul_prim_mul_shade}, + // Tony Hawk's Pro Skater 3. Added by Gonetz + // (env-0)*t0+0, (t1-0)*shade+cmb ** INC ** + {0xe1f504f2, cc__t0_add_t1__mul_shade}, + // text, tonic trouble. Added by Gonetz + // (env-0)*t0+0 + {0xe1f5e1f5, cc_t0_mul_env}, + // powder keg, zelda 2. Added by Gonetz + // (env-0)*t0+0, (cmb-0)*shade+0 + {0xe1f5e4f0, cc_t0_mul_env_mul_shade}, + // Buss rush + // (1-0)*t0+0, (0-cmb)*0+cmb + {0xe1f61f0f, cc_t0}, + // water, Starshot. Added by Gonetz + // (1-0)*t0+0, (1-0)*cmb+0 + {0xe1f6e0f6, cc_t0}, + // bomberman 64 [Ogy] + // (1-0)*t0+0 + {0xe1f6e1f6, cc_t0}, + // Mermaid attack, Mystical Ninja + // (noise-0)*t0+0 + {0xe1f7e1f7, cc_t0}, + // paper mario. Added by Gonetz * changed because of odd palette copy + // (t0-0)*t1+0, (shade-env)*cmb+cmb **INC** ? + {0xe2f10054, cc_shade_sub_env_mul__t0_mul_t1__add__t0_mul_t1}, + // Duck Dodgers Starring Daffy Duck text background + // (t0-0)*t1+0, (shade-cmb)*prim+cmb + {0xe2f10304, cc_one_sub_prim_mul__t0_mul_t1__add__prim_mul_shade}, + // water, PGA European Tour + // (t0-0)*t1+0, (env-cmb)*prim+cmb + {0xe2f10305, cc_one_sub_prim_mul__t0_mul_t1__add__prim_mul_env}, + // Grass, mario golf + // (t0-0)*t1+0, (cmb-t0)*cmb_a+t0 + {0xe2f12710, cc_t0_mul_t1}, + // xg2, Added by Gonetz + // (t0-0)*t1+0, (env-prim)*cmb+prim + {0xe2f16035, cc_env_sub_prim_mul__t0_mul_t1__add_prim}, + // poo, CBFD, Added by Gonetz + // (t0-0)*t1+0, (cmb-env)*shade+prim ** INC ** + {0xe2f16450, cc__t0_mul_t1__mul_shade_add_prim}, + // the champion stage, Pokemon Stadium 2 + // (t0-0)*t1+0, (cmb-0)*shade+prim + {0xe2f164f0, cc__t0_mul_t1__mul_shade_add_prim}, + // sky, xg2, Added by Gonetz + // (t0-0)*t1+0, (cmb-prim)*cmb_a+prim + {0xe2f16730, cc__t0_mul_t1__sub_prim_mul__t0t1a__add_prim }, + // Sin and Punishment, [scorpiove], Added by Gonetz + // (t0-0)*t1+0, (env-prim)*cmb_a+prim + {0xe2f16735, cc_env_sub_prim_mul__t0t1a__add_prim}, + // cianwood gym walls, pokemon stadium 2 + // (t0-0)*t1+0, (cmb-prim)*shade+shade + {0xe2f18430, cc__t0_mul_t1__sub_prim_mul_shade_add_shade}, + // light, Ridge Racer. Added by Gonetz + // (t0-0)*t1+0, (prim-env)*cmb+env + {0xe2f1a053, cc_prim_sub_env_mul__t0_mul_t1__add_env}, + // Waterfall, duck dodgers. Added by Gonetz + // (t0-0)*t1+0, (shade-env)*cmb+env + {0xe2f1a054, cc_shade_sub_env_mul__t0_mul_t1__add_env}, + // Arena, Pokemon Stadium 2 ** INC ** + // (t0-0)*t1+0, (cmb-prim)*shade+env + {0xe2f1a430, cc__t0_mul_t1__mul_shade_add_env}, + // bikes, xg2 + // (t0-0)*t1+0, (shade-0)*cmb+0 + {0xe2f1e0f4, cc__t0_mul_t1__mul_shade}, + // Sky background, xg2 + // (t0-0)*t1+0 + {0xe2f1e2f1, cc_t0_mul_t1}, + // statistics, Banjo 2. Added by Gonetz + // (t0-0)*t1+0, (cmb-0)*prim+0 + {0xe2f1e3f0, cc__t0_mul_t1__mul_prim}, + // the champion stage, Pokemon Stadium 2 + // (t0-0)*t1+0, (cmb-prim)*shade+0 + {0xe2f1e430, cc__t0_mul_t1__sub_prim_mul_shade}, + // Water, pilotwings + // (t0-0)*t1+0, (cmb-0)*shade+0 + {0xe2f1e4f0, cc__t0_mul_t1__mul_shade}, + //beetle adventure racing. A dded by Gonetz + // (t0-0)*t1+0, (cmb-0)*env+0 + {0xe2f1e5f0, cc__t0_mul_t1__mul_env}, + //fall headwaters, zelda 2. Added by Gonetz + // (t1-0)*t1+0, (cmb-0)*shade+0 + {0xe2f2e4f0, cc_t1_mul_shade}, + //text, Paper Mario + // (prim-0)*t1+0 + {0xe2f3e2f3, cc_t1_mul_prim}, + //terrain, Beetle Adventure Racing. Added by Gonetz + // (shade-0)*t1+0 + {0xe2f4e2f4, cc_t1_mul_shade}, + // Transfer pack, Pokemon Stadium 2 + // (noise-0)*t1+0, (prim-env)*cmb+env + {0xe2f7a053, cc_prim_sub_env_mul_t1_add_env}, + // lens of truth, zelda 2 [Ogy]. Added by Gonetz + // (1-t0)*prim+0 + {0xe316e316, cc_one_sub_t0_mul_prim}, + //C&C pointer + //(shade-env)*prim+0 + {0xe354e354, cc_shade_sub_env_mul_prim}, + //C&C shadows + //(1-env)*prim+0 + {0xe356e356, cc_one_sub_env_mul_prim}, + // Magnitude, pokemon stadium 2 + // (t0-0)*prim+0, (t0-0)*env+cmb + {0xe3f105f1, cc_t0_mul__prim_add_env}, + // night vision, jet force gemini + // (t0-0)*prim+0, (noise-0)*env+cmb + {0xe3f105f7, cc_t0_mul_prim_add_env}, + // Smoke, diddy kong racing + // (t0-0)*prim+0, (env-cmb)*env_alpha+cmb + {0xe3f10c05, cc__t0_mul_prim__inter_env_using_enva}, + // battle menu, Paper Mario. Added by Gonetz + // (t0-0)*prim+0, (t0-env)*env_alpha+cmb ** INC ** + {0xe3f10c51, cc_t0_mul_prim}, + // stalactites, Beetle adventure Racing. Added by Gonetz + // (t0-0)*prim+0, (cmb-shade)*t1_alpha+shade ** INC ** + {0xe3f18940, cc_t0_mul_prim_add_shade }, + // ? in Jabu-Jabu's belly, submitted by gokuss4 + // {0xe4f1a053, (t0-0)*prim+0, (prim-env)*cmb+env + {0xe3f1a053, cc_prim_sub_env_mul__t0_mul_prim__add_env}, + // kirby drill, kirby 64. Added by Gonetz + // (t0-0)*prim+0, (cmb-env)*shade+env **INC** + {0xe3f1a450, cc_t0_mul_prim_mul_shade_add_env}, + // ? sign, zelda 2. Added by Gonetz + // (t0-0)*prim+0, (cmb-0)*cmb+0 ** INC ** + {0xe3f1e0f0, cc_t0_mul_prim}, + // vehicle, Star Wars Ep.1 Racer, [Raziel64]. Added by Gonetz + // (t0-0)*prim+0, (shade-0)*cmb+0 + {0xe3f1e0f4, cc_t0_mul_prim_mul_shade}, + // mini game, Pokemon Stadium 2 + // (t0-0)*prim+0, (1-0)*cmb+0 + {0xe3f1e0f6, cc_t0_mul_prim}, + // magic stuff, buck bumble. Added by Gonetz + // (t0-0)*prim+0, (cmb-0)*prim+0 + {0xe3f1e3f0, cc_t0_mul_prim_mul_prim}, + // The mario face, mario + //z (t0-k5)*prim+cmb_a + {0xe3f1e3f1, cc_t0_mul_prim}, + // Butterflies at Jabu-Jabu's lake, zelda + // (t0-0)*prim+0, (cmb-0)*shade+0 + {0xe3f1e4f0, cc_t0_mul_prim_mul_shade}, + // Sports shirt, Mia Soccer. Added by Gonetz + // (t1-0)*prim+0, (1-t0)*t1+cmb **INC** + // {0xe3f20216, cc_t0_mul_prim_add_t1}, + {0xe3f20216, cc_shirt}, + // Sprites, Ogre Battle. Added by Gonetz + // (t1-0)*prim+0 + {0xe3f2e3f2, cc_t1_mul_prim}, + // F1 World Grand Prix. Added by Gonetz + // (t1-0)*prim+0, (cmb-0)*shade+0 + {0xe3f2e4f0, cc_t1_mul_prim_mul_shade}, + // intro background, bio freaks. Added by Gonetz + // (prim-0)*prim+0 + {0xe3f3e3f3, cc_prim_mul_prim}, + // player, Ohzumou2 + // (shade-0)*prim+0, (env-cmb)*t0+cmb + {0xe3f40105, cc_env_sub_primshade_mul_t0_add_primshade}, + // floor in pyramides, beetle adventure racing. + // (shade-0)*prim+0, (t1-0)*cmb+0 + {0xe3f4e0f2, cc_t1_mul_prim_mul_shade}, + // Slingshot string, zelda + // (shade-0)*prim+0 + {0xe3f4e3f4, cc_prim_mul_shade}, + // ? + // (shade-0)*prim+0, (cmb-0)*shade+0 ** INC ** + {0xe3f4e4f0, cc_prim_mul_shade}, + // ???, zelda + // (env-0)*prim+0, (0-0)*0+cmb + {0xe3f5e3f5, cc_prim_mul_env}, + // Option selection, zelda + //z (1-0)*prim+0 + {0xe3f6e3f6, cc_prim}, + // ranco monster, zelda 2. Added by Gonetz + // (noise-0)*prim+0, (cmb-0)*prim_a+prim + {0xe3f76af0, cc_prim_mul_prima_add_prim}, + // F-1_World_Grand_Prix_II, olivieryuyu + // (noise-0)*prim+0, (0-cmb)*prim_a+shade + {0xe3f78a0f, cc_shade_sub__prim_mul_prima}, + // zelda 2 [Ogy]. Added by Gonetz + // (noise-0)*prim+0 + {0xe3f7e3f7, cc_prim}, + // Road rush. Added by Gonetz + // (0-0)*prim+0 ** INC ** ? + {0xe3ffe3ff, cc_prim}, + // Letter to Kafei's mom, zelda 2. Added by Gonetz + // (0-0)*prim+0, (cmb-0)*shade+0 + {0xe3ffe4f0, cc_prim_mul_shade}, + // Jabu-Jabu's Belly, zelda. Added by Gonetz + // (1-t0)*shade+0, (cmb-0)*prim+0 + {0xe416e3f0, cc_one_sub_t0_mul_prim_mul_shade}, + // Arena, Pokemon Stadium 2 + // (t0-prim)*shade+0 + {0xe431e431, cc_t0_sub_prim_mul_shade}, + // silver cave, pokemon stadium 2 + // (t0-env)*shade+0, (cmb-prim)*shade+prim + {0xe4516430, cc__t0_sub_env_mul_shade__sub_prim_mul_shade_add_prim}, + // bomb mask, zelda 2. Added by Gonetz + // (t0-env)*shade+0, (cmb-prim)*shade+shade ** INC ** + {0xe4518430, cc__t0_sub_env_mul_shade__sub_prim_mul_shade}, + // terrain, Top Gear Rally 2. Added by Gonetz + // (t0-env)*shade+0 + {0xe451e451, cc_t0_sub_env_mul_shade}, + // closes, Nightmire Creatures + // (1-env)*shade+0 + {0xe456e456, cc_one_sub_env_mul_shade}, + // water, Fushigi no Dungeon - Furai no Shiren 2. Added by Gonetz + // (t0-0)*shade+0, (cmb-cmb)*cmb+cmb + {0xe4f10000, cc_t0_mul_shade}, + // Monster truck madness intro. Added by Gonetz + // (t0-0)*shade+0, (1-0)*cmb+cmb ** INC ** + {0xe4f100f6, cc_t0_mul_shade}, + // terrain, SCARS. Added by Gonetz + // (t0-0)*shade+0, (prim-cmb)*t0+cmb ** INC ** + {0xe4f10103, cc_t0_mul_shade}, + // Boomerang circle, zelda + // (t0-0)*shade+0, (1-cmb)*t0+cmb + {0xe4f10106, cc_t0_mul_shade}, + // THPS3. + // (t0-0)*shade+0, (1-0)*t0+cmb + {0xe4f101f6, cc_t0_mul_shade}, + // ???, WWF No Mercy [CpuMaster] + // (t0-0)*shade+0, (env-cmb)*prim+cmb + {0xe4f10305, cc_t0_mul_one_sub_prim_mul_shade_add_prim_mul_env}, + // magic bubble, zelda2. Added by Gonetz + // (t0-0)*shade+0, (t1-0)*shade+cmb + {0xe4f104f2, cc__t0_mul_shade__add__t1_mul_shade}, + // bike select, xg2. Added by Gonetz + // (t0-0)*shade+0, (1-cmb)*env+cmb ** INC ** + {0xe4f10506, cc_t0_mul_shade}, + // a bugs life [Ogy] + // (t0-0)*shade+0, (cmb-0)*env+cmb + // {0xe4f105f0, cc_t0_mul_env_mul_shade}, + {0xe4f105f0, cc_t0_mul_shade}, + // Wall, quest64 + // (t0-0)*shade+0, (1-0)*env+cmb + {0xe4f105f6, cc_t0_mul_shade_add_env}, + //lava, beetle adventure racing. Added by Gonetz + // (t0-0)*shade+0, (prim-cmb)*cmb_a+cmb **INC** + {0xe4f10703, cc_t0_mul_shade}, + // course map, Ridge Racer. Added by Gonetz + // (t0-0)*shade+0, (prim-cmb)*prima+cmb **INC** + {0xe4f10a03, cc_t0_mul_shade}, + // arena, custom robo. Added by Gonetz + // (t0-0)*shade+0, (noise-cmb)*prima+cmb **INC** + {0xe4f10a07, cc_t0_mul_shade}, + // arena, custom robo 2. Added by Gonetz + // (t0-0)*shade+0, (0-cmb)*prima+cmb **INC** + {0xe4f10a0f, cc_t0_mul_shade}, + //floor in a cave, Paper mario. Added by Gonetz + // (t0-0)*shade+0, (cmb-prim)*prima+cmb **INC** + {0xe4f10a30, cc_t0_mul_shade}, + //beetle adventure racing. Added by Gonetz + // (t0-0)*shade+0, (t1-prim)*prima+cmb **INC** + {0xe4f10a32, cc_t0_mul_shade}, + // Monster truck madness intro. Added by Gonetz + // (t0-0)*shade+0, (shade-cmb)*shade_a+cmb ** INC ** + {0xe4f10b04, cc_t0_mul_shade}, + // xg2 intro. Added by Gonetz + // (t0-0)*shade+0, (1-cmb)*shade_a+cmb ** INC ** + {0xe4f10b06, cc__t0_mul_shade__inter_one_using_shadea}, + // Link's bomb, smash bros + // (t0-0)*shade+0, (env-cmb)*env_a+cmb ** INC ** + {0xe4f10c05, cc__t0_mul_shade__inter_env_using_enva}, + // language selection, Extreme-G XG2 (E) + // (t0-0)*shade+0, (1-cmb)*env_a+cmb + {0xe4f10c06, cc__t0_mul_shade__inter_one_using_enva}, + // A Bugs Life, [Raziel64] + // (t0-0)*shade+0, (cmb-0)*k5+cmb + {0xe4f10ff0, cc_t0_mul_shade}, + // Bass Rush + // (t0-0)*shade+0, (cmb-0)*0+cmb + {0xe4f11f0f, cc_t0_mul_shade}, + // car, Top Gear Rally. Added by Gonetz + // (t0-0)*shade+0, (cmb-t0)*t0a+t0 **INC** + {0xe4f12810, cc_t0_mul_shade}, + // logo, SCARS. Added by Gonetz + // (t0-0)*shade+0, (cmb-t0)*shadea+t0 **INC** + {0xe4f12b10, cc__t0_mul_shade_mul_shadea__add__t1_mul_one_sub_shadea}, + // ? sign, Spiderman. Added by Gonetz + // (t0-0)*shade+0, (0-0)*0+t1 + {0xe4f15fff, cc_t0_mul_shade}, + // Major League Baseball Featuring Ken Griffey Jr. + // (t0-0)*shade+0, (1-0)*cmb+prim ** INC ** + {0xe4f160f6, cc_t0_mul_shade_add_prim}, + // plants, CBFD. Added by Gonetz + // (t0-0)*shade+0, (cmb-env)*shade+prim ** INC ** + {0xe4f16450, cc_t0_sub_env_mul_shade_add_prim}, + // Kirby64. Added by Gonetz + // (t0-0)*shade+0, (cmb-prim)*prima+prim + {0xe4f16a30, cc_t0_mul_prima_mul_shade_add_prim_mul_one_sub_prima}, + // building shadow, Fushigi no Dungeon - Furai no Shiren 2. Added by Gonetz + // (t0-0)*shade+0, (0-0)*0+prim + {0xe4f17fff, cc_prim}, + // tire trace, beetle adventure racing. Added by Gonetz + // (t0-0)*shade+0, (env-cmb)*t1+shade **INC** + {0xe4f18205, cc_env_sub_shade_mul_t0_add_shade}, + // Gold Skulltula, zelda + // (t0-0)*shade+0, (prim-env)*cmb+env + {0xe4f1a053, cc_prim_sub_env_mul_t0_mul_shade_add_env}, + // {0xe4f1a053, cc_t0_mul_prim_mul_shade}, + // fighters, GASP Fighters + // (t0-0)*shade+0, (1-env)*cmb+env + {0xe4f1a056, cc_t0_mul_one_sub_env_mul_shade_add_env}, + // Brian, quest64 + // (t0-0)*shade+0, (cmb-0)*prim+env + {0xe4f1a3f0, cc_t0_mul_prim_mul_shade_add_env}, + // Objects in arena, pokemon stadium 2 + // (t0-0)*shade+0 + // (cmb-prim)*shade+env + {0xe4f1a430, cc_t0_mul_shade}, + // Monster truck madness intro. Added by Gonetz + // (t0-0)*shade+0, (cmb-env)*shadea+env **INC** + // {0xe4f1ab50, cc_t0_mul_shade_add_env}, + {0xe4f1ab50, cc__t0_mul_shade__sub_env_mul_shadea_add_env}, + // Taz express. Added by Gonetz + // (t0-0)*shade+0, (cmb-env)*enva+env **INC** + {0xe4f1ac50, cc_t0_mul_shade_add_env}, + // sky in doom. Added by Gonetz + // (t0-0)*shade+0, (cmb-0)*primlod+env **INC** + {0xe4f1aef0, cc_t0_mul_shade_add_env}, + // fighters, GASP Fighters + // (t0-0)*shade+0, (1-env)*cmb+0 + {0xe4f1e056, cc_t0_mul_one_sub_env_mul_shade}, + // walls, beetle adventure racing. Added by Gonetz + // (t0-0)*shade+0, (t0-0)*cmb+0 **INC** + {0xe4f1e0f1, cc_t0_mul_shade}, + // Link's face, zelda + //z (t0-k5)*shade+cmb_a, (prim-k5)*cmb+cmb_a + {0xe4f1e0f3, cc_t0_mul_prim_mul_shade}, + // Link's suit, zelda + //z (t0-k5)*shade+cmb_a, (env-k5)*cmb+cmb_a + {0xe4f1e0f5, cc_t0_mul_env_mul_shade}, + // Window, starfox + //z (t0-k5)*shade+cmb_a, (cmb-k5)*prim+cmb_a + {0xe4f1e3f0, cc_t0_mul_prim_mul_shade}, + // crystal, Doraemon 2 + //(t0-0)*shade+0, (t0-0)*prim+0 + {0xe4f1e3f1, cc_t0_mul_prim}, + // Characters, mace + // (t0-0)*shade+0, (cmb-0)*shade+0 + {0xe4f1e4f0, cc_t0_mul_shade}, + // Super Mario 64 logo + //z (t0-k5)*shade+cmb_a + {0xe4f1e4f1, cc_t0_mul_shade}, + // Kokiri's hat, zelda + // (t0-0)*shade+0, (cmb-0)*env+0 + {0xe4f1e5f0, cc_t0_mul_env_mul_shade}, + // Gauntlet Legends intro + // (t0-0)*shade+0, (cmb-0)*scale+0 + {0xe4f1e6f0, cc_t0_mul_scale_mul_shade}, + // Something on a tree, Paper Mario. Added by Gonetz + // (t0-0)*shade+0, (cmb-0)*prima+0 + {0xe4f1eaf0, cc_t0_mul_prima_mul_shade}, + // Course map, Ridge Racer. Added by Gonetz + // (t0-0)*shade+0, (cmb-0)*shadea+0 + {0xe4f1ebf0, cc_t0_mul_shade_mul_shadea}, + // Dodongo skull's eyes, zelda + // (t0-0)*shade+0, (cmb-0)*env_alpha+0 + {0xe4f1ecf0, cc_t0_mul_enva_mul_shade}, + // lava, beetle adventure racing. Added by Gonetz + // (t1-0)*shade+0, (cmb-prim)*cmb_a+prim **INC** + {0xe4f26730, cc_prim_inter_t1_mul_shade_using_texa}, + // headlight, beetle adventure racing. Added by Gonetz + // (t1-0)*shade+0, (env-cmb)*t0+shade **INC** + {0xe4f28105, cc_one_sub__t0_mul_t1__mul_shade}, + // bubble, Banjo-Kazooie. Added by Gonetz + // (t1-0)*shade+0 + {0xe4f2e4f2, cc_t1_mul_shade}, + // water, Fushigi no Dungeon - Furai no Shiren 2. Added by Gonetz + // (prim-0)*shade+0, (cmb-cmb)*cmb+cmb + {0xe4f30000, cc_prim_mul_shade}, + // lamp shadow, Fushigi no Dungeon - Furai no Shiren 2. Added by Gonetz + // (prim-0)*shade+0, (cmb-cmb)*t0+cmb + {0xe4f30100, cc_prim_mul_shade}, + // Yoshi, mario golf + // (prim-0)*shade+0, (env-cmb)*t0+cmb + {0xe4f30105, cc_env_sub_primshade_mul_t0_add_primshade}, + //Spacestation Silicon Valley intro. Added by Gonetz + // (prim-0)*shade+0, (env-cmb)*t1+cmb + {0xe4f30205, cc_env_sub_primshade_mul_t1_add_primshade}, + // Tip of brian's hair, quest64 + // (prim-0)*shade+0, (1-0)*env+cmb + {0xe4f305f6, cc_prim_mul_shade_add_env}, + // V8-2 menu + // (prim-0)*shade+0, (env-cmb)*cmb_a+cmb + {0xe4f30705, cc__prim_mul_shade__inter_env_using__prim_mul_shade_alpha}, + // Background circle, xg2 + // (prim-0)*shade+0, (1-cmb)*shade_a+cmb + {0xe4f30b06, cc_prim_mul_shade}, + // circle, waverace. Added by Gonetz + // (prim-0)*shade+0, (t0-cmb)*enva+cmb + {0xe4f30c01, cc_t0_sub__prim_mul_shade__mul_enva_add__prim_mul_shade}, + // enemy hit, Glover2 + // (prim-0)*shade+0, (env-cmb)*enva+cmb + {0xe4f30c05, cc__prim_mul_shade__inter_env_using_enva}, + // player, super bowling + // (prim-0)*shade+0, (0-0)*k5+cmb + {0xe4f30fff, cc_prim_mul_shade}, + //Lure, bass rush + // (prim-0)*shade+0, (0-cmb)*0+cmb + {0xe4f31f0f, cc_prim_mul_shade}, + // walls, beetle adventure racing. Added by Gonetz + // (prim-0)*shade+0, (cmb-shade)*t1+shade **INC** + {0xe4f38240, cc__one_inter_prim_using_t1__mul_shade}, + // GASP fighters + //(prim-0)*shade+0, (1-env)*cmb+0 + {0xe4f3e056, cc_prim_mul_one_sub_env_mul_shade}, + // Flag, mario kart + //z (prim-k5)*shade+cmb_a + {0xe4f3e4f3, cc_prim_mul_shade}, + // Characters, smash bros + // (prim-0)*shade+0, (cmb-0)*env+0 + {0xe4f3e5f0, cc_prim_mul_env_mul_shade}, + // N64 logo, ridge race. Added by Gonetz + // (shade-0)*shade+0, (prim-cmb)*prima+cmb **INC** + {0xe4f40a03, cc_shade}, + // fighter, shield mode, bio freaks. Added by Gonetz + // (shade-0)*shade+0 + {0xe4f4e4f4, cc_shade}, + // truck crush, Monster truck madness. Added by Gonetz + // (env-0)*shade+0, (env-0)*shade+cmb + {0xe4f504f5, cc_env_mul_shade}, + // Course map, Ridge Racer. Added by Gonetz + // (env-0)*shade+0 + {0xe4f5e4f5, cc_env_mul_shade}, + // lava, beetle adventure racing + // (1-0)*shade+0, (prim-cmb)*cmb_a+cmb + {0xe4f60703, cc_prim_sub_shade_mul_shadea_add_shade}, + // the wings in the song of soaring cut-scene, zelda2 [Ogy]. Added by Gonetz + // (1-0)*shade+0, (prim-0)*cmb+0 + {0xe4f6e0f3, cc_prim_mul_shade}, + // parts of vehicle, Star Wars Ep.I Racer. Added by Gonetz + // (1-0)*shade+0, (cmb-0)*prim+0 + {0xe4f6e3f0, cc_prim_mul_shade}, + // Snowflakes???, mario kart. Boxer shadow (fb effect}, Knockout Kings 2000 + // (1-0)*shade+0, (1-0)*shade+0 + {0xe4f6e4f6, cc_one_mul_shade}, + // ??? + // (noise-0)*shade+0 + {0xe4f7e4f7, cc_shade}, + // quest64 [Ogy] + // (prim-t0)*env+0, (0-0)*0+prim + {0xe5137fff, cc_prim}, + // field, Mike Piazza's Strike Zone + // (t0-prim)*env+0 ** INC ** + {0xe531e531, cc_t0_mul_env}, + // Mike Piazza's Strike Zone + // (shade-prim)*env+0 + {0xe534e534, cc_shade_sub_prim_mul_env}, + // rope, CBFD. Added by Gonetz + // (t0-0)*env+0, (1-env)*prim+cmb + {0xe5f10356, cc_one_sub_env_mul_prim_add__t0_mul_env}, + // Bell, Pokemon Stadium 2. Added by Gonetz + // (t0-0)*env+0, (shade-0)*prim+cmb + {0xe5f103f4, cc_t0_mul_env_add_prim_mul_shade}, + // aerofighter's assault [Ogy] + // (t0-0)*env+0, (1-t0)*shade+cmb + {0xe5f10416, cc_t0_mul_env_add_1mt0_mul_shade}, + // foto, Armorines - Project S.W.A.R.M. Added by Gonetz + // (t0-0)*env+0, (noise-0)*scale+cmb + {0xe5f106f7, cc_t0_mul_env}, + // Extreme G2, score. Added by Gonetz + // (t0-0)*env+0, (1-cmb)*enva+cmb ** INC ** + {0xe5f10c06, cc_t0_mul_env}, + // many objects in Tonic Trouble + // (t0-0)*env+0, (shade-0)*cmb+0 + {0xe5f1e0f4, cc_t0_mul_env_mul_shade}, + // Flying skull's eyes, zelda + // (t0-0)*env+0, (cmb-0)*prim+0 + {0xe5f1e3f0, cc_t0_mul_prim_mul_env}, + // Rock spell, quest64 + // (t0-0)*env+0, (cmb-0)*shade+0 + {0xe5f1e4f0, cc_t0_mul_env_mul_shade}, + // Text, mario + //z (t0-k5)*env+cmb_a + {0xe5f1e5f1, cc_t0_mul_env}, + // kirby 64. Added by Gonetz + // (prim-0)*env+0, (cmb-0)*shade+0 + {0xe5f3e4f0, cc_prim_mul_env_mul_shade}, + // wings, kirby 64. Added by Gonetz + // (prim-0)*env+0 + {0xe5f3e5f3, cc_prim_mul_env}, + // Text, xg2 + // (shade-0)*env+0, (1-cmb)*env_a+cmb + {0xe5f40c06, cc_env_mul_shade}, + // Text box, mario + //z (shade-k5)*env+cmb_a + {0xe5f4e5f4, cc_env_mul_shade}, + // bomberman 64 [Ogy] + // (1-0)*env+0 + {0xe5f6e5f6, cc_env}, + // Fushigi no Dungeon - Furai no Shiren 2. Added by Gonetz + // (1-t0)*scale+0 + {0xe616e616, cc_zero}, + // Gauntlet Legends intro. Added by Gonetz + // (t0-0)*scale+0, (cmb-0)*shade+0 + {0xe6f1e4f0, cc_t0_mul_scale_mul_shade}, + // shadows, Taz express. Added by Gonetz + // (t0-0)*scale+0 + {0xe6f1e6f1, cc_t0_mul_scale}, + // shadows, Knockout Kings 2000. Added by Gonetz + // (shade-0)*scale+0 + {0xe6f4e6f4, cc_scale_mul_shade}, + // bomberman 64 2 [Ogy]. Added by Gonetz + // (1-0)*scale+0 + {0xe6f6e6f6, cc_scale}, + // walls, beetle adventure racing. Added by Gonetz + // (t1-0)*t0_a+0, (1-t1)*cmb+t1 **INC** + {0xe8f24026, cc_t1}, + // house on rancho, zelda2. Added by Gonetz + // (t1-0)*t0_a+0, (cmb-0)*prim+0 + {0xe8f2e3f0, cc__t0a_mul_t1__mul_prim}, + // zelda2 [Ogy]. Added by Gonetz + // (t1-0)*t0_a+0, (cmb-0)*shade+0 + {0xe8f2e4f0, cc__t0a_mul_t1__mul_shade}, + // mini quiz, Pokemon Stadium 2 + // (prim-0)*t0_a+0, (cmb-t1)*primlod+t1 ** INC ** + {0xe8f34e20, cc_t0}, + // Major League Baseball Featuring Ken Griffey Jr. + // (prim-0)*t0_a+0 + {0xe8f3e8f3, cc_t0a_mul_prim}, + // Top Gear Hyper-Bike + // (1-0)*t0_a+0 + {0xe8f6e8f6, cc_t0a}, + // waterfall, Dobutsu_no_Mori + // (t0-0)*t1_a+0, (prim-env)*cmb+env + {0xe9f1a053, cc_prim_sub_env_mul__t0_mul_t1a__add_env}, + // logo, Deadly Arts. Added by Gonetz + // (t0-0)*t1_a+0, (cmb-0)*shade+0 + {0xe9f1e4f0, cc__t0_mul_t1a__mul_shade}, + // car, Roadsters. Added by Gonetz + // (prim-t0)*prim_a+0, (prim-cmb)*shade+0 ** INC ** + {0xea13e403, cc_prim_sub__prim_sub_t0_mul_prima__mul_shade}, + // arena, Pokemon Stadium 2. Added by Gonetz + // (1-t0)*prim_a+0, (0-prim)*cmb+prim ** INC ** + {0xea16603f, cc_t0_mul_prim}, + // V8-2 + // (1-prim)*prim_a+0 + {0xea36ea36, cc_one_sub_prim_mul_prima}, + // match start, Mario Tennis. Added by Gonetz + // (t0-0)*prim_a+0, (1-t0)*cmb+t0 ** INC ** + {0xeaf12016, cc_one_sub_t0_mul_prima_add_t0}, + // blast corps [Ogy] + // (t0-0)*prim_a+0 + {0xeaf1eaf1, cc_t0_mul_prima}, + // final battle, CBFD. Added by Gonetz + // (prim-0)*prim_a+0 + {0xeaf3eaf3, cc_prim_mul_prima}, + // flower's stalk, Paper Mario. Added by Gonetz + // (shade-0)*prim_a+0 + {0xeaf4eaf4, cc_shade_mul_prima}, + // blast corps [Ogy] + // (noise-0)*prim_a+0, (t1-0)*shade+cmb ** INC ** + {0xeaf704f2, cc_t0_mul_shade_add_prima}, + // F1 World Grand Prix. Added by Gonetz + // (noise-0)*prim_a+0, (t1-0)*env_a+cmb ** INC ** + {0xeaf70cf2, cc_t1_mul_enva}, + // shadows, killer instinct gold + // (0-0)*prim_a+0 + {0xeaffeaff, cc_zero}, + // background, killer instinct gold + // (t0-prim)*shade_a+0 + {0xeb31eb31, cc_t0_sub_prim_mul_shadea}, + // ground, C&C + // (t0-shade)*shade_a+0 + {0xeb41eb41, cc_t0_sub_shade_mul_shadea}, + // Wreslters, WWF No Mercy, [CpUMasteR] + // (t0-0)*shade_alpha+0, (env-cmb)*prim+cmb + {0xebf10305, cc_t0_mul_one_sub_prim_mul_shadea_add_prim_mul_env}, + // map, Pilot wings. Added by Gonetz + // (t0-0)*shade_alpha+0, (1-cmb)*shade+cmb + {0xebf10406, cc_one_sub_shade_mul__t0_mul_shadea__add_shade}, + // Indy Racing 2000. Added by Gonetz + // (t0-0)*shade_alpha+0, (1-0)*shade+cmb + {0xebf104f6, cc_t0_mul_shadea_add_shade}, + // logo, WCW-nWo Revenge + // (t0-0)*shade_alpha+0, (cmb-0)*prim+0 + {0xebf1e3f0, cc_t0_mul_prim_mul_shadea}, + // sky, pilot wings + // (t0-0)*shade_alpha+0, (1-cmb)*shade+0 + {0xebf1e406, cc_one_sub__t0_mul_shadea__mul_shade}, + // Wrestlers in Game, WWF No mercy [CpUMasteR] + // (t0-0)*shade_alpha+0 + {0xebf1ebf1, cc_t0_mul_shadea}, + // flag, top gear overdrive + // (prim-0)*shade_alpha+0 + {0xebf3ebf3, cc_prim_mul_shadea}, + // Ropes, WWF games + // (shade-0)*shade_alpha+0, (env-cmb)*prim+cmb + {0xebf40305, cc_shade_mul_shadea}, + // Ropes, WWF games + // (shade-0)*shade_alpha+0 + {0xebf4ebf4, cc_shade_mul_shadea}, + // arena, custom robo 2 + // (noise-0)*shade_alpha+0 + {0xebf7ebf7, cc_shadea}, + // Baton Pass attack, Pokemon Stadium 2 + // (t0-env)*enva+0, (shade-0)*prim+cmb + {0xec5103f4, cc__t0_sub_env_mul_enva__add_prim_mul_shade}, + // Bell, Pokemon Stadium 2. Added by Gonetz + // (t0-0)*enva+0, (shade-0)*prim+cmb + {0xecf103f4, cc_t0_mul_enva_add_prim_mul_shade}, + // blastcorps, unimp log. Added by Gonetz + // (t0-0)*enva+0 + {0xecf1ecf1, cc_t0_mul_enva}, + // car, Top Gear Rally. Added by Gonetz + // (env-0)*enva+0 + {0xecf5ecf5, cc_env_mul_enva}, + // Sand attack, pokemon Stadium (J) + // (noise-0)*enva+0, (prim-env)*cmb+env + {0xecf7a053, cc_prim_sub_env_mul_enva_add_env}, + // Walls of well through lens of truth, zelda + // (prim-t0)*primlod+0 ** INC ** + {0xee13ee13, cc_t0}, // JUST t0 b/c the other combiner handles the subtraction + // Pokemon attack, Pokemon Stadium 2 + // (noise-t0)*primlod+0, (1-env)*cmb+env ** INC ** + {0xee17a056, cc_env_inter_one_using__one_sub_t0_mul_primlod}, + // barrage attack, Pokemon Stadium 2 + // (t0-0)*primlod+0, (prim-0)*shade+cmb + {0xeef104f3, cc__t0_mul_primlod__add__prim_mul_shade}, + // something on a flor in stone temple, zelda 2. Added by Gonetz + // (t0-0)*primlod+0, (cmb-0)*prim+0 + {0xeef1e3f0, cc_t0_mul_primlod_mul_prim}, + // entrance to oceanside spider house, zelda 2. Added by Gonetz + // (t0-0)*primlod+0, (cmb-0)*shade+0 + {0xeef1e4f0, cc_t0_mul_primlod_mul_shade}, + // Haze/(all powder status changers}, Pokemon Stadium 2 [gokuss4]. Added by Gonetz + // (noise-0)*primlod+0, (prim-env)*cmb+env ** INC ** + {0xeef7a053, cc_prim_sub_env_mul_primlod_add_env}, + // pokemon attack, Pokemon Stadium 2. Added by Gonetz + // (noise-0)*primlod+0, (prim-cmb)*cmb+0 ** INC ** + {0xeef7e003, cc_zero}, + // Night trees, Monster truck madness. Added by Gonetz + // (t0-0)*k5+0 + {0xeff1eff1, cc_t0_mul_k5}, + // submitted by gokuss4 + // (0-0)*0+0, (0-0)*0+prim + {0xfffd5fe6, cc_prim}, + // intro, Bettle Adventure Racing, [Raziel64] + // (0-0)*0+0, (0-0)*0+t0 + {0xffff3fff, cc_t0}, + // Conker's face, CBFD + // (0-0)*0+0, (shade-env)*k5+prim + {0xffff6f54, cc_shade_sub_env_mul_k5_add_prim}, + // Boost, Beetle Adventure Racing. Added by Gonetz + // (0-0)*0+0, (0-0)*0+prim + {0xffff7fff, cc_prim}, + // headlight, beetle adventure racing. Added by Gonetz + // (0-0)*0+0, (0-0)*0+shade + {0xffff9fff, cc_shade}, + // intro, Bettle Adventure Racing, [Raziel64] + // (0-0)*0+0, (shade-env)*t1+env + {0xffffa254, cc_shade_sub_env_mul_t1_add_env}, + // Fly Swooping in, Pokemon Stadium 2 [gokuss4]. Added by Gonetz + // (0-0)*0+0, (1-env)*cmb_a+env + {0xffffa756, cc_env}, + // Waterfall, Donkey Kong 64 + // (0-0)*0+0, (t0-0)*t1+0 + {0xffffe1f2, cc_t0_mul_t1}, + // Screen clear, banjo kazooie + // (0-0)*0+0 + {0xffffffff, cc_zero}, + // { #CCEND } +}; + +static COMBINER alpha_cmb_list[] = { + // { #ACSTART } + //Tony Hawk's Pro Skater. Added by Gonetz + // (0-0)*0+0 + {0x01ff01ff, ac_zero}, + //terminal, Spacestation Silicon Valley. Added by Gonetz + // (0-0)*0+0, (0-0)*0+prim + {0x01ff07ff, ac_prim}, + // kirby drill, kirby 64. Added by Gonetz + // (0-0)*0+cmb, (0-0)*0+1 + {0x01ff0dff, ac_one}, + //chip in Spacestation Silicon Valley intro. Added by Gonetz + // (0-0)*0+cmb, (prim-0)*shade+0 + {0x01ff0f3b, ac_prim_mul_shade}, + //Goldeneye, [Jeremy]. Added by Gonetz + // (t0-t0)*lodf+t0, (cmb-0)*prim+0 + {0x02090ef8, ac_t0_mul_prim}, + // Indy Racing 2000. Added by Gonetz + // (t1-t0)*lodf+t0, (env-cmb)*prim+cmb ** INC ** + {0x020a00c5, ac_t0_inter_t1_using_primlod}, + // water, Spacestation Silicon Valley. Added by Gonetz + // (t1-t0)*lodf+t0, (0-shade)*0+cmb + {0x020a01e7, ac_t0_inter_t1_using_primlod}, + // Bridge, sf rush + //z (t1-t0)*lodf+t0 + {0x020a020a, ac_t0_inter_t1_using_primlod}, + // explosion, body harvest. Added by Gonetz + //(t1-t0)*lodf+t0, (0-0)*0+t0 + {0x020a03ff, ac_t0}, + // cars, PD intro. Added by Gonetz + // (t1-t0)*lodf+t0, (cmb-0)*shade+prim + {0x020a0738, ac__t0_inter_t1_using_primlod__mul_shade_add_prim}, + // Rocket Robot in Wheels intro + //(t1-t0)*lodf+t0, (0-0)*0+prim + {0x020a07ff, ac_prim}, + // Iguana background ground, turok + // (t1-t0)*lodf+t0, (0-0)*0+shade + {0x020a09ff, ac_shade}, + // Ground, monster truck madness + // (t1-t0)*lodf+t0, (0-0)*0+env + {0x020a0bff, ac_env}, + // Taz express. Added by Gonetz + // (t1-t0)*lodf+t0, (0-0)*0+1 + {0x020a0dff, ac_one}, + // Mike Piazza's Strike Zone + // (t1-t0)*lodf+t0, (cmb-0)*t0+0 + {0x020a0e78, ac_t0_inter_t1_using_primlod}, + // N64 logo, tetrisphere. Added by Gonetz + // (t1-t0)*lodf+t0, (cmb-0)*prim+0 + {0x020a0ef8, ac__t0_inter_t1_using_primlod__mul_prim}, + // Ground, mace + // (t1-t0)*lodf+t0, (cmb-0)*shade+0 + // {0x020a0f38, ac_t0_mul_shade}, + {0x020a0f38, ac__t0_inter_t1_using_primlod__mul_shade}, + // blast corps [Ogy] + // (t1-t0)*lodf+t0, (cmb-0)*env+0 + {0x020a0f78, ac__t0_inter_t1_using_primlod__mul_env}, + // blast corps [Ogy] + // (t1-t0)*lodf+t0, (t0-0)*env+0 + {0x020a0f79, ac_t0_mul_env}, + // blast corps. Added by Gonetz + // (t1-t0)*lodf+t0, (shade-0)*env+0 + {0x020a0f7c, ac_env_mul_shade}, + // field, Mike Piazza's Strike Zone + // (t1-t0)*lodf+t0, (0-0)*0+0 + {0x020a0fff, ac_t0_inter_t1_using_primlod}, + // blast corps, unimp log. Added by Gonetz + // (t1-t0)*t0+t0 + {0x024a024a, ac_t0_inter_t1_using_t0a}, + // zelda 2 [Ogy]. Added by Gonetz + // (t1-t0)*t0+t0, (cmb-0)*prim+0 **INC** + {0x024a0ef8, ac__t0_inter_t1_using_t0a__mul_prim}, + // text in a menu, Twisted_Edge_Extreme_Snowboarding [Razeil64]. Added by Gonetz + // (prim-t0)*t0+t0 **INC** + {0x024b024b, ac_t0}, + // enemy's shot, battle tanks 2 + // (env-prim)*t0+t0 **INC** + {0x025d025d, ac_t0}, + //Bowser in final battle, Paper Mario. Added by Gonetz + // (t1-env)*t0+t0, (cmb-env)*prim+0 ** INC ** + {0x026a0ee8, ac__t0_mul_t1__mul_prim}, + // paper mario. Added by Gonetz + // (t1-env)*t0+t0, (cmb-0)*prim+0 ** INC ** + {0x026a0ef8, ac__t0_mul_t1__mul_prim}, + // V8-2 + // (prim-0)*t0+t0 + {0x027b027b, ac_t0_mul_prim_add_t0}, + // THPS3. Added by Gonetz + // (0-0)*t0+t0 + {0x027f027f, ac_t0}, + // zelda 2. Added by Gonetz + // (0-0)*t0+t0, (cmb-0)*prim+0 + {0x027f0ef8, ac_t0_mul_prim}, + // Spider Web attack, Pokemon Stadium 2. + // (t1-t0)*t1+t0, (cmb-0)*prim+cmb + {0x028a00f8, ac__t0_inter_t1_using_t1a__mul_prim_add__t0_inter_t1_using_t1a}, + // teleportation, Spacestation Silicon Valley. Added by Gonetz + // (t1-t0)*t1+t0 + {0x028a028a, ac_t0_inter_t1_using_t1a}, + // mega shock, paper mario. Added by Gonetz + // (t1-t0)*t1+t0, (cmb-0)*prim+0 + {0x028a0ef8, ac__t0_inter_t1_using_t1a__mul_prim}, + // mini game, Pokemon Stadium 2 + // (t1-t0)*t1+t0, (cmb-0)*shade+0 + {0x028a0f38, ac__t0_inter_t1_using_t1a__mul_shade}, + // Magnitude, pokemon stadium 2 + // (shade-t0)*t1+t0, (cmb-0)*shade+env + {0x028c0b38, ac__t0_mul_t1__mul_shade}, + // paper mario. Added by Gonetz + // (1-t0)*t1+t0, (t1-0)*prim+0 ** INC ** + {0x028e0efa, ac__one_sub_t0_mul_t1_add_t0__mul_prim}, + // {0x028e0efa, ac_t1_mul_prim}, + // Spider Web attack, Pokemon Stadium 2. + // (1-t0)*t1+t0, (cmb-0)*shade+0 ** INC ** + {0x028e0f38, ac__one_sub_t0_mul_t1_add_t0__mul_prim}, + // paper mario. Added by Gonetz + // (t1-env)*t1+t0, (cmb-0)*shade+0 + {0x02aa0f38, ac__t0_inter_t1_using_enva__mul_shade}, + // Scary dead boss thing, zelda + // (env-1)*t1+t0, (cmb-0)*prim+0 * MAY need t1_inter_t0 instead... + {0x02b50ef8, ac__env_sub_one_mul_t1_add_t0__mul_prim}, + // first screen, castlevania. Added by Gonetz + // (env-0)*t1+t0 **INC** + {0x02bd02bd, ac_t0}, + // enemy's shot, battle tanks 2 [Flash] + // (1-0)*t1+t0, (0-0)*0+env + {0x02be0bff, ac_env}, + // battle tanks 2 [Ogy] + // (1-0)*t1+t0, (0-0)*0+1 + {0x02be0dff, ac_one}, + // menu screen, Rayman2. Added by Gonetz + // (1-0)*t1+t0, (cmb-0)*shade+0 + {0x02be0f38, ac__t0_add_t1__mul_shade}, + // Sky, zelda + //z (t1-t0)*prim+t0 + {0x02ca02ca, ac_t0_inter_t1_using_prima}, + // F1 World Grand Prix. Added by Gonetz + // (t1-t0)*prim+t0, (0-0)*0+1 + {0x02ca0dff, ac_t0_inter_t1_using_prima}, + // logo, PD. Added by Gonetz + // (t1-t0)*prim+t0, (cmb-0)*shade+0 + {0x02ca0f38, ac__t0_inter_t1_using_prima__mul_shade}, + // battle tanks [Ogy] + // (t1-t0)*prim+t0, (cmb-0)*env+0 + {0x02ca0f78, ac__t0_inter_t1_using_prima__mul_env}, + // logo, Deadly Arts. Added by Gonetz + // (env-t0)*prim+t0 + {0x02cd02cd, ac_one_sub_prim_mul_t0_add__prim_mul_env}, + // intro, castlevania 2. Added by Gonetz + // (1-t0)*prim+t0 + {0x02ce02ce, ac_one_sub_t0_mul_prim_add_t0}, + // intro, diddy kong racing. Added by Gonetz + // (1-t0)*prim+t0, (cmb-0)*shade+0 **INC** + {0x02ce0f38, ac_t0_mul_shade}, + // submitted by Scorpiove, mario party 1 + // (0-t0)*prim+t0 + {0x02cf02cf, ac_one_sub_prim_mul_t0}, + // Pokemon attack, pokemon Stadium (J) + // (t1-t1)*prim+t0, (prim-0)*lod_f+env **INC** + {0x02d20a3b, ac_env}, + // Ground, pokemon stadium 2 + // (t0-0)*prim+t0 + {0x02f902f9, ac_t0_mul_prim}, + // GASP Fighters + // (t1-0)*prim+t0, ** INC ** + {0x02fa02fa, ac_t1_mul_prim_add_t0}, + // foresight attack, Pokemon Stadium 2 + // (t1-0)*prim+t0, (cmb-env)*shade+0 + {0x02fa0f28, ac__t1_mul_prima_add_t0__sub_env_mul_shade}, + // Earthquake pokemon attack, Pokemon Stadium 2 [gokuss4]. Added by Gonetz + // (t1-0)*prim+t0, (cmb-0)*shade+0 + {0x02fa0f38, ac__t1_mul_prima_add_t0__mul_shade}, + // Paper Mario, fortune teller + // (t1-0)*prim+t0, (cmb-0)*env+0 + {0x02fa0f78, ac__t1_mul_prima_add_t0__mul_env}, + // Hydro Pump Attack, Pokemon Stadium. + // (shade-0)*prim+t0, (cmb-0)*shade+0 + {0x02fc0f38, ac__t0_add_prim_mul_shade__mul_shade}, + // map, Ogre Battle 64. Added by Gonetz + // (1-0)*prim+t0 + {0x02fe02fe, ac_t0_add_prim}, + // borders, Tony Hawk's Pro Skater 2. Added by Gonetz + // (t1-t0)*shade+t0 ** INC ** + {0x030a030a, ac_t0_inter_t1_using_shadea}, + // Mickey USA + // (t1-t0)*shade+t0, (cmb-0)*prim+0 ** INC ** + {0x030a0ef8, ac__t0_inter_t1_using_shadea__mul_prim}, + // Rocket Robot in Wheels intro + // (t1-t0)*shade+t0, (cmb-0)*env+0 ** INC ** + {0x030a0f78, ac__t0_inter_t1_using_shadea__mul_env}, + // water, Fushigi no Dungeon - Furai no Shiren 2. Added by Gonetz + // (1-t0)*shade+t0, (cmb-0)*shade+0 ** INC ** + {0x030e0f38, ac_t0_mul_shade}, + // sky, f-zero x + // (0-t0)*shade+t0 + {0x030f030f, ac_one_sub_shade_mul_t0}, + // Deku tree from kokiri villiage, zelda + //z (t1-t0)*env+t0, (t1-0)*primlod+cmb + {0x034a01ba, ac_t0_inter_t1_using_enva}, + // Hearts, zelda + //z (t1-t0)*env+t0 + {0x034a034a, ac_t0_inter_t1_using_enva}, + // Faries, zelda + //z (t1-t0)*env+t0, (cmb-0)*prim+0 + {0x034a0ef8, ac__t0_inter_t1_using_enva__mul_prim}, + // zelda, waterfall. Added by Gonetz + //z (t1-t0)*env+t0, (cmb-0)*shade+0 + {0x034a0f38, ac__t0_inter_t1_using_enva__mul_shade}, + // pokemon stadium 1. Added by Gonetz + //(t1-t0)*env+t0, (cmb-0)*primlod+0 + {0x034a0fb8, ac__t0_inter_t1_using_enva__mul_primlod}, + // fruits, Yoshi Story. Added by Gonetz + //(prim-t0)*env+t0 + {0x034b034b, ac_prim_sub_t0_mul_env_add_t0}, + // window, Rayman2. Added by Gonetz + //(1-t0)*env+t0 + {0x034e034e, ac_one_sub_t0_mul_env_add_t0}, + // menu, PokemonStadium1, [Raziel64] + //(1-t0)*env+t0, (cmb-0)*shade+0 ** INC ** + {0x034e0f38, ac_t0_mul_shade}, + // Ganon's sword swinging, zelda + // (t0-t1)*env+t0, (cmb-0)*prim+0 ** INC ** + {0x03510ef8, ac__t0_sub_t1_mul_enva_add_t0__mul_prim}, + // Lave piranha atack, Paper Mario + // (t1-prim)*env+t0, (0-cmb)*t1+0 ** INC ** + {0x035a0e87, ac_t0_mul_t1}, + // Reflected fire at kotake & koume's, zelda + // (t0-1)*env+t0, (cmb-0)*prim+0 ** INC ** + {0x03710ef8, ac__t0_sub_one_mul_enva_add_t0__mul_prim}, + // thing that escapes from the well, zelda + // (t1-1)*env+t0 ** INC ** + {0x03720372, ac_t1_sub_one_mul_enva_add_t0}, + // Sword charge, zelda + // (t1-1)*env+t0, (cmb-0)*prim+0 + {0x03720ef8, ac__t1_sub_one_mul_enva_add_t0__mul_prim}, + // Gannon hitting the ground, zelda + // (t1-1)*env+t0, (cmb-0)*shade+0 ** INC ** + {0x03720f38, ac__t1_sub_one_mul_enva_add_t0__mul_shade}, + // Tony Hawk's Pro Skater 3. Added by Gonetz + // (t0-0)*env+t0 + {0x03790379, ac_t0_mul_env}, + // paper mario. Added by Gonetz + // (t0-0)*env+t0, (cmb-0)*prim+0 + {0x03790ef8, ac_t0_mul_prim}, + // pads, Pokemon Stadium 2. Added by Gonetz + // (t1-0)*env+t0, (cmb-0)*prim+env ** INC ** + {0x037a0af8, ac__t0_inter_t1_using_enva__mul_prim_add_env}, + // attack, Pokemon Stadium 2 + // (t1-0)*env+t0, (cmb-t0)*prim+0 ** INC ** + {0x037a0ec8, ac__t1_mul_enva_add_t0__mul_prim}, + // Ice arrow gfx, zelda + // (t1-0)*env+t0, (cmb-0)*prim+0 + {0x037a0ef8, ac__t1_mul_enva_add_t0__mul_prim}, + // Scary face move, pokemon stadium 2 + // (t1-0)*env+t0, (cmb-prim)*shade+0 + {0x037a0f18, ac__t1_mul_enva_add_t0__sub_prim_mul_shade}, + // Saria's song, zelda + // (t1-0)*env+t0, (cmb-0)*shade+0 + {0x037a0f38, ac__t1_mul_enva_add_t0__mul_shade}, + // eye drops bottle, zelda + // (t0-t0)*prim_lodfrac+t0 + {0x03890389, ac_t0}, + // lighthouse's beam, zelda 2. Added by Gonetz + // (t0-t0)*prim_lodfrac+t0, (cmb-0)*prim+0 + {0x03890ef8, ac_t0_mul_prim}, + // zelda 2. Added by Gonetz + // (t1-t0)*primlod+t0, (cmb-0)*env+cmb ** INC ** + {0x038a0178, ac__t0_inter_t1_using_primlod__mul_env_add__t0_inter_t1_using_primlod}, + // Enter name letter background, zelda + //z (t1-t0)*primlod+t0 + {0x038a038a, ac_t0_inter_t1_using_primlod}, + // Sunny Day, Pokemon Stadium 2 + // (t1-t0)*primlod+t0, (cmb-0)*0+prim + {0x038a07f8, ac_prim}, + //attack, Pokemon Stadium 2 + // (t1-t0)*primlod+t0, (cmb-env)*shade+shade ** INC ** + {0x038a0928, ac__t0_inter_t1_using_primlod__sub_env_mul_shade_add_shade}, + // blastcorps, unimp log. Added by Gonetz + // (t1-t0)*primlod+t0, (0-0)*0+shade **INC**? + {0x038a09ff, ac_t0_inter_t1_using_primlod}, + // pokemon attack, pokemon monsters (J) + // (t1-t0)*primlod+t0, (cmb-0)*prim+env + {0x038a0af8, ac__t0_inter_t1_using_primlod__mul_prim_add_env}, + // sky, PGA European Tour + // (t1-t0)*primlod+t0, (0-0)*0+1 + {0x038a0dff, ac_one}, + // Ice surrounding enemy, zelda + // (t1-t0)*primlod+t0, (env-0)*lodf+0 + {0x038a0e3d, ac__t0_inter_t1_using_primlod__mul_env}, + // the bridge out side the mountain smithy shop, zelda 2 [Ogy]. Added by Gonetz + // (t1-t0)*primlod+t0, (cmb-0)*t0+0 + {0x038a0e78, ac_t0_inter_t1_using_primlod}, + // zelda 2, [Ogy]. Added by Gonetz + // (t1-t0)*primlod+t0, (cmb-0)*t1+0 + {0x038a0eb8, ac_t0_inter_t1_using_primlod}, + // Kirby's pool, smash bros + // (t1-t0)*primlod+t0, (cmb-0)*prim+0 + {0x038a0ef8, ac__t0_inter_t1_using_primlod__mul_prim}, + // Samus stage fire, smash bros + // (t1-t0)*primlod+t0, (cmb-0)*shade+0 + {0x038a0f38, ac__t0_inter_t1_using_primlod__mul_shade}, + // something about ice, zelda + // (t1-t0)*primlod+t0, (cmb-0)*env+0 + {0x038a0f78, ac__t0_inter_t1_using_primlod__mul_env}, + // Blast Corps. Added by Gonetz + // (t1-t0)*primlod+t0, (shade-0)*env+0 + {0x038a0f7c, ac_env_mul_shade}, + // goals, J. League Tactics Soccer. Added by Gonetz + // (prim-t0)*primlod+t0 ** INC ** + {0x038b038b, ac_t0}, + // zelda 2, [Ogy]. Added by Gonetz + // (t0-t1)*primlod+t0, (cmb-0)*prim+0 + {0x03910ef8, ac__t0_sub_t1_mul_primlod_add_t0__mul_prim}, + // a plane in the entrance to the mountain village zelda 2, [Ogy]. Added by Gonetz + // (t1-t1)*primlod+t0, (cmb-0)*prim+0 ** INC **? + {0x03920ef8, ac_t0_mul_prim}, + // zelda 2. Added by Gonetz + // (t1-prim)*primlod+t0, (cmb-0)*prim+0 ** INC ** + {0x039a0ef8, ac__t1_sub_prim_mul_primlod_add_t0__mul_prim}, + // zelda 2. Added by Gonetz + // (t1-shade)*primlod+t0, (cmb-0)*shade+0 ** INC ** + {0x03a20f38, ac__t1_sub_shade_mul_primlod_add_t0__mul_shade}, + // saffron city, Pokemon Stadium 2 + // (t1-1)*primlod+t0, (cmb-0)*0+cmb + {0x03b201f8, ac_t1_sub_one_mul_primlod_add_t0}, + // Candle flame in ganon's castle, zelda + // (t1-1)*primlod+t0 + {0x03b203b2, ac_t1_sub_one_mul_primlod_add_t0}, + // Fire, zelda + //z (t1-1)*primlod+t0, (cmb-0)*prim+0 ** INC ** + {0x03b20ef8, ac__t1_sub_one_mul_primlod_add_t0__mul_prim}, + // explosion, zelda 2. Added by Gonetz + // (t1-1)*primlod+t0, (t0-0)*prim+0 ** INC ** + {0x03b20ef9, ac_t0_mul_prim}, + // Din's fire, zelda + // (t1-1)*prim_lodfrac+t0, (cmb-0)*shade+0 ** INC ** + {0x03b20f38, ac__t1_sub_one_mul_primlod_add_t0__mul_shade}, + // Fire cloud, zelda + // (t1-1)*prim_lodfrac+t0, (cmb-0)*env+0 ** INC ** + {0x03b20f78, ac__t1_sub_one_mul_primlod_add_t0__mul_env}, + // zelda 2 [Ogy]. Added by Gonetz + // (prim-1)*prim_lodfrac+t0, (cmb-0)*env+0 ** INC ** + {0x03b30f78, ac__prim_sub_one_mul_primlod_add_t0__mul_env}, + // fairy's spirit, zelda oot + // (t0-0)*primlod+t0 + {0x03b903b9, ac_t0_mul_primlod_add_t0}, + // Scary face, pokemon stadium 2 + // (t0-0)*primlod+t0, (cmb-0)*prim+0 + {0x03b90ef8, ac_t0_mul_prim}, + // Magnitude attack, Pokemon Stadium 2 + // (t0-0)*primlod+t0, (cmb-0)*shade+0 + {0x03b90f38, ac__t0_mul_primlod_add_t0__mul_shade}, + // Leftovers Recovery, Pokemon Stadium 2 [gokuss4]. Added by Gonetz + // (t1-0)*prim_lodfrac+t0, (cmb-env)*prim+0 ** INC ** + {0x03ba0ee8, ac__t1_mul_primlod_add_t0__sub_env_mul_prim}, + // zelda 2 [Ogy]. Added by Gonetz + // (t1-0)*prim_lodfrac+t0, (cmb-0)*prim+0 + {0x03ba0ef8, ac__t1_mul_primlod_add_t0__mul_prim}, + // Mega punch attack, Pokemon Stadium 2 + // (t1-0)*prim_lodfrac+t0, (cmb-prim)*shade+0 + {0x03ba0f18, ac__t1_mul_primlod_add_t0__sub_prim_mul_shade}, + // zelda 2 [Ogy]. Added by Gonetz + // (t1-0)*prim_lodfrac+t0, (cmb-0)*shade+0 + {0x03ba0f38, ac__t1_mul_primlod_add_t0__mul_shade}, + // chuchu monsters, zelda 2 [Ogy]. Added by Gonetz + // (t1-0)*prim_lodfrac+t0, (cmb-0)*env+0 + {0x03ba0f78, ac__t1_mul_primlod_add_t0__mul_env}, + // Scary face, pokemon stadium 2 + // (env-0)*primlod+t0, (cmb-0)*prim+0 + {0x03bd0ef8, ac_t0_mul_prim}, + // ground, zelda 2. Added by Gonetz + // (t1-t0)*0+t0, (cmb-0)*0+cmb + {0x03ca01f8, ac_t0}, + // zelda 2. Added by Gonetz + // (t1-t0)*0+t0, (cmb-0)*prim+0 + {0x03ca0ef8, ac_t0_mul_prim}, + // smoke in a night, zelda 2. Added by Gonetz + // (t1-t0)*0+t0, (cmb-0)*shade+0 + {0x03ca0f38, ac_t0_mul_shade}, + //the ice plane out side the mountain smithy shop, zelda 2 [Ogy]. Added by Gonetz + //(t1-1)*0+t0, (cmb-0)*env+0 + {0x03f20f78, ac_t0_mul_env}, + //something on level 5, Kirby64 [Raziel64] + //(t0-0)*0+t0 + {0x03f903f9, ac_t0}, + //spider house, zelda 2 [Ogy]. Added by Gonetz + //(t0-0)*0+t0, (cmb-0)*prim+0 + {0x03f90ef8, ac_t0_mul_prim}, + //Darmani's fire spin, zelda 2 [Ogy]. Added by Gonetz + //(t1-0)*0+t0, (cmb-0)*prim+0 + {0x03fa0ef8, ac_t0_mul_prim}, + // headlight, beetle adventure racing. Added by Gonetz + //(1-0)*0+t0 + {0x03fe03fe, ac_t0}, + // player, super bowling + // (0-0)*0+t0, + {0x03ff0000, ac_t0}, + // Ghost's lantern, zelda + // (0-0)*0+t0, (t1-0)*prim_lod+cmb + {0x03ff01ba, ac_t1_mul_primlod_add_t0}, + // Hand cursor, mario + //z (0-0)*0+t0 + {0x03ff03ff, ac_t0}, + // Taz express. Added by Gonetz + // (0-0)*0+t0, (0-0)*0+t1 + {0x03ff05ff, ac_t0}, + // powder keg, zelda2. Added by Gonetz + // (0-0)*0+t0, (0-0)*0+prim + {0x03ff07ff, ac_t0}, + // water, Spacestation Silicon Valley. Added by Gonetz + // (0-0)*0+t0, (0-0)*0+shade + {0x03ff09ff, ac_t0}, + // Characters, Ogre Battle. Added by Gonetz. + // (0-0)*0+t0, (cmb-0)*prim+env + {0x03ff0af8, ac_t0_mul_prim_add_env}, + // Monster truck madness intro. Added by Gonetz + // (0-0)*0+t0, (0-0)*0+env + {0x03ff0bff, ac_t0}, + // Battlezone + // (0-0)*0+t0, (0-0)*0+1 + {0x03ff0dff, ac_t0}, + // Zoras, zelda + // (0-0)*0+t0, (env-0)*lodf+0 + {0x03ff0e3d, ac_env}, + // logo, v-rally 99 + // (0-0)*0+t0, (prim-0)*t0+0 + {0x03ff0e7b, ac_t0_mul_prim}, + // intro, WWF-War Zone + // (0-0)*0+t0, (env-0)*t0+0 + {0x03ff0e7d, ac_t0_mul_env}, + // Window, starfox + //z (0-0)*0+t0, (cmb-0)*prim+0 + {0x03ff0ef8, ac_t0_mul_prim}, + //beetle adventure racing. Added by Gonetz + // (0-0)*0+t0, (cmb-0)*shade+0 + {0x03ff0f38, ac_t0_mul_shade}, + // Wonder Project J2 logo. Added by Gonetz + // (0-0)*0+t0, (t0-0)*shade+0 + {0x03ff0f39, ac_t0_mul_shade}, + // Saria's suit, zelda + // (0-0)*0+t0, (cmb-0)*env+0 + {0x03ff0f78, ac_t0_mul_env}, + // Pokemon Stadium 2, [Jeremy]. Added by Gonetz + // (0-0)*0+t0, (cmb-0)*primlod+0 + {0x03ff0fb8, ac_t0_mul_primlod}, + // Tony Hawk's Pro Skater. Added by Gonetz + // (0-0)*0+t0, (0-0)*0+0 + {0x03ff0fff, ac_zero}, + // Spider Web attack, Pokemon Stadium 2. + // (t0-t1)*t0+t1, (cmb-0)*prim+cmb **INC** + {0x045100f8, ac__t1_inter_t0_using_t0a__mul_prim_add__t1_inter_t0_using_t0a}, + // Powered Star Beam, Paper Mario. Added by Gonetz + // (t0-t1)*t0+t1, (cmb-0)*prim+0 **INC** + {0x04510ef8, ac__t1_inter_t0_using_t0a__mul_prim}, + // Deadly Arts logo. Added by Gonetz + // (1-0)*t0+t1, (1-0)*prim+cmb + {0x047e00fe, ac__t0_add_t1__add_prim}, + // Spiderman. Added by Gonetz + // (1-0)*t0+t1 + {0x047e047e, ac_t0_add_t1}, + // water, Dobutsu no Mori. Added by Gonetz + // (1-0)*t0+t1, (cmb-0)*primlod+prim + {0x047e07b8, ac__t0_add_t1__mul_primlod_add_prim}, + // paper mario. Added by Gonetz + // (1-t0)*t1+t1, (cmb-0)*t1+0 **INC** + {0x048e0eb8, ac_t0_mul_t1}, + // Pokemon Stadium 2. Added by Gonetz + // (t0-prim)*t1+t1, (cmb-0)*shade+0 **INC** + {0x04990f38, ac_t1_mul_shade}, + // waterfall, Dobutsu no Mori. Added by Gonetz + // (t0-0)*t1+t1 + {0x04b904b9, ac_t0_mul_t1_add_t1}, + // light, Dobutsu no Mori. Added by Gonetz + // (t0-0)*t1+t1, (cmb-0)*primlod+0 ** INC ** + {0x04b90fb8, ac__t0_add_t1__mul_primlod}, + // lava, beetle adventure racing + // (t1-0)*t1+t1, (cmb-0)*shade+0 ** INC ** + {0x04ba0f38, ac__t1_mul_t1_add_t1__mul_shade}, + // wheels, F1 World Grand Prix. Added by Gonetz + // (t0-t1)*prim+t1 + {0x04d104d1, ac_t1_inter_t0_using_prima}, + // intro, castlevania 2. Added by Gonetz + // (t0-t1)*prim+t1, (cmb-0)*shade+0 + {0x04d10f38, ac__t1_inter_t0_using_prima__mul_shade}, + // flame, castlevania 2. Added by Gonetz + // (t0-t1)*prim+t1, (cmb-0)*env+0 + {0x04d10f78, ac__t1_inter_t0_using_prima__mul_env}, + // walls, beetle adventure racing. Added by Gonetz + // (t0-0)*prim+t1 **INC** + {0x04f904f9, ac_t0_mul_prim}, + // Reflect pokemon attack, Pokemon Stadium 2 [gokuss4]. Added by Gonetz + // (t0-0)*prim+t1, (cmb-0)*prim+env **INC** + {0x04f90af8, ac__t0_add_t1__mul_prim_add_env}, + // Psychic pokemon attack, Pokemon Stadium 2 [gokuss4]. Added by Gonetz + // (t0-0)*prim+t1, (cmb-0)*shade+0 **INC** + {0x04f90f38, ac__t0_add_t1__mul_shade}, + // Rayman2. Added by Gonetz + // (0-0)*shade+t1, (cmb-0)*env+0 + {0x053f0f78, ac_t1_mul_env}, + // Ground at kotake & koume, zelda + // (t1-t0)*env+t1, (cmb-0)*prim+0 ** INC ** + {0x054a0ef8, ac__t1_sub_t0_mul_enva_add_t1__mul_prim}, + // Tony Hawk's Pro Skater. Added by Gonetz + // (t0-t1)*env+t1 + {0x05510551, ac_t1_inter_t0_using_enva}, + // Shiek's disappearance, zelda + // (t0-1)*env+t1 + {0x05710571, ac_t0_sub_one_mul_enva_add_t1}, + // Kotake or koume's magic poof, zelda + // (t0-1)*env+t1, (cmb-0)*prim+0 ** INC ** + {0x05710ef8, ac__t0_sub_one_mul_enva_add_t1__mul_prim}, + // Gauntlet Legends intro + // (t0-0)*env+t1, (cmb-0)*prim+0 ** INC ** + {0x05790ef8, ac__t0_add_t1__mul_prim}, + // Zelda opening door, zelda + // (t0-0)*env+t1, (cmb-0)*shade+0 + {0x05790f38, ac_t1_mul_shade}, + // paper mario. Added by Gonetz + // (t1-0)*env+t1, (cmb-0)*prim+0 ** INC ** + {0x057a0ef8, ac_t1_mul_prim}, + // pokemon attack, Pokemon Stadium 2. Added by Gonetz + // (t0-t1)*prim_lod+t1, (cmb-0)*prim+0 + {0x05910ef8, ac__t1_inter_t0_using_primlod__mul_prim}, + // Skulltula coin, zelda + // (t0-1)*primlod+t1 ** INC ** + {0x05b105b1, ac_t0_mul_t1}, + // Bell, Pokemon Stadium 2. Added by Gonetz + // (t0-0)*primlod+t1, (cmb-env)*prim ** INC ** + {0x05b90ee8, ac__t0_add_t1__mul_prim}, + // intro, Aidyn Chronicles. Added by Gonetz + // (0-cmb)*0+t1, (t1-1)*0+cmb + {0x05c701f2, ac_t1}, + // zelda 2 [Ogy]. Added by Gonetz + // (t1-t0)*0+t1, (cmb-0)*prim+0 + {0x05ca0ef8, ac_t1_mul_prim}, + // beaver's river, zelda 2. Added by Gonetz + // (t1-0)*0+t1, (cmb-0)*prim+0 + {0x05fa0ef8, ac_t1_mul_prim}, + // Arena, pokemon stadium 2 + // (0-0)*0+t1, (0-0)*t0+cmb + {0x05ff007f, ac_t1}, + // Ogre Battle, unimp log. Added by Gonetz + // (0-0)*0+t1, (0-0)*0+cmb + {0x05ff05ff, ac_t1}, + // lullaby, Paper Mario. Added by Gonetz + // (0-0)*0+t1, (cmb-0)*prim+0 + {0x05ff0ef8, ac_t1_mul_prim}, + // aerofighter's assault [Ogy] + // (0-0)*0+t1, (cmb-0)*shade+0 + {0x05ff0f38, ac_t1_mul_shade}, + // magic fist, Rayman2. Added by Gonetz + // (0-0)*0+t1, (cmb-0)*env+0 + {0x05ff0f78, ac_t1_mul_env}, + // Pokemon selection background, Pokemon stadium 2 + // (env-prim)*t0+prim + {0x065d065d, ac_env_sub_prim_mul_t0_add_prim}, + // text background, Ganbare Goemon - Mononoke Sugoroku + // (1-prim)*t0+prim + {0x065e065e, ac_one_sub_prim_mul_t0_add_prim}, + // shadows, star wars: ep1 racer + // (0-prim)*t0+prim + {0x065f065f, ac_zero_sub_prim_mul_t0_add_prim}, + // lava, beetle adventure racing + // (0-1)*t0+prim, (cmb-0)*prim+0 ** INC ** + {0x06770ef8, ac_t0_mul_prim}, + // menu, Ganbare Goemon - Mononoke Sugoroku + // (t0-0)*t0+prim + {0x06790679, ac_t0_add_prim}, + // Water, pokemon stadium 2 + // (t1-0)*t0+prim + {0x067a067a, ac_t0_mul_t1_add_prim}, + // Smackdown Mall Menu, WWF No Mercy + // (shade-0)*t0+prim + {0x067c067c, ac_t0_mul_shade_add_prim}, + // flag, Top Gear Rally 2. Added by Gonetz + // (env-0)*t0+prim + {0x067d067d, ac_t0_mul_env_add_prim}, + // Mario Tennis. Added by Gonetz + // (1-0)*t0+prim + {0x067e067e, ac_t0_add_prim}, + // sky, PGA European Tour + // (t0-0)*t1+prim + {0x06b906b9, ac_t0_mul_t1_add_prim}, + // lava, beetle adventure racing + // (t0-0)*t1+prim, (0-0)*0+1 **INC**? + {0x06b90dff, ac_one}, + // Pokemon Stadium 2, [Jeremy]. Added by Gonetz + // (prim-0)*t1+prim + {0x06bb06bb, ac_t1_mul_prim_add_prim}, + // pokemon psyattack, Pokemon Stadium 2. Added by Gonetz + // (1-0)*t1+prim, (cmb-0)*env+0 + {0x06be0f78, ac_t1_add_prim_mul_env}, + // Rush2 2. Added by Gonetz + // (prim-prim)*prim+prim + {0x06db06db, ac_prim}, + //Spacestation Silicon Valley intro. Added by Gonetz + // (t1-prim)*shade+prim + // {0x071a071a, ac_t1_mul_shade}, + {0x071a071a, ac_t1_sub_prim_mul_shade_add_prim}, + //KI logos. Added by Gonetz + // (env-prim)*shade+prim + {0x071d071d, ac_env_sub_prim_mul_shade_add_prim}, + // Deadly Arts, arena. Added by Gonetz + // (1-0)*shade+prim + {0x073e073e, ac_prim_add_shade}, + // Phantom Gannon's portal, zelda + // (t1-t0)*env+prim, (cmb-0)*shade+0 ** INC ** + {0x074a0f38, ac__t0_mul_t1__mul_prim_mul_shade}, + // Road rush. Added by Gonetz + // (t0-0)*env+prim + {0x07790779, ac_t0_mul_env_add_prim}, + // arena, Pokemon Stadium 2 + // (shade-t0)*primlod+prim, (cmb-t0)*shade ** INC ** + {0x078c0f08, ac_shade_sub_t0_mul_primlod_add_prim}, + // telescope, zelda 2. Added by Gonetz + // (1-t0)*primlod+prim + {0x078e078e, ac_one_sub_t0_mul_primlod_add_prim}, + // zelda 2 [Ogy]. Added by Gonetz + // (t0-t1)*primlod+prim, (cmb-0)*t0+0 + {0x07910e78, ac_t0_inter_t1_using_primlod}, + // Dobutsu no Mori. Added by Gonetz + // (t0-0)*primlod+prim + {0x07b907b9, ac_t0_mul_primlod_add_prim}, + // Lock-On attack, Pokemon Stadium 2 + // (t1-t0)*0+prim, (cmb-0)*0+cmb + {0x07ca01f8, ac_prim}, + // water, DK64 + // (0-0)*0+0, (0-t1)*0+prim + {0x07d707d7, ac_prim}, + // Menu, megaman + // (1-0)*0+prim + {0x07fe07fe, ac_prim}, + // super bowling + //(0-0)*0+prim, + {0x07ff0000, ac_prim}, + // menu, Ganbare Goemon - Mononoke Sugoroku + // (0-0)*0+prim, (0-0)*0+t0 + {0x07ff03ff, ac_t0}, + // Intro background, starfox + //z (0-0)*0+prim + {0x07ff07ff, ac_prim}, + // velva boss, JFG + //(0-0)*0+prim, (0-0)*0+env + {0x07ff0bff, ac_env}, + // gem, castlevania 2. Added by Gonetz + // (0-0)*0+prim, (cmb-0)*t0+0 + {0x07ff0e78, ac_t0_mul_prim}, + // text, Tony Hawk's Pro Skater. Added by Gonetz + // (0-0)*0+prim, (cmb-0)*t1+0 + {0x07ff0eb8, ac_t1_mul_prim}, //weird, but implementing this makes text unreadable + // zelda 2. Added by Gonetz + // (0-0)*0+prim, (cmb-0)*prim+0 + {0x07ff0ef8, ac_prim_mul_prim}, + // explosion, Blast Corps. Added by Gonetz + // (0-0)*0+prim, (t0-0)*prim+0 + {0x07ff0ef9, ac_t0_mul_prim}, + // zelda 2, [Ogy]. Added by Gonetz + // (0-0)*0+prim, (cmb-0)*shade+0 + {0x07ff0f38, ac_prim_mul_shade}, + // Fox's ears and arms, smash bros + // (0-0)*0+prim, (cmb-0)*env+0 + {0x07ff0f78, ac_prim_mul_env}, + // monsters, Pokemon Stadium. Added by Gonetz + // (0-0)*0+prim, (cmb-0)*primlod+0 + {0x07ff0fb8, ac_prim_mul_primlod}, + // Hydro Pump Attack, Pokemon Stadium. + // (1-t1)*t0+shade, (cmb-prim)*shade+0 + {0x08560f18, ac__one_sub_t1_mul_t0_add_shade__sub_prim_mul_shade}, + // focus, Paper Mario. Added by Gonetz + //(t0-shade)*t0+shade, (cmb-0)*prim+0 * INC ** + {0x08610ef8, ac_t0_mul_prim}, + // Mario's head, mario //Added by Gonetz + //(prim-shade)*t0+shade + {0x08630863, ac_prim_sub_shade_mul_t0_add_shade}, + // Fissure attack, pokemon stadium 2 + //(t1-t0)*prim+shade, (cmb-0)*shade+0 + {0x08ca0f38, ac__t1_sub_t0_mul_prim_add_shade__mul_shade}, + // Earthquake pokemon attack, Pokemon Stadium 2 [gokuss4]. Added by Gonetz + //(t0-t1)*prim+shade, (cmb-0)*shade+0 ** INC ** + {0x08d10f38, ac__t0_sub_t1_mul_prim_add_shade__mul_shade}, + // ? + //(t0-shade)*prim+shade + {0x08e108e1, ac_t0_mul_prim_add_shade_mul_one_minus_prim}, + // Paper Mario + // (t0-prim)*shade+shade, (cmb-0)*env+0 + {0x09190f78, ac__t0_sub_prim_mul_shade_add_shade__mul_env}, + // pads, Pokemon Stadium 2. Added by Gonetz + // (0-t0)*env+shade, (cmb-0)*prim+0 ** INC ** + {0x094f0ef8, ac_one_sub_t0_mul_prim_mul_shade}, + // sun rays, Pokemon Stadium 2. + // (shade-0)*env+shade, (cmb-0)*prim+0 + {0x097c0ef8, ac_one_plus_env_mul_prim_mul_shade}, + // attack, Pokemon Stadium 2. + // (t0-0)*primlod+shade, (cmb-0)*shade+0 + {0x09b90f38, ac__t0_mul_primlod_add_shade__mul_shade}, + // Huge turtle appearance, zelda 2. Added by Gonetz + // (t1-0)*primlod+shade, (cmb-0)*shade+0 ** INC ** + {0x09ba0f38, ac__t1_mul_primlod_add_shade__mul_shade}, + // roof, Kirby 64. Added by Gonetz + // (t0-0)*0+shade + {0x09f909f9, ac_shade}, + // water, Fushigi no Dungeon - Furai no Shiren 2. Added by Gonetz + // (0-0)*0+shade, (cmb-cmb)*lodf+cmb + {0x09ff0000, ac_shade}, + // water temple, zelda 2. Added by Gonetz + // (0-0)*0+shade, (cmb-0)*prim+cmb + {0x09ff00f8, ac_prim_mul_shade_add_shade}, + // damaged car, SCARS. Added by Gonetz + // (0-0)*0+shade, (t0-t1)*primlod+prim ** INC ** + {0x09ff0791, ac_t0_mul_primlod_add_prim}, + // Hyrule castle gate, zelda + //z (0-0)*0+shade, (0-0)*0+prim + {0x09ff07ff, ac_prim}, + // Super Mario 64 logo + //z (0-0)*0+shade + {0x09ff09ff, ac_shade}, + // terrain, SCARS. Added by Gonetz + // (0-0)*0+shade, (0-0)*0+1 + {0x09ff0dff, ac_one}, + // terrain, SCARS. Added by Gonetz + // (0-0)*0+shade, (t0-0)*t1+0 + {0x09ff0eb9, ac_t0_mul_t1}, + // N64 logo, Aidyn Chronicles. Added by Gonetz + // (0-0)*0+shade, (cmb-0)*prim+0 + {0x09ff0ef8, ac_prim_mul_shade}, + // birds?, custom robo. Added by Gonetz + // (0-0)*0+shade, (cmb-0)*shade+0 + {0x09ff0f38, ac_shade}, + // sky, Glover, [Raziel64]. Added by Gonetz + // (0-0)*0+shade, (t0-0)*shade+0 + {0x09ff0f39, ac_t0_mul_shade}, + // Hand, smash bros + // (0-0)*0+shade, (cmb-0)*env+0 + {0x09ff0f78, ac_env_mul_shade}, + // Conker's helicopter tail, CBFD + // (0-0)*0+shade, (shade-0)*env+0 + {0x09ff0f7c, ac_env_mul_shade}, + // menu, PokemonStadium1, [Raziel64] + // (0-0)*0+shade, (cmb-0)*primlod+0 + {0x09ff0fb8, ac_primlod_mul_shade}, + // Link's sword slashing, smash bros + // (prim-env)*t0+env + {0x0a6b0a6b, ac_prim_sub_env_mul_t0_add_env}, + // Reflected beam at kotake & koume's, zelda + // (prim-env)*t0+env, (cmb-0)*prim+0 ** INC ** + {0x0a6b0ef8, ac_t0_mul_prim}, + // teleporter, Spacestation Silicon Valley. Added by Gonetz + // (prim-env)*t0+env, (cmb-0)*shade+0 ** INC ** + {0x0a6b0f38, ac_t0_mul_shade}, + // Ridge Racer, unimp log. Added by Gonetz + // (prim-env)*t0+env, (cmb-0)*primlod+0 + {0x0a6b0fb8, ac_prim_sub_env_mul_t0_add_env}, + // Kotake or koume's hair, zelda + // (prim-0)*t0+env + {0x0a7b0a7b, ac_t0_mul_prim_add_env}, + // menu, doubut no mori + // (1-0)*t0+env + {0x0a7e0a7e, ac_t0_add_env}, + // Grass, mario golf + // (env-shade)*t1+env, (0-0)*0+1 + {0x0aa50dff, ac_one}, + // Ridge Racer, cars select. Added by Gonetz + // (prim-env)*t1+env + {0x0aab0aab, ac_prim_sub_env_mul_t1_add_env}, + // text, monster truck madness + // (prim-env)*t1+env, (cmb-0)*t1+0 + {0x0aab0eb8, ac_t1_mul_env}, + // zelda 2 [Ogy]. Added by Gonetz + // (1-0)*t1+env, (0-0)*0+cmb + //{0x0abe0abe, ac_one}, + {0x0abe0abe, ac_t1_add_env}, + // arena, Pokemon Stadium 2. Added by Gonetz + // (1-t0)*prim+env, (cmb-0)*shade+0 + {0x0ace0f38, ac_one_sub_t0_mul_prim_mul_shade}, + // intro, Bomberman 64 - 2. Added by Gonetz + // (t0-env)*prim+env + {0x0ae90ae9, ac_t0_sub_env_mul_prim_add_env}, + // N64 logo, Ogre Battle. Added by Gonetz + // (t0-0)*prim+env + {0x0af90af9, ac_t0_mul_prim_add_env}, + // girls, PD intro. Added by Gonetz + // (t0-env)*shade+env ** INC ** + {0x0b290b29, ac_t0_sub_env_mul_shadea_add_env}, + // Text, Mia Soccer. Added by Gonetz + // (t0-env)*shade+env, (cmb-0)*lod_fraction+0 ** INC ** + {0x0b290e38, ac_t0_sub_env_mul_shadea_add_env}, + // shadows, Mario Tennis. Added by Gonetz + // (prim-env)*shade+env, (0-cmb)*t1+cmb ** INC ** + {0x0b2b0087, ac_prim_sub_env_mul_shade_add_env_mul_t1}, + // lamppost?, Ridge Racer. Added by Gonetz + // (prim-env)*shade+env, (0-0)*0+cmb + {0x0b2b0b2b, ac_prim_sub_env_mul_shade_add_env}, + // ground, zelda2. Added by Gonetz + // (1-env)*shade+env, (t1-0)*prim+0 + {0x0b2e0efa, ac_t1_mul_prim}, + // GASP Fighters + // (t0-0)*shade+env + {0x0b390b39, ac_t0_mul_shade_add_env}, + // destroying stuff, golden eye + // (1-0)*shade+env + {0x0b3e0b3e, ac_env_add_shade}, + // Torches, Paper Mario. Added by Gonetz + // (t0-t1)*env+env, (0-0)*0+1 + {0x0b510dff, ac_t0_sub_t1_mul_env_add_env}, + // Mini Racers + // (t0-0)*primlod+env + {0x0bb90bb9, ac_t0_mul_primlod_add_env}, + // International Track and Field 2000. Added by Gonetz + // (t0-0)*0+env + {0x0bf90bf9, ac_env}, + // TM, mario + //z (0-0)*0+env + {0x0bff0bff, ac_env}, + // rancho monster, zelda2. Added by Gonetz + // (0-0)*0+env, (cmb-0)*t1+0 + {0x0bff0eb8, ac_t1_mul_env}, + // Rocket Robot in Wheels intro + // (0-0)*0+env, (cmb-0)*prim+0 + {0x0bff0ef8, ac_prim_mul_env}, + // Background, Pokemon Snap + // (prim-env)*t0+1 + {0x0c6b0c6b, ac_prim_sub_env_mul_t0_add_one}, + // Mario Golf + // (0-1)*t0+1 + {0x0c770c77, ac_one_sub_t0}, + // flame, paper mario. Added by Gonetz + // (1-t0)*t1+1, (cmb-t1)*t1+t1 + {0x0c8e0490, ac_t0_mul_t1}, + // hall of fame, Pokemon Stadium + // (t0-1)*prim+1, (cmb-0)*env+0 + {0x0cf10f78, ac__one_inter_t0_using_prim__mul_env}, + // Ring boundary, dual heroes + // (0-1)*prim+1 + {0x0cf70cf7, ac_one_sub_prim}, + // Kirby64, level 6, [Raziel64] + // (0-0)*prim+1 + {0x0cff0cff, ac_one}, + // Mystical Ninja + // (0-1)*env+1 + {0x0d770d77, ac_one}, + // Deku shield in shop, zelda + // (1-1)*primlod+1 + {0x0db60db6, ac_one}, + // water near gorons willage. Added by Gonetz + // (t1-t0)*0+1, (cmb-0)*prim+0 + {0x0dca0ef8, ac_prim}, + // background, kirby 64. Added by Gonetz + // (t0-0)*0+1 + {0x0df90df9, ac_one}, + // kirby 64. Added by Gonetz + // (1-0)*0+1 + {0x0dfe0dfe, ac_one}, + // background on level 2-1, kirby 64 [Raziel64]. Added by Gonetz + // (1-0)*0+1, (0-0)*0+1 + {0x0dfe0dff, ac_one}, + // duck dodgers intro. Added by Gonetz + // (0-0)*0+1, (cmb-cmb)*primlod+cmb + {0x0dff0000, ac_one}, + // duck dodgers intro. Added by Gonetz + // (0-0)*0+1, (0-0)*0+t1 **INC**? + {0x0dff05ff, ac_t1}, + // ? + // (0-0)*0+1, (0-0)*0+prim + {0x0dff07ff, ac_prim}, + // arena, custom robo. Added by Gonetz + // (0-0)*0+1, (0-0)*0+shade + {0x0dff09ff, ac_shade}, + // field, Mario Golf + // (0-0)*0+1, (1-env)*shade+env + {0x0dff0b2e, ac_one_sub_env_mul_shade_add_env}, + // battle tanks 2 [Ogy] + // (0-0)*0+1, (0-0)*0+env + {0x0dff0bff, ac_env}, + // helmet, F1 World Grand Prix. Added by Gonetz + // (0-0)*0+1, (0-1)*0+1 + {0x0dff0df7, ac_one}, + // secret in level 3-4, Kirby64, [Raziel64] + // (0-0)*0+1, (cmb-0)*0+1 + {0x0dff0df8, ac_one}, + // Menu options, starfox + // (0-0)*0+1 + {0x0dff0dff, ac_one}, + // Water, zelda + //z (0-0)*0+primlod, (cmb-0)*prim+0 + {0x0dff0ef8, ac_prim}, + // Desert ground, zelda + // (0-0)*0+1, (cmb-0)*shade+0 + {0x0dff0f38, ac_shade}, + // Characters, smash bros + // (0-0)*0+1, (cmb-0)*env+0 + {0x0dff0f78, ac_env}, + // end of level 3-4, Kirby64, [Raziel64] + // (0-0)*0+1, (cmb-0)*0+0 + {0x0dff0ff8, ac_zero}, + // Kirby64 + // (0-0)*0+1, (0-0)*0+0 + {0x0dff0fff, ac_zero}, + // floor, Spiderman [Raziel64]. Added by Gonetz + // (env-t1)*t0+0 ** INC ** + {0x0e550e55, ac_t0_mul_env}, + // skeleton, castlevania 2. Added by Gonetz + // (1-prim)*t0+0 + {0x0e5e0e5e, ac_one_sub_prim_mul_t0}, + // player select, Forsaken [Raziel64]. Added by Gonetz + // (prim-shade)*t0+0 + {0x0e630e63, ac_prim_sub_shade_mul_t0}, + // castlevania 2 [Ogy]. Added by Gonetz + // (1-shade)*t0+0 + {0x0e660e66, ac_one_sub_shade_mul_t0}, + // GoldenEye: Helicopter rotors + // (shade-env)*t0+0, (1-0)*prim+cmb + {0x0e6c00fe, ac_shade_sub_env_mul_t0_add_prim}, + // background, level3-4, Kirby64, [Raziel64] + // (shade-env)*t0+0 + {0x0e6c0e6c, ac_shade_sub_env_mul_t0}, + // Goemon, mystical ninja. Added by Gonetz + // (1-env)*t0+0 + {0x0e6e0e6e, ac_one_sub_env_mul_t0}, + // fist attack, Fushigi no Dungeon - Furai no Shiren 2. Added by Gonetz + // (t0-0)*t0+0, (t1-cmb)*prim+cmb + {0x0e7900c2, ac_t0_inter_t1_using_prima}, + // Clay Fighter [Ogy]. Added by Gonetz + // (t0-0)*t0+0 + {0x0e790e79, ac_t0_mul_t0}, + // Fushigi no Dungeon - Furai no Shiren 2. Added by Gonetz + // (t0-0)*t0+0, (prim-0)*t1+0 + {0x0e790ebb, ac_t1_mul_prim}, + // zelda 2 [Ogy]. Added by Gonetz + // (t0-0)*t0+0, (cmb-0)*prim+0 + {0x0e790ef8, ac_t0_mul_prim}, + // zelda 2. Added by Gonetz + // (t0-0)*t0+0, (cmb-0)*shade+0 + {0x0e790f38, ac_t0_mul_shade}, + // zelda 2. Added by Gonetz + // (t0-0)*t0+0, (cmb-0)*env+0 + {0x0e790f78, ac_t0_mul_env}, + // the ice plane just before the entrance to gorons village (where tingle is}, zelda 2 [Ogy]. Added by Gonetz + // (t1-0)*t0+0, (cmb-0)*0+cmb + {0x0e7a01f8, ac_t0_mul_t1}, + // paper mario. Added by Gonetz + // (t1-0)*t0+0, (cmb-env)*prim+env ** INC ** + {0x0e7a0ae8, ac_t1_mul_prim}, + // mini games quiz monitor backround, Pokemon Stadium 2 + // (t1-0)*t0+0, (0-0)*0+1 + {0x0e7a0dff, ac_one}, + // Tony Hawk's Pro Skater. Added by Gonetz + // (t1-0)*t0+0, (cmb-0)*t0+0 + {0x0e7a0e78, ac_t0_mul_t1}, + // bike trace, xg2. Added by Gonetz + // (t1-0)*t0+0 + {0x0e7a0e7a, ac_t0_mul_t1}, + // Kotake & koume defeated, zelda + // (t1-0)*t0+0, (cmb-0)*prim+0 + {0x0e7a0ef8, ac__t0_mul_t1__mul_prim}, + // Magnitude, pokemon stadium 2 + // (t1-0)*t0+0, (cmb-env)*shade+0 + {0x0e7a0f28, ac__t0_mul_t1__mul_env_mul_shade}, + // Bongo Bongo, zelda + // (t1-0)*t0+0, (cmb-0)*shade+0 + {0x0e7a0f38, ac__t0_mul_t1__mul_shade}, + // Dobutsu_no_Mori, waterfall + // (t1-0)*t0+0, (cmb-0)*prim_lod+0 + {0x0e7a0fb8, ac__t0_mul_t1__mul_primlod}, + // Back of doors, megaman + // (prim-0)*t0+0, (cmb-0)*lodfrac+0 + {0x0e7b0e38, ac_t0_mul_prim}, + // Karts, mario kart + //z (prim-0)*t0+0 + {0x0e7b0e7b, ac_t0_mul_prim}, + // paper mario. Added by Gonetz + // (prim-0)*t0+0, (t0-0)*prim+0 + {0x0e7b0ef9, ac_t0_mul_prim}, + // Table, mace + // (prim-0)*t0+0, (cmb-0)*shade+0 + {0x0e7b0f38, ac_t0_mul_prim_mul_shade}, + // lamp shadow, Fushigi no Dungeon - Furai no Shiren 2. Added by Gonetz + // (shade-0)*t0+0, (cmb-cmb)*lodf+cmb + {0x0e7c0000, ac_t0_mul_shade}, + // Game logo, Aerofighters Assault [Raziel64] + //(shade-0)*t0+0, (0-0)*0+1 + {0x0e7c0dff, ac_one}, + // Higher sky, waverace + //z (shade-0)*t0+0 + {0x0e7c0e7c, ac_t0_mul_shade}, + // duck dodgers, intro. Added by Gonetz + // (shade-0)*t0+0, (cmb-0)*prim+0 + {0x0e7c0ef8, ac_t0_mul_prim_mul_shade}, + // waterwheel in water temple, zelda 2. Added by Gonetz + // (shade-0)*t0+0, (cmb-0)*env+0 + {0x0e7c0f78, ac_t0_mul_env_mul_shade}, + // Blowing up mine at bowser's, mario + // (env-0)*t0+0 + {0x0e7d0e7d, ac_t0_mul_env}, + // castlevania 2, intro. Added by Gonetz + // (1-0)*t0+0 + {0x0e7e0e7e, ac_t0}, + // moon, castlevania 2. Added by Gonetz + // (1-0)*t0+0, (cmb-0)*prim+0 + {0x0e7e0ef8, ac_t0_mul_prim}, + //beetle adventure racing. Added by Gonetz + // (1-0)*t0+0, (cmb-0)*shade+0 + {0x0e7e0f38, ac_t0_mul_shade}, + // lava, beetle adventure racing + // (t0-prim)*t1+0, (0-0)*0+shade ** INC ** + {0x0e9909ff, ac_shade}, + // Rain Dance, Pokemon Stadium 2 [gokuss4]. Added by Gonetz + // (t0-env)*t1+0, (cmb-0)*0+prim ** INC ** + {0x0ea90ef8, ac__t0_mul_t1__mul_prim}, + // Duck Dodgers Starring Daffy Duck text background + // (t0-0)*t1+0, (shade-cmb)*prim+cmb + {0x0eb900c4, ac_one_sub_prim_mul__t0_mul_t1__add__prim_mul_shade}, + // torches, pokemon stadium 2 + // (t0-0)*t1+0, (cmb-env)*prim+cmb + {0x0eb900e8, ac__t0_mul_t1__sub_env_mul_prim_add__t0_mul_t1}, + // airboarder 64 [Ogy] + // (t0-0)*t1+0, (0-0)*0+prim + {0x0eb907ff, ac_prim}, + // explosion, body harvest. Added by Gonetz + // (t0-0)*t1+0, (0-0)*0+shade + {0x0eb909ff, ac_shade}, + // Text off top, banjo kazooie + // (t0-0)*t1+0 + {0x0eb90eb9, ac_t0_mul_t1}, + // smoke, daikatana. Added by Gonetz + // (t0-0)*t1+0, (cmb-0)*prim+0 + {0x0eb90ef8, ac__t0_mul_t1__mul_prim}, + // Arena, Pokemon Stadium 2. + // (t0-0)*t1+0, (cmb-prim)*shade+0 + {0x0eb90f18, ac__t0_mul_t1__sub_prim_mul_shade}, + // Water, pilotwings + // (t0-0)*t1+0, (cmb-0)*shade+0 + {0x0eb90f38, ac__t0_mul_t1__mul_shade}, + // Tony Hawk's Pro Skater. Added by Gonetz + // (t0-0)*t1+0, (cmb-0)*env+0 + {0x0eb90f78, ac__t0_mul_t1__mul_env}, + // light from window, Dobutsu no Mori. Added by Gonetz + // (t0-0)*t1+0, (cmb-0)*primlod+0 + {0x0eb90fb8, ac__t0_mul_t1__mul_primlod}, + // chandelier in spider house, zelda 2. Added by Gonetz + // (t1-0)*t1+0, (cmb-0)*prim+0 + {0x0eba0ef8, ac_t1_mul_prim}, + // cars, ridge racer. Added by Gonetz + // (prim-0)*t1+0, (0-0)*0+1 + {0x0ebb0dff, ac_t1_mul_prim}, + // aerofighter's assault [Ogy] + // (prim-0)*t1+0 + {0x0ebb0ebb, ac_t1_mul_prim}, + // tire trace, beetle adventure racing. Added by Gonetz + // (shade-0)*t1+0 + {0x0ebc0ebc, ac_t1_mul_shade}, + // smoke, Starshot. Added by Gonetz + // (env-0)*t1+0 + {0x0ebd0ebd, ac_t1_mul_env}, + // lots of things, goldeneye + // (1-0)*t1+0, (0-0)*0+shade + {0x0ebe09ff, ac_shade}, + // zelda 2 [Ogy]. Added by Gonetz + // (1-0)*t1+0, (cmb-0)*prim+0 + {0x0ebe0ef8, ac_t1_mul_prim}, + // walls, perfect dark. Added by Gonetz + // (1-0)*t1+0, (cmb-0)*shade+0 + {0x0ebe0f38, ac_t1_mul_shade}, + // sand, perfect dark. Added by Gonetz + // (1-0)*t1+0, (cmb-0)*env+0 + {0x0ebe0f78, ac_t1_mul_env}, + // light, Ridge Racer. Added by Gonetz + // (1-t0)*prim+0 + {0x0ece0ece, ac_one_sub_t0_mul_prim}, + // exaust, star wars ep1 racer + // (1-t0)*prim+0, (cmb-0)*shade+0 + {0x0ece0f38, ac_one_sub_t0_mul_primshade}, + // iguana, Forsaken, [Raziel64]. Added by Gonetz + // (t0-shade)*prim+0 + {0x0ee10ee1, ac_t0_sub_shade_mul_prim}, + // stands, NASCAR 2000 + // (prim-shade)*prim+0 + {0x0ee30ee3, ac_prim_sub_shade_mul_prim}, + // arena, Pokemon Stadium 2. Added by Gonetz + // (t0-env)*prim+0 ** INC ** + {0x0ee90ee9, ac_t0_mul_prim}, + // lure, bass rush + // (t0-0)*prim+0, (cmb-cmb)*lodf+cmb + {0x0ef90000, ac_t0_mul_prim}, + // explosion, body harvest. Added by Gonetz + // (t0-0)*prim+0, (t0-0)*env+cmb + {0x0ef90179, ac_prim_add_env_mul_t0}, + // frog's eyes, zelda + // (t0-0)*prim+0, (1-1)*prim_lod+cmb + {0x0ef901b6, ac_t0_mul_prim}, + // Monster truck madness intro. Added by Gonetz + // (t0-0)*prim+0, (cmb-0)*prim_lod+cmb ** INC ** + {0x0ef901b8, ac_t0_mul_prim}, + // Road, zelda + //z (t0-0)*prim+0, (t1-0)*primlod+cmb + {0x0ef901ba, ac__t0_mul_prim__add__t1_mul_primlod}, + // Track, wipeout. Addded by Gonetz + // (t0-0)*prim+0, (0-0)*0+prim + {0x0ef907ff, ac_t0_mul_prim}, + // magic stuff, buck bumble. Added by Gonetz + // (t0-0)*prim+0, (cmb-0)*prim+0 + {0x0ef90ef8, ac_t0_mul_prim_mul_prim}, + // The mario face, mario + //z (t0-0)*prim+0 + {0x0ef90ef9, ac_t0_mul_prim}, + // paper mario. Added by Gonetz + // (t0-0)*prim+0, (cmb-0)*shade+0 + {0x0ef90f38, ac_t0_mul_prim_mul_shade}, + // Pikachu's mouth, smash bros + // (t0-0)*prim+0, (cmb-0)*env+0 + {0x0ef90f78, ac_t0_mul_prim_mul_env}, + // bomb mask, zelda 2. Added by Gonetz + // (t0-0)*prim+0, (1-0)*env+0 + {0x0ef90f7e, ac_t0_mul_prim}, + // Charmander's tail, pokemon stadium 2 + // (t0-0)*prim+0, (cmb-0)*primlod+0 + {0x0ef90fb8, ac_t0_mul_prim_mul_primlod}, + // stalactites, Beetle adventure Racing. Added by Gonetz + // (t1-0)*prim+0, (1-cmb)*shade+cmb + {0x0efa0106, ac_one_sub_shade_mul_t1_add_shade}, + // Sprites, Ogre Battle. Added by Gonetz + // (t1-0)*prim+0, (0-0)*0+cmb + {0x0efa0efa, ac_t1_mul_prim}, + // Something about kotake & koume's combined attack, zelda + // (t1-0)*prim+0, (cmb-0)*shade+0 + {0x0efa0f38, ac_t1_mul_prim_mul_shade}, + // intro background, bio freaks. Added by Gonetz + // (prim-0)*prim+0 + {0x0efb0efb, ac_prim_mul_prim}, + // sky, xg2. Added by Gonetz + // (shade-0)*prim+0, (0-0)*0+1 + {0x0efc0dff, ac_one}, + // Zelda, unimp log. Added by Gonetz + // (shade-0)*prim+0 + {0x0efc0efc, ac_prim_mul_shade}, + // ? + // (shade-0)*prim+0, (cmb-0)*shade+0 ** INC ** + {0x0efc0f38, ac_prim_mul_shade}, + // Baby mario's hat shadow, mario golf + // (env-0)*prim+0 + {0x0efd0efd, ac_prim_mul_env}, + // Menu, doom + // (1-0)*prim+0 + {0x0efe0efe, ac_prim}, + // Peris Song attack, Pokemin Stadium 2 + // (1-0)*prim+0, (cmb-0)*shade+0 + {0x0efe0f38, ac_prim_mul_shade}, + // Conker's shadow, CBFD. Added by Gonetz + // (1-t0)*shade+0 + {0x0f0e0f0e, ac_one_sub_t0_mul_shade}, + // Rock smash, pokemon stadium 2 + // (1-t0)*shade+0 + {0x0f0f0ee8, ac_one_sub_t0_mul_shade}, + //waterfall, Paper Mario + // (t0-t1)*shade+0 + {0x0f110f11, ac__t0_sub_t1__mul_shade}, + // mahogany town statue, Pokemon Stadium 2 + // (t0-prim)*shade+0 + {0x0f190f19, ac_t0_sub_prim_mul_shade}, + // silver cave, pokemon stadium 2 + // (t0-prim)*shade+0, (cmb-0)*env+0 + {0x0f190f78, ac_t0_sub_prim_mul_shade_mul_env}, + // Boomerang circle, zelda + // (t0-0)*shade+0, (1-cmb)*t0+cmb + {0x0f390046, ac_t0_mul_shade}, + // THPS3 + // (t0-0)*shade+0, (1-0)*t0+cmb + {0x0f39007e, ac_t0_mul_shade}, + // ??? + // (t0-0)*shade+0, (env-0)*t1+cmb + {0x0f3900bd, ac_t0_mul_shade}, + // Forest temple doorway, zelda + // (t0-0)*shade+0, (t1-0)*primlod+cmb + {0x0f3901ba, ac_t0_mul_shade}, + // skis, Spacestation Silicon Valley. Added by Gonetz + // (t0-0)*shade+0, (0-0)*0+t0 + {0x0f3903ff, ac_t0}, + // paper mario. Added by Gonetz + // (t0-0)*shade+0, (cmb-t0)*prim+0 + {0x0f390ec8, ac_t0_mul_prim_mul_shade}, + // House windows, zelda intro + //z (t0-0)*shade+0, (cmb-0)*prim+0 + {0x0f390ef8, ac_t0_mul_prim_mul_shade}, + // Characters, mace + // (t0-0)*shade+0, (cmb-0)*shade+0 + {0x0f390f38, ac_t0_mul_shade}, + // Shadows, mario + //z (t0-0)*shade+0 + {0x0f390f39, ac_t0_mul_shade}, + // Clear screen intro, banjo kazooie + // (t0-0)*shade+0, (cmb-0)*env+0 + {0x0f390f78, ac_t0_mul_env_mul_shade}, + // ridge racer, unimp log. Added by Gonetz + // (t0-0)*shade+0, (cmb-0)*primlod+0 **INC**? + {0x0f390fb8, ac_t0_mul_shade}, + // Reflecting combined attack at kotake & koume's, zelda + // (t1-0)*shade+0, (cmb-0)*prim+0 + {0x0f3a0ef8, ac_t1_mul_prim_mul_shade}, + // aerofighter's assault [Ogy] + // (t1-0)*shade+0 + {0x0f3a0f3a, ac_t1_mul_shade}, + //beetle adventure racing. Added by Gonetz + //(t1-0)*shade+0, (cmb-0)*env+0 + {0x0f3a0f78, ac_t1_mul_env_mul_shade}, + // building shadow, Fushigi no Dungeon - Furai no Shiren 2. Added by Gonetz + // (prim-0)*shade+0, (cmb-cmb)*lodf+cmb + {0x0f3b0000, ac_prim_mul_shade}, + //chip in Spacestation Silicon Valley intro. Added by Gonetz + // (prim-0)*shade+0, (env-cmb)*t1+cmb + {0x0f3b0085, ac_env_sub_primshade_mul_t1_add_primshade}, + // N64 logo, tetrisphere. Added by Gonetz + // (prim-0)*shade+0, (prim-0)*shade+0 + {0x0f3b0f3b, ac_prim_mul_shade}, + // rays, Fushigi no Dungeon - Furai no Shiren 2. Added by Gonetz + // (shade-0)*shade+0, (cmb-0)*prim+0 + {0x0f3c0ef8, ac_prim_mul_shade}, + // light, dracula resurrection, castlevania 2. Added by Gonetz + // (env-0)*shade+0 + {0x0f3d0f3d, ac_env_mul_shade}, + // zelda 2 [Ogy]. Added by Gonetz + // (1-0)*shade+0 + {0x0f3e0f3e, ac_shade}, + // surf pokemon attack, Pokemon Stadium 2 [gokuss4]. Added by Gonetz + // (1-t0)*env+0, (1-cmb)*shade+0 ** INC ** + {0x0f4e0f06, ac_t0_mul_shade}, + // GE, boxes + // (1-shade)*env+0, (cmb-0)*shade+0 ** INC ** + {0x0f660f38, ac_one_sub_shade_mul_env}, + //beetle adventure racing. Added by Gonetz + //(t0-0)*env+0, (1-t0)*prim+cmb + //{0x0f7900ce, ac_t0_mul_env}, //this one looks better + //{0x0f7900ce, ac_env_sub_prim_mul_t0_add_prim}, + {0x0f7900ce, ac_one_sub_t1_add_t0_mul_env}, + //Zelda, logo ? Added by Gonetz + //(t0-0)*env+0, (t1-0)*primlod+0 **INC** changed to mul_env for gannon's organ disappearing [Dave2001] + {0x0f7901ba, ac__t0_inter_t1_using_primlod__mul_env}, + // V8-2 menu + // (t0-0)*env+0, (0-0)*0+prim + {0x0f7907ff, ac_prim}, + // Skeleton guy's eyes, zelda + // (t0-0)*env+0, (cmb-0)*prim+0 + {0x0f790ef8, ac_t0_mul_prim_mul_env}, + // Dust from rock spell, quest64 + // (t0-0)*env+0, (cmb-0)*shade+0 + {0x0f790f38, ac_t0_mul_env_mul_shade}, + // eyes of poe, zelda + // (t0-0)*env+0, (cmb-0)*env+0 + {0x0f790f78, ac_t0_mul_env}, + // Text, mario + //z (t0-0)*env+0 + {0x0f790f79, ac_t0_mul_env}, + // Shadows, pokemon stadeom 2 + // (t0-0)*env+0, (cmb-0)*primlod+0 + {0x0f790fb8, ac_t0_mul_env_mul_primlod}, + //gauge, PGA + // (t1-0)*env+0, (cmb-0)*t1+0 ** INC ** + {0x0f7a0eb8, ac_t1_mul_env}, + //text and shadows, Rayman2. Added by Gonetz + // (t1-0)*env+0, (cmb-0)*shade+0 + {0x0f7a0f38, ac_t1_mul_env_mul_shade}, + // shadows, tom and jerry. Added by Gonetz + // (t1-0)*env+0 + {0x0f7a0f7a, ac_t1_mul_env}, + // Bomberman64-2 intro. Added by Gonetz + // (prim-0)*env+0 + {0x0f7b0f7b, ac_prim_mul_env}, + // Text box, mario + //z (shade-0)*env+0 + {0x0f7c0f7c, ac_env_mul_shade}, + // Ogre battle 64 + // (env-0)*env+0 + {0x0f7d0f7d, ac_env}, + //Goldeneye, [Jeremy]. Added by Gonetz + // (1-0)*env+0, (cmb-0)*shade+0 + {0x0f7e0f38, ac_env_mul_shade}, + // Status items, megaman + // (1-0)*env+0 + {0x0f7e0f7e, ac_env}, + // gun fire, Beast_Wars_Transmetal [Raziel64] + // (0-0)*env+0 + {0x0f7f0f7f, ac_zero}, + // Pokemon attack, Pokemon stadium (J). Added by Gonetz + // (t1-t0)*primlod+0, (cmb-0)*env+prim ** INC ** + {0x0f8a0778, ac__t1_sub_t0_mul_primlod__mul_env_add_prim}, + // Shadow Ball, Pokemon Stadium 2 [gokuss4]. Added by Gonetz + // (t1-t0)*primlod+0, (t1-cmb)*prim+0 ** INC ** + {0x0f8a0ec2, ac_t0_mul_prim}, + // Walls of well through lens of truth, zelda + // (prim-t0)*primlod+0 + {0x0f8b0f8b, ac_prim_sub_t0}, + // N64 logo, ridge racer. Added by Gonetz + // (1-prim)*primlod+0 **INC** + {0x0f9e0f9e, ac_zero}, + // Vines that covers a door in the third room of woodfall temple, zelda 2 [Ogy]. Added by Gonetz + // (t0-0)*primlod+0, (cmb-0)*prim+0 + {0x0fb90ef8, ac_t0_mul_primlod_mul_prim}, + // zelda 2. Added by Gonetz + // (t0-0)*primlod+0 + {0x0fb90fb9, ac_t0_mul_primlod}, + // NFL Blitz logo. Added by Gonetz + // (t1-0)*primlod+0 + {0x0fba0fba, ac_t1_mul_primlod}, //causes issues + // fallen stars at star summit, Paper Mario. Added by Gonetz + // (shade-0)*primlod+0 + {0x0fbc0fbc, ac_primlod_mul_shade}, + // expansion pack, Jeremy McGrath Supercross 2000. Added by Gonetz + // (1-0)*primlod+0 + {0x0fbe0fbe, ac_primlod}, + // intro, Aidyn Chronicles. Added by Gonetz + // (0-0)*primlod+0, (prim-env)*t0+prim **INC** + {0x0fbf066b, ac_t0_mul_prim}, + // sky, Rayman2. Added by Gonetz + // (0-shade)*0+0 + {0x0fe70fe7, ac_zero}, + // flame, PokemonStadium1 [Raziel64] + // (t0-0)*0+0 + {0x0ff90ff9, ac_zero}, + //BAR + // (0-0)*0+0, (0-0)*0+TEXEL1 + {0x0fff05ff, ac_t0}, + // Screen clear, banjo kazooie + // (0-0)*0+0 + {0x0fff0fff, ac_zero}, + // { #ACEND } +}; + +// CountCombine - count the # of entries in the combine lists +void CountCombine () +{ + int size = sizeof(color_cmb_list) / sizeof(COMBINER); + int i=0, index=0, a, b; + do { + a = color_cmb_list[index].key >> 24; + for (; i<=a; i++) + cc_lookup[i] = index; + + while (index < size) + { + b = color_cmb_list[index].key >> 24; + if (b != a) break; + index ++; + } + } while (index < size); + for (; i<257; i++) cc_lookup[i] = index; + + size = sizeof(alpha_cmb_list) / sizeof(COMBINER); + i=0, index=0; + do { + a = (alpha_cmb_list[index].key >> 20) & 0xFF; + for (; i<=a; i++) + ac_lookup[i] = index; + + while (index < size) + { + b = (alpha_cmb_list[index].key >> 20) & 0xFF; + if (b != a) break; + index ++; + } + } while (index < size); + for (; i<257; i++) ac_lookup[i] = index; + + //color_cmb_list_count = sizeof(color_cmb_list) >> 3; // #bytes/4/2 + //alpha_cmb_list_count = sizeof(alpha_cmb_list) >> 3; +} + +//**************************************************************** +// Main Combine +//**************************************************************** + +void Combine () +{ + FRDP (" | |- color combine: %08lx, #1: (%s-%s)*%s+%s, #2: (%s-%s)*%s+%s\n", + ((rdp.cycle1 & 0xFFFF) << 16) | (rdp.cycle2 & 0xFFFF), + Mode0[rdp.cycle1&0xF], Mode1[(rdp.cycle1>>4)&0xF], Mode2[(rdp.cycle1>>8)&0x1F], Mode3[(rdp.cycle1>>13)&7], + Mode0[rdp.cycle2&0xF], Mode1[(rdp.cycle2>>4)&0xF], Mode2[(rdp.cycle2>>8)&0x1F], Mode3[(rdp.cycle2>>13)&7]); + FRDP (" | |- alpha combine: %08lx, #1: (%s-%s)*%s+%s, #2: (%s-%s)*%s+%s\n", + (rdp.cycle1 & 0x0FFF0000) | ((rdp.cycle2 & 0x0FFF0000) >> 16), + Alpha0[(rdp.cycle1>>16)&7], Alpha1[(rdp.cycle1>>19)&7], Alpha2[(rdp.cycle1>>22)&7], Alpha3[(rdp.cycle1>>25)&7], + Alpha0[(rdp.cycle2>>16)&7], Alpha1[(rdp.cycle2>>19)&7], Alpha2[(rdp.cycle2>>22)&7], Alpha3[(rdp.cycle2>>25)&7]); + if (!rdp.LOD_en || rdp.cur_tile == rdp.mipmap_level) + lod_frac = rdp.prim_lodfrac; + else if (settings.lodmode == 0) + lod_frac = 0; + else + lod_frac = 10; + + rdp.noise = RDP::noise_none; + + wxUint32 found = TRUE; + + rdp.col[0] = rdp.col[1] = rdp.col[2] = rdp.col[3] = + rdp.coladd[0] = rdp.coladd[1] = rdp.coladd[2] = rdp.coladd[3] = 1.0f; + rdp.cmb_flags = rdp.cmb_flags_2 = 0; + + rdp.uncombined = 0; + + cmb.tex = 0; + cmb.tmu0_func = cmb.tmu1_func = cmb.tmu0_a_func = cmb.tmu1_a_func = GR_COMBINE_FUNCTION_ZERO; + cmb.tmu0_fac = cmb.tmu1_fac = cmb.tmu0_a_fac = cmb.tmu1_a_fac = GR_COMBINE_FACTOR_NONE; + cmb.tmu0_invert = cmb.tmu0_a_invert = cmb.tmu1_invert = cmb.tmu1_a_invert = FXFALSE; + + cmb.dc0_detailmax = cmb.dc1_detailmax = 0; + + cmb.mod_0 = cmb.mod_1 = 0; // remove all modifications + cmb.modcolor_0 = cmb.modcolor1_0 = cmb.modcolor2_0 = cmb.modcolor_1 = cmb.modcolor1_1 = cmb.modcolor2_1 + = cmb.modfactor_0 = cmb.modfactor_1 = 0; + + cmb.ccolor = cmb.tex_ccolor = 0; + if (cmb.cmb_ext_use || cmb.tex_cmb_ext_use) + { + //have to draw something to allow use of standard combine functions + if (fullscreen) + { + VERTEX v; + memset(&v,0,sizeof(v)); + grDrawPoint(&v); + } + cmb.cmb_ext_use = 0; + cmb.tex_cmb_ext_use = 0; + } + + wxUint32 cmb_mode_c = (rdp.cycle1 << 16) | (rdp.cycle2 & 0xFFFF); + wxUint32 cmb_mode_a = (rdp.cycle1 & 0x0FFF0000) | ((rdp.cycle2 >> 16) & 0x00000FFF); + + cmb.abf1 = GR_BLEND_SRC_ALPHA; + cmb.abf2 = GR_BLEND_ONE_MINUS_SRC_ALPHA; + +#ifdef FASTSEARCH + // Fast, ordered search + int current=0x7FFFFFFF, last; + wxUint32 actual_combine, current_combine, color_combine, alpha_combine; + int left, right; + + actual_combine = cmb_mode_c; + color_combine = actual_combine; + if ((rdp.cycle2 & 0xFFFF) == 0x1FFF) + actual_combine = (rdp.cycle1 << 16) | (rdp.cycle1 & 0xFFFF); + + left = cc_lookup[actual_combine>>24]; + right = cc_lookup[(actual_combine>>24)+1]; + + while (1) + { + last = current; + current = left + ((right-left) >> 1); + if (current == last) + break; // can't be found! + + current_combine = color_cmb_list[current].key; + if (current_combine < actual_combine) + left = current; + else if (current_combine > actual_combine) + right = current; + else + break; // found it! + } + + // Check if we didn't find it + if (actual_combine != current_combine) + { + rdp.uncombined |= 1; +#ifdef UNIMP_LOG + if (settings.log_unk) + { + sprintf (out_buf, "COLOR combine not found: %08x, #1: (%s-%s)*%s+%s, #2: (%s-%s)*%s+%s\n", + actual_combine, + Mode0[rdp.cycle1&0xF], Mode1[(rdp.cycle1>>4)&0xF], Mode2[(rdp.cycle1>>8)&0x1F], Mode3[(rdp.cycle1>>13)&7], + Mode0[rdp.cycle2&0xF], Mode1[(rdp.cycle2>>4)&0xF], Mode2[(rdp.cycle2>>8)&0x1F], Mode3[(rdp.cycle2>>13)&7]); + UNIMPMODE(); + } +#endif + found = FALSE; + //tex |= 3; + + // use t0 as default + cc_t0 (); + } + else + color_cmb_list[current].func(); + + LRDP(" | |- Color done\n"); + + // Now again for alpha + current = 0x7FFFFFFF; + actual_combine = cmb_mode_a; + alpha_combine = actual_combine; + if ((rdp.cycle2 & 0x0FFF0000) == 0x01FF0000) + actual_combine = (rdp.cycle1 & 0x0FFF0000) | ((rdp.cycle1 >> 16) & 0x00000FFF); + if ((rdp.cycle1 & 0x0FFF0000) == 0x0FFF0000) + actual_combine = (rdp.cycle2 & 0x0FFF0000) | ((rdp.cycle2 >> 16) & 0x00000FFF); + + left = ac_lookup[(actual_combine>>20)&0xFF]; + right = ac_lookup[((actual_combine>>20)&0xFF)+1]; + + while (1) + { + last = current; + current = left + ((right-left) >> 1); + if (current == last) + break; // can't be found! + + current_combine = alpha_cmb_list[current].key; + if (current_combine < actual_combine) + left = current; + else if (current_combine > actual_combine) + right = current; + else + break; // found it! + } + + // Check if we didn't find it + if (actual_combine != current_combine || !found) + { + if (actual_combine != current_combine) + { + rdp.uncombined |= 2; +#ifdef UNIMP_LOG + if (settings.log_unk) + { + sprintf (out_buf, "ALPHA combine not found: %08x, #1: (%s-%s)*%s+%s, #2: (%s-%s)*%s+%s\n", + actual_combine, + Alpha0[(rdp.cycle1>>16)&7], Alpha1[(rdp.cycle1>>19)&7], Alpha2[(rdp.cycle1>>22)&7], Alpha3[(rdp.cycle1>>25)&7], + Alpha0[(rdp.cycle2>>16)&7], Alpha1[(rdp.cycle2>>19)&7], Alpha2[(rdp.cycle2>>22)&7], Alpha3[(rdp.cycle2>>25)&7]); + UNIMPMODE(); + } +#endif + } + if (settings.unk_as_red) + { + BrightRed (); + } + else + { + // use full alpha as default + ac_t0 (); + } + //tex |= 3; + } + else + alpha_cmb_list[current].func(); + + + if (color_combine == 0x69351fff) //text, PD, need to change texture alpha + { + A_USE_T1(); + } + else if ((color_combine == 0x3fff1fff) && (alpha_combine == 0x03ff03ff) && (rdp.last_tile > rdp.cur_tile))//Dr. Mario + { + cc_t0(); + ac_t1(); + } + else if (color_combine == 0x613522f0 && (settings.hacks&hack_PMario)) //Paper Mario fortune teller spheres + { + ac_t0(); + } + + LRDP(" | |- Alpha done\n"); +#endif // FASTSEARCH + + CombineBlender (); + //* + // Update textures? + // if (tex == 2 && rdp.texrecting && (cmb.tmu1_func != GR_COMBINE_FUNCTION_ZERO) && (rdp.last_tile_size == 0)) + if (cmb.tex == 2 && rdp.texrecting && (rdp.cur_tile == rdp.last_tile_size)) + { + cmb.tex = 0; + USE_T0(); + A_USE_T0(); + } + //*/ + rdp.tex = cmb.tex; + + if (fullscreen) + { + TBUFF_COLOR_IMAGE * aTBuff[2] = {0, 0}; + if (rdp.aTBuffTex[0]) + aTBuff[rdp.aTBuffTex[0]->tile] = rdp.aTBuffTex[0]; + if (rdp.aTBuffTex[1]) + aTBuff[rdp.aTBuffTex[1]->tile] = rdp.aTBuffTex[1]; + if (cmb.tex && (aTBuff[0] || aTBuff[1])) + { + if (aTBuff[0] && (settings.frame_buffer&fb_read_alpha)) + { + if ((settings.hacks&hack_PMario) && aTBuff[0]->width == rdp.ci_width) + ; + else + { + grChromakeyValue(0); + grChromakeyMode(GR_CHROMAKEY_ENABLE); + } + } + else + grChromakeyMode(GR_CHROMAKEY_DISABLE); + + if (aTBuff[0] && aTBuff[0]->info.format == GR_TEXFMT_ALPHA_INTENSITY_88) + { + if (cmb.tex_cmb_ext_use & TEX_COMBINE_EXT_COLOR) + { + if (cmb.t0c_ext_a == GR_CMBX_LOCAL_TEXTURE_RGB) + cmb.t0c_ext_a = GR_CMBX_LOCAL_TEXTURE_ALPHA; + if (cmb.t0c_ext_b == GR_CMBX_LOCAL_TEXTURE_RGB) + cmb.t0c_ext_b = GR_CMBX_LOCAL_TEXTURE_ALPHA; + if (cmb.t0c_ext_c == GR_CMBX_LOCAL_TEXTURE_RGB) + cmb.t0c_ext_c = GR_CMBX_LOCAL_TEXTURE_ALPHA; + } + else + cmb.tmu0_func = GR_COMBINE_FUNCTION_LOCAL_ALPHA; + } + + if (aTBuff[1] && aTBuff[1]->info.format == GR_TEXFMT_ALPHA_INTENSITY_88) + { + if (cmb.tex_cmb_ext_use & TEX_COMBINE_EXT_COLOR) + { + if (cmb.t1c_ext_a == GR_CMBX_LOCAL_TEXTURE_RGB) + cmb.t1c_ext_a = GR_CMBX_LOCAL_TEXTURE_ALPHA; + if (cmb.t1c_ext_b == GR_CMBX_LOCAL_TEXTURE_RGB) + cmb.t1c_ext_b = GR_CMBX_LOCAL_TEXTURE_ALPHA; + if (cmb.t1c_ext_c == GR_CMBX_LOCAL_TEXTURE_RGB) + cmb.t1c_ext_c = GR_CMBX_LOCAL_TEXTURE_ALPHA; + } + else + cmb.tmu1_func = GR_COMBINE_FUNCTION_LOCAL_ALPHA; + } + } + else + grChromakeyMode(GR_CHROMAKEY_DISABLE); + } + cmb.shade_mod_hash = (rdp.cmb_flags + rdp.cmb_flags_2) * (rdp.prim_color + rdp.env_color + rdp.K5); + + LRDP(" | + Combine end\n"); +} + +void CombineBlender () +{ + wxUint32 blendmode = rdp.othermode_l >> 16; + // Check force-blending + if ((rdp.othermode_l & 0x4000) && (rdp.cycle_mode < 2)) + { + switch (blendmode) + { + // Mace objects + case 0x0382: + case 0x0091: + // 1080 sky + case 0x0c08: + // Mario kart player select + // clr_in * 0 + clr_in * 1 + // - or just clr_in, no matter what alpha + case 0x0f0a: + //DK64 blue prints + case 0x0302: + //Sin and Punishment + case 0xcb02: + // Battlezone + // clr_in * a + clr_in * (1-a) + case 0xc800: + case 0x00c0: + //ISS64 + case 0xc302: + A_BLEND (GR_BLEND_ONE, GR_BLEND_ZERO); + break; + + //Space Invaders + case 0x0448: + case 0x055a: + A_BLEND (GR_BLEND_ONE, GR_BLEND_ONE); + break; + + // LOT in Zelda: MM + case 0xaf50: + case 0x0f5a: //clr_in * 0 + clr_mem * 1 + A_BLEND (GR_BLEND_ZERO, GR_BLEND_ONE); + break; + + case 0x5f50: //clr_mem * 0 + clr_mem * (1-a) + A_BLEND (GR_BLEND_ZERO, GR_BLEND_ONE_MINUS_SRC_ALPHA); + break; + + /* + case 0xc410: // Perfect Dark Mauler + { + MOD_0 (TMOD_TEX_INTER_COLOR_USING_FACTOR); + MOD_0_COL (rdp.fog_color & 0xFFFFFF00); + MOD_0_FAC (rdp.fog_color & 0xFF); + INTERSHADE_2 (rdp.fog_color & 0xFFFFFF00, rdp.fog_color & 0xFF); + + float percent = (rdp.fog_color & 0xFF) / 255.0f; + cmb.ccolor = + ((wxUint32)(((cmb.ccolor >> 24) & 0xFF) * (1.0f-percent) + ((rdp.fog_color>>24) & 0xFF) * percent) << 24) | + ((wxUint32)(((cmb.ccolor >> 16) & 0xFF) * (1.0f-percent) + ((rdp.fog_color>>16) & 0xFF) * percent) << 16) | + ((wxUint32)(((cmb.ccolor >> 8) & 0xFF) * (1.0f-percent) + ((rdp.fog_color>>8) & 0xFF) * percent) << 8) | + (cmb.ccolor & 0xFF); + + rdp.col[0] = rdp.col[0] * (1.0f-percent) + ((rdp.fog_color>>24) & 0xFF) / 255.0f * percent; + rdp.col[1] = rdp.col[1] * (1.0f-percent) + ((rdp.fog_color>>16) & 0xFF) / 255.0f * percent; + rdp.col[2] = rdp.col[2] * (1.0f-percent) + ((rdp.fog_color>>8) & 0xFF) / 255.0f * percent; + A_BLEND (GR_BLEND_SRC_ALPHA, GR_BLEND_ONE_MINUS_SRC_ALPHA); + } + break; + */ + case 0xf550: //clr_fog * a_fog + clr_mem * (1-a) + A_BLEND (GR_BLEND_SRC_ALPHA, GR_BLEND_ONE_MINUS_SRC_ALPHA); + { + wxUint32 prim = rdp.prim_color; + rdp.prim_color = rdp.fog_color; + cc_prim(); + ac_prim(); + rdp.prim_color = prim; + } + break; + + case 0x0150: //spiderman + case 0x0d18: //clr_in * a_fog + clr_mem * (1-a) + A_BLEND (GR_BLEND_SRC_ALPHA, GR_BLEND_ONE_MINUS_SRC_ALPHA); + if (rdp.cycle_mode == 1 && rdp.cycle2 != 0x01ff1fff) + { + wxUint32 prim = rdp.prim_color; + rdp.prim_color = rdp.fog_color; + ac_prim(); + rdp.prim_color = prim; + } + break; + + case 0xc912: //40 winks, clr_in * a_fog + clr_mem * 1 + { + wxUint32 prim = rdp.prim_color; + rdp.prim_color = rdp.fog_color; + ac_prim(); + rdp.prim_color = prim; + } + A_BLEND (GR_BLEND_SRC_ALPHA, GR_BLEND_ONE); + break; + + default: + A_BLEND (GR_BLEND_SRC_ALPHA, GR_BLEND_ONE_MINUS_SRC_ALPHA); + } + } + /* + else if (blendmode == 0xc411) // Super Smash Bros, faked fog for flashing characters + { + MOD_0 (TMOD_TEX_INTER_COLOR_USING_FACTOR); + MOD_0_COL (rdp.fog_color & 0xFFFFFF00); + MOD_0_FAC (rdp.fog_color & 0xFF); + INTERSHADE_2 (rdp.fog_color & 0xFFFFFF00, rdp.fog_color & 0xFF); + + float percent = (rdp.fog_color & 0xFF) / 255.0f; + cmb.ccolor = + ((wxUint32)(((cmb.ccolor >> 24) & 0xFF) * (1.0f-percent) + ((rdp.fog_color>>24) & 0xFF) * percent) << 24) | + ((wxUint32)(((cmb.ccolor >> 16) & 0xFF) * (1.0f-percent) + ((rdp.fog_color>>16) & 0xFF) * percent) << 16) | + ((wxUint32)(((cmb.ccolor >> 8) & 0xFF) * (1.0f-percent) + ((rdp.fog_color>>8) & 0xFF) * percent) << 8) | + (cmb.ccolor & 0xFF); + + rdp.col[0] = rdp.col[0] * (1.0f-percent) + ((rdp.fog_color>>24) & 0xFF) / 255.0f * percent; + rdp.col[1] = rdp.col[1] * (1.0f-percent) + ((rdp.fog_color>>16) & 0xFF) / 255.0f * percent; + rdp.col[2] = rdp.col[2] * (1.0f-percent) + ((rdp.fog_color>>8) & 0xFF) / 255.0f * percent; + A_BLEND (GR_BLEND_ONE, GR_BLEND_ZERO); + } + */ + else if (blendmode == 0x0040) // Mia Soccer Lights + A_BLEND (GR_BLEND_SRC_ALPHA, GR_BLEND_ONE_MINUS_SRC_ALPHA); + else if ((settings.hacks&hack_Pilotwings) && (rdp.othermode_l & 0x80)) //CLR_ON_CVG without FORCE_BL + A_BLEND (GR_BLEND_ZERO, GR_BLEND_ONE); + else + A_BLEND (GR_BLEND_ONE, GR_BLEND_ZERO); + + // ALPHA_CVG_SEL means full alpha + // The reason it wasn't working before was because I wasn't handling rdp:setothermode + // if (rdp.othermode_l & 0x2000) + if ((rdp.othermode_l & 0x2000) && ((rdp.othermode_l & 0x7000) != 0x7000)) + { + if ((settings.hacks&hack_PMario) && (blendmode == 0x5055)) + { + A_BLEND (GR_BLEND_ZERO, GR_BLEND_ONE); + } + else if (blendmode == 0x4055) // Mario Golf + { + A_BLEND (GR_BLEND_ZERO, GR_BLEND_ONE); + } + else + { + A_BLEND (GR_BLEND_ONE, GR_BLEND_ZERO); + } + } + + //hack + //* + if (settings.hacks&hack_ISS64) + { + if (rdp.othermode_l == 0xff5a6379) + { + A_BLEND (GR_BLEND_ZERO, GR_BLEND_SRC_ALPHA); + } + else if (rdp.othermode_l == 0x00504dd9) //players shadows. CVG_DST_WRAP + { + A_BLEND (GR_BLEND_ZERO, GR_BLEND_ONE); + } + } + else if (settings.hacks&hack_TGR) + { + if (rdp.othermode_l == 0x0f0a0235) + { + A_BLEND (GR_BLEND_SRC_ALPHA, GR_BLEND_ONE_MINUS_SRC_ALPHA); + } + } + //*/ +} + +void InitCombine () +{ + LOG ("InitCombine() "); + memset(&cmb, 0, sizeof(cmb)); + const char *extensions = grGetString (GR_EXTENSION); + if (const char * extstr = strstr(extensions, "COMBINE")) { + if (!strncmp(extstr, "COMBINE", 7)) { + LOG ("extensions "); + char strColorCombineExt[] = "grColorCombineExt"; + cmb.grColorCombineExt = (GRCOLORCOMBINEEXT) grGetProcAddress(strColorCombineExt); + char strAlphaCombineExt[] = "grAlphaCombineExt"; + cmb.grAlphaCombineExt = (GRCOLORCOMBINEEXT) grGetProcAddress(strAlphaCombineExt); + char strTexColorCombineExt[] = "grTexColorCombineExt"; + cmb.grTexColorCombineExt = (GRTEXCOLORCOMBINEEXT) grGetProcAddress(strTexColorCombineExt); + char strTexAlphaCombineExt[] = "grTexAlphaCombineExt"; + cmb.grTexAlphaCombineExt = (GRTEXCOLORCOMBINEEXT) grGetProcAddress(strTexAlphaCombineExt); + char strConstantColorValueExt[] = "grConstantColorValueExt"; + cmb.grConstantColorValueExt = (GRCONSTANTCOLORVALUEEXT) grGetProcAddress(strConstantColorValueExt); + if (cmb.grColorCombineExt && cmb.grAlphaCombineExt && + cmb.grTexColorCombineExt && cmb.grTexAlphaCombineExt) + { + cmb.combine_ext = TRUE; + LOG ("initialized."); + } + else + { + cmb.combine_ext = FALSE; + } + } + } + cmb.dc0_lodbias = cmb.dc1_lodbias = 31; + cmb.dc0_detailscale = cmb.dc1_detailscale = 7; + cmb.lodbias0 = cmb.lodbias1 = 1.0f; + LOG ("\n"); +} + +void ColorCombinerToExtension () +{ + wxUint32 ext_local, ext_local_a, ext_other, ext_other_a; + switch (cmb.c_loc) + { + case GR_COMBINE_LOCAL_ITERATED: + ext_local = GR_CMBX_ITRGB; + ext_local_a = GR_CMBX_ITALPHA; + break; + case GR_COMBINE_LOCAL_CONSTANT: + ext_local = GR_CMBX_CONSTANT_COLOR; + ext_local_a = GR_CMBX_CONSTANT_ALPHA; + break; + }; + switch (cmb.c_oth) + { + case GR_COMBINE_OTHER_ITERATED: + ext_other = GR_CMBX_ITRGB; + ext_other_a = GR_CMBX_ITALPHA; + break; + case GR_COMBINE_OTHER_TEXTURE: + ext_other = GR_CMBX_TEXTURE_RGB; + ext_other_a = GR_CMBX_TEXTURE_ALPHA; + break; + case GR_COMBINE_OTHER_CONSTANT: + ext_other = GR_CMBX_CONSTANT_COLOR; + ext_other_a = GR_CMBX_CONSTANT_ALPHA; + break; + }; + switch (cmb.c_fac) + { + case GR_COMBINE_FACTOR_ZERO: + cmb.c_ext_c = GR_CMBX_ZERO; + cmb.c_ext_c_invert = 0; + break; + case GR_COMBINE_FACTOR_ONE: + cmb.c_ext_c = GR_CMBX_ZERO; + cmb.c_ext_c_invert = 1; + break; + case GR_COMBINE_FACTOR_LOCAL: + cmb.c_ext_c = ext_local; + cmb.c_ext_c_invert = 0; + break; + case GR_COMBINE_FACTOR_LOCAL_ALPHA: + cmb.c_ext_c = ext_local_a; + cmb.c_ext_c_invert = 0; + break; + case GR_COMBINE_FACTOR_OTHER_ALPHA: + cmb.c_ext_c = ext_other_a; + cmb.c_ext_c_invert = 0; + break; + case GR_COMBINE_FACTOR_TEXTURE_RGB: + cmb.c_ext_c = GR_CMBX_TEXTURE_RGB; + cmb.c_ext_c_invert = 0; + break; + case GR_COMBINE_FACTOR_TEXTURE_ALPHA: + cmb.c_ext_c = GR_CMBX_TEXTURE_ALPHA; + cmb.c_ext_c_invert = 0; + break; + case GR_COMBINE_FACTOR_ONE_MINUS_LOCAL: + cmb.c_ext_c = ext_local; + cmb.c_ext_c_invert = 1; + break; + case GR_COMBINE_FACTOR_ONE_MINUS_LOCAL_ALPHA: + cmb.c_ext_c = ext_local_a; + cmb.c_ext_c_invert = 1; + break; + case GR_COMBINE_FACTOR_ONE_MINUS_OTHER_ALPHA: + cmb.c_ext_c = ext_other_a; + cmb.c_ext_c_invert = 1; + break; + case GR_COMBINE_FACTOR_ONE_MINUS_TEXTURE_ALPHA: + cmb.c_ext_c = GR_CMBX_TEXTURE_ALPHA; + cmb.c_ext_c_invert = 1; + break; + } + + switch (cmb.c_fnc) + { + case GR_COMBINE_FUNCTION_ZERO: + cmb.c_ext_a = GR_CMBX_ZERO; + cmb.c_ext_a_mode = GR_FUNC_MODE_X; + cmb.c_ext_b = GR_CMBX_ZERO; + cmb.c_ext_b_mode = GR_FUNC_MODE_X; + cmb.c_ext_c = GR_CMBX_ZERO; + cmb.c_ext_c_invert = 0; + cmb.c_ext_d = GR_CMBX_ZERO; + cmb.c_ext_d_invert = 0; + break; + case GR_COMBINE_FUNCTION_LOCAL: + cmb.c_ext_a = ext_local; + cmb.c_ext_a_mode = GR_FUNC_MODE_X; + cmb.c_ext_b = GR_CMBX_ZERO; + cmb.c_ext_b_mode = GR_FUNC_MODE_X; + cmb.c_ext_c = GR_CMBX_ZERO; + cmb.c_ext_c_invert = 1; + cmb.c_ext_d = GR_CMBX_ZERO; + cmb.c_ext_d_invert = 0; + break; + case GR_COMBINE_FUNCTION_LOCAL_ALPHA: + cmb.c_ext_a = ext_local_a; + cmb.c_ext_a_mode = GR_FUNC_MODE_X; + cmb.c_ext_b = GR_CMBX_ZERO; + cmb.c_ext_b_mode = GR_FUNC_MODE_X; + cmb.c_ext_c = GR_CMBX_ZERO; + cmb.c_ext_c_invert = 1; + cmb.c_ext_d = GR_CMBX_ZERO; + cmb.c_ext_d_invert = 0; + break; + case GR_COMBINE_FUNCTION_SCALE_OTHER: + cmb.c_ext_a = ext_other; + cmb.c_ext_a_mode = GR_FUNC_MODE_X; + cmb.c_ext_b = GR_CMBX_ZERO; + cmb.c_ext_b_mode = GR_FUNC_MODE_ZERO; + cmb.c_ext_d = GR_CMBX_ZERO; + cmb.c_ext_d_invert = 0; + break; + case GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL: + cmb.c_ext_a = ext_other; + cmb.c_ext_a_mode = GR_FUNC_MODE_X; + cmb.c_ext_b = ext_local; + cmb.c_ext_b_mode = GR_FUNC_MODE_ZERO; + cmb.c_ext_d = GR_CMBX_B; + cmb.c_ext_d_invert = 0; + break; + case GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL_ALPHA: + cmb.c_ext_a = ext_other; + cmb.c_ext_a_mode = GR_FUNC_MODE_X; + cmb.c_ext_b = ext_local_a; + cmb.c_ext_b_mode = GR_FUNC_MODE_ZERO; + cmb.c_ext_d = GR_CMBX_B; + cmb.c_ext_d_invert = 0; + break; + case GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL: + cmb.c_ext_a = ext_other; + cmb.c_ext_a_mode = GR_FUNC_MODE_X; + cmb.c_ext_b = ext_local; + cmb.c_ext_b_mode = GR_FUNC_MODE_NEGATIVE_X; + cmb.c_ext_d = GR_CMBX_ZERO; + cmb.c_ext_d_invert = 0; + break; + case GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL: + cmb.c_ext_a = ext_other; + cmb.c_ext_a_mode = GR_FUNC_MODE_X; + cmb.c_ext_b = ext_local; + cmb.c_ext_b_mode = GR_FUNC_MODE_NEGATIVE_X; + cmb.c_ext_d = GR_CMBX_B; + cmb.c_ext_d_invert = 0; + break; + case GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL_ALPHA: + cmb.c_ext_a = ext_other; + cmb.c_ext_a_mode = GR_FUNC_MODE_X; + cmb.c_ext_b = ext_local; + cmb.c_ext_b_mode = GR_FUNC_MODE_NEGATIVE_X; + cmb.c_ext_d = GR_CMBX_ALOCAL; + cmb.c_ext_d_invert = 0; + break; + case GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL: + cmb.c_ext_a = GR_CMBX_ZERO; + cmb.c_ext_a_mode = GR_FUNC_MODE_ZERO; + cmb.c_ext_b = ext_local; + cmb.c_ext_b_mode = GR_FUNC_MODE_NEGATIVE_X; + cmb.c_ext_d = GR_CMBX_B; + cmb.c_ext_d_invert = 0; + break; + case GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL_ALPHA: + cmb.c_ext_a = GR_CMBX_ZERO; + cmb.c_ext_a_mode = GR_FUNC_MODE_ZERO; + cmb.c_ext_b = ext_local; + cmb.c_ext_b_mode = GR_FUNC_MODE_NEGATIVE_X; + cmb.c_ext_d = GR_CMBX_ALOCAL; + cmb.c_ext_d_invert = 0; + break; + } +} + +void AlphaCombinerToExtension () +{ + wxUint32 ext_local, ext_other; + switch (cmb.a_loc) + { + case GR_COMBINE_LOCAL_ITERATED: + ext_local = GR_CMBX_ITALPHA; + break; + case GR_COMBINE_LOCAL_CONSTANT: + ext_local = GR_CMBX_CONSTANT_ALPHA; + break; + default: + ext_local = GR_CMBX_ZERO; + }; + switch (cmb.a_oth) + { + case GR_COMBINE_OTHER_ITERATED: + ext_other = GR_CMBX_ITALPHA; + break; + case GR_COMBINE_OTHER_TEXTURE: + ext_other = GR_CMBX_TEXTURE_ALPHA; + break; + case GR_COMBINE_OTHER_CONSTANT: + ext_other = GR_CMBX_CONSTANT_ALPHA; + break; + default: + ext_other = GR_CMBX_ZERO; + }; + switch (cmb.a_fac) + { + case GR_COMBINE_FACTOR_ZERO: + cmb.a_ext_c = GR_CMBX_ZERO; + cmb.a_ext_c_invert = 0; + break; + case GR_COMBINE_FACTOR_ONE: + cmb.a_ext_c = GR_CMBX_ZERO; + cmb.a_ext_c_invert = 1; + break; + case GR_COMBINE_FACTOR_LOCAL: + case GR_COMBINE_FACTOR_LOCAL_ALPHA: + cmb.a_ext_c = ext_local; + cmb.a_ext_c_invert = 0; + break; + case GR_COMBINE_FACTOR_OTHER_ALPHA: + cmb.a_ext_c = ext_other; + cmb.a_ext_c_invert = 0; + break; + case GR_COMBINE_FACTOR_TEXTURE_ALPHA: + cmb.a_ext_c = GR_CMBX_TEXTURE_ALPHA; + cmb.a_ext_c_invert = 0; + break; + case GR_COMBINE_FACTOR_ONE_MINUS_LOCAL: + case GR_COMBINE_FACTOR_ONE_MINUS_LOCAL_ALPHA: + cmb.a_ext_c = ext_local; + cmb.a_ext_c_invert = 1; + break; + case GR_COMBINE_FACTOR_ONE_MINUS_OTHER_ALPHA: + cmb.a_ext_c = ext_other; + cmb.a_ext_c_invert = 1; + break; + case GR_COMBINE_FACTOR_ONE_MINUS_TEXTURE_ALPHA: + cmb.a_ext_c = GR_CMBX_TEXTURE_ALPHA; + cmb.a_ext_c_invert = 1; + break; + default: + cmb.a_ext_c = GR_CMBX_ZERO; + cmb.a_ext_c_invert = 0; + } + + switch (cmb.a_fnc) + { + case GR_COMBINE_FUNCTION_ZERO: + cmb.a_ext_a = GR_CMBX_ZERO; + cmb.a_ext_a_mode = GR_FUNC_MODE_X; + cmb.a_ext_b = GR_CMBX_ZERO; + cmb.a_ext_b_mode = GR_FUNC_MODE_X; + cmb.a_ext_c = GR_CMBX_ZERO; + cmb.a_ext_c_invert = 0; + cmb.a_ext_d = GR_CMBX_ZERO; + cmb.a_ext_d_invert = 0; + break; + case GR_COMBINE_FUNCTION_LOCAL: + case GR_COMBINE_FUNCTION_LOCAL_ALPHA: + cmb.a_ext_a = GR_CMBX_ZERO; + cmb.a_ext_a_mode = GR_FUNC_MODE_ZERO; + cmb.a_ext_b = ext_local; + cmb.a_ext_b_mode = GR_FUNC_MODE_X; + cmb.a_ext_c = GR_CMBX_ZERO; + cmb.a_ext_c_invert = 1; + cmb.a_ext_d = GR_CMBX_ZERO; + cmb.a_ext_d_invert = 0; + break; + case GR_COMBINE_FUNCTION_SCALE_OTHER: + cmb.a_ext_a = ext_other; + cmb.a_ext_a_mode = GR_FUNC_MODE_X; + cmb.a_ext_b = GR_CMBX_ZERO; + cmb.a_ext_b_mode = GR_FUNC_MODE_ZERO; + cmb.a_ext_d = GR_CMBX_ZERO; + cmb.a_ext_d_invert = 0; + break; + case GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL: + case GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL_ALPHA: + cmb.a_ext_a = ext_other; + cmb.a_ext_a_mode = GR_FUNC_MODE_X; + cmb.a_ext_b = ext_local; + cmb.a_ext_b_mode = GR_FUNC_MODE_ZERO; + cmb.a_ext_d = GR_CMBX_B; + cmb.a_ext_d_invert = 0; + break; + case GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL: + cmb.a_ext_a = ext_other; + cmb.a_ext_a_mode = GR_FUNC_MODE_X; + cmb.a_ext_b = ext_local; + cmb.a_ext_b_mode = GR_FUNC_MODE_NEGATIVE_X; + cmb.a_ext_d = GR_CMBX_ZERO; + cmb.a_ext_d_invert = 0; + break; + case GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL: + case GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL_ALPHA: + cmb.a_ext_a = ext_other; + cmb.a_ext_a_mode = GR_FUNC_MODE_X; + cmb.a_ext_b = ext_local; + cmb.a_ext_b_mode = GR_FUNC_MODE_NEGATIVE_X; + cmb.a_ext_d = GR_CMBX_B; + cmb.a_ext_d_invert = 0; + break; + case GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL: + case GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL_ALPHA: + cmb.a_ext_a = GR_CMBX_ZERO; + cmb.a_ext_a_mode = GR_FUNC_MODE_ZERO; + cmb.a_ext_b = ext_local; + cmb.a_ext_b_mode = GR_FUNC_MODE_NEGATIVE_X; + cmb.a_ext_d = GR_CMBX_B; + cmb.a_ext_d_invert = 0; + break; + } +} + +void TexColorCombinerToExtension (GrChipID_t tmu) +{ + wxUint32 tc_ext_a, tc_ext_a_mode, tc_ext_b, tc_ext_b_mode, tc_ext_c, tc_ext_d; + int tc_ext_c_invert, tc_ext_d_invert; + wxUint32 tmu_func, tmu_fac; + + if (tmu == GR_TMU0) + { + tmu_func = cmb.tmu0_func; + tmu_fac = cmb.tmu0_fac; + } + else + { + tmu_func = cmb.tmu1_func; + tmu_fac = cmb.tmu1_fac; + } + + switch (tmu_fac) + { + case GR_COMBINE_FACTOR_ZERO: + tc_ext_c = GR_CMBX_ZERO; + tc_ext_c_invert = 0; + break; + case GR_COMBINE_FACTOR_LOCAL: + tc_ext_c = GR_CMBX_LOCAL_TEXTURE_RGB; + tc_ext_c_invert = 0; + break; + case GR_COMBINE_FACTOR_LOCAL_ALPHA: + tc_ext_c = GR_CMBX_LOCAL_TEXTURE_ALPHA; + tc_ext_c_invert = 0; + break; + case GR_COMBINE_FACTOR_OTHER_ALPHA: + tc_ext_c = GR_CMBX_OTHER_TEXTURE_ALPHA; + tc_ext_c_invert = 0; + break; + case GR_COMBINE_FACTOR_DETAIL_FACTOR: + tc_ext_c = GR_CMBX_DETAIL_FACTOR; + tc_ext_c_invert = 0; + break; + case GR_COMBINE_FACTOR_ONE: + tc_ext_c = GR_CMBX_ZERO; + tc_ext_c_invert = 1; + break; + case GR_COMBINE_FACTOR_ONE_MINUS_LOCAL: + tc_ext_c = GR_CMBX_LOCAL_TEXTURE_RGB; + tc_ext_c_invert = 1; + break; + case GR_COMBINE_FACTOR_ONE_MINUS_LOCAL_ALPHA: + tc_ext_c = GR_CMBX_LOCAL_TEXTURE_ALPHA; + tc_ext_c_invert = 1; + break; + case GR_COMBINE_FACTOR_ONE_MINUS_OTHER_ALPHA: + tc_ext_c = GR_CMBX_OTHER_TEXTURE_ALPHA; + tc_ext_c_invert = 1; + break; + case GR_COMBINE_FACTOR_ONE_MINUS_DETAIL_FACTOR: + tc_ext_c = GR_CMBX_DETAIL_FACTOR; + tc_ext_c_invert = 1; + break; + } + + switch (tmu_func) + { + case GR_COMBINE_FUNCTION_ZERO: + tc_ext_a = GR_CMBX_LOCAL_TEXTURE_RGB; + tc_ext_a_mode = GR_FUNC_MODE_ZERO; + tc_ext_b = GR_CMBX_LOCAL_TEXTURE_RGB; + tc_ext_b_mode = GR_FUNC_MODE_ZERO; + tc_ext_c = GR_CMBX_ZERO; + tc_ext_c_invert = 0; + tc_ext_d = GR_CMBX_ZERO; + tc_ext_d_invert = 0; + break; + case GR_COMBINE_FUNCTION_LOCAL: + tc_ext_a = GR_CMBX_LOCAL_TEXTURE_RGB; + tc_ext_a_mode = GR_FUNC_MODE_X; + tc_ext_b = GR_CMBX_LOCAL_TEXTURE_RGB; + tc_ext_b_mode = GR_FUNC_MODE_ZERO; + tc_ext_c = GR_CMBX_ZERO; + tc_ext_c_invert = 1; + tc_ext_d = GR_CMBX_ZERO; + tc_ext_d_invert = 0; + break; + case GR_COMBINE_FUNCTION_LOCAL_ALPHA: + tc_ext_a = GR_CMBX_LOCAL_TEXTURE_ALPHA; + tc_ext_a_mode = GR_FUNC_MODE_X; + tc_ext_b = GR_CMBX_LOCAL_TEXTURE_RGB; + tc_ext_b_mode = GR_FUNC_MODE_ZERO; + tc_ext_c = GR_CMBX_ZERO; + tc_ext_c_invert = 1; + tc_ext_d = GR_CMBX_ZERO; + tc_ext_d_invert = 0; + break; + case GR_COMBINE_FUNCTION_SCALE_OTHER: + tc_ext_a = GR_CMBX_OTHER_TEXTURE_RGB; + tc_ext_a_mode = GR_FUNC_MODE_X; + tc_ext_b = GR_CMBX_LOCAL_TEXTURE_RGB; + tc_ext_b_mode = GR_FUNC_MODE_ZERO; + tc_ext_d = GR_CMBX_ZERO; + tc_ext_d_invert = 0; + break; + case GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL: + tc_ext_a = GR_CMBX_OTHER_TEXTURE_RGB; + tc_ext_a_mode = GR_FUNC_MODE_X; + tc_ext_b = GR_CMBX_LOCAL_TEXTURE_RGB; + tc_ext_b_mode = GR_FUNC_MODE_ZERO; + tc_ext_d = GR_CMBX_B; + tc_ext_d_invert = 0; + break; + case GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL_ALPHA: + tc_ext_a = GR_CMBX_OTHER_TEXTURE_RGB; + tc_ext_a_mode = GR_FUNC_MODE_X; + tc_ext_b = GR_CMBX_LOCAL_TEXTURE_ALPHA; + tc_ext_b_mode = GR_FUNC_MODE_ZERO; + tc_ext_d = GR_CMBX_B; + tc_ext_d_invert = 0; + break; + case GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL: + tc_ext_a = GR_CMBX_OTHER_TEXTURE_RGB; + tc_ext_a_mode = GR_FUNC_MODE_X; + tc_ext_b = GR_CMBX_LOCAL_TEXTURE_RGB; + tc_ext_b_mode = GR_FUNC_MODE_NEGATIVE_X; + tc_ext_d = GR_CMBX_ZERO; + tc_ext_d_invert = 0; + break; + case GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL: + tc_ext_a = GR_CMBX_OTHER_TEXTURE_RGB; + tc_ext_a_mode = GR_FUNC_MODE_X; + tc_ext_b = GR_CMBX_LOCAL_TEXTURE_RGB; + tc_ext_b_mode = GR_FUNC_MODE_NEGATIVE_X; + tc_ext_d = GR_CMBX_B; + tc_ext_d_invert = 0; + break; + case GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL_ALPHA: + tc_ext_a = GR_CMBX_OTHER_TEXTURE_RGB; + tc_ext_a_mode = GR_FUNC_MODE_X; + tc_ext_b = GR_CMBX_LOCAL_TEXTURE_RGB; + tc_ext_b_mode = GR_FUNC_MODE_NEGATIVE_X; + tc_ext_d = GR_CMBX_LOCAL_TEXTURE_ALPHA; + tc_ext_d_invert = 0; + break; + case GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL: + tc_ext_a = GR_CMBX_LOCAL_TEXTURE_RGB; + tc_ext_a_mode = GR_FUNC_MODE_ZERO; + tc_ext_b = GR_CMBX_LOCAL_TEXTURE_RGB; + tc_ext_b_mode = GR_FUNC_MODE_NEGATIVE_X; + tc_ext_d = GR_CMBX_B; + tc_ext_d_invert = 0; + break; + case GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL_ALPHA: + tc_ext_a = GR_CMBX_LOCAL_TEXTURE_RGB; + tc_ext_a_mode = GR_FUNC_MODE_ZERO; + tc_ext_b = GR_CMBX_LOCAL_TEXTURE_RGB; + tc_ext_b_mode = GR_FUNC_MODE_NEGATIVE_X; + tc_ext_d = GR_CMBX_LOCAL_TEXTURE_ALPHA; + tc_ext_d_invert = 0; + break; + } + + if (tmu == GR_TMU0) + { + cmb.t0c_ext_a = tc_ext_a; + cmb.t0c_ext_a_mode = tc_ext_a_mode; + cmb.t0c_ext_b = tc_ext_b; + cmb.t0c_ext_b_mode = tc_ext_b_mode; + cmb.t0c_ext_c = tc_ext_c; + cmb.t0c_ext_c_invert = tc_ext_c_invert; + cmb.t0c_ext_d = tc_ext_d; + cmb.t0c_ext_d_invert = tc_ext_d_invert; + } + else + { + cmb.t1c_ext_a = tc_ext_a; + cmb.t1c_ext_a_mode = tc_ext_a_mode; + cmb.t1c_ext_b = tc_ext_b; + cmb.t1c_ext_b_mode = tc_ext_b_mode; + cmb.t1c_ext_c = tc_ext_c; + cmb.t1c_ext_c_invert = tc_ext_c_invert; + cmb.t1c_ext_d = tc_ext_d; + cmb.t1c_ext_d_invert = tc_ext_d_invert; + } +} + +void TexAlphaCombinerToExtension (GrChipID_t tmu) +{ + wxUint32 ta_ext_a, ta_ext_a_mode, ta_ext_b, ta_ext_b_mode, ta_ext_c, ta_ext_d; + int ta_ext_c_invert, ta_ext_d_invert; + wxUint32 tmu_a_func, tmu_a_fac; + + if (tmu == GR_TMU0) + { + tmu_a_func = cmb.tmu0_a_func; + tmu_a_fac = cmb.tmu0_a_fac; + } + else + { + tmu_a_func = cmb.tmu1_a_func; + tmu_a_fac = cmb.tmu1_a_fac; + } + + switch (tmu_a_fac) + { + case GR_COMBINE_FACTOR_ZERO: + ta_ext_c = GR_CMBX_ZERO; + ta_ext_c_invert = 0; + break; + case GR_COMBINE_FACTOR_LOCAL: + case GR_COMBINE_FACTOR_LOCAL_ALPHA: + ta_ext_c = GR_CMBX_LOCAL_TEXTURE_ALPHA; + ta_ext_c_invert = 0; + break; + case GR_COMBINE_FACTOR_OTHER_ALPHA: + ta_ext_c = GR_CMBX_OTHER_TEXTURE_ALPHA; + ta_ext_c_invert = 0; + break; + case GR_COMBINE_FACTOR_DETAIL_FACTOR: + ta_ext_c = GR_CMBX_DETAIL_FACTOR; + ta_ext_c_invert = 0; + break; + case GR_COMBINE_FACTOR_ONE: + ta_ext_c = GR_CMBX_ZERO; + ta_ext_c_invert = 1; + break; + case GR_COMBINE_FACTOR_ONE_MINUS_LOCAL: + case GR_COMBINE_FACTOR_ONE_MINUS_LOCAL_ALPHA: + ta_ext_c = GR_CMBX_LOCAL_TEXTURE_ALPHA; + ta_ext_c_invert = 1; + break; + case GR_COMBINE_FACTOR_ONE_MINUS_OTHER_ALPHA: + ta_ext_c = GR_CMBX_OTHER_TEXTURE_ALPHA; + ta_ext_c_invert = 1; + break; + case GR_COMBINE_FACTOR_ONE_MINUS_DETAIL_FACTOR: + ta_ext_c = GR_CMBX_DETAIL_FACTOR; + ta_ext_c_invert = 1; + break; + } + + switch (tmu_a_func) + { + case GR_COMBINE_FUNCTION_ZERO: + ta_ext_a = GR_CMBX_LOCAL_TEXTURE_ALPHA; + ta_ext_a_mode = GR_FUNC_MODE_ZERO; + ta_ext_b = GR_CMBX_LOCAL_TEXTURE_ALPHA; + ta_ext_b_mode = GR_FUNC_MODE_ZERO; + ta_ext_c = GR_CMBX_ZERO; + ta_ext_c_invert = 0; + ta_ext_d = GR_CMBX_ZERO; + ta_ext_d_invert = 0; + break; + case GR_COMBINE_FUNCTION_LOCAL: + case GR_COMBINE_FUNCTION_LOCAL_ALPHA: + ta_ext_a = GR_CMBX_LOCAL_TEXTURE_ALPHA; + ta_ext_a_mode = GR_FUNC_MODE_X; + ta_ext_b = GR_CMBX_LOCAL_TEXTURE_ALPHA; + ta_ext_b_mode = GR_FUNC_MODE_ZERO; + ta_ext_c = GR_CMBX_ZERO; + ta_ext_c_invert = 1; + ta_ext_d = GR_CMBX_ZERO; + ta_ext_d_invert = 0; + break; + case GR_COMBINE_FUNCTION_SCALE_OTHER: + ta_ext_a = GR_CMBX_OTHER_TEXTURE_ALPHA; + ta_ext_a_mode = GR_FUNC_MODE_X; + ta_ext_b = GR_CMBX_LOCAL_TEXTURE_ALPHA; + ta_ext_b_mode = GR_FUNC_MODE_ZERO; + ta_ext_d = GR_CMBX_ZERO; + ta_ext_d_invert = 0; + break; + case GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL: + case GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL_ALPHA: + ta_ext_a = GR_CMBX_OTHER_TEXTURE_ALPHA; + ta_ext_a_mode = GR_FUNC_MODE_X; + ta_ext_b = GR_CMBX_LOCAL_TEXTURE_ALPHA; + ta_ext_b_mode = GR_FUNC_MODE_ZERO; + ta_ext_d = GR_CMBX_B; + ta_ext_d_invert = 0; + break; + case GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL: + ta_ext_a = GR_CMBX_OTHER_TEXTURE_ALPHA; + ta_ext_a_mode = GR_FUNC_MODE_X; + ta_ext_b = GR_CMBX_LOCAL_TEXTURE_ALPHA; + ta_ext_b_mode = GR_FUNC_MODE_NEGATIVE_X; + ta_ext_d = GR_CMBX_ZERO; + ta_ext_d_invert = 0; + break; + case GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL: + case GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL_ALPHA: + ta_ext_a = GR_CMBX_OTHER_TEXTURE_ALPHA; + ta_ext_a_mode = GR_FUNC_MODE_X; + ta_ext_b = GR_CMBX_LOCAL_TEXTURE_ALPHA; + ta_ext_b_mode = GR_FUNC_MODE_NEGATIVE_X; + ta_ext_d = GR_CMBX_B; + ta_ext_d_invert = 0; + break; + case GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL: + case GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL_ALPHA: + ta_ext_a = GR_CMBX_LOCAL_TEXTURE_ALPHA; + ta_ext_a_mode = GR_FUNC_MODE_ZERO; + ta_ext_b = GR_CMBX_LOCAL_TEXTURE_ALPHA; + ta_ext_b_mode = GR_FUNC_MODE_NEGATIVE_X; + ta_ext_d = GR_CMBX_B; + ta_ext_d_invert = 0; + break; + } + + if (tmu == GR_TMU0) + { + cmb.t0a_ext_a = ta_ext_a; + cmb.t0a_ext_a_mode = ta_ext_a_mode; + cmb.t0a_ext_b = ta_ext_b; + cmb.t0a_ext_b_mode = ta_ext_b_mode; + cmb.t0a_ext_c = ta_ext_c; + cmb.t0a_ext_c_invert = ta_ext_c_invert; + cmb.t0a_ext_d = ta_ext_d; + cmb.t0a_ext_d_invert = ta_ext_d_invert; + } + else + { + cmb.t1a_ext_a = ta_ext_a; + cmb.t1a_ext_a_mode = ta_ext_a_mode; + cmb.t1a_ext_b = ta_ext_b; + cmb.t1a_ext_b_mode = ta_ext_b_mode; + cmb.t1a_ext_c = ta_ext_c; + cmb.t1a_ext_c_invert = ta_ext_c_invert; + cmb.t1a_ext_d = ta_ext_d; + cmb.t1a_ext_d_invert = ta_ext_d_invert; + } +} diff --git a/Source/Glide64/Combine.h b/Source/Glide64/Combine.h new file mode 100644 index 000000000..def39fe4a --- /dev/null +++ b/Source/Glide64/Combine.h @@ -0,0 +1,120 @@ +/* +* Glide64 - Glide video plugin for Nintendo 64 emulators. +* Copyright (c) 2002 Dave2001 +* Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski +* +* 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 +* 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 +*/ + +//**************************************************************** +// +// Glide64 - Glide Plugin for Nintendo 64 emulators +// Project started on December 29th, 2001 +// +// Authors: +// Dave2001, original author, founded the project in 2001, left it in 2002 +// Gugaman, joined the project in 2002, left it in 2002 +// Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002 +// Hiroshi 'KoolSmoky' Morii, joined the project in 2007 +// +//**************************************************************** +// +// To modify Glide64: +// * Write your name and (optional)email, commented by your work, so I know who did it, and so that you can find which parts you modified when it comes time to send it to me. +// * Do NOT send me the whole project or file that you modified. Take out your modified code sections, and tell me where to put them. If people sent the whole thing, I would have many different versions, but no idea how to combine them all. +// +//**************************************************************** +#ifndef COMBINE_H +#define COMBINE_H + +// texture MOD types +#define TMOD_TEX_INTER_COLOR_USING_FACTOR 1 +#define TMOD_TEX_INTER_COL_USING_COL1 2 +#define TMOD_FULL_COLOR_SUB_TEX 3 +#define TMOD_COL_INTER_COL1_USING_TEX 4 +#define TMOD_COL_INTER_COL1_USING_TEXA 5 +#define TMOD_COL_INTER_COL1_USING_TEXA__MUL_TEX 6 +#define TMOD_COL_INTER_TEX_USING_TEXA 7 +#define TMOD_COL2_INTER__COL_INTER_COL1_USING_TEX__USING_TEXA 8 +#define TMOD_TEX_SCALE_FAC_ADD_FAC 9 +#define TMOD_TEX_SUB_COL_MUL_FAC_ADD_TEX 10 +#define TMOD_TEX_SCALE_COL_ADD_COL 11 +#define TMOD_TEX_ADD_COL 12 +#define TMOD_TEX_SUB_COL 13 +#define TMOD_TEX_SUB_COL_MUL_FAC 14 +#define TMOD_COL_INTER_TEX_USING_COL1 15 +#define TMOD_COL_MUL_TEXA_ADD_TEX 16 +#define TMOD_COL_INTER_TEX_USING_TEX 17 +#define TMOD_TEX_INTER_NOISE_USING_COL 18 +#define TMOD_TEX_INTER_COL_USING_TEXA 19 +#define TMOD_TEX_MUL_COL 20 +#define TMOD_TEX_SCALE_FAC_ADD_COL 21 + +#define COMBINE_EXT_COLOR 1 +#define COMBINE_EXT_ALPHA 2 +#define TEX_COMBINE_EXT_COLOR 1 +#define TEX_COMBINE_EXT_ALPHA 2 + +typedef struct +{ + wxUint32 ccolor; // constant color to set at the end, color and alpha + wxUint32 c_fnc, c_fac, c_loc, c_oth; // grColorCombine flags + wxUint32 a_fnc, a_fac, a_loc, a_oth; // grAlphaCombine flags + wxUint32 tex, tmu0_func, tmu0_fac, tmu0_invert, tmu1_func, tmu1_fac, tmu1_invert; + wxUint32 tmu0_a_func, tmu0_a_fac, tmu0_a_invert, tmu1_a_func, tmu1_a_fac, tmu1_a_invert; + int dc0_lodbias, dc1_lodbias; + wxUint8 dc0_detailscale, dc1_detailscale; + float dc0_detailmax, dc1_detailmax; + float lodbias0, lodbias1; + wxUint32 abf1, abf2; + wxUint32 mod_0, modcolor_0, modcolor1_0, modcolor2_0, modfactor_0; + wxUint32 mod_1, modcolor_1, modcolor1_1, modcolor2_1, modfactor_1; + //combine extensions + wxUint32 c_ext_a, c_ext_a_mode, c_ext_b, c_ext_b_mode, c_ext_c, c_ext_d; + int c_ext_c_invert, c_ext_d_invert; + wxUint32 a_ext_a, a_ext_a_mode, a_ext_b, a_ext_b_mode, a_ext_c, a_ext_d; + int a_ext_c_invert, a_ext_d_invert; + wxUint32 t0c_ext_a, t0c_ext_a_mode, t0c_ext_b, t0c_ext_b_mode, t0c_ext_c, t0c_ext_d; + int t0c_ext_c_invert, t0c_ext_d_invert; + wxUint32 t0a_ext_a, t0a_ext_a_mode, t0a_ext_b, t0a_ext_b_mode, t0a_ext_c, t0a_ext_d; + int t0a_ext_c_invert, t0a_ext_d_invert; + wxUint32 t1c_ext_a, t1c_ext_a_mode, t1c_ext_b, t1c_ext_b_mode, t1c_ext_c, t1c_ext_d; + int t1c_ext_c_invert, t1c_ext_d_invert; + wxUint32 t1a_ext_a, t1a_ext_a_mode, t1a_ext_b, t1a_ext_b_mode, t1a_ext_c, t1a_ext_d; + int t1a_ext_c_invert, t1a_ext_d_invert; + GRCOLORCOMBINEEXT grColorCombineExt; + GRCOLORCOMBINEEXT grAlphaCombineExt; + GRTEXCOLORCOMBINEEXT grTexColorCombineExt; + GRTEXCOLORCOMBINEEXT grTexAlphaCombineExt; + GRCONSTANTCOLORVALUEEXT grConstantColorValueExt; + wxUint32 tex_ccolor; + int combine_ext; + wxUint8 cmb_ext_use; + wxUint8 tex_cmb_ext_use; + wxUint32 shade_mod_hash; +} COMBINE; + +extern COMBINE cmb; + +void Combine (); +void CombineBlender (); +void CountCombine (); +void InitCombine (); +void ColorCombinerToExtension (); +void AlphaCombinerToExtension (); +void TexColorCombinerToExtension (GrChipID_t tmu); +void TexAlphaCombinerToExtension (GrChipID_t tmu); + +#endif //COMBINE _H diff --git a/Source/Glide64/Config.cpp b/Source/Glide64/Config.cpp new file mode 100644 index 000000000..c8bdf077e --- /dev/null +++ b/Source/Glide64/Config.cpp @@ -0,0 +1,1430 @@ +/* +* Glide64 - Glide video plugin for Nintendo 64 emulators. +* Copyright (c) 2002 Dave2001 +* Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski +* +* 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 +* 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 +*/ + +//**************************************************************** +// +// Glide64 - Glide Plugin for Nintendo 64 emulators (tested mostly with Project64) +// Project started on December 29th, 2001 +// +// Authors: +// Dave2001, original author, founded the project in 2001, left it in 2002 +// Gugaman, joined the project in 2002, left it in 2002 +// Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002 +// Hiroshi 'KoolSmoky' Morii, joined the project in 2007 +// +//**************************************************************** +// +// To modify Glide64: +// * Write your name and (optional)email, commented by your work, so I know who did it, and so that you can find which parts you modified when it comes time to send it to me. +// * Do NOT send me the whole project or file that you modified. Take out your modified code sections, and tell me where to put them. If people sent the whole thing, I would have many different versions, but no idea how to combine them all. +// +//**************************************************************** +// +// Glide64 dialogs +// Created by Gonetz, 2008 +// +//**************************************************************** + + +// -*- C++ -*- generated by wxGlade 0.6.3 on Tue Oct 07 22:39:28 2008 + +#include "Gfx #1.3.h" +#include "DepthBufferRender.h" +#include "Config.h" +#include +#include +// begin wxGlade: ::extracode +// end wxGlade + + + +ConfigNotebook::ConfigNotebook(wxWindow* parent, int id, const wxPoint& pos, const wxSize& size, long style): +wxNotebook(parent, id, pos, size, 0) +{ + // begin wxGlade: ConfigNotebook::ConfigNotebook + //Basic settings panel + BasicSettingsPanel = new wxPanel(this, wxID_ANY); + BasicRenderingSizer_staticbox = new wxStaticBox(BasicSettingsPanel, -1, _("Rendering")); + OtherSizer_staticbox = new wxStaticBox(BasicSettingsPanel, -1, _("Other")); + SpeedSizer_staticbox = new wxStaticBox(BasicSettingsPanel, -1, _("Speed")); + TimeSizer_staticbox = new wxStaticBox(BasicSettingsPanel, -1, _("Time")); + OnScreenDisplaySizer_staticbox = new wxStaticBox(BasicSettingsPanel, -1, _("On screen display")); + WrapperSizer_staticbox = new wxStaticBox(BasicSettingsPanel, -1, _("OpenGL settings")); + WrapperFBOptionsSizer_staticbox = new wxStaticBox(BasicSettingsPanel, -1, _("Frame buffer emulation")); + lblResolution = new wxStaticText(BasicSettingsPanel, wxID_ANY, _("Windowed or\n3dfx card resolution:")); + const wxString cmbResolution_choices[] = { + wxT("320x200"), + wxT("320x240"), + wxT("400x256"), + wxT("512x384"), + wxT("640x200"), + wxT("640x350"), + wxT("640x400"), + wxT("640x480"), + wxT("800x600"), + wxT("960x720"), + wxT("856x480"), + wxT("512x256"), + wxT("1024x768"), + wxT("1280x1024"), + wxT("1600x1200"), + wxT("400x300"), + wxT("1152x864"), + wxT("1280x960"), + wxT("1600x1024"), + wxT("1792x1344"), + wxT("1856x1392"), + wxT("1920x1440"), + wxT("2048x1536"), + wxT("2048x2048") + }; + cmbResolution = new wxComboBox(BasicSettingsPanel, wxID_ANY, wxT(""), wxDefaultPosition, wxDefaultSize, 24, cmbResolution_choices, wxCB_DROPDOWN|wxCB_DROPDOWN|wxCB_READONLY); + cbxVSync = new wxCheckBox(BasicSettingsPanel, wxID_ANY, _("Vertical sync")); + cbxAdvancedSettings = new wxCheckBox(BasicSettingsPanel, wxID_ANY, _("Show advanced emulation options")); + cbxTextureSettings = new wxCheckBox(BasicSettingsPanel, wxID_ANY, _("Show texture enhancement options")); + lblScreenShotFormat = new wxStaticText(BasicSettingsPanel, wxID_ANY, _("Screenshot format:")); + cmbScreenShotFormat = new wxComboBox(BasicSettingsPanel, wxID_ANY, wxT(""), wxDefaultPosition, wxDefaultSize, 0, NULL, wxCB_DROPDOWN|wxCB_DROPDOWN|wxCB_READONLY); + lang_id = settings.lang_id; + wxString strLanguage = _("Language: "); + wxString strLanguageName = lang_id == wxLANGUAGE_ENGLISH_US ? wxLocale::GetLanguageName(lang_id) : wxString(_("LANGUAGE_NAME")); + if (strLanguageName != wxT("LANGUAGE_NAME")) + strLanguage += strLanguageName; + else + strLanguage += wxLocale::GetLanguageName(lang_id); + btnLanguage = new wxButton(BasicSettingsPanel, wxID_Language, strLanguage); + cbxFPS = new wxCheckBox(BasicSettingsPanel, wxID_ANY, _("FPS counter")); + cbxVIS = new wxCheckBox(BasicSettingsPanel, wxID_ANY, _("VI/s counter")); + cbxPercent = new wxCheckBox(BasicSettingsPanel, wxID_ANY, _("% speed")); + cbxClockEnabled = new wxCheckBox(BasicSettingsPanel, wxID_ANY, _("Clock enabled")); + cbxClock24 = new wxCheckBox(BasicSettingsPanel, wxID_ANY, _("Clock is 24-hour")); + cbxTextTransparent = new wxCheckBox(BasicSettingsPanel, wxID_ANY, _("Transparent text background")); + lblFSResolution = new wxStaticText(BasicSettingsPanel, wxID_ANY, _("Full screen\nresolution:")); + const wxString *cmbFSResolution_choices = NULL; + cmbFSResolution = new wxComboBox(BasicSettingsPanel, wxID_ANY, wxT(""), wxDefaultPosition, wxDefaultSize, 0, cmbFSResolution_choices, wxCB_DROPDOWN|wxCB_READONLY); + cbxAnisotropic = new wxCheckBox(BasicSettingsPanel, wxID_ANY, _("Anisotropic filtering")); + cbxVRAM = new wxCheckBox(BasicSettingsPanel, wxID_VRAM, _("Autodetect ")); + lblVRAM = new wxStaticText(BasicSettingsPanel, wxID_ANY, _("VRAM size")); + spinVRAM = new wxSpinCtrl(BasicSettingsPanel, wxID_ANY, wxT("128"), wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS|wxTE_CENTRE, 32, 2000); + lblMb = new wxStaticText(BasicSettingsPanel, wxID_ANY, _("Mb")); + cbxFBO = new wxCheckBox(BasicSettingsPanel, wxID_ANY, _("Use frame buffer objects")); + + //emulation settings panel + if (settings.advanced_options) + { + EmuSettingsPanel = new wxPanel(this, wxID_ANY); + if (romopen) + EmuSettingsBoxSizer_staticbox = new wxStaticBox(EmuSettingsPanel, -1, _("Current game emulation settings. Change with care!")); + else + EmuSettingsBoxSizer_staticbox = new wxStaticBox(EmuSettingsPanel, -1, _("Default emulation settings. Not recommended to change!")); + EmuSettingsLeftSizer_staticbox = new wxStaticBox(EmuSettingsPanel, -1, _("General options")); + FrameBufferSizer_staticbox = new wxStaticBox(EmuSettingsPanel, -1, _("Frame buffer emulation")); + DepthBufferSizer_staticbox = new wxStaticBox(EmuSettingsPanel, -1, _("Depth buffer emulation")); + lbFiltering = new wxStaticText(EmuSettingsPanel, wxID_ANY, _("Filtering mode:")); + const wxString cmbFiltering_choices[] = { + _("Automatic"), + _("Force Bilinear"), + _("Force Point-sampled") + }; + cmbFiltering = new wxComboBox(EmuSettingsPanel, wxID_ANY, wxT(""), wxDefaultPosition, wxDefaultSize, 3, cmbFiltering_choices, wxCB_DROPDOWN|wxCB_DROPDOWN|wxCB_READONLY); + lbBufferSwap = new wxStaticText(EmuSettingsPanel, wxID_ANY, _("Buffer swapping method:")); + const wxString cmbBufferSwap_choices[] = { + _("Old"), + _("New"), + _("Hybrid") + }; + cmbBufferSwap = new wxComboBox(EmuSettingsPanel, wxID_ANY, wxT(""), wxDefaultPosition, wxDefaultSize, 3, cmbBufferSwap_choices, wxCB_DROPDOWN|wxCB_DROPDOWN|wxCB_READONLY); + lblLOD = new wxStaticText(EmuSettingsPanel, wxID_ANY, _("LOD calculation:")); + const wxString cmbLOD_choices[] = { + _("off"), + _("fast"), + _("precise") + }; + cmbLOD = new wxComboBox(EmuSettingsPanel, wxID_ANY, wxT(""), wxDefaultPosition, wxDefaultSize, 3, cmbLOD_choices, wxCB_DROPDOWN|wxCB_DROPDOWN|wxCB_READONLY); + lblAspect = new wxStaticText(EmuSettingsPanel, wxID_ANY, _("Aspect ratio:")); + const wxString cmbAspect_choices[] = { + _("4:3 (default)"), + _("Force 16:9"), + _("Stretch"), + _("Original") + }; + cmbAspect = new wxComboBox(EmuSettingsPanel, wxID_ANY, wxT(""), wxDefaultPosition, wxDefaultSize, 4, cmbAspect_choices, wxCB_DROPDOWN|wxCB_DROPDOWN|wxCB_READONLY); + cbxFog = new wxCheckBox(EmuSettingsPanel, wxID_ANY, _("Fog")); + cbxBuffer = new wxCheckBox(EmuSettingsPanel, wxID_ANY, _("Buffer clear on every frame")); + cbxFBEnable = new wxCheckBox(EmuSettingsPanel, wxID_FBEnable, _("Enable frame buffer emulation")); + cbxFBHWFBE = new wxCheckBox(EmuSettingsPanel, wxID_ANY, _("Hardware frame buffer emulation")); + cbxFBGetFBI = new wxCheckBox(EmuSettingsPanel, wxID_ANY, _("Get frame buffer info")); + cbxFBReadEveryFrame = new wxCheckBox(EmuSettingsPanel, wxID_ANY, _("Read every frame (slow!)")); + cbxFBasTex = new wxCheckBox(EmuSettingsPanel, wxID_ANY, _("Render N64 frame buffer as texture")); + cbxDetect = new wxCheckBox(EmuSettingsPanel, wxID_ANY, _("Detect CPU write to the N64 frame buffer")); + cbxFBDepthBuffer = new wxCheckBox(EmuSettingsPanel, wxID_ANY, _("Software depth buffer rendering")); + } + +#ifdef TEXTURE_FILTER + if (settings.texenh_options) + { + if (!fullscreen) + { + grGlideInit (); + grSstSelect (settings.card_id); + } + const char *extensions = grGetString (GR_EXTENSION); + if (strstr (extensions, "EVOODOO")) + evoodoo = 1; + else + evoodoo = 0; + if (strstr (extensions, "TEXFMT")) + voodoo.sup_32bit_tex = TRUE; + else + voodoo.sup_32bit_tex = FALSE; + if (!fullscreen) + grGlideShutdown (); + + TexturePanel = new wxPanel(this, wxID_ANY); + EnhTexSizer_staticbox = new wxStaticBox(TexturePanel, -1, _("Texture enhancement")); + TextureRightSizer_staticbox = new wxStaticBox(TexturePanel, -1, _("Hi-resolution textures")); + CommonSizer_staticbox = new wxStaticBox(TexturePanel, -1, _("Common")); + PresetsSizer_staticbox = new wxStaticBox(TexturePanel, -1, _("Presets")); + EnhTexPerfTweaksSizer_staticbox = new wxStaticBox(TexturePanel, -1, _("Performance tweaks")); + HRTexPerfTweaksSizer_staticbox = new wxStaticBox(TexturePanel, -1, _("Performance tweaks")); + lblFilter = new wxStaticText(TexturePanel, wxID_ANY, _("Filter")); + const wxString cmbEnhFilter_choices[] = { + _("None"), + _("Smooth filtering 1"), + _("Smooth filtering 2"), + _("Smooth filtering 3"), + _("Smooth filtering 4"), + _("Sharp filtering 1"), + _("Sharp filtering 2") + }; + cmbEnhFilter = new wxComboBox(TexturePanel, wxID_ANY, wxT(""), wxDefaultPosition, wxDefaultSize, 7, cmbEnhFilter_choices, wxCB_DROPDOWN|wxCB_DROPDOWN|wxCB_READONLY); + lblEnhancement = new wxStaticText(TexturePanel, wxID_ANY, _("Enhancement")); + const wxString cmbEnhEnhancement_choices[] = { + _("None"), + _("Store"), + wxT("X2"), + wxT("X2SAI"), + wxT("HQ2X"), + wxT("HQ2XS"), + wxT("LQ2X"), + wxT("LQ2XS"), + wxT("HQ4X") + }; + cmbEnhEnhancement = new wxComboBox(TexturePanel, wxID_ANY, wxT(""), wxDefaultPosition, wxDefaultSize, 9, cmbEnhEnhancement_choices, wxCB_DROPDOWN|wxCB_DROPDOWN|wxCB_READONLY); + lblTexCache = new wxStaticText(TexturePanel, wxID_ANY, _("Texture cache")); + spinEnhCacheSize = new wxSpinCtrl(TexturePanel, wxID_ANY, wxT("0"), wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 0, 300); + lblTexCacheMB = new wxStaticText(TexturePanel, wxID_ANY, _("Mbytes")); + cbxEnhIgnoreBG = new wxCheckBox(TexturePanel, wxID_ANY, _("Ignore Backgrounds")); + cbxEnhTexCompression = new wxCheckBox(TexturePanel, wxID_ANY, _("Apply texture compression")); + cbxEnhCompressCache = new wxCheckBox(TexturePanel, wxID_ANY, _("Compress texture cache")); + lblHrsFormat = new wxStaticText(TexturePanel, wxID_ANY, _("Format")); + const wxString cmbHrsFormat_choices[] = { + _("None"), + _("Rice format") + }; + cmbHrsFormat = new wxComboBox(TexturePanel, wxID_ANY, wxT(""), wxDefaultPosition, wxDefaultSize, 2, cmbHrsFormat_choices, wxCB_DROPDOWN|wxCB_DROPDOWN|wxCB_READONLY); + cbxHrsTile = new wxCheckBox(TexturePanel, wxID_ANY, _("Tile textures")); + cbxHrsForce16 = new wxCheckBox(TexturePanel, wxID_ANY, _("Force 16bpp textures")); + cbxHrsAltCRC = new wxCheckBox(TexturePanel, wxID_ANY, _("Alternative CRC calculation")); + cbxHrsTexCompression = new wxCheckBox(TexturePanel, wxID_ANY, _("Apply texture compression")); + cbxHrsCompressCache = new wxCheckBox(TexturePanel, wxID_ANY, _("Compress texture cache")); + cbxHrsLetFly = new wxCheckBox(TexturePanel, wxID_ANY, _("Use alpha channel fully")); + cbxHrsTexEdit = new wxCheckBox(TexturePanel, wxID_TexEdit, _("Texture dumping/editing mode")); + lblTexCompression = new wxStaticText(TexturePanel, wxID_ANY, _("Texture compression method")); + const wxString cmbTextureCompression_choices[] = { + wxT("S3TC"), + wxT("FXT1") + }; + cmbTextureCompression = new wxComboBox(TexturePanel, wxID_ANY, wxT(""), wxDefaultPosition, wxDefaultSize, evoodoo ? 1 : 2, cmbTextureCompression_choices, wxCB_DROPDOWN|wxCB_DROPDOWN|wxCB_READONLY); + cbxSaveTexCache = new wxCheckBox(TexturePanel, wxID_ANY, _("Save texture cache to hard disk")); + btnPerformance = new wxButton(TexturePanel, wxID_Performance, _("Best performance")); + btnQuality = new wxButton(TexturePanel, wxID_Quality, _("Best texture quality")); + } +#endif //TEXTURE_FILTER + +#ifndef _ENDUSER_RELEASE_ + DebugPanel = new wxPanel(this, wxID_ANY); + DevSettingsSizer_staticbox = new wxStaticBox(DebugPanel, -1, _("Developers settings")); + DebugSizer_staticbox = new wxStaticBox(DebugPanel, -1, _("Debug/Misc")); + cbxAutoUcode = new wxCheckBox(DebugPanel, wxID_ANY, _("Autodetect Microcode")); + lblForceUcode = new wxStaticText(DebugPanel, wxID_ANY, _("Force Microcode:")); + const wxString cmbForceUcode_choices[] = { + wxT("0: RSP SW 2.0X (ex. Mario)"), + wxT("1: F3DEX 1.XX (ex. Star Fox)"), + wxT("2: F3DEX 2.XX (ex. Zelda OOT)"), + wxT("3: RSP SW 2.0D EXT (ex. Waverace)"), + wxT("4: RSP SW 2.0D EXT (ex. Shadows of the Empire)"), + wxT("5: RSP SW 2.0 (ex. Diddy Kong Racing)"), + wxT("6: S2DEX 1.XX (ex. Yoshi's Story)"), + wxT("7: RSP SW PD Perfect Dark"), + wxT("8: F3DEXBG 2.08 Conker's Bad Fur Day") + }; + cmbForceUcode = new wxComboBox(DebugPanel, wxID_ANY, wxT(""), wxDefaultPosition, wxDefaultSize, 9, cmbForceUcode_choices, wxCB_DROPDOWN|wxCB_DROPDOWN|wxCB_READONLY); + cbxWireframe = new wxCheckBox(DebugPanel, wxID_ANY, _("Wireframe using:")); + const wxString cmbWireframe_choices[] = { + _("Original colors"), + _("Vertex colors"), + _("Red only") + }; + cmbWireframe = new wxComboBox(DebugPanel, wxID_ANY, wxT(""), wxDefaultPosition, wxDefaultSize, 3, cmbWireframe_choices, wxCB_DROPDOWN|wxCB_DROPDOWN|wxCB_READONLY); + cbxLog = new wxCheckBox(DebugPanel, wxID_ANY, _("Log to rdp.txt (SLOW)")); + cbxCombRed = new wxCheckBox(DebugPanel, wxID_ANY, _("Unknown combiners as red")); + cbxLogClear = new wxCheckBox(DebugPanel, wxID_ANY, _("Log clear every frame")); + cbxCmbLog = new wxCheckBox(DebugPanel, wxID_ANY, _("Combiner logging")); + cbxWindowLog = new wxCheckBox(DebugPanel, wxID_ANY, _("Run (+log) in window")); + cbxCmbLogClear = new wxCheckBox(DebugPanel, wxID_ANY, _("Cmb. clear every frame")); + cbxErrLog = new wxCheckBox(DebugPanel, wxID_ANY, _("Error log (rdp_e.txt)")); + cbxBilinearTexCache = new wxCheckBox(DebugPanel, wxID_ANY, _("Bilinear filter texture cache")); +#endif //_ENDUSER_RELEASE_ + + set_properties(); + do_layout(); + // end wxGlade +} + + +BEGIN_EVENT_TABLE(ConfigNotebook, wxNotebook) +// begin wxGlade: ConfigNotebook::event_table +EVT_CHECKBOX(wxID_VRAM, ConfigNotebook::OnClickVRAM) +EVT_CHECKBOX(wxID_FBEnable, ConfigNotebook::OnClickFB) +EVT_BUTTON(wxID_Language, ConfigNotebook::OnLanguageSelect) +#ifdef TEXTURE_FILTER +EVT_BUTTON(wxID_Performance, ConfigNotebook::onPerformace) +EVT_BUTTON(wxID_Quality, ConfigNotebook::onQuality) +EVT_CHECKBOX(wxID_TexEdit, ConfigNotebook::OnClickTexEdit) +#endif //TEXTURE_FILTER +// EVT_NOTEBOOK_PAGE_CHANGED(wxID_ANY, ConfigNotebook::onPageChanged) +// EVT_NOTEBOOK_PAGE_CHANGING(wxID_ANY, ConfigNotebook::onPageChanging) +// end wxGlade +END_EVENT_TABLE(); + +void ConfigNotebook::OnClickVRAM(wxCommandEvent &event) +{ + if (event.GetEventObject() == cbxVRAM) + { + bool enable = !cbxVRAM->GetValue(); + if (enable) + spinVRAM->SetValue(settings.wrpVRAM); + else + spinVRAM->SetValue(_(" auto")); + spinVRAM->Enable(enable); + lblMb->Enable(enable); + } +// event.Skip(); +// wxLogDebug(wxT("Event handler (ConfigNotebook::FrameBufferOnClick) not implemented yet")); //notify the user that he hasn't implemented the event handler yet +} + +void ConfigNotebook::OnClickFB(wxCommandEvent &event) +{ + if (event.GetEventObject() == cbxFBEnable) + cbxFBHWFBE->Enable(cbxFBEnable->GetValue()); + // event.Skip(); + // wxLogDebug(wxT("Event handler (ConfigNotebook::FrameBufferOnClick) not implemented yet")); //notify the user that he hasn't implemented the event handler yet +} + +static wxString GetTranslationsPath() +{ + if (!iniPath.IsEmpty()) + return iniPath; //.BeforeLast(wxFileName::GetPathSeparator()); + return pluginPath; +} + +void ConfigNotebook::OnLanguageSelect(wxCommandEvent &event) +{ + if (event.GetEventObject() != btnLanguage) + event.Skip(); + wxArrayString files; + size_t nbLangs = wxDir::GetAllFiles(GetTranslationsPath(), &files, wxString(wxT("Glide64_*.mo")), wxDIR_FILES); + if (nbLangs == 0) + { + wxMessageBox(wxT("No translation (Glide64_*.mo) files found.\nUsing default language."), wxT("Files not found"), wxOK|wxICON_EXCLAMATION); + settings.lang_id = wxLANGUAGE_ENGLISH_US; + return; + } + size_t i; + wxArrayInt aLangIds; + wxArrayString aLangNames; + const wxLanguageInfo * info = wxLocale::GetLanguageInfo(wxLANGUAGE_ENGLISH_US); + aLangIds.Add(info->Language); + aLangNames.Add(info->Description); + for (i = 0; i < nbLangs; i++) + { + info = wxLocale::FindLanguageInfo(wxFileName(files[i]).GetName().AfterFirst('_')); + if (info && wxLocale::IsAvailable(info->Language)) { + //vLangInfos.push_back(LangInfo(info->Description, info->Language)); + aLangIds.Add(info->Language); + aLangNames.Add(info->Description); + } + } + if (aLangIds.Count() == 1) + { + wxMessageBox(wxT("No translations supported by your OS found.\nUsing default language."), wxT("Files not found"), wxOK|wxICON_EXCLAMATION); + settings.lang_id = wxLANGUAGE_ENGLISH_US; + return; + } + int lng = wxGetSingleChoiceIndex ( + _("Please choose language:"), + _("Language"), + aLangNames, + this + ); + if (lng != -1 && lang_id != aLangIds[lng]) + { + lang_id = aLangIds[lng]; + wxString strLanguage(_("Press OK to change to ")); + strLanguage += aLangNames[lng]; + btnLanguage->wxButton::SetLabel(strLanguage); + } +} + +#ifdef TEXTURE_FILTER +void ConfigNotebook::onPerformace(wxCommandEvent &event) +{ + cbxEnhCompressCache->SetValue(true); + cbxHrsCompressCache->SetValue(true); + cbxEnhIgnoreBG->SetValue(true); + cbxHrsAltCRC->SetValue(true); + cbxHrsLetFly->SetValue(true); + cbxSaveTexCache->SetValue(true); + cmbTextureCompression->SetSelection(0); + cbxHrsTexCompression->SetValue(false); + cbxEnhTexCompression->SetValue(false); + cbxHrsTexEdit->SetValue(false); + + if (voodoo.sup_32bit_tex) + { + cbxHrsTexCompression->SetValue(true); + cbxEnhTexCompression->SetValue(true); + cmbTextureCompression->SetSelection(1); + } + else + { + cbxHrsForce16->SetValue(true); + } + // event.Skip(); + // wxLogDebug(wxT("Event handler (ConfigNotebook::onPerformace) not implemented yet")); //notify the user that he hasn't implemented the event handler yet +} + + +void ConfigNotebook::onQuality(wxCommandEvent &event) +{ + cbxEnhCompressCache->SetValue(true); + cbxHrsCompressCache->SetValue(true); + cbxEnhIgnoreBG->SetValue(false); + cbxHrsTile->SetValue(false); + cbxHrsAltCRC->SetValue(true); + cbxHrsLetFly->SetValue(true); + cbxSaveTexCache->SetValue(true); + cmbTextureCompression->SetSelection(0); + cbxHrsTexCompression->SetValue(false); + cbxEnhTexCompression->SetValue(false); + cbxHrsTexEdit->SetValue(false); + cbxHrsForce16->SetValue(false); + + if (!voodoo.sup_32bit_tex) + { + cbxHrsForce16->SetValue(true); + } + // event.Skip(); + // wxLogDebug(wxT("Event handler (ConfigNotebook::onQuality) not implemented yet")); //notify the user that he hasn't implemented the event handler yet +} + +void ConfigNotebook::OnClickTexEdit(wxCommandEvent &event) +{ + if (event.GetEventObject() == cbxHrsTexEdit) + { + bool val = !cbxHrsTexEdit->GetValue(); + cbxHrsAltCRC->Enable(val); + if (val) + cbxHrsAltCRC->SetValue(settings.ghq_hirs_altcrc>0); + else + cbxHrsAltCRC->SetValue(false); + } + // event.Skip(); + // wxLogDebug(wxT("Event handler (ConfigNotebook::FrameBufferOnClick) not implemented yet")); //notify the user that he hasn't implemented the event handler yet +} +#endif //TEXTURE_FILTER + +/* +void ConfigNotebook::onPageChanged(wxNotebookEvent &event) +{ +event.Skip(); +wxLogDebug(wxT("Event handler (ConfigNotebook::onPageChanged) not implemented yet")); //notify the user that he hasn't implemented the event handler yet +} + + +void ConfigNotebook::onPageChanging(wxNotebookEvent &event) +{ +event.Skip(); +wxLogDebug(wxT("Event handler (ConfigNotebook::onPageChanging) not implemented yet")); //notify the user that he hasn't implemented the event handler yet +} +*/ + +// wxGlade: add ConfigNotebook event handlers + + +void ConfigNotebook::set_properties() +{ + // begin wxGlade: ConfigNotebook::set_properties + //Basic panel + AddPage(BasicSettingsPanel, _("Basic settings")); + wxString tooltip = _("Resolution\nThis option selects the fullscreen resolution for 3dfx cards and windowed resolution for other cards\n(note again that for 3dfx cards the plugin must be in fullscreen mode to see anything).\n[Recommended: 640x480, 800x600, 1024x768]"); + lblResolution->SetToolTip(tooltip); + cmbResolution->SetToolTip(tooltip); + cmbResolution->SetSelection(settings.res_data); + cbxVSync->SetToolTip(_("Vertical sync\nThis option will enable the vertical sync, which will prevent tearing.\nNote: this option will ONLY have effect if vsync is set to \"Software Controlled\".\n")); + cbxVSync->SetValue(settings.vsync>0); + tooltip = _("Select a format, in which screen shots will be saved"); + lblScreenShotFormat->SetToolTip(tooltip); + cmbScreenShotFormat->SetToolTip(tooltip); + for (int f = 0; f < NumOfFormats; f++) { + cmbScreenShotFormat->Append(ScreenShotFormats[f].format); + } + cmbScreenShotFormat->SetSelection(settings.ssformat); + btnLanguage->SetToolTip(_("Language select:\nPress the button to invoke language selection dialog.\nSelected language will be activated after restart of the configuration dialog.")); + cbxFPS->SetToolTip(_("FPS counter\nWhen this option is checked, a FPS (frames per second) counter will be shown\nin the lower left corner of the screen.\n[Recommended: your preference]")); + cbxFPS->SetValue((settings.show_fps&1) > 0); + cbxVIS->SetToolTip(_("VI/s counter\nWhen this option is checked, a VI/s (vertical interrupts per second) counter\nwill be shown in the lower left corner of the screen. This is like the FPS\ncounter but will be consistent at 60 VI/s for full speed on NTSC (U) games and\n50 VI/s for full speed on PAL (E) ones.\n[Recommended: your preference]")); + cbxVIS->SetValue((settings.show_fps&2) > 0); + cbxPercent->SetToolTip(_("% speed\nThis displays a percentage of the actual N64 speed in the lower\nleft corner of the screen.\n[Recommended: your preference]")); + cbxPercent->SetValue((settings.show_fps&4) > 0); + cbxClockEnabled->SetToolTip(_("Clock enabled\nThis option will put a clock in the lower right corner of the screen, showing the current time.\n[Recommended: your preference]")); + cbxClockEnabled->SetValue(settings.clock>0); + cbxClock24->SetValue(settings.clock_24_hr>0); + cbxClock24->SetToolTip(_("Display hours as 24-hour clock.\n[Recommended: your preference]")); + cbxTextTransparent->SetToolTip(_("Transparent text background\nIf this is checked, all on-screen messages will have a transparent background. Otherwise, it will have a solid black background.\n[Recommended: your preference]")); + cbxTextTransparent->SetValue((settings.show_fps&8) > 0); + cbxAdvancedSettings->SetValue(settings.advanced_options > 0); + cbxAdvancedSettings->SetToolTip(_("Enable \"Emulation settings\" panel. For experienced users only!\nIt shows default emulation settings when game is not loaded, or current game settings otherwise.")); + cbxTextureSettings->SetValue(settings.texenh_options > 0); + cbxTextureSettings->SetToolTip(_("Enable \"Texture enhancement\" panel.\nIt shows various enhancement options for original textures as well as options for hi-resolution textures.")); + tooltip = _("Full screen resolution:\nThis sets the full screen resolution for non-3dfx video cards.\nAll the resolutions that your video card/monitor support should be displayed.\n[Recommended: native (max) resolution of your monitor - unless performance becomes an issue]"); + lblFSResolution->SetToolTip(tooltip); + cmbFSResolution->SetToolTip(tooltip); + cbxAnisotropic->SetToolTip(_("Anisotropic filtering:\nThis filter sharpens and brings out the details of textures that recede into the distance.\nWhen activated, it will use the max anisotropy your video card supports.\nHowever, this will override native way of texture filtering and may cause visual artifacts in some games.\n[Recommended: your preference, game dependant]")); + cbxVRAM->SetToolTip(_("Autodetect VRAM Size:\nSince OpenGL cannot do this reliably at the moment, the option to set this manually is available.\nIf checked, plugin will try to autodetect VRAM size.\nBut if this appears wrong, please uncheck and set it to correct value.\n[Recommended: on]")); + spinVRAM->SetMinSize(wxSize(55, 21)); + cbxFBO->SetToolTip(_("Use frame buffer objects:\nChanges the way FB effects are rendered - with or without usage of the OpenGL Frame Buffer Objects (FBO) extension.\nThe choice depends on game and your video card. FBO off is good for NVIDIA cards, while for ATI cards, it's usually best that FBOs are turned on.\nAlso, some FB effects works only with one of the methods, no matter, which card you have.\nOn the whole, with FBO off, compatibility/ accuracy is a bit better (which is the case for Resident Evil 2).\nHowever, with FBO on with some systems, it can actually be a bit faster in cases.\n[Recommended: video card and game dependant]")); + char strConfigWrapperExt[] = "grConfigWrapperExt"; + GRCONFIGWRAPPEREXT grConfigWrapperExt = (GRCONFIGWRAPPEREXT)grGetProcAddress(strConfigWrapperExt); + if (grConfigWrapperExt) + { + char strQueryResolutionsExt[] = "grQueryResolutionsExt"; + GRQUERYRESOLUTIONSEXT grQueryResolutionsExt = (GRQUERYRESOLUTIONSEXT)grGetProcAddress(strQueryResolutionsExt); + if (grQueryResolutionsExt) + { + FxI32 size = 0; + char ** aRes = grQueryResolutionsExt(&size); + if (aRes && size) + { + for (int r = 0; r < size; r++) { + wxString res(aRes[r], wxConvUTF8); + cmbFSResolution->Append(res); + } + cmbFSResolution->SetSelection(settings.wrpResolution < size ? settings.wrpResolution : 0); + } + } +#ifdef __WINDOWS__ + cbxVRAM->SetValue(settings.wrpVRAM == 0); + if (cbxVRAM->GetValue()) + spinVRAM->SetValue(_(" auto")); + else + spinVRAM->SetValue(settings.wrpVRAM); + spinVRAM->Enable(!cbxVRAM->GetValue()); + lblMb->Enable(!cbxVRAM->GetValue()); +#else + cbxVRAM->SetValue(false); + cbxVRAM->Disable(); + spinVRAM->SetValue(settings.wrpVRAM ? settings.wrpVRAM : 32); + spinVRAM->Enable(true); + lblMb->Enable(true); +#endif + cbxFBO->SetValue(settings.wrpFBO > 0); + cbxAnisotropic->SetValue(settings.wrpAnisotropic > 0); + } + else + { + WrapperSizer_staticbox->Disable(); + WrapperFBOptionsSizer_staticbox->Disable(); + lblFSResolution->Disable(); + cmbFSResolution->Disable(); + cbxAnisotropic->Disable(); + cbxVRAM->Disable(); + lblVRAM->Disable(); + spinVRAM->Disable(); + lblMb->Disable(); + cbxFBO->Disable(); + } + + //emulation settings panel + if (settings.advanced_options) + { + AddPage(EmuSettingsPanel, _("Emulation settings")); + tooltip = _("Filtering mode\nThere are three filtering modes possible:\n* Automatic filtering - filter exactly how the N64 specifies.\n* Point-sampled filtering - causes texels to appear square and sharp.\n* Bilinear filtering - interpolates the texture to make it appear more smooth.\n[Recommended: Automatic]"); + lbFiltering->SetToolTip(tooltip); + cmbFiltering->SetToolTip(tooltip); + cmbFiltering->SetSelection(settings.filtering); + tooltip = _("Buffer swapping method\nThere are 3 buffer swapping methods:\n* old - swap buffers when vertical interrupt has occurred.\n* new - swap buffers when set of conditions is satisfied. Prevents flicker on some games.\n* hybrid - mix of first two methods.\nCan prevent even more flickering then previous method, but also can cause artefacts.\nIf you have flickering problems in a game (or graphics that don't show),\ntry to change swapping method.\n[Recommended: new (hybrid for Paper Mario)]"); + lbBufferSwap->SetToolTip(tooltip); + cmbBufferSwap->SetToolTip(tooltip); + cmbBufferSwap->SetSelection(settings.swapmode); + tooltip = _("Per-pixel level-of-detail calculation\nN64 uses special mechanism for mip-mapping, which nearly impossible to reproduce\ncorrectly on PC hardware. This option enables approximate emulation of this feature.\nFor example, it is required for the Peach/Bowser portrait's transition in Super Mario 64.\nThere are 3 modes:\n* off - LOD is not calculated\n* fast - fast imprecise LOD calculation.\n* precise - most precise LOD calculation possible, but more slow.\n[Recommended: your preference]"); + lblLOD->SetToolTip(tooltip); + cmbLOD->SetToolTip(tooltip); + cmbLOD->SetSelection(settings.lodmode); + cmbAspect->SetSelection(settings.aspectmode); + tooltip = _("Aspect ratio of the output.\nMost N64 games use 4:3 aspect ratio, but some support widescreen too.\nYou may select appropriate aspect here and set widescreen mode in game settings.\nIn \"Stretch\" mode the output will be stretched to the entire screen,\nother modes may add black borders if necessary"); + cmbAspect->SetToolTip(tooltip); + lblAspect->SetToolTip(tooltip); + cbxFog->SetToolTip(_("Fog enabled\nSets fog emulation on//off.\n[Recommended: on]")); + cbxFog->SetValue(settings.fog>0); + cbxBuffer->SetToolTip(_("Buffer clear on every frame\nForces the frame buffer to be cleared every frame drawn.\nUsually frame buffer clear is controlled by the game.\nHowever, in some cases it is not well emulated,\nand some garbage may be left on the screen.\nIn such cases, this option must be set on.\n[Recommended: on]")); + cbxBuffer->SetValue(settings.buff_clear>0); + cbxFBEnable->SetToolTip(_("Enable frame buffer emulation\nIf on, plugin will try to detect frame buffer usage and apply appropriate frame buffer emulation.\n[Recommended: on for games which use frame buffer effects]")); + cbxFBEnable->SetValue(fb_emulation_enabled); + cbxFBHWFBE->SetToolTip(_("Enable hardware frame buffer emulation\nIf this option is on, plugin will create auxiliary frame buffers in video memory instead of copying\nframe buffer content into main memory. This allows plugin to run frame buffer effects without slowdown\nand without scaling image down to N64's native resolution. This feature is fully supported by\nVoodoo 4/5 cards and partially by Voodoo3 and Banshee. Modern cards also fully support it.\n[Recommended: on, if supported by your hardware]")); + cbxFBHWFBE->SetValue(((settings.frame_buffer&fb_hwfbe)>0)); + cbxFBHWFBE->Enable(fb_emulation_enabled); + cbxFBGetFBI->SetToolTip(_("Get information about frame buffers\nThis is compatibility option. It must be set on for Mupen64 and off for 1964")); + cbxFBGetFBI->SetValue((settings.frame_buffer&fb_get_info)>0); + cbxFBReadEveryFrame->SetToolTip(_("Read every frame\nIn some games plugin can't detect frame buffer usage.\nIn such cases you need to enable this option to see frame buffer effects.\nEvery drawn frame will be read from video card -> it works very slow.\n[Recommended: mostly off (needed only for a few games)]")); + cbxFBReadEveryFrame->SetValue((settings.frame_buffer&fb_ref)>0); + cbxFBasTex->SetToolTip(_("Render N64 frame buffer as texture\nWhen this option is enabled, content of each N64 frame buffer is rendered\nas texture over the frame, rendered by the plugin. This prevents graphics lost,\nbut may cause slowdowns and various glitches in some games.\n[Recommended: mostly off]")); + cbxFBasTex->SetValue((settings.frame_buffer&fb_read_back_to_screen)>0); + cbxDetect->SetToolTip(_("Detect CPU write to the N64 frame buffer\nThis option works as the previous options, but the plugin is trying to detect,\nwhen game uses CPU writes to N64 frame buffer. The N64 frame buffer is rendered\nonly when CPU writes is detected. Use this option for those games, in which you\nsee still image or no image at all for some time with no reason.\n[Recommended: mostly off]")); + cbxDetect->SetValue((settings.frame_buffer&fb_cpu_write_hack)>0); + cbxFBDepthBuffer->SetToolTip(_("Enable depth buffer rendering\nThis option is used to fully emulate N64 depth buffer.\nIt is required for correct emulation of depth buffer based effects.\nHowever, it requires fast (>1GHz) CPU to work full speed.\n[Recommended: on for fast PC]")); + cbxFBDepthBuffer->SetValue((settings.frame_buffer&fb_depth_render)>0); + } + +#ifdef TEXTURE_FILTER + if (settings.texenh_options) + { + AddPage(TexturePanel, _("Texture enhancement")); + tooltip = _("Filters:\nApply a filter to either smooth or sharpen textures.\nThere are 4 different smoothing filters and 2 different sharpening filters.\nThe higher the number, the stronger the effect,\ni.e. \"Smoothing filter 4\" will have a much more noticeable effect than \"Smoothing filter 1\".\nBe aware that performance may have an impact depending on the game and/or the PC.\n[Recommended: your preference]"); + lblFilter->SetToolTip(tooltip); + cmbEnhFilter->SetToolTip(tooltip); + cmbEnhFilter->SetSelection(settings.ghq_fltr); + tooltip = _("Texture enhancement:\n7 different filters are selectable here, each one with a distinctive look.\nBe aware of possible performance impacts.\n\nIMPORTANT: 'Store' mode - saves textures in cache 'as is'. It can improve performance in games, which load many textures.\nDisable 'Ignore backgrounds' option for better result.\n\n[Recommended: your preference]"); + lblEnhancement->SetToolTip(tooltip); + cmbEnhEnhancement->SetToolTip(tooltip); + cmbEnhEnhancement->SetSelection(settings.ghq_enht); + tooltip = _("Texture cache size:\nEnhanced and filtered textures can be cached to aid performance.\nThis setting will adjust how much PC memory will be dedicated for texture cache.\nThis helps boost performance if there are subsequent requests for the same texture (usually the case).\nNormally, 128MB should be more than enough but there is a sweet spot for each game.\nSuper Mario may not need more than 32megs, but Conker streams a lot of textures,\nso setting 256+ megs can boost performance. Adjust accordingly if you are encountering speed issues.\n'0' disables cache.\n[Recommended: PC and game dependant]"); + lblTexCache->SetToolTip(tooltip); + lblTexCacheMB->SetToolTip(tooltip); + spinEnhCacheSize->SetToolTip(tooltip); + spinEnhCacheSize->SetMinSize(wxSize(55, 21)); + spinEnhCacheSize->SetValue(settings.ghq_cache_size); + cbxEnhIgnoreBG->SetToolTip(_("Ignore Backgrounds:\nIt is used to skip enhancement for long narrow textures, usually used for backgrounds.\nThis may save texture memory greatly and increase performance.\n[Recommended: on (off for 'Store' mode)]")); + cbxEnhIgnoreBG->SetValue(settings.ghq_enht_nobg>0); + tooltip = _("Texture compression:\nTextures will be compressed using selected texture compression method.\nThe overall compression ratio is about 1/6 for FXT1 and 1/4 for S3TC.\nIn addition to saving space on the texture cache,\nthe space occupied on the GFX hardware's texture RAM,\nby the enhanced textures, will be greatly reduced.\nThis minimizes texture RAM usage,\ndecreasing the number of texture swaps to the GFX hardware leading to performance gains.\nHowever, due to the nature of lossy compression of FXT1 and S3TC, using this option can sometimes lead to quality degradation of small size textures and color banding of gradient colored textures.\n[Recommended: off]"); + cbxEnhTexCompression->SetToolTip(tooltip); + cbxHrsTexCompression->SetToolTip(tooltip); + cbxEnhTexCompression->SetValue(settings.ghq_enht_cmpr>0); + cbxEnhCompressCache->SetToolTip(_("Compress texture cache:\nMemory will be compressed so that more textures can be held in the texture cache.\nThe compression ratio varies with each texture,\nbut 1/5 of the original size would be a modest approximation.\nThey will be decompressed on-the-fly, before being downloaded to the gfx hardware.\nThis option will still help save memory space even when using texture compression.\n[Recommended: on]")); + cbxEnhCompressCache->SetValue(settings.ghq_enht_gz>0); + tooltip = _("Hi-res pack format:\nChoose which method is to be used for loading Hi-res texture packs.\nOnly Rice's format is available currently.\nLeave on \"None\" if you will not be needing to load hi-res packs.\n[Recommended: Rice's format. Default: \"None\"]"); + lblHrsFormat->SetToolTip(tooltip); + cmbHrsFormat->SetToolTip(tooltip); + cmbHrsFormat->SetSelection(settings.ghq_hirs); + cbxHrsTile->SetToolTip(_("Tile textures:\nWhen on, wide texture will be split on several tiles to fit in one 256-width texture.\nThis tiled texture takes much less video memory space and thus overall performance will increase.\nHowever, corresponding polygons must be split too, and this is not polished yet\n- various issues are possible, including black lines and polygons distortions.\n[Recommended: off]")); + cbxHrsTile->SetValue(settings.ghq_hirs_tile>0); + cbxHrsForce16->SetToolTip(_("Force 16bpp textures:\nThe color of the textures will be reduced to 16bpp.\nThis is another space saver and performance enhancer.\nThis halves the space used on the texture cache and the GFX hardware's texture RAM.\nColor reduction is done so that the original quality is preserved as much as possible.\nDepending on the texture, this usually is hardly noticeable.\nSometimes though, it can be: skies are a good example.\n[Recommended: off]")); + cbxHrsForce16->SetValue(settings.ghq_hirs_f16bpp>0); + cbxHrsTexEdit->SetToolTip(_("Texture dumping mode:\nIn this mode, you have that ability to dump textures on screen to the appropriate folder.\nYou can also reload textures while the game is running to see how they look instantly - big time saver!\n\nHotkeys: \"R\" reloads hires textures from the texture pack - \"D\" toggles texture dumps on/off.")); + cbxHrsTexEdit->SetValue(settings.ghq_hirs_dump>0); + cbxHrsAltCRC->SetToolTip(_("Alternative CRC calculation:\nThis option enables emulation of a palette CRC calculation bug in RiceVideo.\nIf some textures are not loaded, try to set this option on/off.\n[Recommended: texture pack dependant, mostly on]")); + cbxHrsAltCRC->SetValue(settings.ghq_hirs_altcrc>0 && settings.ghq_hirs_dump==0); + if (settings.ghq_hirs_dump) + cbxHrsAltCRC->Disable(); + cbxHrsTexCompression->SetValue(settings.ghq_hirs_cmpr>0); + cbxHrsCompressCache->SetToolTip(_("Compress texture cache:\nWhen game started, plugin loads all its hi-resolution textures into PC memory.\nSince hi-resolution textures are usually large, the whole pack can take hundreds megabytes of memory.\nCache compression allows save memory space greatly.\nTextures will be decompressed on-the-fly, before being downloaded to the gfx hardware.\nThis option will still help save memory space even when using texture compression.\n[Recommended: on]")); + cbxHrsCompressCache->SetValue(settings.ghq_hirs_gz>0); + cbxHrsLetFly->SetToolTip(_("Use Alpha channel fully:\nWhen this option is off, 16bit rgba textures will be loaded using RiceVideo style\n- with 1bit for alpha channel.\nWhen it is on, GlideHQ will check, how alpha channel is used by the hires texture,\nand select most appropriate format for it.\nThis gives texture designers freedom to play with alpha, as they need,\nregardless of format of original N64 texture.\nFor older and badly designed texture packs it can cause unwanted black borders.\n[Recommended: texture pack dependant]")); + cbxHrsLetFly->SetValue(settings.ghq_hirs_let_texartists_fly>0); + cmbTextureCompression->SetSelection(settings.ghq_cmpr); + cbxSaveTexCache->SetToolTip(_("Save texture cache to HD:\n\nFor enhanced textures cache:\nThis will save all previously loaded and enhanced textures to HD.\nSo upon next game launch, all the textures will be instantly loaded, resulting in smoother performance.\n\nFor high-resolution textures cache:\nAfter creation, loading hi-res texture will take only a few seconds upon game launch,\nas opposed to the 5 -60 seconds a pack can take to load without this cache file.\nThe only downside here is upon any changes to the pack, the cache file will need to be manually deleted.\n\nSaved cache files go into a folder called \"Cache\" within the Plugins folder.\n\n[Highly Recommended: on]")); + cbxSaveTexCache->SetValue(settings.ghq_cache_save>0); + TexturePanel->SetMinSize(wxSize(526, 494)); + + if (!voodoo.sup_32bit_tex) + { + settings.ghq_cmpr = 0; + settings.ghq_enht_cmpr = settings.ghq_hirs_cmpr = FALSE; + settings.ghq_enht_f16bpp = settings.ghq_hirs_f16bpp = TRUE; + lblTexCompression->Disable(); + cmbTextureCompression->SetSelection(0); + cmbTextureCompression->Disable(); + cbxEnhTexCompression->SetValue(false); + cbxEnhTexCompression->Disable(); + cbxHrsTexCompression->SetValue(false); + cbxHrsTexCompression->Disable(); + cbxHrsForce16->SetValue(false); + cbxHrsForce16->Disable(); + } + } +#endif //TEXTURE_FILTER + +#ifndef _ENDUSER_RELEASE_ + AddPage(DebugPanel, _("Debug")); + cbxAutoUcode->SetToolTip(_("Autodetect Microcode\nIf this option is checked, the microcode of the game\nwill be detected automatically from the INI, and\ntherefore it will not need to be set in this\nconfiguration dialog.\n[Recommended: on]")); + cbxAutoUcode->SetValue(settings.autodetect_ucode>0); + tooltip = _("Force Microcode\nThis option ONLY has an effect if Autodetect Microcode\nis unchecked, the crc from the game could not be\nfound in the INI, OR after the game has already started\nrunning. In any of those three cases, this will\nselect the microcode to use\n[Recommended: any, turn on Autodetect Microcode]"); + lblForceUcode->SetToolTip(tooltip); + cmbForceUcode->SetToolTip(tooltip); + cmbForceUcode->SetSelection(settings.ucode); + cbxWireframe->SetToolTip(_("Wireframe\nThis option, when checked, makes it so that the plugin will draw only the\noutlines of objects. The colors specified in the combo box to the right\ndetermines the color that the wireframes show up as.\n[Recommended: off]")); + cbxWireframe->SetValue(settings.wireframe>0); + cmbWireframe->SetToolTip(_("Wireframe Colors\nThis selects the colors to use for the wireframes (if wireframe mode is enabled).\nThere are 3 modes:\n* Original colors - draw exactly as it would normally, textures and all, only in wireframes.\n* Vertex colors - use the colors specified in the vertices to draw the wireframes with.\n* Red only - use a constant red color to draw the wireframes.\n[Recommended: Vertex colors]")); + cmbWireframe->SetSelection(settings.wfmode); + cbxLog->SetToolTip(_("Log to RDP.txt\nRECOMMENDED FOR DEBUGGING ONLY - this option, when checked, will log EVERY SINGLE\nCOMMAND the plugin processes to a file called RDP.txt in the current directory.\nThis is incredibly slow, so I recommend keeping it disabled.\n[Recommended: off]")); + cbxLog->SetValue(settings.logging>0); + cbxCombRed->SetToolTip(_("Unknown combiners as red\nObjects that use an unimplemented combine mode will show up as red instead of\nassuming texture with full alpha. Disable this option to remove the red stuff\nand at least have a guess at the correct combine mode.\n[Recommended: off]")); + cbxCombRed->SetValue(settings.unk_as_red>0); + cbxLogClear->SetToolTip(_("Log clear every frame\nRECOMMENDED FOR DEBUGGING ONLY - this option has no effect unless 'Log to RDP.txt'\nis checked. This will make it so that the log, RDP.txt, will be cleared at the\nbeginning of every frame.\n[Recommended: off]")); + cbxLogClear->SetValue(settings.log_clear>0); + cbxCmbLog->SetToolTip(_("Log unknown combiners\nRECOMMENDED FOR DEBUGGING ONLY - when checked, this option will cause every\nunimplemented combiner drawn to be logged to a file called Unimp.txt in the\ncurrent directory. This becomes slow when there are unimplemented combiners\non the screen, so I recommend keeping it disabled.\n[Recommended: off]")); + cbxCmbLog->SetValue(settings.log_unk>0); + cbxWindowLog->SetToolTip(_("Run and log in window\nRECOMMENDED FOR DEBUGGING ONLY - this option will make it so that the plugin will\nstill process dlists in windowed mode. This allows for logging to occur while not\nin fullscreen, possibly allowing you to debug a crash.\n[Recommended: off]")); + cbxWindowLog->SetValue(settings.run_in_window>0); + cbxCmbLogClear->SetToolTip(_("Clear unknown combiner log every frame\nRECOMMENDED FOR DEBUGGING ONLY - this option works much like 'Log clear every frame'\nexcept it clears the combiner log (Unimp.txt) instead of RDP.txt at the\nbeginning of each frame. Again, this option has no effect if 'combiner logging' is disabled.\n[Recommended: off]")); + cbxCmbLogClear->SetValue(settings.unk_clear>0); + cbxErrLog->SetValue(settings.elogging>0); + cbxBilinearTexCache->SetToolTip(_("Bilinear filter texture cache\nRECOMMENDED FOR DEBUGGING ONLY - when checked, this option will make the graphical\ndebugger texture cache use bilinear filtering as opposed to point-sampled filtering,\nwhich it will use otherwise. See 'Filtering mode' for descriptions of bilinear and\npoint-sampled filtering.\n[Recommended: off]")); + cbxBilinearTexCache->SetValue(settings.filter_cache>0); +#endif //_ENDUSER_RELEASE_ + // end wxGlade +} + + +void ConfigNotebook::do_layout() +{ + // begin wxGlade: ConfigNotebook::do_layout + + //Basic panel + wxBoxSizer* ConfigMainSizer = new wxBoxSizer(wxVERTICAL); + wxStaticBoxSizer* OtherSizer = new wxStaticBoxSizer(OtherSizer_staticbox, wxVERTICAL); + wxBoxSizer* OtherOtherSizer = new wxBoxSizer(wxHORIZONTAL); + wxBoxSizer* ScreenShotFormatSizer = new wxBoxSizer(wxHORIZONTAL); + wxBoxSizer* ShowPanelsSizer = new wxBoxSizer(wxHORIZONTAL); + wxBoxSizer* ConfigUpperSizer = new wxBoxSizer(wxHORIZONTAL); + wxStaticBoxSizer* OnScreenInfoSizer = new wxStaticBoxSizer(OnScreenDisplaySizer_staticbox, wxHORIZONTAL); + wxBoxSizer* InfoMainSizer = new wxBoxSizer(wxVERTICAL); + wxStaticBoxSizer* TimeSizer = new wxStaticBoxSizer(TimeSizer_staticbox, wxVERTICAL); + wxStaticBoxSizer* SpeedSizer = new wxStaticBoxSizer(SpeedSizer_staticbox, wxVERTICAL); + wxBoxSizer* BasicLeftSizer = new wxBoxSizer(wxVERTICAL); + wxStaticBoxSizer* BasicRenderingSizer = new wxStaticBoxSizer(BasicRenderingSizer_staticbox, wxVERTICAL); + wxStaticBoxSizer* WrapperSizer = new wxStaticBoxSizer(WrapperSizer_staticbox, wxVERTICAL); + wxStaticBoxSizer* WrapperFBOptionsSizer = new wxStaticBoxSizer(WrapperFBOptionsSizer_staticbox, wxVERTICAL); + wxBoxSizer* VRAMSizer = new wxBoxSizer(wxHORIZONTAL); + wxBoxSizer* FSResolutionSizer = new wxBoxSizer(wxHORIZONTAL); + wxBoxSizer* ResolutionSizer = new wxBoxSizer(wxHORIZONTAL); + ResolutionSizer->Add(lblResolution, 1, wxALIGN_CENTER_VERTICAL, 0); + ResolutionSizer->Add(20, 20, 0, 0, 0); + ResolutionSizer->Add(cmbResolution, 0, wxALIGN_CENTER_VERTICAL, 0); + BasicRenderingSizer->Add(ResolutionSizer, 0, wxTOP|wxBOTTOM, 10); + BasicRenderingSizer->Add(cbxVSync, 0, wxBOTTOM, 10); + FSResolutionSizer->Add(lblFSResolution, 1, wxALIGN_CENTER_VERTICAL, 0); + FSResolutionSizer->Add(20, 20, 0, 0, 0); + FSResolutionSizer->Add(cmbFSResolution, 0, 0, 0); + WrapperSizer->Add(FSResolutionSizer, 0, wxTOP|wxBOTTOM, 10); + WrapperSizer->Add(cbxAnisotropic, 0, wxBOTTOM, 10); + VRAMSizer->Add(cbxVRAM, 0, wxALIGN_CENTER_VERTICAL, 0); + VRAMSizer->Add(lblVRAM, 0, wxALIGN_CENTER_VERTICAL, 0); + VRAMSizer->Add(spinVRAM, 0, wxLEFT, 10); + VRAMSizer->Add(lblMb, 0, wxLEFT|wxALIGN_BOTTOM, 3); + WrapperSizer->Add(VRAMSizer, 0, wxBOTTOM|wxEXPAND, 10); + WrapperFBOptionsSizer->Add(cbxFBO, 0, wxTOP|wxBOTTOM, 10); + WrapperSizer->Add(WrapperFBOptionsSizer, 0, wxEXPAND, 0); + BasicRenderingSizer->Add(WrapperSizer, 0, wxEXPAND, 0); + BasicLeftSizer->Add(BasicRenderingSizer, 1, wxEXPAND, 0); + ConfigUpperSizer->Add(BasicLeftSizer, 1, wxLEFT|wxRIGHT|wxEXPAND, 10); + SpeedSizer->Add(cbxFPS, 0, wxTOP|wxBOTTOM, 10); + SpeedSizer->Add(cbxVIS, 0, wxBOTTOM, 10); + SpeedSizer->Add(cbxPercent, 0, wxBOTTOM, 10); + InfoMainSizer->Add(SpeedSizer, 0, wxALL|wxEXPAND, 10); + TimeSizer->Add(cbxClockEnabled, 0, wxTOP|wxBOTTOM, 10); + TimeSizer->Add(cbxClock24, 0, wxBOTTOM, 10); + InfoMainSizer->Add(TimeSizer, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND, 10); + InfoMainSizer->Add(cbxTextTransparent, 0, wxLEFT|wxTOP, 15); + OnScreenInfoSizer->Add(InfoMainSizer, 1, wxEXPAND, 0); + ConfigUpperSizer->Add(OnScreenInfoSizer, 1, wxLEFT|wxRIGHT|wxEXPAND, 10); + ConfigMainSizer->Add(ConfigUpperSizer, 1, wxEXPAND, 0); + ShowPanelsSizer->Add(cbxAdvancedSettings, 1, 0, 10); + ShowPanelsSizer->Add(cbxTextureSettings, 1, wxLEFT, 10); + OtherSizer->Add(ShowPanelsSizer, 0, wxTOP|wxBOTTOM|wxEXPAND, 10); + ScreenShotFormatSizer->Add(lblScreenShotFormat, 0, 0, 0); + ScreenShotFormatSizer->Add(20, 20, 0, 0, 0); + ScreenShotFormatSizer->Add(cmbScreenShotFormat, 0, 0, 0); + OtherOtherSizer->Add(ScreenShotFormatSizer, 1, wxALIGN_CENTER_VERTICAL, 0); + OtherOtherSizer->Add(btnLanguage, 1, wxLEFT, 10); + OtherSizer->Add(OtherOtherSizer, 0, wxEXPAND, 0); + ConfigMainSizer->Add(OtherSizer, 0, wxALL|wxEXPAND, 10); + BasicSettingsPanel->SetSizer(ConfigMainSizer); + + //emulation settings panel + if (settings.advanced_options) + { + wxStaticBoxSizer* EmuSettingsBoxSizer = new wxStaticBoxSizer(EmuSettingsBoxSizer_staticbox, wxHORIZONTAL); + wxBoxSizer* EmuSettingsMainSizer = new wxBoxSizer(wxHORIZONTAL); + wxBoxSizer* EmuSettingsRightSizer = new wxBoxSizer(wxVERTICAL); + wxStaticBoxSizer* DepthBufferSizer = new wxStaticBoxSizer(DepthBufferSizer_staticbox, wxHORIZONTAL); + wxStaticBoxSizer* FrameBufferSizer = new wxStaticBoxSizer(FrameBufferSizer_staticbox, wxVERTICAL); + wxBoxSizer* HWFBESizer = new wxBoxSizer(wxHORIZONTAL); + wxStaticBoxSizer* EmuSettingsLeftSizer = new wxStaticBoxSizer(EmuSettingsLeftSizer_staticbox, wxVERTICAL); + wxBoxSizer* AspectSizer = new wxBoxSizer(wxHORIZONTAL); + wxBoxSizer* LODSizer = new wxBoxSizer(wxHORIZONTAL); + wxBoxSizer* SwappingSizer = new wxBoxSizer(wxHORIZONTAL); + wxBoxSizer* FilteringSizer = new wxBoxSizer(wxHORIZONTAL); + FilteringSizer->Add(lbFiltering, 0, 0, 0); + FilteringSizer->Add(20, 20, 0, 0, 0); + FilteringSizer->Add(cmbFiltering, 0, 0, 0); + EmuSettingsLeftSizer->Add(FilteringSizer, 1, wxTOP, 10); + SwappingSizer->Add(lbBufferSwap, 0, 0, 0); + SwappingSizer->Add(20, 20, 0, 0, 0); + SwappingSizer->Add(cmbBufferSwap, 0, 0, 0); + EmuSettingsLeftSizer->Add(SwappingSizer, 1, 0, 0); + LODSizer->Add(lblLOD, 0, 0, 0); + LODSizer->Add(20, 20, 0, 0, 0); + LODSizer->Add(cmbLOD, 0, 0, 0); + EmuSettingsLeftSizer->Add(LODSizer, 1, 0, 0); + AspectSizer->Add(lblAspect, 0, 0, 0); + AspectSizer->Add(20, 20, 0, 0, 0); + AspectSizer->Add(cmbAspect, 0, 0, 0); + EmuSettingsLeftSizer->Add(AspectSizer, 1, 0, 0); + EmuSettingsLeftSizer->Add(cbxFog, 1, 0, 0); + EmuSettingsLeftSizer->Add(cbxBuffer, 1, 0, 0); + EmuSettingsMainSizer->Add(EmuSettingsLeftSizer, 1, wxLEFT|wxRIGHT|wxEXPAND, 10); + FrameBufferSizer->Add(cbxFBEnable, 1, wxTOP|wxBOTTOM, 10); + HWFBESizer->Add(30, 20, 0, 0, 0); + HWFBESizer->Add(cbxFBHWFBE, 0, 0, 0); + FrameBufferSizer->Add(HWFBESizer, 0, wxBOTTOM, 10); + FrameBufferSizer->Add(cbxFBGetFBI, 1, wxBOTTOM, 10); + FrameBufferSizer->Add(cbxFBReadEveryFrame, 1, wxBOTTOM, 10); + FrameBufferSizer->Add(cbxFBasTex, 1, wxBOTTOM, 10); + FrameBufferSizer->Add(cbxDetect, 1, wxBOTTOM, 10); + EmuSettingsRightSizer->Add(FrameBufferSizer, 1, wxEXPAND, 0); + DepthBufferSizer->Add(cbxFBDepthBuffer, 0, wxTOP|wxBOTTOM, 10); + EmuSettingsRightSizer->Add(DepthBufferSizer, 0, wxTOP|wxEXPAND, 10); + EmuSettingsMainSizer->Add(EmuSettingsRightSizer, 1, wxLEFT|wxRIGHT|wxEXPAND, 10); + EmuSettingsBoxSizer->Add(EmuSettingsMainSizer, 1, wxTOP|wxBOTTOM|wxEXPAND, 10); + EmuSettingsPanel->SetSizer(EmuSettingsBoxSizer); + } + +#ifdef TEXTURE_FILTER + if (settings.texenh_options) + { + wxBoxSizer* TextureMainSizer = new wxBoxSizer(wxVERTICAL); + wxStaticBoxSizer* PresetsSizer = new wxStaticBoxSizer(PresetsSizer_staticbox, wxHORIZONTAL); + wxStaticBoxSizer* CommonSizer = new wxStaticBoxSizer(CommonSizer_staticbox, wxHORIZONTAL); + wxBoxSizer* TexCompressionSizer = new wxBoxSizer(wxHORIZONTAL); + wxBoxSizer* TexLeftSizer = new wxBoxSizer(wxHORIZONTAL); + wxStaticBoxSizer* TextureRightSizer = new wxStaticBoxSizer(TextureRightSizer_staticbox, wxVERTICAL); + wxStaticBoxSizer* HRTexPerfTweaksSizer = new wxStaticBoxSizer(HRTexPerfTweaksSizer_staticbox, wxVERTICAL); + wxBoxSizer* FormatSizer = new wxBoxSizer(wxHORIZONTAL); + wxStaticBoxSizer* EnhTexSizer = new wxStaticBoxSizer(EnhTexSizer_staticbox, wxVERTICAL); + wxStaticBoxSizer* EnhTexPerfTweaksSizer = new wxStaticBoxSizer(EnhTexPerfTweaksSizer_staticbox, wxVERTICAL); + wxBoxSizer* TexCacheSizer = new wxBoxSizer(wxHORIZONTAL); + wxBoxSizer* EnhSizer = new wxBoxSizer(wxHORIZONTAL); + wxBoxSizer* FilterSizer = new wxBoxSizer(wxHORIZONTAL); + FilterSizer->Add(lblFilter, 0, 0, 0); + FilterSizer->Add(20, 20, 0, 0, 0); + FilterSizer->Add(cmbEnhFilter, 0, 0, 0); + EnhTexSizer->Add(FilterSizer, 0, wxTOP|wxBOTTOM|wxEXPAND, 10); + EnhSizer->Add(lblEnhancement, 0, 0, 0); + EnhSizer->Add(20, 20, 0, 0, 0); + EnhSizer->Add(cmbEnhEnhancement, 0, 0, 0); + EnhTexSizer->Add(EnhSizer, 0, wxBOTTOM|wxEXPAND, 10); + TexCacheSizer->Add(lblTexCache, 0, 0, 0); + TexCacheSizer->Add(20, 20, 0, 0, 0); + TexCacheSizer->Add(spinEnhCacheSize, 0, 0, 0); + TexCacheSizer->Add(lblTexCacheMB, 0, wxLEFT|wxALIGN_BOTTOM, 4); + EnhTexSizer->Add(TexCacheSizer, 0, wxBOTTOM|wxEXPAND, 10); + EnhTexSizer->Add(cbxEnhCompressCache, 0, wxBOTTOM, 10); + EnhTexPerfTweaksSizer->Add(cbxEnhTexCompression, 0, wxTOP|wxBOTTOM, 10); + EnhTexPerfTweaksSizer->Add(cbxEnhIgnoreBG, 0, wxBOTTOM, 10); + EnhTexSizer->Add(EnhTexPerfTweaksSizer, 1, wxEXPAND, 0); + TexLeftSizer->Add(EnhTexSizer, 1, wxALL|wxEXPAND, 10); + FormatSizer->Add(lblHrsFormat, 0, 0, 0); + FormatSizer->Add(20, 20, 0, 0, 0); + FormatSizer->Add(cmbHrsFormat, 0, 0, 0); + TextureRightSizer->Add(FormatSizer, 0, wxTOP|wxBOTTOM|wxEXPAND, 10); + TextureRightSizer->Add(cbxHrsAltCRC, 0, wxBOTTOM, 10); + TextureRightSizer->Add(cbxHrsTexEdit, 0, wxBOTTOM, 10); + TextureRightSizer->Add(cbxHrsLetFly, 0, wxBOTTOM, 10); + TextureRightSizer->Add(cbxHrsCompressCache, 0, wxBOTTOM, 10); + HRTexPerfTweaksSizer->Add(cbxHrsTexCompression, 0, wxTOP|wxBOTTOM, 10); + HRTexPerfTweaksSizer->Add(cbxHrsForce16, 0, wxBOTTOM, 10); + HRTexPerfTweaksSizer->Add(cbxHrsTile, 0, wxBOTTOM, 10); + TextureRightSizer->Add(HRTexPerfTweaksSizer, 1, wxEXPAND, 0); + TexLeftSizer->Add(TextureRightSizer, 1, wxALL|wxEXPAND, 10); + TextureMainSizer->Add(TexLeftSizer, 1, wxEXPAND, 0); + TexCompressionSizer->Add(lblTexCompression, 0, wxALIGN_CENTER_VERTICAL, 0); + TexCompressionSizer->Add(20, 20, 0, 0, 0); + TexCompressionSizer->Add(cmbTextureCompression, 0, 0, 0); + CommonSizer->Add(TexCompressionSizer, 1, wxBOTTOM|wxEXPAND, 10); + CommonSizer->Add(cbxSaveTexCache, 1, wxLEFT|wxEXPAND, 15); + TextureMainSizer->Add(CommonSizer, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND, 10); + PresetsSizer->Add(btnPerformance, 1, wxEXPAND|wxALIGN_CENTER_VERTICAL, 0); + PresetsSizer->Add(60, 20, 0, 0, 0); + PresetsSizer->Add(btnQuality, 1, wxEXPAND|wxALIGN_CENTER_VERTICAL, 0); + TextureMainSizer->Add(PresetsSizer, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND, 10); + TexturePanel->SetSizer(TextureMainSizer); + } +#endif //TEXTURE_FILTER + +#ifndef _ENDUSER_RELEASE_ + wxBoxSizer* DebugMainSizer = new wxBoxSizer(wxVERTICAL); + wxStaticBoxSizer* DebugSizer = new wxStaticBoxSizer(DebugSizer_staticbox, wxVERTICAL); + wxGridSizer* DebugOptionsSizer = new wxGridSizer(4, 2, 0, 0); + wxStaticBoxSizer* DevSettingsSizer = new wxStaticBoxSizer(DevSettingsSizer_staticbox, wxVERTICAL); + wxBoxSizer* WireframeSizer = new wxBoxSizer(wxHORIZONTAL); + wxBoxSizer* ForceUcodeSizer = new wxBoxSizer(wxHORIZONTAL); + DevSettingsSizer->Add(cbxAutoUcode, 1, 0, 0); + ForceUcodeSizer->Add(lblForceUcode, 0, 0, 0); + ForceUcodeSizer->Add(20, 20, 0, 0, 0); + ForceUcodeSizer->Add(cmbForceUcode, 0, 0, 0); + DevSettingsSizer->Add(ForceUcodeSizer, 1, wxEXPAND, 0); + WireframeSizer->Add(cbxWireframe, 0, 0, 0); + WireframeSizer->Add(20, 20, 0, 0, 0); + WireframeSizer->Add(cmbWireframe, 0, 0, 0); + DevSettingsSizer->Add(WireframeSizer, 1, wxEXPAND, 0); + DebugMainSizer->Add(DevSettingsSizer, 1, wxALL|wxEXPAND, 10); + DebugOptionsSizer->Add(cbxLog, 0, wxTOP, 5); + DebugOptionsSizer->Add(cbxCombRed, 0, wxTOP, 5); + DebugOptionsSizer->Add(cbxLogClear, 0, 0, 10); + DebugOptionsSizer->Add(cbxCmbLog, 0, 0, 10); + DebugOptionsSizer->Add(cbxWindowLog, 0, 0, 10); + DebugOptionsSizer->Add(cbxCmbLogClear, 0, 0, 10); + DebugOptionsSizer->Add(cbxErrLog, 0, 0, 0); + DebugOptionsSizer->Add(cbxBilinearTexCache, 0, 0, 0); + DebugSizer->Add(DebugOptionsSizer, 1, wxEXPAND, 0); + DebugMainSizer->Add(DebugSizer, 1, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND, 10); + DebugPanel->SetSizer(DebugMainSizer); +#endif //_ENDUSER_RELEASE_ + // end wxGlade +} + +void ConfigNotebook::SaveSettings() +{ + SETTINGS oldsettings = settings; + int is_advanced_changed = 0; + if (settings.advanced_options) + { + settings.filtering = cmbFiltering->GetSelection(); + settings.aspectmode = cmbAspect->GetSelection(); + settings.swapmode = cmbBufferSwap->GetSelection(); + settings.fog = (int)cbxFog->GetValue(); + settings.buff_clear = cbxBuffer->GetValue(); + settings.lodmode = cmbLOD->GetSelection(); + + if (cbxFBEnable->GetValue()) settings.frame_buffer |= fb_emulation; + else settings.frame_buffer &= ~fb_emulation; + if (cbxFBHWFBE->GetValue()) settings.frame_buffer |= fb_hwfbe; + else settings.frame_buffer &= ~fb_hwfbe; + if (cbxFBReadEveryFrame->GetValue()) settings.frame_buffer |= fb_ref; + else settings.frame_buffer &= ~fb_ref; + if (cbxFBasTex->GetValue()) settings.frame_buffer |= fb_read_back_to_screen; + else settings.frame_buffer &= ~fb_read_back_to_screen; + if (cbxDetect->GetValue()) settings.frame_buffer |= fb_cpu_write_hack; + else settings.frame_buffer &= ~fb_cpu_write_hack; + if (cbxFBGetFBI->GetValue()) settings.frame_buffer |= fb_get_info; + else settings.frame_buffer &= ~fb_get_info; + if (cbxFBDepthBuffer->GetValue()) settings.frame_buffer |= fb_depth_render; + else settings.frame_buffer &= ~fb_depth_render; + is_advanced_changed = memcmp(&oldsettings, &settings, sizeof(SETTINGS)); + } + + settings.lang_id = lang_id; + settings.res_data = cmbResolution->GetSelection(); + settings.res_data_org = settings.res_data; + settings.scr_res_x = settings.res_x = resolutions[settings.res_data][0]; + settings.scr_res_y = settings.res_y = resolutions[settings.res_data][1]; + settings.vsync = (int)cbxVSync->GetValue(); + settings.ssformat = cmbScreenShotFormat->GetSelection(); + settings.show_fps = + (cbxFPS->GetValue()?1:0) | + (cbxVIS->GetValue()?2:0) | + (cbxPercent->GetValue()?4:0) | + (cbxTextTransparent->GetValue()?8:0); + settings.clock = (int)cbxClockEnabled->GetValue(); + settings.clock_24_hr = (int)cbxClock24->GetValue(); + + settings.wrpResolution = cmbFSResolution->GetSelection(); + settings.wrpVRAM = cbxVRAM->GetValue()? 0 : spinVRAM->GetValue(); + settings.wrpFBO = cbxFBO->GetValue(); + settings.wrpAnisotropic = cbxAnisotropic->GetValue(); + +#ifdef TEXTURE_FILTER + if (settings.texenh_options) + { + settings.ghq_fltr = cmbEnhFilter->GetSelection(); + settings.ghq_enht = cmbEnhEnhancement->GetSelection(); + settings.ghq_cache_size = spinEnhCacheSize->GetValue(); + settings.ghq_enht_nobg = (int)cbxEnhIgnoreBG->GetValue(); + settings.ghq_enht_cmpr = (int)cbxEnhTexCompression->GetValue(); + settings.ghq_enht_gz = (int)cbxEnhCompressCache->GetValue(); + settings.ghq_hirs = cmbHrsFormat->GetSelection(); + settings.ghq_hirs_tile = (int)cbxHrsTile->GetValue(); + settings.ghq_hirs_f16bpp = (int)cbxHrsForce16->GetValue(); + settings.ghq_hirs_dump = (int)cbxHrsTexEdit->GetValue(); + settings.ghq_hirs_altcrc = (int)cbxHrsAltCRC->GetValue(); + settings.ghq_hirs_cmpr = (int)cbxHrsTexCompression->GetValue(); + settings.ghq_hirs_gz = (int)cbxHrsCompressCache->GetValue(); + settings.ghq_hirs_let_texartists_fly = (int)cbxHrsLetFly->GetValue(); + settings.ghq_cmpr = (int)cmbTextureCompression->GetSelection(); + settings.ghq_cache_save = (int)cbxSaveTexCache->GetValue(); + } +#endif //TEXTURE_FILTER + + settings.advanced_options = (int)cbxAdvancedSettings->GetValue(); + settings.texenh_options = (int)cbxTextureSettings->GetValue(); + +#ifndef _ENDUSER_RELEASE_ + settings.autodetect_ucode = (int)cbxAutoUcode->GetValue(); + settings.ucode = cmbForceUcode->GetSelection(); + settings.wireframe = (int)cbxWireframe->GetValue(); + settings.wfmode = cmbWireframe->GetSelection(); + settings.logging = (int)cbxLog->GetValue(); + settings.unk_as_red = (int)cbxCombRed->GetValue(); + settings.log_clear = (int)cbxLogClear->GetValue(); + settings.log_unk = (int)cbxCmbLog->GetValue(); + settings.run_in_window = (int)cbxWindowLog->GetValue(); + settings.unk_clear = (int)cbxCmbLogClear->GetValue(); + settings.elogging = (int)cbxErrLog->GetValue(); + settings.filter_cache = (int)cbxBilinearTexCache->GetValue(); +#endif //_ENDUSER_RELEASE_ + + if (memcmp(&oldsettings, &settings, sizeof(SETTINGS))) //check that settings were changed + { + if (romopen) + { + if (is_advanced_changed) + { + wxMessageDialog dialog( this, _T("Current game emulation settings changed. Save the settings permanently?\nSelect 'No' to use the settings without save."), + _T("Save settings"), wxNO_DEFAULT|wxYES_NO|wxICON_QUESTION); + WriteSettings (dialog.ShowModal() == wxID_YES); + } + else + WriteSettings (false); + } + else + WriteSettings (is_advanced_changed != 0); + } + void ConfigWrapper(); + ConfigWrapper(); +} + +Glide64ConfigDialog::Glide64ConfigDialog(wxWindow* parent, int id, const wxString& title, const wxPoint& pos, const wxSize& size, long style): +wxDialog(parent, id, title, pos, size, wxDEFAULT_DIALOG_STYLE) +{ + // begin wxGlade: Glide64ConfigDialog::Glide64ConfigDialog + Config = new ConfigNotebook(this, wxID_ANY); + btnOK = new wxButton(this, wxID_OK, wxEmptyString); + btnCancel = new wxButton(this, wxID_CANCEL, wxEmptyString); + + set_properties(); + do_layout(); + // end wxGlade +} + + +BEGIN_EVENT_TABLE(Glide64ConfigDialog, wxDialog) +// begin wxGlade: Glide64ConfigDialog::event_table +// EVT_NOTEBOOK_PAGE_CHANGED(wxID_ANY, Glide64ConfigDialog::onPageChanged) +// EVT_NOTEBOOK_PAGE_CHANGING(wxID_ANY, Glide64ConfigDialog::onPageChanging) +EVT_BUTTON(wxID_OK, Glide64ConfigDialog::OnOK) +EVT_BUTTON(wxID_CANCEL, Glide64ConfigDialog::OnCancel) +EVT_CLOSE(Glide64ConfigDialog::OnClose) +// end wxGlade +END_EVENT_TABLE(); + +/* +void Glide64ConfigDialog::onPageChanged(wxNotebookEvent &event) +{ +event.Skip(); +wxLogDebug(wxT("Event handler (Glide64ConfigDialog::onPageChanged) not implemented yet")); //notify the user that he hasn't implemented the event handler yet +} + + +void Glide64ConfigDialog::onPageChanging(wxNotebookEvent &event) +{ +event.Skip(); +wxLogDebug(wxT("Event handler (Glide64ConfigDialog::onPageChanging) not implemented yet")); //notify the user that he hasn't implemented the event handler yet +} +*/ +void CloseConfig(); + +void Glide64ConfigDialog::OnClose(wxCloseEvent& event) +{ + event.Skip(); + CloseConfig(); + // wxLogDebug(wxT("Event handler (MyDialog::OnCancel) not implemented yet")); //notify the user that he hasn't implemented the event handler yet +} + +void Glide64ConfigDialog::OnOK(wxCommandEvent &event) +{ + Config->SaveSettings(); + event.Skip(); + CloseConfig(); + // wxLogDebug(wxT("Event handler (Glide64ConfigDialog::OnOK) not implemented yet")); //notify the user that he hasn't implemented the event handler yet +} + + +void Glide64ConfigDialog::OnCancel(wxCommandEvent &event) +{ + event.Skip(); + CloseConfig(); + // wxLogDebug(wxT("Event handler (Glide64ConfigDialog::OnCancel) not implemented yet")); //notify the user that he hasn't implemented the event handler yet +} + + +// wxGlade: add Glide64ConfigDialog event handlers + + +void Glide64ConfigDialog::set_properties() +{ + // begin wxGlade: Glide64ConfigDialog::set_properties + SetTitle(_("Glide64 settings")); + // end wxGlade +} + + +void Glide64ConfigDialog::do_layout() +{ + // begin wxGlade: Glide64ConfigDialog::do_layout + wxBoxSizer* MainSizer = new wxBoxSizer(wxVERTICAL); + wxBoxSizer* MainSizer2 = new wxBoxSizer(wxHORIZONTAL); + wxBoxSizer* NotebookSizer = new wxBoxSizer(wxVERTICAL); + NotebookSizer->Add(Config, 1, wxEXPAND, 0); + MainSizer->Add(NotebookSizer, 0, wxEXPAND, 0); + MainSizer2->Add(btnOK, 0, 0, 0); + MainSizer2->Add(btnCancel, 0, wxLEFT, 10); + MainSizer->Add(MainSizer2, 0, wxALL|wxALIGN_RIGHT, 5); + SetSizer(MainSizer); + MainSizer->Fit(this); + Layout(); +#ifdef __WINDOWS__ + Centre(); +#endif + // end wxGlade +} + + + +#ifdef TEXTURE_FILTER +wxUint32 texfltr[] = { + NO_FILTER, //"None" + SMOOTH_FILTER_1, //"Smooth filtering 1" + SMOOTH_FILTER_2, //"Smooth filtering 2" + SMOOTH_FILTER_3, //"Smooth filtering 3" + SMOOTH_FILTER_4, //"Smooth filtering 4" + SHARP_FILTER_1, //"Sharp filtering 1" + SHARP_FILTER_2, //"Sharp filtering 2" +}; + +wxUint32 texenht[] = { + NO_ENHANCEMENT, //"None" + NO_ENHANCEMENT, //"Store" + X2_ENHANCEMENT, //"X2" + X2SAI_ENHANCEMENT, //"X2SAI" + HQ2X_ENHANCEMENT, //"HQ2X" + HQ2XS_ENHANCEMENT, //"HQ2XS" + LQ2X_ENHANCEMENT, //"LQ2X" + LQ2XS_ENHANCEMENT, //"LQ2XS" + HQ4X_ENHANCEMENT, //"HQ4X" +}; + +wxUint32 texcmpr[] = { + //NO_COMPRESSION, //"None" + // NCC_COMPRESSION, //"NCC" + S3TC_COMPRESSION, //"S3TC" + FXT1_COMPRESSION, //"FXT1" +}; + +wxUint32 texhirs[] = { + NO_HIRESTEXTURES, //"Do not use" + RICE_HIRESTEXTURES, //"Rice format" + // GHQ_HIRESTEXTURES, //"GlideHQ format" + // JABO_HIRESTEXTURES, //"Jabo format" +}; +#endif + +static void SetLocale(wxLocale & locale) +{ + if (settings.lang_id >= 0 && settings.lang_id != wxLANGUAGE_ENGLISH_US) + { + if (locale.Init(settings.lang_id, wxLOCALE_CONV_ENCODING)) + { + wxString fileName(wxT("Glide64_")); + fileName += wxLocale::GetLanguageInfo(settings.lang_id)->CanonicalName; + wxLocale::AddCatalogLookupPathPrefix(GetTranslationsPath()); + if (!locale.AddCatalog(fileName)) + { + wxString strMessage(wxT("Can't find file ")); + strMessage += fileName; + strMessage += wxT(".mo for language '"); + strMessage += wxLocale::GetLanguageInfo(settings.lang_id)->Description; + strMessage += wxT("'\nUsing default language."); + wxMessageBox(strMessage, wxT("File not found"), wxOK|wxICON_EXCLAMATION); + settings.lang_id = wxLANGUAGE_ENGLISH_US; + } + } + } +} + +wxWindow * hostWindow = NULL; + +/****************************************************************** +Function: DllConfig +Purpose: This function is optional function that is provided +to allow the user to configure the dll +input: a handle to the window that calls this function +output: none +*******************************************************************/ +void CALL DllConfig ( HWND hParent ) +{ + LOG ("DllConfig ()\n"); + mutexProcessDList->Lock(); + ReadSettings(); + + //translation + wxLocale locale; + SetLocale(locale); + + if (romopen) + { +// ReadSpecialSettings ((char*)rdp.RomName.c_str()); + if (evoodoo)// && fullscreen && !ev_fullscreen) + { + ReleaseGfx (); + rdp_reset (); + } +#ifdef TEXTURE_FILTER // Hiroshi Morii + if (settings.ghq_use) + { + ext_ghq_shutdown(); + settings.ghq_use = 0; + } +#endif + //wxThread::Sleep(1000); + } + else + { + char name[21] = "DEFAULT"; + ReadSpecialSettings (name); + } + +#ifdef __WINDOWS__ + if (hostWindow == NULL) + hostWindow = new wxWindow(); + WXHWND hwnd = hParent; + hostWindow->SetHWND(hwnd); + hostWindow->SubclassWin(hwnd); + hostWindow->Disable(); +#endif + + Glide64ConfigDialog* Glide64Config = new Glide64ConfigDialog(hostWindow, wxID_ANY, wxEmptyString); + Glide64Config->ShowModal(); +} + +#ifndef _DEBUG +//#if 1 +#ifndef __GNUG__ +void wxStringData::Free() +{ + free(this); +} +#endif +#endif + +void CloseConfig() +{ + if (romopen) + { + if (fb_depth_render_enabled) + ZLUT_init(); + // re-init evoodoo graphics to resize window + if (evoodoo)// && !ev_fullscreen) + InitGfx (); + else + rdp_reset (); + } +#ifdef __WINDOWS__ + hostWindow->Enable(); + hostWindow->UnsubclassWin(); + hostWindow->SetHWND(NULL); +#endif + mutexProcessDList->Unlock(); +} + + +AboutDialog::AboutDialog(wxWindow* parent, int id, const wxString& title, const wxPoint& pos, const wxSize& size, long style): +wxDialog(parent, id, title, pos, size, wxDEFAULT_DIALOG_STYLE) +{ + // begin wxGlade: AboutDialog::AboutDialog + button_ok = new wxButton(this, wxID_OK, wxEmptyString); + + set_properties(); + do_layout(); + // end wxGlade +} + + +void AboutDialog::set_properties() +{ + // begin wxGlade: AboutDialog::set_properties + SetTitle(_("About Glide64")); + button_ok->SetDefault(); + // end wxGlade +} + + +void AboutDialog::do_layout() +{ + // begin wxGlade: AboutDialog::do_layout + wxBoxSizer* sizer_1 = new wxBoxSizer(wxVERTICAL); + wxBoxSizer* sizer_12 = new wxBoxSizer(wxHORIZONTAL); + wxBoxSizer* sizer_11 = new wxBoxSizer(wxHORIZONTAL); + wxBoxSizer* sizer_8 = new wxBoxSizer(wxHORIZONTAL); + wxBoxSizer* sizer_10 = new wxBoxSizer(wxHORIZONTAL); + wxBoxSizer* sizer_9 = new wxBoxSizer(wxHORIZONTAL); + wxBoxSizer* sizer_5 = new wxBoxSizer(wxHORIZONTAL); + wxBoxSizer* sizer_7 = new wxBoxSizer(wxHORIZONTAL); + wxBoxSizer* sizer_6 = new wxBoxSizer(wxHORIZONTAL); + wxBoxSizer* sizer_13 = new wxBoxSizer(wxHORIZONTAL); + wxBoxSizer* sizer_4 = new wxBoxSizer(wxHORIZONTAL); + wxBoxSizer* sizer_3 = new wxBoxSizer(wxHORIZONTAL); + wxBoxSizer* sizer_2 = new wxBoxSizer(wxHORIZONTAL); + +#include "logo.xpm" +#include "australia.xpm" +#include "brazil.xpm" +#include "france.xpm" +#include "japan.xpm" +#include "russia.xpm" +#include "usa.xpm" + + wxStaticBitmap* bitmap_1 = new wxStaticBitmap(this, wxID_ANY, wxBitmap(logo_xpm, wxBITMAP_TYPE_XPM), wxDefaultPosition, wxDefaultSize, wxRAISED_BORDER); + sizer_1->Add(bitmap_1, 0, wxALL|wxEXPAND, 10); + wxStaticText* label_1 = new wxStaticText(this, wxID_ANY, _("authors:")); + sizer_1->Add(label_1, 0, wxALL|wxALIGN_CENTER_HORIZONTAL, 5); + wxStaticBitmap* bitmap_2 = new wxStaticBitmap(this, wxID_ANY, wxBitmap(usa_xpm, wxBITMAP_TYPE_XPM), wxDefaultPosition, wxDefaultSize, wxSTATIC_BORDER); + sizer_2->Add(bitmap_2, 0, wxALL|wxALIGN_CENTER_VERTICAL, 10); + wxStaticText* label_2 = new wxStaticText(this, wxID_ANY, _("Dave2001. Original author and former main developer.\nHe founded Glide64 project on Dec. 29th, 2001.\nLeft the project at fall of 2002.\n")); + label_2->Enable(false); + sizer_2->Add(label_2, 0, 0, 0); + sizer_1->Add(sizer_2, 1, wxEXPAND, 0); + wxStaticBitmap* bitmap_3 = new wxStaticBitmap(this, wxID_ANY, wxBitmap(brazil_xpm, wxBITMAP_TYPE_XPM), wxDefaultPosition, wxDefaultSize, wxSTATIC_BORDER); + sizer_3->Add(bitmap_3, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, 10); + wxStaticText* label_3 = new wxStaticText(this, wxID_ANY, _("Gugaman. Developer. Joined the project at winter 2002\n and left it at fall 2002.")); + label_3->Enable(false); + sizer_3->Add(label_3, 0, 0, 0); + sizer_1->Add(sizer_3, 1, wxEXPAND, 0); + wxStaticBitmap* bitmap_4 = new wxStaticBitmap(this, wxID_ANY, wxBitmap(russia_xpm, wxBITMAP_TYPE_XPM), wxDefaultPosition, wxDefaultSize, wxSTATIC_BORDER); + sizer_4->Add(bitmap_4, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, 10); + wxStaticText* label_4 = new wxStaticText(this, wxID_ANY, _("Sergey 'Gonetz' Lipski. Joined the project at winter 2002.\nMain developer since fall of 2002.")); + sizer_4->Add(label_4, 0, 0, 0); + sizer_1->Add(sizer_4, 1, wxEXPAND, 0); + wxStaticBitmap* bitmap_5 = new wxStaticBitmap(this, wxID_ANY, wxBitmap(japan_xpm, wxBITMAP_TYPE_XPM), wxDefaultPosition, wxDefaultSize, wxSTATIC_BORDER); + sizer_13->Add(bitmap_5, 0, wxLEFT|wxRIGHT|wxBOTTOM, 10); + wxStaticText* label_15 = new wxStaticText(this, wxID_ANY, _("Hiroshi 'KoolSmoky' Morii, Joined the project in 2007. ")); + sizer_13->Add(label_15, 0, 0, 0); + sizer_1->Add(sizer_13, 1, wxEXPAND, 0); + wxStaticText* label_5 = new wxStaticText(this, wxID_ANY, _("Glitch64 (the wrapper) authors:")); + sizer_1->Add(label_5, 0, wxBOTTOM|wxALIGN_CENTER_HORIZONTAL, 10); + wxStaticBitmap* bitmap_6 = new wxStaticBitmap(this, wxID_ANY, wxBitmap(france_xpm, wxBITMAP_TYPE_XPM)); + sizer_6->Add(bitmap_6, 0, wxLEFT|wxRIGHT|wxBOTTOM, 10); + wxStaticText* label_6 = new wxStaticText(this, wxID_ANY, wxT("hacktarux")); + sizer_6->Add(label_6, 0, 0, 0); + sizer_5->Add(sizer_6, 1, wxEXPAND, 0); + wxStaticBitmap* bitmap_7 = new wxStaticBitmap(this, wxID_ANY, wxBitmap(australia_xpm, wxBITMAP_TYPE_XPM)); + sizer_7->Add(bitmap_7, 0, wxRIGHT|wxBOTTOM, 10); + wxStaticText* label_7 = new wxStaticText(this, wxID_ANY, wxT("mudlord")); + sizer_7->Add(label_7, 0, 0, 0); + sizer_5->Add(sizer_7, 1, wxEXPAND, 0); + sizer_1->Add(sizer_5, 0, wxEXPAND, 0); + wxStaticBitmap* bitmap_8 = new wxStaticBitmap(this, wxID_ANY, wxBitmap(france_xpm, wxBITMAP_TYPE_XPM)); + sizer_9->Add(bitmap_8, 0, wxLEFT|wxRIGHT|wxBOTTOM, 10); + wxStaticText* label_8 = new wxStaticText(this, wxID_ANY, wxT("ziggy")); + sizer_9->Add(label_8, 0, 0, 0); + sizer_8->Add(sizer_9, 1, wxEXPAND, 0); + wxStaticBitmap* bitmap_9 = new wxStaticBitmap(this, wxID_ANY, wxBitmap(japan_xpm, wxBITMAP_TYPE_XPM)); + sizer_10->Add(bitmap_9, 0, wxRIGHT|wxBOTTOM, 10); + wxStaticText* label_9 = new wxStaticText(this, wxID_ANY, wxT("Hiroshi 'KoolSmoky' Morii")); + sizer_10->Add(label_9, 0, 0, 0); + sizer_8->Add(sizer_10, 1, wxEXPAND, 0); + sizer_1->Add(sizer_8, 0, wxEXPAND, 0); + wxStaticText* label_10 = new wxStaticText(this, wxID_ANY, _("GlideHQ author:")); + sizer_11->Add(label_10, 0, wxLEFT|wxALIGN_CENTER_VERTICAL, 10); + wxStaticBitmap* bitmap_10 = new wxStaticBitmap(this, wxID_ANY, wxBitmap(japan_xpm, wxBITMAP_TYPE_XPM)); + sizer_11->Add(bitmap_10, 0, wxLEFT|wxRIGHT|wxALIGN_CENTER_VERTICAL, 10); + wxStaticText* label_11 = new wxStaticText(this, wxID_ANY, wxT("Hiroshi 'KoolSmoky' Morii")); + sizer_11->Add(label_11, 0, wxALIGN_CENTER_VERTICAL, 0); + sizer_1->Add(sizer_11, 1, wxEXPAND, 0); + wxStaticText* label_12 = new wxStaticText(this, wxID_ANY, _("beta tester:")); + sizer_12->Add(label_12, 0, wxLEFT|wxALIGN_CENTER_VERTICAL, 10); + wxStaticBitmap* bitmap_11 = new wxStaticBitmap(this, wxID_ANY, wxBitmap(france_xpm, wxBITMAP_TYPE_XPM)); + sizer_12->Add(bitmap_11, 0, wxLEFT|wxRIGHT|wxALIGN_CENTER_VERTICAL, 10); + wxStaticText* label_13 = new wxStaticText(this, wxID_ANY, wxT("olivieryuyu")); + sizer_12->Add(label_13, 0, wxALIGN_CENTER_VERTICAL, 0); + sizer_1->Add(sizer_12, 1, wxEXPAND, 0); + wxStaticText* label_14 = new wxStaticText(this, wxID_ANY, _("special thanks to:\n Orkin, Rice, Daniel Borca, Legend.\nThanks to EmuXHaven for hosting my site:\nhttp://glide64.emuxhaven.net\n"), wxDefaultPosition, wxDefaultSize, wxALIGN_CENTRE); + sizer_1->Add(label_14, 0, wxALIGN_CENTER_HORIZONTAL, 0); + sizer_1->Add(button_ok, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND|wxALIGN_CENTER_HORIZONTAL, 10); + SetSizer(sizer_1); + sizer_1->Fit(this); + Layout(); +#ifdef __WINDOWS__ + Centre(); +#endif + // end wxGlade +} + +/****************************************************************** +Function: DllAbout +Purpose: This function is optional function that is provided +to give further information about the DLL. +input: a handle to the window that calls this function +output: none +*******************************************************************/ +void CALL DllAbout ( HWND hParent ) +{ +#ifdef __WINDOWS__ + if (hostWindow == NULL) + hostWindow = new wxWindow(); + WXHWND hwnd = hParent; + hostWindow->SetHWND(hwnd); + // hostWindow->SubclassWin(hwnd); + hostWindow->Disable(); +#endif + + //translation + ReadSettings(); + wxLocale locale; + SetLocale(locale); + + AboutDialog* AboutGlide64 = new AboutDialog(hostWindow, wxID_ANY, wxEmptyString); + AboutGlide64->ShowModal(); +#ifdef __WINDOWS__ + hostWindow->Enable(); + // hostWindow->UnsubclassWin(); + hostWindow->SetHWND(NULL); +#endif +} diff --git a/Source/Glide64/Config.h b/Source/Glide64/Config.h new file mode 100644 index 000000000..ce3c52bee --- /dev/null +++ b/Source/Glide64/Config.h @@ -0,0 +1,264 @@ +/* +* Glide64 - Glide video plugin for Nintendo 64 emulators. +* Copyright (c) 2002 Dave2001 +* Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski +* +* 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 +* 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 +*/ + +//**************************************************************** +// +// Glide64 - Glide Plugin for Nintendo 64 emulators (tested mostly with Project64) +// Project started on December 29th, 2001 +// +// Authors: +// Dave2001, original author, founded the project in 2001, left it in 2002 +// Gugaman, joined the project in 2002, left it in 2002 +// Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002 +// Hiroshi 'KoolSmoky' Morii, joined the project in 2007 +// +//**************************************************************** +// +// To modify Glide64: +// * Write your name and (optional)email, commented by your work, so I know who did it, and so that you can find which parts you modified when it comes time to send it to me. +// * Do NOT send me the whole project or file that you modified. Take out your modified code sections, and tell me where to put them. If people sent the whole thing, I would have many different versions, but no idea how to combine them all. +// +//**************************************************************** +// +// Glide64 dialogs +// Created by Gonetz, 2008 +// +//**************************************************************** + +// -*- C++ -*- generated by wxGlade 0.6.3 on Wed Oct 08 18:56:23 2008 + +#include +#include +// begin wxGlade: ::dependencies +#include +#include +// end wxGlade + + +#ifndef CONFIG_H +#define CONFIG_H + + +// begin wxGlade: ::extracode +// end wxGlade + + +class ConfigNotebook: public wxNotebook { +public: + // begin wxGlade: ConfigNotebook::ids + enum { + wxID_VRAM = wxID_HIGHEST + 1000, + wxID_FBEnable = wxID_HIGHEST + 1002, + wxID_TexEdit = wxID_HIGHEST + 1004, + wxID_Performance = wxID_HIGHEST + 1006, + wxID_Quality = wxID_HIGHEST + 1008, + wxID_Language = wxID_HIGHEST + 1010 + }; + // end wxGlade + + ConfigNotebook(wxWindow* parent, int id, const wxPoint& pos=wxDefaultPosition, const wxSize& size=wxDefaultSize, long style=0); + +private: + // begin wxGlade: ConfigNotebook::methods + void set_properties(); + void do_layout(); + // end wxGlade + int lang_id; + +protected: + // begin wxGlade: ConfigNotebook::attributes + wxStaticBox* BasicRenderingSizer_staticbox; + wxStaticBox* OnScreenDisplaySizer_staticbox; + wxStaticBox* SpeedSizer_staticbox; + wxStaticBox* TimeSizer_staticbox; + wxStaticText* lblResolution; + wxComboBox* cmbResolution; + wxCheckBox* cbxVSync; + wxCheckBox* cbxFPS; + wxCheckBox* cbxVIS; + wxCheckBox* cbxPercent; + wxCheckBox* cbxClockEnabled; + wxCheckBox* cbxClock24; + wxCheckBox* cbxTextTransparent; + wxStaticBox* WrapperSizer_staticbox; + wxStaticBox* WrapperFBOptionsSizer_staticbox; + wxStaticText* lblFSResolution; + wxComboBox* cmbFSResolution; + wxCheckBox* cbxAnisotropic; + wxCheckBox* cbxVRAM; + wxStaticText* lblVRAM; + wxSpinCtrl* spinVRAM; + wxStaticText* lblMb; + wxCheckBox* cbxFBO; + wxStaticBox* OtherSizer_staticbox; + wxCheckBox* cbxAdvancedSettings; + wxCheckBox* cbxTextureSettings; + wxStaticText* lblScreenShotFormat; + wxComboBox* cmbScreenShotFormat; + wxButton* btnLanguage; + wxPanel* BasicSettingsPanel; + + wxStaticBox* EmuSettingsBoxSizer_staticbox; + wxStaticBox* EmuSettingsLeftSizer_staticbox; + wxStaticBox* DepthBufferSizer_staticbox; + wxStaticBox* FrameBufferSizer_staticbox; + wxStaticText* lbFiltering; + wxComboBox* cmbFiltering; + wxStaticText* lbBufferSwap; + wxComboBox* cmbBufferSwap; + wxStaticText* lblLOD; + wxComboBox* cmbLOD; + wxStaticText* lblAspect; + wxComboBox* cmbAspect; + wxCheckBox* cbxFog; + wxCheckBox* cbxBuffer; + wxCheckBox* cbxFBEnable; + wxCheckBox* cbxFBHWFBE; + wxCheckBox* cbxFBGetFBI; + wxCheckBox* cbxFBReadEveryFrame; + wxCheckBox* cbxFBasTex; + wxCheckBox* cbxDetect; + wxCheckBox* cbxFBDepthBuffer; + wxPanel* EmuSettingsPanel; + +#ifdef TEXTURE_FILTER + wxStaticBox* PresetsSizer_staticbox; + wxStaticBox* CommonSizer_staticbox; + wxStaticBox* TextureRightSizer_staticbox; + wxStaticBox* EnhTexSizer_staticbox; + wxStaticBox* HRTexPerfTweaksSizer_staticbox; + wxStaticBox* EnhTexPerfTweaksSizer_staticbox; + wxStaticText* lblFilter; + wxComboBox* cmbEnhFilter; + wxStaticText* lblEnhancement; + wxComboBox* cmbEnhEnhancement; + wxStaticText* lblTexCache; + wxSpinCtrl* spinEnhCacheSize; + wxStaticText* lblTexCacheMB; + wxCheckBox* cbxEnhIgnoreBG; + wxCheckBox* cbxEnhTexCompression; + wxCheckBox* cbxEnhCompressCache; + wxStaticText* lblHrsFormat; + wxComboBox* cmbHrsFormat; + wxCheckBox* cbxHrsTile; + wxCheckBox* cbxHrsForce16; + wxCheckBox* cbxHrsAltCRC; + wxCheckBox* cbxHrsTexCompression; + wxCheckBox* cbxHrsCompressCache; + wxCheckBox* cbxHrsLetFly; + wxCheckBox* cbxHrsTexEdit; + wxStaticText* lblTexCompression; + wxComboBox* cmbTextureCompression; + wxCheckBox* cbxSaveTexCache; + wxButton* btnPerformance; + wxButton* btnQuality; + wxPanel* TexturePanel; +#endif //TEXTURE_FILTER + +#ifndef _ENDUSER_RELEASE_ + wxStaticBox* DebugSizer_staticbox; + wxStaticBox* DevSettingsSizer_staticbox; + wxCheckBox* cbxAutoUcode; + wxStaticText* lblForceUcode; + wxComboBox* cmbForceUcode; + wxCheckBox* cbxWireframe; + wxComboBox* cmbWireframe; + wxCheckBox* cbxLog; + wxCheckBox* cbxCombRed; + wxCheckBox* cbxLogClear; + wxCheckBox* cbxCmbLog; + wxCheckBox* cbxWindowLog; + wxCheckBox* cbxCmbLogClear; + wxCheckBox* cbxErrLog; + wxCheckBox* cbxBilinearTexCache; + wxPanel* DebugPanel; +#endif //_ENDUSER_RELEASE_ + + // end wxGlade + + DECLARE_EVENT_TABLE(); + +public: + virtual void OnClickVRAM(wxCommandEvent &event); // wxGlade: + virtual void OnClickFB(wxCommandEvent &event); // wxGlade: + virtual void OnLanguageSelect(wxCommandEvent &event); // wxGlade: +#ifdef TEXTURE_FILTER + virtual void onPerformace(wxCommandEvent &event); // wxGlade: + virtual void onQuality(wxCommandEvent &event); // wxGlade: + virtual void OnClickTexEdit(wxCommandEvent &event); // wxGlade: +#endif //TEXTURE_FILTER + +// virtual void onPageChanged(wxNotebookEvent &event); // wxGlade: +// virtual void onPageChanging(wxNotebookEvent &event); // wxGlade: + void SaveSettings(); +}; // wxGlade: end class + + +class Glide64ConfigDialog: public wxDialog { +public: + // begin wxGlade: Glide64ConfigDialog::ids + // end wxGlade + + Glide64ConfigDialog(wxWindow* parent, int id, const wxString& title, const wxPoint& pos=wxDefaultPosition, const wxSize& size=wxDefaultSize, long style=wxDEFAULT_DIALOG_STYLE); + void OnClose(wxCloseEvent& event); + +private: + // begin wxGlade: Glide64ConfigDialog::methods + void set_properties(); + void do_layout(); + // end wxGlade + +protected: + // begin wxGlade: Glide64ConfigDialog::attributes + ConfigNotebook* Config; + wxButton* btnOK; + wxButton* btnCancel; + // end wxGlade + + DECLARE_EVENT_TABLE(); + +public: +// virtual void onPageChanged(wxNotebookEvent &event); // wxGlade: +// virtual void onPageChanging(wxNotebookEvent &event); // wxGlade: + virtual void OnOK(wxCommandEvent &event); // wxGlade: + virtual void OnCancel(wxCommandEvent &event); // wxGlade: +}; // wxGlade: end class + + +class AboutDialog: public wxDialog { +public: + // begin wxGlade: AboutDialog::ids + // end wxGlade + + AboutDialog(wxWindow* parent, int id, const wxString& title, const wxPoint& pos=wxDefaultPosition, const wxSize& size=wxDefaultSize, long style=wxDEFAULT_DIALOG_STYLE); + +private: + // begin wxGlade: AboutDialog::methods + void set_properties(); + void do_layout(); + // end wxGlade + +protected: + // begin wxGlade: AboutDialog::attributes + wxButton* button_ok; + // end wxGlade +}; // wxGlade: end class + +#endif // CONFIG_H diff --git a/Source/Glide64/Debugger.cpp b/Source/Glide64/Debugger.cpp new file mode 100644 index 000000000..c0ac22f38 --- /dev/null +++ b/Source/Glide64/Debugger.cpp @@ -0,0 +1,1020 @@ +/* +* Glide64 - Glide video plugin for Nintendo 64 emulators. +* Copyright (c) 2002 Dave2001 +* Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski +* +* 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 +* 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 +*/ + +//**************************************************************** +// +// Glide64 - Glide Plugin for Nintendo 64 emulators +// Project started on December 29th, 2001 +// +// Authors: +// Dave2001, original author, founded the project in 2001, left it in 2002 +// Gugaman, joined the project in 2002, left it in 2002 +// Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002 +// Hiroshi 'KoolSmoky' Morii, joined the project in 2007 +// +//**************************************************************** +// +// To modify Glide64: +// * Write your name and (optional)email, commented by your work, so I know who did it, and so that you can find which parts you modified when it comes time to send it to me. +// * Do NOT send me the whole project or file that you modified. Take out your modified code sections, and tell me where to put them. If people sent the whole thing, I would have many different versions, but no idea how to combine them all. +// +//**************************************************************** + +#include "Gfx #1.3.h" +#include "Util.h" +#include "Debugger.h" + +GLIDE64_DEBUGGER _debugger; + +#define SX(x) ((x)*rdp.scale_1024) +#define SY(x) ((x)*rdp.scale_768) + +#ifdef COLORED_DEBUGGER +#define COL_CATEGORY() grConstantColorValue(0xD288F400) +#define COL_UCC() grConstantColorValue(0xFF000000) +#define COL_CC() grConstantColorValue(0x88C3F400) +#define COL_UAC() grConstantColorValue(0xFF808000) +#define COL_AC() grConstantColorValue(0x3CEE5E00) +#define COL_TEXT() grConstantColorValue(0xFFFFFF00) +#define COL_SEL(x) grConstantColorValue((x)?0x00FF00FF:0x800000FF) +#else +#define COL_CATEGORY() +#define COL_UCC() +#define COL_CC() +#define COL_UAC() +#define COL_AC() +#define COL_TEXT() +#define COL_SEL(x) +#endif + +#define COL_GRID 0xFFFFFF80 + +int grid = 0; +static const char *tri_type[4] = { "TRIANGLE", "TEXRECT", "FILLRECT", "BACKGROUND" }; + +//Platform-specific stuff +#ifndef __WINDOWS__ +typedef struct dbgPOINT { + int x; + int y; +} POINT; +#endif +void DbgCursorPos(POINT * pt) +{ +#ifdef __WINDOWS__ + GetCursorPos (pt); +#else //!todo find a way to get cursor position on Unix + pt->x = pt->y = 0; +#endif +} + +// +// debug_init - initialize the debugger +// + +void debug_init () +{ + _debugger.capture = 0; + _debugger.selected = SELECTED_TRI; + _debugger.screen = NULL; + _debugger.tri_list = NULL; + _debugger.tri_last = NULL; + _debugger.tri_sel = NULL; + _debugger.tmu = 0; + + _debugger.tex_scroll = 0; + _debugger.tex_sel = 0; + + _debugger.draw_mode = 0; +} + +// +// debug_cacheviewer - views the debugger's cache +// + +void debug_cacheviewer () +{ + grCullMode (GR_CULL_DISABLE); + + int i; + for (i=0; i<2; i++) + { + grTexFilterMode (i, + (settings.filter_cache)?GR_TEXTUREFILTER_BILINEAR:GR_TEXTUREFILTER_POINT_SAMPLED, + (settings.filter_cache)?GR_TEXTUREFILTER_BILINEAR:GR_TEXTUREFILTER_POINT_SAMPLED); + grTexClampMode (i, + GR_TEXTURECLAMP_CLAMP, + GR_TEXTURECLAMP_CLAMP); + } + + switch (_debugger.draw_mode) + { + case 0: + grColorCombine (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_NONE, + GR_COMBINE_OTHER_TEXTURE, + FXFALSE); + grAlphaCombine (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_NONE, + GR_COMBINE_OTHER_TEXTURE, + FXFALSE); + break; + case 1: + grColorCombine (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_NONE, + GR_COMBINE_OTHER_TEXTURE, + FXFALSE); + grAlphaCombine (GR_COMBINE_FUNCTION_LOCAL, + GR_COMBINE_FACTOR_NONE, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_NONE, + FXFALSE); + grConstantColorValue (0xFFFFFFFF); + break; + case 2: + grColorCombine (GR_COMBINE_FUNCTION_LOCAL, + GR_COMBINE_FACTOR_NONE, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_NONE, + FXFALSE); + grAlphaCombine (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_NONE, + GR_COMBINE_OTHER_TEXTURE, + FXFALSE); + grConstantColorValue (0xFFFFFFFF); + } + + if (_debugger.tmu == 1) + { + grTexCombine (GR_TMU1, + GR_COMBINE_FUNCTION_LOCAL, + GR_COMBINE_FACTOR_NONE, + GR_COMBINE_FUNCTION_LOCAL, + GR_COMBINE_FACTOR_NONE, + FXFALSE, + FXFALSE); + + grTexCombine (GR_TMU0, + GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_ONE, + FXFALSE, + FXFALSE); + } + else + { + grTexCombine (GR_TMU0, + GR_COMBINE_FUNCTION_LOCAL, + GR_COMBINE_FACTOR_NONE, + GR_COMBINE_FUNCTION_LOCAL, + GR_COMBINE_FACTOR_NONE, + FXFALSE, + FXFALSE); + } + + grAlphaBlendFunction (GR_BLEND_SRC_ALPHA, + GR_BLEND_ONE_MINUS_SRC_ALPHA, + GR_BLEND_ONE, + GR_BLEND_ZERO); + + // Draw texture memory + for (i=0; i<4; i++) + { + for (wxUint32 x=0; x<16; x++) + { + wxUint32 y = i+_debugger.tex_scroll; + if (x+y*16 >= (wxUint32)rdp.n_cached[_debugger.tmu]) break; + CACHE_LUT * cache = voodoo.tex_UMA?rdp.cache[0]:rdp.cache[_debugger.tmu]; + + VERTEX v[4] = { + { SX(x*64.0f), SY(512+64.0f*i), 1, 1, 0, 0, 0, 0, {0, 0, 0, 0} }, + { SX(x*64.0f+64.0f*cache[x+y*16].scale_x), SY(512+64.0f*i), 1, 1, 255*cache[x+y*16].scale_x, 0, 0, 0, {0, 0, 0, 0} }, + { SX(x*64.0f), SY(512+64.0f*i+64.0f*cache[x+y*16].scale_y), 1, 1, 0, 255*cache[x+y*16].scale_y, 0, 0, {0, 0, 0, 0} }, + { SX(x*64.0f+64.0f*cache[x+y*16].scale_x), SY(512+64.0f*i+64.0f*cache[x+y*16].scale_y), 1, 1, 255*cache[x+y*16].scale_x, 255*cache[x+y*16].scale_y, 0, 0, {0, 0, 0, 0} } + }; + for + (int i=0; i<4; i++) + { + v[i].u1 = v[i].u0; + v[i].v1 = v[i].v0; + } + + ConvertCoordsConvert (v, 4); + + grTexSource(_debugger.tmu, + voodoo.tex_min_addr[_debugger.tmu] + cache[x+y*16].tmem_addr, + GR_MIPMAPLEVELMASK_BOTH, + &cache[x+y*16].t_info); + + grDrawTriangle (&v[2], &v[1], &v[0]); + grDrawTriangle (&v[2], &v[3], &v[1]); + } + } + +} + +// +// debug_capture - does a frame capture event (for debugging) +// + +void debug_capture () +{ + wxUint32 i,j; + + if (_debugger.tri_list == NULL) goto END; + _debugger.tri_sel = _debugger.tri_list; + _debugger.selected = SELECTED_TRI; + + // Connect the list + _debugger.tri_last->pNext = _debugger.tri_list; + + while (!CheckKeyPressed(G64_VK_INSERT, 0x0001)) //INSERT + { + // Check for clicks + if (CheckKeyPressed(G64_VK_LBUTTON, 0x0001)) //LBUTTON + { + POINT pt; + DbgCursorPos(&pt); + + //int diff = settings.scr_res_y-settings.res_y; + + if (pt.y <= (int)settings.res_y) + { + int x = pt.x; + int y = pt.y;//settings.res_y - (pt.y - diff); + + TRI_INFO *start; + TRI_INFO *tri; + if (_debugger.tri_sel == NULL) tri = _debugger.tri_list, start = _debugger.tri_list; + else tri = _debugger.tri_sel->pNext, start = _debugger.tri_sel; + + // Select a triangle (start from the currently selected one) + do { + if (tri->v[0].x == tri->v[1].x && + tri->v[0].y == tri->v[1].y) + { + tri = tri->pNext; + continue; + } + + for (i=0; inv; i++) + { + j=i+1; + if (j==tri->nv) j=0; + + if ((y-tri->v[i].y)*(tri->v[j].x-tri->v[i].x) - + (x-tri->v[i].x)*(tri->v[j].y-tri->v[i].y) < 0) + break; // It's outside + } + + if (i==tri->nv) // all lines passed + { + _debugger.tri_sel = tri; + break; + } + + for (i=0; inv; i++) + { + j=i+1; + if (j==tri->nv) j=0; + + if ((y-tri->v[i].y)*(tri->v[j].x-tri->v[i].x) - + (x-tri->v[i].x)*(tri->v[j].y-tri->v[i].y) > 0) + break; // It's outside + } + + if (i==tri->nv) // all lines passed + { + _debugger.tri_sel = tri; + break; + } + + tri = tri->pNext; + } while (tri != start); + } + else + { + // on a texture + _debugger.tex_sel = (((wxUint32)((pt.y-SY(512))/SY(64))+_debugger.tex_scroll)*16) + + (wxUint32)(pt.x/SX(64)); + } + } + + debug_keys (); + + grBufferClear (0, 0, 0xFFFF); + + // Copy the screen capture back to the screen: + grLfbWriteRegion(GR_BUFFER_BACKBUFFER, + (wxUint32)rdp.offset_x, + (wxUint32)rdp.offset_y, + GR_LFB_SRC_FMT_565, + settings.res_x, + settings.res_y, + FXFALSE, + settings.res_x<<1, + _debugger.screen); + + // Do the cacheviewer + debug_cacheviewer (); + + // ** + // 3/16/02: Moved texture viewer out of loop, remade it. Now it's simpler, and + // supports TMU1. [Dave2001] + // Original by Gugaman + + CACHE_LUT * cache = voodoo.tex_UMA?rdp.cache[0]:rdp.cache[_debugger.tmu]; + if (_debugger.page == PAGE_TEX_INFO) + { + grTexSource(_debugger.tmu, + voodoo.tex_min_addr[_debugger.tmu] + cache[_debugger.tex_sel].tmem_addr, + GR_MIPMAPLEVELMASK_BOTH, + &cache[_debugger.tex_sel].t_info); + +#ifdef SHOW_FULL_TEXVIEWER + float scx = 1.0f; + float scy = 1.0f; +#else + float scx = cache[_debugger.tex_sel].scale_x; + float scy = cache[_debugger.tex_sel].scale_y; +#endif + VERTEX v[4] = { + { SX(704.0f), SY(221.0f), 1, 1, 0, 0, 0, 0, {0, 0, 0, 0} }, + { SX(704.0f+256.0f*scx), SY(221.0f), 1, 1, 255*scx, 0, 255*scx, 0, {0, 0, 0, 0} }, + { SX(704.0f), SY(221.0f+256.0f*scy), 1, 1, 0, 255*scy, 0, 255*scy, {0, 0, 0, 0} }, + { SX(704.0f+256.0f*scx), SY(221.0f+256.0f*scy), 1, 1, 255*scx, 255*scy, 255*scx, 255*scy, {0, 0, 0, 0} } + }; + ConvertCoordsConvert (v, 4); + VERTEX *varr[4] = { &v[0], &v[1], &v[2], &v[3] }; + grDrawVertexArray (GR_TRIANGLE_STRIP, 4, varr); + } + + // ** + + grTexFilterMode (GR_TMU0, + GR_TEXTUREFILTER_BILINEAR, + GR_TEXTUREFILTER_BILINEAR); + + grColorCombine (GR_COMBINE_FUNCTION_LOCAL, + GR_COMBINE_FACTOR_NONE, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_NONE, + FXFALSE); + + grAlphaCombine (GR_COMBINE_FUNCTION_LOCAL, + GR_COMBINE_FACTOR_NONE, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_NONE, + FXFALSE); + + grConstantColorValue (0x0000FFFF); + + VERTEX *v[8]; + if (_debugger.tri_sel) + { + // Draw the outline around the selected triangle + for (i=0; i<_debugger.tri_sel->nv; i++) + { + j=i+1; + if (j>=_debugger.tri_sel->nv) j=0; + + grDrawLine (&_debugger.tri_sel->v[i], &_debugger.tri_sel->v[j]); + + v[i] = &_debugger.tri_sel->v[i]; + } + } + + // and the selected texture + wxUint32 t_y = ((_debugger.tex_sel & 0xFFFFFFF0) >> 4) - _debugger.tex_scroll; + wxUint32 t_x = _debugger.tex_sel & 0xF; + VERTEX vt[4] = { + { SX(t_x*64.0f), SY(512+64.0f*t_y), 1, 1 }, + { SX(t_x*64.0f+64.0f), SY(512+64.0f*t_y), 1, 1 }, + { SX(t_x*64.0f), SY(512+64.0f*t_y+64.0f), 1, 1 }, + { SX(t_x*64.0f+64.0f), SY(512+64.0f*t_y+64.0f), 1, 1 } }; + if (t_y < 4) + { + grDrawLine (&vt[0], &vt[1]); + grDrawLine (&vt[1], &vt[3]); + grDrawLine (&vt[3], &vt[2]); + grDrawLine (&vt[2], &vt[0]); + } + + grConstantColorValue (0xFF000020); + + if (t_y < 4) + { + grDrawTriangle (&vt[2], &vt[1], &vt[0]); + grDrawTriangle (&vt[2], &vt[3], &vt[1]); + } + + if (_debugger.tri_sel) + grDrawVertexArray (GR_TRIANGLE_FAN, _debugger.tri_sel->nv, &v); + + // Draw the outline of the cacheviewer + if (_debugger.page == PAGE_TEX_INFO) + { + float scx = cache[_debugger.tex_sel].scale_x; + float scy = cache[_debugger.tex_sel].scale_y; + + // And the grid + if (grid) + { + grConstantColorValue (COL_GRID); + + float scale_y = (256.0f * scy) / (float)cache[_debugger.tex_sel].height; + for (int y=0; y<=(int)cache[_debugger.tex_sel].height; y++) + { + float y_val = SY(221.0f+y*scale_y); + VERTEX vh[2] = { + { SX(704.0f), y_val, 1, 1 }, + { SX(704.0f+255.0f*scx), y_val, 1, 1 } }; + grDrawLine (&vh[0], &vh[1]); + } + + float scale_x = (256.0f * scx) / (float)cache[_debugger.tex_sel].width; + for (int x=0; x<=(int)cache[_debugger.tex_sel].width; x++) + { + float x_val = SX(704.0f+x*scale_x); + VERTEX vv[2] = { + { x_val, SX(221.0f), 1, 1 }, + { x_val, SX(221.0f+256.0f*scy), 1, 1 } }; + grDrawLine (&vv[0], &vv[1]); + } + } + } + + grTexCombine (GR_TMU0, + GR_COMBINE_FUNCTION_LOCAL, + GR_COMBINE_FACTOR_NONE, + GR_COMBINE_FUNCTION_LOCAL, + GR_COMBINE_FACTOR_NONE, + FXFALSE, + FXFALSE); + + grColorCombine (GR_COMBINE_FUNCTION_LOCAL, + GR_COMBINE_FACTOR_NONE, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_NONE, + FXFALSE); + + grAlphaCombine (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_NONE, + GR_COMBINE_OTHER_TEXTURE, + FXFALSE); + + grConstantColorValue (0xFFFFFF00); + + // Output the information about the selected triangle + grTexSource(GR_TMU0, // Text + voodoo.tex_min_addr[_debugger.tmu]+ offset_font, + GR_MIPMAPLEVELMASK_BOTH, + &fontTex); + + static const char *cycle_mode_s[4] = { "1 cycle (0)", "2 cycle (1)", "copy (2)", "fill (3)" }; + +#define OUTPUT(fmt,other) output(642,(float)i,1,fmt,other); i-=16; +#define OUTPUT1(fmt,other,other1) output(642,(float)i,1,fmt,other,other1); i-=16; +#define OUTPUT_(fmt,cc) COL_SEL(cc); x=642; output(x,(float)i,1,fmt,0); x+=8*(strlen(fmt)+1) +#define _OUTPUT(fmt,cc) COL_SEL(cc); output(x,(float)i,1,fmt,0); x+=8*(strlen(fmt)+1) + i = 740; + float x; + if (_debugger.page == PAGE_GENERAL && _debugger.tri_sel) + { + COL_CATEGORY(); + OUTPUT ("GENERAL (page 1):",0); + COL_TEXT(); + OUTPUT ("tri #%d", _debugger.tri_sel->tri_n); + OUTPUT ("type: %s", tri_type[_debugger.tri_sel->type]); + OUTPUT ("geom: 0x%08lx", _debugger.tri_sel->geom_mode); + OUTPUT ("othermode_h: 0x%08lx", _debugger.tri_sel->othermode_h); + OUTPUT ("othermode_l: 0x%08lx", _debugger.tri_sel->othermode_l); + OUTPUT ("flags: 0x%08lx", _debugger.tri_sel->flags); + OUTPUT ("",0); + COL_CATEGORY(); + OUTPUT ("COMBINE:",0); + COL_TEXT(); + OUTPUT ("cycle_mode: %s", cycle_mode_s[_debugger.tri_sel->cycle_mode]); + OUTPUT ("cycle1: 0x%08lx", _debugger.tri_sel->cycle1); + OUTPUT ("cycle2: 0x%08lx", _debugger.tri_sel->cycle2); + if (_debugger.tri_sel->uncombined & 1) + COL_UCC(); + else + COL_CC(); + OUTPUT ("a0: %s", Mode0[(_debugger.tri_sel->cycle1)&0x0000000F]); + OUTPUT ("b0: %s", Mode1[(_debugger.tri_sel->cycle1>>4)&0x0000000F]); + OUTPUT ("c0: %s", Mode2[(_debugger.tri_sel->cycle1>>8)&0x0000001F]); + OUTPUT ("d0: %s", Mode3[(_debugger.tri_sel->cycle1>>13)&0x00000007]); + if (_debugger.tri_sel->uncombined & 2) + COL_UAC(); + else + COL_AC(); + OUTPUT ("Aa0: %s", Alpha0[(_debugger.tri_sel->cycle1>>16)&0x00000007]); + OUTPUT ("Ab0: %s", Alpha1[(_debugger.tri_sel->cycle1>>19)&0x00000007]); + OUTPUT ("Ac0: %s", Alpha2[(_debugger.tri_sel->cycle1>>22)&0x00000007]); + OUTPUT ("Ad0: %s", Alpha3[(_debugger.tri_sel->cycle1>>25)&0x00000007]); + if (_debugger.tri_sel->uncombined & 1) + COL_UCC(); + else + COL_CC(); + OUTPUT ("a1: %s", Mode0[(_debugger.tri_sel->cycle2)&0x0000000F]); + OUTPUT ("b1: %s", Mode1[(_debugger.tri_sel->cycle2>>4)&0x0000000F]); + OUTPUT ("c1: %s", Mode2[(_debugger.tri_sel->cycle2>>8)&0x0000001F]); + OUTPUT ("d1: %s", Mode3[(_debugger.tri_sel->cycle2>>13)&0x00000007]); + if (_debugger.tri_sel->uncombined & 2) + COL_UAC(); + else + COL_AC(); + OUTPUT ("Aa1: %s", Alpha0[(_debugger.tri_sel->cycle2>>16)&0x00000007]); + OUTPUT ("Ab1: %s", Alpha1[(_debugger.tri_sel->cycle2>>19)&0x00000007]); + OUTPUT ("Ac1: %s", Alpha2[(_debugger.tri_sel->cycle2>>22)&0x00000007]); + OUTPUT ("Ad1: %s", Alpha3[(_debugger.tri_sel->cycle2>>25)&0x00000007]); + } + if ((_debugger.page == PAGE_TEX1 || _debugger.page == PAGE_TEX2) && _debugger.tri_sel) + { + COL_CATEGORY (); + OUTPUT1 ("TEXTURE %d (page %d):", _debugger.page-PAGE_TEX1, 2+_debugger.page-PAGE_TEX1); + COL_TEXT(); + int tmu = _debugger.page - PAGE_TEX1; + OUTPUT1 ("cur cache: %d,%d", _debugger.tri_sel->t[tmu].cur_cache[tmu]&0x0F, _debugger.tri_sel->t[tmu].cur_cache[tmu]>>4); + OUTPUT ("tex_size: %d", _debugger.tri_sel->t[tmu].size); + OUTPUT ("tex_format: %d", _debugger.tri_sel->t[tmu].format); + OUTPUT ("width: %d", _debugger.tri_sel->t[tmu].width); + OUTPUT ("height: %d", _debugger.tri_sel->t[tmu].height); + OUTPUT ("palette: %d", _debugger.tri_sel->t[tmu].palette); + OUTPUT ("clamp_s: %d", _debugger.tri_sel->t[tmu].clamp_s); + OUTPUT ("clamp_t: %d", _debugger.tri_sel->t[tmu].clamp_t); + OUTPUT ("mirror_s: %d", _debugger.tri_sel->t[tmu].mirror_s); + OUTPUT ("mirror_t: %d", _debugger.tri_sel->t[tmu].mirror_t); + OUTPUT ("mask_s: %d", _debugger.tri_sel->t[tmu].mask_s); + OUTPUT ("mask_t: %d", _debugger.tri_sel->t[tmu].mask_t); + OUTPUT ("shift_s: %d", _debugger.tri_sel->t[tmu].shift_s); + OUTPUT ("shift_t: %d", _debugger.tri_sel->t[tmu].shift_t); + OUTPUT ("ul_s: %d", _debugger.tri_sel->t[tmu].ul_s); + OUTPUT ("ul_t: %d", _debugger.tri_sel->t[tmu].ul_t); + OUTPUT ("lr_s: %d", _debugger.tri_sel->t[tmu].lr_s); + OUTPUT ("lr_t: %d", _debugger.tri_sel->t[tmu].lr_t); + OUTPUT ("t_ul_s: %d", _debugger.tri_sel->t[tmu].t_ul_s); + OUTPUT ("t_ul_t: %d", _debugger.tri_sel->t[tmu].t_ul_t); + OUTPUT ("t_lr_s: %d", _debugger.tri_sel->t[tmu].t_lr_s); + OUTPUT ("t_lr_t: %d", _debugger.tri_sel->t[tmu].t_lr_t); + OUTPUT ("scale_s: %f", _debugger.tri_sel->t[tmu].scale_s); + OUTPUT ("scale_t: %f", _debugger.tri_sel->t[tmu].scale_t); + OUTPUT ("s_mode: %s", str_cm[((_debugger.tri_sel->t[tmu].clamp_s << 1) | _debugger.tri_sel->t[tmu].mirror_s)&3]); + OUTPUT ("t_mode: %s", str_cm[((_debugger.tri_sel->t[tmu].clamp_t << 1) | _debugger.tri_sel->t[tmu].mirror_t)&3]); + } + if (_debugger.page == PAGE_COLORS && _debugger.tri_sel) + { + COL_CATEGORY(); + OUTPUT ("COLORS (page 4)", 0); + COL_TEXT(); + OUTPUT ("fill: %08lx", _debugger.tri_sel->fill_color); + OUTPUT ("prim: %08lx", _debugger.tri_sel->prim_color); + OUTPUT ("blend: %08lx", _debugger.tri_sel->blend_color); + OUTPUT ("env: %08lx", _debugger.tri_sel->env_color); + OUTPUT ("fog: %08lx", _debugger.tri_sel->fog_color); + OUTPUT ("prim_lodmin: %d", _debugger.tri_sel->prim_lodmin); + OUTPUT ("prim_lodfrac: %d", _debugger.tri_sel->prim_lodfrac); + } + if (_debugger.page == PAGE_FBL && _debugger.tri_sel) + { + COL_CATEGORY(); + OUTPUT ("BLENDER", 0); + COL_TEXT(); + OUTPUT ("fbl_a0: %s", FBLa[(_debugger.tri_sel->othermode_l>>30)&0x3]); + OUTPUT ("fbl_b0: %s", FBLb[(_debugger.tri_sel->othermode_l>>26)&0x3]); + OUTPUT ("fbl_c0: %s", FBLc[(_debugger.tri_sel->othermode_l>>22)&0x3]); + OUTPUT ("fbl_d0: %s", FBLd[(_debugger.tri_sel->othermode_l>>18)&0x3]); + OUTPUT ("fbl_a1: %s", FBLa[(_debugger.tri_sel->othermode_l>>28)&0x3]); + OUTPUT ("fbl_b1: %s", FBLb[(_debugger.tri_sel->othermode_l>>24)&0x3]); + OUTPUT ("fbl_c1: %s", FBLc[(_debugger.tri_sel->othermode_l>>20)&0x3]); + OUTPUT ("fbl_d1: %s", FBLd[(_debugger.tri_sel->othermode_l>>16)&0x3]); + OUTPUT ("", 0); + OUTPUT ("fbl: %08lx", _debugger.tri_sel->othermode_l&0xFFFF0000); + OUTPUT ("fbl #1: %08lx", _debugger.tri_sel->othermode_l&0xCCCC0000); + OUTPUT ("fbl #2: %08lx", _debugger.tri_sel->othermode_l&0x33330000); + } + if (_debugger.page == PAGE_OTHERMODE_L && _debugger.tri_sel) + { + wxUint32 othermode_l = _debugger.tri_sel->othermode_l; + COL_CATEGORY (); + OUTPUT ("OTHERMODE_L: %08lx", othermode_l); + OUTPUT_ ("AC_NONE", (othermode_l & 3) == 0); + _OUTPUT ("AC_THRESHOLD", (othermode_l & 3) == 1); + _OUTPUT ("AC_DITHER", (othermode_l & 3) == 3); + i -= 16; + OUTPUT_ ("ZS_PIXEL", !(othermode_l & 4)); + _OUTPUT ("ZS_PRIM", (othermode_l & 4)); + i -= 32; + COL_CATEGORY (); + OUTPUT ("RENDERMODE: %08lx", othermode_l); + OUTPUT_ ("AA_EN", othermode_l & 0x08); + i -= 16; + OUTPUT_ ("Z_CMP", othermode_l & 0x10); + i -= 16; + OUTPUT_ ("Z_UPD", othermode_l & 0x20); + i -= 16; + OUTPUT_ ("IM_RD", othermode_l & 0x40); + i -= 16; + OUTPUT_ ("CLR_ON_CVG", othermode_l & 0x80); + i -= 16; + OUTPUT_ ("CVG_DST_CLAMP", (othermode_l & 0x300) == 0x000); + _OUTPUT ("CVG_DST_WRAP", (othermode_l & 0x300) == 0x100); + _OUTPUT (".._FULL", (othermode_l & 0x300) == 0x200); + _OUTPUT (".._SAVE", (othermode_l & 0x300) == 0x300); + i -= 16; + OUTPUT_ ("ZM_OPA", (othermode_l & 0xC00) == 0x000); + _OUTPUT ("ZM_INTER", (othermode_l & 0xC00) == 0x400); + _OUTPUT ("ZM_XLU", (othermode_l & 0xC00) == 0x800); + _OUTPUT ("ZM_DEC", (othermode_l & 0xC00) == 0xC00); + i -= 16; + OUTPUT_ ("CVG_X_ALPHA", othermode_l & 0x1000); + i -= 16; + OUTPUT_ ("ALPHA_CVG_SEL", othermode_l & 0x2000); + i -= 16; + OUTPUT_ ("FORCE_BL", othermode_l & 0x4000); + } + if (_debugger.page == PAGE_OTHERMODE_H && _debugger.tri_sel) + { + wxUint32 othermode_h = _debugger.tri_sel->othermode_h; + COL_CATEGORY (); + OUTPUT ("OTHERMODE_H: %08lx", othermode_h); + OUTPUT_ ("CK_NONE", (othermode_h & 0x100) == 0); + _OUTPUT ("CK_KEY", (othermode_h & 0x100) == 1); + i -= 16; + OUTPUT_ ("TC_CONV", (othermode_h & 0xE00) == 0x200); + _OUTPUT ("TC_FILTCONV", (othermode_h & 0xE00) == 0xA00); + _OUTPUT ("TC_FILT", (othermode_h & 0xE00) == 0xC00); + i -= 16; + OUTPUT_ ("TF_POINT", (othermode_h & 0x3000) == 0x0000); + _OUTPUT ("TF_AVERAGE", (othermode_h & 0x3000) == 0x3000); + _OUTPUT ("TF_BILERP", (othermode_h & 0x3000) == 0x2000); + i -= 16; + OUTPUT_ ("TT_NONE", (othermode_h & 0xC000) == 0x0000); + _OUTPUT ("TT_RGBA16", (othermode_h & 0xC000) == 0x8000); + _OUTPUT ("TT_IA16", (othermode_h & 0xC000) == 0xC000); + i -= 16; + OUTPUT_ ("TL_TILE", (othermode_h & 0x10000) == 0x00000); + _OUTPUT ("TL_LOD", (othermode_h & 0x10000) == 0x10000); + i -= 16; + OUTPUT_ ("TD_CLAMP", (othermode_h & 0x60000) == 0x00000); + _OUTPUT ("TD_SHARPEN", (othermode_h & 0x60000) == 0x20000); + _OUTPUT ("TD_DETAIL", (othermode_h & 0x60000) == 0x40000); + i -= 16; + OUTPUT_ ("TP_NONE", (othermode_h & 0x80000) == 0x00000); + _OUTPUT ("TP_PERSP", (othermode_h & 0x80000) == 0x80000); + i -= 16; + OUTPUT_ ("1CYCLE", (othermode_h & 0x300000) == 0x000000); + _OUTPUT ("2CYCLE", (othermode_h & 0x300000) == 0x100000); + _OUTPUT ("COPY", (othermode_h & 0x300000) == 0x200000); + _OUTPUT ("FILL", (othermode_h & 0x300000) == 0x300000); + i -= 16; + OUTPUT_ ("PM_1PRIM", (othermode_h & 0x400000) == 0x000000); + _OUTPUT ("PM_NPRIM", (othermode_h & 0x400000) == 0x400000); + } + if (_debugger.page == PAGE_TEXELS && _debugger.tri_sel) + { + // change these to output whatever you need, ou for triangles, or u0 for texrects + COL_TEXT(); + OUTPUT ("n: %d", _debugger.tri_sel->nv); + OUTPUT ("",0); + for (j=0; j<_debugger.tri_sel->nv; j++) + { + OUTPUT1 ("v[%d].s0: %f", j, _debugger.tri_sel->v[j].ou); + OUTPUT1 ("v[%d].t0: %f", j, _debugger.tri_sel->v[j].ov); + } + OUTPUT ("",0); + for (j=0; j<_debugger.tri_sel->nv; j++) + { + OUTPUT1 ("v[%d].s1: %f", j, _debugger.tri_sel->v[j].u0); + OUTPUT1 ("v[%d].t1: %f", j, _debugger.tri_sel->v[j].v0); + } + } + if (_debugger.page == PAGE_COORDS && _debugger.tri_sel) + { + COL_TEXT(); + OUTPUT ("n: %d", _debugger.tri_sel->nv); + for (j=0; j<_debugger.tri_sel->nv; j++) + { + OUTPUT1 ("v[%d].x: %f", j, _debugger.tri_sel->v[j].x); + OUTPUT1 ("v[%d].y: %f", j, _debugger.tri_sel->v[j].y); + OUTPUT1 ("v[%d].z: %f", j, _debugger.tri_sel->v[j].z); + OUTPUT1 ("v[%d].w: %f", j, _debugger.tri_sel->v[j].w); + OUTPUT1 ("v[%d].f: %f", j, 1.0f/_debugger.tri_sel->v[j].f); + OUTPUT1 ("v[%d].r: %d", j, _debugger.tri_sel->v[j].r); + OUTPUT1 ("v[%d].g: %d", j, _debugger.tri_sel->v[j].g); + OUTPUT1 ("v[%d].b: %d", j, _debugger.tri_sel->v[j].b); + OUTPUT1 ("v[%d].a: %d", j, _debugger.tri_sel->v[j].a); + } + } + if (_debugger.page == PAGE_TEX_INFO && _debugger.tex_sel < (wxUint32)rdp.n_cached[_debugger.tmu]) + { + COL_CATEGORY(); + OUTPUT ("CACHE (page 0)", 0); + COL_TEXT(); + //OUTPUT ("t_mem: %08lx", rdp.cache[0][_debugger.tex_sel].t_mem); + //OUTPUT ("crc: %08lx", rdp.cache[0][_debugger.tex_sel].crc); + OUTPUT ("addr: %08lx", cache[_debugger.tex_sel].addr); + OUTPUT ("scale_x: %f", cache[_debugger.tex_sel].scale_x); + OUTPUT ("scale_y: %f", cache[_debugger.tex_sel].scale_y); + OUTPUT ("tmem_addr: %08lx", cache[_debugger.tex_sel].tmem_addr); + OUTPUT ("palette: %08lx", cache[_debugger.tex_sel].palette); + OUTPUT ("set_by: %08lx", cache[_debugger.tex_sel].set_by); + OUTPUT ("texrecting: %d", cache[_debugger.tex_sel].texrecting); + + OUTPUT ("mod: %08lx", cache[_debugger.tex_sel].mod); + OUTPUT ("mod_col: %08lx", cache[_debugger.tex_sel].mod_color); + OUTPUT ("mod_col1: %08lx", cache[_debugger.tex_sel].mod_color1); + i=740; + output(800,(float)i,1,"width: %d", cache[_debugger.tex_sel].width); + i-=16; + output(800,(float)i,1,"height: %d", cache[_debugger.tex_sel].height); + i-=16; + output(800,(float)i,1,"format: %d", cache[_debugger.tex_sel].format); + i-=16; + output(800,(float)i,1,"size: %d", cache[_debugger.tex_sel].size); + i-=16; + output(800,(float)i,1,"crc: %08lx", cache[_debugger.tex_sel].crc); + i-=16; +#ifdef TEXTURE_FILTER + output(800,(float)i,1,"RiceCrc: %08lx", (wxUint32)(rdp.cache[_debugger.tmu][_debugger.tex_sel].ricecrc&0xFFFFFFFF)); + i-=16; + output(800,(float)i,1,"RicePalCrc: %08lx", (wxUint32)(rdp.cache[_debugger.tmu][_debugger.tex_sel].ricecrc>>32)); + i-=16; +#endif + output(800,(float)i,1,"flags: %08lx", cache[_debugger.tex_sel].flags); + i-=16; + output(800,(float)i,1,"line: %d", cache[_debugger.tex_sel].line); + i-=16; + output(800,(float)i,1,"mod_factor: %08lx", cache[_debugger.tex_sel].mod_factor); + i-=32; + + output(800,(float)i,1,"lod: %s", str_lod[cache[_debugger.tex_sel].lod]); + i-=16; + output(800,(float)i,1,"aspect: %s", str_aspect[cache[_debugger.tex_sel].aspect + 3]); + +// debug_texture(_debugger.tmu, cache[_debugger.tex_sel].addr, _debugger.tex_sel); + } + + // Draw the vertex numbers + if (_debugger.tri_sel) + { + for (i=0; i<_debugger.tri_sel->nv; i++) + { + grConstantColorValue (0x000000FF); + output (_debugger.tri_sel->v[i].x+1, settings.scr_res_y-_debugger.tri_sel->v[i].y+1, 1, + "%d", i); + grConstantColorValue (0xFFFFFFFF); + output (_debugger.tri_sel->v[i].x, settings.scr_res_y-_debugger.tri_sel->v[i].y, 1, + "%d", i); + } + } + + // Draw the cursor + debug_mouse (); + + grBufferSwap (1); + } + +END: + // Release all data + delete [] _debugger.screen; + TRI_INFO *tri; + for (tri=_debugger.tri_list; tri != _debugger.tri_last;) + { + TRI_INFO *tmp = tri; + tri = tri->pNext; + delete [] tmp->v; + delete tmp; + } + delete [] tri->v; + delete tri; + + // Reset all values + _debugger.capture = 0; + _debugger.selected = SELECTED_TRI; + _debugger.screen = NULL; + _debugger.tri_list = NULL; + _debugger.tri_last = NULL; + _debugger.tri_sel = NULL; + _debugger.tex_sel = 0; +} + +// +// debug_mouse - draws the debugger mouse +// + +void debug_mouse () +{ + grColorCombine (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_NONE, + GR_COMBINE_OTHER_TEXTURE, + FXFALSE); + + grAlphaCombine (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_NONE, + GR_COMBINE_OTHER_TEXTURE, + FXFALSE); + + // Draw the cursor + POINT pt; + DbgCursorPos(&pt); + float cx = (float)pt.x; + float cy = (float)pt.y; + + VERTEX v[4] = { + { cx, cy, 1, 1, 0, 0, 0, 0, {0, 0, 0, 0} }, + { cx+32, cy, 1, 1, 255, 0, 0, 0, {0, 0, 0, 0} }, + { cx, cy+32, 1, 1, 0, 255, 0, 0, {0, 0, 0, 0} }, + { cx+32, cy+32, 1, 1, 255, 255, 0, 0, {0, 0, 0, 0} } + }; + + ConvertCoordsKeep (v, 4); + + grTexSource(GR_TMU0, + voodoo.tex_min_addr[GR_TMU0] + offset_cursor, + GR_MIPMAPLEVELMASK_BOTH, + &cursorTex); + + if (voodoo.num_tmu >= 3) + grTexCombine (GR_TMU2, + GR_COMBINE_FUNCTION_NONE, + GR_COMBINE_FACTOR_NONE, + GR_COMBINE_FUNCTION_NONE, + GR_COMBINE_FACTOR_NONE, FXFALSE, FXFALSE); + if (voodoo.num_tmu >= 2) + grTexCombine (GR_TMU1, + GR_COMBINE_FUNCTION_NONE, + GR_COMBINE_FACTOR_NONE, + GR_COMBINE_FUNCTION_NONE, + GR_COMBINE_FACTOR_NONE, FXFALSE, FXFALSE); + grTexCombine (GR_TMU0, + GR_COMBINE_FUNCTION_LOCAL, + GR_COMBINE_FACTOR_NONE, + GR_COMBINE_FUNCTION_LOCAL, + GR_COMBINE_FACTOR_NONE, FXFALSE, FXFALSE); + + grDrawTriangle (&v[0], &v[1], &v[2]); + grDrawTriangle (&v[1], &v[3], &v[2]); +} + +// +// debug_keys - receives debugger key input +// + +void debug_keys () +{ + if (CheckKeyPressed(G64_VK_RIGHT, 0x0001) && _debugger.tri_sel) + { + TRI_INFO *start = _debugger.tri_sel; + + while (_debugger.tri_sel->pNext != start) + _debugger.tri_sel = _debugger.tri_sel->pNext; + } + + if (CheckKeyPressed(G64_VK_LEFT, 0x0001) && _debugger.tri_sel) + _debugger.tri_sel = _debugger.tri_sel->pNext; + + // Check for page changes + if (CheckKeyPressed(G64_VK_1, 0x0001)) + _debugger.page = PAGE_GENERAL; + if (CheckKeyPressed(G64_VK_2, 0x0001)) + _debugger.page = PAGE_TEX1; + if (CheckKeyPressed(G64_VK_3, 0x0001)) + _debugger.page = PAGE_TEX2; + if (CheckKeyPressed(G64_VK_4, 0x0001)) + _debugger.page = PAGE_COLORS; + if (CheckKeyPressed(G64_VK_5, 0x0001)) + _debugger.page = PAGE_FBL; + if (CheckKeyPressed(G64_VK_6, 0x0001)) + _debugger.page = PAGE_OTHERMODE_L; + if (CheckKeyPressed(G64_VK_7, 0x0001)) + _debugger.page = PAGE_OTHERMODE_H; + if (CheckKeyPressed(G64_VK_8, 0x0001)) + _debugger.page = PAGE_TEXELS; + if (CheckKeyPressed(G64_VK_9, 0x0001)) + _debugger.page = PAGE_COORDS; + if (CheckKeyPressed(G64_VK_0, 0x0001)) + _debugger.page = PAGE_TEX_INFO; + if (CheckKeyPressed(G64_VK_Q, 0x0001)) + _debugger.tmu = 0; + if (CheckKeyPressed(G64_VK_W, 0x0001)) + _debugger.tmu = 1; + + if (CheckKeyPressed(G64_VK_G, 0x0001)) + grid = !grid; + + // Go to texture + if (CheckKeyPressed(G64_VK_SPACE, 0x0001)) + { + int tile = -1; + if (_debugger.page == PAGE_TEX2) + tile = 1; + else + tile = 0; + if (tile != -1) + { + _debugger.tmu = _debugger.tri_sel->t[tile].tmu; + _debugger.tex_sel = _debugger.tri_sel->t[tile].cur_cache[_debugger.tmu]; + _debugger.tex_scroll = (_debugger.tri_sel->t[tile].cur_cache[_debugger.tmu] >> 4) - 1; + } + } + + // Go to triangle + CACHE_LUT * cache = voodoo.tex_UMA?rdp.cache[0]:rdp.cache[_debugger.tmu]; + if (CheckKeyPressed(G64_VK_CONTROL, 0x0001)) + { + int count = rdp.debug_n - cache[_debugger.tex_sel].uses - 1; + if (cache[_debugger.tex_sel].last_used == frame_count) + { + TRI_INFO *t = _debugger.tri_list; + while (count && t) { + t = t->pNext; + count --; + } + _debugger.tri_sel = t; + } + else + _debugger.tri_sel = NULL; + } + + if (CheckKeyPressed(G64_VK_A, 0x0001)) + _debugger.draw_mode = 0; // texture & texture alpha + if (CheckKeyPressed(G64_VK_S, 0x0001)) + _debugger.draw_mode = 1; // texture + if (CheckKeyPressed(G64_VK_D, 0x0001)) + _debugger.draw_mode = 2; // texture alpha + + // Check for texture scrolling + if (CheckKeyPressed(G64_VK_DOWN, 0x0001)) + _debugger.tex_scroll ++; + if (CheckKeyPressed(G64_VK_UP, 0x0001)) + _debugger.tex_scroll --; +} + +// +// output - output debugger text +// + +void output (float x, float y, int scale, const char *fmt, ...) +{ + va_list ap; + va_start(ap,fmt); + vsprintf(out_buf, fmt, ap); + va_end(ap); + + wxUint8 c,r; + for (wxUint32 i=0; i> 5) * 16;//<< 4; + VERTEX v[4] = { { SX(x), SY(768-y), 1, 1, (float)c, r+16.0f, 0, 0, {0, 0, 0, 0} }, + { SX(x+8), SY(768-y), 1, 1, c+8.0f, r+16.0f, 0, 0, {0, 0, 0, 0} }, + { SX(x), SY(768-y-16), 1, 1, (float)c, (float)r, 0, 0, {0, 0, 0, 0} }, + { SX(x+8), SY(768-y-16), 1, 1, c+8.0f, (float)r, 0, 0, {0, 0, 0, 0} } + }; + if (!scale) + { + v[0].x = x; + v[0].y = y; + v[1].x = x+8; + v[1].y = y; + v[2].x = x; + v[2].y = y-16; + v[3].x = x+8; + v[3].y = y-16; + } + + ConvertCoordsKeep (v, 4); + + grDrawTriangle (&v[0], &v[1], &v[2]); + grDrawTriangle (&v[1], &v[3], &v[2]); + + x+=8; + } +} diff --git a/Source/Glide64/Debugger.h b/Source/Glide64/Debugger.h new file mode 100644 index 000000000..cc6b7444c --- /dev/null +++ b/Source/Glide64/Debugger.h @@ -0,0 +1,137 @@ +/* +* Glide64 - Glide video plugin for Nintendo 64 emulators. +* Copyright (c) 2002 Dave2001 +* Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski +* +* 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 +* 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 +*/ + +//**************************************************************** +// +// Glide64 - Glide Plugin for Nintendo 64 emulators +// Project started on December 29th, 2001 +// +// Authors: +// Dave2001, original author, founded the project in 2001, left it in 2002 +// Gugaman, joined the project in 2002, left it in 2002 +// Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002 +// Hiroshi 'KoolSmoky' Morii, joined the project in 2007 +// +//**************************************************************** +// +// To modify Glide64: +// * Write your name and (optional)email, commented by your work, so I know who did it, and so that you can find which parts you modified when it comes time to send it to me. +// * Do NOT send me the whole project or file that you modified. Take out your modified code sections, and tell me where to put them. If people sent the whole thing, I would have many different versions, but no idea how to combine them all. +// +//**************************************************************** + +#define SELECTED_NONE 0x00000000 +#define SELECTED_TRI 0x00000001 +#define SELECTED_TEX 0x00000002 + +typedef struct TEX_INFO_t +{ + wxUint32 cur_cache[2]; // Current cache # + wxUint8 format; + wxUint8 size; + wxUint32 width, height; + wxUint16 line, wid; + wxUint8 palette; + wxUint8 clamp_s, clamp_t; + wxUint8 mirror_s, mirror_t; + wxUint8 mask_s, mask_t; + wxUint8 shift_s, shift_t; + wxUint16 ul_s, ul_t, lr_s, lr_t; + wxUint16 t_ul_s, t_ul_t, t_lr_s, t_lr_t; + float scale_s, scale_t; + int tmu; +} TEX_INFO; + +typedef struct TRI_INFO_t +{ + wxUint32 nv; // Number of vertices + VERTEX *v; // Vertices (2d screen coords) of the triangle, used to outline + wxUint32 cycle1, cycle2, cycle_mode; // Combine mode at the time of rendering + wxUint8 uncombined; // which is uncombined: 0x01=color 0x02=alpha 0x03=both + wxUint32 geom_mode; // geometry mode flags + wxUint32 othermode_h; // setothermode_h flags + wxUint32 othermode_l; // setothermode_l flags + wxUint32 tri_n; // Triangle number + wxUint32 flags; + + int type; // 0-normal, 1-texrect, 2-fillrect + + // texture info + TEX_INFO t[2]; + + // colors + wxUint32 fog_color; + wxUint32 fill_color; + wxUint32 prim_color; + wxUint32 blend_color; + wxUint32 env_color; + wxUint32 prim_lodmin, prim_lodfrac; + + TRI_INFO_t *pNext; +} TRI_INFO; + +typedef struct DEBUGGER_t +{ + int capture; // Capture moment for debugging? + + wxUint32 selected; // Selected object (see flags above) + TRI_INFO *tri_sel; + + wxUint32 tex_scroll; // texture scrolling + wxUint32 tex_sel; + + // CAPTURE INFORMATION + wxUint8 *screen; // Screen capture + TRI_INFO *tri_list; // Triangle information list + TRI_INFO *tri_last; // Last in the list (first in) + + wxUint32 tmu; // tmu # + + wxUint32 draw_mode; + + // Page number + int page; + +} GLIDE64_DEBUGGER; + +#define PAGE_GENERAL 0 +#define PAGE_TEX1 1 +#define PAGE_TEX2 2 +#define PAGE_COLORS 3 +#define PAGE_FBL 4 +#define PAGE_OTHERMODE_L 5 +#define PAGE_OTHERMODE_H 6 +#define PAGE_TEXELS 7 +#define PAGE_COORDS 8 +#define PAGE_TEX_INFO 9 + +#define TRI_TRIANGLE 0 +#define TRI_TEXRECT 1 +#define TRI_FILLRECT 2 +#define TRI_BACKGROUND 3 + +extern GLIDE64_DEBUGGER _debugger; + +void debug_init (); +void debug_capture (); +void debug_cacheviewer (); +void debug_mouse (); +void debug_keys (); +void output (float x, float y, int scale, const char *fmt, ...); diff --git a/Source/Glide64/DepthBufferRender.cpp b/Source/Glide64/DepthBufferRender.cpp new file mode 100644 index 000000000..1e3949b9f --- /dev/null +++ b/Source/Glide64/DepthBufferRender.cpp @@ -0,0 +1,300 @@ +/* +* Glide64 - Glide video plugin for Nintendo 64 emulators. +* Copyright (c) 2002 Dave2001 +* Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski +* +* 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 +* 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 +*/ + +//**************************************************************** +// +// Glide64 - Glide Plugin for Nintendo 64 emulators +// Project started on December 29th, 2001 +// +// Authors: +// Dave2001, original author, founded the project in 2001, left it in 2002 +// Gugaman, joined the project in 2002, left it in 2002 +// Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002 +// Hiroshi 'KoolSmoky' Morii, joined the project in 2007 +// +//**************************************************************** +// +// To modify Glide64: +// * Write your name and (optional)email, commented by your work, so I know who did it, and so that you can find which parts you modified when it comes time to send it to me. +// * Do NOT send me the whole project or file that you modified. Take out your modified code sections, and tell me where to put them. If people sent the whole thing, I would have many different versions, but no idea how to combine them all. +// +//**************************************************************** +// +// Software rendering into N64 depth buffer +// Idea and N64 depth value format by Orkin +// Polygon rasterization algorithm is taken from FATMAP2 engine by Mats Byggmastar, mri@penti.sit.fi +// +// Created by Gonetz, Dec 2004 +// +//**************************************************************** + +#include "Gfx #1.3.h" +#include "rdp.h" +#include "DepthBufferRender.h" + +wxUint16 * zLUT = 0; + +void ZLUT_init() +{ + if (zLUT) + return; + zLUT = new wxUint16[0x40000]; + for(int i=0; i<0x40000; i++) + { + wxUint32 exponent = 0; + wxUint32 testbit = 1 << 17; + while((i & testbit) && (exponent < 7)) + { + exponent++; + testbit = 1 << (17 - exponent); + } + + wxUint32 mantissa = (i >> (6 - (6 < exponent ? 6 : exponent))) & 0x7ff; + zLUT[i] = (wxUint16)(((exponent << 11) | mantissa) << 2); + } +} + +void ZLUT_release() +{ + delete[] zLUT; + zLUT = 0; +} + +static vertexi * max_vtx; // Max y vertex (ending vertex) +static vertexi * start_vtx, * end_vtx; // First and last vertex in array +static vertexi * right_vtx, * left_vtx; // Current right and left vertex + +static int right_height, left_height; +static int right_x, right_dxdy, left_x, left_dxdy; +static int left_z, left_dzdy; + +extern "C" int imul16(int x, int y); +extern "C" int imul14(int x, int y); +extern "C" int idiv16(int x, int y); + +__inline int iceil(int x) +{ + x += 0xffff; + return (x >> 16); +} + +static void RightSection(void) +{ + // Walk backwards trough the vertex array + + vertexi * v2, * v1 = right_vtx; + if(right_vtx > start_vtx) v2 = right_vtx-1; + else v2 = end_vtx; // Wrap to end of array + right_vtx = v2; + + // v1 = top vertex + // v2 = bottom vertex + + // Calculate number of scanlines in this section + + right_height = iceil(v2->y) - iceil(v1->y); + if(right_height <= 0) return; + + // Guard against possible div overflows + + if(right_height > 1) { + // OK, no worries, we have a section that is at least + // one pixel high. Calculate slope as usual. + + int height = v2->y - v1->y; + right_dxdy = idiv16(v2->x - v1->x, height); + } + else { + // Height is less or equal to one pixel. + // Calculate slope = width * 1/height + // using 18:14 bit precision to avoid overflows. + + int inv_height = (0x10000 << 14) / (v2->y - v1->y); + right_dxdy = imul14(v2->x - v1->x, inv_height); + } + + // Prestep initial values + + int prestep = (iceil(v1->y) << 16) - v1->y; + right_x = v1->x + imul16(prestep, right_dxdy); +} + +static void LeftSection(void) +{ + // Walk forward trough the vertex array + + vertexi * v2, * v1 = left_vtx; + if(left_vtx < end_vtx) v2 = left_vtx+1; + else v2 = start_vtx; // Wrap to start of array + left_vtx = v2; + + // v1 = top vertex + // v2 = bottom vertex + + // Calculate number of scanlines in this section + + left_height = iceil(v2->y) - iceil(v1->y); + if(left_height <= 0) return; + + // Guard against possible div overflows + + if(left_height > 1) { + // OK, no worries, we have a section that is at least + // one pixel high. Calculate slope as usual. + + int height = v2->y - v1->y; + left_dxdy = idiv16(v2->x - v1->x, height); + left_dzdy = idiv16(v2->z - v1->z, height); + } + else { + // Height is less or equal to one pixel. + // Calculate slope = width * 1/height + // using 18:14 bit precision to avoid overflows. + + int inv_height = (0x10000 << 14) / (v2->y - v1->y); + left_dxdy = imul14(v2->x - v1->x, inv_height); + left_dzdy = imul14(v2->z - v1->z, inv_height); + } + + // Prestep initial values + + int prestep = (iceil(v1->y) << 16) - v1->y; + left_x = v1->x + imul16(prestep, left_dxdy); + left_z = v1->z + imul16(prestep, left_dzdy); +} + + +void Rasterize(vertexi * vtx, int vertices, int dzdx) +{ + start_vtx = vtx; // First vertex in array + + // Search trough the vtx array to find min y, max y + // and the location of these structures. + + vertexi * min_vtx = vtx; + max_vtx = vtx; + + int min_y = vtx->y; + int max_y = vtx->y; + + vtx++; + + for(int n=1; ny < min_y) { + min_y = vtx->y; + min_vtx = vtx; + } + else + if(vtx->y > max_y) { + max_y = vtx->y; + max_vtx = vtx; + } + vtx++; + } + + // OK, now we know where in the array we should start and + // where to end while scanning the edges of the polygon + + left_vtx = min_vtx; // Left side starting vertex + right_vtx = min_vtx; // Right side starting vertex + end_vtx = vtx-1; // Last vertex in array + + // Search for the first usable right section + + do { + if(right_vtx == max_vtx) return; + RightSection(); + } while(right_height <= 0); + + // Search for the first usable left section + + do { + if(left_vtx == max_vtx) return; + LeftSection(); + } while(left_height <= 0); + + wxUint16 * destptr = (wxUint16*)(gfx.RDRAM+rdp.zimg); + int y1 = iceil(min_y); + if (y1 >= (int)rdp.scissor_o.lr_y) return; + int shift; + + for(;;) + { + int x1 = iceil(left_x); + if (x1 < (int)rdp.scissor_o.ul_x) + x1 = rdp.scissor_o.ul_x; + int width = iceil(right_x) - x1; + if (x1+width >= (int)rdp.scissor_o.lr_x) + width = rdp.scissor_o.lr_x - x1 - 1; + + if(width > 0 && y1 >= (int)rdp.scissor_o.ul_y) { + + // Prestep initial z + + int prestep = (x1 << 16) - left_x; + int z = left_z + imul16(prestep, dzdx); + + shift = x1 + y1*rdp.zi_width; + //draw to depth buffer + int trueZ; + int idx; + wxUint16 encodedZ; + for (int x = 0; x < width; x++) + { + trueZ = z/8192; + if (trueZ < 0) trueZ = 0; + else if (trueZ > 0x3FFFF) trueZ = 0x3FFFF; + encodedZ = zLUT[trueZ]; + idx = (shift+x)^1; + if(encodedZ < destptr[idx]) + destptr[idx] = encodedZ; + z += dzdx; + } + } + + //destptr += rdp.zi_width; + y1++; + if (y1 >= (int)rdp.scissor_o.lr_y) return; + + // Scan the right side + + if(--right_height <= 0) { // End of this section? + do { + if(right_vtx == max_vtx) return; + RightSection(); + } while(right_height <= 0); + } + else + right_x += right_dxdy; + + // Scan the left side + + if(--left_height <= 0) { // End of this section? + do { + if(left_vtx == max_vtx) return; + LeftSection(); + } while(left_height <= 0); + } + else { + left_x += left_dxdy; + left_z += left_dzdy; + } + } +} diff --git a/Source/Glide64/DepthBufferRender.h b/Source/Glide64/DepthBufferRender.h new file mode 100644 index 000000000..e8760024b --- /dev/null +++ b/Source/Glide64/DepthBufferRender.h @@ -0,0 +1,60 @@ +/* +* Glide64 - Glide video plugin for Nintendo 64 emulators. +* Copyright (c) 2002 Dave2001 +* Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski +* +* 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 +* 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 +*/ + +//**************************************************************** +// +// Glide64 - Glide Plugin for Nintendo 64 emulators +// Project started on December 29th, 2001 +// +// Authors: +// Dave2001, original author, founded the project in 2001, left it in 2002 +// Gugaman, joined the project in 2002, left it in 2002 +// Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002 +// Hiroshi 'KoolSmoky' Morii, joined the project in 2007 +// +//**************************************************************** +// +// To modify Glide64: +// * Write your name and (optional)email, commented by your work, so I know who did it, and so that you can find which parts you modified when it comes time to send it to me. +// * Do NOT send me the whole project or file that you modified. Take out your modified code sections, and tell me where to put them. If people sent the whole thing, I would have many different versions, but no idea how to combine them all. +// +//**************************************************************** +// +// Software rendering to N64 depth buffer +// Created by Gonetz, Dec 2004 +// +//**************************************************************** + +#ifndef DEPTH_BUFFER_RENDER_H +#define DEPTH_BUFFER_RENDER_H + +struct vertexi +{ + int x,y; // Screen position in 16:16 bit fixed point + int z; // z value in 16:16 bit fixed point +}; + +extern wxUint16 * zLUT; +void ZLUT_init(); +void ZLUT_release(); + +void Rasterize(vertexi * vtx, int vertices, int dzdx); + +#endif //DEPTH_BUFFER_RENDER_H diff --git a/Source/Glide64/Ext_TxFilter.cpp b/Source/Glide64/Ext_TxFilter.cpp new file mode 100644 index 000000000..df77c125b --- /dev/null +++ b/Source/Glide64/Ext_TxFilter.cpp @@ -0,0 +1,164 @@ +/* + * Texture Filtering + * Version: 1.0 + * + * Copyright (C) 2007 Hiroshi Morii All Rights Reserved. + * Email koolsmoky(at)users.sourceforge.net + * Web http://www.3dfxzone.it/koolsmoky + * + * this 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, or (at your option) + * any later version. + * + * this 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 GNU Make; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include "Ext_TxFilter.h" + +typedef boolean (*txfilter_init)(int maxwidth, int maxheight, int maxbpp, + int options, int cachesize, + wchar_t *path, wchar_t *ident, + dispInfoFuncExt callback); + +typedef void (*txfilter_shutdown)(void); + +typedef boolean (*txfilter_filter)(unsigned char *src, int srcwidth, int srcheight, unsigned short srcformat, + uint64 g64crc, GHQTexInfo *info); + +typedef boolean (*txfilter_hirestex)(uint64 g64crc, uint64 r_crc64, unsigned short *palette, GHQTexInfo *info); + +typedef uint64 (*txfilter_checksum)(unsigned char *src, int width, int height, int size, int rowStride, unsigned char *palette); + +typedef boolean (*txfilter_dmptx)(unsigned char *src, int width, int height, int rowStridePixel, unsigned short gfmt, unsigned short n64fmt, uint64 r_crc64); + +typedef boolean (*txfilter_reloadhirestex)(); + +static struct { + TXHMODULE lib; + txfilter_init init; + txfilter_shutdown shutdown; + txfilter_filter filter; + txfilter_hirestex hirestex; + txfilter_checksum checksum; + txfilter_dmptx dmptx; + txfilter_reloadhirestex reloadhirestex; +} txfilter; + +void ext_ghq_shutdown(void) +{ + if (txfilter.shutdown) + (*txfilter.shutdown)(); + + if (txfilter.lib) { + DLCLOSE(txfilter.lib); + memset(&txfilter, 0, sizeof(txfilter)); + } +} + +boolean ext_ghq_init(int maxwidth, int maxheight, int maxbpp, int options, int cachesize, + wchar_t *path, wchar_t *ident, + dispInfoFuncExt callback) +{ + boolean bRet = 0; + + if (!txfilter.lib) { + wchar_t curpath[MAX_PATH]; + wcscpy(curpath, path); +#ifdef WIN32 + wcscat(curpath, L"\\GlideHQ.dll"); + txfilter.lib = DLOPEN(curpath); +#else + char cbuf[MAX_PATH]; + wcscat(curpath, L"/GlideHQ.so"); + wcstombs(cbuf, curpath, MAX_PATH); + txfilter.lib = DLOPEN(cbuf); +#endif + } + + if (txfilter.lib) { + if (!txfilter.init) + txfilter.init = (txfilter_init)DLSYM(txfilter.lib, "txfilter_init"); + if (!txfilter.shutdown) + txfilter.shutdown = (txfilter_shutdown)DLSYM(txfilter.lib, "txfilter_shutdown"); + if (!txfilter.filter) + txfilter.filter = (txfilter_filter)DLSYM(txfilter.lib, "txfilter"); + if (!txfilter.hirestex) + txfilter.hirestex = (txfilter_hirestex)DLSYM(txfilter.lib, "txfilter_hirestex"); + if (!txfilter.checksum) + txfilter.checksum = (txfilter_checksum)DLSYM(txfilter.lib, "txfilter_checksum"); + if (!txfilter.dmptx) + txfilter.dmptx = (txfilter_dmptx)DLSYM(txfilter.lib, "txfilter_dmptx"); + if (!txfilter.reloadhirestex) + txfilter.reloadhirestex = (txfilter_reloadhirestex)DLSYM(txfilter.lib, "txfilter_reloadhirestex"); + } + + if (txfilter.init && txfilter.shutdown && txfilter.filter && + txfilter.hirestex && txfilter.checksum /*&& txfilter.dmptx && txfilter.reloadhirestex */) + bRet = (*txfilter.init)(maxwidth, maxheight, maxbpp, options, cachesize, path, ident, callback); + else + ext_ghq_shutdown(); + + return bRet; +} + +boolean ext_ghq_txfilter(unsigned char *src, int srcwidth, int srcheight, unsigned short srcformat, + uint64 g64crc, GHQTexInfo *info) +{ + boolean ret = 0; + + if (txfilter.filter) + ret = (*txfilter.filter)(src, srcwidth, srcheight, srcformat, + g64crc, info); + + return ret; +} + +boolean ext_ghq_hirestex(uint64 g64crc, uint64 r_crc64, unsigned short *palette, GHQTexInfo *info) +{ + boolean ret = 0; + + if (txfilter.hirestex) + ret = (*txfilter.hirestex)(g64crc, r_crc64, palette, info); + + return ret; +} + +uint64 ext_ghq_checksum(unsigned char *src, int width, int height, int size, int rowStride, unsigned char *palette) +{ + uint64 ret = 0; + + if (txfilter.checksum) + ret = (*txfilter.checksum)(src, width, height, size, rowStride, palette); + + return ret; +} + +boolean ext_ghq_dmptx(unsigned char *src, int width, int height, int rowStridePixel, unsigned short gfmt, unsigned short n64fmt, uint64 r_crc64) +{ + boolean ret = 0; + + if (txfilter.dmptx) + ret = (*txfilter.dmptx)(src, width, height, rowStridePixel, gfmt, n64fmt, r_crc64); + + return ret; +} + +boolean ext_ghq_reloadhirestex() +{ + boolean ret = 0; + + if (txfilter.reloadhirestex) + ret = (*txfilter.reloadhirestex)(); + + return ret; +} diff --git a/Source/Glide64/Ext_TxFilter.h b/Source/Glide64/Ext_TxFilter.h new file mode 100644 index 000000000..2ea585a89 --- /dev/null +++ b/Source/Glide64/Ext_TxFilter.h @@ -0,0 +1,211 @@ +/* + * Texture Filtering + * Version: 1.0 + * + * Copyright (C) 2007 Hiroshi Morii All Rights Reserved. + * Email koolsmoky(at)users.sourceforge.net + * Web http://www.3dfxzone.it/koolsmoky + * + * this 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, or (at your option) + * any later version. + * + * this 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 GNU Make; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __EXT_TXFILTER_H__ +#define __EXT_TXFILTER_H__ + +#ifdef WIN32 +#include +#define TXHMODULE HMODULE +#define DLOPEN(a) LoadLibraryW(a) +#define DLCLOSE(a) FreeLibrary(a) +#define DLSYM(a, b) GetProcAddress(a, b) +#define GETCWD(a, b) GetCurrentDirectoryW(a, b) +#define CHDIR(a) SetCurrentDirectoryW(a) +#else +#include +#include +#define MAX_PATH 4095 +#define TXHMODULE void* +#define DLOPEN(a) dlopen(a, RTLD_LAZY|RTLD_GLOBAL) +#define DLCLOSE(a) dlclose(a) +#define DLSYM(a, b) dlsym(a, b) +#define GETCWD(a, b) getcwd(b, a) +#define CHDIR(a) chdir(a) +#endif + +#ifdef __MSC__ +typedef __int64 int64; +typedef unsigned __int64 uint64; +#else +typedef long long int64; +typedef unsigned long long uint64; +typedef unsigned char boolean; +#endif + +#define NO_OPTIONS 0x00000000 + +#define FILTER_MASK 0x000000ff +#define NO_FILTER 0x00000000 +#define SMOOTH_FILTER_MASK 0x0000000f +#define NO_SMOOTH_FILTER 0x00000000 +#define SMOOTH_FILTER_1 0x00000001 +#define SMOOTH_FILTER_2 0x00000002 +#define SMOOTH_FILTER_3 0x00000003 +#define SMOOTH_FILTER_4 0x00000004 +#define SHARP_FILTER_MASK 0x000000f0 +#define NO_SHARP_FILTER 0x00000000 +#define SHARP_FILTER_1 0x00000010 +#define SHARP_FILTER_2 0x00000020 + +#define ENHANCEMENT_MASK 0x00000f00 +#define NO_ENHANCEMENT 0x00000000 +#define X2_ENHANCEMENT 0x00000100 +#define X2SAI_ENHANCEMENT 0x00000200 +#define HQ2X_ENHANCEMENT 0x00000300 +#define LQ2X_ENHANCEMENT 0x00000400 +#define HQ4X_ENHANCEMENT 0x00000500 +#define HQ2XS_ENHANCEMENT 0x00000600 +#define LQ2XS_ENHANCEMENT 0x00000700 + +#define COMPRESSION_MASK 0x0000f000 +#define NO_COMPRESSION 0x00000000 +#define FXT1_COMPRESSION 0x00001000 +#define NCC_COMPRESSION 0x00002000 +#define S3TC_COMPRESSION 0x00003000 + +#define HIRESTEXTURES_MASK 0x000f0000 +#define NO_HIRESTEXTURES 0x00000000 +#define GHQ_HIRESTEXTURES 0x00010000 +#define RICE_HIRESTEXTURES 0x00020000 +#define JABO_HIRESTEXTURES 0x00030000 + +#define COMPRESS_TEX 0x00100000 +#define COMPRESS_HIRESTEX 0x00200000 +#define GZ_TEXCACHE 0x00400000 +#define GZ_HIRESTEXCACHE 0x00800000 +#define DUMP_TEXCACHE 0x01000000 +#define DUMP_HIRESTEXCACHE 0x02000000 +#define TILE_HIRESTEX 0x04000000 +#define UNDEFINED_0 0x08000000 +#define FORCE16BPP_HIRESTEX 0x10000000 +#define FORCE16BPP_TEX 0x20000000 +#define LET_TEXARTISTS_FLY 0x40000000 /* a little freedom for texture artists */ +#define DUMP_TEX 0x80000000 + +#ifndef __GLIDE_H__ /* GLIDE3 */ +/* from 3Dfx Interactive Inc. glide.h */ +#define GR_TEXFMT_ALPHA_8 0x2 +#define GR_TEXFMT_INTENSITY_8 0x3 + +#define GR_TEXFMT_ALPHA_INTENSITY_44 0x4 +#define GR_TEXFMT_P_8 0x5 + +#define GR_TEXFMT_RGB_565 0xa +#define GR_TEXFMT_ARGB_1555 0xb +#define GR_TEXFMT_ARGB_4444 0xc +#define GR_TEXFMT_ALPHA_INTENSITY_88 0xd + +/* from 3Dfx Interactive Inc. g3ext.h */ +#define GR_TEXFMT_ARGB_CMP_FXT1 0x11 + +#define GR_TEXFMT_ARGB_8888 0x12 + +#define GR_TEXFMT_ARGB_CMP_DXT1 0x16 +#define GR_TEXFMT_ARGB_CMP_DXT3 0x18 +#define GR_TEXFMT_ARGB_CMP_DXT5 0x1A +#endif /* GLIDE3 */ + +struct GHQTexInfo { + unsigned char *data; + int width; + int height; + unsigned short format; + + int smallLodLog2; + int largeLodLog2; + int aspectRatioLog2; + + int tiles; + int untiled_width; + int untiled_height; + + unsigned char is_hires_tex; +}; + +/* Callback to display hires texture info. + * Gonetz + * + * void DispInfo(const char *format, ...) + * { + * va_list args; + * char buf[INFO_BUF]; + * + * va_start(args, format); + * vsprintf(buf, format, args); + * va_end(args); + * + * printf(buf); + * } + */ +#define INFO_BUF 4095 +typedef void (*dispInfoFuncExt)(const wchar_t *format, ...); + +#ifndef TXFILTER_DLL +boolean ext_ghq_init(int maxwidth, /* maximum texture width supported by hardware */ + int maxheight,/* maximum texture height supported by hardware */ + int maxbpp, /* maximum texture bpp supported by hardware */ + int options, /* options */ + int cachesize,/* cache textures to system memory */ + wchar_t *path, /* plugin directory. must be smaller than MAX_PATH */ + wchar_t *ident, /* name of ROM. must be no longer than 64 in character. */ + dispInfoFuncExt callback /* callback function to display info */ + ); + +void ext_ghq_shutdown(void); + +boolean ext_ghq_txfilter(unsigned char *src, /* input texture */ + int srcwidth, /* width of input texture */ + int srcheight, /* height of input texture */ + unsigned short srcformat, /* format of input texture */ + uint64 g64crc, /* glide64 crc */ + GHQTexInfo *info /* output */ + ); + +boolean ext_ghq_hirestex(uint64 g64crc, /* glide64 crc */ + uint64 r_crc64, /* checksum hi:palette low:texture */ + unsigned short *palette, /* palette for CI textures */ + GHQTexInfo *info /* output */ + ); + +uint64 ext_ghq_checksum(unsigned char *src, /* input texture */ + int width, /* width of texture */ + int height, /* height of texture */ + int size, /* type of texture pixel */ + int rowStride, /* row stride in bytes */ + unsigned char *palette /* palette */ + ); + +boolean ext_ghq_dmptx(unsigned char *src, /* input texture (must be in 3Dfx Glide format) */ + int width, /* width of texture */ + int height, /* height of texture */ + int rowStridePixel, /* row stride of input texture in pixels */ + unsigned short gfmt, /* glide format of input texture */ + unsigned short n64fmt,/* N64 format hi:format low:size */ + uint64 r_crc64 /* checksum hi:palette low:texture */ + ); + +boolean ext_ghq_reloadhirestex(); +#endif /* TXFILTER_DLL */ + +#endif /* __EXT_TXFILTER_H__ */ diff --git a/Source/Glide64/FBtoScreen.cpp b/Source/Glide64/FBtoScreen.cpp new file mode 100644 index 000000000..3833b308a --- /dev/null +++ b/Source/Glide64/FBtoScreen.cpp @@ -0,0 +1,663 @@ +/* +* Glide64 - Glide video plugin for Nintendo 64 emulators. +* Copyright (c) 2002 Dave2001 +* Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski +* +* 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 +* 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 +*/ + +//**************************************************************** +// +// Glide64 - Glide Plugin for Nintendo 64 emulators +// Project started on December 29th, 2001 +// +// Authors: +// Dave2001, original author, founded the project in 2001, left it in 2002 +// Gugaman, joined the project in 2002, left it in 2002 +// Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002 +// Hiroshi 'KoolSmoky' Morii, joined the project in 2007 +// +//**************************************************************** +// +// To modify Glide64: +// * Write your name and (optional)email, commented by your work, so I know who did it, and so that you can find which parts you modified when it comes time to send it to me. +// * Do NOT send me the whole project or file that you modified. Take out your modified code sections, and tell me where to put them. If people sent the whole thing, I would have many different versions, but no idea how to combine them all. +// +//**************************************************************** +// +// Draw N64 frame buffer to screen. +// Created by Gonetz, 2007 +// +//**************************************************************** + + +#include "Gfx #1.3.h" +#include "FBtoScreen.h" +#include "TexCache.h" + +static int SetupFBtoScreenCombiner(wxUint32 texture_size, wxUint32 opaque) +{ + int tmu; + if (voodoo.tmem_ptr[GR_TMU0]+texture_size < voodoo.tex_max_addr[0]) + { + tmu = GR_TMU0; + grTexCombine( GR_TMU1, + GR_COMBINE_FUNCTION_NONE, + GR_COMBINE_FACTOR_NONE, + GR_COMBINE_FUNCTION_NONE, + GR_COMBINE_FACTOR_NONE, + FXFALSE, + FXFALSE ); + grTexCombine( GR_TMU0, + GR_COMBINE_FUNCTION_LOCAL, + GR_COMBINE_FACTOR_NONE, + GR_COMBINE_FUNCTION_LOCAL, + GR_COMBINE_FACTOR_NONE, + FXFALSE, + FXFALSE ); + } + else + { + if (voodoo.tmem_ptr[GR_TMU1]+texture_size >= voodoo.tex_max_addr[1]) + ClearCache (); + tmu = GR_TMU1; + grTexCombine( GR_TMU1, + GR_COMBINE_FUNCTION_LOCAL, + GR_COMBINE_FACTOR_NONE, + GR_COMBINE_FUNCTION_LOCAL, + GR_COMBINE_FACTOR_NONE, + FXFALSE, + FXFALSE ); + grTexCombine( GR_TMU0, + GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_ONE, + FXFALSE, + FXFALSE ); + } + int filter = (rdp.filter_mode!=2)?GR_TEXTUREFILTER_POINT_SAMPLED:GR_TEXTUREFILTER_BILINEAR; + grTexFilterMode (tmu, filter, filter); + grTexClampMode (tmu, + GR_TEXTURECLAMP_CLAMP, + GR_TEXTURECLAMP_CLAMP); +// grConstantColorValue (0xFFFFFFFF); + grColorCombine (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_NONE, + GR_COMBINE_OTHER_TEXTURE, +// GR_COMBINE_OTHER_CONSTANT, + FXFALSE); + grAlphaCombine (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_NONE, + GR_COMBINE_OTHER_TEXTURE, + FXFALSE); + if (opaque) + { + grAlphaTestFunction (GR_CMP_ALWAYS); + grAlphaBlendFunction( GR_BLEND_ONE, + GR_BLEND_ZERO, + GR_BLEND_ONE, + GR_BLEND_ZERO); + } + else + { + grAlphaBlendFunction( GR_BLEND_SRC_ALPHA, + GR_BLEND_ONE_MINUS_SRC_ALPHA, + GR_BLEND_ONE, + GR_BLEND_ZERO); + } + grDepthBufferFunction (GR_CMP_ALWAYS); + grCullMode(GR_CULL_DISABLE); + grDepthMask (FXFALSE); + rdp.update |= UPDATE_COMBINE | UPDATE_ZBUF_ENABLED | UPDATE_CULL_MODE; + return tmu; +} + +static void DrawRE2Video(FB_TO_SCREEN_INFO & fb_info, float scale) +{ + float scale_y = (float)fb_info.width/rdp.vi_height; + float height = settings.scr_res_x/scale_y; + float ul_x = 0.5f; + float ul_y = (settings.scr_res_y - height)/2.0f; + float lr_y = settings.scr_res_y - ul_y - 1.0f; + float lr_x = settings.scr_res_x - 1.0f; + float lr_u = (fb_info.width - 1)*scale; + float lr_v = (fb_info.height - 1)*scale; + VERTEX v[4] = { + { ul_x, ul_y, 1, 1, 0.5f, 0.5f, 0.5f, 0.5f, {0.5f, 0.5f, 0.5f, 0.5f} }, + { lr_x, ul_y, 1, 1, lr_u, 0.5f, lr_u, 0.5f, {lr_u, 0.5f, lr_u, 0.5f} }, + { ul_x, lr_y, 1, 1, 0.5f, lr_v, 0.5f, lr_v, {0.5f, lr_v, 0.5f, lr_v} }, + { lr_x, lr_y, 1, 1, lr_u, lr_v, lr_u, lr_v, {lr_u, lr_v, lr_u, lr_v} } + }; + grDrawTriangle (&v[0], &v[2], &v[1]); + grDrawTriangle (&v[2], &v[3], &v[1]); +} + +static void DrawRE2Video256(FB_TO_SCREEN_INFO & fb_info) +{ + FRDP("DrawRE2Video256. ul_x=%d, ul_y=%d, lr_x=%d, lr_y=%d, size=%d, addr=%08lx\n", fb_info.ul_x, fb_info.ul_y, fb_info.lr_x, fb_info.lr_y, fb_info.size, fb_info.addr); + wxUint32 * src = (wxUint32*)(gfx.RDRAM+fb_info.addr); + GrTexInfo t_info; + t_info.smallLodLog2 = GR_LOD_LOG2_256; + t_info.largeLodLog2 = GR_LOD_LOG2_256; + t_info.aspectRatioLog2 = GR_ASPECT_LOG2_1x1; + wxUint16 * tex = (wxUint16*)texture_buffer; + wxUint16 * dst = tex; + wxUint32 col; + wxUint8 r, g, b; + fb_info.height = min(256, fb_info.height); + for (wxUint32 h = 0; h < fb_info.height; h++) + { + for (wxUint32 w = 0; w < 256; w++) + { + col = *(src++); + r = (wxUint8)((col >> 24)&0xFF); + r = (wxUint8)((float)r / 255.0f * 31.0f); + g = (wxUint8)((col >> 16)&0xFF); + g = (wxUint8)((float)g / 255.0f * 63.0f); + b = (wxUint8)((col >> 8)&0xFF); + b = (wxUint8)((float)b / 255.0f * 31.0f); + *(dst++) = (r << 11) | (g << 5) | b; + } + src += (fb_info.width - 256); + } + t_info.format = GR_TEXFMT_RGB_565; + t_info.data = tex; + int tmu = SetupFBtoScreenCombiner(grTexTextureMemRequired(GR_MIPMAPLEVELMASK_BOTH, &t_info), fb_info.opaque); + grTexDownloadMipMap (tmu, + voodoo.tex_min_addr[tmu]+voodoo.tmem_ptr[tmu], + GR_MIPMAPLEVELMASK_BOTH, + &t_info); + grTexSource (tmu, + voodoo.tex_min_addr[tmu]+voodoo.tmem_ptr[tmu], + GR_MIPMAPLEVELMASK_BOTH, + &t_info); + DrawRE2Video(fb_info, 1.0f); +} + +static void DrawFrameBufferToScreen256(FB_TO_SCREEN_INFO & fb_info) +{ + if (settings.hacks&hack_RE2) + { + DrawRE2Video256(fb_info); + return; + } + FRDP("DrawFrameBufferToScreen256. ul_x=%d, ul_y=%d, lr_x=%d, lr_y=%d, size=%d, addr=%08lx\n", fb_info.ul_x, fb_info.ul_y, fb_info.lr_x, fb_info.lr_y, fb_info.size, fb_info.addr); + wxUint32 width = fb_info.lr_x - fb_info.ul_x + 1; + wxUint32 height = fb_info.lr_y - fb_info.ul_y + 1; + GrTexInfo t_info; + wxUint8 * image = gfx.RDRAM+fb_info.addr; + wxUint32 width256 = ((width-1) >> 8) + 1; + wxUint32 height256 = ((height-1) >> 8) + 1; + t_info.smallLodLog2 = t_info.largeLodLog2 = GR_LOD_LOG2_256; + t_info.aspectRatioLog2 = GR_ASPECT_LOG2_1x1; + t_info.format = GR_TEXFMT_ARGB_1555; + wxUint16 * tex = (wxUint16*)texture_buffer; + t_info.data = tex; + wxUint32 tex_size = grTexTextureMemRequired (GR_MIPMAPLEVELMASK_BOTH, &t_info); + int tmu = SetupFBtoScreenCombiner(tex_size*width256*height256, fb_info.opaque); + wxUint16 * src = (wxUint16*)image; + src += fb_info.ul_x + fb_info.ul_y * fb_info.width; + wxUint32 * src32 = (wxUint32*)image; + src32 += fb_info.ul_x + fb_info.ul_y * fb_info.width; + wxUint32 w_tail = width%256; + wxUint32 h_tail = height%256; + wxUint16 c; + wxUint32 c32; + wxUint32 idx; + wxUint32 bound = BMASK+1-fb_info.addr; + bound = fb_info.size == 2 ? bound >> 1 : bound >> 2; + wxUint8 r, g, b, a; + wxUint32 cur_width, cur_height, cur_tail; + wxUint32 tex_adr = voodoo.tex_min_addr[tmu]+voodoo.tmem_ptr[tmu]; + if ((voodoo.tmem_ptr[tmu] < TEXMEM_2MB_EDGE) && (voodoo.tmem_ptr[tmu]+tex_size*width256*height256 > TEXMEM_2MB_EDGE)) + { + tex_adr = TEXMEM_2MB_EDGE; + } + for (wxUint32 h = 0; h < height256; h++) + { + for (wxUint32 w = 0; w < width256; w++) + { + cur_width = (256*(w+1) < width) ? 256 : w_tail; + cur_height = (256*(h+1) < height) ? 256 : h_tail; + cur_tail = 256 - cur_width; + wxUint16 * dst = tex; + if (fb_info.size == 2) + { + for (wxUint32 y=0; y < cur_height; y++) + { + for (wxUint32 x=0; x < cur_width; x++) + { + idx = (x+256*w+(y+256*h)*fb_info.width)^1; + if (idx >= bound) + break; + c = src[idx]; + *(dst++) = (c >> 1) | ((c&1)<<15); + } + dst += cur_tail; + } + } + else + { + for (wxUint32 y=0; y < cur_height; y++) + { + for (wxUint32 x=0; x < cur_width; x++) + { + idx = (x+256*w+(y+256*h)*fb_info.width); + if (idx >= bound) + break; + c32 = src32[idx]; + r = (wxUint8)((c32 >> 24)&0xFF); + r = (wxUint8)((float)r / 255.0f * 31.0f); + g = (wxUint8)((c32 >> 16)&0xFF); + g = (wxUint8)((float)g / 255.0f * 63.0f); + b = (wxUint8)((c32 >> 8)&0xFF); + b = (wxUint8)((float)b / 255.0f * 31.0f); + a = (c32&0xFF) ? 1 : 0; + *(dst++) = (a<<15) | (r << 10) | (g << 5) | b; + } + dst += cur_tail; + } + } + grTexDownloadMipMap (tmu, tex_adr, GR_MIPMAPLEVELMASK_BOTH, &t_info); + grTexSource (tmu, tex_adr, GR_MIPMAPLEVELMASK_BOTH, &t_info); + tex_adr += tex_size; + float ul_x = (float)(fb_info.ul_x + 256*w); + float ul_y = (float)(fb_info.ul_y + 256*h); + float lr_x = (ul_x + (float)(cur_width)) * rdp.scale_x; + float lr_y = (ul_y + (float)(cur_height)) * rdp.scale_y; + ul_x *= rdp.scale_x; + ul_y *= rdp.scale_y; + ul_x += rdp.offset_x; + ul_y += rdp.offset_y; + lr_x += rdp.offset_x; + lr_y += rdp.offset_y; + + float lr_u = (float)(cur_width-1); + float lr_v = (float)(cur_height-1); + // Make the vertices + VERTEX v[4] = { + { ul_x, ul_y, 1, 1, 0.5f, 0.5f, 0.5f, 0.5f, {0.5f, 0.5f, 0.5f, 0.5f} }, + { lr_x, ul_y, 1, 1, lr_u, 0.5f, lr_u, 0.5f, {lr_u, 0.5f, lr_u, 0.5f} }, + { ul_x, lr_y, 1, 1, 0.5f, lr_v, 0.5f, lr_v, {0.5f, lr_v, 0.5f, lr_v} }, + { lr_x, lr_y, 1, 1, lr_u, lr_v, lr_u, lr_v, {lr_u, lr_v, lr_u, lr_v} } + }; + grDrawTriangle (&v[0], &v[2], &v[1]); + grDrawTriangle (&v[2], &v[3], &v[1]); + } + } +} + +bool DrawFrameBufferToScreen(FB_TO_SCREEN_INFO & fb_info) +{ + if (fb_info.width < 200 || fb_info.size < 2) + return false; + wxUint32 width = fb_info.lr_x - fb_info.ul_x + 1; + wxUint32 height = fb_info.lr_y - fb_info.ul_y + 1; + wxUint32 max_size = min(voodoo.max_tex_size, 512); + if (width > (wxUint32)max_size || height > (wxUint32)max_size) + { + DrawFrameBufferToScreen256(fb_info); + return true; + } + FRDP("DrawFrameBufferToScreen. ul_x=%d, ul_y=%d, lr_x=%d, lr_y=%d, size=%d, addr=%08lx\n", fb_info.ul_x, fb_info.ul_y, fb_info.lr_x, fb_info.lr_y, fb_info.size, fb_info.addr); + GrTexInfo t_info; + wxUint8 * image = gfx.RDRAM+fb_info.addr; + wxUint32 texwidth, texheight; + float scale; + if (width <= 256) + { + texwidth = 256; + scale = 1.0f; + t_info.smallLodLog2 = t_info.largeLodLog2 = GR_LOD_LOG2_256; + } + else + { + texwidth = 512; + scale = 0.5f; + t_info.smallLodLog2 = t_info.largeLodLog2 = GR_LOD_LOG2_512; + } + + if (height <= (texwidth>>1)) + { + t_info.aspectRatioLog2 = GR_ASPECT_LOG2_2x1; + texheight = texwidth>>1; + } + else + { + t_info.aspectRatioLog2 = GR_ASPECT_LOG2_1x1; + texheight = texwidth; + } + + if (fb_info.size == 2) + { + wxUint16 * tex = (wxUint16*)texture_buffer; + wxUint16 * dst = tex; + wxUint16 * src = (wxUint16*)image; + src += fb_info.ul_x + fb_info.ul_y * fb_info.width; + wxUint16 c; + wxUint32 idx; + const wxUint32 bound = (BMASK+1-fb_info.addr) >> 1; + bool empty = true; + for (wxUint32 y=0; y < height; y++) + { + for (wxUint32 x=0; x < width; x++) + { + idx = (x+y*fb_info.width)^1; + if (idx >= bound) + break; + c = src[idx]; + if (c) empty = false; + *(dst++) = (c >> 1) | ((c&1)<<15); + } + dst += texwidth-width; + } + if (empty) + return false; + t_info.format = GR_TEXFMT_ARGB_1555; + t_info.data = tex; + } + else + { + wxUint32 * tex = (wxUint32*)texture_buffer; + wxUint32 * dst = tex; + wxUint32 * src = (wxUint32*)image; + src += fb_info.ul_x + fb_info.ul_y * fb_info.width; + wxUint32 col; + wxUint32 idx; + const wxUint32 bound = (BMASK+1-fb_info.addr) >> 2; + for (wxUint32 y=0; y < height; y++) + { + for (wxUint32 x=0; x < width; x++) + { + idx = x+y*fb_info.width; + if (idx >= bound) + break; + col = src[idx]; + *(dst++) = (col >> 8) | 0xFF000000; + } + dst += texwidth-width; + } + t_info.format = GR_TEXFMT_ARGB_8888; + t_info.data = tex; + } + + int tmu = SetupFBtoScreenCombiner(grTexTextureMemRequired(GR_MIPMAPLEVELMASK_BOTH, &t_info), fb_info.opaque); + grTexDownloadMipMap (tmu, + voodoo.tex_min_addr[tmu]+voodoo.tmem_ptr[tmu], + GR_MIPMAPLEVELMASK_BOTH, + &t_info); + grTexSource (tmu, + voodoo.tex_min_addr[tmu]+voodoo.tmem_ptr[tmu], + GR_MIPMAPLEVELMASK_BOTH, + &t_info); + if (settings.hacks&hack_RE2) + { + DrawRE2Video(fb_info, scale); + } + else + { + float ul_x = fb_info.ul_x * rdp.scale_x + rdp.offset_x; + float ul_y = fb_info.ul_y * rdp.scale_y + rdp.offset_y; + float lr_x = fb_info.lr_x * rdp.scale_x + rdp.offset_x; + float lr_y = fb_info.lr_y * rdp.scale_y + rdp.offset_y; + float lr_u = (width-1)*scale; + float lr_v = (height-1)*scale; + // Make the vertices + VERTEX v[4] = { + { ul_x, ul_y, 1, 1, 0.5f, 0.5f, 0.5f, 0.5f, {0.5f, 0.5f, 0.5f, 0.5f} }, + { lr_x, ul_y, 1, 1, lr_u, 0.5f, lr_u, 0.5f, {lr_u, 0.5f, lr_u, 0.5f} }, + { ul_x, lr_y, 1, 1, 0.5f, lr_v, 0.5f, lr_v, {0.5f, lr_v, 0.5f, lr_v} }, + { lr_x, lr_y, 1, 1, lr_u, lr_v, lr_u, lr_v, {lr_u, lr_v, lr_u, lr_v} } + }; + grDrawTriangle (&v[0], &v[2], &v[1]); + grDrawTriangle (&v[2], &v[3], &v[1]); + } + return true; +} + +static void DrawDepthBufferToScreen256(FB_TO_SCREEN_INFO & fb_info) +{ + FRDP("DrawDepthBufferToScreen256. ul_x=%d, ul_y=%d, lr_x=%d, lr_y=%d, size=%d, addr=%08lx\n", fb_info.ul_x, fb_info.ul_y, fb_info.lr_x, fb_info.lr_y, fb_info.size, fb_info.addr); + wxUint32 width = fb_info.lr_x - fb_info.ul_x + 1; + wxUint32 height = fb_info.lr_y - fb_info.ul_y + 1; + GrTexInfo t_info; + wxUint8 * image = gfx.RDRAM+fb_info.addr; + wxUint32 width256 = ((width-1) >> 8) + 1; + wxUint32 height256 = ((height-1) >> 8) + 1; + t_info.smallLodLog2 = t_info.largeLodLog2 = GR_LOD_LOG2_256; + t_info.aspectRatioLog2 = GR_ASPECT_LOG2_1x1; + t_info.format = GR_TEXFMT_ALPHA_INTENSITY_88; + wxUint16 * tex = (wxUint16*)texture_buffer; + t_info.data = tex; + wxUint32 tex_size = grTexTextureMemRequired (GR_MIPMAPLEVELMASK_BOTH, &t_info); + int tmu = SetupFBtoScreenCombiner(tex_size*width256*height256, fb_info.opaque); + grConstantColorValue (rdp.fog_color); + grColorCombine (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_NONE, + GR_COMBINE_OTHER_CONSTANT, + FXFALSE); + wxUint16 * src = (wxUint16*)image; + src += fb_info.ul_x + fb_info.ul_y * fb_info.width; + wxUint32 w_tail = width%256; + wxUint32 h_tail = height%256; + wxUint32 cur_width, cur_height, cur_tail; + wxUint32 tex_adr = voodoo.tex_min_addr[tmu]+voodoo.tmem_ptr[tmu]; + if ((voodoo.tmem_ptr[tmu] < TEXMEM_2MB_EDGE) && (voodoo.tmem_ptr[tmu]+tex_size*width256*height256 > TEXMEM_2MB_EDGE)) + { + tex_adr = TEXMEM_2MB_EDGE; + } + for (wxUint32 h = 0; h < height256; h++) + { + for (wxUint32 w = 0; w < width256; w++) + { + cur_width = (256*(w+1) < width) ? 256 : w_tail; + cur_height = (256*(h+1) < height) ? 256 : h_tail; + cur_tail = 256 - cur_width; + wxUint16 * dst = tex; + for (wxUint32 y=0; y < cur_height; y++) + { + for (wxUint32 x=0; x < cur_width; x++) + { + *(dst++) = rdp.pal_8[src[(x+256*w+(y+256*h)*fb_info.width)^1]>>8]; + } + dst += cur_tail; + } + grTexDownloadMipMap (tmu, tex_adr, GR_MIPMAPLEVELMASK_BOTH, &t_info); + grTexSource (tmu, tex_adr, GR_MIPMAPLEVELMASK_BOTH, &t_info); + tex_adr += tex_size; + float ul_x = (float)(fb_info.ul_x + 256*w); + float ul_y = (float)(fb_info.ul_y + 256*h); + float lr_x = (ul_x + (float)(cur_width)) * rdp.scale_x + rdp.offset_x; + float lr_y = (ul_y + (float)(cur_height)) * rdp.scale_y + rdp.offset_y; + ul_x = ul_x * rdp.scale_x + rdp.offset_x; + ul_y = ul_y * rdp.scale_y + rdp.offset_y; + float lr_u = (float)(cur_width-1); + float lr_v = (float)(cur_height-1); + // Make the vertices + VERTEX v[4] = { + { ul_x, ul_y, 1, 1, 0.5f, 0.5f, 0.5f, 0.5f, {0.5f, 0.5f, 0.5f, 0.5f} }, + { lr_x, ul_y, 1, 1, lr_u, 0.5f, lr_u, 0.5f, {lr_u, 0.5f, lr_u, 0.5f} }, + { ul_x, lr_y, 1, 1, 0.5f, lr_v, 0.5f, lr_v, {0.5f, lr_v, 0.5f, lr_v} }, + { lr_x, lr_y, 1, 1, lr_u, lr_v, lr_u, lr_v, {lr_u, lr_v, lr_u, lr_v} } + }; + grDrawTriangle (&v[0], &v[2], &v[1]); + grDrawTriangle (&v[2], &v[3], &v[1]); + } + } +} + +static void DrawHiresDepthBufferToScreen(FB_TO_SCREEN_INFO & fb_info) +{ + FRDP("DrawHiresDepthBufferToScreen. ul_x=%d, ul_y=%d, lr_x=%d, lr_y=%d, size=%d, addr=%08lx\n", fb_info.ul_x, fb_info.ul_y, fb_info.lr_x, fb_info.lr_y, fb_info.size, fb_info.addr); + GrTexInfo t_info; + float scale = 0.25f; + GrLOD_t LOD = GR_LOD_LOG2_1024; + if (settings.scr_res_x > 1024) + { + scale = 0.125f; + LOD = GR_LOD_LOG2_2048; + } + t_info.format = GR_TEXFMT_ALPHA_INTENSITY_88; + t_info.smallLodLog2 = t_info.largeLodLog2 = LOD; + t_info.aspectRatioLog2 = GR_ASPECT_LOG2_1x1; + grConstantColorValue (rdp.fog_color); + grColorCombine (GR_COMBINE_FUNCTION_LOCAL, + GR_COMBINE_FACTOR_NONE, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_NONE, + FXFALSE); + grAlphaCombine (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_NONE, + GR_COMBINE_OTHER_TEXTURE, + FXFALSE); + grAlphaBlendFunction( GR_BLEND_SRC_ALPHA, + GR_BLEND_ONE_MINUS_SRC_ALPHA, + GR_BLEND_ONE, + GR_BLEND_ZERO); + grDepthBufferFunction (GR_CMP_ALWAYS); + grDepthMask (FXFALSE); + grCullMode (GR_CULL_DISABLE); + grTexCombine( GR_TMU1, + GR_COMBINE_FUNCTION_NONE, + GR_COMBINE_FACTOR_NONE, + GR_COMBINE_FUNCTION_NONE, + GR_COMBINE_FACTOR_NONE, + FXFALSE, + FXFALSE ); + grTexCombine( GR_TMU0, + GR_COMBINE_FUNCTION_LOCAL, + GR_COMBINE_FACTOR_NONE, + GR_COMBINE_FUNCTION_LOCAL, + GR_COMBINE_FACTOR_NONE, + FXFALSE, + FXFALSE); +// grAuxBufferExt( GR_BUFFER_AUXBUFFER ); + grTexSource( rdp.texbufs[0].tmu, rdp.texbufs[0].begin, GR_MIPMAPLEVELMASK_BOTH, &(t_info) ); + float ul_x = (float)rdp.scissor.ul_x; + float ul_y = (float)rdp.scissor.ul_y; + float lr_x = (float)rdp.scissor.lr_x; + float lr_y = (float)rdp.scissor.lr_y; + float ul_u = (float)rdp.scissor.ul_x * scale; + float ul_v = (float)rdp.scissor.ul_y * scale; + float lr_u = (float)rdp.scissor.lr_x * scale; + float lr_v = (float)rdp.scissor.lr_y * scale; + // Make the vertices + VERTEX v[4] = { + { ul_x, ul_y, 1, 1, ul_u, ul_v, ul_u, ul_v, {ul_u, ul_v, ul_u, ul_v} }, + { lr_x, ul_y, 1, 1, lr_u, ul_v, lr_u, ul_v, {lr_u, ul_v, lr_u, ul_v} }, + { ul_x, lr_y, 1, 1, ul_u, lr_v, ul_u, lr_v, {ul_u, lr_v, ul_u, lr_v} }, + { lr_x, lr_y, 1, 1, lr_u, lr_v, lr_u, lr_v, {lr_u, lr_v, lr_u, lr_v} } + }; + grDrawTriangle (&v[0], &v[2], &v[1]); + grDrawTriangle (&v[2], &v[3], &v[1]); +// grAuxBufferExt( GR_BUFFER_TEXTUREAUXBUFFER_EXT ); + rdp.update |= UPDATE_COMBINE | UPDATE_ZBUF_ENABLED | UPDATE_CULL_MODE; +} + +void DrawDepthBufferToScreen(FB_TO_SCREEN_INFO & fb_info) +{ + wxUint32 width = fb_info.lr_x - fb_info.ul_x + 1; + wxUint32 height = fb_info.lr_y - fb_info.ul_y + 1; + if (width > (wxUint32)voodoo.max_tex_size || height > (wxUint32)voodoo.max_tex_size || width > 512) + { + DrawDepthBufferToScreen256(fb_info); + return; + } + if (fb_hwfbe_enabled && !evoodoo) + { + DrawHiresDepthBufferToScreen(fb_info); + return; + } + FRDP("DrawDepthBufferToScreen. ul_x=%d, ul_y=%d, lr_x=%d, lr_y=%d, size=%d, addr=%08lx\n", fb_info.ul_x, fb_info.ul_y, fb_info.lr_x, fb_info.lr_y, fb_info.size, fb_info.addr); + GrTexInfo t_info; + wxUint8 * image = gfx.RDRAM+fb_info.addr; + wxUint32 texwidth, texheight; + float scale; + if (width <= 256) + { + texwidth = 256; + scale = 1.0f; + t_info.smallLodLog2 = t_info.largeLodLog2 = GR_LOD_LOG2_256; + } + else + { + texwidth = 512; + scale = 0.5f; + t_info.smallLodLog2 = t_info.largeLodLog2 = GR_LOD_LOG2_512; + } + + if (height <= (texwidth>>1)) + { + t_info.aspectRatioLog2 = GR_ASPECT_LOG2_2x1; + texheight = texwidth>>1; + } + else + { + t_info.aspectRatioLog2 = GR_ASPECT_LOG2_1x1; + texheight = texwidth; + } + + wxUint16 * tex = (wxUint16*)texture_buffer; + wxUint16 * dst = tex; + wxUint16 * src = (wxUint16*)image; + src += fb_info.ul_x + fb_info.ul_y * fb_info.width; + for (wxUint32 y=0; y < height; y++) + { + for (wxUint32 x=0; x < width; x++) + { + *(dst++) = rdp.pal_8[src[(x+y*fb_info.width)^1]>>8]; + } + dst += texwidth-width; + } + t_info.format = GR_TEXFMT_ALPHA_INTENSITY_88; + t_info.data = tex; + + int tmu = SetupFBtoScreenCombiner(grTexTextureMemRequired(GR_MIPMAPLEVELMASK_BOTH, &t_info), fb_info.opaque); + grConstantColorValue (rdp.fog_color); + grColorCombine (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_NONE, + GR_COMBINE_OTHER_CONSTANT, + FXFALSE); + grTexDownloadMipMap (tmu, + voodoo.tex_min_addr[tmu]+voodoo.tmem_ptr[tmu], + GR_MIPMAPLEVELMASK_BOTH, + &t_info); + grTexSource (tmu, + voodoo.tex_min_addr[tmu]+voodoo.tmem_ptr[tmu], + GR_MIPMAPLEVELMASK_BOTH, + &t_info); + float ul_x = fb_info.ul_x * rdp.scale_x + rdp.offset_x; + float ul_y = fb_info.ul_y * rdp.scale_y + rdp.offset_y; + float lr_x = fb_info.lr_x * rdp.scale_x + rdp.offset_x; + float lr_y = fb_info.lr_y * rdp.scale_y + rdp.offset_y; + float lr_u = (width-1)*scale; + float lr_v = (height-1)*scale; + float zero = scale*0.5f; + // Make the vertices + VERTEX v[4] = { + { ul_x, ul_y, 1, 1, zero, zero, zero, zero, {zero, zero, zero, zero} }, + { lr_x, ul_y, 1, 1, lr_u, zero, lr_u, zero, {lr_u, zero, lr_u, zero} }, + { ul_x, lr_y, 1, 1, zero, lr_v, zero, lr_v, {zero, lr_v, zero, lr_v} }, + { lr_x, lr_y, 1, 1, lr_u, lr_v, lr_u, lr_v, {lr_u, lr_v, lr_u, lr_v} } + }; + grDrawTriangle (&v[0], &v[2], &v[1]); + grDrawTriangle (&v[2], &v[3], &v[1]); +} diff --git a/Source/Glide64/FBtoScreen.h b/Source/Glide64/FBtoScreen.h new file mode 100644 index 000000000..b5846e5c9 --- /dev/null +++ b/Source/Glide64/FBtoScreen.h @@ -0,0 +1,63 @@ +/* +* Glide64 - Glide video plugin for Nintendo 64 emulators. +* Copyright (c) 2002 Dave2001 +* Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski +* +* 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 +* 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 +*/ + +//**************************************************************** +// +// Glide64 - Glide Plugin for Nintendo 64 emulators +// Project started on December 29th, 2001 +// +// Authors: +// Dave2001, original author, founded the project in 2001, left it in 2002 +// Gugaman, joined the project in 2002, left it in 2002 +// Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002 +// Hiroshi 'KoolSmoky' Morii, joined the project in 2007 +// +//**************************************************************** +// +// To modify Glide64: +// * Write your name and (optional)email, commented by your work, so I know who did it, and so that you can find which parts you modified when it comes time to send it to me. +// * Do NOT send me the whole project or file that you modified. Take out your modified code sections, and tell me where to put them. If people sent the whole thing, I would have many different versions, but no idea how to combine them all. +// +//**************************************************************** +// +// Render N64 frame buffer to screen +// Created by Gonetz, 2007 +// +//**************************************************************** +#ifndef FBtoSCREEN_H +#define FBtoSCREEN_H + +typedef struct +{ + wxUint32 addr; //color image address + wxUint32 size; + wxUint32 width; + wxUint32 height; + wxUint32 ul_x; + wxUint32 ul_y; + wxUint32 lr_x; + wxUint32 lr_y; + wxUint32 opaque; +} FB_TO_SCREEN_INFO; + +bool DrawFrameBufferToScreen(FB_TO_SCREEN_INFO & fb_info); +void DrawDepthBufferToScreen(FB_TO_SCREEN_INFO & fb_info); + +#endif // #ifndef FBtoSCREEN_H diff --git a/Source/Glide64/FixedPoint.asm b/Source/Glide64/FixedPoint.asm new file mode 100644 index 000000000..62bb87408 --- /dev/null +++ b/Source/Glide64/FixedPoint.asm @@ -0,0 +1,81 @@ +;/* +;* Glide64 - Glide video plugin for Nintendo 64 emulators. +;* +;* 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 +;* 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 +;*/ +; +;**************************************************************** +; +; Glide64 - Glide Plugin for Nintendo 64 emulators +; Project started on December 29th, 2001 +; +; Authors: +; Dave2001, original author, founded the project in 2001, left it in 2002 +; Gugaman, joined the project in 2002, left it in 2002 +; Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002 +; Hiroshi 'KoolSmoky' Morii, joined the project in 2007 +; +;**************************************************************** +; +; To modify Glide64: +; * Write your name and (optional)email, commented by your work, so I know who did it, and so that you can find which parts you modified when it comes time to send it to me. +; * Do NOT send me the whole project or file that you modified. Take out your modified code sections, and tell me where to put them. If people sent the whole thing, I would have many different versions, but no idea how to combine them all. +; +;**************************************************************** + +%include "inc/c32.mac" + +segment .text + +; (x * y) >> 16 +proc imul16 +CPU 586 + + %$x arg + %$y arg + mov eax, [ebp + %$x] + mov edx, [ebp + %$y] + imul edx + shrd eax,edx,16 + +endproc ;imul16 + +;(x * y) >> 14 +proc imul14 +CPU 586 + + %$x arg + %$y arg + mov eax, [ebp + %$x] + mov edx, [ebp + %$y] + imul edx + shrd eax,edx,14 + +endproc ;imul14 + +;(x << 16) / y +proc idiv16 +CPU 586 + + %$x arg + %$y arg + mov eax, [ebp + %$x] + mov ebx, [ebp + %$y] + mov edx,eax + sar edx,16 + shl eax,16 + idiv ebx + +endproc ;idiv16 \ No newline at end of file diff --git a/Source/Glide64/Gfx #1.3.h b/Source/Glide64/Gfx #1.3.h new file mode 100644 index 000000000..f178950f7 --- /dev/null +++ b/Source/Glide64/Gfx #1.3.h @@ -0,0 +1,700 @@ +/* +* Glide64 - Glide video plugin for Nintendo 64 emulators. +* Copyright (c) 2002 Dave2001 +* Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski +* +* 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 +* 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 +*/ + +//**************************************************************** +// +// Glide64 - Glide Plugin for Nintendo 64 emulators +// Project started on December 29th, 2001 +// +// Authors: +// Dave2001, original author, founded the project in 2001, left it in 2002 +// Gugaman, joined the project in 2002, left it in 2002 +// Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002 +// Hiroshi 'KoolSmoky' Morii, joined the project in 2007 +// +//**************************************************************** +// +// To modify Glide64: +// * Write your name and (optional)email, commented by your work, so I know who did it, and so that you can find which parts you modified when it comes time to send it to me. +// * Do NOT send me the whole project or file that you modified. Take out your modified code sections, and tell me where to put them. If people sent the whole thing, I would have many different versions, but no idea how to combine them all. +// +//**************************************************************** + +/********************************************************************************** +Common gfx plugin spec, version #1.3 maintained by zilmar (zilmar@emulation64.com) + +All questions or suggestions should go through the mailing list. +http://www.egroups.com/group/Plugin64-Dev +*********************************************************************************** + +Notes: +------ + +Setting the approprate bits in the MI_INTR_REG and calling CheckInterrupts which +are both passed to the DLL in InitiateGFX will generate an Interrupt from with in +the plugin. + +The Setting of the RSP flags and generating an SP interrupt should not be done in +the plugin + +**********************************************************************************/ + +// THIS FILE IS A PRECOMPILED HEADER TO DECREASE BUILD TIME. INCLUDE ALL STANDARD +// .H FILES HERE + +#ifndef _GFX_H_INCLUDED__ +#define _GFX_H_INCLUDED__ + +#include +#include +#include +#include +#include +#include +#include // offsetof +#include +#include "GlideExtensions.h" +#include "rdp.h" +#include "Keys.h" + +#if defined __VISUALC__ +#define GLIDE64_TRY __try +#define GLIDE64_CATCH __except (EXCEPTION_EXECUTE_HANDLER) +#else +#define GLIDE64_TRY try +#define GLIDE64_CATCH catch (...) +#endif + +#ifndef __WINDOWS__ +typedef void* HWND; +#endif + +#ifndef TEXTURE_FILTER +typedef wxInt64 int64; +typedef wxUint64 uint64; +#endif + +#if defined(__cplusplus) +extern "C" { +#endif + +#define _ENDUSER_RELEASE_ + +//******** +// Logging + +// ******************************** +// ** TAKE OUT BEFORE RELEASE!!! ** +//#define LOGGING // log of spec functions called +//#define LOG_KEY // says "Key!!!" in the log when space bar is pressed + +//#define LOG_UCODE + +//#define ALTTAB_FIX + +//#define EXTREME_LOGGING // lots of logging + // note that some of these things are inserted/removed + // from within the code & may not be changed by this define. + +//#define TLUT_LOGGING // log every entry of the TLUT? +// ******************************** + +#define FPS // fps counter able? (not enabled necessarily) + +#define LOGNOTKEY // Log if not pressing: +#define LOGKEY 0x11 // this key (CONTROL) + +#define LOG_COMMANDS // log the whole 64-bit command as (0x........, 0x........) + +#define CATCH_EXCEPTIONS // catch exceptions so it doesn't freeze and will report + // "The gfx plugin has caused an exception" instead. + +#define FLUSH // flush the file buffer. slower logging, but makes sure + // the command is logged before continuing (in case of + // crash or exception, the log will not be cut short) +#ifndef _ENDUSER_RELEASE_ +#define RDP_LOGGING // Allow logging (will not log unless checked, but allows the option) + // Logging functions will not be compiled if this is not present. +//#define RDP_ERROR_LOG +#endif + +#define FPS_FRAMES 10 // Number of frames in which to make an FPS count + +//#define SHOW_FULL_TEXVIEWER // shows the entire contents of the texture in the cache viewer, + // usually used to debug clamping issues. + + +// Usually enabled +#define LARGE_TEXTURE_HANDLING // allow large-textured objects to be split? + +#ifdef ALTTAB_FIX +extern HHOOK hhkLowLevelKybd; +extern LRESULT CALLBACK LowLevelKeyboardProc(int nCode, + WPARAM wParam, LPARAM lParam); +#endif + +// Simulations +//#define SIMULATE_VOODOO1 +//#define SIMULATE_BANSHEE +//******** + +#ifdef EXT_LOGGING +extern std::ofstream extlog; +#define EXT(x) extlog.open("ext.txt",std::ios::app); extlog << x; extlog.close(); +#else +#define EXT(x) +#endif + +#ifndef _ENDUSER_RELEASE_ +#define UNIMP_LOG // Keep enabled, option in dialog +#define BRIGHT_RED // Keep enabled, option in dialog +#endif + +#define COLORED_DEBUGGER // ;) pretty colors + +#ifdef FPS +extern wxDateTime fps_last; +extern wxDateTime fps_next; +extern float fps; +extern wxUint32 fps_count; +#endif + +// rdram mask at 0x400000 bytes (bah, not right for majora's mask) +//#define BMASK 0x7FFFFF +extern unsigned int BMASK; +#define WMASK 0x3FFFFF +#define DMASK 0x1FFFFF + +extern wxUint32 update_screen_count; +extern wxUint32 resolutions[0x18][2]; + +int CheckKeyPressed(int key, int mask); + +//#define PERFORMANCE +#ifdef PERFORMANCE +extern int64 perf_cur; +extern int64 perf_next; +#endif + +#ifdef LOGGING +extern std::ofstream loga; +#define LOG(x) loga.open("glide64_log.txt",std::ios::app); loga << x; loga.flush(); loga.close(); +#else +#define LOG(x) +#endif + + +#ifdef RDP_LOGGING +extern int log_open; +extern std::ofstream rdp_log; +#define OPEN_RDP_LOG() EXT("OPEN_RDP_LOG ()\n"); if (settings.logging && !log_open) { rdp_log.open ("rdp.txt"); log_open=TRUE; } +#define CLOSE_RDP_LOG() EXT("CLOSE_RDP_LOG ()\n"); if (settings.logging && log_open) { rdp_log.close (); log_open=FALSE; } + +#ifdef LOGNOTKEY +#define LRDP(x) EXT("RDP (...)\n"); if (settings.logging && log_open) { if (!CheckKeyPressed(LOGKEY,0x8000)) { rdp_log << x; rdp_log.flush(); } } +#else +#define LRDP(x) EXT("RDP (...)\n"); if (settings.logging && log_open) { rdp_log << x; rdp_log.flush(); } +#endif + +#else +#define OPEN_RDP_LOG() +#define CLOSE_RDP_LOG() +#define LRDP(x) +#endif + + +#ifdef RDP_ERROR_LOG +extern int elog_open; +extern std::ofstream rdp_err; +#define OPEN_RDP_E_LOG() EXT("OPEN_RDP_E_LOG ()\n"); if (settings.elogging && !elog_open) { rdp_err.open ("rdp_e.txt"); elog_open=TRUE; } +#define CLOSE_RDP_E_LOG() EXT("CLOSE_RDP_LOG ()\n"); if (settings.elogging && elog_open) { rdp_err.close (); elog_open=FALSE; } +#define RDP_E(x) if (settings.elogging) { FRDP_E (x); } +#else +#define OPEN_RDP_E_LOG() +#define CLOSE_RDP_E_LOG() +#define RDP_E(x) +#endif + +__inline void FRDP (const char *fmt, ...) +{ +#ifdef RDP_LOGGING + if (!settings.logging || !log_open) return; + +#ifdef LOGNOTKEY + if (CheckKeyPressed(LOGKEY,0x8000)) return; +#endif + + va_list ap; + va_start(ap, fmt); + vsprintf(out_buf, fmt, ap); + LRDP (out_buf); + va_end(ap); +#endif +} +__inline void FRDP_E (const char *fmt, ...) +{ +#ifdef RDP_ERROR_LOG + if (!settings.elogging || !elog_open) return; + +#ifdef LOGNOTKEY + if (CheckKeyPressed(LOGKEY,0x8000)) return; +#endif + + sprintf (out_buf, "%08lx: (%08lx, %08lx) ", rdp.pc[rdp.pc_i]-8, rdp.cmd0, rdp.cmd1); + rdp_err << out_buf; + + va_list ap2; + va_start(ap2, fmt); + vsprintf(out_buf, fmt, ap2); + rdp_err << out_buf; + rdp_err.flush(); + va_end(ap2); +#endif +} + +extern int fullscreen; +extern int romopen; +extern int to_fullscreen; +extern int debugging; + +extern int evoodoo; +extern int ev_fullscreen; + +extern int exception; +extern wxMutex *mutexProcessDList; + +int InitGfx (); +void ReleaseGfx (); + +// The highest 8 bits are the segment # (1-16), and the lower 24 bits are the offset to +// add to it. +__inline wxUint32 segoffset (wxUint32 so) +{ + return (rdp.segment[(so>>24)&0x0f] + (so&BMASK))&BMASK; +} + +/* Plugin types */ +#define PLUGIN_TYPE_GFX 2 + +#ifdef __WINDOWS__ +#define EXPORT __declspec(dllexport) +#define CALL _cdecl +#else +#define EXPORT extern +#define CALL +#endif + +/***** Structures *****/ +typedef struct { + wxUint16 Version; /* Set to 0x0103 */ + wxUint16 Type; /* Set to PLUGIN_TYPE_GFX */ + char Name[100]; /* Name of the DLL */ + + /* If DLL supports memory these memory options then set them to TRUE or FALSE + if it does not support it */ + int NormalMemory; /* a normal wxUint8 array */ + int MemoryBswaped; /* a normal wxUint8 array where the memory has been pre + bswap on a dword (32 bits) boundry */ +} PLUGIN_INFO; + +typedef struct { + HWND hWnd; /* Render window */ + HWND hStatusBar; /* if render window does not have a status bar then this is NULL */ + + int MemoryBswaped; // If this is set to TRUE, then the memory has been pre + // bswap on a dword (32 bits) boundry + // eg. the first 8 bytes are stored like this: + // 4 3 2 1 8 7 6 5 + + wxUint8 * HEADER; // This is the rom header (first 40h bytes of the rom + // This will be in the same memory format as the rest of the memory. + wxUint8 * RDRAM; + wxUint8 * DMEM; + wxUint8 * IMEM; + + wxUint32 * MI_INTR_REG; + + wxUint32 * DPC_START_REG; + wxUint32 * DPC_END_REG; + wxUint32 * DPC_CURRENT_REG; + wxUint32 * DPC_STATUS_REG; + wxUint32 * DPC_CLOCK_REG; + wxUint32 * DPC_BUFBUSY_REG; + wxUint32 * DPC_PIPEBUSY_REG; + wxUint32 * DPC_TMEM_REG; + + wxUint32 * VI_STATUS_REG; + wxUint32 * VI_ORIGIN_REG; + wxUint32 * VI_WIDTH_REG; + wxUint32 * VI_INTR_REG; + wxUint32 * VI_V_CURRENT_LINE_REG; + wxUint32 * VI_TIMING_REG; + wxUint32 * VI_V_SYNC_REG; + wxUint32 * VI_H_SYNC_REG; + wxUint32 * VI_LEAP_REG; + wxUint32 * VI_H_START_REG; + wxUint32 * VI_V_START_REG; + wxUint32 * VI_V_BURST_REG; + wxUint32 * VI_X_SCALE_REG; + wxUint32 * VI_Y_SCALE_REG; + + void (*CheckInterrupts)( void ); +} GFX_INFO; + +extern GFX_INFO gfx; +extern wxWindow * GFXWindow; +extern bool no_dlist; + +typedef GrContext_t (FX_CALL *GRWINOPENEXT)( FxU32 hWnd, + GrScreenResolution_t resolution, + GrScreenRefresh_t refresh, + GrColorFormat_t format, + GrOriginLocation_t origin, + GrPixelFormat_t pixelformat, + int nColBuffers, + int nAuxBuffers) ; + +typedef void (FX_CALL *GRTEXBUFFEREXT)( GrChipID_t tmu, + FxU32 startAddress, + GrLOD_t lodmin, + GrLOD_t lodmax, + GrAspectRatio_t aspect, + GrTextureFormat_t fmt, + FxU32 evenOdd) ; + +typedef void (FX_CALL *GRAUXBUFFEREXT)( GrBuffer_t buffer ) ; + +typedef void (FX_CALL *GRCOLORCOMBINEEXT) (GrCCUColor_t a, + GrCombineMode_t a_mode, + GrCCUColor_t b, + GrCombineMode_t b_mode, + GrCCUColor_t c, + FxBool c_invert, + GrCCUColor_t d, + FxBool d_invert, + FxU32 shift, + FxBool invert) ; + +typedef void (FX_CALL *GRTEXCOLORCOMBINEEXT) (GrChipID_t tmu, + GrTCCUColor_t a, + GrCombineMode_t a_mode, + GrTCCUColor_t b, + GrCombineMode_t b_mode, + GrTCCUColor_t c, + FxBool c_invert, + GrTCCUColor_t d, + FxBool d_invert, + FxU32 shift, + FxBool invert); + +typedef void (FX_CALL *GRCONSTANTCOLORVALUEEXT) + (GrChipID_t tmu, + GrColor_t value); + +typedef void (FX_CALL *GRSTIPPLE)( FxI32 mode) ; + +typedef void (FX_CALL *GRCONFIGWRAPPEREXT)(FxI32, FxI32, FxBool, FxBool); + +typedef GrScreenResolution_t (FX_CALL *GRWRAPPERFULLSCREENRESOLUTIONEXT)(wxUint32*, wxUint32*); + +typedef char ** (FX_CALL *GRQUERYRESOLUTIONSEXT)(FxI32*); + +typedef int (*GETTEXADDR)(int tmu, int texsize); + +extern GRTEXBUFFEREXT grTextureBufferExt; +extern GRTEXBUFFEREXT grTextureAuxBufferExt; +extern GRAUXBUFFEREXT grAuxBufferExt; +extern GRSTIPPLE grStippleModeExt; +extern GRSTIPPLE grStipplePatternExt; +extern GETTEXADDR GetTexAddr; + +#ifndef GR_STIPPLE_DISABLE +#define GR_STIPPLE_DISABLE 0x0 +#define GR_STIPPLE_PATTERN 0x1 +#define GR_STIPPLE_ROTATE 0x2 +#endif + +void ReadSettings (); +void ReadSpecialSettings (const char * name); +void WriteSettings (bool saveEmulationSettings = false); + +/****************************************************************** + Function: CaptureScreen + Purpose: This function dumps the current frame to a file + input: pointer to the directory to save the file to + output: none +*******************************************************************/ +EXPORT void CALL CaptureScreen ( char * Directory ); + +/****************************************************************** + Function: ChangeWindow + Purpose: to change the window between fullscreen and window + mode. If the window was in fullscreen this should + change the screen to window mode and vice vesa. + input: none + output: none +*******************************************************************/ +EXPORT void CALL ChangeWindow (void); + +/****************************************************************** + Function: CloseDLL + Purpose: This function is called when the emulator is closing + down allowing the dll to de-initialise. + input: none + output: none +*******************************************************************/ +EXPORT void CALL CloseDLL (void); + +/****************************************************************** + Function: DllAbout + Purpose: This function is optional function that is provided + to give further information about the DLL. + input: a handle to the window that calls this function + output: none +*******************************************************************/ +EXPORT void CALL DllAbout ( HWND hParent ); + +/****************************************************************** + Function: DllConfig + Purpose: This function is optional function that is provided + to allow the user to configure the dll + input: a handle to the window that calls this function + output: none +*******************************************************************/ +EXPORT void CALL DllConfig ( HWND hParent ); + +/****************************************************************** + Function: DllTest + Purpose: This function is optional function that is provided + to allow the user to test the dll + input: a handle to the window that calls this function + output: none +*******************************************************************/ +EXPORT void CALL DllTest ( HWND hParent ); + + +EXPORT void CALL ReadScreen(void **dest, int *width, int *height); + +/****************************************************************** + Function: DrawScreen + Purpose: This function is called when the emulator receives a + WM_PAINT message. This allows the gfx to fit in when + it is being used in the desktop. + input: none + output: none +*******************************************************************/ +EXPORT void CALL DrawScreen (void); + +/****************************************************************** + Function: GetDllInfo + Purpose: This function allows the emulator to gather information + about the dll by filling in the PluginInfo structure. + input: a pointer to a PLUGIN_INFO stucture that needs to be + filled by the function. (see def above) + output: none +*******************************************************************/ +EXPORT void CALL GetDllInfo ( PLUGIN_INFO * PluginInfo ); + +/****************************************************************** + Function: InitiateGFX + Purpose: This function is called when the DLL is started to give + information from the emulator that the n64 graphics + uses. This is not called from the emulation thread. + Input: Gfx_Info is passed to this function which is defined + above. + Output: TRUE on success + FALSE on failure to initialise + + ** note on interrupts **: + To generate an interrupt set the appropriate bit in MI_INTR_REG + and then call the function CheckInterrupts to tell the emulator + that there is a waiting interrupt. +*******************************************************************/ +EXPORT int CALL InitiateGFX (GFX_INFO Gfx_Info); + +/****************************************************************** + Function: MoveScreen + Purpose: This function is called in response to the emulator + receiving a WM_MOVE passing the xpos and ypos passed + from that message. + input: xpos - the x-coordinate of the upper-left corner of the + client area of the window. + ypos - y-coordinate of the upper-left corner of the + client area of the window. + output: none +*******************************************************************/ +EXPORT void CALL MoveScreen (int xpos, int ypos); + +/****************************************************************** + Function: ProcessDList + Purpose: This function is called when there is a Dlist to be + processed. (High level GFX list) + input: none + output: none +*******************************************************************/ +EXPORT void CALL ProcessDList(void); + +/****************************************************************** + Function: ProcessRDPList + Purpose: This function is called when there is a Dlist to be + processed. (Low level GFX list) + input: none + output: none +*******************************************************************/ +EXPORT void CALL ProcessRDPList(void); + +/****************************************************************** + Function: RomClosed + Purpose: This function is called when a rom is closed. + input: none + output: none +*******************************************************************/ +EXPORT void CALL RomClosed (void); + +/****************************************************************** + Function: RomOpen + Purpose: This function is called when a rom is open. (from the + emulation thread) + input: none + output: none +*******************************************************************/ +EXPORT void CALL RomOpen (void); + +/****************************************************************** + Function: ShowCFB + Purpose: Useally once Dlists are started being displayed, cfb is + ignored. This function tells the dll to start displaying + them again. + input: none + output: none +*******************************************************************/ +EXPORT void CALL ShowCFB (void); + +/****************************************************************** + Function: UpdateScreen + Purpose: This function is called in response to a vsync of the + screen were the VI bit in MI_INTR_REG has already been + set + input: none + output: none +*******************************************************************/ +EXPORT void CALL UpdateScreen (void); + +/****************************************************************** + Function: ViStatusChanged + Purpose: This function is called to notify the dll that the + ViStatus registers value has been changed. + input: none + output: none +*******************************************************************/ +EXPORT void CALL ViStatusChanged (void); + +/****************************************************************** + Function: ViWidthChanged + Purpose: This function is called to notify the dll that the + ViWidth registers value has been changed. + input: none + output: none +*******************************************************************/ +EXPORT void CALL ViWidthChanged (void); + + +/****************************************************************** + Function: FrameBufferWrite + Purpose: This function is called to notify the dll that the + frame buffer has been modified by CPU at the given address. + input: addr rdram address + val val + size 1 = wxUint8, 2 = wxUint16, 4 = wxUint32 + output: none +*******************************************************************/ +EXPORT void CALL FBWrite(wxUint32, wxUint32); + +typedef struct +{ + wxUint32 addr; + wxUint32 val; + wxUint32 size; // 1 = wxUint8, 2 = wxUint16, 4=wxUint32 +} FrameBufferModifyEntry; + +/****************************************************************** + Function: FrameBufferWriteList + Purpose: This function is called to notify the dll that the + frame buffer has been modified by CPU at the given address. + input: FrameBufferModifyEntry *plist + size = size of the plist, max = 1024 + output: none +*******************************************************************/ +EXPORT void CALL FBWList(FrameBufferModifyEntry *plist, wxUint32 size); + +/****************************************************************** + Function: FrameBufferRead + Purpose: This function is called to notify the dll that the + frame buffer memory is beening read at the given address. + DLL should copy content from its render buffer to the frame buffer + in N64 RDRAM + DLL is responsible to maintain its own frame buffer memory addr list + DLL should copy 4KB block content back to RDRAM frame buffer. + Emulator should not call this function again if other memory + is read within the same 4KB range + input: addr rdram address + val val + size 1 = wxUint8, 2 = wxUint16, 4 = wxUint32 + output: none +*******************************************************************/ +EXPORT void CALL FBRead(wxUint32 addr); + +/************************************************************************ +Function: FBGetFrameBufferInfo +Purpose: This function is called by the emulator core to retrieve depth +buffer information from the video plugin in order to be able +to notify the video plugin about CPU depth buffer read/write +operations + +size: += 1 byte += 2 word (16 bit) <-- this is N64 default depth buffer format += 4 dword (32 bit) + +when depth buffer information is not available yet, set all values +in the FrameBufferInfo structure to 0 + +input: FrameBufferInfo *pinfo +pinfo is pointed to a FrameBufferInfo structure which to be +filled in by this function +output: Values are return in the FrameBufferInfo structure +************************************************************************/ +EXPORT void CALL FBGetFrameBufferInfo(void *pinfo); + +/****************************************************************** + NOTE: THIS HAS BEEN ADDED FOR MUPEN64PLUS AND IS NOT PART OF THE + ORIGINAL SPEC + Function: SetConfigDir + Purpose: To pass the location where config files should be read/ + written to. + input: path to config directory + output: none +*******************************************************************/ +EXPORT void CALL SetConfigDir(char *configDir); + +#if defined(__cplusplus) +} +#endif +#endif //_GFX_H_INCLUDED__ diff --git a/Source/Glide64/GlideExtensions.h b/Source/Glide64/GlideExtensions.h new file mode 100644 index 000000000..656c86ed7 --- /dev/null +++ b/Source/Glide64/GlideExtensions.h @@ -0,0 +1,45 @@ +#define GR_BUFFER_TEXTUREBUFFER_EXT 0x6 +#define GR_BUFFER_TEXTUREAUXBUFFER_EXT 0x7 + +typedef FxU32 GrPixelFormat_t; +#define GR_PIXFMT_RGB_565 0x03 +#define GR_PIXFMT_ARGB_1555 0x0004 +#define GR_PIXFMT_ARGB_8888 0x0005 + +typedef FxU32 GrCCUColor_t; +typedef FxU32 GrACUColor_t; +typedef FxU32 GrTCCUColor_t; +typedef FxU32 GrTACUColor_t; +#define GR_CMBX_ZERO 0x00 +#define GR_CMBX_TEXTURE_ALPHA 0x01 +#define GR_CMBX_ALOCAL 0x02 +#define GR_CMBX_AOTHER 0x03 +#define GR_CMBX_B 0x04 +#define GR_CMBX_CONSTANT_ALPHA 0x05 +#define GR_CMBX_CONSTANT_COLOR 0x06 +#define GR_CMBX_DETAIL_FACTOR 0x07 +#define GR_CMBX_ITALPHA 0x08 +#define GR_CMBX_ITRGB 0x09 +#define GR_CMBX_LOCAL_TEXTURE_ALPHA 0x0a +#define GR_CMBX_LOCAL_TEXTURE_RGB 0x0b +#define GR_CMBX_LOD_FRAC 0x0c +#define GR_CMBX_OTHER_TEXTURE_ALPHA 0x0d +#define GR_CMBX_OTHER_TEXTURE_RGB 0x0e +#define GR_CMBX_TEXTURE_RGB 0x0f +#define GR_CMBX_TMU_CALPHA 0x10 +#define GR_CMBX_TMU_CCOLOR 0x11 + +typedef FxU32 GrCombineMode_t; +#define GR_FUNC_MODE_ZERO 0x00 +#define GR_FUNC_MODE_X 0x01 +#define GR_FUNC_MODE_ONE_MINUS_X 0x02 +#define GR_FUNC_MODE_NEGATIVE_X 0x03 +#define GR_FUNC_MODE_X_MINUS_HALF 0x04 + +#define GR_TEXFMT_ARGB_8888 0x12 + +#define GR_LOD_LOG2_2048 0xb +#define GR_LOD_LOG2_1024 0xa +#define GR_LOD_LOG2_512 0x9 + +#define GR_TEXTURE_UMA_EXT 0x06 diff --git a/Source/Glide64/Help/Glide64 Help.chm b/Source/Glide64/Help/Glide64 Help.chm new file mode 100644 index 0000000000000000000000000000000000000000..808323c507f5283946f3765335bd348c94e8edc6 GIT binary patch literal 119621 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

(ov3-ea4yj)YlhcTKiq6io9qF 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 XM~~5?^yoc$j~=5(=+S!gemwvP@qY6N literal 0 HcmV?d00001 diff --git a/Source/Glide64/Help/Glide64 Known Issues.html b/Source/Glide64/Help/Glide64 Known Issues.html new file mode 100644 index 000000000..fc02ecc8d --- /dev/null +++ b/Source/Glide64/Help/Glide64 Known Issues.html @@ -0,0 +1,1399 @@ + + + + + + + + + + + +Glide64 Known Issues + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current + Version: 9.07 (year: 2009, + month: 07)
Known + issues
GameDescriptionCorrect with 
 following plugin:
64 de + Hakken!! Tamagotchi Minna de Tamagotchi WorldMissing or wrong textures + everywhereZiggy LLE
All-Star + Baseball '99Missing gfx in menuRice, Jabo
Bio + FreaksMissing transition effects + during introNone
Blast + Corpsmissing 2d + gfx in menu and game; missing noise effects Jabo software
Command + & ConquerBriefing menu error. Intro + texture errors.(Intro only )Ziggy LLE
Derby + Stallion 64textures problem during demoRice
Donkey + kong 64Wide screen doesn t work 
Excitebike + 64sky textures sliced in + multiplayerto check
Extreme-GWrong title: the blue square + must not appear (coverage?)NONE
FX-Zero: Wrong or missing (fb ?) effects + in menuJabo Software
Gauntlet + Legends 64Missing status bar, flickering + (fb+core issue ?)NONE
Gex 3, + Deep Cover GeckoBad waterNONE
Gloverstrange blue line in sky + sometimesZiggy LLE
Harvest + Moon 64 (Bokujo Monogatari 2)Problem with shadowsZiggy LLE
Hey + You, PikachuMissing gfxRice
Jet + force geminiCoronas behave slighly + incorrectlyWonder++
Kuiki-Uhabi-SuigoMissing jigsaw (microcode issue + ? )Ziggy LLE
Mahjong + MasterPictures of the character are + wrong. Menu doesn't show the japanese lettersRice/SP8
Major + League Baseball Featuring Ken Griffey JrWrong textures in gameJabo soft/Rice
Mario + TennisGfx errorsto check
Mia + Hamm Soccer/Michael Owens WLS/Telefoot/RTL World League SoccerMissing title; wrong transition + effectNone
Midway's + Greatest Arcade Hits Volume 1gfx errors in lot of mini gamesto check
Mission + Impossiblemissing dithering color alpha + effect in menuNONE
Monster + Truck Madness 64Letters have some very small gfx + issueto check
Nascar + 2000Split screen in multiplayer + doesn't work correctly.Jabo Software
Nushi + Zuri 64 - Shiokaze ni NotteMissing gfx in game (blender ?)Direct64, LLE
Operation + WinBackA gray square sometimes appear + on the screen; missing skyZiggy LLE
OgreBattle + 64the shadows in menu are wrongNONE
Parlor! + Pro 64 Pachinko Jikki Simulation Gamesmall texture issue in gameRice
PGA + European Tourcolors seems wrong / jauge doesn + t workJabo
Pikachu + Genki DechMissing and stretched texturesRice
PilotwingsWrong shadows (coverage?)None
Space + Silicon ValleyMissing on TV dithering color + alpha (noise)NONE
Starfox + 64Missing dithering color alpha + (noise) at logoNONE
Super + Bowling 64In game, the two part of the + screen is mixedRice (hack)
Super + Robot SpiritIn menu, just before beginning a + new game there is a problem in this screen: it's seems that there is only + half of the screen for the flames ( checked on real system)Rice
Super + Speed Race 64Sliced textures in menuRice
Top + Gear Hyper-Bikewrong texture, problem of + framebuffer effectNONE
Top + Gear OverdriveResolution change causes gfx + glitches in menuNONE
Turok 2Flashlight doesn't workZiggy LLE
Twinetitle screen during demo is + wrong; shadow at entrance of 1st level should be displayedJabo
Twisted + Edge Extreme Snowboardingwrong background in gameto check
Vigilante + 8No menus, missing textures and + many gfx errorsJabo software
Vigilante + 8 - 2nd OffenseNo menus, depth problem, missing + textures and many gfx errorsJabo software
Wipeout + 64wrong sky in some particular + places, ok with jaboJabo
Yoshi's + Storycut texturesJabo
 
Framebuffer + issues
NOTE: + HWFBE or fb notification with Mupen is correct solution in terms of speed and + quality. Only when REFB is needed or when the fb effect
is + not emulated that it is considered as an issue.
GameDescription
Akumajou + Dracula Makushiroku: Real Action AdventureREFB needed to get motion blur + in intro and correct gfx in menuJabo
All-Star + Baseball 2000, 2001Monitors requires REFB.NONE
Bakushou + Jinsei 64 - MezaseNeeds REFB to be playable (or + background will be missing) (Mupen doesn t handle fb effect + correctly=disabled)NONE
Beetle + Adventure RacingUnemulated fb effects in menu + (scrolling effect); shadows on cars needs REFBZiggy LLE
Blast + Corpswrong depth with shadows with + HWFBEto check
Bottom + of the 9thneeds REFB for correct intro; + With HWFBE only one of the 2 of the player heads are displayed in gameNONE
Castlevania + - Legacy of DarknessREFB needed to get motion blur + in intro and correct gfx in menuJabo
Dobutsu + no Mori (Animal Forest)The character menu is uncorrect + due to an unhandeld fb effectDirect64
Donkey + Kong 64The zipper screen issue is a + framebuffer effects (needs REFB) (Mupen doesn t support this game)NONE
Extreme-GMissing transfer effects in + after select the carDirect64
iss98/2000/Jikkyou + World Cup France '98/J. League Perfect Striker Missing fb effect when a goal is + scoredGLN64 0.41
The New + tetrisMissing fb effect in menu + (partially working with HWBFE)Direct64
Micromachines + 64Missing shadows for some + elements of the environmentJabo software
Ogre + Battle 64 - Person of Lordly CaliberScreen transition effects + requires REFB.to check
Tonic + Troubletexts for the screen just before + going in game needs REFB (side effect of cpu gfx effect ?)NONE
WWF + WrestleMania 2000 /Virtual Pro Wrestling 2REFB is needed to get motion + blur in introZiggy LLE
Yoshi's + Story Transition "page" level needs REFBto check
 
Pending + investigation
GameDescription
F1 Pole + position 64Wrong use of dithering alpha for + texts ?
 
Non-working + games
GameDescription
Indiana + Jones and the Infernal MachineUnimplemented microcodeJabo/ Ziggy LLE
Last + Legion UUnimplemented microcodeJabo/ Ziggy LLE
Star + Wars - Rogue SquadronUnimplemented microcodeJabo/ Ziggy LLE
Star + Wars Episode I - Battle for NabooUnimplemented microcodeJabo/ Ziggy LLE
Toukon + Road - Brave SpiritsUnimplemented microcodeJabo/ Ziggy LLE
Toukon + Roads - The Next GenerationUnimplemented microcodeJabo/ Ziggy LLE
 
Emu + issues
GameDescription
Ai + Shougi 3Textures are completely + distorted (use 1964!)
Banjo + TooieRandom crashes
Dobutsu + no MoriNES games crash emulation
Hoshi + no Kirby 64Minor gfx errors with the status + bar (use Mupen!)
Kirby + 64 - The Crystal ShardsMinor gfx errors with the status + bar (use Mupen!)
Mario + No PhotopieSpecial card issues
NBA + Courtside 2 - Featuring Kobe Bryant    CPU gfx effect issue >> Missing intro. (TIP: set "Frame Buffer R/W: Yes" + with 1964 : got some gfx but broken)
Yakouchuu + II - Satsujun Kouru: CPU gfx effect issue >> Missing movies
 
Wrapper + issues
GameDescription
Depth + issue when using HWFBE, mostly with fbo:International Track and Field Summer + Games, NFL98 TV screen (?), others 
 
Unknown + issues
GameDescription
Stunt + Racer 64Microcode issue and core issues
World + Driver ChampionshipMicrocode issue and core issues
Credits :) + Current list's maintainer: Olivieryuyu
A BIG thanks to:
Raziel64, MasterPhW, Noxious Ninja, TRS, Straight, Knuckles, Flash, Milen, Jelta, + Federelli, Clements, Doomulation, etc.
They are issues' hunters :D + (so am i, hehe)
And a Very special thanks to:
Dave2001 for starting, Gugaman and Gonetz (^_^ He is tha man! ^_^ Thks a lot pal :) ) for enhancing and + fixing
the + best video plugin and showing the true power of 3DFX and Glide. And to the N64 emulators' authors & + betatesters!
Hacktarux, + Mulord and Ziggy for making the best Glide Wrapper out + there.
+ + + + diff --git a/Source/Glide64/Help/Glide64 Readme.html b/Source/Glide64/Help/Glide64 Readme.html new file mode 100644 index 000000000..1eab205cc --- /dev/null +++ b/Source/Glide64/Help/Glide64 Readme.html @@ -0,0 +1,311 @@ + +

+

Glide64


+

International Emulation Project

+

Version: "Napalm WX"

+

Author: Sergey 'Gonetz' Lipski +(Russia)

+

Disclaimer:

+
Neither I, nor anyone who is working with me, will take ANY +responsibility for your actions or if this program causes harm to anything, +including you and your computer, in any way, physically or +mentally.

+

Table of Contents:

+

+
    +
  1. +
    What is Glide64?
    +
  2. +
    The Very Quick Start
    +
  3. +
    Common Settings
    +
  4. +
    Emulation settings +
  5. +
    About hardware frame buffer emulation
    +
  6. +
    Texture enhancement and + hi-resolution textures
  7. Hotkeys
  8. Specific Game Settings

+

 

1. What is Glide64?

+

Glide64 is a graphics plugin for Nintendo 64 emulators. It can run +natively on 3dfx cards, or via a OpenGL-based wrapper for modern video +cards. The project started on 29 December 2001 by David 'Dave2001' +Forrester (USA). Gugaman (Brazil) and Sergey +'Gonetz' Lipski (that is me) joined him at February 2002. We worked +together until the autumn of 2002. Then, Dave2001 and Gugaman left the project. +Since that time I'm the only developer of the plugin. However, I'm not the only +one, who works on this project. The Glide64 project includes two additional +libraries beside the plugin itself. The first one is the library known as the +'Glitch64' wrapper, previously known as "Hacktarux's glide wrapper", named after +its original author, Hacktarux (France). It then was heavily +modified & improved by Vincent 'ziggy' +Penne (France) and Brad 'mudlord' +Miller (Australia). The second library is a texture enhancement +module named 'GlideHQ', created by Hiroshi 'KoolSmoky' Morii +(Japan). Beside that, lots of people from around the world helped me to test the +plugin and gave me valuable advices on how to improve it. The main tester of +this version is Olivieryuyu (France); and additional +testing, advices and friendly support was provided by Wes 'Legend' +McDaniel (USA).

+

2. The Very Quick Start

+

To install Glide64: +

  1. Open archive and copy everything from the 'Plugin' folder into the + folder where all your N64 plugins are stored (this is usually the + 'Plugin' folder in your emulator's folder, e.g. + Project64\Plugin).
    +
  2. +
    If you don’t have a Voodoo card, make sure you copy the glide3x.dll file from the + 'Wrapper' folder into your emulator's folder.
+

To setup Glide64:

+
    +
  1. +
    Launch your emulator.
    +
  2. +
    Select Glide64 as your graphics plugin.
    +
  3. +
    Select 'Configure graphics plugin'
    +
  4. +
    In Glide64 configuration dialog, on the 'Common + settings' tab, in the "Rendering" section, select your desired windowed + and full screen resolution. 
+

Glide64 is now ready to use. If you're a novice in N64 emulation, +you may skip the rest of this document, start your favorite games and enjoy! If +you are an experienced emu fan, or a curious person, read further for +explanation for other options and various tips and tricks.

+

3. Common Settings

3.1 Rendering

Rendering related settings described here.

3.1.1 Common

'Windowed or 3dfx card resolution' - This option selects the fullscreen resolution for 3dfx cards and windowed resolution for other cards. Note: for 3dfx cards the plugin must be in fullscreen mode to see anything.

'Vertical sync' - This option will enable the vertical sync, which will prevent tearing. Note: this option will ONLY have effect if vsync is set to "Software Controlled".

3.1.2 OpenGL settings

'Anisotropic filtering'  -  This filter sharpens and brings out the details of textures that recede into the distance. When activated, it will use the max anisotropy your video card supports. However, this will override native way of texture filtering and may cause visual artifacts in some games.

'Autodetect VRAM Size' - If checked, plugin will try to autodetect VRAM size. But if this appears wrong, please uncheck and set it to correct value. Currently VRAM autodetection is implemented only for Windows.

'Use Frame buffer objects' - Changes the way frame buffer effects are rendered - with or without usage of the OpenGL Frame Buffer Objects (FBO) extension. The choice depends on game and your video card. FBO off is good for NVIDIA cards, while for ATI cards, it's usually best that FBOs are turned on. Also, some FB effects work only with one of the methods, no matter which card you have. On the whole, with FBO off, compatibility/accuracy is a bit better (which is the case for Resident Evil 2). However, with FBO on with some systems, it can actually be a bit faster in cases.

3.2 On screen display

These settings are located in 'Common settings' tab - in the 'On screen display' section. You may select them with no worries - these settings do not impact the emulation.

Select any or all options in the 'Speed' option group to see how fast the game is running. 'FPS counter' will show you the actual frames per second (FPS) for the current game. This number depends on the running game. The 'VI/s counter' will show you the number of visual interrupts per second received by the plugin. This number must be 50 for PAL games and 60 for NTSC games.  '% speed' will show you, how fast your game is emulated; 100% means that the currently emulated game runs at perfect speed. 'FPS transparent' option makes the background of the counter(s) transparent.

Select 'Clock enabled' in the 'Time' group to see the current  time. Select 'Clock is 24-hour' to see the time in 24-hour format. Time information will be displayed in the lower right corner of the screen.

3.3 Other

All other common settings are grouped in the 'Other' section.

'Show advanced emulation options' - Enable 'Emulation settings' tab. Read more in 'Emulation settings' section.

'Show texture enhancement options' - Enable 'Texture enhancement' tab. Read more in 'Texture enhancement and hi-resolution textures' section.

'Screenshot format' - Format, in which screen shots will be saved. Currently you may choose 'BMP', 'PNG' or 'JPEG'.

'Glide card #' - This option is only for users with multiple 3dfx cards installed in one machine. This selects the glide card number to use. If you only have one glide card installed in your system, set this option to #1. Otherwise, select the number that corresponds to the glide card you want to use.

4. Emulation settings

+

Warning: The plugin already has optimal settings for all +games. Changing these settings is dangerous: it can cause glitches and +instability. Access to emulation settings is disabled by default.

+

To enable 'Emulation settings' tab, check 'Show advanced emulation +options' on the 'Common settings tab' and close the configuration +dialog. Open configuration dialog again and the 'Emulation +settings' tab will now be available.

Important: 'Emulation settings' tab operates in 2 different ways depending on whether or not a game is running.

+
    +
  • +
    When no game is running, you may change "default" emulation + settings. The plugin uses these settings when a game does not + have corresponding custom settings. Again, it is strongly recommended to not touch anything here.
    +
  • +
    When a game IS running, this tab shows emulation settings the + game is using. Any changes will be applied immediately after you close the configuration dialog. You will be asked - save the changes in the ini file or use them in the current session only. If you choose 'Yes', your changes will be saved in the custom section of the ini file and will be used permanently. Otherwise, new setting will be used until the game stops or new save state loaded.
+
4.1 General options
+

'Filtering mode' - you may set 'Force bilinear', +'Automatic' or 'Force point-sampled' mode. You also may easily +switch between filtering modes during game play by pressing the backspace +button.

+

'Buffer swapping modes' - It's hard to explain the +difference between these modes. Just select any available option. If a game suffers from flickering, select another buffer swapping mode and see if that fixes the problem.

'LOD calculation'. +The N64 uses a very special way to implement mip-mapping, which is not available on PC hardware. Glide64 implements a rough approximation of N64 +mip-mapping, which can be enabled by setting 'LOD calculation' option +to 'fast' or 'precise'. The result is not always good +though.

'Aspect ratio' - Most N64 games use 4:3 aspect ratio, but some support widescreen too. You may select appropriate aspect here and set widescreen mode in game settings. In 'Stretch' mode the output will be stretched to the entire screen, other modes may add black boarders if necessary.

+

'Fog' - Sets fog emulation on/off.

+

'Buffer clear on every frame' - Forces the frame buffer to be cleared every frame drawn. Usually frame buffer clear is controlled by the game. However, in some cases it is not well emulated, and some garbage may be left on the screen. In such cases, this option must be set on.

+

+

4.2. Frame buffer emulation
+

N64 games often use auxiliary frame buffers to implement special +game effects like motion blur or for optimization purposes. The console can +allocate as many auxiliary frame buffers as needed and then use them as usual +textures. PC video cards usually use only one buffer per frame, thus emulation +of frame buffer effects is always a hard problem. Glide64 implements lot of +methods of frame buffer emulation, to support as many effects as possible. Most +games will work fine with pre-defined settings, but some effects require +additional options to be set. Known cases are described in the Compatibility List and in the Specific Game Settings. You may set the following +options:

+

'Enable frame buffer emulation' - When this option is on, the plugin will try to detect frame buffer effects usage and emulate them. This option is off by default, but for all games, which use frame buffer effects, it will be automatically turned on.

+

'Hardware frame buffer emulation' - Enables hardware +frame buffer emulation. Usually, this must be set on, except some rare cases, +mentioned in the Compatibility +List. Read next chapter for explanation of hardware +frame buffer emulation.

+

'Motion blur' - Enables motion blur emulation. Motion blur +works slow without hardware frame buffer emulation, so it is made optional. This +option usually must be on, because most of cards support hardware frame buffer +emulation. You may also switch it on/off during game play by pressing ALT-B.

+

'Read every frame' - In some cases,  Glide64 cannot +detect frame buffer usage by the game. In this case the only way to emulate +frame buffer effects, is to read every rendered frame from video memory and put +it into the emulated RDRAM. Reading from video memory is usually slow, so this +method of frame buffer emulation is optional. You may also switch it on/off +during game play by pressing ALT-V.

+

'Get frame buffer info' - This is another way to emulate +frame buffer effects, which the plugin cannot detect. This option allows the +plugin to get notification about frame buffer usage from the emulator and thus +emulate frame buffer effects without slowdown. Currently it works only with +Mupen64 (and even Mupen is not 100% reliable with this). Do not enable this option with 1964, otherwise the emulator will +crash.

+

'Render N64 frame buffer as texture'. The N64 +architecture allows the CPU to write directly into the frame buffer. Sometimes +N64 games uses this ability, which may lead to graphics lost during emulation, +since graphics plugin does not know, that some graphics are already written in +the N64 frame buffer by the CPU. Some examples of this are: falling pills in +Dr.Mario and rain in Jet Force Gemini. When this option is enabled, content of +each N64 frame buffer is rendered as a texture over the current rendered frame. +This prevents graphics loss, but may cause slowdowns and various glitches in +some games.

+

'Detect CPU write to N64 frame buffer'- This option works +as the previous options, but the plugin is trying to detect, when a game uses +CPU writes to the N64 frame buffer. The N64 frame buffer is rendered only when +CPU writes is detected. Use this option for those games, in which you see still +image or no image at all for some time with no reason.

+

+

4.3. Depth buffer emulation
+

Sometimes N64 games use values in the depth buffer to decide, when +to render some particular object or not. This is often used for coronas, which +must be rendered only if they are not covered by other objects in the 3D scene. +To emulate it properly, the N64 depth buffer must be filled with correct values. +Glide64 uses software rendering to fill the N64 depth buffer. It is enabled by +default. If you experience performance issues, set the 'Software depth +buffer rendering' option off.

+

5. About hardware frame buffer emulation

+

The usual method of frame buffer emulation, which theoretically +should always work, is to render auxiliary frame buffers into the main video +buffer and then read it from video memory into main memory, and put into the +structure representing N64 memory (RDRAM). This approach has 2 main +disadvantages:

+

1) auxiliary frame buffers may be visible when they should +n't be.

+

2) reading from video memory is a very slow operation, thus many +frame buffer effects will be slow.

+

Also, image taken from video memory must be scaled down to N64 +native resolution (usually 320x240), thus quality lost is inevitable. To avoid +these problems, Glide64 uses the Glide3x extension, which allows it to create +auxiliary frame buffers right into video memory, like the N64 does. This allows +the plugin to run frame buffer effects without speed hits or quality loss. +Hardware frame buffer emulation (HWFBE) greatly improves many games, but it has +some restrictions:

+

1) HWFBE is in fact a hack - auxiliary frame buffers are not put +into N64 memory. When a game uses a texture located in RDRAM corresponding to an +auxiliary frame buffer, the plugin uses the texture located in video memory +instead. The game may use this area in RDRAM for different textures later, but +the plugin will use it's auxiliary buffer anyway, which leads to serious +glitches. I have tried to reduce the probability of this situation, but it is +still possible. If you encounter it, switch to windowed mode, and then back to +full screen again.

+

2) The Glide extension used for HWFBE is fully supported by Voodoo +4/5 only. Banshee and Voodoo3 cards also support it, but only for small +auxiliary frame buffers (e.g. shadows). Other Voodoo cards do not support it at +all!

+

3) HWFBE may not work for Voodoo4/5 if the anti-aliasing option is +set to "fastest performance". Use any other option there.

+

4) Anti-aliasing is not applicable to auxiliary frame buffers.

+

5) The wrapper support HWFBE almost fully, but it has its peculiarities. Two ways of hardware frame buffer emulation are implemented in the wrapper - with, and without usage of the OpenGL Frame Buffer Objects (FBO) extension. The method with FBO's works fast on any card, which supports FBO's, but it may cause depth issues, since framebuffer objects use their own depth buffer. The method without FBO's works on almost any card, has no problems with depth buffer usage, but it may work slowly on ATI cards. To switch between these methods set the 'Use frame buffer objects' option on/off. 

+

6. Texture enhancement and hi-resolution +textures

+

Texture enhancement is done via GlideHQ - a real-time texture enhancer library with hi-resolution texture pack support. GlideHQ is an independent DLL, which dynamically loaded by Glide64, when it is needed. GlideHQ itself has no user interface; all its settings are placed on the 'Texture enhancement' tab. This tab is disabled by default. To enable it, check 'Show texture enhancement options' on the 'Common settings' tab and close the configuration dialog. Open configuration dialog again and switch to 'Texture enhancement' tab.

6.1. Texture enhancement

GlideHQ uses variety of methods to enhance the original N64 textures.

'Filter' - Apply a filter to either smooth or sharpen textures. There are 4 different smoothing filters and 2 different sharpening filters. The higher the number, the stronger the effect, i.e. 'Smoothing filter 4' will have a much more noticeable effect than 'Smoothing filter 1'. Be aware that performance may have an impact depending on the game and/or the PC.

'Enhancement' - 7 different filters are selectable here, each one with a distinctive look. Be aware of possible performance impacts.
Important: 'Store' mode - saves textures in cache "as is". It can improve performance in games, which load many textures. Disable 'Ignore backgrounds' option for better result.

'Texture cache' - Enhanced and filtered textures are cached for later use. This helps boost performance if there are subsequent requests for the same texture, which is the case for most games. Normally, 128MB should be more than enough but there is a sweet spot for each game. 32MB will be enough for Super Mario, but Conker's BFD streams a lot of textures so setting 256MB or more will boost performance.

'Compress texture cache' - Memory will be compressed so that more textures can be held in the texture cache. The compression ratio varies with each texture, but 1/5 of the original size would be a modest approximation. They will be decompressed on-the-fly, before being downloaded to the gfx hardware. This option will still help save memory space even when using texture compressions such as FXT1 and S3TC.

'Apply texture compression' - Textures will be compressed using selected texture compression method. The overall compression ratio is about 1/6 for FXT1 and 1/4 for S3TC. In addition to saving space on the texture cache, the space occupied on the GFX hardware's texture RAM, by the enhanced textures, will be greatly reduced. This minimizes texture RAM usage, decreasing the number of texture swaps to the GFX hardware leading to performance gains. However, due to the nature of lossy compression of FXT1 and S3TC, using this option can sometimes lead to quality degradtion of small size textures and color banding of gradient colored textures.

'Ignore backgrounds' - It is used to skip enhancement for wide narrow textures, usually used for backgrounds. This may save texture memory greatly and increase performance.

6.2 Hi-resolution textures

GlideHQ supports hi-resolution texture packs, and texture dumping/editing.

'Format' - Chose which method is to be used for loading Hi-res texture packs. Only Rice's format is available currently. Leave on 'None' if you will not be needing to load hi-res packs.

'Alternative CRC calculation' - This option enables emulation of a palette CRC calculation bug in RiceVideo. If some textures are not loaded, try to set this option on/off. This option is disabled in texture dumping mode.

'Texture dumping/editing mode' - In this mode, you have that ability to dump textures on screen to the appropriate folder. You can also reload textures while the game is running to see how they look instantly - big time saver! Hotkeys: "R" reloads hires textures from texture pack - "D" toggles texture dumps on/off.

'Use alpha channel fully' - When this option is off, 16bit rgba textures will be loaded using RiceVideo style - with 1bit for alpha channel. When it is on, GlideHQ will check, how alpha channel is used by the hires texture, and select most appropriate format for it. This gives texture designers freedom to play with alpha, as they need, regardless of format of original N64 texture. For older and badly designed texture packs it may cause unwanted black borders.

'Compress texture cache'  - When game started, plugin loads all its hi-resolution textures into PC memory. Since hi-resolution textures are usually large, the whole pack can take hundreds megabytes of memory. Cache compression allows to save memory space greatly. Textures will be decompressed on-the-fly, before being downloaded to the gfx hardware. This option will still help save memory space even when using texture compression.

'Apply texture compression' - Textures will be compressed using selected texture compression method. The overall compression ratio is about 1/6 for FXT1 and 1/4 for S3TC. In addition to saving space on the texture cache, the space occupied on the GFX hardware's texture RAM, by the enhanced textures, will be greatly reduced. This minimizes texture RAM usage, decreasing the number of texture swaps to the GFX hardware leading to performance gains. However, due to the nature of lossy compression of FXT1 and S3TC, using this option can sometimes lead to quality degradtion of small size textures and color banding of gradient colored textures.

'Force 16bpp textures' - The color of the textures will be reduced to 16bpp. This is another space saver and performance enhancer. This halves the space used on the texture cache and the GFX hardware's texture RAM. Color reduction is done so that the original quality is preserved as much as possible. Depending on the texture, this usually is hardly noticeable. Sometimes though, it can be: skies are a good example.

'Tile textures' - When on, wide texture will be split on several tiles to fit in one 256-width texture. This tiled texture takes much less video memory space and thus overall performance will increase. However, corresponding polygons must be split too, and this is not polished yet- various issues are possible, including black lines and polygons distortions.

6.3 Common

'Texture compression method' - Select the method for texture compression. 3dfx cards support both FXT1 and S3TC, other cards can use S3TC only.

'Save texture cache to hard disk' - For enhanced textures cache: this will save all previously loaded and enhanced textures to the hard drive. So upon next game launch, all the textures will be instantly loaded, resulting in smoother performance for all your games. For high-resolution textures cache: After creation, loading hi-res texture will take only a few seconds upon game launch, as opposed to the 5 - 60 seconds a pack can take to load without this cache file. The only downside here is upon any changes to the pack, the cache file will need to be manually deleted. Saved cache files go into a folder called "Cache" within the "Plugins" folder.

7. Hotkeys

Glide64 uses the following hotkeys:

"BACKSPACE" - Cycle between texture filtering modes. Currently selected mode will be shown in the status line on the bottom of the screen for a short time.

"Alt"+"V" - Toggles read every frame on/off. Current status of this option will be shown in the status line on the bottom of the screen for a short time.

"Alt"+"B" - Toggles motion blur on/off. Current status of this option will be shown in the status line on the bottom of the screen for a short time.

GlideHQ uses the following hotkeys:

"D" - toggles texture dumps on/off.

"R" - reloads hires textures from the texture pack.

+ 8. Specific Game Settings

+
+ +
Banjo-Kazooie
+

The puzzle effect +is not emulated by default. To see it, either set 'Read every frame' +option on or set 'Get frame buffer info' and run this game with +Mupen64.

+

+
Beetle Adventure +Racing / HSV Adventure Racing
+

+

+

Fog. The fog in this game is +implemented in a very specific way. When rendering of the current +frame is finished, the depth buffer, filled during rendering of this frame, is +used as a texture and blended with the color buffer. As the result, the frame +becomes fogged, and the fog is thicker where depth values are higher. Glide64 +implements two ways to emulate this effect, software and hardware ones. +

+

Software emulation +uses software depth buffer rendering. It works on all cards, but has two +disadvantages:

+

 - Alpha testing is not used during +software depth buffer rendering. As the result, the pixels, which would normally +be rejected by alpha testing, are stored in the depth buffer. This causes +artifacts in the produced fog.

+

- The software +depth buffer has original (that is low) N64 resolution output. When it is used +as a texture, blended with the high-resolution frame buffer, aliasing is +visible.

+

Hardware emulation +produces perfect fog, but currently it works only on 3dfx Voodoo 4/5's. These +cards use the same depth buffer format, as the N64, and they can allocate the +depth buffer right in the texture memory, so it can be easily used as a texture, +as on N64 hardware. In both cases, the +'Software depth buffer rendering' option must be on.


On car reflection. Your car (the car +you drive) should reflect the environment in this game. That is, various +objects, which you roll by, should be reflected on your car. This is implemented +via the usage of frame buffer content. Emulation of this effect implies frame +buffer emulation. Unfortunately, this can't be done in hardware, because the +texture, which is used as a reflection, is not a part of the frame buffer - it +is the result of frame buffer post processing, made on the N64 CPU. Thus, the +only way to emulate this effect is to use the 'Read every frame' +option. If your hardware allows you to use this option without slowdown, you are +lucky.

+

+
Bio Hazard 2 / Resident Evil +2
+

+

This game uses +pre-rendered depth buffers, which are stored in the game's ROM, and are loaded +into the depth buffer memory area each frame before rendering is started. This +is hard to emulate, and especially hard to emulate efficiently. The following +options must be set:

+

'Hardware frame buffer emulation' - on

+

'Software depth buffer rendering' - on

+

'Use Framebuffer Objects' - off

+

To get good sound +in this game, use Mupen64 with Azimer's HLE sound plugin v.056. However, the +game may flicker in some places with Mupen64.  

+
Conker's Bad Fur +Day
+

The game is well +emulated with default settings. However, there are two special effects in this +game, which require special settings: the black-and-white "It's war" cut-scene, +and the Uga-Buga pixilated effect. To see these effects, set the following +options:
'Read every frame' - on
'Render N64 frame buffer as texture' - on
The game is not +playable with these settings, so use them only to see these particular effects. +

Note for ATI users: you must set 'Use Framebuffer Objects' +option on, otherwise the game will work very +slow.

+
Fushigi no Dungeon - Furai no Shiren 2 +(J)
+

To see correct +background in menus, either set 'Read every frame' option on or set 'Get frame buffer info' and run this game with Mupen64.

+
Legend of Zelda, The - +Majora's Mask
+

Lens of  +Truth may not work, if 'Use Framebuffer Objects' option set off +.
Also, when Lens of Truth is used, some +objects outside of the lens can be cut. This is not a bug - depth buffer copy +must be emulated to fully emulate Lens of Truth. It is currently supported +only by 3dfx Voodoo 4/5 cards.

+
Mario Story / Paper Mario
+

To see correct +background in the menu subscreen, either set the 'Read every frame' +option on or set 'Get frame buffer info' and run this game with +Mupen64. 

Perfect Dark
+

Frame buffer +emulation must be disabled in multiplayer mode to avoid flickering. Most of the +special effects used will not work without frame buffer emulation, but it's +not that important for multiplayer.

For settings for other games check the Compatibility List.


+ \ No newline at end of file diff --git a/Source/Glide64/Help/Glide64 compatibility list.html b/Source/Glide64/Help/Glide64 compatibility list.html new file mode 100644 index 000000000..58d24c4c5 --- /dev/null +++ b/Source/Glide64/Help/Glide64 compatibility list.html @@ -0,0 +1,6153 @@ + + + + + + + + + +.::Glide64 compatibility list::. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Compatibility List 
for + Glide64 1.0
 
Game + Name: RSP MicrocodePlayability LevelRelative speedComments
007 - The World is Not EnoughF3DEX2.XX5NormalCompatible
1080 SnowboardingF3DEX1.XX5NormalCompatible. Use "Read every frame" option to see correct TV + monitors (slow)
40 + WinksF3DEX2.XX5NormalCompatible
64 OozumouF3DEX1.XX5NormalCompatible
64 Oozumou 2F3DEX1.XX5NormalCompatible
64 Trump Collection - Alice no Wakuwaku + Trump WorldF3DEX1.XX5NormalCompatible
64 de Hakken!! Tamagotchi Minna de Tamagotchi WorldF3DTEX/A 3SlowMajor gfx errors
AI Shogi 3F3DEX1.XX5FastCompatible. Use 1964
Aerofighter's AssaultRSP SW 2.0X5NormalCompatible
AeroGaugeF3DEX1.XX5FastCompatible
Aidyn Chronicles - The First MageF3DEX2.XX5NormalCompatible
Airboarder 64 F3DEX1.XX5FastCompatible
Akumajou + Dracula Makushiroku - Real Action AdventureF3DEX2.XX5NormalCompatible. Use "Read every frame" option to see correct menu + (slow)
Akumajou Dracula Makushiroku-Legend of + CornellF3DEX2.XX5NormalCompatible. Enable hi-res mode for correct menus
All Star Tennis '99F3DEX1.XX5FastCompatible
All-Star Baseball 99F3DEX1.XX5NormalCompatible. Use "Get frame buffer info" option with Mupen or + use "Read every frame" option to see correct TV monitors (slow). + Minor gfx errors
All-Star Baseball 2000F3DEX2.XX5NormalCompatible. Use Nemu 0.8. Use "Read every frame" option to see + correct TV monitors (slow)
All-Star Baseball 2001F3DEX1.XX5NormalCompatible. Use Nemu 0.8. Use "Read every frame" option to see + correct TV monitors (slow)
Armorines - Project S.W.A.R.M.F3DEX2.XX5NormalCompatible
Army Men - Air CombatF3DEX2.XX5NormalCompatible
Army Men - Sarge's HeroesF3DEX2.XX5NormalCompatible
Army Men - Sarge's Heroes 2F3DEX2.XX5NormalCompatible
Asteroids Hyper 64F3DEX2.XX5FastCompatible
Automobili LamborghiniF3DEX1.XX5NormalCompatible. Minor gfx errors
Baku + BombermanF3DEX1.XX5NormalCompatible. Use "Get frame buffer info" option with Mupen or + use "Read every frame" option to see intro correctly (slow)
Baku + Bomberman 2F3DEX2.XX5NormalCompatible
Bakuretsu Muteki BangaiohF3DEX1.XX5SlowCompatible
Bakushou Jinsei 64 - Mezase! (Game of + Life)RSP SW 2.0X5SlowCompatible. Use "Read every frame" option to have correct gfx + in game
Banjo to + Kazooie no Dai BoukenF3DEX1.XX5NormalCompatible. Use "Read every frame" option (slow) or "Get + frame buffer info" option with Mupen to see puzzle effect   
Banjo to Kazooie no Dai Bouken 2F3DEX2.XX5NormalCompatible
Banjo-KazooieF3DEX1.XX5NormalCompatible. Use "Read every frame" option (slow) or "Get + frame buffer info" option to see puzzle effect with + Mupen   
Banjo-TooieF3DEX2.XX5NormalCompatible
Bass Hunter 64F3DEX2.XX5NormalCompatible
Bass Rush - ECOGEAR PowerWorm + ChampionshipF3DEX2.XX5NormalCompatible
Bass Tsuri No.1 - Shigesato Itoi's Bass + FishingF3DEX2.XX5NormalCompatible
Bassmasters 2000F3DEX2.XX5NormalCompatible
Batman Beyond - Return of the JokerF3DEX2.XX5NormalCompatible
BattleTanxF3DEX1.XX5FastCompatible
BattleTanx - Global AssaultF3DEX2.XX5FastCompatible
Battlezone - Rise of the Black DogsF3DEX2.XX5NormalCompatible
Beetle Adventure RacingF3DEX2.XX5NormalCompatible
Big Mountain 2000F3DEX2.XX5FastCompatible
Bio F.R.E.A.K.S.F3DEX1.XX5NormalCompatible
Bio Hazard 2F3DEX1.XX5NormalCompatible
Blast CorpsRSP SW 2.0X5NormalCompatible. Use PJ64. Minor gfx errors
Blast DozerRSP SW 2.0X5NormalCompatible. Use PJ64. Minor gfx errors
Blues Brothers 2000F3DEX2.XX5NormalCompatible
Body HarvestF3DEX1.XX5NormalCompatible. Use "Read every frame" option (slow) or "Get + frame buffer info" with Mupen to have correct menu
Bokujo Monogatari 2F3DEX2.XX5NormalCompatible
Bomberman 64F3DEX1.XX5NormalCompatible. Use "Get frame buffer info" option with Mupen or + use "Read every frame" option to see intro correctly (slow)
Bomberman64 - The Second AttackF3DEX2.XX5NormalCompatible
Bomberman HeroF3DEX1.XX5FastCompatible. 
Bottom of the 9thF3DEX2.XX5FastCompatible. Use "Read every frame" option (slow) to see + correct intro
Brunswick + Circuit Pro BowlingF3DEX1.XX5FastCompatible
Buck BumbleF3DEX2.XX5NormalCompatible
Bug's Life, AF3DEX1.XX5NormalCompatible
Bust-A-Move '99F3DEX1.XX5FastCompatible
Bust-A-Move 2 - Arcade EditionF3DEX1.XX5FastCompatible
Bust-A-Move 3 DXF3DEX1.XX5FastCompatible
California + SpeedF3DEX2.XX5NormalCompatible
Carmageddon 64F3DEX2.XX5FastCompatible
CastlevaniaF3DEX2.XX5NormalCompatible. Use "Read every frame" option to see correct menu + (slow)
Castlevania - Legacy of DarknessF3DEX2.XX5NormalCompatible. Enable hi-res mode for correct menus
Centre Court TennisF3DEX1.XX5FastCompatible
Chameleon TwistF3DEX1.XX5FastCompatible
Chameleon Twist 2F3DEX2.XX5NormalCompatible
Charlie Blast's TerritoryF3DEX1.XX5FastCompatible
Chopper AttackRSP SW 2.0X5FastCompatible
Choro Q 64F3DEX1.XX5FastCompatible
Choro Q 64 IIF3DEX2.XX5FastCompatible. Use "Read every frame" option (slow) or "Get + frame buffer info" option with Mupen to see correct menu
Chou Kuukan Night Pro Yakyuu KingF3DEX1.XX5NormalCompatible
Chou Kuukan Night Pro Yakyuu King 2F3DEX1.XX5NormalCompatible
Chou Snobow KidsF3DEX2.XX5FastCompatible
City-Tour GP - Zennihon GT SenshukenF3DEX1.XX5NormalCompatible
Clay Fighter - Sculptor's CutF3DEX1.XX5SlowCompatible
Clay Fighter 63 1-3F3DEX1.XX5SlowCompatible
Command & ConquerF3DEX2.XX3FastNot playable
Conker's Bad Fur DayF3DEXGB2.085NormalCompatible. Use "Read every frame" option (slow) to get black + and white effect during “It’s war” cut scene and Buga + pixellisation effect
Cruis'n ExoticaF3DEX2.XX5FastCompatible
Cruis'n USARSP SW 2.0X5FastCompatible
Cruis'n WorldF3DEX2.XX5FastCompatible
Custom RoboF3DEX2.XX5NormalCompatible
Custom Robo V2F3DEX2.XX5NormalCompatible
CyberTiger F3DEX2.XX5NormalCompatible
Dance Dance Revolution - Disney Dancing + MuseumF3DEX2.XX5NormalCompatible
Dark RiftTURBO3D5NormalCompatible
Deadly ArtsF3DEX1.XX5SlowCompatible
Défi au Tetris MagiqueS2DEX.XX5NormalCompatible
Densha de GO! 64F3DEX2.XX5NormalCompatible. Use 1964
Derby + StallionF3DEX2.XX5NormalCompatible. Use Nemu 0.8
Destruction Derby 64F3DEX1.XX5SlowCompatible
Dezaemon 3DF3DEX1.XX5FastCompatible
Diddy Kong RacingRSP SW DKR5FastCompatible
Disney's Donald Duck - Goin' QuackersF3DEX1.XX5NormalCompatible. Use "Read every frame" option to see correct + transition effects in menu
Disney's TarzanF3DEX2.XX5NormalCompatible. Use PJ64
Donald Duck - Quack AttackF3DEX1.XX5NormalCompatible. Use "Read every frame" option to see correct + transition effect in menu
Donkey Kong 64F3DEX2.XX5NormalCompatible. Use PJ64
Doom 64F3DEX1.XX5FastCompatible
Doraemon - Mittsu no SeireisekiF3DEX2.XX5FastCompatible
Doraemon 2 - Hikari no ShindenF3DEX1.XX5FastCompatible
Doraemon 3 - Nobi Dai no Machi SOS!F3DEX1.XX5FastCompatible. Use 1964 
Doubutsu no MoriF3DEX2.XX5NormalCompatible
Dr. Mario 64F3DEX2.XX5NormalCompatible
Dual HeroesF3DEX1.XX5NormalCompatible
Duck Dodgers Starring Daffy DuckF3DEX2.XX5SlowCompatible
Duke Nukem - ZER0 H0URF3DEX2.XX5FastCompatible
Duke Nukem 64RSPSW 2.0X5NormalCompatible. Minor gfx errors
ECW Hardcore RevolutionF3DEX2.XX5FastCompatible
Earthworm Jim 3DF3DEX1.XX5NormalCompatible
Eikou no Saint AndrewRSP SW 2.0X2NormalCompatible, Use "Read every frame" option (slow) or "Get + frame buffer info" with Mupen to have correct background in game
Elmo's Letter AdventureF3DEX1.XX5NormalCompatible
Elmo's Number JourneyF3DEX1.XX5NormalCompatible
Eltale MonstersF3DEX1.XX5FastCompatible
Excitebike 64F3DEX2.XX5NormalCompatible
Extreme-GF3DEX1.XX5NormalCompatible. Minor gfx errors 
Extreme-G XG2F3DEX2.XX5NormalCompatible
F-1 Pole Position 64F3DEX1.XX5FastCompatible. Use "Read every frame" option (slow) or "Get + frame buffer info" with Mupen to have correct menu
F-1 World Grand PrixF3DEX1.XX5NormalCompatible
F-1 World Grand Prix IIF3DEX2.XX5NormalCompatible
F-Zero XF3DEX2.XX5NormalCompatible
F1 Racing ChampionshipF3DEX2.XX5NormalCompatible. Use Mupen
FIFA - Road to World Cup 98RSP SW 2.0X5SlowCompatible
FIFA 99F3DEX1.XX5NormalCompatible
FIFA Soccer 64RSP SW 2.0X5NormalCompatible. Use 1964
Famista 64F3DEX2.XX5NormalCompatible. Use "Read every frame" option (slow) or "Get + frame buffer info" with Mupen to have ground in game
Fighter Destiny 2F3DEX2.XX5FastCompatible
Fighter's DestinyF3DEX1.XX5FastCompatible
Fighting CupF3DEX1.XX5FastCompatible
Fighting Force 64F3DEX1.XX5NormalCompatible
Fire Electric PenF3DEX1.XX5NormalCompatible
Flying DragonF3DEX1.XX5NormalCompatible. Minor gfx errors
Forsaken 64F3DEX1.XX5FastCompatible
Frogger + 2 (Alpha)F3DEX2.XX5FastCompatible
FoxSportsCollege Hoops ‘99F3DEX2.XX5NormalCompatible
Fushigi no Dungeon - Fuurai no Shiren 2F3DEX2.XX5NormalCompatible. + Use "Read every frame" option (slow) or "Get frame buffer + info" with Mupen to have backgrounds in menus 
G.A.S.P! Fighter's NEXTreamF3DEX2.XX5NormalCompatible. Use (J) version or use Mupen
GT 64 - Championship EditionF3DEX1.XX5NormalCompatible
Ganbare Goemon - Derudero Douchuu Obake TenkomoriF3DEX2.XX5FastCompatible
Ganbare Goemon - Mononoke SugorokuF3DEX2.XX5NormalCompatible
Ganbare Goemon - Neo Momoyama Bakufu no + OdoriF3DEX1.XX5NormalCompatible
Ganbare Nippon Olympics 2000F3DEX2.XX5FastCompatible
Gauntlet LegendsF3DEX2.XX2NormalMissing gfx. Flickerings. Use PJ64
Getter Love !! Cho Renai Party GameF3DEX2.XX5FastCompatible
Gex 3 - Deep Cover GeckoF3DEX2.XX5FastCompatible
Gex 64 - Enter the GeckoF3DEX1.XX5FastCompatible
GloverF3DEX1.XX5NormalCompatible (For (E) version use Mupen)
Goemon's Great AdventureF3DEX2.XX5FastCompatible
Golden Nugget 64RSP SW 2.0X5FastCompatible. Use 1964 or Mupen
GoldenEye 007RSP SW 2.0G5SlowCompatible
HVS Adventure RacingF3DEX2.XX5NormalCompatible. Use PJ64 Audio Fix Edition
Hamster Monogatari 64S2DEX.XX5NormalCompatible
Hanafuda 64 - Tenshi no YakusokuF3DEX2.XX5NormalCompatible. Use 1964
Harukanaru Augusta Masters 98F3DEX1.XX5NormalCompatible
Harvest Moon 64F3DEX2.XX5FastCompatible
Heiwa Pachinko World 64F3DEX2.XX3NormalGfx errors
Hercules - The Legendary JourneysF3DEX2.XX5NormalCompatible. Minor gfx errors
HexenF3DEX1.XX5NormalCompatible. Use "Read every frame" option (slow) to see texts + at objectives screen
Hey You, Pikachu!F3DEX2.XX3NormalGfx errors (needs voice pak)
Hiryuu no Ken TwinF3DEX1.XX5NormalCompatible. Minor gfx errors
Holy Magic CenturyF3DEX1.XX5FastCompatible
Hoshi no Kirby 64F3DEX2.XX5NormalCompatible. Use Mupen for correct status bar
Hot Wheels Turbo RacingF3DEX2.XX5SlowCompatible
Human Grand Prix - New GenerationF3DEX1.XX5NormalCompatible. Use "Read every frame" option (slow) or "Get + frame buffer info" with Mupen to have correct menu
Hybrid HeavenF3DEX2.XX5NormalCompatible
Hydro ThunderF3DEX2.XX5NormalCompatible. Use PJ64
Ide Yosuke no Mahjong JukuF3DEX1.XX5Normal Compatible. Use Nemu 0.8 (disable audio HLE)
Iggy's Reckin' BallsF3DEX1.XX5NormalCompatible
Iggy-kun no Bura Bura PoyonF3DEX1.XX5NormalCompatible
In-Fisherman Bass Hunter 64F3DEX2.XX5NormalCompatible
Indiana + Jones and the Infernal Machine?0?Unsupported. Microcode not implemented
Indy Racing 2000F3DEX2.XX5NormalCompatible
International Superstar Soccer '98F3DEX1.XX5NormalCompatible. + Use “Read every frame” option to see correct effects after + scoring a goal  
International Superstar Soccer 2000F3DEX2.XX5NormalCompatible. + Use “Read every frame” option to see correct effects after + scoring a goal  
International Superstar Soccer 64F3DEX1.XX5NormalCompatible. Minor gfx errors
International Track &  Field + 2000F3DEX2.XX5NormalCompatible
International Track & Field Summer + GamesF3DEX2.XX5NormalCompatible
J. League Dynamite Soccer 64F3DEX1.XX5NormalCompatible
J. League Eleven Beat 1997F3DEX1.XX5NormalCompatible
J. League Live 64F3DEX1.XX5NormalCompatible
J. League Tactics SoccerF3DEX2.XX5NormalCompatible
Jangou Simulation Mahjong Do 64F3DEX1.XX5NormalCompatible
Jeopardy!RSP SW 2.0X5NormalCompatible
Jeremy McGrath Supercross 2000F3DEX2.XX5FastCompatible
Jet Force GeminiRSP SW RARE45NormalCompatible
Jikkyou G1 StableF3DEX2.XX5NormalCompatible
Jikkyou J. League 1999 - Perfect Striker + 2F3DEX2.XX5NormalCompatible. + Use “Read every frame” option to see correct effects after + scoring a goal  
Jikkyou J. League Perfect StrikerRSP SW 2.0X5NormalCompatible. + Use “Read every frame” option to see correct effects after + scoring a goal  
Jikkyou Powerful Pro Yakyuu - Basic Han + 2001F3DEX2.XX5NormalCompatible
Jikkyou Powerful Pro Yakyuu 2000F3DEX2.XX5NormalCompatible
Jikkyou Powerful Pro Yakyuu 4F3DEX1.XX5NormalCompatible
Jikkyou Powerful Pro Yakyuu 5F3DEX1.XX5NormalCompatible
Jikkyou Powerful Pro Yakyuu 6F3DEX2.XX5NormalCompatible
Jikkyou World Cup France '98RSP SW 2.0X5NormalCompatible. + Use “Read every frame” option to see correct effects after + scoring a goal  
Jikkyou World Soccer 3RSP SW 2.0X5NormalCompatible
Jinsei Game 64F3DEX2.XX5NormalCompatible
John Romero's DaikatanaF3DEX2.XX5NormalCompatible
Kakutou Denshou - F-Cup ManiaxF3DEX2.XX5NormalCompatible
Ken Griffey Jr.'s SlugfestF3DEX2.XX5NormalCompatible
Killer Instinct GoldRSP SW 2.0X5FastCompatible
King Hill 64 - Extreme SnowboardingF3DEX2.XX5NormalCompatible. Minor gfx errors.
Kiratto Kaiketsu! 64 TanteidanF3DEX1.XX5NormalCompatible
Kirby 64 - The Crystal ShardsF3DEX2.XX5FastCompatible. Use Mupen for correct status bar
Knife Edge - Nose GunnerF3DEX2.XX5FastCompatible
Knockout Kings 2000F3DEX2.XX5FastCompatible. Use 1964. Minor gfx errors
Kobe + Bryant NBA CourtsideF3DEX1.XX5FastCompatible
Kuiki-Uhabi-SuigoRSP SW 2.0X2NormalGfx errors
LEGO RacersF3DEX2.XX5DependsCompatible
Last Legion UX?0?Unsupported. Microcode + not implemented
Legend of Zelda, The - Ocarina of TimeF3DEX 2.06H5*Mostly* FastCompatible
Legend of Zelda 2, The - Majora's MaskF3DEX2.XX5NormalCompatible
Legend of Zelda, The - Ocarina of Time - + Master QuestF3DEX 2.06H5*Mostly* FastCompatible
Les Razmoket - La Chasse aux TrésorsF3DEX2.XX5NormalCompatible
Let's Smash TennisF3DEX1.XX5NormalCompatible
Lode Runner 3-DF3DEX2.XX5NormalCompatible
Looney Tunes - Duck DodgersF3DEX2.XX5SlowCompatible
Lylat WarsF3DEX1.XX5FastCompatible
MRC - Multi Racing ChampionshipF3DEX1.XX5FastCompatible
Mace - The Dark AgeF3DEX1.XX5NormalCompatible.
Madden Football 64F3DEX1.XX5SlowCompatible
Madden NFL 2000F3DEX1.XX5SlowCompatible
Madden NFL 2001F3DEX1.XX5SlowCompatible
Madden NFL 2002F3DEX1.XX5NormalCompatible
Madden NFL 99F3DEX1.XX5NormalCompatible
Magical Tetris ChallengeF3DEX1.XX5NormalCompatible
Mahjong 64RSP SW 2.0X5NormalCompatible
Mahjong Hourouki ClassicRSP SW 2.0X5NormalCompatible
Mahjong MasterRSP SW 2.0X5NormalCompatible. Minors gfx errors
Major League Baseball Featuring Ken + Griffey Jr.F3DEX1.XX3NormalGfx errors
Mario GolfF3DEX2.XX5NormalCompatible
Mario + Kart 64F3DEX1.XX5FastCompatible. Use “Read every frame” option (slow) or use + "Get frame buffer info" with Mupen to see correct billboards
Mario PartyF3DEX2.XX5FastCompatible
Mario Party 2F3DEX2.XX5FastCompatible
Mario Party 3F3DEX2.XX5FastCompatible
Mario StoryF3DEX2.XX5NormalCompatible
Mario + TennisF3DEX2.XX4UnstableVarious gfx errors.
Mario No Photopie?0?Unsupported
Mega Man 64F3DEX2.XX5FastCompatible
Mia Hamm SoccerZSortp 0.335FastCompatible. Minors gfx errors
Michael Owens WLS 2000ZSortp 0.335FastCompatible. Minors gfx errors
Mickey no Racing Challenge USARSP SW RARE45FastCompatible
Mickey's Speedway USARSP SW RARE45FastCompatible
Micro Machines 64 TurboF3DEX1.XX5FastCompatible
Midway's Greatest Arcade Hits Volume 1RSP SW 2.0X3NormalOnly few games are fully playable
Mike Piazza's Strike ZoneF3DEX1.XX5FastCompatible
Milo's Astro LanesF3DEX1.XX5NormalCompatible
Mischief MakersRSP SW 2.0X5NormalCompatible
Mission + ImpossibleF3DEX1.XX5NormalCompatible
Monaco + Grand PrixF3DEX2.XX5NormalCompatible. Use Mupen64
Monaco + Grand Prix - Racing Simulation 2F3DEX2.XX5NormalCompatible. Use 1964
MonopolyF3DEX2.XX5FastCompatible
Monster Truck Madness 64F3DEX2.XX5NormalCompatible
Morita Shougi 64RSP SW 2.0X5NormalCompatible
Mortal Kombat 4F3DEX1.XX5Scene dependentCompatible
Mortal Kombat Mythologies - Sub-ZeroF3DEX1.XX5FastCompatible
Mortal Kombat TrilogyRSP SW 0.2X5FastCompatible
Ms. Pac-Man - Maze MadnessF3DEX2.XX5NormalCompatible
Mystical Ninja 2 - Starring + Goemon F3DEX1.XX5NormalCompatible
Mystical Ninja - Starring GoemonF3DEX1.XX5NormalCompatible
NASCAR 99F3DEX2.XX5NormalCompatible
NASCAR 2000F3DEX2.XX5NormalCompatible
NBA Courtside 2 - Featuring Kobe BryantF3DEX2.XX5NormalCompatible
NBA HangtimeRSP SW 2.0X5SlowCompatible
NBA In the Zone '98F3DEX1.XX5FastCompatible
NBA In the Zone '99F3DEX2.XX5FastCompatible
NBA In the Zone 2F3DEX2.XX5NormalCompatible
NBA In the Zone 2000F3DEX2.XX5NormalCompatible
NBA Jam 2000F3DEX2.XX5SlowCompatible
NBA Jam 99F3DEX2.XX5NormalCompatible
NBA Live 2000F3DEX2.XX5NormalCompatible
NBA Live 99F3DEX2.XX5NormalCompatible
NBA Showtime - NBA on NBCF3DEX2.XX5SlowCompatible. Use PJ64
NFL BlitzF3DEX2.XX5FastCompatible
NFL Blitz - Special EditionF3DEX2.XX5FastCompatible
NFL Blitz 2000F3DEX2.XX5FastCompatible
NFL Blitz 2001F3DEX2.XX5FastCompatible
NFL Quarterback Club 2000F3DEX2.XX5NormalCompatible. Use Nemu 0.8
NFL Quarterback Club 2001F3DEX2.XX5NormalCompatible. Use Nemu 0.8
NFL Quarterback Club 98F3DEX1.XX5NormalCompatible. Use Mupen
NFL Quarterback Club 99F3DEX2.XX5NormalCompatible. Use Nemu 0.8
NHL 99F3DEX2.XX5NormalCompatible
NHL Blades of Steel '99F3DEX2.XX5NormalCompatible
NHL Breakaway 98F3DEX1.XX5NormalCompatible
NHL Breakaway 99F3DEX2.XX5NormalCompatible
NHL Pro 99F3DEX2.XX5NormalCompatible
Nagano + Winter Olympics '98F3DEX1.XX5NormalCompatible
Namco + Museum 64F3DEX1.XX5NormalCompatible
Neon Genesis EvangelionF3DEX2.XX5NormalCompatible
New Tetris, TheF3DEX2.XX5NormalCompatible. + Use + Mupen                                                                                      
Nightmare CreaturesF3DEX2.XX5NormalCompatible. Use PJ64
Nintama Rantarou Gallery 64S2DEX.XX5SlowCompatible
Nintendo All-Star! Dairantou Smash + BrothersF3DEX2.XX5NormalCompatible
Nuclear Strike 64F3DEX2.XX5NormalCompatible
Nushi Zuri 64F3DEX1.XX5NormalCompatible. Use “Read every frame” option (slow) or use + "Get frame buffer info" with Mupen to have backgrounds in game
Nushi Zuri 64 - Shiokaze ni NotteF3DEX2.XX2NormalMissing gfx in game
O.D.TF3DEX2.XX5NormalCompatible
Off Road ChallengeF3DEX1.XX5NormalCompatible
Ogre Battle 64 - Person of Lordly CaliberF3DEX2.XX5NormalCompatible. Use PJ64 or 1964 0.8.5 (Win9X users must use 1964 0.8.5 or + Nemu 0.8, to get backgrounds). Use "Read every frame" option to see + screen transition effects (slow)
Olympic Hockey Nagano '98F3DEX1.XX5NormalCompatible
Onegai MonsterF3DEX2.XX5NormalCompatible
Operation WinBackF3DEX2.XX5FastCompatible, but a gray square sometimes appear on the screen. Missing + sky
PD Ultraman Battle Collection 64F3DEX2.XX5NormalCompatible
PGA European TourF3DEX2.XX5NormalCompatible. Minor gfx errors
Pachinko 365 NichiRSP SW 2.0X2NormalCompatible
Paper MarioF3DEX2.XX5FastCompatible. Minor gfx errors
PaperboyF3DEX2.XX5NormalCompatible
Parlor! Pro 64 Pachinko Jikki Simulation + GameS2DEX.XX5NormalCompatible
Penny RacersF3DEX1.XX5FastCompatible
Perfect DarkRSP SW PD5SlowCompatible. Use "Read every frame" (slow) or "Get frame + buffer info" with Mupen to get correct pause menu in game
Pikachu Genki DechuF3DEX2.XX3NormalGfx errors (needs voice pak)
Pilot WingsF3DEX1.XX5FastCompatible
Pocket + Monsters SnapF3DEX2.XX5NormalCompatible. Use "Read every frame" option when selecting shots + for professor Oak
Pokemon Puzzle LeagueS2DEX.XX5NormalCompatible
Pokemon SnapF3DEX2.XX5NormalCompatible. Use "Read every frame" option when selecting shots + for professor Oak
Pokemon StadiumF3DEX2.XX5FastCompatible
Pokemon Stadium 2F3DEX2.XX5NormalCompatible
Polaris SnoCrossF3DEX2.XX5NormalCompatible
Power League Baseball 64F3DEX2.XX4NormalCompatible
Power Rangers - Lightspeed RescueF3DEX2.XX5NormalCompatible
Powerpuff Girls, The - Chemical + X-tractionF3DEX1.XX5NormalCompatible
Premier Manager 64F3DEX2.XX5FastCompatible
Pro Mahjong Kiwame 64RSP SW 2.0X5NormalCompatible
Pro Majhong Tsuwamono 64S2DEX.XX5SlowCompatible
Puyo Puyo 4 - Puyo Puyo PartyS2DEX.XX5NormalCompatible
Puyo Puyo Sun 64RSP SW 2.0X5NormalCompatible
Puzzle Bobble 64F3DEX1.XX5NormalCompatible
Quake 64F3DEX1.XX5FastCompatible
Quake IIF3DEX1.XX5NormalCompatible, Use "Read every frame" (slow) or "Get frame + buffer info" with Mupen to get correct pause menu in game
Quest 64F3DEX1.XX5FastCompatible
RR64 - Ridge Racer 64F3DEX2.XX5FastCompatible. Pause menu doesn't work correctly with Voodoo 1-3
RTL World League Soccer 2000ZSortp 0.335FastCompatible. Minor gfx errors
Racing Simulation 2F3DEX2.XX5NormalCompatible. Use 1964. Minor gfx errors
Rakuga KidsF3DEX2.XX5NormalCompatible
Rally '99F3DEX2.XX5NormalCompatible
Rally Challenge 2000F3DEX2.XX5NormalCompatible
Rampage - World TourF3DEX1.XX5FastCompatible
Rampage 2 - Universal TourF3DEX1.XX5NormalCompatible
Rat AttackF3DEX1.XX5FastCompatible
Rayman 2 - The Great EscapeF3DEX1.XX5NormalCompatible. Use "Read every frame" option to see correct + transition effects in game
Razor Freestyle ScooterF3DEX2.XX5NormalCompatible
Re-VoltF3DEX2.XX5FastCompatible. Use PJ64
Ready 2 Rumble BoxingF3DEX1.XX5FastCompatible
Ready 2 Rumble Boxing Round 2F3DEX1.XX5FastCompatible
Resident Evil 2F3DEX2.XX5NormalCompatible
Road Rash 64 F3DEX2.XX5NormalCompatible
RoadstersF3DEX2.XX5NormalCompatible
Robotech + - Crystal Dreams (Beta)F3DEX2.XX5NormalCompatible
Robot Ponkottsu 64 - Caramel of the 7 + SeasF3DEX2.XX5NormalCompatible
Robotron 64F3DEX1.XX5FastCompatible
Rocket - Robot on WheelsF3DEX2.XX5FastCompatible
Rockman DashF3DEX2.XX5FastCompatible
Rugrats - Scavenger HuntF3DEX2.XX5FastCompatible
Rugrats - Treasure HuntF3DEX2.XX5FastCompatible
Rugrats in Paris - The MovieF3DEX2.XX5FastCompatible
Rush 2 - Extreme Racing USA F3DEX2.XX5NormalCompatible
S.C.A.R.S.F3DEX2.XX5FastCompatible
SD Hiryuu no Ken DensetsuF3DEX1.XX5NormalCompatible. Minor gfx errors
San Francisco Rush - Extreme RacingF3DEX1.XX5NormalCompatible
San Francisco Rush 2049F3DEX2.XX5NormalCompatible
Scooby-Doo - Classic Creep CapersF3DEX2.XX5NormalCompatible. Sky in game doesn't work correctly with Voodoo 1-3
Shadow Man F3DEX2.XX5NormalCompatible. Use "Read every frame" option (slow) or "Get + frame buffer info" with Mupen to have correct pause menu in game
Shadowgate 64 - Trials of the Four TowersF3DEX2.XX5FastCompatible
Sim City 2000S2DEX.XX5NormalCompatible
Snow SpeedersF3DEX2.XX5NormalCompatible
Snowboard KidsF3DEX1.XX5NormalCompatible
Snowboard Kids 2F3DEX2.XX5NormalCompatible
Sonic Wings AssaultRSP SW 2.0X5SlowCompatible
South + ParkF3DEX2.XX5FastCompatible
SouthPark - Chef's Luv ShackF3DEX2.XX5FastCompatible
South + Park RallyF3DEX2.XX5FastCompatible
Space DynamitesTURBO3D5NormalCompatible
Space + Invaders F3DEX2.XX5FastCompatible
Space Station Silicon ValleyF3DEX1.XX5NormalCompatible
Spider-Man F3DEX2.XX5FastCompatible
Star Fox 64F3DEX1.XX5FastCompatible
Star Soldier - Vanishing EarthF3DEX1.XX5FastCompatible
Star TwinsRSP SW RARE45NormalCompatible. Use "Get frame buffer info" option with Mupen or + use “Read every frame” option (slow) to see correct TV
Star Wars - Rogue Squadron?0?Unsupported. Microcode not implemented
Star Wars - Shadows of the EmpireRSP SW 2.0D EXT5NormalCompatible
Star Wars Episode I - Battle for Naboo?0?Unsupported. Microcode not implemented
Star Wars Episode I - RacerF3DEX2.XX5NormalCompatible
StarCraft 64 F3DEX2.XX5NormalCompatible
Starshot - Space Circus FeverF3DEX2.XX5NormalCompatible
Stunt Racer 64?0?Unsupported
Super B-Daman - Battle Phoenix 64F3DEX1.XX5FastCompatible
Super Bowling 64F3DEX2.XX3FastGfx errors
Super Mario + 64 RSP SW 2.0X5FastCompatible
Super Robot SpiritsF3DEX1.XX5NormalCompatible
Super Robot Taisen 64RSP SW 2.0X5NormalCompatible
Super Smash Bros.F3DEX2.XX5NormalCompatible
Super Speed Race 64F3DEX1.XX5FastCompatible
Supercross 2000F3DEX2.XX5NormalCompatible
Superman F3DEX1.XX5NormalCompatible
Susume! taisen puzzle dama toukon ! + Marumata ChouS2DEX.XX5NormalCompatible
Taz ExpressRSP SW 2.0X5NormalCompatible. Use Mupen 0.4 
Telefoot Soccer 2000ZSortp 0.335NormalCompatible. Minor gfx errors
Tetris 64RSP SW 2.0X5NormalCompatible
TetrisphereRSP SW 2.0X5FastCompatible
Tigger's Honey HuntF3DEX2.XX5NormalCompatible
Tom Clancy's Rainbow SixF3DEX2.XX5NormalCompatible
Tom and Jerry in Fists of FurryF3DEX1.XX5NormalCompatible
Tonic TroubleF3DEX1.XX5NormalCompatible. Use "Read every frame" option to see correct + transition effects for pause menu in game
Tony Hawk's Pro SkaterF3DEX2.XX5FastCompatible. Use PJ64
Tony Hawk's Pro Skater 2F3DEX2.XX5FastCompatible
Tony Hawk's Pro Skater 3F3DEX2.XX5FastCompatible
Toon + PanicF3DEX2.XX5FastCompatible
Top Gear Hyper-BikeF3DEX2.XX2NormalMajor gfx errors. Use Mupen
Top Gear OverdriveF3DEX2.XX4NormalGfx errors. Use Mupen
Top Gear RallyF3DEX1.XX5NormalCompatible
Top Gear Rally 2F3DEX2.XX5NormalCompatible
Toukon Roads?0?Unsupported. Microcode + not implemented
Toukon Roads 2?0?Unsupported. Microcode + not implemented
Toy Story 2 F3DEX1.XX5NormalCompatible
Transformers - Beast Wars Metals 64F3DEX2.XX5FastCompatible
Transformers - Beast Wars TransmetalF3DEX2.XX5FastCompatible
Triple Play + 2000 F3DEX2.XX5NormalCompatible. Use "Get frame buffer info" option with Mupen or + use "Read every frame" option to see correct TV monitors (slow)
Tsumi to Batsu - Chikyuu no KeishoushaF3DEX2.XX5NormalCompatible
Turok - Dinosaur HunterF3DEX1.XX5FastCompatible
Turok - Rage WarsF3DEX2.XX5NormalCompatible
Turok 2 - Seeds of EvilF3DEX2.XX5SlowCompatible
Turok 3 - Shadow of OblivionF3DEX2.XX5SlowCompatible
Twisted Edge Extreme SnowboardingF3DEX2.XX5SlowCompatible. Minor gfx errors
V-Rally Edition 99F3DEX2.XX5SlowCompatible. Minor gfx errors
Vigilante 8 F3DEX2.XX2SlowMany gfx errors
Vigilante 8 - 2nd OffenseF3DEX2.XX2SlowMany gfx errors
Virtual Chess 64F3DEX1.XX5SlowCompatible
Virtual Pool 64F3DEX1.XX5FastCompatible
Virtual Pro Wrestling 2  - Oudou + KeishouF3DEX2.XX5NormalCompatible. Use "Read every frame" option to see motion blur + effects during intro
Virtual Pro Wrestling 64F3DEX1.XX5NormalCompatible
WCW Backstage AssaultF3DEX2.XX5NormalCompatible
WCW MayhemF3DEX2.XX5NormalCompatible
WCW NitroF3DEX1.XX5NormalCompatible
WCW vs. nWo - World TourF3DEX1.XX5NormalCompatible
WCW-nWo RevengeF3DEX2.XX5NormalCompatible
WWF - War ZoneF3DEX2.XX5FastCompatible. Use "Get frame buffer info" option with Mupen or + use "Read every frame" option to see correct TV monitors (slow)
WWF AttitudeF3DEX2.XX5FastCompatible
WWF No MercyF3DEX2.XX5FastCompatible
WWF WrestleMania 2000F3DEX2.XX5NormalCompatible. Use "Read every frame" option to see motion blur + effects during intro
Waialae Country Club - True Golf ClassicsF3DEX1.XX5NormalCompatible. Minor gfx errors
War GodsRSP SW 2.0X5FastCompatible
Wave Race 64RSP SW 2.0D EXT5FastCompatible
Wave Race 64 Shindou EditionF3DEX1.XX5NormalCompatible
Wayne Gretzky's 3D Hockey '98F3DEX1.XX5FastCompatible
WetrixF3DEX1.XX5NormalCompatible
Wheel of FortuneRSP SW 2.0X5SlowCompatible
Wild ChoppersRSP SW 2.0X5NormalCompatible
WinBack - Covert OperationsF3DEX2.XX5FastCompatible, but a gray square sometimes appear on the screen. Missing + sky
Wipeout 64F3DEX1.XX5FastCompatible
Wonder Project J2RSP SW 2.0X5NormalCompatible
World Cup 98F3DEX1.XX5NormalCompatible
World Driver Championship?0?Unsupported
Worms + - ArmageddonF3DEX2.XX5NormalCompatible
Xena Warrior Princess - Talisman of FateF3DEX2.XX5FastCompatible
Yakouchuu II - Satsujun KouruF3DEX2.XX4NormalUse Nemu 0.8 (disable audio HLE). No movies
Yoshi's StoryS2DEX.XX5NormalCompatible. + Minor texture errors. Use "Read every frame" option to see + transition effects 
Yuke Yuke!! Trouble MakersRSP SW 2.0X5NormalCompatible
Zelda no Densetsu 2 - Mujura no KamenF3DEX2.XX5NormalCompatible
Zelda no Densetsu - Toki no OcarinaF3DEX 2.06H5*Mostly* FastCompatible
Zool - Majou Tsukai DensetsuF3DEX1.XX5NormalCompatible
  
+ + + + diff --git a/Source/Glide64/Internalization/Glide64_de_DE.po b/Source/Glide64/Internalization/Glide64_de_DE.po new file mode 100644 index 000000000..a04607c46 --- /dev/null +++ b/Source/Glide64/Internalization/Glide64_de_DE.po @@ -0,0 +1,1284 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2011-12-19 17:29+0700\n" +"PO-Revision-Date: 2012-01-27 16:23+0100\n" +"Last-Translator: Herr et \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: Config.cpp:64 +msgid "Rendering" +msgstr "Wiedergabe" + +#: Config.cpp:65 +msgid "Other" +msgstr "Andere" + +#: Config.cpp:66 +msgid "Speed" +msgstr "Geschwindigkeit" + +#: Config.cpp:67 +msgid "Time" +msgstr "Zeit" + +#: Config.cpp:68 +msgid "On screen display" +msgstr "Anzeigen" + +#: Config.cpp:69 +msgid "OpenGL settings" +msgstr "OpenGL Einstellungen" + +#: Config.cpp:70 +#: Config.cpp:137 +msgid "Frame buffer emulation" +msgstr "Framebuffer Emulation" + +#: Config.cpp:71 +msgid "" +"Windowed or\n" +"3dfx card resolution:" +msgstr "Fenster- oder 3dfx-Kartenauflösung" + +#: Config.cpp:99 +msgid "Vertical sync" +msgstr "vertikale Synchronisation" + +#: Config.cpp:100 +msgid "Show advanced emulation options" +msgstr "erweiterte Emulationseinstellungen anzeigen" + +#: Config.cpp:101 +msgid "Show texture enhancement options" +msgstr "Texturverbesserungsoptionen anzeigen" + +#: Config.cpp:102 +msgid "Screenshot format:" +msgstr "Screenshotformat" + +#: Config.cpp:105 +msgid "Language: " +msgstr "Sprache:" + +#: Config.cpp:106 +msgid "LANGUAGE_NAME" +msgstr "Deutsch" + +#: Config.cpp:112 +msgid "FPS counter" +msgstr "FPS-Zähler" + +#: Config.cpp:113 +msgid "VI/s counter" +msgstr "VI/s-Zähler" + +#: Config.cpp:114 +#, c-format +msgid "% speed" +msgstr "% Geschwindigkeit" + +#: Config.cpp:115 +msgid "Clock enabled" +msgstr "Uhr anzeigen" + +#: Config.cpp:116 +msgid "Clock is 24-hour" +msgstr "24 Stunden verwenden" + +#: Config.cpp:117 +msgid "Transparent text background" +msgstr "transparenter Texthintergrund" + +#: Config.cpp:118 +msgid "" +"Full screen\n" +"resolution:" +msgstr "Vollbildauflösung" + +#: Config.cpp:121 +msgid "Anisotropic filtering" +msgstr "anisotropische Filterung" + +#: Config.cpp:122 +msgid "Autodetect " +msgstr "automatisch" + +#: Config.cpp:123 +msgid "VRAM size" +msgstr "VRAM-Größe bestimmen" + +#: Config.cpp:125 +msgid "Mb" +msgstr "Mb" + +#: Config.cpp:126 +msgid "Use frame buffer objects" +msgstr "Framebufferobjekte verwenden" + +#: Config.cpp:133 +msgid "Current game emulation settings. Change with care!" +msgstr "Spielspezifische Emulationseinstellungen. Vorsicht bei Veränderungen!" + +#: Config.cpp:135 +msgid "Default emulation settings. Not recommended to change!" +msgstr "Standardmäßige Emulationseinstellungen. Veränderungen sind nicht empfohlen!" + +#: Config.cpp:136 +msgid "General options" +msgstr "allgemeine Optionen" + +#: Config.cpp:138 +msgid "Depth buffer emulation" +msgstr "depht buffer emulation" + +#: Config.cpp:139 +msgid "Filtering mode:" +msgstr "Filtermodus" + +#: Config.cpp:141 +msgid "Automatic" +msgstr "automatisch" + +#: Config.cpp:142 +msgid "Force Bilinear" +msgstr "bilinearen Filter erzwingen" + +#: Config.cpp:143 +msgid "Force Point-sampled" +msgstr "point-sampled Filter erzwingen" + +#: Config.cpp:146 +msgid "Buffer swapping method:" +msgstr "Buffertauschmethode" + +#: Config.cpp:148 +msgid "Old" +msgstr "alt" + +#: Config.cpp:149 +msgid "New" +msgstr "neu" + +#: Config.cpp:150 +msgid "Hybrid" +msgstr "hybrid" + +#: Config.cpp:153 +msgid "LOD calculation:" +msgstr "LOD-Kalkulation" + +#: Config.cpp:155 +msgid "off" +msgstr "aus" + +#: Config.cpp:156 +msgid "fast" +msgstr "schnell" + +#: Config.cpp:157 +msgid "precise" +msgstr "prezise" + +#: Config.cpp:160 +msgid "Aspect ratio:" +msgstr "Seitenverhältnis:" + +#: Config.cpp:162 +msgid "4:3 (default)" +msgstr "4:3 (Standard)" + +#: Config.cpp:163 +msgid "Force 16:9" +msgstr "16:9 erzwingen" + +#: Config.cpp:164 +msgid "Stretch" +msgstr "strecken" + +#: Config.cpp:165 +msgid "Original" +msgstr "Original" + +#: Config.cpp:168 +msgid "Fog" +msgstr "Nebel" + +#: Config.cpp:169 +msgid "Buffer clear on every frame" +msgstr "Buffer nach jedem Frame entleeren" + +#: Config.cpp:170 +msgid "Enable frame buffer emulation" +msgstr "Framebufferemulation aktivieren" + +#: Config.cpp:171 +msgid "Hardware frame buffer emulation" +msgstr "Hardware Framebuffer Emulation" + +#: Config.cpp:172 +msgid "Get frame buffer info" +msgstr "Framebufferinformation erhalten" + +#: Config.cpp:173 +msgid "Read every frame (slow!)" +msgstr "jeden Frame lesen (langsam!)" + +#: Config.cpp:174 +msgid "Render N64 frame buffer as texture" +msgstr "N64 Framebuffer als Textur darstellen" + +#: Config.cpp:175 +msgid "Detect CPU write to the N64 frame buffer" +msgstr "CPU-writes auf den Nintendo64 Framebuffer ermitteln" + +#: Config.cpp:176 +msgid "Software depth buffer rendering" +msgstr "Depthbufferdarstellung durch Software" + +#: Config.cpp:200 +#: Config.cpp:619 +msgid "Texture enhancement" +msgstr "Texturverbesserung" + +#: Config.cpp:201 +msgid "Hi-resolution textures" +msgstr "Texturpakete" + +#: Config.cpp:202 +msgid "Common" +msgstr "allgemein" + +#: Config.cpp:203 +msgid "Presets" +msgstr "Voreinstellungen" + +#: Config.cpp:204 +#: Config.cpp:205 +msgid "Performance tweaks" +msgstr "Leistung verbessern" + +#: Config.cpp:206 +msgid "Filter" +msgstr "Filterung" + +#: Config.cpp:208 +#: Config.cpp:219 +#: Config.cpp:238 +msgid "None" +msgstr "keine/s" + +#: Config.cpp:209 +msgid "Smooth filtering 1" +msgstr "weiche Filterung 1" + +#: Config.cpp:210 +msgid "Smooth filtering 2" +msgstr "weiche Filterung 2" + +#: Config.cpp:211 +msgid "Smooth filtering 3" +msgstr "weiche Filterung 3" + +#: Config.cpp:212 +msgid "Smooth filtering 4" +msgstr "weiche Filterung 4" + +#: Config.cpp:213 +msgid "Sharp filtering 1" +msgstr "harte Filterung 1" + +#: Config.cpp:214 +msgid "Sharp filtering 2" +msgstr "harte Filterung 2" + +#: Config.cpp:217 +msgid "Enhancement" +msgstr "Erweiterung" + +#: Config.cpp:220 +msgid "Store" +msgstr "Speicher" + +#: Config.cpp:230 +msgid "Texture cache" +msgstr "Textur-cache" + +#: Config.cpp:232 +msgid "Mbytes" +msgstr "Mbytes" + +#: Config.cpp:233 +msgid "Ignore Backgrounds" +msgstr "Hintergründe ignorieren" + +#: Config.cpp:234 +#: Config.cpp:245 +msgid "Apply texture compression" +msgstr "Texturkomprimierung anwenden" + +#: Config.cpp:235 +#: Config.cpp:246 +msgid "Compress texture cache" +msgstr "Textur-cache komprimieren" + +#: Config.cpp:236 +msgid "Format" +msgstr "Format" + +#: Config.cpp:239 +msgid "Rice format" +msgstr "Rice Format" + +#: Config.cpp:242 +msgid "Tile textures" +msgstr "Texturen teilen" + +#: Config.cpp:243 +msgid "Force 16bpp textures" +msgstr "16bpp-Texturen erzwingen" + +#: Config.cpp:244 +msgid "Alternative CRC calculation" +msgstr "alternative CRC-Kalkulation" + +#: Config.cpp:247 +msgid "Use alpha channel fully" +msgstr "Alphakanal vollständig verwenden" + +#: Config.cpp:248 +msgid "Texture dumping/editing mode" +msgstr "Texturbearbeitungsmodus" + +#: Config.cpp:249 +msgid "Texture compression method" +msgstr "Texturkompressionsmethode" + +#: Config.cpp:255 +msgid "Save texture cache to hard disk" +msgstr "Textur-cache auf der Festplatte speichern" + +#: Config.cpp:256 +msgid "Best performance" +msgstr "beste Leisung" + +#: Config.cpp:257 +msgid "Best texture quality" +msgstr "höchste Texturqualität" + +#: Config.cpp:263 +msgid "Developers settings" +msgstr "" + +#: Config.cpp:264 +msgid "Debug/Misc" +msgstr "" + +#: Config.cpp:265 +msgid "Autodetect Microcode" +msgstr "" + +#: Config.cpp:266 +msgid "Force Microcode:" +msgstr "" + +#: Config.cpp:279 +msgid "Wireframe using:" +msgstr "" + +#: Config.cpp:281 +msgid "Original colors" +msgstr "" + +#: Config.cpp:282 +msgid "Vertex colors" +msgstr "" + +#: Config.cpp:283 +msgid "Red only" +msgstr "" + +#: Config.cpp:286 +msgid "Log to rdp.txt (SLOW)" +msgstr "" + +#: Config.cpp:287 +msgid "Unknown combiners as red" +msgstr "" + +#: Config.cpp:288 +msgid "Log clear every frame" +msgstr "" + +#: Config.cpp:289 +msgid "Combiner logging" +msgstr "" + +#: Config.cpp:290 +msgid "Run (+log) in window" +msgstr "" + +#: Config.cpp:291 +msgid "Cmb. clear every frame" +msgstr "" + +#: Config.cpp:292 +msgid "Error log (rdp_e.txt)" +msgstr "" + +#: Config.cpp:293 +msgid "Bilinear filter texture cache" +msgstr "" + +#: Config.cpp:325 +#: Config.cpp:546 +msgid " auto" +msgstr "" + +#: Config.cpp:382 +msgid "Please choose language:" +msgstr "Wähle deine Sprache:" + +#: Config.cpp:383 +msgid "Language" +msgstr "Sprache" + +#: Config.cpp:390 +msgid "Press OK to change to " +msgstr "Drücke OK um die Sprache zu ändern" + +#: Config.cpp:486 +msgid "Basic settings" +msgstr "Grundeinstellungen" + +#: Config.cpp:487 +msgid "" +"Resolution\n" +"This option selects the fullscreen resolution for 3dfx cards and windowed resolution for other cards\n" +"(note again that for 3dfx cards the plugin must be in fullscreen mode to see anything).\n" +"[Recommended: 640x480, 800x600, 1024x768]" +msgstr "" +"Auflösung\n" +"Diese Option wählt die Vollbildauflösung für 3dfx-Grafikkarten und die Fenstergröße für andere Grafikkarten\n" +"(bei 3dfx-Grafikkarten muss der Vollbildmodus verwendet werden, um etwas zu sehen).\n" +"[empfohlen: 640x480, 800x600, 1024x768]" + +#: Config.cpp:491 +msgid "" +"Vertical sync\n" +"This option will enable the vertical sync, which will prevent tearing.\n" +"Note: this option will ONLY have effect if vsync is set to \"Software Controlled\".\n" +msgstr "" +"vertikale Synchronisation\n" +"Diese Option aktiviert vertikale Synchronisation um tearing zu vermeiden.\n" +"Beachte: Diese Option hat NUR dann einen Effekt, wenn vsync auf \"software controlled\" gestellt ist." + +#: Config.cpp:493 +msgid "Select a format, in which screen shots will be saved" +msgstr "Wähle das Format, in dem Screenshots gespeichert werden sollen" + +#: Config.cpp:500 +msgid "" +"Language select:\n" +"Press the button to invoke language selection dialog.\n" +"Selected language will be activated after restart of the configuration dialog." +msgstr "" +"Sprachauswahl:\n" +"Drücke den Knopf, um den Dialog zur Sprachauswahl aufzurufen.\n" +"Die gewählte Sprache wird nach einem Neustart des Konfigurationsdialoges aktiviert." + +#: Config.cpp:501 +msgid "" +"FPS counter\n" +"When this option is checked, a FPS (frames per second) counter will be shown\n" +"in the lower left corner of the screen.\n" +"[Recommended: your preference]" +msgstr "" +"FPS-Zähler\n" +"Wenn diese Option aktiviert wird, wird ein FPS (Frames pro Sekunde)-Zähler\n" +"in der linken, unteren Ecke des Bildes angezeigt.\n" +"[empfohlen: deine Wahl]" + +#: Config.cpp:503 +msgid "" +"VI/s counter\n" +"When this option is checked, a VI/s (vertical interrupts per second) counter\n" +"will be shown in the lower left corner of the screen. This is like the FPS\n" +"counter but will be consistent at 60 VI/s for full speed on NTSC (U) games and\n" +"50 VI/s for full speed on PAL (E) ones.\n" +"[Recommended: your preference]" +msgstr "" +"VI/s-Zähler\n" +"Wenn diese Option aktiviert wird, wird ein VI/s (vertikale Unterbrechungen pro Sekunde)-Zähler\n" +"in der linken, unteren Ecke des Bildes angezeigt. Das ist wie bei dem FPS-Zähler, aber es wird\n" +"konstant 60 VI/s für Normalgeschwindigkeit bei NTSC (U) Spielen und 50 VI/s für\n" +"Normalgeschwindigkeit bei PAL (E) Spielen anzeigen.\n" +"[empfohlen: deine Wahl]" + +#: Config.cpp:505 +#, c-format +msgid "" +"% speed\n" +"This displays a percentage of the actual N64 speed in the lower\n" +"left corner of the screen.\n" +"[Recommended: your preference]" +msgstr "" +"% Geschwindigkeit\n" +"Zeigt die aktuelle Geschwindigkeit in % in der linken, unteren Ecke\n" +"des Bildes an.\n" +"[empfohlen: deine Wahl]" + +#: Config.cpp:507 +msgid "" +"Clock enabled\n" +"This option will put a clock in the lower right corner of the screen, showing the current time.\n" +"[Recommended: your preference]" +msgstr "" +"Uhr anzeigen\n" +"Diese Option zeigt eine Uhr in der rechten, unteren Ecke des Bildes an, die die Uhrzeit anzeigt.\n" +"[empfohlen: deine Wahl]" + +#: Config.cpp:510 +msgid "" +"Display hours as 24-hour clock.\n" +"[Recommended: your preference]" +msgstr "" +"Zeigt die Uhr im 24-Stunden-Format an.\n" +"[empfohlen: deine Wahl]" + +#: Config.cpp:511 +msgid "" +"Transparent text background\n" +"If this is checked, all on-screen messages will have a transparent background. Otherwise, it will have a solid black background.\n" +"[Recommended: your preference]" +msgstr "" +"transparenter Texthintergrund\n" +"Ersetzt den schwarzen Standardhintergrund für alle Anzeigen durch einen transparenten Hintergrund.\n" +"[empfohlen: deine Wahl]" + +#: Config.cpp:514 +msgid "" +"Enable \"Emulation settings\" panel. For experienced users only!\n" +"It shows default emulation settings when game is not loaded, or current game settings otherwise." +msgstr "" +"Zeigt die \"Emulationseinstellungen\" an. Nur für erfahrene Benutzer!\n" +"Wenn kein Spiel geladen ist, werden die Standardeinstellungen angezeigt. Während des Spiels\n" +"werden die Optionen für das jeweilige Spiel angezeigt." + +#: Config.cpp:516 +msgid "" +"Enable \"Texture enhancement\" panel.\n" +"It shows various enhancement options for original textures as well as options for hi-resolution textures." +msgstr "" +"Zeigt das Texturverbesserungsmenü an.\n" +"Es zeigt verschiedene Verbesserungsoptionen für Originaltexturen und Texturpakete an." + +#: Config.cpp:517 +msgid "" +"Full screen resolution:\n" +"This sets the full screen resolution for non-3dfx video cards.\n" +"All the resolutions that your video card/monitor support should be displayed.\n" +"[Recommended: native (max) resolution of your monitor - unless performance becomes an issue]" +msgstr "" +"Vollbildauflösung:\n" +"Bestimmt die Vollbildauflösung für nicht-3dfx Grafikkarten.\n" +"Alle Auflösungen, die deine Grafikkarte/dein Monitor unterstützt, sollten angezeigt werden.\n" +"[empfohlen: maximale Auflösung deines Monitors - es sei denn die Leistung leidet darunter]" + +#: Config.cpp:520 +msgid "" +"Anisotropic filtering:\n" +"This filter sharpens and brings out the details of textures that recede into the distance.\n" +"When activated, it will use the max anisotropy your video card supports.\n" +"However, this will override native way of texture filtering and may cause visual artifacts in some games.\n" +"[Recommended: your preference, game dependant]" +msgstr "" +"anisotropische Filterung:\n" +"Dieser Filter schärft Texturen, die in die Ferne ragen und bringt die Details besser zur Geltung.\n" +"Durch die Aktivierung wird so viel Anisotropie verwendet, wie deine Grafikkarte unterstützt.\n" +"Die naturliche Texturfilterung wird jedoch überschrieben und in manchen Spielen können Bildfehler entstehen.\n" +"[empfohlen: deine Wahl, Spielabhängig]" + +#: Config.cpp:521 +msgid "" +"Autodetect VRAM Size:\n" +"Since OpenGL cannot do this reliably at the moment, the option to set this manually is available.\n" +"If checked, plugin will try to autodetect VRAM size.\n" +"But if this appears wrong, please uncheck and set it to correct value.\n" +"[Recommended: on]" +msgstr "" +"automatisch VRAM-Größe bestimmen:\n" +"Da OpenGL diese Funktion derzeit nicht zuverlässig übernehmen kann, ist sie manuell einstellbar.\n" +"Wenn diese Option ausgewählt wird, wird das Plugin versuchen, die VRAM-Größe automatisch zu bestimmen.\n" +"Bitte stelle den richtigen Wert ein, wenn sich der automatische Wert als falsch herausstellt.\n" +"[empfohlen: ein]" + +#: Config.cpp:523 +msgid "" +"Use frame buffer objects:\n" +"Changes the way FB effects are rendered - with or without usage of the OpenGL Frame Buffer Objects (FBO) extension.\n" +"The choice depends on game and your video card. FBO off is good for NVIDIA cards, while for ATI cards, it's usually best that FBOs are turned on.\n" +"Also, some FB effects works only with one of the methods, no matter, which card you have.\n" +"On the whole, with FBO off, compatibility/ accuracy is a bit better (which is the case for Resident Evil 2).\n" +"However, with FBO on with some systems, it can actually be a bit faster in cases.\n" +"[Recommended: video card and game dependant]" +msgstr "" +"Framebufferobjekte verwenden:\n" +"Ändert die Art, in der FB-Effekte verarbeitet werden - mit oder ohne der OpenGL Frame Buffer Objects (FBO)-Erweiterung.\n" +"Die Auswahl hängt vom Spiel und von der Grafikkarte ab. FBO aus ist gut für NVIDIA-Karten, während es für ATI-Karten meist am besten\n" +"ist, wenn FBO aktiviert sind. Manche FB-Effekte funktionieren nur mit einer dieser Methoden unabhängig von der Grafikkarte.\n" +"Insgesamt ist Kompatibilität/Genauigkeit ohne FBO ein bisschen besser (das ist in Resident Evil 2 der Fall).\n" +"Jedoch ist die Spielgeschwindigkeit auf manchen Systemen besser, wenn FBO aktiviert wurde.\n" +"[empfohlen: von der Grafikkarte und vom Spiel abhängig]" + +#: Config.cpp:578 +msgid "Emulation settings" +msgstr "Emulationseinstellungen" + +#: Config.cpp:579 +msgid "" +"Filtering mode\n" +"There are three filtering modes possible:\n" +"* Automatic filtering - filter exactly how the N64 specifies.\n" +"* Point-sampled filtering - causes texels to appear square and sharp.\n" +"* Bilinear filtering - interpolates the texture to make it appear more smooth.\n" +"[Recommended: Automatic]" +msgstr "" +"Filtermodus:\n" +"3 verschiedene Filtermodi sind möglich:\n" +"*Automatische Filterung - filtert genauso, wie es der N64 vorgibt.\n" +"*Point-sampled Filterung - lässt texturen eckig und scharf erscheinen.\n" +"*bilineare Filterung - interpoliert Texturen um sie weicher erscheinen zu lassen.\n" +"[empfohlen: automatisch]" + +#: Config.cpp:583 +msgid "" +"Buffer swapping method\n" +"There are 3 buffer swapping methods:\n" +"* old - swap buffers when vertical interrupt has occurred.\n" +"* new - swap buffers when set of conditions is satisfied. Prevents flicker on some games.\n" +"* hybrid - mix of first two methods.\n" +"Can prevent even more flickering then previous method, but also can cause artefacts.\n" +"If you have flickering problems in a game (or graphics that don't show),\n" +"try to change swapping method.\n" +"[Recommended: new (hybrid for Paper Mario)]" +msgstr "" +"Buffertauschmethode\n" +"Es gibt 3 Buffertauschmethoden:\n" +"*alt - wechselt Buffer, wenn eine vertikale Unterbrechung aufgetreten ist\n" +"*new - wechselt Buffer, wenn bestimmte Bedingungen erfüllt sind. Vermeidet Flimmern in manchen Spielen\n" +"*hybrid - eine Mischung aus diesen zwei Methoden\n" +"Kann mehr Flimmern als die vorherige Methode vermeiden, aber kann auch Bildfehler verursachen.\n" +"Bei Problemen mit Flimmern in einem Spiel (oder mit Grafiken die nicht erscheinen),\n" +"versuche die Methode zu ändern.\n" +"[empfohlen: neu (hybrid für Paper Mario)]" + +#: Config.cpp:587 +msgid "" +"Per-pixel level-of-detail calculation\n" +"N64 uses special mechanism for mip-mapping, which nearly impossible to reproduce\n" +"correctly on PC hardware. This option enables approximate emulation of this feature.\n" +"For example, it is required for the Peach/Bowser portrait's transition in Super Mario 64.\n" +"There are 3 modes:\n" +"* off - LOD is not calculated\n" +"* fast - fast imprecise LOD calculation.\n" +"* precise - most precise LOD calculation possible, but more slow.\n" +"[Recommended: your preference]" +msgstr "" +"Detailstufen (Level-Of-Detail)-Kalkulation pro Pixel\n" +"Es ist beinahe unmöglich den speziellen Mechanismus des N64 für mip-mapping korrekt\n" +"auf PC-Hardware wiederzugeben. Diese Option stellt dieses Feature annäherungsweise dar.\n" +"Zum Beispiel benötigt Ãœbergang des Peach/Bowser Porträts in Super Mario 64 diese Option.\n" +"Es gibt 3 Modi:\n" +"*aus - LOD wird nicht kalkuliert\n" +"*schnell - schnelle und ungenaue LOD-Kalkulation\n" +"*prezise - die preziseste LOD-Kalkulation ist etwas langsamer\n" +"[empfohlen: deine Wahl]" + +#: Config.cpp:592 +msgid "" +"Aspect ratio of the output.\n" +"Most N64 games use 4:3 aspect ratio, but some support widescreen too.\n" +"You may select appropriate aspect here and set widescreen mode in game settings.\n" +"In \"Stretch\" mode the output will be stretched to the entire screen,\n" +"other modes may add black borders if necessary" +msgstr "" +"Seitenverhältnis der Anzeige\n" +"Die meisten N64-Spiele verwenden das Seitenverhältnis 4:3 aber manche unterstützen auch Breitbild.\n" +"Stelle hier das passende Seitenverhältnis ein und lege den Breitbildmodus in den Spieleinstellungen fest.\n" +"Mit \"strecken\" wird das Bild verzerrt, um den Bildschirm auszufüllen,\n" +"andere Modi verwenden schwarze Streifen, wenn benötigt." + +#: Config.cpp:595 +msgid "" +"Fog enabled\n" +"Sets fog emulation on//off.\n" +"[Recommended: on]" +msgstr "" +"Nebel aktivieren\n" +"Schaltet Nebel ein/aus.\n" +"[empfohlen: ein]" + +#: Config.cpp:597 +msgid "" +"Buffer clear on every frame\n" +"Forces the frame buffer to be cleared every frame drawn.\n" +"Usually frame buffer clear is controlled by the game.\n" +"However, in some cases it is not well emulated,\n" +"and some garbage may be left on the screen.\n" +"In such cases, this option must be set on.\n" +"[Recommended: on]" +msgstr "" +"Buffer nach jedem Frame entleeren\n" +"Zwingt den Framebuffer, sich nach jedem Frame zu entleeren.\n" +"Normalerweise kontrolliert das Spiel das entleeren des Framebuffers.\n" +"Jedoch wird dies in manchen Fällen nicht gut emuliert,\n" +"und es bleibt Müll auf den Bildschirm zurück.\n" +"In diesen Fällen muss diese Option aktiviert werden.\n" +"[empfohlen: ein]" + +#: Config.cpp:599 +msgid "" +"Enable frame buffer emulation\n" +"If on, plugin will try to detect frame buffer usage and apply appropriate frame buffer emulation.\n" +"[Recommended: on for games which use frame buffer effects]" +msgstr "" +"Framebuffer Emulation aktivieren\n" +"Aktiviert wird das Plugin versuchen, die Benützung des Framebuffers aufzuspüren, und die\n" +"dementsprechende Framebufferemulation anwenden.\n" +"[empfohlen: ein für Spiele, die Framebuffer Effekte verwenden]" + +#: Config.cpp:601 +msgid "" +"Enable hardware frame buffer emulation\n" +"If this option is on, plugin will create auxiliary frame buffers in video memory instead of copying\n" +"frame buffer content into main memory. This allows plugin to run frame buffer effects without slowdown\n" +"and without scaling image down to N64's native resolution. This feature is fully supported by\n" +"Voodoo 4/5 cards and partially by Voodoo3 and Banshee. Modern cards also fully support it.\n" +"[Recommended: on, if supported by your hardware]" +msgstr "" +"Hardware Framebuffer Emulation aktivieren\n" +"Wenn diese Option aktiviert wurde, wird das Plugin Hilfsframebuffer im Video-Speicher erzeugen, statt\n" +"Framebfferinhalt in den Arbeitsspeicher zu kopieren. Dadurch können Framebuffer Effekte ohne\n" +"Geschwindigkeitsverlust und ohne das Bild auf die Originalauflösung des Nintendo64 zu verkleinern\n" +"dargestellt werden. Dieses Feature wird von Voodoo 4/5-Karten vollständig und von Voodoo3/Banshee-Karten\n" +"teilweise unterstützt. Moderne Grafikkarten unterstützen es auch vollständig.\n" +"[empfohlen: ein, wenn von deiner Hardware unterstützt]" + +#: Config.cpp:604 +msgid "" +"Get information about frame buffers\n" +"This is compatibility option. It must be set on for Mupen64 and off for 1964" +msgstr "" +"Informationen über Framebuffer erhalten\n" +"Das ist eine Kompatibilitätsoption. Es muss für Mupen64 aktiviert und für 1964 deaktiviert werden." + +#: Config.cpp:606 +msgid "" +"Read every frame\n" +"In some games plugin can't detect frame buffer usage.\n" +"In such cases you need to enable this option to see frame buffer effects.\n" +"Every drawn frame will be read from video card -> it works very slow.\n" +"[Recommended: mostly off (needed only for a few games)]" +msgstr "" +"jeden Frame lesen\n" +"In manchen Spielen kann das plugin die Benützung des Framebuffers nicht feststellen.\n" +"In diesen Fällen muss diese Option aktiviert werden, um die Framebuffereffekte zu sehen.\n" +"Jeder Frame wird von der Grafikkarte gelesen -> sehr langsam.\n" +"[empfohlen: meist aus (wird nur für wenige Spiele gebraucht)]" + +#: Config.cpp:608 +msgid "" +"Render N64 frame buffer as texture\n" +"When this option is enabled, content of each N64 frame buffer is rendered\n" +"as texture over the frame, rendered by the plugin. This prevents graphics lost,\n" +"but may cause slowdowns and various glitches in some games.\n" +"[Recommended: mostly off]" +msgstr "" +"N64 Framebuffer als Textur darstellen\n" +"Wenn diese Option aktiviert ist, wird der Inhalt jedes N64 Framebuffers als Textur\n" +"über dem Frame durch das Plugin dargestellt. Dadurch kann verhindert werden, dass\n" +"Grafiken verloren gehen, aber es kann das Spiel verlangsamen und verschiedene Fehler\n" +"können etstehen.\n" +"[empfohlen: meist aus]" + +#: Config.cpp:610 +msgid "" +"Detect CPU write to the N64 frame buffer\n" +"This option works as the previous options, but the plugin is trying to detect,\n" +"when game uses CPU writes to N64 frame buffer. The N64 frame buffer is rendered\n" +"only when CPU writes is detected. Use this option for those games, in which you\n" +"see still image or no image at all for some time with no reason.\n" +"[Recommended: mostly off]" +msgstr "" +"CPU-writes auf den Nintendo64 Framebuffer ermitteln\n" +"Diese Option funktioniert wie die vorherigen Optionen, aber das plugin versucht\n" +"CPU-writes auf den Nintendo64 Framebuffer zu ermitteln. Der N64 Framebuffer\n" +"wird nur verabbeitet, wenn CPU-writes festgestellt werden. Verwende diese\n" +"Option für Spiele, in denen Standbilder manchmal grundlos vorkommen, oder\n" +"wenn teilweise kein Bild angezeigt wird\n" +"[empfohlen: meist aus]" + +#: Config.cpp:612 +msgid "" +"Enable depth buffer rendering\n" +"This option is used to fully emulate N64 depth buffer.\n" +"It is required for correct emulation of depth buffer based effects.\n" +"However, it requires fast (>1GHz) CPU to work full speed.\n" +"[Recommended: on for fast PC]" +msgstr "" +"depht buffer-Verarbeitung aktivieren\n" +"Mit dieser Option wird der N64 depth buffer vollständig dargestellt.\n" +"Dies ist erforderlich um Effekte, die auf dem depth buffer basieren\n" +"korrekt darzustellen. Es wird jedoch ein schneller (>1GHz) Prozsssor\n" +"benötigt, um die volle Geschwindigkeit zu erreichen.\n" +"[empfohlen: ein für schnelle PCs]" + +#: Config.cpp:620 +msgid "" +"Filters:\n" +"Apply a filter to either smooth or sharpen textures.\n" +"There are 4 different smoothing filters and 2 different sharpening filters.\n" +"The higher the number, the stronger the effect,\n" +"i.e. \"Smoothing filter 4\" will have a much more noticeable effect than \"Smoothing filter 1\".\n" +"Be aware that performance may have an impact depending on the game and/or the PC.\n" +"[Recommended: your preference]" +msgstr "" +"Filter:\n" +"Verwende Filter, um Texturen zu glätten oder zu schärfen.\n" +"Es gibt 4 verschiedene Glättungs- und 2 verschiedene Schärfungsfilter.\n" +"Je höher die Nummer, desto stärker ist der Effekt,\n" +"d. h. \"weiche Filterung 4\" ist viel stärker spürbar als \"weiche Filterung1\".\n" +"Beachten Sie, dass sich Filter auf die Leistung abhängig von dem Spiel und\n" +"dem PC auswirken können.\n" +"[empfohlen: deine Wahl]" + +#: Config.cpp:624 +msgid "" +"Texture enhancement:\n" +"7 different filters are selectable here, each one with a distinctive look.\n" +"Be aware of possible performance impacts.\n" +"\n" +"IMPORTANT: 'Store' mode - saves textures in cache 'as is'. It can improve performance in games, which load many textures.\n" +"Disable 'Ignore backgrounds' option for better result.\n" +"\n" +"[Recommended: your preference]" +msgstr "" +"Texturverbesserung:\n" +"7 verschiedene Filter können hier ausgewählt werden.\n" +"Die Benützung eines Filters kann sich auf die Leistung auswirken.\n" +"\n" +"WICHTIG: \"Speicher\"-Modus speichert Texturen im Speicher \"as is\".\n" +"Dadurch kann die Leistung in Spielen, die viele Texturen laden, verbessert werden.\n" +"Deaktiviere \"Hintergründe ignorieren\" für bessere Ergebnisse.\n" +"\n" +"[empfohlen: deine Wahl]" + +#: Config.cpp:628 +msgid "" +"Texture cache size:\n" +"Enhanced and filtered textures can be cached to aid performance.\n" +"This setting will adjust how much PC memory will be dedicated for texture cache.\n" +"This helps boost performance if there are subsequent requests for the same texture (usually the case).\n" +"Normally, 128MB should be more than enough but there is a sweet spot for each game.\n" +"Super Mario may not need more than 32megs, but Conker streams a lot of textures,\n" +"so setting 256+ megs can boost performance. Adjust accordingly if you are encountering speed issues.\n" +"'0' disables cache.\n" +"[Recommended: PC and game dependant]" +msgstr "" +"Größe des Textur-cache:\n" +"Verbesserte und gefilterte Texturen können zwischengespeichert werden, um die Leistung zu verbessern.\n" +"Hier kann eingestellt werden, wie viel Speicher für den Textur-cache verwendet werden soll.\n" +"Dadurch wird die Leistung verbessert, wenn die gleiche Textur mehrmals abgerufen wird (das ist meistens der Fall).\n" +"Normalerweise sollten 128MB mehr als genug sein aber es gibt einen Optimalbereich für jedes Spiel.\n" +"Super Mario wird nicht mehr als 32MB brauchen, aber Conker verwendet viele Texturen.\n" +"Hier können 256+ MB die Leistung verbessern. Stelle bei Problemen mit der Geschwindigkeit die richtige Größe ein.\n" +"'0' deaktiviert den Textur-cache.\n" +"[empfohlen: abhängig von PC und Spiel]" + +#: Config.cpp:634 +msgid "" +"Ignore Backgrounds:\n" +"It is used to skip enhancement for long narrow textures, usually used for backgrounds.\n" +"This may save texture memory greatly and increase performance.\n" +"[Recommended: on (off for 'Store' mode)]" +msgstr "" +"Hintergründe ignorieren:\n" +"Lange, schmale Texturen, die normalerweise für Hintergründe verwedet werden, werden nicht verbessert.\n" +"Dadurch kann Texturspeicher gespart, und die Leistung verbessert werden\n" +"[empfohlen: ein (aus für 'Speicher'-Modus)]" + +#: Config.cpp:636 +msgid "" +"Texture compression:\n" +"Textures will be compressed using selected texture compression method.\n" +"The overall compression ratio is about 1/6 for FXT1 and 1/4 for S3TC.\n" +"In addition to saving space on the texture cache,\n" +"the space occupied on the GFX hardware's texture RAM,\n" +"by the enhanced textures, will be greatly reduced.\n" +"This minimizes texture RAM usage,\n" +"decreasing the number of texture swaps to the GFX hardware leading to performance gains.\n" +"However, due to the nature of lossy compression of FXT1 and S3TC, using this option can sometimes lead to quality degradation of small size textures and color banding of gradient colored textures.\n" +"[Recommended: off]" +msgstr "" +"Texturkomprimierung:\n" +"Texturen werden mit der ausgewählten Methode komprimiert.\n" +"Insgesamt liegt das Verhältnis ungefähr bei 1/6 für FXT1 und 1/4 für S3TC.\n" +"Neben den Speichereinsparungen im Textur-cache\n" +"wird auch der Speicherbedarf auf der Textur-RAM der GFX-Hardware\n" +"durch die verbesserten Texturen stark reduziert.\n" +"Es wird die benützte Textur-RAM minimiert\n" +"was zu einer Verringerung von textur-swaps auf der GFX-Hardware führt und dadurch die Leistung steigert.\n" +"Da FXT1 und S3TC nicht verlustfrei sind, kann diese Option bei kleinen Texturen die Qualität verringern und zu Streifen bei Texturen mit großem Farbunterschied führen.\n" +"[empfohlen: aus]" + +#: Config.cpp:640 +msgid "" +"Compress texture cache:\n" +"Memory will be compressed so that more textures can be held in the texture cache.\n" +"The compression ratio varies with each texture,\n" +"but 1/5 of the original size would be a modest approximation.\n" +"They will be decompressed on-the-fly, before being downloaded to the gfx hardware.\n" +"This option will still help save memory space even when using texture compression.\n" +"[Recommended: on]" +msgstr "" +"Textur cache komprimieren:\n" +"Der speicher wird komprimiert, damit mehr Texturen im Textur cache Platz haben.\n" +"Das Verhältnis der Komprimierung variiert bei jeder Textur,\n" +"und liegt bei ca. 1/5 der Originalgröße.\n" +"Texturen werden laufend dekomprimiert, bevor sie von der Grafikkarte geladen werden.\n" +"Diese Option wird helfen, um Speicherplatz zu sparen, selbst wenn Texturkomprimierung verwendet wird.\n" +"[empfohlen: ein]" + +#: Config.cpp:642 +msgid "" +"Hi-res pack format:\n" +"Choose which method is to be used for loading Hi-res texture packs.\n" +"Only Rice's format is available currently.\n" +"Leave on \"None\" if you will not be needing to load hi-res packs.\n" +"[Recommended: Rice's format. Default: \"None\"]" +msgstr "" +"Hi-res FormatWähle welche Methode für das Laden von Hi-res Texturen verwendet werden soll.\n" +"Derzeit ist nur Rices Format verfügbar.\n" +"Wähle \"keine/s\" um keine Hi-res Packete zu laden.\n" +"[empfohlen: Rices Format, Standard: \"keine/s\"]" + +#: Config.cpp:646 +msgid "" +"Tile textures:\n" +"When on, wide texture will be split on several tiles to fit in one 256-width texture.\n" +"This tiled texture takes much less video memory space and thus overall performance will increase.\n" +"However, corresponding polygons must be split too, and this is not polished yet\n" +"- various issues are possible, including black lines and polygons distortions.\n" +"[Recommended: off]" +msgstr "" +"Texturen teilen:\n" +"Große Texturen werden in mehrere Teile zerlegt, um in eine 256 Pixel breite Textur zu passen.\n" +"Geteilte Texturen brauchen weniger Grafikspeicher und deshalb verbessert sich die Leistung.\n" +"Jedoch müssen auch die betreffenden Polygone geteilt werden, was derzeit nicht glatt fungtioniert.\n" +"- verschiedene Probleme wie schwarze Linien und verzerrte Polygone sind möglich.\n" +"[empfohlen: aus]" + +#: Config.cpp:648 +msgid "" +"Force 16bpp textures:\n" +"The color of the textures will be reduced to 16bpp.\n" +"This is another space saver and performance enhancer.\n" +"This halves the space used on the texture cache and the GFX hardware's texture RAM.\n" +"Color reduction is done so that the original quality is preserved as much as possible.\n" +"Depending on the texture, this usually is hardly noticeable.\n" +"Sometimes though, it can be: skies are a good example.\n" +"[Recommended: off]" +msgstr "" +"16bpp-Texturen erzwingen:\n" +"Reduziert die Farbe der Texturen auf 16bpp.\n" +"Es wird Speicher gespart und die Leistung verbessert.\n" +"Der verwendete Spercher im Textur cache und im Textur-RAM der GFX-Hardware.\n" +"Bei der Farbreduktion wird darauf geachtet, dass Qualität des Originals so gut wie möglich erhalten bleibt.\n" +"Das ist, von der Textur abhängig, normalerweise kaum bemerkbar.\n" +"Manchmal ist es sichtbar: Himmel sind ein gutes Beispiel.\n" +"[empfohlen: aus]" + +#: Config.cpp:650 +msgid "" +"Texture dumping mode:\n" +"In this mode, you have that ability to dump textures on screen to the appropriate folder.\n" +"You can also reload textures while the game is running to see how they look instantly - big time saver!\n" +"\n" +"Hotkeys: \"R\" reloads hires textures from the texture pack - \"D\" toggles texture dumps on/off." +msgstr "" +"Texturbearbeitungsmodus:\n" +"In diesem Modus gibt es die Möglichkeit Texturen, die angezeigt werden, in den entsprechenden Ordner zu speichern.\n" +"Texturen können auch neu geladen werden während das Spiel läuft, um neue Texturen auszuprobieren - spart viel Zeit!\n" +"\n" +"Tastenkombinationen: \"R\" Texturen aus dem Packet neu laden - \"D\" schaltet Textur-dumps ein/aus." + +#: Config.cpp:652 +msgid "" +"Alternative CRC calculation:\n" +"This option enables emulation of a palette CRC calculation bug in RiceVideo.\n" +"If some textures are not loaded, try to set this option on/off.\n" +"[Recommended: texture pack dependant, mostly on]" +msgstr "" +"Alternative CRC Kalkulation:\n" +"Diese Option ahmt einen CRC Kalkulationsbugs aus RiceVideo nach.\n" +"Wenn einige Texturen nicht geladen werden, versuche diese Option ein- oder auszuschelten.\n" +"[empfohlen: abhängig vom Texturpaket, meist ein]" + +#: Config.cpp:657 +msgid "" +"Compress texture cache:\n" +"When game started, plugin loads all its hi-resolution textures into PC memory.\n" +"Since hi-resolution textures are usually large, the whole pack can take hundreds megabytes of memory.\n" +"Cache compression allows save memory space greatly.\n" +"Textures will be decompressed on-the-fly, before being downloaded to the gfx hardware.\n" +"This option will still help save memory space even when using texture compression.\n" +"[Recommended: on]" +msgstr "" +"Textur-cache komprimieren:\n" +"Wenn ein Spiel startet, werden alle Texturen in den Arbeitsspeicher geladen.\n" +"Da Texturpakete meist viel Speicher benötigen, kann das gesamte Paket mehrere hundert megabyte benötigen.\n" +"Durch Komprimierung kann viel Speicherplatz gespart werden.\n" +"Texturen werden laufend dekomprimiert, bevor sie von der Grafikkarte geladen werden.\n" +"Diese Option wird helfen, um Speicherplatz zu sparen, selbst wenn Texturkomprimierung verwendet wird.\n" +"[empfohlen: ein]" + +#: Config.cpp:659 +msgid "" +"Use Alpha channel fully:\n" +"When this option is off, 16bit rgba textures will be loaded using RiceVideo style\n" +"- with 1bit for alpha channel.\n" +"When it is on, GlideHQ will check, how alpha channel is used by the hires texture,\n" +"and select most appropriate format for it.\n" +"This gives texture designers freedom to play with alpha, as they need,\n" +"regardless of format of original N64 texture.\n" +"For older and badly designed texture packs it can cause unwanted black borders.\n" +"[Recommended: texture pack dependant]" +msgstr "" +"Alphakanal vollständig verwenden:\n" +"Wenn diese Option deaktiviert ist, werden 16bit rgba Texturen wie in RiceVideo geladen\n" +"-mit 1bit für den Alphakanal.\n" +"Wenn diese Option aktiviert ist, wird GlideHQ überprüfen, wie der Alphakanal verwendet wird\n" +"und wird das passende Format auswählen.\n" +"Dadurch können Texturdesigner den Alphakanal verwenden, wie sie ihn benötigen,\n" +"unabhängig vom Format der Originaltextur des N64.\n" +"Bei älteren und schlecht designten Texturpaketen können schwarze Ränder entstehen.\n" +"[empfohlen: abhängig vom Texturpaket]" + +#: Config.cpp:662 +msgid "" +"Save texture cache to HD:\n" +"\n" +"For enhanced textures cache:\n" +"This will save all previously loaded and enhanced textures to HD.\n" +"So upon next game launch, all the textures will be instantly loaded, resulting in smoother performance.\n" +"\n" +"For high-resolution textures cache:\n" +"After creation, loading hi-res texture will take only a few seconds upon game launch,\n" +"as opposed to the 5 -60 seconds a pack can take to load without this cache file.\n" +"The only downside here is upon any changes to the pack, the cache file will need to be manually deleted.\n" +"\n" +"Saved cache files go into a folder called \"Cache\" within the Plugins folder.\n" +"\n" +"[Highly Recommended: on]" +msgstr "" +"Textur-cache auf der Festplatte speichern:\n" +"\n" +"Für verbesserten Textur-cache:\n" +"Alle zuvor geladenen und verbesserten Texturen werden auf der Festplatte gespeichert.\n" +"Wenn das Spiel das nächste mal gestartet wird, werden alle texturen sofort geladen und die Leistung wird dadurch verbessert.\n" +"\n" +"Für Texturpakete:\n" +"Nach der Erstellung werden Texturpakete in wenigen Sekunden nach dem Spielstart geladen.\n" +"Ohne diese Option kann es 5-60 Sekunden dauern, bis die Texturen geladen sind.\n" +"Es gibt einen Nachteil. Die cache-Datei muss manuell gelöscht werden, wenn das Texturpaket verändert wird.\n" +"\n" +"Cache-Dateien werden im Ordner \"Cache\" gespeichert, der sich im Plugin-Ordner befindet.\n" +"\n" +"[dringend empfohlen: ein]" + +#: Config.cpp:685 +msgid "Debug" +msgstr "" + +#: Config.cpp:686 +msgid "" +"Autodetect Microcode\n" +"If this option is checked, the microcode of the game\n" +"will be detected automatically from the INI, and\n" +"therefore it will not need to be set in this\n" +"configuration dialog.\n" +"[Recommended: on]" +msgstr "" + +#: Config.cpp:688 +msgid "" +"Force Microcode\n" +"This option ONLY has an effect if Autodetect Microcode\n" +"is unchecked, the crc from the game could not be\n" +"found in the INI, OR after the game has already started\n" +"running. In any of those three cases, this will\n" +"select the microcode to use\n" +"[Recommended: any, turn on Autodetect Microcode]" +msgstr "" + +#: Config.cpp:692 +msgid "" +"Wireframe\n" +"This option, when checked, makes it so that the plugin will draw only the\n" +"outlines of objects. The colors specified in the combo box to the right\n" +"determines the color that the wireframes show up as.\n" +"[Recommended: off]" +msgstr "" + +#: Config.cpp:694 +msgid "" +"Wireframe Colors\n" +"This selects the colors to use for the wireframes (if wireframe mode is enabled).\n" +"There are 3 modes:\n" +"* Original colors - draw exactly as it would normally, textures and all, only in wireframes.\n" +"* Vertex colors - use the colors specified in the vertices to draw the wireframes with.\n" +"* Red only - use a constant red color to draw the wireframes.\n" +"[Recommended: Vertex colors]" +msgstr "" + +#: Config.cpp:696 +msgid "" +"Log to RDP.txt\n" +"RECOMMENDED FOR DEBUGGING ONLY - this option, when checked, will log EVERY SINGLE\n" +"COMMAND the plugin processes to a file called RDP.txt in the current directory.\n" +"This is incredibly slow, so I recommend keeping it disabled.\n" +"[Recommended: off]" +msgstr "" + +#: Config.cpp:698 +msgid "" +"Unknown combiners as red\n" +"Objects that use an unimplemented combine mode will show up as red instead of\n" +"assuming texture with full alpha. Disable this option to remove the red stuff\n" +"and at least have a guess at the correct combine mode.\n" +"[Recommended: off]" +msgstr "" + +#: Config.cpp:700 +msgid "" +"Log clear every frame\n" +"RECOMMENDED FOR DEBUGGING ONLY - this option has no effect unless 'Log to RDP.txt'\n" +"is checked. This will make it so that the log, RDP.txt, will be cleared at the\n" +"beginning of every frame.\n" +"[Recommended: off]" +msgstr "" + +#: Config.cpp:702 +msgid "" +"Log unknown combiners\n" +"RECOMMENDED FOR DEBUGGING ONLY - when checked, this option will cause every\n" +"unimplemented combiner drawn to be logged to a file called Unimp.txt in the\n" +"current directory. This becomes slow when there are unimplemented combiners\n" +"on the screen, so I recommend keeping it disabled.\n" +"[Recommended: off]" +msgstr "" + +#: Config.cpp:704 +msgid "" +"Run and log in window\n" +"RECOMMENDED FOR DEBUGGING ONLY - this option will make it so that the plugin will\n" +"still process dlists in windowed mode. This allows for logging to occur while not\n" +"in fullscreen, possibly allowing you to debug a crash.\n" +"[Recommended: off]" +msgstr "" + +#: Config.cpp:706 +msgid "" +"Clear unknown combiner log every frame\n" +"RECOMMENDED FOR DEBUGGING ONLY - this option works much like 'Log clear every frame'\n" +"except it clears the combiner log (Unimp.txt) instead of RDP.txt at the\n" +"beginning of each frame. Again, this option has no effect if 'combiner logging' is disabled.\n" +"[Recommended: off]" +msgstr "" + +#: Config.cpp:709 +msgid "" +"Bilinear filter texture cache\n" +"RECOMMENDED FOR DEBUGGING ONLY - when checked, this option will make the graphical\n" +"debugger texture cache use bilinear filtering as opposed to point-sampled filtering,\n" +"which it will use otherwise. See 'Filtering mode' for descriptions of bilinear and\n" +"point-sampled filtering.\n" +"[Recommended: off]" +msgstr "" + +#: Config.cpp:1104 +msgid "Glide64 settings" +msgstr "Glide64 Einstellungen" + +#: Config.cpp:1293 +msgid "About Glide64" +msgstr "Ãœber Glide64" + +#: Config.cpp:1326 +msgid "authors:" +msgstr "Urheber:" + +#: Config.cpp:1330 +msgid "" +"Dave2001. Original author and former main developer.\n" +"He founded Glide64 project on Dec. 29th, 2001.\n" +"Left the project at fall of 2002.\n" +msgstr "" +"Dave2001. Originalautor und ehemaliger Hauptentwickler.\n" +"Er gründete das Glide64-Projekt am 29. Dez. 2001.\n" +"Er verließ das Projekt im Herbst 2002.\n" + +#: Config.cpp:1336 +msgid "" +"Gugaman. Developer. Joined the project at winter 2002\n" +" and left it at fall 2002." +msgstr "" +"Gugaman. Entwickler. Trat dem Projekt Winter 2002 bei\n" +"und verließ es Herbst 2002." + +#: Config.cpp:1342 +msgid "" +"Sergey 'Gonetz' Lipski. Joined the project at winter 2002.\n" +"Main developer since fall of 2002." +msgstr "" +"Sergey 'Gonetz' Lipski. Trat dem Projekt Winter 2002 bei.\n" +"Hauptentwickler seit Herbst 2002." + +#: Config.cpp:1347 +msgid "Hiroshi 'KoolSmoky' Morii, Joined the project in 2007. " +msgstr "Hiroshi 'KoolSmoky' Morii, trat dem Projekt 2007 bei." + +#: Config.cpp:1350 +msgid "Glitch64 (the wrapper) authors:" +msgstr "Glitch64 (der Wrapper) Autoren:" + +#: Config.cpp:1374 +msgid "GlideHQ author:" +msgstr "GlideHQ Autor:" + +#: Config.cpp:1381 +msgid "beta tester:" +msgstr "Betatester:" + +#: Config.cpp:1388 +msgid "" +"special thanks to:\n" +" Orkin, Rice, Daniel Borca, Legend.\n" +"Thanks to EmuXHaven for hosting my site:\n" +"http://glide64.emuxhaven.net\n" +msgstr "" +"Besonderen Dank an:\n" +"Orkin, Rice, Daniel Borca, Legend.\n" +"EmuXHaven für das hosten meiner Seite:\n" +"http://glide64.emuxhaven.net\n" + diff --git a/Source/Glide64/Internalization/Glide64_en.pot b/Source/Glide64/Internalization/Glide64_en.pot new file mode 100644 index 000000000..e2f8b5c55 --- /dev/null +++ b/Source/Glide64/Internalization/Glide64_en.pot @@ -0,0 +1,1118 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2011-12-19 17:29+0700\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=CHARSET\n" +"Content-Transfer-Encoding: 8bit\n" + +#: Config.cpp:64 +msgid "Rendering" +msgstr "" + +#: Config.cpp:65 +msgid "Other" +msgstr "" + +#: Config.cpp:66 +msgid "Speed" +msgstr "" + +#: Config.cpp:67 +msgid "Time" +msgstr "" + +#: Config.cpp:68 +msgid "On screen display" +msgstr "" + +#: Config.cpp:69 +msgid "OpenGL settings" +msgstr "" + +#: Config.cpp:70 Config.cpp:137 +msgid "Frame buffer emulation" +msgstr "" + +#: Config.cpp:71 +msgid "" +"Windowed or\n" +"3dfx card resolution:" +msgstr "" + +#: Config.cpp:99 +msgid "Vertical sync" +msgstr "" + +#: Config.cpp:100 +msgid "Show advanced emulation options" +msgstr "" + +#: Config.cpp:101 +msgid "Show texture enhancement options" +msgstr "" + +#: Config.cpp:102 +msgid "Screenshot format:" +msgstr "" + +#: Config.cpp:105 +msgid "Language: " +msgstr "" + +#: Config.cpp:106 +msgid "LANGUAGE_NAME" +msgstr "" + +#: Config.cpp:112 +msgid "FPS counter" +msgstr "" + +#: Config.cpp:113 +msgid "VI/s counter" +msgstr "" + +#: Config.cpp:114 +#, c-format +msgid "% speed" +msgstr "" + +#: Config.cpp:115 +msgid "Clock enabled" +msgstr "" + +#: Config.cpp:116 +msgid "Clock is 24-hour" +msgstr "" + +#: Config.cpp:117 +msgid "Transparent text background" +msgstr "" + +#: Config.cpp:118 +msgid "" +"Full screen\n" +"resolution:" +msgstr "" + +#: Config.cpp:121 +msgid "Anisotropic filtering" +msgstr "" + +#: Config.cpp:122 +msgid "Autodetect " +msgstr "" + +#: Config.cpp:123 +msgid "VRAM size" +msgstr "" + +#: Config.cpp:125 +msgid "Mb" +msgstr "" + +#: Config.cpp:126 +msgid "Use frame buffer objects" +msgstr "" + +#: Config.cpp:133 +msgid "Current game emulation settings. Change with care!" +msgstr "" + +#: Config.cpp:135 +msgid "Default emulation settings. Not recommended to change!" +msgstr "" + +#: Config.cpp:136 +msgid "General options" +msgstr "" + +#: Config.cpp:138 +msgid "Depth buffer emulation" +msgstr "" + +#: Config.cpp:139 +msgid "Filtering mode:" +msgstr "" + +#: Config.cpp:141 +msgid "Automatic" +msgstr "" + +#: Config.cpp:142 +msgid "Force Bilinear" +msgstr "" + +#: Config.cpp:143 +msgid "Force Point-sampled" +msgstr "" + +#: Config.cpp:146 +msgid "Buffer swapping method:" +msgstr "" + +#: Config.cpp:148 +msgid "Old" +msgstr "" + +#: Config.cpp:149 +msgid "New" +msgstr "" + +#: Config.cpp:150 +msgid "Hybrid" +msgstr "" + +#: Config.cpp:153 +msgid "LOD calculation:" +msgstr "" + +#: Config.cpp:155 +msgid "off" +msgstr "" + +#: Config.cpp:156 +msgid "fast" +msgstr "" + +#: Config.cpp:157 +msgid "precise" +msgstr "" + +#: Config.cpp:160 +msgid "Aspect ratio:" +msgstr "" + +#: Config.cpp:162 +msgid "4:3 (default)" +msgstr "" + +#: Config.cpp:163 +msgid "Force 16:9" +msgstr "" + +#: Config.cpp:164 +msgid "Stretch" +msgstr "" + +#: Config.cpp:165 +msgid "Original" +msgstr "" + +#: Config.cpp:168 +msgid "Fog" +msgstr "" + +#: Config.cpp:169 +msgid "Buffer clear on every frame" +msgstr "" + +#: Config.cpp:170 +msgid "Enable frame buffer emulation" +msgstr "" + +#: Config.cpp:171 +msgid "Hardware frame buffer emulation" +msgstr "" + +#: Config.cpp:172 +msgid "Get frame buffer info" +msgstr "" + +#: Config.cpp:173 +msgid "Read every frame (slow!)" +msgstr "" + +#: Config.cpp:174 +msgid "Render N64 frame buffer as texture" +msgstr "" + +#: Config.cpp:175 +msgid "Detect CPU write to the N64 frame buffer" +msgstr "" + +#: Config.cpp:176 +msgid "Software depth buffer rendering" +msgstr "" + +#: Config.cpp:200 Config.cpp:619 +msgid "Texture enhancement" +msgstr "" + +#: Config.cpp:201 +msgid "Hi-resolution textures" +msgstr "" + +#: Config.cpp:202 +msgid "Common" +msgstr "" + +#: Config.cpp:203 +msgid "Presets" +msgstr "" + +#: Config.cpp:204 Config.cpp:205 +msgid "Performance tweaks" +msgstr "" + +#: Config.cpp:206 +msgid "Filter" +msgstr "" + +#: Config.cpp:208 Config.cpp:219 Config.cpp:238 +msgid "None" +msgstr "" + +#: Config.cpp:209 +msgid "Smooth filtering 1" +msgstr "" + +#: Config.cpp:210 +msgid "Smooth filtering 2" +msgstr "" + +#: Config.cpp:211 +msgid "Smooth filtering 3" +msgstr "" + +#: Config.cpp:212 +msgid "Smooth filtering 4" +msgstr "" + +#: Config.cpp:213 +msgid "Sharp filtering 1" +msgstr "" + +#: Config.cpp:214 +msgid "Sharp filtering 2" +msgstr "" + +#: Config.cpp:217 +msgid "Enhancement" +msgstr "" + +#: Config.cpp:220 +msgid "Store" +msgstr "" + +#: Config.cpp:230 +msgid "Texture cache" +msgstr "" + +#: Config.cpp:232 +msgid "Mbytes" +msgstr "" + +#: Config.cpp:233 +msgid "Ignore Backgrounds" +msgstr "" + +#: Config.cpp:234 Config.cpp:245 +msgid "Apply texture compression" +msgstr "" + +#: Config.cpp:235 Config.cpp:246 +msgid "Compress texture cache" +msgstr "" + +#: Config.cpp:236 +msgid "Format" +msgstr "" + +#: Config.cpp:239 +msgid "Rice format" +msgstr "" + +#: Config.cpp:242 +msgid "Tile textures" +msgstr "" + +#: Config.cpp:243 +msgid "Force 16bpp textures" +msgstr "" + +#: Config.cpp:244 +msgid "Alternative CRC calculation" +msgstr "" + +#: Config.cpp:247 +msgid "Use alpha channel fully" +msgstr "" + +#: Config.cpp:248 +msgid "Texture dumping/editing mode" +msgstr "" + +#: Config.cpp:249 +msgid "Texture compression method" +msgstr "" + +#: Config.cpp:255 +msgid "Save texture cache to hard disk" +msgstr "" + +#: Config.cpp:256 +msgid "Best performance" +msgstr "" + +#: Config.cpp:257 +msgid "Best texture quality" +msgstr "" + +#: Config.cpp:263 +msgid "Developers settings" +msgstr "" + +#: Config.cpp:264 +msgid "Debug/Misc" +msgstr "" + +#: Config.cpp:265 +msgid "Autodetect Microcode" +msgstr "" + +#: Config.cpp:266 +msgid "Force Microcode:" +msgstr "" + +#: Config.cpp:279 +msgid "Wireframe using:" +msgstr "" + +#: Config.cpp:281 +msgid "Original colors" +msgstr "" + +#: Config.cpp:282 +msgid "Vertex colors" +msgstr "" + +#: Config.cpp:283 +msgid "Red only" +msgstr "" + +#: Config.cpp:286 +msgid "Log to rdp.txt (SLOW)" +msgstr "" + +#: Config.cpp:287 +msgid "Unknown combiners as red" +msgstr "" + +#: Config.cpp:288 +msgid "Log clear every frame" +msgstr "" + +#: Config.cpp:289 +msgid "Combiner logging" +msgstr "" + +#: Config.cpp:290 +msgid "Run (+log) in window" +msgstr "" + +#: Config.cpp:291 +msgid "Cmb. clear every frame" +msgstr "" + +#: Config.cpp:292 +msgid "Error log (rdp_e.txt)" +msgstr "" + +#: Config.cpp:293 +msgid "Bilinear filter texture cache" +msgstr "" + +#: Config.cpp:325 Config.cpp:546 +msgid " auto" +msgstr "" + +#: Config.cpp:382 +msgid "Please choose language:" +msgstr "" + +#: Config.cpp:383 +msgid "Language" +msgstr "" + +#: Config.cpp:390 +msgid "Press OK to change to " +msgstr "" + +#: Config.cpp:486 +msgid "Basic settings" +msgstr "" + +#: Config.cpp:487 +msgid "" +"Resolution\n" +"This option selects the fullscreen resolution for 3dfx cards and windowed " +"resolution for other cards\n" +"(note again that for 3dfx cards the plugin must be in fullscreen mode to see " +"anything).\n" +"[Recommended: 640x480, 800x600, 1024x768]" +msgstr "" + +#: Config.cpp:491 +msgid "" +"Vertical sync\n" +"This option will enable the vertical sync, which will prevent tearing.\n" +"Note: this option will ONLY have effect if vsync is set to \"Software " +"Controlled\".\n" +msgstr "" + +#: Config.cpp:493 +msgid "Select a format, in which screen shots will be saved" +msgstr "" + +#: Config.cpp:500 +msgid "" +"Language select:\n" +"Press the button to invoke language selection dialog.\n" +"Selected language will be activated after restart of the configuration " +"dialog." +msgstr "" + +#: Config.cpp:501 +msgid "" +"FPS counter\n" +"When this option is checked, a FPS (frames per second) counter will be " +"shown\n" +"in the lower left corner of the screen.\n" +"[Recommended: your preference]" +msgstr "" + +#: Config.cpp:503 +msgid "" +"VI/s counter\n" +"When this option is checked, a VI/s (vertical interrupts per second) " +"counter\n" +"will be shown in the lower left corner of the screen. This is like the FPS\n" +"counter but will be consistent at 60 VI/s for full speed on NTSC (U) games " +"and\n" +"50 VI/s for full speed on PAL (E) ones.\n" +"[Recommended: your preference]" +msgstr "" + +#: Config.cpp:505 +#, c-format +msgid "" +"% speed\n" +"This displays a percentage of the actual N64 speed in the lower\n" +"left corner of the screen.\n" +"[Recommended: your preference]" +msgstr "" + +#: Config.cpp:507 +msgid "" +"Clock enabled\n" +"This option will put a clock in the lower right corner of the screen, " +"showing the current time.\n" +"[Recommended: your preference]" +msgstr "" + +#: Config.cpp:510 +msgid "" +"Display hours as 24-hour clock.\n" +"[Recommended: your preference]" +msgstr "" + +#: Config.cpp:511 +msgid "" +"Transparent text background\n" +"If this is checked, all on-screen messages will have a transparent " +"background. Otherwise, it will have a solid black background.\n" +"[Recommended: your preference]" +msgstr "" + +#: Config.cpp:514 +msgid "" +"Enable \"Emulation settings\" panel. For experienced users only!\n" +"It shows default emulation settings when game is not loaded, or current game " +"settings otherwise." +msgstr "" + +#: Config.cpp:516 +msgid "" +"Enable \"Texture enhancement\" panel.\n" +"It shows various enhancement options for original textures as well as " +"options for hi-resolution textures." +msgstr "" + +#: Config.cpp:517 +msgid "" +"Full screen resolution:\n" +"This sets the full screen resolution for non-3dfx video cards.\n" +"All the resolutions that your video card/monitor support should be " +"displayed.\n" +"[Recommended: native (max) resolution of your monitor - unless performance " +"becomes an issue]" +msgstr "" + +#: Config.cpp:520 +msgid "" +"Anisotropic filtering:\n" +"This filter sharpens and brings out the details of textures that recede into " +"the distance.\n" +"When activated, it will use the max anisotropy your video card supports.\n" +"However, this will override native way of texture filtering and may cause " +"visual artifacts in some games.\n" +"[Recommended: your preference, game dependant]" +msgstr "" + +#: Config.cpp:521 +msgid "" +"Autodetect VRAM Size:\n" +"Since OpenGL cannot do this reliably at the moment, the option to set this " +"manually is available.\n" +"If checked, plugin will try to autodetect VRAM size.\n" +"But if this appears wrong, please uncheck and set it to correct value.\n" +"[Recommended: on]" +msgstr "" + +#: Config.cpp:523 +msgid "" +"Use frame buffer objects:\n" +"Changes the way FB effects are rendered - with or without usage of the " +"OpenGL Frame Buffer Objects (FBO) extension.\n" +"The choice depends on game and your video card. FBO off is good for NVIDIA " +"cards, while for ATI cards, it's usually best that FBOs are turned on.\n" +"Also, some FB effects works only with one of the methods, no matter, which " +"card you have.\n" +"On the whole, with FBO off, compatibility/ accuracy is a bit better (which " +"is the case for Resident Evil 2).\n" +"However, with FBO on with some systems, it can actually be a bit faster in " +"cases.\n" +"[Recommended: video card and game dependant]" +msgstr "" + +#: Config.cpp:578 +msgid "Emulation settings" +msgstr "" + +#: Config.cpp:579 +msgid "" +"Filtering mode\n" +"There are three filtering modes possible:\n" +"* Automatic filtering - filter exactly how the N64 specifies.\n" +"* Point-sampled filtering - causes texels to appear square and sharp.\n" +"* Bilinear filtering - interpolates the texture to make it appear more " +"smooth.\n" +"[Recommended: Automatic]" +msgstr "" + +#: Config.cpp:583 +msgid "" +"Buffer swapping method\n" +"There are 3 buffer swapping methods:\n" +"* old - swap buffers when vertical interrupt has occurred.\n" +"* new - swap buffers when set of conditions is satisfied. Prevents flicker " +"on some games.\n" +"* hybrid - mix of first two methods.\n" +"Can prevent even more flickering then previous method, but also can cause " +"artefacts.\n" +"If you have flickering problems in a game (or graphics that don't show),\n" +"try to change swapping method.\n" +"[Recommended: new (hybrid for Paper Mario)]" +msgstr "" + +#: Config.cpp:587 +msgid "" +"Per-pixel level-of-detail calculation\n" +"N64 uses special mechanism for mip-mapping, which nearly impossible to " +"reproduce\n" +"correctly on PC hardware. This option enables approximate emulation of this " +"feature.\n" +"For example, it is required for the Peach/Bowser portrait's transition in " +"Super Mario 64.\n" +"There are 3 modes:\n" +"* off - LOD is not calculated\n" +"* fast - fast imprecise LOD calculation.\n" +"* precise - most precise LOD calculation possible, but more slow.\n" +"[Recommended: your preference]" +msgstr "" + +#: Config.cpp:592 +msgid "" +"Aspect ratio of the output.\n" +"Most N64 games use 4:3 aspect ratio, but some support widescreen too.\n" +"You may select appropriate aspect here and set widescreen mode in game " +"settings.\n" +"In \"Stretch\" mode the output will be stretched to the entire screen,\n" +"other modes may add black borders if necessary" +msgstr "" + +#: Config.cpp:595 +msgid "" +"Fog enabled\n" +"Sets fog emulation on//off.\n" +"[Recommended: on]" +msgstr "" + +#: Config.cpp:597 +msgid "" +"Buffer clear on every frame\n" +"Forces the frame buffer to be cleared every frame drawn.\n" +"Usually frame buffer clear is controlled by the game.\n" +"However, in some cases it is not well emulated,\n" +"and some garbage may be left on the screen.\n" +"In such cases, this option must be set on.\n" +"[Recommended: on]" +msgstr "" + +#: Config.cpp:599 +msgid "" +"Enable frame buffer emulation\n" +"If on, plugin will try to detect frame buffer usage and apply appropriate " +"frame buffer emulation.\n" +"[Recommended: on for games which use frame buffer effects]" +msgstr "" + +#: Config.cpp:601 +msgid "" +"Enable hardware frame buffer emulation\n" +"If this option is on, plugin will create auxiliary frame buffers in video " +"memory instead of copying\n" +"frame buffer content into main memory. This allows plugin to run frame " +"buffer effects without slowdown\n" +"and without scaling image down to N64's native resolution. This feature is " +"fully supported by\n" +"Voodoo 4/5 cards and partially by Voodoo3 and Banshee. Modern cards also " +"fully support it.\n" +"[Recommended: on, if supported by your hardware]" +msgstr "" + +#: Config.cpp:604 +msgid "" +"Get information about frame buffers\n" +"This is compatibility option. It must be set on for Mupen64 and off for 1964" +msgstr "" + +#: Config.cpp:606 +msgid "" +"Read every frame\n" +"In some games plugin can't detect frame buffer usage.\n" +"In such cases you need to enable this option to see frame buffer effects.\n" +"Every drawn frame will be read from video card -> it works very slow.\n" +"[Recommended: mostly off (needed only for a few games)]" +msgstr "" + +#: Config.cpp:608 +msgid "" +"Render N64 frame buffer as texture\n" +"When this option is enabled, content of each N64 frame buffer is rendered\n" +"as texture over the frame, rendered by the plugin. This prevents graphics " +"lost,\n" +"but may cause slowdowns and various glitches in some games.\n" +"[Recommended: mostly off]" +msgstr "" + +#: Config.cpp:610 +msgid "" +"Detect CPU write to the N64 frame buffer\n" +"This option works as the previous options, but the plugin is trying to " +"detect,\n" +"when game uses CPU writes to N64 frame buffer. The N64 frame buffer is " +"rendered\n" +"only when CPU writes is detected. Use this option for those games, in which " +"you\n" +"see still image or no image at all for some time with no reason.\n" +"[Recommended: mostly off]" +msgstr "" + +#: Config.cpp:612 +msgid "" +"Enable depth buffer rendering\n" +"This option is used to fully emulate N64 depth buffer.\n" +"It is required for correct emulation of depth buffer based effects.\n" +"However, it requires fast (>1GHz) CPU to work full speed.\n" +"[Recommended: on for fast PC]" +msgstr "" + +#: Config.cpp:620 +msgid "" +"Filters:\n" +"Apply a filter to either smooth or sharpen textures.\n" +"There are 4 different smoothing filters and 2 different sharpening filters.\n" +"The higher the number, the stronger the effect,\n" +"i.e. \"Smoothing filter 4\" will have a much more noticeable effect than " +"\"Smoothing filter 1\".\n" +"Be aware that performance may have an impact depending on the game and/or " +"the PC.\n" +"[Recommended: your preference]" +msgstr "" + +#: Config.cpp:624 +msgid "" +"Texture enhancement:\n" +"7 different filters are selectable here, each one with a distinctive look.\n" +"Be aware of possible performance impacts.\n" +"\n" +"IMPORTANT: 'Store' mode - saves textures in cache 'as is'. It can improve " +"performance in games, which load many textures.\n" +"Disable 'Ignore backgrounds' option for better result.\n" +"\n" +"[Recommended: your preference]" +msgstr "" + +#: Config.cpp:628 +msgid "" +"Texture cache size:\n" +"Enhanced and filtered textures can be cached to aid performance.\n" +"This setting will adjust how much PC memory will be dedicated for texture " +"cache.\n" +"This helps boost performance if there are subsequent requests for the same " +"texture (usually the case).\n" +"Normally, 128MB should be more than enough but there is a sweet spot for " +"each game.\n" +"Super Mario may not need more than 32megs, but Conker streams a lot of " +"textures,\n" +"so setting 256+ megs can boost performance. Adjust accordingly if you are " +"encountering speed issues.\n" +"'0' disables cache.\n" +"[Recommended: PC and game dependant]" +msgstr "" + +#: Config.cpp:634 +msgid "" +"Ignore Backgrounds:\n" +"It is used to skip enhancement for long narrow textures, usually used for " +"backgrounds.\n" +"This may save texture memory greatly and increase performance.\n" +"[Recommended: on (off for 'Store' mode)]" +msgstr "" + +#: Config.cpp:636 +msgid "" +"Texture compression:\n" +"Textures will be compressed using selected texture compression method.\n" +"The overall compression ratio is about 1/6 for FXT1 and 1/4 for S3TC.\n" +"In addition to saving space on the texture cache,\n" +"the space occupied on the GFX hardware's texture RAM,\n" +"by the enhanced textures, will be greatly reduced.\n" +"This minimizes texture RAM usage,\n" +"decreasing the number of texture swaps to the GFX hardware leading to " +"performance gains.\n" +"However, due to the nature of lossy compression of FXT1 and S3TC, using this " +"option can sometimes lead to quality degradation of small size textures and " +"color banding of gradient colored textures.\n" +"[Recommended: off]" +msgstr "" + +#: Config.cpp:640 +msgid "" +"Compress texture cache:\n" +"Memory will be compressed so that more textures can be held in the texture " +"cache.\n" +"The compression ratio varies with each texture,\n" +"but 1/5 of the original size would be a modest approximation.\n" +"They will be decompressed on-the-fly, before being downloaded to the gfx " +"hardware.\n" +"This option will still help save memory space even when using texture " +"compression.\n" +"[Recommended: on]" +msgstr "" + +#: Config.cpp:642 +msgid "" +"Hi-res pack format:\n" +"Choose which method is to be used for loading Hi-res texture packs.\n" +"Only Rice's format is available currently.\n" +"Leave on \"None\" if you will not be needing to load hi-res packs.\n" +"[Recommended: Rice's format. Default: \"None\"]" +msgstr "" + +#: Config.cpp:646 +msgid "" +"Tile textures:\n" +"When on, wide texture will be split on several tiles to fit in one 256-width " +"texture.\n" +"This tiled texture takes much less video memory space and thus overall " +"performance will increase.\n" +"However, corresponding polygons must be split too, and this is not polished " +"yet\n" +"- various issues are possible, including black lines and polygons " +"distortions.\n" +"[Recommended: off]" +msgstr "" + +#: Config.cpp:648 +msgid "" +"Force 16bpp textures:\n" +"The color of the textures will be reduced to 16bpp.\n" +"This is another space saver and performance enhancer.\n" +"This halves the space used on the texture cache and the GFX hardware's " +"texture RAM.\n" +"Color reduction is done so that the original quality is preserved as much as " +"possible.\n" +"Depending on the texture, this usually is hardly noticeable.\n" +"Sometimes though, it can be: skies are a good example.\n" +"[Recommended: off]" +msgstr "" + +#: Config.cpp:650 +msgid "" +"Texture dumping mode:\n" +"In this mode, you have that ability to dump textures on screen to the " +"appropriate folder.\n" +"You can also reload textures while the game is running to see how they look " +"instantly - big time saver!\n" +"\n" +"Hotkeys: \"R\" reloads hires textures from the texture pack - \"D\" toggles " +"texture dumps on/off." +msgstr "" + +#: Config.cpp:652 +msgid "" +"Alternative CRC calculation:\n" +"This option enables emulation of a palette CRC calculation bug in " +"RiceVideo.\n" +"If some textures are not loaded, try to set this option on/off.\n" +"[Recommended: texture pack dependant, mostly on]" +msgstr "" + +#: Config.cpp:657 +msgid "" +"Compress texture cache:\n" +"When game started, plugin loads all its hi-resolution textures into PC " +"memory.\n" +"Since hi-resolution textures are usually large, the whole pack can take " +"hundreds megabytes of memory.\n" +"Cache compression allows save memory space greatly.\n" +"Textures will be decompressed on-the-fly, before being downloaded to the gfx " +"hardware.\n" +"This option will still help save memory space even when using texture " +"compression.\n" +"[Recommended: on]" +msgstr "" + +#: Config.cpp:659 +msgid "" +"Use Alpha channel fully:\n" +"When this option is off, 16bit rgba textures will be loaded using RiceVideo " +"style\n" +"- with 1bit for alpha channel.\n" +"When it is on, GlideHQ will check, how alpha channel is used by the hires " +"texture,\n" +"and select most appropriate format for it.\n" +"This gives texture designers freedom to play with alpha, as they need,\n" +"regardless of format of original N64 texture.\n" +"For older and badly designed texture packs it can cause unwanted black " +"borders.\n" +"[Recommended: texture pack dependant]" +msgstr "" + +#: Config.cpp:662 +msgid "" +"Save texture cache to HD:\n" +"\n" +"For enhanced textures cache:\n" +"This will save all previously loaded and enhanced textures to HD.\n" +"So upon next game launch, all the textures will be instantly loaded, " +"resulting in smoother performance.\n" +"\n" +"For high-resolution textures cache:\n" +"After creation, loading hi-res texture will take only a few seconds upon " +"game launch,\n" +"as opposed to the 5 -60 seconds a pack can take to load without this cache " +"file.\n" +"The only downside here is upon any changes to the pack, the cache file will " +"need to be manually deleted.\n" +"\n" +"Saved cache files go into a folder called \"Cache\" within the Plugins " +"folder.\n" +"\n" +"[Highly Recommended: on]" +msgstr "" + +#: Config.cpp:685 +msgid "Debug" +msgstr "" + +#: Config.cpp:686 +msgid "" +"Autodetect Microcode\n" +"If this option is checked, the microcode of the game\n" +"will be detected automatically from the INI, and\n" +"therefore it will not need to be set in this\n" +"configuration dialog.\n" +"[Recommended: on]" +msgstr "" + +#: Config.cpp:688 +msgid "" +"Force Microcode\n" +"This option ONLY has an effect if Autodetect Microcode\n" +"is unchecked, the crc from the game could not be\n" +"found in the INI, OR after the game has already started\n" +"running. In any of those three cases, this will\n" +"select the microcode to use\n" +"[Recommended: any, turn on Autodetect Microcode]" +msgstr "" + +#: Config.cpp:692 +msgid "" +"Wireframe\n" +"This option, when checked, makes it so that the plugin will draw only the\n" +"outlines of objects. The colors specified in the combo box to the right\n" +"determines the color that the wireframes show up as.\n" +"[Recommended: off]" +msgstr "" + +#: Config.cpp:694 +msgid "" +"Wireframe Colors\n" +"This selects the colors to use for the wireframes (if wireframe mode is " +"enabled).\n" +"There are 3 modes:\n" +"* Original colors - draw exactly as it would normally, textures and all, " +"only in wireframes.\n" +"* Vertex colors - use the colors specified in the vertices to draw the " +"wireframes with.\n" +"* Red only - use a constant red color to draw the wireframes.\n" +"[Recommended: Vertex colors]" +msgstr "" + +#: Config.cpp:696 +msgid "" +"Log to RDP.txt\n" +"RECOMMENDED FOR DEBUGGING ONLY - this option, when checked, will log EVERY " +"SINGLE\n" +"COMMAND the plugin processes to a file called RDP.txt in the current " +"directory.\n" +"This is incredibly slow, so I recommend keeping it disabled.\n" +"[Recommended: off]" +msgstr "" + +#: Config.cpp:698 +msgid "" +"Unknown combiners as red\n" +"Objects that use an unimplemented combine mode will show up as red instead " +"of\n" +"assuming texture with full alpha. Disable this option to remove the red " +"stuff\n" +"and at least have a guess at the correct combine mode.\n" +"[Recommended: off]" +msgstr "" + +#: Config.cpp:700 +msgid "" +"Log clear every frame\n" +"RECOMMENDED FOR DEBUGGING ONLY - this option has no effect unless 'Log to " +"RDP.txt'\n" +"is checked. This will make it so that the log, RDP.txt, will be cleared at " +"the\n" +"beginning of every frame.\n" +"[Recommended: off]" +msgstr "" + +#: Config.cpp:702 +msgid "" +"Log unknown combiners\n" +"RECOMMENDED FOR DEBUGGING ONLY - when checked, this option will cause every\n" +"unimplemented combiner drawn to be logged to a file called Unimp.txt in the\n" +"current directory. This becomes slow when there are unimplemented combiners\n" +"on the screen, so I recommend keeping it disabled.\n" +"[Recommended: off]" +msgstr "" + +#: Config.cpp:704 +msgid "" +"Run and log in window\n" +"RECOMMENDED FOR DEBUGGING ONLY - this option will make it so that the plugin " +"will\n" +"still process dlists in windowed mode. This allows for logging to occur " +"while not\n" +"in fullscreen, possibly allowing you to debug a crash.\n" +"[Recommended: off]" +msgstr "" + +#: Config.cpp:706 +msgid "" +"Clear unknown combiner log every frame\n" +"RECOMMENDED FOR DEBUGGING ONLY - this option works much like 'Log clear " +"every frame'\n" +"except it clears the combiner log (Unimp.txt) instead of RDP.txt at the\n" +"beginning of each frame. Again, this option has no effect if 'combiner " +"logging' is disabled.\n" +"[Recommended: off]" +msgstr "" + +#: Config.cpp:709 +msgid "" +"Bilinear filter texture cache\n" +"RECOMMENDED FOR DEBUGGING ONLY - when checked, this option will make the " +"graphical\n" +"debugger texture cache use bilinear filtering as opposed to point-sampled " +"filtering,\n" +"which it will use otherwise. See 'Filtering mode' for descriptions of " +"bilinear and\n" +"point-sampled filtering.\n" +"[Recommended: off]" +msgstr "" + +#: Config.cpp:1104 +msgid "Glide64 settings" +msgstr "" + +#: Config.cpp:1293 +msgid "About Glide64" +msgstr "" + +#: Config.cpp:1326 +msgid "authors:" +msgstr "" + +#: Config.cpp:1330 +msgid "" +"Dave2001. Original author and former main developer.\n" +"He founded Glide64 project on Dec. 29th, 2001.\n" +"Left the project at fall of 2002.\n" +msgstr "" + +#: Config.cpp:1336 +msgid "" +"Gugaman. Developer. Joined the project at winter 2002\n" +" and left it at fall 2002." +msgstr "" + +#: Config.cpp:1342 +msgid "" +"Sergey 'Gonetz' Lipski. Joined the project at winter 2002.\n" +"Main developer since fall of 2002." +msgstr "" + +#: Config.cpp:1347 +msgid "Hiroshi 'KoolSmoky' Morii, Joined the project in 2007. " +msgstr "" + +#: Config.cpp:1350 +msgid "Glitch64 (the wrapper) authors:" +msgstr "" + +#: Config.cpp:1374 +msgid "GlideHQ author:" +msgstr "" + +#: Config.cpp:1381 +msgid "beta tester:" +msgstr "" + +#: Config.cpp:1388 +msgid "" +"special thanks to:\n" +" Orkin, Rice, Daniel Borca, Legend.\n" +"Thanks to EmuXHaven for hosting my site:\n" +"http://glide64.emuxhaven.net\n" +msgstr "" diff --git a/Source/Glide64/Internalization/Glide64_fr_FR.po b/Source/Glide64/Internalization/Glide64_fr_FR.po new file mode 100644 index 000000000..d619e39af --- /dev/null +++ b/Source/Glide64/Internalization/Glide64_fr_FR.po @@ -0,0 +1,1336 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2011-12-19 17:29+0700\n" +"PO-Revision-Date: 2011-12-29 12:30+0700\n" +"Last-Translator: Navitel \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: Config.cpp:64 +msgid "Rendering" +msgstr "Rendu" + +#: Config.cpp:65 +msgid "Other" +msgstr "Autres" + +#: Config.cpp:66 +msgid "Speed" +msgstr "Vitesse" + +#: Config.cpp:67 +msgid "Time" +msgstr "Heure" + +#: Config.cpp:68 +msgid "On screen display" +msgstr "Affichage" + +#: Config.cpp:69 +msgid "OpenGL settings" +msgstr "Configuration OpenGL" + +#: Config.cpp:70 +#: Config.cpp:137 +msgid "Frame buffer emulation" +msgstr "Emulation du frame buffer" + +#: Config.cpp:71 +msgid "" +"Windowed or\n" +"3dfx card resolution:" +msgstr "" +"Fenétré ou\n" +"resolution de la carte 3DFX" + +#: Config.cpp:99 +msgid "Vertical sync" +msgstr "Synchronisation verticale" + +#: Config.cpp:100 +msgid "Show advanced emulation options" +msgstr "Afficher les options d'emulation avancée" + +#: Config.cpp:101 +msgid "Show texture enhancement options" +msgstr "Afficher les options des textures améliorés" + +#: Config.cpp:102 +msgid "Screenshot format:" +msgstr "Format des captures d'écran" + +#: Config.cpp:105 +msgid "Language: " +msgstr "Langues:" + +#: Config.cpp:106 +msgid "LANGUAGE_NAME" +msgstr "Francais" + +#: Config.cpp:112 +msgid "FPS counter" +msgstr "Compteur FPS" + +#: Config.cpp:113 +msgid "VI/s counter" +msgstr "Compteur VI/s" + +#: Config.cpp:114 +#, c-format +msgid "% speed" +msgstr "% speed" + +#: Config.cpp:115 +msgid "Clock enabled" +msgstr "Horloge activé" + +#: Config.cpp:116 +msgid "Clock is 24-hour" +msgstr "Horloge est 24-heure" + +#: Config.cpp:117 +msgid "Transparent text background" +msgstr "Texte transparent" + +#: Config.cpp:118 +msgid "" +"Full screen\n" +"resolution:" +msgstr "" +"Plein écran\n" +"résolution" + +#: Config.cpp:121 +msgid "Anisotropic filtering" +msgstr "Filterage Anisotropic" + +#: Config.cpp:122 +msgid "Autodetect " +msgstr "Autodetection" + +#: Config.cpp:123 +msgid "VRAM size" +msgstr "Taille VRAM" + +#: Config.cpp:125 +msgid "Mb" +msgstr "Mb" + +#: Config.cpp:126 +msgid "Use frame buffer objects" +msgstr "Utiliser frame buffer objects" + +#: Config.cpp:133 +msgid "Current game emulation settings. Change with care!" +msgstr "paramétres d'émulation actuelle. A changer avec précaution!" + +#: Config.cpp:135 +msgid "Default emulation settings. Not recommended to change!" +msgstr "Paramétres d'émulation par défaut. Changement non recommandé.!" + +#: Config.cpp:136 +msgid "General options" +msgstr "Options générales" + +#: Config.cpp:138 +msgid "Depth buffer emulation" +msgstr "Emulation Depth buffer" + +#: Config.cpp:139 +msgid "Filtering mode:" +msgstr "Mode de filtrage" + +#: Config.cpp:141 +msgid "Automatic" +msgstr "Automatique" + +#: Config.cpp:142 +msgid "Force Bilinear" +msgstr "Forcer Bilinéaire" + +#: Config.cpp:143 +msgid "Force Point-sampled" +msgstr "Forcer Point sampled" + +#: Config.cpp:146 +msgid "Buffer swapping method:" +msgstr "Méthode de changement de buffer" + +#: Config.cpp:148 +msgid "Old" +msgstr "Vieux" + +#: Config.cpp:149 +msgid "New" +msgstr "Nouveau" + +#: Config.cpp:150 +msgid "Hybrid" +msgstr "Hybride" + +#: Config.cpp:153 +msgid "LOD calculation:" +msgstr "Calculation LOD:" + +#: Config.cpp:155 +msgid "off" +msgstr "désactivé" + +#: Config.cpp:156 +msgid "fast" +msgstr "rapide" + +#: Config.cpp:157 +msgid "precise" +msgstr "précis" + +#: Config.cpp:160 +msgid "Aspect ratio:" +msgstr "Ratio d'aspect" + +#: Config.cpp:162 +msgid "4:3 (default)" +msgstr "4:3 (défaut)" + +#: Config.cpp:163 +msgid "Force 16:9" +msgstr "Forcer 16:9" + +#: Config.cpp:164 +msgid "Stretch" +msgstr "Etirer" + +#: Config.cpp:165 +msgid "Original" +msgstr "Originale" + +#: Config.cpp:168 +msgid "Fog" +msgstr "Brouillard" + +#: Config.cpp:169 +msgid "Buffer clear on every frame" +msgstr "Vider Buffer à chaque image" + +#: Config.cpp:170 +msgid "Enable frame buffer emulation" +msgstr "Activer émulation du frame buffer" + +#: Config.cpp:171 +msgid "Hardware frame buffer emulation" +msgstr "Emulation matériel du frame buffer " + +#: Config.cpp:172 +msgid "Get frame buffer info" +msgstr "Obtenir les infos frame buffer" + +#: Config.cpp:173 +msgid "Read every frame (slow!)" +msgstr "Lire chaque image (lent)" + +#: Config.cpp:174 +msgid "Render N64 frame buffer as texture" +msgstr "Rendre le frame buffer de la N64 comme une texture" + +#: Config.cpp:175 +msgid "Detect CPU write to the N64 frame buffer" +msgstr "Detecter écritures du CPU dans le frame buffer de la N64" + +#: Config.cpp:176 +msgid "Software depth buffer rendering" +msgstr "Rendu du buffer de profondeur da manière logicielle" + +#: Config.cpp:200 +#: Config.cpp:619 +msgid "Texture enhancement" +msgstr "Amélioration des textures" + +#: Config.cpp:201 +msgid "Hi-resolution textures" +msgstr "Textures hautes resolutions" + +#: Config.cpp:202 +msgid "Common" +msgstr "Commun" + +#: Config.cpp:203 +msgid "Presets" +msgstr "Prédéfinis" + +#: Config.cpp:204 +#: Config.cpp:205 +msgid "Performance tweaks" +msgstr "Performance " + +#: Config.cpp:206 +msgid "Filter" +msgstr "Filtre" + +#: Config.cpp:208 +#: Config.cpp:219 +#: Config.cpp:238 +msgid "None" +msgstr "Aucun" + +#: Config.cpp:209 +msgid "Smooth filtering 1" +msgstr "Filtre doux 1" + +#: Config.cpp:210 +msgid "Smooth filtering 2" +msgstr "Filtre doux 2" + +#: Config.cpp:211 +msgid "Smooth filtering 3" +msgstr "Filtre doux 3" + +#: Config.cpp:212 +msgid "Smooth filtering 4" +msgstr "Filtre doux 1" + +#: Config.cpp:213 +msgid "Sharp filtering 1" +msgstr "Filtre dur 1" + +#: Config.cpp:214 +msgid "Sharp filtering 2" +msgstr "Filtre dur 1" + +#: Config.cpp:217 +msgid "Enhancement" +msgstr "Amélioration" + +#: Config.cpp:220 +msgid "Store" +msgstr "Stocker" + +#: Config.cpp:230 +msgid "Texture cache" +msgstr "Mise en cache des textures" + +#: Config.cpp:232 +msgid "Mbytes" +msgstr "Mbytes" + +#: Config.cpp:233 +msgid "Ignore Backgrounds" +msgstr "Ignorer les arriéres plans" + +#: Config.cpp:234 +#: Config.cpp:245 +msgid "Apply texture compression" +msgstr "Appliquer la compression des textures" + +#: Config.cpp:235 +#: Config.cpp:246 +msgid "Compress texture cache" +msgstr "Compresser la mise en cache des textures" + +#: Config.cpp:236 +msgid "Format" +msgstr "Format" + +#: Config.cpp:239 +msgid "Rice format" +msgstr "Format Rice" + +#: Config.cpp:242 +msgid "Tile textures" +msgstr "Texures de tuiles" + +#: Config.cpp:243 +msgid "Force 16bpp textures" +msgstr "Forcer les textures en 16bits" + +#: Config.cpp:244 +msgid "Alternative CRC calculation" +msgstr "Calculation CRC alternative" + +#: Config.cpp:247 +msgid "Use alpha channel fully" +msgstr "Utilisation totale du canal alpha " + +#: Config.cpp:248 +msgid "Texture dumping/editing mode" +msgstr "Dump des texutres/mode d'édition" + +#: Config.cpp:249 +msgid "Texture compression method" +msgstr "méthode de compression des textures" + +#: Config.cpp:255 +msgid "Save texture cache to hard disk" +msgstr "Sauver le cache texture sur le disque dur" + +#: Config.cpp:256 +msgid "Best performance" +msgstr "Meilleure performance" + +#: Config.cpp:257 +msgid "Best texture quality" +msgstr "Meilleure qualité de textures" + +#: Config.cpp:263 +msgid "Developers settings" +msgstr "Paramétres développeurs" + +#: Config.cpp:264 +msgid "Debug/Misc" +msgstr "Debug/Divers" + +#: Config.cpp:265 +msgid "Autodetect Microcode" +msgstr "Détection automatique du microcode" + +#: Config.cpp:266 +msgid "Force Microcode:" +msgstr "Forcage du Microcode:" + +#: Config.cpp:279 +msgid "Wireframe using:" +msgstr "Rendu fil de fer" + +#: Config.cpp:281 +msgid "Original colors" +msgstr "Couleurs d'origine" + +#: Config.cpp:282 +msgid "Vertex colors" +msgstr "Couleurs des vertex" + +#: Config.cpp:283 +msgid "Red only" +msgstr "Rouge seulement" + +#: Config.cpp:286 +msgid "Log to rdp.txt (SLOW)" +msgstr "Logger vers rdp.txt(lent)" + +#: Config.cpp:287 +msgid "Unknown combiners as red" +msgstr "Combiners inconnus en rouge" + +#: Config.cpp:288 +msgid "Log clear every frame" +msgstr "Vidage du log à chaque frame" + +#: Config.cpp:289 +msgid "Combiner logging" +msgstr "Loggage des combiners" + +#: Config.cpp:290 +msgid "Run (+log) in window" +msgstr "Démarrer (+log) en mode fenétré" + +#: Config.cpp:291 +msgid "Cmb. clear every frame" +msgstr "effacer Cmb. a chaque frame " + +#: Config.cpp:292 +msgid "Error log (rdp_e.txt)" +msgstr "Log d'erreurs (rdp_e.txt)" + +#: Config.cpp:293 +msgid "Bilinear filter texture cache" +msgstr "Cache des textures filtrées bilinéaires" + +#: Config.cpp:325 +#: Config.cpp:546 +msgid " auto" +msgstr "auto" + +#: Config.cpp:382 +msgid "Please choose language:" +msgstr "SVP choissisez la langue" + +#: Config.cpp:383 +msgid "Language" +msgstr "Langue" + +#: Config.cpp:390 +msgid "Press OK to change to " +msgstr "Pressez OK pour changer à" + +#: Config.cpp:486 +msgid "Basic settings" +msgstr "Paramétres basiques" + +#: Config.cpp:487 +msgid "" +"Resolution\n" +"This option selects the fullscreen resolution for 3dfx cards and windowed resolution for other cards\n" +"(note again that for 3dfx cards the plugin must be in fullscreen mode to see anything).\n" +"[Recommended: 640x480, 800x600, 1024x768]" +msgstr "" +"Résolution\n" +"Cette option choisit la resolution plein écran des cartes 3dfx ou la résolution fenétré pour les autres cartes\n" +"(attention avec les cartes 3dfx les plugin doit être en mode plein écran pour voir quelque chose).\n" +"[Recommandé: 640x480, 800x600, 1024x768]" + +#: Config.cpp:491 +msgid "" +"Vertical sync\n" +"This option will enable the vertical sync, which will prevent tearing.\n" +"Note: this option will ONLY have effect if vsync is set to \"Software Controlled\".\n" +msgstr "" +"Vertical sync\n" +"Cette option va activer la synchronisation verticale, ce qui va empécher les balayages.\n" + +#: Config.cpp:493 +msgid "Select a format, in which screen shots will be saved" +msgstr "Choissisez un format dans lequel les captures d'écran seront sauvés" + +#: Config.cpp:500 +msgid "" +"Language select:\n" +"Press the button to invoke language selection dialog.\n" +"Selected language will be activated after restart of the configuration dialog." +msgstr "" +"Selection de la language:\n" +"Pressez le bouton pour demander la menu de séléection du language.\n" +"Le language sélectionné sera activé aprés le rédémmarage de la boite de dialogue." + +#: Config.cpp:501 +msgid "" +"FPS counter\n" +"When this option is checked, a FPS (frames per second) counter will be shown\n" +"in the lower left corner of the screen.\n" +"[Recommended: your preference]" +msgstr "" +"Compteur FPS\n" +"Lorsque cette option est activé, un compteur FPS (Frame Per Second) sera affiché\n" +"dans le coin gauche en bas de l'écran.\n" +"[Recommandé: votre préférence]" + +#: Config.cpp:503 +msgid "" +"VI/s counter\n" +"When this option is checked, a VI/s (vertical interrupts per second) counter\n" +"will be shown in the lower left corner of the screen. This is like the FPS\n" +"counter but will be consistent at 60 VI/s for full speed on NTSC (U) games and\n" +"50 VI/s for full speed on PAL (E) ones.\n" +"[Recommended: your preference]" +msgstr "" +"VI/s counter\n" +"Lorsque cette option est activée, un compteur VI/s (vertical interrupts per second)\n" +"sera affiché dans le coin gauche en bas de l'écran. Ce sera comme le compteur FPS\n" +"mais il sera toujouts a 60/VI/s à plein vitesse pour les jeux NTSC (U) games et\n" +"50 VI/s à pleine vitesse pour un jeu PAL (E).\n" +"[Recommandé: votre préférence]" + +#: Config.cpp:505 +#, c-format +msgid "" +"% speed\n" +"This displays a percentage of the actual N64 speed in the lower\n" +"left corner of the screen.\n" +"[Recommended: your preference]" +msgstr "" +"% speed\n" +"Ceci affiche le pourcentage de la vitesse de la N64 dans le coin gauche\n" +"en bas de l'écran.\n" +"[Recommandé: votre préférence]" + +#: Config.cpp:507 +msgid "" +"Clock enabled\n" +"This option will put a clock in the lower right corner of the screen, showing the current time.\n" +"[Recommended: your preference]" +msgstr "" +"Horloge activée\n" +"Cette option affichera l'heure dans le coin droit de l'écran.\n" +"[Recommandé: votre préférence]" + +#: Config.cpp:510 +msgid "" +"Display hours as 24-hour clock.\n" +"[Recommended: your preference]" +msgstr "" +"Afficher l'heure comme une horloge de 24 heures.\n" +"[Recommandé: votre préférence]" + +#: Config.cpp:511 +msgid "" +"Transparent text background\n" +"If this is checked, all on-screen messages will have a transparent background. Otherwise, it will have a solid black background.\n" +"[Recommended: your preference]" +msgstr "" +"Texte en arrière plan transparent\n" +"Si activé, tout les messages à l'écran affichés aurant un arrière plan transparent. Autrement ils auront une arrière plan opaque.\n" +"[Recommandé: votre préférence]" + +#: Config.cpp:514 +msgid "" +"Enable \"Emulation settings\" panel. For experienced users only!\n" +"It shows default emulation settings when game is not loaded, or current game settings otherwise." +msgstr "" +"Activer le panneau \"paramètres d'émulation\". Pour utilisateurs expérimentés seulement!\n" +"Il montre les options d'émulation par défault si aucun jeu n'est chargé. Si un jeu est chargé les options d'émulation de ce jeu particulier autrement." + +#: Config.cpp:516 +msgid "" +"Enable \"Texture enhancement\" panel.\n" +"It shows various enhancement options for original textures as well as options for hi-resolution textures." +msgstr "" +"Activer un panneau \"Amélioration des textures\".\n" +"Il montre les divers options d'amélioration des textures originales ainsi ques les options pour les textures hautes résolutions." + +#: Config.cpp:517 +msgid "" +"Full screen resolution:\n" +"This sets the full screen resolution for non-3dfx video cards.\n" +"All the resolutions that your video card/monitor support should be displayed.\n" +"[Recommended: native (max) resolution of your monitor - unless performance becomes an issue]" +msgstr "" +"Résolution plein écran:\n" +"Cela paramétre la résolution plein écran pour les cartes graphiques non-3dfx.\n" +"Toutes les résolutions supportées par votre carte vidéo/écran devrait être affichées.\n" +"[Recommandé: résolution native de votre écran - sauf en cas de soucis de performance]" + +#: Config.cpp:520 +msgid "" +"Anisotropic filtering:\n" +"This filter sharpens and brings out the details of textures that recede into the distance.\n" +"When activated, it will use the max anisotropy your video card supports.\n" +"However, this will override native way of texture filtering and may cause visual artifacts in some games.\n" +"[Recommended: your preference, game dependant]" +msgstr "" +"Filtrage anisotropic:\n" +"Ce filtre améliore les détails des textures qui s'estompe vers l'horizon.\n" +"Activé ce paramétre utilisera le niveau maximum d'anisotropie supporté par votre carte vidéo.\n" +"Par contre ce filtrage supplantera la manière native de filtrage des textures et peut causer des parasites visuels dans certains jeux.\n" +"[Recommandé: votre préférence, selon le jeu]" + +#: Config.cpp:521 +msgid "" +"Autodetect VRAM Size:\n" +"Since OpenGL cannot do this reliably at the moment, the option to set this manually is available.\n" +"If checked, plugin will try to autodetect VRAM size.\n" +"But if this appears wrong, please uncheck and set it to correct value.\n" +"[Recommended: on]" +msgstr "" +"Autodetection de la taille de mémoire vidéo::\n" +"Comme OpenGL ne peut effectuer la detection de la mémoire vidéo de manière fiable, une option manuelle est disponible.\n" +"Si activée, le plugin tentera de détecter la taille de la mémoire vidéoMais si celle-ci est incorrecte, svp desactivez l'option et saisissez la valeur correct.\n" +"[Recommandé: activé]" + +#: Config.cpp:523 +msgid "" +"Use frame buffer objects:\n" +"Changes the way FB effects are rendered - with or without usage of the OpenGL Frame Buffer Objects (FBO) extension.\n" +"The choice depends on game and your video card. FBO off is good for NVIDIA cards, while for ATI cards, it's usually best that FBOs are turned on.\n" +"Also, some FB effects works only with one of the methods, no matter, which card you have.\n" +"On the whole, with FBO off, compatibility/ accuracy is a bit better (which is the case for Resident Evil 2).\n" +"However, with FBO on with some systems, it can actually be a bit faster in cases.\n" +"[Recommended: video card and game dependant]" +msgstr "" +"Utiliser \"frame buffer objects\":\n" +"Change la facon dans les effets frame buffer sont rendu - avec ou sans utilisation de l'extension OpenGL Frame Buffer Objects (FBO)Ce choix depend du jeu et de votre carte vidéo. Pour les cartes vidéos NVIDIA, FBO est meilleur desactivé alors que pour les cartes vidéos ATI il est habituellement meilleur de l'activer.Aussi certain effets frame buffer ne marche qu'avec l'une des deux méthodes, qu'importe la carte video.\n" +"De manière générale sans FBO, la compatibilité et la précision est meilleure (par exemple pour Resident Evil 2).\n" +"Par contre FBO sur certain systèmes est plus rapide dans certains cas.\n" +"[Recommandé: selon la carte vidéo et le jeu]" + +#: Config.cpp:578 +msgid "Emulation settings" +msgstr "Paramètres d'émulation" + +#: Config.cpp:579 +msgid "" +"Filtering mode\n" +"There are three filtering modes possible:\n" +"* Automatic filtering - filter exactly how the N64 specifies.\n" +"* Point-sampled filtering - causes texels to appear square and sharp.\n" +"* Bilinear filtering - interpolates the texture to make it appear more smooth.\n" +"[Recommended: Automatic]" +msgstr "" +"Méthode de filtrage\n" +"Il y a trois méthodes de filtrage possible:\n" +"* Filtrage automatique - filtre exactement comme la N64 le specifie.\n" +"* Filtrage Point-sampled - les pixels s'affichent comme des carrés grossiers.\n" +"* Filtrage Bilinéaire - ce filtre extrapole les textures pour les rendres plus douces.\n" +"[Recommended: Automatique]" + +#: Config.cpp:583 +msgid "" +"Buffer swapping method\n" +"There are 3 buffer swapping methods:\n" +"* old - swap buffers when vertical interrupt has occurred.\n" +"* new - swap buffers when set of conditions is satisfied. Prevents flicker on some games.\n" +"* hybrid - mix of first two methods.\n" +"Can prevent even more flickering then previous method, but also can cause artefacts.\n" +"If you have flickering problems in a game (or graphics that don't show),\n" +"try to change swapping method.\n" +"[Recommended: new (hybrid for Paper Mario)]" +msgstr "" +"Méthode de changement de buffer\n" +"Il y a 3 méthodes de changement de buffer:\n" +"* ancienne - change de buffer lorque l'interruption verticale s'est faite.\n" +"* nouvelle -change de buffer lorsque les conditions sont satisfaites. Previent des flashs dans certains jeux.\n" +"* hybride - mélange des 2 premières méthodes.\n" +"Peut prévenir encore plus de flashs que la méthode précédente, mais peut aussi en causer.\n" +"Si vous avez des problémes des flashs dans un jeu (ou les graphiques ne s'affichent pas,\n" +"essayez de changer de méthode de changement de buffer.\n" +"[Recommandé: nouvelle (hybride pour Paper Mario)]" + +#: Config.cpp:587 +msgid "" +"Per-pixel level-of-detail calculation\n" +"N64 uses special mechanism for mip-mapping, which nearly impossible to reproduce\n" +"correctly on PC hardware. This option enables approximate emulation of this feature.\n" +"For example, it is required for the Peach/Bowser portrait's transition in Super Mario 64.\n" +"There are 3 modes:\n" +"* off - LOD is not calculated\n" +"* fast - fast imprecise LOD calculation.\n" +"* precise - most precise LOD calculation possible, but more slow.\n" +"[Recommended: your preference]" +msgstr "" +"Level de détail par pixel\n" +"La N64 utilise un mechanisme spécial pour le mip-mapping qui est presque impossible à reproduire\n" +"correctement sur PC. Cette option en active une émulation approximative\n" +"Par exemple, il est requis pour le portrait de Peach/Browser dans Super Mario 64.\n" +"Il existe 3 modes:\n" +"* off - LOD n'est pas calculé\n" +"* rapide - caculation rapide mais imprécise du LOD.\n" +"* précise - calculation la plus précise possible du LOD mais plus lente.\n" +"[Recommandé: votre préférence]" + +#: Config.cpp:592 +msgid "" +"Aspect ratio of the output.\n" +"Most N64 games use 4:3 aspect ratio, but some support widescreen too.\n" +"You may select appropriate aspect here and set widescreen mode in game settings.\n" +"In \"Stretch\" mode the output will be stretched to the entire screen,\n" +"other modes may add black borders if necessary" +msgstr "" +"Ratio d'affichage.\n" +"La plupart des jeux N64 utilise un ratio d'affichage 4:3, mais certains supportent aussi les écrans 16:9.\n" +"Vous pouvez choisir le ratio approprié ici et selectionner le mode grand écran dans les paramètres du jeu.\n" +"En mode \"Etiré\" l'affichage sera étiré sur la totalité de l'écran,\n" +"les autres modes peuvent ajouter des bords noirs si nécéssaire" + +#: Config.cpp:595 +msgid "" +"Fog enabled\n" +"Sets fog emulation on//off.\n" +"[Recommended: on]" +msgstr "" +"Brouillard activé\n" +"Active ou désactive l'émulation du brouillard.\n" +"[Recommandé: activé]" + +#: Config.cpp:597 +msgid "" +"Buffer clear on every frame\n" +"Forces the frame buffer to be cleared every frame drawn.\n" +"Usually frame buffer clear is controlled by the game.\n" +"However, in some cases it is not well emulated,\n" +"and some garbage may be left on the screen.\n" +"In such cases, this option must be set on.\n" +"[Recommended: on]" +msgstr "" +"Vide le Buffer à chaque frame\n" +"Force le frame buffer à se vider à chaque drawn.\n" +"Habituellement ce vidage est controlé par le jeu.\n" +"Par contre dans certain cas cela n'est pas bien émulé,\n" +"et des rebuts peut rester à l'écran.\n" +"Dans ces case, cette option doit être utilisée.\n" +"[Recommandé: activé]" + +#: Config.cpp:599 +msgid "" +"Enable frame buffer emulation\n" +"If on, plugin will try to detect frame buffer usage and apply appropriate frame buffer emulation.\n" +"[Recommended: on for games which use frame buffer effects]" +msgstr "" +"Active l'émulation du frame buffer\n" +"Si actif, le plugin essayera de détecter l'usage du frame buffer et appliquera l'émulation du frame buffer appropriée.\n" +"[Recommandé: actif pour les jeux utilisant des effets de \"frames buffer\"]" + +#: Config.cpp:601 +msgid "" +"Enable hardware frame buffer emulation\n" +"If this option is on, plugin will create auxiliary frame buffers in video memory instead of copying\n" +"frame buffer content into main memory. This allows plugin to run frame buffer effects without slowdown\n" +"and without scaling image down to N64's native resolution. This feature is fully supported by\n" +"Voodoo 4/5 cards and partially by Voodoo3 and Banshee. Modern cards also fully support it.\n" +"[Recommended: on, if supported by your hardware]" +msgstr "" +"Active l'émulation matérielle du frame buffer \n" +"Si cette option est active, le plugin crééra des frame buffer auxilliaire dans la mémoire vidéo au lieu de copier\n" +"le contenu du frame buffer dans la mémoire principale. Ceci permet au plugin d'utiliser les effets frame buffer sans ralenti\n" +"et sans réduire l'image à la résolution native de la N64. Cette option est supporté pleinement par\n" +"les cartes Voodoo 4/5 cards and partiellment par les Voodoo3 and les Banshee. Les cartes modernes la supportent pleinement aussi.\n" +"[Recommandé: activée, si supporté par votre matériel]" + +#: Config.cpp:604 +msgid "" +"Get information about frame buffers\n" +"This is compatibility option. It must be set on for Mupen64 and off for 1964" +msgstr "" +"Obtenir les informations concernant le frame buffer\n" +"Ceci est un option de compatibilité. Elle doit être activée pour Mupen64 and désactivé pour 1964" + +#: Config.cpp:606 +msgid "" +"Read every frame\n" +"In some games plugin can't detect frame buffer usage.\n" +"In such cases you need to enable this option to see frame buffer effects.\n" +"Every drawn frame will be read from video card -> it works very slow.\n" +"[Recommended: mostly off (needed only for a few games)]" +msgstr "" +"Lire chaque frame\n" +"Dans certain jeux le plugin ne peut détecter l'usage du frame buffer.\n" +"Dans de tel case vous devez activer cette option pour voir les effets de frame buffer.\n" +"Chaque frame sera lu par votre carte vidéo -> ceci marche trés lentement.\n" +"[Recommandé: normalement desactivée (requis que pour certains jeux)]" + +#: Config.cpp:608 +msgid "" +"Render N64 frame buffer as texture\n" +"When this option is enabled, content of each N64 frame buffer is rendered\n" +"as texture over the frame, rendered by the plugin. This prevents graphics lost,\n" +"but may cause slowdowns and various glitches in some games.\n" +"[Recommended: mostly off]" +msgstr "" +"Rendre le frame buffer de la N64 comme une texture\n" +"Quand cette option est activée, le contenu de chaque frame buffer de la N64 est rendu\n" +"comme texture par le plugin. Ceci empéche de perdre certains graphismes,\n" +"mais peut causer des ralentissements et divers erreurs d'affichage dans certain jeux.\n" +"[Recommandé: principalement désactivé]" + +#: Config.cpp:610 +msgid "" +"Detect CPU write to the N64 frame buffer\n" +"This option works as the previous options, but the plugin is trying to detect,\n" +"when game uses CPU writes to N64 frame buffer. The N64 frame buffer is rendered\n" +"only when CPU writes is detected. Use this option for those games, in which you\n" +"see still image or no image at all for some time with no reason.\n" +"[Recommended: mostly off]" +msgstr "" +"Détecte l'écriture du CPU dans le frame buffer de la N64\n" +"Cette option marche comme les options précédentes mais le plugin va essayer de détecter,\n" +"lorsque le jeu utilise des écritures du CPU dans le frame buffer de la N64. Le frame buffer de la N64 est rendu\n" +"seulement lorsque ces écriture sont détectées. Utilisez cette option pour certains jeux dans lequels vous\n" +"voyez une image fixe ou pas d'image du tout pour un certain temps sont raison.\n" +"[Recommandé: principalement désactivé]" + +#: Config.cpp:612 +msgid "" +"Enable depth buffer rendering\n" +"This option is used to fully emulate N64 depth buffer.\n" +"It is required for correct emulation of depth buffer based effects.\n" +"However, it requires fast (>1GHz) CPU to work full speed.\n" +"[Recommended: on for fast PC]" +msgstr "" +"Activer le rendu du depth buffer\n" +"Cette option est utilisé pour émuler pleinement le depth buffer de la N64.\n" +"Elle est requise pour émuler correctement des effets graphiques basés sur le depth buffer.\n" +"Par contre cela demande une CPU rapide (>1GHz) pour éviter tout ralentissement.\n" +"[Recommandé: activée sur les PC rapides]" + +#: Config.cpp:620 +msgid "" +"Filters:\n" +"Apply a filter to either smooth or sharpen textures.\n" +"There are 4 different smoothing filters and 2 different sharpening filters.\n" +"The higher the number, the stronger the effect,\n" +"i.e. \"Smoothing filter 4\" will have a much more noticeable effect than \"Smoothing filter 1\".\n" +"Be aware that performance may have an impact depending on the game and/or the PC.\n" +"[Recommended: your preference]" +msgstr "" +"Filtres:\n" +"Applique un filtre pour adoucir ou affiner les textures.\n" +"Il y a 4 différentes filtres adoucissants et deux filtres affinants.\n" +"Plus le nombre est élevé, plus l'effet est fort,\n" +"par exemple \"Filtre adoucissant 4\" aura un effet plus notable que \"Filtre adoucissant 1\".\n" +"Prenez note que les performances peuvent être impacter selon le jeu et/ou le PC.\n" +"[Recommandé: votre préférence]" + +#: Config.cpp:624 +msgid "" +"Texture enhancement:\n" +"7 different filters are selectable here, each one with a distinctive look.\n" +"Be aware of possible performance impacts.\n" +"\n" +"IMPORTANT: 'Store' mode - saves textures in cache 'as is'. It can improve performance in games, which load many textures.\n" +"Disable 'Ignore backgrounds' option for better result.\n" +"\n" +"[Recommended: your preference]" +msgstr "" +"Amélioration des textures:\n" +"Sept différent filtres sont sélectionnables ici, chacun avec un aspect différent.\n" +"Attention à l'impact possible sur les performances.\n" +"\n" +"IMPORTANT: Mode 'Mise en mémoire cache' - Sauve les textures en cache en tant que tel. Cela peut améliorer les performances dans les jeux où beaucoup de textures sont chargées.\n" +"Désactivez 'Ignorer l'arrière plan' pour de meilleurs résultats.\n" +"\n" +"[Recommandé: votre préférence]" + +#: Config.cpp:628 +msgid "" +"Texture cache size:\n" +"Enhanced and filtered textures can be cached to aid performance.\n" +"This setting will adjust how much PC memory will be dedicated for texture cache.\n" +"This helps boost performance if there are subsequent requests for the same texture (usually the case).\n" +"Normally, 128MB should be more than enough but there is a sweet spot for each game.\n" +"Super Mario may not need more than 32megs, but Conker streams a lot of textures,\n" +"so setting 256+ megs can boost performance. Adjust accordingly if you are encountering speed issues.\n" +"'0' disables cache.\n" +"[Recommended: PC and game dependant]" +msgstr "" +"Taille du cache des textures:\n" +"Les textures améliorées et filtrées peuvent être mise en cache pour de meilleures performances.\n" +"Ce paramètre s'ajustera la mémoire qui sera dédiée au cache des textures.\n" +"Cela aide à booster les performances si il y a des requêtes ultérieures pour la même texture (souvent).\n" +"Normalement, 128MB devvrait être plus que suffisant mais cela dépend aussi du jeu.\n" +"Super Mario 64 peut n'avoir besoin que de 32MB, mais Conker utilise beaucoup de textures,\n" +"donc 256MB pour ce jeu peut améliorer les performances. Ajustez ce paramètre en case de soucis de performance.\n" +"'0' désactive le cache.\n" +"[Recommandé: selon le PC et le jeu]" + +#: Config.cpp:634 +msgid "" +"Ignore Backgrounds:\n" +"It is used to skip enhancement for long narrow textures, usually used for backgrounds.\n" +"This may save texture memory greatly and increase performance.\n" +"[Recommended: on (off for 'Store' mode)]" +msgstr "" +"Ignorer les arrière plans:\n" +"Cette option est utilisée pour passer l'amélioration des longues textures, généralement utilisées pour les arrière plans.\n" +"Cela peut sauver beaucoup de mémoire et augementer les performances.\n" +"[Recommandé: activé (desactivé pour mode 'Store')]" + +#: Config.cpp:636 +msgid "" +"Texture compression:\n" +"Textures will be compressed using selected texture compression method.\n" +"The overall compression ratio is about 1/6 for FXT1 and 1/4 for S3TC.\n" +"In addition to saving space on the texture cache,\n" +"the space occupied on the GFX hardware's texture RAM,\n" +"by the enhanced textures, will be greatly reduced.\n" +"This minimizes texture RAM usage,\n" +"decreasing the number of texture swaps to the GFX hardware leading to performance gains.\n" +"However, due to the nature of lossy compression of FXT1 and S3TC, using this option can sometimes lead to quality degradation of small size textures and color banding of gradient colored textures.\n" +"[Recommended: off]" +msgstr "" +"Compression des textures:\n" +"Les textures vont être compréssé en utilisant la méthode de compression sélectionné.\n" +"La ratio de compression est d'environ 1/6 pour FXT1 and 1/4 pour S3TC.\n" +"Cela va sauver de l'espace disque du cache de texture,\n" +"ainsi que de la mémoire graphique, ce qui peut améliorer les performances.\n" +"Par contre,de part la nature de la compression du FXT1 et S3TC, utiliser cette option peut mener à une dégradation des petites textures et de la couleur des textures dégradées.\n" +"[Recommandé: desactivée]" + +#: Config.cpp:640 +msgid "" +"Compress texture cache:\n" +"Memory will be compressed so that more textures can be held in the texture cache.\n" +"The compression ratio varies with each texture,\n" +"but 1/5 of the original size would be a modest approximation.\n" +"They will be decompressed on-the-fly, before being downloaded to the gfx hardware.\n" +"This option will still help save memory space even when using texture compression.\n" +"[Recommended: on]" +msgstr "" +"Compresser le cache des textures:\n" +"Les textures seront compressées donc plus de textures pourra être mise dans le cache des textures.\n" +"Le ratio de compression varie selon chaque texture,\n" +"mais 1/5 de la taille originale devrait être un approximation modeste.\n" +"Elles seront décompressées à la volée, avant d'être envoyées à la carte graphique.\n" +"Cette option sauvera de l'espace disque, même en utilisant la compression des textures.\n" +"[Recommandé: on]" + +#: Config.cpp:642 +msgid "" +"Hi-res pack format:\n" +"Choose which method is to be used for loading Hi-res texture packs.\n" +"Only Rice's format is available currently.\n" +"Leave on \"None\" if you will not be needing to load hi-res packs.\n" +"[Recommended: Rice's format. Default: \"None\"]" +msgstr "" +"Format du paquet de textures haute résolution:\n" +"Choissisez quelle méthode doit être utilisée pour charger le paquet de textures haute résolution.\n" +"Seul le format 'Rice' est actuellement disponible.\n" +"Laisser sur \"Aucun\" si vous n'avez pas besoin de charger des paquet de textures haute résolution.\n" +"[Recommandé: Rice's format. Par défaut: \"Aucun\"]" + +#: Config.cpp:646 +msgid "" +"Tile textures:\n" +"When on, wide texture will be split on several tiles to fit in one 256-width texture.\n" +"This tiled texture takes much less video memory space and thus overall performance will increase.\n" +"However, corresponding polygons must be split too, and this is not polished yet\n" +"- various issues are possible, including black lines and polygons distortions.\n" +"[Recommended: off]" +msgstr "" +"Textures découpées:\n" +"Lorsque activée, les larges textures seront découpées en plus petites textures de 256 pixels de large.\n" +"Ces textures prennent moins de mémoire vidéo et les performances augementeront.\n" +"Par contre les polygones correspondant peuvent être découpés aussi et ceci n'est pas encore totalement pris en charge\n" +"- différent problémes peuvent survenir, comme des lignes noires et des distortions de polygones.\n" +"[Recommandé: desactivée]" + +#: Config.cpp:648 +msgid "" +"Force 16bpp textures:\n" +"The color of the textures will be reduced to 16bpp.\n" +"This is another space saver and performance enhancer.\n" +"This halves the space used on the texture cache and the GFX hardware's texture RAM.\n" +"Color reduction is done so that the original quality is preserved as much as possible.\n" +"Depending on the texture, this usually is hardly noticeable.\n" +"Sometimes though, it can be: skies are a good example.\n" +"[Recommended: off]" +msgstr "" +"Forcer les textures en 16 bits:\n" +"La couleur des textures sera réduit à 16 bits.\n" +"C'est une autre source d'économie de mémoire et d'augementation des performances.\n" +"Ceci réduit de moitié l'espace utilisé dans le cache des textures et dans la mémoire de la carte vidéo.\n" +"La réduction des couleurs essaye de préserver la qualité originelle autant que possible.\n" +"Selon la texture, cette réduction sera à pein remarquable.\n" +"Parfois elle peut l'être: les ciels sont un bon exemple.\n" +"[Recommandé: desactivée]" + +#: Config.cpp:650 +msgid "" +"Texture dumping mode:\n" +"In this mode, you have that ability to dump textures on screen to the appropriate folder.\n" +"You can also reload textures while the game is running to see how they look instantly - big time saver!\n" +"\n" +"Hotkeys: \"R\" reloads hires textures from the texture pack - \"D\" toggles texture dumps on/off." +msgstr "" +"Mode dumping des textures:\n" +"Dans ce mode, vous avez la possibilité de dumper les textures affichées à l'écran dans le répertoire approprié.\n" +"Vous pouvez aussi recharger les textures pendant que le jeu tourne pour voir à quoi elles ressemblent directement - gain de temps considérable!\n" +"\n" +"Raccourcis clavier: \"R\" recharge les textures haute résolution à partir du paquet de textures - \"D\" active/désactive le dump des textures." + +#: Config.cpp:652 +msgid "" +"Alternative CRC calculation:\n" +"This option enables emulation of a palette CRC calculation bug in RiceVideo.\n" +"If some textures are not loaded, try to set this option on/off.\n" +"[Recommended: texture pack dependant, mostly on]" +msgstr "" +"Calcul alternatif du CRC:\n" +"Cette option active l'émulation d'un bug de calcul de la palette CRC par RiceVideo.\n" +"Si certaines textures ne se chargent pas , activez our désactivez cette option .\n" +"[Recommandé: selon le paquet de textures, principalement activé]" + +#: Config.cpp:657 +msgid "" +"Compress texture cache:\n" +"When game started, plugin loads all its hi-resolution textures into PC memory.\n" +"Since hi-resolution textures are usually large, the whole pack can take hundreds megabytes of memory.\n" +"Cache compression allows save memory space greatly.\n" +"Textures will be decompressed on-the-fly, before being downloaded to the gfx hardware.\n" +"This option will still help save memory space even when using texture compression.\n" +"[Recommended: on]" +msgstr "" +"Compression du cache des textures:\n" +"Lorsqu'un jeu est lancé, le plugin charge toutes les textures haute résolution dans mémoire du PC.\n" +"Puisque les textures haute résolution sont habituellement assez larges, tout le paquet peut prendre des centaines de megabytes de mémoire.\n" +"La compression du cache permet de sauver de beaucoup d'espace mémoire.\n" +"Les textures seront décompréssées à la volée, avant d'être envoyé à la carte graphique.\n" +"Cette option sauvera de l'espace mémoire même en utilisant la compression des textures.\n" +"[Recommandé: activé]" + +#: Config.cpp:659 +msgid "" +"Use Alpha channel fully:\n" +"When this option is off, 16bit rgba textures will be loaded using RiceVideo style\n" +"- with 1bit for alpha channel.\n" +"When it is on, GlideHQ will check, how alpha channel is used by the hires texture,\n" +"and select most appropriate format for it.\n" +"This gives texture designers freedom to play with alpha, as they need,\n" +"regardless of format of original N64 texture.\n" +"For older and badly designed texture packs it can cause unwanted black borders.\n" +"[Recommended: texture pack dependant]" +msgstr "" +"Utilisation du canal alpha pleinement:\n" +"Lorsque cette option est desactivée, les textures rgba 16 bits seront chargées en utilisant le style RiceVideo\n" +"- avec un 1bit for canal alpha.\n" +"Lorsqu'elle est active, GlideHQ vérifiera comment le canal alpha est utilisé par les textures haute résolution,\n" +"et sélectionnera le format les plus approprié pour celles-ci.\n" +"Cela donne aux designers la liberté de jouer avec le canal alpha selon leurs besoins,\n" +"sans faire attention au format original de la texture.\n" +"For les plus vieux et mal conçu des paquets de textures cela peut causer des bords noirs non desirés.\n" +"[Recommandé: selon le paquet de textures]" + +#: Config.cpp:662 +msgid "" +"Save texture cache to HD:\n" +"\n" +"For enhanced textures cache:\n" +"This will save all previously loaded and enhanced textures to HD.\n" +"So upon next game launch, all the textures will be instantly loaded, resulting in smoother performance.\n" +"\n" +"For high-resolution textures cache:\n" +"After creation, loading hi-res texture will take only a few seconds upon game launch,\n" +"as opposed to the 5 -60 seconds a pack can take to load without this cache file.\n" +"The only downside here is upon any changes to the pack, the cache file will need to be manually deleted.\n" +"\n" +"Saved cache files go into a folder called \"Cache\" within the Plugins folder.\n" +"\n" +"[Highly Recommended: on]" +msgstr "" +"Sauver le cache des textures sur le disque dur:\n" +"\n" +"Pour une cache de textures améliorées:\n" +"Cela sauvera toutes les textures préalablement chargées sur le disque dur.\n" +"Au prochain lancement du jeu, toutes les textures seront instantement chargées, ce qui améliore les performances.\n" +"\n" +"Pour un cache de textures haute resolution:\n" +"Après création, le chargement des textures haute résolution ne prendra que quelque secondes au lancement du jeu,\n" +", loin des 5 à 60 secondes qu'un paquet de textures peut prendre pour charger sans le cache.\n" +"Seulement si le paquet de textures change, le cache doit être manuellement effacé.\n" +"\n" +"Sauver les fichiers du cache dans un répertoire nommé \"Cache\" dans le répertoire Plugins.\n" +"\n" +"[Hautement Recommandé: activé]" + +#: Config.cpp:685 +msgid "Debug" +msgstr "Debug" + +#: Config.cpp:686 +msgid "" +"Autodetect Microcode\n" +"If this option is checked, the microcode of the game\n" +"will be detected automatically from the INI, and\n" +"therefore it will not need to be set in this\n" +"configuration dialog.\n" +"[Recommended: on]" +msgstr "" +"Détection automatique du microcode\n" +"Si cette option est activée, le microcode du jeu\n" +"sera automatiquement détecté à partir de l'INI, et\n" +"donc il n'est pas besoin de le choisir\n" +"dans la boite de dialogue.\n" +"[Recommandé: activé]" + +#: Config.cpp:688 +msgid "" +"Force Microcode\n" +"This option ONLY has an effect if Autodetect Microcode\n" +"is unchecked, the crc from the game could not be\n" +"found in the INI, OR after the game has already started\n" +"running. In any of those three cases, this will\n" +"select the microcode to use\n" +"[Recommended: any, turn on Autodetect Microcode]" +msgstr "" +"Forcer le microcode\n" +"Cette option n'a SEULEMENT d'effet si l'autodétection du microcode\n" +"est désactivée, the crc du jeu ne peut pas\n" +"trouvé dans l'INI, OU après que le jeu ne soit lancé.\n" +"Si ces trois conditions sont remplis cas, le microcode selectionné\n" +"sera utilisé\n" +"[Recommandé: desactivée]" + +#: Config.cpp:692 +msgid "" +"Wireframe\n" +"This option, when checked, makes it so that the plugin will draw only the\n" +"outlines of objects. The colors specified in the combo box to the right\n" +"determines the color that the wireframes show up as.\n" +"[Recommended: off]" +msgstr "" +"Wireframe\n" +"Cette option fait en sorte que le plugin n'affiche que les arrêtes des objets.\n" +"Les couleurs spécifiées dans la boite de dialogue à droite\n" +"determine la couleur que ces arrêtes prennent.\n" +"[Recommandé: desactivée]" + +#: Config.cpp:694 +msgid "" +"Wireframe Colors\n" +"This selects the colors to use for the wireframes (if wireframe mode is enabled).\n" +"There are 3 modes:\n" +"* Original colors - draw exactly as it would normally, textures and all, only in wireframes.\n" +"* Vertex colors - use the colors specified in the vertices to draw the wireframes with.\n" +"* Red only - use a constant red color to draw the wireframes.\n" +"[Recommended: Vertex colors]" +msgstr "" +"Couleurs des arrêtes\n" +"Cela selectionne les couleurs lors de l'utilisation des arrêtes (si le mode \"Wireframe\" est activé).\n" +"Il existe 3 modes:\n" +"* Couleurs originales - utilise exactement les couleurs définies par le jeu lui même mais en affichant seulement les arrêtes.\n" +"* Couleurs des vertices - utilise les couleurs spécifiées des vertices pour afficher les arrêtes.\n" +"* Rouge seulement - utilise une seule couleur rouge pour afficher les arrêtes.\n" +"[Recommandé: les couleurs des vertices]" + +#: Config.cpp:696 +msgid "" +"Log to RDP.txt\n" +"RECOMMENDED FOR DEBUGGING ONLY - this option, when checked, will log EVERY SINGLE\n" +"COMMAND the plugin processes to a file called RDP.txt in the current directory.\n" +"This is incredibly slow, so I recommend keeping it disabled.\n" +"[Recommended: off]" +msgstr "" +"Log vers RDP.txt\n" +"RECOMMANDE POU DEBOGAGE SEULEMENT - Cette option si activée logera chaque\n" +"COMMANDE que le plugin exécute vers un fichier nommé RDP.txt dans le répertoire du plugin.\n" +"Ceci est incroyablement lent, donc il est recommandé de garder cette option désactivée.\n" +"[Recommandé: désactivée]" + +#: Config.cpp:698 +msgid "" +"Unknown combiners as red\n" +"Objects that use an unimplemented combine mode will show up as red instead of\n" +"assuming texture with full alpha. Disable this option to remove the red stuff\n" +"and at least have a guess at the correct combine mode.\n" +"[Recommended: off]" +msgstr "" +"Combiners inconnus en rouge\n" +"Les objets qui utilise des modes de combiners inconnus seront affichés en rouge\n" +"au lieu de sa texture. Désactiver cette option pour ne plus voir ce rouge\n" +"et au moins deviner le mode de combiners correct.\n" +"[Recommandé: désactivée]" + +#: Config.cpp:700 +msgid "" +"Log clear every frame\n" +"RECOMMENDED FOR DEBUGGING ONLY - this option has no effect unless 'Log to RDP.txt'\n" +"is checked. This will make it so that the log, RDP.txt, will be cleared at the\n" +"beginning of every frame.\n" +"[Recommended: off]" +msgstr "" +"Logger à chaque frame\n" +"RECOMMANDE SEULEMENT POUR DEBOGAGE - cette option n'a pas d' effet sauf si 'Log to RDP.txt'\n" +"est activé. Cela fera que le log sera effacé à chaque frame\n" +"[Recommandé: désactivée]" + +#: Config.cpp:702 +msgid "" +"Log unknown combiners\n" +"RECOMMENDED FOR DEBUGGING ONLY - when checked, this option will cause every\n" +"unimplemented combiner drawn to be logged to a file called Unimp.txt in the\n" +"current directory. This becomes slow when there are unimplemented combiners\n" +"on the screen, so I recommend keeping it disabled.\n" +"[Recommended: off]" +msgstr "" +"Logger les combiners inconnus\n" +"RECOMMANDE SEULEMENT POUR DEBOGAGE - lorsqu'elle est active cette option aura pour effets\n" +"de logger tous les combiners non implémentés vers un fichier nommé Unimp.txt dans\n" +"répertoire courant. Lorsque beaucoup de combiners non implémentés sont affichés à l'écran, des ralentissements peuvent survenir\n" +", de ce fait il est recommandé de garder cette option désactivée.\n" +"[Recommandé: desactivée]" + +#: Config.cpp:704 +msgid "" +"Run and log in window\n" +"RECOMMENDED FOR DEBUGGING ONLY - this option will make it so that the plugin will\n" +"still process dlists in windowed mode. This allows for logging to occur while not\n" +"in fullscreen, possibly allowing you to debug a crash.\n" +"[Recommended: off]" +msgstr "" +"Logger en mode fenêtré\n" +"RECOMMANDE SEULEMENT POUR DEBOGAGE - cette option fera que le pluginl\n" +"continuera à traiter les dlists en mode fenêtré. Ceci permet de logger même\n" +"sans affichage, permettant de deboger un crash.\n" +"[Recommandé: desactivée]" + +#: Config.cpp:706 +msgid "" +"Clear unknown combiner log every frame\n" +"RECOMMENDED FOR DEBUGGING ONLY - this option works much like 'Log clear every frame'\n" +"except it clears the combiner log (Unimp.txt) instead of RDP.txt at the\n" +"beginning of each frame. Again, this option has no effect if 'combiner logging' is disabled.\n" +"[Recommended: off]" +msgstr "" +"Effacer le log des combiner inconnus à chaque frame\n" +"RECOMMANDE SEULEMENT POUR DEBOGAGE - cette option ressemble à 'Logger à chaque frame'\n" +"sauf que c'est le log des combiners qui s'efface (Unimp.txt) au lieu de RDP.txt à chaque frame.\n" +"De même cette option n'a aucun effet si 'logger les combiners' est désactivé.\n" +"[Recommandé: desactivée]" + +#: Config.cpp:709 +msgid "" +"Bilinear filter texture cache\n" +"RECOMMENDED FOR DEBUGGING ONLY - when checked, this option will make the graphical\n" +"debugger texture cache use bilinear filtering as opposed to point-sampled filtering,\n" +"which it will use otherwise. See 'Filtering mode' for descriptions of bilinear and\n" +"point-sampled filtering.\n" +"[Recommended: off]" +msgstr "" +"Cache de textures en filtre bilinéaire\n" +"RECOMMANDE SEULEMENT POUR DEBOGAGE - lorsque activée cette ption fera en sorte que\n" +"le cache pour le déboggage des textures utilise le filtre bilinéaire et non le filtre 'point-sampled',\n" +"qu'il utiliserait autrement. Voir 'Mode de filtrage' pour la description de filtre\n" +"bilinéaire et 'point-sampled'.\n" +"[Recommandé: désactivée]" + +#: Config.cpp:1104 +msgid "Glide64 settings" +msgstr "Paramètres Glide64" + +#: Config.cpp:1293 +msgid "About Glide64" +msgstr "A propos Glide64" + +#: Config.cpp:1326 +msgid "authors:" +msgstr "auteurs:" + +#: Config.cpp:1330 +msgid "" +"Dave2001. Original author and former main developer.\n" +"He founded Glide64 project on Dec. 29th, 2001.\n" +"Left the project at fall of 2002.\n" +msgstr "" +"Dave2001. Auteur originel et ancien principal développeur.\n" +"Il fonda le projet Glide64 le 29 Décembre 2001.\n" +"Parti du projet à l'automne 2002.\n" + +#: Config.cpp:1336 +msgid "" +"Gugaman. Developer. Joined the project at winter 2002\n" +" and left it at fall 2002." +msgstr "" +"Gugaman. Développeur. A rejoint le projet en hiver 2002\n" +" and l'a quitté à l'automne 2002." + +#: Config.cpp:1342 +msgid "" +"Sergey 'Gonetz' Lipski. Joined the project at winter 2002.\n" +"Main developer since fall of 2002." +msgstr "" +"Sergey 'Gonetz' Lipski. A rejoint le projet fin 2002.\n" +"Principal développeur depuis l'automne 2002." + +#: Config.cpp:1347 +msgid "Hiroshi 'KoolSmoky' Morii, Joined the project in 2007. " +msgstr "Hiroshi 'KoolSmoky' Morii, A rejoint le project en 2007. " + +#: Config.cpp:1350 +msgid "Glitch64 (the wrapper) authors:" +msgstr "Auteurs de Glitch64 (le wrapper):" + +#: Config.cpp:1374 +msgid "GlideHQ author:" +msgstr "Auteur de GlideHQ:" + +#: Config.cpp:1381 +msgid "beta tester:" +msgstr "beta tester:" + +#: Config.cpp:1388 +msgid "" +"special thanks to:\n" +" Orkin, Rice, Daniel Borca, Legend.\n" +"Thanks to EmuXHaven for hosting my site:\n" +"http://glide64.emuxhaven.net\n" +msgstr "" +"Grand merci à:\n" +"Orkin, Rice, Daniel Borca, Legend.\n" +"Merci à EmuXHaven d'héberger mon site:\n" +"http://glide64.emuxhaven.net\n" + diff --git a/Source/Glide64/Internalization/Glide64_ja_JP.po b/Source/Glide64/Internalization/Glide64_ja_JP.po new file mode 100644 index 000000000..cd84065b6 --- /dev/null +++ b/Source/Glide64/Internalization/Glide64_ja_JP.po @@ -0,0 +1,1258 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2011-12-19 17:29+0700\n" +"PO-Revision-Date: 2011-12-19 17:59+0700\n" +"Last-Translator: Navitel \n" +"Language-Team: \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: Config.cpp:64 +msgid "Rendering" +msgstr "レンダリング" + +#: Config.cpp:65 +msgid "Other" +msgstr "ãã®ä»–" + +#: Config.cpp:66 +msgid "Speed" +msgstr "速度関連" + +#: Config.cpp:67 +msgid "Time" +msgstr "時間関連" + +#: Config.cpp:68 +msgid "On screen display" +msgstr "ç”»é¢è¡¨ç¤º" + +#: Config.cpp:69 +msgid "OpenGL settings" +msgstr "OpenGLã®è¨­å®š" + +#: Config.cpp:70 +#: Config.cpp:137 +msgid "Frame buffer emulation" +msgstr "フレームãƒãƒƒãƒ•ã‚¡ã‚¨ãƒŸãƒ¥ãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³" + +#: Config.cpp:71 +msgid "" +"Windowed or\n" +"3dfx card resolution:" +msgstr "ウインドウ表示時解åƒåº¦" + +#: Config.cpp:99 +msgid "Vertical sync" +msgstr "åž‚ç›´åŒæœŸã‚’有効ã«ã™ã‚‹" + +#: Config.cpp:100 +msgid "Show advanced emulation options" +msgstr "エミュレーションã®è¨­å®šã‚’表示ã™ã‚‹" + +#: Config.cpp:101 +msgid "Show texture enhancement options" +msgstr "テクスãƒãƒ£å‘上ã®è¨­å®šã‚’表示ã™ã‚‹" + +#: Config.cpp:102 +msgid "Screenshot format:" +msgstr "スクリーンショットã®å½¢å¼" + +#: Config.cpp:105 +msgid "Language: " +msgstr "言語:" + +#: Config.cpp:106 +msgid "LANGUAGE_NAME" +msgstr "日本語(2010.05.21対応版)" + +#: Config.cpp:112 +msgid "FPS counter" +msgstr "FPS カウンタ" + +#: Config.cpp:113 +msgid "VI/s counter" +msgstr "VI/s カウンタ" + +#: Config.cpp:114 +#, c-format +msgid "% speed" +msgstr "実機速度比(ï¼…)" + +#: Config.cpp:115 +msgid "Clock enabled" +msgstr "時計" + +#: Config.cpp:116 +msgid "Clock is 24-hour" +msgstr "時計を24時間制ã§è¡¨ç¤ºã™ã‚‹" + +#: Config.cpp:117 +msgid "Transparent text background" +msgstr "テキスト表示ã®èƒŒæ™¯ã‚’é€éŽã•ã›ã‚‹" + +#: Config.cpp:118 +msgid "" +"Full screen\n" +"resolution:" +msgstr "" +"全画é¢è¡¨ç¤ºæ™‚\n" +"解åƒåº¦" + +#: Config.cpp:121 +msgid "Anisotropic filtering" +msgstr "異方性フィルタリングを有効ã«ã™ã‚‹" + +#: Config.cpp:122 +msgid "Autodetect " +msgstr "自動検出" + +#: Config.cpp:123 +msgid "VRAM size" +msgstr "VRAM容é‡" + +#: Config.cpp:125 +msgid "Mb" +msgstr "MB" + +#: Config.cpp:126 +msgid "Use frame buffer objects" +msgstr "フレームãƒãƒƒãƒ•ã‚¡ã‚ªãƒ–ジェクトを使用ã™ã‚‹" + +#: Config.cpp:133 +msgid "Current game emulation settings. Change with care!" +msgstr "実行中ã®ã‚²ãƒ¼ãƒ ã®ã‚¨ãƒŸãƒ¥ãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³è¨­å®šã§ã™ã€‚注æ„ã—ã¦å¤‰æ›´ã—ã¦ãã ã•ã„ï¼" + +#: Config.cpp:135 +msgid "Default emulation settings. Not recommended to change!" +msgstr "デフォルトã®ã‚¨ãƒŸãƒ¥ãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³è¨­å®šã§ã™ã€‚ã“ã®è¨­å®šã®å¤‰æ›´ã¯æŽ¨å¥¨ã•ã‚Œã¾ã›ã‚“ï¼" + +#: Config.cpp:136 +msgid "General options" +msgstr "一般" + +#: Config.cpp:138 +msgid "Depth buffer emulation" +msgstr "Zãƒãƒƒãƒ•ã‚¡ã‚¨ãƒŸãƒ¥ãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³" + +#: Config.cpp:139 +msgid "Filtering mode:" +msgstr "フィルタモード" + +#: Config.cpp:141 +msgid "Automatic" +msgstr "自動" + +#: Config.cpp:142 +msgid "Force Bilinear" +msgstr "強制 ãƒã‚¤ãƒªãƒ‹ã‚¢" + +#: Config.cpp:143 +msgid "Force Point-sampled" +msgstr "強制 点サンプリング" + +#: Config.cpp:146 +msgid "Buffer swapping method:" +msgstr "ãƒãƒƒãƒ•ã‚¡ã‚¹ãƒ¯ãƒƒãƒ”ング方å¼" + +#: Config.cpp:148 +msgid "Old" +msgstr "æ—§å¼" + +#: Config.cpp:149 +msgid "New" +msgstr "æ–°å¼" + +#: Config.cpp:150 +msgid "Hybrid" +msgstr "ãƒã‚¤ãƒ–リッド" + +#: Config.cpp:153 +msgid "LOD calculation:" +msgstr "LOD計算方å¼" + +#: Config.cpp:155 +msgid "off" +msgstr "無効" + +#: Config.cpp:156 +msgid "fast" +msgstr "速度優先" + +#: Config.cpp:157 +msgid "precise" +msgstr "精度優先" + +#: Config.cpp:160 +msgid "Aspect ratio:" +msgstr "アスペクト比" + +#: Config.cpp:162 +msgid "4:3 (default)" +msgstr "4:3 (デフォルト)" + +#: Config.cpp:163 +msgid "Force 16:9" +msgstr "強制 16:9" + +#: Config.cpp:164 +msgid "Stretch" +msgstr "引ã伸ã°ã—" + +#: Config.cpp:165 +msgid "Original" +msgstr "" + +#: Config.cpp:168 +msgid "Fog" +msgstr "フォグエミュレーション" + +#: Config.cpp:169 +msgid "Buffer clear on every frame" +msgstr "フレーム毎ã«ãƒãƒƒãƒ•ã‚¡ã‚’消去ã™ã‚‹" + +#: Config.cpp:170 +msgid "Enable frame buffer emulation" +msgstr "フレームãƒãƒƒãƒ•ã‚¡ã‚¨ãƒŸãƒ¥ãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³ã‚’有効ã«ã™ã‚‹" + +#: Config.cpp:171 +msgid "Hardware frame buffer emulation" +msgstr "ãƒãƒ¼ãƒ‰ã‚¦ã‚§ã‚¢ã§å‡¦ç†ã™ã‚‹" + +#: Config.cpp:172 +msgid "Get frame buffer info" +msgstr "フレームãƒãƒƒãƒ•ã‚¡ã®æƒ…報をå–å¾—ã™ã‚‹" + +#: Config.cpp:173 +msgid "Read every frame (slow!)" +msgstr "å…¨ã¦ã®ãƒ•ãƒ¬ãƒ¼ãƒ ã‚’読ã¿è¾¼ã‚€ï¼ˆé…ããªã‚Šã¾ã™ï¼ï¼‰" + +#: Config.cpp:174 +msgid "Render N64 frame buffer as texture" +msgstr "フレームãƒãƒƒãƒ•ã‚¡ã‚’テクスãƒãƒ£ã¨ã—ã¦æ写ã™ã‚‹" + +#: Config.cpp:175 +msgid "Detect CPU write to the N64 frame buffer" +msgstr "CPUã®N64フレームãƒãƒƒãƒ•ã‚¡ã¸ã®æ›¸ãè¾¼ã¿ã‚’検出ã™ã‚‹" + +#: Config.cpp:176 +msgid "Software depth buffer rendering" +msgstr "ソフトウェアZãƒãƒƒãƒ•ã‚¡ãƒ¬ãƒ³ãƒ€ãƒªãƒ³ã‚°ã‚’使用ã™ã‚‹" + +#: Config.cpp:200 +#: Config.cpp:619 +msgid "Texture enhancement" +msgstr "テクスãƒãƒ£å‘上ã®è¨­å®š" + +#: Config.cpp:201 +msgid "Hi-resolution textures" +msgstr "ãƒã‚¤ãƒ¬ã‚¾ãƒ†ã‚¯ã‚¹ãƒãƒ£" + +#: Config.cpp:202 +msgid "Common" +msgstr "共通設定" + +#: Config.cpp:203 +msgid "Presets" +msgstr "プリセット" + +#: Config.cpp:204 +#: Config.cpp:205 +msgid "Performance tweaks" +msgstr "パフォーマンス" + +#: Config.cpp:206 +msgid "Filter" +msgstr "フィルタ" + +#: Config.cpp:208 +#: Config.cpp:219 +#: Config.cpp:238 +msgid "None" +msgstr "ç„¡ã—" + +#: Config.cpp:209 +msgid "Smooth filtering 1" +msgstr "スムースãƒã‚¹ 1" + +#: Config.cpp:210 +msgid "Smooth filtering 2" +msgstr "スムースãƒã‚¹ 2" + +#: Config.cpp:211 +msgid "Smooth filtering 3" +msgstr "スムースãƒã‚¹ 3" + +#: Config.cpp:212 +msgid "Smooth filtering 4" +msgstr "スムースãƒã‚¹ 4" + +#: Config.cpp:213 +msgid "Sharp filtering 1" +msgstr "シャープãƒã‚¹ 1" + +#: Config.cpp:214 +msgid "Sharp filtering 2" +msgstr "シャープãƒã‚¹ 2" + +#: Config.cpp:217 +msgid "Enhancement" +msgstr "ピクセルフィルタ" + +#: Config.cpp:220 +msgid "Store" +msgstr "ä¿å­˜ç”¨" + +#: Config.cpp:230 +msgid "Texture cache" +msgstr "テクスãƒãƒ£ã‚­ãƒ£ãƒƒã‚·ãƒ¥ã‚µã‚¤ã‚º" + +#: Config.cpp:232 +msgid "Mbytes" +msgstr "MB" + +#: Config.cpp:233 +msgid "Ignore Backgrounds" +msgstr "背景を無視ã™ã‚‹" + +#: Config.cpp:234 +#: Config.cpp:245 +msgid "Apply texture compression" +msgstr "テクスãƒãƒ£åœ§ç¸®ã‚’有効ã«ã™ã‚‹" + +#: Config.cpp:235 +#: Config.cpp:246 +msgid "Compress texture cache" +msgstr "テクスãƒãƒ£ã‚­ãƒ£ãƒƒã‚·ãƒ¥ã‚’圧縮ã™ã‚‹" + +#: Config.cpp:236 +msgid "Format" +msgstr "フォーマット設定" + +#: Config.cpp:239 +msgid "Rice format" +msgstr "Rice フォーマット" + +#: Config.cpp:242 +msgid "Tile textures" +msgstr "テクスãƒãƒ£ã‚’タイル状ã«åˆ†å‰²ã™ã‚‹" + +#: Config.cpp:243 +msgid "Force 16bpp textures" +msgstr "強制16ビットテクスãƒãƒ£" + +#: Config.cpp:244 +msgid "Alternative CRC calculation" +msgstr "別ã®æ–¹æ³•ã§CRC計算処ç†ã‚’è¡Œã†" + +#: Config.cpp:247 +msgid "Use alpha channel fully" +msgstr "高精度アルファãƒãƒ£ãƒ³ãƒãƒ«ã‚’使用ã™ã‚‹" + +#: Config.cpp:248 +msgid "Texture dumping/editing mode" +msgstr "テクスãƒãƒ£ãƒ€ãƒ³ãƒ—ï¼ç·¨é›†ãƒ¢ãƒ¼ãƒ‰" + +#: Config.cpp:249 +msgid "Texture compression method" +msgstr "テクスãƒãƒ£åœ§ç¸®æ–¹å¼" + +#: Config.cpp:255 +msgid "Save texture cache to hard disk" +msgstr "テクスãƒãƒ£ã‚­ãƒ£ãƒƒã‚·ãƒ¥ã‚’HDDã«ä¿å­˜ã™ã‚‹" + +#: Config.cpp:256 +msgid "Best performance" +msgstr "ãƒã‚¤ãƒ‘フォーマンス設定" + +#: Config.cpp:257 +msgid "Best texture quality" +msgstr "ãƒã‚¤ã‚¯ã‚ªãƒªãƒ†ã‚£è¨­å®š" + +#: Config.cpp:263 +msgid "Developers settings" +msgstr "開発者å‘ã‘ã®è¨­å®š" + +#: Config.cpp:264 +msgid "Debug/Misc" +msgstr "デãƒãƒƒã‚°ï¼ãã®ä»–" + +#: Config.cpp:265 +msgid "Autodetect Microcode" +msgstr "マイクロコード自動検出" + +#: Config.cpp:266 +msgid "Force Microcode:" +msgstr "マイクロコード強制é©ç”¨" + +#: Config.cpp:279 +msgid "Wireframe using:" +msgstr "ワイヤーフレームを使用ã™ã‚‹" + +#: Config.cpp:281 +msgid "Original colors" +msgstr "オリジナルカラー" + +#: Config.cpp:282 +msgid "Vertex colors" +msgstr "頂点色" + +#: Config.cpp:283 +msgid "Red only" +msgstr "赤" + +#: Config.cpp:286 +msgid "Log to rdp.txt (SLOW)" +msgstr "ログを rdp.txt ã«å‡ºåŠ›(é…ããªã‚Šã¾ã™ï¼)" + +#: Config.cpp:287 +msgid "Unknown combiners as red" +msgstr "ä¸æ˜Žãªã‚³ãƒ³ãƒã‚¤ãƒŠã‚’赤ã§è¡¨ç¤ºã™ã‚‹" + +#: Config.cpp:288 +msgid "Log clear every frame" +msgstr "フレーム毎ã«ãƒ­ã‚°ã‚’消去ã™ã‚‹" + +#: Config.cpp:289 +msgid "Combiner logging" +msgstr "コンãƒã‚¤ãƒŠã‚’ログ出力" + +#: Config.cpp:290 +msgid "Run (+log) in window" +msgstr "ウィンドウ内ã§å®Ÿè¡Œã™ã‚‹ï¼ˆãƒ­ã‚°ä»˜ã)" + +#: Config.cpp:291 +msgid "Cmb. clear every frame" +msgstr "コンãƒã‚¤ãƒŠã‚’フレーム毎ã«ã‚¯ãƒªã‚¢" + +#: Config.cpp:292 +msgid "Error log (rdp_e.txt)" +msgstr "エラーログ (rdp_e.txt)" + +#: Config.cpp:293 +msgid "Bilinear filter texture cache" +msgstr "ãƒã‚¤ãƒªãƒ‹ã‚¢ãƒ•ã‚£ãƒ«ã‚¿ テクスãƒãƒ£ã‚­ãƒ£ãƒƒã‚·ãƒ¥" + +#: Config.cpp:325 +#: Config.cpp:546 +msgid " auto" +msgstr "自動" + +#: Config.cpp:382 +msgid "Please choose language:" +msgstr "言語をé¸æŠžã—ã¦ãã ã•ã„" + +#: Config.cpp:383 +msgid "Language" +msgstr "言語" + +#: Config.cpp:390 +msgid "Press OK to change to " +msgstr "ã“ã®ç”»é¢ã‚’é–‰ã˜ã‚‹ã¨æ¬¡ã«å¤‰æ›´ï¼š" + +#: Config.cpp:486 +msgid "Basic settings" +msgstr "基本的ãªè¨­å®š" + +#: Config.cpp:487 +msgid "" +"Resolution\n" +"This option selects the fullscreen resolution for 3dfx cards and windowed resolution for other cards\n" +"(note again that for 3dfx cards the plugin must be in fullscreen mode to see anything).\n" +"[Recommended: 640x480, 800x600, 1024x768]" +msgstr "" +"ã€ã‚¦ã‚¤ãƒ³ãƒ‰ã‚¦è¡¨ç¤ºæ™‚解åƒåº¦ã€‘\n" +"ウインドウ表示時ã®è§£åƒåº¦ã‚’é¸æŠžã™ã‚‹ã‚ªãƒ—ションã§ã™ã€‚(3dfx製ã®ãƒ“デオカードã®å ´åˆã¯ãƒ•ãƒ«ã‚¹ã‚¯ãƒªãƒ¼ãƒ³æ™‚)\n" +"[推奨設定: 640x480, 800x600, 1024x768]" + +#: Config.cpp:491 +msgid "" +"Vertical sync\n" +"This option will enable the vertical sync, which will prevent tearing.\n" +"Note: this option will ONLY have effect if vsync is set to \"Software Controlled\".\n" +msgstr "" +"ã€åž‚ç›´åŒæœŸã‚’有効ã«ã™ã‚‹ã€‘\n" +"有効ã«ã™ã‚‹ã¨ç”»é¢ã®ã¡ã‚‰ã¤ããŒæŠ‘ãˆã‚‰ã‚Œã¾ã™ã€‚\n" +"※ ã“ã‚Œã¯ãƒ“デオカードã®ãƒ‰ãƒ©ã‚¤ãƒå´ã§åž‚ç›´åŒæœŸã‚’ã€ã‚¢ãƒ—リケーションå´ã§ã‚³ãƒ³ãƒˆãƒ­ãƒ¼ãƒ«ã™ã‚‹ã€‘設定ã«ã—ã¦ã„る時ã®ã¿å‹•ä½œã—ã¾ã™ã€‚" + +#: Config.cpp:493 +msgid "Select a format, in which screen shots will be saved" +msgstr "é¸æŠžã—ãŸãƒ•ã‚©ãƒ¼ãƒžãƒƒãƒˆã§ã‚¹ã‚¯ãƒªãƒ¼ãƒ³ã‚·ãƒ§ãƒƒãƒˆãŒä¿å­˜ã•ã‚Œã¾ã™ã€‚\n" + +#: Config.cpp:500 +msgid "" +"Language select:\n" +"Press the button to invoke language selection dialog.\n" +"Selected language will be activated after restart of the configuration dialog." +msgstr "" +"ã€è¨€èªžã®å¤‰æ›´ã€‘\n" +"ã“ã®ãƒœã‚¿ãƒ³ã‚’クリックã™ã‚‹ã¨è¨€èªžé¸æŠžç”»é¢ãŒé–‹ãã¾ã™ã€‚\n" +"é¸æŠžã•ã‚ŒãŸè¨€èªžã¯ã“ã®è¨­å®šç”»é¢ã‚’一度抜ã‘ã‚‹ã¨é©ç”¨ã•ã‚Œã¾ã™ã€‚" + +#: Config.cpp:501 +msgid "" +"FPS counter\n" +"When this option is checked, a FPS (frames per second) counter will be shown\n" +"in the lower left corner of the screen.\n" +"[Recommended: your preference]" +msgstr "" +"ã€FPS カウンタ】\n" +"有効ã«ã™ã‚‹ã¨ç”»é¢å·¦ä¸‹ã«FPSカウンタを表示ã—ã¾ã™ã€‚" + +#: Config.cpp:503 +msgid "" +"VI/s counter\n" +"When this option is checked, a VI/s (vertical interrupts per second) counter\n" +"will be shown in the lower left corner of the screen. This is like the FPS\n" +"counter but will be consistent at 60 VI/s for full speed on NTSC (U) games and\n" +"50 VI/s for full speed on PAL (E) ones.\n" +"[Recommended: your preference]" +msgstr "" +"ã€VI/s カウンタ】\n" +"有効ã«ã™ã‚‹ã¨ç”»é¢å·¦ä¸‹ã«VI/sカウンタを表示ã—ã¾ã™ã€‚ \n" +"ã“ã‚Œã¯FPSカウンタã«ä¼¼ã¦ã„ã¾ã™ãŒã€NTSCã®ã‚²ãƒ¼ãƒ ã®å ´åˆ 60 VI/s ã€PALã®å ´åˆã¯ 50 VI/sãŒãƒ•ãƒ«ã‚¹ãƒ”ードã«ç›¸å½“ã—ã¾ã™ã€‚" + +#: Config.cpp:505 +#, c-format +msgid "" +"% speed\n" +"This displays a percentage of the actual N64 speed in the lower\n" +"left corner of the screen.\n" +"[Recommended: your preference]" +msgstr "" +"ã€å®Ÿæ©Ÿé€Ÿåº¦æ¯”】\n" +"有効ã«ã™ã‚‹ã¨ç”»é¢å·¦ä¸‹ã«N64実機ã¨ã®æ¯”較速度を%表示ã—ã¾ã™ã€‚" + +#: Config.cpp:507 +msgid "" +"Clock enabled\n" +"This option will put a clock in the lower right corner of the screen, showing the current time.\n" +"[Recommended: your preference]" +msgstr "" +"ã€æ™‚計】\n" +"有効ã«ã™ã‚‹ã¨ç”»é¢å³ä¸‹ã«ç¾åœ¨æ™‚刻を表示ã—ã¾ã™ã€‚" + +#: Config.cpp:510 +msgid "" +"Display hours as 24-hour clock.\n" +"[Recommended: your preference]" +msgstr "時計を24時間制ã§è¡¨ç¤ºã—ã¾ã™ã€‚" + +#: Config.cpp:511 +msgid "" +"Transparent text background\n" +"If this is checked, all on-screen messages will have a transparent background. Otherwise, it will have a solid black background.\n" +"[Recommended: your preference]" +msgstr "" +"ã€èƒŒæ™¯é€éŽãƒ†ã‚­ã‚¹ãƒˆè¡¨ç¤ºã€‘\n" +"有効ã«ã™ã‚‹ã¨ãƒ†ã‚­ã‚¹ãƒˆè¡¨ç¤ºã®èƒŒæ™¯ãŒé€éŽå‡¦ç†ã•ã‚Œã¾ã™ã€‚無効ã®å ´åˆã€é»’背景上ã§è¡¨ç¤ºã•ã‚Œã¾ã™ã€‚" + +#: Config.cpp:514 +msgid "" +"Enable \"Emulation settings\" panel. For experienced users only!\n" +"It shows default emulation settings when game is not loaded, or current game settings otherwise." +msgstr "" +"ã€ã‚¨ãƒŸãƒ¥ãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³ã®è¨­å®š タブを表示】 ※上級者å‘ã‘\n" +"有効ã«ã™ã‚‹ã¨ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆã®ã‚¨ãƒŸãƒ¥ãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³è¨­å®šã‚’変更ã™ã‚‹ç‚ºã®ã‚¿ãƒ–ãŒè¡¨ç¤ºã•ã‚Œã¾ã™ã€‚\n" +"ãƒã‚§ãƒƒã‚¯ã‚’入れãŸå¾Œã€ã“ã®è¨­å®šç”»é¢ã‚’一度抜ã‘ã‚‹ã¨æœ‰åŠ¹ã«ãªã‚Šã¾ã™ã€‚" + +#: Config.cpp:516 +msgid "" +"Enable \"Texture enhancement\" panel.\n" +"It shows various enhancement options for original textures as well as options for hi-resolution textures." +msgstr "" +"ã€ãƒ†ã‚¯ã‚¹ãƒãƒ£å‘上ã®è¨­å®š タブを表示】\n" +"有効ã«ã™ã‚‹ã¨ã‚ªãƒªã‚¸ãƒŠãƒ«ãƒ†ã‚¯ã‚¹ãƒãƒ£ã¨ãƒã‚¤ãƒ¬ã‚¾ãƒ†ã‚¯ã‚¹ãƒãƒ£ã«å¯¾ã—ã¦ã®è¨­å®šã‚’è¡Œã†ã‚¿ãƒ–を表示ã—ã¾ã™ã€‚\n" +"ãƒã‚§ãƒƒã‚¯ã‚’入れãŸå¾Œã€ã“ã®è¨­å®šç”»é¢ã‚’一度抜ã‘ã‚‹ã¨æœ‰åŠ¹ã«ãªã‚Šã¾ã™ã€‚" + +#: Config.cpp:517 +msgid "" +"Full screen resolution:\n" +"This sets the full screen resolution for non-3dfx video cards.\n" +"All the resolutions that your video card/monitor support should be displayed.\n" +"[Recommended: native (max) resolution of your monitor - unless performance becomes an issue]" +msgstr "" +"ã€å…¨ç”»é¢è¡¨ç¤ºæ™‚解åƒåº¦ã€‘\n" +"全画é¢è¡¨ç¤ºã«ã—ãŸéš›ã®è§£åƒåº¦ã‚’é¸æŠžã—ã¾ã™ã€‚\n" +"ã“ã“ã§é¸æŠžã§ãã‚‹ã®ã¯æ­è¼‰ä¸­ã®ãƒ“デオカードï¼ãƒ¢ãƒ‹ã‚¿ãŒã‚µãƒãƒ¼ãƒˆã—ã¦ã„ã‚‹å½¢å¼ã«é™ã‚‰ã‚Œã¾ã™ã€‚\n" +"[推奨設定: パフォーマンスã«å•é¡ŒãŒç„¡ã‘ã‚Œã°ã€é¸æŠžã§ãる最大ã®è§£åƒåº¦]" + +#: Config.cpp:520 +msgid "" +"Anisotropic filtering:\n" +"This filter sharpens and brings out the details of textures that recede into the distance.\n" +"When activated, it will use the max anisotropy your video card supports.\n" +"However, this will override native way of texture filtering and may cause visual artifacts in some games.\n" +"[Recommended: your preference, game dependant]" +msgstr "" +"ã€ç•°æ–¹æ€§ãƒ•ã‚£ãƒ«ã‚¿ãƒªãƒ³ã‚°ã‚’有効ã«ã™ã‚‹ã€‘\n" +"é æ–¹ã®ãƒ†ã‚¯ã‚¹ãƒãƒ£ã®ãƒ‡ã‚£ãƒ†ãƒ¼ãƒ«ã‚’よりãã£ãã‚Šã•ã›ã‚‹ãƒ•ã‚£ãƒ«ã‚¿ã§ã™ã€‚\n" +"有効ã«ã™ã‚‹ã¨ã€æ­è¼‰ã—ã¦ã„るビデオカードã§ä½¿ç”¨å¯èƒ½ãªæœ€é«˜ãƒ¬ãƒ™ãƒ«ã®ç•°æ–¹æ€§ãƒ•ã‚£ãƒ«ã‚¿ãƒªãƒ³ã‚°ãŒé¸æŠžã•ã‚Œã¾ã™ã€‚\n" +"ã¾ãŸã€ã“ã‚Œã¯é€šå¸¸è¡Œã‚れるã¯ãšã®ãƒ†ã‚¯ã‚¹ãƒãƒ£ãƒ•ã‚£ãƒ«ã‚¿ãƒªãƒ³ã‚°ã‚’上書ãã™ã‚‹ã®ã§ã€ã‚²ãƒ¼ãƒ ã«ã‚ˆã£ã¦ä¸è‡ªç„¶ãªè¡¨ç¤ºã«ãªã‚‹å ´åˆãŒã‚ã‚Šã¾ã™ã€‚\n" +"[推奨設定: PC性能ã¨ã‚²ãƒ¼ãƒ ã‚¿ã‚¤ãƒˆãƒ«ã«ä¾å­˜]" + +#: Config.cpp:521 +msgid "" +"Autodetect VRAM Size:\n" +"Since OpenGL cannot do this reliably at the moment, the option to set this manually is available.\n" +"If checked, plugin will try to autodetect VRAM size.\n" +"But if this appears wrong, please uncheck and set it to correct value.\n" +"[Recommended: on]" +msgstr "" +"ã€VRAM容é‡è‡ªå‹•æ¤œå‡ºã€‘\n" +"有効ã«ã™ã‚‹ã¨ã€ãƒ“デオカードã®VRAM容é‡ã‚’自動検出ã—ã¾ã™ã€‚\n" +"ã—ã‹ã—ç¾åœ¨ OpenGL ã¯æ­£ç¢ºãªVRAM容é‡ã‚’検出ã§ããªã„ã®ã§ã€é–“é•ã£ãŸå€¤ãŒè¡¨ç¤ºã•ã‚ŒãŸå ´åˆã¯ç„¡åŠ¹ã«ã—ã¦æ­£ç¢ºãªå€¤ã‚’入力ã—ã¦ãã ã•ã„。\n" +"[推奨設定: 有効]" + +#: Config.cpp:523 +msgid "" +"Use frame buffer objects:\n" +"Changes the way FB effects are rendered - with or without usage of the OpenGL Frame Buffer Objects (FBO) extension.\n" +"The choice depends on game and your video card. FBO off is good for NVIDIA cards, while for ATI cards, it's usually best that FBOs are turned on.\n" +"Also, some FB effects works only with one of the methods, no matter, which card you have.\n" +"On the whole, with FBO off, compatibility/ accuracy is a bit better (which is the case for Resident Evil 2).\n" +"However, with FBO on with some systems, it can actually be a bit faster in cases.\n" +"[Recommended: video card and game dependant]" +msgstr "" +"ã€ãƒ•ãƒ¬ãƒ¼ãƒ ãƒãƒƒãƒ•ã‚¡ã‚ªãƒ–ジェクトを使用ã™ã‚‹ã€‘\n" +"有効ã«ã™ã‚‹ã¨ã€ãƒ•ãƒ¬ãƒ¼ãƒ ãƒãƒƒãƒ•ã‚¡ã‚¨ãƒ•ã‚§ã‚¯ãƒˆã®ãƒ¬ãƒ³ãƒ€ãƒªãƒ³ã‚°æ–¹å¼ã¨ã—ã¦OpenGLã®ãƒ•ãƒ¬ãƒ¼ãƒ ãƒãƒƒãƒ•ã‚¡ã‚ªãƒ–ジェクトãŒä½¿ç”¨ã•ã‚Œã¾ã™ã€‚\n" +"ã“ã®ã‚ªãƒ—ションã¯ä½¿ç”¨ã—ã¦ã„るビデオカードã¨ã‚²ãƒ¼ãƒ ã‚¿ã‚¤ãƒˆãƒ«ã«ä¾å­˜ã—ã¾ã™ã€‚\n" +"NVIDIA製ã®ãƒ“デオカードã¯ã€ç„¡åŠ¹ã€‘ATI製ã¯ã€æœ‰åŠ¹ã€‘ã«ã—ãŸã»ã†ãŒè‰¯ã„よã†ã§ã™ãŒã€\n" +"有効ã«ã—ãªã„ã¨å‹•ä½œã—ãªã„フレームãƒãƒƒãƒ•ã‚¡ã‚¨ãƒ•ã‚§ã‚¯ãƒˆãŒã‚ã‚Šã¾ã™ã€‚ã¾ãŸãã®é€†ã‚‚ã‚ã‚Šã¾ã™ã€‚\n" +"有効ã«ã™ã‚‹ã¨ã‚¨ãƒŸãƒ¥ãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³é€Ÿåº¦ãŒå‘上ã™ã‚‹ã‚ˆã†ã§ã™ã€‚\n" +"無効ã«ã™ã‚‹ã¨ã‚¨ãƒŸãƒ¥ãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³ç²¾åº¦ãŒå‘上ã—ã¾ã™ã€‚(例:ãƒã‚¤ã‚ªãƒã‚¶ãƒ¼ãƒ‰2).\n" +"[推奨設定: ビデオカードã¨ã‚²ãƒ¼ãƒ ã‚¿ã‚¤ãƒˆãƒ«ã«ä¾å­˜]" + +#: Config.cpp:578 +msgid "Emulation settings" +msgstr "エミュレーションã®è¨­å®š" + +#: Config.cpp:579 +msgid "" +"Filtering mode\n" +"There are three filtering modes possible:\n" +"* Automatic filtering - filter exactly how the N64 specifies.\n" +"* Point-sampled filtering - causes texels to appear square and sharp.\n" +"* Bilinear filtering - interpolates the texture to make it appear more smooth.\n" +"[Recommended: Automatic]" +msgstr "" +"ã€ãƒ•ã‚£ãƒ«ã‚¿ãƒ¢ãƒ¼ãƒ‰ã€‘\n" +"3ã¤ã®ãƒ•ã‚£ãƒ«ã‚¿ãŒé¸æŠžå¯èƒ½ã§ã™ã€‚\n" +"* 自動 - N64ã®ä»•æ§˜ã«æ²¿ã£ãŸãƒ•ã‚£ãƒ«ã‚¿ãƒªãƒ³ã‚°ã‚’è¡Œã„ã¾ã™ã€‚\n" +"* 強制 ãƒã‚¤ãƒªãƒ‹ã‚¢ - テクスãƒãƒ£ã‚’滑らã‹ãªè¡¨ç¤ºã«ãªã‚‹ã‚ˆã†è£œé–“ã—ã¾ã™ã€‚\n" +"* 強制 点サンプリング - テクセルã®ãã£ãり感を際立ãŸã›ã¾ã™ã€‚\n" +"[推奨設定: 自動]" + +#: Config.cpp:583 +msgid "" +"Buffer swapping method\n" +"There are 3 buffer swapping methods:\n" +"* old - swap buffers when vertical interrupt has occurred.\n" +"* new - swap buffers when set of conditions is satisfied. Prevents flicker on some games.\n" +"* hybrid - mix of first two methods.\n" +"Can prevent even more flickering then previous method, but also can cause artefacts.\n" +"If you have flickering problems in a game (or graphics that don't show),\n" +"try to change swapping method.\n" +"[Recommended: new (hybrid for Paper Mario)]" +msgstr "" +"ã€ãƒãƒƒãƒ•ã‚¡ã‚¹ãƒ¯ãƒƒãƒ”ング方å¼ã€‘\n" +"3ã¤ã®æ–¹å¼ãŒé¸æŠžå¯èƒ½ã§ã™ã€‚\n" +"* æ—§å¼ - åž‚ç›´åŒæœŸå‰²ã‚Šè¾¼ã¿ãŒç™ºç”Ÿã—ãŸæ™‚ã«ãƒãƒƒãƒ•ã‚¡ã‚¹ãƒ¯ãƒƒãƒ”ングを行ã„ã¾ã™ã€‚\n" +"* æ–°å¼ - 特定ã®æ¡ä»¶ã‚’満ãŸã—ãŸæ™‚ã«ãƒãƒƒãƒ•ã‚¡ã‚¹ãƒ¯ãƒƒãƒ”ングを行ã„ã¾ã™ã€‚一部ã®ã‚²ãƒ¼ãƒ ã®ã¡ã‚‰ã¤ãを抑ãˆã¾ã™ã€‚\n" +"* ãƒã‚¤ãƒ–リッド - æ–°å¼ã¨æ—§å¼ã¨ã‚’æ··åˆã—ãŸå‡¦ç†ã§ã™ã€‚æ–°å¼ã‚ˆã‚Šã‚‚ã¡ã‚‰ã¤ãを抑ãˆã‚‰ã‚Œã¾ã™ãŒã€ä¸è‡ªç„¶ãªç”»é¢æ写ã®åŽŸå› ã«ãªã‚‹ã“ã¨ã‚‚ã‚ã‚Šã¾ã™ã€‚\n" +"ゲーム中ã«ã¡ã‚‰ã¤ããŒç™ºç”Ÿã—ãŸã‚Šç”»é¢è¡¨ç¤ºãŒã•ã‚Œãªããªã£ãŸå ´åˆã¯ã€ã‚¹ãƒ¯ãƒƒãƒ—æ–¹å¼ã‚’変更ã—ã¦ã¿ã¦ãã ã•ã„。\n" +"[推奨設定: æ–°å¼]" + +#: Config.cpp:587 +msgid "" +"Per-pixel level-of-detail calculation\n" +"N64 uses special mechanism for mip-mapping, which nearly impossible to reproduce\n" +"correctly on PC hardware. This option enables approximate emulation of this feature.\n" +"For example, it is required for the Peach/Bowser portrait's transition in Super Mario 64.\n" +"There are 3 modes:\n" +"* off - LOD is not calculated\n" +"* fast - fast imprecise LOD calculation.\n" +"* precise - most precise LOD calculation possible, but more slow.\n" +"[Recommended: your preference]" +msgstr "" +"ã€LOD計算方å¼ã€‘\n" +"N64ã§ã¯ãƒŸãƒƒãƒ—マッピングã®ãŸã‚ã«ç‰¹æ®Šãªå‡¦ç†ã‚’ã—ã¦ãŠã‚Šã€ã“ã‚Œã¯PCå‘ã‘ã®ãƒãƒ¼ãƒ‰ã‚¦ã‚§ã‚¢ã§ã¯æ­£ç¢ºãªå†ç¾ãŒé›£ã—ã„ã‚‚ã®ã§ã™ã€‚\n" +"ã“ã®ã‚ªãƒ—ションを有効ã«ã™ã‚‹ã“ã¨ã§ã“ã®å‡¦ç†ã®ã»ã¼æ­£ç¢ºãªã‚¨ãƒŸãƒ¥ãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³ãŒå¯èƒ½ã§ã™ã€‚\n" +"例ãˆã°ã€Žã‚¹ãƒ¼ãƒ‘ーマリオ64ã€ã«ãŠã„ã¦ãƒ”ーãƒå§«ã‹ã‚‰ã‚¯ãƒƒãƒ‘ã¸å¤‰åŒ–ã™ã‚‹è‚–åƒç”»ã®æ写ã«å¿…è¦ã§ã™ã€‚\n" +"3ã¤ã®æ–¹å¼ãŒé¸æŠžå¯èƒ½ã§ã™ã€‚\n" +"* 無効 - LODã¯è¨ˆç®—ã•ã‚Œã¾ã›ã‚“。\n" +"* 速度優先 - 速ã„ãŒä¸æ­£ç¢ºãªLOD計算を行ã„ã¾ã™ã€‚\n" +"* 精度優先 - ã§ãã‚‹ã ã‘正確ãªLOD計算を行ã„ã¾ã™ãŒã€éžå¸¸ã«é…ããªã‚Šã¾ã™ã€‚\n" +"[推奨設定: PC性能ã«ä¾å­˜]" + +#: Config.cpp:592 +msgid "" +"Aspect ratio of the output.\n" +"Most N64 games use 4:3 aspect ratio, but some support widescreen too.\n" +"You may select appropriate aspect here and set widescreen mode in game settings.\n" +"In \"Stretch\" mode the output will be stretched to the entire screen,\n" +"other modes may add black borders if necessary" +msgstr "" +"ã€ã‚¢ã‚¹ãƒšã‚¯ãƒˆæ¯”】\n" +"多ãã®N64ã®ã‚²ãƒ¼ãƒ ã§ã¯4:3ã®æ¯”率ãŒä½¿ã‚ã‚Œã¦ã„ã¾ã™ãŒã€ãƒ¯ã‚¤ãƒ‰ã‚¹ã‚¯ãƒªãƒ¼ãƒ³ã‚’サãƒãƒ¼ãƒˆã—ã¦ã„るソフトも存在ã—ã¾ã™ã€‚\n" +"ã“ã®ã‚ªãƒ—ションã§é©åˆ‡ãªã‚¢ã‚¹ãƒšã‚¯ãƒˆæ¯”を設定ã™ã‚Œã°ã€ã‚²ãƒ¼ãƒ å†…設定ã‹ã‚‰ãƒ¯ã‚¤ãƒ‰ã‚¹ã‚¯ãƒªãƒ¼ãƒ³è¡¨ç¤ºã‚’ã™ã‚‹ã“ã¨ãŒå¯èƒ½ã§ã™ã€‚\n" +"ã€å¼•ã伸ã°ã—】モードã§ã¯ã‚¢ã‚¹ãƒšã‚¯ãƒˆæ¯”ã«é–¢ä¿‚ãªãç”»é¢å…¨ä½“ã«å‡ºåŠ›ãŒè¡Œã‚ã‚Œã¾ã™ã€‚\n" +"ä»–ã®ãƒ¢ãƒ¼ãƒ‰ã§ã¯å¼·åˆ¶çš„ã«é»’帯ãŒè¡¨ç¤ºã•ã‚Œã‚‹ã“ã¨ãŒã‚ã‚Šã¾ã™ã€‚" + +#: Config.cpp:595 +msgid "" +"Fog enabled\n" +"Sets fog emulation on//off.\n" +"[Recommended: on]" +msgstr "" +"ã€ãƒ•ã‚©ã‚°ã‚¨ãƒŸãƒ¥ãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³ã€‘\n" +"有効ã«ã™ã‚‹ã¨ãƒ•ã‚©ã‚°ã®ã‚¨ãƒŸãƒ¥ãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³ã‚’è¡Œã„ã¾ã™ã€‚\n" +"[推奨設定: 有効]" + +#: Config.cpp:597 +msgid "" +"Buffer clear on every frame\n" +"Forces the frame buffer to be cleared every frame drawn.\n" +"Usually frame buffer clear is controlled by the game.\n" +"However, in some cases it is not well emulated,\n" +"and some garbage may be left on the screen.\n" +"In such cases, this option must be set on.\n" +"[Recommended: on]" +msgstr "" +"ã€ãƒ•ãƒ¬ãƒ¼ãƒ æ¯Žã«ãƒãƒƒãƒ•ã‚¡ã‚’消去ã™ã‚‹ã€‘\n" +"有効ã«ã™ã‚‹ã¨ãƒ•ãƒ¬ãƒ¼ãƒ æ¯Žã«å¼·åˆ¶çš„ã«ãƒ•ãƒ¬ãƒ¼ãƒ ãƒãƒƒãƒ•ã‚¡ã‚’消去ã—ã¾ã™ã€‚\n" +"消去ã®ã‚¿ã‚¤ãƒŸãƒ³ã‚°ã¯é€šå¸¸ã‚²ãƒ¼ãƒ å´ã§ã‚³ãƒ³ãƒˆãƒ­ãƒ¼ãƒ«ã•ã‚Œã¾ã™ãŒã€æ™‚々エミュレートãŒã†ã¾ãã„ã‹ãšã€ç”»é¢ä¸Šã«ã‚´ãƒŸãŒæ®‹ã‚‹å ´åˆãŒã‚ã‚Šã¾ã™ã€‚\n" +"ãã®ã‚ˆã†ãªå ´åˆã«å‚™ãˆã¦ã€é€šå¸¸ã“ã®ã‚ªãƒ—ションã¯æœ‰åŠ¹ã«ã—ã¦ãŠã„ã¦ãã ã•ã„。\n" +"[推奨設定: 有効]" + +#: Config.cpp:599 +msgid "" +"Enable frame buffer emulation\n" +"If on, plugin will try to detect frame buffer usage and apply appropriate frame buffer emulation.\n" +"[Recommended: on for games which use frame buffer effects]" +msgstr "" +"ã€ãƒ•ãƒ¬ãƒ¼ãƒ ãƒãƒƒãƒ•ã‚¡ã‚¨ãƒŸãƒ¥ãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³ã‚’有効ã«ã™ã‚‹ã€‘\n" +"有効ã«ã™ã‚‹ã¨ãƒ•ãƒ¬ãƒ¼ãƒ ãƒãƒƒãƒ•ã‚¡ã®ä½¿ç”¨ã‚’検出ã—ã€é©åˆ‡ãªãƒ•ãƒ¬ãƒ¼ãƒ ãƒãƒƒãƒ•ã‚¡ã‚¨ãƒŸãƒ¥ãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³ã‚’試ã¿ã¾ã™ã€‚\n" +"[推奨設定: フレームãƒãƒƒãƒ•ã‚¡ã‚¨ãƒ•ã‚§ã‚¯ãƒˆã‚’使用ã—ã¦ã„るゲームã§ã¯æœ‰åŠ¹]" + +#: Config.cpp:601 +msgid "" +"Enable hardware frame buffer emulation\n" +"If this option is on, plugin will create auxiliary frame buffers in video memory instead of copying\n" +"frame buffer content into main memory. This allows plugin to run frame buffer effects without slowdown\n" +"and without scaling image down to N64's native resolution. This feature is fully supported by\n" +"Voodoo 4/5 cards and partially by Voodoo3 and Banshee. Modern cards also fully support it.\n" +"[Recommended: on, if supported by your hardware]" +msgstr "" +"ã€ãƒãƒ¼ãƒ‰ã‚¦ã‚§ã‚¢ã§å‡¦ç†ã™ã‚‹ã€‘\n" +"有効ã«ã—ãŸå ´åˆã€ãƒ¡ã‚¤ãƒ³ãƒ¡ãƒ¢ãƒªã¸ã®ãƒ•ãƒ¬ãƒ¼ãƒ ãƒãƒƒãƒ•ã‚¡ã®ã‚³ãƒ”ーã®ä»£ç”¨ã¨ã—ã¦ãƒ“デオメモリ内ã«è£œåŠ©çš„ãªãƒ•ãƒ¬ãƒ¼ãƒ ãƒãƒƒãƒ•ã‚¡ã‚’作æˆã—ã¾ã™ã€‚\n" +"ã“ã‚Œã¯ãƒ•ãƒ¬ãƒ¼ãƒ ãƒãƒƒãƒ•ã‚¡ã‚¨ãƒ•ã‚§ã‚¯ãƒˆã‚’減速ã•ã›ãšã«ã€ã¾ãŸè§£åƒåº¦ã‚’N64実機ã®ã‚‚ã®ã¾ã§è½ã¨ã•ãªã„よã†ã«å‹•ä½œã•ã›ã‚‹ã“ã¨ã‚’å¯èƒ½ã«ã—ã¾ã™ã€‚\n" +"ã“ã®æ©Ÿèƒ½ã¯ Voodoo 4/5 ã§å®Œå…¨ã«ã€ Voodoo 3 / Banshee ã§ã¯ä¸€éƒ¨ã‚µãƒãƒ¼ãƒˆã•ã‚Œã¾ã™ã€‚è¿‘å¹´ã®ãƒ“デオカードã§ã‚‚完全ã«å‹•ä½œã™ã‚‹ã§ã—ょã†ã€‚\n" +"[推奨設定: ビデオカードã§ã‚µãƒãƒ¼ãƒˆã—ã¦ã„ã‚Œã°æœ‰åŠ¹]" + +#: Config.cpp:604 +msgid "" +"Get information about frame buffers\n" +"This is compatibility option. It must be set on for Mupen64 and off for 1964" +msgstr "" +"ã€ãƒ•ãƒ¬ãƒ¼ãƒ ãƒãƒƒãƒ•ã‚¡ã®æƒ…報をå–å¾—ã™ã‚‹ã€‘\n" +"ã“ã‚Œã¯äº’æ›æ€§ã®ãŸã‚ã®ã‚ªãƒ—ションã§ã™ã€‚Mupen64ã§ã¯æœ‰åŠ¹ã«ã€1964ã§ã¯ç„¡åŠ¹ã«ã—ã¦ãã ã•ã„。" + +#: Config.cpp:606 +msgid "" +"Read every frame\n" +"In some games plugin can't detect frame buffer usage.\n" +"In such cases you need to enable this option to see frame buffer effects.\n" +"Every drawn frame will be read from video card -> it works very slow.\n" +"[Recommended: mostly off (needed only for a few games)]" +msgstr "" +"ã€å…¨ã¦ã®ãƒ•ãƒ¬ãƒ¼ãƒ ã‚’読ã¿è¾¼ã‚€ã€‘\n" +"一部ã®ã‚²ãƒ¼ãƒ ã§ã¯ãƒ•ãƒ¬ãƒ¼ãƒ ãƒãƒƒãƒ•ã‚¡ã‚’使用ã—ã¦ã„ã¦ã‚‚検出ã§ããªã„ã“ã¨ãŒã‚ã‚Šã¾ã™ã€‚\n" +"ãã®ã‚ˆã†ãªå ´åˆã€ã“ã®ã‚ªãƒ—ションを有効ã«ã™ã‚‹ã“ã¨ã§ãƒ•ãƒ¬ãƒ¼ãƒ ãƒãƒƒãƒ•ã‚¡ã‚¨ãƒ•ã‚§ã‚¯ãƒˆãŒèªè­˜å¯èƒ½ã¨ãªã‚Šã¾ã™ã€‚\n" +"有効ã«ã—ã¦ã„ã‚‹é–“ã¯å…¨ã¦ã®ãƒ•ãƒ¬ãƒ¼ãƒ ã‚’ビデオカードã‹ã‚‰èª­ã¿ã“ã‚€ã®ã§éžå¸¸ã«é…ããªã‚Šã¾ã™ã€‚\n" +"[推奨設定: ã»ã¨ã‚“ã©ã®å ´åˆç„¡åŠ¹ (特定ã®ã‚²ãƒ¼ãƒ ã‚¿ã‚¤ãƒˆãƒ«ã®ã¿æœ‰åŠ¹)]" + +#: Config.cpp:608 +msgid "" +"Render N64 frame buffer as texture\n" +"When this option is enabled, content of each N64 frame buffer is rendered\n" +"as texture over the frame, rendered by the plugin. This prevents graphics lost,\n" +"but may cause slowdowns and various glitches in some games.\n" +"[Recommended: mostly off]" +msgstr "" +"ã€ãƒ•ãƒ¬ãƒ¼ãƒ ãƒãƒƒãƒ•ã‚¡ã‚’テクスãƒãƒ£ã¨ã—ã¦æ写ã™ã‚‹ã€‘\n" +"有効ã«ã™ã‚‹ã¨N64ã®ãƒ•ãƒ¬ãƒ¼ãƒ ãƒãƒƒãƒ•ã‚¡ã‚’テクスãƒãƒ£ã¨åŒã˜ã‚ˆã†ã«ãƒ•ãƒ¬ãƒ¼ãƒ ä¸Šã«æ写ã—ã¾ã™ã€‚\n" +"ã“ã‚Œã«ã‚ˆã‚Šã‚°ãƒ©ãƒ•ã‚£ãƒƒã‚¯æ¬ ã‘を防ãã“ã¨ãŒã§ãã¾ã™ãŒã€ã‚²ãƒ¼ãƒ ã«ã‚ˆã£ã¦ã¯å‡¦ç†è½ã¡ã‚„ä¸å…·åˆã®åŽŸå› ã«ãªã‚Šã¾ã™ã€‚\n" +"[推奨設定: ã»ã¨ã‚“ã©ã®å ´åˆã§ç„¡åŠ¹]" + +#: Config.cpp:610 +msgid "" +"Detect CPU write to the N64 frame buffer\n" +"This option works as the previous options, but the plugin is trying to detect,\n" +"when game uses CPU writes to N64 frame buffer. The N64 frame buffer is rendered\n" +"only when CPU writes is detected. Use this option for those games, in which you\n" +"see still image or no image at all for some time with no reason.\n" +"[Recommended: mostly off]" +msgstr "" +"ã€CPUã®N64フレームãƒãƒƒãƒ•ã‚¡ã¸ã®æ›¸ãè¾¼ã¿ã‚’検出ã™ã‚‹ã€‘\n" +"ã“ã®ã‚ªãƒ—ションã¯éŽåŽ»ã®ã‚‚ã®ã§ã€æœ‰åŠ¹ã«ã™ã‚‹ã¨ãƒ—ラグインã¯ã‚²ãƒ¼ãƒ å†…ã§CPUãŒN64フレームãƒãƒƒãƒ•ã‚¡ã¸æ›¸ã込むよã†ã«ã™ã‚‹ã¨ã“ã‚を検出ã—ã¾ã™ã€‚\n" +"N64フレームãƒãƒƒãƒ•ã‚¡ã¯CPUãŒæ›¸ã込むã®ã‚’検出ã—ãŸæ™‚ã®ã¿æ写ã•ã‚Œã‚‹ã¨ã„ã†ã“ã¨ã§ã™ã€‚\n" +"ã“ã®ã‚ªãƒ—ションã¯ãれらã®ã‚²ãƒ¼ãƒ ã‚¿ã‚¤ãƒˆãƒ«ã«ä½¿ç”¨ã—ã¦ãã ã•ã„。(ãã®éš›ã—ã°ã‚‰ãé™æ­¢ç”»ã¾ãŸã¯çœŸã£æš—ãªç”»é¢ãŒè¡¨ç¤ºã•ã‚Œã¾ã™ã€‚)\n" +"[推奨設定: ã»ã¨ã‚“ã©ã®å ´åˆç„¡åŠ¹]" + +#: Config.cpp:612 +msgid "" +"Enable depth buffer rendering\n" +"This option is used to fully emulate N64 depth buffer.\n" +"It is required for correct emulation of depth buffer based effects.\n" +"However, it requires fast (>1GHz) CPU to work full speed.\n" +"[Recommended: on for fast PC]" +msgstr "" +"ã€ã‚½ãƒ•ãƒˆã‚¦ã‚§ã‚¢Zãƒãƒƒãƒ•ã‚¡ãƒ¬ãƒ³ãƒ€ãƒªãƒ³ã‚°ã‚’使用ã™ã‚‹ã€‘\n" +"有効ã«ã™ã‚‹ã¨N64ã®Zãƒãƒƒãƒ•ã‚¡ã®å®Œå…¨ãªã‚¨ãƒŸãƒ¥ãƒ¬ãƒ¼ãƒˆã‚’è¡Œã„ã¾ã™ã€‚\n" +"ã“ã‚Œã¯Zãƒãƒƒãƒ•ã‚¡ã«åŸºã¥ãエフェクトを正ã—ãエミュレートã™ã‚‹ãŸã‚ã«å¿…è¦ã§ã™ã€‚\n" +"ã“ã®ã‚ªãƒ—ションをフルスピードã§å‹•ä½œã•ã›ã‚‹ãŸã‚ã«ã¯ã€1GHz以上ã®CPUãŒå¿…è¦ã¨ã•ã‚Œã¾ã™ã€‚\n" +"[推奨設定: 高性能ãªPCã§ã¯æœ‰åŠ¹]" + +#: Config.cpp:620 +msgid "" +"Filters:\n" +"Apply a filter to either smooth or sharpen textures.\n" +"There are 4 different smoothing filters and 2 different sharpening filters.\n" +"The higher the number, the stronger the effect,\n" +"i.e. \"Smoothing filter 4\" will have a much more noticeable effect than \"Smoothing filter 1\".\n" +"Be aware that performance may have an impact depending on the game and/or the PC.\n" +"[Recommended: your preference]" +msgstr "" +"ã€ãƒ•ã‚£ãƒ«ã‚¿ã€‘\n" +"テクスãƒãƒ£ã‚’よりスムースã¾ãŸã¯ã‚·ãƒ£ãƒ¼ãƒ—ã«ã™ã‚‹ãƒ•ã‚£ãƒ«ã‚¿ã‚’é©ç”¨ã§ãã¾ã™ã€‚æ•°å­—ãŒå¤§ãã„ã»ã©å¼·ã„効果ã¨ãªã‚Šã¾ã™ã€‚\n" +"(ã¤ã¾ã‚Šã€ã€ã‚¹ãƒ ãƒ¼ã‚¹ãƒã‚¹ 1】よりã€ã‚¹ãƒ ãƒ¼ã‚¹ãƒã‚¹ 4】ã®ã»ã†ãŒå¼·ã„効果ã¨ãªã‚Šã¾ã™ã€‚)\n" +"ゲームタイトルやPC性能ã«ã‚ˆã£ã¦ã¯ãƒ‘フォーマンスã«å½±éŸ¿ã‚’与ãˆã‚‹ã®ã§æ³¨æ„ã—ã¦ãã ã•ã„。\n" +"[推奨設定: PC性能ã«ä¾å­˜]" + +#: Config.cpp:624 +msgid "" +"Texture enhancement:\n" +"7 different filters are selectable here, each one with a distinctive look.\n" +"Be aware of possible performance impacts.\n" +"\n" +"IMPORTANT: 'Store' mode - saves textures in cache 'as is'. It can improve performance in games, which load many textures.\n" +"Disable 'Ignore backgrounds' option for better result.\n" +"\n" +"[Recommended: your preference]" +msgstr "" +"ã€ãƒ”クセルフィルタ】\n" +"7ã¤ã®ãã‚Œãžã‚Œç‹¬ç‰¹ã®ãƒ•ã‚£ãƒ«ã‚¿ãŒé¸æŠžã§ãã¾ã™ã€‚パフォーマンスã«å½±éŸ¿ã‚’与ãˆã‚‹ã®ã§æ³¨æ„ã—ã¦ãã ã•ã„。\n" +"\n" +"é‡è¦ï¼šã€ä¿å­˜ç”¨ã€‘モードã«ã¤ã„㦠- ã“ã‚Œã¯ãƒ†ã‚¯ã‚¹ãƒãƒ£ã‚’ãã®ã¾ã¾ã‚­ãƒ£ãƒƒã‚·ãƒ¥ã¨ã—ã¦ä¿å­˜ã™ã‚‹ã‚‚ã®ã§ã™ã€‚\n" +"ゲーム中多ãã®ãƒ†ã‚¯ã‚¹ãƒãƒ£ãŒä½¿ç”¨ã•ã‚Œã‚‹å ´é¢ã§ãƒ‘フォーマンスå‘上ãŒæœŸå¾…ã§ãã¾ã™ã€‚\n" +"ã“ã®ã‚ªãƒ—ションをé¸æŠžã—ã¦ã„ã‚‹å ´åˆã¯ä¸‹ã®ã€èƒŒæ™¯ã‚’無視ã™ã‚‹ã€‘オプションを無効ã«ã—ãŸã»ã†ãŒè‰¯ã„çµæžœã«ãªã‚Šã¾ã™ã€‚\n" +"[推奨設定: PC性能ã«ä¾å­˜]" + +#: Config.cpp:628 +msgid "" +"Texture cache size:\n" +"Enhanced and filtered textures can be cached to aid performance.\n" +"This setting will adjust how much PC memory will be dedicated for texture cache.\n" +"This helps boost performance if there are subsequent requests for the same texture (usually the case).\n" +"Normally, 128MB should be more than enough but there is a sweet spot for each game.\n" +"Super Mario may not need more than 32megs, but Conker streams a lot of textures,\n" +"so setting 256+ megs can boost performance. Adjust accordingly if you are encountering speed issues.\n" +"'0' disables cache.\n" +"[Recommended: PC and game dependant]" +msgstr "" +"ã€ãƒ†ã‚¯ã‚¹ãƒãƒ£ã‚­ãƒ£ãƒƒã‚·ãƒ¥ã‚µã‚¤ã‚ºã€‘\n" +"パフォーマンス改善ã®ãŸã‚ã«ãƒ•ã‚£ãƒ«ã‚¿ãƒªãƒ³ã‚°ã•ã‚ŒãŸãƒ†ã‚¯ã‚¹ãƒãƒ£ã‚’キャッシュã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚\n" +"ã“ã®è¨­å®šã¯ãƒ†ã‚¯ã‚¹ãƒãƒ£ã‚­ãƒ£ãƒƒã‚·ãƒ³ã‚°ã®ãŸã‚ã®ãƒ¡ãƒ¢ãƒªä½¿ç”¨é‡ã‚’調節ã™ã‚‹ã‚‚ã®ã§ã™ã€‚\n" +"キャッシングã•ã‚ŒãŸãƒ†ã‚¯ã‚¹ãƒãƒ£ã¯ã€åŒã˜ãƒ†ã‚¯ã‚¹ãƒãƒ£ã‚’後続è¦æ±‚ã•ã‚ŒãŸå ´åˆãªã©ã§ãƒ‘フォーマンスを大ãã高ã‚ã‚‹ã®ã«å½¹ç«‹ã¡ã¾ã™ã€‚\n" +"通常ã€128MB程度ã‚ã‚Œã°å……分ãªã¯ãšã§ã™ãŒã€ãã‚Œãžã‚Œã®ã‚²ãƒ¼ãƒ ã§åŠ¹æžœçš„ãªå®¹é‡ã¯é•ã£ã¦ãã¾ã™ã€‚\n" +"『スーパーマリオ64ã€ã§ã¯32MBã‚‚å¿…è¦ã‚ã‚Šã¾ã›ã‚“ãŒã€ã€ŽConker 64ã€ã§ã¯å¤šãã®ãƒ†ã‚¯ã‚¹ãƒãƒ£ã‚’使用ã™ã‚‹ã®ã§ã€ãƒ‘フォーマンスå‘上ã«ã¯256MB以上必è¦ã§ã™ã€‚\n" +"キャッシュをã—ã¦ã„ã‚‹ã®ã«é€Ÿåº¦ãŒå‡ºãªã„時ã¯ã€ã‚­ãƒ£ãƒƒã‚·ãƒ¥å®¹é‡ã‚’調節ã—ã¦ã¿ã¦ãã ã•ã„。\n" +"ã€0】ã«è¨­å®šã™ã‚‹ã¨ã‚­ãƒ£ãƒƒã‚·ãƒ¥ã¯ç„¡åŠ¹ã«ãªã‚Šã¾ã™ã€‚\n" +"[推奨設定: PC性能ã¨ã‚²ãƒ¼ãƒ ã‚¿ã‚¤ãƒˆãƒ«ã«ä¾å­˜]" + +#: Config.cpp:634 +msgid "" +"Ignore Backgrounds:\n" +"It is used to skip enhancement for long narrow textures, usually used for backgrounds.\n" +"This may save texture memory greatly and increase performance.\n" +"[Recommended: on (off for 'Store' mode)]" +msgstr "" +"ã€èƒŒæ™¯ã‚’無視ã™ã‚‹ã€‘\n" +"ã“ã‚Œã¯ãŸã„ã¦ã„ã®å ´åˆèƒŒæ™¯ã«ä½¿ã‚ã‚Œã¦ã„ã‚‹ã€ç´°é•·ã„テクスãƒãƒ£ã‚’フィルタã®å¯¾è±¡ã‹ã‚‰å¤–ã™ã‚ªãƒ—ションã§ã™ã€‚\n" +"テクスãƒãƒ£ãƒ¡ãƒ¢ãƒªã®ä½¿ç”¨é‡ã¨ãƒ‘フォーマンスを大ãã改善ã—ã¾ã™ã€‚\n" +"[推奨設定: 有効 (ã€ä¿å­˜ç”¨ã€‘モード時ã¯ç„¡åŠ¹)]" + +#: Config.cpp:636 +msgid "" +"Texture compression:\n" +"Textures will be compressed using selected texture compression method.\n" +"The overall compression ratio is about 1/6 for FXT1 and 1/4 for S3TC.\n" +"In addition to saving space on the texture cache,\n" +"the space occupied on the GFX hardware's texture RAM,\n" +"by the enhanced textures, will be greatly reduced.\n" +"This minimizes texture RAM usage,\n" +"decreasing the number of texture swaps to the GFX hardware leading to performance gains.\n" +"However, due to the nature of lossy compression of FXT1 and S3TC, using this option can sometimes lead to quality degradation of small size textures and color banding of gradient colored textures.\n" +"[Recommended: off]" +msgstr "" +"ã€ãƒ†ã‚¯ã‚¹ãƒãƒ£åœ§ç¸®ã‚’有効ã«ã™ã‚‹ã€‘\n" +"有効ã«ã™ã‚‹ã¨ã€ãƒ†ã‚¯ã‚¹ãƒãƒ£ãŒé¸æŠžã•ã‚ŒãŸæ–¹å¼ã«ã‚ˆã£ã¦åœ§ç¸®ã•ã‚Œã¾ã™ã€‚\n" +"FXT1ã§ã¯6分ã®1ã€S3TCã§ã¯4分ã®1程度ã¨ãªã‚‹ã§ã—ょã†ã€‚\n" +"テクスãƒãƒ£ã‚­ãƒ£ãƒƒã‚·ãƒ¥ã‚’è¡Œã†ã“ã¨ã§å®¹é‡ã‚‚抑ãˆã‚‰ã‚Œã€ã¾ãŸãƒ•ã‚£ãƒ«ã‚¿ãƒªãƒ³ã‚°ã•ã‚ŒãŸãƒ†ã‚¯ã‚¹ãƒãƒ£ã«ã‚ˆã£ã¦ã€ãƒ“デオカードã®ãƒ†ã‚¯ã‚¹ãƒãƒ£RAM使用é‡ã‚‚削減ã•ã‚Œã¾ã™ã€‚\n" +"テクスãƒãƒ£RAM使用é‡ã‚’最å°é™ã«ã™ã‚‹ã“ã¨ã¯ã¾ãŸã€ãƒ†ã‚¯ã‚¹ãƒãƒ£ã‚¹ãƒ¯ãƒƒãƒ”ングも起ã“ã‚Šã«ãããªã‚Šã€ãƒ“デオカード性能ã¯å‘上ã—ã¾ã™ã€‚\n" +"ã—ã‹ã—ãªãŒã‚‰ã€FXT1ã¨S3TCã®éžå¯é€†åœ§ç¸®ã¨ã„ã†æ€§è³ªã®ãŸã‚ã«ã€æ™‚々å°ã•ãªãƒ†ã‚¯ã‚¹ãƒãƒ£ã®å“質ãŒæ‚ªåŒ–ã—ãŸã‚Šã€ã‚«ãƒ©ãƒ¼ãƒãƒ³ãƒ‡ã‚£ãƒ³ã‚°ãŒç™ºç”Ÿã—ãŸã‚Šã™ã‚‹å ´åˆãŒã‚ã‚Šã¾ã™ã€‚\n" +"[推奨設定: 無効]" + +#: Config.cpp:640 +msgid "" +"Compress texture cache:\n" +"Memory will be compressed so that more textures can be held in the texture cache.\n" +"The compression ratio varies with each texture,\n" +"but 1/5 of the original size would be a modest approximation.\n" +"They will be decompressed on-the-fly, before being downloaded to the gfx hardware.\n" +"This option will still help save memory space even when using texture compression.\n" +"[Recommended: on]" +msgstr "" +"ã€ãƒ†ã‚¯ã‚¹ãƒãƒ£ã‚­ãƒ£ãƒƒã‚·ãƒ¥ã‚’圧縮ã™ã‚‹ã€‘\n" +"有効ã«ã™ã‚‹ã¨ãƒ¡ãƒ¢ãƒªã«ã‚ˆã‚Šä¿æŒã—ã¦ã„るテクスãƒãƒ£ã‚­ãƒ£ãƒƒã‚·ãƒ¥å†…部ã®ã‚­ãƒ£ãƒƒã‚·ãƒ¥ã‚’圧縮ã—ã¾ã™ã€‚\n" +"テクスãƒãƒ£ã«ã‚ˆã£ã¦åœ§ç¸®çŽ‡ã¯é•ã„ã¾ã™ãŒã€æŽ§ãˆã‚ã«è¦‹ã¦ã‚‚5分ã®1程度ã®ã‚µã‚¤ã‚ºã«ãªã‚‹ã§ã—ょã†ã€‚\n" +"圧縮ã•ã‚ŒãŸãƒ†ã‚¯ã‚¹ãƒãƒ£ã‚­ãƒ£ãƒƒã‚·ãƒ¥ã¯ã€ãƒ“デオカードã«é€ã‚‰ã‚Œã‚‹å‰ã«ã‚ªãƒ³ã‚¶ãƒ•ãƒ©ã‚¤ã§è§£å‡ã•ã‚Œã¾ã™ã€‚\n" +"ã“ã®ã‚ªãƒ—ションã¯åœ§ç¸®ã•ã‚ŒãŸãƒ†ã‚¯ã‚¹ãƒãƒ£ã‚­ãƒ£ãƒƒã‚·ãƒ¥ã‚’使用ã™ã‚‹éš›ã®ãƒ¡ãƒ¢ãƒªä½¿ç”¨é‡ã®å‰Šæ¸›ã«å½¹ç«‹ã¤ã§ã—ょã†ã€‚\n" +"[推奨設定: 有効]" + +#: Config.cpp:642 +msgid "" +"Hi-res pack format:\n" +"Choose which method is to be used for loading Hi-res texture packs.\n" +"Only Rice's format is available currently.\n" +"Leave on \"None\" if you will not be needing to load hi-res packs.\n" +"[Recommended: Rice's format. Default: \"None\"]" +msgstr "" +"フォーマット設定\n" +"ãƒã‚¤ãƒ¬ã‚¾ãƒ‘ックを読ã¿è¾¼ã‚€ã®ã«ä½¿ç”¨ã™ã‚‹æ–¹å¼ã‚’é¸æŠžã§ãã¾ã™ã€‚\n" +"ç¾åœ¨ã¯ Rice フォーマット ã®ã¿ãŒé¸æŠžå¯èƒ½ã§ã™ã€‚\n" +"ãƒã‚¤ãƒ¬ã‚¾ãƒ‘ックを読ã¿è¾¼ã‚€å¿…è¦ãŒãªã„時ã¯ã€ç„¡ã—】ã«ã—ã¦ãŠãã¾ã—ょã†ã€‚\n" +"[推奨設定: Rice フォーマット (デフォルト:無ã—)]" + +#: Config.cpp:646 +msgid "" +"Tile textures:\n" +"When on, wide texture will be split on several tiles to fit in one 256-width texture.\n" +"This tiled texture takes much less video memory space and thus overall performance will increase.\n" +"However, corresponding polygons must be split too, and this is not polished yet\n" +"- various issues are possible, including black lines and polygons distortions.\n" +"[Recommended: off]" +msgstr "" +"ã€ãƒ†ã‚¯ã‚¹ãƒãƒ£ã‚’タイル状ã«åˆ†å‰²ã™ã‚‹ã€‘\n" +"有効ã«ã™ã‚‹ã¨ã€å¤§ããªãƒ†ã‚¯ã‚¹ãƒãƒ£ã‚’256pxå¹…ã®ã‚¿ã‚¤ãƒ«çŠ¶ã®ãƒ†ã‚¯ã‚¹ãƒãƒ£ã¨ã—ã¦åˆ†å‰²ã—ã¾ã™ã€‚\n" +"ã“ã‚Œã«ã‚ˆã‚Šãƒ“デオメモリ使用é‡ãŒå‰Šæ¸›ã•ã‚Œã€ãƒ‘フォーマンスもå‘上ã—ã¾ã™ã€‚\n" +"ã—ã‹ã—ã€å¤šè§’形をも分割ã—ãªã‘ã‚Œã°ãªã‚‰ãšã€ã“ã®æ©Ÿèƒ½ã«ã¤ã„ã¦ã¯ã¾ã ã‚ã¾ã‚Šæ´—ç·´ã•ã‚Œã¦ã„ã¾ã›ã‚“。\n" +"ä¸è¦ãªé»’ç·šãŒå‡ºãŸã‚Šå¤šè§’å½¢ã®ãƒãƒªã‚´ãƒ³ãŒã²ãšã‚“ã§ã—ã¾ã†ãªã©ã€æ§˜ã€…ãªå•é¡Œã‚’ã¯ã‚‰ã‚“ã§ã„ã¾ã™ã€‚\n" +"[推奨設定: 無効]" + +#: Config.cpp:648 +msgid "" +"Force 16bpp textures:\n" +"The color of the textures will be reduced to 16bpp.\n" +"This is another space saver and performance enhancer.\n" +"This halves the space used on the texture cache and the GFX hardware's texture RAM.\n" +"Color reduction is done so that the original quality is preserved as much as possible.\n" +"Depending on the texture, this usually is hardly noticeable.\n" +"Sometimes though, it can be: skies are a good example.\n" +"[Recommended: off]" +msgstr "" +"ã€å¼·åˆ¶16ビットテクスãƒãƒ£ã€‘\n" +"有効ã«ã™ã‚‹ã¨ãƒ†ã‚¯ã‚¹ãƒãƒ£ã®è‰²æ•°ã‚’16ビットã«å¤‰æ›´ã—ã¾ã™ã€‚\n" +"ã“ã‚Œã«ã‚ˆã‚Šãƒ†ã‚¯ã‚¹ãƒãƒ£ã‚­ãƒ£ãƒƒã‚·ãƒ¥ã®ã‚µã‚¤ã‚ºã¨ãƒ“デオカードã®ãƒ†ã‚¯ã‚¹ãƒãƒ£RAM使用é‡ãŒåŠåˆ†ã«ãªã‚Šã¾ã™ã€‚\n" +"減色ã¯å‡ºæ¥ã‚‹é™ã‚Šå…ƒã®å“質をä¿ã£ãŸã¾ã¾è¡Œã‚ã‚Œã€ãƒ†ã‚¯ã‚¹ãƒãƒ£ã«ã‚‚よりã¾ã™ãŒã€ã»ã¨ã‚“ã©ã®å ´åˆç›®ç«‹ã¤ã“ã¨ã¯ãªã„ã§ã—ょã†ã€‚\n" +"ã¨ã¯è¨€ãˆã€ã€Œé’空ã€ã®ãƒ†ã‚¯ã‚¹ãƒãƒ£ãªã©ã€ç›®ç«‹ã¤ä¾‹ã‚‚ã‚ã‚Šã¾ã™ã€‚\n" +"[推奨設定: 無効]" + +#: Config.cpp:650 +msgid "" +"Texture dumping mode:\n" +"In this mode, you have that ability to dump textures on screen to the appropriate folder.\n" +"You can also reload textures while the game is running to see how they look instantly - big time saver!\n" +"\n" +"Hotkeys: \"R\" reloads hires textures from the texture pack - \"D\" toggles texture dumps on/off." +msgstr "" +"ã€ãƒ†ã‚¯ã‚¹ãƒãƒ£ãƒ€ãƒ³ãƒ—ï¼ç·¨é›†ãƒ¢ãƒ¼ãƒ‰ã€‘\n" +"有効ã«ã™ã‚‹ã¨è¡¨ç¤ºä¸­ã®ç”»é¢ã‹ã‚‰ãƒ†ã‚¯ã‚¹ãƒãƒ£ã‚’ダンプã—ã¦å‰²ã‚Šå½“ã¦ã‚‰ã‚ŒãŸãƒ•ã‚©ãƒ«ãƒ€ã«ä¿å­˜ã™ã‚‹æ©Ÿèƒ½ãŒä½¿ç”¨ã§ãるよã†ã«ãªã‚Šã¾ã™ã€‚\n" +"ã“ã®æ©Ÿèƒ½ã§ã‚²ãƒ¼ãƒ å®Ÿè¡Œä¸­ã«ãƒ†ã‚¯ã‚¹ãƒãƒ£ã‚’å†èª­è¾¼ã—ã¦ãã‚ŒãŒã©ã®ã‚ˆã†ã«è¦‹ãˆã‚‹ã‹ã‚’ã™ãã«ç¢ºèªã§ãã¾ã™ã€‚大ããªæ™‚é–“ã®ç¯€ç´„ã«ãªã‚Šã¾ã™ï¼\n" +"\n" +"ホットキー: \"R\" テクスãƒãƒ£ãƒ‘ックã‹ã‚‰ãƒã‚¤ãƒ¬ã‚¾ãƒ†ã‚¯ã‚¹ãƒãƒ£ã‚’å†èª­è¾¼ã™ã‚‹ã€‚ \"D\" テクスãƒãƒ£ãƒ€ãƒ³ãƒ—ã®æœ‰åŠ¹ï¼ç„¡åŠ¹åˆ‡ã‚Šæ›¿ãˆã€‚" + +#: Config.cpp:652 +msgid "" +"Alternative CRC calculation:\n" +"This option enables emulation of a palette CRC calculation bug in RiceVideo.\n" +"If some textures are not loaded, try to set this option on/off.\n" +"[Recommended: texture pack dependant, mostly on]" +msgstr "" +"ã€åˆ¥ã®æ–¹æ³•ã§CRC計算処ç†ã‚’è¡Œã†ã€‘\n" +"有効ã«ã™ã‚‹ã¨ RiceVideo 上ã§ã®ãƒ‘レットCRC計算処ç†ã®ãƒã‚°ã‚’エミュレートã—ã¾ã™ã€‚\n" +"テクスãƒãƒ£ãŒæ­£ã—ãロードã•ã‚Œãªã„時ã«ã“ã®ã‚ªãƒ—ションã®æœ‰åŠ¹ï¼ç„¡åŠ¹ã‚’切り替ãˆã‚‹ã¨æ”¹å–„ã™ã‚‹å ´åˆãŒã‚ã‚Šã¾ã™ã€‚\n" +"[推奨: テクスãƒãƒ£ãƒ‘ックã«ä¾å­˜ã€ã»ã¨ã‚“ã©ã®å ´åˆæœ‰åŠ¹]" + +#: Config.cpp:657 +msgid "" +"Compress texture cache:\n" +"When game started, plugin loads all its hi-resolution textures into PC memory.\n" +"Since hi-resolution textures are usually large, the whole pack can take hundreds megabytes of memory.\n" +"Cache compression allows save memory space greatly.\n" +"Textures will be decompressed on-the-fly, before being downloaded to the gfx hardware.\n" +"This option will still help save memory space even when using texture compression.\n" +"[Recommended: on]" +msgstr "" +"ã€ãƒ†ã‚¯ã‚¹ãƒãƒ£ã‚­ãƒ£ãƒƒã‚·ãƒ¥ã‚’圧縮ã™ã‚‹ã€‘\n" +"プラグインã¯ã‚²ãƒ¼ãƒ èµ·å‹•ã¨åŒæ™‚ã«ã€å…¨ã¦ã®ãƒã‚¤ãƒ¬ã‚¾ãƒ†ã‚¯ã‚¹ãƒãƒ£ã‚’メモリã«èª­ã¿è¾¼ã¿ã¾ã™ã€‚\n" +"多ãã®å ´åˆãƒã‚¤ãƒ¬ã‚¾ãƒ†ã‚¯ã‚¹ãƒãƒ£ã¯ã‚µã‚¤ã‚ºãŒå¤§ãã„ã®ã§ã€ãƒ‘ック全体ã¨ã—ã¦æ•°ç™¾MBã‚‚ã®ãƒ¡ãƒ¢ãƒªãŒä½¿ã‚れるã“ã¨ã«ãªã£ã¦ã—ã¾ã„ã¾ã™ã€‚\n" +"キャッシュã®åœ§ç¸®ã§ã“ã†ã—ãŸãƒ¡ãƒ¢ãƒªä½¿ç”¨é‡ã‚’大ãã削減ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚\n" +"圧縮ã•ã‚ŒãŸãƒ†ã‚¯ã‚¹ãƒãƒ£ã‚­ãƒ£ãƒƒã‚·ãƒ¥ã¯ã€ãƒ“デオカードã«é€ã‚‰ã‚Œã‚‹å‰ã«ã‚ªãƒ³ã‚¶ãƒ•ãƒ©ã‚¤ã§è§£å‡ã•ã‚Œã¾ã™ã€‚\n" +"ã“ã®ã‚ªãƒ—ションã¯åœ§ç¸®ã•ã‚ŒãŸãƒ†ã‚¯ã‚¹ãƒãƒ£ã‚­ãƒ£ãƒƒã‚·ãƒ¥ã‚’使用ã™ã‚‹éš›ã®ãƒ¡ãƒ¢ãƒªä½¿ç”¨é‡ã®å‰Šæ¸›ã«å½¹ç«‹ã¤ã§ã—ょã†ã€‚\n" +"[推奨設定: 有効]" + +#: Config.cpp:659 +msgid "" +"Use Alpha channel fully:\n" +"When this option is off, 16bit rgba textures will be loaded using RiceVideo style\n" +"- with 1bit for alpha channel.\n" +"When it is on, GlideHQ will check, how alpha channel is used by the hires texture,\n" +"and select most appropriate format for it.\n" +"This gives texture designers freedom to play with alpha, as they need,\n" +"regardless of format of original N64 texture.\n" +"For older and badly designed texture packs it can cause unwanted black borders.\n" +"[Recommended: texture pack dependant]" +msgstr "" +"ã€é«˜ç²¾åº¦ã‚¢ãƒ«ãƒ•ã‚¡ãƒãƒ£ãƒ³ãƒãƒ«ã‚’使用ã™ã‚‹ã€‘\n" +"無効ã®å ´åˆã€16ビットã®RGBAテクスãƒãƒ£ã¯ RiceVideo å½¢å¼ï¼ˆ1ビットをアルファãƒãƒ£ãƒ³ãƒãƒ«ä½¿ç”¨ï¼‰ã¨ã—ã¦èª­ã¿è¾¼ã¾ã‚Œã¾ã™ã€‚\n" +"有効ã®å ´åˆã€GlideHQ ã¯ãƒã‚¤ãƒ¬ã‚¾ãƒ†ã‚¯ã‚¹ãƒãƒ£ãŒã©ã®ã‚ˆã†ã«ã‚¢ãƒ«ãƒ•ã‚¡ãƒãƒ£ãƒ³ãƒãƒ«ã‚’使用ã—ã¦ã„ã‚‹ã‹ã‚’検出ã—ã¦ãã®ãƒ•ã‚©ãƒ¼ãƒžãƒƒãƒˆã«åˆã‚ã›ã‚‹ã‚ˆã†ã«ã—ã¾ã™ã€‚\n" +"ã“ã‚Œã¯ãƒ†ã‚¯ã‚¹ãƒãƒ£ãƒ‡ã‚¶ã‚¤ãƒŠãƒ¼ã«ã€N64オリジナルã®ãƒ•ã‚©ãƒ¼ãƒžãƒƒãƒˆã«é–¢ä¿‚ãªãã€è‡ªç”±ã«ã‚¢ãƒ«ãƒ•ã‚¡ãƒãƒ£ãƒ³ãƒãƒ«ã‚’使用ã•ã›ã‚‹ã‚‚ã®ã§ã™ã€‚\n" +"å¤ã‹ã£ãŸã‚Šã§ãã®æ‚ªã„テクスãƒãƒ£ãƒ‘ックã§ã¯é»’æž ãŒè¡¨ç¤ºã•ã‚Œã‚‹å ´åˆãŒã‚ã‚Šã¾ã™ã€‚\n" +"[推奨設定: テクスãƒãƒ£ãƒ‘ックã«ä¾å­˜]" + +#: Config.cpp:662 +msgid "" +"Save texture cache to HD:\n" +"\n" +"For enhanced textures cache:\n" +"This will save all previously loaded and enhanced textures to HD.\n" +"So upon next game launch, all the textures will be instantly loaded, resulting in smoother performance.\n" +"\n" +"For high-resolution textures cache:\n" +"After creation, loading hi-res texture will take only a few seconds upon game launch,\n" +"as opposed to the 5 -60 seconds a pack can take to load without this cache file.\n" +"The only downside here is upon any changes to the pack, the cache file will need to be manually deleted.\n" +"\n" +"Saved cache files go into a folder called \"Cache\" within the Plugins folder.\n" +"\n" +"[Highly Recommended: on]" +msgstr "" +"ã€ãƒ†ã‚¯ã‚¹ãƒãƒ£ã‚­ãƒ£ãƒƒã‚·ãƒ¥ã‚’HDDã«ä¿å­˜ã™ã‚‹ã€‘\n" +"\n" +"※ フィルタリングã•ã‚ŒãŸãƒ†ã‚¯ã‚¹ãƒãƒ£ã®ã‚­ãƒ£ãƒƒã‚·ãƒ¥ã®å ´åˆ\n" +"有効ã«ã™ã‚‹ã¨ã™ã§ã«èª­ã¿è¾¼ã¾ã‚ŒãŸãƒ†ã‚¯ã‚¹ãƒãƒ£ã¨ãƒ•ã‚£ãƒ«ã‚¿ãƒªãƒ³ã‚°ã•ã‚ŒãŸãƒ†ã‚¯ã‚¹ãƒãƒ£ãŒHDDã«ä¿å­˜ã•ã‚Œã¾ã™ã€‚\n" +"ã“ã‚Œã«ã‚ˆã‚Šæ¬¡ã‹ã‚‰ã®ã‚²ãƒ¼ãƒ èµ·å‹•ã§ã‚­ãƒ£ãƒƒã‚·ãƒ¥ã®èª­ã¿è¾¼ã¿ãŒé«˜é€ŸåŒ–ã•ã‚Œã‚‹ãŸã‚ã€ãƒ‘フォーマンスãŒå‘上ã—ã¾ã™ã€‚\n" +"\n" +"※ ãƒã‚¤ãƒ¬ã‚¾ãƒ†ã‚¯ã‚¹ãƒãƒ£ã®ã‚­ãƒ£ãƒƒã‚·ãƒ¥ã®å ´åˆ\n" +"キャッシュä¿å­˜å¾Œã€ã‚²ãƒ¼ãƒ èµ·å‹•æ™‚ã®ãƒã‚¤ãƒ¬ã‚¾ãƒ†ã‚¯ã‚¹ãƒãƒ£ã®èª­ã¿è¾¼ã¿ãŒã€æ•°ç§’ã§å®Œäº†ã™ã‚‹ã‚ˆã†ã«ãªã‚Šã¾ã™ã€‚\n" +"(キャッシュãªã—ã ã¨ä¸€ã¤ã®ãƒ‘ックã§5~60秒ã‹ã‹ã‚‹ã€‚)\n" +"唯一ã®æ¬ ç‚¹ã¯ã€ãƒ†ã‚¯ã‚¹ãƒãƒ£ãƒ‘ックã«ä½•ã‹ã—らã®å¤‰æ›´ãŒã‚ã£ãŸå ´åˆã€ã‚­ãƒ£ãƒƒã‚·ãƒ¥ãƒ•ã‚¡ã‚¤ãƒ«ã‚’手動ã§å‰Šé™¤ã—ãªã‘ã‚Œã°ãªã‚‰ãªã„ã¨ã„ã†ã“ã¨ã§ã™ã€‚\n" +"\n" +"キャッシュファイルã¯ãƒ—ラグインフォルダ内ã®ã€ŽCacheã€ãƒ•ã‚©ãƒ«ãƒ€ã«ä¿å­˜ã•ã‚Œã¾ã™ã€‚\n" +"\n" +"[推奨設定: 有効 (å¼·ã推奨ã—ã¾ã™)]" + +#: Config.cpp:685 +msgid "Debug" +msgstr "デãƒãƒƒã‚°" + +#: Config.cpp:686 +msgid "" +"Autodetect Microcode\n" +"If this option is checked, the microcode of the game\n" +"will be detected automatically from the INI, and\n" +"therefore it will not need to be set in this\n" +"configuration dialog.\n" +"[Recommended: on]" +msgstr "" +"ã€ãƒžã‚¤ã‚¯ãƒ­ã‚³ãƒ¼ãƒ‰è‡ªå‹•æ¤œå‡ºã€‘\n" +"ゲーム別ã®ãƒžã‚¤ã‚¯ãƒ­ã‚³ãƒ¼ãƒ‰ã‚’INIã‚’å…ƒã«è‡ªå‹•æ¤œå‡ºã—ã¾ã™ã€‚\n" +"[推奨設定: 有効]" + +#: Config.cpp:688 +msgid "" +"Force Microcode\n" +"This option ONLY has an effect if Autodetect Microcode\n" +"is unchecked, the crc from the game could not be\n" +"found in the INI, OR after the game has already started\n" +"running. In any of those three cases, this will\n" +"select the microcode to use\n" +"[Recommended: any, turn on Autodetect Microcode]" +msgstr "" + +#: Config.cpp:692 +msgid "" +"Wireframe\n" +"This option, when checked, makes it so that the plugin will draw only the\n" +"outlines of objects. The colors specified in the combo box to the right\n" +"determines the color that the wireframes show up as.\n" +"[Recommended: off]" +msgstr "" +"ã€ãƒ¯ã‚¤ãƒ¤ãƒ¼ãƒ•ãƒ¬ãƒ¼ãƒ ã‚’使用ã™ã‚‹ã€‘\n" +"有効ã«ã™ã‚‹ã¨ãƒ—ラグインã¯ã‚ªãƒ–ジェクトã®è¼ªéƒ­ç·šã ã‘ã‚’æ写ã™ã‚‹ã‚ˆã†ã«ã—ã¾ã™ã€‚\n" +"輪郭線ã®è‰²ã¯å³ã®ã‚³ãƒ³ãƒœãƒœãƒƒã‚¯ã‚¹ã§æŒ‡å®šã•ã‚ŒãŸã‚‚ã®ã«ãªã‚Šã¾ã™ã€‚\n" +"[推奨設定: 無効]" + +#: Config.cpp:694 +msgid "" +"Wireframe Colors\n" +"This selects the colors to use for the wireframes (if wireframe mode is enabled).\n" +"There are 3 modes:\n" +"* Original colors - draw exactly as it would normally, textures and all, only in wireframes.\n" +"* Vertex colors - use the colors specified in the vertices to draw the wireframes with.\n" +"* Red only - use a constant red color to draw the wireframes.\n" +"[Recommended: Vertex colors]" +msgstr "" + +#: Config.cpp:696 +msgid "" +"Log to RDP.txt\n" +"RECOMMENDED FOR DEBUGGING ONLY - this option, when checked, will log EVERY SINGLE\n" +"COMMAND the plugin processes to a file called RDP.txt in the current directory.\n" +"This is incredibly slow, so I recommend keeping it disabled.\n" +"[Recommended: off]" +msgstr "" + +#: Config.cpp:698 +msgid "" +"Unknown combiners as red\n" +"Objects that use an unimplemented combine mode will show up as red instead of\n" +"assuming texture with full alpha. Disable this option to remove the red stuff\n" +"and at least have a guess at the correct combine mode.\n" +"[Recommended: off]" +msgstr "" + +#: Config.cpp:700 +msgid "" +"Log clear every frame\n" +"RECOMMENDED FOR DEBUGGING ONLY - this option has no effect unless 'Log to RDP.txt'\n" +"is checked. This will make it so that the log, RDP.txt, will be cleared at the\n" +"beginning of every frame.\n" +"[Recommended: off]" +msgstr "" + +#: Config.cpp:702 +msgid "" +"Log unknown combiners\n" +"RECOMMENDED FOR DEBUGGING ONLY - when checked, this option will cause every\n" +"unimplemented combiner drawn to be logged to a file called Unimp.txt in the\n" +"current directory. This becomes slow when there are unimplemented combiners\n" +"on the screen, so I recommend keeping it disabled.\n" +"[Recommended: off]" +msgstr "" + +#: Config.cpp:704 +msgid "" +"Run and log in window\n" +"RECOMMENDED FOR DEBUGGING ONLY - this option will make it so that the plugin will\n" +"still process dlists in windowed mode. This allows for logging to occur while not\n" +"in fullscreen, possibly allowing you to debug a crash.\n" +"[Recommended: off]" +msgstr "" + +#: Config.cpp:706 +msgid "" +"Clear unknown combiner log every frame\n" +"RECOMMENDED FOR DEBUGGING ONLY - this option works much like 'Log clear every frame'\n" +"except it clears the combiner log (Unimp.txt) instead of RDP.txt at the\n" +"beginning of each frame. Again, this option has no effect if 'combiner logging' is disabled.\n" +"[Recommended: off]" +msgstr "" + +#: Config.cpp:709 +msgid "" +"Bilinear filter texture cache\n" +"RECOMMENDED FOR DEBUGGING ONLY - when checked, this option will make the graphical\n" +"debugger texture cache use bilinear filtering as opposed to point-sampled filtering,\n" +"which it will use otherwise. See 'Filtering mode' for descriptions of bilinear and\n" +"point-sampled filtering.\n" +"[Recommended: off]" +msgstr "" + +#: Config.cpp:1104 +msgid "Glide64 settings" +msgstr "Glide64 ã®è¨­å®š" + +#: Config.cpp:1293 +msgid "About Glide64" +msgstr "Glide64 ã«ã¤ã„ã¦" + +#: Config.cpp:1326 +msgid "authors:" +msgstr "開発ãƒãƒ¼ãƒ " + +#: Config.cpp:1330 +msgid "" +"Dave2001. Original author and former main developer.\n" +"He founded Glide64 project on Dec. 29th, 2001.\n" +"Left the project at fall of 2002.\n" +msgstr "" +"Dave2001. Original author and former main developer.\n" +"He founded Glide64 project on Dec. 29th, 2001.\n" +"Left the project at fall of 2002.\n" + +#: Config.cpp:1336 +msgid "" +"Gugaman. Developer. Joined the project at winter 2002\n" +" and left it at fall 2002." +msgstr "" +"Gugaman. Developer. Joined the project at winter 2002\n" +" and left it at fall 2002." + +#: Config.cpp:1342 +msgid "" +"Sergey 'Gonetz' Lipski. Joined the project at winter 2002.\n" +"Main developer since fall of 2002." +msgstr "" +"Sergey 'Gonetz' Lipski. Joined the project at winter 2002.\n" +"Main developer since fall of 2002." + +#: Config.cpp:1347 +msgid "Hiroshi 'KoolSmoky' Morii, Joined the project in 2007. " +msgstr "Hiroshi 'KoolSmoky' Morii, Joined the project in 2007. " + +#: Config.cpp:1350 +msgid "Glitch64 (the wrapper) authors:" +msgstr "Glitch64 (the wrapper) 開発ãƒãƒ¼ãƒ " + +#: Config.cpp:1374 +msgid "GlideHQ author:" +msgstr "GlideHQ 作者:" + +#: Config.cpp:1381 +msgid "beta tester:" +msgstr "ベータテスター:" + +#: Config.cpp:1388 +msgid "" +"special thanks to:\n" +" Orkin, Rice, Daniel Borca, Legend.\n" +"Thanks to EmuXHaven for hosting my site:\n" +"http://glide64.emuxhaven.net\n" +msgstr "" +"スペシャルサンクス:\n" +" Orkin, Rice, Daniel Borca, Legend.\n" +"Thanks to EmuXHaven for hosting my site:\n" +"http://glide64.emuxhaven.net\n" + diff --git a/Source/Glide64/Internalization/Glide64_ru_RU.po b/Source/Glide64/Internalization/Glide64_ru_RU.po new file mode 100644 index 000000000..3e7fc2647 --- /dev/null +++ b/Source/Glide64/Internalization/Glide64_ru_RU.po @@ -0,0 +1,1315 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2011-12-19 17:29+0700\n" +"PO-Revision-Date: 2011-12-19 17:56+0700\n" +"Last-Translator: Navitel \n" +"Language-Team: \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: Config.cpp:64 +msgid "Rendering" +msgstr "Рендеринг" + +#: Config.cpp:65 +msgid "Other" +msgstr "Другое" + +#: Config.cpp:66 +msgid "Speed" +msgstr "СкороÑÑ‚ÑŒ" + +#: Config.cpp:67 +msgid "Time" +msgstr "ВремÑ" + +#: Config.cpp:68 +msgid "On screen display" +msgstr "Ð­ÐºÑ€Ð°Ð½Ð½Ð°Ñ Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ" + +#: Config.cpp:69 +msgid "OpenGL settings" +msgstr "ÐаÑтройки OpenGL" + +#: Config.cpp:70 +#: Config.cpp:137 +msgid "Frame buffer emulation" +msgstr "ЭмулÑÑ†Ð¸Ñ Ð±ÑƒÑ„ÐµÑ€Ð° кадра" + +#: Config.cpp:71 +msgid "" +"Windowed or\n" +"3dfx card resolution:" +msgstr "" +"Разрешение окна\n" +"или карты 3dfx:" + +#: Config.cpp:99 +msgid "Vertical sync" +msgstr "ÐšÐ°Ð´Ñ€Ð¾Ð²Ð°Ñ ÑинхронизациÑ" + +#: Config.cpp:100 +msgid "Show advanced emulation options" +msgstr "Показывать раÑширенные наÑтройки ÑмулÑции" + +#: Config.cpp:101 +msgid "Show texture enhancement options" +msgstr "Показывать наÑтройки ÑƒÐ»ÑƒÑ‡ÑˆÐµÐ½Ð¸Ñ Ñ‚ÐµÐºÑтур" + +#: Config.cpp:102 +msgid "Screenshot format:" +msgstr "Формат Ñкриншота:" + +#: Config.cpp:105 +msgid "Language: " +msgstr "Язык: " + +#: Config.cpp:106 +msgid "LANGUAGE_NAME" +msgstr "РуÑÑкий" + +#: Config.cpp:112 +msgid "FPS counter" +msgstr "Счётчик FPS" + +#: Config.cpp:113 +msgid "VI/s counter" +msgstr "Счётчик VI/s" + +#: Config.cpp:114 +#, c-format +msgid "% speed" +msgstr "СкороÑÑ‚ÑŒ в %" + +#: Config.cpp:115 +msgid "Clock enabled" +msgstr "Показывать чаÑÑ‹" + +#: Config.cpp:116 +msgid "Clock is 24-hour" +msgstr "24 чаÑовой формат" + +#: Config.cpp:117 +msgid "Transparent text background" +msgstr "Прозрачный фон текÑта" + +#: Config.cpp:118 +msgid "" +"Full screen\n" +"resolution:" +msgstr "" +"ПолноÑкранное\n" +"разрешение:" + +#: Config.cpp:121 +msgid "Anisotropic filtering" +msgstr "ÐÐ½Ð¸Ð·Ð¾Ñ‚Ñ€Ð¾Ð¿Ð½Ð°Ñ Ñ„Ð¸Ð»ÑŒÑ‚Ñ€Ð°Ñ†Ð¸Ñ" + +#: Config.cpp:122 +msgid "Autodetect " +msgstr "Ðвто " + +#: Config.cpp:123 +msgid "VRAM size" +msgstr "Размер видеопамÑти" + +#: Config.cpp:125 +msgid "Mb" +msgstr "Мб" + +#: Config.cpp:126 +msgid "Use frame buffer objects" +msgstr "ИÑпользовать frame buffer objects" + +#: Config.cpp:133 +msgid "Current game emulation settings. Change with care!" +msgstr "ÐаÑтройки ÑмулÑции текущей игры. МенÑÑ‚ÑŒ оÑтрожно!" + +#: Config.cpp:135 +msgid "Default emulation settings. Not recommended to change!" +msgstr "ÐаÑтройки ÑмулÑции по умолчанию. МенÑÑ‚ÑŒ не рекомендуетÑÑ!" + +#: Config.cpp:136 +msgid "General options" +msgstr "ОÑновные наÑтройки" + +#: Config.cpp:138 +msgid "Depth buffer emulation" +msgstr "ЭмулÑÑ†Ð¸Ñ Ð±ÑƒÑ„ÐµÑ€Ð° глубины" + +#: Config.cpp:139 +msgid "Filtering mode:" +msgstr "" +"ФильтрациÑ\n" +"текÑтур:" + +#: Config.cpp:141 +msgid "Automatic" +msgstr "ÐвтоматичеÑкаÑ" + +#: Config.cpp:142 +msgid "Force Bilinear" +msgstr "Ð’Ñегда биллинейнаÑ" + +#: Config.cpp:143 +msgid "Force Point-sampled" +msgstr "Ð’Ñегда Point-sampled" + +#: Config.cpp:146 +msgid "Buffer swapping method:" +msgstr "" +"Метод Ñмены\n" +"буфера кадра:" + +#: Config.cpp:148 +msgid "Old" +msgstr "Старый" + +#: Config.cpp:149 +msgid "New" +msgstr "Ðовый" + +#: Config.cpp:150 +msgid "Hybrid" +msgstr "Гибридный" + +#: Config.cpp:153 +msgid "LOD calculation:" +msgstr "ВычиÑление LOD:" + +#: Config.cpp:155 +msgid "off" +msgstr "нет" + +#: Config.cpp:156 +msgid "fast" +msgstr "быÑтро" + +#: Config.cpp:157 +msgid "precise" +msgstr "точно" + +#: Config.cpp:160 +msgid "Aspect ratio:" +msgstr "Формат кадра:" + +#: Config.cpp:162 +msgid "4:3 (default)" +msgstr "4:3 (по умолчанию)" + +#: Config.cpp:163 +msgid "Force 16:9" +msgstr "Принудительно 16:9" + +#: Config.cpp:164 +msgid "Stretch" +msgstr "РаÑÑ‚Ñнуть" + +#: Config.cpp:165 +msgid "Original" +msgstr "Как в N64" + +#: Config.cpp:168 +msgid "Fog" +msgstr "Туман" + +#: Config.cpp:169 +msgid "Buffer clear on every frame" +msgstr "ОчиÑтка буфера каждого кадра" + +#: Config.cpp:170 +msgid "Enable frame buffer emulation" +msgstr "Включить ÑмулÑцию буфера кадра" + +#: Config.cpp:171 +msgid "Hardware frame buffer emulation" +msgstr "ÐÐ¿Ð¿Ð°Ñ€Ð°Ñ‚Ð½Ð°Ñ ÑмулÑÑ†Ð¸Ñ Ð±ÑƒÑ„ÐµÑ€Ð° кадра" + +#: Config.cpp:172 +msgid "Get frame buffer info" +msgstr "Давать информацию о буфере" + +#: Config.cpp:173 +msgid "Read every frame (slow!)" +msgstr "Считывать каждый кадр (медленно!)" + +#: Config.cpp:174 +msgid "Render N64 frame buffer as texture" +msgstr "Выводить буфер N64 как текÑтуру" + +#: Config.cpp:175 +msgid "Detect CPU write to the N64 frame buffer" +msgstr "ОпределÑÑ‚ÑŒ, что N64 CPU пишет в буфер" + +#: Config.cpp:176 +msgid "Software depth buffer rendering" +msgstr "Программный рендеринг буфера глубины" + +#: Config.cpp:200 +#: Config.cpp:619 +msgid "Texture enhancement" +msgstr "Улучшение текÑтур" + +#: Config.cpp:201 +msgid "Hi-resolution textures" +msgstr "ТекÑтуры выÑокого разрешениÑ" + +#: Config.cpp:202 +msgid "Common" +msgstr "Общие" + +#: Config.cpp:203 +msgid "Presets" +msgstr "ПредуÑтановки" + +#: Config.cpp:204 +#: Config.cpp:205 +msgid "Performance tweaks" +msgstr "Улучшение производительноÑти" + +#: Config.cpp:206 +msgid "Filter" +msgstr "Фильтр" + +#: Config.cpp:208 +#: Config.cpp:219 +#: Config.cpp:238 +msgid "None" +msgstr "Ðикакой" + +#: Config.cpp:209 +msgid "Smooth filtering 1" +msgstr "Сглаживающий фильтр 1" + +#: Config.cpp:210 +msgid "Smooth filtering 2" +msgstr "Сглаживающий фильтр 2" + +#: Config.cpp:211 +msgid "Smooth filtering 3" +msgstr "Сглаживающий фильтр 3" + +#: Config.cpp:212 +msgid "Smooth filtering 4" +msgstr "Сглаживающий фильтр 4" + +#: Config.cpp:213 +msgid "Sharp filtering 1" +msgstr " 1" + +#: Config.cpp:214 +msgid "Sharp filtering 2" +msgstr "Фильтр резкоÑти 2" + +#: Config.cpp:217 +msgid "Enhancement" +msgstr "Улучшение" + +#: Config.cpp:220 +msgid "Store" +msgstr "Хранить" + +#: Config.cpp:230 +msgid "Texture cache" +msgstr "ТекÑтурный кÑш" + +#: Config.cpp:232 +msgid "Mbytes" +msgstr "Мбайт" + +#: Config.cpp:233 +msgid "Ignore Backgrounds" +msgstr "Игнорировать текÑтуры фона" + +#: Config.cpp:234 +#: Config.cpp:245 +msgid "Apply texture compression" +msgstr "Применить компреÑÑию текÑтур" + +#: Config.cpp:235 +#: Config.cpp:246 +msgid "Compress texture cache" +msgstr "Сжимать текÑтурный кÑш" + +#: Config.cpp:236 +msgid "Format" +msgstr "Формат" + +#: Config.cpp:239 +msgid "Rice format" +msgstr "Формат Rice" + +#: Config.cpp:242 +msgid "Tile textures" +msgstr "Резать на тайлы" + +#: Config.cpp:243 +msgid "Force 16bpp textures" +msgstr "Приводить к 16 бит текÑтурам" + +#: Config.cpp:244 +msgid "Alternative CRC calculation" +msgstr "Ðльтернативное вычиÑление CRC" + +#: Config.cpp:247 +msgid "Use alpha channel fully" +msgstr "ИÑпользовать альфа канал полноÑтью" + +#: Config.cpp:248 +msgid "Texture dumping/editing mode" +msgstr "Дамп/редактирование текÑтур" + +#: Config.cpp:249 +msgid "Texture compression method" +msgstr "Метод компреÑÑии текÑтур" + +#: Config.cpp:255 +msgid "Save texture cache to hard disk" +msgstr "СохранÑÑ‚ÑŒ текÑтурный кÑш на диÑк" + +#: Config.cpp:256 +msgid "Best performance" +msgstr "ÐÐ°Ð¸Ð»ÑƒÑ‡ÑˆÐ°Ñ Ð¿Ñ€Ð¾Ð¸Ð·Ð²Ð¾Ð´Ð¸Ñ‚ÐµÐ»ÑŒÐ½Ð¾ÑÑ‚ÑŒ" + +#: Config.cpp:257 +msgid "Best texture quality" +msgstr "Ðаилучшее качеÑтво текÑтур" + +#: Config.cpp:263 +msgid "Developers settings" +msgstr "ÐаÑтройки разработчика" + +#: Config.cpp:264 +msgid "Debug/Misc" +msgstr "Отладка/Разное" + +#: Config.cpp:265 +msgid "Autodetect Microcode" +msgstr "Ðвтоопределение Микрокода" + +#: Config.cpp:266 +msgid "Force Microcode:" +msgstr "ФорÑировать Микрокод:" + +#: Config.cpp:279 +msgid "Wireframe using:" +msgstr "КаркаÑный режим:" + +#: Config.cpp:281 +msgid "Original colors" +msgstr "ИÑходные цвета" + +#: Config.cpp:282 +msgid "Vertex colors" +msgstr "Цвета вершин" + +#: Config.cpp:283 +msgid "Red only" +msgstr "Только краÑный" + +#: Config.cpp:286 +msgid "Log to rdp.txt (SLOW)" +msgstr "Лог в rdp.txt" + +#: Config.cpp:287 +msgid "Unknown combiners as red" +msgstr "КраÑные неизвеÑтные комбайнеры" + +#: Config.cpp:288 +msgid "Log clear every frame" +msgstr "ОчиÑтка лога каждый кадр" + +#: Config.cpp:289 +msgid "Combiner logging" +msgstr "Лог комбайнеров" + +#: Config.cpp:290 +msgid "Run (+log) in window" +msgstr "Лог в оконном режиме" + +#: Config.cpp:291 +msgid "Cmb. clear every frame" +msgstr "ОчиÑтка комб. лога каждый кадр" + +#: Config.cpp:292 +msgid "Error log (rdp_e.txt)" +msgstr "Лог ошибок (rdp_e.txt)" + +#: Config.cpp:293 +msgid "Bilinear filter texture cache" +msgstr "Ð‘Ð¸Ð»Ð¸Ð½ÐµÐ¹Ð½Ð°Ñ Ñ„Ð¸Ð»ÑŒÑ‚Ñ€Ð°Ñ†Ð¸Ñ Ñ‚ÐµÐºÑтурного кÑша" + +#: Config.cpp:325 +#: Config.cpp:546 +msgid " auto" +msgstr " авто" + +#: Config.cpp:382 +msgid "Please choose language:" +msgstr "ПожалуйÑта, выберите Ñзык:" + +#: Config.cpp:383 +msgid "Language" +msgstr "Язык" + +#: Config.cpp:390 +msgid "Press OK to change to " +msgstr "Ðажмите ОК Ð´Ð»Ñ Ñмены на " + +#: Config.cpp:486 +msgid "Basic settings" +msgstr "Базовые наÑтройки" + +#: Config.cpp:487 +msgid "" +"Resolution\n" +"This option selects the fullscreen resolution for 3dfx cards and windowed resolution for other cards\n" +"(note again that for 3dfx cards the plugin must be in fullscreen mode to see anything).\n" +"[Recommended: 640x480, 800x600, 1024x768]" +msgstr "" +"Разрешение Ñкрана\n" +"Эта Ð¾Ð¿Ñ†Ð¸Ñ ÑƒÑтанавливает полноÑкранное разрешение Ð´Ð»Ñ ÐºÐ°Ñ€Ñ‚ 3dfx и оконное разрешение Ð´Ð»Ñ Ð¾Ñтальных карт\n" +"(ещё раз заметим, что Ð´Ð»Ñ 3dfx карт плагин нужно перевеÑти в полноÑкранный режим)\n" +"[РекомендуетÑÑ: 640x480, 800x600, 1024x768]" + +#: Config.cpp:491 +msgid "" +"Vertical sync\n" +"This option will enable the vertical sync, which will prevent tearing.\n" +"Note: this option will ONLY have effect if vsync is set to \"Software Controlled\".\n" +msgstr "" +"ÐšÐ°Ð´Ñ€Ð¾Ð²Ð°Ñ ÑинхронизациÑ\n" +"Эта Ð¾Ð¿Ñ†Ð¸Ñ Ð²ÐºÐ»ÑŽÑ‡Ð°ÐµÑ‚ кадровую Ñинхронизацию.\n" +"Примечание: Ñта Ð¾Ð¿Ñ†Ð¸Ñ Ð¸Ð¼ÐµÐµÑ‚ Ñффект только еÑли vsync уÑтановлен в \"Software Controlled\".\n" + +#: Config.cpp:493 +msgid "Select a format, in which screen shots will be saved" +msgstr "Выберите формат, в котором будут ÑохранÑÑ‚ÑŒÑÑ Ñкриншоты." + +#: Config.cpp:500 +msgid "" +"Language select:\n" +"Press the button to invoke language selection dialog.\n" +"Selected language will be activated after restart of the configuration dialog." +msgstr "" +"Выбор Ñзыка:\n" +"Ðажмите Ñту кнопку Ð´Ð»Ñ Ð²Ñ‹Ð·Ð¾Ð²Ð° диалога выбора Ñзыка.\n" +"Выбранный Ñзык будет активирован поÑле перезапуÑка\n" +"диалога наÑтроек." + +#: Config.cpp:501 +msgid "" +"FPS counter\n" +"When this option is checked, a FPS (frames per second) counter will be shown\n" +"in the lower left corner of the screen.\n" +"[Recommended: your preference]" +msgstr "" +"Счётчик FPS\n" +"Когда включено, в левом нижнем углу Ñкрана показываетÑÑ Ñчётчик количеÑтва кадров в Ñекунду (FPS, frames per second)\n" +"[РекомендуетÑÑ: на ваше уÑмотрение]" + +#: Config.cpp:503 +msgid "" +"VI/s counter\n" +"When this option is checked, a VI/s (vertical interrupts per second) counter\n" +"will be shown in the lower left corner of the screen. This is like the FPS\n" +"counter but will be consistent at 60 VI/s for full speed on NTSC (U) games and\n" +"50 VI/s for full speed on PAL (E) ones.\n" +"[Recommended: your preference]" +msgstr "" +"Счётчик VI/s\n" +"Когда включено, в левом нижнем углу Ñкрана показываетÑÑ Ñчётчик вертикальных прерываний в Ñекунду (VI/s, vertical interrupts per second)\n" +"Подобно Ñчётчику FPS он показывает ÑкороÑÑ‚ÑŒ работы и при полной ÑкороÑти должен показывать 60 VI/s Ð´Ð»Ñ NTSC (U) игр\n" +"и 50 VI/s Ð´Ð»Ñ PAL (E) игр.\n" +"[РекомендуетÑÑ: на ваше уÑмотрение]" + +#: Config.cpp:505 +#, c-format +msgid "" +"% speed\n" +"This displays a percentage of the actual N64 speed in the lower\n" +"left corner of the screen.\n" +"[Recommended: your preference]" +msgstr "" +"СкороÑÑ‚ÑŒ в %\n" +"Ð’ нижнем левом углу Ñкрана показывает ÑкороÑÑ‚ÑŒ ÑмулÑции в % от ÑкороÑти игры на N64.\n" +"[РекомендуетÑÑ: на ваше уÑмотрение]" + +#: Config.cpp:507 +msgid "" +"Clock enabled\n" +"This option will put a clock in the lower right corner of the screen, showing the current time.\n" +"[Recommended: your preference]" +msgstr "" +"Включить чаÑÑ‹\n" +"ЕÑли включено, в правом нижнем углу выводÑÑ‚ÑÑ Ñ‡Ð°ÑÑ‹, показывающие текущее времÑ.\n" +"[РекомендуетÑÑ: на ваше уÑмотрение]" + +#: Config.cpp:510 +msgid "" +"Display hours as 24-hour clock.\n" +"[Recommended: your preference]" +msgstr "" +"Показывать чаÑÑ‹ в 24Ñ… чаÑовом формате.\n" +"[РекомендуетÑÑ: на ваше уÑмотрение]" + +#: Config.cpp:511 +msgid "" +"Transparent text background\n" +"If this is checked, all on-screen messages will have a transparent background. Otherwise, it will have a solid black background.\n" +"[Recommended: your preference]" +msgstr "" +"Прозрачный фон текÑта\n" +"ЕÑли включено, у вÑех Ñкранных Ñообщений будет прозрачный фон, иначе фон будет чёрный.\n" +"[РекомендуетÑÑ: на ваше уÑмотрение]" + +#: Config.cpp:514 +msgid "" +"Enable \"Emulation settings\" panel. For experienced users only!\n" +"It shows default emulation settings when game is not loaded, or current game settings otherwise." +msgstr "" +"Показывать панель \"ÐаÑтройки ÑмулÑции\". Только Ð´Ð»Ñ Ð¾Ð¿Ñ‹Ñ‚Ð½Ñ‹Ñ… пользователей!\n" +"ЕÑли игра не загружена, показывает наÑтройки ÑмулÑции по умолчанию, иначе показываютÑÑ Ð½Ð°Ñтройки текущей игры." + +#: Config.cpp:516 +msgid "" +"Enable \"Texture enhancement\" panel.\n" +"It shows various enhancement options for original textures as well as options for hi-resolution textures." +msgstr "" +"Показывать панель \"Улучшение текÑтур\".\n" +"Показывает различные наÑтройки ÑƒÐ»ÑƒÑ‡ÑˆÐµÐ½Ð¸Ñ Ð¸Ñходных текÑтур, а также наÑтройки текÑтур выÑокого разрешениÑ." + +#: Config.cpp:517 +msgid "" +"Full screen resolution:\n" +"This sets the full screen resolution for non-3dfx video cards.\n" +"All the resolutions that your video card/monitor support should be displayed.\n" +"[Recommended: native (max) resolution of your monitor - unless performance becomes an issue]" +msgstr "" +"ПолноÑкранное разрешение:\n" +"УÑтанавливает полноÑкранное разрешение Ð´Ð»Ñ Ð½Ðµ-3dfx карт.\n" +"Ð’ ÑпиÑке должны быть вÑе разрешениÑ, поддерживаемые вашей картой и монитором.\n" +"[РекомендуетÑÑ: родное (макÑимальное) разрешение вашего монитора, еÑли нет проблем Ñ Ð¿Ñ€Ð¾Ð¸Ð·Ð²Ð¾Ð´Ð¸Ñ‚ÐµÐ»ÑŒÐ½Ð¾Ñтью]" + +#: Config.cpp:520 +msgid "" +"Anisotropic filtering:\n" +"This filter sharpens and brings out the details of textures that recede into the distance.\n" +"When activated, it will use the max anisotropy your video card supports.\n" +"However, this will override native way of texture filtering and may cause visual artifacts in some games.\n" +"[Recommended: your preference, game dependant]" +msgstr "" +"ÐÐ½Ð¸Ð·Ð¾Ñ‚Ñ€Ð¾Ð¿Ð½Ð°Ñ Ñ„Ð¸Ð»ÑŒÑ‚Ñ€Ð°Ñ†Ð¸Ñ:\n" +"Этот фильтр делает резче и детальнее текÑтуры, уходÑщие в даль.\n" +"ЕÑли включено, иÑпользуетÑÑ Ð¼Ð°ÐºÑимальный уровень анизотропии,\n" +"поддерживаемый вашей картой.\n" +"Однако, Ñто отключает родные методы фильтрации текÑтур и может\n" +"привеÑти к визуальным артифактам в некоторых играх.\n" +"[РекомендуетÑÑ: на ваше уÑмотрение, завиÑит от игры]" + +#: Config.cpp:521 +msgid "" +"Autodetect VRAM Size:\n" +"Since OpenGL cannot do this reliably at the moment, the option to set this manually is available.\n" +"If checked, plugin will try to autodetect VRAM size.\n" +"But if this appears wrong, please uncheck and set it to correct value.\n" +"[Recommended: on]" +msgstr "" +"Ðвто определение размера видеопамÑти:\n" +"Т.к. OpenGL пока не позволÑет надежно определить размер доÑтупной видеопамÑти,\n" +"его можно уÑтановить вручную.\n" +"ЕÑли включено, плагин попытаетÑÑ Ð¾Ð¿Ñ€ÐµÐ´ÐµÐ»Ð¸Ñ‚ÑŒ размеер ÑамоÑтоÑтельно.\n" +"ЕÑли возникнут ошибки в работе плагина, выключите авто определение и уÑтановите размер вручную.\n" +"[РекомендуетÑÑ: вкл.]" + +#: Config.cpp:523 +msgid "" +"Use frame buffer objects:\n" +"Changes the way FB effects are rendered - with or without usage of the OpenGL Frame Buffer Objects (FBO) extension.\n" +"The choice depends on game and your video card. FBO off is good for NVIDIA cards, while for ATI cards, it's usually best that FBOs are turned on.\n" +"Also, some FB effects works only with one of the methods, no matter, which card you have.\n" +"On the whole, with FBO off, compatibility/ accuracy is a bit better (which is the case for Resident Evil 2).\n" +"However, with FBO on with some systems, it can actually be a bit faster in cases.\n" +"[Recommended: video card and game dependant]" +msgstr "" +"ИÑпользовать frame buffer objects:\n" +"ÐžÐ¿Ñ†Ð¸Ñ Ð¼ÐµÐ½Ñет ÑпоÑоб рендеринга Ñффектов буфера кадра:\n" +"Ñ Ð¸Ñпользованием Объектов Буфера Кадра (OpenGL Frame Buffer Objects, FBO) или без.\n" +"Выбор завиÑит от игры и от вышей видео карты. Ð”Ð»Ñ NVidia обычно лучше отключать FBO,\n" +"а Ð´Ð»Ñ ATI карт лучше включить.\n" +"Также, некоторые Ñффекты буфера кадра работают только Ñ Ð¾Ð´Ð½Ð¸Ð¼ из методов,\n" +"в не завиÑимоÑти от иÑпользуемой видеокарты.\n" +"Ð’ целом, при отключенном FBO ÑовмеÑтимоÑÑ‚ÑŒ/качеÑтво чуть лучше (например Ð´Ð»Ñ Resident Evil 2).\n" +"Однако, на некоторые ÑиÑтемы работают заметно быÑтрее Ñ FBO.\n" +"[РекомендуетÑÑ: завиÑит от игры и видео карты]" + +#: Config.cpp:578 +msgid "Emulation settings" +msgstr "ÐаÑтройки ÑмулÑции" + +#: Config.cpp:579 +msgid "" +"Filtering mode\n" +"There are three filtering modes possible:\n" +"* Automatic filtering - filter exactly how the N64 specifies.\n" +"* Point-sampled filtering - causes texels to appear square and sharp.\n" +"* Bilinear filtering - interpolates the texture to make it appear more smooth.\n" +"[Recommended: Automatic]" +msgstr "" +"Ð¤Ð¸Ð»ÑŒÑ‚Ñ€Ð°Ñ†Ð¸Ñ Ñ‚ÐµÐºÑтур\n" +"ДоÑтупны три режима фильтрации:\n" +"* ÐвтоматичеÑÐºÐ°Ñ - фильтровать в точночти как на N64.\n" +"* Ð’Ñегда Point-sampled - вÑе текÑели будут квадратными и резкими.\n" +"* Ð’Ñегда Ð±Ð¸Ð»Ð¸Ð½ÐµÐ¹Ð½Ð°Ñ - интерполирует текÑели текÑтуры, Ð´ÐµÐ»Ð°Ñ ÐµÐµ более гладкой.\n" +"[РекомендуетÑÑ: ÐвтоматичеÑкаÑ]" + +#: Config.cpp:583 +msgid "" +"Buffer swapping method\n" +"There are 3 buffer swapping methods:\n" +"* old - swap buffers when vertical interrupt has occurred.\n" +"* new - swap buffers when set of conditions is satisfied. Prevents flicker on some games.\n" +"* hybrid - mix of first two methods.\n" +"Can prevent even more flickering then previous method, but also can cause artefacts.\n" +"If you have flickering problems in a game (or graphics that don't show),\n" +"try to change swapping method.\n" +"[Recommended: new (hybrid for Paper Mario)]" +msgstr "" +"Метод Ñмены буфера кадра\n" +"ДоÑтупны 3 метода:\n" +"* Ñтарый - Ñмена буфера по вертикальному прерыванию.\n" +"* новый - Ñмена буфера по набору уÑловий.\n" +"Предотвращает мерцание в некоторых играх.\n" +"* гибридный - ÐºÐ¾Ð¼Ð±Ð¸Ð½Ð°Ñ†Ð¸Ñ Ð¿ÐµÑ€Ð²Ñ‹Ñ… двух методов.\n" +"Может ещё надёжнее предотвращать мерцание, чем предыдущий метод,\n" +"но также может вызывать артифакты.\n" +"ЕÑли в какой-то игре еÑÑ‚ÑŒ мерциние (или графика вообще не выводитÑÑ),\n" +"попытайтеÑÑŒ поменÑÑ‚ÑŒ метод Ñмены буфера .\n" +"[РекомендуетÑÑ: новый (гибридный Ð´Ð»Ñ Paper Mario)]" + +#: Config.cpp:587 +msgid "" +"Per-pixel level-of-detail calculation\n" +"N64 uses special mechanism for mip-mapping, which nearly impossible to reproduce\n" +"correctly on PC hardware. This option enables approximate emulation of this feature.\n" +"For example, it is required for the Peach/Bowser portrait's transition in Super Mario 64.\n" +"There are 3 modes:\n" +"* off - LOD is not calculated\n" +"* fast - fast imprecise LOD calculation.\n" +"* precise - most precise LOD calculation possible, but more slow.\n" +"[Recommended: your preference]" +msgstr "" +"ПопикÑельное вычиÑление ÑƒÑ€Ð¾Ð²Ð½Ñ Ð´ÐµÑ‚Ð°Ð»Ð¸Ð·Ð°Ñ†Ð¸Ð¸\n" +"N64 иÑпользует Ñпецифичный механизм мип-маппинга, который почти невозможно\n" +"корректно воÑпроизвеÑти на PC. Эта Ð¾Ð¿Ñ†Ð¸Ñ Ð²ÐºÐ»ÑŽÑ‡Ð°ÐµÑ‚ его приблизительную ÑмулÑцию.\n" +"Это нужно, к примеру, в Super Mario 64 Ð´Ð»Ñ Ð¿Ñ€ÐµÐ²Ñ€Ð°Ñ‰ÐµÐ½Ð¸Ñ Ð¿Ð¾Ñ€Ñ‚Ñ€ÐµÑ‚Ð° Peach в портерт Bowser'а.\n" +"ДоÑтупны 3 режима:\n" +"* нет - LOD не вычиÑлÑетÑÑ\n" +"* быÑтро - быÑтрое неточное вычиÑление LOD.\n" +"* точно - наиболее точный метод вычиÑÐ»ÐµÐ½Ð¸Ñ LOD, но более медленный.\n" +"[РекомендуетÑÑ: на ваше уÑмотрение]" + +#: Config.cpp:592 +msgid "" +"Aspect ratio of the output.\n" +"Most N64 games use 4:3 aspect ratio, but some support widescreen too.\n" +"You may select appropriate aspect here and set widescreen mode in game settings.\n" +"In \"Stretch\" mode the output will be stretched to the entire screen,\n" +"other modes may add black borders if necessary" +msgstr "" +"Соотношение размеров кадра.\n" +"БольшинÑтво игр на N64 иÑпользуют Ñоотношение размеров кадра 4:3,\n" +"но некоторые таже поддерживают широкоформатные разрешениÑ.\n" +"Ð’Ñ‹ можете выбрать подходÑщее Ñоотношение здеÑÑŒ и выбрать режим \"widescreen\"\n" +"в наÑтройках игры.\n" +"Ð’ режиме \"РаÑÑ‚Ñнуть\" кадр будет раÑÑ‚Ñнут на веÑÑŒ Ñкран,\n" +"оÑтальные режимы добавлÑÑŽÑ‚ черные полоÑÑ‹ по краÑм Ñкрана,\n" +"еÑли Ñто необходимо Ð´Ð»Ñ Ð¿Ð¾Ð´Ð´ÐµÑ€Ð¶Ð°Ð½Ð¸Ñ Ð²Ñ‹Ð±Ñ€Ð°Ð½Ð½Ð¾Ð³Ð¾ ÑоотношениÑ." + +#: Config.cpp:595 +msgid "" +"Fog enabled\n" +"Sets fog emulation on//off.\n" +"[Recommended: on]" +msgstr "" +"Туман\n" +"Включает ÑмулÑцию тумана.\n" +"[РекомендуетÑÑ: вкл]" + +#: Config.cpp:597 +msgid "" +"Buffer clear on every frame\n" +"Forces the frame buffer to be cleared every frame drawn.\n" +"Usually frame buffer clear is controlled by the game.\n" +"However, in some cases it is not well emulated,\n" +"and some garbage may be left on the screen.\n" +"In such cases, this option must be set on.\n" +"[Recommended: on]" +msgstr "" +"ОчиÑтка буфера каждого кадра\n" +"Принудительно очищает буфер каждого кадра перед отриÑовкой.\n" +"Как правило, очиÑтка буфера контролируетÑÑ Ð¸Ð³Ñ€Ð¾Ð¹.\n" +"Однако, Ñто не вÑегда хорошо ÑмулируетÑÑ, и на Ñкране может поÑвлÑÑ‚ÑŒÑÑ Ð¼ÑƒÑор.\n" +"Ð’ таких ÑлучаÑÑ… Ñта Ð¾Ð¿Ñ†Ð¸Ñ Ð´Ð¾Ð»Ð¶Ð½Ð° быть включена.\n" +"[РекомендуетÑÑ: вкл]" + +#: Config.cpp:599 +msgid "" +"Enable frame buffer emulation\n" +"If on, plugin will try to detect frame buffer usage and apply appropriate frame buffer emulation.\n" +"[Recommended: on for games which use frame buffer effects]" +msgstr "" +"Включить ÑмулÑцию буфера кадра\n" +"ЕÑли включено, плагин пытаетÑÑ Ð¾Ð¿Ñ€ÐµÐ´ÐµÐ»Ð¸Ñ‚ÑŒ иÑпользование буфера кадра\n" +"и применить подходÑщий метод ÑмулÑции.\n" +"[РекомендуетÑÑ: вкл. Ð´Ð»Ñ Ð¸Ð³Ñ€, иÑпользующих Ñффекты буфера кадра]" + +#: Config.cpp:601 +msgid "" +"Enable hardware frame buffer emulation\n" +"If this option is on, plugin will create auxiliary frame buffers in video memory instead of copying\n" +"frame buffer content into main memory. This allows plugin to run frame buffer effects without slowdown\n" +"and without scaling image down to N64's native resolution. This feature is fully supported by\n" +"Voodoo 4/5 cards and partially by Voodoo3 and Banshee. Modern cards also fully support it.\n" +"[Recommended: on, if supported by your hardware]" +msgstr "" +"ÐÐ¿Ð¿Ð°Ñ€Ð°Ñ‚Ð½Ð°Ñ ÑмулÑÑ†Ð¸Ñ Ð±ÑƒÑ„ÐµÑ€Ð° кадра\n" +"ЕÑли включено, плагин будет Ñоздавать вÑпомогательные буферы кадра в видео памÑти\n" +"вмеÑто ÐºÐ¾Ð¿Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ñодержимого оÑновного буфера кадра в оÑновную памÑÑ‚ÑŒ.\n" +"Это позволÑет Ñфектам буфера кадра работать без Ð·Ð°Ð¼ÐµÐ´Ð»ÐµÐ½Ð¸Ñ Ð¸ без ÑƒÐ¼ÐµÐ½ÑŒÑˆÐµÐ½Ð¸Ñ ÐºÐ°Ñ€Ñ‚Ð¸Ð½ÐºÐ¸ до размеров кадра N64.\n" +"Эта возможноÑÑ‚ÑŒ полноÑтью поддерживаетÑÑ Voodoo 4/5 и Ñовременными видеокартами,\n" +"а также чаÑтично работает на Voodoo3 и Banshee.\n" +"[РекомендуетÑÑ: вкл. еÑли поддерживаетÑÑ Ð²Ð°ÑˆÐµÐ¹ видеокартой]" + +#: Config.cpp:604 +msgid "" +"Get information about frame buffers\n" +"This is compatibility option. It must be set on for Mupen64 and off for 1964" +msgstr "" +"Выдать информацию о буферах кадра\n" +"ÐžÐ¿Ñ†Ð¸Ñ Ð´Ð»Ñ ÑовмеÑтимоÑти. Должна быть включена Ð´Ð»Ñ Mupen64 и выключена Ð´Ð»Ñ 1964." + +#: Config.cpp:606 +msgid "" +"Read every frame\n" +"In some games plugin can't detect frame buffer usage.\n" +"In such cases you need to enable this option to see frame buffer effects.\n" +"Every drawn frame will be read from video card -> it works very slow.\n" +"[Recommended: mostly off (needed only for a few games)]" +msgstr "" +"Считывать каждый кадр\n" +"Ð’ некоторых играх плагин не может обнаружить иÑпользование буфера кадра.\n" +"Ð’ таких ÑлучаÑÑ… нужно включить Ñту опцию чтобы увидеть Ñффект буфера кадра.\n" +"Каждый отриÑованный кадр будет ÑчитыватьÑÑ Ð¸Ð· видео карты в оÑновную\n" +"памÑÑ‚ÑŒ -> работает очень медленно.\n" +"[РекомендуетÑÑ: в оÑновном выкл. (нужна только Ð´Ð»Ñ Ð½ÐµÑкольких игр)]" + +#: Config.cpp:608 +msgid "" +"Render N64 frame buffer as texture\n" +"When this option is enabled, content of each N64 frame buffer is rendered\n" +"as texture over the frame, rendered by the plugin. This prevents graphics lost,\n" +"but may cause slowdowns and various glitches in some games.\n" +"[Recommended: mostly off]" +msgstr "" +"Выводить буфер N64 как текÑтуру\n" +"ЕÑли включено, Ñодержимое каждого буфера кадра N64 выводитÑÑ\n" +"как текÑтура поверх кадра, риÑуемого плагином. Это предотвращает потерю\n" +"графики, выводимой в буфер процеÑÑором N64, но может вызвать замедление и\n" +"различные визуальные проблемы в некоторых играх.\n" +"[РекомендуетÑÑ: в оÑновном выкл.]" + +#: Config.cpp:610 +msgid "" +"Detect CPU write to the N64 frame buffer\n" +"This option works as the previous options, but the plugin is trying to detect,\n" +"when game uses CPU writes to N64 frame buffer. The N64 frame buffer is rendered\n" +"only when CPU writes is detected. Use this option for those games, in which you\n" +"see still image or no image at all for some time with no reason.\n" +"[Recommended: mostly off]" +msgstr "" +"ОпределÑÑ‚ÑŒ, что N64 CPU пишет в буфер\n" +"Эта Ð¾Ð¿Ñ†Ð¸Ñ Ñ€Ð°Ð±Ð¾Ñ‚Ð°ÐµÑ‚ как предыдущаÑ, только плагин пытаетÑÑ Ð¾Ð¿Ñ€ÐµÐ´ÐµÐ»Ð¸Ñ‚ÑŒ,\n" +"когда игра иÑпользует CPU Ð´Ð»Ñ Ð·Ð°Ð¿Ð¸Ñи напрÑмую в буфер N64. Буфер N64 отриÑовываетÑÑ\n" +"только когда обнаружено, что CPU пишет в буфер. ИÑпользуйте Ñту опцию Ð´Ð»Ñ Ð¸Ð³Ñ€,\n" +"в которых картинка заÑтывает или пропадает на некоторое Ð²Ñ€ÐµÐ¼Ñ Ð±ÐµÐ· видимой причины.\n" +"[РекомендуетÑÑ: в оÑновном выкл.]" + +#: Config.cpp:612 +msgid "" +"Enable depth buffer rendering\n" +"This option is used to fully emulate N64 depth buffer.\n" +"It is required for correct emulation of depth buffer based effects.\n" +"However, it requires fast (>1GHz) CPU to work full speed.\n" +"[Recommended: on for fast PC]" +msgstr "" +"Программный рендеринг буфера глубины\n" +"ИÑпользуетÑÑ Ð´Ð»Ñ Ð¿Ð¾Ð»Ð½Ð¾Ð¹ ÑмулÑции буфера глубины N64.\n" +"ТребуетÑÑ Ð´Ð»Ñ ÐºÐ¾Ñ€Ñ€ÐµÐºÑ‚Ð½Ð¾Ð¹ ÑмулÑции Ñфектов, оÑнованных на значениÑÑ… из буфера глубины.\n" +"Ð”Ð»Ñ Ñ€Ð°Ð±Ð¾Ñ‚Ñ‹ на полной ÑкороÑти требуетÑÑ Ð±Ñ‹Ñтрый (>1Ггц) процеÑÑор.\n" +"[РекомендуетÑÑ: Ð´Ð»Ñ Ð±Ñ‹Ñтрых процеÑÑоров - вкл.]" + +#: Config.cpp:620 +msgid "" +"Filters:\n" +"Apply a filter to either smooth or sharpen textures.\n" +"There are 4 different smoothing filters and 2 different sharpening filters.\n" +"The higher the number, the stronger the effect,\n" +"i.e. \"Smoothing filter 4\" will have a much more noticeable effect than \"Smoothing filter 1\".\n" +"Be aware that performance may have an impact depending on the game and/or the PC.\n" +"[Recommended: your preference]" +msgstr "" +"Фильтры:\n" +"Применить фильтр Ð´Ð»Ñ ÑÐ³Ð»Ð°Ð¶Ð¸Ð²Ð°Ð½Ð¸Ñ Ñ‚ÐµÐºÑтур, или наоборот Ð´Ð»Ñ ÑƒÐ²ÐµÐ»Ð¸Ñ‡ÐµÐ½Ð¸Ñ Ñ€ÐµÐ·ÐºÐ¾Ñти.\n" +"ЕÑÑ‚ÑŒ 4 различных Ñглаживающих фильтра и 2 разных фильтра резкоÑти.\n" +"Чем выше номер, тем Ñильнее Ñффект, Ñ‚.е. применение \"Сглаживающего фильтра 4\" будет\n" +"намного заметнее чем \"Сглаживающего фильтра 1\".\n" +"Имейте в виду, что в завиÑимоÑти от игры и вашей ÑиÑтемы фильтры могут влиÑÑ‚ÑŒ на ÑкороÑÑ‚ÑŒ работы.\n" +"[РекомендуетÑÑ: на ваше уÑмотрение]" + +#: Config.cpp:624 +msgid "" +"Texture enhancement:\n" +"7 different filters are selectable here, each one with a distinctive look.\n" +"Be aware of possible performance impacts.\n" +"\n" +"IMPORTANT: 'Store' mode - saves textures in cache 'as is'. It can improve performance in games, which load many textures.\n" +"Disable 'Ignore backgrounds' option for better result.\n" +"\n" +"[Recommended: your preference]" +msgstr "" +"Улучшение текÑтур:\n" +"ЗдеÑÑŒ можно выбрать 7 различных фильтров, каждый выглÑдит по Ñвоему.\n" +"Применение может повлиÑÑ‚ÑŒ на производительноÑÑ‚ÑŒ.\n" +"\n" +"Ð’ÐЖÐО: в режиме 'Хранить' текÑтуры ÑохранÑÑŽÑ‚ÑÑ Ð² кÑше без изменений. Этот режим может повыÑить производительноÑÑ‚ÑŒ в играх,\n" +"которые грузÑÑ‚ множеÑтво текÑтур. Отключите опцию 'Игнорировать текÑтуры фона' Ð´Ð»Ñ Ð»ÑƒÑ‡ÑˆÐµÐ³Ð¾ результата.\n" +"[РекомендуетÑÑ: на ваше уÑмотрение]" + +#: Config.cpp:628 +msgid "" +"Texture cache size:\n" +"Enhanced and filtered textures can be cached to aid performance.\n" +"This setting will adjust how much PC memory will be dedicated for texture cache.\n" +"This helps boost performance if there are subsequent requests for the same texture (usually the case).\n" +"Normally, 128MB should be more than enough but there is a sweet spot for each game.\n" +"Super Mario may not need more than 32megs, but Conker streams a lot of textures,\n" +"so setting 256+ megs can boost performance. Adjust accordingly if you are encountering speed issues.\n" +"'0' disables cache.\n" +"[Recommended: PC and game dependant]" +msgstr "" +"Размер текÑтурного кÑша:\n" +"ТекÑтуры, к которым применÑлиÑÑŒ фильтры, могут ÑохранÑÑ‚ÑŒÑÑ Ð² кÑше Ð´Ð»Ñ Ð¿Ð¾Ð²Ñ‹ÑˆÐµÐ½Ð¸Ñ Ð¿Ñ€Ð¾Ð¸Ð·Ð²Ð¾Ð´Ð¸Ñ‚ÐµÐ»ÑŒÐ½Ð¾Ñти.\n" +"Эта наÑтройка регулирует, Ñколько ÑиÑтемной памÑти будет выделено под текÑтурный кÑш.\n" +"КÑш резко повышает производительноÑÑ‚ÑŒ при многократных обращениÑÑ… к текÑтуре (что обычно и бывает).\n" +"Обычно 128мб больше чем доÑтаточно, но Ð´Ð»Ñ ÐºÐ°Ð¶Ð´Ð¾Ð¹ игры можно подобрать оптимальное значение.\n" +"Ð”Ð»Ñ Super Mario нужно не более 32мб, а вот Conker загружает множеÑтво текÑтур,\n" +"так что 256+ мб под кÑш будут не лишними. ЕÑли возникают проблемы Ñ Ð¿Ñ€Ð¾Ð¸Ð·Ð²Ð¾Ð´Ð¸Ñ‚ÐµÐ»ÑŒÐ½Ð¾Ñтью,\n" +"попробуйте увеличить размер кÑша.\n" +"'0' отключает кÑширование текÑтур.\n" +"[РекомендуетÑÑ: завиÑит от игры и вашей ÑиÑтемы]" + +#: Config.cpp:634 +msgid "" +"Ignore Backgrounds:\n" +"It is used to skip enhancement for long narrow textures, usually used for backgrounds.\n" +"This may save texture memory greatly and increase performance.\n" +"[Recommended: on (off for 'Store' mode)]" +msgstr "" +"Игнорировать текÑтуры фона:\n" +"ИÑпользуетÑÑ Ñ‡Ñ‚Ð¾Ð±Ñ‹ не применÑÑ‚ÑŒ фильтры к длинным узким текÑтурам, обычно иÑпользуемым Ð´Ð»Ñ Ð·Ð°Ð´Ð½ÐµÐ³Ð¾ плана.\n" +"Это может Ñильно Ñократить раÑход видеопамÑти и увеличить производительноÑÑ‚ÑŒ.\n" +"[РекомендуетÑÑ: вкл. (выкл. в режиме 'Хранить')]" + +#: Config.cpp:636 +msgid "" +"Texture compression:\n" +"Textures will be compressed using selected texture compression method.\n" +"The overall compression ratio is about 1/6 for FXT1 and 1/4 for S3TC.\n" +"In addition to saving space on the texture cache,\n" +"the space occupied on the GFX hardware's texture RAM,\n" +"by the enhanced textures, will be greatly reduced.\n" +"This minimizes texture RAM usage,\n" +"decreasing the number of texture swaps to the GFX hardware leading to performance gains.\n" +"However, due to the nature of lossy compression of FXT1 and S3TC, using this option can sometimes lead to quality degradation of small size textures and color banding of gradient colored textures.\n" +"[Recommended: off]" +msgstr "" +"КомпреÑÑÐ¸Ñ Ñ‚ÐµÐºÑтур:\n" +"ТекÑтуры будут Ñжаты Ñ Ð¿Ñ€Ð¸Ð¼ÐµÐ½ÐµÐ½Ð¸ÐµÐ¼ выбранного метода компреÑии.\n" +"Общий уровень ÑÐ¶Ð°Ñ‚Ð¸Ñ Ð¿Ñ€Ð¸Ð±Ð»Ð¸Ð·Ð¸Ñ‚ÐµÐ»ÑŒÐ½Ð¾ равен 1/6 Ð´Ð»Ñ FXT1 и 1/4 Ð´Ð»Ñ S3TC.\n" +"Это позволÑет резко Ñократить размер иÑпользуемой текÑтурной памÑти видеокарты,\n" +"а также Ñохраненить меÑто в текÑтурном кÑше. Ð’ результате минимизируетÑÑ ÐºÐ¾Ð»Ð¸Ñ‡ÐµÑтво\n" +"перезагрузок текÑтур, что улучшает производительноÑÑ‚ÑŒ.\n" +"Так как Ð´Ð»Ñ ÐºÐ¾Ð¼Ð¿Ñ€ÐµÑии текÑтур применÑÑŽÑ‚ÑÑ Ð°Ð»Ð³Ð¾Ñ€Ð¸Ñ‚Ð¼Ñ‹ Ñ Ð¿Ð¾Ñ‚ÐµÑ€ÐµÐ¹ информации,\n" +"иÑпользование Ñтой опции иногда приводит к потере качеÑтва текÑтур небольшого размера\n" +"и равномерной закраÑке текÑтур Ñ Ð³Ñ€Ð°Ð´Ð¸ÐµÐ½Ñ‚Ð½Ð¾Ð¹ закраÑкой.\n" +"[РекомендуетÑÑ: выкл.]" + +#: Config.cpp:640 +msgid "" +"Compress texture cache:\n" +"Memory will be compressed so that more textures can be held in the texture cache.\n" +"The compression ratio varies with each texture,\n" +"but 1/5 of the original size would be a modest approximation.\n" +"They will be decompressed on-the-fly, before being downloaded to the gfx hardware.\n" +"This option will still help save memory space even when using texture compression.\n" +"[Recommended: on]" +msgstr "" +"Сжимать текÑтурный кÑш:\n" +"ПамÑÑ‚ÑŒ кÑша будет ÑжиматьÑÑ Ð¿Ð¾Ð·Ð²Ð¾Ð»ÑÑ Ñ…Ñ€Ð°Ð½Ð¸Ñ‚ÑŒ в нём больше текÑтур.\n" +"Уровень ÑÐ¶Ð°Ñ‚Ð¸Ñ Ñвой Ð´Ð»Ñ ÐºÐ°Ð¶Ð´Ð¾Ð¹ текÑтуры, в Ñреднем приблизительно 1/5.\n" +"Содержимое кÑша раÑпаковываетÑÑ Ð½Ð° лету, перед загрузкой в видеокарту.\n" +"Эта Ð¾Ð¿Ñ†Ð¸Ñ Ð¿Ð¾Ð·Ð²Ð¾Ð»Ñет Ñохранить памÑÑ‚ÑŒ даже в Ñлучае Ð¿Ñ€Ð¸Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ ÐºÐ¾Ð¼Ð¿Ñ€ÐµÑÑии текÑтур.\n" +"[РекомендуетÑÑ: вкл.]" + +#: Config.cpp:642 +msgid "" +"Hi-res pack format:\n" +"Choose which method is to be used for loading Hi-res texture packs.\n" +"Only Rice's format is available currently.\n" +"Leave on \"None\" if you will not be needing to load hi-res packs.\n" +"[Recommended: Rice's format. Default: \"None\"]" +msgstr "" +"Формат набора теÑтур выÑокого разрешениÑ:\n" +"Выбрать метод загрузки теÑтур выÑокого разрешениÑ.\n" +"Ð’ данный момент поддерживаетÑÑ Ñ‚Ð¾Ð»ÑŒÐºÐ¾ формат RiceVideo.\n" +"ОÑтавьте \"Ðикакой\", еÑли вам не нужна загрузка теÑтур выÑокого разрешениÑ.\n" +"[РекомендуетÑÑ: Формат Rice. По умолчанию: \"Ðикакой\"]" + +#: Config.cpp:646 +msgid "" +"Tile textures:\n" +"When on, wide texture will be split on several tiles to fit in one 256-width texture.\n" +"This tiled texture takes much less video memory space and thus overall performance will increase.\n" +"However, corresponding polygons must be split too, and this is not polished yet\n" +"- various issues are possible, including black lines and polygons distortions.\n" +"[Recommended: off]" +msgstr "" +"Резать на тайлы:\n" +"Когда включено, длинные текÑтуры будут разатьÑÑ Ð½Ð° куÑки, помещающиеÑÑ Ð² текÑтуру шириной 256.\n" +"Ñ‚Ð°ÐºÐ°Ñ Ð¿Ð¾Ñ€ÐµÐ·Ð°Ð½Ð½Ð°Ñ Ñ‚ÐµÐºÑтура занимает намного меньше меÑта в видео памÑти,\n" +"что улучшает общую производительноÑÑ‚ÑŒ. Однако, ÑоотвеÑтвующие полигоны также должны быть порезаны,\n" +"и Ñтот механизм ещё не до конца отлажен, так что возможны различные проблемы, вроде черных полоÑ\n" +"или иÑÐºÑ€Ð¸Ð²Ð»ÐµÐ½Ð¸Ñ Ñ‚ÐµÐºÑтур.\n" +"[РекомендуетÑÑ: выкл.]" + +#: Config.cpp:648 +msgid "" +"Force 16bpp textures:\n" +"The color of the textures will be reduced to 16bpp.\n" +"This is another space saver and performance enhancer.\n" +"This halves the space used on the texture cache and the GFX hardware's texture RAM.\n" +"Color reduction is done so that the original quality is preserved as much as possible.\n" +"Depending on the texture, this usually is hardly noticeable.\n" +"Sometimes though, it can be: skies are a good example.\n" +"[Recommended: off]" +msgstr "" +"Приводить к 16 бит текÑтурам:\n" +"Цвет текÑтур будет приведен к 16бит.\n" +"Ещё один ÑпоÑоб Ñохранить памÑÑ‚ÑŒ и улучшить производительноÑÑ‚ÑŒ.\n" +"Размер текÑтуры в видеопамÑти и в текÑтурном кÑше уменьшаетÑÑ Ð²Ð´Ð²Ð¾Ðµ.\n" +"ИÑпользуемый алгоритм Ð¿Ñ€Ð¸Ð²ÐµÐ´ÐµÐ½Ð¸Ñ Ð¼Ð°ÐºÑимально возможно ÑохранÑет качеÑтво иÑходной текÑтуры.\n" +"Обычно разница едва видна, но иногда различие заметно, например в текÑтурах небеÑ.\n" +"[РекомендуетÑÑ: выкл.]" + +#: Config.cpp:650 +msgid "" +"Texture dumping mode:\n" +"In this mode, you have that ability to dump textures on screen to the appropriate folder.\n" +"You can also reload textures while the game is running to see how they look instantly - big time saver!\n" +"\n" +"Hotkeys: \"R\" reloads hires textures from the texture pack - \"D\" toggles texture dumps on/off." +msgstr "" +"Дамп и редактирование текÑтур:\n" +"Ð’ Ñтом режиме вы можете Ñделать дамп текÑтур Ñ Ñкрана в ÑоотвеÑтвующую папку.\n" +"Ð’Ñ‹ также можете перезагрузить текÑтуры во Ð²Ñ€ÐµÐ¼Ñ Ñ€Ð°Ð±Ð¾Ñ‚Ñ‹ игры чтобы Ñразу увидеть, как они выглÑдÑÑ‚.\n" +"\n" +"ГорÑчие клавишы: R - перезагрузить текÑтуры из набора, D - режим дампа вкл./выкл." + +#: Config.cpp:652 +msgid "" +"Alternative CRC calculation:\n" +"This option enables emulation of a palette CRC calculation bug in RiceVideo.\n" +"If some textures are not loaded, try to set this option on/off.\n" +"[Recommended: texture pack dependant, mostly on]" +msgstr "" +"Ðльтернативное вычиÑление CRC:\n" +"Эта Ð¾Ð¿Ñ†Ð¸Ñ Ð²ÐºÐ»ÑŽÑ‡Ð°ÐµÑ‚ ÑмулÑцию ошибки в вычиÑлении контрольной Ñуммы в RiceVideo.\n" +"ЕÑли какие-то текÑтуры не загружаютÑÑ, попробуйте переключить Ñту опцию.\n" +"[РекомендуетÑÑ: завиÑит от набора текÑтур, обычно вкл.]" + +#: Config.cpp:657 +msgid "" +"Compress texture cache:\n" +"When game started, plugin loads all its hi-resolution textures into PC memory.\n" +"Since hi-resolution textures are usually large, the whole pack can take hundreds megabytes of memory.\n" +"Cache compression allows save memory space greatly.\n" +"Textures will be decompressed on-the-fly, before being downloaded to the gfx hardware.\n" +"This option will still help save memory space even when using texture compression.\n" +"[Recommended: on]" +msgstr "" +"Сжимать текÑтурный кÑш:\n" +"При запуÑке игры плагин грузит в оÑновную памÑÑ‚ÑŒ вÑе текÑтуры выÑокого Ñ€Ð°Ð·Ñ€ÐµÑˆÐµÐ½Ð¸Ñ Ð´Ð»Ñ Ñтой игры.\n" +"Так как Ñти текÑтуры довольно большие, веÑÑŒ набор может занимать Ñотни мегабайт памÑти.\n" +"Сжатие текÑтурного кÑша приводит к Ñильной ÑÑкономии памÑти.\n" +"Содержимое кÑша раÑпаковываетÑÑ Ð½Ð° лету, перед загрузкой в видеокарту.\n" +"Эта Ð¾Ð¿Ñ†Ð¸Ñ Ð¿Ð¾Ð·Ð²Ð¾Ð»Ñет Ñохранить памÑÑ‚ÑŒ даже в Ñлучае Ð¿Ñ€Ð¸Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ ÐºÐ¾Ð¼Ð¿Ñ€ÐµÑÑии текÑтур.\n" +"[РекомендуетÑÑ: вкл.]" + +#: Config.cpp:659 +msgid "" +"Use Alpha channel fully:\n" +"When this option is off, 16bit rgba textures will be loaded using RiceVideo style\n" +"- with 1bit for alpha channel.\n" +"When it is on, GlideHQ will check, how alpha channel is used by the hires texture,\n" +"and select most appropriate format for it.\n" +"This gives texture designers freedom to play with alpha, as they need,\n" +"regardless of format of original N64 texture.\n" +"For older and badly designed texture packs it can cause unwanted black borders.\n" +"[Recommended: texture pack dependant]" +msgstr "" +"ИÑпользовать альфа канал полноÑтью:\n" +"ЕÑли отключено, 16 битные RGBA текÑтуры загружаютÑÑ Ð² Ñтиле RiceVideo - \n" +"1бит на альфа канал. ЕÑли включено, GlideHQ проверÑет, каким образом альфа иÑпользуетÑÑ\n" +"в текÑтуре выÑокого Ñ€Ð°Ð·Ñ€ÐµÑˆÐµÐ½Ð¸Ñ Ð¸ иÑпользует Ð´Ð»Ñ Ð·Ð°Ð³Ñ€ÑƒÐ·ÐºÐ¸ наиболее подходÑщий формат.\n" +"Это позволÑет дизайнерам текÑтур работать Ñ Ð°Ð»ÑŒÑ„Ð¾Ð¹ как им нужно,\n" +"в незавиÑимоÑти от формата иÑходной текÑтуры N64.\n" +"ÐžÐ¿Ñ†Ð¸Ñ Ð¼Ð¾Ð¶ÐµÑ‚ вызывать чёрные бордюры у Ñтарых и криво Ñделанных текÑтур.\n" +"[РекомендуетÑÑ: завиÑит от набора текÑтур]" + +#: Config.cpp:662 +msgid "" +"Save texture cache to HD:\n" +"\n" +"For enhanced textures cache:\n" +"This will save all previously loaded and enhanced textures to HD.\n" +"So upon next game launch, all the textures will be instantly loaded, resulting in smoother performance.\n" +"\n" +"For high-resolution textures cache:\n" +"After creation, loading hi-res texture will take only a few seconds upon game launch,\n" +"as opposed to the 5 -60 seconds a pack can take to load without this cache file.\n" +"The only downside here is upon any changes to the pack, the cache file will need to be manually deleted.\n" +"\n" +"Saved cache files go into a folder called \"Cache\" within the Plugins folder.\n" +"\n" +"[Highly Recommended: on]" +msgstr "" +"СохранÑÑ‚ÑŒ текÑтурный кÑш на диÑк:\n" +"\n" +"Ð”Ð»Ñ ÐºÑша улучшенных текÑтур:\n" +"Ð’Ñе имеющиеÑÑ Ð² кÑше улучшенные текÑтуры будут Ñохранены на диÑке.\n" +"При Ñледующем запуÑке игры вÑе Ñти текÑтуры будут мгновенно загружены.\n" +"\n" +"Ð”Ð»Ñ ÐºÑша текÑтур выÑокого разрешениÑ:\n" +"ПоÑле ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ ÐºÑша, загрузка текÑтур Ñ Ð´Ð¸Ñка займет пару Ñекунд, в отличии от\n" +"50-60 Ñекунд, требуемых Ð´Ð»Ñ Ð·Ð°Ð³Ñ€ÑƒÐ·ÐºÐ¸ без кÑша.\n" +"ЕдинÑтвенным неудобÑтвом ÑвлÑетÑÑ Ð½ÐµÐ¾Ð±Ñ…Ð¾Ð´Ð¸Ð¼Ð¾ÑÑ‚ÑŒ вручную удалÑÑ‚ÑŒ файл кÑша при\n" +"изменениÑÑ… в наборе текÑтур.\n" +"\n" +"Файлы кÑша ÑохранÑÑŽÑ‚ÑÑ Ð² папке Plugins, в подпапке Cache.\n" +"\n" +"[ВеÑьма рекомендуетÑÑ: вкл.]" + +#: Config.cpp:685 +msgid "Debug" +msgstr "Отладка" + +#: Config.cpp:686 +msgid "" +"Autodetect Microcode\n" +"If this option is checked, the microcode of the game\n" +"will be detected automatically from the INI, and\n" +"therefore it will not need to be set in this\n" +"configuration dialog.\n" +"[Recommended: on]" +msgstr "" + +#: Config.cpp:688 +msgid "" +"Force Microcode\n" +"This option ONLY has an effect if Autodetect Microcode\n" +"is unchecked, the crc from the game could not be\n" +"found in the INI, OR after the game has already started\n" +"running. In any of those three cases, this will\n" +"select the microcode to use\n" +"[Recommended: any, turn on Autodetect Microcode]" +msgstr "" + +#: Config.cpp:692 +msgid "" +"Wireframe\n" +"This option, when checked, makes it so that the plugin will draw only the\n" +"outlines of objects. The colors specified in the combo box to the right\n" +"determines the color that the wireframes show up as.\n" +"[Recommended: off]" +msgstr "" + +#: Config.cpp:694 +msgid "" +"Wireframe Colors\n" +"This selects the colors to use for the wireframes (if wireframe mode is enabled).\n" +"There are 3 modes:\n" +"* Original colors - draw exactly as it would normally, textures and all, only in wireframes.\n" +"* Vertex colors - use the colors specified in the vertices to draw the wireframes with.\n" +"* Red only - use a constant red color to draw the wireframes.\n" +"[Recommended: Vertex colors]" +msgstr "" + +#: Config.cpp:696 +msgid "" +"Log to RDP.txt\n" +"RECOMMENDED FOR DEBUGGING ONLY - this option, when checked, will log EVERY SINGLE\n" +"COMMAND the plugin processes to a file called RDP.txt in the current directory.\n" +"This is incredibly slow, so I recommend keeping it disabled.\n" +"[Recommended: off]" +msgstr "" + +#: Config.cpp:698 +msgid "" +"Unknown combiners as red\n" +"Objects that use an unimplemented combine mode will show up as red instead of\n" +"assuming texture with full alpha. Disable this option to remove the red stuff\n" +"and at least have a guess at the correct combine mode.\n" +"[Recommended: off]" +msgstr "" + +#: Config.cpp:700 +msgid "" +"Log clear every frame\n" +"RECOMMENDED FOR DEBUGGING ONLY - this option has no effect unless 'Log to RDP.txt'\n" +"is checked. This will make it so that the log, RDP.txt, will be cleared at the\n" +"beginning of every frame.\n" +"[Recommended: off]" +msgstr "" + +#: Config.cpp:702 +msgid "" +"Log unknown combiners\n" +"RECOMMENDED FOR DEBUGGING ONLY - when checked, this option will cause every\n" +"unimplemented combiner drawn to be logged to a file called Unimp.txt in the\n" +"current directory. This becomes slow when there are unimplemented combiners\n" +"on the screen, so I recommend keeping it disabled.\n" +"[Recommended: off]" +msgstr "" + +#: Config.cpp:704 +msgid "" +"Run and log in window\n" +"RECOMMENDED FOR DEBUGGING ONLY - this option will make it so that the plugin will\n" +"still process dlists in windowed mode. This allows for logging to occur while not\n" +"in fullscreen, possibly allowing you to debug a crash.\n" +"[Recommended: off]" +msgstr "" + +#: Config.cpp:706 +msgid "" +"Clear unknown combiner log every frame\n" +"RECOMMENDED FOR DEBUGGING ONLY - this option works much like 'Log clear every frame'\n" +"except it clears the combiner log (Unimp.txt) instead of RDP.txt at the\n" +"beginning of each frame. Again, this option has no effect if 'combiner logging' is disabled.\n" +"[Recommended: off]" +msgstr "" + +#: Config.cpp:709 +msgid "" +"Bilinear filter texture cache\n" +"RECOMMENDED FOR DEBUGGING ONLY - when checked, this option will make the graphical\n" +"debugger texture cache use bilinear filtering as opposed to point-sampled filtering,\n" +"which it will use otherwise. See 'Filtering mode' for descriptions of bilinear and\n" +"point-sampled filtering.\n" +"[Recommended: off]" +msgstr "" + +#: Config.cpp:1104 +msgid "Glide64 settings" +msgstr "ÐаÑтройки Glide64" + +#: Config.cpp:1293 +msgid "About Glide64" +msgstr "Ð¡Ð²ÐµÐ´ÐµÐ½Ð¸Ñ Ð¾ Glide64" + +#: Config.cpp:1326 +msgid "authors:" +msgstr "авторы:" + +#: Config.cpp:1330 +msgid "" +"Dave2001. Original author and former main developer.\n" +"He founded Glide64 project on Dec. 29th, 2001.\n" +"Left the project at fall of 2002.\n" +msgstr "" +"Dave2001. ОÑнователь и бывший главный разработчик\n" +"проекта. ОÑновал проект Glide64 29 ДекабрÑ, 2001 г.\n" +"Покинул проект оÑенью 2002.\n" + +#: Config.cpp:1336 +msgid "" +"Gugaman. Developer. Joined the project at winter 2002\n" +" and left it at fall 2002." +msgstr "" +"Gugaman. Разработчик. Пришёл в проект зимой 2002 г.,\n" +"покинул проект оÑенью 2002 г." + +#: Config.cpp:1342 +msgid "" +"Sergey 'Gonetz' Lipski. Joined the project at winter 2002.\n" +"Main developer since fall of 2002." +msgstr "" +"Сергей 'Gonetz' ЛипÑкий. Пришёл в проект зимой 2002 г.\n" +"ОÑновной разработчик Ñ Ð¾Ñени 2002 г." + +#: Config.cpp:1347 +msgid "Hiroshi 'KoolSmoky' Morii, Joined the project in 2007. " +msgstr "Hiroshi 'KoolSmoky' Morii, пришёл в проект в 2007 г. " + +#: Config.cpp:1350 +msgid "Glitch64 (the wrapper) authors:" +msgstr "авторы Glitch64 (glide3x wrapper):" + +#: Config.cpp:1374 +msgid "GlideHQ author:" +msgstr "автор GlideHQ:" + +#: Config.cpp:1381 +msgid "beta tester:" +msgstr "бета теÑтер:" + +#: Config.cpp:1388 +msgid "" +"special thanks to:\n" +" Orkin, Rice, Daniel Borca, Legend.\n" +"Thanks to EmuXHaven for hosting my site:\n" +"http://glide64.emuxhaven.net\n" +msgstr "" +"оÑÐ¾Ð±Ð°Ñ Ð±Ð»Ð°Ð³Ð¾Ð´Ð°Ñ€Ð½Ð¾ÑÑ‚ÑŒ:\n" +"Orkin, Rice, Daniel Borca, Legend.\n" +"ÑпаÑибо EmuXHaven за хоÑтинг моего Ñайта:\n" +"http://glide64.emuxhaven.net\n" + +#~ msgid "Gfx cannot be drawn in windowed mode" +#~ msgstr "Плагин не может выводить графику в оконном режиме" + +#~ msgid "Press Alt+Enter to switch to fullscreen" +#~ msgstr "Ðажмите Alt+Enter Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ Ð² оконный режим." + +#~ msgid "" +#~ "Buffer clear on every frame\n" +#~ "If this option is checked, the buffer will be cleared (screen initialized " +#~ "to black)\n" +#~ "at the beginning of each frame. If this option is disabled, the speed " +#~ "might increase\n" +#~ "slightly, but some trails may appear.\n" +#~ "[Recommended: on]" +#~ msgstr "" +#~ "ОчиÑтка буфера каждого кадра\n" +#~ "ЕÑли включено, буфер кадра будет очищатьÑÑ (заливатьÑÑ Ñ‡Ñ‘Ñ€Ð½Ñ‹Ð¼)\n" +#~ "в начале отриÑовки каждого кадра. " diff --git a/Source/Glide64/Internalization/Glide64_zh_CN.po b/Source/Glide64/Internalization/Glide64_zh_CN.po new file mode 100644 index 000000000..4db527a13 --- /dev/null +++ b/Source/Glide64/Internalization/Glide64_zh_CN.po @@ -0,0 +1,1419 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: Glide64 Chinese Translation v1.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2011-12-19 17:29+0700\n" +"PO-Revision-Date: 2011-12-19 17:59+0700\n" +"Last-Translator: Navitel \n" +"Language-Team: \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Poedit-Language: Chinese\n" +"X-Poedit-SourceCharset: utf-8\n" + +#: Config.cpp:64 +msgid "Rendering" +msgstr "渲染" + +#: Config.cpp:65 +msgid "Other" +msgstr "其它" + +#: Config.cpp:66 +msgid "Speed" +msgstr "速度" + +#: Config.cpp:67 +msgid "Time" +msgstr "时间" + +#: Config.cpp:68 +msgid "On screen display" +msgstr "å±å¹•ä¸Šæ˜¾ç¤º" + +#: Config.cpp:69 +msgid "OpenGL settings" +msgstr "OpenGL设置" + +#: Config.cpp:70 +#: Config.cpp:137 +msgid "Frame buffer emulation" +msgstr "帧缓冲区仿真" + +#: Config.cpp:71 +msgid "" +"Windowed or\n" +"3dfx card resolution:" +msgstr "" +"窗å£æˆ–\n" +"3dfxå¡åˆ†è¾¨çŽ‡:" + +#: Config.cpp:99 +msgid "Vertical sync" +msgstr "ç›´åŒæ­¥" + +#: Config.cpp:100 +msgid "Show advanced emulation options" +msgstr "显示高级仿真选项" + +#: Config.cpp:101 +msgid "Show texture enhancement options" +msgstr "显示纹ç†å¢žå¼ºé€‰é¡¹" + +#: Config.cpp:102 +msgid "Screenshot format:" +msgstr "截图格å¼:" + +#: Config.cpp:105 +msgid "Language: " +msgstr "语言: " + +#: Config.cpp:106 +msgid "LANGUAGE_NAME" +msgstr "åŽè¯­ï¼ˆç®€ä½“)" + +#: Config.cpp:112 +msgid "FPS counter" +msgstr "FPS 计数器" + +#: Config.cpp:113 +msgid "VI/s counter" +msgstr "VI/s 计数器" + +#: Config.cpp:114 +#, c-format +msgid "% speed" +msgstr "%速度 " + +#: Config.cpp:115 +msgid "Clock enabled" +msgstr "时钟å¯ç”¨" + +#: Config.cpp:116 +msgid "Clock is 24-hour" +msgstr "时钟为24å°æ—¶" + +#: Config.cpp:117 +msgid "Transparent text background" +msgstr "é€æ˜Žæ–‡å­—的背景" + +#: Config.cpp:118 +msgid "" +"Full screen\n" +"resolution:" +msgstr "" +"å…¨å±å¹•\n" +"分辨率:" + +#: Config.cpp:121 +msgid "Anisotropic filtering" +msgstr "å„å‘异性过滤" + +#: Config.cpp:122 +msgid "Autodetect " +msgstr "自动检测 " + +#: Config.cpp:123 +msgid "VRAM size" +msgstr "显存大å°" + +#: Config.cpp:125 +msgid "Mb" +msgstr "å…†" + +#: Config.cpp:126 +msgid "Use frame buffer objects" +msgstr "使用帧缓冲对象" + +#: Config.cpp:133 +msgid "Current game emulation settings. Change with care!" +msgstr "ç›®å‰çš„游æˆä»¿çœŸè®¾ç½®ã€‚更改时è¦å°å¿ƒï¼" + +#: Config.cpp:135 +msgid "Default emulation settings. Not recommended to change!" +msgstr "默认仿真设置。ä¸æŽ¨è更改ï¼" + +#: Config.cpp:136 +msgid "General options" +msgstr "一般选项" + +#: Config.cpp:138 +msgid "Depth buffer emulation" +msgstr "深度缓冲仿真" + +#: Config.cpp:139 +msgid "Filtering mode:" +msgstr "过滤模å¼ï¼š" + +#: Config.cpp:141 +msgid "Automatic" +msgstr "自动" + +#: Config.cpp:142 +msgid "Force Bilinear" +msgstr "强行支æŒåŒçº¿æ€§" + +#: Config.cpp:143 +msgid "Force Point-sampled" +msgstr "强行支æŒç‚¹é‡‡æ ·" + +#: Config.cpp:146 +msgid "Buffer swapping method:" +msgstr "缓冲交æ¢æ–¹æ³•ï¼š" + +#: Config.cpp:148 +msgid "Old" +msgstr "æ—§" + +#: Config.cpp:149 +msgid "New" +msgstr "æ–°" + +#: Config.cpp:150 +msgid "Hybrid" +msgstr "æ··åˆ" + +#: Config.cpp:153 +msgid "LOD calculation:" +msgstr "LOD计算:" + +#: Config.cpp:155 +msgid "off" +msgstr "å…³" + +#: Config.cpp:156 +msgid "fast" +msgstr "å¿«" + +#: Config.cpp:157 +msgid "precise" +msgstr "精确" + +#: Config.cpp:160 +msgid "Aspect ratio:" +msgstr "宽高比:" + +#: Config.cpp:162 +msgid "4:3 (default)" +msgstr "4:3 (默认)" + +#: Config.cpp:163 +msgid "Force 16:9" +msgstr "å¼ºè¡Œæ”¯æŒ 16:9" + +#: Config.cpp:164 +msgid "Stretch" +msgstr "伸展" + +#: Config.cpp:165 +msgid "Original" +msgstr "" + +#: Config.cpp:168 +msgid "Fog" +msgstr "雾" + +#: Config.cpp:169 +msgid "Buffer clear on every frame" +msgstr "清除æ¯ä¸€å¸§ç¼“冲" + +#: Config.cpp:170 +msgid "Enable frame buffer emulation" +msgstr "å¯ç”¨å¸§ç¼“冲仿真" + +#: Config.cpp:171 +msgid "Hardware frame buffer emulation" +msgstr "硬件仿真帧缓冲" + +#: Config.cpp:172 +msgid "Get frame buffer info" +msgstr "å–帧缓冲信æ¯" + +#: Config.cpp:173 +msgid "Read every frame (slow!)" +msgstr "读å–æ¯ä¸€å¸§ï¼ˆæ…¢ï¼ï¼‰" + +#: Config.cpp:174 +msgid "Render N64 frame buffer as texture" +msgstr "呈现N64帧缓冲为纹ç†" + +#: Config.cpp:175 +msgid "Detect CPU write to the N64 frame buffer" +msgstr "检测CPU写入到N64帧缓冲" + +#: Config.cpp:176 +msgid "Software depth buffer rendering" +msgstr "呈现软件深度缓冲" + +#: Config.cpp:200 +#: Config.cpp:619 +msgid "Texture enhancement" +msgstr "纹ç†å¢žå¼º" + +#: Config.cpp:201 +msgid "Hi-resolution textures" +msgstr "高清晰度的纹ç†" + +#: Config.cpp:202 +msgid "Common" +msgstr "一般" + +#: Config.cpp:203 +msgid "Presets" +msgstr "预置" + +#: Config.cpp:204 +#: Config.cpp:205 +msgid "Performance tweaks" +msgstr "性能调整" + +#: Config.cpp:206 +msgid "Filter" +msgstr "过滤器" + +#: Config.cpp:208 +#: Config.cpp:219 +#: Config.cpp:238 +msgid "None" +msgstr "æ— " + +#: Config.cpp:209 +msgid "Smooth filtering 1" +msgstr "平滑过滤 1" + +#: Config.cpp:210 +msgid "Smooth filtering 2" +msgstr "平滑过滤 2" + +#: Config.cpp:211 +msgid "Smooth filtering 3" +msgstr "平滑过滤 3" + +#: Config.cpp:212 +msgid "Smooth filtering 4" +msgstr "平滑过滤 4" + +#: Config.cpp:213 +msgid "Sharp filtering 1" +msgstr "å°–é”过滤 1" + +#: Config.cpp:214 +msgid "Sharp filtering 2" +msgstr "å°–é”过滤 2" + +#: Config.cpp:217 +msgid "Enhancement" +msgstr "增强" + +#: Config.cpp:220 +msgid "Store" +msgstr "储存" + +#: Config.cpp:230 +msgid "Texture cache" +msgstr "纹ç†ç¼“å­˜" + +#: Config.cpp:232 +msgid "Mbytes" +msgstr "å…†" + +#: Config.cpp:233 +msgid "Ignore Backgrounds" +msgstr "忽视背景" + +#: Config.cpp:234 +#: Config.cpp:245 +msgid "Apply texture compression" +msgstr "应用纹ç†åŽ‹ç¼©" + +#: Config.cpp:235 +#: Config.cpp:246 +msgid "Compress texture cache" +msgstr "压缩纹ç†ç¼“å­˜" + +#: Config.cpp:236 +msgid "Format" +msgstr "æ ¼å¼" + +#: Config.cpp:239 +msgid "Rice format" +msgstr "Rice æ ¼å¼" + +#: Config.cpp:242 +msgid "Tile textures" +msgstr "图砖纹ç†" + +#: Config.cpp:243 +msgid "Force 16bpp textures" +msgstr "强行支æŒ16ä½çº¹ç†" + +#: Config.cpp:244 +msgid "Alternative CRC calculation" +msgstr "å¦ä¸€ç§CRC计算" + +#: Config.cpp:247 +msgid "Use alpha channel fully" +msgstr "充分利用é€æ˜Žé€šé“" + +#: Config.cpp:248 +msgid "Texture dumping/editing mode" +msgstr "纹ç†è½¬å‚¨ä¸Žç¼–辑模å¼" + +#: Config.cpp:249 +msgid "Texture compression method" +msgstr "纹ç†åŽ‹ç¼©æ–¹æ³•" + +#: Config.cpp:255 +msgid "Save texture cache to hard disk" +msgstr "ä¿å­˜çº¹ç†ç¼“存到硬盘" + +#: Config.cpp:256 +msgid "Best performance" +msgstr "最佳性能" + +#: Config.cpp:257 +msgid "Best texture quality" +msgstr "最佳纹ç†è´¨é‡" + +#: Config.cpp:263 +msgid "Developers settings" +msgstr "å¼€å‘人员设置" + +#: Config.cpp:264 +msgid "Debug/Misc" +msgstr "调试与æ‚项" + +#: Config.cpp:265 +msgid "Autodetect Microcode" +msgstr "自动检测微ç " + +#: Config.cpp:266 +msgid "Force Microcode:" +msgstr "强行支æŒå¾®ç ï¼š" + +#: Config.cpp:279 +msgid "Wireframe using:" +msgstr "线框使用:" + +#: Config.cpp:281 +msgid "Original colors" +msgstr "原æ¥çš„颜色" + +#: Config.cpp:282 +msgid "Vertex colors" +msgstr "顶点的颜色" + +#: Config.cpp:283 +msgid "Red only" +msgstr "仅红" + +#: Config.cpp:286 +msgid "Log to rdp.txt (SLOW)" +msgstr "登录到 rdp.txt(慢)" + +#: Config.cpp:287 +msgid "Unknown combiners as red" +msgstr "未知åˆæˆå™¨ä¸ºçº¢è‰²" + +#: Config.cpp:288 +msgid "Log clear every frame" +msgstr "在æ¯ä¸€å¸§æ¸…除记录" + +#: Config.cpp:289 +msgid "Combiner logging" +msgstr "åˆæˆå™¨è®°å½•" + +#: Config.cpp:290 +msgid "Run (+log) in window" +msgstr "窗å£è¿è¡Œï¼ˆ+记录)" + +#: Config.cpp:291 +msgid "Cmb. clear every frame" +msgstr "在æ¯ä¸€å¸§æ¸…除åˆæˆå™¨" + +#: Config.cpp:292 +msgid "Error log (rdp_e.txt)" +msgstr "错误记录(rdp_e.txt)" + +#: Config.cpp:293 +msgid "Bilinear filter texture cache" +msgstr "åŒçº¿æ€§è¿‡æ»¤çº¹ç†ç¼“å­˜" + +#: Config.cpp:325 +#: Config.cpp:546 +msgid " auto" +msgstr "自动" + +#: Config.cpp:382 +msgid "Please choose language:" +msgstr "请选择语言:" + +#: Config.cpp:383 +msgid "Language" +msgstr "语言" + +#: Config.cpp:390 +msgid "Press OK to change to " +msgstr "按确定更改为 " + +#: Config.cpp:486 +msgid "Basic settings" +msgstr "基本设置" + +#: Config.cpp:487 +msgid "" +"Resolution\n" +"This option selects the fullscreen resolution for 3dfx cards and windowed resolution for other cards\n" +"(note again that for 3dfx cards the plugin must be in fullscreen mode to see anything).\n" +"[Recommended: 640x480, 800x600, 1024x768]" +msgstr "" +"分辨率\n" +"--------\n" +"此选项选择3dfxå¡ä¸ºå…¨å±åˆ†è¾¨çŽ‡å’Œå…¶å®ƒçª—å£åˆ†è¾¨çŽ‡ã€‚\n" +"注æ„:\t对于3dfxå¡ä¸Šçš„æ’件必须\n" +"\t在全å±æ¨¡å¼æ‰èƒ½çœ‹åˆ°ä¸œè¥¿\n" +"[推è:640x480,800x600,1024X768]" + +#: Config.cpp:491 +msgid "" +"Vertical sync\n" +"This option will enable the vertical sync, which will prevent tearing.\n" +"Note: this option will ONLY have effect if vsync is set to \"Software Controlled\".\n" +msgstr "" +"ç›´åŒæ­¥\n" +"-------\n" +"此选项将å¯ç”¨ç›´åŒæ­¥ï¼Œå®ƒå°†é˜²æ­¢æ’•è£‚。\n" +"注æ„:\t如果直åŒæ­¥è®¾ç½®ä¸º\"软件控制\",\n" +"\t此选项æ‰ä¼šç”Ÿæ•ˆã€‚\n" + +#: Config.cpp:493 +msgid "Select a format, in which screen shots will be saved" +msgstr "选择å±å¹•æˆªå›¾è¢«ä¿å­˜çš„一ç§æ ¼å¼" + +#: Config.cpp:500 +msgid "" +"Language select:\n" +"Press the button to invoke language selection dialog.\n" +"Selected language will be activated after restart of the configuration dialog." +msgstr "" +"语言选择:\n" +"----------\n" +"按下按钮调用语言选择对è¯æ¡†ã€‚\n" +"选择的语言会在é‡æ–°å¯åŠ¨é…置对è¯æ¡†åŽç”Ÿæ•ˆã€‚" + +#: Config.cpp:501 +msgid "" +"FPS counter\n" +"When this option is checked, a FPS (frames per second) counter will be shown\n" +"in the lower left corner of the screen.\n" +"[Recommended: your preference]" +msgstr "" +"FPS 计数器\n" +"------------\n" +"当选定,FPS(帧æ¯ç§’)计数器\n" +"会显示在å±å¹•å·¦ä¸‹è§’的角è½ã€‚\n" +"[推è:您的å好]" + +#: Config.cpp:503 +msgid "" +"VI/s counter\n" +"When this option is checked, a VI/s (vertical interrupts per second) counter\n" +"will be shown in the lower left corner of the screen. This is like the FPS\n" +"counter but will be consistent at 60 VI/s for full speed on NTSC (U) games and\n" +"50 VI/s for full speed on PAL (E) ones.\n" +"[Recommended: your preference]" +msgstr "" +"VI/s 计数器\n" +"------------\n" +"当选定,VI/s(æ¯ç§’垂直中断)计数器\n" +"将显示在å±å¹•å·¦ä¸‹è§’的角è½ã€‚\n" +"它将在全速 NTSC(U)的游æˆé‡Œä¿æŒ 60VI/s\n" +"或在全速 PAL(E)的游æˆé‡Œä¿æŒ 50VI/s。\n" +"[推è:您的å好]" + +#: Config.cpp:505 +#, c-format +msgid "" +"% speed\n" +"This displays a percentage of the actual N64 speed in the lower\n" +"left corner of the screen.\n" +"[Recommended: your preference]" +msgstr "" +"%速度\n" +"-------\n" +"在å±å¹•å·¦ä¸‹è§’的角è½ï¼Œ\n" +"将显示N64实际速度的百分比。\n" +"[推è:您的å好]" + +#: Config.cpp:507 +msgid "" +"Clock enabled\n" +"This option will put a clock in the lower right corner of the screen, showing the current time.\n" +"[Recommended: your preference]" +msgstr "" +"时钟å¯ç”¨\n" +"----------\n" +"此选项将在å±å¹•çš„å³ä¸‹è§’\n" +"摆放时钟,显示当å‰æ—¶é—´ã€‚\n" +"[推è:您的å好]" + +#: Config.cpp:510 +msgid "" +"Display hours as 24-hour clock.\n" +"[Recommended: your preference]" +msgstr "" +"显示时间为24å°æ—¶åˆ¶ã€‚\n" +"[推è:您的å好]" + +#: Config.cpp:511 +msgid "" +"Transparent text background\n" +"If this is checked, all on-screen messages will have a transparent background. Otherwise, it will have a solid black background.\n" +"[Recommended: your preference]" +msgstr "" +"é€æ˜Žæ–‡å­—的背景\n" +"-----------------\n" +"当选定,所有在å±å¹•ä¸Šçš„ä¿¡æ¯\n" +"将有一个é€æ˜Žçš„背景。\n" +"å¦åˆ™ï¼Œå°†æœ‰é»‘色背景。\n" +"[推è:您的å好]" + +#: Config.cpp:514 +msgid "" +"Enable \"Emulation settings\" panel. For experienced users only!\n" +"It shows default emulation settings when game is not loaded, or current game settings otherwise." +msgstr "" +"å¯ç”¨\"仿真设置\"é¢æ¿ã€‚于有ç»éªŒçš„用户ï¼\n" +"它显示了尚未加载游æˆçš„默认仿真设置,\n" +"或当å‰æ¸¸æˆè®¾ç½®ã€‚" + +#: Config.cpp:516 +msgid "" +"Enable \"Texture enhancement\" panel.\n" +"It shows various enhancement options for original textures as well as options for hi-resolution textures." +msgstr "" +"å¯ç”¨\"纹ç†å¢žå¼º\"é¢æ¿ã€‚\n" +"它显示原æ¥çš„纹ç†å¢žå¼ºé€‰é¡¹\n" +"以åŠé«˜æ¸…晰度的纹ç†é€‰é¡¹ã€‚" + +#: Config.cpp:517 +msgid "" +"Full screen resolution:\n" +"This sets the full screen resolution for non-3dfx video cards.\n" +"All the resolutions that your video card/monitor support should be displayed.\n" +"[Recommended: native (max) resolution of your monitor - unless performance becomes an issue]" +msgstr "" +"å…¨å±å¹•åˆ†è¾¨çŽ‡ï¼š\n" +"---------------\n" +"这将设置éž3dfxå¡çš„å…¨å±å¹•åˆ†è¾¨çŽ‡ã€‚\n" +"您的视频å¡ä¸Žæ˜¾ç¤ºå™¨æ‰€æ”¯æŒçš„分辨率将会显示。\n" +"[推è:显示器的原始(最大)分辨率 - 除éžæ€§èƒ½æˆä¸ºé—®é¢˜]" + +#: Config.cpp:520 +msgid "" +"Anisotropic filtering:\n" +"This filter sharpens and brings out the details of textures that recede into the distance.\n" +"When activated, it will use the max anisotropy your video card supports.\n" +"However, this will override native way of texture filtering and may cause visual artifacts in some games.\n" +"[Recommended: your preference, game dependant]" +msgstr "" +"å„å‘异性过滤:\n" +"---------------\n" +"该过滤器会é”化和带出在远方退去的纹ç†ç»†èŠ‚。\n" +"å¯ç”¨æ—¶ï¼Œå®ƒå°†ä½¿ç”¨è§†é¢‘å¡æ‰€æ”¯æŒçš„最大å„å‘异性。\n" +"ä¸è¿‡ï¼Œè¿™å°†è¦†ç›–原始的纹ç†è¿‡æ»¤æ–¹å¼ï¼Œ\n" +"并å¯èƒ½å¯¼è‡´æŸäº›æ¸¸æˆå±•ç¤ºè§†è§‰å¹²æ‰°ã€‚\n" +"[推è:您的å好,å–决于游æˆ]" + +#: Config.cpp:521 +msgid "" +"Autodetect VRAM Size:\n" +"Since OpenGL cannot do this reliably at the moment, the option to set this manually is available.\n" +"If checked, plugin will try to autodetect VRAM size.\n" +"But if this appears wrong, please uncheck and set it to correct value.\n" +"[Recommended: on]" +msgstr "" +"自动检测显存大å°ï¼š\n" +"-------------------\n" +"由于OpenGLä¸èƒ½å¯é åœ°åšåˆ°ï¼Œå› æ­¤å¯ä»¥é€‰æ‹©æ‰‹åŠ¨è®¾ç½®ã€‚\n" +"当选定,æ’件将å°è¯•è‡ªåŠ¨æ£€æµ‹æ˜¾å­˜çš„大å°ã€‚\n" +"如果出现错误,请å–消选择并将其设置为正确的值。\n" +"[推è:选]" + +#: Config.cpp:523 +msgid "" +"Use frame buffer objects:\n" +"Changes the way FB effects are rendered - with or without usage of the OpenGL Frame Buffer Objects (FBO) extension.\n" +"The choice depends on game and your video card. FBO off is good for NVIDIA cards, while for ATI cards, it's usually best that FBOs are turned on.\n" +"Also, some FB effects works only with one of the methods, no matter, which card you have.\n" +"On the whole, with FBO off, compatibility/ accuracy is a bit better (which is the case for Resident Evil 2).\n" +"However, with FBO on with some systems, it can actually be a bit faster in cases.\n" +"[Recommended: video card and game dependant]" +msgstr "" +"使用帧缓冲对象:\n" +"-----------------\n" +"当选定,å³ä½¿æ²¡æœ‰ä½¿ç”¨OpenGL帧缓冲对象(FBO)扩展,\n" +"它ä»ç„¶ä¼šæ”¹å˜å¸§ç¼“冲效果的呈现方å¼ã€‚\n" +"您的选择å–决于你的游æˆå’Œè§†é¢‘å¡ã€‚对于NVIDIA视频å¡ï¼Œ\n" +"ä¸è¦é€‰æ‹©FBO而对于ATI视频å¡ï¼ŒFBO通常是一个很好的选择。\n" +"\n" +"å¦å¤–,一些帧缓冲效果åªé€‚用其中之一的方法,而ä¸ç®¡è§†é¢‘å¡ã€‚\n" +"整体而言,ä¸é€‰FBO将会增加游æˆå…¼å®¹æ€§ä¸Žå‡†ç¡®æ€§ï¼Œä¾‹å¦‚,\n" +"Resident Evil 2。\n" +"\n" +"然而,在æŸäº›ç³»ç»Ÿä¸Šï¼ŒFBO的选择会加速一些游æˆã€‚\n" +"[推è:å–决于视频å¡å’Œæ¸¸æˆ]" + +#: Config.cpp:578 +msgid "Emulation settings" +msgstr "仿真设置" + +#: Config.cpp:579 +msgid "" +"Filtering mode\n" +"There are three filtering modes possible:\n" +"* Automatic filtering - filter exactly how the N64 specifies.\n" +"* Point-sampled filtering - causes texels to appear square and sharp.\n" +"* Bilinear filtering - interpolates the texture to make it appear more smooth.\n" +"[Recommended: Automatic]" +msgstr "" +"过滤模å¼\n" +"----------\n" +"过滤方å¼æœ‰ä¸‰ç§ï¼š\n" +"*自动过滤\t: 与N64的过滤是相åŒçš„。\n" +"*点采样过滤\t: 使纹ç†å…ƒç´ å‡ºçŽ°æ­£æ–¹å½¢å’Œå°–é”。\n" +"*åŒçº¿æ€§è¿‡æ»¤\t: æ’值纹ç†ï¼Œä½¿å…¶çœ‹èµ·æ¥æ›´å…‰æ»‘。\n" +"[推è:自动]" + +#: Config.cpp:583 +msgid "" +"Buffer swapping method\n" +"There are 3 buffer swapping methods:\n" +"* old - swap buffers when vertical interrupt has occurred.\n" +"* new - swap buffers when set of conditions is satisfied. Prevents flicker on some games.\n" +"* hybrid - mix of first two methods.\n" +"Can prevent even more flickering then previous method, but also can cause artefacts.\n" +"If you have flickering problems in a game (or graphics that don't show),\n" +"try to change swapping method.\n" +"[Recommended: new (hybrid for Paper Mario)]" +msgstr "" +"缓冲交æ¢æ–¹æ³•\n" +"---------------\n" +"缓冲交æ¢æ–¹æ³•æœ‰3ç§ï¼š\n" +"*æ—§\t: 在垂直中断å‘生时,交æ¢ç¼“冲区。\n" +"*æ–°\t: 当æ¡ä»¶ç¬¦åˆæ—¶ï¼Œäº¤æ¢ç¼“冲区。\n" +"\t 防止一些游æˆçš„é—ªçƒã€‚\n" +"*æ··åˆ\t: æ··åˆå‰ä¸¤ç§æ–¹æ³•ã€‚\n" +"\t å¯é˜²æ­¢æ›´å¤šé—ªçƒï¼Œä½†ä¹Ÿå¯èƒ½ä¼šæœ‰è§†è§‰å¹²æ‰°ã€‚\n" +"\n" +"如果您在游æˆä¸­æœ‰é—ªçƒçš„问题(或图形ä¸æ˜¾ç¤ºï¼‰ï¼Œ\n" +"å°è¯•æ”¹å˜äº¤æ¢æ–¹æ³•ã€‚\n" +"[推è:新(Paper Mario - 选择混åˆï¼‰]" + +#: Config.cpp:587 +msgid "" +"Per-pixel level-of-detail calculation\n" +"N64 uses special mechanism for mip-mapping, which nearly impossible to reproduce\n" +"correctly on PC hardware. This option enables approximate emulation of this feature.\n" +"For example, it is required for the Peach/Bowser portrait's transition in Super Mario 64.\n" +"There are 3 modes:\n" +"* off - LOD is not calculated\n" +"* fast - fast imprecise LOD calculation.\n" +"* precise - most precise LOD calculation possible, but more slow.\n" +"[Recommended: your preference]" +msgstr "" +"æ¯ä¸ªåƒç´ è¯¦ç»†ç¨‹åº¦è®¡ç®—\n" +"------------------------\n" +"N64使用特殊的纹ç†æ˜ å°„,几乎是ä¸å¯èƒ½åœ¨ç”µè„‘硬件\n" +"上很正确地å¤åˆ¶ã€‚此选项将å¯ç”¨æ­¤åŠŸèƒ½è¿‘似仿真。\n" +"例如,应用在\"Super Mario 64\"游æˆå†…çš„\n" +"Peach与Bowserè‚–åƒçš„过渡。\n" +"\n" +"有3ç§æ¨¡å¼ï¼š\n" +"*å…³\t: ä¸è¿›è¡ŒLOD计算。\n" +"*å¿«\t: 快而ä¸å‡†çš„LOD计算。\n" +"*准确\t: 最精确的LOD计算,但更慢。\n" +"[推è:您的å好]" + +#: Config.cpp:592 +msgid "" +"Aspect ratio of the output.\n" +"Most N64 games use 4:3 aspect ratio, but some support widescreen too.\n" +"You may select appropriate aspect here and set widescreen mode in game settings.\n" +"In \"Stretch\" mode the output will be stretched to the entire screen,\n" +"other modes may add black borders if necessary" +msgstr "" +"宽高比的输出\n" +"---------------\n" +"大多数N64的游æˆä½¿ç”¨4:3的比例,但一些支æŒå®½å±äº†ã€‚\n" +"ä½ å¯ä»¥åœ¨è¿™é‡Œé€‰æ‹©åˆé€‚的比例,并在游æˆä¸Šè®¾ç½®å®½å±æ¨¡å¼ã€‚\n" +"在\"伸展\"模å¼ä¸‹ï¼Œè¾“出将被拉伸到整个å±å¹•ï¼Œ\n" +"其它模å¼å¯èƒ½åœ¨å¿…è¦æ—¶åŠ é»‘色边境。" + +#: Config.cpp:595 +msgid "" +"Fog enabled\n" +"Sets fog emulation on//off.\n" +"[Recommended: on]" +msgstr "" +"å¯ç”¨é›¾\n" +"-------\n" +"设置雾仿真的开与关\n" +"[推è:选]" + +#: Config.cpp:597 +msgid "" +"Buffer clear on every frame\n" +"Forces the frame buffer to be cleared every frame drawn.\n" +"Usually frame buffer clear is controlled by the game.\n" +"However, in some cases it is not well emulated,\n" +"and some garbage may be left on the screen.\n" +"In such cases, this option must be set on.\n" +"[Recommended: on]" +msgstr "" +"清除æ¯ä¸€å¸§ç¼“冲\n" +"-----------------\n" +"强行在æ¯ä¸€å¸§ä¸­çš„绘制,清除帧缓冲。\n" +"通常帧缓冲是由游æˆæŽ§åˆ¶çš„。\n" +"但是,在æŸäº›æƒ…况下,没有很好地模拟,\n" +"有些图形垃圾å¯èƒ½ä¼šæ®‹ç•™åœ¨å±å¹•ä¸Šã€‚\n" +"在这ç§æƒ…况下,此选项必须设置。\n" +"[推è:选]" + +#: Config.cpp:599 +msgid "" +"Enable frame buffer emulation\n" +"If on, plugin will try to detect frame buffer usage and apply appropriate frame buffer emulation.\n" +"[Recommended: on for games which use frame buffer effects]" +msgstr "" +"å¯ç”¨å¸§ç¼“冲仿真\n" +"-----------------\n" +"当选定,æ’件将å°è¯•æ£€æµ‹å¸§ç¼“冲区的\n" +"使用情况而采用适当的帧缓冲仿真。\n" +"[推è:游æˆä½¿ç”¨å¸§ç¼“冲效果- 选]" + +#: Config.cpp:601 +msgid "" +"Enable hardware frame buffer emulation\n" +"If this option is on, plugin will create auxiliary frame buffers in video memory instead of copying\n" +"frame buffer content into main memory. This allows plugin to run frame buffer effects without slowdown\n" +"and without scaling image down to N64's native resolution. This feature is fully supported by\n" +"Voodoo 4/5 cards and partially by Voodoo3 and Banshee. Modern cards also fully support it.\n" +"[Recommended: on, if supported by your hardware]" +msgstr "" +"å¯ç”¨ç¡¬ä»¶å¸§ç¼“冲仿真\n" +"----------------------\n" +"当选定,æ’件将在视频内存中创建辅助的帧缓冲器,\n" +"而ä¸æ˜¯å¤åˆ¶åˆ°ä¸»å­˜å‚¨å™¨ã€‚è¿™å…许æ’件è¿è¡Œå¸§ç¼“冲效果而\n" +"ä¸æ”¾ç¼“,并ä¸ç¼©æ”¾å›¾åƒåˆ°N64的原始分辨率。\n" +"\n" +"此功能会完全支æŒVoodoo 4与5å¡å’Œéƒ¨åˆ†Voodoo3\n" +"å’ŒBanshee。现代å¡ä¹Ÿå®Œå…¨æ”¯æŒã€‚\n" +"[推èï¼šç¡¬ä»¶æ”¯æŒ - 选]" + +#: Config.cpp:604 +msgid "" +"Get information about frame buffers\n" +"This is compatibility option. It must be set on for Mupen64 and off for 1964" +msgstr "" +"å–帧缓冲器的有关信æ¯\n" +"这是兼容性选项。在Mupen64上,必须设置为开\n" +"而在1964必须设置为关" + +#: Config.cpp:606 +msgid "" +"Read every frame\n" +"In some games plugin can't detect frame buffer usage.\n" +"In such cases you need to enable this option to see frame buffer effects.\n" +"Every drawn frame will be read from video card -> it works very slow.\n" +"[Recommended: mostly off (needed only for a few games)]" +msgstr "" +"读å–æ¯ä¸€å¸§\n" +"------------\n" +"在一些游æˆä¸Šï¼Œæ’件无法检测到帧缓冲区的使用。\n" +"在这ç§æƒ…况下,您需è¦å¯ç”¨è¯¥é€‰é¡¹æ‰èƒ½çœ‹åˆ°å¸§ç¼“冲效果。\n" +"æ¯ä¸€ä¸ªå¸§çš„绘制将从视频å¡è¯»å–->这是éžå¸¸çš„缓慢。\n" +"[推è:大多ä¸é€‰ï¼ˆè¿ç”¨åœ¨å°‘数游æˆä¸Šï¼‰]" + +#: Config.cpp:608 +msgid "" +"Render N64 frame buffer as texture\n" +"When this option is enabled, content of each N64 frame buffer is rendered\n" +"as texture over the frame, rendered by the plugin. This prevents graphics lost,\n" +"but may cause slowdowns and various glitches in some games.\n" +"[Recommended: mostly off]" +msgstr "" +"呈现N64的帧缓冲为纹ç†\n" +"--------------------------\n" +"当选定,æ¯ä¸ªN64的帧缓冲的内容将由æ’件\n" +"在帧上呈现为纹ç†ã€‚è¿™å¯ä»¥é˜²æ­¢å›¾å½¢çš„æµå¤±ï¼Œ\n" +"但å¯èƒ½ä¼šå¯¼è‡´é€Ÿåº¦ä¸‹é™ï¼Œå’Œä¸€äº›æ¸¸æˆçš„å„ç§æ•…障。\n" +"[推è:大多ä¸é€‰]" + +#: Config.cpp:610 +msgid "" +"Detect CPU write to the N64 frame buffer\n" +"This option works as the previous options, but the plugin is trying to detect,\n" +"when game uses CPU writes to N64 frame buffer. The N64 frame buffer is rendered\n" +"only when CPU writes is detected. Use this option for those games, in which you\n" +"see still image or no image at all for some time with no reason.\n" +"[Recommended: mostly off]" +msgstr "" +"检测CPU写入到N64帧缓冲\n" +"----------------------------\n" +"此选项与上一个选项有一样的功能,但æ’件会试图\n" +"检测游æˆåœ¨ä½•æ—¶ä½¿ç”¨CPU写入到N64的帧缓冲区。\n" +"当检测到CPU写入时,æ‰ä¼šå‘ˆçŽ°N64的帧缓冲。\n" +"\n" +"如果过了一段时间åŽï¼Œä½ åªèƒ½çœ‹åˆ°é™æ€å›¾åƒæˆ–\n" +"无图åƒæ—¶ï¼Œè¯·ä½¿ç”¨æ­¤é€‰é¡¹ã€‚\n" +"[推è:大多ä¸é€‰]" + +#: Config.cpp:612 +msgid "" +"Enable depth buffer rendering\n" +"This option is used to fully emulate N64 depth buffer.\n" +"It is required for correct emulation of depth buffer based effects.\n" +"However, it requires fast (>1GHz) CPU to work full speed.\n" +"[Recommended: on for fast PC]" +msgstr "" +"å¯ç”¨æ·±åº¦ç¼“冲渲染\n" +"-------------------\n" +"此选项用于完全模仿N64的深度缓冲区。\n" +"这是需è¦æ­£ç¡®çš„仿真深度缓冲的效果。\n" +"但是,它需è¦å¿«é€Ÿï¼ˆ>1GHz)的CPUæ‰èƒ½è¾¾åˆ°å…¨é€Ÿã€‚\n" +"[推è:快速电脑 - 选]" + +#: Config.cpp:620 +msgid "" +"Filters:\n" +"Apply a filter to either smooth or sharpen textures.\n" +"There are 4 different smoothing filters and 2 different sharpening filters.\n" +"The higher the number, the stronger the effect,\n" +"i.e. \"Smoothing filter 4\" will have a much more noticeable effect than \"Smoothing filter 1\".\n" +"Be aware that performance may have an impact depending on the game and/or the PC.\n" +"[Recommended: your preference]" +msgstr "" +"过滤器:\n" +"--------\n" +"应用一个过滤器æ¥å¹³æ»‘或é”化纹ç†ã€‚\n" +"有4ç§ä¸åŒçš„平滑过滤器和2个ä¸åŒçš„é”化过滤器。\n" +"- 数字越高,效果越强。\n" +"- 例如,平滑过滤器4将比1有更明显的效果。\n" +"\n" +"注æ„:\t游æˆæ€§èƒ½å¯èƒ½ä¼šå—到影å“,\n" +"\tå–决于游æˆä¸Žæˆ–电脑。\n" +"[推è:您的å好]" + +#: Config.cpp:624 +msgid "" +"Texture enhancement:\n" +"7 different filters are selectable here, each one with a distinctive look.\n" +"Be aware of possible performance impacts.\n" +"\n" +"IMPORTANT: 'Store' mode - saves textures in cache 'as is'. It can improve performance in games, which load many textures.\n" +"Disable 'Ignore backgrounds' option for better result.\n" +"\n" +"[Recommended: your preference]" +msgstr "" +"纹ç†å¢žå¼ºï¼š\n" +"----------\n" +"在这里å¯é€‰æ‹©7ç§ä¸åŒçš„过滤器,æ¯ä¸€ä¸ªå…·æœ‰ç‹¬ç‰¹çš„外观。\n" +"注æ„:\tå¯èƒ½ä¼šæœ‰æ€§èƒ½å½±å“。\n" +"\n" +"è¦ç‚¹:\t\"存储\"æ¨¡å¼ - 储存在缓存的纹ç†ä¸º\"原状\"。\n" +"\t它å¯ä»¥æ高游æˆçš„性能,但载有很多纹ç†ã€‚\n" +"\tç¦ç”¨\"忽略背景\"选项,让效果更佳。\n" +"[推è:您的å好]" + +#: Config.cpp:628 +msgid "" +"Texture cache size:\n" +"Enhanced and filtered textures can be cached to aid performance.\n" +"This setting will adjust how much PC memory will be dedicated for texture cache.\n" +"This helps boost performance if there are subsequent requests for the same texture (usually the case).\n" +"Normally, 128MB should be more than enough but there is a sweet spot for each game.\n" +"Super Mario may not need more than 32megs, but Conker streams a lot of textures,\n" +"so setting 256+ megs can boost performance. Adjust accordingly if you are encountering speed issues.\n" +"'0' disables cache.\n" +"[Recommended: PC and game dependant]" +msgstr "" +"纹ç†ç¼“存大å°ï¼š\n" +"---------------\n" +"加强和过滤的纹ç†å¯è¢«ç¼“存已助性能。\n" +"此设置将调整多少电脑内存为纹ç†ç¼“存专用。\n" +"如果是相åŒçš„纹ç†ï¼ˆé€šå¸¸å¦‚此)有åŽç»­è¯·æ±‚,\n" +"这将有助于æ高性能。一般情况下,\n" +"128兆应该是绰绰有余,但æ¯ä¸ªæ¸¸æˆæœ‰å…¶ç”œç‚¹ã€‚\n" +"\n" +"\"Super Mario\"å¯èƒ½ä¸éœ€è¦æ¯”32兆多,\n" +"但\"Conker\"用很多纹ç†ï¼Œå› è€Œç”¨256å…†+\n" +"å¯æ高性能。如果你é‡åˆ°é€Ÿåº¦é—®é¢˜ï¼Œ\n" +"å¯æ ¹æ®å®žé™…情况调整。\n" +"\n" +"'0'ç¦ç”¨ç¼“存。\n" +"[推è:å–决于电脑和游æˆ]" + +#: Config.cpp:634 +msgid "" +"Ignore Backgrounds:\n" +"It is used to skip enhancement for long narrow textures, usually used for backgrounds.\n" +"This may save texture memory greatly and increase performance.\n" +"[Recommended: on (off for 'Store' mode)]" +msgstr "" +"忽略背景:\n" +"----------\n" +"它是用æ¥è·³è¿‡å¢žå¼ºç‹­é•¿çº¹ç†ï¼ˆé€šå¸¸ä¸ºèƒŒæ™¯ç”¨ï¼‰ã€‚\n" +"è¿™å¯èƒ½ä¼šå¤§å¤§èŠ‚çœçº¹ç†å†…存和æ高性能。\n" +"[推è:选(\"存储\"模å¼- ä¸é€‰ï¼‰]" + +#: Config.cpp:636 +msgid "" +"Texture compression:\n" +"Textures will be compressed using selected texture compression method.\n" +"The overall compression ratio is about 1/6 for FXT1 and 1/4 for S3TC.\n" +"In addition to saving space on the texture cache,\n" +"the space occupied on the GFX hardware's texture RAM,\n" +"by the enhanced textures, will be greatly reduced.\n" +"This minimizes texture RAM usage,\n" +"decreasing the number of texture swaps to the GFX hardware leading to performance gains.\n" +"However, due to the nature of lossy compression of FXT1 and S3TC, using this option can sometimes lead to quality degradation of small size textures and color banding of gradient colored textures.\n" +"[Recommended: off]" +msgstr "" +"纹ç†åŽ‹ç¼©ï¼š\n" +"----------\n" +"纹ç†çš„压缩是ä¾ç…§é€‰å®šçº¹ç†åŽ‹ç¼©æ–¹æ³•ã€‚\n" +"整体压缩比大约是1/6于FXT1或1/4于S3TC.\n" +"除了节çœçº¹ç†ç¼“存的空间,在显å¡ç¡¬ä»¶çš„纹ç†å†…å­˜\n" +"所å é¢†çš„增强纹ç†ç©ºé—´ï¼Œå°†å¤§å¤§å‡å°‘。\n" +"这将最大é™åº¦åœ°å‡å°‘纹ç†å†…存的使用,\n" +"é™ä½Žçº¹ç†åœ¨æ˜¾å¡ç¡¬ä»¶çš„交æ¢æ•°æ¬¡ï¼Œå¯¼è‡´æ高效能。\n" +"\n" +"然而,由于FXT1å’ŒS3TC有æŸåŽ‹ç¼©çš„性质,\n" +"使用此选项有时会导致体积å°çº¹ç†çš„è´¨é‡é€€åŒ–\n" +"å’Œæ¸å˜è‰²çš„纹ç†å‡ºçŽ°è‰²å¸¦ã€‚\n" +"[推è:ä¸é€‰]" + +#: Config.cpp:640 +msgid "" +"Compress texture cache:\n" +"Memory will be compressed so that more textures can be held in the texture cache.\n" +"The compression ratio varies with each texture,\n" +"but 1/5 of the original size would be a modest approximation.\n" +"They will be decompressed on-the-fly, before being downloaded to the gfx hardware.\n" +"This option will still help save memory space even when using texture compression.\n" +"[Recommended: on]" +msgstr "" +"压缩纹ç†ç¼“存:\n" +"---------------\n" +"内存将被压缩,使更多的纹ç†å¯ä»¥å­˜å‚¨åœ¨çº¹ç†ç¼“存。\n" +"压缩比率会因纹ç†è€Œå„有ä¸åŒï¼Œä½†1/5的原æ¥å¤§å°\n" +"将是一个温和的逼近。\n" +"他们将立å³è¢«è§£åŽ‹ç¼©ï¼Œç„¶åŽè¢«ä¸‹è½½åˆ°æ˜¾å¡ç¡¬ä»¶ã€‚\n" +"å³ä½¿ä½¿ç”¨çº¹ç†åŽ‹ç¼©ï¼Œæ­¤é€‰é¡¹ä»ä¼šèŠ‚çœå†…存空间。\n" +"[推è:选]" + +#: Config.cpp:642 +msgid "" +"Hi-res pack format:\n" +"Choose which method is to be used for loading Hi-res texture packs.\n" +"Only Rice's format is available currently.\n" +"Leave on \"None\" if you will not be needing to load hi-res packs.\n" +"[Recommended: Rice's format. Default: \"None\"]" +msgstr "" +"高清晰度包格å¼ï¼š\n" +"------------------\n" +"选择哪ç§æ–¹æ³•æ¥åŠ è½½é«˜åˆ†è¾¨çŽ‡çº¹ç†åŒ…。\n" +"ç›®å‰åªèƒ½ç”¨ Rice's æ ¼å¼ã€‚\n" +"如果你ä¸éœ€è¦åŠ è½½é«˜æ¸…晰度包,请选择\"æ— \"。\n" +"[推è:Rice's æ ¼å¼ã€‚默认:无]" + +#: Config.cpp:646 +msgid "" +"Tile textures:\n" +"When on, wide texture will be split on several tiles to fit in one 256-width texture.\n" +"This tiled texture takes much less video memory space and thus overall performance will increase.\n" +"However, corresponding polygons must be split too, and this is not polished yet\n" +"- various issues are possible, including black lines and polygons distortions.\n" +"[Recommended: off]" +msgstr "" +"图砖纹ç†ï¼š\n" +"----------\n" +"当选定,宽纹ç†å°†è¢«åˆ†å‰²åœ¨å‡ ä¸ªç“¦ç‰‡ï¼Œä»¥é€‚应一个256宽的纹ç†ã€‚\n" +"这平铺纹ç†èŠ±è´¹æ›´å°‘的视频内存空间,因此整体性能会有所增加。\n" +"但是,必须相应的多边形也需è¦åˆ†å‰²ï¼Œå´å°šæœªå®Œå…¨å¼€å‘出æ¥ã€‚\n" +"- å„ç§é—®é¢˜éƒ½æœ‰å¯èƒ½çš„,包括黑线和多边形的扭曲。\n" +"[推è:ä¸é€‰]" + +#: Config.cpp:648 +msgid "" +"Force 16bpp textures:\n" +"The color of the textures will be reduced to 16bpp.\n" +"This is another space saver and performance enhancer.\n" +"This halves the space used on the texture cache and the GFX hardware's texture RAM.\n" +"Color reduction is done so that the original quality is preserved as much as possible.\n" +"Depending on the texture, this usually is hardly noticeable.\n" +"Sometimes though, it can be: skies are a good example.\n" +"[Recommended: off]" +msgstr "" +"强行支æŒ16ä½çº¹ç†ï¼š\n" +"--------------------\n" +"该纹ç†è‰²å½©å°†å‡å°‘为16ä½ã€‚\n" +"这是å¦ä¸€ç§èŠ‚çœç©ºé—´å’Œæ€§èƒ½å¢žå¼ºã€‚\n" +"这将节çœä¸€åŠçš„纹ç†ç¼“存和\n" +"显å¡ç¡¬ä»¶çš„纹ç†å†…存使用的空间。\n" +"\n" +"色彩还原将尽å¯èƒ½ä¿ç•™å…¶åŽŸæ¥çš„颜色。\n" +"æ ¹æ®ä¸åŒçš„纹ç†ï¼Œè¿™é€šå¸¸æ˜¯éš¾ä»¥å¯Ÿè§‰çš„。\n" +"但,并éžä¸å¯èƒ½ï¼šå¤©ç©ºæ˜¯ä¸€ä¸ªå¾ˆå¥½çš„例å­ã€‚\n" +"[推è:ä¸é€‰]" + +#: Config.cpp:650 +msgid "" +"Texture dumping mode:\n" +"In this mode, you have that ability to dump textures on screen to the appropriate folder.\n" +"You can also reload textures while the game is running to see how they look instantly - big time saver!\n" +"\n" +"Hotkeys: \"R\" reloads hires textures from the texture pack - \"D\" toggles texture dumps on/off." +msgstr "" +"纹ç†è½¬å‚¨æ–¹å¼ï¼š\n" +"---------------\n" +"在这模å¼ä¸‹ï¼Œä½ å¯å°†å±å¹•ä¸Šçš„纹ç†è½¬å‚¨åˆ°é€‚当的文件夹。\n" +"您也å¯ä»¥åœ¨æ¸¸æˆè¿è¡Œæ—¶é‡æ–°è½½å…¥çº¹ç†ï¼Œè€Œé©¬ä¸Šçœ‹åˆ°ç»“æžœ\n" +"- 大大节çœæ—¶é—´ï¼\n" +"热键:\tR - é‡è½½é«˜åˆ†è¾¨çŽ‡çº¹ç†çš„纹ç†åŒ…\n" +"\tD - 将切æ¢çº¹ç†è½¬å‚¨å¼€ä¸Žå…³" + +#: Config.cpp:652 +msgid "" +"Alternative CRC calculation:\n" +"This option enables emulation of a palette CRC calculation bug in RiceVideo.\n" +"If some textures are not loaded, try to set this option on/off.\n" +"[Recommended: texture pack dependant, mostly on]" +msgstr "" +"å¦ä¸€ç§CRC计算:\n" +"-----------------\n" +"此选项å¯ä»¥ä»¿çœŸRiceVideo在调色æ¿ä¸Šçš„CRC计算错误。\n" +"如果æŸäº›çº¹ç†ä¸èƒ½åŠ è½½ï¼Œè¯·å°è¯•è®¾ç½®æ­¤é€‰é¡¹å¼€ä¸Žå…³ã€‚\n" +"[推è:å–决于纹ç†åŒ…,大多选]" + +#: Config.cpp:657 +msgid "" +"Compress texture cache:\n" +"When game started, plugin loads all its hi-resolution textures into PC memory.\n" +"Since hi-resolution textures are usually large, the whole pack can take hundreds megabytes of memory.\n" +"Cache compression allows save memory space greatly.\n" +"Textures will be decompressed on-the-fly, before being downloaded to the gfx hardware.\n" +"This option will still help save memory space even when using texture compression.\n" +"[Recommended: on]" +msgstr "" +"压缩纹ç†ç¼“存:\n" +"---------------\n" +"当游æˆå¼€å§‹ï¼Œæ’件加载所有\n" +"的高清晰度纹ç†åœ¨ç”µè„‘内存。\n" +"由于高清晰度的纹ç†é€šå¸¸å¾ˆå¤§ï¼Œ\n" +"整个包å¯ä»¥åˆ©ç”¨æ•°ç™¾å…†çš„内存。\n" +"缓存压缩å¯ä»¥å¤§å¤§èŠ‚çœå­˜å‚¨ç©ºé—´ã€‚\n" +"纹ç†å°†ç«‹å³è¢«è§£åŽ‹ç¼©ï¼Œç„¶åŽä¸‹è½½åˆ°æ˜¾å¡ç¡¬ä»¶ã€‚\n" +"å³ä½¿ä½¿ç”¨çº¹ç†åŽ‹ç¼©ï¼Œæ­¤é€‰é¡¹ä»ä¼šèŠ‚çœå†…存空间。\n" +"[推è:选]" + +#: Config.cpp:659 +msgid "" +"Use Alpha channel fully:\n" +"When this option is off, 16bit rgba textures will be loaded using RiceVideo style\n" +"- with 1bit for alpha channel.\n" +"When it is on, GlideHQ will check, how alpha channel is used by the hires texture,\n" +"and select most appropriate format for it.\n" +"This gives texture designers freedom to play with alpha, as they need,\n" +"regardless of format of original N64 texture.\n" +"For older and badly designed texture packs it can cause unwanted black borders.\n" +"[Recommended: texture pack dependant]" +msgstr "" +"充分利用é€æ˜Žé€šé“:\n" +"--------------------\n" +"如ä¸é€‰æ­¤é€‰é¡¹ï¼Œä½¿ç”¨RiceVideo风格会加载\n" +"16ä½RGBA纹ç†ä¸Ž1ä½é€æ˜Žé€šé“。\n" +"当选定,GlideHQ将检查高清晰度的纹ç†å¦‚何\n" +"使用é€æ˜Žé€šé“,并选择最适当的格å¼ã€‚\n" +"它让设计者自由å‘挥纹ç†é€æ˜Žçš„使用,\n" +"ä¸è®ºå…¶åŽŸæ¥çš„N64的纹ç†æ ¼å¼ã€‚\n" +"对于旧或设计ä¸è‰¯çš„纹ç†åŒ…,å¯èƒ½ä¼šå‡ºçŽ°ä¸å¿…è¦çš„黑边。\n" +"[推è:å–决于纹ç†åŒ…]" + +#: Config.cpp:662 +msgid "" +"Save texture cache to HD:\n" +"\n" +"For enhanced textures cache:\n" +"This will save all previously loaded and enhanced textures to HD.\n" +"So upon next game launch, all the textures will be instantly loaded, resulting in smoother performance.\n" +"\n" +"For high-resolution textures cache:\n" +"After creation, loading hi-res texture will take only a few seconds upon game launch,\n" +"as opposed to the 5 -60 seconds a pack can take to load without this cache file.\n" +"The only downside here is upon any changes to the pack, the cache file will need to be manually deleted.\n" +"\n" +"Saved cache files go into a folder called \"Cache\" within the Plugins folder.\n" +"\n" +"[Highly Recommended: on]" +msgstr "" +"ä¿å­˜çº¹ç†ç¼“到硬盘:\n" +"--------------------\n" +"增强纹ç†ç¼“存:\n" +"---------------\n" +"这将ä¿å­˜æ‰€æœ‰ä¹‹å‰åŠ è½½å’Œå¢žå¼ºçº¹ç†åˆ°ç¡¬ç›˜ã€‚\n" +"下一次游æˆå¼€å§‹åŽï¼Œæ‰€æœ‰çš„纹ç†å°†å³åˆ»åŠ è½½ï¼Œ\n" +"导致更顺畅的性能。\n" +"\n" +"高分辨率的纹ç†ç¼“存:\n" +"----------------------\n" +"创建åŽï¼Œå½“游æˆå¯åŠ¨æ—¶ï¼ŒåŠ è½½é«˜æ¸…晰度的纹ç†åªéœ€å‡ ç§’钟。\n" +"如果没有这个缓存文件,载入纹ç†åŒ…需è¦5-60秒。\n" +"唯一的缺点是在更改纹ç†åŒ…时,缓存文件将需è¦æ‰‹åŠ¨åˆ é™¤ã€‚\n" +"\n" +"ä¿å­˜çš„缓存文将被ä¿å­˜åˆ°Plugins文件夹内的Cache文件夹。\n" +"[强烈推è:选]" + +#: Config.cpp:685 +msgid "Debug" +msgstr "调试" + +#: Config.cpp:686 +msgid "" +"Autodetect Microcode\n" +"If this option is checked, the microcode of the game\n" +"will be detected automatically from the INI, and\n" +"therefore it will not need to be set in this\n" +"configuration dialog.\n" +"[Recommended: on]" +msgstr "" +"自动检测微ç \n" +"当选定,游æˆçš„å¾®ç ä¼šè‡ªåŠ¨ä»ŽINI检测到。\n" +"因此它ä¸éœ€è¦åœ¨æ­¤é…置对è¯æ¡†ä¸­è®¾ç½®ã€‚\n" +"[推è:选]" + +#: Config.cpp:688 +msgid "" +"Force Microcode\n" +"This option ONLY has an effect if Autodetect Microcode\n" +"is unchecked, the crc from the game could not be\n" +"found in the INI, OR after the game has already started\n" +"running. In any of those three cases, this will\n" +"select the microcode to use\n" +"[Recommended: any, turn on Autodetect Microcode]" +msgstr "" +"强行支æŒå¾®ç \n" +"此选项是在以下情况æ‰æœ‰æ•ˆ:\n" +"1. 如果没选定自动检测微ç ï¼Œ\n" +"2. 游æˆçš„CRC在INI找ä¸åˆ°ï¼Œæˆ–\n" +"3. 游æˆå·²ç»å¼€å§‹è¿è¡Œã€‚\n" +"在这三ç§æƒ…形之下,它将使用微ç ã€‚\n" +"[推è:任何,选自\"动检测微ç \"]" + +#: Config.cpp:692 +msgid "" +"Wireframe\n" +"This option, when checked, makes it so that the plugin will draw only the\n" +"outlines of objects. The colors specified in the combo box to the right\n" +"determines the color that the wireframes show up as.\n" +"[Recommended: off]" +msgstr "" +"线框\n" +"当选定,æ’件会画出对象的轮廓。\n" +"在组åˆæ¡†ä¸­æŒ‡å®šçš„颜色,将决定线框颜色的显示。\n" +"[推è:ä¸é€‰]" + +#: Config.cpp:694 +msgid "" +"Wireframe Colors\n" +"This selects the colors to use for the wireframes (if wireframe mode is enabled).\n" +"There are 3 modes:\n" +"* Original colors - draw exactly as it would normally, textures and all, only in wireframes.\n" +"* Vertex colors - use the colors specified in the vertices to draw the wireframes with.\n" +"* Red only - use a constant red color to draw the wireframes.\n" +"[Recommended: Vertex colors]" +msgstr "" +"线框颜色\n" +"这将选择用于线框的颜色(如线框模å¼å·²å¯ç”¨ï¼‰ã€‚\n" +"有3ç§æ¨¡å¼ï¼š\n" +"*原始颜色\t: 纹ç†å’Œæ‰€æœ‰ï¼Œæ˜¯ä¸ŽåŽŸæ¥ç›¸åŒçš„颜色æ¥ç»˜åˆ¶çº¿æ¡†ã€‚\n" +"*顶点颜色\t: 使用指定的顶点æ¥ç»˜åˆ¶çº¿æ¡†çš„颜色。\n" +"*仅红\t: 利用固定的红色æ¥ç»˜åˆ¶çº¿æ¡†ã€‚\n" +"[推è:顶点颜色]" + +#: Config.cpp:696 +msgid "" +"Log to RDP.txt\n" +"RECOMMENDED FOR DEBUGGING ONLY - this option, when checked, will log EVERY SINGLE\n" +"COMMAND the plugin processes to a file called RDP.txt in the current directory.\n" +"This is incredibly slow, so I recommend keeping it disabled.\n" +"[Recommended: off]" +msgstr "" +"登录到RDP.txt\n" +"推è仅调试 - 当选定,将记录该æ’件程åºçš„\n" +"æ¯ä¸€ä¸ªå‘½ä»¤åˆ°å½“å‰ç›®å½•çš„RDP.txt。\n" +"这是令人难以置信的慢,所以我建议ä¿æŒç¦ç”¨ã€‚\n" +"[推è:ä¸é€‰]" + +#: Config.cpp:698 +msgid "" +"Unknown combiners as red\n" +"Objects that use an unimplemented combine mode will show up as red instead of\n" +"assuming texture with full alpha. Disable this option to remove the red stuff\n" +"and at least have a guess at the correct combine mode.\n" +"[Recommended: off]" +msgstr "" +"未知åˆæˆå™¨ä¸ºçº¢è‰²\n" +"如果对象使用一个未知的åˆæˆæ¨¡å¼ï¼Œå®ƒä¼šæ˜¾ç¤ºä¸ºçº¢è‰²è€Œä¸æ˜¯\n" +"å‡è®¾çº¹ç†å…·æœ‰å®Œå…¨é€æ˜Žçš„功能。ç¦ç”¨æ­¤é€‰é¡¹ï¼Œåˆ é™¤çº¢è‰²çš„东西,\n" +"并至少能对正确的åˆæˆæ¨¡å¼ä½œå‡ºçŒœæµ‹ã€‚\n" +"[推è:ä¸é€‰]" + +#: Config.cpp:700 +msgid "" +"Log clear every frame\n" +"RECOMMENDED FOR DEBUGGING ONLY - this option has no effect unless 'Log to RDP.txt'\n" +"is checked. This will make it so that the log, RDP.txt, will be cleared at the\n" +"beginning of every frame.\n" +"[Recommended: off]" +msgstr "" +"在æ¯ä¸€å¸§æ¸…除记录\n" +"推è仅调试 - 这个选项没有任何作用,除éžé€‰æ‹©\"记录到RDP.txt\"。\n" +"这将让这个记录RDP.txt,在æ¯ä¸€å¸§çš„开始清除。\n" +"[推è:ä¸é€‰]" + +#: Config.cpp:702 +msgid "" +"Log unknown combiners\n" +"RECOMMENDED FOR DEBUGGING ONLY - when checked, this option will cause every\n" +"unimplemented combiner drawn to be logged to a file called Unimp.txt in the\n" +"current directory. This becomes slow when there are unimplemented combiners\n" +"on the screen, so I recommend keeping it disabled.\n" +"[Recommended: off]" +msgstr "" +"登录ä¸æ˜Žåˆæˆå™¨\n" +"推è仅调试 - 当选定,这个选项将导致所有未执行\n" +"的绘制åˆæˆå™¨è¢«è®°å½•åˆ° Unimp.txt的文件。\n" +"如果有未执行的åˆæˆå™¨åœ¨å±å¹•ä¸Šï¼Œå®ƒä¼šå˜å¾—缓慢,\n" +"所以我建议ä¿æŒç¦ç”¨ã€‚\n" +"[推è:ä¸é€‰]" + +#: Config.cpp:704 +msgid "" +"Run and log in window\n" +"RECOMMENDED FOR DEBUGGING ONLY - this option will make it so that the plugin will\n" +"still process dlists in windowed mode. This allows for logging to occur while not\n" +"in fullscreen, possibly allowing you to debug a crash.\n" +"[Recommended: off]" +msgstr "" +"è¿è¡Œå¹¶ç™»å½•çª—å£\n" +"推è仅调试 - 这个选项将让æ’件ä»ç„¶ä¼šåœ¨çª—å£æ¨¡å¼å¤„ç†dlists。\n" +"虽然ä¸æ˜¯åœ¨å…¨å±ï¼Œä½†ä»å…许记录,å¯èƒ½è®©ä½ è°ƒè¯•å´©æºƒçš„原因。\n" +"[推è:ä¸é€‰]" + +#: Config.cpp:706 +msgid "" +"Clear unknown combiner log every frame\n" +"RECOMMENDED FOR DEBUGGING ONLY - this option works much like 'Log clear every frame'\n" +"except it clears the combiner log (Unimp.txt) instead of RDP.txt at the\n" +"beginning of each frame. Again, this option has no effect if 'combiner logging' is disabled.\n" +"[Recommended: off]" +msgstr "" +"在æ¯ä¸€å¸§æ¸…除未知åˆæˆå™¨è®°å½•\n" +"推è仅调试 - 这个选项很åƒ\"在æ¯ä¸€å¸§æ¸…除记录\",\n" +"除了它在æ¯ä¸€å¸§çš„开始清除åˆæˆå™¨è®°å½•ï¼ˆUnimp.txt),\n" +"而ä¸æ˜¯RDP.txt。\n" +"如果\"åˆæˆå™¨è®°å½•\"被ç¦ç”¨ï¼Œè¿™ä¸ªé€‰é¡¹ä¸ä¼šèµ·ä½œç”¨ã€‚\n" +"[推è:ä¸é€‰]" + +#: Config.cpp:709 +msgid "" +"Bilinear filter texture cache\n" +"RECOMMENDED FOR DEBUGGING ONLY - when checked, this option will make the graphical\n" +"debugger texture cache use bilinear filtering as opposed to point-sampled filtering,\n" +"which it will use otherwise. See 'Filtering mode' for descriptions of bilinear and\n" +"point-sampled filtering.\n" +"[Recommended: off]" +msgstr "" +"åŒçº¿æ€§è¿‡æ»¤çº¹ç†ç¼“å­˜\n" +"---------------------\n" +"推è仅调试 - 当选定,此选项将使图形调试器的纹ç†ç¼“å­˜\n" +"使用åŒçº¿æ€§è¿‡æ»¤çº¹ç†ç¼“存,而ä¸æ˜¯ç‚¹é‡‡æ ·è¿‡æ»¤ã€‚\n" +"阅读\"过滤模å¼\"对åŒçº¿æ€§å’Œç‚¹é‡‡æ ·è¿‡æ»¤çš„æ述。\n" +"[推è:ä¸é€‰]" + +#: Config.cpp:1104 +msgid "Glide64 settings" +msgstr "Glide64 设置" + +#: Config.cpp:1293 +msgid "About Glide64" +msgstr "关于Glide64" + +#: Config.cpp:1326 +msgid "authors:" +msgstr "作者:" + +#: Config.cpp:1330 +msgid "" +"Dave2001. Original author and former main developer.\n" +"He founded Glide64 project on Dec. 29th, 2001.\n" +"Left the project at fall of 2002.\n" +msgstr "" +"Dave2001。 原作者和原主è¦å¼€å‘者。\n" +"他在2001å¹´12月29日创立Glide64项目。\n" +"在2002年的秋天离开Glide64项目。\n" + +#: Config.cpp:1336 +msgid "" +"Gugaman. Developer. Joined the project at winter 2002\n" +" and left it at fall 2002." +msgstr "" +"å¼€å‘人员Gugaman。在2002年冬季加入了这个项目,\n" +"在2002年秋天离开Glide64项目。" + +#: Config.cpp:1342 +msgid "" +"Sergey 'Gonetz' Lipski. Joined the project at winter 2002.\n" +"Main developer since fall of 2002." +msgstr "" +"Sergey 'Gonetz' Lipsk。在2002年冬季加入了这个项目。\n" +"主è¦å¼€å‘自2002年秋季。" + +#: Config.cpp:1347 +msgid "Hiroshi 'KoolSmoky' Morii, Joined the project in 2007. " +msgstr "Hiroshi 'KoolSmoky' Morii,加入该项目于2007年。" + +#: Config.cpp:1350 +msgid "Glitch64 (the wrapper) authors:" +msgstr "Glitch64(包装)作者:" + +#: Config.cpp:1374 +msgid "GlideHQ author:" +msgstr "GlideHQ 作者:" + +#: Config.cpp:1381 +msgid "beta tester:" +msgstr "Beta测试者:" + +#: Config.cpp:1388 +msgid "" +"special thanks to:\n" +" Orkin, Rice, Daniel Borca, Legend.\n" +"Thanks to EmuXHaven for hosting my site:\n" +"http://glide64.emuxhaven.net\n" +msgstr "" +"特别感谢:\n" +"--------\n" +"Orkin, Rice, Daniel Borca, Legend.\n" +"æ„Ÿè°¢ EmuXHaven æ供网站:\n" +"http://glide64.emuxhaven.net\n" + diff --git a/Source/Glide64/Internalization/Glide64_zh_TW.po b/Source/Glide64/Internalization/Glide64_zh_TW.po new file mode 100644 index 000000000..87c442677 --- /dev/null +++ b/Source/Glide64/Internalization/Glide64_zh_TW.po @@ -0,0 +1,1419 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: Glide64 Chinese Translation v1.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2011-12-19 17:29+0700\n" +"PO-Revision-Date: 2011-12-19 18:00+0700\n" +"Last-Translator: Navitel \n" +"Language-Team: \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Poedit-SourceCharset: utf-8\n" +"X-Poedit-Language: Chinese\n" + +#: Config.cpp:64 +msgid "Rendering" +msgstr "渲染" + +#: Config.cpp:65 +msgid "Other" +msgstr "其它" + +#: Config.cpp:66 +msgid "Speed" +msgstr "速度" + +#: Config.cpp:67 +msgid "Time" +msgstr "時間" + +#: Config.cpp:68 +msgid "On screen display" +msgstr "在螢幕上顯示" + +#: Config.cpp:69 +msgid "OpenGL settings" +msgstr "OpenGL設置" + +#: Config.cpp:70 +#: Config.cpp:137 +msgid "Frame buffer emulation" +msgstr "幀緩è¡å€æ¨¡æ“¬" + +#: Config.cpp:71 +msgid "" +"Windowed or\n" +"3dfx card resolution:" +msgstr "" +"視窗或\n" +"3dfx解æžåº¦:" + +#: Config.cpp:99 +msgid "Vertical sync" +msgstr "åž‚ç›´åŒæ­¥" + +#: Config.cpp:100 +msgid "Show advanced emulation options" +msgstr "顯示高級模擬é¸é …" + +#: Config.cpp:101 +msgid "Show texture enhancement options" +msgstr "顯示æ質增強é¸é …" + +#: Config.cpp:102 +msgid "Screenshot format:" +msgstr "截圖格å¼:" + +#: Config.cpp:105 +msgid "Language: " +msgstr "語言: " + +#: Config.cpp:106 +msgid "LANGUAGE_NAME" +msgstr "中文(ç¹é«”)" + +#: Config.cpp:112 +msgid "FPS counter" +msgstr "FPS 計數器" + +#: Config.cpp:113 +msgid "VI/s counter" +msgstr "VI/s 計數器" + +#: Config.cpp:114 +#, c-format +msgid "% speed" +msgstr "% 速度 " + +#: Config.cpp:115 +msgid "Clock enabled" +msgstr "時é˜å•Ÿç”¨" + +#: Config.cpp:116 +msgid "Clock is 24-hour" +msgstr "時é˜ç‚º24å°æ™‚" + +#: Config.cpp:117 +msgid "Transparent text background" +msgstr "é€æ˜Žæ–‡å­—背景" + +#: Config.cpp:118 +msgid "" +"Full screen\n" +"resolution:" +msgstr "" +"全螢幕\n" +"解æžåº¦:" + +#: Config.cpp:121 +msgid "Anisotropic filtering" +msgstr "å„å‘異性éŽæ¿¾" + +#: Config.cpp:122 +msgid "Autodetect " +msgstr "自動檢測 " + +#: Config.cpp:123 +msgid "VRAM size" +msgstr "顯å¡è¨˜æ†¶é«”大å°" + +#: Config.cpp:125 +msgid "Mb" +msgstr "Mb" + +#: Config.cpp:126 +msgid "Use frame buffer objects" +msgstr "使用幀緩è¡å°è±¡" + +#: Config.cpp:133 +msgid "Current game emulation settings. Change with care!" +msgstr "ç›®å‰çš„éŠæˆ²æ¨¡æ“¬è¨­ç½®ã€‚更改時è¦å°å¿ƒï¼" + +#: Config.cpp:135 +msgid "Default emulation settings. Not recommended to change!" +msgstr "默èªæ¨¡æ“¬è¨­ç½®ã€‚ä¸æŽ¨è–¦æ›´æ”¹ï¼" + +#: Config.cpp:136 +msgid "General options" +msgstr "一般é¸é …" + +#: Config.cpp:138 +msgid "Depth buffer emulation" +msgstr "深度緩è¡æ¨¡æ“¬" + +#: Config.cpp:139 +msgid "Filtering mode:" +msgstr "éŽæ¿¾æ¨¡å¼ï¼š" + +#: Config.cpp:141 +msgid "Automatic" +msgstr "自動" + +#: Config.cpp:142 +msgid "Force Bilinear" +msgstr "強制啟用雙線性" + +#: Config.cpp:143 +msgid "Force Point-sampled" +msgstr "強制啟用點å–樣" + +#: Config.cpp:146 +msgid "Buffer swapping method:" +msgstr "ç·©è¡äº¤æ›æ–¹æ³•ï¼š" + +#: Config.cpp:148 +msgid "Old" +msgstr "舊" + +#: Config.cpp:149 +msgid "New" +msgstr "æ–°" + +#: Config.cpp:150 +msgid "Hybrid" +msgstr "æ··åˆ" + +#: Config.cpp:153 +msgid "LOD calculation:" +msgstr "LOD計算:" + +#: Config.cpp:155 +msgid "off" +msgstr "關閉" + +#: Config.cpp:156 +msgid "fast" +msgstr "快速" + +#: Config.cpp:157 +msgid "precise" +msgstr "精確" + +#: Config.cpp:160 +msgid "Aspect ratio:" +msgstr "長寬比:" + +#: Config.cpp:162 +msgid "4:3 (default)" +msgstr "4:3 (默èªï¼‰" + +#: Config.cpp:163 +msgid "Force 16:9" +msgstr "強制啟用 16:9" + +#: Config.cpp:164 +msgid "Stretch" +msgstr "拉伸" + +#: Config.cpp:165 +msgid "Original" +msgstr "" + +#: Config.cpp:168 +msgid "Fog" +msgstr "霧化" + +#: Config.cpp:169 +msgid "Buffer clear on every frame" +msgstr "清除æ¯ä¸€å¹€ç·©è¡" + +#: Config.cpp:170 +msgid "Enable frame buffer emulation" +msgstr "啟用幀緩è¡æ¨¡æ“¬" + +#: Config.cpp:171 +msgid "Hardware frame buffer emulation" +msgstr "硬體模擬幀緩è¡" + +#: Config.cpp:172 +msgid "Get frame buffer info" +msgstr "å–得幀緩è¡è¨Šæ¯" + +#: Config.cpp:173 +msgid "Read every frame (slow!)" +msgstr "讀å–æ¯ä¸€å¹€ï¼ˆç·©æ…¢ï¼ï¼‰" + +#: Config.cpp:174 +msgid "Render N64 frame buffer as texture" +msgstr "呈ç¾N64幀緩è¡æ質" + +#: Config.cpp:175 +msgid "Detect CPU write to the N64 frame buffer" +msgstr "檢測CPU寫入到N64幀緩è¡" + +#: Config.cpp:176 +msgid "Software depth buffer rendering" +msgstr "呈ç¾è»Ÿé«”深度緩è¡" + +#: Config.cpp:200 +#: Config.cpp:619 +msgid "Texture enhancement" +msgstr "æ質增強" + +#: Config.cpp:201 +msgid "Hi-resolution textures" +msgstr "高解æžæ質" + +#: Config.cpp:202 +msgid "Common" +msgstr "一般" + +#: Config.cpp:203 +msgid "Presets" +msgstr "é ç½®" + +#: Config.cpp:204 +#: Config.cpp:205 +msgid "Performance tweaks" +msgstr "效能調整" + +#: Config.cpp:206 +msgid "Filter" +msgstr "濾é¡" + +#: Config.cpp:208 +#: Config.cpp:219 +#: Config.cpp:238 +msgid "None" +msgstr "ç„¡" + +#: Config.cpp:209 +msgid "Smooth filtering 1" +msgstr "平滑éŽæ¿¾ 1" + +#: Config.cpp:210 +msgid "Smooth filtering 2" +msgstr "平滑éŽæ¿¾ 2" + +#: Config.cpp:211 +msgid "Smooth filtering 3" +msgstr "平滑éŽæ¿¾ 3" + +#: Config.cpp:212 +msgid "Smooth filtering 4" +msgstr "平滑éŽæ¿¾ 4" + +#: Config.cpp:213 +msgid "Sharp filtering 1" +msgstr "尖銳éŽæ¿¾ 1" + +#: Config.cpp:214 +msgid "Sharp filtering 2" +msgstr "尖銳éŽæ¿¾ 2" + +#: Config.cpp:217 +msgid "Enhancement" +msgstr "增強" + +#: Config.cpp:220 +msgid "Store" +msgstr "儲存" + +#: Config.cpp:230 +msgid "Texture cache" +msgstr "æ質快å–" + +#: Config.cpp:232 +msgid "Mbytes" +msgstr "MBytes" + +#: Config.cpp:233 +msgid "Ignore Backgrounds" +msgstr "忽略背景" + +#: Config.cpp:234 +#: Config.cpp:245 +msgid "Apply texture compression" +msgstr "應用æ質壓縮" + +#: Config.cpp:235 +#: Config.cpp:246 +msgid "Compress texture cache" +msgstr "壓縮æ質快å–" + +#: Config.cpp:236 +msgid "Format" +msgstr "æ ¼å¼" + +#: Config.cpp:239 +msgid "Rice format" +msgstr "Rice æ ¼å¼" + +#: Config.cpp:242 +msgid "Tile textures" +msgstr "圖磚æ質" + +#: Config.cpp:243 +msgid "Force 16bpp textures" +msgstr "強制啟用16ä½å…ƒæ質" + +#: Config.cpp:244 +msgid "Alternative CRC calculation" +msgstr "å¦ä¸€ç¨®CRC計算" + +#: Config.cpp:247 +msgid "Use alpha channel fully" +msgstr "充分利用é€æ˜Žé€šé“" + +#: Config.cpp:248 +msgid "Texture dumping/editing mode" +msgstr "æ質轉儲與編輯模å¼" + +#: Config.cpp:249 +msgid "Texture compression method" +msgstr "æ質壓縮方å¼" + +#: Config.cpp:255 +msgid "Save texture cache to hard disk" +msgstr "ä¿å­˜æ質快å–到硬碟" + +#: Config.cpp:256 +msgid "Best performance" +msgstr "最佳效能" + +#: Config.cpp:257 +msgid "Best texture quality" +msgstr "最佳æ質質é‡" + +#: Config.cpp:263 +msgid "Developers settings" +msgstr "開發人員設置" + +#: Config.cpp:264 +msgid "Debug/Misc" +msgstr "åµéŒ¯èˆ‡é›œé …" + +#: Config.cpp:265 +msgid "Autodetect Microcode" +msgstr "自動檢測微碼" + +#: Config.cpp:266 +msgid "Force Microcode:" +msgstr "強制啟用微碼:" + +#: Config.cpp:279 +msgid "Wireframe using:" +msgstr "線框使用:" + +#: Config.cpp:281 +msgid "Original colors" +msgstr "原始é¡è‰²" + +#: Config.cpp:282 +msgid "Vertex colors" +msgstr "頂點é¡è‰²" + +#: Config.cpp:283 +msgid "Red only" +msgstr "僅紅色" + +#: Config.cpp:286 +msgid "Log to rdp.txt (SLOW)" +msgstr "登錄到 rdp.txt(緩慢)" + +#: Config.cpp:287 +msgid "Unknown combiners as red" +msgstr "未知的åˆæˆå™¨ç‚ºç´…色" + +#: Config.cpp:288 +msgid "Log clear every frame" +msgstr "在æ¯ä¸€å¹€æ¸…除記錄" + +#: Config.cpp:289 +msgid "Combiner logging" +msgstr "åˆæˆå™¨è¨˜éŒ„" + +#: Config.cpp:290 +msgid "Run (+log) in window" +msgstr "視窗執行(+記錄)" + +#: Config.cpp:291 +msgid "Cmb. clear every frame" +msgstr "在æ¯ä¸€å¹€æ¸…除åˆæˆå™¨" + +#: Config.cpp:292 +msgid "Error log (rdp_e.txt)" +msgstr "錯誤記錄(rdp_e.txt)" + +#: Config.cpp:293 +msgid "Bilinear filter texture cache" +msgstr "雙線性éŽæ¿¾æ質快å–" + +#: Config.cpp:325 +#: Config.cpp:546 +msgid " auto" +msgstr "自動" + +#: Config.cpp:382 +msgid "Please choose language:" +msgstr "è«‹é¸æ“‡èªžè¨€ï¼š" + +#: Config.cpp:383 +msgid "Language" +msgstr "語言" + +#: Config.cpp:390 +msgid "Press OK to change to " +msgstr "按確定更改為 " + +#: Config.cpp:486 +msgid "Basic settings" +msgstr "基本設置" + +#: Config.cpp:487 +msgid "" +"Resolution\n" +"This option selects the fullscreen resolution for 3dfx cards and windowed resolution for other cards\n" +"(note again that for 3dfx cards the plugin must be in fullscreen mode to see anything).\n" +"[Recommended: 640x480, 800x600, 1024x768]" +msgstr "" +"解æžåº¦\n" +"--------\n" +"æ­¤é¸é …é¸æ“‡3dfxå¡ç‚ºå…¨èž¢å¹•è§£æžåº¦å’Œå…¶ä»–視窗解æžåº¦ã€‚\n" +"注æ„:\tå°æ–¼3dfxå¡ä¸Šçš„æ’件必須\n" +"\t在全螢幕模å¼æ‰èƒ½çœ‹åˆ°æ±è¥¿\n" +"[推薦:640x480,800x600,1024X768]" + +#: Config.cpp:491 +msgid "" +"Vertical sync\n" +"This option will enable the vertical sync, which will prevent tearing.\n" +"Note: this option will ONLY have effect if vsync is set to \"Software Controlled\".\n" +msgstr "" +"åž‚ç›´åŒæ­¥\n" +"-------\n" +"æ­¤é¸é …將啟用垂直åŒæ­¥ï¼Œå®ƒå°‡é˜²æ­¢æ’•è£‚。\n" +"注æ„:\t如果垂直åŒæ­¥è¨­ç½®ç‚º\"軟體控制\",\n" +"\tæ­¤é¸é …æ‰æœƒç”Ÿæ•ˆã€‚\n" + +#: Config.cpp:493 +msgid "Select a format, in which screen shots will be saved" +msgstr "é¸æ“‡èž¢å¹•æˆªåœ–所è¦å„²å­˜çš„一種格å¼" + +#: Config.cpp:500 +msgid "" +"Language select:\n" +"Press the button to invoke language selection dialog.\n" +"Selected language will be activated after restart of the configuration dialog." +msgstr "" +"語言é¸æ“‡:\n" +"----------\n" +"按下按鈕調用語言é¸æ“‡è¦–窗。\n" +"é¸æ“‡çš„語言會在é‡æ–°å•Ÿå‹•è¨­ç½®è¦–窗後生效。" + +#: Config.cpp:501 +msgid "" +"FPS counter\n" +"When this option is checked, a FPS (frames per second) counter will be shown\n" +"in the lower left corner of the screen.\n" +"[Recommended: your preference]" +msgstr "" +"FPS 計數器\n" +"------------\n" +"當é¸æ“‡å¾Œï¼ŒFPS(幀æ¯ç§’)計數器\n" +"會顯示在螢幕左下角的角è½ã€‚\n" +"[推薦:您的å好]" + +#: Config.cpp:503 +msgid "" +"VI/s counter\n" +"When this option is checked, a VI/s (vertical interrupts per second) counter\n" +"will be shown in the lower left corner of the screen. This is like the FPS\n" +"counter but will be consistent at 60 VI/s for full speed on NTSC (U) games and\n" +"50 VI/s for full speed on PAL (E) ones.\n" +"[Recommended: your preference]" +msgstr "" +"VI/s 計數器\n" +"------------\n" +"當é¸æ“‡å¾Œï¼ŒVI/s(æ¯ç§’垂直中斷)計數器\n" +"將顯示在螢幕左下角的角è½ã€‚\n" +"它將在全速的 NTSC(U)éŠæˆ²è£¡ç¶­æŒ 60VI/s\n" +"或在全速的 PAL(E)éŠæˆ²è£¡ç¶­æŒ 50VI/s。\n" +"[推薦:您的å好]" + +#: Config.cpp:505 +#, c-format +msgid "" +"% speed\n" +"This displays a percentage of the actual N64 speed in the lower\n" +"left corner of the screen.\n" +"[Recommended: your preference]" +msgstr "" +"% 速度\n" +"--------\n" +"在螢幕左下角的角è½ï¼Œ\n" +"將顯示N64實際速度的百分比。\n" +"[推薦:您的å好]" + +#: Config.cpp:507 +msgid "" +"Clock enabled\n" +"This option will put a clock in the lower right corner of the screen, showing the current time.\n" +"[Recommended: your preference]" +msgstr "" +"時é˜å•Ÿç”¨\n" +"----------\n" +"æ­¤é¸é …將在螢幕的å³ä¸‹è§’\n" +"擺放時é˜ï¼Œé¡¯ç¤ºç›®å‰æ™‚間。\n" +"[推薦:您的å好]" + +#: Config.cpp:510 +msgid "" +"Display hours as 24-hour clock.\n" +"[Recommended: your preference]" +msgstr "" +"顯示時間為24 å°æ™‚制。\n" +"[推薦:您的å好]" + +#: Config.cpp:511 +msgid "" +"Transparent text background\n" +"If this is checked, all on-screen messages will have a transparent background. Otherwise, it will have a solid black background.\n" +"[Recommended: your preference]" +msgstr "" +"é€æ˜Žæ–‡å­—背景\n" +"-----------------\n" +"當é¸æ“‡å¾Œï¼Œæ‰€æœ‰åœ¨èž¢å¹•ä¸Šçš„訊æ¯\n" +"將有一個é€æ˜Žçš„背景。\n" +"å¦å‰‡ï¼Œå°‡æœ‰é»‘色背景。\n" +"[推薦:您的å好]" + +#: Config.cpp:514 +msgid "" +"Enable \"Emulation settings\" panel. For experienced users only!\n" +"It shows default emulation settings when game is not loaded, or current game settings otherwise." +msgstr "" +"啟用\"模擬設置\"é¢æ¿ã€‚給有經驗的用戶ï¼\n" +"它顯示了尚未加載éŠæˆ²çš„默èªæ¨¡æ“¬è¨­ç½®ï¼Œ\n" +"或目å‰çš„éŠæˆ²è¨­ç½®ã€‚" + +#: Config.cpp:516 +msgid "" +"Enable \"Texture enhancement\" panel.\n" +"It shows various enhancement options for original textures as well as options for hi-resolution textures." +msgstr "" +"啟用\"æ質增強\"é¢æ¿ã€‚\n" +"它顯示原來的æ質增強é¸é …\n" +"以åŠé«˜è§£æžæ質é¸é …。" + +#: Config.cpp:517 +msgid "" +"Full screen resolution:\n" +"This sets the full screen resolution for non-3dfx video cards.\n" +"All the resolutions that your video card/monitor support should be displayed.\n" +"[Recommended: native (max) resolution of your monitor - unless performance becomes an issue]" +msgstr "" +"全螢幕解æžåº¦ï¼š\n" +"---------------\n" +"é€™å°‡è¨­ç½®éž 3dfxå¡çš„全螢幕解æžåº¦ã€‚\n" +"您的顯示å¡èˆ‡é¡¯ç¤ºå™¨æ‰€æ”¯æ´çš„解æžåº¦å°‡æœƒé¡¯ç¤ºã€‚\n" +"[推薦:顯示器的原始(最大)解æž- 除éžæ€§èƒ½æˆç‚ºå•é¡Œ]" + +#: Config.cpp:520 +msgid "" +"Anisotropic filtering:\n" +"This filter sharpens and brings out the details of textures that recede into the distance.\n" +"When activated, it will use the max anisotropy your video card supports.\n" +"However, this will override native way of texture filtering and may cause visual artifacts in some games.\n" +"[Recommended: your preference, game dependant]" +msgstr "" +"å„å‘異性éŽæ¿¾ï¼š\n" +"---------------\n" +"該éŽæ¿¾å™¨æœƒéŠ³åŒ–和帶出在é æ–¹é€€åŽ»çš„æ質細節。\n" +"啟用時,它將使用顯示å¡æ‰€æ”¯æ´çš„最大å„å‘異性。\n" +"ä¸éŽï¼Œé€™å°‡è¦†è“‹åŽŸå§‹çš„æ質éŽæ¿¾æ–¹å¼ï¼Œ\n" +"並å¯èƒ½å°Žè‡´æŸäº›éŠæˆ²å±•ç¤ºè¦–覺干擾。\n" +"[推薦:您的å好,å–決於éŠæˆ²]" + +#: Config.cpp:521 +msgid "" +"Autodetect VRAM Size:\n" +"Since OpenGL cannot do this reliably at the moment, the option to set this manually is available.\n" +"If checked, plugin will try to autodetect VRAM size.\n" +"But if this appears wrong, please uncheck and set it to correct value.\n" +"[Recommended: on]" +msgstr "" +"自動檢測顯å¡è¨˜æ†¶é«”大å°ï¼š\n" +"-------------------\n" +"由於 OpenGLç›®å‰ç„¡æ³•å¯é åœ°åšåˆ°ç¢ºå¯¦æª¢æ¸¬ï¼Œå› æ­¤å¯ä»¥é¸æ“‡æ‰‹å‹•è¨­ç½®ã€‚\n" +"當é¸æ“‡å¾Œï¼Œæ’件將嘗試自動檢測顯å¡è¨˜æ†¶é«”的大å°ã€‚\n" +"如果出ç¾éŒ¯èª¤ï¼Œè«‹å–消é¸æ“‡ä¸¦å°‡å…¶è¨­ç½®ç‚ºæ­£ç¢ºæ•¸å€¼ã€‚\n" +"[推薦:é¸ç”¨]" + +#: Config.cpp:523 +msgid "" +"Use frame buffer objects:\n" +"Changes the way FB effects are rendered - with or without usage of the OpenGL Frame Buffer Objects (FBO) extension.\n" +"The choice depends on game and your video card. FBO off is good for NVIDIA cards, while for ATI cards, it's usually best that FBOs are turned on.\n" +"Also, some FB effects works only with one of the methods, no matter, which card you have.\n" +"On the whole, with FBO off, compatibility/ accuracy is a bit better (which is the case for Resident Evil 2).\n" +"However, with FBO on with some systems, it can actually be a bit faster in cases.\n" +"[Recommended: video card and game dependant]" +msgstr "" +"使用幀緩è¡å°è±¡ï¼š\n" +"-----------------\n" +"當é¸æ“‡å¾Œï¼Œå³ä½¿æ²’有使用OpenGL幀緩è¡å°è±¡ (FBO)擴展,\n" +"它ä»ç„¶æœƒæ”¹è®Šå¹€ç·©è¡æ•ˆæžœçš„呈ç¾æ–¹å¼ã€‚\n" +"您的é¸æ“‡å–決於你的éŠæˆ²å’Œé¡¯ç¤ºå¡ã€‚å°æ–¼Nvidia顯示å¡ï¼Œ\n" +"ä¸è¦é¸æ“‡FBO而å°æ–¼ATI視頻å¡ï¼ŒFBO通常是一個很好的é¸æ“‡ã€‚\n" +"\n" +"å¦å¤–,一些幀緩è¡æ•ˆæžœåªé©ç”¨å…¶ä¸­ä¹‹ä¸€çš„方法,而ä¸ç®¡é¡¯ç¤ºå¡ã€‚\n" +"整體而言,ä¸é¸FBO將會增加éŠæˆ²ç›¸å®¹æ€§èˆ‡æº–確性,例如,\n" +"Resident Evil 2。\n" +"\n" +"然而,在æŸäº›ç³»çµ±ä¸Šï¼ŒFBOçš„é¸æ“‡æœƒåŠ é€Ÿä¸€äº›éŠæˆ²ã€‚\n" +"[推薦:å–決於顯示å¡å’ŒéŠæˆ²]" + +#: Config.cpp:578 +msgid "Emulation settings" +msgstr "模擬設置" + +#: Config.cpp:579 +msgid "" +"Filtering mode\n" +"There are three filtering modes possible:\n" +"* Automatic filtering - filter exactly how the N64 specifies.\n" +"* Point-sampled filtering - causes texels to appear square and sharp.\n" +"* Bilinear filtering - interpolates the texture to make it appear more smooth.\n" +"[Recommended: Automatic]" +msgstr "" +"éŽæ¿¾æ¨¡å¼\n" +"----------\n" +"éŽæ¿¾æ–¹å¼æœ‰ä¸‰ç¨®ï¼š\n" +"*自動éŽæ¿¾\t: 與N64çš„éŽæ¿¾æ˜¯ç›¸åŒçš„。\n" +"*點å–樣éŽæ¿¾\t: 使æ質元素出ç¾æ­£æ–¹å½¢å’Œå°–銳。\n" +"*雙線性éŽæ¿¾\t: æ’補æ質,使其看起來更光滑。\n" +"[推薦:自動]" + +#: Config.cpp:583 +msgid "" +"Buffer swapping method\n" +"There are 3 buffer swapping methods:\n" +"* old - swap buffers when vertical interrupt has occurred.\n" +"* new - swap buffers when set of conditions is satisfied. Prevents flicker on some games.\n" +"* hybrid - mix of first two methods.\n" +"Can prevent even more flickering then previous method, but also can cause artefacts.\n" +"If you have flickering problems in a game (or graphics that don't show),\n" +"try to change swapping method.\n" +"[Recommended: new (hybrid for Paper Mario)]" +msgstr "" +"ç·©è¡äº¤æ›æ–¹æ³•\n" +"---------------\n" +"ç·©è¡äº¤æ›æ–¹æ³•æœ‰3種:\n" +"*舊\t: 在垂直中斷發生時,交æ›ç·©è¡å€ã€‚\n" +"*æ–°\t: 當æ¢ä»¶ç¬¦åˆæ™‚,交æ›ç·©è¡å€ã€‚\n" +"\t 防止一些éŠæˆ²çš„é–ƒçˆã€‚\n" +"*æ··åˆ\t: æ··åˆå‰å…©ç¨®æ–¹æ³•ã€‚\n" +"\t å¯é˜²æ­¢æ›´å¤šé–ƒçˆï¼Œä½†ä¹Ÿå¯èƒ½æœƒæœ‰è¦–覺干擾。\n" +"\n" +"如果您在éŠæˆ²ä¸­æœ‰é–ƒçˆçš„å•é¡Œï¼ˆæˆ–圖形ä¸é¡¯ç¤ºï¼‰ï¼Œ\n" +"嘗試改變交æ›æ–¹æ³•ã€‚\n" +"[推薦:新(Paper Mario - é¸æ“‡æ··åˆï¼‰]" + +#: Config.cpp:587 +msgid "" +"Per-pixel level-of-detail calculation\n" +"N64 uses special mechanism for mip-mapping, which nearly impossible to reproduce\n" +"correctly on PC hardware. This option enables approximate emulation of this feature.\n" +"For example, it is required for the Peach/Bowser portrait's transition in Super Mario 64.\n" +"There are 3 modes:\n" +"* off - LOD is not calculated\n" +"* fast - fast imprecise LOD calculation.\n" +"* precise - most precise LOD calculation possible, but more slow.\n" +"[Recommended: your preference]" +msgstr "" +"æ¯å€‹åƒç´ è©³ç´°ç¨‹åº¦è¨ˆç®—\n" +"------------------------\n" +"N64使用特殊的æ質映射,幾乎是ä¸å¯èƒ½åœ¨é›»è…¦ç¡¬é«”\n" +"上很正確地複製。此é¸é …將啟用此功能近似模擬。\n" +"例如,應用在\"Super Mario 64\"éŠæˆ²å…§çš„\n" +"Peach與Bowserè‚–åƒçš„éŽæ¸¡ã€‚\n" +"\n" +"有3種模å¼ï¼š\n" +"*關閉\t: ä¸é€²è¡ŒLOD計算。\n" +"*快速\t: 快而ä¸æº–確的LOD計算。\n" +"*準確\t: 最精確的LOD計算,但更慢。\n" +"[推薦:您的å好]" + +#: Config.cpp:592 +msgid "" +"Aspect ratio of the output.\n" +"Most N64 games use 4:3 aspect ratio, but some support widescreen too.\n" +"You may select appropriate aspect here and set widescreen mode in game settings.\n" +"In \"Stretch\" mode the output will be stretched to the entire screen,\n" +"other modes may add black borders if necessary" +msgstr "" +"長寬比的輸出\n" +"---------------\n" +"大多數N64 çš„éŠæˆ²ä½¿ç”¨4:3的比例,但有些支æ´å¯¬èž¢å¹•äº†ã€‚\n" +"ä½ å¯ä»¥åœ¨é€™è£¡é¸æ“‡åˆé©çš„比例,並在éŠæˆ²ä¸Šè¨­ç½®å¯¬èž¢å¹•æ¨¡å¼ã€‚\n" +"在\"拉伸 \"模å¼ä¸‹ï¼Œè¼¸å‡ºå°‡è¢«æ‹‰ä¼¸åˆ°æ•´å€‹èž¢å¹•ï¼Œ\n" +"其它模å¼å¯èƒ½åœ¨å¿…è¦æ™‚加黑色邊框。" + +#: Config.cpp:595 +msgid "" +"Fog enabled\n" +"Sets fog emulation on//off.\n" +"[Recommended: on]" +msgstr "" +"啟用霧化\n" +"-------\n" +"設置霧化模擬的開與關\n" +"[推薦:é¸ç”¨]" + +#: Config.cpp:597 +msgid "" +"Buffer clear on every frame\n" +"Forces the frame buffer to be cleared every frame drawn.\n" +"Usually frame buffer clear is controlled by the game.\n" +"However, in some cases it is not well emulated,\n" +"and some garbage may be left on the screen.\n" +"In such cases, this option must be set on.\n" +"[Recommended: on]" +msgstr "" +"清除æ¯ä¸€å¹€ç·©è¡\n" +"-----------------\n" +"強制在æ¯ä¸€å¹€ä¸­çš„繪製,清除幀緩è¡ã€‚\n" +"通常幀緩è¡æ˜¯ç”±éŠæˆ²æŽ§åˆ¶çš„。\n" +"但是,在æŸäº›æƒ…æ³ä¸‹å¯èƒ½ä¸¦æ²’有很好地模擬,\n" +"有些圖形垃圾或許會殘留在螢幕上。\n" +"在這種情æ³ä¸‹ï¼Œæ­¤é¸é …必須設置。\n" +"[推薦:é¸ç”¨]" + +#: Config.cpp:599 +msgid "" +"Enable frame buffer emulation\n" +"If on, plugin will try to detect frame buffer usage and apply appropriate frame buffer emulation.\n" +"[Recommended: on for games which use frame buffer effects]" +msgstr "" +"啟用幀緩è¡æ¨¡æ“¬\n" +"-----------------\n" +"當é¸æ“‡æ™‚,æ’件將嘗試檢測幀緩è¡å€çš„\n" +"使用情æ³è€ŒæŽ¡ç”¨é©ç•¶çš„幀緩è¡æ¨¡æ“¬ã€‚\n" +"[推薦:éŠæˆ²ä½¿ç”¨å¹€ç·©è¡æ•ˆæžœ- é¸ç”¨]" + +#: Config.cpp:601 +msgid "" +"Enable hardware frame buffer emulation\n" +"If this option is on, plugin will create auxiliary frame buffers in video memory instead of copying\n" +"frame buffer content into main memory. This allows plugin to run frame buffer effects without slowdown\n" +"and without scaling image down to N64's native resolution. This feature is fully supported by\n" +"Voodoo 4/5 cards and partially by Voodoo3 and Banshee. Modern cards also fully support it.\n" +"[Recommended: on, if supported by your hardware]" +msgstr "" +"啟用硬體幀緩è¡æ¨¡æ“¬\n" +"----------------------\n" +"當é¸æ“‡å¾Œï¼Œæ’件將在顯å¡è¨˜æ†¶é«”中創建輔助的幀緩è¡å™¨ï¼Œ\n" +"而ä¸æ˜¯è¤‡è£½åˆ°ä¸»è¨˜æ†¶é«”。這å…許æ’件é‹è¡Œå¹€ç·©è¡æ•ˆæžœ\n" +"而ä¸ç·©è¡ï¼Œä¸¦ä¸ç¸®æ”¾åœ–åƒåˆ°N64的原始解æžçŽ‡ã€‚\n" +"\n" +"此功能會完全支æ´Voodoo 4與5å¡å’Œéƒ¨åˆ†Voodoo3\n" +"å’Œ Banshee。近期顯å¡ä¹Ÿå®Œå…¨æ”¯æ´ã€‚\n" +"[æŽ¨è–¦ï¼šç¡¬é«”æ”¯æ´ - é¸ç”¨]" + +#: Config.cpp:604 +msgid "" +"Get information about frame buffers\n" +"This is compatibility option. It must be set on for Mupen64 and off for 1964" +msgstr "" +"å–得幀緩è¡å™¨çš„有關訊æ¯\n" +"這是相容性é¸é …。在Mupen64上,必須設置為開\n" +"而在1964必須設置為關" + +#: Config.cpp:606 +msgid "" +"Read every frame\n" +"In some games plugin can't detect frame buffer usage.\n" +"In such cases you need to enable this option to see frame buffer effects.\n" +"Every drawn frame will be read from video card -> it works very slow.\n" +"[Recommended: mostly off (needed only for a few games)]" +msgstr "" +"讀å–æ¯ä¸€å¹€\n" +"------------\n" +"在一些éŠæˆ²ä¸Šï¼Œæ’件無法檢測到幀緩è¡å€çš„使用。\n" +"在這種情æ³ä¸‹ï¼Œæ‚¨éœ€è¦å•Ÿç”¨è©²é¸é …æ‰èƒ½çœ‹åˆ°å¹€ç·©è¡æ•ˆæžœã€‚\n" +"æ¯ä¸€å€‹å¹€çš„繪製將從顯示å¡è®€å–->這將是éžå¸¸çš„緩慢。\n" +"[推薦:大多ä¸é¸ï¼ˆé‹ç”¨åœ¨å°‘數éŠæˆ²ä¸Šï¼‰]" + +#: Config.cpp:608 +msgid "" +"Render N64 frame buffer as texture\n" +"When this option is enabled, content of each N64 frame buffer is rendered\n" +"as texture over the frame, rendered by the plugin. This prevents graphics lost,\n" +"but may cause slowdowns and various glitches in some games.\n" +"[Recommended: mostly off]" +msgstr "" +"呈ç¾N64的幀緩è¡åˆ°æ質\n" +"--------------------------\n" +"當é¸æ“‡å¾Œï¼Œæ¯å€‹ N64的幀緩è¡çš„內容將由æ’件\n" +"在幀上呈ç¾æ質。這å¯ä»¥é˜²æ­¢åœ–形的æµå¤±ï¼Œ\n" +"但å¯èƒ½æœƒå°Žè‡´é€Ÿåº¦ä¸‹é™ï¼Œå’Œä¸€äº›éŠæˆ²çš„å„種錯誤。\n" +"[推薦:大多ä¸é¸]" + +#: Config.cpp:610 +msgid "" +"Detect CPU write to the N64 frame buffer\n" +"This option works as the previous options, but the plugin is trying to detect,\n" +"when game uses CPU writes to N64 frame buffer. The N64 frame buffer is rendered\n" +"only when CPU writes is detected. Use this option for those games, in which you\n" +"see still image or no image at all for some time with no reason.\n" +"[Recommended: mostly off]" +msgstr "" +"檢測CPU寫入到N64幀緩è¡\n" +"----------------------------\n" +"æ­¤é¸é …與上一個é¸é …有一樣的功能,但æ’件會試圖\n" +"檢測éŠæˆ²åœ¨ä½•æ™‚使用CPU寫入到N64的幀緩è¡å€ã€‚\n" +"當檢測到 CPU寫入時,æ‰æœƒå‘ˆç¾N64的幀緩è¡ã€‚\n" +"\n" +"如果éŽäº†ä¸€æ®µæ™‚間後,你åªèƒ½çœ‹åˆ°éœæ…‹åœ–åƒæˆ–\n" +"無圖åƒæ™‚,請使用此é¸é …。\n" +"[推薦:大多ä¸é¸]" + +#: Config.cpp:612 +msgid "" +"Enable depth buffer rendering\n" +"This option is used to fully emulate N64 depth buffer.\n" +"It is required for correct emulation of depth buffer based effects.\n" +"However, it requires fast (>1GHz) CPU to work full speed.\n" +"[Recommended: on for fast PC]" +msgstr "" +"啟用深度緩è¡æ¸²æŸ“\n" +"-------------------\n" +"æ­¤é¸é …用於完全模擬N64的深度緩è¡å€ã€‚\n" +"這是需è¦æ­£ç¢ºçš„模擬深度緩è¡çš„效果。\n" +"但是,它需è¦å¿«é€Ÿï¼ˆ>1GHz)的CPUæ‰èƒ½é”到全速。\n" +"[推薦:快速電腦 - é¸ç”¨]" + +#: Config.cpp:620 +msgid "" +"Filters:\n" +"Apply a filter to either smooth or sharpen textures.\n" +"There are 4 different smoothing filters and 2 different sharpening filters.\n" +"The higher the number, the stronger the effect,\n" +"i.e. \"Smoothing filter 4\" will have a much more noticeable effect than \"Smoothing filter 1\".\n" +"Be aware that performance may have an impact depending on the game and/or the PC.\n" +"[Recommended: your preference]" +msgstr "" +"濾é¡ï¼š\n" +"--------\n" +"應用一個濾é¡ä¾†å¹³æ»‘或銳化æ質。\n" +"有4種ä¸åŒçš„平滑濾é¡å’Œ2個ä¸åŒçš„銳化濾é¡ã€‚\n" +"- 數字越高,效果越強。\n" +"- 例如,平滑濾é¡4將比1有更明顯的效果。\n" +"\n" +"注æ„:\téŠæˆ²æ€§èƒ½å¯èƒ½æœƒå—到影響,\n" +"\tå–決於éŠæˆ²èˆ‡æˆ–電腦。\n" +"[推薦:您的å好]" + +#: Config.cpp:624 +msgid "" +"Texture enhancement:\n" +"7 different filters are selectable here, each one with a distinctive look.\n" +"Be aware of possible performance impacts.\n" +"\n" +"IMPORTANT: 'Store' mode - saves textures in cache 'as is'. It can improve performance in games, which load many textures.\n" +"Disable 'Ignore backgrounds' option for better result.\n" +"\n" +"[Recommended: your preference]" +msgstr "" +"æ質增強:\n" +"----------\n" +"在這裡å¯é¸æ“‡ 7種ä¸åŒçš„濾é¡ï¼Œæ¯ä¸€å€‹å…·æœ‰ç¨ç‰¹çš„外觀。\n" +"注æ„:\tå¯èƒ½æœƒæœ‰æ€§èƒ½å½±éŸ¿ã€‚\n" +"\n" +"è¦é»ž:\t \"存儲\"模å¼- 儲存在快å–çš„æ質為\"原狀\"。\n" +"\t它å¯ä»¥æ高éŠæˆ²çš„性能,但載有很多æ質。\n" +"\tç¦ç”¨\"忽略背景\"é¸é …,讓效果更佳。\n" +"[推薦:您的å好]" + +#: Config.cpp:628 +msgid "" +"Texture cache size:\n" +"Enhanced and filtered textures can be cached to aid performance.\n" +"This setting will adjust how much PC memory will be dedicated for texture cache.\n" +"This helps boost performance if there are subsequent requests for the same texture (usually the case).\n" +"Normally, 128MB should be more than enough but there is a sweet spot for each game.\n" +"Super Mario may not need more than 32megs, but Conker streams a lot of textures,\n" +"so setting 256+ megs can boost performance. Adjust accordingly if you are encountering speed issues.\n" +"'0' disables cache.\n" +"[Recommended: PC and game dependant]" +msgstr "" +"æ質快å–大å°ï¼š\n" +"---------------\n" +"加強和éŽæ¿¾å¾Œçš„æ質å¯è¢«å¿«å–以輔助效能。\n" +"此設置將調整多少電腦主記憶體為æ質快å–專用。\n" +"如果是相åŒçš„æ質(通常如此)有後續請求,\n" +"這將有助於æ高效能。一般情æ³ä¸‹ï¼Œ\n" +"128MB應該是綽綽有餘,但æ¯å€‹éŠæˆ²æœ‰å…¶ä¸åŒç‰¹é»žã€‚\n" +"\n" +"\"Super Mario\"å¯èƒ½ä¸éœ€è¦æ¯”32 MB還多,\n" +"但\"Conker \"使用很多æ質,因而用256MB+\n" +"å¯æ高效能。如果你é‡åˆ°é€Ÿåº¦å•é¡Œï¼Œ\n" +"å¯ä¾æ“šå¯¦éš›æƒ…æ³èª¿æ•´ã€‚\n" +"\n" +"'0'ç¦ç”¨å¿«å–。\n" +"[推薦:å–決於電腦和éŠæˆ²]" + +#: Config.cpp:634 +msgid "" +"Ignore Backgrounds:\n" +"It is used to skip enhancement for long narrow textures, usually used for backgrounds.\n" +"This may save texture memory greatly and increase performance.\n" +"[Recommended: on (off for 'Store' mode)]" +msgstr "" +"忽略背景:\n" +"----------\n" +"它是用來跳éŽå¢žå¼·ç‹¹é•·æ質(通常為背景用)。\n" +"這å¯èƒ½æœƒå¤§å¤§ç¯€çœæ質儲存記憶體和æ高性能。\n" +"[推薦:é¸ï¼ˆ\" 存儲\"模å¼- ä¸é¸ï¼‰]" + +#: Config.cpp:636 +msgid "" +"Texture compression:\n" +"Textures will be compressed using selected texture compression method.\n" +"The overall compression ratio is about 1/6 for FXT1 and 1/4 for S3TC.\n" +"In addition to saving space on the texture cache,\n" +"the space occupied on the GFX hardware's texture RAM,\n" +"by the enhanced textures, will be greatly reduced.\n" +"This minimizes texture RAM usage,\n" +"decreasing the number of texture swaps to the GFX hardware leading to performance gains.\n" +"However, due to the nature of lossy compression of FXT1 and S3TC, using this option can sometimes lead to quality degradation of small size textures and color banding of gradient colored textures.\n" +"[Recommended: off]" +msgstr "" +"æ質壓縮:\n" +"----------\n" +"æ質的壓縮是ä¾ç…§æ‰€é¸çš„æ質壓縮方法。\n" +"整體壓縮比大約是 1/6æ–¼FXT1或1/4æ–¼S3TC.\n" +"除了節çœæ質快å–的空間,在顯å¡ç¡¬é«”çš„æ質記憶體\n" +"所佔領的增強æ質空間,將大大減少。\n" +"這將最大é™åº¦åœ°æ¸›å°‘æ質記憶體的使用,\n" +"é™ä½Žæ質在顯å¡ç¡¬é«”的交æ›æ•¸æ¬¡ï¼Œå°Žè‡´æ高效能。\n" +"\n" +"然而,由於 FXT1å’ŒS3TC有æ壓縮的性質,\n" +"使用此é¸é …有時會導致å°é«”ç©çš„æ質出ç¾è³ªé‡é€€åŒ–\n" +"和漸變色的æ質出ç¾è‰²å¸¶ã€‚\n" +"[推薦:ä¸é¸]" + +#: Config.cpp:640 +msgid "" +"Compress texture cache:\n" +"Memory will be compressed so that more textures can be held in the texture cache.\n" +"The compression ratio varies with each texture,\n" +"but 1/5 of the original size would be a modest approximation.\n" +"They will be decompressed on-the-fly, before being downloaded to the gfx hardware.\n" +"This option will still help save memory space even when using texture compression.\n" +"[Recommended: on]" +msgstr "" +"壓縮æ質快å–:\n" +"---------------\n" +"主記憶體將被壓縮,使更多的æ質å¯ä»¥å­˜å„²åœ¨æ質快å–。\n" +"壓縮比率會因æ質而å„有ä¸åŒï¼Œå¤§ç´„1/5的原始大å°\n" +"是個較普é的壓縮效率。\n" +"他們將立å³è¢«è§£å£“縮,然後被下載到顯å¡ç¡¬é«”。\n" +"å³ä½¿ä½¿ç”¨æ質壓縮,此é¸é …ä»æœƒç¯€çœä¸»è¨˜æ†¶é«”空間。\n" +"[推薦:é¸ç”¨]" + +#: Config.cpp:642 +msgid "" +"Hi-res pack format:\n" +"Choose which method is to be used for loading Hi-res texture packs.\n" +"Only Rice's format is available currently.\n" +"Leave on \"None\" if you will not be needing to load hi-res packs.\n" +"[Recommended: Rice's format. Default: \"None\"]" +msgstr "" +"高解æžæ質包格å¼ï¼š\n" +"------------------\n" +"é¸æ“‡å“ªç¨®æ–¹æ³•ä¾†åŠ è¼‰é«˜è§£æžæ質包。\n" +"ç›®å‰åªèƒ½ç”¨ Rice's æ ¼å¼ã€‚\n" +"如果你ä¸éœ€è¦åŠ è¼‰é«˜è§£æžæ質包,請é¸æ“‡\"ç„¡\"。\n" +"[推薦:Rice's æ ¼å¼ã€‚默èªï¼šç„¡]" + +#: Config.cpp:646 +msgid "" +"Tile textures:\n" +"When on, wide texture will be split on several tiles to fit in one 256-width texture.\n" +"This tiled texture takes much less video memory space and thus overall performance will increase.\n" +"However, corresponding polygons must be split too, and this is not polished yet\n" +"- various issues are possible, including black lines and polygons distortions.\n" +"[Recommended: off]" +msgstr "" +"圖磚æ質:\n" +"----------\n" +"當é¸æ“‡å¾Œï¼Œå¯¬æ質將被分割在幾個瓦片,以é©æ‡‰ä¸€å€‹256寬的æ質。\n" +"這平鋪æ質花費更少的顯å¡è¨˜æ†¶é«”空間,因此整體性能會有所增加。\n" +"但是,必須相應的多邊形也需è¦åˆ†å‰²ï¼Œå»å°šæœªå®Œå…¨é–‹ç™¼å‡ºä¾†ã€‚\n" +"- å„種å•é¡Œéƒ½æœ‰å¯èƒ½çš„,包括黑線和多邊形的扭曲。\n" +"[推薦:ä¸é¸]" + +#: Config.cpp:648 +msgid "" +"Force 16bpp textures:\n" +"The color of the textures will be reduced to 16bpp.\n" +"This is another space saver and performance enhancer.\n" +"This halves the space used on the texture cache and the GFX hardware's texture RAM.\n" +"Color reduction is done so that the original quality is preserved as much as possible.\n" +"Depending on the texture, this usually is hardly noticeable.\n" +"Sometimes though, it can be: skies are a good example.\n" +"[Recommended: off]" +msgstr "" +"強制啟用16ä½å…ƒæ質:\n" +"--------------------\n" +"該æ質色彩將減少為16ä½å…ƒã€‚\n" +"這是å¦ä¸€ç¨®ç¯€çœç©ºé–“和性能增強的方å¼ã€‚\n" +"將節çœä¸€åŠçš„æ質快å–å’Œ\n" +"顯å¡ç¡¬é«”存放æ質的記憶體使用空間。\n" +"\n" +"色彩還原將盡å¯èƒ½çš„ä¿ç•™å…¶åŽŸä¾†é¡è‰²ã€‚\n" +"根據ä¸åŒçš„æ質,這通常是難以察覺的。\n" +"但,並éžä¸å¯èƒ½ï¼šå¤©ç©ºæ˜¯ä¸€å€‹å¾ˆå¥½çš„例å­ã€‚\n" +"[推薦:ä¸é¸]" + +#: Config.cpp:650 +msgid "" +"Texture dumping mode:\n" +"In this mode, you have that ability to dump textures on screen to the appropriate folder.\n" +"You can also reload textures while the game is running to see how they look instantly - big time saver!\n" +"\n" +"Hotkeys: \"R\" reloads hires textures from the texture pack - \"D\" toggles texture dumps on/off." +msgstr "" +"æ質轉儲方å¼ï¼š\n" +"---------------\n" +"在這模å¼ä¸‹ï¼Œä½ å¯å°‡èž¢å¹•ä¸Šçš„æ質轉儲到é©ç•¶çš„資料夾。\n" +"您也å¯ä»¥åœ¨éŠæˆ²é‹è¡Œæ™‚é‡æ–°è¼‰å…¥æ質,而馬上看到çµæžœ\n" +"- 大大節çœæ™‚é–“ï¼\n" +"熱éµï¼š\tR - é‡æ–°è¼‰å…¥é«˜è§£æžæ質包\n" +"\tD - 將切æ›æ質轉儲開與關" + +#: Config.cpp:652 +msgid "" +"Alternative CRC calculation:\n" +"This option enables emulation of a palette CRC calculation bug in RiceVideo.\n" +"If some textures are not loaded, try to set this option on/off.\n" +"[Recommended: texture pack dependant, mostly on]" +msgstr "" +"å¦ä¸€ç¨®CRC 計算:\n" +"-----------------\n" +"æ­¤é¸é …å¯ä»¥æ¨¡æ“¬RiceVideo在調色æ¿ä¸Šçš„CRC計算錯誤。\n" +"如果æŸäº›æ質ä¸èƒ½åŠ è¼‰ï¼Œè«‹å˜—試設置此é¸é …開與關。\n" +"[推薦:å–決於æ質包,大多é¸ç”¨]" + +#: Config.cpp:657 +msgid "" +"Compress texture cache:\n" +"When game started, plugin loads all its hi-resolution textures into PC memory.\n" +"Since hi-resolution textures are usually large, the whole pack can take hundreds megabytes of memory.\n" +"Cache compression allows save memory space greatly.\n" +"Textures will be decompressed on-the-fly, before being downloaded to the gfx hardware.\n" +"This option will still help save memory space even when using texture compression.\n" +"[Recommended: on]" +msgstr "" +"壓縮æ質快å–:\n" +"---------------\n" +"當éŠæˆ²é–‹å§‹å¾Œï¼Œæ’件將加載所有\n" +"的高解æžæ質在電腦主記憶體。\n" +"由於高解æžæ質通常很大,\n" +"整個æ質包å¯ä»¥åˆ©ç”¨å¹¾ç™¾MB的主記憶體。\n" +"å¿«å–壓縮å¯ä»¥å¤§å¤§ç¯€çœå­˜å„²ç©ºé–“。\n" +"æ質將立å³è¢«è§£å£“縮,然後下載到顯å¡ç¡¬é«”。\n" +"å³ä½¿ä½¿ç”¨æ質壓縮,此é¸é …ä»æœƒç¯€çœä¸»è¨˜æ†¶é«”空間。\n" +"[推薦:é¸ç”¨]" + +#: Config.cpp:659 +msgid "" +"Use Alpha channel fully:\n" +"When this option is off, 16bit rgba textures will be loaded using RiceVideo style\n" +"- with 1bit for alpha channel.\n" +"When it is on, GlideHQ will check, how alpha channel is used by the hires texture,\n" +"and select most appropriate format for it.\n" +"This gives texture designers freedom to play with alpha, as they need,\n" +"regardless of format of original N64 texture.\n" +"For older and badly designed texture packs it can cause unwanted black borders.\n" +"[Recommended: texture pack dependant]" +msgstr "" +"充分利用é€æ˜Žé€šé“:\n" +"--------------------\n" +"如ä¸é¸æ­¤é¸é …,使用RiceVideo風格會加載\n" +"16ä½å…ƒRGBAæ質與1ä½å…ƒé€æ˜Žé€šé“。\n" +"當é¸æ“‡å¾Œï¼ŒGlideHQ將檢查高解æžæ質如何\n" +"使用é€æ˜Žé€šé“,並é¸æ“‡æœ€é©ç•¶çš„æ ¼å¼ã€‚\n" +"它讓設計者自由發æ®æ質é€æ˜Žçš„使用,\n" +"ä¸è«–其原來的 N64çš„æ質格å¼ã€‚\n" +"å°æ–¼è€èˆŠæˆ–設計ä¸è‰¯çš„æ質包,å¯èƒ½æœƒå‡ºç¾ä¸å¿…è¦çš„黑邊。\n" +"[推薦:å–決於æ質包]" + +#: Config.cpp:662 +msgid "" +"Save texture cache to HD:\n" +"\n" +"For enhanced textures cache:\n" +"This will save all previously loaded and enhanced textures to HD.\n" +"So upon next game launch, all the textures will be instantly loaded, resulting in smoother performance.\n" +"\n" +"For high-resolution textures cache:\n" +"After creation, loading hi-res texture will take only a few seconds upon game launch,\n" +"as opposed to the 5 -60 seconds a pack can take to load without this cache file.\n" +"The only downside here is upon any changes to the pack, the cache file will need to be manually deleted.\n" +"\n" +"Saved cache files go into a folder called \"Cache\" within the Plugins folder.\n" +"\n" +"[Highly Recommended: on]" +msgstr "" +"ä¿å­˜æ質快å–到硬碟:\n" +"--------------------\n" +"增強æ質快å–:\n" +"---------------\n" +"這將ä¿å­˜æ‰€æœ‰ä¹‹å‰åŠ è¼‰å’Œå¢žå¼·æ質到硬碟。\n" +"下一次éŠæˆ²é–‹å§‹å¾Œï¼Œæ‰€æœ‰çš„æ質將å³åˆ»åŠ è¼‰ï¼Œ\n" +"導致更順暢的性能。\n" +"\n" +"高解æžæ質快å–:\n" +"----------------------\n" +"在創建後,當éŠæˆ²å•Ÿå‹•æ™‚,加載高解æžæ質åªéœ€å¹¾ç§’é˜ã€‚\n" +"如果沒有這個快å–檔案,載入æ質包å¯èƒ½éœ€è¦5-60秒。\n" +"唯一的缺點是在更改æ質包時,快å–檔案將需è¦æ‰‹å‹•åˆªé™¤ã€‚\n" +"\n" +"儲存的快å–檔案將被儲存到Plugins資料夾內的Cache資料夾。\n" +"[強烈推薦:é¸ç”¨]" + +#: Config.cpp:685 +msgid "Debug" +msgstr "åµéŒ¯" + +#: Config.cpp:686 +msgid "" +"Autodetect Microcode\n" +"If this option is checked, the microcode of the game\n" +"will be detected automatically from the INI, and\n" +"therefore it will not need to be set in this\n" +"configuration dialog.\n" +"[Recommended: on]" +msgstr "" +"自動檢測微碼\n" +"當é¸æ“‡å¾Œï¼ŒéŠæˆ²çš„微碼會自動從INI檢測到。\n" +"因此它ä¸éœ€è¦åœ¨æ­¤è¨­ç½®è¦–窗中設置。\n" +"[推薦:é¸ç”¨]" + +#: Config.cpp:688 +msgid "" +"Force Microcode\n" +"This option ONLY has an effect if Autodetect Microcode\n" +"is unchecked, the crc from the game could not be\n" +"found in the INI, OR after the game has already started\n" +"running. In any of those three cases, this will\n" +"select the microcode to use\n" +"[Recommended: any, turn on Autodetect Microcode]" +msgstr "" +"強制啟用微碼\n" +"æ­¤é¸é …是在以下情æ³æ‰æœ‰æ•ˆ:\n" +"1. 如果沒é¸å®šè‡ªå‹•æª¢æ¸¬å¾®ç¢¼ï¼Œ\n" +"2. éŠæˆ²çš„CRC在INI找ä¸åˆ°ï¼Œæˆ–\n" +"3. éŠæˆ²å·²ç¶“開始é‹è¡Œã€‚\n" +"在這三種情形之下,它將使用微碼。\n" +"[推薦:任何,é¸è‡ª\"動檢測微碼\"]" + +#: Config.cpp:692 +msgid "" +"Wireframe\n" +"This option, when checked, makes it so that the plugin will draw only the\n" +"outlines of objects. The colors specified in the combo box to the right\n" +"determines the color that the wireframes show up as.\n" +"[Recommended: off]" +msgstr "" +"線框\n" +"當é¸æ“‡å¾Œï¼Œæ’件會畫出å°è±¡çš„輪廓。\n" +"在組åˆæ¡†ä¸­æŒ‡å®šçš„é¡è‰²ï¼Œå°‡æ±ºå®šç·šæ¡†é¡è‰²çš„顯示。\n" +"[推薦:ä¸é¸]" + +#: Config.cpp:694 +msgid "" +"Wireframe Colors\n" +"This selects the colors to use for the wireframes (if wireframe mode is enabled).\n" +"There are 3 modes:\n" +"* Original colors - draw exactly as it would normally, textures and all, only in wireframes.\n" +"* Vertex colors - use the colors specified in the vertices to draw the wireframes with.\n" +"* Red only - use a constant red color to draw the wireframes.\n" +"[Recommended: Vertex colors]" +msgstr "" +"線框é¡è‰²\n" +"這將é¸æ“‡ç”¨æ–¼ç·šæ¡†çš„é¡è‰²ï¼ˆå¦‚線框模å¼å·²å•Ÿç”¨ï¼‰ã€‚\n" +"有3種模å¼ï¼š\n" +"*原始é¡è‰²\t: æ質和所有,是與原來相åŒçš„é¡è‰²ä¾†ç¹ªè£½ç·šæ¡†ã€‚\n" +"*頂點é¡è‰²\t: 使用指定的頂點來繪製線框的é¡è‰²ã€‚\n" +"*僅紅色\t: 利用固定的紅色來繪製線框。\n" +"[推薦:頂點é¡è‰²]" + +#: Config.cpp:696 +msgid "" +"Log to RDP.txt\n" +"RECOMMENDED FOR DEBUGGING ONLY - this option, when checked, will log EVERY SINGLE\n" +"COMMAND the plugin processes to a file called RDP.txt in the current directory.\n" +"This is incredibly slow, so I recommend keeping it disabled.\n" +"[Recommended: off]" +msgstr "" +"登錄到RDP.txt\n" +"推薦僅用於åµéŒ¯- 當é¸æ“‡å¾Œï¼Œå°‡è¨˜éŒ„該æ’件程åºçš„\n" +"æ¯ä¸€å€‹å‘½ä»¤åˆ°ç›®å‰ç›®éŒ„çš„RDP.txt。\n" +"這是令人難以置信的慢,所以我建議ä¿æŒç¦ç”¨ã€‚\n" +"[推薦:ä¸é¸]" + +#: Config.cpp:698 +msgid "" +"Unknown combiners as red\n" +"Objects that use an unimplemented combine mode will show up as red instead of\n" +"assuming texture with full alpha. Disable this option to remove the red stuff\n" +"and at least have a guess at the correct combine mode.\n" +"[Recommended: off]" +msgstr "" +"未知的åˆæˆå™¨ç‚ºç´…色\n" +"如果å°è±¡ä½¿ç”¨ä¸€å€‹æœªçŸ¥çš„åˆæˆæ¨¡å¼ï¼Œå®ƒæœƒé¡¯ç¤ºç‚ºç´…色而ä¸æ˜¯\n" +"å‡è¨­æ質具有完全é€æ˜Žçš„功能。ç¦ç”¨æ­¤é¸é …,刪除紅色的æ±è¥¿ï¼Œ\n" +"並至少能å°æ­£ç¢ºçš„åˆæˆæ¨¡å¼ä½œå‡ºçŒœæ¸¬ã€‚\n" +"[推薦:ä¸é¸]" + +#: Config.cpp:700 +msgid "" +"Log clear every frame\n" +"RECOMMENDED FOR DEBUGGING ONLY - this option has no effect unless 'Log to RDP.txt'\n" +"is checked. This will make it so that the log, RDP.txt, will be cleared at the\n" +"beginning of every frame.\n" +"[Recommended: off]" +msgstr "" +"在æ¯ä¸€å¹€æ¸…除記錄\n" +"推薦僅用於åµéŒ¯- 這個é¸é …沒有任何作用,除éžé¸æ“‡\"記錄到RDP.txt\"。\n" +"這將讓這個記錄RDP.txt,在æ¯ä¸€å¹€çš„開始清除。\n" +"[推薦:ä¸é¸]" + +#: Config.cpp:702 +msgid "" +"Log unknown combiners\n" +"RECOMMENDED FOR DEBUGGING ONLY - when checked, this option will cause every\n" +"unimplemented combiner drawn to be logged to a file called Unimp.txt in the\n" +"current directory. This becomes slow when there are unimplemented combiners\n" +"on the screen, so I recommend keeping it disabled.\n" +"[Recommended: off]" +msgstr "" +"登錄ä¸æ˜Žåˆæˆå™¨\n" +"推薦僅用於åµéŒ¯- 當é¸æ“‡å¾Œï¼Œé€™å€‹é¸é …將導致所有未執行\n" +"的繪製åˆæˆå™¨è¢«è¨˜éŒ„到Unimp.txt的文件。\n" +"如果有未執行的åˆæˆå™¨åœ¨èž¢å¹•ä¸Šï¼Œå®ƒæœƒè®Šå¾—緩慢,\n" +"所以我建議ä¿æŒç¦ç”¨ã€‚\n" +"[推薦:ä¸é¸]" + +#: Config.cpp:704 +msgid "" +"Run and log in window\n" +"RECOMMENDED FOR DEBUGGING ONLY - this option will make it so that the plugin will\n" +"still process dlists in windowed mode. This allows for logging to occur while not\n" +"in fullscreen, possibly allowing you to debug a crash.\n" +"[Recommended: off]" +msgstr "" +"é‹è¡Œä¸¦ç´€éŒ„於視窗\n" +"推薦僅用於åµéŒ¯- 這個é¸é …將讓æ’件ä»ç„¶æœƒåœ¨è¦–窗模å¼è™•ç†dlists。\n" +"雖然ä¸æ˜¯åœ¨å…¨èž¢å¹•ï¼Œä½†ä»å…許記錄,å¯ä»¥è®“你測試崩潰的原因。\n" +"[推薦:ä¸é¸]" + +#: Config.cpp:706 +msgid "" +"Clear unknown combiner log every frame\n" +"RECOMMENDED FOR DEBUGGING ONLY - this option works much like 'Log clear every frame'\n" +"except it clears the combiner log (Unimp.txt) instead of RDP.txt at the\n" +"beginning of each frame. Again, this option has no effect if 'combiner logging' is disabled.\n" +"[Recommended: off]" +msgstr "" +"在æ¯ä¸€å¹€æ¸…除未知åˆæˆå™¨è¨˜éŒ„\n" +"推薦僅用於åµéŒ¯- 這個é¸é …很åƒ\"在æ¯ä¸€å¹€æ¸…除記錄\",\n" +"除了它在æ¯ä¸€å¹€çš„開始清除åˆæˆå™¨è¨˜éŒ„(Unimp.txt),\n" +"而ä¸æ˜¯RDP.txt。\n" +"如果\"åˆæˆå™¨è¨˜éŒ„\"被ç¦ç”¨ï¼Œé€™å€‹é¸é …ä¸æœƒèµ·ä½œç”¨ã€‚\n" +"[推薦:ä¸é¸]" + +#: Config.cpp:709 +msgid "" +"Bilinear filter texture cache\n" +"RECOMMENDED FOR DEBUGGING ONLY - when checked, this option will make the graphical\n" +"debugger texture cache use bilinear filtering as opposed to point-sampled filtering,\n" +"which it will use otherwise. See 'Filtering mode' for descriptions of bilinear and\n" +"point-sampled filtering.\n" +"[Recommended: off]" +msgstr "" +"雙線性éŽæ¿¾æ質快å–\n" +"---------------------\n" +"推薦僅用於åµéŒ¯- 當é¸æ“‡å¾Œï¼Œæ­¤é¸é …將使圖形åµéŒ¯å™¨çš„æ質快å–\n" +"使用雙線性éŽæ¿¾æ質快å–,而ä¸æ˜¯é»žå–樣éŽæ¿¾ã€‚\n" +"閱讀\"éŽæ¿¾æ¨¡å¼\"å°é›™ç·šæ€§å’Œé»žå–樣樣éŽæ¿¾çš„æ述。\n" +"[推薦:ä¸é¸]" + +#: Config.cpp:1104 +msgid "Glide64 settings" +msgstr "Glide64 設置" + +#: Config.cpp:1293 +msgid "About Glide64" +msgstr "關於 Glide64" + +#: Config.cpp:1326 +msgid "authors:" +msgstr "作者:" + +#: Config.cpp:1330 +msgid "" +"Dave2001. Original author and former main developer.\n" +"He founded Glide64 project on Dec. 29th, 2001.\n" +"Left the project at fall of 2002.\n" +msgstr "" +"Dave2001。 原作者和原主è¦é–‹ç™¼è€…。\n" +"他在2001å¹´ 12月29日創立Glide64項目。\n" +"在2002年的秋天離開Glide64項目。\n" + +#: Config.cpp:1336 +msgid "" +"Gugaman. Developer. Joined the project at winter 2002\n" +" and left it at fall 2002." +msgstr "" +"開發人員Gugaman。在2002年冬季加入了這個項目,\n" +"在2002年秋天離開Glide64項目。" + +#: Config.cpp:1342 +msgid "" +"Sergey 'Gonetz' Lipski. Joined the project at winter 2002.\n" +"Main developer since fall of 2002." +msgstr "" +"Sergey 'Gonetz' Lipski。在2002年冬季加入了這個項目。\n" +"主è¦é–‹ç™¼è‡ª2002年秋季。" + +#: Config.cpp:1347 +msgid "Hiroshi 'KoolSmoky' Morii, Joined the project in 2007. " +msgstr "Hiroshi 'KoolSmoky' Morii,加入該項目於 2007年。" + +#: Config.cpp:1350 +msgid "Glitch64 (the wrapper) authors:" +msgstr "Glitch64(包è£ï¼‰ä½œè€…:" + +#: Config.cpp:1374 +msgid "GlideHQ author:" +msgstr "GlideHQ 作者:" + +#: Config.cpp:1381 +msgid "beta tester:" +msgstr "測試版測試者: " + +#: Config.cpp:1388 +msgid "" +"special thanks to:\n" +" Orkin, Rice, Daniel Borca, Legend.\n" +"Thanks to EmuXHaven for hosting my site:\n" +"http://glide64.emuxhaven.net\n" +msgstr "" +"特別感è¬ï¼š\n" +"-------------\n" +"Orkin, Rice, Daniel Borca, Legend.\n" +"æ„Ÿè¬ EmuXHaven æ供網站:\n" +"http://glide64.emuxhaven.net\n" + diff --git a/Source/Glide64/Keys.cpp b/Source/Glide64/Keys.cpp new file mode 100644 index 000000000..83ee5cb05 --- /dev/null +++ b/Source/Glide64/Keys.cpp @@ -0,0 +1,113 @@ +/* +* Glide64 - Glide video plugin for Nintendo 64 emulators. +* Copyright (c) 2002 Dave2001 +* Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski +* +* 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 +* 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 +*/ + +//**************************************************************** +// +// Glide64 - Glide Plugin for Nintendo 64 emulators +// Project started on December 29th, 2001 +// +// Authors: +// Dave2001, original author, founded the project in 2001, left it in 2002 +// Gugaman, joined the project in 2002, left it in 2002 +// Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002 +// Hiroshi 'KoolSmoky' Morii, joined the project in 2007 +// +//**************************************************************** +// +// To modify Glide64: +// * Write your name and (optional)email, commented by your work, so I know who did it, and so that you can find which parts you modified when it comes time to send it to me. +// * Do NOT send me the whole project or file that you modified. Take out your modified code sections, and tell me where to put them. If people sent the whole thing, I would have many different versions, but no idea how to combine them all. +// +//**************************************************************** +// +// Keys, used by Glide64. +// Since key codes are different for WinAPI and SDL, this difference is managed here +// Created by Sergey 'Gonetz' Lipski, July 2009 +// +//**************************************************************** + +#include "Gfx #1.3.h" + +Glide64Keys::Glide64Keys() +{ +#ifdef __WINDOWS__ +_keys[G64_VK_CONTROL] = 0x11; +_keys[G64_VK_ALT] = 0x12; +_keys[G64_VK_INSERT] = 0x2D; +_keys[G64_VK_LBUTTON] = 0x01; +_keys[G64_VK_UP] = 0x26; +_keys[G64_VK_DOWN] = 0x28; +_keys[G64_VK_LEFT] = 0x25; +_keys[G64_VK_RIGHT] = 0x27; +_keys[G64_VK_SPACE] = 0x20; +_keys[G64_VK_BACK] = 0x08; +_keys[G64_VK_SCROLL] = 0x91; +_keys[G64_VK_1] = 0x31; +_keys[G64_VK_2] = 0x32; +_keys[G64_VK_3] = 0x33; +_keys[G64_VK_4] = 0x34; +_keys[G64_VK_5] = 0x35; +_keys[G64_VK_6] = 0x36; +_keys[G64_VK_7] = 0x37; +_keys[G64_VK_8] = 0x38; +_keys[G64_VK_9] = 0x39; +_keys[G64_VK_0] = 0x30; +_keys[G64_VK_A] = 0x41; +_keys[G64_VK_B] = 0x42; +_keys[G64_VK_D] = 0x44; +_keys[G64_VK_G] = 0x47; +_keys[G64_VK_Q] = 0x51; +_keys[G64_VK_R] = 0x52; +_keys[G64_VK_S] = 0x53; +_keys[G64_VK_V] = 0x56; +_keys[G64_VK_W] = 0x57; +#else +_keys[G64_VK_CONTROL] = 306; +_keys[G64_VK_ALT] = 308; +_keys[G64_VK_INSERT] = 277; +_keys[G64_VK_LBUTTON] = 1; +_keys[G64_VK_UP] = 273; +_keys[G64_VK_DOWN] = 274; +_keys[G64_VK_LEFT] = 276; +_keys[G64_VK_RIGHT] = 275; +_keys[G64_VK_SPACE] = 32; +_keys[G64_VK_BACK] = 8; +_keys[G64_VK_SCROLL] = 302; +_keys[G64_VK_1] = 49; +_keys[G64_VK_2] = 50; +_keys[G64_VK_3] = 51; +_keys[G64_VK_4] = 52; +_keys[G64_VK_5] = 53; +_keys[G64_VK_6] = 54; +_keys[G64_VK_7] = 55; +_keys[G64_VK_8] = 56; +_keys[G64_VK_9] = 57; +_keys[G64_VK_0] = 48; +_keys[G64_VK_A] = 97; +_keys[G64_VK_B] = 98; +_keys[G64_VK_D] = 100; +_keys[G64_VK_G] = 103; +_keys[G64_VK_Q] = 113; +_keys[G64_VK_R] = 114; +_keys[G64_VK_S] = 115; +_keys[G64_VK_V] = 118; +_keys[G64_VK_W] = 119; +#endif +} diff --git a/Source/Glide64/Keys.h b/Source/Glide64/Keys.h new file mode 100644 index 000000000..fe5da6e96 --- /dev/null +++ b/Source/Glide64/Keys.h @@ -0,0 +1,93 @@ +/* +* Glide64 - Glide video plugin for Nintendo 64 emulators. +* Copyright (c) 2002 Dave2001 +* Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski +* +* 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 +* 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 +*/ + +//**************************************************************** +// +// Glide64 - Glide Plugin for Nintendo 64 emulators +// Project started on December 29th, 2001 +// +// Authors: +// Dave2001, original author, founded the project in 2001, left it in 2002 +// Gugaman, joined the project in 2002, left it in 2002 +// Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002 +// Hiroshi 'KoolSmoky' Morii, joined the project in 2007 +// +//**************************************************************** +// +// To modify Glide64: +// * Write your name and (optional)email, commented by your work, so I know who did it, and so that you can find which parts you modified when it comes time to send it to me. +// * Do NOT send me the whole project or file that you modified. Take out your modified code sections, and tell me where to put them. If people sent the whole thing, I would have many different versions, but no idea how to combine them all. +// +//**************************************************************** +// +// Keys, used by Glide64. +// Since key codes are different for WinAPI and SDL, this difference is managed here +// Created by Sergey 'Gonetz' Lipski, July 2009 +// +//**************************************************************** + +#ifndef Keys_H +#define Keys_H + +#define G64_VK_CONTROL 0 +#define G64_VK_ALT 1 +#define G64_VK_INSERT 2 +#define G64_VK_LBUTTON 3 +#define G64_VK_UP 4 +#define G64_VK_DOWN 5 +#define G64_VK_LEFT 6 +#define G64_VK_RIGHT 7 +#define G64_VK_SPACE 8 +#define G64_VK_BACK 9 +#define G64_VK_SCROLL 10 +#define G64_VK_1 11 +#define G64_VK_2 12 +#define G64_VK_3 13 +#define G64_VK_4 14 +#define G64_VK_5 15 +#define G64_VK_6 16 +#define G64_VK_7 17 +#define G64_VK_8 18 +#define G64_VK_9 19 +#define G64_VK_0 20 +#define G64_VK_A 21 +#define G64_VK_B 22 +#define G64_VK_D 23 +#define G64_VK_G 24 +#define G64_VK_Q 25 +#define G64_VK_R 26 +#define G64_VK_S 27 +#define G64_VK_V 28 +#define G64_VK_W 29 + +#define G64_NUM_KEYS 30 + +class Glide64Keys +{ + public: + Glide64Keys(); + ~Glide64Keys(){} + int operator[](unsigned int index){return _keys[index];} + + private: + int _keys[G64_NUM_KEYS]; +}; + +#endif //Keys_H diff --git a/Source/Glide64/MSVS/Debug/BuildLog.htm b/Source/Glide64/MSVS/Debug/BuildLog.htm new file mode 100644 index 0000000000000000000000000000000000000000..5ec1d707846fe6b6f3b2ef7b617c31f542518aec GIT binary patch literal 12958 zcmeI3Yfl?T6o%(>r2K~!X`7HXm_QTJl0;37Nz(>GxrC~9W#J2k%79~=V5)ka5yxR{=q|u6HcXrO1Gw++&{-Oe6D6xs`9oy)-U))$$!t zYR~ogIza0=_d`m0?4BYM+a{T;b#?SNDKE~^MMrD=Hb7^cy0s|b!X1-yfQIL2UF7`AET>2Or5h^GVOTS&_KW9}Vt^m+QzQonS| zBWu2=PRD$0^8F3+?GfIku{M=fqP*B(0o2*GABiXB%RNNYEz6LVFRuCLu!q<9}bB(+UD^+0XFv;125*T`8Xz3u*T z`-bJRTe7!tB_wB4Vrae&THW+6-vJvQ>x(~d`3s1q`kCPE;@tEPqs6L)1*-QSPl6S!W zI=THQ+B4sh2QOG#g%Sg*@!SwRC-jam=7e!I%pGBV46BZ?vI?t5MKfWA99GDm$_lw` z(Vb@<#NtH6c`c&BE^(mPh@M4-;wLh zjaiQ)_a4n1a`Z>31B+P2hEylm5tXq6)3?Kyga@g*ZBn+3M-!K}2oLiZ>2J7}xRyzI z>Q;zV#p!j83lz^J{%w*K^xVU57S)#ATjM24u!|8)(|c@GB)m%LvcAs$57=58zp1_# znVb>4#Z_s|iw&!@c%QW9Y55nhyh?eJnasO3VOb6KXdBkE1|k)n_js%Dwn<%T@I^0q z-^8L#klmRB8+E&t@33u!cBx_E7Pf3-nRq=hhC^#Fwd3u2e3@&o zm~Upty}>wKo>FgdTSC49uY6!n!mx}NDRqOd;-^aRU)@Y8YL~Px_lLx0x&dK0YtGhTVTP4=fp9p7mqzS$ozmJ9t?Gd$TpXYds-tkC)lS zZ-+Lk9m4&!=vjHBd*Ip4C9y%fs0ZXJNqZRDX%H6j**QZ?Z2iZ-|L~Uie1M(0N29%zCN;Sj*CFgb z%(l0d-GA_-M%P9^^@%opL6_p7$+<>pzHgk^>e2gBdiAK4XVKMTvdZ+U$u@JfkmiZVMu22p zCvAR>ESdZG)sTLnyUM+9nl_Qv9__h}TZx3U_V}XRQq4o+l9Y03C|*DN20V-4nO%f2_<;aBLD~ov*Bd2$Y%l740n2m-m{)MjeY>G;%5%< zH=W^*%-hBBCfrU5R_FibcN6RVd44fW`Yna$W0M^z@n8|ZWr*l$OWYHV>jAZ#xAW&Z zcc1N{{+s&B?96UtTBiNZLHxYVw#&ljSTX&a|McHJ{I?V5vi>Gcx5S=q{2LDCO@5E^ EF9CX^qyPW_ literal 0 HcmV?d00001 diff --git a/Source/Glide64/MSVS/Debug/CRC.obj b/Source/Glide64/MSVS/Debug/CRC.obj new file mode 100644 index 0000000000000000000000000000000000000000..7d18562ff6df3b101d9470ab763701f5138f71ab GIT binary patch literal 5208 zcmc&&eQaA-6~DIA)^*a==~}JRN_owKXld=4IAm?Qw07*5)T^C%{zyu3>)FpQ$;jn}3l;64U z`Sr!DLkbf+(tYRLbI(2Z+v&^&TtjIGJLsJ#< zhRp^AM8O_@xOvV?wx87%!!A<%F24W>XcVkWY+f zm5e;`XfazYL##*>J>7{x(t%^-Xu?k@O86o^XCXbwdf5Z*rag>pVifu28I#UKic~6; z3u6^wZ)Be^T&yTL<&2Ua7kq_WQOU|BcG1$;Zjz=m>ko!WS?23aXwwh|;I=I6ojKUE zFL7)55v5#BWrb*^no$bEA*U-b;!C8Jd_u}PbELWaZ zbxK~!Rx>gx9qU>)^zRTH{v>uS85Mo;h?pE2PL6sbLxG{eD77R*QC~6%X*4k8?jp^I z@1QFg4-ZDXezDIrAQ_>-qlN|A!au-hh4z{KJt!#g#sdN^vqxVtUi9(6nZo2T! z@2$VPc;~z9xyN&NMkbFlb_4o*=&gfOm3vIUrm4wD{>Ws+6BLq>RFa%Dr_Pv5=#pAgSi|K3PwXGMagxcnpOox}w?yHH``DIh(E>cm` z{$IU9ApO%Dt?|``_$r!TySgA+R~BpHYV!1#YHywT1-(Q+K=GqAh;BR-hjxKtM98H<)XAcVB26$ms;gKoYMx4Et1^zRMISu??PpLxZ7{qB zL+Yo%@kUKL~ypJO%y$xB}h>PV0oV zo25A)1*ec{>YLb%CbhE1HOa=_)^+dbx;AVd^=L(+Q6=qi2_2;mLgqjYaI$5u5u8H;eMbm;3C*-TX@xF)m73=-S(lb~E{LnIipx|d^JQ+n zJb!lCTK+V^^V)JPv^sYMt+W69%RRrIyYkadEw#9p&}rq5lL8EMSG7=mq2)aHvjE7= zU83j?*ZD|GNnXw%?02 zG~)CXw0Ae*lzh@YKa27lzD86sA^Ru$t4cPbz5@uZx<6==jh}i|M|-5&?ZRrSIzf}P6!$ln zaC~+WKJQ0O!zc0+5L6S}fXtd`U-$|c)I#?8znd2Dyg*e}IRLYztJYe`I(LP@TZ`AX z{$!i`H*OVX$ZtBlS6+s#ThDb#SgW{dfz*tqC!nLy8hd#JvN7vbn%ck9gr@JIeSZ_0 z$med9X_Pk!=9~yk?k=A5Xuw4jI=+p8AvWba0#Un`^DKxxT^$?4hX&<6f+*!HsZh;V z@R4#W6BbI!IEN2mOhB*Vt!!sR4aG=gM9o7$0mU5w?*zxk_3Y=skqu{oBo+sM6nq4n z<~9mW;qOOLQA3i78j@_R1*@g%teONJTGDLC4*Lb$k4(>e^}%z0?K?SWS~hq)?)VJ`QOO+ z4*+|HUi9~Yq+4{re~y;QK*m227U(Tzz7z(F+ljPdMAXa7jDISq#bPET5Y5llfGj?{ z7vFtG)is{Rm^VOaG1H$5+I^xHM!M1a=bz%$HIE%yt%V6Ry5YYDWh0B3VxTdJR6m#7 zok6v3e12A|@LpU#qBrZFwLc*g*N1t2_RKd=>78^zOPYK(v_`;@-o`x}{&iTpvd28_Yn)cv_*inCV{(?HiGeOOto+Ij`1@&u?oL8;?ix!>>4W zdM)M&qw#Iz7ok7e_!{zf++lCP%Z_RnIgjUy-ax?bImwbqe7h&36V(d7{_;9l)~YqD vKwhczr^>Sa3rw|YsQGY)*Dnon;zVNz--IkZB9@EX%H5?#5cZx3Ac%hh+c`g{ literal 0 HcmV?d00001 diff --git a/Source/Glide64/MSVS/Debug/Ext_TxFilter.obj b/Source/Glide64/MSVS/Debug/Ext_TxFilter.obj new file mode 100644 index 0000000000000000000000000000000000000000..8295fbb344f545bfec2fd5841364d201977d53a4 GIT binary patch literal 30078 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 \ No newline at end of file diff --git a/Source/Glide64/MSVS/Debug/vc90.idb b/Source/Glide64/MSVS/Debug/vc90.idb new file mode 100644 index 0000000000000000000000000000000000000000..0e8d91e9b75320f67dadceb7ca0b5fa0550d9a13 GIT binary patch literal 142336 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

nYok3?Ee4KSM?GADsMcyKE{TQ0{@cLr- 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 UK&pXM1E~g54Wt_Qzgz?V8{l!(^8f$< literal 0 HcmV?d00001 diff --git a/Source/Glide64/MSVS/Glide64.vcproj b/Source/Glide64/MSVS/Glide64.vcproj new file mode 100644 index 000000000..b8ecbd655 --- /dev/null +++ b/Source/Glide64/MSVS/Glide64.vcproj @@ -0,0 +1,518 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Source/Glide64/Main.cpp b/Source/Glide64/Main.cpp new file mode 100644 index 000000000..255e5001d --- /dev/null +++ b/Source/Glide64/Main.cpp @@ -0,0 +1,2435 @@ +/* +* Glide64 - Glide video plugin for Nintendo 64 emulators. +* Copyright (c) 2002 Dave2001 +* Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski +* +* 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 +* 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 +*/ + +//**************************************************************** +// +// Glide64 - Glide Plugin for Nintendo 64 emulators +// Project started on December 29th, 2001 +// +// Authors: +// Dave2001, original author, founded the project in 2001, left it in 2002 +// Gugaman, joined the project in 2002, left it in 2002 +// Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002 +// Hiroshi 'KoolSmoky' Morii, joined the project in 2007 +// +//**************************************************************** +// +// To modify Glide64: +// * Write your name and (optional)email, commented by your work, so I know who did it, and so that you can find which parts you modified when it comes time to send it to me. +// * Do NOT send me the whole project or file that you modified. Take out your modified code sections, and tell me where to put them. If people sent the whole thing, I would have many different versions, but no idea how to combine them all. +// +//**************************************************************** + +#include "Gfx #1.3.h" +#include +#include +#include "Util.h" +#include "3dmath.h" +#include "Debugger.h" +#include "Combine.h" +#include "TexCache.h" +#include "CRC.h" +#include "FBtoScreen.h" +#include "DepthBufferRender.h" + +#ifdef TEXTURE_FILTER // Hiroshi Morii +#include +int ghq_dmptex_toggle_key = 0; +#endif + +#define G64_VERSION "'Final' " +#define RELTIME "Date: " __DATE__// " Time: " __TIME__ + +#ifdef EXT_LOGGING +std::ofstream extlog; +#endif + +#ifdef LOGGING +std::ofstream loga; +#endif + +#ifdef RDP_LOGGING +int log_open = FALSE; +std::ofstream rdp_log; +#endif + +#ifdef RDP_ERROR_LOG +int elog_open = FALSE; +std::ofstream rdp_err; +#endif + +GFX_INFO gfx; +wxWindow * GFXWindow = NULL; + +int to_fullscreen = FALSE; +int fullscreen = FALSE; +int romopen = FALSE; +GrContext_t gfx_context = 0; +int debugging = FALSE; +int exception = FALSE; + +int evoodoo = 0; +int ev_fullscreen = 0; + +#ifdef __WINDOWS__ +#define WINPROC_OVERRIDE +#endif + +#ifdef WINPROC_OVERRIDE +LRESULT CALLBACK WndProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); +WNDPROC oldWndProc = NULL; +WNDPROC myWndProc = NULL; +#endif + +#ifdef ALTTAB_FIX +HHOOK hhkLowLevelKybd = NULL; +LRESULT CALLBACK LowLevelKeyboardProc(int nCode, + WPARAM wParam, LPARAM lParam); +#endif + +#ifdef PERFORMANCE +int64 perf_cur; +int64 perf_next; +#endif + +#ifdef FPS +wxDateTime fps_last; +wxDateTime fps_next; +float fps = 0.0f; +wxUint32 fps_count = 0; + +wxUint32 vi_count = 0; +float vi = 0.0f; + +wxUint32 region = 0; + +float ntsc_percent = 0.0f; +float pal_percent = 0.0f; + +#endif + +// Resolutions, MUST be in the correct order (SST1VID.H) +wxUint32 resolutions[0x18][2] = { + { 320, 200 }, + { 320, 240 }, + { 400, 256 }, + { 512, 384 }, + { 640, 200 }, + { 640, 350 }, + { 640, 400 }, + { 640, 480 }, + { 800, 600 }, + { 960, 720 }, + { 856, 480 }, + { 512, 256 }, + { 1024, 768 }, + { 1280, 1024 }, + { 1600, 1200 }, + { 400, 300 }, + + // 0x10 + { 1152, 864 }, + { 1280, 960 }, + { 1600, 1024 }, + { 1792, 1344 }, + { 1856, 1392 }, + { 1920, 1440 }, + { 2048, 1536 }, + { 2048, 2048 } +}; + +// ref rate +// 60=0x0, 70=0x1, 72=0x2, 75=0x3, 80=0x4, 90=0x5, 100=0x6, 85=0x7, 120=0x8, none=0xff + +unsigned int BMASK = 0x7FFFFF; +// Reality display processor structure +RDP rdp; + +SETTINGS settings = { FALSE, 640, 480, GR_RESOLUTION_640x480, 0 }; + +HOTKEY_INFO hotkey_info; + +VOODOO voodoo = {0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0 + }; + +GrTexInfo fontTex; +GrTexInfo cursorTex; +wxUint32 offset_font = 0; +wxUint32 offset_cursor = 0; +wxUint32 offset_textures = 0; +wxUint32 offset_texbuf1 = 0; + +int capture_screen = 0; +wxString capture_path; + +wxString pluginPath; +wxString iniPath; +wxString iniName; +wxMutex *mutexProcessDList = NULL; + +/****************************************************************** + NOTE: THIS HAS BEEN ADDED FOR MUPEN64PLUS AND IS NOT PART OF THE + ORIGINAL SPEC + Function: SetConfigDir + Purpose: To pass the location where config files should be read/ + written to. + input: path to config directory + output: none +*******************************************************************/ +EXPORT void CALL SetConfigDir(char *configDir) +{ + wxString dirName(configDir, wxConvUTF8); + wxString path = wxPathOnly(dirName); + if (wxDirExists(path)) + { + iniName = path + wxT("/Glide64.ini"); + iniPath = path; + } +} + +static void PluginPath() +{ + wxDynamicLibraryDetailsArray dlls = wxDynamicLibrary::ListLoaded(); + const size_t count = dlls.GetCount(); + for ( size_t n = 0; n < count; ++n ) + { + const wxDynamicLibraryDetails& details = dlls[n]; + if (details.GetName().Find(wxT("Glide64")) != wxNOT_FOUND) + { + wxFileName libname(details.GetPath()); + pluginPath = libname.GetPath(); + return; + } + } + pluginPath = wxGetCwd() + _T("/Plugin"); //if ListLoaded is not supported by OS use default path +} + +void _ChangeSize () +{ + rdp.scale_1024 = settings.scr_res_x / 1024.0f; + rdp.scale_768 = settings.scr_res_y / 768.0f; + +// float res_scl_x = (float)settings.res_x / 320.0f; + float res_scl_y = (float)settings.res_y / 240.0f; + + wxUint32 scale_x = *gfx.VI_X_SCALE_REG & 0xFFF; + if (!scale_x) return; + wxUint32 scale_y = *gfx.VI_Y_SCALE_REG & 0xFFF; + if (!scale_y) return; + + float fscale_x = (float)scale_x / 1024.0f; + float fscale_y = (float)scale_y / 2048.0f; + + wxUint32 dwHStartReg = *gfx.VI_H_START_REG; + wxUint32 dwVStartReg = *gfx.VI_V_START_REG; + + wxUint32 hstart = dwHStartReg >> 16; + wxUint32 hend = dwHStartReg & 0xFFFF; + + // dunno... but sometimes this happens + if (hend == hstart) hend = (int)(*gfx.VI_WIDTH_REG / fscale_x); + + wxUint32 vstart = dwVStartReg >> 16; + wxUint32 vend = dwVStartReg & 0xFFFF; + + rdp.vi_width = (hend - hstart) * fscale_x; + rdp.vi_height = (vend - vstart) * fscale_y * 1.0126582f; + float aspect = (settings.adjust_aspect && (fscale_y > fscale_x) && (rdp.vi_width > rdp.vi_height)) ? fscale_x/fscale_y : 1.0f; + +#ifdef LOGGING + sprintf (out_buf, "hstart: %d, hend: %d, vstart: %d, vend: %d\n", hstart, hend, vstart, vend); + LOG (out_buf); + sprintf (out_buf, "size: %d x %d\n", (int)rdp.vi_width, (int)rdp.vi_height); + LOG (out_buf); +#endif + + rdp.scale_x = (float)settings.res_x / rdp.vi_width; + if (region > 0 && settings.pal230) + { + // odd... but pal games seem to want 230 as height... + rdp.scale_y = res_scl_y * (230.0f / rdp.vi_height) * aspect; + } + else + { + rdp.scale_y = (float)settings.res_y / rdp.vi_height * aspect; + } + // rdp.offset_x = settings.offset_x * res_scl_x; + // rdp.offset_y = settings.offset_y * res_scl_y; + //rdp.offset_x = 0; + // rdp.offset_y = 0; + rdp.offset_y = ((float)settings.res_y - rdp.vi_height * rdp.scale_y) * 0.5f; + if (((wxUint32)rdp.vi_width <= (*gfx.VI_WIDTH_REG)/2) && (rdp.vi_width > rdp.vi_height)) + rdp.scale_y *= 0.5f; + + rdp.scissor_o.ul_x = 0; + rdp.scissor_o.ul_y = 0; + rdp.scissor_o.lr_x = (wxUint32)rdp.vi_width; + rdp.scissor_o.lr_y = (wxUint32)rdp.vi_height; + + rdp.update |= UPDATE_VIEWPORT | UPDATE_SCISSOR; +} + +void ChangeSize () +{ + if (debugging) + { + _ChangeSize (); + return; + } + switch (settings.aspectmode) + { + case 0: //4:3 + if (settings.scr_res_x >= settings.scr_res_y * 4.0f / 3.0f) { + settings.res_y = settings.scr_res_y; + settings.res_x = (wxUint32)(settings.res_y * 4.0f / 3.0f); + } else { + settings.res_x = settings.scr_res_x; + settings.res_y = (wxUint32)(settings.res_x / 4.0f * 3.0f); + } + break; + case 1: //16:9 + if (settings.scr_res_x >= settings.scr_res_y * 16.0f / 9.0f) { + settings.res_y = settings.scr_res_y; + settings.res_x = (wxUint32)(settings.res_y * 16.0f / 9.0f); + } else { + settings.res_x = settings.scr_res_x; + settings.res_y = (wxUint32)(settings.res_x / 16.0f * 9.0f); + } + break; + default: //stretch or original + settings.res_x = settings.scr_res_x; + settings.res_y = settings.scr_res_y; + } + _ChangeSize (); + rdp.offset_x = (settings.scr_res_x - settings.res_x) / 2.0f; + float offset_y = (settings.scr_res_y - settings.res_y) / 2.0f; + settings.res_x += (wxUint32)rdp.offset_x; + settings.res_y += (wxUint32)offset_y; + rdp.offset_y += offset_y; + if (settings.aspectmode == 3) // original + { + rdp.scale_x = rdp.scale_y = 1.0f; + rdp.offset_x = (settings.scr_res_x - rdp.vi_width) / 2.0f; + rdp.offset_y = (settings.scr_res_y - rdp.vi_height) / 2.0f; + } + // settings.res_x = settings.scr_res_x; + // settings.res_y = settings.scr_res_y; +} + +void ConfigWrapper() +{ + char strConfigWrapperExt[] = "grConfigWrapperExt"; + GRCONFIGWRAPPEREXT grConfigWrapperExt = (GRCONFIGWRAPPEREXT)grGetProcAddress(strConfigWrapperExt); + if (grConfigWrapperExt) + grConfigWrapperExt(settings.wrpResolution, settings.wrpVRAM * 1024 * 1024, settings.wrpFBO, settings.wrpAnisotropic); +} + +static wxConfigBase * OpenIni() +{ + wxConfigBase * ini = wxConfigBase::Get(false); + if (!ini) + { + if (iniName.IsEmpty()) + iniName = pluginPath + wxT("/Glide64.ini"); + if (wxFileExists(iniName)) + { + wxFileInputStream is(iniName); + wxFileConfig * fcfg = new wxFileConfig(is, wxConvISO8859_1); + wxConfigBase::Set(fcfg); + ini = fcfg; + } + } + if (!ini) + wxMessageBox(_T("Can not find ini file! Plugin will not run properly."), _T("File not found"), wxOK|wxICON_EXCLAMATION); + return ini; +} + +void ReadSettings () +{ + // LOG("ReadSettings\n"); + wxConfigBase * ini = OpenIni(); + if (!ini || !ini->HasGroup(_T("/SETTINGS"))) + return; + ini->SetPath(_T("/SETTINGS")); + + settings.card_id = ini->Read(_T("card_id"), 0l); + settings.lang_id = ini->Read(_T("lang_id"), wxLANGUAGE_ENGLISH_US); + settings.res_data = (wxUint32)ini->Read(_T("resolution"), 7); + if (settings.res_data >= 24) settings.res_data = 12; + settings.scr_res_x = settings.res_x = resolutions[settings.res_data][0]; + settings.scr_res_y = settings.res_y = resolutions[settings.res_data][1]; + settings.vsync = ini->Read(_T("vsync"), 0l); + settings.ssformat = (wxUint8)ini->Read(_T("ssformat"), 0l); + settings.show_fps = (wxUint8)ini->Read(_T("show_fps"), 0l); + settings.clock = ini->Read(_T("clock"), 0l); + settings.clock_24_hr = ini->Read(_T("clock_24_hr"), 0l); + settings.advanced_options = ini->Read(_T("advanced_options"), 0l); + settings.texenh_options = ini->Read(_T("texenh_options"), 0l); + settings.use_hotkeys = ini->Read(_T("hotkeys"), 1l); + + settings.wrpResolution = ini->Read(_T("wrpResolution"), 0l); + settings.wrpVRAM = ini->Read(_T("wrpVRAM"), 0l); + settings.wrpFBO = ini->Read(_T("wrpFBO"), 0l); + settings.wrpAnisotropic = ini->Read(_T("wrpAnisotropic"), 0l); + +#ifndef _ENDUSER_RELEASE_ + settings.autodetect_ucode = ini->Read(_T("autodetect_ucode"), 1); + settings.ucode = ini->Read(_T("ucode"), 2); + settings.wireframe = ini->Read(_T("wireframe"), 0l); + settings.wfmode = ini->Read(_T("wfmode"), 1); + settings.logging = ini->Read(_T("logging"), 0l); + settings.log_clear = ini->Read(_T("log_clear"), 0l); + settings.run_in_window = ini->Read(_T("run_in_window"), 0l); + settings.elogging = ini->Read(_T("elogging"), 0l); + settings.filter_cache = ini->Read(_T("filter_cache"), 0l); + settings.unk_as_red = ini->Read(_T("unk_as_red"), 0l); + settings.log_unk = ini->Read(_T("log_unk"), 0l); + settings.unk_clear = ini->Read(_T("unk_clear"), 0l); +#else + settings.autodetect_ucode = TRUE; + settings.ucode = 2; + settings.wireframe = FALSE; + settings.wfmode = 0; + settings.logging = FALSE; + settings.log_clear = FALSE; + settings.run_in_window = FALSE; + settings.elogging = FALSE; + settings.filter_cache = FALSE; + settings.unk_as_red = FALSE; + settings.log_unk = FALSE; + settings.unk_clear = FALSE; +#endif + +#ifdef TEXTURE_FILTER + settings.ghq_fltr = (wxUint8)ini->Read(_T("ghq_fltr"), 0l); + settings.ghq_cmpr = (wxUint8)ini->Read(_T("ghq_cmpr"), 0l); + settings.ghq_enht = (wxUint8)ini->Read(_T("ghq_enht"), 0l); + settings.ghq_hirs = (wxUint8)ini->Read(_T("ghq_hirs"), 0l); + settings.ghq_enht_cmpr = ini->Read(_T("ghq_enht_cmpr"), 0l); + settings.ghq_enht_tile = ini->Read(_T("ghq_enht_tile"), 0l); + settings.ghq_enht_f16bpp = ini->Read(_T("ghq_enht_f16bpp"), 0l); + settings.ghq_enht_gz = ini->Read(_T("ghq_enht_gz"), 1L); + settings.ghq_enht_nobg = ini->Read(_T("ghq_enht_nobg"), 0l); + settings.ghq_hirs_cmpr = ini->Read(_T("ghq_hirs_cmpr"), 0l); + settings.ghq_hirs_tile = ini->Read(_T("ghq_hirs_tile"), 0l); + settings.ghq_hirs_f16bpp = ini->Read(_T("ghq_hirs_f16bpp"), 0l); + settings.ghq_hirs_gz = ini->Read(_T("ghq_hirs_gz"), 1); + settings.ghq_hirs_altcrc = ini->Read(_T("ghq_hirs_altcrc"), 1); + settings.ghq_cache_save = ini->Read(_T("ghq_cache_save"), 1); + settings.ghq_cache_size = ini->Read(_T("ghq_cache_size"), 0l); + settings.ghq_hirs_let_texartists_fly = ini->Read(_T("ghq_hirs_let_texartists_fly"), 0l); + settings.ghq_hirs_dump = ini->Read(_T("ghq_hirs_dump"), 0l); +#endif + ConfigWrapper(); +} + +void ReadSpecialSettings (const char * name) +{ + // char buf [256]; + // sprintf(buf, "ReadSpecialSettings. Name: %s\n", name); + // LOG(buf); + settings.hacks = 0; + + //detect games which require special hacks + if (strstr(name, (const char *)"ZELDA") || strstr(name, (const char *)"MASK")) + settings.hacks |= hack_Zelda; + else if (strstr(name, (const char *)"ROADSTERS TROPHY")) + settings.hacks |= hack_Zelda; + else if (strstr(name, (const char *)"Diddy Kong Racing")) + settings.hacks |= hack_Diddy; + else if (strstr(name, (const char *)"Tonic Trouble")) + settings.hacks |= hack_Tonic; + else if (strstr(name, (const char *)"All") && strstr(name, (const char *)"Star") && strstr(name, (const char *)"Baseball")) + settings.hacks |= hack_ASB; + else if (strstr(name, (const char *)"Beetle") || strstr(name, (const char *)"BEETLE") || strstr(name, (const char *)"HSV")) + settings.hacks |= hack_BAR; + else if (strstr(name, (const char *)"I S S 64") || strstr(name, (const char *)"J WORLD SOCCER3") || strstr(name, (const char *)"PERFECT STRIKER") || strstr(name, (const char *)"RONALDINHO SOCCER")) + settings.hacks |= hack_ISS64; + else if (strstr(name, (const char *)"MARIOKART64")) + settings.hacks |= hack_MK64; + else if (strstr(name, (const char *)"NITRO64")) + settings.hacks |= hack_WCWnitro; + else if (strstr(name, (const char *)"CHOPPER_ATTACK") || strstr(name, (const char *)"WILD CHOPPERS")) + settings.hacks |= hack_Chopper; + else if (strstr(name, (const char *)"Resident Evil II") || strstr(name, (const char *)"BioHazard II")) + settings.hacks |= hack_RE2; + else if (strstr(name, (const char *)"YOSHI STORY")) + settings.hacks |= hack_Yoshi; + else if (strstr(name, (const char *)"F-Zero X") || strstr(name, (const char *)"F-ZERO X")) + settings.hacks |= hack_Fzero; + else if (strstr(name, (const char *)"PAPER MARIO") || strstr(name, (const char *)"MARIO STORY")) + settings.hacks |= hack_PMario; + else if (strstr(name, (const char *)"TOP GEAR RALLY 2")) + settings.hacks |= hack_TGR2; + else if (strstr(name, (const char *)"TOP GEAR RALLY")) + settings.hacks |= hack_TGR; + else if (strstr(name, (const char *)"Top Gear Hyper Bike")) + settings.hacks |= hack_Hyperbike; + else if (strstr(name, (const char *)"Killer Instinct Gold") || strstr(name, (const char *)"KILLER INSTINCT GOLD")) + settings.hacks |= hack_KI; + else if (strstr(name, (const char *)"Knockout Kings 2000")) + settings.hacks |= hack_Knockout; + else if (strstr(name, (const char *)"LEGORacers")) + settings.hacks |= hack_Lego; + else if (strstr(name, (const char *)"OgreBattle64")) + settings.hacks |= hack_Ogre64; + else if (strstr(name, (const char *)"Pilot Wings64")) + settings.hacks |= hack_Pilotwings; + else if (strstr(name, (const char *)"Supercross")) + settings.hacks |= hack_Supercross; + else if (strstr(name, (const char *)"STARCRAFT 64")) + settings.hacks |= hack_Starcraft; + else if (strstr(name, (const char *)"BANJO KAZOOIE 2") || strstr(name, (const char *)"BANJO TOOIE")) + settings.hacks |= hack_Banjo2; + else if (strstr(name, (const char *)"FIFA: RTWC 98") || strstr(name, (const char *)"RoadToWorldCup98")) + settings.hacks |= hack_Fifa98; + else if (strstr(name, (const char *)"Mega Man 64") || strstr(name, (const char *)"RockMan Dash")) + settings.hacks |= hack_Megaman; + else if (strstr(name, (const char *)"MISCHIEF MAKERS") || strstr(name, (const char *)"TROUBLE MAKERS")) + settings.hacks |= hack_Makers; + else if (strstr(name, (const char *)"GOLDENEYE")) + settings.hacks |= hack_GoldenEye; + else if (strstr(name, (const char *)"PUZZLE LEAGUE")) + settings.hacks |= hack_PPL; + + wxString groupName = wxT("/"); + groupName += wxString::FromAscii(name); + wxConfigBase * ini = OpenIni(); + if (!ini || !ini->HasGroup(groupName)) + return; + ini->SetPath(groupName); + + ini->Read(_T("alt_tex_size"), &(settings.alt_tex_size)); + ini->Read(_T("use_sts1_only"), &(settings.use_sts1_only)); + ini->Read(_T("force_calc_sphere"), &(settings.force_calc_sphere)); + ini->Read(_T("correct_viewport"), &(settings.correct_viewport)); + ini->Read(_T("increase_texrect_edge"), &(settings.increase_texrect_edge)); + ini->Read(_T("decrease_fillrect_edge"), &(settings.decrease_fillrect_edge)); + if (ini->Read(_T("texture_correction"), -1) == 0) settings.texture_correction = 0; + else settings.texture_correction = 1; + if (ini->Read(_T("pal230"), -1) == 1) settings.pal230 = 1; + else settings.pal230 = 0; + ini->Read(_T("stipple_mode"), &(settings.stipple_mode)); + int stipple_pattern = ini->Read(_T("stipple_pattern"), -1); + if (stipple_pattern > 0) settings.stipple_pattern = (wxUint32)stipple_pattern; + ini->Read(_T("force_microcheck"), &(settings.force_microcheck)); + ini->Read(_T("force_quad3d"), &(settings.force_quad3d)); + ini->Read(_T("clip_zmin"), &(settings.clip_zmin)); + ini->Read(_T("clip_zmax"), &(settings.clip_zmax)); + ini->Read(_T("fast_crc"), &(settings.fast_crc)); + ini->Read(_T("adjust_aspect"), &(settings.adjust_aspect), 1); + ini->Read(_T("zmode_compare_less"), &(settings.zmode_compare_less)); + ini->Read(_T("old_style_adither"), &(settings.old_style_adither)); + ini->Read(_T("n64_z_scale"), &(settings.n64_z_scale)); + if (settings.n64_z_scale) + ZLUT_init(); + + //frame buffer + int optimize_texrect = ini->Read(_T("optimize_texrect"), -1); + int ignore_aux_copy = ini->Read(_T("ignore_aux_copy"), -1); + int hires_buf_clear = ini->Read(_T("hires_buf_clear"), -1); + int read_alpha = ini->Read(_T("fb_read_alpha"), -1); + int useless_is_useless = ini->Read(_T("useless_is_useless"), -1); + int fb_crc_mode = ini->Read(_T("fb_crc_mode"), -1); + + if (optimize_texrect > 0) settings.frame_buffer |= fb_optimize_texrect; + else if (optimize_texrect == 0) settings.frame_buffer &= ~fb_optimize_texrect; + if (ignore_aux_copy > 0) settings.frame_buffer |= fb_ignore_aux_copy; + else if (ignore_aux_copy == 0) settings.frame_buffer &= ~fb_ignore_aux_copy; + if (hires_buf_clear > 0) settings.frame_buffer |= fb_hwfbe_buf_clear; + else if (hires_buf_clear == 0) settings.frame_buffer &= ~fb_hwfbe_buf_clear; + if (read_alpha > 0) settings.frame_buffer |= fb_read_alpha; + else if (read_alpha == 0) settings.frame_buffer &= ~fb_read_alpha; + if (useless_is_useless > 0) settings.frame_buffer |= fb_useless_is_useless; + else settings.frame_buffer &= ~fb_useless_is_useless; + if (fb_crc_mode >= 0) settings.fb_crc_mode = (SETTINGS::FBCRCMODE)fb_crc_mode; + + // if (settings.custom_ini) + { + ini->Read(_T("filtering"), &(settings.filtering)); + ini->Read(_T("fog"), &(settings.fog)); + ini->Read(_T("buff_clear"), &(settings.buff_clear)); + ini->Read(_T("swapmode"), &(settings.swapmode)); + ini->Read(_T("aspect"), &(settings.aspectmode)); + ini->Read(_T("lodmode"), &(settings.lodmode)); + int resolution; + if (ini->Read(_T("resolution"), &resolution)) + { + settings.res_data = (wxUint32)resolution; + if (settings.res_data >= 0x18) settings.res_data = 12; + settings.scr_res_x = settings.res_x = resolutions[settings.res_data][0]; + settings.scr_res_y = settings.res_y = resolutions[settings.res_data][1]; + } + + //frame buffer + int smart_read = ini->Read(_T("fb_smart"), -1); + int hires = ini->Read(_T("fb_hires"), -1); + int read_always = ini->Read(_T("fb_read_always"), -1); + int read_back_to_screen = ini->Read(_T("read_back_to_screen"), -1); + int cpu_write_hack = ini->Read(_T("detect_cpu_write"), -1); + int get_fbinfo = ini->Read(_T("fb_get_info"), -1); + int depth_render = ini->Read(_T("fb_render"), -1); + + if (smart_read > 0) settings.frame_buffer |= fb_emulation; + else if (smart_read == 0) settings.frame_buffer &= ~fb_emulation; + if (hires > 0) settings.frame_buffer |= fb_hwfbe; + else if (hires == 0) settings.frame_buffer &= ~fb_hwfbe; + if (read_always > 0) settings.frame_buffer |= fb_ref; + else if (read_always == 0) settings.frame_buffer &= ~fb_ref; + if (read_back_to_screen == 1) settings.frame_buffer |= fb_read_back_to_screen; + else if (read_back_to_screen == 2) settings.frame_buffer |= fb_read_back_to_screen2; + else if (read_back_to_screen == 0) settings.frame_buffer &= ~(fb_read_back_to_screen|fb_read_back_to_screen2); + if (cpu_write_hack > 0) settings.frame_buffer |= fb_cpu_write_hack; + else if (cpu_write_hack == 0) settings.frame_buffer &= ~fb_cpu_write_hack; + if (get_fbinfo > 0) settings.frame_buffer |= fb_get_info; + else if (get_fbinfo == 0) settings.frame_buffer &= ~fb_get_info; + if (depth_render > 0) settings.frame_buffer |= fb_depth_render; + else if (depth_render == 0) settings.frame_buffer &= ~fb_depth_render; + settings.frame_buffer |= fb_motionblur; + } + settings.flame_corona = (settings.hacks & hack_Zelda) && !fb_depth_render_enabled; +} + +void WriteSettings (bool saveEmulationSettings) +{ + wxConfigBase * ini = OpenIni(); + if (!ini || !ini->HasGroup(_T("/SETTINGS"))) + return; + ini->SetPath(_T("/SETTINGS")); + + ini->Write(_T("card_id"), settings.card_id); + ini->Write(_T("lang_id"), settings.lang_id); + ini->Write(_T("resolution"), (int)settings.res_data); + ini->Write(_T("ssformat"), settings.ssformat); + ini->Write(_T("vsync"), settings.vsync); + ini->Write(_T("show_fps"), settings.show_fps); + ini->Write(_T("clock"), settings.clock); + ini->Write(_T("clock_24_hr"), settings.clock_24_hr); + ini->Write(_T("advanced_options"), settings.advanced_options); + ini->Write(_T("texenh_options"), settings.texenh_options); + + ini->Write(_T("wrpResolution"), settings.wrpResolution); + ini->Write(_T("wrpVRAM"), settings.wrpVRAM); + ini->Write(_T("wrpFBO"), settings.wrpFBO); + ini->Write(_T("wrpAnisotropic"), settings.wrpAnisotropic); + +#ifndef _ENDUSER_RELEASE_ + ini->Write(_T("autodetect_ucode"), settings.autodetect_ucode); + ini->Write(_T("ucode"), (int)settings.ucode); + ini->Write(_T("wireframe"), settings.wireframe); + ini->Write(_T("wfmode"), settings.wfmode); + ini->Write(_T("logging"), settings.logging); + ini->Write(_T("log_clear"), settings.log_clear); + ini->Write(_T("run_in_window"), settings.run_in_window); + ini->Write(_T("elogging"), settings.elogging); + ini->Write(_T("filter_cache"), settings.filter_cache); + ini->Write(_T("unk_as_red"), settings.unk_as_red); + ini->Write(_T("log_unk"), settings.log_unk); + ini->Write(_T("unk_clear"), settings.unk_clear); +#endif //_ENDUSER_RELEASE_ + +#ifdef TEXTURE_FILTER + ini->Write(_T("ghq_fltr"), settings.ghq_fltr); + ini->Write(_T("ghq_cmpr"), settings.ghq_cmpr); + ini->Write(_T("ghq_enht"), settings.ghq_enht); + ini->Write(_T("ghq_hirs"), settings.ghq_hirs); + ini->Write(_T("ghq_enht_cmpr"), settings.ghq_enht_cmpr); + ini->Write(_T("ghq_enht_tile"), settings.ghq_enht_tile); + ini->Write(_T("ghq_enht_f16bpp"), settings.ghq_enht_f16bpp); + ini->Write(_T("ghq_enht_gz"), settings.ghq_enht_gz); + ini->Write(_T("ghq_enht_nobg"), settings.ghq_enht_nobg); + ini->Write(_T("ghq_hirs_cmpr"), settings.ghq_hirs_cmpr); + ini->Write(_T("ghq_hirs_tile"), settings.ghq_hirs_tile); + ini->Write(_T("ghq_hirs_f16bpp"), settings.ghq_hirs_f16bpp); + ini->Write(_T("ghq_hirs_gz"), settings.ghq_hirs_gz); + ini->Write(_T("ghq_hirs_altcrc"), settings.ghq_hirs_altcrc); + ini->Write(_T("ghq_cache_save"), settings.ghq_cache_save); + ini->Write(_T("ghq_cache_size"), settings.ghq_cache_size); + ini->Write(_T("ghq_hirs_let_texartists_fly"), settings.ghq_hirs_let_texartists_fly); + ini->Write(_T("ghq_hirs_dump"), settings.ghq_hirs_dump); +#endif + + if (saveEmulationSettings) + { + if (romopen) + { + wxString S = _T("/"); + ini->SetPath(S+rdp.RomName); + } + else + ini->SetPath(_T("/DEFAULT")); + ini->Write(_T("filtering"), settings.filtering); + ini->Write(_T("fog"), settings.fog); + ini->Write(_T("buff_clear"), settings.buff_clear); + ini->Write(_T("swapmode"), settings.swapmode); + ini->Write(_T("lodmode"), settings.lodmode); + ini->Write(_T("aspect"), settings.aspectmode); + + ini->Write(_T("fb_read_always"), settings.frame_buffer&fb_ref ? 1 : 0l); + ini->Write(_T("fb_smart"), settings.frame_buffer & fb_emulation ? 1 : 0l); + // ini->Write("motionblur", settings.frame_buffer & fb_motionblur ? 1 : 0); + ini->Write(_T("fb_hires"), settings.frame_buffer & fb_hwfbe ? 1 : 0l); + ini->Write(_T("fb_get_info"), settings.frame_buffer & fb_get_info ? 1 : 0l); + ini->Write(_T("fb_render"), settings.frame_buffer & fb_depth_render ? 1 : 0l); + ini->Write(_T("detect_cpu_write"), settings.frame_buffer & fb_cpu_write_hack ? 1 : 0l); + if (settings.frame_buffer & fb_read_back_to_screen) + ini->Write(_T("read_back_to_screen"), 1); + else if (settings.frame_buffer & fb_read_back_to_screen2) + ini->Write(_T("read_back_to_screen"), 2); + else + ini->Write(_T("read_back_to_screen"), 0l); + } + + wxFileOutputStream os(iniName); + ((wxFileConfig*)ini)->Save(os); +} + +GRTEXBUFFEREXT grTextureBufferExt = NULL; +GRTEXBUFFEREXT grTextureAuxBufferExt = NULL; +GRAUXBUFFEREXT grAuxBufferExt = NULL; +GRSTIPPLE grStippleModeExt = NULL; +GRSTIPPLE grStipplePatternExt = NULL; +FxBool (FX_CALL *grKeyPressed)(FxU32) = NULL; + +int GetTexAddrUMA(int tmu, int texsize) +{ + int addr = voodoo.tex_min_addr[0] + voodoo.tmem_ptr[0]; + voodoo.tmem_ptr[0] += texsize; + voodoo.tmem_ptr[1] = voodoo.tmem_ptr[0]; + return addr; +} +int GetTexAddrNonUMA(int tmu, int texsize) +{ + int addr = voodoo.tex_min_addr[tmu] + voodoo.tmem_ptr[tmu]; + voodoo.tmem_ptr[tmu] += texsize; + return addr; +} +GETTEXADDR GetTexAddr = GetTexAddrNonUMA; + +// guLoadTextures - used to load the cursor and font textures +void guLoadTextures () +{ + if (grTextureBufferExt) + { + int tbuf_size = 0; + if (voodoo.max_tex_size <= 256) + { + grTextureBufferExt( GR_TMU1, voodoo.tex_min_addr[GR_TMU1], GR_LOD_LOG2_256, GR_LOD_LOG2_256, + GR_ASPECT_LOG2_1x1, GR_TEXFMT_RGB_565, GR_MIPMAPLEVELMASK_BOTH ); + tbuf_size = 8 * grTexCalcMemRequired(GR_LOD_LOG2_256, GR_LOD_LOG2_256, + GR_ASPECT_LOG2_1x1, GR_TEXFMT_RGB_565); + } + else if (settings.scr_res_x <= 1024) + { + grTextureBufferExt( GR_TMU0, voodoo.tex_min_addr[GR_TMU0], GR_LOD_LOG2_1024, GR_LOD_LOG2_1024, + GR_ASPECT_LOG2_1x1, GR_TEXFMT_RGB_565, GR_MIPMAPLEVELMASK_BOTH ); + tbuf_size = grTexCalcMemRequired(GR_LOD_LOG2_1024, GR_LOD_LOG2_1024, + GR_ASPECT_LOG2_1x1, GR_TEXFMT_RGB_565); + grRenderBuffer( GR_BUFFER_TEXTUREBUFFER_EXT ); + grBufferClear (0, 0, 0xFFFF); + grRenderBuffer( GR_BUFFER_BACKBUFFER ); + } + else + { + grTextureBufferExt( GR_TMU0, voodoo.tex_min_addr[GR_TMU0], GR_LOD_LOG2_2048, GR_LOD_LOG2_2048, + GR_ASPECT_LOG2_1x1, GR_TEXFMT_RGB_565, GR_MIPMAPLEVELMASK_BOTH ); + tbuf_size = grTexCalcMemRequired(GR_LOD_LOG2_2048, GR_LOD_LOG2_2048, + GR_ASPECT_LOG2_1x1, GR_TEXFMT_RGB_565); + grRenderBuffer( GR_BUFFER_TEXTUREBUFFER_EXT ); + grBufferClear (0, 0, 0xFFFF); + grRenderBuffer( GR_BUFFER_BACKBUFFER ); + } + + rdp.texbufs[0].tmu = GR_TMU0; + rdp.texbufs[0].begin = voodoo.tex_min_addr[GR_TMU0]; + rdp.texbufs[0].end = rdp.texbufs[0].begin+tbuf_size; + rdp.texbufs[0].count = 0; + rdp.texbufs[0].clear_allowed = TRUE; + offset_font = tbuf_size; + if (voodoo.num_tmu > 1) + { + rdp.texbufs[1].tmu = GR_TMU1; + rdp.texbufs[1].begin = voodoo.tex_UMA ? rdp.texbufs[0].end : voodoo.tex_min_addr[GR_TMU1]; + rdp.texbufs[1].end = rdp.texbufs[1].begin+tbuf_size; + rdp.texbufs[1].count = 0; + rdp.texbufs[1].clear_allowed = TRUE; + if (voodoo.tex_UMA) + offset_font += tbuf_size; + else + offset_texbuf1 = tbuf_size; + } + } + else + offset_font = 0; + +#include "font.h" + wxUint32 *data = (wxUint32*)font; + wxUint32 cur; + + // ** Font texture ** + wxUint8 *tex8 = (wxUint8*)malloc(256*64); + + fontTex.smallLodLog2 = fontTex.largeLodLog2 = GR_LOD_LOG2_256; + fontTex.aspectRatioLog2 = GR_ASPECT_LOG2_4x1; + fontTex.format = GR_TEXFMT_ALPHA_8; + fontTex.data = tex8; + + // Decompression: [1-bit inverse alpha --> 8-bit alpha] + wxUint32 i,b; + for (i=0; i<0x200; i++) + { + // cur = ~*(data++), byteswapped +#ifdef __VISUALC__ + cur = _byteswap_ulong(~*(data++)); +#else + cur = ~*(data++); + cur = ((cur&0xFF)<<24)|(((cur>>8)&0xFF)<<16)|(((cur>>16)&0xFF)<<8)|((cur>>24)&0xFF); +#endif + + for (b=0x80000000; b!=0; b>>=1) + { + if (cur&b) *tex8 = 0xFF; + else *tex8 = 0x00; + tex8 ++; + } + } + + grTexDownloadMipMap (GR_TMU0, + voodoo.tex_min_addr[GR_TMU0] + offset_font, + GR_MIPMAPLEVELMASK_BOTH, + &fontTex); + + offset_cursor = offset_font + grTexTextureMemRequired (GR_MIPMAPLEVELMASK_BOTH, &fontTex); + + free (fontTex.data); + + // ** Cursor texture ** +#include "cursor.h" + data = (wxUint32*)cursor; + + wxUint16 *tex16 = (wxUint16*)malloc(32*32*2); + + cursorTex.smallLodLog2 = cursorTex.largeLodLog2 = GR_LOD_LOG2_32; + cursorTex.aspectRatioLog2 = GR_ASPECT_LOG2_1x1; + cursorTex.format = GR_TEXFMT_ARGB_1555; + cursorTex.data = tex16; + + // Conversion: [16-bit 1555 (swapped) --> 16-bit 1555] + for (i=0; i<0x200; i++) + { + cur = *(data++); + *(tex16++) = (wxUint16)(((cur&0x000000FF)<<8)|((cur&0x0000FF00)>>8)); + *(tex16++) = (wxUint16)(((cur&0x00FF0000)>>8)|((cur&0xFF000000)>>24)); + } + + grTexDownloadMipMap (GR_TMU0, + voodoo.tex_min_addr[GR_TMU0] + offset_cursor, + GR_MIPMAPLEVELMASK_BOTH, + &cursorTex); + + // Round to higher 16 + offset_textures = ((offset_cursor + grTexTextureMemRequired (GR_MIPMAPLEVELMASK_BOTH, &cursorTex)) + & 0xFFFFFFF0) + 16; + free (cursorTex.data); +} + +#ifdef TEXTURE_FILTER +void DisplayLoadProgress(const wchar_t *format, ...) +{ + va_list args; + wchar_t wbuf[INFO_BUF]; + char buf[INFO_BUF]; + + // process input + va_start(args, format); + vswprintf(wbuf, INFO_BUF, format, args); + va_end(args); + + // XXX: convert to multibyte + wcstombs(buf, wbuf, INFO_BUF); + + if (fullscreen) + { + float x; + set_message_combiner (); + output (382, 380, 1, "LOADING TEXTURES. PLEASE WAIT..."); + int len = min (strlen(buf)*8, 1024); + x = (1024-len)/2.0f; + output (x, 360, 1, buf); + grBufferSwap (0); + grColorMask (FXTRUE, FXTRUE); + grBufferClear (0, 0, 0xFFFF); + } +} +#endif + +int InitGfx () +{ + if (fullscreen) + ReleaseGfx (); + + OPEN_RDP_LOG (); // doesn't matter if opens again; it will check for it + OPEN_RDP_E_LOG (); + LOG ("InitGfx ()\n"); + + debugging = FALSE; + rdp_reset (); + + // Initialize Glide + grGlideInit (); + + // Select the Glide device + grSstSelect (settings.card_id); + + // Is mirroring allowed? + const char *extensions = grGetString (GR_EXTENSION); + + // Check which SST we are using and initialize stuff + // Hiroshi Morii + enum { + GR_SSTTYPE_VOODOO = 0, + GR_SSTTYPE_SST96 = 1, + GR_SSTTYPE_AT3D = 2, + GR_SSTTYPE_Voodoo2 = 3, + GR_SSTTYPE_Banshee = 4, + GR_SSTTYPE_Voodoo3 = 5, + GR_SSTTYPE_Voodoo4 = 6, + GR_SSTTYPE_Voodoo5 = 7 + }; + const char *hardware = grGetString(GR_HARDWARE); + unsigned int SST_type = GR_SSTTYPE_VOODOO; + if (strstr(hardware, "Rush")) { + SST_type = GR_SSTTYPE_SST96; + } else if (strstr(hardware, "Voodoo2")) { + SST_type = GR_SSTTYPE_Voodoo2; + } else if (strstr(hardware, "Voodoo Banshee")) { + SST_type = GR_SSTTYPE_Banshee; + } else if (strstr(hardware, "Voodoo3")) { + SST_type = GR_SSTTYPE_Voodoo3; + } else if (strstr(hardware, "Voodoo4")) { + SST_type = GR_SSTTYPE_Voodoo4; + } else if (strstr(hardware, "Voodoo5")) { + SST_type = GR_SSTTYPE_Voodoo5; + } + // 2Mb Texture boundary + voodoo.has_2mb_tex_boundary = (SST_type < GR_SSTTYPE_Banshee) && !evoodoo; + // use UMA if available + voodoo.tex_UMA = FALSE; + //* + if (strstr(extensions, " TEXUMA ")) { + // we get better texture cache hits with UMA on + grEnable(GR_TEXTURE_UMA_EXT); + voodoo.tex_UMA = TRUE; + LOG ("Using TEXUMA extension.\n"); + } + //*/ + + wxUint32 res_data = settings.res_data; + char strWrapperFullScreenResolutionExt[] = "grWrapperFullScreenResolutionExt"; + if (ev_fullscreen) + { + GRWRAPPERFULLSCREENRESOLUTIONEXT grWrapperFullScreenResolutionExt = + (GRWRAPPERFULLSCREENRESOLUTIONEXT)grGetProcAddress(strWrapperFullScreenResolutionExt); + if (grWrapperFullScreenResolutionExt) { + wxUint32 _width, _height = 0; + settings.res_data = grWrapperFullScreenResolutionExt(&_width, &_height); + settings.scr_res_x = settings.res_x = _width; + settings.scr_res_y = settings.res_y = _height; + } + res_data = settings.res_data; + } + else if (evoodoo) + { + GRWRAPPERFULLSCREENRESOLUTIONEXT grWrapperFullScreenResolutionExt = + (GRWRAPPERFULLSCREENRESOLUTIONEXT)grGetProcAddress(strWrapperFullScreenResolutionExt); + if (grWrapperFullScreenResolutionExt != NULL) + { + settings.res_data = settings.res_data_org; + settings.scr_res_x = settings.res_x = resolutions[settings.res_data][0]; + settings.scr_res_y = settings.res_y = resolutions[settings.res_data][1]; + } + res_data = settings.res_data | 0x80000000; + } + + gfx_context = 0; + + // Select the window + + if (fb_hwfbe_enabled) + { + char strSstWinOpenExt[] ="grSstWinOpenExt"; + GRWINOPENEXT grSstWinOpenExt = (GRWINOPENEXT)grGetProcAddress(strSstWinOpenExt); + if (grSstWinOpenExt) + gfx_context = grSstWinOpenExt (wxPtrToUInt(gfx.hWnd), + res_data, + GR_REFRESH_60Hz, + GR_COLORFORMAT_RGBA, + GR_ORIGIN_UPPER_LEFT, + fb_emulation_enabled?GR_PIXFMT_RGB_565:GR_PIXFMT_ARGB_8888, //32b color is not compatible with fb emulation + 2, // Double-buffering + 1); // 1 auxillary buffer + } + if (!gfx_context) + gfx_context = grSstWinOpen (wxPtrToUInt(gfx.hWnd), + res_data, + GR_REFRESH_60Hz, + GR_COLORFORMAT_RGBA, + GR_ORIGIN_UPPER_LEFT, + 2, // Double-buffering + 1); // 1 auxillary buffer + + if (!gfx_context) + { + wxMessageBox(_T("Error setting display mode"), _T("Error"), wxOK|wxICON_EXCLAMATION); + // grSstWinClose (gfx_context); + grGlideShutdown (); + return FALSE; + } + + fullscreen = TRUE; + to_fullscreen = FALSE; + +#ifdef __WINDOWS__ + if (ev_fullscreen) + { + if (gfx.hStatusBar) + ShowWindow( gfx.hStatusBar, SW_HIDE ); + ShowCursor( FALSE ); + } +#endif + + // get the # of TMUs available + grGet (GR_NUM_TMU, 4, (FxI32*)&voodoo.num_tmu); + // get maximal texture size + grGet (GR_MAX_TEXTURE_SIZE, 4, (FxI32*)&voodoo.max_tex_size); + voodoo.sup_large_tex = (voodoo.max_tex_size > 256 && !(settings.hacks & hack_PPL)); + + //num_tmu = 1; + if (voodoo.tex_UMA) + { + GetTexAddr = GetTexAddrUMA; + voodoo.tex_min_addr[0] = voodoo.tex_min_addr[1] = grTexMinAddress(GR_TMU0); + voodoo.tex_max_addr[0] = voodoo.tex_max_addr[1] = grTexMaxAddress(GR_TMU0); + } + else + { + GetTexAddr = GetTexAddrNonUMA; + voodoo.tex_min_addr[0] = grTexMinAddress(GR_TMU0); + voodoo.tex_min_addr[1] = grTexMinAddress(GR_TMU1); + voodoo.tex_max_addr[0] = grTexMaxAddress(GR_TMU0); + voodoo.tex_max_addr[1] = grTexMaxAddress(GR_TMU1); + } + + if (strstr (extensions, "TEXMIRROR") && !(settings.hacks&hack_Zelda)) //zelda's trees suffer from hardware mirroring + voodoo.sup_mirroring = 1; + else + voodoo.sup_mirroring = 0; + + if (strstr (extensions, "TEXFMT")) //VSA100 texture format extension + voodoo.sup_32bit_tex = TRUE; + else + voodoo.sup_32bit_tex = FALSE; + + voodoo.gamma_correction = 0; + if (strstr(extensions, "GETGAMMA")) + grGet(GR_GAMMA_TABLE_ENTRIES, sizeof(voodoo.gamma_table_size), &voodoo.gamma_table_size); + + if (fb_hwfbe_enabled) + { + if (char * extstr = (char*)strstr(extensions, "TEXTUREBUFFER")) + { + if (!strncmp(extstr, "TEXTUREBUFFER", 13)) + { + char strTextureBufferExt[] = "grTextureBufferExt"; + grTextureBufferExt = (GRTEXBUFFEREXT) grGetProcAddress(strTextureBufferExt); + char strTextureAuxBufferExt[] = "grTextureAuxBufferExt"; + grTextureAuxBufferExt = (GRTEXBUFFEREXT) grGetProcAddress(strTextureAuxBufferExt); + char strAuxBufferExt[] = "grAuxBufferExt"; + grAuxBufferExt = (GRAUXBUFFEREXT) grGetProcAddress(strAuxBufferExt); + } + } + else + settings.frame_buffer &= ~fb_hwfbe; + } + else + grTextureBufferExt = 0; + +#ifdef __WINDOWS__ + wxDynamicLibrary glidelib(_T("glide3x")); + if (glidelib.IsLoaded()) + { + if (glidelib.HasSymbol(_T("_grStippleMode@4"))) + grStippleModeExt = (GRSTIPPLE)glidelib.GetSymbol(_T("_grStippleMode@4")); + if (glidelib.HasSymbol(_T("_grStipplePattern@4"))) + grStipplePatternExt = (GRSTIPPLE)glidelib.GetSymbol(_T("_grStipplePattern@4")); + } +#else + grStippleModeExt = (GRSTIPPLE)grStippleMode; + grStipplePatternExt = (GRSTIPPLE)grStipplePattern; +#endif + + if (grStipplePatternExt) + grStipplePatternExt(settings.stipple_pattern); + + char strKeyPressedExt[] = "grKeyPressedExt"; + grKeyPressed = (FxBool (FX_CALL *)(FxU32))grGetProcAddress (strKeyPressedExt); + + InitCombine(); + +#ifdef SIMULATE_VOODOO1 + voodoo.num_tmu = 1; + voodoo.sup_mirroring = 0; +#endif + +#ifdef SIMULATE_BANSHEE + voodoo.num_tmu = 1; + voodoo.sup_mirroring = 1; +#endif + + grCoordinateSpace (GR_WINDOW_COORDS); + grVertexLayout (GR_PARAM_XY, offsetof(VERTEX,x), GR_PARAM_ENABLE); + grVertexLayout (GR_PARAM_Q, offsetof(VERTEX,q), GR_PARAM_ENABLE); + grVertexLayout (GR_PARAM_Z, offsetof(VERTEX,z), GR_PARAM_ENABLE); + grVertexLayout (GR_PARAM_ST0, offsetof(VERTEX,coord[0]), GR_PARAM_ENABLE); + grVertexLayout (GR_PARAM_ST1, offsetof(VERTEX,coord[2]), GR_PARAM_ENABLE); + grVertexLayout (GR_PARAM_PARGB, offsetof(VERTEX,b), GR_PARAM_ENABLE); + + grCullMode(GR_CULL_NEGATIVE); + + if (settings.fog) //"FOGCOORD" extension + { + if (strstr (extensions, "FOGCOORD")) + { + GrFog_t fog_t[64]; + guFogGenerateLinear (fog_t, 0.0f, 255.0f);//(float)rdp.fog_multiplier + (float)rdp.fog_offset);//256.0f); + + for (int i = 63; i > 0; i--) + { + if (fog_t[i] - fog_t[i-1] > 63) + { + fog_t[i-1] = fog_t[i] - 63; + } + } + fog_t[0] = 0; + // for (int f = 0; f < 64; f++) + // { + // FRDP("fog[%d]=%d->%f\n", f, fog_t[f], guFogTableIndexToW(f)); + // } + grFogTable (fog_t); + grVertexLayout (GR_PARAM_FOG_EXT, offsetof(VERTEX,f), GR_PARAM_ENABLE); + } + else //not supported + settings.fog = FALSE; + } + + grDepthBufferMode (GR_DEPTHBUFFER_ZBUFFER); + grDepthBufferFunction(GR_CMP_LESS); + grDepthMask(FXTRUE); + + settings.res_x = settings.scr_res_x; + settings.res_y = settings.scr_res_y; + ChangeSize (); + + guLoadTextures (); + ClearCache (); + + grCullMode (GR_CULL_DISABLE); + grDepthBufferMode (GR_DEPTHBUFFER_ZBUFFER); + grDepthBufferFunction (GR_CMP_ALWAYS); + grRenderBuffer(GR_BUFFER_BACKBUFFER); + grColorMask (FXTRUE, FXTRUE); + grDepthMask (FXTRUE); + grBufferClear (0, 0, 0xFFFF); + grBufferSwap (0); + grBufferClear (0, 0, 0xFFFF); + grDepthMask (FXFALSE); + grTexFilterMode (0, GR_TEXTUREFILTER_BILINEAR, GR_TEXTUREFILTER_BILINEAR); + grTexFilterMode (1, GR_TEXTUREFILTER_BILINEAR, GR_TEXTUREFILTER_BILINEAR); + grTexClampMode (0, GR_TEXTURECLAMP_CLAMP, GR_TEXTURECLAMP_CLAMP); + grTexClampMode (1, GR_TEXTURECLAMP_CLAMP, GR_TEXTURECLAMP_CLAMP); + grClipWindow (0, 0, settings.scr_res_x, settings.scr_res_y); + rdp.update |= UPDATE_SCISSOR | UPDATE_COMBINE | UPDATE_ZBUF_ENABLED | UPDATE_CULL_MODE; + +#ifdef TEXTURE_FILTER // Hiroshi Morii + if (!settings.ghq_use) + { + settings.ghq_use = settings.ghq_fltr || settings.ghq_enht /*|| settings.ghq_cmpr*/ || settings.ghq_hirs; + if (settings.ghq_use) + { + /* Plugin path */ + int options = texfltr[settings.ghq_fltr]|texenht[settings.ghq_enht]|texcmpr[settings.ghq_cmpr]|texhirs[settings.ghq_hirs]; + if (settings.ghq_enht_cmpr) + options |= COMPRESS_TEX; + if (settings.ghq_hirs_cmpr) + options |= COMPRESS_HIRESTEX; + // if (settings.ghq_enht_tile) + // options |= TILE_TEX; + if (settings.ghq_hirs_tile) + options |= TILE_HIRESTEX; + if (settings.ghq_enht_f16bpp) + options |= FORCE16BPP_TEX; + if (settings.ghq_hirs_f16bpp) + options |= FORCE16BPP_HIRESTEX; + if (settings.ghq_enht_gz) + options |= GZ_TEXCACHE; + if (settings.ghq_hirs_gz) + options |= GZ_HIRESTEXCACHE; + if (settings.ghq_cache_save) + options |= (DUMP_TEXCACHE|DUMP_HIRESTEXCACHE); + if (settings.ghq_hirs_let_texartists_fly) + options |= LET_TEXARTISTS_FLY; + if (settings.ghq_hirs_dump) + options |= DUMP_TEX; + + ghq_dmptex_toggle_key = 0; + + settings.ghq_use = (int)ext_ghq_init(voodoo.max_tex_size, // max texture width supported by hardware + voodoo.max_tex_size, // max texture height supported by hardware + voodoo.sup_32bit_tex?32:16, // max texture bpp supported by hardware + options, + settings.ghq_cache_size * 1024*1024, // cache texture to system memory + pluginPath.wchar_str(), // plugin path + rdp.RomName.wchar_str(), // name of ROM. must be no longer than 256 characters + DisplayLoadProgress); + } + } + if (settings.ghq_use && strstr (extensions, "TEXMIRROR")) + voodoo.sup_mirroring = 1; +#endif + + return TRUE; +} + +void ReleaseGfx () +{ + LOG("ReleaseGfx ()\n"); + + // Restore gamma settings + if (voodoo.gamma_correction) + { + if (voodoo.gamma_table_r) + grLoadGammaTable(voodoo.gamma_table_size, voodoo.gamma_table_r, voodoo.gamma_table_g, voodoo.gamma_table_b); + else + guGammaCorrectionRGB(1.3f, 1.3f, 1.3f); //1.3f is default 3dfx gamma for everything but desktop + voodoo.gamma_correction = 0; + } + + // Release graphics + grSstWinClose (gfx_context); + + // Shutdown glide + grGlideShutdown(); + + fullscreen = FALSE; + rdp.window_changed = TRUE; +} + +// +// DllMain - called when the DLL is loaded, use this to get the DLL's instance +// +class wxDLLApp : public wxApp +{ +public: + virtual bool OnInit(); +}; + +IMPLEMENT_APP_NO_MAIN(wxDLLApp) + +bool wxDLLApp::OnInit() +{ + if (mutexProcessDList == NULL) + mutexProcessDList = new wxMutex(wxMUTEX_DEFAULT); + wxImage::AddHandler(new wxPNGHandler); + wxImage::AddHandler(new wxJPEGHandler); + PluginPath(); + return true; +} + +#ifndef __WINDOWS__ +int __attribute__ ((constructor)) DllLoad(void); +int __attribute__ ((destructor)) DllUnload(void); +#endif + +// Called when the library is loaded and before dlopen() returns +int DllLoad(void) +{ + int argc = 0; + char **argv = NULL; + wxEntryStart(argc, argv); + if (wxTheApp) + return wxTheApp->CallOnInit() ? TRUE : FALSE; + return 0; +} + +// Called when the library is unloaded and before dlclose() returns +int DllUnload(void) +{ + if ( wxTheApp ) + wxTheApp->OnExit(); + wxEntryCleanup(); + return TRUE; +} + +#ifdef __WINDOWS__ +extern "C" int WINAPI DllMain (HINSTANCE hinstDLL, + wxUint32 fdwReason, + LPVOID lpReserved) +{ + sprintf (out_buf, "DllMain (%08lx - %d)\n", hinstDLL, fdwReason); + LOG (out_buf); + + if (fdwReason == DLL_PROCESS_ATTACH) + { + wxSetInstance(hinstDLL); + return DllLoad(); + } + else if (fdwReason == DLL_PROCESS_DETACH) + { + if (GFXWindow != NULL) + GFXWindow->SetHWND(NULL); + return DllUnload(); + } + return TRUE; +} +#endif + +void CALL ReadScreen(void **dest, int *width, int *height) +{ + *width = settings.res_x; + *height = settings.res_y; + wxUint8 * buff = (wxUint8*)malloc(settings.res_x * settings.res_y * 3); + wxUint8 * line = buff; + *dest = (void*)buff; + + if (!fullscreen) + { + for (wxUint32 y=0; y> 16) & 0xFF); + g = (wxUint8)((col >> 8) & 0xFF); + b = (wxUint8)(col & 0xFF); + line[x*3] = b; + line[x*3+1] = g; + line[x*3+2] = r; + } + line += settings.res_x * 3; + offset_src -= info.strideInBytes; + } + } + else + { + wxUint16 col; + for (wxUint32 y=0; y> 11) / 31.0f * 255.0f); + g = (wxUint8)((float)((col >> 5) & 0x3F) / 63.0f * 255.0f); + b = (wxUint8)((float)(col & 0x1F) / 31.0f * 255.0f); + line[x*3] = b; + line[x*3+1] = g; + line[x*3+2] = r; + } + line += settings.res_x * 3; + offset_src -= info.strideInBytes; + } + } + // Unlock the frontbuffer + grLfbUnlock (GR_LFB_READ_ONLY, GR_BUFFER_FRONTBUFFER); + } + LOG ("ReadScreen. Success.\n"); +} + +/****************************************************************** +Function: CaptureScreen +Purpose: This function dumps the current frame to a file +input: pointer to the directory to save the file to +output: none +*******************************************************************/ +EXPORT void CALL CaptureScreen ( char * Directory ) +{ + capture_screen = 1; + capture_path = wxString::FromAscii(Directory); +} + +/****************************************************************** +Function: ChangeWindow +Purpose: to change the window between fullscreen and window +mode. If the window was in fullscreen this should +change the screen to window mode and vice vesa. +input: none +output: none +*******************************************************************/ +EXPORT void CALL ChangeWindow (void) +{ + LOG ("ChangeWindow()\n"); + + if (evoodoo) + { + if (!ev_fullscreen) + { + to_fullscreen = TRUE; + ev_fullscreen = TRUE; +#ifdef __WINDOWS__ + if (gfx.hStatusBar) + ShowWindow( gfx.hStatusBar, SW_HIDE ); + ShowCursor( FALSE ); +#endif + } + else + { + ev_fullscreen = FALSE; + InitGfx (); +#ifdef __WINDOWS__ + ShowCursor( TRUE ); + if (gfx.hStatusBar) + ShowWindow( gfx.hStatusBar, SW_SHOW ); + SetWindowLong (gfx.hWnd, GWL_WNDPROC, (long)oldWndProc); +#endif + } + } + else + { + // Go to fullscreen at next dlist + // This is for compatibility with 1964, which reloads the plugin + // when switching to fullscreen + if (!fullscreen) + { + to_fullscreen = TRUE; +#ifdef __WINDOWS__ + if (gfx.hStatusBar) + ShowWindow( gfx.hStatusBar, SW_HIDE ); + ShowCursor( FALSE ); +#endif + } + else + { + ReleaseGfx (); +#ifdef __WINDOWS__ + ShowCursor( TRUE ); + if (gfx.hStatusBar) + ShowWindow( gfx.hStatusBar, SW_SHOW ); + // SetWindowLong fixes the following Windows XP Banshee issues: + // 1964 crash error when loading another rom. + // All N64 emu's minimize, restore crashes. + SetWindowLong (gfx.hWnd, GWL_WNDPROC, (long)oldWndProc); +#endif + } + } +} + +/****************************************************************** +Function: CloseDLL +Purpose: This function is called when the emulator is closing +down allowing the dll to de-initialise. +input: none +output: none +*******************************************************************/ +void CALL CloseDLL (void) +{ + LOG ("CloseDLL ()\n"); + + // re-set the old window proc +#ifdef WINPROC_OVERRIDE + SetWindowLong (gfx.hWnd, GWL_WNDPROC, (long)oldWndProc); +#endif + +#ifdef ALTTAB_FIX + if (hhkLowLevelKybd) + { + UnhookWindowsHookEx(hhkLowLevelKybd); + hhkLowLevelKybd = 0; + } +#endif + + //CLOSELOG (); + +#ifdef TEXTURE_FILTER // Hiroshi Morii + if (settings.ghq_use) + { + ext_ghq_shutdown(); + settings.ghq_use = 0; + } +#endif + if (fullscreen) + ReleaseGfx (); + ZLUT_release(); + ClearCache (); + delete[] voodoo.gamma_table_r; + voodoo.gamma_table_r = 0; + delete[] voodoo.gamma_table_g; + voodoo.gamma_table_g = 0; + delete[] voodoo.gamma_table_b; + voodoo.gamma_table_b = 0; +} + +/****************************************************************** +Function: DllTest +Purpose: This function is optional function that is provided +to allow the user to test the dll +input: a handle to the window that calls this function +output: none +*******************************************************************/ +void CALL DllTest ( HWND hParent ) +{ +} + +/****************************************************************** +Function: DrawScreen +Purpose: This function is called when the emulator receives a +WM_PAINT message. This allows the gfx to fit in when +it is being used in the desktop. +input: none +output: none +*******************************************************************/ +void CALL DrawScreen (void) +{ + LOG ("DrawScreen ()\n"); +} + +/****************************************************************** +Function: GetDllInfo +Purpose: This function allows the emulator to gather information +about the dll by filling in the PluginInfo structure. +input: a pointer to a PLUGIN_INFO stucture that needs to be +filled by the function. (see def above) +output: none +*******************************************************************/ +void CALL GetDllInfo ( PLUGIN_INFO * PluginInfo ) +{ + LOG ("GetDllInfo ()\n"); + PluginInfo->Version = 0x0103; // Set to 0x0103 + PluginInfo->Type = PLUGIN_TYPE_GFX; // Set to PLUGIN_TYPE_GFX + sprintf (PluginInfo->Name, "Glide64 "G64_VERSION RELTIME); // Name of the DLL + + // If DLL supports memory these memory options then set them to TRUE or FALSE + // if it does not support it + PluginInfo->NormalMemory = TRUE; // a normal wxUint8 array + PluginInfo->MemoryBswaped = TRUE; // a normal wxUint8 array where the memory has been pre + // bswap on a dword (32 bits) boundry +} + +/****************************************************************** +Function: InitiateGFX +Purpose: This function is called when the DLL is started to give +information from the emulator that the n64 graphics +uses. This is not called from the emulation thread. +Input: Gfx_Info is passed to this function which is defined +above. +Output: TRUE on success +FALSE on failure to initialise + +** note on interrupts **: +To generate an interrupt set the appropriate bit in MI_INTR_REG +and then call the function CheckInterrupts to tell the emulator +that there is a waiting interrupt. +*******************************************************************/ + +int CALL InitiateGFX (GFX_INFO Gfx_Info) +{ + LOG ("InitiateGFX (*)\n"); + voodoo.num_tmu = 2; + + // Assume scale of 1 for debug purposes + rdp.scale_x = 1.0f; + rdp.scale_y = 1.0f; + + memset (&settings, 0, sizeof(SETTINGS)); + ReadSettings (); + char name[21] = "DEFAULT"; + ReadSpecialSettings (name); + settings.res_data_org = settings.res_data; + +#ifdef FPS + fps_last = wxDateTime::UNow(); +#endif + + debug_init (); // Initialize debugger + + gfx = Gfx_Info; +#ifdef __WINDOWS__ + if (GFXWindow == NULL) + GFXWindow = new wxWindow(); + GFXWindow->SetHWND(gfx.hWnd); +#endif + +#ifdef WINPROC_OVERRIDE + // [H.Morii] inject our own winproc so that "alt-enter to fullscreen" + // message is shown when the emulator window is activated. + WNDPROC curWndProc = (WNDPROC)GetWindowLong(gfx.hWnd, GWL_WNDPROC); + if (curWndProc && curWndProc != (WNDPROC)WndProc) { + oldWndProc = (WNDPROC)SetWindowLong (gfx.hWnd, GWL_WNDPROC, (long)WndProc); + } +#endif + + util_init (); + math_init (); + TexCacheInit (); + CRC_BuildTable(); + CountCombine(); + if (fb_depth_render_enabled) + ZLUT_init(); + + char strConfigWrapperExt[] = "grConfigWrapperExt"; + GRCONFIGWRAPPEREXT grConfigWrapperExt = (GRCONFIGWRAPPEREXT)grGetProcAddress(strConfigWrapperExt); + if (grConfigWrapperExt) + grConfigWrapperExt(settings.wrpResolution, settings.wrpVRAM * 1024 * 1024, settings.wrpFBO, settings.wrpAnisotropic); + + grGlideInit (); + grSstSelect (0); + const char *extensions = grGetString (GR_EXTENSION); + grGlideShutdown (); + if (strstr (extensions, "EVOODOO")) + { + evoodoo = 1; + voodoo.has_2mb_tex_boundary = 0; + } + else { + evoodoo = 0; + voodoo.has_2mb_tex_boundary = 1; + } + + return TRUE; +} + +/****************************************************************** +Function: MoveScreen +Purpose: This function is called in response to the emulator +receiving a WM_MOVE passing the xpos and ypos passed +from that message. +input: xpos - the x-coordinate of the upper-left corner of the +client area of the window. +ypos - y-coordinate of the upper-left corner of the +client area of the window. +output: none +*******************************************************************/ +void CALL MoveScreen (int xpos, int ypos) +{ + LOG ("MoveScreen (" << xpos << ", " << ypos << ")\n"); + rdp.window_changed = TRUE; +} + +/****************************************************************** +Function: RomClosed +Purpose: This function is called when a rom is closed. +input: none +output: none +*******************************************************************/ +void CALL RomClosed (void) +{ + LOG ("RomClosed ()\n"); + + CLOSE_RDP_LOG (); + CLOSE_RDP_E_LOG (); + rdp.window_changed = TRUE; + romopen = FALSE; + if (fullscreen && evoodoo) + ReleaseGfx (); +} + +static void CheckDRAMSize() +{ + wxUint32 test; + GLIDE64_TRY + { + test = gfx.RDRAM[0x007FFFFF] + 1; + } + GLIDE64_CATCH + { + test = 0; + } + if (test) + BMASK = 0x7FFFFF; + else + BMASK = WMASK; +#ifdef LOGGING + sprintf (out_buf, "Detected RDRAM size: %08lx\n", BMASK); + LOG (out_buf); +#endif +} + +/****************************************************************** +Function: RomOpen +Purpose: This function is called when a rom is open. (from the +emulation thread) +input: none +output: none +*******************************************************************/ +void CALL RomOpen (void) +{ + LOG ("RomOpen ()\n"); + no_dlist = true; + romopen = TRUE; + ucode_error_report = TRUE; // allowed to report ucode errors + rdp_reset (); + + // Get the country code & translate to NTSC(0) or PAL(1) + wxUint16 code = ((wxUint16*)gfx.HEADER)[0x1F^1]; + + if (code == 0x4400) region = 1; // Germany (PAL) + if (code == 0x4500) region = 0; // USA (NTSC) + if (code == 0x4A00) region = 0; // Japan (NTSC) + if (code == 0x5000) region = 1; // Europe (PAL) + if (code == 0x5500) region = 0; // Australia (NTSC) + + char name[21] = "DEFAULT"; + ReadSpecialSettings (name); + + // get the name of the ROM + for (int i=0; i<20; i++) + name[i] = gfx.HEADER[(32+i)^3]; + name[20] = 0; + + // remove all trailing spaces + while (name[strlen(name)-1] == ' ') + name[strlen(name)-1] = 0; + + wxString strRomName = wxString::FromAscii(name); + if (settings.ghq_use && strRomName != rdp.RomName) + { + ext_ghq_shutdown(); + settings.ghq_use = 0; + } + rdp.RomName = strRomName; + ReadSpecialSettings (name); + ClearCache (); + + CheckDRAMSize(); + + OPEN_RDP_LOG (); + OPEN_RDP_E_LOG (); + + + // ** EVOODOO EXTENSIONS ** + if (!fullscreen) + { + grGlideInit (); + grSstSelect (0); + } + const char *extensions = grGetString (GR_EXTENSION); + if (!fullscreen) + { + grGlideShutdown (); + + if (strstr (extensions, "EVOODOO")) + evoodoo = 1; + else + evoodoo = 0; + + if (evoodoo) + InitGfx (); + } + + if (strstr (extensions, "ROMNAME")) + { + char strSetRomName[] = "grSetRomName"; + void (FX_CALL *grSetRomName)(char*); + grSetRomName = (void (FX_CALL *)(char*))grGetProcAddress (strSetRomName); + grSetRomName (name); + } + // ** +} + +/****************************************************************** +Function: ShowCFB +Purpose: Useally once Dlists are started being displayed, cfb is +ignored. This function tells the dll to start displaying +them again. +input: none +output: none +*******************************************************************/ +bool no_dlist = true; +void CALL ShowCFB (void) +{ + no_dlist = true; + LOG ("ShowCFB ()\n"); +} + +void drawViRegBG() +{ + LRDP("drawViRegBG\n"); + const wxUint32 VIwidth = *gfx.VI_WIDTH_REG; + FB_TO_SCREEN_INFO fb_info; + fb_info.width = VIwidth; + fb_info.height = (wxUint32)rdp.vi_height; + if (fb_info.height == 0) + { + LRDP("Image height = 0 - skipping\n"); + return; + } + fb_info.ul_x = 0; + + fb_info.lr_x = VIwidth - 1; + // fb_info.lr_x = (wxUint32)rdp.vi_width - 1; + fb_info.ul_y = 0; + fb_info.lr_y = fb_info.height - 1; + fb_info.opaque = 1; + fb_info.addr = *gfx.VI_ORIGIN_REG; + fb_info.size = *gfx.VI_STATUS_REG & 3; + rdp.last_bg = fb_info.addr; + + bool drawn = DrawFrameBufferToScreen(fb_info); + if (settings.hacks&hack_Lego && drawn) + { + rdp.updatescreen = 1; + newSwapBuffers (); + DrawFrameBufferToScreen(fb_info); + } +} + +void drawNoFullscreenMessage(); + +static void DrawFrameBuffer () +{ + if (!fullscreen) + { + drawNoFullscreenMessage(); + } + if (to_fullscreen) + GoToFullScreen(); + + if (fullscreen) + { + grDepthMask (FXTRUE); + grColorMask (FXTRUE, FXTRUE); + grBufferClear (0, 0, 0xFFFF); + drawViRegBG(); + } +} + +/****************************************************************** +Function: UpdateScreen +Purpose: This function is called in response to a vsync of the +screen were the VI bit in MI_INTR_REG has already been +set +input: none +output: none +*******************************************************************/ +wxUint32 update_screen_count = 0; +void CALL UpdateScreen (void) +{ +#ifdef LOG_KEY + if (CheckKeyPressed(G64_VK_SPACE, 0x0001)) + { + LOG ("KEY!!!\n"); + } +#endif + char out_buf[128]; + sprintf (out_buf, "UpdateScreen (). Origin: %08lx, Old origin: %08lx, width: %d\n", *gfx.VI_ORIGIN_REG, rdp.vi_org_reg, *gfx.VI_WIDTH_REG); + LOG (out_buf); + LRDP(out_buf); + + wxUint32 width = (*gfx.VI_WIDTH_REG) << 1; + if (fullscreen && (*gfx.VI_ORIGIN_REG > width)) + update_screen_count++; + +#ifdef FPS + // vertical interrupt has occurred, increment counter + vi_count ++; + + // Check frames per second + fps_next = wxDateTime::UNow(); + wxTimeSpan difference = fps_next - fps_last; + double diff_secs = difference.GetMilliseconds().ToDouble() / 1000.0; + if (diff_secs > 0.5f) + { + fps = (float)(fps_count / diff_secs); + vi = (float)(vi_count / diff_secs); + ntsc_percent = vi / 0.6f; + pal_percent = vi / 0.5f; + fps_last = fps_next; + fps_count = 0; + vi_count = 0; + } +#endif + //* + wxUint32 limit = (settings.hacks&hack_Lego) ? 15 : 30; + if ((settings.frame_buffer&fb_cpu_write_hack) && (update_screen_count > limit) && (rdp.last_bg == 0)) + { + LRDP("DirectCPUWrite hack!\n"); + update_screen_count = 0; + no_dlist = true; + ClearCache (); + UpdateScreen(); + return; + } + //*/ + //* + if( no_dlist ) + { + if( *gfx.VI_ORIGIN_REG > width ) + { + ChangeSize (); + LRDP("ChangeSize done\n"); + DrawFrameBuffer(); + LRDP("DrawFrameBuffer done\n"); + rdp.updatescreen = 1; + newSwapBuffers (); + } + return; + } + //*/ + if (settings.swapmode == 0) + newSwapBuffers (); +} + +static void DrawWholeFrameBufferToScreen() +{ + static wxUint32 toScreenCI = 0; + if (rdp.ci_width < 200) + return; + if (rdp.cimg == toScreenCI) + return; + toScreenCI = rdp.cimg; + FB_TO_SCREEN_INFO fb_info; + fb_info.addr = rdp.cimg; + fb_info.size = rdp.ci_size; + fb_info.width = rdp.ci_width; + fb_info.height = rdp.ci_height; + if (fb_info.height == 0) + return; + fb_info.ul_x = 0; + fb_info.lr_x = rdp.ci_width-1; + fb_info.ul_y = 0; + fb_info.lr_y = rdp.ci_height-1; + fb_info.opaque = 0; + DrawFrameBufferToScreen(fb_info); + if (!(settings.frame_buffer & fb_ref)) + memset(gfx.RDRAM+rdp.cimg, 0, (rdp.ci_width*rdp.ci_height)<>1); +} + +static void GetGammaTable() +{ + char strGetGammaTableExt[] = "grGetGammaTableExt"; + void (FX_CALL *grGetGammaTableExt)(FxU32, FxU32*, FxU32*, FxU32*) = + (void (FX_CALL *)(FxU32, FxU32*, FxU32*, FxU32*))grGetProcAddress(strGetGammaTableExt); + if (grGetGammaTableExt) + { + voodoo.gamma_table_r = new FxU32[voodoo.gamma_table_size]; + voodoo.gamma_table_g = new FxU32[voodoo.gamma_table_size]; + voodoo.gamma_table_b = new FxU32[voodoo.gamma_table_size]; + grGetGammaTableExt(voodoo.gamma_table_size, voodoo.gamma_table_r, voodoo.gamma_table_g, voodoo.gamma_table_b); + } +} + +wxUint32 curframe = 0; +void newSwapBuffers() +{ + if (!rdp.updatescreen) + return; + + rdp.updatescreen = 0; + + LRDP("swapped\n"); + + // Allow access to the whole screen + if (fullscreen) + { + rdp.update |= UPDATE_SCISSOR | UPDATE_COMBINE | UPDATE_ZBUF_ENABLED | UPDATE_CULL_MODE; + grClipWindow (0, 0, settings.scr_res_x, settings.scr_res_y); + grDepthBufferFunction (GR_CMP_ALWAYS); + grDepthMask (FXFALSE); + grCullMode (GR_CULL_DISABLE); + + if ((settings.show_fps & 0xF) || settings.clock) + set_message_combiner (); +#ifdef FPS + float y = 0;//(float)settings.res_y; + if (settings.show_fps & 0x0F) + { + if (settings.show_fps & 4) + { + if (region) // PAL + output (0, y, 1, "%d%% ", (int)pal_percent); + else + output (0, y, 1, "%d%% ", (int)ntsc_percent); + y += 16; + } + if (settings.show_fps & 2) + { + output (0, y, 1, "VI/s: %.02f ", vi); + y += 16; + } + if (settings.show_fps & 1) + output (0, y, 1, "FPS: %.02f ", fps); + } +#endif + + if (settings.clock) + { + if (settings.clock_24_hr) + { + output (956.0f, 0, 1, (char*)wxDateTime::Now().Format(wxT("%H:%M:%S")).char_str(), 0); + } + else + { + output (930.0f, 0, 1, (char*)wxDateTime::Now().Format(wxT("%I:%M:%S %p")).char_str(), 0); + } + } + //hotkeys + if (CheckKeyPressed(G64_VK_BACK, 0x0001)) + { + hotkey_info.hk_filtering = 100; + if (settings.filtering < 2) + settings.filtering++; + else + settings.filtering = 0; + } + if ((abs((int)(frame_count - curframe)) > 3 ) && CheckKeyPressed(G64_VK_ALT, 0x8000)) //alt + + { + if (CheckKeyPressed(G64_VK_B, 0x8000)) //b + { + hotkey_info.hk_motionblur = 100; + hotkey_info.hk_ref = 0; + curframe = frame_count; + settings.frame_buffer ^= fb_motionblur; + } + else if (CheckKeyPressed(G64_VK_V, 0x8000)) //v + { + hotkey_info.hk_ref = 100; + hotkey_info.hk_motionblur = 0; + curframe = frame_count; + settings.frame_buffer ^= fb_ref; + } + } + if (settings.buff_clear && (hotkey_info.hk_ref || hotkey_info.hk_motionblur || hotkey_info.hk_filtering)) + { + set_message_combiner (); + char buf[256]; + buf[0] = 0; + char * message = 0; + if (hotkey_info.hk_ref) + { + if (settings.frame_buffer & fb_ref) + message = strcat(buf, "FB READ ALWAYS: ON"); + else + message = strcat(buf, "FB READ ALWAYS: OFF"); + hotkey_info.hk_ref--; + } + if (hotkey_info.hk_motionblur) + { + if (settings.frame_buffer & fb_motionblur) + message = strcat(buf, " MOTION BLUR: ON"); + else + message = strcat(buf, " MOTION BLUR: OFF"); + hotkey_info.hk_motionblur--; + } + if (hotkey_info.hk_filtering) + { + switch (settings.filtering) + { + case 0: + message = strcat(buf, " FILTERING MODE: AUTOMATIC"); + break; + case 1: + message = strcat(buf, " FILTERING MODE: FORCE BILINEAR"); + break; + case 2: + message = strcat(buf, " FILTERING MODE: FORCE POINT-SAMPLED"); + break; + } + hotkey_info.hk_filtering--; + } + output (120.0f, 0.0f, 1, message, 0); + } + } + + if (capture_screen) + { + //char path[256]; + // Make the directory if it doesn't exist + if (!wxDirExists(capture_path)) + wxMkdir(capture_path); + wxString path; + wxString romName = rdp.RomName; + romName.Replace(wxT(" "), wxT("_"), true); + romName.Replace(wxT(":"), wxT(";"), true); + + for (int i=1; ; i++) + { + path = capture_path; + path += wxT("Glide64_"); + path += romName; + path += wxT("_"); + if (i < 10) + path += wxT("0"); + path << i << wxT(".") << ScreenShotFormats[settings.ssformat].extension; + if (!wxFileName::FileExists(path)) + break; + } + + const wxUint32 offset_x = (wxUint32)rdp.offset_x; + const wxUint32 offset_y = (wxUint32)rdp.offset_y; + const wxUint32 image_width = settings.scr_res_x - offset_x*2; + const wxUint32 image_height = settings.scr_res_y - offset_y*2; + + GrLfbInfo_t info; + info.size = sizeof(GrLfbInfo_t); + if (grLfbLock (GR_LFB_READ_ONLY, + GR_BUFFER_BACKBUFFER, + GR_LFBWRITEMODE_565, + GR_ORIGIN_UPPER_LEFT, + FXFALSE, + &info)) + { + wxUint8 *ssimg = (wxUint8*)malloc(image_width * image_height * 3); // will be free in wxImage destructor + int sspos = 0; + wxUint32 offset_src = info.strideInBytes * offset_y; + + // Copy the screen + if (info.writeMode == GR_LFBWRITEMODE_8888) + { + wxUint32 col; + for (wxUint32 y = 0; y < image_height; y++) + { + wxUint32 *ptr = (wxUint32*)((wxUint8*)info.lfbPtr + offset_src); + ptr += offset_x; + for (wxUint32 x = 0; x < image_width; x++) + { + col = *(ptr++); + ssimg[sspos++] = (wxUint8)((col >> 16) & 0xFF); + ssimg[sspos++] = (wxUint8)((col >> 8) & 0xFF); + ssimg[sspos++] = (wxUint8)(col & 0xFF); + } + offset_src += info.strideInBytes; + } + } + else + { + wxUint16 col; + for (wxUint32 y = 0; y < image_height; y++) + { + wxUint16 *ptr = (wxUint16*)((wxUint8*)info.lfbPtr + offset_src); + ptr += offset_x; + for (wxUint32 x = 0; x < image_width; x++) + { + col = *(ptr++); + ssimg[sspos++] = (wxUint8)((float)(col >> 11) / 31.0f * 255.0f); + ssimg[sspos++] = (wxUint8)((float)((col >> 5) & 0x3F) / 63.0f * 255.0f); + ssimg[sspos++] = (wxUint8)((float)(col & 0x1F) / 31.0f * 255.0f); + } + offset_src += info.strideInBytes; + } + } + // Unlock the backbuffer + grLfbUnlock (GR_LFB_READ_ONLY, GR_BUFFER_BACKBUFFER); + wxImage screenshot(image_width, image_height, ssimg); + screenshot.SaveFile(path, ScreenShotFormats[settings.ssformat].type); + capture_screen = 0; + } + } + + // Capture the screen if debug capture is set + if (_debugger.capture) + { + // Allocate the screen + _debugger.screen = new wxUint8 [(settings.res_x*settings.res_y) << 1]; + + // Lock the backbuffer (already rendered) + GrLfbInfo_t info; + info.size = sizeof(GrLfbInfo_t); + while (!grLfbLock (GR_LFB_READ_ONLY, + GR_BUFFER_BACKBUFFER, + GR_LFBWRITEMODE_565, + GR_ORIGIN_UPPER_LEFT, + FXFALSE, + &info)); + + wxUint32 offset_src=0, offset_dst=0; + + // Copy the screen + for (wxUint32 y=0; y> 19) & 0x1F); + g = (wxUint8)((col >> 10) & 0x3F); + b = (wxUint8)((col >> 3) & 0x1F); + dst[x] = (r<<11)|(g<<5)|b; + } + } + else + { + memcpy (_debugger.screen + offset_dst, (wxUint8*)info.lfbPtr + offset_src, settings.res_x << 1); + } + offset_dst += settings.res_x << 1; + offset_src += info.strideInBytes; + } + + // Unlock the backbuffer + grLfbUnlock (GR_LFB_READ_ONLY, GR_BUFFER_BACKBUFFER); + } + + if (fullscreen && debugging) + { + debug_keys (); + debug_cacheviewer (); + debug_mouse (); + } + + if (settings.frame_buffer & fb_read_back_to_screen) + DrawWholeFrameBufferToScreen(); + + if (fullscreen) + { + if (fb_hwfbe_enabled && !(settings.hacks&hack_RE2) && !evoodoo) + grAuxBufferExt( GR_BUFFER_AUXBUFFER ); + LOG ("BUFFER SWAPPED\n"); + grBufferSwap (settings.vsync); + fps_count ++; + if (*gfx.VI_STATUS_REG&0x08) //gamma correction is used + { + if (!voodoo.gamma_correction) + { + if (voodoo.gamma_table_size && !voodoo.gamma_table_r) + GetGammaTable(); //save initial gamma tables + guGammaCorrectionRGB(2.0f, 2.0f, 2.0f); //with gamma=2.0 gamma table is the same, as in N64 + voodoo.gamma_correction = 1; + } + } + else + { + if (voodoo.gamma_correction) + { + if (voodoo.gamma_table_r) + grLoadGammaTable(voodoo.gamma_table_size, voodoo.gamma_table_r, voodoo.gamma_table_g, voodoo.gamma_table_b); + else + guGammaCorrectionRGB(1.3f, 1.3f, 1.3f); //1.3f is default 3dfx gamma for everything but desktop + voodoo.gamma_correction = 0; + } + } + } + + if (_debugger.capture) + debug_capture (); + + if (fullscreen) + { + if (debugging || settings.wireframe || settings.buff_clear || (settings.hacks&hack_PPL && settings.ucode == 6)) + { + if (settings.hacks&hack_RE2 && fb_depth_render_enabled) + grDepthMask (FXFALSE); + else + grDepthMask (FXTRUE); + grBufferClear (0, 0, 0xFFFF); + } + /* //let the game to clear the buffers + else + { + grDepthMask (FXTRUE); + grColorMask (FXFALSE, FXFALSE); + grBufferClear (0, 0, 0xFFFF); + grColorMask (FXTRUE, FXTRUE); + } + */ + } + + if (settings.frame_buffer & fb_read_back_to_screen2) + DrawWholeFrameBufferToScreen(); + + frame_count ++; + + // Open/close debugger? + if (CheckKeyPressed(G64_VK_SCROLL, 0x0001)) + { + if (!debugging) + { + //if (settings.scr_res_x == 1024 && settings.scr_res_y == 768) + { + debugging = 1; + + // Recalculate screen size, don't resize screen + settings.res_x = (wxUint32)(settings.scr_res_x * 0.625f); + settings.res_y = (wxUint32)(settings.scr_res_y * 0.625f); + + ChangeSize (); + } + } + else + { + debugging = 0; + + settings.res_x = settings.scr_res_x; + settings.res_y = settings.scr_res_y; + + ChangeSize (); + } + } + + // Debug capture? + if (/*fullscreen && */debugging && CheckKeyPressed(G64_VK_INSERT, 0x0001)) + { + _debugger.capture = 1; + } +} + +/****************************************************************** +Function: ViStatusChanged +Purpose: This function is called to notify the dll that the +ViStatus registers value has been changed. +input: none +output: none +*******************************************************************/ +void CALL ViStatusChanged (void) +{ +} + +/****************************************************************** +Function: ViWidthChanged +Purpose: This function is called to notify the dll that the +ViWidth registers value has been changed. +input: none +output: none +*******************************************************************/ +void CALL ViWidthChanged (void) +{ +} + +#ifdef WINPROC_OVERRIDE +LRESULT CALLBACK WndProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + switch (msg) + { + case WM_ACTIVATEAPP: + if (wParam == TRUE && !fullscreen) rdp.window_changed = TRUE; + break; + case WM_PAINT: + if (!fullscreen) rdp.window_changed = TRUE; + break; + + /* case WM_DESTROY: + SetWindowLong (gfx.hWnd, GWL_WNDPROC, (long)oldWndProc); + break;*/ + } + + return CallWindowProc(oldWndProc, hwnd, msg, wParam, lParam); +} +#endif + +int CheckKeyPressed(int key, int mask) +{ +static Glide64Keys g64Keys; + if (settings.use_hotkeys == 0) + return 0; +#ifdef __WINDOWS__ + return (GetAsyncKeyState(g64Keys[key]) & mask); +#else + if (grKeyPressed) + return grKeyPressed(g64Keys[key]); +#endif + return 0; +} + + +#ifdef ALTTAB_FIX +int k_ctl=0, k_alt=0, k_del=0; + +LRESULT CALLBACK LowLevelKeyboardProc(int nCode, + WPARAM wParam, LPARAM lParam) +{ + if (!fullscreen) return CallNextHookEx(NULL, nCode, wParam, lParam); + + int TabKey = FALSE; + + PKBDLLHOOKSTRUCT p; + + if (nCode == HC_ACTION) + { + switch (wParam) { +case WM_KEYUP: case WM_SYSKEYUP: + p = (PKBDLLHOOKSTRUCT) lParam; + if (p->vkCode == 162) k_ctl = 0; + if (p->vkCode == 164) k_alt = 0; + if (p->vkCode == 46) k_del = 0; + goto do_it; + +case WM_KEYDOWN: case WM_SYSKEYDOWN: + p = (PKBDLLHOOKSTRUCT) lParam; + if (p->vkCode == 162) k_ctl = 1; + if (p->vkCode == 164) k_alt = 1; + if (p->vkCode == 46) k_del = 1; + goto do_it; + +do_it: + TabKey = + ((p->vkCode == VK_TAB) && ((p->flags & LLKHF_ALTDOWN) != 0)) || + ((p->vkCode == VK_ESCAPE) && ((p->flags & LLKHF_ALTDOWN) != 0)) || + ((p->vkCode == VK_ESCAPE) && ((GetKeyState(VK_CONTROL) & 0x8000) != 0)) || + (k_ctl && k_alt && k_del); + + break; + } + } + + if (TabKey) + { + k_ctl = 0; + k_alt = 0; + k_del = 0; + ReleaseGfx (); + } + + return CallNextHookEx(NULL, nCode, wParam, lParam); +} +#endif diff --git a/Source/Glide64/Makefile.gcc b/Source/Glide64/Makefile.gcc new file mode 100644 index 000000000..f01ebaf05 --- /dev/null +++ b/Source/Glide64/Makefile.gcc @@ -0,0 +1,189 @@ +# This MUST be processed by GNU make +# +# Glide64 Makefile +# Version: 1.0 +# +# this 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, or (at your option) +# any later version. +# +# this 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 GNU Make; see the file COPYING. If not, write to +# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +# + +# +# Available options: +# +# Environment variables: +# DEBUG=1 enable debugging checks and messages +# default = no +# +# Environment variables: +# +# Targets: +# all: build dynamic module +# clean: remove object files +# realclean: remove all generated files +# +# +# Requirements: +# +# Compiler: +# GCC 4.2 +# +# Libraries: +# glide3x - build Glitch64 first, copy the result dll to 'lib' folder +# wx-widgets 2.8 (http://www.wxwidgets.org) +# + +# +# GCC does not have SEH (structured exception handling) +# + +.PHONY: all clean realclean ostype + +OS=$(shell uname) +ifeq ($(findstring MINGW,$(OS)),MINGW) +OS := WINDOWS +endif +ifeq ($(findstring CYGWIN,$(OS)),CYGWIN) +OS=WINDOWS +endif +ifeq ($(findstring WINNT,$(OS)),WINNT) +OS=WINDOWS +endif +ifeq ($(OS),Darwin) +OS=MACOSX +endif + +ifeq ($(OS), WINDOWS) +DLLNAME = Glide64.dll +else +DLLNAME = Glide64.so +endif + +EXT_INC = ./inc +EXT_LIB = ./lib + +CC = g++ +STRIP = strip + +CFLAGS = -DBUILDING_DLL=1 -fexceptions +LDLIBS = -L"." -L"lib" `wx-config --libs` + +ifeq ($(OS), Linux) +CC += -V 4.2 +LDFLAGS = -shared -lstdc++ +CFLAGS += -D__unix__ +LDLIBS += $(EXT_LIB)/glide3x.so +endif +ifeq ($(OS), MACOSX) +LDFLAGS = -dynamiclib -lstdc++ +CFLAGS += -D__unix__ -Dmacintosh +LDLIBS += $(EXT_LIB)/glide3x.dylib +endif +ifeq ($(OS), WINDOWS) +LDFLAGS = -shared -mwindows +CFLAGS += -D__WIN32__ -DWIN32 -D_WIN32 +LDLIBS += $(EXT_LIB)/glide3x.lib +endif + +CFLAGS += -ffast-math -funroll-loops +#CFLAGS += -fexpensive-optimizations -march=k6 +CFLAGS += -I. -I$(EXT_INC) `wx-config --cppflags` + +ifdef DEBUG +CFLAGS += -g -DDEBUG +endif + +LD = g++ + +AS = nasm +ifeq ($(OS), Linux) +ASFLAGS = -O6 -felf -D__linux__ +ASM_OBJ = \ + 3dmathSIMD.o \ + FixedPoint.o \ + Texture.o +else + ifeq ($(OS), MACOSX) + ASFLAGS = -O6 -fmacho --prefix _ + ASM_OBJ = \ + 3dmathSIMD.o \ + FixedPoint.o \ + Texture.o + else + ifeq ($(OS), WINDOWS) + ASFLAGS = -O6 -fwin32 -D__WIN32__ --prefix _ + ASM_OBJ = \ + 3dmathSIMD.obj \ + FixedPoint.obj \ + Texture.obj + endif + endif +endif + +RM = rm + +SOURCES = \ + 3dmath.cpp \ + Combine.cpp \ + Config.cpp \ + CRC.cpp \ + Debugger.cpp \ + DepthBufferRender.cpp \ + Ext_TxFilter.cpp \ + FBtoScreen.cpp \ + Main.cpp \ + Keys.cpp \ + rdp.cpp \ + TexBuffer.cpp \ + TexCache.cpp \ + Util.cpp + +OBJECTS = $(SOURCES:.cpp=.o) + +.cpp.o: + $(CC) -o $@ $(CFLAGS) -c $< + +all: $(DLLNAME) + +$(DLLNAME): $(OBJECTS) $(ASM_OBJ) + $(LD) -o $@ $(LDFLAGS) $^ $(LDLIBS) +ifeq ($(OS), Linux) + $(STRIP) $@ +endif + +ifneq ($(OS), WINDOWS) +3dmathSIMD.o: 3dmathSIMD.asm + $(AS) -o $@ $(ASFLAGS) $< +FixedPoint.o: FixedPoint.asm + $(AS) -o $@ $(ASFLAGS) $< +Texture.o: Texture.asm + $(AS) -o $@ $(ASFLAGS) $< +else +3dmathSIMD.obj: 3dmathSIMD.asm + $(AS) -o $@ $(ASFLAGS) $< +FixedPoint.obj: FixedPoint.asm + $(AS) -o $@ $(ASFLAGS) $< +Texture.obj: Texture.asm + $(AS) -o $@ $(ASFLAGS) $< +endif + +clean: + -$(RM) *.o + +realclean: clean + -$(RM) $(DLLNAME) + +ostype: + echo $(OS) + +-include depend diff --git a/Source/Glide64/MiClWr16b.h b/Source/Glide64/MiClWr16b.h new file mode 100644 index 000000000..949cd3952 --- /dev/null +++ b/Source/Glide64/MiClWr16b.h @@ -0,0 +1,167 @@ +/* +* Glide64 - Glide video plugin for Nintendo 64 emulators. +* Copyright (c) 2002 Dave2001 +* Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski +* +* 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 +* 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 +*/ + +//**************************************************************** +// +// Glide64 - Glide Plugin for Nintendo 64 emulators +// Project started on December 29th, 2001 +// +// Authors: +// Dave2001, original author, founded the project in 2001, left it in 2002 +// Gugaman, joined the project in 2002, left it in 2002 +// Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002 +// Hiroshi 'KoolSmoky' Morii, joined the project in 2007 +// +//**************************************************************** +// +// To modify Glide64: +// * Write your name and (optional)email, commented by your work, so I know who did it, and so that you can find which parts you modified when it comes time to send it to me. +// * Do NOT send me the whole project or file that you modified. Take out your modified code sections, and tell me where to put them. If people sent the whole thing, I would have many different versions, but no idea how to combine them all. +// +//**************************************************************** + +extern "C" void asmMirror16bS (int tex, int start, int width, int height, int mask, int line, int full, int count); +extern "C" void asmWrap16bS (int tex, int start, int height, int mask, int line, int full, int count); +extern "C" void asmClamp16bS (int tex, int constant, int height,int line, int full, int count); + +//**************************************************************** +// 16-bit Horizontal Mirror + +void Mirror16bS (wxUint32 tex, wxUint32 mask, wxUint32 max_width, wxUint32 real_width, wxUint32 height) +{ + if (mask == 0) return; + + wxUint32 mask_width = (1 << mask); + wxUint32 mask_mask = (mask_width-1) << 1; + if (mask_width >= max_width) return; + int count = max_width - mask_width; + if (count <= 0) return; + int line_full = real_width << 1; + int line = line_full - (count << 1); + if (line < 0) return; + wxUint32 start = tex + (mask_width << 1); + asmMirror16bS (tex, start, mask_width, height, mask_mask, line, line_full, count); +} + +//**************************************************************** +// 16-bit Horizontal Wrap (like mirror) + +void Wrap16bS (wxUint32 tex, wxUint32 mask, wxUint32 max_width, wxUint32 real_width, wxUint32 height) +{ + if (mask == 0) return; + + wxUint32 mask_width = (1 << mask); + wxUint32 mask_mask = (mask_width-1) >> 1; + if (mask_width >= max_width) return; + int count = (max_width - mask_width) >> 1; + if (count <= 0) return; + int line_full = real_width << 1; + int line = line_full - (count << 2); + if (line < 0) return; + wxUint32 start = tex + (mask_width << 1); + asmWrap16bS (tex, start, height, mask_mask, line, line_full, count); +} + +//**************************************************************** +// 16-bit Horizontal Clamp + +void Clamp16bS (wxUint32 tex, wxUint32 width, wxUint32 clamp_to, wxUint32 real_width, wxUint32 real_height) +{ + if (real_width <= width) return; + + wxUint32 dest = tex + (width << 1); + wxUint32 constant = dest-2; + int count = clamp_to - width; + + int line_full = real_width << 1; + int line = width << 1; + + asmClamp16bS (dest, constant, real_height, line, line_full, count); +} + +//**************************************************************** +// 16-bit Vertical Mirror + +void Mirror16bT (wxUint32 tex, wxUint32 mask, wxUint32 max_height, wxUint32 real_width) +{ + if (mask == 0) return; + + wxUint32 mask_height = (1 << mask); + wxUint32 mask_mask = mask_height-1; + if (max_height <= mask_height) return; + int line_full = real_width << 1; + + wxUint32 dst = tex + mask_height * line_full; + + for (wxUint32 y=mask_height; y= max_width) return; + int count = max_width - mask_width; + if (count <= 0) return; + int line_full = real_width << 2; + int line = line_full - (count << 2); + if (line < 0) return; + wxUint32 start = tex + (mask_width << 2); + asmMirror32bS (tex, start, mask_width, height, mask_mask, line, line_full, count); +} + +//**************************************************************** +// 32-bit Horizontal Wrap + +void Wrap32bS (wxUint32 tex, wxUint32 mask, wxUint32 max_width, wxUint32 real_width, wxUint32 height) +{ + if (mask == 0) return; + + wxUint32 mask_width = (1 << mask); + wxUint32 mask_mask = (mask_width-1); + if (mask_width >= max_width) return; + int count = (max_width - mask_width); + if (count <= 0) return; + int line_full = real_width << 2; + int line = line_full - (count << 2); + if (line < 0) return; + wxUint32 start = tex + (mask_width << 2); + asmWrap32bS (tex, start, height, mask_mask, line, line_full, count); +} + +//**************************************************************** +// 32-bit Horizontal Clamp + +void Clamp32bS (wxUint32 tex, wxUint32 width, wxUint32 clamp_to, wxUint32 real_width, wxUint32 real_height) +{ + if (real_width <= width) return; + + wxUint32 dest = tex + (width << 2); + wxUint32 constant = dest-4; + int count = clamp_to - width; + + int line_full = real_width << 2; + int line = width << 2; + + asmClamp32bS (dest, constant, real_height, line, line_full, count); +} + +//**************************************************************** +// 32-bit Vertical Mirror + +void Mirror32bT (wxUint32 tex, wxUint32 mask, wxUint32 max_height, wxUint32 real_width) +{ + if (mask == 0) return; + + wxUint32 mask_height = (1 << mask); + wxUint32 mask_mask = mask_height-1; + if (max_height <= mask_height) return; + int line_full = real_width << 2; + + wxUint32 dst = tex + mask_height * line_full; + + for (wxUint32 y=mask_height; y= max_width) return; + int count = max_width - mask_width; + if (count <= 0) return; + int line_full = real_width; + int line = line_full - (count); + if (line < 0) return; + wxUint32 start = tex + (mask_width); + asmMirror8bS (tex, start, mask_width, height, mask_mask, line, line_full, count); +} + +//**************************************************************** +// 8-bit Horizontal Wrap (like mirror) ** UNTESTED ** + +void Wrap8bS (wxUint32 tex, wxUint32 mask, wxUint32 max_width, wxUint32 real_width, wxUint32 height) +{ + if (mask == 0) return; + + wxUint32 mask_width = (1 << mask); + wxUint32 mask_mask = (mask_width-1) >> 2; + if (mask_width >= max_width) return; + int count = (max_width - mask_width) >> 2; + if (count <= 0) return; + int line_full = real_width; + int line = line_full - (count << 2); + if (line < 0) return; + wxUint32 start = tex + (mask_width); + asmWrap8bS (tex, start, height, mask_mask, line, line_full, count); +} + +//**************************************************************** +// 8-bit Horizontal Clamp + +void Clamp8bS (wxUint32 tex, wxUint32 width, wxUint32 clamp_to, wxUint32 real_width, wxUint32 real_height) +{ + if (real_width <= width) return; + + wxUint32 dest = tex + (width); + wxUint32 constant = dest-1; + int count = clamp_to - width; + + int line_full = real_width; + int line = width; + asmClamp8bS (dest, constant, real_height, line, line_full, count); +} + +//**************************************************************** +// 8-bit Vertical Mirror + +void Mirror8bT (wxUint32 tex, wxUint32 mask, wxUint32 max_height, wxUint32 real_width) +{ + if (mask == 0) return; + + wxUint32 mask_height = (1 << mask); + wxUint32 mask_mask = mask_height-1; + if (max_height <= mask_height) return; + int line_full = real_width; + + wxUint32 dst = tex + mask_height * line_full; + + for (wxUint32 y=mask_height; y>1); + texbuf.width = cimage.width; + texbuf.height = cimage.height; + texbuf.format = cimage.format; + texbuf.size = cimage.size; + texbuf.scr_width = min(cimage.width * rdp.scale_x, settings.scr_res_x); + float height = min(rdp.vi_height,cimage.height); + if (cimage.status == ci_copy_self || (cimage.status == ci_copy && cimage.width == rdp.frame_buffers[rdp.main_ci_index].width)) + height = rdp.vi_height; + texbuf.scr_height = height * rdp.scale_y; +// texbuf.scr_height = texbuf.height * rdp.scale_y; + + wxUint16 max_size = max((wxUint16)texbuf.scr_width, (wxUint16)texbuf.scr_height); + if (max_size > voodoo.max_tex_size) //texture size is too large + return 0; + wxUint32 tex_size; + //calculate LOD + switch ((max_size-1) >> 6) + { + case 0: + texbuf.info.smallLodLog2 = texbuf.info.largeLodLog2 = GR_LOD_LOG2_64; + tex_size = 64; + break; + case 1: + texbuf.info.smallLodLog2 = texbuf.info.largeLodLog2 = GR_LOD_LOG2_128; + tex_size = 128; + break; + case 2: + case 3: + texbuf.info.smallLodLog2 = texbuf.info.largeLodLog2 = GR_LOD_LOG2_256; + tex_size = 256; + break; + case 4: + case 5: + case 6: + case 7: + texbuf.info.smallLodLog2 = texbuf.info.largeLodLog2 = GR_LOD_LOG2_512; + tex_size = 512; + break; + case 8: + case 9: + case 10: + case 11: + case 12: + case 13: + case 14: + case 15: + texbuf.info.smallLodLog2 = texbuf.info.largeLodLog2 = GR_LOD_LOG2_1024; + tex_size = 1024; + break; + default: + texbuf.info.smallLodLog2 = texbuf.info.largeLodLog2 = GR_LOD_LOG2_2048; + tex_size = 2048; + } + //calculate aspect + if (texbuf.scr_width >= texbuf.scr_height) + { + if ((texbuf.scr_width/texbuf.scr_height) >= 2) + { + texbuf.info.aspectRatioLog2 = GR_ASPECT_LOG2_2x1; + texbuf.tex_width = tex_size; + texbuf.tex_height = tex_size >> 1; + } + else + { + texbuf.info.aspectRatioLog2 = GR_ASPECT_LOG2_1x1; + texbuf.tex_width = texbuf.tex_height = tex_size; + } + } + else + { + if ((texbuf.scr_height/texbuf.scr_width) >= 2) + { + texbuf.info.aspectRatioLog2 = GR_ASPECT_LOG2_1x2; + texbuf.tex_width = tex_size >> 1; + texbuf.tex_height = tex_size; + } + else + { + texbuf.info.aspectRatioLog2 = GR_ASPECT_LOG2_1x1; + texbuf.tex_width = texbuf.tex_height = tex_size; + } + } + if ((cimage.format != 0))// && (cimage.width <= 64)) + texbuf.info.format = GR_TEXFMT_ALPHA_INTENSITY_88; + else + texbuf.info.format = GR_TEXFMT_RGB_565; + + texbuf.lr_u = 256.0f * texbuf.scr_width / (float)tex_size;// + 1.0f; + texbuf.lr_v = 256.0f * texbuf.scr_height / (float)tex_size;// + 1.0f; + texbuf.tile = 0; + texbuf.tile_uls = 0; + texbuf.tile_ult = 0; + texbuf.u_shift = 0; + texbuf.v_shift = 0; + texbuf.drawn = FALSE; + texbuf.u_scale = texbuf.lr_u / (float)(texbuf.width); + texbuf.v_scale = texbuf.lr_v / (float)(texbuf.height); + texbuf.cache = 0; + texbuf.crc = 0; + texbuf.t_mem = 0; + + FRDP("\nAllocateTextureBuffer. width: %d, height: %d, scr_width: %f, scr_height: %f, vi_width: %f, vi_height:%f, scale_x: %f, scale_y: %f, lr_u: %f, lr_v: %f, u_scale: %f, v_scale: %f\n", texbuf.width, texbuf.height, texbuf.scr_width, texbuf.scr_height, rdp.vi_width, rdp.vi_height, rdp.scale_x, rdp.scale_y, texbuf.lr_u, texbuf.lr_v, texbuf.u_scale, texbuf.v_scale); + + wxUint32 required = grTexCalcMemRequired(texbuf.info.smallLodLog2, texbuf.info.largeLodLog2, + texbuf.info.aspectRatioLog2, texbuf.info.format); + //find free space + for (int i = 0; i < voodoo.num_tmu; i++) + { + wxUint32 available = 0; + wxUint32 top = 0; + if (rdp.texbufs[i].count) + { + TBUFF_COLOR_IMAGE & t = rdp.texbufs[i].images[rdp.texbufs[i].count - 1]; + if (rdp.read_whole_frame || rdp.motionblur) + { + if ((cimage.status == ci_aux) && (rdp.cur_tex_buf == i)) + { + top = t.tex_addr + t.tex_width * (int)(t.scr_height+1) * 2; + if (rdp.texbufs[i].end - top < required) + return 0; + } + else + top = rdp.texbufs[i].end; + } + else + top = t.tex_addr + t.tex_width * t.tex_height * 2; + available = rdp.texbufs[i].end - top; + } + else + { + available = rdp.texbufs[i].end - rdp.texbufs[i].begin; + top = rdp.texbufs[i].begin; + } + if (available >= required) + { + rdp.texbufs[i].count++; + rdp.texbufs[i].clear_allowed = FALSE; + texbuf.tex_addr = top; + rdp.cur_tex_buf = i; + texbuf.tmu = rdp.texbufs[i].tmu; + rdp.texbufs[i].images[rdp.texbufs[i].count - 1] = texbuf; + return &(rdp.texbufs[i].images[rdp.texbufs[i].count - 1]); + } + } + //not found. keep recently accessed bank, clear second one + if (!rdp.texbufs[rdp.cur_tex_buf^1].clear_allowed) //can't clear => can't allocate + return 0; + rdp.cur_tex_buf ^= 1; + rdp.texbufs[rdp.cur_tex_buf].count = 1; + rdp.texbufs[rdp.cur_tex_buf].clear_allowed = FALSE; + texbuf.tmu = rdp.texbufs[rdp.cur_tex_buf].tmu; + texbuf.tex_addr = rdp.texbufs[rdp.cur_tex_buf].begin; + rdp.texbufs[rdp.cur_tex_buf].images[0] = texbuf; + return &(rdp.texbufs[rdp.cur_tex_buf].images[0]); +} + +int OpenTextureBuffer(COLOR_IMAGE & cimage) +{ + FRDP("OpenTextureBuffer. cur_tex_buf: %d, addr: %08lx, width: %d, height: %d", rdp.cur_tex_buf, cimage.addr, cimage.width, cimage.height); + if (!fullscreen) return FALSE; + + int found = FALSE, search = TRUE; + TBUFF_COLOR_IMAGE *texbuf = 0; + wxUint32 addr = cimage.addr; + if ((settings.hacks&hack_Banjo2) && cimage.status == ci_copy_self) + addr = rdp.frame_buffers[rdp.copy_ci_index].addr; + wxUint32 end_addr = addr + ((cimage.width*cimage.height)<>1); + if (rdp.motionblur) + { +// if (cimage.format != 0) +// return FALSE; + search = FALSE; + } + if (rdp.read_whole_frame) + { + if (settings.hacks&hack_PMario) //motion blur effects in Paper Mario + { + rdp.cur_tex_buf = rdp.acc_tex_buf; + FRDP("\nread_whole_frame. last allocated bank: %d\n", rdp.acc_tex_buf); + } + else + { + if (!rdp.texbufs[0].clear_allowed || !rdp.texbufs[1].clear_allowed) + { + if (cimage.status == ci_main) + { + texbuf = &(rdp.texbufs[rdp.cur_tex_buf].images[0]); + found = TRUE; + } + else + { + for (int t = 0; (t < rdp.texbufs[rdp.cur_tex_buf].count) && !found; t++) + { + texbuf = &(rdp.texbufs[rdp.cur_tex_buf].images[t]); + if (addr == texbuf->addr && cimage.width == texbuf->width) + { + texbuf->drawn = FALSE; + found = TRUE; + } + } + } + } + search = FALSE; + } + } + if (search) + { + for (int i = 0; (i < voodoo.num_tmu) && !found; i++) + { + for (int j = 0; (j < rdp.texbufs[i].count) && !found; j++) + { + texbuf = &(rdp.texbufs[i].images[j]); + if (addr == texbuf->addr && cimage.width == texbuf->width) + { + //texbuf->height = cimage.height; + //texbuf->end_addr = end_addr; + texbuf->drawn = FALSE; + texbuf->format = (wxUint16)cimage.format; + if ((cimage.format != 0)) + texbuf->info.format = GR_TEXFMT_ALPHA_INTENSITY_88; + else + texbuf->info.format = GR_TEXFMT_RGB_565; + texbuf->crc = 0; + texbuf->t_mem = 0; + texbuf->tile = 0; + found = TRUE; + rdp.cur_tex_buf = i; + rdp.texbufs[i].clear_allowed = FALSE; + } + else //check intersection + { + if (!((end_addr <= texbuf->addr) || (addr >= texbuf->end_addr))) //intersected, remove + { + grRenderBuffer( GR_BUFFER_TEXTUREBUFFER_EXT ); + grTextureBufferExt( texbuf->tmu, texbuf->tex_addr, texbuf->info.smallLodLog2, texbuf->info.largeLodLog2, + texbuf->info.aspectRatioLog2, texbuf->info.format, GR_MIPMAPLEVELMASK_BOTH ); + grDepthMask (FXFALSE); + grBufferClear (0, 0, 0xFFFF); + grDepthMask (FXTRUE); + grRenderBuffer( GR_BUFFER_BACKBUFFER ); + rdp.texbufs[i].count--; + if (j < rdp.texbufs[i].count) + memcpy(&(rdp.texbufs[i].images[j]), &(rdp.texbufs[i].images[j+1]), sizeof(TBUFF_COLOR_IMAGE)*(rdp.texbufs[i].count-j)); + } + } + } + } + } + else + { + LRDP(" not searched"); + } + + if (!found) + { + LRDP(" not found"); + texbuf = AllocateTextureBuffer(cimage); + } + else + { + LRDP(" found"); + } + + if (!texbuf) + { + LRDP(" KO\n"); + return FALSE; + } + + rdp.acc_tex_buf = rdp.cur_tex_buf; + rdp.cur_image = texbuf; + grRenderBuffer( GR_BUFFER_TEXTUREBUFFER_EXT ); + grTextureBufferExt( rdp.cur_image->tmu, rdp.cur_image->tex_addr, rdp.cur_image->info.smallLodLog2, rdp.cur_image->info.largeLodLog2, + rdp.cur_image->info.aspectRatioLog2, rdp.cur_image->info.format, GR_MIPMAPLEVELMASK_BOTH ); + ///* + if (rdp.cur_image->clear && (settings.frame_buffer&fb_hwfbe_buf_clear) && cimage.changed) + { + rdp.cur_image->clear = FALSE; + grDepthMask (FXFALSE); + grBufferClear (0, 0, 0xFFFF); + grDepthMask (FXTRUE); + } + //*/ + // memset(gfx.RDRAM+cimage.addr, 0, cimage.width*cimage.height*cimage.size); + FRDP(" texaddr: %08lx, tex_width: %d, tex_height: %d, cur_tex_buf: %d, texformat: %d, motionblur: %d\n", rdp.cur_image->tex_addr, rdp.cur_image->tex_width, rdp.cur_image->tex_height, rdp.cur_tex_buf, rdp.cur_image->info.format, rdp.motionblur); + if (!rdp.offset_x_bak) + { + rdp.offset_x_bak = rdp.offset_x; + rdp.offset_x = 0; + } + if (!rdp.offset_y_bak) + { + rdp.offset_y_bak = rdp.offset_y; + rdp.offset_y = 0; + } + rdp.update |= UPDATE_VIEWPORT | UPDATE_SCISSOR; + return TRUE; +} + +static GrTextureFormat_t TexBufSetupCombiner(int force_rgb = FALSE) +{ + grColorCombine( GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_NONE, + GR_COMBINE_OTHER_TEXTURE, +// GR_COMBINE_OTHER_CONSTANT, + FXFALSE); + grAlphaCombine (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_NONE, + GR_COMBINE_OTHER_TEXTURE, + FXFALSE); +// grConstantColorValue (0xFFFFFFFF); + grAlphaBlendFunction (GR_BLEND_ONE, // use alpha compare, but not T0 alpha + GR_BLEND_ZERO, + GR_BLEND_ONE, + GR_BLEND_ZERO); + grClipWindow (0, 0, settings.scr_res_x, settings.scr_res_y); + grDepthBufferFunction (GR_CMP_ALWAYS); + grDepthMask (FXFALSE); + grCullMode (GR_CULL_DISABLE); + grFogMode (GR_FOG_DISABLE); + GrTextureFormat_t buf_format = (rdp.tbuff_tex) ? rdp.tbuff_tex->info.format : GR_TEXFMT_RGB_565; + GrCombineFunction_t color_source = GR_COMBINE_FUNCTION_LOCAL; + if (!force_rgb && rdp.black_ci_index > 0 && rdp.black_ci_index <= rdp.copy_ci_index) + { + color_source = GR_COMBINE_FUNCTION_LOCAL_ALPHA; + buf_format = GR_TEXFMT_ALPHA_INTENSITY_88; + } + if (rdp.tbuff_tex->tmu == GR_TMU0) + { + grTexCombine( GR_TMU1, + GR_COMBINE_FUNCTION_NONE, + GR_COMBINE_FACTOR_NONE, + GR_COMBINE_FUNCTION_NONE, + GR_COMBINE_FACTOR_NONE, + FXFALSE, + FXFALSE ); + grTexCombine( GR_TMU0, + color_source, + GR_COMBINE_FACTOR_NONE, + GR_COMBINE_FUNCTION_ZERO, + GR_COMBINE_FACTOR_NONE, + FXFALSE, + FXTRUE ); + } + else + { + grTexCombine( GR_TMU1, + color_source, + GR_COMBINE_FACTOR_NONE, + GR_COMBINE_FUNCTION_ZERO, + GR_COMBINE_FACTOR_NONE, + FXFALSE, + FXTRUE ); + grTexCombine( GR_TMU0, + GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_ONE, + FXFALSE, + FXFALSE ); + } + return buf_format; +} + +int CloseTextureBuffer(int draw) +{ + if (!fullscreen || !rdp.cur_image) + { + LRDP("CloseTextureBuffer KO\n"); + return FALSE; + } + grRenderBuffer( GR_BUFFER_BACKBUFFER ); + rdp.offset_x = rdp.offset_x_bak; + rdp.offset_y = rdp.offset_y_bak; + rdp.offset_x_bak = rdp.offset_y_bak = 0; + rdp.update |= UPDATE_VIEWPORT | UPDATE_SCISSOR; + if (!draw) + { + LRDP("CloseTextureBuffer no draw, OK\n"); + rdp.cur_image = 0; + return TRUE; + } + rdp.tbuff_tex = rdp.cur_image; + rdp.cur_image = 0; + rdp.tbuff_tex->info.format = TexBufSetupCombiner(); + float zero = 0.0f; + float ul_x = rdp.offset_x; + float ul_y = rdp.offset_y; + float lr_x = rdp.tbuff_tex->scr_width + rdp.offset_x; + float lr_y = rdp.tbuff_tex->scr_height + rdp.offset_y; + float lr_u = rdp.tbuff_tex->lr_u; + float lr_v = rdp.tbuff_tex->lr_v; + FRDP("lr_x: %f, lr_y: %f, lr_u: %f, lr_v: %f\n", lr_x, lr_y, lr_u, lr_v); + + + // Make the vertices + VERTEX v[4] = { + { ul_x, ul_y, 1, 1, zero, zero, zero, zero, {zero, zero, zero, zero} }, + { lr_x, ul_y, 1, 1, lr_u, zero, lr_u, zero, {lr_u, zero, lr_u, zero} }, + { ul_x, lr_y, 1, 1, zero, lr_v, zero, lr_v, {zero, lr_v, zero, lr_v} }, + { lr_x, lr_y, 1, 1, lr_u, lr_v, lr_u, lr_v, {lr_u, lr_v, lr_u, lr_v} } + }; + + grTexSource( rdp.tbuff_tex->tmu, rdp.tbuff_tex->tex_addr, GR_MIPMAPLEVELMASK_BOTH, &(rdp.tbuff_tex->info) ); + grClipWindow (0, 0, settings.res_x, settings.res_y); + grDrawTriangle (&v[0], &v[2], &v[1]); + grDrawTriangle (&v[2], &v[3], &v[1]); + rdp.update |= UPDATE_ZBUF_ENABLED | UPDATE_COMBINE | UPDATE_TEXTURE | UPDATE_ALPHA_COMPARE; + if (settings.fog && (rdp.flags & FOG_ENABLED)) + { + grFogMode (GR_FOG_WITH_TABLE_ON_FOGCOORD_EXT); + } + LRDP("CloseTextureBuffer draw, OK\n"); + rdp.tbuff_tex = 0; + return TRUE; +} + +int CopyTextureBuffer(COLOR_IMAGE & fb_from, COLOR_IMAGE & fb_to) +{ + if (!fullscreen) + return FALSE; + FRDP("CopyTextureBuffer from %08x to %08x\n", fb_from.addr, fb_to.addr); + if (rdp.cur_image) + { + rdp.cur_image->crc = 0; + if (rdp.cur_image->addr == fb_to.addr) + return CloseTextureBuffer(TRUE); + rdp.tbuff_tex = rdp.cur_image; + } + else if (!FindTextureBuffer(fb_from.addr, (wxUint16)fb_from.width)) + { + LRDP("Can't find 'from' buffer.\n"); + return FALSE; + } + if (!OpenTextureBuffer(fb_to)) + { + LRDP("Can't open new buffer.\n"); + return CloseTextureBuffer(TRUE); + } + rdp.tbuff_tex->crc = 0; + GrTextureFormat_t buf_format = rdp.tbuff_tex->info.format; + rdp.tbuff_tex->info.format = GR_TEXFMT_RGB_565; + TexBufSetupCombiner(TRUE); + float ul_x = 0.0f; + float ul_y = 0.0f; + float lr_x = rdp.tbuff_tex->scr_width; + float lr_y = rdp.tbuff_tex->scr_height; + float zero = 0.0f; + float lr_u = rdp.tbuff_tex->lr_u; + float lr_v = rdp.tbuff_tex->lr_v; + FRDP("lr_x: %f, lr_y: %f\n", lr_x, lr_y); + + + // Make the vertices + VERTEX v[4] = { + { ul_x, ul_y, 1, 1, zero, zero, zero, zero, {zero, zero, zero, zero} }, + { lr_x, ul_y, 1, 1, lr_u, zero, lr_u, zero, {lr_u, zero, lr_u, zero} }, + { ul_x, lr_y, 1, 1, zero, lr_v, zero, lr_v, {zero, lr_v, zero, lr_v} }, + { lr_x, lr_y, 1, 1, lr_u, lr_v, lr_u, lr_v, {lr_u, lr_v, lr_u, lr_v} } + }; + + grTexSource( rdp.tbuff_tex->tmu, rdp.tbuff_tex->tex_addr, GR_MIPMAPLEVELMASK_BOTH, &(rdp.tbuff_tex->info) ); + grDrawTriangle (&v[0], &v[2], &v[1]); + grDrawTriangle (&v[2], &v[3], &v[1]); + grRenderBuffer( GR_BUFFER_BACKBUFFER ); + rdp.offset_x = rdp.offset_x_bak; + rdp.offset_y = rdp.offset_y_bak; + rdp.offset_x_bak = rdp.offset_y_bak = 0; + AddOffset(v, 4); + grClipWindow (0, 0, settings.res_x, settings.res_y); + grDrawTriangle (&v[0], &v[2], &v[1]); + grDrawTriangle (&v[2], &v[3], &v[1]); + rdp.tbuff_tex->info.format = buf_format; + + rdp.update |= UPDATE_ZBUF_ENABLED | UPDATE_COMBINE | UPDATE_TEXTURE | UPDATE_ALPHA_COMPARE; + rdp.update |= UPDATE_VIEWPORT | UPDATE_SCISSOR; + if (settings.fog && (rdp.flags & FOG_ENABLED)) + grFogMode (GR_FOG_WITH_TABLE_ON_FOGCOORD_EXT); + LRDP("CopyTextureBuffer draw, OK\n"); + rdp.tbuff_tex = 0; + rdp.cur_image = 0; + return TRUE; +} + +int CopyDepthBuffer() +{ + if (!fullscreen) + return FALSE; + LRDP("CopyDepthBuffer. "); + float bound = 1024.0f; + GrLOD_t LOD = GR_LOD_LOG2_1024; + if (settings.scr_res_x > 1024) + { + bound = 2048.0f; + LOD = GR_LOD_LOG2_2048; + } + rdp.tbuff_tex = &(rdp.texbufs[0].images[0]); + rdp.tbuff_tex->tmu = rdp.texbufs[0].tmu; + rdp.tbuff_tex->info.format = GR_TEXFMT_RGB_565; + rdp.tbuff_tex->info.smallLodLog2 = rdp.tbuff_tex->info.largeLodLog2 = LOD; + rdp.tbuff_tex->info.aspectRatioLog2 = GR_ASPECT_LOG2_1x1; + TexBufSetupCombiner(TRUE); + float ul_x = 0.0f; + float ul_y = 0.0f; + float lr_x = bound; + float lr_y = bound; + float zero = 0.0f; + float lr_u = 255.5f; + float lr_v = 255.5f; + FRDP("lr_x: %f, lr_y: %f\n", lr_x, lr_y); + + + // Make the vertices + VERTEX v[4] = { + { ul_x, ul_y, 1, 1, zero, zero, zero, zero, {zero, zero, zero, zero} }, + { lr_x, ul_y, 1, 1, lr_u, zero, lr_u, zero, {lr_u, zero, lr_u, zero} }, + { ul_x, lr_y, 1, 1, zero, lr_v, zero, lr_v, {zero, lr_v, zero, lr_v} }, + { lr_x, lr_y, 1, 1, lr_u, lr_v, lr_u, lr_v, {lr_u, lr_v, lr_u, lr_v} } + }; + + grAuxBufferExt( GR_BUFFER_AUXBUFFER ); + grTexSource( rdp.texbufs[0].tmu, rdp.texbufs[0].begin, GR_MIPMAPLEVELMASK_BOTH, &(rdp.tbuff_tex->info) ); + grRenderBuffer( GR_BUFFER_TEXTUREBUFFER_EXT ); + grTextureBufferExt( rdp.texbufs[1].tmu, rdp.texbufs[1].begin, LOD, LOD, + GR_ASPECT_LOG2_1x1, GR_TEXFMT_RGB_565, GR_MIPMAPLEVELMASK_BOTH ); + grDrawTriangle (&v[0], &v[2], &v[1]); + grDrawTriangle (&v[2], &v[3], &v[1]); + grRenderBuffer( GR_BUFFER_BACKBUFFER ); + grTextureAuxBufferExt( rdp.texbufs[1].tmu, rdp.texbufs[1].begin, LOD, LOD, + GR_ASPECT_LOG2_1x1, GR_TEXFMT_RGB_565, GR_MIPMAPLEVELMASK_BOTH ); + grAuxBufferExt( GR_BUFFER_TEXTUREAUXBUFFER_EXT ); + + rdp.update |= UPDATE_ZBUF_ENABLED | UPDATE_COMBINE | UPDATE_TEXTURE | UPDATE_ALPHA_COMPARE; + if (settings.fog && (rdp.flags & FOG_ENABLED)) + grFogMode (GR_FOG_WITH_TABLE_ON_FOGCOORD_EXT); + LRDP("CopyDepthBuffer draw, OK\n"); + rdp.tbuff_tex = 0; + return TRUE; +} + +int SwapTextureBuffer() +{ + if (!fullscreen || !rdp.tbuff_tex) + return FALSE; + LRDP("SwapTextureBuffer."); + COLOR_IMAGE ci; + ci.addr = rdp.tbuff_tex->addr; + ci.format = rdp.tbuff_tex->format; + ci.width = rdp.tbuff_tex->width; + ci.height = rdp.tbuff_tex->height; + ci.size = 2; + ci.status = ci_main; + ci.changed = FALSE; + TBUFF_COLOR_IMAGE * texbuf = AllocateTextureBuffer(ci); + if (!texbuf) + { + LRDP("Failed!\n"); + return FALSE; + } + TexBufSetupCombiner(); + + float ul_x = 0.0f; + float ul_y = 0.0f; + float lr_x = rdp.tbuff_tex->scr_width; + float lr_y = rdp.tbuff_tex->scr_height; + float zero = 0.0f; + float lr_u = rdp.tbuff_tex->lr_u; + float lr_v = rdp.tbuff_tex->lr_v; + + // Make the vertices + VERTEX v[4] = { + { ul_x, ul_y, 1, 1, zero, zero, zero, zero, {zero, zero, zero, zero} }, + { lr_x, ul_y, 1, 1, lr_u, zero, lr_u, zero, {lr_u, zero, lr_u, zero} }, + { ul_x, lr_y, 1, 1, zero, lr_v, zero, lr_v, {zero, lr_v, zero, lr_v} }, + { lr_x, lr_y, 1, 1, lr_u, lr_v, lr_u, lr_v, {lr_u, lr_v, lr_u, lr_v} } + }; + + grTexSource( rdp.tbuff_tex->tmu, rdp.tbuff_tex->tex_addr, GR_MIPMAPLEVELMASK_BOTH, &(rdp.tbuff_tex->info) ); + texbuf->tile_uls = rdp.tbuff_tex->tile_uls; + texbuf->tile_ult = rdp.tbuff_tex->tile_ult; + texbuf->v_shift = rdp.tbuff_tex->v_shift; + grRenderBuffer( GR_BUFFER_TEXTUREBUFFER_EXT ); + grTextureBufferExt( texbuf->tmu, texbuf->tex_addr, texbuf->info.smallLodLog2, texbuf->info.largeLodLog2, + texbuf->info.aspectRatioLog2, texbuf->info.format, GR_MIPMAPLEVELMASK_BOTH ); + grDrawTriangle (&v[0], &v[2], &v[1]); + grDrawTriangle (&v[2], &v[3], &v[1]); + rdp.texbufs[rdp.tbuff_tex->tmu].clear_allowed = TRUE; + rdp.texbufs[rdp.tbuff_tex->tmu].count = 0; + texbuf->tile_uls = rdp.tbuff_tex->tile_uls; + texbuf->tile_ult = rdp.tbuff_tex->tile_ult; + texbuf->u_shift = rdp.tbuff_tex->u_shift; + texbuf->v_shift = rdp.tbuff_tex->v_shift; + rdp.tbuff_tex = texbuf; + if (rdp.cur_image) + { + grTextureBufferExt( rdp.cur_image->tmu, rdp.cur_image->tex_addr, rdp.cur_image->info.smallLodLog2, rdp.cur_image->info.largeLodLog2, + rdp.cur_image->info.aspectRatioLog2, rdp.cur_image->info.format, GR_MIPMAPLEVELMASK_BOTH ); + } + else + { + grRenderBuffer( GR_BUFFER_BACKBUFFER ); + rdp.offset_x = rdp.offset_x_bak; + rdp.offset_y = rdp.offset_y_bak; + rdp.offset_x_bak = rdp.offset_y_bak = 0; + rdp.update |= UPDATE_VIEWPORT | UPDATE_SCISSOR; + } + rdp.update |= UPDATE_ZBUF_ENABLED | UPDATE_COMBINE | UPDATE_TEXTURE | UPDATE_ALPHA_COMPARE; + if (settings.fog && (rdp.flags & FOG_ENABLED)) + { + grFogMode (GR_FOG_WITH_TABLE_ON_FOGCOORD_EXT); + } + LRDP("SwapTextureBuffer draw, OK\n"); + return TRUE; +} + +static wxUint32 CalcCRC(TBUFF_COLOR_IMAGE * pTCI) +{ + wxUint32 result = 0; + if ((settings.frame_buffer&fb_ref) > 0) + pTCI->crc = 0; //Since fb content changes each frame, crc check is meaningless. + else if (settings.fb_crc_mode == SETTINGS::fbcrcFast) + result = *((wxUint32*)(gfx.RDRAM + pTCI->addr + (pTCI->end_addr-pTCI->addr)/2)); + else if (settings.fb_crc_mode == SETTINGS::fbcrcSafe) + { + wxUint8 * pSrc = gfx.RDRAM + pTCI->addr; + const wxUint32 nSize = pTCI->end_addr-pTCI->addr; + result = CRC32(0xFFFFFFFF, pSrc, 32); + result = CRC32(result, pSrc + (nSize>>1), 32); + result = CRC32(result, pSrc + nSize - 32, 32); + } + return result; +} + +int FindTextureBuffer(wxUint32 addr, wxUint16 width) +{ + if (rdp.skip_drawing) + return FALSE; + FRDP("FindTextureBuffer. addr: %08lx, width: %d, scale_x: %f\n", addr, width, rdp.scale_x); + int found = FALSE; + wxUint32 shift = 0; + for (int i = 0; i < voodoo.num_tmu && !found; i++) + { + wxUint8 index = rdp.cur_tex_buf^i; + for (int j = 0; j < rdp.texbufs[index].count && !found; j++) + { + rdp.tbuff_tex = &(rdp.texbufs[index].images[j]); + if(addr >= rdp.tbuff_tex->addr && addr < rdp.tbuff_tex->end_addr)// && rdp.timg.format == 0) + { + bool bCorrect; + if (rdp.tbuff_tex->crc == 0) + { + rdp.tbuff_tex->crc = CalcCRC(rdp.tbuff_tex); + bCorrect = width == 1 || rdp.tbuff_tex->width == width || (rdp.tbuff_tex->width > 320 && rdp.tbuff_tex->width == width*2); + } + else + bCorrect = rdp.tbuff_tex->crc == CalcCRC(rdp.tbuff_tex); + if (bCorrect) + { + shift = addr - rdp.tbuff_tex->addr; + // if (!rdp.motionblur) + if (!rdp.cur_image) + rdp.cur_tex_buf = index; + found = TRUE; + // FRDP("FindTextureBuffer, found in TMU%d buffer: %d\n", rdp.tbuff_tex->tmu, j); + } + else //new texture is loaded into this place, texture buffer is not valid anymore + { + rdp.texbufs[index].count--; + if (j < rdp.texbufs[index].count) + memcpy(&(rdp.texbufs[index].images[j]), &(rdp.texbufs[index].images[j+1]), sizeof(TBUFF_COLOR_IMAGE)*(rdp.texbufs[index].count-j)); + } + } + } + } + if (found) + { + rdp.tbuff_tex->tile_uls = 0; + rdp.tbuff_tex->tile_ult = 0; + if (shift > 0) + { + shift >>= 1; + rdp.tbuff_tex->v_shift = shift / rdp.tbuff_tex->width; + rdp.tbuff_tex->u_shift = shift % rdp.tbuff_tex->width; + } + else + { + rdp.tbuff_tex->v_shift = 0; + rdp.tbuff_tex->u_shift = 0; + } + FRDP("FindTextureBuffer, found, u_shift: %d, v_shift: %d, format: %s\n", rdp.tbuff_tex->u_shift, rdp.tbuff_tex->v_shift, str_format[rdp.tbuff_tex->format]); + //FRDP("Buffer, addr=%08lx, end_addr=%08lx, width: %d, height: %d\n", rdp.tbuff_tex->addr, rdp.tbuff_tex->end_addr, rdp.tbuff_tex->width, rdp.tbuff_tex->height); + return TRUE; + } + rdp.tbuff_tex = 0; + LRDP("FindTextureBuffer, not found\n"); + return FALSE; +} diff --git a/Source/Glide64/TexBuffer.h b/Source/Glide64/TexBuffer.h new file mode 100644 index 000000000..57119027f --- /dev/null +++ b/Source/Glide64/TexBuffer.h @@ -0,0 +1,60 @@ +/* +* Glide64 - Glide video plugin for Nintendo 64 emulators. +* Copyright (c) 2002 Dave2001 +* Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski +* +* 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 +* 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 +*/ + +//**************************************************************** +// +// Glide64 - Glide Plugin for Nintendo 64 emulators +// Project started on December 29th, 2001 +// +// Authors: +// Dave2001, original author, founded the project in 2001, left it in 2002 +// Gugaman, joined the project in 2002, left it in 2002 +// Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002 +// Hiroshi 'KoolSmoky' Morii, joined the project in 2007 +// +//**************************************************************** +// +// To modify Glide64: +// * Write your name and (optional)email, commented by your work, so I know who did it, and so that you can find which parts you modified when it comes time to send it to me. +// * Do NOT send me the whole project or file that you modified. Take out your modified code sections, and tell me where to put them. If people sent the whole thing, I would have many different versions, but no idea how to combine them all. +// +//**************************************************************** +// +// Hardware frame buffer emulation +// Dec 2003 created by Gonetz +// +//**************************************************************** + +#ifndef TEXBUFFER_H +#define TEXBUFFER_H + +int OpenTextureBuffer(COLOR_IMAGE & cimage); + +int CloseTextureBuffer(int draw = FALSE); + +int CopyTextureBuffer(COLOR_IMAGE & fb_from, COLOR_IMAGE & fb_to); + +int CopyDepthBuffer(); + +int SwapTextureBuffer(); + +int FindTextureBuffer(wxUint32 addr, wxUint16 width); + +#endif // ifndef TEXBUFFER diff --git a/Source/Glide64/TexCache.cpp b/Source/Glide64/TexCache.cpp new file mode 100644 index 000000000..9da80de3e --- /dev/null +++ b/Source/Glide64/TexCache.cpp @@ -0,0 +1,1807 @@ +/* +* Glide64 - Glide video plugin for Nintendo 64 emulators. +* Copyright (c) 2002 Dave2001 +* Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski +* +* 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 +* 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 +*/ + +//**************************************************************** +// +// Glide64 - Glide Plugin for Nintendo 64 emulators +// Project started on December 29th, 2001 +// +// Authors: +// Dave2001, original author, founded the project in 2001, left it in 2002 +// Gugaman, joined the project in 2002, left it in 2002 +// Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002 +// Hiroshi 'KoolSmoky' Morii, joined the project in 2007 +// +//**************************************************************** +// +// To modify Glide64: +// * Write your name and (optional)email, commented by your work, so I know who did it, and so that you can find which parts you modified when it comes time to send it to me. +// * Do NOT send me the whole project or file that you modified. Take out your modified code sections, and tell me where to put them. If people sent the whole thing, I would have many different versions, but no idea how to combine them all. +// +//**************************************************************** + +#include "Gfx #1.3.h" +#include "TexCache.h" +#include "Combine.h" + +void LoadTex (int id, int tmu); + +wxUint8 tex1[1024*1024*4]; // temporary texture +wxUint8 tex2[1024*1024*4]; +wxUint8 *texture; +wxUint8 *texture_buffer = tex1; + +#include "TexLoad.h" // texture loading functions, ONLY INCLUDE IN THIS FILE!!! +#include "MiClWr32b.h" +#include "MiClWr16b.h" // Mirror/Clamp/Wrap functions, ONLY INCLUDE IN THIS FILE!!! +#include "MiClWr8b.h" // Mirror/Clamp/Wrap functions, ONLY INCLUDE IN THIS FILE!!! +#include "TexConv.h" // texture conversions, ONLY INCLUDE IN THIS FILE!!! +#include "TexMod.h" +#include "TexModCI.h" +#include "CRC.h" +#ifdef TEXTURE_FILTER // Hiroshi Morii +extern int ghq_dmptex_toggle_key; +#endif + +typedef struct TEXINFO_t { + int real_image_width, real_image_height; // FOR ALIGNMENT PURPOSES ONLY!!! + int tile_width, tile_height; + int mask_width, mask_height; + int width, height; + int wid_64, line; + wxUint32 crc; + wxUint32 flags; + int splits, splitheight; +#ifdef TEXTURE_FILTER + uint64 ricecrc; +#endif +} TEXINFO; + +TEXINFO texinfo[2]; +int tex_found[2][MAX_TMU]; + +#ifdef TEXTURE_FILTER +typedef struct HIRESTEX_t { + int width, height; + wxUint16 format; + wxUint8 *data; +} HIRESTEX; +#endif + +//**************************************************************** +// List functions + +typedef struct NODE_t { + wxUint32 crc; + wxUIntPtr data; + int tmu; + int number; + NODE_t *pNext; +} NODE; + +NODE *cachelut[65536]; + +void AddToList (NODE **list, wxUint32 crc, wxUIntPtr data, int tmu, int number) +{ + NODE *node = new NODE; + node->crc = crc; + node->data = data; + node->tmu = tmu; + node->number = number; + node->pNext = *list; + *list = node; + rdp.n_cached[tmu] ++; + if (voodoo.tex_UMA) + rdp.n_cached[tmu^1] = rdp.n_cached[tmu]; +} + +void DeleteList (NODE **list) +{ + while (*list) + { + NODE *next = (*list)->pNext; + delete (*list); + *list = next; + } +} + +void TexCacheInit () +{ + for (int i=0; i<65536; i++) + { + cachelut[i] = NULL; + } +} + +//**************************************************************** +// ClearCache - clear the texture cache for BOTH tmus + +void ClearCache () +{ + voodoo.tmem_ptr[0] = offset_textures; + rdp.n_cached[0] = 0; + voodoo.tmem_ptr[1] = voodoo.tex_UMA ? offset_textures : offset_texbuf1; + rdp.n_cached[1] = 0; + + for (int i=0; i<65536; i++) + { + DeleteList (&cachelut[i]); + } +} + +//**************************************************************** +// GetTexInfo - gets information for either t0 or t1, checks if in cache & fills tex_found + +extern "C" int asmTextureCRC(int addr, int width, int height, int line); +void GetTexInfo (int id, int tile) +{ + FRDP (" | |-+ GetTexInfo (id: %d, tile: %d)\n", id, tile); + + // this is the NEW cache searching, searches only textures with similar crc's + int t; + for (t=0; ttile == id) + pFBTex = rdp.aTBuffTex[0]; + else if (rdp.aTBuffTex[1] && rdp.aTBuffTex[1]->tile == id) + pFBTex = rdp.aTBuffTex[1]; + if (pFBTex && pFBTex->cache) + return; + + TEXINFO *info = &texinfo[id]; + + int tile_width, tile_height; + int mask_width, mask_height; + int width, height; + int wid_64, line, bpl; + + // Get width and height + tile_width = rdp.tiles[tile].lr_s - rdp.tiles[tile].ul_s + 1; + tile_height = rdp.tiles[tile].lr_t - rdp.tiles[tile].ul_t + 1; + + mask_width = (rdp.tiles[tile].mask_s==0)?(tile_width):(1 << rdp.tiles[tile].mask_s); + mask_height = (rdp.tiles[tile].mask_t==0)?(tile_height):(1 << rdp.tiles[tile].mask_t); + + if (settings.alt_tex_size) + { + // ** ALTERNATE TEXTURE SIZE METHOD ** + // Helps speed in some games that loaded weird-sized textures, but could break other + // textures. + + // Get the width/height to load + if ((rdp.tiles[tile].clamp_s && tile_width <= 256) || (mask_width > 256)) + { + // loading width + width = min(mask_width, tile_width); + // actual width + rdp.tiles[tile].width = tile_width; + } + else + { + // wrap all the way + width = min(mask_width, tile_width); // changed from mask_width only + rdp.tiles[tile].width = width; + } + + if ((rdp.tiles[tile].clamp_t && tile_height <= 256) || (mask_height > 256)) + { + // loading height + height = min(mask_height, tile_height); + // actual height + rdp.tiles[tile].height = tile_height; + } + else + { + // wrap all the way + height = min(mask_height, tile_height); + rdp.tiles[tile].height = height; + } + } + else + { + // ** NORMAL TEXTURE SIZE METHOD ** + // This is the 'correct' method for determining texture size, but may cause certain + // textures to load too large & make the whole game go slow. + + if (mask_width > 256 && mask_height > 256) + { + mask_width = tile_width; + mask_height = tile_height; + } + + // Get the width/height to load + if ((rdp.tiles[tile].clamp_s && tile_width <= 256) )//|| (mask_width > 256)) + { + // loading width + width = min(mask_width, tile_width); + // actual width + rdp.tiles[tile].width = tile_width; + } + else + { + // wrap all the way + width = mask_width; + rdp.tiles[tile].width = mask_width; + } + + if ((rdp.tiles[tile].clamp_t && tile_height <= 256) || (mask_height > 256)) + { + // loading height + height = min(mask_height, tile_height); + // actual height + rdp.tiles[tile].height = tile_height; + } + else + { + // wrap all the way + height = mask_height; + rdp.tiles[tile].height = mask_height; + } + } + + // without any large texture fixing-up; for alignment + int real_image_width = rdp.tiles[tile].width; + int real_image_height = rdp.tiles[tile].height; + int crc_height = height; + if (rdp.timg.set_by == 1) + crc_height = tile_height; + + bpl = width << rdp.tiles[tile].size >> 1; + + // ** COMMENT THIS TO DISABLE LARGE TEXTURES +#ifdef LARGE_TEXTURE_HANDLING + if (!voodoo.sup_large_tex && width > 256) + { + info->splits = ((width-1)>>8)+1; + info->splitheight = rdp.tiles[tile].height; + rdp.tiles[tile].height *= info->splits; + rdp.tiles[tile].width = 256; + width = 256; + } + else +#endif + // ** + { + info->splits = 1; + } + + LRDP(" | | |-+ Texture approved:\n"); + FRDP (" | | | |- tmem: %08lx\n", rdp.tiles[tile].t_mem); + FRDP (" | | | |- load width: %d\n", width); + FRDP (" | | | |- load height: %d\n", height); + FRDP (" | | | |- actual width: %d\n", rdp.tiles[tile].width); + FRDP (" | | | |- actual height: %d\n", rdp.tiles[tile].height); + FRDP (" | | | |- size: %d\n", rdp.tiles[tile].size); + FRDP (" | | | +- format: %d\n", rdp.tiles[tile].format); + LRDP(" | | |- Calculating CRC... "); + + // ** CRC CHECK + + wid_64 = width << (rdp.tiles[tile].size) >> 1; + if (rdp.tiles[tile].size == 3) + { + if (wid_64 & 15) wid_64 += 16; + wid_64 &= 0xFFFFFFF0; + } + else + { + if (wid_64 & 7) wid_64 += 8; // round up + } + wid_64 = wid_64>>3; + + // Texture too big for tmem & needs to wrap? (trees in mm) + if (rdp.tiles[tile].t_mem + min(height, tile_height) * (rdp.tiles[tile].line<<3) > 4096) + { + LRDP("TEXTURE WRAPS TMEM!!! "); + + // calculate the y value that intersects at 4096 bytes + int y = (4096 - rdp.tiles[tile].t_mem) / (rdp.tiles[tile].line<<3); + + rdp.tiles[tile].clamp_t = 0; + rdp.tiles[tile].lr_t = rdp.tiles[tile].ul_t + y - 1; + + // calc mask + int shift; + for (shift=0; (1< 0) // Check the CRC + { + if (rdp.tiles[tile].size < 3) + crc = asmTextureCRC(addr, wid_64, crc_height, line); + else //32b texture + { + int line_2 = line >> 1; + int wid_64_2 = max(1, wid_64 >> 1); + crc = asmTextureCRC(addr, wid_64_2, crc_height, line_2); + crc += asmTextureCRC(addr+0x800, wid_64_2, crc_height, line_2); + } + } + } + else + { + crc = 0xFFFFFFFF; + wxUIntPtr addr = wxPtrToUInt(rdp.tmem) + (rdp.tiles[tile].t_mem<<3); + wxUint32 line2 = max(line,1); + if (rdp.tiles[tile].size < 3) + { + line2 <<= 3; + for (int y = 0; y < crc_height; y++) + { + crc = CRC32( crc, reinterpret_cast(addr), bpl ); + addr += line2; + } + } + else //32b texture + { + line2 <<= 2; + //32b texel is split in two 16b parts, so bpl/2 and line/2. + //Min value for bpl is 4, because when width==1 first 2 bytes of tmem will not be used. + bpl = max(bpl >> 1, 4); + for (int y = 0; y < crc_height; y++) + { + crc = CRC32( crc, reinterpret_cast(addr), bpl); + crc = CRC32( crc, reinterpret_cast(addr + 0x800), bpl); + addr += line2; + } + } + line = (line - wid_64) << 3; + if (wid_64 < 1) wid_64 = 1; + } + if ((rdp.tiles[tile].size < 2) && (rdp.tlut_mode || rdp.tiles[tile].format == 2)) + { + if (rdp.tiles[tile].size == 0) + crc += rdp.pal_8_crc[rdp.tiles[tile].palette]; + else + crc += rdp.pal_256_crc; + } + + FRDP ("Done. CRC is: %08lx.\n", crc); + + wxUint32 flags = (rdp.tiles[tile].clamp_s << 23) | (rdp.tiles[tile].mirror_s << 22) | + (rdp.tiles[tile].mask_s << 18) | (rdp.tiles[tile].clamp_t << 17) | + (rdp.tiles[tile].mirror_t << 16) | (rdp.tiles[tile].mask_t << 12); + + info->real_image_width = real_image_width; + info->real_image_height = real_image_height; + info->tile_width = tile_width; + info->tile_height = tile_height; + info->mask_width = mask_width; + info->mask_height = mask_height; + info->width = width; + info->height = height; + info->wid_64 = wid_64; + info->line = line; + info->crc = crc; + info->flags = flags; + + // Search the texture cache for this texture + LRDP(" | | |-+ Checking cache...\n"); + + CACHE_LUT *cache; + + if (rdp.noise == RDP::noise_texture) + return; + + wxUint32 mod, modcolor, modcolor1, modcolor2, modfactor; + if (id == 0) + { + mod = cmb.mod_0; + modcolor = cmb.modcolor_0; + modcolor1 = cmb.modcolor1_0; + modcolor2 = cmb.modcolor2_0; + modfactor = cmb.modfactor_0; + } + else + { + mod = cmb.mod_1; + modcolor = cmb.modcolor_1; + modcolor1 = cmb.modcolor1_1; + modcolor2 = cmb.modcolor2_1; + modfactor = cmb.modfactor_1; + } + + NODE *node = cachelut[crc>>16]; + wxUint32 mod_mask = (rdp.tiles[tile].format == 2)?0xFFFFFFFF:0xF0F0F0F0; + while (node) + { + if (node->crc == crc) + { + cache = (CACHE_LUT*)node->data; + if (/*tex_found[id][node->tmu] == -1 && + rdp.tiles[tile].palette == cache->palette && + rdp.tiles[tile].format == cache->format && + rdp.tiles[tile].size == cache->size &&*/ + rdp.tiles[tile].width == cache->width && + rdp.tiles[tile].height == cache->height && + flags == cache->flags) + { + if (!(mod+cache->mod) || (cache->mod == mod && + (cache->mod_color&mod_mask) == (modcolor&mod_mask) && + (cache->mod_color1&mod_mask) == (modcolor1&mod_mask) && + (cache->mod_color2&mod_mask) == (modcolor2&mod_mask) && + abs((int)(cache->mod_factor - modfactor)) < 8)) + { + FRDP (" | | | |- Texture found in cache (tmu=%d).\n", node->tmu); + tex_found[id][node->tmu] = node->number; + if (voodoo.tex_UMA) + { + tex_found[id][node->tmu^1] = node->number; + return; + } + } + } + } + node = node->pNext; + } + + LRDP(" | | | +- Done.\n | | +- GetTexInfo end\n"); +} + +//**************************************************************** +// ChooseBestTmu - chooses the best TMU to load to (the one with the most memory) + +int ChooseBestTmu (int tmu1, int tmu2) +{ + if (!fullscreen) return tmu1; + if (voodoo.tex_UMA) return 0; + + if (tmu1 >= voodoo.num_tmu) return tmu2; + if (tmu2 >= voodoo.num_tmu) return tmu1; + + if (voodoo.tex_max_addr[tmu1]-voodoo.tmem_ptr[tmu1] > + voodoo.tex_max_addr[tmu2]-voodoo.tmem_ptr[tmu2]) + return tmu1; + else + return tmu2; +} + +//**************************************************************** +// SelectTBuffTex - select texture from texture buffer +static void SelectTBuffTex(TBUFF_COLOR_IMAGE * pTBuffTex) +{ + FRDP ("SelectTBuffTex: tex: %d, tmu: %d, tile: %d\n", rdp.tex, pTBuffTex->tmu, pTBuffTex->tile); + grTexSource(pTBuffTex->tile, pTBuffTex->tex_addr, GR_MIPMAPLEVELMASK_BOTH, &(pTBuffTex->info) ); +} + +//**************************************************************** +// TexCache - does texture loading after combiner is set +int SwapTextureBuffer(); +void TexCache () +{ + LRDP(" |-+ TexCache called\n"); + +#ifdef TEXTURE_FILTER /* Hiroshi Morii */ // POSTNAPALM + if (settings.ghq_use && settings.ghq_hirs_dump) { + /* Force reload hi-res textures. Useful for texture artists */ + if (CheckKeyPressed(G64_VK_R, 0x0001)) { + if (ext_ghq_reloadhirestex()) ClearCache(); + } + /* Turn on texture dump */ + else if (CheckKeyPressed(G64_VK_D, 0x0001)) { + extern void DisplayLoadProgress(const wchar_t *format, ...); + ghq_dmptex_toggle_key = !ghq_dmptex_toggle_key; + if (ghq_dmptex_toggle_key) { + DisplayLoadProgress(L"Texture dump - ON\n"); + ClearCache(); + wxThread::Sleep(1000); + } else { + DisplayLoadProgress(L"Texture dump - OFF\n"); + wxThread::Sleep(1000); + } + } + } +#endif + + if (rdp.tex & 1) + GetTexInfo (0, rdp.cur_tile); + if (rdp.tex & 2) + GetTexInfo (1, rdp.cur_tile+1); + + TBUFF_COLOR_IMAGE * aTBuff[2] = {0, 0}; + if (rdp.aTBuffTex[0]) + aTBuff[rdp.aTBuffTex[0]->tile] = rdp.aTBuffTex[0]; + if (rdp.aTBuffTex[1]) + aTBuff[rdp.aTBuffTex[1]->tile] = rdp.aTBuffTex[1]; + +#define TMUMODE_NORMAL 0 +#define TMUMODE_PASSTHRU 1 +#define TMUMODE_NONE 2 + + int tmu_0, tmu_1; + int tmu_0_mode=0, tmu_1_mode=0; + + // Select the best TMUs to use (removed 3 tmu support, unnecessary) + if (rdp.tex == 3) // T0 and T1 + { + tmu_0 = 0; + tmu_1 = 1; + } + else if (rdp.tex == 2) // T1 + { + if (tex_found[1][0] != -1) // T1 found in tmu 0 + tmu_1 = 0; + else if (tex_found[1][1] != -1) // T1 found in tmu 1 + tmu_1 = 1; + else // T1 not found + tmu_1 = ChooseBestTmu (0, 1); + + tmu_0 = !tmu_1; + tmu_0_mode = (tmu_0==1)?TMUMODE_NONE:TMUMODE_PASSTHRU; + } + else if (rdp.tex == 1) // T0 + { + if (tex_found[0][0] != -1) // T0 found in tmu 0 + tmu_0 = 0; + else if (tex_found[0][1] != -1) // T0 found in tmu 1 + tmu_0 = 1; + else // T0 not found + tmu_0 = ChooseBestTmu (0, 1); + + tmu_1 = !tmu_0; + tmu_1_mode = (tmu_1==1)?TMUMODE_NONE:TMUMODE_PASSTHRU; + } + else // no texture + { + tmu_0 = 0; + tmu_0_mode = TMUMODE_NONE; + tmu_1 = 0; + tmu_1_mode = TMUMODE_NONE; + } + + FRDP (" | |-+ Modes set:\n | | |- tmu_0 = %d\n | | |- tmu_1 = %d\n", + tmu_0, tmu_1); + FRDP (" | | |- tmu_0_mode = %d\n | | |- tmu_1_mode = %d\n", + tmu_0_mode, tmu_1_mode); + + if (tmu_0_mode == TMUMODE_PASSTHRU) { + cmb.tmu0_func = cmb.tmu0_a_func = GR_COMBINE_FUNCTION_SCALE_OTHER; + cmb.tmu0_fac = cmb.tmu0_a_fac = GR_COMBINE_FACTOR_ONE; + if (cmb.tex_cmb_ext_use) + { + cmb.t0c_ext_a = GR_CMBX_OTHER_TEXTURE_RGB; + cmb.t0c_ext_a_mode = GR_FUNC_MODE_X; + cmb.t0c_ext_b = GR_CMBX_LOCAL_TEXTURE_RGB; + cmb.t0c_ext_b_mode = GR_FUNC_MODE_ZERO; + cmb.t0c_ext_c = GR_CMBX_ZERO; + cmb.t0c_ext_c_invert = 1; + cmb.t0c_ext_d = GR_CMBX_ZERO; + cmb.t0c_ext_d_invert = 0; + cmb.t0a_ext_a = GR_CMBX_OTHER_TEXTURE_ALPHA; + cmb.t0a_ext_a_mode = GR_FUNC_MODE_X; + cmb.t0a_ext_b = GR_CMBX_LOCAL_TEXTURE_ALPHA; + cmb.t0a_ext_b_mode = GR_FUNC_MODE_ZERO; + cmb.t0a_ext_c = GR_CMBX_ZERO; + cmb.t0a_ext_c_invert = 1; + cmb.t0a_ext_d = GR_CMBX_ZERO; + cmb.t0a_ext_d_invert = 0; + } + } + else if (tmu_0_mode == TMUMODE_NONE) { + cmb.tmu0_func = cmb.tmu0_a_func = GR_COMBINE_FUNCTION_NONE; + cmb.tmu0_fac = cmb.tmu0_a_fac = GR_COMBINE_FACTOR_NONE; + if (cmb.tex_cmb_ext_use) + { + cmb.t0c_ext_a = GR_CMBX_LOCAL_TEXTURE_RGB; + cmb.t0c_ext_a_mode = GR_FUNC_MODE_ZERO; + cmb.t0c_ext_b = GR_CMBX_LOCAL_TEXTURE_RGB; + cmb.t0c_ext_b_mode = GR_FUNC_MODE_ZERO; + cmb.t0c_ext_c = GR_CMBX_ZERO; + cmb.t0c_ext_c_invert = 0; + cmb.t0c_ext_d = GR_CMBX_ZERO; + cmb.t0c_ext_d_invert = 0; + cmb.t0a_ext_a = GR_CMBX_LOCAL_TEXTURE_ALPHA; + cmb.t0a_ext_a_mode = GR_FUNC_MODE_ZERO; + cmb.t0a_ext_b = GR_CMBX_LOCAL_TEXTURE_ALPHA; + cmb.t0a_ext_b_mode = GR_FUNC_MODE_ZERO; + cmb.t0a_ext_c = GR_CMBX_ZERO; + cmb.t0a_ext_c_invert = 0; + cmb.t0a_ext_d = GR_CMBX_ZERO; + cmb.t0a_ext_d_invert = 0; + } + } + if (tmu_1_mode == TMUMODE_PASSTHRU) { + cmb.tmu1_func = cmb.tmu1_a_func = GR_COMBINE_FUNCTION_SCALE_OTHER; + cmb.tmu1_fac = cmb.tmu1_a_fac = GR_COMBINE_FACTOR_ONE; + if (cmb.tex_cmb_ext_use) + { + cmb.t1c_ext_a = GR_CMBX_OTHER_TEXTURE_RGB; + cmb.t1c_ext_a_mode = GR_FUNC_MODE_X; + cmb.t1c_ext_b = GR_CMBX_LOCAL_TEXTURE_RGB; + cmb.t1c_ext_b_mode = GR_FUNC_MODE_ZERO; + cmb.t1c_ext_c = GR_CMBX_ZERO; + cmb.t1c_ext_c_invert = 1; + cmb.t1c_ext_d = GR_CMBX_ZERO; + cmb.t1c_ext_d_invert = 0; + cmb.t1a_ext_a = GR_CMBX_OTHER_TEXTURE_ALPHA; + cmb.t1a_ext_a_mode = GR_FUNC_MODE_X; + cmb.t1a_ext_b = GR_CMBX_LOCAL_TEXTURE_ALPHA; + cmb.t1a_ext_b_mode = GR_FUNC_MODE_ZERO; + cmb.t1a_ext_c = GR_CMBX_ZERO; + cmb.t1a_ext_c_invert = 1; + cmb.t1a_ext_d = GR_CMBX_ZERO; + cmb.t1a_ext_d_invert = 0; + } + } + else if (tmu_1_mode == TMUMODE_NONE) { + cmb.tmu1_func = cmb.tmu1_a_func = GR_COMBINE_FUNCTION_NONE; + cmb.tmu1_fac = cmb.tmu1_a_fac = GR_COMBINE_FACTOR_NONE; + if (cmb.tex_cmb_ext_use) + { + cmb.t1c_ext_a = GR_CMBX_LOCAL_TEXTURE_RGB; + cmb.t1c_ext_a_mode = GR_FUNC_MODE_ZERO; + cmb.t1c_ext_b = GR_CMBX_LOCAL_TEXTURE_RGB; + cmb.t1c_ext_b_mode = GR_FUNC_MODE_ZERO; + cmb.t1c_ext_c = GR_CMBX_ZERO; + cmb.t1c_ext_c_invert = 0; + cmb.t1c_ext_d = GR_CMBX_ZERO; + cmb.t1c_ext_d_invert = 0; + cmb.t1a_ext_a = GR_CMBX_LOCAL_TEXTURE_ALPHA; + cmb.t1a_ext_a_mode = GR_FUNC_MODE_ZERO; + cmb.t1a_ext_b = GR_CMBX_LOCAL_TEXTURE_ALPHA; + cmb.t1a_ext_b_mode = GR_FUNC_MODE_ZERO; + cmb.t1a_ext_c = GR_CMBX_ZERO; + cmb.t1a_ext_c_invert = 0; + cmb.t1a_ext_d = GR_CMBX_ZERO; + cmb.t1a_ext_d_invert = 0; + } + } + + // little change to make single-tmu cards look better, use first texture no matter what + + if (voodoo.num_tmu == 1) + { + if (rdp.best_tex == 0) + { + cmb.tmu0_func = cmb.tmu0_a_func = GR_COMBINE_FUNCTION_LOCAL; + cmb.tmu0_fac = cmb.tmu0_a_fac = GR_COMBINE_FACTOR_NONE; + tmu_0 = 0; + tmu_1 = 1; + } + else + { + cmb.tmu1_func = cmb.tmu1_a_func = GR_COMBINE_FUNCTION_LOCAL; + cmb.tmu1_fac = cmb.tmu1_a_fac = GR_COMBINE_FACTOR_NONE; + tmu_1 = 0; + tmu_0 = 1; + } + } + + + rdp.t0 = tmu_0; + rdp.t1 = tmu_1; + + // SET the combiner + if (fullscreen) + { + if (rdp.allow_combine) + { + // Now actually combine + if (cmb.cmb_ext_use) + { + LRDP(" | | | |- combiner extension\n"); + if (!(cmb.cmb_ext_use & COMBINE_EXT_COLOR)) + ColorCombinerToExtension (); + if (!(cmb.cmb_ext_use & COMBINE_EXT_ALPHA)) + AlphaCombinerToExtension (); + cmb.grColorCombineExt(cmb.c_ext_a, cmb.c_ext_a_mode, + cmb.c_ext_b, cmb.c_ext_b_mode, + cmb.c_ext_c, cmb.c_ext_c_invert, + cmb.c_ext_d, cmb.c_ext_d_invert, 0, 0); + cmb.grAlphaCombineExt(cmb.a_ext_a, cmb.a_ext_a_mode, + cmb.a_ext_b, cmb.a_ext_b_mode, + cmb.a_ext_c, cmb.a_ext_c_invert, + cmb.a_ext_d, cmb.a_ext_d_invert, 0, 0); + } + else + { + grColorCombine (cmb.c_fnc, cmb.c_fac, cmb.c_loc, cmb.c_oth, FXFALSE); + grAlphaCombine (cmb.a_fnc, cmb.a_fac, cmb.a_loc, cmb.a_oth, FXFALSE); + } + grConstantColorValue (cmb.ccolor); + grAlphaBlendFunction (cmb.abf1, cmb.abf2, GR_BLEND_ZERO, GR_BLEND_ZERO); + if (!rdp.tex) //nothing more to do + return; + } + + if (tmu_1 < voodoo.num_tmu) + { + if (cmb.tex_cmb_ext_use) + { + LRDP(" | | | |- combiner extension tmu1\n"); + if (!(cmb.tex_cmb_ext_use & TEX_COMBINE_EXT_COLOR)) + TexColorCombinerToExtension (GR_TMU1); + if (!(cmb.tex_cmb_ext_use & TEX_COMBINE_EXT_ALPHA)) + TexAlphaCombinerToExtension (GR_TMU1); + cmb.grTexColorCombineExt(tmu_1, cmb.t1c_ext_a, cmb.t1c_ext_a_mode, + cmb.t1c_ext_b, cmb.t1c_ext_b_mode, + cmb.t1c_ext_c, cmb.t1c_ext_c_invert, + cmb.t1c_ext_d, cmb.t1c_ext_d_invert, 0, 0); + cmb.grTexAlphaCombineExt(tmu_1, cmb.t1a_ext_a, cmb.t1a_ext_a_mode, + cmb.t1a_ext_b, cmb.t1a_ext_b_mode, + cmb.t1a_ext_c, cmb.t1a_ext_c_invert, + cmb.t1a_ext_d, cmb.t1a_ext_d_invert, 0, 0); + cmb.grConstantColorValueExt(tmu_1, cmb.tex_ccolor); + } + else + { + grTexCombine (tmu_1, cmb.tmu1_func, cmb.tmu1_fac, cmb.tmu1_a_func, cmb.tmu1_a_fac, cmb.tmu1_invert, cmb.tmu1_a_invert); + if (cmb.combine_ext) + cmb.grConstantColorValueExt(tmu_1, 0); + } + grTexDetailControl (tmu_1, cmb.dc1_lodbias, cmb.dc1_detailscale, cmb.dc1_detailmax); + grTexLodBiasValue (tmu_1, cmb.lodbias1); + } + if (tmu_0 < voodoo.num_tmu) + { + if (cmb.tex_cmb_ext_use) + { + LRDP(" | | | |- combiner extension tmu0\n"); + if (!(cmb.tex_cmb_ext_use & TEX_COMBINE_EXT_COLOR)) + TexColorCombinerToExtension (GR_TMU0); + if (!(cmb.tex_cmb_ext_use & TEX_COMBINE_EXT_ALPHA)) + TexAlphaCombinerToExtension (GR_TMU0); + cmb.grTexColorCombineExt(tmu_0, cmb.t0c_ext_a, cmb.t0c_ext_a_mode, + cmb.t0c_ext_b, cmb.t0c_ext_b_mode, + cmb.t0c_ext_c, cmb.t0c_ext_c_invert, + cmb.t0c_ext_d, cmb.t0c_ext_d_invert, 0, 0); + cmb.grTexAlphaCombineExt(tmu_0, cmb.t0a_ext_a, cmb.t0a_ext_a_mode, + cmb.t0a_ext_b, cmb.t0a_ext_b_mode, + cmb.t0a_ext_c, cmb.t0a_ext_c_invert, + cmb.t0a_ext_d, cmb.t0a_ext_d_invert, 0, 0); + cmb.grConstantColorValueExt(tmu_0, cmb.tex_ccolor); + } + else + { + grTexCombine (tmu_0, cmb.tmu0_func, cmb.tmu0_fac, cmb.tmu0_a_func, cmb.tmu0_a_fac, cmb.tmu0_invert, cmb.tmu0_a_invert); + if (cmb.combine_ext) + cmb.grConstantColorValueExt(tmu_0, 0); + } + grTexDetailControl (tmu_0, cmb.dc0_lodbias, cmb.dc0_detailscale, cmb.dc0_detailmax); + grTexLodBiasValue (tmu_0, cmb.lodbias0); + } + } + + if ((rdp.tex & 1) && tmu_0 < voodoo.num_tmu) + { + if (aTBuff[0] && aTBuff[0]->cache) + { + LRDP(" | |- Hires tex T0 found in cache.\n"); + if (fullscreen) + { + rdp.cur_cache[0] = aTBuff[0]->cache; + rdp.cur_cache[0]->last_used = frame_count; + rdp.cur_cache[0]->uses = rdp.debug_n; + } + } + else if (tex_found[0][tmu_0] != -1) + { + LRDP(" | |- T0 found in cache.\n"); + if (fullscreen) + { + CACHE_LUT *cache = voodoo.tex_UMA?&rdp.cache[0][tex_found[0][0]]:&rdp.cache[tmu_0][tex_found[0][tmu_0]]; + rdp.cur_cache_n[0] = tex_found[0][tmu_0]; + rdp.cur_cache[0] = cache; + rdp.cur_cache[0]->last_used = frame_count; + rdp.cur_cache[0]->uses = rdp.debug_n; + grTexSource (tmu_0, + (voodoo.tex_min_addr[tmu_0] + cache->tmem_addr), + GR_MIPMAPLEVELMASK_BOTH, + &cache->t_info); + } + } + else + LoadTex (0, tmu_0); + } + if ((rdp.tex & 2) && tmu_1 < voodoo.num_tmu) + { + if (aTBuff[1] && aTBuff[1]->cache) + { + LRDP(" | |- Hires tex T1 found in cache.\n"); + if (fullscreen) + { + rdp.cur_cache[1] = aTBuff[1]->cache; + rdp.cur_cache[1]->last_used = frame_count; + rdp.cur_cache[1]->uses = rdp.debug_n; + } + } + else if (tex_found[1][tmu_1] != -1) + { + LRDP(" | |- T1 found in cache.\n"); + if (fullscreen) + { + CACHE_LUT *cache = voodoo.tex_UMA?&rdp.cache[0][tex_found[1][0]]:&rdp.cache[tmu_1][tex_found[1][tmu_1]]; + rdp.cur_cache_n[1] = tex_found[1][tmu_1]; + rdp.cur_cache[1] = cache; + rdp.cur_cache[1]->last_used = frame_count; + rdp.cur_cache[1]->uses = rdp.debug_n; + grTexSource (tmu_1, + (voodoo.tex_min_addr[tmu_1] + cache->tmem_addr), + GR_MIPMAPLEVELMASK_BOTH, + &cache->t_info); + } + } + else + LoadTex (1, tmu_1); + } + + if (fullscreen) + { + for (int i=0; i<2; i++) + { + int tmu; + if (i==0) tmu=tmu_0; + else if (i==1) tmu=tmu_1; + + if (tmu >= voodoo.num_tmu) continue; + + int tile = rdp.cur_tile + i; + + if (settings.filtering == 0) + { + int filter = (rdp.filter_mode!=2)?GR_TEXTUREFILTER_POINT_SAMPLED:GR_TEXTUREFILTER_BILINEAR; + grTexFilterMode (tmu, filter, filter); + } + else + { + int filter = (settings.filtering==1)?GR_TEXTUREFILTER_BILINEAR:GR_TEXTUREFILTER_POINT_SAMPLED; + grTexFilterMode (tmu, filter, filter); + } + + if (rdp.cur_cache[i]) + { + wxUint32 mode_s, mode_t; + int clamp_s, clamp_t; + if (rdp.force_wrap && !rdp.texrecting) + { + clamp_s = rdp.tiles[tile].clamp_s && rdp.tiles[tile].lr_s-rdp.tiles[tile].ul_s < 256; + clamp_t = rdp.tiles[tile].clamp_t && rdp.tiles[tile].lr_t-rdp.tiles[tile].ul_t < 256; + } + else + { + clamp_s = (rdp.tiles[tile].clamp_s || rdp.tiles[tile].mask_s == 0) && + rdp.tiles[tile].lr_s-rdp.tiles[tile].ul_s < 256; + clamp_t = (rdp.tiles[tile].clamp_t || rdp.tiles[tile].mask_t == 0) && + rdp.tiles[tile].lr_t-rdp.tiles[tile].ul_t < 256; + } + + if (rdp.cur_cache[i]->f_mirror_s) + mode_s = GR_TEXTURECLAMP_MIRROR_EXT; + else if (rdp.cur_cache[i]->f_wrap_s) + mode_s = GR_TEXTURECLAMP_WRAP; + else if (clamp_s) + mode_s = GR_TEXTURECLAMP_CLAMP; + else + { + if (rdp.tiles[tile].mirror_s && voodoo.sup_mirroring) + mode_s = GR_TEXTURECLAMP_MIRROR_EXT; + else + mode_s = GR_TEXTURECLAMP_WRAP; + } + + if (rdp.cur_cache[i]->f_mirror_t) + mode_t = GR_TEXTURECLAMP_MIRROR_EXT; + else if (rdp.cur_cache[i]->f_wrap_t) + mode_t = GR_TEXTURECLAMP_WRAP; + else if (clamp_t) + mode_t = GR_TEXTURECLAMP_CLAMP; + else + { + if (rdp.tiles[tile].mirror_t && voodoo.sup_mirroring) + mode_t = GR_TEXTURECLAMP_MIRROR_EXT; + else + mode_t = GR_TEXTURECLAMP_WRAP; + } + + grTexClampMode (tmu, + mode_s, + mode_t); + } + if (aTBuff[i] && (rdp.tex&(i+1))) + SelectTBuffTex(aTBuff[i]); + } + } + + LRDP(" | +- TexCache End\n"); +} + + +#ifdef TEXTURE_FILTER +/** cite from RiceVideo */ +inline wxUint32 CalculateDXT(wxUint32 txl2words) +{ + if( txl2words == 0 ) return 1; + else return (2048+txl2words-1)/txl2words; +} + +wxUint32 sizeBytes[4] = {0,1,2,4}; + +inline wxUint32 Txl2Words(wxUint32 width, wxUint32 size) +{ + if( size == 0 ) + return max(1, width/16); + else + return max(1, width*sizeBytes[size]/8); +} + +inline wxUint32 ReverseDXT(wxUint32 val, wxUint32 lrs, wxUint32 width, wxUint32 size) +{ + if( val == 0x800 ) return 1; + + int low = 2047/val; + if( CalculateDXT(low) > val ) low++; + int high = 2047/(val-1); + + if( low == high ) return low; + + for( int i=low; i<=high; i++ ) + { + if( Txl2Words(width, size) == (wxUint32)i ) + return i; + } + + return (low+high)/2; +} +/** end RiceVideo cite */ +#endif + +//**************************************************************** +// LoadTex - does the actual texture loading after everything is prepared + +void LoadTex (int id, int tmu) +{ + FRDP (" | |-+ LoadTex (id: %d, tmu: %d)\n", id, tmu); + + int td = rdp.cur_tile + id; + int lod, aspect; + CACHE_LUT *cache; + + if (texinfo[id].width < 0 || texinfo[id].height < 0) + return; + + // Clear the cache if it's full + if (rdp.n_cached[tmu] >= MAX_CACHE) + { + LRDP("Cache count reached, clearing...\n"); + ClearCache (); + if (id == 1 && rdp.tex == 3) + LoadTex (0, rdp.t0); + } + + // Get this cache object + cache = voodoo.tex_UMA?&rdp.cache[0][rdp.n_cached[0]]:&rdp.cache[tmu][rdp.n_cached[tmu]]; + rdp.cur_cache[id] = cache; + rdp.cur_cache_n[id] = rdp.n_cached[tmu]; + + //!Hackalert + //GoldenEye water texture. It has CI format in fact, but the game set it to RGBA + if ((settings.hacks&hack_GoldenEye) && rdp.tiles[td].format == 0 && rdp.tlut_mode == 2 && rdp.tiles[td].size == 2) + { + rdp.tiles[td].format = 2; + rdp.tiles[td].size = 1; + } + + // Set the data + cache->line = rdp.tiles[td].line; + cache->addr = rdp.addr[rdp.tiles[td].t_mem]; + cache->crc = texinfo[id].crc; + cache->palette = rdp.tiles[td].palette; + cache->width = rdp.tiles[td].width; + cache->height = rdp.tiles[td].height; + cache->format = rdp.tiles[td].format; + cache->size = rdp.tiles[td].size; + cache->tmem_addr = voodoo.tmem_ptr[tmu]; + cache->set_by = rdp.timg.set_by; + cache->texrecting = rdp.texrecting; + cache->last_used = frame_count; + cache->uses = rdp.debug_n; + cache->flags = texinfo[id].flags; + cache->f_mirror_s = FALSE; + cache->f_mirror_t = FALSE; + cache->f_wrap_s = FALSE; + cache->f_wrap_t = FALSE; + cache->is_hires_tex = FALSE; +#ifdef TEXTURE_FILTER + cache->ricecrc = texinfo[id].ricecrc; +#endif + + // Add this cache to the list + AddToList (&cachelut[cache->crc>>16], cache->crc, wxPtrToUInt(cache), tmu, rdp.n_cached[tmu]); + + // temporary + cache->t_info.format = GR_TEXFMT_ARGB_1555; + + // Calculate lod and aspect + wxUint32 size_x = rdp.tiles[td].width; + wxUint32 size_y = rdp.tiles[td].height; + + // make size_x and size_y both powers of two + if (!voodoo.sup_large_tex) + { + if (size_x > 256) size_x = 256; + if (size_y > 256) size_y = 256; + } + + int shift; + for (shift=0; (1<scale = 256.0f; + break; + case 2: + lod = GR_LOD_LOG2_2; + cache->scale = 128.0f; + break; + case 4: + lod = GR_LOD_LOG2_4; + cache->scale = 64.0f; + break; + case 8: + lod = GR_LOD_LOG2_8; + cache->scale = 32.0f; + break; + case 16: + lod = GR_LOD_LOG2_16; + cache->scale = 16.0f; + break; + case 32: + lod = GR_LOD_LOG2_32; + cache->scale = 8.0f; + break; + case 64: + lod = GR_LOD_LOG2_64; + cache->scale = 4.0f; + break; + case 128: + lod = GR_LOD_LOG2_128; + cache->scale = 2.0f; + break; + case 256: + lod = GR_LOD_LOG2_256; + cache->scale = 1.0f; + break; + case 512: + lod = GR_LOD_LOG2_512; + cache->scale = 0.5f; + break; + default: + lod = GR_LOD_LOG2_1024; + cache->scale = 0.25f; + break; + } + + // Calculate the aspect ratio + if (size_x >= size_y) + { + int ratio = size_x / size_y; + switch (ratio) + { + case 1: + aspect = GR_ASPECT_LOG2_1x1; + cache->scale_x = 1.0f; + cache->scale_y = 1.0f; + break; + case 2: + aspect = GR_ASPECT_LOG2_2x1; + cache->scale_x = 1.0f; + cache->scale_y = 0.5f; + real_y >>= 1; + break; + case 4: + aspect = GR_ASPECT_LOG2_4x1; + cache->scale_x = 1.0f; + cache->scale_y = 0.25f; + real_y >>= 2; + break; + default: + aspect = GR_ASPECT_LOG2_8x1; + cache->scale_x = 1.0f; + cache->scale_y = 0.125f; + real_y >>= 3; + break; + } + } + else + { + int ratio = size_y / size_x; + switch (ratio) + { + case 2: + aspect = GR_ASPECT_LOG2_1x2; + cache->scale_x = 0.5f; + cache->scale_y = 1.0f; + real_x >>= 1; + break; + case 4: + aspect = GR_ASPECT_LOG2_1x4; + cache->scale_x = 0.25f; + cache->scale_y = 1.0f; + real_x >>= 2; + break; + default: + aspect = GR_ASPECT_LOG2_1x8; + cache->scale_x = 0.125f; + cache->scale_y = 1.0f; + real_x >>= 3; + break; + } + } + + if (real_x != cache->width || real_y != cache->height) + { + cache->scale_x *= (float)cache->width / (float)real_x; + cache->scale_y *= (float)cache->height / (float)real_y; + } + + int splits = texinfo[id].splits; + cache->splits = texinfo[id].splits; + cache->splitheight = real_y / cache->splits; + if (cache->splitheight < texinfo[id].splitheight) + cache->splitheight = texinfo[id].splitheight; + + // ** Calculate alignment values + int wid = cache->width; + int hei = cache->height; + + if (splits > 1) + { + wid = texinfo[id].real_image_width; + hei = texinfo[id].real_image_height; + } + + cache->c_off = cache->scale * 0.5f; + if (wid != 1) cache->c_scl_x = cache->scale; + else cache->c_scl_x = 0.0f; + if (hei != 1) cache->c_scl_y = cache->scale; + else cache->c_scl_y = 0.0f; + // ** + + wxUint32 mod, modcolor, modcolor1, modcolor2, modfactor; + if (id == 0) + { + mod = cmb.mod_0; + modcolor = cmb.modcolor_0; + modcolor1 = cmb.modcolor1_0; + modcolor2 = cmb.modcolor2_0; + modfactor = cmb.modfactor_0; + } + else + { + mod = cmb.mod_1; + modcolor = cmb.modcolor_1; + modcolor1 = cmb.modcolor1_1; + modcolor2 = cmb.modcolor2_1; + modfactor = cmb.modfactor_1; + } + + wxUint16 tmp_pal[256]; + int modifyPalette = (mod && (cache->format == 2) && (rdp.tlut_mode == 2)); + + if (modifyPalette) + { + memcpy(tmp_pal, rdp.pal_8, 512); + ModifyPalette(mod, modcolor, modcolor1, modfactor); + } + + cache->mod = mod; + cache->mod_color = modcolor; + cache->mod_color1 = modcolor1; + cache->mod_factor = modfactor; + + for (int t = 0; t < 2; t++) { + if (rdp.aTBuffTex[t] && rdp.aTBuffTex[t]->tile == id) //texture buffer will be used instead of frame buffer texture + { + rdp.aTBuffTex[t]->cache = cache; + FRDP("tbuff_tex selected: %d, tile=%d\n", t, id); + return; + } + } + + wxUint32 result = 0; // keep =0 so it doesn't mess up on the first split + + texture = tex1; + + // Hiroshi Morii + // NOTE: Loading Hi-res texture packs and filtering should be done + // before the texture is modified with color palettes, etc. + // + // Since the internal texture identification needs Glide64CRC, (RiceCRC + // doesn't always return unique values) it seems reasonable that the + // extra CRC calculation for hires textures should be executed only + // when we get passed the texture ram cache and texture buffers for + // minimal calculation overhead. + // +#ifdef TEXTURE_FILTER // Hiroshi Morii + GHQTexInfo ghqTexInfo; + memset(&ghqTexInfo, 0, sizeof(GHQTexInfo)); + wxUint32 g64_crc = cache->crc; + if (settings.ghq_use) + { + int bpl; + wxUint8* addr = (wxUint8*)(gfx.RDRAM+rdp.addr[rdp.tiles[td].t_mem]); + int tile_width = texinfo[id].width; + int tile_height = texinfo[id].height; + LOAD_TILE_INFO &info = rdp.load_info[rdp.tiles[td].t_mem]; + if (rdp.timg.set_by == 1) + { + bpl = info.tex_width << info.tex_size >> 1; + addr += (info.tile_ul_t * bpl) + (((info.tile_ul_s<>1); + + tile_width = min(info.tile_width, info.tex_width); + if (info.tex_size > rdp.tiles[td].size) + tile_width <<= info.tex_size - rdp.tiles[td].size; + + if (rdp.tiles[td].lr_t > rdp.bg_image_height) + tile_height = rdp.bg_image_height - rdp.tiles[td].ul_t; + else + tile_height = info.tile_height; + } + else + { + if (rdp.tiles[td].size == 3) + bpl = rdp.tiles[td].line << 4; + else if (info.dxt == 0) + bpl = rdp.tiles[td].line << 3; + else { + wxUint32 dxt = info.dxt; + if (dxt > 1) + dxt = ReverseDXT(dxt, info.tile_width, texinfo[id].width, rdp.tiles[td].size); + bpl = dxt << 3; + } + } + + // wxUint8* addr = (wxUint8*)(gfx.RDRAM+rdp.addr[rdp.tiles[td].t_mem] + (rdp.tiles[td].ul_t * bpl) + (((rdp.tiles[td].ul_s<>1)); + wxUint8 * paladdr = 0; + wxUint16 * palette = 0; + if ((rdp.tiles[td].size < 2) && (rdp.tlut_mode || rdp.tiles[td].format == 2)) + { + if (rdp.tiles[td].size == 1) + paladdr = (wxUint8*)(rdp.pal_8_rice); + else if (settings.ghq_hirs_altcrc) + paladdr = (wxUint8*)(rdp.pal_8_rice + (rdp.tiles[td].palette << 5)); + else + paladdr = (wxUint8*)(rdp.pal_8_rice + (rdp.tiles[td].palette << 4)); + palette = (rdp.pal_8 + (rdp.tiles[td].palette << 4)); + } + + // XXX: Special combiner modes are ignored for hires textures + // for now. Come back to this later!! The following is needed + // for (2xSai, hq4x, etc) enhanced/filtered textures. + g64_crc = CRC32( g64_crc, &cache->mod, 4 ); + g64_crc = CRC32( g64_crc, &cache->mod_color, 4 ); + g64_crc = CRC32( g64_crc, &cache->mod_color1, 4 ); + //g64_crc = CRC32( g64_crc, &cache->mod_color2, 4 ); // not used? + g64_crc = CRC32( g64_crc, &cache->mod_factor, 4 ); + + cache->ricecrc = ext_ghq_checksum(addr, tile_width, tile_height, (unsigned short)(rdp.tiles[td].format << 8 | rdp.tiles[td].size), bpl, paladdr); + FRDP("CI RICE CRC. format: %d, size: %d, CRC: %08lx, PalCRC: %08lx\n", rdp.tiles[td].format, rdp.tiles[td].size, (wxUint32)(cache->ricecrc&0xFFFFFFFF), (wxUint32)(cache->ricecrc>>32)); + if (ext_ghq_hirestex((uint64)g64_crc, cache->ricecrc, palette, &ghqTexInfo)) + { + cache->is_hires_tex = ghqTexInfo.is_hires_tex; + if (!ghqTexInfo.is_hires_tex && aspect != ghqTexInfo.aspectRatioLog2) + ghqTexInfo.data = 0; //if aspects of current texture and found filtered texture are different, texture must be filtered again. + } + } + + + // ** handle texture splitting ** + if (ghqTexInfo.data) + ;//do nothing + else +#endif + if (splits > 1) + { + cache->scale_y = 0.125f; + + int i; + for (i=0; isplitheight * 256; // start lower + start_dst <<= HIWORD(result); // 1st time, result is set to 0, but start_dst is 0 anyway so it doesn't matter + + int start_src = i * 256; // start 256 more to the right + start_src = start_src << (rdp.tiles[td].size) >> 1; + if (rdp.tiles[td].size == 3) + start_src >>= 1; + + result = load_table[rdp.tiles[td].size][rdp.tiles[td].format] + (wxPtrToUInt(texture)+start_dst, wxPtrToUInt(rdp.tmem)+(rdp.tiles[td].t_mem<<3)+start_src, + texinfo[id].wid_64, texinfo[id].height, texinfo[id].line, real_x, td); + + wxUint32 size = HIWORD(result); + // clamp so that it looks somewhat ok when wrapping + if (size == 1) + Clamp16bT (wxPtrToUInt(texture)+start_dst, texinfo[id].height, real_x, cache->splitheight); + else if (size != 2) + Clamp8bT (wxPtrToUInt(texture)+start_dst, texinfo[id].height, real_x, cache->splitheight); + else + Clamp32bT (wxPtrToUInt(texture)+start_dst, texinfo[id].height, real_x, cache->splitheight); + } + } + // ** end texture splitting ** + else + { + result = load_table[rdp.tiles[td].size][rdp.tiles[td].format] + (wxPtrToUInt(texture), wxPtrToUInt(rdp.tmem)+(rdp.tiles[td].t_mem<<3), + texinfo[id].wid_64, texinfo[id].height, texinfo[id].line, real_x, td); + + wxUint32 size = HIWORD(result); + + int min_x, min_y; + if (rdp.tiles[td].mask_s != 0) + min_x = min((int)real_x, 1< texinfo[id].width) + { + if (size == 1) + Clamp16bS (wxPtrToUInt(texture), texinfo[id].width, min_x, real_x, texinfo[id].height); + else if (size != 2) + Clamp8bS (wxPtrToUInt(texture), texinfo[id].width, min_x, real_x, texinfo[id].height); + else + Clamp32bS (wxPtrToUInt(texture), texinfo[id].width, min_x, real_x, texinfo[id].height); + } + + if (texinfo[id].width < (int)real_x) + { + if (rdp.tiles[td].mirror_s) + { + if (size == 1) + Mirror16bS (wxPtrToUInt(texture), rdp.tiles[td].mask_s, + real_x, real_x, texinfo[id].height); + else if (size != 2) + Mirror8bS (wxPtrToUInt(texture), rdp.tiles[td].mask_s, + real_x, real_x, texinfo[id].height); + else + Mirror32bS (wxPtrToUInt(texture), rdp.tiles[td].mask_s, + real_x, real_x, texinfo[id].height); + } + else + { + if (size == 1) + Wrap16bS (wxPtrToUInt(texture), rdp.tiles[td].mask_s, + real_x, real_x, texinfo[id].height); + else if (size != 2) + Wrap8bS (wxPtrToUInt(texture), rdp.tiles[td].mask_s, + real_x, real_x, texinfo[id].height); + else + Wrap32bS (wxPtrToUInt(texture), rdp.tiles[td].mask_s, + real_x, real_x, texinfo[id].height); + } + } + + if (min_y > texinfo[id].height) + { + if (size == 1) + Clamp16bT (wxPtrToUInt(texture), texinfo[id].height, real_x, min_y); + else if (size != 2) + Clamp8bT (wxPtrToUInt(texture), texinfo[id].height, real_x, min_y); + else + Clamp32bT (wxPtrToUInt(texture), texinfo[id].height, real_x, min_y); + } + + if (texinfo[id].height < (int)real_y) + { + if (rdp.tiles[td].mirror_t) + { + if (size == 1) + Mirror16bT (wxPtrToUInt(texture), rdp.tiles[td].mask_t, + real_y, real_x); + else if (size != 2) + Mirror8bT (wxPtrToUInt(texture), rdp.tiles[td].mask_t, + real_y, real_x); + else + Mirror32bT (wxPtrToUInt(texture), rdp.tiles[td].mask_t, + real_y, real_x); + } + else + { + if (size == 1) + Wrap16bT (wxPtrToUInt(texture), rdp.tiles[td].mask_t, + real_y, real_x); + else if (size != 2) + Wrap8bT (wxPtrToUInt(texture), rdp.tiles[td].mask_t, + real_y, real_x); + else + Wrap32bT (wxPtrToUInt(texture), rdp.tiles[td].mask_t, + real_y, real_x); + } + } + } + + if (modifyPalette) + { + memcpy(rdp.pal_8, tmp_pal, 512); + } + +#ifdef TEXTURE_FILTER + if (mod && !modifyPalette && !ghqTexInfo.data) +#else + if (mod && !modifyPalette) +#endif + { + // Convert the texture to ARGB 4444 + if (LOWORD(result) == GR_TEXFMT_ARGB_1555) + { + TexConv_ARGB1555_ARGB4444 (wxPtrToUInt(texture), wxPtrToUInt(tex2), real_x, real_y); + texture = tex2; + } + else if (LOWORD(result) == GR_TEXFMT_ALPHA_INTENSITY_88) + { + TexConv_AI88_ARGB4444 (wxPtrToUInt(texture), wxPtrToUInt(tex2), real_x, real_y); + texture = tex2; + } + else if (LOWORD(result) == GR_TEXFMT_ALPHA_INTENSITY_44) + { + TexConv_AI44_ARGB4444 (wxPtrToUInt(texture), wxPtrToUInt(tex2), real_x, real_y); + texture = tex2; + } + else if (LOWORD(result) == GR_TEXFMT_ALPHA_8) + { + TexConv_A8_ARGB4444 (wxPtrToUInt(texture), wxPtrToUInt(tex2), real_x, real_y); + texture = tex2; + } + /*else if (LOWORD(result) == GR_TEXFMT_ARGB_4444) + { + memcpy (tex2, texture, (real_x*real_y) << 1); + texture = tex2; + }*/ // we can skip memcpy since "texture" won't be swapped between "tex1" and "tex2" after this. + // Hiroshi Morii + + result = (1 << 16) | GR_TEXFMT_ARGB_4444; + + // Now convert the color to the same + modcolor = ((modcolor & 0xF0000000) >> 16) | ((modcolor & 0x00F00000) >> 12) | + ((modcolor & 0x0000F000) >> 8) | ((modcolor & 0x000000F0) >> 4); + modcolor1 = ((modcolor1 & 0xF0000000) >> 16) | ((modcolor1 & 0x00F00000) >> 12) | + ((modcolor1 & 0x0000F000) >> 8) | ((modcolor1 & 0x000000F0) >> 4); + modcolor2 = ((modcolor2 & 0xF0000000) >> 16) | ((modcolor2 & 0x00F00000) >> 12) | + ((modcolor2 & 0x0000F000) >> 8) | ((modcolor2 & 0x000000F0) >> 4); + + int size = (real_x * real_y) << 1; + + switch (mod) + { + case TMOD_TEX_INTER_COLOR_USING_FACTOR: + mod_tex_inter_color_using_factor ((wxUint16*)texture, size, modcolor, modfactor); + break; + case TMOD_TEX_INTER_COL_USING_COL1: + mod_tex_inter_col_using_col1 ((wxUint16*)texture, size, modcolor, modcolor1); + break; + case TMOD_FULL_COLOR_SUB_TEX: + mod_full_color_sub_tex ((wxUint16*)texture, size, modcolor); + break; + case TMOD_COL_INTER_COL1_USING_TEX: + mod_col_inter_col1_using_tex ((wxUint16*)texture, size, modcolor, modcolor1); + break; + case TMOD_COL_INTER_COL1_USING_TEXA: + mod_col_inter_col1_using_texa ((wxUint16*)texture, size, modcolor, modcolor1); + break; + case TMOD_COL_INTER_COL1_USING_TEXA__MUL_TEX: + mod_col_inter_col1_using_texa__mul_tex ((wxUint16*)texture, size, modcolor, modcolor1); + break; + case TMOD_COL_INTER_TEX_USING_TEXA: + mod_col_inter_tex_using_texa ((wxUint16*)texture, size, modcolor); + break; + case TMOD_COL2_INTER__COL_INTER_COL1_USING_TEX__USING_TEXA: + mod_col2_inter__col_inter_col1_using_tex__using_texa ((wxUint16*)texture, size, modcolor, modcolor1, modcolor2); + break; + case TMOD_TEX_SCALE_FAC_ADD_FAC: + mod_tex_scale_fac_add_fac ((wxUint16*)texture, size, modfactor); + break; + case TMOD_TEX_SUB_COL_MUL_FAC_ADD_TEX: + mod_tex_sub_col_mul_fac_add_tex ((wxUint16*)texture, size, modcolor, modfactor); + break; + case TMOD_TEX_SCALE_COL_ADD_COL: + mod_tex_scale_col_add_col ((wxUint16*)texture, size, modcolor, modcolor1); + break; + case TMOD_TEX_ADD_COL: + mod_tex_add_col ((wxUint16*)texture, size, modcolor); + break; + case TMOD_TEX_SUB_COL: + mod_tex_sub_col ((wxUint16*)texture, size, modcolor); + break; + case TMOD_TEX_SUB_COL_MUL_FAC: + mod_tex_sub_col_mul_fac ((wxUint16*)texture, size, modcolor, modfactor); + break; + case TMOD_COL_INTER_TEX_USING_COL1: + mod_col_inter_tex_using_col1 ((wxUint16*)texture, size, modcolor, modcolor1); + break; + case TMOD_COL_MUL_TEXA_ADD_TEX: + mod_col_mul_texa_add_tex((wxUint16*)texture, size, modcolor); + break; + case TMOD_COL_INTER_TEX_USING_TEX: + mod_col_inter_tex_using_tex ((wxUint16*)texture, size, modcolor); + break; + case TMOD_TEX_INTER_NOISE_USING_COL: + mod_tex_inter_noise_using_col ((wxUint16*)texture, size, modcolor); + break; + case TMOD_TEX_INTER_COL_USING_TEXA: + mod_tex_inter_col_using_texa ((wxUint16*)texture, size, modcolor); + break; + case TMOD_TEX_MUL_COL: + mod_tex_mul_col ((wxUint16*)texture, size, modcolor); + break; + case TMOD_TEX_SCALE_FAC_ADD_COL: + mod_tex_scale_fac_add_col ((wxUint16*)texture, size, modcolor, modfactor); + break; + default: + ; + } + } + + + cache->t_info.format = LOWORD(result); + + cache->realwidth = real_x; + cache->realheight = real_y; + cache->lod = lod; + cache->aspect = aspect; + + if (fullscreen) + { +#ifdef TEXTURE_FILTER // Hiroshi Morii + if (settings.ghq_use) + { + if (!ghqTexInfo.data && ghq_dmptex_toggle_key) { + unsigned char *tmpbuf = (unsigned char*)texture; + int tmpwidth = real_x; + if (texinfo[id].splits > 1) { + int dstpixoffset, srcpixoffset; + int shift; + switch (LOWORD(result) & 0x7fff) { // XXX is there a better way of determining the pixel color depth? + case GR_TEXFMT_ARGB_8888: + shift = 3; + break; + case GR_TEXFMT_ALPHA_INTENSITY_44: + case GR_TEXFMT_ALPHA_8: + shift = 0; + break; + default: + shift = 1; + } + tmpwidth = texinfo[id].real_image_width; + tmpbuf = (unsigned char*)malloc((256*256)<<3); // XXX performance overhead + for (int i = 0; i < cache->splitheight; i++) { + dstpixoffset = texinfo[id].real_image_width * i; + srcpixoffset = 256 * i; + for (int k = 0; k < texinfo[id].splits; k++) { + memcpy(tmpbuf + (dstpixoffset << shift), texture + (srcpixoffset << shift), (256 << shift)); + dstpixoffset += 256; + srcpixoffset += (256 * cache->splitheight); + } + } + } + ext_ghq_dmptx(tmpbuf, (int)texinfo[id].real_image_width, (int)texinfo[id].real_image_height, (int)tmpwidth, (unsigned short)LOWORD(result), (unsigned short)((cache->format << 8) | (cache->size)), cache->ricecrc); + if (tmpbuf != texture && tmpbuf) { + free(tmpbuf); + } + } + + if (!ghqTexInfo.data) + if (!settings.ghq_enht_nobg || !rdp.texrecting || (texinfo[id].splits == 1 && texinfo[id].width <= 256)) + ext_ghq_txfilter((unsigned char*)texture, (int)real_x, (int)real_y, LOWORD(result), (uint64)g64_crc, &ghqTexInfo); + + if (ghqTexInfo.data) + { + if (ghqTexInfo.aspectRatioLog2 < GR_ASPECT_LOG2_1x8 || + ghqTexInfo.aspectRatioLog2 > GR_ASPECT_LOG2_8x1 || + ghqTexInfo.largeLodLog2 > GR_LOD_LOG2_2048 || + ghqTexInfo.largeLodLog2 < GR_LOD_LOG2_1) + { + /* invalid dimensions */ + } + else + { + texture = (wxUint8 *)ghqTexInfo.data; + lod = ghqTexInfo.largeLodLog2; + int splits = cache->splits; + if (ghqTexInfo.is_hires_tex) + { + if (ghqTexInfo.tiles/*ghqTexInfo.untiled_width > max_tex_size*/) + { + cache->scale = 1.0f; + cache->c_off = 0.5f; + cache->splits = ghqTexInfo.tiles;//((hirestex.width-1)>>8)+1; + cache->splitheight = ghqTexInfo.untiled_height; + cache->scale_x = 1.0f; + cache->scale_y = float(ghqTexInfo.untiled_height*ghqTexInfo.tiles)/float(ghqTexInfo.width);//*sy; + if (splits == 1) + { + int shift; + for (shift=9; (1<> 8); + cache->c_scl_x *= mult; + cache->c_scl_y *= mult; + } + else + { + int tile_width = rdp.tiles[td].width; + if (rdp.timg.set_by == 1) + tile_width = rdp.load_info[rdp.tiles[td].t_mem].tex_width; + float mult = float(ghqTexInfo.untiled_width/tile_width); + cache->c_scl_x *= mult; + cache->c_scl_y *= mult; + } + } + else + { + cache->scale = 256.0f / float(1<c_off = cache->scale * 0.5f; + cache->splits = 1; + if (aspect != ghqTexInfo.aspectRatioLog2) + { + float mscale = float(1< abs(ghqTexInfo.aspectRatioLog2)) + { + cache->c_scl_y *= mscale; + cache->c_scl_x *= mscale; + } + /* + else + { + if (rdp.tiles[td].mirror_s && sup_mirroring) + cache->f_mirror_s = TRUE; + if (rdp.tiles[td].mirror_t && sup_mirroring) + cache->f_mirror_t = TRUE; + //cache->c_scl_y /= mscale; + //cache->c_scl_x /= mscale; + } + */ + if (ghqTexInfo.aspectRatioLog2 >= 0) + { + cache->scale_x = 1.0f; + cache->scale_y = 1.0f/float(1<scale_y = 1.0f; + cache->scale_x = 1.0f/float(1<<(-ghqTexInfo.aspectRatioLog2)); + } + } + else if (splits > 1) + { + cache->c_scl_x /= splits; + cache->c_scl_y /= splits; + } + } + if (voodoo.sup_mirroring) + { + if (rdp.tiles[td].mirror_s && texinfo[id].tile_width == 2*texinfo[id].width) + cache->f_mirror_s = TRUE; + else if (texinfo[id].tile_width >= 2*texinfo[id].width) + cache->f_wrap_s = TRUE; + if (rdp.tiles[td].mirror_t && texinfo[id].tile_height == 2*texinfo[id].height) + cache->f_mirror_t = TRUE; + else if (texinfo[id].tile_height >= 2*texinfo[id].height) + cache->f_wrap_t = TRUE; + if (cache->f_mirror_s && cache->f_mirror_t) + { + cache->c_scl_x *= 2.0f; + cache->c_scl_y *= 2.0f; + } + } + aspect = ghqTexInfo.aspectRatioLog2; + cache->lod = lod; + cache->aspect = aspect; + } + else + { + //cache->scale = 256.0f / float(1<c_off = 128.0f / float(1<t_info.format = ghqTexInfo.format; + cache->realwidth = real_x; + cache->realheight = real_y; + } + } + } +#endif + + // Load the texture into texture memory + GrTexInfo *t_info = &cache->t_info; + t_info->data = texture; + t_info->smallLodLog2 = lod; + t_info->largeLodLog2 = lod; + t_info->aspectRatioLog2 = aspect; + + wxUint32 texture_size = grTexTextureMemRequired (GR_MIPMAPLEVELMASK_BOTH, t_info); + + // Check for 2mb boundary + // Hiroshi Morii required only for V1,Rush, and V2 + if (voodoo.has_2mb_tex_boundary && + (voodoo.tmem_ptr[tmu] < TEXMEM_2MB_EDGE) && (voodoo.tmem_ptr[tmu]+texture_size > TEXMEM_2MB_EDGE)) + { + voodoo.tmem_ptr[tmu] = TEXMEM_2MB_EDGE; + cache->tmem_addr = voodoo.tmem_ptr[tmu]; + } + + // Check for end of memory (too many textures to fit, clear cache) + if (voodoo.tmem_ptr[tmu]+texture_size >= voodoo.tex_max_addr[tmu]) + { + LRDP("Cache size reached, clearing...\n"); + ClearCache (); + + if (id == 1 && rdp.tex == 3) + LoadTex (0, rdp.t0); + + LoadTex (id, tmu); + return; + // DON'T CONTINUE (already done) + } + + wxUint32 tex_addr = GetTexAddr(tmu, texture_size); + grTexDownloadMipMap (tmu, + tex_addr, + GR_MIPMAPLEVELMASK_BOTH, + t_info); + + grTexSource (tmu, + tex_addr, + GR_MIPMAPLEVELMASK_BOTH, + t_info); + } + + LRDP(" | | +- LoadTex end\n"); +} diff --git a/Source/Glide64/TexCache.h b/Source/Glide64/TexCache.h new file mode 100644 index 000000000..e2b2f3fa9 --- /dev/null +++ b/Source/Glide64/TexCache.h @@ -0,0 +1,49 @@ +/* +* Glide64 - Glide video plugin for Nintendo 64 emulators. +* Copyright (c) 2002 Dave2001 +* Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski +* +* 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 +* 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 +*/ + +//**************************************************************** +// +// Glide64 - Glide Plugin for Nintendo 64 emulators +// Project started on December 29th, 2001 +// +// Authors: +// Dave2001, original author, founded the project in 2001, left it in 2002 +// Gugaman, joined the project in 2002, left it in 2002 +// Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002 +// Hiroshi 'KoolSmoky' Morii, joined the project in 2007 +// +//**************************************************************** +// +// To modify Glide64: +// * Write your name and (optional)email, commented by your work, so I know who did it, and so that you can find which parts you modified when it comes time to send it to me. +// * Do NOT send me the whole project or file that you modified. Take out your modified code sections, and tell me where to put them. If people sent the whole thing, I would have many different versions, but no idea how to combine them all. +// +//**************************************************************** + +#ifndef TEXCACHE_H +#define TEXCACHE_H + +void TexCacheInit (); +void TexCache (); +void ClearCache (); + +extern wxUint8 * texture_buffer; + +#endif //TEXCACHE_H diff --git a/Source/Glide64/TexConv.h b/Source/Glide64/TexConv.h new file mode 100644 index 000000000..eb910e808 --- /dev/null +++ b/Source/Glide64/TexConv.h @@ -0,0 +1,75 @@ +/* +* Glide64 - Glide video plugin for Nintendo 64 emulators. +* Copyright (c) 2002 Dave2001 +* Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski +* +* 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 +* 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 +*/ + +//**************************************************************** +// +// Glide64 - Glide Plugin for Nintendo 64 emulators +// Project started on December 29th, 2001 +// +// Authors: +// Dave2001, original author, founded the project in 2001, left it in 2002 +// Gugaman, joined the project in 2002, left it in 2002 +// Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002 +// Hiroshi 'KoolSmoky' Morii, joined the project in 2007 +// +//**************************************************************** +// +// To modify Glide64: +// * Write your name and (optional)email, commented by your work, so I know who did it, and so that you can find which parts you modified when it comes time to send it to me. +// * Do NOT send me the whole project or file that you modified. Take out your modified code sections, and tell me where to put them. If people sent the whole thing, I would have many different versions, but no idea how to combine them all. +// +//**************************************************************** + +extern "C" void asmTexConv_ARGB1555_ARGB4444(wxUIntPtr src, wxUIntPtr dst, int size); +extern "C" void asmTexConv_AI88_ARGB4444(wxUIntPtr src, wxUIntPtr dst, int size); +extern "C" void asmTexConv_AI44_ARGB4444(wxUIntPtr src, wxUIntPtr dst, int size); +extern "C" void asmTexConv_A8_ARGB4444(wxUIntPtr src, wxUIntPtr dst, int size); + +void TexConv_ARGB1555_ARGB4444 (wxUIntPtr src, wxUIntPtr dst, int width, int height) +{ + int size = (width * height) >> 1; // Hiroshi Morii + // 2 pixels are converted in one loop + // NOTE: width * height must be a multiple of 2 + asmTexConv_ARGB1555_ARGB4444(src, dst, size); +} + +void TexConv_AI88_ARGB4444 (wxUIntPtr src, wxUIntPtr dst, int width, int height) +{ + int size = (width * height) >> 1; // Hiroshi Morii + // 2 pixels are converted in one loop + // NOTE: width * height must be a multiple of 2 + asmTexConv_AI88_ARGB4444(src, dst, size); +} + +void TexConv_AI44_ARGB4444 (wxUIntPtr src, wxUIntPtr dst, int width, int height) +{ + int size = (width * height) >> 2; // Hiroshi Morii + // 4 pixels are converted in one loop + // NOTE: width * height must be a multiple of 4 + asmTexConv_AI44_ARGB4444(src, dst, size); +} + +void TexConv_A8_ARGB4444 (wxUIntPtr src, wxUIntPtr dst, int width, int height) +{ + int size = (width * height) >> 2; // Hiroshi Morii + // 4 pixels are converted in one loop + // NOTE: width * height must be a multiple of 4 + asmTexConv_A8_ARGB4444(src, dst, size); +} diff --git a/Source/Glide64/TexLoad.h b/Source/Glide64/TexLoad.h new file mode 100644 index 000000000..98c1606da --- /dev/null +++ b/Source/Glide64/TexLoad.h @@ -0,0 +1,76 @@ +/* +* Glide64 - Glide video plugin for Nintendo 64 emulators. +* Copyright (c) 2002 Dave2001 +* Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski +* +* 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 +* 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 +*/ + +//**************************************************************** +// +// Glide64 - Glide Plugin for Nintendo 64 emulators +// Project started on December 29th, 2001 +// +// Authors: +// Dave2001, original author, founded the project in 2001, left it in 2002 +// Gugaman, joined the project in 2002, left it in 2002 +// Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002 +// Hiroshi 'KoolSmoky' Morii, joined the project in 2007 +// +//**************************************************************** +// +// To modify Glide64: +// * Write your name and (optional)email, commented by your work, so I know who did it, and so that you can find which parts you modified when it comes time to send it to me. +// * Do NOT send me the whole project or file that you modified. Take out your modified code sections, and tell me where to put them. If people sent the whole thing, I would have many different versions, but no idea how to combine them all. +// +//**************************************************************** + +#include "TexLoad4b.h" +#include "TexLoad8b.h" +#include "TexLoad16b.h" +#include "TexLoad32b.h" + +wxUint32 LoadNone (wxUIntPtr dst, wxUIntPtr src, int wid_64, int height, int line, int real_width, int tile) +{ + memset (texture, 0, 4096*4); + return (1 << 16) | GR_TEXFMT_ARGB_1555; +} + +typedef wxUint32 (*texfunc)(wxUIntPtr, wxUIntPtr, int, int, int, int, int); +texfunc load_table [4][5] = { // [size][format] +{ Load4bSelect, + LoadNone, + Load4bCI, + Load4bIA, + Load4bI }, + +{ Load8bCI, + LoadNone, + Load8bCI, + Load8bIA, + Load8bI }, + +{ Load16bRGBA, + Load16bYUV, + Load16bRGBA, + Load16bIA, + LoadNone }, + +{ Load32bRGBA, + LoadNone, + LoadNone, + LoadNone, + LoadNone } +}; diff --git a/Source/Glide64/TexLoad16b.h b/Source/Glide64/TexLoad16b.h new file mode 100644 index 000000000..6beb5522d --- /dev/null +++ b/Source/Glide64/TexLoad16b.h @@ -0,0 +1,136 @@ +/* +* Glide64 - Glide video plugin for Nintendo 64 emulators. +* Copyright (c) 2002 Dave2001 +* Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski +* +* 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 +* 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 +*/ + +//**************************************************************** +// +// Glide64 - Glide Plugin for Nintendo 64 emulators +// Project started on December 29th, 2001 +// +// Authors: +// Dave2001, original author, founded the project in 2001, left it in 2002 +// Gugaman, joined the project in 2002, left it in 2002 +// Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002 +// Hiroshi 'KoolSmoky' Morii, joined the project in 2007 +// +//**************************************************************** +// +// To modify Glide64: +// * Write your name and (optional)email, commented by your work, so I know who did it, and so that you can find which parts you modified when it comes time to send it to me. +// * Do NOT send me the whole project or file that you modified. Take out your modified code sections, and tell me where to put them. If people sent the whole thing, I would have many different versions, but no idea how to combine them all. +// +//**************************************************************** + +extern "C" void asmLoad16bRGBA (wxUIntPtr src, wxUIntPtr dst, int wid_64, int height, int line, int ext); +extern "C" void asmLoad16bIA (wxUIntPtr src, wxUIntPtr dst, int wid_64, int height, int line, int ext); + + +//**************************************************************** +// Size: 2, Format: 0 +// + +wxUint32 Load16bRGBA (wxUIntPtr dst, wxUIntPtr src, int wid_64, int height, int line, int real_width, int tile) +{ + if (wid_64 < 1) wid_64 = 1; + if (height < 1) height = 1; + int ext = (real_width - (wid_64 << 2)) << 1; + + asmLoad16bRGBA(src, dst, wid_64, height, line, ext); + + return (1 << 16) | GR_TEXFMT_ARGB_1555; +} + +//**************************************************************** +// Size: 2, Format: 3 +// + +wxUint32 Load16bIA (wxUIntPtr dst, wxUIntPtr src, int wid_64, int height, int line, int real_width, int tile) +{ + if (wid_64 < 1) wid_64 = 1; + if (height < 1) height = 1; + int ext = (real_width - (wid_64 << 2)) << 1; + + asmLoad16bIA(src, dst, wid_64, height, line, ext); + + return (1 << 16) | GR_TEXFMT_ALPHA_INTENSITY_88; +} + +//**************************************************************** +// Size: 2, Format: 1 +// + +wxUint16 yuv_to_rgb565(wxUint8 y, wxUint8 u, wxUint8 v) +{ + //* + float r = y + (1.370705f * (v-128)); + float g = y - (0.698001f * (v-128)) - (0.337633f * (u-128)); + float b = y + (1.732446f * (u-128)); + r *= 0.125f; + g *= 0.25f; + b *= 0.125f; + //clipping the result + if (r > 31) r = 31; + if (g > 63) g = 63; + if (b > 31) b = 31; + if (r < 0) r = 0; + if (g < 0) g = 0; + if (b < 0) b = 0; + wxUint16 c = (wxUint16)(((wxUint16)(r) << 11) | + ((wxUint16)(g) << 5) | + (wxUint16)(b) ); + return c; + //*/ + /* + const wxUint32 c = y - 16; + const wxUint32 d = u - 128; + const wxUint32 e = v - 128; + + wxUint32 r = (298 * c + 409 * e + 128) & 0xf800; + wxUint32 g = ((298 * c - 100 * d - 208 * e + 128) >> 5) & 0x7e0; + wxUint32 b = ((298 * c + 516 * d + 128) >> 11) & 0x1f; + + WORD texel = (WORD)(r | g | b); + + return texel; + */ +} + +//**************************************************************** +// Size: 2, Format: 1 +// + +wxUint32 Load16bYUV (wxUIntPtr dst, wxUIntPtr src, int wid_64, int height, int line, int real_width, int tile) +{ + wxUint32 * mb = (wxUint32*)(gfx.RDRAM+rdp.addr[rdp.tiles[tile].t_mem]); //pointer to the macro block + wxUint16 * tex = (wxUint16*)dst; + wxUint16 i; + for (i = 0; i < 128; i++) + { + wxUint32 t = mb[i]; //each wxUint32 contains 2 pixels + wxUint8 y1 = (wxUint8)t&0xFF; + wxUint8 v = (wxUint8)(t>>8)&0xFF; + wxUint8 y0 = (wxUint8)(t>>16)&0xFF; + wxUint8 u = (wxUint8)(t>>24)&0xFF; + wxUint16 c = yuv_to_rgb565(y0, u, v); + *(tex++) = c; + c = yuv_to_rgb565(y1, u, v); + *(tex++) = c; + } + return (1 << 16) | GR_TEXFMT_RGB_565; +} diff --git a/Source/Glide64/TexLoad32b.h b/Source/Glide64/TexLoad32b.h new file mode 100644 index 000000000..0217dbbbd --- /dev/null +++ b/Source/Glide64/TexLoad32b.h @@ -0,0 +1,177 @@ +/* +* Glide64 - Glide video plugin for Nintendo 64 emulators. +* Copyright (c) 2002 Dave2001 +* Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski +* +* 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 +* 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 +*/ + +//**************************************************************** +// +// Glide64 - Glide Plugin for Nintendo 64 emulators +// Project started on December 29th, 2001 +// +// Authors: +// Dave2001, original author, founded the project in 2001, left it in 2002 +// Gugaman, joined the project in 2002, left it in 2002 +// Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002 +// Hiroshi 'KoolSmoky' Morii, joined the project in 2007 +// +//**************************************************************** +// +// To modify Glide64: +// * Write your name and (optional)email, commented by your work, so I know who did it, and so that you can find which parts you modified when it comes time to send it to me. +// * Do NOT send me the whole project or file that you modified. Take out your modified code sections, and tell me where to put them. If people sent the whole thing, I would have many different versions, but no idea how to combine them all. +// +//**************************************************************** + +//**************************************************************** +// Size: 2, Format: 0 +// +// Load 32bit RGBA texture +// Based on sources of angrylion's software plugin. +// +wxUint32 Load32bRGBA (wxUIntPtr dst, wxUIntPtr src, int wid_64, int height, int line, int real_width, int tile) +{ + if (height < 1) height = 1; + const wxUint16 *tmem16 = (wxUint16*)rdp.tmem; + const wxUint32 tbase = (src - (wxUIntPtr)rdp.tmem) >> 1; + const wxUint32 width = max(1, wid_64 << 1); + const int ext = real_width - width; + line = width + (line>>2); + wxUint32 s, t, c; + wxUint32 * tex = (wxUint32*)dst; + wxUint16 rg, ba; + for (t = 0; t < (wxUint32)height; t++) + { + wxUint32 tline = tbase + line * t; + wxUint32 xorval = (t & 1) ? 3 : 1; + for (s = 0; s < width; s++) + { + wxUint32 taddr = ((tline + s) ^ xorval) & 0x3ff; + rg = tmem16[taddr]; + ba = tmem16[taddr|0x400]; + c = ((ba&0xFF)<<24) | (rg << 8) | (ba>>8); + *tex++ = c; + } + tex += ext; + } + int id = tile - rdp.cur_tile; + wxUint32 mod = (id == 0) ? cmb.mod_0 : cmb.mod_1; + if (mod || !voodoo.sup_32bit_tex) + { + //convert to ARGB_4444 + const wxUint32 tex_size = real_width * height; + tex = (wxUint32 *)dst; + wxUint16 *tex16 = (wxUint16*)dst; + wxUint16 a, r, g, b; + for (wxUint32 i = 0; i < tex_size; i++) { + c = tex[i]; + a = (c >> 28) & 0xF; + r = (c >> 20) & 0xF; + g = (c >> 12) & 0xF; + b = (c >> 4) & 0xF; + tex16[i] = (a <<12) | (r << 8) | (g << 4) | b; + } + return (1 << 16) | GR_TEXFMT_ARGB_4444; + } + return (2 << 16) | GR_TEXFMT_ARGB_8888; +} + +//**************************************************************** +// LoadTile for 32bit RGBA texture +// Based on sources of angrylion's software plugin. +// +void LoadTile32b (wxUint32 tile, wxUint32 ul_s, wxUint32 ul_t, wxUint32 width, wxUint32 height) +{ + const wxUint32 line = rdp.tiles[tile].line << 2; + const wxUint32 tbase = rdp.tiles[tile].t_mem << 2; + const wxUint32 addr = rdp.timg.addr >> 2; + const wxUint32* src = (const wxUint32*)gfx.RDRAM; + wxUint16 *tmem16 = (wxUint16*)rdp.tmem; + wxUint32 c, ptr, tline, s, xorval; + + for (wxUint32 j = 0; j < height; j++) + { + tline = tbase + line * j; + s = ((j + ul_t) * rdp.timg.width) + ul_s; + xorval = (j & 1) ? 3 : 1; + for (wxUint32 i = 0; i < width; i++) + { + c = src[addr + s + i]; + ptr = ((tline + i) ^ xorval) & 0x3ff; + tmem16[ptr] = c >> 16; + tmem16[ptr|0x400] = c & 0xffff; + } + } +} + +//**************************************************************** +// LoadBlock for 32bit RGBA texture +// Based on sources of angrylion's software plugin. +// +void LoadBlock32b(wxUint32 tile, wxUint32 ul_s, wxUint32 ul_t, wxUint32 lr_s, wxUint32 dxt) +{ + const wxUint32 * src = (const wxUint32*)gfx.RDRAM; + const wxUint32 tb = rdp.tiles[tile].t_mem << 2; + const wxUint32 tiwindwords = rdp.timg.width; + const wxUint32 slindwords = ul_s; + const wxUint32 line = rdp.tiles[tile].line << 2; + + wxUint16 *tmem16 = (wxUint16*)rdp.tmem; + wxUint32 addr = rdp.timg.addr >> 2; + wxUint32 width = (lr_s - ul_s + 1) << 2; + if (width & 7) + width = (width & (~7)) + 8; + + if (dxt != 0) + { + wxUint32 j= 0; + wxUint32 t = 0; + wxUint32 oldt = 0; + wxUint32 ptr; + + addr += (ul_t * tiwindwords) + slindwords; + wxUint32 c = 0; + for (wxUint32 i = 0; i < width; i += 2) + { + oldt = t; + t = ((j >> 11) & 1) ? 3 : 1; + if (t != oldt) + i += line; + ptr = ((tb + i) ^ t) & 0x3ff; + c = src[addr + i]; + tmem16[ptr] = c >> 16; + tmem16[ptr|0x400] = c & 0xffff; + ptr = ((tb+ i + 1) ^ t) & 0x3ff; + c = src[addr + i + 1]; + tmem16[ptr] = c >> 16; + tmem16[ptr|0x400] = c & 0xffff; + j += dxt; + } + } + else + { + addr += (ul_t * tiwindwords) + slindwords; + wxUint32 c, ptr; + for (wxUint32 i = 0; i < width; i ++) + { + ptr = ((tb + i) ^ 1) & 0x3ff; + c = src[addr + i]; + tmem16[ptr] = c >> 16; + tmem16[ptr|0x400] = c & 0xffff; + } + } +} diff --git a/Source/Glide64/TexLoad4b.h b/Source/Glide64/TexLoad4b.h new file mode 100644 index 000000000..1ed02751d --- /dev/null +++ b/Source/Glide64/TexLoad4b.h @@ -0,0 +1,114 @@ +/* +* Glide64 - Glide video plugin for Nintendo 64 emulators. +* Copyright (c) 2002 Dave2001 +* Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski +* +* 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 +* 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 +*/ + +//**************************************************************** +// +// Glide64 - Glide Plugin for Nintendo 64 emulators +// Project started on December 29th, 2001 +// +// Authors: +// Dave2001, original author, founded the project in 2001, left it in 2002 +// Gugaman, joined the project in 2002, left it in 2002 +// Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002 +// Hiroshi 'KoolSmoky' Morii, joined the project in 2007 +// +//**************************************************************** +// +// To modify Glide64: +// * Write your name and (optional)email, commented by your work, so I know who did it, and so that you can find which parts you modified when it comes time to send it to me. +// * Do NOT send me the whole project or file that you modified. Take out your modified code sections, and tell me where to put them. If people sent the whole thing, I would have many different versions, but no idea how to combine them all. +// +//**************************************************************** + +extern "C" void asmLoad4bCI (wxUIntPtr src, wxUIntPtr dst, int wid_64, int height, int line, int ext, wxUIntPtr pal); +extern "C" void asmLoad4bIAPal (wxUIntPtr src, wxUIntPtr dst, int wid_64, int height, int line, int ext, wxUIntPtr pal); +extern "C" void asmLoad4bIA (wxUIntPtr src, wxUIntPtr dst, int wid_64, int height, int line, int ext); +extern "C" void asmLoad4bI (wxUIntPtr src, int dst, wxUIntPtr wid_64, int height, int line, int ext); + +//**************************************************************** +// Size: 0, Format: 2 + +wxUint32 Load4bCI (wxUIntPtr dst, wxUIntPtr src, int wid_64, int height, int line, int real_width, int tile) +{ + if (wid_64 < 1) wid_64 = 1; + if (height < 1) height = 1; + int ext = (real_width - (wid_64 << 4)) << 1; + + if (rdp.tlut_mode == 0) + { + //in tlut DISABLE mode load CI texture as plain intensity texture instead of palette dereference. + //Thanks to angrylion for the advice + asmLoad4bI (src, dst, wid_64, height, line, ext); + return /*(0 << 16) | */GR_TEXFMT_ALPHA_INTENSITY_44; + } + + wxUIntPtr pal = wxPtrToUInt(rdp.pal_8 + (rdp.tiles[tile].palette << 4)); + if (rdp.tlut_mode == 2) + { + asmLoad4bCI (src, dst, wid_64, height, line, ext, pal); + return (1 << 16) | GR_TEXFMT_ARGB_1555; + } + + asmLoad4bIAPal (src, dst, wid_64, height, line, ext, pal); + return (1 << 16) | GR_TEXFMT_ALPHA_INTENSITY_88; +} + +//**************************************************************** +// Size: 0, Format: 3 +// +// ** BY GUGAMAN ** + +wxUint32 Load4bIA (wxUIntPtr dst, wxUIntPtr src, int wid_64, int height, int line, int real_width, int tile) +{ + if (rdp.tlut_mode != 0) + return Load4bCI (dst, src, wid_64, height, line, real_width, tile); + + if (wid_64 < 1) wid_64 = 1; + if (height < 1) height = 1; + int ext = (real_width - (wid_64 << 4)); + asmLoad4bIA (src, dst, wid_64, height, line, ext); + return /*(0 << 16) | */GR_TEXFMT_ALPHA_INTENSITY_44; +} + +//**************************************************************** +// Size: 0, Format: 4 + +wxUint32 Load4bI (wxUIntPtr dst, wxUIntPtr src, int wid_64, int height, int line, int real_width, int tile) +{ + if (rdp.tlut_mode != 0) + return Load4bCI (dst, src, wid_64, height, line, real_width, tile); + + if (wid_64 < 1) wid_64 = 1; + if (height < 1) height = 1; + int ext = (real_width - (wid_64 << 4)); + asmLoad4bI (src, dst, wid_64, height, line, ext); + return /*(0 << 16) | */GR_TEXFMT_ALPHA_INTENSITY_44; +} + +//**************************************************************** +// Size: 0, Format: 0 + +wxUint32 Load4bSelect (wxUIntPtr dst, wxUIntPtr src, int wid_64, int height, int line, int real_width, int tile) +{ + if (rdp.tlut_mode == 0) + return Load4bI (dst, src, wid_64, height, line, real_width, tile); + + return Load4bCI (dst, src, wid_64, height, line, real_width, tile); +} diff --git a/Source/Glide64/TexLoad8b.h b/Source/Glide64/TexLoad8b.h new file mode 100644 index 000000000..fbd68fe05 --- /dev/null +++ b/Source/Glide64/TexLoad8b.h @@ -0,0 +1,103 @@ +/* +* Glide64 - Glide video plugin for Nintendo 64 emulators. +* Copyright (c) 2002 Dave2001 +* Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski +* +* 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 +* 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 +*/ + +//**************************************************************** +// +// Glide64 - Glide Plugin for Nintendo 64 emulators +// Project started on December 29th, 2001 +// +// Authors: +// Dave2001, original author, founded the project in 2001, left it in 2002 +// Gugaman, joined the project in 2002, left it in 2002 +// Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002 +// Hiroshi 'KoolSmoky' Morii, joined the project in 2007 +// +//**************************************************************** +// +// To modify Glide64: +// * Write your name and (optional)email, commented by your work, so I know who did it, and so that you can find which parts you modified when it comes time to send it to me. +// * Do NOT send me the whole project or file that you modified. Take out your modified code sections, and tell me where to put them. If people sent the whole thing, I would have many different versions, but no idea how to combine them all. +// +//**************************************************************** + +extern "C" void asmLoad8bCI (wxUIntPtr src, wxUIntPtr dst, int wid_64, int height, int line, int ext, wxUIntPtr pal); +extern "C" void asmLoad8bIA8 (wxUIntPtr src, wxUIntPtr dst, int wid_64, int height, int line, int ext, wxUIntPtr pal); +extern "C" void asmLoad8bIA4 (wxUIntPtr src, wxUIntPtr dst, int wid_64, int height, int line, int ext); +extern "C" void asmLoad8bI (wxUIntPtr src, int dst, wxUIntPtr wid_64, int height, int line, int ext); + +//**************************************************************** +// Size: 1, Format: 2 +// + +wxUint32 Load8bCI (wxUIntPtr dst, wxUIntPtr src, int wid_64, int height, int line, int real_width, int tile) +{ + if (wid_64 < 1) wid_64 = 1; + if (height < 1) height = 1; + int ext = (real_width - (wid_64 << 3)); + wxUIntPtr pal = wxPtrToUInt(rdp.pal_8); + + switch (rdp.tlut_mode) { + case 0: //palette is not used + //in tlut DISABLE mode load CI texture as plain intensity texture instead of palette dereference. + //Thanks to angrylion for the advice + asmLoad8bI (src, dst, wid_64, height, line, ext); + return /*(0 << 16) | */GR_TEXFMT_ALPHA_8; + case 2: //color palette + ext <<= 1; + asmLoad8bCI (src, dst, wid_64, height, line, ext, pal); + return (1 << 16) | GR_TEXFMT_ARGB_1555; + default: //IA palette + ext <<= 1; + asmLoad8bIA8 (src, dst, wid_64, height, line, ext, pal); + return (1 << 16) | GR_TEXFMT_ALPHA_INTENSITY_88; + } +} + +//**************************************************************** +// Size: 1, Format: 3 +// + +wxUint32 Load8bIA (wxUIntPtr dst, wxUIntPtr src, int wid_64, int height, int line, int real_width, int tile) +{ + if (rdp.tlut_mode != 0) + return Load8bCI (dst, src, wid_64, height, line, real_width, tile); + + if (wid_64 < 1) wid_64 = 1; + if (height < 1) height = 1; + int ext = (real_width - (wid_64 << 3)); + asmLoad8bIA4 (src, dst, wid_64, height, line, ext); + return /*(0 << 16) | */GR_TEXFMT_ALPHA_INTENSITY_44; +} + +//**************************************************************** +// Size: 1, Format: 4 +// + +wxUint32 Load8bI (wxUIntPtr dst, wxUIntPtr src, int wid_64, int height, int line, int real_width, int tile) +{ + if (rdp.tlut_mode != 0) + return Load8bCI (dst, src, wid_64, height, line, real_width, tile); + + if (wid_64 < 1) wid_64 = 1; + if (height < 1) height = 1; + int ext = (real_width - (wid_64 << 3)); + asmLoad8bI (src, dst, wid_64, height, line, ext); + return /*(0 << 16) | */GR_TEXFMT_ALPHA_8; +} diff --git a/Source/Glide64/TexMod.h b/Source/Glide64/TexMod.h new file mode 100644 index 000000000..39563d15b --- /dev/null +++ b/Source/Glide64/TexMod.h @@ -0,0 +1,581 @@ +/* +* Glide64 - Glide video plugin for Nintendo 64 emulators. +* Copyright (c) 2002 Dave2001 +* Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski +* +* 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 +* 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 +*/ + +//**************************************************************** +// +// Glide64 - Glide Plugin for Nintendo 64 emulators +// Project started on December 29th, 2001 +// +// Authors: +// Dave2001, original author, founded the project in 2001, left it in 2002 +// Gugaman, joined the project in 2002, left it in 2002 +// Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002 +// Hiroshi 'KoolSmoky' Morii, joined the project in 2007 +// +//**************************************************************** +// +// To modify Glide64: +// * Write your name and (optional)email, commented by your work, so I know who did it, and so that you can find which parts you modified when it comes time to send it to me. +// * Do NOT send me the whole project or file that you modified. Take out your modified code sections, and tell me where to put them. If people sent the whole thing, I would have many different versions, but no idea how to combine them all. +// +//**************************************************************** + +static void mod_tex_inter_color_using_factor (wxUint16 *dst, int size, wxUint32 color, wxUint32 factor) +{ + float percent = factor / 255.0f; + float percent_i = 1 - percent; + wxUint32 cr, cg, cb; + wxUint16 col, a; + wxUint8 r, g, b; + + cr = (color >> 12) & 0xF; + cg = (color >> 8) & 0xF; + cb = (color >> 4) & 0xF; + + for (int i=0; i> 8) & 0xF) + percent * cr); + g = (wxUint8)(percent_i * ((col >> 4) & 0xF) + percent * cg); + b = (wxUint8)(percent_i * (col & 0xF) + percent * cb); + *(dst++) = a | (r << 8) | (g << 4) | b; + } +} + +static void mod_tex_inter_col_using_col1 (wxUint16 *dst, int size, wxUint32 color0, wxUint32 color1) +{ + wxUint32 cr, cg, cb; + wxUint16 col, a; + wxUint8 r, g, b; + + float percent_r = ((color1 >> 12) & 0xF) / 15.0f; + float percent_g = ((color1 >> 8) & 0xF) / 15.0f; + float percent_b = ((color1 >> 4) & 0xF) / 15.0f; + float percent_r_i = 1.0f - percent_r; + float percent_g_i = 1.0f - percent_g; + float percent_b_i = 1.0f - percent_b; + + cr = (color0 >> 12) & 0xF; + cg = (color0 >> 8) & 0xF; + cb = (color0 >> 4) & 0xF; + + for (int i=0; i> 8) & 0xF) + percent_r * cr); + g = (wxUint8)(percent_g_i * ((col >> 4) & 0xF) + percent_g * cg); + b = (wxUint8)(percent_b_i * (col & 0xF) + percent_b * cb); + *(dst++) = a | (r << 8) | (g << 4) | b; + } +} + +static void mod_full_color_sub_tex (wxUint16 *dst, int size, wxUint32 color) +{ + wxUint32 cr, cg, cb, ca; + wxUint16 col; + wxUint8 a, r, g, b; + + cr = (color >> 12) & 0xF; + cg = (color >> 8) & 0xF; + cb = (color >> 4) & 0xF; + ca = color & 0xF; + + for (int i=0; i> 12) & 0xF)); + r = (wxUint8)(cr - ((col >> 8) & 0xF)); + g = (wxUint8)(cg - ((col >> 4) & 0xF)); + b = (wxUint8)(cb - (col & 0xF)); + *(dst++) = (a << 12) | (r << 8) | (g << 4) | b; + } +} + +static void mod_col_inter_col1_using_tex (wxUint16 *dst, int size, wxUint32 color0, wxUint32 color1) +{ + wxUint32 cr0, cg0, cb0, cr1, cg1, cb1; + wxUint16 col; + wxUint8 r, g, b; + wxUint16 a; + float percent_r, percent_g, percent_b; + + cr0 = (color0 >> 12) & 0xF; + cg0 = (color0 >> 8) & 0xF; + cb0 = (color0 >> 4) & 0xF; + cr1 = (color1 >> 12) & 0xF; + cg1 = (color1 >> 8) & 0xF; + cb1 = (color1 >> 4) & 0xF; + + for (int i=0; i> 8) & 0xF) / 15.0f; + percent_g = ((col >> 4) & 0xF) / 15.0f; + percent_b = (col & 0xF) / 15.0f; + r = min(15, (wxUint8)((1.0f-percent_r) * cr0 + percent_r * cr1 + 0.0001f)); + g = min(15, (wxUint8)((1.0f-percent_g) * cg0 + percent_g * cg1 + 0.0001f)); + b = min(15, (wxUint8)((1.0f-percent_b) * cb0 + percent_b * cb1 + 0.0001f)); + *(dst++) = a | (r << 8) | (g << 4) | b; + } +} + +static void mod_col_inter_col1_using_texa (wxUint16 *dst, int size, wxUint32 color0, wxUint32 color1) +{ + wxUint32 cr0, cg0, cb0, cr1, cg1, cb1; + wxUint16 col; + wxUint8 r, g, b; + wxUint16 a; + float percent, percent_i; + + cr0 = (color0 >> 12) & 0xF; + cg0 = (color0 >> 8) & 0xF; + cb0 = (color0 >> 4) & 0xF; + cr1 = (color1 >> 12) & 0xF; + cg1 = (color1 >> 8) & 0xF; + cb1 = (color1 >> 4) & 0xF; + + for (int i=0; i> 12) / 15.0f; + percent_i = 1.0f - percent; + r = (wxUint8)(percent_i * cr0 + percent * cr1); + g = (wxUint8)(percent_i * cg0 + percent * cg1); + b = (wxUint8)(percent_i * cb0 + percent * cb1); + *(dst++) = a | (r << 8) | (g << 4) | b; + } +} + +static void mod_col_inter_col1_using_texa__mul_tex (wxUint16 *dst, int size, wxUint32 color0, wxUint32 color1) +{ + wxUint32 cr0, cg0, cb0, cr1, cg1, cb1; + wxUint16 col; + wxUint8 r, g, b; + wxUint16 a; + float percent, percent_i; + + cr0 = (color0 >> 12) & 0xF; + cg0 = (color0 >> 8) & 0xF; + cb0 = (color0 >> 4) & 0xF; + cr1 = (color1 >> 12) & 0xF; + cg1 = (color1 >> 8) & 0xF; + cb1 = (color1 >> 4) & 0xF; + + for (int i=0; i> 12) / 15.0f; + percent_i = 1.0f - percent; + r = (wxUint8)(((percent_i * cr0 + percent * cr1) / 15.0f) * (((col & 0x0F00) >> 8) / 15.0f) * 15.0f); + g = (wxUint8)(((percent_i * cg0 + percent * cg1) / 15.0f) * (((col & 0x00F0) >> 4) / 15.0f) * 15.0f); + b = (wxUint8)(((percent_i * cb0 + percent * cb1) / 15.0f) * ((col & 0x000F) / 15.0f) * 15.0f); + *(dst++) = a | (r << 8) | (g << 4) | b; + } +} + +static void mod_col_inter_tex_using_tex (wxUint16 *dst, int size, wxUint32 color) +{ + wxUint32 cr, cg, cb; + wxUint16 col; + wxUint8 r, g, b; + wxUint16 a; + float percent_r, percent_g, percent_b; + + cr = (color >> 12) & 0xF; + cg = (color >> 8) & 0xF; + cb = (color >> 4) & 0xF; + + for (int i=0; i> 8) & 0xF) / 15.0f; + percent_g = ((col >> 4) & 0xF) / 15.0f; + percent_b = (col & 0xF) / 15.0f; + r = (wxUint8)((1.0f-percent_r) * cr + percent_r * ((col & 0x0F00) >> 8)); + g = (wxUint8)((1.0f-percent_g) * cg + percent_g * ((col & 0x00F0) >> 4)); + b = (wxUint8)((1.0f-percent_b) * cb + percent_b * (col & 0x000F)); + *(dst++) = a | (r << 8) | (g << 4) | b; + } +} + +static void mod_col_inter_tex_using_texa (wxUint16 *dst, int size, wxUint32 color) +{ + wxUint32 cr, cg, cb; + wxUint16 col; + wxUint8 r, g, b; + wxUint16 a; + float percent, percent_i; + + cr = (color >> 12) & 0xF; + cg = (color >> 8) & 0xF; + cb = (color >> 4) & 0xF; + + for (int i=0; i> 12) / 15.0f; + percent_i = 1.0f - percent; + r = (wxUint8)(percent_i * cr + percent * ((col & 0x0F00) >> 8)); + g = (wxUint8)(percent_i * cg + percent * ((col & 0x00F0) >> 4)); + b = (wxUint8)(percent_i * cb + percent * (col & 0x000F)); + *(dst++) = a | (r << 8) | (g << 4) | b; + } +} + +static void mod_col2_inter__col_inter_col1_using_tex__using_texa (wxUint16 *dst, int size, + wxUint32 color0, wxUint32 color1, + wxUint32 color2) +{ + wxUint32 cr0, cg0, cb0, cr1, cg1, cb1, cr2, cg2, cb2; + wxUint16 col; + wxUint8 r, g, b; + wxUint16 a; + float percent_r, percent_g, percent_b, percent_a; + + cr0 = (color0 >> 12) & 0xF; + cg0 = (color0 >> 8) & 0xF; + cb0 = (color0 >> 4) & 0xF; + cr1 = (color1 >> 12) & 0xF; + cg1 = (color1 >> 8) & 0xF; + cb1 = (color1 >> 4) & 0xF; + cr2 = (color2 >> 12) & 0xF; + cg2 = (color2 >> 8) & 0xF; + cb2 = (color2 >> 4) & 0xF; + + for (int i=0; i> 12) / 15.0f; + percent_r = ((col >> 8) & 0xF) / 15.0f; + percent_g = ((col >> 4) & 0xF) / 15.0f; + percent_b = (col & 0xF) / 15.0f; + r = (wxUint8)(((1.0f-percent_r) * cr0 + percent_r * cr1) * percent_a + cr2 * (1.0f-percent_a)); + g = (wxUint8)(((1.0f-percent_g) * cg0 + percent_g * cg1) * percent_a + cg2 * (1.0f-percent_a)); + b = (wxUint8)(((1.0f-percent_b) * cb0 + percent_b * cb1) * percent_a + cb2 * (1.0f-percent_a)); + *(dst++) = a | (r << 8) | (g << 4) | b; + } +} + +static void mod_tex_scale_fac_add_fac (wxUint16 *dst, int size, wxUint32 factor) +{ + float percent = factor / 255.0f; + wxUint16 col; + wxUint8 a; + float base_a = (1.0f - percent) * 15.0f; + + for (int i=0; i>12)); + *(dst++) = (a<<12) | (col & 0x0FFF); + } +} + +static void mod_tex_sub_col_mul_fac_add_tex (wxUint16 *dst, int size, wxUint32 color, wxUint32 factor) +{ + float percent = factor / 255.0f; + wxUint32 cr, cg, cb; + wxUint16 col, a; + float r, g, b; + + cr = (color >> 12) & 0xF; + cg = (color >> 8) & 0xF; + cb = (color >> 4) & 0xF; + + for (int i=0; i> 8) & 0xF); + r = /*max(*/(r - cr) * percent/*, 0.0f)*/ + r; + if (r > 15.0f) r = 15.0f; + if (r < 0.0f) r = 0.0f; + g = (float)((col >> 4) & 0xF); + g = /*max(*/(g - cg) * percent/*, 0.0f)*/ + g; + if (g > 15.0f) g = 15.0f; + if (g < 0.0f) g = 0.0f; + b = (float)(col & 0xF); + b = /*max(*/(b - cb) * percent/*, 0.0f)*/ + b; + if (b > 15.0f) b = 15.0f; + if (b < 0.0f) b = 0.0f; + + *(dst++) = a | ((wxUint16)r << 8) | ((wxUint16)g << 4) | (wxUint16)b; + } +} + +static void mod_tex_scale_col_add_col (wxUint16 *dst, int size, wxUint32 color0, wxUint32 color1) +{ + wxUint32 cr0, cg0, cb0, cr1, cg1, cb1; + wxUint16 col; + wxUint8 r, g, b; + wxUint16 a; + float percent_r, percent_g, percent_b; + + cr0 = (color0 >> 12) & 0xF; + cg0 = (color0 >> 8) & 0xF; + cb0 = (color0 >> 4) & 0xF; + cr1 = (color1 >> 12) & 0xF; + cg1 = (color1 >> 8) & 0xF; + cb1 = (color1 >> 4) & 0xF; + + for (int i=0; i> 8) & 0xF) / 15.0f; + percent_g = ((col >> 4) & 0xF) / 15.0f; + percent_b = (col & 0xF) / 15.0f; + r = min(15, (wxUint8)(percent_r * cr0 + cr1 + 0.0001f)); + g = min(15, (wxUint8)(percent_g * cg0 + cg1 + 0.0001f)); + b = min(15, (wxUint8)(percent_b * cb0 + cb1 + 0.0001f)); + *(dst++) = a | (r << 8) | (g << 4) | b; + } +} + +static void mod_tex_add_col (wxUint16 *dst, int size, wxUint32 color) +{ + wxUint32 cr, cg, cb, ca; + wxUint16 col; + wxUint8 a, r, g, b; + + cr = (color >> 12) & 0xF; + cg = (color >> 8) & 0xF; + cb = (color >> 4) & 0xF; + ca = color & 0xF; + + for (int i=0; i> 12) & 0xF); +// a = col & 0xF000; + r = (wxUint8)(cr + ((col >> 8) & 0xF))&0xF; + g = (wxUint8)(cg + ((col >> 4) & 0xF))&0xF; + b = (wxUint8)(cb + (col & 0xF))&0xF; + *(dst++) = (a << 12) | (r << 8) | (g << 4) | b; + } +} + +static void mod_col_mul_texa_add_tex (wxUint16 *dst, int size, wxUint32 color) +{ + wxUint32 cr, cg, cb; + wxUint16 col; + wxUint8 r, g, b; + wxUint16 a; + float factor; + + cr = (color >> 12) & 0xF; + cg = (color >> 8) & 0xF; + cb = (color >> 4) & 0xF; + + for (int i=0; i> 12) / 15.0f; + r = (wxUint8)(cr*factor + ((col >> 8) & 0xF))&0xF; + g = (wxUint8)(cg*factor + ((col >> 4) & 0xF))&0xF; + b = (wxUint8)(cb*factor + (col & 0xF))&0xF; + *(dst++) = a | (r << 8) | (g << 4) | b; + } +} + +static void mod_tex_sub_col (wxUint16 *dst, int size, wxUint32 color) +{ + int cr, cg, cb; + wxUint16 col; + wxUint8 a, r, g, b; + + cr = (color >> 12) & 0xF; + cg = (color >> 8) & 0xF; + cb = (color >> 4) & 0xF; + + for (int i=0; i> 8) & 0xF) - cr), 0); + g = (wxUint8)max((((col >> 4) & 0xF) - cg), 0); + b = (wxUint8)max(((col & 0xF) - cb), 0); + *(dst++) = (a << 12) | (r << 8) | (g << 4) | b; + } +} + +static void mod_tex_sub_col_mul_fac (wxUint16 *dst, int size, wxUint32 color, wxUint32 factor) +{ + float percent = factor / 255.0f; + wxUint32 cr, cg, cb; + wxUint16 col, a; + float r, g, b; + + cr = (color >> 12) & 0xF; + cg = (color >> 8) & 0xF; + cb = (color >> 4) & 0xF; + + for (int i=0; i> 12) & 0xF); + r = (float)((col >> 8) & 0xF); + r = (r - cr) * percent; + if (r > 15.0f) r = 15.0f; + if (r < 0.0f) r = 0.0f; + g = (float)((col >> 4) & 0xF); + g = (g - cg) * percent; + if (g > 15.0f) g = 15.0f; + if (g < 0.0f) g = 0.0f; + b = (float)(col & 0xF); + b = (b - cb) * percent; + if (b > 15.0f) b = 15.0f; + if (b < 0.0f) b = 0.0f; + + *(dst++) = (a << 12) | ((wxUint16)r << 8) | ((wxUint16)g << 4) | (wxUint16)b; + } +} + +static void mod_col_inter_tex_using_col1 (wxUint16 *dst, int size, wxUint32 color0, wxUint32 color1) +{ + wxUint32 cr, cg, cb; + wxUint16 col, a; + wxUint8 r, g, b; + + float percent_r = ((color1 >> 12) & 0xF) / 15.0f; + float percent_g = ((color1 >> 8) & 0xF) / 15.0f; + float percent_b = ((color1 >> 4) & 0xF) / 15.0f; + float percent_r_i = 1.0f - percent_r; + float percent_g_i = 1.0f - percent_g; + float percent_b_i = 1.0f - percent_b; + + cr = (color0 >> 12) & 0xF; + cg = (color0 >> 8) & 0xF; + cb = (color0 >> 4) & 0xF; + + for (int i=0; i> 12) & 0xF); + r = (wxUint8)(percent_r * ((col >> 8) & 0xF) + percent_r_i * cr); + g = (wxUint8)(percent_g * ((col >> 4) & 0xF) + percent_g_i * cg); + b = (wxUint8)(percent_b * (col & 0xF) + percent_b_i * cb); + *(dst++) = (a << 12) | (r << 8) | (g << 4) | b; + } +} + +static void mod_tex_inter_noise_using_col (wxUint16 *dst, int size, wxUint32 color) +{ + wxUint16 col, a; + wxUint8 r, g, b, noise; + + float percent_r = ((color >> 12) & 0xF) / 15.0f; + float percent_g = ((color >> 8) & 0xF) / 15.0f; + float percent_b = ((color >> 4) & 0xF) / 15.0f; + float percent_r_i = 1.0f - percent_r; + float percent_g_i = 1.0f - percent_g; + float percent_b_i = 1.0f - percent_b; + + for (int i=0; i> 8) & 0xF) + percent_r * noise); + g = (wxUint8)(percent_g_i * ((col >> 4) & 0xF) + percent_g * noise); + b = (wxUint8)(percent_b_i * (col & 0xF) + percent_b * noise); + *(dst++) = a | (r << 8) | (g << 4) | b; + } +} + +static void mod_tex_inter_col_using_texa (wxUint16 *dst, int size, wxUint32 color) +{ + wxUint32 cr, cg, cb; + wxUint16 col; + wxUint8 r, g, b; + wxUint16 a; + float percent, percent_i; + + cr = (color >> 12) & 0xF; + cg = (color >> 8) & 0xF; + cb = (color >> 4) & 0xF; + + for (int i=0; i> 12) / 15.0f; + percent_i = 1.0f - percent; + r = (wxUint8)(percent * cr + percent_i * ((col & 0x0F00) >> 8)); + g = (wxUint8)(percent * cg + percent_i * ((col & 0x00F0) >> 4)); + b = (wxUint8)(percent * cb + percent_i * (col & 0x000F)); + *(dst++) = a | (r << 8) | (g << 4) | b; + } +} + +static void mod_tex_mul_col (wxUint16 *dst, int size, wxUint32 color) +{ + float cr, cg, cb; + wxUint16 col; + wxUint8 r, g, b; + wxUint16 a; + float percent, percent_i; + + cr = (float)((color >> 12) & 0xF)/16.0f; + cg = (float)((color >> 8) & 0xF)/16.0f; + cb = (float)((color >> 4) & 0xF)/16.0f; + + for (int i=0; i> 12) / 15.0f; + percent_i = 1.0f - percent; + r = (wxUint8)(cr * ((col & 0x0F00) >> 8)); + g = (wxUint8)(cg * ((col & 0x00F0) >> 4)); + b = (wxUint8)(cb * (col & 0x000F)); + *(dst++) = a | (r << 8) | (g << 4) | b; + } +} + +static void mod_tex_scale_fac_add_col (wxUint16 *dst, int size, wxUint32 color, wxUint32 factor) +{ + float percent = factor / 255.0f; + wxUint32 cr, cg, cb; + wxUint16 col; + float r, g, b; + + cr = (color >> 12) & 0xF; + cg = (color >> 8) & 0xF; + cb = (color >> 4) & 0xF; + + for (int i=0; i>8)&0xF); + g = cg + percent * (float)((col>>4)&0xF); + b = cb + percent * (float)(col&0xF); + *(dst++) = (col&0xF000) | ((wxUint8)r << 8) | ((wxUint8)g << 4) | (wxUint8)b; + } +} diff --git a/Source/Glide64/TexModCI.h b/Source/Glide64/TexModCI.h new file mode 100644 index 000000000..14ef9ec95 --- /dev/null +++ b/Source/Glide64/TexModCI.h @@ -0,0 +1,437 @@ +/* +* Glide64 - Glide video plugin for Nintendo 64 emulators. +* Copyright (c) 2002 Dave2001 +* Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski +* +* 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 +* 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 +*/ + +//**************************************************************** +// +// Glide64 - Glide Plugin for Nintendo 64 emulators +// Project started on December 29th, 2001 +// +// Authors: +// Dave2001, original author, founded the project in 2001, left it in 2002 +// Gugaman, joined the project in 2002, left it in 2002 +// Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002 +// Hiroshi 'KoolSmoky' Morii, joined the project in 2007 +// +//**************************************************************** +// +// To modify Glide64: +// * Write your name and (optional)email, commented by your work, so I know who did it, and so that you can find which parts you modified when it comes time to send it to me. +// * Do NOT send me the whole project or file that you modified. Take out your modified code sections, and tell me where to put them. If people sent the whole thing, I would have many different versions, but no idea how to combine them all. +// +//**************************************************************** + +static void mod_tex_inter_color_using_factor_CI (wxUint32 color, wxUint32 factor) +{ + float percent = factor / 255.0f; + float percent_i = 1 - percent; + wxUint8 cr, cg, cb; + wxUint16 col; + wxUint8 a, r, g, b; + + cr = (wxUint8)((color >> 24) & 0xFF); + cg = (wxUint8)((color >> 16) & 0xFF); + cb = (wxUint8)((color >> 8) & 0xFF); + + for (int i=0; i<256; i++) + { + col = rdp.pal_8[i]; + a = (wxUint8)(col&0x0001);; + r = (wxUint8)((float)((col&0xF800) >> 11) / 31.0f * 255.0f); + g = (wxUint8)((float)((col&0x07C0) >> 6) / 31.0f * 255.0f); + b = (wxUint8)((float)((col&0x003E) >> 1) / 31.0f * 255.0f); + r = (wxUint8)(min(255, percent_i * r + percent * cr)); + g = (wxUint8)(min(255, percent_i * g + percent * cg)); + b = (wxUint8)(min(255, percent_i * b + percent * cb)); + rdp.pal_8[i] = (wxUint16)(((wxUint16)(r >> 3) << 11) | + ((wxUint16)(g >> 3) << 6) | + ((wxUint16)(b >> 3) << 1) | + ((wxUint16)(a ) << 0)); + } +} + +static void mod_tex_inter_col_using_col1_CI (wxUint32 color0, wxUint32 color1) +{ + wxUint8 cr, cg, cb; + wxUint16 col; + wxUint8 a, r, g, b; + + float percent_r = ((color1 >> 24) & 0xFF) / 255.0f; + float percent_g = ((color1 >> 16) & 0xFF) / 255.0f; + float percent_b = ((color1 >> 8) & 0xFF) / 255.0f; + float percent_r_i = 1.0f - percent_r; + float percent_g_i = 1.0f - percent_g; + float percent_b_i = 1.0f - percent_b; + + cr = (wxUint8)((color0 >> 24) & 0xFF); + cg = (wxUint8)((color0 >> 16) & 0xFF); + cb = (wxUint8)((color0 >> 8) & 0xFF); + + for (int i=0; i<256; i++) + { + col = rdp.pal_8[i]; + a = (wxUint8)(col&0x0001);; + r = (wxUint8)((float)((col&0xF800) >> 11) / 31.0f * 255.0f); + g = (wxUint8)((float)((col&0x07C0) >> 6) / 31.0f * 255.0f); + b = (wxUint8)((float)((col&0x003E) >> 1) / 31.0f * 255.0f); + r = (wxUint8)(min(255, percent_r_i * r + percent_r * cr)); + g = (wxUint8)(min(255, percent_g_i * g + percent_g * cg)); + b = (wxUint8)(min(255, percent_b_i * b + percent_b * cb)); + rdp.pal_8[i] = (wxUint16)(((wxUint16)(r >> 3) << 11) | + ((wxUint16)(g >> 3) << 6) | + ((wxUint16)(b >> 3) << 1) | + ((wxUint16)(a ) << 0)); + } +} + +static void mod_full_color_sub_tex_CI (wxUint32 color) +{ + wxUint8 cr, cg, cb, ca; + wxUint16 col; + wxUint8 a, r, g, b; + + cr = (wxUint8)((color >> 24) & 0xFF); + cg = (wxUint8)((color >> 16) & 0xFF); + cb = (wxUint8)((color >> 8) & 0xFF); + ca = (wxUint8)(color & 0xFF); + + for (int i=0; i<256; i++) + { + col = rdp.pal_8[i]; + a = (wxUint8)(col&0x0001);; + r = (wxUint8)((float)((col&0xF800) >> 11) / 31.0f * 255.0f); + g = (wxUint8)((float)((col&0x07C0) >> 6) / 31.0f * 255.0f); + b = (wxUint8)((float)((col&0x003E) >> 1) / 31.0f * 255.0f); + a = max(0, ca - a); + r = max(0, cr - r); + g = max(0, cg - g); + b = max(0, cb - b); + rdp.pal_8[i] = (wxUint16)(((wxUint16)(r >> 3) << 11) | + ((wxUint16)(g >> 3) << 6) | + ((wxUint16)(b >> 3) << 1) | + ((wxUint16)(a ) << 0)); + } +} + +static void mod_col_inter_col1_using_tex_CI (wxUint32 color0, wxUint32 color1) +{ + wxUint32 cr0, cg0, cb0, cr1, cg1, cb1; + wxUint16 col; + wxUint8 a, r, g, b; + float percent_r, percent_g, percent_b; + + cr0 = (wxUint8)((color0 >> 24) & 0xFF); + cg0 = (wxUint8)((color0 >> 16) & 0xFF); + cb0 = (wxUint8)((color0 >> 8) & 0xFF); + cr1 = (wxUint8)((color1 >> 24) & 0xFF); + cg1 = (wxUint8)((color1 >> 16) & 0xFF); + cb1 = (wxUint8)((color1 >> 8) & 0xFF); + + for (int i=0; i<256; i++) + { + col = rdp.pal_8[i]; + a = (wxUint8)(col&0x0001);; + percent_r = ((col&0xF800) >> 11) / 31.0f; + percent_g = ((col&0x07C0) >> 6) / 31.0f; + percent_b = ((col&0x003E) >> 1) / 31.0f; + r = (wxUint8)(min((1.0f-percent_r) * cr0 + percent_r * cr1, 255)); + g = (wxUint8)(min((1.0f-percent_g) * cg0 + percent_g * cg1, 255)); + b = (wxUint8)(min((1.0f-percent_b) * cb0 + percent_b * cb1, 255)); + rdp.pal_8[i] = (wxUint16)(((wxUint16)(r >> 3) << 11) | + ((wxUint16)(g >> 3) << 6) | + ((wxUint16)(b >> 3) << 1) | + ((wxUint16)(a ) << 0)); + } +} + + + +static void mod_tex_sub_col_mul_fac_add_tex_CI (wxUint32 color, wxUint32 factor) +{ + float percent = factor / 255.0f; + wxUint8 cr, cg, cb, a; + wxUint16 col; + float r, g, b; + + cr = (wxUint8)((color >> 24) & 0xFF); + cg = (wxUint8)((color >> 16) & 0xFF); + cb = (wxUint8)((color >> 8) & 0xFF); + + for (int i=0; i<256; i++) + { + col = rdp.pal_8[i]; + a = (wxUint8)(col&0x0001);; + r = (wxUint8)((float)((col&0xF800) >> 11) / 31.0f * 255.0f); + g = (wxUint8)((float)((col&0x07C0) >> 6) / 31.0f * 255.0f); + b = (wxUint8)((float)((col&0x003E) >> 1) / 31.0f * 255.0f); + r = (r - cr) * percent + r; + if (r > 255.0f) r = 255.0f; + if (r < 0.0f) r = 0.0f; + g = (g - cg) * percent + g; + if (g > 255.0f) g = 255.0f; + if (g < 0.0f) g = 0.0f; + b = (b - cb) * percent + b; + if (b > 255.0f) g = 255.0f; + if (b < 0.0f) b = 0.0f; + rdp.pal_8[i] = (wxUint16)(((wxUint16)((wxUint8)(r) >> 3) << 11) | + ((wxUint16)((wxUint8)(g) >> 3) << 6) | + ((wxUint16)((wxUint8)(b) >> 3) << 1) | + (wxUint16)(a) ); + } +} + +static void mod_tex_scale_col_add_col_CI (wxUint32 color0, wxUint32 color1) +{ + wxUint8 cr, cg, cb; + wxUint16 col; + wxUint8 a, r, g, b; + + float percent_r = ((color0 >> 24) & 0xFF) / 255.0f; + float percent_g = ((color0 >> 16) & 0xFF) / 255.0f; + float percent_b = ((color0 >> 8) & 0xFF) / 255.0f; + cr = (wxUint8)((color1 >> 24) & 0xFF); + cg = (wxUint8)((color1 >> 16) & 0xFF); + cb = (wxUint8)((color1 >> 8) & 0xFF); + + for (int i=0; i<256; i++) + { + col = rdp.pal_8[i]; + a = (wxUint8)(col&0x0001);; + r = (wxUint8)((float)((col&0xF800) >> 11) / 31.0f * 255.0f); + g = (wxUint8)((float)((col&0x07C0) >> 6) / 31.0f * 255.0f); + b = (wxUint8)((float)((col&0x003E) >> 1) / 31.0f * 255.0f); + r = (wxUint8)(min(255, percent_r * r + cr)); + g = (wxUint8)(min(255, percent_g * g + cg)); + b = (wxUint8)(min(255, percent_b * b + cb)); + rdp.pal_8[i] = (wxUint16)(((wxUint16)(r >> 3) << 11) | + ((wxUint16)(g >> 3) << 6) | + ((wxUint16)(b >> 3) << 1) | + ((wxUint16)(a ) << 0)); + } +} + +static void mod_tex_add_col_CI (wxUint32 color) +{ + wxUint8 cr, cg, cb; + wxUint16 col; + wxUint8 a, r, g, b; + + cr = (wxUint8)((color >> 24) & 0xFF); + cg = (wxUint8)((color >> 16) & 0xFF); + cb = (wxUint8)((color >> 8) & 0xFF); + + for (int i=0; i<256; i++) + { + col = rdp.pal_8[i]; + a = (wxUint8)(col&0x0001);; + r = (wxUint8)((float)((col&0xF800) >> 11) / 31.0f * 255.0f); + g = (wxUint8)((float)((col&0x07C0) >> 6) / 31.0f * 255.0f); + b = (wxUint8)((float)((col&0x003E) >> 1) / 31.0f * 255.0f); + r = min(cr + r, 255); + g = min(cg + g, 255); + b = min(cb + b, 255); + rdp.pal_8[i] = (wxUint16)(((wxUint16)(r >> 3) << 11) | + ((wxUint16)(g >> 3) << 6) | + ((wxUint16)(b >> 3) << 1) | + ((wxUint16)(a ) << 0)); + } +} + +static void mod_tex_sub_col_CI (wxUint32 color) +{ + wxUint8 cr, cg, cb; + wxUint16 col; + wxUint8 a, r, g, b; + + cr = (wxUint8)((color >> 24) & 0xFF); + cg = (wxUint8)((color >> 16) & 0xFF); + cb = (wxUint8)((color >> 8) & 0xFF); + + for (int i=0; i<256; i++) + { + col = rdp.pal_8[i]; + a = (wxUint8)(col&0x0001);; + r = (wxUint8)((float)((col&0xF800) >> 11) / 31.0f * 255.0f); + g = (wxUint8)((float)((col&0x07C0) >> 6) / 31.0f * 255.0f); + b = (wxUint8)((float)((col&0x003E) >> 1) / 31.0f * 255.0f); + r = max(r - cr, 0); + g = max(g - cg, 0); + b = max(b - cb, 0); + rdp.pal_8[i] = (wxUint16)(((wxUint16)(r >> 3) << 11) | + ((wxUint16)(g >> 3) << 6) | + ((wxUint16)(b >> 3) << 1) | + ((wxUint16)(a ) << 0)); + } +} + +static void mod_tex_sub_col_mul_fac_CI (wxUint32 color, wxUint32 factor) +{ + float percent = factor / 255.0f; + wxUint8 cr, cg, cb; + wxUint16 col; + wxUint8 a; + float r, g, b; + + cr = (wxUint8)((color >> 24) & 0xFF); + cg = (wxUint8)((color >> 16) & 0xFF); + cb = (wxUint8)((color >> 8) & 0xFF); + + for (int i=0; i<256; i++) + { + col = rdp.pal_8[i]; + a = (wxUint8)(col&0x0001); + r = (float)((col&0xF800) >> 11) / 31.0f * 255.0f; + g = (float)((col&0x07C0) >> 6) / 31.0f * 255.0f; + b = (float)((col&0x003E) >> 1) / 31.0f * 255.0f; + r = (r - cr) * percent; + if (r > 255.0f) r = 255.0f; + if (r < 0.0f) r = 0.0f; + g = (g - cg) * percent; + if (g > 255.0f) g = 255.0f; + if (g < 0.0f) g = 0.0f; + b = (b - cb) * percent; + if (b > 255.0f) g = 255.0f; + if (b < 0.0f) b = 0.0f; + + rdp.pal_8[i] = (wxUint16)(((wxUint16)((wxUint8)(r) >> 3) << 11) | + ((wxUint16)((wxUint8)(g) >> 3) << 6) | + ((wxUint16)((wxUint8)(b) >> 3) << 1) | + (wxUint16)(a) ); + } +} + +static void mod_col_inter_tex_using_col1_CI (wxUint32 color0, wxUint32 color1) +{ + wxUint8 cr, cg, cb; + wxUint16 col; + wxUint8 a, r, g, b; + + float percent_r = ((color1 >> 24) & 0xFF) / 255.0f; + float percent_g = ((color1 >> 16) & 0xFF) / 255.0f; + float percent_b = ((color1 >> 8) & 0xFF) / 255.0f; + float percent_r_i = 1.0f - percent_r; + float percent_g_i = 1.0f - percent_g; + float percent_b_i = 1.0f - percent_b; + + cr = (wxUint8)((color0 >> 24) & 0xFF); + cg = (wxUint8)((color0 >> 16) & 0xFF); + cb = (wxUint8)((color0 >> 8) & 0xFF); + + for (int i=0; i<256; i++) + { + col = rdp.pal_8[i]; + a = (wxUint8)(col&0x0001);; + r = (wxUint8)((float)((col&0xF800) >> 11) / 31.0f * 255.0f); + g = (wxUint8)((float)((col&0x07C0) >> 6) / 31.0f * 255.0f); + b = (wxUint8)((float)((col&0x003E) >> 1) / 31.0f * 255.0f); + r = (wxUint8)(min(255, percent_r * r + percent_r_i * cr)); + g = (wxUint8)(min(255, percent_g * g + percent_g_i * cg)); + b = (wxUint8)(min(255, percent_b * b + percent_b_i * cb)); + rdp.pal_8[i] = (wxUint16)(((wxUint16)(r >> 3) << 11) | + ((wxUint16)(g >> 3) << 6) | + ((wxUint16)(b >> 3) << 1) | + ((wxUint16)(a ) << 0)); + } +} + +static void mod_tex_inter_col_using_texa_CI (wxUint32 color) +{ + wxUint8 a, r, g, b; + + r = (wxUint8)((float)((color >> 24) & 0xFF) / 255.0f * 31.0f); + g = (wxUint8)((float)((color >> 16) & 0xFF) / 255.0f * 31.0f); + b = (wxUint8)((float)((color >> 8) & 0xFF) / 255.0f * 31.0f); + a = (color&0xFF) ? 1 : 0; + wxUint16 col16 = (wxUint16)((r<<11)|(g<<6)|(b<<1)|a); + + for (int i=0; i<256; i++) + { + if (rdp.pal_8[i]&1) + rdp.pal_8[i] = col16; + } +} + +static void mod_tex_mul_col_CI (wxUint32 color) +{ + wxUint8 a, r, g, b; + wxUint16 col; + float cr, cg, cb; + + cr = (float)((color >> 24) & 0xFF) / 255.0f; + cg = (float)((color >> 16) & 0xFF) / 255.0f; + cb = (float)((color >> 8) & 0xFF) / 255.0f; + + for (int i=0; i<256; i++) + { + col = rdp.pal_8[i]; + a = (wxUint8)(col&0x0001);; + r = (wxUint8)((float)((col&0xF800) >> 11) * cr); + g = (wxUint8)((float)((col&0x07C0) >> 6) * cg); + b = (wxUint8)((float)((col&0x003E) >> 1) * cb); + rdp.pal_8[i] = (wxUint16)(((wxUint16)(r >> 3) << 11) | + ((wxUint16)(g >> 3) << 6) | + ((wxUint16)(b >> 3) << 1) | + ((wxUint16)(a ) << 0)); + } +} + +static void ModifyPalette(wxUint32 mod, wxUint32 modcolor, wxUint32 modcolor1, wxUint32 modfactor) +{ + switch (mod) + { + case TMOD_TEX_INTER_COLOR_USING_FACTOR: + mod_tex_inter_color_using_factor_CI (modcolor, modfactor); + break; + case TMOD_TEX_INTER_COL_USING_COL1: + mod_tex_inter_col_using_col1_CI (modcolor, modcolor1); + break; + case TMOD_FULL_COLOR_SUB_TEX: + mod_full_color_sub_tex_CI (modcolor); + break; + case TMOD_COL_INTER_COL1_USING_TEX: + mod_col_inter_col1_using_tex_CI (modcolor, modcolor1); + break; + case TMOD_TEX_SUB_COL_MUL_FAC_ADD_TEX: + mod_tex_sub_col_mul_fac_add_tex_CI (modcolor, modfactor); + break; + case TMOD_TEX_SCALE_COL_ADD_COL: + mod_tex_scale_col_add_col_CI (modcolor, modcolor1); + break; + case TMOD_TEX_ADD_COL: + mod_tex_add_col_CI (modcolor); + break; + case TMOD_TEX_SUB_COL: + mod_tex_sub_col_CI (modcolor); + break; + case TMOD_TEX_SUB_COL_MUL_FAC: + mod_tex_sub_col_mul_fac_CI (modcolor, modfactor); + break; + case TMOD_COL_INTER_TEX_USING_COL1: + mod_col_inter_tex_using_col1_CI (modcolor, modcolor1); + break; + case TMOD_TEX_INTER_COL_USING_TEXA: + mod_tex_inter_col_using_texa_CI (modcolor); + break; + case TMOD_TEX_MUL_COL: + mod_tex_mul_col_CI (modcolor); + break; + default: + ; + } +} diff --git a/Source/Glide64/Texture.asm b/Source/Glide64/Texture.asm new file mode 100644 index 000000000..f974fec55 --- /dev/null +++ b/Source/Glide64/Texture.asm @@ -0,0 +1,3836 @@ +;/* +;* Glide64 - Glide video plugin for Nintendo 64 emulators. +;* +;* 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 +;* 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 +;*/ +; +;**************************************************************** +; +; Glide64 - Glide Plugin for Nintendo 64 emulators +; Project started on December 29th, 2001 +; +; Authors: +; Dave2001, original author, founded the project in 2001, left it in 2002 +; Gugaman, joined the project in 2002, left it in 2002 +; Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002 +; Hiroshi 'KoolSmoky' Morii, joined the project in 2007 +; +;**************************************************************** +; +; To modify Glide64: +; * Write your name and (optional)email, commented by your work, so I know who did it, and so that you can find which parts you modified when it comes time to send it to me. +; * Do NOT send me the whole project or file that you modified. Take out your modified code sections, and tell me where to put them. If people sent the whole thing, I would have many different versions, but no idea how to combine them all. +; +;**************************************************************** + +%include "inc/c32.mac" + +segment .text + + +;**************************************************************** +; +; ******** Textures load ******** +; +;**************************************************************** + + +;**************************************************************** +;4b textures load +;**************************************************************** + + +;**************************************************************** +; Size: 0, Format: 2 +; 2009 ported to NASM - Sergey (Gonetz) Lipski + +proc asmLoad4bCI +CPU 586 + %$src arg + %$dst arg + %$wid_64 arg + %$height arg + %$line arg + %$ext arg + %$pal arg +ci4: + push ebx + push esi + push edi + + mov ebx,[ebp + %$pal] + mov esi,[ebp + %$src] + mov edi,[ebp + %$dst] + mov ecx,[ebp + %$height] +.y_loop: + push ecx + mov ecx,[ebp + %$wid_64] +.x_loop: + push ecx + + mov eax,[esi] ; read all 8 pixels + bswap eax + add esi,4 + mov edx,eax + + ; 1st dword output { + shr eax,23 + and eax,0x1E + mov cx,[ebx+eax] + ror cx,1 + shl ecx,16 + + mov eax,edx + shr eax,27 + and eax,0x1E + mov cx,[ebx+eax] + ror cx,1 + + mov [edi],ecx + add edi,4 + ; } + + ; 2nd dword output { + mov eax,edx + shr eax,15 + and eax,0x1E + mov cx,[ebx+eax] + ror cx,1 + shl ecx,16 + + mov eax,edx + shr eax,19 + and eax,0x1E + mov cx,[ebx+eax] + ror cx,1 + + mov [edi],ecx + add edi,4 + ; } + + ; 3rd dword output { + mov eax,edx + shr eax,7 + and eax,0x1E + mov cx,[ebx+eax] + ror cx,1 + shl ecx,16 + + mov eax,edx + shr eax,11 + and eax,0x1E + mov cx,[ebx+eax] + ror cx,1 + + mov [edi],ecx + add edi,4 + ; } + + ; 4th dword output { + mov eax,edx + shl eax,1 + and eax,0x1E + mov cx,[ebx+eax] + ror cx,1 + shl ecx,16 + + shr edx,3 + and edx,0x1E + mov cx,[ebx+edx] + ror cx,1 + + mov [edi],ecx + add edi,4 + ; } + + ; * copy + mov eax,[esi] ; read all 8 pixels + bswap eax + add esi,4 + mov edx,eax + + ; 1st dword output { + shr eax,23 + and eax,0x1E + mov cx,[ebx+eax] + ror cx,1 + shl ecx,16 + + mov eax,edx + shr eax,27 + and eax,0x1E + mov cx,[ebx+eax] + ror cx,1 + + mov [edi],ecx + add edi,4 + ; } + + ; 2nd dword output { + mov eax,edx + shr eax,15 + and eax,0x1E + mov cx,[ebx+eax] + ror cx,1 + shl ecx,16 + + mov eax,edx + shr eax,19 + and eax,0x1E + mov cx,[ebx+eax] + ror cx,1 + + mov [edi],ecx + add edi,4 + ; } + + ; 3rd dword output { + mov eax,edx + shr eax,7 + and eax,0x1E + mov cx,[ebx+eax] + ror cx,1 + shl ecx,16 + + mov eax,edx + shr eax,11 + and eax,0x1E + mov cx,[ebx+eax] + ror cx,1 + + mov [edi],ecx + add edi,4 + ; } + + ; 4th dword output { + mov eax,edx + shl eax,1 + and eax,0x1E + mov cx,[ebx+eax] + ror cx,1 + shl ecx,16 + + shr edx,3 + and edx,0x1E + mov cx,[ebx+edx] + ror cx,1 + + mov [edi],ecx + add edi,4 + ; } + ; * + + pop ecx + + dec ecx + jnz .x_loop + + pop ecx + dec ecx + jz near .end_y_loop + push ecx + + mov eax,esi + add eax,[ebp + %$line] + mov esi,[ebp + %$src] + sub eax,esi + and eax,0x7FF + add esi,eax + add edi,[ebp + %$ext] + + mov ecx,[ebp + %$wid_64] + .x_loop_2: + push ecx + + mov eax,[esi+4] ; read all 8 pixels + bswap eax + mov edx,eax + + ; 1st dword output { + shr eax,23 + and eax,0x1E + mov cx,[ebx+eax] + ror cx,1 + shl ecx,16 + + mov eax,edx + shr eax,27 + and eax,0x1E + mov cx,[ebx+eax] + ror cx,1 + + mov [edi],ecx + add edi,4 + ; } + + ; 2nd dword output { + mov eax,edx + shr eax,15 + and eax,0x1E + mov cx,[ebx+eax] + ror cx,1 + shl ecx,16 + + mov eax,edx + shr eax,19 + and eax,0x1E + mov cx,[ebx+eax] + ror cx,1 + + mov [edi],ecx + add edi,4 + ; } + + ; 3rd dword output { + mov eax,edx + shr eax,7 + and eax,0x1E + mov cx,[ebx+eax] + ror cx,1 + shl ecx,16 + + mov eax,edx + shr eax,11 + and eax,0x1E + mov cx,[ebx+eax] + ror cx,1 + + mov [edi],ecx + add edi,4 + ; } + + ; 4th dword output { + mov eax,edx + shl eax,1 + and eax,0x1E + mov cx,[ebx+eax] + ror cx,1 + shl ecx,16 + + shr edx,3 + and edx,0x1E + mov cx,[ebx+edx] + ror cx,1 + + mov [edi],ecx + add edi,4 + ; } + + ; * copy + mov eax,[esi] ; read all 8 pixels + bswap eax + mov edx,esi + add edx,8 + mov esi,[ebp + %$src] + sub edx,esi + and edx,0x7FF + add esi,edx + mov edx,eax + + ; 1st dword output { + shr eax,23 + and eax,0x1E + mov cx,[ebx+eax] + ror cx,1 + shl ecx,16 + + mov eax,edx + shr eax,27 + and eax,0x1E + mov cx,[ebx+eax] + ror cx,1 + + mov [edi],ecx + add edi,4 + ; } + + ; 2nd dword output { + mov eax,edx + shr eax,15 + and eax,0x1E + mov cx,[ebx+eax] + ror cx,1 + shl ecx,16 + + mov eax,edx + shr eax,19 + and eax,0x1E + mov cx,[ebx+eax] + ror cx,1 + + mov [edi],ecx + add edi,4 + ; } + + ; 3rd dword output { + mov eax,edx + shr eax,7 + and eax,0x1E + mov cx,[ebx+eax] + ror cx,1 + shl ecx,16 + + mov eax,edx + shr eax,11 + and eax,0x1E + mov cx,[ebx+eax] + ror cx,1 + + mov [edi],ecx + add edi,4 + ; } + + ; 4th dword output { + mov eax,edx + shl eax,1 + and eax,0x1E + mov cx,[ebx+eax] + ror cx,1 + shl ecx,16 + + shr edx,3 + and edx,0x1E + mov cx,[ebx+edx] + ror cx,1 + + mov [edi],ecx + add edi,4 + ; } + ; * + + pop ecx + + dec ecx + jnz .x_loop_2 + + mov eax,esi + add eax,[ebp + %$line] + mov esi,[ebp + %$src] + sub eax,esi + and eax,0x7FF + add esi,eax + add edi,[ebp + %$ext] + + pop ecx + dec ecx + jnz .y_loop + +.end_y_loop: + pop edi + pop esi + pop ebx +endproc ;asmLoad4bCI + +proc asmLoad4bIAPal +CPU 586 + %$src arg + %$dst arg + %$wid_64 arg + %$height arg + %$line arg + %$ext arg + %$pal arg +ia4pal: + push ebx + push esi + push edi + + mov ebx,[ebp + %$pal] + mov esi,[ebp + %$src] + mov edi,[ebp + %$dst] + mov ecx,[ebp + %$height] +.y_loop: + push ecx + mov ecx,[ebp + %$wid_64] +.x_loop: + push ecx + + mov eax,[esi] ; read all 8 pixels + bswap eax + add esi,4 + mov edx,eax + + ; 1st dword output { + shr eax,23 + and eax,0x1E + mov cx,[ebx+eax] + ror cx,8 + shl ecx,16 + + mov eax,edx + shr eax,27 + and eax,0x1E + mov cx,[ebx+eax] + ror cx,8 + + mov [edi],ecx + add edi,4 + ; } + + ; 2nd dword output { + mov eax,edx + shr eax,15 + and eax,0x1E + mov cx,[ebx+eax] + ror cx,8 + shl ecx,16 + + mov eax,edx + shr eax,19 + and eax,0x1E + mov cx,[ebx+eax] + ror cx,8 + + mov [edi],ecx + add edi,4 + ; } + + ; 3rd dword output { + mov eax,edx + shr eax,7 + and eax,0x1E + mov cx,[ebx+eax] + ror cx,8 + shl ecx,16 + + mov eax,edx + shr eax,11 + and eax,0x1E + mov cx,[ebx+eax] + ror cx,8 + + mov [edi],ecx + add edi,4 + ; } + + ; 4th dword output { + mov eax,edx + shl eax,1 + and eax,0x1E + mov cx,[ebx+eax] + ror cx,8 + shl ecx,16 + + shr edx,3 + and edx,0x1E + mov cx,[ebx+edx] + ror cx,8 + + mov [edi],ecx + add edi,4 + ; } + + ; * copy + mov eax,[esi] ; read all 8 pixels + bswap eax + add esi,4 + mov edx,eax + + ; 1st dword output { + shr eax,23 + and eax,0x1E + mov cx,[ebx+eax] + ror cx,8 + shl ecx,16 + + mov eax,edx + shr eax,27 + and eax,0x1E + mov cx,[ebx+eax] + ror cx,8 + + mov [edi],ecx + add edi,4 + ; } + + ; 2nd dword output { + mov eax,edx + shr eax,15 + and eax,0x1E + mov cx,[ebx+eax] + ror cx,8 + shl ecx,16 + + mov eax,edx + shr eax,19 + and eax,0x1E + mov cx,[ebx+eax] + ror cx,8 + + mov [edi],ecx + add edi,4 + ; } + + ; 3rd dword output { + mov eax,edx + shr eax,7 + and eax,0x1E + mov cx,[ebx+eax] + ror cx,8 + shl ecx,16 + + mov eax,edx + shr eax,11 + and eax,0x1E + mov cx,[ebx+eax] + ror cx,8 + + mov [edi],ecx + add edi,4 + ; } + + ; 4th dword output { + mov eax,edx + shl eax,1 + and eax,0x1E + mov cx,[ebx+eax] + ror cx,8 + shl ecx,16 + + shr edx,3 + and edx,0x1E + mov cx,[ebx+edx] + ror cx,8 + + mov [edi],ecx + add edi,4 + ; } + ; * + + pop ecx + + dec ecx + jnz .x_loop + + pop ecx + dec ecx + jz near .end_y_loop + push ecx + + mov eax,esi + add eax,[ebp + %$line] + mov esi,[ebp + %$src] + sub eax,esi + and eax,0x7FF + add esi,eax + add edi,[ebp + %$ext] + + mov ecx,[ebp + %$wid_64] +.x_loop_2: + push ecx + + mov eax,[esi+4] ; read all 8 pixels + bswap eax + mov edx,eax + + ; 1st dword output { + shr eax,23 + and eax,0x1E + mov cx,[ebx+eax] + ror cx,8 + shl ecx,16 + + mov eax,edx + shr eax,27 + and eax,0x1E + mov cx,[ebx+eax] + ror cx,8 + + mov [edi],ecx + add edi,4 + ; } + + ; 2nd dword output { + mov eax,edx + shr eax,15 + and eax,0x1E + mov cx,[ebx+eax] + ror cx,8 + shl ecx,16 + + mov eax,edx + shr eax,19 + and eax,0x1E + mov cx,[ebx+eax] + ror cx,8 + + mov [edi],ecx + add edi,4 + ; } + + ; 3rd dword output { + mov eax,edx + shr eax,7 + and eax,0x1E + mov cx,[ebx+eax] + ror cx,8 + shl ecx,16 + + mov eax,edx + shr eax,11 + and eax,0x1E + mov cx,[ebx+eax] + ror cx,8 + + mov [edi],ecx + add edi,4 + ; } + + ; 4th dword output { + mov eax,edx + shl eax,1 + and eax,0x1E + mov cx,[ebx+eax] + ror cx,8 + shl ecx,16 + + shr edx,3 + and edx,0x1E + mov cx,[ebx+edx] + ror cx,8 + + mov [edi],ecx + add edi,4 + ; } + + ; * copy + mov eax,[esi] ; read all 8 pixels + bswap eax + mov edx,esi + add edx,8 + mov esi,[ebp + %$src] + sub edx,esi + and edx,0x7FF + add esi,edx + mov edx,eax + + ; 1st dword output { + shr eax,23 + and eax,0x1E + mov cx,[ebx+eax] + ror cx,8 + shl ecx,16 + + mov eax,edx + shr eax,27 + and eax,0x1E + mov cx,[ebx+eax] + ror cx,8 + + mov [edi],ecx + add edi,4 + ; } + + ; 2nd dword output { + mov eax,edx + shr eax,15 + and eax,0x1E + mov cx,[ebx+eax] + ror cx,8 + shl ecx,16 + + mov eax,edx + shr eax,19 + and eax,0x1E + mov cx,[ebx+eax] + ror cx,8 + + mov [edi],ecx + add edi,4 + ; } + + ; 3rd dword output { + mov eax,edx + shr eax,7 + and eax,0x1E + mov cx,[ebx+eax] + ror cx,8 + shl ecx,16 + + mov eax,edx + shr eax,11 + and eax,0x1E + mov cx,[ebx+eax] + ror cx,8 + + mov [edi],ecx + add edi,4 + ; } + + ; 4th dword output { + mov eax,edx + shl eax,1 + and eax,0x1E + mov cx,[ebx+eax] + ror cx,8 + shl ecx,16 + + shr edx,3 + and edx,0x1E + mov cx,[ebx+edx] + ror cx,8 + + mov [edi],ecx + add edi,4 + ; } + ; * + + pop ecx + + dec ecx + jnz .x_loop_2 + + mov eax,esi + add eax,[ebp + %$line] + mov esi,[ebp + %$src] + sub eax,esi + and eax,0x7FF + add esi,eax + add edi,[ebp + %$ext] + + pop ecx + dec ecx + jnz .y_loop + +.end_y_loop: + pop edi + pop esi + pop ebx +endproc ;asmLoad4bIAPal + +;**************************************************************** +; Size: 0, Format: 3 +; +; ** BY GUGAMAN ** +; 2009 ported to NASM - Sergey (Gonetz) Lipski + +proc asmLoad4bIA +CPU 586 + %$src arg + %$dst arg + %$wid_64 arg + %$height arg + %$line arg + %$ext arg +ia4: + push ebx + push esi + push edi + + mov esi,[ebp + %$src] + mov edi,[ebp + %$dst] + mov ecx,[ebp + %$height] +.y_loop: + push ecx + mov ecx,[ebp + %$wid_64] +.x_loop: + push ecx + + mov eax,[esi] ; read all 8 pixels + bswap eax + add esi,4 + mov edx,eax + + ; 1st dword { + xor ecx,ecx + + ; pixel #1 + ; IIIAxxxxxxxxxxxxxxxxxxxxxxxxxxxx + ; xxxxxxxxxxxxxxxxxxxxxxxxAAAAIIII + mov eax,edx + shr eax,24 ;Alpha + and eax,0x00000010 + or ecx,eax + shl eax,1 + or ecx,eax + shl eax,1 + or ecx,eax + shl eax,1 + or ecx,eax + mov eax,edx + shr eax,28 ; Intensity + and eax,0x0000000E + or ecx,eax + shr eax,3 + or ecx,eax + + ; pixel #2 + ; xxxxIIIAxxxxxxxxxxxxxxxxxxxxxxxx + ; xxxxxxxxxxxxxxxxAAAAIIIIxxxxxxxx + mov eax,edx + shr eax,12 ;Alpha + and eax,0x00001000 + or ecx,eax + shl eax,1 + or ecx,eax + shl eax,1 + or ecx,eax + shl eax,1 + or ecx,eax + mov eax,edx + shr eax,16 ; Intensity + and eax,0x00000E00 + or ecx,eax + shr eax,3 + and eax,0x00000100 + or ecx,eax + + ; pixel #3 + ; xxxxxxxxIIIAxxxxxxxxxxxxxxxxxxxx + ; xxxxxxxxAAAAIIIIxxxxxxxxxxxxxxxx + ;Alpha + mov eax,edx + and eax,0x00100000 + or ecx,eax + shl eax,1 + or ecx,eax + shl eax,1 + or ecx,eax + shl eax,1 + or ecx,eax + mov eax,edx + shr eax,4 ; Intensity + and eax,0x000E0000 + or ecx,eax + shr eax,3 + and eax,0x00010000 + or ecx,eax + + ; pixel #4 + ; xxxxxxxxxxxxIIIAxxxxxxxxxxxxxxxx + ; AAAAIIIIxxxxxxxxxxxxxxxxxxxxxxxx + mov eax,edx + shl eax,12 ;Alpha + and eax,0x10000000 + or ecx,eax + shl eax,1 + or ecx,eax + shl eax,1 + or ecx,eax + shl eax,1 + or ecx,eax + mov eax,edx + shl eax,8 ; Intensity + and eax,0x0E000000 + or ecx,eax + shr eax,3 + and eax,0x01000000 + or ecx,eax + + + mov [edi],ecx + add edi,4 + ; } + +; 2nd dword { + xor ecx,ecx + + ; pixel #5 + ; xxxxxxxxxxxxxxxxIIIAxxxxxxxxxxxx + ; xxxxxxxxxxxxxxxxxxxxxxxxAAAAIIII + mov eax,edx + shr eax,8 ;Alpha + and eax,0x00000010 + or ecx,eax + shl eax,1 + or ecx,eax + shl eax,1 + or ecx,eax + shl eax,1 + or ecx,eax + mov eax,edx + shr eax,12 ; Intensity + and eax,0x0000000E + or ecx,eax + shr eax,3 + or ecx,eax + + ; pixel #6 + ; xxxxxxxxxxxxxxxxxxxxIIIAxxxxxxxx + ; xxxxxxxxxxxxxxxxAAAAIIIIxxxxxxxx + ;Alpha + mov eax,edx + shl eax,4 + and eax,0x00001000 + or ecx,eax + shl eax,1 + or ecx,eax + shl eax,1 + or ecx,eax + shl eax,1 + or ecx,eax + mov eax,edx ; Intensity + and eax,0x00000E00 + or ecx,eax + shr eax,3 + and eax,0x00000100 + or ecx,eax + + ; pixel #7 + ; xxxxxxxxxxxxxxxxxxxxxxxxIIIAxxxx + ; xxxxxxxxAAAAIIIIxxxxxxxxxxxxxxxx + ;Alpha + mov eax,edx + shl eax,16 + and eax,0x00100000 + or ecx,eax + shl eax,1 + or ecx,eax + shl eax,1 + or ecx,eax + shl eax,1 + or ecx,eax + mov eax,edx + shl eax,12 ; Intensity + and eax,0x000E0000 + or ecx,eax + shr eax,3 + and eax,0x00010000 + or ecx,eax + + ; pixel #8 + ; xxxxxxxxxxxxxxxxxxxxxxxxxxxxIIIA + ; AAAAIIIIxxxxxxxxxxxxxxxxxxxxxxxx + mov eax,edx + shl eax,28 ;Alpha + and eax,0x10000000 + or ecx,eax + shl eax,1 + or ecx,eax + shl eax,1 + or ecx,eax + shl eax,1 + or ecx,eax + mov eax,edx + shl eax,24 ; Intensity + and eax,0x0E000000 + or ecx,eax + shr eax,3 + and eax,0x01000000 + or ecx,eax + + mov [edi],ecx + add edi,4 + ; } + + ; * copy + mov eax,[esi] ; read all 8 pixels + bswap eax + add esi,4 + mov edx,eax + + ; 1st dword { + xor ecx,ecx + + ; pixel #1 + ; IIIAxxxxxxxxxxxxxxxxxxxxxxxxxxxx + ; xxxxxxxxxxxxxxxxxxxxxxxxAAAAIIII + mov eax,edx + shr eax,24 ;Alpha + and eax,0x00000010 + or ecx,eax + shl eax,1 + or ecx,eax + shl eax,1 + or ecx,eax + shl eax,1 + or ecx,eax + mov eax,edx + shr eax,28 ; Intensity + and eax,0x0000000E + or ecx,eax + shr eax,3 + or ecx,eax + + ; pixel #2 + ; xxxxIIIAxxxxxxxxxxxxxxxxxxxxxxxx + ; xxxxxxxxxxxxxxxxAAAAIIIIxxxxxxxx + mov eax,edx + shr eax,12 ;Alpha + and eax,0x00001000 + or ecx,eax + shl eax,1 + or ecx,eax + shl eax,1 + or ecx,eax + shl eax,1 + or ecx,eax + mov eax,edx + shr eax,16 ; Intensity + and eax,0x00000E00 + or ecx,eax + shr eax,3 + and eax,0x00000100 + or ecx,eax + + ; pixel #3 + ; xxxxxxxxIIIAxxxxxxxxxxxxxxxxxxxx + ; xxxxxxxxAAAAIIIIxxxxxxxxxxxxxxxx + ;Alpha + mov eax,edx + and eax,0x00100000 + or ecx,eax + shl eax,1 + or ecx,eax + shl eax,1 + or ecx,eax + shl eax,1 + or ecx,eax + mov eax,edx + shr eax,4 ; Intensity + and eax,0x000E0000 + or ecx,eax + shr eax,3 + and eax,0x00010000 + or ecx,eax + + ; pixel #4 + ; xxxxxxxxxxxxIIIAxxxxxxxxxxxxxxxx + ; AAAAIIIIxxxxxxxxxxxxxxxxxxxxxxxx + mov eax,edx + shl eax,12 ;Alpha + and eax,0x10000000 + or ecx,eax + shl eax,1 + or ecx,eax + shl eax,1 + or ecx,eax + shl eax,1 + or ecx,eax + mov eax,edx + shl eax,8 ; Intensity + and eax,0x0E000000 + or ecx,eax + shr eax,3 + and eax,0x01000000 + or ecx,eax + + + mov [edi],ecx + add edi,4 + ; } + +; 2nd dword { + xor ecx,ecx + + ; pixel #5 + ; xxxxxxxxxxxxxxxxIIIAxxxxxxxxxxxx + ; xxxxxxxxxxxxxxxxxxxxxxxxAAAAIIII + mov eax,edx + shr eax,8 ;Alpha + and eax,0x00000010 + or ecx,eax + shl eax,1 + or ecx,eax + shl eax,1 + or ecx,eax + shl eax,1 + or ecx,eax + mov eax,edx + shr eax,12 ; Intensity + and eax,0x0000000E + or ecx,eax + shr eax,3 + or ecx,eax + + ; pixel #6 + ; xxxxxxxxxxxxxxxxxxxxIIIAxxxxxxxx + ; xxxxxxxxxxxxxxxxAAAAIIIIxxxxxxxx + ;Alpha + mov eax,edx + shl eax,4 + and eax,0x00001000 + or ecx,eax + shl eax,1 + or ecx,eax + shl eax,1 + or ecx,eax + shl eax,1 + or ecx,eax + mov eax,edx ; Intensity + and eax,0x00000E00 + or ecx,eax + shr eax,3 + and eax,0x00000100 + or ecx,eax + + ; pixel #7 + ; xxxxxxxxxxxxxxxxxxxxxxxxIIIAxxxx + ; xxxxxxxxAAAAIIIIxxxxxxxxxxxxxxxx + ;Alpha + mov eax,edx + shl eax,16 + and eax,0x00100000 + or ecx,eax + shl eax,1 + or ecx,eax + shl eax,1 + or ecx,eax + shl eax,1 + or ecx,eax + mov eax,edx + shl eax,12 ; Intensity + and eax,0x000E0000 + or ecx,eax + shr eax,3 + and eax,0x00010000 + or ecx,eax + + ; pixel #8 + ; xxxxxxxxxxxxxxxxxxxxxxxxxxxxIIIA + ; AAAAIIIIxxxxxxxxxxxxxxxxxxxxxxxx + mov eax,edx + shl eax,28 ;Alpha + and eax,0x10000000 + or ecx,eax + shl eax,1 + or ecx,eax + shl eax,1 + or ecx,eax + shl eax,1 + or ecx,eax + mov eax,edx + shl eax,24 ; Intensity + and eax,0x0E000000 + or ecx,eax + shr eax,3 + and eax,0x01000000 + or ecx,eax + + mov [edi],ecx + add edi,4 + ; } + + ; * + + pop ecx + dec ecx + jnz .x_loop + + pop ecx + dec ecx + jz near .end_y_loop + push ecx + + add esi,[ebp + %$line] + add edi,[ebp + %$ext] + + mov ecx,[ebp + %$wid_64] +.x_loop_2: + push ecx + + mov eax,[esi+4] ; read all 8 pixels + bswap eax + mov edx,eax + + ; 1st dword { + xor ecx,ecx + + ; pixel #1 + ; IIIAxxxxxxxxxxxxxxxxxxxxxxxxxxxx + ; xxxxxxxxxxxxxxxxxxxxxxxxAAAAIIII + mov eax,edx + shr eax,24 ;Alpha + and eax,0x00000010 + or ecx,eax + shl eax,1 + or ecx,eax + shl eax,1 + or ecx,eax + shl eax,1 + or ecx,eax + mov eax,edx + shr eax,28 ; Intensity + and eax,0x0000000E + or ecx,eax + shr eax,3 + or ecx,eax + + ; pixel #2 + ; xxxxIIIAxxxxxxxxxxxxxxxxxxxxxxxx + ; xxxxxxxxxxxxxxxxAAAAIIIIxxxxxxxx + mov eax,edx + shr eax,12 ;Alpha + and eax,0x00001000 + or ecx,eax + shl eax,1 + or ecx,eax + shl eax,1 + or ecx,eax + shl eax,1 + or ecx,eax + mov eax,edx + shr eax,16 ; Intensity + and eax,0x00000E00 + or ecx,eax + shr eax,3 + and eax,0x00000100 + or ecx,eax + + ; pixel #3 + ; xxxxxxxxIIIAxxxxxxxxxxxxxxxxxxxx + ; xxxxxxxxAAAAIIIIxxxxxxxxxxxxxxxx + ;Alpha + mov eax,edx + and eax,0x00100000 + or ecx,eax + shl eax,1 + or ecx,eax + shl eax,1 + or ecx,eax + shl eax,1 + or ecx,eax + mov eax,edx + shr eax,4 ; Intensity + and eax,0x000E0000 + or ecx,eax + shr eax,3 + and eax,0x00010000 + or ecx,eax + + ; pixel #4 + ; xxxxxxxxxxxxIIIAxxxxxxxxxxxxxxxx + ; AAAAIIIIxxxxxxxxxxxxxxxxxxxxxxxx + mov eax,edx + shl eax,12 ;Alpha + and eax,0x10000000 + or ecx,eax + shl eax,1 + or ecx,eax + shl eax,1 + or ecx,eax + shl eax,1 + or ecx,eax + mov eax,edx + shl eax,8 ; Intensity + and eax,0x0E000000 + or ecx,eax + shr eax,3 + and eax,0x01000000 + or ecx,eax + + + mov [edi],ecx + add edi,4 + ; } + +; 2nd dword { + xor ecx,ecx + + ; pixel #5 + ; xxxxxxxxxxxxxxxxIIIAxxxxxxxxxxxx + ; xxxxxxxxxxxxxxxxxxxxxxxxAAAAIIII + mov eax,edx + shr eax,8 ;Alpha + and eax,0x00000010 + or ecx,eax + shl eax,1 + or ecx,eax + shl eax,1 + or ecx,eax + shl eax,1 + or ecx,eax + mov eax,edx + shr eax,12 ; Intensity + and eax,0x0000000E + or ecx,eax + shr eax,3 + or ecx,eax + + ; pixel #6 + ; xxxxxxxxxxxxxxxxxxxxIIIAxxxxxxxx + ; xxxxxxxxxxxxxxxxAAAAIIIIxxxxxxxx + ;Alpha + mov eax,edx + shl eax,4 + and eax,0x00001000 + or ecx,eax + shl eax,1 + or ecx,eax + shl eax,1 + or ecx,eax + shl eax,1 + or ecx,eax + mov eax,edx ; Intensity + and eax,0x00000E00 + or ecx,eax + shr eax,3 + and eax,0x00000100 + or ecx,eax + + ; pixel #7 + ; xxxxxxxxxxxxxxxxxxxxxxxxIIIAxxxx + ; xxxxxxxxAAAAIIIIxxxxxxxxxxxxxxxx + ;Alpha + mov eax,edx + shl eax,16 + and eax,0x00100000 + or ecx,eax + shl eax,1 + or ecx,eax + shl eax,1 + or ecx,eax + shl eax,1 + or ecx,eax + mov eax,edx + shl eax,12 ; Intensity + and eax,0x000E0000 + or ecx,eax + shr eax,3 + and eax,0x00010000 + or ecx,eax + + ; pixel #8 + ; xxxxxxxxxxxxxxxxxxxxxxxxxxxxIIIA + ; AAAAIIIIxxxxxxxxxxxxxxxxxxxxxxxx + mov eax,edx + shl eax,28 ;Alpha + and eax,0x10000000 + or ecx,eax + shl eax,1 + or ecx,eax + shl eax,1 + or ecx,eax + shl eax,1 + or ecx,eax + mov eax,edx + shl eax,24 ; Intensity + and eax,0x0E000000 + or ecx,eax + shr eax,3 + and eax,0x01000000 + or ecx,eax + + mov [edi],ecx + add edi,4 + ; } + + ; * copy + mov eax,[esi] ; read all 8 pixels + bswap eax + add esi,8 + mov edx,eax + +; 1st dword { + xor ecx,ecx + + ; pixel #1 + ; IIIAxxxxxxxxxxxxxxxxxxxxxxxxxxxx + ; xxxxxxxxxxxxxxxxxxxxxxxxAAAAIIII + mov eax,edx + shr eax,24 ;Alpha + and eax,0x00000010 + or ecx,eax + shl eax,1 + or ecx,eax + shl eax,1 + or ecx,eax + shl eax,1 + or ecx,eax + mov eax,edx + shr eax,28 ; Intensity + and eax,0x0000000E + or ecx,eax + shr eax,3 + or ecx,eax + + ; pixel #2 + ; xxxxIIIAxxxxxxxxxxxxxxxxxxxxxxxx + ; xxxxxxxxxxxxxxxxAAAAIIIIxxxxxxxx + mov eax,edx + shr eax,12 ;Alpha + and eax,0x00001000 + or ecx,eax + shl eax,1 + or ecx,eax + shl eax,1 + or ecx,eax + shl eax,1 + or ecx,eax + mov eax,edx + shr eax,16 ; Intensity + and eax,0x00000E00 + or ecx,eax + shr eax,3 + and eax,0x00000100 + or ecx,eax + + ; pixel #3 + ; xxxxxxxxIIIAxxxxxxxxxxxxxxxxxxxx + ; xxxxxxxxAAAAIIIIxxxxxxxxxxxxxxxx + ;Alpha + mov eax,edx + and eax,0x00100000 + or ecx,eax + shl eax,1 + or ecx,eax + shl eax,1 + or ecx,eax + shl eax,1 + or ecx,eax + mov eax,edx + shr eax,4 ; Intensity + and eax,0x000E0000 + or ecx,eax + shr eax,3 + and eax,0x00010000 + or ecx,eax + + ; pixel #4 + ; xxxxxxxxxxxxIIIAxxxxxxxxxxxxxxxx + ; AAAAIIIIxxxxxxxxxxxxxxxxxxxxxxxx + mov eax,edx + shl eax,12 ;Alpha + and eax,0x10000000 + or ecx,eax + shl eax,1 + or ecx,eax + shl eax,1 + or ecx,eax + shl eax,1 + or ecx,eax + mov eax,edx + shl eax,8 ; Intensity + and eax,0x0E000000 + or ecx,eax + shr eax,3 + and eax,0x01000000 + or ecx,eax + + + mov [edi],ecx + add edi,4 + ; } + +; 2nd dword { + xor ecx,ecx + + ; pixel #5 + ; xxxxxxxxxxxxxxxxIIIAxxxxxxxxxxxx + ; xxxxxxxxxxxxxxxxxxxxxxxxAAAAIIII + mov eax,edx + shr eax,8 ;Alpha + and eax,0x00000010 + or ecx,eax + shl eax,1 + or ecx,eax + shl eax,1 + or ecx,eax + shl eax,1 + or ecx,eax + mov eax,edx + shr eax,12 ; Intensity + and eax,0x0000000E + or ecx,eax + shr eax,3 + or ecx,eax + + ; pixel #6 + ; xxxxxxxxxxxxxxxxxxxxIIIAxxxxxxxx + ; xxxxxxxxxxxxxxxxAAAAIIIIxxxxxxxx + ;Alpha + mov eax,edx + shl eax,4 + and eax,0x00001000 + or ecx,eax + shl eax,1 + or ecx,eax + shl eax,1 + or ecx,eax + shl eax,1 + or ecx,eax + mov eax,edx ; Intensity + and eax,0x00000E00 + or ecx,eax + shr eax,3 + and eax,0x00000100 + or ecx,eax + + ; pixel #7 + ; xxxxxxxxxxxxxxxxxxxxxxxxIIIAxxxx + ; xxxxxxxxAAAAIIIIxxxxxxxxxxxxxxxx + ;Alpha + mov eax,edx + shl eax,16 + and eax,0x00100000 + or ecx,eax + shl eax,1 + or ecx,eax + shl eax,1 + or ecx,eax + shl eax,1 + or ecx,eax + mov eax,edx + shl eax,12 ; Intensity + and eax,0x000E0000 + or ecx,eax + shr eax,3 + and eax,0x00010000 + or ecx,eax + + ; pixel #8 + ; xxxxxxxxxxxxxxxxxxxxxxxxxxxxIIIA + ; AAAAIIIIxxxxxxxxxxxxxxxxxxxxxxxx + mov eax,edx + shl eax,28 ;Alpha + and eax,0x10000000 + or ecx,eax + shl eax,1 + or ecx,eax + shl eax,1 + or ecx,eax + shl eax,1 + or ecx,eax + mov eax,edx + shl eax,24 ; Intensity + and eax,0x0E000000 + or ecx,eax + shr eax,3 + and eax,0x01000000 + or ecx,eax + + mov [edi],ecx + add edi,4 + ; } + ; * + + pop ecx + dec ecx + jnz .x_loop_2 + + add esi,[ebp + %$line] + add edi,[ebp + %$ext] + + pop ecx + dec ecx + jnz .y_loop + +.end_y_loop: + pop edi + pop esi + pop ebx +endproc ;asmLoad4bIA + +;**************************************************************** +; Size: 0, Format: 4 +; 2009 ported to NASM - Sergey (Gonetz) Lipski + +proc asmLoad4bI +CPU 586 + %$src arg + %$dst arg + %$wid_64 arg + %$height arg + %$line arg + %$ext arg +i4: + push ebx + push esi + push edi + + mov esi,[ebp + %$src] + mov edi,[ebp + %$dst] + mov ecx,[ebp + %$height] +.y_loop: + push ecx + mov ecx,[ebp + %$wid_64] +.x_loop: + push ecx + + mov eax,[esi] ; read all 8 pixels + bswap eax + add esi,4 + mov edx,eax + + ; 1st dword { + xor ecx,ecx + shr eax,28 ; 0xF0000000 -> 0x0000000F + or ecx,eax + shl eax,4 + or ecx,eax + + mov eax,edx ; 0x0F000000 -> 0x00000F00 + shr eax,16 + and eax,0x00000F00 + or ecx,eax + shl eax,4 + or ecx,eax + + mov eax,edx + shr eax,4 ; 0x00F00000 -> 0x000F0000 + and eax,0x000F0000 + or ecx,eax + shl eax,4 + or ecx,eax + + mov eax,edx + shl eax,8 ; 0x000F0000 -> 0x0F000000 + and eax,0x0F000000 + or ecx,eax + shl eax,4 + or ecx,eax + + mov [edi],ecx + add edi,4 + ; } + + ; 2nd dword { + xor ecx,ecx + mov eax,edx + shr eax,12 ; 0x0000F000 -> 0x0000000F + and eax,0x0000000F + or ecx,eax + shl eax,4 + or ecx,eax + + mov eax,edx ; 0x00000F00 -> 0x00000F00 + and eax,0x00000F00 + or ecx,eax + shl eax,4 + or ecx,eax + + mov eax,edx + shl eax,12 ; 0x000000F0 -> 0x000F0000 + and eax,0x000F0000 + or ecx,eax + shl eax,4 + or ecx,eax + + shl edx,24 ; 0x0000000F -> 0x0F000000 + and edx,0x0F000000 + or ecx,edx + shl edx,4 + or ecx,edx + + mov [edi],ecx + add edi,4 + ; } + + ; * copy + mov eax,[esi] ; read all 8 pixels + bswap eax + add esi,4 + mov edx,eax + + ; 1st dword { + xor ecx,ecx + shr eax,28 ; 0xF0000000 -> 0x0000000F + or ecx,eax + shl eax,4 + or ecx,eax + + mov eax,edx ; 0x0F000000 -> 0x00000F00 + shr eax,16 + and eax,0x00000F00 + or ecx,eax + shl eax,4 + or ecx,eax + + mov eax,edx + shr eax,4 ; 0x00F00000 -> 0x000F0000 + and eax,0x000F0000 + or ecx,eax + shl eax,4 + or ecx,eax + + mov eax,edx + shl eax,8 ; 0x000F0000 -> 0x0F000000 + and eax,0x0F000000 + or ecx,eax + shl eax,4 + or ecx,eax + + mov [edi],ecx + add edi,4 + ; } + + ; 2nd dword { + xor ecx,ecx + mov eax,edx + shr eax,12 ; 0x0000F000 -> 0x0000000F + and eax,0x0000000F + or ecx,eax + shl eax,4 + or ecx,eax + + mov eax,edx ; 0x00000F00 -> 0x00000F00 + and eax,0x00000F00 + or ecx,eax + shl eax,4 + or ecx,eax + + mov eax,edx + shl eax,12 ; 0x000000F0 -> 0x000F0000 + and eax,0x000F0000 + or ecx,eax + shl eax,4 + or ecx,eax + + shl edx,24 ; 0x0000000F -> 0x0F000000 + and edx,0x0F000000 + or ecx,edx + shl edx,4 + or ecx,edx + + mov [edi],ecx + add edi,4 + ; } + ; * + + pop ecx + dec ecx + jnz .x_loop + + pop ecx + dec ecx + jz near .end_y_loop + push ecx + + add esi,[ebp + %$line] + add edi,[ebp + %$ext] + + mov ecx,[ebp + %$wid_64] +.x_loop_2: + push ecx + + mov eax,[esi+4] ; read all 8 pixels + bswap eax + mov edx,eax + + ; 1st dword { + xor ecx,ecx + shr eax,28 ; 0xF0000000 -> 0x0000000F + or ecx,eax + shl eax,4 + or ecx,eax + + mov eax,edx ; 0x0F000000 -> 0x00000F00 + shr eax,16 + and eax,0x00000F00 + or ecx,eax + shl eax,4 + or ecx,eax + + mov eax,edx + shr eax,4 ; 0x00F00000 -> 0x000F0000 + and eax,0x000F0000 + or ecx,eax + shl eax,4 + or ecx,eax + + mov eax,edx + shl eax,8 ; 0x000F0000 -> 0x0F000000 + and eax,0x0F000000 + or ecx,eax + shl eax,4 + or ecx,eax + + mov [edi],ecx + add edi,4 + ; } + + ; 2nd dword { + xor ecx,ecx + mov eax,edx + shr eax,12 ; 0x0000F000 -> 0x0000000F + and eax,0x0000000F + or ecx,eax + shl eax,4 + or ecx,eax + + mov eax,edx ; 0x00000F00 -> 0x00000F00 + and eax,0x00000F00 + or ecx,eax + shl eax,4 + or ecx,eax + + mov eax,edx + shl eax,12 ; 0x000000F0 -> 0x000F0000 + and eax,0x000F0000 + or ecx,eax + shl eax,4 + or ecx,eax + + shl edx,24 ; 0x0000000F -> 0x0F000000 + and edx,0x0F000000 + or ecx,edx + shl edx,4 + or ecx,edx + + mov [edi],ecx + add edi,4 + ; } + + ; * copy + mov eax,[esi] ; read all 8 pixels + bswap eax + add esi,8 + mov edx,eax + + ; 1st dword { + xor ecx,ecx + shr eax,28 ; 0xF0000000 -> 0x0000000F + or ecx,eax + shl eax,4 + or ecx,eax + + mov eax,edx ; 0x0F000000 -> 0x00000F00 + shr eax,16 + and eax,0x00000F00 + or ecx,eax + shl eax,4 + or ecx,eax + + mov eax,edx + shr eax,4 ; 0x00F00000 -> 0x000F0000 + and eax,0x000F0000 + or ecx,eax + shl eax,4 + or ecx,eax + + mov eax,edx + shl eax,8 ; 0x000F0000 -> 0x0F000000 + and eax,0x0F000000 + or ecx,eax + shl eax,4 + or ecx,eax + + mov [edi],ecx + add edi,4 + ; } + + ; 2nd dword { + xor ecx,ecx + mov eax,edx + shr eax,12 ; 0x0000F000 -> 0x0000000F + and eax,0x0000000F + or ecx,eax + shl eax,4 + or ecx,eax + + mov eax,edx ; 0x00000F00 -> 0x00000F00 + and eax,0x00000F00 + or ecx,eax + shl eax,4 + or ecx,eax + + mov eax,edx + shl eax,12 ; 0x000000F0 -> 0x000F0000 + and eax,0x000F0000 + or ecx,eax + shl eax,4 + or ecx,eax + + shl edx,24 ; 0x0000000F -> 0x0F000000 + and edx,0x0F000000 + or ecx,edx + shl edx,4 + or ecx,edx + + mov [edi],ecx + add edi,4 + ; } + ; * + + pop ecx + dec ecx + jnz .x_loop_2 + + add esi,[ebp + %$line] + add edi,[ebp + %$ext] + + pop ecx + dec ecx + jnz .y_loop + +.end_y_loop: + pop edi + pop esi + pop ebx +endproc ;asmLoad4bI + +;**************************************************************** +;8b textures load +;**************************************************************** + +;**************************************************************** +; Size: 1, Format: 2 +; +; 2008.03.29 cleaned up - H.Morii +; 2009 ported to NASM - Sergey (Gonetz) Lipski + +proc asmLoad8bCI +CPU 586 + %$src arg + %$dst arg + %$wid_64 arg + %$height arg + %$line arg + %$ext arg + %$pal arg +ci8: + push ebx + push esi + push edi + + mov ebx,[ebp + %$pal] + mov esi,[ebp + %$src] + mov edi,[ebp + %$dst] + mov ecx,[ebp + %$height] +.y_loop: + push ecx + mov ecx,[ebp + %$wid_64] +.x_loop: + push ecx + + mov eax,[esi] ; read all 4 pixels + bswap eax + add esi,4 + mov edx,eax + + ; 1st dword output { + shr eax,15 + and eax,0x1FE + mov cx,[ebx+eax] + ror cx,1 + shl ecx,16 + + mov eax,edx + shr eax,23 + and eax,0x1FE + mov cx,[ebx+eax] + ror cx,1 + + mov [edi],ecx + add edi,4 + ; } + + ; 2nd dword output { + mov eax,edx + shl eax,1 + and eax,0x1FE + mov cx,[ebx+eax] + ror cx,1 + shl ecx,16 + + shr edx,7 + and edx,0x1FE + mov cx,[ebx+edx] + ror cx,1 + + mov [edi],ecx + add edi,4 + ; } + + ; * copy + mov eax,[esi] ; read all 4 pixels + bswap eax + add esi,4 + mov edx,eax + + ; 1st dword output { + shr eax,15 + and eax,0x1FE + mov cx,[ebx+eax] + ror cx,1 + shl ecx,16 + + mov eax,edx + shr eax,23 + and eax,0x1FE + mov cx,[ebx+eax] + ror cx,1 + + mov [edi],ecx + add edi,4 + ; } + + ; 2nd dword output { + mov eax,edx + shl eax,1 + and eax,0x1FE + mov cx,[ebx+eax] + ror cx,1 + shl ecx,16 + + shr edx,7 + and edx,0x1FE + mov cx,[ebx+edx] + ror cx,1 + + mov [edi],ecx + add edi,4 + ; } + ; * + + pop ecx + + dec ecx + jnz .x_loop + + pop ecx + dec ecx + jz near .end_y_loop + push ecx + + mov eax,esi + add eax,[ebp + %$line] + mov esi,[ebp + %$src] + sub eax,esi + and eax,0x7FF + add esi,eax + add edi,[ebp + %$ext] + + mov ecx,[ebp + %$wid_64] +.x_loop_2: + push ecx + + mov eax,[esi+4] ; read all 4 pixels + bswap eax + mov edx,eax + + ; 1st dword output { + shr eax,15 + and eax,0x1FE + mov cx,[ebx+eax] + ror cx,1 + shl ecx,16 + + mov eax,edx + shr eax,23 + and eax,0x1FE + mov cx,[ebx+eax] + ror cx,1 + + mov [edi],ecx + add edi,4 + ; } + + ; 2nd dword output { + mov eax,edx + shl eax,1 + and eax,0x1FE + mov cx,[ebx+eax] + ror cx,1 + shl ecx,16 + + shr edx,7 + and edx,0x1FE + mov cx,[ebx+edx] + ror cx,1 + + mov [edi],ecx + add edi,4 + ; } + + ; * copy + mov eax,[esi] ; read all 4 pixels + bswap eax + mov edx,esi + add edx,8 + mov esi,[ebp + %$src] + sub edx,esi + and edx,0x7FF + add esi,edx + mov edx,eax + + ; 1st dword output { + shr eax,15 + and eax,0x1FE + mov cx,[ebx+eax] + ror cx,1 + shl ecx,16 + + mov eax,edx + shr eax,23 + and eax,0x1FE + mov cx,[ebx+eax] + ror cx,1 + + mov [edi],ecx + add edi,4 + ; } + + ; 2nd dword output { + mov eax,edx + shl eax,1 + and eax,0x1FE + mov cx,[ebx+eax] + ror cx,1 + shl ecx,16 + + shr edx,7 + and edx,0x1FE + mov cx,[ebx+edx] + ror cx,1 + + mov [edi],ecx + add edi,4 + ; } + ; * + + pop ecx + + dec ecx + jnz .x_loop_2 + + mov eax,esi + add eax,[ebp + %$line] + mov esi,[ebp + %$src] + sub eax,esi + and eax,0x7FF + add esi,eax + add edi,[ebp + %$ext] + + pop ecx + dec ecx + jnz .y_loop + +.end_y_loop: + pop edi + pop esi + pop ebx +endproc ;asmLoad8bCI + +proc asmLoad8bIA8 +CPU 586 + %$src arg + %$dst arg + %$wid_64 arg + %$height arg + %$line arg + %$ext arg + %$pal arg +ia88: + push ebx + push esi + push edi + + mov ebx,[ebp + %$pal] + mov esi,[ebp + %$src] + mov edi,[ebp + %$dst] + mov ecx,[ebp + %$height] +.y_loop: + push ecx + mov ecx,[ebp + %$wid_64] +.x_loop: + push ecx + + mov eax,[esi] ; read all 4 pixels + bswap eax + add esi,4 + mov edx,eax + + ; 1st dword output { + shr eax,15 + and eax,0x1FE + mov cx,[ebx+eax] + ror cx,8 + shl ecx,16 + + mov eax,edx + shr eax,23 + and eax,0x1FE + mov cx,[ebx+eax] + ror cx,8 + + mov [edi],ecx + add edi,4 + ; } + + ; 2nd dword output { + mov eax,edx + shl eax,1 + and eax,0x1FE + mov cx,[ebx+eax] + ror cx,8 + shl ecx,16 + + shr edx,7 + and edx,0x1FE + mov cx,[ebx+edx] + ror cx,8 + + mov [edi],ecx + add edi,4 + ; } + + ; * copy + mov eax,[esi] ; read all 4 pixels + bswap eax + add esi,4 + mov edx,eax + + ; 1st dword output { + shr eax,15 + and eax,0x1FE + mov cx,[ebx+eax] + ror cx,8 + shl ecx,16 + + mov eax,edx + shr eax,23 + and eax,0x1FE + mov cx,[ebx+eax] + ror cx,8 + + mov [edi],ecx + add edi,4 + ; } + + ; 2nd dword output { + mov eax,edx + shl eax,1 + and eax,0x1FE + mov cx,[ebx+eax] + ror cx,8 + shl ecx,16 + + shr edx,7 + and edx,0x1FE + mov cx,[ebx+edx] + ror cx,8 + + mov [edi],ecx + add edi,4 + ; } + ; * + + pop ecx + + dec ecx + jnz .x_loop + + pop ecx + dec ecx + jz near .end_y_loop + push ecx + + add esi,[ebp + %$line] + add edi,[ebp + %$ext] + + mov ecx,[ebp + %$wid_64] +.x_loop_2: + push ecx + + mov eax,[esi+4] ; read all 4 pixels + bswap eax + mov edx,eax + + ; 1st dword output { + shr eax,15 + and eax,0x1FE + mov cx,[ebx+eax] + ror cx,8 + shl ecx,16 + + mov eax,edx + shr eax,23 + and eax,0x1FE + mov cx,[ebx+eax] + ror cx,8 + + mov [edi],ecx + add edi,4 + ; } + + ; 2nd dword output { + mov eax,edx + shl eax,1 + and eax,0x1FE + mov cx,[ebx+eax] + ror cx,8 + shl ecx,16 + + shr edx,7 + and edx,0x1FE + mov cx,[ebx+edx] + ror cx,8 + + mov [edi],ecx + add edi,4 + ; } + + ; * copy + mov eax,[esi] ; read all 4 pixels + bswap eax + add esi,8 + mov edx,eax + + ; 1st dword output { + shr eax,15 + and eax,0x1FE + mov cx,[ebx+eax] + ror cx,8 + shl ecx,16 + + mov eax,edx + shr eax,23 + and eax,0x1FE + mov cx,[ebx+eax] + ror cx,8 + + mov [edi],ecx + add edi,4 + ; } + + ; 2nd dword output { + mov eax,edx + shl eax,1 + and eax,0x1FE + mov cx,[ebx+eax] + ror cx,8 + shl ecx,16 + + shr edx,7 + and edx,0x1FE + mov cx,[ebx+edx] + ror cx,8 + + mov [edi],ecx + add edi,4 + ; } + ; * + + pop ecx + + dec ecx + jnz .x_loop_2 + + add esi,[ebp + %$line] + add edi,[ebp + %$ext] + + pop ecx + dec ecx + jnz .y_loop + +.end_y_loop: + pop edi + pop esi + pop ebx +endproc ;asmLoad8bIA8 + +;**************************************************************** +; Size: 1, Format: 3 +; +; ** by Gugaman ** +; +; 2008.03.29 cleaned up - H.Morii +; 2009 ported to NASM - Sergey (Gonetz) Lipski + +proc asmLoad8bIA4 +CPU 586 + %$src arg + %$dst arg + %$wid_64 arg + %$height arg + %$line arg + %$ext arg +ia84: + push ebx + push esi + push edi + + mov esi,[ebp + %$src] + mov edi,[ebp + %$dst] + mov ecx,[ebp + %$height] +.y_loop: + push ecx + mov ecx,[ebp + %$wid_64] +.x_loop: + mov eax,[esi] ; read all 4 pixels + mov edx,eax + + shr eax,4 ;all alpha + shl edx,4 + and eax,0x0F0F0F0F + and edx,0xF0F0F0F0 + add esi,4 + or eax,edx + + mov [edi],eax ; save dword + add edi,4 + + mov eax,[esi] ; read all 4 pixels + mov edx,eax + + shr eax,4 ;all alpha + shl edx,4 + and eax,0x0F0F0F0F + and edx,0xF0F0F0F0 + add esi,4 + or eax,edx + + mov [edi],eax ; save dword + add edi,4 + ; * + + dec ecx + jnz .x_loop + + pop ecx + dec ecx + jz .end_y_loop + push ecx + + add esi,[ebp + %$line] + add edi,[ebp + %$ext] + + mov ecx,[ebp + %$wid_64] +.x_loop_2: + mov eax,[esi+4] ; read both pixels + mov edx,eax + + shr eax,4 ;all alpha + shl edx,4 + and eax,0x0F0F0F0F + and edx,0xF0F0F0F0 + or eax,edx + + mov [edi],eax ;save dword + add edi,4 + + mov eax,[esi] ; read both pixels + add esi,8 + mov edx,eax + + shr eax,4 ;all alpha + shl edx,4 + and eax,0x0F0F0F0F + and edx,0xF0F0F0F0 + or eax,edx + + mov [edi],eax ;save dword + add edi,4 + ; * + + dec ecx + jnz .x_loop_2 + + add esi,[ebp + %$line] + add edi,[ebp + %$ext] + + pop ecx + dec ecx + jnz .y_loop + +.end_y_loop: + pop edi + pop esi + pop ebx +endproc ;asmLoad8bIA4 + +;**************************************************************** +; Size: 1, Format: 4 +; +; ** by Gugaman ** +; 2009 ported to NASM - Sergey (Gonetz) Lipski + +proc asmLoad8bI +CPU 586 + %$src arg + %$dst arg + %$wid_64 arg + %$height arg + %$line arg + %$ext arg +i8: + push ebx + push esi + push edi + + mov esi,[ebp + %$src] + mov edi,[ebp + %$dst] + mov ecx,[ebp + %$height] +.y_loop: + push ecx + mov ecx,[ebp + %$wid_64] +.x_loop: + mov eax,[esi] ; read all 4 pixels + add esi,4 + + mov [edi],eax ; save dword + add edi,4 + + mov eax,[esi] ; read all 4 pixels + add esi,4 + + mov [edi],eax ; save dword + add edi,4 + ; * + + dec ecx + jnz .x_loop + + pop ecx + dec ecx + jz .end_y_loop + push ecx + + add esi,[ebp + %$line] + add edi,[ebp + %$ext] + + mov ecx,[ebp + %$wid_64] +.x_loop_2: + mov eax,[esi+4] ; read both pixels + + mov [edi],eax ;save dword + add edi,4 + + mov eax,[esi] ; read both pixels + add esi,8 + + mov [edi],eax ;save dword + add edi,4 + ; * + + dec ecx + jnz .x_loop_2 + + add esi,[ebp + %$line] + add edi,[ebp + %$ext] + + pop ecx + dec ecx + jnz .y_loop + +.end_y_loop: + pop edi + pop esi + pop ebx +endproc ;asmLoad8bI + + +;**************************************************************** +;16b textures load +;**************************************************************** + +ALIGN 4 + +;**************************************************************** +; Size: 2, Format: 0 +; +; 2008.03.29 cleaned up - H.Morii +; 2009 ported to NASM - Sergey (Gonetz) Lipski + +proc asmLoad16bRGBA +CPU 586 + %$src arg + %$dst arg + %$wid_64 arg + %$height arg + %$line arg + %$ext arg +rgba16: + push ebx + push esi + push edi + + mov esi,[ebp + %$src] + mov edi,[ebp + %$dst] + mov ecx,[ebp + %$height] +.y_loop: + push ecx + mov ecx,[ebp + %$wid_64] +.x_loop: + mov eax,[esi] ; read both pixels + mov ebx,[esi+4] ; read both pixels + bswap eax + bswap ebx + + ror ax,1 + ror bx,1 + ror eax,16 + ror ebx,16 + ror ax,1 + ror bx,1 + + mov [edi],eax + mov [edi+4],ebx + add esi,8 + add edi,8 + + dec ecx + jnz .x_loop + + pop ecx + dec ecx + jz .end_y_loop + push ecx + + mov eax,esi + add eax,[ebp + %$line] + mov esi,[ebp + %$src] + sub eax, esi + and eax, 0xFFF + add esi, eax + add edi,[ebp + %$ext] + + mov ecx,[ebp + %$wid_64] +.x_loop_2: + mov eax,[esi+4] ; read both pixels + mov ebx,[esi] ; read both pixels + bswap eax + bswap ebx + + ror ax,1 + ror bx,1 + ror eax,16 + ror ebx,16 + ror ax,1 + ror bx,1 + + mov [edi],eax + mov [edi+4],ebx + add esi,8 + add edi,8 + + dec ecx + jnz .x_loop_2 + + mov eax,esi + add eax,[ebp + %$line] + mov esi,[ebp + %$src] + sub eax, esi + and eax, 0xFFF + add esi, eax + add edi,[ebp + %$ext] + + pop ecx + dec ecx + jnz .y_loop + +.end_y_loop: + pop edi + pop esi + pop ebx +endproc ;asmLoad16bRGBA + + +ALIGN 4 + +;**************************************************************** +; Size: 2, Format: 3 +; +; ** by Gugaman/Dave2001 ** +; +; 2008.03.29 cleaned up - H.Morii +; 2009 ported to NASM - Sergey (Gonetz) Lipski + +proc asmLoad16bIA +CPU 586 + %$src arg + %$dst arg + %$wid_64 arg + %$height arg + %$line arg + %$ext arg +ia16: + push ebx + push esi + push edi + + mov esi,[ebp + %$src] + mov edi,[ebp + %$dst] + mov ecx,[ebp + %$height] +.y_loop: + push ecx + mov ecx,[ebp + %$wid_64] +.x_loop: + mov eax,[esi] ; read both pixels + mov ebx,[esi+4] ; read both pixels + mov [edi],eax + mov [edi+4],ebx + add esi,8 + add edi,8 + + dec ecx + jnz .x_loop + + pop ecx + dec ecx + jz .end_y_loop + push ecx + + add esi,[ebp + %$line] + add edi,[ebp + %$ext] + + mov ecx,[ebp + %$wid_64] +.x_loop_2: + mov eax,[esi+4] ; read both pixels + mov ebx,[esi] ; read both pixels + mov [edi],eax + mov [edi+4],ebx + add esi,8 + add edi,8 + + dec ecx + jnz .x_loop_2 + + add esi,[ebp + %$line] + add edi,[ebp + %$ext] + + pop ecx + dec ecx + jnz .y_loop + +.end_y_loop: + pop edi + pop esi + pop ebx +endproc ;asmLoad16bIA + +;**************************************************************** +; +; ******** Textures mirror/clamp/wrap ******** +; +;**************************************************************** + +;**************************************************************** +;8b textures mirror/clamp/wrap +;**************************************************************** + +proc asmMirror8bS +CPU 586 + %$tex arg + %$start arg + %$width arg + %$height arg + %$mask arg + %$line arg + %$full arg + %$count arg +mirror8b: + push ebx + push esi + push edi + + mov edi,[ebp + %$start] + mov ecx,[ebp + %$height] +.loop_y: + + xor edx,edx +.loop_x: + mov esi,[ebp + %$tex] + mov ebx,[ebp + %$width] + add ebx,edx + and ebx,[ebp + %$width] + jnz .is_mirrored + + mov eax,edx + and eax,[ebp + %$mask] + add esi,eax + mov al,[esi] + mov [edi],al + inc edi + jmp .end_mirror_check +.is_mirrored: + add esi,[ebp + %$mask] + mov eax,edx + and eax,[ebp + %$mask] + sub esi,eax + mov al,[esi] + mov [edi],al + inc edi +.end_mirror_check: + + inc edx + cmp edx,[ebp + %$count] + jne .loop_x + + add edi,[ebp + %$line] + mov eax,[ebp + %$tex] + add eax,[ebp + %$full] + mov [ebp + %$tex],eax + + dec ecx + jnz .loop_y + + pop edi + pop esi + pop ebx +endproc ;asmMirror8bS + +proc asmWrap8bS +CPU 586 + %$tex arg + %$start arg + %$height arg + %$mask arg + %$line arg + %$full arg + %$count arg +wrap8b: + push ebx + push esi + push edi + + mov edi,[ebp + %$start] + mov ecx,[ebp + %$height] +.loop_y: + + xor edx,edx +.loop_x: + + mov esi,[ebp + %$tex] + mov eax,edx + and eax,[ebp + %$mask] + shl eax,2 + add esi,eax + mov eax,[esi] + mov [edi],eax + add edi,4 + + inc edx + cmp edx,[ebp + %$count] + jne .loop_x + + add edi,[ebp + %$line] + mov eax,[ebp + %$tex] + add eax,[ebp + %$full] + mov [ebp + %$tex],eax + + dec ecx + jnz .loop_y + + pop edi + pop esi + pop ebx +endproc ;asmWrap8bS + +proc asmClamp8bS +CPU 586 + %$tex arg + %$constant arg + %$height arg + %$line arg + %$full arg + %$count arg +clamp8b: + push ebx + push esi + push edi + + mov esi,[ebp + %$constant] + mov edi,[ebp + %$tex] + + mov ecx,[ebp + %$height] +.y_loop: + + mov al,[esi] + + mov edx,[ebp + %$count] +.x_loop: + + mov [edi],al ; don't unroll or make dword, it may go into next line (doesn't have to be multiple of two) + inc edi + + dec edx + jnz .x_loop + + add esi,[ebp + %$full] + add edi,[ebp + %$line] + + dec ecx + jnz .y_loop + + pop edi + pop esi + pop ebx +endproc ;asmClamp8bS + +;**************************************************************** +;16b textures mirror/clamp/wrap +;**************************************************************** + +proc asmMirror16bS +CPU 586 + %$tex arg + %$start arg + %$width arg + %$height arg + %$mask arg + %$line arg + %$full arg + %$count arg +mirror16b: + push ebx + push esi + push edi + + mov edi,[ebp + %$start] + mov ecx,[ebp + %$height] +.loop_y: + + xor edx,edx +.loop_x: + mov esi,[ebp + %$tex] + mov ebx,[ebp + %$width] + add ebx,edx + and ebx,[ebp + %$width] + jnz .is_mirrored + + mov eax,edx + shl eax,1 + and eax,[ebp + %$mask] + add esi,eax + mov ax,[esi] + mov [edi],ax + add edi,2 + jmp .end_mirror_check +.is_mirrored: + add esi,[ebp + %$mask] + mov eax,edx + shl eax,1 + and eax,[ebp + %$mask] + sub esi,eax + mov ax,[esi] + mov [edi],ax + add edi,2 +.end_mirror_check: + + inc edx + cmp edx,[ebp + %$count] + jne .loop_x + + add edi,[ebp + %$line] + mov eax,[ebp + %$tex] + add eax,[ebp + %$full] + mov [ebp + %$tex],eax + + dec ecx + jnz .loop_y + + pop edi + pop esi + pop ebx +endproc ;asmMirror16bS + +proc asmWrap16bS +CPU 586 + %$tex arg + %$start arg + %$height arg + %$mask arg + %$line arg + %$full arg + %$count arg +wrap16b: + push ebx + push esi + push edi + + mov edi,[ebp + %$start] + mov ecx,[ebp + %$height] +.loop_y: + + xor edx,edx +.loop_x: + + mov esi,[ebp + %$tex] + mov eax,edx + and eax,[ebp + %$mask] + shl eax,2 + add esi,eax + mov eax,[esi] + mov [edi],eax + add edi,4 + + inc edx + cmp edx,[ebp + %$count] + jne .loop_x + + add edi,[ebp + %$line] + mov eax,[ebp + %$tex] + add eax,[ebp + %$full] + mov [ebp + %$tex],eax + + dec ecx + jnz .loop_y + + pop edi + pop esi + pop ebx +endproc ;asmWrap16bS + + +proc asmClamp16bS +CPU 586 + %$tex arg + %$constant arg + %$height arg + %$line arg + %$full arg + %$count arg +clamp16b: + push ebx + push esi + push edi + + mov esi,[ebp + %$constant] + mov edi,[ebp + %$tex] + + mov ecx,[ebp + %$height] +.y_loop: + + mov ax,[esi] + + mov edx,[ebp + %$count] +.x_loop: + + mov [edi],ax ; don't unroll or make dword, it may go into next line (doesn't have to be multiple of two) + add edi,2 + + dec edx + jnz .x_loop + + add esi,[ebp + %$full] + add edi,[ebp + %$line] + + dec ecx + jnz .y_loop + + pop edi + pop esi + pop ebx +endproc ;asmClamp16bS + +;**************************************************************** +;32b textures mirror/clamp/wrap +;**************************************************************** + +proc asmMirror32bS +CPU 586 + %$tex arg + %$start arg + %$width arg + %$height arg + %$mask arg + %$line arg + %$full arg + %$count arg +mirror32b: + push ebx + push esi + push edi + + mov edi,[ebp + %$start] + mov ecx,[ebp + %$height] +.loop_y: + + xor edx,edx +.loop_x: + mov esi,[ebp + %$tex] + mov ebx,[ebp + %$width] + add ebx,edx + and ebx,[ebp + %$width] + jnz .is_mirrored + + mov eax,edx + shl eax,2 + and eax,[ebp + %$mask] + add esi,eax + mov eax,[esi] + mov [edi],eax + add edi,4 + jmp .end_mirror_check +.is_mirrored: + add esi,[ebp + %$mask] + mov eax,edx + shl eax,2 + and eax,[ebp + %$mask] + sub esi,eax + mov eax,[esi] + mov [edi],eax + add edi,4 +.end_mirror_check: + + inc edx + cmp edx,[ebp + %$count] + jne .loop_x + + add edi,[ebp + %$line] + mov eax,[ebp + %$tex] + add eax,[ebp + %$full] + mov [ebp + %$tex],eax + + dec ecx + jnz .loop_y + + pop edi + pop esi + pop ebx +endproc ;asmMirror32bS + +proc asmWrap32bS +CPU 586 + %$tex arg + %$start arg + %$height arg + %$mask arg + %$line arg + %$full arg + %$count arg +wrap32b: + push ebx + push esi + push edi + + mov edi,[ebp + %$start] + mov ecx,[ebp + %$height] +.loop_y: + + xor edx,edx +.loop_x: + + mov esi,[ebp + %$tex] + mov eax,edx + and eax,[ebp + %$mask] + shl eax,2 + add esi,eax + mov eax,[esi] + mov [edi],eax + add edi,4 + + inc edx + cmp edx,[ebp + %$count] + jne .loop_x + + add edi,[ebp + %$line] + mov eax,[ebp + %$tex] + add eax,[ebp + %$full] + mov [ebp + %$tex],eax + + dec ecx + jnz .loop_y + + pop edi + pop esi + pop ebx +endproc ;asmWrap32bS + +proc asmClamp32bS +CPU 586 + %$tex arg + %$constant arg + %$height arg + %$line arg + %$full arg + %$count arg +clamp32b: + push ebx + push esi + push edi + + mov esi,[ebp + %$constant] + mov edi,[ebp + %$tex] + + mov ecx,[ebp + %$height] +.y_loop: + + mov eax,[esi] + + mov edx,[ebp + %$count] +.x_loop: + + mov [edi],eax ; don't unroll or make dword, it may go into next line (doesn't have to be multiple of two) + add edi,4 + + dec edx + jnz .x_loop + + add esi,[ebp + %$full] + add edi,[ebp + %$line] + + dec ecx + jnz .y_loop + + pop edi + pop esi + pop ebx +endproc ;asmClamp32bS + +;**************************************************************** +; +; ******** Textures conversion ******** +; +;**************************************************************** + +proc asmTexConv_ARGB1555_ARGB4444 +CPU 586 + %$src arg + %$dst arg + %$size arg +argb1555_argb4444: + push ebx + push esi + push edi + + mov esi,[ebp + %$src] + mov edi,[ebp + %$dst] + mov ecx,[ebp + %$size] + +.tc1_loop: + mov eax,[esi] + add esi,4 + + ; arrr rrgg gggb bbbb + ; aaaa rrrr gggg bbbb + mov edx,eax + and eax,0x80008000 + mov ebx,eax ; ebx = 0xa000000000000000 + shr eax,1 + or ebx,eax ; ebx = 0xaa00000000000000 + shr eax,1 + or ebx,eax ; ebx = 0xaaa0000000000000 + shr eax,1 + or ebx,eax ; ebx = 0xaaaa000000000000 + + mov eax,edx + and eax,0x78007800 ; eax = 0x0rrrr00000000000 + shr eax,3 ; eax = 0x0000rrrr00000000 + or ebx,eax ; ebx = 0xaaaarrrr00000000 + + mov eax,edx + and eax,0x03c003c0 ; eax = 0x000000gggg000000 + shr eax,2 ; eax = 0x00000000gggg0000 + or ebx,eax ; ebx = 0xaaaarrrrgggg0000 + + and edx,0x001e001e ; edx = 0x00000000000bbbb0 + shr edx,1 ; edx = 0x000000000000bbbb + or ebx,edx ; ebx = 0xaaaarrrrggggbbbb + + mov [edi],ebx + add edi,4 + + dec ecx + jnz .tc1_loop + + pop edi + pop esi + pop ebx +endproc ;asmTexConv_ARGB1555_ARGB4444 + +proc asmTexConv_AI88_ARGB4444 +CPU 586 + %$src arg + %$dst arg + %$size arg +ai88_argb4444: + push ebx + push esi + push edi + + mov esi,[ebp + %$src] + mov edi,[ebp + %$dst] + mov ecx,[ebp + %$size] + +.tc1_loop: + mov eax,[esi] + add esi,4 + + ; aaaa aaaa iiii iiii + ; aaaa rrrr gggg bbbb + mov edx,eax + and eax,0xF000F000 ; eax = 0xaaaa000000000000 + mov ebx,eax ; ebx = 0xaaaa000000000000 + + and edx,0x00F000F0 ; edx = 0x00000000iiii0000 + shl edx,4 ; edx = 0x0000iiii00000000 + or ebx,edx ; ebx = 0xaaaaiiii00000000 + shr edx,4 ; edx = 0x00000000iiii0000 + or ebx,edx ; ebx = 0xaaaaiiiiiiii0000 + shr edx,4 ; edx = 0x000000000000iiii + or ebx,edx ; ebx = 0xaaaaiiiiiiiiiiii + + mov [edi],ebx + add edi,4 + + dec ecx + jnz .tc1_loop + + pop edi + pop esi + pop ebx +endproc ;asmTexConv_AI88_ARGB4444 + +proc asmTexConv_AI44_ARGB4444 +CPU 586 + %$src arg + %$dst arg + %$size arg +ai44_argb4444: + push ebx + push esi + push edi + + mov esi,[ebp + %$src] + mov edi,[ebp + %$dst] + mov ecx,[ebp + %$size] + +.tc1_loop: + mov eax,[esi] + add esi,4 + + ; aaaa3 iiii3 aaaa2 iiii2 aaaa1 iiii1 aaaa0 iiii0 + ; aaaa1 rrrr1 gggg1 bbbb1 aaaa0 rrrr0 gggg0 bbbb0 + ; aaaa3 rrrr3 gggg3 bbbb3 aaaa2 rrrr2 gggg2 bbbb2 + mov edx,eax ; eax = aaaa3 iiii3 aaaa2 iiii2 aaaa1 iiii1 aaaa0 iiii0 + shl eax,16 ; eax = aaaa1 iiii1 aaaa0 iiii0 0000 0000 0000 0000 + and eax,0xFF000000 ; eax = aaaa1 iiii1 0000 0000 0000 0000 0000 0000 + mov ebx,eax ; ebx = aaaa1 iiii1 0000 0000 0000 0000 0000 0000 + and eax,0x0F000000 ; eax = 0000 iiii1 0000 0000 0000 0000 0000 0000 + shr eax,4 ; eax = 0000 0000 iiii1 0000 0000 0000 0000 0000 + or ebx,eax ; ebx = aaaa1 iiii1 iiii1 0000 0000 0000 0000 0000 + shr eax,4 ; eax = 0000 0000 0000 iiii1 0000 0000 0000 0000 + or ebx,eax ; ebx = aaaa1 iiii1 iiii1 iiii1 0000 0000 0000 0000 + + mov eax,edx ; eax = aaaa3 iiii3 aaaa2 iiii2 aaaa1 iiii1 aaaa0 iiii0 + shl eax,8 ; eax = aaaa2 iiii2 aaaa1 iiii1 aaaa0 iiii0 0000 0000 + and eax,0x0000FF00 ; eax = 0000 0000 0000 0000 aaaa0 iiii0 0000 0000 + or ebx,eax ; ebx = aaaa1 iiii1 iiii1 iiii1 aaaa0 iiii0 0000 0000 + and eax,0x00000F00 ; eax = 0000 0000 0000 0000 0000 iiii0 0000 0000 + shr eax,4 ; eax = 0000 0000 0000 0000 0000 0000 iiii0 0000 + or ebx,eax ; ebx = aaaa1 iiii1 iiii1 iiii1 aaaa0 iiii0 iiii0 0000 + shr eax,4 ; eax = 0000 0000 0000 0000 0000 0000 0000 iiii0 + or ebx,eax ; ebx = aaaa1 iiii1 iiii1 iiii1 aaaa0 iiii0 iiii0 iiii0 + + mov [edi],ebx + add edi,4 + + mov eax,edx ; eax = aaaa3 iiii3 aaaa2 iiii2 aaaa1 iiii1 aaaa0 iiii0 + and eax,0xFF000000 ; eax = aaaa3 iiii3 0000 0000 0000 0000 0000 0000 + mov ebx,eax ; ebx = aaaa3 iiii3 0000 0000 0000 0000 0000 0000 + and eax,0x0F000000 ; eax = 0000 iiii3 0000 0000 0000 0000 0000 0000 + shr eax,4 ; eax = 0000 0000 iiii3 0000 0000 0000 0000 0000 + or ebx,eax ; ebx = aaaa3 iiii3 iiii3 0000 0000 0000 0000 0000 + shr eax,4 ; eax = 0000 0000 0000 iiii3 0000 0000 0000 0000 + or ebx,eax ; ebx = aaaa3 iiii3 iiii3 iiii3 0000 0000 0000 0000 + + ; edx = aaaa3 iiii3 aaaa2 iiii2 aaaa1 iiii1 aaaa0 iiii0 + shr edx,8 ; edx = 0000 0000 aaaa3 aaaa3 aaaa2 iiii2 aaaa1 iiii1 + and edx,0x0000FF00 ; edx = 0000 0000 0000 0000 aaaa2 iiii2 0000 0000 + or ebx,edx ; ebx = aaaa3 iiii3 iiii3 iiii3 aaaa2 iiii2 0000 0000 + and edx,0x00000F00 ; edx = 0000 0000 0000 0000 0000 iiii2 0000 0000 + shr edx,4 ; edx = 0000 0000 0000 0000 0000 0000 iiii2 0000 + or ebx,edx ; ebx = aaaa3 iiii3 iiii3 iiii3 aaaa2 iiii2 iiii2 0000 + shr edx,4 ; edx = 0000 0000 0000 0000 0000 0000 0000 iiii2 + or ebx,edx ; ebx = aaaa3 iiii3 iiii3 iiii3 aaaa2 iiii2 iiii2 iiii2 + + mov [edi],ebx + add edi,4 + + dec ecx + jnz .tc1_loop + + pop edi + pop esi + pop ebx +endproc ;asmTexConv_AI44_ARGB4444 + +proc asmTexConv_A8_ARGB4444 +CPU 586 + %$src arg + %$dst arg + %$size arg +a8_argb4444: + push ebx + push esi + push edi + + mov esi,[ebp + %$src] + mov edi,[ebp + %$dst] + mov ecx,[ebp + %$size] + +.tc1_loop: + mov eax,[esi] + add esi,4 + + ; aaaa3 aaaa3 aaaa2 aaaa2 aaaa1 aaaa1 aaaa0 aaaa0 + ; aaaa1 rrrr1 gggg1 bbbb1 aaaa0 rrrr0 gggg0 bbbb0 + ; aaaa3 rrrr3 gggg3 bbbb3 aaaa2 rrrr2 gggg2 bbbb2 + mov edx,eax + and eax,0x0000F000 ; eax = 00 00 00 00 a1 00 00 00 + shl eax,16 ; eax = a1 00 00 00 00 00 00 00 + mov ebx,eax ; ebx = a1 00 00 00 00 00 00 00 + shr eax,4 + or ebx,eax ; ebx = a1 a1 00 00 00 00 00 00 + shr eax,4 + or ebx,eax ; ebx = a1 a1 a1 00 00 00 00 00 + shr eax,4 + or ebx,eax ; ebx = a1 a1 a1 a1 00 00 00 00 + + mov eax,edx + and eax,0x000000F0 ; eax = 00 00 00 00 00 00 a0 00 + shl eax,8 ; eax = 00 00 00 00 a0 00 00 00 + or ebx,eax + shr eax,4 + or ebx,eax + shr eax,4 + or ebx,eax + shr eax,4 + or ebx,eax ; ebx = a1 a1 a1 a1 a0 a0 a0 a0 + + mov [edi],ebx + add edi,4 + + mov eax,edx ; eax = a3 a3 a2 a2 a1 a1 a0 a0 + and eax,0xF0000000 ; eax = a3 00 00 00 00 00 00 00 + mov ebx,eax ; ebx = a3 00 00 00 00 00 00 00 + shr eax,4 + or ebx,eax ; ebx = a3 a3 00 00 00 00 00 00 + shr eax,4 + or ebx,eax ; ebx = a3 a3 a3 00 00 00 00 00 + shr eax,4 + or ebx,eax ; ebx = a3 a3 a3 a3 00 00 00 00 + + and edx,0x00F00000 ; eax = 00 00 a2 00 00 00 00 00 + shr edx,8 ; eax = 00 00 00 00 a2 00 00 00 + or ebx,edx + shr edx,4 + or ebx,edx + shr edx,4 + or ebx,edx + shr edx,4 + or ebx,edx ; ebx = a3 a3 a3 a3 a2 a2 a2 a2 + + mov [edi],ebx + add edi,4 + + dec ecx + jnz .tc1_loop + + pop edi + pop esi + pop ebx +endproc ;asmTexConv_A8_ARGB4444 + +;**************************************************************** +; +; ******** Tmem functions ******** +; +;**************************************************************** + +;**************************************************************** +; CopyBlock - copies a block from base_addr+offset to dest_addr, while unswapping the +; data within. +; +; edi = dest_addr -> end of dest +; ecx = num_words +; esi = base_addr (preserved) +; edx = offset (preserved) +;**************************************************************** + +ALIGN 4 + +global CopyBlock +CopyBlock: +CPU 586 + push eax + push ebx + push esi + push edx + + or ecx,ecx + jz near copyblock_end + + push ecx + + ; first, set the source address and check if not on a dword boundary + push esi + push edx + mov ebx,edx + and edx,0FFFFFFFCh + add esi,edx + + and ebx,3 ; ebx = # we DON'T need to copy + jz copyblock_copy + + mov edx,4 ; ecx = # we DO need to copy + sub edx,ebx + + ; load the first word, accounting for swapping + + mov eax,[esi] + add esi,4 +copyblock_precopy_skip: + rol eax,8 + dec ebx + jnz copyblock_precopy_skip + +copyblock_precopy_copy: + rol eax,8 + mov [edi],al + inc edi + dec edx + jnz copyblock_precopy_copy + + mov eax,[esi] + add esi,4 + bswap eax + mov [edi],eax + add edi,4 + + dec ecx ; 1 less word to copy + jz copyblock_postcopy + +copyblock_copy: + mov eax,[esi] + bswap eax + mov [edi],eax + + mov eax,[esi+4] + bswap eax + mov [edi+4],eax + + add esi,8 + add edi,8 + + dec ecx + jnz copyblock_copy + +copyblock_postcopy: + pop edx + pop esi + pop ecx + + ; check again if on dword boundary + mov ebx,edx ; ebx = # we DO need to copy + + and ebx,3 + jz copyblock_end + + shl ecx,3 ; ecx = num_words * 8 + add edx,ecx + and edx,0FFFFFFFCh + add esi,edx + + mov eax,[esi] + +copyblock_postcopy_copy: + rol eax,8 + mov [edi],al + inc edi + dec ebx + jnz copyblock_postcopy_copy + +copyblock_end: + pop edx + pop esi + pop ebx + pop eax + ret + +;**************************************************************** +; SwapBlock - swaps every other 32-bit word at addr +; +; ecx = num_words -> 0 +; edi = addr -> end of dest +;**************************************************************** + +ALIGN 4 + +global SwapBlock32 +SwapBlock32: +CPU 586 + push eax + push ebx + or ecx,ecx + jz swapblock32_end +swapblock32_loop: + mov eax,[edi] + mov ebx,[edi+4] + mov [edi],ebx + mov [edi+4],eax + add edi,8 + dec ecx + jnz swapblock32_loop +swapblock32_end: + pop ebx + pop eax + ret + +;**************************************************************** +; +; ******** Load block/tile ******** +; +;**************************************************************** + +proc asmLoadBlock +CPU 586 + %$src arg + %$dst arg + %$off arg + %$dxt arg + %$cnt arg + %$swp arg + + push ebx + push esi + push edi + + ; copy the data + mov esi,[ebp + %$src] + mov edi,[ebp + %$dst] + mov ecx,[ebp + %$cnt] + mov edx,[ebp + %$off] + call CopyBlock + + ; now swap it + mov eax,[ebp + %$cnt] ; eax = count remaining + xor edx,edx ; edx = dxt counter + mov edi,[ebp + %$dst] + mov ebx,[ebp + %$dxt] + + xor ecx,ecx ; ecx = how much to copy +dxt_test: + add edi,8 + dec eax + jz end_dxt_test + add edx,ebx + jns dxt_test + +dxt_s_test: + inc ecx + dec eax + jz end_dxt_test + add edx,ebx + js dxt_s_test + + ; swap this data (ecx set, dst set) + call [ebp + %$swp] ; (ecx reset to 0 after) + + jmp dxt_test ; and repeat + +end_dxt_test: + ; swap any remaining data + call [ebp + %$swp] + + pop edi + pop esi + pop ebx +endproc ;asmLoadBlock + + +proc asmLoadTile +CPU 586 + %$src arg + %$dst arg + %$width arg + %$height arg + %$line arg + %$off arg + %$end arg + %$swp arg + + push ebx + push esi + push edi + + ; set initial values + mov edi,[ebp + %$dst] + mov ecx,[ebp + %$width] + mov esi,[ebp + %$src] + mov edx,[ebp + %$off] + xor ebx,ebx ; swap this line? + mov eax,[ebp + %$height] + +loadtile_loop: + cmp [ebp + %$end],edi ; end of tmem: error + jc loadtile_end + + ; copy this line + push edi + push ecx + call CopyBlock + pop ecx + + ; swap it? + xor ebx,1 + jnz loadtile_no_swap + + ; (ecx set, restore edi) + pop edi + push ecx + call [ebp + %$swp] + pop ecx + jmp loadtile_swap_end +loadtile_no_swap: + add sp,4 ; forget edi, we are already at the next position +loadtile_swap_end: + + add edx,[ebp + %$line] + + dec eax + jnz loadtile_loop + +loadtile_end: + + pop edi + pop esi + pop ebx +endproc ;asmLoadTile + + +;**************************************************************** +; +; ******** Texture CRC ******** +; +;**************************************************************** + +proc asmTextureCRC +CPU 586 + %$addr arg + %$width arg + %$height arg + %$line arg + + push ebx + push edi + + xor eax,eax ; eax is final result + mov ebx,[ebp + %$line] + mov ecx,[ebp + %$height] ; ecx is height counter + mov edi,[ebp + %$addr] ; edi is ptr to texture memory +crc_loop_y: + push ecx + + mov ecx,[ebp + %$width] +crc_loop_x: + + add eax,[edi] ; MUST be 64-bit aligned, so manually unroll + add eax,[edi+4] + mov edx,ecx + mul edx + add eax,edx + add edi,8 + + dec ecx + jnz crc_loop_x + + pop ecx + + mov edx,ecx + mul edx + add eax,edx + + add edi,ebx + + dec ecx + jnz crc_loop_y + + pop edi + pop ebx +endproc ;asmTextureCRC diff --git a/Source/Glide64/Util.cpp b/Source/Glide64/Util.cpp new file mode 100644 index 000000000..76d186db2 --- /dev/null +++ b/Source/Glide64/Util.cpp @@ -0,0 +1,2182 @@ +/* +* Glide64 - Glide video plugin for Nintendo 64 emulators. +* Copyright (c) 2002 Dave2001 +* Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski +* +* 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 +* 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 +*/ + +//**************************************************************** +// +// Glide64 - Glide Plugin for Nintendo 64 emulators +// Project started on December 29th, 2001 +// +// Authors: +// Dave2001, original author, founded the project in 2001, left it in 2002 +// Gugaman, joined the project in 2002, left it in 2002 +// Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002 +// Hiroshi 'KoolSmoky' Morii, joined the project in 2007 +// +//**************************************************************** +// +// To modify Glide64: +// * Write your name and (optional)email, commented by your work, so I know who did it, and so that you can find which parts you modified when it comes time to send it to me. +// * Do NOT send me the whole project or file that you modified. Take out your modified code sections, and tell me where to put them. If people sent the whole thing, I would have many different versions, but no idea how to combine them all. +// +//**************************************************************** + +#include "Gfx #1.3.h" +#include "Util.h" +#include "Combine.h" +#include "3dmath.h" +#include "Debugger.h" +#include "TexCache.h" +#include "DepthBufferRender.h" + +#define Vj rdp.vtxbuf2[j] +#define Vi rdp.vtxbuf2[i] + +VERTEX *vtx_list1[32]; // vertex indexing +VERTEX *vtx_list2[32]; + +// +// util_init - initialize data for the functions in this file +// + +void util_init () +{ + for (int i=0; i<32; i++) + { + vtx_list1[i] = &rdp.vtx1[i]; + vtx_list2[i] = &rdp.vtx2[i]; + } +} + +static wxUint32 u_cull_mode = 0; + +//software backface culling. Gonetz +// mega modifications by Dave2001 +int cull_tri(VERTEX **v) // type changed to VERTEX** [Dave2001] +{ + int i; + + if (v[0]->scr_off & v[1]->scr_off & v[2]->scr_off) + { + LRDP (" clipped\n"); + return TRUE; + } + + // Triangle can't be culled, if it need clipping + int draw = FALSE; + + for (i=0; i<3; i++) + { + if (!v[i]->screen_translated) + { + v[i]->sx = rdp.view_trans[0] + v[i]->x_w * rdp.view_scale[0] + rdp.offset_x; + v[i]->sy = rdp.view_trans[1] + v[i]->y_w * rdp.view_scale[1] + rdp.offset_y; + v[i]->sz = rdp.view_trans[2] + v[i]->z_w * rdp.view_scale[2]; + v[i]->screen_translated = 1; + } + if (v[i]->w < 0.01f) //need clip_z. can't be culled now + draw = 1; + } + + u_cull_mode = (rdp.flags & CULLMASK); + if (draw || u_cull_mode == 0 || u_cull_mode == CULLMASK) //no culling set + { + u_cull_mode >>= CULLSHIFT; + return FALSE; + } + +#define SW_CULLING +#ifdef SW_CULLING +#if 1 // H.Morii - faster float comparisons with zero area check added + + const float x1 = v[0]->sx - v[1]->sx; + const float y1 = v[0]->sy - v[1]->sy; + const float x2 = v[2]->sx - v[1]->sx; + const float y2 = v[2]->sy - v[1]->sy; + const float area = y1*x2 - x1*y2; + + const int iarea = *(int*)&area; + const unsigned int mode = (u_cull_mode << 19UL); + u_cull_mode >>= CULLSHIFT; + + if ((iarea & 0x7FFFFFFF) == 0) + { + LRDP (" zero area triangles\n"); + return TRUE; + } + + if ((rdp.flags & CULLMASK) && ((int)(iarea ^ mode)) >= 0) + { + LRDP (" culled\n"); + return TRUE; + } +#else + + float x1 = v[0]->sx - v[1]->sx; + float y1 = v[0]->sy - v[1]->sy; + float x2 = v[2]->sx - v[1]->sx; + float y2 = v[2]->sy - v[1]->sy; + + u_cull_mode >>= CULLSHIFT; + switch (u_cull_mode) + { + case 1: // cull front + // if ((x1*y2 - y1*x2) < 0.0f) //counter-clockwise, positive + if ((y1*x2-x1*y2) < 0.0f) //counter-clockwise, positive + { + LRDP (" culled!\n"); + return TRUE; + } + return FALSE; + case 2: // cull back + // if ((x1*y2 - y1*x2) >= 0.0f) //clockwise, negative + if ((y1*x2-x1*y2) >= 0.0f) //clockwise, negative + { + LRDP (" culled!\n"); + return TRUE; + } + return FALSE; + } +#endif +#endif + + return FALSE; +} + + +void apply_shade_mods (VERTEX *v) +{ + float col[4]; + wxUint32 mod; + memcpy (col, rdp.col, 16); + + if (rdp.cmb_flags) + { + if (v->shade_mod == 0) + v->color_backup = *(wxUint32*)(&(v->b)); + else + *(wxUint32*)(&(v->b)) = v->color_backup; + mod = rdp.cmb_flags; + if (mod & CMB_SET) + { + if (col[0] > 1.0f) col[0] = 1.0f; + if (col[1] > 1.0f) col[1] = 1.0f; + if (col[2] > 1.0f) col[2] = 1.0f; + if (col[0] < 0.0f) col[0] = 0.0f; + if (col[1] < 0.0f) col[1] = 0.0f; + if (col[2] < 0.0f) col[2] = 0.0f; + v->r = (wxUint8)(255.0f * col[0]); + v->g = (wxUint8)(255.0f * col[1]); + v->b = (wxUint8)(255.0f * col[2]); + } + if (mod & CMB_A_SET) + { + if (col[3] > 1.0f) col[3] = 1.0f; + if (col[3] < 0.0f) col[3] = 0.0f; + v->a = (wxUint8)(255.0f * col[3]); + } + if (mod & CMB_SETSHADE_SHADEALPHA) + { + v->r = v->g = v->b = v->a; + } + if (mod & CMB_MULT_OWN_ALPHA) + { + float percent = v->a / 255.0f; + v->r = (wxUint8)(v->r * percent); + v->g = (wxUint8)(v->g * percent); + v->b = (wxUint8)(v->b * percent); + } + if (mod & CMB_MULT) + { + if (col[0] > 1.0f) col[0] = 1.0f; + if (col[1] > 1.0f) col[1] = 1.0f; + if (col[2] > 1.0f) col[2] = 1.0f; + if (col[0] < 0.0f) col[0] = 0.0f; + if (col[1] < 0.0f) col[1] = 0.0f; + if (col[2] < 0.0f) col[2] = 0.0f; + v->r = (wxUint8)(v->r * col[0]); + v->g = (wxUint8)(v->g * col[1]); + v->b = (wxUint8)(v->b * col[2]); + } + if (mod & CMB_A_MULT) + { + if (col[3] > 1.0f) col[3] = 1.0f; + if (col[3] < 0.0f) col[3] = 0.0f; + v->a = (wxUint8)(v->a * col[3]); + } + if (mod & CMB_SUB) + { + int r = v->r - (int)(255.0f * rdp.coladd[0]); + int g = v->g - (int)(255.0f * rdp.coladd[1]); + int b = v->b - (int)(255.0f * rdp.coladd[2]); + if (r < 0) r = 0; + if (g < 0) g = 0; + if (b < 0) b = 0; + v->r = (wxUint8)r; + v->g = (wxUint8)g; + v->b = (wxUint8)b; + } + if (mod & CMB_A_SUB) + { + int a = v->a - (int)(255.0f * rdp.coladd[3]); + if (a < 0) a = 0; + v->a = (wxUint8)a; + } + if (mod & CMB_ADD) + { + int r = v->r + (int)(255.0f * rdp.coladd[0]); + int g = v->g + (int)(255.0f * rdp.coladd[1]); + int b = v->b + (int)(255.0f * rdp.coladd[2]); + if (r > 255) r = 255; + if (g > 255) g = 255; + if (b > 255) b = 255; + v->r = (wxUint8)r; + v->g = (wxUint8)g; + v->b = (wxUint8)b; + } + if (mod & CMB_A_ADD) + { + int a = v->a + (int)(255.0f * rdp.coladd[3]); + if (a > 255) a = 255; + v->a = (wxUint8)a; + } + if (mod & CMB_COL_SUB_OWN) + { + int r = (wxUint8)(255.0f * rdp.coladd[0]) - v->r; + int g = (wxUint8)(255.0f * rdp.coladd[1]) - v->g; + int b = (wxUint8)(255.0f * rdp.coladd[2]) - v->b; + if (r < 0) r = 0; + if (g < 0) g = 0; + if (b < 0) b = 0; + v->r = (wxUint8)r; + v->g = (wxUint8)g; + v->b = (wxUint8)b; + } + v->shade_mod = cmb.shade_mod_hash; + } + if (rdp.cmb_flags_2 & CMB_INTER) + { + v->r = (wxUint8)(rdp.col_2[0] * rdp.shade_factor * 255.0f + v->r * (1.0f - rdp.shade_factor)); + v->g = (wxUint8)(rdp.col_2[1] * rdp.shade_factor * 255.0f + v->g * (1.0f - rdp.shade_factor)); + v->b = (wxUint8)(rdp.col_2[2] * rdp.shade_factor * 255.0f + v->b * (1.0f - rdp.shade_factor)); + v->shade_mod = cmb.shade_mod_hash; + } +} + +static int dzdx = 0; +static int deltaZ = 0; +VERTEX **org_vtx; + +void draw_tri (VERTEX **vtx, wxUint16 linew) +{ + deltaZ = dzdx = 0; + if (linew == 0 && (fb_depth_render_enabled || (rdp.rm & 0xC00) == 0xC00)) + { + double X0 = vtx[0]->sx / rdp.scale_x; + double Y0 = vtx[0]->sy / rdp.scale_y; + double X1 = vtx[1]->sx / rdp.scale_x; + double Y1 = vtx[1]->sy / rdp.scale_y; + double X2 = vtx[2]->sx / rdp.scale_x; + double Y2 = vtx[2]->sy / rdp.scale_y; + double diffy_02 = Y0 - Y2; + double diffy_12 = Y1 - Y2; + double diffx_02 = X0 - X2; + double diffx_12 = X1 - X2; + + double denom = (diffx_02 * diffy_12 - diffx_12 * diffy_02); + if(denom*denom > 0.0) + { + double diffz_02 = vtx[0]->sz - vtx[2]->sz; + double diffz_12 = vtx[1]->sz - vtx[2]->sz; + double fdzdx = (diffz_02 * diffy_12 - diffz_12 * diffy_02) / denom; + if ((rdp.rm & 0xC00) == 0xC00) { + // Calculate deltaZ per polygon for Decal z-mode + double fdzdy = (diffz_02 * diffx_12 - diffz_12 * diffx_02) / denom; + double fdz = fabs(fdzdx) + fabs(fdzdy); + if ((settings.hacks & hack_Zelda) && (rdp.rm & 0x800)) + fdz *= 4.0; // Decal mode in Zelda sometimes needs mutiplied deltaZ to work correct, e.g. roads + deltaZ = max(8, (int)fdz); + } + dzdx = (int)(fdzdx * 65536.0); + } + } + + org_vtx = vtx; + + for (int i=0; i<3; i++) + { + VERTEX *v = vtx[i]; + + if (v->uv_calculated != rdp.tex_ctr) + { +#ifdef EXTREME_LOGGING + FRDP(" * CALCULATING VERTEX U/V: %d\n", v->number); +#endif + v->uv_calculated = rdp.tex_ctr; + + if (!(rdp.geom_mode & 0x00020000)) + { + if (!(rdp.geom_mode & 0x00000200)) + { + if (rdp.geom_mode & 0x00000004) // flat shading + { + int flag = min(2, (rdp.cmd1 >> 24) & 3); + v->a = vtx[flag]->a; + v->b = vtx[flag]->b; + v->g = vtx[flag]->g; + v->r = vtx[flag]->r; +#ifdef EXTREME_LOGGING + FRDP(" * Flat shaded, flag%d - r: %d, g: %d, b: %d, a: %d\n", flag, v->r, v->g, v->b, v->a); +#endif + } + else // prim color + { +#ifdef EXTREME_LOGGING + FRDP(" * Prim shaded %08lx\n", rdp.prim_color); +#endif + v->a = (wxUint8)(rdp.prim_color & 0xFF); + v->b = (wxUint8)((rdp.prim_color >> 8) & 0xFF); + v->g = (wxUint8)((rdp.prim_color >> 16) & 0xFF); + v->r = (wxUint8)((rdp.prim_color >> 24) & 0xFF); + } + } + } + + // Fix texture coordinates + if (!v->uv_scaled) + { + v->ou *= rdp.tiles[rdp.cur_tile].s_scale; + v->ov *= rdp.tiles[rdp.cur_tile].t_scale; + v->uv_scaled = 1; + if (!rdp.Persp_en) + { +// v->oow = v->w = 1.0f; + v->ou *= 0.5f; + v->ov *= 0.5f; + } + } + v->u1 = v->u0 = v->ou; + v->v1 = v->v0 = v->ov; + + if (rdp.tex >= 1 && rdp.cur_cache[0]) + { + if (rdp.aTBuffTex[0]) + { + v->u0 += rdp.aTBuffTex[0]->u_shift + rdp.aTBuffTex[0]->tile_uls; + v->v0 += rdp.aTBuffTex[0]->v_shift + rdp.aTBuffTex[0]->tile_ult; + } + + if (rdp.tiles[rdp.cur_tile].shift_s) + { + if (rdp.tiles[rdp.cur_tile].shift_s > 10) + v->u0 *= (float)(1 << (16 - rdp.tiles[rdp.cur_tile].shift_s)); + else + v->u0 /= (float)(1 << rdp.tiles[rdp.cur_tile].shift_s); + } + if (rdp.tiles[rdp.cur_tile].shift_t) + { + if (rdp.tiles[rdp.cur_tile].shift_t > 10) + v->v0 *= (float)(1 << (16 - rdp.tiles[rdp.cur_tile].shift_t)); + else + v->v0 /= (float)(1 << rdp.tiles[rdp.cur_tile].shift_t); + } + + if (rdp.aTBuffTex[0]) + { + if (rdp.aTBuffTex[0]->tile_uls != (int)rdp.tiles[rdp.cur_tile].f_ul_s) + v->u0 -= rdp.tiles[rdp.cur_tile].f_ul_s; + if (rdp.aTBuffTex[0]->tile_ult != (int)rdp.tiles[rdp.cur_tile].f_ul_t || (settings.hacks&hack_Megaman)) + v->v0 -= rdp.tiles[rdp.cur_tile].f_ul_t; //required for megaman (boss special attack) + v->u0 *= rdp.aTBuffTex[0]->u_scale; + v->v0 *= rdp.aTBuffTex[0]->v_scale; +#ifdef EXTREME_LOGGING + FRDP("tbuff_tex t0: (%f, %f)->(%f, %f)\n", v->ou, v->ov, v->u0, v->v0); +#endif + } + else + { + v->u0 -= rdp.tiles[rdp.cur_tile].f_ul_s; + v->v0 -= rdp.tiles[rdp.cur_tile].f_ul_t; + v->u0 = rdp.cur_cache[0]->c_off + rdp.cur_cache[0]->c_scl_x * v->u0; + v->v0 = rdp.cur_cache[0]->c_off + rdp.cur_cache[0]->c_scl_y * v->v0; + } + v->u0_w = v->u0 / v->w; + v->v0_w = v->v0 / v->w; + } + + if (rdp.tex >= 2 && rdp.cur_cache[1]) + { + if (rdp.aTBuffTex[1]) + { + v->u1 += rdp.aTBuffTex[1]->u_shift + rdp.aTBuffTex[1]->tile_uls; + v->v1 += rdp.aTBuffTex[1]->v_shift + rdp.aTBuffTex[1]->tile_ult; + } + if (rdp.tiles[rdp.cur_tile+1].shift_s) + { + if (rdp.tiles[rdp.cur_tile+1].shift_s > 10) + v->u1 *= (float)(1 << (16 - rdp.tiles[rdp.cur_tile+1].shift_s)); + else + v->u1 /= (float)(1 << rdp.tiles[rdp.cur_tile+1].shift_s); + } + if (rdp.tiles[rdp.cur_tile+1].shift_t) + { + if (rdp.tiles[rdp.cur_tile+1].shift_t > 10) + v->v1 *= (float)(1 << (16 - rdp.tiles[rdp.cur_tile+1].shift_t)); + else + v->v1 /= (float)(1 << rdp.tiles[rdp.cur_tile+1].shift_t); + } + + if (rdp.aTBuffTex[1]) + { + if (rdp.aTBuffTex[1]->tile_uls != (int)rdp.tiles[rdp.cur_tile].f_ul_s) + v->u1 -= rdp.tiles[rdp.cur_tile].f_ul_s; + v->u1 *= rdp.aTBuffTex[1]->u_scale; + v->v1 *= rdp.aTBuffTex[1]->v_scale; +#ifdef EXTREME_LOGGING + FRDP("tbuff_tex t1: (%f, %f)->(%f, %f)\n", v->ou, v->ov, v->u1, v->v1); +#endif + } + else + { + v->u1 -= rdp.tiles[rdp.cur_tile+1].f_ul_s; + v->v1 -= rdp.tiles[rdp.cur_tile+1].f_ul_t; + v->u1 = rdp.cur_cache[1]->c_off + rdp.cur_cache[1]->c_scl_x * v->u1; + v->v1 = rdp.cur_cache[1]->c_off + rdp.cur_cache[1]->c_scl_y * v->v1; + } + + v->u1_w = v->u1 / v->w; + v->v1_w = v->v1 / v->w; + } + // FRDP(" * CALCULATING VERTEX U/V: %d u0: %f, v0: %f, u1: %f, v1: %f\n", v->number, v->u0, v->v0, v->u1, v->v1); + } +#ifdef EXTREME_LOGGING + FRDP("draw_tri. v[%d] ou=%f, ov = %f\n", i, v->ou, v->ov); +#endif + if (v->shade_mod != cmb.shade_mod_hash) + apply_shade_mods (v); + } //for + + rdp.clip = 0; + + if ((vtx[0]->scr_off & 16) || + (vtx[1]->scr_off & 16) || + (vtx[2]->scr_off & 16)) + rdp.clip |= CLIP_WMIN; + + vtx[0]->not_zclipped = vtx[1]->not_zclipped = vtx[2]->not_zclipped = 1; + + if (rdp.cur_cache[0] && (rdp.tex & 1) && (rdp.cur_cache[0]->splits > 1) && !rdp.aTBuffTex[0] && !rdp.clip) + { + int index,i,j, min_256,max_256, cur_256,left_256,right_256; + float percent; + + min_256 = min((int)vtx[0]->u0,(int)vtx[1]->u0); // bah, don't put two mins on one line + min_256 = min(min_256,(int)vtx[2]->u0) >> 8; // or it will be calculated twice + + max_256 = max((int)vtx[0]->u0,(int)vtx[1]->u0); // not like it makes much difference + max_256 = max(max_256,(int)vtx[2]->u0) >> 8; // anyway :P + + for (cur_256=min_256; cur_256<=max_256; cur_256++) + { + left_256 = cur_256 << 8; + right_256 = (cur_256+1) << 8; + + // Set vertex buffers + rdp.vtxbuf = rdp.vtx1; // copy from v to rdp.vtx1 + rdp.vtxbuf2 = rdp.vtx2; + rdp.vtx_buffer = 0; + rdp.n_global = 3; + index = 0; + + // ** Left plane ** + for (i=0; i<3; i++) + { + j = i+1; + if (j == 3) j = 0; + + VERTEX *v1 = vtx[i]; + VERTEX *v2 = vtx[j]; + + if (v1->u0 >= left_256) + { + if (v2->u0 >= left_256) // Both are in, save the last one + { + rdp.vtxbuf[index] = *v2; + rdp.vtxbuf[index].u0 -= left_256; + rdp.vtxbuf[index++].v0 += cur_256 * rdp.cur_cache[0]->splitheight; + } + else // First is in, second is out, save intersection + { + percent = (left_256 - v1->u0) / (v2->u0 - v1->u0); + rdp.vtxbuf[index].x = v1->x + (v2->x - v1->x) * percent; + rdp.vtxbuf[index].y = v1->y + (v2->y - v1->y) * percent; + rdp.vtxbuf[index].z = v1->z + (v2->z - v1->z) * percent; + rdp.vtxbuf[index].w = v1->w + (v2->w - v1->w) * percent; + rdp.vtxbuf[index].f = v1->f + (v2->f - v1->f) * percent; + rdp.vtxbuf[index].u0 = 0.5f; + rdp.vtxbuf[index].v0 = v1->v0 + (v2->v0 - v1->v0) * percent + + cur_256 * rdp.cur_cache[0]->splitheight; + rdp.vtxbuf[index].u1 = v1->u1 + (v2->u1 - v1->u1) * percent; + rdp.vtxbuf[index].v1 = v1->v1 + (v2->v1 - v1->v1) * percent; + rdp.vtxbuf[index].b = (wxUint8)(v1->b + (v2->b - v1->b) * percent); + rdp.vtxbuf[index].g = (wxUint8)(v1->g + (v2->g - v1->g) * percent); + rdp.vtxbuf[index].r = (wxUint8)(v1->r + (v2->r - v1->r) * percent); + rdp.vtxbuf[index++].a = (wxUint8)(v1->a + (v2->a - v1->a) * percent); + } + } + else + { + //if (v2->u0 < left_256) // Both are out, save nothing + if (v2->u0 >= left_256) // First is out, second is in, save intersection & in point + { + percent = (left_256 - v2->u0) / (v1->u0 - v2->u0); + rdp.vtxbuf[index].x = v2->x + (v1->x - v2->x) * percent; + rdp.vtxbuf[index].y = v2->y + (v1->y - v2->y) * percent; + rdp.vtxbuf[index].z = v2->z + (v1->z - v2->z) * percent; + rdp.vtxbuf[index].w = v2->w + (v1->w - v2->w) * percent; + rdp.vtxbuf[index].f = v2->f + (v1->f - v2->f) * percent; + rdp.vtxbuf[index].u0 = 0.5f; + rdp.vtxbuf[index].v0 = v2->v0 + (v1->v0 - v2->v0) * percent + + cur_256 * rdp.cur_cache[0]->splitheight; + rdp.vtxbuf[index].u1 = v2->u1 + (v1->u1 - v2->u1) * percent; + rdp.vtxbuf[index].v1 = v2->v1 + (v1->v1 - v2->v1) * percent; + rdp.vtxbuf[index].b = (wxUint8)(v2->b + (v1->b - v2->b) * percent); + rdp.vtxbuf[index].g = (wxUint8)(v2->g + (v1->g - v2->g) * percent); + rdp.vtxbuf[index].r = (wxUint8)(v2->r + (v1->r - v2->r) * percent); + rdp.vtxbuf[index++].a = (wxUint8)(v2->a + (v1->a - v2->a) * percent); + + // Save the in point + rdp.vtxbuf[index] = *v2; + rdp.vtxbuf[index].u0 -= left_256; + rdp.vtxbuf[index++].v0 += cur_256 * rdp.cur_cache[0]->splitheight; + } + } + } + rdp.n_global = index; + + rdp.vtxbuf = rdp.vtx2; // now vtx1 holds the value, & vtx2 is the destination + rdp.vtxbuf2 = rdp.vtx1; + rdp.vtx_buffer ^= 1; + index = 0; + + for (i=0; iu0 <= right_256) + { + if (v2->u0 <= right_256) // Both are in, save the last one + { + rdp.vtxbuf[index] = *v2; + rdp.vtxbuf[index++].not_zclipped = 0; + } + else // First is in, second is out, save intersection + { + percent = (right_256 - v1->u0) / (v2->u0 - v1->u0); + rdp.vtxbuf[index].x = v1->x + (v2->x - v1->x) * percent; + rdp.vtxbuf[index].y = v1->y + (v2->y - v1->y) * percent; + rdp.vtxbuf[index].z = v1->z + (v2->z - v1->z) * percent; + rdp.vtxbuf[index].w = v1->w + (v2->w - v1->w) * percent; + rdp.vtxbuf[index].f = v1->f + (v2->f - v1->f) * percent; + rdp.vtxbuf[index].u0 = 255.5f; + rdp.vtxbuf[index].v0 = v1->v0 + (v2->v0 - v1->v0) * percent; + rdp.vtxbuf[index].u1 = v1->u1 + (v2->u1 - v1->u1) * percent; + rdp.vtxbuf[index].v1 = v1->v1 + (v2->v1 - v1->v1) * percent; + rdp.vtxbuf[index].b = (wxUint8)(v1->b + (v2->b - v1->b) * percent); + rdp.vtxbuf[index].g = (wxUint8)(v1->g + (v2->g - v1->g) * percent); + rdp.vtxbuf[index].r = (wxUint8)(v1->r + (v2->r - v1->r) * percent); + rdp.vtxbuf[index].a = (wxUint8)(v1->a + (v2->a - v1->a) * percent); + rdp.vtxbuf[index++].not_zclipped = 0; + } + } + else + { + //if (v2->u0 > 256.0f) // Both are out, save nothing + if (v2->u0 <= right_256) // First is out, second is in, save intersection & in point + { + percent = (right_256 - v2->u0) / (v1->u0 - v2->u0); + rdp.vtxbuf[index].x = v2->x + (v1->x - v2->x) * percent; + rdp.vtxbuf[index].y = v2->y + (v1->y - v2->y) * percent; + rdp.vtxbuf[index].z = v2->z + (v1->z - v2->z) * percent; + rdp.vtxbuf[index].w = v2->w + (v1->w - v2->w) * percent; + rdp.vtxbuf[index].f = v2->f + (v1->f - v2->f) * percent; + rdp.vtxbuf[index].u0 = 255.5f; + rdp.vtxbuf[index].v0 = v2->v0 + (v1->v0 - v2->v0) * percent; + rdp.vtxbuf[index].u1 = v2->u1 + (v1->u1 - v2->u1) * percent; + rdp.vtxbuf[index].v1 = v2->v1 + (v1->v1 - v2->v1) * percent; + rdp.vtxbuf[index].b = (wxUint8)(v2->b + (v1->b - v2->b) * percent); + rdp.vtxbuf[index].g = (wxUint8)(v2->g + (v1->g - v2->g) * percent); + rdp.vtxbuf[index].r = (wxUint8)(v2->r + (v1->r - v2->r) * percent); + rdp.vtxbuf[index].a = (wxUint8)(v2->a + (v1->a - v2->a) * percent); + rdp.vtxbuf[index++].not_zclipped = 0; + + // Save the in point + rdp.vtxbuf[index] = *v2; + rdp.vtxbuf[index++].not_zclipped = 0; + } + } + } + rdp.n_global = index; + + do_triangle_stuff (linew, TRUE); + } + } + else + { + // Set vertex buffers + rdp.vtxbuf = rdp.vtx1; // copy from v to rdp.vtx1 + rdp.vtxbuf2 = rdp.vtx2; + rdp.vtx_buffer = 0; + rdp.n_global = 3; + + rdp.vtxbuf[0] = *vtx[0]; + rdp.vtxbuf[0].number = 1; + rdp.vtxbuf[1] = *vtx[1]; + rdp.vtxbuf[1].number = 2; + rdp.vtxbuf[2] = *vtx[2]; + rdp.vtxbuf[2].number = 4; + + do_triangle_stuff (linew, FALSE); + } +} + +#define interp2p(a, b, r) (a + (b - a) * r) + +//* +static void InterpolateColors(VERTEX & va, VERTEX & vb, VERTEX & res, float percent) +{ + res.b = (wxUint8)interp2p(va.b, vb.b, percent); + res.g = (wxUint8)interp2p(va.g, vb.g, percent);; + res.r = (wxUint8)interp2p(va.r, vb.r, percent);; + res.a = (wxUint8)interp2p(va.a, vb.a, percent);; + res.f = interp2p(va.f, vb.f, percent);; +} +//*/ +// +// clip_w - clips aint the z-axis +// +static void clip_w (int interpolate_colors) +{ + int i,j,index,n=rdp.n_global; + float percent; + // Swap vertex buffers + VERTEX *tmp = rdp.vtxbuf2; + rdp.vtxbuf2 = rdp.vtxbuf; + rdp.vtxbuf = tmp; + rdp.vtx_buffer ^= 1; + index = 0; + + // Check the vertices for clipping + for (i=0; i= 0.01f) + { + if (Vj.w >= 0.01f) // Both are in, save the last one + { + rdp.vtxbuf[index] = Vj; + rdp.vtxbuf[index++].not_zclipped = 1; + } + else // First is in, second is out, save intersection + { + percent = (-Vi.w) / (Vj.w - Vi.w); + rdp.vtxbuf[index].not_zclipped = 0; + rdp.vtxbuf[index].x = Vi.x + (Vj.x - Vi.x) * percent; + rdp.vtxbuf[index].y = Vi.y + (Vj.y - Vi.y) * percent; + rdp.vtxbuf[index].z = Vi.z + (Vj.z - Vi.z) * percent; + rdp.vtxbuf[index].w = 0.01f; + rdp.vtxbuf[index].u0 = Vi.u0 + (Vj.u0 - Vi.u0) * percent; + rdp.vtxbuf[index].v0 = Vi.v0 + (Vj.v0 - Vi.v0) * percent; + rdp.vtxbuf[index].u1 = Vi.u1 + (Vj.u1 - Vi.u1) * percent; + rdp.vtxbuf[index].v1 = Vi.v1 + (Vj.v1 - Vi.v1) * percent; + if (interpolate_colors) + InterpolateColors(Vi, Vj, rdp.vtxbuf[index++], percent); + else + rdp.vtxbuf[index++].number = Vi.number | Vj.number; + } + } + else + { + //if (Vj.w < 0.01f) // Both are out, save nothing + if (Vj.w >= 0.01f) // First is out, second is in, save intersection & in point + { + percent = (-Vj.w) / (Vi.w - Vj.w); + rdp.vtxbuf[index].not_zclipped = 0; + rdp.vtxbuf[index].x = Vj.x + (Vi.x - Vj.x) * percent; + rdp.vtxbuf[index].y = Vj.y + (Vi.y - Vj.y) * percent; + rdp.vtxbuf[index].z = Vj.z + (Vi.z - Vj.z) * percent; + rdp.vtxbuf[index].w = 0.01f; + rdp.vtxbuf[index].u0 = Vj.u0 + (Vi.u0 - Vj.u0) * percent; + rdp.vtxbuf[index].v0 = Vj.v0 + (Vi.v0 - Vj.v0) * percent; + rdp.vtxbuf[index].u1 = Vj.u1 + (Vi.u1 - Vj.u1) * percent; + rdp.vtxbuf[index].v1 = Vj.v1 + (Vi.v1 - Vj.v1) * percent; + if (interpolate_colors) + InterpolateColors(Vj, Vi, rdp.vtxbuf[index++], percent); + else + rdp.vtxbuf[index++].number = Vi.number | Vj.number; + + // Save the in point + rdp.vtxbuf[index] = Vj; + rdp.vtxbuf[index++].not_zclipped = 1; + } + } + } + rdp.n_global = index; +} + +static void render_tri (wxUint16 linew, int old_interpolate); + +void do_triangle_stuff (wxUint16 linew, int old_interpolate) // what else?? do the triangle stuff :P (to keep from writing code twice) +{ + int i; + + if (rdp.clip & CLIP_WMIN) + clip_w (old_interpolate); + + float maxZ = (rdp.zsrc != 1) ? rdp.view_trans[2] + rdp.view_scale[2] : rdp.prim_depth; + + wxUint8 no_clip = 2; + for (i=0; i= 1) + { + rdp.vtxbuf[i].u0 *= rdp.vtxbuf[i].q; + rdp.vtxbuf[i].v0 *= rdp.vtxbuf[i].q; + } + if (rdp.tex >= 2) + { + rdp.vtxbuf[i].u1 *= rdp.vtxbuf[i].q; + rdp.vtxbuf[i].v1 *= rdp.vtxbuf[i].q; + } + } + + if (rdp.zsrc == 1) + rdp.vtxbuf[i].z = rdp.prim_depth; + + // Don't remove clipping, or it will freeze + if (rdp.vtxbuf[i].x > rdp.clip_max_x) rdp.clip |= CLIP_XMAX; + if (rdp.vtxbuf[i].x < rdp.clip_min_x) rdp.clip |= CLIP_XMIN; + if (rdp.vtxbuf[i].y > rdp.clip_max_y) rdp.clip |= CLIP_YMAX; + if (rdp.vtxbuf[i].y < rdp.clip_min_y) rdp.clip |= CLIP_YMIN; + if (rdp.vtxbuf[i].z > maxZ) rdp.clip |= CLIP_ZMAX; + if (rdp.vtxbuf[i].z < 0.0f) rdp.clip |= CLIP_ZMIN; + no_clip &= rdp.vtxbuf[i].screen_translated; + } + if (no_clip) + rdp.clip = 0; + else + { + if (!settings.clip_zmin) + rdp.clip &= ~CLIP_ZMIN; + if (!settings.clip_zmax) + rdp.clip &= ~CLIP_ZMAX; + } + render_tri (linew, old_interpolate); +} + +void do_triangle_stuff_2 (wxUint16 linew) +{ + rdp.clip = 0; + + for (int i=0; i rdp.clip_max_x) rdp.clip |= CLIP_XMAX; + if (rdp.vtxbuf[i].x < rdp.clip_min_x) rdp.clip |= CLIP_XMIN; + if (rdp.vtxbuf[i].y > rdp.clip_max_y) rdp.clip |= CLIP_YMAX; + if (rdp.vtxbuf[i].y < rdp.clip_min_y) rdp.clip |= CLIP_YMIN; + } + + render_tri (linew, TRUE); +} + +__inline wxUint8 real_to_char(double x) +{ + return (wxUint8)(((int)floor(x+0.5))&0xFF); +} + +//* +static void InterpolateColors2(VERTEX & va, VERTEX & vb, VERTEX & res, float percent) +{ + float w = 1.0f/(va.oow + (vb.oow-va.oow) * percent); + // res.oow = va.oow + (vb.oow-va.oow) * percent; + // res.q = res.oow; + float ba = va.b * va.oow; + float bb = vb.b * vb.oow; + res.b = real_to_char(interp2p(ba, bb, percent) * w); + float ga = va.g * va.oow; + float gb = vb.g * vb.oow; + res.g = real_to_char(interp2p(ga, gb, percent) * w); + float ra = va.r * va.oow; + float rb = vb.r * vb.oow; + res.r = real_to_char(interp2p(ra, rb, percent) * w); + float aa = va.a * va.oow; + float ab = vb.a * vb.oow; + res.a = real_to_char(interp2p(aa, ab, percent) * w); + float fa = va.f * va.oow; + float fb = vb.f * vb.oow; + res.f = interp2p(fa, fb, percent) * w; + /* + float u0a = va.u0_w * va.oow; + float u0b = vb.u0_w * vb.oow; + res.u0 = (u0a + (u0b - u0a) * percent) * w; + float v0a = va.v0_w * va.oow; + float v0b = vb.v0_w * vb.oow; + res.v0 = (v0a + (v0b - v0a) * percent) * w; + float u1a = va.u1_w * va.oow; + float u1b = vb.u1_w * vb.oow; + res.u1 = (u1a + (u1b - u1a) * percent) * w; + float v1a = va.v1_w * va.oow; + float v1b = vb.v1_w * vb.oow; + res.v1 = (v1a + (v1b - v1a) * percent) * w; + */ +} +//*/ + +typedef struct { + double d; + double x; + double y; +} LineEuqationType; + +static double EvaLine(LineEuqationType &li, double x, double y) +{ + return li.x*x+li.y*y+li.d; +} + +static void Create1LineEq(LineEuqationType &l, VERTEX &v1, VERTEX &v2, VERTEX &v3) +{ + // Line between (x1,y1) to (x2,y2) + l.x = v2.sy-v1.sy; + l.y = v1.sx-v2.sx; + l.d = -(l.x*v2.sx+(l.y)*v2.sy); + if (EvaLine(l,v3.sx,v3.sy)*v3.oow < 0) + { + l.x = -l.x; + l.y = -l.y; + l.d = -l.d; + } +} + + +__inline double interp3p(float a, float b, float c, double r1, double r2) +{ + return (a)+(((b)+((c)-(b))*(r2))-(a))*(r1); +} +/* +#define interp3p(a, b, c, r1, r2) \ + (a+(((b)+((c)-(b))*(r2))-(a))*(r1)) +*/ + +static void InterpolateColors3(VERTEX &v1, VERTEX &v2, VERTEX &v3, VERTEX &out) +{ + + LineEuqationType line; + Create1LineEq(line, v2, v3, v1); + + double aDot = (out.x*line.x + out.y*line.y); + double bDot = (v1.sx*line.x + v1.sy*line.y); + + double scale1 = ( - line.d - aDot) / ( bDot - aDot ); + + double tx = out.x + scale1 * (v1.sx - out.x); + double ty = out.y + scale1 * (v1.sy - out.y); + + double s1 = 101.0, s2 = 101.0; + double den = tx - v1.sx; + if (fabs(den) > 1.0) + s1 = (out.x-v1.sx)/den; + if (s1 > 100.0f) + s1 = (out.y-v1.sy)/(ty-v1.sy); + + den = v3.sx - v2.sx; + if (fabs(den) > 1.0) + s2 = (tx-v2.sx)/den; + if (s2 > 100.0f) + s2 =(ty-v2.sy)/(v3.sy-v2.sy); + + double w = 1.0/interp3p(v1.oow,v2.oow,v3.oow,s1,s2); + + out.r = real_to_char(interp3p(v1.r*v1.oow,v2.r*v2.oow,v3.r*v3.oow,s1,s2)*w); + out.g = real_to_char(interp3p(v1.g*v1.oow,v2.g*v2.oow,v3.g*v3.oow,s1,s2)*w); + out.b = real_to_char(interp3p(v1.b*v1.oow,v2.b*v2.oow,v3.b*v3.oow,s1,s2)*w); + out.a = real_to_char(interp3p(v1.a*v1.oow,v2.a*v2.oow,v3.a*v3.oow,s1,s2)*w); + out.f = (float)(interp3p(v1.f*v1.oow,v2.f*v2.oow,v3.f*v3.oow,s1,s2)*w); + /* + out.u0 = interp3p(v1.u0_w*v1.oow,v2.u0_w*v2.oow,v3.u0_w*v3.oow,s1,s2)/oow; + out.v0 = interp3p(v1.v0_w*v1.oow,v2.v0_w*v2.oow,v3.v0_w*v3.oow,s1,s2)/oow; + out.u1 = interp3p(v1.u1_w*v1.oow,v2.u1_w*v2.oow,v3.u1_w*v3.oow,s1,s2)/oow; + out.v1 = interp3p(v1.v1_w*v1.oow,v2.v1_w*v2.oow,v3.v1_w*v3.oow,s1,s2)/oow; + */ +} + +static void CalculateLOD(VERTEX *v, int n) +{ + //rdp.update |= UPDATE_TEXTURE; + /* + if (rdp.lod_calculated) + { + float detailmax; + if (dc0_detailmax < 0.5) + detailmax = rdp.lod_fraction; + else + detailmax = 1.0f - rdp.lod_fraction; + grTexDetailControl (GR_TMU0, dc0_lodbias, dc0_detailscale, detailmax); + if (num_tmu == 2) + grTexDetailControl (GR_TMU1, dc1_lodbias, dc1_detailscale, detailmax); + return; + } + */ + float deltaS, deltaT; + float deltaX, deltaY; + double deltaTexels, deltaPixels, lodFactor = 0; + double intptr; + float s_scale = rdp.tiles[rdp.cur_tile].width / 255.0f; + float t_scale = rdp.tiles[rdp.cur_tile].height / 255.0f; + if (settings.lodmode == 1) + { + deltaS = (v[1].u0/v[1].q - v[0].u0/v[0].q) * s_scale; + deltaT = (v[1].v0/v[1].q - v[0].v0/v[0].q) * t_scale; + deltaTexels = sqrt( deltaS * deltaS + deltaT * deltaT ); + + deltaX = (v[1].x - v[0].x)/rdp.scale_x; + deltaY = (v[1].y - v[0].y)/rdp.scale_y; + deltaPixels = sqrt( deltaX * deltaX + deltaY * deltaY ); + + lodFactor = deltaTexels / deltaPixels; + } + else + { + int i, j; + for (i = 0; i < n; i++) + { + j = (i < n-1) ? i + 1 : 0; + + deltaS = (v[j].u0/v[j].q - v[i].u0/v[i].q) * s_scale; + deltaT = (v[j].v0/v[j].q - v[i].v0/v[i].q) * t_scale; + // deltaS = v[j].ou - v[i].ou; + // deltaT = v[j].ov - v[i].ov; + deltaTexels = sqrt( deltaS * deltaS + deltaT * deltaT ); + + deltaX = (v[j].x - v[i].x)/rdp.scale_x; + deltaY = (v[j].y - v[i].y)/rdp.scale_y; + deltaPixels = sqrt( deltaX * deltaX + deltaY * deltaY ); + + lodFactor += deltaTexels / deltaPixels; + } + // Divide by n (n edges) to find average + lodFactor = lodFactor / n; + } + int ilod = (int)lodFactor; + int lod_tile = min((int)(log10f((float)ilod)/log10f(2.0f)), rdp.cur_tile + rdp.mipmap_level); + float lod_fraction = 1.0f; + if (lod_tile < rdp.cur_tile + rdp.mipmap_level) + { + lod_fraction = max((float)modf(lodFactor / pow(2.,lod_tile),&intptr), rdp.prim_lodmin / 255.0f); + } + float detailmax; + if (cmb.dc0_detailmax < 0.5f) + detailmax = lod_fraction; + else + detailmax = 1.0f - lod_fraction; + grTexDetailControl (GR_TMU0, cmb.dc0_lodbias, cmb.dc0_detailscale, detailmax); + if (voodoo.num_tmu == 2) + grTexDetailControl (GR_TMU1, cmb.dc1_lodbias, cmb.dc1_detailscale, detailmax); + FRDP("CalculateLOD factor: %f, tile: %d, lod_fraction: %f\n", (float)lodFactor, lod_tile, lod_fraction); +} + +float ScaleZ(float z) +{ + if (settings.n64_z_scale) + { + int iz = (int)(z*8.0f+0.5f); + if (iz < 0) iz = 0; + else if (iz >= 0x40000) iz = 0x40000 - 1; + return (float)zLUT[iz]; + } + if (z < 0.0f) return 0.0f; + z *= 1.9f; + if (z > 65534.0f) return 65534.0f; + return z; +} + +static void DepthBuffer(VERTEX * vtx, int n) +{ + if (fb_depth_render_enabled && !(settings.hacks&hack_RE2) && dzdx && (rdp.flags & ZBUF_UPDATE)) + { + vertexi v[12]; + if (u_cull_mode == 1) //cull front + { + for(int i=0; i rdp.clip_max_x) // Both are out, save nothing + if (Vj.x <= rdp.clip_max_x) // First is out, second is in, save intersection & in point + { + percent = (rdp.clip_max_x - Vj.x) / (Vi.x - Vj.x); + rdp.vtxbuf[index].x = rdp.clip_max_x; + rdp.vtxbuf[index].y = Vj.y + (Vi.y - Vj.y) * percent; + rdp.vtxbuf[index].z = Vj.z + (Vi.z - Vj.z) * percent; + rdp.vtxbuf[index].q = Vj.q + (Vi.q - Vj.q) * percent; + rdp.vtxbuf[index].u0 = Vj.u0 + (Vi.u0 - Vj.u0) * percent; + rdp.vtxbuf[index].v0 = Vj.v0 + (Vi.v0 - Vj.v0) * percent; + rdp.vtxbuf[index].u1 = Vj.u1 + (Vi.u1 - Vj.u1) * percent; + rdp.vtxbuf[index].v1 = Vj.v1 + (Vi.v1 - Vj.v1) * percent; + if (interpolate_colors) + InterpolateColors(Vj, Vi, rdp.vtxbuf[index++], percent); + else + rdp.vtxbuf[index++].number = Vi.number | Vj.number | 8; + + // Save the in point + rdp.vtxbuf[index++] = Vj; + } + } + } + n = index; + } + if (rdp.clip & CLIP_XMIN) // left of the screen + { + // Swap vertex buffers + VERTEX *tmp = rdp.vtxbuf2; + rdp.vtxbuf2 = rdp.vtxbuf; + rdp.vtxbuf = tmp; + rdp.vtx_buffer ^= 1; + index = 0; + + // Check the vertices for clipping + for (i=0; i= rdp.clip_min_x) + { + if (Vj.x >= rdp.clip_min_x) // Both are in, save the last one + { + rdp.vtxbuf[index++] = Vj; + } + else // First is in, second is out, save intersection + { + percent = (rdp.clip_min_x - Vi.x) / (Vj.x - Vi.x); + rdp.vtxbuf[index].x = rdp.clip_min_x; + rdp.vtxbuf[index].y = Vi.y + (Vj.y - Vi.y) * percent; + rdp.vtxbuf[index].z = Vi.z + (Vj.z - Vi.z) * percent; + rdp.vtxbuf[index].q = Vi.q + (Vj.q - Vi.q) * percent; + rdp.vtxbuf[index].u0 = Vi.u0 + (Vj.u0 - Vi.u0) * percent; + rdp.vtxbuf[index].v0 = Vi.v0 + (Vj.v0 - Vi.v0) * percent; + rdp.vtxbuf[index].u1 = Vi.u1 + (Vj.u1 - Vi.u1) * percent; + rdp.vtxbuf[index].v1 = Vi.v1 + (Vj.v1 - Vi.v1) * percent; + if (interpolate_colors) + InterpolateColors(Vi, Vj, rdp.vtxbuf[index++], percent); + else + rdp.vtxbuf[index++].number = Vi.number | Vj.number | 8; + } + } + else + { + //if (Vj.x < rdp.clip_min_x) // Both are out, save nothing + if (Vj.x >= rdp.clip_min_x) // First is out, second is in, save intersection & in point + { + percent = (rdp.clip_min_x - Vj.x) / (Vi.x - Vj.x); + rdp.vtxbuf[index].x = rdp.clip_min_x; + rdp.vtxbuf[index].y = Vj.y + (Vi.y - Vj.y) * percent; + rdp.vtxbuf[index].z = Vj.z + (Vi.z - Vj.z) * percent; + rdp.vtxbuf[index].q = Vj.q + (Vi.q - Vj.q) * percent; + rdp.vtxbuf[index].u0 = Vj.u0 + (Vi.u0 - Vj.u0) * percent; + rdp.vtxbuf[index].v0 = Vj.v0 + (Vi.v0 - Vj.v0) * percent; + rdp.vtxbuf[index].u1 = Vj.u1 + (Vi.u1 - Vj.u1) * percent; + rdp.vtxbuf[index].v1 = Vj.v1 + (Vi.v1 - Vj.v1) * percent; + if (interpolate_colors) + InterpolateColors(Vj, Vi, rdp.vtxbuf[index++], percent); + else + rdp.vtxbuf[index++].number = Vi.number | Vj.number | 8; + + // Save the in point + rdp.vtxbuf[index++] = Vj; + } + } + } + n = index; + } + if (rdp.clip & CLIP_YMAX) // top of the screen + { + // Swap vertex buffers + VERTEX *tmp = rdp.vtxbuf2; + rdp.vtxbuf2 = rdp.vtxbuf; + rdp.vtxbuf = tmp; + rdp.vtx_buffer ^= 1; + index = 0; + + // Check the vertices for clipping + for (i=0; i rdp.clip_max_y) // Both are out, save nothing + if (Vj.y <= rdp.clip_max_y) // First is out, second is in, save intersection & in point + { + percent = (rdp.clip_max_y - Vj.y) / (Vi.y - Vj.y); + rdp.vtxbuf[index].x = Vj.x + (Vi.x - Vj.x) * percent; + rdp.vtxbuf[index].y = rdp.clip_max_y; + rdp.vtxbuf[index].z = Vj.z + (Vi.z - Vj.z) * percent; + rdp.vtxbuf[index].q = Vj.q + (Vi.q - Vj.q) * percent; + rdp.vtxbuf[index].u0 = Vj.u0 + (Vi.u0 - Vj.u0) * percent; + rdp.vtxbuf[index].v0 = Vj.v0 + (Vi.v0 - Vj.v0) * percent; + rdp.vtxbuf[index].u1 = Vj.u1 + (Vi.u1 - Vj.u1) * percent; + rdp.vtxbuf[index].v1 = Vj.v1 + (Vi.v1 - Vj.v1) * percent; + if (interpolate_colors) + InterpolateColors(Vj, Vi, rdp.vtxbuf[index++], percent); + else + rdp.vtxbuf[index++].number = Vi.number | Vj.number | 16; + + // Save the in point + rdp.vtxbuf[index++] = Vj; + } + } + } + n = index; + } + if (rdp.clip & CLIP_YMIN) // bottom of the screen + { + // Swap vertex buffers + VERTEX *tmp = rdp.vtxbuf2; + rdp.vtxbuf2 = rdp.vtxbuf; + rdp.vtxbuf = tmp; + rdp.vtx_buffer ^= 1; + index = 0; + + // Check the vertices for clipping + for (i=0; i= rdp.clip_min_y) + { + if (Vj.y >= rdp.clip_min_y) // Both are in, save the last one + { + rdp.vtxbuf[index++] = Vj; + } + else // First is in, second is out, save intersection + { + percent = (rdp.clip_min_y - Vi.y) / (Vj.y - Vi.y); + rdp.vtxbuf[index].x = Vi.x + (Vj.x - Vi.x) * percent; + rdp.vtxbuf[index].y = rdp.clip_min_y; + rdp.vtxbuf[index].z = Vi.z + (Vj.z - Vi.z) * percent; + rdp.vtxbuf[index].q = Vi.q + (Vj.q - Vi.q) * percent; + rdp.vtxbuf[index].u0 = Vi.u0 + (Vj.u0 - Vi.u0) * percent; + rdp.vtxbuf[index].v0 = Vi.v0 + (Vj.v0 - Vi.v0) * percent; + rdp.vtxbuf[index].u1 = Vi.u1 + (Vj.u1 - Vi.u1) * percent; + rdp.vtxbuf[index].v1 = Vi.v1 + (Vj.v1 - Vi.v1) * percent; + if (interpolate_colors) + InterpolateColors(Vi, Vj, rdp.vtxbuf[index++], percent); + else + rdp.vtxbuf[index++].number = Vi.number | Vj.number | 16; + } + } + else + { + //if (Vj.y < rdp.clip_min_y) // Both are out, save nothing + if (Vj.y >= rdp.clip_min_y) // First is out, second is in, save intersection & in point + { + percent = (rdp.clip_min_y - Vj.y) / (Vi.y - Vj.y); + rdp.vtxbuf[index].x = Vj.x + (Vi.x - Vj.x) * percent; + rdp.vtxbuf[index].y = rdp.clip_min_y; + rdp.vtxbuf[index].z = Vj.z + (Vi.z - Vj.z) * percent; + rdp.vtxbuf[index].q = Vj.q + (Vi.q - Vj.q) * percent; + rdp.vtxbuf[index].u0 = Vj.u0 + (Vi.u0 - Vj.u0) * percent; + rdp.vtxbuf[index].v0 = Vj.v0 + (Vi.v0 - Vj.v0) * percent; + rdp.vtxbuf[index].u1 = Vj.u1 + (Vi.u1 - Vj.u1) * percent; + rdp.vtxbuf[index].v1 = Vj.v1 + (Vi.v1 - Vj.v1) * percent; + if (interpolate_colors) + InterpolateColors(Vj, Vi, rdp.vtxbuf[index++], percent); + else + rdp.vtxbuf[index++].number = Vi.number | Vj.number | 16; + + // Save the in point + rdp.vtxbuf[index++] = Vj; + } + } + } + n = index; + } + if (rdp.clip & CLIP_ZMAX) // far plane + { + // Swap vertex buffers + VERTEX *tmp = rdp.vtxbuf2; + rdp.vtxbuf2 = rdp.vtxbuf; + rdp.vtxbuf = tmp; + rdp.vtx_buffer ^= 1; + index = 0; + float maxZ = rdp.view_trans[2] + rdp.view_scale[2]; + + // Check the vertices for clipping + for (i=0; i maxZ) // Both are out, save nothing + if (Vj.z < maxZ) // First is out, second is in, save intersection & in point + { + percent = (maxZ - Vj.z) / (Vi.z - Vj.z); + rdp.vtxbuf[index].x = Vj.x + (Vi.x - Vj.x) * percent; + rdp.vtxbuf[index].y = Vj.y + (Vi.y - Vj.y) * percent; + rdp.vtxbuf[index].z = maxZ - 0.001f;; + rdp.vtxbuf[index].q = Vj.q + (Vi.q - Vj.q) * percent; + rdp.vtxbuf[index].u0 = Vj.u0 + (Vi.u0 - Vj.u0) * percent; + rdp.vtxbuf[index].v0 = Vj.v0 + (Vi.v0 - Vj.v0) * percent; + rdp.vtxbuf[index].u1 = Vj.u1 + (Vi.u1 - Vj.u1) * percent; + rdp.vtxbuf[index].v1 = Vj.v1 + (Vi.v1 - Vj.v1) * percent; + if (interpolate_colors) + InterpolateColors(Vj, Vi, rdp.vtxbuf[index++], percent); + else + rdp.vtxbuf[index++].number = Vi.number | Vj.number; + + // Save the in point + rdp.vtxbuf[index++] = Vj; + } + } + } + n = index; + } +/* + if (rdp.clip & CLIP_ZMIN) // near Z + { + // Swap vertex buffers + VERTEX *tmp = rdp.vtxbuf2; + rdp.vtxbuf2 = rdp.vtxbuf; + rdp.vtxbuf = tmp; + rdp.vtx_buffer ^= 1; + index = 0; + + // Check the vertices for clipping + for (i=0; i= 0.0f) + { + if (Vj.z >= 0.0f) // Both are in, save the last one + { + rdp.vtxbuf[index++] = Vj; + } + else // First is in, second is out, save intersection + { + percent = (-Vi.z) / (Vj.z - Vi.z); + rdp.vtxbuf[index].x = Vi.x + (Vj.x - Vi.x) * percent; + rdp.vtxbuf[index].y = Vi.y + (Vj.y - Vi.y) * percent; + rdp.vtxbuf[index].z = 0.0f; + rdp.vtxbuf[index].q = Vi.q + (Vj.q - Vi.q) * percent; + rdp.vtxbuf[index].u0 = Vi.u0 + (Vj.u0 - Vi.u0) * percent; + rdp.vtxbuf[index].v0 = Vi.v0 + (Vj.v0 - Vi.v0) * percent; + rdp.vtxbuf[index].u1 = Vi.u1 + (Vj.u1 - Vi.u1) * percent; + rdp.vtxbuf[index].v1 = Vi.v1 + (Vj.v1 - Vi.v1) * percent; + if (interpolate_colors) + InterpolateColors(Vi, Vj, rdp.vtxbuf[index++], percent); + else + rdp.vtxbuf[index++].number = Vi.number | Vj.number; + } + } + else + { + //if (Vj.z < 0.0f) // Both are out, save nothing + if (Vj.z >= 0.0f) // First is out, second is in, save intersection & in point + { + percent = (-Vj.z) / (Vi.z - Vj.z); + rdp.vtxbuf[index].x = Vj.x + (Vi.x - Vj.x) * percent; + rdp.vtxbuf[index].y = Vj.y + (Vi.y - Vj.y) * percent; + rdp.vtxbuf[index].z = 0.0f;; + rdp.vtxbuf[index].q = Vj.q + (Vi.q - Vj.q) * percent; + rdp.vtxbuf[index].u0 = Vj.u0 + (Vi.u0 - Vj.u0) * percent; + rdp.vtxbuf[index].v0 = Vj.v0 + (Vi.v0 - Vj.v0) * percent; + rdp.vtxbuf[index].u1 = Vj.u1 + (Vi.u1 - Vj.u1) * percent; + rdp.vtxbuf[index].v1 = Vj.v1 + (Vi.v1 - Vj.v1) * percent; + if (interpolate_colors) + InterpolateColors(Vj, Vi, rdp.vtxbuf[index++], percent); + else + rdp.vtxbuf[index++].number = Vi.number | Vj.number; + + // Save the in point + rdp.vtxbuf[index++] = Vj; + } + } + } + n = index; + } +*/ + rdp.n_global = n; +} + +static void render_tri (wxUint16 linew, int old_interpolate) +{ + if (rdp.clip) + clip_tri(old_interpolate); + int n = rdp.n_global; + if (n < 3) + { + FRDP (" * render_tri: n < 3\n"); + return; + } + int i,j; + //* + if ((rdp.clip & CLIP_ZMIN) && (rdp.othermode_l & 0x00000030)) + { + + int to_render = FALSE; + for (i = 0; i < n; i++) + { + if (rdp.vtxbuf[i].z >= 0.0f) + { + to_render = TRUE; + break; + } + } + if (!to_render) //all z < 0 + { + FRDP (" * render_tri: all z < 0\n"); + return; + } + } + //*/ + if (rdp.clip && !old_interpolate) + { + for (i = 0; i < n; i++) + { + float percent = 101.0f; + VERTEX * v1 = 0, * v2 = 0; + switch (rdp.vtxbuf[i].number&7) + { + case 1: + case 2: + case 4: + continue; + break; + case 3: + v1 = org_vtx[0]; + v2 = org_vtx[1]; + break; + case 5: + v1 = org_vtx[0]; + v2 = org_vtx[2]; + break; + case 6: + v1 = org_vtx[1]; + v2 = org_vtx[2]; + break; + case 7: + InterpolateColors3(*org_vtx[0], *org_vtx[1], *org_vtx[2], rdp.vtxbuf[i]); + continue; + break; + } + switch (rdp.vtxbuf[i].number&24) + { + case 8: + percent = (rdp.vtxbuf[i].x-v1->sx)/(v2->sx-v1->sx); + break; + case 16: + percent = (rdp.vtxbuf[i].y-v1->sy)/(v2->sy-v1->sy); + break; + default: + { + float d = (v2->sx-v1->sx); + if (fabs(d) > 1.0) + percent = (rdp.vtxbuf[i].x-v1->sx)/d; + if (percent > 100.0f) + percent = (rdp.vtxbuf[i].y-v1->sy)/(v2->sy-v1->sy); + } + } + InterpolateColors2(*v1, *v2, rdp.vtxbuf[i], percent); + } + } + /* + if (rdp.clip) + { + LOGG("Colors before clipping:\n"); + unsigned int k; + for(k=0; k<3; k++) + { + FRDP2("V%d: r=%d, g=%d, b=%d, a=%d, f=%d\n", k, org_vtx[k]->r, org_vtx[k]->g, org_vtx[k]->b, org_vtx[k]->a, (short)org_vtx[k]->f); + } + FRDP("Got %d vertex after clipping\n", n); + for(k=0; k 0 && rdp.cur_tile < rdp.mipmap_level) + CalculateLOD(rdp.vtxbuf, n); + + cmb.cmb_ext_use = cmb.tex_cmb_ext_use = 0; + + /* + if (rdp.tbuff_tex) + { + for (int k = 0; k < 3; k++) + { + FRDP("v%d %f->%f, width: %d. height: %d, tex_width: %d, tex_height: %d, lr_u: %f, lr_v: %f\n", k, vv0[k], pv[k]->v1, rdp.tbuff_tex->width, rdp.tbuff_tex->height, rdp.tbuff_tex->tex_width, rdp.tbuff_tex->tex_height, rdp.tbuff_tex->lr_u, rdp.tbuff_tex->lr_v); + } + } + */ + if (fullscreen) + { + if (settings.wireframe) + { + SetWireframeCol (); + for (i=0; ix, pv[k]->y, pv[k]->z, pv[k]->coord[rdp.t0<<1], pv[k]->coord[(rdp.t0<<1)+1]); + // pv[k]->y = settings.res_y - pv[k]->y; + + if (linew > 0) + { + VERTEX *V0 = &rdp.vtxbuf[0]; + VERTEX *V1 = &rdp.vtxbuf[1]; + if (fabs(V0->x - V1->x) < 0.01 && fabs(V0->y - V1->y) < 0.01) + V1 = &rdp.vtxbuf[2]; + V0->z = ScaleZ(V0->z); + V1->z = ScaleZ(V1->z); + VERTEX v[4]; + v[0] = *V0; + v[1] = *V0; + v[2] = *V1; + v[3] = *V1; + float width = linew * 0.25f; + if (fabs(V0->y - V1->y) < 0.0001) + { + v[0].x = v[1].x = V0->x; + v[2].x = v[3].x = V1->x; + + width *= rdp.scale_y; + v[0].y = v[2].y = V0->y - width; + v[1].y = v[3].y = V0->y + width; + } + else if (fabs(V0->x - V1->x) < 0.0001) + { + v[0].y = v[1].y = V0->y; + v[2].y = v[3].y = V1->y; + + width *= rdp.scale_x; + v[0].x = v[2].x = V0->x - width; + v[1].x = v[3].x = V0->x + width; + } + else + { + float dx = V1->x - V0->x; + float dy = V1->y - V0->y; + float len = sqrtf(dx*dx + dy*dy); + float wx = dy * width * rdp.scale_x / len; + float wy = dx * width * rdp.scale_y / len; + v[0].x = V0->x + wx; + v[0].y = V0->y - wy; + v[1].x = V0->x - wx; + v[1].y = V0->y + wy; + v[2].x = V1->x + wx; + v[2].y = V1->y - wy; + v[3].x = V1->x - wx; + v[3].y = V1->y + wy; + } + grDrawTriangle(&v[0], &v[1], &v[2]); + grDrawTriangle(&v[1], &v[2], &v[3]); + } + else + { + DepthBuffer(rdp.vtxbuf, n); + if ((rdp.rm & 0xC10) == 0xC10) + grDepthBiasLevel (-deltaZ); + grDrawVertexArray (GR_TRIANGLE_FAN, n, rdp.vtx_buffer?(&vtx_list2):(&vtx_list1)); + } + } + } + + if (_debugger.capture) add_tri (rdp.vtxbuf, n, TRI_TRIANGLE); +} + +void add_tri (VERTEX *v, int n, int type) +{ + //FRDP ("ENTER (%f, %f, %f), (%f, %f, %f), (%f, %f, %f)\n", v[0].x, v[0].y, v[0].w, + // v[1].x, v[1].y, v[1].w, v[2].x, v[2].y, v[2].w); + + // Debug capture + if (_debugger.capture) + { + rdp.debug_n ++; + + TRI_INFO *info = new TRI_INFO; + info->nv = n; + info->v = new VERTEX [n]; + memcpy (info->v, v, sizeof(VERTEX)*n); + info->cycle_mode = rdp.cycle_mode; + info->cycle1 = rdp.cycle1; + info->cycle2 = rdp.cycle2; + info->uncombined = rdp.uncombined; + info->geom_mode = rdp.geom_mode; + info->othermode_h = rdp.othermode_h; + info->othermode_l = rdp.othermode_l; + info->tri_n = rdp.tri_n; + info->type = type; + + for (int i=0; i<2; i++) + { + int j = rdp.cur_tile+i; + if (i == 0) + info->t[i].tmu = rdp.t0; + else + info->t[i].tmu = rdp.t1; + info->t[i].cur_cache[0] = rdp.cur_cache_n[rdp.t0]; + info->t[i].cur_cache[1] = rdp.cur_cache_n[rdp.t1]; + info->t[i].format = rdp.tiles[j].format; + info->t[i].size = rdp.tiles[j].size; + info->t[i].width = rdp.tiles[j].width; + info->t[i].height = rdp.tiles[j].height; + info->t[i].line = rdp.tiles[j].line; + info->t[i].palette = rdp.tiles[j].palette; + info->t[i].clamp_s = rdp.tiles[j].clamp_s; + info->t[i].clamp_t = rdp.tiles[j].clamp_t; + info->t[i].mirror_s = rdp.tiles[j].mirror_s; + info->t[i].mirror_t = rdp.tiles[j].mirror_t; + info->t[i].shift_s = rdp.tiles[j].shift_s; + info->t[i].shift_t = rdp.tiles[j].shift_t; + info->t[i].mask_s = rdp.tiles[j].mask_s; + info->t[i].mask_t = rdp.tiles[j].mask_t; + info->t[i].ul_s = rdp.tiles[j].ul_s; + info->t[i].ul_t = rdp.tiles[j].ul_t; + info->t[i].lr_s = rdp.tiles[j].lr_s; + info->t[i].lr_t = rdp.tiles[j].lr_t; + info->t[i].t_ul_s = rdp.tiles[7].t_ul_s; + info->t[i].t_ul_t = rdp.tiles[7].t_ul_t; + info->t[i].t_lr_s = rdp.tiles[7].t_lr_s; + info->t[i].t_lr_t = rdp.tiles[7].t_lr_t; + info->t[i].scale_s = rdp.tiles[j].s_scale; + info->t[i].scale_t = rdp.tiles[j].t_scale; + } + + info->fog_color = rdp.fog_color; + info->fill_color = rdp.fill_color; + info->prim_color = rdp.prim_color; + info->blend_color = rdp.blend_color; + info->env_color = rdp.env_color; + info->prim_lodmin = rdp.prim_lodmin; + info->prim_lodfrac = rdp.prim_lodfrac; + + info->pNext = _debugger.tri_list; + _debugger.tri_list = info; + + if (_debugger.tri_last == NULL) + _debugger.tri_last = _debugger.tri_list; + } +} + +void update_scissor () +{ + if (rdp.update & UPDATE_SCISSOR) + { + rdp.update ^= UPDATE_SCISSOR; + + // KILL the floating point error with 0.01f + rdp.scissor.ul_x = (wxUint32)max(min((rdp.scissor_o.ul_x * rdp.scale_x + rdp.offset_x + 0.01f),settings.res_x),0); + rdp.scissor.lr_x = (wxUint32)max(min((rdp.scissor_o.lr_x * rdp.scale_x + rdp.offset_x + 0.01f),settings.res_x),0); + rdp.scissor.ul_y = (wxUint32)max(min((rdp.scissor_o.ul_y * rdp.scale_y + rdp.offset_y + 0.01f),settings.res_y),0); + rdp.scissor.lr_y = (wxUint32)max(min((rdp.scissor_o.lr_y * rdp.scale_y + rdp.offset_y + 0.01f),settings.res_y),0); + //grClipWindow specifies the hardware clipping window. Any pixels outside the clipping window are rejected. + //Values are inclusive for minimum x and y values and exclusive for maximum x and y values. +// grClipWindow (rdp.scissor.ul_x?rdp.scissor.ul_x+1:0, rdp.scissor.ul_y?rdp.scissor.ul_y+1:0, rdp.scissor.lr_x, rdp.scissor.lr_y); + if (fullscreen) + grClipWindow (rdp.scissor.ul_x, rdp.scissor.ul_y, rdp.scissor.lr_x, rdp.scissor.lr_y); + FRDP (" |- scissor - (%d, %d) -> (%d, %d)\n", rdp.scissor.ul_x, rdp.scissor.ul_y, + rdp.scissor.lr_x, rdp.scissor.lr_y); + } +} + +// +// update - update states if they need it +// + +typedef struct +{ + unsigned int c2_m2b:2; + unsigned int c1_m2b:2; + unsigned int c2_m2a:2; + unsigned int c1_m2a:2; + unsigned int c2_m1b:2; + unsigned int c1_m1b:2; + unsigned int c2_m1a:2; + unsigned int c1_m1a:2; +} rdp_blender_setting; + +void update () +{ + LRDP ("-+ update called\n"); + // Check for rendermode changes + // Z buffer + if (rdp.render_mode_changed & 0x00000C30) + { + FRDP (" |- render_mode_changed zbuf - decal: %s, update: %s, compare: %s\n", + str_yn[(rdp.othermode_l & 0x00000400)?1:0], + str_yn[(rdp.othermode_l&0x00000020)?1:0], + str_yn[(rdp.othermode_l&0x00000010)?1:0]); + + rdp.render_mode_changed &= ~0x00000C30; + rdp.update |= UPDATE_ZBUF_ENABLED; + + // Update? + if ((rdp.othermode_l & 0x00000020)) + rdp.flags |= ZBUF_UPDATE; + else + rdp.flags &= ~ZBUF_UPDATE; + + // Compare? + if (rdp.othermode_l & 0x00000010) + rdp.flags |= ZBUF_COMPARE; + else + rdp.flags &= ~ZBUF_COMPARE; + } + + // Alpha compare + if (rdp.render_mode_changed & 0x00001000) + { + FRDP (" |- render_mode_changed alpha compare - on: %s\n", + str_yn[(rdp.othermode_l&0x00001000)?1:0]); + rdp.render_mode_changed &= ~0x00001000; + rdp.update |= UPDATE_ALPHA_COMPARE; + + if (rdp.othermode_l & 0x00001000) + rdp.flags |= ALPHA_COMPARE; + else + rdp.flags &= ~ALPHA_COMPARE; + } + + if (rdp.render_mode_changed & 0x00002000) // alpha cvg sel + { + FRDP (" |- render_mode_changed alpha cvg sel - on: %s\n", + str_yn[(rdp.othermode_l&0x00002000)?1:0]); + rdp.render_mode_changed &= ~0x00002000; + rdp.update |= UPDATE_COMBINE; + rdp.update |= UPDATE_ALPHA_COMPARE; + } + + // Force blend + if (rdp.render_mode_changed & 0xFFFF0000) + { + FRDP (" |- render_mode_changed force_blend - %08lx\n", rdp.othermode_l&0xFFFF0000); + rdp.render_mode_changed &= 0x0000FFFF; + + rdp.fbl_a0 = (wxUint8)((rdp.othermode_l>>30)&0x3); + rdp.fbl_b0 = (wxUint8)((rdp.othermode_l>>26)&0x3); + rdp.fbl_c0 = (wxUint8)((rdp.othermode_l>>22)&0x3); + rdp.fbl_d0 = (wxUint8)((rdp.othermode_l>>18)&0x3); + rdp.fbl_a1 = (wxUint8)((rdp.othermode_l>>28)&0x3); + rdp.fbl_b1 = (wxUint8)((rdp.othermode_l>>24)&0x3); + rdp.fbl_c1 = (wxUint8)((rdp.othermode_l>>20)&0x3); + rdp.fbl_d1 = (wxUint8)((rdp.othermode_l>>16)&0x3); + + rdp.update |= UPDATE_COMBINE; + } + + // Combine MUST go before texture + if ((rdp.update & UPDATE_COMBINE) && rdp.allow_combine) + { + TBUFF_COLOR_IMAGE * aTBuff[2] = {0, 0}; + if (rdp.aTBuffTex[0]) + aTBuff[rdp.aTBuffTex[0]->tile] = rdp.aTBuffTex[0]; + if (rdp.aTBuffTex[1]) + aTBuff[rdp.aTBuffTex[1]->tile] = rdp.aTBuffTex[1]; + rdp.aTBuffTex[0] = aTBuff[0]; + rdp.aTBuffTex[1] = aTBuff[1]; + + LRDP (" |-+ update_combine\n"); + Combine (); + } + + if (rdp.update & UPDATE_TEXTURE) // note: UPDATE_TEXTURE and UPDATE_COMBINE are the same + { + rdp.tex_ctr ++; + if (rdp.tex_ctr == 0xFFFFFFFF) + rdp.tex_ctr = 0; + + TexCache (); + if (rdp.noise == RDP::noise_none) + rdp.update ^= UPDATE_TEXTURE; + } + + if (fullscreen) + { + // Z buffer + if (rdp.update & UPDATE_ZBUF_ENABLED) + { + // already logged above + rdp.update ^= UPDATE_ZBUF_ENABLED; + + if (((rdp.flags & ZBUF_ENABLED) || rdp.zsrc == 1) && rdp.cycle_mode < 2) + { + if (rdp.flags & ZBUF_COMPARE) + { + switch ((rdp.rm & 0xC00)>>10) { + case 0: + grDepthBiasLevel(0); + grDepthBufferFunction (settings.zmode_compare_less ? GR_CMP_LESS : GR_CMP_LEQUAL); + break; + case 1: + grDepthBiasLevel(-4); + grDepthBufferFunction (settings.zmode_compare_less ? GR_CMP_LESS : GR_CMP_LEQUAL); + break; + case 2: + grDepthBiasLevel(settings.ucode == 7 ? -4 : 0); + grDepthBufferFunction (GR_CMP_LESS); + break; + case 3: + // will be set dynamically per polygon + //grDepthBiasLevel(-deltaZ); + grDepthBufferFunction (GR_CMP_LEQUAL); + break; + } + } + else + { + grDepthBiasLevel(0); + grDepthBufferFunction (GR_CMP_ALWAYS); + } + + if (rdp.flags & ZBUF_UPDATE) + grDepthMask (FXTRUE); + else + grDepthMask (FXFALSE); + } + else + { + grDepthBiasLevel(0); + grDepthBufferFunction (GR_CMP_ALWAYS); + grDepthMask (FXFALSE); + } + } + + // Alpha compare + if (rdp.update & UPDATE_ALPHA_COMPARE) + { + // already logged above + rdp.update ^= UPDATE_ALPHA_COMPARE; + + // if (rdp.acmp == 1 && !(rdp.othermode_l & 0x00002000) && !force_full_alpha) + // if (rdp.acmp == 1 && !(rdp.othermode_l & 0x00002000) && (rdp.blend_color&0xFF)) + if (rdp.acmp == 1 && !(rdp.othermode_l & 0x00002000) && (!(rdp.othermode_l & 0x00004000) || (rdp.blend_color&0xFF))) + { + wxUint8 reference = (wxUint8)(rdp.blend_color&0xFF); + grAlphaTestFunction (reference ? GR_CMP_GEQUAL : GR_CMP_GREATER); + grAlphaTestReferenceValue (reference); + FRDP (" |- alpha compare: blend: %02lx\n", reference); + } + else + { + if (rdp.flags & ALPHA_COMPARE) + { + if ((rdp.othermode_l & 0x5000) != 0x5000) + { + grAlphaTestFunction (GR_CMP_GEQUAL); + grAlphaTestReferenceValue (0x20);//0xA0); + LRDP (" |- alpha compare: 0x20\n"); + } + else + { + grAlphaTestFunction (GR_CMP_GREATER); + if (rdp.acmp == 3) + { + grAlphaTestReferenceValue ((wxUint8)(rdp.blend_color&0xFF)); + FRDP (" |- alpha compare: blend: %02lx\n", rdp.blend_color&0xFF); + } + else + { + grAlphaTestReferenceValue (0x00); + LRDP (" |- alpha compare: 0x00\n"); + } + } + } + else + { + grAlphaTestFunction (GR_CMP_ALWAYS); + LRDP (" |- alpha compare: none\n"); + } + } + if (rdp.acmp == 3 && rdp.cycle_mode < 2) + { + if (grStippleModeExt != 0) + { + if (settings.old_style_adither || rdp.alpha_dither_mode != 3) { + LRDP (" |- alpha compare: dither\n"); + grStippleModeExt(settings.stipple_mode); + } + else + grStippleModeExt(GR_STIPPLE_DISABLE); + } + } + else + { + if (grStippleModeExt) + { + //LRDP (" |- alpha compare: dither disabled\n"); + grStippleModeExt(GR_STIPPLE_DISABLE); + } + } + } + // Cull mode (leave this in for z-clipped triangles) + if (rdp.update & UPDATE_CULL_MODE) + { + rdp.update ^= UPDATE_CULL_MODE; + wxUint32 mode = (rdp.flags & CULLMASK) >> CULLSHIFT; + FRDP (" |- cull_mode - mode: %s\n", str_cull[mode]); + switch (mode) + { + case 0: // cull none + case 3: // cull both + grCullMode(GR_CULL_DISABLE); + break; + case 1: // cull front + // grCullMode(GR_CULL_POSITIVE); + grCullMode(GR_CULL_NEGATIVE); + break; + case 2: // cull back + // grCullMode (GR_CULL_NEGATIVE); + grCullMode (GR_CULL_POSITIVE); + break; + } + } + + //Added by Gonetz. + if (settings.fog && (rdp.update & UPDATE_FOG_ENABLED)) + { + rdp.update ^= UPDATE_FOG_ENABLED; + + wxUint16 blender = (wxUint16)(rdp.othermode_l >> 16); + if (rdp.flags & FOG_ENABLED) + { + rdp_blender_setting &bl = *(rdp_blender_setting*)(&(blender)); + if((rdp.fog_multiplier > 0) && (bl.c1_m1a==3 || bl.c1_m2a == 3 || bl.c2_m1a == 3 || bl.c2_m2a == 3)) + { + grFogColorValue(rdp.fog_color); + grFogMode (GR_FOG_WITH_TABLE_ON_FOGCOORD_EXT); + rdp.fog_mode = RDP::fog_enabled; + LRDP("fog enabled \n"); + } + else + { + LRDP("fog disabled in blender\n"); + rdp.fog_mode = RDP::fog_disabled; + grFogMode (GR_FOG_DISABLE); + } + } + else if (blender == 0xc410 || blender == 0xc411 || blender == 0xf500) + { + grFogColorValue(rdp.fog_color); + grFogMode (GR_FOG_WITH_TABLE_ON_FOGCOORD_EXT); + rdp.fog_mode = RDP::fog_blend; + LRDP("fog blend \n"); + } + else if (blender == 0x04d1) + { + grFogColorValue(rdp.fog_color); + grFogMode (GR_FOG_WITH_TABLE_ON_FOGCOORD_EXT); + rdp.fog_mode = RDP::fog_blend_inverse; + LRDP("fog blend \n"); + } + else + { + LRDP("fog disabled\n"); + rdp.fog_mode = RDP::fog_disabled; + grFogMode (GR_FOG_DISABLE); + } + } + } + + if (rdp.update & UPDATE_VIEWPORT) + { + rdp.update ^= UPDATE_VIEWPORT; + if (fullscreen) + { + float scale_x = (float)fabs(rdp.view_scale[0]); + float scale_y = (float)fabs(rdp.view_scale[1]); + + rdp.clip_min_x = max((rdp.view_trans[0] - scale_x + rdp.offset_x) / rdp.clip_ratio, 0.0f); + rdp.clip_min_y = max((rdp.view_trans[1] - scale_y + rdp.offset_y) / rdp.clip_ratio, 0.0f); + rdp.clip_max_x = min((rdp.view_trans[0] + scale_x + rdp.offset_x) * rdp.clip_ratio, settings.res_x); + rdp.clip_max_y = min((rdp.view_trans[1] + scale_y + rdp.offset_y) * rdp.clip_ratio, settings.res_y); + + FRDP (" |- viewport - (%d, %d, %d, %d)\n", (wxUint32)rdp.clip_min_x, (wxUint32)rdp.clip_min_y, (wxUint32)rdp.clip_max_x, (wxUint32)rdp.clip_max_y); + if (!rdp.scissor_set) + { + rdp.scissor.ul_x = (wxUint32)rdp.clip_min_x; + rdp.scissor.lr_x = (wxUint32)rdp.clip_max_x; + rdp.scissor.ul_y = (wxUint32)rdp.clip_min_y; + rdp.scissor.lr_y = (wxUint32)rdp.clip_max_y; + grClipWindow (rdp.scissor.ul_x, rdp.scissor.ul_y, rdp.scissor.lr_x, rdp.scissor.lr_y); + } + } + } + + if (rdp.update & UPDATE_SCISSOR) + update_scissor (); + + LRDP (" + update end\n"); +} + +void set_message_combiner () +{ + grColorCombine (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_NONE, + GR_COMBINE_OTHER_TEXTURE, + FXFALSE); + grAlphaCombine (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_NONE, + GR_COMBINE_OTHER_TEXTURE, + FXFALSE); + if (settings.buff_clear && (settings.show_fps & 0x08)) + grAlphaBlendFunction (GR_BLEND_SRC_ALPHA, + GR_BLEND_ONE_MINUS_SRC_ALPHA, + GR_BLEND_ZERO, + GR_BLEND_ZERO); + else + grAlphaBlendFunction (GR_BLEND_ONE, + GR_BLEND_ZERO, + GR_BLEND_ZERO, + GR_BLEND_ZERO); + grAlphaTestFunction (GR_CMP_ALWAYS); + if (grStippleModeExt) + { + grStippleModeExt(GR_STIPPLE_DISABLE); + } + grTexFilterMode (0, GR_TEXTUREFILTER_BILINEAR, GR_TEXTUREFILTER_BILINEAR); + grTexCombine (GR_TMU1, + GR_COMBINE_FUNCTION_NONE, + GR_COMBINE_FACTOR_NONE, + GR_COMBINE_FUNCTION_NONE, + GR_COMBINE_FACTOR_NONE, + FXFALSE, FXFALSE); + grTexCombine (GR_TMU0, + GR_COMBINE_FUNCTION_LOCAL, + GR_COMBINE_FACTOR_NONE, + GR_COMBINE_FUNCTION_LOCAL, + GR_COMBINE_FACTOR_NONE, + FXFALSE, FXFALSE); + grTexSource(GR_TMU0, + voodoo.tex_min_addr[GR_TMU0] + offset_font, + GR_MIPMAPLEVELMASK_BOTH, + &fontTex); + grFogMode (GR_FOG_DISABLE); +} + diff --git a/Source/Glide64/Util.h b/Source/Glide64/Util.h new file mode 100644 index 000000000..9f11c56d0 --- /dev/null +++ b/Source/Glide64/Util.h @@ -0,0 +1,93 @@ +/* +* Glide64 - Glide video plugin for Nintendo 64 emulators. +* Copyright (c) 2002 Dave2001 +* Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski +* +* 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 +* 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 +*/ + +//**************************************************************** +// +// Glide64 - Glide Plugin for Nintendo 64 emulators +// Project started on December 29th, 2001 +// +// Authors: +// Dave2001, original author, founded the project in 2001, left it in 2002 +// Gugaman, joined the project in 2002, left it in 2002 +// Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002 +// Hiroshi 'KoolSmoky' Morii, joined the project in 2007 +// +//**************************************************************** +// +// To modify Glide64: +// * Write your name and (optional)email, commented by your work, so I know who did it, and so that you can find which parts you modified when it comes time to send it to me. +// * Do NOT send me the whole project or file that you modified. Take out your modified code sections, and tell me where to put them. If people sent the whole thing, I would have many different versions, but no idea how to combine them all. +// +//**************************************************************** + +#ifndef Util_H +#define Util_H + +#define NOT_TMU0 0x00 +#define NOT_TMU1 0x01 +#define NOT_TMU2 0x02 + +void util_init (); +void render_tri (wxUint16 linew = 0); + +int cull_tri (VERTEX **v); +void draw_tri (VERTEX **v, wxUint16 linew = 0); +void do_triangle_stuff (wxUint16 linew = 0, int old_interpolate = TRUE); +void do_triangle_stuff_2 (wxUint16 linew = 0); +void add_tri (VERTEX *v, int n, int type); +void apply_shade_mods (VERTEX *v); + +void update (); +void update_scissor (); + +void set_message_combiner (); + +float ScaleZ(float z); + +// positional and texel coordinate clipping +#define CCLIP(ux,lx,ut,lt,uc,lc) \ + if (ux > lx || lx < uc || ux > lc) { rdp.tri_n += 2; return; } \ + if (ux < uc) { \ + float p = (uc-ux)/(lx-ux); \ + ut = p*(lt-ut)+ut; \ + ux = uc; \ + } \ + if (lx > lc) { \ + float p = (lc-ux)/(lx-ux); \ + lt = p*(lt-ut)+ut; \ + lx = lc; \ + } + +#define CCLIP2(ux,lx,ut,lt,un,ln,uc,lc) \ + if (ux > lx || lx < uc || ux > lc) { rdp.tri_n += 2; return; } \ + if (ux < uc) { \ + float p = (uc-ux)/(lx-ux); \ + ut = p*(lt-ut)+ut; \ + un = p*(ln-un)+un; \ + ux = uc; \ + } \ + if (lx > lc) { \ + float p = (lc-ux)/(lx-ux); \ + lt = p*(lt-ut)+ut; \ + ln = p*(ln-un)+un; \ + lx = lc; \ + } + +#endif // ifndef Util_H diff --git a/Source/Glide64/australia.xpm b/Source/Glide64/australia.xpm new file mode 100644 index 000000000..a07822b50 --- /dev/null +++ b/Source/Glide64/australia.xpm @@ -0,0 +1,34 @@ +/* XPM */ +static const char *australia_xpm[]={ +"30 15 16 1", +" c #E68885", +"0 c #D7BCC7", +"1 c #2F4C95", +"2 c #092A7F", +"3 c #DC2C23", +"4 c #EB9A99", +"5 c #916785", +"6 c #59659D", +"7 c #AEA8C3", +"8 c #DDD5E1", +"9 c #7689BA", +"a c #F7F8FA", +"b c #E46A64", +"c c #C08494", +"d c #6C426C", +"e c #6C2A54", +" 001120342215 0222222221222221", +"65 07143 15 781222222212222222", +"99700a03400a099222222281222222", +"333333333333333222222222222222", +"44 44 b3b4 4 4 222222222221222", +"2170 c43478 512222122222297222", +"08 5227342270 5222792222222222", +"6d22226e122229d222222222122222", +"222222222222222222222222122222", +"222222922222222222222222222222", +"222228a72222222222222222222222", +"22226aa81222222222222212222222", +"222229762222222222222286222222", +"222221212222222222222212222222", +"122222222222222222222222222221"}; diff --git a/Source/Glide64/brazil.xpm b/Source/Glide64/brazil.xpm new file mode 100644 index 000000000..424d7050c --- /dev/null +++ b/Source/Glide64/brazil.xpm @@ -0,0 +1,40 @@ +/* XPM */ +static const char *brazil_xpm[]={ +"30 21 16 1", +" c #3A8E12", +"0 c #3B960A", +"1 c #6FAA02", +"2 c #96B802", +"3 c #FBDD02", +"4 c #D6CA0C", +"5 c #B8BF0D", +"6 c #728652", +"7 c #426272", +"8 c #A29E3A", +"9 c #063C9F", +"a c #A2C2AA", +"b c #8AB1A3", +"c c #3A68A2", +"d c #1D4DA0", +"e c #528492", +" 0 0 0 0 0 ", +" 0000000000000000000000000000 ", +" 0000000000000110000000000000 ", +" 0000000000002332000000000000 ", +" 0000000000143333410000000000 ", +" 0000000005346776435000000000 ", +" 0000000133899999983310000000 ", +" 0000005338999999998335000000 ", +" 000023333abbbbc999d333320000 ", +" 0014333349999cebc99433334100 ", +" 0133333359999999ebd533333310 ", +" 0014333349d999d99da433334100 ", +" 000023333d9d99d99dc333320000 ", +" 0000005338999999dd8335000000 ", +" 0000000133899999983310000000 ", +" 0000000002346776435000000000 ", +" 0000000000143333410000000000 ", +" 0000000000002332000000000000 ", +" 0000000000000000000000000000 ", +" 0000000000000000000000000000 ", +" 0 0 0 0 0 "}; diff --git a/Source/Glide64/build_asm.bat b/Source/Glide64/build_asm.bat new file mode 100644 index 000000000..d017f8eee --- /dev/null +++ b/Source/Glide64/build_asm.bat @@ -0,0 +1,3 @@ +nasm.exe -o lib\Texture.obj -O6 -fwin32 -D__WIN32__ --prefix _ Texture.asm +nasm.exe -o lib\FixedPoint.obj -O6 -fwin32 -D__WIN32__ --prefix _ FixedPoint.asm +nasm.exe -o lib\3dmathSIMD.obj -O6 -fwin32 -D__WIN32__ --prefix _ 3dmathSIMD.asm \ No newline at end of file diff --git a/Source/Glide64/config/Glide64.ini b/Source/Glide64/config/Glide64.ini new file mode 100644 index 000000000..84a844a78 --- /dev/null +++ b/Source/Glide64/config/Glide64.ini @@ -0,0 +1,1774 @@ +;_____________________________________________________________________ +; SETTINGS: +; This section contains the plugin settings, such as +; resolution. +; +; resolution - specifies which resolution to use +; Resolutions are as follows: +; 0 - 320, 200 +; 1 - 320, 240 +; 2 - 400, 256 +; 3 - 512, 384 +; 4 - 640, 200 +; 5 - 640, 350 +; 6 - 640, 400 +; 7 - 640, 480 +; 8 - 800, 600 +; 9 - 960, 720 +; 10 - 856, 480 +; 11 - 512, 256 +; 12 - 1024, 768 +; 13 - 1280, 1024 +; 14 - 1600, 1200 +; 15 - 400, 300 +; 16 - 1152, 864 +; 17 - 1280, 960 +; 18 - 1600, 1024 +; 19 - 1792, 1344 +; 20 - 1856, 1392 +; 21 - 1920, 1440 +; 22 - 2048, 1536 +; 23 - 2048, 2048 +; Note: some video cards or monitors do not support all +; resolutions! +; +; Note#2:For compatibility issues always distribute this +; file with the resolution: 640, 480 (7) +; + +[SETTINGS] +card_id = 0 +resolution=8 +filter_cache = 0 +autodetect_ucode = 1 +ucode = 2 +wireframe = 0 +wfmode=1 +filtering = 1 +depthmode = 0 +fog = 1 +buff_clear = 1 +vsync = 1 +swapmode = 1 +run_in_window = 0 +show_fps = 0 +clock = 0 +clock_24_hr = 0 +wrap_big_tex = 0 +custom_ini = 1 +hotkeys = 1 +ssformat=1 +logging = 0 +log_clear = 0 +unk_as_red = 0 +log_unk = 0 +unk_clear = 0 +new_swap = 1 +hires_motionblur = 0 +flame_corona = 0 +fb_smart = 1 +fb_read_always = 0 +fb_clear = 0 +fb_hires = 1 +fb_depth_clear = 0 +motionblur = 1 +elogging = 0 +lodmode = 0 +fb_get_info = 0 +fb_render = 1 +detect_cpu_write = 0 +fillrec_depth_compare = 0 +tex_wrap_hack = 0 +read_back_to_screen = 0 +advanced_options = 0 +texenh_options = 0 +ghq_fltr = 0 +ghq_cmpr = 0 +ghq_enht = 0 +ghq_hirs = 0 +ghq_enht_cmpr = 0 +ghq_enht_tile = 0 +ghq_enht_f16bpp = 0 +ghq_enht_gz = 1 +ghq_enht_nobg=0 +ghq_hirs_cmpr = 0 +ghq_hirs_tile = 0 +ghq_hirs_f16bpp = 0 +ghq_hirs_gz = 1 +ghq_hirs_altcrc = 1 +ghq_cache_save = 1 +ghq_cache_size=0 +ghq_hirs_let_texartists_fly = 0 +ghq_hirs_dump = 0 +wrpResolution=0 +wrpVRAM=0 +wrpFBO=0 +wrpAnisotropic=0 + +; UCODE: +; These are ucode crcs used in the uCode detector. +; If a crc is not found here, the plugin will ask you +; to add it. All these values are in hexadecimal. +; +; uCodes: +; -1 - Unknown, display error +; 0 - RSP SW 2.0X (Super Mario 64) +; 1 - F3DEX 1.XX (Star Fox 64) +; 2 - F3DEX 2.XX (The Legend of Zelda: Ocarina of Time) +; 3 - F3DEX ? (WaveRace) +; 4 - RSP SW 2.0D EXT (Star Wars: Shadows of the Empire) +; 5 - RSP SW 2.0 (Diddy Kong Racing); +; 6 - S2DEX 1.XX (Yoshi's Story - SimCity 2000) +; 7 - RSP SW PD (Perfect Dark) +; 8 - F3DEXBG 2.08 (Conker's Bad Fur Day) + +[UCODE] +006bd77f=0 +03044b84=2 +030f4b84=2 +05165579=1 +05777c62=1 +057e7c62=1 +07200895=0 +0bf36d36=9 +0d7bbffb=-1 +0d7cbffb=5 +0ff79527=2 +0ff795bf=-1 +1118b3e0=1 +1517a281=1 +168e9cd5=2 +1a1e18a0=2 +1a1e1920=2 +1a62dbaf=2 +1a62dc2f=2 +1de712ff=1 +1ea9e30f=6 +1f120bbb=21 +21f91834=2 +21f91874=2 +22099872=2 +24cd885b=1 +26a7879a=1 +299d5072=6 +2b291027=2 +2b5a89c2=6 +2c7975d6=1 +2d3fe3f1=1 +2f71d1d5=2 +2f7dd1d5=2 +327b933d=1 +339872a6=1 +377359b6=2 +3a1c2b34=0 +3a1cbac3=0 +3f7247fb=0 +3ff1a4ca=1 +4165e1fd=0 +4340ac9b=1 +440cfad6=1 +47d46e86=7 +485abff2=2 +4fe6df78=1 +5182f610=0 +5257cd2a=1 +5414030c=1 +5414030d=1 +559ff7d4=1 +5b5d36e3=4 +5b5d3763=3 +5d1d6f53=0 +5d3099f1=2 +5df1408c=1 +5ef4e34a=1 +6075e9eb=1 +60c1dcc4=1 +6124a508=2 +630a61fb=2 +63be08b1=5 +63be08b3=5 +64ed27e5=1 +65201989=2 +65201a09=2 +66c0b10a=1 +679e1205=2 +6bb745c9=6 +6d8f8f8a=2 +6e4d50af=0 +6eaa1da8=1 +72a4f34e=1 +73999a23=1 +74af0a74=6 +753be4a5=2 +794c3e28=6 +7df75834=1 +7f2d0a2e=1 +82f48073=1 +832fcb99=1 +841ce10f=1 +844b55b5=-1 +863e1ca7=1 +86b1593e=-1 +8805ffea=1 +8d5735b2=1 +8d5735b3=1 +8ec3e124=-1 +93d11f7b=2 +93d11ffb=2 +93d1ff7b=2 +9551177b=2 +955117fb=2 +95cd0062=2 +97d1b58a=1 +a2d0f88e=2 +a346a5cc=1 +aa86cb1d=2 +aae4a5b9=2 +ad0a6292=2 +ad0a6312=2 +ae08d5b9=0 +b1821ed3=1 +b4577b9c=1 +b54e7f93=0 +b62f900f=2 +ba65ea1e=2 +ba86cb1d=8 +bc03e969=0 +bc45382e=2 +be78677c=1 +bed8b069=1 +c3704e41=1 +c46dbc3d=1 +c99a4c6c=1 +c901ce73=2 +c901cef3=2 +cb8c9b6c=2 +cee7920f=1 +cfa35a45=2 +d1663234=1 +d20dedbf=6 +d2a9f59c=1 +d41db5f7=1 +d5604971=0 +d57049a5=1 +d5c4dc96=-1 +d5d68b1f=0 +d67c2f8b=0 +d802ec04=1 +da13ab96=2 +de7d67d4=2 +e1290fa2=2 +e41ec47e=0 +e65cb4ad=2 +e89c2b92=1 +e9231df2=1 +ec040469=1 +ee47381b=1 +ef54ee35=1 +f9893f70=21 +fb816260=1 +ff372492=21 + + + +; Game specific settings +; +; In the [DEFAULT] section there are the default options for a game, which can +; be overriden in the section with the game's internal name. + +[DEFAULT] +filtering = 0 +fog = 1 +buff_clear = 1 +swapmode = 1 +lodmode = 0 +fb_smart = 0 +fb_hires = 1 +fb_get_info = 0 +fb_read_always = 0 +fb_render = 1 +fb_crc_mode = 1 +read_back_to_screen = 0 +detect_cpu_write = 0 +alt_tex_size = 0 +use_sts1_only = 0 +PPL = 0 +fast_crc = 1 +force_microcheck = 0 +force_quad3d = 0 +texrect_zbuf = 0 +fix_tex_coord = 0 +optimize_texrect = 1 +optimize_write = 0 +hires_buf_clear = 1 +depthmode = 1 +fb_clear = 0 +fb_read_alpha = 0 +ignore_previous = 0 +soft_depth_compare = 0 +force_depth_compare = 0 +force_calc_sphere = 0 +texrect_compare_less = 0 +texture_correction = 1 +fillcolor_fix = 0 +depth_bias = 20 +increase_texrect_edge = 0 +decrease_fillrect_edge = 0 +stipple_mode = 2 +stipple_pattern = 1041204192 +clip_zmax = 1 +clip_zmin = 0 +adjust_aspect = 1 +correct_viewport = 0 +aspect = 0 +zmode_compare_less = 0 +old_style_adither = 0 +n64_z_scale = 0 + +[1080 SNOWBOARDING] +optimize_texrect = 1 +alt_tex_size = 1 +depthmode = 0 +swapmode = 2 +fb_smart = 1 +fb_hires = 1 +fb_clear = 1 + +[A Bug's Life] +depthmode = 0 + +[AERO FIGHTERS ASSAUL] +clip_zmin = 1 + +[AIDYN_CHRONICLES] +depthmode = 1 + +[All-Star Baseball 20] +force_depth_compare = 1 + +[All-Star Baseball 99] +force_depth_compare = 1 +depthmode = 1 +buff_clear = 0 + +[All Star Baseball 99] +force_depth_compare = 1 +depthmode = 1 +buff_clear = 0 + +[All-Star Baseball '0] +force_depth_compare = 1 +depthmode = 0 +fb_smart = 1 +fb_hires = 1 + +[ARMYMENAIRCOMBAT] +increase_texrect_edge = 1 +depthmode = 1 + +[BURABURA POYON] +fix_tex_coord = 1 +depthmode = 0 + +;Bakushou Jinsei 64 - Mezease! Resort Ou. +[ÊÞ¸¼®³¼Þݾ²64] +fb_info_disable = 1 +depthmode = 0 + +[BAKU-BOMBERMAN] +depthmode = 0 +fb_smart = 1 +fb_hires = 1 + +[BAKUBOMB2] +filtering = 1 +depthmode = 0 + +[BANGAIOH] +depthmode = 1 + +[Banjo-Kazooie] +filtering = 1 +depthmode = 1 +fb_smart = 1 +fb_hires = 1 + +[BANJO KAZOOIE 2] +filtering = 1 +depthmode = 1 +fb_smart = 1 +fb_hires = 1 + +[BANJO TOOIE] +filtering = 1 +depthmode = 1 +fb_smart = 1 +fb_hires = 1 + +[BASS HUNTER 64] +fix_tex_coord = 1 +depthmode = 1 +buff_clear = 0 +swapmode = 2 + +[BATTLEZONE] +force_depth_compare = 1 +depthmode = 1 + +[BEETLE ADVENTURE JP] +wrap_big_tex = 1 +n64_z_scale = 1 +filtering = 1 +depthmode = 1 +fb_smart = 1 +fb_hires = 1 + +[Beetle Adventure Rac] +wrap_big_tex = 1 +n64_z_scale = 1 +filtering = 1 +depthmode = 1 +fb_smart = 1 +fb_hires = 1 + +[Big Mountain 2000] +depthmode = 1 + +[BIOFREAKS] +depthmode = 0 +buff_clear = 0 +fb_smart = 1 +fb_hires = 1 + +[BioHazard II] +detect_cpu_write = 1 +adjust_aspect = 0 +n64_z_scale = 1 +fix_tex_coord = 128 +depthmode = 0 +swapmode = 2 +fb_smart = 1 +fb_hires = 1 + +[Blast Corps] +depthmode = 1 +swapmode = 0 +fb_smart = 1 +fb_hires = 1 +fb_read_alpha = 1 + +[Blastdozer] +depthmode = 1 +swapmode = 0 +fb_smart = 1 +fb_hires = 1 +fb_read_alpha = 1 + +[blitz2k] +lodmode = 2 + +[Body Harvest] +depthmode = 1 +fb_smart = 1 +fb_hires = 1 + +[BOMBERMAN64E] +depthmode = 0 +fb_smart = 1 +fb_hires = 1 + +[BOMBERMAN64U] +depthmode = 0 +fb_smart = 1 +fb_hires = 1 + +[BOMBERMAN64U2] +filtering = 1 +depthmode = 0 + +[Bottom of the 9th] +optimize_texrect = 0 +filtering = 1 +depthmode = 0 +fb_smart = 1 +fb_hires = 1 + +[BRUNSWICKBOWLING] +depthmode = 0 +buff_clear = 0 +swapmode = 0 + +[Bust A Move 3 DX] +filtering = 2 +depthmode = 1 + +[Bust A Move '99] +filtering = 2 +depthmode = 1 + +[Bust A Move 2] +fix_tex_coord = 1 +filtering = 2 +depthmode = 1 +fog = 0 + +[CARMAGEDDON64] +wrap_big_tex = 1 +filtering = 1 +depthmode = 1 + +[CASTLEVANIA] +depthmode = 0 +fb_clear = 1 +old_style_adither = 1 + +[CASTLEVANIA2] +depthmode = 0 +fb_clear = 1 + +[CENTRE COURT TENNIS] +soft_depth_compare = 1 +depthmode = 0 + +[Chameleon Twist2] +filtering = 1 +depthmode = 0 + +[CHOPPER_ATTACK] +filtering = 1 +depthmode = 0 + +[CITY TOUR GP] +force_microcheck = 1 +filtering = 1 +depthmode = 1 + +[Command&Conquer] +fix_tex_coord = 1 +aspect = 2 +filtering = 1 +depthmode = 1 +fog = 0 + +[CONKER BFD] +optimize_texrect = 1 +ignore_previous = 1 +lodmode = 1 +filtering = 1 +depthmode = 0 +fb_smart = 1 +fb_hires = 1 +fb_clear = 1 + +[Cruis'n USA] +filtering = 1 +depthmode = 1 +fb_smart = 1 +fb_hires = 1 +fb_clear = 1 + +[CruisnExotica] +filtering = 1 +depthmode = 1 +buff_clear = 0 +swapmode = 0 + +[custom robo] +depthmode = 0 +fb_smart = 1 +fb_hires = 1 + +[CUSTOMROBOV2] +depthmode = 0 +fb_smart = 1 +fb_hires = 1 + +[CyberTiger] +fix_tex_coord = 16 +depthmode = 0 + +[DAFFY DUCK STARRING] +depthmode = 1 +wrap_big_tex = 1 + +[DARK RIFT] +force_microcheck = 1 + +[DeadlyArts] +soft_depth_compare = 1 +depthmode = 0 +fb_smart = 1 +fb_hires = 1 +clip_zmin = 1 + +[DERBYSTALLION 64] +fix_tex_coord = 1 +depthmode = 0 + +[D K DISPLAY] +depthmode = 1 +fb_clear = 1 + +[Donald Duck Goin' Qu] +detect_cpu_write = 1 +depthmode = 0 + +[Donald Duck Quack At] +detect_cpu_write = 1 +depthmode = 0 + +[DONKEY KONG 64] +lodmode = 1 +depth_bias = 64 +depthmode = 1 +fb_clear = 1 + +[Doom64] +fillcolor_fix = 1 +depthmode = 1 + +;Doraemon - Mittsu no Seireiseki (J) +[ÄÞ×´ÓÝ Ð¯Âɾ²Ú²¾·] +read_back_to_screen = 1 +depthmode = 1 +fb_smart = 1 +fb_hires = 1 + +;Doraemon 3 - Nobita no Machi SOS! (J) +[ÄÞ×´ÓÝ3 ÉËÞÀÉÏÁSOS!] +clip_zmin = 1 + +[DR.MARIO 64] +fix_tex_coord = 256 +optimize_write = 1 +read_back_to_screen = 1 +depthmode = 1 +fb_smart = 1 +fb_hires = 0 + +[DRACULA MOKUSHIROKU] +depthmode = 0 +fb_clear = 1 + +[DRACULA MOKUSHIROKU2] +depthmode = 0 +fb_clear = 1 + +[Dual heroes JAPAN] +filtering = 1 +depthmode = 0 +swapmode = 0 + +[Dual heroes PAL] +filtering = 1 +depthmode = 0 +swapmode = 0 + +[Dual heroes USA] +filtering = 1 +depthmode = 0 +swapmode = 0 + +[DUKE NUKEM] +increase_primdepth = 1 +depthmode = 0 + +[EARTHWORM JIM 3D] +increase_primdepth = 1 +filtering = 1 +depthmode = 0 +buff_clear = 0 + +;Eikou no Saint Andrew +[´²º³É¾ÝıÝÄÞØ­°½] +correct_viewport = 1 + +[Eltail] +filtering = 2 +depthmode = 1 + +[EVANGELION] +depthmode = 1 + +[EXCITEBIKE64] +depthmode = 0 +fb_smart = 1 +fb_hires = 1 + +[extreme_g] +depthmode = 0 +fb_smart = 1 +fb_hires = 1 + +[extremeg] +depthmode = 0 +fb_smart = 1 +fb_hires = 1 + +[´¸½ÄØ°ÑG2] +depthmode = 0 +fb_smart = 1 +fb_hires = 1 +fb_clear = 1 + +[Extreme G 2] +depthmode = 0 +fb_smart = 1 +fb_hires = 1 +fb_clear = 1 + +[F1 POLE POSITION 64] +clip_zmin = 1 +filtering = 2 +depthmode = 1 + +[F1RacingChampionship] +depthmode = 0 +buff_clear = 0 +swapmode = 0 + +[F1 WORLD GRAND PRIX] +soft_depth_compare = 1 +wrap_big_tex = 1 +depthmode = 0 +buff_clear = 0 + +[F1 WORLD GRAND PRIX2] +wrap_big_tex = 1 +soft_depth_compare = 1 +depthmode = 0 +buff_clear = 0 + +[F-ZERO X] +depthmode = 1 + +;Fushigi no Dungeon - Furai no Shiren 2 (J) +[F3 ̳ײɼÚÝ2] +decrease_fillrect_edge = 1 +depthmode = 0 + +[Fighting Force] +depthmode = 1 + +[G.A.S.P!!Fighters'NE] +soft_depth_compare = 1 +depthmode = 0 +fb_smart = 1 +fb_hires = 1 +clip_zmin = 1 + +[GANBAKE GOEMON] +optimize_texrect = 0 +alt_tex_size = 1 +filtering = 1 +depthmode = 1 +fb_smart = 1 +fb_hires = 1 + +;Ganbare Goemon - Neo Momoyama Bakufu no Odori +[¶ÞÝÊÞÚ\ ºÞ´ÓÝ] +optimize_texrect = 0 +alt_tex_size = 1 +filtering = 1 +depthmode = 1 +fb_smart = 1 +fb_hires = 1 + +[GAUNTLET LEGENDS] +depthmode = 1 +swapmode = 2 + +[Getter Love!!] +zmode_compare_less = 1 +texrect_compare_less = 1 +filtering = 2 +depthmode = 1 + +[Gex 3 Deep Cover Gec] +filtering = 1 +depthmode = 0 + +[GEX: ENTER THE GECKO] +filtering = 1 +depthmode = 0 + +[Glover] +filtering = 1 +depthmode = 0 + +[GOEMON2 DERODERO] +filtering = 1 +depthmode = 1 +fb_smart = 1 +fb_hires = 1 + +[GOEMONS GREAT ADV] +filtering = 1 +depthmode = 1 +fb_smart = 1 +fb_hires = 1 + +[GOLDENEYE] +lodmode = 1 +depth_bias = 40 +filtering = 1 +depthmode = 0 +fb_smart = 1 +fb_hires = 1 + +[GOLDEN NUGGET 64] +filtering = 2 +depthmode = 1 + +[GT64] +force_microcheck = 1 +filtering = 1 +depthmode = 1 + +; Hamster Monogatori +[ÊѽÀ°ÓɶÞÀØ64] +force_microcheck = 1 +depthmode = 0 + +[HARVESTMOON64] +zmode_compare_less = 1 +depthmode = 0 +fog = 0 + +; Harvest Moon 64 JAP +[ÎÞ¸¼Þ®³ÓɶÞÀØ2] +zmode_compare_less = 1 +depthmode = 0 +fog = 0 + +; Heiwa Pachinko World +[HEIWA ÊßÁݺ Ü°ÙÄÞ64] +depthmode = 0 +fog = 0 +swapmode = 2 +fb_smart = 1 +fb_hires = 1 + +[HEXEN] +detect_cpu_write = 1 +filtering = 1 +depthmode = 1 +buff_clear = 0 +swapmode = 2 + +[HSV ADVENTURE RACING] +wrap_big_tex = 1 +n64_z_scale = 1 +filtering = 1 +depthmode = 1 +fb_smart = 1 +fb_hires = 1 + +[Holy Magic Century] +filtering = 2 +depthmode = 1 + +[HUMAN GRAND PRIX] +filtering = 2 +depthmode = 0 + +[·×¯Ä¶²¹Â 64ÀÝòÀÞÝ] +filtering = 1 +depthmode = 0 +buff_clear = 0 + +[Iggy's Reckin' Balls] +fix_tex_coord = 512 +depthmode = 0 + +[I S S 64] +depthmode = 1 +swapmode = 2 +old_style_adither = 1 + +[I.S.S.2000] +depthmode = 1 +fb_smart = 1 +fb_hires = 1 + +[ITF 2000] +filtering = 1 +depthmode = 1 +fb_smart = 1 +fb_hires = 1 + +[IT&F SUMMERGAMES] +filtering = 1 +depthmode = 1 +fb_smart = 1 +fb_hires = 1 + +[J_league 1997] +fix_tex_coord = 1 +depthmode = 1 +swapmode = 0 + +;J.League Eleven Beat 1997 +[JØ°¸Þ\ ²ÚÌÞÝËÞ°Ä1997] +fb_smart=1 +fb_hires=1 + +[J LEAGUE LIVE 64] +wrap_big_tex = 1 +depthmode = 1 + +[J WORLD SOCCER3] +depthmode = 1 +swapmode = 2 + +[JEREMY MCGRATH SUPER] +depthmode = 0 +swapmode = 0 + +[JET FORCE GEMINI] +read_back_to_screen = 1 +decrease_fillrect_edge = 1 +alt_tex_size = 1 +depthmode = 1 +swapmode = 2 +fb_smart = 1 +fb_hires = 1 + +[J F G DISPLAY] +read_back_to_screen = 1 +decrease_fillrect_edge = 1 +alt_tex_size = 1 +depthmode = 1 +swapmode = 2 +fb_smart = 1 +fb_hires = 1 + +[KEN GRIFFEY SLUGFEST] +read_back_to_screen = 2 +depthmode = 1 +swapmode = 0 +fb_smart = 1 +fb_hires = 1 + +[Kirby64] +filtering = 1 +depthmode = 0 +buff_clear = 0 +swapmode = 0 + +[Killer Instinct Gold] +filtering = 1 +depthmode = 0 +fog = 0 +buff_clear = 0 + +[KNIFE EDGE] +wrap_big_tex = 1 +fast_crc = 0 +filtering = 1 +depthmode = 1 + +[Knockout Kings 2000] +fb_info_disable = 1 +depthmode = 1 +fb_smart = 1 +fb_hires = 1 +fb_clear = 1 +fb_read_alpha = 1 + +[LAMBORGHINI] +use_sts1_only = 1 + +[LCARS - WT_Riker] +depthmode = 1 + +[LEGORacers] +detect_cpu_write = 1 +depthmode = 1 +buff_clear = 0 +fb_smart = 1 +fb_hires = 1 +fb_read_alpha = 1 + +[LET'S SMASH] +soft_depth_compare = 1 +depthmode = 0 + +[Lode Runner 3D] +swapmode = 0 + +[LT DUCK DODGERS] +wrap_big_tex = 1 +depthmode = 1 + +[MACE] +fix_tex_coord = 8 +filtering = 1 +depthmode = 1 + +[MAGICAL TETRIS] +force_microcheck = 1 +depthmode = 1 +fog = 0 + +;Mahjong Master (J) +[Ï°¼Þ¬Ý ϽÀ°] +n64_z_scale = 1 +texrect_compare_less = 1 +zmode_compare_less = 1 + +[MAJORA'S MASK] +wrap_big_tex = 1 +filtering = 1 +depthmode = 1 +fb_smart = 1 +fb_hires = 1 +fb_clear = 1 +fb_crc_mode = 0 + +[MARIOKART64] +fast_crc = 0 +stipple_mode = 1 +stipple_pattern = 4286595040 +depthmode = 1 + +[MarioGolf64] +fb_info_disable = 1 +ignore_aux_copy = 1 +buff_clear = 0 +depthmode = 0 +fb_smart = 1 +fb_hires = 1 +fb_clear = 1 + +[MarioParty] +clip_zmin = 1 +depthmode = 0 +swapmode = 2 + +[MarioParty2] +depthmode = 0 +swapmode = 2 + +[MarioParty3] +fix_tex_coord = 1 +depthmode = 0 + +[MARIO STORY] +useless_is_useless = 1 +hires_buf_clear = 0 +optimize_texrect = 0 +filtering = 1 +depthmode = 1 +swapmode = 2 +fb_smart = 1 +fb_hires = 1 +fb_read_alpha = 1 + +[MASTERS'98] +wrap_big_tex = 1 +depthmode = 0 +fb_smart = 1 +fb_hires = 1 + +[Mega Man 64] +increase_texrect_edge = 1 +depthmode = 1 +fb_smart = 1 +fb_hires = 1 + +[MGAH VOL1] +force_microcheck = 1 +depthmode = 1 +zmode_compare_less = 1 +fb_smart = 1 + +[Mia Hamm Soccer 64] +buff_clear = 0 + +[MICKEY USA] +alt_tex_size = 1 +depthmode = 1 +fb_smart = 1 +fb_hires = 1 +fb_clear = 1 + +[MICKEY USA PAL] +alt_tex_size = 1 +depthmode = 1 +fb_smart = 1 +fb_hires = 1 +fb_clear = 1 + +[MICROMACHINES64TURBO] +depthmode = 0 + +[Mini Racers] +force_microcheck = 1 +buff_clear = 0 +fb_smart = 1 +fb_hires = 1 +swapmode = 0 + +[MISCHIEF MAKERS] +tex_wrap_hack = 0 +depthmode = 1 +fog = 0 + +[MLB FEATURING K G JR] +read_back_to_screen = 2 +depthmode = 1 + +[MK_MYTHOLOGIES] +depthmode = 1 + +[MO WORLD LEAGUE SOCC] +buff_clear = 0 + +[Monaco GP Racing 2] +depthmode = 0 +buff_clear = 0 + +[Monaco Grand Prix] +depthmode = 0 +buff_clear = 0 + +;Morita Shogi 64 +[ÓØÀ¼®³·Þ64] +correct_viewport = 1 + +[MortalKombatTrilogy] +filtering = 2 +depthmode = 1 + +[MS. PAC-MAN MM] +detect_cpu_write = 1 +depthmode = 1 + +[MYSTICAL NINJA] +alt_tex_size = 1 +optimize_texrect = 0 +filtering = 1 +depthmode = 1 +fb_smart = 1 +fb_hires = 1 + +[MYSTICAL NINJA2 SG] +alt_tex_size = 1 +optimize_texrect = 0 +filtering = 1 +depthmode = 1 +fb_smart = 1 +fb_hires = 1 + +[NASCAR 99] +depthmode = 0 +buff_clear = 0 +swapmode = 0 + +[NASCAR 2000] +depthmode = 0 +buff_clear = 0 +swapmode = 0 + +[NBA Courtside 2] +depthmode = 0 +buff_clear = 0 +swapmode = 0 + +[NBA JAM 2000] +buff_clear = 0 + +[NBA JAM 99] +buff_clear = 0 + +[NBA LIVE 2000] +adjust_aspect = 0 + +[NBA Live 99] +swapmode = 0 +adjust_aspect = 0 + +[NEWTETRIS] +pal230 = 1 +fix_tex_coord = 1 +increase_texrect_edge = 1 +depthmode = 0 +fog = 0 + +[NFL BLITZ] +lodmode = 2 + +[NFL BLITZ 2001] +lodmode = 2 + +[NFL BLITZ SPECIAL ED] +lodmode = 2 + +[NFL QBC '99] +force_depth_compare = 1 +wrap_big_tex = 1 +depthmode = 0 + +[NFL QBC 2000] +wrap_big_tex = 1 +depthmode = 0 +swapmode = 0 + +[NFL Quarterback Club] +wrap_big_tex = 1 +depthmode = 0 +swapmode = 0 + +[NINTAMAGAMEGALLERY64] +force_microcheck = 1 +depthmode = 0 + +[NITRO64] +fb_smart = 1 +fb_hires = 1 + +[NUCLEARSTRIKE64] +buff_clear = 0 + +; Nushi Zuri 64 +[ǼÂÞØ64] +force_microcheck = 1 +wrap_big_tex = 0 +depthmode = 0 +buff_clear = 0 + +[OgreBattle64] +fb_info_disable = 1 +force_depth_compare = 1 +depthmode = 1 + +[PACHINKO365NICHI] +correct_viewport = 1 + +[PAPER MARIO] +useless_is_useless = 1 +hires_buf_clear = 0 +optimize_texrect = 0 +filtering = 1 +depthmode = 1 +swapmode = 2 +fb_smart = 1 +fb_hires = 1 +fb_read_alpha = 1 + +[Parlor PRO 64] +force_microcheck = 1 +filtering = 1 +depthmode = 1 + +[Perfect Dark] +useless_is_useless = 1 +decrease_fillrect_edge = 1 +optimize_texrect = 0 +filtering = 1 +depthmode = 1 +fb_smart = 1 +fb_hires = 1 +fb_clear = 1 + +[PERFECT STRIKER] +depthmode = 1 +swapmode = 2 + +[Pilot Wings64] +depthmode = 1 +buff_clear = 0 + +[PUZZLE LEAGUE N64] +PPL = 1 +force_microcheck = 1 +fix_tex_coord = 1 +filtering = 2 +depthmode = 1 +fog = 0 +buff_clear = 0 +fb_smart = 1 +fb_hires = 0 +fb_read_alpha = 1 + +[PUZZLE LEAGUE] +PPL = 1 +force_microcheck = 1 +fix_tex_coord = 1 +filtering = 2 +depthmode = 1 +fog = 0 +buff_clear = 0 +fb_smart = 1 +fb_hires = 0 +fb_read_alpha = 1 + +[POKEMON SNAP] +fast_crc = 0 +depthmode = 1 +fb_smart = 1 +fb_hires = 0 +fb_clear = 1 + +[POKEMON STADIUM] +optimize_texrect = 0 +depthmode = 1 +fast_crc = 0 +buff_clear = 0 +fb_smart = 1 +fb_hires = 0 +fb_read_alpha = 1 +fb_crc_mode = 2 + +[POKEMON STADIUM 2] +optimize_texrect = 0 +swapmode = 2 +depthmode = 1 +fast_crc = 0 +buff_clear = 0 +fb_smart = 1 +fb_hires = 1 +fb_read_alpha = 1 +fb_crc_mode = 2 + +[POKEMON STADIUM G&S] +optimize_texrect = 0 +depthmode = 1 +fast_crc = 0 +buff_clear = 0 +fb_smart = 1 +fb_hires = 0 +fb_read_alpha = 1 +fb_crc_mode = 2 + +[POLARISSNOCROSS] +fix_tex_coord = 5 +depthmode = 1 + +[PowerLeague64] +force_quad3d = 1 + +[Quake] +force_microcheck = 1 +swapmode = 2 +buff_clear = 0 + +[QUAKE II] +fb_smart = 1 +fb_hires = 1 + +[quarterback_club_98] +optimize_texrect = 0 +hires_buf_clear = 0 +filtering = 1 +depthmode = 1 +swapmode = 0 +buff_clear = 0 +fb_smart = 1 +fb_hires = 1 +fb_read_alpha = 1 + +[Quest 64] +depthmode = 1 + +[Racing Simulation 2] +depthmode = 0 +buff_clear = 0 + +[RAINBOW SIX] +increase_texrect_edge = 1 +depthmode = 1 + +[Rally'99] +filtering = 1 +depthmode = 1 +buff_clear = 0 +fb_smart = 1 +fb_hires = 1 + +[RALLY CHALLENGE] +filtering = 1 +depthmode = 1 +buff_clear = 0 +fb_smart = 1 +fb_hires = 1 + +[Rayman 2] +depthmode = 0 +detect_cpu_write = 1 + +[READY 2 RUMBLE] +fix_tex_coord = 64 +depthmode = 0 + +[Ready to Rumble] +fix_tex_coord = 1 +depthmode = 0 + +[Resident Evil II] +detect_cpu_write = 1 +adjust_aspect = 0 +n64_z_scale = 1 +fix_tex_coord = 128 +depthmode = 0 +swapmode = 2 +fb_smart = 1 +fb_hires = 1 + +[Re-Volt] +texture_correction = 0 +depthmode = 1 + +[RIDGE RACER 64] +force_calc_sphere = 1 +depthmode = 0 +fb_smart = 1 +fb_hires = 1 + +[ROAD RASH 64] +depthmode = 0 +swapmode = 2 + +[Robopon64] +depthmode = 0 +fb_smart = 1 +fb_hires = 1 + +[ROCKETROBOTONWHEELS] +clip_zmin = 1 + +[RockMan Dash] +increase_texrect_edge = 1 +depthmode = 1 +fb_smart = 1 +fb_hires = 1 + +[RONALDINHO SOCCER] +depthmode = 1 +swapmode = 2 +old_style_adither = 1 + +[RTL WLS2000] +buff_clear = 0 + +[RUGRATS IN PARIS] +depthmode = 1 + +[RUSH 2049] +force_texrect_zbuf = 1 +filtering = 1 +depthmode = 0 + +[SCARS] +filtering = 1 +depthmode = 0 + +[SD HIRYU STADIUM] +force_microcheck = 1 +depthmode = 0 + +[Shadow of the Empire] +swapmode = 2 + +[Shadowman] +depthmode = 0 + +[Silicon Valley] +filtering = 1 +depthmode = 0 + +[Snobow Kids 2] +swapmode = 0 +filtering = 1 + +[SNOWBOARD KIDS2] +swapmode = 0 +filtering = 1 + +[South Park: Chef's L] +fix_tex_coord = 4 +filtering = 2 +depthmode = 1 +fog = 0 +buff_clear = 0 + +[South Park Chef's Lu] +fix_tex_coord = 4 +filtering = 1 +depthmode = 1 +fog = 0 +buff_clear = 0 + +[SPACE DYNAMITES] +force_microcheck = 1 + +[SPIDERMAN] +fast_crc = 0 + +[STARCRAFT 64] +detect_cpu_write = 1 +aspect = 2 +filtering = 2 +depthmode = 1 +fog = 0 + +[STAR SOLDIER] +force_microcheck = 1 +filtering = 1 +depthmode = 1 +swapmode = 0 + +[STAR TWINS] +read_back_to_screen = 1 +decrease_fillrect_edge = 1 +alt_tex_size = 1 +depthmode = 1 +swapmode = 2 +fb_smart = 1 +fb_hires = 1 + +[STAR WARS EP1 RACER] +swapmode = 2 + +[SUPERROBOTSPIRITS] +aspect = 2 + +;Super Robot Taisen 64 (J) +[½°Êß°ÛÎÞ¯ÄÀ²¾Ý64] +fast_crc = 0 +use_sts1_only = 1 +fb_smart = 1 +fb_hires = 1 + +[Supercross] +depthmode = 1 +buff_clear = 0 + +[SUPER MARIO 64] +depth_bias = 32 +lodmode = 1 +filtering = 1 +depthmode = 1 + +[SUPERMARIO64] +depth_bias = 32 +lodmode = 1 +filtering = 1 +depthmode = 1 + +[SUPERMAN] +detect_cpu_write = 1 + +;Susume! Taisen Puzzle Dama Toukon! Marumata Chou (J) +[½½Ò!À²¾ÝÊß½ÞÙÀÞÏ] +force_microcheck = 1 +depthmode = 1 +fog = 0 +swapmode = 0 + +;Tamagotchi World 64 (J) +[ÐÝÅÃÞÀϺޯÁÜ°ÙÄÞ] +use_sts1_only = 1 +depthmode = 0 +fog = 0 + +[Taz Express] +filtering = 1 +depthmode = 0 +buff_clear = 0 + +[TELEFOOT SOCCER 2000] +buff_clear = 0 + +[TETRISPHERE] +alt_tex_size = 1 +use_sts1_only = 1 +increase_texrect_edge = 1 +depthmode = 1 +fb_smart = 1 +fb_hires = 1 +fb_crc_mode = 2 + +[TG RALLY 2] +filtering = 1 +depthmode = 1 +buff_clear = 0 +swapmode = 2 + +[THE LEGEND OF ZELDA] +depth_bias = 60 +filtering = 1 +depthmode = 1 +fb_smart = 1 +fb_hires = 1 +fb_clear = 1 + +[THE MASK OF MUJURA] +wrap_big_tex = 1 +filtering = 1 +depthmode = 1 +fb_smart = 1 +fb_hires = 1 +fb_clear = 1 +fb_crc_mode = 0 + +[THPS2] +filtering = 1 +depthmode = 0 + +[THPS3] +filtering = 1 +depthmode = 0 + +[Tigger's Honey Hunt] +zmode_compare_less = 1 +depthmode = 0 +buff_clear = 0 + +[TOM AND JERRY] +depth_bias = 2 +filtering = 1 +depthmode = 0 + +[Tonic Trouble] +depthmode = 0 +detect_cpu_write = 1 + +[TONY HAWK PRO SKATER] +filtering = 1 +depthmode = 0 + +[TONY HAWK SKATEBOARD] +filtering = 1 +depthmode = 0 + +[Top Gear Hyper Bike] +fb_info_disable = 1 +swapmode = 2 +depthmode = 0 +fb_smart = 1 +fb_hires = 1 +fb_clear = 1 + +[Top Gear Overdrive] +fb_info_disable = 1 +depthmode = 0 +buff_clear = 0 + +[TOP GEAR RALLY] +depth_bias = 64 +fillcolor_fix = 1 +depthmode = 0 + +[TOP GEAR RALLY 2] +filtering = 1 +depthmode = 1 +buff_clear = 0 +swapmode = 2 + +[TRIPLE PLAY 2000] +wrap_big_tex = 1 +depthmode = 0 +fb_smart = 1 +fb_hires = 1 + +[TROUBLE MAKERS] +mischief_tex_hack = 0 +depthmode = 1 +fog = 0 + +[TSUMI TO BATSU] +filtering = 1 +depthmode = 1 +fb_smart = 1 +fb_hires = 1 +fb_clear = 1 + +[TSUWAMONO64] +force_microcheck = 1 +depthmode = 0 + +[TWINE] +filtering = 1 +depthmode = 0 + +[TWISTED EDGE] +depthmode = 1 +fb_smart = 1 +fb_hires = 1 +fb_clear = 1 + +[Ultraman Battle JAPA] +depthmode = 0 + +[Virtual Pool 64] +depthmode = 1 +buff_clear = 0 + +[V-RALLY] +fix_tex_coord = 3 +filtering = 1 +depthmode = 0 +buff_clear = 0 +swapmode = 0 + +[Waialae Country Club] +wrap_big_tex = 1 +depthmode = 0 +fb_smart = 1 +fb_hires = 1 + +[WAVE RACE 64] +pal230 = 1 + +[WILD CHOPPERS] +filtering = 1 +depthmode = 0 + +[Wipeout 64] +filtering = 1 +depthmode = 0 +swapmode = 2 + +[WONDER PROJECT J2] +depthmode = 0 +buff_clear = 0 +swapmode = 0 + +[World Cup 98] +depthmode = 0 +swapmode = 0 +fb_smart = 1 +fb_hires = 1 + +[WRESTLEMANIA 2000] +depthmode = 0 + +[YAKOUTYUU2] +depthmode = 0 + +[YOSHI STORY] +fix_tex_coord = 32 +filtering = 1 +depthmode = 1 +fog = 0 + +[ZELDA MAJORA'S MASK] +wrap_big_tex = 1 +filtering = 1 +depthmode = 1 +fb_smart = 1 +fb_hires = 1 +fb_clear = 1 +fb_crc_mode = 0 + +[ZELDA MASTER QUEST] +depth_bias = 60 +filtering = 1 +depthmode = 1 +fb_smart = 1 +fb_hires = 1 +fb_clear = 1 + +;End Of Original File diff --git a/Source/Glide64/cursor.h b/Source/Glide64/cursor.h new file mode 100644 index 000000000..1fa053b42 --- /dev/null +++ b/Source/Glide64/cursor.h @@ -0,0 +1,2049 @@ +wxUint8 cursor[] = {127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +128, +0, +128, +0, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +128, +0, +160, +31, +128, +0, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +128, +0, +160, +31, +160, +31, +128, +0, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +128, +0, +130, +31, +160, +31, +160, +31, +128, +0, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +128, +0, +130, +31, +160, +31, +160, +31, +160, +31, +128, +0, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +128, +0, +130, +31, +130, +31, +160, +31, +160, +31, +160, +31, +128, +0, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +128, +0, +130, +31, +130, +31, +160, +31, +160, +31, +160, +31, +160, +31, +128, +0, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +128, +0, +130, +31, +130, +31, +130, +31, +160, +31, +160, +31, +160, +31, +160, +31, +128, +0, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +128, +0, +130, +31, +130, +31, +130, +31, +160, +31, +160, +31, +160, +31, +160, +31, +160, +31, +128, +0, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +128, +0, +130, +31, +130, +31, +130, +31, +130, +31, +160, +31, +128, +0, +128, +0, +128, +0, +128, +0, +128, +0, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +128, +0, +130, +31, +130, +31, +128, +0, +130, +31, +160, +31, +128, +0, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +128, +0, +130, +31, +128, +0, +127, +255, +128, +0, +130, +31, +160, +31, +128, +0, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +128, +0, +128, +0, +127, +255, +127, +255, +128, +0, +130, +31, +160, +31, +128, +0, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +128, +0, +127, +255, +127, +255, +127, +255, +127, +255, +128, +0, +130, +31, +160, +31, +128, +0, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +128, +0, +130, +31, +160, +31, +128, +0, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +128, +0, +130, +31, +160, +31, +128, +0, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +128, +0, +130, +31, +160, +31, +128, +0, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +128, +0, +128, +0, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +127, +255, +0}; diff --git a/Source/Glide64/font.h b/Source/Glide64/font.h new file mode 100644 index 000000000..46df5f538 --- /dev/null +++ b/Source/Glide64/font.h @@ -0,0 +1,2049 @@ +wxUint8 font[] = {255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +231, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +231, +143, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +231, +153, +201, +195, +39, +199, +231, +243, +207, +255, +255, +255, +255, +255, +249, +225, +243, +195, +195, +207, +129, +227, +129, +195, +195, +255, +255, +249, +255, +159, +195, +255, +195, +153, +201, +153, +37, +147, +231, +231, +231, +255, +255, +255, +255, +255, +249, +204, +227, +153, +153, +207, +159, +231, +249, +153, +153, +255, +255, +243, +255, +207, +153, +255, +195, +153, +128, +159, +137, +147, +231, +231, +231, +201, +231, +255, +255, +255, +243, +200, +131, +153, +153, +201, +159, +207, +243, +153, +153, +227, +227, +231, +255, +231, +153, +255, +195, +255, +201, +207, +243, +199, +255, +207, +243, +227, +231, +255, +255, +255, +243, +200, +243, +249, +249, +201, +159, +131, +243, +137, +153, +227, +227, +207, +129, +243, +243, +255, +231, +255, +201, +231, +231, +159, +255, +207, +243, +128, +129, +255, +129, +255, +231, +204, +243, +243, +227, +201, +131, +153, +231, +195, +153, +255, +255, +159, +255, +249, +231, +255, +231, +255, +201, +243, +207, +144, +255, +207, +243, +227, +231, +255, +255, +255, +231, +196, +243, +231, +249, +153, +249, +153, +231, +145, +193, +255, +255, +207, +129, +243, +231, +255, +255, +255, +128, +249, +145, +153, +255, +207, +243, +201, +231, +255, +255, +255, +207, +196, +243, +207, +153, +128, +249, +153, +207, +153, +243, +255, +255, +231, +255, +231, +255, +255, +231, +255, +201, +153, +164, +153, +255, +207, +243, +255, +255, +227, +255, +227, +207, +204, +243, +159, +153, +249, +243, +153, +207, +153, +231, +227, +227, +243, +255, +207, +231, +255, +231, +255, +201, +195, +228, +196, +255, +231, +231, +255, +255, +227, +255, +227, +159, +225, +243, +129, +195, +249, +135, +195, +207, +195, +199, +227, +227, +249, +255, +159, +231, +255, +255, +255, +255, +231, +241, +255, +255, +231, +231, +255, +255, +243, +255, +255, +159, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +243, +255, +255, +255, +255, +255, +255, +255, +255, +231, +255, +255, +255, +243, +207, +255, +255, +231, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +231, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +231, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +195, +255, +129, +231, +131, +195, +135, +129, +129, +195, +153, +195, +249, +153, +159, +156, +156, +195, +131, +195, +131, +195, +129, +153, +153, +156, +153, +153, +129, +195, +159, +195, +153, +255, +60, +195, +153, +153, +147, +159, +159, +153, +153, +231, +249, +153, +159, +156, +156, +153, +153, +153, +153, +153, +231, +153, +153, +156, +153, +153, +249, +207, +159, +243, +255, +255, +60, +153, +153, +153, +153, +159, +159, +153, +153, +231, +249, +147, +159, +136, +140, +153, +153, +153, +153, +159, +231, +153, +153, +156, +203, +153, +249, +207, +207, +243, +255, +255, +48, +153, +153, +159, +153, +159, +159, +159, +153, +231, +249, +147, +159, +148, +132, +153, +153, +153, +153, +207, +231, +153, +153, +148, +231, +153, +243, +207, +207, +243, +255, +255, +36, +153, +131, +159, +153, +131, +131, +159, +129, +231, +249, +135, +159, +148, +144, +153, +131, +153, +131, +231, +231, +153, +153, +148, +231, +195, +231, +207, +231, +243, +255, +255, +36, +129, +153, +159, +153, +159, +159, +145, +153, +231, +249, +147, +159, +148, +152, +153, +159, +153, +147, +243, +231, +153, +153, +148, +211, +231, +207, +207, +231, +243, +255, +255, +48, +153, +153, +153, +153, +159, +159, +153, +153, +231, +153, +147, +159, +156, +156, +153, +159, +153, +153, +249, +231, +153, +153, +201, +153, +231, +159, +207, +243, +243, +255, +255, +63, +153, +153, +153, +147, +159, +159, +153, +153, +231, +153, +153, +159, +156, +156, +153, +159, +153, +153, +153, +231, +153, +195, +201, +153, +231, +159, +207, +243, +243, +255, +255, +128, +153, +131, +195, +135, +129, +159, +193, +153, +195, +195, +153, +129, +156, +156, +195, +159, +195, +153, +195, +231, +195, +231, +201, +153, +231, +129, +207, +249, +243, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +243, +255, +255, +255, +255, +255, +255, +255, +255, +255, +207, +249, +243, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +249, +255, +255, +255, +255, +255, +255, +255, +255, +255, +207, +255, +243, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +195, +255, +195, +255, +0, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +199, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +231, +255, +255, +255, +255, +255, +255, +255, +255, +231, +243, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +243, +255, +159, +255, +249, +255, +225, +255, +159, +231, +243, +159, +135, +255, +255, +255, +255, +255, +255, +255, +207, +255, +255, +255, +255, +255, +255, +243, +231, +207, +255, +255, +255, +255, +159, +255, +249, +255, +207, +255, +159, +255, +255, +159, +231, +255, +255, +255, +255, +255, +255, +255, +207, +255, +255, +255, +255, +255, +255, +231, +231, +231, +255, +255, +255, +195, +131, +195, +193, +195, +207, +193, +131, +135, +195, +153, +231, +129, +131, +195, +131, +193, +153, +193, +129, +153, +153, +156, +153, +153, +129, +231, +231, +231, +255, +255, +255, +249, +153, +153, +153, +153, +207, +153, +153, +231, +243, +153, +231, +148, +153, +153, +153, +153, +145, +159, +207, +153, +153, +148, +153, +153, +249, +231, +231, +231, +255, +255, +255, +249, +153, +159, +153, +153, +129, +153, +153, +231, +243, +147, +231, +148, +153, +153, +153, +153, +143, +159, +207, +153, +153, +148, +195, +153, +243, +207, +231, +243, +255, +255, +255, +193, +153, +159, +153, +129, +207, +153, +153, +231, +243, +135, +231, +148, +153, +153, +153, +153, +159, +195, +207, +153, +153, +148, +231, +153, +231, +159, +231, +249, +255, +255, +255, +153, +153, +159, +153, +159, +207, +153, +153, +231, +243, +147, +231, +148, +153, +153, +153, +153, +159, +249, +207, +153, +153, +148, +195, +153, +207, +207, +231, +243, +255, +255, +255, +153, +153, +153, +153, +159, +207, +153, +153, +231, +243, +153, +231, +148, +153, +153, +153, +153, +159, +249, +207, +153, +195, +201, +153, +153, +159, +231, +231, +231, +255, +255, +255, +193, +131, +195, +193, +195, +207, +193, +153, +129, +243, +153, +129, +156, +153, +195, +131, +193, +159, +131, +225, +193, +231, +201, +153, +195, +129, +231, +231, +231, +255, +255, +255, +255, +255, +255, +255, +255, +255, +249, +255, +255, +243, +255, +255, +255, +255, +255, +159, +249, +255, +255, +255, +255, +255, +255, +255, +243, +255, +231, +231, +231, +255, +255, +255, +255, +255, +255, +255, +255, +255, +249, +255, +255, +243, +255, +255, +255, +255, +255, +159, +249, +255, +255, +255, +255, +255, +255, +255, +231, +255, +243, +231, +207, +255, +255, +255, +255, +255, +255, +255, +255, +255, +131, +255, +255, +135, +255, +255, +255, +255, +255, +159, +249, +255, +255, +255, +255, +255, +255, +255, +15, +255, +255, +231, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +0}; diff --git a/Source/Glide64/france.xpm b/Source/Glide64/france.xpm new file mode 100644 index 000000000..a54f5cea4 --- /dev/null +++ b/Source/Glide64/france.xpm @@ -0,0 +1,28 @@ +/* XPM */ +static const char *france_xpm[]={ +"30 20 5 1", +" c #0C429C", +"0 c #F4F6FC", +"1 c #FCFEFC", +"2 c #FCEAEC", +"3 c #FC0204", +" 01111111123333333333", +" 21111111123333333333", +" 01111111123333333333", +" 21111111123333333333", +" 01111111123333333333", +" 21111111123333333333", +" 01111111123333333333", +" 21111111123333333333", +" 01111111123333333333", +" 21111111123333333333", +" 01111111123333333333", +" 21111111123333333333", +" 01111111123333333333", +" 01111111123333333333", +" 01111111123333333333", +" 21111111123333333333", +" 01111111123333333333", +" 01111111123333333333", +" 01111111123333333333", +" 01111111123333333333"}; diff --git a/Source/Glide64/gpl.txt b/Source/Glide64/gpl.txt new file mode 100644 index 000000000..74a0f2ce8 --- /dev/null +++ b/Source/Glide64/gpl.txt @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so int as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/Source/Glide64/inc/3dfx.h b/Source/Glide64/inc/3dfx.h new file mode 100644 index 000000000..b2011bfee --- /dev/null +++ b/Source/Glide64/inc/3dfx.h @@ -0,0 +1,130 @@ +/* +** THIS SOFTWARE IS SUBJECT TO COPYRIGHT PROTECTION AND IS OFFERED ONLY +** PURSUANT TO THE 3DFX GLIDE GENERAL PUBLIC LICENSE. THERE IS NO RIGHT +** TO USE THE GLIDE TRADEMARK WITHOUT PRIOR WRITTEN PERMISSION OF 3DFX +** INTERACTIVE, INC. A COPY OF THIS LICENSE MAY BE OBTAINED FROM THE +** DISTRIBUTOR OR BY CONTACTING 3DFX INTERACTIVE INC(info@3dfx.com). +** THIS PROGRAM IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER +** EXPRESSED OR IMPLIED. SEE THE 3DFX GLIDE GENERAL PUBLIC LICENSE FOR A +** FULL TEXT OF THE NON-WARRANTY PROVISIONS. +** +** USE, DUPLICATION OR DISCLOSURE BY THE GOVERNMENT IS SUBJECT TO +** RESTRICTIONS AS SET FORTH IN SUBDIVISION (C)(1)(II) OF THE RIGHTS IN +** TECHNICAL DATA AND COMPUTER SOFTWARE CLAUSE AT DFARS 252.227-7013, +** AND/OR IN SIMILAR OR SUCCESSOR CLAUSES IN THE FAR, DOD OR NASA FAR +** SUPPLEMENT. UNPUBLISHED RIGHTS RESERVED UNDER THE COPYRIGHT LAWS OF +** THE UNITED STATES. +** +** COPYRIGHT 3DFX INTERACTIVE, INC. 1999, ALL RIGHTS RESERVED +** +** $Revision: 1.3.4.2 $ +** $Date: 2003/05/05 06:50:41 $ +*/ +#ifndef __3DFX_H__ +#define __3DFX_H__ + +/* +** basic data types +*/ +typedef unsigned char FxU8; +typedef signed char FxI8; +typedef unsigned short FxU16; +typedef signed short FxI16; +#if defined(__alpha__) || defined (__LP64__) +typedef signed int FxI32; +typedef unsigned int FxU32; +#else +typedef signed long FxI32; +typedef unsigned long FxU32; +#endif +typedef unsigned long AnyPtr; +typedef int FxBool; +typedef float FxFloat; +typedef double FxDouble; + +/* +** color types +*/ +typedef unsigned long FxColor_t; +typedef struct { float r, g, b, a; } FxColor4; + +/* +** fundamental types +*/ +#define FXTRUE 1 +#define FXFALSE 0 + +/* +** helper macros +*/ +#define FXUNUSED( a ) ((void)(a)) +#define FXBIT( i ) ( 1L << (i) ) + +/* +** export macros +*/ + +#if defined(__MSC__) || defined(_MSC_VER) +# if defined (MSVC16) +# define FX_ENTRY +# define FX_CALL +# else +# define FX_ENTRY extern +# define FX_CALL __stdcall +# endif +#elif defined(__WATCOMC__) +# define FX_ENTRY extern +# define FX_CALL __stdcall +#elif defined (__IBMC__) || defined (__IBMCPP__) + /* IBM Visual Age C/C++: */ +# define FX_ENTRY extern +# define FX_CALL __stdcall +#elif defined(__DJGPP__) +# define FX_ENTRY extern +# define FX_CALL +#elif defined(__MINGW32__) +# define FX_ENTRY extern +# define FX_CALL __stdcall +#elif defined(__unix__) +# define FX_ENTRY extern +# define FX_CALL +#elif defined(__MWERKS__) +# if macintosh +# define FX_ENTRY extern +# define FX_CALL +# else /* !macintosh */ +# error "Unknown MetroWerks target platform" +# endif /* !macintosh */ +#else +# warning define FX_ENTRY & FX_CALL for your compiler +# define FX_ENTRY extern +# define FX_CALL +#endif + +/* +** x86 compiler specific stuff +*/ +#if defined(__BORLANDC_) +# define REALMODE + +# define REGW( a, b ) ((a).x.b) +# define REGB( a, b ) ((a).h.b) +# define INT86( a, b, c ) int86(a,b,c) +# define INT86X( a, b, c, d ) int86x(a,b,c,d) + +# define RM_SEG( a ) FP_SEG( a ) +# define RM_OFF( a ) FP_OFF( a ) +#elif defined(__WATCOMC__) +# undef FP_SEG +# undef FP_OFF + +# define REGW( a, b ) ((a).w.b) +# define REGB( a, b ) ((a).h.b) +# define INT86( a, b, c ) int386(a,b,c) +# define INT86X( a, b, c, d ) int386x(a,b,c,d) + +# define RM_SEG( a ) ( ( ( ( FxU32 ) (a) ) & 0x000F0000 ) >> 4 ) +# define RM_OFF( a ) ( ( FxU16 ) (a) ) +#endif + +#endif /* !__3DFX_H__ */ diff --git a/Source/Glide64/inc/c32.mac b/Source/Glide64/inc/c32.mac new file mode 100644 index 000000000..f0c116ba3 --- /dev/null +++ b/Source/Glide64/inc/c32.mac @@ -0,0 +1,52 @@ +; NASM macro set to make interfacing to 32-bit programs easier -*- nasm -*- + + + +%imacro proc 1 ; begin a procedure definition + +%push proc + + global %1 + +%1: push ebp + + mov ebp,esp + +%assign %$arg 8 + +%define %$procname %1 + +%endmacro + + + +%imacro arg 0-1 4 ; used with the argument name as a label + +%00 equ %$arg + +%assign %$arg %1+%$arg + +%endmacro + + + +%imacro endproc 0 + +%ifnctx proc + +%error Mismatched `endproc'/`proc' + +%else + + leave + + ret + +__end_%$procname: ; useful for calculating function size + +%pop + +%endif + +%endmacro + diff --git a/Source/Glide64/inc/glide.h b/Source/Glide64/inc/glide.h new file mode 100644 index 000000000..d89f049ff --- /dev/null +++ b/Source/Glide64/inc/glide.h @@ -0,0 +1,946 @@ +/* +** THIS SOFTWARE IS SUBJECT TO COPYRIGHT PROTECTION AND IS OFFERED ONLY +** PURSUANT TO THE 3DFX GLIDE GENERAL PUBLIC LICENSE. THERE IS NO RIGHT +** TO USE THE GLIDE TRADEMARK WITHOUT PRIOR WRITTEN PERMISSION OF 3DFX +** INTERACTIVE, INC. A COPY OF THIS LICENSE MAY BE OBTAINED FROM THE +** DISTRIBUTOR OR BY CONTACTING 3DFX INTERACTIVE INC(info@3dfx.com). +** THIS PROGRAM IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER +** EXPRESSED OR IMPLIED. SEE THE 3DFX GLIDE GENERAL PUBLIC LICENSE FOR A +** FULL TEXT OF THE NON-WARRANTY PROVISIONS. +** +** USE, DUPLICATION OR DISCLOSURE BY THE GOVERNMENT IS SUBJECT TO +** RESTRICTIONS AS SET FORTH IN SUBDIVISION (C)(1)(II) OF THE RIGHTS IN +** TECHNICAL DATA AND COMPUTER SOFTWARE CLAUSE AT DFARS 252.227-7013, +** AND/OR IN SIMILAR OR SUCCESSOR CLAUSES IN THE FAR, DOD OR NASA FAR +** SUPPLEMENT. UNPUBLISHED RIGHTS RESERVED UNDER THE COPYRIGHT LAWS OF +** THE UNITED STATES. +** +** COPYRIGHT 3DFX INTERACTIVE, INC. 1999, ALL RIGHTS RESERVED +*/ + +/* +** GLIDE.H +** +** The following #defines are relevant when using Glide: +** +** One of the following "platform constants" must be defined during +** compilation: +** +** __DOS__ Defined for 32-bit DOS applications +** __WIN32__ Defined for 32-bit Windows applications +** __sparc__ Defined for Sun Solaris/SunOS +** __linux__ Defined for Linux applications +** __FreeBSD__ Defined for FreeBSD applications +** __NetBSD__ Defined for NetBSD applications +** __OpenBSD__ Defined for OpenBSD applications +** __IRIX__ Defined for SGI Irix applications +** +*/ +#ifndef __GLIDE_H__ +#define __GLIDE_H__ + +#include <3dfx.h> +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* +** ----------------------------------------------------------------------- +** TYPE DEFINITIONS +** ----------------------------------------------------------------------- +*/ +typedef FxU32 GrColor_t; +typedef FxU8 GrAlpha_t; +typedef FxU32 GrMipMapId_t; +typedef FxU32 GrStipplePattern_t; +typedef FxU8 GrFog_t; +typedef FxU32 GrContext_t; +typedef int (FX_CALL *GrProc)(); + +/* +** ----------------------------------------------------------------------- +** CONSTANTS AND TYPES +** ----------------------------------------------------------------------- +*/ +#define GR_NULL_MIPMAP_HANDLE ((GrMipMapId_t) -1) + +#define GR_MIPMAPLEVELMASK_EVEN FXBIT(0) +#define GR_MIPMAPLEVELMASK_ODD FXBIT(1) +#define GR_MIPMAPLEVELMASK_BOTH (GR_MIPMAPLEVELMASK_EVEN | GR_MIPMAPLEVELMASK_ODD ) + +#define GR_LODBIAS_BILINEAR 0.5 +#define GR_LODBIAS_TRILINEAR 0.0 + +typedef FxI32 GrChipID_t; +#define GR_TMU0 0x0 +#define GR_TMU1 0x1 +#define GR_TMU2 0x2 + +#define GR_FBI 0x0 + +typedef FxI32 GrCombineFunction_t; +#define GR_COMBINE_FUNCTION_ZERO 0x0 +#define GR_COMBINE_FUNCTION_NONE GR_COMBINE_FUNCTION_ZERO +#define GR_COMBINE_FUNCTION_LOCAL 0x1 +#define GR_COMBINE_FUNCTION_LOCAL_ALPHA 0x2 +#define GR_COMBINE_FUNCTION_SCALE_OTHER 0x3 +#define GR_COMBINE_FUNCTION_BLEND_OTHER GR_COMBINE_FUNCTION_SCALE_OTHER +#define GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL 0x4 +#define GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL_ALPHA 0x5 +#define GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL 0x6 +#define GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL 0x7 +#define GR_COMBINE_FUNCTION_BLEND GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL +#define GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL_ALPHA 0x8 +#define GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL 0x9 +#define GR_COMBINE_FUNCTION_BLEND_LOCAL GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL +#define GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL_ALPHA 0x10 + +typedef FxI32 GrCombineFactor_t; +#define GR_COMBINE_FACTOR_ZERO 0x0 +#define GR_COMBINE_FACTOR_NONE GR_COMBINE_FACTOR_ZERO +#define GR_COMBINE_FACTOR_LOCAL 0x1 +#define GR_COMBINE_FACTOR_OTHER_ALPHA 0x2 +#define GR_COMBINE_FACTOR_LOCAL_ALPHA 0x3 +#define GR_COMBINE_FACTOR_TEXTURE_ALPHA 0x4 +#define GR_COMBINE_FACTOR_TEXTURE_RGB 0x5 +#define GR_COMBINE_FACTOR_DETAIL_FACTOR GR_COMBINE_FACTOR_TEXTURE_ALPHA +#define GR_COMBINE_FACTOR_LOD_FRACTION 0x5 +#define GR_COMBINE_FACTOR_ONE 0x8 +#define GR_COMBINE_FACTOR_ONE_MINUS_LOCAL 0x9 +#define GR_COMBINE_FACTOR_ONE_MINUS_OTHER_ALPHA 0xa +#define GR_COMBINE_FACTOR_ONE_MINUS_LOCAL_ALPHA 0xb +#define GR_COMBINE_FACTOR_ONE_MINUS_TEXTURE_ALPHA 0xc +#define GR_COMBINE_FACTOR_ONE_MINUS_DETAIL_FACTOR GR_COMBINE_FACTOR_ONE_MINUS_TEXTURE_ALPHA +#define GR_COMBINE_FACTOR_ONE_MINUS_LOD_FRACTION 0xd + + +typedef FxI32 GrCombineLocal_t; +#define GR_COMBINE_LOCAL_ITERATED 0x0 +#define GR_COMBINE_LOCAL_CONSTANT 0x1 +#define GR_COMBINE_LOCAL_NONE GR_COMBINE_LOCAL_CONSTANT +#define GR_COMBINE_LOCAL_DEPTH 0x2 + +typedef FxI32 GrCombineOther_t; +#define GR_COMBINE_OTHER_ITERATED 0x0 +#define GR_COMBINE_OTHER_TEXTURE 0x1 +#define GR_COMBINE_OTHER_CONSTANT 0x2 +#define GR_COMBINE_OTHER_NONE GR_COMBINE_OTHER_CONSTANT + + +typedef FxI32 GrAlphaSource_t; +#define GR_ALPHASOURCE_CC_ALPHA 0x0 +#define GR_ALPHASOURCE_ITERATED_ALPHA 0x1 +#define GR_ALPHASOURCE_TEXTURE_ALPHA 0x2 +#define GR_ALPHASOURCE_TEXTURE_ALPHA_TIMES_ITERATED_ALPHA 0x3 + + +typedef FxI32 GrColorCombineFnc_t; +#define GR_COLORCOMBINE_ZERO 0x0 +#define GR_COLORCOMBINE_CCRGB 0x1 +#define GR_COLORCOMBINE_ITRGB 0x2 +#define GR_COLORCOMBINE_ITRGB_DELTA0 0x3 +#define GR_COLORCOMBINE_DECAL_TEXTURE 0x4 +#define GR_COLORCOMBINE_TEXTURE_TIMES_CCRGB 0x5 +#define GR_COLORCOMBINE_TEXTURE_TIMES_ITRGB 0x6 +#define GR_COLORCOMBINE_TEXTURE_TIMES_ITRGB_DELTA0 0x7 +#define GR_COLORCOMBINE_TEXTURE_TIMES_ITRGB_ADD_ALPHA 0x8 +#define GR_COLORCOMBINE_TEXTURE_TIMES_ALPHA 0x9 +#define GR_COLORCOMBINE_TEXTURE_TIMES_ALPHA_ADD_ITRGB 0xa +#define GR_COLORCOMBINE_TEXTURE_ADD_ITRGB 0xb +#define GR_COLORCOMBINE_TEXTURE_SUB_ITRGB 0xc +#define GR_COLORCOMBINE_CCRGB_BLEND_ITRGB_ON_TEXALPHA 0xd +#define GR_COLORCOMBINE_DIFF_SPEC_A 0xe +#define GR_COLORCOMBINE_DIFF_SPEC_B 0xf +#define GR_COLORCOMBINE_ONE 0x10 + +typedef FxI32 GrAlphaBlendFnc_t; +#define GR_BLEND_ZERO 0x0 +#define GR_BLEND_SRC_ALPHA 0x1 +#define GR_BLEND_SRC_COLOR 0x2 +#define GR_BLEND_DST_COLOR GR_BLEND_SRC_COLOR +#define GR_BLEND_DST_ALPHA 0x3 +#define GR_BLEND_ONE 0x4 +#define GR_BLEND_ONE_MINUS_SRC_ALPHA 0x5 +#define GR_BLEND_ONE_MINUS_SRC_COLOR 0x6 +#define GR_BLEND_ONE_MINUS_DST_COLOR GR_BLEND_ONE_MINUS_SRC_COLOR +#define GR_BLEND_ONE_MINUS_DST_ALPHA 0x7 +#define GR_BLEND_RESERVED_8 0x8 +#define GR_BLEND_RESERVED_9 0x9 +#define GR_BLEND_RESERVED_A 0xa +#define GR_BLEND_RESERVED_B 0xb +#define GR_BLEND_RESERVED_C 0xc +#define GR_BLEND_RESERVED_D 0xd +#define GR_BLEND_RESERVED_E 0xe +#define GR_BLEND_ALPHA_SATURATE 0xf +#define GR_BLEND_PREFOG_COLOR GR_BLEND_ALPHA_SATURATE + +typedef FxI32 GrAspectRatio_t; +#define GR_ASPECT_LOG2_8x1 3 /* 8W x 1H */ +#define GR_ASPECT_LOG2_4x1 2 /* 4W x 1H */ +#define GR_ASPECT_LOG2_2x1 1 /* 2W x 1H */ +#define GR_ASPECT_LOG2_1x1 0 /* 1W x 1H */ +#define GR_ASPECT_LOG2_1x2 -1 /* 1W x 2H */ +#define GR_ASPECT_LOG2_1x4 -2 /* 1W x 4H */ +#define GR_ASPECT_LOG2_1x8 -3 /* 1W x 8H */ + +typedef FxI32 GrBuffer_t; +#define GR_BUFFER_FRONTBUFFER 0x0 +#define GR_BUFFER_BACKBUFFER 0x1 +#define GR_BUFFER_AUXBUFFER 0x2 +#define GR_BUFFER_DEPTHBUFFER 0x3 +#define GR_BUFFER_ALPHABUFFER 0x4 +#define GR_BUFFER_TRIPLEBUFFER 0x5 + +typedef FxI32 GrChromakeyMode_t; +#define GR_CHROMAKEY_DISABLE 0x0 +#define GR_CHROMAKEY_ENABLE 0x1 + +typedef FxI32 GrChromaRangeMode_t; +#define GR_CHROMARANGE_RGB_ALL_EXT 0x0 + +#define GR_CHROMARANGE_DISABLE_EXT 0x00 +#define GR_CHROMARANGE_ENABLE_EXT 0x01 + +typedef FxI32 GrTexChromakeyMode_t; +#define GR_TEXCHROMA_DISABLE_EXT 0x0 +#define GR_TEXCHROMA_ENABLE_EXT 0x1 + +#define GR_TEXCHROMARANGE_RGB_ALL_EXT 0x0 + +typedef FxI32 GrCmpFnc_t; +#define GR_CMP_NEVER 0x0 +#define GR_CMP_LESS 0x1 +#define GR_CMP_EQUAL 0x2 +#define GR_CMP_LEQUAL 0x3 +#define GR_CMP_GREATER 0x4 +#define GR_CMP_NOTEQUAL 0x5 +#define GR_CMP_GEQUAL 0x6 +#define GR_CMP_ALWAYS 0x7 + +typedef FxI32 GrColorFormat_t; +#define GR_COLORFORMAT_ARGB 0x0 +#define GR_COLORFORMAT_ABGR 0x1 + +#define GR_COLORFORMAT_RGBA 0x2 +#define GR_COLORFORMAT_BGRA 0x3 + +typedef FxI32 GrCullMode_t; +#define GR_CULL_DISABLE 0x0 +#define GR_CULL_NEGATIVE 0x1 +#define GR_CULL_POSITIVE 0x2 + +typedef FxI32 GrDepthBufferMode_t; +#define GR_DEPTHBUFFER_DISABLE 0x0 +#define GR_DEPTHBUFFER_ZBUFFER 0x1 +#define GR_DEPTHBUFFER_WBUFFER 0x2 +#define GR_DEPTHBUFFER_ZBUFFER_COMPARE_TO_BIAS 0x3 +#define GR_DEPTHBUFFER_WBUFFER_COMPARE_TO_BIAS 0x4 + +typedef FxI32 GrDitherMode_t; +#define GR_DITHER_DISABLE 0x0 +#define GR_DITHER_2x2 0x1 +#define GR_DITHER_4x4 0x2 + +typedef FxI32 GrStippleMode_t; +#define GR_STIPPLE_DISABLE 0x0 +#define GR_STIPPLE_PATTERN 0x1 +#define GR_STIPPLE_ROTATE 0x2 + +typedef FxI32 GrFogMode_t; +#define GR_FOG_DISABLE 0x0 +#define GR_FOG_WITH_TABLE_ON_FOGCOORD_EXT 0x1 +#define GR_FOG_WITH_TABLE_ON_Q 0x2 +#define GR_FOG_WITH_TABLE_ON_W GR_FOG_WITH_TABLE_ON_Q +#define GR_FOG_WITH_ITERATED_Z 0x3 +#define GR_FOG_WITH_ITERATED_ALPHA_EXT 0x4 +#define GR_FOG_MULT2 0x100 +#define GR_FOG_ADD2 0x200 + +typedef FxU32 GrLock_t; +#define GR_LFB_READ_ONLY 0x00 +#define GR_LFB_WRITE_ONLY 0x01 +#define GR_LFB_IDLE 0x00 +#define GR_LFB_NOIDLE 0x10 + +#define GR_LFB_WRITE_ONLY_EXPLICIT_EXT 0x02 /* explicitly not allow reading from the lfb pointer */ + +typedef FxI32 GrLfbBypassMode_t; +#define GR_LFBBYPASS_DISABLE 0x0 +#define GR_LFBBYPASS_ENABLE 0x1 + +typedef FxI32 GrLfbWriteMode_t; +#define GR_LFBWRITEMODE_565 0x0 /* RGB:RGB */ +#define GR_LFBWRITEMODE_555 0x1 /* RGB:RGB */ +#define GR_LFBWRITEMODE_1555 0x2 /* ARGB:ARGB */ +#define GR_LFBWRITEMODE_RESERVED1 0x3 +#define GR_LFBWRITEMODE_888 0x4 /* RGB */ +#define GR_LFBWRITEMODE_8888 0x5 /* ARGB */ +#define GR_LFBWRITEMODE_RESERVED2 0x6 +#define GR_LFBWRITEMODE_RESERVED3 0x7 +#define GR_LFBWRITEMODE_RESERVED4 0x8 +#define GR_LFBWRITEMODE_RESERVED5 0x9 +#define GR_LFBWRITEMODE_RESERVED6 0xa +#define GR_LFBWRITEMODE_RESERVED7 0xb +#define GR_LFBWRITEMODE_565_DEPTH 0xc /* RGB:DEPTH */ +#define GR_LFBWRITEMODE_555_DEPTH 0xd /* RGB:DEPTH */ +#define GR_LFBWRITEMODE_1555_DEPTH 0xe /* ARGB:DEPTH */ +#define GR_LFBWRITEMODE_ZA16 0xf /* DEPTH:DEPTH */ +#define GR_LFBWRITEMODE_ANY 0xFF + + +typedef FxI32 GrOriginLocation_t; +#define GR_ORIGIN_UPPER_LEFT 0x0 +#define GR_ORIGIN_LOWER_LEFT 0x1 +#define GR_ORIGIN_ANY 0xFF + +typedef struct { + int size; + void *lfbPtr; + FxU32 strideInBytes; + GrLfbWriteMode_t writeMode; + GrOriginLocation_t origin; +} GrLfbInfo_t; + +typedef FxI32 GrLOD_t; +#define GR_LOD_LOG2_256 0x8 +#define GR_LOD_LOG2_128 0x7 +#define GR_LOD_LOG2_64 0x6 +#define GR_LOD_LOG2_32 0x5 +#define GR_LOD_LOG2_16 0x4 +#define GR_LOD_LOG2_8 0x3 +#define GR_LOD_LOG2_4 0x2 +#define GR_LOD_LOG2_2 0x1 +#define GR_LOD_LOG2_1 0x0 + +typedef FxI32 GrMipMapMode_t; +#define GR_MIPMAP_DISABLE 0x0 /* no mip mapping */ +#define GR_MIPMAP_NEAREST 0x1 /* use nearest mipmap */ +#define GR_MIPMAP_NEAREST_DITHER 0x2 /* GR_MIPMAP_NEAREST + LOD dith */ + +typedef FxI32 GrSmoothingMode_t; +#define GR_SMOOTHING_DISABLE 0x0 +#define GR_SMOOTHING_ENABLE 0x1 + +typedef FxI32 GrTextureClampMode_t; +#define GR_TEXTURECLAMP_WRAP 0x0 +#define GR_TEXTURECLAMP_CLAMP 0x1 +#define GR_TEXTURECLAMP_MIRROR_EXT 0x2 + +typedef FxI32 GrTextureCombineFnc_t; +#define GR_TEXTURECOMBINE_ZERO 0x0 /* texout = 0 */ +#define GR_TEXTURECOMBINE_DECAL 0x1 /* texout = texthis */ +#define GR_TEXTURECOMBINE_OTHER 0x2 /* this TMU in passthru mode */ +#define GR_TEXTURECOMBINE_ADD 0x3 /* tout = tthis + t(this+1) */ +#define GR_TEXTURECOMBINE_MULTIPLY 0x4 /* texout = tthis * t(this+1) */ +#define GR_TEXTURECOMBINE_SUBTRACT 0x5 /* Sutract from upstream TMU */ +#define GR_TEXTURECOMBINE_DETAIL 0x6 /* detail--detail on tthis */ +#define GR_TEXTURECOMBINE_DETAIL_OTHER 0x7 /* detail--detail on tthis+1 */ +#define GR_TEXTURECOMBINE_TRILINEAR_ODD 0x8 /* trilinear--odd levels tthis*/ +#define GR_TEXTURECOMBINE_TRILINEAR_EVEN 0x9 /*trilinear--even levels tthis*/ +#define GR_TEXTURECOMBINE_ONE 0xa /* texout = 0xFFFFFFFF */ + +typedef FxI32 GrTextureFilterMode_t; +#define GR_TEXTUREFILTER_POINT_SAMPLED 0x0 +#define GR_TEXTUREFILTER_BILINEAR 0x1 + +typedef FxI32 GrTextureFormat_t; +/* KoolSmoky - */ +#define GR_TEXFMT_8BIT 0x0 +#define GR_TEXFMT_RGB_332 GR_TEXFMT_8BIT +#define GR_TEXFMT_YIQ_422 0x1 +#define GR_TEXFMT_ALPHA_8 0x2 /* (0..0xFF) alpha */ +#define GR_TEXFMT_INTENSITY_8 0x3 /* (0..0xFF) intensity */ +#define GR_TEXFMT_ALPHA_INTENSITY_44 0x4 +#define GR_TEXFMT_P_8 0x5 /* 8-bit palette */ +#define GR_TEXFMT_RSVD0 0x6 /* GR_TEXFMT_P_8_RGBA */ +#define GR_TEXFMT_P_8_6666 GR_TEXFMT_RSVD0 +#define GR_TEXFMT_P_8_6666_EXT GR_TEXFMT_RSVD0 +#define GR_TEXFMT_RSVD1 0x7 +#define GR_TEXFMT_16BIT 0x8 +#define GR_TEXFMT_ARGB_8332 GR_TEXFMT_16BIT +#define GR_TEXFMT_AYIQ_8422 0x9 +#define GR_TEXFMT_RGB_565 0xa +#define GR_TEXFMT_ARGB_1555 0xb +#define GR_TEXFMT_ARGB_4444 0xc +#define GR_TEXFMT_ALPHA_INTENSITY_88 0xd +#define GR_TEXFMT_AP_88 0xe /* 8-bit alpha 8-bit palette */ +#define GR_TEXFMT_RSVD2 0xf +#define GR_TEXFMT_RSVD4 GR_TEXFMT_RSVD2 + +typedef FxU32 GrTexTable_t; +#define GR_TEXTABLE_NCC0 0x0 +#define GR_TEXTABLE_NCC1 0x1 +#define GR_TEXTABLE_PALETTE 0x2 +#define GR_TEXTABLE_PALETTE_6666_EXT 0x3 + +typedef FxU32 GrNCCTable_t; +#define GR_NCCTABLE_NCC0 0x0 +#define GR_NCCTABLE_NCC1 0x1 + +typedef FxU32 GrTexBaseRange_t; +#define GR_TEXBASE_256 0x3 +#define GR_TEXBASE_128 0x2 +#define GR_TEXBASE_64 0x1 +#define GR_TEXBASE_32_TO_1 0x0 + + +typedef FxU32 GrEnableMode_t; +#define GR_MODE_DISABLE 0x0 +#define GR_MODE_ENABLE 0x1 + +#define GR_AA_ORDERED 0x01 +#define GR_ALLOW_MIPMAP_DITHER 0x02 +#define GR_PASSTHRU 0x03 +#define GR_SHAMELESS_PLUG 0x04 +#define GR_VIDEO_SMOOTHING 0x05 + +typedef FxU32 GrCoordinateSpaceMode_t; +#define GR_WINDOW_COORDS 0x00 +#define GR_CLIP_COORDS 0x01 + +/* Types of data in strips */ +#define GR_FLOAT 0 +#define GR_U8 1 + +/* Parameters for strips */ +#define GR_PARAM_XY 0x01 +#define GR_PARAM_Z 0x02 +#define GR_PARAM_W 0x03 +#define GR_PARAM_Q 0x04 +#define GR_PARAM_FOG_EXT 0x05 + +#define GR_PARAM_A 0x10 + +#define GR_PARAM_RGB 0x20 + +#define GR_PARAM_PARGB 0x30 + +#define GR_PARAM_ST0 0x40 +#define GR_PARAM_ST1 GR_PARAM_ST0+1 +#define GR_PARAM_ST2 GR_PARAM_ST0+2 + +#define GR_PARAM_Q0 0x50 +#define GR_PARAM_Q1 GR_PARAM_Q0+1 +#define GR_PARAM_Q2 GR_PARAM_Q0+2 + +#define GR_PARAM_DISABLE 0x00 +#define GR_PARAM_ENABLE 0x01 + +/* +** grDrawVertexArray/grDrawVertexArrayContiguous primitive type +*/ +#define GR_POINTS 0 +#define GR_LINE_STRIP 1 +#define GR_LINES 2 +#define GR_POLYGON 3 +#define GR_TRIANGLE_STRIP 4 +#define GR_TRIANGLE_FAN 5 +#define GR_TRIANGLES 6 +#define GR_TRIANGLE_STRIP_CONTINUE 7 +#define GR_TRIANGLE_FAN_CONTINUE 8 + +/* +** grGet/grReset types +*/ +#define GR_BITS_DEPTH 0x01 +#define GR_BITS_RGBA 0x02 +#define GR_FIFO_FULLNESS 0x03 +#define GR_FOG_TABLE_ENTRIES 0x04 +#define GR_GAMMA_TABLE_ENTRIES 0x05 +#define GR_GLIDE_STATE_SIZE 0x06 +#define GR_GLIDE_VERTEXLAYOUT_SIZE 0x07 +#define GR_IS_BUSY 0x08 +#define GR_LFB_PIXEL_PIPE 0x09 +#define GR_MAX_TEXTURE_SIZE 0x0a +#define GR_MAX_TEXTURE_ASPECT_RATIO 0x0b +#define GR_MEMORY_FB 0x0c +#define GR_MEMORY_TMU 0x0d +#define GR_MEMORY_UMA 0x0e +#define GR_NUM_BOARDS 0x0f +#define GR_NON_POWER_OF_TWO_TEXTURES 0x10 +#define GR_NUM_FB 0x11 +#define GR_NUM_SWAP_HISTORY_BUFFER 0x12 +#define GR_NUM_TMU 0x13 +#define GR_PENDING_BUFFERSWAPS 0x14 +#define GR_REVISION_FB 0x15 +#define GR_REVISION_TMU 0x16 +#define GR_STATS_LINES 0x17 /* grGet/grReset */ +#define GR_STATS_PIXELS_AFUNC_FAIL 0x18 +#define GR_STATS_PIXELS_CHROMA_FAIL 0x19 +#define GR_STATS_PIXELS_DEPTHFUNC_FAIL 0x1a +#define GR_STATS_PIXELS_IN 0x1b +#define GR_STATS_PIXELS_OUT 0x1c +#define GR_STATS_PIXELS 0x1d /* grReset */ +#define GR_STATS_POINTS 0x1e /* grGet/grReset */ +#define GR_STATS_TRIANGLES_IN 0x1f +#define GR_STATS_TRIANGLES_OUT 0x20 +#define GR_STATS_TRIANGLES 0x21 /* grReset */ +#define GR_SWAP_HISTORY 0x22 +#define GR_SUPPORTS_PASSTHRU 0x23 +#define GR_TEXTURE_ALIGN 0x24 +#define GR_VIDEO_POSITION 0x25 +#define GR_VIEWPORT 0x26 +#define GR_WDEPTH_MIN_MAX 0x27 +#define GR_ZDEPTH_MIN_MAX 0x28 +#define GR_VERTEX_PARAMETER 0x29 +#define GR_BITS_GAMMA 0x2a +#define GR_GET_RESERVED_1 0x1000 + +/* +** grGetString types +*/ +#define GR_EXTENSION 0xa0 +#define GR_HARDWARE 0xa1 +#define GR_RENDERER 0xa2 +#define GR_VENDOR 0xa3 +#define GR_VERSION 0xa4 + +/* +** ----------------------------------------------------------------------- +** STRUCTURES +** ----------------------------------------------------------------------- +*/ + +typedef struct { + GrLOD_t smallLodLog2; + GrLOD_t largeLodLog2; + GrAspectRatio_t aspectRatioLog2; + GrTextureFormat_t format; + void *data; +} GrTexInfo; + +typedef struct GrSstPerfStats_s { + FxU32 pixelsIn; /* # pixels processed (minus buffer clears) */ + FxU32 chromaFail; /* # pixels not drawn due to chroma key */ + FxU32 zFuncFail; /* # pixels not drawn due to Z comparison */ + FxU32 aFuncFail; /* # pixels not drawn due to alpha comparison */ + FxU32 pixelsOut; /* # pixels drawn (including buffer clears) */ +} GrSstPerfStats_t; + +typedef struct { + GrScreenResolution_t resolution; + GrScreenRefresh_t refresh; + int numColorBuffers; + int numAuxBuffers; +} GrResolution; + +typedef GrResolution GlideResolution; + +#define GR_QUERY_ANY ((FxU32)(~0)) + +typedef FxU32 GrLfbSrcFmt_t; +#define GR_LFB_SRC_FMT_565 0x00 +#define GR_LFB_SRC_FMT_555 0x01 +#define GR_LFB_SRC_FMT_1555 0x02 +#define GR_LFB_SRC_FMT_888 0x04 +#define GR_LFB_SRC_FMT_8888 0x05 +#define GR_LFB_SRC_FMT_565_DEPTH 0x0c +#define GR_LFB_SRC_FMT_555_DEPTH 0x0d +#define GR_LFB_SRC_FMT_1555_DEPTH 0x0e +#define GR_LFB_SRC_FMT_ZA16 0x0f +#define GR_LFB_SRC_FMT_RLE16 0x80 + +#ifdef H3D +#define GR_HINT_H3DENABLE 4 +#undef GR_HINTTYPE_MAX +#define GR_HINTTYPE_MAX 4 +#endif + +/* +** ----------------------------------------------------------------------- +** FUNCTION PROTOTYPES +** ----------------------------------------------------------------------- +*/ +#ifndef FX_GLIDE_NO_FUNC_PROTO +/* +** rendering functions +*/ +FX_ENTRY void FX_CALL +grDrawPoint( const void *pt ); + +FX_ENTRY void FX_CALL +grDrawLine( const void *v1, const void *v2 ); + +FX_ENTRY void FX_CALL +grDrawTriangle( const void *a, const void *b, const void *c ); + +FX_ENTRY void FX_CALL +grVertexLayout(FxU32 param, FxI32 offset, FxU32 mode); + +FX_ENTRY void FX_CALL +grDrawVertexArray(FxU32 mode, FxU32 Count, void *pointers); + +FX_ENTRY void FX_CALL +grDrawVertexArrayContiguous(FxU32 mode, FxU32 Count, void *pointers, FxU32 stride); + +/* +** Antialiasing Functions +*/ + +FX_ENTRY void FX_CALL +grAADrawTriangle( + const void *a, const void *b, const void *c, + FxBool ab_antialias, FxBool bc_antialias, FxBool ca_antialias + ); + +/* +** buffer management +*/ +FX_ENTRY void FX_CALL +grBufferClear( GrColor_t color, GrAlpha_t alpha, FxU32 depth ); + +FX_ENTRY void FX_CALL +grBufferSwap( FxU32 swap_interval ); + +FX_ENTRY void FX_CALL +grRenderBuffer( GrBuffer_t buffer ); + +/* +** error management +*/ +typedef void (*GrErrorCallbackFnc_t)( const char *string, FxBool fatal ); + +FX_ENTRY void FX_CALL +grErrorSetCallback( GrErrorCallbackFnc_t fnc ); + +/* +** SST routines +*/ +FX_ENTRY void FX_CALL +grFinish(void); + +FX_ENTRY void FX_CALL +grFlush(void); + +FX_ENTRY GrContext_t FX_CALL +grSstWinOpen( + FxU32 hWnd, + GrScreenResolution_t screen_resolution, + GrScreenRefresh_t refresh_rate, + GrColorFormat_t color_format, + GrOriginLocation_t origin_location, + int nColBuffers, + int nAuxBuffers); + +FX_ENTRY FxBool FX_CALL +grSstWinClose( GrContext_t context ); + +FX_ENTRY void FX_CALL +grSetNumPendingBuffers(FxI32 NumPendingBuffers); + +FX_ENTRY FxBool FX_CALL +grSelectContext( GrContext_t context ); + +FX_ENTRY void FX_CALL +grSstOrigin(GrOriginLocation_t origin); + +FX_ENTRY void FX_CALL +grSstSelect( int which_sst ); + +/* +** Glide configuration and special effect maintenance functions +*/ +FX_ENTRY void FX_CALL +grAlphaBlendFunction( + GrAlphaBlendFnc_t rgb_sf, GrAlphaBlendFnc_t rgb_df, + GrAlphaBlendFnc_t alpha_sf, GrAlphaBlendFnc_t alpha_df + ); + +FX_ENTRY void FX_CALL +grAlphaCombine( + GrCombineFunction_t function, GrCombineFactor_t factor, + GrCombineLocal_t local, GrCombineOther_t other, + FxBool invert + ); + +FX_ENTRY void FX_CALL +grAlphaControlsITRGBLighting( FxBool enable ); + +FX_ENTRY void FX_CALL +grAlphaTestFunction( GrCmpFnc_t function ); + +FX_ENTRY void FX_CALL +grAlphaTestReferenceValue( GrAlpha_t value ); + +FX_ENTRY void FX_CALL +grChromakeyMode( GrChromakeyMode_t mode ); + +FX_ENTRY void FX_CALL +grChromakeyValue( GrColor_t value ); + +FX_ENTRY void FX_CALL +grClipWindow( FxU32 minx, FxU32 miny, FxU32 maxx, FxU32 maxy ); + +FX_ENTRY void FX_CALL +grColorCombine( + GrCombineFunction_t function, GrCombineFactor_t factor, + GrCombineLocal_t local, GrCombineOther_t other, + FxBool invert ); + +FX_ENTRY void FX_CALL +grColorMask( FxBool rgb, FxBool a ); + +FX_ENTRY void FX_CALL +grCullMode( GrCullMode_t mode ); + +FX_ENTRY void FX_CALL +grConstantColorValue( GrColor_t value ); + +FX_ENTRY void FX_CALL +grDepthBiasLevel( FxI32 level ); + +FX_ENTRY void FX_CALL +grDepthBufferFunction( GrCmpFnc_t function ); + +FX_ENTRY void FX_CALL +grDepthBufferMode( GrDepthBufferMode_t mode ); + +FX_ENTRY void FX_CALL +grDepthMask( FxBool mask ); + +FX_ENTRY void FX_CALL +grDisableAllEffects( void ); + +FX_ENTRY void FX_CALL +grDitherMode( GrDitherMode_t mode ); + +FX_ENTRY void FX_CALL +grFogColorValue( GrColor_t fogcolor ); + +FX_ENTRY void FX_CALL +grFogMode( GrFogMode_t mode ); + +FX_ENTRY void FX_CALL +grFogTable( const GrFog_t ft[] ); + +FX_ENTRY void FX_CALL +grLoadGammaTable( FxU32 nentries, FxU32 *red, FxU32 *green, FxU32 *blue); + +FX_ENTRY void FX_CALL +grSplash(float x, float y, float width, float height, FxU32 frame); + +FX_ENTRY FxU32 FX_CALL +grGet( FxU32 pname, FxU32 plength, FxI32 *params ); + +FX_ENTRY const char * FX_CALL +grGetString( FxU32 pname ); + +FX_ENTRY FxI32 FX_CALL +grQueryResolutions( const GrResolution *resTemplate, GrResolution *output ); + +FX_ENTRY FxBool FX_CALL +grReset( FxU32 what ); + +FX_ENTRY GrProc FX_CALL +grGetProcAddress( char *procName ); + +FX_ENTRY void FX_CALL +grEnable( GrEnableMode_t mode ); + +FX_ENTRY void FX_CALL +grDisable( GrEnableMode_t mode ); + +FX_ENTRY void FX_CALL +grCoordinateSpace( GrCoordinateSpaceMode_t mode ); + +FX_ENTRY void FX_CALL +grDepthRange( FxFloat n, FxFloat f ); + +FX_ENTRY void FX_CALL +grStippleMode( GrStippleMode_t mode ); + +FX_ENTRY void FX_CALL +grStipplePattern( GrStipplePattern_t mode ); + +FX_ENTRY void FX_CALL +grViewport( FxI32 x, FxI32 y, FxI32 width, FxI32 height ); + +/* +** texture mapping control functions +*/ +FX_ENTRY FxU32 FX_CALL +grTexCalcMemRequired( + GrLOD_t lodmin, GrLOD_t lodmax, + GrAspectRatio_t aspect, GrTextureFormat_t fmt); + +FX_ENTRY FxU32 FX_CALL +grTexTextureMemRequired( FxU32 evenOdd, + GrTexInfo *info ); + +FX_ENTRY FxU32 FX_CALL +grTexMinAddress( GrChipID_t tmu ); + +FX_ENTRY FxU32 FX_CALL +grTexMaxAddress( GrChipID_t tmu ); + +FX_ENTRY void FX_CALL +grTexNCCTable( GrNCCTable_t table ); + +FX_ENTRY void FX_CALL +grTexSource( GrChipID_t tmu, + FxU32 startAddress, + FxU32 evenOdd, + GrTexInfo *info ); + +FX_ENTRY void FX_CALL +grTexClampMode( + GrChipID_t tmu, + GrTextureClampMode_t s_clampmode, + GrTextureClampMode_t t_clampmode + ); + +FX_ENTRY void FX_CALL +grTexCombine( + GrChipID_t tmu, + GrCombineFunction_t rgb_function, + GrCombineFactor_t rgb_factor, + GrCombineFunction_t alpha_function, + GrCombineFactor_t alpha_factor, + FxBool rgb_invert, + FxBool alpha_invert + ); + +FX_ENTRY void FX_CALL +grTexDetailControl( + GrChipID_t tmu, + int lod_bias, + FxU8 detail_scale, + float detail_max + ); + +FX_ENTRY void FX_CALL +grTexFilterMode( + GrChipID_t tmu, + GrTextureFilterMode_t minfilter_mode, + GrTextureFilterMode_t magfilter_mode + ); + + +FX_ENTRY void FX_CALL +grTexLodBiasValue(GrChipID_t tmu, float bias ); + +FX_ENTRY void FX_CALL +grTexDownloadMipMap( GrChipID_t tmu, + FxU32 startAddress, + FxU32 evenOdd, + GrTexInfo *info ); + +FX_ENTRY void FX_CALL +grTexDownloadMipMapLevel( GrChipID_t tmu, + FxU32 startAddress, + GrLOD_t thisLod, + GrLOD_t largeLod, + GrAspectRatio_t aspectRatio, + GrTextureFormat_t format, + FxU32 evenOdd, + void *data ); + +FX_ENTRY FxBool FX_CALL +grTexDownloadMipMapLevelPartial( GrChipID_t tmu, + FxU32 startAddress, + GrLOD_t thisLod, + GrLOD_t largeLod, + GrAspectRatio_t aspectRatio, + GrTextureFormat_t format, + FxU32 evenOdd, + void *data, + int start, + int end ); + +FX_ENTRY void FX_CALL +grTexDownloadTable( GrTexTable_t type, + void *data ); + +FX_ENTRY void FX_CALL +grTexDownloadTablePartial( GrTexTable_t type, + void *data, + int start, + int end ); + +FX_ENTRY void FX_CALL +grTexMipMapMode( GrChipID_t tmu, + GrMipMapMode_t mode, + FxBool lodBlend ); + +FX_ENTRY void FX_CALL +grTexMultibase( GrChipID_t tmu, + FxBool enable ); + +FX_ENTRY void FX_CALL +grTexMultibaseAddress( GrChipID_t tmu, + GrTexBaseRange_t range, + FxU32 startAddress, + FxU32 evenOdd, + GrTexInfo *info ); + +/* +** linear frame buffer functions +*/ + +FX_ENTRY FxBool FX_CALL +grLfbLock( GrLock_t type, GrBuffer_t buffer, GrLfbWriteMode_t writeMode, + GrOriginLocation_t origin, FxBool pixelPipeline, + GrLfbInfo_t *info ); + +FX_ENTRY FxBool FX_CALL +grLfbUnlock( GrLock_t type, GrBuffer_t buffer ); + +FX_ENTRY void FX_CALL +grLfbConstantAlpha( GrAlpha_t alpha ); + +FX_ENTRY void FX_CALL +grLfbConstantDepth( FxU32 depth ); + +FX_ENTRY void FX_CALL +grLfbWriteColorSwizzle(FxBool swizzleBytes, FxBool swapWords); + +FX_ENTRY void FX_CALL +grLfbWriteColorFormat(GrColorFormat_t colorFormat); + +FX_ENTRY FxBool FX_CALL +grLfbWriteRegion( GrBuffer_t dst_buffer, + FxU32 dst_x, FxU32 dst_y, + GrLfbSrcFmt_t src_format, + FxU32 src_width, FxU32 src_height, + FxBool pixelPipeline, + FxI32 src_stride, void *src_data ); + +FX_ENTRY FxBool FX_CALL +grLfbReadRegion( GrBuffer_t src_buffer, + FxU32 src_x, FxU32 src_y, + FxU32 src_width, FxU32 src_height, + FxU32 dst_stride, void *dst_data ); + +/* +** glide management functions +*/ +FX_ENTRY void FX_CALL +grGlideInit( void ); + +FX_ENTRY void FX_CALL +grGlideShutdown( void ); + +FX_ENTRY void FX_CALL +grGlideGetState( void *state ); + +FX_ENTRY void FX_CALL +grGlideSetState( const void *state ); + +FX_ENTRY void FX_CALL +grGlideGetVertexLayout( void *layout ); + +FX_ENTRY void FX_CALL +grGlideSetVertexLayout( const void *layout ); + +#endif /* FX_GLIDE_NO_FUNC_PROTO */ + +#ifdef __cplusplus +} +#endif + +#include + +#endif /* __GLIDE_H__ */ diff --git a/Source/Glide64/inc/glidesys.h b/Source/Glide64/inc/glidesys.h new file mode 100644 index 000000000..4925b9d95 --- /dev/null +++ b/Source/Glide64/inc/glidesys.h @@ -0,0 +1,160 @@ +/* +** THIS SOFTWARE IS SUBJECT TO COPYRIGHT PROTECTION AND IS OFFERED ONLY +** PURSUANT TO THE 3DFX GLIDE GENERAL PUBLIC LICENSE. THERE IS NO RIGHT +** TO USE THE GLIDE TRADEMARK WITHOUT PRIOR WRITTEN PERMISSION OF 3DFX +** INTERACTIVE, INC. A COPY OF THIS LICENSE MAY BE OBTAINED FROM THE +** DISTRIBUTOR OR BY CONTACTING 3DFX INTERACTIVE INC(info@3dfx.com). +** THIS PROGRAM IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER +** EXPRESSED OR IMPLIED. SEE THE 3DFX GLIDE GENERAL PUBLIC LICENSE FOR A +** FULL TEXT OF THE NON-WARRANTY PROVISIONS. +** +** USE, DUPLICATION OR DISCLOSURE BY THE GOVERNMENT IS SUBJECT TO +** RESTRICTIONS AS SET FORTH IN SUBDIVISION (C)(1)(II) OF THE RIGHTS IN +** TECHNICAL DATA AND COMPUTER SOFTWARE CLAUSE AT DFARS 252.227-7013, +** AND/OR IN SIMILAR OR SUCCESSOR CLAUSES IN THE FAR, DOD OR NASA FAR +** SUPPLEMENT. UNPUBLISHED RIGHTS RESERVED UNDER THE COPYRIGHT LAWS OF +** THE UNITED STATES. +** +** COPYRIGHT 3DFX INTERACTIVE, INC. 1999, ALL RIGHTS RESERVED +** +** $Header: /cvsroot/glide/glide3x/h5/glide3/src/glidesys.h,v 1.3.4.3 2003/07/24 03:51:08 anholt Exp $ +** $Log: +** 3 3dfx 1.0.1.0.1.0 10/11/00 Brent Forced check in to enforce +** branching. +** 2 3dfx 1.0.1.0 06/20/00 Joseph Kain Changes to support the +** Napalm Glide open source release. Changes include cleaned up offensive +** comments and new legal headers. +** 1 3dfx 1.0 09/11/99 StarTeam VTS Administrator +** $ +** +** 4 11/05/98 11:18a Russp +** Fix GLIDE_NUM_TMU error check (change "&&" to "||") +** +** 3 7/24/98 1:41p Hohn +** +** 2 6/15/98 10:50a Peter +** made csim compile time option + * + * 1 1/16/98 4:29p Atai + * create glide 3 src + * + * 10 12/09/97 12:20p Peter + * mac glide port + * + * 9 11/04/97 4:00p Dow + * Banshee Mods + * + * 8 8/18/97 3:52p Peter + * pre-hw arrival fixes/cleanup + * + * 7 6/02/97 4:09p Peter + * Compile w/ gcc for Dural + * + * 6 5/27/97 1:16p Peter + * Basic cvg, w/o cmd fifo stuff. + * + * 5 5/21/97 6:05a Peter +*/ +#ifndef __GLIDESYS_H__ +#define __GLIDESYS_H__ + +/* +n** ----------------------------------------------------------------------- +** COMPILER/ENVIRONMENT CONFIGURATION +** ----------------------------------------------------------------------- +*/ + +/* Endianness is stored in bits [30:31] */ +#define GLIDE_ENDIAN_SHIFT 30 +#define GLIDE_ENDIAN_LITTLE (0x1 << GLIDE_ENDIAN_SHIFT) +#define GLIDE_ENDIAN_BIG (0x2 << GLIDE_ENDIAN_SHIFT) + +/* OS is stored in bits [0:6] */ +#define GLIDE_OS_SHIFT 0 +#define GLIDE_OS_UNIX 0x1 +#define GLIDE_OS_DOS32 0x2 +#define GLIDE_OS_WIN32 0x4 +#define GLIDE_OS_MACOS 0x8 +#define GLIDE_OS_OS2 0x10 +#define GLIDE_OS_OTHER 0x40 /* For Proprietary Arcade HW */ + +/* Sim vs. Hardware is stored in bits [7:8] */ +#define GLIDE_SST_SHIFT 7 +#define GLIDE_SST_SIM (0x1 << GLIDE_SST_SHIFT) +#define GLIDE_SST_HW (0x2 << GLIDE_SST_SHIFT) + +/* Hardware Type is stored in bits [9:13] */ +#define GLIDE_HW_SHIFT 9 +#define GLIDE_HW_SST1 (0x1 << GLIDE_HW_SHIFT) +#define GLIDE_HW_SST96 (0x2 << GLIDE_HW_SHIFT) +#define GLIDE_HW_H3 (0x4 << GLIDE_HW_SHIFT) +#define GLIDE_HW_SST2 (0x8 << GLIDE_HW_SHIFT) +#define GLIDE_HW_CVG (0x10 << GLIDE_HW_SHIFT) + +/* +** Make sure we handle all instances of WIN32 +*/ +#ifndef __WIN32__ +# if defined (_WIN32) || defined (WIN32) || defined(__NT__) +# define __WIN32__ +# endif +#endif + +/* We need two checks on the OS: one for endian, the other for OS */ +/* Check for endianness */ +#if defined(__IRIX__) || defined(__sparc__) || defined(MACOS) +# define GLIDE_ENDIAN GLIDE_ENDIAN_BIG +#else +# define GLIDE_ENDIAN GLIDE_ENDIAN_LITTLE +#endif + +/* Check for OS */ +#if defined(__IRIX__) || defined(__sparc__) || defined(__linux__) || \ + defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) +# define GLIDE_OS GLIDE_OS_UNIX +#elif defined(__DOS__) +# define GLIDE_OS GLIDE_OS_DOS32 +#elif defined(__WIN32__) +# define GLIDE_OS GLIDE_OS_WIN32 +#elif defined(macintosh) +# define GLIDE_OS GLIDE_OS_MACOS +#else +#error "Unknown OS" +#endif + +/* Check for Simulator vs. Hardware */ +#if HAL_CSIM || HWC_CSIM +# define GLIDE_SST GLIDE_SST_SIM +#else +# define GLIDE_SST GLIDE_SST_HW +#endif + +/* Check for type of hardware */ +#ifdef SST96 +# define GLIDE_HW GLIDE_HW_SST96 +#elif defined(H3) +# define GLIDE_HW GLIDE_HW_H3 +#elif defined(SST2) +# define GLIDE_HW GLIDE_HW_SST2 +#elif defined(CVG) +# define GLIDE_HW GLIDE_HW_CVG +#else /* Default to SST1 */ +# define GLIDE_HW GLIDE_HW_SST1 +#endif + + +#define GLIDE_PLATFORM (GLIDE_ENDIAN | GLIDE_OS | GLIDE_SST | GLIDE_HW) + +/* +** Control the number of TMUs +*/ +#ifndef GLIDE_NUM_TMU +# define GLIDE_NUM_TMU 2 +#endif + + +#if ((GLIDE_NUM_TMU < 0) || (GLIDE_NUM_TMU > 3)) +# error "GLIDE_NUM_TMU set to an invalid value" +#endif + +#endif /* __GLIDESYS_H__ */ diff --git a/Source/Glide64/inc/glideutl.h b/Source/Glide64/inc/glideutl.h new file mode 100644 index 000000000..16c6e3299 --- /dev/null +++ b/Source/Glide64/inc/glideutl.h @@ -0,0 +1,153 @@ +/* +** THIS SOFTWARE IS SUBJECT TO COPYRIGHT PROTECTION AND IS OFFERED ONLY +** PURSUANT TO THE 3DFX GLIDE GENERAL PUBLIC LICENSE. THERE IS NO RIGHT +** TO USE THE GLIDE TRADEMARK WITHOUT PRIOR WRITTEN PERMISSION OF 3DFX +** INTERACTIVE, INC. A COPY OF THIS LICENSE MAY BE OBTAINED FROM THE +** DISTRIBUTOR OR BY CONTACTING 3DFX INTERACTIVE INC(info@3dfx.com). +** THIS PROGRAM IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER +** EXPRESSED OR IMPLIED. SEE THE 3DFX GLIDE GENERAL PUBLIC LICENSE FOR A +** FULL TEXT OF THE NON-WARRANTY PROVISIONS. +** +** USE, DUPLICATION OR DISCLOSURE BY THE GOVERNMENT IS SUBJECT TO +** RESTRICTIONS AS SET FORTH IN SUBDIVISION (C)(1)(II) OF THE RIGHTS IN +** TECHNICAL DATA AND COMPUTER SOFTWARE CLAUSE AT DFARS 252.227-7013, +** AND/OR IN SIMILAR OR SUCCESSOR CLAUSES IN THE FAR, DOD OR NASA FAR +** SUPPLEMENT. UNPUBLISHED RIGHTS RESERVED UNDER THE COPYRIGHT LAWS OF +** THE UNITED STATES. +** +** COPYRIGHT 3DFX INTERACTIVE, INC. 1999, ALL RIGHTS RESERVED +** +** $Header: /cvsroot/glide/glide3x/h5/glide3/src/glideutl.h,v 1.3.4.2 2003/06/05 08:23:53 koolsmoky Exp $ +** $Log: +** 3 3dfx 1.0.1.0.1.0 10/11/00 Brent Forced check in to enforce +** branching. +** 2 3dfx 1.0.1.0 06/20/00 Joseph Kain Changes to support the +** Napalm Glide open source release. Changes include cleaned up offensive +** comments and new legal headers. +** 1 3dfx 1.0 09/11/99 StarTeam VTS Administrator +** $ +** +** 4 7/24/98 1:41p Hohn +** +** 3 1/30/98 4:27p Atai +** gufog* prototype +** +** 1 1/29/98 4:00p Atai + * + * 1 1/16/98 4:29p Atai + * create glide 3 src + * + * 11 1/07/98 11:18a Atai + * remove GrMipMapInfo and GrGC.mm_table in glide3 + * + * 10 1/06/98 6:47p Atai + * undo grSplash and remove gu routines + * + * 9 1/05/98 6:04p Atai + * move 3df gu related data structure from glide.h to glideutl.h + * + * 8 12/18/97 2:13p Peter + * fogTable cataclysm + * + * 7 12/15/97 5:52p Atai + * disable obsolete glide2 api for glide3 + * + * 6 8/14/97 5:32p Pgj + * remove dead code per GMT + * + * 5 6/12/97 5:19p Pgj + * Fix bug 578 + * + * 4 3/05/97 9:36p Jdt + * Removed guFbWriteRegion added guEncodeRLE16 + * + * 3 1/16/97 3:45p Dow + * Embedded fn protos in ifndef FX_GLIDE_NO_FUNC_PROTO +*/ + +/* Glide Utility routines */ + +#ifndef __GLIDEUTL_H__ +#define __GLIDEUTL_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* +** 3DF texture file structs +*/ + +typedef struct +{ + FxU32 width, height; + int small_lod, large_lod; + GrAspectRatio_t aspect_ratio; + GrTextureFormat_t format; +} Gu3dfHeader; + +typedef struct +{ + FxU8 yRGB[16]; + FxI16 iRGB[4][3]; + FxI16 qRGB[4][3]; + FxU32 packed_data[12]; +} GuNccTable; + +typedef struct { + FxU32 data[256]; +} GuTexPalette; + +typedef union { + GuNccTable nccTable; + GuTexPalette palette; +} GuTexTable; + +typedef struct +{ + Gu3dfHeader header; + GuTexTable table; + void *data; + FxU32 mem_required; /* memory required for mip map in bytes. */ +} Gu3dfInfo; + +#ifndef FX_GLIDE_NO_FUNC_PROTO +/* +** Gamma functions +*/ + +FX_ENTRY void FX_CALL +guGammaCorrectionRGB( FxFloat red, FxFloat green, FxFloat blue ); + +/* +** fog stuff +*/ +FX_ENTRY float FX_CALL +guFogTableIndexToW( int i ); + +FX_ENTRY void FX_CALL +guFogGenerateExp( GrFog_t *fogtable, float density ); + +FX_ENTRY void FX_CALL +guFogGenerateExp2( GrFog_t *fogtable, float density ); + +FX_ENTRY void FX_CALL +guFogGenerateLinear(GrFog_t *fogtable, + float nearZ, float farZ ); + +/* +** hi-level texture manipulation tools. +*/ +FX_ENTRY FxBool FX_CALL +gu3dfGetInfo( const char *filename, Gu3dfInfo *info ); + +FX_ENTRY FxBool FX_CALL +gu3dfLoad( const char *filename, Gu3dfInfo *data ); + +#endif /* FX_GLIDE_NO_FUNC_PROTO */ + +#ifdef __cplusplus +} +#endif + +#endif /* __GLIDEUTL_H__ */ diff --git a/Source/Glide64/inc/sst1vid.h b/Source/Glide64/inc/sst1vid.h new file mode 100644 index 000000000..d76e7141d --- /dev/null +++ b/Source/Glide64/inc/sst1vid.h @@ -0,0 +1,148 @@ +/* +** THIS SOFTWARE IS SUBJECT TO COPYRIGHT PROTECTION AND IS OFFERED ONLY +** PURSUANT TO THE 3DFX GLIDE GENERAL PUBLIC LICENSE. THERE IS NO RIGHT +** TO USE THE GLIDE TRADEMARK WITHOUT PRIOR WRITTEN PERMISSION OF 3DFX +** INTERACTIVE, INC. A COPY OF THIS LICENSE MAY BE OBTAINED FROM THE +** DISTRIBUTOR OR BY CONTACTING 3DFX INTERACTIVE INC(info@3dfx.com). +** THIS PROGRAM IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER +** EXPRESSED OR IMPLIED. SEE THE 3DFX GLIDE GENERAL PUBLIC LICENSE FOR A +** FULL TEXT OF THE NON-WARRANTY PROVISIONS. +** +** USE, DUPLICATION OR DISCLOSURE BY THE GOVERNMENT IS SUBJECT TO +** RESTRICTIONS AS SET FORTH IN SUBDIVISION (C)(1)(II) OF THE RIGHTS IN +** TECHNICAL DATA AND COMPUTER SOFTWARE CLAUSE AT DFARS 252.227-7013, +** AND/OR IN SIMILAR OR SUCCESSOR CLAUSES IN THE FAR, DOD OR NASA FAR +** SUPPLEMENT. UNPUBLISHED RIGHTS RESERVED UNDER THE COPYRIGHT LAWS OF +** THE UNITED STATES. +** +** COPYRIGHT 3DFX INTERACTIVE, INC. 1999, ALL RIGHTS RESERVED +** +** $Header: /cvsroot/glide/glide3x/h5/incsrc/sst1vid.h,v 1.3.4.1 2003/04/06 18:23:10 koolsmoky Exp $ +** $Log: +** 7 3dfx 1.4.1.0.1.0 10/11/00 Brent Forced check in to enforce +** branching. +** 6 3dfx 1.4.1.0 06/20/00 Joseph Kain Changes to support the +** Napalm Glide open source release. Changes include cleaned up offensive +** comments and new legal headers. +** 5 3dfx 1.4 12/10/99 Leo Galway Removed previous hi-res +** mode information for Glide3. These modes were only necessary for +** Cornerstone (or future hi-res) support in RT4.2 source branch and +** proceeded to break the V3 and V2 builds (from 3dfx view), hence they have +** been removed. +** 4 3dfx 1.3 12/08/99 Leo Galway Added mode information for +** 1600x1280, 1792x1440, 1920x1080, 1920x1200, 2046x1536 (as a result of +** glide being tested with Cornerstone modes). Although not all of these +** modes are currently capable under Glide, their inclusion prevents Glide +** apps from displaying in incorrect modes when these hi-res modes are +** selected. Search for SUSTAINED_ENGINEERING_CHANGE_BEGIN. +** 3 3dfx 1.2 09/17/99 Jeremy Zelsnack +** 2 3dfx 1.1 09/17/99 Jeremy Zelsnack +** 1 3dfx 1.0 09/11/99 StarTeam VTS Administrator +** $ +** +** 8 3/04/99 1:19p Atai +** sync new res modes +** +** 10 2/27/99 12:28p Dow +** new resolutions +** +** 6 2/13/99 1:56p Dow +** Added new resolution constants +** +** 5 7/24/98 1:38p Hohn + * + * 4 9/09/97 7:35p Sellers + * Added 400x300 resolution + * + * 3 8/24/97 9:31a Sellers + * moved new video timing to sst1vid.h + * redefined 1600x1280 to be 1600x1200 + * + * 2 6/05/97 11:14p Pgj + * + * 5 7/24/96 3:43p Sellers + * added 512x384 @ 60 Hz for arcade monitors + * added 512x256 @ 60 Hz for arcade monitors + * + * 4 7/18/96 10:58a Sellers + * fixed FT and TF clock delay values for lower frequencies with + * .5/.5 combos + * + * 3 6/18/96 6:54p Sellers + * added sst1InitShutdownSli() to fix Glide Splash screen problems with + * SLI + * + * 2 6/13/96 7:45p Sellers + * added "voodoo.ini" support + * added DirectX support + * misc cleanup + * + * 2 6/11/96 1:43p Sellers + * added support for 60, 75, 85, and 120 Hz refresh rates for "most" + * resolutions + * + * 1 5/08/96 5:43p Paik + * Video definitions +*/ +#ifndef __SST1VID_H__ +#define __SST1VID_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Video defines */ + +typedef FxI32 GrScreenRefresh_t; +#define GR_REFRESH_60Hz 0x0 +#define GR_REFRESH_70Hz 0x1 +#define GR_REFRESH_72Hz 0x2 +#define GR_REFRESH_75Hz 0x3 +#define GR_REFRESH_80Hz 0x4 +#define GR_REFRESH_90Hz 0x5 +#define GR_REFRESH_100Hz 0x6 +#define GR_REFRESH_85Hz 0x7 +#define GR_REFRESH_120Hz 0x8 +#define GR_REFRESH_NONE 0xff + +typedef FxI32 GrScreenResolution_t; +#define GR_RESOLUTION_320x200 0x0 +#define GR_RESOLUTION_320x240 0x1 +#define GR_RESOLUTION_400x256 0x2 +#define GR_RESOLUTION_512x384 0x3 +#define GR_RESOLUTION_640x200 0x4 +#define GR_RESOLUTION_640x350 0x5 +#define GR_RESOLUTION_640x400 0x6 +#define GR_RESOLUTION_640x480 0x7 +#define GR_RESOLUTION_800x600 0x8 +#define GR_RESOLUTION_960x720 0x9 +#define GR_RESOLUTION_856x480 0xa +#define GR_RESOLUTION_512x256 0xb +#define GR_RESOLUTION_1024x768 0xC +#define GR_RESOLUTION_1280x1024 0xD +#define GR_RESOLUTION_1600x1200 0xE +#define GR_RESOLUTION_400x300 0xF +#define GR_RESOLUTION_1152x864 0x10 +#define GR_RESOLUTION_1280x960 0x11 +#define GR_RESOLUTION_1600x1024 0x12 +#define GR_RESOLUTION_1792x1344 0x13 +#define GR_RESOLUTION_1856x1392 0x14 +#define GR_RESOLUTION_1920x1440 0x15 +#define GR_RESOLUTION_2048x1536 0x16 +#define GR_RESOLUTION_2048x2048 0x17 +#define GR_RESOLUTION_NONE 0xff + +#ifdef GR_RESOLUTION_MAX +#undef GR_RESOLUTION_MAX +#endif +#ifdef GR_RESOLUTION_MIN +#undef GR_RESOLUTION_MIN +#endif +#define GR_RESOLUTION_MIN GR_RESOLUTION_320x200 +#define GR_RESOLUTION_MAX GR_RESOLUTION_2048x2048 + +#ifdef __cplusplus +} +#endif + +#endif /* __SST1VID_H__ */ diff --git a/Source/Glide64/japan.xpm b/Source/Glide64/japan.xpm new file mode 100644 index 000000000..0eb198182 --- /dev/null +++ b/Source/Glide64/japan.xpm @@ -0,0 +1,27 @@ +/* XPM */ +static const char *japan_xpm[]={ +"30 20 4 1", +" c #FFFFFF", +"0 c #C0C0C0", +"1 c #FF0000", +"2 c #808080", +" ", +" ", +" ", +" ", +" 011110 ", +" 11111111 ", +" 1111111111 ", +" 211111111110 ", +" 111111111111 ", +" 111111111111 ", +" 111111111111 ", +" 111111111111 ", +" 211111111110 ", +" 1111111111 ", +" 11111111 ", +" 211112 ", +" ", +" ", +" ", +" "}; diff --git a/Source/Glide64/lib/glide3x.lib b/Source/Glide64/lib/glide3x.lib new file mode 100644 index 0000000000000000000000000000000000000000..60d950f930870634c3907c828cfdbb18f3c26923 GIT binary patch literal 77030 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 OoO?jH3EP+ing0VC3X%l? literal 0 HcmV?d00001 diff --git a/Source/Glide64/logo.xpm b/Source/Glide64/logo.xpm new file mode 100644 index 000000000..7b3fd20da --- /dev/null +++ b/Source/Glide64/logo.xpm @@ -0,0 +1,360 @@ +/* XPM */ +static const char *logo_xpm[] = { +/* columns rows colors chars-per-pixel */ +"315 98 256 2", +" c #141A2C", +". c #848E94", +"X c #52565C", +"o c #C4CACC", +"O c #ACAEAC", +"+ c #546A94", +"@ c #343A3C", +"# c #6C7274", +"$ c #768EBC", +"% c #DCE6E4", +"& c #9CAECC", +"* c #44567C", +"= c #2C3E64", +"- c #9C9E9C", +"; c #6C7E94", +": c #BCCAE4", +"> c #444A4C", +", c #ECF6F4", +"< c #B2BECC", +"1 c #1F2A34", +"2 c #7C8EAC", +"3 c #687EAC", +"4 c #5F666C", +"5 c #8D9EBC", +"6 c #2B3A54", +"7 c #767E84", +"8 c #DCE6F4", +"9 c #5B667C", +"0 c #D0DAE4", +"q c #24324C", +"w c #48566C", +"e c #BBBEC4", +"r c #7B8694", +"t c #869ECC", +"y c #949694", +"u c #A1AEBC", +"i c #3B4A64", +"p c #ADBEDC", +"a c #647284", +"s c #919EAC", +"d c #2B323C", +"f c #D7DBDC", +"g c #647694", +"h c #AAB8CC", +"j c #58698C", +"k c #545E6C", +"l c #B0B7BC", +"z c #3E5074", +"x c #A2A9AC", +"c c #CCD2D4", +"v c #394454", +"b c #E4EEF4", +"n c #D7E2F4", +"m c #3C4244", +"M c #8B98AC", +"N c #EBEFEC", +"B c #9BA9BC", +"V c #6B80A4", +"C c #404C5C", +"Z c #F4FEFC", +"A c #C1C6CC", +"S c #646E7C", +"D c #DFE2E4", +"F c #465264", +"G c #747A84", +"H c #6379A4", +"J c #172334", +"K c #8391A4", +"L c #8498BC", +"P c #50607C", +"I c #C4D3E4", +"U c #232D44", +"Y c #7388AC", +"T c #7687A4", +"R c #A8B9DC", +"E c #C0CCDC", +"W c #555F64", +"Q c #2F3B4C", +"! c #E5E7E4", +"~ c #F4F7F4", +"^ c #93A8CC", +"/ c #8A97A4", +"( c #758094", +") c #686E74", +"_ c #81868C", +"` c #D2DCEC", +"' c #7B889C", +"] c #A3B0C4", +"[ c #3B4D6C", +"{ c #B9C6DC", +"} c #6D7484", +"| c #93A1B4", +" . c #273344", +".. c #6C7A94", +"X. c #A5B7D4", +"o. c #536074", +"O. c #EDF0F4", +"+. c #CBD6EC", +"@. c #8F8F94", +"#. c #4C5664", +"$. c #787A7C", +"%. c #B3C1D4", +"&. c #202B3C", +"*. c #2F3E5C", +"=. c #566784", +"-. c #495874", +";. c #A9B6C4", +":. c #9AA6B4", +">. c #38455C", +",. c #8898B4", +"<. c #1B263C", +"1. c #849ACC", +"2. c #4F6084", +"3. c #748ABC", +"4. c #617294", +"5. c #9CB1D4", +"6. c #7B90B4", +"7. c #5F6874", +"8. c #8AA0C4", +"9. c #737E8C", +"0. c #DEEAFC", +"q. c #243454", +"w. c #97A7C4", +"e. c #4A525C", +"r. c #849AC4", +"t. c #7088B4", +"y. c #93A9D4", +"u. c #C1CBD4", +"i. c #6B747C", +"p. c #4C5254", +"a. c #374664", +"s. c #C4C6C4", +"d. c #5D6E8C", +"f. c #A9AFB4", +"g. c #343B44", +"h. c #414B54", +"j. c #93989C", +"k. c #CAD3DC", +"l. c #3B424C", +"z. c #DCE2DC", +"x. c #BBC6D4", +"c. c #636E84", +"v. c #D8E2EC", +"b. c #44526C", +"n. c #141E34", +"m. c #828F9C", +"M. c #546E9C", +"N. c #7C92C4", +"B. c #DCE6EC", +"V. c #445A84", +"C. c #9A9FA4", +"Z. c #6B7E9C", +"A. c #ECF7FC", +"S. c #6C82B4", +"D. c #B4C2E4", +"F. c #63728C", +"G. c #63789C", +"H. c #3C527C", +"J. c #E4F0FC", +"K. c #E6E9EC", +"L. c #F6F9FC", +"P. c #75829C", +"I. c #6C768C", +"U. c #6C7A9C", +"Y. c #EDF2FC", +"T. c #8C929C", +"R. c #BCC2CC", +"E. c #343E54", +"W. c #E4E9F4", +"Q. c #646A7C", +"!. c #DCDEE4", +"~. c #545A6C", +"^. c #C4C2C4", +"/. c #848994", +"(. c #ACB2BC", +"). c #444E64", +"_. c #9CA2AC", +"`. c #34363C", +"'. c #B4BACC", +"]. c #5C626C", +"[. c #444654", +"{. c #949AAC", +"}. c #F4F2EC", +"|. c #A4AABC", +" X c #7482A4", +".X c #4C4E5C", +"XX c #6C7AA4", +"oX c #8C92A4", +"OX c #8C9ABC", +"+X c #5C627C", +"@X c #CCD5E4", +"#X c #7C8AAC", +"$X c #CCCEDC", +"%X c #3C3E4C", +"&X c #9CAACC", +"*X c #9499A4", +"=X c #DCDEEC", +"-X c #848A9C", +";X c #ACB2C4", +":X c #444E6C", +">X c #9CA2B4", +",X c #343644", +".v pX( ( r ' F.Z.5.aX` W.A.L.dXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXL.L.W.` aX& X>.F A.Z A.J.8 u G.^ { ` 8 A.L.dXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdX", +"dXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXL.O.v.I R ,.-. .=.9.; ( r ( K j L X.+.v.O.~ dXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXL.O.v.+.%.L P DXA Z Z J.W.8 v.pX6.R +.v.O.L.L.dXL.dXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdX", +"dXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXL.L.O.W.` PX^ 4.q.C 9.( ( ( r ' ' ( g ^ PX` 8 O.L.dXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXL.L.A.W.` aX&X4.>.wXdXZ A.J.ZXZXB.%.F.8.D.@X8 O.L.dXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdX", +"dXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXL.O.=XbXX.2 b. .a pX( ( ( ( ( ' K F.Y X.I ` O.A.dXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXL.dXdXdXA.O.v.bXR 8Xb. .v.Z Z Y.J.W.ZX8 B.K Y xXbX` O.L.L.dXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdX", +"dXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdX~ Y.8 ` PX8.=.CX#.pX9.; ( ( r ' ' m.T F.8.{ +.W.Y.L.dXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdX~ O.W.` PX^ lXDXm.dXdXL.J.J.W.ZX8 W.@Xg OXPX+.8 Y.L.dXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdX", +"dXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXL.A.O.` : & V i Q I.pX( 9.( P.( ' ' T / I. XX.bX=XO.L.dXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXL.L.O.` bX5.#XLXv ~ dXZ A.J.0.J.W.W.8 b B Z.& : v.O.~ dXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdX", +"dXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdX~ O.8 I p 8.P U o.9...; ( ( r ' ' ' m.K M F.5 { =XO.~ L.dXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXL.O.B.+.PXr.P DX(.dXdXL.Y.J.J.W.b W.ZXW.v.; OX{ ` W.L.L.dXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdX", +"dXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXL.O.8 ` { &XU.CXv I.9.9.( ( ( ( ' ' ' K K M T P.X.` W.A.dXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdX~ A.W.` aX& Z.>.1XdXdXZ A.Y.J.b J.b J.W.J.b 3XZ.XM I W.O.A.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.dXL.dXdXL.dXZ L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.A.L.L.L.A.A.b v.+.PX^ G.6 G dXdXdXA.A.A.Y.J.Y.J.J.J.O.Y.J.v.M E ZXO.A.L.L.A.L.L.A.L.L.L.L.L.L.A.L.A.L.L.A.L.A.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.dXdXdXdXdXdXL.L.L.L.L.L.L.L.L.L.L.A.L.A.L.A.A.L.L.L.A.L.A.L.A.A.L.L.L.L.A.L.L.L.L.L.L.L.L.L.L.L.dXL.dXdXdXdXL.dXL.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.dXdXdXdXdXdXdXL.dXL.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.dXdXdXdXdXdX", +"dXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXL.L.~ Y.O.O.b b b b b J.O.O.b O.J.O.b O.O.O.O.b O.J.O.O.J.O.O.O.O.J.O.O.O.J.O.O.O.O.O.J.O.Y.~ O.W.` : X.Y [ ,Xa pXpX9.( ( ( r ' ' T T.K / M | (.u k.8 b O.J.b b b b b b J.b O.b b J.O.A.O.L.L.A.~ O.O.Y.b b b b b b b b O.b O.O.b O.O.b O.b W.8 ` I aX& Y b.Q K.dXdXZ A.Y.Y.Y.Y.A.Y.Y.J.Y.J., A.x.gX=XW.O.O.b O.b O.O.O.O.b O.b O.O.O.O.J.O.O.O.J.O.b O.b b b b b b b b b b b b b J.O.O.A.~ A.L.L.L.L.O.Y.O.b b J.O.b O.b J.O.O.O.O.O.O.O.O.O.b O.O.O.O.O.O.b O.b O.J.O.b O.O.b O.b O.O.O.O.A.L.L.L.L.A.~ O.O.b b b b O.b J.b b b b O.J.O.A.L.~ L.dXdXL.L.L.A.O.O.b J.b b b J.b b O.b O.O.J.O.~ L.~ L.dXdXdXdX", +"dXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXL.L.O.O.b B.n v.n v.v.v.` v.` v.` v.` v.=X=Xv.` v.v.` v.` v.` v.` v.` v.` v.` v.` v.v.` v.v.8 K.W.8 n I PX8.=. .w pXpXpX..9.( ( P.' ' ' K K M s >X(.E bX` n v.v.v.v.` v.` v.` v.` v.v.B.B.ZXO.b O.O.b ZX8 v.v.` v.` v.` v.` v.` v.` v.` v.` v.` ` +.bXD.X.r.2.DX_.dXdXdXL.A.A.Y.A.Y.Y.A.Y.Y.A.Y.J.O.b E ` =Xv.v.=Xv.=Xv.` v.` v.` v.=Xv.` v.` v.` v.` v.v.` v.` v.v.` v.` v.` v.` v.` v.v.v.ZXO.O., , O.b b B.n v.v.` v.` v.` v.v.` v.` v.v.` v.` =Xv.v.` v.` v.` v.` v.` v.` v.` v.` v.=Xv.8 8 O.O.O.A., O.b 8 n v.v.v.` v.` v.` v.` v.v.v.8 W.O.L.~ L.L.A.~ O.ZXK.8 v.v.` v.v.` v.v.` v.=Xv.v.8 W.O.L.L.L.dXdXdX", +"dXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdX~ dX~ A.W.B.` @XI bX{ : : : : : : : : : : : : : : bXbX: : E : : aX: : aX: : : : : : : : : : bXbXI ` ` 0 @XaX^ T a.Q a pXpXpX( ; ( r ' ' ' -XK K M s :.5XI E @XI bXbX: : : : : : : : : { bXbXI ` ` 8 B.v.` @XI bX: : : : : : : : : : : : : E : : bX{ : PXR 5.1.G.*.C L.dXdXZ A.A.A.A.Y.A.A.Y.A.A.O.Y.b N K.{ : : : : : : : : : : : : : : : : : bXbXE bX: E : : : : : : : : : : : : : : : : : bXI ` ` ZXW.b 8 ` +.I bX: : : : : : : { bX: : : : : bX: bXE : : : : : : : : : : { : : : : : : : : : bX@X` B.W.W.W.v.` @XI bX: : : : : : : : : : : bX@X` B.O.Y.A.L.O.b 8 ` @XI bXbX: { : : : : : aX: : I I ` v.W.O.L.dXdXdX", +"dXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXL.O.ZX` +.{ p R 5.5.5.5.5.5.5.5.5.5.5.5.5.5.X.R X.X.R R R X.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5.5..} pXpXpXpX( 9.( ' P.' T K K M s >X(.E bXX.5.^ JXt r.1.r.r.r.N.r.1.r.1.r.JX5.X.p aXD.p 5.y.JXt r.1.N.1.N.r.N.r.1.N.r.1.t JXy.^ y.&XJX8.$ H z q 7.dXdXdXZ L.A.L.A.L.A.L.A.L.A., A.O.K.% uXy.y.t 1.r.1.N.N.r.N.1.N.1.r.r.t t JX^ y.^ y.^ JXt 8.1.N.1.N.r.N.r.1.r.N.r.1.r.r.t JX& R : bXI bXaXp y.^ t r.1.r.1.N.1.r.1.N.1.N.t t JXJXy.y.& ^ ^ t t N.r.1.N.1.r.1.r.1.r.N.r.r.N.8.t ^ X.p bX+.bX: PX5.y.t t r.1.N.1.N.1.r.1.N.1.t ^ 5.p I n 8 O.8 ` bXPX5.^ t 1.1.N.1.1.N.1.N.r.1.r.t ^ 5.p bXv.O.O.L.dXdX", +"dXdXdXdXdXdXdXdXdXdXdXdXdXdXdXL.A.W.` bXp ^ $ NXM.M.M.M.M.M.M.M.M.M.M.M.M.M.G.H V T V V V G.sXM.M.M.M.M.M.M.M.M.M.M.M.M.M.M.sXH V 6.8.^ y.Y [ .S } I.pXpXpX9.; r P.' ' m.K / {.s |.< E X.JXzXNXM.M.M.+ M.M.M.M.M.M.+ M.M.G.V 6.w.5.5.^ r.NXH M.M.+ M.M.M.M.M.M.M.M.M.sXG.G.V V T V V sX2.vXq Q D dXdXdXZ L.L.A.L.A.L.L.L.A.L.A.O.K.% f xX$ 3 sXM.M.M.M.M.M.M.M.+ M.M.M.M.G.XXV XT XV H G.M.M.+ M.M.M.M.M.M.+ M.M.+ M.M.M.H V MXw.p { p 5.r.t.H M.M.M.+ M.+ M.+ M.+ M.M.sXsXG.V T V X XH G.sXM.M.lXM.M.lXM.M.lXM.M.M.M.M.M.sXXX#XVXX.PXp X.^ $ NXM.M.M.M.M.M.M.M.M.M.M.M.sXH T OX%.0 v.8 ` bXp ^ $ 3 H M.M.M.M.M.M.M.M.M.M.M.sXH T ,.'.` W.L.dXdXdX", +"dXdXdXdXdXdXdXdXdXdXdXdXdXdXL.~ O.v.+.p JXNX2.vX*.6 q.6 q.6 q.6 q.6 6 6 *.CX>.>.C C C C >.*.CX6 q.q.q.q.q.6 q.q.q.q.q.q.6 q.6 CX>.w G.r.zXj DXLX} I.pXpXpX( ( ( ( ' ' ' K K M {.| ;.x.PXJXY V.a.6 q.q.q.q q.q q.q q.q q.6 CXCXw g 8.t t.+ [ 6 q.q q.q q q q q.q q q q.q.CXCX>.v >.v v q.U J ,Xk.dXdXdXdXZ L.A.L.A.L.A.A.Z A.A.O.N % SXE Y P a.6 q.q q q q.q q q q.q q q.6 6 CX>.v >.>.v 6 6 q.DXq.q q q.q q q.q.q q.q.q q.6 6 CXw ; w.X.y.L 4.z *.q.q.q q.q.q.q.q.q.q.q.q.6 6 v >.>.C C >.>.CX*.q.q.q.q.q.q.q.q.q.q.q.q.q.6 6 CX>.C =.| R 5.JXV 2.i 6 6 q.q.6 q.q.q.6 q.6 *.6 *.C o.s bX=X` I PX^ Y 2.i *.q.6 q.6 q.6 q.6 q.q.6 CX*.i k M k.W.A.L.dXdX", +"dXdXdXdXdXdXdXdXdXdXdXdXdXdXL.Y.K.+.{ ^ Z.b. .<.J n.J n.J J n.J J J J <.1 &.&.d ,Xg.g.,Xd &.<.J J J <.J <.n.<.J <.<.J <.J <.&.&.d Q 9 t.H i DXS a pXpXpXpXpX( ( ( ' ' -XK K {.s |.< { w.V b.DX<.<.U <.U &.&.U &.U U U &. . . .CX=.t.NXcXCXU J U U .U U .U .U . .,X .g.%Xl.v iXv l.,Xh./.O.dXdXdXdXZ A.L.L.A.L.L.L.L.L.L., O.K.z.SXM z DX&.J . .U .U .U .U . . .,Xg.%Xl.v iXv %XDX . .U U .U U .U U &.U U &. .&. . .g.CX9 5 ^ $ d.CXU <.&.&.&.U &.&.<.&.&.&.&.&.&. .,Xg.%X%X%Xg. .4X&.&.<.&.<.<.<.<.<.<.<.J <.<.<.<.&.U d F 2 ^ 8.H b.q <.J <.J J J J J J J J J J <.4Xd v . E ` I aX& V z q <.J J J n.J n.J n.n.<.J J <.&.d l.r k.O.L.dXdXdX", +"dXdXdXdXdXdXdXdXdXdXdXdXL.dXA.O.` bXX.Y b.U n. hXn.hXn.n.J J J <.J &.&. .%Xh.X o.AXo.C Q g.Q Q DXQ 6 CXv *.v >.C >.LXLXw w k o.a T NXcXq #.} I.I.pXpX..( ( ( ' ' ' K K M {.| ;.{ X.Y z U .9.] ;.h < X.x.%.{ { E I I I +.0 0 I Y V.DXd P.v.A.A.A.A.Z A.Z Z Z Z Z Z dXdXdXdXdXdXZ dXdXdXdXdXdXdXdXZ L.A.Z L.L.L.Z L.Z L.L.~ N ! !.h -.U Q 6XL.dXdXdXdXdXdXdXdXdXdXdXdXdXdXZ dXZ Z Z L.A.A.A.A.A.J.J.J.0.0.ZX0.n n +.+.+.I I I k.I w.r.d.*.<.FXs xX] ] B B B | | M | s s | s >X:.f.u u s m.( 0XpXpXI.} a a Q.9 o.o.w #.F #.#.#.#.~.} OX8.NXb.U J U .DX .q .U &. .&.&.&.&.&. .%X2X| E @XaXX.2 z .n. hX n. hXn.J 4X,X2X6Xv.O.L.dXdXdX", +"dXdXdXdXdXdXdXdXdXdXdXdXdXL.O.8 @XPX8.j DXJ n.n.J n.n.<.J J &.&. .%X.X7./.>XB K 9 v Q .DXQ Q E.E.E.v >.>.>.C LXF F FXFXo.P.L g *.Q a F.} I.pXpXpX9.( ( P.' -XK K M s |.< E L j .LX| ] ;.h xXh < X.%.%.PX{ E E I E E I +.K *.DX%.J.A.J.J.J.J.A.A.A.A.A.A.Z Z Z Z Z dXdXdXdXZ dXdXdXdXdXdXZ L.Z L.L.L.Z dXZ Z dXdX~ }.K.! 0 F.DX2XO.dXdXdXdXdXdXdXdXdXdXdXdXdXZ dXZ Z dXL.L.A.A.A.J.J.J.0.0.ZX8 8 n n v.` I +.I I k.E E { @Xp V i &.m.h & ] ] w.B B | | | | ,.s M s >XB 5XE @Xk.< {.r ; 9.pXG I.} a S AXo.o.FXw w w w FXk AXT w.L 2.DX&.DXQ DXDX .DX . .U U &.&.U &. .%XC 9.< +.I p 8.d.DXJ hX n. n.n.hXn.hXn.hXn.J J ,Xe.m.!.O.L.L.dXdXdX", +"dXdXdXdXdXdXdXdXdXdXdXdXL.A.W.` : ^ V >.J hX n.n.n.n.J n.J <.n.<.<.&.,X%Xe.9.(.bX+.aXw.F.>.g.Q Q Q E.6 E.v >.>.>.i i F F FXo.o.a MX,.-.U o.a a } I.pXpX( pX( P.r ' -XK / {.>X;.{ 7XV >.CX| ] ] ] ] ;.xXh h < %.%.%.{ { E E E k.I P DX< J.A.J.0.ZXZX0.ZX0.J.J.Y.A.A.A.A.L.L.L.~ O.b K.A.Z dXdXZ Z L.A.Z L.Z Z Z L.dXdXdX~ ~ N ! ! |.a.%XK.dXdXdXdXdXdXdXdXZ dXZ Z Z Z L.A.A.L.A.O.O.B.n ZX0.ZXZX8 8 n v.v.` ` +.0 I k.E E E { u.E I 8.2. .r X.< ;.] B B B | | | M M s M s s |.5X0 O.O.v.gX{.( 0X0X9.pXG } } a S 7.o.o.k k k k o.7.( VX8.Z.a.&.Q Q Q DXDXDX .q .U .U U &. .,Xv S :.I I D.& T i <. n. n.hXn.hXhXn. n.hXn.J <.d tXr f dXL.L.dXdXdXdX", +"dXdXdXdXdXdXdXdXdXdXdXdXL.O.v.I p L P .hX n.hXhXn.n.n.<.n.J J &.&.4XDXh.fX;.8 J.` : 5 o.CXQ Q Q Q 6 E.v v >.>.C C ).F w FXk 7.P.5 G.q.v c.} a I.pXpXpXpX( ( ( ' ' m.K *Xs u %.p 6.P .( u ] ] u ] ] ] ;.h xX%.h %.%.x.x.x.E I ,.DX9.0.J.0.n n v.n 8 8 8 ZXZXb J.J.Y.O.Y.O.O.v.: 9Xd.T.L.dXZ Z L.Z L.L.Z Z dXdXdXdX~ L.~ O.! D uX2. .6XdXdXdXdXdXdXZ Z dXZ L.A.L.A.A.A.Y.O.O.O.v.PXOX=.B ZXZX8 n v.v.` ` 0 0 @X@XI E E { u.u.{ k.%.G.>.>.h nXxX] ] B VX:.| | ,.| M M M M | (.k.b A.8 I :.i.r _ ( 0X9.pXG G } i.S 7.7.].o.].7.7.} s ^ 6.cXU DXQ Q 6 Q DXDXq . . .&.U &. . .Q X ' %.bX: X.zXP .n.hX n.hXn. n.n. n.hXn.J J 4Xl.fXA L.L.A.dXdXdXdXdX", +"dXdXdXdXdXdXdXdXdXdXdX~ ~ W.+.aX^ g *.J hXn. n.n.n.n.J n.n.<.<.<.&. .v k *Xv.A.8 @X{ T C g.Q Q CXv v v >.>.C C ).).F w FXk o.a 6.6.b. .7.c.a } I.} pXpX9.( ( ( ' ' K oXM :.h E w.G.>.LXVXB B u w.] ] ] ;.xX< h %.< %.x.x.x.I x.b.DXI 0.ZXn v.v.v.n v.n 8 ZXZXZXb J.b J.O.N v.E X.6.b.k dXdXdXZ L.L.Z Z dXdXL.~ dXL.dX~ O.N D z.M a.#.L.dXdXdXdXdXZ L.L.A.L.A.A.A.Y.A.O.b O.K.0 aX& V ).r 0.ZXn v.v.` 0 +.0 @XI k.E E E { x.x.E k.6.-. .| nXh ;.] B B :.| | ,.s s M M M M :.< ` B.` ` E oX#._ r 0X_ 9.9.7 G G } S S 7.7.7.S S G M & 9X4.CX .CXQ CXQ DXDXDXDXDX .U .U .U .%Xo.VXPXPXR JXg *.1 hXn. hXn.hXn.hXn.hXn.hXn.J &.,X2Xs O.dX~ L.dXdXdXdXdX", +"dXdXdXdXdXdXdXdXdXdXL.~ W.n bXX.6.b.<.hX n.hXn.n.n.n.n.<.J <.&.U Q e.9.A A.Y.B.0 ] S g.Q %Xv v v v C C C C F F #.#.FXk o.S T ,.d.DXLXQ.c.a a } pXpX..pX( ( P.' m.K *Xs u x....& 5.5.JXNX[ U n.hX n. n. n.hXn.n.hXn.J J .h.9.uXdXL.L.dXdXdXdXdXdX", +"dXdXdXdXdXdXdXdXdXdXL.~ 8 ` PX8.4.Q J n.hXn.hXn.n.<.n.<.J <.J &.,Xl.1Xx 8 A.O.8 bXM e.g.l.CXh.h.C C C C e.F F #.FXk k ].7...L Y >. .AXc.c.} a I.pXpXpX( ( ( ' ' m.oXM :.'.E 8.d.DXo.:.B B B :.u w.] ] ;.;.h h %.%.%.%.x.E xX>.LX0 n n v.` ` v.v.v.n v.8 8 ZXZXb W.b b K.@X: 5.V i F ~ dXdXdXZ L.Z dXdXdXdXdX~ dXL.~ O.K.! D P.DX} dXdXdXdXdXZ Z L.L.A.L.A.A.A.Y.O.O.W.K.D : p ^ G.6 o.L.A.0.8 v.` ` 0 I 0 I k.I k.E E x.u.u.E 2 [ q ] %.< ;.] w.B :.VX:.| | M M M *XM s ] { p R p R X.L | :.| | | | M M M M M M M M s :.;Xx.$X{ ] F.Q DXv v E.6 Q Q Q Q DX . . . . . . .Q -.Y y.y.t $ j q J hXn.hXn.n.hXn.n.n. n.n.n.J &.,X4 (.L.L.~ L.dXdXdXdXdXdX", +"dXdXdXdXdXdXdXdXdXdXA.W.` bX5.T LX<.hX hXn.hXn.n.n.n.n.J <.&. .%XC 0XE A.b ZXv.x._ l.l.h.h.h.C e.C e.F #.#.2Xk ].o.7.AXpXM 5 P U F AXS c.a a } I.pXpX; ( ( ' -XK / s ] %.X.Y i Q M B B B B B u w.] ] ;.xXh < h %.nX%.x.E c.DXu n n v.` ` 0 ` ` v.v.n B.8 ZXb W.b W.O.SX: p L P DXA dXdXdXdXZ Z dXdX~ dXL.dXdXdXL.O.}.! D 5X:XDXD dXdXdXdXdXdXdXZ L.L.L.A.A.A.O.J.W.B.D bXR y.6.-.U f Z A.ZXv.v.v.+.0 +.@X0 I @XI E E x.u.E ^ j DX9.%.%.< ] ] u B B B | | s | s M M M | xXX.JXJXy.JXJXt xXX.xXxXxXxX& & & & & & 7X%.: @Xv.v.=XPX,.w ,Xh.>.v v v v E.%XQ Q Q Q DXg. . . .%X2.6.N.N.S.+ *.<.J n.hXn.n.hXn.hXhXhXn.hXn.J &. .tXm.B.dX~ L.L.dXdXdXdXdXdX", +"dXdXdXdXdXdXdXdXL.~ O.8 I p L 2. .n. n.hXn.hXn.n.n.n.<.n.J <.&. .v 7.6X8 O.8 v.+.< ( #.e.e.#.#.#.FXFXk k o.o.7.S S i.9.' | 8. XCXDX7.AXc.a } a I.pXpX..9.( r ' K K *X6X< PXL 2.q a | B B VX:.B B ] u ] ;.;.h < %.< %.x.E VX6 o.n v.v.` ` 0 ` v.` v.v.n 8 8 ZXZXb W.N K.I PX& G.*.7.dXdXdXdXZ Z dXZ dXL.dXdXdXL.~ ~ }.K.D f d.q j.dXdXdXdXdXdXdX~ dXZ ~ A.~ A.O.O.b B.D I X.y.r.j DXHXdXZ J.0.n v.` ` SX0 @X@X@Xk.k.k.E u.E x.Z.a.CX%.%.%.xX;.] u B B | :.| | s M s M *Xs ] 6.t.3.3.S.t.S.3.r.L r.L L L L L N.r.8.8.7XPX+.n 8 @X'.pXl.v C C C C >.h.v v v l.l.%X%XQ %Xg.DXE.P V S.H V.*.<.n.n.n.n.n.n.n. n.n.n.n.n.n.J 4Xl.7.A L.L.L.L.dXdXdXdXdXdXdX", +"dXdXdXdXdXdXdXdXdXY.b ` { 5.Z.*.<.hX n.hX n.n.n.n.n.<.J &.4X%X#.0Xx.J.v.` @XbXX.,.; F.g g ..; Z.; ; Z.' ' T K M s :.] xX,.w .w 9 AXc.c.a } I.I.9.pX( ( ' ' T./ s ] E ^ G.>.>.| | B | B B B B ] ] ] ;.h h h < < nXE E -.q < n n ` ` 0 ` 0 ` v.v.v.n 8 ZXb W.W.b K.` : R ,.cXDXf dXdXdXdXdXZ Z dXL.dXdXL.dXdX~ O.N ! !.| i C ~ dXdXdXdXdXL.dXdX~ Z L.L.A.A.A.O.K.B.SXX.y.8.XX[ v O.dXA.J.ZXv.v.v.` ` 0 ` 0 @X@X@XE qXu.k.L cX .M { %.< ;.] u B B :.B | | | | | s {.{.s T -.2.cX* V.* V.* * * H.V.* V.V.* * * P 2.d.' ] @Xn ` 6X].[.X #.X F e.e.C tXC h.h.[.[.v l.l.%X%X%XC -.* i DX<.n.J n.n.J n.n.hXn.hX hXhXn.J &.,X#.oXN dXL.L.dXdXdXdXdXdXdXdX", +"dXdXdXdXdXdXdXL.~ O.v.bXX.,.-.&.n.hXn.n.hXn.hXn.n.n.J <.J <.&.,Xv S 6X` 8 ` : PXR ^ 8.zX,.L L r.L r.r.8.8.t ^ & X.%.PXPXX.8.d.6 v o.7.AXc.c.a F.I.pXpXpX( ( ' ' K M B %.PX6.-. .r | VX:.| B :.B B ] ] ] xXh < < < < x.E MXDXpX` n ` ` 0 ` ` ` ` v.v.n 8 B.ZXW.b W.N B.I p 9Xg CX/.dXdXdXdXZ Z Z dX~ dXdXdXdXL.~ ~ }.! D qXP DXl dXdXdXdXdXL.dXL.dXdXL.Z L.A., , O.B.D x.JX8.Y -. .l dXZ A.J.ZXv.n v.` SX` 0 @X@X@XuXE E k.%.4.CXw I { %.< xX;.& u B B :.B | | :.| >XIXs {.9. .U U U U <.U <.U <.U <.<.<.<.U <.U U .Q #.oXk.W.0 *XjX2Xk k k W ~.2X2X#.X #.X e.e..XtXh.h.[.%XQ .U &.J n.J n.J n.n.n.n.n. n.n.n.n.J J 4Xv 7 u.dXL.~ L.dXdXdXdXdXdXdXdX", +"dXdXdXdXdXdXL.L.A.8 ` D.w.4.CXn.hX n.hXn. n. n.n.n.J J <. .Q X m.E n +.bXp 5.8.$ $ Y S.S.S.S.t.t.t.t.t.6.zXr.w.5.X.X.^ Y i U w o.9 AXc.c.} a I.I.pXpX( ( ' m.oXs ;.{ w.4.6 F | | | VX>X| B B u w.] ;.;.h h < < x.E < LXCX{ ` v.v.+.0 0 ` 0 ` ` v.8 8 8 ZXZXW.b K.@X: X.#X:X[.N dXdXdXdXZ Z dXdXdXdXdXdX~ L.~ O.K.z.B.K 6 1XdXdXdXdXdXdXdXL.dXdX~ Z dXA.L.A.O.b % 0 ,.6...-.Q ].L.dXA.O.W.8 v.v.v.` D ` 0 ` 0 @Xk.k.E k.6.z .KXE x.X.h ;.] KXw.B B B | :.| | >X:.>X:.IXM } FX2Xw F F F F ).).C i C C C >.C v >.C C 7._.@XW.K.O $.G wX$.} } wXwXi.i.i.# ) ) ) ) BX4 ].W e.C g.&.J <.J <.J n.n.J n.n.n.hX hXhXn.J 4X,Xk 6XA.L.L.L.dXdXdXdXdXdXdXdXdX", +"dXdXdXdXdXdXL.L.O.` bXX.Y b.&.hX n.n.hXn.hXn.n.n.n.J J <.&.,Xh.S ;X` +.bXp ^ zX4.V.z z z z z z z z z z z z -.cX9 G.L JXzX=.DXv FXo.9 AXS c.a I.I.pXpX( ( r ' T.M |.%.X.6.z .T | | | | | B B B B ] ] ] ;.h < h nXx.{ g .M 0 +.` +.0 0 +.` v.` v.v.n B.ZXW.K.W.b v.bXPX8.=. .6XdXdXdXdXZ L.Z Z L.dX~ dXL.dXL.~ }.! !.gX-. .k.dXdXdXdXdXdXL.dXL.dXdX~ Z ~ L., O.O.K.KX7.-.C rXC !.dXdXY.J.W.8 B.v.v.v.` SX` SX0 @Xk.k.k.& 4.CXa { { %.< ;.xX] KXu B B B :.B :.B 6Xu (.'.< KXs K m.' ' ' ( ( ( pXpXpX} } a c.c.c.} } 9.6X=XK.A.O.f A e e ^.R.^.R.e ^.GXe e e e e l l eX6XC.K pX~.DX&.J J n.n.<.n.n.n.n.n. n.n.n.J J .v _ !.dXL.L.L.dXdXdXdXdXdXdXdXdX", +"dXdXdXdXdXdXL.O.8 @Xp 5 =.DXn. n.hX n.n. n.hXn.n.n.J <. .l.2X/ @X` I PX^ V z CX<.<.<.<.J <.<.J <.<.<.<.<.&.U .i G.zXG.*.U #.-.o.9 AXc.c.a } I.pXpX9.( ' -XK >Xh PXL j DX7.M | | | | | >XB B B ] ] ] ;.h h < %.E u CXLX+.+.+.0 0 I 0 +.0 +.` v.v.8 8 8 ZXb W.K.@XaX5. X>.F L.dXdXdXZ L.Z Z dXdXL.dXL.dXL.~ O.K.z.!.( q.0XdXdXdXdXdXdXL.dXdXL.dXL.dXL.Z Z A., O.K.l %Xg.,XG K.dXZ A.O.8 B.v.v.v.v.` v.` ` 0 0 @Xk.@XE T [ Q %.: x.%.< xX;.] u w.B B B :.B 6X|.(.< k.uXI x.B K -X' ' ' ( ( ( ( pXpXI.a a a c.} } 9.*Xk.L.O.L.L.L.L.L.dXL.L.dXL.dXdXL.dXL.dXL.dXL.L.~ W.0 3Xw.g v &.<.J <.J n.n.J n.n. n.hXhXJ J 4X%X4 5XL.L.~ dXL.dXdXdXdXdXdXdXdXdX", +"dXdXdXdXdXdX~ W.v.: 7XT a.<.hXn.hXn.n.n. hXhXn.n.n.J <.&. ..XG ;.` +.{ X.6.-. .<.J <.<.&. .&.U U U . .q DX%XQ v -.Z.3 z .C b.FXo.9 Q.c.c.} F.} pXpX( r ' m./ u { h V a.Q M M | | | | | VX:.B u u ] ;.h 5X;.< x.E =.U :.I 0 I 0 I 0 0 0 ` SX` v.n n B.ZXW.K.K.v.bX.C ).FX..Y j CXDXw w -.o.9 =.S c.a } I.I.9.( r /.oXIX< PX6.P .} M | M ,.| | | | B B u ] ] ] ;.h < %.{ ,.6 9 I +.I I I @XI 0 +.0 ` ` v.n B.ZX8 W.N B.I D.&XU.a.i.dXdXdXdXZ A.L.Z Z dX~ dX~ dXL.~ }.! ! uX=.U 6XdXdXdXdXdXdXL.dXL.dXdX~ dX~ Z Z A., O.O.N N b O., A.A.b K.v.v.SXSX0 SXSXSXSXD v.v.B.D SXuX%.Z.*.C I I { %.< h ;.& ] u ] B B B B u (.'.k.B.` { 5.T >.a ' ' ' P.( ( ..pXpXpXI.a a a } pX0Xs @XdXA.L.dXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXL.~ O.B.I p r.P U <.J J <.n.<.n.J n.n.n.hXn.J J 4Xl.wXgXL.L.~ L.dXdXdXdXdXdXdXdXdXdXdX", +"dXdXdXdXL.~ W.` { ^ g *.J hXn. n.n.hXn. hXn.n.n.J J &.Q .X0X%.` +.aX& Z.>.<.<. .d .q DXDXDXDXCXQ E.v >.C C F 9 T Y [ &.LXF w FXo.o.AXc.c.a F.I.pX9.( ' -XM KXPX&XG.*.>.M s ,.s | M | | B B :.w.u ] ;.h ;.< x.%.b.DXh I I I I I I 0 0 0 +.SXv.n v.8 B.ZXK.W.0 : X.6.z %XD dXdXdXdXL.A.L.L.Z dXL.dXdX~ ~ O.K.D ! {.*.e.L.dXdXdXdXdXL.dXdXL.dXL.dXdX~ dXA.~ O.}.K.! K.K.N ZXK.K.B.v.D SXSXSXSXSX0 SXv.v.B.K.B.B.0 %.zXP .VXI E x.%.h ;.xX;.] ] B B B |.u u ;.u.v.v.bX.J <.J J J n.J n.n.n.hXn.n.n.J &.,X#._.O.dXL.L.dXdXdXdXdXdXdXdXdXdXdXdX", +"dXdXdXdXL.O.v.I R 6.-.U hXhX n.hXn. n.n.n. hXn.J <. .l.].:.` ` { p 6.-.U &.&.&.U . .DXDXDXQ Q 6 6 >.v C F FXg 6.d.DX6 F b.w FXo.9 AXS c.} a I.pX( r HXK >X%.X.6.-.U ( / ,.M s M | | | | B B u ] ] ;.;.h x.{ P. .r E I I E I k.I I 0 +.0 v.` v.n B.ZXK.K.B.I PX^ F.q . dXdXdXZ L.L.L.L.Z Z L.dXdXL.L.~ }.! z.$XP q R.dXdXdXdXdXdXdXL.dXL.dXdXdX~ Z ~ ~ ~ N K.D I %.5.w.L ,.,.6.6.6.6.6.6.6.6.6.6.,.5 w.h { aXX.^ g CX9 I I { PX< < h ;.] ] u ] u B u u ] R.@Xv.I aX^ U.>.v K m.' ' ( ( ( pXpXI.I.I.} } G 7 r 6Xv.L.~ L.dXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXL.O.v.I p 8X-. .&.J J J <.n.n.J n.n.n.n.hXJ J .v G uXdXL.L.dXdXdXdXdXdXdXdXdXdXdXdXdX", +"dXdXdXL.O.W.@XPX8.d.DXJ n.hXn. n.n. n.hXn.n.n.J 4Xg.F r x.` bXp ^ 4.6 &.&.&.U . . .q .DXQ CXQ CXv >.C F =.Y V a.U C F w w -.o.o.AXc.c.a } I.pX( r -X{.;XPXOXd.CXw / M M M M s | | | B :.B u ] ;.;.;.h u.xX*.CX{ I I E E bXI I 0 I SX` ` v.v.8 n B.W.K.@XaX7X#X[ v O.dXdXZ L.L.A.L.L.Z L.dXdX~ dX~ O.K.! z.T E.fXdXdXdXdXdXdXL.dXdXL.dXL.dXL.dX~ ~ , N ! 0 aX7X8.H cX[ = = = *.= = *.= = vX*.vXa.LX-.I.9XX.y.Y b.CX%.I I x.%.h h ;.h ;.] u ] B u u ] 5XE v.0 : R 8X-. .( K ' ' P.( ( pXpXpXI.} } } I.pX( *Xu.L.L.L.L.dXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXL.O.W.+.PX^ lX6 J J J <.J n.<.n.n.J n.n.hXJ J &.rX].f.L.L.L.L.L.dXdXdXdXdXdXdXdXdXdXdXdX", +"dXdXL.A.b ` bX7X#XLX&. hXn.hXn.n.hXn. n.hXn.J J 4X%X7.:.@X+.: 5.2 b.&.<.&.&.U &. .q .DXDX6 Q 6 v v C LXo.Z.Y 2. .v LXb.F w FXo.9 S S c.a I.pX9.( ' m.:.%.X.Y i DX' K M M M M s ,.| | :.B B u ] ] ;.;.x.{ F. .MXE I : E E k.I I 0 I +.0 ` v.v.v.B.K.K.` bXp 8.=.DXf.dXdXdXL.A.A.L.A.L.L.Z ~ dXL.~ ~ N ! D < i Q D dXdXdXdXdXdXdXL.L.dXdXdX~ dXL.~ O.N K.0 E p 8.d.vXU n.J J J J J n.J J J J J J &.&.,XF #X^ r.j q r ` I { %.%.< < h xX] ] ] ] B ] KX] R.0 v.bXPXw.4.6 w oXK m.' ' ( ( ( pXpXpXI.I.pXpX0Xm.(.W.L.~ dXL.dXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXL.A.O.v.bXX.2 b.&.<.J <.J <.<.n.J n.n.n.n.n.J &.4XC /.v.dX~ L.dXdXdXdXdXdXdXdXdXdXdXdXdXdX", +"dXdXL.O.B.+.p OX=.DXhXhXn.n. n.hXhXn.hXhXn.n.J J &. .C r %.bX: R 5 j Q <.&.&.U . .U .DXDXDXQ Q CXv >.C F c.2 G.E. .).LXF b.w FXo.P AXc.c.a } pX0Xr -Xs h p OX2.DX7.MX/ MXM M M s | | | | B B ] ] ] ;.h x.VX*.F { E E E { E E I I 0 0 0 ` ` v.v.v.v.B.D bXD.&XZ.a.k L.dXdXZ A.A.A.L.A.L.L.Z L.Z dX~ }.K.! !.F.q T.dXdXdXdXdXdXL.dXdXdXdXL.dXL.dX~ , }.K.!.: p &XU.>.U #.f.k.uXuXk.uXk.k.k.E E E E qXE x.x.] t V a.v I ` I { %.%.h h ;.;.;.] KXu ] u ] 5XqX` bXD.5.t.b. .-XMXK ' ' P.( ( ( pXpXpX} pXpX9.r _.k.L.L.L.L.dXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXL.O.8 +.PX5 j DXJ &.J J <.J n.<.n.n.<.n.n.n.J d %XS R.L.L.L.L.dXdXdXdXdXdXdXdXdXdXdXdXdXdX", +"dX~ L.W.` : & Z.>.J n.hXhXn.n.n.n.hXn.n.hXn.n.J &.,Xk | PX{ p ^ G.i &.J &.&.&.U U U .DXDXDXQ 6 CXv C C o. XY z U v LXF b.#.w -.o.9 AXS a } I.9.( HXoXB %.& V vXQ m.M K M K M M M | | | B B B u ;X] ;.%.%.-.DXu E E { x.E { E k.@XI 0 +.SX` ` v.D v.v.I p X.6.-.DXqXdXdXZ A.A.A.Y.L.A.A.L.Z Z dX~ }.N ! D |.vXv O.dXdXdXdXdXL.dXL.dXdXL.dXdXdX~ ~ }.K.D E p y.Y b.U *XdXdXdXdXdXZ Z Z Z Z A.L.A.A.A.J.b ZX+.6.P .| v.+.E x.%.%.< h h h ] ] ] ] ] u ;X%.uXI PXX.L =.q AXK / K ' ' ' ( ( 9.pXpXpXpX9.9.( *X< O.L.L.dXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXL.A.O.` : & V i &.J <.1 <.<.<.J <.n.J n.n.J J &.,X#.*XO.L.~ L.dXdXdXdXdXdXdXdXdXdXdXdXdXdXdX", +"dXL.O.W.+.p L -. .n. n. hXhXhXhXhXhXhXn.hXJ J 4XE.F.&XR R y.zXcX .J &.<.&.U U . . .DXDXDXQ CXv v C w F.2 4.6 .i ).).F b.w FXo.9 AXc.a } pX0Xr /.>X%.%.6.P .a K K MXoXM M M s | | | :.B u ] u ;.%.E K DX9 { E { u.{ { { E I I @X+.0 +.SX` ` ` D ` R 5.JXsX6 S dXdXZ L.A.Y.A.A.A.L.~ A.L.Z ~ ~ O.N z.uX=.DXeXdXdXdXdXdXdXdXL.dXL.dXdXL.L.~ ~ O.N ! k.R 5.r.=.6 @.dXdXdXdXZ A.A.Y.J.A.J.J.J.0.J.8 B.v.B.{ 4.>.o.` ` I { x.< h < h ;.] ;.] KXu ] u h u.I R X.JXU.a.v oXM K K ' ' P.( ( 9.( pXpXpX9.( /.6X!.L.~ L.L.dXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXL.O.W.@XD.OXP DXJ &.<.J J J J J n.J n.J n.n.J 4Xv i.qXdXL.L.L.dXdXdXdXdXdXdXdXdXdXdXdXdXdXdX", +"L.A.O.v.bXxX..E.<.hXn.hXn.J n.J n.n.n.n.n.J n.J J U LX Xy.y.JXzXlX6 J &.<.<. .&.U .U q .DXDXQ v v C ).AXT Y :X .C LXLXF b.w FX-.o.7.S c.} I.9.( ' *Xh E &Xg >.F ' K / K K M M M M | | | B B u ] ;.h x.%.[ Q ;.E { { { x.{ u.E I @X@X0 0 0 ` ` SXSXSX%.5.JXY b.Q D dXdXL.A.A.A.Y.Y.A.A.L.A.L.Z L.~ N ! D M >.1XdXdXdXdXdXdXdXL.dXL.dXL.dXL.dX~ , N ! SX5.y.8.G.a.F A.dXdXZ L.Y.Y.J.J.J.ZXZX0.W.8 8 B.` v.v.,.-.Q %.n @XE u.%.%.%.< h h h ;.] ] ] u ] < E R 5.y.t.cX .( M M K m.' ' r P.( ( 9.pX( 9.( /.*XgXA.L.L.L.dXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXL.L.J.=XbXX.Z.v &.&.&.&.&.&.<.<.J <.J J J J 1 &.%X4 6XA.dX~ L.L.dXdXdXdXdXdXdXdXdXdXdXdXdXdXdX", +"dX~ J.=X{ 5 o.4XJ hX1 J J n.J J J J J J J J J J <.DXP $ t 1.N.M.[ <.<.J &.&.&.U U d .q DXDXDXQ CXC C o.' OXd.Q E.C F F b.#.w FXo.o.AXc.a } 9.( r / f.E : ,.o.,X( K K K / M M M {.s | | B B u u ;Xh x.E ' Q ( { { x.x.x.{ { E E k.@X@X0 0 ` 0 0 0 ` E y.JX6.2.Q T.dXdXZ A.Y.J.Y.A.A.A.L.A.A.L.L.~ , K.N qXo.Q k.dXdXdXdXdXdXdXL.dXdXdXdX~ dXL.~ }.K.D PX^ JXY -. .GXdXdXdXA.A.J.0.b W.ZX8 8 B.8 v.v.v.!.D { ..E.pXZXn I E { %.nX< '.h h 5X;.] ] KX] ] nX{ y.^ zXd.6 F s ,.*XK K ' -X' ( r ( ( ( 0X( r oX(.B.dXL.L.dXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdX~ O.n E 9Xo.U 4X&.4X&.&.&.&.&.&.<.1 <.J <.&.,Xe.@.!.dXL.L.dXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdX", +"dXL.O.=X3Xr >.mXJ &.J <.1 1 &.J &.1 <.1 <.1 1 &.&.Q 2.t.$ S.+ [ q J J <.<.<.U &.U U . .DXDXQ v v C 2XpXVX,.F Q e.F F #.FXFXFXk o.9 S } } pX( HXT.:.x.0 %.' v k oX/ K M / M M {.s | | :.6Xu ] ] 5XR.k.'.#.F %.x.E x.x.{ x.E E E I @X@X@X` 0 ` 0 0 0 w.r.6.=.E.C A.dXZ A.Y.A.J.A.Y.A.Y.L.A.L.L.L., }.K.O./ >.7 dXdXdXdXdXdXdXL.dXL.dXdXL.dXdX~ , O.% k.w.r.Y 2.%X7.dXdXdXL.Y.J.b b W.W.ZXB.8 8 8 v.v.v.v.=XB o.C E 8 ` I E x.x.%.%.< < h h ;.;.;X] u ;.%.&X8.6.4.i Q K | s M oXoXK m.-X' r ( r ( r /.m.6Xk.L.L.A.dXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXL.Y.v.3X-XC d . . . .&. .d 4X&.&.&.&.4X4Xg.h.} A dXL.L.L.dXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdX", +"dXL.O.v.(.7.rXmXd 4Xd 4Xd d d 4X4Xd d 4Xd 4Xd d 4X,XLX2.j H.6 <.J J &.<.&.<.U &. .U .q .DXQ CXC 2Xa >Xh 9.l..Xw ~.k k o.o.1X7.9 S i.G 9.r /.T._.A D =X;X7.[.-X/ M *X{.{.{.| IX>X>X:.|.u ;X;X5X%.@X0 r [._.E u.{ x.{ u.E E E I I 0 0 ` 0 ` 0 0 @X(...I.o.E.,Xo dXdXL.A.Y.J.Y.Y.A.Y.A.A.L.A.A.~ , O.N c fX[.N dXdXdXdXdXL.dXdXdXdXdXL.dXdX~ Z , }.% s ; c.w l.[.B.dXdXZ A.Y.O.0.W.W.ZXZXK.8 B.8 v.B.B.K.$Xm..XC.ZX8 ` E E E x.x.%.%.nX< '.h 5X;.;.u ] B ( g o.C g.} B |.IX{.M / oXK m.m.-X-X/./.-XT.s R.O.dXL.dXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXL.~ O.v.;X) %Xg.Q g.g.g.g.g.,Xg. .,X,X,Xg.g..X) f.L.dXL.L.dXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdX", +"L.L.~ v.s X @ `.`.`.`.g.,X@ ,Xg.`.g.`.g.`.g.,X`.,Xd ,XQ DXU <.J J <.J <.<.<.U <.U U U .DXDXl.v F Q./ gX;.4 [.2XW k ].].7.7.Q.) fXi.G 9._ /.T._.e v.Y.0 _.#.wX/ *X{.{.s s IX_.>X:.6X|.u u ;.;.R.uXW.A 4 ) x.E E E x.u.E E $XE k.@X@XSX0 SX` SX0 0 /.v %X,XiXGXdXdXZ A.Y.Y.Y.Y.Y.A.Y.A.A.A.L.L.L.~ ~ O.6XW x dXdXdXdXdXdXdXL.dXL.dXL.dXdX~ Z ~ , O.K.) v %XUX2XD dXdXdXL.Y.J.J.b 0.b W.W.ZX8 8 8 B.W.O.O.R.wX7.` 8 v.0 k.E E x.u.x.R.%.R.< < '.;.;.;.KX/.v l.rXg.} (.u :.6Xs C.M *X*XoXT.T.m.m.m.oXC.5XB.dXL.L.dXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXL.L.v._.2Xm l.l.l.%X%Xl.%Xm %XrXg.rXrXl.h.) C.B.dXL.L.L.dXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdX", +"dXL.L.K.x 4 > tXtXtXp.tXp.tXp.tXp.tXp.tXp.tXp.tX> l.%XUX&.J 1 J J <.&.<.<.&.U U &. . . .DXQ CXC 4 T.E W.5XwXBX) fXwXwXG G 7 7 9.0X/./.T.j.s eXo W.dX~ D 6X$.C._.6X6X6X6X|.f.u (.(.l ;.5X5XR.$XSXO.L.e wX;.$Xk.$X$Xk.$Xk.I k.@X0 0 SX` v.v.v.v.v.v.u.wX) C.K.dXdXdXL.A.Y.Y.Y.Y.Y.A.A.Y.A.A.L.L.L.~ ~ K.eX_ L.dXdXdXdXdXdXL.dXdXdXdXdXdXdXL.L.dX~ ~ O.s.wX$.f.~ dXdXdXZ A.Y.Y.J.O.b b W.b W.W.W.b O.A.L.O.o 0XA W.W.v.0 @XuX$Xk.$XqXE u.u.x.3XR.nX< e h KX# ].G 6Xe < 5Xl u 6X6X>Xx _._._.s _.C._.f.GXv.dXdXL.L.dXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXL.L.K.x BXX X X jX#.jXjXX X X X X X jX].wXC.D dXdXL.dXL.dXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdX", +"dXdXL.~ kXx yX@.T.y j.j.j.yXj.j.j.yXj.j.j.j.@.@.r G Q.C d &.J J <.J <.<.&.<.&.&.U U . .Q %X>.2X9.x.L.Y.f l x x f.f.f.(.eX(.(.l l l 5X^.A c v.L.dXdXL.O.c R.A o u.qXu.u.qXqX$Xc k.k.uX@X0 v.O.L.dXL.f s.v.8 B.v.v.v.v.B.B.B.8 B.W.W.W.W.b W.O.0.O.A.L.dXdXdXdXdXdXL.L.A.A.A.A.L.L.A.L.L.L.L.dXL.L.L.O.uXD dXdXdXdXdXL.dXL.dXdXL.dXdXL.dXL.dXL.L.L.L.dXdXdXdXdXdXdXdXdXL.A.A.A.A.Y.Y.Y.Y.Y.Y.A.L.L.dXdX~ D o L.L.Y.b W.8 B.B.v.v.v.D v.SX!.SX!.0 f @Xf uXuX0 D =X=X!.@Xk.qXqXqXu.o gXo A A A o qX!.Y.dXdXL.dXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXO.qXx yXj.yX*X- C.yXC.- C.- - C.C.x ^.O.dXdXdXL.dXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdX", +"dXdXdXL.O.O.N N O.O.O.O.O.O.O.O.O.O.O.O.O.N K.v.k.< |.pXv <.J J <.J <.<.<.&.U U U U . .Q CXe.7.6XO.dXO.O.O.O.O.O.O.A.O.A.O.L.O.A.L.A.L.L.dXdXdXdXdXL.dXO.~ A.L.L.L.L.L.L.L.L.L.L.L.L.L.dXdXdXdXdXL.A.~ L.dXdXL.dXL.L.L.L.dXL.L.dXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXL.~ L.dXdXdXdXdXL.L.dXL.L.dXL.L.dXL.L.dXL.L.dXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXL.L.O.dXdXdXdXdXL.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.dXdXdXdXdXL.L.L.A.~ A.L.A.L.A.L.A.L.L.dXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXO.N B.K.O.O.O.O.O.O.O.O.O.O.O.~ L.dXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdX", +"dXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXO.` 3XT v &.J <.J <.<.<.<.<.&.&.U . .DX%X>.k /.@XdX~ L.dXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdX", +"dXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXL.Y.v.{ ( %X<.J J J <.J &.<.<.U &.U U .Q CXe.i.l A.L.L.L.dXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdX", +"dXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXL.O.v. +#include "3dmath.h" +#include "Util.h" +#include "Debugger.h" +#include "Combine.h" +#include "TexCache.h" +#include "TexBuffer.h" +#include "FBtoScreen.h" +#include "CRC.h" + +extern "C" void SwapBlock32 (); +extern "C" void SwapBlock64 (); + +const int NumOfFormats = 3; +SCREEN_SHOT_FORMAT ScreenShotFormats[NumOfFormats] = { {wxT("BMP"), wxT("bmp"), wxBITMAP_TYPE_BMP}, {wxT("PNG"), wxT("png"), wxBITMAP_TYPE_PNG}, {wxT("JPEG"), wxT("jpeg"), wxBITMAP_TYPE_JPEG} }; + +const char *ACmp[] = { "NONE", "THRESHOLD", "UNKNOWN", "DITHER" }; + +const char *Mode0[] = { "COMBINED", "TEXEL0", + "TEXEL1", "PRIMITIVE", + "SHADE", "ENVIORNMENT", + "1", "NOISE", + "0", "0", + "0", "0", + "0", "0", + "0", "0" }; + +const char *Mode1[] = { "COMBINED", "TEXEL0", + "TEXEL1", "PRIMITIVE", + "SHADE", "ENVIORNMENT", + "CENTER", "K4", + "0", "0", + "0", "0", + "0", "0", + "0", "0" }; + +const char *Mode2[] = { "COMBINED", "TEXEL0", + "TEXEL1", "PRIMITIVE", + "SHADE", "ENVIORNMENT", + "SCALE", "COMBINED_ALPHA", + "T0_ALPHA", "T1_ALPHA", + "PRIM_ALPHA", "SHADE_ALPHA", + "ENV_ALPHA", "LOD_FRACTION", + "PRIM_LODFRAC", "K5", + "0", "0", + "0", "0", + "0", "0", + "0", "0", + "0", "0", + "0", "0", + "0", "0", + "0", "0" }; + +const char *Mode3[] = { "COMBINED", "TEXEL0", + "TEXEL1", "PRIMITIVE", + "SHADE", "ENVIORNMENT", + "1", "0" }; + +const char *Alpha0[] = { "COMBINED", "TEXEL0", + "TEXEL1", "PRIMITIVE", + "SHADE", "ENVIORNMENT", + "1", "0" }; + +#define Alpha1 Alpha0 +const char *Alpha2[] = { "LOD_FRACTION", "TEXEL0", + "TEXEL1", "PRIMITIVE", + "SHADE", "ENVIORNMENT", + "PRIM_LODFRAC", "0" }; +#define Alpha3 Alpha0 + +const char *FBLa[] = { "G_BL_CLR_IN", "G_BL_CLR_MEM", "G_BL_CLR_BL", "G_BL_CLR_FOG" }; +const char *FBLb[] = { "G_BL_A_IN", "G_BL_A_FOG", "G_BL_A_SHADE", "G_BL_0" }; +const char *FBLc[] = { "G_BL_CLR_IN", "G_BL_CLR_MEM", "G_BL_CLR_BL", "G_BL_CLR_FOG"}; +const char *FBLd[] = { "G_BL_1MA", "G_BL_A_MEM", "G_BL_1", "G_BL_0" }; + +const char *str_zs[] = { "G_ZS_PIXEL", "G_ZS_PRIM" }; + +const char *str_yn[] = { "NO", "YES" }; +const char *str_offon[] = { "OFF", "ON" }; + +const char *str_cull[] = { "DISABLE", "FRONT", "BACK", "BOTH" }; + +// I=intensity probably +const char *str_format[] = { "RGBA", "YUV", "CI", "IA", "I", "?", "?", "?" }; +const char *str_size[] = { "4bit", "8bit", "16bit", "32bit" }; +const char *str_cm[] = { "WRAP/NO CLAMP", "MIRROR/NO CLAMP", "WRAP/CLAMP", "MIRROR/CLAMP" }; +const char *str_lod[] = { "1", "2", "4", "8", "16", "32", "64", "128", "256", "512", "1024", "2048" }; +const char *str_aspect[] = { "1x8", "1x4", "1x2", "1x1", "2x1", "4x1", "8x1" }; + +const char *str_filter[] = { "Point Sampled", "Average (box)", "Bilinear" }; + +const char *str_tlut[] = { "TT_NONE", "TT_UNKNOWN", "TT_RGBA_16", "TT_IA_16" }; + +const char *str_dither[] = { "Pattern", "~Pattern", "Noise", "None" }; + +const char *CIStatus[] = { "ci_main", "ci_zimg", "ci_unknown", "ci_useless", + "ci_old_copy", "ci_copy", "ci_copy_self", + "ci_zcopy", "ci_aux", "ci_aux_copy" }; + +//static variables + +char out_buf[2048]; + +wxUint32 frame_count; // frame counter + +int ucode_error_report = TRUE; +int wrong_tile = -1; + +// ** RDP graphics functions ** +static void undef(); +static void spnoop(); + +static void rdp_noop(); +static void rdp_texrect(); +//static void rdp_texrectflip(); +static void rdp_loadsync(); +static void rdp_pipesync(); +static void rdp_tilesync(); +static void rdp_fullsync(); +static void rdp_setkeygb(); +static void rdp_setkeyr(); +static void rdp_setconvert(); +static void rdp_setscissor(); +static void rdp_setprimdepth(); +static void rdp_setothermode(); +static void rdp_loadtlut(); +static void rdp_settilesize(); +static void rdp_loadblock(); +static void rdp_loadtile(); +static void rdp_settile(); +static void rdp_fillrect(); +static void rdp_setfillcolor(); +static void rdp_setfogcolor(); +static void rdp_setblendcolor(); +static void rdp_setprimcolor(); +static void rdp_setenvcolor(); +static void rdp_setcombine(); +static void rdp_settextureimage(); +static void rdp_setdepthimage(); +static void rdp_setcolorimage(); +static void rdp_trifill(); +static void rdp_trishade(); +static void rdp_tritxtr(); +static void rdp_trishadetxtr(); +static void rdp_trifillz(); +static void rdp_trishadez(); +static void rdp_tritxtrz(); +static void rdp_trishadetxtrz(); +static void rdphalf_1(); +static void rdphalf_2(); +static void rdphalf_cont(); + +static void rsp_reserved0(); +static void rsp_reserved1(); +static void rsp_reserved2(); +static void rsp_reserved3(); + +static void ys_memrect(); + +wxUint8 microcode[4096]; +wxUint32 uc_crc; +void microcheck (); + +// ** UCODE FUNCTIONS ** +#include "ucode00.h" +#include "ucode01.h" +#include "ucode02.h" +#include "ucode03.h" +#include "ucode04.h" +#include "ucode05.h" +#include "ucode06.h" +#include "ucode07.h" +#include "ucode08.h" +#include "ucode09.h" +#include "ucode.h" +#include "ucode09rdp.h" +#include "turbo3D.h" + +static int reset = 0; +static int old_ucode = -1; + +void RDP::Reset() +{ + memset(this, 0, sizeof(RDP_Base)); + // set all vertex numbers + for (int i=0; i>2; i++) + { + uc_crc += ((wxUint32*)microcode)[i]; + } + + FRDP_E ("crc: %08lx\n", uc_crc); + +#ifdef LOG_UCODE + std::ofstream ucf; + ucf.open ("ucode.txt", std::ios::out | std::ios::binary); + char d; + for (i=0; i<0x400000; i++) + { + d = ((char*)gfx.RDRAM)[i^3]; + ucf.write (&d, 1); + } + ucf.close (); +#endif + + FRDP("ucode = %08lx\n", uc_crc); + + wxConfigBase * ini = wxConfigBase::Get(false); + ini->SetPath(wxT("/UCODE")); + wxString str; + str.Printf(wxT("%08lx"), uc_crc); + int uc = ini->Read(str, -2); + + if (uc == -2 && ucode_error_report) + { + settings.ucode = ini->Read(_T("/SETTINGS/ucode"), 0l); + + ReleaseGfx (); + str.Printf(_T("Error: uCode crc not found in INI, using currently selected uCode\n\n%08lx"), uc_crc); + wxMessageBox(str, _T("Error"), wxOK | wxICON_EXCLAMATION, GFXWindow); + + ucode_error_report = FALSE; // don't report any more ucode errors from this game + } + else if (uc == -1 && ucode_error_report) + { + settings.ucode = ini->Read(_T("/SETTINGS/ucode"), 0l); + + ReleaseGfx (); + str.Printf(_T("Error: Unsupported uCode!\n\ncrc: %08lx"), uc_crc); + wxMessageBox(str, _T("Error"), wxOK | wxICON_EXCLAMATION, GFXWindow); + + ucode_error_report = FALSE; // don't report any more ucode errors from this game + } + else + { + old_ucode = settings.ucode; + settings.ucode = uc; + FRDP("microcheck: old ucode: %d, new ucode: %d\n", old_ucode, uc); + if (uc_crc == 0x8d5735b2 || uc_crc == 0xb1821ed3 || uc_crc == 0x1118b3e0) //F3DLP.Rej ucode. perspective texture correction is not implemented + { + rdp.Persp_en = 1; + rdp.persp_supported = FALSE; + } + else if (settings.texture_correction) + rdp.persp_supported = TRUE; + } +} + +#ifdef __WINDOWS__ +static void GetClientSize(int * width, int * height) +{ +#ifdef __WINDOWS__ + RECT win_rect; + GetClientRect (gfx.hWnd, &win_rect); + *width = win_rect.right; + *height = win_rect.bottom; +#else + GFXWindow->GetClientSize(width, height); +#endif +} +#endif + +void drawNoFullscreenMessage() +{ +//need to find, how to do it on non-windows OS +//the code below will compile on any OS +//but it works only on windows, because +//I don't know, how to initialize GFXWindow on other OS +#ifdef __WINDOWS__ + LOG ("drawNoFullscreenMessage ()\n"); + if (rdp.window_changed) + { + rdp.window_changed = FALSE; + int width, height; + GetClientSize(&width, &height); + + wxClientDC dc(GFXWindow); + dc.SetBrush(*wxMEDIUM_GREY_BRUSH); + dc.SetTextForeground(*wxWHITE); + dc.SetBackgroundMode(wxTRANSPARENT); + dc.DrawRectangle(0, 0, width, height); + + wxCoord w, h; + wxString text = wxT("Glide64"); + dc.GetTextExtent(text, &w, &h); + wxCoord x = (width - w)/2; + wxCoord y = height/2 - h*4; + dc.DrawText(text, x, y); + + text = wxT("Gfx cannot be drawn in windowed mode"); + dc.GetTextExtent(text, &w, &h); + x = (width - w)/2; + y = height/2 - h; + dc.DrawText(text, x, y); + + text = wxT("Press Alt+Enter to switch to fullscreen"); + dc.GetTextExtent(text, &w, &h); + x = (width - w)/2; + y = (height - h)/2 + h*2; + dc.DrawText(text, x, y); + } +#endif +} + +static wxUint32 d_ul_x, d_ul_y, d_lr_x, d_lr_y; + +static void DrawPartFrameBufferToScreen() +{ + FB_TO_SCREEN_INFO fb_info; + fb_info.addr = rdp.cimg; + fb_info.size = rdp.ci_size; + fb_info.width = rdp.ci_width; + fb_info.height = rdp.ci_height; + fb_info.ul_x = d_ul_x; + fb_info.lr_x = d_lr_x; + fb_info.ul_y = d_ul_y; + fb_info.lr_y = d_lr_y; + fb_info.opaque = 0; + DrawFrameBufferToScreen(fb_info); + memset(gfx.RDRAM+rdp.cimg, 0, (rdp.ci_width*rdp.ci_height)<>1); +} + +#define RGBA16TO32(color) \ + ((color&1)?0xFF:0) | \ + ((wxUint32)((float)((color&0xF800) >> 11) / 31.0f * 255.0f) << 24) | \ + ((wxUint32)((float)((color&0x07C0) >> 6) / 31.0f * 255.0f) << 16) | \ + ((wxUint32)((float)((color&0x003E) >> 1) / 31.0f * 255.0f) << 8) + +static void CopyFrameBuffer (GrBuffer_t buffer = GR_BUFFER_BACKBUFFER) +{ + if (!fullscreen) + return; + FRDP ("CopyFrameBuffer: %08lx... ", rdp.cimg); + + // don't bother to write the stuff in asm... the slow part is the read from video card, + // not the copy. + + wxUint32 width = rdp.ci_width;//*gfx.VI_WIDTH_REG; + wxUint32 height; + if (fb_emulation_enabled && !(settings.hacks&hack_PPL)) + { + int ind = (rdp.ci_count > 0)?rdp.ci_count-1:0; + height = rdp.frame_buffers[ind].height; + } + else + { + height = rdp.ci_lower_bound; + if (settings.hacks&hack_PPL) + height -= rdp.ci_upper_bound; + } + FRDP ("width: %d, height: %d... ", width, height); + + if (rdp.scale_x < 1.1f) + { + wxUint16 * ptr_src = new wxUint16[width*height]; + if (grLfbReadRegion(buffer, + (wxUint32)rdp.offset_x, + (wxUint32)rdp.offset_y,//rdp.ci_upper_bound, + width, + height, + width<<1, + ptr_src)) + { + wxUint16 *ptr_dst = (wxUint16*)(gfx.RDRAM+rdp.cimg); + wxUint32 *ptr_dst32 = (wxUint32*)(gfx.RDRAM+rdp.cimg); + wxUint16 c; + + for (wxUint32 y=0; y 0) + c = (c&0xFFC0) | ((c&0x001F) << 1) | 1; + } + else + { + c = (c&0xFFC0) | ((c&0x001F) << 1) | 1; + } + if (rdp.ci_size == 2) + ptr_dst[(x + y * width)^1] = c; + else + ptr_dst32[x + y * width] = RGBA16TO32(c); + } + } + LRDP("ReadRegion. Framebuffer copy complete.\n"); + } + else + { + LRDP("Framebuffer copy failed.\n"); + } + delete[] ptr_src; + } + else + { + if (rdp.motionblur && fb_hwfbe_enabled) + { + return; + } + else + { + float scale_x = (settings.scr_res_x - rdp.offset_x*2.0f) / max(width, rdp.vi_width); + float scale_y = (settings.scr_res_y - rdp.offset_y*2.0f) / max(height, rdp.vi_height); + + FRDP("width: %d, height: %d, ul_y: %d, lr_y: %d, scale_x: %f, scale_y: %f, ci_width: %d, ci_height: %d\n",width, height, rdp.ci_upper_bound, rdp.ci_lower_bound, scale_x, scale_y, rdp.ci_width, rdp.ci_height); + GrLfbInfo_t info; + info.size = sizeof(GrLfbInfo_t); + + if (grLfbLock (GR_LFB_READ_ONLY, + buffer, + GR_LFBWRITEMODE_565, + GR_ORIGIN_UPPER_LEFT, + FXFALSE, + &info)) + { + wxUint16 *ptr_src = (wxUint16*)info.lfbPtr; + wxUint16 *ptr_dst = (wxUint16*)(gfx.RDRAM+rdp.cimg); + wxUint32 *ptr_dst32 = (wxUint32*)(gfx.RDRAM+rdp.cimg); + wxUint16 c; + wxUint32 stride = info.strideInBytes>>1; + + int read_alpha = settings.frame_buffer & fb_read_alpha; + if ((settings.hacks&hack_PMario) && rdp.frame_buffers[rdp.ci_count-1].status != ci_aux) + read_alpha = FALSE; + int x_start = 0, y_start = 0, x_end = width, y_end = height; + if (settings.hacks&hack_BAR) + { + x_start = 80, y_start = 24, x_end = 240, y_end = 86; + } + for (int y=y_start; yTryLock() == wxMUTEX_NO_ERROR ); } + + // returns true if mutex was successfully locked in ctor + bool IsOk() const + { return _isOk; } + + // unlock the mutex in dtor + ~SoftLocker() + { if ( IsOk() ) _mutex->Unlock(); } + +private: + bool _isOk; + wxMutex* _mutex; +}; + +/****************************************************************** +Function: ProcessDList +Purpose: This function is called when there is a Dlist to be +processed. (High level GFX list) +input: none +output: none +*******************************************************************/ +void DetectFrameBufferUsage (); +wxUint32 fbreads_front = 0; +wxUint32 fbreads_back = 0; +int cpu_fb_read_called = FALSE; +int cpu_fb_write_called = FALSE; +int cpu_fb_write = FALSE; +int cpu_fb_ignore = FALSE; +int CI_SET = TRUE; +wxUint32 ucode5_texshiftaddr = 0; +wxUint32 ucode5_texshiftcount = 0; +wxUint16 ucode5_texshift = 0; +int depth_buffer_fog; + +EXPORT void CALL ProcessDList(void) +{ + SoftLocker lock(mutexProcessDList); + if (!lock.IsOk()) //mutex is busy + { + if (!fullscreen) + drawNoFullscreenMessage(); + // Set an interrupt to allow the game to continue + *gfx.MI_INTR_REG |= 0x20; + gfx.CheckInterrupts(); + return; + } + + no_dlist = false; + update_screen_count = 0; + ChangeSize (); + +#ifdef ALTTAB_FIX + if (!hhkLowLevelKybd) + { + hhkLowLevelKybd = SetWindowsHookEx(WH_KEYBOARD_LL, + LowLevelKeyboardProc, hInstance, 0); + } +#endif + + LOG ("ProcessDList ()\n"); + + if (!fullscreen) + { + drawNoFullscreenMessage(); + // Set an interrupt to allow the game to continue + *gfx.MI_INTR_REG |= 0x20; + gfx.CheckInterrupts(); + } + + if (reset) + { + reset = 0; + if (settings.autodetect_ucode) + { + // Thanks to ZeZu for ucode autodetection!!! + wxUint32 startUcode = *(wxUint32*)(gfx.DMEM+0xFD0); + memcpy (microcode, gfx.RDRAM+startUcode, 4096); + microcheck (); + } + else + memset (microcode, 0, 4096); + } + else if ( ((old_ucode == ucode_S2DEX) && (settings.ucode == ucode_F3DEX)) || settings.force_microcheck) + { + wxUint32 startUcode = *(wxUint32*)(gfx.DMEM+0xFD0); + memcpy (microcode, gfx.RDRAM+startUcode, 4096); + microcheck (); + } + + if (exception) + return; + + // Switch to fullscreen? + if (to_fullscreen) + GoToFullScreen(); + + if (!fullscreen && !settings.run_in_window) + return; + + // Clear out the RDP log +#ifdef RDP_LOGGING + if (settings.logging && settings.log_clear) + { + CLOSE_RDP_LOG (); + OPEN_RDP_LOG (); + } +#endif + +#ifdef UNIMP_LOG + if (settings.log_unk && settings.unk_clear) + { + std::ofstream unimp; + unimp.open("unimp.txt"); + unimp.close(); + } +#endif + + //* Set states *// + if (settings.swapmode > 0) + SwapOK = TRUE; + rdp.updatescreen = 1; + + rdp.tri_n = 0; // 0 triangles so far this frame + rdp.debug_n = 0; + + rdp.model_i = 0; // 0 matrices so far in stack + //stack_size can be less then 32! Important for Silicon Vally. Thanks Orkin! + rdp.model_stack_size = min(32, (*(wxUint32*)(gfx.DMEM+0x0FE4))>>6); + if (rdp.model_stack_size == 0) + rdp.model_stack_size = 32; + rdp.Persp_en = TRUE; + rdp.fb_drawn = rdp.fb_drawn_front = FALSE; + rdp.update = 0x7FFFFFFF; // All but clear cache + rdp.geom_mode = 0; + rdp.acmp = 0; + rdp.maincimg[1] = rdp.maincimg[0]; + rdp.skip_drawing = FALSE; + rdp.s2dex_tex_loaded = FALSE; + rdp.bg_image_height = 0xFFFF; + fbreads_front = fbreads_back = 0; + rdp.fog_multiplier = rdp.fog_offset = 0; + rdp.zsrc = 0; + if (rdp.vi_org_reg != *gfx.VI_ORIGIN_REG) + rdp.tlut_mode = 0; //is it correct? + rdp.scissor_set = FALSE; + ucode5_texshiftaddr = ucode5_texshiftcount = 0; + cpu_fb_write = FALSE; + cpu_fb_read_called = FALSE; + cpu_fb_write_called = FALSE; + cpu_fb_ignore = FALSE; + d_ul_x = 0xffff; + d_ul_y = 0xffff; + d_lr_x = 0; + d_lr_y = 0; + depth_buffer_fog = TRUE; + + //analize possible frame buffer usage + if (fb_emulation_enabled) + DetectFrameBufferUsage(); + if (!(settings.hacks&hack_Lego) || rdp.num_of_ci > 1) + rdp.last_bg = 0; + //* End of set states *// + + // Get the start of the display list and the length of it + wxUint32 dlist_start = *(wxUint32*)(gfx.DMEM+0xFF0); + wxUint32 dlist_length = *(wxUint32*)(gfx.DMEM+0xFF4); + FRDP("--- NEW DLIST --- crc: %08lx, ucode: %d, fbuf: %08lx, fbuf_width: %d, dlist start: %08lx, dlist_length: %d, x_scale: %f, y_scale: %f\n", uc_crc, settings.ucode, *gfx.VI_ORIGIN_REG, *gfx.VI_WIDTH_REG, dlist_start, dlist_length, (*gfx.VI_X_SCALE_REG & 0xFFF)/1024.0f, (*gfx.VI_Y_SCALE_REG & 0xFFF)/1024.0f); + FRDP_E("--- NEW DLIST --- crc: %08lx, ucode: %d, fbuf: %08lx\n", uc_crc, settings.ucode, *gfx.VI_ORIGIN_REG); + + if (cpu_fb_write == TRUE) + DrawPartFrameBufferToScreen(); + if ((settings.hacks&hack_Tonic) && dlist_length < 16) + { + rdp_fullsync(); + FRDP_E("DLIST is too short!\n"); + return; + } + + // Start executing at the start of the display list + rdp.pc_i = 0; + rdp.pc[rdp.pc_i] = dlist_start; + rdp.dl_count = -1; + rdp.halt = 0; + wxUint32 a; + + // catches exceptions so that it doesn't freeze +#ifdef CATCH_EXCEPTIONS + try { +#endif + if (settings.ucode == ucode_Turbo3d) + { + Turbo3D(); + } + else + { + // MAIN PROCESSING LOOP + do { + + // Get the address of the next command + a = rdp.pc[rdp.pc_i] & BMASK; + + // Load the next command and its input + rdp.cmd0 = ((wxUint32*)gfx.RDRAM)[a>>2]; // \ Current command, 64 bit + rdp.cmd1 = ((wxUint32*)gfx.RDRAM)[(a>>2)+1]; // / + // cmd2 and cmd3 are filled only when needed, by the function that needs them + + // Output the address before the command +#ifdef LOG_COMMANDS + FRDP ("%08lx (c0:%08lx, c1:%08lx): ", a, rdp.cmd0, rdp.cmd1); +#else + FRDP ("%08lx: ", a); +#endif + + // Go to the next instruction + rdp.pc[rdp.pc_i] = (a+8) & BMASK; + +#ifdef PERFORMANCE + perf_cur = wxDateTime::UNow(); +#endif + // Process this instruction + gfx_instruction[settings.ucode][rdp.cmd0>>24] (); + + // check DL counter + if (rdp.dl_count != -1) + { + rdp.dl_count --; + if (rdp.dl_count == 0) + { + rdp.dl_count = -1; + + LRDP("End of DL\n"); + rdp.pc_i --; + } + } + +#ifdef PERFORMANCE + perf_next = wxDateTime::UNow(); + sprintf (out_buf, "perf %08lx: %016I64d\n", a-8, (perf_next-perf_cur).Format(_T("%l")).mb_str()); + rdp_log << out_buf; +#endif + + } while (!rdp.halt); + } +#ifdef CATCH_EXCEPTIONS + } catch (...) { + + if (fullscreen) + { + ReleaseGfx (); + rdp_reset (); +#ifdef TEXTURE_FILTER + if (settings.ghq_use) + { + ext_ghq_shutdown(); + settings.ghq_use = 0; + } +#endif + } + if (wxMessageBox(_T("The GFX plugin caused an exception and has been disabled.\nWould you like to turn it back on and attempt to continue?"), _T("Glide64 Exception"), wxYES_NO|wxICON_EXCLAMATION, GFXWindow) == wxNO) + exception = TRUE; + else + to_fullscreen = TRUE; + return; + } +#endif + + if (fb_emulation_enabled) + { + rdp.scale_x = rdp.scale_x_bak; + rdp.scale_y = rdp.scale_y_bak; + } + if (settings.frame_buffer & fb_ref) + CopyFrameBuffer (); + if (rdp.cur_image) + CloseTextureBuffer(rdp.read_whole_frame && ((settings.hacks&hack_PMario) || rdp.swap_ci_index >= 0)); + + if ((settings.hacks&hack_TGR2) && rdp.vi_org_reg != *gfx.VI_ORIGIN_REG && CI_SET) + { + newSwapBuffers (); + CI_SET = FALSE; + } + LRDP("ProcessDList end\n"); +} + +// undef - undefined instruction, always ignore +static void undef() +{ + FRDP_E("** undefined ** (%08lx)\n", rdp.cmd0); + FRDP("** undefined ** (%08lx) - IGNORED\n", rdp.cmd0); +#ifdef _ENDUSER_RELEASE_ + *gfx.MI_INTR_REG |= 0x20; + gfx.CheckInterrupts(); + rdp.halt = 1; +#endif +} + +// spnoop - no operation, always ignore +static void spnoop() +{ + LRDP("spnoop\n"); +} + +// noop - no operation, always ignore +static void rdp_noop() +{ + LRDP("noop\n"); +} + +static void ys_memrect () +{ + wxUint32 tile = (wxUint16)((rdp.cmd1 & 0x07000000) >> 24); + + wxUint32 lr_x = (wxUint16)((rdp.cmd0 & 0x00FFF000) >> 14); + wxUint32 lr_y = (wxUint16)((rdp.cmd0 & 0x00000FFF) >> 2); + wxUint32 ul_x = (wxUint16)((rdp.cmd1 & 0x00FFF000) >> 14); + wxUint32 ul_y = (wxUint16)((rdp.cmd1 & 0x00000FFF) >> 2); + + if (lr_y > rdp.scissor_o.lr_y) + lr_y = rdp.scissor_o.lr_y; + wxUint32 off_x = ((rdp.cmd2 & 0xFFFF0000) >> 16) >> 5; + wxUint32 off_y = (rdp.cmd2 & 0x0000FFFF) >> 5; + + FRDP ("memrect (%d, %d, %d, %d), ci_width: %d", ul_x, ul_y, lr_x, lr_y, rdp.ci_width); + if (off_x > 0) + FRDP (" off_x: %d", off_x); + if (off_y > 0) + FRDP (" off_y: %d", off_y); + LRDP("\n"); + + wxUint32 y, width = lr_x - ul_x; + wxUint32 tex_width = rdp.tiles[tile].line << 3; + wxUint8 * texaddr = gfx.RDRAM + rdp.addr[rdp.tiles[tile].t_mem] + tex_width*off_y + off_x; + wxUint8 * fbaddr = gfx.RDRAM + rdp.cimg + ul_x; + + for (y = ul_y; y < lr_y; y++) { + wxUint8 *src = texaddr + (y - ul_y) * tex_width; + wxUint8 *dst = fbaddr + y * rdp.ci_width; + memcpy (dst, src, width); + } +} + +static void pm_palette_mod () +{ + wxUint8 envr = (wxUint8)((float)((rdp.env_color >> 24)&0xFF)/255.0f*31.0f); + wxUint8 envg = (wxUint8)((float)((rdp.env_color >> 16)&0xFF)/255.0f*31.0f); + wxUint8 envb = (wxUint8)((float)((rdp.env_color >> 8)&0xFF)/255.0f*31.0f); + wxUint16 env16 = (wxUint16)((envr<<11)|(envg<<6)|(envb<<1)|1); + wxUint8 prmr = (wxUint8)((float)((rdp.prim_color >> 24)&0xFF)/255.0f*31.0f); + wxUint8 prmg = (wxUint8)((float)((rdp.prim_color >> 16)&0xFF)/255.0f*31.0f); + wxUint8 prmb = (wxUint8)((float)((rdp.prim_color >> 8)&0xFF)/255.0f*31.0f); + wxUint16 prim16 = (wxUint16)((prmr<<11)|(prmg<<6)|(prmb<<1)|1); + wxUint16 * dst = (wxUint16*)(gfx.RDRAM+rdp.cimg); + for (int i = 0; i < 16; i++) + { + dst[i^1] = (rdp.pal_8[i]&1) ? prim16 : env16; + } + LRDP("Texrect palette modification\n"); +} + +static void pd_zcopy () +{ + wxUint16 ul_x = (wxUint16)((rdp.cmd1 & 0x00FFF000) >> 14); + wxUint16 lr_x = (wxUint16)((rdp.cmd0 & 0x00FFF000) >> 14) + 1; + wxUint16 ul_u = (wxUint16)((rdp.cmd2 & 0xFFFF0000) >> 21) + 1; + wxUint16 *ptr_dst = (wxUint16*)(gfx.RDRAM+rdp.cimg); + wxUint16 width = lr_x - ul_x; + wxUint16 * ptr_src = ((wxUint16*)rdp.tmem)+ul_u; + wxUint16 c; + for (wxUint16 x=0; x> 8); + ptr_dst[(ul_x+x)^1] = c; + // FRDP("dst[%d]=%04lx \n", (x + ul_x)^1, c); + } +} + +static void DrawDepthBufferFog() +{ + if (rdp.zi_width < 200) + return; + FB_TO_SCREEN_INFO fb_info; + fb_info.addr = rdp.zimg; + fb_info.size = 2; + fb_info.width = rdp.zi_width; + fb_info.height = rdp.ci_height; + fb_info.ul_x = rdp.scissor_o.ul_x; + fb_info.lr_x = rdp.scissor_o.lr_x; + fb_info.ul_y = rdp.scissor_o.ul_y; + fb_info.lr_y = rdp.scissor_o.lr_y; + fb_info.opaque = 0; + DrawDepthBufferToScreen(fb_info); +} + +static void rdp_texrect() +{ + if (!rdp.LLE) + { + wxUint32 a = rdp.pc[rdp.pc_i]; + wxUint8 cmdHalf1 = gfx.RDRAM[a+3]; + wxUint8 cmdHalf2 = gfx.RDRAM[a+11]; + a >>= 2; + if ((cmdHalf1 == 0xE1 && cmdHalf2 == 0xF1) || (cmdHalf1 == 0xB4 && cmdHalf2 == 0xB3) || (cmdHalf1 == 0xB3 && cmdHalf2 == 0xB2)) + { + //gSPTextureRectangle + rdp.cmd2 = ((wxUint32*)gfx.RDRAM)[a+1]; + rdp.cmd3 = ((wxUint32*)gfx.RDRAM)[a+3]; + rdp.pc[rdp.pc_i] += 16; + } + else + { + //gDPTextureRectangle + if (settings.hacks&hack_ASB) + rdp.cmd2 = 0; + else + rdp.cmd2 = ((wxUint32*)gfx.RDRAM)[a+0]; + rdp.cmd3 = ((wxUint32*)gfx.RDRAM)[a+1]; + rdp.pc[rdp.pc_i] += 8; + } + } + if ((settings.hacks&hack_Yoshi) && settings.ucode == ucode_S2DEX) + { + ys_memrect(); + return; + } + + if (rdp.skip_drawing || (!fb_emulation_enabled && (rdp.cimg == rdp.zimg))) + { + if ((settings.hacks&hack_PMario) && rdp.ci_status == ci_useless) + { + pm_palette_mod (); + } + else + { + LRDP("Texrect skipped\n"); + } + return; + } + + if ((settings.ucode == ucode_CBFD) && rdp.cur_image && rdp.cur_image->format) + { + //FRDP("Wrong Texrect. texaddr: %08lx, cimg: %08lx, cimg_end: %08lx\n", rdp.timg.addr, rdp.maincimg[1].addr, rdp.maincimg[1].addr+rdp.ci_width*rdp.ci_height*rdp.ci_size); + LRDP("Shadow texrect is skipped.\n"); + rdp.tri_n += 2; + return; + } + + if ((settings.ucode == ucode_PerfectDark) && (rdp.frame_buffers[rdp.ci_count-1].status == ci_zcopy)) + { + pd_zcopy (); + LRDP("Depth buffer copied.\n"); + rdp.tri_n += 2; + return; + } + + if ((rdp.othermode_l >> 16) == 0x3c18 && rdp.cycle1 == 0x03ffffff && rdp.cycle2 == 0x01ff1fff) //depth image based fog + { + if (!depth_buffer_fog) + return; + if (settings.fog) + DrawDepthBufferFog(); + depth_buffer_fog = FALSE; + return; + } + + // FRDP ("rdp.cycle1 %08lx, rdp.cycle2 %08lx\n", rdp.cycle1, rdp.cycle2); + + float ul_x, ul_y, lr_x, lr_y; + if (rdp.cycle_mode == 2) + { + ul_x = max(0.0f, (short)((rdp.cmd1 & 0x00FFF000) >> 14)); + ul_y = max(0.0f, (short)((rdp.cmd1 & 0x00000FFF) >> 2)); + lr_x = max(0.0f, (short)((rdp.cmd0 & 0x00FFF000) >> 14)); + lr_y = max(0.0f, (short)((rdp.cmd0 & 0x00000FFF) >> 2)); + } + else + { + ul_x = max(0.0f, ((short)((rdp.cmd1 & 0x00FFF000) >> 12)) / 4.0f); + ul_y = max(0.0f, ((short)(rdp.cmd1 & 0x00000FFF)) / 4.0f); + lr_x = max(0.0f, ((short)((rdp.cmd0 & 0x00FFF000) >> 12)) / 4.0f); + lr_y = max(0.0f, ((short)(rdp.cmd0 & 0x00000FFF)) / 4.0f); + } + + if (ul_x >= lr_x) + { + FRDP("Wrong Texrect: ul_x: %f, lr_x: %f\n", ul_x, lr_x); + return; + } + + if (rdp.cycle_mode > 1) + { + lr_x += 1.0f; + lr_y += 1.0f; + } else if (lr_y - ul_y < 1.0f) + lr_y = ceil(lr_y); + + if (settings.increase_texrect_edge) + { + if (floor(lr_x) != lr_x) + lr_x = ceil(lr_x); + if (floor(lr_y) != lr_y) + lr_y = ceil(lr_y); + } + + //* + if (rdp.tbuff_tex && (settings.frame_buffer & fb_optimize_texrect)) + { + LRDP("Attempt to optimize texrect\n"); + if (!rdp.tbuff_tex->drawn) + { + DRAWIMAGE d; + d.imageX = 0; + d.imageW = (wxUint16)rdp.tbuff_tex->width; + d.frameX = (wxUint16)ul_x; + d.frameW = (wxUint16)(rdp.tbuff_tex->width); + + d.imageY = 0; + d.imageH = (wxUint16)rdp.tbuff_tex->height; + d.frameY = (wxUint16)ul_y; + d.frameH = (wxUint16)(rdp.tbuff_tex->height); + FRDP("texrect. ul_x: %d, ul_y: %d, lr_x: %d, lr_y: %d, width: %d, height: %d\n", ul_x, ul_y, lr_x, lr_y, rdp.tbuff_tex->width, rdp.tbuff_tex->height); + d.scaleX = 1.0f; + d.scaleY = 1.0f; + DrawHiresImage(d, rdp.tbuff_tex->width == rdp.ci_width); + rdp.tbuff_tex->drawn = TRUE; + } + return; + } + //*/ + // framebuffer workaround for Zelda: MM LOT + if ((rdp.othermode_l & 0xFFFF0000) == 0x0f5a0000) + return; + + /*Gonetz*/ + //hack for Zelda MM. it removes black texrects which cover all geometry in "Link meets Zelda" cut scene + if ((settings.hacks&hack_Zelda) && rdp.timg.addr >= rdp.cimg && rdp.timg.addr < rdp.ci_end) + { + FRDP("Wrong Texrect. texaddr: %08lx, cimg: %08lx, cimg_end: %08lx\n", rdp.cur_cache[0]->addr, rdp.cimg, rdp.cimg+rdp.ci_width*rdp.ci_height*2); + rdp.tri_n += 2; + return; + } + //* + //hack for Banjo2. it removes black texrects under Banjo + if (!fb_hwfbe_enabled && ((rdp.cycle1 << 16) | (rdp.cycle2 & 0xFFFF)) == 0xFFFFFFFF && (rdp.othermode_l & 0xFFFF0000) == 0x00500000) + { + rdp.tri_n += 2; + return; + } + //*/ + //* + //remove motion blur in night vision + if ((settings.ucode == ucode_PerfectDark) && (rdp.maincimg[1].addr != rdp.maincimg[0].addr) && (rdp.timg.addr >= rdp.maincimg[1].addr) && (rdp.timg.addr < (rdp.maincimg[1].addr+rdp.ci_width*rdp.ci_height*rdp.ci_size))) + { + if (fb_emulation_enabled) + if (rdp.frame_buffers[rdp.ci_count-1].status == ci_copy_self) + { + //FRDP("Wrong Texrect. texaddr: %08lx, cimg: %08lx, cimg_end: %08lx\n", rdp.timg.addr, rdp.maincimg[1], rdp.maincimg[1]+rdp.ci_width*rdp.ci_height*rdp.ci_size); + LRDP("Wrong Texrect.\n"); + rdp.tri_n += 2; + return; + } + } + //*/ + + int i; + + wxUint32 tile = (wxUint16)((rdp.cmd1 & 0x07000000) >> 24); + + rdp.texrecting = 1; + + wxUint32 prev_tile = rdp.cur_tile; + rdp.cur_tile = tile; + + const float Z = set_sprite_combine_mode (); + + rdp.texrecting = 0; + + if (!rdp.cur_cache[0]) + { + rdp.cur_tile = prev_tile; + rdp.tri_n += 2; + return; + } + // **** + // ** Texrect offset by Gugaman ** + // + //integer representation of texture coordinate. + //needed to detect and avoid overflow after shifting + wxInt32 off_x_i = (rdp.cmd2 >> 16) & 0xFFFF; + wxInt32 off_y_i = rdp.cmd2 & 0xFFFF; + float dsdx = (float)((short)((rdp.cmd3 & 0xFFFF0000) >> 16)) / 1024.0f; + float dtdy = (float)((short)(rdp.cmd3 & 0x0000FFFF)) / 1024.0f; + if (off_x_i & 0x8000) //check for sign bit + off_x_i |= ~0xffff; //make it negative + //the same as for off_x_i + if (off_y_i & 0x8000) + off_y_i |= ~0xffff; + + if (rdp.cycle_mode == 2) + dsdx /= 4.0f; + + float s_ul_x = ul_x * rdp.scale_x + rdp.offset_x; + float s_lr_x = lr_x * rdp.scale_x + rdp.offset_x; + float s_ul_y = ul_y * rdp.scale_y + rdp.offset_y; + float s_lr_y = lr_y * rdp.scale_y + rdp.offset_y; + + FRDP("texrect (%.2f, %.2f, %.2f, %.2f), tile: %d, #%d, #%d\n", ul_x, ul_y, lr_x, lr_y, tile, rdp.tri_n, rdp.tri_n+1); + FRDP ("(%f, %f) -> (%f, %f), s: (%d, %d) -> (%d, %d)\n", s_ul_x, s_ul_y, s_lr_x, s_lr_y, rdp.scissor.ul_x, rdp.scissor.ul_y, rdp.scissor.lr_x, rdp.scissor.lr_y); + FRDP("\toff_x: %f, off_y: %f, dsdx: %f, dtdy: %f\n", off_x_i/32.0f, off_y_i/32.0f, dsdx, dtdy); + + float off_size_x; + float off_size_y; + + if ( ((rdp.cmd0>>24)&0xFF) == 0xE5 ) //texrectflip + { +#ifdef TEXTURE_FILTER + if (rdp.cur_cache[0]->is_hires_tex) + { + off_size_x = (float)((lr_y - ul_y) * dsdx); + off_size_y = (float)((lr_x - ul_x) * dtdy); + } + else +#endif + { + off_size_x = (lr_y - ul_y - 1) * dsdx; + off_size_y = (lr_x - ul_x - 1) * dtdy; + } + } + else + { +#ifdef TEXTURE_FILTER + if (rdp.cur_cache[0]->is_hires_tex) + { + off_size_x = (float)((lr_x - ul_x) * dsdx); + off_size_y = (float)((lr_y - ul_y) * dtdy); + } + else +#endif + { + off_size_x = (lr_x - ul_x - 1) * dsdx; + off_size_y = (lr_y - ul_y - 1) * dtdy; + } + } + + struct { + float ul_u, ul_v, lr_u, lr_v; + } texUV[2]; //struct for texture coordinates + //angrylion's macro, helps to cut overflowed values. + #define SIGN16(x) (((x) & 0x8000) ? ((x) | ~0xffff) : ((x) & 0xffff)) + + //calculate texture coordinates + for (int i = 0; i < 2; i++) + { + if (rdp.cur_cache[i] && (rdp.tex & (i+1))) + { + float sx = 1, sy = 1; + int x_i = off_x_i, y_i = off_y_i; + TILE & tile = rdp.tiles[rdp.cur_tile + i]; + //shifting + if (tile.shift_s) + { + if (tile.shift_s > 10) + { + wxUint8 iShift = (16 - tile.shift_s); + x_i <<= iShift; + sx = (float)(1 << iShift); + } + else + { + wxUint8 iShift = tile.shift_s; + x_i >>= iShift; + sx = 1.0f/(float)(1 << iShift); + } + } + if (tile.shift_t) + { + if (tile.shift_t > 10) + { + wxUint8 iShift = (16 - tile.shift_t); + y_i <<= iShift; + sy = (float)(1 << iShift); + } + else + { + wxUint8 iShift = tile.shift_t; + y_i >>= iShift; + sy = 1.0f/(float)(1 << iShift); + } + } + + if (rdp.aTBuffTex[i]) //hwfbe texture + { + float t0_off_x; + float t0_off_y; + if (off_x_i + off_y_i == 0) + { + t0_off_x = tile.ul_s; + t0_off_y = tile.ul_t; + } + else + { + t0_off_x = off_x_i/32.0f; + t0_off_y = off_y_i/32.0f; + } + t0_off_x += rdp.aTBuffTex[i]->u_shift;// + tile.ul_s; //commented for Paper Mario motion blur + t0_off_y += rdp.aTBuffTex[i]->v_shift;// + tile.ul_t; + texUV[i].ul_u = t0_off_x * sx; + texUV[i].ul_v = t0_off_y * sy; + + texUV[i].lr_u = texUV[i].ul_u + off_size_x * sx; + texUV[i].lr_v = texUV[i].ul_v + off_size_y * sy; + + texUV[i].ul_u *= rdp.aTBuffTex[i]->u_scale; + texUV[i].ul_v *= rdp.aTBuffTex[i]->v_scale; + texUV[i].lr_u *= rdp.aTBuffTex[i]->u_scale; + texUV[i].lr_v *= rdp.aTBuffTex[i]->v_scale; + FRDP("tbuff_tex[%d] ul_u: %f, ul_v: %f, lr_u: %f, lr_v: %f\n", + i, texUV[i].ul_u, texUV[i].ul_v, texUV[i].lr_u, texUV[i].lr_v); + } + else //common case + { + //kill 10.5 format overflow by SIGN16 macro + texUV[i].ul_u = SIGN16(x_i) / 32.0f; + texUV[i].ul_v = SIGN16(y_i) / 32.0f; + + texUV[i].ul_u -= tile.f_ul_s; + texUV[i].ul_v -= tile.f_ul_t; + + texUV[i].lr_u = texUV[i].ul_u + off_size_x * sx; + texUV[i].lr_v = texUV[i].ul_v + off_size_y * sy; + + texUV[i].ul_u = rdp.cur_cache[i]->c_off + rdp.cur_cache[i]->c_scl_x * texUV[i].ul_u; + texUV[i].lr_u = rdp.cur_cache[i]->c_off + rdp.cur_cache[i]->c_scl_x * texUV[i].lr_u; + texUV[i].ul_v = rdp.cur_cache[i]->c_off + rdp.cur_cache[i]->c_scl_y * texUV[i].ul_v; + texUV[i].lr_v = rdp.cur_cache[i]->c_off + rdp.cur_cache[i]->c_scl_y * texUV[i].lr_v; + } + } + else + { + texUV[i].ul_u = texUV[i].ul_v = texUV[i].lr_u = texUV[i].lr_v = 0; + } + } + rdp.cur_tile = prev_tile; + + // **** + + FRDP (" scissor: (%d, %d) -> (%d, %d)\n", rdp.scissor.ul_x, rdp.scissor.ul_y, rdp.scissor.lr_x, rdp.scissor.lr_y); + + CCLIP2 (s_ul_x, s_lr_x, texUV[0].ul_u, texUV[0].lr_u, texUV[1].ul_u, texUV[1].lr_u, (float)rdp.scissor.ul_x, (float)rdp.scissor.lr_x); + CCLIP2 (s_ul_y, s_lr_y, texUV[0].ul_v, texUV[0].lr_v, texUV[1].ul_v, texUV[1].lr_v, (float)rdp.scissor.ul_y, (float)rdp.scissor.lr_y); + + FRDP (" draw at: (%f, %f) -> (%f, %f)\n", s_ul_x, s_ul_y, s_lr_x, s_lr_y); + + VERTEX vstd[4] = { + { s_ul_x, s_ul_y, Z, 1.0f, texUV[0].ul_u, texUV[0].ul_v, texUV[1].ul_u, texUV[1].ul_v, {0, 0, 0, 0}, 255 }, + { s_lr_x, s_ul_y, Z, 1.0f, texUV[0].lr_u, texUV[0].ul_v, texUV[1].lr_u, texUV[1].ul_v, {0, 0, 0, 0}, 255 }, + { s_ul_x, s_lr_y, Z, 1.0f, texUV[0].ul_u, texUV[0].lr_v, texUV[1].ul_u, texUV[1].lr_v, {0, 0, 0, 0}, 255 }, + { s_lr_x, s_lr_y, Z, 1.0f, texUV[0].lr_u, texUV[0].lr_v, texUV[1].lr_u, texUV[1].lr_v, {0, 0, 0, 0}, 255 } }; + + if ( ((rdp.cmd0>>24)&0xFF) == 0xE5 ) //texrectflip + { + vstd[1].u0 = texUV[0].ul_u; + vstd[1].v0 = texUV[0].lr_v; + vstd[1].u1 = texUV[1].ul_u; + vstd[1].v1 = texUV[1].lr_v; + + vstd[2].u0 = texUV[0].lr_u; + vstd[2].v0 = texUV[0].ul_v; + vstd[2].u1 = texUV[1].lr_u; + vstd[2].v1 = texUV[1].ul_v; + } + + VERTEX *vptr = vstd; + int n_vertices = 4; + + VERTEX *vnew = 0; + // for (int j =0; j < 4; j++) + // FRDP("v[%d] u0: %f, v0: %f, u1: %f, v1: %f\n", j, vstd[j].u0, vstd[j].v0, vstd[j].u1, vstd[j].v1); + + + if (!rdp.aTBuffTex[0] && rdp.cur_cache[0]->splits != 1) + { + // ** LARGE TEXTURE HANDLING ** + // *VERY* simple algebra for texrects + float min_u, min_x, max_u, max_x; + if (vstd[0].u0 < vstd[1].u0) + { + min_u = vstd[0].u0; + min_x = vstd[0].x; + max_u = vstd[1].u0; + max_x = vstd[1].x; + } + else + { + min_u = vstd[1].u0; + min_x = vstd[1].x; + max_u = vstd[0].u0; + max_x = vstd[0].x; + } + + int start_u_256, end_u_256; + start_u_256 = (int)min_u >> 8; + end_u_256 = (int)max_u >> 8; + //FRDP(" min_u: %f, max_u: %f start: %d, end: %d\n", min_u, max_u, start_u_256, end_u_256); + + int splitheight = rdp.cur_cache[0]->splitheight; + + int num_verts_line = 2 + ((end_u_256-start_u_256)<<1); + n_vertices = num_verts_line << 1; + vnew = new VERTEX [n_vertices]; + vptr = vnew; + + vnew[0] = vstd[0]; + vnew[0].u0 -= 256.0f * start_u_256; + vnew[0].v0 += splitheight * start_u_256; + vnew[0].u1 -= 256.0f * start_u_256; + vnew[0].v1 += splitheight * start_u_256; + vnew[1] = vstd[2]; + vnew[1].u0 -= 256.0f * start_u_256; + vnew[1].v0 += splitheight * start_u_256; + vnew[1].u1 -= 256.0f * start_u_256; + vnew[1].v1 += splitheight * start_u_256; + vnew[n_vertices-2] = vstd[1]; + vnew[n_vertices-2].u0 -= 256.0f * end_u_256; + vnew[n_vertices-2].v0 += splitheight * end_u_256; + vnew[n_vertices-2].u1 -= 256.0f * end_u_256; + vnew[n_vertices-2].v1 += splitheight * end_u_256; + vnew[n_vertices-1] = vstd[3]; + vnew[n_vertices-1].u0 -= 256.0f * end_u_256; + vnew[n_vertices-1].v0 += splitheight * end_u_256; + vnew[n_vertices-1].u1 -= 256.0f * end_u_256; + vnew[n_vertices-1].v1 += splitheight * end_u_256; + + // find the equation of the line of u,x + float m = (max_x - min_x) / (max_u - min_u); // m = delta x / delta u + float b = min_x - m * min_u; // b = y - m * x + + for (i=start_u_256; i 12) + { + float texbound = (float)(splitheight << 1); + for (int k = 0; k < n_vertices; k ++) + { + if (vnew[k].v0 > texbound) + vnew[k].v0 = (float)fmod(vnew[k].v0, texbound); + } + } + //*/ + } + + AllowShadeMods (vptr, n_vertices); + for (i=0; i= RDP::fog_blend) + { + float fog; + if (rdp.fog_mode == RDP::fog_blend) + fog = 1.0f/max(1, rdp.fog_color&0xFF); + else + fog = 1.0f/max(1, (~rdp.fog_color)&0xFF); + for (i = 0; i < n_vertices; i++) + { + vptr[i].f = fog; + } + grFogMode (GR_FOG_WITH_TABLE_ON_FOGCOORD_EXT); + } + + ConvertCoordsConvert (vptr, n_vertices); + + if (settings.wireframe) + { + SetWireframeCol (); + grDrawLine (&vstd[0], &vstd[2]); + grDrawLine (&vstd[2], &vstd[1]); + grDrawLine (&vstd[1], &vstd[0]); + grDrawLine (&vstd[2], &vstd[3]); + grDrawLine (&vstd[3], &vstd[1]); + } + else + { + grDrawVertexArrayContiguous (GR_TRIANGLE_STRIP, n_vertices, vptr, sizeof(VERTEX)); + } + + if (_debugger.capture) + { + VERTEX vl[3]; + vl[0] = vstd[0]; + vl[1] = vstd[2]; + vl[2] = vstd[1]; + add_tri (vl, 3, TRI_TEXRECT); + rdp.tri_n ++; + vl[0] = vstd[2]; + vl[1] = vstd[3]; + vl[2] = vstd[1]; + add_tri (vl, 3, TRI_TEXRECT); + rdp.tri_n ++; + } + else + rdp.tri_n += 2; + } + else + { + rdp.tri_n += 2; + } + + delete[] vnew; +} + +static void rdp_loadsync() +{ + LRDP("loadsync - ignored\n"); +} + +static void rdp_pipesync() +{ + LRDP("pipesync - ignored\n"); +} + +static void rdp_tilesync() +{ + LRDP("tilesync - ignored\n"); +} + +static void rdp_fullsync() +{ + // Set an interrupt to allow the game to continue + *gfx.MI_INTR_REG |= 0x20; + gfx.CheckInterrupts(); + LRDP("fullsync\n"); +} + +static void rdp_setkeygb() +{ + wxUint32 sB = rdp.cmd1&0xFF; + wxUint32 cB = (rdp.cmd1>>8)&0xFF; + wxUint32 sG = (rdp.cmd1>>16)&0xFF; + wxUint32 cG = (rdp.cmd1>>24)&0xFF; + rdp.SCALE = (rdp.SCALE&0xFF0000FF) | (sG<<16) | (sB<<8); + rdp.CENTER = (rdp.CENTER&0xFF0000FF) | (cG<<16) | (cB<<8); + FRDP("setkeygb. cG=%02lx, sG=%02lx, cB=%02lx, sB=%02lx\n", cG, sG, cB, sB); +} + +static void rdp_setkeyr() +{ + wxUint32 sR = rdp.cmd1&0xFF; + wxUint32 cR = (rdp.cmd1>>8)&0xFF; + rdp.SCALE = (rdp.SCALE&0x00FFFFFF) | (sR<<24); + rdp.CENTER = (rdp.CENTER&0x00FFFFFF) | (cR<<24); + FRDP("setkeyr. cR=%02lx, sR=%02lx\n", cR, sR); +} + +static void rdp_setconvert() +{ + /* + rdp.YUV_C0 = 1.1647f ; + rdp.YUV_C1 = 0.79931f ; + rdp.YUV_C2 = -0.1964f ; + rdp.YUV_C3 = -0.40651f; + rdp.YUV_C4 = 1.014f ; + */ + rdp.K4 = (wxUint8)(rdp.cmd1>>9)&0x1FF; + rdp.K5 = (wxUint8)(rdp.cmd1&0x1FF); + // RDP_E("setconvert - IGNORED\n"); + FRDP("setconvert. K4=%02lx K5=%02lx\n", rdp.K4, rdp.K5); +} + +// +// setscissor - sets the screen clipping rectangle +// + +static void rdp_setscissor() +{ + // clipper resolution is 320x240, scale based on computer resolution + rdp.scissor_o.ul_x = /*min(*/(wxUint32)(((rdp.cmd0 & 0x00FFF000) >> 14))/*, 320)*/; + rdp.scissor_o.ul_y = /*min(*/(wxUint32)(((rdp.cmd0 & 0x00000FFF) >> 2))/*, 240)*/; + rdp.scissor_o.lr_x = /*min(*/(wxUint32)(((rdp.cmd1 & 0x00FFF000) >> 14))/*, 320)*/; + rdp.scissor_o.lr_y = /*min(*/(wxUint32)(((rdp.cmd1 & 0x00000FFF) >> 2))/*, 240)*/; + + rdp.ci_upper_bound = rdp.scissor_o.ul_y; + rdp.ci_lower_bound = rdp.scissor_o.lr_y; + rdp.scissor_set = TRUE; + + FRDP("setscissor: (%d,%d) -> (%d,%d)\n", rdp.scissor_o.ul_x, rdp.scissor_o.ul_y, + rdp.scissor_o.lr_x, rdp.scissor_o.lr_y); + + rdp.update |= UPDATE_SCISSOR; + + if (rdp.view_scale[0] == 0) //viewport is not set? + { + rdp.view_scale[0] = (rdp.scissor_o.lr_x>>1)*rdp.scale_x; + rdp.view_scale[1] = (rdp.scissor_o.lr_y>>1)*-rdp.scale_y; + rdp.view_trans[0] = rdp.view_scale[0]; + rdp.view_trans[1] = -rdp.view_scale[1]; + rdp.update |= UPDATE_VIEWPORT; + } +} + +static void rdp_setprimdepth() +{ + rdp.prim_depth = (wxUint16)((rdp.cmd1 >> 16) & 0x7FFF); + rdp.prim_dz = (wxUint16)(rdp.cmd1 & 0x7FFF); + + FRDP("setprimdepth: %d\n", rdp.prim_depth); +} + +static void rdp_setothermode() +{ +#define F3DEX2_SETOTHERMODE(cmd,sft,len,data) { \ + rdp.cmd0 = (cmd<<24) | ((32-(sft)-(len))<<8) | (((len)-1)); \ + rdp.cmd1 = data; \ + gfx_instruction[settings.ucode][cmd] (); \ +} +#define SETOTHERMODE(cmd,sft,len,data) { \ + rdp.cmd0 = (cmd<<24) | ((sft)<<8) | (len); \ + rdp.cmd1 = data; \ + gfx_instruction[settings.ucode][cmd] (); \ +} + + LRDP("rdp_setothermode\n"); + + if ((settings.ucode == ucode_F3DEX2) || (settings.ucode == ucode_CBFD)) + { + int cmd0 = rdp.cmd0; + F3DEX2_SETOTHERMODE(0xE2, 0, 32, rdp.cmd1); // SETOTHERMODE_L + F3DEX2_SETOTHERMODE(0xE3, 0, 32, cmd0 & 0x00FFFFFF); // SETOTHERMODE_H + } + else + { + int cmd0 = rdp.cmd0; + SETOTHERMODE(0xB9, 0, 32, rdp.cmd1); // SETOTHERMODE_L + SETOTHERMODE(0xBA, 0, 32, cmd0 & 0x00FFFFFF); // SETOTHERMODE_H + } +} + +void load_palette (wxUint32 addr, wxUint16 start, wxUint16 count) +{ + LRDP("Loading palette... "); + wxUint16 *dpal = rdp.pal_8 + start; + wxUint16 end = start+count; +#ifdef TEXTURE_FILTER + wxUint16 *spal = (wxUint16*)(gfx.RDRAM + (addr & BMASK)); +#endif + + for (wxUint16 i=start; i>= 4; + end = start + (count >> 4); + if (end == start) // it can be if count < 16 + end = start + 1; + for (wxUint16 p = start; p < end; p++) + { + rdp.pal_8_crc[p] = CRC32( 0xFFFFFFFF, &rdp.pal_8[(p << 4)], 32 ); + } + rdp.pal_256_crc = CRC32( 0xFFFFFFFF, rdp.pal_8_crc, 64 ); + LRDP("Done.\n"); +} + +static void rdp_loadtlut() +{ + wxUint32 tile = (rdp.cmd1 >> 24) & 0x07; + wxUint16 start = rdp.tiles[tile].t_mem - 256; // starting location in the palettes + // wxUint16 start = ((wxUint16)(rdp.cmd1 >> 2) & 0x3FF) + 1; + wxUint16 count = ((wxUint16)(rdp.cmd1 >> 14) & 0x3FF) + 1; // number to copy + + if (rdp.timg.addr + (count<<1) > BMASK) + count = (wxUint16)((BMASK - rdp.timg.addr) >> 1); + + if (start+count > 256) count = 256-start; + + FRDP("loadtlut: tile: %d, start: %d, count: %d, from: %08lx\n", tile, start, count, + rdp.timg.addr); + + load_palette (rdp.timg.addr, start, count); + + rdp.timg.addr += count << 1; + + if (rdp.tbuff_tex) //paranoid check. + { + //the buffer is definitely wrong, as there must be no CI frame buffers + //find and remove it + for (int i = 0; i < voodoo.num_tmu; i++) + { + for (int j = 0; j < rdp.texbufs[i].count; j++) + { + if (&(rdp.texbufs[i].images[j]) == rdp.tbuff_tex) + { + rdp.texbufs[i].count--; + if (j < rdp.texbufs[i].count) + memcpy(&(rdp.texbufs[i].images[j]), &(rdp.texbufs[i].images[j+1]), sizeof(TBUFF_COLOR_IMAGE)*(rdp.texbufs[i].count-j)); + return; + } + } + } + } +} + +int tile_set = 0; +static void rdp_settilesize() +{ + wxUint32 tile = (rdp.cmd1 >> 24) & 0x07; + rdp.last_tile_size = tile; + + rdp.tiles[tile].f_ul_s = (float)((rdp.cmd0 >> 12) & 0xFFF) / 4.0f; + rdp.tiles[tile].f_ul_t = (float)(rdp.cmd0 & 0xFFF) / 4.0f; + + int ul_s = (((wxUint16)(rdp.cmd0 >> 14)) & 0x03ff); + int ul_t = (((wxUint16)(rdp.cmd0 >> 2 )) & 0x03ff); + int lr_s = (((wxUint16)(rdp.cmd1 >> 14)) & 0x03ff); + int lr_t = (((wxUint16)(rdp.cmd1 >> 2 )) & 0x03ff); + + if (lr_s == 0 && ul_s == 0) //pokemon puzzle league set such tile size + wrong_tile = tile; + else if (wrong_tile == (int)tile) + wrong_tile = -1; + + if (settings.use_sts1_only) + { + // ** USE FIRST SETTILESIZE ONLY ** + // This option helps certain textures while using the 'Alternate texture size method', + // but may break others. (should help more than break) + + if (tile_set) + { + // coords in 10.2 format + rdp.tiles[tile].ul_s = ul_s; + rdp.tiles[tile].ul_t = ul_t; + rdp.tiles[tile].lr_s = lr_s; + rdp.tiles[tile].lr_t = lr_t; + tile_set = 0; + } + } + else + { + // coords in 10.2 format + rdp.tiles[tile].ul_s = ul_s; + rdp.tiles[tile].ul_t = ul_t; + rdp.tiles[tile].lr_s = lr_s; + rdp.tiles[tile].lr_t = lr_t; + } + + // handle wrapping + if (rdp.tiles[tile].lr_s < rdp.tiles[tile].ul_s) rdp.tiles[tile].lr_s += 0x400; + if (rdp.tiles[tile].lr_t < rdp.tiles[tile].ul_t) rdp.tiles[tile].lr_t += 0x400; + + rdp.update |= UPDATE_TEXTURE; + + rdp.first = 1; + + FRDP ("settilesize: tile: %d, ul_s: %d, ul_t: %d, lr_s: %d, lr_t: %d, f_ul_s: %f, f_ul_t: %f\n", + tile, ul_s, ul_t, lr_s, lr_t, rdp.tiles[tile].f_ul_s, rdp.tiles[tile].f_ul_t); +} + +void setTBufTex(wxUint16 t_mem, wxUint32 cnt) +{ + FRDP("setTBufTex t_mem=%d, cnt=%d\n", t_mem, cnt); + TBUFF_COLOR_IMAGE * pTbufTex = rdp.tbuff_tex; + for (int i = 0; i < 2; i++) + { + LRDP("Before: "); + if (rdp.aTBuffTex[i]) { + FRDP("rdp.aTBuffTex[%d]: tmu=%d t_mem=%d tile=%d\n", i, rdp.aTBuffTex[i]->tmu, rdp.aTBuffTex[i]->t_mem, rdp.aTBuffTex[i]->tile); + } else { + FRDP("rdp.aTBuffTex[%d]=0\n", i); + } + if ((rdp.aTBuffTex[i] == 0 && rdp.aTBuffTex[i^1] != pTbufTex) || (rdp.aTBuffTex[i] && rdp.aTBuffTex[i]->t_mem >= t_mem && rdp.aTBuffTex[i]->t_mem < t_mem + cnt)) + { + if (pTbufTex) + { + rdp.aTBuffTex[i] = pTbufTex; + rdp.aTBuffTex[i]->t_mem = t_mem; + pTbufTex = 0; + FRDP("rdp.aTBuffTex[%d] tmu=%d t_mem=%d\n", i, rdp.aTBuffTex[i]->tmu, rdp.aTBuffTex[i]->t_mem); + } + else + { + rdp.aTBuffTex[i] = 0; + FRDP("rdp.aTBuffTex[%d]=0\n", i); + } + } + } +} + +extern "C" void asmLoadBlock(int src, int dst, int off, int dxt, int cnt, int swp); +void LoadBlock32b(wxUint32 tile, wxUint32 ul_s, wxUint32 ul_t, wxUint32 lr_s, wxUint32 dxt); +static void rdp_loadblock() +{ + if (rdp.skip_drawing) + { + LRDP("loadblock skipped\n"); + return; + } + wxUint32 tile = (wxUint32)((rdp.cmd1 >> 24) & 0x07); + wxUint32 dxt = (wxUint32)(rdp.cmd1 & 0x0FFF); + wxUint16 lr_s = (wxUint16)(rdp.cmd1 >> 14) & 0x3FF; + if (ucode5_texshiftaddr) + { + if (ucode5_texshift % ((lr_s+1)<<3)) + { + rdp.timg.addr -= ucode5_texshift; + ucode5_texshiftaddr = 0; + ucode5_texshift = 0; + ucode5_texshiftcount = 0; + } + else + ucode5_texshiftcount++; + } + + rdp.addr[rdp.tiles[tile].t_mem] = rdp.timg.addr; + + // ** DXT is used for swapping every other line + /* double fdxt = (double)0x8000000F/(double)((wxUint32)(2047/(dxt-1))); // F for error + wxUint32 _dxt = (wxUint32)fdxt;*/ + + // 0x00000800 -> 0x80000000 (so we can check the sign bit instead of the 11th bit) + wxUint32 _dxt = dxt << 20; + + wxUint32 addr = segoffset(rdp.timg.addr) & BMASK; + + // lr_s specifies number of 64-bit words to copy + // 10.2 format + wxUint16 ul_s = (wxUint16)(rdp.cmd0 >> 14) & 0x3FF; + wxUint16 ul_t = (wxUint16)(rdp.cmd0 >> 2) & 0x3FF; + + rdp.tiles[tile].ul_s = ul_s; + rdp.tiles[tile].ul_t = ul_t; + rdp.tiles[tile].lr_s = lr_s; + + rdp.timg.set_by = 0; // load block + +#ifdef TEXTURE_FILTER + LOAD_TILE_INFO &info = rdp.load_info[rdp.tiles[tile].t_mem]; + info.tile_width = lr_s; + info.dxt = dxt; +#endif + + // do a quick boundary check before copying to eliminate the possibility for exception + if (ul_s >= 512) { + lr_s = 1; // 1 so that it doesn't die on memcpy + ul_s = 511; + } + if (ul_s+lr_s > 512) + lr_s = 512-ul_s; + + if (addr+(lr_s<<3) > BMASK+1) + lr_s = (wxUint16)((BMASK-addr)>>3); + + //angrylion's advice to use ul_s in texture image offset and cnt calculations. + //Helps to fix Vigilante 8 jpeg backgrounds and logos + wxUint32 off = rdp.timg.addr + (ul_s << rdp.tiles[tile].size >> 1); + wxUIntPtr dst = wxPtrToUInt(rdp.tmem)+(rdp.tiles[tile].t_mem<<3); + wxUint32 cnt = lr_s-ul_s+1; + if (rdp.tiles[tile].size == 3) + cnt <<= 1; + + wxUIntPtr SwapMethod = wxPtrToUInt(reinterpret_cast(SwapBlock32)); + + if (rdp.timg.size == 3) + LoadBlock32b(tile, ul_s, ul_t, lr_s, dxt); + else + asmLoadBlock(wxPtrToUInt(gfx.RDRAM), dst, off, _dxt, cnt, SwapMethod); + + rdp.timg.addr += cnt << 3; + rdp.tiles[tile].lr_t = ul_t + ((dxt*cnt)>>11); + + rdp.update |= UPDATE_TEXTURE; + + FRDP ("loadblock: tile: %d, ul_s: %d, ul_t: %d, lr_s: %d, dxt: %08lx -> %08lx\n", + tile, ul_s, ul_t, lr_s, + dxt, _dxt); + + if (fb_hwfbe_enabled) + setTBufTex(rdp.tiles[tile].t_mem, cnt); +} + +extern "C" void asmLoadTile(int src, int dst, int width, int height, int line, int off, int end, int swap); +void LoadTile32b (wxUint32 tile, wxUint32 ul_s, wxUint32 ul_t, wxUint32 width, wxUint32 height); +static void rdp_loadtile() +{ + if (rdp.skip_drawing) + { + LRDP("loadtile skipped\n"); + return; + } + rdp.timg.set_by = 1; // load tile + + wxUint32 tile = (wxUint32)((rdp.cmd1 >> 24) & 0x07); + + rdp.addr[rdp.tiles[tile].t_mem] = rdp.timg.addr; + + wxUint16 ul_s = (wxUint16)((rdp.cmd0 >> 14) & 0x03FF); + wxUint16 ul_t = (wxUint16)((rdp.cmd0 >> 2 ) & 0x03FF); + wxUint16 lr_s = (wxUint16)((rdp.cmd1 >> 14) & 0x03FF); + wxUint16 lr_t = (wxUint16)((rdp.cmd1 >> 2 ) & 0x03FF); + + if (lr_s < ul_s || lr_t < ul_t) return; + + if (wrong_tile >= 0) //there was a tile with zero length + { + rdp.tiles[wrong_tile].lr_s = lr_s; + + if (rdp.tiles[tile].size > rdp.tiles[wrong_tile].size) + rdp.tiles[wrong_tile].lr_s <<= (rdp.tiles[tile].size - rdp.tiles[wrong_tile].size); + else if (rdp.tiles[tile].size < rdp.tiles[wrong_tile].size) + rdp.tiles[wrong_tile].lr_s >>= (rdp.tiles[wrong_tile].size - rdp.tiles[tile].size); + rdp.tiles[wrong_tile].lr_t = lr_t; + rdp.tiles[wrong_tile].mask_s = rdp.tiles[wrong_tile].mask_t = 0; + // wrong_tile = -1; + } + + if (rdp.tbuff_tex)// && (rdp.tiles[tile].format == 0)) + { + FRDP("loadtile: tbuff_tex ul_s: %d, ul_t:%d\n", ul_s, ul_t); + rdp.tbuff_tex->tile_uls = ul_s; + rdp.tbuff_tex->tile_ult = ul_t; + } + + if ((settings.hacks&hack_Tonic) && tile == 7) + { + rdp.tiles[0].ul_s = ul_s; + rdp.tiles[0].ul_t = ul_t; + rdp.tiles[0].lr_s = lr_s; + rdp.tiles[0].lr_t = lr_t; + } + + wxUint32 height = lr_t - ul_t + 1; // get height + wxUint32 width = lr_s - ul_s + 1; + +#ifdef TEXTURE_FILTER + LOAD_TILE_INFO &info = rdp.load_info[rdp.tiles[tile].t_mem]; + info.tile_ul_s = ul_s; + info.tile_ul_t = ul_t; + info.tile_width = (rdp.tiles[tile].mask_s ? min((wxUint16)width, 1<> 1; + wxUint32 offs = ul_t * line_n; + offs += ul_s << rdp.tiles[tile].size >> 1; + offs += rdp.timg.addr; + if (offs >= BMASK) + return; + + if (rdp.timg.size == 3) + { + LoadTile32b(tile, ul_s, ul_t, width, height); + } + else + { + // check if points to bad location + if (offs + line_n*height > BMASK) + height = (BMASK - offs) / line_n; + if (height == 0) + return; + + wxUint32 wid_64 = rdp.tiles[tile].line; + wxUIntPtr SwapMethod = wxPtrToUInt(reinterpret_cast(SwapBlock32)); + wxUIntPtr dst = wxPtrToUInt(rdp.tmem) + (rdp.tiles[tile].t_mem<<3); + wxUIntPtr end = wxPtrToUInt(rdp.tmem) + 4096 - (wid_64<<3); + asmLoadTile(wxPtrToUInt(gfx.RDRAM), dst, wid_64, height, line_n, offs, end, SwapMethod); + } + FRDP("loadtile: tile: %d, ul_s: %d, ul_t: %d, lr_s: %d, lr_t: %d\n", tile, + ul_s, ul_t, lr_s, lr_t); + + if (fb_hwfbe_enabled) + setTBufTex(rdp.tiles[tile].t_mem, rdp.tiles[tile].line*height); +} + +static void rdp_settile() +{ + tile_set = 1; // used to check if we only load the first settilesize + + rdp.first = 0; + + rdp.last_tile = (wxUint32)((rdp.cmd1 >> 24) & 0x07); + TILE *tile = &rdp.tiles[rdp.last_tile]; + + tile->format = (wxUint8)((rdp.cmd0 >> 21) & 0x07); + tile->size = (wxUint8)((rdp.cmd0 >> 19) & 0x03); + tile->line = (wxUint16)((rdp.cmd0 >> 9) & 0x01FF); + tile->t_mem = (wxUint16)(rdp.cmd0 & 0x1FF); + tile->palette = (wxUint8)((rdp.cmd1 >> 20) & 0x0F); + tile->clamp_t = (wxUint8)((rdp.cmd1 >> 19) & 0x01); + tile->mirror_t = (wxUint8)((rdp.cmd1 >> 18) & 0x01); + tile->mask_t = (wxUint8)((rdp.cmd1 >> 14) & 0x0F); + tile->shift_t = (wxUint8)((rdp.cmd1 >> 10) & 0x0F); + tile->clamp_s = (wxUint8)((rdp.cmd1 >> 9) & 0x01); + tile->mirror_s = (wxUint8)((rdp.cmd1 >> 8) & 0x01); + tile->mask_s = (wxUint8)((rdp.cmd1 >> 4) & 0x0F); + tile->shift_s = (wxUint8)(rdp.cmd1 & 0x0F); + + rdp.update |= UPDATE_TEXTURE; + + FRDP ("settile: tile: %d, format: %s, size: %s, line: %d, " + "t_mem: %08lx, palette: %d, clamp_t/mirror_t: %s, mask_t: %d, " + "shift_t: %d, clamp_s/mirror_s: %s, mask_s: %d, shift_s: %d\n", + rdp.last_tile, str_format[tile->format], str_size[tile->size], tile->line, + tile->t_mem, tile->palette, str_cm[(tile->clamp_t<<1)|tile->mirror_t], tile->mask_t, + tile->shift_t, str_cm[(tile->clamp_s<<1)|tile->mirror_s], tile->mask_s, tile->shift_s); + + if (fb_hwfbe_enabled && rdp.last_tile < rdp.cur_tile + 2) + { + for (int i = 0; i < 2; i++) + { + if (rdp.aTBuffTex[i]) + { + if (rdp.aTBuffTex[i]->t_mem == tile->t_mem) + { + if (rdp.aTBuffTex[i]->size == tile->size) + { + rdp.aTBuffTex[i]->tile = rdp.last_tile; + rdp.aTBuffTex[i]->info.format = tile->format == 0 ? GR_TEXFMT_RGB_565 : GR_TEXFMT_ALPHA_INTENSITY_88; + FRDP("rdp.aTBuffTex[%d] tile=%d, format=%s\n", i, rdp.last_tile, tile->format == 0 ? "RGB565" : "Alpha88"); + } + else + rdp.aTBuffTex[i] = 0; + break; + } + else if (rdp.aTBuffTex[i]->tile == rdp.last_tile) //wrong! t_mem must be the same + rdp.aTBuffTex[i] = 0; + } + } + } +} + +// +// fillrect - fills a rectangle +// + +static void rdp_fillrect() +{ + wxUint32 ul_x = ((rdp.cmd1 & 0x00FFF000) >> 14); + wxUint32 ul_y = (rdp.cmd1 & 0x00000FFF) >> 2; + wxUint32 lr_x = ((rdp.cmd0 & 0x00FFF000) >> 14) + 1; + wxUint32 lr_y = ((rdp.cmd0 & 0x00000FFF) >> 2) + 1; + if ((ul_x > lr_x) || (ul_y > lr_y)) + { + LRDP("Fillrect. Wrong coordinates. Skipped\n"); + return; + } + int pd_multiplayer = (settings.ucode == ucode_PerfectDark) && (rdp.cycle_mode == 3) && (rdp.fill_color == 0xFFFCFFFC); + if ((rdp.cimg == rdp.zimg) || (fb_emulation_enabled && rdp.frame_buffers[rdp.ci_count-1].status == ci_zimg) || pd_multiplayer) + { + LRDP("Fillrect - cleared the depth buffer\n"); + if (fullscreen) + { + if (!(settings.hacks&hack_Hyperbike) || rdp.ci_width > 64) //do not clear main depth buffer for aux depth buffers + { + update_scissor (); + grDepthMask (FXTRUE); + grColorMask (FXFALSE, FXFALSE); + grBufferClear (0, 0, rdp.fill_color ? rdp.fill_color&0xFFFF : 0xFFFF); + grColorMask (FXTRUE, FXTRUE); + rdp.update |= UPDATE_ZBUF_ENABLED; + } + //if (settings.frame_buffer&fb_depth_clear) + { + ul_x = min(max(ul_x, rdp.scissor_o.ul_x), rdp.scissor_o.lr_x); + lr_x = min(max(lr_x, rdp.scissor_o.ul_x), rdp.scissor_o.lr_x); + ul_y = min(max(ul_y, rdp.scissor_o.ul_y), rdp.scissor_o.lr_y); + lr_y = min(max(lr_y, rdp.scissor_o.ul_y), rdp.scissor_o.lr_y); + wxUint32 zi_width_in_dwords = rdp.ci_width >> 1; + ul_x >>= 1; + lr_x >>= 1; + wxUint32 * dst = (wxUint32*)(gfx.RDRAM+rdp.cimg); + dst += ul_y * zi_width_in_dwords; + for (wxUint32 y = ul_y; y < lr_y; y++) + { + for (wxUint32 x = ul_x; x < lr_x; x++) + { + dst[x] = rdp.fill_color; + } + dst += zi_width_in_dwords; + } + } + } + return; + } + + if (rdp.skip_drawing) + { + LRDP("Fillrect skipped\n"); + return; + } + + if (rdp.cur_image && (rdp.cur_image->format != 0) && (rdp.cycle_mode == 3) && (rdp.cur_image->width == lr_x - ul_x) && (rdp.cur_image->height == lr_y - ul_y)) + { + wxUint32 color = rdp.fill_color; + if (rdp.ci_size < 3) + { + color = ((color&1)?0xFF:0) | + ((wxUint32)((float)((color&0xF800) >> 11) / 31.0f * 255.0f) << 24) | + ((wxUint32)((float)((color&0x07C0) >> 6) / 31.0f * 255.0f) << 16) | + ((wxUint32)((float)((color&0x003E) >> 1) / 31.0f * 255.0f) << 8); + } + grDepthMask (FXFALSE); + grBufferClear (color, 0, 0xFFFF); + grDepthMask (FXTRUE); + rdp.update |= UPDATE_ZBUF_ENABLED; + LRDP("Fillrect - cleared the texture buffer\n"); + return; + } + + // Update scissor + if (fullscreen) + update_scissor (); + + if (settings.decrease_fillrect_edge && rdp.cycle_mode == 0) + { + lr_x--; lr_y--; + } + FRDP("fillrect (%d,%d) -> (%d,%d), cycle mode: %d, #%d, #%d\n", ul_x, ul_y, lr_x, lr_y, rdp.cycle_mode, + rdp.tri_n, rdp.tri_n+1); + + FRDP("scissor (%d,%d) -> (%d,%d)\n", rdp.scissor.ul_x, rdp.scissor.ul_y, rdp.scissor.lr_x, + rdp.scissor.lr_y); + + // KILL the floating point error with 0.01f + wxInt32 s_ul_x = (wxUint32)min(max(ul_x * rdp.scale_x + rdp.offset_x + 0.01f, rdp.scissor.ul_x), rdp.scissor.lr_x); + wxInt32 s_lr_x = (wxUint32)min(max(lr_x * rdp.scale_x + rdp.offset_x + 0.01f, rdp.scissor.ul_x), rdp.scissor.lr_x); + wxInt32 s_ul_y = (wxUint32)min(max(ul_y * rdp.scale_y + rdp.offset_y + 0.01f, rdp.scissor.ul_y), rdp.scissor.lr_y); + wxInt32 s_lr_y = (wxUint32)min(max(lr_y * rdp.scale_y + rdp.offset_y + 0.01f, rdp.scissor.ul_y), rdp.scissor.lr_y); + + if (s_lr_x < 0) s_lr_x = 0; + if (s_lr_y < 0) s_lr_y = 0; + if ((wxUint32)s_ul_x > settings.res_x) s_ul_x = settings.res_x; + if ((wxUint32)s_ul_y > settings.res_y) s_ul_y = settings.res_y; + + FRDP (" - %d, %d, %d, %d\n", s_ul_x, s_ul_y, s_lr_x, s_lr_y); + + if (fullscreen) + { + grFogMode (GR_FOG_DISABLE); + + const float Z = (rdp.cycle_mode == 3) ? 0.0f : set_sprite_combine_mode(); + + // Draw the rectangle + VERTEX v[4] = { + { (float)s_ul_x, (float)s_ul_y, Z, 1.0f, 0,0,0,0, {0,0,0,0}, 0,0, 0,0,0,0}, + { (float)s_lr_x, (float)s_ul_y, Z, 1.0f, 0,0,0,0, {0,0,0,0}, 0,0, 0,0,0,0}, + { (float)s_ul_x, (float)s_lr_y, Z, 1.0f, 0,0,0,0, {0,0,0,0}, 0,0, 0,0,0,0}, + { (float)s_lr_x, (float)s_lr_y, Z, 1.0f, 0,0,0,0, {0,0,0,0}, 0,0, 0,0,0,0} }; + + if (rdp.cycle_mode == 3) + { + wxUint32 color = rdp.fill_color; + + if ((settings.hacks&hack_PMario) && rdp.frame_buffers[rdp.ci_count-1].status == ci_aux) + { + //background of auxiliary frame buffers must have zero alpha. + //make it black, set 0 alpha to plack pixels on frame buffer read + color = 0; + } + else if (rdp.ci_size < 3) + { + color = ((color&1)?0xFF:0) | + ((wxUint32)((float)((color&0xF800) >> 11) / 31.0f * 255.0f) << 24) | + ((wxUint32)((float)((color&0x07C0) >> 6) / 31.0f * 255.0f) << 16) | + ((wxUint32)((float)((color&0x003E) >> 1) / 31.0f * 255.0f) << 8); + } + + grConstantColorValue (color); + + grColorCombine (GR_COMBINE_FUNCTION_LOCAL, + GR_COMBINE_FACTOR_NONE, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_NONE, + FXFALSE); + + grAlphaCombine (GR_COMBINE_FUNCTION_LOCAL, + GR_COMBINE_FACTOR_NONE, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_NONE, + FXFALSE); + + grAlphaBlendFunction (GR_BLEND_ONE, GR_BLEND_ZERO, GR_BLEND_ONE, GR_BLEND_ZERO); + + grAlphaTestFunction (GR_CMP_ALWAYS); + if (grStippleModeExt) + grStippleModeExt(GR_STIPPLE_DISABLE); + + grCullMode(GR_CULL_DISABLE); + grFogMode (GR_FOG_DISABLE); + grDepthBufferFunction (GR_CMP_ALWAYS); + grDepthMask (FXFALSE); + + rdp.update |= UPDATE_COMBINE | UPDATE_CULL_MODE | UPDATE_FOG_ENABLED | UPDATE_ZBUF_ENABLED; + } + else + { + wxUint32 cmb_mode_c = (rdp.cycle1 << 16) | (rdp.cycle2 & 0xFFFF); + wxUint32 cmb_mode_a = (rdp.cycle1 & 0x0FFF0000) | ((rdp.cycle2 >> 16) & 0x00000FFF); + if (cmb_mode_c == 0x9fff9fff || cmb_mode_a == 0x09ff09ff) //shade + { + AllowShadeMods (v, 4); + for (int k = 0; k < 4; k++) + apply_shade_mods (&v[k]); + } + if ((rdp.othermode_l & 0x4000) && ((rdp.othermode_l >> 16) == 0x0550)) //special blender mode for Bomberman64 + { + grAlphaCombine (GR_COMBINE_FUNCTION_LOCAL, + GR_COMBINE_FACTOR_NONE, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_NONE, + FXFALSE); + grConstantColorValue((cmb.ccolor&0xFFFFFF00)|(rdp.fog_color&0xFF)); + rdp.update |= UPDATE_COMBINE; + } + } + + if (settings.wireframe) + { + SetWireframeCol (); + grDrawLine (&v[0], &v[2]); + grDrawLine (&v[2], &v[1]); + grDrawLine (&v[1], &v[0]); + grDrawLine (&v[2], &v[3]); + grDrawLine (&v[3], &v[1]); + //grDrawLine (&v[1], &v[2]); + } + else + { + grDrawTriangle (&v[0], &v[2], &v[1]); + grDrawTriangle (&v[2], &v[3], &v[1]); + } + + if (_debugger.capture) + { + VERTEX v1[3]; + v1[0] = v[0]; + v1[1] = v[2]; + v1[2] = v[1]; + add_tri (v1, 3, TRI_FILLRECT); + rdp.tri_n ++; + v1[0] = v[2]; + v1[1] = v[3]; + add_tri (v1, 3, TRI_FILLRECT); + rdp.tri_n ++; + } + else + rdp.tri_n += 2; + } + else + { + rdp.tri_n += 2; + } +} + +// +// setfillcolor - sets the filling color +// + +static void rdp_setfillcolor() +{ + rdp.fill_color = rdp.cmd1; + rdp.update |= UPDATE_ALPHA_COMPARE | UPDATE_COMBINE; + + FRDP("setfillcolor: %08lx\n", rdp.cmd1); +} + +static void rdp_setfogcolor() +{ + rdp.fog_color = rdp.cmd1; + rdp.update |= UPDATE_COMBINE | UPDATE_FOG_ENABLED; + + FRDP("setfogcolor - %08lx\n", rdp.cmd1); +} + +static void rdp_setblendcolor() +{ + rdp.blend_color = rdp.cmd1; + rdp.update |= UPDATE_COMBINE; + + FRDP("setblendcolor: %08lx\n", rdp.cmd1); +} + +static void rdp_setprimcolor() +{ + rdp.prim_color = rdp.cmd1; + rdp.prim_lodmin = (rdp.cmd0 >> 8) & 0xFF; + rdp.prim_lodfrac = max(rdp.cmd0 & 0xFF, rdp.prim_lodmin); + rdp.update |= UPDATE_COMBINE; + + FRDP("setprimcolor: %08lx, lodmin: %d, lodfrac: %d\n", rdp.cmd1, rdp.prim_lodmin, + rdp.prim_lodfrac); +} + +static void rdp_setenvcolor() +{ + rdp.env_color = rdp.cmd1; + rdp.update |= UPDATE_COMBINE; + + FRDP("setenvcolor: %08lx\n", rdp.cmd1); +} + +static void rdp_setcombine() +{ + rdp.c_a0 = (wxUint8)((rdp.cmd0 >> 20) & 0xF); + rdp.c_b0 = (wxUint8)((rdp.cmd1 >> 28) & 0xF); + rdp.c_c0 = (wxUint8)((rdp.cmd0 >> 15) & 0x1F); + rdp.c_d0 = (wxUint8)((rdp.cmd1 >> 15) & 0x7); + rdp.c_Aa0 = (wxUint8)((rdp.cmd0 >> 12) & 0x7); + rdp.c_Ab0 = (wxUint8)((rdp.cmd1 >> 12) & 0x7); + rdp.c_Ac0 = (wxUint8)((rdp.cmd0 >> 9) & 0x7); + rdp.c_Ad0 = (wxUint8)((rdp.cmd1 >> 9) & 0x7); + + rdp.c_a1 = (wxUint8)((rdp.cmd0 >> 5) & 0xF); + rdp.c_b1 = (wxUint8)((rdp.cmd1 >> 24) & 0xF); + rdp.c_c1 = (wxUint8)((rdp.cmd0 >> 0) & 0x1F); + rdp.c_d1 = (wxUint8)((rdp.cmd1 >> 6) & 0x7); + rdp.c_Aa1 = (wxUint8)((rdp.cmd1 >> 21) & 0x7); + rdp.c_Ab1 = (wxUint8)((rdp.cmd1 >> 3) & 0x7); + rdp.c_Ac1 = (wxUint8)((rdp.cmd1 >> 18) & 0x7); + rdp.c_Ad1 = (wxUint8)((rdp.cmd1 >> 0) & 0x7); + + rdp.cycle1 = (rdp.c_a0<<0) | (rdp.c_b0<<4) | (rdp.c_c0<<8) | (rdp.c_d0<<13)| + (rdp.c_Aa0<<16)| (rdp.c_Ab0<<19)| (rdp.c_Ac0<<22)| (rdp.c_Ad0<<25); + rdp.cycle2 = (rdp.c_a1<<0) | (rdp.c_b1<<4) | (rdp.c_c1<<8) | (rdp.c_d1<<13)| + (rdp.c_Aa1<<16)| (rdp.c_Ab1<<19)| (rdp.c_Ac1<<22)| (rdp.c_Ad1<<25); + + rdp.update |= UPDATE_COMBINE; + + FRDP("setcombine\na0=%s b0=%s c0=%s d0=%s\nAa0=%s Ab0=%s Ac0=%s Ad0=%s\na1=%s b1=%s c1=%s d1=%s\nAa1=%s Ab1=%s Ac1=%s Ad1=%s\n", + Mode0[rdp.c_a0], Mode1[rdp.c_b0], Mode2[rdp.c_c0], Mode3[rdp.c_d0], + Alpha0[rdp.c_Aa0], Alpha1[rdp.c_Ab0], Alpha2[rdp.c_Ac0], Alpha3[rdp.c_Ad0], + Mode0[rdp.c_a1], Mode1[rdp.c_b1], Mode2[rdp.c_c1], Mode3[rdp.c_d1], + Alpha0[rdp.c_Aa1], Alpha1[rdp.c_Ab1], Alpha2[rdp.c_Ac1], Alpha3[rdp.c_Ad1]); +} + +// +// settextureimage - sets the source for an image copy +// + +static void rdp_settextureimage() +{ + static const char *format[] = { "RGBA", "YUV", "CI", "IA", "I", "?", "?", "?" }; + static const char *size[] = { "4bit", "8bit", "16bit", "32bit" }; + + rdp.timg.format = (wxUint8)((rdp.cmd0 >> 21) & 0x07); + rdp.timg.size = (wxUint8)((rdp.cmd0 >> 19) & 0x03); + rdp.timg.width = (wxUint16)(1 + (rdp.cmd0 & 0x00000FFF)); + rdp.timg.addr = segoffset(rdp.cmd1); + if (ucode5_texshiftaddr) + { + if (rdp.timg.format == 0) + { + wxUint16 * t = (wxUint16*)(gfx.RDRAM+ucode5_texshiftaddr); + ucode5_texshift = t[ucode5_texshiftcount^1]; + rdp.timg.addr += ucode5_texshift; + } + else + { + ucode5_texshiftaddr = 0; + ucode5_texshift = 0; + ucode5_texshiftcount = 0; + } + } + rdp.s2dex_tex_loaded = TRUE; + rdp.update |= UPDATE_TEXTURE; + + if (rdp.frame_buffers[rdp.ci_count-1].status == ci_copy_self && (rdp.timg.addr >= rdp.cimg) && (rdp.timg.addr < rdp.ci_end)) + { + if (!rdp.fb_drawn) + { + if (!rdp.cur_image) + CopyFrameBuffer(); + else + CloseTextureBuffer(TRUE); + rdp.fb_drawn = TRUE; + } + } + + if (fb_hwfbe_enabled) //search this texture among drawn texture buffers + FindTextureBuffer(rdp.timg.addr, rdp.timg.width); + + FRDP("settextureimage: format: %s, size: %s, width: %d, addr: %08lx\n", + format[rdp.timg.format], size[rdp.timg.size], + rdp.timg.width, rdp.timg.addr); +} + +static void rdp_setdepthimage() +{ + rdp.zimg = segoffset(rdp.cmd1) & BMASK; + rdp.zi_width = rdp.ci_width; + FRDP("setdepthimage - %08lx\n", rdp.zimg); +} + +int SwapOK = TRUE; +static void RestoreScale() +{ + FRDP("Return to original scale: x = %f, y = %f\n", rdp.scale_x_bak, rdp.scale_y_bak); + rdp.scale_x = rdp.scale_x_bak; + rdp.scale_y = rdp.scale_y_bak; + // update_scissor(); + rdp.view_scale[0] *= rdp.scale_x; + rdp.view_scale[1] *= rdp.scale_y; + rdp.view_trans[0] *= rdp.scale_x; + rdp.view_trans[1] *= rdp.scale_y; + rdp.update |= UPDATE_VIEWPORT | UPDATE_SCISSOR; + //* + if (fullscreen) + { + grDepthMask (FXFALSE); + grBufferClear (0, 0, 0xFFFF); + grDepthMask (FXTRUE); + } + //*/ +} + +static wxUint32 swapped_addr = 0; + +static void rdp_setcolorimage() +{ + if (fb_emulation_enabled && (rdp.num_of_ci < NUMTEXBUF)) + { + COLOR_IMAGE & cur_fb = rdp.frame_buffers[rdp.ci_count]; + COLOR_IMAGE & prev_fb = rdp.frame_buffers[rdp.ci_count?rdp.ci_count-1:0]; + COLOR_IMAGE & next_fb = rdp.frame_buffers[rdp.ci_count+1]; + switch (cur_fb.status) + { + case ci_main: + { + + if (rdp.ci_count == 0) + { + if ((rdp.ci_status == ci_aux)) //for PPL + { + float sx = rdp.scale_x; + float sy = rdp.scale_y; + rdp.scale_x = 1.0f; + rdp.scale_y = 1.0f; + CopyFrameBuffer (); + rdp.scale_x = sx; + rdp.scale_y = sy; + } + if (!fb_hwfbe_enabled) + { + if ((rdp.num_of_ci > 1) && + (next_fb.status == ci_aux) && + (next_fb.width >= cur_fb.width)) + { + rdp.scale_x = 1.0f; + rdp.scale_y = 1.0f; + } + } + else if (rdp.copy_ci_index && (settings.hacks&hack_PMario)) //tidal wave + OpenTextureBuffer(rdp.frame_buffers[rdp.main_ci_index]); + } + else if (!rdp.motionblur && fb_hwfbe_enabled && !SwapOK && (rdp.ci_count <= rdp.copy_ci_index)) + { + if (next_fb.status == ci_aux_copy) + OpenTextureBuffer(rdp.frame_buffers[rdp.main_ci_index]); + else + OpenTextureBuffer(rdp.frame_buffers[rdp.copy_ci_index]); + } + else if (fb_hwfbe_enabled && prev_fb.status == ci_aux) + { + if (rdp.motionblur) + { + rdp.cur_image = &(rdp.texbufs[rdp.cur_tex_buf].images[0]); + grRenderBuffer( GR_BUFFER_TEXTUREBUFFER_EXT ); + grTextureBufferExt( rdp.cur_image->tmu, rdp.cur_image->tex_addr, rdp.cur_image->info.smallLodLog2, rdp.cur_image->info.largeLodLog2, + rdp.cur_image->info.aspectRatioLog2, rdp.cur_image->info.format, GR_MIPMAPLEVELMASK_BOTH ); + } + else if (rdp.read_whole_frame) + { + OpenTextureBuffer(rdp.frame_buffers[rdp.main_ci_index]); + } + } + //else if (rdp.ci_status == ci_aux && !rdp.copy_ci_index) + // CloseTextureBuffer(); + + rdp.skip_drawing = FALSE; + } + break; + case ci_copy: + { + if (!rdp.motionblur || (settings.frame_buffer&fb_motionblur)) + { + if (cur_fb.width == rdp.ci_width) + { + if (CopyTextureBuffer(prev_fb, cur_fb)) + { + // if (CloseTextureBuffer(TRUE)) + //* + if ((settings.hacks&hack_Zelda) && (rdp.frame_buffers[rdp.ci_count+2].status == ci_aux) && !rdp.fb_drawn) //hack for photo camera in Zelda MM + { + CopyFrameBuffer (GR_BUFFER_TEXTUREBUFFER_EXT); + rdp.fb_drawn = TRUE; + memcpy(gfx.RDRAM+cur_fb.addr,gfx.RDRAM+rdp.cimg, (cur_fb.width*cur_fb.height)<>1); + } + //*/ + } + else + { + if (!rdp.fb_drawn || prev_fb.status == ci_copy_self) + { + CopyFrameBuffer (); + rdp.fb_drawn = TRUE; + } + memcpy(gfx.RDRAM+cur_fb.addr,gfx.RDRAM+rdp.cimg, (cur_fb.width*cur_fb.height)<>1); + } + } + else + { + CloseTextureBuffer(TRUE); + } + } + else + { + memset(gfx.RDRAM+cur_fb.addr, 0, cur_fb.width*cur_fb.height*rdp.ci_size); + } + rdp.skip_drawing = TRUE; + } + break; + case ci_aux_copy: + { + rdp.skip_drawing = FALSE; + if (CloseTextureBuffer(prev_fb.status != ci_aux_copy)) + ; + else if (!rdp.fb_drawn) + { + CopyFrameBuffer (); + rdp.fb_drawn = TRUE; + } + if (fb_hwfbe_enabled) + OpenTextureBuffer(cur_fb); + } + break; + case ci_old_copy: + { + if (!rdp.motionblur || (settings.frame_buffer&fb_motionblur)) + { + if (cur_fb.width == rdp.ci_width) + { + memcpy(gfx.RDRAM+cur_fb.addr,gfx.RDRAM+rdp.maincimg[1].addr, (cur_fb.width*cur_fb.height)<>1); + } + //rdp.skip_drawing = TRUE; + } + else + { + memset(gfx.RDRAM+cur_fb.addr, 0, (cur_fb.width*cur_fb.height)<>1); + } + } + break; + /* + else if (rdp.frame_buffers[rdp.ci_count].status == ci_main_i) + { + // CopyFrameBuffer (); + rdp.scale_x = rdp.scale_x_bak; + rdp.scale_y = rdp.scale_y_bak; + rdp.skip_drawing = FALSE; + } + */ + case ci_aux: + { + if (!fb_hwfbe_enabled && cur_fb.format != 0) + rdp.skip_drawing = TRUE; + else + { + rdp.skip_drawing = FALSE; + if (fb_hwfbe_enabled && OpenTextureBuffer(cur_fb)) + ; + else + { + if (cur_fb.format != 0) + rdp.skip_drawing = TRUE; + if (rdp.ci_count == 0) + { + // if (rdp.num_of_ci > 1) + // { + rdp.scale_x = 1.0f; + rdp.scale_y = 1.0f; + // } + } + else if (!fb_hwfbe_enabled && (prev_fb.status == ci_main) && + (prev_fb.width == cur_fb.width)) // for Pokemon Stadium + CopyFrameBuffer (); + } + } + cur_fb.status = ci_aux; + } + break; + case ci_zimg: + if (settings.ucode != ucode_PerfectDark) + { + if (fb_hwfbe_enabled && !rdp.copy_ci_index && (rdp.copy_zi_index || (settings.hacks&hack_BAR))) + { + GrLOD_t LOD = GR_LOD_LOG2_1024; + if (settings.scr_res_x > 1024) + LOD = GR_LOD_LOG2_2048; + grTextureAuxBufferExt( rdp.texbufs[0].tmu, rdp.texbufs[0].begin, LOD, LOD, + GR_ASPECT_LOG2_1x1, GR_TEXFMT_RGB_565, GR_MIPMAPLEVELMASK_BOTH ); + grAuxBufferExt( GR_BUFFER_TEXTUREAUXBUFFER_EXT ); + LRDP("rdp_setcolorimage - set texture depth buffer to TMU0\n"); + } + } + rdp.skip_drawing = TRUE; + break; + case ci_zcopy: + if (settings.ucode != ucode_PerfectDark) + { + if (fb_hwfbe_enabled && !rdp.copy_ci_index && rdp.copy_zi_index == rdp.ci_count) + { + CopyDepthBuffer(); + } + rdp.skip_drawing = TRUE; + } + break; + case ci_useless: + rdp.skip_drawing = TRUE; + break; + case ci_copy_self: + if (fb_hwfbe_enabled && (rdp.ci_count <= rdp.copy_ci_index) && (!SwapOK || settings.swapmode == 2)) + OpenTextureBuffer(cur_fb); + rdp.skip_drawing = FALSE; + break; + default: + rdp.skip_drawing = FALSE; + } + + if ((rdp.ci_count > 0) && (prev_fb.status >= ci_aux)) //for Pokemon Stadium + { + if (!fb_hwfbe_enabled && prev_fb.format == 0) + CopyFrameBuffer (); + else if ((settings.hacks&hack_Knockout) && prev_fb.width < 100) + CopyFrameBuffer (GR_BUFFER_TEXTUREBUFFER_EXT); + } + if (!fb_hwfbe_enabled && cur_fb.status == ci_copy) + { + if (!rdp.motionblur && (rdp.num_of_ci > rdp.ci_count+1) && (next_fb.status != ci_aux)) + { + RestoreScale(); + } + } + if (!fb_hwfbe_enabled && cur_fb.status == ci_aux) + { + if (cur_fb.format == 0) + { + if ((settings.hacks&hack_PPL) && (rdp.scale_x < 1.1f)) //need to put current image back to frame buffer + { + int width = cur_fb.width; + int height = cur_fb.height; + wxUint16 *ptr_dst = new wxUint16[width*height]; + wxUint16 *ptr_src = (wxUint16*)(gfx.RDRAM+cur_fb.addr); + wxUint16 c; + + for (int y=0; y> 1) | 0x8000; + ptr_dst[x + y * width] = c; + } + } + grLfbWriteRegion(GR_BUFFER_BACKBUFFER, + (wxUint32)rdp.offset_x, + (wxUint32)rdp.offset_y, + GR_LFB_SRC_FMT_555, + width, + height, + FXFALSE, + width<<1, + ptr_dst); + delete[] ptr_dst; + } + /* + else //just clear buffer + { + + grColorMask(FXTRUE, FXTRUE); + grBufferClear (0, 0, 0xFFFF); + } + */ + } + } + + if ((cur_fb.status == ci_main) && (rdp.ci_count > 0)) + { + int to_org_res = TRUE; + for (int i = rdp.ci_count + 1; i < rdp.num_of_ci; i++) + { + if ((rdp.frame_buffers[i].status != ci_main) && (rdp.frame_buffers[i].status != ci_zimg) && (rdp.frame_buffers[i].status != ci_zcopy)) + { + to_org_res = FALSE; + break; + } + } + if (to_org_res) + { + LRDP("return to original scale\n"); + rdp.scale_x = rdp.scale_x_bak; + rdp.scale_y = rdp.scale_y_bak; + if (fb_hwfbe_enabled && !rdp.read_whole_frame) + CloseTextureBuffer(); + } + if (fb_hwfbe_enabled && !rdp.read_whole_frame && (prev_fb.status >= ci_aux) && (rdp.ci_count > rdp.copy_ci_index)) + CloseTextureBuffer(); + + } + rdp.ci_status = cur_fb.status; + rdp.ci_count++; + } + + rdp.ocimg = rdp.cimg; + rdp.cimg = segoffset(rdp.cmd1) & BMASK; + rdp.ci_width = (rdp.cmd0 & 0xFFF) + 1; + if (fb_emulation_enabled) + rdp.ci_height = rdp.frame_buffers[rdp.ci_count-1].height; + else if (rdp.ci_width == 32) + rdp.ci_height = 32; + else + rdp.ci_height = rdp.scissor_o.lr_y; + if (rdp.zimg == rdp.cimg) + { + rdp.zi_width = rdp.ci_width; + // int zi_height = min((int)rdp.zi_width*3/4, (int)rdp.vi_height); + // rdp.zi_words = rdp.zi_width * zi_height; + } + wxUint32 format = (rdp.cmd0 >> 21) & 0x7; + rdp.ci_size = (rdp.cmd0 >> 19) & 0x3; + rdp.ci_end = rdp.cimg + ((rdp.ci_width*rdp.ci_height)<<(rdp.ci_size-1)); + FRDP("setcolorimage - %08lx, width: %d, height: %d, format: %d, size: %d\n", rdp.cmd1, rdp.ci_width, rdp.ci_height, format, rdp.ci_size); + FRDP("cimg: %08lx, ocimg: %08lx, SwapOK: %d\n", rdp.cimg, rdp.ocimg, SwapOK); + + if (format != 0) //can't draw into non RGBA buffer + { + if (!rdp.cur_image) + { + if (fb_hwfbe_enabled && rdp.ci_width <= 64) + OpenTextureBuffer(rdp.frame_buffers[rdp.ci_count - 1]); + else if (format > 2) + rdp.skip_drawing = TRUE; + return; + } + } + else + { + if (!fb_emulation_enabled) + rdp.skip_drawing = FALSE; + } + + CI_SET = TRUE; + if (settings.swapmode > 0) + { + if (rdp.zimg == rdp.cimg) + rdp.updatescreen = 1; + + int viSwapOK = ((settings.swapmode == 2) && (rdp.vi_org_reg == *gfx.VI_ORIGIN_REG)) ? FALSE : TRUE; + if ((rdp.zimg != rdp.cimg) && (rdp.ocimg != rdp.cimg) && SwapOK && viSwapOK && !rdp.cur_image) + { + if (fb_emulation_enabled) + rdp.maincimg[0] = rdp.frame_buffers[rdp.main_ci_index]; + else + rdp.maincimg[0].addr = rdp.cimg; + rdp.last_drawn_ci_addr = (settings.swapmode == 2) ? swapped_addr : rdp.maincimg[0].addr; + swapped_addr = rdp.cimg; + newSwapBuffers(); + rdp.vi_org_reg = *gfx.VI_ORIGIN_REG; + SwapOK = FALSE; + if (fb_hwfbe_enabled) + { + if (rdp.copy_ci_index && (rdp.frame_buffers[rdp.ci_count-1].status != ci_zimg)) + { + int idx = (rdp.frame_buffers[rdp.ci_count].status == ci_aux_copy) ? rdp.main_ci_index : rdp.copy_ci_index; + FRDP("attempt open tex buffer. status: %s, addr: %08lx\n", CIStatus[rdp.frame_buffers[idx].status], rdp.frame_buffers[idx].addr); + OpenTextureBuffer(rdp.frame_buffers[idx]); + if (rdp.frame_buffers[rdp.copy_ci_index].status == ci_main) //tidal wave + rdp.copy_ci_index = 0; + } + else if (rdp.read_whole_frame && !rdp.cur_image) + { + OpenTextureBuffer(rdp.frame_buffers[rdp.main_ci_index]); + } + } + } + } +} + +static void rsp_reserved0() +{ + if (settings.ucode == ucode_DiddyKong) + { + ucode5_texshiftaddr = segoffset(rdp.cmd1); + ucode5_texshiftcount = 0; + FRDP("uc5_texshift. addr: %08lx\n", ucode5_texshiftaddr); + } + else + { + RDP_E("reserved0 - IGNORED\n"); + LRDP("reserved0 - IGNORED\n"); + } +} + +static void rsp_reserved1() +{ + LRDP("reserved1 - ignored\n"); +} + +static void rsp_reserved2() +{ + LRDP("reserved2\n"); +} + +static void rsp_reserved3() +{ + LRDP("reserved3 - ignored\n"); +} + +void SetWireframeCol () +{ + if (!fullscreen) return; + + switch (settings.wfmode) + { + //case 0: // normal colors, don't do anything + case 1: // vertex colors + grColorCombine (GR_COMBINE_FUNCTION_LOCAL, + GR_COMBINE_FACTOR_NONE, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_NONE, + FXFALSE); + grAlphaCombine (GR_COMBINE_FUNCTION_LOCAL, + GR_COMBINE_FACTOR_NONE, + GR_COMBINE_LOCAL_ITERATED, + GR_COMBINE_OTHER_NONE, + FXFALSE); + grAlphaBlendFunction (GR_BLEND_ONE, + GR_BLEND_ZERO, + GR_BLEND_ZERO, + GR_BLEND_ZERO); + grTexCombine (GR_TMU0, + GR_COMBINE_FUNCTION_ZERO, + GR_COMBINE_FACTOR_NONE, + GR_COMBINE_FUNCTION_ZERO, + GR_COMBINE_FACTOR_NONE, + FXFALSE, FXFALSE); + grTexCombine (GR_TMU1, + GR_COMBINE_FUNCTION_ZERO, + GR_COMBINE_FACTOR_NONE, + GR_COMBINE_FUNCTION_ZERO, + GR_COMBINE_FACTOR_NONE, + FXFALSE, FXFALSE); + break; + case 2: // red only + grColorCombine (GR_COMBINE_FUNCTION_LOCAL, + GR_COMBINE_FACTOR_NONE, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_NONE, + FXFALSE); + grAlphaCombine (GR_COMBINE_FUNCTION_LOCAL, + GR_COMBINE_FACTOR_NONE, + GR_COMBINE_LOCAL_CONSTANT, + GR_COMBINE_OTHER_NONE, + FXFALSE); + grConstantColorValue (0xFF0000FF); + grAlphaBlendFunction (GR_BLEND_ONE, + GR_BLEND_ZERO, + GR_BLEND_ZERO, + GR_BLEND_ZERO); + grTexCombine (GR_TMU0, + GR_COMBINE_FUNCTION_ZERO, + GR_COMBINE_FACTOR_NONE, + GR_COMBINE_FUNCTION_ZERO, + GR_COMBINE_FACTOR_NONE, + FXFALSE, FXFALSE); + grTexCombine (GR_TMU1, + GR_COMBINE_FUNCTION_ZERO, + GR_COMBINE_FACTOR_NONE, + GR_COMBINE_FUNCTION_ZERO, + GR_COMBINE_FACTOR_NONE, + FXFALSE, FXFALSE); + break; + } + + grAlphaTestFunction (GR_CMP_ALWAYS); + grCullMode (GR_CULL_DISABLE); + + rdp.update |= UPDATE_COMBINE | UPDATE_ALPHA_COMPARE; +} + +/****************************************************************** +Function: FrameBufferRead +Purpose: This function is called to notify the dll that the +frame buffer memory is beening read at the given address. +DLL should copy content from its render buffer to the frame buffer +in N64 RDRAM +DLL is responsible to maintain its own frame buffer memory addr list +DLL should copy 4KB block content back to RDRAM frame buffer. +Emulator should not call this function again if other memory +is read within the same 4KB range +input: addr rdram address +val val +size 1 = wxUint8, 2 = wxUint16, 4 = wxUint32 +output: none +*******************************************************************/ +EXPORT void CALL FBRead(wxUint32 addr) +{ + LOG ("FBRead ()\n"); + + if (cpu_fb_ignore) + return; + if (cpu_fb_write_called) + { + cpu_fb_ignore = TRUE; + cpu_fb_write = FALSE; + return; + } + cpu_fb_read_called = TRUE; + wxUint32 a = segoffset(addr); + FRDP("FBRead. addr: %08lx\n", a); + if (!rdp.fb_drawn && (a >= rdp.cimg) && (a < rdp.ci_end)) + { + fbreads_back++; + //if (fbreads_back > 2) //&& (rdp.ci_width <= 320)) + { + CopyFrameBuffer (); + rdp.fb_drawn = TRUE; + } + } + if (!rdp.fb_drawn_front && (a >= rdp.maincimg[1].addr) && (a < rdp.maincimg[1].addr + rdp.ci_width*rdp.ci_height*2)) + { + fbreads_front++; + //if (fbreads_front > 2)//&& (rdp.ci_width <= 320)) + { + wxUint32 cimg = rdp.cimg; + rdp.cimg = rdp.maincimg[1].addr; + if (fb_emulation_enabled) + { + rdp.ci_width = rdp.maincimg[1].width; + rdp.ci_count = 0; + wxUint32 h = rdp.frame_buffers[0].height; + rdp.frame_buffers[0].height = rdp.maincimg[1].height; + CopyFrameBuffer(GR_BUFFER_FRONTBUFFER); + rdp.frame_buffers[0].height = h; + } + else + { + CopyFrameBuffer(GR_BUFFER_FRONTBUFFER); + } + rdp.cimg = cimg; + rdp.fb_drawn_front = TRUE; + } + } +} + +/****************************************************************** +Function: FrameBufferWriteList +Purpose: This function is called to notify the dll that the +frame buffer has been modified by CPU at the given address. +input: FrameBufferModifyEntry *plist +size = size of the plist, max = 1024 +output: none +*******************************************************************/ +EXPORT void CALL FBWList(FrameBufferModifyEntry *plist, wxUint32 size) +{ + LOG ("FBWList ()\n"); + FRDP("FBWList. size: %d\n", size); +} + + +/****************************************************************** +Function: FrameBufferWrite +Purpose: This function is called to notify the dll that the +frame buffer has been modified by CPU at the given address. +input: addr rdram address +val val +size 1 = wxUint8, 2 = wxUint16, 4 = wxUint32 +output: none +*******************************************************************/ +EXPORT void CALL FBWrite(wxUint32 addr, wxUint32 size) +{ + LOG ("FBWrite ()\n"); + if (cpu_fb_ignore) + return; + if (cpu_fb_read_called) + { + cpu_fb_ignore = TRUE; + cpu_fb_write = FALSE; + return; + } + cpu_fb_write_called = TRUE; + wxUint32 a = segoffset(addr); + FRDP("FBWrite. addr: %08lx\n", a); + if (a < rdp.cimg || a > rdp.ci_end) + return; + cpu_fb_write = TRUE; + wxUint32 shift_l = (a-rdp.cimg) >> 1; + wxUint32 shift_r = shift_l+2; + + d_ul_x = min(d_ul_x, shift_l%rdp.ci_width); + d_ul_y = min(d_ul_y, shift_l/rdp.ci_width); + d_lr_x = max(d_lr_x, shift_r%rdp.ci_width); + d_lr_y = max(d_lr_y, shift_r/rdp.ci_width); +} + + +/************************************************************************ +Function: FBGetFrameBufferInfo +Purpose: This function is called by the emulator core to retrieve frame +buffer information from the video plugin in order to be able +to notify the video plugin about CPU frame buffer read/write +operations + +size: += 1 byte += 2 word (16 bit) <-- this is N64 default depth buffer format += 4 dword (32 bit) + +when frame buffer information is not available yet, set all values +in the FrameBufferInfo structure to 0 + +input: FrameBufferInfo pinfo[6] +pinfo is pointed to a FrameBufferInfo structure which to be +filled in by this function +output: Values are return in the FrameBufferInfo structure +Plugin can return up to 6 frame buffer info +************************************************************************/ +///* +typedef struct +{ + wxUint32 addr; + wxUint32 size; + wxUint32 width; + wxUint32 height; +} FrameBufferInfo; +EXPORT void CALL FBGetFrameBufferInfo(void *p) +{ + LOG ("FBGetFrameBufferInfo ()\n"); + FrameBufferInfo * pinfo = (FrameBufferInfo *)p; + memset(pinfo,0,sizeof(FrameBufferInfo)*6); + if (!(settings.frame_buffer&fb_get_info)) + return; + LRDP("FBGetFrameBufferInfo ()\n"); + //* + if (fb_emulation_enabled) + { + pinfo[0].addr = rdp.maincimg[1].addr; + pinfo[0].size = rdp.maincimg[1].size; + pinfo[0].width = rdp.maincimg[1].width; + pinfo[0].height = rdp.maincimg[1].height; + int info_index = 1; + for (int i = 0; i < rdp.num_of_ci && info_index < 6; i++) + { + COLOR_IMAGE & cur_fb = rdp.frame_buffers[i]; + if (cur_fb.status == ci_main || cur_fb.status == ci_copy_self || + cur_fb.status == ci_old_copy) + { + pinfo[info_index].addr = cur_fb.addr; + pinfo[info_index].size = cur_fb.size; + pinfo[info_index].width = cur_fb.width; + pinfo[info_index].height = cur_fb.height; + info_index++; + } + } + } + else + { + pinfo[0].addr = rdp.maincimg[0].addr; + pinfo[0].size = rdp.ci_size; + pinfo[0].width = rdp.ci_width; + pinfo[0].height = rdp.ci_width*3/4; + pinfo[1].addr = rdp.maincimg[1].addr; + pinfo[1].size = rdp.ci_size; + pinfo[1].width = rdp.ci_width; + pinfo[1].height = rdp.ci_width*3/4; + } + //*/ +} +//*/ +#include "ucodeFB.h" + +void DetectFrameBufferUsage () +{ + LRDP("DetectFrameBufferUsage\n"); + + wxUint32 dlist_start = *(wxUint32*)(gfx.DMEM+0xFF0); + wxUint32 a; + + int tidal = FALSE; + if ((settings.hacks&hack_PMario) && (rdp.copy_ci_index || rdp.frame_buffers[rdp.copy_ci_index].status == ci_copy_self)) + tidal = TRUE; + wxUint32 ci = rdp.cimg, zi = rdp.zimg; + wxUint32 ci_height = rdp.frame_buffers[(rdp.ci_count > 0)?rdp.ci_count-1:0].height; + rdp.main_ci = rdp.main_ci_end = rdp.main_ci_bg = rdp.ci_count = 0; + rdp.main_ci_index = rdp.copy_ci_index = rdp.copy_zi_index = 0; + rdp.zimg_end = 0; + rdp.tmpzimg = 0; + rdp.motionblur = FALSE; + rdp.main_ci_last_tex_addr = 0; + int previous_ci_was_read = rdp.read_previous_ci; + rdp.read_previous_ci = FALSE; + rdp.read_whole_frame = FALSE; + rdp.swap_ci_index = rdp.black_ci_index = -1; + SwapOK = TRUE; + + // Start executing at the start of the display list + rdp.pc_i = 0; + rdp.pc[rdp.pc_i] = dlist_start; + rdp.dl_count = -1; + rdp.halt = 0; + rdp.scale_x_bak = rdp.scale_x; + rdp.scale_y_bak = rdp.scale_y; + + // MAIN PROCESSING LOOP + do { + + // Get the address of the next command + a = rdp.pc[rdp.pc_i] & BMASK; + + // Load the next command and its input + rdp.cmd0 = ((wxUint32*)gfx.RDRAM)[a>>2]; // \ Current command, 64 bit + rdp.cmd1 = ((wxUint32*)gfx.RDRAM)[(a>>2)+1]; // / + + // Output the address before the command + + // Go to the next instruction + rdp.pc[rdp.pc_i] = (a+8) & BMASK; + + if (wxPtrToUInt(reinterpret_cast(gfx_instruction_lite[settings.ucode][rdp.cmd0>>24]))) + gfx_instruction_lite[settings.ucode][rdp.cmd0>>24] (); + + // check DL counter + if (rdp.dl_count != -1) + { + rdp.dl_count --; + if (rdp.dl_count == 0) + { + rdp.dl_count = -1; + + LRDP("End of DL\n"); + rdp.pc_i --; + } + } + + } while (!rdp.halt); + SwapOK = TRUE; + if (rdp.ci_count > NUMTEXBUF) //overflow + { + rdp.cimg = ci; + rdp.zimg = zi; + rdp.num_of_ci = rdp.ci_count; + rdp.scale_x = rdp.scale_x_bak; + rdp.scale_y = rdp.scale_y_bak; + return; + } + + if (rdp.black_ci_index > 0 && rdp.black_ci_index < rdp.copy_ci_index) + rdp.frame_buffers[rdp.black_ci_index].status = ci_main; + + if (rdp.frame_buffers[rdp.ci_count-1].status == ci_unknown) + { + if (rdp.ci_count > 1) + rdp.frame_buffers[rdp.ci_count-1].status = ci_aux; + else + rdp.frame_buffers[rdp.ci_count-1].status = ci_main; + } + + if ((rdp.frame_buffers[rdp.ci_count-1].status == ci_aux) && + (rdp.frame_buffers[rdp.main_ci_index].width < 320) && + (rdp.frame_buffers[rdp.ci_count-1].width > rdp.frame_buffers[rdp.main_ci_index].width)) + { + for (int i = 0; i < rdp.ci_count; i++) + { + if (rdp.frame_buffers[i].status == ci_main) + rdp.frame_buffers[i].status = ci_aux; + else if (rdp.frame_buffers[i].addr == rdp.frame_buffers[rdp.ci_count-1].addr) + rdp.frame_buffers[i].status = ci_main; + // FRDP("rdp.frame_buffers[%d].status = %d\n", i, rdp.frame_buffers[i].status); + } + rdp.main_ci_index = rdp.ci_count-1; + } + + int all_zimg = TRUE; + int i; + for (i = 0; i < rdp.ci_count; i++) + { + if (rdp.frame_buffers[i].status != ci_zimg) + { + all_zimg = FALSE; + break; + } + } + if (all_zimg) + { + for (i = 0; i < rdp.ci_count; i++) + rdp.frame_buffers[i].status = ci_main; + } + + LRDP("detect fb final results: \n"); + for (i = 0; i < rdp.ci_count; i++) + { + FRDP("rdp.frame_buffers[%d].status = %s, addr: %08lx, height: %d\n", i, CIStatus[rdp.frame_buffers[i].status], rdp.frame_buffers[i].addr, rdp.frame_buffers[i].height); + } + + rdp.cimg = ci; + rdp.zimg = zi; + rdp.num_of_ci = rdp.ci_count; + if (rdp.read_previous_ci && previous_ci_was_read) + { + if (!fb_hwfbe_enabled || !rdp.copy_ci_index) + rdp.motionblur = TRUE; + } + if (rdp.motionblur || fb_hwfbe_enabled || (rdp.frame_buffers[rdp.copy_ci_index].status == ci_aux_copy)) + { + rdp.scale_x = rdp.scale_x_bak; + rdp.scale_y = rdp.scale_y_bak; + } + + if ((rdp.read_previous_ci || previous_ci_was_read) && !rdp.copy_ci_index) + rdp.read_whole_frame = TRUE; + if (rdp.read_whole_frame) + { + if (fb_hwfbe_enabled) + { + if (rdp.read_previous_ci && !previous_ci_was_read && (settings.swapmode != 2) && (settings.ucode != ucode_PerfectDark)) + { + int ind = (rdp.ci_count > 0)?rdp.ci_count-1:0; + wxUint32 height = rdp.frame_buffers[ind].height; + rdp.frame_buffers[ind].height = ci_height; + CopyFrameBuffer(); + rdp.frame_buffers[ind].height = height; + } + if (rdp.swap_ci_index < 0) + { + rdp.texbufs[0].clear_allowed = rdp.texbufs[1].clear_allowed = TRUE; + OpenTextureBuffer(rdp.frame_buffers[rdp.main_ci_index]); + } + } + else + { + if (rdp.motionblur) + { + if (settings.frame_buffer&fb_motionblur) + CopyFrameBuffer(); + else + memset(gfx.RDRAM+rdp.cimg, 0, rdp.ci_width*rdp.ci_height*rdp.ci_size); + } + else //if (ci_width == rdp.frame_buffers[rdp.main_ci_index].width) + { + if (rdp.maincimg[0].height > 65) //for 1080 + { + rdp.cimg = rdp.maincimg[0].addr; + rdp.ci_width = rdp.maincimg[0].width; + rdp.ci_count = 0; + wxUint32 h = rdp.frame_buffers[0].height; + rdp.frame_buffers[0].height = rdp.maincimg[0].height; + CopyFrameBuffer(); + rdp.frame_buffers[0].height = h; + } + else //conker + { + CopyFrameBuffer(); + } + } + } + } + + if (fb_hwfbe_enabled) + { + for (i = 0; i < voodoo.num_tmu; i++) + { + rdp.texbufs[i].clear_allowed = TRUE; + for (int j = 0; j < 256; j++) + { + rdp.texbufs[i].images[j].drawn = FALSE; + rdp.texbufs[i].images[j].clear = TRUE; + } + } + if (tidal) + { + //LRDP("Tidal wave!\n"); + rdp.copy_ci_index = rdp.main_ci_index; + } + } + rdp.ci_count = 0; + if (settings.hacks&hack_Banjo2) + rdp.cur_tex_buf = 0; + rdp.maincimg[0] = rdp.frame_buffers[rdp.main_ci_index]; + // rdp.scale_x = rdp.scale_x_bak; + // rdp.scale_y = rdp.scale_y_bak; + LRDP("DetectFrameBufferUsage End\n"); +} + +/******************************************* + * ProcessRDPList * + ******************************************* + * based on sources of ziggy's z64 * + *******************************************/ + +static wxUint32 rdp_cmd_ptr = 0; +static wxUint32 rdp_cmd_cur = 0; +static wxUint32 rdp_cmd_data[0x1000]; + +void lle_triangle(wxUint32 w1, wxUint32 w2, int shade, int texture, int zbuffer, + wxUint32 * rdp_cmd) +{ + rdp.cur_tile = (w1 >> 16) & 0x7; + int j; + int xleft, xright, xleft_inc, xright_inc; + int r, g, b, a, z, s, t, w; + int drdx = 0, dgdx = 0, dbdx = 0, dadx = 0, dzdx = 0, dsdx = 0, dtdx = 0, dwdx = 0; + int drde = 0, dgde = 0, dbde = 0, dade = 0, dzde = 0, dsde = 0, dtde = 0, dwde = 0; + int flip = (w1 & 0x800000) ? 1 : 0; + + wxInt32 yl, ym, yh; + wxInt32 xl, xm, xh; + wxInt32 dxldy, dxhdy, dxmdy; + wxUint32 w3, w4, w5, w6, w7, w8; + + wxUint32 * shade_base = rdp_cmd + 8; + wxUint32 * texture_base = rdp_cmd + 8; + wxUint32 * zbuffer_base = rdp_cmd + 8; + + if (shade) + { + texture_base += 16; + zbuffer_base += 16; + } + if (texture) + { + zbuffer_base += 16; + } + + w3 = rdp_cmd[2]; + w4 = rdp_cmd[3]; + w5 = rdp_cmd[4]; + w6 = rdp_cmd[5]; + w7 = rdp_cmd[6]; + w8 = rdp_cmd[7]; + + yl = (w1 & 0x3fff); + ym = ((w2 >> 16) & 0x3fff); + yh = ((w2 >> 0) & 0x3fff); + xl = (wxInt32)(w3); + xh = (wxInt32)(w5); + xm = (wxInt32)(w7); + dxldy = (wxInt32)(w4); + dxhdy = (wxInt32)(w6); + dxmdy = (wxInt32)(w8); + + if (yl & (0x800<<2)) yl |= 0xfffff000<<2; + if (ym & (0x800<<2)) ym |= 0xfffff000<<2; + if (yh & (0x800<<2)) yh |= 0xfffff000<<2; + + yh &= ~3; + + r = 0xff; g = 0xff; b = 0xff; a = 0xff; z = 0xffff0000; s = 0; t = 0; w = 0x30000; + + if (shade) + { + r = (shade_base[0] & 0xffff0000) | ((shade_base[+4 ] >> 16) & 0x0000ffff); + g = ((shade_base[0 ] << 16) & 0xffff0000) | (shade_base[4 ] & 0x0000ffff); + b = (shade_base[1 ] & 0xffff0000) | ((shade_base[5 ] >> 16) & 0x0000ffff); + a = ((shade_base[1 ] << 16) & 0xffff0000) | (shade_base[5 ] & 0x0000ffff); + drdx = (shade_base[2 ] & 0xffff0000) | ((shade_base[6 ] >> 16) & 0x0000ffff); + dgdx = ((shade_base[2 ] << 16) & 0xffff0000) | (shade_base[6 ] & 0x0000ffff); + dbdx = (shade_base[3 ] & 0xffff0000) | ((shade_base[7 ] >> 16) & 0x0000ffff); + dadx = ((shade_base[3 ] << 16) & 0xffff0000) | (shade_base[7 ] & 0x0000ffff); + drde = (shade_base[8 ] & 0xffff0000) | ((shade_base[12] >> 16) & 0x0000ffff); + dgde = ((shade_base[8 ] << 16) & 0xffff0000) | (shade_base[12] & 0x0000ffff); + dbde = (shade_base[9 ] & 0xffff0000) | ((shade_base[13] >> 16) & 0x0000ffff); + dade = ((shade_base[9 ] << 16) & 0xffff0000) | (shade_base[13] & 0x0000ffff); + } + if (texture) + { + s = (texture_base[0 ] & 0xffff0000) | ((texture_base[4 ] >> 16) & 0x0000ffff); + t = ((texture_base[0 ] << 16) & 0xffff0000) | (texture_base[4 ] & 0x0000ffff); + w = (texture_base[1 ] & 0xffff0000) | ((texture_base[5 ] >> 16) & 0x0000ffff); + // w = abs(w); + dsdx = (texture_base[2 ] & 0xffff0000) | ((texture_base[6 ] >> 16) & 0x0000ffff); + dtdx = ((texture_base[2 ] << 16) & 0xffff0000) | (texture_base[6 ] & 0x0000ffff); + dwdx = (texture_base[3 ] & 0xffff0000) | ((texture_base[7 ] >> 16) & 0x0000ffff); + dsde = (texture_base[8 ] & 0xffff0000) | ((texture_base[12] >> 16) & 0x0000ffff); + dtde = ((texture_base[8 ] << 16) & 0xffff0000) | (texture_base[12] & 0x0000ffff); + dwde = (texture_base[9 ] & 0xffff0000) | ((texture_base[13] >> 16) & 0x0000ffff); + } + if (zbuffer) + { + z = zbuffer_base[0]; + dzdx = zbuffer_base[1]; + dzde = zbuffer_base[2]; + } + + xh <<= 2; xm <<= 2; xl <<= 2; + r <<= 2; g <<= 2; b <<= 2; a <<= 2; + dsde >>= 2; dtde >>= 2; dsdx >>= 2; dtdx >>= 2; + dzdx >>= 2; dzde >>= 2; + dwdx >>= 2; dwde >>= 2; + +#define XSCALE(x) (float(x)/(1<<18)) +#define YSCALE(y) (float(y)/(1<<2)) +#define ZSCALE(z) ((rdp.zsrc == 1)? float(rdp.prim_depth) : float(wxUint32(z))/0xffff0000) + //#define WSCALE(w) (rdp.Persp_en? (float(wxUint32(w) + 0x10000)/0xffff0000) : 1.0f) + //#define WSCALE(w) (rdp.Persp_en? 4294901760.0/(w + 65536) : 1.0f) +#define WSCALE(w) (rdp.Persp_en? 65536.0f/float((w+ 0xffff)>>16) : 1.0f) +#define CSCALE(c) (((c)>0x3ff0000? 0x3ff0000:((c)<0? 0 : (c)))>>18) +#define _PERSP(w) ( w ) +#define PERSP(s, w) ( ((int64)(s) << 20) / (_PERSP(w)? _PERSP(w):1) ) +#define SSCALE(s, _w) (rdp.Persp_en? float(PERSP(s, _w))/(1 << 10) : float(s)/(1<<21)) +#define TSCALE(s, w) (rdp.Persp_en? float(PERSP(s, w))/(1 << 10) : float(s)/(1<<21)) + + int nbVtxs = 0; + VERTEX vtxbuf[12]; + VERTEX * vtx = &vtxbuf[nbVtxs++]; + + xleft = xm; + xright = xh; + xleft_inc = dxmdy; + xright_inc = dxhdy; + + while (yh xright-0x10000))) { + xleft += xleft_inc; + xright += xright_inc; + s += dsde; t += dtde; w += dwde; + r += drde; g += dgde; b += dbde; a += dade; + z += dzde; + yh++; + } + + j = ym-yh; + if (j > 0) + { + int dx = (xleft-xright)>>16; + if ((!flip && xleft < xright) || + (flip/* && xleft > xright*/)) + { + if (shade) { + vtx->r = CSCALE(r+drdx*dx); + vtx->g = CSCALE(g+dgdx*dx); + vtx->b = CSCALE(b+dbdx*dx); + vtx->a = CSCALE(a+dadx*dx); + } + if (texture) { + vtx->ou = SSCALE(s+dsdx*dx, w+dwdx*dx); + vtx->ov = TSCALE(t+dtdx*dx, w+dwdx*dx); + } + vtx->x = XSCALE(xleft); + vtx->y = YSCALE(yh); + vtx->z = ZSCALE(z+dzdx*dx); + vtx->w = WSCALE(w+dwdx*dx); + vtx = &vtxbuf[nbVtxs++]; + } + if ((!flip/* && xleft < xright*/) || + (flip && xleft > xright)) + { + if (shade) { + vtx->r = CSCALE(r); + vtx->g = CSCALE(g); + vtx->b = CSCALE(b); + vtx->a = CSCALE(a); + } + if (texture) { + vtx->ou = SSCALE(s, w); + vtx->ov = TSCALE(t, w); + } + vtx->x = XSCALE(xright); + vtx->y = YSCALE(yh); + vtx->z = ZSCALE(z); + vtx->w = WSCALE(w); + vtx = &vtxbuf[nbVtxs++]; + } + xleft += xleft_inc*j; xright += xright_inc*j; + s += dsde*j; t += dtde*j; + if (w + dwde*j) w += dwde*j; + else w += dwde*(j-1); + r += drde*j; g += dgde*j; b += dbde*j; a += dade*j; + z += dzde*j; + // render ... + } + + if (xl != xh) + xleft = xl; + + //if (yl-ym > 0) + { + int dx = (xleft-xright)>>16; + if ((!flip && xleft <= xright) || + (flip/* && xleft >= xright*/)) + { + if (shade) { + vtx->r = CSCALE(r+drdx*dx); + vtx->g = CSCALE(g+dgdx*dx); + vtx->b = CSCALE(b+dbdx*dx); + vtx->a = CSCALE(a+dadx*dx); + } + if (texture) { + vtx->ou = SSCALE(s+dsdx*dx, w+dwdx*dx); + vtx->ov = TSCALE(t+dtdx*dx, w+dwdx*dx); + } + vtx->x = XSCALE(xleft); + vtx->y = YSCALE(ym); + vtx->z = ZSCALE(z+dzdx*dx); + vtx->w = WSCALE(w+dwdx*dx); + vtx = &vtxbuf[nbVtxs++]; + } + if ((!flip/* && xleft <= xright*/) || + (flip && xleft >= xright)) + { + if (shade) { + vtx->r = CSCALE(r); + vtx->g = CSCALE(g); + vtx->b = CSCALE(b); + vtx->a = CSCALE(a); + } + if (texture) { + vtx->ou = SSCALE(s, w); + vtx->ov = TSCALE(t, w); + } + vtx->x = XSCALE(xright); + vtx->y = YSCALE(ym); + vtx->z = ZSCALE(z); + vtx->w = WSCALE(w); + vtx = &vtxbuf[nbVtxs++]; + } + } + xleft_inc = dxldy; + xright_inc = dxhdy; + + j = yl-ym; + //j--; // ? + xleft += xleft_inc*j; xright += xright_inc*j; + s += dsde*j; t += dtde*j; w += dwde*j; + r += drde*j; g += dgde*j; b += dbde*j; a += dade*j; + z += dzde*j; + + while (yl>ym && + !((!flip && xleft < xright+0x10000) || + (flip && xleft > xright-0x10000))) { + xleft -= xleft_inc; xright -= xright_inc; + s -= dsde; t -= dtde; w -= dwde; + r -= drde; g -= dgde; b -= dbde; a -= dade; + z -= dzde; + j--; + yl--; + } + + // render ... + if (j >= 0) { + int dx = (xleft-xright)>>16; + if ((!flip && xleft <= xright) || + (flip/* && xleft >= xright*/)) + { + if (shade) { + vtx->r = CSCALE(r+drdx*dx); + vtx->g = CSCALE(g+dgdx*dx); + vtx->b = CSCALE(b+dbdx*dx); + vtx->a = CSCALE(a+dadx*dx); + } + if (texture) { + vtx->ou = SSCALE(s+dsdx*dx, w+dwdx*dx); + vtx->ov = TSCALE(t+dtdx*dx, w+dwdx*dx); + } + vtx->x = XSCALE(xleft); + vtx->y = YSCALE(yl); + vtx->z = ZSCALE(z+dzdx*dx); + vtx->w = WSCALE(w+dwdx*dx); + vtx = &vtxbuf[nbVtxs++]; + } + if ((!flip/* && xleft <= xright*/) || + (flip && xleft >= xright)) + { + if (shade) { + vtx->r = CSCALE(r); + vtx->g = CSCALE(g); + vtx->b = CSCALE(b); + vtx->a = CSCALE(a); + } + if (texture) { + vtx->ou = SSCALE(s, w); + vtx->ov = TSCALE(t, w); + } + vtx->x = XSCALE(xright); + vtx->y = YSCALE(yl); + vtx->z = ZSCALE(z); + vtx->w = WSCALE(w); + vtx = &vtxbuf[nbVtxs++]; + } + } + + if (fullscreen) + { + update (); + for (int k = 0; k < nbVtxs-1; k++) + { + VERTEX * v = &vtxbuf[k]; + v->x = v->x * rdp.scale_x + rdp.offset_x; + v->y = v->y * rdp.scale_y + rdp.offset_y; + // v->z = 1.0f;///v->w; + v->q = 1.0f/v->w; + v->u1 = v->u0 = v->ou; + v->v1 = v->v0 = v->ov; + if (rdp.tex >= 1 && rdp.cur_cache[0]) + { + if (rdp.tiles[rdp.cur_tile].shift_s) + { + if (rdp.tiles[rdp.cur_tile].shift_s > 10) + v->u0 *= (float)(1 << (16 - rdp.tiles[rdp.cur_tile].shift_s)); + else + v->u0 /= (float)(1 << rdp.tiles[rdp.cur_tile].shift_s); + } + if (rdp.tiles[rdp.cur_tile].shift_t) + { + if (rdp.tiles[rdp.cur_tile].shift_t > 10) + v->v0 *= (float)(1 << (16 - rdp.tiles[rdp.cur_tile].shift_t)); + else + v->v0 /= (float)(1 << rdp.tiles[rdp.cur_tile].shift_t); + } + + v->u0 -= rdp.tiles[rdp.cur_tile].f_ul_s; + v->v0 -= rdp.tiles[rdp.cur_tile].f_ul_t; + v->u0 = rdp.cur_cache[0]->c_off + rdp.cur_cache[0]->c_scl_x * v->u0; + v->v0 = rdp.cur_cache[0]->c_off + rdp.cur_cache[0]->c_scl_y * v->v0; + v->u0 /= v->w; + v->v0 /= v->w; + } + + if (rdp.tex >= 2 && rdp.cur_cache[1]) + { + if (rdp.tiles[rdp.cur_tile+1].shift_s) + { + if (rdp.tiles[rdp.cur_tile+1].shift_s > 10) + v->u1 *= (float)(1 << (16 - rdp.tiles[rdp.cur_tile+1].shift_s)); + else + v->u1 /= (float)(1 << rdp.tiles[rdp.cur_tile+1].shift_s); + } + if (rdp.tiles[rdp.cur_tile+1].shift_t) + { + if (rdp.tiles[rdp.cur_tile+1].shift_t > 10) + v->v1 *= (float)(1 << (16 - rdp.tiles[rdp.cur_tile+1].shift_t)); + else + v->v1 /= (float)(1 << rdp.tiles[rdp.cur_tile+1].shift_t); + } + + v->u1 -= rdp.tiles[rdp.cur_tile+1].f_ul_s; + v->v1 -= rdp.tiles[rdp.cur_tile+1].f_ul_t; + v->u1 = rdp.cur_cache[1]->c_off + rdp.cur_cache[1]->c_scl_x * v->u1; + v->v1 = rdp.cur_cache[1]->c_off + rdp.cur_cache[1]->c_scl_y * v->v1; + v->u1 /= v->w; + v->v1 /= v->w; + } + apply_shade_mods (v); + } + ConvertCoordsConvert (vtxbuf, nbVtxs); + grCullMode (GR_CULL_DISABLE); + grDrawVertexArrayContiguous (GR_TRIANGLE_STRIP, nbVtxs-1, vtxbuf, sizeof(VERTEX)); + if (_debugger.capture) + { + VERTEX vl[3]; + vl[0] = vtxbuf[0]; + vl[1] = vtxbuf[2]; + vl[2] = vtxbuf[1]; + add_tri (vl, 3, TRI_TRIANGLE); + rdp.tri_n++; + if (nbVtxs > 4) + { + vl[0] = vtxbuf[2]; + vl[1] = vtxbuf[3]; + vl[2] = vtxbuf[1]; + add_tri (vl, 3, TRI_TRIANGLE); + rdp.tri_n++; + } + } + } +} + +static void rdp_triangle(int shade, int texture, int zbuffer) +{ + lle_triangle(rdp.cmd0, rdp.cmd1, shade, texture, zbuffer, rdp_cmd_data + rdp_cmd_cur); +} + +static void rdp_trifill() +{ + rdp_triangle(0, 0, 0); + LRDP("trifill\n"); +} + +static void rdp_trishade() +{ + rdp_triangle(1, 0, 0); + LRDP("trishade\n"); +} + +static void rdp_tritxtr() +{ + rdp_triangle(0, 1, 0); + LRDP("tritxtr\n"); +} + +static void rdp_trishadetxtr() +{ + rdp_triangle(1, 1, 0); + LRDP("trishadetxtr\n"); +} + +static void rdp_trifillz() +{ + rdp_triangle(0, 0, 1); + LRDP("trifillz\n"); +} + +static void rdp_trishadez() +{ + rdp_triangle(1, 0, 1); + LRDP("trishadez\n"); +} + +static void rdp_tritxtrz() +{ + rdp_triangle(0, 1, 1); + LRDP("tritxtrz\n"); +} + +static void rdp_trishadetxtrz() +{ + rdp_triangle(1, 1, 1); + LRDP("trishadetxtrz\n"); +} + + +static rdp_instr rdp_command_table[64] = +{ + /* 0x00 */ + spnoop, undef, undef, undef, + undef, undef, undef, undef, + rdp_trifill, rdp_trifillz, rdp_tritxtr, rdp_tritxtrz, + rdp_trishade, rdp_trishadez, rdp_trishadetxtr, rdp_trishadetxtrz, + /* 0x10 */ + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + /* 0x20 */ + undef, undef, undef, undef, + rdp_texrect, rdp_texrect, rdp_loadsync, rdp_pipesync, + rdp_tilesync, rdp_fullsync, rdp_setkeygb, rdp_setkeyr, + rdp_setconvert, rdp_setscissor, rdp_setprimdepth, rdp_setothermode, + /* 0x30 */ + rdp_loadtlut, undef, rdp_settilesize, rdp_loadblock, + rdp_loadtile, rdp_settile, rdp_fillrect, rdp_setfillcolor, + rdp_setfogcolor, rdp_setblendcolor, rdp_setprimcolor, rdp_setenvcolor, + rdp_setcombine, rdp_settextureimage, rdp_setdepthimage, rdp_setcolorimage +}; + +static const wxUint32 rdp_command_length[64] = +{ + 8, // 0x00, No Op + 8, // 0x01, ??? + 8, // 0x02, ??? + 8, // 0x03, ??? + 8, // 0x04, ??? + 8, // 0x05, ??? + 8, // 0x06, ??? + 8, // 0x07, ??? + 32, // 0x08, Non-Shaded Triangle + 32+16, // 0x09, Non-Shaded, Z-Buffered Triangle + 32+64, // 0x0a, Textured Triangle + 32+64+16, // 0x0b, Textured, Z-Buffered Triangle + 32+64, // 0x0c, Shaded Triangle + 32+64+16, // 0x0d, Shaded, Z-Buffered Triangle + 32+64+64, // 0x0e, Shaded+Textured Triangle + 32+64+64+16,// 0x0f, Shaded+Textured, Z-Buffered Triangle + 8, // 0x10, ??? + 8, // 0x11, ??? + 8, // 0x12, ??? + 8, // 0x13, ??? + 8, // 0x14, ??? + 8, // 0x15, ??? + 8, // 0x16, ??? + 8, // 0x17, ??? + 8, // 0x18, ??? + 8, // 0x19, ??? + 8, // 0x1a, ??? + 8, // 0x1b, ??? + 8, // 0x1c, ??? + 8, // 0x1d, ??? + 8, // 0x1e, ??? + 8, // 0x1f, ??? + 8, // 0x20, ??? + 8, // 0x21, ??? + 8, // 0x22, ??? + 8, // 0x23, ??? + 16, // 0x24, Texture_Rectangle + 16, // 0x25, Texture_Rectangle_Flip + 8, // 0x26, Sync_Load + 8, // 0x27, Sync_Pipe + 8, // 0x28, Sync_Tile + 8, // 0x29, Sync_Full + 8, // 0x2a, Set_Key_GB + 8, // 0x2b, Set_Key_R + 8, // 0x2c, Set_Convert + 8, // 0x2d, Set_Scissor + 8, // 0x2e, Set_Prim_Depth + 8, // 0x2f, Set_Other_Modes + 8, // 0x30, Load_TLUT + 8, // 0x31, ??? + 8, // 0x32, Set_Tile_Size + 8, // 0x33, Load_Block + 8, // 0x34, Load_Tile + 8, // 0x35, Set_Tile + 8, // 0x36, Fill_Rectangle + 8, // 0x37, Set_Fill_Color + 8, // 0x38, Set_Fog_Color + 8, // 0x39, Set_Blend_Color + 8, // 0x3a, Set_Prim_Color + 8, // 0x3b, Set_Env_Color + 8, // 0x3c, Set_Combine + 8, // 0x3d, Set_Texture_Image + 8, // 0x3e, Set_Mask_Image + 8 // 0x3f, Set_Color_Image +}; + +#define rdram ((wxUint32*)gfx.RDRAM) +#define rsp_dmem ((wxUint32*)gfx.DMEM) + +#define dp_start (*(wxUint32*)gfx.DPC_START_REG) +#define dp_end (*(wxUint32*)gfx.DPC_END_REG) +#define dp_current (*(wxUint32*)gfx.DPC_CURRENT_REG) +#define dp_status (*(wxUint32*)gfx.DPC_STATUS_REG) + +inline wxUint32 READ_RDP_DATA(wxUint32 address) +{ + if (dp_status & 0x1) // XBUS_DMEM_DMA enabled + return rsp_dmem[(address & 0xfff)>>2]; + else + return rdram[address>>2]; +} + +static void rdphalf_1() +{ + wxUint32 cmd = rdp.cmd1 >> 24; + if (cmd >= 0xc8 && cmd <=0xcf) //triangle command + { + LRDP("rdphalf_1 - lle triangle\n"); + rdp_cmd_ptr = 0; + rdp_cmd_cur = 0; + wxUint32 a; + + do + { + rdp_cmd_data[rdp_cmd_ptr++] = rdp.cmd1; + // check DL counter + if (rdp.dl_count != -1) + { + rdp.dl_count --; + if (rdp.dl_count == 0) + { + rdp.dl_count = -1; + + LRDP("End of DL\n"); + rdp.pc_i --; + } + } + + // Get the address of the next command + a = rdp.pc[rdp.pc_i] & BMASK; + + // Load the next command and its input + rdp.cmd0 = ((wxUint32*)gfx.RDRAM)[a>>2]; // \ Current command, 64 bit + rdp.cmd1 = ((wxUint32*)gfx.RDRAM)[(a>>2)+1]; // / + + // Go to the next instruction + rdp.pc[rdp.pc_i] = (a+8) & BMASK; + + }while ((rdp.cmd0 >> 24) != 0xb3); + rdp_cmd_data[rdp_cmd_ptr++] = rdp.cmd1; + cmd = (rdp_cmd_data[rdp_cmd_cur] >> 24) & 0x3f; + rdp.cmd0 = rdp_cmd_data[rdp_cmd_cur+0]; + rdp.cmd1 = rdp_cmd_data[rdp_cmd_cur+1]; + /* + wxUint32 cmd3 = ((wxUint32*)gfx.RDRAM)[(a>>2)+2]; + if ((cmd3>>24) == 0xb4) + rglSingleTriangle = TRUE; + else + rglSingleTriangle = FALSE; + */ + rdp_command_table[cmd](); + } + else + { + LRDP("rdphalf_1 - IGNORED\n"); + } +} + +static void rdphalf_2() +{ + RDP_E("rdphalf_2 - IGNORED\n"); + LRDP("rdphalf_2 - IGNORED\n"); +} + +static void rdphalf_cont() +{ + RDP_E("rdphalf_cont - IGNORED\n"); + LRDP("rdphalf_cont - IGNORED\n"); +} + +/****************************************************************** +Function: ProcessRDPList +Purpose: This function is called when there is a Dlist to be +processed. (Low level GFX list) +input: none +output: none +*******************************************************************/ +void CALL ProcessRDPList(void) +{ + LOG ("ProcessRDPList ()\n"); + LRDP("ProcessRDPList ()\n"); + + SoftLocker lock(mutexProcessDList); + if (!lock.IsOk()) //mutex is busy + { + if (!fullscreen) + drawNoFullscreenMessage(); + // Set an interrupt to allow the game to continue + *gfx.MI_INTR_REG |= 0x20; + gfx.CheckInterrupts(); + return; + } + + wxUint32 i; + wxUint32 cmd, length, cmd_length; + rdp_cmd_ptr = 0; + rdp_cmd_cur = 0; + + if (dp_end <= dp_current) return; + length = dp_end - dp_current; + + // load command data + for (i=0; i < length; i += 4) + { + rdp_cmd_data[rdp_cmd_ptr++] = READ_RDP_DATA(dp_current + i); + if (rdp_cmd_ptr >= 0x1000) + { + FRDP("rdp_process_list: rdp_cmd_ptr overflow %x %x --> %x\n", length, dp_current, dp_end); + } + } + + dp_current = dp_end; + + cmd = (rdp_cmd_data[0] >> 24) & 0x3f; + cmd_length = (rdp_cmd_ptr + 1) * 4; + + // check if more data is needed + if (cmd_length < rdp_command_length[cmd]) + return; + rdp.LLE = TRUE; + while (rdp_cmd_cur < rdp_cmd_ptr) + { + cmd = (rdp_cmd_data[rdp_cmd_cur] >> 24) & 0x3f; + + if (((rdp_cmd_ptr-rdp_cmd_cur) * 4) < rdp_command_length[cmd]) + return; + + // execute the command + rdp.cmd0 = rdp_cmd_data[rdp_cmd_cur+0]; + rdp.cmd1 = rdp_cmd_data[rdp_cmd_cur+1]; + rdp.cmd2 = rdp_cmd_data[rdp_cmd_cur+2]; + rdp.cmd3 = rdp_cmd_data[rdp_cmd_cur+3]; + rdp_command_table[cmd](); + + rdp_cmd_cur += rdp_command_length[cmd] / 4; + }; + rdp.LLE = FALSE; + + dp_start = dp_end; + + dp_status &= ~0x0002; + + //} +} + diff --git a/Source/Glide64/rdp.h b/Source/Glide64/rdp.h new file mode 100644 index 000000000..c6fcf201e --- /dev/null +++ b/Source/Glide64/rdp.h @@ -0,0 +1,912 @@ +/* +* Glide64 - Glide video plugin for Nintendo 64 emulators. +* Copyright (c) 2002 Dave2001 +* Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski +* +* 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 +* 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 +*/ + +//**************************************************************** +// +// Glide64 - Glide Plugin for Nintendo 64 emulators +// Project started on December 29th, 2001 +// +// Authors: +// Dave2001, original author, founded the project in 2001, left it in 2002 +// Gugaman, joined the project in 2002, left it in 2002 +// Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002 +// Hiroshi 'KoolSmoky' Morii, joined the project in 2007 +// +//**************************************************************** +// +// To modify Glide64: +// * Write your name and (optional)email, commented by your work, so I know who did it, and so that you can find which parts you modified when it comes time to send it to me. +// * Do NOT send me the whole project or file that you modified. Take out your modified code sections, and tell me where to put them. If people sent the whole thing, I would have many different versions, but no idea how to combine them all. +// +//**************************************************************** + +#ifndef RDP_H +#define RDP_H + +extern char out_buf[2048]; + +extern wxUint32 frame_count; // frame counter + +//GlideHQ support +#define TEXTURE_FILTER +#ifdef TEXTURE_FILTER +#include "Ext_TxFilter.h" +#endif + +#define MAX_CACHE 1024*4 +#define MAX_TRI_CACHE 768 // this is actually # of vertices, not triangles +#define MAX_VTX 256 + +#define MAX_TMU 2 + +#define TEXMEM_2MB_EDGE 2097152 + +// Supported flags +#define SUP_TEXMIRROR 0x00000001 + +// Clipping flags +#define CLIP_XMAX 0x00000001 +#define CLIP_XMIN 0x00000002 +#define CLIP_YMAX 0x00000004 +#define CLIP_YMIN 0x00000008 +#define CLIP_WMIN 0x00000010 +#define CLIP_ZMAX 0x00000020 +#define CLIP_ZMIN 0x00000040 + +// Flags +#define ZBUF_ENABLED 0x00000001 +#define ZBUF_DECAL 0x00000002 +#define ZBUF_COMPARE 0x00000004 +#define ZBUF_UPDATE 0x00000008 +#define ALPHA_COMPARE 0x00000010 +#define FORCE_BL 0x00000020 +#define CULL_FRONT 0x00001000 // * must be here +#define CULL_BACK 0x00002000 // * must be here +#define FOG_ENABLED 0x00010000 + +#define CULLMASK 0x00003000 +#define CULLSHIFT 12 + +// Update flags +#define UPDATE_ZBUF_ENABLED 0x00000001 + +#define UPDATE_TEXTURE 0x00000002 // \ Same thing! +#define UPDATE_COMBINE 0x00000002 // / + +#define UPDATE_CULL_MODE 0x00000004 +#define UPDATE_LIGHTS 0x00000010 +#define UPDATE_BIASLEVEL 0x00000020 +#define UPDATE_ALPHA_COMPARE 0x00000040 +#define UPDATE_VIEWPORT 0x00000080 +#define UPDATE_MULT_MAT 0x00000100 +#define UPDATE_SCISSOR 0x00000200 +#define UPDATE_FOG_ENABLED 0x00010000 + +#define CMB_MULT 0x00000001 +#define CMB_SET 0x00000002 +#define CMB_SUB 0x00000004 +#define CMB_ADD 0x00000008 +#define CMB_A_MULT 0x00000010 +#define CMB_A_SET 0x00000020 +#define CMB_A_SUB 0x00000040 +#define CMB_A_ADD 0x00000080 +#define CMB_SETSHADE_SHADEALPHA 0x00000100 +#define CMB_INTER 0x00000200 +#define CMB_MULT_OWN_ALPHA 0x00000400 +#define CMB_COL_SUB_OWN 0x00000800 + +#define uc(x) coord[x<<1] +#define vc(x) coord[(x<<1)+1] + +#if defined __VISUALC__ +#define DECLAREALIGN16VAR(var) __declspec(align(16)) float (var) +#elif defined __GNUG__ +#define DECLAREALIGN16VAR(var) float (var) __attribute__ ((aligned(16))) +#endif + +// Vertex structure +typedef struct +{ + float x, y, z, q; + float u0, v0, u1, v1; + float coord[4]; + float w; + wxUint16 flags; + + wxUint8 b; // These values are arranged like this so that *(wxUint32*)(VERTEX+?) is + wxUint8 g; // ARGB format that glide can use. + wxUint8 r; + wxUint8 a; + + float f; //fog + + float vec[3]; // normal vector + + float sx, sy, sz; + float x_w, y_w, z_w, u0_w, v0_w, u1_w, v1_w, oow; + wxUint8 not_zclipped; + wxUint8 screen_translated; + wxUint8 uv_scaled; + wxUint32 uv_calculated; // like crc + wxUint32 shade_mod; + wxUint32 color_backup; + + float ou, ov; + + int number; // way to identify it + int scr_off, z_off; // off the screen? +} VERTEX; + +// Clipping (scissors) +typedef struct { + wxUint32 ul_x; + wxUint32 ul_y; + wxUint32 lr_x; + wxUint32 lr_y; +} SCISSOR; + +#ifdef TEXTURE_FILTER +extern wxUint32 texfltr[]; +extern wxUint32 texenht[]; +extern wxUint32 texcmpr[]; +extern wxUint32 texhirs[]; + +typedef struct { + wxUint16 tile_ul_s; + wxUint16 tile_ul_t; + wxUint16 tile_width; + wxUint16 tile_height; + wxUint16 tex_width; + wxUint16 tex_size; + wxUint32 dxt; +} LOAD_TILE_INFO; +#endif + +typedef struct { + const wxChar * format; + const wxChar * extension; + wxBitmapType type; +} SCREEN_SHOT_FORMAT; + +extern const int NumOfFormats; +extern SCREEN_SHOT_FORMAT ScreenShotFormats[]; + +typedef struct { + int card_id; + int lang_id; + + wxUint32 res_x, scr_res_x; + wxUint32 res_y, scr_res_y; + wxUint32 res_data, res_data_org; + + int advanced_options; + int texenh_options; + int ssformat; + int vsync; + + int show_fps; + int clock; + int clock_24_hr; + + int filtering; + int fog; + int buff_clear; + int swapmode; + int lodmode; + int aspectmode; + int use_hotkeys; + + //Frame buffer emulation options + #define fb_emulation (1<<0) //frame buffer emulation + #define fb_hwfbe (1<<1) //hardware frame buffer emualtion + #define fb_motionblur (1<<2) //emulate motion blur + #define fb_ref (1<<3) //read every frame + #define fb_read_alpha (1<<4) //read alpha + #define fb_hwfbe_buf_clear (1<<5) //clear auxiliary texture frame buffers + #define fb_depth_render (1<<6) //enable software depth render + #define fb_optimize_texrect (1<<7) //fast texrect rendering with hwfbe + #define fb_ignore_aux_copy (1<<8) //do not copy auxiliary frame buffers + #define fb_useless_is_useless (1<<10) // + #define fb_get_info (1<<11) //get frame buffer info + #define fb_read_back_to_screen (1<<12) //render N64 frame buffer to screen + #define fb_read_back_to_screen2 (1<<13) //render N64 frame buffer to screen + #define fb_cpu_write_hack (1<<14) //show images writed directly by CPU + + #define fb_emulation_enabled ((settings.frame_buffer&fb_emulation)>0) + #define fb_hwfbe_enabled ((settings.frame_buffer&(fb_emulation|fb_hwfbe))==(fb_emulation|fb_hwfbe)) + #define fb_depth_render_enabled ((settings.frame_buffer&fb_depth_render)>0) + + wxUint32 frame_buffer; + enum FBCRCMODE { + fbcrcNone = 0, + fbcrcFast = 1, + fbcrcSafe = 2} fb_crc_mode; + +#ifdef TEXTURE_FILTER + //Texture filtering options + int ghq_fltr; + int ghq_enht; + int ghq_cmpr; + int ghq_hirs; + int ghq_use; + int ghq_enht_cmpr; + int ghq_enht_tile; + int ghq_enht_f16bpp; + int ghq_enht_gz; + int ghq_enht_nobg; + int ghq_hirs_cmpr; + int ghq_hirs_tile; + int ghq_hirs_f16bpp; + int ghq_hirs_gz; + int ghq_hirs_altcrc; + int ghq_cache_save; + int ghq_cache_size; + int ghq_hirs_let_texartists_fly; + int ghq_hirs_dump; +#endif + + //Debug + int autodetect_ucode; + int ucode; + int logging; + int elogging; + int log_clear; + int run_in_window; + int filter_cache; + int unk_as_red; + int log_unk; + int unk_clear; + int wireframe; + int wfmode; + + // Special fixes + int offset_x, offset_y; + int scale_x, scale_y; + int fast_crc; + int alt_tex_size; + int use_sts1_only; + int flame_corona; //hack for zeldas flame's corona + int increase_texrect_edge; // add 1 to lower right corner coordinates of texrect + int decrease_fillrect_edge; // sub 1 from lower right corner coordinates of fillrect + int texture_correction; // enable perspective texture correction emulation. is on by default + int stipple_mode; //used for dithered alpha emulation + wxUint32 stipple_pattern; //used for dithered alpha emulation + int force_microcheck; //check microcode each frame, for mixed F3DEX-S2DEX games + int force_quad3d; //force 0xb5 command to be quad, not line 3d + int clip_zmin; //enable near z clipping + int clip_zmax; //enable far plane clipping; + int adjust_aspect; //adjust screen aspect for wide screen mode + int force_calc_sphere; //use spheric mapping only, Ridge Racer 64 + int pal230; //set special scale for PAL games + int correct_viewport; //correct viewport values + int zmode_compare_less; //force GR_CMP_LESS for zmode=0 (opaque)and zmode=1 (interpenetrating) + int old_style_adither; //apply alpha dither regardless of alpha_dither_mode + int n64_z_scale; //scale vertex z value before writing to depth buffer, as N64 does. + + //Special game hacks + #define hack_ASB (1<<0) //All-Star Baseball games + #define hack_Banjo2 (1<<1) //Banjo Tooie + #define hack_BAR (1<<2) //Beetle Adventure Racing + #define hack_Chopper (1<<3) //Chopper Attack + #define hack_Diddy (1<<4) //diddy kong racing + #define hack_Fifa98 (1<<5) //FIFA - Road to World Cup 98 + #define hack_Fzero (1<<6) //F-Zero + #define hack_GoldenEye (1<<7) //Golden Eye + #define hack_Hyperbike (1<<8) //Top Gear Hyper Bike + #define hack_ISS64 (1<<9) //International Superstar Soccer 64 + #define hack_KI (1<<10) //Killer Instinct + #define hack_Knockout (1<<11) //Knockout Kings 2000 + #define hack_Lego (1<<12) //LEGO Racers + #define hack_MK64 (1<<13) //Mario Kart + #define hack_Megaman (1<<14) //Megaman64 + #define hack_Makers (1<<15) //Mischief-makers + #define hack_WCWnitro (1<<16) //WCW Nitro + #define hack_Ogre64 (1<<17) //Ogre Battle 64 + #define hack_Pilotwings (1<<18) //Pilotwings + #define hack_PMario (1<<19) //Paper Mario + #define hack_PPL (1<<20) //pokemon puzzle league requires many special fixes + #define hack_RE2 (1<<21) //Resident Evil 2 + #define hack_Starcraft (1<<22) //StarCraft64 + #define hack_Supercross (1<<23) //Supercross 2000 + #define hack_TGR (1<<24) //Top Gear Rally + #define hack_TGR2 (1<<25) //Top Gear Rally 2 + #define hack_Tonic (1<<26) //tonic trouble + #define hack_Yoshi (1<<27) //Yoshi Story + #define hack_Zelda (1<<28) //zeldas hacks + wxUint32 hacks; + + //wrapper settings + int wrpResolution; + int wrpVRAM; + int wrpFBO; + int wrpAnisotropic; + +} SETTINGS; + +typedef struct +{ + wxUint8 hk_ref; + wxUint8 hk_motionblur; + wxUint8 hk_filtering; +} HOTKEY_INFO; + +typedef struct +{ + int num_tmu; + int max_tex_size; + int sup_large_tex; + int sup_mirroring; + int sup_32bit_tex; + int has_2mb_tex_boundary; + int tex_UMA; + int gamma_correction; + FxI32 gamma_table_size; + FxU32 *gamma_table_r; + FxU32 *gamma_table_g; + FxU32 *gamma_table_b; + wxUint32 tmem_ptr[MAX_TMU]; + wxUint32 tex_min_addr[MAX_TMU]; + wxUint32 tex_max_addr[MAX_TMU]; +} VOODOO; + +// This structure is what is passed in by rdp:settextureimage +typedef struct { + wxUint8 format; // format: ARGB, IA, ... + wxUint8 size; // size: 4,8,16, or 32 bit + wxUint16 width; // used in settextureimage + wxUint32 addr; // address in RDRAM to load the texture from + int set_by; // 0-loadblock 1-loadtile +} TEXTURE_IMAGE; + +// This structure is a tile descriptor (as used by rdp:settile and rdp:settilesize) +typedef struct +{ + // rdp:settile + wxUint8 format; // format: ARGB, IA, ... + wxUint8 size; // size: 4,8,16, or 32 bit + wxUint16 line; // size of one row (x axis) in 64 bit words + wxUint16 t_mem; // location in texture memory (in 64 bit words, max 512 (4MB)) + wxUint8 palette; // palette # to use + wxUint8 clamp_t; // clamp or wrap (y axis)? + wxUint8 mirror_t; // mirroring on (y axis)? + wxUint8 mask_t; // mask to wrap around (ex: 5 would wrap around 32) (y axis) + wxUint8 shift_t; // ??? (scaling) + wxUint8 clamp_s; // clamp or wrap (x axis)? + wxUint8 mirror_s; // mirroring on (x axis)? + wxUint8 mask_s; // mask to wrap around (x axis) + wxUint8 shift_s; // ??? (scaling) + + // rdp:settilesize + wxUint16 ul_s; // upper left s coordinate + wxUint16 ul_t; // upper left t coordinate + wxUint16 lr_s; // lower right s coordinate + wxUint16 lr_t; // lower right t coordinate + + float f_ul_s; + float f_ul_t; + + // these are set by loadtile + wxUint16 t_ul_s; // upper left s coordinate + wxUint16 t_ul_t; // upper left t coordinate + wxUint16 t_lr_s; // lower right s coordinate + wxUint16 t_lr_t; // lower right t coordinate + + wxUint32 width; + wxUint32 height; + + // uc0:texture + wxUint8 on; + float s_scale; + float t_scale; + + wxUint16 org_s_scale; + wxUint16 org_t_scale; +} TILE; + +// This structure forms the lookup table for cached textures +typedef struct { + wxUint32 addr; // address in RDRAM + wxUint32 crc; // CRC check + wxUint32 palette; // Palette # + wxUint32 width; // width + wxUint32 height; // height + wxUint32 format; // format + wxUint32 size; // size + wxUint32 last_used; // what frame # was this texture last used (used for replacing) + + wxUint32 line; + + wxUint32 flags; // clamp/wrap/mirror flags + + wxUint32 realwidth; // width of actual texture + wxUint32 realheight; // height of actual texture + wxUint32 lod; + wxUint32 aspect; + + wxUint8 set_by; + wxUint8 texrecting; + + int f_mirror_s; + int f_mirror_t; + int f_wrap_s; + int f_wrap_t; + + float scale_x; // texture scaling + float scale_y; + float scale; // general scale to 256 + + GrTexInfo t_info; // texture info (glide) + wxUint32 tmem_addr; // addres in texture memory (glide) + + int uses; // 1 triangle that uses this texture + + int splits; // number of splits + int splitheight; + + float c_off; // ul center texel offset (both x and y) + float c_scl_x; // scale to lower-right center-texel x + float c_scl_y; // scale to lower-right center-texel y + + wxUint32 mod, mod_color, mod_color1, mod_color2, mod_factor; +#ifdef TEXTURE_FILTER + uint64 ricecrc; + int is_hires_tex; +#endif +} CACHE_LUT; + +// Lights +typedef struct { + float r, g, b, a; // color + float dir_x, dir_y, dir_z; // direction towards the light source + float x, y, z, w; // light position + float ca, la, qa; + wxUint32 nonblack; + wxUint32 nonzero; +} LIGHT; + +typedef enum { + ci_main, //0, main color image + ci_zimg, //1, depth image + ci_unknown, //2, status is unknown + ci_useless, //3, status is unclear + ci_old_copy, //4, auxiliary color image, copy of last color image from previous frame + ci_copy, //5, auxiliary color image, copy of previous color image + ci_copy_self, //6, main color image, it's content will be used to draw into itself + ci_zcopy, //7, auxiliary color image, copy of depth image + ci_aux, //8, auxiliary color image + ci_aux_copy //9, auxiliary color image, partial copy of previous color image +} CI_STATUS; + +// Frame buffers +typedef struct +{ + wxUint32 addr; //color image address + wxUint8 format; + wxUint8 size; + wxUint16 width; + wxUint16 height; + CI_STATUS status; + int changed; +} COLOR_IMAGE; + +typedef struct +{ + GrChipID_t tmu; + wxUint32 addr; //address of color image + wxUint32 end_addr; + wxUint32 tex_addr; //address in video memory + wxUint32 width; //width of color image + wxUint32 height; //height of color image + wxUint8 format; //format of color image + wxUint8 size; //format of color image + wxUint8 clear; //flag. texture buffer must be cleared + wxUint8 drawn; //flag. if equal to 1, this image was already drawn in current frame + wxUint32 crc; //checksum of the color image + float scr_width; //width of rendered image + float scr_height; //height of rendered image + wxUint32 tex_width; //width of texture buffer + wxUint32 tex_height; //height of texture buffer + int tile; // + wxUint16 tile_uls; //shift from left bound of the texture + wxUint16 tile_ult; //shift from top of the texture + wxUint32 v_shift; //shift from top of the texture + wxUint32 u_shift; //shift from left of the texture + float lr_u; + float lr_v; + float u_scale; //used to map vertex u,v coordinates into hires texture + float v_scale; //used to map vertex u,v coordinates into hires texture + CACHE_LUT * cache; //pointer to texture cache item + GrTexInfo info; + wxUint16 t_mem; +} TBUFF_COLOR_IMAGE; + +typedef struct +{ + GrChipID_t tmu; + wxUint32 begin; //start of the block in video memory + wxUint32 end; //end of the block in video memory + wxUint8 count; //number of allocated texture buffers + int clear_allowed; //stack of buffers can be cleared + TBUFF_COLOR_IMAGE images[256]; +} TEXTURE_BUFFER; + +#define NUMTEXBUF 92 + +struct RDP_Base{ + float vi_width; + float vi_height; + + int window_changed; + + float offset_x, offset_y, offset_x_bak, offset_y_bak; + + float scale_x, scale_1024, scale_x_bak; + float scale_y, scale_768, scale_y_bak; + + float view_scale[3]; + float view_trans[3]; + float clip_min_x, clip_max_x, clip_min_y, clip_max_y; + float clip_ratio; + + int updatescreen; + + wxUint32 tri_n; // triangle counter + wxUint32 debug_n; + + // Program counter + wxUint32 pc[10]; // DList PC stack + wxUint32 pc_i; // current PC index in the stack + int dl_count; // number of instructions before returning + int LLE; + + // Segments + wxUint32 segment[16]; // Segment pointer + + // Marks the end of DList execution (done in uc?:enddl) + int halt; + + // Next command + wxUint32 cmd0; + wxUint32 cmd1; + wxUint32 cmd2; + wxUint32 cmd3; + + // Clipping + SCISSOR scissor_o; + SCISSOR scissor; + int scissor_set; + + // Colors + wxUint32 fog_color; + wxUint32 fill_color; + wxUint32 prim_color; + wxUint32 blend_color; + wxUint32 env_color; + wxUint32 SCALE; + wxUint32 CENTER; + wxUint32 prim_lodmin, prim_lodfrac; + wxUint16 prim_depth; + wxUint16 prim_dz; + wxUint8 K4; + wxUint8 K5; + enum { + noise_none, + noise_combine, + noise_texture + } noise; + + float col[4]; // color multiplier + float coladd[4]; // color add/subtract + float shade_factor; + + float col_2[4]; + + wxUint32 cmb_flags, cmb_flags_2; + + // othermode_l flags + int acmp; // 0 = none, 1 = threshold, 2 = dither + int zsrc; // 0 = pixel, 1 = prim + wxUint8 alpha_dither_mode; + + // Matrices + DECLAREALIGN16VAR(model[4][4]); + DECLAREALIGN16VAR(proj[4][4]); + DECLAREALIGN16VAR(combined[4][4]); + DECLAREALIGN16VAR(dkrproj[3][4][4]); + + DECLAREALIGN16VAR(model_stack[32][4][4]); // 32 deep, will warn if overflow + int model_i; // index in the model matrix stack + int model_stack_size; + + // Textures + TEXTURE_IMAGE timg; // 1 for each tmem address + TILE tiles[8]; // 8 tile descriptors + wxUint8 tmem[4096]; // 4k tmem + wxUint32 addr[512]; // 512 addresses (used to determine address loaded from) +#ifdef TEXTURE_FILTER + LOAD_TILE_INFO load_info[512]; // 512 addresses. inforamation about tile loading. +#endif + + int cur_tile; // current tile + int mipmap_level; + int last_tile; // last tile set + int last_tile_size; // last tile size set + + int t0, t1; + int best_tex; // if no 2-tmus, which texture? (0 or 1) + int tex; + int filter_mode; + + // Texture palette + wxUint16 pal_8[256]; + wxUint32 pal_8_crc[16]; + wxUint32 pal_256_crc; + wxUint8 tlut_mode; + int LOD_en; + int Persp_en; + int persp_supported; + int force_wrap; +#ifdef TEXTURE_FILTER + wxUint16 pal_8_rice[512]; +#endif + + // Lighting + wxUint32 num_lights; + LIGHT light[12]; + float light_vector[12][3]; + float lookat[2][3]; + int use_lookat; + + // Combine modes + wxUint32 cycle1, cycle2, cycle_mode; + wxUint8 c_a0, c_b0, c_c0, c_d0, c_Aa0, c_Ab0, c_Ac0, c_Ad0; + wxUint8 c_a1, c_b1, c_c1, c_d1, c_Aa1, c_Ab1, c_Ac1, c_Ad1; + + wxUint8 fbl_a0, fbl_b0, fbl_c0, fbl_d0; + wxUint8 fbl_a1, fbl_b1, fbl_c1, fbl_d1; + + wxUint8 uncombined; // which is uncombined: 0x01=color 0x02=alpha 0x03=both + +// float YUV_C0, YUV_C1, YUV_C2, YUV_C3, YUV_C4; //YUV textures conversion coefficients + + // What needs updating + wxUint32 update; + wxUint32 flags; + + int first; + + wxUint32 tex_ctr; // incremented every time textures are updated + + int allow_combine; // allow combine updating? + + int s2dex_tex_loaded; + wxUint16 bg_image_height; + + // Debug stuff + wxUint32 rm; // use othermode_l instead, this just as a check for changes + wxUint32 render_mode_changed; + wxUint32 geom_mode; + + wxUint32 othermode_h; + wxUint32 othermode_l; + + // used to check if in texrect while loading texture + wxUint8 texrecting; + + //frame buffer related slots. Added by Gonetz + wxUint32 cimg, ocimg, zimg, tmpzimg, vi_org_reg; + COLOR_IMAGE maincimg[2]; + wxUint32 last_drawn_ci_addr; + wxUint32 main_ci, main_ci_end, main_ci_bg, main_ci_last_tex_addr, zimg_end, last_bg; + wxUint32 ci_width, ci_height, ci_size, ci_end; + wxUint32 zi_width; + int zi_lrx, zi_lry; + wxUint8 ci_count, num_of_ci, main_ci_index, copy_ci_index, copy_zi_index; + int swap_ci_index, black_ci_index; + wxUint32 ci_upper_bound, ci_lower_bound; + int motionblur, fb_drawn, fb_drawn_front, read_previous_ci, read_whole_frame; + CI_STATUS ci_status; + TBUFF_COLOR_IMAGE * cur_image; //image currently being drawn + TBUFF_COLOR_IMAGE * tbuff_tex; //image, which corresponds to currently selected texture + TBUFF_COLOR_IMAGE * aTBuffTex[2]; + wxUint8 cur_tex_buf; + wxUint8 acc_tex_buf; + int skip_drawing; //rendering is not required. used for frame buffer emulation + + //fog related slots. Added by Gonetz + float fog_multiplier, fog_offset; + enum { + fog_disabled, + fog_enabled, + fog_blend, + fog_blend_inverse + } + fog_mode; +}; + +struct RDP : public RDP_Base +{ + // Clipping + int clip; // clipping flags + VERTEX *vtx1; //[256] copy vertex buffer #1 (used for clipping) + VERTEX *vtx2; //[256] copy vertex buffer #2 + VERTEX *vtxbuf; // current vertex buffer (reset to vtx, used to determine current vertex buffer) + VERTEX *vtxbuf2; + int n_global; // Used to pass the number of vertices from clip_z to clip_tri + int vtx_buffer; + + CACHE_LUT *cache[MAX_TMU]; //[MAX_CACHE] + CACHE_LUT *cur_cache[MAX_TMU]; + wxUint32 cur_cache_n[MAX_TMU]; + int n_cached[MAX_TMU]; + + // Vertices + VERTEX *vtx; //[MAX_VTX] + int v0, vn; + + COLOR_IMAGE *frame_buffers; //[NUMTEXBUF+2] + TEXTURE_BUFFER texbufs[2]; + + wxString RomName; + + RDP(); + ~RDP(); + void Reset(); +}; + + +void SetWireframeCol (); +void ChangeSize (); +void GoToFullScreen(); + +extern RDP rdp; +extern SETTINGS settings; +extern HOTKEY_INFO hotkey_info; +extern VOODOO voodoo; + +extern GrTexInfo fontTex; +extern GrTexInfo cursorTex; +extern wxUint32 offset_font; +extern wxUint32 offset_cursor; +extern wxUint32 offset_textures; +extern wxUint32 offset_texbuf1; + +extern int ucode_error_report; + +extern wxString pluginPath; +extern wxString iniPath; + +// RDP functions +void rdp_reset (); + +extern const char *ACmp[]; +extern const char *Mode0[]; +extern const char *Mode1[]; +extern const char *Mode2[]; +extern const char *Mode3[]; +extern const char *Alpha0[]; +#define Alpha1 Alpha0 +extern const char *Alpha2[]; +#define Alpha3 Alpha0 +extern const char *FBLa[]; +extern const char *FBLb[]; +extern const char *FBLc[]; +extern const char *FBLd[]; +extern const char *str_zs[]; +extern const char *str_yn[]; +extern const char *str_offon[]; +extern const char *str_cull[]; +// I=intensity probably +extern const char *str_format[]; +extern const char *str_size[]; +extern const char *str_cm[]; +extern const char *str_lod[]; +extern const char *str_aspect[]; +extern const char *str_filter[]; +extern const char *str_tlut[]; +extern const char *CIStatus[]; + +#define FBL_D_1 2 +#define FBL_D_0 3 + +#ifndef max +#define max(a,b) (((a) > (b)) ? (a) : (b)) +#endif +#ifndef min +#define min(a,b) (((a) < (b)) ? (a) : (b)) +#endif +#ifndef TRUE +#define TRUE 1 +#endif +#ifndef FALSE +#define FALSE 0 +#endif +#ifndef HIWORD +#define HIWORD(a) ((unsigned int)(a) >> 16) +#endif +#ifndef LOWORD +#define LOWORD(a) ((a) & 0xFFFF) +#endif + +// Convert from u0/v0/u1/v1 to the real coordinates without regard to tmu +__inline void ConvertCoordsKeep (VERTEX *v, int n) +{ + for (int i=0; iw < 0.0f) + v->f = 0.0f; + else + v->f = min(255.0f, max(0.0f, v->z_w * rdp.fog_multiplier + rdp.fog_offset)); + v->a = (wxUint8)v->f; + } + else + { + v->f = 1.0f; + } +} + +void newSwapBuffers(); +extern int SwapOK; + +// ** utility functions +void load_palette (wxUint32 addr, wxUint16 start, wxUint16 count); +void setTBufTex(wxUint16 t_mem, wxUint32 cnt); + +#endif // ifndef RDP_H diff --git a/Source/Glide64/russia.xpm b/Source/Glide64/russia.xpm new file mode 100644 index 000000000..babcb7f8e --- /dev/null +++ b/Source/Glide64/russia.xpm @@ -0,0 +1,35 @@ +/* XPM */ +static const char *russia_xpm[]={ +"30 20 12 1", +" c #E7E7E7", +"0 c #F7F7F7", +"1 c #FFFFFF", +"2 c #ADCEE7", +"3 c #B5D6EF", +"4 c #0073C6", +"5 c #0073CE", +"6 c #9C394A", +"7 c #9C3942", +"8 c #CE2918", +"9 c #DE2110", +"a c #D62110", +" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ", +"011111111111111111111111111110", +"01111111111111111111111111111 ", +"001111111111111111111111111110", +"01111111111111111111111111111 ", +"001111111111111111111111111110", +"223232323232323232323232323232", +"455555555555555555555555555554", +"455555555555555555555555555554", +"455555555555555555555555555554", +"455555555555555555555555555554", +"455555555555555555555555555554", +"455555555555555555555555555554", +"677677677677677677677677677676", +"89999999999999999999999999999a", +"89999999999999999999999999999a", +"a99999999999999999999999999998", +"89999999999999999999999999999a", +"899999999999999999999999999998", +"88a8a8a8a8a8a8a8a8a8a8a8a8a8a8"}; diff --git a/Source/Glide64/turbo3D.h b/Source/Glide64/turbo3D.h new file mode 100644 index 000000000..d36c1feb7 --- /dev/null +++ b/Source/Glide64/turbo3D.h @@ -0,0 +1,276 @@ +/* +* Glide64 - Glide video plugin for Nintendo 64 emulators. +* Copyright (c) 2002 Dave2001 +* Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski +* +* 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 +* 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 +*/ + +//**************************************************************** +// +// Glide64 - Glide Plugin for Nintendo 64 emulators +// Project started on December 29th, 2001 +// +// Authors: +// Dave2001, original author, founded the project in 2001, left it in 2002 +// Gugaman, joined the project in 2002, left it in 2002 +// Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002 +// Hiroshi 'KoolSmoky' Morii, joined the project in 2007 +// +//**************************************************************** +// +// To modify Glide64: +// * Write your name and (optional)email, commented by your work, so I know who did it, and so that you can find which parts you modified when it comes time to send it to me. +// * Do NOT send me the whole project or file that you modified. Take out your modified code sections, and tell me where to put them. If people sent the whole thing, I would have many different versions, but no idea how to combine them all. +// +//**************************************************************** +// +// Created by Gonetz, 2008 +// +//**************************************************************** + +/******************Turbo3D microcode*************************/ + +struct t3dGlobState { + wxUint16 pad0; + wxUint16 perspNorm; + wxUint32 flag; + wxUint32 othermode0; + wxUint32 othermode1; + wxUint32 segBases[16]; + /* the viewport to use */ + short vsacle1; + short vsacle0; + short vsacle3; + short vsacle2; + short vtrans1; + short vtrans0; + short vtrans3; + short vtrans2; + wxUint32 rdpCmds; +}; + +struct t3dState { + wxUint32 renderState; /* render state */ + wxUint32 textureState; /* texture state */ + wxUint8 flag; + wxUint8 triCount; /* how many tris? */ + wxUint8 vtxV0; /* where to load verts? */ + wxUint8 vtxCount; /* how many verts? */ + wxUint32 rdpCmds; /* ptr (segment address) to RDP DL */ + wxUint32 othermode0; + wxUint32 othermode1; +}; + + +struct t3dTriN{ + wxUint8 flag, v2, v1, v0; /* flag is which one for flat shade */ +}; + + +static void t3dProcessRDP(wxUint32 a) +{ + if (a) + { + rdp.LLE = 1; + rdp.cmd0 = ((wxUint32*)gfx.RDRAM)[a++]; + rdp.cmd1 = ((wxUint32*)gfx.RDRAM)[a++]; + while (rdp.cmd0 + rdp.cmd1) { + gfx_instruction[0][rdp.cmd0>>24] (); + rdp.cmd0 = ((wxUint32*)gfx.RDRAM)[a++]; + rdp.cmd1 = ((wxUint32*)gfx.RDRAM)[a++]; + wxUint32 cmd = rdp.cmd0>>24; + if (cmd == 0xE4 || cmd == 0xE5) + { + rdp.cmd2 = ((wxUint32*)gfx.RDRAM)[a++]; + rdp.cmd3 = ((wxUint32*)gfx.RDRAM)[a++]; + } + } + rdp.LLE = 0; + } +} + +static void t3dLoadGlobState(wxUint32 pgstate) +{ + t3dGlobState *gstate = (t3dGlobState*)&gfx.RDRAM[segoffset(pgstate)]; + FRDP ("Global state. pad0: %04lx, perspNorm: %04lx, flag: %08lx\n", gstate->pad0, gstate->perspNorm, gstate->flag); + rdp.cmd0 = gstate->othermode0; + rdp.cmd1 = gstate->othermode1; + rdp_setothermode(); + + for (int s = 0; s < 16; s++) + { + rdp.segment[s] = gstate->segBases[s]; + FRDP ("segment: %08lx -> seg%d\n", rdp.segment[s], s); + } + + short scale_x = gstate->vsacle0 / 4; + short scale_y = gstate->vsacle1 / 4;; + short scale_z = gstate->vsacle2; + short trans_x = gstate->vtrans0 / 4; + short trans_y = gstate->vtrans1 / 4; + short trans_z = gstate->vtrans2; + rdp.view_scale[0] = scale_x * rdp.scale_x; + rdp.view_scale[1] = -scale_y * rdp.scale_y; + rdp.view_scale[2] = 32.0f * scale_z; + rdp.view_trans[0] = trans_x * rdp.scale_x; + rdp.view_trans[1] = trans_y * rdp.scale_y; + rdp.view_trans[2] = 32.0f * trans_z; + rdp.update |= UPDATE_VIEWPORT; + FRDP ("viewport scale(%d, %d, %d), trans(%d, %d, %d)\n", scale_x, scale_y, scale_z, + trans_x, trans_y, trans_z); + + t3dProcessRDP(segoffset(gstate->rdpCmds) >> 2); +} + +static void t3d_vertex(wxUint32 addr, wxUint32 v0, wxUint32 n) +{ + float x, y, z; + + rdp.v0 = v0; // Current vertex + rdp.vn = n; // Number of vertices to copy + n <<= 4; + + for (wxUint32 i=0; i < n; i+=16) + { + VERTEX *v = &rdp.vtx[v0 + (i>>4)]; + x = (float)((short*)gfx.RDRAM)[(((addr+i) >> 1) + 0)^1]; + y = (float)((short*)gfx.RDRAM)[(((addr+i) >> 1) + 1)^1]; + z = (float)((short*)gfx.RDRAM)[(((addr+i) >> 1) + 2)^1]; + v->flags = ((wxUint16*)gfx.RDRAM)[(((addr+i) >> 1) + 3)^1]; + v->ou = 2.0f * (float)((short*)gfx.RDRAM)[(((addr+i) >> 1) + 4)^1]; + v->ov = 2.0f * (float)((short*)gfx.RDRAM)[(((addr+i) >> 1) + 5)^1]; + v->uv_scaled = 0; + v->r = ((wxUint8*)gfx.RDRAM)[(addr+i + 12)^3]; + v->g = ((wxUint8*)gfx.RDRAM)[(addr+i + 13)^3]; + v->b = ((wxUint8*)gfx.RDRAM)[(addr+i + 14)^3]; + v->a = ((wxUint8*)gfx.RDRAM)[(addr+i + 15)^3]; + + v->x = x*rdp.combined[0][0] + y*rdp.combined[1][0] + z*rdp.combined[2][0] + rdp.combined[3][0]; + v->y = x*rdp.combined[0][1] + y*rdp.combined[1][1] + z*rdp.combined[2][1] + rdp.combined[3][1]; + v->z = x*rdp.combined[0][2] + y*rdp.combined[1][2] + z*rdp.combined[2][2] + rdp.combined[3][2]; + v->w = x*rdp.combined[0][3] + y*rdp.combined[1][3] + z*rdp.combined[2][3] + rdp.combined[3][3]; + + if (fabs(v->w) < 0.001) v->w = 0.001f; + v->oow = 1.0f / v->w; + v->x_w = v->x * v->oow; + v->y_w = v->y * v->oow; + v->z_w = v->z * v->oow; + + v->uv_calculated = 0xFFFFFFFF; + v->screen_translated = 0; + v->shade_mod = 0; + + v->scr_off = 0; + if (v->x < -v->w) v->scr_off |= 1; + if (v->x > v->w) v->scr_off |= 2; + if (v->y < -v->w) v->scr_off |= 4; + if (v->y > v->w) v->scr_off |= 8; + if (v->w < 0.1f) v->scr_off |= 16; +#ifdef EXTREME_LOGGING + FRDP ("v%d - x: %f, y: %f, z: %f, w: %f, u: %f, v: %f, f: %f, z_w: %f, r=%d, g=%d, b=%d, a=%d\n", i>>4, v->x, v->y, v->z, v->w, v->ou*rdp.tiles[rdp.cur_tile].s_scale, v->ov*rdp.tiles[rdp.cur_tile].t_scale, v->f, v->z_w, v->r, v->g, v->b, v->a); +#endif + } +} + +static void t3dLoadObject(wxUint32 pstate, wxUint32 pvtx, wxUint32 ptri) +{ + LRDP("Loading Turbo3D object\n"); + t3dState *ostate = (t3dState*)&gfx.RDRAM[segoffset(pstate)]; + rdp.cur_tile = (ostate->textureState)&7; + FRDP("tile: %d\n", rdp.cur_tile); + if (rdp.tiles[rdp.cur_tile].s_scale < 0.001f) + rdp.tiles[rdp.cur_tile].s_scale = 0.015625; + if (rdp.tiles[rdp.cur_tile].t_scale < 0.001f) + rdp.tiles[rdp.cur_tile].t_scale = 0.015625; + +#ifdef EXTREME_LOGGING + FRDP("renderState: %08lx, textureState: %08lx, othermode0: %08lx, othermode1: %08lx, rdpCmds: %08lx, triCount : %d, v0: %d, vn: %d\n", ostate->renderState, ostate->textureState, + ostate->othermode0, ostate->othermode1, ostate->rdpCmds, ostate->triCount, ostate->vtxV0, ostate->vtxCount); +#endif + + rdp.cmd0 = ostate->othermode0; + rdp.cmd1 = ostate->othermode1; + rdp_setothermode(); + + rdp.cmd1 = ostate->renderState; + uc0_setgeometrymode(); + + if (!(ostate->flag&1)) //load matrix + { + wxUint32 addr = segoffset(pstate+sizeof(t3dState)) & BMASK; + load_matrix(rdp.combined, addr); +#ifdef EXTREME_LOGGING + FRDP ("{%f,%f,%f,%f}\n", rdp.combined[0][0], rdp.combined[0][1], rdp.combined[0][2], rdp.combined[0][3]); + FRDP ("{%f,%f,%f,%f}\n", rdp.combined[1][0], rdp.combined[1][1], rdp.combined[1][2], rdp.combined[1][3]); + FRDP ("{%f,%f,%f,%f}\n", rdp.combined[2][0], rdp.combined[2][1], rdp.combined[2][2], rdp.combined[2][3]); + FRDP ("{%f,%f,%f,%f}\n", rdp.combined[3][0], rdp.combined[3][1], rdp.combined[3][2], rdp.combined[3][3]); +#endif + } + + rdp.geom_mode &= ~0x00020000; + rdp.geom_mode |= 0x00000200; + if (pvtx) //load vtx + t3d_vertex(segoffset(pvtx) & BMASK, ostate->vtxV0, ostate->vtxCount); + + t3dProcessRDP(segoffset(ostate->rdpCmds) >> 2); + + if (ptri) + { + update (); + wxUint32 a = segoffset(ptri); + for (int t=0; t < ostate->triCount; t++) + { + t3dTriN * tri = (t3dTriN*)&gfx.RDRAM[a]; + a += 4; + FRDP("tri #%d - %d, %d, %d\n", t, tri->v0, tri->v1, tri->v2); + VERTEX *v[3] = { &rdp.vtx[tri->v0], &rdp.vtx[tri->v1], &rdp.vtx[tri->v2] }; + if (cull_tri(v)) + rdp.tri_n ++; + else + { + draw_tri (v); + rdp.tri_n ++; + } + } + } +} + +static void Turbo3D() +{ + LRDP("Start Turbo3D microcode\n"); + settings.ucode = ucode_Fast3D; + wxUint32 a = 0, pgstate = 0, pstate = 0, pvtx = 0, ptri = 0; + do { + a = rdp.pc[rdp.pc_i] & BMASK; + pgstate = ((wxUint32*)gfx.RDRAM)[a>>2]; + pstate = ((wxUint32*)gfx.RDRAM)[(a>>2)+1]; + pvtx = ((wxUint32*)gfx.RDRAM)[(a>>2)+2]; + ptri = ((wxUint32*)gfx.RDRAM)[(a>>2)+3]; + FRDP("GlobalState: %08lx, Object: %08lx, Vertices: %08lx, Triangles: %08lx\n", pgstate, pstate, pvtx, ptri); + if (!pstate) + { + rdp.halt = 1; + break; + } + if (pgstate) + t3dLoadGlobState(pgstate); + t3dLoadObject(pstate, pvtx, ptri); + // Go to the next instruction + rdp.pc[rdp.pc_i] += 16; + } while (pstate); +// rdp_fullsync(); + settings.ucode = ucode_Turbo3d; +} diff --git a/Source/Glide64/ucode.h b/Source/Glide64/ucode.h new file mode 100644 index 000000000..05bdda7dc --- /dev/null +++ b/Source/Glide64/ucode.h @@ -0,0 +1,792 @@ +/* +* Glide64 - Glide video plugin for Nintendo 64 emulators. +* Copyright (c) 2002 Dave2001 +* Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski +* +* 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 +* 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 +*/ + +//**************************************************************** +// +// Glide64 - Glide Plugin for Nintendo 64 emulators +// Project started on December 29th, 2001 +// +// Authors: +// Dave2001, original author, founded the project in 2001, left it in 2002 +// Gugaman, joined the project in 2002, left it in 2002 +// Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002 +// Hiroshi 'KoolSmoky' Morii, joined the project in 2007 +// +//**************************************************************** +// +// To modify Glide64: +// * Write your name and (optional)email, commented by your work, so I know who did it, and so that you can find which parts you modified when it comes time to send it to me. +// * Do NOT send me the whole project or file that you modified. Take out your modified code sections, and tell me where to put them. If people sent the whole thing, I would have many different versions, but no idea how to combine them all. +// +//**************************************************************** + +typedef void (*rdp_instr)(); + +// RDP graphic instructions pointer table + +static rdp_instr gfx_instruction[10][256] = +{ + { + // uCode 0 - RSP SW 2.0X + // 00-3f + // games: Super Mario 64, Tetrisphere, Demos + spnoop, uc0_matrix, rsp_reserved0, uc0_movemem, + uc0_vertex, rsp_reserved1, uc0_displaylist, rsp_reserved2, + rsp_reserved3, uc6_sprite2d, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + // 40-7f: Unused + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + // 80-bf: Immediate commands + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, uc0_tri4, rdphalf_cont, rdphalf_2, + rdphalf_1, uc0_line3d, uc0_cleargeometrymode, uc0_setgeometrymode, + uc0_enddl, uc0_setothermode_l, uc0_setothermode_h, uc0_texture, + uc0_moveword, uc0_popmatrix, uc0_culldl, uc0_tri1, + // c0-ff: RDP commands + rdp_noop, undef, undef, undef, + undef, undef, undef, undef, + rdp_trifill, rdp_trifillz, rdp_tritxtr, rdp_tritxtrz, + rdp_trishade, rdp_trishadez, rdp_trishadetxtr, rdp_trishadetxtrz, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + rdp_texrect, rdp_texrect, rdp_loadsync, rdp_pipesync, + rdp_tilesync, rdp_fullsync, rdp_setkeygb, rdp_setkeyr, + rdp_setconvert, rdp_setscissor, rdp_setprimdepth, rdp_setothermode, + rdp_loadtlut, undef, rdp_settilesize, rdp_loadblock, + rdp_loadtile, rdp_settile, rdp_fillrect, rdp_setfillcolor, + rdp_setfogcolor, rdp_setblendcolor, rdp_setprimcolor, rdp_setenvcolor, + rdp_setcombine, rdp_settextureimage, rdp_setdepthimage, rdp_setcolorimage + }, + + // uCode 1 - F3DEX 1.XX + // 00-3f + // games: Mario Kart, Star Fox + { + spnoop, uc0_matrix, rsp_reserved0, uc0_movemem, + uc1_vertex, rsp_reserved1, uc0_displaylist, rsp_reserved2, + rsp_reserved3, uc6_sprite2d, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + // 40-7f: unused + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + // 80-bf: Immediate commands + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, uc6_loaducode, + uc1_branch_z, uc1_tri2, uc2_modifyvtx, rdphalf_2, + uc1_rdphalf_1, uc1_line3d, uc0_cleargeometrymode, uc0_setgeometrymode, + uc0_enddl, uc0_setothermode_l, uc0_setothermode_h, uc0_texture, + uc0_moveword, uc0_popmatrix, uc2_culldl, uc1_tri1, + // c0-ff: RDP commands + rdp_noop, undef, undef, undef, + undef, undef, undef, undef, + rdp_trifill, rdp_trifillz, rdp_tritxtr, rdp_tritxtrz, + rdp_trishade, rdp_trishadez, rdp_trishadetxtr, rdp_trishadetxtrz, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + rdp_texrect, rdp_texrect, rdp_loadsync, rdp_pipesync, + rdp_tilesync, rdp_fullsync, rdp_setkeygb, rdp_setkeyr, + rdp_setconvert, rdp_setscissor, rdp_setprimdepth, rdp_setothermode, + rdp_loadtlut, undef, rdp_settilesize, rdp_loadblock, + rdp_loadtile, rdp_settile, rdp_fillrect, rdp_setfillcolor, + rdp_setfogcolor, rdp_setblendcolor, rdp_setprimcolor, rdp_setenvcolor, + rdp_setcombine, rdp_settextureimage, rdp_setdepthimage, rdp_setcolorimage + }, + + // uCode 2 - F3DEX 2.XX + // games: Zelda 64 + { + // 00-3f + spnoop, uc2_vertex, uc2_modifyvtx, uc2_culldl, + uc1_branch_z, uc2_tri1, uc2_quad, uc2_quad, + uc2_line3d, uc6_bg_1cyc, uc6_bg_copy, uc6_obj_rendermode/*undef*/, + undef, undef, undef, undef, + uc0_tri4, uc0_tri4, uc0_tri4, uc0_tri4, + uc0_tri4, uc0_tri4, uc0_tri4, uc0_tri4, + uc0_tri4, uc0_tri4, uc0_tri4, uc0_tri4, + uc0_tri4, uc0_tri4, uc0_tri4, uc0_tri4, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + + // 40-7f: unused + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + + // 80-bf: unused + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + + // c0-ff: RDP commands mixed with uc2 commands + rdp_noop, undef, undef, undef, + undef, undef, undef, undef, + rdp_trifill, rdp_trifillz, rdp_tritxtr, rdp_tritxtrz, + rdp_trishade, rdp_trishadez, rdp_trishadetxtr, rdp_trishadetxtrz, + undef, undef, undef, uc2_special3, + uc2_special2, uc2_dlist_cnt, uc2_dma_io, uc0_texture, + uc2_pop_matrix, uc2_geom_mode, uc2_matrix, uc2_moveword, + uc2_movemem, uc2_load_ucode, uc0_displaylist, uc0_enddl, + spnoop, uc1_rdphalf_1, uc0_setothermode_l, uc0_setothermode_h, + rdp_texrect, rdp_texrect, rdp_loadsync, rdp_pipesync, + rdp_tilesync, rdp_fullsync, rdp_setkeygb, rdp_setkeyr, + rdp_setconvert, rdp_setscissor, rdp_setprimdepth, rdp_setothermode, + rdp_loadtlut, uc2_rdphalf_2, rdp_settilesize, rdp_loadblock, + rdp_loadtile, rdp_settile, rdp_fillrect, rdp_setfillcolor, + rdp_setfogcolor, rdp_setblendcolor, rdp_setprimcolor, rdp_setenvcolor, + rdp_setcombine, rdp_settextureimage, rdp_setdepthimage, rdp_setcolorimage + }, + + // uCode 3 - "RSP SW 2.0D", but not really + // 00-3f + // games: Wave Race + // ** Added by Gonetz ** + { + spnoop, uc0_matrix, rsp_reserved0, uc0_movemem, + uc3_vertex, rsp_reserved1, uc0_displaylist, rsp_reserved2, + rsp_reserved3, uc6_sprite2d, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + // 40-7f: unused + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + // 80-bf: Immediate commands + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, uc3_tri2, rdphalf_cont, rdphalf_2, + rdphalf_1, uc3_quad3d, uc0_cleargeometrymode, uc0_setgeometrymode, + uc0_enddl, uc0_setothermode_l, uc0_setothermode_h, uc0_texture, + uc0_moveword, uc0_popmatrix, uc0_culldl, uc3_tri1, + // c0-ff: RDP commands + rdp_noop, undef, undef, undef, + undef, undef, undef, undef, + rdp_trifill, rdp_trifillz, rdp_tritxtr, rdp_tritxtrz, + rdp_trishade, rdp_trishadez, rdp_trishadetxtr, rdp_trishadetxtrz, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + rdp_texrect, rdp_texrect, rdp_loadsync, rdp_pipesync, + rdp_tilesync, rdp_fullsync, rdp_setkeygb, rdp_setkeyr, + rdp_setconvert, rdp_setscissor, rdp_setprimdepth, rdp_setothermode, + rdp_loadtlut, undef, rdp_settilesize, rdp_loadblock, + rdp_loadtile, rdp_settile, rdp_fillrect, rdp_setfillcolor, + rdp_setfogcolor, rdp_setblendcolor, rdp_setprimcolor, rdp_setenvcolor, + rdp_setcombine, rdp_settextureimage, rdp_setdepthimage, rdp_setcolorimage + }, + + { + // uCode 4 - RSP SW 2.0D EXT + // 00-3f + // games: Star Wars: Shadows of the Empire + spnoop, uc0_matrix, rsp_reserved0, uc0_movemem, + uc4_vertex, rsp_reserved1, uc0_displaylist, rsp_reserved2, + rsp_reserved3, uc6_sprite2d, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + // 40-7f: Unused + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + // 80-bf: Immediate commands + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, uc0_tri4, rdphalf_cont, rdphalf_2, + rdphalf_1, uc4_quad3d, uc0_cleargeometrymode, uc0_setgeometrymode, + uc0_enddl, uc0_setothermode_l, uc0_setothermode_h, uc0_texture, + uc0_moveword, uc0_popmatrix, uc0_culldl, uc4_tri1, + // c0-ff: RDP commands + rdp_noop, undef, undef, undef, + undef, undef, undef, undef, + rdp_trifill, rdp_trifillz, rdp_tritxtr, rdp_tritxtrz, + rdp_trishade, rdp_trishadez, rdp_trishadetxtr, rdp_trishadetxtrz, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + rdp_texrect, rdp_texrect, rdp_loadsync, rdp_pipesync, + rdp_tilesync, rdp_fullsync, rdp_setkeygb, rdp_setkeyr, + rdp_setconvert, rdp_setscissor, rdp_setprimdepth, rdp_setothermode, + rdp_loadtlut, undef, rdp_settilesize, rdp_loadblock, + rdp_loadtile, rdp_settile, rdp_fillrect, rdp_setfillcolor, + rdp_setfogcolor, rdp_setblendcolor, rdp_setprimcolor, rdp_setenvcolor, + rdp_setcombine, rdp_settextureimage, rdp_setdepthimage, rdp_setcolorimage + }, + + { + // uCode 5 - RSP SW 2.0 Diddy + // 00-3f + // games: Diddy Kong Racing + spnoop, uc5_matrix, rsp_reserved0, uc0_movemem, + uc5_vertex, uc5_tridma, uc0_displaylist, uc5_dl_in_mem, + rsp_reserved3, uc6_sprite2d, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + // 40-7f: Unused + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + // 80-bf: Immediate commands + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, uc0_tri4, rdphalf_cont, rdphalf_2, + rdphalf_1, uc0_line3d, uc5_cleargeometrymode, uc5_setgeometrymode, + uc0_enddl, uc0_setothermode_l, uc0_setothermode_h, uc0_texture, + uc5_moveword, uc0_popmatrix, uc0_culldl, uc5_dma_offsets, + // c0-ff: RDP commands + rdp_noop, undef, undef, undef, + undef, undef, undef, undef, + rdp_trifill, rdp_trifillz, rdp_tritxtr, rdp_tritxtrz, + rdp_trishade, rdp_trishadez, rdp_trishadetxtr, rdp_trishadetxtrz, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + rdp_texrect, rdp_texrect, rdp_loadsync, rdp_pipesync, + rdp_tilesync, rdp_fullsync, rdp_setkeygb, rdp_setkeyr, + rdp_setconvert, rdp_setscissor, rdp_setprimdepth, rdp_setothermode, + rdp_loadtlut, undef, rdp_settilesize, rdp_loadblock, + rdp_loadtile, rdp_settile, rdp_fillrect, rdp_setfillcolor, + rdp_setfogcolor, rdp_setblendcolor, rdp_setprimcolor, rdp_setenvcolor, + rdp_setcombine, rdp_settextureimage, rdp_setdepthimage, rdp_setcolorimage + }, + + // uCode 6 - S2DEX 1.XX + // games: Yoshi's Story + { + spnoop, uc6_bg_1cyc, uc6_bg_copy, uc6_obj_rectangle, + uc6_obj_sprite, uc6_obj_movemem, uc0_displaylist, rsp_reserved2, + rsp_reserved3, undef/*uc6_sprite2d*/, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + // 40-7f: unused + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + // 80-bf: Immediate commands + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, uc6_loaducode, + uc6_select_dl, uc6_obj_rendermode, uc6_obj_rectangle_r, rdphalf_2, + rdphalf_1, uc1_line3d, uc0_cleargeometrymode, uc0_setgeometrymode, + uc0_enddl, uc0_setothermode_l, uc0_setothermode_h, uc0_texture, + uc0_moveword, uc0_popmatrix, uc2_culldl, uc1_tri1, + // c0-ff: RDP commands + rdp_noop, uc6_obj_loadtxtr, uc6_obj_ldtx_sprite, uc6_obj_ldtx_rect, + uc6_ldtx_rect_r, undef, undef, undef, + rdp_trifill, rdp_trifillz, rdp_tritxtr, rdp_tritxtrz, + rdp_trishade, rdp_trishadez, rdp_trishadetxtr, rdp_trishadetxtrz, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + rdp_texrect, rdp_texrect, rdp_loadsync, rdp_pipesync, + rdp_tilesync, rdp_fullsync, rdp_setkeygb, rdp_setkeyr, + rdp_setconvert, rdp_setscissor, rdp_setprimdepth, rdp_setothermode, + rdp_loadtlut, undef, rdp_settilesize, rdp_loadblock, + rdp_loadtile, rdp_settile, rdp_fillrect, rdp_setfillcolor, + rdp_setfogcolor, rdp_setblendcolor, rdp_setprimcolor, rdp_setenvcolor, + rdp_setcombine, rdp_settextureimage, rdp_setdepthimage, rdp_setcolorimage + }, + // uCode 7 - unknown + // games: Perfect Dark + { + // 00-3f + spnoop, uc0_matrix, rsp_reserved0, uc0_movemem, + uc7_vertex, rsp_reserved1, uc0_displaylist, uc7_colorbase, + rsp_reserved3, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + + // 40-7f: unused + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + + // 80-bf: unused + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + + undef, uc0_tri4, rdphalf_cont, rdphalf_2, + rdphalf_1, uc1_tri2, uc0_cleargeometrymode, uc0_setgeometrymode, + uc0_enddl, uc0_setothermode_l, uc0_setothermode_h, uc0_texture, + uc0_moveword, uc0_popmatrix, uc0_culldl, uc0_tri1, + + // c0-ff: RDP commands mixed with uc2 commands + rdp_noop, undef, undef, undef, + undef, undef, undef, undef, + rdp_trifill, rdp_trifillz, rdp_tritxtr, rdp_tritxtrz, + rdp_trishade, rdp_trishadez, rdp_trishadetxtr, rdp_trishadetxtrz, + + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + + undef, undef, undef, undef, + rdp_texrect, rdp_texrect, rdp_loadsync, rdp_pipesync, + rdp_tilesync, rdp_fullsync, rdp_setkeygb, rdp_setkeyr, + rdp_setconvert, rdp_setscissor, rdp_setprimdepth, rdp_setothermode, + + rdp_loadtlut, rdphalf_2, rdp_settilesize, rdp_loadblock, + rdp_loadtile, rdp_settile, rdp_fillrect, rdp_setfillcolor, + rdp_setfogcolor, rdp_setblendcolor, rdp_setprimcolor, rdp_setenvcolor, + rdp_setcombine, rdp_settextureimage, rdp_setdepthimage, rdp_setcolorimage + }, + + // uCode 8 - unknown + // games: Conker's Bad Fur Day + { + // 00-3f + spnoop, uc8_vertex, uc2_modifyvtx, uc2_culldl, + uc1_branch_z, uc2_tri1, uc2_quad, uc2_quad, + uc2_line3d, uc6_bg_1cyc, uc6_bg_copy, uc6_obj_rendermode/*undef*/, + undef, undef, undef, undef, + uc8_tri4, uc8_tri4, uc8_tri4, uc8_tri4, + uc8_tri4, uc8_tri4, uc8_tri4, uc8_tri4, + uc8_tri4, uc8_tri4, uc8_tri4, uc8_tri4, + uc8_tri4, uc8_tri4, uc8_tri4, uc8_tri4, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + + // 40-7f: unused + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + + // 80-bf: unused + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + + // c0-ff: RDP commands mixed with uc2 commands + rdp_noop, undef, undef, undef, + undef, undef, undef, undef, + rdp_trifill, rdp_trifillz, rdp_tritxtr, rdp_tritxtrz, + rdp_trishade, rdp_trishadez, rdp_trishadetxtr, rdp_trishadetxtrz, + undef, undef, undef, uc2_special3, + uc2_special2, uc2_dlist_cnt, uc2_dma_io, uc0_texture, + uc2_pop_matrix, uc2_geom_mode, uc2_matrix, uc8_moveword, + uc8_movemem, uc2_load_ucode, uc0_displaylist, uc0_enddl, + spnoop, rdphalf_1, uc0_setothermode_l, uc0_setothermode_h, + rdp_texrect, rdp_texrect, rdp_loadsync, rdp_pipesync, + rdp_tilesync, rdp_fullsync, rdp_setkeygb, rdp_setkeyr, + rdp_setconvert, rdp_setscissor, rdp_setprimdepth, rdp_setothermode, + rdp_loadtlut, uc2_rdphalf_2, rdp_settilesize, rdp_loadblock, + rdp_loadtile, rdp_settile, rdp_fillrect, rdp_setfillcolor, + rdp_setfogcolor, rdp_setblendcolor, rdp_setprimcolor, rdp_setenvcolor, + rdp_setcombine, rdp_settextureimage, rdp_setdepthimage, rdp_setcolorimage + }, + + { + // uCode 9 - gzsort + // games: Telefoot Soccer + // 00-3f + spnoop, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + // 40-7f: Unused + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + // 80-bf: Immediate commands + uc9_object, uc9_rpdcmd, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + undef, undef, undef, undef, + rdphalf_1, undef, uc0_cleargeometrymode, uc0_setgeometrymode, + uc0_enddl, uc0_setothermode_l, uc0_setothermode_h, uc0_texture, + uc0_moveword, undef, uc0_culldl, undef, + // c0-ff: RDP commands + rdp_noop, undef, undef, undef, + undef, undef, undef, undef, + rdp_trifill, rdp_trifillz, rdp_tritxtr, rdp_tritxtrz, + rdp_trishade, rdp_trishadez, rdp_trishadetxtr, rdp_trishadetxtrz, + + uc9_mix, uc9_fmlight, uc9_light, undef, + uc9_mtxtrnsp, uc9_mtxcat, uc9_mult_mpmtx, uc9_link_subdl, + uc9_set_subdl, uc9_wait_signal, uc9_send_signal, uc0_moveword, + uc9_movemem, undef, uc0_displaylist, uc0_enddl, + + undef, undef, uc0_setothermode_l, uc0_setothermode_h, + rdp_texrect, rdp_texrect, rdp_loadsync, rdp_pipesync, + rdp_tilesync, rdp_fullsync, rdp_setkeygb, rdp_setkeyr, + rdp_setconvert, uc9_setscissor, rdp_setprimdepth, rdp_setothermode, + + rdp_loadtlut, rdphalf_2, rdp_settilesize, rdp_loadblock, + rdp_loadtile, rdp_settile, rdp_fillrect, rdp_setfillcolor, + rdp_setfogcolor, rdp_setblendcolor, rdp_setprimcolor, rdp_setenvcolor, + rdp_setcombine, rdp_settextureimage, rdp_setdepthimage, rdp_setcolorimage + }, +}; diff --git a/Source/Glide64/ucode00.h b/Source/Glide64/ucode00.h new file mode 100644 index 000000000..52f71b401 --- /dev/null +++ b/Source/Glide64/ucode00.h @@ -0,0 +1,1156 @@ +/* +* Glide64 - Glide video plugin for Nintendo 64 emulators. +* Copyright (c) 2002 Dave2001 +* Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski +* +* 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 +* 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 +*/ + +//**************************************************************** +// +// Glide64 - Glide Plugin for Nintendo 64 emulators +// Project started on December 29th, 2001 +// +// Authors: +// Dave2001, original author, founded the project in 2001, left it in 2002 +// Gugaman, joined the project in 2002, left it in 2002 +// Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002 +// Hiroshi 'KoolSmoky' Morii, joined the project in 2007 +// +//**************************************************************** +// +// To modify Glide64: +// * Write your name and (optional)email, commented by your work, so I know who did it, and so that you can find which parts you modified when it comes time to send it to me. +// * Do NOT send me the whole project or file that you modified. Take out your modified code sections, and tell me where to put them. If people sent the whole thing, I would have many different versions, but no idea how to combine them all. +// +//**************************************************************** + +#define ucode_Fast3D 0 +#define ucode_F3DEX 1 +#define ucode_F3DEX2 2 +#define ucode_WaveRace 3 +#define ucode_StarWars 4 +#define ucode_DiddyKong 5 +#define ucode_S2DEX 6 +#define ucode_PerfectDark 7 +#define ucode_CBFD 8 +#define ucode_zSort 9 +#define ucode_Turbo3d 21 + +static void rsp_vertex(int v0, int n) +{ + wxUint32 addr = segoffset(rdp.cmd1) & 0x00FFFFFF; + int i; + float x, y, z; + + rdp.v0 = v0; // Current vertex + rdp.vn = n; // Number to copy + + // This is special, not handled in update(), but here + // * Matrix Pre-multiplication idea by Gonetz (Gonetz@ngs.ru) + if (rdp.update & UPDATE_MULT_MAT) + { + rdp.update ^= UPDATE_MULT_MAT; + MulMatrices(rdp.model, rdp.proj, rdp.combined); + } + // * + + // This is special, not handled in update() + if (rdp.update & UPDATE_LIGHTS) + { + rdp.update ^= UPDATE_LIGHTS; + + // Calculate light vectors + for (wxUint32 l=0; l>4)]; + x = (float)((short*)gfx.RDRAM)[(((addr+i) >> 1) + 0)^1]; + y = (float)((short*)gfx.RDRAM)[(((addr+i) >> 1) + 1)^1]; + z = (float)((short*)gfx.RDRAM)[(((addr+i) >> 1) + 2)^1]; + v->flags = ((wxUint16*)gfx.RDRAM)[(((addr+i) >> 1) + 3)^1]; + v->ou = (float)((short*)gfx.RDRAM)[(((addr+i) >> 1) + 4)^1]; + v->ov = (float)((short*)gfx.RDRAM)[(((addr+i) >> 1) + 5)^1]; + v->uv_scaled = 0; + v->a = ((wxUint8*)gfx.RDRAM)[(addr+i + 15)^3]; + + v->x = x*rdp.combined[0][0] + y*rdp.combined[1][0] + z*rdp.combined[2][0] + rdp.combined[3][0]; + v->y = x*rdp.combined[0][1] + y*rdp.combined[1][1] + z*rdp.combined[2][1] + rdp.combined[3][1]; + v->z = x*rdp.combined[0][2] + y*rdp.combined[1][2] + z*rdp.combined[2][2] + rdp.combined[3][2]; + v->w = x*rdp.combined[0][3] + y*rdp.combined[1][3] + z*rdp.combined[2][3] + rdp.combined[3][3]; + + + if (fabs(v->w) < 0.001) v->w = 0.001f; + v->oow = 1.0f / v->w; + v->x_w = v->x * v->oow; + v->y_w = v->y * v->oow; + v->z_w = v->z * v->oow; + CalculateFog (v); + + v->uv_calculated = 0xFFFFFFFF; + v->screen_translated = 0; + v->shade_mod = 0; + + v->scr_off = 0; + if (v->x < -v->w) v->scr_off |= 1; + if (v->x > v->w) v->scr_off |= 2; + if (v->y < -v->w) v->scr_off |= 4; + if (v->y > v->w) v->scr_off |= 8; + if (v->w < 0.1f) v->scr_off |= 16; +// if (v->z_w > 1.0f) v->scr_off |= 32; + + if (rdp.geom_mode & 0x00020000) + { + v->vec[0] = ((char*)gfx.RDRAM)[(addr+i + 12)^3]; + v->vec[1] = ((char*)gfx.RDRAM)[(addr+i + 13)^3]; + v->vec[2] = ((char*)gfx.RDRAM)[(addr+i + 14)^3]; + if (rdp.geom_mode & 0x40000) + { + if (rdp.geom_mode & 0x80000) + calc_linear (v); + else + calc_sphere (v); + } + NormalizeVector (v->vec); + + calc_light (v); + } + else + { + v->r = ((wxUint8*)gfx.RDRAM)[(addr+i + 12)^3]; + v->g = ((wxUint8*)gfx.RDRAM)[(addr+i + 13)^3]; + v->b = ((wxUint8*)gfx.RDRAM)[(addr+i + 14)^3]; + } +#ifdef EXTREME_LOGGING + FRDP ("v%d - x: %f, y: %f, z: %f, w: %f, u: %f, v: %f, f: %f, z_w: %f, r=%d, g=%d, b=%d, a=%d\n", i>>4, v->x, v->y, v->z, v->w, v->ou*rdp.tiles[rdp.cur_tile].s_scale, v->ov*rdp.tiles[rdp.cur_tile].t_scale, v->f, v->z_w, v->r, v->g, v->b, v->a); +#endif + + } +} + +static void rsp_tri1(VERTEX **v, wxUint16 linew = 0) +{ + if (cull_tri(v)) + rdp.tri_n ++; + else + { + update (); + draw_tri (v, linew); + rdp.tri_n ++; + } +} + +static void rsp_tri2 (VERTEX **v) +{ + int updated = 0; + + if (cull_tri(v)) + rdp.tri_n ++; + else + { + updated = 1; + update (); + + draw_tri (v); + rdp.tri_n ++; + } + + if (cull_tri(v+3)) + rdp.tri_n ++; + else + { + if (!updated) + update (); + + draw_tri (v+3); + rdp.tri_n ++; + } +} + +// +// uc0:vertex - loads vertices +// +static void uc0_vertex() +{ + int v0 = (rdp.cmd0 >> 16) & 0xF; // Current vertex + int n = ((rdp.cmd0 >> 20) & 0xF) + 1; // Number of vertices to copy + rsp_vertex(v0, n); +} + +// ** Definitions ** + +void modelview_load (float m[4][4]) +{ + memcpy (rdp.model, m, 64); // 4*4*4(float) + + rdp.update |= UPDATE_MULT_MAT | UPDATE_LIGHTS; +} + +void modelview_mul (float m[4][4]) +{ + DECLAREALIGN16VAR(m_src[4][4]); + memcpy (m_src, rdp.model, 64); + MulMatrices(m, m_src, rdp.model); + rdp.update |= UPDATE_MULT_MAT | UPDATE_LIGHTS; +} + +void modelview_push () +{ + if (rdp.model_i == rdp.model_stack_size) + { + RDP_E ("** Model matrix stack overflow ** too many pushes\n"); + LRDP("** Model matrix stack overflow ** too many pushes\n"); + return; + } + + memcpy (rdp.model_stack[rdp.model_i], rdp.model, 64); + rdp.model_i ++; +} + +void modelview_pop (int num = 1) +{ + if (rdp.model_i > num - 1) + { + rdp.model_i -= num; + } + else + { + RDP_E ("** Model matrix stack error ** too many pops\n"); + LRDP("** Model matrix stack error ** too many pops\n"); + return; + } + memcpy (rdp.model, rdp.model_stack[rdp.model_i], 64); + rdp.update |= UPDATE_MULT_MAT | UPDATE_LIGHTS; +} + +void modelview_load_push (float m[4][4]) +{ + modelview_push (); + modelview_load (m); +} + +void modelview_mul_push (float m[4][4]) +{ + modelview_push (); + modelview_mul (m); +} + +void projection_load (float m[4][4]) +{ + memcpy (rdp.proj, m, 64); // 4*4*4(float) + + rdp.update |= UPDATE_MULT_MAT; +} + +void projection_mul (float m[4][4]) +{ + DECLAREALIGN16VAR(m_src[4][4]); + memcpy (m_src, rdp.proj, 64); + MulMatrices(m, m_src, rdp.proj); + rdp.update |= UPDATE_MULT_MAT; +} + +void load_matrix (float m[4][4], wxUint32 addr) +{ + FRDP ("matrix - addr: %08lx\n", addr); + int x,y; // matrix index + addr >>= 1; + wxUint16 * src = (wxUint16*)gfx.RDRAM; + for (x=0; x<16; x+=4) { // Adding 4 instead of one, just to remove mult. later + for (y=0; y<4; y++) { + m[x>>2][y] = (float)( + (((wxInt32)src[(addr+x+y)^1]) << 16) | + src[(addr+x+y+16)^1] + ) / 65536.0f; + } + } +} + +// +// uc0:matrix - performs matrix operations +// +static void uc0_matrix() +{ + LRDP("uc0:matrix "); + + // Use segment offset to get the address + wxUint32 addr = segoffset(rdp.cmd1) & 0x00FFFFFF; + wxUint8 command = (wxUint8)((rdp.cmd0 >> 16) & 0xFF); + + DECLAREALIGN16VAR(m[4][4]); + load_matrix(m, addr); + + switch (command) + { + case 0: // modelview mul nopush + LRDP("modelview mul\n"); + modelview_mul (m); + break; + + case 1: // projection mul nopush + case 5: // projection mul push, can't push projection + LRDP("projection mul\n"); + projection_mul (m); + break; + + case 2: // modelview load nopush + LRDP("modelview load\n"); + modelview_load (m); + break; + + case 3: // projection load nopush + case 7: // projection load push, can't push projection + LRDP("projection load\n"); + projection_load (m); + + break; + + case 4: // modelview mul push + LRDP("modelview mul push\n"); + modelview_mul_push (m); + break; + + case 6: // modelview load push + LRDP("modelview load push\n"); + modelview_load_push (m); + break; + + default: + FRDP_E ("Unknown matrix command, %02lx", command); + FRDP ("Unknown matrix command, %02lx", command); + } + +#ifdef EXTREME_LOGGING + FRDP ("{%f,%f,%f,%f}\n", m[0][0], m[0][1], m[0][2], m[0][3]); + FRDP ("{%f,%f,%f,%f}\n", m[1][0], m[1][1], m[1][2], m[1][3]); + FRDP ("{%f,%f,%f,%f}\n", m[2][0], m[2][1], m[2][2], m[2][3]); + FRDP ("{%f,%f,%f,%f}\n", m[3][0], m[3][1], m[3][2], m[3][3]); + FRDP ("\nmodel\n{%f,%f,%f,%f}\n", rdp.model[0][0], rdp.model[0][1], rdp.model[0][2], rdp.model[0][3]); + FRDP ("{%f,%f,%f,%f}\n", rdp.model[1][0], rdp.model[1][1], rdp.model[1][2], rdp.model[1][3]); + FRDP ("{%f,%f,%f,%f}\n", rdp.model[2][0], rdp.model[2][1], rdp.model[2][2], rdp.model[2][3]); + FRDP ("{%f,%f,%f,%f}\n", rdp.model[3][0], rdp.model[3][1], rdp.model[3][2], rdp.model[3][3]); + FRDP ("\nproj\n{%f,%f,%f,%f}\n", rdp.proj[0][0], rdp.proj[0][1], rdp.proj[0][2], rdp.proj[0][3]); + FRDP ("{%f,%f,%f,%f}\n", rdp.proj[1][0], rdp.proj[1][1], rdp.proj[1][2], rdp.proj[1][3]); + FRDP ("{%f,%f,%f,%f}\n", rdp.proj[2][0], rdp.proj[2][1], rdp.proj[2][2], rdp.proj[2][3]); + FRDP ("{%f,%f,%f,%f}\n", rdp.proj[3][0], rdp.proj[3][1], rdp.proj[3][2], rdp.proj[3][3]); +#endif +} + +// +// uc0:movemem - loads a structure with data +// +static void uc0_movemem() +{ + LRDP("uc0:movemem "); + + wxUint32 i,a; + + // Check the command + switch ((rdp.cmd0 >> 16) & 0xFF) + { + case 0x80: + { + a = (segoffset(rdp.cmd1) & 0xFFFFFF) >> 1; + + short scale_x = ((short*)gfx.RDRAM)[(a+0)^1] / 4; + short scale_y = ((short*)gfx.RDRAM)[(a+1)^1] / 4; + short scale_z = ((short*)gfx.RDRAM)[(a+2)^1]; + short trans_x = ((short*)gfx.RDRAM)[(a+4)^1] / 4; + short trans_y = ((short*)gfx.RDRAM)[(a+5)^1] / 4; + short trans_z = ((short*)gfx.RDRAM)[(a+6)^1]; + if (settings.correct_viewport) + { + scale_x = abs(scale_x); + scale_y = abs(scale_y); + } + rdp.view_scale[0] = scale_x * rdp.scale_x; + rdp.view_scale[1] = -scale_y * rdp.scale_y; + rdp.view_scale[2] = 32.0f * scale_z; + rdp.view_trans[0] = trans_x * rdp.scale_x; + rdp.view_trans[1] = trans_y * rdp.scale_y; + rdp.view_trans[2] = 32.0f * trans_z; + + // there are other values than x and y, but I don't know what they do + + rdp.update |= UPDATE_VIEWPORT; + + FRDP ("viewport scale(%d, %d, %d), trans(%d, %d, %d), from:%08lx\n", scale_x, scale_y, scale_z, + trans_x, trans_y, trans_z, rdp.cmd1); + } + break; + + case 0x82: + { + a = segoffset(rdp.cmd1) & 0x00ffffff; + char dir_x = ((char*)gfx.RDRAM)[(a+8)^3]; + rdp.lookat[1][0] = (float)(dir_x) / 127.0f; + char dir_y = ((char*)gfx.RDRAM)[(a+9)^3]; + rdp.lookat[1][1] = (float)(dir_y) / 127.0f; + char dir_z = ((char*)gfx.RDRAM)[(a+10)^3]; + rdp.lookat[1][2] = (float)(dir_z) / 127.0f; + if (!dir_x && !dir_y) + rdp.use_lookat = FALSE; + else + rdp.use_lookat = TRUE; + FRDP("lookat_y (%f, %f, %f)\n", rdp.lookat[1][0], rdp.lookat[1][1], rdp.lookat[1][2]); + } + break; + + case 0x84: + a = segoffset(rdp.cmd1) & 0x00ffffff; + rdp.lookat[0][0] = (float)(((char*)gfx.RDRAM)[(a+8)^3]) / 127.0f; + rdp.lookat[0][1] = (float)(((char*)gfx.RDRAM)[(a+9)^3]) / 127.0f; + rdp.lookat[0][2] = (float)(((char*)gfx.RDRAM)[(a+10)^3]) / 127.0f; + rdp.use_lookat = TRUE; + FRDP("lookat_x (%f, %f, %f)\n", rdp.lookat[1][0], rdp.lookat[1][1], rdp.lookat[1][2]); + break; + + case 0x86: + case 0x88: + case 0x8a: + case 0x8c: + case 0x8e: + case 0x90: + case 0x92: + case 0x94: + // Get the light # + i = (((rdp.cmd0 >> 16) & 0xff) - 0x86) >> 1; + a = segoffset(rdp.cmd1) & 0x00ffffff; + + // Get the data + rdp.light[i].r = (float)(((wxUint8*)gfx.RDRAM)[(a+0)^3]) / 255.0f; + rdp.light[i].g = (float)(((wxUint8*)gfx.RDRAM)[(a+1)^3]) / 255.0f; + rdp.light[i].b = (float)(((wxUint8*)gfx.RDRAM)[(a+2)^3]) / 255.0f; + rdp.light[i].a = 1.0f; + // ** Thanks to Icepir8 for pointing this out ** + // Lighting must be signed byte instead of byte + rdp.light[i].dir_x = (float)(((char*)gfx.RDRAM)[(a+8)^3]) / 127.0f; + rdp.light[i].dir_y = (float)(((char*)gfx.RDRAM)[(a+9)^3]) / 127.0f; + rdp.light[i].dir_z = (float)(((char*)gfx.RDRAM)[(a+10)^3]) / 127.0f; + // ** + + //rdp.update |= UPDATE_LIGHTS; + + FRDP ("light: n: %d, r: %.3f, g: %.3f, b: %.3f, x: %.3f, y: %.3f, z: %.3f\n", + i, rdp.light[i].r, rdp.light[i].g, rdp.light[i].b, + rdp.light_vector[i][0], rdp.light_vector[i][1], rdp.light_vector[i][2]); + break; + + + case 0x9E: //gSPForceMatrix command. Modification of uc2_movemem:matrix. Gonetz. + { + // do not update the combined matrix! + rdp.update &= ~UPDATE_MULT_MAT; + + wxUint32 addr = segoffset(rdp.cmd1) & 0x00FFFFFF; + load_matrix(rdp.combined, addr); + + addr = rdp.pc[rdp.pc_i] & BMASK; + rdp.pc[rdp.pc_i] = (addr+24) & BMASK; //skip next 3 command, b/c they all are part of gSPForceMatrix + +#ifdef EXTREME_LOGGING + FRDP ("{%f,%f,%f,%f}\n", rdp.combined[0][0], rdp.combined[0][1], rdp.combined[0][2], rdp.combined[0][3]); + FRDP ("{%f,%f,%f,%f}\n", rdp.combined[1][0], rdp.combined[1][1], rdp.combined[1][2], rdp.combined[1][3]); + FRDP ("{%f,%f,%f,%f}\n", rdp.combined[2][0], rdp.combined[2][1], rdp.combined[2][2], rdp.combined[2][3]); + FRDP ("{%f,%f,%f,%f}\n", rdp.combined[3][0], rdp.combined[3][1], rdp.combined[3][2], rdp.combined[3][3]); +#endif + } + break; + + //next 3 command should never appear since they will be skipped in previous command + case 0x98: + RDP_E ("uc0:movemem matrix 0 - ERROR!\n"); + LRDP("matrix 0 - IGNORED\n"); + break; + + case 0x9A: + RDP_E ("uc0:movemem matrix 1 - ERROR!\n"); + LRDP("matrix 1 - IGNORED\n"); + break; + + case 0x9C: + RDP_E ("uc0:movemem matrix 2 - ERROR!\n"); + LRDP("matrix 2 - IGNORED\n"); + break; + + default: + FRDP_E ("uc0:movemem unknown (index: 0x%08lx)\n", (rdp.cmd0 >> 16) & 0xFF); + FRDP ("unknown (index: 0x%08lx)\n", (rdp.cmd0 >> 16) & 0xFF); + } +} + +// +// uc0:displaylist - makes a call to another section of code +// +static void uc0_displaylist() +{ + wxUint32 addr = segoffset(rdp.cmd1) & 0x00FFFFFF; + + // This fixes partially Gauntlet: Legends + if (addr == rdp.pc[rdp.pc_i] - 8) { LRDP("display list not executed!\n"); return; } + + wxUint32 push = (rdp.cmd0 >> 16) & 0xFF; // push the old location? + + FRDP("uc0:displaylist: %08lx, push:%s", addr, push?"no":"yes"); + FRDP(" (seg %d, offset %08lx)\n", (rdp.cmd1>>24)&0x0F, rdp.cmd1&0x00FFFFFF); + + switch (push) + { + case 0: // push + if (rdp.pc_i >= 9) { + RDP_E ("** DL stack overflow **"); + LRDP("** DL stack overflow **\n"); + return; + } + rdp.pc_i ++; // go to the next PC in the stack + rdp.pc[rdp.pc_i] = addr; // jump to the address + break; + + case 1: // no push + rdp.pc[rdp.pc_i] = addr; // just jump to the address + break; + + default: + RDP_E("Unknown displaylist operation\n"); + LRDP("Unknown displaylist operation\n"); + } +} + +// +// tri1 - renders a triangle +// +static void uc0_tri1() +{ + FRDP("uc0:tri1 #%d - %d, %d, %d\n", rdp.tri_n, + ((rdp.cmd1>>16) & 0xFF) / 10, + ((rdp.cmd1>>8) & 0xFF) / 10, + (rdp.cmd1 & 0xFF) / 10); + + VERTEX *v[3] = { + &rdp.vtx[((rdp.cmd1 >> 16) & 0xFF) / 10], + &rdp.vtx[((rdp.cmd1 >> 8) & 0xFF) / 10], + &rdp.vtx[(rdp.cmd1 & 0xFF) / 10] + }; + if (settings.hacks & hack_Makers) + { + rdp.force_wrap = FALSE; + for (int i = 0; i < 3; i++) + { + if (v[i]->ou < 0.0f || v[i]->ov < 0.0f) + { + rdp.force_wrap = TRUE; + break; + } + } + } + rsp_tri1(v); +} + +// +// uc0:enddl - ends a call made by uc0:displaylist +// +static void uc0_enddl() +{ + LRDP("uc0:enddl\n"); + + if (rdp.pc_i == 0) + { + LRDP("RDP end\n"); + + // Halt execution here + rdp.halt = 1; + } + + rdp.pc_i --; +} + +static void uc0_culldl() +{ + wxUint8 vStart = (wxUint8)((rdp.cmd0 & 0x00FFFFFF) / 40) & 0xF; + wxUint8 vEnd = (wxUint8)(rdp.cmd1 / 40) & 0x0F; + wxUint32 cond = 0; + VERTEX *v; + + FRDP("uc0:culldl start: %d, end: %d\n", vStart, vEnd); + + if (vEnd < vStart) return; + for (wxUint16 i=vStart; i<=vEnd; i++) + { + v = &rdp.vtx[i]; + // Check if completely off the screen (quick frustrum clipping for 90 FOV) + if (v->x >= -v->w) + cond |= 0x01; + if (v->x <= v->w) + cond |= 0x02; + if (v->y >= -v->w) + cond |= 0x04; + if (v->y <= v->w) + cond |= 0x08; + if (v->w >= 0.1f) + cond |= 0x10; + + if (cond == 0x1F) + return; + } + + LRDP(" - "); // specify that the enddl is not a real command + uc0_enddl (); +} + +static void uc0_popmatrix() +{ + LRDP("uc0:popmatrix\n"); + + wxUint32 param = rdp.cmd1; + + switch (param) + { + case 0: // modelview + modelview_pop (); + break; + + case 1: // projection, can't + break; + + default: + FRDP_E ("Unknown uc0:popmatrix command: 0x%08lx\n", param); + FRDP ("Unknown uc0:popmatrix command: 0x%08lx\n", param); + } +} + +static void uc6_obj_sprite (); + +static void uc0_modifyvtx(wxUint8 where, wxUint16 vtx, wxUint32 val) +{ + VERTEX *v = &rdp.vtx[vtx]; + + switch (where) + { + case 0: + uc6_obj_sprite (); + break; + + case 0x10: // RGBA + v->r = (wxUint8)(val >> 24); + v->g = (wxUint8)((val >> 16) & 0xFF); + v->b = (wxUint8)((val >> 8) & 0xFF); + v->a = (wxUint8)(val & 0xFF); + v->shade_mod = 0; + + FRDP ("RGBA: %d, %d, %d, %d\n", v->r, v->g, v->b, v->a); + break; + + case 0x14: // ST + { + float scale = rdp.Persp_en ? 0.03125f : 0.015625f; + v->ou = (float)((short)(val>>16)) * scale; + v->ov = (float)((short)(val&0xFFFF)) * scale; + v->uv_calculated = 0xFFFFFFFF; + v->uv_scaled = 1; + } + FRDP ("u/v: (%04lx, %04lx), (%f, %f)\n", (short)(val>>16), (short)(val&0xFFFF), + v->ou, v->ov); + break; + + case 0x18: // XY screen + { + float scr_x = (float)((short)(val>>16)) / 4.0f; + float scr_y = (float)((short)(val&0xFFFF)) / 4.0f; + v->screen_translated = 2; + v->sx = scr_x * rdp.scale_x + rdp.offset_x; + v->sy = scr_y * rdp.scale_y + rdp.offset_y; + if (v->w < 0.01f) + { + v->w = 1.0f; + v->oow = 1.0f; + v->z_w = 1.0f; + } + v->sz = rdp.view_trans[2] + v->z_w * rdp.view_scale[2]; + + v->scr_off = 0; + if (scr_x < 0) v->scr_off |= 1; + if (scr_x > rdp.vi_width) v->scr_off |= 2; + if (scr_y < 0) v->scr_off |= 4; + if (scr_y > rdp.vi_height) v->scr_off |= 8; + if (v->w < 0.1f) v->scr_off |= 16; + + FRDP ("x/y: (%f, %f)\n", scr_x, scr_y); + } + break; + + case 0x1C: // Z screen + { + float scr_z = (float)((short)(val>>16)); + v->z_w = (scr_z - rdp.view_trans[2]) / rdp.view_scale[2]; + v->z = v->z_w * v->w; + FRDP ("z: %f\n", scr_z); + } + break; + + default: + LRDP("UNKNOWN\n"); + break; + } +} + +// +// uc0:moveword - moves a word to someplace, like the segment pointers +// +static void uc0_moveword() +{ + LRDP("uc0:moveword "); + + // Find which command this is (lowest byte of cmd0) + switch (rdp.cmd0 & 0xFF) + { + case 0x00: + RDP_E ("uc0:moveword matrix - IGNORED\n"); + LRDP("matrix - IGNORED\n"); + break; + + case 0x02: + rdp.num_lights = ((rdp.cmd1 - 0x80000000) >> 5) - 1; // inverse of equation + if (rdp.num_lights > 8) rdp.num_lights = 0; + + rdp.update |= UPDATE_LIGHTS; + FRDP ("numlights: %d\n", rdp.num_lights); + break; + + case 0x04: + if (((rdp.cmd0>>8)&0xFFFF) == 0x04) + { + rdp.clip_ratio = sqrt((float)rdp.cmd1); + rdp.update |= UPDATE_VIEWPORT; + } + FRDP ("clip %08lx, %08lx\n", rdp.cmd0, rdp.cmd1); + break; + + case 0x06: // segment + FRDP ("segment: %08lx -> seg%d\n", rdp.cmd1, (rdp.cmd0 >> 10) & 0x0F); + if ((rdp.cmd1&BMASK)> 10) & 0x0F] = rdp.cmd1; + break; + + case 0x08: + { + rdp.fog_multiplier = (short)(rdp.cmd1 >> 16); + rdp.fog_offset = (short)(rdp.cmd1 & 0x0000FFFF); + FRDP ("fog: multiplier: %f, offset: %f\n", rdp.fog_multiplier, rdp.fog_offset); + } + break; + + case 0x0a: // moveword LIGHTCOL + { + int n = (rdp.cmd0&0xE000) >> 13; + FRDP ("lightcol light:%d, %08lx\n", n, rdp.cmd1); + + rdp.light[n].r = (float)((rdp.cmd1 >> 24) & 0xFF) / 255.0f; + rdp.light[n].g = (float)((rdp.cmd1 >> 16) & 0xFF) / 255.0f; + rdp.light[n].b = (float)((rdp.cmd1 >> 8) & 0xFF) / 255.0f; + rdp.light[n].a = 255; + } + break; + + case 0x0c: + { + wxUint16 val = (wxUint16)((rdp.cmd0 >> 8) & 0xFFFF); + wxUint16 vtx = val / 40; + wxUint8 where = val%40; + uc0_modifyvtx(where, vtx, rdp.cmd1); + FRDP ("uc0:modifyvtx: vtx: %d, where: 0x%02lx, val: %08lx - ", vtx, where, rdp.cmd1); + } + break; + + case 0x0e: + LRDP("perspnorm - IGNORED\n"); + break; + + default: + FRDP_E ("uc0:moveword unknown (index: 0x%08lx)\n", rdp.cmd0 & 0xFF); + FRDP ("unknown (index: 0x%08lx)\n", rdp.cmd0 & 0xFF); + } +} + +static void uc0_texture() +{ + int tile = (rdp.cmd0 >> 8) & 0x07; + if (tile == 7 && (settings.hacks&hack_Supercross)) tile = 0; //fix for supercross 2000 + rdp.mipmap_level = (rdp.cmd0 >> 11) & 0x07; + wxUint32 on = (rdp.cmd0 & 0xFF); + rdp.cur_tile = tile; + + if (on) + { + wxUint16 s = (wxUint16)((rdp.cmd1 >> 16) & 0xFFFF); + wxUint16 t = (wxUint16)(rdp.cmd1 & 0xFFFF); + + TILE *tmp_tile = &rdp.tiles[tile]; + tmp_tile->on = 1; + tmp_tile->org_s_scale = s; + tmp_tile->org_t_scale = t; + tmp_tile->s_scale = (float)(s+1)/65536.0f; + tmp_tile->t_scale = (float)(t+1)/65536.0f; + tmp_tile->s_scale /= 32.0f; + tmp_tile->t_scale /= 32.0f; + + rdp.update |= UPDATE_TEXTURE; + + FRDP("uc0:texture: tile: %d, mipmap_lvl: %d, on: %d, s_scale: %f, t_scale: %f\n", + tile, rdp.mipmap_level, on, tmp_tile->s_scale, tmp_tile->t_scale); + } + else + { + LRDP("uc0:texture skipped b/c of off\n"); + rdp.tiles[tile].on = 0; + } +} + + +static void uc0_setothermode_h() +{ + LRDP("uc0:setothermode_h: "); + + int shift, len; + if ((settings.ucode == ucode_F3DEX2) || (settings.ucode == ucode_CBFD)) + { + len = (rdp.cmd0 & 0xFF) + 1; + shift = 32 - ((rdp.cmd0 >> 8) & 0xFF) - len; + } + else + { + shift = (rdp.cmd0 >> 8) & 0xFF; + len = rdp.cmd0 & 0xFF; + } + + wxUint32 mask = 0; + int i = len; + for (; i; i--) + mask = (mask << 1) | 1; + mask <<= shift; + + rdp.cmd1 &= mask; + rdp.othermode_h &= ~mask; + rdp.othermode_h |= rdp.cmd1; + + if (mask & 0x00000030) // alpha dither mode + { + rdp.alpha_dither_mode = (rdp.othermode_h >> 4) & 0x3; + FRDP ("alpha dither mode: %s\n", str_dither[rdp.alpha_dither_mode]); + } + + if (mask & 0x000000C0) // rgb dither mode + { + wxUint32 dither_mode = (rdp.othermode_h >> 6) & 0x3; + FRDP ("rgb dither mode: %s\n", str_dither[dither_mode]); + } + + if (mask & 0x00003000) // filter mode + { + rdp.filter_mode = (int)((rdp.othermode_h & 0x00003000) >> 12); + rdp.update |= UPDATE_TEXTURE; + FRDP ("filter mode: %s\n", str_filter[rdp.filter_mode]); + } + + if (mask & 0x0000C000) // tlut mode + { + rdp.tlut_mode = (wxUint8)((rdp.othermode_h & 0x0000C000) >> 14); + FRDP ("tlut mode: %s\n", str_tlut[rdp.tlut_mode]); + } + + if (mask & 0x00300000) // cycle type + { + rdp.cycle_mode = (wxUint8)((rdp.othermode_h & 0x00300000) >> 20); + rdp.update |= UPDATE_ZBUF_ENABLED; + FRDP ("cycletype: %d\n", rdp.cycle_mode); + } + + if (mask & 0x00010000) // LOD enable + { + rdp.LOD_en = (rdp.othermode_h & 0x00010000) ? TRUE : FALSE; + FRDP ("LOD_en: %d\n", rdp.LOD_en); + } + + if (mask & 0x00080000) // Persp enable + { + if (rdp.persp_supported) + rdp.Persp_en = (rdp.othermode_h & 0x00080000) ? TRUE : FALSE; + FRDP ("Persp_en: %d\n", rdp.Persp_en); + } + + wxUint32 unk = mask & 0x0FFC60F0F; + if (unk) // unknown portions, LARGE + { + FRDP ("UNKNOWN PORTIONS: shift: %d, len: %d, unknowns: %08lx\n", shift, len, unk); + } +} + +static void uc0_setothermode_l() +{ + LRDP("uc0:setothermode_l "); + + int shift, len; + if ((settings.ucode == ucode_F3DEX2) || (settings.ucode == ucode_CBFD)) + { + len = (rdp.cmd0 & 0xFF) + 1; + shift = 32 - ((rdp.cmd0 >> 8) & 0xFF) - len; + if (shift < 0) shift = 0; + } + else + { + len = rdp.cmd0 & 0xFF; + shift = (rdp.cmd0 >> 8) & 0xFF; + } + + wxUint32 mask = 0; + int i = len; + for (; i; i--) + mask = (mask << 1) | 1; + mask <<= shift; + + rdp.cmd1 &= mask; + rdp.othermode_l &= ~mask; + rdp.othermode_l |= rdp.cmd1; + + if (mask & 0x00000003) // alpha compare + { + rdp.acmp = rdp.othermode_l & 0x00000003; + FRDP ("alpha compare %s\n", ACmp[rdp.acmp]); + rdp.update |= UPDATE_ALPHA_COMPARE; + } + + if (mask & 0x00000004) // z-src selection + { + rdp.zsrc = (rdp.othermode_l & 0x00000004) >> 2; + FRDP ("z-src sel: %s\n", str_zs[rdp.zsrc]); + FRDP ("z-src sel: %08lx\n", rdp.zsrc); + rdp.update |= UPDATE_ZBUF_ENABLED; + } + + if (mask & 0xFFFFFFF8) // rendermode / blender bits + { + rdp.update |= UPDATE_FOG_ENABLED; //if blender has no fog bits, fog must be set off + rdp.render_mode_changed |= rdp.rm ^ rdp.othermode_l; + rdp.rm = rdp.othermode_l; + if (settings.flame_corona && (rdp.rm == 0x00504341)) //hack for flame's corona + rdp.othermode_l |= /*0x00000020 |*/ 0x00000010; + FRDP ("rendermode: %08lx\n", rdp.othermode_l); // just output whole othermode_l + } + + // there is not one setothermode_l that's not handled :) +} + +static void uc0_setgeometrymode() +{ + rdp.geom_mode |= rdp.cmd1; + FRDP("uc0:setgeometrymode %08lx; result: %08lx\n", rdp.cmd1, rdp.geom_mode); + + if (rdp.cmd1 & 0x00000001) // Z-Buffer enable + { + if (!(rdp.flags & ZBUF_ENABLED)) + { + rdp.flags |= ZBUF_ENABLED; + rdp.update |= UPDATE_ZBUF_ENABLED; + } + } + if (rdp.cmd1 & 0x00001000) // Front culling + { + if (!(rdp.flags & CULL_FRONT)) + { + rdp.flags |= CULL_FRONT; + rdp.update |= UPDATE_CULL_MODE; + } + } + if (rdp.cmd1 & 0x00002000) // Back culling + { + if (!(rdp.flags & CULL_BACK)) + { + rdp.flags |= CULL_BACK; + rdp.update |= UPDATE_CULL_MODE; + } + } + + //Added by Gonetz + if (rdp.cmd1 & 0x00010000) // Fog enable + { + if (!(rdp.flags & FOG_ENABLED)) + { + rdp.flags |= FOG_ENABLED; + rdp.update |= UPDATE_FOG_ENABLED; + } + } +} + +static void uc0_cleargeometrymode() +{ + FRDP("uc0:cleargeometrymode %08lx\n", rdp.cmd1); + + rdp.geom_mode &= (~rdp.cmd1); + + if (rdp.cmd1 & 0x00000001) // Z-Buffer enable + { + if (rdp.flags & ZBUF_ENABLED) + { + rdp.flags ^= ZBUF_ENABLED; + rdp.update |= UPDATE_ZBUF_ENABLED; + } + } + if (rdp.cmd1 & 0x00001000) // Front culling + { + if (rdp.flags & CULL_FRONT) + { + rdp.flags ^= CULL_FRONT; + rdp.update |= UPDATE_CULL_MODE; + } + } + if (rdp.cmd1 & 0x00002000) // Back culling + { + if (rdp.flags & CULL_BACK) + { + rdp.flags ^= CULL_BACK; + rdp.update |= UPDATE_CULL_MODE; + } + } + + //Added by Gonetz + if (rdp.cmd1 & 0x00010000) // Fog enable + { + if (rdp.flags & FOG_ENABLED) + { + rdp.flags ^= FOG_ENABLED; + rdp.update |= UPDATE_FOG_ENABLED; + } + } +} + +static void uc0_line3d() +{ + wxUint32 v0 = ((rdp.cmd1 >> 16) & 0xff) / 10; + wxUint32 v1 = ((rdp.cmd1 >> 8) & 0xff) / 10; + wxUint16 width = (wxUint16)(rdp.cmd1 & 0xFF) + 3; + + VERTEX *v[3] = { + &rdp.vtx[v1], + &rdp.vtx[v0], + &rdp.vtx[v0] + }; + wxUint32 cull_mode = (rdp.flags & CULLMASK) >> CULLSHIFT; + rdp.flags |= CULLMASK; + rdp.update |= UPDATE_CULL_MODE; + rsp_tri1(v, width); + rdp.flags ^= CULLMASK; + rdp.flags |= cull_mode << CULLSHIFT; + rdp.update |= UPDATE_CULL_MODE; + + FRDP("uc0:line3d v0:%d, v1:%d, width:%d\n", v0, v1, width); +} + +static void uc0_tri4 () +{ + // c0: 0000 0123, c1: 456789ab + // becomes: 405 617 829 a3b + + LRDP("uc0:tri4"); + FRDP(" #%d, #%d, #%d, #%d - %d, %d, %d - %d, %d, %d - %d, %d, %d - %d, %d, %d\n", rdp.tri_n, rdp.tri_n+1, rdp.tri_n+2, rdp.tri_n+3, + (rdp.cmd1 >> 28) & 0xF, + (rdp.cmd0 >> 12) & 0xF, + (rdp.cmd1 >> 24) & 0xF, + (rdp.cmd1 >> 20) & 0xF, + (rdp.cmd0 >> 8) & 0xF, + (rdp.cmd1 >> 16) & 0xF, + (rdp.cmd1 >> 12) & 0xF, + (rdp.cmd0 >> 4) & 0xF, + (rdp.cmd1 >> 8) & 0xF, + (rdp.cmd1 >> 4) & 0xF, + (rdp.cmd0 >> 0) & 0xF, + (rdp.cmd1 >> 0) & 0xF); + + VERTEX *v[12] = { + &rdp.vtx[(rdp.cmd1 >> 28) & 0xF], + &rdp.vtx[(rdp.cmd0 >> 12) & 0xF], + &rdp.vtx[(rdp.cmd1 >> 24) & 0xF], + &rdp.vtx[(rdp.cmd1 >> 20) & 0xF], + &rdp.vtx[(rdp.cmd0 >> 8) & 0xF], + &rdp.vtx[(rdp.cmd1 >> 16) & 0xF], + &rdp.vtx[(rdp.cmd1 >> 12) & 0xF], + &rdp.vtx[(rdp.cmd0 >> 4) & 0xF], + &rdp.vtx[(rdp.cmd1 >> 8) & 0xF], + &rdp.vtx[(rdp.cmd1 >> 4) & 0xF], + &rdp.vtx[(rdp.cmd0 >> 0) & 0xF], + &rdp.vtx[(rdp.cmd1 >> 0) & 0xF], + }; + + int updated = 0; + + if (cull_tri(v)) + rdp.tri_n ++; + else + { + updated = 1; + update (); + + draw_tri (v); + rdp.tri_n ++; + } + + if (cull_tri(v+3)) + rdp.tri_n ++; + else + { + if (!updated) + { + updated = 1; + update (); + } + + draw_tri (v+3); + rdp.tri_n ++; + } + + if (cull_tri(v+6)) + rdp.tri_n ++; + else + { + if (!updated) + { + updated = 1; + update (); + } + + draw_tri (v+6); + rdp.tri_n ++; + } + + if (cull_tri(v+9)) + rdp.tri_n ++; + else + { + if (!updated) + { + updated = 1; + update (); + } + + draw_tri (v+9); + rdp.tri_n ++; + } +} diff --git a/Source/Glide64/ucode01.h b/Source/Glide64/ucode01.h new file mode 100644 index 000000000..af5c8d6f9 --- /dev/null +++ b/Source/Glide64/ucode01.h @@ -0,0 +1,163 @@ +/* +* Glide64 - Glide video plugin for Nintendo 64 emulators. +* Copyright (c) 2002 Dave2001 +* Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski +* +* 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 +* 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 +*/ + +//**************************************************************** +// +// Glide64 - Glide Plugin for Nintendo 64 emulators +// Project started on December 29th, 2001 +// +// Authors: +// Dave2001, original author, founded the project in 2001, left it in 2002 +// Gugaman, joined the project in 2002, left it in 2002 +// Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002 +// Hiroshi 'KoolSmoky' Morii, joined the project in 2007 +// +//**************************************************************** +// +// To modify Glide64: +// * Write your name and (optional)email, commented by your work, so I know who did it, and so that you can find which parts you modified when it comes time to send it to me. +// * Do NOT send me the whole project or file that you modified. Take out your modified code sections, and tell me where to put them. If people sent the whole thing, I would have many different versions, but no idea how to combine them all. +// +//**************************************************************** + +// +// vertex - loads vertices +// + +static void uc1_vertex() +{ + int v0 = (rdp.cmd0 >> 17) & 0x7F; // Current vertex + int n = (rdp.cmd0 >> 10) & 0x3F; // Number to copy + rsp_vertex(v0, n); +} + +// +// tri1 - renders a triangle +// + +static void uc1_tri1() +{ + if (rdp.skip_drawing) + { + LRDP("uc1:tri1. skipped\n"); + return; + } + FRDP("uc1:tri1 #%d - %d, %d, %d - %08lx - %08lx\n", rdp.tri_n, + ((rdp.cmd1 >> 17) & 0x7F), + ((rdp.cmd1 >> 9) & 0x7F), + ((rdp.cmd1 >> 1) & 0x7F), rdp.cmd0, rdp.cmd1); + + VERTEX *v[3] = { + &rdp.vtx[(rdp.cmd1 >> 17) & 0x7F], + &rdp.vtx[(rdp.cmd1 >> 9) & 0x7F], + &rdp.vtx[(rdp.cmd1 >> 1) & 0x7F] + }; + + rsp_tri1(v); +} + +static void uc1_tri2 () +{ + if (rdp.skip_drawing) + { + LRDP("uc1:tri2. skipped\n"); + return; + } + LRDP("uc1:tri2"); + + FRDP(" #%d, #%d - %d, %d, %d - %d, %d, %d\n", rdp.tri_n, rdp.tri_n+1, + ((rdp.cmd0 >> 17) & 0x7F), + ((rdp.cmd0 >> 9) & 0x7F), + ((rdp.cmd0 >> 1) & 0x7F), + ((rdp.cmd1 >> 17) & 0x7F), + ((rdp.cmd1 >> 9) & 0x7F), + ((rdp.cmd1 >> 1) & 0x7F)); + + VERTEX *v[6] = { + &rdp.vtx[(rdp.cmd0 >> 17) & 0x7F], + &rdp.vtx[(rdp.cmd0 >> 9) & 0x7F], + &rdp.vtx[(rdp.cmd0 >> 1) & 0x7F], + &rdp.vtx[(rdp.cmd1 >> 17) & 0x7F], + &rdp.vtx[(rdp.cmd1 >> 9) & 0x7F], + &rdp.vtx[(rdp.cmd1 >> 1) & 0x7F] + }; + + rsp_tri2(v); +} + +static void uc1_line3d() +{ + if (!settings.force_quad3d && ((rdp.cmd1&0xFF000000) == 0) && ((rdp.cmd0&0x00FFFFFF) == 0)) + { + wxUint16 width = (wxUint16)(rdp.cmd1&0xFF) + 3; + + FRDP("uc1:line3d width: %d #%d, #%d - %d, %d\n", width, rdp.tri_n, rdp.tri_n+1, + (rdp.cmd1 >> 17) & 0x7F, + (rdp.cmd1 >> 9) & 0x7F); + + VERTEX *v[3] = { + &rdp.vtx[(rdp.cmd1 >> 17) & 0x7F], + &rdp.vtx[(rdp.cmd1 >> 9) & 0x7F], + &rdp.vtx[(rdp.cmd1 >> 9) & 0x7F] + }; + wxUint32 cull_mode = (rdp.flags & CULLMASK) >> CULLSHIFT; + rdp.flags |= CULLMASK; + rdp.update |= UPDATE_CULL_MODE; + rsp_tri1(v, width); + rdp.flags ^= CULLMASK; + rdp.flags |= cull_mode << CULLSHIFT; + rdp.update |= UPDATE_CULL_MODE; + } + else + { + FRDP("uc1:quad3d #%d, #%d\n", rdp.tri_n, rdp.tri_n+1); + + VERTEX *v[6] = { + &rdp.vtx[(rdp.cmd1 >> 25) & 0x7F], + &rdp.vtx[(rdp.cmd1 >> 17) & 0x7F], + &rdp.vtx[(rdp.cmd1 >> 9) & 0x7F], + &rdp.vtx[(rdp.cmd1 >> 1) & 0x7F], + &rdp.vtx[(rdp.cmd1 >> 25) & 0x7F], + &rdp.vtx[(rdp.cmd1 >> 9) & 0x7F] + }; + + rsp_tri2(v); + } +} + +wxUint32 branch_dl = 0; + +static void uc1_rdphalf_1() +{ + LRDP("uc1:rdphalf_1\n"); + branch_dl = rdp.cmd1; + rdphalf_1(); +} + +static void uc1_branch_z() +{ + wxUint32 addr = segoffset(branch_dl); + FRDP ("uc1:branch_less_z, addr: %08lx\n", addr); + wxUint32 vtx = (rdp.cmd0 & 0xFFF) >> 1; + if( fabs(rdp.vtx[vtx].z) <= (rdp.cmd1/*&0xFFFF*/) ) + { + rdp.pc[rdp.pc_i] = addr; + } +} diff --git a/Source/Glide64/ucode02.h b/Source/Glide64/ucode02.h new file mode 100644 index 000000000..8bb7af1ad --- /dev/null +++ b/Source/Glide64/ucode02.h @@ -0,0 +1,815 @@ +/* +* Glide64 - Glide video plugin for Nintendo 64 emulators. +* Copyright (c) 2002 Dave2001 +* Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski +* +* 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 +* 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 +*/ + +//**************************************************************** +// +// Glide64 - Glide Plugin for Nintendo 64 emulators +// Project started on December 29th, 2001 +// +// Authors: +// Dave2001, original author, founded the project in 2001, left it in 2002 +// Gugaman, joined the project in 2002, left it in 2002 +// Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002 +// Hiroshi 'KoolSmoky' Morii, joined the project in 2007 +// +//**************************************************************** +// +// To modify Glide64: +// * Write your name and (optional)email, commented by your work, so I know who did it, and so that you can find which parts you modified when it comes time to send it to me. +// * Do NOT send me the whole project or file that you modified. Take out your modified code sections, and tell me where to put them. If people sent the whole thing, I would have many different versions, but no idea how to combine them all. +// +//**************************************************************** + +static void calc_point_light (VERTEX *v, float * vpos) +{ + float light_intensity = 0.0f; + register float color[3] = {rdp.light[rdp.num_lights].r, rdp.light[rdp.num_lights].g, rdp.light[rdp.num_lights].b}; + for (wxUint32 l=0; l 0.0f) + light_intensity = 1/at;//DotProduct (lvec, nvec) / (light_len * normal_len * at); + else + light_intensity = 0.0f; + } + else + { + light_intensity = 0.0f; + } + if (light_intensity > 0.0f) + { + color[0] += rdp.light[l].r * light_intensity; + color[1] += rdp.light[l].g * light_intensity; + color[2] += rdp.light[l].b * light_intensity; + } + } + if (color[0] > 1.0f) color[0] = 1.0f; + if (color[1] > 1.0f) color[1] = 1.0f; + if (color[2] > 1.0f) color[2] = 1.0f; + + v->r = (wxUint8)(color[0]*255.0f); + v->g = (wxUint8)(color[1]*255.0f); + v->b = (wxUint8)(color[2]*255.0f); +} + +static void uc6_obj_rectangle(); + +static void uc2_vertex () +{ + if (!(rdp.cmd0 & 0x00FFFFFF)) + { + uc6_obj_rectangle(); + return; + } + + // This is special, not handled in update(), but here + // * Matrix Pre-multiplication idea by Gonetz (Gonetz@ngs.ru) + if (rdp.update & UPDATE_MULT_MAT) + { + rdp.update ^= UPDATE_MULT_MAT; + MulMatrices(rdp.model, rdp.proj, rdp.combined); + } + if (rdp.update & UPDATE_LIGHTS) + { + rdp.update ^= UPDATE_LIGHTS; + + // Calculate light vectors + for (wxUint32 l=0; l> 12) & 0xFF; + rdp.v0 = v0 = ((rdp.cmd0 >> 1) & 0x7F) - n; + + FRDP ("uc2:vertex n: %d, v0: %d, from: %08lx\n", n, v0, addr); + + if (v0 < 0) + { + RDP_E ("** ERROR: uc2:vertex v0 < 0\n"); + LRDP("** ERROR: uc2:vertex v0 < 0\n"); + return; + } + + wxUint32 geom_mode = rdp.geom_mode; + if ((settings.hacks&hack_Fzero) && (rdp.geom_mode & 0x40000)) + { + if (((short*)gfx.RDRAM)[(((addr) >> 1) + 4)^1] || ((short*)gfx.RDRAM)[(((addr) >> 1) + 5)^1]) + rdp.geom_mode ^= 0x40000; + } + for (i=0; i < (n<<4); i+=16) + { + VERTEX *v = &rdp.vtx[v0 + (i>>4)]; + x = (float)((short*)gfx.RDRAM)[(((addr+i) >> 1) + 0)^1]; + y = (float)((short*)gfx.RDRAM)[(((addr+i) >> 1) + 1)^1]; + z = (float)((short*)gfx.RDRAM)[(((addr+i) >> 1) + 2)^1]; + v->flags = ((wxUint16*)gfx.RDRAM)[(((addr+i) >> 1) + 3)^1]; + v->ou = (float)((short*)gfx.RDRAM)[(((addr+i) >> 1) + 4)^1]; + v->ov = (float)((short*)gfx.RDRAM)[(((addr+i) >> 1) + 5)^1]; + v->uv_scaled = 0; + v->a = ((wxUint8*)gfx.RDRAM)[(addr+i + 15)^3]; + + v->x = x*rdp.combined[0][0] + y*rdp.combined[1][0] + z*rdp.combined[2][0] + rdp.combined[3][0]; + v->y = x*rdp.combined[0][1] + y*rdp.combined[1][1] + z*rdp.combined[2][1] + rdp.combined[3][1]; + v->z = x*rdp.combined[0][2] + y*rdp.combined[1][2] + z*rdp.combined[2][2] + rdp.combined[3][2]; + v->w = x*rdp.combined[0][3] + y*rdp.combined[1][3] + z*rdp.combined[2][3] + rdp.combined[3][3]; + + if (fabs(v->w) < 0.001) v->w = 0.001f; + v->oow = 1.0f / v->w; + v->x_w = v->x * v->oow; + v->y_w = v->y * v->oow; + v->z_w = v->z * v->oow; + CalculateFog (v); + + v->uv_calculated = 0xFFFFFFFF; + v->screen_translated = 0; + v->shade_mod = 0; + + v->scr_off = 0; + if (v->x < -v->w) v->scr_off |= 1; + if (v->x > v->w) v->scr_off |= 2; + if (v->y < -v->w) v->scr_off |= 4; + if (v->y > v->w) v->scr_off |= 8; + if (v->w < 0.1f) v->scr_off |= 16; +// if (v->z_w > 1.0f) v->scr_off |= 32; + + if (rdp.geom_mode & 0x00020000) + { + v->vec[0] = ((char*)gfx.RDRAM)[(addr+i + 12)^3]; + v->vec[1] = ((char*)gfx.RDRAM)[(addr+i + 13)^3]; + v->vec[2] = ((char*)gfx.RDRAM)[(addr+i + 14)^3]; + // FRDP("Calc light. x: %f, y: %f z: %f\n", v->vec[0], v->vec[1], v->vec[2]); + // if (!(rdp.geom_mode & 0x800000)) + { + if (rdp.geom_mode & 0x40000) + { + if (rdp.geom_mode & 0x80000) + { + calc_linear (v); +#ifdef EXTREME_LOGGING + FRDP ("calc linear: v%d - u: %f, v: %f\n", i>>4, v->ou, v->ov); +#endif + } + else + { + calc_sphere (v); +#ifdef EXTREME_LOGGING + FRDP ("calc sphere: v%d - u: %f, v: %f\n", i>>4, v->ou, v->ov); +#endif + } + } + } + if (rdp.geom_mode & 0x00400000) + { + float tmpvec[3] = {x, y, z}; + calc_point_light (v, tmpvec); + } + else + { + NormalizeVector (v->vec); + calc_light (v); + } + } + else + { + v->r = ((wxUint8*)gfx.RDRAM)[(addr+i + 12)^3]; + v->g = ((wxUint8*)gfx.RDRAM)[(addr+i + 13)^3]; + v->b = ((wxUint8*)gfx.RDRAM)[(addr+i + 14)^3]; + } +#ifdef EXTREME_LOGGING + FRDP ("v%d - x: %f, y: %f, z: %f, w: %f, u: %f, v: %f, f: %f, z_w: %f, r=%d, g=%d, b=%d, a=%d\n", i>>4, v->x, v->y, v->z, v->w, v->ou*rdp.tiles[rdp.cur_tile].s_scale, v->ov*rdp.tiles[rdp.cur_tile].t_scale, v->f, v->z_w, v->r, v->g, v->b, v->a); +#endif + } + rdp.geom_mode = geom_mode; +} + +static void uc2_modifyvtx () +{ + wxUint8 where = (wxUint8)((rdp.cmd0 >> 16) & 0xFF); + wxUint16 vtx = (wxUint16)((rdp.cmd0 >> 1) & 0xFFFF); + + FRDP ("uc2:modifyvtx: vtx: %d, where: 0x%02lx, val: %08lx - ", vtx, where, rdp.cmd1); + uc0_modifyvtx(where, vtx, rdp.cmd1); +} + +static void uc2_culldl () +{ + wxUint16 vStart = (wxUint16)(rdp.cmd0 & 0xFFFF) >> 1; + wxUint16 vEnd = (wxUint16)(rdp.cmd1 & 0xFFFF) >> 1; + wxUint32 cond = 0; + FRDP ("uc2:culldl start: %d, end: %d\n", vStart, vEnd); + + if (vEnd < vStart) return; + for (wxUint16 i=vStart; i<=vEnd; i++) + { + /* + VERTEX v = &rdp.vtx[i]; + // Check if completely off the screen (quick frustrum clipping for 90 FOV) + if (v->x >= -v->w) + cond |= 0x01; + if (v->x <= v->w) + cond |= 0x02; + if (v->y >= -v->w) + cond |= 0x04; + if (v->y <= v->w) + cond |= 0x08; + if (v->w >= 0.1f) + cond |= 0x10; + + if (cond == 0x1F) + return; + //*/ + +#ifdef EXTREME_LOGGING + FRDP (" v[%d] = (%02f, %02f, %02f, 0x%02lx)\n", i, rdp.vtx[i].x, rdp.vtx[i].y, rdp.vtx[i].w, rdp.vtx[i].scr_off); +#endif + + cond |= (~rdp.vtx[i].scr_off) & 0x1F; + if (cond == 0x1F) + return; + } + + LRDP(" - "); // specify that the enddl is not a real command + uc0_enddl (); +} + +static void uc6_obj_loadtxtr (); + +static void uc2_tri1() +{ + if ((rdp.cmd0 & 0x00FFFFFF) == 0x17) + { + uc6_obj_loadtxtr (); + return; + } + if (rdp.skip_drawing) + { + LRDP("uc2:tri1. skipped\n"); + return; + } + + FRDP("uc2:tri1 #%d - %d, %d, %d\n", rdp.tri_n, + ((rdp.cmd0 >> 17) & 0x7F), + ((rdp.cmd0 >> 9) & 0x7F), + ((rdp.cmd0 >> 1) & 0x7F)); + + VERTEX *v[3] = { + &rdp.vtx[(rdp.cmd0 >> 17) & 0x7F], + &rdp.vtx[(rdp.cmd0 >> 9) & 0x7F], + &rdp.vtx[(rdp.cmd0 >> 1) & 0x7F] + }; + + rsp_tri1(v); +} + +static void uc6_obj_ldtx_sprite (); +static void uc6_obj_ldtx_rect (); + +static void uc2_quad () +{ + if ((rdp.cmd0 & 0x00FFFFFF) == 0x2F) + { + wxUint32 command = rdp.cmd0>>24; + if (command == 0x6) + { + uc6_obj_ldtx_sprite (); + return; + } + if (command == 0x7) + { + uc6_obj_ldtx_rect (); + return; + } + } + + if (rdp.skip_drawing) + { + LRDP("uc2_quad. skipped\n"); + return; + } + + LRDP("uc2:quad"); + + FRDP(" #%d, #%d - %d, %d, %d - %d, %d, %d\n", rdp.tri_n, rdp.tri_n+1, + ((rdp.cmd0 >> 17) & 0x7F), + ((rdp.cmd0 >> 9) & 0x7F), + ((rdp.cmd0 >> 1) & 0x7F), + ((rdp.cmd1 >> 17) & 0x7F), + ((rdp.cmd1 >> 9) & 0x7F), + ((rdp.cmd1 >> 1) & 0x7F)); + + VERTEX *v[6] = { + &rdp.vtx[(rdp.cmd0 >> 17) & 0x7F], + &rdp.vtx[(rdp.cmd0 >> 9) & 0x7F], + &rdp.vtx[(rdp.cmd0 >> 1) & 0x7F], + &rdp.vtx[(rdp.cmd1 >> 17) & 0x7F], + &rdp.vtx[(rdp.cmd1 >> 9) & 0x7F], + &rdp.vtx[(rdp.cmd1 >> 1) & 0x7F] + }; + + rsp_tri2(v); +} + +static void uc6_ldtx_rect_r (); + +static void uc2_line3d () +{ + if ( (rdp.cmd0&0xFF) == 0x2F ) + uc6_ldtx_rect_r (); + else + { + FRDP("uc2:line3d #%d, #%d - %d, %d\n", rdp.tri_n, rdp.tri_n+1, + (rdp.cmd0 >> 17) & 0x7F, + (rdp.cmd0 >> 9) & 0x7F); + + VERTEX *v[3] = { + &rdp.vtx[(rdp.cmd0 >> 17) & 0x7F], + &rdp.vtx[(rdp.cmd0 >> 9) & 0x7F], + &rdp.vtx[(rdp.cmd0 >> 9) & 0x7F] + }; + wxUint16 width = (wxUint16)(rdp.cmd0 + 3)&0xFF; + wxUint32 cull_mode = (rdp.flags & CULLMASK) >> CULLSHIFT; + rdp.flags |= CULLMASK; + rdp.update |= UPDATE_CULL_MODE; + rsp_tri1(v, width); + rdp.flags ^= CULLMASK; + rdp.flags |= cull_mode << CULLSHIFT; + rdp.update |= UPDATE_CULL_MODE; + } +} + +static void uc2_special3 () +{ + LRDP("uc2:special3\n"); +} + +static void uc2_special2 () +{ + LRDP("uc2:special2\n"); +} + +static void uc2_dma_io () +{ + LRDP("uc2:dma_io\n"); +} + +static void uc2_pop_matrix () +{ + FRDP ("uc2:pop_matrix %08lx, %08lx\n", rdp.cmd0, rdp.cmd1); + + // Just pop the modelview matrix + modelview_pop (rdp.cmd1 >> 6); +} + +static void uc2_geom_mode () +{ + // Switch around some things + wxUint32 clr_mode = (rdp.cmd0 & 0x00DFC9FF) | + ((rdp.cmd0 & 0x00000600) << 3) | + ((rdp.cmd0 & 0x00200000) >> 12) | 0xFF000000; + wxUint32 set_mode = (rdp.cmd1 & 0xFFDFC9FF) | + ((rdp.cmd1 & 0x00000600) << 3) | + ((rdp.cmd1 & 0x00200000) >> 12); + + FRDP("uc2:geom_mode c:%08lx, s:%08lx ", clr_mode, set_mode); + + rdp.geom_mode &= clr_mode; + rdp.geom_mode |= set_mode; + + FRDP ("result:%08lx\n", rdp.geom_mode); + + if (rdp.geom_mode & 0x00000001) // Z-Buffer enable + { + if (!(rdp.flags & ZBUF_ENABLED)) + { + rdp.flags |= ZBUF_ENABLED; + rdp.update |= UPDATE_ZBUF_ENABLED; + } + } + else + { + if ((rdp.flags & ZBUF_ENABLED)) + { + if (!settings.flame_corona || (rdp.rm != 0x00504341)) //hack for flame's corona + rdp.flags ^= ZBUF_ENABLED; + rdp.update |= UPDATE_ZBUF_ENABLED; + } + } + if (rdp.geom_mode & 0x00001000) // Front culling + { + if (!(rdp.flags & CULL_FRONT)) + { + rdp.flags |= CULL_FRONT; + rdp.update |= UPDATE_CULL_MODE; + } + } + else + { + if (rdp.flags & CULL_FRONT) + { + rdp.flags ^= CULL_FRONT; + rdp.update |= UPDATE_CULL_MODE; + } + } + if (rdp.geom_mode & 0x00002000) // Back culling + { + if (!(rdp.flags & CULL_BACK)) + { + rdp.flags |= CULL_BACK; + rdp.update |= UPDATE_CULL_MODE; + } + } + else + { + if (rdp.flags & CULL_BACK) + { + rdp.flags ^= CULL_BACK; + rdp.update |= UPDATE_CULL_MODE; + } + } + + //Added by Gonetz + if (rdp.geom_mode & 0x00010000) // Fog enable + { + if (!(rdp.flags & FOG_ENABLED)) + { + rdp.flags |= FOG_ENABLED; + rdp.update |= UPDATE_FOG_ENABLED; + } + } + else + { + if (rdp.flags & FOG_ENABLED) + { + rdp.flags ^= FOG_ENABLED; + rdp.update |= UPDATE_FOG_ENABLED; + } + } +} + +static void uc6_obj_rectangle_r (); + +static void uc2_matrix () +{ + if (!(rdp.cmd0 & 0x00FFFFFF)) + { + uc6_obj_rectangle_r(); + return; + } + LRDP("uc2:matrix\n"); + + DECLAREALIGN16VAR(m[4][4]); + load_matrix(m, segoffset(rdp.cmd1)); + + wxUint8 command = (wxUint8)((rdp.cmd0 ^ 1) & 0xFF); + switch (command) + { + case 0: // modelview mul nopush + LRDP("modelview mul\n"); + modelview_mul (m); + break; + + case 1: // modelview mul push + LRDP("modelview mul push\n"); + modelview_mul_push (m); + break; + + case 2: // modelview load nopush + LRDP("modelview load\n"); + modelview_load (m); + break; + + case 3: // modelview load push + LRDP("modelview load push\n"); + modelview_load_push (m); + break; + + case 4: // projection mul nopush + case 5: // projection mul push, can't push projection + LRDP("projection mul\n"); + projection_mul (m); + break; + + case 6: // projection load nopush + case 7: // projection load push, can't push projection + LRDP("projection load\n"); + projection_load (m); + break; + + default: + FRDP_E ("Unknown matrix command, %02lx", command); + FRDP ("Unknown matrix command, %02lx", command); + } + +#ifdef EXTREME_LOGGING + FRDP ("{%f,%f,%f,%f}\n", m[0][0], m[0][1], m[0][2], m[0][3]); + FRDP ("{%f,%f,%f,%f}\n", m[1][0], m[1][1], m[1][2], m[1][3]); + FRDP ("{%f,%f,%f,%f}\n", m[2][0], m[2][1], m[2][2], m[2][3]); + FRDP ("{%f,%f,%f,%f}\n", m[3][0], m[3][1], m[3][2], m[3][3]); + FRDP ("\nmodel\n{%f,%f,%f,%f}\n", rdp.model[0][0], rdp.model[0][1], rdp.model[0][2], rdp.model[0][3]); + FRDP ("{%f,%f,%f,%f}\n", rdp.model[1][0], rdp.model[1][1], rdp.model[1][2], rdp.model[1][3]); + FRDP ("{%f,%f,%f,%f}\n", rdp.model[2][0], rdp.model[2][1], rdp.model[2][2], rdp.model[2][3]); + FRDP ("{%f,%f,%f,%f}\n", rdp.model[3][0], rdp.model[3][1], rdp.model[3][2], rdp.model[3][3]); + FRDP ("\nproj\n{%f,%f,%f,%f}\n", rdp.proj[0][0], rdp.proj[0][1], rdp.proj[0][2], rdp.proj[0][3]); + FRDP ("{%f,%f,%f,%f}\n", rdp.proj[1][0], rdp.proj[1][1], rdp.proj[1][2], rdp.proj[1][3]); + FRDP ("{%f,%f,%f,%f}\n", rdp.proj[2][0], rdp.proj[2][1], rdp.proj[2][2], rdp.proj[2][3]); + FRDP ("{%f,%f,%f,%f}\n", rdp.proj[3][0], rdp.proj[3][1], rdp.proj[3][2], rdp.proj[3][3]); +#endif +} + +static void uc2_moveword () +{ + wxUint8 index = (wxUint8)((rdp.cmd0 >> 16) & 0xFF); + wxUint16 offset = (wxUint16)(rdp.cmd0 & 0xFFFF); + wxUint32 data = rdp.cmd1; + + FRDP ("uc2:moveword "); + + switch (index) + { + // NOTE: right now it's assuming that it sets the integer part first. This could + // be easily fixed, but only if i had something to test with. + + case 0x00: // moveword matrix + { + // do matrix pre-mult so it's re-updated next time + if (rdp.update & UPDATE_MULT_MAT) + { + rdp.update ^= UPDATE_MULT_MAT; + MulMatrices(rdp.model, rdp.proj, rdp.combined); + } + + if (rdp.cmd0 & 0x20) // fractional part + { + int index_x = (rdp.cmd0 & 0x1F) >> 1; + int index_y = index_x >> 2; + index_x &= 3; + + float fpart = (rdp.cmd1>>16)/65536.0f; + rdp.combined[index_y][index_x] = (float)(int)rdp.combined[index_y][index_x]; + rdp.combined[index_y][index_x] += fpart; + + fpart = (rdp.cmd1&0xFFFF)/65536.0f; + rdp.combined[index_y][index_x+1] = (float)(int)rdp.combined[index_y][index_x+1]; + rdp.combined[index_y][index_x+1] += fpart; + } + else + { + int index_x = (rdp.cmd0 & 0x1F) >> 1; + int index_y = index_x >> 2; + index_x &= 3; + + float fpart = (float)fabs(rdp.combined[index_y][index_x] - (int)rdp.combined[index_y][index_x]); + rdp.combined[index_y][index_x] = (short)(rdp.cmd1>>16); + + fpart = (float)fabs(rdp.combined[index_y][index_x+1] - (int)rdp.combined[index_y][index_x+1]); + rdp.combined[index_y][index_x+1] = (short)(rdp.cmd1&0xFFFF); + } + + LRDP("matrix\n"); + } + break; + + case 0x02: + rdp.num_lights = data / 24; + rdp.update |= UPDATE_LIGHTS; + FRDP ("numlights: %d\n", rdp.num_lights); + break; + + case 0x04: + if (offset == 0x04) + { + rdp.clip_ratio = sqrt((float)rdp.cmd1); + rdp.update |= UPDATE_VIEWPORT; + } + FRDP ("mw_clip %08lx, %08lx\n", rdp.cmd0, rdp.cmd1); + break; + + case 0x06: // moveword SEGMENT + { + FRDP ("SEGMENT %08lx -> seg%d\n", data, offset >> 2); + if ((data&BMASK)> 2) & 0xF] = data; + } + break; + + + case 0x08: + { + rdp.fog_multiplier = (short)(rdp.cmd1 >> 16); + rdp.fog_offset = (short)(rdp.cmd1 & 0x0000FFFF); + FRDP ("fog: multiplier: %f, offset: %f\n", rdp.fog_multiplier, rdp.fog_offset); + + //offset must be 0 for move_fog, but it can be non zero in Nushi Zuri 64 - Shiokaze ni Notte + //low-level display list has setothermode commands in this place, so this is obviously not move_fog. + if (offset == 0x04) + rdp.tlut_mode = (data == 0xffffffff) ? 0 : 2; + } + break; + + case 0x0a: // moveword LIGHTCOL + { + int n = offset / 24; + FRDP ("lightcol light:%d, %08lx\n", n, data); + + rdp.light[n].r = (float)((data >> 24) & 0xFF) / 255.0f; + rdp.light[n].g = (float)((data >> 16) & 0xFF) / 255.0f; + rdp.light[n].b = (float)((data >> 8) & 0xFF) / 255.0f; + rdp.light[n].a = 255; + } + break; + + case 0x0c: + RDP_E ("uc2:moveword forcemtx - IGNORED\n"); + LRDP("forcemtx - IGNORED\n"); + break; + + case 0x0e: + LRDP("perspnorm - IGNORED\n"); + break; + + default: + FRDP_E("uc2:moveword unknown (index: 0x%08lx, offset 0x%08lx)\n", index, offset); + FRDP ("unknown (index: 0x%08lx, offset 0x%08lx)\n", index, offset); + } +} + +static void uc6_obj_movemem (); + +static void uc2_movemem () +{ + int idx = rdp.cmd0 & 0xFF; + wxUint32 addr = segoffset(rdp.cmd1); + int ofs = (rdp.cmd0 >> 5) & 0x7F8; + + FRDP ("uc2:movemem ofs:%d ", ofs); + + switch (idx) + { + case 0: + case 2: + uc6_obj_movemem (); + break; + + case 8: // VIEWPORT + { + wxUint32 a = addr >> 1; + short scale_x = ((short*)gfx.RDRAM)[(a+0)^1] >> 2; + short scale_y = ((short*)gfx.RDRAM)[(a+1)^1] >> 2; + short scale_z = ((short*)gfx.RDRAM)[(a+2)^1]; + short trans_x = ((short*)gfx.RDRAM)[(a+4)^1] >> 2; + short trans_y = ((short*)gfx.RDRAM)[(a+5)^1] >> 2; + short trans_z = ((short*)gfx.RDRAM)[(a+6)^1]; + rdp.view_scale[0] = scale_x * rdp.scale_x; + rdp.view_scale[1] = -scale_y * rdp.scale_y; + rdp.view_scale[2] = 32.0f * scale_z; + rdp.view_trans[0] = trans_x * rdp.scale_x; + rdp.view_trans[1] = trans_y * rdp.scale_y; + rdp.view_trans[2] = 32.0f * trans_z; + + rdp.update |= UPDATE_VIEWPORT; + + FRDP ("viewport scale(%d, %d, %d), trans(%d, %d, %d), from:%08lx\n", scale_x, scale_y, scale_z, + trans_x, trans_y, trans_z, a); + } + break; + + case 10: // LIGHT + { + int n = ofs / 24; + + if (n < 2) + { + char dir_x = ((char*)gfx.RDRAM)[(addr+8)^3]; + rdp.lookat[n][0] = (float)(dir_x) / 127.0f; + char dir_y = ((char*)gfx.RDRAM)[(addr+9)^3]; + rdp.lookat[n][1] = (float)(dir_y) / 127.0f; + char dir_z = ((char*)gfx.RDRAM)[(addr+10)^3]; + rdp.lookat[n][2] = (float)(dir_z) / 127.0f; + rdp.use_lookat = TRUE; + if (n == 1) + { + if (!dir_x && !dir_y) + rdp.use_lookat = FALSE; + } + FRDP("lookat_%d (%f, %f, %f)\n", n, rdp.lookat[n][0], rdp.lookat[n][1], rdp.lookat[n][2]); + return; + } + n -= 2; + if (n > 7) return; + + // Get the data + wxUint8 col = gfx.RDRAM[(addr+0)^3]; + rdp.light[n].r = (float)col / 255.0f; + rdp.light[n].nonblack = col; + col = gfx.RDRAM[(addr+1)^3]; + rdp.light[n].g = (float)col / 255.0f; + rdp.light[n].nonblack += col; + col = gfx.RDRAM[(addr+2)^3]; + rdp.light[n].b = (float)col / 255.0f; + rdp.light[n].nonblack += col; + rdp.light[n].a = 1.0f; + // ** Thanks to Icepir8 for pointing this out ** + // Lighting must be signed byte instead of byte + rdp.light[n].dir_x = (float)(((char*)gfx.RDRAM)[(addr+8)^3]) / 127.0f; + rdp.light[n].dir_y = (float)(((char*)gfx.RDRAM)[(addr+9)^3]) / 127.0f; + rdp.light[n].dir_z = (float)(((char*)gfx.RDRAM)[(addr+10)^3]) / 127.0f; + wxUint32 a = addr >> 1; + rdp.light[n].x = (float)(((short*)gfx.RDRAM)[(a+4)^1]); + rdp.light[n].y = (float)(((short*)gfx.RDRAM)[(a+5)^1]); + rdp.light[n].z = (float)(((short*)gfx.RDRAM)[(a+6)^1]); + rdp.light[n].ca = (float)(gfx.RDRAM[(addr+3)^3]) / 16.0f; + rdp.light[n].la = (float)(gfx.RDRAM[(addr+7)^3]); + rdp.light[n].qa = (float)(gfx.RDRAM[(addr+14)^3]) / 8.0f; +#ifdef EXTREME_LOGGING + FRDP ("light: n: %d, pos: x: %f, y: %f, z: %f, ca: %f, la:%f, qa: %f\n", + n, rdp.light[n].x, rdp.light[n].y, rdp.light[n].z, rdp.light[n].ca, rdp.light[n].la, rdp.light[n].qa); +#endif + FRDP ("light: n: %d, r: %.3f, g: %.3f, b: %.3f. dir: x: %.3f, y: %.3f, z: %.3f\n", + n, rdp.light[n].r, rdp.light[n].g, rdp.light[n].b, + rdp.light[n].dir_x, rdp.light[n].dir_y, rdp.light[n].dir_z); + } + break; + + case 14: // matrix + { + // do not update the combined matrix! + rdp.update &= ~UPDATE_MULT_MAT; + load_matrix(rdp.combined, segoffset(rdp.cmd1)); + +#ifdef EXTREME_LOGGING + FRDP ("{%f,%f,%f,%f}\n", rdp.combined[0][0], rdp.combined[0][1], rdp.combined[0][2], rdp.combined[0][3]); + FRDP ("{%f,%f,%f,%f}\n", rdp.combined[1][0], rdp.combined[1][1], rdp.combined[1][2], rdp.combined[1][3]); + FRDP ("{%f,%f,%f,%f}\n", rdp.combined[2][0], rdp.combined[2][1], rdp.combined[2][2], rdp.combined[2][3]); + FRDP ("{%f,%f,%f,%f}\n", rdp.combined[3][0], rdp.combined[3][1], rdp.combined[3][2], rdp.combined[3][3]); +#endif + } + break; + + default: + FRDP ("uc2:matrix unknown (%d)\n", idx); + FRDP ("** UNKNOWN %d\n", idx); + } +} + +static void uc2_load_ucode () +{ + LRDP("uc2:load_ucode\n"); +} + +static void uc2_rdphalf_2 () +{ + LRDP("uc2:rdphalf_2\n"); +} + +static void uc2_dlist_cnt () +{ + wxUint32 addr = segoffset(rdp.cmd1) & BMASK; + int count = rdp.cmd0 & 0x000000FF; + FRDP ("dl_count - addr: %08lx, count: %d\n", addr, count); + if (addr == 0) + return; + + if (rdp.pc_i >= 9) { + RDP_E ("** DL stack overflow **\n"); + LRDP("** DL stack overflow **\n"); + return; + } + rdp.pc_i ++; // go to the next PC in the stack + rdp.pc[rdp.pc_i] = addr; // jump to the address + rdp.dl_count = count + 1; +} diff --git a/Source/Glide64/ucode03.h b/Source/Glide64/ucode03.h new file mode 100644 index 000000000..8bd5a5830 --- /dev/null +++ b/Source/Glide64/ucode03.h @@ -0,0 +1,114 @@ +/* +* Glide64 - Glide video plugin for Nintendo 64 emulators. +* Copyright (c) 2002 Dave2001 +* Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski +* +* 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 +* 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 +*/ + +//**************************************************************** +// +// Glide64 - Glide Plugin for Nintendo 64 emulators +// Project started on December 29th, 2001 +// +// Authors: +// Dave2001, original author, founded the project in 2001, left it in 2002 +// Gugaman, joined the project in 2002, left it in 2002 +// Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002 +// Hiroshi 'KoolSmoky' Morii, joined the project in 2007 +// +//**************************************************************** +// +// To modify Glide64: +// * Write your name and (optional)email, commented by your work, so I know who did it, and so that you can find which parts you modified when it comes time to send it to me. +// * Do NOT send me the whole project or file that you modified. Take out your modified code sections, and tell me where to put them. If people sent the whole thing, I would have many different versions, but no idea how to combine them all. +// +//**************************************************************** + +// +// vertex - loads vertices +// + +static void uc3_vertex() +{ + int v0 = ((rdp.cmd0 >> 16) & 0xFF)/5; // Current vertex + int n = (wxUint16)((rdp.cmd0&0xFFFF) + 1)/0x210; // Number to copy + + if (v0 >= 32) + v0 = 31; + + if ((v0 + n) > 32) + n = 32 - v0; + + rsp_vertex(v0, n); +} + +// +// tri1 - renders a triangle +// + +static void uc3_tri1() +{ + FRDP("uc3:tri1 #%d - %d, %d, %d - %08lx - %08lx\n", rdp.tri_n, + ((rdp.cmd1 >> 16) & 0xFF)/5, + ((rdp.cmd1 >> 8) & 0xFF)/5, + ((rdp.cmd1 ) & 0xFF)/5, rdp.cmd0, rdp.cmd1); + + VERTEX *v[3] = { + &rdp.vtx[((rdp.cmd1 >> 16) & 0xFF)/5], + &rdp.vtx[((rdp.cmd1 >> 8) & 0xFF)/5], + &rdp.vtx[(rdp.cmd1 & 0xFF)/5] + }; + + rsp_tri1(v); +} + +static void uc3_tri2 () +{ + FRDP("uc3:tri2 #%d, #%d - %d, %d, %d - %d, %d, %d\n", rdp.tri_n, rdp.tri_n+1, + ((rdp.cmd0 >> 16) & 0xFF)/5, + ((rdp.cmd0 >> 8) & 0xFF)/5, + ((rdp.cmd0 ) & 0xFF)/5, + ((rdp.cmd1 >> 16) & 0xFF)/5, + ((rdp.cmd1 >> 8) & 0xFF)/5, + ((rdp.cmd1 ) & 0xFF)/5); + + VERTEX *v[6] = { + &rdp.vtx[((rdp.cmd0 >> 16) & 0xFF)/5], + &rdp.vtx[((rdp.cmd0 >> 8) & 0xFF)/5], + &rdp.vtx[(rdp.cmd0 & 0xFF)/5], + &rdp.vtx[((rdp.cmd1 >> 16) & 0xFF)/5], + &rdp.vtx[((rdp.cmd1 >> 8) & 0xFF)/5], + &rdp.vtx[(rdp.cmd1 & 0xFF)/5] + }; + + rsp_tri2(v); +} + +static void uc3_quad3d() +{ + FRDP("uc3:quad3d #%d, #%d\n", rdp.tri_n, rdp.tri_n+1); + + VERTEX *v[6] = { + &rdp.vtx[((rdp.cmd1 >> 24) & 0xFF)/5], + &rdp.vtx[((rdp.cmd1 >> 16) & 0xFF)/5], + &rdp.vtx[((rdp.cmd1 >> 8) & 0xFF)/5], + &rdp.vtx[(rdp.cmd1 & 0xFF)/5], + &rdp.vtx[((rdp.cmd1 >> 24) & 0xFF)/5], + &rdp.vtx[((rdp.cmd1 >> 8) & 0xFF)/5] + }; + + rsp_tri2(v); +} diff --git a/Source/Glide64/ucode04.h b/Source/Glide64/ucode04.h new file mode 100644 index 000000000..30c4c0e61 --- /dev/null +++ b/Source/Glide64/ucode04.h @@ -0,0 +1,82 @@ +/* +* Glide64 - Glide video plugin for Nintendo 64 emulators. +* Copyright (c) 2002 Dave2001 +* Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski +* +* 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 +* 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 +*/ + +//**************************************************************** +// +// Glide64 - Glide Plugin for Nintendo 64 emulators +// Project started on December 29th, 2001 +// +// Authors: +// Dave2001, original author, founded the project in 2001, left it in 2002 +// Gugaman, joined the project in 2002, left it in 2002 +// Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002 +// Hiroshi 'KoolSmoky' Morii, joined the project in 2007 +// +//**************************************************************** +// +// To modify Glide64: +// * Write your name and (optional)email, commented by your work, so I know who did it, and so that you can find which parts you modified when it comes time to send it to me. +// * Do NOT send me the whole project or file that you modified. Take out your modified code sections, and tell me where to put them. If people sent the whole thing, I would have many different versions, but no idea how to combine them all. +// +//**************************************************************** + +//**************************************************************** +// uCode 4 - RSP SW 2.0D EXT +//**************************************************************** + +static void uc4_vertex() +{ + int v0 = 0; // Current vertex + int n = ((rdp.cmd0 >> 4) & 0xFFF) / 33 + 1; // Number of vertices to copy + rsp_vertex(v0, n); +} + +static void uc4_tri1() +{ + int v1 = ((rdp.cmd1 >> 16) & 0xFF) / 5; + int v2 = ((rdp.cmd1 >> 8) & 0xFF) / 5; + int v3 = (rdp.cmd1 & 0xFF) / 5; + FRDP("uc4:tri1 #%d - %d, %d, %d\n", rdp.tri_n, + v1, v2, v3); + + VERTEX *v[3] = { + &rdp.vtx[v1], + &rdp.vtx[v2], + &rdp.vtx[v3] + }; + + rsp_tri1(v); +} + +static void uc4_quad3d() +{ + FRDP("uc4:quad3d #%d, #%d\n", rdp.tri_n, rdp.tri_n+1); + + VERTEX *v[6] = { + &rdp.vtx[((rdp.cmd1 >> 24) & 0xFF) / 5], + &rdp.vtx[((rdp.cmd1 >> 16) & 0xFF) / 5], + &rdp.vtx[((rdp.cmd1 >> 8) & 0xFF) / 5], + &rdp.vtx[((rdp.cmd1 >> 24) & 0xFF) / 5], + &rdp.vtx[((rdp.cmd1 >> 8) & 0xFF) / 5], + &rdp.vtx[(rdp.cmd1 & 0xFF) / 5] + }; + + rsp_tri2(v); +} diff --git a/Source/Glide64/ucode05.h b/Source/Glide64/ucode05.h new file mode 100644 index 000000000..278398c1e --- /dev/null +++ b/Source/Glide64/ucode05.h @@ -0,0 +1,375 @@ +/* +* Glide64 - Glide video plugin for Nintendo 64 emulators. +* Copyright (c) 2002 Dave2001 +* Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski +* +* 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 +* 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 +*/ + +//**************************************************************** +// +// Glide64 - Glide Plugin for Nintendo 64 emulators +// Project started on December 29th, 2001 +// +// Authors: +// Dave2001, original author, founded the project in 2001, left it in 2002 +// Gugaman, joined the project in 2002, left it in 2002 +// Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002 +// Hiroshi 'KoolSmoky' Morii, joined the project in 2007 +// +//**************************************************************** +// +// To modify Glide64: +// * Write your name and (optional)email, commented by your work, so I know who did it, and so that you can find which parts you modified when it comes time to send it to me. +// * Do NOT send me the whole project or file that you modified. Take out your modified code sections, and tell me where to put them. If people sent the whole thing, I would have many different versions, but no idea how to combine them all. +// +//**************************************************************** + +int cur_mtx = 0; +int billboarding = 0; +int vtx_last = 0; +wxUint32 dma_offset_mtx = 0; +wxUint32 dma_offset_vtx = 0; + +static void uc5_dma_offsets () +{ + dma_offset_mtx = rdp.cmd0 & 0x00FFFFFF; + dma_offset_vtx = rdp.cmd1 & 0x00FFFFFF; + vtx_last = 0; + FRDP("uc5:dma_offsets - mtx: %08lx, vtx: %08lx\n", dma_offset_mtx, dma_offset_vtx); +} + +static void uc5_matrix () +{ + // Use segment offset to get the address + wxUint32 addr = dma_offset_mtx + (segoffset(rdp.cmd1) & BMASK); + + wxUint8 n = (wxUint8)((rdp.cmd0 >> 16) & 0xF); + wxUint8 multiply; + + if (n == 0) //DKR + { + n = (wxUint8)((rdp.cmd0 >> 22) & 0x3); + multiply = 0; + } + else //JF + { + multiply = (wxUint8)((rdp.cmd0 >> 23) & 0x1); + } + + cur_mtx = n; + + FRDP("uc5:matrix - #%d, addr: %08lx\n", n, addr); + + if (multiply) + { + DECLAREALIGN16VAR(m[4][4]); + load_matrix(m, addr); + DECLAREALIGN16VAR(m_src[4][4]); + memcpy (m_src, rdp.dkrproj[0], 64); + MulMatrices(m, m_src, rdp.dkrproj[n]); + } + else + { + load_matrix(rdp.dkrproj[n], addr); + } + rdp.update |= UPDATE_MULT_MAT; + +#ifdef EXTREME_LOGGING + FRDP ("{%f,%f,%f,%f}\n", rdp.dkrproj[n][0][0], rdp.dkrproj[n][0][1], rdp.dkrproj[n][0][2], rdp.dkrproj[n][0][3]); + FRDP ("{%f,%f,%f,%f}\n", rdp.dkrproj[n][1][0], rdp.dkrproj[n][1][1], rdp.dkrproj[n][1][2], rdp.dkrproj[n][1][3]); + FRDP ("{%f,%f,%f,%f}\n", rdp.dkrproj[n][2][0], rdp.dkrproj[n][2][1], rdp.dkrproj[n][2][2], rdp.dkrproj[n][2][3]); + FRDP ("{%f,%f,%f,%f}\n", rdp.dkrproj[n][3][0], rdp.dkrproj[n][3][1], rdp.dkrproj[n][3][2], rdp.dkrproj[n][3][3]); + + for (int i=0; i<3; i++) + { + FRDP ("proj %d\n", i); + FRDP ("{%f,%f,%f,%f}\n", rdp.dkrproj[i][0][0], rdp.dkrproj[i][0][1], rdp.dkrproj[i][0][2], rdp.dkrproj[i][0][3]); + FRDP ("{%f,%f,%f,%f}\n", rdp.dkrproj[i][1][0], rdp.dkrproj[i][1][1], rdp.dkrproj[i][1][2], rdp.dkrproj[i][1][3]); + FRDP ("{%f,%f,%f,%f}\n", rdp.dkrproj[i][2][0], rdp.dkrproj[i][2][1], rdp.dkrproj[i][2][2], rdp.dkrproj[i][2][3]); + FRDP ("{%f,%f,%f,%f}\n", rdp.dkrproj[i][3][0], rdp.dkrproj[i][3][1], rdp.dkrproj[i][3][2], rdp.dkrproj[i][3][3]); + } +#endif +} + +static void uc5_vertex () +{ + wxUint32 addr = dma_offset_vtx + (segoffset(rdp.cmd1) & BMASK); + + // | cccc cccc 1111 1??? 0000 0002 2222 2222 | cmd1 = address | + // c = vtx command + // 1 = method #1 of getting count + // 2 = method #2 of getting count + // ? = unknown, but used + // 0 = unused + + int n = ((rdp.cmd0 >> 19) & 0x1F);// + 1; + if (settings.hacks&hack_Diddy) + n++; + + if (rdp.cmd0 & 0x00010000) + { + if (billboarding) + vtx_last = 1; + } + else + vtx_last = 0; + + int first = ((rdp.cmd0 >> 9) & 0x1F) + vtx_last; + FRDP ("uc5:vertex - addr: %08lx, first: %d, count: %d, matrix: %08lx\n", addr, first, n, cur_mtx); + + int prj = cur_mtx; + + int start = 0; + float x, y, z; + for (int i=first; i> 1) + 0)^1]; + y = (float)((short*)gfx.RDRAM)[(((addr+start) >> 1) + 1)^1]; + z = (float)((short*)gfx.RDRAM)[(((addr+start) >> 1) + 2)^1]; + + v->x = x*rdp.dkrproj[prj][0][0] + y*rdp.dkrproj[prj][1][0] + z*rdp.dkrproj[prj][2][0] + rdp.dkrproj[prj][3][0]; + v->y = x*rdp.dkrproj[prj][0][1] + y*rdp.dkrproj[prj][1][1] + z*rdp.dkrproj[prj][2][1] + rdp.dkrproj[prj][3][1]; + v->z = x*rdp.dkrproj[prj][0][2] + y*rdp.dkrproj[prj][1][2] + z*rdp.dkrproj[prj][2][2] + rdp.dkrproj[prj][3][2]; + v->w = x*rdp.dkrproj[prj][0][3] + y*rdp.dkrproj[prj][1][3] + z*rdp.dkrproj[prj][2][3] + rdp.dkrproj[prj][3][3]; + + if (billboarding) + { + v->x += rdp.vtx[0].x; + v->y += rdp.vtx[0].y; + v->z += rdp.vtx[0].z; + v->w += rdp.vtx[0].w; + } + + if (fabs(v->w) < 0.001) v->w = 0.001f; + v->oow = 1.0f / v->w; + v->x_w = v->x * v->oow; + v->y_w = v->y * v->oow; + v->z_w = v->z * v->oow; + + v->uv_calculated = 0xFFFFFFFF; + v->screen_translated = 0; + v->shade_mod = 0; + + v->scr_off = 0; + if (v->x < -v->w) v->scr_off |= 1; + if (v->x > v->w) v->scr_off |= 2; + if (v->y < -v->w) v->scr_off |= 4; + if (v->y > v->w) v->scr_off |= 8; + if (v->w < 0.1f) v->scr_off |= 16; + if (fabs(v->z_w) > 1.0) v->scr_off |= 32; + + v->r = ((wxUint8*)gfx.RDRAM)[(addr+start + 6)^3]; + v->g = ((wxUint8*)gfx.RDRAM)[(addr+start + 7)^3]; + v->b = ((wxUint8*)gfx.RDRAM)[(addr+start + 8)^3]; + v->a = ((wxUint8*)gfx.RDRAM)[(addr+start + 9)^3]; + CalculateFog (v); + +#ifdef EXTREME_LOGGING + FRDP ("v%d - x: %f, y: %f, z: %f, w: %f, z_w: %f, r=%d, g=%d, b=%d, a=%d\n", i, v->x, v->y, v->z, v->w, v->z_w, v->r, v->g, v->b, v->a); +#endif + } + + vtx_last += n; +} + +static void uc5_tridma () +{ + vtx_last = 0; // we've drawn something, so the vertex index needs resetting + if (rdp.skip_drawing) + return; + + // | cccc cccc 2222 0000 1111 1111 1111 0000 | cmd1 = address | + // c = tridma command + // 1 = method #1 of getting count + // 2 = method #2 of getting count + // 0 = unused + + wxUint32 addr = segoffset(rdp.cmd1) & BMASK; + int num = (rdp.cmd0 & 0xFFF0) >> 4; + //int num = ((rdp.cmd0 & 0x00F00000) >> 20) + 1; // same thing! + FRDP("uc5:tridma #%d - addr: %08lx, count: %d\n", rdp.tri_n, addr, num); + + int start, v0, v1, v2, flags; + for (int i=0; iou = (float)((short*)gfx.RDRAM)[((addr+start) >> 1) + 5] / 32.0f; + v[0]->ov = (float)((short*)gfx.RDRAM)[((addr+start) >> 1) + 4] / 32.0f; + v[1]->ou = (float)((short*)gfx.RDRAM)[((addr+start) >> 1) + 3] / 32.0f; + v[1]->ov = (float)((short*)gfx.RDRAM)[((addr+start) >> 1) + 2] / 32.0f; + v[2]->ou = (float)((short*)gfx.RDRAM)[((addr+start) >> 1) + 1] / 32.0f; + v[2]->ov = (float)((short*)gfx.RDRAM)[((addr+start) >> 1) + 0] / 32.0f; + + v[0]->uv_calculated = 0xFFFFFFFF; + v[1]->uv_calculated = 0xFFFFFFFF; + v[2]->uv_calculated = 0xFFFFFFFF; + + if (cull_tri(v)) + rdp.tri_n ++; + else + { + update (); + + draw_tri (v); + rdp.tri_n ++; + } + } +} + +static void uc5_dl_in_mem () +{ + wxUint32 addr = segoffset(rdp.cmd1) & BMASK; + int count = (rdp.cmd0 & 0x00FF0000) >> 16; + FRDP ("uc5:dl_in_mem - addr: %08lx, count: %d\n", addr, count); + + if (rdp.pc_i >= 9) { + RDP_E ("** DL stack overflow **\n"); + LRDP("** DL stack overflow **\n"); + return; + } + rdp.pc_i ++; // go to the next PC in the stack + rdp.pc[rdp.pc_i] = addr; // jump to the address + rdp.dl_count = count + 1; +} + +static void uc5_moveword() +{ + LRDP("uc5:moveword "); + + // Find which command this is (lowest byte of cmd0) + switch (rdp.cmd0 & 0xFF) + { + case 0x02: // moveword matrix 2 billboard + billboarding = (rdp.cmd1 & 1); + FRDP ("matrix billboard - %s\n", str_offon[billboarding]); + break; + + case 0x04: // clip (verified same) + if (((rdp.cmd0>>8)&0xFFFF) == 0x04) + { + rdp.clip_ratio = sqrt((float)rdp.cmd1); + rdp.update |= UPDATE_VIEWPORT; + } + FRDP ("clip %08lx, %08lx\n", rdp.cmd0, rdp.cmd1); + break; + + case 0x06: // segment (verified same) + FRDP ("segment: %08lx -> seg%d\n", rdp.cmd1, (rdp.cmd0 >> 10) & 0x0F); + rdp.segment[(rdp.cmd0 >> 10) & 0x0F] = rdp.cmd1; + break; + + case 0x08: + { + rdp.fog_multiplier = (short)(rdp.cmd1 >> 16); + rdp.fog_offset = (short)(rdp.cmd1 & 0x0000FFFF); + FRDP ("fog: multiplier: %f, offset: %f\n", rdp.fog_multiplier, rdp.fog_offset); + // rdp.update |= UPDATE_FOG_ENABLED; + } + break; + + case 0x0a: // moveword matrix select + cur_mtx = (rdp.cmd1 >> 6) & 3; + FRDP ("matrix select - mtx: %d\n", cur_mtx); + break; + + default: + FRDP ("(unknown) %02lx - IGNORED\n", rdp.cmd0&0xFF); + } +} + +static void uc5_setgeometrymode() +{ + FRDP("uc0:setgeometrymode %08lx\n", rdp.cmd1); + + rdp.geom_mode |= rdp.cmd1; + + if (rdp.cmd1 & 0x00000001) // Z-Buffer enable + { + if (!(rdp.flags & ZBUF_ENABLED)) + { + rdp.flags |= ZBUF_ENABLED; + rdp.update |= UPDATE_ZBUF_ENABLED; + } + } + + //Added by Gonetz + if (rdp.cmd1 & 0x00010000) // Fog enable + { + if (!(rdp.flags & FOG_ENABLED)) + { + rdp.flags |= FOG_ENABLED; + rdp.update |= UPDATE_FOG_ENABLED; + } + } +} + +static void uc5_cleargeometrymode() +{ + FRDP("uc0:cleargeometrymode %08lx\n", rdp.cmd1); + + rdp.geom_mode &= (~rdp.cmd1); + + if (rdp.cmd1 & 0x00000001) // Z-Buffer enable + { + if (rdp.flags & ZBUF_ENABLED) + { + rdp.flags ^= ZBUF_ENABLED; + rdp.update |= UPDATE_ZBUF_ENABLED; + } + } + //Added by Gonetz + if (rdp.cmd1 & 0x00010000) // Fog enable + { + if (rdp.flags & FOG_ENABLED) + { + rdp.flags ^= FOG_ENABLED; + rdp.update |= UPDATE_FOG_ENABLED; + } + } +} diff --git a/Source/Glide64/ucode06.h b/Source/Glide64/ucode06.h new file mode 100644 index 000000000..ad0dbe56a --- /dev/null +++ b/Source/Glide64/ucode06.h @@ -0,0 +1,1720 @@ +/* +* Glide64 - Glide video plugin for Nintendo 64 emulators. +* Copyright (c) 2002 Dave2001 +* Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski +* +* 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 +* 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 +*/ + +//**************************************************************** +// +// Glide64 - Glide Plugin for Nintendo 64 emulators +// Project started on December 29th, 2001 +// +// Authors: +// Dave2001, original author, founded the project in 2001, left it in 2002 +// Gugaman, joined the project in 2002, left it in 2002 +// Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002 +// Hiroshi 'KoolSmoky' Morii, joined the project in 2007 +// +//**************************************************************** +// +// To modify Glide64: +// * Write your name and (optional)email, commented by your work, so I know who did it, and so that you can find which parts you modified when it comes time to send it to me. +// * Do NOT send me the whole project or file that you modified. Take out your modified code sections, and tell me where to put them. If people sent the whole thing, I would have many different versions, but no idea how to combine them all. +// +//**************************************************************** + +// STANDARD DRAWIMAGE - draws a 2d image based on the following structure + +static float set_sprite_combine_mode () +{ + if (rdp.cycle_mode == 2) + { + rdp.tex = 1; + rdp.allow_combine = 0; + // Now actually combine ! + GrCombineFunction_t color_source = GR_COMBINE_FUNCTION_LOCAL; + if (rdp.tbuff_tex && rdp.tbuff_tex->info.format == GR_TEXFMT_ALPHA_INTENSITY_88) + color_source = GR_COMBINE_FUNCTION_LOCAL_ALPHA; + cmb.tmu1_func = cmb.tmu0_func = color_source; + cmb.tmu1_fac = cmb.tmu0_fac = GR_COMBINE_FACTOR_NONE; + cmb.tmu1_a_func = cmb.tmu0_a_func = GR_COMBINE_FUNCTION_LOCAL; + cmb.tmu1_a_fac = cmb.tmu0_a_fac = GR_COMBINE_FACTOR_NONE; + cmb.tmu1_invert = cmb.tmu0_invert = FXFALSE; + cmb.tmu1_a_invert = cmb.tmu0_a_invert = FXFALSE; + } + + rdp.update |= UPDATE_COMBINE; + update (); + + rdp.allow_combine = 1; + + // set z buffer mode + float Z = 0.0f; + if ((rdp.othermode_l & 0x00000030) && rdp.cycle_mode < 2) + { + wxUint16 prim_dz = 0; + if (rdp.zsrc == 1) + { + Z = rdp.prim_depth; + prim_dz = rdp.prim_dz; + } + FRDP ("prim_depth = %d, prim_dz = %d\n", rdp.prim_depth, rdp.prim_dz); + Z = ScaleZ(Z); + + if (rdp.othermode_l & 0x00000400) + grDepthBiasLevel(rdp.prim_dz); + } + else + { + LRDP("z compare not used, using 0\n"); + } + + grCullMode (GR_CULL_DISABLE); + grFogMode (GR_FOG_DISABLE); + rdp.update |= UPDATE_CULL_MODE | UPDATE_FOG_ENABLED; + + if (rdp.cycle_mode == 2) + { + grColorCombine (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_NONE, + GR_COMBINE_OTHER_TEXTURE, + FXFALSE); + grAlphaCombine (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_NONE, + GR_COMBINE_OTHER_TEXTURE, + FXFALSE); + grAlphaBlendFunction (GR_BLEND_ONE, + GR_BLEND_ZERO, + GR_BLEND_ZERO, + GR_BLEND_ZERO); + if (rdp.othermode_l & 1) + { + grAlphaTestFunction (GR_CMP_GEQUAL); + grAlphaTestReferenceValue (0x80); + } + else + grAlphaTestFunction (GR_CMP_ALWAYS); + rdp.update |= UPDATE_ALPHA_COMPARE | UPDATE_COMBINE; + } + return Z; +} + +void uc6_sprite2d (); + +typedef struct DRAWIMAGE_t { + float frameX; + float frameY; + wxUint16 frameW; + wxUint16 frameH; + wxUint16 imageX; + wxUint16 imageY; + wxUint16 imageW; + wxUint16 imageH; + wxUint32 imagePtr; + wxUint8 imageFmt; + wxUint8 imageSiz; + wxUint16 imagePal; + wxUint8 flipX; + wxUint8 flipY; + float scaleX; + float scaleY; +} DRAWIMAGE; + +typedef struct DRAWOBJECT_t { + float objX; + float objY; + float scaleW; + float scaleH; + short imageW; + short imageH; + + wxUint16 imageStride; + wxUint16 imageAdrs; + wxUint8 imageFmt; + wxUint8 imageSiz; + wxUint8 imagePal; + wxUint8 imageFlags; +} DRAWOBJECT; + +void DrawHiresDepthImage (const DRAWIMAGE & d) +{ + wxUint16 * src = (wxUint16*)(gfx.RDRAM+d.imagePtr); + wxUint16 image[512*512]; + wxUint16 * dst = image; + for (int h = 0; h < d.imageH; h++) + { + for (int w = 0; w < d.imageW; w++) + { + *(dst++) = src[(w+h*d.imageW)^1]; + } + dst += (512 - d.imageW); + } + GrTexInfo t_info; + t_info.format = GR_TEXFMT_RGB_565; + t_info.data = image; + t_info.smallLodLog2 = GR_LOD_LOG2_512; + t_info.largeLodLog2 = GR_LOD_LOG2_512; + t_info.aspectRatioLog2 = GR_ASPECT_LOG2_1x1; + + grTexDownloadMipMap (rdp.texbufs[1].tmu, + rdp.texbufs[1].begin, + GR_MIPMAPLEVELMASK_BOTH, + &t_info); + grTexSource (rdp.texbufs[1].tmu, + rdp.texbufs[1].begin, + GR_MIPMAPLEVELMASK_BOTH, + &t_info); + grTexCombine( GR_TMU1, + GR_COMBINE_FUNCTION_LOCAL, + GR_COMBINE_FACTOR_NONE, + GR_COMBINE_FUNCTION_LOCAL, + GR_COMBINE_FACTOR_NONE, + FXFALSE, + FXFALSE ); + grTexCombine( GR_TMU0, + GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_ONE, + FXFALSE, + FXFALSE ); + grColorCombine (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_NONE, + GR_COMBINE_OTHER_TEXTURE, + FXFALSE); + grAlphaCombine (GR_COMBINE_FUNCTION_SCALE_OTHER, + GR_COMBINE_FACTOR_ONE, + GR_COMBINE_LOCAL_NONE, + GR_COMBINE_OTHER_TEXTURE, + FXFALSE); + grAlphaBlendFunction (GR_BLEND_ONE, + GR_BLEND_ZERO, + GR_BLEND_ONE, + GR_BLEND_ZERO); + grDepthBufferFunction (GR_CMP_ALWAYS); + grDepthMask (FXFALSE); + + GrLOD_t LOD = GR_LOD_LOG2_1024; + if (settings.scr_res_x > 1024) + LOD = GR_LOD_LOG2_2048; + + float lr_x = (float)d.imageW * rdp.scale_x; + float lr_y = (float)d.imageH * rdp.scale_y; + float lr_u = (float)d.imageW * 0.5f;// - 0.5f; + float lr_v = (float)d.imageH * 0.5f;// - 0.5f; + VERTEX v[4] = { + { 0, 0, 1.0f, 1.0f, 0, 0, 0, 0 }, + { lr_x, 0, 1.0f, 1.0f, lr_u, 0, lr_u, 0 }, + { 0, lr_y, 1.0f, 1.0f, 0, lr_v, 0, lr_v }, + { lr_x, lr_y, 1.0f, 1.0f, lr_u, lr_v, lr_u, lr_v } + }; + AddOffset(v, 4); + for (int i=0; i<4; i++) + { + v[i].uc(0) = v[i].uc(1) = v[i].u0; + v[i].vc(0) = v[i].vc(1) = v[i].v0; + } + grTextureBufferExt( rdp.texbufs[0].tmu, rdp.texbufs[0].begin, LOD, LOD, + GR_ASPECT_LOG2_1x1, GR_TEXFMT_RGB_565, GR_MIPMAPLEVELMASK_BOTH ); + grRenderBuffer( GR_BUFFER_TEXTUREBUFFER_EXT ); + grAuxBufferExt( GR_BUFFER_AUXBUFFER ); + grSstOrigin(GR_ORIGIN_UPPER_LEFT); + grBufferClear (0, 0, 0xFFFF); + grDrawTriangle (&v[0], &v[2], &v[1]); + grDrawTriangle (&v[2], &v[3], &v[1]); + grRenderBuffer( GR_BUFFER_BACKBUFFER ); + grTextureAuxBufferExt( rdp.texbufs[0].tmu, rdp.texbufs[0].begin, LOD, LOD, + GR_ASPECT_LOG2_1x1, GR_TEXFMT_RGB_565, GR_MIPMAPLEVELMASK_BOTH ); + grAuxBufferExt( GR_BUFFER_TEXTUREAUXBUFFER_EXT ); + grDepthMask (FXTRUE); +} + + +void DrawDepthImage (const DRAWIMAGE & d) +{ + if (!fullscreen || !fb_depth_render_enabled) + return; + if (d.imageH > d.imageW) + return; + LRDP("Depth image write\n"); + if (fb_hwfbe_enabled) + { + DrawHiresDepthImage(d); + return; + } + float scale_x_dst = rdp.scale_x; + float scale_y_dst = rdp.scale_y; + float scale_x_src = 1.0f/rdp.scale_x; + float scale_y_src = 1.0f/rdp.scale_y; + int src_width = d.imageW; + int src_height = d.imageH; + int dst_width = min(int(src_width*scale_x_dst), (int)settings.scr_res_x); + int dst_height = min(int(src_height*scale_y_dst), (int)settings.scr_res_y); + wxUint16 * src = (wxUint16*)(gfx.RDRAM+d.imagePtr); + wxUint16 * dst = new wxUint16[dst_width*dst_height]; + for (int y=0; y < dst_height; y++) + { + for (int x=0; x < dst_width; x++) + { + dst[x+y*dst_width] = src[(int(x*scale_x_src)+int(y*scale_y_src)*src_width)^1]; + } + } + grLfbWriteRegion(GR_BUFFER_AUXBUFFER, + 0, + 0, + GR_LFB_SRC_FMT_ZA16, + dst_width, + dst_height, + FXFALSE, + dst_width<<1, + dst); + delete[] dst; +} + +void DrawImage (DRAWIMAGE & d) +{ + if (d.imageW == 0 || d.imageH == 0 || d.frameH == 0) return; + + int x_size, y_size, x_shift, y_shift, line; + // choose optimum size for the format/size + switch (d.imageSiz) + { + case 0: + if (rdp.tlut_mode < 2) + { + y_size = 64; + y_shift = 6; + } + else + { + y_size = 32; + y_shift = 5; + } + x_size = 128; + x_shift = 7; + line = 8; + break; + case 1: + if (rdp.tlut_mode < 2) + { + y_size = 64; + y_shift = 6; + } + else + { + y_size = 32; + y_shift = 5; + } + x_size = 64; + x_shift = 6; + line = 8; + break; + case 2: + x_size = 64; + y_size = 32; + x_shift = 6; + y_shift = 5; + line = 16; + break; + case 3: + x_size = 32; + y_size = 16; + x_shift = 4; + y_shift = 3; + line = 16; + break; + default: + FRDP("DrawImage. unknown image size: %d\n", d.imageSiz); + return; + } + + if (rdp.ci_width == 512 && !no_dlist) //RE2 + { + wxUint16 width = (wxUint16)(*gfx.VI_WIDTH_REG & 0xFFF); + d.frameH = d.imageH = (d.frameW*d.frameH)/width; + d.frameW = d.imageW = width; + if (rdp.zimg == rdp.cimg) + { + DrawDepthImage(d); + rdp.update |= UPDATE_ZBUF_ENABLED | UPDATE_COMBINE | + UPDATE_ALPHA_COMPARE | UPDATE_VIEWPORT; + return; + } + } + + if ((settings.hacks&hack_PPL) > 0) + { + if (d.imageY > d.imageH) + d.imageY = (d.imageY%d.imageH); + } + else if ((settings.hacks&hack_Starcraft) > 0) + { + if (d.imageH%2 == 1) + d.imageH -= 1; + } + else + { + if ( (d.frameX > 0) && (d.frameW == rdp.ci_width) ) + d.frameW -= (wxUint16)(2.0f*d.frameX); + if ( (d.frameY > 0) && (d.frameH == rdp.ci_height) ) + d.frameH -= (wxUint16)(2.0f*d.frameY); + } + + int ul_u = (int)d.imageX; + int ul_v = (int)d.imageY; + int lr_u = (int)d.imageX + (int)(d.frameW * d.scaleX); + int lr_v = (int)d.imageY + (int)(d.frameH * d.scaleY); + + float ul_x, ul_y, lr_x, lr_y; + if (d.flipX) + { + ul_x = d.frameX + d.frameW; + lr_x = d.frameX; + } + else + { + ul_x = d.frameX; + lr_x = d.frameX + d.frameW; + } + if (d.flipY) + { + ul_y = d.frameY + d.frameH; + lr_y = d.frameY; + } + else + { + ul_y = d.frameY; + lr_y = d.frameY + d.frameH; + } + + int min_wrap_u = ul_u / d.imageW; + //int max_wrap_u = lr_u / d.wrapW; + int min_wrap_v = ul_v / d.imageH; + //int max_wrap_v = lr_v / d.wrapH; + int min_256_u = ul_u >> x_shift; + //int max_256_u = (lr_u-1) >> x_shift; + int min_256_v = ul_v >> y_shift; + //int max_256_v = (lr_v-1) >> y_shift; + + + // SetTextureImage () + rdp.timg.format = d.imageFmt; // RGBA + rdp.timg.size = d.imageSiz; // 16-bit + rdp.timg.addr = d.imagePtr; + rdp.timg.width = (d.imageW%2)?d.imageW-1:d.imageW; + rdp.timg.set_by = 0; + + // SetTile () + TILE *tile = &rdp.tiles[0]; + tile->format = d.imageFmt; // RGBA + tile->size = d.imageSiz; // 16-bit + tile->line = line; + tile->t_mem = 0; + tile->palette = (wxUint8)d.imagePal; + tile->clamp_t = 1; + tile->mirror_t = 0; + tile->mask_t = 0; + tile->shift_t = 0; + tile->clamp_s = 1; + tile->mirror_s = 0; + tile->mask_s = 0; + tile->shift_s = 0; + + rdp.tiles[0].ul_s = 0; + rdp.tiles[0].ul_t = 0; + rdp.tiles[0].lr_s = x_size-1; + rdp.tiles[0].lr_t = y_size-1; + + const float Z = set_sprite_combine_mode (); + if (rdp.cycle_mode == 2) + rdp.allow_combine = 0; + + if (fullscreen) + { + if (rdp.ci_width == 512 && !no_dlist) + grClipWindow (0, 0, settings.scr_res_x, settings.scr_res_y); + else if (d.scaleX == 1.0f && d.scaleY == 1.0f) + grClipWindow (rdp.scissor.ul_x, rdp.scissor.ul_y, rdp.scissor.lr_x, rdp.scissor.lr_y); + else + grClipWindow (rdp.scissor.ul_x, rdp.scissor.ul_y, min(rdp.scissor.lr_x, (wxUint32)((d.frameX+d.imageW/d.scaleX+0.5f)*rdp.scale_x)), min(rdp.scissor.lr_y, (wxUint32)((d.frameY+d.imageH/d.scaleY+0.5f)*rdp.scale_y))); + rdp.update |= UPDATE_SCISSOR; + } + + // Texture () + rdp.cur_tile = 0; + + float nul_x, nul_y, nlr_x, nlr_y; + int nul_u, nul_v, nlr_u, nlr_v; + float ful_u, ful_v, flr_u, flr_v; + float ful_x, ful_y, flr_x, flr_y; + + float mx = (float)(lr_x - ul_x) / (float)(lr_u - ul_u); + float bx = ul_x - mx * ul_u; + + float my = (float)(lr_y - ul_y) / (float)(lr_v - ul_v); + float by = ul_y - my * ul_v; + + int cur_wrap_u, cur_wrap_v, cur_u, cur_v; + int cb_u, cb_v; // coordinate-base + int tb_u, tb_v; // texture-base + + nul_v = ul_v; + nul_y = ul_y; + + // #162 + + cur_wrap_v = min_wrap_v + 1; + cur_v = min_256_v + 1; + cb_v = ((cur_v-1)<= d.imageH) cb_v -= d.imageH; + tb_v = cb_v; + rdp.bg_image_height = d.imageH; + + while (1) + { + cur_wrap_u = min_wrap_u + 1; + cur_u = min_256_u + 1; + + // calculate intersection with this point + nlr_v = min (min (cur_wrap_v*d.imageH, (cur_v<= d.imageW) cb_u -= d.imageW; + tb_u = cb_u; + + while (1) + { + // calculate intersection with this point + nlr_u = min (min (cur_wrap_u*d.imageW, (cur_u<c_scl_x; + ful_v *= rdp.cur_cache[0]->c_scl_y; + flr_u *= rdp.cur_cache[0]->c_scl_x; + flr_v *= rdp.cur_cache[0]->c_scl_y; + + ful_x = nul_x * rdp.scale_x + rdp.offset_x; + flr_x = nlr_x * rdp.scale_x + rdp.offset_x; + ful_y = nul_y * rdp.scale_y + rdp.offset_y; + flr_y = nlr_y * rdp.scale_y + rdp.offset_y; + + // Make the vertices + + if ((flr_x <= rdp.scissor.lr_x) || (ful_x < rdp.scissor.lr_x)) + { + VERTEX v[4] = { + { ful_x, ful_y, Z, 1.0f, ful_u, ful_v }, + { flr_x, ful_y, Z, 1.0f, flr_u, ful_v }, + { ful_x, flr_y, Z, 1.0f, ful_u, flr_v }, + { flr_x, flr_y, Z, 1.0f, flr_u, flr_v } }; + AllowShadeMods (v, 4); + for (int s = 0; s < 4; s++) + apply_shade_mods (&(v[s])); + ConvertCoordsConvert (v, 4); + + if (fullscreen) + grDrawVertexArrayContiguous (GR_TRIANGLE_STRIP, 4, v, sizeof(VERTEX)); + + if (_debugger.capture) + { + VERTEX vl[3]; + vl[0] = v[0]; + vl[1] = v[2]; + vl[2] = v[1]; + add_tri (vl, 3, TRI_BACKGROUND); + rdp.tri_n ++; + vl[0] = v[2]; + vl[1] = v[3]; + vl[2] = v[1]; + add_tri (vl, 3, TRI_BACKGROUND); + rdp.tri_n ++; + } + else + rdp.tri_n += 2; + } + else + { + rdp.tri_n += 2; + LRDP("Clipped!\n"); + } + + // increment whatever caused this split + tb_u += x_size - (x_size-(nlr_u-cb_u)); + cb_u = nlr_u; + if (nlr_u == cur_wrap_u*d.imageW) { + cur_wrap_u ++; + tb_u = 0; + } + if (nlr_u == (cur_u<info.format); + + setTBufTex(rdp.tbuff_tex->t_mem, rdp.tbuff_tex->width << rdp.tbuff_tex->size >> 1); + + const float Z = set_sprite_combine_mode (); + grClipWindow (0, 0, settings.res_x, settings.res_y); + + if (d.imageW%2 == 1) d.imageW -= 1; + if (d.imageH%2 == 1) d.imageH -= 1; + if (d.imageY > d.imageH) d.imageY = (d.imageY%d.imageH); + + if (!(settings.hacks&hack_PPL)) + { + if ( (d.frameX > 0) && (d.frameW == rdp.ci_width) ) + d.frameW -= (wxUint16)(2.0f*d.frameX); + if ( (d.frameY > 0) && (d.frameH == rdp.ci_height) ) + d.frameH -= (wxUint16)(2.0f*d.frameY); + } + + float ul_x, ul_y, ul_u, ul_v, lr_x, lr_y, lr_u, lr_v; + if (screensize) + { + ul_x = 0.0f; + ul_y = 0.0f; + ul_u = 0.15f; + ul_v = 0.15f; + lr_x = rdp.tbuff_tex->scr_width; + lr_y = rdp.tbuff_tex->scr_height; + lr_u = rdp.tbuff_tex->lr_u; + lr_v = rdp.tbuff_tex->lr_v; + } + else + { + ul_u = d.imageX; + ul_v = d.imageY; + lr_u = d.imageX + (d.frameW * d.scaleX) ; + lr_v = d.imageY + (d.frameH * d.scaleY) ; + + ul_x = d.frameX; + ul_y = d.frameY; + + lr_x = d.frameX + d.frameW; + lr_y = d.frameY + d.frameH; + ul_x *= rdp.scale_x; + lr_x *= rdp.scale_x; + ul_y *= rdp.scale_y; + lr_y *= rdp.scale_y; + ul_u *= rdp.tbuff_tex->u_scale; + lr_u *= rdp.tbuff_tex->u_scale; + ul_v *= rdp.tbuff_tex->v_scale; + lr_v *= rdp.tbuff_tex->v_scale; + ul_u = max(0.15f, ul_u); + ul_v = max(0.15f, ul_v); + if (lr_x > rdp.scissor.lr_x) lr_x = (float)rdp.scissor.lr_x; + if (lr_y > rdp.scissor.lr_y) lr_y = (float)rdp.scissor.lr_y; + } + // Make the vertices + VERTEX v[4] = { + { ul_x, ul_y, Z, 1.0f, ul_u, ul_v, ul_u, ul_v }, + { lr_x, ul_y, Z, 1.0f, lr_u, ul_v, lr_u, ul_v }, + { ul_x, lr_y, Z, 1.0f, ul_u, lr_v, ul_u, lr_v }, + { lr_x, lr_y, Z, 1.0f, lr_u, lr_v, lr_u, lr_v } }; + ConvertCoordsConvert (v, 4); + AllowShadeMods (v, 4); + AddOffset(v, 4); + for (int s = 0; s < 4; s++) + apply_shade_mods (&(v[s])); + grDrawTriangle (&v[0], &v[2], &v[1]); + grDrawTriangle (&v[2], &v[3], &v[1]); + rdp.update |= UPDATE_ZBUF_ENABLED | UPDATE_COMBINE | UPDATE_TEXTURE | UPDATE_ALPHA_COMPARE | UPDATE_SCISSOR; + if (_debugger.capture) + { + VERTEX vl[3]; + vl[0] = v[0]; + vl[1] = v[2]; + vl[2] = v[1]; + add_tri (vl, 3, TRI_BACKGROUND); + rdp.tri_n ++; + vl[0] = v[2]; + vl[1] = v[3]; + vl[2] = v[1]; + add_tri (vl, 3, TRI_BACKGROUND); + rdp.tri_n ++; + } + else + rdp.tri_n += 2; + rdp.tbuff_tex = tbuff_tex; + +} + +//**************************************************************** + + +struct MAT2D { + float A, B, C, D; + float X, Y; + float BaseScaleX; + float BaseScaleY; +} mat_2d = {1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f}; + +static void uc6_read_background_data (DRAWIMAGE & d, bool bReadScale) +{ + wxUint32 addr = segoffset(rdp.cmd1) >> 1; + + d.imageX = (((wxUint16 *)gfx.RDRAM)[(addr+0)^1] >> 5); // 0 + d.imageW = (((wxUint16 *)gfx.RDRAM)[(addr+1)^1] >> 2); // 1 + d.frameX = ((short*)gfx.RDRAM)[(addr+2)^1] / 4.0f; // 2 + d.frameW = ((wxUint16 *)gfx.RDRAM)[(addr+3)^1] >> 2; // 3 + + d.imageY = (((wxUint16 *)gfx.RDRAM)[(addr+4)^1] >> 5); // 4 + d.imageH = (((wxUint16 *)gfx.RDRAM)[(addr+5)^1] >> 2); // 5 + d.frameY = ((short*)gfx.RDRAM)[(addr+6)^1] / 4.0f; // 6 + d.frameH = ((wxUint16 *)gfx.RDRAM)[(addr+7)^1] >> 2; // 7 + + d.imagePtr = segoffset(((wxUint32*)gfx.RDRAM)[(addr+8)>>1]); // 8,9 + d.imageFmt = ((wxUint8 *)gfx.RDRAM)[(((addr+11)<<1)+0)^3]; // 11 + d.imageSiz = ((wxUint8 *)gfx.RDRAM)[(((addr+11)<<1)+1)^3]; // | + d.imagePal = ((wxUint16 *)gfx.RDRAM)[(addr+12)^1]; // 12 + wxUint16 imageFlip = ((wxUint16 *)gfx.RDRAM)[(addr+13)^1]; // 13; + d.flipX = (wxUint8)imageFlip&0x01; + + if (bReadScale) + { + d.scaleX = ((short *)gfx.RDRAM)[(addr+14)^1] / 1024.0f; // 14 + d.scaleY = ((short *)gfx.RDRAM)[(addr+15)^1] / 1024.0f; // 15 + } + else + d.scaleX = d.scaleY = 1.0f; + + d.flipY = 0; + int imageYorig= ((int *)gfx.RDRAM)[(addr+16)>>1] >> 5; + rdp.last_bg = d.imagePtr; + + FRDP ("imagePtr: %08lx\n", d.imagePtr); + FRDP ("frameX: %f, frameW: %d, frameY: %f, frameH: %d\n", d.frameX, d.frameW, d.frameY, d.frameH); + FRDP ("imageX: %d, imageW: %d, imageY: %d, imageH: %d\n", d.imageX, d.imageW, d.imageY, d.imageH); + FRDP ("imageYorig: %d, scaleX: %f, scaleY: %f\n", imageYorig, d.scaleX, d.scaleY); + FRDP ("imageFmt: %d, imageSiz: %d, imagePal: %d, imageFlip: %d\n", d.imageFmt, d.imageSiz, d.imagePal, d.flipX); +} + +static void uc6_bg (bool bg_1cyc) +{ + static const char *strFuncNames[] = {"uc6:bg_1cyc", "uc6:bg_copy"}; + const char *strFuncName = bg_1cyc ? strFuncNames[0] : strFuncNames[1]; + if (rdp.skip_drawing) + { + FRDP("%s skipped\n", strFuncName); + return; + } + FRDP ("%s #%d, #%d\n", strFuncName, rdp.tri_n, rdp.tri_n+1); + + DRAWIMAGE d; + uc6_read_background_data(d, bg_1cyc); + + if (fb_hwfbe_enabled && FindTextureBuffer(d.imagePtr, d.imageW)) + { + DrawHiresImage(d); + return; + } + + if (settings.ucode == ucode_F3DEX2 || (settings.hacks&hack_PPL)) + { + if ( (d.imagePtr != rdp.cimg) && (d.imagePtr != rdp.ocimg) && d.imagePtr) //can't draw from framebuffer + DrawImage (d); + else + { + FRDP("%s skipped\n", strFuncName); + } + } + else + { + DrawImage (d); + } +} + +static void uc6_bg_1cyc () +{ + uc6_bg(true); +} + +static void uc6_bg_copy () +{ + uc6_bg(false); +} + +static void draw_split_triangle(VERTEX **vtx) +{ + vtx[0]->not_zclipped = vtx[1]->not_zclipped = vtx[2]->not_zclipped = 1; + + int index,i,j, min_256,max_256, cur_256,left_256,right_256; + float percent; + + min_256 = min((int)vtx[0]->u0,(int)vtx[1]->u0); // bah, don't put two mins on one line + min_256 = min(min_256,(int)vtx[2]->u0) >> 8; // or it will be calculated twice + + max_256 = max((int)vtx[0]->u0,(int)vtx[1]->u0); // not like it makes much difference + max_256 = max(max_256,(int)vtx[2]->u0) >> 8; // anyway :P + + for (cur_256=min_256; cur_256<=max_256; cur_256++) + { + left_256 = cur_256 << 8; + right_256 = (cur_256+1) << 8; + + // Set vertex buffers + rdp.vtxbuf = rdp.vtx1; // copy from v to rdp.vtx1 + rdp.vtxbuf2 = rdp.vtx2; + rdp.vtx_buffer = 0; + rdp.n_global = 3; + index = 0; + + // ** Left plane ** + for (i=0; i<3; i++) + { + j = i+1; + if (j == 3) j = 0; + + VERTEX *v1 = vtx[i]; + VERTEX *v2 = vtx[j]; + + if (v1->u0 >= left_256) + { + if (v2->u0 >= left_256) // Both are in, save the last one + { + rdp.vtxbuf[index] = *v2; + rdp.vtxbuf[index].u0 -= left_256; + rdp.vtxbuf[index++].v0 += rdp.cur_cache[0]->c_scl_y * (cur_256 * rdp.cur_cache[0]->splitheight); + } + else // First is in, second is out, save intersection + { + percent = (left_256 - v1->u0) / (v2->u0 - v1->u0); + rdp.vtxbuf[index].x = v1->x + (v2->x - v1->x) * percent; + rdp.vtxbuf[index].y = v1->y + (v2->y - v1->y) * percent; + rdp.vtxbuf[index].z = 1; + rdp.vtxbuf[index].q = 1; + rdp.vtxbuf[index].u0 = 0.5f; + rdp.vtxbuf[index].v0 = v1->v0 + (v2->v0 - v1->v0) * percent + + rdp.cur_cache[0]->c_scl_y * cur_256 * rdp.cur_cache[0]->splitheight; + rdp.vtxbuf[index].b = (wxUint8)(v1->b + (v2->b - v1->b) * percent); + rdp.vtxbuf[index].g = (wxUint8)(v1->g + (v2->g - v1->g) * percent); + rdp.vtxbuf[index].r = (wxUint8)(v1->r + (v2->r - v1->r) * percent); + rdp.vtxbuf[index++].a = (wxUint8)(v1->a + (v2->a - v1->a) * percent); + } + } + else + { + //if (v2->u0 < left_256) // Both are out, save nothing + if (v2->u0 >= left_256) // First is out, second is in, save intersection & in point + { + percent = (left_256 - v2->u0) / (v1->u0 - v2->u0); + rdp.vtxbuf[index].x = v2->x + (v1->x - v2->x) * percent; + rdp.vtxbuf[index].y = v2->y + (v1->y - v2->y) * percent; + rdp.vtxbuf[index].z = 1; + rdp.vtxbuf[index].q = 1; + rdp.vtxbuf[index].u0 = 0.5f; + rdp.vtxbuf[index].v0 = v2->v0 + (v1->v0 - v2->v0) * percent + + rdp.cur_cache[0]->c_scl_y * cur_256 * rdp.cur_cache[0]->splitheight; + rdp.vtxbuf[index].b = (wxUint8)(v2->b + (v1->b - v2->b) * percent); + rdp.vtxbuf[index].g = (wxUint8)(v2->g + (v1->g - v2->g) * percent); + rdp.vtxbuf[index].r = (wxUint8)(v2->r + (v1->r - v2->r) * percent); + rdp.vtxbuf[index++].a = (wxUint8)(v2->a + (v1->a - v2->a) * percent); + + // Save the in point + rdp.vtxbuf[index] = *v2; + rdp.vtxbuf[index].u0 -= left_256; + rdp.vtxbuf[index++].v0 += rdp.cur_cache[0]->c_scl_y * (cur_256 * rdp.cur_cache[0]->splitheight); + } + } + } + rdp.n_global = index; + + rdp.vtxbuf = rdp.vtx2; // now vtx1 holds the value, & vtx2 is the destination + rdp.vtxbuf2 = rdp.vtx1; + rdp.vtx_buffer ^= 1; + index = 0; + + for (i=0; iu0 <= 256.0f) + { + if (v2->u0 <= 256.0f) // Both are in, save the last one + { + rdp.vtxbuf[index++] = *v2; + } + else // First is in, second is out, save intersection + { + percent = (right_256 - v1->u0) / (v2->u0 - v1->u0); + rdp.vtxbuf[index].x = v1->x + (v2->x - v1->x) * percent; + rdp.vtxbuf[index].y = v1->y + (v2->y - v1->y) * percent; + rdp.vtxbuf[index].z = 1; + rdp.vtxbuf[index].q = 1; + rdp.vtxbuf[index].u0 = 255.5f; + rdp.vtxbuf[index].v0 = v1->v0 + (v2->v0 - v1->v0) * percent; + rdp.vtxbuf[index].b = (wxUint8)(v1->b + (v2->b - v1->b) * percent); + rdp.vtxbuf[index].g = (wxUint8)(v1->g + (v2->g - v1->g) * percent); + rdp.vtxbuf[index].r = (wxUint8)(v1->r + (v2->r - v1->r) * percent); + rdp.vtxbuf[index++].a = (wxUint8)(v1->a + (v2->a - v1->a) * percent); + } + } + else + { + //if (v2->u0 > 256.0f) // Both are out, save nothing + if (v2->u0 <= 256.0f) // First is out, second is in, save intersection & in point + { + percent = (right_256 - v2->u0) / (v1->u0 - v2->u0); + rdp.vtxbuf[index].x = v2->x + (v1->x - v2->x) * percent; + rdp.vtxbuf[index].y = v2->y + (v1->y - v2->y) * percent; + rdp.vtxbuf[index].z = 1; + rdp.vtxbuf[index].q = 1; + rdp.vtxbuf[index].u0 = 255.5f; + rdp.vtxbuf[index].v0 = v2->v0 + (v1->v0 - v2->v0) * percent; + rdp.vtxbuf[index].b = (wxUint8)(v2->b + (v1->b - v2->b) * percent); + rdp.vtxbuf[index].g = (wxUint8)(v2->g + (v1->g - v2->g) * percent); + rdp.vtxbuf[index].r = (wxUint8)(v2->r + (v1->r - v2->r) * percent); + rdp.vtxbuf[index++].a = (wxUint8)(v2->a + (v1->a - v2->a) * percent); + + // Save the in point + rdp.vtxbuf[index++] = *v2; + } + } + } + rdp.n_global = index; + + do_triangle_stuff_2 (); + } +} + +static void uc6_draw_polygons (VERTEX v[4]) +{ + AllowShadeMods (v, 4); + for (int s = 0; s < 4; s++) + apply_shade_mods (&(v[s])); + AddOffset(v, 4); + + // Set vertex buffers + if (rdp.cur_cache[0] && rdp.cur_cache[0]->splits > 1) + { + VERTEX *vptr[3]; + int i; + for (i = 0; i < 3; i++) + vptr[i] = &v[i]; + draw_split_triangle(vptr); + + rdp.tri_n ++; + for (i = 0; i < 3; i++) + vptr[i] = &v[i+1]; + draw_split_triangle(vptr); + rdp.tri_n ++; + } + else + { + rdp.vtxbuf = rdp.vtx1; // copy from v to rdp.vtx1 + rdp.vtxbuf2 = rdp.vtx2; + rdp.vtx_buffer = 0; + rdp.n_global = 3; + memcpy (rdp.vtxbuf, v, sizeof(VERTEX)*3); + do_triangle_stuff_2 (); + rdp.tri_n ++; + + rdp.vtxbuf = rdp.vtx1; // copy from v to rdp.vtx1 + rdp.vtxbuf2 = rdp.vtx2; + rdp.vtx_buffer = 0; + rdp.n_global = 3; + memcpy (rdp.vtxbuf, v+1, sizeof(VERTEX)*3); + do_triangle_stuff_2 (); + rdp.tri_n ++; + } + rdp.update |= UPDATE_ZBUF_ENABLED | UPDATE_VIEWPORT; + + if (fullscreen && settings.fog && (rdp.flags & FOG_ENABLED)) + { + grFogMode (GR_FOG_WITH_TABLE_ON_FOGCOORD_EXT); + } +} + +static void uc6_read_object_data (DRAWOBJECT & d) +{ + wxUint32 addr = segoffset(rdp.cmd1) >> 1; + + d.objX = ((short*)gfx.RDRAM)[(addr+0)^1] / 4.0f; // 0 + d.scaleW = ((wxUint16 *)gfx.RDRAM)[(addr+1)^1] / 1024.0f; // 1 + d.imageW = ((short*)gfx.RDRAM)[(addr+2)^1] >> 5; // 2, 3 is padding + d.objY = ((short*)gfx.RDRAM)[(addr+4)^1] / 4.0f; // 4 + d.scaleH = ((wxUint16 *)gfx.RDRAM)[(addr+5)^1] / 1024.0f; // 5 + d.imageH = ((short*)gfx.RDRAM)[(addr+6)^1] >> 5; // 6, 7 is padding + + d.imageStride = ((wxUint16 *)gfx.RDRAM)[(addr+8)^1]; // 8 + d.imageAdrs = ((wxUint16 *)gfx.RDRAM)[(addr+9)^1]; // 9 + d.imageFmt = ((wxUint8 *)gfx.RDRAM)[(((addr+10)<<1)+0)^3]; // 10 + d.imageSiz = ((wxUint8 *)gfx.RDRAM)[(((addr+10)<<1)+1)^3]; // | + d.imagePal = ((wxUint8 *)gfx.RDRAM)[(((addr+10)<<1)+2)^3]; // 11 + d.imageFlags = ((wxUint8 *)gfx.RDRAM)[(((addr+10)<<1)+3)^3]; // | + + if (d.imageW < 0) + d.imageW = (short)rdp.scissor_o.lr_x - (short)d.objX - d.imageW; + if (d.imageH < 0) + d.imageH = (short)rdp.scissor_o.lr_y - (short)d.objY - d.imageH; + + FRDP ("#%d, #%d\n" + "objX: %f, scaleW: %f, imageW: %d\n" + "objY: %f, scaleH: %f, imageH: %d\n" + "size: %d, format: %d\n", rdp.tri_n, rdp.tri_n+1, + d.objX, d.scaleW, d.imageW, d.objY, d.scaleH, d.imageH, d.imageSiz, d.imageFmt); +} + +static void uc6_init_tile(const DRAWOBJECT & d) +{ + // SetTile () + TILE *tile = &rdp.tiles[0]; + tile->format = d.imageFmt; // RGBA + tile->size = d.imageSiz; // 16-bit + tile->line = d.imageStride; + tile->t_mem = d.imageAdrs; + tile->palette = d.imagePal; + tile->clamp_t = 1; + tile->mirror_t = 0; + tile->mask_t = 0; + tile->shift_t = 0; + tile->clamp_s = 1; + tile->mirror_s = 0; + tile->mask_s = 0; + tile->shift_s = 0; + + // SetTileSize () + rdp.tiles[0].ul_s = 0; + rdp.tiles[0].ul_t = 0; + rdp.tiles[0].lr_s = (d.imageW>0)?d.imageW-1:0; + rdp.tiles[0].lr_t = (d.imageH>0)?d.imageH-1:0; +} + +static void uc6_obj_rectangle () +{ + LRDP ("uc6:obj_rectangle "); + DRAWOBJECT d; + uc6_read_object_data(d); + + if (d.imageAdrs > 4096) + { + FRDP("tmem: %08lx is out of bounds! return\n", d.imageAdrs); + return; + } + if (!rdp.s2dex_tex_loaded) + { + LRDP("Texture was not loaded! return\n"); + return; + } + + uc6_init_tile(d); + + float Z = set_sprite_combine_mode (); + + float ul_x = d.objX; + float lr_x = d.objX + d.imageW/d.scaleW; + float ul_y = d.objY; + float lr_y = d.objY + d.imageH/d.scaleH; + float ul_u, lr_u, ul_v, lr_v; + if (rdp.cur_cache[0]->splits > 1) + { + lr_u = (float)(d.imageW-1); + lr_v = (float)(d.imageH-1); + } + else + { + lr_u = 255.0f*rdp.cur_cache[0]->scale_x; + lr_v = 255.0f*rdp.cur_cache[0]->scale_y; + } + + if (d.imageFlags&0x01) //flipS + { + ul_u = lr_u; + lr_u = 0.5f; + } + else + ul_u = 0.5f; + if (d.imageFlags&0x10) //flipT + { + ul_v = lr_v; + lr_v = 0.5f; + } + else + ul_v = 0.5f; + + // Make the vertices + VERTEX v[4] = { + { ul_x, ul_y, Z, 1, ul_u, ul_v }, + { lr_x, ul_y, Z, 1, lr_u, ul_v }, + { ul_x, lr_y, Z, 1, ul_u, lr_v }, + { lr_x, lr_y, Z, 1, lr_u, lr_v } + }; + + for (int i=0; i<4; i++) + { + v[i].x *= rdp.scale_x; + v[i].y *= rdp.scale_y; + } + + uc6_draw_polygons (v); +} + +static void uc6_obj_sprite () +{ + LRDP ("uc6:obj_sprite "); + DRAWOBJECT d; + uc6_read_object_data(d); + uc6_init_tile(d); + + float Z = set_sprite_combine_mode (); + + float ul_x = d.objX; + float lr_x = d.objX + d.imageW/d.scaleW; + float ul_y = d.objY; + float lr_y = d.objY + d.imageH/d.scaleH; + float ul_u, lr_u, ul_v, lr_v; + if (rdp.cur_cache[0]->splits > 1) + { + lr_u = (float)(d.imageW-1); + lr_v = (float)(d.imageH-1); + } + else + { + lr_u = 255.0f*rdp.cur_cache[0]->scale_x; + lr_v = 255.0f*rdp.cur_cache[0]->scale_y; + } + + if (d.imageFlags&0x01) //flipS + { + ul_u = lr_u; + lr_u = 0.5f; + } + else + ul_u = 0.5f; + if (d.imageFlags&0x10) //flipT + { + ul_v = lr_v; + lr_v = 0.5f; + } + else + ul_v = 0.5f; + + // Make the vertices + // FRDP("scale_x: %f, scale_y: %f\n", rdp.cur_cache[0]->scale_x, rdp.cur_cache[0]->scale_y); + + VERTEX v[4] = { + { ul_x, ul_y, Z, 1, ul_u, ul_v }, + { lr_x, ul_y, Z, 1, lr_u, ul_v }, + { ul_x, lr_y, Z, 1, ul_u, lr_v }, + { lr_x, lr_y, Z, 1, lr_u, lr_v } + }; + + for (int i=0; i<4; i++) + { + float x = v[i].x; + float y = v[i].y; + v[i].x = (x * mat_2d.A + y * mat_2d.B + mat_2d.X) * rdp.scale_x; + v[i].y = (x * mat_2d.C + y * mat_2d.D + mat_2d.Y) * rdp.scale_y; + } + + uc6_draw_polygons (v); +} + +static void uc6_obj_movemem () +{ + LRDP("uc6:obj_movemem\n"); + + int index = rdp.cmd0 & 0xFFFF; + wxUint32 addr = segoffset(rdp.cmd1) >> 1; + + if (index == 0) { // movemem matrix + mat_2d.A = ((int*)gfx.RDRAM)[(addr+0)>>1] / 65536.0f; + mat_2d.B = ((int*)gfx.RDRAM)[(addr+2)>>1] / 65536.0f; + mat_2d.C = ((int*)gfx.RDRAM)[(addr+4)>>1] / 65536.0f; + mat_2d.D = ((int*)gfx.RDRAM)[(addr+6)>>1] / 65536.0f; + mat_2d.X = ((short*)gfx.RDRAM)[(addr+8)^1] / 4.0f; + mat_2d.Y = ((short*)gfx.RDRAM)[(addr+9)^1] / 4.0f; + mat_2d.BaseScaleX = ((wxUint16*)gfx.RDRAM)[(addr+10)^1] / 1024.0f; + mat_2d.BaseScaleY = ((wxUint16*)gfx.RDRAM)[(addr+11)^1] / 1024.0f; + + FRDP ("mat_2d\nA: %f, B: %f, c: %f, D: %f\nX: %f, Y: %f\nBaseScaleX: %f, BaseScaleY: %f\n", + mat_2d.A, mat_2d.B, mat_2d.C, mat_2d.D, mat_2d.X, mat_2d.Y, mat_2d.BaseScaleX, mat_2d.BaseScaleY); + } + else if (index == 2) { // movemem submatrix + mat_2d.X = ((short*)gfx.RDRAM)[(addr+0)^1] / 4.0f; + mat_2d.Y = ((short*)gfx.RDRAM)[(addr+1)^1] / 4.0f; + mat_2d.BaseScaleX = ((wxUint16*)gfx.RDRAM)[(addr+2)^1] / 1024.0f; + mat_2d.BaseScaleY = ((wxUint16*)gfx.RDRAM)[(addr+3)^1] / 1024.0f; + + FRDP ("submatrix\nX: %f, Y: %f\nBaseScaleX: %f, BaseScaleY: %f\n", + mat_2d.X, mat_2d.Y, mat_2d.BaseScaleX, mat_2d.BaseScaleY); + } +} + +static void uc6_select_dl () +{ + LRDP("uc6:select_dl\n"); + RDP_E ("uc6:select_dl\n"); +} + +static void uc6_obj_rendermode () +{ + LRDP("uc6:obj_rendermode\n"); + RDP_E ("uc6:obj_rendermode\n"); +} + +static wxUint16 uc6_yuv_to_rgba(wxUint8 y, wxUint8 u, wxUint8 v) +{ + float r = y + (1.370705f * (v-128)); + float g = y - (0.698001f * (v-128)) - (0.337633f * (u-128)); + float b = y + (1.732446f * (u-128)); + r *= 0.125f; + g *= 0.125f; + b *= 0.125f; + //clipping the result + if (r > 32) r = 32; + if (g > 32) g = 32; + if (b > 32) b = 32; + if (r < 0) r = 0; + if (g < 0) g = 0; + if (b < 0) b = 0; + + wxUint16 c = (wxUint16)(((wxUint16)(r) << 11) | + ((wxUint16)(g) << 6) | + ((wxUint16)(b) << 1) | 1); + return c; +} + +static void uc6_DrawYUVImageToFrameBuffer(wxUint16 ul_x, wxUint16 ul_y, wxUint16 lr_x, wxUint16 lr_y) +{ + FRDP ("uc6:DrawYUVImageToFrameBuffer ul_x%d, ul_y%d, lr_x%d, lr_y%d\n", ul_x, ul_y, lr_x, lr_y); + wxUint32 ci_width = rdp.ci_width; + wxUint32 ci_height = rdp.ci_lower_bound; + if (ul_x >= ci_width) + return; + if (ul_y >= ci_height) + return; + wxUint32 width = 16, height = 16; + if (lr_x > ci_width) + width = ci_width - ul_x; + if (lr_y > ci_height) + height = ci_height - ul_y; + wxUint32 * mb = (wxUint32*)(gfx.RDRAM+rdp.timg.addr); //pointer to the first macro block + wxUint16 * dst = (wxUint16*)(gfx.RDRAM+rdp.cimg); + dst += ul_x + ul_y * ci_width; + //yuv macro block contains 16x16 texture. we need to put it in the proper place inside cimg + for (wxUint16 h = 0; h < 16; h++) + { + for (wxUint16 w = 0; w < 16; w+=2) + { + wxUint32 t = *(mb++); //each wxUint32 contains 2 pixels + if ((h < height) && (w < width)) //clipping. texture image may be larger than color image + { + wxUint8 y0 = (wxUint8)t&0xFF; + wxUint8 v = (wxUint8)(t>>8)&0xFF; + wxUint8 y1 = (wxUint8)(t>>16)&0xFF; + wxUint8 u = (wxUint8)(t>>24)&0xFF; + *(dst++) = uc6_yuv_to_rgba(y0, u, v); + *(dst++) = uc6_yuv_to_rgba(y1, u, v); + } + } + dst += rdp.ci_width - 16; + } +} + +static void uc6_obj_rectangle_r () +{ + LRDP ("uc6:obj_rectangle_r "); + DRAWOBJECT d; + uc6_read_object_data(d); + + if (d.imageFmt == 1 && (settings.hacks&hack_Ogre64)) //Ogre Battle needs to copy YUV texture to frame buffer + { + float ul_x = d.objX/mat_2d.BaseScaleX + mat_2d.X; + float lr_x = (d.objX + d.imageW/d.scaleW)/mat_2d.BaseScaleX + mat_2d.X; + float ul_y = d.objY/mat_2d.BaseScaleY + mat_2d.Y; + float lr_y = (d.objY + d.imageH/d.scaleH)/mat_2d.BaseScaleY + mat_2d.Y; + uc6_DrawYUVImageToFrameBuffer((wxUint16)ul_x, (wxUint16)ul_y, (wxUint16)lr_x, (wxUint16)lr_y); + rdp.tri_n += 2; + return; + } + + uc6_init_tile(d); + + float Z = set_sprite_combine_mode (); + + float ul_x = d.objX/mat_2d.BaseScaleX; + float lr_x = (d.objX + d.imageW/d.scaleW)/mat_2d.BaseScaleX; + float ul_y = d.objY/mat_2d.BaseScaleY; + float lr_y = (d.objY + d.imageH/d.scaleH)/mat_2d.BaseScaleY; + float ul_u, lr_u, ul_v, lr_v; + if (rdp.cur_cache[0]->splits > 1) + { + lr_u = (float)(d.imageW-1); + lr_v = (float)(d.imageH-1); + } + else + { + lr_u = 255.0f*rdp.cur_cache[0]->scale_x; + lr_v = 255.0f*rdp.cur_cache[0]->scale_y; + } + + if (d.imageFlags&0x01) //flipS + { + ul_u = lr_u; + lr_u = 0.5f; + } + else + ul_u = 0.5f; + if (d.imageFlags&0x10) //flipT + { + ul_v = lr_v; + lr_v = 0.5f; + } + else + ul_v = 0.5f; + + // Make the vertices + VERTEX v[4] = { + { ul_x, ul_y, Z, 1, ul_u, ul_v }, + { lr_x, ul_y, Z, 1, lr_u, ul_v }, + { ul_x, lr_y, Z, 1, ul_u, lr_v }, + { lr_x, lr_y, Z, 1, lr_u, lr_v } + }; + + for (int i=0; i<4; i++) + { + float x = v[i].x; + float y = v[i].y; + v[i].x = (x + mat_2d.X) * rdp.scale_x; + v[i].y = (y + mat_2d.Y) * rdp.scale_y; + } + + uc6_draw_polygons (v); +} + +static void uc6_obj_loadtxtr () +{ + LRDP("uc6:obj_loadtxtr "); + rdp.s2dex_tex_loaded = TRUE; + rdp.update |= UPDATE_TEXTURE; + + wxUint32 addr = segoffset(rdp.cmd1) >> 1; + wxUint32 type = ((wxUint32*)gfx.RDRAM)[(addr + 0) >> 1]; // 0, 1 + + if (type == 0x00000030) { // TLUT + wxUint32 image = segoffset(((wxUint32*)gfx.RDRAM)[(addr + 2) >> 1]); // 2, 3 + wxUint16 phead = ((wxUint16 *)gfx.RDRAM)[(addr + 4) ^ 1] - 256; // 4 + wxUint16 pnum = ((wxUint16 *)gfx.RDRAM)[(addr + 5) ^ 1] + 1; // 5 + + FRDP ("palette addr: %08lx, start: %d, num: %d\n", image, phead, pnum); + load_palette (image, phead, pnum); + } + else if (type == 0x00001033) { // TxtrBlock + wxUint32 image = segoffset(((wxUint32*)gfx.RDRAM)[(addr + 2) >> 1]); // 2, 3 + wxUint16 tmem = ((wxUint16 *)gfx.RDRAM)[(addr + 4) ^ 1]; // 4 + wxUint16 tsize = ((wxUint16 *)gfx.RDRAM)[(addr + 5) ^ 1]; // 5 + wxUint16 tline = ((wxUint16 *)gfx.RDRAM)[(addr + 6) ^ 1]; // 6 + + FRDP ("addr: %08lx, tmem: %08lx, size: %d\n", image, tmem, tsize); + rdp.timg.addr = image; + rdp.timg.width = 1; + rdp.timg.size = 1; + + rdp.tiles[7].t_mem = tmem; + rdp.tiles[7].size = 1; + rdp.cmd0 = 0; + rdp.cmd1 = 0x07000000 | (tsize << 14) | tline; + rdp_loadblock (); + } + else if (type == 0x00fc1034) + { + wxUint32 image = segoffset(((wxUint32*)gfx.RDRAM)[(addr + 2) >> 1]); // 2, 3 + wxUint16 tmem = ((wxUint16 *)gfx.RDRAM)[(addr + 4) ^ 1]; // 4 + wxUint16 twidth = ((wxUint16 *)gfx.RDRAM)[(addr + 5) ^ 1]; // 5 + wxUint16 theight = ((wxUint16 *)gfx.RDRAM)[(addr + 6) ^ 1]; // 6 + + FRDP ("tile addr: %08lx, tmem: %08lx, twidth: %d, theight: %d\n", image, tmem, twidth, theight); + + int line = (twidth + 1) >> 2; + + rdp.timg.addr = image; + rdp.timg.width = line << 3; + rdp.timg.size = 1; + + rdp.tiles[7].t_mem = tmem; + rdp.tiles[7].line = line; + rdp.tiles[7].size = 1; + + rdp.cmd0 = 0; + rdp.cmd1 = 0x07000000 | (twidth << 14) | (theight << 2); + + rdp_loadtile (); + } + else + { + FRDP ("UNKNOWN (0x%08lx)\n", type); + FRDP_E ("uc6:obj_loadtxtr UNKNOWN (0x%08lx)\n", type); + } +} + +static void uc6_obj_ldtx_sprite () +{ + LRDP("uc6:obj_ldtx_sprite\n"); + + wxUint32 addr = rdp.cmd1; + uc6_obj_loadtxtr (); + rdp.cmd1 = addr + 24; + uc6_obj_sprite (); +} + +static void uc6_obj_ldtx_rect () +{ + LRDP("uc6:obj_ldtx_rect\n"); + + wxUint32 addr = rdp.cmd1; + uc6_obj_loadtxtr (); + rdp.cmd1 = addr + 24; + uc6_obj_rectangle (); +} + +static void uc6_ldtx_rect_r () +{ + LRDP("uc6:ldtx_rect_r\n"); + + wxUint32 addr = rdp.cmd1; + uc6_obj_loadtxtr (); + rdp.cmd1 = addr + 24; + uc6_obj_rectangle_r (); +} + +static void uc6_loaducode () +{ + LRDP("uc6:load_ucode\n"); + RDP_E ("uc6:load_ucode\n"); + + // copy the microcode data + wxUint32 addr = segoffset(rdp.cmd1); + wxUint32 size = (rdp.cmd0 & 0xFFFF) + 1; + memcpy (microcode, gfx.RDRAM+addr, size); + + microcheck (); +} + +void uc6_sprite2d () +{ + wxUint32 a = rdp.pc[rdp.pc_i] & BMASK; + wxUint32 cmd0 = ((wxUint32*)gfx.RDRAM)[a>>2]; //check next command + if ( (cmd0>>24) != 0xBE ) + return; + + FRDP ("uc6:uc6_sprite2d #%d, #%d\n", rdp.tri_n, rdp.tri_n+1); + wxUint32 addr = segoffset(rdp.cmd1) >> 1; + DRAWIMAGE d; + + d.imagePtr = segoffset(((wxUint32*)gfx.RDRAM)[(addr+0)>>1]); // 0,1 + wxUint16 stride = (((wxUint16 *)gfx.RDRAM)[(addr+4)^1]); // 4 + d.imageW = (((wxUint16 *)gfx.RDRAM)[(addr+5)^1]); // 5 + d.imageH = (((wxUint16 *)gfx.RDRAM)[(addr+6)^1]); // 6 + d.imageFmt = ((wxUint8 *)gfx.RDRAM)[(((addr+7)<<1)+0)^3]; // 7 + d.imageSiz = ((wxUint8 *)gfx.RDRAM)[(((addr+7)<<1)+1)^3]; // | + d.imagePal = 0; + d.imageX = (((wxUint16 *)gfx.RDRAM)[(addr+8)^1]); // 8 + d.imageY = (((wxUint16 *)gfx.RDRAM)[(addr+9)^1]); // 9 + wxUint32 tlut = ((wxUint32*)gfx.RDRAM)[(addr + 2) >> 1]; // 2, 3 + //low-level implementation of sprite2d apparently calls setothermode command to set tlut mode + //However, description of sprite2d microcode just says that + //TlutPointer should be Null when CI images will not be used. + //HLE implementation sets rdp.tlut_mode=2 if TlutPointer is not null, and rdp.tlut_mode=0 otherwise + //Alas, it is not sufficient, since WCW Nitro uses non-Null TlutPointer for rgba textures. + //So, additional check added. + if (tlut) + { + load_palette (segoffset(tlut), 0, 256); + if (d.imageFmt > 0) + rdp.tlut_mode = 2; + else + rdp.tlut_mode = 0; + } + else + { + rdp.tlut_mode = 0; + } + + if (d.imageW == 0) + return;// d.imageW = stride; + + cmd0 = ((wxUint32*)gfx.RDRAM)[a>>2]; //check next command + while (1) + { + if ( (cmd0>>24) == 0xBE ) + { + wxUint32 cmd1 = ((wxUint32*)gfx.RDRAM)[(a>>2)+1]; + rdp.pc[rdp.pc_i] = (a+8) & BMASK; + + d.scaleX = ((cmd1>>16)&0xFFFF)/1024.0f; + d.scaleY = (cmd1&0xFFFF)/1024.0f; + //the code below causes wrong background height in super robot spirit, so it is disabled. + //need to find, for which game this hack was made + //if( (cmd1&0xFFFF) < 0x100 ) + // d.scaleY = d.scaleX; + d.flipX = (wxUint8)((cmd0>>8)&0xFF); + d.flipY = (wxUint8)(cmd0&0xFF); + + a = rdp.pc[rdp.pc_i] & BMASK; + rdp.pc[rdp.pc_i] = (a+8) & BMASK; + cmd0 = ((wxUint32*)gfx.RDRAM)[a>>2]; //check next command + } + if ( (cmd0>>24) == 0xBD ) + { + wxUint32 cmd1 = ((wxUint32*)gfx.RDRAM)[(a>>2)+1]; + + d.frameX = ((short)((cmd1>>16)&0xFFFF)) / 4.0f; + d.frameY = ((short)(cmd1&0xFFFF)) / 4.0f; + d.frameW = (wxUint16) (d.imageW / d.scaleX); + d.frameH = (wxUint16) (d.imageH / d.scaleY); + if (settings.hacks&hack_WCWnitro) + { + int scaleY = (int)d.scaleY; + d.imageH /= scaleY; + d.imageY /= scaleY; + stride *= scaleY; + d.scaleY = 1.0f; + } + FRDP ("imagePtr: %08lx\n", d.imagePtr); + FRDP ("frameX: %f, frameW: %d, frameY: %f, frameH: %d\n", d.frameX, d.frameW, d.frameY, d.frameH); + FRDP ("imageX: %d, imageW: %d, imageY: %d, imageH: %d\n", d.imageX, d.imageW, d.imageY, d.imageH); + FRDP ("imageFmt: %d, imageSiz: %d, imagePal: %d, imageStride: %d\n", d.imageFmt, d.imageSiz, d.imagePal, stride); + FRDP ("scaleX: %f, scaleY: %f\n", d.scaleX, d.scaleY); + } + else + { + return; + } + + const wxUint32 texsize = (d.imageW * d.imageH) << d.imageSiz >> 1; + const wxUint32 maxTexSize = rdp.tlut_mode < 2 ? 4096 : 2048; + + if (texsize > maxTexSize) + { + if (d.scaleX != 1) + d.scaleX *= (float)stride/(float)d.imageW; + d.imageW = stride; + d.imageH += d.imageY; + DrawImage (d); + } + else + { + wxUint16 line = d.imageW; + if (line & 7) line += 8; // round up + line >>= 3; + if (d.imageSiz == 0) + { + if (line%2) + line++; + line >>= 1; + } + else + { + line <<= (d.imageSiz-1); + } + if (line == 0) + line = 1; + + rdp.timg.addr = d.imagePtr; + rdp.timg.width = stride; + rdp.tiles[7].t_mem = 0; + rdp.tiles[7].line = line;//(d.imageW>>3); + rdp.tiles[7].size = d.imageSiz; + rdp.cmd0 = (d.imageX << 14) | (d.imageY << 2); + rdp.cmd1 = 0x07000000 | ((d.imageX+d.imageW-1) << 14) | ((d.imageY+d.imageH-1) << 2); + rdp_loadtile (); + + // SetTile () + TILE *tile = &rdp.tiles[0]; + tile->format = d.imageFmt; + tile->size = d.imageSiz; + tile->line = line;//(d.imageW>>3); + tile->t_mem = 0; + tile->palette = 0; + tile->clamp_t = 1; + tile->mirror_t = 0; + tile->mask_t = 0; + tile->shift_t = 0; + tile->clamp_s = 1; + tile->mirror_s = 0; + tile->mask_s = 0; + tile->shift_s = 0; + + // SetTileSize () + rdp.tiles[0].ul_s = d.imageX; + rdp.tiles[0].ul_t = d.imageY; + rdp.tiles[0].lr_s = d.imageX+d.imageW-1; + rdp.tiles[0].lr_t = d.imageY+d.imageH-1; + + float Z = set_sprite_combine_mode (); + + float ul_x, ul_y, lr_x, lr_y; + if (d.flipX) + { + ul_x = d.frameX + d.frameW; + lr_x = d.frameX; + } + else + { + ul_x = d.frameX; + lr_x = d.frameX + d.frameW; + } + if (d.flipY) + { + ul_y = d.frameY + d.frameH; + lr_y = d.frameY; + } + else + { + ul_y = d.frameY; + lr_y = d.frameY + d.frameH; + } + + float lr_u, lr_v; + if (rdp.cur_cache[0]->splits > 1) + { + lr_u = (float)(d.imageW-1); + lr_v = (float)(d.imageH-1); + } + else + { + lr_u = 255.0f*rdp.cur_cache[0]->scale_x; + lr_v = 255.0f*rdp.cur_cache[0]->scale_y; + } + + // Make the vertices + VERTEX v[4] = { + { ul_x, ul_y, Z, 1, 0.5f, 0.5f }, + { lr_x, ul_y, Z, 1, lr_u, 0.5f }, + { ul_x, lr_y, Z, 1, 0.5f, lr_v }, + { lr_x, lr_y, Z, 1, lr_u, lr_v } }; + + for (int i=0; i<4; i++) + { + v[i].x *= rdp.scale_x; + v[i].y *= rdp.scale_y; + } + + // ConvertCoordsConvert (v, 4); + AllowShadeMods (v, 4); + for (int s = 0; s < 4; s++) + apply_shade_mods (&(v[s])); + AddOffset(v, 4); + + // Set vertex buffers + if (rdp.cur_cache[0]->splits > 1) + { + VERTEX *vptr[3]; + int i; + for (i = 0; i < 3; i++) + vptr[i] = &v[i]; + draw_split_triangle(vptr); + + rdp.tri_n ++; + for (i = 0; i < 3; i++) + vptr[i] = &v[i+1]; + draw_split_triangle(vptr); + rdp.tri_n ++; + } + else + { + rdp.vtxbuf = rdp.vtx1; // copy from v to rdp.vtx1 + rdp.vtxbuf2 = rdp.vtx2; + rdp.vtx_buffer = 0; + rdp.n_global = 3; + memcpy (rdp.vtxbuf, v, sizeof(VERTEX)*3); + do_triangle_stuff_2 (); + rdp.tri_n ++; + + rdp.vtxbuf = rdp.vtx1; // copy from v to rdp.vtx1 + rdp.vtxbuf2 = rdp.vtx2; + rdp.vtx_buffer = 0; + rdp.n_global = 3; + memcpy (rdp.vtxbuf, v+1, sizeof(VERTEX)*3); + do_triangle_stuff_2 (); + rdp.tri_n ++; + } + rdp.update |= UPDATE_ZBUF_ENABLED | UPDATE_VIEWPORT; + + if (fullscreen && settings.fog && (rdp.flags & FOG_ENABLED)) + { + grFogMode (GR_FOG_WITH_TABLE_ON_FOGCOORD_EXT); + } + + } + a = rdp.pc[rdp.pc_i] & BMASK; + cmd0 = ((wxUint32*)gfx.RDRAM)[a>>2]; //check next command + if (( (cmd0>>24) == 0xBD ) || ( (cmd0>>24) == 0xBE )) + rdp.pc[rdp.pc_i] = (a+8) & BMASK; + else + return; + } +} diff --git a/Source/Glide64/ucode07.h b/Source/Glide64/ucode07.h new file mode 100644 index 000000000..8d01b62ab --- /dev/null +++ b/Source/Glide64/ucode07.h @@ -0,0 +1,179 @@ +/* +* Glide64 - Glide video plugin for Nintendo 64 emulators. +* Copyright (c) 2002 Dave2001 +* Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski +* +* 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 +* 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 +*/ + +//**************************************************************** +// +// Glide64 - Glide Plugin for Nintendo 64 emulators +// Project started on December 29th, 2001 +// +// Authors: +// Dave2001, original author, founded the project in 2001, left it in 2002 +// Gugaman, joined the project in 2002, left it in 2002 +// Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002 +// Hiroshi 'KoolSmoky' Morii, joined the project in 2007 +// +//**************************************************************** +// +// To modify Glide64: +// * Write your name and (optional)email, commented by your work, so I know who did it, and so that you can find which parts you modified when it comes time to send it to me. +// * Do NOT send me the whole project or file that you modified. Take out your modified code sections, and tell me where to put them. If people sent the whole thing, I would have many different versions, but no idea how to combine them all. +// +//**************************************************************** +// +// Oct 2002 Created by Gonetz (Gonetz@ngs.ru) +// Info about this ucode is taken from TR64 OGL plugin. Thanks, Icepir8! +// Oct 2003 Modified by Gonetz (Gonetz@ngs.ru) +// Bugs fixed with help from glN64 sources. Thanks, Orkin! +//**************************************************************** + +wxUint32 pd_col_addr = 0; + +static void uc7_colorbase () +{ + LRDP("uc7_colorbase\n"); + pd_col_addr = segoffset(rdp.cmd1); +} + + +typedef struct +{ + short y; + short x; + wxUint16 idx; + + short z; + + short t; + short s; + +} vtx_uc7; + +static void uc7_vertex () +{ + if (rdp.update & UPDATE_MULT_MAT) + { + rdp.update ^= UPDATE_MULT_MAT; + MulMatrices(rdp.model, rdp.proj, rdp.combined); + } + + // This is special, not handled in update() + if (rdp.update & UPDATE_LIGHTS) + { + rdp.update ^= UPDATE_LIGHTS; + + // Calculate light vectors + for (wxUint32 l=0; l> 16; + rdp.vn = n = ((rdp.cmd0 & 0xF00000) >> 20) + 1; + + FRDP ("uc7:vertex n: %d, v0: %d, from: %08lx\n", n, v0, addr); + + vtx_uc7 *vertex = (vtx_uc7 *)&gfx.RDRAM[addr]; + + for(i = 0; i < n; i++) + { + VERTEX *v = &rdp.vtx[v0 + i]; + x = (float)vertex->x; + y = (float)vertex->y; + z = (float)vertex->z; + v->flags = 0; + v->ou = (float)vertex->s; + v->ov = (float)vertex->t; + v->uv_scaled = 0; + +#ifdef EXTREME_LOGGING +// FRDP ("before: v%d - x: %f, y: %f, z: %f, flags: %04lx, ou: %f, ov: %f\n", i>>4, x, y, z, v->flags, v->ou, v->ov); +#endif + + v->x = x*rdp.combined[0][0] + y*rdp.combined[1][0] + z*rdp.combined[2][0] + rdp.combined[3][0]; + v->y = x*rdp.combined[0][1] + y*rdp.combined[1][1] + z*rdp.combined[2][1] + rdp.combined[3][1]; + v->z = x*rdp.combined[0][2] + y*rdp.combined[1][2] + z*rdp.combined[2][2] + rdp.combined[3][2]; + v->w = x*rdp.combined[0][3] + y*rdp.combined[1][3] + z*rdp.combined[2][3] + rdp.combined[3][3]; + + + if (fabs(v->w) < 0.001) v->w = 0.001f; + v->oow = 1.0f / v->w; + v->x_w = v->x * v->oow; + v->y_w = v->y * v->oow; + v->z_w = v->z * v->oow; + + v->uv_calculated = 0xFFFFFFFF; + v->screen_translated = 0; + + v->scr_off = 0; + if (v->x < -v->w) v->scr_off |= 1; + if (v->x > v->w) v->scr_off |= 2; + if (v->y < -v->w) v->scr_off |= 4; + if (v->y > v->w) v->scr_off |= 8; + if (v->w < 0.1f) v->scr_off |= 16; + + wxUint8 *color = &gfx.RDRAM[pd_col_addr + (vertex->idx & 0xff)]; + + v->a = color[0]; + CalculateFog (v); + + if (rdp.geom_mode & 0x00020000) + { + v->vec[0] = (char)color[3]; + v->vec[1] = (char)color[2]; + v->vec[2] = (char)color[1]; + + if (rdp.geom_mode & 0x80000) + { + calc_linear (v); +#ifdef EXTREME_LOGGING + FRDP ("calc linear: v%d - u: %f, v: %f\n", i>>4, v->ou, v->ov); +#endif + } + else if (rdp.geom_mode & 0x40000) + { + calc_sphere (v); +#ifdef EXTREME_LOGGING + FRDP ("calc sphere: v%d - u: %f, v: %f\n", i>>4, v->ou, v->ov); +#endif + } + + NormalizeVector (v->vec); + + calc_light (v); + } + else + { + v->r = color[3]; + v->g = color[2]; + v->b = color[1]; + } +#ifdef EXTREME_LOGGING + FRDP ("v%d - x: %f, y: %f, z: %f, w: %f, u: %f, v: %f\n", i>>4, v->x, v->y, v->z, v->w, v->ou, v->ov); +#endif + vertex++; + } +} + diff --git a/Source/Glide64/ucode08.h b/Source/Glide64/ucode08.h new file mode 100644 index 000000000..c9d86a491 --- /dev/null +++ b/Source/Glide64/ucode08.h @@ -0,0 +1,546 @@ +/* +* Glide64 - Glide video plugin for Nintendo 64 emulators. +* Copyright (c) 2002 Dave2001 +* Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski +* +* 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 +* 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 +*/ + +//**************************************************************** +// +// Glide64 - Glide Plugin for Nintendo 64 emulators +// Project started on December 29th, 2001 +// +// Authors: +// Dave2001, original author, founded the project in 2001, left it in 2002 +// Gugaman, joined the project in 2002, left it in 2002 +// Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002 +// Hiroshi 'KoolSmoky' Morii, joined the project in 2007 +// +//**************************************************************** +// +// To modify Glide64: +// * Write your name and (optional)email, commented by your work, so I know who did it, and so that you can find which parts you modified when it comes time to send it to me. +// * Do NOT send me the whole project or file that you modified. Take out your modified code sections, and tell me where to put them. If people sent the whole thing, I would have many different versions, but no idea how to combine them all. +// +//**************************************************************** +// +// January 2004 Created by Gonetz (Gonetz@ngs.ru) +// +//**************************************************************** + +wxUint32 uc8_normale_addr = 0; +float uc8_coord_mod[16]; + +static void uc8_vertex () +{ + if (rdp.update & UPDATE_MULT_MAT) + { + rdp.update ^= UPDATE_MULT_MAT; + MulMatrices(rdp.model, rdp.proj, rdp.combined); + } + + wxUint32 addr = segoffset(rdp.cmd1); + int v0, i, n; + float x, y, z; + + rdp.vn = n = (rdp.cmd0 >> 12) & 0xFF; + rdp.v0 = v0 = ((rdp.cmd0 >> 1) & 0x7F) - n; + + FRDP ("uc8:vertex n: %d, v0: %d, from: %08lx\n", n, v0, addr); + + if (v0 < 0) + { + RDP_E ("** ERROR: uc2:vertex v0 < 0\n"); + LRDP("** ERROR: uc2:vertex v0 < 0\n"); + return; + } + //* + // This is special, not handled in update() + if (rdp.update & UPDATE_LIGHTS) + { + rdp.update ^= UPDATE_LIGHTS; + + // Calculate light vectors + for (wxUint32 l=0; l>4)]; + x = (float)((short*)gfx.RDRAM)[(((addr+i) >> 1) + 0)^1]; + y = (float)((short*)gfx.RDRAM)[(((addr+i) >> 1) + 1)^1]; + z = (float)((short*)gfx.RDRAM)[(((addr+i) >> 1) + 2)^1]; + v->flags = ((wxUint16*)gfx.RDRAM)[(((addr+i) >> 1) + 3)^1]; + v->ou = (float)((short*)gfx.RDRAM)[(((addr+i) >> 1) + 4)^1]; + v->ov = (float)((short*)gfx.RDRAM)[(((addr+i) >> 1) + 5)^1]; + v->uv_scaled = 0; + v->a = ((wxUint8*)gfx.RDRAM)[(addr+i + 15)^3]; + +#ifdef EXTREME_LOGGING + FRDP ("before v%d - x: %f, y: %f, z: %f\n", i>>4, x, y, z); +#endif + v->x = x*rdp.combined[0][0] + y*rdp.combined[1][0] + z*rdp.combined[2][0] + rdp.combined[3][0]; + v->y = x*rdp.combined[0][1] + y*rdp.combined[1][1] + z*rdp.combined[2][1] + rdp.combined[3][1]; + v->z = x*rdp.combined[0][2] + y*rdp.combined[1][2] + z*rdp.combined[2][2] + rdp.combined[3][2]; + v->w = x*rdp.combined[0][3] + y*rdp.combined[1][3] + z*rdp.combined[2][3] + rdp.combined[3][3]; + +#ifdef EXTREME_LOGGING + FRDP ("v%d - x: %f, y: %f, z: %f, w: %f, u: %f, v: %f, flags: %d\n", i>>4, v->x, v->y, v->z, v->w, v->ou, v->ov, v->flags); +#endif + + if (fabs(v->w) < 0.001) v->w = 0.001f; + v->oow = 1.0f / v->w; + v->x_w = v->x * v->oow; + v->y_w = v->y * v->oow; + v->z_w = v->z * v->oow; + + v->uv_calculated = 0xFFFFFFFF; + v->screen_translated = 0; + v->shade_mod = 0; + + v->scr_off = 0; + if (v->x < -v->w) v->scr_off |= 1; + if (v->x > v->w) v->scr_off |= 2; + if (v->y < -v->w) v->scr_off |= 4; + if (v->y > v->w) v->scr_off |= 8; + if (v->w < 0.1f) v->scr_off |= 16; + ///* + v->r = ((wxUint8*)gfx.RDRAM)[(addr+i + 12)^3]; + v->g = ((wxUint8*)gfx.RDRAM)[(addr+i + 13)^3]; + v->b = ((wxUint8*)gfx.RDRAM)[(addr+i + 14)^3]; +#ifdef EXTREME_LOGGING + FRDP ("r: %02lx, g: %02lx, b: %02lx, a: %02lx\n", v->r, v->g, v->b, v->a); +#endif + + if ((rdp.geom_mode & 0x00020000)) + { + wxUint32 shift = v0 << 1; + v->vec[0] = ((char*)gfx.RDRAM)[(uc8_normale_addr + (i>>3) + shift + 0)^3]; + v->vec[1] = ((char*)gfx.RDRAM)[(uc8_normale_addr + (i>>3) + shift + 1)^3]; + v->vec[2] = (char)(v->flags&0xff); + + if (rdp.geom_mode & 0x80000) + { + calc_linear (v); +#ifdef EXTREME_LOGGING + FRDP ("calc linear: v%d - u: %f, v: %f\n", i>>4, v->ou, v->ov); +#endif + } + else if (rdp.geom_mode & 0x40000) + { + calc_sphere (v); +#ifdef EXTREME_LOGGING + FRDP ("calc sphere: v%d - u: %f, v: %f\n", i>>4, v->ou, v->ov); +#endif + } + // FRDP("calc light. r: 0x%02lx, g: 0x%02lx, b: 0x%02lx, nx: %.3f, ny: %.3f, nz: %.3f\n", v->r, v->g, v->b, v->vec[0], v->vec[1], v->vec[2]); + FRDP("v[%d] calc light. r: 0x%02lx, g: 0x%02lx, b: 0x%02lx\n", i>>4, v->r, v->g, v->b); + float color[3] = {rdp.light[rdp.num_lights].r, rdp.light[rdp.num_lights].g, rdp.light[rdp.num_lights].b}; + FRDP("ambient light. r: %f, g: %f, b: %f\n", color[0], color[1], color[2]); + float light_intensity = 0.0f; + wxUint32 l; + if (rdp.geom_mode & 0x00400000) + { + NormalizeVector (v->vec); + for (l = 0; l < rdp.num_lights-1; l++) + { + if (!rdp.light[l].nonblack) + continue; + light_intensity = DotProduct (rdp.light_vector[l], v->vec); + FRDP("light %d, intensity : %f\n", l, light_intensity); + if (light_intensity < 0.0f) + continue; + //* + if (rdp.light[l].ca > 0.0f) + { + float vx = (v->x + uc8_coord_mod[8])*uc8_coord_mod[12] - rdp.light[l].x; + float vy = (v->y + uc8_coord_mod[9])*uc8_coord_mod[13] - rdp.light[l].y; + float vz = (v->z + uc8_coord_mod[10])*uc8_coord_mod[14] - rdp.light[l].z; + float vw = (v->w + uc8_coord_mod[11])*uc8_coord_mod[15] - rdp.light[l].w; + float len = (vx*vx+vy*vy+vz*vz+vw*vw)/65536.0f; + float p_i = rdp.light[l].ca / len; + if (p_i > 1.0f) p_i = 1.0f; + light_intensity *= p_i; + FRDP("light %d, len: %f, p_intensity : %f\n", l, len, p_i); + } + //*/ + color[0] += rdp.light[l].r * light_intensity; + color[1] += rdp.light[l].g * light_intensity; + color[2] += rdp.light[l].b * light_intensity; + FRDP("light %d r: %f, g: %f, b: %f\n", l, color[0], color[1], color[2]); + } + light_intensity = DotProduct (rdp.light_vector[l], v->vec); + FRDP("light %d, intensity : %f\n", l, light_intensity); + if (light_intensity > 0.0f) + { + color[0] += rdp.light[l].r * light_intensity; + color[1] += rdp.light[l].g * light_intensity; + color[2] += rdp.light[l].b * light_intensity; + } + FRDP("light %d r: %f, g: %f, b: %f\n", l, color[0], color[1], color[2]); + } + else + { + for (l = 0; l < rdp.num_lights; l++) + { + if (rdp.light[l].nonblack && rdp.light[l].nonzero) + { + float vx = (v->x + uc8_coord_mod[8])*uc8_coord_mod[12] - rdp.light[l].x; + float vy = (v->y + uc8_coord_mod[9])*uc8_coord_mod[13] - rdp.light[l].y; + float vz = (v->z + uc8_coord_mod[10])*uc8_coord_mod[14] - rdp.light[l].z; + float vw = (v->w + uc8_coord_mod[11])*uc8_coord_mod[15] - rdp.light[l].w; + float len = (vx*vx+vy*vy+vz*vz+vw*vw)/65536.0f; + light_intensity = rdp.light[l].ca / len; + if (light_intensity > 1.0f) light_intensity = 1.0f; + FRDP("light %d, p_intensity : %f\n", l, light_intensity); + color[0] += rdp.light[l].r * light_intensity; + color[1] += rdp.light[l].g * light_intensity; + color[2] += rdp.light[l].b * light_intensity; + //FRDP("light %d r: %f, g: %f, b: %f\n", l, color[0], color[1], color[2]); + } + } + } + if (color[0] > 1.0f) color[0] = 1.0f; + if (color[1] > 1.0f) color[1] = 1.0f; + if (color[2] > 1.0f) color[2] = 1.0f; + v->r = (wxUint8)(((float)v->r)*color[0]); + v->g = (wxUint8)(((float)v->g)*color[1]); + v->b = (wxUint8)(((float)v->b)*color[2]); +#ifdef EXTREME_LOGGING + FRDP("color after light: r: 0x%02lx, g: 0x%02lx, b: 0x%02lx\n", v->r, v->g, v->b); +#endif + } + } +} + +static void uc8_moveword () +{ + wxUint8 index = (wxUint8)((rdp.cmd0 >> 16) & 0xFF); + wxUint16 offset = (wxUint16)(rdp.cmd0 & 0xFFFF); + wxUint32 data = rdp.cmd1; + + FRDP ("uc8:moveword "); + + switch (index) + { + // NOTE: right now it's assuming that it sets the integer part first. This could + // be easily fixed, but only if i had something to test with. + + case 0x02: + rdp.num_lights = (data / 48); + rdp.update |= UPDATE_LIGHTS; + FRDP ("numlights: %d\n", rdp.num_lights); + break; + + case 0x04: + if (offset == 0x04) + { + rdp.clip_ratio = sqrt((float)rdp.cmd1); + rdp.update |= UPDATE_VIEWPORT; + } + FRDP ("mw_clip %08lx, %08lx\n", rdp.cmd0, rdp.cmd1); + break; + + case 0x06: // moveword SEGMENT + { + FRDP ("SEGMENT %08lx -> seg%d\n", data, offset >> 2); + rdp.segment[(offset >> 2) & 0xF] = data; + } + break; + + case 0x08: + { + rdp.fog_multiplier = (short)(rdp.cmd1 >> 16); + rdp.fog_offset = (short)(rdp.cmd1 & 0x0000FFFF); + FRDP ("fog: multiplier: %f, offset: %f\n", rdp.fog_multiplier, rdp.fog_offset); + } + break; + + case 0x0c: + RDP_E ("uc8:moveword forcemtx - IGNORED\n"); + LRDP("forcemtx - IGNORED\n"); + break; + + case 0x0e: + LRDP("perspnorm - IGNORED\n"); + break; + + case 0x10: // moveword coord mod + { + wxUint8 n = offset >> 2; + + FRDP ("coord mod:%d, %08lx\n", n, data); + if (rdp.cmd0&8) + return; + wxUint32 idx = (rdp.cmd0>>1)&3; + wxUint32 pos = rdp.cmd0&0x30; + if (pos == 0) + { + uc8_coord_mod[0+idx] = (short)(rdp.cmd1>>16); + uc8_coord_mod[1+idx] = (short)(rdp.cmd1&0xffff); + } + else if (pos == 0x10) + { + uc8_coord_mod[4+idx] = (rdp.cmd1>>16)/65536.0f; + uc8_coord_mod[5+idx] = (rdp.cmd1&0xffff)/65536.0f; + uc8_coord_mod[12+idx] = uc8_coord_mod[0+idx] + uc8_coord_mod[4+idx]; + uc8_coord_mod[13+idx] = uc8_coord_mod[1+idx] + uc8_coord_mod[5+idx]; + + } + else if (pos == 0x20) + { + uc8_coord_mod[8+idx] = (short)(rdp.cmd1>>16); + uc8_coord_mod[9+idx] = (short)(rdp.cmd1&0xffff); +#ifdef EXTREME_LOGGING + if (idx) + { + for (int k = 8; k < 16; k++) + { + FRDP("coord_mod[%d]=%f\n", k, uc8_coord_mod[k]); + } + } +#endif + } + + } + break; + + default: + FRDP_E("uc8:moveword unknown (index: 0x%08lx, offset 0x%08lx)\n", index, offset); + FRDP ("unknown (index: 0x%08lx, offset 0x%08lx)\n", index, offset); + } +} + +static void uc8_movemem () +{ + int idx = rdp.cmd0 & 0xFF; + wxUint32 addr = segoffset(rdp.cmd1); + int ofs = (rdp.cmd0 >> 5) & 0x3FFF; + + FRDP ("uc8:movemem ofs:%d ", ofs); + + switch (idx) + { + case 8: // VIEWPORT + { + wxUint32 a = addr >> 1; + short scale_x = ((short*)gfx.RDRAM)[(a+0)^1] >> 2; + short scale_y = ((short*)gfx.RDRAM)[(a+1)^1] >> 2; + short scale_z = ((short*)gfx.RDRAM)[(a+2)^1]; + short trans_x = ((short*)gfx.RDRAM)[(a+4)^1] >> 2; + short trans_y = ((short*)gfx.RDRAM)[(a+5)^1] >> 2; + short trans_z = ((short*)gfx.RDRAM)[(a+6)^1]; + rdp.view_scale[0] = scale_x * rdp.scale_x; + rdp.view_scale[1] = -scale_y * rdp.scale_y; + rdp.view_scale[2] = 32.0f * scale_z; + rdp.view_trans[0] = trans_x * rdp.scale_x; + rdp.view_trans[1] = trans_y * rdp.scale_y; + rdp.view_trans[2] = 32.0f * trans_z; + + rdp.update |= UPDATE_VIEWPORT; + + FRDP ("viewport scale(%d, %d), trans(%d, %d), from:%08lx\n", scale_x, scale_y, + trans_x, trans_y, a); + } + break; + + case 10: // LIGHT + { + int n = (ofs / 48); + if (n < 2) + { + char dir_x = ((char*)gfx.RDRAM)[(addr+8)^3]; + rdp.lookat[n][0] = (float)(dir_x) / 127.0f; + char dir_y = ((char*)gfx.RDRAM)[(addr+9)^3]; + rdp.lookat[n][1] = (float)(dir_y) / 127.0f; + char dir_z = ((char*)gfx.RDRAM)[(addr+10)^3]; + rdp.lookat[n][2] = (float)(dir_z) / 127.0f; + rdp.use_lookat = TRUE; + if (n == 1) + { + if (!dir_x && !dir_y) + rdp.use_lookat = FALSE; + } + FRDP("lookat_%d (%f, %f, %f)\n", n, rdp.lookat[n][0], rdp.lookat[n][1], rdp.lookat[n][2]); + return; + } + n -= 2; + wxUint8 col = gfx.RDRAM[(addr+0)^3]; + rdp.light[n].r = (float)col / 255.0f; + rdp.light[n].nonblack = col; + col = gfx.RDRAM[(addr+1)^3]; + rdp.light[n].g = (float)col / 255.0f; + rdp.light[n].nonblack += col; + col = gfx.RDRAM[(addr+2)^3]; + rdp.light[n].b = (float)col / 255.0f; + rdp.light[n].nonblack += col; + rdp.light[n].a = 1.0f; + rdp.light[n].dir_x = (float)(((char*)gfx.RDRAM)[(addr+8)^3]) / 127.0f; + rdp.light[n].dir_y = (float)(((char*)gfx.RDRAM)[(addr+9)^3]) / 127.0f; + rdp.light[n].dir_z = (float)(((char*)gfx.RDRAM)[(addr+10)^3]) / 127.0f; + // ** + wxUint32 a = addr >> 1; + rdp.light[n].x = (float)(((short*)gfx.RDRAM)[(a+16)^1]); + rdp.light[n].y = (float)(((short*)gfx.RDRAM)[(a+17)^1]); + rdp.light[n].z = (float)(((short*)gfx.RDRAM)[(a+18)^1]); + rdp.light[n].w = (float)(((short*)gfx.RDRAM)[(a+19)^1]); + rdp.light[n].nonzero = gfx.RDRAM[(addr+12)^3]; + rdp.light[n].ca = (float)rdp.light[n].nonzero / 16.0f; + //rdp.light[n].la = rdp.light[n].ca * 1.0f; +#ifdef EXTREME_LOGGING + FRDP ("light: n: %d, pos: x: %f, y: %f, z: %f, w: %f, ca: %f\n", + n, rdp.light[n].x, rdp.light[n].y, rdp.light[n].z, rdp.light[n].w, rdp.light[n].ca); +#endif + FRDP ("light: n: %d, r: %f, g: %f, b: %f. dir: x: %.3f, y: %.3f, z: %.3f\n", + n, rdp.light[n].r, rdp.light[n].g, rdp.light[n].b, + rdp.light[n].dir_x, rdp.light[n].dir_y, rdp.light[n].dir_z); +#ifdef EXTREME_LOGGING + for (int t=0; t < 24; t++) + { + FRDP ("light[%d] = 0x%04lx \n", t, ((wxUint16*)gfx.RDRAM)[(a+t)^1]); + } +#endif + } + break; + + case 14: //Normales + { + uc8_normale_addr = segoffset(rdp.cmd1); + FRDP ("Normale - addr: %08lx\n", uc8_normale_addr); +#ifdef EXTREME_LOGGING + int i; + for (i = 0; i < 32; i++) + { + char x = ((char*)gfx.RDRAM)[uc8_normale_addr + ((i<<1) + 0)^3]; + char y = ((char*)gfx.RDRAM)[uc8_normale_addr + ((i<<1) + 1)^3]; + FRDP("#%d x = %d, y = %d\n", i, x, y); + } + wxUint32 a = uc8_normale_addr >> 1; + for (i = 0; i < 32; i++) + { + FRDP ("n[%d] = 0x%04lx \n", i, ((wxUint16*)gfx.RDRAM)[(a+i)^1]); + } +#endif + } + break; + + default: + FRDP ("uc8:movemem unknown (%d)\n", idx); + } +} + + +static void uc8_tri4() //by Gugaman Apr 19 2002 +{ + if (rdp.skip_drawing) + { + LRDP("uc8:tri4. skipped\n"); + return; + } + + FRDP("uc8:tri4 (#%d - #%d), %d-%d-%d, %d-%d-%d, %d-%d-%d, %d-%d-%d\n", + rdp.tri_n, + rdp.tri_n+3, + ((rdp.cmd0 >> 23) & 0x1F), + ((rdp.cmd0 >> 18) & 0x1F), + ((((rdp.cmd0 >> 15) & 0x7) << 2) | ((rdp.cmd1 >> 30) &0x3)), + ((rdp.cmd0 >> 10) & 0x1F), + ((rdp.cmd0 >> 5) & 0x1F), + ((rdp.cmd0 >> 0) & 0x1F), + ((rdp.cmd1 >> 25) & 0x1F), + ((rdp.cmd1 >> 20) & 0x1F), + ((rdp.cmd1 >> 15) & 0x1F), + ((rdp.cmd1 >> 10) & 0x1F), + ((rdp.cmd1 >> 5) & 0x1F), + ((rdp.cmd1 >> 0) & 0x1F)); + + VERTEX *v[12] = { + &rdp.vtx[(rdp.cmd0 >> 23) & 0x1F], + &rdp.vtx[(rdp.cmd0 >> 18) & 0x1F], + &rdp.vtx[((((rdp.cmd0 >> 15) & 0x7) << 2) | ((rdp.cmd1 >> 30) &0x3))], + &rdp.vtx[(rdp.cmd0 >> 10) & 0x1F], + &rdp.vtx[(rdp.cmd0 >> 5) & 0x1F], + &rdp.vtx[(rdp.cmd0 >> 0) & 0x1F], + &rdp.vtx[(rdp.cmd1 >> 25) & 0x1F], + &rdp.vtx[(rdp.cmd1 >> 20) & 0x1F], + &rdp.vtx[(rdp.cmd1 >> 15) & 0x1F], + &rdp.vtx[(rdp.cmd1 >> 10) & 0x1F], + &rdp.vtx[(rdp.cmd1 >> 5) & 0x1F], + &rdp.vtx[(rdp.cmd1 >> 0) & 0x1F] + }; + + int updated = 0; + + if (cull_tri(v)) + rdp.tri_n ++; + else + { + updated = 1; + update (); + + draw_tri (v); + rdp.tri_n ++; + } + + if (cull_tri(v+3)) + rdp.tri_n ++; + else + { + if (!updated) + { + updated = 1; + update (); + } + + draw_tri (v+3); + rdp.tri_n ++; + } + + if (cull_tri(v+6)) + rdp.tri_n ++; + else + { + if (!updated) + { + updated = 1; + update (); + } + + draw_tri (v+6); + rdp.tri_n ++; + } + + if (cull_tri(v+9)) + rdp.tri_n ++; + else + { + if (!updated) + { + updated = 1; + update (); + } + + draw_tri (v+9); + rdp.tri_n ++; + } +} diff --git a/Source/Glide64/ucode09.h b/Source/Glide64/ucode09.h new file mode 100644 index 000000000..49253f4d3 --- /dev/null +++ b/Source/Glide64/ucode09.h @@ -0,0 +1,687 @@ +/* +* Glide64 - Glide video plugin for Nintendo 64 emulators. +* Copyright (c) 2002 Dave2001 +* Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski +* +* 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 +* 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 +*/ + +//**************************************************************** +// +// Glide64 - Glide Plugin for Nintendo 64 emulators +// Project started on December 29th, 2001 +// +// Authors: +// Dave2001, original author, founded the project in 2001, left it in 2002 +// Gugaman, joined the project in 2002, left it in 2002 +// Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002 +// Hiroshi 'KoolSmoky' Morii, joined the project in 2007 +// +//**************************************************************** +// +// To modify Glide64: +// * Write your name and (optional)email, commented by your work, so I know who did it, and so that you can find which parts you modified when it comes time to send it to me. +// * Do NOT send me the whole project or file that you modified. Take out your modified code sections, and tell me where to put them. If people sent the whole thing, I would have many different versions, but no idea how to combine them all. +// +//**************************************************************** +// +// December 2008 Created by Gonetz (Gonetz@ngs.ru) +// +//**************************************************************** + +void uc9_rpdcmd (); + +typedef float M44[4][4]; + +struct ZSORTRDP { + float view_scale[2]; + float view_trans[2]; + float scale_x; + float scale_y; +} zSortRdp = {{0, 0}, {0, 0}, 0, 0}; + +//RSP command VRCPL +static int Calc_invw (int w) { + int count, neg; + union { + wxInt32 W; + wxUint32 UW; + wxInt16 HW[2]; + wxUint16 UHW[2]; + } Result; + Result.W = w; + if (Result.UW == 0) { + Result.UW = 0x7FFFFFFF; + } else { + if (Result.W < 0) { + neg = TRUE; + if (Result.UHW[1] == 0xFFFF && Result.HW[0] < 0) { + Result.W = ~Result.W + 1; + } else { + Result.W = ~Result.W; + } + } else { + neg = FALSE; + } + for (count = 31; count > 0; count--) { + if ((Result.W & (1 << count))) { + Result.W &= (0xFFC00000 >> (31 - count) ); + count = 0; + } + } + Result.W = 0x7FFFFFFF / Result.W; + for (count = 31; count > 0; count--) { + if ((Result.W & (1 << count))) { + Result.W &= (0xFFFF8000 >> (31 - count) ); + count = 0; + } + } + if (neg == TRUE) { + Result.W = ~Result.W; + } + } + return Result.W; +} + +static void uc9_draw_object (wxUint8 * addr, wxUint32 type) +{ + wxUint32 textured, vnum, vsize; + switch (type) { + case 0: //null + textured = vnum = vsize = 0; + break; + case 1: //sh tri + textured = 0; + vnum = 3; + vsize = 8; + break; + case 2: //tx tri + textured = 1; + vnum = 3; + vsize = 16; + break; + case 3: //sh quad + textured = 0; + vnum = 4; + vsize = 8; + break; + case 4: //tx quad + textured = 1; + vnum = 4; + vsize = 16; + break; + } + VERTEX vtx[4]; + for (wxUint32 i = 0; i < vnum; i++) + { + VERTEX &v = vtx[i]; + v.sx = zSortRdp.scale_x * ((short*)addr)[0^1]; + v.sy = zSortRdp.scale_y * ((short*)addr)[1^1]; + v.sz = 1.0f; + v.r = addr[4^3]; + v.g = addr[5^3]; + v.b = addr[6^3]; + v.a = addr[7^3]; + v.flags = 0; + v.uv_scaled = 0; + v.uv_calculated = 0xFFFFFFFF; + v.shade_mod = 0; + v.scr_off = 0; + v.screen_translated = 2; + if (textured) + { + v.ou = ((short*)addr)[4^1]; + v.ov = ((short*)addr)[5^1]; + v.w = Calc_invw(((int*)addr)[3]) / 31.0f; + v.oow = 1.0f / v.w; + FRDP ("v%d - sx: %f, sy: %f ou: %f, ov: %f, w: %f, r=%d, g=%d, b=%d, a=%d\n", i, v.sx/rdp.scale_x, v.sy/rdp.scale_y, v.ou*rdp.tiles[rdp.cur_tile].s_scale, v.ov*rdp.tiles[rdp.cur_tile].t_scale, v.w, v.r, v.g, v.b, v.a); + } + else + { + v.oow = v.w = 1.0f; + FRDP ("v%d - sx: %f, sy: %f r=%d, g=%d, b=%d, a=%d\n", i, v.sx/rdp.scale_x, v.sy/rdp.scale_y, v.r, v.g, v.b, v.a); + } + addr += vsize; + } + //* + VERTEX *pV[4] = { + &vtx[0], + &vtx[1], + &vtx[2], + &vtx[3] + }; + if (vnum == 3) + { + FRDP("uc9:Tri #%d, #%d\n", rdp.tri_n, rdp.tri_n+1); + draw_tri (pV, 0); + rdp.tri_n ++; + } + else + { + FRDP("uc9:Quad #%d, #%d\n", rdp.tri_n, rdp.tri_n+1); + draw_tri (pV, 0); + draw_tri (pV+1, 0); + rdp.tri_n += 2; + } +} + +static wxUint32 uc9_load_object (wxUint32 zHeader, wxUint32 * rdpcmds) +{ + wxUint32 type = zHeader & 7; + wxUint8 * addr = gfx.RDRAM + (zHeader&0xFFFFFFF8); + switch (type) { + case 1: //sh tri + case 3: //sh quad + { + rdp.cmd1 = ((wxUint32*)addr)[1]; + if (rdp.cmd1 != rdpcmds[0]) + { + rdpcmds[0] = rdp.cmd1; + uc9_rpdcmd (); + } + update (); + uc9_draw_object(addr + 8, type); + } + break; + case 0: //null + case 2: //tx tri + case 4: //tx quad + { + rdp.cmd1 = ((wxUint32*)addr)[1]; + if (rdp.cmd1 != rdpcmds[0]) + { + rdpcmds[0] = rdp.cmd1; + uc9_rpdcmd (); + } + rdp.cmd1 = ((wxUint32*)addr)[2]; + if (rdp.cmd1 != rdpcmds[1]) + { + uc9_rpdcmd (); + rdpcmds[1] = rdp.cmd1; + } + rdp.cmd1 = ((wxUint32*)addr)[3]; + if (rdp.cmd1 != rdpcmds[2]) + { + uc9_rpdcmd (); + rdpcmds[2] = rdp.cmd1; + } + if (type) + { + update (); + uc9_draw_object(addr + 16, type); + } + } + break; + } + return segoffset(((wxUint32*)addr)[0]); +} + +static void uc9_object () +{ + LRDP("uc9:object\n"); + wxUint32 rdpcmds[3] = {0, 0, 0}; + wxUint32 cmd1 = rdp.cmd1; + wxUint32 zHeader = segoffset(rdp.cmd0); + while (zHeader) + zHeader = uc9_load_object(zHeader, rdpcmds); + zHeader = segoffset(cmd1); + while (zHeader) + zHeader = uc9_load_object(zHeader, rdpcmds); +} + +static void uc9_mix () +{ + LRDP("uc9:mix IGNORED\n"); +} + +static void uc9_fmlight () +{ + int mid = rdp.cmd0&0xFF; + rdp.num_lights = 1 + ((rdp.cmd1>>12)&0xFF); + wxUint32 a = -1024 + (rdp.cmd1&0xFFF); + FRDP ("uc9:fmlight matrix: %d, num: %d, dmem: %04lx\n", mid, rdp.num_lights, a); + + M44 *m; + switch (mid) { + case 4: + m = (M44*)rdp.model; + break; + case 6: + m = (M44*)rdp.proj; + break; + case 8: + m = (M44*)rdp.combined; + break; + } + + rdp.light[rdp.num_lights].r = (float)(((wxUint8*)gfx.DMEM)[(a+0)^3]) / 255.0f; + rdp.light[rdp.num_lights].g = (float)(((wxUint8*)gfx.DMEM)[(a+1)^3]) / 255.0f; + rdp.light[rdp.num_lights].b = (float)(((wxUint8*)gfx.DMEM)[(a+2)^3]) / 255.0f; + rdp.light[rdp.num_lights].a = 1.0f; + FRDP ("ambient light: r: %.3f, g: %.3f, b: %.3f\n", rdp.light[rdp.num_lights].r, rdp.light[rdp.num_lights].g, rdp.light[rdp.num_lights].b); + a += 8; + wxUint32 i; + for (i = 0; i < rdp.num_lights; i++) + { + rdp.light[i].r = (float)(((wxUint8*)gfx.DMEM)[(a+0)^3]) / 255.0f; + rdp.light[i].g = (float)(((wxUint8*)gfx.DMEM)[(a+1)^3]) / 255.0f; + rdp.light[i].b = (float)(((wxUint8*)gfx.DMEM)[(a+2)^3]) / 255.0f; + rdp.light[i].a = 1.0f; + rdp.light[i].dir_x = (float)(((char*)gfx.DMEM)[(a+8)^3]) / 127.0f; + rdp.light[i].dir_y = (float)(((char*)gfx.DMEM)[(a+9)^3]) / 127.0f; + rdp.light[i].dir_z = (float)(((char*)gfx.DMEM)[(a+10)^3]) / 127.0f; + FRDP ("light: n: %d, r: %.3f, g: %.3f, b: %.3f, x: %.3f, y: %.3f, z: %.3f\n", + i, rdp.light[i].r, rdp.light[i].g, rdp.light[i].b, + rdp.light[i].dir_x, rdp.light[i].dir_y, rdp.light[i].dir_z); +// TransformVector(&rdp.light[i].dir_x, rdp.light_vector[i], *m); + InverseTransformVector(&rdp.light[i].dir_x, rdp.light_vector[i], *m); + NormalizeVector (rdp.light_vector[i]); + FRDP ("light vector: n: %d, x: %.3f, y: %.3f, z: %.3f\n", + i, rdp.light_vector[i][0], rdp.light_vector[i][1], rdp.light_vector[i][2]); + a += 24; + } + for (i = 0; i < 2; i++) + { + float dir_x = (float)(((char*)gfx.DMEM)[(a+8)^3]) / 127.0f; + float dir_y = (float)(((char*)gfx.DMEM)[(a+9)^3]) / 127.0f; + float dir_z = (float)(((char*)gfx.DMEM)[(a+10)^3]) / 127.0f; + if (sqrt(dir_x*dir_x + dir_y*dir_y + dir_z*dir_z) < 0.98) + { + rdp.use_lookat = FALSE; + return; + } + rdp.lookat[i][0] = dir_x; + rdp.lookat[i][1] = dir_y; + rdp.lookat[i][2] = dir_z; + a += 24; + } + rdp.use_lookat = TRUE; +} + +static void uc9_light () +{ + wxUint32 csrs = -1024 + ((rdp.cmd0>>12)&0xFFF); + wxUint32 nsrs = -1024 + (rdp.cmd0&0xFFF); + wxUint32 num = 1 + ((rdp.cmd1>>24)&0xFF); + wxUint32 cdest = -1024 + ((rdp.cmd1>>12)&0xFFF); + wxUint32 tdest = -1024 + (rdp.cmd1&0xFFF); + int use_material = (csrs != 0x0ff0); + tdest >>= 1; + FRDP ("uc9:light n: %d, colsrs: %04lx, normales: %04lx, coldst: %04lx, texdst: %04lx\n", num, csrs, nsrs, cdest, tdest); + VERTEX v; + for (wxUint32 i = 0; i < num; i++) + { + v.vec[0] = ((char*)gfx.DMEM)[(nsrs++)^3]; + v.vec[1] = ((char*)gfx.DMEM)[(nsrs++)^3]; + v.vec[2] = ((char*)gfx.DMEM)[(nsrs++)^3]; + calc_sphere (&v); +// calc_linear (&v); + NormalizeVector (v.vec); + calc_light (&v); + v.a = 0xFF; + if (use_material) + { + v.r = (wxUint8)(((wxUint32)v.r * gfx.DMEM[(csrs++)^3])>>8); + v.g = (wxUint8)(((wxUint32)v.g * gfx.DMEM[(csrs++)^3])>>8); + v.b = (wxUint8)(((wxUint32)v.b * gfx.DMEM[(csrs++)^3])>>8); + v.a = gfx.DMEM[(csrs++)^3]; + } + gfx.DMEM[(cdest++)^3] = v.r; + gfx.DMEM[(cdest++)^3] = v.g; + gfx.DMEM[(cdest++)^3] = v.b; + gfx.DMEM[(cdest++)^3] = v.a; + ((short*)gfx.DMEM)[(tdest++)^1] = (short)v.ou; + ((short*)gfx.DMEM)[(tdest++)^1] = (short)v.ov; + } +} + +static void uc9_mtxtrnsp () +{ + LRDP("uc9:mtxtrnsp - ignored\n"); + /* + LRDP("uc9:mtxtrnsp "); + M44 *s; + switch (rdp.cmd1&0xF) { + case 4: + s = (M44*)rdp.model; + LRDP("Model\n"); + break; + case 6: + s = (M44*)rdp.proj; + LRDP("Proj\n"); + break; + case 8: + s = (M44*)rdp.combined; + LRDP("Comb\n"); + break; + } + float m = *s[1][0]; + *s[1][0] = *s[0][1]; + *s[0][1] = m; + m = *s[2][0]; + *s[2][0] = *s[0][2]; + *s[0][2] = m; + m = *s[2][1]; + *s[2][1] = *s[1][2]; + *s[1][2] = m; + */ +} + +static void uc9_mtxcat () +{ + LRDP("uc9:mtxcat "); + M44 *s; + M44 *t; + wxUint32 S = rdp.cmd0&0xF; + wxUint32 T = (rdp.cmd1>>16)&0xF; + wxUint32 D = rdp.cmd1&0xF; + switch (S) { + case 4: + s = (M44*)rdp.model; + LRDP("Model * "); + break; + case 6: + s = (M44*)rdp.proj; + LRDP("Proj * "); + break; + case 8: + s = (M44*)rdp.combined; + LRDP("Comb * "); + break; + } + switch (T) { + case 4: + t = (M44*)rdp.model; + LRDP("Model -> "); + break; + case 6: + t = (M44*)rdp.proj; + LRDP("Proj -> "); + break; + case 8: + LRDP("Comb -> "); + t = (M44*)rdp.combined; + break; + } + DECLAREALIGN16VAR(m[4][4]); + MulMatrices(*s, *t, m); + + switch (D) { + case 4: + memcpy (rdp.model, m, 64);; + LRDP("Model\n"); + break; + case 6: + memcpy (rdp.proj, m, 64);; + LRDP("Proj\n"); + break; + case 8: + memcpy (rdp.combined, m, 64);; + LRDP("Comb\n"); + break; + } +#ifdef EXTREME_LOGGING + FRDP ("\nmodel\n{%f,%f,%f,%f}\n", rdp.model[0][0], rdp.model[0][1], rdp.model[0][2], rdp.model[0][3]); + FRDP ("{%f,%f,%f,%f}\n", rdp.model[1][0], rdp.model[1][1], rdp.model[1][2], rdp.model[1][3]); + FRDP ("{%f,%f,%f,%f}\n", rdp.model[2][0], rdp.model[2][1], rdp.model[2][2], rdp.model[2][3]); + FRDP ("{%f,%f,%f,%f}\n", rdp.model[3][0], rdp.model[3][1], rdp.model[3][2], rdp.model[3][3]); + FRDP ("\nproj\n{%f,%f,%f,%f}\n", rdp.proj[0][0], rdp.proj[0][1], rdp.proj[0][2], rdp.proj[0][3]); + FRDP ("{%f,%f,%f,%f}\n", rdp.proj[1][0], rdp.proj[1][1], rdp.proj[1][2], rdp.proj[1][3]); + FRDP ("{%f,%f,%f,%f}\n", rdp.proj[2][0], rdp.proj[2][1], rdp.proj[2][2], rdp.proj[2][3]); + FRDP ("{%f,%f,%f,%f}\n", rdp.proj[3][0], rdp.proj[3][1], rdp.proj[3][2], rdp.proj[3][3]); + FRDP ("\ncombined\n{%f,%f,%f,%f}\n", rdp.combined[0][0], rdp.combined[0][1], rdp.combined[0][2], rdp.combined[0][3]); + FRDP ("{%f,%f,%f,%f}\n", rdp.combined[1][0], rdp.combined[1][1], rdp.combined[1][2], rdp.combined[1][3]); + FRDP ("{%f,%f,%f,%f}\n", rdp.combined[2][0], rdp.combined[2][1], rdp.combined[2][2], rdp.combined[2][3]); + FRDP ("{%f,%f,%f,%f}\n", rdp.combined[3][0], rdp.combined[3][1], rdp.combined[3][2], rdp.combined[3][3]); +#endif +} + +typedef struct { + short sy; + short sx; + int invw; + short yi; + short xi; + short wi; + wxUint8 fog; + wxUint8 cc; +} zSortVDest; + +static void uc9_mult_mpmtx () +{ + //int id = rdp.cmd0&0xFF; + int num = 1+ ((rdp.cmd1>>24)&0xFF); + int src = -1024 + ((rdp.cmd1>>12)&0xFFF); + int dst = -1024 + (rdp.cmd1&0xFFF); + FRDP ("uc9:mult_mpmtx from: %04lx to: %04lx n: %d\n", src, dst, num); + short * saddr = (short*)(gfx.DMEM+src); + zSortVDest * daddr = (zSortVDest*)(gfx.DMEM+dst); + int idx = 0; + zSortVDest v; + memset(&v, 0, sizeof(zSortVDest)); + //float scale_x = 4.0f/rdp.scale_x; + //float scale_y = 4.0f/rdp.scale_y; + for (int i = 0; i < num; i++) + { + short sx = saddr[(idx++)^1]; + short sy = saddr[(idx++)^1]; + short sz = saddr[(idx++)^1]; + float x = sx*rdp.combined[0][0] + sy*rdp.combined[1][0] + sz*rdp.combined[2][0] + rdp.combined[3][0]; + float y = sx*rdp.combined[0][1] + sy*rdp.combined[1][1] + sz*rdp.combined[2][1] + rdp.combined[3][1]; + float z = sx*rdp.combined[0][2] + sy*rdp.combined[1][2] + sz*rdp.combined[2][2] + rdp.combined[3][2]; + float w = sx*rdp.combined[0][3] + sy*rdp.combined[1][3] + sz*rdp.combined[2][3] + rdp.combined[3][3]; + v.sx = (short)(zSortRdp.view_trans[0] + x / w * zSortRdp.view_scale[0]); + v.sy = (short)(zSortRdp.view_trans[1] + y / w * zSortRdp.view_scale[1]); + + v.xi = (short)x; + v.yi = (short)y; + v.wi = (short)w; + v.invw = Calc_invw((int)(w * 31.0)); + + if (w < 0.0f) + v.fog = 0; + else + { + int fog = (int)(z / w * rdp.fog_multiplier + rdp.fog_offset); + if (fog > 255) + fog = 255; + v.fog = (fog >= 0) ? (wxUint8)fog : 0; + } + + v.cc = 0; + if (x < -w) v.cc |= 0x10; + if (x > w) v.cc |= 0x01; + if (y < -w) v.cc |= 0x20; + if (y > w) v.cc |= 0x02; + if (w < 0.1f) v.cc |= 0x04; + + daddr[i] = v; + //memcpy(gfx.DMEM+dst+sizeof(zSortVDest)*i, &v, sizeof(zSortVDest)); +// FRDP("v%d x: %d, y: %d, z: %d -> sx: %d, sy: %d, w: %d, xi: %d, yi: %d, wi: %d, fog: %d\n", i, sx, sy, sz, v.sx, v.sy, v.invw, v.xi, v.yi, v.wi, v.fog); + FRDP("v%d x: %d, y: %d, z: %d -> sx: %04lx, sy: %04lx, invw: %08lx - %f, xi: %04lx, yi: %04lx, wi: %04lx, fog: %04lx\n", i, sx, sy, sz, v.sx, v.sy, v.invw, w, v.xi, v.yi, v.wi, v.fog); + } +} + +static void uc9_link_subdl () +{ + LRDP("uc9:link_subdl IGNORED\n"); +} + +static void uc9_set_subdl () +{ + LRDP("uc9:set_subdl IGNORED\n"); +} + +static void uc9_wait_signal () +{ + LRDP("uc9:wait_signal IGNORED\n"); +} + +static void uc9_send_signal () +{ + LRDP("uc9:send_signal IGNORED\n"); +} + +void uc9_movemem () +{ + LRDP("uc9:movemem\n"); + int idx = rdp.cmd0 & 0x0E; + int ofs = ((rdp.cmd0>>6)&0x1ff)<<3; + int len = (1 + ((rdp.cmd0>>15)&0x1ff))<<3; + FRDP ("uc9:movemem ofs: %d, len: %d. ", ofs, len); + int flag = rdp.cmd0 & 0x01; + wxUint32 addr = segoffset(rdp.cmd1); + switch (idx) + { + + case 0: //save/load + if (flag == 0) + { + int dmem_addr = (idx<<3) + ofs; + FRDP ("Load to DMEM. %08lx -> %08lx\n", addr, dmem_addr); + memcpy(gfx.DMEM + dmem_addr, gfx.RDRAM + addr, len); + } + else + { + int dmem_addr = (idx<<3) + ofs; + FRDP ("Load from DMEM. %08lx -> %08lx\n", dmem_addr, addr); + memcpy(gfx.RDRAM + addr, gfx.DMEM + dmem_addr, len); + } + break; + + case 4: // model matrix + case 6: // projection matrix + case 8: // combined matrix + { + DECLAREALIGN16VAR(m[4][4]); + load_matrix(m, addr); + switch (idx) + { + case 4: // model matrix + LRDP("Modelview load\n"); + modelview_load (m); + break; + case 6: // projection matrix + LRDP("Projection load\n"); + projection_load (m); + break; + case 8: // projection matrix + LRDP("Combined load\n"); + rdp.update &= ~UPDATE_MULT_MAT; + memcpy (rdp.combined, m, 64);; + break; + } +#ifdef EXTREME_LOGGING + FRDP ("{%f,%f,%f,%f}\n", m[0][0], m[0][1], m[0][2], m[0][3]); + FRDP ("{%f,%f,%f,%f}\n", m[1][0], m[1][1], m[1][2], m[1][3]); + FRDP ("{%f,%f,%f,%f}\n", m[2][0], m[2][1], m[2][2], m[2][3]); + FRDP ("{%f,%f,%f,%f}\n", m[3][0], m[3][1], m[3][2], m[3][3]); + FRDP ("\nmodel\n{%f,%f,%f,%f}\n", rdp.model[0][0], rdp.model[0][1], rdp.model[0][2], rdp.model[0][3]); + FRDP ("{%f,%f,%f,%f}\n", rdp.model[1][0], rdp.model[1][1], rdp.model[1][2], rdp.model[1][3]); + FRDP ("{%f,%f,%f,%f}\n", rdp.model[2][0], rdp.model[2][1], rdp.model[2][2], rdp.model[2][3]); + FRDP ("{%f,%f,%f,%f}\n", rdp.model[3][0], rdp.model[3][1], rdp.model[3][2], rdp.model[3][3]); + FRDP ("\nproj\n{%f,%f,%f,%f}\n", rdp.proj[0][0], rdp.proj[0][1], rdp.proj[0][2], rdp.proj[0][3]); + FRDP ("{%f,%f,%f,%f}\n", rdp.proj[1][0], rdp.proj[1][1], rdp.proj[1][2], rdp.proj[1][3]); + FRDP ("{%f,%f,%f,%f}\n", rdp.proj[2][0], rdp.proj[2][1], rdp.proj[2][2], rdp.proj[2][3]); + FRDP ("{%f,%f,%f,%f}\n", rdp.proj[3][0], rdp.proj[3][1], rdp.proj[3][2], rdp.proj[3][3]); +#endif + } + break; + + case 10: + LRDP("Othermode - IGNORED\n"); + break; + + case 12: // VIEWPORT + { + wxUint32 a = addr >> 1; + short scale_x = ((short*)gfx.RDRAM)[(a+0)^1] >> 2; + short scale_y = ((short*)gfx.RDRAM)[(a+1)^1] >> 2; + short scale_z = ((short*)gfx.RDRAM)[(a+2)^1]; + rdp.fog_multiplier = ((short*)gfx.RDRAM)[(a+3)^1]; + short trans_x = ((short*)gfx.RDRAM)[(a+4)^1] >> 2; + short trans_y = ((short*)gfx.RDRAM)[(a+5)^1] >> 2; + short trans_z = ((short*)gfx.RDRAM)[(a+6)^1]; + rdp.fog_offset = ((short*)gfx.RDRAM)[(a+7)^1]; + rdp.view_scale[0] = scale_x * rdp.scale_x; + rdp.view_scale[1] = scale_y * rdp.scale_y; + rdp.view_scale[2] = 32.0f * scale_z; + rdp.view_trans[0] = trans_x * rdp.scale_x; + rdp.view_trans[1] = trans_y * rdp.scale_y; + rdp.view_trans[2] = 32.0f * trans_z; + zSortRdp.view_scale[0] = (float)(scale_x*4); + zSortRdp.view_scale[1] = (float)(scale_y*4); + zSortRdp.view_trans[0] = (float)(trans_x*4); + zSortRdp.view_trans[1] = (float)(trans_y*4); + zSortRdp.scale_x = rdp.scale_x / 4.0f; + zSortRdp.scale_y = rdp.scale_y / 4.0f; + + rdp.update |= UPDATE_VIEWPORT; + + rdp.mipmap_level = 0; + rdp.cur_tile = 0; + TILE *tmp_tile = &rdp.tiles[0]; + tmp_tile->on = 1; + tmp_tile->org_s_scale = 0xFFFF; + tmp_tile->org_t_scale = 0xFFFF; + tmp_tile->s_scale = 0.031250f; + tmp_tile->t_scale = 0.031250f; + + rdp.geom_mode |= 0x0200; + + FRDP ("viewport scale(%d, %d, %d), trans(%d, %d, %d), from:%08lx\n", scale_x, scale_y, scale_z, + trans_x, trans_y, trans_z, a); + FRDP ("fog: multiplier: %f, offset: %f\n", rdp.fog_multiplier, rdp.fog_offset); + } + break; + + default: + FRDP ("** UNKNOWN %d\n", idx); + } + +} + +static void uc9_setscissor() +{ + rdp_setscissor(); + + if ((rdp.scissor_o.lr_x - rdp.scissor_o.ul_x) > (zSortRdp.view_scale[0] - zSortRdp.view_trans[0])) + { + float w = (rdp.scissor_o.lr_x - rdp.scissor_o.ul_x) / 2.0f; + float h = (rdp.scissor_o.lr_y - rdp.scissor_o.ul_y) / 2.0f; + rdp.view_scale[0] = w * rdp.scale_x; + rdp.view_scale[1] = h * rdp.scale_y; + rdp.view_trans[0] = w * rdp.scale_x; + rdp.view_trans[1] = h * rdp.scale_y; + zSortRdp.view_scale[0] = w * 4.0f; + zSortRdp.view_scale[1] = h * 4.0f; + zSortRdp.view_trans[0] = w * 4.0f; + zSortRdp.view_trans[1] = h * 4.0f; + zSortRdp.scale_x = rdp.scale_x / 4.0f; + zSortRdp.scale_y = rdp.scale_y / 4.0f; + rdp.update |= UPDATE_VIEWPORT; + + rdp.mipmap_level = 0; + rdp.cur_tile = 0; + TILE *tmp_tile = &rdp.tiles[0]; + tmp_tile->on = 1; + tmp_tile->org_s_scale = 0xFFFF; + tmp_tile->org_t_scale = 0xFFFF; + tmp_tile->s_scale = 0.031250f; + tmp_tile->t_scale = 0.031250f; + + rdp.geom_mode |= 0x0200; + } +} diff --git a/Source/Glide64/ucode09rdp.h b/Source/Glide64/ucode09rdp.h new file mode 100644 index 000000000..c595d59a9 --- /dev/null +++ b/Source/Glide64/ucode09rdp.h @@ -0,0 +1,70 @@ +/* +* Glide64 - Glide video plugin for Nintendo 64 emulators. +* Copyright (c) 2002 Dave2001 +* Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski +* +* 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 +* 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 +*/ + +//**************************************************************** +// +// Glide64 - Glide Plugin for Nintendo 64 emulators +// Project started on December 29th, 2001 +// +// Authors: +// Dave2001, original author, founded the project in 2001, left it in 2002 +// Gugaman, joined the project in 2002, left it in 2002 +// Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002 +// Hiroshi 'KoolSmoky' Morii, joined the project in 2007 +// +//**************************************************************** +// +// To modify Glide64: +// * Write your name and (optional)email, commented by your work, so I know who did it, and so that you can find which parts you modified when it comes time to send it to me. +// * Do NOT send me the whole project or file that you modified. Take out your modified code sections, and tell me where to put them. If people sent the whole thing, I would have many different versions, but no idea how to combine them all. +// +//**************************************************************** +// +// December 2008 Created by Gonetz (Gonetz@ngs.ru) +// +//**************************************************************** + +void uc9_rpdcmd () +{ + wxUint32 a = segoffset(rdp.cmd1) >> 2; + FRDP ("uc9:rdpcmd addr: %08lx\n", a); + if (a) + { + rdp.LLE = 1; + wxUint32 cmd = 0; + while(1) + { + rdp.cmd0 = ((wxUint32*)gfx.RDRAM)[a++]; + cmd = rdp.cmd0>>24; + if (cmd == 0xDF) + break; + rdp.cmd1 = ((wxUint32*)gfx.RDRAM)[a++]; + if (cmd == 0xE4 || cmd == 0xE5) + { + a++; + rdp.cmd2 = ((wxUint32*)gfx.RDRAM)[a++]; + a++; + rdp.cmd3 = ((wxUint32*)gfx.RDRAM)[a++]; + } + gfx_instruction[ucode_zSort][cmd] (); + }; + rdp.LLE = 0; + } +} diff --git a/Source/Glide64/ucodeFB.h b/Source/Glide64/ucodeFB.h new file mode 100644 index 000000000..141c31ec2 --- /dev/null +++ b/Source/Glide64/ucodeFB.h @@ -0,0 +1,1110 @@ +/* +* Glide64 - Glide video plugin for Nintendo 64 emulators. +* Copyright (c) 2002 Dave2001 +* Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski +* +* 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 +* 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 +*/ + +//**************************************************************** +// +// Glide64 - Glide Plugin for Nintendo 64 emulators +// Project started on December 29th, 2001 +// +// Authors: +// Dave2001, original author, founded the project in 2001, left it in 2002 +// Gugaman, joined the project in 2002, left it in 2002 +// Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002 +// Hiroshi 'KoolSmoky' Morii, joined the project in 2007 +// +//**************************************************************** +// +// To modify Glide64: +// * Write your name and (optional)email, commented by your work, so I know who did it, and so that you can find which parts you modified when it comes time to send it to me. +// * Do NOT send me the whole project or file that you modified. Take out your modified code sections, and tell me where to put them. If people sent the whole thing, I would have many different versions, but no idea how to combine them all. +// +//**************************************************************** +// +// Creation 13 August 2003 Gonetz +// +//**************************************************************** + +static void fb_uc0_moveword() +{ + if ((rdp.cmd0 & 0xFF) == 0x06) // segment + { + rdp.segment[(rdp.cmd0 >> 10) & 0x0F] = rdp.cmd1; + } +} + +static void fb_uc2_moveword() +{ + if (((rdp.cmd0 >> 16) & 0xFF) == 0x06) // segment + { + rdp.segment[((rdp.cmd0 & 0xFFFF) >> 2)&0xF] = rdp.cmd1; + } +} + +static void fb_bg_copy () +{ + if (rdp.main_ci == 0) + return; + CI_STATUS status = rdp.frame_buffers[rdp.ci_count-1].status; + if ( (status == ci_copy) ) + return; + + wxUint32 addr = segoffset(rdp.cmd1) >> 1; + wxUint8 imageFmt = ((wxUint8 *)gfx.RDRAM)[(((addr+11)<<1)+0)^3]; + wxUint8 imageSiz = ((wxUint8 *)gfx.RDRAM)[(((addr+11)<<1)+1)^3]; + wxUint32 imagePtr = segoffset(((wxUint32*)gfx.RDRAM)[(addr+8)>>1]); + FRDP ("fb_bg_copy. fmt: %d, size: %d, imagePtr %08lx, main_ci: %08lx, cur_ci: %08lx \n", imageFmt, imageSiz, imagePtr, rdp.main_ci, rdp.frame_buffers[rdp.ci_count-1].addr); + + if (status == ci_main) + { + wxUint16 frameW = ((wxUint16 *)gfx.RDRAM)[(addr+3)^1] >> 2; + wxUint16 frameH = ((wxUint16 *)gfx.RDRAM)[(addr+7)^1] >> 2; + if ( (frameW == rdp.frame_buffers[rdp.ci_count-1].width) && (frameH == rdp.frame_buffers[rdp.ci_count-1].height) ) + rdp.main_ci_bg = imagePtr; + } + else if (imagePtr >= rdp.main_ci && imagePtr < rdp.main_ci_end) //addr within main frame buffer + { + rdp.copy_ci_index = rdp.ci_count-1; + rdp.frame_buffers[rdp.copy_ci_index].status = ci_copy; + FRDP("rdp.frame_buffers[%d].status = ci_copy\n", rdp.copy_ci_index); + + if (rdp.frame_buffers[rdp.copy_ci_index].addr != rdp.main_ci_bg) + { + rdp.scale_x = 1.0f; + rdp.scale_y = 1.0f; + } + else + { + LRDP("motion blur!\n"); + rdp.motionblur = TRUE; + } + + FRDP ("Detect FB usage. texture addr is inside framebuffer: %08lx - %08lx \n", imagePtr, rdp.main_ci); + } + else if (imagePtr == rdp.zimg) + { + if (status == ci_unknown) + { + rdp.frame_buffers[rdp.ci_count-1].status = ci_zcopy; + rdp.tmpzimg = rdp.frame_buffers[rdp.ci_count-1].addr; + if (!rdp.copy_zi_index) + rdp.copy_zi_index = rdp.ci_count-1; + FRDP("rdp.frame_buffers[%d].status = ci_zcopy\n", rdp.copy_ci_index); + } + } +} + +static void fb_setscissor() +{ + rdp.scissor_o.lr_y = (wxUint32)(((rdp.cmd1 & 0x00000FFF) >> 2)); + if (rdp.ci_count) + { + rdp.scissor_o.ul_x = (wxUint32)(((rdp.cmd0 & 0x00FFF000) >> 14)); + rdp.scissor_o.lr_x = (wxUint32)(((rdp.cmd1 & 0x00FFF000) >> 14)); + COLOR_IMAGE & cur_fb = rdp.frame_buffers[rdp.ci_count-1]; + if (rdp.scissor_o.lr_x - rdp.scissor_o.ul_x > (wxUint32)(cur_fb.width >> 1)) + { + if (cur_fb.height == 0 || (cur_fb.width >= rdp.scissor_o.lr_x-1 && cur_fb.width <= rdp.scissor_o.lr_x+1)) + cur_fb.height = rdp.scissor_o.lr_y; + } + FRDP("fb_setscissor. lr_x = %d, lr_y = %d, fb_width = %d, fb_height = %d\n", rdp.scissor_o.lr_x, rdp.scissor_o.lr_y, cur_fb.width, cur_fb.height); + } +} + +static void fb_uc2_movemem() +{ + if ((rdp.cmd0 & 0xFF) == 8) + { + wxUint32 a = segoffset(rdp.cmd1) >> 1; + short scale_x = ((short*)gfx.RDRAM)[(a+0)^1] >> 2; + short trans_x = ((short*)gfx.RDRAM)[(a+4)^1] >> 2; + COLOR_IMAGE & cur_fb = rdp.frame_buffers[rdp.ci_count-1]; + if ( abs((int)(scale_x + trans_x - cur_fb.width)) < 3) + { + short scale_y = ((short*)gfx.RDRAM)[(a+1)^1] >> 2; + short trans_y = ((short*)gfx.RDRAM)[(a+5)^1] >> 2; + wxUint32 height = scale_y + trans_y; + if (height < rdp.scissor_o.lr_y) + cur_fb.height = height; + } + } +} + +static void fb_rect() +{ + if (rdp.frame_buffers[rdp.ci_count-1].width == 32) + return; + int ul_x = ((rdp.cmd1 & 0x00FFF000) >> 14); + int lr_x = ((rdp.cmd0 & 0x00FFF000) >> 14); + int width = lr_x-ul_x; + int diff = abs((int)rdp.frame_buffers[rdp.ci_count-1].width - width); + if (diff < 4) + { + wxUint32 lr_y = min(rdp.scissor_o.lr_y, (rdp.cmd0 & 0xFFF) >> 2); + if (rdp.frame_buffers[rdp.ci_count-1].height < lr_y) + { + FRDP("fb_rect. ul_x: %d, lr_x: %d, fb_height: %d -> %d\n", ul_x, lr_x, rdp.frame_buffers[rdp.ci_count-1].height, lr_y); + rdp.frame_buffers[rdp.ci_count-1].height = lr_y; + } + } +} + +static void fb_rdphalf_1() +{ + branch_dl = rdp.cmd1; +} + + +static void fb_settextureimage() +{ + if (rdp.main_ci == 0) + return; + COLOR_IMAGE & cur_fb = rdp.frame_buffers[rdp.ci_count-1]; + if ( cur_fb.status >= ci_copy ) + return; + if (((rdp.cmd0 >> 19) & 0x03) >= 2) //check that texture is 16/32bit + { + int tex_format = ((rdp.cmd0 >> 21) & 0x07); + wxUint32 addr = segoffset(rdp.cmd1); + if ( tex_format == 0 ) + { + FRDP ("fb_settextureimage. fmt: %d, size: %d, imagePtr %08lx, main_ci: %08lx, cur_ci: %08lx \n", ((rdp.cmd0 >> 21) & 0x07), ((rdp.cmd0 >> 19) & 0x03), addr, rdp.main_ci, rdp.frame_buffers[rdp.ci_count-1].addr); + if (cur_fb.status == ci_main) + { + rdp.main_ci_last_tex_addr = addr; + if (cur_fb.height == 0) + { + cur_fb.height = rdp.scissor_o.lr_y; + rdp.main_ci_end = cur_fb.addr + ((cur_fb.width * cur_fb.height) << cur_fb.size >> 1); + } + } + if ((addr >= rdp.main_ci) && (addr < rdp.main_ci_end)) //addr within main frame buffer + { + if (cur_fb.status == ci_main) + { + rdp.copy_ci_index = rdp.ci_count-1; + cur_fb.status = ci_copy_self; + rdp.scale_x = rdp.scale_x_bak; + rdp.scale_y = rdp.scale_y_bak; + FRDP("rdp.frame_buffers[%d].status = ci_copy_self\n", rdp.ci_count-1); + } + else + { + if (cur_fb.width == rdp.frame_buffers[rdp.main_ci_index].width) + { + rdp.copy_ci_index = rdp.ci_count-1; + cur_fb.status = ci_copy; + FRDP("rdp.frame_buffers[%d].status = ci_copy\n", rdp.copy_ci_index); + if ((rdp.main_ci_last_tex_addr >= cur_fb.addr) && + (rdp.main_ci_last_tex_addr < (cur_fb.addr + cur_fb.width*cur_fb.height*cur_fb.size))) + { + LRDP("motion blur!\n"); + rdp.motionblur = TRUE; + } + else + { + rdp.scale_x = 1.0f; + rdp.scale_y = 1.0f; + } + } + else if (!(settings.frame_buffer & fb_ignore_aux_copy) && cur_fb.width < rdp.frame_buffers[rdp.main_ci_index].width) + { + rdp.copy_ci_index = rdp.ci_count-1; + cur_fb.status = ci_aux_copy; + FRDP("rdp.frame_buffers[%d].status = ci_aux_copy\n", rdp.copy_ci_index); + rdp.scale_x = 1.0f; + rdp.scale_y = 1.0f; + } + else + { + cur_fb.status = ci_aux; + FRDP("rdp.frame_buffers[%d].status = ci_aux\n", rdp.copy_ci_index); + } + } + FRDP ("Detect FB usage. texture addr is inside framebuffer: %08lx - %08lx \n", addr, rdp.main_ci); + } + ///* + else if ((cur_fb.status != ci_main) && (addr >= rdp.zimg && addr < rdp.zimg_end)) + { + cur_fb.status = ci_zcopy; + if (!rdp.copy_zi_index) + rdp.copy_zi_index = rdp.ci_count-1; + FRDP("fb_settextureimage. rdp.frame_buffers[%d].status = ci_zcopy\n", rdp.ci_count-1); + } + //*/ + else if ((rdp.maincimg[0].width > 64) && (addr >= rdp.maincimg[0].addr) && (addr < (rdp.maincimg[0].addr + rdp.maincimg[0].width*rdp.maincimg[0].height*2))) + { + if (cur_fb.status != ci_main) + { + cur_fb.status = ci_old_copy; + FRDP("rdp.frame_buffers[%d].status = ci_old_copy 1, addr:%08lx\n", rdp.ci_count-1, rdp.last_drawn_ci_addr); + } + rdp.read_previous_ci = TRUE; + LRDP("read_previous_ci = TRUE\n"); + } + else if ((addr >= rdp.last_drawn_ci_addr) && (addr < (rdp.last_drawn_ci_addr + rdp.maincimg[0].width*rdp.maincimg[0].height*2))) + { + if (cur_fb.status != ci_main) + { + cur_fb.status = ci_old_copy; + FRDP("rdp.frame_buffers[%d].status = ci_old_copy 2, addr:%08lx\n", rdp.ci_count-1, rdp.last_drawn_ci_addr); + } + rdp.read_previous_ci = TRUE; + LRDP("read_previous_ci = TRUE\n"); + } + } + else if (fb_hwfbe_enabled && (cur_fb.status == ci_main)) + { + if ((addr >= rdp.main_ci) && (addr < rdp.main_ci_end)) //addr within main frame buffer + { + rdp.copy_ci_index = rdp.ci_count-1; + rdp.black_ci_index = rdp.ci_count-1; + cur_fb.status = ci_copy_self; + FRDP("rdp.frame_buffers[%d].status = ci_copy_self\n", rdp.ci_count-1); + } + } + } + if (cur_fb.status == ci_unknown) + { + cur_fb.status = ci_aux; + FRDP("fb_settextureimage. rdp.frame_buffers[%d].status = ci_aux\n", rdp.ci_count-1); + } +} + +static void fb_loadtxtr() +{ + if (rdp.frame_buffers[rdp.ci_count-1].status == ci_unknown) + { + rdp.frame_buffers[rdp.ci_count-1].status = ci_aux; + FRDP("rdp.frame_buffers[%d].status = ci_aux\n", rdp.ci_count-1); + } +} + +static void fb_setdepthimage() +{ + rdp.zimg = segoffset(rdp.cmd1) & BMASK; + rdp.zimg_end = rdp.zimg + rdp.ci_width*rdp.ci_height*2; + FRDP ("fb_setdepthimage. addr %08lx - %08lx\n", rdp.zimg, rdp.zimg_end); + if (rdp.zimg == rdp.main_ci) //strange, but can happen + { + rdp.frame_buffers[rdp.main_ci_index].status = ci_unknown; + if (rdp.main_ci_index < rdp.ci_count) + { + rdp.frame_buffers[rdp.main_ci_index].status = ci_zimg; + FRDP("rdp.frame_buffers[%d].status = ci_zimg\n", rdp.main_ci_index); + rdp.main_ci_index++; + rdp.frame_buffers[rdp.main_ci_index].status = ci_main; + FRDP("rdp.frame_buffers[%d].status = ci_main\n", rdp.main_ci_index); + rdp.main_ci = rdp.frame_buffers[rdp.main_ci_index].addr; + rdp.main_ci_end = rdp.main_ci + (rdp.frame_buffers[rdp.main_ci_index].width * rdp.frame_buffers[rdp.main_ci_index].height * rdp.frame_buffers[rdp.main_ci_index].size); + for (int i = rdp.main_ci_index+1; i < rdp.ci_count; i++) + { + COLOR_IMAGE & fb = rdp.frame_buffers[i]; + if (fb.addr == rdp.main_ci) + { + fb.status = ci_main; + FRDP("rdp.frame_buffers[%d].status = ci_main\n", i); + } + } + } + else + { + rdp.main_ci = 0; + } + } + for (int i = 0; i < rdp.ci_count; i++) + { + COLOR_IMAGE & fb = rdp.frame_buffers[i]; + if ((fb.addr == rdp.zimg) && (fb.status == ci_aux || fb.status == ci_useless)) + { + fb.status = ci_zimg; + FRDP("rdp.frame_buffers[%d].status = ci_zimg\n", i); + } + } +} + +static void fb_setcolorimage() +{ + rdp.ocimg = rdp.cimg; + rdp.cimg = segoffset(rdp.cmd1) & BMASK; + COLOR_IMAGE & cur_fb = rdp.frame_buffers[rdp.ci_count]; + cur_fb.width = (rdp.cmd0 & 0xFFF) + 1; + if (cur_fb.width == 32 ) + cur_fb.height = 32; + else if (cur_fb.width == 16 ) + cur_fb.height = 16; + else if (rdp.ci_count > 0) + cur_fb.height = rdp.scissor_o.lr_y; + else + cur_fb.height = 0; + cur_fb.format = (rdp.cmd0 >> 21) & 0x7; + cur_fb.size = (rdp.cmd0 >> 19) & 0x3; + cur_fb.addr = rdp.cimg; + cur_fb.changed = 1; + /* + if (rdp.ci_count > 0) + if (rdp.frame_buffers[0].addr == rdp.cimg) + rdp.frame_buffers[0].height = rdp.scissor_o.lr_y; + */ + FRDP ("fb_setcolorimage. width: %d, height: %d, fmt: %d, size: %d, addr %08lx\n", cur_fb.width, cur_fb.height, cur_fb.format, cur_fb.size, cur_fb.addr); + if (rdp.cimg == rdp.zimg) + { + cur_fb.status = ci_zimg; + rdp.zimg_end = rdp.zimg + cur_fb.width*rdp.scissor_o.lr_y*2; + FRDP("rdp.frame_buffers[%d].status = ci_zimg\n", rdp.ci_count); + } + else if (rdp.cimg == rdp.tmpzimg) + { + cur_fb.status = ci_zcopy; + if (!rdp.copy_zi_index) + rdp.copy_zi_index = rdp.ci_count-1; + FRDP("rdp.frame_buffers[%d].status = ci_zcopy\n", rdp.ci_count); + } + else if (rdp.main_ci != 0) + { + if (rdp.cimg == rdp.main_ci) //switched to main fb again + { + cur_fb.height = max(cur_fb.height, rdp.frame_buffers[rdp.main_ci_index].height); + rdp.main_ci_index = rdp.ci_count; + rdp.main_ci_end = rdp.cimg + ((cur_fb.width * cur_fb.height) << cur_fb.size >> 1); + cur_fb.status = ci_main; + FRDP("rdp.frame_buffers[%d].status = ci_main\n", rdp.ci_count); + } + else // status is not known yet + { + cur_fb.status = ci_unknown; + } + } + else + { + if ((rdp.zimg != rdp.cimg))//&& (rdp.ocimg != rdp.cimg)) + { + rdp.main_ci = rdp.cimg; + rdp.main_ci_end = rdp.cimg + ((cur_fb.width * cur_fb.height) << cur_fb.size >> 1); + rdp.main_ci_index = rdp.ci_count; + cur_fb.status = ci_main; + FRDP("rdp.frame_buffers[%d].status = ci_main\n", rdp.ci_count); + } + else + { + cur_fb.status = ci_unknown; + } + + } + if (rdp.ci_count > 0 && rdp.frame_buffers[rdp.ci_count-1].status == ci_unknown) //status of previous fb was not changed - it is useless + { + if (fb_hwfbe_enabled && !(settings.frame_buffer & fb_useless_is_useless)) + { + rdp.frame_buffers[rdp.ci_count-1].status = ci_aux; + rdp.frame_buffers[rdp.ci_count-1].changed = 0; + FRDP("rdp.frame_buffers[%d].status = ci_aux\n", rdp.ci_count-1); + } + else + { + rdp.frame_buffers[rdp.ci_count-1].status = ci_useless; + /* + wxUint32 addr = rdp.frame_buffers[rdp.ci_count-1].addr; + for (int i = 0; i < rdp.ci_count - 1; i++) + { + if (rdp.frame_buffers[i].addr == addr) + { + rdp.frame_buffers[rdp.ci_count-1].status = rdp.frame_buffers[i].status; + break; + } + } + //*/ + FRDP("rdp.frame_buffers[%d].status = %s\n", rdp.ci_count-1, CIStatus[rdp.frame_buffers[rdp.ci_count-1].status]); + } + } + if (cur_fb.status == ci_main) + { + int viSwapOK = ((settings.swapmode == 2) && (rdp.vi_org_reg == *gfx.VI_ORIGIN_REG)) ? FALSE : TRUE; + if ((rdp.maincimg[0].addr != cur_fb.addr) && SwapOK && viSwapOK) + { + SwapOK = FALSE; + rdp.swap_ci_index = rdp.ci_count; + } + } + rdp.ci_count++; + if (rdp.ci_count > NUMTEXBUF) //overflow + rdp.halt = 1; +} + +// RDP graphic instructions pointer table used in DetectFrameBufferUsage + +static rdp_instr gfx_instruction_lite[9][256] = +{ + { + // uCode 0 - RSP SW 2.0X + // 00-3f + // games: Super Mario 64, Tetrisphere, Demos + 0, 0, 0, 0, + 0, 0, uc0_displaylist, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + // 40-7f: Unused + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + // 80-bf: Immediate commands + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + uc0_enddl, 0, 0, 0, + fb_uc0_moveword, 0, uc0_culldl, 0, + // c0-ff: RDP commands + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + fb_rect, fb_rect, 0, 0, + 0, 0, 0, 0, + 0, fb_setscissor, 0, 0, + 0, 0, 0, 0, + 0, 0, fb_rect, 0, + 0, 0, 0, 0, + 0, fb_settextureimage, fb_setdepthimage, fb_setcolorimage + }, + + // uCode 1 - F3DEX 1.XX + // 00-3f + // games: Mario Kart, Star Fox + { + 0, 0, 0, 0, + 0, 0, uc0_displaylist, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + // 40-7f: unused + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + // 80-bf: Immediate commands + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, uc6_loaducode, + uc1_branch_z, 0, 0, 0, + fb_rdphalf_1, 0, 0, 0, + uc0_enddl, 0, 0, 0, + fb_uc0_moveword, 0, uc2_culldl, 0, + // c0-ff: RDP commands + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + fb_rect, fb_rect, 0, 0, + 0, 0, 0, 0, + 0, fb_setscissor, 0, 0, + 0, 0, 0, 0, + 0, 0, fb_rect, 0, + 0, 0, 0, 0, + 0, fb_settextureimage, fb_setdepthimage, fb_setcolorimage + }, + + // uCode 2 - F3DEX 2.XX + // games: Zelda 64 + { + // 00-3f + 0, 0, 0, uc2_culldl, + uc1_branch_z, 0, 0, 0, + 0, fb_bg_copy, fb_bg_copy, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + + // 40-7f: unused + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + + // 80-bf: unused + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + + // c0-ff: RDP commands mixed with uc2 commands + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, uc2_dlist_cnt, 0, 0, + 0, 0, 0, fb_uc2_moveword, + fb_uc2_movemem, uc2_load_ucode, uc0_displaylist, uc0_enddl, + 0, fb_rdphalf_1, 0, 0, + fb_rect, fb_rect, 0, 0, + 0, 0, 0, 0, + 0, fb_setscissor, 0, 0, + 0, 0, 0, 0, + 0, 0, fb_rect, 0, + 0, 0, 0, 0, + 0, fb_settextureimage, fb_setdepthimage, fb_setcolorimage + }, + + // uCode 3 - "RSP SW 2.0D", but not really + // 00-3f + // games: Wave Race + // ** Added by Gonetz ** + { + 0, 0, 0, 0, + 0, 0, uc0_displaylist, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + // 40-7f: unused + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + // 80-bf: Immediate commands + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + uc0_enddl, 0, 0, 0, + fb_uc0_moveword, 0, uc0_culldl, 0, + // c0-ff: RDP commands + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + fb_rect, fb_rect, 0, 0, + 0, 0, 0, 0, + 0, fb_setscissor, 0, 0, + 0, 0, 0, 0, + 0, 0, fb_rect, 0, + 0, 0, 0, 0, + 0, fb_settextureimage, fb_setdepthimage, fb_setcolorimage + }, + + { + // uCode 4 - RSP SW 2.0D EXT + // 00-3f + // games: Star Wars: Shadows of the Empire + 0, 0, 0, 0, + 0, 0, uc0_displaylist, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + // 40-7f: Unused + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + // 80-bf: Immediate commands + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + uc0_enddl, 0, 0, 0, + fb_uc0_moveword, 0, uc0_culldl, 0, + // c0-ff: RDP commands + rdp_noop, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + fb_rect, fb_rect, 0, 0, + 0, 0, 0, 0, + 0, fb_setscissor, 0, 0, + 0, 0, 0, 0, + 0, 0, fb_rect, 0, + 0, 0, 0, 0, + 0, fb_settextureimage, fb_setdepthimage, fb_setcolorimage + }, + + { + // uCode 5 - RSP SW 2.0 Diddy + // 00-3f + // games: Diddy Kong Racing + 0, 0, 0, 0, + 0, 0, uc0_displaylist, uc5_dl_in_mem, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + // 40-7f: Unused + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + // 80-bf: Immediate commands + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + uc0_enddl, 0, 0, 0, + fb_uc0_moveword, 0, uc0_culldl, 0, + // c0-ff: RDP commands + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + fb_rect, fb_rect, 0, 0, + 0, 0, 0, 0, + 0, fb_setscissor, 0, 0, + 0, 0, 0, 0, + 0, 0, fb_rect, 0, + 0, 0, 0, 0, + 0, fb_settextureimage, fb_setdepthimage, fb_setcolorimage + }, + + // uCode 6 - S2DEX 1.XX + // games: Yoshi's Story + { + 0, 0, 0, 0, + 0, 0, uc0_displaylist, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + // 40-7f: unused + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + // 80-bf: Immediate commands + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, uc6_loaducode, + uc6_select_dl, 0, 0, 0, + 0, 0, 0, 0, + uc0_enddl, 0, 0, 0, + fb_uc0_moveword, 0, uc2_culldl, 0, + // c0-ff: RDP commands + 0, fb_loadtxtr, fb_loadtxtr, fb_loadtxtr, + fb_loadtxtr, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + fb_rect, fb_rect, 0, 0, + 0, 0, 0, 0, + 0, fb_setscissor, 0, 0, + 0, 0, 0, 0, + 0, 0, fb_rect, 0, + 0, 0, 0, 0, + 0, fb_settextureimage, fb_setdepthimage, fb_setcolorimage + }, + + { + 0, 0, 0, 0, + 0, 0, uc0_displaylist, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + // 40-7f: unused + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + // 80-bf: Immediate commands + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + uc0_enddl, 0, 0, 0, + fb_uc0_moveword, 0, uc0_culldl, 0, + // c0-ff: RDP commands + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + fb_rect, fb_rect, 0, 0, + 0, 0, 0, 0, + 0, fb_setscissor, 0, 0, + 0, 0, 0, 0, + 0, 0, fb_rect, 0, + 0, 0, 0, 0, + 0, fb_settextureimage, fb_setdepthimage, fb_setcolorimage + }, + + { + // 00-3f + 0, 0, 0, uc2_culldl, + uc1_branch_z, 0, 0, 0, + 0, fb_bg_copy, fb_bg_copy, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + + // 40-7f: unused + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + + // 80-bf: unused + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + + // c0-ff: RDP commands mixed with uc2 commands + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, uc2_dlist_cnt, 0, 0, + 0, 0, 0, fb_uc2_moveword, + 0, uc2_load_ucode, uc0_displaylist, uc0_enddl, + 0, 0, 0, 0, + fb_rect, fb_rect, 0, 0, + 0, 0, 0, 0, + 0, fb_setscissor, 0, 0, + 0, 0, 0, 0, + 0, 0, fb_rect, 0, + 0, 0, 0, 0, + 0, fb_settextureimage, fb_setdepthimage, fb_setcolorimage + } +}; diff --git a/Source/Glide64/usa.xpm b/Source/Glide64/usa.xpm new file mode 100644 index 000000000..f38194564 --- /dev/null +++ b/Source/Glide64/usa.xpm @@ -0,0 +1,35 @@ +/* XPM */ +static const char *usa_xpm[]={ +"30 16 16 1", +" c #303F8B", +"0 c #27327A", +"1 c #D3332B", +"2 c #1A2A7A", +"3 c #3A428E", +"4 c #F5CDCD", +"5 c #3A4A8E", +"6 c #EB8E8D", +"7 c #122272", +"8 c #E56A64", +"9 c #FBE1E1", +"a c #FBEEEE", +"b c #DE322A", +"c c #F3D6DB", +"d c #EA7A7A", +"e c #636DA9", +" 0 0 0 0 0 0111111111111111111", +"23 3 3 3 3 2444444444444444444", +"5 666666666666666666", +"73 7888888888888888888", +"3 3 9aaaaaaaaaaaaaaaa9", +"0535535355301bbbbbbbbbbbbbbbb1", +"05 3 3 3 3 0cccccccccccccccc94", +"3 3 3 3 3 dddddddddddddddddd", +"eeeeeeeeeeeedddddddddddddddddd", +"cc9c9c9c9c9c9c99c99c99c99c99cc", +"1bbbbbbbbbbbbbbbbbbbbbbbbbbbb1", +"99aaa9aa9aa9aaa9aa9aaa9aaa9aa9", +"888888888888888888888888888888", +"666666666666666666666666666666", +"444444444444444444444444444444", +"111111111111111111111111111111"};