From 441d4a0698c2a34736f195157c763974e4c592ff Mon Sep 17 00:00:00 2001
From: twinaphex <autechre1024@hotmail.com>
Date: Tue, 12 Mar 2013 02:42:33 +0100
Subject: [PATCH] (Xbox 1) Initial RGUI code - incomplete

---
 gfx/context/xdk_ctx.c |   4 ++
 xdk/xdk_d3d.cpp       | 108 ++++++++++++++++++++++++++++++++++++++++++
 xdk/xdk_d3d.h         |   2 +
 3 files changed, 114 insertions(+)

diff --git a/gfx/context/xdk_ctx.c b/gfx/context/xdk_ctx.c
index d418bf49db..714a02123b 100644
--- a/gfx/context/xdk_ctx.c
+++ b/gfx/context/xdk_ctx.c
@@ -327,6 +327,10 @@ static void gfx_ctx_xdk_destroy(void)
 {
    xdk_d3d_video_t * d3d = (xdk_d3d_video_t*)driver.video_data;
 
+#ifdef HAVE_RGUI
+   texture_image_free(&d3d->rgui_texture);
+#endif
+
    if (d3d->d3d_render_device)
    {
       d3d->d3d_render_device->Release();
diff --git a/xdk/xdk_d3d.cpp b/xdk/xdk_d3d.cpp
index 05266fdf84..f8bb2e5163 100644
--- a/xdk/xdk_d3d.cpp
+++ b/xdk/xdk_d3d.cpp
@@ -113,6 +113,42 @@ const DWORD g_MapLinearToSrgbGpuFormat[] =
 };
 #endif
 
+#ifdef HAVE_RGUI
+static bool xdk_d3d_init_rgui_texture(void *data)
+{
+   xdk_d3d_video_t *d3d = (xdk_d3d_video_t*)data;
+   struct texture_image *out_img = &d3d->rgui_texture;
+   out_img->pixels      = NULL;
+   out_img->vertex_buf  = NULL;
+
+   HRESULT ret = D3DXCreateTexture(d3d->d3d_render_device,
+         RGUI_WIDTH, RGUI_HEIGHT, D3DX_DEFAULT, 0, D3DFMT_A4R4G4B4,
+         D3DPOOL_MANAGED, &out_img->pixels);
+
+   if(FAILED(ret))
+   {
+      RARCH_ERR("Error occurred during D3DXCreateTexture (RGUI texture init).\n");
+      return false;
+   }
+
+   // create a vertex buffer for the quad that will display the texture
+   ret = d3d->d3d_render_device->CreateVertexBuffer(4 * sizeof(DrawVerticeFormats),
+         D3DUSAGE_WRITEONLY, D3DFVF_CUSTOMVERTEX, D3DPOOL_MANAGED, &out_img->vertex_buf);
+
+   if (FAILED(ret))
+   {
+      RARCH_ERR("Error occurred during CreateVertexBuffer().\n");
+      out_img->pixels->Release();
+      return false;
+   }
+
+   out_img->width = RGUI_WIDTH;
+   out_img->height = RGUI_HEIGHT;
+
+   return true;
+}
+#endif
+
 static void check_window(void *data)
 {
    xdk_d3d_video_t *d3d = (xdk_d3d_video_t*)data;
@@ -479,6 +515,10 @@ static void xdk_d3d_init_textures(void *data, const video_info_t *video)
       return;
    }
 
+#ifdef HAVE_RGUI
+   xdk_d3d_init_rgui_texture(d3d);
+#endif
+
    D3DLOCKED_RECT d3dlr;
    d3d->lpTexture->LockRect(0, &d3dlr, NULL, D3DLOCK_NOSYSLOCK);
    memset(d3dlr.pBits, 0, d3d->tex_w * d3dlr.Pitch);
@@ -528,6 +568,10 @@ static void xdk_d3d_reinit_textures(void *data, const video_info_t *video)
       RARCH_LOG("Reinitializing textures (%u x %u @ %u bpp)\n", d3d->tex_w,
             d3d->tex_h, d3d->base_size * CHAR_BIT);
 
+#ifdef HAVE_RGUI
+      texture_image_free(&d3d->rgui_texture);
+#endif
+
       xdk_d3d_init_textures(d3d, video);
 
 #ifdef HAVE_FBO
@@ -692,6 +736,65 @@ static void *xdk_d3d_init(const video_info_t *video, const input_driver_t **inpu
    return d3d;
 }
 
+#ifdef HAVE_RGUI
+static inline void xdk_d3d_draw_rgui(void *data)
+{
+   xdk_d3d_video_t *d3d = (xdk_d3d_video_t*)driver.video_data;
+
+   if (out_img->pixels == NULL || out_img->vertex_buf == NULL)
+      return false;
+
+   int x = out_img->x;
+   int y = out_img->y;
+   int w = out_img->width;
+   int h = out_img->height;
+
+   float fX = static_cast<float>(x);
+   float fY = static_cast<float>(y);
+
+   // create the new vertices
+   DrawVerticeFormats newVerts[] =
+   {
+      // x,           y,              z,     color, u ,v
+      {fX,            fY,             0.0f,  0,     0, 0},
+      {fX + w,        fY,             0.0f,  0,     1, 0},
+      {fX + w,        fY + h,         0.0f,  0,     1, 1},
+      {fX,            fY + h,         0.0f,  0,     0, 1}
+   };
+
+   // load the existing vertices
+   DrawVerticeFormats *pCurVerts;
+
+   HRESULT ret = out_img->vertex_buf->Lock(0, 0, (unsigned char**)&pCurVerts, 0);
+
+   if (FAILED(ret))
+   {
+      RARCH_ERR("[RGUI Draw] - Error occurred during m_pVertexBuffer->Lock().\n");
+      return;
+   }
+
+   // copy the new verts over the old verts
+   memcpy(pCurVerts, newVerts, 4 * sizeof(DrawVerticeFormats));
+
+   out_img->vertex_buf->Unlock();
+
+   d3d->d3d_render_device->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
+   d3d->d3d_render_device->SetRenderState(D3DRS_SRCBLEND,  D3DBLEND_SRCALPHA);
+   d3d->d3d_render_device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
+
+   // also blend the texture with the set alpha value
+   d3d->d3d_render_device->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
+   d3d->d3d_render_device->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
+   d3d->d3d_render_device->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_TEXTURE);
+
+   // draw the quad
+   d3d->d3d_render_device->SetTexture(0, out_img->pixels);
+   d3d->d3d_render_device->SetStreamSource(0, out_img->vertex_buf, sizeof(DrawVerticeFormats));
+   d3d->d3d_render_device->SetVertexShader(D3DFVF_CUSTOMVERTEX);
+   d3d->d3d_render_device->DrawPrimitive(D3DPT_QUADLIST, 0, 1);
+}
+#endif
+
 static bool xdk_d3d_frame(void *data, const void *frame,
       unsigned width, unsigned height, unsigned pitch, const char *msg)
 {
@@ -871,6 +974,11 @@ static bool xdk_d3d_frame(void *data, const void *frame,
    float msg_width  = mem_width;
    float msg_height = mem_height + 50;
 #endif
+
+#ifdef HAVE_RGUI
+   if (d3d->rgui_data)
+      xd_d3d_draw_rgui(d3d);
+#endif
    font_params_t font_parms = {0};
 
    if (lifecycle_mode_state & (1ULL << MODE_FPS_DRAW))
diff --git a/xdk/xdk_d3d.h b/xdk/xdk_d3d.h
index a2fb2ce44a..061393c033 100644
--- a/xdk/xdk_d3d.h
+++ b/xdk/xdk_d3d.h
@@ -21,6 +21,7 @@
 #ifdef _XBOX1
 #include <xfont.h>
 #endif
+#include "../gfx/image.h"
 #include "../gfx/fonts/d3d_font.h"
 
 #include "../gfx/gfx_context.h"
@@ -74,6 +75,7 @@ typedef struct xdk_d3d_video
    IDirect3DVertexDeclaration9* v_decl;
 #endif
 #ifdef HAVE_RGUI
+   texture_image rgui_texture;
    const void *rgui_data;
 #endif
    const d3d_font_renderer_t *font_ctx;