Copyright update.
2 * Copyright (C) 2008 Chris Porter
4 * See LICENSE.txt for licensing information.
7 #define WIN32_LEAN_AND_MEAN
16 static BOOL (WINAPI *TrueBitBlt)(HDC hdc, int x, int y, int cx, int cy, HDC hdcSrc, int x1, int y1, DWORD rop) = BitBlt;
17 static HANDLE (WINAPI *TrueFindFirstFileA)(LPCSTR lpFileName, LPWIN32_FIND_DATA lpFindFileData) = FindFirstFileA;
18 static BOOL (WINAPI *TrueFindNextFileA)(HANDLE hFindFile, LPWIN32_FIND_DATA lpFindFileData) = FindNextFileA;
19 static BOOL (WINAPI *TrueFindClose)(HANDLE hFindFile) = FindClose;
20 static BOOL (WINAPI *TrueHeapFree)(HANDLE hHeap, DWORD dwFlags, LPVOID lpMem) = HeapFree;
21 static HRESULT (WINAPI *TrueDirectDrawCreate)(GUID *lpGUID, LPDIRECTDRAW *lplpDD, IUnknown *pUnkOuter);
23 static HRESULT (STDMETHODCALLTYPE *TrueCreateSurface)(void *, LPDDSURFACEDESC, LPDIRECTDRAWSURFACE *, IUnknown *);
24 static HRESULT (STDMETHODCALLTYPE *TrueUnlock)(IDirectDrawSurface *, LPVOID);
25 static HRESULT (STDMETHODCALLTYPE *TrueLock)(IDirectDrawSurface *, LPRECT, LPDDSURFACEDESC, DWORD, HANDLE);
27 static BOOL WINAPI FixedBitBlt(HDC hdc, int x, int y, int cx, int cy, HDC hdcSrc, int x1, int y1, DWORD rop) {
28 BOOL b = TrueBitBlt(hdc, x, y, cx, cy, hdcSrc, x1, y1, rop);
35 static HANDLE mechlab = INVALID_HANDLE_VALUE;
37 static void mutatefinddata(LPWIN32_FIND_DATA fd) {
38 memcpy(fd->cAlternateFileName, fd->cFileName, sizeof(fd->cAlternateFileName));
39 fd->cAlternateFileName[sizeof(fd->cAlternateFileName) - 1] = '\0';
42 static HANDLE WINAPI FixedFindFirstFileA(LPCSTR lpFileName, LPWIN32_FIND_DATA lpFindFileData) {
43 HANDLE h = TrueFindFirstFileA(lpFileName, lpFindFileData);
46 if(h == INVALID_HANDLE_VALUE)
49 if(sscanf_s(lpFileName, "mek\\%c%c%c??usr.mek", &a, &b, &c)) {
51 mutatefinddata(lpFindFileData);
57 static BOOL WINAPI FixedFindNextFileA(HANDLE hFindFile, LPWIN32_FIND_DATA lpFindFileData) {
58 BOOL b = TrueFindNextFileA(hFindFile, lpFindFileData);
60 if(b && (mechlab == lpFindFileData))
61 mutatefinddata(lpFindFileData);
66 static BOOL WINAPI FixedFindClose(HANDLE hFindFile) {
67 if(mechlab == hFindFile)
68 mechlab = INVALID_HANDLE_VALUE;
70 return TrueFindClose(hFindFile);
73 static BOOL WINAPI FixedHeapFree(HANDLE hHeap, DWORD dwFlags, LPVOID lpMem) {
74 /* memory leaks ahoy */
79 static void LimitRate(int rate) {
80 static DWORD nexttick;
81 DWORD t = timeGetTime();
89 /*sleepfor = nexttick - t;*/
91 /* for some reason sleeping here screws up windows... */
93 while(timeGetTime() < nexttick)
97 static int frameratelimit;
98 static const char *setupframeratelimit(char *args) {
99 frameratelimit = 1000 / atoi(args);
100 if(frameratelimit < 1 || frameratelimit > 1000)
101 return "Bad frame rate limit supplied.";
107 static const char *setupfpscounter(char *args) {
108 if(!strcmp(args, "1"))
114 static int getfpsrate() {
115 static DWORD lastticks;
116 static int fps, frames;
117 DWORD ticks = timeGetTime(), delta;
125 delta = ticks - lastticks;
127 double denom = ((double)delta / (double)frames);
131 fps = (int)(1000.0 / denom);
141 static LPDDSURFACEDESC mainsurface;
142 static HRESULT STDMETHODCALLTYPE FixedUnlock(IDirectDrawSurface *p, LPVOID a) {
143 static TIMECAPS timecaps;
144 static int gottimecaps;
146 if(gottimecaps == 0) {
148 if(timeGetDevCaps(&timecaps, sizeof(timecaps)) != TIMERR_NOERROR)
149 timecaps.wPeriodMin = 10;
152 timeBeginPeriod(timecaps.wPeriodMin);
153 LimitRate(frameratelimit);
156 int rate = getfpsrate();
157 int scale = 4, oncolour = 0, offcolour = 255;
158 plotnumbers(rate, mainsurface, 0, 0, scale, oncolour);
159 plotnumbers(rate, mainsurface, 2, 2, scale, oncolour);
160 plotnumbers(rate, mainsurface, 0, 2, scale, oncolour);
161 plotnumbers(rate, mainsurface, 2, 0, scale, oncolour);
162 plotnumbers(rate, mainsurface, 1, 1, scale, offcolour);
165 timeEndPeriod(timecaps.wPeriodMin);
167 return TrueUnlock(p, a);
170 static HRESULT STDMETHODCALLTYPE FixedLock(IDirectDrawSurface *p, LPRECT a, LPDDSURFACEDESC b, DWORD c, HANDLE d) {
171 HRESULT ret = TrueLock(p, a, b, c, d);
179 static HRESULT STDMETHODCALLTYPE FixedCreateSurface(void *p, LPDDSURFACEDESC a, LPDIRECTDRAWSURFACE *b, IUnknown *c) {
180 IDirectDrawSurface *psurf;
181 HRESULT ret = TrueCreateSurface(p, a, b, c);
188 if(psurf->lpVtbl->Unlock != FixedUnlock)
189 TrueUnlock = psurf->lpVtbl->Unlock;
190 psurf->lpVtbl->Unlock = FixedUnlock;
193 if(psurf->lpVtbl->Lock != FixedLock)
194 TrueLock = psurf->lpVtbl->Lock;
195 psurf->lpVtbl->Lock = FixedLock;
201 static HRESULT WINAPI FixedDirectDrawCreate(GUID *lpGUID, LPDIRECTDRAW *lplpDD, IUnknown *pUnkOuter) {
203 HRESULT ret = TrueDirectDrawCreate(lpGUID, lplpDD, pUnkOuter);
210 if(pdd->lpVtbl->CreateSurface != FixedCreateSurface)
211 TrueCreateSurface = pdd->lpVtbl->CreateSurface;
212 pdd->lpVtbl->CreateSurface = FixedCreateSurface;
217 static hunk hstartup[] = {
218 { HUNK_FUNC, (void *)&FixedBitBlt, (void *)&TrueBitBlt, },
221 static hunk hmechlab[] = {
222 { HUNK_FUNC, (void *)&FixedFindFirstFileA, (void *)&TrueFindFirstFileA },
223 { HUNK_FUNC, (void *)&FixedFindNextFileA, (void *)&TrueFindNextFileA },
224 { HUNK_FUNC, (void *)&FixedFindClose, (void *)&TrueFindClose },
227 static hunk hheaphack[] = {
228 { HUNK_FUNC, (void *)&FixedHeapFree, (void *)&TrueHeapFree },
231 static hunk hddraw[] = {
232 { HUNK_NAME, (void *)&FixedDirectDrawCreate, NULL, "ddraw.dll", "DirectDrawCreate", &TrueDirectDrawCreate },
237 { "startup", "Fixes startup termination", 1, hstartup },
238 { "mechlab", "Fixes Mech Lab overweight issue", 3, hmechlab },
239 { "heaphack", "Fixes a lot of random crashes but will increase memory usage.", 1, hheaphack },
240 { "frameratelimit", "Fixes jumpjet and missile problems", 1, hddraw, "45", "[frame rate in frames/second]", setupframeratelimit },
241 { "fpscounter", "FPS counter", 1, hddraw, "0", "[1 to enable]", setupfpscounter },