feat(console): hardware detection et cetera

This commit is contained in:
phaneron 2025-04-12 04:35:49 -04:00
parent 97bbe2ea66
commit 31f215ea14
118 changed files with 4059 additions and 1931 deletions

View file

@ -22,7 +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 m_hwCursor = 0;
int32_t int130 = 1;
int32_t int134 = 0;
int32_t int138 = 0;

View file

@ -8,27 +8,36 @@
#include "gx/Transform.hpp"
#include "gx/Draw.hpp"
#include "util/SFile.hpp"
#include "event/Input.hpp"
#include "os/Input.hpp"
#include <storm/Error.hpp>
#include <bc/Memory.hpp>
#include <bc/os/File.hpp>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <limits>
#include <storm/Error.hpp>
#include <bc/Memory.hpp>
#if defined(WHOA_SYSTEM_WIN)
#include "gx/d3d/CGxDeviceD3d.hpp"
#include "gx/d3d/CGxDeviceD3d.hpp"
#endif
#if defined(WHOA_BUILD_GLSDL)
#include "gx/glsdl/CGxDeviceGLSDL.hpp"
#include <SDL3/SDL.h>
#include "gx/glsdl/CGxDeviceGLSDL.hpp"
#endif
#if defined(WHOA_SYSTEM_MAC)
#include "gx/gll/CGxDeviceGLL.hpp"
#endif
HSLOG CGxDevice::m_log;
uint32_t CGxDevice::m_logBytes;
uint32_t CGxDevice::s_alphaRef[] = {
0, // GxBlend_Opaque
224, // GxBlend_AlphaKey
@ -106,23 +115,331 @@ uint32_t CGxDevice::s_texFormatBytesPerBlock[] = {
CGxShader* CGxDevice::s_uiVertexShader = nullptr;
CGxShader* CGxDevice::s_uiPixelShader = nullptr;
void CGxDevice::LogOpen() {
#if defined(WHOA_SYSTEM_WIN)
uint16_t HToI(const char* h, uint32_t count) {
uint32_t i = 0;
while (count) {
auto cur = *h;
--count;
i *= 16;
++h;
if (isxdigit(cur)) {
if (isdigit(cur)) {
i += cur - '0';
} else {
i += toupper(cur) - '7';
}
}
}
return i;
}
int32_t CGxDevice::AdapterID(uint16_t& vendorID, uint16_t& deviceID, uint32_t& driverVersionHi, uint32_t& driverVersionLow) {
int32_t result = 0;
vendorID = 0xFFFF;
deviceID = 0xFFFF;
driverVersionHi = 0;
driverVersionLow = 0;
DISPLAY_DEVICE dd;
memset(&dd, 0, sizeof(dd));
dd.cb = sizeof(DISPLAY_DEVICE);
DWORD device = 0;
while (EnumDisplayDevices(0, device, &dd, 0)) {
if (dd.StateFlags & 4) {
break;
}
device++;
}
uint16_t vI;
uint16_t dI;
if (strlen(dd.DeviceID) > 20 && (vI = HToI(&dd.DeviceID[8], 4)) && (dI = HToI(&dd.DeviceID[17], 4))) {
vendorID = vI;
deviceID = dI;
result = true;
} else {
HINSTANCE d3dLib = nullptr;
LPDIRECT3D9 d3d = nullptr;
if (CGxDeviceD3d::ILoadD3dLib(d3dLib, d3d)) {
D3DADAPTER_IDENTIFIER9 d3dadapterid;
if (d3d->GetAdapterIdentifier(0, 0, &d3dadapterid) >= D3D_OK) {
vendorID = d3dadapterid.VendorId;
deviceID = d3dadapterid.DeviceId;
driverVersionLow = d3dadapterid.DriverVersion.LowPart;
driverVersionHi = d3dadapterid.DriverVersion.HighPart;
result = true;
}
CGxDeviceD3d::IUnloadD3dLib(d3dLib, d3d);
}
}
// NOTE: this doesn't appear to be a typo on our part
Log("CGxDevice::DeviceAdapterID(): RET: %d, VID: %x, DID: %x, DVER: %x.%x", result, vendorID, deviceID, driverVersionHi, driverVersionLow);
return result;
}
int32_t CGxDevice::AdapterInfer(uint16_t& deviceID) {
HINSTANCE d3dLib;
LPDIRECT3D9 d3d;
D3DCAPS9 d3dcaps;
int32_t result = 0;
if (!CGxDeviceD3d::ILoadD3dLib(d3dLib, d3d)) {
return result;
}
if (d3d->GetDeviceCaps(0, D3DDEVTYPE_HAL, &d3dcaps) == D3D_OK) {
if ((d3dcaps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) != 0 && d3dcaps.MaxSimultaneousTextures > 2 && d3dcaps.PixelShaderVersion >= 0x200) {
deviceID = 3;
result = 1;
} else if ((d3dcaps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) != 0) {
if (d3dcaps.MaxSimultaneousTextures > 2 && d3dcaps.PixelShaderVersion >= 0x101) {
deviceID = 2;
result = 1;
} else if (d3dcaps.MaxSimultaneousTextures >= 2) {
deviceID = 1;
result = 1;
}
} else {
deviceID = 0;
result = 1;
}
}
CGxDeviceD3d::IUnloadD3dLib(d3dLib, d3d);
Log("CGxDevice::DeviceAdapterInfer(): RET: %d, DID: %x", result, deviceID);
return result;
}
// TODO: replace this invented name
int32_t FindDisplayDevice(PDISPLAY_DEVICE device, uint32_t flag) {
DWORD i = 0;
device->cb = sizeof(DISPLAY_DEVICE);
while (EnumDisplayDevices(nullptr, i, device, 0)) {
if ((device->StateFlags & flag) == flag) {
return 1;
}
}
return 0;
}
int32_t CGxDevice::AdapterMonitorModes(TSGrowableArray<CGxMonitorMode>& modes) {
modes.SetCount(0);
DISPLAY_DEVICE device;
if (!FindDisplayDevice(&device, DISPLAY_DEVICE_PRIMARY_DEVICE)) {
return 0;
}
DEVMODE dm;
dm.dmSize = sizeof(DEVMODE);
DWORD i = 0;
while (EnumDisplaySettings(device.DeviceName, i, &dm)) {
if ((dm.dmPelsWidth >= 640 && dm.dmPelsHeight >= 480)
&& dm.dmBitsPerPel >= 16) {
auto mode = modes.New();
mode->size.x = dm.dmPelsWidth;
mode->size.y = dm.dmPelsHeight;
mode->bpp = dm.dmBitsPerPel;
mode->refreshRate = dm.dmDisplayFrequency;
}
i++;
}
qsort(modes.Ptr(), modes.Count(), sizeof(CGxMonitorMode), CGxMonitorModeSort);
return modes.Count() != 0;
}
int32_t CGxDevice::AdapterDesktopMode(CGxMonitorMode& mode) {
DISPLAY_DEVICE device;
if (!FindDisplayDevice(&device, DISPLAY_DEVICE_ACTIVE|DISPLAY_DEVICE_PRIMARY_DEVICE)) {
return 0;
}
DEVMODE dm;
dm.dmSize = sizeof(DEVMODE);
if (!EnumDisplaySettings(device.DeviceName, ENUM_CURRENT_SETTINGS, &dm)) {
return 0;
}
mode.size.x = dm.dmPelsWidth;
mode.size.y = dm.dmPelsHeight;
mode.refreshRate = dm.dmDisplayFrequency;
mode.bpp = dm.dmBitsPerPel;
return 1;
}
#elif (WHOA_SYSTEM_MAC)
int32_t CGxDevice::AdapterID(uint16_t& vendorID, uint16_t& deviceID, uint32_t& driverVersionHi, uint32_t& driverVersionLow) {
// TODO: proper implementation
vendorID = 0xFFFF;
deviceID = 3;
driverVersionHi = 0;
driverVersionLow = 0;
return 1;
}
int32_t CGxDevice::AdapterInfer(uint16_t& deviceID) {
// TODO
deviceID = 3;
return 1;
}
int32_t CGxDevice::AdapterMonitorModes(TSGrowableArray<CGxMonitorMode>& modes) {
// TODO: Mac support
return 0;
}
int32_t CGxDevice::AdapterDesktopMode(CGxMonitorMode& mode) {
// TODO: Mac support
return 0;
}
#elif (WHOA_BUILD_GLSDL)
int32_t CGxDevice::AdapterID(uint16_t& vendorID, uint16_t& deviceID, uint32_t& driverVersionHi, uint32_t& driverVersionLow) {
// TODO
vendorID = 0xFFFF;
deviceID = 3;
driverVersionHi = 0;
driverVersionLow = 0;
return 1;
}
int32_t CGxDevice::AdapterInfer(uint16_t& deviceID) {
// TODO
deviceID = 3;
return 1;
}
int32_t CGxDevice::AdapterMonitorModes(TSGrowableArray<CGxMonitorMode>& modes) {
auto primaryDisplay = SDL_GetPrimaryDisplay();
if (!primaryDisplay) {
return false;
}
int32_t displayModeCount;
auto displayModes = SDL_GetFullscreenDisplayModes(primaryDisplay, &displayModeCount);
if (displayModes == nullptr) {
return false;
}
modes.SetCount(displayModeCount);
for (auto i = 0; i < displayModeCount; i++) {
auto displayMode = displayModes[i];
CGxMonitorMode& mode = modes[i];
mode.size.x = displayMode->w;
mode.size.y = displayMode->h;
mode.bpp = SDL_BITSPERPIXEL(displayMode->format);
mode.refreshRate = static_cast<uint32_t>(displayMode->refresh_rate_numerator / displayMode->refresh_rate_denominator);
}
SDL_free(displayModes);
qsort(modes.Ptr(), modes.Count(), sizeof(CGxMonitorMode), CGxMonitorModeSort);
return true;
}
int32_t CGxDevice::AdapterDesktopMode(CGxMonitorMode& mode) {
auto primaryDisplay = SDL_GetPrimaryDisplay();
if (!primaryDisplay) {
return 0;
}
auto displayMode = SDL_GetDesktopDisplayMode(primaryDisplay);
if (!displayMode) {
return 0;
}
mode.size.x = displayMode->w;
mode.size.y = displayMode->h;
mode.bpp = SDL_BITSPERPIXEL(displayMode->format);
mode.refreshRate = static_cast<uint32_t>(displayMode->refresh_rate_numerator / displayMode->refresh_rate_denominator);
return 1;
}
#endif
void CGxDevice::LogOpen() {
if (!m_log) {
OsCreateDirectory("Logs", 0);
SLogCreate("Logs\\gx.log", 0, &m_log);
m_logBytes = 0;
}
}
void CGxDevice::LogClose() {
// TODO
if (m_log) {
SLogClose(m_log);
m_log = nullptr;
}
}
void CGxDevice::VLog(const char* format, va_list args) {
char buffer[2048];
if (m_log) {
vsnprintf(buffer, sizeof(buffer), format, args);
if (m_logBytes < 0x200000) {
SLogWrite(m_log, "%s", buffer);
m_logBytes += strlen(buffer);
}
}
}
void CGxDevice::Log(const char* format, ...) {
// TODO
va_list args;
va_start(args, format);
if (m_log) {
VLog(format, args);
}
}
void CGxDevice::Log(const CGxFormat& format) {
// TODO
static const char* s_formatToString[] = {
"Rgb565",
"ArgbX888",
"Argb2101010",
"Ds160",
"Ds24X",
"Ds248",
"Ds320"
};
if (format.window) {
Log("\tFormat: %d x %d Window, %s, multisample %d",
format.size.x,
format.size.y,
s_formatToString[format.depthFormat],
format.sampleCount);
} else {
Log("\tFormat %d x %d @ %d Fullscreen, %s, %s, multisample %d",
format.size.x,
format.size.y,
format.refreshRate,
s_formatToString[format.colorFormat],
s_formatToString[format.depthFormat],
format.sampleCount);
}
}
#if defined(WHOA_SYSTEM_WIN)
CGxDevice* CGxDevice::NewD3d() {
return NEW(CGxDeviceD3d);
}
@ -131,12 +448,15 @@ CGxDevice* CGxDevice::NewD3d9Ex() {
// TODO
return nullptr;
}
#endif
#if defined(WHOA_SYSTEM_MAC)
CGxDevice* CGxDevice::NewGLL() {
return NEW(CGxDeviceGLL);
}
#endif
CGxDevice* CGxDevice::NewOpenGl() {
@ -144,9 +464,11 @@ CGxDevice* CGxDevice::NewOpenGl() {
}
#if defined(WHOA_BUILD_GLSDL)
CGxDevice* CGxDevice::NewGLSDL() {
return NEW(CGxDeviceGLSDL);
}
#endif
uint32_t CGxDevice::PrimCalcCount(EGxPrim primType, uint32_t count) {
@ -168,93 +490,6 @@ void CGxDevice::ICursorUpdate(EGxTexCommand command, uint32_t width, uint32_t he
}
}
#if defined(WHOA_SYSTEM_WIN)
// TODO: replace this invented name
int32_t FindDisplayDevice(PDISPLAY_DEVICE device, uint32_t flag) {
DWORD i = 0;
device->cb = sizeof(DISPLAY_DEVICE);
while (EnumDisplayDevices(nullptr, i, device, 0)) {
if ((device->StateFlags & flag) == flag) {
return 1;
}
}
return 0;
}
bool CGxDevice::AdapterMonitorModes(TSGrowableArray<CGxMonitorMode>& modes) {
modes.SetCount(0);
DISPLAY_DEVICE device;
if (!FindDisplayDevice(&device, DISPLAY_DEVICE_PRIMARY_DEVICE)) {
return false;
}
DEVMODE dm;
dm.dmSize = sizeof(DEVMODE);
DWORD i = 0;
while (EnumDisplaySettings(&device, i, &dm)) {
if ((dm.dmPelsWidth >= 640 && dm.dmPelsHeight >= 480)
&& dm.dmBitsPerPel >= 16) {
auto mode = modes.New();
mode->size.x = dm.dmPelsWidth;
mode->size.y = dm.dmPelsHeight;
mode->bpp = dm.dmBitsPerPel;
mode->refreshRate = dm.dmDisplayFrequency;
}
i++;
}
qsort(modes.Ptr(), modes.Count(), sizeof(CGxMonitorMode), CGxMonitorModeSort);
return modes.Count() != 0;
}
#elif (WHOA_SYSTEM_MAC)
bool CGxDevice::AdapterMonitorModes(TSGrowableArray<CGxMonitorMode>& modes) {
// TODO: Mac support
return false;
}
#elif (WHOA_BUILD_GLSDL)
bool CGxDevice::AdapterMonitorModes(TSGrowableArray<CGxMonitorMode>& modes) {
auto primaryDisplay = SDL_GetPrimaryDisplay();
if (!primaryDisplay) {
return false;
}
int32_t displayModeCount;
auto displayModes = SDL_GetFullscreenDisplayModes(primaryDisplay, &displayModeCount);
if (displayModes == nullptr) {
return false;
}
modes.SetCount(displayModeCount);
for (auto i = 0; i < displayModeCount; i++) {
auto displayMode = displayModes[i];
CGxMonitorMode& mode = modes[i];
mode.size.x = displayMode->w;
mode.size.y = displayMode->h;
mode.bpp = displayMode->format.BitsPerPixel;
mode.refreshRate = static_cast<uint32_t>(displayMode->format.refresh_rate);
}
SDL_free(displayModes);
qsort(modes.Ptr(), modes.Count(), sizeof(CGxMonitorMode), CGxMonitorModeSort);
return true;
}
#endif
CGxDevice::CGxDevice() {
// TODO
// - implement rest of constructor
@ -321,6 +556,10 @@ const CGxCaps& CGxDevice::Caps() const {
return this->m_caps;
}
EGxApi CGxDevice::DeviceApi() {
return this->m_api;
}
int32_t CGxDevice::DeviceCreate(int32_t (*windowProc)(void* window, uint32_t message, uintptr_t wparam, intptr_t lparam), const CGxFormat& format) {
this->m_windowProc = windowProc;
@ -1366,7 +1605,7 @@ void CGxDevice::XformSetViewport(float minX, float maxX, float minY, float maxY,
return;
}
this->intF6C = 1;
this->m_needsReset = 1;
this->m_viewport.x.l = minX;
this->m_viewport.x.h = maxX;

View file

@ -11,7 +11,9 @@
#include "gx/Shader.hpp"
#include "cursor/Cursor.hpp"
#include <cstdint>
#include <cstdarg>
#include <storm/Hash.hpp>
#include <storm/Log.hpp>
#include <tempest/Box.hpp>
#include <tempest/Rect.hpp>
@ -39,6 +41,14 @@ struct ShaderConstants {
class CGxDevice {
public:
// Types
typedef void (*DEVICE_RESTORED_CALLBACK)();
typedef void (*TEXTURE_RECREATION_CALLBACK)();
typedef void (*STEREO_CHANGED_CALLBACK)();
static HSLOG m_log;
static uint32_t m_logBytes;
// Static variables
static uint32_t s_alphaRef[];
static C3Vector s_pointScaleIdentity;
@ -52,13 +62,19 @@ class CGxDevice {
static CGxShader* s_uiPixelShader;
// Static functions
static bool AdapterMonitorModes(TSGrowableArray<CGxMonitorMode>& modes);
static int32_t AdapterID(uint16_t& vendorID, uint16_t& deviceID, uint32_t& driverVersionHi, uint32_t& driverVersionLow);
static int32_t AdapterInfer(uint16_t& deviceID);
static int32_t AdapterDesktopMode(CGxMonitorMode& mode);
static int32_t AdapterMonitorModes(TSGrowableArray<CGxMonitorMode>& modes);
static void ICursorUpdate(EGxTexCommand, uint32_t, uint32_t, uint32_t, uint32_t, void*, uint32_t&, const void*&);
static void LogOpen();
static void VLog(const char* format, va_list args);
static void Log(const char* format, ...);
static void Log(const CGxFormat& format);
static void LogClose();
static uint32_t PrimCalcCount(EGxPrim primType, uint32_t count);
// graphics api factory
#if defined(WHOA_SYSTEM_WIN)
static CGxDevice* NewD3d();
static CGxDevice* NewD3d9Ex();
@ -111,7 +127,7 @@ class CGxDevice {
TSFixedArray<CGxStateBom> m_hwRenderStates;
uint32_t m_baseMipLevel = 0; // TODO placeholder
int32_t m_cursorVisible = 0;
int32_t m_hardwareCursor = 0;
int32_t m_hwCursor = 0;
uint32_t m_cursorHotspotX = 0;
uint32_t m_cursorHotspotY = 0;
uint32_t m_cursor[CURSOR_IMAGE_SIZE] = { 0 };
@ -156,6 +172,7 @@ class CGxDevice {
const CGxCaps& Caps() const;
CGxBuf* BufCreate(CGxPool* pool, uint32_t itemSize, uint32_t itemCount, uint32_t index);
CGxBuf* BufStream(EGxPoolTarget target, uint32_t itemSize, uint32_t itemCount);
EGxApi DeviceApi();
void DeviceCreatePools();
void DeviceCreateStreamBufs();
const CRect& DeviceCurWindow();

View file

@ -1,7 +1,5 @@
#include "gx/CGxFormat.hpp"
const char* CGxFormat::formatToColorBitsString[Formats_Last] = { "16", "24", "24", "30", "16", "24", "24", "32" };
CGxFormat::CGxFormat() {
this->size.x = 0;
this->size.y = 0;
@ -12,12 +10,12 @@ CGxFormat::CGxFormat() {
this->stereoEnabled = false;
this->sampleCount = 1;
this->aspect = 1;
this->unk1 = -1;
this->unk2 = -1;
this->unk3 = -1;
this->unk4 = -1;
this->unk5 = -1;
this->unk6 = -1;
this->unk38 = 0xFFFFFFFF;
this->unk3C = 0xFFFFFFFF;
this->unk40 = 0xFFFFFFFF;
this->unk44 = 0xFFFFFFFF;
this->unk48 = 0xFFFFFFFF;
this->unk4C = 0xFFFFFFFF;
}
CGxFormat::CGxFormat(bool p_window, const C2iVector& p_size, Format p_colorFormat, Format p_depthFormat, uint32_t p_refreshRate, uint32_t p_vsync, bool p_hwTnl, bool p_fixLag, bool p_hwCursor, bool p_aspect, bool p_maximize) {
@ -41,10 +39,10 @@ CGxFormat::CGxFormat(bool p_window, const C2iVector& p_size, Format p_colorForma
this->maximize = p_maximize;
this->backbuffers = 1;
this->sampleCount = 1;
this->unk1 = -1;
this->unk2 = -1;
this->unk3 = -1;
this->unk4 = -1;
this->unk5 = -1;
this->unk6 = -1;
this->unk38 = 0xFFFFFFFF;
this->unk3C = 0xFFFFFFFF;
this->unk40 = 0xFFFFFFFF;
this->unk44 = 0xFFFFFFFF;
this->unk48 = 0xFFFFFFFF;
this->unk4C = 0xFFFFFFFF;
}

View file

@ -22,8 +22,6 @@ class CGxFormat {
CGxFormat();
CGxFormat(bool p_window, const C2iVector& p_size, Format p_colorFormat, Format p_depthFormat, uint32_t p_refreshRate, uint32_t p_vsync, bool p_hwTnl, bool p_fixLag, bool p_hwCursor, bool p_aspect, bool p_maximize);
static const char* formatToColorBitsString[Formats_Last];
// Member variables
uint32_t apiSpecificModeID;
bool hwTnL;
@ -41,12 +39,12 @@ class CGxFormat {
uint32_t refreshRate;
uint32_t vsync;
bool stereoEnabled;
uint32_t unk1;
uint32_t unk2;
uint32_t unk3;
uint32_t unk4;
uint32_t unk5;
uint32_t unk6;
uint32_t unk38;
uint32_t unk3C;
uint32_t unk40;
uint32_t unk44;
uint32_t unk48;
uint32_t unk4C;
C2iVector pos;
};

View file

@ -11,6 +11,6 @@ class CGxMonitorMode {
uint32_t refreshRate;
};
int32_t CGxMonitorModeSort(const void* i, const void* j);
int32_t CGxMonitorModeSort(const void* a, const void* b);
#endif

View file

@ -61,11 +61,11 @@ if (WHOA_SYSTEM_WIN)
endif ()
endif ()
# Link SDL2 and GLEW for GLSDL
# Link SDL3 and GLEW for GLSDL
if (WHOA_BUILD_GLSDL)
target_link_libraries(gx
PRIVATE
SDL2::SDL2-static
SDL3::SDL3-static
libglew_static
)
endif ()

View file

@ -59,8 +59,7 @@ CGxDevice* GxDevCreate(EGxApi api, int32_t (*windowProc)(void* window, uint32_t
}
if (!device) {
SErrPrepareAppFatal(__FILE__, __LINE__);
SErrDisplayAppFatal("GxDevCreate: failed to create graphics device %d", api);
SErrPrepareAppFatal(__FILE__, __LINE__); SErrDisplayAppFatal("GxDevCreate: failed to create graphics device %d", api);
}
// STORM_ASSERT(device != nullptr);
@ -78,15 +77,19 @@ CGxDevice* GxDevCreate(EGxApi api, int32_t (*windowProc)(void* window, uint32_t
}
}
int32_t GxDevExists() {
return g_theGxDevicePtr != nullptr;
void GxDevDestroy(CGxDevice* device) {
// TODO
// device->DeviceDestroy();
}
EGxApi GxDevApi() {
return g_theGxDevicePtr->m_api;
}
bool GxDevExists() {
return g_theGxDevicePtr != nullptr;
}
void* GxDevWindow() {
return g_theGxDevicePtr->DeviceWindow();
}
@ -95,7 +98,12 @@ int32_t GxMasterEnable(EGxMasterEnables state) {
return g_theGxDevicePtr->MasterEnable(state);
}
EGxApi GxApiDefault() {
void GxDevOverride(EGxOverride override, uint32_t value) {
// TODO
// g_theGxDevicePtr->DeviceOverride(override, value);
}
EGxApi GxDefaultApi() {
#if defined(WHOA_SYSTEM_WIN)
return GxApi_D3d9;
#endif
@ -110,13 +118,69 @@ EGxApi GxApiDefault() {
}
bool GxApiSupported(EGxApi api) {
return (g_supportedApis & static_cast<uint32_t>(api)) != 0;
return (g_supportedApis & (1 << static_cast<uint32_t>(api))) != 0;
}
bool GxAdapterMonitorModes(TSGrowableArray<CGxMonitorMode>& modes) {
int32_t GxAdapterID(uint16_t& vendorID, uint16_t& deviceID, uint32_t& driverVersionHi, uint32_t& driverVersionLo) {
return g_theGxDevicePtr->AdapterID(vendorID, deviceID, driverVersionHi, driverVersionLo);
}
int32_t GxAdapterInfer(uint16_t& deviceID) {
return g_theGxDevicePtr->AdapterInfer(deviceID);
}
int32_t GxAdapterMonitorModes(TSGrowableArray<CGxMonitorMode>& modes) {
return CGxDevice::AdapterMonitorModes(modes);
}
int32_t GxAdapterDesktopMode(CGxMonitorMode& mode) {
return CGxDevice::AdapterDesktopMode(mode);
}
void GxLogOpen() {
CGxDevice::LogOpen();
}
void GxLog(const char* format, ...) {
va_list args;
va_start(args, format);
CGxDevice::VLog(format, args);
}
void GxLogClose() {
CGxDevice::LogClose();
}
void GxAddStereoChangedCallback(CGxDevice::STEREO_CHANGED_CALLBACK callback) {
// TODO
// g_theGxDevicePtr->AddStereoChangedCallback(callback);
}
int32_t GxRemoveStereoChangedCallback(CGxDevice::STEREO_CHANGED_CALLBACK callback) {
// TODO
// return g_theGxDevicePtr->RemoveStereoChangedCallback(callback);
return 1;
}
void GxStereoSetConvergence(float value) {
// TODO
// return g_theGxDevicePtr->StereoSetConvergence(value);
}
void GxStereoSetSeparation(float value) {
// TODO
// return g_theGxDevicePtr->StereoSetSeparation(value);
}
const CGxCaps& GxCaps() {
return g_theGxDevicePtr->Caps();
}
bool GxCapsWindowHasFocus(int32_t a1) {
// TODO
return true;
}
void GxCapsWindowSize(CRect& rect) {
g_theGxDevicePtr->CapsWindowSize(rect);
}

View file

@ -9,12 +9,51 @@ class CGxFormat;
extern CGxDevice* g_theGxDevicePtr;
bool GxApiSupported(EGxApi api);
EGxApi GxDefaultApi();
CGxDevice* GxDevCreate(EGxApi api, int32_t (*windowProc)(void* window, uint32_t message, uintptr_t wparam, intptr_t lparam), const CGxFormat& format);
void GxDevDestroy(CGxDevice* device);
EGxApi GxDevApi(void);
bool GxDevExists();
void* GxDevWindow();
int32_t GxMasterEnable(EGxMasterEnables state);
void GxDevOverride(EGxOverride override, uint32_t value);
int32_t GxAdapterDesktopMode(CGxMonitorMode& mode);
int32_t GxAdapterMonitorModes(TSGrowableArray<CGxMonitorMode>& modes);
int32_t GxAdapterID(uint16_t& vendorID, uint16_t& deviceID, uint32_t& driverVersionHi, uint32_t& driverVersionLow);
int32_t GxAdapterInfer(uint16_t& deviceID);
void GxLogOpen();
void GxLog(const char* format, ...);
void GxLogClose();
void GxAddStereoChangedCallback(CGxDevice::STEREO_CHANGED_CALLBACK callback);
int32_t GxRemoveStereoChangedCallback(CGxDevice::STEREO_CHANGED_CALLBACK callback);
void GxStereoSetConvergence(float value);
void GxStereoSetSeparation(float value);
const CGxCaps& GxCaps();
bool GxCapsWindowHasFocus(int32_t);
void GxCapsWindowSize(CRect&);
#endif

View file

@ -37,44 +37,6 @@ const char** g_gxShaderProfileNames[GxShTargets_Last] = {
static uint32_t s_maxFPS;
static uint32_t s_maxFPSBk;
const CGxCaps& GxCaps() {
return g_theGxDevicePtr->Caps();
}
bool GxCapsWindowHasFocus(int32_t a1) {
// TODO
return true;
}
void GxCapsWindowSize(CRect& rect) {
g_theGxDevicePtr->CapsWindowSize(rect);
}
void GxFormatColor(CImVector& color) {
if (GxCaps().m_colorFormat == GxCF_rgba) {
CImVector formattedColor = {
color.r,
color.g,
color.b,
color.a
};
color = formattedColor;
}
}
void GxLogOpen() {
CGxDevice::LogOpen();
}
void GxLogClose() {
CGxDevice::LogClose();
}
void GxLog(const char* format, ...) {
// TODO
}
void GxSetMaxFPS(uint32_t maxFPS) {
s_maxFPS = maxFPS;
}
@ -90,3 +52,16 @@ uint32_t GxGetMaxFPS() {
uint32_t GxGetMaxFPSBk() {
return s_maxFPSBk;
}
void GxFormatColor(CImVector& color) {
if (GxCaps().m_colorFormat == GxCF_rgba) {
CImVector formattedColor = {
color.r,
color.g,
color.b,
color.a
};
color = formattedColor;
}
}

View file

@ -10,20 +10,8 @@ class CRect;
extern const char** g_gxShaderProfileNames[GxShTargets_Last];
const CGxCaps& GxCaps();
bool GxCapsWindowHasFocus(int32_t);
void GxCapsWindowSize(CRect&);
void GxFormatColor(CImVector&);
void GxLogOpen();
void GxLogClose();
void GxLog(const char* format, ...);
void GxSetMaxFPS(uint32_t maxFPS);
void GxSetMaxFPSBk(uint32_t maxFPSBk);

View file

@ -530,7 +530,7 @@ void CGxDeviceD3d::DeviceWM(EGxWM wm, uintptr_t param1, uintptr_t param2) {
// TODO
this->intF6C = 1;
this->m_needsReset = 1;
return;
} else {
@ -538,7 +538,7 @@ void CGxDeviceD3d::DeviceWM(EGxWM wm, uintptr_t param1, uintptr_t param2) {
}
}
this->intF6C = 1;
this->m_needsReset = 1;
}
break;
@ -1746,7 +1746,7 @@ void CGxDeviceD3d::IStateSync() {
// TODO
if (this->intF6C) {
if (this->m_needsReset) {
this->IXformSetViewport();
}
}
@ -2124,7 +2124,7 @@ void CGxDeviceD3d::IXformSetViewport() {
this->m_d3dDevice->SetViewport(&d3dViewport);
this->intF6C = 0;
this->m_needsReset = 0;
}
void CGxDeviceD3d::IXformSetWorld() {
@ -2159,7 +2159,7 @@ void CGxDeviceD3d::SceneClear(uint32_t mask, CImVector color) {
flags |= 0x2;
}
if (this->intF6C) {
if (this->m_needsReset) {
this->IXformSetViewport();
}
@ -2200,12 +2200,8 @@ void CGxDeviceD3d::ShaderCreate(CGxShader* shaders[], EGxShTarget target, const
}
int32_t CGxDeviceD3d::StereoEnabled() {
return this->m_d3dStereoEnabled == 1;
}
void CGxDeviceD3d::CursorUnlock() {
CGxDevice::CursorUnlock(x, y);
this->m_hwCursorNeedsUpdate = 1;
// return this->m_d3dStereoEnabled == 1;
return 0;
}
void CGxDeviceD3d::XformSetProjection(const C44Matrix& matrix) {

View file

@ -1,5 +1,5 @@
#include "gx/glsdl/CGxDeviceGLSDL.hpp"
#include "event/Input.hpp"
#include "os/Input.hpp"
#include "gx/Blit.hpp"
#include "gx/CGxBatch.hpp"
#include "gx/Shader.hpp"
@ -681,9 +681,13 @@ 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;
this->m_caps.m_hwCursor = 0;
// TODO
// TODO: proper implementation
this->m_caps.m_numTmus = 2;
this->m_caps.m_numStreams = 1;
}
void CGxDeviceGLSDL::IShaderBindPixel(CGxShader* sh) {

View file

@ -27,7 +27,7 @@ void GLSDLContext::Create(GLSDLWindow* window) {
void GLSDLContext::Destroy() {
BC_ASSERT(this->m_sdlGLContext != nullptr);
SDL_GL_DeleteContext(this->m_sdlGLContext);
SDL_GL_DestroyContext(this->m_sdlGLContext);
this->m_sdlGLContext = nullptr;
}
@ -37,7 +37,7 @@ bool GLSDLContext::IsCurrentContext() {
void GLSDLContext::MakeCurrent(GLSDLWindow* window) {
auto status = SDL_GL_MakeCurrent(window->m_sdlWindow, this->m_sdlGLContext);
BC_ASSERT(status == 0);
BC_ASSERT(status);
}
int32_t GLSDLContext::GetSampleCount() {

View file

@ -1,6 +1,6 @@
#ifndef GX_GL_SDL_GL_SDL_CONTEXT_HPP
#include <SDL2/SDL.h>
#include <SDL3/SDL.h>
#include "gx/glsdl/GLSDLWindow.hpp"
#include "gx/glsdl/GLTypes.hpp"

View file

@ -68,15 +68,13 @@ void GLSDLWindow::Create(const char* title, const GLSDLWindowRect& rect, GLTextu
this->m_sdlWindow = SDL_CreateWindow(
title,
SDL_WINDOWPOS_CENTERED,
SDL_WINDOWPOS_CENTERED,
static_cast<int>(rect.size.width), static_cast<int>(rect.size.height),
SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE
);
BC_ASSERT(this->m_sdlWindow != nullptr);
SDL_StartTextInput();
SDL_StartTextInput(this->m_sdlWindow);
}
void GLSDLWindow::Swap() {

View file

@ -2,7 +2,7 @@
#define GX_GL_SDL_GL_SDL_WINDOW_HPP
#include <cstdint>
#include <SDL2/SDL.h>
#include <SDL3/SDL.h>
#include "gx/glsdl/GLTypes.hpp"

View file

@ -141,11 +141,13 @@ void CBLPFile::DecompPalARGB8888(uint8_t* data, void* tempbuffer, uint32_t color
auto pixels = data;
auto bytes = reinterpret_cast<uint8_t*>(tempbuffer);
for (auto i = colorSize; i; i--) {
auto i = colorSize;
while (i != 0) {
*reinterpret_cast<BlpPalPixel*>(pixels) = this->m_header.extended.palette[*bytes];
pixels[3] = 0xFF;
pixels += 4;
bytes++;
i--;
}
auto alphaBits = this->AlphaBits();

View file

@ -27,7 +27,10 @@ struct BlpPalPixel {
uint8_t pad;
};
static_assert(sizeof(BlpPalPixel) == 4);
class CBLPFile {
#pragma pack(push, 1)
struct BLPHeader {
uint32_t magic = 0x32504C42;
uint32_t formatVersion = 1;
@ -49,6 +52,7 @@ class CBLPFile {
} jpeg;
} extended;
};
#pragma pack(pop)
public:
// Static variables

View file

@ -1,5 +1,5 @@
#include "gx/texture/CGxTex.hpp"
#include "gx/Gx.hpp"
#include "gx/Device.hpp"
#include <algorithm>
CGxTexFlags::CGxTexFlags(EGxTexFilter filter, uint32_t wrapU, uint32_t wrapV, uint32_t force, uint32_t generateMipMaps, uint32_t renderTarget, uint32_t maxAnisotropy) {