source: Daodan/src/Daodan.c@ 722

Last change on this file since 722 was 705, checked in by alloc, 12 years ago

Daodan: DaodanGL fixes, intro/outro fixes, chinese=true by default

File size: 29.2 KB
RevLine 
[692]1#include <windows.h>
[346]2#include <string.h>
3
[272]4#include "Daodan.h"
5#include "Daodan_Patch.h"
6#include "Daodan_Utility.h"
[323]7#include "Daodan_Win32.h"
[339]8#include "Daodan_Cheater.h"
9#include "Daodan_Persistence.h"
[439]10#include "Daodan_BSL.h"
[476]11#include "Daodan_Console.h"
[349]12
[273]13#include "Oni.h"
[339]14
[692]15#include "Oni_GL.h"
16#include "Daodan_GL.h"
[272]17
[692]18#include "Inifile_Reader.h"
[297]19
[272]20HMODULE DDrDLLModule;
21HMODULE DDrONiModule;
22
[347]23bool patch_fonttexturecache = true;
24bool patch_largetextures = true;
[349]25bool patch_levelplugins = true;
[347]26bool patch_pathfinding = true;
27bool patch_projaware = true;
[348]28bool patch_directinput = true;
[347]29bool patch_wpfadetime = true;
30bool patch_kickguns = false;
31bool patch_cooldowntimer = true;
32bool patch_throwtest = false;
33bool patch_alttab = true;
34bool patch_particledisablebit = false;
[422]35bool patch_multibyte = false;
[347]36bool patch_cheattable = true;
[426]37bool patch_argb8888 = true;
[459]38bool patch_killvtune = true;
[466]39bool patch_getcmdline = true;
40bool patch_disablecmdline = true;
[693]41bool patch_optionsvisible = true;
[347]42
[705]43bool patch_binkplay = true;
[347]44bool patch_safeprintf = true;
45bool patch_daodandisplayenum = true;
46bool patch_usegettickcount = true;
[348]47bool patch_cheatsenabled = true;
[705]48bool patch_usedaodangl = true;
49bool patch_clipcursor = true;
[439]50bool patch_daodaninit = true;
[447]51bool patch_bsl = true;
[452]52bool patch_cheater = true;
[677]53bool patch_newweapon = true;
[439]54bool opt_usedaodanbsl = true;
[468]55bool opt_border = true;
56bool opt_topmost = false;
[705]57bool opt_gamma = true;
[439]58
[705]59typedef int (__cdecl *CHINESEPROC)(DWORD ThreadId);
60bool patch_chinese = true;
[693]61
62
[705]63// Hooked WMrSlider_SetRange() in ONiOGU_Options_InitDialog. Disables a gamma
64// slider in windowed mode.
65static void ONICALL DD_ONiOGU_GammaSlider_SetRange(WMtWindow* window, int min_value, int max_value)
[693]66{
[705]67 WMrWindow_SetEnabled(window, M3gResolutionSwitch && opt_gamma);
68 WMrSlider_SetRange(window, min_value, max_value);
69}
70
71void ONICALL DDrShowResumeButton(WMtWindow* window, int visibility)
72{
[693]73 if (visibility)
74 WMrWindow_SetLocation(window, 150, 350);
75 WMrWindow_SetVisible(window, visibility);
76}
77
78
79/* Options always visible patch */
[705]80void ONICALL DDrShowOptionsButton(WMtWindow* window, int visibility)
[693]81{
82 WMrWindow_SetVisible(window, 1);
83}
84
85
86
[272]87bool DDrPatch_Init()
88{
[346]89 DDrStartupMessage("patching engine");
[342]90
[272]91 // Font texture cache doubled
[347]92 if (patch_fonttexturecache)
93 {
[689]94 DDrPatch_Byte((char*)(OniExe + 0x00020ea7), 0x20);
95 DDrPatch_Byte((char*)(OniExe + 0x00020f4a), 0x40);
[347]96 }
[272]97
98 // Now supports textures up to 512x512
[347]99 if (patch_largetextures)
[689]100 DDrPatch_Byte ((char*)(OniExe + 0x00005251), 0x10);
[272]101
102 // Non-"_Final" levels are now valid
[348]103 if (patch_levelplugins)
[689]104 DDrPatch_Byte ((char*)(OniExe + 0x000206a8), 0x01);
[272]105
106 // Pathfinding grid cache size x8
[347]107 if (patch_pathfinding)
108 {
[689]109 const unsigned char pathfinding[2] = {0x90 , 0xE9 };
110 DDrPatch_Byte ((char*)(OniExe + 0x0010b03b), 0x20);
111 DDrPatch_Byte ((char*)(OniExe + 0x0010b04c), 0x20);
[677]112
113 //other stuff
[689]114 DDrPatch_Const((char*)(OniExe + 0x00040789), pathfinding);
[347]115 }
[272]116
117 // Projectile awareness fixed
[347]118 if (patch_projaware)
119 {
[689]120 DDrPatch_Byte ((char*)(OniExe + 0x0009c07c), 0x6c);
121 DDrPatch_Byte ((char*)(OniExe + 0x0009c080), 0x70);
122 DDrPatch_Byte ((char*)(OniExe + 0x0009c084), 0x74);
123 DDrPatch_Byte ((char*)(OniExe + 0x0009c110), 0x6c);
[347]124 }
[272]125
126 // Forced DirectInput (for Windows NT)
[348]127 if (patch_directinput)
[689]128 DDrPatch_Byte((char*)(OniExe + 0x00002e6d), 0xeb);
[677]129
[347]130 if (patch_wpfadetime)
131 {
132 // Makes wp_fadetime actually have a function
[689]133 const unsigned char fadetime_patch[] = { 0x66, 0x8B, 0x1D, 0xC4, 0x7D, 0x62, 0x00, 0x66, 0x89, 0x5E, 0x46, 0x5B, 0x5E, 0x83, 0xC4, 0x14, 0xC3 };
134 DDrPatch_Const ((char*)(OniExe + 0x0011a889), fadetime_patch);
135 DDrPatch_Byte ((char*)(OniExe + 0x0011a560), 0x31);
[347]136
137 // Sets the fadetime to 4800 by default
[689]138 DDrPatch_Int16 ((short*)(OniExe + 0x0011ab0e), 0x12c0);
[347]139 }
[272]140
[677]141 // FIXME: add switches
142 //pathfinding fix
143
[272]144
[677]145
146
[272]147 // Hackish fix for Konoko not kicking guns
[677]148 // Don't use this, it breaks stairs.
[347]149 if (patch_kickguns)
150 {
[689]151 const unsigned char kickgun_patch[] = { 0x00, 0x05, 0x00, 0x00, 0x00, 0xC7, 0x05, 0x1C, 0xC9, 0x5E, 0x00, 0x70, 0xB8, 0x43, 0x00, 0xC7, 0x05, 0x20, 0xC9, 0x5E, 0x00, 0x20, 0xBE, 0x43 };
152 DDrPatch_Const ((char*)(OniExe + 0x000dc420), kickgun_patch);
[347]153 }
[272]154
155 // Cooldown timer exploit fix ^_^
[347]156 if (patch_cooldowntimer)
157 {
[689]158 const unsigned char cooldown_patch[] = { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 };
159 DDrPatch_Const ((char*)(OniExe + 0x0011a825), cooldown_patch);
[347]160 }
[272]161
[347]162 if (patch_throwtest)
163 {
[689]164 const unsigned char throwtest_patch[] = { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 };
165 DDrPatch_Const((char*)(OniExe + 0x000dc190), throwtest_patch);
[347]166 }
[272]167
[322]168 // Disable UUrPlatform_Initalize/Terminate, this enables the Alt-Tab and the Windows key but has the possible side effect of allowing the screensaver to enable itself in-game.
[347]169 if (patch_alttab)
170 {
[690]171 // 0xC3 = ret, so makes those functions just have a "ret" instruction at their start
[689]172 DDrPatch_Byte ((char*)UUrPlatform_Initialize, 0xC3);
173 DDrPatch_Byte ((char*)UUrPlatform_Terminate, 0xC3);
[347]174 }
[322]175
176 // Unlocks particle action disabling/enabling bits for all events. (Will be controlled by a command line switch when I figure out how to do that without Win32 hacks.)
[347]177 if (patch_particledisablebit)
[689]178 DDrPatch_Int16 ((short*)(OniExe + 0x001b184), 0x9090);
[322]179
[329]180 // Multi-byte patch (multiple language support)
[422]181 if (!patch_multibyte)
[347]182 {
[689]183 DDrPatch_Byte ((char*)(OniExe + 0x0002d8f8), 0xeb);
184 DDrPatch_Byte ((char*)(OniExe + 0x0002d9ad), 0xeb);
185 DDrPatch_Byte ((char*)(OniExe + 0x0002dbe2), 0xeb);
186 DDrPatch_Byte ((char*)(OniExe + 0x0002dec3), 0xeb);
187 DDrPatch_Byte ((char*)(OniExe + 0x0002e2ab), 0xeb);
188 DDrPatch_Byte ((char*)(OniExe + 0x0002e2c4), 0xeb);
189 DDrPatch_Byte ((char*)(OniExe + 0x0002e379), 0xeb);
190 DDrPatch_Byte ((char*)(OniExe + 0x0002e48c), 0xeb);
191 DDrPatch_Byte ((char*)(OniExe + 0x0002e4d0), 0xeb);
192 DDrPatch_Byte ((char*)(OniExe + 0x0002e4f4), 0xeb);
193 DDrPatch_Byte ((char*)(OniExe + 0x0002e646), 0xeb);
194 DDrPatch_Byte ((char*)(OniExe + 0x0002e695), 0xeb);
195 DDrPatch_Byte ((char*)(OniExe + 0x0002e944), 0xeb);
196 DDrPatch_Byte ((char*)(OniExe + 0x0002e95d), 0xeb);
197 DDrPatch_Byte ((char*)(OniExe + 0x0002e98e), 0xeb);
198 DDrPatch_Byte ((char*)(OniExe + 0x0002e9dc), 0xeb);
[347]199 }
[329]200
[339]201 // Cheat table patch
[347]202 if (patch_cheattable)
203 {
[689]204 DDrPatch_Int32 ((int*)(OniExe + 0x000f616b), (int)&DDr_CheatTable[0].name);
205 DDrPatch_Int32 ((int*)(OniExe + 0x000f617a), (int)&DDr_CheatTable[0].message_on);
[347]206 }
[339]207
[459]208 // ARGB8888 textures
[426]209 if (patch_argb8888)
210 {
[689]211 DDrPatch_Byte ((char*)(OniExe + 0x00135af0), 0x07);
212 DDrPatch_Byte ((char*)(OniExe + 0x00135af4), 0x0B);
[426]213 }
[473]214
215 //Test newweap patch
[677]216 if (patch_newweapon) {
[476]217
218 //Makes it always say "Recieved weapon_name."
219 //Needs check for loc_4DFC66
[689]220 //DDrPatch_NOOP((char*)(OniExe + 0x000E4DF8),2);
[476]221
222 //Adds Weapon name and ammo meter to pickup autoprompt
[689]223 DDrPatch_NOOP((char*)(OniExe + 0x000FAC73), 9);
224 DDrPatch_NOOP((char*)(OniExe + 0x000FAC80), 5);
225 DDrPatch_MakeCall((void*)(OniExe + 0xFAC85), (void*)DDrWeapon2Message);
[476]226
227 //Moves location of colors
[689]228 //DDrPatch_Int32((int*)(OniExe + 0x0002E3D5), (int)&DDrDSayColors );
229 //DDrPatch_Int32((int*)(OniExe + 0x0002E3DA), (int)&DDrDSayColors );
[677]230 }
[426]231
[459]232 // Disable loading the vtuneapi.dll
[677]233 //if (patch_killvtune)
[689]234 //DDrPatch_Byte ((char*)(OniExe + 0x00026340), 0xC3);
[459]235
[466]236 // Disable Oni's internal CLrGetCommandLine function (to eventually replace it with our own)
237 if (patch_getcmdline)
[689]238 DDrPatch_NOOP ((char*)(OniExe + 0x000d3280), 51);
[466]239
240 // Disable Oni's command line parser so it doesn't interfere with ours
241 if (patch_disablecmdline)
[689]242 DDrPatch_Int32 ((int*)(OniExe + 0x000d3570), 0xc3c03366);
[466]243
[677]244 if (patch_bsl)
245 {
246 //Calculating the value of the needed offset is much more reliable when the compiler does it for you.
247
248 //TODO: fix moonshadow.
249 Character * Chr = 0;
250 int NoPath = (int)&(Chr[0].RegenHax) & 0x000000FF;
[689]251 const unsigned char regen_patch[] =
[677]252 {0x90, 0x90, 0x90, 0x90, 0x90, // mov al, _WPgRegenerationCheat -> NOOP
253 0x90, 0x90, // test al, al -> NOOP
254 0x90, 0x90, // jz short loc_51BB98 -> NOOP
255 0x8B, 0x86, (char)NoPath, 0x01, 0x00, 0x00, // mov eax, [esi+Character.field_1E8]
256 // -> mov eax, [esi+Character.RegenHax]
257 0x85, 0xC0, // test eax, eax
258 0x74, 0x21 // jnz 0x21 -> jz 0x21
259 };
[689]260 DDrPatch_Const((char*)(OniExe + 0x0011BB64), regen_patch);
[677]261 }
262
263 if(patch_chinese)
264 {
[705]265 HMODULE dll;
266 DWORD err;
267
268 DDrStartupMessage("Loading chinese DLL");
269 dll = LoadLibrary("xfhsm_oni.dll");
270 err = GetLastError();
[677]271 if( dll )
272 {
273 void* proc = GetProcAddress( dll, "InstallHook" );
274 if(proc)
275 {
276 ((CHINESEPROC)proc)(GetCurrentThreadId());
277 }
[705]278 } else {
279 char msg[100];
280 FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, err, 0, msg, 100, NULL);
281 DDrStartupMessage(" - Module loading failed with error %i: %s", err, msg);
[677]282 }
283 }
284
285 //Fix crappy ai2_shownames
286 if(1)
287 {
288 //Set distance above head to 4.0
[689]289 DDrPatch_Int32((int*)(OniExe + 0x0008C998), 0x005296C8);
[677]290 //texture height
[689]291 DDrPatch_Byte((char*)(OniExe + 0x0008C9DF), 0x3F );
[677]292 //texture width
[689]293 DDrPatch_NOOP((char*)(OniExe + 0x0008C9CA), 6 );
[677]294 //Set the text color to whatever we like ;)
[689]295 DDrPatch_NOOP((char*)(OniExe + 0x0008C898), 6 );
296 DDrPatch_Byte((char*)(OniExe + 0x0008C898), 0x8B );
297 DDrPatch_Byte((char*)(OniExe + 0x0008C899), 0xCE );
298//FLATLINE? DDrPatch_MakeCall((void*)(OniExe + 0x0008C8A3), FLrHook_DebugNameShadeHack);
[677]299
300 //Make the background black for additive blending
[689]301//FLATLINE? DDrPatch_MakeCall((void*)(OniExe + 0x0008C802), FLrHook_DebugNameTextureInit );
[677]302 }
303
304 if(1)
305 {
[689]306 //DDrPatch_NOOP((char*)(OniExe + 0x000E1957), 6 );
307 //DDrPatch_MakeCall((void*)(OniExe + 0x000E17F6), FLrHook_Lasers );
[677]308 }
309
310 //Flatline related stuff
[689]311// DDrPatch_MakeCall((void*)(OniExe + 0x000FBCEA), DDrText_Hook);
[677]312
[689]313//FLATLINE? DDrPatch_Int32((int*)(OniExe + 0x000B24D2), FLrSpawnHack);
[677]314
[689]315//FLATLINE? DDrPatch_NOOP((char*)(OniExe + 0x000C26CB), 6);
[677]316
[689]317//FLATLINE? DDrPatch_MakeCall((void*)(OniExe + 0x000C26CB), FLrHook_DoorOpen);
318//FLATLINE? DDrPatch_MakeCall((void*)(OniExe + 0x000EE3CF), FLrHook_ConsoleActivate);
[693]319
320
321 // Fix options not visible in main menu when a game was started
322 if(patch_optionsvisible)
323 {
324 DDrPatch_MakeCall((void*)(OniExe + 0x000d2d2d), DDrShowOptionsButton);
325 DDrPatch_MakeCall((void*)(OniExe + 0x000d2d43), DDrShowResumeButton);
326 }
327
[705]328 // Fix BinkBufferInit() call in BKrMovie_Play() to use GDI (DIB) blitting
329 // instead of DirectDraw; patch ONiRunGame to use the same method to play
330 // outro (ie., BKrMovie_Play() instead of ONrMovie_Play_Hardware() as the
331 // latter has problems on WINE).
332 if (patch_binkplay)
333 {
334 // push BINKBUFFERAUTO -> push BINKBUFFERDIBSECTION.
335 DDrPatch_Byte((void*)(OniExe + 0x0008829b + 1), 0x02);
336 // call ONrMovie_Play_Hardware -> call ONrMovie_Play
337 DDrPatch_MakeCall((void*)(OniExe + 0x000d496f), ONrMovie_Play);
338 }
339
340 // Patch a gamma slider in Options dialog (unconditionally).
341 // ONiOGU_Options_InitDialog: replace WMrSlider_SetRange(gammaSliderWindow, ...)
342 // call with our hook function.
343 DDrPatch_MakeCall((void*)(OniExe + 0x000d262c), (void*)DD_ONiOGU_GammaSlider_SetRange);
344
[272]345 return true;
346}
347
[693]348
[445]349enum {s_unknown, s_options, s_patch, s_bsl, s_language} ini_section;
[346]350
351bool DDrIniCallback(char* section, bool newsection, char* name, char* value)
352{
353 if (newsection)
354 {
[677]355 if (!_stricmp(section, "options"))
[439]356 ini_section = s_options;
[677]357 else if (!_stricmp(section, "patch"))
[347]358 ini_section = s_patch;
[677]359 else if (!_stricmp(section, "bsl"))
[445]360 ini_section = s_bsl;
[677]361 else if (!_stricmp(section, "language"))
[346]362 ini_section = s_language;
363 else
364 {
365 ini_section = s_unknown;
[466]366 DDrStartupMessage("unrecognised section \"%s\"", section);
[346]367 }
368 }
369
370 switch (ini_section)
371 {
[439]372 case s_options:
[677]373 if (!_stricmp(name, "usedaodanbsl"))
374 opt_usedaodanbsl = !_stricmp(inifile_cleanstr(value), "true");
375 else if (!_stricmp(name, "border"))
376 opt_border = !_stricmp(inifile_cleanstr(value), "true");
377 else if (!_stricmp(name, "topmost"))
378 opt_topmost = !_stricmp(inifile_cleanstr(value), "true");
379 else if (!_stricmp(name, "multibyte"))
380 patch_multibyte = !_stricmp(inifile_cleanstr(value), "true");
381 else if (!_stricmp(name, "debug"))
382 AKgDebug_DebugMaps = !_stricmp(inifile_cleanstr(value), "true");
383 else if (!_stricmp(name, "debugfiles"))
384 BFgDebugFileEnable = !_stricmp(inifile_cleanstr(value), "true");
385 else if (!_stricmp(name, "findsounds"))
386 SSgSearchOnDisk = !_stricmp(inifile_cleanstr(value), "true");
387 else if (!_stricmp(name, "ignore_private_data"))
388 opt_ignore_private_data = !_stricmp(inifile_cleanstr(value), "true");
389 else if (!_stricmp(name, "sound"))
390 opt_sound = !_stricmp(inifile_cleanstr(value), "true");
391 else if (!_stricmp(name, "switch"))
392 M3gResolutionSwitch = !_stricmp(inifile_cleanstr(value), "true");
[705]393 else if (!_stricmp(name, "gamma"))
394 opt_gamma = !_stricmp(inifile_cleanstr(value), "true");
[466]395 else
396 DDrStartupMessage("unrecognised option \"%s\"", name);
[439]397 break;
[347]398 case s_patch:
[677]399 if (!_stricmp(name, "fonttexturecache"))
400 patch_fonttexturecache = !_stricmp(inifile_cleanstr(value), "true");
401 else if (!_stricmp(name, "largetextures"))
402 patch_largetextures = !_stricmp(inifile_cleanstr(value), "true");
403 else if (!_stricmp(name, "levelplugins"))
404 patch_levelplugins = !_stricmp(inifile_cleanstr(value), "true");
405 else if (!_stricmp(name, "pathfinding"))
406 patch_pathfinding = !_stricmp(inifile_cleanstr(value), "true");
407 else if (!_stricmp(name, "projaware"))
408 patch_projaware = !_stricmp(inifile_cleanstr(value), "true");
409 else if (!_stricmp(name, "directinput"))
410 patch_directinput = !_stricmp(inifile_cleanstr(value), "true");
411 else if (!_stricmp(name, "wpfadetime"))
412 patch_wpfadetime = !_stricmp(inifile_cleanstr(value), "true");
413 else if (!_stricmp(name, "kickguns"))
414 patch_kickguns = !_stricmp(inifile_cleanstr(value), "true");
415 else if (!_stricmp(name, "cooldowntimer"))
416 patch_cooldowntimer = !_stricmp(inifile_cleanstr(value), "true");
417 else if (!_stricmp(name, "throwtest"))
418 patch_throwtest = !_stricmp(inifile_cleanstr(value), "true");
419 else if (!_stricmp(name, "alttab"))
420 patch_alttab = !_stricmp(inifile_cleanstr(value), "true");
421 else if (!_stricmp(name, "particledisablebit"))
422 patch_particledisablebit = !_stricmp(inifile_cleanstr(value), "true");
423 else if (!_stricmp(name, "multibyte"))
424 patch_multibyte = !_stricmp(inifile_cleanstr(value), "true");
425 else if (!_stricmp(name, "cheattable"))
426 patch_cheattable = !_stricmp(inifile_cleanstr(value), "true");
427 else if (!_stricmp(name, "argb8888"))
428 patch_argb8888 = !_stricmp(inifile_cleanstr(value), "true");
429 else if (!_stricmp(name, "killvtune"))
430 patch_killvtune = !_stricmp(inifile_cleanstr(value), "true");
431 else if (!_stricmp(name, "getcmdline"))
432 patch_getcmdline = !_stricmp(inifile_cleanstr(value), "true");
433 else if (!_stricmp(name, "disablecmdline"))
434 patch_disablecmdline = !_stricmp(inifile_cleanstr(value), "true");
435 else if (!_stricmp(name, "safeprintf"))
436 patch_safeprintf = !_stricmp(inifile_cleanstr(value), "true");
437 else if (!_stricmp(name, "daodandisplayenum"))
438 patch_daodandisplayenum = !_stricmp(inifile_cleanstr(value), "true");
439 else if (!_stricmp(name, "usegettickcount"))
440 patch_usegettickcount = !_stricmp(inifile_cleanstr(value), "true");
441 else if (!_stricmp(name, "cheatsenabled"))
442 patch_cheatsenabled = !_stricmp(inifile_cleanstr(value), "true");
443 else if (!_stricmp(name, "usedaodangl"))
444 patch_usedaodangl = !_stricmp(inifile_cleanstr(value), "true");
[705]445 else if (!_stricmp(name, "clipcursor"))
446 patch_clipcursor = !_stricmp(inifile_cleanstr(value), "true");
[677]447 else if (!_stricmp(name, "daodaninit"))
448 patch_daodaninit = !_stricmp(inifile_cleanstr(value), "true");
449 else if (!_stricmp(name, "bsl"))
450 patch_bsl = !_stricmp(inifile_cleanstr(value), "true");
451 else if (!_stricmp(name, "cheater"))
452 patch_cheater = !_stricmp(inifile_cleanstr(value), "true");
453 else if (!_stricmp(name, "newweap"))
454 patch_newweapon = !_stricmp(inifile_cleanstr(value), "true");
[693]455 else if (!_stricmp(name, "optionsvisible"))
456 patch_optionsvisible = !_stricmp(inifile_cleanstr(value), "true");
[705]457 else if (!_stricmp(name, "binkplay"))
458 patch_binkplay = !_stricmp(inifile_cleanstr(value), "true");
[347]459 else
460 DDrStartupMessage("unrecognised patch \"%s\"", name);
461 break;
[346]462 case s_language:
[677]463 if (!_stricmp(name, "chinese"))
464 patch_chinese = true;
465 else if (!_stricmp(name, "savepoint"))
[346]466 {
[677]467 char* str = _strdup(value);
[689]468 DDrPatch_Int32((int*)(OniExe + 0x000fd730), (int)str);
469 DDrPatch_Int32((int*)(OniExe + 0x000fd738), (int)str);
[346]470 }
[677]471 else if (!_stricmp(name, "syndicatewarehouse"))
[346]472 {
[677]473 char* str = _strdup(value);
[689]474 DDrPatch_Int32((int*)(OniExe + 0x000fd71a), (int)str);
475 DDrPatch_Int32((int*)(OniExe + 0x0010ef75), (int)str);
[346]476 }
[677]477 else if (!_stricmp(name, "damn"))
[689]478 DDrPatch__strdup((int*)(OniExe + 0x0010fb6e), value);
[677]479 else if (!_stricmp(name, "blam"))
[689]480 DDrPatch__strdup((int*)(OniExe + 0x0010fb73), value);
[677]481 else if (!_stricmp(name, "shapeshifter_on"))
482 DDr_CheatTable[0].message_on = _strdup(value);
483 else if (!_stricmp(name, "shapeshifter_off"))
484 DDr_CheatTable[0].message_off = _strdup(value);
485 else if (!_stricmp(name, "liveforever_on"))
486 DDr_CheatTable[1].message_on = _strdup(value);
487 else if (!_stricmp(name, "liveforever_off"))
488 DDr_CheatTable[1].message_off = _strdup(value);
489 else if (!_stricmp(name, "touchofdeath_on"))
490 DDr_CheatTable[2].message_on = _strdup(value);
491 else if (!_stricmp(name, "touchofdeath_off"))
492 DDr_CheatTable[2].message_off = _strdup(value);
493 else if (!_stricmp(name, "canttouchthis_on"))
494 DDr_CheatTable[3].message_on = _strdup(value);
495 else if (!_stricmp(name, "canttouchthis_off"))
496 DDr_CheatTable[3].message_off = _strdup(value);
497 else if (!_stricmp(name, "fatloot_on"))
498 DDr_CheatTable[4].message_on = _strdup(value);
499 else if (!_stricmp(name, "glassworld_on"))
500 DDr_CheatTable[5].message_on = _strdup(value);
501 else if (!_stricmp(name, "glassworld_off"))
502 DDr_CheatTable[5].message_off = _strdup(value);
503 else if (!_stricmp(name, "winlevel_on"))
504 DDr_CheatTable[6].message_on = _strdup(value);
505 else if (!_stricmp(name, "loselevel_on"))
506 DDr_CheatTable[7].message_on = _strdup(value);
507 else if (!_stricmp(name, "bighead_on"))
508 DDr_CheatTable[8].message_on = _strdup(value);
509 else if (!_stricmp(name, "bighead_off"))
510 DDr_CheatTable[8].message_off = _strdup(value);
511 else if (!_stricmp(name, "minime_on"))
512 DDr_CheatTable[9].message_on = _strdup(value);
513 else if (!_stricmp(name, "minime_off"))
514 DDr_CheatTable[9].message_off = _strdup(value);
515 else if (!_stricmp(name, "superammo_on"))
516 DDr_CheatTable[10].message_on = _strdup(value);
517 else if (!_stricmp(name, "superammo_off"))
518 DDr_CheatTable[10].message_off = _strdup(value);
519 else if (!_stricmp(name, "devmode_on"))
[349]520 {
[677]521 char* str = _strdup(value);
[349]522 DDr_CheatTable[11].message_on = str;
[452]523 DDr_CheatTable[cheat_x].message_on = str;
[349]524 }
[677]525 else if (!_stricmp(name, "devmode_off"))
[349]526 {
[677]527 char* str = _strdup(value);
[349]528 DDr_CheatTable[11].message_off = str;
[452]529 DDr_CheatTable[cheat_x].message_off = str;
[349]530 }
[677]531 else if (!_stricmp(name, "reservoirdogs_on"))
532 DDr_CheatTable[12].message_on = _strdup(value);
533 else if (!_stricmp(name, "reservoirdogs_off"))
534 DDr_CheatTable[12].message_off = _strdup(value);
535 else if (!_stricmp(name, "roughjustice_on"))
536 DDr_CheatTable[13].message_on = _strdup(value);
537 else if (!_stricmp(name, "roughjustice_off"))
538 DDr_CheatTable[13].message_off = _strdup(value);
539 else if (!_stricmp(name, "chenille_on"))
540 DDr_CheatTable[14].message_on = _strdup(value);
541 else if (!_stricmp(name, "chenille_off"))
542 DDr_CheatTable[14].message_off = _strdup(value);
543 else if (!_stricmp(name, "behemoth_on"))
544 DDr_CheatTable[15].message_on = _strdup(value);
545 else if (!_stricmp(name, "behemoth_off"))
546 DDr_CheatTable[15].message_off = _strdup(value);
547 else if (!_stricmp(name, "elderrune_on"))
548 DDr_CheatTable[16].message_on = _strdup(value);
549 else if (!_stricmp(name, "elderrune_off"))
550 DDr_CheatTable[16].message_off = _strdup(value);
551 else if (!_stricmp(name, "moonshadow_on"))
552 DDr_CheatTable[17].message_on = _strdup(value);
553 else if (!_stricmp(name, "moonshadow_off"))
554 DDr_CheatTable[17].message_off = _strdup(value);
555 else if (!_stricmp(name, "munitionfrenzy_on"))
556 DDr_CheatTable[18].message_on = _strdup(value);
557 else if (!_stricmp(name, "fistsoflegend_on"))
558 DDr_CheatTable[19].message_on = _strdup(value);
559 else if (!_stricmp(name, "fistsoflegend_off"))
560 DDr_CheatTable[19].message_off = _strdup(value);
561 else if (!_stricmp(name, "killmequick_on"))
562 DDr_CheatTable[20].message_on = _strdup(value);
563 else if (!_stricmp(name, "killmequick_off"))
564 DDr_CheatTable[20].message_off = _strdup(value);
565 else if (!_stricmp(name, "carousel_on"))
566 DDr_CheatTable[21].message_on = _strdup(value);
567 else if (!_stricmp(name, "carousel_off"))
568 DDr_CheatTable[21].message_off = _strdup(value);
[346]569 else
570 DDrStartupMessage("unrecognised language item \"%s\"", name);
571 break;
[451]572 case s_bsl:
[346]573 default:
574 break;
575 }
576
577 return true;
578}
579
580void DDrConfig()
581{
[677]582
[346]583 if (GetFileAttributes("daodan.ini") == INVALID_FILE_ATTRIBUTES)
584 {
[677]585 FILE* fp;
[346]586 DDrStartupMessage("daodan.ini doesn't exist, creating");
[677]587 fp = fopen("daodan.ini", "w");
[346]588 if (fp)
589 {
590 fputs("[Options]\n", fp);
591 fclose(fp);
592 }
593 }
594
595 DDrStartupMessage("parsing daodan.ini...");
596 if (!inifile_read("daodan.ini", DDrIniCallback))
597 DDrStartupMessage("error reading daodan.ini, check your syntax!");
598 DDrStartupMessage("finished parsing");
599}
600
[439]601void ONICALL DDrGame_Init()
602{
603 if (opt_usedaodanbsl)
604 SLrDaodan_Initalize();
605}
606
[677]607void DDrException() {
608 int* i = 0;
609 *i = 1;
610}
611#include <stdio.h>
612
613//this was broken
614FILE** _UUgError_WarningFile = (FILE**)0x005711B4;
615FILE *__fastcall DDrPrintWarning(int filename, int linenumber, unsigned __int16 errornum, int message)
616{
617
618 FILE *v4; // eax@1
619 FILE *result; // eax@4
620 char v6[512]; // [sp+0h] [bp-100h]@1
621 FILE* UUgError_WarningFile = *_UUgError_WarningFile;
622
[689]623 if (filename && message && (strlen((const char*)filename)+strlen((const char*)message))<420) {
[681]624 sprintf(
625 v6,
626 "Error %x reported from File: %s, Line: %d (message follows) \r\n%s",
627 errornum,
[689]628 (const char*)filename,
[681]629 linenumber,
[689]630 (const char*)message);
[681]631
632 if ( UUgError_WarningFile
633 || (UUgError_WarningFile = oni_fopen("debugger.txt", "wb"), UUgError_WarningFile ) )
634 {
635 oni_fprintf(UUgError_WarningFile, "%s\r\n", v6);
636 oni_fflush(UUgError_WarningFile);
637 }
[677]638 }
639 //oni_fprintf(stdout, v6);
640 //sprintf(&v6, "%s", message);
641 *_UUgError_WarningFile = UUgError_WarningFile;
642 result = UUgError_WarningFile;
643 return result;
644}
645
[274]646void __cdecl DDrMain(int argc, char* argv[])
[273]647{
[677]648 int i;
649 char* section;
650 char* option;
651 bool falseoption;
652
[346]653 DDrStartupMessage("daodan attached!");
[466]654
[690]655 // Tell Oni to not load non levelX_final-files by default:
[466]656 opt_ignore_private_data = false;
[690]657
658 // Enable sound by default:
[466]659 opt_sound = true;
660
[346]661 DDrConfig();
[466]662 DDrStartupMessage("parsing command line...");
663 for (i = 1; i < argc; i ++)
664 {
665 if (argv[i][0] == '-')
666 {
667 section = argv[i] + 1;
668 if ((option = strchr(argv[i], '.')))
669 {
670 *option = '\0';
671 falseoption = (option[1] == 'n' || option[1] == 'N') && (option[2] = 'o' || option[2] == 'O');
672 if (i < (argc - 1) && argv[i + 1][0] != '-')
[467]673 DDrIniCallback(section, true, option + 1, argv[++i]);
[466]674 else
675 DDrIniCallback(section, true, option + (falseoption ? 3 : 1), (falseoption ? "false" : "true"));
676 *option = '.';
677 }
678 else
679 {
680 falseoption = (section[0] == 'n' || section[0] == 'N') && (section[1] = 'o' || section[1] == 'O');
681 ini_section = s_options;
682 if (i < (argc - 1) && argv[i + 1][0] != '-')
[467]683 DDrIniCallback(NULL, false, section, argv[++i]);
[466]684 else
685 DDrIniCallback(NULL, false, section + (falseoption ? 2 : 0), (falseoption ? "false" : "true"));
686 }
687 }
688 else
689 {
690 DDrStartupMessage("parse error \"%s\"", argv[i]);
691 break;
692 }
693 }
694 DDrStartupMessage("finished parsing");
[273]695 DDrPatch_Init();
696
697 // Safe startup message printer
[347]698 if (patch_safeprintf)
[689]699 DDrPatch_MakeJump((void*)UUrStartupMessage, (void*)DDrStartupMessage);
[273]700
[297]701 // Daodan device mode enumeration function
[347]702 if (patch_daodandisplayenum)
[705]703 DDrPatch_MakeJump((void*)gl_enumerate_valid_display_modes, (void*)DD_GLrEnumerateDisplayModes);
[297]704
705 // Performance patch
[347]706 if (patch_usegettickcount)
707 {
[689]708 DDrPatch_MakeJump((void*)UUrMachineTime_High, (void*)DDrMachineTime_High);
709 DDrPatch_MakeJump((void*)UUrMachineTime_High_Frequency, (void*)DDrMachineTime_High_Frequency);
710 DDrPatch_MakeJump((void*)UUrMachineTime_Sixtieths, (void*)DDrMachineTime_Sixtieths);
[347]711 }
[677]712
[339]713 // Cheats always enabled
[348]714 if (patch_cheatsenabled)
[689]715 DDrPatch_MakeJump((void*)ONrPersist_GetWonGame, (void*)DDrPersist_GetWonGame);
[677]716
[705]717 // DaodanGL with windowed mode support.
[347]718 if (patch_usedaodangl)
719 {
[705]720 // LIrPlatform_Mode_Set: GetWindowRect -> GetClientRect.
721 DDrPatch_NOOP((char*) OniExe + 0x00002dd6, 6);
722 DDrPatch_MakeCall((char*) OniExe + 0x00002dd6, (void*) GetClientRect);
723
724 // UUrWindow_GetSize: GetWindowRect -> GetClientRect.
725 DDrPatch_NOOP((char*) OniExe + 0x0002651c, 6);
726 DDrPatch_MakeCall((char*) OniExe + 0x0002651c, (void*) GetClientRect);
727
728 // LIrPlatform_PollInputForAction: fix GetCursorPos call to return client coordinates.
729 DDrPatch_NOOP((char*) OniExe + 0x000032cc, 6);
730 DDrPatch_MakeCall((char*) OniExe + 0x000032cc, (void*) DD_GetCursorPos);
731
732 // LIrPlatform_InputEvent_GetMouse: fix GetCursorPos call to return client coordinates.
733 DDrPatch_NOOP((char*) OniExe + 0x00002cc2, 6);
734 DDrPatch_MakeCall((char*) OniExe + 0x00002cc2, (void*) DD_GetCursorPos);
735
736 // LIrPlatform_PollInputForAction: translate SetCursorPos position to screen coordinates.
737 DDrPatch_NOOP((char*) OniExe + 0x000032b7, 6);
738 DDrPatch_MakeCall((char*) OniExe + 0x000032b7, (void*) DD_SetCursorPos);
739
740 // LIrPlatform_PollInputForAction: translate SetCursorPos position to screen coordinates.
741 DDrPatch_NOOP((char*) OniExe + 0x00003349, 6);
742 DDrPatch_MakeCall((char*) OniExe + 0x00003349, (void*) DD_SetCursorPos);
743
744 // Replace ONrPlatformInitialize.
745 DDrPatch_MakeJump((void*) ONrPlatform_Initialize, (void*) DD_ONrPlatform_Initialize);
746
747 // Replace gl_platform_initialize.
748 DDrPatch_MakeJump((void*) gl_platform_initialize, (void*) DD_GLrPlatform_Initialize);
749
750 // Replace gl_platform_dispose.
751 DDrPatch_MakeJump((void *) gl_platform_dispose, (void*) DD_GLrPlatform_Dispose);
752 }
753
754 if (patch_clipcursor)
755 {
756 // LIrMode_Set: replace LIrPlatform_Mode_Set call with our hook.
757 DDrPatch_MakeCall((void*)(OniExe + 0x00003f9f), (void*) DD_LIrPlatform_Mode_Set);
758
759 // LIrMode_Set_Internal: replace LIrPlatform_Mode_Set call with our hook.
760 DDrPatch_MakeCall((void*)(OniExe + 0x00003fff), (void*) DD_LIrPlatform_Mode_Set);
761
762 // LIrTermiante: replace LIrPlatform_Terminate call with our hook.
763 DDrPatch_MakeCall((void*)(OniExe + 0x000004cb8), (void*) DD_LIrPlatform_Terminate);
[347]764 }
[705]765
[349]766
[439]767 if (patch_daodaninit)
[689]768 DDrPatch_MakeCall((void*)(OniExe + 0x000d345a), (void*)DDrGame_Init);
[439]769
[447]770 // Patches for existing BSL functions
771 if (patch_bsl)
772 SLrDaodan_Patch();
[677]773
[452]774 if (patch_cheater)
[455]775 {
[689]776 DDrPatch_MakeCall((void*)(OniExe + 0x000f618f), (void*)DDrCheater);
777 DDrPatch_Int16((short*)(OniExe + 0x000deb45), 0x5590);
[677]778#if 1
[689]779 DDrPatch_MakeCall((void*)(OniExe + 0x000deb47), (void*)FallingFrames);
[677]780#endif
[689]781 DDrPatch_MakeJump((void*)(OniExe + 0x0010f021), (void*)DDrCheater_LevelLoad);
[455]782 }
[677]783
[689]784 DDrPatch_MakeJump((void*)(OniExe + 0x000245A0), (void*)DDrPrintWarning);
[452]785
[705]786 ONiMain(argc, argv);
[273]787}
[465]788/*
789void DDrWrongExe()
790{
791 switch (MessageBox(NULL, "This version of the Daodan DLL is incompatible with your Oni.exe.\n"
792 "Click OK for more information. To continue using Oni without the patch, replace the downloaded binkw32.dll with the original.", "Daodan", MB_OKCANCEL | MB_ICONERROR))
793 {
794 case IDOK:
795 {
796 STARTUPINFO si;
797 PROCESS_INFORMATION pi;
798 FillMemory(&si, 0, sizeof(si));
799 FillMemory(&pi, 0, sizeof(pi));
800 si.cb = sizeof(si);
801 if (!CreateProcess(NULL, "cmd /c \"start http://wiki.oni2.net/Daodan_DLL\"", NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi))
802 MessageBox(NULL, "", "", 0);
803 CloseHandle(pi.hProcess);
804 CloseHandle(pi.hThread);
805 }
806 default:
807 ExitProcess(0);
808 }
809}
810*/
[272]811BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved)
812{
813 switch (fdwReason)
814 {
815 case DLL_PROCESS_ATTACH:
816 DDrDLLModule = hinstDLL;
817 DDrONiModule = GetModuleHandle(NULL);
818
[677]819 if (*(uint32_t*)(OniExe + 0x0011acd0) == 0x09d36852)
[689]820 DDrPatch_MakeCall((void*)(OniExe + 0x0010fb49), (void*)DDrMain);
[465]821 else
822 ExitProcess(0);
[272]823 break;
824 }
825 return TRUE;
826}
Note: See TracBrowser for help on using the repository browser.