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