Initial CFont implementation, proper CTexture/CGraphicsPalette structures

This commit is contained in:
Phillip Stephens 2022-02-26 18:18:58 -08:00
parent 40a1f3c4a0
commit b02ec12049
Signed by: Antidote
GPG Key ID: F8BEE4C83DACA60D
14 changed files with 312 additions and 110 deletions

View File

@ -54,7 +54,7 @@ void CCubeMaterial::SetCurrent(const CModelFlags& flags, const CCubeSurface& sur
materialDataCur += 8;
for (u32 i = 0; i < texCount; ++i) {
u32 texIdx = SBig(*reinterpret_cast<const u32*>(materialDataCur));
sRenderingModel->GetTexture(texIdx)->Load(i, CTexture::EClampMode::One);
sRenderingModel->GetTexture(texIdx)->Load(i, CTexture::EClampMode::Repeat);
materialDataCur += 4;
}
}

View File

@ -232,8 +232,11 @@ void CCubeRenderer::PrimColor(float, float, float, float) {}
void CCubeRenderer::PrimColor(const zeus::CColor&) {}
void CCubeRenderer::EndPrimitive() {}
void CCubeRenderer::SetAmbientColor(const zeus::CColor& color) {}
void CCubeRenderer::DrawString(const char* string, int, int) {}
u32 CCubeRenderer::GetFPS() { return 0; }
void CCubeRenderer::DrawString(const char* string, int x, int y) {
x10_font.DrawString(string, x, y, zeus::skWhite);
}
u32 CCubeRenderer::GetFPS() { return CGraphics::GetFPS(); }
void CCubeRenderer::CacheReflection(IRenderer::TReflectionCallback cb, void* ctx, bool clearAfter) {}
void CCubeRenderer::DrawSpaceWarp(const zeus::CVector3f& pt, float strength) {}
void CCubeRenderer::DrawThermalModel(const CModel& model, const zeus::CColor& multCol, const zeus::CColor& addCol,

View File

@ -1,10 +1,11 @@
#pragma once
#include "Graphics/CCubeModel.hpp"
#include "Graphics/CPVSVisSet.hpp"
#include "Graphics/CTexture.hpp"
#include "IRenderer.hpp"
#include "CRandom16.hpp"
#include "Runtime/Graphics/CCubeModel.hpp"
#include "Runtime/Graphics/CPVSVisSet.hpp"
#include "Runtime/Graphics/CTexture.hpp"
#include "Runtime/Graphics/IRenderer.hpp"
#include "Runtime/CRandom16.hpp"
#include "Runtime/Graphics/CFont.hpp"
#include <list>
@ -51,7 +52,7 @@ class CCubeRenderer final : public IRenderer {
private:
IFactory& x8_factory;
IObjectStore& xc_store;
// CFont x10_font{1.f};
CFont x10_font{1.f};
// u32 x18_ = 0;
std::list<CAreaListItem> x1c_areaListItems;
// TODO x34...x40

View File

@ -0,0 +1,82 @@
#include "Runtime/Graphics/CFont.hpp"
#include "Runtime/Graphics/CGraphics.hpp"
namespace metaforce {
/* TODO: Custom I8 font */
std::array<u8, 65536> CFont::sSystemFont = {
/* Omitted due to copyright issues */};
u32 CFont::sNumInstances = 0;
std::unique_ptr<CTexture> CFont::mpTexture;
CFont::CFont(float scale) : x0_fontSize(16.f * scale), x4_scale(scale) {
if (sNumInstances == 0) {
mpTexture = std::make_unique<CTexture>(ETexelFormat::I8, 256, 256, 1);
u8* fontData = new u8[(mpTexture->GetBitsPerPixel() * mpTexture->GetWidth() * mpTexture->GetHeight()) / 8];
memcpy(fontData, sSystemFont.data(), sSystemFont.size());
// u8* textureData = mpTexture->GetBitMapData();
// LinearToTile8(textureData, fontData);
delete[] fontData;
// mpTexture->UnLock();
}
++sNumInstances;
}
void CFont::TileCopy8(u8* dest, const u8* src) {
for (u32 i = 0; i < 4; ++i) {
dest[0] = src[0];
dest[1] = src[1];
dest[2] = src[2];
dest[3] = src[3];
dest[4] = src[4];
dest[5] = src[5];
dest[6] = src[6];
dest[7] = src[7];
src += 256;
dest += 8;
}
}
void CFont::LinearToTile8(u8* dest, const u8* src) {
int iVar1 = 0;
int iVar2 = 0;
for (size_t y = 0; y < 256; y += 4) {
iVar2 = iVar1;
for (size_t x = 0; x < 256; x += 8) {
TileCopy8(dest, src + iVar2);
dest += 32;
iVar2 += 8;
}
iVar1 += 1024;
}
}
void CFont::DrawString(const char* str, int x, int y, const zeus::CColor& col) {
bool bVar2 = CGraphics::BeginRender2D(*mpTexture.get());
char chr = *str;
while (chr != 0) {
u32 cellSize = static_cast<u32>(16.f * x4_scale);
++str;
CGraphics::DoRender2D(*mpTexture, x, y, (chr & 0xf) * 16, 0xf0, 0x10, cellSize, cellSize, col);
chr = *str;
}
CGraphics::EndRender2D(bVar2);
}
u32 CFont::StringWidth(const char* str) const {
u32 width = 0;
char chr = *str;
while (chr != 0) {
++str;
width += static_cast<u32>(15.f * x4_scale);
chr = *str;
}
return width;
}
u32 CFont::CharsWidth(const char* str, u32 len) const { return len * (15.f * x4_scale); }
u32 CFont::CharWidth(const char chr) const { return 15.f * x4_scale; }
} // namespace metaforce

View File

@ -0,0 +1,28 @@
#pragma once
#include "Runtime/GCNTypes.hpp"
#include "Runtime/Graphics/CTexture.hpp"
#include <zeus/CColor.hpp>
#include <memory>
#include <array>
namespace metaforce {
class CFont {
static std::array<u8, 65536> sSystemFont;
static u32 sNumInstances;
static std::unique_ptr<CTexture> mpTexture;
float x0_fontSize;
float x4_scale;
void TileCopy8(u8* dest, const u8* src);
void LinearToTile8(u8* dest, const u8* src);
public:
explicit CFont(float scale);
void DrawString(const char* str, int x, int y, const zeus::CColor& color);
u32 StringWidth(const char* str) const;
u32 CharsWidth(const char* str, u32 len) const;
u32 CharWidth(const char chr) const;
};
}

View File

@ -3,6 +3,7 @@
#include "Runtime/CTimeProvider.hpp"
#include "Runtime/Graphics/CLight.hpp"
#include "Runtime/Graphics/CLineRenderer.hpp"
#include "Runtime/Graphics/CTexture.hpp"
#include "Runtime/Graphics/Shaders/CTextSupportShader.hpp"
#include "Runtime/GuiSys/CGuiSys.hpp"
@ -145,6 +146,12 @@ void CGraphics::EndScene() {
UpdateFPSCounter();
}
bool CGraphics::BeginRender2D(const CTexture& tex) { return false; }
void CGraphics::DoRender2D(const CTexture& tex, s32 x, s32 y, s32 w1, s32 w2, s32 w3, s32 w4, s32 w5,
const zeus::CColor& col) {}
void CGraphics::EndRender2D(bool v) {}
void CGraphics::SetAlphaCompare(ERglAlphaFunc comp0, u8 ref0, ERglAlphaOp op, ERglAlphaFunc comp1, u8 ref1) {}
void CGraphics::SetViewPointMatrix(const zeus::CTransform& xf) {

View File

@ -1,26 +1,28 @@
#pragma once
#include <array>
#include <vector>
#include <chrono>
#include <vector>
#include "optick.h"
#include "Runtime/RetroTypes.hpp"
#include "GX.hpp"
#include "Runtime/Graphics/GX.hpp"
#include "ConsoleVariables/CVar.hpp"
#include "Runtime/ConsoleVariables/CVar.hpp"
#include <zeus/CColor.hpp>
#include <zeus/CTransform.hpp>
#include <zeus/CVector2i.hpp>
#include <zeus/CVector2f.hpp>
#include <zeus/CVector2i.hpp>
#include <aurora/gfx.hpp>
using frame_clock = std::chrono::high_resolution_clock;
namespace metaforce {
class CTexture;
extern CVar* g_disableLighting;
class CLight;
class CTimeProvider;
@ -212,6 +214,10 @@ public:
static void SetCullMode(ERglCullMode);
static void BeginScene();
static void EndScene();
static bool BeginRender2D(const CTexture& tex);
static void DoRender2D(const CTexture& tex, s32 x, s32 y, s32 w1, s32 w2, s32 w3, s32 w4, s32 w5,
const zeus::CColor& col);
static void EndRender2D(bool v);
static void SetAlphaCompare(ERglAlphaFunc comp0, u8 ref0, ERglAlphaOp op, ERglAlphaFunc comp1, u8 ref1);
static void SetViewPointMatrix(const zeus::CTransform& xf);
static void SetViewMatrix();

View File

@ -0,0 +1,22 @@
#include "Runtime/Graphics/CGraphicsPalette.hpp"
#include "Runtime/Streams/CInputStream.hpp"
namespace metaforce {
u32 CGraphicsPalette::sCurrentFrameCount = 0;
CGraphicsPalette::CGraphicsPalette(EPaletteFormat fmt, int count)
: x0_fmt(fmt), x8_entryCount(count), xc_entries(new u8[count * 2]) {
//GXInitTlutObj(&x10_tlutObj, xc_entries.get(), x8_entryCount);
}
CGraphicsPalette::CGraphicsPalette(CInputStream& in) : x0_fmt(EPaletteFormat(in.ReadLong())) {
u16 w = in.ReadShort();
u16 h = in.ReadShort();
x8_entryCount = w * h;
xc_entries.reset(new u8[x8_entryCount * 2]);
in.Get(xc_entries.get(), x8_entryCount * 2);
//GXInitTlutObj(&x10_tlutObj, xc_entries.get(), x8_entryCount);
//DCFlushRange(xc_entries.get(), x8_entryCount * 2);
}
} // namespace metaforce

View File

@ -4,6 +4,7 @@
#include "Runtime/RetroTypes.hpp"
namespace metaforce {
class CInputStream;
enum class EPaletteFormat {
IA8 = 0x0,
@ -12,24 +13,19 @@ enum class EPaletteFormat {
};
class CGraphicsPalette {
static u32 sCurrentFrameCount;
friend class CTextRenderBuffer;
EPaletteFormat x0_fmt;
u32 x4_;
int x8_entryCount;
std::unique_ptr<u16[]> xc_entries;
/* x10_ GXTlutObj here */
bool x1c_ = false;
u32 x4_frameLoaded{};
u32 x8_entryCount;
std::unique_ptr<u8[]> xc_entries;
/* GXTlutObj x10_; */
bool x1c_locked = false;
public:
explicit CGraphicsPalette(EPaletteFormat fmt, int count)
: x0_fmt(fmt), x8_entryCount(count), xc_entries(new u16[count]) {}
explicit CGraphicsPalette(CInputStream& in) : x0_fmt(EPaletteFormat(in.ReadLong())) {
u16 w = in.ReadShort();
u16 h = in.ReadShort();
x8_entryCount = w * h;
explicit CGraphicsPalette(EPaletteFormat fmt, int count);
/* GX Tlut init here */
}
explicit CGraphicsPalette(CInputStream& in);
};
} // namespace metaforce

View File

@ -15,13 +15,14 @@ set(GRAPHICS_SOURCES
CSkinnedModel.hpp CSkinnedModel.cpp
CVertexMorphEffect.hpp CVertexMorphEffect.cpp
CMoviePlayer.hpp CMoviePlayer.cpp
CGraphicsPalette.hpp
CGraphicsPalette.hpp CGraphicsPalette.cpp
CPVSVisSet.hpp CPVSVisSet.cpp
CPVSVisOctree.hpp CPVSVisOctree.cpp
CPVSAreaSet.hpp CPVSAreaSet.cpp
CGraphics.hpp CGraphics.cpp
CSimpleShadow.hpp CSimpleShadow.cpp
CRainSplashGenerator.hpp CRainSplashGenerator.cpp
CFont.hpp CFont.cpp
Shaders/CLineRendererShaders.hpp Shaders/CLineRendererShaders.cpp
Shaders/CTexturedQuadFilter.hpp Shaders/CTexturedQuadFilter.cpp
Shaders/CColoredQuadFilter.hpp Shaders/CColoredQuadFilter.cpp

View File

@ -5,16 +5,33 @@
#include "Runtime/CFactoryMgr.hpp"
#include "Runtime/GCNTypes.hpp"
#include "Runtime/Graphics/CGraphics.hpp"
#include "Runtime/IObj.hpp"
#include "Runtime/Streams/IOStreams.hpp"
#include "Runtime/Graphics/CGraphics.hpp"
#include "Runtime/Graphics/CGraphicsPalette.hpp"
namespace metaforce {
class CVParamTransfer;
class CTextureInfo;
class CTexture {
class CDumpedBitmapDataReloader {
int x0_;
u32 x4_;
int x8_;
u32 xc_;
bool x10_;
int x14_;
void* x18_;
};
public:
enum class EClampMode {
Clamp,
Repeat,
Mirror,
};
enum class EFontType {
None = -1,
OneLayer = 0, /* Fill bit0 */
@ -29,8 +46,16 @@ private:
ETexelFormat x0_fmt;
u16 x4_w;
u16 x6_h;
u32 x8_mips;
// boo::ObjToken<boo::ITexture> m_booTex;
u8 x8_mips;
u8 x9_bitsPerPixel;
u32 xc_memoryAllocated;
std::unique_ptr<CGraphicsPalette> x10_graphicsPalette;
std::unique_ptr<CDumpedBitmapDataReloader> x14_bitmapReloader;
u32 x18_gxFormat;
u32 x1c_gxCIFormat;
/* GXTexObj x20_texObj */
EClampMode x40_clampMode;
aurora::gfx::TextureHandle m_tex;
aurora::gfx::TextureHandle m_paletteTex;
std::unique_ptr<u8[]> m_otex;
@ -56,10 +81,11 @@ private:
void BuildDXT1(const void* data, size_t length, aurora::zstring_view label);
void BuildDXT3(const void* data, size_t length, aurora::zstring_view label);
void InitBitmapBuffers(ETexelFormat fmt, s16 width, s16 height, s32 mips);
public:
CTexture(ETexelFormat, s16, s16, s32);
CTexture(std::unique_ptr<u8[]>&& in, u32 length, bool otex, const CTextureInfo* inf, CAssetId id);
enum class EClampMode { None, One };
ETexelFormat GetTexelFormat() const { return x0_fmt; }
ETexelFormat GetMemoryCardTexelFormat() const {
return x0_fmt == ETexelFormat::C8PC ? ETexelFormat::C8 : ETexelFormat::RGB5A3;
@ -67,6 +93,7 @@ public:
u16 GetWidth() const { return x4_w; }
u16 GetHeight() const { return x6_h; }
u32 GetNumMips() const { return x8_mips; }
u8 GetBitsPerPixel() const { return x9_bitsPerPixel; }
void Load(int slot, EClampMode clamp) const;
const aurora::gfx::TextureHandle& GetTexture() const { return m_tex; }
// const boo::ObjToken<boo::ITexture>& GetBooTexture() const { return m_booTex; }
@ -75,6 +102,8 @@ public:
const aurora::gfx::TextureHandle& GetFontTexture(EFontType tp);
const CTextureInfo* GetTextureInfo() const { return m_textureInfo; }
static u32 TexelFormatBitsPerPixel(ETexelFormat fmt);
};
CFactoryFnReturn FTextureFactory(const metaforce::SObjectTag& tag, std::unique_ptr<u8[]>&& in, u32 len,

View File

@ -707,12 +707,36 @@ static std::string_view TextureFormatString(ETexelFormat format) {
}
}
CTexture::CTexture(ETexelFormat fmt, s16 w, s16 h, s32 mips) : x0_fmt(fmt), x4_w(w), x6_h(h), x8_mips(mips) {
/*
x64_ = sMangleMipmaps;
u32 CTexture::TexelFormatBitsPerPixel(ETexelFormat fmt) {
switch(fmt) {
case ETexelFormat::I4:
case ETexelFormat::C4:
case ETexelFormat::CMPR:
return 4;
case ETexelFormat::I8:
case ETexelFormat::IA4:
case ETexelFormat::C8:
return 8;
case ETexelFormat::IA8:
case ETexelFormat::C14X2:
case ETexelFormat::RGB565:
case ETexelFormat::RGB5A3:
return 16;
case ETexelFormat::RGBA8:
return 32;
default:
return 0;
}
}
CTexture::CTexture(ETexelFormat fmt, s16 w, s16 h, s32 mips)
: x0_fmt(fmt), x4_w(w), x6_h(h), x8_mips(mips), x9_bitsPerPixel(TexelFormatBitsPerPixel(fmt)) {
#if 0
x64_ = sCurrentFrameCount;
InitBitmapBuffers(fmt, w, h, mips);
InitTextureObjs();
*/
#endif
}
CTexture::CTexture(std::unique_ptr<u8[]>&& in, u32 length, bool otex, const CTextureInfo* inf, CAssetId id)
@ -723,6 +747,7 @@ CTexture::CTexture(std::unique_ptr<u8[]>&& in, u32 length, bool otex, const CTex
x4_w = r.ReadShort();
x6_h = r.ReadShort();
x8_mips = r.ReadLong();
x9_bitsPerPixel = TexelFormatBitsPerPixel(x0_fmt);
auto label = fmt::format(FMT_STRING("TXTR {:08X} ({})"), id.Value(), TextureFormatString(x0_fmt));
switch (x0_fmt) {
@ -826,7 +851,8 @@ std::unique_ptr<u8[]> CTexture::BuildMemoryCardTex(u32& sizeOut, ETexelFormat& f
const RGBA8* source = sourceMip + (x6_h - (baseY + y) - 1) * w + baseX;
for (int x = 0; x < 4; ++x) {
if (source[x].a == 0xff) {
*texel++ = CBasics::SwapBytes(u16((source[x].r >> 3 << 10) | (source[x].g >> 3 << 5) | (source[x].b >> 3)));
*texel++ =
CBasics::SwapBytes(u16((source[x].r >> 3 << 10) | (source[x].g >> 3 << 5) | (source[x].b >> 3)));
} else {
*texel++ = CBasics::SwapBytes(u16((source[x].r >> 4 << 8) | (source[x].g >> 4 << 4) | (source[x].b >> 4) |
(source[x].a >> 5 << 12)));

View File

@ -918,7 +918,7 @@ void CElementGen::RenderModels(const CActorLights* actorLights) {
CParticle& target = x30_particles[0];
int partFrame = x74_curFrame - target.x28_startFrame;
cachedTex = texr->GetValueTexture(partFrame).GetObj();
cachedTex->Load(0, CTexture::EClampMode::One);
cachedTex->Load(0, CTexture::EClampMode::Repeat);
/* Shade as TEXC * RASC and TEXA * RASA */
if (moveRedToAlphaBuffer) {
/* Color = Prev.rgb * Prev.a */
@ -1043,7 +1043,7 @@ void CElementGen::RenderModels(const CActorLights* actorLights) {
if (!texConst) {
CTexture* tex = texr->GetValueTexture(x74_curFrame - particle.x28_startFrame).GetObj();
if (tex != cachedTex) {
tex->Load(0, CTexture::EClampMode::One);
tex->Load(0, CTexture::EClampMode::Repeat);
cachedTex = tex;
}
}
@ -1157,7 +1157,7 @@ void CElementGen::RenderLines() {
CParticle& target = x30_particles[0];
int partFrame = x74_curFrame - target.x28_startFrame;
cachedTex = texr->GetValueTexture(partFrame).GetObj();
cachedTex->Load(0, CTexture::EClampMode::One);
cachedTex->Load(0, CTexture::EClampMode::Repeat);
/* Set TEXC * RASC */
@ -1187,7 +1187,7 @@ void CElementGen::RenderLines() {
if (!constTexr) {
CTexture* tex = texr->GetValueTexture(partFrame).GetObj();
if (tex != cachedTex) {
tex->Load(0, CTexture::EClampMode::One);
tex->Load(0, CTexture::EClampMode::Repeat);
cachedTex = tex;
}
}
@ -1264,7 +1264,7 @@ void CElementGen::RenderParticles() {
CParticle& target = x30_particles[0];
int partFrame = x74_curFrame - target.x28_startFrame;
cachedTex = texr->GetValueTexture(partFrame).GetObj();
cachedTex->Load(0, CTexture::EClampMode::One);
cachedTex->Load(0, CTexture::EClampMode::Repeat);
if (x338_moduColor != zeus::skBlack) {
/* Add RASC * PREVC pass for MODU color loaded into channel mat-color */
@ -1678,7 +1678,7 @@ void CElementGen::RenderParticlesIndirectTexture() {
CParticle& firstParticle = x30_particles[0];
int partFrame = x74_curFrame - firstParticle.x28_startFrame;
CTexture* cachedTex = texr->GetValueTexture(partFrame).GetObj();
cachedTex->Load(0, CTexture::EClampMode::One);
cachedTex->Load(0, CTexture::EClampMode::Repeat);
SUVElementSet uvs = {0.f, 0.f, 1.f, 1.f};
bool constTexr = texr->HasConstantTexture();
@ -1687,7 +1687,7 @@ void CElementGen::RenderParticlesIndirectTexture() {
CUVElement* tind = desc->x58_x44_TIND.get();
CTexture* cachedIndTex = tind->GetValueTexture(partFrame).GetObj();
cachedIndTex->Load(2, CTexture::EClampMode::One);
cachedIndTex->Load(2, CTexture::EClampMode::Repeat);
SUVElementSet uvsInd = {0.f, 0.f, 1.f, 1.f};
bool constIndTexr = tind->HasConstantTexture();
@ -1734,7 +1734,7 @@ void CElementGen::RenderParticlesIndirectTexture() {
if (!constTexr) {
CTexture* tex = texr->GetValueTexture(thisPartFrame).GetObj();
if (tex != cachedTex) {
tex->Load(0, CTexture::EClampMode::One);
tex->Load(0, CTexture::EClampMode::Repeat);
cachedTex = tex;
}
}
@ -1742,7 +1742,7 @@ void CElementGen::RenderParticlesIndirectTexture() {
if (!constIndTexr) {
CTexture* tex = tind->GetValueTexture(thisPartFrame).GetObj();
if (tex != cachedIndTex) {
tex->Load(2, CTexture::EClampMode::One);
tex->Load(2, CTexture::EClampMode::Repeat);
cachedIndTex = tex;
}
}

View File

@ -48,8 +48,9 @@ u32 CPFAreaOctree::GetChildIndex(const zeus::CVector3f& point) const {
}
rstl::prereserved_vector<CPFRegion*>* CPFAreaOctree::GetRegionList(const zeus::CVector3f& point) {
if (x0_isLeaf)
if (x0_isLeaf != 0u) {
return &x48_regions;
}
return x28_children[GetChildIndex(point)]->GetRegionList(point);
}