diff --git a/src/gx/CGxDevice.cpp b/src/gx/CGxDevice.cpp index e924220..96fa81b 100644 --- a/src/gx/CGxDevice.cpp +++ b/src/gx/CGxDevice.cpp @@ -35,6 +35,24 @@ uint32_t CGxDevice::s_alphaRef[] = { C3Vector CGxDevice::s_pointScaleIdentity = { 1.0f, 0.0f, 0.0f }; +uint32_t CGxDevice::s_primVtxAdjust[] = { + 0, // GxPrim_Points + 0, // GxPrim_Lines + 1, // GxPrim_LineStrip + 0, // GxPrim_Triangles + 2, // GxPrim_TriangleStrip + 2, // GxPrim_TriangleFan +}; + +uint32_t CGxDevice::s_primVtxDiv[] = { + 1, // GxPrim_Points + 2, // GxPrim_Lines + 1, // GxPrim_LineStrip + 3, // GxPrim_Triangles + 1, // GxPrim_TriangleStrip + 1, // GxPrim_TriangleFan +}; + ShaderConstants CGxDevice::s_shadowConstants[2]; uint32_t CGxDevice::s_streamPoolSize[] = { @@ -109,6 +127,15 @@ CGxDevice* CGxDevice::NewOpenGl() { return nullptr; } +uint32_t CGxDevice::PrimCalcCount(EGxPrim primType, uint32_t count) { + auto div = CGxDevice::s_primVtxDiv[primType]; + if (div != 1) { + count /= div; + } + + return count - CGxDevice::s_primVtxAdjust[primType]; +} + CGxDevice::CGxDevice() { // TODO // - implement rest of constructor diff --git a/src/gx/CGxDevice.hpp b/src/gx/CGxDevice.hpp index 06df246..539bcab 100644 --- a/src/gx/CGxDevice.hpp +++ b/src/gx/CGxDevice.hpp @@ -40,6 +40,8 @@ class CGxDevice { // Static variables static uint32_t s_alphaRef[]; static C3Vector s_pointScaleIdentity; + static uint32_t s_primVtxAdjust[]; + static uint32_t s_primVtxDiv[]; static ShaderConstants s_shadowConstants[2]; static uint32_t s_streamPoolSize[]; static uint32_t s_texFormatBitDepth[]; @@ -56,6 +58,7 @@ class CGxDevice { static CGxDevice* NewGLL(); #endif static CGxDevice* NewOpenGl(); + static uint32_t PrimCalcCount(EGxPrim primType, uint32_t count); // Member variables TSGrowableArray m_pushedStates; @@ -69,6 +72,7 @@ class CGxDevice { int32_t m_shaderProfiles[GxShTargets_Last] = { 6, 0, 0, 0, 12, 0 }; // TODO placeholder TSHashTable m_shaderList[GxShTargets_Last]; int32_t m_context = 0; + int32_t intF5C = 0; int32_t intF64 = 0; CBoundingBox m_viewport; C44Matrix m_projection; diff --git a/src/gx/d3d/CGxDeviceD3d.cpp b/src/gx/d3d/CGxDeviceD3d.cpp index 88cd932..c8ab03c 100644 --- a/src/gx/d3d/CGxDeviceD3d.cpp +++ b/src/gx/d3d/CGxDeviceD3d.cpp @@ -1,4 +1,5 @@ #include "gx/d3d/CGxDeviceD3d.hpp" +#include "gx/CGxBatch.hpp" #include "gx/texture/CGxTex.hpp" #include @@ -55,6 +56,15 @@ EGxTexFormat CGxDeviceD3d::s_GxTexFmtToUse[] = { GxTex_D24X8, }; +D3DPRIMITIVETYPE CGxDeviceD3d::s_primitiveConversion[] = { + D3DPT_POINTLIST, // GxPrim_Points + D3DPT_LINELIST, // GxPrim_Lines + D3DPT_LINESTRIP, // GxPrim_LineStrip + D3DPT_TRIANGLELIST, // GxPrim_Triangles + D3DPT_TRIANGLESTRIP, // GxPrim_TriangleStrip + D3DPT_TRIANGLEFAN, // GxPrim_TriangleFan +}; + EGxTexFormat CGxDeviceD3d::s_tolerableTexFmtMapping[] = { GxTex_Unknown, // GxTex_Unknown GxTex_Argb4444, // GxTex_Abgr8888 @@ -347,6 +357,36 @@ void CGxDeviceD3d::DeviceWM(EGxWM wm, uintptr_t param1, uintptr_t param2) { // TODO } +void CGxDeviceD3d::Draw(CGxBatch* batch, int32_t count) { + if (!this->m_context || this->intF5C) { + return; + } + + this->IStateSync(); + + int32_t baseIndex = 0; + if (!this->m_caps.int10) { + baseIndex = this->m_primVertexFormatBuf[0]->m_index / this->m_primVertexFormatBuf[0]->m_itemSize; + } + + if (count) { + this->m_d3dDevice->DrawIndexedPrimitive( + CGxDeviceD3d::s_primitiveConversion[batch->m_primType], + baseIndex, + batch->m_minIndex, + batch->m_maxIndex - batch->m_minIndex + 1, + batch->m_start + (this->m_primIndexBuf->m_index / 2), + CGxDevice::PrimCalcCount(batch->m_primType, batch->m_count) + ); + } else { + this->m_d3dDevice->DrawPrimitive( + CGxDeviceD3d::s_primitiveConversion[batch->m_primType], + baseIndex, + CGxDevice::PrimCalcCount(batch->m_primType, batch->m_count) + ); + } +} + void CGxDeviceD3d::DsSet(EDeviceState state, uint32_t val) { // TODO } @@ -883,6 +923,10 @@ void CGxDeviceD3d::IShaderCreateVertex(CGxShader* shader) { } } +void CGxDeviceD3d::IStateSync() { + // TODO +} + void CGxDeviceD3d::ITexCreate(CGxTex* texId) { uint32_t width, height, startLevel, endLevel; this->ITexWHDStartEnd(texId, width, height, startLevel, endLevel); diff --git a/src/gx/d3d/CGxDeviceD3d.hpp b/src/gx/d3d/CGxDeviceD3d.hpp index d26fd21..828f0ff 100644 --- a/src/gx/d3d/CGxDeviceD3d.hpp +++ b/src/gx/d3d/CGxDeviceD3d.hpp @@ -200,6 +200,7 @@ class CGxDeviceD3d : public CGxDevice { static D3DFORMAT s_GxFormatToD3dFormat[]; static D3DFORMAT s_GxTexFmtToD3dFmt[]; static EGxTexFormat s_GxTexFmtToUse[]; + static D3DPRIMITIVETYPE s_primitiveConversion[]; static EGxTexFormat s_tolerableTexFmtMapping[]; static D3DTEXTUREADDRESS s_wrapModes[]; @@ -229,6 +230,7 @@ class CGxDeviceD3d : public CGxDevice { virtual void DeviceWM(EGxWM wm, uintptr_t param1, uintptr_t param2); virtual void CapsWindowSize(CRect& dst); virtual void CapsWindowSizeInScreenCoords(CRect& dst); + virtual void Draw(CGxBatch* batch, int32_t count); virtual void PoolSizeSet(CGxPool* pool, uint32_t size); virtual char* BufLock(CGxBuf* buf); virtual int32_t BufUnlock(CGxBuf* buf, uint32_t size); @@ -254,6 +256,7 @@ class CGxDeviceD3d : public CGxDevice { void ISetTexture(uint32_t tmu, CGxTex* texId); void IShaderCreatePixel(CGxShader* shader); void IShaderCreateVertex(CGxShader* shader); + void IStateSync(); void ITexCreate(CGxTex* texId); void ITexUpload(CGxTex* texId); };