MW2Shim/patches.c
changeset 8: 6f2deddc0cf6
parent 0:27248e64b537
manifest: 6f2deddc0cf6
author: Chris Porter <chris@warp13.co.uk>
date: Sun Apr 13 02:46:24 2008 +0100 (7 months ago)
permissions: -rw-r--r--
Write version information to registry in installer.
        1 /*
        2  * Copyright (C) 2008 Chris Porter
        3  * All rights reserved.
        4  * See LICENSE.txt for licensing information.
        5  */
        6 
        7 #define WIN32_LEAN_AND_MEAN
        8 
        9 #include <windows.h>
       10 #include <stdio.h>
       11 #include <ddraw.h>
       12 
       13 #include "mw2shim.h"
       14 
       15 static BOOL	(WINAPI *TrueBitBlt)(HDC hdc, int x, int y, int cx, int cy, HDC hdcSrc, int x1, int y1, DWORD rop) = BitBlt;
       16 static HANDLE (WINAPI *TrueFindFirstFileA)(LPCSTR lpFileName, LPWIN32_FIND_DATA lpFindFileData) = FindFirstFileA;
       17 static BOOL (WINAPI *TrueFindNextFileA)(HANDLE hFindFile, LPWIN32_FIND_DATA lpFindFileData) = FindNextFileA;
       18 static BOOL (WINAPI *TrueFindClose)(HANDLE hFindFile) = FindClose;
       19 static BOOL (WINAPI *TrueHeapFree)(HANDLE hHeap, DWORD dwFlags, LPVOID lpMem) = HeapFree;
       20 static HRESULT (WINAPI *TrueDirectDrawCreate)(GUID *lpGUID, LPDIRECTDRAW *lplpDD, IUnknown *pUnkOuter);
       21 
       22 static HRESULT (STDMETHODCALLTYPE *TrueCreateSurface)(void *, LPDDSURFACEDESC, LPDIRECTDRAWSURFACE *, IUnknown *);
       23 static HRESULT (STDMETHODCALLTYPE *TrueUnlock)(IDirectDrawSurface *, LPVOID);
       24 
       25 static BOOL WINAPI FixedBitBlt(HDC hdc, int x, int y, int cx, int cy, HDC hdcSrc, int x1, int y1, DWORD rop) {
       26   BOOL b = TrueBitBlt(hdc, x, y, cx, cy, hdcSrc, x1, y1, rop);  
       27   if(!b)
       28     return 0;
       29 
       30   return cy;
       31 }
       32 
       33 static HANDLE mechlab = INVALID_HANDLE_VALUE;
       34 
       35 static void mutatefinddata(LPWIN32_FIND_DATA fd) {
       36   memcpy(fd->cAlternateFileName, fd->cFileName, sizeof(fd->cAlternateFileName));
       37   fd->cAlternateFileName[sizeof(fd->cAlternateFileName) - 1] = '\0';
       38 }
       39 
       40 static HANDLE WINAPI FixedFindFirstFileA(LPCSTR lpFileName, LPWIN32_FIND_DATA lpFindFileData) {
       41   HANDLE h = TrueFindFirstFileA(lpFileName, lpFindFileData);
       42   char a, b, c;
       43 
       44   if(h == INVALID_HANDLE_VALUE)
       45     return h;
       46   
       47   if(sscanf_s(lpFileName, "mek\\%c%c%c??usr.mek", &a, &b, &c)) {
       48     mechlab = h;
       49     mutatefinddata(lpFindFileData);
       50   }
       51     
       52   return h;
       53 }
       54 
       55 static BOOL WINAPI FixedFindNextFileA(HANDLE hFindFile, LPWIN32_FIND_DATA lpFindFileData) {
       56   BOOL b = TrueFindNextFileA(hFindFile, lpFindFileData);
       57   
       58   if(b && (mechlab == lpFindFileData))
       59     mutatefinddata(lpFindFileData);
       60   
       61   return b;
       62 }
       63 
       64 static BOOL WINAPI FixedFindClose(HANDLE hFindFile) {
       65   if(mechlab == hFindFile)
       66     mechlab = INVALID_HANDLE_VALUE;
       67 
       68   return TrueFindClose(hFindFile);
       69 }
       70 
       71 static BOOL WINAPI FixedHeapFree(HANDLE hHeap, DWORD dwFlags, LPVOID lpMem) {
       72   /* memory leaks ahoy */
       73   
       74   return TRUE;
       75 }
       76 
       77 static DWORD limitlasttime, limitavg;
       78 static int fpscalls, fpslasttime, lastfps = -1;
       79 static int LimitRate(int rate) {
       80   DWORD t = GetTickCount();
       81   int timetaken, delta;
       82   
       83   fpscalls++;
       84   if(!fpslasttime)
       85     fpslasttime = t;
       86   
       87   if(t - fpslasttime > 1000) {
       88     lastfps = fpscalls;
       89     fpscalls = 0;
       90     fpslasttime = t;
       91   }
       92   if(!limitlasttime) {
       93     limitlasttime = t;
       94     return lastfps;
       95   }
       96   
       97   timetaken = t - limitlasttime;
       98   limitlasttime = t;
       99   
      100   if(!limitavg) {
      101     limitavg = timetaken;
      102   } else {
      103     limitavg = (DWORD)((1 - ALPHA) * (double)limitavg + (ALPHA) * (double)timetaken);
      104   }
      105   delta = rate - limitavg;
      106   if(delta > 10)
      107     Sleep(delta);
      108 
      109   t+=delta;
      110   
      111   while(GetTickCount() < t)
      112     ;
      113     
      114   return lastfps;
      115 }
      116 
      117 static HRESULT STDMETHODCALLTYPE FixedUnlock(IDirectDrawSurface *p, LPVOID a) {
      118   LimitRate(RATE); 
      119 
      120   return TrueUnlock(p, a);
      121 }
      122 
      123 static HRESULT STDMETHODCALLTYPE FixedCreateSurface(void *p, LPDDSURFACEDESC a, LPDIRECTDRAWSURFACE *b, IUnknown *c) {
      124   IDirectDrawSurface *psurf;
      125   HRESULT ret = TrueCreateSurface(p, a, b, c);
      126   
      127   if(ret != DD_OK)
      128     return ret;
      129 
      130   psurf = *b;
      131   
      132   if(psurf->lpVtbl->Unlock != FixedUnlock)
      133     TrueUnlock = psurf->lpVtbl->Unlock;
      134   psurf->lpVtbl->Unlock = FixedUnlock;
      135   
      136   return ret;
      137 }
      138 
      139 static HRESULT WINAPI FixedDirectDrawCreate(GUID *lpGUID, LPDIRECTDRAW *lplpDD, IUnknown *pUnkOuter) {
      140   IDirectDraw *pdd;
      141   HRESULT ret = TrueDirectDrawCreate(lpGUID, lplpDD, pUnkOuter);
      142   
      143   if(ret != DD_OK)
      144     return ret;
      145   
      146   pdd = *lplpDD;
      147   
      148   if(pdd->lpVtbl->CreateSurface != FixedCreateSurface)
      149     TrueCreateSurface = pdd->lpVtbl->CreateSurface;
      150   pdd->lpVtbl->CreateSurface = FixedCreateSurface;
      151   
      152   return ret;
      153 }
      154 
      155 static hunk hstartup[] = {
      156   { HUNK_FUNC, (void *)&FixedBitBlt, (void *)&TrueBitBlt, },
      157 };
      158 
      159 static hunk hmechlab[] = {
      160   { HUNK_FUNC, (void *)&FixedFindFirstFileA, (void *)&TrueFindFirstFileA },
      161   { HUNK_FUNC, (void *)&FixedFindNextFileA, (void *)&TrueFindNextFileA },
      162   { HUNK_FUNC, (void *)&FixedFindClose, (void *)&TrueFindClose },
      163 };
      164 
      165 static hunk hheaphack[] = {
      166   { HUNK_FUNC, (void *)&FixedHeapFree, (void *)&TrueHeapFree },
      167 };
      168 
      169 static hunk hframerate[] = {
      170   { HUNK_NAME, (void *)&FixedDirectDrawCreate, NULL, "ddraw.dll", "DirectDrawCreate", &TrueDirectDrawCreate },
      171 };
      172 
      173 int patchcount = 4;
      174 
      175 patch patches[] = { 
      176   { "startup", "Fixes startup termination", 1, hstartup },
      177   { "mechlab", "Fixes Mech Lab overweight issue", 3, hmechlab },
      178   { "heaphack", "Fixes a lot of random crashes but will increase memory usage.", 1, hheaphack },
      179   { "frameratelimit", "Fixes jumpjet and missile problems", 1, hframerate },
      180 };