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] =
75 const int numberOfResolutions = sizeof(resolutions)/sizeof(int)/2;
77 const char* resolutionsS[] =
94 const char *frameBufferWriteBackControlSettings[] =
96 "Every Frame (default)",
106 const char *renderToTextureSettings[] =
109 "Hide Render-to-texture Effects",
110 "Basic Render-to-texture",
111 "Basic & Write Back",
112 "Write Back & Reload",
115 const char *screenUpdateSettings[] =
117 "At VI origin update",
118 "At VI origin change",
120 "At the 1st CI change",
121 "At the 1st drawing",
122 "Before clear the screen",
123 "At VI origin update after screen is drawn (default)",
126 WindowSettingStruct windowSetting;
127 GlobalOptions options;
128 RomOptions defaultRomOptions;
129 RomOptions currentRomOptions;
130 FrameBufferOptions frameBufferOptions;
131 std::vector<IniSection> IniSections;
132 bool bIniIsChanged = false;
133 char szIniFileName[300];
135 SettingInfo TextureQualitySettings[] =
137 {"Default", FORCE_DEFAULT_FILTER},
138 {"32-bit Texture", FORCE_POINT_FILTER},
139 {"16-bit Texture", FORCE_LINEAR_FILTER},
142 SettingInfo ForceTextureFilterSettings[] =
144 {"N64 Default Texture Filter", FORCE_DEFAULT_FILTER},
145 {"Force Nearest Filter (faster, low quality)", FORCE_POINT_FILTER},
146 {"Force Linear Filter (slower, better quality)", FORCE_LINEAR_FILTER},
149 SettingInfo TextureEnhancementSettings[] =
151 {"N64 original texture (No enhancement)", TEXTURE_NO_ENHANCEMENT},
152 {"2x (Double the texture size)", TEXTURE_2X_ENHANCEMENT},
153 {"2xSaI", TEXTURE_2XSAI_ENHANCEMENT},
154 {"hq2x", TEXTURE_HQ2X_ENHANCEMENT},
155 {"lq2x", TEXTURE_LQ2X_ENHANCEMENT},
156 {"hq4x", TEXTURE_HQ4X_ENHANCEMENT},
157 {"Sharpen", TEXTURE_SHARPEN_ENHANCEMENT},
158 {"Sharpen More", TEXTURE_SHARPEN_MORE_ENHANCEMENT},
161 SettingInfo TextureEnhancementControlSettings[] =
163 {"Normal", TEXTURE_ENHANCEMENT_NORMAL},
164 {"Smooth", TEXTURE_ENHANCEMENT_WITH_SMOOTH_FILTER_1},
165 {"Less smooth", TEXTURE_ENHANCEMENT_WITH_SMOOTH_FILTER_2},
166 {"2xSaI smooth", TEXTURE_ENHANCEMENT_WITH_SMOOTH_FILTER_3},
167 {"Less 2xSaI smooth", TEXTURE_ENHANCEMENT_WITH_SMOOTH_FILTER_4},
170 SettingInfo colorQualitySettings[] =
172 {"16-bit", TEXTURE_FMT_A4R4G4B4},
173 {"32-bit (def)", TEXTURE_FMT_A8R8G8B8},
176 const char* strDXDeviceDescs[] = { "HAL", "REF" };
178 SettingInfo openGLDepthBufferSettings[] =
180 {"16-bit (def)", 16},
184 RenderEngineSetting OpenGLRenderSettings[] =
186 {"To Fit Your Video Card", OGL_DEVICE},
187 {"OpenGL 1.1 (Lowest)", OGL_1_1_DEVICE},
188 {"OpenGL 1.2/1.3", OGL_1_2_DEVICE},
189 {"OpenGL 1.4", OGL_1_4_DEVICE},
190 //{"OpenGL 1.4, the 2nd combiner", OGL_1_4_V2_DEVICE},
191 {"OpenGL for Nvidia TNT or better", OGL_TNT2_DEVICE},
192 {"OpenGL for Nvidia GeForce or better ", NVIDIA_OGL_DEVICE},
193 {"OpenGL Fragment Program Extension", OGL_FRAGMENT_PROGRAM},
196 SettingInfo OnScreenDisplaySettings[] =
198 {"Display Nothing", ONSCREEN_DISPLAY_NOTHING},
199 {"Display DList Per Second", ONSCREEN_DISPLAY_DLIST_PER_SECOND},
200 {"Display Frame Per Second", ONSCREEN_DISPLAY_FRAME_PER_SECOND},
201 {"Display Debug Information Only", ONSCREEN_DISPLAY_DEBUG_INFORMATION_ONLY},
202 {"Display Messages From CPU Core Only", ONSCREEN_DISPLAY_TEXT_FROM_CORE_ONLY},
203 {"Display DList Per Second With Core Msgs", ONSCREEN_DISPLAY_DLIST_PER_SECOND_WITH_CORE_MSG},
204 {"Display Frame Per Second With Core Msgs", ONSCREEN_DISPLAY_FRAME_PER_SECOND_WITH_CORE_MSG},
205 {"Display Debug Information With Core Msgs", ONSCREEN_DISPLAY_DEBUG_INFORMATION_WITH_CORE_MSG},
208 const int numberOfOpenGLRenderEngineSettings = sizeof(OpenGLRenderSettings)/sizeof(RenderEngineSetting);
210 void GenerateFrameBufferOptions(void)
212 if( CDeviceBuilder::GetGeneralDeviceType() == OGL_DEVICE )
214 // OpenGL does not support much yet
215 if( currentRomOptions.N64FrameBufferEmuType != FRM_BUF_NONE )
216 currentRomOptions.N64FrameBufferEmuType = FRM_BUF_IGNORE;
217 if( currentRomOptions.N64RenderToTextureEmuType != TXT_BUF_NONE )
218 currentRomOptions.N64RenderToTextureEmuType = TXT_BUF_IGNORE;
221 frameBufferOptions.bUpdateCIInfo = false;
223 frameBufferOptions.bCheckBackBufs = false;
224 frameBufferOptions.bWriteBackBufToRDRAM = false;
225 frameBufferOptions.bLoadBackBufFromRDRAM = false;
227 frameBufferOptions.bIgnore = true;
229 frameBufferOptions.bSupportRenderTextures = false;
230 frameBufferOptions.bCheckRenderTextures = false;
231 frameBufferOptions.bRenderTextureWriteBack = false;
232 frameBufferOptions.bLoadRDRAMIntoRenderTexture = false;
234 frameBufferOptions.bProcessCPUWrite = false;
235 frameBufferOptions.bProcessCPURead = false;
236 frameBufferOptions.bAtEachFrameUpdate = false;
237 frameBufferOptions.bIgnoreRenderTextureIfHeightUnknown = false;
239 switch( currentRomOptions.N64FrameBufferEmuType )
243 case FRM_BUF_COMPLETE:
244 frameBufferOptions.bAtEachFrameUpdate = true;
245 frameBufferOptions.bProcessCPUWrite = true;
246 frameBufferOptions.bProcessCPURead = true;
247 frameBufferOptions.bUpdateCIInfo = true;
249 case FRM_BUF_WRITEBACK_AND_RELOAD:
250 frameBufferOptions.bLoadBackBufFromRDRAM = true;
251 case FRM_BUF_BASIC_AND_WRITEBACK:
252 frameBufferOptions.bWriteBackBufToRDRAM = true;
254 frameBufferOptions.bCheckBackBufs = true;
256 frameBufferOptions.bUpdateCIInfo = true;
258 case FRM_BUF_BASIC_AND_WITH_EMULATOR:
260 frameBufferOptions.bCheckBackBufs = true;
261 case FRM_BUF_WITH_EMULATOR:
262 frameBufferOptions.bUpdateCIInfo = true;
263 frameBufferOptions.bProcessCPUWrite = true;
264 frameBufferOptions.bProcessCPURead = true;
266 case FRM_BUF_WITH_EMULATOR_READ_ONLY:
267 frameBufferOptions.bUpdateCIInfo = true;
268 frameBufferOptions.bProcessCPURead = true;
270 case FRM_BUF_WITH_EMULATOR_WRITE_ONLY:
271 frameBufferOptions.bUpdateCIInfo = true;
272 frameBufferOptions.bProcessCPUWrite = true;
276 switch( currentRomOptions.N64RenderToTextureEmuType )
279 frameBufferOptions.bSupportRenderTextures = false;
281 case TXT_BUF_WRITE_BACK_AND_RELOAD:
282 frameBufferOptions.bLoadRDRAMIntoRenderTexture = true;
283 case TXT_BUF_WRITE_BACK:
284 frameBufferOptions.bRenderTextureWriteBack = true;
286 frameBufferOptions.bCheckRenderTextures = true;
287 frameBufferOptions.bIgnore = false;
289 frameBufferOptions.bUpdateCIInfo = true;
290 frameBufferOptions.bSupportRenderTextures = true;
294 if( currentRomOptions.screenUpdateSetting >= SCREEN_UPDATE_AT_CI_CHANGE )
296 frameBufferOptions.bUpdateCIInfo = true;
300 BOOL InitConfiguration(void)
302 if (ConfigOpenSection("Video-General", &l_ConfigVideoGeneral) != M64ERR_SUCCESS)
304 DebugMessage(M64MSG_ERROR, "Unable to open Video-General configuration section");
307 if (ConfigOpenSection("Video-Rice", &l_ConfigVideoRice) != M64ERR_SUCCESS)
309 DebugMessage(M64MSG_ERROR, "Unable to open Video-Rice configuration section");
313 ConfigSetDefaultBool(l_ConfigVideoGeneral, "Fullscreen", 0, "Use fullscreen mode if True, or windowed mode if False ");
314 ConfigSetDefaultInt(l_ConfigVideoGeneral, "ScreenWidth", 640, "Width of output window or fullscreen width");
315 ConfigSetDefaultInt(l_ConfigVideoGeneral, "ScreenHeight", 480, "Height of output window or fullscreen height");
316 ConfigSetDefaultBool(l_ConfigVideoGeneral, "VerticalSync", 0, "If true, activate the SDL_GL_SWAP_CONTROL attribute");
318 ConfigSetDefaultInt(l_ConfigVideoRice, "FrameBufferSetting", FRM_BUF_NONE, "Frame Buffer Emulation (0=ROM default, 1=disable)");
319 ConfigSetDefaultInt(l_ConfigVideoRice, "FrameBufferWriteBackControl", FRM_BUF_WRITEBACK_NORMAL, "Frequency to write back the frame buffer (0=every frame, 1=every other frame, etc)");
320 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)");
322 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
324 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
326 ConfigSetDefaultBool(l_ConfigVideoRice, "NormalAlphaBlender", FALSE, "Force to use normal alpha blender");
327 ConfigSetDefaultBool(l_ConfigVideoRice, "FastTextureLoading", FALSE, "Use a faster algorithm to speed up texture loading and CRC computation");
328 ConfigSetDefaultBool(l_ConfigVideoRice, "AccurateTextureMapping", TRUE, "Use different texture coordinate clamping code");
329 ConfigSetDefaultBool(l_ConfigVideoRice, "InN64Resolution", FALSE, "Force emulated frame buffers to be in N64 native resolution");
330 ConfigSetDefaultBool(l_ConfigVideoRice, "SaveVRAM", FALSE, "Try to reduce Video RAM usage (should never be used)");
331 ConfigSetDefaultBool(l_ConfigVideoRice, "DoubleSizeForSmallTxtrBuf", FALSE, "Enable this option to have better render-to-texture quality");
332 ConfigSetDefaultBool(l_ConfigVideoRice, "DefaultCombinerDisable", FALSE, "Force to use normal color combiner");
334 ConfigSetDefaultBool(l_ConfigVideoRice, "EnableHacks", TRUE, "Enable game-specific settings from INI file");
335 ConfigSetDefaultBool(l_ConfigVideoRice, "WinFrameMode", FALSE, "If enabled, graphics will be drawn in WinFrame mode instead of solid and texture mode");
336 ConfigSetDefaultBool(l_ConfigVideoRice, "FullTMEMEmulation", FALSE, "N64 Texture Memory Full Emulation (may fix some games, may break others)");
337 ConfigSetDefaultBool(l_ConfigVideoRice, "OpenGLVertexClipper", FALSE, "Enable vertex clipper for fog operations");
338 ConfigSetDefaultBool(l_ConfigVideoRice, "EnableSSE", TRUE, "Enable/Disable SSE optimizations for capable CPUs");
339 ConfigSetDefaultBool(l_ConfigVideoRice, "EnableVertexShader", FALSE, "Use GPU vertex shader");
340 ConfigSetDefaultBool(l_ConfigVideoRice, "SkipFrame", FALSE, "If this option is enabled, the plugin will skip every other frame");
341 ConfigSetDefaultBool(l_ConfigVideoRice, "TexRectOnly", FALSE, "If enabled, texture enhancement will be done only for TxtRect ucode");
342 ConfigSetDefaultBool(l_ConfigVideoRice, "SmallTextureOnly", FALSE, "If enabled, texture enhancement will be done only for textures width+height<=128");
343 ConfigSetDefaultBool(l_ConfigVideoRice, "LoadHiResCRCOnly", TRUE, "Select hi-resolution textures based only on the CRC and ignore format+size information (Glide64 compatibility)");
344 ConfigSetDefaultBool(l_ConfigVideoRice, "LoadHiResTextures", FALSE, "Enable hi-resolution texture file loading");
345 ConfigSetDefaultBool(l_ConfigVideoRice, "DumpTexturesToFiles", FALSE, "Enable texture dumping");
346 ConfigSetDefaultBool(l_ConfigVideoRice, "ShowFPS", FALSE, "Display On-screen FPS");
348 ConfigSetDefaultInt(l_ConfigVideoRice, "Mipmapping", 2, "Use Mipmapping? 0=no, 1=nearest, 2=bilinear, 3=trilinear");
349 ConfigSetDefaultInt(l_ConfigVideoRice, "FogMethod", 0, "Enable, Disable or Force fog generation (0=Disable, 1=Enable n64 choose, 2=Force Fog)");
350 ConfigSetDefaultInt(l_ConfigVideoRice, "ForceTextureFilter", 0, "Force to use texture filtering or not (0=auto: n64 choose, 1=force no filtering, 2=force filtering)");
351 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)");
352 ConfigSetDefaultInt(l_ConfigVideoRice, "TextureEnhancementControl", 0, "Secondary texture enhancement filter (0 = none, 1-4 = filtered)");
353 ConfigSetDefaultInt(l_ConfigVideoRice, "TextureQuality", TXT_QUALITY_DEFAULT, "Color bit depth to use for textures (0=default, 1=32 bits, 2=16 bits)");
354 ConfigSetDefaultInt(l_ConfigVideoRice, "OpenGLDepthBufferSetting", 16, "Z-buffer depth (only 16 or 32)");
355 ConfigSetDefaultInt(l_ConfigVideoRice, "MultiSampling", 0, "Enable/Disable MultiSampling (0=off, 2,4,8,16=quality)");
356 ConfigSetDefaultInt(l_ConfigVideoRice, "ColorQuality", TEXTURE_FMT_A8R8G8B8, "Color bit depth for rendering window (0=32 bits, 1=16 bits)");
357 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)");
358 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");
362 bool isMMXSupported()
364 int IsMMXSupported = 0;
366 #if !defined(__GNUC__) && !defined(NO_ASM)
369 mov eax,1 // CPUID level 1
370 cpuid // EDX = feature flag
371 and edx,0x800000 // test bit 23 of feature flag
372 mov IsMMXSupported,edx // != 0 if MMX is supported
374 #elif defined(__GNUC__) && defined(__x86_64__) && !defined(NO_ASM)
376 #elif !defined(NO_ASM) // GCC assumed
379 "mov $1, %%eax \n" // CPUID level 1
380 "cpuid \n" // EDX = feature flag
381 "and $0x800000, %%edx \n" // test bit 23 of feature flag
383 : "=d"(IsMMXSupported)
385 : "memory", "cc", "eax", "ecx"
388 if (IsMMXSupported != 0)
394 bool isSSESupported()
398 // And finally, check the CPUID for Streaming SIMD Extensions support.
399 #if !defined(__GNUC__) && !defined(NO_ASM)
402 mov eax, 1 // Put a "1" in eax to tell CPUID to get the feature bits
403 cpuid // Perform CPUID (puts processor feature info into EDX)
404 and edx, 02000000h // Test bit 25, for Streaming SIMD Extensions existence.
405 mov SSESupport, edx // SIMD Extensions). Set return value to 1 to indicate,
407 #elif defined(__GNUC__) && defined(__x86_64__) && !defined(NO_ASM)
409 #elif !defined(NO_ASM) // GCC assumed
412 "mov $1, %%eax \n" // Put a "1" in eax to tell CPUID to get the feature bits
413 "cpuid \n" // Perform CPUID (puts processor feature info into EDX)
414 "and $0x02000000, %%edx \n" // Test bit 25, for Streaming SIMD Extensions existence.
418 : "memory", "cc", "eax", "ecx"
428 static void ReadConfiguration(void)
430 windowSetting.bDisplayFullscreen = ConfigGetParamBool(l_ConfigVideoGeneral, "Fullscreen");
431 windowSetting.uDisplayWidth = ConfigGetParamInt(l_ConfigVideoGeneral, "ScreenWidth");
432 windowSetting.uDisplayHeight = ConfigGetParamInt(l_ConfigVideoGeneral, "ScreenHeight");
433 windowSetting.bVerticalSync = ConfigGetParamBool(l_ConfigVideoGeneral, "VerticalSync");
435 defaultRomOptions.N64FrameBufferEmuType = ConfigGetParamInt(l_ConfigVideoRice, "FrameBufferSetting");
436 defaultRomOptions.N64FrameBufferWriteBackControl = ConfigGetParamInt(l_ConfigVideoRice, "FrameBufferWriteBackControl");
437 defaultRomOptions.N64RenderToTextureEmuType = ConfigGetParamInt(l_ConfigVideoRice, "RenderToTexture");
438 defaultRomOptions.screenUpdateSetting = ConfigGetParamInt(l_ConfigVideoRice, "screenUpdateSetting");
440 defaultRomOptions.bNormalBlender = ConfigGetParamBool(l_ConfigVideoRice, "NormalAlphaBlender");
441 defaultRomOptions.bFastTexCRC = ConfigGetParamBool(l_ConfigVideoRice, "FastTextureLoading");
442 defaultRomOptions.bAccurateTextureMapping = ConfigGetParamBool(l_ConfigVideoRice, "AccurateTextureMapping");
443 defaultRomOptions.bInN64Resolution = ConfigGetParamBool(l_ConfigVideoRice, "InN64Resolution");
444 defaultRomOptions.bSaveVRAM = ConfigGetParamBool(l_ConfigVideoRice, "SaveVRAM");
445 defaultRomOptions.bDoubleSizeForSmallTxtrBuf = ConfigGetParamBool(l_ConfigVideoRice, "DoubleSizeForSmallTxtrBuf");
446 defaultRomOptions.bNormalCombiner = ConfigGetParamBool(l_ConfigVideoRice, "DefaultCombinerDisable");
448 options.bEnableHacks = ConfigGetParamBool(l_ConfigVideoRice, "EnableHacks");
449 options.bWinFrameMode = ConfigGetParamBool(l_ConfigVideoRice, "WinFrameMode");
450 options.bFullTMEM = ConfigGetParamBool(l_ConfigVideoRice, "FullTMEMEmulation");
451 options.bOGLVertexClipper = ConfigGetParamBool(l_ConfigVideoRice, "OpenGLVertexClipper");
452 options.bEnableSSE = ConfigGetParamBool(l_ConfigVideoRice, "EnableSSE");
453 options.bEnableVertexShader = ConfigGetParamBool(l_ConfigVideoRice, "EnableVertexShader");
454 options.bSkipFrame = ConfigGetParamBool(l_ConfigVideoRice, "SkipFrame");
455 options.bTexRectOnly = ConfigGetParamBool(l_ConfigVideoRice, "TexRectOnly");
456 options.bSmallTextureOnly = ConfigGetParamBool(l_ConfigVideoRice, "SmallTextureOnly");
457 options.bLoadHiResTextures = ConfigGetParamBool(l_ConfigVideoRice, "LoadHiResTextures");
458 options.bLoadHiResCRCOnly = ConfigGetParamBool(l_ConfigVideoRice, "LoadHiResCRCOnly");
459 options.bDumpTexturesToFiles = ConfigGetParamBool(l_ConfigVideoRice, "DumpTexturesToFiles");
460 options.bShowFPS = ConfigGetParamBool(l_ConfigVideoRice, "ShowFPS");
462 options.mipmapping = ConfigGetParamInt(l_ConfigVideoRice, "Mipmapping");
463 options.fogMethod = ConfigGetParamInt(l_ConfigVideoRice, "FogMethod");
464 options.forceTextureFilter = ConfigGetParamInt(l_ConfigVideoRice, "ForceTextureFilter");
465 options.textureEnhancement = ConfigGetParamInt(l_ConfigVideoRice, "TextureEnhancement");
466 options.textureEnhancementControl = ConfigGetParamInt(l_ConfigVideoRice, "TextureEnhancementControl");
467 options.textureQuality = ConfigGetParamInt(l_ConfigVideoRice, "TextureQuality");
468 options.OpenglDepthBufferSetting = ConfigGetParamInt(l_ConfigVideoRice, "OpenGLDepthBufferSetting");
469 options.multiSampling = ConfigGetParamInt(l_ConfigVideoRice, "MultiSampling");
470 options.colorQuality = ConfigGetParamInt(l_ConfigVideoRice, "ColorQuality");
471 options.OpenglRenderSetting = ConfigGetParamInt(l_ConfigVideoRice, "OpenGLRenderSetting");
472 options.anisotropicFiltering = ConfigGetParamInt(l_ConfigVideoRice, "AnisotropicFiltering");
474 CDeviceBuilder::SelectDeviceType((SupportedDeviceType)options.OpenglRenderSetting);
476 status.isMMXSupported = isMMXSupported();
477 status.isSSESupported = isSSESupported();
478 status.isVertexShaderSupported = false;
480 status.isSSEEnabled = status.isSSESupported && options.bEnableSSE;
482 if( status.isSSEEnabled )
484 ProcessVertexData = ProcessVertexDataSSE;
485 DebugMessage(M64MSG_INFO, "SSE processing enabled.");
490 ProcessVertexData = ProcessVertexDataNoSSE;
491 DebugMessage(M64MSG_INFO, "Disabled SSE processing.");
494 status.isVertexShaderEnabled = status.isVertexShaderSupported && options.bEnableVertexShader;
495 status.bUseHW_T_L = false;
498 BOOL LoadConfiguration(void)
501 bIniIsChanged = false;
502 strcpy(szIniFileName, INI_FILE);
506 DebugMessage(M64MSG_ERROR, "Unable to read ini file from disk");
510 if (l_ConfigVideoGeneral == NULL || l_ConfigVideoRice == NULL)
512 DebugMessage(M64MSG_ERROR, "Rice Video configuration sections are not open!");
516 // Read config parameters from core config API and set up internal variables
522 void GenerateCurrentRomOptions()
524 currentRomOptions.N64FrameBufferEmuType =g_curRomInfo.dwFrameBufferOption;
525 currentRomOptions.N64FrameBufferWriteBackControl =defaultRomOptions.N64FrameBufferWriteBackControl;
526 currentRomOptions.N64RenderToTextureEmuType =g_curRomInfo.dwRenderToTextureOption;
527 currentRomOptions.screenUpdateSetting =g_curRomInfo.dwScreenUpdateSetting;
528 currentRomOptions.bNormalCombiner =g_curRomInfo.dwNormalCombiner;
529 currentRomOptions.bNormalBlender =g_curRomInfo.dwNormalBlender;
530 currentRomOptions.bFastTexCRC =g_curRomInfo.dwFastTextureCRC;
531 currentRomOptions.bAccurateTextureMapping =g_curRomInfo.dwAccurateTextureMapping;
533 options.enableHackForGames = NO_HACK_FOR_GAME;
534 if ((strncmp((char*)g_curRomInfo.szGameName, "BANJO TOOIE", 11) == 0))
536 options.enableHackForGames = HACK_FOR_BANJO_TOOIE;
538 else if ((strncmp((char*)g_curRomInfo.szGameName, "DR.MARIO", 8) == 0))
540 options.enableHackForGames = HACK_FOR_DR_MARIO;
542 else if ((strncasecmp((char*)g_curRomInfo.szGameName, "Pilot", 5) == 0))
544 options.enableHackForGames = HACK_FOR_PILOT_WINGS;
546 else if ((strncasecmp((char*)g_curRomInfo.szGameName, "YOSHI", 5) == 0))
548 options.enableHackForGames = HACK_FOR_YOSHI;
550 else if ((strncasecmp((char*)g_curRomInfo.szGameName, "NITRO", 5) == 0))
552 options.enableHackForGames = HACK_FOR_NITRO;
554 else if ((strncasecmp((char*)g_curRomInfo.szGameName, "TONY HAWK", 9) == 0))
556 options.enableHackForGames = HACK_FOR_TONYHAWK;
558 else if ((strncasecmp((char*)g_curRomInfo.szGameName, "THPS", 4) == 0))
560 options.enableHackForGames = HACK_FOR_TONYHAWK;
562 else if ((strncasecmp((char*)g_curRomInfo.szGameName, "SPIDERMAN", 9) == 0))
564 options.enableHackForGames = HACK_FOR_TONYHAWK;
566 else if ((strncasecmp((char*)g_curRomInfo.szGameName, "NASCAR", 6) == 0))
568 options.enableHackForGames = HACK_FOR_NASCAR;
570 else if ((strstr((char*)g_curRomInfo.szGameName, "ZELDA") != 0) && (strstr((char*)g_curRomInfo.szGameName, "MASK") != 0))
572 options.enableHackForGames = HACK_FOR_ZELDA_MM;
574 else if ((strstr((char*)g_curRomInfo.szGameName, "ZELDA") != 0))
576 options.enableHackForGames = HACK_FOR_ZELDA;
578 else if ((strstr((char*)g_curRomInfo.szGameName, "Ogre") != 0))
580 options.enableHackForGames = HACK_FOR_OGRE_BATTLE;
582 else if ((strstr((char*)g_curRomInfo.szGameName, "TWINE") != 0))
584 options.enableHackForGames = HACK_FOR_TWINE;
586 else if ((strstr((char*)g_curRomInfo.szGameName, "Squadron") != 0))
588 options.enableHackForGames = HACK_FOR_ROGUE_SQUADRON;
590 else if ((strstr((char*)g_curRomInfo.szGameName, "Baseball") != 0) && (strstr((char*)g_curRomInfo.szGameName, "Star") != 0))
592 options.enableHackForGames = HACK_FOR_ALL_STAR_BASEBALL;
594 else if ((strstr((char*)g_curRomInfo.szGameName, "Tigger") != 0) && (strstr((char*)g_curRomInfo.szGameName, "Honey") != 0))
596 options.enableHackForGames = HACK_FOR_TIGER_HONEY_HUNT;
598 else if ((strstr((char*)g_curRomInfo.szGameName, "Bust") != 0) && (strstr((char*)g_curRomInfo.szGameName, "Move") != 0))
600 options.enableHackForGames = HACK_FOR_BUST_A_MOVE;
602 else if ((strncasecmp((char*)g_curRomInfo.szGameName, "MarioTennis",11) == 0))
604 options.enableHackForGames = HACK_FOR_MARIO_TENNIS;
606 else if ((strncasecmp((char*)g_curRomInfo.szGameName, "SUPER BOWLING",13) == 0))
608 options.enableHackForGames = HACK_FOR_SUPER_BOWLING;
610 else if ((strncasecmp((char*)g_curRomInfo.szGameName, "CONKER",6) == 0))
612 options.enableHackForGames = HACK_FOR_CONKER;
614 else if ((strncasecmp((char*)g_curRomInfo.szGameName, "MK_MYTHOLOGIES",14) == 0))
616 options.enableHackForGames = HACK_REVERSE_Y_COOR;
618 else if ((strncasecmp((char*)g_curRomInfo.szGameName, "Fighting Force",14) == 0))
620 options.enableHackForGames = HACK_REVERSE_XY_COOR;
622 else if ((strncasecmp((char*)g_curRomInfo.szGameName, "GOLDENEYE",9) == 0))
624 options.enableHackForGames = HACK_FOR_GOLDEN_EYE;
626 else if ((strncasecmp((char*)g_curRomInfo.szGameName, "F-ZERO",6) == 0))
628 options.enableHackForGames = HACK_FOR_FZERO;
630 else if ((strncasecmp((char*)g_curRomInfo.szGameName, "Command&Conquer",15) == 0))
632 options.enableHackForGames = HACK_FOR_COMMANDCONQUER;
634 else if ((strncasecmp((char*)g_curRomInfo.szGameName, "READY 2 RUMBLE",14) == 0))
636 options.enableHackForGames = HACK_FOR_RUMBLE;
638 else if ((strncasecmp((char*)g_curRomInfo.szGameName, "READY to RUMBLE",15) == 0))
640 options.enableHackForGames = HACK_FOR_RUMBLE;
642 else if ((strncasecmp((char*)g_curRomInfo.szGameName, "South Park Rally",16) == 0))
644 options.enableHackForGames = HACK_FOR_SOUTH_PARK_RALLY;
646 else if ((strncasecmp((char*)g_curRomInfo.szGameName, "Extreme G 2",11) == 0))
648 options.enableHackForGames = HACK_FOR_EXTREME_G2;
650 else if ((strncasecmp((char*)g_curRomInfo.szGameName, "MarioGolf64",11) == 0))
652 options.enableHackForGames = HACK_FOR_MARIO_GOLF;
654 else if ((strncasecmp((char*)g_curRomInfo.szGameName, "MLB FEATURING",13) == 0))
656 options.enableHackForGames = HACK_FOR_MLB;
658 else if ((strncasecmp((char*)g_curRomInfo.szGameName, "POLARISSNOCROSS",15) == 0))
660 options.enableHackForGames = HACK_FOR_POLARISSNOCROSS;
662 else if ((strncasecmp((char*)g_curRomInfo.szGameName, "TOP GEAR RALLY",14) == 0))
664 options.enableHackForGames = HACK_FOR_TOPGEARRALLY;
666 else if ((strncasecmp((char*)g_curRomInfo.szGameName, "DUKE NUKEM",10) == 0))
668 options.enableHackForGames = HACK_FOR_DUKE_NUKEM;
670 else if ((strncasecmp((char*)g_curRomInfo.szGameName, "MARIOKART64",11) == 0))
672 options.enableHackForGames = HACK_FOR_MARIO_KART;
675 if (options.enableHackForGames != NO_HACK_FOR_GAME)
676 DebugMessage(M64MSG_INFO, "Enabled hacks for game: '%s'", g_curRomInfo.szGameName);
678 if( currentRomOptions.N64FrameBufferEmuType == 0 ) currentRomOptions.N64FrameBufferEmuType = defaultRomOptions.N64FrameBufferEmuType;
679 else currentRomOptions.N64FrameBufferEmuType--;
680 if( currentRomOptions.N64RenderToTextureEmuType == 0 ) currentRomOptions.N64RenderToTextureEmuType = defaultRomOptions.N64RenderToTextureEmuType;
681 else currentRomOptions.N64RenderToTextureEmuType--;
682 if( currentRomOptions.screenUpdateSetting == 0 ) currentRomOptions.screenUpdateSetting = defaultRomOptions.screenUpdateSetting;
683 if( currentRomOptions.bNormalCombiner == 0 ) currentRomOptions.bNormalCombiner = defaultRomOptions.bNormalCombiner;
684 else currentRomOptions.bNormalCombiner--;
685 if( currentRomOptions.bNormalBlender == 0 ) currentRomOptions.bNormalBlender = defaultRomOptions.bNormalBlender;
686 else currentRomOptions.bNormalBlender--;
687 if( currentRomOptions.bFastTexCRC == 0 ) currentRomOptions.bFastTexCRC = defaultRomOptions.bFastTexCRC;
688 else currentRomOptions.bFastTexCRC--;
689 if( currentRomOptions.bAccurateTextureMapping == 0 ) currentRomOptions.bAccurateTextureMapping = defaultRomOptions.bAccurateTextureMapping;
690 else currentRomOptions.bAccurateTextureMapping--;
692 options.bUseFullTMEM = ((options.bFullTMEM && (g_curRomInfo.dwFullTMEM == 0)) || g_curRomInfo.dwFullTMEM == 2);
694 GenerateFrameBufferOptions();
696 if( options.enableHackForGames == HACK_FOR_MARIO_GOLF || options.enableHackForGames == HACK_FOR_MARIO_TENNIS )
698 frameBufferOptions.bIgnoreRenderTextureIfHeightUnknown = true;
702 void Ini_GetRomOptions(LPGAMESETTING pGameSetting)
706 i = FindIniEntry(pGameSetting->romheader.dwCRC1,
707 pGameSetting->romheader.dwCRC2,
708 pGameSetting->romheader.nCountryID,
709 (char*)pGameSetting->szGameName, 1);
711 pGameSetting->bDisableTextureCRC = IniSections[i].bDisableTextureCRC;
712 pGameSetting->bDisableCulling = IniSections[i].bDisableCulling;
713 pGameSetting->bIncTexRectEdge = IniSections[i].bIncTexRectEdge;
714 pGameSetting->bZHack = IniSections[i].bZHack;
715 pGameSetting->bTextureScaleHack = IniSections[i].bTextureScaleHack;
716 pGameSetting->bPrimaryDepthHack = IniSections[i].bPrimaryDepthHack;
717 pGameSetting->bTexture1Hack = IniSections[i].bTexture1Hack;
718 pGameSetting->bFastLoadTile = IniSections[i].bFastLoadTile;
719 pGameSetting->bUseSmallerTexture = IniSections[i].bUseSmallerTexture;
721 pGameSetting->VIWidth = IniSections[i].VIWidth;
722 pGameSetting->VIHeight = IniSections[i].VIHeight;
723 pGameSetting->UseCIWidthAndRatio = IniSections[i].UseCIWidthAndRatio;
724 pGameSetting->dwFullTMEM = IniSections[i].dwFullTMEM;
725 pGameSetting->bTxtSizeMethod2 = IniSections[i].bTxtSizeMethod2;
726 pGameSetting->bEnableTxtLOD = IniSections[i].bEnableTxtLOD;
728 pGameSetting->dwFastTextureCRC = IniSections[i].dwFastTextureCRC;
729 pGameSetting->bEmulateClear = IniSections[i].bEmulateClear;
730 pGameSetting->bForceScreenClear = IniSections[i].bForceScreenClear;
731 pGameSetting->dwAccurateTextureMapping = IniSections[i].dwAccurateTextureMapping;
732 pGameSetting->dwNormalBlender = IniSections[i].dwNormalBlender;
733 pGameSetting->bDisableBlender = IniSections[i].bDisableBlender;
734 pGameSetting->dwNormalCombiner = IniSections[i].dwNormalCombiner;
735 pGameSetting->bForceDepthBuffer = IniSections[i].bForceDepthBuffer;
736 pGameSetting->bDisableObjBG = IniSections[i].bDisableObjBG;
737 pGameSetting->dwFrameBufferOption = IniSections[i].dwFrameBufferOption;
738 pGameSetting->dwRenderToTextureOption = IniSections[i].dwRenderToTextureOption;
739 pGameSetting->dwScreenUpdateSetting = IniSections[i].dwScreenUpdateSetting;
742 void Ini_StoreRomOptions(LPGAMESETTING pGameSetting)
746 i = FindIniEntry(pGameSetting->romheader.dwCRC1,
747 pGameSetting->romheader.dwCRC2,
748 pGameSetting->romheader.nCountryID,
749 (char*)pGameSetting->szGameName, 0);
751 if( IniSections[i].bDisableTextureCRC !=pGameSetting->bDisableTextureCRC )
753 IniSections[i].bDisableTextureCRC =pGameSetting->bDisableTextureCRC ;
757 if( IniSections[i].bDisableCulling !=pGameSetting->bDisableCulling )
759 IniSections[i].bDisableCulling =pGameSetting->bDisableCulling ;
763 if( IniSections[i].dwFastTextureCRC !=pGameSetting->dwFastTextureCRC )
765 IniSections[i].dwFastTextureCRC =pGameSetting->dwFastTextureCRC ;
769 if( IniSections[i].bEmulateClear !=pGameSetting->bEmulateClear )
771 IniSections[i].bEmulateClear =pGameSetting->bEmulateClear ;
775 if( IniSections[i].dwNormalBlender !=pGameSetting->dwNormalBlender )
777 IniSections[i].dwNormalBlender =pGameSetting->dwNormalBlender ;
781 if( IniSections[i].bDisableBlender !=pGameSetting->bDisableBlender )
783 IniSections[i].bDisableBlender =pGameSetting->bDisableBlender ;
787 if( IniSections[i].bForceScreenClear !=pGameSetting->bForceScreenClear )
789 IniSections[i].bForceScreenClear =pGameSetting->bForceScreenClear ;
792 if( IniSections[i].dwAccurateTextureMapping !=pGameSetting->dwAccurateTextureMapping )
794 IniSections[i].dwAccurateTextureMapping =pGameSetting->dwAccurateTextureMapping ;
797 if( IniSections[i].dwNormalCombiner !=pGameSetting->dwNormalCombiner )
799 IniSections[i].dwNormalCombiner =pGameSetting->dwNormalCombiner ;
802 if( IniSections[i].bForceDepthBuffer !=pGameSetting->bForceDepthBuffer )
804 IniSections[i].bForceDepthBuffer =pGameSetting->bForceDepthBuffer ;
807 if( IniSections[i].bDisableObjBG !=pGameSetting->bDisableObjBG )
809 IniSections[i].bDisableObjBG =pGameSetting->bDisableObjBG ;
812 if( IniSections[i].dwFrameBufferOption !=pGameSetting->dwFrameBufferOption )
814 IniSections[i].dwFrameBufferOption =pGameSetting->dwFrameBufferOption ;
817 if( IniSections[i].dwRenderToTextureOption !=pGameSetting->dwRenderToTextureOption )
819 IniSections[i].dwRenderToTextureOption =pGameSetting->dwRenderToTextureOption ;
822 if( IniSections[i].dwScreenUpdateSetting !=pGameSetting->dwScreenUpdateSetting )
824 IniSections[i].dwScreenUpdateSetting =pGameSetting->dwScreenUpdateSetting ;
827 if( IniSections[i].bIncTexRectEdge != pGameSetting->bIncTexRectEdge )
829 IniSections[i].bIncTexRectEdge =pGameSetting->bIncTexRectEdge;
832 if( IniSections[i].bZHack != pGameSetting->bZHack )
834 IniSections[i].bZHack =pGameSetting->bZHack;
837 if( IniSections[i].bTextureScaleHack != pGameSetting->bTextureScaleHack )
839 IniSections[i].bTextureScaleHack =pGameSetting->bTextureScaleHack;
842 if( IniSections[i].bPrimaryDepthHack != pGameSetting->bPrimaryDepthHack )
844 IniSections[i].bPrimaryDepthHack =pGameSetting->bPrimaryDepthHack;
847 if( IniSections[i].bTexture1Hack != pGameSetting->bTexture1Hack )
849 IniSections[i].bTexture1Hack =pGameSetting->bTexture1Hack;
852 if( IniSections[i].bFastLoadTile != pGameSetting->bFastLoadTile )
854 IniSections[i].bFastLoadTile =pGameSetting->bFastLoadTile;
857 if( IniSections[i].bUseSmallerTexture != pGameSetting->bUseSmallerTexture )
859 IniSections[i].bUseSmallerTexture =pGameSetting->bUseSmallerTexture;
862 if( IniSections[i].VIWidth != pGameSetting->VIWidth )
864 IniSections[i].VIWidth =pGameSetting->VIWidth;
867 if( IniSections[i].VIHeight != pGameSetting->VIHeight )
869 IniSections[i].VIHeight =pGameSetting->VIHeight;
872 if( IniSections[i].UseCIWidthAndRatio != pGameSetting->UseCIWidthAndRatio )
874 IniSections[i].UseCIWidthAndRatio =pGameSetting->UseCIWidthAndRatio;
877 if( IniSections[i].dwFullTMEM != pGameSetting->dwFullTMEM )
879 IniSections[i].dwFullTMEM =pGameSetting->dwFullTMEM;
882 if( IniSections[i].bTxtSizeMethod2 != pGameSetting->bTxtSizeMethod2 )
884 IniSections[i].bTxtSizeMethod2 =pGameSetting->bTxtSizeMethod2;
887 if( IniSections[i].bEnableTxtLOD != pGameSetting->bEnableTxtLOD )
889 IniSections[i].bEnableTxtLOD =pGameSetting->bEnableTxtLOD;
896 TRACE0("Rom option is changed and saved");
900 std::ifstream& getline( std::ifstream &is, char *str );
902 char * left(const char * src, int nchars)
904 static char dst[300];
905 strncpy(dst,src,nchars);
910 char * right(const char *src, int nchars)
912 static char dst[300];
913 int srclen = strlen(src);
914 if (nchars >= srclen)
920 strncpy(dst, src + srclen - nchars, nchars);
926 char * tidy(char * s)
928 char * p = s + strlen(s);
931 while (p >= s && (*p == ' ' || *p == 0xa || *p == '\n') )
942 std::ifstream inifile;
944 const char *ini_filepath = ConfigGetSharedDataFilepath(szIniFileName);
946 DebugMessage(M64MSG_VERBOSE, "Reading .ini file: %s", ini_filepath);
947 inifile.open(ini_filepath);
954 while (getline(inifile,readinfo)/*&§ionno<999*/)
958 if (readinfo[0] == '/')
961 if (!strcasecmp(readinfo,"")==0)
963 if (readinfo[0] == '{') //if a section heading
967 readinfo[strlen(readinfo)-1]='\0';
968 strcpy(newsection.crccheck, readinfo+1);
970 newsection.bDisableTextureCRC = FALSE;
971 newsection.bDisableCulling = FALSE;
972 newsection.bIncTexRectEdge = FALSE;
973 newsection.bZHack = FALSE;
974 newsection.bTextureScaleHack = FALSE;
975 newsection.bFastLoadTile = FALSE;
976 newsection.bUseSmallerTexture = FALSE;
977 newsection.bPrimaryDepthHack = FALSE;
978 newsection.bTexture1Hack = FALSE;
979 newsection.bDisableObjBG = FALSE;
980 newsection.VIWidth = -1;
981 newsection.VIHeight = -1;
982 newsection.UseCIWidthAndRatio = NOT_USE_CI_WIDTH_AND_RATIO;
983 newsection.dwFullTMEM = 0;
984 newsection.bTxtSizeMethod2 = FALSE;
985 newsection.bEnableTxtLOD = FALSE;
987 newsection.bEmulateClear = FALSE;
988 newsection.bForceScreenClear = FALSE;
989 newsection.bDisableBlender = FALSE;
990 newsection.bForceDepthBuffer = FALSE;
991 newsection.dwFastTextureCRC = 0;
992 newsection.dwAccurateTextureMapping = 0;
993 newsection.dwNormalBlender = 0;
994 newsection.dwNormalCombiner = 0;
995 newsection.dwFrameBufferOption = 0;
996 newsection.dwRenderToTextureOption = 0;
997 newsection.dwScreenUpdateSetting = 0;
999 IniSections.push_back(newsection);
1004 int sectionno = IniSections.size() - 1;
1006 if (strcasecmp(left(readinfo,4), "Name")==0)
1007 strcpy(IniSections[sectionno].name,right(readinfo,strlen(readinfo)-5));
1009 if (strcasecmp(left(readinfo,17), "DisableTextureCRC")==0)
1010 IniSections[sectionno].bDisableTextureCRC=true;
1012 if (strcasecmp(left(readinfo,14), "DisableCulling")==0)
1013 IniSections[sectionno].bDisableCulling=true;
1015 if (strcasecmp(left(readinfo,16), "PrimaryDepthHack")==0)
1016 IniSections[sectionno].bPrimaryDepthHack=true;
1018 if (strcasecmp(left(readinfo,12), "Texture1Hack")==0)
1019 IniSections[sectionno].bTexture1Hack=true;
1021 if (strcasecmp(left(readinfo,12), "FastLoadTile")==0)
1022 IniSections[sectionno].bFastLoadTile=true;
1024 if (strcasecmp(left(readinfo,17), "UseSmallerTexture")==0)
1025 IniSections[sectionno].bUseSmallerTexture=true;
1027 if (strcasecmp(left(readinfo,14), "IncTexRectEdge")==0)
1028 IniSections[sectionno].bIncTexRectEdge=true;
1030 if (strcasecmp(left(readinfo,5), "ZHack")==0)
1031 IniSections[sectionno].bZHack=true;
1033 if (strcasecmp(left(readinfo,16), "TexRectScaleHack")==0)
1034 IniSections[sectionno].bTextureScaleHack=true;
1036 if (strcasecmp(left(readinfo,7), "VIWidth")==0)
1037 IniSections[sectionno].VIWidth = strtol(right(readinfo,3),NULL,10);
1039 if (strcasecmp(left(readinfo,8), "VIHeight")==0)
1040 IniSections[sectionno].VIHeight = strtol(right(readinfo,3),NULL,10);
1042 if (strcasecmp(left(readinfo,18), "UseCIWidthAndRatio")==0)
1043 IniSections[sectionno].UseCIWidthAndRatio = strtol(right(readinfo,1),NULL,10);
1045 if (strcasecmp(left(readinfo,8), "FullTMEM")==0)
1046 IniSections[sectionno].dwFullTMEM = strtol(right(readinfo,1),NULL,10);
1048 if (strcasecmp(left(readinfo,24), "AlternativeTxtSizeMethod")==0)
1049 IniSections[sectionno].bTxtSizeMethod2 = strtol(right(readinfo,1),NULL,10);
1051 if (strcasecmp(left(readinfo,12), "EnableTxtLOD")==0)
1052 IniSections[sectionno].bEnableTxtLOD = strtol(right(readinfo,1),NULL,10);
1054 if (strcasecmp(left(readinfo,12), "DisableObjBG")==0)
1055 IniSections[sectionno].bDisableObjBG = strtol(right(readinfo,1),NULL,10);
1057 if (strcasecmp(left(readinfo,16), "ForceScreenClear")==0)
1058 IniSections[sectionno].bForceScreenClear = strtol(right(readinfo,1),NULL,10);
1060 if (strcasecmp(left(readinfo,22), "AccurateTextureMapping")==0)
1061 IniSections[sectionno].dwAccurateTextureMapping = strtol(right(readinfo,1),NULL,10);
1063 if (strcasecmp(left(readinfo,14), "FastTextureCRC")==0)
1064 IniSections[sectionno].dwFastTextureCRC = strtol(right(readinfo,1),NULL,10);
1066 if (strcasecmp(left(readinfo,12), "EmulateClear")==0)
1067 IniSections[sectionno].bEmulateClear = strtol(right(readinfo,1),NULL,10);
1069 if (strcasecmp(left(readinfo,18), "NormalAlphaBlender")==0)
1070 IniSections[sectionno].dwNormalBlender = strtol(right(readinfo,1),NULL,10);
1072 if (strcasecmp(left(readinfo,19), "DisableAlphaBlender")==0)
1073 IniSections[sectionno].bDisableBlender = strtol(right(readinfo,1),NULL,10);
1075 if (strcasecmp(left(readinfo,19), "NormalColorCombiner")==0)
1076 IniSections[sectionno].dwNormalCombiner = strtol(right(readinfo,1),NULL,10);
1078 if (strcasecmp(left(readinfo,16), "ForceDepthBuffer")==0)
1079 IniSections[sectionno].bForceDepthBuffer = strtol(right(readinfo,1),NULL,10);
1081 if (strcasecmp(left(readinfo,20), "FrameBufferEmulation")==0)
1082 IniSections[sectionno].dwFrameBufferOption = strtol(readinfo+21,NULL,10);
1084 if (strcasecmp(left(readinfo,15), "RenderToTexture")==0)
1085 IniSections[sectionno].dwRenderToTextureOption = strtol(right(readinfo,1),NULL,10);
1087 if (strcasecmp(left(readinfo,19), "ScreenUpdateSetting")==0)
1088 IniSections[sectionno].dwScreenUpdateSetting = strtol(right(readinfo,1),NULL,10);
1097 //read a line from the ini file
1098 std::ifstream & getline(std::ifstream & is, char *str)
1102 is.getline(buf,100);
1113 /* get path to game-hack INI file and read it */
1114 const char *ini_filepath = ConfigGetSharedDataFilepath(szIniFileName);
1115 if (ini_filepath == NULL)
1117 fhIn = fopen(ini_filepath, "r");
1120 fseek(fhIn, 0L, SEEK_END);
1121 long filelen = ftell(fhIn);
1122 fseek(fhIn, 0L, SEEK_SET);
1123 char *chIniData = (char *) malloc(filelen + 1);
1124 if (chIniData == NULL)
1129 long bytesread = fread(chIniData, 1, filelen, fhIn);
1131 if (bytesread != filelen)
1136 chIniData[filelen] = 0;
1138 /* now try to open the file for writing */
1139 fhOut = fopen(ini_filepath, "w");
1146 // Mark all sections and needing to be written
1147 for (i = 0; i < IniSections.size(); i++)
1149 IniSections[i].bOutput = false;
1152 char *thisline = chIniData;
1153 while ((thisline - chIniData) < filelen)
1155 char *nextline = strchr(thisline, '\n');
1156 if (nextline == NULL)
1157 nextline = thisline + strlen(thisline) + 1;
1160 if (thisline[0] == '{')
1162 BOOL bFound = FALSE;
1164 tidy((char*) thisline);
1165 thisline[strlen(thisline) - 1] = '\0';
1166 for (i = 0; i < IniSections.size(); i++)
1168 if (IniSections[i].bOutput)
1170 if (strcasecmp((char*) thisline + 1, IniSections[i].crccheck) == 0)
1173 OutputSectionDetails(i, fhOut);
1174 IniSections[i].bOutput = true;
1181 // Do what? This should never happen, unless the user
1182 // replaces the inifile while game is running!
1185 else if (thisline[0] == '/')
1188 fputs((char*) thisline, fhOut);
1190 thisline = nextline;
1193 // Input buffer done- process any new entries!
1194 for (i = 0; i < IniSections.size(); i++)
1196 // Skip any that have not been done.
1197 if (IniSections[i].bOutput)
1200 OutputSectionDetails(i, fhOut);
1201 IniSections[i].bOutput = true;
1207 bIniIsChanged = false;
1210 void OutputSectionDetails(uint32 i, FILE * fh)
1212 fprintf(fh, "{%s}\n", IniSections[i].crccheck);
1214 fprintf(fh, "Name=%s\n", IniSections[i].name);
1215 //fprintf(fh, "UCode=%d\n", IniSections[i].ucode);
1217 // Tri-state variables
1218 if (IniSections[i].dwAccurateTextureMapping != 0)
1219 fprintf(fh, "AccurateTextureMapping=%d\n", IniSections[i].dwAccurateTextureMapping);
1221 if (IniSections[i].dwFastTextureCRC != 0)
1222 fprintf(fh, "FastTextureCRC=%d\n", IniSections[i].dwFastTextureCRC);
1224 if (IniSections[i].dwNormalBlender != 0)
1225 fprintf(fh, "NormalAlphaBlender=%d\n", IniSections[i].dwNormalBlender);
1227 if (IniSections[i].dwNormalCombiner != 0)
1228 fprintf(fh, "NormalColorCombiner=%d\n", IniSections[i].dwNormalCombiner);
1231 // Normal bi-state variables
1232 if (IniSections[i].bDisableTextureCRC)
1233 fprintf(fh, "DisableTextureCRC\n");
1235 if (IniSections[i].bDisableCulling)
1236 fprintf(fh, "DisableCulling\n");
1238 if (IniSections[i].bPrimaryDepthHack)
1239 fprintf(fh, "PrimaryDepthHack\n");
1241 if (IniSections[i].bTexture1Hack)
1242 fprintf(fh, "Texture1Hack\n");
1244 if (IniSections[i].bFastLoadTile)
1245 fprintf(fh, "FastLoadTile\n");
1247 if (IniSections[i].bUseSmallerTexture)
1248 fprintf(fh, "UseSmallerTexture\n");
1250 if (IniSections[i].bIncTexRectEdge)
1251 fprintf(fh, "IncTexRectEdge\n");
1253 if (IniSections[i].bZHack)
1254 fprintf(fh, "ZHack\n");
1256 if (IniSections[i].bTextureScaleHack)
1257 fprintf(fh, "TexRectScaleHack\n");
1259 if (IniSections[i].VIWidth > 0)
1260 fprintf(fh, "VIWidth=%d\n", IniSections[i].VIWidth);
1262 if (IniSections[i].VIHeight > 0)
1263 fprintf(fh, "VIHeight=%d\n", IniSections[i].VIHeight);
1265 if (IniSections[i].UseCIWidthAndRatio > 0)
1266 fprintf(fh, "UseCIWidthAndRatio=%d\n", IniSections[i].UseCIWidthAndRatio);
1268 if (IniSections[i].dwFullTMEM > 0)
1269 fprintf(fh, "FullTMEM=%d\n", IniSections[i].dwFullTMEM);
1271 if (IniSections[i].bTxtSizeMethod2 != FALSE )
1272 fprintf(fh, "AlternativeTxtSizeMethod=%d\n", IniSections[i].bTxtSizeMethod2);
1274 if (IniSections[i].bEnableTxtLOD != FALSE )
1275 fprintf(fh, "EnableTxtLOD=%d\n", IniSections[i].bEnableTxtLOD);
1277 if (IniSections[i].bDisableObjBG != 0 )
1278 fprintf(fh, "DisableObjBG=%d\n", IniSections[i].bDisableObjBG);
1280 if (IniSections[i].bForceScreenClear != 0)
1281 fprintf(fh, "ForceScreenClear=%d\n", IniSections[i].bForceScreenClear);
1283 if (IniSections[i].bEmulateClear != 0)
1284 fprintf(fh, "EmulateClear=%d\n", IniSections[i].bEmulateClear);
1286 if (IniSections[i].bDisableBlender != 0)
1287 fprintf(fh, "DisableAlphaBlender=%d\n", IniSections[i].bDisableBlender);
1289 if (IniSections[i].bForceDepthBuffer != 0)
1290 fprintf(fh, "ForceDepthBuffer=%d\n", IniSections[i].bForceDepthBuffer);
1292 if (IniSections[i].dwFrameBufferOption != 0)
1293 fprintf(fh, "FrameBufferEmulation=%d\n", IniSections[i].dwFrameBufferOption);
1295 if (IniSections[i].dwRenderToTextureOption != 0)
1296 fprintf(fh, "RenderToTexture=%d\n", IniSections[i].dwRenderToTextureOption);
1298 if (IniSections[i].dwScreenUpdateSetting != 0)
1299 fprintf(fh, "ScreenUpdateSetting=%d\n", IniSections[i].dwScreenUpdateSetting);
1301 fprintf(fh, "\n"); // Spacer
1304 // Find the entry corresponding to the specified rom.
1305 // If the rom is not found, a new entry is created
1306 // The resulting value is returned
1307 void __cdecl DebuggerAppendMsg (const char * Message, ...);
1309 static int FindIniEntry(uint32 dwCRC1, uint32 dwCRC2, uint8 nCountryID, char* szName, int PrintInfo)
1312 unsigned char szCRC[50+1];
1314 // Generate the CRC-ID for this rom:
1315 sprintf((char*)szCRC, "%08x%08x-%02x", (unsigned int)dwCRC1, (unsigned int)dwCRC2, nCountryID);
1317 for (i = 0; i < IniSections.size(); i++)
1319 if (strcasecmp((char*)szCRC, IniSections[i].crccheck) == 0)
1322 DebugMessage(M64MSG_INFO, "Found ROM '%s', CRC %s", IniSections[i].name, szCRC);
1331 DebugMessage(M64MSG_INFO, "ROM (CRC %s) not found in INI file", szCRC);
1333 strcpy(newsection.crccheck, (char*)szCRC);
1335 strncpy(newsection.name, szName, 50);
1336 newsection.bDisableTextureCRC = FALSE;
1337 newsection.bDisableCulling = FALSE;
1338 newsection.bIncTexRectEdge = FALSE;
1339 newsection.bZHack = FALSE;
1340 newsection.bTextureScaleHack = FALSE;
1341 newsection.bFastLoadTile = FALSE;
1342 newsection.bUseSmallerTexture = FALSE;
1343 newsection.bPrimaryDepthHack = FALSE;
1344 newsection.bTexture1Hack = FALSE;
1345 newsection.bDisableObjBG = FALSE;
1346 newsection.VIWidth = -1;
1347 newsection.VIHeight = -1;
1348 newsection.UseCIWidthAndRatio = NOT_USE_CI_WIDTH_AND_RATIO;
1349 newsection.dwFullTMEM = 0;
1350 newsection.bTxtSizeMethod2 = FALSE;
1351 newsection.bEnableTxtLOD = FALSE;
1353 newsection.bEmulateClear = FALSE;
1354 newsection.bForceScreenClear = FALSE;
1355 newsection.bDisableBlender = FALSE;
1356 newsection.bForceDepthBuffer = FALSE;
1357 newsection.dwFastTextureCRC = 0;
1358 newsection.dwAccurateTextureMapping = 0;
1359 newsection.dwNormalBlender = 0;
1360 newsection.dwNormalCombiner = 0;
1361 newsection.dwFrameBufferOption = 0;
1362 newsection.dwRenderToTextureOption = 0;
1363 newsection.dwScreenUpdateSetting = 0;
1365 IniSections.push_back(newsection);
1367 bIniIsChanged = true; // Flag to indicate we should be updated
1368 return IniSections.size()-1; // -1 takes into account increment
1371 GameSetting g_curRomInfo;
1373 void ROM_GetRomNameFromHeader(unsigned char * szName, ROMHeader * pHdr)
1377 memcpy(szName, pHdr->szName, 20);
1380 p = szName + (strlen((char*)szName) -1); // -1 to skip null
1381 while (p >= szName && *p == ' ')
1388 uint32 CountryCodeToTVSystem(uint32 countryCode)
1395 system = TV_SYSTEM_NTSC;
1399 system = TV_SYSTEM_NTSC;
1403 system = TV_SYSTEM_NTSC;
1408 system = TV_SYSTEM_PAL;
1413 system = TV_SYSTEM_NTSC;
1418 system = TV_SYSTEM_PAL;
1423 system = TV_SYSTEM_PAL;
1428 system = TV_SYSTEM_NTSC;
1433 system = TV_SYSTEM_PAL;
1436 case 'S': /* Spain */
1437 system = TV_SYSTEM_PAL;
1442 system = TV_SYSTEM_PAL;
1446 system = TV_SYSTEM_PAL;
1451 system = TV_SYSTEM_PAL;
1458 system = TV_SYSTEM_PAL;
1463 system = TV_SYSTEM_PAL;