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");
435 if (windowSetting.uDisplayWidth==800)
436 windowSetting.uDisplayWidth = 640; // no strech
438 windowSetting.uDisplayHeight = ConfigGetParamInt(l_ConfigVideoGeneral, "ScreenHeight");
439 windowSetting.bVerticalSync = ConfigGetParamBool(l_ConfigVideoGeneral, "VerticalSync");
441 defaultRomOptions.N64FrameBufferEmuType = ConfigGetParamInt(l_ConfigVideoRice, "FrameBufferSetting");
442 defaultRomOptions.N64FrameBufferWriteBackControl = ConfigGetParamInt(l_ConfigVideoRice, "FrameBufferWriteBackControl");
443 defaultRomOptions.N64RenderToTextureEmuType = ConfigGetParamInt(l_ConfigVideoRice, "RenderToTexture");
444 defaultRomOptions.screenUpdateSetting = ConfigGetParamInt(l_ConfigVideoRice, "screenUpdateSetting");
446 defaultRomOptions.bNormalBlender = ConfigGetParamBool(l_ConfigVideoRice, "NormalAlphaBlender");
447 defaultRomOptions.bFastTexCRC = ConfigGetParamBool(l_ConfigVideoRice, "FastTextureLoading");
448 defaultRomOptions.bAccurateTextureMapping = ConfigGetParamBool(l_ConfigVideoRice, "AccurateTextureMapping");
449 defaultRomOptions.bInN64Resolution = ConfigGetParamBool(l_ConfigVideoRice, "InN64Resolution");
450 defaultRomOptions.bSaveVRAM = ConfigGetParamBool(l_ConfigVideoRice, "SaveVRAM");
451 defaultRomOptions.bDoubleSizeForSmallTxtrBuf = ConfigGetParamBool(l_ConfigVideoRice, "DoubleSizeForSmallTxtrBuf");
452 defaultRomOptions.bNormalCombiner = ConfigGetParamBool(l_ConfigVideoRice, "DefaultCombinerDisable");
454 options.bEnableHacks = ConfigGetParamBool(l_ConfigVideoRice, "EnableHacks");
455 options.bWinFrameMode = ConfigGetParamBool(l_ConfigVideoRice, "WinFrameMode");
456 options.bFullTMEM = ConfigGetParamBool(l_ConfigVideoRice, "FullTMEMEmulation");
457 options.bOGLVertexClipper = ConfigGetParamBool(l_ConfigVideoRice, "OpenGLVertexClipper");
458 options.bEnableSSE = ConfigGetParamBool(l_ConfigVideoRice, "EnableSSE");
459 options.bEnableVertexShader = ConfigGetParamBool(l_ConfigVideoRice, "EnableVertexShader");
460 options.bSkipFrame = ConfigGetParamBool(l_ConfigVideoRice, "SkipFrame");
461 options.bTexRectOnly = ConfigGetParamBool(l_ConfigVideoRice, "TexRectOnly");
462 options.bSmallTextureOnly = ConfigGetParamBool(l_ConfigVideoRice, "SmallTextureOnly");
463 options.bLoadHiResTextures = ConfigGetParamBool(l_ConfigVideoRice, "LoadHiResTextures");
464 options.bLoadHiResCRCOnly = ConfigGetParamBool(l_ConfigVideoRice, "LoadHiResCRCOnly");
465 options.bDumpTexturesToFiles = ConfigGetParamBool(l_ConfigVideoRice, "DumpTexturesToFiles");
466 options.bShowFPS = ConfigGetParamBool(l_ConfigVideoRice, "ShowFPS");
468 options.mipmapping = ConfigGetParamInt(l_ConfigVideoRice, "Mipmapping");
469 options.fogMethod = ConfigGetParamInt(l_ConfigVideoRice, "FogMethod");
470 options.forceTextureFilter = ConfigGetParamInt(l_ConfigVideoRice, "ForceTextureFilter");
471 options.textureEnhancement = ConfigGetParamInt(l_ConfigVideoRice, "TextureEnhancement");
472 options.textureEnhancementControl = ConfigGetParamInt(l_ConfigVideoRice, "TextureEnhancementControl");
473 options.textureQuality = ConfigGetParamInt(l_ConfigVideoRice, "TextureQuality");
474 options.OpenglDepthBufferSetting = ConfigGetParamInt(l_ConfigVideoRice, "OpenGLDepthBufferSetting");
475 options.multiSampling = ConfigGetParamInt(l_ConfigVideoRice, "MultiSampling");
476 options.colorQuality = ConfigGetParamInt(l_ConfigVideoRice, "ColorQuality");
477 options.OpenglRenderSetting = ConfigGetParamInt(l_ConfigVideoRice, "OpenGLRenderSetting");
478 options.anisotropicFiltering = ConfigGetParamInt(l_ConfigVideoRice, "AnisotropicFiltering");
480 CDeviceBuilder::SelectDeviceType((SupportedDeviceType)options.OpenglRenderSetting);
482 status.isMMXSupported = isMMXSupported();
483 status.isSSESupported = isSSESupported();
484 status.isVertexShaderSupported = false;
486 status.isSSEEnabled = status.isSSESupported && options.bEnableSSE;
488 if( status.isSSEEnabled )
490 ProcessVertexData = ProcessVertexDataSSE;
491 DebugMessage(M64MSG_INFO, "SSE processing enabled.");
496 ProcessVertexData = ProcessVertexDataNoSSE;
497 DebugMessage(M64MSG_INFO, "Disabled SSE processing.");
500 status.isVertexShaderEnabled = status.isVertexShaderSupported && options.bEnableVertexShader;
501 status.bUseHW_T_L = false;
504 BOOL LoadConfiguration(void)
507 bIniIsChanged = false;
508 strcpy(szIniFileName, INI_FILE);
512 DebugMessage(M64MSG_ERROR, "Unable to read ini file from disk");
516 if (l_ConfigVideoGeneral == NULL || l_ConfigVideoRice == NULL)
518 DebugMessage(M64MSG_ERROR, "Rice Video configuration sections are not open!");
522 // Read config parameters from core config API and set up internal variables
528 void GenerateCurrentRomOptions()
530 currentRomOptions.N64FrameBufferEmuType =g_curRomInfo.dwFrameBufferOption;
531 currentRomOptions.N64FrameBufferWriteBackControl =defaultRomOptions.N64FrameBufferWriteBackControl;
532 currentRomOptions.N64RenderToTextureEmuType =g_curRomInfo.dwRenderToTextureOption;
533 currentRomOptions.screenUpdateSetting =g_curRomInfo.dwScreenUpdateSetting;
534 currentRomOptions.bNormalCombiner =g_curRomInfo.dwNormalCombiner;
535 currentRomOptions.bNormalBlender =g_curRomInfo.dwNormalBlender;
536 currentRomOptions.bFastTexCRC =g_curRomInfo.dwFastTextureCRC;
537 currentRomOptions.bAccurateTextureMapping =g_curRomInfo.dwAccurateTextureMapping;
539 options.enableHackForGames = NO_HACK_FOR_GAME;
540 if ((strncmp((char*)g_curRomInfo.szGameName, "BANJO TOOIE", 11) == 0))
542 options.enableHackForGames = HACK_FOR_BANJO_TOOIE;
544 else if ((strncmp((char*)g_curRomInfo.szGameName, "DR.MARIO", 8) == 0))
546 options.enableHackForGames = HACK_FOR_DR_MARIO;
548 else if ((strncasecmp((char*)g_curRomInfo.szGameName, "Pilot", 5) == 0))
550 options.enableHackForGames = HACK_FOR_PILOT_WINGS;
552 else if ((strncasecmp((char*)g_curRomInfo.szGameName, "YOSHI", 5) == 0))
554 options.enableHackForGames = HACK_FOR_YOSHI;
556 else if ((strncasecmp((char*)g_curRomInfo.szGameName, "NITRO", 5) == 0))
558 options.enableHackForGames = HACK_FOR_NITRO;
560 else if ((strncasecmp((char*)g_curRomInfo.szGameName, "TONY HAWK", 9) == 0))
562 options.enableHackForGames = HACK_FOR_TONYHAWK;
564 else if ((strncasecmp((char*)g_curRomInfo.szGameName, "THPS", 4) == 0))
566 options.enableHackForGames = HACK_FOR_TONYHAWK;
568 else if ((strncasecmp((char*)g_curRomInfo.szGameName, "SPIDERMAN", 9) == 0))
570 options.enableHackForGames = HACK_FOR_TONYHAWK;
572 else if ((strncasecmp((char*)g_curRomInfo.szGameName, "NASCAR", 6) == 0))
574 options.enableHackForGames = HACK_FOR_NASCAR;
576 else if ((strstr((char*)g_curRomInfo.szGameName, "ZELDA") != 0) && (strstr((char*)g_curRomInfo.szGameName, "MASK") != 0))
578 options.enableHackForGames = HACK_FOR_ZELDA_MM;
580 else if ((strstr((char*)g_curRomInfo.szGameName, "ZELDA") != 0))
582 options.enableHackForGames = HACK_FOR_ZELDA;
584 else if ((strstr((char*)g_curRomInfo.szGameName, "Ogre") != 0))
586 options.enableHackForGames = HACK_FOR_OGRE_BATTLE;
588 else if ((strstr((char*)g_curRomInfo.szGameName, "TWINE") != 0))
590 options.enableHackForGames = HACK_FOR_TWINE;
592 else if ((strstr((char*)g_curRomInfo.szGameName, "Squadron") != 0))
594 options.enableHackForGames = HACK_FOR_ROGUE_SQUADRON;
596 else if ((strstr((char*)g_curRomInfo.szGameName, "Baseball") != 0) && (strstr((char*)g_curRomInfo.szGameName, "Star") != 0))
598 options.enableHackForGames = HACK_FOR_ALL_STAR_BASEBALL;
600 else if ((strstr((char*)g_curRomInfo.szGameName, "Tigger") != 0) && (strstr((char*)g_curRomInfo.szGameName, "Honey") != 0))
602 options.enableHackForGames = HACK_FOR_TIGER_HONEY_HUNT;
604 else if ((strstr((char*)g_curRomInfo.szGameName, "Bust") != 0) && (strstr((char*)g_curRomInfo.szGameName, "Move") != 0))
606 options.enableHackForGames = HACK_FOR_BUST_A_MOVE;
608 else if ((strncasecmp((char*)g_curRomInfo.szGameName, "MarioTennis",11) == 0))
610 options.enableHackForGames = HACK_FOR_MARIO_TENNIS;
612 else if ((strncasecmp((char*)g_curRomInfo.szGameName, "SUPER BOWLING",13) == 0))
614 options.enableHackForGames = HACK_FOR_SUPER_BOWLING;
616 else if ((strncasecmp((char*)g_curRomInfo.szGameName, "CONKER",6) == 0))
618 options.enableHackForGames = HACK_FOR_CONKER;
620 else if ((strncasecmp((char*)g_curRomInfo.szGameName, "MK_MYTHOLOGIES",14) == 0))
622 options.enableHackForGames = HACK_REVERSE_Y_COOR;
624 else if ((strncasecmp((char*)g_curRomInfo.szGameName, "Fighting Force",14) == 0))
626 options.enableHackForGames = HACK_REVERSE_XY_COOR;
628 else if ((strncasecmp((char*)g_curRomInfo.szGameName, "GOLDENEYE",9) == 0))
630 options.enableHackForGames = HACK_FOR_GOLDEN_EYE;
632 else if ((strncasecmp((char*)g_curRomInfo.szGameName, "F-ZERO",6) == 0))
634 options.enableHackForGames = HACK_FOR_FZERO;
636 else if ((strncasecmp((char*)g_curRomInfo.szGameName, "Command&Conquer",15) == 0))
638 options.enableHackForGames = HACK_FOR_COMMANDCONQUER;
640 else if ((strncasecmp((char*)g_curRomInfo.szGameName, "READY 2 RUMBLE",14) == 0))
642 options.enableHackForGames = HACK_FOR_RUMBLE;
644 else if ((strncasecmp((char*)g_curRomInfo.szGameName, "READY to RUMBLE",15) == 0))
646 options.enableHackForGames = HACK_FOR_RUMBLE;
648 else if ((strncasecmp((char*)g_curRomInfo.szGameName, "South Park Rally",16) == 0))
650 options.enableHackForGames = HACK_FOR_SOUTH_PARK_RALLY;
652 else if ((strncasecmp((char*)g_curRomInfo.szGameName, "Extreme G 2",11) == 0))
654 options.enableHackForGames = HACK_FOR_EXTREME_G2;
656 else if ((strncasecmp((char*)g_curRomInfo.szGameName, "MarioGolf64",11) == 0))
658 options.enableHackForGames = HACK_FOR_MARIO_GOLF;
660 else if ((strncasecmp((char*)g_curRomInfo.szGameName, "MLB FEATURING",13) == 0))
662 options.enableHackForGames = HACK_FOR_MLB;
664 else if ((strncasecmp((char*)g_curRomInfo.szGameName, "POLARISSNOCROSS",15) == 0))
666 options.enableHackForGames = HACK_FOR_POLARISSNOCROSS;
668 else if ((strncasecmp((char*)g_curRomInfo.szGameName, "TOP GEAR RALLY",14) == 0))
670 options.enableHackForGames = HACK_FOR_TOPGEARRALLY;
672 else if ((strncasecmp((char*)g_curRomInfo.szGameName, "DUKE NUKEM",10) == 0))
674 options.enableHackForGames = HACK_FOR_DUKE_NUKEM;
676 else if ((strncasecmp((char*)g_curRomInfo.szGameName, "MARIOKART64",11) == 0))
678 options.enableHackForGames = HACK_FOR_MARIO_KART;
681 if (options.enableHackForGames != NO_HACK_FOR_GAME)
682 DebugMessage(M64MSG_INFO, "Enabled hacks for game: '%s'", g_curRomInfo.szGameName);
684 if( currentRomOptions.N64FrameBufferEmuType == 0 ) currentRomOptions.N64FrameBufferEmuType = defaultRomOptions.N64FrameBufferEmuType;
685 else currentRomOptions.N64FrameBufferEmuType--;
686 if( currentRomOptions.N64RenderToTextureEmuType == 0 ) currentRomOptions.N64RenderToTextureEmuType = defaultRomOptions.N64RenderToTextureEmuType;
687 else currentRomOptions.N64RenderToTextureEmuType--;
688 if( currentRomOptions.screenUpdateSetting == 0 ) currentRomOptions.screenUpdateSetting = defaultRomOptions.screenUpdateSetting;
689 if( currentRomOptions.bNormalCombiner == 0 ) currentRomOptions.bNormalCombiner = defaultRomOptions.bNormalCombiner;
690 else currentRomOptions.bNormalCombiner--;
691 if( currentRomOptions.bNormalBlender == 0 ) currentRomOptions.bNormalBlender = defaultRomOptions.bNormalBlender;
692 else currentRomOptions.bNormalBlender--;
693 if( currentRomOptions.bFastTexCRC == 0 ) currentRomOptions.bFastTexCRC = defaultRomOptions.bFastTexCRC;
694 else currentRomOptions.bFastTexCRC--;
695 if( currentRomOptions.bAccurateTextureMapping == 0 ) currentRomOptions.bAccurateTextureMapping = defaultRomOptions.bAccurateTextureMapping;
696 else currentRomOptions.bAccurateTextureMapping--;
698 options.bUseFullTMEM = ((options.bFullTMEM && (g_curRomInfo.dwFullTMEM == 0)) || g_curRomInfo.dwFullTMEM == 2);
700 GenerateFrameBufferOptions();
702 if( options.enableHackForGames == HACK_FOR_MARIO_GOLF || options.enableHackForGames == HACK_FOR_MARIO_TENNIS )
704 frameBufferOptions.bIgnoreRenderTextureIfHeightUnknown = true;
708 void Ini_GetRomOptions(LPGAMESETTING pGameSetting)
712 i = FindIniEntry(pGameSetting->romheader.dwCRC1,
713 pGameSetting->romheader.dwCRC2,
714 pGameSetting->romheader.nCountryID,
715 (char*)pGameSetting->szGameName, 1);
717 pGameSetting->bDisableTextureCRC = IniSections[i].bDisableTextureCRC;
718 pGameSetting->bDisableCulling = IniSections[i].bDisableCulling;
719 pGameSetting->bIncTexRectEdge = IniSections[i].bIncTexRectEdge;
720 pGameSetting->bZHack = IniSections[i].bZHack;
721 pGameSetting->bTextureScaleHack = IniSections[i].bTextureScaleHack;
722 pGameSetting->bPrimaryDepthHack = IniSections[i].bPrimaryDepthHack;
723 pGameSetting->bTexture1Hack = IniSections[i].bTexture1Hack;
724 pGameSetting->bFastLoadTile = IniSections[i].bFastLoadTile;
725 pGameSetting->bUseSmallerTexture = IniSections[i].bUseSmallerTexture;
727 pGameSetting->VIWidth = IniSections[i].VIWidth;
728 pGameSetting->VIHeight = IniSections[i].VIHeight;
729 pGameSetting->UseCIWidthAndRatio = IniSections[i].UseCIWidthAndRatio;
730 pGameSetting->dwFullTMEM = IniSections[i].dwFullTMEM;
731 pGameSetting->bTxtSizeMethod2 = IniSections[i].bTxtSizeMethod2;
732 pGameSetting->bEnableTxtLOD = IniSections[i].bEnableTxtLOD;
734 pGameSetting->dwFastTextureCRC = IniSections[i].dwFastTextureCRC;
735 pGameSetting->bEmulateClear = IniSections[i].bEmulateClear;
736 pGameSetting->bForceScreenClear = IniSections[i].bForceScreenClear;
737 pGameSetting->dwAccurateTextureMapping = IniSections[i].dwAccurateTextureMapping;
738 pGameSetting->dwNormalBlender = IniSections[i].dwNormalBlender;
739 pGameSetting->bDisableBlender = IniSections[i].bDisableBlender;
740 pGameSetting->dwNormalCombiner = IniSections[i].dwNormalCombiner;
741 pGameSetting->bForceDepthBuffer = IniSections[i].bForceDepthBuffer;
742 pGameSetting->bDisableObjBG = IniSections[i].bDisableObjBG;
743 pGameSetting->dwFrameBufferOption = IniSections[i].dwFrameBufferOption;
744 pGameSetting->dwRenderToTextureOption = IniSections[i].dwRenderToTextureOption;
745 pGameSetting->dwScreenUpdateSetting = IniSections[i].dwScreenUpdateSetting;
748 void Ini_StoreRomOptions(LPGAMESETTING pGameSetting)
752 i = FindIniEntry(pGameSetting->romheader.dwCRC1,
753 pGameSetting->romheader.dwCRC2,
754 pGameSetting->romheader.nCountryID,
755 (char*)pGameSetting->szGameName, 0);
757 if( IniSections[i].bDisableTextureCRC !=pGameSetting->bDisableTextureCRC )
759 IniSections[i].bDisableTextureCRC =pGameSetting->bDisableTextureCRC ;
763 if( IniSections[i].bDisableCulling !=pGameSetting->bDisableCulling )
765 IniSections[i].bDisableCulling =pGameSetting->bDisableCulling ;
769 if( IniSections[i].dwFastTextureCRC !=pGameSetting->dwFastTextureCRC )
771 IniSections[i].dwFastTextureCRC =pGameSetting->dwFastTextureCRC ;
775 if( IniSections[i].bEmulateClear !=pGameSetting->bEmulateClear )
777 IniSections[i].bEmulateClear =pGameSetting->bEmulateClear ;
781 if( IniSections[i].dwNormalBlender !=pGameSetting->dwNormalBlender )
783 IniSections[i].dwNormalBlender =pGameSetting->dwNormalBlender ;
787 if( IniSections[i].bDisableBlender !=pGameSetting->bDisableBlender )
789 IniSections[i].bDisableBlender =pGameSetting->bDisableBlender ;
793 if( IniSections[i].bForceScreenClear !=pGameSetting->bForceScreenClear )
795 IniSections[i].bForceScreenClear =pGameSetting->bForceScreenClear ;
798 if( IniSections[i].dwAccurateTextureMapping !=pGameSetting->dwAccurateTextureMapping )
800 IniSections[i].dwAccurateTextureMapping =pGameSetting->dwAccurateTextureMapping ;
803 if( IniSections[i].dwNormalCombiner !=pGameSetting->dwNormalCombiner )
805 IniSections[i].dwNormalCombiner =pGameSetting->dwNormalCombiner ;
808 if( IniSections[i].bForceDepthBuffer !=pGameSetting->bForceDepthBuffer )
810 IniSections[i].bForceDepthBuffer =pGameSetting->bForceDepthBuffer ;
813 if( IniSections[i].bDisableObjBG !=pGameSetting->bDisableObjBG )
815 IniSections[i].bDisableObjBG =pGameSetting->bDisableObjBG ;
818 if( IniSections[i].dwFrameBufferOption !=pGameSetting->dwFrameBufferOption )
820 IniSections[i].dwFrameBufferOption =pGameSetting->dwFrameBufferOption ;
823 if( IniSections[i].dwRenderToTextureOption !=pGameSetting->dwRenderToTextureOption )
825 IniSections[i].dwRenderToTextureOption =pGameSetting->dwRenderToTextureOption ;
828 if( IniSections[i].dwScreenUpdateSetting !=pGameSetting->dwScreenUpdateSetting )
830 IniSections[i].dwScreenUpdateSetting =pGameSetting->dwScreenUpdateSetting ;
833 if( IniSections[i].bIncTexRectEdge != pGameSetting->bIncTexRectEdge )
835 IniSections[i].bIncTexRectEdge =pGameSetting->bIncTexRectEdge;
838 if( IniSections[i].bZHack != pGameSetting->bZHack )
840 IniSections[i].bZHack =pGameSetting->bZHack;
843 if( IniSections[i].bTextureScaleHack != pGameSetting->bTextureScaleHack )
845 IniSections[i].bTextureScaleHack =pGameSetting->bTextureScaleHack;
848 if( IniSections[i].bPrimaryDepthHack != pGameSetting->bPrimaryDepthHack )
850 IniSections[i].bPrimaryDepthHack =pGameSetting->bPrimaryDepthHack;
853 if( IniSections[i].bTexture1Hack != pGameSetting->bTexture1Hack )
855 IniSections[i].bTexture1Hack =pGameSetting->bTexture1Hack;
858 if( IniSections[i].bFastLoadTile != pGameSetting->bFastLoadTile )
860 IniSections[i].bFastLoadTile =pGameSetting->bFastLoadTile;
863 if( IniSections[i].bUseSmallerTexture != pGameSetting->bUseSmallerTexture )
865 IniSections[i].bUseSmallerTexture =pGameSetting->bUseSmallerTexture;
868 if( IniSections[i].VIWidth != pGameSetting->VIWidth )
870 IniSections[i].VIWidth =pGameSetting->VIWidth;
873 if( IniSections[i].VIHeight != pGameSetting->VIHeight )
875 IniSections[i].VIHeight =pGameSetting->VIHeight;
878 if( IniSections[i].UseCIWidthAndRatio != pGameSetting->UseCIWidthAndRatio )
880 IniSections[i].UseCIWidthAndRatio =pGameSetting->UseCIWidthAndRatio;
883 if( IniSections[i].dwFullTMEM != pGameSetting->dwFullTMEM )
885 IniSections[i].dwFullTMEM =pGameSetting->dwFullTMEM;
888 if( IniSections[i].bTxtSizeMethod2 != pGameSetting->bTxtSizeMethod2 )
890 IniSections[i].bTxtSizeMethod2 =pGameSetting->bTxtSizeMethod2;
893 if( IniSections[i].bEnableTxtLOD != pGameSetting->bEnableTxtLOD )
895 IniSections[i].bEnableTxtLOD =pGameSetting->bEnableTxtLOD;
902 TRACE0("Rom option is changed and saved");
906 std::ifstream& getline( std::ifstream &is, char *str );
908 char * left(const char * src, int nchars)
910 static char dst[300];
911 strncpy(dst,src,nchars);
916 char * right(const char *src, int nchars)
918 static char dst[300];
919 int srclen = strlen(src);
920 if (nchars >= srclen)
926 strncpy(dst, src + srclen - nchars, nchars);
932 char * tidy(char * s)
934 char * p = s + strlen(s);
937 while (p >= s && (*p == ' ' || *p == 0xa || *p == '\n') )
948 std::ifstream inifile;
950 const char *ini_filepath = ConfigGetSharedDataFilepath(szIniFileName);
952 DebugMessage(M64MSG_VERBOSE, "Reading .ini file: %s", ini_filepath);
953 inifile.open(ini_filepath);
960 while (getline(inifile,readinfo)/*&§ionno<999*/)
964 if (readinfo[0] == '/')
967 if (!strcasecmp(readinfo,"")==0)
969 if (readinfo[0] == '{') //if a section heading
973 readinfo[strlen(readinfo)-1]='\0';
974 strcpy(newsection.crccheck, readinfo+1);
976 newsection.bDisableTextureCRC = FALSE;
977 newsection.bDisableCulling = FALSE;
978 newsection.bIncTexRectEdge = FALSE;
979 newsection.bZHack = FALSE;
980 newsection.bTextureScaleHack = FALSE;
981 newsection.bFastLoadTile = FALSE;
982 newsection.bUseSmallerTexture = FALSE;
983 newsection.bPrimaryDepthHack = FALSE;
984 newsection.bTexture1Hack = FALSE;
985 newsection.bDisableObjBG = FALSE;
986 newsection.VIWidth = -1;
987 newsection.VIHeight = -1;
988 newsection.UseCIWidthAndRatio = NOT_USE_CI_WIDTH_AND_RATIO;
989 newsection.dwFullTMEM = 0;
990 newsection.bTxtSizeMethod2 = FALSE;
991 newsection.bEnableTxtLOD = FALSE;
993 newsection.bEmulateClear = FALSE;
994 newsection.bForceScreenClear = FALSE;
995 newsection.bDisableBlender = FALSE;
996 newsection.bForceDepthBuffer = FALSE;
997 newsection.dwFastTextureCRC = 0;
998 newsection.dwAccurateTextureMapping = 0;
999 newsection.dwNormalBlender = 0;
1000 newsection.dwNormalCombiner = 0;
1001 newsection.dwFrameBufferOption = 0;
1002 newsection.dwRenderToTextureOption = 0;
1003 newsection.dwScreenUpdateSetting = 0;
1005 IniSections.push_back(newsection);
1010 int sectionno = IniSections.size() - 1;
1012 if (strcasecmp(left(readinfo,4), "Name")==0)
1013 strcpy(IniSections[sectionno].name,right(readinfo,strlen(readinfo)-5));
1015 if (strcasecmp(left(readinfo,17), "DisableTextureCRC")==0)
1016 IniSections[sectionno].bDisableTextureCRC=true;
1018 if (strcasecmp(left(readinfo,14), "DisableCulling")==0)
1019 IniSections[sectionno].bDisableCulling=true;
1021 if (strcasecmp(left(readinfo,16), "PrimaryDepthHack")==0)
1022 IniSections[sectionno].bPrimaryDepthHack=true;
1024 if (strcasecmp(left(readinfo,12), "Texture1Hack")==0)
1025 IniSections[sectionno].bTexture1Hack=true;
1027 if (strcasecmp(left(readinfo,12), "FastLoadTile")==0)
1028 IniSections[sectionno].bFastLoadTile=true;
1030 if (strcasecmp(left(readinfo,17), "UseSmallerTexture")==0)
1031 IniSections[sectionno].bUseSmallerTexture=true;
1033 if (strcasecmp(left(readinfo,14), "IncTexRectEdge")==0)
1034 IniSections[sectionno].bIncTexRectEdge=true;
1036 if (strcasecmp(left(readinfo,5), "ZHack")==0)
1037 IniSections[sectionno].bZHack=true;
1039 if (strcasecmp(left(readinfo,16), "TexRectScaleHack")==0)
1040 IniSections[sectionno].bTextureScaleHack=true;
1042 if (strcasecmp(left(readinfo,7), "VIWidth")==0)
1043 IniSections[sectionno].VIWidth = strtol(right(readinfo,3),NULL,10);
1045 if (strcasecmp(left(readinfo,8), "VIHeight")==0)
1046 IniSections[sectionno].VIHeight = strtol(right(readinfo,3),NULL,10);
1048 if (strcasecmp(left(readinfo,18), "UseCIWidthAndRatio")==0)
1049 IniSections[sectionno].UseCIWidthAndRatio = strtol(right(readinfo,1),NULL,10);
1051 if (strcasecmp(left(readinfo,8), "FullTMEM")==0)
1052 IniSections[sectionno].dwFullTMEM = strtol(right(readinfo,1),NULL,10);
1054 if (strcasecmp(left(readinfo,24), "AlternativeTxtSizeMethod")==0)
1055 IniSections[sectionno].bTxtSizeMethod2 = strtol(right(readinfo,1),NULL,10);
1057 if (strcasecmp(left(readinfo,12), "EnableTxtLOD")==0)
1058 IniSections[sectionno].bEnableTxtLOD = strtol(right(readinfo,1),NULL,10);
1060 if (strcasecmp(left(readinfo,12), "DisableObjBG")==0)
1061 IniSections[sectionno].bDisableObjBG = strtol(right(readinfo,1),NULL,10);
1063 if (strcasecmp(left(readinfo,16), "ForceScreenClear")==0)
1064 IniSections[sectionno].bForceScreenClear = strtol(right(readinfo,1),NULL,10);
1066 if (strcasecmp(left(readinfo,22), "AccurateTextureMapping")==0)
1067 IniSections[sectionno].dwAccurateTextureMapping = strtol(right(readinfo,1),NULL,10);
1069 if (strcasecmp(left(readinfo,14), "FastTextureCRC")==0)
1070 IniSections[sectionno].dwFastTextureCRC = strtol(right(readinfo,1),NULL,10);
1072 if (strcasecmp(left(readinfo,12), "EmulateClear")==0)
1073 IniSections[sectionno].bEmulateClear = strtol(right(readinfo,1),NULL,10);
1075 if (strcasecmp(left(readinfo,18), "NormalAlphaBlender")==0)
1076 IniSections[sectionno].dwNormalBlender = strtol(right(readinfo,1),NULL,10);
1078 if (strcasecmp(left(readinfo,19), "DisableAlphaBlender")==0)
1079 IniSections[sectionno].bDisableBlender = strtol(right(readinfo,1),NULL,10);
1081 if (strcasecmp(left(readinfo,19), "NormalColorCombiner")==0)
1082 IniSections[sectionno].dwNormalCombiner = strtol(right(readinfo,1),NULL,10);
1084 if (strcasecmp(left(readinfo,16), "ForceDepthBuffer")==0)
1085 IniSections[sectionno].bForceDepthBuffer = strtol(right(readinfo,1),NULL,10);
1087 if (strcasecmp(left(readinfo,20), "FrameBufferEmulation")==0)
1088 IniSections[sectionno].dwFrameBufferOption = strtol(readinfo+21,NULL,10);
1090 if (strcasecmp(left(readinfo,15), "RenderToTexture")==0)
1091 IniSections[sectionno].dwRenderToTextureOption = strtol(right(readinfo,1),NULL,10);
1093 if (strcasecmp(left(readinfo,19), "ScreenUpdateSetting")==0)
1094 IniSections[sectionno].dwScreenUpdateSetting = strtol(right(readinfo,1),NULL,10);
1103 //read a line from the ini file
1104 std::ifstream & getline(std::ifstream & is, char *str)
1108 is.getline(buf,100);
1119 /* get path to game-hack INI file and read it */
1120 const char *ini_filepath = ConfigGetSharedDataFilepath(szIniFileName);
1121 if (ini_filepath == NULL)
1123 fhIn = fopen(ini_filepath, "r");
1126 fseek(fhIn, 0L, SEEK_END);
1127 long filelen = ftell(fhIn);
1128 fseek(fhIn, 0L, SEEK_SET);
1129 char *chIniData = (char *) malloc(filelen + 1);
1130 if (chIniData == NULL)
1135 long bytesread = fread(chIniData, 1, filelen, fhIn);
1137 if (bytesread != filelen)
1142 chIniData[filelen] = 0;
1144 /* now try to open the file for writing */
1145 fhOut = fopen(ini_filepath, "w");
1152 // Mark all sections and needing to be written
1153 for (i = 0; i < IniSections.size(); i++)
1155 IniSections[i].bOutput = false;
1158 char *thisline = chIniData;
1159 while ((thisline - chIniData) < filelen)
1161 char *nextline = strchr(thisline, '\n');
1162 if (nextline == NULL)
1163 nextline = thisline + strlen(thisline) + 1;
1166 if (thisline[0] == '{')
1168 BOOL bFound = FALSE;
1170 tidy((char*) thisline);
1171 thisline[strlen(thisline) - 1] = '\0';
1172 for (i = 0; i < IniSections.size(); i++)
1174 if (IniSections[i].bOutput)
1176 if (strcasecmp((char*) thisline + 1, IniSections[i].crccheck) == 0)
1179 OutputSectionDetails(i, fhOut);
1180 IniSections[i].bOutput = true;
1187 // Do what? This should never happen, unless the user
1188 // replaces the inifile while game is running!
1191 else if (thisline[0] == '/')
1194 fputs((char*) thisline, fhOut);
1196 thisline = nextline;
1199 // Input buffer done- process any new entries!
1200 for (i = 0; i < IniSections.size(); i++)
1202 // Skip any that have not been done.
1203 if (IniSections[i].bOutput)
1206 OutputSectionDetails(i, fhOut);
1207 IniSections[i].bOutput = true;
1213 bIniIsChanged = false;
1216 void OutputSectionDetails(uint32 i, FILE * fh)
1218 fprintf(fh, "{%s}\n", IniSections[i].crccheck);
1220 fprintf(fh, "Name=%s\n", IniSections[i].name);
1221 //fprintf(fh, "UCode=%d\n", IniSections[i].ucode);
1223 // Tri-state variables
1224 if (IniSections[i].dwAccurateTextureMapping != 0)
1225 fprintf(fh, "AccurateTextureMapping=%d\n", IniSections[i].dwAccurateTextureMapping);
1227 if (IniSections[i].dwFastTextureCRC != 0)
1228 fprintf(fh, "FastTextureCRC=%d\n", IniSections[i].dwFastTextureCRC);
1230 if (IniSections[i].dwNormalBlender != 0)
1231 fprintf(fh, "NormalAlphaBlender=%d\n", IniSections[i].dwNormalBlender);
1233 if (IniSections[i].dwNormalCombiner != 0)
1234 fprintf(fh, "NormalColorCombiner=%d\n", IniSections[i].dwNormalCombiner);
1237 // Normal bi-state variables
1238 if (IniSections[i].bDisableTextureCRC)
1239 fprintf(fh, "DisableTextureCRC\n");
1241 if (IniSections[i].bDisableCulling)
1242 fprintf(fh, "DisableCulling\n");
1244 if (IniSections[i].bPrimaryDepthHack)
1245 fprintf(fh, "PrimaryDepthHack\n");
1247 if (IniSections[i].bTexture1Hack)
1248 fprintf(fh, "Texture1Hack\n");
1250 if (IniSections[i].bFastLoadTile)
1251 fprintf(fh, "FastLoadTile\n");
1253 if (IniSections[i].bUseSmallerTexture)
1254 fprintf(fh, "UseSmallerTexture\n");
1256 if (IniSections[i].bIncTexRectEdge)
1257 fprintf(fh, "IncTexRectEdge\n");
1259 if (IniSections[i].bZHack)
1260 fprintf(fh, "ZHack\n");
1262 if (IniSections[i].bTextureScaleHack)
1263 fprintf(fh, "TexRectScaleHack\n");
1265 if (IniSections[i].VIWidth > 0)
1266 fprintf(fh, "VIWidth=%d\n", IniSections[i].VIWidth);
1268 if (IniSections[i].VIHeight > 0)
1269 fprintf(fh, "VIHeight=%d\n", IniSections[i].VIHeight);
1271 if (IniSections[i].UseCIWidthAndRatio > 0)
1272 fprintf(fh, "UseCIWidthAndRatio=%d\n", IniSections[i].UseCIWidthAndRatio);
1274 if (IniSections[i].dwFullTMEM > 0)
1275 fprintf(fh, "FullTMEM=%d\n", IniSections[i].dwFullTMEM);
1277 if (IniSections[i].bTxtSizeMethod2 != FALSE )
1278 fprintf(fh, "AlternativeTxtSizeMethod=%d\n", IniSections[i].bTxtSizeMethod2);
1280 if (IniSections[i].bEnableTxtLOD != FALSE )
1281 fprintf(fh, "EnableTxtLOD=%d\n", IniSections[i].bEnableTxtLOD);
1283 if (IniSections[i].bDisableObjBG != 0 )
1284 fprintf(fh, "DisableObjBG=%d\n", IniSections[i].bDisableObjBG);
1286 if (IniSections[i].bForceScreenClear != 0)
1287 fprintf(fh, "ForceScreenClear=%d\n", IniSections[i].bForceScreenClear);
1289 if (IniSections[i].bEmulateClear != 0)
1290 fprintf(fh, "EmulateClear=%d\n", IniSections[i].bEmulateClear);
1292 if (IniSections[i].bDisableBlender != 0)
1293 fprintf(fh, "DisableAlphaBlender=%d\n", IniSections[i].bDisableBlender);
1295 if (IniSections[i].bForceDepthBuffer != 0)
1296 fprintf(fh, "ForceDepthBuffer=%d\n", IniSections[i].bForceDepthBuffer);
1298 if (IniSections[i].dwFrameBufferOption != 0)
1299 fprintf(fh, "FrameBufferEmulation=%d\n", IniSections[i].dwFrameBufferOption);
1301 if (IniSections[i].dwRenderToTextureOption != 0)
1302 fprintf(fh, "RenderToTexture=%d\n", IniSections[i].dwRenderToTextureOption);
1304 if (IniSections[i].dwScreenUpdateSetting != 0)
1305 fprintf(fh, "ScreenUpdateSetting=%d\n", IniSections[i].dwScreenUpdateSetting);
1307 fprintf(fh, "\n"); // Spacer
1310 // Find the entry corresponding to the specified rom.
1311 // If the rom is not found, a new entry is created
1312 // The resulting value is returned
1313 void __cdecl DebuggerAppendMsg (const char * Message, ...);
1315 static int FindIniEntry(uint32 dwCRC1, uint32 dwCRC2, uint8 nCountryID, char* szName, int PrintInfo)
1318 unsigned char szCRC[50+1];
1320 // Generate the CRC-ID for this rom:
1321 sprintf((char*)szCRC, "%08x%08x-%02x", (unsigned int)dwCRC1, (unsigned int)dwCRC2, nCountryID);
1323 for (i = 0; i < IniSections.size(); i++)
1325 if (strcasecmp((char*)szCRC, IniSections[i].crccheck) == 0)
1328 DebugMessage(M64MSG_INFO, "Found ROM '%s', CRC %s", IniSections[i].name, szCRC);
1337 DebugMessage(M64MSG_INFO, "ROM (CRC %s) not found in INI file", szCRC);
1339 strcpy(newsection.crccheck, (char*)szCRC);
1341 strncpy(newsection.name, szName, 50);
1342 newsection.bDisableTextureCRC = FALSE;
1343 newsection.bDisableCulling = FALSE;
1344 newsection.bIncTexRectEdge = FALSE;
1345 newsection.bZHack = FALSE;
1346 newsection.bTextureScaleHack = FALSE;
1347 newsection.bFastLoadTile = FALSE;
1348 newsection.bUseSmallerTexture = FALSE;
1349 newsection.bPrimaryDepthHack = FALSE;
1350 newsection.bTexture1Hack = FALSE;
1351 newsection.bDisableObjBG = FALSE;
1352 newsection.VIWidth = -1;
1353 newsection.VIHeight = -1;
1354 newsection.UseCIWidthAndRatio = NOT_USE_CI_WIDTH_AND_RATIO;
1355 newsection.dwFullTMEM = 0;
1356 newsection.bTxtSizeMethod2 = FALSE;
1357 newsection.bEnableTxtLOD = FALSE;
1359 newsection.bEmulateClear = FALSE;
1360 newsection.bForceScreenClear = FALSE;
1361 newsection.bDisableBlender = FALSE;
1362 newsection.bForceDepthBuffer = FALSE;
1363 newsection.dwFastTextureCRC = 0;
1364 newsection.dwAccurateTextureMapping = 0;
1365 newsection.dwNormalBlender = 0;
1366 newsection.dwNormalCombiner = 0;
1367 newsection.dwFrameBufferOption = 0;
1368 newsection.dwRenderToTextureOption = 0;
1369 newsection.dwScreenUpdateSetting = 0;
1371 IniSections.push_back(newsection);
1373 bIniIsChanged = true; // Flag to indicate we should be updated
1374 return IniSections.size()-1; // -1 takes into account increment
1377 GameSetting g_curRomInfo;
1379 void ROM_GetRomNameFromHeader(unsigned char * szName, ROMHeader * pHdr)
1383 memcpy(szName, pHdr->szName, 20);
1386 p = szName + (strlen((char*)szName) -1); // -1 to skip null
1387 while (p >= szName && *p == ' ')
1394 uint32 CountryCodeToTVSystem(uint32 countryCode)
1401 system = TV_SYSTEM_NTSC;
1405 system = TV_SYSTEM_NTSC;
1409 system = TV_SYSTEM_NTSC;
1414 system = TV_SYSTEM_PAL;
1419 system = TV_SYSTEM_NTSC;
1424 system = TV_SYSTEM_PAL;
1429 system = TV_SYSTEM_PAL;
1434 system = TV_SYSTEM_NTSC;
1439 system = TV_SYSTEM_PAL;
1442 case 'S': /* Spain */
1443 system = TV_SYSTEM_PAL;
1448 system = TV_SYSTEM_PAL;
1452 system = TV_SYSTEM_PAL;
1457 system = TV_SYSTEM_PAL;
1464 system = TV_SYSTEM_PAL;
1469 system = TV_SYSTEM_PAL;