mirror of
https://github.com/thunderbrewhq/thunderbrew
synced 2025-04-09 23:06:47 +03:00
feat(gx): add broken cursor drawing implementation
This commit is contained in:
parent
520b6254b3
commit
9fc5476ef7
@ -188,6 +188,10 @@ uint32_t GxVertexAttribOffset(EGxVertexBufferFormat format, EGxVertexAttrib attr
|
||||
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) {
|
||||
return g_theGxDevicePtr->BufCreate(pool, itemSize, itemCount, index);
|
||||
}
|
||||
|
@ -25,6 +25,8 @@ namespace Buffer {
|
||||
|
||||
uint32_t GxVertexAttribOffset(EGxVertexBufferFormat, EGxVertexAttrib);
|
||||
|
||||
CGxBuf* GxBufStream(EGxPoolTarget target, uint32_t itemSize, uint32_t itemCount);
|
||||
|
||||
CGxBuf* GxBufCreate(CGxPool*, uint32_t, uint32_t, uint32_t);
|
||||
|
||||
void GxBufData(CGxBuf* buf, const void* data, uint32_t size, uint32_t offset);
|
||||
|
@ -22,6 +22,7 @@ class CGxCaps {
|
||||
int32_t m_texFilterAnisotropic = 0;
|
||||
uint32_t m_maxTexAnisotropy = 0;
|
||||
int32_t m_depthBias = 0;
|
||||
int32_t m_hardwareCursor = 0;
|
||||
int32_t int130 = 1;
|
||||
int32_t int134 = 0;
|
||||
int32_t int138 = 0;
|
||||
|
@ -2,10 +2,16 @@
|
||||
#include "gx/Gx.hpp"
|
||||
#include "gx/Shader.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 "event/Input.hpp"
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
#include <cstdio>
|
||||
#include <cmath>
|
||||
#include <limits>
|
||||
#include <new>
|
||||
#include <storm/Error.hpp>
|
||||
@ -97,6 +103,9 @@ uint32_t CGxDevice::s_texFormatBytesPerBlock[] = {
|
||||
4 // GxTex_D24X8
|
||||
};
|
||||
|
||||
CGxShader* CGxDevice::s_uiVertexShader = nullptr;
|
||||
CGxShader* CGxDevice::s_uiPixelShader = nullptr;
|
||||
|
||||
void CGxDevice::Log(const char* format, ...) {
|
||||
// TODO
|
||||
}
|
||||
@ -144,6 +153,16 @@ uint32_t CGxDevice::PrimCalcCount(EGxPrim primType, uint32_t count) {
|
||||
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() {
|
||||
// TODO
|
||||
// - implement rest of constructor
|
||||
@ -264,7 +283,201 @@ const CRect& CGxDevice::DeviceDefWindow() {
|
||||
}
|
||||
|
||||
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() {
|
||||
@ -1030,6 +1243,12 @@ void CGxDevice::XformPush(EGxXform xf) {
|
||||
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) {
|
||||
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;
|
||||
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/Types.hpp"
|
||||
#include "gx/Shader.hpp"
|
||||
#include "cursor/Cursor.hpp"
|
||||
#include <cstdint>
|
||||
#include <storm/Hash.hpp>
|
||||
#include <tempest/Box.hpp>
|
||||
@ -46,6 +47,8 @@ class CGxDevice {
|
||||
static uint32_t s_streamPoolSize[];
|
||||
static uint32_t s_texFormatBitDepth[];
|
||||
static uint32_t s_texFormatBytesPerBlock[];
|
||||
static CGxShader* s_uiVertexShader;
|
||||
static CGxShader* s_uiPixelShader;
|
||||
|
||||
// Static functions
|
||||
static void Log(const char* format, ...);
|
||||
@ -62,6 +65,7 @@ class CGxDevice {
|
||||
#endif
|
||||
static CGxDevice* NewOpenGl();
|
||||
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
|
||||
TSGrowableArray<CGxPushedRenderState> m_pushedStates;
|
||||
@ -102,11 +106,20 @@ class CGxDevice {
|
||||
TSFixedArray<CGxAppRenderState> m_appRenderStates;
|
||||
TSFixedArray<CGxStateBom> m_hwRenderStates;
|
||||
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 void ITexMarkAsUpdated(CGxTex*) = 0;
|
||||
virtual void IRsSendToHw(EGxRenderState) = 0;
|
||||
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 DeviceSetFormat(const CGxFormat&);
|
||||
virtual void* DeviceWindow() = 0;
|
||||
@ -130,6 +143,9 @@ class CGxDevice {
|
||||
virtual void ShaderConstantsSet(EGxShTarget, uint32_t, const float*, uint32_t);
|
||||
virtual void IShaderCreate(CGxShader*) = 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
|
||||
CGxDevice();
|
||||
@ -142,6 +158,7 @@ class CGxDevice {
|
||||
void DeviceSetCurWindow(const CRect&);
|
||||
void DeviceSetDefWindow(CRect const&);
|
||||
const CRect& DeviceDefWindow(void);
|
||||
void ICursorUpdate();
|
||||
int32_t IDevIsWindowed();
|
||||
void IRsDirty(EGxRenderState);
|
||||
void IRsForceUpdate(void);
|
||||
@ -173,10 +190,12 @@ class CGxDevice {
|
||||
void XformProjection(C44Matrix&);
|
||||
void XformProjNative(C44Matrix&);
|
||||
void XformPush(EGxXform xf);
|
||||
void XformPush(EGxXform xf, const C44Matrix& matrix);
|
||||
void XformSet(EGxXform xf, const C44Matrix& matrix);
|
||||
void XformSetViewport(float, float, float, float, float, float);
|
||||
void XformView(C44Matrix&);
|
||||
void XformViewport(float&, float&, float&, float&, float&, float&);
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -21,6 +21,8 @@ class CGxFormat {
|
||||
|
||||
// Member variables
|
||||
bool hwTnL;
|
||||
bool hwCursor;
|
||||
bool fixLag;
|
||||
int8_t window;
|
||||
int32_t maximize;
|
||||
Format depthFormat;
|
||||
|
@ -31,6 +31,11 @@ void GxXformPush(EGxXform 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) {
|
||||
g_theGxDevicePtr->XformSet(xf, matrix);
|
||||
}
|
||||
|
@ -16,6 +16,8 @@ void GxXformProjNativeTranspose(C44Matrix&);
|
||||
|
||||
void GxXformPush(EGxXform xf);
|
||||
|
||||
void GxXformPush(EGxXform xf, const C44Matrix& matrix);
|
||||
|
||||
void GxXformSet(EGxXform xf, const C44Matrix& matrix);
|
||||
|
||||
void GxXformSetProjection(const C44Matrix&);
|
||||
|
@ -339,10 +339,17 @@ enum PIXEL_FORMAT {
|
||||
};
|
||||
|
||||
struct C4Pixel {
|
||||
char b;
|
||||
char g;
|
||||
char r;
|
||||
char a;
|
||||
uint8_t b;
|
||||
uint8_t g;
|
||||
uint8_t r;
|
||||
uint8_t a;
|
||||
};
|
||||
|
||||
struct C4LargePixel {
|
||||
uint64_t b;
|
||||
uint64_t g;
|
||||
uint64_t r;
|
||||
uint64_t a;
|
||||
};
|
||||
|
||||
struct MipBits {
|
||||
|
@ -336,12 +336,7 @@ LRESULT CGxDeviceD3d::WindowProcD3d(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM
|
||||
if (device) {
|
||||
if (device->m_d3dDevice && lParam == 1) {
|
||||
SetCursor(nullptr);
|
||||
BOOL show = TRUE;
|
||||
// if (device->unk2904[0x13] == 0) || (device->.unk2904[0x14] == 0)) {
|
||||
// show = FALSE;
|
||||
// } else {
|
||||
// show = TRUE;
|
||||
// }
|
||||
BOOL show = device->m_cursorVisible && device->m_hardwareCursor ? TRUE : FALSE;
|
||||
device->m_d3dDevice->ShowCursor(show);
|
||||
}
|
||||
}
|
||||
@ -889,6 +884,8 @@ int32_t CGxDeviceD3d::ICreateD3dDevice(const CGxFormat& format) {
|
||||
|
||||
this->IStateSetD3dDefaults();
|
||||
|
||||
this->ICursorCreate(format);
|
||||
|
||||
// TODO
|
||||
|
||||
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() {
|
||||
if (this->m_context) {
|
||||
this->ShaderConstantsClear();
|
||||
@ -1303,6 +1388,10 @@ void CGxDeviceD3d::ISetCaps(const CGxFormat& format) {
|
||||
|
||||
// TODO modify shader targets based on format
|
||||
|
||||
// Detect hardware cursor
|
||||
|
||||
this->m_caps.m_hardwareCursor = this->m_d3dCaps.CursorCaps & D3DCURSORCAPS_COLOR;
|
||||
|
||||
// Texture formats
|
||||
|
||||
for (int32_t i = 0; i < GxTexFormats_Last; i++) {
|
||||
@ -1596,7 +1685,7 @@ void CGxDeviceD3d::IStateSync() {
|
||||
this->IShaderConstantsFlush();
|
||||
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->IStateSyncMaterial();
|
||||
this->IStateSyncXforms();
|
||||
@ -1734,7 +1823,9 @@ void CGxDeviceD3d::IStateSyncXforms() {
|
||||
this->m_xforms[GxXform_View].m_dirty = 0;
|
||||
}
|
||||
|
||||
// TODO world
|
||||
if (this->m_xforms[GxXform_World].m_dirty) {
|
||||
this->IXformSetWorld();
|
||||
}
|
||||
|
||||
// TODO tex
|
||||
}
|
||||
@ -1932,6 +2023,7 @@ UNLOCK:
|
||||
|
||||
void CGxDeviceD3d::IXformSetProjection(const C44Matrix& matrix) {
|
||||
#if defined(_MSC_VER)
|
||||
// This is the correct way
|
||||
DirectX::XMMATRIX projNative;
|
||||
memcpy(&projNative, &matrix, sizeof(projNative));
|
||||
|
||||
@ -1966,6 +2058,8 @@ void CGxDeviceD3d::IXformSetProjection(const C44Matrix& matrix) {
|
||||
this->m_xforms[GxXform_Projection].m_dirty = 1;
|
||||
memcpy(&this->m_projNative, &projNative, sizeof(this->m_projNative));
|
||||
#else
|
||||
// Without the DirectX::XMMATRIX, we can soldier on
|
||||
// with a Tempest matrix
|
||||
C44Matrix projNative;
|
||||
memcpy(&projNative, &matrix, sizeof(projNative));
|
||||
|
||||
@ -2026,6 +2120,19 @@ void CGxDeviceD3d::IXformSetViewport() {
|
||||
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) {
|
||||
// TODO
|
||||
}
|
||||
@ -2059,6 +2166,8 @@ void CGxDeviceD3d::ScenePresent() {
|
||||
CGxDevice::ScenePresent();
|
||||
this->ISceneEnd();
|
||||
|
||||
this->ICursorDraw();
|
||||
|
||||
// TODO
|
||||
|
||||
// TODO fixLag
|
||||
@ -2092,3 +2201,4 @@ void CGxDeviceD3d::XformSetProjection(const C44Matrix& matrix) {
|
||||
CGxDevice::XformSetProjection(matrix);
|
||||
this->IXformSetProjection(matrix);
|
||||
}
|
||||
|
||||
|
@ -235,6 +235,9 @@ class CGxDeviceD3d : public CGxDevice {
|
||||
D3DFORMAT m_devAdapterFormat;
|
||||
LPDIRECT3DSURFACE9 m_defColorSurface = nullptr;
|
||||
LPDIRECT3DSURFACE9 m_defDepthSurface = nullptr;
|
||||
int32_t m_hwCursorNeedsUpdate = 1;
|
||||
LPDIRECT3DTEXTURE9 m_hwCursorTexture = nullptr;
|
||||
LPDIRECT3DSURFACE9 m_hwCursorBitmap = nullptr;
|
||||
LPDIRECT3DVERTEXDECLARATION9 m_d3dCurrentVertexDecl;
|
||||
LPDIRECT3DINDEXBUFFER9 m_d3dCurrentIndexBuf;
|
||||
LPDIRECT3DVERTEXBUFFER9 m_d3dVertexStreamBuf[8];
|
||||
@ -245,6 +248,10 @@ class CGxDeviceD3d : public CGxDevice {
|
||||
// Virtual member functions
|
||||
virtual void ITexMarkAsUpdated(CGxTex* texId);
|
||||
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 DeviceSetFormat(const CGxFormat& format);
|
||||
virtual void* DeviceWindow();
|
||||
@ -302,6 +309,7 @@ class CGxDeviceD3d : public CGxDevice {
|
||||
void ITexUpload(CGxTex* texId);
|
||||
void IXformSetProjection(const C44Matrix& matrix);
|
||||
void IXformSetViewport();
|
||||
void IXformSetWorld();
|
||||
};
|
||||
|
||||
#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_NonPow2] = 4096;
|
||||
|
||||
this->m_caps.m_hardwareCursor = 0;
|
||||
|
||||
// TODO
|
||||
}
|
||||
|
||||
|
@ -320,7 +320,7 @@ int32_t CGxDeviceGLSDL::DeviceSetFormat(const CGxFormat& format) {
|
||||
}
|
||||
|
||||
void* CGxDeviceGLSDL::DeviceWindow() {
|
||||
return &this->m_GLSDLWindow;
|
||||
return this->m_GLSDLWindow.m_sdlWindow;
|
||||
}
|
||||
|
||||
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_NonPow2] = 4096;
|
||||
|
||||
this->m_caps.m_hardwareCursor = 0;
|
||||
|
||||
// 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() {
|
||||
if (this->m_xforms[GxXform_World].m_dirty) {
|
||||
this->IXformSetWorld();
|
||||
}
|
||||
|
||||
// TODO this->IXformSetWorld();
|
||||
// TODO this->IXformSetTex();
|
||||
|
||||
@ -1268,13 +1280,13 @@ void CGxDeviceGLSDL::SceneClear(uint32_t mask, CImVector color) {
|
||||
}
|
||||
|
||||
void CGxDeviceGLSDL::ScenePresent() {
|
||||
this->m_GLSDLWindow.DispatchEvents();
|
||||
|
||||
if (this->m_context) {
|
||||
// TODO
|
||||
|
||||
CGxDevice::ScenePresent();
|
||||
|
||||
this->ICursorDraw();
|
||||
|
||||
// TODO
|
||||
|
||||
this->m_GLSDLDevice.Swap();
|
||||
|
@ -74,6 +74,7 @@ class CGxDeviceGLSDL : public CGxDevice {
|
||||
void IXformSetProjection(const C44Matrix&);
|
||||
void IXformSetView(const C44Matrix&);
|
||||
void IXformSetViewport();
|
||||
void IXformSetWorld();
|
||||
void PatchPixelShader(CGxShader*);
|
||||
void PatchVertexShader(CGxShader*);
|
||||
void Resize(uint32_t width, uint32_t height);
|
||||
|
@ -12,136 +12,6 @@
|
||||
|
||||
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) {
|
||||
BLIZZARD_ASSERT(this->m_sdlWindow == nullptr);
|
||||
|
||||
@ -213,13 +83,6 @@ void GLSDLWindow::Swap() {
|
||||
SDL_GL_SwapWindow(this->m_sdlWindow);
|
||||
}
|
||||
|
||||
void GLSDLWindow::DispatchEvents() {
|
||||
SDL_Event event;
|
||||
while (SDL_PollEvent(&event)) {
|
||||
this->DispatchSDLEvent(event);
|
||||
}
|
||||
}
|
||||
|
||||
void GLSDLWindow::Destroy() {
|
||||
SDL_DestroyWindow(this->m_sdlWindow);
|
||||
this->m_sdlWindow = nullptr;
|
||||
@ -275,116 +138,3 @@ int32_t GLSDLWindow::GetHeight() {
|
||||
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 Destroy();
|
||||
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);
|
||||
|
||||
GLSDLWindowRect GetRect();
|
||||
|
Loading…
Reference in New Issue
Block a user