1 /*
2 Copyright (C) 2003 Rice1964
3 
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
8 
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 GNU General Public License for more details.
13 
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
17 
18 */
19 
20 #include <vector>
21 #include <fstream>
22 
23 #include <stdlib.h>
24 #include "../../libretro/libretro_private.h"
25 
26 #define M64P_PLUGIN_PROTOTYPES 1
27 #include "osal_preproc.h"
28 #include "m64p_types.h"
29 #include "m64p_plugin.h"
30 #include "m64p_config.h"
31 
32 #include "Config.h"
33 #include "Debugger.h"
34 #include "DeviceBuilder.h"
35 #include "RenderBase.h"
36 #include "TextureManager.h"
37 #include "Video.h"
38 
39 #ifdef _MSC_VER
40 #define strncasecmp _strnicmp
41 #endif
42 
43 
44 #define INI_FILE        "RiceVideoLinux.ini"
45 
46 #ifdef __cplusplus
47 extern "C" {
48 #endif
49 
50 extern uint32_t screen_width, screen_height;
51 extern retro_environment_t environ_cb;
52 
53 #ifdef __cplusplus
54 }
55 #endif
56 
57 static m64p_handle l_ConfigVideoRice = NULL;
58 static m64p_handle l_ConfigVideoGeneral = NULL;
59 
60 //static int FindIniEntry(uint32_t dwCRC1, uint32_t dwCRC2, uint8_t nCountryID, char* szName, int PrintInfo);
61 
62 const char *frameBufferSettings[] =
63 {
64 "None (default)",
65 "Hide Framebuffer Effects",
66 "Basic Framebuffer",
67 "Basic & Write Back",
68 "Write Back & Reload",
69 "Write Back Every Frame",
70 "With Emulator",
71 "Basic Framebuffer & With Emulator",
72 "With Emulator Read Only",
73 "With Emulator Write Only",
74 };
75 
76 const int resolutions[][2] =
77 {
78 {320, 240},
79 {400, 300},
80 {480, 360},
81 {512, 384},
82 {640, 480},
83 {800, 600},
84 {1024, 768},
85 {1152, 864},
86 {1280, 960},
87 {1400, 1050},
88 {1600, 1200},
89 {1920, 1440},
90 {2048, 1536},
91 };
92 const int numberOfResolutions = sizeof(resolutions)/sizeof(int)/2;
93 
94 const char* resolutionsS[] =
95 {
96 "320 x 240",
97 "400 x 300",
98 "480 x 360",
99 "512 x 384",
100 "640 x 480",
101 "800 x 600",
102 "1024 x 768",
103 "1152 x 864",
104 "1280 x 960",
105 "1400 x 1050",
106 "1600 x 1200",
107 "1920 x 1440",
108 "2048 x 1536"
109 };
110 
111 const char *frameBufferWriteBackControlSettings[] =
112 {
113 "Every Frame (default)",
114 "Every 2 Frames",
115 "Every 3 Frames",
116 "Every 4 Frames",
117 "Every 5 Frames",
118 "Every 6 Frames",
119 "Every 7 Frames",
120 "Every 8 Frames",
121 };
122 
123 const char *renderToTextureSettings[] =
124 {
125 "None (default)",
126 "Hide Render-to-texture Effects",
127 "Basic Render-to-texture",
128 "Basic & Write Back",
129 "Write Back & Reload",
130 };
131 
132 const char *screenUpdateSettings[] =
133 {
134 "At VI origin update",
135 "At VI origin change",
136 "At CI change",
137 "At the 1st CI change",
138 "At the 1st drawing",
139 "Before clear the screen",
140 "At VI origin update after screen is drawn (default)",
141 };
142 
143 WindowSettingStruct windowSetting;
144 GlobalOptions options;
145 RomOptions defaultRomOptions;
146 RomOptions currentRomOptions;
147 FrameBufferOptions frameBufferOptions;
148 //std::vector<IniSection> IniSections;
149 //bool    bIniIsChanged = false;
150 //char    szIniFileName[300];
151 
152 SettingInfo TextureQualitySettings[] =
153 {
154 {"Default", FORCE_DEFAULT_FILTER},
155 {"32-bit Texture", FORCE_POINT_FILTER},
156 {"16-bit Texture", FORCE_LINEAR_FILTER},
157 };
158 
159 SettingInfo ForceTextureFilterSettings[] =
160 {
161 {"N64 Default Texture Filter",  FORCE_DEFAULT_FILTER},
162 {"Force Nearest Filter (faster, low quality)", FORCE_POINT_FILTER},
163 {"Force Linear Filter (slower, better quality)", FORCE_LINEAR_FILTER},
164 };
165 
166 SettingInfo TextureEnhancementSettings[] =
167 {
168 {"N64 original texture (No enhancement)", TEXTURE_NO_ENHANCEMENT},
169 {"2x (Double the texture size)", TEXTURE_2X_ENHANCEMENT},
170 {"2xSaI", TEXTURE_2XSAI_ENHANCEMENT},
171 {"hq2x", TEXTURE_HQ2X_ENHANCEMENT},
172 {"lq2x", TEXTURE_LQ2X_ENHANCEMENT},
173 {"hq4x", TEXTURE_HQ4X_ENHANCEMENT},
174 {"Sharpen", TEXTURE_SHARPEN_ENHANCEMENT},
175 {"Sharpen More", TEXTURE_SHARPEN_MORE_ENHANCEMENT},
176 };
177 
178 SettingInfo TextureEnhancementControlSettings[] =
179 {
180 {"Normal", TEXTURE_ENHANCEMENT_NORMAL},
181 {"Smooth", TEXTURE_ENHANCEMENT_WITH_SMOOTH_FILTER_1},
182 {"Less smooth", TEXTURE_ENHANCEMENT_WITH_SMOOTH_FILTER_2},
183 {"2xSaI smooth", TEXTURE_ENHANCEMENT_WITH_SMOOTH_FILTER_3},
184 {"Less 2xSaI smooth", TEXTURE_ENHANCEMENT_WITH_SMOOTH_FILTER_4},
185 };
186 
187 SettingInfo colorQualitySettings[] =
188 {
189 {"16-bit", TEXTURE_FMT_A4R4G4B4},
190 {"32-bit (def)", TEXTURE_FMT_A8R8G8B8},
191 };
192 
193 const char* strDXDeviceDescs[] = { "HAL", "REF" };
194 
195 SettingInfo openGLDepthBufferSettings[] =
196 {
197 {"16-bit (def)", 16},
198 {"32-bit", 32},
199 };
200 
201 RenderEngineSetting OpenGLRenderSettings[] =
202 {
203 {"To Fit Your Video Card", OGL_DEVICE},
204 {"OpenGL 1.1 (Lowest)",  OGL_1_1_DEVICE},
205 {"OpenGL 1.2/1.3", OGL_1_2_DEVICE},
206 {"OpenGL 1.4", OGL_1_4_DEVICE},
207 //{"OpenGL 1.4, the 2nd combiner",  OGL_1_4_V2_DEVICE},
208 {"OpenGL for Nvidia TNT or better", OGL_TNT2_DEVICE},
209 {"OpenGL for Nvidia GeForce or better ", NVIDIA_OGL_DEVICE},
210 {"OpenGL Fragment Program Extension", OGL_FRAGMENT_PROGRAM},
211 };
212 
213 SettingInfo OnScreenDisplaySettings[] =
214 {
215 {"Display Nothing", ONSCREEN_DISPLAY_NOTHING},
216 {"Display DList Per Second", ONSCREEN_DISPLAY_DLIST_PER_SECOND},
217 {"Display Frame Per Second", ONSCREEN_DISPLAY_FRAME_PER_SECOND},
218 {"Display Debug Information Only", ONSCREEN_DISPLAY_DEBUG_INFORMATION_ONLY},
219 {"Display Messages From CPU Core Only", ONSCREEN_DISPLAY_TEXT_FROM_CORE_ONLY},
220 {"Display DList Per Second With Core Msgs", ONSCREEN_DISPLAY_DLIST_PER_SECOND_WITH_CORE_MSG},
221 {"Display Frame Per Second With Core Msgs", ONSCREEN_DISPLAY_FRAME_PER_SECOND_WITH_CORE_MSG},
222 {"Display Debug Information With Core Msgs", ONSCREEN_DISPLAY_DEBUG_INFORMATION_WITH_CORE_MSG},
223 };
224 
225 const int numberOfOpenGLRenderEngineSettings = sizeof(OpenGLRenderSettings)/sizeof(RenderEngineSetting);
226 
GenerateFrameBufferOptions(void)227 void GenerateFrameBufferOptions(void)
228 {
229    // OpenGL does not support much yet
230    if( currentRomOptions.N64FrameBufferEmuType != FRM_BUF_NONE )
231       currentRomOptions.N64FrameBufferEmuType = FRM_BUF_IGNORE;
232    if( currentRomOptions.N64RenderToTextureEmuType != TXT_BUF_NONE )
233       currentRomOptions.N64RenderToTextureEmuType = TXT_BUF_IGNORE;
234 
235     frameBufferOptions.bUpdateCIInfo            = false;
236 
237     frameBufferOptions.bCheckBackBufs           = false;
238     frameBufferOptions.bWriteBackBufToRDRAM     = false;
239     frameBufferOptions.bLoadBackBufFromRDRAM    = false;
240 
241     frameBufferOptions.bIgnore                  = true;
242 
243     frameBufferOptions.bSupportRenderTextures           = false;
244     frameBufferOptions.bCheckRenderTextures         = false;
245     frameBufferOptions.bRenderTextureWriteBack          = false;
246     frameBufferOptions.bLoadRDRAMIntoRenderTexture      = false;
247 
248     frameBufferOptions.bProcessCPUWrite         = false;
249     frameBufferOptions.bProcessCPURead          = false;
250     frameBufferOptions.bAtEachFrameUpdate       = false;
251     frameBufferOptions.bIgnoreRenderTextureIfHeightUnknown      = false;
252 
253     switch( currentRomOptions.N64FrameBufferEmuType )
254     {
255     case FRM_BUF_NONE:
256         break;
257     case FRM_BUF_COMPLETE:
258         frameBufferOptions.bAtEachFrameUpdate       = true;
259         frameBufferOptions.bProcessCPUWrite         = true;
260         frameBufferOptions.bProcessCPURead          = true;
261         frameBufferOptions.bUpdateCIInfo            = true;
262         break;
263     case FRM_BUF_WRITEBACK_AND_RELOAD:
264         frameBufferOptions.bLoadBackBufFromRDRAM    = true;
265     case FRM_BUF_BASIC_AND_WRITEBACK:
266         frameBufferOptions.bWriteBackBufToRDRAM     = true;
267     case FRM_BUF_BASIC:
268         frameBufferOptions.bCheckBackBufs           = true;
269     case FRM_BUF_IGNORE:
270         frameBufferOptions.bUpdateCIInfo            = true;
271         break;
272     case FRM_BUF_BASIC_AND_WITH_EMULATOR:
273         // Banjo Kazooie
274         frameBufferOptions.bCheckBackBufs           = true;
275     case FRM_BUF_WITH_EMULATOR:
276         frameBufferOptions.bUpdateCIInfo            = true;
277         frameBufferOptions.bProcessCPUWrite         = true;
278         frameBufferOptions.bProcessCPURead          = true;
279         break;
280     case FRM_BUF_WITH_EMULATOR_READ_ONLY:
281         frameBufferOptions.bUpdateCIInfo            = true;
282         frameBufferOptions.bProcessCPURead          = true;
283         break;
284     case FRM_BUF_WITH_EMULATOR_WRITE_ONLY:
285         frameBufferOptions.bUpdateCIInfo            = true;
286         frameBufferOptions.bProcessCPUWrite         = true;
287         break;
288     }
289 
290     switch( currentRomOptions.N64RenderToTextureEmuType )
291     {
292     case TXT_BUF_NONE:
293         frameBufferOptions.bSupportRenderTextures           = false;
294         break;
295     case TXT_BUF_WRITE_BACK_AND_RELOAD:
296         frameBufferOptions.bLoadRDRAMIntoRenderTexture      = true;
297     case TXT_BUF_WRITE_BACK:
298         frameBufferOptions.bRenderTextureWriteBack          = true;
299     case TXT_BUF_NORMAL:
300         frameBufferOptions.bCheckRenderTextures         = true;
301         frameBufferOptions.bIgnore                  = false;
302     case TXT_BUF_IGNORE:
303         frameBufferOptions.bUpdateCIInfo            = true;
304         frameBufferOptions.bSupportRenderTextures           = true;
305         break;
306     }
307 
308     if( currentRomOptions.screenUpdateSetting >= SCREEN_UPDATE_AT_CI_CHANGE )
309     {
310         frameBufferOptions.bUpdateCIInfo = true;
311     }
312 }
313 
InitConfiguration(void)314 bool InitConfiguration(void)
315 {
316     if (ConfigOpenSection("Video-General", &l_ConfigVideoGeneral) != M64ERR_SUCCESS)
317     {
318         DebugMessage(M64MSG_ERROR, "Unable to open Video-General configuration section");
319         return false;
320     }
321     if (ConfigOpenSection("Video-Rice", &l_ConfigVideoRice) != M64ERR_SUCCESS)
322     {
323         DebugMessage(M64MSG_ERROR, "Unable to open Video-Rice configuration section");
324         return false;
325     }
326 
327     ConfigSetDefaultBool(l_ConfigVideoGeneral, "Fullscreen", 0, "Use fullscreen mode if True, or windowed mode if False ");
328     ConfigSetDefaultInt(l_ConfigVideoGeneral, "ScreenWidth", 640, "Width of output window or fullscreen width");
329     ConfigSetDefaultInt(l_ConfigVideoGeneral, "ScreenHeight", 480, "Height of output window or fullscreen height");
330     ConfigSetDefaultBool(l_ConfigVideoGeneral, "VerticalSync", 0, "If true, activate the SDL_GL_SWAP_CONTROL attribute");
331 
332     ConfigSetDefaultInt(l_ConfigVideoRice, "FrameBufferSetting", FRM_BUF_NONE, "Frame Buffer Emulation (0=ROM default, 1=disable)");
333     ConfigSetDefaultInt(l_ConfigVideoRice, "FrameBufferWriteBackControl", FRM_BUF_WRITEBACK_NORMAL, "Frequency to write back the frame buffer (0=every frame, 1=every other frame, etc)");
334     ConfigSetDefaultInt(l_ConfigVideoRice, "RenderToTexture", TXT_BUF_NONE, "Render-to-texture emulation (0=none, 1=ignore, 2=normal, 3=write back, 4=write back and reload)");
335 #if defined(WIN32)
336     ConfigSetDefaultInt(l_ConfigVideoRice, "ScreenUpdateSetting", SCREEN_UPDATE_AT_1ST_CI_CHANGE, "Control when the screen will be updated (0=ROM default, 1=VI origin update, 2=VI origin change, 3=CI change, 4=first CI change, 5=first primitive draw, 6=before screen clear, 7=after screen drawn)");  // SCREEN_UPDATE_AT_VI_UPDATE_AND_DRAWN
337 #else
338     ConfigSetDefaultInt(l_ConfigVideoRice, "ScreenUpdateSetting", SCREEN_UPDATE_AT_VI_UPDATE, "Control when the screen will be updated (0=ROM default, 1=VI origin update, 2=VI origin change, 3=CI change, 4=first CI change, 5=first primitive draw, 6=before screen clear, 7=after screen drawn)");  // SCREEN_UPDATE_AT_VI_UPDATE_AND_DRAWN
339 #endif
340     ConfigSetDefaultBool(l_ConfigVideoRice, "NormalAlphaBlender", false, "Force to use normal alpha blender");
341     ConfigSetDefaultBool(l_ConfigVideoRice, "FastTextureLoading", false, "Use a faster algorithm to speed up texture loading and CRC computation");
342     ConfigSetDefaultBool(l_ConfigVideoRice, "AccurateTextureMapping", true, "Use different texture coordinate clamping code");
343     ConfigSetDefaultBool(l_ConfigVideoRice, "InN64Resolution", false, "Force emulated frame buffers to be in N64 native resolution");
344     ConfigSetDefaultBool(l_ConfigVideoRice, "SaveVRAM", false, "Try to reduce Video RAM usage (should never be used)");
345     ConfigSetDefaultBool(l_ConfigVideoRice, "DoubleSizeForSmallTxtrBuf", false, "Enable this option to have better render-to-texture quality");
346     ConfigSetDefaultBool(l_ConfigVideoRice, "DefaultCombinerDisable", false, "Force to use normal color combiner");
347 
348     ConfigSetDefaultBool(l_ConfigVideoRice, "EnableHacks", true, "Enable game-specific settings from INI file");
349     ConfigSetDefaultBool(l_ConfigVideoRice, "WinFrameMode", false, "If enabled, graphics will be drawn in WinFrame mode instead of solid and texture mode");
350     ConfigSetDefaultBool(l_ConfigVideoRice, "FullTMEMEmulation", false, "N64 Texture Memory Full Emulation (may fix some games, may break others)");
351     ConfigSetDefaultBool(l_ConfigVideoRice, "OpenGLVertexClipper", false, "Enable vertex clipper for fog operations");
352     ConfigSetDefaultBool(l_ConfigVideoRice, "SkipFrame", false, "If this option is enabled, the plugin will skip every other frame");
353     ConfigSetDefaultBool(l_ConfigVideoRice, "TexRectOnly", false, "If enabled, texture enhancement will be done only for TxtRect ucode");
354     ConfigSetDefaultBool(l_ConfigVideoRice, "SmallTextureOnly", false, "If enabled, texture enhancement will be done only for textures width+height<=128");
355     ConfigSetDefaultBool(l_ConfigVideoRice, "LoadHiResCRCOnly", true, "Select hi-resolution textures based only on the CRC and ignore format+size information (Glide64 compatibility)");
356     ConfigSetDefaultBool(l_ConfigVideoRice, "LoadHiResTextures", false, "Enable hi-resolution texture file loading");
357     ConfigSetDefaultBool(l_ConfigVideoRice, "DumpTexturesToFiles", false, "Enable texture dumping");
358     ConfigSetDefaultBool(l_ConfigVideoRice, "ShowFPS", false, "Display On-screen FPS");
359 
360     ConfigSetDefaultInt(l_ConfigVideoRice, "Mipmapping", 2, "Use Mipmapping? 0=no, 1=nearest, 2=bilinear, 3=trilinear");
361     ConfigSetDefaultInt(l_ConfigVideoRice, "FogMethod", 0, "Enable, Disable or Force fog generation (0=Disable, 1=Enable n64 choose, 2=Force Fog)");
362     ConfigSetDefaultInt(l_ConfigVideoRice, "ForceTextureFilter", 0, "Force to use texture filtering or not (0=auto: n64 choose, 1=force no filtering, 2=force filtering)");
363     ConfigSetDefaultInt(l_ConfigVideoRice, "TextureEnhancement", 0, "Primary texture enhancement filter (0=None, 1=2X, 2=2XSAI, 3=HQ2X, 4=LQ2X, 5=HQ4X, 6=Sharpen, 7=Sharpen More, 8=External, 9=Mirrored)");
364     ConfigSetDefaultInt(l_ConfigVideoRice, "TextureEnhancementControl", 0, "Secondary texture enhancement filter (0 = none, 1-4 = filtered)");
365     ConfigSetDefaultInt(l_ConfigVideoRice, "TextureQuality", TXT_QUALITY_DEFAULT, "Color bit depth to use for textures (0=default, 1=32 bits, 2=16 bits)");
366     ConfigSetDefaultInt(l_ConfigVideoRice, "OpenGLDepthBufferSetting", 16, "Z-buffer depth (only 16 or 32)");
367     ConfigSetDefaultInt(l_ConfigVideoRice, "MultiSampling", 0, "Enable/Disable MultiSampling (0=off, 2,4,8,16=quality)");
368     ConfigSetDefaultInt(l_ConfigVideoRice, "ColorQuality", TEXTURE_FMT_A8R8G8B8, "Color bit depth for rendering window (0=32 bits, 1=16 bits)");
369     ConfigSetDefaultInt(l_ConfigVideoRice, "OpenGLRenderSetting", OGL_DEVICE, "OpenGL level to support (0=auto, 1=OGL_1.1, 2=OGL_1.2, 3=OGL_1.3, 4=OGL_1.4, 5=OGL_1.4_V2, 6=OGL_TNT2, 7=NVIDIA_OGL, 8=OGL_FRAGMENT_PROGRAM)");
370     return true;
371 }
372 
isMMXSupported()373 bool isMMXSupported()
374 {
375    unsigned cpu = 0;
376 
377    if (perf_get_cpu_features_cb)
378       cpu = perf_get_cpu_features_cb();
379 
380    if (cpu & RETRO_SIMD_MMX)
381       return true;
382 
383    return false;
384 }
385 
ReadConfiguration(void)386 static void ReadConfiguration(void)
387 {
388    struct retro_variable var = { "parallel-n64-screensize", 0 };
389    bool ret = environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var);
390 
391    if (ret && var.value)
392    {
393       if (sscanf(var.value ? var.value : "640x480", "%dx%d", &screen_width, &screen_height) != 2)
394       {
395          screen_width = 640;
396          screen_height = 480;
397       }
398    }
399    else
400    {
401       screen_width = 640;
402       screen_height =480;
403    }
404 
405    windowSetting.uDisplayWidth = screen_width;
406    windowSetting.uDisplayHeight = screen_height;
407    windowSetting.bVerticalSync = ConfigGetParamBool(l_ConfigVideoGeneral, "VerticalSync");
408 
409    defaultRomOptions.N64FrameBufferEmuType = ConfigGetParamInt(l_ConfigVideoRice, "FrameBufferSetting");
410    defaultRomOptions.N64FrameBufferWriteBackControl = ConfigGetParamInt(l_ConfigVideoRice, "FrameBufferWriteBackControl");
411    defaultRomOptions.N64RenderToTextureEmuType = ConfigGetParamInt(l_ConfigVideoRice, "RenderToTexture");
412    defaultRomOptions.screenUpdateSetting = ConfigGetParamInt(l_ConfigVideoRice, "screenUpdateSetting");
413 
414    defaultRomOptions.bNormalBlender = ConfigGetParamBool(l_ConfigVideoRice, "NormalAlphaBlender");
415    defaultRomOptions.bFastTexCRC = ConfigGetParamBool(l_ConfigVideoRice, "FastTextureLoading");
416    defaultRomOptions.bAccurateTextureMapping = ConfigGetParamBool(l_ConfigVideoRice, "AccurateTextureMapping");
417    defaultRomOptions.bInN64Resolution = ConfigGetParamBool(l_ConfigVideoRice, "InN64Resolution");
418    defaultRomOptions.bSaveVRAM = ConfigGetParamBool(l_ConfigVideoRice, "SaveVRAM");
419    defaultRomOptions.bDoubleSizeForSmallTxtrBuf = ConfigGetParamBool(l_ConfigVideoRice, "DoubleSizeForSmallTxtrBuf");
420    defaultRomOptions.bNormalCombiner = ConfigGetParamBool(l_ConfigVideoRice, "DefaultCombinerDisable");
421 
422    options.bEnableHacks = ConfigGetParamBool(l_ConfigVideoRice, "EnableHacks");
423    options.bWinFrameMode = ConfigGetParamBool(l_ConfigVideoRice, "WinFrameMode");
424    options.bFullTMEM = ConfigGetParamBool(l_ConfigVideoRice, "FullTMEMEmulation");
425    options.bOGLVertexClipper = ConfigGetParamBool(l_ConfigVideoRice, "OpenGLVertexClipper");
426    options.bSkipFrame = ConfigGetParamBool(l_ConfigVideoRice, "SkipFrame");
427    options.bTexRectOnly = ConfigGetParamBool(l_ConfigVideoRice, "TexRectOnly");
428    options.bSmallTextureOnly = ConfigGetParamBool(l_ConfigVideoRice, "SmallTextureOnly");
429    options.bLoadHiResTextures = ConfigGetParamBool(l_ConfigVideoRice, "LoadHiResTextures");
430    options.bLoadHiResCRCOnly = ConfigGetParamBool(l_ConfigVideoRice, "LoadHiResCRCOnly");
431    options.bDumpTexturesToFiles = ConfigGetParamBool(l_ConfigVideoRice, "DumpTexturesToFiles");
432 
433    options.mipmapping = TEXTURE_NO_MIPMAP;
434    //options.mipmapping = ConfigGetParamInt(l_ConfigVideoRice, "Mipmapping");
435    options.fogMethod = ConfigGetParamInt(l_ConfigVideoRice, "FogMethod");
436    options.forceTextureFilter = ConfigGetParamInt(l_ConfigVideoRice, "ForceTextureFilter");
437    options.textureEnhancement = ConfigGetParamInt(l_ConfigVideoRice, "TextureEnhancement");
438    options.textureEnhancementControl = ConfigGetParamInt(l_ConfigVideoRice, "TextureEnhancementControl");
439    options.textureQuality = ConfigGetParamInt(l_ConfigVideoRice, "TextureQuality");
440    options.OpenglDepthBufferSetting = ConfigGetParamInt(l_ConfigVideoRice, "OpenGLDepthBufferSetting");
441    options.multiSampling = ConfigGetParamInt(l_ConfigVideoRice, "MultiSampling");
442    options.colorQuality = ConfigGetParamInt(l_ConfigVideoRice, "ColorQuality");
443    options.OpenglRenderSetting = ConfigGetParamInt(l_ConfigVideoRice, "OpenGLRenderSetting");
444 
445    CDeviceBuilder::SelectDeviceType((SupportedDeviceType)options.OpenglRenderSetting);
446 
447    status.isMMXSupported = isMMXSupported();
448    ProcessVertexData = ProcessVertexDataNoSSE;
449 }
450 
LoadConfiguration(void)451 bool LoadConfiguration(void)
452 {
453 #if 0
454     IniSections.clear();
455     bIniIsChanged = false;
456     strcpy(szIniFileName, INI_FILE);
457 
458     if (!ReadIniFile())
459     {
460         DebugMessage(M64MSG_ERROR, "Unable to read ini file from disk");
461         return false;
462     }
463 #endif
464 
465     if (l_ConfigVideoGeneral == NULL || l_ConfigVideoRice == NULL)
466     {
467         DebugMessage(M64MSG_ERROR, "Rice Video configuration sections are not open!");
468         return false;
469     }
470 
471     // Read config parameters from core config API and set up internal variables
472     ReadConfiguration();
473 
474     return true;
475 }
476 
GenerateCurrentRomOptions()477 void GenerateCurrentRomOptions()
478 {
479     currentRomOptions.N64FrameBufferEmuType     =g_curRomInfo.dwFrameBufferOption;
480     currentRomOptions.N64FrameBufferWriteBackControl        =defaultRomOptions.N64FrameBufferWriteBackControl;
481     currentRomOptions.N64RenderToTextureEmuType =g_curRomInfo.dwRenderToTextureOption;
482     currentRomOptions.screenUpdateSetting       =g_curRomInfo.dwScreenUpdateSetting;
483     currentRomOptions.bNormalCombiner           =g_curRomInfo.dwNormalCombiner;
484     currentRomOptions.bNormalBlender            =g_curRomInfo.dwNormalBlender;
485     currentRomOptions.bFastTexCRC               =g_curRomInfo.dwFastTextureCRC;
486     currentRomOptions.bAccurateTextureMapping   =g_curRomInfo.dwAccurateTextureMapping;
487 
488     options.enableHackForGames = NO_HACK_FOR_GAME;
489     if ((strncmp((char*)g_curRomInfo.szGameName, "BANJO TOOIE", 11) == 0))
490     {
491         options.enableHackForGames = HACK_FOR_BANJO_TOOIE;
492     }
493     else if ((strncmp((char*)g_curRomInfo.szGameName, "DR.MARIO", 8) == 0))
494     {
495         options.enableHackForGames = HACK_FOR_DR_MARIO;
496     }
497     else if ((strncasecmp((char*)g_curRomInfo.szGameName, "Pilot", 5) == 0))
498     {
499         options.enableHackForGames = HACK_FOR_PILOT_WINGS;
500     }
501     else if ((strncasecmp((char*)g_curRomInfo.szGameName, "YOSHI", 5) == 0))
502     {
503         options.enableHackForGames = HACK_FOR_YOSHI;
504     }
505     else if ((strncasecmp((char*)g_curRomInfo.szGameName, "NITRO", 5) == 0))
506     {
507         options.enableHackForGames = HACK_FOR_NITRO;
508     }
509     else if ((strncasecmp((char*)g_curRomInfo.szGameName, "TONY HAWK", 9) == 0))
510     {
511         options.enableHackForGames = HACK_FOR_TONYHAWK;
512     }
513     else if ((strncasecmp((char*)g_curRomInfo.szGameName, "THPS", 4) == 0))
514     {
515         options.enableHackForGames = HACK_FOR_TONYHAWK;
516     }
517     else if ((strncasecmp((char*)g_curRomInfo.szGameName, "SPIDERMAN", 9) == 0))
518     {
519         options.enableHackForGames = HACK_FOR_TONYHAWK;
520     }
521     else if ((strncasecmp((char*)g_curRomInfo.szGameName, "NASCAR", 6) == 0))
522     {
523         options.enableHackForGames = HACK_FOR_NASCAR;
524     }
525     else if ((strstr((char*)g_curRomInfo.szGameName, "ZELDA") != 0) && (strstr((char*)g_curRomInfo.szGameName, "MASK") != 0))
526     {
527         options.enableHackForGames = HACK_FOR_ZELDA_MM;
528     }
529     else if ((strstr((char*)g_curRomInfo.szGameName, "ZELDA") != 0))
530     {
531         options.enableHackForGames = HACK_FOR_ZELDA;
532     }
533     else if ((strstr((char*)g_curRomInfo.szGameName, "Ogre") != 0))
534     {
535         options.enableHackForGames = HACK_FOR_OGRE_BATTLE;
536     }
537     else if ((strstr((char*)g_curRomInfo.szGameName, "TWINE") != 0))
538     {
539         options.enableHackForGames = HACK_FOR_TWINE;
540     }
541     else if ((strstr((char*)g_curRomInfo.szGameName, "Squadron") != 0))
542     {
543         options.enableHackForGames = HACK_FOR_ROGUE_SQUADRON;
544     }
545     else if ((strstr((char*)g_curRomInfo.szGameName, "Baseball") != 0) && (strstr((char*)g_curRomInfo.szGameName, "Star") != 0))
546     {
547         options.enableHackForGames = HACK_FOR_ALL_STAR_BASEBALL;
548     }
549     else if ((strstr((char*)g_curRomInfo.szGameName, "Tigger") != 0) && (strstr((char*)g_curRomInfo.szGameName, "Honey") != 0))
550     {
551         options.enableHackForGames = HACK_FOR_TIGER_HONEY_HUNT;
552     }
553     else if ((strstr((char*)g_curRomInfo.szGameName, "Bust") != 0) && (strstr((char*)g_curRomInfo.szGameName, "Move") != 0))
554     {
555         options.enableHackForGames = HACK_FOR_BUST_A_MOVE;
556     }
557     else if ((strncasecmp((char*)g_curRomInfo.szGameName, "MarioTennis",11) == 0))
558     {
559         options.enableHackForGames = HACK_FOR_MARIO_TENNIS;
560     }
561     else if ((strncasecmp((char*)g_curRomInfo.szGameName, "SUPER BOWLING",13) == 0))
562     {
563         options.enableHackForGames = HACK_FOR_SUPER_BOWLING;
564     }
565     else if ((strncasecmp((char*)g_curRomInfo.szGameName, "CONKER",6) == 0))
566     {
567         options.enableHackForGames = HACK_FOR_CONKER;
568     }
569     else if ((strncasecmp((char*)g_curRomInfo.szGameName, "MK_MYTHOLOGIES",14) == 0))
570     {
571         options.enableHackForGames = HACK_REVERSE_Y_COOR;
572     }
573     else if ((strncasecmp((char*)g_curRomInfo.szGameName, "Fighting Force",14) == 0))
574     {
575         options.enableHackForGames = HACK_REVERSE_XY_COOR;
576     }
577     else if ((strncasecmp((char*)g_curRomInfo.szGameName, "GOLDENEYE",9) == 0))
578     {
579         options.enableHackForGames = HACK_FOR_GOLDEN_EYE;
580     }
581     else if ((strncasecmp((char*)g_curRomInfo.szGameName, "F-ZERO",6) == 0))
582     {
583         options.enableHackForGames = HACK_FOR_FZERO;
584     }
585     else if ((strncasecmp((char*)g_curRomInfo.szGameName, "Command&Conquer",15) == 0))
586     {
587         options.enableHackForGames = HACK_FOR_COMMANDCONQUER;
588     }
589     else if ((strncasecmp((char*)g_curRomInfo.szGameName, "READY 2 RUMBLE",14) == 0))
590     {
591         options.enableHackForGames = HACK_FOR_RUMBLE;
592     }
593     else if ((strncasecmp((char*)g_curRomInfo.szGameName, "READY to RUMBLE",15) == 0))
594     {
595         options.enableHackForGames = HACK_FOR_RUMBLE;
596     }
597     else if ((strncasecmp((char*)g_curRomInfo.szGameName, "South Park Rally",16) == 0))
598     {
599         options.enableHackForGames = HACK_FOR_SOUTH_PARK_RALLY;
600     }
601     else if ((strncasecmp((char*)g_curRomInfo.szGameName, "Extreme G 2",11) == 0))
602     {
603         options.enableHackForGames = HACK_FOR_EXTREME_G2;
604     }
605     else if ((strncasecmp((char*)g_curRomInfo.szGameName, "MarioGolf64",11) == 0))
606     {
607         options.enableHackForGames = HACK_FOR_MARIO_GOLF;
608     }
609     else if ((strncasecmp((char*)g_curRomInfo.szGameName, "MLB FEATURING",13) == 0))
610     {
611         options.enableHackForGames = HACK_FOR_MLB;
612     }
613     else if ((strncasecmp((char*)g_curRomInfo.szGameName, "POLARISSNOCROSS",15) == 0))
614     {
615         options.enableHackForGames = HACK_FOR_POLARISSNOCROSS;
616     }
617     else if ((strncasecmp((char*)g_curRomInfo.szGameName, "TOP GEAR RALLY",14) == 0))
618     {
619         options.enableHackForGames = HACK_FOR_TOPGEARRALLY;
620     }
621     else if ((strncasecmp((char*)g_curRomInfo.szGameName, "DUKE NUKEM",10) == 0))
622     {
623         options.enableHackForGames = HACK_FOR_DUKE_NUKEM;
624     }
625     else if ((strncasecmp((char*)g_curRomInfo.szGameName, "MARIOKART64",11) == 0))
626     {
627         options.enableHackForGames = HACK_FOR_MARIO_KART;
628     }
629 
630     if (options.enableHackForGames != NO_HACK_FOR_GAME)
631         DebugMessage(M64MSG_INFO, "Enabled hacks for game: '%s'", g_curRomInfo.szGameName);
632 
633     if( currentRomOptions.N64FrameBufferEmuType == 0 )      currentRomOptions.N64FrameBufferEmuType = defaultRomOptions.N64FrameBufferEmuType;
634     else currentRomOptions.N64FrameBufferEmuType--;
635     if( currentRomOptions.N64RenderToTextureEmuType == 0 )  currentRomOptions.N64RenderToTextureEmuType = defaultRomOptions.N64RenderToTextureEmuType;
636     else currentRomOptions.N64RenderToTextureEmuType--;
637     if( currentRomOptions.screenUpdateSetting == 0 )        currentRomOptions.screenUpdateSetting = defaultRomOptions.screenUpdateSetting;
638 #if 0
639     if( currentRomOptions.bNormalCombiner == 0 )            currentRomOptions.bNormalCombiner = defaultRomOptions.bNormalCombiner;
640     else currentRomOptions.bNormalCombiner--;
641     if( currentRomOptions.bNormalBlender == 0 )             currentRomOptions.bNormalBlender = defaultRomOptions.bNormalBlender;
642     else currentRomOptions.bNormalBlender--;
643     if( currentRomOptions.bFastTexCRC == 0 )                currentRomOptions.bFastTexCRC = defaultRomOptions.bFastTexCRC;
644     else currentRomOptions.bFastTexCRC--;
645     if( currentRomOptions.bAccurateTextureMapping == 0 )    currentRomOptions.bAccurateTextureMapping = defaultRomOptions.bAccurateTextureMapping;
646     else currentRomOptions.bAccurateTextureMapping--;
647 #endif
648 
649     options.bUseFullTMEM = ((options.bFullTMEM && (g_curRomInfo.dwFullTMEM == 0)) || g_curRomInfo.dwFullTMEM == 2);
650 
651     GenerateFrameBufferOptions();
652 
653     if( options.enableHackForGames == HACK_FOR_MARIO_GOLF || options.enableHackForGames == HACK_FOR_MARIO_TENNIS )
654     {
655         frameBufferOptions.bIgnoreRenderTextureIfHeightUnknown = true;
656     }
657 }
658 
Ini_GetRomOptions(LPGAMESETTING pGameSetting)659 void Ini_GetRomOptions(LPGAMESETTING pGameSetting)
660 {
661 #if 0
662     int i;
663 
664     i = FindIniEntry(pGameSetting->romheader.dwCRC1,
665                      pGameSetting->romheader.dwCRC2,
666                      pGameSetting->romheader.nCountryID,
667                      (char*)pGameSetting->szGameName, 1);
668 
669     pGameSetting->bDisableTextureCRC    = IniSections[i].bDisableTextureCRC;
670     pGameSetting->bDisableCulling       = IniSections[i].bDisableCulling;
671     pGameSetting->bIncTexRectEdge       = IniSections[i].bIncTexRectEdge;
672     pGameSetting->bZHack                = IniSections[i].bZHack;
673     pGameSetting->bTextureScaleHack     = IniSections[i].bTextureScaleHack;
674     pGameSetting->bPrimaryDepthHack     = IniSections[i].bPrimaryDepthHack;
675     pGameSetting->bTexture1Hack         = IniSections[i].bTexture1Hack;
676     pGameSetting->bFastLoadTile         = IniSections[i].bFastLoadTile;
677     pGameSetting->bUseSmallerTexture    = IniSections[i].bUseSmallerTexture;
678 
679     pGameSetting->VIWidth               = IniSections[i].VIWidth;
680     pGameSetting->VIHeight              = IniSections[i].VIHeight;
681     pGameSetting->UseCIWidthAndRatio    = IniSections[i].UseCIWidthAndRatio;
682     pGameSetting->dwFullTMEM            = IniSections[i].dwFullTMEM;
683     pGameSetting->bTxtSizeMethod2       = IniSections[i].bTxtSizeMethod2;
684     pGameSetting->bEnableTxtLOD         = IniSections[i].bEnableTxtLOD;
685 
686     pGameSetting->dwFastTextureCRC      = IniSections[i].dwFastTextureCRC;
687     pGameSetting->bEmulateClear         = IniSections[i].bEmulateClear;
688     pGameSetting->bForceScreenClear     = IniSections[i].bForceScreenClear;
689     pGameSetting->dwAccurateTextureMapping  = IniSections[i].dwAccurateTextureMapping;
690     pGameSetting->dwNormalBlender       = IniSections[i].dwNormalBlender;
691     pGameSetting->bDisableBlender       = IniSections[i].bDisableBlender;
692     pGameSetting->dwNormalCombiner      = IniSections[i].dwNormalCombiner;
693     pGameSetting->bForceDepthBuffer     = IniSections[i].bForceDepthBuffer;
694     pGameSetting->bDisableObjBG         = IniSections[i].bDisableObjBG;
695     pGameSetting->dwFrameBufferOption   = IniSections[i].dwFrameBufferOption;
696     pGameSetting->dwRenderToTextureOption   = IniSections[i].dwRenderToTextureOption;
697     pGameSetting->dwScreenUpdateSetting = IniSections[i].dwScreenUpdateSetting;
698 #endif
699 }
700 
Ini_StoreRomOptions(LPGAMESETTING pGameSetting)701 void Ini_StoreRomOptions(LPGAMESETTING pGameSetting)
702 {
703 #if 0
704     int i;
705 
706     i = FindIniEntry(pGameSetting->romheader.dwCRC1,
707                      pGameSetting->romheader.dwCRC2,
708                      pGameSetting->romheader.nCountryID,
709                      (char*)pGameSetting->szGameName, 0);
710 
711     if( IniSections[i].bDisableTextureCRC   !=pGameSetting->bDisableTextureCRC )
712     {
713         IniSections[i].bDisableTextureCRC   =pGameSetting->bDisableTextureCRC    ;
714         bIniIsChanged=true;
715     }
716 
717     if( IniSections[i].bDisableCulling  !=pGameSetting->bDisableCulling )
718     {
719         IniSections[i].bDisableCulling  =pGameSetting->bDisableCulling   ;
720         bIniIsChanged=true;
721     }
722 
723     if( IniSections[i].dwFastTextureCRC !=pGameSetting->dwFastTextureCRC )
724     {
725         IniSections[i].dwFastTextureCRC =pGameSetting->dwFastTextureCRC      ;
726         bIniIsChanged=true;
727     }
728 
729     if( IniSections[i].bEmulateClear !=pGameSetting->bEmulateClear )
730     {
731         IniSections[i].bEmulateClear    =pGameSetting->bEmulateClear         ;
732         bIniIsChanged=true;
733     }
734 
735     if( IniSections[i].dwNormalBlender      !=pGameSetting->dwNormalBlender )
736     {
737         IniSections[i].dwNormalBlender      =pGameSetting->dwNormalBlender       ;
738         bIniIsChanged=true;
739     }
740 
741     if( IniSections[i].bDisableBlender  !=pGameSetting->bDisableBlender )
742     {
743         IniSections[i].bDisableBlender  =pGameSetting->bDisableBlender       ;
744         bIniIsChanged=true;
745     }
746 
747     if( IniSections[i].bForceScreenClear    !=pGameSetting->bForceScreenClear )
748     {
749         IniSections[i].bForceScreenClear    =pGameSetting->bForceScreenClear         ;
750         bIniIsChanged=true;
751     }
752     if( IniSections[i].dwAccurateTextureMapping !=pGameSetting->dwAccurateTextureMapping )
753     {
754         IniSections[i].dwAccurateTextureMapping =pGameSetting->dwAccurateTextureMapping      ;
755         bIniIsChanged=true;
756     }
757     if( IniSections[i].dwNormalCombiner !=pGameSetting->dwNormalCombiner )
758     {
759         IniSections[i].dwNormalCombiner =pGameSetting->dwNormalCombiner      ;
760         bIniIsChanged=true;
761     }
762     if( IniSections[i].bForceDepthBuffer    !=pGameSetting->bForceDepthBuffer )
763     {
764         IniSections[i].bForceDepthBuffer    =pGameSetting->bForceDepthBuffer         ;
765         bIniIsChanged=true;
766     }
767     if( IniSections[i].bDisableObjBG    !=pGameSetting->bDisableObjBG )
768     {
769         IniSections[i].bDisableObjBG    =pGameSetting->bDisableObjBG         ;
770         bIniIsChanged=true;
771     }
772     if( IniSections[i].dwFrameBufferOption  !=pGameSetting->dwFrameBufferOption )
773     {
774         IniSections[i].dwFrameBufferOption  =pGameSetting->dwFrameBufferOption       ;
775         bIniIsChanged=true;
776     }
777     if( IniSections[i].dwRenderToTextureOption  !=pGameSetting->dwRenderToTextureOption )
778     {
779         IniSections[i].dwRenderToTextureOption  =pGameSetting->dwRenderToTextureOption       ;
780         bIniIsChanged=true;
781     }
782     if( IniSections[i].dwScreenUpdateSetting    !=pGameSetting->dwScreenUpdateSetting )
783     {
784         IniSections[i].dwScreenUpdateSetting    =pGameSetting->dwScreenUpdateSetting         ;
785         bIniIsChanged=true;
786     }
787     if( IniSections[i].bIncTexRectEdge  != pGameSetting->bIncTexRectEdge )
788     {
789         IniSections[i].bIncTexRectEdge      =pGameSetting->bIncTexRectEdge;
790         bIniIsChanged=true;
791     }
792     if( IniSections[i].bZHack   != pGameSetting->bZHack )
793     {
794         IniSections[i].bZHack       =pGameSetting->bZHack;
795         bIniIsChanged=true;
796     }
797     if( IniSections[i].bTextureScaleHack    != pGameSetting->bTextureScaleHack )
798     {
799         IniSections[i].bTextureScaleHack        =pGameSetting->bTextureScaleHack;
800         bIniIsChanged=true;
801     }
802     if( IniSections[i].bPrimaryDepthHack    != pGameSetting->bPrimaryDepthHack )
803     {
804         IniSections[i].bPrimaryDepthHack        =pGameSetting->bPrimaryDepthHack;
805         bIniIsChanged=true;
806     }
807     if( IniSections[i].bTexture1Hack    != pGameSetting->bTexture1Hack )
808     {
809         IniSections[i].bTexture1Hack        =pGameSetting->bTexture1Hack;
810         bIniIsChanged=true;
811     }
812     if( IniSections[i].bFastLoadTile    != pGameSetting->bFastLoadTile )
813     {
814         IniSections[i].bFastLoadTile    =pGameSetting->bFastLoadTile;
815         bIniIsChanged=true;
816     }
817     if( IniSections[i].bUseSmallerTexture   != pGameSetting->bUseSmallerTexture )
818     {
819         IniSections[i].bUseSmallerTexture   =pGameSetting->bUseSmallerTexture;
820         bIniIsChanged=true;
821     }
822     if( IniSections[i].VIWidth  != pGameSetting->VIWidth )
823     {
824         IniSections[i].VIWidth  =pGameSetting->VIWidth;
825         bIniIsChanged=true;
826     }
827     if( IniSections[i].VIHeight != pGameSetting->VIHeight )
828     {
829         IniSections[i].VIHeight =pGameSetting->VIHeight;
830         bIniIsChanged=true;
831     }
832     if( IniSections[i].UseCIWidthAndRatio   != pGameSetting->UseCIWidthAndRatio )
833     {
834         IniSections[i].UseCIWidthAndRatio   =pGameSetting->UseCIWidthAndRatio;
835         bIniIsChanged=true;
836     }
837     if( IniSections[i].dwFullTMEM   != pGameSetting->dwFullTMEM )
838     {
839         IniSections[i].dwFullTMEM   =pGameSetting->dwFullTMEM;
840         bIniIsChanged=true;
841     }
842     if( IniSections[i].bTxtSizeMethod2  != pGameSetting->bTxtSizeMethod2 )
843     {
844         IniSections[i].bTxtSizeMethod2  =pGameSetting->bTxtSizeMethod2;
845         bIniIsChanged=true;
846     }
847     if( IniSections[i].bEnableTxtLOD    != pGameSetting->bEnableTxtLOD )
848     {
849         IniSections[i].bEnableTxtLOD    =pGameSetting->bEnableTxtLOD;
850         bIniIsChanged=true;
851     }
852 
853     if( bIniIsChanged )
854     {
855         WriteIniFile();
856         TRACE0("Rom option is changed and saved");
857     }
858 #endif
859 }
860 
861 //std::ifstream& getline( std::ifstream &is, char *str );
862 
863 #if 0
864 char * left(const char * src, int nchars)
865 {
866     static char dst[300];
867     strncpy(dst,src,nchars);
868     dst[nchars]=0;
869     return dst;
870 }
871 
872 char * right(const char *src, int nchars)
873 {
874     static char dst[300];
875     int srclen = strlen(src);
876     if (nchars >= srclen)
877     {
878         strcpy(dst, src);
879     }
880     else
881     {
882         strncpy(dst, src + srclen - nchars, nchars);
883         dst[nchars]=0;
884     }
885     return dst;
886 }
887 
888 char * tidy(char * s)
889 {
890     char * p = s + strlen(s);
891 
892     p--;
893     while (p >= s && (*p == ' ' || *p == 0xa || *p == '\n') )
894     {
895         *p = 0;
896         p--;
897     }
898     return s;
899 
900 }
901 
902 bool ReadIniFile()
903 {
904     std::ifstream inifile;
905     char readinfo[100];
906     const char *ini_filepath = ConfigGetSharedDataFilepath(szIniFileName);
907 
908     DebugMessage(M64MSG_VERBOSE, "Reading .ini file: %s", ini_filepath);
909     inifile.open(ini_filepath);
910 
911     if (inifile.fail())
912     {
913         return false;
914     }
915 
916     while (getline(inifile,readinfo)/*&&sectionno<999*/)
917     {
918         tidy(readinfo);
919 
920         if (readinfo[0] == '/')
921             continue;
922 
923         if (!strcasecmp(readinfo,"")==0)
924         {
925             if (readinfo[0] == '{') //if a section heading
926             {
927                 section newsection;
928 
929                 readinfo[strlen(readinfo)-1]='\0';
930                 strcpy(newsection.crccheck, readinfo+1);
931 
932                 newsection.bDisableTextureCRC = false;
933                 newsection.bDisableCulling = false;
934                 newsection.bIncTexRectEdge = false;
935                 newsection.bZHack = false;
936                 newsection.bTextureScaleHack = false;
937                 newsection.bFastLoadTile = false;
938                 newsection.bUseSmallerTexture = false;
939                 newsection.bPrimaryDepthHack = false;
940                 newsection.bTexture1Hack = false;
941                 newsection.bDisableObjBG = false;
942                 newsection.VIWidth = -1;
943                 newsection.VIHeight = -1;
944                 newsection.UseCIWidthAndRatio = NOT_USE_CI_WIDTH_AND_RATIO;
945                 newsection.dwFullTMEM = 0;
946                 newsection.bTxtSizeMethod2 = false;
947                 newsection.bEnableTxtLOD = false;
948 
949                 newsection.bEmulateClear = false;
950                 newsection.bForceScreenClear = false;
951                 newsection.bDisableBlender = false;
952                 newsection.bForceDepthBuffer = false;
953                 newsection.dwFastTextureCRC = 0;
954                 newsection.dwAccurateTextureMapping = 0;
955                 newsection.dwNormalBlender = 0;
956                 newsection.dwNormalCombiner = 0;
957                 newsection.dwFrameBufferOption = 0;
958                 newsection.dwRenderToTextureOption = 0;
959                 newsection.dwScreenUpdateSetting = 0;
960 
961 #if 0
962                 IniSections.push_back(newsection);
963 #endif
964 
965             }
966             else
967             {
968 #if 0
969                 int sectionno = IniSections.size() - 1;
970 
971                 if (strcasecmp(left(readinfo,4), "Name")==0)
972                     strcpy(IniSections[sectionno].name,right(readinfo,strlen(readinfo)-5));
973 
974                 if (strcasecmp(left(readinfo,17), "DisableTextureCRC")==0)
975                     IniSections[sectionno].bDisableTextureCRC=true;
976 
977                 if (strcasecmp(left(readinfo,14), "DisableCulling")==0)
978                     IniSections[sectionno].bDisableCulling=true;
979 
980                 if (strcasecmp(left(readinfo,16), "PrimaryDepthHack")==0)
981                     IniSections[sectionno].bPrimaryDepthHack=true;
982 
983                 if (strcasecmp(left(readinfo,12), "Texture1Hack")==0)
984                     IniSections[sectionno].bTexture1Hack=true;
985 
986                 if (strcasecmp(left(readinfo,12), "FastLoadTile")==0)
987                     IniSections[sectionno].bFastLoadTile=true;
988 
989                 if (strcasecmp(left(readinfo,17), "UseSmallerTexture")==0)
990                     IniSections[sectionno].bUseSmallerTexture=true;
991 
992                 if (strcasecmp(left(readinfo,14), "IncTexRectEdge")==0)
993                     IniSections[sectionno].bIncTexRectEdge=true;
994 
995                 if (strcasecmp(left(readinfo,5), "ZHack")==0)
996                     IniSections[sectionno].bZHack=true;
997 
998                 if (strcasecmp(left(readinfo,16), "TexRectScaleHack")==0)
999                     IniSections[sectionno].bTextureScaleHack=true;
1000 
1001                 if (strcasecmp(left(readinfo,7), "VIWidth")==0)
1002                     IniSections[sectionno].VIWidth = strtol(right(readinfo,3),NULL,10);
1003 
1004                 if (strcasecmp(left(readinfo,8), "VIHeight")==0)
1005                     IniSections[sectionno].VIHeight = strtol(right(readinfo,3),NULL,10);
1006 
1007                 if (strcasecmp(left(readinfo,18), "UseCIWidthAndRatio")==0)
1008                     IniSections[sectionno].UseCIWidthAndRatio = strtol(right(readinfo,1),NULL,10);
1009 
1010                 if (strcasecmp(left(readinfo,8), "FullTMEM")==0)
1011                     IniSections[sectionno].dwFullTMEM = strtol(right(readinfo,1),NULL,10);
1012 
1013                 if (strcasecmp(left(readinfo,24), "AlternativeTxtSizeMethod")==0)
1014                     IniSections[sectionno].bTxtSizeMethod2 = strtol(right(readinfo,1),NULL,10);
1015 
1016                 if (strcasecmp(left(readinfo,12), "EnableTxtLOD")==0)
1017                     IniSections[sectionno].bEnableTxtLOD = strtol(right(readinfo,1),NULL,10);
1018 
1019                 if (strcasecmp(left(readinfo,12), "DisableObjBG")==0)
1020                     IniSections[sectionno].bDisableObjBG = strtol(right(readinfo,1),NULL,10);
1021 
1022                 if (strcasecmp(left(readinfo,16), "ForceScreenClear")==0)
1023                     IniSections[sectionno].bForceScreenClear = strtol(right(readinfo,1),NULL,10);
1024 
1025                 if (strcasecmp(left(readinfo,22), "AccurateTextureMapping")==0)
1026                     IniSections[sectionno].dwAccurateTextureMapping = strtol(right(readinfo,1),NULL,10);
1027 
1028                 if (strcasecmp(left(readinfo,14), "FastTextureCRC")==0)
1029                     IniSections[sectionno].dwFastTextureCRC = strtol(right(readinfo,1),NULL,10);
1030 
1031                 if (strcasecmp(left(readinfo,12), "EmulateClear")==0)
1032                     IniSections[sectionno].bEmulateClear = strtol(right(readinfo,1),NULL,10);
1033 
1034                 if (strcasecmp(left(readinfo,18), "NormalAlphaBlender")==0)
1035                     IniSections[sectionno].dwNormalBlender = strtol(right(readinfo,1),NULL,10);
1036 
1037                 if (strcasecmp(left(readinfo,19), "DisableAlphaBlender")==0)
1038                     IniSections[sectionno].bDisableBlender = strtol(right(readinfo,1),NULL,10);
1039 
1040                 if (strcasecmp(left(readinfo,19), "NormalColorCombiner")==0)
1041                     IniSections[sectionno].dwNormalCombiner = strtol(right(readinfo,1),NULL,10);
1042 
1043                 if (strcasecmp(left(readinfo,16), "ForceDepthBuffer")==0)
1044                     IniSections[sectionno].bForceDepthBuffer = strtol(right(readinfo,1),NULL,10);
1045 
1046                 if (strcasecmp(left(readinfo,20), "FrameBufferEmulation")==0)
1047                     IniSections[sectionno].dwFrameBufferOption = strtol(readinfo+21,NULL,10);
1048 
1049                 if (strcasecmp(left(readinfo,15), "RenderToTexture")==0)
1050                     IniSections[sectionno].dwRenderToTextureOption = strtol(right(readinfo,1),NULL,10);
1051 
1052                 if (strcasecmp(left(readinfo,19), "ScreenUpdateSetting")==0)
1053                     IniSections[sectionno].dwScreenUpdateSetting = strtol(right(readinfo,1),NULL,10);
1054 #endif
1055             }
1056         }
1057     }
1058     //inifile.close();
1059 
1060     return true;
1061 }
1062 
1063 //read a line from the ini file
1064 std::ifstream & getline(std::ifstream & is, char *str)
1065 {
1066     char buf[100];
1067 
1068     is.getline(buf,100);
1069     strcpy( str,buf);
1070     return is;
1071 }
1072 
1073 void WriteIniFile()
1074 {
1075     uint32_t i;
1076     FILE * fhIn;
1077     FILE * fhOut;
1078 
1079     /* get path to game-hack INI file and read it */
1080     const char *ini_filepath = ConfigGetSharedDataFilepath(szIniFileName);
1081     if (ini_filepath == NULL)
1082         return;
1083     fhIn = fopen(ini_filepath, "r");
1084     if (fhIn == NULL)
1085         return;
1086     fseek(fhIn, 0L, SEEK_END);
1087     long filelen = ftell(fhIn);
1088     fseek(fhIn, 0L, SEEK_SET);
1089     char *chIniData = (char *) malloc(filelen + 1);
1090     if (chIniData == NULL)
1091     {
1092         fclose(fhIn);
1093         return;
1094     }
1095     long bytesread = fread(chIniData, 1, filelen, fhIn);
1096     fclose(fhIn);
1097     if (bytesread != filelen)
1098     {
1099         free(chIniData);
1100         return;
1101     }
1102     chIniData[filelen] = 0;
1103 
1104     /* now try to open the file for writing */
1105     fhOut = fopen(ini_filepath, "w");
1106     if (fhOut == NULL)
1107     {
1108         free(chIniData);
1109         return;
1110     }
1111 
1112     // Mark all sections and needing to be written
1113     for (i = 0; i < IniSections.size(); i++)
1114     {
1115         IniSections[i].bOutput = false;
1116     }
1117 
1118     char *thisline = chIniData;
1119     while ((thisline - chIniData) < filelen)
1120     {
1121         char *nextline = strchr(thisline, '\n');
1122         if (nextline == NULL)
1123             nextline = thisline + strlen(thisline) + 1;
1124         else
1125             nextline++;
1126         if (thisline[0] == '{')
1127         {
1128             bool bFound = false;
1129             // Start of section
1130             tidy((char*) thisline);
1131             thisline[strlen(thisline) - 1] = '\0';
1132             for (i = 0; i < IniSections.size(); i++)
1133             {
1134                 if (IniSections[i].bOutput)
1135                     continue;
1136                 if (strcasecmp((char*) thisline + 1, IniSections[i].crccheck) == 0)
1137                 {
1138                     // Output this CRC
1139                     OutputSectionDetails(i, fhOut);
1140                     IniSections[i].bOutput = true;
1141                     bFound = true;
1142                     break;
1143                 }
1144             }
1145             if (!bFound)
1146             {
1147                 // Do what? This should never happen, unless the user
1148                 // replaces the inifile while game is running!
1149             }
1150         }
1151         else if (thisline[0] == '/')
1152         {
1153             // Comment
1154             fputs((char*) thisline, fhOut);
1155         }
1156         thisline = nextline;
1157     }
1158 
1159     // Input buffer done-  process any new entries!
1160     for (i = 0; i < IniSections.size(); i++)
1161     {
1162         // Skip any that have not been done.
1163         if (IniSections[i].bOutput)
1164             continue;
1165         // Output this CRC
1166         OutputSectionDetails(i, fhOut);
1167         IniSections[i].bOutput = true;
1168     }
1169 
1170     fclose(fhOut);
1171     free(chIniData);
1172 
1173     bIniIsChanged = false;
1174 }
1175 
1176 void OutputSectionDetails(uint32_t i, FILE * fh)
1177 {
1178     fprintf(fh, "{%s}\n", IniSections[i].crccheck);
1179 
1180     fprintf(fh, "Name=%s\n", IniSections[i].name);
1181     //fprintf(fh, "UCode=%d\n", IniSections[i].ucode);
1182 
1183     // Tri-state variables
1184     if (IniSections[i].dwAccurateTextureMapping != 0)
1185         fprintf(fh, "AccurateTextureMapping=%d\n", IniSections[i].dwAccurateTextureMapping);
1186 
1187     if (IniSections[i].dwFastTextureCRC != 0)
1188         fprintf(fh, "FastTextureCRC=%d\n", IniSections[i].dwFastTextureCRC);
1189 
1190     if (IniSections[i].dwNormalBlender != 0)
1191         fprintf(fh, "NormalAlphaBlender=%d\n", IniSections[i].dwNormalBlender);
1192 
1193     if (IniSections[i].dwNormalCombiner != 0)
1194         fprintf(fh, "NormalColorCombiner=%d\n", IniSections[i].dwNormalCombiner);
1195 
1196 
1197     // Normal bi-state variables
1198     if (IniSections[i].bDisableTextureCRC)
1199         fprintf(fh, "DisableTextureCRC\n");
1200 
1201     if (IniSections[i].bDisableCulling)
1202         fprintf(fh, "DisableCulling\n");
1203 
1204     if (IniSections[i].bPrimaryDepthHack)
1205         fprintf(fh, "PrimaryDepthHack\n");
1206 
1207     if (IniSections[i].bTexture1Hack)
1208         fprintf(fh, "Texture1Hack\n");
1209 
1210     if (IniSections[i].bFastLoadTile)
1211         fprintf(fh, "FastLoadTile\n");
1212 
1213     if (IniSections[i].bUseSmallerTexture)
1214         fprintf(fh, "UseSmallerTexture\n");
1215 
1216     if (IniSections[i].bIncTexRectEdge)
1217         fprintf(fh, "IncTexRectEdge\n");
1218 
1219     if (IniSections[i].bZHack)
1220         fprintf(fh, "ZHack\n");
1221 
1222     if (IniSections[i].bTextureScaleHack)
1223         fprintf(fh, "TexRectScaleHack\n");
1224 
1225     if (IniSections[i].VIWidth > 0)
1226         fprintf(fh, "VIWidth=%d\n", IniSections[i].VIWidth);
1227 
1228     if (IniSections[i].VIHeight > 0)
1229         fprintf(fh, "VIHeight=%d\n", IniSections[i].VIHeight);
1230 
1231     if (IniSections[i].UseCIWidthAndRatio > 0)
1232         fprintf(fh, "UseCIWidthAndRatio=%d\n", IniSections[i].UseCIWidthAndRatio);
1233 
1234     if (IniSections[i].dwFullTMEM > 0)
1235         fprintf(fh, "FullTMEM=%d\n", IniSections[i].dwFullTMEM);
1236 
1237     if (IniSections[i].bTxtSizeMethod2 != false )
1238         fprintf(fh, "AlternativeTxtSizeMethod=%d\n", IniSections[i].bTxtSizeMethod2);
1239 
1240     if (IniSections[i].bEnableTxtLOD != false )
1241         fprintf(fh, "EnableTxtLOD=%d\n", IniSections[i].bEnableTxtLOD);
1242 
1243     if (IniSections[i].bDisableObjBG != 0 )
1244         fprintf(fh, "DisableObjBG=%d\n", IniSections[i].bDisableObjBG);
1245 
1246     if (IniSections[i].bForceScreenClear != 0)
1247         fprintf(fh, "ForceScreenClear=%d\n", IniSections[i].bForceScreenClear);
1248 
1249     if (IniSections[i].bEmulateClear != 0)
1250         fprintf(fh, "EmulateClear=%d\n", IniSections[i].bEmulateClear);
1251 
1252     if (IniSections[i].bDisableBlender != 0)
1253         fprintf(fh, "DisableAlphaBlender=%d\n", IniSections[i].bDisableBlender);
1254 
1255     if (IniSections[i].bForceDepthBuffer != 0)
1256         fprintf(fh, "ForceDepthBuffer=%d\n", IniSections[i].bForceDepthBuffer);
1257 
1258     if (IniSections[i].dwFrameBufferOption != 0)
1259         fprintf(fh, "FrameBufferEmulation=%d\n", IniSections[i].dwFrameBufferOption);
1260 
1261     if (IniSections[i].dwRenderToTextureOption != 0)
1262         fprintf(fh, "RenderToTexture=%d\n", IniSections[i].dwRenderToTextureOption);
1263 
1264     if (IniSections[i].dwScreenUpdateSetting != 0)
1265         fprintf(fh, "ScreenUpdateSetting=%d\n", IniSections[i].dwScreenUpdateSetting);
1266 
1267     fprintf(fh, "\n");          // Spacer
1268 }
1269 
1270 // Find the entry corresponding to the specified rom.
1271 // If the rom is not found, a new entry is created
1272 // The resulting value is returned
1273 void __cdecl DebuggerAppendMsg (const char * Message, ...);
1274 
1275 static int FindIniEntry(uint32_t dwCRC1, uint32_t dwCRC2, uint8_t nCountryID, char* szName, int PrintInfo)
1276 {
1277     uint32_t i;
1278     unsigned char szCRC[50+1];
1279 
1280     // Generate the CRC-ID for this rom:
1281     sprintf((char*)szCRC, "%08x%08x-%02x", (unsigned int)dwCRC1, (unsigned int)dwCRC2, nCountryID);
1282 
1283     for (i = 0; i < IniSections.size(); i++)
1284     {
1285         if (strcasecmp((char*)szCRC, IniSections[i].crccheck) == 0)
1286         {
1287             if (PrintInfo)
1288                 DebugMessage(M64MSG_INFO, "Found ROM '%s', CRC %s", IniSections[i].name, szCRC);
1289             return i;
1290         }
1291     }
1292 
1293     // Add new entry!!!
1294     section newsection;
1295 
1296     if (PrintInfo)
1297         DebugMessage(M64MSG_INFO, "ROM (CRC %s) not found in INI file", szCRC);
1298 
1299     strcpy(newsection.crccheck, (char*)szCRC);
1300 
1301     strncpy(newsection.name, szName, 50);
1302     newsection.bDisableTextureCRC = false;
1303     newsection.bDisableCulling = false;
1304     newsection.bIncTexRectEdge = false;
1305     newsection.bZHack = false;
1306     newsection.bTextureScaleHack = false;
1307     newsection.bFastLoadTile = false;
1308     newsection.bUseSmallerTexture = false;
1309     newsection.bPrimaryDepthHack = false;
1310     newsection.bTexture1Hack = false;
1311     newsection.bDisableObjBG = false;
1312     newsection.VIWidth = -1;
1313     newsection.VIHeight = -1;
1314     newsection.UseCIWidthAndRatio = NOT_USE_CI_WIDTH_AND_RATIO;
1315     newsection.dwFullTMEM = 0;
1316     newsection.bTxtSizeMethod2 = false;
1317     newsection.bEnableTxtLOD = false;
1318 
1319     newsection.bEmulateClear = false;
1320     newsection.bForceScreenClear = false;
1321     newsection.bDisableBlender = false;
1322     newsection.bForceDepthBuffer = false;
1323     newsection.dwFastTextureCRC = 0;
1324     newsection.dwAccurateTextureMapping = 0;
1325     newsection.dwNormalBlender = 0;
1326     newsection.dwNormalCombiner = 0;
1327     newsection.dwFrameBufferOption = 0;
1328     newsection.dwRenderToTextureOption = 0;
1329     newsection.dwScreenUpdateSetting = 0;
1330 
1331     IniSections.push_back(newsection);
1332 
1333     bIniIsChanged = true;               // Flag to indicate we should be updated
1334     return IniSections.size()-1;            // -1 takes into account increment
1335 }
1336 #endif
1337 
1338 GameSetting g_curRomInfo;
1339 
ROM_GetRomNameFromHeader(unsigned char * szName,ROMHeader * pHdr)1340 void ROM_GetRomNameFromHeader(unsigned char * szName, ROMHeader * pHdr)
1341 {
1342     unsigned char * p;
1343 
1344     memcpy(szName, pHdr->szName, 20);
1345     szName[20] = '\0';
1346 
1347     p = szName + (strlen((char*)szName) -1);        // -1 to skip null
1348     while (p >= szName && *p == ' ')
1349     {
1350         *p = 0;
1351         p--;
1352     }
1353 }
1354 
CountryCodeToTVSystem(uint32_t countryCode)1355 uint32_t CountryCodeToTVSystem(uint32_t countryCode)
1356 {
1357     uint32_t system;
1358     switch(countryCode)
1359     {
1360         /* Demo */
1361     case 0:
1362         system = TV_SYSTEM_NTSC;
1363         break;
1364 
1365     case '7':
1366         system = TV_SYSTEM_NTSC;
1367         break;
1368 
1369     case 0x41:
1370         system = TV_SYSTEM_NTSC;
1371         break;
1372 
1373         /* Germany */
1374     case 0x44:
1375         system = TV_SYSTEM_PAL;
1376         break;
1377 
1378         /* USA */
1379     case 0x45:
1380         system = TV_SYSTEM_NTSC;
1381         break;
1382 
1383         /* France */
1384     case 0x46:
1385         system = TV_SYSTEM_PAL;
1386         break;
1387 
1388         /* Italy */
1389     case 'I':
1390         system = TV_SYSTEM_PAL;
1391         break;
1392 
1393         /* Japan */
1394     case 0x4A:
1395         system = TV_SYSTEM_NTSC;
1396         break;
1397 
1398         /* Europe - PAL */
1399     case 0x50:
1400         system = TV_SYSTEM_PAL;
1401         break;
1402 
1403     case 'S':   /* Spain */
1404         system = TV_SYSTEM_PAL;
1405         break;
1406 
1407         /* Australia */
1408     case 0x55:
1409         system = TV_SYSTEM_PAL;
1410         break;
1411 
1412     case 0x58:
1413         system = TV_SYSTEM_PAL;
1414         break;
1415 
1416         /* Australia */
1417     case 0x59:
1418         system = TV_SYSTEM_PAL;
1419         break;
1420 
1421     case 0x20:
1422     case 0x21:
1423     case 0x38:
1424     case 0x70:
1425         system = TV_SYSTEM_PAL;
1426         break;
1427 
1428         /* ??? */
1429     default:
1430         system = TV_SYSTEM_PAL;
1431         break;
1432     }
1433 
1434     return system;
1435 }
1436 
1437 
1438