diff Render.cpp @ 2069:259df09dfb50

32bits almost there
author Nomad
date Tue, 03 Dec 2013 20:18:17 +0200
parents b2a434d65344
children 38bf1c70fc70
line wrap: on
line diff
--- a/Render.cpp	Mon Dec 02 15:13:49 2013 +0200
+++ b/Render.cpp	Tue Dec 03 20:18:17 2013 +0200
@@ -87,7 +87,7 @@
 signed int __stdcall RenderD3D__DeviceEnumerator(GUID *lpGUID, const char *lpDevDesc, const char *lpDriverName, RenderD3D__DevInfo *pOut); // idb
 
 //----- (0049E79F) --------------------------------------------------------
-bool  CheckTextureStages()
+bool CheckTextureStages()
 {
   bool v0; // edi@1
   IDirectDrawSurface4 *pSurface2; // [sp+Ch] [bp-14h]@1
@@ -1206,7 +1206,7 @@
 {
   HRESULT v2; // esi@2
 
-  if ( Src->dwFlags & 0x400 | 0x2000 )
+  if ( Src->dwFlags & (0x400 | 0x2000))
   {
     v2 = 0;
     if ( Src->dwRGBBitCount == 16 && !Src->dwRBitMask )
@@ -1375,7 +1375,7 @@
 }
 
 //----- (0049DE14) --------------------------------------------------------
-bool RenderD3D::CreateDevice(unsigned int uDeviceID, int bWindowed, HWND hWnd)
+bool RenderD3D::CreateDevice(unsigned int uDeviceID, int bWindowed, OSWindow *window)
 {
   //IDirectDraw4 *v8; // eax@12
   //IDirectDraw4 *v9; // eax@16
@@ -1391,6 +1391,10 @@
   IDirectDrawClipper *v30; // [sp+C4h] [bp-14h]@18
   LPDIRECTDRAW lpDD; // [sp+C8h] [bp-10h]@1
 
+  auto hWnd = window->GetApiHandle();
+  int game_width = window->GetWidth();
+  int game_height = window->GetHeight();
+
   this->bWindowed = bWindowed;
   this->hWindow = hWnd;
 
@@ -1432,7 +1436,7 @@
     {
       ddsd2.dwSize = sizeof(DDSURFACEDESC2);
       pHost->GetDisplayMode(&ddsd2);
-      if ( ddsd2.ddpfPixelFormat.dwRGBBitCount != 16 )
+      if ( FORCE_16_BITS && ddsd2.ddpfPixelFormat.dwRGBBitCount != 16 )
       {
         v24 = "Init - Desktop isn't in 16 bit mode.\n";
         goto LABEL_14;
@@ -1440,8 +1444,8 @@
 
       ddsd2.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
       ddsd2.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE;
-      ddsd2.dwWidth = 640;
-      ddsd2.dwHeight = 480;
+      ddsd2.dwWidth = game_width;
+      ddsd2.dwHeight = game_height;
       if (pHost->CreateSurface(&ddsd2, &pBackBuffer, 0) )
       {
         v24 = "Init - Failed to create back buffer.\n";
@@ -1469,8 +1473,8 @@
 
       ddsd2.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
       ddsd2.ddsCaps.dwCaps = DDSCAPS_ZBUFFER;
-      ddsd2.dwWidth = 640;
-      ddsd2.dwHeight = 480;
+      ddsd2.dwWidth = game_width;
+      ddsd2.dwHeight = game_height;
 
       if ( pDirect3D->EnumZBufferFormats(*pAvailableDevices[uDeviceID].pGUID,
              (HRESULT (__stdcall *)(DDPIXELFORMAT *, void *))D3DZBufferFormatEnumerator,
@@ -1610,8 +1614,8 @@
 LABEL_54:
   d3dvp2.dwSize = sizeof(D3DVIEWPORT2);
   //v17 = *hWnda;
-  d3dvp2.dwWidth = 640;
-  d3dvp2.dwHeight = 480;
+  d3dvp2.dwWidth = game_width;
+  d3dvp2.dwHeight = game_height;
   d3dvp2.dvClipX = -1.0;
   //v18 = v17->lpVtbl;
   //v32 = &v4->pViewport;
@@ -2106,14 +2110,14 @@
   v1->pRenderD3D = 0;
   v1->uNumSceneBegins = 0;
   v1->uNumD3DSceneBegins = 0;
-  v1->field_40110 = 0;
+  v1->using_software_screen_buffer = 0;
   v1->pTargetSurface = 0;
   v1->uTargetSurfacePitch = 0;
   v1->uClipY = 0;
   v1->uClipX = 0;
   v1->uClipW = 480;
   v1->bClip = 1;
-  v1->bColorKeySupported = 0;
+  //v1->bColorKeySupported = 0;
   v1->bRequiredTextureStagesAvailable = 0;
   v1->bTinting = 1;
   LOBYTE(v1->field_103668) = 0;
@@ -2127,12 +2131,12 @@
   sub_4A19B0();
 }
 
-bool Render::Initialize(bool bWindowed, OSWindow *window, bool bColoredLights, uint32_t uDetailLevel, bool bTinting)
+bool Render::Initialize(OSWindow *window, bool bColoredLights, uint32_t uDetailLevel, bool bTinting)
 {
   //bUserDirect3D = true;//ReadWindowsRegistryInt("Use D3D", 0);
 
   this->window = window;
-  bStartInWindow = bWindowed;
+  //bStartInWindow = true;
   //windowed_mode_width = windowed_width;
   //windowed_mode_height = windowed_height;
 
@@ -2149,62 +2153,13 @@
   return r1 && r2;
 }
 
-//----- (0049EBF1) --------------------------------------------------------
-void Render::_49EBF1()
-{
-  signed int uNumRedBits; // edx@1
-  signed int uNuGreenBits; // edi@1
-  signed int uNumBlueBits; // esi@1
-  unsigned int v4; // edx@4
-  unsigned int v5; // edi@4
-  int v6; // ebx@4
-  int v7; // edx@4
-  signed int v8; // [sp+8h] [bp-24h]@1
-  signed int v9; // [sp+Ch] [bp-20h]@1
-  signed int v10; // [sp+20h] [bp-Ch]@1
-  signed int i; // [sp+24h] [bp-8h]@2
-  signed int v12; // [sp+28h] [bp-4h]@3
-
-  v10 = 0;
-  uNumRedBits = 1 << this->uTargetRBits;
-  uNuGreenBits = 1 << this->uTargetGBits;
-  uNumBlueBits = 1 << this->uTargetBBits;
-  v9 = 1 << this->uTargetRBits;
-  v8 = 1 << this->uTargetGBits;
-  if ( uNumRedBits > 0 )
-  {
-    do
-    {
-      for ( i = 0; i < uNuGreenBits; ++i )
-      {
-        v12 = 0;
-        if ( uNumBlueBits > 0 )
-        {
-          do
-          {
-            v4 = this->uTargetBBits;
-            v5 = v4 + this->uTargetGBits;
-            v6 = (v12 >> 1) + (v10 >> 1 << v5) + (i >> 1 << this->uTargetBBits);
-            v7 = (v10 << v5) + v12++ + (i << v4);
-            this->field_2C[v7] = v6;
-          }
-          while ( v12 < uNumBlueBits );
-          uNumRedBits = v9;
-          uNuGreenBits = v8;
-        }
-      }
-      ++v10;
-    }
-    while ( v10 < uNumRedBits );
-  }
-}
 
 //----- (0049ECC4) --------------------------------------------------------
 void Render::ClearBlack()
 {
   if (pRenderD3D)
   {
-    if (field_40110)
+    if (using_software_screen_buffer)
       pRenderD3D->ClearTarget(true, 0, false, 0.0);
   }
   else
@@ -2275,7 +2230,7 @@
 
   v1 = this;
   v2 = 0;
-  if ( !this->pRenderD3D || this->field_40110 )
+  if ( !this->pRenderD3D || this->using_software_screen_buffer )
   {
     sprintf(Filename, "screen%0.2i.pcx", dword_4EFA80++ % 100);
     File = fopen(Filename, "wb");
@@ -2420,7 +2375,7 @@
 // 4EFA80: using guessed type int dword_4EFA80;
 
 //----- (0049F1BC) --------------------------------------------------------
-void Render::_49F1BC(const char *a1)
+void Render::SaveWinnersCertificate(const char *a1)
 {
   Render *v2; // esi@1
   __int16 v3; // di@1
@@ -2470,7 +2425,7 @@
 
   v2 = this;
   v3 = 0;
-  if ( !this->pRenderD3D || this->field_40110 )
+  if ( !this->pRenderD3D || this->using_software_screen_buffer )
   {
     ++dword_4EFA84;
     File = fopen(a1, "wb");
@@ -2498,7 +2453,7 @@
       else
       {
         pRenderer->BeginScene();
-        v42 = pRenderer->pTargetSurface;
+        //v42 = pRenderer->pTargetSurface;
         v6 = pRenderer->uTargetSurfacePitch;
       }
       i = (char *)v6;
@@ -2909,7 +2864,7 @@
 {
   if (pRenderD3D)
   {
-    if (field_40110)
+    if (using_software_screen_buffer)
       pRenderD3D->ClearTarget(true, uColor, false, 0.0);
   }
   else
@@ -2932,12 +2887,12 @@
   struct tagPOINT Point; // [sp+28h] [bp-8h]@11
 
   v1 = this;
-  if ( !pRenderer->pRenderD3D || this->field_40110 )
+  if ( !pRenderer->pRenderD3D || this->using_software_screen_buffer )
   {
     this->pBeforePresentFunction();
     if ( v1->pRenderD3D )
     {
-      if ( v1->field_40110 )
+      if ( v1->using_software_screen_buffer )
       {
         pRenderD3D->Present(false);
       }
@@ -3031,7 +2986,7 @@
   v1 = this;
   if (pRenderD3D)
   {
-    if ( v1->field_40110 )
+    if ( v1->using_software_screen_buffer )
     {
       pRenderD3D->ClearTarget(true, 0, false, 1.0);
       pRenderD3D->Present(0);
@@ -3043,9 +2998,9 @@
     v1->pDirectDraw4 = 0;
     if (v1->pTargetSurface)
     {
-      free(v1->ptr_400E8);
+      delete [] v1->pTargetSurface_unaligned;
       v1->pTargetSurface = 0;
-      v1->ptr_400E8 = 0;
+      v1->pTargetSurface_unaligned = 0;
     }
     if (pRenderD3D)
     {
@@ -3155,11 +3110,11 @@
   int v13; // ecx@25
   int v14; // eax@27
   signed int v15; // ebx@31
-  bool v16; // eax@35
-  char v17; // zf@35
+  //bool v16; // eax@35
+  //char v17; // zf@35
   IDirectDraw4 *v18; // eax@38
   HRESULT v19; // eax@38
-  int *v20; // eax@39
+  //int *v20; // eax@39
   int *v22; // eax@42
   int v23; // ecx@42
   D3DDEVICEDESC refCaps; // [sp+Ch] [bp-300h]@25
@@ -3169,13 +3124,15 @@
   void *v28; // [sp+2FCh] [bp-10h]@2
   int v29; // [sp+308h] [bp-4h]@2
 
+  __debugbreak(); // Nomad
+
   //v2 = this;
-  this->field_40110 = 0;
+  this->using_software_screen_buffer = 0;
   this->pColorKeySurface4 = 0;
   this->pBackBuffer4 = 0;
   this->pFrontBuffer4 = 0;
   this->pDirectDraw4 = 0;
-  this->bColorKeySupported = 0;
+  //this->bColorKeySupported = 0;
   Release();
   //v3 = hWnd;
   this->window = window;
@@ -3198,14 +3155,14 @@
     v7 = pRenderD3D->pAvailableDevices;
     if ( v7[v6].bIsDeviceCompatible )
     {
-      v8 = pRenderD3D->CreateDevice(v6, 0, window->GetApiHandle());
+      v8 = pRenderD3D->CreateDevice(v6, /*0*/true, window);
       uAcquiredDirect3DDevice = uDesiredDirect3DDevice;
     }
     else
     {
       if ( v7[1].bIsDeviceCompatible )
       {
-        v8 = pRenderD3D->CreateDevice(1u, 0, window->GetApiHandle());
+        v8 = pRenderD3D->CreateDevice(1, /*0*/true, window);
         uAcquiredDirect3DDevice = 1;
       }
       else
@@ -3213,7 +3170,7 @@
         if ( !v7->bIsDeviceCompatible )
           Error("There aren't any D3D devices to create.");
 
-        v8 = pRenderD3D->CreateDevice(0, 0, window->GetApiHandle());
+        v8 = pRenderD3D->CreateDevice(0, /*0*/true, window);
         uAcquiredDirect3DDevice = 1;
       }
     }
@@ -3302,13 +3259,18 @@
     ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_COLORARG2, 0));
     ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_COLOROP, 4u));
   //}
-  ddpfPrimareSuface.dwSize = 32;
-  GetTargetPixelFormat(&ddpfPrimareSuface);
+  ddpfPrimarySuface.dwSize = 32;
+  GetTargetPixelFormat(&ddpfPrimarySuface);
   ParseTargetPixelFormat();
-  _49EBF1();
-  if ( pRenderD3D )
-  {
-    v16 = IsColorKeySupported(pDirectDraw4);
+
+  if (!pRenderD3D)
+  {
+    __debugbreak();
+    pBeforePresentFunction = 0;//nullsub_1;
+  }
+  //else
+  //{
+    /*v16 = IsColorKeySupported(pDirectDraw4);
     v17 = uAcquiredDirect3DDevice == v15;
     bColorKeySupported = v16;
     if ( !v17 )
@@ -3327,35 +3289,30 @@
       ErrD3D(v18->CreateSurface(&ddsd2, &pColorKeySurface4, 0));
       pBeforePresentFunction = Present_ColorKey;
     }
-    else
+    else*/
     {
       pTargetSurface = 0;
-      ptr_400E8 = 0;
-      v20 = (int *)malloc(0x96020u);
-      ptr_400E8 = v20;
-      if ( !v20
+      pTargetSurface_unaligned = 0;
+      pTargetSurface_unaligned = (unsigned int *)malloc(640 * 480 * 2 + 32);
+      if ( !pTargetSurface_unaligned
         || (memset(&pDesc, 0, 0x7Cu),
             pDesc.dwSize = 124,
             !pRenderer->LockSurface_DDraw4(pRenderer->pBackBuffer4, &pDesc, v15)) )
         return 0;
       pBackBuffer4->Unlock(0);
-      v22 = ptr_400E8 + 4;
+      v22 = (int *)pTargetSurface_unaligned + 4;
       v23 = (unsigned int)pDesc.lpSurface & 7;
       LOBYTE(v22) = (unsigned __int8)v22 & 0xF8;
       uTargetSurfacePitch = 640;
       pBeforePresentFunction = Present_NoColorKey;
       v15 = 1;
-      pTargetSurface = (unsigned __int16 *)((char *)v22 + 2 * v23);
-    }
-    field_40110 = v15;
-  }
-  else
-  {
-    pBeforePresentFunction = 0;//nullsub_1;
-  }
+      pTargetSurface = (unsigned __int32 *)((char *)v22 + 2 * v23);
+    }
+    using_software_screen_buffer = v15;
+  //}
   bWindowMode = 0;
   pParty->uFlags |= 2u;
-  LODWORD(flt_6BE3A0) = 0x3F0CCCCDu;  __debugbreak(); // replace with actual float
+  flt_6BE3A0 = 0.55000001f;
   pViewport->_4C02F8(36044);
   return v15 != 0;
 }
@@ -3375,11 +3332,11 @@
   HRESULT v11; // eax@24
   int v12; // eax@24
   int v13; // eax@26
-  bool v14; // eax@32
-  char v15; // zf@32
+  //bool v14; // eax@32
+  //char v15; // zf@32
   IDirectDraw4 *v16; // eax@35
   HRESULT v17; // eax@35
-  int *v18; // eax@36
+  //int *v18; // eax@36
   int *v19; // edx@38
   int v20; // eax@38
   unsigned int v21; // ecx@38
@@ -3391,17 +3348,17 @@
   //RenderD3D *thisa; // [sp+2FCh] [bp-10h]@2
   int v29; // [sp+308h] [bp-4h]@2
 
-  pParty->uFlags |= 2u;
+  pParty->uFlags |= PARTY_FLAGS_1_0002;
   //v2 = this;
   flt_6BE3A0 = 0.55000001f;
   pViewport->_4C02F8(36044);
-  field_40110 = 0;
+  using_software_screen_buffer = 0;
   Release();
   pColorKeySurface4 = 0;
   pBackBuffer4 = 0;
   pFrontBuffer4 = 0;
   pDirectDraw4 = 0;
-  bColorKeySupported = 0;
+  //bColorKeySupported = 0;
   CreateZBuffer();
   /*if (!bUserDirect3D)
   {
@@ -3431,7 +3388,7 @@
     if (pRenderD3D->pAvailableDevices[uDesiredDirect3DDevice].bIsDeviceCompatible &&
         uDesiredDirect3DDevice != 1 )
     {
-      v7 = pRenderD3D->CreateDevice(uDesiredDirect3DDevice, 1, window->GetApiHandle());
+      v7 = pRenderD3D->CreateDevice(uDesiredDirect3DDevice, true, window);
       uAcquiredDirect3DDevice = uDesiredDirect3DDevice;
     }
     else
@@ -3439,7 +3396,7 @@
       if ( !pRenderD3D->pAvailableDevices[0].bIsDeviceCompatible )
         Error("There aren't any D3D devices to init.");
 
-      v7 = pRenderD3D->CreateDevice(0, 1, window->GetApiHandle());
+      v7 = pRenderD3D->CreateDevice(0, true, window);
       uAcquiredDirect3DDevice = 0;
     }
     if ( !v7 )
@@ -3500,7 +3457,7 @@
     refCaps.dwSize = 252;
     ErrD3D(pRenderD3D->pDevice->GetCaps(&halCaps, &refCaps));
     v12 = halCaps.dwMinTextureWidth;
-    if ( (unsigned int)halCaps.dwMinTextureWidth >= halCaps.dwMinTextureHeight )
+    if ( (unsigned int)halCaps.dwMinTextureWidth > halCaps.dwMinTextureHeight )
       v12 = halCaps.dwMinTextureHeight;
     uMinDeviceTextureDim = v12;
     v13 = halCaps.dwMaxTextureWidth;
@@ -3525,23 +3482,25 @@
     ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_COLOROP, 4u));
   //}
 
-  ddpfPrimareSuface.dwSize = 32;
-  GetTargetPixelFormat(&ddpfPrimareSuface);
+  ddpfPrimarySuface.dwSize = 32;
+  GetTargetPixelFormat(&ddpfPrimarySuface);
   ParseTargetPixelFormat();
-  _49EBF1();
+
   if ( !pRenderD3D )
   {
-    pBeforePresentFunction = 0;//nullsub_1;
-    goto LABEL_47;
-  }
-  v14 = IsColorKeySupported(pDirectDraw4);
+    __debugbreak();
+    //pBeforePresentFunction = 0;//nullsub_1;
+    //goto LABEL_47;
+  }
+  /*v14 = IsColorKeySupported(pDirectDraw4);
   v15 = uAcquiredDirect3DDevice == 1;
   bColorKeySupported = v14;
   if ( !v15 )
-    bColorKeySupported = 0;
-  if ( bColorKeySupported )
-  {
-    memset(&ddsd2, 0, 0x7Cu);
+    bColorKeySupported = 0;*/
+  //if ( bColorKeySupported )
+  if (false)
+  {
+    /*memset(&ddsd2, 0, 0x7Cu);
     ddsd2.ddckCKSrcBlt.dwColorSpaceLowValue = uTargetGMask | uTargetBMask;
     ddsd2.ddckCKSrcBlt.dwColorSpaceHighValue = ddsd2.ddckCKSrcBlt.dwColorSpaceLowValue;
     v16 = pDirectDraw4;
@@ -3551,27 +3510,36 @@
     ddsd2.dwWidth = 640;
     ddsd2.dwHeight = 480;
     ErrD3D(v16->CreateSurface(&ddsd2, &pColorKeySurface4, 0));
-    pBeforePresentFunction = Present_ColorKey;
+    pBeforePresentFunction = Present_ColorKey;*/
 LABEL_45:
-    field_40110 = 1;
-LABEL_47:
+    using_software_screen_buffer = 1;
+//LABEL_47:
     bWindowMode = 1;
     //hWnd = hWnd;
     return 0;
   }
   pTargetSurface = 0;
-  ptr_400E8 = 0;
-  v18 = (int *)new char[0x96020];
-  memset(v18, -1, 0x96020);
-  ptr_400E8 = v18;
-  if ( v18 )
-  {
-    memset(&pDesc, 0, 0x7Cu);
-    pDesc.dwSize = 124;
-    if ( pRenderer->LockSurface_DDraw4(pRenderer->pBackBuffer4, &pDesc, DDLOCK_WAIT) )
-    {
+  pTargetSurface_unaligned = 0;
+
+  uint num_pixels = window->GetWidth() * window->GetHeight();
+  pTargetSurface_unaligned = new unsigned int[num_pixels];
+
+  if (!pTargetSurface_unaligned)
+    return false;
+
+  memset(&pDesc, 0, 0x7Cu);
+  pDesc.dwSize = 124;
+  if (!pRenderer->LockSurface_DDraw4(pRenderer->pBackBuffer4, &pDesc, DDLOCK_WAIT))
+  {
+    delete [] pTargetSurface_unaligned;
+    return false;
+  }
+
+  memset32(pTargetSurface_unaligned, -1, num_pixels);
+
+
       pRenderer->pBackBuffer4->Unlock(0);
-      v19 = ptr_400E8;
+      /*v19 = pTargetSurface_unaligned;
       v20 = (unsigned int)pDesc.lpSurface & 7;
       v21 = (unsigned int)ptr_400E8 & 7;
       if ( v21 == v20 )
@@ -3585,13 +3553,11 @@
         else
           v22 = (int)((char *)v19 + 2 * (v20 - v21) + 16);
         pTargetSurface = (unsigned __int16 *)v22;
-      }
-      uTargetSurfacePitch = 640;
+      }*/
+      pTargetSurface = pTargetSurface_unaligned;
+      uTargetSurfacePitch = window->GetWidth();
       pBeforePresentFunction = Present_NoColorKey;
       goto LABEL_45;
-    }
-  }
-  return 0;
 }
 
 //----- (004A0BEE) --------------------------------------------------------
@@ -3688,7 +3654,9 @@
         v24 = -1;
       }
       v25 = 0;
-      v26 = v35->pTargetSurface;
+
+      __debugbreak(); //target sruface will most likely be 32bits/pixel, but this sub awaits 16 bits
+      v26 = (unsigned __int16 *)v35->pTargetSurface;
       if ( v26 )
       {
         if ( (signed int)uXa <= v23 )
@@ -3852,11 +3820,11 @@
   signed int v5; // ecx@5
   unsigned int uBlueMask; // edx@9
   signed int v7; // ecx@9
-  unsigned int v8; // ecx@13
+  //unsigned int v8; // ecx@13
 
   v1 = this;
   v2 = 0;
-  uRedMask = v1->ddpfPrimareSuface.dwRBitMask;
+  uRedMask = v1->ddpfPrimarySuface.dwRBitMask;
   v1->uTargetBBits = 0;
   v1->uTargetGBits = 0;
   v1->uTargetRBits = 0;
@@ -3866,8 +3834,8 @@
       ++v1->uTargetRBits;
     ++v2;
   }
-  while ( v2 < 16 );
-  uGreenMask = v1->ddpfPrimareSuface.dwGBitMask;
+  while ( v2 < 32 );
+  uGreenMask = v1->ddpfPrimarySuface.dwGBitMask;
   v5 = 0;
   do
   {
@@ -3875,8 +3843,8 @@
       ++v1->uTargetGBits;
     ++v5;
   }
-  while ( v5 < 16 );
-  uBlueMask = v1->ddpfPrimareSuface.dwBBitMask;
+  while ( v5 < 32 );
+  uBlueMask = v1->ddpfPrimarySuface.dwBBitMask;
   v7 = 0;
   do
   {
@@ -3884,10 +3852,9 @@
       ++v1->uTargetBBits;
     ++v7;
   }
-  while ( v7 < 16 );
-  v8 = v1->ddpfPrimareSuface.dwRBitMask;
+  while ( v7 < 32 );
   v1->uTargetGMask = uGreenMask;
-  v1->uTargetRMask = v8;
+  v1->uTargetRMask = v1->ddpfPrimarySuface.dwRBitMask;
   v1->uTargetBMask = uBlueMask;
 }
 
@@ -6155,62 +6122,6 @@
     pBillboardRenderListD3D[v8].uOpacity = RenderBillboardD3D::Transparent;
 }
 
-//----- (004A48E4) --------------------------------------------------------
-int Render::MakeParticleBillboardAndPush_BLV_Software(int screenSpaceX, int screenSpaceY, int z, int lightColor, int a6)
-{
-  int v6; // ecx@1
-  int v7; // ebx@1
-  int v8; // ecx@1
-  int v9; // edx@1
-  int v10; // edi@1
-  unsigned int x; // esi@1
-  int result; // eax@8
-  int v13; // [sp+Ch] [bp-10h]@1
-  int v14; // [sp+10h] [bp-Ch]@1
-  int v15; // [sp+14h] [bp-8h]@1
-  int v16; // [sp+18h] [bp-4h]@1
-  int v17; // [sp+24h] [bp+8h]@1
-  unsigned int v18; // [sp+28h] [bp+Ch]@1
-  int v19; // [sp+34h] [bp+18h]@1
-
-  v6 = screenSpaceX;
-  v7 = (a6 >> 1) + screenSpaceY;
-  v17 = 0;
-  v15 = 0;
-  v8 = (a6 >> 1) + v6;
-  v14 = (a6 >> 1) * (a6 >> 1);
-  v9 = 2 * (a6 >> 1);
-  v10 = (a6 >> 1) * ((a6 >> 1) - 1);
-  x = v8 - (a6 >> 1);
-  v16 = (a6 >> 1) + screenSpaceY - v8;
-  v19 = a6 >> 1;
-  v13 = v9;
-  v18 = v8;
-  do
-  {
-    sr_4A46E6_draw_particle_segment(x, v16 + v18, z, 2 * v19, lightColor);
-    if ( v15 )
-      sr_4A46E6_draw_particle_segment(x, v17 + v7, z, 2 * v19, lightColor);
-    v14 -= v15;
-    if ( v14 <= v10 )
-    {
-      if ( v19 != v17 )
-      {
-        sr_4A46E6_draw_particle_segment(v18, v16 + x, z, 2 * v17, lightColor);
-        sr_4A46E6_draw_particle_segment(v18, v19 + v7, z, 2 * v17, lightColor);
-      }
-      --v19;
-      v13 -= 2;
-      ++x;
-      v10 -= v13;
-    }
-    result = v17++;
-    v15 += 2;
-    --v18;
-  }
-  while ( result < v19 );
-  return result;
-}
 
 //----- (004A49D0) --------------------------------------------------------
 void Render::DrawProjectile(float srcX, float srcY, float a3, float a4, float dstX, float dstY, float a7, float a8, IDirect3DTexture2 *a9)
@@ -6536,7 +6447,7 @@
   {
     if ( this->pRenderD3D )
     {
-      if ( this->bColorKeySupported )
+      /*if ( this->bColorKeySupported )
       {
         memset(&Dst, 0, 0x7Cu);
         Dst.dwSize = 124;
@@ -6547,7 +6458,7 @@
           this->field_18_locked_pitch = Dst.lPitch >> 1;
         }
         --this->uNumSceneBegins;
-      }
+      }*/
     }
     else
     {
@@ -6575,13 +6486,13 @@
     {
       if ( this->pRenderD3D )
       {
-        if ( this->bColorKeySupported )
+        /*if ( this->bColorKeySupported )
         {
           this->pTargetSurface = 0;
           this->uTargetSurfacePitch = 0;
           this->field_18_locked_pitch = 0;
           ErrD3D(this->pColorKeySurface4->Unlock(0));
-        }
+        }*/
       }
       else
       {
@@ -6827,11 +6738,33 @@
   this->uClipZ = 640;
 }
 
+unsigned __int32 Color32(unsigned __int16 color16)
+{
+  unsigned __int32 c = color16;
+  unsigned int b = (c & 31) * 8;
+  unsigned int g = ((c >> 5) & 63) * 4;
+  unsigned int r = ((c >> 11) & 31) * 8;
+
+  return 0xFF000000 | (r << 16) | (g << 8) | b;
+}
+
+//----- (0040DEF3) --------------------------------------------------------
+unsigned __int16 Color16(unsigned __int32 r, unsigned __int32 g, unsigned __int32 b)
+{
+  //return ((unsigned int)b >> (8 - LOBYTE(pRenderer->uTargetBBits))) | pRenderer->uTargetGMask & (g << (LOBYTE(pRenderer->uTargetGBits) + 
+  //                         LOBYTE(pRenderer->uTargetBBits) - 8)) | pRenderer->uTargetRMask & (r << (LOBYTE(pRenderer->uTargetGBits) + 
+  //                         LOBYTE(pRenderer->uTargetRBits) + LOBYTE(pRenderer->uTargetBBits) - 8));
+  return (b >> (8 - 5)) |
+         0x7E0 & (g << (6 + 5 - 8)) |
+         0xF800 & (r << (6 + 5 + 5 - 8));
+}
+
+
 //----- (004A5BE3) --------------------------------------------------------
 void Render::DrawTextureRGB(unsigned int uOutX, unsigned int uOutY, RGBTexture *a4)
 {
   int v4; // edi@3
-  unsigned __int16 *v5; // edx@3
+  //unsigned __int16 *v5; // edx@3
   unsigned __int16 *v6; // esi@3
   unsigned int v8; // eax@5
   unsigned int v9; // ebx@5
@@ -6845,7 +6778,7 @@
   if ( this->uNumSceneBegins && a4 )
   {
     v4 = a4->uWidth;
-    v5 = &this->pTargetSurface[uOutX + uOutY * this->uTargetSurfacePitch];
+    //v5 = &this->pTargetSurface[uOutX + uOutY * this->uTargetSurfacePitch];
     v6 = a4->pPixels;
     v23 = a4->uHeight;
     v19 = v4;
@@ -6858,14 +6791,14 @@
         v8 *= 2;
         v4 += v9;
         v6 = (unsigned __int16 *)((char *)v6 + v8);
-        v5 = (unsigned __int16 *)((char *)v5 + v8);
+        //v5 = (unsigned __int16 *)((char *)v5 + v8);
       }
       if ( (signed int)uOutY < (signed int)this->uClipY )
       {
         v11 = this->uClipY - uOutY;
         v6 += v19 * v11;
         v23 += uOutY - this->uClipY;
-        v5 += this->uTargetSurfacePitch * v11;
+        //v5 += this->uTargetSurfacePitch * v11;
       }
       v12 = max(this->uClipX, uOutX);
       if ( (signed int)(v4 + v12) > (signed int)this->uClipZ )
@@ -6879,16 +6812,17 @@
       }
     }
 
-    for (int outerCounter = 0; outerCounter < v23; outerCounter++)
-    {
-      for (int counter = 0; counter < v4; counter++)
-      {
-        *v5 = *v6;
-        ++v5;
+    for (int y = 0; y < v23; y++)
+    {
+      for (int x = 0; x < v4; x++)
+      {
+        WritePixel16(uOutX + x, uOutY + y, *v6);
+        //*v5 = *v6;
+        //++v5;
         ++v6;
       }
       v6 += v19 - v4;
-      v5 += this->uTargetSurfacePitch - v4;
+      //v5 += this->uTargetSurfacePitch - v4;
     }
   }
 }
@@ -6896,15 +6830,19 @@
 //----- (004A5D33) --------------------------------------------------------
 void Render::CreditsTextureScroll(unsigned int pX, unsigned int pY, int move_X, int move_Y, RGBTexture *pTexture)
 {
-  unsigned __int16 *v7; // ebx@3
+  //unsigned __int16 *v7; // ebx@3
   int full_width; // ecx@3
   int full_height; // edi@3
-  int v23; // edi@23
+  //int v23; // edi@23
   unsigned __int16 *pTexturea; // [sp+28h] [bp+18h]@3
 
   if ( this->uNumSceneBegins && pTexture )
   {
-    v7 = &this->pTargetSurface[pX + pY * this->uTargetSurfacePitch];
+    /*auto v7 = this->pTargetSurface;
+    if (FORCE_16_BITS)
+      v7 = (unsigned __int32 *)((char *)v7 + (pX + pY * this->uTargetSurfacePitch) * 2);
+    else
+      v7 = (unsigned __int32 *)((char *)v7 + (pX + pY * this->uTargetSurfacePitch) * 4);*/
     full_width = pTexture->uWidth - move_X;
     full_height = pTexture->uHeight - move_Y;
     pTexturea = &pTexture->pPixels[move_X + move_Y * pTexture->uWidth];
@@ -6914,13 +6852,13 @@
       {
         pTexturea = (unsigned __int16 *)((char *)pTexturea + (2 * (this->uClipX - pX)));
         full_width += pX - this->uClipX;
-        v7 = (unsigned __int16 *)((char *)v7 + (2 * (this->uClipX - pX)));
+        //v7 = (unsigned __int32 *)((char *)v7 + ((FORCE_16_BITS ? 2 : 4) * (this->uClipX - pX)));
       }
       if ( pY < this->uClipY )//åñëè êàäð âûõîäèò çà âåðõíþþ ãðàíèöó
       {
         pTexturea += pTexture->uWidth * (this->uClipY - pY);
         full_height += pY - this->uClipY;
-        v7 += this->uTargetSurfacePitch * (this->uClipY - pY);
+        //v7 = (unsigned __int32 *)((char *)v7 + (FORCE_16_BITS ? 2 : 4) * this->uTargetSurfacePitch * (this->uClipY - pY));
       }
       if ( this->uClipX < pX )//åñëè ïðàâàÿ ãðàíèöà îêíà ìåíüøå õ êîîðäèíàòû êàäðà
         this->uClipX = pX;
@@ -6939,36 +6877,32 @@
         full_height = this->uClipW - this->uClipY;
       }
     }
-    if ( full_height > 0 )
-    {
-      do
-      {
-        if ( full_width > 0 )
-        {
-          v23 = full_width;
-          do
-          {
-            if ( *pTexturea != TargetColor(0, 0xFFu, 0xFFu) )
-              *v7 = *pTexturea;
+
+    for (int y = 0; y < full_height; ++y)
+    {
+      for (int x = 0; x < full_width; ++x)
+      {
+            if ( *pTexturea != Color16(0, 0xFFu, 0xFFu) )
+            {
+              WritePixel16(pX + x, pY + y, *pTexturea);
+              /*if (FORCE_16_BITS)
+                *(unsigned __int16 *)v7 = *pTexturea;
+              else
+                *(unsigned __int32 *)v7 = r5g6b5_2_r8g8b8(*pTexturea);*/
+            }
             ++pTexturea;
-            ++v7;
-            --v23;
-          }
-          while ( v23 );
+            //++v7;
         }
-        v7 += this->uTargetSurfacePitch - full_width;
+        //v7 += this->uTargetSurfacePitch - full_width;
         pTexturea = (unsigned __int16 *)((char *)pTexturea + 2 * (pTexture->uWidth - full_width));
-        --full_height;
-      }
-      while ( full_height );
-    }
+      }
   }
 }
 
 //----- (004A6E7E) --------------------------------------------------------
 void Render::_4A6E7E(unsigned int a2, unsigned int a3, Texture *a4)
 {
-  unsigned __int16 *v4; // eax@4
+  //unsigned __int16 *v4; // eax@4
   int v5; // edx@4
   unsigned int v6; // edi@4
   unsigned int v7; // edx@5
@@ -6992,12 +6926,14 @@
 
   if ( this->uNumSceneBegins && a4 && a4->pPalette16 )
   {
-    v4 = &this->pTargetSurface[a2 + a3 * this->uTargetSurfacePitch];
+    //v4 = &this->pTargetSurface[a2 + a3 * this->uTargetSurfacePitch];
     v20 = a4->pLevelOfDetail0_prolly_alpha_mask;
     v5 = a4->uTextureWidth;
     v6 = a4->uTextureHeight;
     v19 = a4->uTextureWidth;
     v18 = a4->uTextureWidth;
+    int clipped_out_x = a2;
+    int clipped_out_y = a3;
     if ( this->bClip )
     {
       v7 = this->uClipX;
@@ -7006,7 +6942,8 @@
         v8 = v7 - a2;
         v20 += v8;
         v19 += a2 - this->uClipX;
-        v4 += v8;
+        //v4 += v8;
+        clipped_out_x = uClipX;
       }
       v9 = this->uClipY;
       if ( (signed int)a3 < (signed int)v9 )
@@ -7014,7 +6951,8 @@
         v10 = v9 - a3;
         v20 += v18 * v10;
         v6 = a3 - this->uClipY + a4->uTextureHeight;
-        v4 += this->uTargetSurfacePitch * v10;
+        //v4 += this->uTargetSurfacePitch * v10;
+        clipped_out_y = uClipY;
       }
       v11 = this->uClipX;
       v5 = v19;
@@ -7040,7 +6978,19 @@
         v6 = v15 - v16;
       }
     }
-    if ( pRenderer->uTargetGBits == 5 )
+
+    for (int y = 0; y < v6; ++y)
+    {
+      for (int x = 0; x < v5; ++x)
+      {
+        if ( *v20 )
+          WritePixel16(clipped_out_x + x, clipped_out_y + y, ((unsigned int)a4->pPalette16[*v20] >> 1) & 0x7BEF);
+        ++v20;
+      }
+          v20 += v18 - v5;
+    }
+
+    /*if ( pRenderer->uTargetGBits == 5 )
     {
       if ( (signed int)v6 > 0 )
       {
@@ -7093,12 +7043,12 @@
         }
         while ( !v17 );
       }
-    }
+    }*/
   }
 }
 
 //----- (004A6DF5) --------------------------------------------------------
-int Render::_4A6DF5(unsigned __int16 *pBitmap, unsigned int uBitmapPitch, Vec2_int_ *pBitmapXY, unsigned __int16 *pTarget, unsigned int uTargetPitch, Vec4_int_ *a7)
+void Render::_4A6DF5(unsigned __int16 *pBitmap, unsigned int uBitmapPitch, Vec2_int_ *pBitmapXY, void *pTarget, unsigned int uTargetPitch, Vec4_int_ *a7)
 {
   int result; // eax@0
   int v8; // ecx@3
@@ -7108,19 +7058,19 @@
   unsigned __int16 *pBitmapa; // [sp+14h] [bp+8h]@3
   unsigned __int16 *pTargeta; // [sp+20h] [bp+14h]@3
 
-  if ( pBitmap )
-  {
-    if ( pTarget )
-    {
+  if ( !pBitmap || !pTarget)
+    return;
+
       pBitmapa = &pBitmap[pBitmapXY->x + uBitmapPitch * pBitmapXY->y];
-      pTargeta = &pTarget[a7->x + uTargetPitch * a7->y];
+
+      __debugbreak(); // sub expects 16bit target surface, we may have 32bit
+      pTargeta = (unsigned short *)pTarget + a7->x + uTargetPitch * a7->y;
       v8 = a7->z - a7->x;
-      result = a7->w - a7->y;
-      if ( result > 0 )
+      v11 = a7->w - a7->y;
+      if ( v11 > 0 )
       {
         v9 = pBitmapa;
         v10 = pTargeta;
-        v11 = a7->w - a7->y;
         do
         {
           if ( v8 > 0 )
@@ -7141,9 +7091,6 @@
         }
         while ( v11 );
       }
-    }
-  }
-  return result;
 }
 
 //----- (004A6D87) --------------------------------------------------------
@@ -7155,11 +7102,14 @@
   unsigned __int32 twoColors = (uColor16 << 16) | uColor16;
   for (uint y = 0; y < uHeight; ++y)
   {
-    ushort* pDst = &pTargetSurface[uX + (y + uY) * uTargetSurfacePitch];
-
-    memset32(pDst, twoColors, uWidth / 2);
-    if (uWidth & 1)
-      pDst[uWidth - 1] = uColor16;
+    void *pDst = (char *)pTargetSurface + (FORCE_16_BITS ? 2 : 4) * (uX + (y + uY) * uTargetSurfacePitch);
+
+    memset32(pDst,
+             FORCE_16_BITS ? twoColors : Color32(uColor16),  // two colors per int (16bit) or 1 (32bit)
+             uWidth / (FORCE_16_BITS ? 2 : 1));                      // two pixels per int (16bit) or 1 (32bit)
+
+    if (FORCE_16_BITS && uWidth & 1) // we may miss one pixel for 16bit
+      ((unsigned __int16 *)pTargetSurface)[uX + uWidth - 1 + (y + uY) * uTargetSurfacePitch] = uColor16;
     }
 }
 
@@ -7168,7 +7118,7 @@
 {
   unsigned int v9; // edi@2
   unsigned int v10; // esi@2
-  unsigned __int16 *v11; // eax@2
+  //unsigned __int16 *v11; // eax@2
   unsigned int v12; // ebx@3
   signed int v13; // edx@5
   int v14; // edx@6
@@ -7178,25 +7128,29 @@
   signed int v18; // ebx@13
   unsigned int v19; // edx@15
   signed int v20; // esi@16
-  unsigned int v21; // esi@22
+  //unsigned int v21; // esi@22
   unsigned __int16 v22; // dx@24
-  char v23; // zf@28
+  //char v23; // zf@28
   unsigned __int8 *v24; // [sp+Ch] [bp-4h]@2
-  unsigned int uOutXa; // [sp+18h] [bp+8h]@20
-
-  if ( this->uNumSceneBegins )
-  {
+  //unsigned int uOutXa; // [sp+18h] [bp+8h]@20
+
+  if (!this->uNumSceneBegins)
+    return;
+
     v9 = uCharWidth;
     v10 = uCharHeight;
-    v11 = &this->pTargetSurface[uOutX + uOutY * this->uTargetSurfacePitch];
+    //v11 = &this->pTargetSurface[uOutX + uOutY * this->uTargetSurfacePitch];
     v24 = pFontPixels;
+
+    int clipped_out_x = uOutX, clipped_out_y = uOutY;
     if ( this->bClip )
     {
       v12 = this->uClipX;
       if ( uOutX < (signed int)v12 )
       {
         v24 = &pFontPixels[v12 - uOutX];
-        v11 += v12 - uOutX;
+        //v11 += v12 - uOutX;
+        clipped_out_x = uClipX;
         v9 = uCharWidth + uOutX - v12;
       }
       v13 = this->uClipY;
@@ -7205,7 +7159,8 @@
         v14 = v13 - uOutY;
         v24 += uCharWidth * v14;
         v10 = uCharHeight + uOutY - this->uClipY;
-        v11 += this->uTargetSurfacePitch * v14;
+        //v11 += this->uTargetSurfacePitch * v14;
+        clipped_out_y = uClipY;
       }
       v15 = this->uClipX;
       if ( v15 < uOutX )
@@ -7230,36 +7185,23 @@
         v10 = v19 - v20;
       }
     }
-    if ( (signed int)v10 > 0 )
-    {
-      uOutXa = v10;
-      do
-      {
-        if ( (signed int)v9 > 0 )
+
+    for (int y = 0; y < v10; ++y)
+    {
+      for (int x = 0; x < v9; ++x)
+      {
+        if (*v24)
         {
-          v21 = v9;
-          do
-          {
-            if ( *v24 )
-            {
-              v22 = uShadowColor;
-              if ( *v24 != 1 )
-                v22 = uFaceColor;
-              *v11 = v22;
-            }
-            ++v11;
-            ++v24;
-            --v21;
-          }
-          while ( v21 );
+          v22 = uShadowColor;
+          if ( *v24 != 1 )
+            v22 = uFaceColor;
+          WritePixel16(clipped_out_x + x, clipped_out_y + y, v22);
         }
+      }
         v24 += uCharWidth - v9;
-        v23 = uOutXa-- == 1;
-        v11 += this->uTargetSurfacePitch - v9;
-      }
-      while ( !v23 );
-    }
-  }
+        //v23 = uOutXa-- == 1;
+        //v11 += this->uTargetSurfacePitch - v9;
+    }
 }
 
 //----- (004A6A68) --------------------------------------------------------
@@ -7278,7 +7220,7 @@
     {
   int v8; // edi@2
   unsigned int v9; // esi@2
-  unsigned __int16 *v10; // eax@2
+  //unsigned __int16 *v10; // eax@2
   unsigned char *v11; // edx@2
   unsigned int v12; // ebx@3
   signed int v13; // edx@5
@@ -7303,21 +7245,25 @@
   int a2 = x;
   int a3 = y;
   uint a6 = uFontHeight;
-  if ( this->uNumSceneBegins )
-  {
+  if (!this->uNumSceneBegins)
+    return;
+
     v8 = a5;
     v9 = a6;
-    v10 = &pTargetSurface[x + y * uTargetSurfacePitch];
+    //v10 = &pTargetSurface[x + y * uTargetSurfacePitch];
     v11 = (unsigned char *)font_pixels;
     v25 = (int)font_pixels;
+    int clipped_out_x = x;
+    int clipped_out_y = y;
     if ( this->bClip )
     {
       v12 = this->uClipX;
       if ( a2 < (signed int)v12 )
       {
         v25 = v12 - a2 + (int)font_pixels;
-        v10 += v12 - a2;
+        //v10 += v12 - a2;
         v8 = a5 + a2 - v12;
+        clipped_out_x = uClipX;
       }
       v13 = this->uClipY;
       if ( a3 < v13 )
@@ -7325,7 +7271,8 @@
         v14 = v13 - a3;
         v25 += a5 * v14;
         v9 = a6 + a3 - this->uClipY;
-        v10 += this->uTargetSurfacePitch * v14;
+        //v10 += this->uTargetSurfacePitch * v14;
+        clipped_out_y = uClipY;
       }
       v15 = this->uClipX;
       if ( v15 < a2 )
@@ -7351,10 +7298,27 @@
       }
       v11 = (unsigned char *)v25;
     }
+
     if ( a8 )
     {
-      v28 = pRenderer->uTargetGMask | pRenderer->uTargetBMask;
-      if ( (signed int)v9 > 0 )
+      v28 = 0x7FF; // 16bit pRenderer->uTargetGMask | pRenderer->uTargetBMask;
+      for (int dy = 0; dy < v9; ++dy)
+      {
+        for (int dx = 0; dx < v8; ++dx)
+        {
+              if ( *v11 )
+                v24 = pPalette[*v11];
+              else
+                v24 = v28;
+              WritePixel16(clipped_out_x + dx, clipped_out_y + dy, v24);
+              //*v10 = v24;
+              //++v10;
+              //++v11;
+              //--v27;
+        }
+          v11 += a5 - v8;
+      }
+      /*if ( (signed int)v9 > 0 )
       {
         v23 = a5;
         v30 = v9;
@@ -7381,11 +7345,24 @@
           v10 += this->uTargetSurfacePitch - v8;
         }
         while ( !v22 );
-      }
+      }*/
     }
     else
     {
-      if ( (signed int)v9 > 0 )
+      for (int dy = 0; dy < v9; ++dy)
+      {
+        for (int dx = 0; dx < v8; ++dx)
+        {
+              WritePixel16(clipped_out_x + dx, clipped_out_y + dy, pPalette[*v11]);
+              //*v10 = v24;
+              //++v10;
+              //++v11;
+              //--v27;
+        }
+          v11 += a5 - v8;
+      }
+
+      /*if ( (signed int)v9 > 0 )
       {
         v21 = a5;
         v29 = v9;
@@ -7409,124 +7386,22 @@
           v10 += this->uTargetSurfacePitch - v8;
         }
         while ( !v22 );
-      }
-    }
-  }
+      }*/
+    }
 }
 
 //----- (004A68EF) --------------------------------------------------------
 void Render::DrawTransparentGreenShade(signed int a2, signed int a3, Texture *pTexture)
 {
-  Texture *v4; // edi@2
-  unsigned int v5; // ebx@4
-  unsigned __int16 *v6; // eax@4
-  signed int v7; // edx@5
-  int v8; // edx@6
-  signed int v9; // edx@7
-  int v10; // edx@8
-  signed int v11; // edx@9
-  signed int v12; // esi@12
-  signed int v13; // esi@15
-  unsigned int v14; // edx@17
-  signed int v15; // esi@18
-  unsigned __int8 *v16; // ebx@22
-  char v17; // zf@28
-  int v18; // [sp+10h] [bp-10h]@4
-  unsigned __int8 *v19; // [sp+18h] [bp-8h]@4
-  int v20; // [sp+1Ch] [bp-4h]@4
-  int v21; // [sp+28h] [bp+8h]@24
-  unsigned int v22; // [sp+2Ch] [bp+Ch]@22
-  unsigned int pTexturea; // [sp+30h] [bp+10h]@11
-
-  if ( this->uNumSceneBegins )
-  {
-    v4 = pTexture;
-    if ( pTexture )
-    {
-      if ( pTexture->pPalette16 )
-      {
-        v5 = pTexture->uTextureHeight;
-        v6 = &this->pTargetSurface[a2 + a3 * this->uTargetSurfacePitch];
-        v19 = pTexture->pLevelOfDetail0_prolly_alpha_mask;
-        v20 = pTexture->uTextureWidth;
-        v18 = pTexture->uTextureWidth;
-        if ( this->bClip )
-        {
-          v7 = this->uClipX;
-          if ( a2 < v7 )
-          {
-            v8 = v7 - a2;
-            v19 += v8;
-            v20 += a2 - this->uClipX;
-            v6 += v8;
-          }
-          v9 = this->uClipY;
-          v5 = pTexture->uTextureHeight;
-          if ( a3 < v9 )
-          {
-            v10 = v9 - a3;
-            v19 += v18 * v10;
-            v5 = a3 - this->uClipY + pTexture->uTextureHeight;
-            v4 = pTexture;
-            v6 += this->uTargetSurfacePitch * v10;
-          }
-          v11 = this->uClipX;
-          if ( v11 < a2 )
-            v11 = a2;
-          pTexturea = this->uClipZ;
-          if ( v11 + v20 > (signed int)pTexturea )
-          {
-            v12 = this->uClipX;
-            if ( v12 < a2 )
-              v12 = a2;
-            v20 = pTexturea - v12;
-          }
-          v13 = this->uClipY;
-          if ( v13 < a3 )
-            v13 = a3;
-          v14 = this->uClipW;
-          if ( (signed int)(v5 + v13) > (signed int)v14 )
-          {
-            v15 = this->uClipY;
-            if ( v15 < a3 )
-              v15 = a3;
-            v5 = v14 - v15;
-          }
-        }
-        if ( (signed int)v5 > 0 )
-        {
-          v22 = v5;
-          v16 = v19;
-          do
-          {
-            if ( v20 > 0 )
-            {
-              v21 = v20;
-              do
-              {
-                if ( *v16 )
-                  *v6 = this->uTargetGMask & v4->pPalette16[*v16];
-                ++v6;
-                ++v16;
-                --v21;
-              }
-              while ( v21 );
-            }
-            v16 += v18 - v20;
-            v17 = v22-- == 1;
-            v6 += this->uTargetSurfacePitch - v20;
-          }
-          while ( !v17 );
-        }
-      }
-    }
-  }
-}
+  DrawMasked(a2, a3, pTexture, 0x07E0);
+}
+
 
 //----- (004A6776) --------------------------------------------------------
 void Render::DrawTransparentRedShade(unsigned int a2, unsigned int a3, Texture *a4)
 {
-  Texture *v4; // edi@2
+  DrawMasked(a2, a3, a4, 0xF800);
+  /*Texture *v4; // edi@2
   unsigned int v5; // ebx@4
   unsigned __int16 *v6; // eax@4
   unsigned int v7; // edx@5
@@ -7629,13 +7504,138 @@
         }
       }
     }
-  }
-}
+  }*/
+}
+
+//----- (004A68EF) --------------------------------------------------------
+void Render::DrawMasked(signed int a2, signed int a3, Texture *pTexture, unsigned __int16 mask)
+{
+  Texture *v4; // edi@2
+  unsigned int v5; // ebx@4
+  //unsigned __int16 *v6; // eax@4
+  signed int v7; // edx@5
+  int v8; // edx@6
+  signed int v9; // edx@7
+  int v10; // edx@8
+  signed int v11; // edx@9
+  signed int v12; // esi@12
+  signed int v13; // esi@15
+  unsigned int v14; // edx@17
+  signed int v15; // esi@18
+  unsigned __int8 *v16; // ebx@22
+  char v17; // zf@28
+  int v18; // [sp+10h] [bp-10h]@4
+  unsigned __int8 *v19; // [sp+18h] [bp-8h]@4
+  int v20; // [sp+1Ch] [bp-4h]@4
+  int v21; // [sp+28h] [bp+8h]@24
+  unsigned int v22; // [sp+2Ch] [bp+Ch]@22
+  unsigned int pTexturea; // [sp+30h] [bp+10h]@11
+
+  if (!uNumSceneBegins || !pTexture)
+    return;
+
+    v4 = pTexture;
+
+      if ( pTexture->pPalette16 )
+      {
+        v5 = pTexture->uTextureHeight;
+        //v6 = &this->pTargetSurface[a2 + a3 * this->uTargetSurfacePitch];
+        v19 = pTexture->pLevelOfDetail0_prolly_alpha_mask;
+        v20 = pTexture->uTextureWidth;
+        v18 = pTexture->uTextureWidth;
+        int clipped_out_x = a2;
+        int clipped_out_y = a3;
+        if ( this->bClip )
+        {
+          v7 = this->uClipX;
+          if ( a2 < v7 )
+          {
+            v8 = v7 - a2;
+            v19 += v8;
+            v20 += a2 - this->uClipX;
+            //v6 += v8;
+            clipped_out_x = uClipX;
+          }
+          v9 = this->uClipY;
+          v5 = pTexture->uTextureHeight;
+          if ( a3 < v9 )
+          {
+            v10 = v9 - a3;
+            v19 += v18 * v10;
+            v5 = a3 - this->uClipY + pTexture->uTextureHeight;
+            v4 = pTexture;
+            //v6 += this->uTargetSurfacePitch * v10;
+            clipped_out_y = uClipY;
+          }
+          v11 = this->uClipX;
+          if ( v11 < a2 )
+            v11 = a2;
+          pTexturea = this->uClipZ;
+          if ( v11 + v20 > (signed int)pTexturea )
+          {
+            v12 = this->uClipX;
+            if ( v12 < a2 )
+              v12 = a2;
+            v20 = pTexturea - v12;
+          }
+          v13 = this->uClipY;
+          if ( v13 < a3 )
+            v13 = a3;
+          v14 = this->uClipW;
+          if ( (signed int)(v5 + v13) > (signed int)v14 )
+          {
+            v15 = this->uClipY;
+            if ( v15 < a3 )
+              v15 = a3;
+            v5 = v14 - v15;
+          }
+        }
+        
+          v16 = v19;
+        for (int y = 0; y < v5; ++y)
+        {
+          for (int x = 0; x < v20; ++x)
+          {
+                if ( *v16 )
+                  WritePixel16(clipped_out_x + x, clipped_out_y + y, v4->pPalette16[*v16] & mask);
+                ++v16;
+          }
+            v16 += v18 - v20;
+        }
+
+        /*if ( (signed int)v5 > 0 )
+        {
+          v22 = v5;
+          v16 = v19;
+          do
+          {
+            if ( v20 > 0 )
+            {
+              v21 = v20;
+              do
+              {
+                if ( *v16 )
+                  *v6 = this->uTargetGMask & v4->pPalette16[*v16];
+                ++v6;
+                ++v16;
+                --v21;
+              }
+              while ( v21 );
+            }
+            v16 += v18 - v20;
+            v17 = v22-- == 1;
+            v6 += this->uTargetSurfacePitch - v20;
+          }
+          while ( !v17 );
+        }*/
+      }
+}
+
 
 //----- (004A65CC) --------------------------------------------------------
 void Render::_4A65CC(unsigned int x, unsigned int y, Texture *a4, Texture *a5, int a6, int a7, int a8)
 {
-  unsigned __int16 *v8; // esi@6
+  //unsigned __int16 *v8; // esi@6
   unsigned int v9; // edi@6
   unsigned int v10; // eax@7
   unsigned int v11; // eax@8
@@ -7658,11 +7658,13 @@
 
   if ( this->uNumSceneBegins && a4 && a4->pPalette16 && a5 && a5->pPalette16 )
   {
-    v8 = &this->pTargetSurface[x + y * this->uTargetSurfacePitch];
+    //v8 = &this->pTargetSurface[x + y * this->uTargetSurfacePitch];
     v24 = a4->pLevelOfDetail0_prolly_alpha_mask;
     v27 = a4->uTextureWidth;
     v9 = a4->uTextureHeight;
     v22 = a4->uTextureWidth;
+    int clipped_out_x = x;
+    int clipped_out_y = y;
     if ( this->bClip )
     {
       v10 = this->uClipX;
@@ -7671,7 +7673,8 @@
         v11 = v10 - x;
         v24 += v11;
         v27 += x - this->uClipX;
-        v8 += v11;
+        //v8 += v11;
+        clipped_out_x = uClipX;
       }
       v12 = this->uClipY;
       if ( (signed int)y < (signed int)v12 )
@@ -7679,7 +7682,8 @@
         v13 = v12 - y;
         v24 += v22 * v13;
         v9 = y - this->uClipY + a4->uTextureHeight;
-        v8 += this->uTargetSurfacePitch * v13;
+        //v8 += this->uTargetSurfacePitch * v13;
+        clipped_out_y = uClipY;
       }
       v14 = this->uClipX;
       if ( (signed int)v14 < (signed int)x )
@@ -7704,7 +7708,25 @@
         v9 = v18 - v19;
       }
     }
-    if ( (signed int)v9 > 0 )
+
+    for (int dy = 0; dy < v9; ++dy)
+    {
+      for (int dx = 0; dx < v27; ++dx)
+      {
+            v20 = *v24;
+            if ( v20 >= a7 && v20 <= a8 )
+            {
+              v21 = a7 + (a6 + v20) % (2 * (a8 - a7));
+              if ( (a6 + v20) % (2 * (a8 - a7)) >= a8 - a7 )
+                v21 = 2 * a8 - v21 - a7;
+              //*v8 = a4->pPalette16[v21];
+              WritePixel16(clipped_out_x + dx, clipped_out_y + dy, a4->pPalette16[v21]);
+            }
+            ++v24;
+      }
+        v24 += v22 - v27;
+    }
+    /*if ( (signed int)v9 > 0 )
     {
       ya = v9;
       v23 = v22 - v27;
@@ -7734,7 +7756,7 @@
         --ya;
       }
       while ( ya );
-    }
+    }*/
   }
 }
 
@@ -7742,8 +7764,8 @@
 void Render::DrawAura(unsigned int a2, unsigned int a3, Texture *a4, Texture *a5, int a6, int a7, int a8)
 {
   Texture *v8; // eax@2
-  Texture *v9; // ebx@4
-  unsigned __int16 *v10; // esi@6
+  //Texture *v9; // ebx@4
+  //unsigned __int16 *v10; // esi@6
   unsigned int v11; // edi@7
   unsigned int v12; // eax@9
   unsigned int v13; // eax@10
@@ -7770,16 +7792,18 @@
     {
       if ( a4->pPalette16 )
       {
-        v9 = a5;
         if ( a5 )
         {
           if ( a5->pPalette16 )
           {
-            v10 = &this->pTargetSurface[a2 + a3 * this->uTargetSurfacePitch];
+            //v10 = &this->pTargetSurface[a2 + a3 * this->uTargetSurfacePitch];
             v28 = a4->pLevelOfDetail0_prolly_alpha_mask;
             v25 = v8->uTextureWidth;
             v24 = v8->uTextureHeight;
             v22 = v8->uTextureWidth;
+
+            int clipped_out_x = a2;
+            int clipped_out_y = a3;
             if ( this->bClip )
             {
               v11 = this->uClipX;
@@ -7787,17 +7811,17 @@
               {
                 v28 += v11 - a2;
                 v25 += a2 - v11;
-                v9 = a5;
-                v10 += v11 - a2;
+                //v10 += v11 - a2;
+                clipped_out_x = uClipX;
               }
               v12 = this->uClipY;
               if ( (signed int)a3 < (signed int)v12 )
               {
                 v13 = v12 - a3;
-                v9 = a5;
                 v28 += v22 * v13;
                 v24 += a3 - this->uClipY;
-                v10 += this->uTargetSurfacePitch * v13;
+                //v10 += this->uTargetSurfacePitch * v13;
+                clipped_out_y = uClipY;
               }
               v14 = this->uClipX;
               if ( (signed int)v14 < (signed int)a2 )
@@ -7822,8 +7846,34 @@
                 v24 = v18 - v19;
               }
             }
+
             v27 = 0;
-            if ( v24 > 0 )
+            for (int y = 0; y < v24; ++y)
+            {
+              for (int x = 0; x < v25; ++x)
+              {
+                  if ( *v28 )
+                  {
+                    v20 = *(&a5->pLevelOfDetail0_prolly_alpha_mask[i & a5->uWidthMinus1] + a5->uTextureWidth * (v27 & a5->uHeightMinus1));
+                    if ( v20 >= a7 )
+                    {
+                      if ( v20 <= a8 )
+                      {
+                        v21 = a7 + (a6 + v20) % (2 * (a8 - a7));
+                        if ( (a6 + v20) % (2 * (a8 - a7)) >= a8 - a7 )
+                          v21 = 2 * a8 - v21 - a7;
+                        //v9 = a5;
+                        //*v10 = a5->pPalette16[v21];
+                        WritePixel16(clipped_out_x + x, clipped_out_y + y, a5->pPalette16[v21]);
+                      }
+                    }
+                  }
+                  v28++;
+              }
+                v28 += v22 - v25;
+            }
+
+            /*if ( v24 > 0 )
             {
               v23 = v22 - v25;
               do
@@ -7853,7 +7903,10 @@
                 v28 += v23;
               }
               while ( v27 < v24 );
-            }
+            }*/
+
+
+
           }
         }
       }
@@ -7866,7 +7919,7 @@
 {
   Texture *pCurrentTexture; // edi@2
   int uHeight; // ebx@4
-  unsigned __int16 *v6; // eax@4
+  //unsigned __int16 *v6; // eax@4
   unsigned int v7; // edx@5
   unsigned int v8; // edx@6
   unsigned int v9; // edx@7
@@ -7893,10 +7946,13 @@
       if ( pTexture->pPalette16 )
       {
         uHeight = pTexture->uTextureHeight;
-        v6 = &this->pTargetSurface[uX + uY * this->uTargetSurfacePitch];
+        //v6 = &this->pTargetSurface[uX + uY * this->uTargetSurfacePitch];
         v19 = pTexture->pLevelOfDetail0_prolly_alpha_mask;
         uWidth = pTexture->uTextureWidth;
         v18 = pTexture->uTextureWidth;
+
+        int clipped_out_x = uX;
+        int clipped_out_y = uY;
         if ( this->bClip )
         {
           v7 = this->uClipX;
@@ -7905,7 +7961,8 @@
             v8 = v7 - uX;
             v19 += v8;
             uWidth += uX - this->uClipX;
-            v6 += v8;
+            //v6 += v8;
+            clipped_out_x = uClipX;
           }
           v9 = this->uClipY;
           uHeight = pTexture->uTextureHeight;
@@ -7915,7 +7972,8 @@
             v19 += v18 * v10;
             uHeight = uY - this->uClipY + pTexture->uTextureHeight;
             pCurrentTexture = pTexture;
-            v6 += this->uTargetSurfacePitch * v10;
+            //v6 += this->uTargetSurfacePitch * v10;
+            clipped_out_y = uClipY;
           }
           v11 = this->uClipX;
           if ( (signed int)v11 < (signed int)uX )
@@ -7940,7 +7998,19 @@
             uHeight = v14 - v15;
           }
         }
-        if ( (signed int)uHeight > 0 )
+        
+          v16 = v19;
+        for (int y = 0; y < uHeight; ++y)
+        {
+          for (int x = 0; x < uWidth; ++x)
+          {
+                if ( *v16 )
+                  WritePixel16(clipped_out_x + x, clipped_out_y + y, pCurrentTexture->pPalette16[*v16]);
+                ++v16;
+          }
+            v16 += v18 - uWidth;
+        }
+        /*if ( (signed int)uHeight > 0 )
         {
           uYa = uHeight;
           v16 = v19;
@@ -7963,7 +8033,7 @@
             v6 += this->uTargetSurfacePitch - uWidth;
           }
           while ( !uFlag );
-        }
+        }*/
       }
     }
   }
@@ -8159,8 +8229,8 @@
 void Render::DrawTextureIndexed(unsigned int uX, unsigned int uY, Texture *a4)
 {
   Texture *v4; // edi@2
-  unsigned int v5; // ebx@4
-  unsigned __int16 *pTarget; // eax@4
+  int v5; // ebx@4
+  //unsigned __int16 *pTarget; // eax@4
   unsigned int v7; // edx@5
   unsigned int v8; // edx@6
   unsigned int v9; // edx@7
@@ -8168,7 +8238,7 @@
   unsigned int v11; // edx@9
   unsigned int v12; // esi@12
   unsigned int v13; // esi@15
-  unsigned int v14; // edx@17
+  //unsigned int v14; // edx@17
   unsigned int v15; // esi@18
   unsigned __int8 *v16; // edx@22
   char v17; // zf@26
@@ -8187,10 +8257,13 @@
       if ( a4->pPalette16 )
       {
         v5 = a4->uTextureHeight;
-        pTarget = &this->pTargetSurface[uX + uY * this->uTargetSurfacePitch];
+        //pTarget = &this->pTargetSurface[uX + uY * this->uTargetSurfacePitch];
         v19 = a4->pLevelOfDetail0_prolly_alpha_mask;
         v20 = a4->uTextureWidth;
         v18 = a4->uTextureWidth;
+
+        int clipped_out_x = uX;
+        int clipped_out_y = uY;
         if ( this->bClip )
         {
           v7 = this->uClipX;
@@ -8199,7 +8272,8 @@
             v8 = v7 - uX;
             v19 += v8;
             v20 += uX - this->uClipX;
-            pTarget += v8;
+            //pTarget += v8;
+            clipped_out_x = uClipX;
           }
           v9 = this->uClipY;
           v5 = a4->uTextureHeight;
@@ -8209,7 +8283,8 @@
             v19 += v18 * v10;
             v5 = uY - this->uClipY + a4->uTextureHeight;
             v4 = a4;
-            pTarget += this->uTargetSurfacePitch * v10;
+            //pTarget += this->uTargetSurfacePitch * v10;
+            clipped_out_y = uClipY;
           }
           v11 = this->uClipX;
           if ( (signed int)v11 < (signed int)uX )
@@ -8225,16 +8300,27 @@
           v13 = this->uClipY;
           if ( (signed int)v13 < (signed int)uY )
             v13 = uY;
-          v14 = this->uClipW;
-          if ( (signed int)(v5 + v13) > (signed int)v14 )
+
+          if ( (signed int)(v5 + v13) > (signed int)uClipW )
           {
             v15 = this->uClipY;
             if ( (signed int)v15 < (signed int)uY )
               v15 = uY;
-            v5 = v14 - v15;
+            v5 = uClipW - v15;
           }
         }
-        if ( (signed int)v5 > 0 )
+        
+          v16 = v19;
+        for (int y = 0; y < v5; ++y)
+        {
+          for (int x = 0; x < v20; ++x)
+          {
+                WritePixel16(clipped_out_x + x, clipped_out_y + y, v4->pPalette16[*v16]);
+                ++v16;
+          }
+            v16 += v18 - v20;
+        }
+        /*if ( (signed int)v5 > 0 )
         {
           uYa = v5;
           v16 = v19;
@@ -8257,7 +8343,7 @@
             pTarget += this->uTargetSurfacePitch - v20;
           }
           while ( !v17 );
-        }
+        }*/
       }
     }
   }