From c84b62a6af184a02995a4e44f602d57ca0d02509 Mon Sep 17 00:00:00 2001 From: AdventureT Date: Tue, 2 Jan 2024 17:47:47 +0100 Subject: [PATCH] Did some major render stuff --- OpenJPOG/Source/ABINKMoviePlayer.cpp | 67 ++++- OpenJPOG/Source/ABINKMoviePlayer.h | 10 +- OpenJPOG/Source/AGUIGameHUD.cpp | 1 + OpenJPOG/Source/AGUIGameHUD.h | 5 + OpenJPOG/Source/ARenderer.cpp | 6 + OpenJPOG/Source/ARenderer.h | 11 + OpenJPOG/Source/ARootState.cpp | 5 + OpenJPOG/Source/ARootState.h | 19 ++ OpenJPOG/Source/ARootTask.h | 9 +- OpenJPOG/premake5.lua | 18 +- .../Source/TKernel/TManagedPointer_Tests.cpp | 4 +- Toshi/Include/TApplication/Defines.h | 3 +- Toshi/Include/TKernel/Defines.h | 13 +- Toshi/Include/TKernel/TCString.h | 1 + Toshi/Include/TKernel/TKernelInterface.h | 2 +- Toshi/Include/TKernel/TManagedPointer.h | 8 +- Toshi/Include/TKernel/TSystemTools.h | 5 + Toshi/Include/TKernel/TWString.h | 165 +++++++++++ Toshi/Include/TRender/Defines.h | 13 +- Toshi/Include/TRender/TRenderAdapter.h | 67 +++++ Toshi/Include/TRender/TRenderInterface.h | 7 + Toshi/Include/TRender/TTextureFactory.h | 23 +- Toshi/Include/TRender/TTextureResource.h | 13 +- Toshi/Include/TRenderD3D/Defines.h | 13 +- Toshi/Include/TRenderD3D/TMSWindow.h | 38 +++ Toshi/Include/TRenderD3D/TRenderD3DAdapter.h | 147 ++++++++++ .../Include/TRenderD3D/TRenderD3DInterface.h | 38 ++- Toshi/Include/TRenderD3D/TTextureFactoryD3D.h | 9 +- Toshi/Source/TKernel/TCString.cpp | 28 +- Toshi/Source/TKernel/TSystemTools.cpp | 32 +++ Toshi/Source/TKernel/TWString.cpp | 152 +++++++++++ Toshi/Source/TRender/TRenderAdapter.cpp | 1 + Toshi/Source/TRender/TTextureFactory.cpp | 22 ++ Toshi/Source/TRenderD3D/TMSWindow.cpp | 149 ++++++++++ Toshi/Source/TRenderD3D/TRenderD3DAdapter.cpp | 258 ++++++++++++++++++ .../Source/TRenderD3D/TRenderD3DInterface.cpp | 131 +++++++++ .../Source/TRenderD3D/TTextureFactoryD3D.cpp | 4 +- .../Source/TRenderD3D/TTextureResourceD3D.cpp | 2 +- 38 files changed, 1431 insertions(+), 68 deletions(-) create mode 100644 OpenJPOG/Source/AGUIGameHUD.cpp create mode 100644 OpenJPOG/Source/AGUIGameHUD.h create mode 100644 OpenJPOG/Source/ARenderer.cpp create mode 100644 OpenJPOG/Source/ARenderer.h create mode 100644 OpenJPOG/Source/ARootState.cpp create mode 100644 OpenJPOG/Source/ARootState.h create mode 100644 Toshi/Include/TKernel/TWString.h create mode 100644 Toshi/Include/TRender/TRenderAdapter.h create mode 100644 Toshi/Include/TRenderD3D/TMSWindow.h create mode 100644 Toshi/Include/TRenderD3D/TRenderD3DAdapter.h create mode 100644 Toshi/Source/TKernel/TWString.cpp create mode 100644 Toshi/Source/TRender/TRenderAdapter.cpp create mode 100644 Toshi/Source/TRenderD3D/TMSWindow.cpp create mode 100644 Toshi/Source/TRenderD3D/TRenderD3DAdapter.cpp diff --git a/OpenJPOG/Source/ABINKMoviePlayer.cpp b/OpenJPOG/Source/ABINKMoviePlayer.cpp index bdf88ca..c3aac2c 100644 --- a/OpenJPOG/Source/ABINKMoviePlayer.cpp +++ b/OpenJPOG/Source/ABINKMoviePlayer.cpp @@ -1,4 +1,8 @@ #include "ABINKMoviePlayer.h" +#include "main.h" +#include "TKernel/TManagedPointer.h" +#include "TRender/TTextureFactory.h" +#include "TRenderD3D/TRenderD3DInterface.h" TOSHI_NAMESPACE_USING @@ -18,14 +22,12 @@ ABINKMoviePlayer::ABINKMoviePlayer() TBOOL ABINKMoviePlayer::InitializeMoviePlayer() { - HRESULT hResult = DirectSoundCreate(NULL, &m_pDirectSound, NULL); - if (FAILED(hResult)) { - m_pDirectSound = NULL; + if (!m_bIsBINKInitialized) { + InitializeAudioResource(); + InitializeVideoResource(); + m_bIsBINKInitialized = TTRUE; } - else { - BinkSoundUseDirectSound(m_pDirectSound); - } - return TTRUE; + return TFALSE; } TBOOL ABINKMoviePlayer::ShutdownMoviePlayer() @@ -39,6 +41,13 @@ TBOOL ABINKMoviePlayer::ShutdownMoviePlayer() return TFALSE; } +TBOOL ABINKMoviePlayer::StartMovie(TPCHAR a_szMovieName, TBOOL a_bUnk1, TPCHAR a_szUnk2, TBOOL a_bUnk3) +{ + TManagedPtr renderer = g_oTheApp.GetRootTask()->GetRenderInterface(); + + return TBOOL(); +} + TBOOL ABINKMoviePlayer::Update(TFLOAT a_fDeltaTime) { if (!m_bHasMovieStopped && m_hBink) { @@ -111,6 +120,50 @@ TBOOL ABINKMoviePlayer::RenderToFrameBuffer(TPBYTE a_pDest, TINT a_iDestWidth, T return TFALSE; } +TBOOL ABINKMoviePlayer::InitializeVideoResource() +{ + TManagedPtr renderer = g_oTheApp.GetRootTask()->GetRenderInterface(); + TTextureFactory* factory = (TTextureFactory*)renderer->GetSystemResource(TRenderInterface::SYSRESOURCE_TEXTUREFACTORY); + TINT size; + TTEXTURERESOURCEFORMAT textureFormat; + TINT textureFormatSize; + if (renderer->Supports32BitTextures()) { + size = 4; + textureFormat = TTEXTURERESOURCEFORMAT::R8G8B8A8; + textureFormatSize = 32; + } + else { + size = 2; + textureFormat = TTEXTURERESOURCEFORMAT::R5G5B5A1; + textureFormatSize = 8; + } + size *= 0x10000; + TPVOID buffer = tmalloc(size, TNULL, -1); + TSystem::MemSet(buffer, 0xFF, size); + factory->CreateEx(buffer, size, 256, 256, 1, textureFormat, textureFormatSize); + return TTRUE; +} + +TBOOL ABINKMoviePlayer::InitializeAudioResource() +{ + TManagedPtr renderer = (TRenderD3DInterface*)g_oTheApp.GetRootTask()->GetRenderInterface().m_pObject; + HRESULT hResult = DirectSoundCreate(NULL, &m_pDirectSound, NULL); + + if (FAILED(hResult)) { + m_pDirectSound = NULL; + } + else { + m_pDirectSound->SetCooperativeLevel(renderer->GetMSWindow()->GetHWND(), 2); + BinkSoundUseDirectSound(m_pDirectSound); + } + return TTRUE; +} + +TBOOL ABINKMoviePlayer::FreeVideoResource() +{ + return TTRUE; +} + void ABINKMoviePlayer::BinkSleep(TINT a_iMicroseconds) { static S32 s_iTotalSleep = 0; diff --git a/OpenJPOG/Source/ABINKMoviePlayer.h b/OpenJPOG/Source/ABINKMoviePlayer.h index 1580ad1..109dcea 100644 --- a/OpenJPOG/Source/ABINKMoviePlayer.h +++ b/OpenJPOG/Source/ABINKMoviePlayer.h @@ -18,6 +18,8 @@ class ABINKMoviePlayer : public AMoviePlayer virtual TBOOL ShutdownMoviePlayer(); + virtual TBOOL StartMovie(TPCHAR a_szMovieName, TBOOL a_bUnk1, TPCHAR a_szUnk2, TBOOL a_bUnk3); + virtual TBOOL Update(TFLOAT a_fDeltaTime); virtual TBOOL RenderToTexture(TTextureResource *a_pTexture); @@ -25,10 +27,10 @@ class ABINKMoviePlayer : public AMoviePlayer virtual TBOOL RenderToFrameBuffer(); virtual TBOOL RenderToFrameBuffer(TPBYTE a_pDest, TINT a_iSourceHeigth, TINT a_iDestHeigth, TINT a_iDestPitch, TINT a_iDestX, INT a_iDestY, INT a_iSrcX, INT a_iSrcY); - virtual TBOOL FreeVideoResource() - { - return TTRUE; - } + virtual TBOOL InitializeVideoResource(); + virtual TBOOL InitializeAudioResource(); + + virtual TBOOL FreeVideoResource(); virtual TBOOL FreeAudioResource() { diff --git a/OpenJPOG/Source/AGUIGameHUD.cpp b/OpenJPOG/Source/AGUIGameHUD.cpp new file mode 100644 index 0000000..068431c --- /dev/null +++ b/OpenJPOG/Source/AGUIGameHUD.cpp @@ -0,0 +1 @@ +#include "AGUIGameHUD.h" diff --git a/OpenJPOG/Source/AGUIGameHUD.h b/OpenJPOG/Source/AGUIGameHUD.h new file mode 100644 index 0000000..1d80c63 --- /dev/null +++ b/OpenJPOG/Source/AGUIGameHUD.h @@ -0,0 +1,5 @@ +#pragma once +class AGUIGameHUD +{ +}; + diff --git a/OpenJPOG/Source/ARenderer.cpp b/OpenJPOG/Source/ARenderer.cpp new file mode 100644 index 0000000..e3e1605 --- /dev/null +++ b/OpenJPOG/Source/ARenderer.cpp @@ -0,0 +1,6 @@ +#include "ARenderer.h" + +TOSHI_NAMESPACE_USING + +IMPLEMENT_DYNCREATE(ARenderer, TTask) + diff --git a/OpenJPOG/Source/ARenderer.h b/OpenJPOG/Source/ARenderer.h new file mode 100644 index 0000000..733fc16 --- /dev/null +++ b/OpenJPOG/Source/ARenderer.h @@ -0,0 +1,11 @@ +#pragma once +#include "TKernel/TTask.h" + +TOSHI_NAMESPACE_BEGIN + +class ARenderer : public TTask +{ + DECLARE_DYNAMIC(ARenderer) +}; + +TOSHI_NAMESPACE_END \ No newline at end of file diff --git a/OpenJPOG/Source/ARootState.cpp b/OpenJPOG/Source/ARootState.cpp new file mode 100644 index 0000000..7298687 --- /dev/null +++ b/OpenJPOG/Source/ARootState.cpp @@ -0,0 +1,5 @@ +#include "ARootState.h" + +TOSHI_NAMESPACE_USING + +IMPLEMENT_DYNCREATE(ARootState, TObject) \ No newline at end of file diff --git a/OpenJPOG/Source/ARootState.h b/OpenJPOG/Source/ARootState.h new file mode 100644 index 0000000..5541f21 --- /dev/null +++ b/OpenJPOG/Source/ARootState.h @@ -0,0 +1,19 @@ +#pragma once +#include "TKernel/TObject.h" +#include "AGUIGameHUD.h" + +class ARootState : public Toshi::TObject +{ + DECLARE_DYNAMIC(ARootState) + + +public: + + AGUIGameHUD& GetHUDState() { return m_oHUDState; } + +private: + ARootState* m_pParent; // 0x4 + ARootState* m_pNext; // 0x8 + AGUIGameHUD m_oHUDState; // 0x10 +}; + diff --git a/OpenJPOG/Source/ARootTask.h b/OpenJPOG/Source/ARootTask.h index bb20898..04d0bd6 100644 --- a/OpenJPOG/Source/ARootTask.h +++ b/OpenJPOG/Source/ARootTask.h @@ -4,6 +4,8 @@ #include "TKernel/TCString.h" #include "AVibrationManager.h" #include "ABINKMoviePlayer.h" +#include "TRender/TRenderInterface.h" +#include "TKernel/TManagedPointer.h" class ARootTask : public Toshi::TTask { @@ -20,12 +22,15 @@ class ARootTask : public Toshi::TTask m_szName = a_szName; } + Toshi::TManagedPtr GetRenderInterface() { return m_pRenderInterface; } + private: void AllocateInputSystem(); private: Toshi::TCString m_szName; - TTask* m_pInputTask; // 0x38 - AVibrationManager* m_pVibrationTask; // 0xE8 + Toshi::TTask* m_pInputTask; // 0x38 + Toshi::TRenderInterface* m_pRenderInterface;// 0xD0 + AVibrationManager* m_pVibrationTask; // 0xE8 Toshi::ABINKMoviePlayer* m_pMoviePlayer; // 0xF0 }; \ No newline at end of file diff --git a/OpenJPOG/premake5.lua b/OpenJPOG/premake5.lua index b1fda98..b2b23f4 100644 --- a/OpenJPOG/premake5.lua +++ b/OpenJPOG/premake5.lua @@ -9,7 +9,16 @@ project ("OpenJPOG") "TKernelInterface", "TApplication", "TRenderInterface", + "TRenderD3DInterface", + "d3d8.lib", + "d3dx8.lib", + "dxguid.lib", + "dxgi.lib", + "DxErr8.lib", "dsound.lib", + "legacy_stdio_definitions.lib", + "winmm.lib", + "dinput8.lib", "fmodvc.lib", "binkw32.lib" } @@ -27,6 +36,11 @@ project ("OpenJPOG") "%{IncludeDir.bink}" } + externalincludedirs + { + "%{IncludeDir.dx8}" + } + defines { "TOSHI_USER_CLIENT" @@ -35,7 +49,8 @@ project ("OpenJPOG") libdirs { "%{LibDir.fmod}", - "%{LibDir.bink}" + "%{LibDir.bink}", + "%{LibDir.dx8}" } postbuildcommands @@ -43,6 +58,7 @@ project ("OpenJPOG") "{COPY} \"%{wks.location}bin/" .. outputdir .. "/TKernelInterface/TKernelInterface.dll\" \"%{wks.location}bin/" .. outputdir .. "/%{prj.name}\"", "{COPY} \"%{wks.location}bin/" .. outputdir .. "/TApplication/TApplication.dll\" \"%{wks.location}bin/" .. outputdir .. "/%{prj.name}\"", "{COPY} \"%{wks.location}bin/" .. outputdir .. "/TRenderInterface/TRenderInterface.dll\" \"%{wks.location}bin/" .. outputdir .. "/%{prj.name}\"", + "{COPY} \"%{wks.location}bin/" .. outputdir .. "/TRenderD3DInterface/TRenderD3DInterface.dll\" \"%{wks.location}bin/" .. outputdir .. "/%{prj.name}\"", "{COPY} \"%{wks.location}Toshi/vendor/fmod/lib/fmod.dll\" \"%{wks.location}bin/" .. outputdir .. "/%{prj.name}\"", "{COPY} \"%{wks.location}Toshi/vendor/bink/lib/binkw32.dll\" \"%{wks.location}bin/" .. outputdir .. "/%{prj.name}\"", } diff --git a/Tools/UnitTests/Source/TKernel/TManagedPointer_Tests.cpp b/Tools/UnitTests/Source/TKernel/TManagedPointer_Tests.cpp index 9e7a6fa..8eba26e 100644 --- a/Tools/UnitTests/Source/TKernel/TManagedPointer_Tests.cpp +++ b/Tools/UnitTests/Source/TKernel/TManagedPointer_Tests.cpp @@ -8,11 +8,11 @@ struct Test int m_iTest; }; -TEST_CASE("Test Managed Pointer", "[TManagedPointer]") +TEST_CASE("Test Managed Pointer", "[TManagedPtr]") { Test* test = new Test; { - TManagedPointer testptr(test); + TManagedPtr testptr(test); } // Ensure that the pointer is not 0xCC (freed memory) diff --git a/Toshi/Include/TApplication/Defines.h b/Toshi/Include/TApplication/Defines.h index f82a619..d795f73 100644 --- a/Toshi/Include/TApplication/Defines.h +++ b/Toshi/Include/TApplication/Defines.h @@ -49,7 +49,8 @@ typedef unsigned __int64 TUINT64; typedef short TSHORT; typedef unsigned short TUSHORT; typedef wchar_t TWCHAR; -typedef unsigned short* TPWCHAR; +typedef wchar_t* TPWCHAR; +typedef const wchar_t* TPCWCHAR; typedef const char* TPCCHAR; typedef char* TPCHAR; typedef char TCHAR; diff --git a/Toshi/Include/TKernel/Defines.h b/Toshi/Include/TKernel/Defines.h index 254b60e..9e942e4 100644 --- a/Toshi/Include/TKernel/Defines.h +++ b/Toshi/Include/TKernel/Defines.h @@ -49,16 +49,17 @@ typedef unsigned __int64 TUINT64; typedef short TSHORT; typedef unsigned short TUSHORT; typedef wchar_t TWCHAR; -typedef unsigned short* TPWCHAR; -typedef const char* TPCCHAR; -typedef char* TPCHAR; +typedef wchar_t* TPWCHAR; +typedef const wchar_t* TPCWCHAR; +typedef const char* TPCCHAR; +typedef char* TPCHAR; typedef char TCHAR; typedef const char TCCHAR; typedef char TINT8; typedef unsigned char TUINT8; typedef unsigned char TBYTE; -typedef unsigned char* TPBYTE; -typedef void* TPVOID; -typedef const void* TPCVOID; +typedef unsigned char* TPBYTE; +typedef void* TPVOID; +typedef const void* TPCVOID; typedef float TFLOAT; typedef const float TCFLOAT; \ No newline at end of file diff --git a/Toshi/Include/TKernel/TCString.h b/Toshi/Include/TKernel/TCString.h index 1aa7501..304c18a 100644 --- a/Toshi/Include/TKernel/TCString.h +++ b/Toshi/Include/TKernel/TCString.h @@ -40,6 +40,7 @@ class TKERNELINTERFACE_EXPORTS TCString } TCString& Concat(TCString const& a_rString, TINT a_iLength = -1); + TCString& Concat(TPCCHAR a_String, TINT a_iLength = -1); TINT Compare(TPCCHAR a_pcString, int a_iLength = -1) const; void Copy(const TCString& a_rOther, TINT a_iLength = -1); diff --git a/Toshi/Include/TKernel/TKernelInterface.h b/Toshi/Include/TKernel/TKernelInterface.h index 38040ed..72da02a 100644 --- a/Toshi/Include/TKernel/TKernelInterface.h +++ b/Toshi/Include/TKernel/TKernelInterface.h @@ -20,7 +20,7 @@ class TKERNELINTERFACE_EXPORTS TKernelInterface : public TObject TScheduler* GetScheduler() const { return m_pScheduler.m_pObject; } private: THPTimer m_oSysTimer; // 0x8 - TManagedPointer m_pScheduler; // 0x30 + TManagedPtr m_pScheduler; // 0x30 TFLOAT m_fDeltaTime; // 0x44 TFLOAT m_fAvgFPS; // 0x48 TBOOL m_bVerbose; // 0x4C diff --git a/Toshi/Include/TKernel/TManagedPointer.h b/Toshi/Include/TKernel/TManagedPointer.h index b3cef8d..80acd77 100644 --- a/Toshi/Include/TKernel/TManagedPointer.h +++ b/Toshi/Include/TKernel/TManagedPointer.h @@ -4,20 +4,20 @@ TOSHI_NAMESPACE_BEGIN template -class TManagedPointer +class TManagedPtr { public: - TManagedPointer() : m_pObject(TNULL) + TManagedPtr() : m_pObject(TNULL) { } - TManagedPointer(T* a_pObject) : m_pObject(a_pObject) + TManagedPtr(T* a_pObject) : m_pObject(a_pObject) { } - ~TManagedPointer() + ~TManagedPtr() { delete m_pObject; } diff --git a/Toshi/Include/TKernel/TSystemTools.h b/Toshi/Include/TKernel/TSystemTools.h index 317ff25..49eb03a 100644 --- a/Toshi/Include/TKernel/TSystemTools.h +++ b/Toshi/Include/TKernel/TSystemTools.h @@ -7,14 +7,19 @@ class TKERNELINTERFACE_EXPORTS TSystem { public: + static TPCCHAR TOSHI_API StringUnicodeToChar(TPCHAR a_CharString, TPCWCHAR a_UnicodeString, TINT a_iLength); static TPCCHAR TOSHI_API StringIntToString(TINT a_iInt, TPCHAR a_szString, TINT a_iRadix); static TINT TOSHI_API StringLength(TPCCHAR a_String); + static TINT TOSHI_API StringLength(TPCWCHAR a_String); static TINT TOSHI_API StringCompareNoCase(TPCCHAR a_String1, TPCCHAR a_String2, TINT a_uiSize); static TCHAR const* TOSHI_API StringCopy(TPCHAR a_DestinationString, TCHAR const* a_SourceString, TINT a_iCount); + static TPCWCHAR TOSHI_API StringCopy(TPWCHAR a_DestinationString, TPCWCHAR a_SourceString, TINT a_iCount); static TPVOID TOSHI_API MemCopy(TPVOID a_dest, TPCVOID a_src, TUINT a_iSize); static TPVOID TOSHI_API MemSet(TPVOID a_dest, TINT a_iValue, TINT m_iSize); static TPBYTE GetScratchMem() { return ms_aScratchMem; } + static TPCWCHAR GetTempWString() { return (TPCWCHAR)ms_aScratchMem; } + static TPCHAR GetTempCString() { return (TPCHAR)ms_aScratchMem; } private: inline static TBYTE ms_aScratchMem[1024] = {}; }; diff --git a/Toshi/Include/TKernel/TWString.h b/Toshi/Include/TKernel/TWString.h new file mode 100644 index 0000000..ba9280b --- /dev/null +++ b/Toshi/Include/TKernel/TWString.h @@ -0,0 +1,165 @@ +#pragma once +#include "Defines.h" +#include +#include +#include "TDebug.h" +#include "TSystemTools.h" + +TOSHI_NAMESPACE_BEGIN + +class TKERNELINTERFACE_EXPORTS TWString +{ +public: + + TWString() + { + Reset(); + AllocBuffer(0); + } + + TWString(TINT a_iLength) + { + Reset(); + AllocBuffer(a_iLength); + } + + TWString(const TWString& a_rOther) + { + Reset(); + Copy(a_rOther); + } + + TWString(TPCWCHAR a_pcString) + { + Reset(); + Copy(a_pcString); + } + + ~TWString() + { + FreeBuffer(); + } + + TWString& Concat(TWString const& a_rString, TINT a_iLength = -1); + TWString& Concat(TPCWCHAR a_String, TINT a_iLength = -1); + TINT Compare(TPCWCHAR a_pcString, int a_iLength = -1) const; + + void Copy(const TWString& a_rOther, TINT a_iLength = -1); + void Copy(TPCWCHAR a_pcString, TINT a_iLength = -1); + + TWString& TOSHI_CALLBACKAPI Format(TPCWCHAR a_pcFormat, ...); + TINT Find(TWCHAR a_cFind, TINT a_iIndex = 0) const; + + void Truncate(TINT a_iLength); + + TBOOL IsIndexValid(TINT a_iIndex = 0) const + { + return a_iIndex <= m_iStrLen && a_iIndex >= 0; + } + + TPCWCHAR GetString(TINT a_iIndex = 0) const + { + return IsIndexValid(a_iIndex) ? m_pBuffer + a_iIndex : TNULL; + } + + bool operator!=(TPCWCHAR a_pcString) const + { + return Compare(a_pcString) != 0; + } + + bool operator!=(const TWString& a_rOther) const + { + return Compare(a_rOther.m_pBuffer) != 0; + } + + bool operator==(TPCWCHAR a_pcString) const + { + return Compare(a_pcString) == 0; + } + + bool operator==(const TWString& a_rOther) const + { + return Compare(a_rOther.m_pBuffer) == 0; + } + + TWString& operator=(TPCWCHAR a_pcString) + { + Copy(a_pcString); + return *this; + } + + TWString& operator=(TWString& a_rOther) + { + Copy(a_rOther); + return *this; + } + + operator TPWCHAR() const + { + return m_pBuffer; + } + + TWString& operator+=(TPCWCHAR a_pcString) + { + Concat(a_pcString); + return *this; + } + + TWString& operator+=(TWString const& a_rString) + { + Concat(a_rString); + return *this; + } + + TWCHAR& operator[](TINT a_iIndex) const + { + TASSERT(a_iIndex <= (int) m_iStrLen); + return m_pBuffer[a_iIndex]; + } + + TWCHAR& operator[](TINT a_iIndex) + { + TASSERT(a_iIndex <= (int)m_iStrLen); + return m_pBuffer[a_iIndex]; + } + + const TWString& Print() const + { + TASSERT(GetString() != TNULL); + TDPRINTF("%s", TSystem::StringUnicodeToChar(TSystem::GetTempCString(), GetString(), 0x400)); + return *this; + } + + TINT ExcessLength() const { return m_iExcessLen; } + TINT Length() const { return m_iStrLen; } + +private: + + TBOOL AllocBuffer(TINT a_iLength, TBOOL a_bClear = TTRUE); + + void FreeBuffer() + { + if (m_iStrLen != 0) { + free(m_pBuffer); + m_pBuffer = TNULL; + } + Reset(); + } + + void Reset() + { + m_pBuffer = m_aNull; + m_iExcessLen = 0; + m_iStrLen = 0; + } + +private: + + inline static TWCHAR m_aNull[4] = { 0, 0, 0, 0 }; + + TPWCHAR m_pBuffer; // 0x0 + TINT m_iExcessLen : 8 = 0; // 0x4 + TINT m_iStrLen : 24 = 0; // 0x5 +}; + +TOSHI_NAMESPACE_END \ No newline at end of file diff --git a/Toshi/Include/TRender/Defines.h b/Toshi/Include/TRender/Defines.h index 3d1e4a7..f4e90d0 100644 --- a/Toshi/Include/TRender/Defines.h +++ b/Toshi/Include/TRender/Defines.h @@ -49,16 +49,17 @@ typedef unsigned __int64 TUINT64; typedef short TSHORT; typedef unsigned short TUSHORT; typedef wchar_t TWCHAR; -typedef unsigned short* TPWCHAR; -typedef const char* TPCCHAR; -typedef char* TPCHAR; +typedef wchar_t* TPWCHAR; +typedef const wchar_t* TPCWCHAR; +typedef const char* TPCCHAR; +typedef char* TPCHAR; typedef char TCHAR; typedef const char TCCHAR; typedef char TINT8; typedef unsigned char TUINT8; typedef unsigned char TBYTE; -typedef unsigned char* TPBYTE; -typedef void* TPVOID; -typedef const void* TPCVOID; +typedef unsigned char* TPBYTE; +typedef void* TPVOID; +typedef const void* TPCVOID; typedef float TFLOAT; typedef const float TCFLOAT; \ No newline at end of file diff --git a/Toshi/Include/TRender/TRenderAdapter.h b/Toshi/Include/TRender/TRenderAdapter.h new file mode 100644 index 0000000..bc67297 --- /dev/null +++ b/Toshi/Include/TRender/TRenderAdapter.h @@ -0,0 +1,67 @@ +#pragma once +#include "TKernel/TNodeList.h" +#include "TKernel/TCString.h" +#include "Defines.h" + +#include + +TOSHI_NAMESPACE_BEGIN + +class TRENDERINTERFACE_EXPORTS TRenderAdapter : public TNodeList::TNode +{ +public: + class TRENDERINTERFACE_EXPORTS Mode : public TNodeList::TNode + { + public: + class TRENDERINTERFACE_EXPORTS Device : public TNodeList::TNode + { + public: + Device() = default; + virtual ~Device() = default; + + virtual Mode* GetMode() const = 0; + virtual TUINT GetDeviceIndex() const = 0; + virtual TPCCHAR GetTypeString() const = 0; + virtual TBOOL IsSoftware() const = 0; + virtual TBOOL CanRenderWindowed() const = 0; + virtual TBOOL SupportsHardwareTransfomations() const = 0; + virtual TBOOL IsDepthStencilFormatSupported(TUINT a_iIndex) const = 0; + }; + + public: + Mode() = default; + + virtual ~Mode() = default; + + virtual TRenderAdapter* GetAdapter() const = 0; + virtual TUINT GetModeIndex() const = 0; + virtual TUINT GetWidth() const = 0; + virtual TUINT GetHeight() const = 0; + virtual TBOOL Is32Bit() const = 0; + virtual TBOOL Is16Bit() const = 0; + virtual TUINT GetRefreshRate() const = 0; + virtual TRenderAdapter::Mode::Device* GetDevice(TUINT a_iDevice) = 0; + }; + +public: + TRenderAdapter() = default; + virtual ~TRenderAdapter() = default; + + // TODO: complete vftable + virtual TUINT GetAdapterIndex() const = 0; + virtual const TCString& GetDriver() const = 0; + virtual const TCString& GetDriverDescription() const = 0; + virtual TUSHORT GetProductID() const = 0; + virtual TUSHORT GetVersion() const = 0; + virtual TUSHORT GetSubVersion() const = 0; + virtual TUSHORT GetBuild() const = 0; + virtual const GUID& GetDeviceIdentifier() const = 0; + virtual TUINT GetNumSupportedDevices() const = 0; + + TNodeList* GetModeList() { return &m_Modes; } + +private: + TNodeList m_Modes; // 0x10 +}; + +TOSHI_NAMESPACE_END \ No newline at end of file diff --git a/Toshi/Include/TRender/TRenderInterface.h b/Toshi/Include/TRender/TRenderInterface.h index 5a5de18..d3c9c8a 100644 --- a/Toshi/Include/TRender/TRenderInterface.h +++ b/Toshi/Include/TRender/TRenderInterface.h @@ -4,6 +4,8 @@ #include "TKernel/TKernelInterface.h" #include "TRenderContext.h" #include "TResource.h" +#include "TRenderAdapter.h" +#include "TTextureFactory.h" TOSHI_NAMESPACE_BEGIN @@ -11,6 +13,7 @@ class TRENDERINTERFACE_EXPORTS TRenderInterface : public TObject { DECLARE_DYNAMIC(TRenderInterface) +public: enum FLAG { FLAG_DIRTY = BITFIELD(0), @@ -54,6 +57,8 @@ class TRENDERINTERFACE_EXPORTS TRenderInterface : public TObject TRenderInterface(); virtual TBOOL Create(TKernelInterface* pKernelInterface); + virtual TBOOL IsTextureFormatSupported(TTEXTURERESOURCEFORMAT a_eTextureFormat) { return TTRUE; } + virtual TBOOL Supports32BitTextures() { return TFALSE; } protected: @@ -78,6 +83,7 @@ class TRENDERINTERFACE_EXPORTS TRenderInterface : public TObject } TBOOL IsCreated() { return m_bIsCreated; } + TNodeList* GetAdapterList() { return &m_pAdapterList; }; private: @@ -88,6 +94,7 @@ class TRENDERINTERFACE_EXPORTS TRenderInterface : public TObject TRenderContext* m_pDefaultRenderContext; // 0x20 TKernelInterface* m_pKernel; // 0x24 TResource* m_aSysResources[SYSRESOURCES_NUMOF]; // 0x28 + TNodeList m_pAdapterList; // 0xFC TINT m_iResourceCount; // 0x124 TNodeTree m_Resources; // 0x128 }; diff --git a/Toshi/Include/TRender/TTextureFactory.h b/Toshi/Include/TRender/TTextureFactory.h index fa4821f..e80bbbc 100644 --- a/Toshi/Include/TRender/TTextureFactory.h +++ b/Toshi/Include/TRender/TTextureFactory.h @@ -1,14 +1,26 @@ #pragma once #include "TKernel/TObject.h" -#include "TRenderInterface.h" #include "TKernel/TNodeList.h" #include "TKernel/TSystemTools.h" +#include "Defines.h" +#include "TRender/TResource.h" TOSHI_NAMESPACE_BEGIN +class TRenderInterface; class TTextureResource; +enum TTEXTURERESOURCEFORMAT +{ + UNKNOWN, + R8G8B8A8, + R8G8B8, + R5G5B5A1, + DDS, + R4G4B4A4, +}; + class TRENDERINTERFACE_EXPORTS TTextureFactory : public TResource { DECLARE_DYNAMIC(TTextureFactory) @@ -47,10 +59,11 @@ class TRENDERINTERFACE_EXPORTS TTextureFactory : public TResource public: - static TTextureFactory* TOSHI_API CreateHAL(TRenderInterface* a_pRenderer, TPCCHAR a_szName, TResource* a_pResource) - { - return (TTextureFactory*)a_pRenderer->CreateResource(TClass::Find("TTextureFactoryHAL", TNULL), a_szName, a_pResource); - } + virtual TTextureResource* CreateTextureFromFile(TPCCHAR a_szFileName, TUINT a_eTextureFlags) = 0; + virtual TTextureResource* CreateTextureFromMemory(TPVOID a_pData, TUINT a_uiDataSize, TUINT a_uiWidth, TUINT a_uiHeight, TUINT a_uiMipLevels) = 0; + virtual TTextureResource* CreateEx(TPVOID a_pData, TUINT a_uiDataSize, TUINT a_uiWidth, TUINT a_uiHeight, TUINT a_uiMipLevels, TTEXTURERESOURCEFORMAT a_eFormat, TUINT a_bNoMipLevels) = 0; + + static TTextureFactory* TOSHI_API CreateHAL(TRenderInterface* a_pRenderer, TPCCHAR a_szName, TResource* a_pResource); TTextureResource* FindTexture(TPCCHAR a_szName); diff --git a/Toshi/Include/TRender/TTextureResource.h b/Toshi/Include/TRender/TTextureResource.h index e70aaba..ae0434d 100644 --- a/Toshi/Include/TRender/TTextureResource.h +++ b/Toshi/Include/TRender/TTextureResource.h @@ -1,20 +1,11 @@ #pragma once #include "TKernel/TDebug.h" +#include "TRender/TResource.h" #include "TTextureFactory.h" TOSHI_NAMESPACE_BEGIN -enum TTEXTURERESOURCEFORMAT -{ - UNKNOWN, - R8G8B8A8, - R8G8B8, - R5G5B5A1, - DDS, - R4G4B4A4, -}; - class TRENDERINTERFACE_EXPORTS TTextureResource : public TResource { DECLARE_DYNAMIC(TTextureResource) @@ -22,7 +13,7 @@ class TRENDERINTERFACE_EXPORTS TTextureResource : public TResource friend class TTextureFactory; friend class TTextureFactoryHAL; -protected: +public: virtual TBOOL Create(TPVOID a_pData, TUINT a_uiDataSize, TUINT a_eTextureFlags, TUINT a_uiWidth, TUINT a_uiHeight) = 0; virtual TBOOL Create(TPCCHAR a_szFileName, TUINT a_eTextureFlags) = 0; diff --git a/Toshi/Include/TRenderD3D/Defines.h b/Toshi/Include/TRenderD3D/Defines.h index 31b5c46..e3dd6d9 100644 --- a/Toshi/Include/TRenderD3D/Defines.h +++ b/Toshi/Include/TRenderD3D/Defines.h @@ -49,16 +49,17 @@ typedef unsigned __int64 TUINT64; typedef short TSHORT; typedef unsigned short TUSHORT; typedef wchar_t TWCHAR; -typedef unsigned short* TPWCHAR; -typedef const char* TPCCHAR; -typedef char* TPCHAR; +typedef wchar_t* TPWCHAR; +typedef const wchar_t* TPCWCHAR; +typedef const char* TPCCHAR; +typedef char* TPCHAR; typedef char TCHAR; typedef const char TCCHAR; typedef char TINT8; typedef unsigned char TUINT8; typedef unsigned char TBYTE; -typedef unsigned char* TPBYTE; -typedef void* TPVOID; -typedef const void* TPCVOID; +typedef unsigned char* TPBYTE; +typedef void* TPVOID; +typedef const void* TPCVOID; typedef float TFLOAT; typedef const float TCFLOAT; \ No newline at end of file diff --git a/Toshi/Include/TRenderD3D/TMSWindow.h b/Toshi/Include/TRenderD3D/TMSWindow.h new file mode 100644 index 0000000..9e4f4d2 --- /dev/null +++ b/Toshi/Include/TRenderD3D/TMSWindow.h @@ -0,0 +1,38 @@ +#pragma once +#include "TKernel/TObject.h" +#include "Defines.h" +#include + +TOSHI_NAMESPACE_BEGIN + +class TRenderD3DInterface; + +class TRENDERINTERFACED3D_EXPORTS TMSWindow : public TObject +{ + DECLARE_DYNAMIC(TMSWindow) +public: + + TMSWindow(); + ~TMSWindow(); + + TBOOL Create(TRenderD3DInterface* a_pRenderer, TPCCHAR a_szName); + void Destroy(); + void Disable(); + void Enable(); + void Position(TINT X, TINT Y, TINT cx, TINT cy); + void SetFullscreen(); + void SetWindowed(); + + operator HWND() const { return m_hWnd; } + + HWND GetHWND() const { return m_hWnd; } + TRenderD3DInterface* GetD3DInterface() const { return m_pD3DInterface; } + +private: + HWND m_hWnd; // 0x4 + TRenderD3DInterface *m_pD3DInterface; // 0x8 + TBOOL m_bIsEnabled; // 0xC + TBOOL m_bIsWindowed; // 0xD +}; + +TOSHI_NAMESPACE_END \ No newline at end of file diff --git a/Toshi/Include/TRenderD3D/TRenderD3DAdapter.h b/Toshi/Include/TRenderD3D/TRenderD3DAdapter.h new file mode 100644 index 0000000..ba3a21e --- /dev/null +++ b/Toshi/Include/TRenderD3D/TRenderD3DAdapter.h @@ -0,0 +1,147 @@ +#pragma once + +#include "Defines.h" +#include "TRender/TRenderAdapter.h" +#include "TRender/TRenderInterface.h" +#include + +TOSHI_NAMESPACE_BEGIN + +class TRENDERINTERFACED3D_EXPORTS TD3DAdapter : public TRenderAdapter +{ +public: + class TRENDERINTERFACED3D_EXPORTS Mode : public TRenderAdapter::Mode + { + public: + static constexpr TUINT32 NUMSUPPORTEDDEVICES = 2; + + class TRENDERINTERFACED3D_EXPORTS Device : public TRenderAdapter::Mode::Device + { + public: + friend TD3DAdapter; + friend Mode; + + static constexpr D3DDEVTYPE DEVICETYPES[NUMSUPPORTEDDEVICES] = { + D3DDEVTYPE_HAL, + D3DDEVTYPE_REF + }; + + static constexpr const char* DEVICETYPESSTRINGS[NUMSUPPORTEDDEVICES] = { + "HAL", + "REF" + }; + + static constexpr D3DFORMAT DEPTHSTENCILFORMATS[] = { + D3DFMT_D16, + D3DFMT_D15S1, + D3DFMT_D24X8, + D3DFMT_D24S8, + D3DFMT_D32 + }; + + static constexpr TUINT32 NUMDEPTHSTENCILFORMATS = sizeof(DEPTHSTENCILFORMATS) / sizeof(*DEPTHSTENCILFORMATS); + + public: + virtual TRenderAdapter::Mode* GetMode() const override; + virtual TUINT GetDeviceIndex() const override; + virtual TPCCHAR GetTypeString() const override; + virtual TBOOL IsSoftware() const override; + virtual TBOOL CanRenderWindowed() const override; + virtual TBOOL SupportsHardwareTransfomations() const override; + virtual TBOOL IsDepthStencilFormatSupported(TUINT a_iIndex) const override; + virtual TBOOL SupportsPureDevice() const; + + void SetD3DCaps(const D3DCAPS8& a_rCaps) { m_Caps = a_rCaps; } + void SetOwnerMode(Mode* a_pMode) { m_pOwnerMode = a_pMode; } + void SetDeviceIndex(TUINT32 a_uiIndex) { m_uiDeviceIndex = a_uiIndex; } + + TUINT32 GetD3DDeviceFlags() const { return m_eFlags; } + + D3DCAPS8& GetD3DCaps() { return m_Caps; } + const D3DCAPS8& GetD3DCaps() const { return m_Caps; } + + private: + D3DCAPS8 m_Caps; + TUINT32 m_eFlags; + Mode* m_pOwnerMode; + TUINT32 m_uiDeviceIndex; + TBOOL m_bIsSoftware; + TBOOL m_bCanRenderWindowed; + TBOOL m_bSupportsTransformation; + TBOOL m_bSupportsPureDevice; + TBOOL m_bSupportsNPatches; + TBOOL m_aSupportedDSFormats[NUMDEPTHSTENCILFORMATS]; + }; + + public: + virtual TRenderAdapter* GetAdapter() const override; + virtual TUINT GetModeIndex() const override; + virtual TUINT GetWidth() const override; + virtual TUINT GetHeight() const override; + virtual TBOOL Is32Bit() const override; + virtual TBOOL Is16Bit() const override; + virtual TUINT GetRefreshRate() const override; + virtual TRenderAdapter::Mode::Device* GetDevice(TUINT a_iDevice) override; + + D3DFORMAT GetBackBufferFormat(TUINT a_uiColourDepth); + + void SetOwnerAdapter(TD3DAdapter* a_pOwnerAdapter) { m_pOwnerAdapter = a_pOwnerAdapter; } + void SetModeIndex(TUINT a_uiModeIndex) { m_uiModeIndex = a_uiModeIndex; } + + void SetD3DDisplayMode(const D3DDISPLAYMODE& a_rDisplayMode) { m_DisplayMode = a_rDisplayMode; } + D3DDISPLAYMODE& GetD3DDisplayMode() { return m_DisplayMode; } + + private: + TD3DAdapter* m_pOwnerAdapter; + D3DDISPLAYMODE m_DisplayMode; + TUINT32 m_uiModeIndex; + Device m_aDevices[NUMSUPPORTEDDEVICES]; + }; + +public: + virtual TUINT GetAdapterIndex() const override; + virtual const TCString& GetDriver() const override; + virtual const TCString& GetDriverDescription() const override; + virtual TUSHORT GetProductID() const override; + virtual TUSHORT GetVersion() const override; + virtual TUSHORT GetSubVersion() const override; + virtual TUSHORT GetBuild() const override; + virtual const GUID& GetDeviceIdentifier() const override; + virtual TUINT GetNumSupportedDevices() const override; + + void SetAdapterIndex(TUINT a_uiAdapterIndex) { m_uiAdapterIndex = a_uiAdapterIndex; } + void SetDriver(const TCString& a_rDriver) { m_Driver = a_rDriver; } + void SetDescription(const TCString& a_rDescription) { m_Description = a_rDescription; } + void SetDriverVersionLowPart(DWORD a_uiDriverVersionLowPart) { m_DriverVersionLowPart = a_uiDriverVersionLowPart; } + void SetDriverVersionHighPart(DWORD a_uiDriverVersionHighPart) { m_DriverVersionHighPart = a_uiDriverVersionHighPart; } + void SetVendorId(DWORD a_uiVendorId) { m_VendorId = a_uiVendorId; } + void SetDeviceId(DWORD a_uiDeviceId) { m_DeviceId = a_uiDeviceId; } + void SetSubSysId(DWORD a_uiSubSysId) { m_SubSysId = a_uiSubSysId; } + void SetRevision(DWORD a_uiRevision) { m_Revision = a_uiRevision; } + void SetDeviceIdentifier(const GUID& a_rDeviceIdentifier) { m_DeviceIdentifier = a_rDeviceIdentifier; } + + Mode& GetMode() { return m_Mode; } + const Mode& GetMode() const { return m_Mode; } + + D3DADAPTER_IDENTIFIER8* GetD3DIdentifier8() { return &m_Identifier; } + const D3DADAPTER_IDENTIFIER8* GetD3DIdentifier8() const { return &m_Identifier; } + + void EnumerateOutputs(TRenderInterface* a_pRenderer); + +private: + D3DADAPTER_IDENTIFIER8 m_Identifier; + Mode m_Mode; + TUINT32 m_uiAdapterIndex; + TCString m_Driver; + TCString m_Description; + DWORD m_DriverVersionLowPart; + DWORD m_DriverVersionHighPart; + DWORD m_VendorId; + DWORD m_DeviceId; + DWORD m_SubSysId; + DWORD m_Revision; + GUID m_DeviceIdentifier; +}; + + +TOSHI_NAMESPACE_END diff --git a/Toshi/Include/TRenderD3D/TRenderD3DInterface.h b/Toshi/Include/TRenderD3D/TRenderD3DInterface.h index e2e5ee3..1d2c3e0 100644 --- a/Toshi/Include/TRenderD3D/TRenderD3DInterface.h +++ b/Toshi/Include/TRenderD3D/TRenderD3DInterface.h @@ -2,19 +2,55 @@ #include "Defines.h" #include "TKernel/TDebug.h" #include "TRender/TRenderInterface.h" +#include "TKernel/TKernelInterface.h" +#include "TRenderD3D/TMSWindow.h" +#include "TRenderD3D/TRenderD3DAdapter.h" #include TOSHI_NAMESPACE_BEGIN +class TMSWindow; + class TRENDERINTERFACED3D_EXPORTS TRenderD3DInterface : public TRenderInterface { public: + + TRenderD3DInterface(); + static void TOSHI_API TD3DAssert(HRESULT a_hr, TPCCHAR a_pError); + virtual TBOOL Create(TKernelInterface* a_pKernel) override; + virtual TBOOL IsTextureFormatSupported(TTEXTURERESOURCEFORMAT a_eTextureFormat) override; + virtual TBOOL Supports32BitTextures() override; + + TBOOL IsTextureFormatSupported(D3DFORMAT a_eFormat); + void Exit() { m_bIsExited = TTRUE; } + +private: + + void BuildAdapterDatabase(); + void CreateAcceleratorTableA(); + void DestroyAcceleratorTable(); + +protected: + + TBOOL LoadShaders(); + +public: + IDirect3DDevice8* GetD3DDevice() { return m_pD3DDevice; } + IDirect3D8* GetD3DInterface() { return m_pD3DInterface; } + TMSWindow* GetMSWindow() { return &m_pMSWindow; } + TD3DAdapter::Mode::Device* GetCurrentDevice() { return m_pCurrentDevice; } private: - IDirect3DDevice8* m_pD3DDevice; // 0x180 + IDirect3D8* m_pD3DInterface; // 0x17C + IDirect3DDevice8* m_pD3DDevice; // 0x180 + D3DPRESENT_PARAMETERS m_oPresentParams; // 0x18C + HACCEL m_hAccel; // 0x1DC + TD3DAdapter::Mode::Device* m_pCurrentDevice; // 0x1E0 + TMSWindow m_pMSWindow; // 0x1F8 + TBOOL m_bIsExited; // 0x208 }; TOSHI_NAMESPACE_END \ No newline at end of file diff --git a/Toshi/Include/TRenderD3D/TTextureFactoryD3D.h b/Toshi/Include/TRenderD3D/TTextureFactoryD3D.h index e9f6058..eb84bc5 100644 --- a/Toshi/Include/TRenderD3D/TTextureFactoryD3D.h +++ b/Toshi/Include/TRenderD3D/TTextureFactoryD3D.h @@ -1,7 +1,7 @@ #pragma once #include "Defines.h" #include "TRender/TResource.h" -#include "TRender/TTextureResource.h" +#include "TRender/TTextureFactory.h" TOSHI_NAMESPACE_BEGIN @@ -11,10 +11,9 @@ class TRENDERINTERFACED3D_EXPORTS TTextureFactoryHAL : public TTextureFactory public: - virtual TTextureResource* CreateTextureFromFile(TPCCHAR a_szFileName, TUINT a_eTextureFlags); - virtual TTextureResource* CreateTextureFromMemory(TPVOID a_pData, TUINT a_uiDataSize, TUINT a_uiWidth, TUINT a_uiHeight, TUINT a_uiMipLevels); - - virtual TTextureResource* CreateEx(TPVOID a_pData, TUINT a_uiDataSize, TUINT a_uiWidth, TUINT a_uiHeight, TUINT a_uiMipLevels, TTEXTURERESOURCEFORMAT a_eFormat, BOOL a_bNoMipLevels); + virtual TTextureResource* CreateTextureFromFile(TPCCHAR a_szFileName, TUINT a_eTextureFlags) override; + virtual TTextureResource* CreateTextureFromMemory(TPVOID a_pData, TUINT a_uiDataSize, TUINT a_uiWidth, TUINT a_uiHeight, TUINT a_uiMipLevels) override; + virtual TTextureResource* CreateEx(TPVOID a_pData, TUINT a_uiDataSize, TUINT a_uiWidth, TUINT a_uiHeight, TUINT a_uiMipLevels, TTEXTURERESOURCEFORMAT a_eFormat, TUINT a_bNoMipLevels) override; }; diff --git a/Toshi/Source/TKernel/TCString.cpp b/Toshi/Source/TKernel/TCString.cpp index 12efc2a..f01e0a8 100644 --- a/Toshi/Source/TKernel/TCString.cpp +++ b/Toshi/Source/TKernel/TCString.cpp @@ -13,7 +13,7 @@ TBOOL TCString::AllocBuffer(TINT a_iLength, TBOOL a_bClear) if (a_iLength != m_iStrLen) { if (a_iLength == 0) { - if (a_bClear) free(m_pBuffer); + if (a_bClear) tfree(m_pBuffer); m_pBuffer = m_aNull; hasChanged = TTRUE; @@ -23,9 +23,9 @@ TBOOL TCString::AllocBuffer(TINT a_iLength, TBOOL a_bClear) TINT newExcessLen = (m_iStrLen - a_iLength) + m_iExcessLen; if (newExcessLen < 0 || newExcessLen > 0xFF) { - if (m_iStrLen != 0 && a_bClear) free(m_pBuffer); + if (m_iStrLen != 0 && a_bClear) tfree(m_pBuffer); - m_pBuffer = (TPCHAR)malloc(a_iLength + 1); + m_pBuffer = (TPCHAR)tmalloc(a_iLength + 1, TNULL, -1); m_iExcessLen = 0; TASSERT(m_pBuffer!=TNULL); hasChanged = TTRUE; @@ -53,7 +53,27 @@ TCString& TCString::Concat(TCString const& a_rString, TINT a_iLength) if (ret) { TSystem::StringCopy(m_pBuffer, pBuffer, -1); } - TSystem::StringCopy(m_pBuffer + len, a_rString.m_pBuffer, a_iLength); + TSystem::StringCopy(&m_pBuffer[len], a_rString.m_pBuffer, a_iLength); + m_pBuffer[len + a_iLength] = '\0'; + if (ret && len != 0) { + tfree(pBuffer); + } + return *this; +} + +TCString& TCString::Concat(TPCCHAR a_String, TINT a_iLength) +{ + TINT len = TSystem::StringLength(a_String); + if (len < a_iLength || a_iLength == -1) { + a_iLength = len; + } + TPCHAR pBuffer = m_pBuffer; + len = Length(); + TBOOL ret = AllocBuffer(len + a_iLength, TFALSE); + if (ret) { + TSystem::StringCopy(m_pBuffer, pBuffer, -1); + } + TSystem::StringCopy(&m_pBuffer[len], a_String, a_iLength); m_pBuffer[len + a_iLength] = '\0'; if (ret && len != 0) { tfree(pBuffer); diff --git a/Toshi/Source/TKernel/TSystemTools.cpp b/Toshi/Source/TKernel/TSystemTools.cpp index 8ff616e..049ca2e 100644 --- a/Toshi/Source/TKernel/TSystemTools.cpp +++ b/Toshi/Source/TKernel/TSystemTools.cpp @@ -5,6 +5,23 @@ TOSHI_NAMESPACE_USING +TPCCHAR TOSHI_API TSystem::StringUnicodeToChar(TPCHAR a_CharString, TPCWCHAR a_UnicodeString, TINT a_iLength) +{ + TASSERT((a_UnicodeString!=TNULL) && (a_CharString!=TNULL)); + TINT iUnicodeStringLength = StringLength(a_UnicodeString); + + if (iUnicodeStringLength < a_iLength || a_iLength == -1) { + a_iLength = iUnicodeStringLength; + } + + for (size_t i = 0; i < a_iLength; i++) { + a_CharString[i] = TSTATICCAST(char, a_UnicodeString[i]); + } + + a_CharString[a_iLength] = '\0'; + return a_CharString; +} + TPCCHAR TOSHI_API TSystem::StringIntToString(TINT a_iInt, TPCHAR a_szString, TINT a_iRadix) { if (a_iRadix == 8) { @@ -30,6 +47,12 @@ TINT TOSHI_API TSystem::StringLength(TPCCHAR a_String) return iLength; } +TINT TOSHI_API TSystem::StringLength(TPCWCHAR a_String) +{ + TASSERT(a_String != TNULL); + return wcslen(a_String); +} + TINT TOSHI_API TSystem::StringCompareNoCase(TPCCHAR a_String1, TPCCHAR a_String2, TINT a_uiSize) { TASSERT((a_String1!=TNULL) && (a_String2!=TNULL)); @@ -51,6 +74,15 @@ TCHAR const* TOSHI_API TSystem::StringCopy(TPCHAR a_DestinationString, TCHAR con return a_DestinationString; } +TPCWCHAR TOSHI_API TSystem::StringCopy(TPWCHAR a_DestinationString, TPCWCHAR a_SourceString, TINT a_iCount) +{ + TASSERT((a_DestinationString != TNULL) && (a_SourceString != TNULL)); + if (a_iCount != -1) { + return wcsncpy(a_DestinationString, a_SourceString, a_iCount); + } + return wcscpy(a_DestinationString, a_SourceString); +} + TPVOID TOSHI_API TSystem::MemCopy(TPVOID a_dest, TPCVOID a_src, TUINT a_iSize) { // Note: Idk if they used gcclib's memcpy() or their own diff --git a/Toshi/Source/TKernel/TWString.cpp b/Toshi/Source/TKernel/TWString.cpp new file mode 100644 index 0000000..f1159ef --- /dev/null +++ b/Toshi/Source/TKernel/TWString.cpp @@ -0,0 +1,152 @@ +#include "TWString.h" +#include "TSystemTools.h" +#include +#include + +TOSHI_NAMESPACE_USING + +TBOOL TWString::AllocBuffer(TINT a_iLength, TBOOL a_bClear) +{ + TASSERT(a_iLength >= 0); + + TBOOL hasChanged = TFALSE; + + if (a_iLength != m_iStrLen) { + if (a_iLength == 0) { + if (a_bClear) tfree(m_pBuffer); + + m_pBuffer = m_aNull; + hasChanged = TTRUE; + m_iExcessLen = 0; + } + else { + TINT newExcessLen = (m_iStrLen - a_iLength * 2) + m_iExcessLen; + + if (newExcessLen < 0 || newExcessLen > 0xFF) { + if (m_iStrLen != 0 && a_bClear) tfree(m_pBuffer); + + m_pBuffer = (TPWCHAR)tmalloc((a_iLength * 2) + 1, TNULL, -1); + m_iExcessLen = 0; + TASSERT(m_pBuffer != TNULL); + hasChanged = TTRUE; + } + else { + m_iExcessLen = newExcessLen; + hasChanged = TFALSE; + } + } + m_iStrLen = a_iLength; + } + if (a_bClear) m_pBuffer[0] = '\0'; + return hasChanged; +} + +TWString& TWString::Concat(TWString const& a_rString, TINT a_iLength) +{ + TINT len = a_rString.Length(); + if (len < a_iLength || a_iLength == -1) { + a_iLength = len; + } + TPWCHAR pBuffer = m_pBuffer; + len = Length(); + TBOOL ret = AllocBuffer(len + a_iLength, TFALSE); + if (ret) { + TSystem::StringCopy(m_pBuffer, pBuffer, -1); + } + TSystem::StringCopy(&m_pBuffer[len], a_rString.m_pBuffer, a_iLength); + m_pBuffer[len + a_iLength] = '\0'; + if (ret && len != 0) { + tfree(pBuffer); + } + return *this; +} + +TWString& TWString::Concat(TPCWCHAR a_String, TINT a_iLength) +{ + TINT len = TSystem::StringLength(a_String); + if (len < a_iLength || a_iLength == -1) { + a_iLength = len; + } + TPWCHAR pBuffer = m_pBuffer; + len = Length(); + TBOOL ret = AllocBuffer(len + a_iLength, TFALSE); + if (ret) { + TSystem::StringCopy(m_pBuffer, pBuffer, -1); + } + TSystem::StringCopy(&m_pBuffer[len], a_String, a_iLength); + m_pBuffer[len + a_iLength] = '\0'; + if (ret && len != 0) { + tfree(pBuffer); + } + return *this; +} + +TINT TWString::Compare(TPCWCHAR a_pcString, int a_iLength) const +{ + TASSERT(a_pcString != TNULL); + TASSERT(GetString() != TNULL); + if (a_iLength != -1) + { + return wcsncmp(GetString(), a_pcString, a_iLength); + } + return wcscmp(GetString(), a_pcString); +} + +void TWString::Copy(const TWString& a_rOther, TINT a_iLength) +{ + if (*this != a_rOther) { + if (a_rOther.m_iStrLen < a_iLength || a_iLength == -1) a_iLength = a_rOther.m_iStrLen; + AllocBuffer(a_iLength); + TSystem::MemCopy(m_pBuffer, a_rOther.m_pBuffer, a_iLength); + m_pBuffer[a_iLength] = '\0'; + } +} + +void TWString::Copy(TPCWCHAR a_pcString, TINT a_iLength) +{ + if (m_pBuffer != a_pcString) { + TINT iLength = a_pcString ? TSystem::StringLength(a_pcString) : 0; + if (iLength < a_iLength || a_iLength == -1) a_iLength = iLength; + AllocBuffer(a_iLength, TTRUE); + TSystem::MemCopy(m_pBuffer, a_pcString, a_iLength); + m_pBuffer[a_iLength] = '\0'; + } +} + +TWString& TOSHI_CALLBACKAPI TWString::Format(TPCWCHAR a_pcFormat, ...) +{ + TWCHAR buffer[0x400]; + va_list vargs; + va_start(vargs, a_pcFormat); + _vsnwprintf(buffer, sizeof(buffer), a_pcFormat, vargs); + va_end(vargs); + Copy(buffer); + return *this; +} + +TINT TWString::Find(TWCHAR a_cFind, TINT a_iIndex) const +{ + if (!IsIndexValid(a_iIndex)) return -1; + TPCWCHAR foundAt = wcschr(GetString() + a_iIndex, a_cFind); + if (foundAt == TNULL) return -1; + + return foundAt - GetString() >> 1; +} + +void TWString::Truncate(TINT a_iLength) +{ + TINT len = Length(); + if (len < a_iLength) { + a_iLength = len; + } + TPWCHAR pBuffer = m_pBuffer; + TBOOL ret = AllocBuffer(a_iLength, TFALSE); + if (ret) { + TSystem::StringCopy(m_pBuffer, pBuffer, a_iLength); + } + m_pBuffer[a_iLength] = '\0'; + if (ret && len != 0) { + tfree(pBuffer); + } +} + diff --git a/Toshi/Source/TRender/TRenderAdapter.cpp b/Toshi/Source/TRender/TRenderAdapter.cpp new file mode 100644 index 0000000..d7c417f --- /dev/null +++ b/Toshi/Source/TRender/TRenderAdapter.cpp @@ -0,0 +1 @@ +#include "TRenderAdapter.h" \ No newline at end of file diff --git a/Toshi/Source/TRender/TTextureFactory.cpp b/Toshi/Source/TRender/TTextureFactory.cpp index 6b465af..c58005b 100644 --- a/Toshi/Source/TRender/TTextureFactory.cpp +++ b/Toshi/Source/TRender/TTextureFactory.cpp @@ -1,10 +1,32 @@ #include "TTextureFactory.h" +#include "TRender/TRenderInterface.h" #include "TTextureResource.h" + TOSHI_NAMESPACE_USING IMPLEMENT_DYNAMIC(TTextureFactory, TResource) +TTextureResource* TTextureFactory::CreateTextureFromFile(TPCCHAR a_szFileName, TUINT a_eTextureFlags) +{ + return TNULL; +} + +TTextureResource* TTextureFactory::CreateTextureFromMemory(TPVOID a_pData, TUINT a_uiDataSize, TUINT a_uiWidth, TUINT a_uiHeight, TUINT a_uiMipLevels) +{ + return TNULL; +} + +TTextureResource* TTextureFactory::CreateEx(TPVOID a_pData, TUINT a_uiDataSize, TUINT a_uiWidth, TUINT a_uiHeight, TUINT a_uiMipLevels, TTEXTURERESOURCEFORMAT a_eFormat, TUINT a_bNoMipLevels) +{ + return TNULL; +} + +TTextureFactory* TOSHI_API TTextureFactory::CreateHAL(TRenderInterface* a_pRenderer, TPCCHAR a_szName, TResource* a_pResource) +{ + return (TTextureFactory*)a_pRenderer->CreateResource(TClass::Find("TTextureFactoryHAL", TNULL), a_szName, a_pResource); +} + TTextureResource* TTextureFactory::FindTexture(TPCCHAR a_szName) { auto pList = &m_aLists[HashName(a_szName)]; diff --git a/Toshi/Source/TRenderD3D/TMSWindow.cpp b/Toshi/Source/TRenderD3D/TMSWindow.cpp new file mode 100644 index 0000000..210e0db --- /dev/null +++ b/Toshi/Source/TRenderD3D/TMSWindow.cpp @@ -0,0 +1,149 @@ +#include "TRenderD3D/TMSWindow.h" +#include "TRenderD3D/TRenderD3DInterface.h" + +TOSHI_NAMESPACE_USING + +IMPLEMENT_DYNCREATE(TMSWindow, TObject) + +LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, + WPARAM wParam, LPARAM lParam); + +TMSWindow::TMSWindow() +{ + m_hWnd = NULL; + m_pD3DInterface = TNULL; + m_bIsEnabled = TFALSE; + m_bIsWindowed = TTRUE; + + TCString className = TGetClass(TRenderD3DInterface).GetName(); + Destroy(); + + WNDCLASSEX wndClass; + wndClass.cbSize = sizeof(WNDCLASSEX); + wndClass.style = CS_CLASSDC; + wndClass.lpfnWndProc = WindowProc; + wndClass.cbClsExtra = 0; // No extra bytes after the window class + wndClass.cbWndExtra = 0; // structure or the window instance + wndClass.hInstance = 0; + wndClass.hIcon = 0; + wndClass.hCursor = 0; + wndClass.hbrBackground = 0; + wndClass.lpszMenuName = 0; + wndClass.lpszClassName = 0; + wndClass.hIconSm = 0; + wndClass.hInstance = GetModuleHandle(NULL); + wndClass.lpszClassName = className; + + RegisterClassEx(&wndClass); +} + +TMSWindow::~TMSWindow() +{ + TCString className = TGetClass(TRenderD3DInterface).GetName(); + UnregisterClass(className, GetModuleHandle(NULL)); +} + +LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, + WPARAM wParam, LPARAM lParam) +{ + TMSWindow* pWindow; + if (message == WM_CREATE) { + SetWindowLong(hWnd, GWL_USERDATA, lParam); + return 0; + } + if (message != WM_CLOSE) { + if (message == WM_PAINT) { + PAINTSTRUCT paint; + BeginPaint(hWnd, &paint); + EndPaint(hWnd, &paint); + return 0; + } + if (message != WM_SIZE) { + if (message == WM_COMMAND && LOWORD(wParam) == 0) { + return 0; + } + else if (message != WM_DESTROY) { + if (message == WM_SETCURSOR) { + SetCursor(NULL); + pWindow = (TMSWindow*)GetWindowLongA(hWnd, GWL_USERDATA); + pWindow->GetD3DInterface()->GetD3DDevice()->ShowCursor(TRUE); + return 1; + } + return DefWindowProcA(hWnd, message, wParam, lParam); + } + } + return 0; + } + pWindow = (TMSWindow*)GetWindowLongA(hWnd, GWL_USERDATA); + pWindow->GetD3DInterface()->Exit(); + return 0; +} + +TBOOL TMSWindow::Create(TRenderD3DInterface* a_pRenderer, TPCCHAR a_szName) +{ + Destroy(); + m_pD3DInterface = a_pRenderer; + m_hWnd = CreateWindowEx( + 0, + TGetClass(TRenderD3DInterface).GetName(), + a_szName, + WS_DISABLED | WS_CAPTION | WS_SYSMENU | WS_GROUP, + 0, 0, 0, 0, + GetDesktopWindow(), + NULL, + GetModuleHandle(NULL), + this + ); + + if (m_hWnd) { + Disable(); + return TTRUE; + } + return TFALSE; +} + +void TMSWindow::Destroy() +{ + if (GetHWND() != TNULL) { + Disable(); + DestroyWindow(GetHWND()); + m_hWnd = NULL; + } + m_pD3DInterface = TNULL; +} + +void TMSWindow::Disable() +{ + TASSERT(GetHWND() != TNULL); + EnableWindow(GetHWND(), FALSE); + ShowWindow(GetHWND(), SW_HIDE); + m_bIsEnabled = TFALSE; +} + +void TMSWindow::Enable() +{ + TASSERT(GetHWND() != TNULL); + EnableWindow(GetHWND(), TRUE); + ShowWindow(GetHWND(), SW_SHOW); + m_bIsEnabled = TTRUE; +} + +void TMSWindow::Position(TINT X, TINT Y, TINT cx, TINT cy) +{ + TASSERT(GetHWND() != TNULL); + SetWindowPos(GetHWND(), NULL, X, Y, cx, cy, 0); +} + +void TMSWindow::SetFullscreen() +{ + TASSERT(GetHWND() != TNULL); + SetWindowLong(GetHWND(), GWL_STYLE, (WS_POPUP | WS_SYSMENU)); + m_bIsWindowed = TFALSE; +} + +void TMSWindow::SetWindowed() +{ + TASSERT(GetHWND() != TNULL); + SetWindowLong(GetHWND(), GWL_STYLE, (WS_CAPTION | WS_SYSMENU | WS_GROUP)); + m_bIsWindowed = TTRUE; +} diff --git a/Toshi/Source/TRenderD3D/TRenderD3DAdapter.cpp b/Toshi/Source/TRenderD3D/TRenderD3DAdapter.cpp new file mode 100644 index 0000000..c51dd1d --- /dev/null +++ b/Toshi/Source/TRenderD3D/TRenderD3DAdapter.cpp @@ -0,0 +1,258 @@ +#include "TRenderD3D/TRenderD3DAdapter.h" +#include "TRenderD3D/TRenderD3DInterface.h" + +TOSHI_NAMESPACE_USING + +TUINT TD3DAdapter::GetAdapterIndex() const +{ + return m_uiAdapterIndex; +} + +const TCString& TD3DAdapter::GetDriver() const +{ + return m_Driver; +} + +const TCString& TD3DAdapter::GetDriverDescription() const +{ + return m_Description; +} + +TUSHORT TD3DAdapter::GetProductID() const +{ + return m_DriverVersionHighPart >> 16; +} + +TUSHORT TD3DAdapter::GetVersion() const +{ + return m_DriverVersionHighPart & 0xFFFF; +} + +TUSHORT TD3DAdapter::GetSubVersion() const +{ + return m_DriverVersionLowPart >> 16; +} + +TUSHORT TD3DAdapter::GetBuild() const +{ + return m_DriverVersionLowPart & 0xFFFF; +} + +const GUID& TD3DAdapter::GetDeviceIdentifier() const +{ + return m_DeviceIdentifier; +} + +TUINT TD3DAdapter::GetNumSupportedDevices() const +{ + return Mode::NUMSUPPORTEDDEVICES; +} + +void TD3DAdapter::EnumerateOutputs(TRenderInterface* a_pRenderer) +{ + TRenderD3DInterface* pRenderer = TSTATICCAST(TRenderD3DInterface*, a_pRenderer); + + TUINT32 uiAdapterIndex = GetAdapterIndex(); + TUINT32 uiNumSupportedDevices = GetNumSupportedDevices(); + TUINT32 uiAdapterModeCount = pRenderer->GetD3DInterface()->GetAdapterModeCount(uiAdapterIndex); + + for (TUINT32 i = 0; i < uiAdapterModeCount; i++) + { + auto pMode = new Mode(); + + pMode->SetOwnerAdapter(this); + pMode->SetModeIndex(i); + + pRenderer->GetD3DInterface()->EnumAdapterModes(uiAdapterIndex, i, &pMode->GetD3DDisplayMode()); + + for (TUINT32 k = 0; k < uiNumSupportedDevices; k++) + { + auto pDevice = TSTATICCAST(TD3DAdapter::Mode::Device*, pMode->GetDevice(k)); + + pDevice->SetOwnerMode(pMode); + pDevice->SetDeviceIndex(k); + + pRenderer->GetD3DInterface()->GetDeviceCaps(uiAdapterIndex, Mode::Device::DEVICETYPES[k], &pDevice->GetD3DCaps()); + HRESULT hRes = pRenderer->GetD3DInterface()->CheckDeviceType( + uiAdapterIndex, + Mode::Device::DEVICETYPES[k], + pMode->GetD3DDisplayMode().Format, + pMode->GetD3DDisplayMode().Format, + FALSE + ); + + if (SUCCEEDED(hRes)) + { + auto& caps = pDevice->GetD3DCaps(); + + if (Mode::Device::DEVICETYPES[k] == D3DDEVTYPE_REF) + { + pDevice->m_bIsSoftware = TTRUE; + } + + if (caps.Caps2 & D3DCAPS2_CANRENDERWINDOWED) + { + pDevice->m_bCanRenderWindowed = TTRUE; + } + + if (caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) + { + pDevice->m_bSupportsTransformation = TTRUE; + pDevice->m_bSupportsPureDevice = caps.DevCaps & D3DDEVCAPS_PUREDEVICE; + } + + if (caps.DevCaps & D3DDEVCAPS_NPATCHES) + { + pDevice->m_bSupportsNPatches = TTRUE; + } + + if (pDevice->SupportsHardwareTransfomations()) + { + if (pDevice->SupportsPureDevice()) + { + pDevice->m_eFlags |= D3DCREATE_HARDWARE_VERTEXPROCESSING; + } + else + { + pDevice->m_eFlags |= D3DCREATE_MIXED_VERTEXPROCESSING; + } + } + else + { + pDevice->m_eFlags |= D3DCREATE_SOFTWARE_VERTEXPROCESSING; + } + + for (int j = 0; j < Mode::Device::NUMDEPTHSTENCILFORMATS; j++) + { + if (Mode::Device::DEPTHSTENCILFORMATS[j] != D3DFMT_UNKNOWN) + { + HRESULT hCheck = pRenderer->GetD3DInterface()->CheckDeviceFormat( + uiAdapterIndex, + Mode::Device::DEVICETYPES[k], + pMode->GetD3DDisplayMode().Format, + D3DUSAGE_DEPTHSTENCIL, + D3DRTYPE_SURFACE, + Mode::Device::DEPTHSTENCILFORMATS[j] + ); + + if (SUCCEEDED(hCheck)) + { + HRESULT hMatch = pRenderer->GetD3DInterface ()->CheckDepthStencilMatch( + uiAdapterIndex, + Mode::Device::DEVICETYPES[k], + pMode->GetD3DDisplayMode().Format, + pMode->GetD3DDisplayMode().Format, + Mode::Device::DEPTHSTENCILFORMATS[j] + ); + + if (SUCCEEDED(hMatch)) + { + pDevice->m_aSupportedDSFormats[j] = TTRUE; + } + } + } + } + } + } + + GetModeList()->InsertTail(*pMode); + } +} + +TRenderAdapter* TD3DAdapter::Mode::GetAdapter() const +{ + return m_pOwnerAdapter; +} + +TUINT TD3DAdapter::Mode::GetModeIndex() const +{ + return m_uiModeIndex; +} + +TUINT TD3DAdapter::Mode::GetWidth() const +{ + return m_DisplayMode.Width; +} + +TUINT TD3DAdapter::Mode::GetHeight() const +{ + return m_DisplayMode.Height; +} + +TBOOL TD3DAdapter::Mode::Is32Bit() const +{ + return m_DisplayMode.Format == D3DFMT_X8R8G8B8; +} + +TBOOL TD3DAdapter::Mode::Is16Bit() const +{ + return + m_DisplayMode.Format == D3DFMT_R5G6B5 || + m_DisplayMode.Format == D3DFMT_X1R5G5B5 || + m_DisplayMode.Format == D3DFMT_X4R4G4B4; +} + +TUINT TD3DAdapter::Mode::GetRefreshRate() const +{ + return m_DisplayMode.RefreshRate; +} + +TRenderAdapter::Mode::Device* TD3DAdapter::Mode::GetDevice(TUINT a_iDevice) +{ + if (a_iDevice >= 0 && a_iDevice < NUMSUPPORTEDDEVICES) + { + return &m_aDevices[a_iDevice]; + } + + return TNULL; +} + +D3DFORMAT TD3DAdapter::Mode::GetBackBufferFormat(TUINT a_uiColourDepth) +{ + if (a_uiColourDepth == 16) + { + return TSTATICCAST(D3DFORMAT, (-(TUINT32)((*(TUINT8*)&(m_DisplayMode).Format & 0x17) != 0) & 0xfffffff9) + D3DFMT_X4R4G4B4); + } + + return TSTATICCAST(D3DFORMAT, (a_uiColourDepth != 32) - 1 & 0x16); +} + +TRenderAdapter::Mode* TD3DAdapter::Mode::Device::GetMode() const +{ + return m_pOwnerMode; +} + +TUINT TD3DAdapter::Mode::Device::GetDeviceIndex() const +{ + return m_uiDeviceIndex; +} + +TPCCHAR TD3DAdapter::Mode::Device::GetTypeString() const +{ + return DEVICETYPESSTRINGS[m_uiDeviceIndex]; +} + +TBOOL TD3DAdapter::Mode::Device::IsSoftware() const +{ + return m_bIsSoftware; +} + +TBOOL TD3DAdapter::Mode::Device::CanRenderWindowed() const +{ + return m_bCanRenderWindowed; +} + +TBOOL TD3DAdapter::Mode::Device::SupportsHardwareTransfomations() const +{ + return m_bSupportsTransformation; +} + +TBOOL TD3DAdapter::Mode::Device::IsDepthStencilFormatSupported(TUINT a_iIndex) const +{ + return m_aSupportedDSFormats[a_iIndex]; +} + +TBOOL TD3DAdapter::Mode::Device::SupportsPureDevice() const +{ + return m_bSupportsPureDevice; +} \ No newline at end of file diff --git a/Toshi/Source/TRenderD3D/TRenderD3DInterface.cpp b/Toshi/Source/TRenderD3D/TRenderD3DInterface.cpp index 457c01a..a51c57a 100644 --- a/Toshi/Source/TRenderD3D/TRenderD3DInterface.cpp +++ b/Toshi/Source/TRenderD3D/TRenderD3DInterface.cpp @@ -1,8 +1,18 @@ #include "TRenderD3D/TRenderD3DInterface.h" +#include "TKernel/TWString.h" +#include "TRenderD3D/TRenderD3DAdapter.h" #include TOSHI_NAMESPACE_USING +TRenderD3DInterface::TRenderD3DInterface() +{ + m_pD3DInterface = NULL; + m_pD3DDevice = NULL; + m_hAccel = NULL; + m_bIsExited = TFALSE; +} + void TOSHI_API TRenderD3DInterface::TD3DAssert(HRESULT a_hr, TPCCHAR a_pError) { if (FAILED(a_hr)) { @@ -15,3 +25,124 @@ void TOSHI_API TRenderD3DInterface::TD3DAssert(HRESULT a_hr, TPCCHAR a_pError) TASSERT(SUCCEEDED(a_hr)); } } + +TBOOL TRenderD3DInterface::Create(TKernelInterface* a_pKernel) +{ + TASSERT(TFALSE==IsCreated()); + + if (!TRenderInterface::Create(a_pKernel)) { + return TFALSE; + } + + TDPRINTF("Creating TRenderD3DInterface\n"); + m_pD3DInterface = Direct3DCreate8(D3D_SDK_VERSION); + if (!m_pD3DInterface) { + TDPRINTF("Failed to Create a Direct 3D8 Interface!\n"); + return TFALSE; + } + TDPRINTF("Successfully created a Direct 3D8 Interface.\n"); + + BuildAdapterDatabase(); + CreateAcceleratorTableA(); + + if (!GetMSWindow()->Create(this, GetClass().GetName())) { + return TFALSE; + } + LoadShaders(); + CreateSystemResources(); + + TWString(L"Created TRenderD3DInterface\n").Print(); + + return TTRUE; +} + +TBOOL TRenderD3DInterface::IsTextureFormatSupported(TTEXTURERESOURCEFORMAT a_eTextureFormat) +{ + switch (a_eTextureFormat) { + case R8G8B8A8: + return IsTextureFormatSupported(D3DFMT_A8R8G8B8); + case R8G8B8: + return IsTextureFormatSupported(D3DFMT_X8R8G8B8); + case R5G5B5A1: + return IsTextureFormatSupported(D3DFMT_A1R5G5B5); + case DDS: + return TTRUE; + default: + return TFALSE; + } +} + +TBOOL TRenderD3DInterface::IsTextureFormatSupported(D3DFORMAT a_eFormat) +{ + return SUCCEEDED( + GetD3DInterface()->CheckDeviceFormat( + GetCurrentDevice()->GetMode()->GetAdapter()->GetAdapterIndex(), + TD3DAdapter::Mode::Device::DEVICETYPES[GetCurrentDevice()->GetDeviceIndex()], + m_oPresentParams.BackBufferFormat, + 0, + D3DRTYPE_TEXTURE, + a_eFormat + ) + ); +} + +TBOOL TRenderD3DInterface::Supports32BitTextures() +{ + return IsTextureFormatSupported(R8G8B8A8) && IsTextureFormatSupported(R8G8B8); +} + +void TRenderD3DInterface::BuildAdapterDatabase() +{ + for (UINT i = 0; i < m_pD3DInterface->GetAdapterCount(); i++) { + auto pAdapter = new TD3DAdapter(); + pAdapter->SetAdapterIndex(i); + + D3DDISPLAYMODE displayMode; + auto pIdentifier = pAdapter->GetD3DIdentifier8(); + m_pD3DInterface->GetAdapterIdentifier(i, D3DENUM_NO_WHQL_LEVEL, pIdentifier); + m_pD3DInterface->GetAdapterDisplayMode(i, &displayMode); + + pAdapter->SetDriver(pIdentifier->Driver); + pAdapter->SetDescription(pIdentifier->Description); + pAdapter->SetDriverVersionLowPart(pIdentifier->DriverVersion.LowPart); + pAdapter->SetDriverVersionHighPart(pIdentifier->DriverVersion.HighPart); + pAdapter->SetDeviceId(pIdentifier->DeviceId); + pAdapter->SetVendorId(pIdentifier->VendorId); + pAdapter->SetSubSysId(pIdentifier->SubSysId); + pAdapter->SetRevision(pIdentifier->Revision); + pAdapter->SetDeviceIdentifier(pIdentifier->DeviceIdentifier); + + pAdapter->GetMode().SetD3DDisplayMode(displayMode); + pAdapter->EnumerateOutputs(this); + + GetAdapterList()->InsertTail(*pAdapter); + } +} + +void TRenderD3DInterface::CreateAcceleratorTableA() +{ + DestroyAcceleratorTable(); + ACCEL accel[2]; + // ESCAPE + accel[0].fVirt = FVIRTKEY; + accel[0].key = VK_ESCAPE; + accel[0].cmd = 0; + // ALT+ENTER + accel[1].fVirt = FALT; + accel[1].key = VK_RETURN; + accel[1].cmd = 1; + m_hAccel = ::CreateAcceleratorTableA(accel, 2); +} + +void TRenderD3DInterface::DestroyAcceleratorTable() +{ + if (m_hAccel) { + ::DestroyAcceleratorTable(m_hAccel); + m_hAccel = NULL; + } +} + +TBOOL TRenderD3DInterface::LoadShaders() +{ + return TBOOL(); +} diff --git a/Toshi/Source/TRenderD3D/TTextureFactoryD3D.cpp b/Toshi/Source/TRenderD3D/TTextureFactoryD3D.cpp index d0393ba..14e39a6 100644 --- a/Toshi/Source/TRenderD3D/TTextureFactoryD3D.cpp +++ b/Toshi/Source/TRenderD3D/TTextureFactoryD3D.cpp @@ -1,4 +1,6 @@ #include "TRenderD3D/TTextureFactoryD3D.h" +#include "TRender/TRenderInterface.h" +#include "TRenderD3D/TTextureResourceD3D.h" TOSHI_NAMESPACE_USING @@ -53,7 +55,7 @@ TTextureResource* TTextureFactoryHAL::CreateTextureFromMemory(TPVOID a_pData, TU return pTexture; } -TTextureResource* TTextureFactoryHAL::CreateEx(TPVOID a_pData, TUINT a_uiDataSize, TUINT a_uiWidth, TUINT a_uiHeight, TUINT a_uiMipLevels, TTEXTURERESOURCEFORMAT a_eFormat, BOOL a_bNoMipLevels) +TTextureResource* TTextureFactoryHAL::CreateEx(TPVOID a_pData, TUINT a_uiDataSize, TUINT a_uiWidth, TUINT a_uiHeight, TUINT a_uiMipLevels, TTEXTURERESOURCEFORMAT a_eFormat, TUINT a_bNoMipLevels) { static TUINT s_iNumMemTextures = 0; static char s_szName[32]; diff --git a/Toshi/Source/TRenderD3D/TTextureResourceD3D.cpp b/Toshi/Source/TRenderD3D/TTextureResourceD3D.cpp index 1156412..0842934 100644 --- a/Toshi/Source/TRenderD3D/TTextureResourceD3D.cpp +++ b/Toshi/Source/TRenderD3D/TTextureResourceD3D.cpp @@ -10,7 +10,7 @@ IMPLEMENT_DYNCREATE(TTextureResourceHAL, TTextureResource) TBOOL TTextureResourceHAL::Create(TPVOID a_pData, TUINT a_uiDataSize, TUINT a_eTextureFlags, TUINT a_uiWidth, TUINT a_uiHeight) { TDPRINTF("Deprecated! Please use: TTextureResourceHAL::CreateEx()\n"); - if (!TTextureResource::Create(a_pData, a_uiDataSize, a_uiWidth, 0, 0)) { + if (!TTextureResource::Create(a_pData, a_uiDataSize, a_eTextureFlags, 0, 0)) { return TFALSE; }