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)/*&§ionno<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