source: Daodan/src/Daodan.c@ 465

Last change on this file since 465 was 465, checked in by rossy, 15 years ago
File size: 16.8 KB
Line 
1#include <string.h>
2
3#include "Daodan.h"
4#include "Daodan_Patch.h"
5#include "Daodan_Utility.h"
6#include "Daodan_Win32.h"
7#include "Daodan_Cheater.h"
8#include "Daodan_Persistence.h"
9#include "Daodan_BSL.h"
10
11#include "Daodan_WindowHack.h"
12
13#include "Oni.h"
14#include "Oni_Persistence.h"
15
16#include "BFW_Utility.h"
17
18#include "oni_gl.h"
19#include "daodan_gl.h"
20
21#include "inifile.h"
22
23HMODULE DDrDLLModule;
24HMODULE DDrONiModule;
25
26bool patch_fonttexturecache = true;
27bool patch_largetextures = true;
28bool patch_levelplugins = true;
29bool patch_pathfinding = true;
30bool patch_projaware = true;
31bool patch_directinput = true;
32bool patch_wpfadetime = true;
33bool patch_kickguns = false;
34bool patch_cooldowntimer = true;
35bool patch_throwtest = false;
36bool patch_alttab = true;
37bool patch_particledisablebit = false;
38bool patch_multibyte = false;
39bool patch_cheattable = true;
40bool patch_argb8888 = true;
41bool patch_killvtune = true;
42
43bool patch_safeprintf = true;
44bool patch_daodandisplayenum = true;
45bool patch_usegettickcount = true;
46bool patch_cheatsenabled = true;
47bool patch_usedaodangl = false;
48bool patch_windowhack = true;
49bool patch_daodaninit = true;
50bool patch_bsl = true;
51bool patch_cheater = true;
52
53bool opt_usedaodanbsl = true;
54
55bool DDrPatch_Init()
56{
57 DDrStartupMessage("patching engine");
58
59 // Font texture cache doubled
60 if (patch_fonttexturecache)
61 {
62 DDrPatch_Byte (OniExe + 0x00020ea7, 0x20);
63 DDrPatch_Byte (OniExe + 0x00020f4a, 0x40);
64 }
65
66 // Now supports textures up to 512x512
67 if (patch_largetextures)
68 DDrPatch_Byte (OniExe + 0x00005251, 0x10);
69
70 // Non-"_Final" levels are now valid
71 if (patch_levelplugins)
72 DDrPatch_Byte (OniExe + 0x000206a8, 0x01);
73
74 // Pathfinding grid cache size x8
75 if (patch_pathfinding)
76 {
77 DDrPatch_Byte (OniExe + 0x0010b03b, 0x20);
78 DDrPatch_Byte (OniExe + 0x0010b04c, 0x20);
79 }
80
81 // Projectile awareness fixed
82 if (patch_projaware)
83 {
84 DDrPatch_Byte (OniExe + 0x0009c07c, 0x6c);
85 DDrPatch_Byte (OniExe + 0x0009c080, 0x70);
86 DDrPatch_Byte (OniExe + 0x0009c084, 0x74);
87 DDrPatch_Byte (OniExe + 0x0009c110, 0x6c);
88 }
89
90 // Forced DirectInput (for Windows NT)
91 if (patch_directinput)
92 DDrPatch_Byte (OniExe + 0x00002e6d, 0xeb);
93
94 if (patch_wpfadetime)
95 {
96 // Makes wp_fadetime actually have a function
97 const char fadetime_patch[] = { 0x66, 0x8B, 0x1D, 0xC4, 0x7D, 0x62, 0x00, 0x66, 0x89, 0x5E, 0x46, 0x5B, 0x5E, 0x83, 0xC4, 0x14, 0xC3 };
98 DDrPatch_Const (OniExe + 0x0011a889, fadetime_patch);
99 DDrPatch_Byte (OniExe + 0x0011a560, 0x31);
100
101 // Sets the fadetime to 4800 by default
102 DDrPatch_Int16 (OniExe + 0x0011ab0e, 0x12c0);
103 }
104
105
106 // Hackish fix for Konoko not kicking guns
107 if (patch_kickguns)
108 {
109 const 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 };
110 DDrPatch_Const (OniExe + 0x000dc420, kickgun_patch);
111 }
112
113 // Cooldown timer exploit fix ^_^
114 if (patch_cooldowntimer)
115 {
116 const 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 };
117 DDrPatch_Const (OniExe + 0x0011a825, cooldown_patch);
118 }
119
120 if (patch_throwtest)
121 {
122 const char throwtest_patch[] = { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 };
123 DDrPatch_Const(OniExe + 0x000dc190, throwtest_patch);
124 }
125
126 // 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.
127 if (patch_alttab)
128 {
129 DDrPatch_Byte ((void*)UUrPlatform_Initialize, 0xC3);
130 DDrPatch_Byte ((void*)UUrPlatform_Terminate, 0xC3);
131 }
132
133 // 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.)
134 if (patch_particledisablebit)
135 DDrPatch_Int16 (OniExe + 0x001b184, 0x9090);
136
137 // Multi-byte patch (multiple language support)
138 if (!patch_multibyte)
139 {
140 DDrPatch_Byte (OniExe + 0x0002d8f8, 0xeb);
141 DDrPatch_Byte (OniExe + 0x0002d9ad, 0xeb);
142 DDrPatch_Byte (OniExe + 0x0002dbe2, 0xeb);
143 DDrPatch_Byte (OniExe + 0x0002dec3, 0xeb);
144 DDrPatch_Byte (OniExe + 0x0002e2ab, 0xeb);
145 DDrPatch_Byte (OniExe + 0x0002e2c4, 0xeb);
146 DDrPatch_Byte (OniExe + 0x0002e379, 0xeb);
147 DDrPatch_Byte (OniExe + 0x0002e48c, 0xeb);
148 DDrPatch_Byte (OniExe + 0x0002e4d0, 0xeb);
149 DDrPatch_Byte (OniExe + 0x0002e4f4, 0xeb);
150 DDrPatch_Byte (OniExe + 0x0002e646, 0xeb);
151 DDrPatch_Byte (OniExe + 0x0002e695, 0xeb);
152 DDrPatch_Byte (OniExe + 0x0002e944, 0xeb);
153 DDrPatch_Byte (OniExe + 0x0002e95d, 0xeb);
154 DDrPatch_Byte (OniExe + 0x0002e98e, 0xeb);
155 DDrPatch_Byte (OniExe + 0x0002e9dc, 0xeb);
156 }
157
158 // Cheat table patch
159 if (patch_cheattable)
160 {
161 DDrPatch_Int32 (OniExe + 0x000f616b, (int)&DDr_CheatTable[0].name);
162 DDrPatch_Int32 (OniExe + 0x000f617a, (int)&DDr_CheatTable[0].message_on);
163 }
164
165 // ARGB8888 textures
166 if (patch_argb8888)
167 {
168 DDrPatch_Byte (OniExe + 0x00135af0, 0x07);
169 DDrPatch_Byte (OniExe + 0x00135af4, 0x0B);
170 }
171
172 // Disable loading the vtuneapi.dll
173 if (patch_killvtune)
174 DDrPatch_Byte (OniExe + 0x00026340, 0xC3);
175
176 return true;
177}
178
179enum {s_unknown, s_options, s_patch, s_bsl, s_language} ini_section;
180
181bool DDrIniCallback(char* section, bool newsection, char* name, char* value)
182{
183 if (newsection)
184 {
185 if (!stricmp(section, "options"))
186 ini_section = s_options;
187 else if (!stricmp(section, "patch"))
188 ini_section = s_patch;
189 else if (!stricmp(section, "bsl"))
190 ini_section = s_bsl;
191 else if (!stricmp(section, "language"))
192 ini_section = s_language;
193 else
194 {
195 ini_section = s_unknown;
196 DDrStartupMessage("unrecognised ini section \"%s\"", section);
197 }
198 }
199
200 switch (ini_section)
201 {
202 case s_options:
203 if (!stricmp(name, "usedaodanbsl"))
204 opt_usedaodanbsl = !stricmp(inifile_cleanstr(value), "true");
205 break;
206 case s_patch:
207 if (!stricmp(name, "fonttexturecache"))
208 patch_fonttexturecache = !stricmp(inifile_cleanstr(value), "true");
209 else if (!stricmp(name, "largetextures"))
210 patch_largetextures = !stricmp(inifile_cleanstr(value), "true");
211 else if (!stricmp(name, "levelplugins"))
212 patch_levelplugins = !stricmp(inifile_cleanstr(value), "true");
213 else if (!stricmp(name, "pathfinding"))
214 patch_pathfinding = !stricmp(inifile_cleanstr(value), "true");
215 else if (!stricmp(name, "projaware"))
216 patch_projaware = !stricmp(inifile_cleanstr(value), "true");
217 else if (!stricmp(name, "directinput"))
218 patch_directinput = !stricmp(inifile_cleanstr(value), "true");
219 else if (!stricmp(name, "wpfadetime"))
220 patch_wpfadetime = !stricmp(inifile_cleanstr(value), "true");
221 else if (!stricmp(name, "kickguns"))
222 patch_kickguns = !stricmp(inifile_cleanstr(value), "true");
223 else if (!stricmp(name, "cooldowntimer"))
224 patch_cooldowntimer = !stricmp(inifile_cleanstr(value), "true");
225 else if (!stricmp(name, "throwtest"))
226 patch_throwtest = !stricmp(inifile_cleanstr(value), "true");
227 else if (!stricmp(name, "alttab"))
228 patch_alttab = !stricmp(inifile_cleanstr(value), "true");
229 else if (!stricmp(name, "particledisablebit"))
230 patch_particledisablebit = !stricmp(inifile_cleanstr(value), "true");
231 else if (!stricmp(name, "multibyte"))
232 patch_multibyte = !stricmp(inifile_cleanstr(value), "true");
233 else if (!stricmp(name, "cheattable"))
234 patch_cheattable = !stricmp(inifile_cleanstr(value), "true");
235 else if (!stricmp(name, "argb8888"))
236 patch_argb8888 = !stricmp(inifile_cleanstr(value), "true");
237 else if (!stricmp(name, "killvtune"))
238 patch_killvtune = !stricmp(inifile_cleanstr(value), "true");
239 else if (!stricmp(name, "safeprintf"))
240 patch_safeprintf = !stricmp(inifile_cleanstr(value), "true");
241 else if (!stricmp(name, "daodandisplayenum"))
242 patch_daodandisplayenum = !stricmp(inifile_cleanstr(value), "true");
243 else if (!stricmp(name, "usegettickcount"))
244 patch_usegettickcount = !stricmp(inifile_cleanstr(value), "true");
245 else if (!stricmp(name, "cheatsenabled"))
246 patch_cheatsenabled = !stricmp(inifile_cleanstr(value), "true");
247 else if (!stricmp(name, "usedaodangl"))
248 patch_usedaodangl = !stricmp(inifile_cleanstr(value), "true");
249 else if (!stricmp(name, "windowhack"))
250 patch_windowhack = !stricmp(inifile_cleanstr(value), "true");
251 else if (!stricmp(name, "daodaninit"))
252 patch_daodaninit = !stricmp(inifile_cleanstr(value), "true");
253 else if (!stricmp(name, "bsl"))
254 patch_bsl = !stricmp(inifile_cleanstr(value), "true");
255 else if (!stricmp(name, "cheater"))
256 patch_cheater = !stricmp(inifile_cleanstr(value), "true");
257 else
258 DDrStartupMessage("unrecognised patch \"%s\"", name);
259 break;
260 case s_language:
261 if (!stricmp(name, "savepoint"))
262 {
263 char* str = strdup(value);
264 DDrPatch_Int32(OniExe + 0x000fd730, (int)str);
265 DDrPatch_Int32(OniExe + 0x000fd738, (int)str);
266 }
267 else if (!stricmp(name, "syndicatewarehouse"))
268 {
269 char* str = strdup(value);
270 DDrPatch_Int32(OniExe + 0x000fd71a, (int)str);
271 DDrPatch_Int32(OniExe + 0x0010ef75, (int)str);
272 }
273 else if (!stricmp(name, "damn"))
274 DDrPatch_StrDup(OniExe + 0x0010fb6e, value);
275 else if (!stricmp(name, "blam"))
276 DDrPatch_StrDup(OniExe + 0x0010fb73, value);
277 else if (!stricmp(name, "shapeshifter_on"))
278 DDr_CheatTable[0].message_on = strdup(value);
279 else if (!stricmp(name, "shapeshifter_off"))
280 DDr_CheatTable[0].message_off = strdup(value);
281 else if (!stricmp(name, "liveforever_on"))
282 DDr_CheatTable[1].message_on = strdup(value);
283 else if (!stricmp(name, "liveforever_off"))
284 DDr_CheatTable[1].message_off = strdup(value);
285 else if (!stricmp(name, "touchofdeath_on"))
286 DDr_CheatTable[2].message_on = strdup(value);
287 else if (!stricmp(name, "touchofdeath_off"))
288 DDr_CheatTable[2].message_off = strdup(value);
289 else if (!stricmp(name, "canttouchthis_on"))
290 DDr_CheatTable[3].message_on = strdup(value);
291 else if (!stricmp(name, "canttouchthis_off"))
292 DDr_CheatTable[3].message_off = strdup(value);
293 else if (!stricmp(name, "fatloot_on"))
294 DDr_CheatTable[4].message_on = strdup(value);
295 else if (!stricmp(name, "glassworld_on"))
296 DDr_CheatTable[5].message_on = strdup(value);
297 else if (!stricmp(name, "glassworld_off"))
298 DDr_CheatTable[5].message_off = strdup(value);
299 else if (!stricmp(name, "winlevel_on"))
300 DDr_CheatTable[6].message_on = strdup(value);
301 else if (!stricmp(name, "loselevel_on"))
302 DDr_CheatTable[7].message_on = strdup(value);
303 else if (!stricmp(name, "bighead_on"))
304 DDr_CheatTable[8].message_on = strdup(value);
305 else if (!stricmp(name, "bighead_off"))
306 DDr_CheatTable[8].message_off = strdup(value);
307 else if (!stricmp(name, "minime_on"))
308 DDr_CheatTable[9].message_on = strdup(value);
309 else if (!stricmp(name, "minime_off"))
310 DDr_CheatTable[9].message_off = strdup(value);
311 else if (!stricmp(name, "superammo_on"))
312 DDr_CheatTable[10].message_on = strdup(value);
313 else if (!stricmp(name, "superammo_off"))
314 DDr_CheatTable[10].message_off = strdup(value);
315 else if (!stricmp(name, "devmode_on"))
316 {
317 char* str = strdup(value);
318 DDr_CheatTable[11].message_on = str;
319 DDr_CheatTable[cheat_x].message_on = str;
320 }
321 else if (!stricmp(name, "devmode_off"))
322 {
323 char* str = strdup(value);
324 DDr_CheatTable[11].message_off = str;
325 DDr_CheatTable[cheat_x].message_off = str;
326 }
327 else if (!stricmp(name, "reservoirdogs_on"))
328 DDr_CheatTable[12].message_on = strdup(value);
329 else if (!stricmp(name, "reservoirdogs_off"))
330 DDr_CheatTable[12].message_off = strdup(value);
331 else if (!stricmp(name, "roughjustice_on"))
332 DDr_CheatTable[13].message_on = strdup(value);
333 else if (!stricmp(name, "roughjustice_off"))
334 DDr_CheatTable[13].message_off = strdup(value);
335 else if (!stricmp(name, "chenille_on"))
336 DDr_CheatTable[14].message_on = strdup(value);
337 else if (!stricmp(name, "chenille_off"))
338 DDr_CheatTable[14].message_off = strdup(value);
339 else if (!stricmp(name, "behemoth_on"))
340 DDr_CheatTable[15].message_on = strdup(value);
341 else if (!stricmp(name, "behemoth_off"))
342 DDr_CheatTable[15].message_off = strdup(value);
343 else if (!stricmp(name, "elderrune_on"))
344 DDr_CheatTable[16].message_on = strdup(value);
345 else if (!stricmp(name, "elderrune_off"))
346 DDr_CheatTable[16].message_off = strdup(value);
347 else if (!stricmp(name, "moonshadow_on"))
348 DDr_CheatTable[17].message_on = strdup(value);
349 else if (!stricmp(name, "moonshadow_off"))
350 DDr_CheatTable[17].message_off = strdup(value);
351 else if (!stricmp(name, "munitionfrenzy_on"))
352 DDr_CheatTable[18].message_on = strdup(value);
353 else if (!stricmp(name, "fistsoflegend_on"))
354 DDr_CheatTable[19].message_on = strdup(value);
355 else if (!stricmp(name, "fistsoflegend_off"))
356 DDr_CheatTable[19].message_off = strdup(value);
357 else if (!stricmp(name, "killmequick_on"))
358 DDr_CheatTable[20].message_on = strdup(value);
359 else if (!stricmp(name, "killmequick_off"))
360 DDr_CheatTable[20].message_off = strdup(value);
361 else if (!stricmp(name, "carousel_on"))
362 DDr_CheatTable[21].message_on = strdup(value);
363 else if (!stricmp(name, "carousel_off"))
364 DDr_CheatTable[21].message_off = strdup(value);
365 else
366 DDrStartupMessage("unrecognised language item \"%s\"", name);
367 break;
368 case s_bsl:
369 default:
370 break;
371 }
372
373 return true;
374}
375
376void DDrConfig()
377{
378 if (GetFileAttributes("daodan.ini") == INVALID_FILE_ATTRIBUTES)
379 {
380 DDrStartupMessage("daodan.ini doesn't exist, creating");
381 FILE* fp = fopen("daodan.ini", "w");
382 if (fp)
383 {
384 fputs("[Options]\n", fp);
385 fclose(fp);
386 }
387 }
388
389 DDrStartupMessage("parsing daodan.ini...");
390 if (!inifile_read("daodan.ini", DDrIniCallback))
391 DDrStartupMessage("error reading daodan.ini, check your syntax!");
392 DDrStartupMessage("finished parsing");
393}
394
395void ONICALL DDrGame_Init()
396{
397 if (opt_usedaodanbsl)
398 SLrDaodan_Initalize();
399}
400
401void __cdecl DDrMain(int argc, char* argv[])
402{
403 DDrStartupMessage("daodan attached!");
404 DDrConfig();
405 DDrPatch_Init();
406
407 // Safe startup message printer
408 if (patch_safeprintf)
409 DDrPatch_MakeJump(UUrStartupMessage, DDrStartupMessage);
410
411 // Daodan device mode enumeration function
412 if (patch_daodandisplayenum)
413 DDrPatch_MakeJump(gl_enumerate_valid_display_modes, daodan_enumerate_valid_display_modes);
414
415 // Performance patch
416 if (patch_usegettickcount)
417 {
418 DDrPatch_MakeJump(UUrMachineTime_High, DDrMachineTime_High);
419 DDrPatch_MakeJump(UUrMachineTime_High_Frequency, DDrMachineTime_High_Frequency);
420 DDrPatch_MakeJump(UUrMachineTime_Sixtieths, DDrMachineTime_Sixtieths);
421 }
422
423 // Cheats always enabled
424 if (patch_cheatsenabled)
425 DDrPatch_MakeJump(ONrPersist_GetWonGame, DDrPersist_GetWonGame);
426
427 // Windowed mode
428 if (patch_usedaodangl)
429 {
430 DDrPatch_MakeJump(ONrPlatform_Initialize, DDrPlatform_Initialize);
431 DDrPatch_MakeJump(gl_platform_initialize, daodangl_platform_initialize);
432 }
433
434 // Hacked windowed mode (for when daodangl isn't working properly)
435 if (patch_windowhack)
436 DDrWindowHack_Install();
437
438 if (patch_daodaninit)
439 DDrPatch_MakeCall(OniExe + 0x000d345a, DDrGame_Init);
440
441 // Patches for existing BSL functions
442 if (patch_bsl)
443 SLrDaodan_Patch();
444
445 if (patch_cheater)
446 {
447 DDrPatch_MakeCall(OniExe + 0x000f618f, DDrCheater);
448 DDrPatch_Int16(OniExe + 0x000deb45, 0x5590);
449 DDrPatch_MakeCall(OniExe + 0x000deb47, FallingFrames);
450 DDrPatch_MakeJump(OniExe + 0x0010f021, DDrCheater_LevelLoad);
451 }
452
453 init_daodan_gl();
454
455 ONiMain(argc, argv);
456}
457/*
458void DDrWrongExe()
459{
460 switch (MessageBox(NULL, "This version of the Daodan DLL is incompatible with your Oni.exe.\n"
461 "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))
462 {
463 case IDOK:
464 {
465 STARTUPINFO si;
466 PROCESS_INFORMATION pi;
467 FillMemory(&si, 0, sizeof(si));
468 FillMemory(&pi, 0, sizeof(pi));
469 si.cb = sizeof(si);
470 if (!CreateProcess(NULL, "cmd /c \"start http://wiki.oni2.net/Daodan_DLL\"", NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi))
471 MessageBox(NULL, "", "", 0);
472 CloseHandle(pi.hProcess);
473 CloseHandle(pi.hThread);
474 }
475 default:
476 ExitProcess(0);
477 }
478}
479*/
480BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved)
481{
482 switch (fdwReason)
483 {
484 case DLL_PROCESS_ATTACH:
485 DDrDLLModule = hinstDLL;
486 DDrONiModule = GetModuleHandle(NULL);
487
488 if (*(uint32_t*)((void*)OniExe + 0x0011acd0) == 0x09d36852)
489 DDrPatch_MakeCall(OniExe + 0x0010fb49, DDrMain);
490 else
491 ExitProcess(0);
492 break;
493 }
494 return TRUE;
495}
Note: See TracBrowser for help on using the repository browser.