mirror of
https://github.com/thunderbrewhq/thunderbrew
synced 2025-12-12 03:02:30 +00:00
feat(gx): add broken cursor drawing implementation
This commit is contained in:
parent
520b6254b3
commit
9fc5476ef7
16 changed files with 423 additions and 273 deletions
|
|
@ -188,6 +188,10 @@ uint32_t GxVertexAttribOffset(EGxVertexBufferFormat format, EGxVertexAttrib attr
|
||||||
return Buffer::s_vertexBufOffset[format][attrib];
|
return Buffer::s_vertexBufOffset[format][attrib];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CGxBuf* GxBufStream(EGxPoolTarget target, uint32_t itemSize, uint32_t itemCount) {
|
||||||
|
return g_theGxDevicePtr->BufStream(target, itemSize, itemCount);
|
||||||
|
}
|
||||||
|
|
||||||
CGxBuf* GxBufCreate(CGxPool* pool, uint32_t itemSize, uint32_t itemCount, uint32_t index) {
|
CGxBuf* GxBufCreate(CGxPool* pool, uint32_t itemSize, uint32_t itemCount, uint32_t index) {
|
||||||
return g_theGxDevicePtr->BufCreate(pool, itemSize, itemCount, index);
|
return g_theGxDevicePtr->BufCreate(pool, itemSize, itemCount, index);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,8 @@ namespace Buffer {
|
||||||
|
|
||||||
uint32_t GxVertexAttribOffset(EGxVertexBufferFormat, EGxVertexAttrib);
|
uint32_t GxVertexAttribOffset(EGxVertexBufferFormat, EGxVertexAttrib);
|
||||||
|
|
||||||
|
CGxBuf* GxBufStream(EGxPoolTarget target, uint32_t itemSize, uint32_t itemCount);
|
||||||
|
|
||||||
CGxBuf* GxBufCreate(CGxPool*, uint32_t, uint32_t, uint32_t);
|
CGxBuf* GxBufCreate(CGxPool*, uint32_t, uint32_t, uint32_t);
|
||||||
|
|
||||||
void GxBufData(CGxBuf* buf, const void* data, uint32_t size, uint32_t offset);
|
void GxBufData(CGxBuf* buf, const void* data, uint32_t size, uint32_t offset);
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@ class CGxCaps {
|
||||||
int32_t m_texFilterAnisotropic = 0;
|
int32_t m_texFilterAnisotropic = 0;
|
||||||
uint32_t m_maxTexAnisotropy = 0;
|
uint32_t m_maxTexAnisotropy = 0;
|
||||||
int32_t m_depthBias = 0;
|
int32_t m_depthBias = 0;
|
||||||
|
int32_t m_hardwareCursor = 0;
|
||||||
int32_t int130 = 1;
|
int32_t int130 = 1;
|
||||||
int32_t int134 = 0;
|
int32_t int134 = 0;
|
||||||
int32_t int138 = 0;
|
int32_t int138 = 0;
|
||||||
|
|
|
||||||
|
|
@ -2,10 +2,16 @@
|
||||||
#include "gx/Gx.hpp"
|
#include "gx/Gx.hpp"
|
||||||
#include "gx/Shader.hpp"
|
#include "gx/Shader.hpp"
|
||||||
#include "gx/texture/CGxTex.hpp"
|
#include "gx/texture/CGxTex.hpp"
|
||||||
|
#include "gx/Texture.hpp"
|
||||||
|
#include "gx/RenderState.hpp"
|
||||||
|
#include "gx/Transform.hpp"
|
||||||
|
#include "gx/Draw.hpp"
|
||||||
#include "util/SFile.hpp"
|
#include "util/SFile.hpp"
|
||||||
|
#include "event/Input.hpp"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
#include <cmath>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
#include <new>
|
#include <new>
|
||||||
#include <storm/Error.hpp>
|
#include <storm/Error.hpp>
|
||||||
|
|
@ -97,6 +103,9 @@ uint32_t CGxDevice::s_texFormatBytesPerBlock[] = {
|
||||||
4 // GxTex_D24X8
|
4 // GxTex_D24X8
|
||||||
};
|
};
|
||||||
|
|
||||||
|
CGxShader* CGxDevice::s_uiVertexShader = nullptr;
|
||||||
|
CGxShader* CGxDevice::s_uiPixelShader = nullptr;
|
||||||
|
|
||||||
void CGxDevice::Log(const char* format, ...) {
|
void CGxDevice::Log(const char* format, ...) {
|
||||||
// TODO
|
// TODO
|
||||||
}
|
}
|
||||||
|
|
@ -144,6 +153,16 @@ uint32_t CGxDevice::PrimCalcCount(EGxPrim primType, uint32_t count) {
|
||||||
return count - CGxDevice::s_primVtxAdjust[primType];
|
return count - CGxDevice::s_primVtxAdjust[primType];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CGxDevice::ICursorUpdate(EGxTexCommand command, uint32_t width, uint32_t height, uint32_t face, uint32_t level, void* userArg, uint32_t& texelStrideInBytes, const void*& texels) {
|
||||||
|
// TODO
|
||||||
|
if (command == GxTex_Latch) {
|
||||||
|
auto device = static_cast<CGxDevice*>(userArg);
|
||||||
|
|
||||||
|
texelStrideInBytes = 0x80;
|
||||||
|
texels = device->m_cursor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
CGxDevice::CGxDevice() {
|
CGxDevice::CGxDevice() {
|
||||||
// TODO
|
// TODO
|
||||||
// - implement rest of constructor
|
// - implement rest of constructor
|
||||||
|
|
@ -264,7 +283,201 @@ const CRect& CGxDevice::DeviceDefWindow() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGxDevice::ICursorCreate(const CGxFormat& format) {
|
void CGxDevice::ICursorCreate(const CGxFormat& format) {
|
||||||
// TODO
|
int32_t hardwareCursor = format.hwCursor && this->m_caps.m_hardwareCursor;
|
||||||
|
|
||||||
|
this->m_hardwareCursor = hardwareCursor;
|
||||||
|
|
||||||
|
// If hardware cursor is disabled, and there is no cursor texture yet, create one
|
||||||
|
if (!hardwareCursor && this->m_cursorTexture == nullptr) {
|
||||||
|
// default flags?
|
||||||
|
CGxTexFlags cursorTextureFlags;
|
||||||
|
|
||||||
|
// Create a 32x32 cursor texture
|
||||||
|
GxTexCreate(
|
||||||
|
32,
|
||||||
|
32,
|
||||||
|
GxTex_Argb8888,
|
||||||
|
cursorTextureFlags,
|
||||||
|
reinterpret_cast<void*>(this),
|
||||||
|
CGxDevice::ICursorUpdate,
|
||||||
|
this->m_cursorTexture
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CGxDevice::ICursorDestroy() {
|
||||||
|
if (this->m_cursorTexture) {
|
||||||
|
GxTexDestroy(this->m_cursorTexture);
|
||||||
|
this->m_cursorTexture = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CGxDevice::ICursorDraw() {
|
||||||
|
if (!this->m_cursorVisible) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this->m_hardwareCursor) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t mouseX;
|
||||||
|
int32_t mouseY;
|
||||||
|
OsInputGetMousePosition(&mouseX, &mouseY);
|
||||||
|
|
||||||
|
if (mouseX <= -1 || mouseY <= -1 || mouseX >= this->m_curWindowRect.maxX || mouseY >= this->m_curWindowRect.maxY) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
GxRsPush();
|
||||||
|
// Turn off everything
|
||||||
|
GxRsSet(GxRs_PolygonOffset, 0);
|
||||||
|
GxRsSet(GxRs_NormalizeNormals, 0);
|
||||||
|
GxRsSet(GxRs_BlendingMode, 1);
|
||||||
|
GxRsSetAlphaRef();
|
||||||
|
GxRsSet(GxRs_Lighting, 0);
|
||||||
|
GxRsSet(GxRs_Fog, 0);
|
||||||
|
GxRsSet(GxRs_DepthTest, 0);
|
||||||
|
GxRsSet(GxRs_DepthWrite, 0);
|
||||||
|
GxRsSet(GxRs_ColorWrite, 15);
|
||||||
|
GxRsSet(GxRs_Culling, 0);
|
||||||
|
GxRsSet(GxRs_ClipPlaneMask, 0);
|
||||||
|
GxRsSet(GxRs_Texture0, this->m_cursorTexture);
|
||||||
|
GxRsSet(GxRs_Texture1, static_cast<CGxTex*>(nullptr));
|
||||||
|
GxRsSet(GxRs_ColorOp0, 0);
|
||||||
|
GxRsSet(GxRs_AlphaOp0, 0);
|
||||||
|
GxRsSet(GxRs_TexGen0, 0);
|
||||||
|
GxRsSet(GxRs_Unk61, 0);
|
||||||
|
|
||||||
|
C44Matrix identity;
|
||||||
|
GxXformPush(GxXform_World, identity);
|
||||||
|
|
||||||
|
float cursorDepth = 1.0f;
|
||||||
|
|
||||||
|
C44Matrix projection;
|
||||||
|
|
||||||
|
if (!this->StereoEnabled() ||
|
||||||
|
(CGxDevice::s_uiVertexShader == 0 || !s_uiVertexShader->Valid()) ||
|
||||||
|
(CGxDevice::s_uiPixelShader == 0 || !s_uiPixelShader->Valid())) {
|
||||||
|
// Disable shaders
|
||||||
|
GxRsSet(GxRs_VertexShader, static_cast<CGxShader*>(nullptr));
|
||||||
|
GxRsSet(GxRs_PixelShader, static_cast<CGxShader*>(nullptr));
|
||||||
|
} else {
|
||||||
|
cursorDepth = this->m_cursorDepth;
|
||||||
|
|
||||||
|
float minX, maxX, minY, maxY, minZ, maxZ;
|
||||||
|
GxXformViewport(minX, maxX, minY, maxY, minZ, maxZ);
|
||||||
|
|
||||||
|
GxXformProjection(projection);
|
||||||
|
|
||||||
|
C44Matrix mProj;
|
||||||
|
mProj.a0 = 2.0f / (maxX - minX);
|
||||||
|
mProj.b0 = 0.0f;
|
||||||
|
mProj.c0 = 0.0f;
|
||||||
|
mProj.d0 = -((minX + maxX) / (maxX - minX));
|
||||||
|
mProj.a1 = 0.0f;
|
||||||
|
mProj.b1 = 2.0f / (maxY - minY);
|
||||||
|
mProj.c1 = 0.0f;
|
||||||
|
mProj.d1 = -((minY + maxY) / (maxY - minY));
|
||||||
|
mProj.a2 = 0.0f;
|
||||||
|
mProj.b2 = 0.0f;
|
||||||
|
mProj.c2 = 1.00008f;
|
||||||
|
mProj.d2 = -0.400016f;
|
||||||
|
mProj.a3 = 0.0f;
|
||||||
|
mProj.b3 = 0.0f;
|
||||||
|
mProj.c3 = 1.0f;
|
||||||
|
mProj.d3 = 0.0f;
|
||||||
|
GxXformSetProjection(mProj);
|
||||||
|
|
||||||
|
GxRsSet(GxRs_VertexShader, CGxDevice::s_uiVertexShader);
|
||||||
|
GxRsSet(GxRs_PixelShader, CGxDevice::s_uiPixelShader);
|
||||||
|
|
||||||
|
C44Matrix transposition;
|
||||||
|
GxXformProjNativeTranspose(transposition);
|
||||||
|
GxShaderConstantsSet(GxSh_Vertex, 0, reinterpret_cast<float*>(&transposition), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto buffer = GxBufStream(GxPoolTarget_Vertex, sizeof(CGxVertexPCT), 4);
|
||||||
|
auto vertices = reinterpret_cast<CGxVertexPCT*>(GxBufLock(buffer));
|
||||||
|
|
||||||
|
if (!vertices) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto scaleX = this->m_curWindowRect.maxX > 0.0f ? 1.0f / this->m_curWindowRect.maxX : 0.0f;
|
||||||
|
auto scaleY = this->m_curWindowRect.maxY > 0.0f ? 1.0f / this->m_curWindowRect.maxY : 0.0f;
|
||||||
|
|
||||||
|
mouseX -= this->m_cursorHotspotX;
|
||||||
|
mouseY -= this->m_cursorHotspotY;
|
||||||
|
|
||||||
|
auto minX = std::fabsf(static_cast<float>(mouseX)) * scaleX;
|
||||||
|
auto maxX = std::fabsf(static_cast<float>(mouseX + 32)) * scaleX;
|
||||||
|
|
||||||
|
auto minY = 1.0f - (std::fabsf(static_cast<float>(mouseY)) * scaleY);
|
||||||
|
auto maxY = 1.0f - (std::fabsf(static_cast<float>(mouseY + 32)) * scaleY);
|
||||||
|
|
||||||
|
if (this->m_api == GxApi_D3d9 || this->m_api == GxApi_D3d9Ex) {
|
||||||
|
minX -= (scaleX * 0.5f);
|
||||||
|
maxX += (scaleX * 0.5f);
|
||||||
|
minY -= (scaleY * 0.5f);
|
||||||
|
maxY += (scaleY * 0.5f);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Vertex coordinates
|
||||||
|
vertices[0].p.x = minX;
|
||||||
|
vertices[0].p.y = minY;
|
||||||
|
vertices[0].p.z = cursorDepth;
|
||||||
|
|
||||||
|
vertices[1].p.x = minX;
|
||||||
|
vertices[1].p.y = maxY;
|
||||||
|
vertices[1].p.z = cursorDepth;
|
||||||
|
|
||||||
|
vertices[2].p.x = maxX;
|
||||||
|
vertices[2].p.y = minY;
|
||||||
|
vertices[2].p.z = cursorDepth;
|
||||||
|
|
||||||
|
vertices[3].p.x = maxX;
|
||||||
|
vertices[3].p.y = maxY;
|
||||||
|
vertices[3].p.z = cursorDepth;
|
||||||
|
|
||||||
|
// Color values
|
||||||
|
vertices[0].c = { 0xFF, 0xFF, 0xFF, 0xFF };
|
||||||
|
vertices[1].c = { 0xFF, 0xFF, 0xFF, 0xFF };
|
||||||
|
vertices[2].c = { 0xFF, 0xFF, 0xFF, 0xFF };
|
||||||
|
vertices[3].c = { 0xFF, 0xFF, 0xFF, 0xFF };
|
||||||
|
|
||||||
|
// Texture coordinates
|
||||||
|
vertices[0].tc[0].x = 0.0f;
|
||||||
|
vertices[0].tc[0].y = 0.0f;
|
||||||
|
|
||||||
|
vertices[1].tc[0].x = 0.0f;
|
||||||
|
vertices[1].tc[0].y = 1.0f;
|
||||||
|
|
||||||
|
vertices[2].tc[0].x = 1.0f;
|
||||||
|
vertices[2].tc[0].y = 0.0f;
|
||||||
|
|
||||||
|
vertices[3].tc[0].x = 1.0f;
|
||||||
|
vertices[3].tc[0].y = 1.0f;
|
||||||
|
|
||||||
|
GxBufUnlock(buffer, 0);
|
||||||
|
GxPrimVertexPtr(buffer, GxVBF_PCT);
|
||||||
|
|
||||||
|
CGxBatch batch;
|
||||||
|
batch.m_primType = GxPrim_TriangleStrip;
|
||||||
|
batch.m_count = 4;
|
||||||
|
batch.m_start = 0;
|
||||||
|
batch.m_minIndex = 0;
|
||||||
|
batch.m_maxIndex = 3;
|
||||||
|
|
||||||
|
GxDraw(&batch, 0);
|
||||||
|
|
||||||
|
GxXformPop(GxXform_World);
|
||||||
|
|
||||||
|
if (this->StereoEnabled()) {
|
||||||
|
GxXformSetProjection(projection);
|
||||||
|
}
|
||||||
|
|
||||||
|
GxRsPop();
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t CGxDevice::IDevIsWindowed() {
|
int32_t CGxDevice::IDevIsWindowed() {
|
||||||
|
|
@ -1030,6 +1243,12 @@ void CGxDevice::XformPush(EGxXform xf) {
|
||||||
this->m_xforms[xf].Push();
|
this->m_xforms[xf].Push();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 1-liner for Push/Set
|
||||||
|
void CGxDevice::XformPush(EGxXform xf, const C44Matrix& matrix) {
|
||||||
|
this->m_xforms[xf].Push();
|
||||||
|
this->m_xforms[xf].Top() = matrix;
|
||||||
|
}
|
||||||
|
|
||||||
void CGxDevice::XformSet(EGxXform xf, const C44Matrix& matrix) {
|
void CGxDevice::XformSet(EGxXform xf, const C44Matrix& matrix) {
|
||||||
this->m_xforms[xf].Top() = matrix;
|
this->m_xforms[xf].Top() = matrix;
|
||||||
}
|
}
|
||||||
|
|
@ -1082,3 +1301,16 @@ void CGxDevice::XformViewport(float& minX, float& maxX, float& minY, float& maxY
|
||||||
minZ = this->m_viewport.z.l;
|
minZ = this->m_viewport.z.l;
|
||||||
maxZ = this->m_viewport.z.h;
|
maxZ = this->m_viewport.z.h;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CGxDevice::CursorSetVisible(int32_t visible) {
|
||||||
|
this->m_cursorVisible = visible;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t* CGxDevice::CursorLock() {
|
||||||
|
return this->m_cursor;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CGxDevice::CursorUnlock(uint32_t x, uint32_t y) {
|
||||||
|
this->m_cursorHotspotX = x;
|
||||||
|
this->m_cursorHotspotY = y;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@
|
||||||
#include "gx/CGxStateBom.hpp"
|
#include "gx/CGxStateBom.hpp"
|
||||||
#include "gx/Types.hpp"
|
#include "gx/Types.hpp"
|
||||||
#include "gx/Shader.hpp"
|
#include "gx/Shader.hpp"
|
||||||
|
#include "cursor/Cursor.hpp"
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <storm/Hash.hpp>
|
#include <storm/Hash.hpp>
|
||||||
#include <tempest/Box.hpp>
|
#include <tempest/Box.hpp>
|
||||||
|
|
@ -46,6 +47,8 @@ class CGxDevice {
|
||||||
static uint32_t s_streamPoolSize[];
|
static uint32_t s_streamPoolSize[];
|
||||||
static uint32_t s_texFormatBitDepth[];
|
static uint32_t s_texFormatBitDepth[];
|
||||||
static uint32_t s_texFormatBytesPerBlock[];
|
static uint32_t s_texFormatBytesPerBlock[];
|
||||||
|
static CGxShader* s_uiVertexShader;
|
||||||
|
static CGxShader* s_uiPixelShader;
|
||||||
|
|
||||||
// Static functions
|
// Static functions
|
||||||
static void Log(const char* format, ...);
|
static void Log(const char* format, ...);
|
||||||
|
|
@ -62,6 +65,7 @@ class CGxDevice {
|
||||||
#endif
|
#endif
|
||||||
static CGxDevice* NewOpenGl();
|
static CGxDevice* NewOpenGl();
|
||||||
static uint32_t PrimCalcCount(EGxPrim primType, uint32_t count);
|
static uint32_t PrimCalcCount(EGxPrim primType, uint32_t count);
|
||||||
|
static void ICursorUpdate(EGxTexCommand, uint32_t, uint32_t, uint32_t, uint32_t, void*, uint32_t&, const void*&);
|
||||||
|
|
||||||
// Member variables
|
// Member variables
|
||||||
TSGrowableArray<CGxPushedRenderState> m_pushedStates;
|
TSGrowableArray<CGxPushedRenderState> m_pushedStates;
|
||||||
|
|
@ -102,11 +106,20 @@ class CGxDevice {
|
||||||
TSFixedArray<CGxAppRenderState> m_appRenderStates;
|
TSFixedArray<CGxAppRenderState> m_appRenderStates;
|
||||||
TSFixedArray<CGxStateBom> m_hwRenderStates;
|
TSFixedArray<CGxStateBom> m_hwRenderStates;
|
||||||
uint32_t m_baseMipLevel = 0; // TODO placeholder
|
uint32_t m_baseMipLevel = 0; // TODO placeholder
|
||||||
|
int32_t m_cursorVisible = 0;
|
||||||
|
int32_t m_hardwareCursor = 0;
|
||||||
|
uint32_t m_cursorHotspotX = 0;
|
||||||
|
uint32_t m_cursorHotspotY = 0;
|
||||||
|
uint32_t m_cursor[CURSOR_IMAGE_SIZE] = { 0 };
|
||||||
|
CGxTex* m_cursorTexture = nullptr;
|
||||||
|
float m_cursorDepth = 0.0f;
|
||||||
|
|
||||||
// Virtual member functions
|
// Virtual member functions
|
||||||
virtual void ITexMarkAsUpdated(CGxTex*) = 0;
|
virtual void ITexMarkAsUpdated(CGxTex*) = 0;
|
||||||
virtual void IRsSendToHw(EGxRenderState) = 0;
|
virtual void IRsSendToHw(EGxRenderState) = 0;
|
||||||
virtual void ICursorCreate(const CGxFormat& format);
|
virtual void ICursorCreate(const CGxFormat& format);
|
||||||
|
virtual void ICursorDestroy();
|
||||||
|
virtual void ICursorDraw();
|
||||||
virtual int32_t DeviceCreate(int32_t (*windowProc)(void* window, uint32_t message, uintptr_t wparam, intptr_t lparam), const CGxFormat&);
|
virtual int32_t DeviceCreate(int32_t (*windowProc)(void* window, uint32_t message, uintptr_t wparam, intptr_t lparam), const CGxFormat&);
|
||||||
virtual int32_t DeviceSetFormat(const CGxFormat&);
|
virtual int32_t DeviceSetFormat(const CGxFormat&);
|
||||||
virtual void* DeviceWindow() = 0;
|
virtual void* DeviceWindow() = 0;
|
||||||
|
|
@ -130,6 +143,9 @@ class CGxDevice {
|
||||||
virtual void ShaderConstantsSet(EGxShTarget, uint32_t, const float*, uint32_t);
|
virtual void ShaderConstantsSet(EGxShTarget, uint32_t, const float*, uint32_t);
|
||||||
virtual void IShaderCreate(CGxShader*) = 0;
|
virtual void IShaderCreate(CGxShader*) = 0;
|
||||||
virtual int32_t StereoEnabled(void) = 0;
|
virtual int32_t StereoEnabled(void) = 0;
|
||||||
|
virtual void CursorSetVisible(int32_t visible);
|
||||||
|
virtual uint32_t* CursorLock();
|
||||||
|
virtual void CursorUnlock(uint32_t x, uint32_t y);
|
||||||
|
|
||||||
// Member functions
|
// Member functions
|
||||||
CGxDevice();
|
CGxDevice();
|
||||||
|
|
@ -142,6 +158,7 @@ class CGxDevice {
|
||||||
void DeviceSetCurWindow(const CRect&);
|
void DeviceSetCurWindow(const CRect&);
|
||||||
void DeviceSetDefWindow(CRect const&);
|
void DeviceSetDefWindow(CRect const&);
|
||||||
const CRect& DeviceDefWindow(void);
|
const CRect& DeviceDefWindow(void);
|
||||||
|
void ICursorUpdate();
|
||||||
int32_t IDevIsWindowed();
|
int32_t IDevIsWindowed();
|
||||||
void IRsDirty(EGxRenderState);
|
void IRsDirty(EGxRenderState);
|
||||||
void IRsForceUpdate(void);
|
void IRsForceUpdate(void);
|
||||||
|
|
@ -173,10 +190,12 @@ class CGxDevice {
|
||||||
void XformProjection(C44Matrix&);
|
void XformProjection(C44Matrix&);
|
||||||
void XformProjNative(C44Matrix&);
|
void XformProjNative(C44Matrix&);
|
||||||
void XformPush(EGxXform xf);
|
void XformPush(EGxXform xf);
|
||||||
|
void XformPush(EGxXform xf, const C44Matrix& matrix);
|
||||||
void XformSet(EGxXform xf, const C44Matrix& matrix);
|
void XformSet(EGxXform xf, const C44Matrix& matrix);
|
||||||
void XformSetViewport(float, float, float, float, float, float);
|
void XformSetViewport(float, float, float, float, float, float);
|
||||||
void XformView(C44Matrix&);
|
void XformView(C44Matrix&);
|
||||||
void XformViewport(float&, float&, float&, float&, float&, float&);
|
void XformViewport(float&, float&, float&, float&, float&, float&);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,8 @@ class CGxFormat {
|
||||||
|
|
||||||
// Member variables
|
// Member variables
|
||||||
bool hwTnL;
|
bool hwTnL;
|
||||||
|
bool hwCursor;
|
||||||
|
bool fixLag;
|
||||||
int8_t window;
|
int8_t window;
|
||||||
int32_t maximize;
|
int32_t maximize;
|
||||||
Format depthFormat;
|
Format depthFormat;
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,11 @@ void GxXformPush(EGxXform xf) {
|
||||||
g_theGxDevicePtr->XformPush(xf);
|
g_theGxDevicePtr->XformPush(xf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 1-liner for Push/Set
|
||||||
|
void GxXformPush(EGxXform xf, const C44Matrix& matrix) {
|
||||||
|
g_theGxDevicePtr->XformPush(xf, matrix);
|
||||||
|
}
|
||||||
|
|
||||||
void GxXformSet(EGxXform xf, const C44Matrix& matrix) {
|
void GxXformSet(EGxXform xf, const C44Matrix& matrix) {
|
||||||
g_theGxDevicePtr->XformSet(xf, matrix);
|
g_theGxDevicePtr->XformSet(xf, matrix);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,8 @@ void GxXformProjNativeTranspose(C44Matrix&);
|
||||||
|
|
||||||
void GxXformPush(EGxXform xf);
|
void GxXformPush(EGxXform xf);
|
||||||
|
|
||||||
|
void GxXformPush(EGxXform xf, const C44Matrix& matrix);
|
||||||
|
|
||||||
void GxXformSet(EGxXform xf, const C44Matrix& matrix);
|
void GxXformSet(EGxXform xf, const C44Matrix& matrix);
|
||||||
|
|
||||||
void GxXformSetProjection(const C44Matrix&);
|
void GxXformSetProjection(const C44Matrix&);
|
||||||
|
|
|
||||||
|
|
@ -339,10 +339,17 @@ enum PIXEL_FORMAT {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct C4Pixel {
|
struct C4Pixel {
|
||||||
char b;
|
uint8_t b;
|
||||||
char g;
|
uint8_t g;
|
||||||
char r;
|
uint8_t r;
|
||||||
char a;
|
uint8_t a;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct C4LargePixel {
|
||||||
|
uint64_t b;
|
||||||
|
uint64_t g;
|
||||||
|
uint64_t r;
|
||||||
|
uint64_t a;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct MipBits {
|
struct MipBits {
|
||||||
|
|
|
||||||
|
|
@ -336,12 +336,7 @@ LRESULT CGxDeviceD3d::WindowProcD3d(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM
|
||||||
if (device) {
|
if (device) {
|
||||||
if (device->m_d3dDevice && lParam == 1) {
|
if (device->m_d3dDevice && lParam == 1) {
|
||||||
SetCursor(nullptr);
|
SetCursor(nullptr);
|
||||||
BOOL show = TRUE;
|
BOOL show = device->m_cursorVisible && device->m_hardwareCursor ? TRUE : FALSE;
|
||||||
// if (device->unk2904[0x13] == 0) || (device->.unk2904[0x14] == 0)) {
|
|
||||||
// show = FALSE;
|
|
||||||
// } else {
|
|
||||||
// show = TRUE;
|
|
||||||
// }
|
|
||||||
device->m_d3dDevice->ShowCursor(show);
|
device->m_d3dDevice->ShowCursor(show);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -889,6 +884,8 @@ int32_t CGxDeviceD3d::ICreateD3dDevice(const CGxFormat& format) {
|
||||||
|
|
||||||
this->IStateSetD3dDefaults();
|
this->IStateSetD3dDefaults();
|
||||||
|
|
||||||
|
this->ICursorCreate(format);
|
||||||
|
|
||||||
// TODO
|
// TODO
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
|
@ -1199,6 +1196,94 @@ void CGxDeviceD3d::IRsSendToHw(EGxRenderState which) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CGxDeviceD3d::ICursorCreate(const CGxFormat& format) {
|
||||||
|
CGxDevice::ICursorCreate(format);
|
||||||
|
|
||||||
|
if (this->m_hardwareCursor && this->m_hwCursorTexture == nullptr) {
|
||||||
|
this->m_d3dDevice->CreateTexture(
|
||||||
|
32,
|
||||||
|
32,
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
D3DFMT_A8R8G8B8,
|
||||||
|
D3DPOOL_MANAGED,
|
||||||
|
&this->m_hwCursorTexture,
|
||||||
|
nullptr);
|
||||||
|
|
||||||
|
if (this->m_hwCursorTexture) {
|
||||||
|
this->m_hwCursorTexture->GetSurfaceLevel(0, &this->m_hwCursorBitmap);
|
||||||
|
}
|
||||||
|
|
||||||
|
this->m_hwCursorNeedsUpdate = 1;
|
||||||
|
this->ICursorDraw();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CGxDeviceD3d::ICursorDestroy() {
|
||||||
|
CGxDevice::ICursorDestroy();
|
||||||
|
|
||||||
|
if (this->m_hwCursorBitmap) {
|
||||||
|
this->m_hwCursorBitmap->Release();
|
||||||
|
this->m_hwCursorBitmap = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this->m_hwCursorTexture) {
|
||||||
|
this->m_hwCursorTexture->Release();
|
||||||
|
this->m_hwCursorTexture = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CGxDeviceD3d::CursorSetVisible(int32_t visible) {
|
||||||
|
CGxDevice::CursorSetVisible(visible);
|
||||||
|
|
||||||
|
if (this->m_hardwareCursor && this->m_context) {
|
||||||
|
POINT point;
|
||||||
|
RECT rect;
|
||||||
|
GetCursorPos(&point);
|
||||||
|
ScreenToClient(this->m_hwnd, &point);
|
||||||
|
GetClientRect(this->m_hwnd, &rect);
|
||||||
|
|
||||||
|
if (rect.left <= point.x && (point.x < rect.right && (rect.top <= point.y)) && point.y < rect.bottom) {
|
||||||
|
this->m_d3dDevice->ShowCursor(this->m_cursorVisible);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CGxDeviceD3d::ICursorDraw() {
|
||||||
|
if (!this->m_hardwareCursor) {
|
||||||
|
this->ISceneBegin();
|
||||||
|
}
|
||||||
|
|
||||||
|
CGxDevice::ICursorDraw();
|
||||||
|
|
||||||
|
if (!this->m_hardwareCursor) {
|
||||||
|
this->ISceneEnd();
|
||||||
|
if (!this->m_hardwareCursor) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this->m_hwCursorNeedsUpdate && this->m_hwCursorBitmap && this->m_context) {
|
||||||
|
D3DLOCKED_RECT lockedRect;
|
||||||
|
if SUCCEEDED(this->m_hwCursorBitmap->LockRect(&lockedRect, nullptr, 0)) {
|
||||||
|
// upload cursor texture data
|
||||||
|
auto src = reinterpret_cast<uint8_t*>(this->m_cursor);
|
||||||
|
|
||||||
|
for (int32_t i = 0; i < 32; i++) {
|
||||||
|
auto dest = reinterpret_cast<uint8_t*>(lockedRect.pBits) + (lockedRect.Pitch * i);
|
||||||
|
memcpy(dest, src, 128);
|
||||||
|
src += 128;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->m_hwCursorBitmap->UnlockRect();
|
||||||
|
|
||||||
|
this->m_d3dDevice->SetCursorProperties(this->m_cursorHotspotX, this->m_cursorHotspotY, this->m_hwCursorBitmap);
|
||||||
|
}
|
||||||
|
|
||||||
|
this->m_hwCursorNeedsUpdate = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void CGxDeviceD3d::ISceneBegin() {
|
void CGxDeviceD3d::ISceneBegin() {
|
||||||
if (this->m_context) {
|
if (this->m_context) {
|
||||||
this->ShaderConstantsClear();
|
this->ShaderConstantsClear();
|
||||||
|
|
@ -1303,6 +1388,10 @@ void CGxDeviceD3d::ISetCaps(const CGxFormat& format) {
|
||||||
|
|
||||||
// TODO modify shader targets based on format
|
// TODO modify shader targets based on format
|
||||||
|
|
||||||
|
// Detect hardware cursor
|
||||||
|
|
||||||
|
this->m_caps.m_hardwareCursor = this->m_d3dCaps.CursorCaps & D3DCURSORCAPS_COLOR;
|
||||||
|
|
||||||
// Texture formats
|
// Texture formats
|
||||||
|
|
||||||
for (int32_t i = 0; i < GxTexFormats_Last; i++) {
|
for (int32_t i = 0; i < GxTexFormats_Last; i++) {
|
||||||
|
|
@ -1596,7 +1685,7 @@ void CGxDeviceD3d::IStateSync() {
|
||||||
this->IShaderConstantsFlush();
|
this->IShaderConstantsFlush();
|
||||||
this->IRsSync(0);
|
this->IRsSync(0);
|
||||||
|
|
||||||
if (this->m_hwRenderStates[GxRs_VertexShader] == nullptr && this->m_appRenderStates[GxRs_VertexShader].m_value == nullptr) {
|
if (this->m_hwRenderStates[GxRs_VertexShader] == nullptr || this->m_appRenderStates[GxRs_VertexShader].m_value == nullptr) {
|
||||||
this->IStateSyncLights();
|
this->IStateSyncLights();
|
||||||
this->IStateSyncMaterial();
|
this->IStateSyncMaterial();
|
||||||
this->IStateSyncXforms();
|
this->IStateSyncXforms();
|
||||||
|
|
@ -1734,7 +1823,9 @@ void CGxDeviceD3d::IStateSyncXforms() {
|
||||||
this->m_xforms[GxXform_View].m_dirty = 0;
|
this->m_xforms[GxXform_View].m_dirty = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO world
|
if (this->m_xforms[GxXform_World].m_dirty) {
|
||||||
|
this->IXformSetWorld();
|
||||||
|
}
|
||||||
|
|
||||||
// TODO tex
|
// TODO tex
|
||||||
}
|
}
|
||||||
|
|
@ -1932,6 +2023,7 @@ UNLOCK:
|
||||||
|
|
||||||
void CGxDeviceD3d::IXformSetProjection(const C44Matrix& matrix) {
|
void CGxDeviceD3d::IXformSetProjection(const C44Matrix& matrix) {
|
||||||
#if defined(_MSC_VER)
|
#if defined(_MSC_VER)
|
||||||
|
// This is the correct way
|
||||||
DirectX::XMMATRIX projNative;
|
DirectX::XMMATRIX projNative;
|
||||||
memcpy(&projNative, &matrix, sizeof(projNative));
|
memcpy(&projNative, &matrix, sizeof(projNative));
|
||||||
|
|
||||||
|
|
@ -1966,6 +2058,8 @@ void CGxDeviceD3d::IXformSetProjection(const C44Matrix& matrix) {
|
||||||
this->m_xforms[GxXform_Projection].m_dirty = 1;
|
this->m_xforms[GxXform_Projection].m_dirty = 1;
|
||||||
memcpy(&this->m_projNative, &projNative, sizeof(this->m_projNative));
|
memcpy(&this->m_projNative, &projNative, sizeof(this->m_projNative));
|
||||||
#else
|
#else
|
||||||
|
// Without the DirectX::XMMATRIX, we can soldier on
|
||||||
|
// with a Tempest matrix
|
||||||
C44Matrix projNative;
|
C44Matrix projNative;
|
||||||
memcpy(&projNative, &matrix, sizeof(projNative));
|
memcpy(&projNative, &matrix, sizeof(projNative));
|
||||||
|
|
||||||
|
|
@ -2026,6 +2120,19 @@ void CGxDeviceD3d::IXformSetViewport() {
|
||||||
this->intF6C = 0;
|
this->intF6C = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CGxDeviceD3d::IXformSetWorld() {
|
||||||
|
static int32_t isIdent = 0;
|
||||||
|
|
||||||
|
auto& stack = this->m_xforms[GxXform_World];
|
||||||
|
|
||||||
|
if (!isIdent || !(stack.m_flags[stack.m_level] & CGxMatrixStack::F_Identity)) {
|
||||||
|
this->m_d3dDevice->SetTransform(D3DTS_WORLD, reinterpret_cast<const D3DMATRIX*>(&stack.TopConst()));
|
||||||
|
}
|
||||||
|
|
||||||
|
isIdent = stack.m_flags[stack.m_level] & CGxMatrixStack::F_Identity;
|
||||||
|
stack.m_dirty = 0;
|
||||||
|
}
|
||||||
|
|
||||||
void CGxDeviceD3d::PoolSizeSet(CGxPool* pool, uint32_t size) {
|
void CGxDeviceD3d::PoolSizeSet(CGxPool* pool, uint32_t size) {
|
||||||
// TODO
|
// TODO
|
||||||
}
|
}
|
||||||
|
|
@ -2059,6 +2166,8 @@ void CGxDeviceD3d::ScenePresent() {
|
||||||
CGxDevice::ScenePresent();
|
CGxDevice::ScenePresent();
|
||||||
this->ISceneEnd();
|
this->ISceneEnd();
|
||||||
|
|
||||||
|
this->ICursorDraw();
|
||||||
|
|
||||||
// TODO
|
// TODO
|
||||||
|
|
||||||
// TODO fixLag
|
// TODO fixLag
|
||||||
|
|
@ -2092,3 +2201,4 @@ void CGxDeviceD3d::XformSetProjection(const C44Matrix& matrix) {
|
||||||
CGxDevice::XformSetProjection(matrix);
|
CGxDevice::XformSetProjection(matrix);
|
||||||
this->IXformSetProjection(matrix);
|
this->IXformSetProjection(matrix);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -235,6 +235,9 @@ class CGxDeviceD3d : public CGxDevice {
|
||||||
D3DFORMAT m_devAdapterFormat;
|
D3DFORMAT m_devAdapterFormat;
|
||||||
LPDIRECT3DSURFACE9 m_defColorSurface = nullptr;
|
LPDIRECT3DSURFACE9 m_defColorSurface = nullptr;
|
||||||
LPDIRECT3DSURFACE9 m_defDepthSurface = nullptr;
|
LPDIRECT3DSURFACE9 m_defDepthSurface = nullptr;
|
||||||
|
int32_t m_hwCursorNeedsUpdate = 1;
|
||||||
|
LPDIRECT3DTEXTURE9 m_hwCursorTexture = nullptr;
|
||||||
|
LPDIRECT3DSURFACE9 m_hwCursorBitmap = nullptr;
|
||||||
LPDIRECT3DVERTEXDECLARATION9 m_d3dCurrentVertexDecl;
|
LPDIRECT3DVERTEXDECLARATION9 m_d3dCurrentVertexDecl;
|
||||||
LPDIRECT3DINDEXBUFFER9 m_d3dCurrentIndexBuf;
|
LPDIRECT3DINDEXBUFFER9 m_d3dCurrentIndexBuf;
|
||||||
LPDIRECT3DVERTEXBUFFER9 m_d3dVertexStreamBuf[8];
|
LPDIRECT3DVERTEXBUFFER9 m_d3dVertexStreamBuf[8];
|
||||||
|
|
@ -245,6 +248,10 @@ class CGxDeviceD3d : public CGxDevice {
|
||||||
// Virtual member functions
|
// Virtual member functions
|
||||||
virtual void ITexMarkAsUpdated(CGxTex* texId);
|
virtual void ITexMarkAsUpdated(CGxTex* texId);
|
||||||
virtual void IRsSendToHw(EGxRenderState which);
|
virtual void IRsSendToHw(EGxRenderState which);
|
||||||
|
virtual void ICursorCreate(const CGxFormat& format);
|
||||||
|
virtual void ICursorDestroy();
|
||||||
|
virtual void ICursorDraw();
|
||||||
|
virtual void CursorSetVisible(int32_t visible);
|
||||||
virtual int32_t DeviceCreate(int32_t (*windowProc)(void* window, uint32_t message, uintptr_t wparam, intptr_t lparam), const CGxFormat& format);
|
virtual int32_t DeviceCreate(int32_t (*windowProc)(void* window, uint32_t message, uintptr_t wparam, intptr_t lparam), const CGxFormat& format);
|
||||||
virtual int32_t DeviceSetFormat(const CGxFormat& format);
|
virtual int32_t DeviceSetFormat(const CGxFormat& format);
|
||||||
virtual void* DeviceWindow();
|
virtual void* DeviceWindow();
|
||||||
|
|
@ -302,6 +309,7 @@ class CGxDeviceD3d : public CGxDevice {
|
||||||
void ITexUpload(CGxTex* texId);
|
void ITexUpload(CGxTex* texId);
|
||||||
void IXformSetProjection(const C44Matrix& matrix);
|
void IXformSetProjection(const C44Matrix& matrix);
|
||||||
void IXformSetViewport();
|
void IXformSetViewport();
|
||||||
|
void IXformSetWorld();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -703,6 +703,8 @@ void CGxDeviceGLL::ISetCaps(const CGxFormat& format) {
|
||||||
this->m_caps.m_texMaxSize[GxTex_Rectangle] = 4096;
|
this->m_caps.m_texMaxSize[GxTex_Rectangle] = 4096;
|
||||||
this->m_caps.m_texMaxSize[GxTex_NonPow2] = 4096;
|
this->m_caps.m_texMaxSize[GxTex_NonPow2] = 4096;
|
||||||
|
|
||||||
|
this->m_caps.m_hardwareCursor = 0;
|
||||||
|
|
||||||
// TODO
|
// TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -320,7 +320,7 @@ int32_t CGxDeviceGLSDL::DeviceSetFormat(const CGxFormat& format) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void* CGxDeviceGLSDL::DeviceWindow() {
|
void* CGxDeviceGLSDL::DeviceWindow() {
|
||||||
return &this->m_GLSDLWindow;
|
return this->m_GLSDLWindow.m_sdlWindow;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGxDeviceGLSDL::Draw(CGxBatch* batch, int32_t indexed) {
|
void CGxDeviceGLSDL::Draw(CGxBatch* batch, int32_t indexed) {
|
||||||
|
|
@ -681,6 +681,8 @@ void CGxDeviceGLSDL::ISetCaps(const CGxFormat& format) {
|
||||||
this->m_caps.m_texMaxSize[GxTex_Rectangle] = 4096;
|
this->m_caps.m_texMaxSize[GxTex_Rectangle] = 4096;
|
||||||
this->m_caps.m_texMaxSize[GxTex_NonPow2] = 4096;
|
this->m_caps.m_texMaxSize[GxTex_NonPow2] = 4096;
|
||||||
|
|
||||||
|
this->m_caps.m_hardwareCursor = 0;
|
||||||
|
|
||||||
// TODO
|
// TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -926,7 +928,17 @@ void CGxDeviceGLSDL::IStateSyncVertexPtrs() {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CGxDeviceGLSDL::IXformSetWorld() {
|
||||||
|
auto& stack = this->m_xforms[GxXform_World];
|
||||||
|
this->m_GLSDLDevice.SetTransform('WRLD', reinterpret_cast<const float*>(&stack.TopConst()));
|
||||||
|
stack.m_dirty = 0;
|
||||||
|
}
|
||||||
|
|
||||||
void CGxDeviceGLSDL::IStateSyncXforms() {
|
void CGxDeviceGLSDL::IStateSyncXforms() {
|
||||||
|
if (this->m_xforms[GxXform_World].m_dirty) {
|
||||||
|
this->IXformSetWorld();
|
||||||
|
}
|
||||||
|
|
||||||
// TODO this->IXformSetWorld();
|
// TODO this->IXformSetWorld();
|
||||||
// TODO this->IXformSetTex();
|
// TODO this->IXformSetTex();
|
||||||
|
|
||||||
|
|
@ -1268,13 +1280,13 @@ void CGxDeviceGLSDL::SceneClear(uint32_t mask, CImVector color) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGxDeviceGLSDL::ScenePresent() {
|
void CGxDeviceGLSDL::ScenePresent() {
|
||||||
this->m_GLSDLWindow.DispatchEvents();
|
|
||||||
|
|
||||||
if (this->m_context) {
|
if (this->m_context) {
|
||||||
// TODO
|
// TODO
|
||||||
|
|
||||||
CGxDevice::ScenePresent();
|
CGxDevice::ScenePresent();
|
||||||
|
|
||||||
|
this->ICursorDraw();
|
||||||
|
|
||||||
// TODO
|
// TODO
|
||||||
|
|
||||||
this->m_GLSDLDevice.Swap();
|
this->m_GLSDLDevice.Swap();
|
||||||
|
|
|
||||||
|
|
@ -74,6 +74,7 @@ class CGxDeviceGLSDL : public CGxDevice {
|
||||||
void IXformSetProjection(const C44Matrix&);
|
void IXformSetProjection(const C44Matrix&);
|
||||||
void IXformSetView(const C44Matrix&);
|
void IXformSetView(const C44Matrix&);
|
||||||
void IXformSetViewport();
|
void IXformSetViewport();
|
||||||
|
void IXformSetWorld();
|
||||||
void PatchPixelShader(CGxShader*);
|
void PatchPixelShader(CGxShader*);
|
||||||
void PatchVertexShader(CGxShader*);
|
void PatchVertexShader(CGxShader*);
|
||||||
void Resize(uint32_t width, uint32_t height);
|
void Resize(uint32_t width, uint32_t height);
|
||||||
|
|
|
||||||
|
|
@ -12,136 +12,6 @@
|
||||||
|
|
||||||
static bool s_GLSDL_Initialized = false;
|
static bool s_GLSDL_Initialized = false;
|
||||||
|
|
||||||
static const std::map<SDL_Scancode, KEY> s_keyConversion = {
|
|
||||||
{SDL_SCANCODE_LSHIFT, KEY_LSHIFT},
|
|
||||||
{SDL_SCANCODE_RSHIFT, KEY_RSHIFT},
|
|
||||||
{SDL_SCANCODE_LCTRL, KEY_LCONTROL},
|
|
||||||
{SDL_SCANCODE_RCTRL, KEY_RCONTROL},
|
|
||||||
{SDL_SCANCODE_LALT, KEY_LALT},
|
|
||||||
{SDL_SCANCODE_RALT, KEY_RALT},
|
|
||||||
{SDL_SCANCODE_SPACE, KEY_SPACE},
|
|
||||||
{SDL_SCANCODE_0, KEY_0},
|
|
||||||
{SDL_SCANCODE_1, KEY_1},
|
|
||||||
{SDL_SCANCODE_2, KEY_2},
|
|
||||||
{SDL_SCANCODE_3, KEY_3},
|
|
||||||
{SDL_SCANCODE_4, KEY_4},
|
|
||||||
{SDL_SCANCODE_5, KEY_5},
|
|
||||||
{SDL_SCANCODE_6, KEY_6},
|
|
||||||
{SDL_SCANCODE_7, KEY_7},
|
|
||||||
{SDL_SCANCODE_8, KEY_8},
|
|
||||||
{SDL_SCANCODE_9, KEY_9},
|
|
||||||
{SDL_SCANCODE_A, KEY_A},
|
|
||||||
{SDL_SCANCODE_B, KEY_B},
|
|
||||||
{SDL_SCANCODE_C, KEY_C},
|
|
||||||
{SDL_SCANCODE_D, KEY_D},
|
|
||||||
{SDL_SCANCODE_E, KEY_E},
|
|
||||||
{SDL_SCANCODE_F, KEY_F},
|
|
||||||
{SDL_SCANCODE_G, KEY_G},
|
|
||||||
{SDL_SCANCODE_H, KEY_H},
|
|
||||||
{SDL_SCANCODE_I, KEY_I},
|
|
||||||
{SDL_SCANCODE_J, KEY_J},
|
|
||||||
{SDL_SCANCODE_K, KEY_K},
|
|
||||||
{SDL_SCANCODE_L, KEY_L},
|
|
||||||
{SDL_SCANCODE_M, KEY_M},
|
|
||||||
{SDL_SCANCODE_N, KEY_N},
|
|
||||||
{SDL_SCANCODE_O, KEY_O},
|
|
||||||
{SDL_SCANCODE_P, KEY_P},
|
|
||||||
{SDL_SCANCODE_Q, KEY_Q},
|
|
||||||
{SDL_SCANCODE_R, KEY_R},
|
|
||||||
{SDL_SCANCODE_S, KEY_S},
|
|
||||||
{SDL_SCANCODE_T, KEY_T},
|
|
||||||
{SDL_SCANCODE_U, KEY_U},
|
|
||||||
{SDL_SCANCODE_V, KEY_V},
|
|
||||||
{SDL_SCANCODE_W, KEY_W},
|
|
||||||
{SDL_SCANCODE_X, KEY_X},
|
|
||||||
{SDL_SCANCODE_Y, KEY_Y},
|
|
||||||
{SDL_SCANCODE_Z, KEY_Z},
|
|
||||||
{SDL_SCANCODE_GRAVE, KEY_TILDE},
|
|
||||||
{SDL_SCANCODE_KP_0, KEY_NUMPAD0},
|
|
||||||
{SDL_SCANCODE_KP_1, KEY_NUMPAD1},
|
|
||||||
{SDL_SCANCODE_KP_2, KEY_NUMPAD2},
|
|
||||||
{SDL_SCANCODE_KP_3, KEY_NUMPAD3},
|
|
||||||
{SDL_SCANCODE_KP_4, KEY_NUMPAD4},
|
|
||||||
{SDL_SCANCODE_KP_5, KEY_NUMPAD5},
|
|
||||||
{SDL_SCANCODE_KP_6, KEY_NUMPAD6},
|
|
||||||
{SDL_SCANCODE_KP_7, KEY_NUMPAD7},
|
|
||||||
{SDL_SCANCODE_KP_8, KEY_NUMPAD8},
|
|
||||||
{SDL_SCANCODE_KP_9, KEY_NUMPAD9},
|
|
||||||
{SDL_SCANCODE_KP_PLUS, KEY_NUMPAD_PLUS},
|
|
||||||
{SDL_SCANCODE_KP_MINUS, KEY_NUMPAD_MINUS},
|
|
||||||
{SDL_SCANCODE_KP_MULTIPLY, KEY_NUMPAD_MULTIPLY},
|
|
||||||
{SDL_SCANCODE_KP_DIVIDE, KEY_NUMPAD_DIVIDE},
|
|
||||||
{SDL_SCANCODE_KP_DECIMAL, KEY_NUMPAD_DECIMAL},
|
|
||||||
{SDL_SCANCODE_KP_EQUALS, KEY_NUMPAD_EQUALS},
|
|
||||||
{SDL_SCANCODE_EQUALS, KEY_PLUS},
|
|
||||||
{SDL_SCANCODE_MINUS, KEY_MINUS},
|
|
||||||
{SDL_SCANCODE_LEFTBRACKET, KEY_BRACKET_OPEN},
|
|
||||||
{SDL_SCANCODE_RIGHTBRACKET, KEY_BRACKET_CLOSE},
|
|
||||||
{SDL_SCANCODE_SLASH, KEY_SLASH},
|
|
||||||
{SDL_SCANCODE_BACKSLASH, KEY_BACKSLASH},
|
|
||||||
{SDL_SCANCODE_SEMICOLON, KEY_SEMICOLON},
|
|
||||||
{SDL_SCANCODE_APOSTROPHE, KEY_APOSTROPHE},
|
|
||||||
{SDL_SCANCODE_COMMA, KEY_COMMA},
|
|
||||||
{SDL_SCANCODE_PERIOD, KEY_PERIOD},
|
|
||||||
{SDL_SCANCODE_ESCAPE, KEY_ESCAPE},
|
|
||||||
{SDL_SCANCODE_RETURN, KEY_ENTER},
|
|
||||||
{SDL_SCANCODE_BACKSPACE, KEY_BACKSPACE},
|
|
||||||
{SDL_SCANCODE_TAB, KEY_TAB},
|
|
||||||
{SDL_SCANCODE_LEFT, KEY_LEFT},
|
|
||||||
{SDL_SCANCODE_UP, KEY_UP},
|
|
||||||
{SDL_SCANCODE_RIGHT, KEY_RIGHT},
|
|
||||||
{SDL_SCANCODE_DOWN, KEY_DOWN},
|
|
||||||
{SDL_SCANCODE_INSERT, KEY_INSERT},
|
|
||||||
{SDL_SCANCODE_DELETE, KEY_DELETE},
|
|
||||||
{SDL_SCANCODE_HOME, KEY_HOME},
|
|
||||||
{SDL_SCANCODE_END, KEY_END},
|
|
||||||
{SDL_SCANCODE_PAGEUP, KEY_PAGEUP},
|
|
||||||
{SDL_SCANCODE_PAGEDOWN, KEY_PAGEDOWN},
|
|
||||||
{SDL_SCANCODE_CAPSLOCK, KEY_CAPSLOCK},
|
|
||||||
{SDL_SCANCODE_NUMLOCKCLEAR, KEY_NUMLOCK},
|
|
||||||
{SDL_SCANCODE_SCROLLLOCK, KEY_SCROLLLOCK},
|
|
||||||
{SDL_SCANCODE_PAUSE, KEY_PAUSE},
|
|
||||||
{SDL_SCANCODE_PRINTSCREEN, KEY_PRINTSCREEN},
|
|
||||||
{SDL_SCANCODE_F1, KEY_F1},
|
|
||||||
{SDL_SCANCODE_F2, KEY_F2},
|
|
||||||
{SDL_SCANCODE_F3, KEY_F3},
|
|
||||||
{SDL_SCANCODE_F4, KEY_F4},
|
|
||||||
{SDL_SCANCODE_F5, KEY_F5},
|
|
||||||
{SDL_SCANCODE_F6, KEY_F6},
|
|
||||||
{SDL_SCANCODE_F7, KEY_F7},
|
|
||||||
{SDL_SCANCODE_F8, KEY_F8},
|
|
||||||
{SDL_SCANCODE_F9, KEY_F9},
|
|
||||||
{SDL_SCANCODE_F10, KEY_F10},
|
|
||||||
{SDL_SCANCODE_F11, KEY_F11},
|
|
||||||
{SDL_SCANCODE_F12, KEY_F12},
|
|
||||||
{SDL_SCANCODE_F13, KEY_F13},
|
|
||||||
{SDL_SCANCODE_F14, KEY_F14},
|
|
||||||
{SDL_SCANCODE_F15, KEY_F15},
|
|
||||||
{SDL_SCANCODE_F16, KEY_F16},
|
|
||||||
{SDL_SCANCODE_F17, KEY_F17},
|
|
||||||
{SDL_SCANCODE_F18, KEY_F18},
|
|
||||||
{SDL_SCANCODE_F19, KEY_F19}
|
|
||||||
};
|
|
||||||
|
|
||||||
static MOUSEBUTTON s_buttonConversion[16] = {
|
|
||||||
MOUSE_BUTTON_NONE,
|
|
||||||
MOUSE_BUTTON_LEFT,
|
|
||||||
MOUSE_BUTTON_MIDDLE,
|
|
||||||
MOUSE_BUTTON_RIGHT,
|
|
||||||
MOUSE_BUTTON_XBUTTON1,
|
|
||||||
MOUSE_BUTTON_XBUTTON2,
|
|
||||||
MOUSE_BUTTON_XBUTTON3,
|
|
||||||
MOUSE_BUTTON_XBUTTON4,
|
|
||||||
MOUSE_BUTTON_XBUTTON5,
|
|
||||||
MOUSE_BUTTON_XBUTTON6,
|
|
||||||
MOUSE_BUTTON_XBUTTON7,
|
|
||||||
MOUSE_BUTTON_XBUTTON8,
|
|
||||||
MOUSE_BUTTON_XBUTTON9,
|
|
||||||
MOUSE_BUTTON_XBUTTON10,
|
|
||||||
MOUSE_BUTTON_XBUTTON11,
|
|
||||||
MOUSE_BUTTON_XBUTTON12
|
|
||||||
};
|
|
||||||
|
|
||||||
void GLSDLWindow::Create(const char* title, const GLSDLWindowRect& rect, GLTextureFormat depthFormat, uint32_t sampleCount) {
|
void GLSDLWindow::Create(const char* title, const GLSDLWindowRect& rect, GLTextureFormat depthFormat, uint32_t sampleCount) {
|
||||||
BLIZZARD_ASSERT(this->m_sdlWindow == nullptr);
|
BLIZZARD_ASSERT(this->m_sdlWindow == nullptr);
|
||||||
|
|
||||||
|
|
@ -213,13 +83,6 @@ void GLSDLWindow::Swap() {
|
||||||
SDL_GL_SwapWindow(this->m_sdlWindow);
|
SDL_GL_SwapWindow(this->m_sdlWindow);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLSDLWindow::DispatchEvents() {
|
|
||||||
SDL_Event event;
|
|
||||||
while (SDL_PollEvent(&event)) {
|
|
||||||
this->DispatchSDLEvent(event);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void GLSDLWindow::Destroy() {
|
void GLSDLWindow::Destroy() {
|
||||||
SDL_DestroyWindow(this->m_sdlWindow);
|
SDL_DestroyWindow(this->m_sdlWindow);
|
||||||
this->m_sdlWindow = nullptr;
|
this->m_sdlWindow = nullptr;
|
||||||
|
|
@ -275,116 +138,3 @@ int32_t GLSDLWindow::GetHeight() {
|
||||||
return this->GetBackingRect().size.height;
|
return this->GetBackingRect().size.height;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLSDLWindow::DispatchSDLEvent(const SDL_Event& event) {
|
|
||||||
switch (event.type) {
|
|
||||||
case SDL_KEYDOWN:
|
|
||||||
case SDL_KEYUP:
|
|
||||||
this->DispatchSDLKeyboardEvent(event);
|
|
||||||
break;
|
|
||||||
case SDL_MOUSEBUTTONDOWN:
|
|
||||||
case SDL_MOUSEBUTTONUP:
|
|
||||||
this->DispatchSDLMouseButtonEvent(event);
|
|
||||||
break;
|
|
||||||
case SDL_MOUSEMOTION:
|
|
||||||
this->DispatchSDLMouseMotionEvent(event);
|
|
||||||
break;
|
|
||||||
case SDL_TEXTINPUT:
|
|
||||||
this->DispatchSDLTextInputEvent(event);
|
|
||||||
break;
|
|
||||||
case SDL_WINDOWEVENT_RESIZED:
|
|
||||||
this->DispatchSDLWindowResizedEvent(event);
|
|
||||||
break;
|
|
||||||
case SDL_QUIT:
|
|
||||||
EventPostClose();
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void GLSDLWindow::DispatchSDLKeyboardEvent(const SDL_Event& event) {
|
|
||||||
// Is this an up or down keypress?
|
|
||||||
OSINPUT inputclass = event.type == SDL_KEYUP ? OS_INPUT_KEY_UP : OS_INPUT_KEY_DOWN;
|
|
||||||
|
|
||||||
// What key does this SDL scancode correspond to?
|
|
||||||
auto lookup = s_keyConversion.find(event.key.keysym.scancode);
|
|
||||||
if (lookup != s_keyConversion.end()) {
|
|
||||||
// Scancode was found
|
|
||||||
KEY key = lookup->second;
|
|
||||||
|
|
||||||
// Push key event into input queue
|
|
||||||
OsQueuePut(inputclass, key, 0, 0, 0);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void GLSDLWindow::DispatchSDLMouseMotionEvent(const SDL_Event& event) {
|
|
||||||
auto x = static_cast<int32_t>(event.motion.x);
|
|
||||||
auto y = static_cast<int32_t>(event.motion.y);
|
|
||||||
|
|
||||||
OsQueuePut(OS_INPUT_MOUSE_MOVE, 0, x, y, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void GLSDLWindow::DispatchSDLMouseButtonEvent(const SDL_Event& event) {
|
|
||||||
// Is this an up or down mouse click?
|
|
||||||
OSINPUT inputclass = event.type == SDL_MOUSEBUTTONUP ? OS_INPUT_MOUSE_UP : OS_INPUT_MOUSE_DOWN;
|
|
||||||
|
|
||||||
// XY click coordinates
|
|
||||||
auto x = static_cast<int32_t>(event.button.x);
|
|
||||||
auto y = static_cast<int32_t>(event.button.y);
|
|
||||||
|
|
||||||
// Convert SDL button index into internal MOUSEBUTTON ID
|
|
||||||
auto buttonIndex = event.button.button;
|
|
||||||
if (buttonIndex > 15) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
auto button = s_buttonConversion[buttonIndex];
|
|
||||||
|
|
||||||
// Push mousebutton event into input queue
|
|
||||||
OsQueuePut(inputclass, button, x, y, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void GLSDLWindow::DispatchSDLTextInputEvent(const SDL_Event& event) {
|
|
||||||
// text input string holding one or more UTF-8 characters
|
|
||||||
auto text = reinterpret_cast<const uint8_t*>(event.text.text);
|
|
||||||
|
|
||||||
// Because SDL_TextInputEvent can hold multiple UTF-8 characters
|
|
||||||
// explode variable number of these characters into
|
|
||||||
// individual OS_INPUT_CHAR events
|
|
||||||
while (*text != '\0') {
|
|
||||||
// byte size of current UTF-8 character
|
|
||||||
int32_t charactersize = 0;
|
|
||||||
|
|
||||||
// Read UTF-8 character
|
|
||||||
auto character = static_cast<int32_t>(SUniSGetUTF8(text, &charactersize));
|
|
||||||
if (character < 0) {
|
|
||||||
// Cancel in case of invalid input
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Push character to input queue
|
|
||||||
OsQueuePut(OS_INPUT_CHAR, character, 1, 0, 0);
|
|
||||||
|
|
||||||
// Advance text pointer
|
|
||||||
text += charactersize;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void GLSDLWindow::DispatchSDLWindowResizedEvent(const SDL_Event& event) {
|
|
||||||
auto width = static_cast<int32_t>(event.window.data1);
|
|
||||||
auto height = static_cast<int32_t>(event.window.data2);
|
|
||||||
|
|
||||||
static_cast<CGxDeviceGLSDL*>(g_theGxDevicePtr)->Resize(width, height);
|
|
||||||
|
|
||||||
OsQueuePut(OS_INPUT_SIZE, width, height, 0, 0);
|
|
||||||
|
|
||||||
auto bounds = GetSavedWindowBounds();
|
|
||||||
Rect newBounds = {
|
|
||||||
bounds->top,
|
|
||||||
bounds->left,
|
|
||||||
static_cast<int16_t>(bounds->top + height),
|
|
||||||
static_cast<int16_t>(bounds->left + width)
|
|
||||||
};
|
|
||||||
SetSavedWindowBounds(newBounds);
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -30,13 +30,6 @@ class GLSDLWindow {
|
||||||
void Create(const char* title, const GLSDLWindowRect& rect, GLTextureFormat depthFormat, uint32_t sampleCount);
|
void Create(const char* title, const GLSDLWindowRect& rect, GLTextureFormat depthFormat, uint32_t sampleCount);
|
||||||
void Destroy();
|
void Destroy();
|
||||||
void Swap();
|
void Swap();
|
||||||
void DispatchEvents();
|
|
||||||
void DispatchSDLEvent(const SDL_Event& event);
|
|
||||||
void DispatchSDLKeyboardEvent(const SDL_Event& event);
|
|
||||||
void DispatchSDLMouseMotionEvent(const SDL_Event& event);
|
|
||||||
void DispatchSDLMouseButtonEvent(const SDL_Event& event);
|
|
||||||
void DispatchSDLTextInputEvent(const SDL_Event& event);
|
|
||||||
void DispatchSDLWindowResizedEvent(const SDL_Event& event);
|
|
||||||
void Resize(const GLSDLWindowRect& rect);
|
void Resize(const GLSDLWindowRect& rect);
|
||||||
|
|
||||||
GLSDLWindowRect GetRect();
|
GLSDLWindowRect GetRect();
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue