设为主页 | 加入收藏 | 繁體中文

一个游戏的汉化实例


  wc.style = 0;
  wc.lpfnWndProc = WinProc;
  wc.cbClsExtra = 0;
  wc.cbWndExtra = 0;
  wc.hInstance = hInstance;
  wc.hIcon = LoadIcon (hInstance, IDI_APPLICATION);
  wc.hCursor = LoadCursor (NULL, IDC_ARROW);
  wc.hbrBackground = (HBRUSH) GetStockObject (BLACK_BRUSH);
  wc.lpszMenuName = NULL;
  wc.lpszClassName = "dxHello";
  //注册窗口类
  RegisterClass (&wc);
  //创立主窗口
  hwnd = CreateWindowEx (0, "dxHello", "", WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | WS_OVERLAPPED, 0, 0, MAXWIDTH + (GSM_CXBORDER << 1),      //注意这里
  MAXHEIGHT + GSM_CAPTION + (GSM_CYBORDER << 1), //注意这里
  NULL, NULL, hInstance, NULL);
  if (!hwnd)
  return FALSE;
  ShowWindow (hwnd, nCmdShow);
  UpdateWindow (hwnd);
  return TRUE;
  }
  //--------------------------------------------------
  //函数:WinProc()
  //功效:处置惩罚主窗口消息
  //--------------------------------------------------
  LRESULT CALLBACK
  WinProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
  {
  switch (message)
  {
  case WM_ACTIVATEAPP:
  bActive = wParam;
  break;
  case WM_KEYDOWN:           //击键消息
  switch (wParam)
  {
  case VK_ESCAPE:
  PostMessage (hWnd, WM_CLOSE, 0, 0);
  break;
  }
  break;
  case WM_SETCURSOR:
  SetCursor (NULL);
  return TRUE;
  case WM_DESTROY:           //加入消息
  FreeDDraw ();
  DeleteObject (hfont);
  PostQuitMessage (0);
  break;
  }
  //调用缺省消息处置惩罚历程
  return DefWindowProc (hWnd, message, wParam, lParam);
  }
  //----------------------------------------------------------------
  //函数: InitDDraw()
  //功效: 初始化DirectDraw环境并完成其功效.包括:创立DirectDraw对象,
  //设置显示形式,创立主表面
  //----------------------------------------------------------------
  bool
  InitDDraw (void)
  {
  DDSURFACEDESC2 ddsd;          //表面形貌
  //创立DirectDraw对象
  if (DirectDrawCreateEx (NULL, (void **) &lpDD, IID_IDirectDraw7, NULL) !=
  DD_OK)
  return FALSE;
  //设置窗口形式
  if (lpDD->SetCooperativeLevel (hwnd, DDSCL_NORMAL) != DD_OK)
  return FALSE;
  //添补主表面信息
  ZeroMemory (&ddsd, sizeof (ddsd));
  ddsd.dwSize = sizeof (ddsd);
  ddsd.dwFlags = DDSD_CAPS;     // | DDSD_BACKBUFFERCOUNT;
  ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; // | DDSCAPS_FLIP | DDSCAPS_COMPLEX;
  //创立主表面临象
  if (lpDD->CreateSurface (&ddsd, &lpDDSPrimary, NULL) != DD_OK)
  return FALSE;
  LPDIRECTDRAWCLIPPER lpclip;
  lpDD->CreateClipper (NULL, &lpclip, NULL);
  lpDDSPrimary->SetClipper (lpclip);
  lpclip->SetHWnd (NULL, hwnd);
  lpclip->Release ();
  ZeroMemory (&ddsd, sizeof (ddsd));
  ddsd.dwSize = sizeof (ddsd);
  ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
  ddsd.ddsCaps.dwCaps =
  DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM;
  ddsd.dwWidth = MAXWIDTH;
  ddsd.dwHeight = MAXHEIGHT;
  //创立后表面临象
  if (lpDD->CreateSurface (&ddsd, &lpDDSBack, NULL) != DD_OK)
  return FALSE;
  return TRUE;
  }
  //-------------------------------------------------------
  //函数:FreeDDraw()
  //功效:开释全部的DirectDraw对象
  //-------------------------------------------------------
  void
  FreeDDraw (void)
  {
  if (lpDD != NULL)
  {
  if (lpDDSPrimary != NULL)
  {
  lpDDSPrimary->Release ();
  lpDDSPrimary = NULL;
  }
  lpDD->Release ();
  lpDD = NULL;
  }
  }
  void
  _TextOut (int x, int y, char *string, COLORREF color)
  {
  HDC hdc;
  if (lpDDSBack->GetDC (&hdc) == DD_OK)
  {
  SelectObject (hdc, hfont);
  SetBkMode (hdc, TRANSPARENT);
  SetTextColor (hdc, color);
  TextOut (hdc, x, y, string, lstrlen (string));
  lpDDSBack->ReleaseDC (hdc);
  }
  }
  //-------------------------------------------------------
  //函数:MainLoop()
  //功效:游戏主循环
  //-------------------------------------------------------
  void
  MainLoop (void)
  {
  //后台缓冲表面上的操纵
  HDC hdc;
  RECT rect;                    //这个是主表面的地区
  RECT rectback = { 0, 0, MAXWIDTH, MAXHEIGHT};;                //这个是次表面的地区
  if (lpDDSBack->GetDC (&hdc) == DD_OK)
  {
  //清屏                  
  GetWindowRect (hwnd, &rect);      //取得整个窗口地区
  rect.left += GSM_CXBORDER;        //修正到主表面地区
  rect.top += GSM_CAPTION + GSM_CYBORDER;
  rect.right -= GSM_CXBORDER;
  rect.bottom -= GSM_CYBORDER;
  FillRect (hdc, &rectback, (HBRUSH) GetStockObject (BLACK_BRUSH));
  lpDDSBack->ReleaseDC (hdc);
  }
  _TextOut (220, 200, szMsg1, RGB (0xf0, 0xf0, 0xf0));
  _TextOut (220, 220, szMsg2, RGB (0, 255, 0));
  lpDDSPrimary->Blt (&rect, lpDDSBack, &rectback, DDBLT_WAIT, NULL);
  }
  --------------------------------------------------------------------------------
  编译后,把_TextOut的汇编代码植入游戏(可用ODBG的二进制复制粘贴功效),并修改相关的api调用。
  其中int x, int y, char *string, COLORREF color,lpDDSBack都已经阐发出,而hfont需要在游戏开
  始时用CreateFontA创立,偷偷生存在数据段的末尾,竣事前用DeleteObject析构。
  代码:-------------------------------------------------------------------------------- 
  04634300    51                     push ecx                                     ; _TextOut
  04634301    A1 54840F04            mov eax,dword ptr ds:[40F8454]
  04634306    8B08                   mov ecx,dword ptr ds:[eax]
  04634308    8D1424                 lea edx,dword ptr ss:[esp]
  0463430B    52                     push edx
  0463430C    50                     push eax
  0463430D    FF51 44                call dword ptr ds:[ecx+44]                   ; BackSurface->GetDC
  04634310    85C0                   test eax,eax
  04634312    75 61                  jnz short war_in_t.04634375
  04634314    A1 FC1F6204            mov eax,dword ptr ds:[4621FFC]               ; hfont
  04634319    8B0C24                 mov ecx,dword ptr ss:[esp]
  0463431C    56                     push esi
  0463431D    50                     push eax
  0463431E    51                     push ecx
  0463431F    FF15 34105B00          call dword ptr ds:[<&GDI32.SelectObject>]    ; GDI32.SelectObject
  04634325    8B5424 04              mov edx,dword ptr ss:[esp+4]
  04634329    6A 01                  push 1
  0463432B    52                     push edx
  0463432C    FF15 E4806304          call dword ptr ds:[<&GDI32.SetBkMode>]       ; GDI32.SetBkMode
  04634332    8B4424 18              mov eax,dword ptr ss:[esp+18]
  04634336    8B4C24 04              mov ecx,dword ptr ss:[esp+4]
  0463433A    50                     push eax
  0463433B    51                     push ecx
  0463433C    FF15 4C105B00          call dword ptr ds:[<&GDI32.SetTextColor>]    ; GDI32.SetTextColor
  04634342    8B7424 14              mov esi,dword ptr ss:[esp+14]
  04634346    56                     push esi
  04634347    FF15 2C115B00          call dword ptr ds:[<&KERNEL32.lstrlenA>]     ; KERNEL32.lstrlenA
  0463434D    8B5424 10              mov edx,dword ptr ss:[esp+10]
  04634351    8B4C24 04              mov ecx,dword ptr ss:[esp+4]
  04634355    50                     push eax
  04634356    8B4424 10              mov eax,dword ptr ss:[esp+10]
  0463435A    56                     push esi
  0463435B    52                     push edx
  0463435C    50                     push eax
  0463435D    51                     push ecx
  0463435E    FF15 50105B00          call dword ptr ds:[<&GDI32.TextOutA>]        ; GDI32.TextOutA
  04634364    8B4C24 04              mov ecx,dword ptr ss:[esp+4]
  04634368    A1 54840F04            mov eax,dword ptr ds:[40F8454]
  0463436D    8B10                   mov edx,dword ptr ds:[eax]
  0463436F    51                     push ecx
  04634370    50                     push eax
  04634371    FF52 68                call dword ptr ds:[edx+68]                   ; BackSurface->ReleaseDC
  04634374    5E                     pop esi
  04634375    59                     pop ecx
  04634376    C3                     retn
  --------------------------------------------------------------------------------
  然后修改原来的字符串输出函数:
  代码:-------------------------------------------------------------------------------- 
  0057E5E0    - E9 9B5A0B04          jmp war_in_t.04634080                        ; 原: mov eax, dword ptr ds:[4605D10]
  --------------------------------------------------------------------------------
  跳到这里,调用我们本身的_TextOut:
  代码:-------------------------------------------------------------------------------- 
  04634080    8B0D 080B0E04          mov ecx,dword ptr ds:[40E0B08]
  04634086    FF71 10                push dword ptr ds:[ecx+10]                   ; 颜色
  04634089    FF7424 10              push dword ptr ss:[esp+10]                   ; 字符串
  0463408D    FF7424 10              push dword ptr ss:[esp+10]                   ; y
  04634091    FF7424 10              push dword ptr ss:[esp+10]                   ; x
  04634095    E8 66020000            call war_in_t.04634300                       ; _TextOut
  0463409A    83C4 10                add esp,10
  0463409D    C3                     retn
  --------------------------------------------------------------------------------
  至此,游戏已能正常显示中文。
 


    文章作者: 福州军威计算机技术有限公司
    军威网络是福州最专业的电脑维修公司,专业承接福州电脑维修、上门维修、IT外包、企业电脑包年维护、局域网网络布线、网吧承包等相关维修服务。
    版权声明:原创作品,允许转载,转载时请务必以超链接形式标明文章原始出处 、作者信息和声明。否则将追究法律责任。

TAG:
评论加载中...
内容:
评论者: 验证码: