Nearly match DolphinCTexture and various cleanups

Former-commit-id: 76f3ff2603441ac6aa39fa009e7f466e84c8bc56
This commit is contained in:
Phillip Stephens 2023-10-17 11:26:21 -07:00
parent 130c641550
commit 602ed2b570
20 changed files with 603 additions and 79 deletions

View File

@ -12,7 +12,8 @@
},
"clangd.fallbackFlags": [
"-I${workspaceFolder}/include",
"-I${workspaceFolder}/libc"
"-I${workspaceFolder}/libc",
"-D__MWERKS__",
],
"editor.tabSize": 2,
"files.associations": {

View File

@ -13550,7 +13550,7 @@ Load__16CGraphicsPaletteCFv = .text:0x8030DEC4; // type:function size:0x3C scope
__dt__16CGraphicsPaletteFv = .text:0x8030DF00; // type:function size:0x88 scope:global
__ct__16CGraphicsPaletteFR12CInputStream = .text:0x8030DF88; // type:function size:0xEC scope:global
__ct__16CGraphicsPaletteF14EPaletteFormati = .text:0x8030E074; // type:function size:0x98 scope:global
fn_8030E10C = .text:0x8030E10C; // type:function size:0x3C
fn_8030E10C__8CTextureFv = .text:0x8030E10C; // type:function size:0x3C
InvalidateTexmap__8CTextureF11_GXTexMapID = .text:0x8030E148; // type:function size:0x18 scope:global
UncountMemory__8CTextureCFv = .text:0x8030E160; // type:function size:0x2C scope:global
CountMemory__8CTextureCFv = .text:0x8030E18C; // type:function size:0x2C scope:global
@ -13570,7 +13570,7 @@ LoadToMRAM__8CTextureCFv = .text:0x8030EC28; // type:function size:0x50 scope:gl
TryBuildReloadedBitmapData__Q28CTexture25CDumpedBitmapDataReloaderFR11CResFactory = .text:0x8030EC78; // type:function size:0x2F8 scope:global
BeginReloadBitmapData__Q28CTexture25CDumpedBitmapDataReloaderFR11CResFactory = .text:0x8030EF70; // type:function size:0xF4 scope:global
__ct__Q28CTexture25CDumpedBitmapDataReloaderFUiUib = .text:0x8030F064; // type:function size:0x24 scope:global
fn_8030F088 = .text:0x8030F088; // type:function size:0x7C
fn_8030F088__8CTextureCFv = .text:0x8030F088; // type:function size:0x7C
TryReloadBitmapData__8CTextureCFR11CResFactory = .text:0x8030F104; // type:function size:0x100 scope:global
UnloadBitmapData__8CTextureCFUi = .text:0x8030F204; // type:function size:0x194 scope:global
LoadMipLevel__8CTextureCFi11_GXTexMapIDQ28CTexture10EClampMode = .text:0x8030F398; // type:function size:0x3A4 scope:global
@ -15804,7 +15804,7 @@ Run = .text:0x80382E28; // type:function size:0x10 scope:local
Callback = .text:0x80382E38; // type:function size:0xC scope:local
__OSReboot = .text:0x80382E44; // type:function size:0x1C8 scope:global
OSSetSaveRegion = .text:0x8038300C; // type:function size:0xC scope:global
OSGetSaveRegion = .text:0x80383018; // type:function size:0x14 scope:global
OSGetSavedRegion = .text:0x80383018; // type:function size:0x14 scope:global
OSRegisterResetFunction = .text:0x8038302C; // type:function size:0x84 scope:global
__OSCallResetFunctions = .text:0x803830B0; // type:function size:0x8C scope:global
Reset = .text:0x8038313C; // type:function size:0x70 scope:global
@ -17813,7 +17813,7 @@ vtxDescList$288 = .rodata:0x803D73B8; // type:object size:0x10 scope:local
lbl_803D73C8 = .rodata:0x803D73C8; // type:object size:0x20
lbl_803D73E8 = .rodata:0x803D73E8; // type:object size:0x8
lbl_803D73F0 = .rodata:0x803D73F0; // type:object size:0x10 data:4byte
lbl_803D7400 = .rodata:0x803D7400; // type:object size:0x8
@stringBase0 = .rodata:0x803D7400; // type:object size:0x8 scope:local data:string_table
gkCRC32Table = .rodata:0x803D7408; // type:object size:0x400 scope:local
@stringBase0 = .rodata:0x803D7808; // type:object size:0x18 scope:local data:string_table
lbl_803D7820 = .rodata:0x803D7820; // type:object size:0x20
@ -17928,7 +17928,7 @@ __THPAANScaleFactor = .rodata:0x803D8D20; // type:object size:0x40 scope:local
lbl_803D8D60 = .data:0x803D8D60; // type:object size:0xC
__vt__4IObj = .data:0x803D8D6C; // type:object size:0xC scope:global
__vt__31CObjOwnerDerivedFromIObjUntyped = .data:0x803D8D78; // type:object size:0xC scope:global
lbl_803D8D84 = .data:0x803D8D84; // type:object size:0xC
__vt__35TObjOwnerDerivedFromIObj<8CTexture> = .data:0x803D8D84; // type:object size:0xC
lbl_803D8D90 = .data:0x803D8D90; // type:object size:0x10C
__vt__24IArchitectureMessageParm = .data:0x803D8E9C; // type:object size:0xC scope:global
__vt__22CCameraShakerComponent = .data:0x803D8EA8; // type:object size:0x10 scope:global
@ -18718,7 +18718,7 @@ mViewport__9CGraphics = .data:0x803ED910; // type:object size:0x18 scope:global
mLightTypes__9CGraphics = .data:0x803ED928; // type:object size:0x20 scope:global data:4byte
jumptable_803ED948 = .data:0x803ED948; // type:object size:0x20 scope:local
jumptable_803ED968 = .data:0x803ED968; // type:object size:0x2C scope:local
jumptable_803ED994 = .data:0x803ED994; // type:object size:0x2C scope:local
@344 = .data:0x803ED994; // type:object size:0x2C scope:local
__vt__10IAllocator = .data:0x803ED9C0; // type:object size:0x40 scope:global
lbl_803EDA00 = .data:0x803EDA00; // type:object size:0x10
__vt__18CCEKeyframeEmitter = .data:0x803EDA10; // type:object size:0x10 scope:global
@ -21933,7 +21933,7 @@ init$2340 = .sbss:0x805A9420; // type:object size:0x8 scope:global data:byte
sCurrentFrameCount__16CGraphicsPalette = .sbss:0x805A9428; // type:object size:0x8 scope:global data:4byte
sCurrentFrameCount__8CTexture = .sbss:0x805A9430; // type:object size:0x4 scope:global data:4byte
sTotalAllocatedMemory__8CTexture = .sbss:0x805A9434; // type:object size:0x4 scope:global data:4byte
sMangleMips__8CTexture = .sbss:0x805A9438; // type:object size:0x8 scope:global data:byte
sMangleMips__8CTexture = .sbss:0x805A9438; // type:object size:0x1 scope:global data:byte
svector2_Identity = .sbss:0x805A9440; // type:object size:0x8 scope:local
lbl_805A9448 = .sbss:0x805A9448; // type:object size:0x4 data:float
lbl_805A944C = .sbss:0x805A944C; // type:object size:0x1 data:byte

View File

@ -13585,7 +13585,7 @@ LoadToMRAM__8CTextureCFv = .text:0x8030ED08; // type:function size:0x50 scope:gl
TryBuildReloadedBitmapData__Q28CTexture25CDumpedBitmapDataReloaderFR11CResFactory = .text:0x8030ED58; // type:function size:0x2F8 scope:global
BeginReloadBitmapData__Q28CTexture25CDumpedBitmapDataReloaderFR11CResFactory = .text:0x8030F050; // type:function size:0xF4 scope:global
__ct__Q28CTexture25CDumpedBitmapDataReloaderFUiUib = .text:0x8030F144; // type:function size:0x24 scope:global
fn_8030F088 = .text:0x8030F168; // type:function size:0x7C scope:global
fn_8030F088__8CTextureCFv = .text:0x8030F168; // type:function size:0x7C scope:global
TryReloadBitmapData__8CTextureCFR11CResFactory = .text:0x8030F1E4; // type:function size:0x100 scope:global
UnloadBitmapData__8CTextureCFUi = .text:0x8030F2E4; // type:function size:0x194 scope:global
LoadMipLevel__8CTextureCFi11_GXTexMapIDQ28CTexture10EClampMode = .text:0x8030F478; // type:function size:0x3A4 scope:global

View File

@ -22,6 +22,7 @@ public:
~CARAMToken();
void PostConstruct(void* ptr, uint len, int unk);
CARAMToken& operator=(const CARAMToken& other);
const EStatus GetStatus() const { return x0_status; }
bool LoadToMRAM();
bool LoadToARAM();
bool RefreshStatus();

View File

@ -1,6 +1,7 @@
#ifndef _CRESFACTORY
#define _CRESFACTORY
#include "Kyoto/Streams/CInputStream.hpp"
#include "types.h"
#include "rstl/list.hpp"
@ -36,7 +37,9 @@ public:
CResLoader& GetResLoader() { return x4_resLoader; }
FourCC GetResourceTypeById(CAssetId id) { return GetResLoader().GetResourceTypeById(id); }
CInputStream* LoadResourceFromMemorySync(const SObjectTag& tag, const void* extBuf) {
return x4_resLoader.LoadResourceFromMemorySync(tag, extBuf);
}
private:
CResLoader x4_resLoader;
CFactoryMgr x5c_factoryMgr;

View File

@ -1,6 +1,7 @@
#ifndef _CRESLOADER
#define _CRESLOADER
#include "Kyoto/SObjectTag.hpp"
#include "types.h"
#include "rstl/list.hpp"
@ -9,7 +10,7 @@
#include "Kyoto/IObjectStore.hpp"
class CPakFile;
class CARAMDvdRequest;
class CDvdRequest;
struct SResInfo {
CAssetId x0_id;
@ -27,8 +28,10 @@ public:
void AsyncIdlePakLoading();
bool AreAllPaksLoaded() const;
CInputStream* LoadNewResourceSync(const SObjectTag& tag, char* extBuf);
CInputStream* LoadResourceFromMemorySync(const SObjectTag& tag, const void* extBuf);
CInputStream* LoadNewResourceSync(const SObjectTag& tag, int, int, char* extBuf);
CARAMDvdRequest* LoadResourcePartAsync(const SObjectTag& tag, int, int, char*);
CDvdRequest* LoadResourcePartAsync(const SObjectTag& tag, int, int, char*);
CDvdRequest* LoadResourceAsync(const SObjectTag& tag, char*);
FourCC GetResourceTypeById(CAssetId) const;
uint ResourceSize(const SObjectTag& tag) const;

View File

@ -23,7 +23,7 @@ public:
CGraphicsPalette(CInputStream& in);
~CGraphicsPalette();
inline GXTlutFmt GetTlutFmt() const { return static_cast<GXTlutFmt>(x0_fmt); }
inline GXTlutFmt GetTlutFmt() const { return static_cast< GXTlutFmt >(x0_fmt); }
ushort* GetPaletteData() { return xc_entries.get(); }
const ushort* GetPaletteData() const { return xc_entries.get(); }
void Load() const;
@ -39,4 +39,8 @@ private:
bool x1c_locked;
};
static inline GXTlutFmt format_to_format(EPaletteFormat fmt) {
return static_cast< GXTlutFmt >(fmt);
}
#endif // _CGRAPHICSPALETTE

View File

@ -1,6 +1,7 @@
#ifndef _CTEXTURE
#define _CTEXTURE
#include "dolphin/gx/GXEnum.h"
#include "types.h"
#include "Kyoto/CARAMToken.hpp"
@ -8,6 +9,7 @@
#include <dolphin/gx.h>
class CResFactory;
class CDvdRequest;
class CInputStream;
class CGraphicsPalette;
@ -37,6 +39,14 @@ public:
bool x10_;
rstl::single_ptr< CDvdRequest > x14_;
rstl::single_ptr< uchar > x18_;
public:
CDumpedBitmapDataReloader(uint unk1, uint unk2, bool unk3);
void BeginReloadBitmapData(CResFactory& factory);
void* TryBuildReloadedBitmapData(CResFactory& factory);
int GetStatus() const { return x0_; }
const bool GetX10() const { return x10_; }
};
enum EClampMode {
@ -56,19 +66,15 @@ public:
~CTexture();
// Used in certain destructors
void sub_8030e10c();
void fn_8030E10C();
void LoadMipLevel(int, GXTexMapID tex, EClampMode) const;
void Load(GXTexMapID texMapId, EClampMode clampMode) const;
void UnLock();
bool HasPalette() const { return IsCITextureFormat(mTexelFormat); }
const void* GetConstBitMapData(const int mip) const;
void* GetBitMapData(int);
void InitBitmapBuffers(ETexelFormat fmt, short w, short h, int mips);
void InitTextureObjects();
ETexelFormat GetTexelFormat() const { return mTexelFormat; }
short GetWidth() const { return mWidth; }
short GetHeight() const { return mHeight; }
const short GetWidth() const { return mWidth; }
const short GetHeight() const { return mHeight; }
void* Lock() {
mLocked = true;
return GetBitMapData(0);
@ -78,35 +84,51 @@ public:
void CountMemory() const;
void UncountMemory() const;
void SetFlag1(bool b) { mLocked = b; }
void MangleMipmap(int mip);
const char GetBitsPerPixel() const { return mBitsPerPixel; }
void UnloadBitmapData(uint unk) const;
bool TryReloadBitmapData(CResFactory& factory) const;
int fn_8030F088() const;
bool LoadToMRAM() const;
bool LoadToARAM() const;
bool IsARAMTransferInProgress() const;
static int TexelFormatBitsPerPixel(ETexelFormat fmt);
void InitBitmapBuffers(const ETexelFormat fmt, const short w, const short h, const int mips);
void InitTextureObjects();
void UnLock();
static uint TexelFormatBitsPerPixel(ETexelFormat fmt);
static void InvalidateTexmap(GXTexMapID id);
static bool IsCITextureFormat(ETexelFormat fmt) {
return fmt == kTF_C4 ? true : fmt == kTF_C8 ? true : fmt == kTF_C14X2 ? true : false;
}
static void SetMangleMipmaps(bool v) { sMangleMips = true; }
static const bool GetMangleMipmaps() { return sMangleMips; }
static int sCurrentFrameCount;
static int sTotalAllocatedMemory;
static bool sMangleMips;
private:
ETexelFormat mTexelFormat; // TODO: Enum
ETexelFormat mTexelFormat;
short mWidth;
short mHeight;
uchar mNumMips;
uchar mBitsPerPixel;
char mNumMips;
char mBitsPerPixel;
bool mLocked : 1;
bool mCanLoadPalette : 1;
mutable bool mCanLoadPalette : 1;
bool mIsPowerOfTwo : 1;
mutable bool mNoSwap : 1;
mutable bool mCounted : 1;
uchar mCanLoadObj : 1;
mutable bool mCanLoadObj : 1;
uint mMemoryAllocated;
rstl::single_ptr< CGraphicsPalette > mGraphicsPalette;
rstl::single_ptr< CDumpedBitmapDataReloader > mBitmapReloader;
uint mNativeFormat;
uint mNativeCIFormat;
GXTexObj mTexObj;
EClampMode mClampMode;
CARAMToken mARAMToken;
uint mFrameAllocated;
mutable rstl::single_ptr< CDumpedBitmapDataReloader > mBitmapReloader;
GXTexFmt mNativeFormat;
GXCITexFmt mNativeCIFormat;
mutable GXTexObj mTexObj;
mutable EClampMode mClampMode;
mutable CARAMToken mARAMToken;
mutable uint mFrameAllocated;
};
CHECK_SIZEOF(CTexture, 0x68)

View File

@ -78,6 +78,7 @@ public:
// CeilingF__5CMathFf global
// ArcTangentR__5CMathFf global
// Swap<f>__5CMathFRfRf weak
static int FloorPowerOfTwo(int v);
};
#endif // _CMATH

View File

@ -44,7 +44,8 @@ public:
// CIEKeyframeEmitter / rstl::vector(CInputStream&)
// why?
int ReadInt32() { return static_cast< uint >(Get(TType< int >())); }
u16 ReadUint16() { return Get<u16>(); }
ushort ReadUint16() { return Get<ushort>(); }
short ReadInt16() { return Get<short>(); }
uint GetBlockOffset() const { return x4_blockOffset; }

View File

@ -35,7 +35,6 @@ public:
single_ptr& Set(T* ptr);
};
template < typename T >
single_ptr< T >& single_ptr< T >::Set(T* ptr) {
return *this = ptr;

53
src/Dolphin/os/OSReboot.c Normal file
View File

@ -0,0 +1,53 @@
#include "dolphin/os.h"
typedef struct ApploaderHeader {
// total size: 0x20
char date[16]; // offset 0x0, size 0x10
u32 entry; // offset 0x10, size 0x4
u32 size; // offset 0x14, size 0x4
u32 rebootSize; // offset 0x18, size 0x4
u32 reserved2; // offset 0x1C, size 0x4
} ApploaderHeader;
static ApploaderHeader Header;
extern void* __OSSavedRegionStart;
extern void* __OSSavedRegionEnd;
static void* SaveStart = NULL;
static void* SaveEnd = NULL;
static BOOL Prepared = FALSE;
asm void Run() {
// clang-format off
nofralloc
sync
isync
mtlr r3
blr
// clang-format on
}
static void Callback() {
Prepared = TRUE;
}
void __OSReboot(u32 resetCode, u32 bootDol) {
OSDisableInterrupts();
}
void OSSetSaveRegion(void* start, void* end) {
SaveStart = start;
SaveEnd = end;
}
void OSGetSaveRegion(void** start, void** end) {
*start = SaveStart;
*end = SaveEnd;
}
void OSGetSavedRegion(void** start, void** end) {
*start = __OSSavedRegionStart;
*end = __OSSavedRegionEnd;
}

View File

@ -109,6 +109,8 @@ bool CARAMToken::LoadToMRAM() {
MoveToList(kS_Three);
break;
}
default:
break;
}
return RefreshStatus();
@ -143,8 +145,9 @@ bool CARAMToken::LoadToARAM() {
MoveToList(kS_Two);
break;
}
default:
break;
}
return RefreshStatus();
}
@ -176,6 +179,8 @@ bool CARAMToken::RefreshStatus() {
MoveToList(kS_Zero);
break;
}
default:
break;
}
return true;

View File

@ -29,11 +29,6 @@ int CDependencyGroup::GetCountForResType(FourCC type) const {
/* this is such a hack... */
#pragma inline_max_size(250)
template <>
CFactoryFnReturn::CFactoryFnReturn(CDependencyGroup* ptr)
: obj(TToken< CDependencyGroup >::GetIObjObjectFor(rstl::auto_ptr< CDependencyGroup >(ptr))
.release()) {}
CFactoryFnReturn FDependencyGroupFactory(const SObjectTag& tag, CInputStream& in,
const CVParamTransfer& xfer) {
return rs_new CDependencyGroup(in);

View File

@ -773,7 +773,7 @@ void CGraphics::EndScene() {
GXEnableBreakPt(writePtr);
mLastFrameUsedAbove = mInterruptLastFrameUsedAbove;
++mFrameCounter;
CFrameDelayedKiller::sub_8036cb90();
CFrameDelayedKiller::fn_8036CB90();
}
void CGraphics::SetDepthWriteMode(bool test, ERglEnum comp, bool write) {

View File

@ -8,16 +8,12 @@
uint CGraphicsPalette::sCurrentFrameCount = 0;
inline GXTlutFmt ConvertFormat(EPaletteFormat fmt) {
return static_cast<GXTlutFmt>(fmt);
}
CGraphicsPalette::CGraphicsPalette(EPaletteFormat format, int numEntries)
: x0_fmt(format)
, x8_entryCount(numEntries)
, xc_entries((ushort*)CMemory::Alloc(numEntries * sizeof(ushort), IAllocator::kHI_RoundUpLen))
, x1c_locked(false) {
GXInitTlutObj(&x10_tlutObj, xc_entries.get(), ConvertFormat(x0_fmt), x8_entryCount);
GXInitTlutObj(&x10_tlutObj, xc_entries.get(), format_to_format(x0_fmt), x8_entryCount);
}
CGraphicsPalette::CGraphicsPalette(CInputStream& in)
@ -26,7 +22,7 @@ CGraphicsPalette::CGraphicsPalette(CInputStream& in)
, xc_entries((ushort*)CMemory::Alloc(x8_entryCount * sizeof(ushort), IAllocator::kHI_RoundUpLen))
, x1c_locked(false) {
in.Get(reinterpret_cast< uchar* >(xc_entries.get()), x8_entryCount * sizeof(ushort));
GXInitTlutObj(&x10_tlutObj, xc_entries.get(), ConvertFormat(x0_fmt), x8_entryCount);
GXInitTlutObj(&x10_tlutObj, xc_entries.get(), format_to_format(x0_fmt), x8_entryCount);
DCFlushRange(xc_entries.get(), x8_entryCount * sizeof(ushort));
}
@ -44,7 +40,7 @@ void CGraphicsPalette::Load() const {
void CGraphicsPalette::UnLock() {
DCStoreRange(xc_entries.get(), x8_entryCount * sizeof(ushort));
GXInitTlutObj(&x10_tlutObj, xc_entries.get(), ConvertFormat(x0_fmt), x8_entryCount);
GXInitTlutObj(&x10_tlutObj, xc_entries.get(), format_to_format(x0_fmt), x8_entryCount);
DCFlushRange(xc_entries.get(), x8_entryCount * sizeof(ushort));
x1c_locked = false;
}

View File

@ -1,16 +1,33 @@
#include "Kyoto/Alloc/IAllocator.hpp"
#include "Kyoto/CARAMToken.hpp"
#include "Kyoto/CFrameDelayedKiller.hpp"
#include "Kyoto/Graphics/CTexture.hpp"
#include "Kyoto/SObjectTag.hpp"
#include "dolphin/PPCArch.h"
#include "dolphin/gx/GXEnum.h"
#include "dolphin/gx/GXStruct.h"
#include "dolphin/gx/GXTexture.h"
#include "dolphin/os.h"
#include "dolphin/os/OSCache.h"
#include "rstl/single_ptr.hpp"
#include "types.h"
#include "Kyoto/CDvdRequest.hpp"
#include "Kyoto/Graphics/CGraphicsPalette.hpp"
#include "Kyoto/Alloc/CMemorySys.hpp"
#include <Kyoto/Alloc/CMemory.hpp>
#include <Kyoto/CDvdRequest.hpp>
#include <Kyoto/CResFactory.hpp>
#include <Kyoto/Graphics/CGraphicsPalette.hpp>
#include <Kyoto/Math/CMath.hpp>
#include <Kyoto/Streams/CInputStream.hpp>
int CTexture::sCurrentFrameCount = 0;
int CTexture::sTotalAllocatedMemory = 0;
bool CTexture::sMangleMips = false;
static CTexture* sLoadedTextures[GX_MAX_TEXMAP];
#define ROUND_UP_4(v) (((v) + 3) & ~3)
CTexture::CTexture(ETexelFormat fmt, short w, short h, int mips)
static const CTexture* sLoadedTextures[GX_MAX_TEXMAP];
CTexture::CTexture(ETexelFormat fmt, const short w, const short h, int mips)
: mTexelFormat(fmt)
, mWidth(w)
, mHeight(h)
@ -31,14 +48,441 @@ CTexture::CTexture(ETexelFormat fmt, short w, short h, int mips)
InitTextureObjects();
}
CTexture::CTexture(CInputStream& in, EAutoMipmap automip, EBlackKey blackKey) {
CTexture::CTexture(CInputStream& in, EAutoMipmap automip, EBlackKey blackKey)
: mTexelFormat(kTF_Invalid)
, mWidth(0)
, mHeight(0)
, mNumMips(0)
, mBitsPerPixel(0)
, mLocked(false)
, mCanLoadPalette(false)
, mIsPowerOfTwo(false)
, mNoSwap(true)
, mCounted(false)
, mCanLoadObj(false)
, mMemoryAllocated(0)
, mFrameAllocated(sCurrentFrameCount)
, mNativeFormat(GX_TF_RGB565)
, mNativeCIFormat(GX_TF_C8)
, mClampMode(kCM_Repeat) {
mTexelFormat = ETexelFormat(in.Get< uint >());
mWidth = in.ReadUint16();
mHeight = in.ReadUint16();
mNumMips = in.ReadLong();
if (IsCITextureFormat(mTexelFormat)) {
mGraphicsPalette = rs_new CGraphicsPalette(in);
mCanLoadPalette = true;
}
mBitsPerPixel = TexelFormatBitsPerPixel(mTexelFormat);
InitBitmapBuffers(mTexelFormat, mWidth, mHeight, mNumMips);
int bufLen = 0;
for (int i = 0; i < mNumMips;) {
int width = ((GetWidth() >> i) + 3) & ~3;
int height = ((GetHeight() >> i) + 3) & ~3;
int page = width * height;
i++;
bufLen += (GetBitsPerPixel() * page) >> 3;
}
uchar* buf = (uchar*)mARAMToken.GetMRAMSafe();
for (int off = 0, len = 0; off < bufLen; off += len) {
len = bufLen - off;
if (len > 256) {
len = 256;
}
in.Get(buf + off, len);
DCFlushRangeNoSync(buf + off, OSRoundUp32B(len));
}
if (sMangleMips != false) {
for (int i = 1; i < mNumMips; ++i) {
MangleMipmap(i);
}
}
InitTextureObjects();
PPCSync();
}
CTexture::~CTexture() {
UncountMemory();
CTexture::~CTexture() { UncountMemory(); }
void CTexture::InitTextureObjects() {
mIsPowerOfTwo =
CMath::FloorPowerOfTwo(mWidth) == mWidth && CMath::FloorPowerOfTwo(mHeight) == mHeight;
if (!mIsPowerOfTwo) {
mClampMode = kCM_Clamp;
}
bool hasMips = mNumMips > 1;
GXTexWrapMode wrap = (GXTexWrapMode)mClampMode;
short width = mWidth;
short height = mHeight;
void* buf = mARAMToken.GetMRAMSafe();
CountMemory();
if (IsCITextureFormat(mTexelFormat)) {
GXInitTexObjCI(&mTexObj, buf, width, height, mNativeCIFormat, wrap, wrap, hasMips, 0);
} else {
GXInitTexObj(&mTexObj, buf, width, height, mNativeFormat, wrap, wrap, hasMips);
GXInitTexObjLOD(&mTexObj, mNumMips > 1 ? GX_LIN_MIP_LIN : GX_LINEAR, GX_LINEAR, 0.f,
mNumMips - 1.f, 0.f, false, false, mNumMips > 1 ? GX_ANISO_4 : GX_ANISO_1);
}
mCanLoadObj = true;
}
void CTexture::Load(GXTexMapID tex, EClampMode clamp) const {
if (sLoadedTextures[tex] != this || mCanLoadObj) {
void* ptr = mARAMToken.GetMRAMSafe();
CountMemory();
if (!mGraphicsPalette.null()) {
mGraphicsPalette->Load();
mCanLoadPalette = false;
}
mCanLoadObj = false;
if (mClampMode != clamp) {
if (!mIsPowerOfTwo) {
mClampMode = kCM_Clamp;
} else {
mClampMode = clamp;
}
GXInitTexObjWrapMode(&mTexObj, (GXTexWrapMode)mClampMode, (GXTexWrapMode)mClampMode);
}
GXInitTexObjData(&mTexObj, ptr);
GXLoadTexObj(&mTexObj, tex);
sLoadedTextures[tex] = this;
mFrameAllocated = sCurrentFrameCount;
}
}
void CTexture::LoadMipLevel(int mip, GXTexMapID tex, EClampMode clamp) const {
char* ptr = (char*)mARAMToken.GetMRAMSafe();
GXTexObj obj = mTexObj;
int width = GetWidth();
int height = GetHeight();
int offset = 0;
GXTexWrapMode wrap = (GXTexWrapMode)clamp;
for (int i = 0; i < mip; i++) {
int w = ROUND_UP_4(width);
int h = ROUND_UP_4(height);
offset += OSRoundUp32B(((mBitsPerPixel * (w * h)) / 8));
width /= 2;
height /= 2;
}
GXInitTexObj(&obj, ptr + offset, width, height, mNativeFormat, wrap, wrap, false);
GXInitTexObjLOD(&obj, GX_LINEAR, GX_LINEAR, 0.f, 0.f, 0.f, false, false, GX_ANISO_1);
if (!mGraphicsPalette.null()) {
mGraphicsPalette->Load();
mCanLoadPalette = false;
}
GXLoadTexObj(&obj, tex);
sLoadedTextures[tex] = nullptr;
mFrameAllocated = sCurrentFrameCount;
}
void CTexture::UnloadBitmapData(CAssetId textureId) const {
if (!mBitmapReloader.null()) {
bool b = mBitmapReloader->GetX10();
mBitmapReloader = rs_new CDumpedBitmapDataReloader(textureId, mMemoryAllocated, b);
} else {
bool complete = mARAMToken.GetStatus() == CARAMToken::kS_Zero ||
mARAMToken.GetStatus() == CARAMToken::kS_Two ||
mARAMToken.GetStatus() == CARAMToken::kS_Five;
mARAMToken = CARAMToken();
mBitmapReloader = rs_new CDumpedBitmapDataReloader(textureId, mMemoryAllocated, complete);
}
}
bool CTexture::TryReloadBitmapData(CResFactory& factory) const {
if (mBitmapReloader.null()) {
return true;
}
mBitmapReloader->BeginReloadBitmapData(factory);
uchar* ptr = (uchar*)mBitmapReloader->TryBuildReloadedBitmapData(factory);
if (ptr != nullptr) {
bool bVar1 = mBitmapReloader->GetX10();
mBitmapReloader = nullptr;
mARAMToken.PostConstruct(ptr, mMemoryAllocated, 1);
const_cast< CTexture& >(*this).InitTextureObjects();
if (bVar1) {
LoadToARAM();
}
return true;
}
return false;
}
int CTexture::fn_8030F088() const {
if (!mBitmapReloader.null()) {
if (mBitmapReloader->GetStatus() == 0) {
return 2;
}
return 5;
}
switch (mARAMToken.GetStatus()) {
case CARAMToken::kS_Zero:
return 1;
case CARAMToken::kS_One:
return 0;
case CARAMToken::kS_Five:
case CARAMToken::kS_Two:
return 3;
case CARAMToken::kS_Three:
case CARAMToken::kS_Four:
return 4;
default:
return -1;
}
}
CTexture::CDumpedBitmapDataReloader::CDumpedBitmapDataReloader(uint unk1, uint unk2, bool unk3)
: x0_(0), x4_(unk1), x8_(0), xc_(unk2), x10_(unk3) {}
void CTexture::CDumpedBitmapDataReloader::BeginReloadBitmapData(CResFactory& factory) {
if (x0_ != 0) {
return;
}
SObjectTag tag('TXTR', x4_);
x8_ = factory.ResourceSize(tag);
x18_ = (uchar*)CMemory::Alloc(x8_, IAllocator::kHI_RoundUpLen);
x14_ = factory.GetResLoader().LoadResourceAsync(tag, (char*)x18_.get());
x0_ = 1;
}
void* CTexture::CDumpedBitmapDataReloader::TryBuildReloadedBitmapData(CResFactory& factory) {
if (x14_->IsComplete()) {
x0_ = 2;
x14_ = nullptr;
SObjectTag tag('TXTR', x4_);
rstl::single_ptr< CInputStream > buf = factory.LoadResourceFromMemorySync(tag, x18_.get());
CInputStream* in = buf.get();
ETexelFormat format = ETexelFormat(in->ReadInt32());
const int w = in->ReadInt16();
const int h = in->ReadInt16();
const int numMips = in->ReadInt32();
const int bitsPerPixel = TexelFormatBitsPerPixel(format);
if (IsCITextureFormat(format)) {
CGraphicsPalette tmp(*in);
}
int bufLen = 0;
for (int i = 0; i < numMips;) {
int width = ((w >> i) + 3) & ~3;
int height = ((h >> i) + 3) & ~3;
int page = (width * height);
i++;
bufLen += (page * bitsPerPixel) >> 3;
}
void* ptr = CMemory::Alloc(xc_, IAllocator::kHI_RoundUpLen);
for (int off = 0, len = 0; off < bufLen; off += len) {
len = bufLen - off;
if (len > 256) {
len = 256;
}
in->Get((char*)ptr + off, len);
DCFlushRangeNoSync((char*)ptr + off, OSRoundUp32B(len));
}
PPCSync();
x18_ = nullptr;
return ptr;
}
return nullptr;
}
bool CTexture::LoadToMRAM() const {
if (mARAMToken.GetStatus() == CARAMToken::kS_Six) {
return false;
}
mFrameAllocated = sCurrentFrameCount;
CountMemory();
return mARAMToken.LoadToMRAM();
}
bool CTexture::LoadToARAM() const {
if (mARAMToken.GetStatus() == CARAMToken::kS_Six) {
return false;
}
if (mNoSwap) {
return false;
}
if (mFrameAllocated < sCurrentFrameCount - 1) {
bool ret = mARAMToken.LoadToARAM();
if (mARAMToken.GetStatus() != CARAMToken::kS_One) {
UncountMemory();
mCanLoadObj = true;
}
return ret;
}
return false;
}
bool CTexture::IsARAMTransferInProgress() const {
if (mNoSwap) {
return false;
}
return mARAMToken.GetStatus() >= CARAMToken::kS_Two &&
mARAMToken.GetStatus() <= CARAMToken::kS_Five;
}
int CTexture::TexelFormatBitsPerPixel(ETexelFormat fmt) {
switch (fmt) {
case kTF_I4:
case kTF_C4:
case kTF_CMPR:
return 4;
case kTF_I8:
case kTF_IA4:
case kTF_C8:
return 8;
case kTF_IA8:
case kTF_C14X2:
case kTF_RGB565:
case kTF_RGB5A3:
return 16;
case kTF_RGBA8:
return 32;
default:
return 0;
}
}
void CTexture::InitBitmapBuffers(ETexelFormat fmt, short width, short height, int mips) {
switch (fmt) {
case kTF_C4:
mNativeCIFormat = GX_TF_C4;
break;
case kTF_C8:
mNativeCIFormat = GX_TF_C8;
break;
case kTF_C14X2:
mNativeCIFormat = GX_TF_C14X2;
break;
case kTF_I4:
mNativeFormat = GX_TF_I4;
break;
case kTF_I8:
mNativeFormat = GX_TF_I8;
break;
case kTF_IA4:
mNativeFormat = GX_TF_IA4;
break;
case kTF_IA8:
mNativeFormat = GX_TF_IA8;
break;
case kTF_RGB565:
mNativeFormat = GX_TF_RGB565;
break;
case kTF_RGB5A3:
mNativeFormat = GX_TF_RGB5A3;
break;
case kTF_RGBA8:
mNativeFormat = GX_TF_RGBA8;
break;
case kTF_CMPR:
mNativeFormat = GX_TF_CMPR;
break;
default:
break;
}
bool hasMips = mips > 1;
mMemoryAllocated = GXGetTexBufferSize(
width, height, HasPalette() ? mNativeCIFormat : mNativeFormat, hasMips, hasMips ? 11 : 0);
mARAMToken.PostConstruct(CMemory::Alloc(mMemoryAllocated, IAllocator::kHI_RoundUpLen),
mMemoryAllocated, 1);
CountMemory();
}
void CTexture::UnLock() {
mLocked = false;
CountMemory();
DCFlushRange(mARAMToken.GetMRAMSafe(), OSRoundUp32B(mMemoryAllocated));
}
CFactoryFnReturn FTextureFactory(const SObjectTag& tag, CInputStream& in,
const CVParamTransfer& xfer) {
return rs_new CTexture(in, CTexture::kAM_Zero, CTexture::kBK_Zero);
}
const void* CTexture::GetConstBitMapData(const int mip) const {
int offset = 0;
for (int i = 0; i < mip; i++) {
offset += (GetBitsPerPixel() >> 3) * ((GetWidth() >> i) * (GetHeight() >> i));
}
return (const uchar*)mARAMToken.GetMRAMSafe() + offset;
}
void* CTexture::GetBitMapData(int mip) { return const_cast< void* >(GetConstBitMapData(mip)); }
void CTexture::MangleMipmap(int mip) {
static const uint kMangleColors[4] = {0x000000FF, 0x0000FF00, 0x00FF0000, 0x0000FFFF};
uint color1 = *(uint*)((uchar*)kMangleColors + (((mip - 1) * 4) & 12));
uint color2 = color1 >> 8;
uint color3 = color2 & 0xf800 | (color1 >> 3) & 0x1f | (color1 >> 5) & 0x7e0;
int width = GetWidth();
int height = GetHeight();
int offset = 0;
for (int i = 0; i < mip; i++) {
offset += (width * height);
width /= 2;
height /= 2;
}
switch (GetTexelFormat()) {
case kTF_RGB565: {
ushort* ptr = (ushort*)mARAMToken.GetMRAMSafe();
for (int i = 0; i < width * height; ++i) {
ptr[i + offset] = color3;
}
break;
}
case kTF_RGB5A3: {
ushort* ptr = (ushort*)mARAMToken.GetMRAMSafe();
for (int i = 0; i < width * height; ++i) {
if (ptr[i + offset] & 0x8000) {
ptr[i + offset] = ptr[i + offset] & 0xf000 | (color1 >> 12) | 0xf00 | (color1 >> 4) & 0xf | color2 & 0xf0;
} else {
ptr[i + offset] = (color1 >> 9) | 0x7c00 | (color1 >> 6) & 0x3e0 | (color1 >> 3) & 0x1f | 0x8000;
}
}
break;
}
case kTF_CMPR: {
ushort* ptr = (ushort*)mARAMToken.GetMRAMSafe();
}
default:
break;
}
}
void CTexture::MakeSwappable() const {
if (!mNoSwap) {
@ -47,6 +491,7 @@ void CTexture::MakeSwappable() const {
mNoSwap = false;
}
void CTexture::CountMemory() const {
if (mCounted) {
return;
@ -56,7 +501,6 @@ void CTexture::CountMemory() const {
sTotalAllocatedMemory += mMemoryAllocated;
}
void CTexture::UncountMemory() const {
if (!mCounted) {
return;
@ -66,10 +510,10 @@ void CTexture::UncountMemory() const {
sTotalAllocatedMemory -= mMemoryAllocated;
}
void CTexture::InvalidateTexmap(GXTexMapID texmap) {
sLoadedTextures[texmap] = nullptr;
}
void CTexture::sub_8030e10c() {
void CTexture::InvalidateTexmap(GXTexMapID texmap) { sLoadedTextures[texmap] = nullptr; }
void CTexture::fn_8030E10C() {
if (mARAMToken.GetStatus() != CARAMToken::kS_Six) {
CFrameDelayedKiller::fn_8036CC1C(true, mARAMToken.ForceSyncMRAM());
}
}

View File

@ -42,10 +42,7 @@ const wchar_t* CStringTable::GetString(int idx) const {
return reinterpret_cast< const wchar_t* >(x4_data.get() + offset);
}
template <>
CFactoryFnReturn::CFactoryFnReturn(CStringTable* ptr)
: obj(TToken< CStringTable >::GetIObjObjectFor(rstl::auto_ptr< CStringTable >(ptr)).release()) {}
#pragma inline_max_size(250)
CFactoryFnReturn FStringTableFactory(const SObjectTag& tag, CInputStream& in,
const CVParamTransfer& xfer) {
return rs_new CStringTable(in);

View File

@ -17,7 +17,7 @@ CProjectedShadow::CProjectedShadow(int w, int h, uchar persistent)
{}
CProjectedShadow::~CProjectedShadow() {
x0_texture.sub_8030e10c();
x0_texture.fn_8030E10C();
}
void CProjectedShadow::ModelDrawCallback(const float*, const float*, const SShadowDrawContext*) {

View File

@ -30,7 +30,7 @@ CWorldShadow::CWorldShadow(uint w, uint h, bool rgba8)
CWorldShadow::~CWorldShadow() {
if (x0_texture.get())
x0_texture->sub_8030e10c();
x0_texture->fn_8030E10C();
}
void CWorldShadow::BuildLightShadowTexture(const CStateManager& mgr, TAreaId aid, uint lightIdx,
@ -151,8 +151,7 @@ void CWorldShadow::BuildLightShadowTexture(const CStateManager& mgr, TAreaId aid
}
GXSetTexCopyDst(x0_texture->GetWidth(), x0_texture->GetHeight(), fmt, true);
static int unkInt = 0;
x0_texture->SetFlag1(true);
void * dest = x0_texture->GetBitMapData(0);
void * dest = x0_texture->Lock();
GXCopyTex(dest, true);
x0_texture->UnLock();