#include "main.h"
#include "proxyIDirect3D9.h"
#include "proxyIDirect3DDevice9.h"
#include "proxyIDirect3DSwapChain9.h"
#include "d3drender.h"

#define SHOULD_RENDER                  \
   ( set.d3dtext_hud  |                \
      ( cheat_state != NULL &&         \
         (cheat_state->generic.map  |  \
          cheat_state->generic.menu |  \
          cheat_state->debug_enabled)  \
      )                                \
   )


static CD3DFont *pD3DFont = new CD3DFont("Verdana", 10, /*unused?*/256, FCR_BOLD);
static CD3DFont *pD3DFont_fixed = new CD3DFont("Lucida Console", 8, /*unused?*/256, FCR_NONE);


void proxyIDirect3DDevice9::render_map_dot(const float self_matrix[16], const float matrix[16])
{
   D3DCOLOR color;
   IDirect3DSurface9 *target;
   float vect[3], rvect[2];
   float a;
   RECT rect;


   vect[0] = matrix[4*3+0] - self_matrix[4*3+0];
   vect[1] = matrix[4*3+1] - self_matrix[4*3+1];
   vect[2] = matrix[4*3+2] - self_matrix[4*3+2];

   if(vect3_length(vect) > 200.0f)
      return;

   if(matrix == self_matrix)
      color = D3DCOLOR_XRGB(255, 255, 255);
   else if(vect[3] > 10.0f)
      color = D3DCOLOR_XRGB(127, 127, 255);
   else if(vect[3] < -10.0f)
      color = D3DCOLOR_XRGB(0, 0, 127);
   else
      color = D3DCOLOR_XRGB(0, 0, 255);

   a = -atan2f(cam_matrix[4*0+0], cam_matrix[4*0+1]) - M_PI / 2.0f;

   rvect[0] = vect[0] * cosf(a) - -vect[1] * sinf(a);
   rvect[1] = vect[0] * sinf(a) + -vect[1] * cosf(a);

   rvect[1] /= pPresentParam.BackBufferWidth / pPresentParam.BackBufferHeight;

   rect.left   = pPresentParam.BackBufferWidth  / 2 + (int)(rvect[0] + 0.5f) - 2;
   rect.top    = pPresentParam.BackBufferHeight / 2 + (int)(rvect[1] + 0.5f) - 2;
   rect.right  = rect.left + 4;
   rect.bottom = rect.top + 4;

   if(SUCCEEDED(origIDirect3DDevice9->GetRenderTarget(0, &target)))
   {
      origIDirect3DDevice9->ColorFill(target, &rect, 0);
      rect.left++; rect.top++;
      rect.right--; rect.bottom--;
      origIDirect3DDevice9->ColorFill(target, &rect, color);
   }
}


void proxyIDirect3DDevice9::render_map(void)
{
   if(pool_actor != NULL)
   {
      const struct actor_info *self = actor_info_get(ACTOR_SELF, 0);
      int i;

      for(i=0; i<pool_actor->size && self!=NULL; i++)
      {
         struct actor_info *info = actor_info_get(i, ACTOR_ALIVE);

         if(info == NULL)
            continue;

         render_map_dot(self->base.matrix, info->base.matrix);
      }
   }
}


void proxyIDirect3DDevice9::render_box(int x, int y, int w, int h, D3DCOLOR color)
{
   if(SUCCEEDED(pD3DFont->m_pRender->Begin(D3DPT_TRIANGLELIST)))
   {
      D3DAddQuad(pD3DFont->m_pRender, (float)x, (float)y, (float)w, (float)h, color);
      pD3DFont->m_pRender->End();
   }
}

void proxyIDirect3DDevice9::render_box_border(int x, int y, int w, int h, D3DCOLOR border_color, D3DCOLOR color)
{
   render_box(x,   y,   w, 1, border_color);
   render_box(x+w, y,   1, h, border_color);
   render_box(x,   y,   1, h, border_color);
   render_box(x,   y+h, w, 1, border_color);
   render_box(x + 1, y + 1, w - 1, h - 1, color);
}


/* quick hack */
void debug_ptr_set(void *ptr)
{
   struct debug_info *debug = &cheat_state->debug;

   if(debug->hist_pos < DEBUG_HIST_LEN)
   {
      debug->hist_pos++;
   }
   else
   {
      memmove(debug->ptr, debug->ptr + 1, sizeof(debug->ptr) - sizeof(debug->ptr[0]));
      memmove(debug->offset, debug->offset + 1, sizeof(debug->offset) - sizeof(debug->offset[0]));
   }

   debug->ptr[debug->hist_pos] = (uint8_t *)ptr;
   debug->offset[debug->hist_pos] = 0;
   debug->data_prev_clear = 1;
}


/* quick hack */
void proxyIDirect3DDevice9::render_debug(void)
{
   static const int ROW_HEIGHT = (int)ceilf(pD3DFont_fixed->DrawHeight());
   static const int CHAR_WIDTH  = (int)ceilf(pD3DFont_fixed->DrawLength("W"));
   static const int ROWS = DEBUG_DATA_SIZE / 16;
   static const int data_size[4] = { 1, 2, 4, 4 };
   struct debug_info *debug = &cheat_state->debug;
   static char str_data[17], str[256];
   int x, y, row, col, i;
   int offset, offset16;
   uint8_t *ptr, *data;


   ptr = debug->ptr[debug->hist_pos] - DEBUG_DATA_SIZE;
   offset = debug->offset[debug->hist_pos];
   offset16 = (unsigned int)offset % 16;
   ptr += offset - offset16 + DEBUG_DATA_SIZE / 2;

   memset(debug->data, 0, DEBUG_DATA_SIZE);
   memcpy_safe(debug->data, ptr, DEBUG_DATA_SIZE);

   if(!debug->data_prev_clear)
   {
      for(i=0; i<DEBUG_DATA_SIZE; i++)
      {
         if(debug->data[i] != debug->data_prev[i])
            debug->modify_time[i] = time_get();
      }
   }
   else
   {
      memset(debug->modify_time, 0, sizeof(debug->modify_time));
   }
   debug->data_prev_clear = 0;

   x = 324;
   y = 4;

   /* blue box */
   render_box(x - 2, y - 2, CHAR_WIDTH * 75 + 4, ROW_HEIGHT * 27 + 4, D3DCOLOR_ARGB(191, 0, 0, 255));

   /* render selection   XXX: match data type size */
   for(row=offset16; row<offset16+data_size[debug->data_type]; row++)
   {
      col = (ROWS / 2) + row / 16;
      render_box(
         x + CHAR_WIDTH * (10 + (row % 16) * 3), y + ROW_HEIGHT * col,
         CHAR_WIDTH * 3, ROW_HEIGHT, D3DCOLOR_ARGB(127, 0, 255, 0));
      render_box(
         x + CHAR_WIDTH * (59 + (row % 16)), y + ROW_HEIGHT * col,
         CHAR_WIDTH, ROW_HEIGHT, D3DCOLOR_ARGB(127, 0, 255, 0));
   }

   /* render hex view */
   for(row=0; row<ROWS; row++)
   {
      int red_text = 0;
      int len = 10;
      int xpos = x;

      snprintf(str, sizeof(str), "%p  ", ptr + row * 16);

      for(col=0; col<16; col++)
      {
         uint32_t mod_time = debug->modify_time[row*16+col];
         uint8_t ch = debug->data[row*16+col];
         int color_switch = 0;


         if(mod_time != 0 && time_get() < mod_time + MSEC_TO_TIME(2000))
            color_switch = !red_text;  /* switch color, unless red_text == 1 */
         else if(red_text)
            color_switch = 1;

         if(color_switch)
         {
            pD3DFont_fixed->Print((float)xpos, (float)y,
               red_text ? D3DCOLOR_XRGB(255, 31, 31) : D3DCOLOR_XRGB(191, 191, 191),
               str, FT_NONE);

            xpos += CHAR_WIDTH * len;
            str[0] = 0;
            len = 0;

            red_text ^= 1;
         }

         snprintf(str + len, sizeof(str) - len, "%02x ", debug->data[row*16+col]);
         len += 3;

         str_data[col] = (char)((ch < 32) ? '.' : ch);
      }

      pD3DFont_fixed->Print((float)xpos, (float)y,
         red_text ? D3DCOLOR_XRGB(255, 31, 31) : D3DCOLOR_XRGB(191, 191, 191),
         str, FT_NONE);

      pD3DFont_fixed->Print((float)x + CHAR_WIDTH * 59, (float)y, D3DCOLOR_XRGB(191, 191, 191), str_data, FT_NONE);

      y += ROW_HEIGHT;
   }


   /* everything else \o/ */
   data = &debug->data[DEBUG_DATA_SIZE / 2 + offset16];
   memcpy(debug->cursor_data, data, sizeof(debug->cursor_data));

   /* data type info */
   snprintf(str, sizeof(str), "=>%c%02x(%-3d),%c%04x(%-5d),%c%08x(%d),%c%.4f, %s ptr",
      (debug->data_type == 0) ? '*' : ' ', *(uint8_t  *)data, *(uint8_t  *)data,
      (debug->data_type == 1) ? '*' : ' ', *(uint16_t *)data, *(uint16_t *)data,
      (debug->data_type == 2) ? '*' : ' ', *(uint32_t *)data, *(uint32_t *)data,
      (debug->data_type == 3) ? '*' : ' ', *(float *)data,
      IsBadReadPtr(*(void **)data, 1) ? "Bad" : "OK");
   pD3DFont_fixed->Print((float)x, (float)y, D3DCOLOR_XRGB(191, 191, 191), str, FT_NONE);
   y += ROW_HEIGHT;

   /* ptr info */
   snprintf(str, sizeof(str), "Viewing: %s", debug_classify_pointer((void *)(debug->ptr[debug->hist_pos] + offset)));
   pD3DFont_fixed->Print((float)x, (float)y, D3DCOLOR_XRGB(191, 191, 191), str, FT_NONE);
   y += ROW_HEIGHT;

   snprintf(str, sizeof(str), "Pointer: %s", debug_classify_pointer(*(void **)data));
   pD3DFont_fixed->Print((float)x, (float)y, D3DCOLOR_XRGB(191, 191, 191), str, FT_NONE);
   y += ROW_HEIGHT;

   /* ptr stack info */
   snprintf(debug->ptr_hist_str, sizeof(debug->ptr_hist_str),
      "Ptr stack (%d): %s", debug->hist_pos, debug->hist_pos > 2 ? "... " : "");
   for(i=debug->hist_pos-2; i<=debug->hist_pos; i++)
   {
      int len = (int)strlen(debug->ptr_hist_str);

      if(i < 0)
         continue;
      snprintf(debug->ptr_hist_str + len, sizeof(debug->ptr_hist_str) - len, "%p+%d -> ",
         debug->ptr[i], debug->offset[i]);
   }
   debug->ptr_hist_str[strlen(debug->ptr_hist_str) - 4] = 0;
   pD3DFont_fixed->Print((float)x, (float)y, D3DCOLOR_XRGB(191, 191, 191), debug->ptr_hist_str, FT_NONE);
   y += ROW_HEIGHT * 2;

   /* print help */
   pD3DFont_fixed->Print((float)x, (float)y, D3DCOLOR_XRGB(191, 191, 191),
      "np4/6,8/2,9/3 = move   np7 = return   np1 = go to pointer", FT_NONE);
   y += ROW_HEIGHT;

   pD3DFont_fixed->Print((float)x, (float)y, D3DCOLOR_XRGB(191, 191, 191),
      "np/ = data type   np-/+ = inc/dec   np* = ptr stack to clipboard", FT_NONE);

   memcpy(debug->data_prev, debug->data, DEBUG_DATA_SIZE);
}


#define MENU_ROWS  12
#define MENU_WIDTH 400

void proxyIDirect3DDevice9::render_menu(void)
{
   static const int ROW_HEIGHT = (int)ceilf(pD3DFont->DrawHeight());
   static const int MENU_HEIGHT = (int)ceilf(pD3DFont->DrawHeight() * (float)MENU_ROWS) + 2;
   char title[256];
   struct menu_item *item;
   struct menu *menu;
   int left, top;
   float x, y;
   int pos, top_pos, i;


   if(menu_active == NULL)
      return;

   /* find root menu */
   for(menu=menu_active; menu->parent!=NULL; menu=menu->parent);

   strlcpy(title, "m0d_s0beit", sizeof(title));
   while(menu != NULL)
   {
      if(menu->pos < 0 || menu->pos >= menu->count)
         break;
      item = &menu->item[menu->pos];
      if(item->submenu == NULL || menu == menu_active)
         break;
      snprintf(title + strlen(title), sizeof(title) - strlen(title), " > %s", item->name);
      menu = item->submenu;
   }

   /* draw titlebar */
   left = pPresentParam.BackBufferWidth  / 2 - MENU_WIDTH / 2;
   top = pPresentParam.BackBufferHeight - MENU_HEIGHT - ROW_HEIGHT - 2 - 16 - 2;
   render_box_border(left, top, (int)ceilf(pD3DFont->DrawLength(title)) + 2, ROW_HEIGHT + 2,
      D3DCOLOR_ARGB(223, 91, 91, 91), D3DCOLOR_ARGB(223, 63, 63, 63));
   pD3DFont->Print((float)(left + 1), (float)(top + 1), D3DCOLOR_XRGB(223, 223, 223), title, FT_NONE);

   /* draw window */
   left = pPresentParam.BackBufferWidth  / 2 - MENU_WIDTH / 2;
   top = pPresentParam.BackBufferHeight - MENU_HEIGHT - 1 - 16;
   render_box_border(left, top, MENU_WIDTH, MENU_HEIGHT,
      D3DCOLOR_ARGB(223, 63, 63, 63), D3DCOLOR_ARGB(223, 31, 31, 31));

   /* calculate positions */
   pos = menu_active->pos;
   top_pos = menu_active->top_pos;

   if(pos - MENU_ROWS >= top_pos)
      top_pos = pos - MENU_ROWS + 1;
   if(pos < top_pos)
      top_pos = pos;

   if(top_pos < 0)
      top_pos = 0;
   else if(top_pos >= menu_active->count)
      top_pos = menu_active->count - 1;

   menu_active->top_pos = top_pos;

   /* draw menu items */
   y = (float)top;
   x = (float)(left + 2);
   for(i=top_pos; i<top_pos+MENU_ROWS; i++,y+=pD3DFont->DrawHeight())
   {
      int enabled;

      if(i < 0 || i >= menu_active->count)
         continue;

      item = &menu_active->item[i];
      enabled = menu_active->callback(MENU_OP_ENABLED, item);

      if(i == pos)
      {
         render_box(
            left + 1, (int)floorf(y) + 1,
            MENU_WIDTH - 1, ROW_HEIGHT + 1,
            D3DCOLOR_ARGB(223, 127, 63, 63));
      }

      if(item->name[0] == '\t')
      {
         pD3DFont->Print(x, y, item->color, item->name + 1, FT_NONE);
         render_box(left + 2, (int)floorf(y) + ROW_HEIGHT - 1,
            (int)ceilf(pD3DFont->DrawLength(item->name + 1)), 1,
            D3DCOLOR_ARGB(191, 127, 127, 127));
      }
      else
      {
         /* XXX ... */
         pD3DFont->Print(x, y, enabled ? D3DCOLOR_XRGB(157, 255, 157) : item->color, item->name, FT_NONE);
      }

      if(item->submenu != NULL)
      {
         pD3DFont->Print(
            x + (float)MENU_WIDTH - pD3DFont->DrawLength(">") - 4, y,
            D3DCOLOR_ARGB(191, 127, 127, 127), ">", FT_NONE);
      }
   }
}


proxyIDirect3DDevice9::proxyIDirect3DDevice9(IDirect3DDevice9 *pOriginal)
{
   log_debug("proxyIDirect3DDevice9 constructor called. Original IDirect3DDevice9 interface address is 0x%p", pOriginal);

   origIDirect3DDevice9 = pOriginal;
   bD3DRenderInit = false;
}

proxyIDirect3DDevice9::~proxyIDirect3DDevice9(void)
{
   log_debug("proxyIDirect3DDevice9 destructor called.");
}

HRESULT proxyIDirect3DDevice9::QueryInterface(REFIID riid, void **ppvObj)
{
   HRESULT hRes;

   *ppvObj = NULL;
   hRes = origIDirect3DDevice9->QueryInterface(riid, ppvObj); 
   if(hRes == NOERROR)
      *ppvObj = this;

   return hRes;
}

ULONG proxyIDirect3DDevice9::AddRef(void)
{
   return origIDirect3DDevice9->AddRef();
}

ULONG proxyIDirect3DDevice9::Release(void)
{
   ULONG count = origIDirect3DDevice9->Release();

   if(count == 0)
   {
      pDirect3DDevice9 = NULL;
      delete(this);
   }

   return count;
}

HRESULT proxyIDirect3DDevice9::TestCooperativeLevel(void)
{
   return origIDirect3DDevice9->TestCooperativeLevel();
}

UINT proxyIDirect3DDevice9::GetAvailableTextureMem(void)
{
   return origIDirect3DDevice9->GetAvailableTextureMem();
}

HRESULT proxyIDirect3DDevice9::EvictManagedResources(void)
{
   return origIDirect3DDevice9->EvictManagedResources();
}

HRESULT proxyIDirect3DDevice9::GetDirect3D(IDirect3D9 **ppD3D9)
{
   return origIDirect3DDevice9->GetDirect3D(ppD3D9);
}

HRESULT proxyIDirect3DDevice9::GetDeviceCaps(D3DCAPS9 *pCaps)
{
   return origIDirect3DDevice9->GetDeviceCaps(pCaps);
}

HRESULT proxyIDirect3DDevice9::GetDisplayMode(UINT iSwapChain, D3DDISPLAYMODE *pMode)
{
   return origIDirect3DDevice9->GetDisplayMode(iSwapChain, pMode);
}

HRESULT proxyIDirect3DDevice9::GetCreationParameters(D3DDEVICE_CREATION_PARAMETERS *pParameters)
{
   return origIDirect3DDevice9->GetCreationParameters(pParameters);
}

HRESULT proxyIDirect3DDevice9::SetCursorProperties(UINT XHotSpot, UINT YHotSpot, IDirect3DSurface9 *pCursorBitmap)
{
   return origIDirect3DDevice9->SetCursorProperties(XHotSpot, YHotSpot, pCursorBitmap);
}

void proxyIDirect3DDevice9::SetCursorPosition(int X, int Y, DWORD Flags)
{
   return origIDirect3DDevice9->SetCursorPosition(X, Y, Flags);
}

BOOL proxyIDirect3DDevice9::ShowCursor(BOOL bShow)
{
   return origIDirect3DDevice9->ShowCursor(bShow);
}

HRESULT proxyIDirect3DDevice9::CreateAdditionalSwapChain(D3DPRESENT_PARAMETERS *pPresentationParameters, IDirect3DSwapChain9 **pSwapChain)
{
   return origIDirect3DDevice9->CreateAdditionalSwapChain(pPresentationParameters, pSwapChain);
}

HRESULT proxyIDirect3DDevice9::GetSwapChain(UINT iSwapChain, IDirect3DSwapChain9 **pSwapChain)
{
	IDirect3DSwapChain9 *pOriginal = NULL;
	HRESULT hRes;


   if(iSwapChain != 0)
      return origIDirect3DDevice9->GetSwapChain(iSwapChain, pSwapChain);
	
	if(pDirect3DSwapChain9 != NULL)
	{
      *pSwapChain = pDirect3DSwapChain9;
      return D3D_OK;
	}

	pOriginal = NULL;
	hRes = origIDirect3DDevice9->GetSwapChain(iSwapChain, &pOriginal);

	pDirect3DSwapChain9 = new proxyIDirect3DSwapChain9(pOriginal, origIDirect3DDevice9);

	*pSwapChain = pDirect3DSwapChain9;

	return hRes;
}

UINT proxyIDirect3DDevice9::GetNumberOfSwapChains(void)
{
   return origIDirect3DDevice9->GetNumberOfSwapChains();
}

HRESULT proxyIDirect3DDevice9::Reset(D3DPRESENT_PARAMETERS *pPresentationParameters)
{
   HRESULT hRet;


   log_debug("proxyIDirect3DDevice9::Reset called.");

   if(SHOULD_RENDER && bD3DRenderInit)
   {
      log_debug("Invalidating D3D renderer.");
      pD3DFont->Invalidate();
      pD3DFont_fixed->Invalidate();
      bD3DRenderInit = false;
   }

   if(set.window_mode)
   {
      log_debug("Forcing window mode.");
      pPresentationParameters->Windowed = 1;
      pPresentationParameters->Flags = 0;
      pPresentationParameters->FullScreen_RefreshRateInHz = 0;
      pPresentationParameters->PresentationInterval = 0;
   }

   hRet = origIDirect3DDevice9->Reset(pPresentationParameters);

	if(SUCCEEDED(hRet))
	{
      if(SHOULD_RENDER)
      {
         log_debug("Initializing D3D renderer.");
         pD3DFont->Initialize(pDirect3DDevice9);
         pD3DFont_fixed->Initialize(pDirect3DDevice9);
         bD3DRenderInit = true;
         log_debug("Ok.");
      }

      pPresentParam = *pPresentationParameters;

      if(set.window_mode                     &&
         pPresentParam.BackBufferWidth != 0  &&
         pPresentParam.BackBufferHeight != 0)
      {
         log_debug("Setting window parameters.");

         if(set.window_mode_titlebar)
         {
            RECT r;

            /* add caption bar, etc */
            SetWindowLong(pPresentParam.hDeviceWindow, GWL_STYLE,
               WS_POPUP | WS_CAPTION | WS_MINIMIZEBOX | WS_SYSMENU | WS_VISIBLE);

            /* update caption bar, etc */
            SetWindowPos(pPresentParam.hDeviceWindow, HWND_NOTOPMOST,
               0, 0, 0, 0,
               SWP_FRAMECHANGED | SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE);

            /* the client area of the window must be the same size as the back buffer */
            GetClientRect(pPresentParam.hDeviceWindow, &r);
            SetWindowPos(pPresentParam.hDeviceWindow, HWND_NOTOPMOST,
               0, 0,
               pPresentParam.BackBufferWidth + (pPresentParam.BackBufferWidth - r.right),
               pPresentParam.BackBufferHeight + (pPresentParam.BackBufferHeight - r.bottom),
               SWP_FRAMECHANGED | SWP_SHOWWINDOW | SWP_NOMOVE);
         }
         else
         {
            SetWindowPos(pPresentParam.hDeviceWindow, HWND_NOTOPMOST,
               0, 0, 0, 0,
               SWP_SHOWWINDOW | SWP_NOMOVE | SWP_NOSIZE);
         }
      }
	}

   log_debug("Leaving.");

	return hRet;
}

LONG WINAPI proxyUnhandledExceptionFilter(struct _EXCEPTION_POINTERS *ExceptionInfo)
{
   log_debug("Crashed inside m0d_s0beit.");
   log_debug("Base address is 0x%p, EIP is at 0x%p, Reason is %08x.",
      hDllModule,
      ExceptionInfo->ExceptionRecord->ExceptionAddress,
      ExceptionInfo->ExceptionRecord->ExceptionCode);

   return EXCEPTION_EXECUTE_HANDLER;
}

HRESULT proxyIDirect3DDevice9::Present(CONST RECT *pSourceRect, CONST RECT *pDestRect, HWND hDestWindowOverride, CONST RGNDATA *pDirtyRegion)
{
   SetUnhandledExceptionFilter(proxyUnhandledExceptionFilter);

   cheat_hook(pPresentParam.hDeviceWindow);

   /* dumb macro */
   #define TEXT_RENDER(x, color, text) \
      pD3DFont->Print(                                                                       \
         1.0f + (x), (float)(pPresentParam.BackBufferHeight - 1) - pD3DFont->DrawHeight(),   \
         (color), (text), FT_NONE);                                                          \
      (x) += pD3DFont->DrawLength(text);
   #define TEXT_RENDER_TGL(x, color, text) \
      TEXT_RENDER(x, color_text, "[");     \
      TEXT_RENDER(x, color, text);         \
      TEXT_RENDER(x, color_text, "] ")

   if(SHOULD_RENDER && bD3DRenderInit && origIDirect3DDevice9->BeginScene() == D3D_OK)
   {
      char buf[128];
      float x = 0.0f;
      uint32_t color_text = D3DCOLOR_ARGB(127, 255, 255, 255);
      uint32_t color_enabled  = D3DCOLOR_ARGB(191, 63, 255, 63);
      uint32_t color_disabled = D3DCOLOR_ARGB(191, 191, 191, 191);

      if(SUCCEEDED(CD3DBaseRender::BeginRender()))
      {
         if(set.d3dtext_hud)
         {
            if(cheat_state->state == CHEAT_STATE_NONE)
            {
               TEXT_RENDER(x, color_text, "m0d s0beit for SA:MP");
            }
            else
            {
               TEXT_RENDER_TGL(x, cheat_state->generic.hp_cheat ? color_enabled : color_disabled , "Inv");
               TEXT_RENDER_TGL(x, cheat_state->generic.weapon ? color_enabled : color_disabled , "Weapon");
               TEXT_RENDER_TGL(x, cheat_state->generic.money ? color_enabled : color_disabled , "Money");
            }

            if(cheat_state->state == CHEAT_STATE_VEHICLE)
            {
               TEXT_RENDER_TGL(x, cheat_state->vehicle.air_break ? color_enabled : color_disabled , "AirBrk");
               TEXT_RENDER_TGL(x, cheat_state->vehicle.stick ? color_enabled : color_disabled , "Stick");
               TEXT_RENDER_TGL(x, cheat_state->vehicle.protection ? color_enabled : color_disabled , "Prot");
            }

            if(cheat_state->state == CHEAT_STATE_ACTOR)
            {
               TEXT_RENDER_TGL(x, cheat_state->actor.air_break ? color_enabled : color_disabled , "AirBrk");
               TEXT_RENDER_TGL(x, cheat_state->actor.stick ? color_enabled : color_disabled , "Stick");
               TEXT_RENDER_TGL(x, cheat_state->actor.autoaim ? color_enabled : color_disabled , "Aim");
            }

            if(cheat_state->state != CHEAT_STATE_NONE)
            {
               float *coord = (cheat_state->state == CHEAT_STATE_VEHICLE) ?
                              cheat_state->vehicle.coords
                           : cheat_state->actor.coords;

               snprintf(buf, sizeof(buf), "Pos: %.2f %.2f %.2f %d", coord[0], coord[1], coord[2], gta_interior_id_get());
               TEXT_RENDER(x, color_text, buf);
            }

            if(cheat_state->text_time > 0 && time_get() - cheat_state->text_time < MSEC_TO_TIME(3000))
            {
               uint32_t color, alpha = 191;

               if(time_get() - cheat_state->text_time > MSEC_TO_TIME(2000))
                  alpha -= (time_get() - cheat_state->text_time - MSEC_TO_TIME(2000)) * 191 / MSEC_TO_TIME(1000);

               color = D3DCOLOR_ARGB(alpha, 191, 31, 31);

               TEXT_RENDER(x, color, ": ");
               TEXT_RENDER(x, color, cheat_state->text);
            }
         }  /* if(set.d3dtext_enabled) */

         if(cheat_state->generic.map)
            render_map();

         if(cheat_state->generic.menu)
            render_menu();

         if(cheat_state->debug_enabled)
            render_debug();

         CD3DBaseRender::EndRender();
      }  /* CD3DBaseRender::BeginRender() */

      origIDirect3DDevice9->EndScene();
   }  /* d3dtext */

   SetUnhandledExceptionFilter(NULL);

   return origIDirect3DDevice9->Present(pSourceRect, pDestRect, hDestWindowOverride, pDirtyRegion);
}

HRESULT proxyIDirect3DDevice9::GetBackBuffer(UINT iSwapChain, UINT iBackBuffer, D3DBACKBUFFER_TYPE Type, IDirect3DSurface9 **ppBackBuffer)
{
   return origIDirect3DDevice9->GetBackBuffer(iSwapChain, iBackBuffer, Type, ppBackBuffer);
}

HRESULT proxyIDirect3DDevice9::GetRasterStatus(UINT iSwapChain, D3DRASTER_STATUS *pRasterStatus)
{
   return origIDirect3DDevice9->GetRasterStatus(iSwapChain, pRasterStatus);
}

HRESULT proxyIDirect3DDevice9::SetDialogBoxMode(BOOL bEnableDialogs)
{
   return origIDirect3DDevice9->SetDialogBoxMode(bEnableDialogs);
}

void proxyIDirect3DDevice9::SetGammaRamp(UINT iSwapChain, DWORD Flags, CONST D3DGAMMARAMP *pRamp)
{
   origIDirect3DDevice9->SetGammaRamp(iSwapChain, Flags, pRamp);
}

void proxyIDirect3DDevice9::GetGammaRamp(UINT iSwapChain, D3DGAMMARAMP *pRamp)
{
   origIDirect3DDevice9->GetGammaRamp(iSwapChain, pRamp);
}

HRESULT proxyIDirect3DDevice9::CreateTexture(UINT Width, UINT Height, UINT Levels, DWORD Usage, D3DFORMAT Format, D3DPOOL Pool, IDirect3DTexture9 **ppTexture, HANDLE *pSharedHandle)
{
   return origIDirect3DDevice9->CreateTexture(Width, Height, Levels, Usage, Format, Pool, ppTexture, pSharedHandle);
}

HRESULT proxyIDirect3DDevice9::CreateVolumeTexture(UINT Width, UINT Height, UINT Depth, UINT Levels, DWORD Usage, D3DFORMAT Format, D3DPOOL Pool, IDirect3DVolumeTexture9 **ppVolumeTexture, HANDLE *pSharedHandle)
{
   return origIDirect3DDevice9->CreateVolumeTexture(Width, Height, Depth, Levels, Usage, Format, Pool, ppVolumeTexture, pSharedHandle);
}

HRESULT proxyIDirect3DDevice9::CreateCubeTexture(UINT EdgeLength, UINT Levels, DWORD Usage, D3DFORMAT Format, D3DPOOL Pool, IDirect3DCubeTexture9 **ppCubeTexture, HANDLE *pSharedHandle)
{
   return origIDirect3DDevice9->CreateCubeTexture(EdgeLength, Levels, Usage, Format, Pool, ppCubeTexture, pSharedHandle);
}

HRESULT proxyIDirect3DDevice9::CreateVertexBuffer(UINT Length, DWORD Usage, DWORD FVF, D3DPOOL Pool, IDirect3DVertexBuffer9 **ppVertexBuffer, HANDLE *pSharedHandle)
{
   return origIDirect3DDevice9->CreateVertexBuffer(Length, Usage, FVF, Pool, ppVertexBuffer, pSharedHandle);
}

HRESULT proxyIDirect3DDevice9::CreateIndexBuffer(UINT Length, DWORD Usage, D3DFORMAT Format, D3DPOOL Pool, IDirect3DIndexBuffer9 **ppIndexBuffer, HANDLE *pSharedHandle)
{
   return origIDirect3DDevice9->CreateIndexBuffer(Length, Usage, Format, Pool, ppIndexBuffer, pSharedHandle);
}

HRESULT proxyIDirect3DDevice9::CreateRenderTarget(UINT Width, UINT Height, D3DFORMAT Format, D3DMULTISAMPLE_TYPE MultiSample, DWORD MultisampleQuality, BOOL Lockable, IDirect3DSurface9 **ppSurface, HANDLE *pSharedHandle)
{
   return origIDirect3DDevice9->CreateRenderTarget(Width, Height, Format, MultiSample, MultisampleQuality, Lockable, ppSurface, pSharedHandle);
}

HRESULT proxyIDirect3DDevice9::CreateDepthStencilSurface(UINT Width, UINT Height, D3DFORMAT Format, D3DMULTISAMPLE_TYPE MultiSample, DWORD MultisampleQuality, BOOL Discard, IDirect3DSurface9 **ppSurface, HANDLE *pSharedHandle)
{
   return origIDirect3DDevice9->CreateDepthStencilSurface(Width, Height, Format, MultiSample, MultisampleQuality, Discard, ppSurface, pSharedHandle);
}

HRESULT proxyIDirect3DDevice9::UpdateSurface(IDirect3DSurface9 *pSourceSurface, CONST RECT *pSourceRect, IDirect3DSurface9 *pDestinationSurface, CONST POINT *pDestPoint)
{
   return origIDirect3DDevice9->UpdateSurface(pSourceSurface, pSourceRect, pDestinationSurface, pDestPoint);
}

HRESULT proxyIDirect3DDevice9::UpdateTexture(IDirect3DBaseTexture9 *pSourceTexture, IDirect3DBaseTexture9 *pDestinationTexture)
{
   return origIDirect3DDevice9->UpdateTexture(pSourceTexture, pDestinationTexture);
}

HRESULT proxyIDirect3DDevice9::GetRenderTargetData(IDirect3DSurface9 *pRenderTarget, IDirect3DSurface9 *pDestSurface)
{
   return origIDirect3DDevice9->GetRenderTargetData(pRenderTarget, pDestSurface);
}

HRESULT proxyIDirect3DDevice9::GetFrontBufferData(UINT iSwapChain, IDirect3DSurface9 *pDestSurface)
{
   return origIDirect3DDevice9->GetFrontBufferData(iSwapChain, pDestSurface);
}

HRESULT proxyIDirect3DDevice9::StretchRect(IDirect3DSurface9 *pSourceSurface, CONST RECT *pSourceRect, IDirect3DSurface9 *pDestSurface, CONST RECT *pDestRect, D3DTEXTUREFILTERTYPE Filter)
{
   return origIDirect3DDevice9->StretchRect(pSourceSurface, pSourceRect, pDestSurface, pDestRect, Filter);
}

HRESULT proxyIDirect3DDevice9::ColorFill(IDirect3DSurface9 *pSurface, CONST RECT *pRect, D3DCOLOR color)
{
   return origIDirect3DDevice9->ColorFill(pSurface, pRect, color);
}

HRESULT proxyIDirect3DDevice9::CreateOffscreenPlainSurface(UINT Width, UINT Height, D3DFORMAT Format, D3DPOOL Pool, IDirect3DSurface9 **ppSurface, HANDLE *pSharedHandle)
{
   return origIDirect3DDevice9->CreateOffscreenPlainSurface(Width, Height, Format, Pool, ppSurface, pSharedHandle);
}

HRESULT proxyIDirect3DDevice9::SetRenderTarget(DWORD RenderTargetIndex, IDirect3DSurface9 *pRenderTarget)
{
   return origIDirect3DDevice9->SetRenderTarget(RenderTargetIndex, pRenderTarget);
}

HRESULT proxyIDirect3DDevice9::GetRenderTarget(DWORD RenderTargetIndex, IDirect3DSurface9 **ppRenderTarget)
{
   return origIDirect3DDevice9->GetRenderTarget(RenderTargetIndex, ppRenderTarget);
}

HRESULT proxyIDirect3DDevice9::SetDepthStencilSurface(IDirect3DSurface9 *pNewZStencil)
{
   return origIDirect3DDevice9->SetDepthStencilSurface(pNewZStencil);
}

HRESULT proxyIDirect3DDevice9::GetDepthStencilSurface(IDirect3DSurface9 **ppZStencilSurface)
{
   return origIDirect3DDevice9->GetDepthStencilSurface(ppZStencilSurface);
}

HRESULT proxyIDirect3DDevice9::BeginScene(void)
{
   HRESULT hRet = origIDirect3DDevice9->BeginScene();

   if(SUCCEEDED(hRet) && SHOULD_RENDER && !bD3DRenderInit)
   {
      bD3DRenderInit = true;
      log_debug("Initializing D3D renderer.");
      pD3DFont->Initialize(pDirect3DDevice9);
      pD3DFont_fixed->Initialize(pDirect3DDevice9);
      log_debug("Ok.");
   }

   return hRet;
}

HRESULT proxyIDirect3DDevice9::EndScene(void)
{
   return origIDirect3DDevice9->EndScene();
}

HRESULT proxyIDirect3DDevice9::Clear(DWORD Count, CONST D3DRECT *pRects, DWORD Flags, D3DCOLOR Color, float Z, DWORD Stencil)
{
   return origIDirect3DDevice9->Clear(Count, pRects, Flags, Color, Z, Stencil);
}

HRESULT proxyIDirect3DDevice9::SetTransform(D3DTRANSFORMSTATETYPE State, CONST D3DMATRIX *pMatrix)
{
   return origIDirect3DDevice9->SetTransform(State, pMatrix);
}

HRESULT proxyIDirect3DDevice9::GetTransform(D3DTRANSFORMSTATETYPE State, D3DMATRIX *pMatrix)
{
   return origIDirect3DDevice9->GetTransform(State, pMatrix);
}

HRESULT proxyIDirect3DDevice9::MultiplyTransform(D3DTRANSFORMSTATETYPE State, CONST D3DMATRIX *pMatrix)
{
   return origIDirect3DDevice9->MultiplyTransform(State, pMatrix);
}

HRESULT proxyIDirect3DDevice9::SetViewport(CONST D3DVIEWPORT9 *pViewport)
{
   return origIDirect3DDevice9->SetViewport(pViewport);
}

HRESULT proxyIDirect3DDevice9::GetViewport(D3DVIEWPORT9 *pViewport)
{
   return origIDirect3DDevice9->GetViewport(pViewport);
}

HRESULT proxyIDirect3DDevice9::SetMaterial(CONST D3DMATERIAL9 *pMaterial)
{
   return origIDirect3DDevice9->SetMaterial(pMaterial);
}

HRESULT proxyIDirect3DDevice9::GetMaterial(D3DMATERIAL9 *pMaterial)
{
   return origIDirect3DDevice9->GetMaterial(pMaterial);
}

HRESULT proxyIDirect3DDevice9::SetLight(DWORD Index, CONST D3DLIGHT9 *pLight)
{
   return origIDirect3DDevice9->SetLight(Index, pLight);
}

HRESULT proxyIDirect3DDevice9::GetLight(DWORD Index, D3DLIGHT9 *pLight)
{
   return origIDirect3DDevice9->GetLight(Index, pLight);
}

HRESULT proxyIDirect3DDevice9::LightEnable(DWORD Index, BOOL Enable)
{
   return origIDirect3DDevice9->LightEnable(Index, Enable);
}

HRESULT proxyIDirect3DDevice9::GetLightEnable(DWORD Index, BOOL *pEnable)
{
   return origIDirect3DDevice9->GetLightEnable(Index, pEnable);
}

HRESULT proxyIDirect3DDevice9::SetClipPlane(DWORD Index, CONST float *pPlane)
{
   return origIDirect3DDevice9->SetClipPlane(Index, pPlane);
}

HRESULT proxyIDirect3DDevice9::GetClipPlane(DWORD Index, float *pPlane)
{
   return origIDirect3DDevice9->GetClipPlane(Index, pPlane);
}

HRESULT proxyIDirect3DDevice9::SetRenderState(D3DRENDERSTATETYPE State, DWORD Value)
{
   return origIDirect3DDevice9->SetRenderState(State, Value);
}

HRESULT proxyIDirect3DDevice9::GetRenderState(D3DRENDERSTATETYPE State, DWORD *pValue)
{
   return origIDirect3DDevice9->GetRenderState(State, pValue);
}

HRESULT proxyIDirect3DDevice9::CreateStateBlock(D3DSTATEBLOCKTYPE Type, IDirect3DStateBlock9 **ppSB)
{
   return origIDirect3DDevice9->CreateStateBlock(Type, ppSB);
}

HRESULT proxyIDirect3DDevice9::BeginStateBlock(void)
{
   return origIDirect3DDevice9->BeginStateBlock();
}

HRESULT proxyIDirect3DDevice9::EndStateBlock(IDirect3DStateBlock9 **ppSB)
{
   return origIDirect3DDevice9->EndStateBlock(ppSB);
}

HRESULT proxyIDirect3DDevice9::SetClipStatus(CONST D3DCLIPSTATUS9 *pClipStatus)
{
   return origIDirect3DDevice9->SetClipStatus(pClipStatus);
}

HRESULT proxyIDirect3DDevice9::GetClipStatus(D3DCLIPSTATUS9 *pClipStatus)
{
   return origIDirect3DDevice9->GetClipStatus(pClipStatus);
}

HRESULT proxyIDirect3DDevice9::GetTexture(DWORD Stage, IDirect3DBaseTexture9 **ppTexture)
{
   return origIDirect3DDevice9->GetTexture(Stage, ppTexture);
}

HRESULT proxyIDirect3DDevice9::SetTexture(DWORD Stage, IDirect3DBaseTexture9 *pTexture)
{
   return origIDirect3DDevice9->SetTexture(Stage, pTexture);
}

HRESULT proxyIDirect3DDevice9::GetTextureStageState(DWORD Stage, D3DTEXTURESTAGESTATETYPE Type, DWORD *pValue)
{
   return origIDirect3DDevice9->GetTextureStageState(Stage, Type, pValue);
}

HRESULT proxyIDirect3DDevice9::SetTextureStageState(DWORD Stage, D3DTEXTURESTAGESTATETYPE Type, DWORD Value)
{
   return origIDirect3DDevice9->SetTextureStageState(Stage, Type, Value);
}

HRESULT proxyIDirect3DDevice9::GetSamplerState(DWORD Sampler, D3DSAMPLERSTATETYPE Type, DWORD *pValue)
{
   return origIDirect3DDevice9->GetSamplerState(Sampler, Type, pValue);
}

HRESULT proxyIDirect3DDevice9::SetSamplerState(DWORD Sampler, D3DSAMPLERSTATETYPE Type, DWORD Value)
{
   return origIDirect3DDevice9->SetSamplerState(Sampler, Type, Value);
}

HRESULT proxyIDirect3DDevice9::ValidateDevice(DWORD *pNumPasses)
{
   return origIDirect3DDevice9->ValidateDevice(pNumPasses);
}

HRESULT proxyIDirect3DDevice9::SetPaletteEntries(UINT PaletteNumber, CONST PALETTEENTRY *pEntries)
{
   return origIDirect3DDevice9->SetPaletteEntries(PaletteNumber, pEntries);
}

HRESULT proxyIDirect3DDevice9::GetPaletteEntries(UINT PaletteNumber, PALETTEENTRY *pEntries)
{
   return origIDirect3DDevice9->GetPaletteEntries(PaletteNumber, pEntries);
}

HRESULT proxyIDirect3DDevice9::SetCurrentTexturePalette(UINT PaletteNumber)
{
   return origIDirect3DDevice9->SetCurrentTexturePalette(PaletteNumber);
}

HRESULT proxyIDirect3DDevice9::GetCurrentTexturePalette(UINT *PaletteNumber)
{
   return origIDirect3DDevice9->GetCurrentTexturePalette(PaletteNumber);
}

HRESULT proxyIDirect3DDevice9::SetScissorRect(CONST RECT *pRect)
{
   return origIDirect3DDevice9->SetScissorRect(pRect);
}

HRESULT proxyIDirect3DDevice9::GetScissorRect(RECT *pRect)
{
   return origIDirect3DDevice9->GetScissorRect(pRect);
}

HRESULT proxyIDirect3DDevice9::SetSoftwareVertexProcessing(BOOL bSoftware)
{
   return origIDirect3DDevice9->SetSoftwareVertexProcessing(bSoftware);
}

BOOL proxyIDirect3DDevice9::GetSoftwareVertexProcessing(void)
{
   return origIDirect3DDevice9->GetSoftwareVertexProcessing();
}

HRESULT proxyIDirect3DDevice9::SetNPatchMode(float nSegments)
{
   return origIDirect3DDevice9->SetNPatchMode(nSegments);
}

float proxyIDirect3DDevice9::GetNPatchMode(void)
{
   return origIDirect3DDevice9->GetNPatchMode();
}

HRESULT proxyIDirect3DDevice9::DrawPrimitive(D3DPRIMITIVETYPE PrimitiveType, UINT StartVertex, UINT PrimitiveCount)
{
   return origIDirect3DDevice9->DrawPrimitive(PrimitiveType, StartVertex, PrimitiveCount);
}

HRESULT proxyIDirect3DDevice9::DrawIndexedPrimitive(D3DPRIMITIVETYPE PrimitiveType, INT BaseVertexIndex, UINT MinVertexIndex, UINT NumVertices, UINT startIndex, UINT primCount)
{
	if(set.blur_remove && primCount == 360 && NumVertices == 720)
			return D3D_OK;

   return origIDirect3DDevice9->DrawIndexedPrimitive(PrimitiveType, BaseVertexIndex, MinVertexIndex, NumVertices, startIndex, primCount);
}

HRESULT proxyIDirect3DDevice9::DrawPrimitiveUP(D3DPRIMITIVETYPE PrimitiveType, UINT PrimitiveCount, CONST void *pVertexStreamZeroData, UINT VertexStreamZeroStride)
{
   return origIDirect3DDevice9->DrawPrimitiveUP(PrimitiveType, PrimitiveCount, pVertexStreamZeroData, VertexStreamZeroStride);
}

HRESULT proxyIDirect3DDevice9::DrawIndexedPrimitiveUP(D3DPRIMITIVETYPE PrimitiveType, UINT MinVertexIndex, UINT NumVertices, UINT PrimitiveCount, CONST void *pIndexData, D3DFORMAT IndexDataFormat, CONST void *pVertexStreamZeroData, UINT VertexStreamZeroStride)
{
   return origIDirect3DDevice9->DrawIndexedPrimitiveUP(PrimitiveType, MinVertexIndex, NumVertices, PrimitiveCount, pIndexData, IndexDataFormat, pVertexStreamZeroData, VertexStreamZeroStride);
}

HRESULT proxyIDirect3DDevice9::ProcessVertices(UINT SrcStartIndex, UINT DestIndex, UINT VertexCount, IDirect3DVertexBuffer9 *pDestBuffer, IDirect3DVertexDeclaration9 *pVertexDecl, DWORD Flags)
{
   return origIDirect3DDevice9->ProcessVertices(SrcStartIndex, DestIndex, VertexCount, pDestBuffer, pVertexDecl, Flags);
}

HRESULT proxyIDirect3DDevice9::CreateVertexDeclaration(CONST D3DVERTEXELEMENT9 *pVertexElements, IDirect3DVertexDeclaration9 **ppDecl)
{
   return origIDirect3DDevice9->CreateVertexDeclaration(pVertexElements, ppDecl);
}

HRESULT proxyIDirect3DDevice9::SetVertexDeclaration(IDirect3DVertexDeclaration9 *pDecl)
{
   return origIDirect3DDevice9->SetVertexDeclaration(pDecl);
}

HRESULT proxyIDirect3DDevice9::GetVertexDeclaration(IDirect3DVertexDeclaration9 **ppDecl)
{
   return origIDirect3DDevice9->GetVertexDeclaration(ppDecl);
}

HRESULT proxyIDirect3DDevice9::SetFVF(DWORD FVF)
{
   return origIDirect3DDevice9->SetFVF(FVF);
}

HRESULT proxyIDirect3DDevice9::GetFVF(DWORD *pFVF)
{
   return origIDirect3DDevice9->GetFVF(pFVF);
}

HRESULT proxyIDirect3DDevice9::CreateVertexShader(CONST DWORD *pFunction, IDirect3DVertexShader9 **ppShader)
{
   return origIDirect3DDevice9->CreateVertexShader(pFunction, ppShader);
}

HRESULT proxyIDirect3DDevice9::SetVertexShader(IDirect3DVertexShader9 *pShader)
{
   return origIDirect3DDevice9->SetVertexShader(pShader);
}

HRESULT proxyIDirect3DDevice9::GetVertexShader(IDirect3DVertexShader9 **ppShader)
{
   return origIDirect3DDevice9->GetVertexShader(ppShader);
}

HRESULT proxyIDirect3DDevice9::SetVertexShaderConstantF(UINT StartRegister, CONST float *pConstantData, UINT Vector4fCount)
{
   return origIDirect3DDevice9->SetVertexShaderConstantF(StartRegister, pConstantData, Vector4fCount);
}

HRESULT proxyIDirect3DDevice9::GetVertexShaderConstantF(UINT StartRegister, float *pConstantData, UINT Vector4fCount)
{
   return origIDirect3DDevice9->GetVertexShaderConstantF(StartRegister, pConstantData, Vector4fCount);
}

HRESULT proxyIDirect3DDevice9::SetVertexShaderConstantI(UINT StartRegister, CONST int *pConstantData, UINT Vector4iCount)
{
   return origIDirect3DDevice9->SetVertexShaderConstantI(StartRegister, pConstantData, Vector4iCount);
}

HRESULT proxyIDirect3DDevice9::GetVertexShaderConstantI(UINT StartRegister, int *pConstantData, UINT Vector4iCount)
{
   return origIDirect3DDevice9->GetVertexShaderConstantI(StartRegister, pConstantData, Vector4iCount);
}

HRESULT proxyIDirect3DDevice9::SetVertexShaderConstantB(UINT StartRegister, CONST BOOL *pConstantData, UINT  BoolCount)
{
   return origIDirect3DDevice9->SetVertexShaderConstantB(StartRegister, pConstantData, BoolCount);
}

HRESULT proxyIDirect3DDevice9::GetVertexShaderConstantB(UINT StartRegister, BOOL *pConstantData, UINT BoolCount)
{
   return origIDirect3DDevice9->GetVertexShaderConstantB(StartRegister, pConstantData, BoolCount);
}

HRESULT proxyIDirect3DDevice9::SetStreamSource(UINT StreamNumber, IDirect3DVertexBuffer9 *pStreamData, UINT OffsetInBytes, UINT Stride)
{
   return origIDirect3DDevice9->SetStreamSource(StreamNumber, pStreamData, OffsetInBytes, Stride);
}

HRESULT proxyIDirect3DDevice9::GetStreamSource(UINT StreamNumber, IDirect3DVertexBuffer9 **ppStreamData, UINT *OffsetInBytes, UINT *pStride)
{
   return origIDirect3DDevice9->GetStreamSource(StreamNumber, ppStreamData, OffsetInBytes, pStride);
}

HRESULT proxyIDirect3DDevice9::SetStreamSourceFreq(UINT StreamNumber, UINT Divider)
{
   return origIDirect3DDevice9->SetStreamSourceFreq(StreamNumber, Divider);
}

HRESULT proxyIDirect3DDevice9::GetStreamSourceFreq(UINT StreamNumber, UINT *Divider)
{
   return origIDirect3DDevice9->GetStreamSourceFreq(StreamNumber, Divider);
}

HRESULT proxyIDirect3DDevice9::SetIndices(IDirect3DIndexBuffer9 *pIndexData)
{
   return origIDirect3DDevice9->SetIndices(pIndexData);
}

HRESULT proxyIDirect3DDevice9::GetIndices(IDirect3DIndexBuffer9 **ppIndexData)
{
   return origIDirect3DDevice9->GetIndices(ppIndexData);
}

HRESULT proxyIDirect3DDevice9::CreatePixelShader(CONST DWORD *pFunction, IDirect3DPixelShader9 **ppShader)
{
   return origIDirect3DDevice9->CreatePixelShader(pFunction, ppShader);
}

HRESULT proxyIDirect3DDevice9::SetPixelShader(IDirect3DPixelShader9 *pShader)
{
   return origIDirect3DDevice9->SetPixelShader(pShader);
}

HRESULT proxyIDirect3DDevice9::GetPixelShader(IDirect3DPixelShader9 **ppShader)
{
   return origIDirect3DDevice9->GetPixelShader(ppShader);
}

HRESULT proxyIDirect3DDevice9::SetPixelShaderConstantF(UINT StartRegister, CONST float *pConstantData, UINT Vector4fCount)
{
   return origIDirect3DDevice9->SetPixelShaderConstantF(StartRegister, pConstantData, Vector4fCount);
}

HRESULT proxyIDirect3DDevice9::GetPixelShaderConstantF(UINT StartRegister, float *pConstantData, UINT Vector4fCount)
{
   return origIDirect3DDevice9->GetPixelShaderConstantF(StartRegister, pConstantData, Vector4fCount);
}

HRESULT proxyIDirect3DDevice9::SetPixelShaderConstantI(UINT StartRegister, CONST int *pConstantData, UINT Vector4iCount)
{
   return origIDirect3DDevice9->SetPixelShaderConstantI(StartRegister, pConstantData, Vector4iCount);
}

HRESULT proxyIDirect3DDevice9::GetPixelShaderConstantI(UINT StartRegister, int *pConstantData, UINT Vector4iCount)
{
   return origIDirect3DDevice9->GetPixelShaderConstantI(StartRegister, pConstantData, Vector4iCount);
}

HRESULT proxyIDirect3DDevice9::SetPixelShaderConstantB(UINT StartRegister, CONST BOOL *pConstantData, UINT  BoolCount)
{
   return origIDirect3DDevice9->SetPixelShaderConstantB(StartRegister, pConstantData, BoolCount);
}

HRESULT proxyIDirect3DDevice9::GetPixelShaderConstantB(UINT StartRegister, BOOL *pConstantData, UINT BoolCount)
{
   return origIDirect3DDevice9->GetPixelShaderConstantB(StartRegister, pConstantData, BoolCount);
}

HRESULT proxyIDirect3DDevice9::DrawRectPatch(UINT Handle, CONST float *pNumSegs, CONST D3DRECTPATCH_INFO *pRectPatchInfo)
{
   return origIDirect3DDevice9->DrawRectPatch(Handle, pNumSegs, pRectPatchInfo);
}

HRESULT proxyIDirect3DDevice9::DrawTriPatch(UINT Handle, CONST float *pNumSegs, CONST D3DTRIPATCH_INFO *pTriPatchInfo)
{
   return origIDirect3DDevice9->DrawTriPatch(Handle, pNumSegs, pTriPatchInfo);
}

HRESULT proxyIDirect3DDevice9::DeletePatch(UINT Handle)
{
   return origIDirect3DDevice9->DeletePatch(Handle);
}

HRESULT proxyIDirect3DDevice9::CreateQuery(D3DQUERYTYPE Type, IDirect3DQuery9 **ppQuery)
{
   return origIDirect3DDevice9->CreateQuery(Type, ppQuery);
}

