2 Copyright (C) 2003 Rice1964
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.
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.
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.
25 #define M64P_PLUGIN_PROTOTYPES 1
26 #include "osal_preproc.h"
27 #include "m64p_types.h"
28 #include "m64p_plugin.h"
29 #include "m64p_config.h"
33 #include "DeviceBuilder.h"
34 #include "RenderBase.h"
35 #include "TextureManager.h"
38 #define INI_FILE "RiceVideoLinux.ini"
40 static m64p_handle l_ConfigVideoRice = NULL;
41 static m64p_handle l_ConfigVideoGeneral = NULL;
43 static int FindIniEntry(uint32 dwCRC1, uint32 dwCRC2, uint8 nCountryID, char* szName, int PrintInfo);
45 const char *frameBufferSettings[] =
48 "Hide Framebuffer Effects",
51 "Write Back & Reload",
52 "Write Back Every Frame",
54 "Basic Framebuffer & With Emulator",
55 "With Emulator Read Only",
56 "With Emulator Write Only",
59 const int resolutions[][2] =
76 const int numberOfResolutions = sizeof(resolutions)/sizeof(int)/2;
78 const char* resolutionsS[] =
96 const char *frameBufferWriteBackControlSettings[] =
98 "Every Frame (default)",
108 const char *renderToTextureSettings[] =
111 "Hide Render-to-texture Effects",
112 "Basic Render-to-texture",
113 "Basic & Write Back",
114 "Write Back & Reload",
117 const char *screenUpdateSettings[] =
119 "At VI origin update",
120 "At VI origin change",
122 "At the 1st CI change",
123 "At the 1st drawing",
124 "Before clear the screen",
125 "At VI origin update after screen is drawn (default)",
128 WindowSettingStruct windowSetting;
129 GlobalOptions options;
130 RomOptions defaultRomOptions;
131 RomOptions currentRomOptions;
132 FrameBufferOptions frameBufferOptions;
133 std::vector<IniSection> IniSections;
134 bool bIniIsChanged = false;
135 char szIniFileName[300];
137 SettingInfo TextureQualitySettings[] =
139 {"Default", FORCE_DEFAULT_FILTER},
140 {"32-bit Texture", FORCE_POINT_FILTER},
141 {"16-bit Texture", FORCE_LINEAR_FILTER},
144 SettingInfo ForceTextureFilterSettings[] =
146 {"N64 Default Texture Filter", FORCE_DEFAULT_FILTER},
147 {"Force Nearest Filter (faster, low quality)", FORCE_POINT_FILTER},
148 {"Force Linear Filter (slower, better quality)", FORCE_LINEAR_FILTER},
151 SettingInfo TextureEnhancementSettings[] =
153 {"N64 original texture (No enhancement)", TEXTURE_NO_ENHANCEMENT},
154 {"2x (Double the texture size)", TEXTURE_2X_ENHANCEMENT},
155 {"2xSaI", TEXTURE_2XSAI_ENHANCEMENT},
156 {"hq2x", TEXTURE_HQ2X_ENHANCEMENT},
157 {"lq2x", TEXTURE_LQ2X_ENHANCEMENT},
158 {"hq4x", TEXTURE_HQ4X_ENHANCEMENT},
159 {"Sharpen", TEXTURE_SHARPEN_ENHANCEMENT},
160 {"Sharpen More", TEXTURE_SHARPEN_MORE_ENHANCEMENT},
163 SettingInfo TextureEnhancementControlSettings[] =
165 {"Normal", TEXTURE_ENHANCEMENT_NORMAL},
166 {"Smooth", TEXTURE_ENHANCEMENT_WITH_SMOOTH_FILTER_1},
167 {"Less smooth", TEXTURE_ENHANCEMENT_WITH_SMOOTH_FILTER_2},
168 {"2xSaI smooth", TEXTURE_ENHANCEMENT_WITH_SMOOTH_FILTER_3},
169 {"Less 2xSaI smooth", TEXTURE_ENHANCEMENT_WITH_SMOOTH_FILTER_4},
172 SettingInfo colorQualitySettings[] =
174 {"16-bit", TEXTURE_FMT_A4R4G4B4},
175 {"32-bit (def)", TEXTURE_FMT_A8R8G8B8},
178 const char* strDXDeviceDescs[] = { "HAL", "REF" };
180 SettingInfo openGLDepthBufferSettings[] =
182 {"16-bit (def)", 16},
186 RenderEngineSetting OpenGLRenderSettings[] =
188 {"To Fit Your Video Card", OGL_DEVICE},
189 {"OpenGL 1.1 (Lowest)", OGL_1_1_DEVICE},
190 {"OpenGL 1.2/1.3", OGL_1_2_DEVICE},
191 {"OpenGL 1.4", OGL_1_4_DEVICE},
192 {"OpenGL 1.4, the 2nd combiner", OGL_1_4_V2_DEVICE},
193 {"OpenGL for Nvidia TNT or better", OGL_TNT2_DEVICE},
194 {"OpenGL for Nvidia GeForce or better ", NVIDIA_OGL_DEVICE},
195 {"OpenGL Fragment Program Extension", OGL_FRAGMENT_PROGRAM},
198 SettingInfo OnScreenDisplaySettings[] =
200 {"Display Nothing", ONSCREEN_DISPLAY_NOTHING},
201 {"Display DList Per Second", ONSCREEN_DISPLAY_DLIST_PER_SECOND},
202 {"Display Frame Per Second", ONSCREEN_DISPLAY_FRAME_PER_SECOND},
203 {"Display Debug Information Only", ONSCREEN_DISPLAY_DEBUG_INFORMATION_ONLY},
204 {"Display Messages From CPU Core Only", ONSCREEN_DISPLAY_TEXT_FROM_CORE_ONLY},
205 {"Display DList Per Second With Core Msgs", ONSCREEN_DISPLAY_DLIST_PER_SECOND_WITH_CORE_MSG},
206 {"Display Frame Per Second With Core Msgs", ONSCREEN_DISPLAY_FRAME_PER_SECOND_WITH_CORE_MSG},
207 {"Display Debug Information With Core Msgs", ONSCREEN_DISPLAY_DEBUG_INFORMATION_WITH_CORE_MSG},
210 const int numberOfOpenGLRenderEngineSettings = sizeof(OpenGLRenderSettings)/sizeof(RenderEngineSetting);
212 void GenerateFrameBufferOptions(void)
214 if( CDeviceBuilder::GetGeneralDeviceType() == OGL_DEVICE )
216 // OpenGL does not support much yet
217 if( currentRomOptions.N64FrameBufferEmuType != FRM_BUF_NONE )
218 currentRomOptions.N64FrameBufferEmuType = FRM_BUF_IGNORE;
219 if( currentRomOptions.N64RenderToTextureEmuType != TXT_BUF_NONE )
220 currentRomOptions.N64RenderToTextureEmuType = TXT_BUF_IGNORE;
223 frameBufferOptions.bUpdateCIInfo = false;
225 frameBufferOptions.bCheckBackBufs = false;
226 frameBufferOptions.bWriteBackBufToRDRAM = false;
227 frameBufferOptions.bLoadBackBufFromRDRAM = false;
229 frameBufferOptions.bIgnore = true;
231 frameBufferOptions.bSupportRenderTextures = false;
232 frameBufferOptions.bCheckRenderTextures = false;
233 frameBufferOptions.bRenderTextureWriteBack = false;
234 frameBufferOptions.bLoadRDRAMIntoRenderTexture = false;
236 frameBufferOptions.bProcessCPUWrite = false;
237 frameBufferOptions.bProcessCPURead = false;
238 frameBufferOptions.bAtEachFrameUpdate = false;
239 frameBufferOptions.bIgnoreRenderTextureIfHeightUnknown = false;
241 switch( currentRomOptions.N64FrameBufferEmuType )
245 case FRM_BUF_COMPLETE:
246 frameBufferOptions.bAtEachFrameUpdate = true;
247 frameBufferOptions.bProcessCPUWrite = true;
248 frameBufferOptions.bProcessCPURead = true;
249 frameBufferOptions.bUpdateCIInfo = true;
251 case FRM_BUF_WRITEBACK_AND_RELOAD:
252 frameBufferOptions.bLoadBackBufFromRDRAM = true;
253 case FRM_BUF_BASIC_AND_WRITEBACK:
254 frameBufferOptions.bWriteBackBufToRDRAM = true;
256 frameBufferOptions.bCheckBackBufs = true;
258 frameBufferOptions.bUpdateCIInfo = true;
260 case FRM_BUF_BASIC_AND_WITH_EMULATOR:
262 frameBufferOptions.bCheckBackBufs = true;
263 case FRM_BUF_WITH_EMULATOR:
264 frameBufferOptions.bUpdateCIInfo = true;
265 frameBufferOptions.bProcessCPUWrite = true;
266 frameBufferOptions.bProcessCPURead = true;
268 case FRM_BUF_WITH_EMULATOR_READ_ONLY:
269 frameBufferOptions.bUpdateCIInfo = true;
270 frameBufferOptions.bProcessCPURead = true;
272 case FRM_BUF_WITH_EMULATOR_WRITE_ONLY:
273 frameBufferOptions.bUpdateCIInfo = true;
274 frameBufferOptions.bProcessCPUWrite = true;
278 switch( currentRomOptions.N64RenderToTextureEmuType )
281 frameBufferOptions.bSupportRenderTextures = false;
283 case TXT_BUF_WRITE_BACK_AND_RELOAD:
284 frameBufferOptions.bLoadRDRAMIntoRenderTexture = true;
285 case TXT_BUF_WRITE_BACK:
286 frameBufferOptions.bRenderTextureWriteBack = true;
288 frameBufferOptions.bCheckRenderTextures = true;
289 frameBufferOptions.bIgnore = false;
291 frameBufferOptions.bUpdateCIInfo = true;
292 frameBufferOptions.bSupportRenderTextures = true;
296 if( currentRomOptions.screenUpdateSetting >= SCREEN_UPDATE_AT_CI_CHANGE )
298 frameBufferOptions.bUpdateCIInfo = true;
302 BOOL InitConfiguration(void)
304 if (ConfigOpenSection("Video-General", &l_ConfigVideoGeneral) != M64ERR_SUCCESS)
306 DebugMessage(M64MSG_ERROR, "Unable to open Video-General configuration section");
309 if (ConfigOpenSection("Video-Rice", &l_ConfigVideoRice) != M64ERR_SUCCESS)
311 DebugMessage(M64MSG_ERROR, "Unable to open Video-Rice configuration section");
315 ConfigSetDefaultBool(l_ConfigVideoGeneral, "Fullscreen", 1, "Use fullscreen mode if True, or windowed mode if False ");
316 ConfigSetDefaultInt(l_ConfigVideoGeneral, "ScreenWidth", 640, "Width of output window or fullscreen width");
317 ConfigSetDefaultInt(l_ConfigVideoGeneral, "ScreenHeight", 480, "Height of output window or fullscreen height");
318 ConfigSetDefaultBool(l_ConfigVideoGeneral, "VerticalSync", 0, "If true, activate the SDL_GL_SWAP_CONTROL attribute");
320 ConfigSetDefaultInt(l_ConfigVideoRice, "FrameBufferSetting", FRM_BUF_NONE, "Frame Buffer Emulation (0=ROM default, 1=disable)");
321 ConfigSetDefaultInt(l_ConfigVideoRice, "FrameBufferWriteBackControl", FRM_BUF_WRITEBACK_NORMAL, "Frequency to write back the frame buffer (0=every frame, 1=every other frame, etc)");
322 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)");
324 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
326 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
328 ConfigSetDefaultBool(l_ConfigVideoRice, "NormalAlphaBlender", FALSE, "Force to use normal alpha blender");
329 ConfigSetDefaultBool(l_ConfigVideoRice, "FastTextureLoading", FALSE, "Use a faster algorithm to speed up texture loading and CRC computation");
330 ConfigSetDefaultBool(l_ConfigVideoRice, "AccurateTextureMapping", TRUE, "Use different texture coordinate clamping code");
331 ConfigSetDefaultBool(l_ConfigVideoRice, "InN64Resolution", FALSE, "Force emulated frame buffers to be in N64 native resolution");
332 ConfigSetDefaultBool(l_ConfigVideoRice, "SaveVRAM", FALSE, "Try to reduce Video RAM usage (should never be used)");
333 ConfigSetDefaultBool(l_ConfigVideoRice, "DoubleSizeForSmallTxtrBuf", FALSE, "Enable this option to have better render-to-texture quality");
334 ConfigSetDefaultBool(l_ConfigVideoRice, "DefaultCombinerDisable", FALSE, "Force to use normal color combiner");
336 ConfigSetDefaultBool(l_ConfigVideoRice, "EnableHacks", TRUE, "Enable game-specific settings from INI file");
337 ConfigSetDefaultBool(l_ConfigVideoRice, "WinFrameMode", FALSE, "If enabled, graphics will be drawn in WinFrame mode instead of solid and texture mode");
338 ConfigSetDefaultBool(l_ConfigVideoRice, "FullTMEMEmulation", FALSE, "N64 Texture Memory Full Emulation (may fix some games, may break others)");
339 ConfigSetDefaultBool(l_ConfigVideoRice, "OpenGLVertexClipper", FALSE, "Enable vertex clipper for fog operations");
340 ConfigSetDefaultBool(l_ConfigVideoRice, "EnableSSE", TRUE, "Enable/Disable SSE optimizations for capable CPUs");
341 ConfigSetDefaultBool(l_ConfigVideoRice, "EnableVertexShader", FALSE, "Use GPU vertex shader");
342 ConfigSetDefaultBool(l_ConfigVideoRice, "SkipFrame", FALSE, "If this option is enabled, the plugin will skip every other frame");
343 ConfigSetDefaultBool(l_ConfigVideoRice, "TexRectOnly", FALSE, "If enabled, texture enhancement will be done only for TxtRect ucode");
344 ConfigSetDefaultBool(l_ConfigVideoRice, "SmallTextureOnly", FALSE, "If enabled, texture enhancement will be done only for textures width+height<=128");
345 ConfigSetDefaultBool(l_ConfigVideoRice, "LoadHiResCRCOnly", TRUE, "Select hi-resolution textures based only on the CRC and ignore format+size information (Glide64 compatibility)");
346 ConfigSetDefaultBool(l_ConfigVideoRice, "LoadHiResTextures", FALSE, "Enable hi-resolution texture file loading");
347 ConfigSetDefaultBool(l_ConfigVideoRice, "DumpTexturesToFiles", FALSE, "Enable texture dumping");
348 ConfigSetDefaultBool(l_ConfigVideoRice, "ShowFPS", FALSE, "Display On-screen FPS");
350 ConfigSetDefaultInt(l_ConfigVideoRice, "Mipmapping", 2, "Use Mipmapping? 0=no, 1=nearest, 2=bilinear, 3=trilinear");
351 ConfigSetDefaultInt(l_ConfigVideoRice, "FogMethod", 0, "Enable, Disable or Force fog generation (0=Disable, 1=Enable n64 choose, 2=Force Fog)");
352 ConfigSetDefaultInt(l_ConfigVideoRice, "ForceTextureFilter", 0, "Force to use texture filtering or not (0=auto: n64 choose, 1=force no filtering, 2=force filtering)");
353 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)");
354 ConfigSetDefaultInt(l_ConfigVideoRice, "TextureEnhancementControl", 0, "Secondary texture enhancement filter (0 = none, 1-4 = filtered)");
355 ConfigSetDefaultInt(l_ConfigVideoRice, "TextureQuality", TXT_QUALITY_DEFAULT, "Color bit depth to use for textures (0=default, 1=32 bits, 2=16 bits)");
356 ConfigSetDefaultInt(l_ConfigVideoRice, "OpenGLDepthBufferSetting", 16, "Z-buffer depth (only 16 or 32)");
357 ConfigSetDefaultInt(l_ConfigVideoRice, "MultiSampling", 0, "Enable/Disable MultiSampling (0=off, 2,4,8,16=quality)");
358 ConfigSetDefaultInt(l_ConfigVideoRice, "ColorQuality", TEXTURE_FMT_A8R8G8B8, "Color bit depth for rendering window (0=32 bits, 1=16 bits)");
359 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)");
360 ConfigSetDefaultInt(l_ConfigVideoRice, "AnisotropicFiltering", 0, "Enable/Disable Anisotropic Filtering for Mipmapping (0=no filtering, 2-16=quality). This is uneffective if Mipmapping is 0. If the given value is to high to be supported by your graphic card, the value will be the highest value your graphic card can support. Better result with Trilinear filtering");
364 bool isMMXSupported()
366 int IsMMXSupported = 0;
368 #if !defined(__GNUC__) && !defined(NO_ASM)
371 mov eax,1 // CPUID level 1
372 cpuid // EDX = feature flag
373 and edx,0x800000 // test bit 23 of feature flag
374 mov IsMMXSupported,edx // != 0 if MMX is supported
376 #elif defined(__GNUC__) && defined(__x86_64__) && !defined(NO_ASM)
378 #elif !defined(NO_ASM) // GCC assumed
381 "mov $1, %%eax \n" // CPUID level 1
382 "cpuid \n" // EDX = feature flag
383 "and $0x800000, %%edx \n" // test bit 23 of feature flag
385 : "=d"(IsMMXSupported)
387 : "memory", "cc", "eax", "ecx"
390 if (IsMMXSupported != 0)
396 bool isSSESupported()
400 // And finally, check the CPUID for Streaming SIMD Extensions support.
401 #if !defined(__GNUC__) && !defined(NO_ASM)
404 mov eax, 1 // Put a "1" in eax to tell CPUID to get the feature bits
405 cpuid // Perform CPUID (puts processor feature info into EDX)
406 and edx, 02000000h // Test bit 25, for Streaming SIMD Extensions existence.
407 mov SSESupport, edx // SIMD Extensions). Set return value to 1 to indicate,
409 #elif defined(__GNUC__) && defined(__x86_64__) && !defined(NO_ASM)
411 #elif !defined(NO_ASM) // GCC assumed
414 "mov $1, %%eax \n" // Put a "1" in eax to tell CPUID to get the feature bits
415 "cpuid \n" // Perform CPUID (puts processor feature info into EDX)
416 "and $0x02000000, %%edx \n" // Test bit 25, for Streaming SIMD Extensions existence.
420 : "memory", "cc", "eax", "ecx"
430 static void ReadConfiguration(void)
432 windowSetting.bDisplayFullscreen = ConfigGetParamBool(l_ConfigVideoGeneral, "Fullscreen");
433 windowSetting.uDisplayWidth = ConfigGetParamInt(l_ConfigVideoGeneral, "ScreenWidth");
434 windowSetting.bDisplayRatio = true;
435 windowSetting.uDisplayX = 0;
436 windowSetting.uDisplayY = 0;
437 windowSetting.bDisplayRatio = ConfigGetParamBool(l_ConfigVideoGeneral, "AspectRatio");
438 if (windowSetting.bDisplayRatio) {
439 if (windowSetting.uDisplayWidth==800) {
440 windowSetting.uDisplayWidth = 640; // no strech
441 windowSetting.uDisplayX = 80;
444 windowSetting.uDisplayHeight = ConfigGetParamInt(l_ConfigVideoGeneral, "ScreenHeight");
445 windowSetting.bVerticalSync = ConfigGetParamBool(l_ConfigVideoGeneral, "VerticalSync");
447 defaultRomOptions.N64FrameBufferEmuType = ConfigGetParamInt(l_ConfigVideoRice, "FrameBufferSetting");
448 defaultRomOptions.N64FrameBufferWriteBackControl = ConfigGetParamInt(l_ConfigVideoRice, "FrameBufferWriteBackControl");
449 defaultRomOptions.N64RenderToTextureEmuType = ConfigGetParamInt(l_ConfigVideoRice, "RenderToTexture");
450 defaultRomOptions.screenUpdateSetting = ConfigGetParamInt(l_ConfigVideoRice, "screenUpdateSetting");
452 defaultRomOptions.bNormalBlender = ConfigGetParamBool(l_ConfigVideoRice, "NormalAlphaBlender");
453 defaultRomOptions.bFastTexCRC = ConfigGetParamBool(l_ConfigVideoRice, "FastTextureLoading");
454 defaultRomOptions.bAccurateTextureMapping = ConfigGetParamBool(l_ConfigVideoRice, "AccurateTextureMapping");
455 defaultRomOptions.bInN64Resolution = ConfigGetParamBool(l_ConfigVideoRice, "InN64Resolution");
456 defaultRomOptions.bSaveVRAM = ConfigGetParamBool(l_ConfigVideoRice, "SaveVRAM");
457 defaultRomOptions.bDoubleSizeForSmallTxtrBuf = ConfigGetParamBool(l_ConfigVideoRice, "DoubleSizeForSmallTxtrBuf");
458 defaultRomOptions.bNormalCombiner = ConfigGetParamBool(l_ConfigVideoRice, "DefaultCombinerDisable");
460 options.bEnableHacks = ConfigGetParamBool(l_ConfigVideoRice, "EnableHacks");
461 options.bWinFrameMode = ConfigGetParamBool(l_ConfigVideoRice, "WinFrameMode");
462 options.bFullTMEM = ConfigGetParamBool(l_ConfigVideoRice, "FullTMEMEmulation");
463 options.bOGLVertexClipper = ConfigGetParamBool(l_ConfigVideoRice, "OpenGLVertexClipper");
464 options.bEnableSSE = ConfigGetParamBool(l_ConfigVideoRice, "EnableSSE");
465 options.bEnableVertexShader = ConfigGetParamBool(l_ConfigVideoRice, "EnableVertexShader");
466 options.bSkipFrame = ConfigGetParamBool(l_ConfigVideoRice, "SkipFrame");
467 options.bTexRectOnly = ConfigGetParamBool(l_ConfigVideoRice, "TexRectOnly");
468 options.bSmallTextureOnly = ConfigGetParamBool(l_ConfigVideoRice, "SmallTextureOnly");
469 options.bLoadHiResTextures = ConfigGetParamBool(l_ConfigVideoRice, "LoadHiResTextures");
470 options.bLoadHiResCRCOnly = ConfigGetParamBool(l_ConfigVideoRice, "LoadHiResCRCOnly");
471 options.bDumpTexturesToFiles = ConfigGetParamBool(l_ConfigVideoRice, "DumpTexturesToFiles");
472 options.bShowFPS = ConfigGetParamBool(l_ConfigVideoRice, "ShowFPS");
474 options.mipmapping = ConfigGetParamInt(l_ConfigVideoRice, "Mipmapping");
475 options.fogMethod = ConfigGetParamInt(l_ConfigVideoRice, "FogMethod");
476 options.forceTextureFilter = ConfigGetParamInt(l_ConfigVideoRice, "ForceTextureFilter");
477 options.textureEnhancement = ConfigGetParamInt(l_ConfigVideoRice, "TextureEnhancement");
478 options.textureEnhancementControl = ConfigGetParamInt(l_ConfigVideoRice, "TextureEnhancementControl");
479 options.textureQuality = ConfigGetParamInt(l_ConfigVideoRice, "TextureQuality");
480 options.OpenglDepthBufferSetting = ConfigGetParamInt(l_ConfigVideoRice, "OpenGLDepthBufferSetting");
481 options.multiSampling = ConfigGetParamInt(l_ConfigVideoRice, "MultiSampling");
482 options.colorQuality = ConfigGetParamInt(l_ConfigVideoRice, "ColorQuality");
483 options.OpenglRenderSetting = ConfigGetParamInt(l_ConfigVideoRice, "OpenGLRenderSetting");
484 options.anisotropicFiltering = ConfigGetParamInt(l_ConfigVideoRice, "AnisotropicFiltering");
486 CDeviceBuilder::SelectDeviceType((SupportedDeviceType)options.OpenglRenderSetting);
488 status.isMMXSupported = isMMXSupported();
489 status.isSSESupported = isSSESupported();
490 status.isVertexShaderSupported = false;
492 status.isSSEEnabled = status.isSSESupported && options.bEnableSSE;
494 if( status.isSSEEnabled )
496 ProcessVertexData = ProcessVertexDataSSE;
497 DebugMessage(M64MSG_INFO, "SSE processing enabled.");
502 ProcessVertexData = ProcessVertexDataNoSSE;
503 DebugMessage(M64MSG_INFO, "Disabled SSE processing.");
506 status.isVertexShaderEnabled = status.isVertexShaderSupported && options.bEnableVertexShader;
507 status.bUseHW_T_L = false;
510 BOOL LoadConfiguration(void)
513 bIniIsChanged = false;
514 strcpy(szIniFileName, INI_FILE);
518 DebugMessage(M64MSG_ERROR, "Unable to read ini file from disk");
522 if (l_ConfigVideoGeneral == NULL || l_ConfigVideoRice == NULL)
524 DebugMessage(M64MSG_ERROR, "Rice Video configuration sections are not open!");
528 // Read config parameters from core config API and set up internal variables
534 void GenerateCurrentRomOptions()
536 currentRomOptions.N64FrameBufferEmuType =g_curRomInfo.dwFrameBufferOption;
537 currentRomOptions.N64FrameBufferWriteBackControl =defaultRomOptions.N64FrameBufferWriteBackControl;
538 currentRomOptions.N64RenderToTextureEmuType =g_curRomInfo.dwRenderToTextureOption;
539 currentRomOptions.screenUpdateSetting =g_curRomInfo.dwScreenUpdateSetting;
540 currentRomOptions.bNormalCombiner =g_curRomInfo.dwNormalCombiner;
541 currentRomOptions.bNormalBlender =g_curRomInfo.dwNormalBlender;
542 currentRomOptions.bFastTexCRC =g_curRomInfo.dwFastTextureCRC;
543 currentRomOptions.bAccurateTextureMapping =g_curRomInfo.dwAccurateTextureMapping;
545 options.enableHackForGames = NO_HACK_FOR_GAME;
546 if ((strncmp((char*)g_curRomInfo.szGameName, "BANJO TOOIE", 11) == 0))
548 options.enableHackForGames = HACK_FOR_BANJO_TOOIE;
550 else if ((strncmp((char*)g_curRomInfo.szGameName, "DR.MARIO", 8) == 0))
552 options.enableHackForGames = HACK_FOR_DR_MARIO;
554 else if ((strncasecmp((char*)g_curRomInfo.szGameName, "Pilot", 5) == 0))
556 options.enableHackForGames = HACK_FOR_PILOT_WINGS;
558 else if ((strncasecmp((char*)g_curRomInfo.szGameName, "YOSHI", 5) == 0))
560 options.enableHackForGames = HACK_FOR_YOSHI;
562 else if ((strncasecmp((char*)g_curRomInfo.szGameName, "NITRO", 5) == 0))
564 options.enableHackForGames = HACK_FOR_NITRO;
566 else if ((strncasecmp((char*)g_curRomInfo.szGameName, "TONY HAWK", 9) == 0))
568 options.enableHackForGames = HACK_FOR_TONYHAWK;
570 else if ((strncasecmp((char*)g_curRomInfo.szGameName, "THPS", 4) == 0))
572 options.enableHackForGames = HACK_FOR_TONYHAWK;
574 else if ((strncasecmp((char*)g_curRomInfo.szGameName, "SPIDERMAN", 9) == 0))
576 options.enableHackForGames = HACK_FOR_TONYHAWK;
578 else if ((strncasecmp((char*)g_curRomInfo.szGameName, "NASCAR", 6) == 0))
580 options.enableHackForGames = HACK_FOR_NASCAR;
582 else if ((strstr((char*)g_curRomInfo.szGameName, "ZELDA") != 0) && (strstr((char*)g_curRomInfo.szGameName, "MASK") != 0))
584 options.enableHackForGames = HACK_FOR_ZELDA_MM;
586 else if ((strstr((char*)g_curRomInfo.szGameName, "ZELDA") != 0))
588 options.enableHackForGames = HACK_FOR_ZELDA;
590 else if ((strstr((char*)g_curRomInfo.szGameName, "Ogre") != 0))
592 options.enableHackForGames = HACK_FOR_OGRE_BATTLE;
594 else if ((strstr((char*)g_curRomInfo.szGameName, "TWINE") != 0))
596 options.enableHackForGames = HACK_FOR_TWINE;
598 else if ((strstr((char*)g_curRomInfo.szGameName, "Squadron") != 0))
600 options.enableHackForGames = HACK_FOR_ROGUE_SQUADRON;
602 else if ((strstr((char*)g_curRomInfo.szGameName, "Baseball") != 0) && (strstr((char*)g_curRomInfo.szGameName, "Star") != 0))
604 options.enableHackForGames = HACK_FOR_ALL_STAR_BASEBALL;
606 else if ((strstr((char*)g_curRomInfo.szGameName, "Tigger") != 0) && (strstr((char*)g_curRomInfo.szGameName, "Honey") != 0))
608 options.enableHackForGames = HACK_FOR_TIGER_HONEY_HUNT;
610 else if ((strstr((char*)g_curRomInfo.szGameName, "Bust") != 0) && (strstr((char*)g_curRomInfo.szGameName, "Move") != 0))
612 options.enableHackForGames = HACK_FOR_BUST_A_MOVE;
614 else if ((strncasecmp((char*)g_curRomInfo.szGameName, "MarioTennis",11) == 0))
616 options.enableHackForGames = HACK_FOR_MARIO_TENNIS;
618 else if ((strncasecmp((char*)g_curRomInfo.szGameName, "SUPER BOWLING",13) == 0))
620 options.enableHackForGames = HACK_FOR_SUPER_BOWLING;
622 else if ((strncasecmp((char*)g_curRomInfo.szGameName, "CONKER",6) == 0))
624 options.enableHackForGames = HACK_FOR_CONKER;
626 else if ((strncasecmp((char*)g_curRomInfo.szGameName, "MK_MYTHOLOGIES",14) == 0))
628 options.enableHackForGames = HACK_REVERSE_Y_COOR;
630 else if ((strncasecmp((char*)g_curRomInfo.szGameName, "Fighting Force",14) == 0))
632 options.enableHackForGames = HACK_REVERSE_XY_COOR;
634 else if ((strncasecmp((char*)g_curRomInfo.szGameName, "GOLDENEYE",9) == 0))
636 options.enableHackForGames = HACK_FOR_GOLDEN_EYE;
638 else if ((strncasecmp((char*)g_curRomInfo.szGameName, "F-ZERO",6) == 0))
640 options.enableHackForGames = HACK_FOR_FZERO;
642 else if ((strncasecmp((char*)g_curRomInfo.szGameName, "Command&Conquer",15) == 0))
644 options.enableHackForGames = HACK_FOR_COMMANDCONQUER;
646 else if ((strncasecmp((char*)g_curRomInfo.szGameName, "READY 2 RUMBLE",14) == 0))
648 options.enableHackForGames = HACK_FOR_RUMBLE;
650 else if ((strncasecmp((char*)g_curRomInfo.szGameName, "READY to RUMBLE",15) == 0))
652 options.enableHackForGames = HACK_FOR_RUMBLE;
654 else if ((strncasecmp((char*)g_curRomInfo.szGameName, "South Park Rally",16) == 0))
656 options.enableHackForGames = HACK_FOR_SOUTH_PARK_RALLY;
658 else if ((strncasecmp((char*)g_curRomInfo.szGameName, "Extreme G 2",11) == 0))
660 options.enableHackForGames = HACK_FOR_EXTREME_G2;
662 else if ((strncasecmp((char*)g_curRomInfo.szGameName, "MarioGolf64",11) == 0))
664 options.enableHackForGames = HACK_FOR_MARIO_GOLF;
666 else if ((strncasecmp((char*)g_curRomInfo.szGameName, "MLB FEATURING",13) == 0))
668 options.enableHackForGames = HACK_FOR_MLB;
670 else if ((strncasecmp((char*)g_curRomInfo.szGameName, "POLARISSNOCROSS",15) == 0))
672 options.enableHackForGames = HACK_FOR_POLARISSNOCROSS;
674 else if ((strncasecmp((char*)g_curRomInfo.szGameName, "TOP GEAR RALLY",14) == 0))
676 options.enableHackForGames = HACK_FOR_TOPGEARRALLY;
678 else if ((strncasecmp((char*)g_curRomInfo.szGameName, "DUKE NUKEM",10) == 0))
680 options.enableHackForGames = HACK_FOR_DUKE_NUKEM;
682 else if ((strncasecmp((char*)g_curRomInfo.szGameName, "MARIOKART64",11) == 0))
684 options.enableHackForGames = HACK_FOR_MARIO_KART;
687 if (options.enableHackForGames != NO_HACK_FOR_GAME)
688 DebugMessage(M64MSG_INFO, "Enabled hacks for game: '%s'", g_curRomInfo.szGameName);
690 if( currentRomOptions.N64FrameBufferEmuType == 0 ) currentRomOptions.N64FrameBufferEmuType = defaultRomOptions.N64FrameBufferEmuType;
691 else currentRomOptions.N64FrameBufferEmuType--;
692 if( currentRomOptions.N64RenderToTextureEmuType == 0 ) currentRomOptions.N64RenderToTextureEmuType = defaultRomOptions.N64RenderToTextureEmuType;
693 else currentRomOptions.N64RenderToTextureEmuType--;
694 if( currentRomOptions.screenUpdateSetting == 0 ) currentRomOptions.screenUpdateSetting = defaultRomOptions.screenUpdateSetting;
695 if( currentRomOptions.bNormalCombiner == 0 ) currentRomOptions.bNormalCombiner = defaultRomOptions.bNormalCombiner;
696 else currentRomOptions.bNormalCombiner--;
697 if( currentRomOptions.bNormalBlender == 0 ) currentRomOptions.bNormalBlender = defaultRomOptions.bNormalBlender;
698 else currentRomOptions.bNormalBlender--;
699 if( currentRomOptions.bFastTexCRC == 0 ) currentRomOptions.bFastTexCRC = defaultRomOptions.bFastTexCRC;
700 else currentRomOptions.bFastTexCRC--;
701 if( currentRomOptions.bAccurateTextureMapping == 0 ) currentRomOptions.bAccurateTextureMapping = defaultRomOptions.bAccurateTextureMapping;
702 else currentRomOptions.bAccurateTextureMapping--;
704 options.bUseFullTMEM = ((options.bFullTMEM && (g_curRomInfo.dwFullTMEM == 0)) || g_curRomInfo.dwFullTMEM == 2);
706 GenerateFrameBufferOptions();
708 if( options.enableHackForGames == HACK_FOR_MARIO_GOLF || options.enableHackForGames == HACK_FOR_MARIO_TENNIS )
710 frameBufferOptions.bIgnoreRenderTextureIfHeightUnknown = true;
714 void Ini_GetRomOptions(LPGAMESETTING pGameSetting)
718 i = FindIniEntry(pGameSetting->romheader.dwCRC1,
719 pGameSetting->romheader.dwCRC2,
720 pGameSetting->romheader.nCountryID,
721 (char*)pGameSetting->szGameName, 1);
723 pGameSetting->bDisableTextureCRC = IniSections[i].bDisableTextureCRC;
724 pGameSetting->bDisableCulling = IniSections[i].bDisableCulling;
725 pGameSetting->bIncTexRectEdge = IniSections[i].bIncTexRectEdge;
726 pGameSetting->bZHack = IniSections[i].bZHack;
727 pGameSetting->bTextureScaleHack = IniSections[i].bTextureScaleHack;
728 pGameSetting->bPrimaryDepthHack = IniSections[i].bPrimaryDepthHack;
729 pGameSetting->bTexture1Hack = IniSections[i].bTexture1Hack;
730 pGameSetting->bFastLoadTile = IniSections[i].bFastLoadTile;
731 pGameSetting->bUseSmallerTexture = IniSections[i].bUseSmallerTexture;
733 pGameSetting->VIWidth = IniSections[i].VIWidth;
734 pGameSetting->VIHeight = IniSections[i].VIHeight;
735 pGameSetting->UseCIWidthAndRatio = IniSections[i].UseCIWidthAndRatio;
736 pGameSetting->dwFullTMEM = IniSections[i].dwFullTMEM;
737 pGameSetting->bTxtSizeMethod2 = IniSections[i].bTxtSizeMethod2;
738 pGameSetting->bEnableTxtLOD = IniSections[i].bEnableTxtLOD;
740 pGameSetting->dwFastTextureCRC = IniSections[i].dwFastTextureCRC;
741 pGameSetting->bEmulateClear = IniSections[i].bEmulateClear;
742 pGameSetting->bForceScreenClear = IniSections[i].bForceScreenClear;
743 pGameSetting->dwAccurateTextureMapping = IniSections[i].dwAccurateTextureMapping;
744 pGameSetting->dwNormalBlender = IniSections[i].dwNormalBlender;
745 pGameSetting->bDisableBlender = IniSections[i].bDisableBlender;
746 pGameSetting->dwNormalCombiner = IniSections[i].dwNormalCombiner;
747 pGameSetting->bForceDepthBuffer = IniSections[i].bForceDepthBuffer;
748 pGameSetting->bDisableObjBG = IniSections[i].bDisableObjBG;
749 pGameSetting->dwFrameBufferOption = IniSections[i].dwFrameBufferOption;
750 pGameSetting->dwRenderToTextureOption = IniSections[i].dwRenderToTextureOption;
751 pGameSetting->dwScreenUpdateSetting = IniSections[i].dwScreenUpdateSetting;
754 void Ini_StoreRomOptions(LPGAMESETTING pGameSetting)
758 i = FindIniEntry(pGameSetting->romheader.dwCRC1,
759 pGameSetting->romheader.dwCRC2,
760 pGameSetting->romheader.nCountryID,
761 (char*)pGameSetting->szGameName, 0);
763 if( IniSections[i].bDisableTextureCRC !=pGameSetting->bDisableTextureCRC )
765 IniSections[i].bDisableTextureCRC =pGameSetting->bDisableTextureCRC ;
769 if( IniSections[i].bDisableCulling !=pGameSetting->bDisableCulling )
771 IniSections[i].bDisableCulling =pGameSetting->bDisableCulling ;
775 if( IniSections[i].dwFastTextureCRC !=pGameSetting->dwFastTextureCRC )
777 IniSections[i].dwFastTextureCRC =pGameSetting->dwFastTextureCRC ;
781 if( IniSections[i].bEmulateClear !=pGameSetting->bEmulateClear )
783 IniSections[i].bEmulateClear =pGameSetting->bEmulateClear ;
787 if( IniSections[i].dwNormalBlender !=pGameSetting->dwNormalBlender )
789 IniSections[i].dwNormalBlender =pGameSetting->dwNormalBlender ;
793 if( IniSections[i].bDisableBlender !=pGameSetting->bDisableBlender )
795 IniSections[i].bDisableBlender =pGameSetting->bDisableBlender ;
799 if( IniSections[i].bForceScreenClear !=pGameSetting->bForceScreenClear )
801 IniSections[i].bForceScreenClear =pGameSetting->bForceScreenClear ;
804 if( IniSections[i].dwAccurateTextureMapping !=pGameSetting->dwAccurateTextureMapping )
806 IniSections[i].dwAccurateTextureMapping =pGameSetting->dwAccurateTextureMapping ;
809 if( IniSections[i].dwNormalCombiner !=pGameSetting->dwNormalCombiner )
811 IniSections[i].dwNormalCombiner =pGameSetting->dwNormalCombiner ;
814 if( IniSections[i].bForceDepthBuffer !=pGameSetting->bForceDepthBuffer )
816 IniSections[i].bForceDepthBuffer =pGameSetting->bForceDepthBuffer ;
819 if( IniSections[i].bDisableObjBG !=pGameSetting->bDisableObjBG )
821 IniSections[i].bDisableObjBG =pGameSetting->bDisableObjBG ;
824 if( IniSections[i].dwFrameBufferOption !=pGameSetting->dwFrameBufferOption )
826 IniSections[i].dwFrameBufferOption =pGameSetting->dwFrameBufferOption ;
829 if( IniSections[i].dwRenderToTextureOption !=pGameSetting->dwRenderToTextureOption )
831 IniSections[i].dwRenderToTextureOption =pGameSetting->dwRenderToTextureOption ;
834 if( IniSections[i].dwScreenUpdateSetting !=pGameSetting->dwScreenUpdateSetting )
836 IniSections[i].dwScreenUpdateSetting =pGameSetting->dwScreenUpdateSetting ;
839 if( IniSections[i].bIncTexRectEdge != pGameSetting->bIncTexRectEdge )
841 IniSections[i].bIncTexRectEdge =pGameSetting->bIncTexRectEdge;
844 if( IniSections[i].bZHack != pGameSetting->bZHack )
846 IniSections[i].bZHack =pGameSetting->bZHack;
849 if( IniSections[i].bTextureScaleHack != pGameSetting->bTextureScaleHack )
851 IniSections[i].bTextureScaleHack =pGameSetting->bTextureScaleHack;
854 if( IniSections[i].bPrimaryDepthHack != pGameSetting->bPrimaryDepthHack )
856 IniSections[i].bPrimaryDepthHack =pGameSetting->bPrimaryDepthHack;
859 if( IniSections[i].bTexture1Hack != pGameSetting->bTexture1Hack )
861 IniSections[i].bTexture1Hack =pGameSetting->bTexture1Hack;
864 if( IniSections[i].bFastLoadTile != pGameSetting->bFastLoadTile )
866 IniSections[i].bFastLoadTile =pGameSetting->bFastLoadTile;
869 if( IniSections[i].bUseSmallerTexture != pGameSetting->bUseSmallerTexture )
871 IniSections[i].bUseSmallerTexture =pGameSetting->bUseSmallerTexture;
874 if( IniSections[i].VIWidth != pGameSetting->VIWidth )
876 IniSections[i].VIWidth =pGameSetting->VIWidth;
879 if( IniSections[i].VIHeight != pGameSetting->VIHeight )
881 IniSections[i].VIHeight =pGameSetting->VIHeight;
884 if( IniSections[i].UseCIWidthAndRatio != pGameSetting->UseCIWidthAndRatio )
886 IniSections[i].UseCIWidthAndRatio =pGameSetting->UseCIWidthAndRatio;
889 if( IniSections[i].dwFullTMEM != pGameSetting->dwFullTMEM )
891 IniSections[i].dwFullTMEM =pGameSetting->dwFullTMEM;
894 if( IniSections[i].bTxtSizeMethod2 != pGameSetting->bTxtSizeMethod2 )
896 IniSections[i].bTxtSizeMethod2 =pGameSetting->bTxtSizeMethod2;
899 if( IniSections[i].bEnableTxtLOD != pGameSetting->bEnableTxtLOD )
901 IniSections[i].bEnableTxtLOD =pGameSetting->bEnableTxtLOD;
908 TRACE0("Rom option is changed and saved");
912 std::ifstream& getline( std::ifstream &is, char *str );
914 char * left(const char * src, int nchars)
916 static char dst[300];
917 strncpy(dst,src,nchars);
922 char * right(const char *src, int nchars)
924 static char dst[300];
925 int srclen = strlen(src);
926 if (nchars >= srclen)
932 strncpy(dst, src + srclen - nchars, nchars);
938 char * tidy(char * s)
940 char * p = s + strlen(s);
943 while (p >= s && (*p == ' ' || *p == 0xa || *p == '\n') )
954 std::ifstream inifile;
956 const char *ini_filepath = ConfigGetSharedDataFilepath(szIniFileName);
958 DebugMessage(M64MSG_VERBOSE, "Reading .ini file: %s", ini_filepath);
959 inifile.open(ini_filepath);
966 while (getline(inifile,readinfo)/*&§ionno<999*/)
970 if (readinfo[0] == '/')
973 if (!strcasecmp(readinfo,"")==0)
975 if (readinfo[0] == '{') //if a section heading
979 readinfo[strlen(readinfo)-1]='\0';
980 strcpy(newsection.crccheck, readinfo+1);
982 newsection.bDisableTextureCRC = FALSE;
983 newsection.bDisableCulling = FALSE;
984 newsection.bIncTexRectEdge = FALSE;
985 newsection.bZHack = FALSE;
986 newsection.bTextureScaleHack = FALSE;
987 newsection.bFastLoadTile = FALSE;
988 newsection.bUseSmallerTexture = FALSE;
989 newsection.bPrimaryDepthHack = FALSE;
990 newsection.bTexture1Hack = FALSE;
991 newsection.bDisableObjBG = FALSE;
992 newsection.VIWidth = -1;
993 newsection.VIHeight = -1;
994 newsection.UseCIWidthAndRatio = NOT_USE_CI_WIDTH_AND_RATIO;
995 newsection.dwFullTMEM = 0;
996 newsection.bTxtSizeMethod2 = FALSE;
997 newsection.bEnableTxtLOD = FALSE;
999 newsection.bEmulateClear = FALSE;
1000 newsection.bForceScreenClear = FALSE;
1001 newsection.bDisableBlender = FALSE;
1002 newsection.bForceDepthBuffer = FALSE;
1003 newsection.dwFastTextureCRC = 0;
1004 newsection.dwAccurateTextureMapping = 0;
1005 newsection.dwNormalBlender = 0;
1006 newsection.dwNormalCombiner = 0;
1007 newsection.dwFrameBufferOption = 0;
1008 newsection.dwRenderToTextureOption = 0;
1009 newsection.dwScreenUpdateSetting = 0;
1011 IniSections.push_back(newsection);
1016 int sectionno = IniSections.size() - 1;
1018 if (strcasecmp(left(readinfo,4), "Name")==0)
1019 strcpy(IniSections[sectionno].name,right(readinfo,strlen(readinfo)-5));
1021 if (strcasecmp(left(readinfo,17), "DisableTextureCRC")==0)
1022 IniSections[sectionno].bDisableTextureCRC=true;
1024 if (strcasecmp(left(readinfo,14), "DisableCulling")==0)
1025 IniSections[sectionno].bDisableCulling=true;
1027 if (strcasecmp(left(readinfo,16), "PrimaryDepthHack")==0)
1028 IniSections[sectionno].bPrimaryDepthHack=true;
1030 if (strcasecmp(left(readinfo,12), "Texture1Hack")==0)
1031 IniSections[sectionno].bTexture1Hack=true;
1033 if (strcasecmp(left(readinfo,12), "FastLoadTile")==0)
1034 IniSections[sectionno].bFastLoadTile=true;
1036 if (strcasecmp(left(readinfo,17), "UseSmallerTexture")==0)
1037 IniSections[sectionno].bUseSmallerTexture=true;
1039 if (strcasecmp(left(readinfo,14), "IncTexRectEdge")==0)
1040 IniSections[sectionno].bIncTexRectEdge=true;
1042 if (strcasecmp(left(readinfo,5), "ZHack")==0)
1043 IniSections[sectionno].bZHack=true;
1045 if (strcasecmp(left(readinfo,16), "TexRectScaleHack")==0)
1046 IniSections[sectionno].bTextureScaleHack=true;
1048 if (strcasecmp(left(readinfo,7), "VIWidth")==0)
1049 IniSections[sectionno].VIWidth = strtol(right(readinfo,3),NULL,10);
1051 if (strcasecmp(left(readinfo,8), "VIHeight")==0)
1052 IniSections[sectionno].VIHeight = strtol(right(readinfo,3),NULL,10);
1054 if (strcasecmp(left(readinfo,18), "UseCIWidthAndRatio")==0)
1055 IniSections[sectionno].UseCIWidthAndRatio = strtol(right(readinfo,1),NULL,10);
1057 if (strcasecmp(left(readinfo,8), "FullTMEM")==0)
1058 IniSections[sectionno].dwFullTMEM = strtol(right(readinfo,1),NULL,10);
1060 if (strcasecmp(left(readinfo,24), "AlternativeTxtSizeMethod")==0)
1061 IniSections[sectionno].bTxtSizeMethod2 = strtol(right(readinfo,1),NULL,10);
1063 if (strcasecmp(left(readinfo,12), "EnableTxtLOD")==0)
1064 IniSections[sectionno].bEnableTxtLOD = strtol(right(readinfo,1),NULL,10);
1066 if (strcasecmp(left(readinfo,12), "DisableObjBG")==0)
1067 IniSections[sectionno].bDisableObjBG = strtol(right(readinfo,1),NULL,10);
1069 if (strcasecmp(left(readinfo,16), "ForceScreenClear")==0)
1070 IniSections[sectionno].bForceScreenClear = strtol(right(readinfo,1),NULL,10);
1072 if (strcasecmp(left(readinfo,22), "AccurateTextureMapping")==0)
1073 IniSections[sectionno].dwAccurateTextureMapping = strtol(right(readinfo,1),NULL,10);
1075 if (strcasecmp(left(readinfo,14), "FastTextureCRC")==0)
1076 IniSections[sectionno].dwFastTextureCRC = strtol(right(readinfo,1),NULL,10);
1078 if (strcasecmp(left(readinfo,12), "EmulateClear")==0)
1079 IniSections[sectionno].bEmulateClear = strtol(right(readinfo,1),NULL,10);
1081 if (strcasecmp(left(readinfo,18), "NormalAlphaBlender")==0)
1082 IniSections[sectionno].dwNormalBlender = strtol(right(readinfo,1),NULL,10);
1084 if (strcasecmp(left(readinfo,19), "DisableAlphaBlender")==0)
1085 IniSections[sectionno].bDisableBlender = strtol(right(readinfo,1),NULL,10);
1087 if (strcasecmp(left(readinfo,19), "NormalColorCombiner")==0)
1088 IniSections[sectionno].dwNormalCombiner = strtol(right(readinfo,1),NULL,10);
1090 if (strcasecmp(left(readinfo,16), "ForceDepthBuffer")==0)
1091 IniSections[sectionno].bForceDepthBuffer = strtol(right(readinfo,1),NULL,10);
1093 if (strcasecmp(left(readinfo,20), "FrameBufferEmulation")==0)
1094 IniSections[sectionno].dwFrameBufferOption = strtol(readinfo+21,NULL,10);
1096 if (strcasecmp(left(readinfo,15), "RenderToTexture")==0)
1097 IniSections[sectionno].dwRenderToTextureOption = strtol(right(readinfo,1),NULL,10);
1099 if (strcasecmp(left(readinfo,19), "ScreenUpdateSetting")==0)
1100 IniSections[sectionno].dwScreenUpdateSetting = strtol(right(readinfo,1),NULL,10);
1109 //read a line from the ini file
1110 std::ifstream & getline(std::ifstream & is, char *str)
1114 is.getline(buf,100);
1125 /* get path to game-hack INI file and read it */
1126 const char *ini_filepath = ConfigGetSharedDataFilepath(szIniFileName);
1127 if (ini_filepath == NULL)
1129 fhIn = fopen(ini_filepath, "r");
1132 fseek(fhIn, 0L, SEEK_END);
1133 long filelen = ftell(fhIn);
1134 fseek(fhIn, 0L, SEEK_SET);
1135 char *chIniData = (char *) malloc(filelen + 1);
1136 if (chIniData == NULL)
1141 long bytesread = fread(chIniData, 1, filelen, fhIn);
1143 if (bytesread != filelen)
1148 chIniData[filelen] = 0;
1150 /* now try to open the file for writing */
1151 fhOut = fopen(ini_filepath, "w");
1158 // Mark all sections and needing to be written
1159 for (i = 0; i < IniSections.size(); i++)
1161 IniSections[i].bOutput = false;
1164 char *thisline = chIniData;
1165 while ((thisline - chIniData) < filelen)
1167 char *nextline = strchr(thisline, '\n');
1168 if (nextline == NULL)
1169 nextline = thisline + strlen(thisline) + 1;
1172 if (thisline[0] == '{')
1174 BOOL bFound = FALSE;
1176 tidy((char*) thisline);
1177 thisline[strlen(thisline) - 1] = '\0';
1178 for (i = 0; i < IniSections.size(); i++)
1180 if (IniSections[i].bOutput)
1182 if (strcasecmp((char*) thisline + 1, IniSections[i].crccheck) == 0)
1185 OutputSectionDetails(i, fhOut);
1186 IniSections[i].bOutput = true;
1193 // Do what? This should never happen, unless the user
1194 // replaces the inifile while game is running!
1197 else if (thisline[0] == '/')
1200 fputs((char*) thisline, fhOut);
1202 thisline = nextline;
1205 // Input buffer done- process any new entries!
1206 for (i = 0; i < IniSections.size(); i++)
1208 // Skip any that have not been done.
1209 if (IniSections[i].bOutput)
1212 OutputSectionDetails(i, fhOut);
1213 IniSections[i].bOutput = true;
1219 bIniIsChanged = false;
1222 void OutputSectionDetails(uint32 i, FILE * fh)
1224 fprintf(fh, "{%s}\n", IniSections[i].crccheck);
1226 fprintf(fh, "Name=%s\n", IniSections[i].name);
1227 //fprintf(fh, "UCode=%d\n", IniSections[i].ucode);
1229 // Tri-state variables
1230 if (IniSections[i].dwAccurateTextureMapping != 0)
1231 fprintf(fh, "AccurateTextureMapping=%d\n", IniSections[i].dwAccurateTextureMapping);
1233 if (IniSections[i].dwFastTextureCRC != 0)
1234 fprintf(fh, "FastTextureCRC=%d\n", IniSections[i].dwFastTextureCRC);
1236 if (IniSections[i].dwNormalBlender != 0)
1237 fprintf(fh, "NormalAlphaBlender=%d\n", IniSections[i].dwNormalBlender);
1239 if (IniSections[i].dwNormalCombiner != 0)
1240 fprintf(fh, "NormalColorCombiner=%d\n", IniSections[i].dwNormalCombiner);
1243 // Normal bi-state variables
1244 if (IniSections[i].bDisableTextureCRC)
1245 fprintf(fh, "DisableTextureCRC\n");
1247 if (IniSections[i].bDisableCulling)
1248 fprintf(fh, "DisableCulling\n");
1250 if (IniSections[i].bPrimaryDepthHack)
1251 fprintf(fh, "PrimaryDepthHack\n");
1253 if (IniSections[i].bTexture1Hack)
1254 fprintf(fh, "Texture1Hack\n");
1256 if (IniSections[i].bFastLoadTile)
1257 fprintf(fh, "FastLoadTile\n");
1259 if (IniSections[i].bUseSmallerTexture)
1260 fprintf(fh, "UseSmallerTexture\n");
1262 if (IniSections[i].bIncTexRectEdge)
1263 fprintf(fh, "IncTexRectEdge\n");
1265 if (IniSections[i].bZHack)
1266 fprintf(fh, "ZHack\n");
1268 if (IniSections[i].bTextureScaleHack)
1269 fprintf(fh, "TexRectScaleHack\n");
1271 if (IniSections[i].VIWidth > 0)
1272 fprintf(fh, "VIWidth=%d\n", IniSections[i].VIWidth);
1274 if (IniSections[i].VIHeight > 0)
1275 fprintf(fh, "VIHeight=%d\n", IniSections[i].VIHeight);
1277 if (IniSections[i].UseCIWidthAndRatio > 0)
1278 fprintf(fh, "UseCIWidthAndRatio=%d\n", IniSections[i].UseCIWidthAndRatio);
1280 if (IniSections[i].dwFullTMEM > 0)
1281 fprintf(fh, "FullTMEM=%d\n", IniSections[i].dwFullTMEM);
1283 if (IniSections[i].bTxtSizeMethod2 != FALSE )
1284 fprintf(fh, "AlternativeTxtSizeMethod=%d\n", IniSections[i].bTxtSizeMethod2);
1286 if (IniSections[i].bEnableTxtLOD != FALSE )
1287 fprintf(fh, "EnableTxtLOD=%d\n", IniSections[i].bEnableTxtLOD);
1289 if (IniSections[i].bDisableObjBG != 0 )
1290 fprintf(fh, "DisableObjBG=%d\n", IniSections[i].bDisableObjBG);
1292 if (IniSections[i].bForceScreenClear != 0)
1293 fprintf(fh, "ForceScreenClear=%d\n", IniSections[i].bForceScreenClear);
1295 if (IniSections[i].bEmulateClear != 0)
1296 fprintf(fh, "EmulateClear=%d\n", IniSections[i].bEmulateClear);
1298 if (IniSections[i].bDisableBlender != 0)
1299 fprintf(fh, "DisableAlphaBlender=%d\n", IniSections[i].bDisableBlender);
1301 if (IniSections[i].bForceDepthBuffer != 0)
1302 fprintf(fh, "ForceDepthBuffer=%d\n", IniSections[i].bForceDepthBuffer);
1304 if (IniSections[i].dwFrameBufferOption != 0)
1305 fprintf(fh, "FrameBufferEmulation=%d\n", IniSections[i].dwFrameBufferOption);
1307 if (IniSections[i].dwRenderToTextureOption != 0)
1308 fprintf(fh, "RenderToTexture=%d\n", IniSections[i].dwRenderToTextureOption);
1310 if (IniSections[i].dwScreenUpdateSetting != 0)
1311 fprintf(fh, "ScreenUpdateSetting=%d\n", IniSections[i].dwScreenUpdateSetting);
1313 fprintf(fh, "\n"); // Spacer
1316 // Find the entry corresponding to the specified rom.
1317 // If the rom is not found, a new entry is created
1318 // The resulting value is returned
1319 void __cdecl DebuggerAppendMsg (const char * Message, ...);
1321 static int FindIniEntry(uint32 dwCRC1, uint32 dwCRC2, uint8 nCountryID, char* szName, int PrintInfo)
1324 unsigned char szCRC[50+1];
1326 // Generate the CRC-ID for this rom:
1327 sprintf((char*)szCRC, "%08x%08x-%02x", (unsigned int)dwCRC1, (unsigned int)dwCRC2, nCountryID);
1329 for (i = 0; i < IniSections.size(); i++)
1331 if (strcasecmp((char*)szCRC, IniSections[i].crccheck) == 0)
1334 DebugMessage(M64MSG_INFO, "Found ROM '%s', CRC %s", IniSections[i].name, szCRC);
1343 DebugMessage(M64MSG_INFO, "ROM (CRC %s) not found in INI file", szCRC);
1345 strcpy(newsection.crccheck, (char*)szCRC);
1347 strncpy(newsection.name, szName, 50);
1348 newsection.bDisableTextureCRC = FALSE;
1349 newsection.bDisableCulling = FALSE;
1350 newsection.bIncTexRectEdge = FALSE;
1351 newsection.bZHack = FALSE;
1352 newsection.bTextureScaleHack = FALSE;
1353 newsection.bFastLoadTile = FALSE;
1354 newsection.bUseSmallerTexture = FALSE;
1355 newsection.bPrimaryDepthHack = FALSE;
1356 newsection.bTexture1Hack = FALSE;
1357 newsection.bDisableObjBG = FALSE;
1358 newsection.VIWidth = -1;
1359 newsection.VIHeight = -1;
1360 newsection.UseCIWidthAndRatio = NOT_USE_CI_WIDTH_AND_RATIO;
1361 newsection.dwFullTMEM = 0;
1362 newsection.bTxtSizeMethod2 = FALSE;
1363 newsection.bEnableTxtLOD = FALSE;
1365 newsection.bEmulateClear = FALSE;
1366 newsection.bForceScreenClear = FALSE;
1367 newsection.bDisableBlender = FALSE;
1368 newsection.bForceDepthBuffer = FALSE;
1369 newsection.dwFastTextureCRC = 0;
1370 newsection.dwAccurateTextureMapping = 0;
1371 newsection.dwNormalBlender = 0;
1372 newsection.dwNormalCombiner = 0;
1373 newsection.dwFrameBufferOption = 0;
1374 newsection.dwRenderToTextureOption = 0;
1375 newsection.dwScreenUpdateSetting = 0;
1377 IniSections.push_back(newsection);
1379 bIniIsChanged = true; // Flag to indicate we should be updated
1380 return IniSections.size()-1; // -1 takes into account increment
1383 GameSetting g_curRomInfo;
1385 void ROM_GetRomNameFromHeader(unsigned char * szName, ROMHeader * pHdr)
1389 memcpy(szName, pHdr->szName, 20);
1392 p = szName + (strlen((char*)szName) -1); // -1 to skip null
1393 while (p >= szName && *p == ' ')
1400 uint32 CountryCodeToTVSystem(uint32 countryCode)
1407 system = TV_SYSTEM_NTSC;
1411 system = TV_SYSTEM_NTSC;
1415 system = TV_SYSTEM_NTSC;
1420 system = TV_SYSTEM_PAL;
1425 system = TV_SYSTEM_NTSC;
1430 system = TV_SYSTEM_PAL;
1435 system = TV_SYSTEM_PAL;
1440 system = TV_SYSTEM_NTSC;
1445 system = TV_SYSTEM_PAL;
1448 case 'S': /* Spain */
1449 system = TV_SYSTEM_PAL;
1454 system = TV_SYSTEM_PAL;
1458 system = TV_SYSTEM_PAL;
1463 system = TV_SYSTEM_PAL;
1470 system = TV_SYSTEM_PAL;
1475 system = TV_SYSTEM_PAL;