chore: initial commit

This commit is contained in:
fallenoak 2023-01-02 13:17:18 -06:00
commit 70b00c5c38
No known key found for this signature in database
GPG key ID: 7628F8E61AEA070D
965 changed files with 264882 additions and 0 deletions

View file

@ -0,0 +1,289 @@
#include "gx/font/CGxStringBatch.hpp"
#include "gx/font/CGxFont.hpp"
#include "gx/Buffer.hpp"
#include "gx/CGxBatch.hpp"
#include "gx/Device.hpp"
#include "gx/Draw.hpp"
#include "gx/Font.hpp"
#include "gx/Gx.hpp"
#include "gx/RenderState.hpp"
#include "gx/Shader.hpp"
#include "gx/Texture.hpp"
#include "gx/Transform.hpp"
#include <cmath>
#include <storm/Error.hpp>
bool BATCHEDRENDERFONTDESC::s_billboarded;
CGxBuf* BATCHEDRENDERFONTDESC::s_indexBuf;
CGxPool* BATCHEDRENDERFONTDESC::s_indexPool;
int32_t SetProjection() {
float minX, maxX, minY, maxY, minZ, maxZ;
GxXformViewport(minX, maxX, minY, maxY, minZ, maxZ);
float v14 = 0.0f;
float v15 = 0.0f;
if (!GxCaps()->m_pixelCenterOnEdge) {
v14 = -0.5f;
v15 = 0.5f;
}
C44Matrix proj;
uint32_t pixelWidth = GetScreenPixelWidth();
float pixelMinX = floor(minX * pixelWidth);
float pixelMaxX = floor(maxX * pixelWidth);
if (pixelMinX >= pixelMaxX) {
return 0;
}
uint32_t pixelHeight = GetScreenPixelHeight();
float pixelMinY = floor(minY * pixelHeight);
float pixelMaxY = floor(maxY * pixelHeight);
if (pixelMinY >= pixelMaxY) {
return 0;
}
if (pixelHeight > pixelMaxY) {
// TODO
}
pixelMinX += v14;
pixelMaxX += v14;
pixelMinY += v15;
pixelMaxY += v15;
GxuXformCreateOrthoDepth(pixelMinX, pixelMaxX, pixelMinY, pixelMaxY, -5000.0f, 5000.0f, proj);
GxXformSetProjection(proj);
return 1;
}
void BATCHEDRENDERFONTDESC::Initialize() {
CGxPool* indexPool = GxPoolCreate(
GxPoolTarget_Index,
GxPoolUsage_Static,
6144,
GxPoolHintBit_Unk0,
"BATCHEDRENDERFONTDESC_idx"
);
CGxBuf* indexBuf = GxBufCreate(
indexPool,
2,
3072,
0
);
BATCHEDRENDERFONTDESC::s_indexPool = indexPool;
BATCHEDRENDERFONTDESC::s_indexBuf = indexBuf;
}
void BATCHEDRENDERFONTDESC::InitializeIndexBuff() {
char* indexData = g_theGxDevicePtr->BufLock(BATCHEDRENDERFONTDESC::s_indexBuf);
uint16_t* indexBuf = reinterpret_cast<uint16_t*>(indexData);
uint16_t index = 0;
for (int32_t i = 0; i < 512; i++) {
indexBuf[i * 6 + 0] = index + 0;
indexBuf[i * 6 + 1] = index + 2;
indexBuf[i * 6 + 2] = index + 1;
indexBuf[i * 6 + 3] = index + 2;
indexBuf[i * 6 + 4] = index + 3;
indexBuf[i * 6 + 5] = index + 1;
index += 4;
}
GxBufUnlock(BATCHEDRENDERFONTDESC::s_indexBuf, 0);
};
CGxVertexPCT* BATCHEDRENDERFONTDESC::UnlockVertexPtrAndRender(CGxBuf*& buf, int32_t count) {
GxBufUnlock(buf, sizeof(CGxVertexPCT) * count);
if (!BATCHEDRENDERFONTDESC::s_indexBuf->unk1C || !BATCHEDRENDERFONTDESC::s_indexBuf->unk1D) {
BATCHEDRENDERFONTDESC::InitializeIndexBuff();
}
if (BATCHEDRENDERFONTDESC::s_indexBuf->unk1C && BATCHEDRENDERFONTDESC::s_indexBuf->unk1D) {
GxPrimVertexPtr(buf, GxVBF_PCT);
GxPrimIndexPtr(BATCHEDRENDERFONTDESC::s_indexBuf);
CGxBatch batch;
batch.m_primType = GxPrim_Triangles;
batch.m_start = 0;
batch.m_count = 6 * (count / 4);
batch.m_minIndex = 0;
batch.m_maxIndex = count - 1;
GxDraw(&batch, 1);
}
return reinterpret_cast<CGxVertexPCT*>(g_theGxDevicePtr->BufLock(buf));
}
void BATCHEDRENDERFONTDESC::RenderBatch() {
if (!BATCHEDRENDERFONTDESC::s_indexPool) {
return;
}
for (auto string = this->m_strings.Head(); string; string = this->m_strings.Next(string)) {
string->CheckGeometry();
}
for (int32_t i = 0; i < 8; i++) {
this->m_face->m_textureCache[i].UpdateDirty();
}
int32_t maxBatchCapacity = 2048;
CGxBuf* vertexStream = g_theGxDevicePtr->BufStream(GxPoolTarget_Vertex, 0x18, maxBatchCapacity);
char* vertexData = g_theGxDevicePtr->BufLock(vertexStream);
CGxVertexPCT* vertexBuf = reinterpret_cast<CGxVertexPCT*>(vertexData);
for (int32_t i = 0; i < 8; i++) {
auto& textureCache = this->m_face->m_textureCache[i];
auto texture = textureCache.m_texture;
if (texture) {
auto gxTex = TextureGetGxTex(reinterpret_cast<CTexture*>(texture), 1, nullptr);
if (gxTex) {
GxRsSet(GxRs_Texture0, gxTex);
for (auto string = this->m_strings.Head(); string; string = this->m_strings.Next(string)) {
auto line = string->m_textLines[i];
if (line) {
int32_t vertsNeeded = string->CalculateVertsNeeded(i);
int32_t batchOffset = 0;
int32_t batchCapacity = maxBatchCapacity;
while (vertsNeeded) {
int32_t batchCount = std::min(vertsNeeded, batchCapacity);
string->WriteGeometry(vertexBuf, i, batchOffset, batchCount);
vertsNeeded -= batchCount;
batchOffset += batchCount;
batchCapacity -= batchCount;
vertexBuf += batchCount;
if (!batchCapacity) {
vertexBuf = this->UnlockVertexPtrAndRender(vertexStream, maxBatchCapacity);
batchCapacity = maxBatchCapacity;
}
}
if (batchCapacity != maxBatchCapacity) {
vertexBuf = this->UnlockVertexPtrAndRender(vertexStream, maxBatchCapacity - batchCapacity);
batchCapacity = maxBatchCapacity;
}
}
}
}
}
}
g_theGxDevicePtr->BufUnlock(vertexStream, 0);
}
CGxStringBatch::~CGxStringBatch() {
this->m_fontBatch.Clear();
}
void CGxStringBatch::AddString(CGxString* string) {
STORM_ASSERT(string);
STORM_ASSERT(string->m_currentFace);
auto face = string->m_currentFace;
uint32_t hashval = reinterpret_cast<uintptr_t>(face);
HASHKEY_PTR key = { face };
auto batch = this->m_fontBatch.Ptr(hashval, key);
if (!batch) {
batch = this->m_fontBatch.New(hashval, key, 0, 0);
batch->m_face = face;
}
batch->m_strings.LinkToTail(string);
}
void CGxStringBatch::RenderBatch() {
// TODO
// if (!g_perf) {
// return;
// }
C44Matrix oldProjection;
C44Matrix oldView;
GxXformProjection(oldProjection);
GxXformView(oldView);
GxRsPush();
GxRsSet(GxRs_Fog, 0);
GxRsSet(GxRs_Culling, 0);
GxRsSet(GxRs_BlendingMode, GxBlend_Alpha);
GxRsSetAlphaRef();
int32_t setProjection;
int32_t stereoEnabled;
if (this->m_flags & 0x1) {
BATCHEDRENDERFONTDESC::s_billboarded = true;
GxRsSet(GxRs_DepthTest, 1);
GxRsSet(GxRs_DepthWrite, 1);
GxRsSet(GxRs_AlphaRef, 1);
setProjection = 1;
stereoEnabled = 0;
} else {
C44Matrix view;
GxXformSetView(view);
GxRsSet(GxRs_DepthTest, 0);
GxRsSet(GxRs_DepthWrite, 0);
setProjection = SetProjection();
stereoEnabled = g_theGxDevicePtr->StereoEnabled();
}
CGxShader* vs = g_fontVertexShader[stereoEnabled ? 1 : 0];
CGxShader* ps = g_fontPixelShader[0];
if (setProjection && vs->Valid() && ps->Valid()) {
GxRsSet(GxRs_VertexShader, vs);
GxRsSet(GxRs_PixelShader, ps);
C44Matrix viewProjMat;
GxXformViewProjNativeTranspose(viewProjMat);
GxShaderConstantsSet(GxSh_Vertex, 0, reinterpret_cast<float*>(&viewProjMat), 4);
for (auto fontBatch = this->m_fontBatch.Head(); fontBatch; fontBatch = this->m_fontBatch.Next(fontBatch)) {
if (fontBatch->m_strings.Head()) {
fontBatch->RenderBatch();
if (this->m_flags & 0x2) {
// TODO
}
} else {
this->m_fontBatch.Unlink(fontBatch);
}
}
}
BATCHEDRENDERFONTDESC::s_billboarded = false;
GxRsPop();
GxXformSetView(oldView);
GxXformSetProjection(oldProjection);
}