Merge pull request #502 from SwareJonge/JSystem

Implement all of JSystem
This commit is contained in:
Cuyler36
2025-06-17 20:42:57 -04:00
committed by GitHub
111 changed files with 10982 additions and 6206 deletions
@@ -0,0 +1,195 @@
#include "JSystem/J2D/J2DGrafContext.h"
#include "MSL_C/math.h"
J2DGrafContext::J2DGrafContext(f32 left, f32 top, f32 right, f32 bottom)
: mBounds(left, top, left + right, top + bottom), mScissorBounds(left, top, left + right, top + bottom) {
JUtility::TColor color(-1);
setColor(color);
setLineWidth(6);
}
void J2DGrafContext::setPort() {
setScissor();
setup2D();
GXSetViewport(mBounds.i.x, mBounds.i.y, mBounds.f.x - mBounds.i.x, mBounds.f.y - mBounds.i.y, 0.0f, 1.0f);
}
void J2DGrafContext::setup2D() {
GXSetNumIndStages(0);
for (int i = 0; i < 8; i++) {
GXSetTevDirect((GXTevStageID)i);
}
GXSetAlphaCompare(GX_ALWAYS, 0, GX_AOP_AND, GX_ALWAYS, 0);
GXSetZMode(0, GX_LEQUAL, 0);
GXSetTevOp(GX_TEVSTAGE0, GX_PASSCLR);
GXSetNumChans(1);
GXSetNumTevStages(1);
GXSetNumTexGens(0);
GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR0A0);
GXSetCullMode(GX_CULL_NONE);
GXLoadPosMtxImm(mPosMtx, 0);
GC_Mtx m;
PSMTXIdentity(m);
GXLoadTexMtxImm(m, 60, GX_MTX3x4);
GXSetChanCtrl(GX_COLOR0A0, 0, GX_SRC_REG, GX_SRC_VTX, GX_LIGHT_NULL, GX_DF_NONE, GX_AF_NONE);
GXSetChanCtrl(GX_COLOR1A1, 0, GX_SRC_REG, GX_SRC_REG, GX_LIGHT_NULL, GX_DF_NONE, GX_AF_NONE);
GXSetCurrentMtx(0);
GXSetTexCoordGen2(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, 60, 0, 125);
GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_CLR0, GX_POS_XYZ, GX_RGBA8, 0);
GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_RGBA4, 0);
GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_POS_XYZ, GX_RGBX8, 0xF);
GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX1, GX_POS_XYZ, GX_RGBX8, 0xF);
GXSetLineWidth(mLineWidth, GX_TO_ZERO);
GXClearVtxDesc();
GXSetVtxDesc(GX_VA_POS, GX_DIRECT);
GXSetVtxDesc(GX_VA_CLR0, GX_DIRECT);
GXSetVtxDesc(GX_VA_TEX0, GX_NONE);
}
void J2DGrafContext::setScissor() {
JGeometry::TBox2f hardBounds(0, 0, 1024, 1000);
JGeometry::TBox2f newBounds(mScissorBounds);
mScissorBounds.intersect(hardBounds);
newBounds.absolute();
newBounds.addPos(0.0f, -1.0f);
if (newBounds.intersect(hardBounds)) {
GXSetScissor(newBounds.i.x, newBounds.i.y, newBounds.getWidth(), newBounds.getHeight());
} else {
GXSetScissor(0, 0, 0, 0);
}
}
void J2DGrafContext::scissor(const JGeometry::TBox2f& bounds) {
mScissorBounds = bounds;
}
void J2DGrafContext::place(const JGeometry::TBox2f& bounds) {
mBounds = bounds;
mScissorBounds = bounds;
}
void J2DGrafContext::setColor(JUtility::TColor colorTL, JUtility::TColor colorTR, JUtility::TColor colorBR,
JUtility::TColor colorBL) {
mColorTL = colorTL;
mColorTR = colorTR;
mColorBR = colorBR;
mColorBL = colorBL;
_B0.mType = 1;
_B0.mSrcFactor = 4;
_B0.mDestFactor = 5;
mLinePart.mType = 1;
mLinePart.mSrcFactor = 4;
mLinePart.mDestFactor = 5;
mBoxPart.mType = 1;
mBoxPart.mSrcFactor = 4;
mBoxPart.mDestFactor = 5;
if ((u8)u32(mColorTL) != 0xFF) {
return;
}
_B0.mType = 0;
_B0.mSrcFactor = 1;
_B0.mDestFactor = 0;
if ((u8)u32(mColorBR) != 0xFF) {
return;
}
mLinePart.mType = 0;
mLinePart.mSrcFactor = 1;
mLinePart.mDestFactor = 0;
if ((u8)u32(mColorTR) != 0xFF) {
return;
}
if ((u8)u32(mColorBL) != 0xFF) {
return;
}
mBoxPart.mType = 0;
mBoxPart.mSrcFactor = 1;
mBoxPart.mDestFactor = 0;
}
void J2DGrafContext::setLineWidth(u8 width) {
mLineWidth = width;
GXSetLineWidth(mLineWidth, GX_TO_ZERO);
}
void J2DGrafContext::fillBox(const JGeometry::TBox2f& box) {
GXSetBlendMode((GXBlendMode)mBoxPart.mType, (GXBlendFactor)mBoxPart.mSrcFactor, (GXBlendFactor)mBoxPart.mDestFactor,
GX_LO_SET);
GXLoadPosMtxImm(mPosMtx, 0);
GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_CLR_RGBA, GX_F32, 0);
GXBegin(GX_QUADS, GX_VTXFMT0, 4);
GXPosition3f32(box.i.x, box.i.y, 0.0f);
GXColor1u32(mColorTL);
GXPosition3f32(box.f.x, box.i.y, 0.0f);
GXColor1u32(mColorTR);
GXPosition3f32(box.f.x, box.f.y, 0.0f);
GXColor1u32(mColorBL);
GXPosition3f32(box.i.x, box.f.y, 0.0f);
GXColor1u32(mColorBR);
GXEnd();
GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_CLR_RGBA, GX_RGBA4, 0);
}
void J2DGrafContext::drawFrame(const JGeometry::TBox2f& box) {
GXSetBlendMode((GXBlendMode)mBoxPart.mType, (GXBlendFactor)mBoxPart.mSrcFactor, (GXBlendFactor)mBoxPart.mDestFactor,
GX_LO_SET);
GXLoadPosMtxImm(mPosMtx, 0);
GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_CLR_RGBA, GX_F32, 0);
GXBegin(GX_LINESTRIP, GX_VTXFMT0, 5);
GXPosition3f32(box.i.x, box.i.y, 0.0f);
GXColor1u32(mColorTL);
GXPosition3f32(box.f.x, box.i.y, 0.0f);
GXColor1u32(mColorTR);
GXPosition3f32(box.f.x, box.f.y, 0.0f);
GXColor1u32(mColorBL);
GXPosition3f32(box.i.x, box.f.y, 0.0f);
GXColor1u32(mColorBR);
GXPosition3f32(box.i.x, box.i.y, 0.0f);
GXColor1u32(mColorTL);
GXEnd();
GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_CLR_RGBA, GX_RGBA4, 0);
}
void J2DGrafContext::line(JGeometry::TVec2f start, JGeometry::TVec2f end) {
GXSetBlendMode((GXBlendMode)mLinePart.mType, (GXBlendFactor)mLinePart.mSrcFactor,
(GXBlendFactor)mLinePart.mDestFactor, GX_LO_SET);
GXLoadPosMtxImm(mPosMtx, 0);
GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_CLR_RGBA, GX_F32, 0);
GXBegin(GX_LINES, GX_VTXFMT0, 2);
GXPosition3f32(start.x, start.y, 0.0f);
GXColor1u32(mColorTL);
GXPosition3f32(end.x, end.y, 0.0f);
GXColor1u32(mColorBR);
GXEnd();
GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_CLR_RGBA, GX_RGBA4, 0);
}
void J2DGrafContext::lineTo(JGeometry::TVec2f pos) {
line(mPrevPos, pos);
mPrevPos = pos;
}
@@ -0,0 +1,84 @@
#include "JSystem/J2D/J2DGrafContext.h"
J2DOrthoGraph::J2DOrthoGraph() : J2DGrafContext(0.0f, 0.0f, 0.0f, 0.0f) {
setLookat();
}
J2DOrthoGraph::J2DOrthoGraph(f32 left, f32 top, f32 right, f32 bottom, f32 near, f32 far)
: J2DGrafContext(left, top, right, bottom) {
mOrtho = JGeometry::TBox2f(0, 0, right, bottom);
mNear = near;
mFar = far;
setLookat();
}
void J2DOrthoGraph::setPort() {
J2DGrafContext::setPort();
C_MTXOrtho(mMtx44, mOrtho.i.y, 0.5f + mOrtho.f.y, mOrtho.i.x, mOrtho.f.x, mNear, mFar);
GXSetProjection(mMtx44, GX_ORTHOGRAPHIC);
}
void J2DOrthoGraph::setOrtho(const JGeometry::TBox2f& bounds, f32 far, f32 near) {
mOrtho = bounds;
mNear = -near;
mFar = -far;
}
void J2DOrthoGraph::setLookat() {
PSMTXIdentity(mPosMtx);
GXLoadPosMtxImm(mPosMtx, 0);
}
void J2DOrthoGraph::scissorBounds(JGeometry::TBox2f* out, const JGeometry::TBox2f* src) {
f32 widthPower = this->getWidthPower();
f32 heightPower = this->getHeightPower();
f32 ix = mBounds.i.x >= 0 ? mBounds.i.x : 0;
f32 iy = mBounds.i.y >= 0 ? mBounds.i.y : 0;
f32 f0 = ix + widthPower * (src->i.x - mOrtho.i.x);
f32 f2 = ix + widthPower * (src->f.x - mOrtho.i.x);
f32 f1 = iy + heightPower * (src->i.y - mOrtho.i.y);
f32 f3 = iy + heightPower * (src->f.y - mOrtho.i.y);
out->set(f0, f1, f2, f3);
out->intersect(mScissorBounds);
}
void J2DDrawLine(f32 x1, f32 y1, f32 x2, f32 y2, JUtility::TColor color, int line_width) {
J2DOrthoGraph oGrph;
oGrph.setLineWidth(line_width);
oGrph.setColor(color);
oGrph.moveTo(x1, y1);
oGrph.lineTo(x2, y2);
}
void J2DFillBox(f32 l, f32 t, f32 x, f32 y, JUtility::TColor color) {
J2DFillBox(JGeometry::TBox2f(l, t, l + x, t + y), color);
}
void J2DFillBox(const JGeometry::TBox2f& box, JUtility::TColor color) {
J2DOrthoGraph oGrph;
oGrph.setColor(color);
oGrph.fillBox(box);
}
void J2DFillBox(f32 l, f32 t, f32 x, f32 y, JUtility::TColor c1, JUtility::TColor c2, JUtility::TColor c3,
JUtility::TColor c4) {
J2DFillBox(JGeometry::TBox2f(l, t, l + x, t + y), c1, c2, c3, c4);
}
void J2DFillBox(const JGeometry::TBox2f& box, JUtility::TColor c1, JUtility::TColor c2, JUtility::TColor c3,
JUtility::TColor c4) {
J2DOrthoGraph oGrph;
oGrph.setColor(c1, c2, c3, c4);
oGrph.fillBox(box);
}
void J2DDrawFrame(f32 l, f32 t, f32 x, f32 y, JUtility::TColor color, u8 line_width) {
J2DDrawFrame(JGeometry::TBox2f(l, t, l + x, t + y), color, line_width);
}
void J2DDrawFrame(const JGeometry::TBox2f& box, JUtility::TColor color, u8 line_width) {
J2DOrthoGraph oGrph;
oGrph.setColor(color);
oGrph.setLineWidth(line_width);
oGrph.drawFrame(box);
}
@@ -0,0 +1,532 @@
#include <libc/string.h>
#include <dolphin/vi.h>
#include "JSystem/J2D/J2DGrafContext.h"
#include "JSystem/JUtility/JUTAssertion.h"
#include "JSystem/JUtility/JUTConsole.h"
#include "JSystem/JUtility/JUTDbPrint.h"
#include "JSystem/JUtility/JUTVideo.h"
#include "JSystem/JUtility/JUTProcBar.h"
#include "JSystem/JFramework/JFWDisplay.h"
// Sources: https://github.com/zeldaret/tp/blob/master/libs/JSystem/JFramework/JFWDisplay.cpp
// https://github.com/kiwi515/ogws/blob/master/src/egg/core/eggAsyncDisplay.cpp
// gpHang: https://github.com/valentinaslover/paper-mar/blob/master/source/sdk/DEMOInit.c#L280
GC_Mtx e_mtx = { { 1.0f, 0.0f, 0.0f, 0.0f }, { 0.0f, 1.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 1.0f, 0.0f } };
JFWDisplay* JFWDisplay::sManager;
extern void JFWThreadAlarmHandler(OSAlarm*, OSContext*);
extern void JFWGXAbortAlarmHandler(OSAlarm*, OSContext*);
void waitForTick(u32, u16);
void diagnoseGpHang();
inline void JFWDrawDoneAlarm() {
OSAlarm alarm;
OSCreateAlarm(&alarm);
OSSetAlarm(&alarm, (OS_TIMER_CLOCK), JFWGXAbortAlarmHandler);
GXDrawDone();
OSCancelAlarm(&alarm);
}
void JFWDisplay::ctor_subroutine(const GXRenderModeObj* rmode, bool enableAlpha) {
mEnableAlpha = enableAlpha;
mClamp = GX_CLAMP_TOP | GX_CLAMP_BOTTOM;
mClearColor.set(0, 0, 0, 0);
mZClear = 0xFFFFFF;
mRMode = (rmode) ? rmode : JUTVideo::sManager->getRenderMode();
mGamma = 0;
mFader = nullptr;
mFrameRate = 1;
mTickRate = 0;
mCombinationRatio = 0.0f;
mFrameTime = 0;
mStartTick = OSGetTick();
mVideoFrameTime = 0;
mDrawingXfbNo = 0;
mIsSingleXfb = false;
mDrawDoneMethod = UNK_METHOD_0;
clearEfb_init();
JUTProcBar::create();
JUTProcBar::clear();
}
JFWDisplay::JFWDisplay(const _GXRenderModeObj* rmode, JKRHeap* heap, JUTXfb::EXfbNumber bufferCount, bool p3) {
ctor_subroutine(rmode, p3);
mXfb = JUTXfb::createManager(rmode, heap, bufferCount);
}
JFWDisplay::~JFWDisplay() {
waitBlanking(2);
JUTProcBar::destroy();
JUTXfb::destroyManager();
}
JFWDisplay* JFWDisplay::createManager(const GXRenderModeObj* rmode, JKRHeap* heap, JUTXfb::EXfbNumber bufferCount,
bool p4) {
JUT_CONFIRM_MESSAGE(sManager == 0);
if (sManager == nullptr)
sManager = new JFWDisplay(rmode, heap, bufferCount, p4);
return sManager;
}
void JFWDisplay::destroyManager() {
JUT_CONFIRM_MESSAGE(sManager);
delete sManager;
sManager = nullptr;
}
void callDirectDraw() {
JUTChangeFrameBuffer(JUTXfb::getManager()->getDrawingXfb(), JUTVideo::getManager()->getEfbHeight(),
JUTVideo::getManager()->getFbWidth());
JUTAssertion::flushMessage();
}
void JFWDisplay::prepareCopyDisp() {
GXRenderModeObj* rmode = JUTVideo::getManager()->getRenderMode();
u16 width = (u16)JUTVideo::getManager()->getFbWidth();
u16 height = (u16)JUTVideo::getManager()->getEfbHeight();
u16 xfbHeight = (u16)JUTVideo::getManager()->getXfbHeight();
GXSetCopyClear(mClearColor, mZClear);
GXSetDispCopySrc(0, 0, width, height);
GXSetDispCopyDst(width, xfbHeight);
GXSetDispCopyYScale(xfbHeight / (f32)height);
VIFlush();
GXSetCopyFilter((GXBool)rmode->aa, rmode->sample_pattern, GX_ENABLE, rmode->vfilter);
GXSetCopyClamp((GXFBClamp)mClamp);
GXSetDispCopyGamma((GXGamma)mGamma);
GXSetZMode(GX_ENABLE, GX_LEQUAL, GX_ENABLE);
if (mEnableAlpha) {
GXSetAlphaUpdate(GX_ENABLE);
}
}
void JFWDisplay::drawendXfb_single() {
JUTXfb* manager = JUTXfb::getManager();
if (manager->getDrawingXfbIndex() >= 0) {
prepareCopyDisp();
JFWDrawDoneAlarm();
GXFlush();
manager->setDrawnXfbIndex(manager->getDrawingXfbIndex());
}
}
void JFWDisplay::exchangeXfb_double() {
JUTXfb* xfbMng = JUTXfb::getManager();
if (xfbMng->getDrawnXfbIndex() == xfbMng->getDisplayingXfbIndex()) {
if (xfbMng->getDrawingXfbIndex() >= 0) {
prepareCopyDisp();
GXCopyDisp(xfbMng->getDrawingXfb(), GX_TRUE);
if (mDrawDoneMethod == UNK_METHOD_0) {
GXDrawDone();
JUTVideo::dummyNoDrawWait();
} else {
JUTVideo::drawDoneStart();
}
if (mDrawDoneMethod == UNK_METHOD_0) {
callDirectDraw();
}
}
int cur_xfb_index = xfbMng->getDrawingXfbIndex();
xfbMng->setDrawnXfbIndex(cur_xfb_index);
xfbMng->setDrawingXfbIndex(cur_xfb_index >= 0 ? cur_xfb_index ^ 1 : 0);
} else {
clearEfb(JUtility::TColor(0, 0, 0, 0xff));
if (xfbMng->getDrawingXfbIndex() < 0) {
xfbMng->setDrawingXfbIndex(0);
}
}
}
void JFWDisplay::exchangeXfb_triple() {
JUTXfb* xfbMng = JUTXfb::getManager();
if (xfbMng->getDrawingXfbIndex() >= 0) {
callDirectDraw();
}
xfbMng->setDrawnXfbIndex(xfbMng->getDrawingXfbIndex());
s16 drawing_idx = xfbMng->getDrawingXfbIndex() + 1;
do {
if (drawing_idx >= 3 || drawing_idx < 0) {
drawing_idx = 0;
}
} while (drawing_idx == xfbMng->getDisplayingXfbIndex());
xfbMng->setDrawingXfbIndex(drawing_idx);
}
void JFWDisplay::copyXfb_triple() {
JUTXfb* xfbMng = JUTXfb::getManager();
if (xfbMng->getDrawingXfbIndex() >= 0) {
prepareCopyDisp();
GXCopyDisp(xfbMng->getDrawingXfb(), GX_TRUE);
GXPixModeSync();
}
}
void JFWDisplay::preGX() {
GXInvalidateTexAll();
GXInvalidateVtxCache();
if (mRMode->aa) {
GXSetPixelFmt(GX_PF_RGB565_Z16, GX_ZC_LINEAR);
GXSetDither(GX_ENABLE);
} else {
if (mEnableAlpha) {
GXSetPixelFmt(GX_PF_RGBA6_Z24, GX_ZC_LINEAR);
GXSetDither(GX_ENABLE);
} else {
GXSetPixelFmt(GX_PF_RGB8_Z24, GX_ZC_LINEAR);
GXSetDither(GX_DISABLE);
}
}
}
void JFWDisplay::endGX() {
u32 width = JUTVideo::getManager()->getFbWidth();
u32 height = JUTVideo::getManager()->getEfbHeight();
J2DOrthoGraph ortho(0.0f, 0.0f, width, height, -1.0f, 1.0f);
if (mFader != nullptr) {
ortho.setPort();
mFader->control();
}
JUTDbPrint::getManager()->flush();
if (JUTConsoleManager::getManager() != nullptr) {
JUTConsoleManager::getManager()->draw();
}
ortho.setPort();
JUTProcBar::getManager()->draw();
if (mDrawDoneMethod != UNK_METHOD_0 || JUTXfb::getManager()->getBufferNum() == 1) {
JUTAssertion::flushMessage_dbPrint();
}
GXFlush();
}
void JFWDisplay::beginRender() {
JUTProcBar::getManager()->wholeLoopEnd();
JUTProcBar::getManager()->wholeLoopStart();
JUTProcBar::getManager()->idleStart();
waitForTick(mTickRate, mFrameRate);
JUTVideo::getManager()->waitRetraceIfNeed();
u32 tick = OSGetTick();
mFrameTime = tick - mStartTick;
mStartTick = tick;
mVideoFrameTime = mStartTick - JUTVideo::getVideoLastTick();
JUTProcBar::getManager()->idleEnd();
JUTProcBar::getManager()->gpStart();
JUTXfb* xfbMgr = JUTXfb::getManager();
switch (xfbMgr->getBufferNum()) {
case 1:
if (xfbMgr->getSDrawingFlag() != 2) {
xfbMgr->setSDrawingFlag(1);
clearEfb(JUtility::TColor(0, 0, 0, 0xff));
} else {
xfbMgr->setSDrawingFlag(1);
}
xfbMgr->setDrawingXfbIndex(mDrawingXfbNo);
break;
case 2:
exchangeXfb_double();
break;
case 3:
exchangeXfb_triple();
break;
default:
break;
}
preGX();
}
void JFWDisplay::endRender() {
endGX();
switch (JUTXfb::getManager()->getBufferNum()) {
case 1:
drawendXfb_single();
case 2:
break;
case 3:
copyXfb_triple();
default:
break;
}
JUTProcBar::getManager()->cpuStart();
calcCombinationRatio();
}
void JFWDisplay::endFrame() {
JUTProcBar::getManager()->cpuEnd();
JUTProcBar::getManager()->gpWaitStart();
switch (JUTXfb::getManager()->getBufferNum()) {
case 1:
break;
case 2:
JFWDrawDoneAlarm();
GXFlush();
break;
case 3:
JFWDrawDoneAlarm();
GXFlush();
break;
default:
break;
}
JUTProcBar::getManager()->gpWaitEnd();
JUTProcBar::getManager()->gpEnd();
static u32 prevFrame = VIGetRetraceCount();
u32 retrace_cnt = VIGetRetraceCount();
JUTProcBar::getManager()->setCostFrame(retrace_cnt - prevFrame);
prevFrame = retrace_cnt;
}
void JFWDisplay::waitBlanking(int p1) {
while (p1-- > 0) {
waitForTick(mTickRate, mFrameRate);
}
}
void waitForTick(u32 p1, u16 p2) {
if (p1 != 0) {
static s64 nextTick = OSGetTime();
s64 time = OSGetTime();
while (time < nextTick) {
JFWDisplay::getManager()->threadSleep((nextTick - time));
time = OSGetTime();
}
nextTick = time + p1;
} else {
static u32 nextCount = VIGetRetraceCount();
u32 uVar1 = (p2 == 0) ? 1 : p2;
OSMessage msg;
do {
if (!OSReceiveMessage(JUTVideo::getManager()->getMessageQueue(), &msg, OS_MESSAGE_BLOCK)) {
msg = 0;
}
} while (((int)msg - (int)nextCount) < 0);
nextCount = (int)msg + uVar1;
}
}
void JFWThreadAlarmHandler(OSAlarm* p_alarm, OSContext* p_ctx) {
JFWAlarm* alarm = static_cast<JFWAlarm*>(p_alarm);
OSResumeThread(alarm->getThread());
}
void JFWDisplay::threadSleep(s64 time) {
JFWAlarm alarm;
alarm.createAlarm();
alarm.setThread(OSGetCurrentThread());
s32 status = OSDisableInterrupts();
OSSetAlarm(&alarm, time, JFWThreadAlarmHandler);
OSSuspendThread(alarm.getThread());
OSRestoreInterrupts(status);
}
static GXTexObj clear_z_tobj;
static u8 clear_z_TX[]
__attribute__((aligned(32))) = { 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00,
0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff,
0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
void* JFWDisplay::changeToSingleXfb(int index) {
JUTXfb* xfb = JUTXfb::getManager();
s16 xfbNo = !index ? 1 : 0;
// Check if xfb is single buffered
if (xfb->getBufferNum() != 2) {
return nullptr;
}
if (mIsSingleXfb) {
return nullptr;
}
VIWaitForRetrace();
if (xfbNo != xfb->getDisplayingXfbIndex()) {
u32 xfbSize = xfb->accumeXfbSize();
DCInvalidateRange(xfb->getDrawingXfb(), xfbSize);
memcpy(xfb->getDrawingXfb(), xfb->getDisplayingXfb(), xfbSize);
DCStoreRange(xfb->getDrawingXfb(), xfbSize);
xfb->setDrawnXfbIndex(xfb->getDrawingXfbIndex());
VISetNextFrameBuffer(xfb->getDrawingXfb());
VIFlush();
VIWaitForRetrace();
}
xfb->setSDrawingFlag(99);
xfb->setBufferNum(1);
mDrawingXfbNo = xfbNo;
mIsSingleXfb = true;
return xfb->getXfb(index);
}
void* JFWDisplay::changeToDoubleXfb() {
JUTXfb* xfb = JUTXfb::getManager();
// Check if xfb is not single buffered already
if (!mIsSingleXfb) {
return nullptr;
}
VIWaitForRetrace();
if (xfb->getSDrawingFlag() != 0) {
VIWaitForRetrace();
}
s16 xfbNo = !mDrawingXfbNo ? 1 : 0;
xfb->setDrawnXfbIndex(mDrawingXfbNo);
xfb->setDisplayingXfbIndex(xfbNo);
xfb->setDrawingXfbIndex(xfbNo);
xfb->setBufferNum(2);
mIsSingleXfb = false;
return xfb->getXfb(xfbNo);
}
void JFWDisplay::clearEfb_init() {
GXInitTexObj(&clear_z_tobj, &clear_z_TX, 4, 4, GX_TF_Z24X8, GX_REPEAT, GX_REPEAT, GX_FALSE);
GXInitTexObjLOD(&clear_z_tobj, GX_NEAR, GX_NEAR, 0.0f, 0.0f, 0.0f, GX_FALSE, GX_FALSE, GX_ANISO_1);
}
void JFWDisplay::clearEfb(GXColor color) {
Mtx44 mtx;
u16 height = mRMode->efbHeight;
u16 width = mRMode->fbWidth;
C_MTXOrtho(mtx, 0.0f, height, 0.0f, width, 0.0f, 1.0f);
GXSetProjection(mtx, GX_ORTHOGRAPHIC);
GXSetViewport(0.0f, 0.0f, width, height, 0.0f, 1.0f);
GXSetScissor(0, 0, width, height);
GXLoadPosMtxImm(e_mtx, GX_PNMTX0);
GXSetCurrentMtx(0);
GXClearVtxDesc();
GXSetVtxDesc(GX_VA_POS, GX_DIRECT);
GXSetVtxDesc(GX_VA_TEX0, GX_DIRECT);
GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_CLR_RGB, GX_RGBX8, 0);
GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_CLR_RGBA, GX_RGB565, 0);
GXSetNumChans(0);
GXSetChanCtrl(GX_COLOR0A0, GX_DISABLE, GX_SRC_REG, GX_SRC_REG, GX_LIGHT_NULL, GX_DF_NONE, GX_AF_NONE);
GXSetChanCtrl(GX_COLOR1A1, GX_DISABLE, GX_SRC_REG, GX_SRC_REG, GX_LIGHT_NULL, GX_DF_NONE, GX_AF_NONE);
GXSetNumTexGens(1);
GXSetTexCoordGen2(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, 60, GX_DISABLE, 125);
GXLoadTexObj(&clear_z_tobj, GX_TEXMAP0);
GXSetNumTevStages(1);
GXSetTevColor(GX_TEVREG0, color);
GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR_NULL);
GXSetTevColorIn(GX_TEVSTAGE0, GX_CC_ZERO, GX_CC_ZERO, GX_CC_ZERO, GX_CC_C0);
GXSetTevColorOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_ENABLE, GX_TEVPREV);
GXSetTevAlphaIn(GX_TEVSTAGE0, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_A0);
GXSetTevAlphaOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_ENABLE, GX_TEVPREV);
GXSetAlphaCompare(GX_ALWAYS, 0, GX_AOP_OR, GX_ALWAYS, 0);
GXSetZTexture(GX_ZT_REPLACE, GX_TF_Z24X8, 0);
GXSetZCompLoc(GX_DISABLE);
GXSetBlendMode(GX_BM_NONE, GX_BL_ZERO, GX_BL_ZERO, GX_LO_NOOP);
if (mEnableAlpha) {
GXSetAlphaUpdate(GX_ENABLE);
GXSetDstAlpha(GX_ENABLE, 0);
}
GXSetZMode(GX_ENABLE, GX_ALWAYS, GX_ENABLE);
GXSetCullMode(GX_CULL_BACK);
GXBegin(GX_QUADS, GX_VTXFMT0, 4);
GXPosition2u16(0, 0);
GXTexCoord2u8(0, 0);
GXPosition2u16(0 + width, 0);
GXTexCoord2u8(1, 0);
GXPosition2u16(0 + width, 0 + height);
GXTexCoord2u8(1, 1);
GXPosition2u16(0, 0 + height);
GXTexCoord2u8(0, 1);
GXEnd();
GXSetZTexture(GX_ZT_DISABLE, GX_TF_Z24X8, 0);
GXSetZCompLoc(GX_ENABLE);
if (mEnableAlpha) {
GXSetDstAlpha(GX_DISABLE, 0);
}
}
void JFWDisplay::calcCombinationRatio() {
u32 vidInterval = JUTVideo::getVideoInterval();
s32 unk30 = mFrameTime * 2;
s32 i = vidInterval;
for (; i < unk30; i += vidInterval) {}
s32 tmp = (i - unk30) - mVideoFrameTime;
if (tmp < 0) {
tmp += vidInterval;
}
mCombinationRatio = (f32)tmp / (f32)mFrameTime;
if (mCombinationRatio > 1.0f) {
mCombinationRatio = 1.0f;
}
}
void JFWGXAbortAlarmHandler(OSAlarm* param_0, OSContext* param_1) {
diagnoseGpHang();
GXAbortFrame();
GXSetDrawDone();
}
void diagnoseGpHang() {
u32 xfTop0, xfBot0, suRdy0, r0Rdy0;
u32 xfTop1, xfBot1, suRdy1, r0Rdy1;
u32 xfTopD, xfBotD, suRdyD, r0RdyD;
GXBool readIdle, cmdIdle, junk;
GXReadXfRasMetric(&xfBot0, &xfTop0, &r0Rdy0, &suRdy0);
GXReadXfRasMetric(&xfBot1, &xfTop1, &r0Rdy1, &suRdy1);
xfTopD = (xfTop1 - xfTop0) == 0;
xfBotD = (xfBot1 - xfBot0) == 0;
suRdyD = (suRdy1 - suRdy0) > 0;
r0RdyD = (r0Rdy1 - r0Rdy0) > 0;
GXGetGPStatus(&junk, &junk, &readIdle, &cmdIdle, &junk);
OSReport("GP status %d%d%d%d%d%d --> ", readIdle, cmdIdle, xfTopD, xfBotD, suRdyD, r0RdyD);
if (!xfBotD && suRdyD)
OSReport("GP hang due to XF stall bug.\n");
else if (!xfTopD && xfBotD && suRdyD)
OSReport("GP hang due to unterminated primitive.\n");
else if (!cmdIdle && xfTopD && xfBotD && suRdyD)
OSReport("GP hang due to illegal instruction.\n");
else if (readIdle && cmdIdle && xfTopD && xfBotD && suRdyD && r0RdyD)
OSReport("GP appears to be not hung (waiting for input).\n");
else
OSReport("GP is in unknown state.\n");
}
@@ -0,0 +1,86 @@
#include "dolphin/dvd.h"
#include "dolphin/gx.h"
#include "dolphin/os.h"
#include "JSystem/JKernel/JKRAram.h"
#include "JSystem/JKernel/JKRHeap.h"
#include "JSystem/JKernel/JKRExpHeap.h"
#include "JSystem/JKernel/JKRThread.h"
#include "JSystem/JUtility/JUTConsole.h"
#include "JSystem/JUtility/JUTAssertion.h"
#include "JSystem/JUtility/JUTDbPrint.h"
#include "JSystem/JUtility/JUTDirectPrint.h"
#include "JSystem/JUtility/JUTException.h"
#include "JSystem/JUtility/JUTFont.h"
#include "JSystem/JUtility/JUTGamePad.h"
#include "JSystem/JUtility/JUTGraphFifo.h"
#include "JSystem/JUtility/JUTVideo.h"
#include "JSystem/JFramework/JFWSystem.h"
int JFWSystem::CSetUpParam::maxStdHeaps = 2;
u32 JFWSystem::CSetUpParam::sysHeapSize = 0x400000;
u32 JFWSystem::CSetUpParam::fifoBufSize = 0x40000;
u32 JFWSystem::CSetUpParam::aramAudioBufSize = 0x800000;
u32 JFWSystem::CSetUpParam::aramGraphBufSize = 0x600000;
s32 JFWSystem::CSetUpParam::streamPriority = 8;
s32 JFWSystem::CSetUpParam::decompPriority = 7;
s32 JFWSystem::CSetUpParam::aPiecePriority = 6;
const ResFONT* JFWSystem::CSetUpParam::systemFontRes = &JUTResFONT_Ascfont_fix12;
const _GXRenderModeObj* JFWSystem::CSetUpParam::renderMode = &GXNtsc480IntDf;
u32 JFWSystem::CSetUpParam::exConsoleBufferSize = 0x24F8;
JKRHeap* JFWSystem::rootHeap;
JKRHeap* JFWSystem::systemHeap;
JKRThread* JFWSystem::mainThread;
JUTDbPrint* JFWSystem::debugPrint;
JUTFont* JFWSystem::systemFont;
JUTConsoleManager* JFWSystem::systemConsoleManager;
JUTConsole* JFWSystem::systemConsole;
bool JFWSystem::sInitCalled;
void JFWSystem::firstInit() {
JUT_ASSERT(rootHeap == 0);
OSInit();
DVDInit();
rootHeap = JKRExpHeap::createRoot(CSetUpParam::maxStdHeaps, false);
systemHeap = JKRExpHeap::create(CSetUpParam::sysHeapSize, rootHeap, false);
}
void JFWSystem::init() {
JUT_ASSERT(sInitCalled == false);
if (rootHeap == 0)
firstInit();
sInitCalled = true;
JKRAram::create(CSetUpParam::aramAudioBufSize, CSetUpParam::aramGraphBufSize, CSetUpParam::streamPriority,
CSetUpParam::decompPriority, CSetUpParam::aPiecePriority);
mainThread = new JKRThread(OSGetCurrentThread(), 4);
JUTVideo::createManager(CSetUpParam::renderMode);
JUTCreateFifo(CSetUpParam::fifoBufSize);
JUTGamePad::init();
JUTDirectPrint* directPrint = JUTDirectPrint::start();
JUTAssertion::create();
JUTException::create(directPrint);
systemFont = new JUTResFont(CSetUpParam::systemFontRes, nullptr);
debugPrint = JUTDbPrint::start(nullptr, nullptr);
debugPrint->changeFont(systemFont);
systemConsoleManager = JUTConsoleManager::createManager(nullptr);
systemConsole = JUTConsole::create(60, 200, nullptr);
systemConsole->setFont(systemFont);
if (CSetUpParam::renderMode->efbHeight < 300) {
systemConsole->setFontSize(systemFont->getWidth() * 0.85f, systemFont->getHeight() * 0.5f);
systemConsole->setPosition(20, 25);
} else {
systemConsole->setFontSize(systemFont->getWidth() * 0.85f, systemFont->getHeight());
systemConsole->setPosition(20, 50);
}
systemConsole->setHeight(25);
systemConsole->setVisible(false);
systemConsole->setOutput(JUTConsole::OUTPUT_OSREPORT | JUTConsole::OUTPUT_CONSOLE);
JUTSetReportConsole(systemConsole);
JUTSetWarningConsole(systemConsole);
void* mem = systemHeap->alloc(CSetUpParam::exConsoleBufferSize, 4);
JUTException::createConsole(mem, CSetUpParam::exConsoleBufferSize);
}
+4 -12
View File
@@ -28,7 +28,6 @@ TNodeLinkList::iterator TNodeLinkList::erase(iterator it, iterator itEnd) {
}
TNodeLinkList::iterator TNodeLinkList::erase(TNodeLinkList::iterator it) {
#line 102
JUT_ASSERT(it.p_!=&oNode_);
iterator itNext = it;
@@ -90,7 +89,6 @@ void TNodeLinkList::splice(TNodeLinkList::iterator it, TNodeLinkList& rSrc, TNod
}
void TNodeLinkList::splice(iterator it, TNodeLinkList& rSrc) {
#line 146
JUT_ASSERT(this!=&rSrc);
this->splice(it, rSrc, rSrc.begin(), rSrc.end());
JUT_ASSERT(rSrc.empty());
@@ -104,7 +102,6 @@ TNodeLinkList::iterator TNodeLinkList::Find(const TLinkListNode* node) {
#define NULL 0
TNodeLinkList::iterator TNodeLinkList::Insert(iterator it, TLinkListNode* p) {
#line 300
JUT_ASSERT(p!=0);
TLinkListNode* pIt = it.p_;
JUT_ASSERT(pIt!=0);
@@ -128,7 +125,6 @@ TNodeLinkList::iterator TNodeLinkList::Insert(iterator it, TLinkListNode* p) {
#define NULL (void*)0;
TNodeLinkList::iterator TNodeLinkList::Erase(TLinkListNode* p) {
#line 325
JUT_ASSERT(!empty());
JUT_ASSERT(p!=0);
JUT_ASSERT(p!=&oNode_);
@@ -151,21 +147,18 @@ bool TNodeLinkList::Confirm() const {
u32 u = 0;
const_iterator itEnd = this->end();
#line 357
JGADGET_EXITWARN(itEnd.p_==&oNode_);
const_iterator it = this->begin();
JGADGET_EXITWARN(it.p_==oNode_.pNext_); // #line 359
JGADGET_EXITWARN(it.p_==oNode_.pNext_);
for (; it != itEnd; ++it, ++u) {
JGADGET_EXITWARN(u<size()); // #line 362
JGADGET_EXITWARN(u<size());
const TLinkListNode* pIt = it.p_;
JUT_ASSERT(pIt!=0); // #line 364
#line 365
JUT_ASSERT(pIt!=0);
JGADGET_EXITWARN(pIt->pNext_->pPrev_==pIt);
JGADGET_EXITWARN(pIt->pPrev_->pNext_==pIt); // #line 366
JGADGET_EXITWARN(pIt->pPrev_->pNext_==pIt);
}
#line 368
JGADGET_EXITWARN(it.p_==&oNode_);
JGADGET_EXITWARN(u==size());
return true;
@@ -183,7 +176,6 @@ bool TNodeLinkList::Confirm_iterator(const_iterator it) const {
++itBegin;
}
#line 383
JGADGET_EXITWARN(it==itEnd);
return true;
+361 -381
View File
@@ -11,18 +11,17 @@ JSUList<JKRAMCommand> JKRAram::sAramCommandList;
JKRAram* JKRAram::sAramObject;
u32 JKRAram::sSZSBufferSize = 0x400;
JKRAram* JKRAram::create(u32 aram_audio_buffer_size, u32 aram_audio_graph_size,
s32 streamPriority, s32 decomp_priority,
s32 piece_priority) {
if (!sAramObject) {
sAramObject = new (JKRGetSystemHeap(), 0)
JKRAram(aram_audio_buffer_size, aram_audio_graph_size, piece_priority);
}
JKRAram* JKRAram::create(u32 aram_audio_buffer_size, u32 aram_audio_graph_size, s32 streamPriority, s32 decomp_priority,
s32 piece_priority) {
if (!sAramObject) {
sAramObject =
new (JKRGetSystemHeap(), 0) JKRAram(aram_audio_buffer_size, aram_audio_graph_size, piece_priority);
}
JKRCreateAramStreamManager(streamPriority);
JKRCreateDecompManager(decomp_priority);
sAramObject->resume();
return sAramObject;
JKRCreateAramStreamManager(streamPriority);
JKRCreateDecompManager(decomp_priority);
sAramObject->resume();
return sAramObject;
}
OSMessage JKRAram::sMessageBuffer[4] = {
@@ -34,269 +33,257 @@ OSMessage JKRAram::sMessageBuffer[4] = {
OSMessageQueue JKRAram::sMessageQueue = { 0 };
JKRAram::JKRAram(u32 bufSize, u32 graphSize, s32 priority)
: JKRThread(0x4000, 0x10, priority) {
u32 aramBase = ARInit(mStackArray, ARRAY_COUNT(mStackArray));
ARQInit();
JKRAram::JKRAram(u32 bufSize, u32 graphSize, s32 priority) : JKRThread(0x4000, 0x10, priority) {
u32 aramBase = ARInit(mStackArray, ARRAY_COUNT(mStackArray));
ARQInit();
u32 aramSize = ARGetSize();
mAudioMemorySize = bufSize;
if (graphSize == 0xffffffff) {
mGraphMemorySize = aramSize - bufSize - aramBase;
mUserMemorySize = 0;
}
else {
mGraphMemorySize = graphSize;
mUserMemorySize = (aramSize - (bufSize + graphSize) - aramBase);
}
u32 aramSize = ARGetSize();
mAudioMemorySize = bufSize;
if (graphSize == 0xffffffff) {
mGraphMemorySize = aramSize - bufSize - aramBase;
mUserMemorySize = 0;
} else {
mGraphMemorySize = graphSize;
mUserMemorySize = (aramSize - (bufSize + graphSize) - aramBase);
}
mAudioMemoryPtr = ARAlloc(mAudioMemorySize);
mGraphMemoryPtr = ARAlloc(mGraphMemorySize);
mAudioMemoryPtr = ARAlloc(mAudioMemorySize);
mGraphMemoryPtr = ARAlloc(mGraphMemorySize);
if (mUserMemorySize != 0) { // ternary?
mUserMemoryPtr = ARAlloc(mUserMemorySize);
}
else {
mUserMemoryPtr = nullptr;
}
if (mUserMemorySize != 0) { // ternary?
mUserMemoryPtr = ARAlloc(mUserMemorySize);
} else {
mUserMemoryPtr = nullptr;
}
mAramHeap = new (JKRHeap::getSystemHeap(), 0)
JKRAramHeap(mGraphMemoryPtr, mGraphMemorySize);
mAramHeap = new (JKRHeap::getSystemHeap(), 0) JKRAramHeap(mGraphMemoryPtr, mGraphMemorySize);
}
JKRAram::~JKRAram() {
sAramObject = nullptr;
if (mAramHeap) delete mAramHeap;
sAramObject = nullptr;
if (mAramHeap)
delete mAramHeap;
}
void* JKRAram::run() {
int result;
JKRAMCommand* command;
JKRAramCommand* message;
OSInitMessageQueue(&sMessageQueue, sMessageBuffer, 4);
do {
OSReceiveMessage(&sMessageQueue, (OSMessage*)&message, OS_MESSAGE_BLOCK);
result = message->mActive;
command = (JKRAMCommand*)message->mArg;
delete message;
int result;
JKRAMCommand* command;
JKRAramCommand* message;
OSInitMessageQueue(&sMessageQueue, sMessageBuffer, 4);
do {
OSReceiveMessage(&sMessageQueue, (OSMessage*)&message, OS_MESSAGE_BLOCK);
result = message->mActive;
command = (JKRAMCommand*)message->mArg;
delete message;
switch (result) {
case 1:
JKRAramPiece::startDMA(command);
break;
}
} while (true);
switch (result) {
case 1:
JKRAramPiece::startDMA(command);
break;
}
} while (true);
}
bool JKRAram::checkOkAddress(u8* addr, u32 size, JKRAramBlock* block,
u32 blockSize) {
if (!IS_ALIGNED((u32)addr, 0x20) && !IS_ALIGNED(size, 0x20)) {
JPANIC(225, ":::address not 32Byte aligned.");
return false;
}
if (block) {
if (!IS_ALIGNED(block->getAddress() + blockSize, 0x20)) {
JPANIC(234, ":::address not 32Byte aligned.");
return false;
bool JKRAram::checkOkAddress(u8* addr, u32 size, JKRAramBlock* block, u32 blockSize) {
if (!IS_ALIGNED((u32)addr, 0x20) && !IS_ALIGNED(size, 0x20)) {
JPANIC(225, ":::address not 32Byte aligned.");
return false;
}
}
return true;
if (block) {
if (!IS_ALIGNED(block->getAddress() + blockSize, 0x20)) {
JPANIC(234, ":::address not 32Byte aligned.");
return false;
}
}
return true;
}
void JKRAram::changeGroupIdIfNeed(u8* data, int groupId) {
JKRHeap* currentHeap = JKRGetCurrentHeap();
if (currentHeap->getHeapType() == 'EXPH' && groupId >= 0) {
JKRExpHeap::CMemBlock* block = (JKRExpHeap::CMemBlock*)(data + -0x10);
block->newGroupId(groupId);
}
JKRHeap* currentHeap = JKRGetCurrentHeap();
if (currentHeap->getHeapType() == 'EXPH' && groupId >= 0) {
JKRExpHeap::CMemBlock* block = (JKRExpHeap::CMemBlock*)(data + -0x10);
block->newGroupId(groupId);
}
}
JKRAramBlock* JKRAram::mainRamToAram(u8* buf, u32 address, u32 alignedSize,
JKRExpandSwitch expandSwitch, u32 fileSize,
JKRHeap* heap, int id) {
JKRAramBlock* block = nullptr;
checkOkAddress(buf, address, nullptr, 0);
if (expandSwitch == EXPAND_SWITCH_DECOMPRESS) {
expandSwitch = (JKRCheckCompressed(buf) == JKRCOMPRESSION_NONE)
? EXPAND_SWITCH_DEFAULT
: EXPAND_SWITCH_DECOMPRESS;
}
if (expandSwitch == EXPAND_SWITCH_DECOMPRESS) {
u32 expandSize = JKRCheckCompressed(buf) != JKRCOMPRESSION_NONE
? JKRDecompExpandSize(buf)
: 0;
if (fileSize == 0 || fileSize > expandSize) {
fileSize = expandSize;
JKRAramBlock* JKRAram::mainRamToAram(u8* buf, u32 address, u32 alignedSize, JKRExpandSwitch expandSwitch, u32 fileSize,
JKRHeap* heap, int id) {
JKRAramBlock* block = nullptr;
checkOkAddress(buf, address, nullptr, 0);
if (expandSwitch == EXPAND_SWITCH_DECOMPRESS) {
expandSwitch =
(JKRCheckCompressed(buf) == JKRCOMPRESSION_NONE) ? EXPAND_SWITCH_DEFAULT : EXPAND_SWITCH_DECOMPRESS;
}
if (address == 0) {
block = JKRAllocFromAram(fileSize, JKRAramHeap::Head);
if (block == nullptr) return nullptr;
if (expandSwitch == EXPAND_SWITCH_DECOMPRESS) {
u32 expandSize = JKRCheckCompressed(buf) != JKRCOMPRESSION_NONE ? JKRDecompExpandSize(buf) : 0;
if (fileSize == 0 || fileSize > expandSize) {
fileSize = expandSize;
}
if (address == 0) {
block = JKRAllocFromAram(fileSize, JKRAramHeap::Head);
if (block == nullptr)
return nullptr;
block->newGroupID(decideAramGroupId(id));
address = block->getAddress();
block->newGroupID(decideAramGroupId(id));
address = block->getAddress();
}
if (alignedSize == 0 || alignedSize > expandSize)
alignedSize = expandSize;
if (fileSize > alignedSize)
fileSize = alignedSize;
void* allocatedMem = JKRAllocFromHeap(heap, fileSize, -32);
if (allocatedMem == nullptr) {
if (block != nullptr) {
delete block;
}
block = nullptr;
} else {
JKRDecompress(buf, (u8*)allocatedMem, fileSize, 0);
JKRAramPcs(0, (u32)allocatedMem, address, alignedSize, block);
JKRFreeToHeap(heap, allocatedMem);
block = block == nullptr ? (JKRAramBlock*)-1 : block;
}
} else {
if (address == 0) {
block = JKRAllocFromAram(alignedSize, JKRAramHeap::Head);
block->newGroupID(decideAramGroupId(id));
if (block == nullptr)
return nullptr;
address = block->getAddress();
}
JKRAramPcs(0, (u32)buf, address, alignedSize, block);
block = block == nullptr ? (JKRAramBlock*)-1 : block;
}
if (alignedSize == 0 || alignedSize > expandSize) alignedSize = expandSize;
if (fileSize > alignedSize) fileSize = alignedSize;
void* allocatedMem = JKRAllocFromHeap(heap, fileSize, -32);
if (allocatedMem == nullptr) {
if (block != nullptr) {
delete block;
}
block = nullptr;
}
else {
JKRDecompress(buf, (u8*)allocatedMem, fileSize, 0);
JKRAramPcs(0, (u32)allocatedMem, address, alignedSize, block);
JKRFreeToHeap(heap, allocatedMem);
block = block == nullptr ? (JKRAramBlock*)-1 : block;
}
}
else {
if (address == 0) {
block = JKRAllocFromAram(alignedSize, JKRAramHeap::Head);
block->newGroupID(decideAramGroupId(id));
if (block == nullptr) return nullptr;
address = block->getAddress();
}
JKRAramPcs(0, (u32)buf, address, alignedSize, block);
block = block == nullptr ? (JKRAramBlock*)-1 : block;
}
return block;
return block;
}
JKRAramBlock* JKRAram::mainRamToAram(u8* buf, JKRAramBlock* block,
u32 alignedSize,
JKRExpandSwitch expandSwitch, u32 fileSize,
JKRHeap* heap, int id) {
checkOkAddress(buf, 0, block, 0);
JKRAramBlock* JKRAram::mainRamToAram(u8* buf, JKRAramBlock* block, u32 alignedSize, JKRExpandSwitch expandSwitch,
u32 fileSize, JKRHeap* heap, int id) {
checkOkAddress(buf, 0, block, 0);
if (block == nullptr) {
return mainRamToAram(buf, (u32)0, alignedSize, expandSwitch, fileSize, heap,
id);
}
if (block == nullptr) {
return mainRamToAram(buf, (u32)0, alignedSize, expandSwitch, fileSize, heap, id);
}
u32 blockSize = block->getSize();
u32 blockSize = block->getSize();
if (expandSwitch == EXPAND_SWITCH_DECOMPRESS) {
fileSize = fileSize >= blockSize ? blockSize : fileSize;
}
if (expandSwitch == EXPAND_SWITCH_DECOMPRESS) {
fileSize = fileSize >= blockSize ? blockSize : fileSize;
}
alignedSize = alignedSize > blockSize ? blockSize : alignedSize;
alignedSize = alignedSize > blockSize ? blockSize : alignedSize;
return mainRamToAram(buf, block->getAddress(), alignedSize, expandSwitch,
fileSize, heap, id);
return mainRamToAram(buf, block->getAddress(), alignedSize, expandSwitch, fileSize, heap, id);
}
// TODO: figure out name of parameter 5
u8* JKRAram::aramToMainRam(u32 address, u8* buf, u32 srcSize,
JKRExpandSwitch expandSwitch, u32 p5, JKRHeap* heap,
int id, u32* pSize) {
int compression = JKRCOMPRESSION_NONE;
if (pSize) *pSize = 0;
u8* JKRAram::aramToMainRam(u32 address, u8* buf, u32 srcSize, JKRExpandSwitch expandSwitch, u32 p5, JKRHeap* heap,
int id, u32* pSize) {
int compression = JKRCOMPRESSION_NONE;
if (pSize)
*pSize = 0;
checkOkAddress(buf, address, nullptr, 0);
checkOkAddress(buf, address, nullptr, 0);
u32 expandSize;
if (expandSwitch == EXPAND_SWITCH_DECOMPRESS) {
u8 buffer[64];
u8* bufPtr = (u8*)ALIGN_NEXT((u32)buffer, 32);
JKRAramPcs(1, address, (u32)bufPtr, sizeof(buffer) / 2,
nullptr); // probably change sizeof(buffer) / 2 to 32
compression = JKRCheckCompressed(bufPtr);
expandSize = JKRDecompExpandSize(bufPtr);
}
if (compression == JKRCOMPRESSION_YAZ0) // SZS
{
if (p5 != 0 && p5 < expandSize) expandSize = p5;
if (buf == nullptr) buf = (u8*)JKRAllocFromHeap(heap, expandSize, 32);
if (buf == nullptr)
return nullptr;
else {
changeGroupIdIfNeed(buf, id);
JKRDecompressFromAramToMainRam(address, buf, srcSize, expandSize, 0);
if (pSize) {
*pSize = expandSize;
}
return buf;
u32 expandSize;
if (expandSwitch == EXPAND_SWITCH_DECOMPRESS) {
u8 buffer[64];
u8* bufPtr = (u8*)ALIGN_NEXT((u32)buffer, 32);
JKRAramPcs(1, address, (u32)bufPtr, sizeof(buffer) / 2,
nullptr); // probably change sizeof(buffer) / 2 to 32
compression = JKRCheckCompressed(bufPtr);
expandSize = JKRDecompExpandSize(bufPtr);
}
}
else if (compression == JKRCOMPRESSION_YAY0) // SZP
{
u8* szpSpace = (u8*)JKRAllocFromHeap(heap, srcSize, -32);
if (szpSpace == nullptr) {
return nullptr;
}
else {
JKRAramPcs(1, address, (u32)szpSpace, srcSize, nullptr);
if (p5 != 0 && p5 < expandSize) expandSize = p5;
u8* szpBuffer =
buf == nullptr ? (u8*)JKRAllocFromHeap(heap, expandSize, 32) : buf;
if (compression == JKRCOMPRESSION_YAZ0) // SZS
{
if (p5 != 0 && p5 < expandSize)
expandSize = p5;
if (szpBuffer == nullptr) {
JKRFree(szpSpace);
return nullptr;
}
else {
changeGroupIdIfNeed(szpBuffer, id);
JKRDecompress(szpSpace, szpBuffer, expandSize, 0);
JKRFreeToHeap(heap, szpSpace);
if (pSize) {
*pSize = expandSize;
if (buf == nullptr)
buf = (u8*)JKRAllocFromHeap(heap, expandSize, 32);
if (buf == nullptr)
return nullptr;
else {
changeGroupIdIfNeed(buf, id);
JKRDecompressFromAramToMainRam(address, buf, srcSize, expandSize, 0);
if (pSize) {
*pSize = expandSize;
}
return buf;
}
} else if (compression == JKRCOMPRESSION_YAY0) // SZP
{
u8* szpSpace = (u8*)JKRAllocFromHeap(heap, srcSize, -32);
if (szpSpace == nullptr) {
return nullptr;
} else {
JKRAramPcs(1, address, (u32)szpSpace, srcSize, nullptr);
if (p5 != 0 && p5 < expandSize)
expandSize = p5;
u8* szpBuffer = buf == nullptr ? (u8*)JKRAllocFromHeap(heap, expandSize, 32) : buf;
if (szpBuffer == nullptr) {
JKRFree(szpSpace);
return nullptr;
} else {
changeGroupIdIfNeed(szpBuffer, id);
JKRDecompress(szpSpace, szpBuffer, expandSize, 0);
JKRFreeToHeap(heap, szpSpace);
if (pSize) {
*pSize = expandSize;
}
return szpBuffer;
}
}
} else // Not compressed or ASR
{
if (buf == nullptr)
buf = (u8*)JKRAllocFromHeap(heap, srcSize, 32);
if (buf == nullptr) {
return nullptr;
} else {
changeGroupIdIfNeed(buf, id);
JKRAramPcs(1, address, (u32)buf, srcSize, nullptr);
if (pSize != nullptr) {
*pSize = srcSize;
}
return buf;
}
return szpBuffer;
}
}
}
else // Not compressed or ASR
{
if (buf == nullptr) buf = (u8*)JKRAllocFromHeap(heap, srcSize, 32);
if (buf == nullptr) {
return nullptr;
}
else {
changeGroupIdIfNeed(buf, id);
JKRAramPcs(1, address, (u32)buf, srcSize, nullptr);
if (pSize != nullptr) {
*pSize = srcSize;
}
return buf;
}
}
}
// TODO: figure out what p6 does
u8* JKRAram::aramToMainRam(JKRAramBlock* block, u8* buf, u32 bufSize,
u32 alignedBlockSize, JKRExpandSwitch expandSwitch,
u32 p6, JKRHeap* heap, int id, u32* pSize) {
int compression = JKRCOMPRESSION_NONE;
if (pSize) *pSize = 0;
u8* JKRAram::aramToMainRam(JKRAramBlock* block, u8* buf, u32 bufSize, u32 alignedBlockSize,
JKRExpandSwitch expandSwitch, u32 p6, JKRHeap* heap, int id, u32* pSize) {
int compression = JKRCOMPRESSION_NONE;
if (pSize)
*pSize = 0;
checkOkAddress(buf, 0, block, alignedBlockSize);
checkOkAddress(buf, 0, block, alignedBlockSize);
if (block == nullptr) {
JPANIC(667, ":::Bad Aram Block specified.\n");
}
if (block == nullptr) {
JPANIC(667, ":::Bad Aram Block specified.\n");
}
u32 freeSize = block->getSize();
u32 freeSize = block->getSize();
if (alignedBlockSize >= freeSize) return nullptr;
if (alignedBlockSize >= freeSize)
return nullptr;
bufSize = bufSize == 0 ? freeSize : bufSize;
bufSize = bufSize == 0 ? freeSize : bufSize;
if (alignedBlockSize + bufSize > freeSize) {
bufSize = freeSize - alignedBlockSize;
}
if (alignedBlockSize + bufSize > freeSize) {
bufSize = freeSize - alignedBlockSize;
}
return aramToMainRam(alignedBlockSize + block->getAddress(), buf, bufSize,
expandSwitch, p6, heap, id, pSize);
return aramToMainRam(alignedBlockSize + block->getAddress(), buf, bufSize, expandSwitch, p6, heap, id, pSize);
}
static OSMutex decompMutex;
@@ -322,188 +309,181 @@ static u8* nextSrcData(u8* current);
static int decompSZS_subroutine(u8* src, u8* dest);
void JKRAram::aramSync(JKRAMCommand*, int) {
// JUT_REPORT_MSG("bad aramSync\n");
// JUT_REPORT_MSG("bad aramSync\n");
}
int JKRDecompressFromAramToMainRam(u32 src, void* dst, u32 srcLength,
u32 dstLength, u32 offset) {
szpBuf = (u8*)JKRAllocFromSysHeap(SZP_BUFFERSIZE, 32);
int JKRDecompressFromAramToMainRam(u32 src, void* dst, u32 srcLength, u32 dstLength, u32 offset) {
szpBuf = (u8*)JKRAllocFromSysHeap(SZP_BUFFERSIZE, 32);
// JUT_ASSERT(szpBuf != 0);
JUT_ASSERT(szpBuf != 0);
szpEnd = szpBuf + SZP_BUFFERSIZE;
if (offset != 0) {
refBuf = (u8*)JKRAllocFromSysHeap(0x1120, 0);
// JUT_ASSERT(refBuf != 0);
refEnd = refBuf + 0x1120;
refCurrent = refBuf;
}
else {
refBuf = nullptr;
}
szpEnd = szpBuf + SZP_BUFFERSIZE;
if (offset != 0) {
refBuf = (u8*)JKRAllocFromSysHeap(0x1120, 0);
JUT_ASSERT(refBuf != 0);
refEnd = refBuf + 0x1120;
refCurrent = refBuf;
} else {
refBuf = nullptr;
}
srcAddress = src;
srcOffset = 0;
transLeft = (srcLength != 0) ? srcLength : -1;
fileOffset = offset;
readCount = 0;
maxDest = dstLength;
srcAddress = src;
srcOffset = 0;
transLeft = (srcLength != 0) ? srcLength : -1;
fileOffset = offset;
readCount = 0;
maxDest = dstLength;
decompSZS_subroutine(firstSrcData(), (u8*)dst);
JKRFree(szpBuf);
decompSZS_subroutine(firstSrcData(), (u8*)dst);
JKRFree(szpBuf);
if (refBuf) {
JKRFree(refBuf);
}
if (refBuf) {
JKRFree(refBuf);
}
return 0;
return 0;
}
int decompSZS_subroutine(u8* src, u8* dest) {
u8* endPtr;
s32 validBitCount = 0;
s32 currCodeByte = 0;
u8* endPtr;
s32 validBitCount = 0;
s32 currCodeByte = 0;
if (src[0] != 'Y' || src[1] != 'a' || src[2] != 'z' || src[3] != '0') {
return -1;
}
SYaz0Header* header = (SYaz0Header*)src;
endPtr = dest + (header->length - fileOffset);
if (endPtr > dest + maxDest) {
endPtr = dest + maxDest;
}
src += 0x10;
do {
if (validBitCount == 0) {
if ((src > srcLimit) && transLeft) {
src = nextSrcData(src);
}
currCodeByte = *src;
validBitCount = 8;
src++;
if (src[0] != 'Y' || src[1] != 'a' || src[2] != 'z' || src[3] != '0') {
return -1;
}
if (currCodeByte & 0x80) {
if (fileOffset != 0) {
if (readCount >= fileOffset) {
*dest = *src;
dest++;
if (dest == endPtr) {
break;
}
}
*(refCurrent++) = *src;
if (refCurrent == refEnd) {
refCurrent = refBuf;
}
src++;
}
else {
*dest = *src;
dest++;
src++;
if (dest == endPtr) {
break;
}
}
readCount++;
SYaz0Header* header = (SYaz0Header*)src;
endPtr = dest + (header->length - fileOffset);
if (endPtr > dest + maxDest) {
endPtr = dest + maxDest;
}
else {
u32 dist = src[1] | (src[0] & 0x0f) << 8;
s32 numBytes = src[0] >> 4;
src += 2;
u8* copySource;
if (fileOffset != 0) {
copySource = refCurrent - dist - 1;
if (copySource < refBuf) {
copySource += refEnd - refBuf;
}
}
else {
copySource = dest - dist - 1;
}
if (numBytes == 0) {
numBytes = *src + 0x12;
src += 1;
}
else {
numBytes += 2;
}
if (fileOffset != 0) {
do {
if (readCount >= fileOffset) {
*dest = *copySource;
dest++;
if (dest == endPtr) {
break;
src += 0x10;
do {
if (validBitCount == 0) {
if ((src > srcLimit) && transLeft) {
src = nextSrcData(src);
}
}
*(refCurrent++) = *copySource;
if (refCurrent == refEnd) {
refCurrent = refBuf;
}
copySource++;
if (copySource == refEnd) {
copySource = refBuf;
}
readCount++;
numBytes--;
} while (numBytes != 0);
}
else {
do {
*dest = *copySource;
dest++;
if (dest == endPtr) {
break;
}
readCount++;
numBytes--;
copySource++;
} while (numBytes != 0);
}
}
currCodeByte <<= 1;
validBitCount--;
} while (dest < endPtr);
return 0;
currCodeByte = *src;
validBitCount = 8;
src++;
}
if (currCodeByte & 0x80) {
if (fileOffset != 0) {
if (readCount >= fileOffset) {
*dest = *src;
dest++;
if (dest == endPtr) {
break;
}
}
*(refCurrent++) = *src;
if (refCurrent == refEnd) {
refCurrent = refBuf;
}
src++;
} else {
*dest = *src;
dest++;
src++;
if (dest == endPtr) {
break;
}
}
readCount++;
} else {
u32 dist = src[1] | (src[0] & 0x0f) << 8;
s32 numBytes = src[0] >> 4;
src += 2;
u8* copySource;
if (fileOffset != 0) {
copySource = refCurrent - dist - 1;
if (copySource < refBuf) {
copySource += refEnd - refBuf;
}
} else {
copySource = dest - dist - 1;
}
if (numBytes == 0) {
numBytes = *src + 0x12;
src += 1;
} else {
numBytes += 2;
}
if (fileOffset != 0) {
do {
if (readCount >= fileOffset) {
*dest = *copySource;
dest++;
if (dest == endPtr) {
break;
}
}
*(refCurrent++) = *copySource;
if (refCurrent == refEnd) {
refCurrent = refBuf;
}
copySource++;
if (copySource == refEnd) {
copySource = refBuf;
}
readCount++;
numBytes--;
} while (numBytes != 0);
} else {
do {
*dest = *copySource;
dest++;
if (dest == endPtr) {
break;
}
readCount++;
numBytes--;
copySource++;
} while (numBytes != 0);
}
}
currCodeByte <<= 1;
validBitCount--;
} while (dest < endPtr);
return 0;
}
static u8* firstSrcData() {
srcLimit = szpEnd - 0x19;
u8* buf = szpBuf;
u32 maxSize = (szpEnd - szpBuf);
u32 transSize = MIN(transLeft, maxSize);
srcLimit = szpEnd - 0x19;
u8* buf = szpBuf;
u32 maxSize = (szpEnd - szpBuf);
u32 transSize = MIN(transLeft, maxSize);
JKRAramPcs(1, srcAddress + srcOffset, (u32)buf, ALIGN_NEXT(transSize, 32),
nullptr);
JKRAramPcs(1, srcAddress + srcOffset, (u32)buf, ALIGN_NEXT(transSize, 32), nullptr);
srcOffset += transSize;
transLeft -= transSize;
srcOffset += transSize;
transLeft -= transSize;
return buf;
return buf;
}
u8* nextSrcData(u8* current) {
u8* dest;
u32 left = (u32)(szpEnd - current);
if (IS_NOT_ALIGNED(left, 0x20))
dest = szpBuf + 0x20 - (left & (0x20 - 1));
else
dest = szpBuf;
u8* dest;
u32 left = (u32)(szpEnd - current);
if (IS_NOT_ALIGNED(left, 0x20))
dest = szpBuf + 0x20 - (left & (0x20 - 1));
else
dest = szpBuf;
memcpy(dest, current, left);
u32 transSize = (u32)(szpEnd - (dest + left));
if (transSize > transLeft) transSize = transLeft;
// JUT_ASSERT(transSize > 0);
memcpy(dest, current, left);
u32 transSize = (u32)(szpEnd - (dest + left));
if (transSize > transLeft)
transSize = transLeft;
JUT_ASSERT(transSize > 0);
JKRAramPcs(1, (u32)(srcAddress + srcOffset), ((u32)dest + left),
ALIGN_NEXT(transSize, 0x20), nullptr);
srcOffset += transSize;
transLeft -= transSize;
JKRAramPcs(1, (u32)(srcAddress + srcOffset), ((u32)dest + left), ALIGN_NEXT(transSize, 0x20), nullptr);
srcOffset += transSize;
transLeft -= transSize;
if (transLeft == 0) srcLimit = (dest + left) + transSize;
if (transLeft == 0)
srcLimit = (dest + left) + transSize;
return dest;
return dest;
}
+229 -246
View File
@@ -9,303 +9,286 @@
#include "JSystem/JSystem.h"
#include "JSystem/JUtility/JUTAssertion.h"
JKRAramArchive::JKRAramArchive() : JKRArchive() {}
JKRAramArchive::JKRAramArchive() : JKRArchive() {
}
JKRAramArchive::JKRAramArchive(s32 entryNum, EMountDirection mountDirection) : JKRArchive(entryNum, MOUNT_ARAM) {
mMountDirection = mountDirection;
if (!open(entryNum)) {
return;
} else {
mVolumeType = 'RARC';
mVolumeName = &mStrTable[mDirectories->mOffset];
sVolumeList.prepend(&mFileLoaderLink);
mIsMounted = true;
}
}
JKRAramArchive::~JKRAramArchive() {
if (mIsMounted == true) {
if (mArcInfoBlock) {
SDIFileEntry* fileEntries = mFileEntries;
for (int i = 0; i < mArcInfoBlock->num_file_entries; i++) {
if (fileEntries->mData != nullptr) {
JKRFreeToHeap(mHeap, fileEntries->mData);
}
fileEntries++;
}
JKRFreeToHeap(mHeap, mArcInfoBlock);
mArcInfoBlock = nullptr;
}
if (mDvdFile) {
delete mDvdFile;
}
if (mBlock) {
delete mBlock;
}
sVolumeList.remove(&mFileLoaderLink);
mIsMounted = false;
}
}
void JKRAramArchive::fixedInit(s32 entryNum, EMountDirection direction) {
mIsMounted = false;
mMountDirection = direction;
mMountMode = 2;
mMountCount = 1;
_54 = 2;
mHeap = JKRGetCurrentHeap();
mEntryNum = entryNum;
if (sCurrentVolume)
return;
sCurrentVolume = this;
sCurrentDirID = 0;
}
bool JKRAramArchive::mountFixed(s32 entryNum, EMountDirection direction) {
if (entryNum < 0)
return false;
if (check_mount_already(entryNum))
return false;
fixedInit(entryNum, direction);
if (open(entryNum) == false) {
return false;
}
JKRAramArchive::JKRAramArchive(s32 entryNum, EMountDirection mountDirection)
: JKRArchive(entryNum, MOUNT_ARAM) {
mMountDirection = mountDirection;
if (!open(entryNum)) {
return;
}
else {
mVolumeType = 'RARC';
mVolumeName = &mStrTable[mDirectories->mOffset];
sVolumeList.prepend(&mFileLoaderLink);
mIsMounted = true;
}
}
JKRAramArchive::~JKRAramArchive() {
if (mIsMounted == true) {
if (mArcInfoBlock) {
SDIFileEntry* fileEntries = mFileEntries;
for (int i = 0; i < mArcInfoBlock->num_file_entries; i++) {
if (fileEntries->mData != nullptr) {
JKRFreeToHeap(mHeap, fileEntries->mData);
}
fileEntries++;
}
JKRFreeToHeap(mHeap, mArcInfoBlock);
mArcInfoBlock = nullptr;
}
if (mDvdFile) {
delete mDvdFile;
}
if (mBlock) {
delete mBlock;
}
sVolumeList.remove(&mFileLoaderLink);
mIsMounted = false;
}
}
void JKRAramArchive::fixedInit(s32 entryNum, EMountDirection direction) {
mIsMounted = false;
mMountDirection = direction;
mMountMode = 2;
mMountCount = 1;
_54 = 2;
mHeap = JKRGetCurrentHeap();
mEntryNum = entryNum;
if (sCurrentVolume) return;
sCurrentVolume = this;
sCurrentDirID = 0;
}
bool JKRAramArchive::mountFixed(s32 entryNum, EMountDirection direction) {
if (entryNum < 0) return false;
if (check_mount_already(entryNum)) return false;
fixedInit(entryNum, direction);
if (open(entryNum) == false) {
return false;
}
mVolumeType = 'RARC';
mVolumeName = &mStrTable[mDirectories->mOffset];
sVolumeList.prepend(&mFileLoaderLink);
mIsMounted = true;
return true;
return true;
}
bool JKRAramArchive::mountFixed(const char* path, EMountDirection direction) {
s32 entrynum = DVDConvertPathToEntrynum((char*)path);
return mountFixed(entrynum, direction);
s32 entrynum = DVDConvertPathToEntrynum((char*)path);
return mountFixed(entrynum, direction);
}
void JKRAramArchive::unmountFixed() {
if (sCurrentVolume == this) sCurrentVolume = nullptr;
if (sCurrentVolume == this)
sCurrentVolume = nullptr;
if (mArcInfoBlock) {
SDIFileEntry* fileEntries = mFileEntries;
for (int i = 0; i < mArcInfoBlock->num_file_entries; i++) {
if (fileEntries->mData != nullptr) {
JKRFreeToHeap(mHeap, fileEntries->mData);
}
fileEntries++;
if (mArcInfoBlock) {
SDIFileEntry* fileEntries = mFileEntries;
for (int i = 0; i < mArcInfoBlock->num_file_entries; i++) {
if (fileEntries->mData != nullptr) {
JKRFreeToHeap(mHeap, fileEntries->mData);
}
fileEntries++;
}
JKRFreeToHeap(mHeap, mArcInfoBlock);
mArcInfoBlock = nullptr;
}
JKRFreeToHeap(mHeap, mArcInfoBlock);
mArcInfoBlock = nullptr;
}
if (mDvdFile) delete mDvdFile;
if (mDvdFile)
delete mDvdFile;
if (mBlock) delete mBlock;
if (mBlock)
delete mBlock;
sVolumeList.remove(&mFileLoaderLink);
mIsMounted = false;
sVolumeList.remove(&mFileLoaderLink);
mIsMounted = false;
}
#if DEBUG
CW_FORCE_STRINGS(JKRAramArchive_cpp, __FILE__, "isMounted()",
"mMountCount == 1")
CW_FORCE_STRINGS(JKRAramArchive_cpp, __FILE__, "isMounted()", "mMountCount == 1")
#endif
bool JKRAramArchive::open(long entryNum) {
mArcInfoBlock = nullptr;
mDirectories = nullptr;
mFileEntries = nullptr;
mStrTable = nullptr;
mBlock = nullptr;
bool JKRAramArchive::open(long entryNum) {
mArcInfoBlock = nullptr;
mDirectories = nullptr;
mFileEntries = nullptr;
mStrTable = nullptr;
mBlock = nullptr;
mDvdFile =
new (JKRGetSystemHeap(), mMountDirection == MOUNT_DIRECTION_HEAD ? 4 : -4)
JKRDvdFile(entryNum);
if (mDvdFile == nullptr) {
mMountMode = 0;
return 0;
}
// NOTE: a different struct is used here for sure, unfortunately i can't get
// any hits on this address, so gonna leave it like this for now
SArcHeader* mem = (SArcHeader*)JKRAllocFromSysHeap(32, -32);
if (mem == nullptr) {
mMountMode = 0;
}
else {
JKRDvdToMainRam(entryNum, (u8*)mem, EXPAND_SWITCH_DECOMPRESS, 32, nullptr,
JKRDvdRipper::ALLOC_DIR_TOP, 0, &mCompression);
int alignment = mMountDirection == MOUNT_DIRECTION_HEAD ? 32 : -32;
u32 alignedSize = ALIGN_NEXT(mem->file_data_offset, 32);
mArcInfoBlock =
(SArcDataInfo*)JKRAllocFromHeap(mHeap, alignedSize, alignment);
if (mArcInfoBlock == nullptr) {
mMountMode = 0;
}
else {
JKRDvdToMainRam(entryNum, (u8*)mArcInfoBlock, EXPAND_SWITCH_DECOMPRESS,
alignedSize, nullptr, JKRDvdRipper::ALLOC_DIR_TOP, 32,
nullptr);
mDirectories =
(SDIDirEntry*)((u8*)mArcInfoBlock + mArcInfoBlock->node_offset);
mFileEntries = (SDIFileEntry*)((u8*)mArcInfoBlock +
mArcInfoBlock->file_entry_offset);
mStrTable = (const char*)((u8*)mArcInfoBlock +
mArcInfoBlock->string_table_offset);
u32 aramSize = ALIGN_NEXT(mem->file_data_length, 32);
mBlock =
JKRAllocFromAram(aramSize, mMountDirection == MOUNT_DIRECTION_HEAD
? JKRAramHeap::Head
: JKRAramHeap::Tail);
if (mBlock == nullptr) {
mDvdFile = new (JKRGetSystemHeap(), mMountDirection == MOUNT_DIRECTION_HEAD ? 4 : -4) JKRDvdFile(entryNum);
if (mDvdFile == nullptr) {
mMountMode = 0;
}
else {
JKRDvdToAram(entryNum, mBlock->getAddress(), EXPAND_SWITCH_DECOMPRESS,
mem->header_length + mem->file_data_offset, 0);
}
return 0;
}
// NOTE: a different struct is used here for sure, unfortunately i can't get
// any hits on this address, so gonna leave it like this for now
SArcHeader* mem = (SArcHeader*)JKRAllocFromSysHeap(32, -32);
if (mem == nullptr) {
mMountMode = 0;
} else {
JKRDvdToMainRam(entryNum, (u8*)mem, EXPAND_SWITCH_DECOMPRESS, 32, nullptr, JKRDvdRipper::ALLOC_DIR_TOP, 0,
&mCompression);
int alignment = mMountDirection == MOUNT_DIRECTION_HEAD ? 32 : -32;
u32 alignedSize = ALIGN_NEXT(mem->file_data_offset, 32);
mArcInfoBlock = (SArcDataInfo*)JKRAllocFromHeap(mHeap, alignedSize, alignment);
if (mArcInfoBlock == nullptr) {
mMountMode = 0;
} else {
JKRDvdToMainRam(entryNum, (u8*)mArcInfoBlock, EXPAND_SWITCH_DECOMPRESS, alignedSize, nullptr,
JKRDvdRipper::ALLOC_DIR_TOP, 32, nullptr);
mDirectories = (SDIDirEntry*)((u8*)mArcInfoBlock + mArcInfoBlock->node_offset);
mFileEntries = (SDIFileEntry*)((u8*)mArcInfoBlock + mArcInfoBlock->file_entry_offset);
mStrTable = (const char*)((u8*)mArcInfoBlock + mArcInfoBlock->string_table_offset);
u32 aramSize = ALIGN_NEXT(mem->file_data_length, 32);
mBlock = JKRAllocFromAram(aramSize,
mMountDirection == MOUNT_DIRECTION_HEAD ? JKRAramHeap::Head : JKRAramHeap::Tail);
if (mBlock == nullptr) {
mMountMode = 0;
} else {
JKRDvdToAram(entryNum, mBlock->getAddress(), EXPAND_SWITCH_DECOMPRESS,
mem->header_length + mem->file_data_offset, 0);
}
}
}
}
cleanup:
if (mem != nullptr) {
JKRFreeToSysHeap(mem);
}
if (mMountMode == 0) {
JREPORTF(":::[%s: %d] Cannot alloc memory\n", __FILE__,
415); // TODO: macro
}
return mMountMode != 0;
if (mem != nullptr) {
JKRFreeToSysHeap(mem);
}
if (mMountMode == 0) {
JREPORTF(":::[%s: %d] Cannot alloc memory\n", __FILE__,
415); // TODO: macro
}
return mMountMode != 0;
}
void* JKRAramArchive::fetchResource(SDIFileEntry* fileEntry, u32* pSize) {
JUT_ASSERT(isMounted());
JUT_ASSERT(isMounted());
u32 sizeRef;
u8* data;
u32 sizeRef;
u8* data;
if (fileEntry->mData) {
if (pSize) *pSize = fileEntry->mSize;
}
else {
u32 addres = mBlock->getAddress();
int compression = JKRConvertAttrToCompressionType(fileEntry->mFlag >> 0x18);
u32 size =
fetchResource_subroutine(fileEntry->mDataOffset + addres,
fileEntry->mSize, mHeap, compression, &data);
if (pSize) *pSize = size;
fileEntry->mData = (void*)data;
}
if (fileEntry->mData) {
if (pSize)
*pSize = fileEntry->mSize;
} else {
u32 addres = mBlock->getAddress();
int compression = JKRConvertAttrToCompressionType(fileEntry->mFlag >> 0x18);
u32 size =
fetchResource_subroutine(fileEntry->mDataOffset + addres, fileEntry->mSize, mHeap, compression, &data);
if (pSize)
*pSize = size;
fileEntry->mData = (void*)data;
}
return fileEntry->mData;
return fileEntry->mData;
}
void* JKRAramArchive::fetchResource(void* data, u32 compressedSize,
SDIFileEntry* fileEntry, u32* pSize,
JKRExpandSwitch expandSwitch) {
JUT_ASSERT(isMounted());
u32 fileSize = fileEntry->mSize;
if (fileSize > compressedSize) {
fileSize = compressedSize;
}
if (fileEntry->mData) {
JKRHeap::copyMemory(data, fileEntry->mData, fileSize);
}
else {
int compression = JKRConvertAttrToCompressionType(fileEntry->mFlag >> 0x18);
if (expandSwitch != EXPAND_SWITCH_DECOMPRESS) compression = 0;
void* JKRAramArchive::fetchResource(void* data, u32 compressedSize, SDIFileEntry* fileEntry, u32* pSize,
JKRExpandSwitch expandSwitch) {
JUT_ASSERT(isMounted());
u32 fileSize = fileEntry->mSize;
if (fileSize > compressedSize) {
fileSize = compressedSize;
}
if (fileEntry->mData) {
JKRHeap::copyMemory(data, fileEntry->mData, fileSize);
} else {
int compression = JKRConvertAttrToCompressionType(fileEntry->mFlag >> 0x18);
if (expandSwitch != EXPAND_SWITCH_DECOMPRESS)
compression = 0;
fileSize = fetchResource_subroutine(
fileEntry->mDataOffset + mBlock->getAddress(), fileSize, (u8*)data,
compressedSize, compression);
}
fileSize = fetchResource_subroutine(fileEntry->mDataOffset + mBlock->getAddress(), fileSize, (u8*)data,
compressedSize, compression);
}
if (pSize != nullptr) {
*pSize = fileSize;
}
return data;
if (pSize != nullptr) {
*pSize = fileSize;
}
return data;
}
u32 JKRAramArchive::getAramAddress_Entry(SDIFileEntry* fileEntry) {
JUT_ASSERT(isMounted());
JUT_ASSERT(isMounted());
if (fileEntry == nullptr) {
return 0;
}
return fileEntry->mDataOffset + mBlock->getAddress();
if (fileEntry == nullptr) {
return 0;
}
return fileEntry->mDataOffset + mBlock->getAddress();
}
u32 JKRAramArchive::getAramAddress(u32 type, const char* file) {
SDIFileEntry* entry = findTypeResource(type, file);
return getAramAddress_Entry(entry);
SDIFileEntry* entry = findTypeResource(type, file);
return getAramAddress_Entry(entry);
}
u32 JKRAramArchive::fetchResource_subroutine(u32 srcAram, u32 size, u8* data,
u32 expandSize, int compression) {
JUT_ASSERT((srcAram & 0x1f) == 0);
u32 JKRAramArchive::fetchResource_subroutine(u32 srcAram, u32 size, u8* data, u32 expandSize, int compression) {
JUT_ASSERT((srcAram & 0x1f) == 0);
u32 sizeRef;
u32 sizeRef;
u32 alignedSize = ALIGN_NEXT(size, 32);
u32 prevAlignedSize = ALIGN_PREV(expandSize, 32);
switch (compression) {
case JKRCOMPRESSION_NONE:
if (alignedSize > prevAlignedSize) {
alignedSize = prevAlignedSize;
u32 alignedSize = ALIGN_NEXT(size, 32);
u32 prevAlignedSize = ALIGN_PREV(expandSize, 32);
switch (compression) {
case JKRCOMPRESSION_NONE:
if (alignedSize > prevAlignedSize) {
alignedSize = prevAlignedSize;
}
JKRAramToMainRam(srcAram, data, alignedSize, EXPAND_SWITCH_DEFAULT, prevAlignedSize, nullptr, -1, &sizeRef);
return sizeRef;
case JKRCOMPRESSION_YAY0:
case JKRCOMPRESSION_YAZ0:
JKRAramToMainRam(srcAram, data, alignedSize, EXPAND_SWITCH_DECOMPRESS, prevAlignedSize, nullptr, -1,
&sizeRef);
return sizeRef;
default:
JPANIC(550, ":::??? bad sequence\n");
return 0;
}
JKRAramToMainRam(srcAram, data, alignedSize, EXPAND_SWITCH_DEFAULT,
prevAlignedSize, nullptr, -1, &sizeRef);
return sizeRef;
case JKRCOMPRESSION_YAY0:
case JKRCOMPRESSION_YAZ0:
JKRAramToMainRam(srcAram, data, alignedSize, EXPAND_SWITCH_DECOMPRESS,
prevAlignedSize, nullptr, -1, &sizeRef);
return sizeRef;
default:
JPANIC(550, ":::??? bad sequence\n");
return 0;
}
}
u32 JKRAramArchive::fetchResource_subroutine(u32 srcAram, u32 size,
JKRHeap* heap, int compression,
u8** pBuf) {
u32 resSize;
u32 alignedSize = ALIGN_NEXT(size, 32);
u32 JKRAramArchive::fetchResource_subroutine(u32 srcAram, u32 size, JKRHeap* heap, int compression, u8** pBuf) {
u32 resSize;
u32 alignedSize = ALIGN_NEXT(size, 32);
u8* buffer;
switch (compression) {
case JKRCOMPRESSION_NONE:
buffer = (u8*)JKRAllocFromHeap(heap, alignedSize, 32);
JUT_ASSERT(buffer != 0);
u8* buffer;
switch (compression) {
case JKRCOMPRESSION_NONE:
buffer = (u8*)JKRAllocFromHeap(heap, alignedSize, 32);
JUT_ASSERT(buffer != 0);
JKRAramToMainRam(srcAram, buffer, alignedSize, EXPAND_SWITCH_DEFAULT,
alignedSize, nullptr, -1, nullptr);
*pBuf = buffer;
JKRAramToMainRam(srcAram, buffer, alignedSize, EXPAND_SWITCH_DEFAULT, alignedSize, nullptr, -1, nullptr);
*pBuf = buffer;
return size;
case JKRCOMPRESSION_YAY0:
case JKRCOMPRESSION_YAZ0:
u8* header = (u8*)JKRAllocFromHeap(heap, 0x20, 0x20);
JKRAramToMainRam(srcAram, header, 0x20, EXPAND_SWITCH_DEFAULT, 0, nullptr,
-1, nullptr);
u32 expandSize = JKRDecompExpandSize(header);
JKRFreeToHeap(heap, header);
expandSize = ALIGN_NEXT(expandSize, 32);
buffer = (u8*)JKRAllocFromHeap(heap, expandSize, 0x20);
JUT_ASSERT(buffer);
return size;
case JKRCOMPRESSION_YAY0:
case JKRCOMPRESSION_YAZ0:
u8* header = (u8*)JKRAllocFromHeap(heap, 0x20, 0x20);
JKRAramToMainRam(srcAram, header, 0x20, EXPAND_SWITCH_DEFAULT, 0, nullptr, -1, nullptr);
u32 expandSize = JKRDecompExpandSize(header);
JKRFreeToHeap(heap, header);
expandSize = ALIGN_NEXT(expandSize, 32);
buffer = (u8*)JKRAllocFromHeap(heap, expandSize, 0x20);
JUT_ASSERT(buffer);
JKRAramToMainRam(srcAram, buffer, alignedSize, EXPAND_SWITCH_DECOMPRESS,
expandSize, heap, -1, &resSize);
*pBuf = buffer;
return resSize;
default:
JPANIC(605, ":::??? bad sequence\n");
return 0;
}
JKRAramToMainRam(srcAram, buffer, alignedSize, EXPAND_SWITCH_DECOMPRESS, expandSize, heap, -1, &resSize);
*pBuf = buffer;
return resSize;
default:
JPANIC(605, ":::??? bad sequence\n");
return 0;
}
}
+23 -31
View File
@@ -1,45 +1,37 @@
#include "JSystem/JKernel/JKRAram.h"
JKRAramBlock::JKRAramBlock(u32 address, u32 size, u32 freeSize, u8 groupID,
bool tempMemory)
: mLink(this),
mAddress(address),
mSize(size),
mFreeSize(freeSize),
mGroupID(groupID),
mIsTempMemory(tempMemory) {}
JKRAramBlock::JKRAramBlock(u32 address, u32 size, u32 freeSize, u8 groupID, bool tempMemory)
: mLink(this), mAddress(address), mSize(size), mFreeSize(freeSize), mGroupID(groupID), mIsTempMemory(tempMemory) {
}
JKRAramBlock::~JKRAramBlock() {
JSULink<JKRAramBlock>* prev = this->mLink.getPrev();
JSUList<JKRAramBlock>* list = this->mLink.getList();
JSULink<JKRAramBlock>* prev = this->mLink.getPrev();
JSUList<JKRAramBlock>* list = this->mLink.getList();
if (prev) {
prev->getObject()->mFreeSize += this->mSize + this->mFreeSize;
list->remove(&this->mLink);
}
else {
this->mFreeSize += this->mSize;
this->mSize = 0;
}
if (prev) {
prev->getObject()->mFreeSize += this->mSize + this->mFreeSize;
list->remove(&this->mLink);
} else {
this->mFreeSize += this->mSize;
this->mSize = 0;
}
}
JKRAramBlock* JKRAramBlock::allocHead(u32 size, u8 groupID, JKRAramHeap* heap) {
u32 address = this->mAddress + this->mSize;
u32 freeSize = this->mFreeSize - size;
u32 address = this->mAddress + this->mSize;
u32 freeSize = this->mFreeSize - size;
JKRAramBlock* block = new (heap->mHeap, nullptr)
JKRAramBlock(address, size, freeSize, groupID, false);
this->mFreeSize = 0;
this->mLink.mPtrList->insert(this->mLink.mNext, &block->mLink);
return block;
JKRAramBlock* block = new (heap->mHeap, nullptr) JKRAramBlock(address, size, freeSize, groupID, false);
this->mFreeSize = 0;
this->mLink.mPtrList->insert(this->mLink.mNext, &block->mLink);
return block;
}
JKRAramBlock* JKRAramBlock::allocTail(u32 size, u8 groupID, JKRAramHeap* heap) {
u32 address = this->mAddress + this->mSize + this->mFreeSize - size;
u32 address = this->mAddress + this->mSize + this->mFreeSize - size;
JKRAramBlock* block =
new (heap->mHeap, nullptr) JKRAramBlock(address, size, 0, groupID, true);
this->mFreeSize -= size;
this->mLink.mPtrList->insert(this->mLink.mNext, &block->mLink);
return block;
JKRAramBlock* block = new (heap->mHeap, nullptr) JKRAramBlock(address, size, 0, groupID, true);
this->mFreeSize -= size;
this->mLink.mPtrList->insert(this->mLink.mNext, &block->mLink);
return block;
}
+95 -106
View File
@@ -5,165 +5,154 @@
JSUList<JKRAramBlock> JKRAramHeap::sAramList;
JKRAramHeap::JKRAramHeap(u32 baseAddress, u32 size) : JKRDisposer() {
OSInitMutex(&this->mMutex);
this->mHeap = JKRHeap::findFromRoot(this);
this->mSize = ALIGN_PREV(size, 0x20);
this->mHeadAddress = ALIGN_NEXT(baseAddress, 0x20);
this->mTailAddress = this->mHeadAddress + this->mSize;
this->mGroupID = 0xFF;
JKRAramBlock* block = new (this->mHeap, nullptr)
JKRAramBlock(this->mHeadAddress, 0, this->mSize, 0xFF, false);
sAramList.append(&block->mLink);
OSInitMutex(&this->mMutex);
this->mHeap = JKRHeap::findFromRoot(this);
this->mSize = ALIGN_PREV(size, 0x20);
this->mHeadAddress = ALIGN_NEXT(baseAddress, 0x20);
this->mTailAddress = this->mHeadAddress + this->mSize;
this->mGroupID = 0xFF;
JKRAramBlock* block = new (this->mHeap, nullptr) JKRAramBlock(this->mHeadAddress, 0, this->mSize, 0xFF, false);
sAramList.append(&block->mLink);
}
JKRAramHeap::~JKRAramHeap() {
for (JSUListIterator<JKRAramBlock> it = sAramList.getFirst();
it != sAramList.getEnd();) {
delete (it++).getObject();
}
for (JSUListIterator<JKRAramBlock> it = sAramList.getFirst(); it != sAramList.getEnd();) {
delete (it++).getObject();
}
}
JKRAramBlock* JKRAramHeap::alloc(u32 size, JKRAramHeap::EAllocMode mode) {
JKRAramBlock* block;
this->lock();
JKRAramBlock* block;
this->lock();
if (mode == Head) {
block = this->allocFromHead(size);
}
else {
block = this->allocFromTail(size);
}
if (mode == Head) {
block = this->allocFromHead(size);
} else {
block = this->allocFromTail(size);
}
this->unlock();
return block;
this->unlock();
return block;
}
/* Code retrieved from Twilight Princess Debug version & matched. Unused in AC.
*/
void JKRAramHeap::free(JKRAramBlock* block) { delete block; }
void JKRAramHeap::free(JKRAramBlock* block) {
delete block;
}
JKRAramBlock* JKRAramHeap::allocFromHead(u32 size) {
size = ALIGN_NEXT(size, 32);
u32 min_size = 0xFFFFFFFFUL;
JKRAramBlock* block = nullptr;
size = ALIGN_NEXT(size, 32);
u32 min_size = 0xFFFFFFFFUL;
JKRAramBlock* block = nullptr;
for (JSUListIterator<JKRAramBlock> it = sAramList.getFirst();
it != sAramList.getEnd(); it++) {
JKRAramBlock* n_block = it.getObject();
if (n_block->mFreeSize >= size && min_size > n_block->mFreeSize) {
min_size = n_block->mFreeSize;
block = n_block;
if (block->mFreeSize == size) {
break;
}
for (JSUListIterator<JKRAramBlock> it = sAramList.getFirst(); it != sAramList.getEnd(); it++) {
JKRAramBlock* n_block = it.getObject();
if (n_block->mFreeSize >= size && min_size > n_block->mFreeSize) {
min_size = n_block->mFreeSize;
block = n_block;
if (block->mFreeSize == size) {
break;
}
}
}
}
if (block != nullptr) {
return block->allocHead(size, this->mGroupID, this);
}
if (block != nullptr) {
return block->allocHead(size, this->mGroupID, this);
}
return nullptr;
return nullptr;
}
JKRAramBlock* JKRAramHeap::allocFromTail(u32 size) {
JKRAramBlock* block = nullptr;
size = ALIGN_NEXT(size, 32);
JKRAramBlock* block = nullptr;
size = ALIGN_NEXT(size, 32);
for (JSUListIterator<JKRAramBlock> it = sAramList.getLast();
it != sAramList.getEnd(); it--) {
JKRAramBlock* n_block = it.getObject();
for (JSUListIterator<JKRAramBlock> it = sAramList.getLast(); it != sAramList.getEnd(); it--) {
JKRAramBlock* n_block = it.getObject();
if (n_block->mFreeSize >= size) {
block = n_block;
break;
if (n_block->mFreeSize >= size) {
block = n_block;
break;
}
}
}
if (block != nullptr) {
return block->allocTail(size, this->mGroupID, this);
}
if (block != nullptr) {
return block->allocTail(size, this->mGroupID, this);
}
return nullptr;
return nullptr;
}
/* Debug code retrieved from Twilight Princess Debug version */
void JKRAramHeap::dump() {
this->lock();
this->lock();
int total_used = 0;
JREPORT("\nJKRAramHeap dump\n");
JREPORT(" attr address: size gid\n");
int total_used = 0;
JREPORT("\nJKRAramHeap dump\n");
JREPORT(" attr address: size gid\n");
for (JSUListIterator<JKRAramBlock> listItr = sAramList.getFirst();
listItr != sAramList.getEnd(); listItr++) {
if (listItr->mSize != 0) {
JREPORTF("%s %08x: %08x %3d\n",
listItr->isTempMemory() ? " temp" : "alloc", listItr->mAddress,
listItr->mSize, listItr->mGroupID);
for (JSUListIterator<JKRAramBlock> listItr = sAramList.getFirst(); listItr != sAramList.getEnd(); listItr++) {
if (listItr->mSize != 0) {
JREPORTF("%s %08x: %08x %3d\n", listItr->isTempMemory() ? " temp" : "alloc", listItr->mAddress,
listItr->mSize, listItr->mGroupID);
}
if (listItr->mFreeSize != 0) {
JREPORTF(" free %08x: %08x 0\n", listItr->mAddress + listItr->mSize, listItr->mFreeSize);
}
total_used += listItr->mSize;
}
if (listItr->mFreeSize != 0) {
JREPORTF(" free %08x: %08x 0\n", listItr->mAddress + listItr->mSize,
listItr->mFreeSize);
}
JREPORTF("%d / %d bytes (%6.2f%%) used\n", total_used, this->mSize, (f32)total_used / (f32)this->mSize);
total_used += listItr->mSize;
}
JREPORTF("%d / %d bytes (%6.2f%%) used\n", total_used, this->mSize,
(f32)total_used / (f32)this->mSize);
this->unlock();
this->unlock();
}
/* Not present in AC, recreated from TP debug. TODO: Check for matching. */
u32 JKRAramHeap::getFreeSize() {
u32 max_free = 0;
this->lock();
u32 max_free = 0;
this->lock();
for (JSUListIterator<JKRAramBlock> it = sAramList.getFirst();
it != sAramList.getEnd(); it++) {
if (it->mFreeSize > max_free) {
max_free = it->mFreeSize;
for (JSUListIterator<JKRAramBlock> it = sAramList.getFirst(); it != sAramList.getEnd(); it++) {
if (it->mFreeSize > max_free) {
max_free = it->mFreeSize;
}
}
}
this->unlock();
return max_free;
this->unlock();
return max_free;
}
/* Not present in AC, recreated from TP debug. TODO: Check for matching. */
u32 JKRAramHeap::getTotalFreeSize() {
u32 total_free = 0;
this->lock();
u32 total_free = 0;
this->lock();
for (JSUListIterator<JKRAramBlock> it = sAramList.getFirst();
it != sAramList.getEnd(); it++) {
total_free += it->mFreeSize;
}
for (JSUListIterator<JKRAramBlock> it = sAramList.getFirst(); it != sAramList.getEnd(); it++) {
total_free += it->mFreeSize;
}
this->unlock();
return total_free;
this->unlock();
return total_free;
}
/* Not present in AC, recreated from TP debug. TODO: Check for matching. */
u32 JKRAramHeap::getUsedSize(u8 groupID) {
u32 total_used = 0;
this->lock();
u32 total_used = 0;
this->lock();
if (groupID == ARAM_GROUP_ID_ALL) {
total_used = this->mSize - this->getTotalFreeSize();
}
else {
for (JSUListIterator<JKRAramBlock> it = sAramList.getFirst();
it != sAramList.getEnd(); it++) {
if (groupID == it->mGroupID) {
total_used += it->mSize;
}
if (groupID == ARAM_GROUP_ID_ALL) {
total_used = this->mSize - this->getTotalFreeSize();
} else {
for (JSUListIterator<JKRAramBlock> it = sAramList.getFirst(); it != sAramList.getEnd(); it++) {
if (groupID == it->mGroupID) {
total_used += it->mSize;
}
}
}
}
this->unlock();
return total_used;
this->unlock();
return total_used;
}
+92 -106
View File
@@ -12,146 +12,132 @@
JSUList<JKRAMCommand> JKRAramPiece::sAramPieceCommandList;
OSMutex JKRAramPiece::mMutex;
JKRAMCommand* JKRAramPiece::prepareCommand(
int direction, u32 source, u32 destination, u32 length,
JKRAramBlock* aramBlock, JKRAMCommand::AMCommandCallback callback) {
JKRAMCommand* cmd = new (JKRGetSystemHeap(), -4) JKRAMCommand();
cmd->mDirection = direction;
cmd->mSource = source;
cmd->mDestination = destination;
cmd->mAramBlock = aramBlock;
cmd->mLength = length;
cmd->mCallback = callback;
JKRAMCommand* JKRAramPiece::prepareCommand(int direction, u32 source, u32 destination, u32 length,
JKRAramBlock* aramBlock, JKRAMCommand::AMCommandCallback callback) {
JKRAMCommand* cmd = new (JKRGetSystemHeap(), -4) JKRAMCommand();
cmd->mDirection = direction;
cmd->mSource = source;
cmd->mDestination = destination;
cmd->mAramBlock = aramBlock;
cmd->mLength = length;
cmd->mCallback = callback;
return cmd;
return cmd;
}
void JKRAramPiece::sendCommand(JKRAMCommand* cmd) {
JKRAramPiece::startDMA(cmd);
JKRAramPiece::startDMA(cmd);
}
JKRAMCommand* JKRAramPiece::orderAsync(
int direction, u32 source, u32 destination, u32 length,
JKRAramBlock* aramBlock, JKRAMCommand::AMCommandCallback callback) {
JKRAramPiece::lock();
JKRAMCommand* JKRAramPiece::orderAsync(int direction, u32 source, u32 destination, u32 length, JKRAramBlock* aramBlock,
JKRAMCommand::AMCommandCallback callback) {
JKRAramPiece::lock();
if (!JKR_ISALIGNED32(source) || !JKR_ISALIGNED32(destination)) {
JLOGF("direction = %x\n", direction);
JLOGF("source = %x\n", source);
JLOGF("destination = %x\n", destination);
JLOGF("length = %x\n", length);
JPANICLINE(102);
}
if (!JKR_ISALIGNED32(source) || !JKR_ISALIGNED32(destination)) {
JLOGF("direction = %x\n", direction);
JLOGF("source = %x\n", source);
JLOGF("destination = %x\n", destination);
JLOGF("length = %x\n", length);
JPANICLINE(102);
}
JKRAramCommand* aramCmd = new (JKRGetSystemHeap(), -4) JKRAramCommand();
JKRAMCommand* cmd = JKRAramPiece::prepareCommand(
direction, source, destination, length, aramBlock, callback);
aramCmd->setting(TRUE, cmd);
OSSendMessage((OSMessageQueue*)&JKRAram::sMessageQueue, (OSMessage)aramCmd,
OS_MESSAGE_BLOCK);
if (cmd->mCallback != nullptr) {
JKRAramPiece::sAramPieceCommandList.append(&cmd->mAramPieceCommandLink);
}
JKRAramCommand* aramCmd = new (JKRGetSystemHeap(), -4) JKRAramCommand();
JKRAMCommand* cmd = JKRAramPiece::prepareCommand(direction, source, destination, length, aramBlock, callback);
aramCmd->setting(TRUE, cmd);
OSSendMessage((OSMessageQueue*)&JKRAram::sMessageQueue, (OSMessage)aramCmd, OS_MESSAGE_BLOCK);
if (cmd->mCallback != nullptr) {
JKRAramPiece::sAramPieceCommandList.append(&cmd->mAramPieceCommandLink);
}
JKRAramPiece::unlock();
return cmd;
JKRAramPiece::unlock();
return cmd;
}
bool JKRAramPiece::sync(JKRAMCommand* cmd, BOOL noBlock) {
OSMessage msg[1];
OSMessage msg[1];
JKRAramPiece::lock();
JKRAramPiece::lock();
if (!noBlock) {
OSReceiveMessage(&cmd->mMesgQueue, msg, OS_MESSAGE_BLOCK);
JKRAramPiece::sAramPieceCommandList.remove(&cmd->mAramPieceCommandLink);
JKRAramPiece::unlock();
return true;
}
else {
if (!OSReceiveMessage(&cmd->mMesgQueue, msg, OS_MESSAGE_NOBLOCK)) {
JKRAramPiece::unlock();
return false;
if (!noBlock) {
OSReceiveMessage(&cmd->mMesgQueue, msg, OS_MESSAGE_BLOCK);
JKRAramPiece::sAramPieceCommandList.remove(&cmd->mAramPieceCommandLink);
JKRAramPiece::unlock();
return true;
} else {
if (!OSReceiveMessage(&cmd->mMesgQueue, msg, OS_MESSAGE_NOBLOCK)) {
JKRAramPiece::unlock();
return false;
} else {
JKRAramPiece::sAramPieceCommandList.remove(&cmd->mAramPieceCommandLink);
JKRAramPiece::unlock();
return true;
}
}
else {
JKRAramPiece::sAramPieceCommandList.remove(&cmd->mAramPieceCommandLink);
JKRAramPiece::unlock();
return true;
}
}
}
bool JKRAramPiece::orderSync(int direction, u32 source, u32 destination,
u32 length, JKRAramBlock* aramBlock) {
JKRAramPiece::lock();
bool JKRAramPiece::orderSync(int direction, u32 source, u32 destination, u32 length, JKRAramBlock* aramBlock) {
JKRAramPiece::lock();
JKRAMCommand* cmd = JKRAramPiece::orderAsync(direction, source, destination,
length, aramBlock, nullptr);
bool res = JKRAramPiece::sync(cmd, FALSE);
delete cmd;
JKRAMCommand* cmd = JKRAramPiece::orderAsync(direction, source, destination, length, aramBlock, nullptr);
bool res = JKRAramPiece::sync(cmd, FALSE);
delete cmd;
JKRAramPiece::unlock();
return res;
JKRAramPiece::unlock();
return res;
}
void JKRAramPiece::startDMA(JKRAMCommand* cmd) {
if (cmd->mDirection == ARAM_DIR_ARAM_TO_MRAM) {
DCInvalidateRange((u8*)cmd->mDestination, cmd->mLength);
}
else { /* cmd->mDirection == ARAM_DIR_MRAM_TO_ARAM */
DCStoreRange((u8*)cmd->mSource, cmd->mLength);
}
if (cmd->mDirection == ARAM_DIR_ARAM_TO_MRAM) {
DCInvalidateRange((u8*)cmd->mDestination, cmd->mLength);
} else { /* cmd->mDirection == ARAM_DIR_MRAM_TO_ARAM */
DCStoreRange((u8*)cmd->mSource, cmd->mLength);
}
ARQPostRequest(cmd, 0, cmd->mDirection, 0, cmd->mSource, cmd->mDestination,
cmd->mLength, JKRAramPiece::doneDMA);
ARQPostRequest(cmd, 0, cmd->mDirection, 0, cmd->mSource, cmd->mDestination, cmd->mLength, JKRAramPiece::doneDMA);
}
void JKRAramPiece::doneDMA(u32 param) {
JKRAMCommand* cmd = (JKRAMCommand*)param;
if (cmd->mDirection == ARAM_DIR_ARAM_TO_MRAM) {
DCInvalidateRange((u8*)cmd->mDestination, cmd->mLength);
}
if (cmd->mCallbackType != ARAMPIECE_DONE_CALLBACK) {
if (cmd->mCallbackType == ARAMPIECE_DONE_DECOMPRESS) {
JKRDecomp::sendCommand(cmd->mDecompCommand);
JKRAMCommand* cmd = (JKRAMCommand*)param;
if (cmd->mDirection == ARAM_DIR_ARAM_TO_MRAM) {
DCInvalidateRange((u8*)cmd->mDestination, cmd->mLength);
}
}
else {
if (cmd->mCallback != nullptr) {
(*cmd->mCallback)(param);
if (cmd->mCallbackType != ARAMPIECE_DONE_CALLBACK) {
if (cmd->mCallbackType == ARAMPIECE_DONE_DECOMPRESS) {
JKRDecomp::sendCommand(cmd->mDecompCommand);
}
} else {
if (cmd->mCallback != nullptr) {
(*cmd->mCallback)(param);
} else {
if (cmd->mCompletedMesgQueue != nullptr) {
OSSendMessage(cmd->mCompletedMesgQueue, (OSMessage)cmd, OS_MESSAGE_NOBLOCK);
} else {
OSSendMessage(&cmd->mMesgQueue, (OSMessage)cmd, OS_MESSAGE_NOBLOCK);
}
}
}
else {
if (cmd->mCompletedMesgQueue != nullptr) {
OSSendMessage(cmd->mCompletedMesgQueue, (OSMessage)cmd,
OS_MESSAGE_NOBLOCK);
}
else {
OSSendMessage(&cmd->mMesgQueue, (OSMessage)cmd, OS_MESSAGE_NOBLOCK);
}
}
}
}
JKRAMCommand::JKRAMCommand() : mAramPieceCommandLink(this), mLink30(this) {
OSInitMessageQueue(&this->mMesgQueue, this->mMesgBuffer, 1);
this->mCallback = nullptr;
this->mCompletedMesgQueue = nullptr;
this->mCallbackType = ARAMPIECE_DONE_CALLBACK;
this->_8C = nullptr;
this->_90 = nullptr;
this->_94 = nullptr;
OSInitMessageQueue(&this->mMesgQueue, this->mMesgBuffer, 1);
this->mCallback = nullptr;
this->mCompletedMesgQueue = nullptr;
this->mCallbackType = ARAMPIECE_DONE_CALLBACK;
this->_8C = nullptr;
this->_90 = nullptr;
this->_94 = nullptr;
}
JKRAMCommand::~JKRAMCommand() {
if (this->_8C != nullptr) {
delete this->_8C;
}
if (this->_8C != nullptr) {
delete this->_8C;
}
if (this->_90 != nullptr) {
delete this->_90;
}
if (this->_90 != nullptr) {
delete this->_90;
}
if (this->_94 != nullptr) {
JKRFree(this->_94);
}
if (this->_94 != nullptr) {
JKRFree(this->_94);
}
}
+136 -150
View File
@@ -17,105 +17,99 @@ u32 JKRAramStream::transSize = nullptr;
JKRHeap* JKRAramStream::transHeap = nullptr;
JKRAramStream* JKRAramStream::create(s32 param) {
if (JKRAramStream::sAramStreamObject == nullptr) {
JKRAramStream::sAramStreamObject =
new (JKRGetSystemHeap(), 0) JKRAramStream(param);
setTransBuffer(nullptr, 0, nullptr);
}
return JKRAramStream::sAramStreamObject;
if (JKRAramStream::sAramStreamObject == nullptr) {
JKRAramStream::sAramStreamObject = new (JKRGetSystemHeap(), 0) JKRAramStream(param);
setTransBuffer(nullptr, 0, nullptr);
}
return JKRAramStream::sAramStreamObject;
}
JKRAramStream::JKRAramStream(s32 priority) : JKRThread(0x4000, 0x10, priority) {
OSResumeThread(mThreadRecord);
OSResumeThread(mThreadRecord);
}
JKRAramStream::~JKRAramStream() {};
void* JKRAramStream::run() {
OSMessage result;
OSInitMessageQueue(
&JKRAramStream::sMessageQueue, JKRAramStream::sMessageBuffer,
ARRAY_COUNT(sMessageBuffer)); // jank cast to void** to satisfy prototype
while (true) {
OSReceiveMessage(&JKRAramStream::sMessageQueue, &result, OS_MESSAGE_BLOCK);
JKRAramStreamCommand* command = static_cast<JKRAramStreamCommand*>(result);
switch (command->type) {
case JKRAramStreamCommand::ECT_READ:
readFromAram();
break;
case JKRAramStreamCommand::ECT_WRITE:
writeToAram(command);
break;
OSMessage result;
OSInitMessageQueue(&JKRAramStream::sMessageQueue, JKRAramStream::sMessageBuffer,
ARRAY_COUNT(sMessageBuffer)); // jank cast to void** to satisfy prototype
while (true) {
OSReceiveMessage(&JKRAramStream::sMessageQueue, &result, OS_MESSAGE_BLOCK);
JKRAramStreamCommand* command = static_cast<JKRAramStreamCommand*>(result);
switch (command->type) {
case JKRAramStreamCommand::ECT_READ:
readFromAram();
break;
case JKRAramStreamCommand::ECT_WRITE:
writeToAram(command);
break;
}
}
}
}
u32 JKRAramStream::readFromAram() {
return 1;
} // probably a define evaluating to 1
return 1;
} // probably a define evaluating to 1
s32 JKRAramStream::writeToAram(JKRAramStreamCommand* command) {
u32 dstSize = command->mSize;
u32 offset = command->mOffset;
u32 writtenLength = 0;
u32 destination = command->mAddress;
u8* buffer = command->mTransferBuffer;
u32 bufferSize = command->mTransferBufferSize;
JKRHeap* heap = command->mHeap;
if (buffer) {
bufferSize = (bufferSize == nullptr) ? 0x8000 : bufferSize;
u32 dstSize = command->mSize;
u32 offset = command->mOffset;
u32 writtenLength = 0;
u32 destination = command->mAddress;
u8* buffer = command->mTransferBuffer;
u32 bufferSize = command->mTransferBufferSize;
JKRHeap* heap = command->mHeap;
if (buffer) {
bufferSize = (bufferSize == nullptr) ? 0x8000 : bufferSize;
command->mTransferBufferSize = bufferSize;
command->mAllocatedTransferBuffer = false;
}
else {
bufferSize = (bufferSize == nullptr) ? 0x8000 : bufferSize;
command->mTransferBufferSize = bufferSize;
command->mAllocatedTransferBuffer = false;
} else {
bufferSize = (bufferSize == nullptr) ? 0x8000 : bufferSize;
if (heap) {
buffer = (u8*)JKRAllocFromHeap(heap, bufferSize, -0x20);
command->mTransferBuffer = buffer;
}
else {
buffer = (u8*)JKRAllocFromHeap(nullptr, bufferSize, -0x20);
command->mTransferBuffer = buffer;
if (heap) {
buffer = (u8*)JKRAllocFromHeap(heap, bufferSize, -0x20);
command->mTransferBuffer = buffer;
} else {
buffer = (u8*)JKRAllocFromHeap(nullptr, bufferSize, -0x20);
command->mTransferBuffer = buffer;
}
command->mTransferBufferSize = bufferSize;
command->mAllocatedTransferBuffer = true;
}
command->mTransferBufferSize = bufferSize;
command->mAllocatedTransferBuffer = true;
}
if (!buffer) {
if (!heap) {
JKRGetCurrentHeap()->dump();
}
else {
heap->dump();
}
JPANIC(169, "abort\n");
}
if (buffer) {
command->mStream->seek(offset, SEEK_SET);
while (dstSize != 0) {
u32 length = (dstSize > bufferSize) ? bufferSize : dstSize;
s32 readLength = command->mStream->read(buffer, length);
JKRAramPcs(0, (u32)buffer, destination, length, nullptr);
dstSize -= length;
writtenLength += length;
destination += length;
if (!buffer) {
if (!heap) {
JKRGetCurrentHeap()->dump();
} else {
heap->dump();
}
JPANIC(169, "abort\n");
}
if (command->mAllocatedTransferBuffer) {
JKRFree(buffer);
command->mAllocatedTransferBuffer = false;
}
}
if (buffer) {
command->mStream->seek(offset, SEEK_SET);
while (dstSize != 0) {
u32 length = (dstSize > bufferSize) ? bufferSize : dstSize;
OSSendMessage(&command->mMessageQueue, (OSMessage)writtenLength,
OS_MESSAGE_NOBLOCK);
return writtenLength;
s32 readLength = command->mStream->read(buffer, length);
JKRAramPcs(0, (u32)buffer, destination, length, nullptr);
dstSize -= length;
writtenLength += length;
destination += length;
}
if (command->mAllocatedTransferBuffer) {
JKRFree(buffer);
command->mAllocatedTransferBuffer = false;
}
}
OSSendMessage(&command->mMessageQueue, (OSMessage)writtenLength, OS_MESSAGE_NOBLOCK);
return writtenLength;
};
/*
@@ -124,92 +118,84 @@ s32 JKRAramStream::writeToAram(JKRAramStreamCommand* command) {
* Should exist to generate JSURandomInputStream::getAvailable() const
* afterwards.
*/
JKRAramStreamCommand* JKRAramStream::write_StreamToAram_Async(
JSUFileInputStream* stream, JKRAramBlock* addr, u32 size, u32 offset) {
JKRAramStreamCommand* command =
new (JKRGetSystemHeap(), -4) JKRAramStreamCommand();
command->type = JKRAramStreamCommand::ECT_WRITE;
command->mAddress = (u32)addr;
command->mSize = size;
command->mStream = stream;
command->_28 = stream->getAvailable();
command->mOffset = offset;
command->mTransferBuffer = transBuffer;
command->mHeap = transHeap;
command->mTransferBufferSize = transSize;
JKRAramStreamCommand* JKRAramStream::write_StreamToAram_Async(JSUFileInputStream* stream, JKRAramBlock* addr, u32 size,
u32 offset) {
JKRAramStreamCommand* command = new (JKRGetSystemHeap(), -4) JKRAramStreamCommand();
command->type = JKRAramStreamCommand::ECT_WRITE;
command->mAddress = (u32)addr;
command->mSize = size;
command->mStream = stream;
command->_28 = stream->getAvailable();
command->mOffset = offset;
command->mTransferBuffer = transBuffer;
command->mHeap = transHeap;
command->mTransferBufferSize = transSize;
OSInitMessageQueue(&command->mMessageQueue, &command->mMessage, 1);
OSSendMessage(&sMessageQueue, command, OS_MESSAGE_BLOCK);
return command;
OSInitMessageQueue(&command->mMessageQueue, &command->mMessage, 1);
OSSendMessage(&sMessageQueue, command, OS_MESSAGE_BLOCK);
return command;
}
JKRAramStreamCommand* JKRAramStream::write_StreamToAram_Async(
JSUFileInputStream* stream, u32 addr, u32 size, u32 offset) {
JKRAramStreamCommand* command =
new (JKRGetSystemHeap(), -4) JKRAramStreamCommand();
command->type = JKRAramStreamCommand::ECT_WRITE;
command->mAddress = addr;
command->mSize = size;
command->mStream = stream;
command->_28 = 0;
command->mOffset = offset;
command->mTransferBuffer = transBuffer;
command->mHeap = transHeap;
command->mTransferBufferSize = transSize;
JKRAramStreamCommand* JKRAramStream::write_StreamToAram_Async(JSUFileInputStream* stream, u32 addr, u32 size,
u32 offset) {
JKRAramStreamCommand* command = new (JKRGetSystemHeap(), -4) JKRAramStreamCommand();
command->type = JKRAramStreamCommand::ECT_WRITE;
command->mAddress = addr;
command->mSize = size;
command->mStream = stream;
command->_28 = 0;
command->mOffset = offset;
command->mTransferBuffer = transBuffer;
command->mHeap = transHeap;
command->mTransferBufferSize = transSize;
OSInitMessageQueue(&command->mMessageQueue, &command->mMessage, 1);
OSSendMessage(&sMessageQueue, command, OS_MESSAGE_BLOCK);
return command;
OSInitMessageQueue(&command->mMessageQueue, &command->mMessage, 1);
OSSendMessage(&sMessageQueue, command, OS_MESSAGE_BLOCK);
return command;
}
JKRAramStreamCommand* JKRAramStream::sync(JKRAramStreamCommand* command,
BOOL isNonBlocking) {
OSMessage msg;
if (isNonBlocking == FALSE) {
OSReceiveMessage(&command->mMessageQueue, &msg, OS_MESSAGE_BLOCK);
if (msg == nullptr) {
command = nullptr;
return command;
JKRAramStreamCommand* JKRAramStream::sync(JKRAramStreamCommand* command, BOOL isNonBlocking) {
OSMessage msg;
if (isNonBlocking == FALSE) {
OSReceiveMessage(&command->mMessageQueue, &msg, OS_MESSAGE_BLOCK);
if (msg == nullptr) {
command = nullptr;
return command;
} else {
return command;
}
} else {
BOOL receiveResult = OSReceiveMessage(&command->mMessageQueue, &msg, OS_MESSAGE_NOBLOCK);
if (receiveResult == FALSE) {
command = nullptr;
return command;
} else if (msg == nullptr) {
command = nullptr;
return command;
} else {
return command;
}
}
else {
return command;
}
}
else {
BOOL receiveResult =
OSReceiveMessage(&command->mMessageQueue, &msg, OS_MESSAGE_NOBLOCK);
if (receiveResult == FALSE) {
command = nullptr;
return command;
}
else if (msg == nullptr) {
command = nullptr;
return command;
}
else {
return command;
}
}
}
void JKRAramStream::setTransBuffer(u8* buffer, u32 bufferSize, JKRHeap* heap) {
transBuffer = nullptr;
transSize = 0x8000;
transHeap = nullptr;
transBuffer = nullptr;
transSize = 0x8000;
transHeap = nullptr;
if (buffer) {
transBuffer = (u8*)ALIGN_NEXT((u32)buffer, 0x20);
}
if (buffer) {
transBuffer = (u8*)ALIGN_NEXT((u32)buffer, 0x20);
}
if (bufferSize) {
transSize = ALIGN_PREV(bufferSize, 0x20);
}
if (bufferSize) {
transSize = ALIGN_PREV(bufferSize, 0x20);
}
if (heap && !buffer) {
transHeap = heap;
}
if (heap && !buffer) {
transHeap = heap;
}
}
JKRAramStreamCommand::JKRAramStreamCommand() {
mAllocatedTransferBuffer = false;
mAllocatedTransferBuffer = false;
}
+44 -97
View File
@@ -7,42 +7,31 @@
u32 JKRArchive::sCurrentDirID;
JKRArchive::JKRArchive()
{
JKRArchive::JKRArchive() {
mIsMounted = false;
mMountDirection = MOUNT_DIRECTION_HEAD;
}
JKRArchive::JKRArchive(s32 entryNum, JKRArchive::EMountMode mountMode)
: JKRFileLoader()
{
JKRArchive::JKRArchive(s32 entryNum, JKRArchive::EMountMode mountMode) : JKRFileLoader() {
mIsMounted = false;
mMountMode = mountMode;
mMountCount = 1;
_54 = 1;
mHeap = JKRHeap::findFromRoot(this);
if (!mHeap)
{
if (!mHeap) {
mHeap = JKRHeap::sCurrentHeap;
}
mEntryNum = entryNum;
if (sCurrentVolume == nullptr)
{
if (sCurrentVolume == nullptr) {
sCurrentDirID = 0;
sCurrentVolume = this;
}
}
JKRArchive::JKRArchive(const char* p1, JKRArchive::EMountMode mountMode)
{
// UNUSED FUNCTION
JKRArchive::~JKRArchive() {
}
JKRArchive::~JKRArchive() {}
bool JKRArchive::isSameName(JKRArchive::CArcName& archiveName,
u32 nameTableOffset, u16 hash) const
{
bool JKRArchive::isSameName(JKRArchive::CArcName& archiveName, u32 nameTableOffset, u16 hash) const {
u16 arcHash = archiveName.getHash();
if (arcHash != hash)
return false;
@@ -50,24 +39,18 @@ bool JKRArchive::isSameName(JKRArchive::CArcName& archiveName,
return strcmp(&mStrTable[nameTableOffset], archiveName.getString()) == 0;
}
JKRArchive::SDIDirEntry* JKRArchive::findResType(u32 type) const
{
JKRArchive::SDIDirEntry* JKRArchive::findResType(u32 type) const {
SDIDirEntry* dirEntry = mDirectories;
for (u32 i = 0; i < mArcInfoBlock->num_nodes; i++, dirEntry++)
{
if (dirEntry->mType == type)
{
for (u32 i = 0; i < mArcInfoBlock->num_nodes; i++, dirEntry++) {
if (dirEntry->mType == type) {
return dirEntry;
}
}
return nullptr;
}
JKRArchive::SDIDirEntry* JKRArchive::findDirectory(const char* path,
u32 index) const
{
if (path == nullptr)
{
JKRArchive::SDIDirEntry* JKRArchive::findDirectory(const char* path, u32 index) const {
if (path == nullptr) {
return &mDirectories[index];
}
@@ -75,12 +58,9 @@ JKRArchive::SDIDirEntry* JKRArchive::findDirectory(const char* path,
SDIDirEntry* dirEntry = &mDirectories[index];
SDIFileEntry* entry = &mFileEntries[dirEntry->mFirstIdx];
for (int i = 0; i < dirEntry->mNum; entry++, i++)
{
if (isSameName(arcName, entry->mFlag & 0xFFFFFF, entry->mHash))
{
if ((entry->mFlag >> 24) & 0x02)
{
for (int i = 0; i < dirEntry->mNum; entry++, i++) {
if (isSameName(arcName, entry->mFlag & 0xFFFFFF, entry->mHash)) {
if ((entry->mFlag >> 24) & 0x02) {
return findDirectory(path, entry->mDataOffset);
}
break;
@@ -90,22 +70,15 @@ JKRArchive::SDIDirEntry* JKRArchive::findDirectory(const char* path,
return nullptr;
}
JKRArchive::SDIFileEntry* JKRArchive::findTypeResource(u32 type,
const char* name) const
{
if (type != 0)
{
JKRArchive::SDIFileEntry* JKRArchive::findTypeResource(u32 type, const char* name) const {
if (type != 0) {
CArcName arcName;
arcName.store(name);
SDIDirEntry* dirEntry = findResType(type);
if (dirEntry != nullptr)
{
if (dirEntry != nullptr) {
SDIFileEntry* fileEntry = mFileEntries + dirEntry->mFirstIdx;
for (int i = 0; i < dirEntry->mNum; fileEntry++, i++)
{
if (isSameName(arcName, fileEntry->mFlag & 0xFFFFFF,
fileEntry->mHash))
{
for (int i = 0; i < dirEntry->mNum; fileEntry++, i++) {
if (isSameName(arcName, fileEntry->mFlag & 0xFFFFFF, fileEntry->mHash)) {
return fileEntry;
}
}
@@ -114,24 +87,17 @@ JKRArchive::SDIFileEntry* JKRArchive::findTypeResource(u32 type,
return nullptr;
}
JKRArchive::SDIFileEntry* JKRArchive::findFsResource(const char* path,
u32 index) const
{
if (path)
{
JKRArchive::SDIFileEntry* JKRArchive::findFsResource(const char* path, u32 index) const {
if (path) {
CArcName arcName(&path, '/');
SDIDirEntry* dirEntry = &mDirectories[index];
SDIFileEntry* entry = &mFileEntries[dirEntry->mFirstIdx];
for (int i = 0; i < dirEntry->mNum; entry++, i++)
{
if (isSameName(arcName, entry->mFlag & 0xFFFFFF, entry->mHash))
{
if (((entry->mFlag >> 0x18) & 2))
{
for (int i = 0; i < dirEntry->mNum; entry++, i++) {
if (isSameName(arcName, entry->mFlag & 0xFFFFFF, entry->mHash)) {
if (((entry->mFlag >> 0x18) & 2)) {
return findFsResource(path, entry->mDataOffset);
}
if (path == 0)
{
if (path == 0) {
return entry;
}
return nullptr;
@@ -141,24 +107,19 @@ JKRArchive::SDIFileEntry* JKRArchive::findFsResource(const char* path,
return nullptr;
}
JKRArchive::SDIFileEntry* JKRArchive::findIdxResource(u32 idx) const
{
if (idx < mArcInfoBlock->num_file_entries)
{
JKRArchive::SDIFileEntry* JKRArchive::findIdxResource(u32 idx) const {
if (idx < mArcInfoBlock->num_file_entries) {
return mFileEntries + idx;
}
return nullptr;
}
JKRArchive::SDIFileEntry* JKRArchive::findNameResource(const char* name) const
{
JKRArchive::SDIFileEntry* JKRArchive::findNameResource(const char* name) const {
SDIFileEntry* fileEntry = mFileEntries;
CArcName arcName(name);
for (int i = 0; i < mArcInfoBlock->num_file_entries; fileEntry++, i++)
{
if (isSameName(arcName, fileEntry->mFlag & 0xFFFFFF, fileEntry->mHash))
{
for (int i = 0; i < mArcInfoBlock->num_file_entries; fileEntry++, i++) {
if (isSameName(arcName, fileEntry->mFlag & 0xFFFFFF, fileEntry->mHash)) {
return fileEntry;
}
}
@@ -166,35 +127,27 @@ JKRArchive::SDIFileEntry* JKRArchive::findNameResource(const char* name) const
return nullptr;
}
JKRArchive::SDIFileEntry* JKRArchive::findPtrResource(const void* ptr) const
{
JKRArchive::SDIFileEntry* JKRArchive::findPtrResource(const void* ptr) const {
SDIFileEntry* entry = mFileEntries;
for (u32 i = 0; i < mArcInfoBlock->num_file_entries; entry++, i++)
{
if (entry->mData == ptr)
{
for (u32 i = 0; i < mArcInfoBlock->num_file_entries; entry++, i++) {
if (entry->mData == ptr) {
return entry;
}
}
return nullptr;
}
JKRArchive::SDIFileEntry* JKRArchive::findIdResource(u16 id) const
{
JKRArchive::SDIFileEntry* JKRArchive::findIdResource(u16 id) const {
SDIFileEntry* entry;
if (id != 0xFFFF)
{
if (id != 0xFFFF) {
entry = &mFileEntries[id];
if (entry->mFileID == id && (entry->getFlag01()))
{
if (entry->mFileID == id && (entry->getFlag01())) {
return entry;
}
entry = mFileEntries;
for (int i = 0; i < mArcInfoBlock->num_file_entries; entry++, i++)
{
if (entry->mFileID == id && (entry->getFlag01()))
{
for (int i = 0; i < mArcInfoBlock->num_file_entries; entry++, i++) {
if (entry->mFileID == id && (entry->getFlag01())) {
return entry;
}
}
@@ -202,16 +155,13 @@ JKRArchive::SDIFileEntry* JKRArchive::findIdResource(u16 id) const
return nullptr;
}
void JKRArchive::CArcName::store(const char* name)
{
void JKRArchive::CArcName::store(const char* name) {
mHash = 0;
int count = 0;
while (*name)
{
while (*name) {
int lower = tolower(*name);
mHash = lower + mHash * 3;
if (count < 0x100)
{
if (count < 0x100) {
mString[count++] = lower;
}
name++;
@@ -220,16 +170,13 @@ void JKRArchive::CArcName::store(const char* name)
mString[count] = '\0';
}
const char* JKRArchive::CArcName::store(const char* name, char endChar)
{
const char* JKRArchive::CArcName::store(const char* name, char endChar) {
mHash = 0;
int count = 0;
for (; *name && *name != endChar; name++)
{
for (; *name && *name != endChar; name++) {
int lower = tolower(*name);
mHash = lower + mHash * 3;
if (count < 0x100)
{
if (count < 0x100) {
mString[count++] = lower;
}
}
+227 -258
View File
@@ -12,329 +12,298 @@
// does that and it doesn't cause any issues
JKRArchive* JKRArchive::check_mount_already(s32 entryNum, JKRHeap* pHeap) {
// UNUSED FUNCTION
JKRHeap* heap = pHeap;
if (heap == nullptr) {
heap = JKRGetCurrentHeap();
}
JSUList<JKRFileLoader>& volumeList = JKRArchive::sVolumeList;
JSUListIterator<JKRFileLoader> iterator;
for (iterator = volumeList.getFirst(); iterator != volumeList.getEnd();
++iterator) {
if (iterator->getVolumeType() == 'RARC') {
JKRArchive* archive =
(JKRArchive*)
iterator.getObject(); // in TP debug it calls operator-> ?
if (archive->mEntryNum == entryNum && archive->mHeap == heap) {
archive->mMountCount++;
return archive;
}
// UNUSED FUNCTION
JKRHeap* heap = pHeap;
if (heap == nullptr) {
heap = JKRGetCurrentHeap();
}
}
return nullptr;
JSUListIterator<JKRFileLoader> iterator;
for (iterator = sVolumeList.getFirst(); iterator != sVolumeList.getEnd(); ++iterator) {
if (iterator->getVolumeType() == 'RARC') {
JKRArchive* archive = (JKRArchive*)iterator.getObject(); // in TP debug it calls operator-> ?
if (archive->mEntryNum == entryNum && archive->mHeap == heap) {
archive->mMountCount++;
return archive;
}
}
}
return nullptr;
}
JKRArchive* JKRArchive::check_mount_already(s32 entryNum) {
JSUList<JKRFileLoader>& volumeList = JKRArchive::sVolumeList;
JSUListIterator<JKRFileLoader> iterator;
for (iterator = volumeList.getFirst(); iterator != volumeList.getEnd();
++iterator) {
if (iterator->getVolumeType() == 'RARC') {
JKRArchive* archive =
(JKRArchive*)
iterator.getObject(); // in TP debug it calls operator-> ?
if (archive->mEntryNum == entryNum) {
archive->mMountCount++;
return archive;
}
for (JSUListIterator<JKRFileLoader> iterator = sVolumeList.getFirst(); iterator != sVolumeList.getEnd();
++iterator) {
if (iterator->getVolumeType() == 'RARC') {
JKRArchive* archive = (JKRArchive*)iterator.getObject(); // in TP debug it calls operator-> ?
if (archive->mEntryNum == entryNum) {
archive->mMountCount++;
return archive;
}
}
}
}
return nullptr;
return nullptr;
}
JKRArchive* JKRArchive::mount(const char* path, EMountMode mode, JKRHeap* heap,
EMountDirection direction) {
int entryNum = DVDConvertPathToEntrynum((char*)path);
if (entryNum < 0) return nullptr;
JKRArchive* JKRArchive::mount(const char* path, EMountMode mode, JKRHeap* heap, EMountDirection direction) {
int entryNum = DVDConvertPathToEntrynum((char*)path);
if (entryNum < 0)
return nullptr;
JKRArchive* mountedArchive = check_mount_already(entryNum);
if (mountedArchive != nullptr) {
return mountedArchive;
}
JKRArchive* mountedArchive = check_mount_already(entryNum);
if (mountedArchive != nullptr) {
return mountedArchive;
}
int alignment = (direction == MOUNT_DIRECTION_HEAD) ? 4 : -4;
JKRArchive* archive;
switch (mode) {
case MOUNT_MEM:
if (entryNum == -1)
archive = nullptr;
else
archive = new (heap, alignment) JKRMemArchive(entryNum, direction);
break;
case MOUNT_ARAM:
archive = new (heap, alignment) JKRAramArchive(entryNum, direction);
break;
case MOUNT_DVD:
archive = new (heap, alignment) JKRDvdArchive(entryNum, direction);
break;
case MOUNT_COMP:
archive = new (heap, alignment) JKRCompArchive(entryNum, direction);
break;
}
if (archive != nullptr && archive->getMountMode() == UNKNOWN_MOUNT_MODE) {
delete archive;
archive = nullptr;
}
return archive;
}
JKRArchive* JKRArchive::mount(void* p1, JKRHeap* heap,
EMountDirection mountDirection) {
JKRArchive* archive = check_mount_already((s32)p1, heap);
if (archive != nullptr) {
return archive;
}
return new (heap, (mountDirection == MOUNT_DIRECTION_HEAD) ? 4 : -4)
JKRMemArchive(p1, 0xFFFF, MBF_0);
}
JKRArchive* JKRArchive::mount(s32 entryNum, EMountMode mountMode, JKRHeap* heap,
EMountDirection mountDirection) {
JKRArchive* archive = check_mount_already(entryNum, heap);
if (archive) {
return archive;
}
else {
int i = (mountDirection == MOUNT_DIRECTION_HEAD) ? 4 : -4;
int alignment = (direction == MOUNT_DIRECTION_HEAD) ? 4 : -4;
JKRArchive* archive;
switch (mountMode) {
case MOUNT_MEM:
archive = new (heap, i) JKRMemArchive(entryNum, mountDirection);
break;
case MOUNT_ARAM:
archive = new (heap, i) JKRAramArchive(entryNum, mountDirection);
break;
case MOUNT_DVD:
archive = new (heap, i) JKRDvdArchive(entryNum, mountDirection);
break;
case MOUNT_COMP:
archive = new (heap, i) JKRCompArchive(entryNum, mountDirection);
break;
switch (mode) {
case MOUNT_MEM:
if (entryNum == -1)
archive = nullptr;
else
archive = new (heap, alignment) JKRMemArchive(entryNum, direction);
break;
case MOUNT_ARAM:
archive = new (heap, alignment) JKRAramArchive(entryNum, direction);
break;
case MOUNT_DVD:
archive = new (heap, alignment) JKRDvdArchive(entryNum, direction);
break;
case MOUNT_COMP:
archive = new (heap, alignment) JKRCompArchive(entryNum, direction);
break;
}
if (archive != nullptr && archive->getMountMode() == UNKNOWN_MOUNT_MODE) {
delete archive;
archive = nullptr;
delete archive;
archive = nullptr;
}
return archive;
}
}
JKRArchive* JKRArchive::mount(void* p1, JKRHeap* heap, EMountDirection mountDirection) {
JKRArchive* archive = check_mount_already((s32)p1, heap);
if (archive != nullptr) {
return archive;
}
return new (heap, (mountDirection == MOUNT_DIRECTION_HEAD) ? 4 : -4) JKRMemArchive(p1, 0xFFFF, MBF_0);
}
JKRArchive* JKRArchive::mount(s32 entryNum, EMountMode mountMode, JKRHeap* heap, EMountDirection mountDirection) {
JKRArchive* archive = check_mount_already(entryNum, heap);
if (archive) {
return archive;
} else {
int i = (mountDirection == MOUNT_DIRECTION_HEAD) ? 4 : -4;
JKRArchive* archive;
switch (mountMode) {
case MOUNT_MEM:
archive = new (heap, i) JKRMemArchive(entryNum, mountDirection);
break;
case MOUNT_ARAM:
archive = new (heap, i) JKRAramArchive(entryNum, mountDirection);
break;
case MOUNT_DVD:
archive = new (heap, i) JKRDvdArchive(entryNum, mountDirection);
break;
case MOUNT_COMP:
archive = new (heap, i) JKRCompArchive(entryNum, mountDirection);
break;
}
if (archive != nullptr && archive->getMountMode() == UNKNOWN_MOUNT_MODE) {
delete archive;
archive = nullptr;
}
return archive;
}
}
bool JKRArchive::becomeCurrent(const char* path) {
SDIDirEntry* entry;
if (*path == '/') {
const char* directoryName = path + 1;
if (*directoryName == '\0') {
directoryName = nullptr;
SDIDirEntry* entry;
if (*path == '/') {
const char* directoryName = path + 1;
if (*directoryName == '\0') {
directoryName = nullptr;
}
entry = findDirectory(directoryName, 0);
} else {
entry = findDirectory(path, sCurrentDirID);
}
entry = findDirectory(directoryName, 0);
}
else {
entry = findDirectory(path, sCurrentDirID);
}
bool result = (entry != nullptr);
if (result) {
sCurrentVolume = this;
sCurrentDirID = (entry - mDirectories);
}
return result;
bool result = (entry != nullptr);
if (result) {
sCurrentVolume = this;
sCurrentDirID = (entry - mDirectories);
}
return result;
}
bool JKRArchive::getDirEntry(JKRArchive::SDirEntry* dirEntry, u32 p2) const {
SDIFileEntry* fileEntry = findIdxResource(p2);
if (!fileEntry) {
return false;
}
SDIFileEntry* fileEntry = findIdxResource(p2);
if (!fileEntry) {
return false;
}
dirEntry->mFlags = fileEntry->mFlag >> 0x18;
dirEntry->mID = fileEntry->mFileID;
dirEntry->mName = (char*)mStrTable + (fileEntry->mFlag & 0xFFFFFF);
return true;
dirEntry->mFlags = fileEntry->mFlag >> 0x18;
dirEntry->mID = fileEntry->mFileID;
dirEntry->mName = (char*)mStrTable + (fileEntry->mFlag & 0xFFFFFF);
return true;
}
void* JKRArchive::getGlbResource(u32 type, const char* name,
JKRArchive* archive) {
void* resource = nullptr;
if (archive) {
return archive->getResource(type, name);
}
for (JSULink<JKRFileLoader>* link = sVolumeList.getFirst(); link != nullptr;
link = link->getNext()) {
if (link->getObject()->getVolumeType() == 'RARC' &&
(resource = link->getObject()->getResource(type, name))) {
break;
void* JKRArchive::getGlbResource(u32 type, const char* name, JKRArchive* archive) {
void* resource = nullptr;
if (archive) {
return archive->getResource(type, name);
}
}
return resource;
for (JSULink<JKRFileLoader>* link = sVolumeList.getFirst(); link != nullptr; link = link->getNext()) {
if (link->getObject()->getVolumeType() == 'RARC' && (resource = link->getObject()->getResource(type, name))) {
break;
}
}
return resource;
}
void* JKRArchive::getResource(const char* path) {
JUT_ASSERT(isMounted());
SDIFileEntry* fileEntry;
if (*path == '/') {
fileEntry = findFsResource(path + 1, 0);
}
else {
fileEntry = findFsResource(path, sCurrentDirID);
}
return (fileEntry != nullptr) ? (void*)fetchResource(fileEntry, nullptr)
: nullptr;
JUT_ASSERT(isMounted());
SDIFileEntry* fileEntry;
if (*path == '/') {
fileEntry = findFsResource(path + 1, 0);
} else {
fileEntry = findFsResource(path, sCurrentDirID);
}
return (fileEntry != nullptr) ? (void*)fetchResource(fileEntry, nullptr) : nullptr;
}
void* JKRArchive::getResource(u32 type, const char* name) {
JUT_ASSERT(isMounted());
SDIFileEntry* fileEntry;
if (type == 0 || type == '????') {
fileEntry = findNameResource(name);
}
else {
fileEntry = findTypeResource(type, name);
}
return (fileEntry != nullptr) ? (void*)fetchResource(fileEntry, nullptr)
: nullptr;
JUT_ASSERT(isMounted());
SDIFileEntry* fileEntry;
if (type == 0 || type == '????') {
fileEntry = findNameResource(name);
} else {
fileEntry = findTypeResource(type, name);
}
return (fileEntry != nullptr) ? (void*)fetchResource(fileEntry, nullptr) : nullptr;
}
void* JKRArchive::getIdxResource(u32 index) {
SDIFileEntry* fileEntry = findIdxResource(index);
return (fileEntry != nullptr) ? (void*)fetchResource(fileEntry, nullptr)
: nullptr;
SDIFileEntry* fileEntry = findIdxResource(index);
return (fileEntry != nullptr) ? (void*)fetchResource(fileEntry, nullptr) : nullptr;
}
size_t JKRArchive::readResource(void* resourceBuffer, u32 bufferSize, u32 type,
const char* name) {
JUT_ASSERT(isMounted());
SDIFileEntry* fileEntry;
if (type == 0 || type == '????') {
fileEntry = findNameResource(name);
}
else {
fileEntry = findTypeResource(type, name);
}
if (fileEntry) {
u32 resourceSize;
fetchResource(resourceBuffer, bufferSize, fileEntry, &resourceSize,
EXPAND_SWITCH_DECOMPRESS);
return resourceSize;
}
return 0;
size_t JKRArchive::readResource(void* resourceBuffer, u32 bufferSize, u32 type, const char* name) {
JUT_ASSERT(isMounted());
SDIFileEntry* fileEntry;
if (type == 0 || type == '????') {
fileEntry = findNameResource(name);
} else {
fileEntry = findTypeResource(type, name);
}
if (fileEntry) {
u32 resourceSize;
fetchResource(resourceBuffer, bufferSize, fileEntry, &resourceSize, EXPAND_SWITCH_DECOMPRESS);
return resourceSize;
}
return 0;
}
// Returns the size of the resource at the given path, or 0 if not found.
size_t JKRArchive::readResource(void* resourceBuffer, u32 bufferSize,
const char* path,
JKRExpandSwitch expandSwitch) {
JUT_ASSERT(isMounted());
SDIFileEntry* fileEntry;
if (*path == '/') {
fileEntry = findFsResource(path + 1, 0);
}
else {
fileEntry = findFsResource(path, sCurrentDirID);
}
if (fileEntry) {
u32 resourceSize;
fetchResource(resourceBuffer, bufferSize, fileEntry, &resourceSize,
expandSwitch);
return resourceSize;
}
return 0;
size_t JKRArchive::readResource(void* resourceBuffer, u32 bufferSize, const char* path, JKRExpandSwitch expandSwitch) {
JUT_ASSERT(isMounted());
SDIFileEntry* fileEntry;
if (*path == '/') {
fileEntry = findFsResource(path + 1, 0);
} else {
fileEntry = findFsResource(path, sCurrentDirID);
}
if (fileEntry) {
u32 resourceSize;
fetchResource(resourceBuffer, bufferSize, fileEntry, &resourceSize, expandSwitch);
return resourceSize;
}
return 0;
}
// Returns the size of the resource with the given ID, or 0 if not found.
size_t JKRArchive::readResource(void* resourceBuffer, u32 bufferSize, u16 id) {
JUT_ASSERT(isMounted());
SDIFileEntry* fileEntry = findIdResource(id);
if (fileEntry) {
u32 resSize;
fetchResource(resourceBuffer, bufferSize, fileEntry, &resSize,
EXPAND_SWITCH_DEFAULT);
return resSize;
}
return 0;
JUT_ASSERT(isMounted());
SDIFileEntry* fileEntry = findIdResource(id);
if (fileEntry) {
u32 resSize;
fetchResource(resourceBuffer, bufferSize, fileEntry, &resSize, EXPAND_SWITCH_DEFAULT);
return resSize;
}
return 0;
}
// This function is currently full off bugs, it doesn't increase the pointer to
// the file entries, and sets the pointer of mData to null before it's sent to
// free
void JKRArchive::removeResourceAll() {
if (mArcInfoBlock && mMountMode != MOUNT_MEM) {
SDIFileEntry* entry = mFileEntries;
for (int i = 0; i < mArcInfoBlock->num_file_entries; i++) {
if (entry->mData) {
entry->mData = nullptr;
JKRFreeToHeap(mHeap, entry->mData);
}
if (mArcInfoBlock && mMountMode != MOUNT_MEM) {
SDIFileEntry* entry = mFileEntries;
for (int i = 0; i < mArcInfoBlock->num_file_entries; i++) {
if (entry->mData) {
entry->mData = nullptr;
JKRFreeToHeap(mHeap, entry->mData);
}
}
}
}
}
bool JKRArchive::removeResource(void* resource) {
JUT_ASSERT(resource != 0);
SDIFileEntry* entry = findPtrResource(resource);
if (entry == nullptr) {
return false;
}
entry->mData = nullptr;
JKRHeap::free(resource, mHeap);
return true;
JUT_ASSERT(resource != 0);
SDIFileEntry* entry = findPtrResource(resource);
if (entry == nullptr) {
return false;
}
entry->mData = nullptr;
JKRHeap::free(resource, mHeap);
return true;
}
bool JKRArchive::detachResource(void* resource) {
JUT_ASSERT(resource != 0);
SDIFileEntry* entry = findPtrResource(resource);
if (entry == nullptr) {
return false;
}
entry->mData = nullptr;
return true;
JUT_ASSERT(resource != 0);
SDIFileEntry* entry = findPtrResource(resource);
if (entry == nullptr) {
return false;
}
entry->mData = nullptr;
return true;
}
s32 JKRArchive::getResSize(const void* resource) const {
JUT_ASSERT(resource != 0);
SDIFileEntry* entry = findPtrResource(resource);
return (entry == nullptr) ? -1 : entry->getSize();
JUT_ASSERT(resource != 0);
SDIFileEntry* entry = findPtrResource(resource);
return (entry == nullptr) ? -1 : entry->getSize();
}
u32 JKRArchive::countFile(const char* path) const {
SDIDirEntry* dirEntry;
if (*path == '/') {
const char* pathPtr = path + 1;
if (*pathPtr == '\0') {
pathPtr = nullptr;
SDIDirEntry* dirEntry;
if (*path == '/') {
const char* pathPtr = path + 1;
if (*pathPtr == '\0') {
pathPtr = nullptr;
}
dirEntry = findDirectory(pathPtr, 0);
} else {
dirEntry = findDirectory(path, sCurrentDirID);
}
dirEntry = findDirectory(pathPtr, 0);
}
else {
dirEntry = findDirectory(path, sCurrentDirID);
}
return (dirEntry) ? dirEntry->mNum : 0;
return (dirEntry) ? dirEntry->mNum : 0;
}
JKRFileFinder* JKRArchive::getFirstFile(const char* path) const {
SDIDirEntry* dirEntry;
if (*path == '/') {
const char* pathPtr = path + 1;
if (*pathPtr == '\0') {
pathPtr = nullptr;
SDIDirEntry* dirEntry;
if (*path == '/') {
const char* pathPtr = path + 1;
if (*pathPtr == '\0') {
pathPtr = nullptr;
}
dirEntry = findDirectory(pathPtr, 0);
} else {
dirEntry = findDirectory(path, sCurrentDirID);
}
dirEntry = findDirectory(pathPtr, 0);
}
else {
dirEntry = findDirectory(path, sCurrentDirID);
}
if (dirEntry) {
return new (JKRGetSystemHeap(), 0) JKRArcFinder(
const_cast<JKRArchive*>(this), dirEntry->mFirstIdx, dirEntry->mNum);
}
return nullptr;
if (dirEntry) {
return new (JKRGetSystemHeap(), 0)
JKRArcFinder(const_cast<JKRArchive*>(this), dirEntry->mFirstIdx, dirEntry->mNum);
}
return nullptr;
}
+254 -286
View File
@@ -8,335 +8,303 @@
#include "JSystem/JSystem.h"
#include "JSystem/JUtility/JUTAssertion.h"
JKRCompArchive::JKRCompArchive(long entryNum, EMountDirection mountDirection)
: JKRArchive(entryNum, MOUNT_COMP) {
mMountDirection = mountDirection;
if (!open(entryNum)) {
return;
}
else {
mVolumeType = 'RARC';
mVolumeName = &mStrTable[mDirectories->mOffset];
sVolumeList.prepend(&mFileLoaderLink);
mIsMounted = true;
}
JKRCompArchive::JKRCompArchive(long entryNum, EMountDirection mountDirection) : JKRArchive(entryNum, MOUNT_COMP) {
mMountDirection = mountDirection;
if (!open(entryNum)) {
return;
} else {
mVolumeType = 'RARC';
mVolumeName = &mStrTable[mDirectories->mOffset];
sVolumeList.prepend(&mFileLoaderLink);
mIsMounted = true;
}
}
#if DEBUG
void stringGen() {
JUT_PANIC("isMounted()");
JUT_PANIC("mMountCount == 1");
JUT_PANIC("isMounted()");
JUT_PANIC("mMountCount == 1");
}
#endif
JKRCompArchive::~JKRCompArchive() {
if (mArcInfoBlock) {
SDIFileEntry* fileEntries = mFileEntries;
for (int i = 0; i < mArcInfoBlock->num_file_entries; i++) {
u32 flag = (fileEntries->mFlag >> 24);
if ((flag & 16) == 0 && fileEntries->mData) {
JKRFreeToHeap(mHeap, fileEntries->mData);
}
fileEntries++;
if (mArcInfoBlock) {
SDIFileEntry* fileEntries = mFileEntries;
for (int i = 0; i < mArcInfoBlock->num_file_entries; i++) {
u32 flag = (fileEntries->mFlag >> 24);
if ((flag & 16) == 0 && fileEntries->mData) {
JKRFreeToHeap(mHeap, fileEntries->mData);
}
fileEntries++;
}
JKRFreeToHeap(mHeap, mArcInfoBlock);
mArcInfoBlock = nullptr;
}
if (mAramPart) {
delete mAramPart;
}
if (mDvdFile) {
delete mDvdFile;
}
JKRFreeToHeap(mHeap, mArcInfoBlock);
mArcInfoBlock = nullptr;
}
if (mAramPart) {
delete mAramPart;
}
if (mDvdFile) {
delete mDvdFile;
}
sVolumeList.remove(&mFileLoaderLink);
mIsMounted = false;
sVolumeList.remove(&mFileLoaderLink);
mIsMounted = false;
}
bool JKRCompArchive::open(long entryNum) {
mArcInfoBlock = nullptr;
_60 = 0;
mAramPart = nullptr;
_68 = 0;
mSizeOfMemPart = 0;
mSizeOfAramPart = 0;
_78 = 0;
mDirectories = nullptr;
mFileEntries = nullptr;
mStrTable = nullptr;
mArcInfoBlock = nullptr;
_60 = 0;
mAramPart = nullptr;
_68 = 0;
mSizeOfMemPart = 0;
mSizeOfAramPart = 0;
_78 = 0;
mDirectories = nullptr;
mFileEntries = nullptr;
mStrTable = nullptr;
mDvdFile = new (JKRGetSystemHeap(), 0) JKRDvdFile(entryNum);
if (mDvdFile == nullptr) {
mMountMode = 0;
return 0;
}
SArcHeader* arcHeader = (SArcHeader*)JKRAllocFromSysHeap(
sizeof(SArcHeader), -32); // NOTE: unconfirmed if this struct is used
if (arcHeader == nullptr) {
mMountMode = 0;
}
else {
int alignment;
JKRDvdToMainRam(entryNum, (u8*)arcHeader, EXPAND_SWITCH_DECOMPRESS, 32,
nullptr, JKRDvdRipper::ALLOC_DIR_TOP, 0, &mCompression);
mSizeOfMemPart = arcHeader->_14;
mSizeOfAramPart = arcHeader->_18;
JUT_ASSERT((mSizeOfMemPart & 0x1f) == 0);
JUT_ASSERT((mSizeOfAramPart & 0x1f) == 0);
switch (mCompression) {
case JKRCOMPRESSION_NONE:
case JKRCOMPRESSION_YAZ0:
alignment = mMountDirection == 1 ? 32 : -32;
mArcInfoBlock = (SArcDataInfo*)JKRAllocFromHeap(
mHeap, arcHeader->file_data_offset + mSizeOfMemPart, alignment);
if (mArcInfoBlock == nullptr) {
mDvdFile = new (JKRGetSystemHeap(), 0) JKRDvdFile(entryNum);
if (mDvdFile == nullptr) {
mMountMode = 0;
}
else {
JKRDvdToMainRam(entryNum, (u8*)mArcInfoBlock,
EXPAND_SWITCH_DECOMPRESS,
(u32)arcHeader->file_data_offset + mSizeOfMemPart,
nullptr, JKRDvdRipper::ALLOC_DIR_TOP, 0x20, nullptr);
_60 = (u32)mArcInfoBlock + arcHeader->file_data_offset;
if (mSizeOfAramPart != 0) {
mAramPart = JKRAllocFromAram(mSizeOfAramPart, JKRAramHeap::Head);
if (mAramPart == nullptr) {
mMountMode = 0;
break;
}
JKRDvdToAram(entryNum, mAramPart->getAddress(),
EXPAND_SWITCH_DECOMPRESS,
arcHeader->header_length +
arcHeader->file_data_offset + mSizeOfMemPart,
0);
}
mDirectories =
(SDIDirEntry*)((u32)mArcInfoBlock + mArcInfoBlock->node_offset);
mFileEntries = (SDIFileEntry*)((u32)mArcInfoBlock +
mArcInfoBlock->file_entry_offset);
mStrTable = (const char*)((u32)mArcInfoBlock +
mArcInfoBlock->string_table_offset);
_68 = arcHeader->header_length + arcHeader->file_data_offset;
}
break;
case JKRCOMPRESSION_YAY0:
u32 alignedSize = ALIGN_NEXT(mDvdFile->getFileSize(), 32);
alignment = ((mMountDirection == 1) ? 32 : -32);
u8* buf = (u8*)JKRAllocFromSysHeap(alignedSize, -alignment);
if (buf == nullptr) {
return 0;
}
SArcHeader* arcHeader =
(SArcHeader*)JKRAllocFromSysHeap(sizeof(SArcHeader), -32); // NOTE: unconfirmed if this struct is used
if (arcHeader == nullptr) {
mMountMode = 0;
}
else {
JKRDvdToMainRam(entryNum, buf, EXPAND_SWITCH_NONE, alignedSize,
nullptr, JKRDvdRipper::ALLOC_DIR_TOP, 0, nullptr);
u32 expandSize = ALIGN_NEXT(JKRDecompExpandSize(buf), 32);
u8* mem = (u8*)JKRAllocFromHeap(mHeap, expandSize, -alignment);
} else {
int alignment;
if (mem == nullptr) {
mMountMode = 0;
JKRDvdToMainRam(entryNum, (u8*)arcHeader, EXPAND_SWITCH_DECOMPRESS, 32, nullptr, JKRDvdRipper::ALLOC_DIR_TOP, 0,
&mCompression);
mSizeOfMemPart = arcHeader->_14;
mSizeOfAramPart = arcHeader->_18;
JUT_ASSERT((mSizeOfMemPart & 0x1f) == 0);
JUT_ASSERT((mSizeOfAramPart & 0x1f) == 0);
switch (mCompression) {
case JKRCOMPRESSION_NONE:
case JKRCOMPRESSION_YAZ0:
alignment = mMountDirection == 1 ? 32 : -32;
mArcInfoBlock =
(SArcDataInfo*)JKRAllocFromHeap(mHeap, arcHeader->file_data_offset + mSizeOfMemPart, alignment);
if (mArcInfoBlock == nullptr) {
mMountMode = 0;
} else {
JKRDvdToMainRam(entryNum, (u8*)mArcInfoBlock, EXPAND_SWITCH_DECOMPRESS,
(u32)arcHeader->file_data_offset + mSizeOfMemPart, nullptr,
JKRDvdRipper::ALLOC_DIR_TOP, 0x20, nullptr);
_60 = (u32)mArcInfoBlock + arcHeader->file_data_offset;
if (mSizeOfAramPart != 0) {
mAramPart = JKRAllocFromAram(mSizeOfAramPart, JKRAramHeap::Head);
if (mAramPart == nullptr) {
mMountMode = 0;
break;
}
JKRDvdToAram(entryNum, mAramPart->getAddress(), EXPAND_SWITCH_DECOMPRESS,
arcHeader->header_length + arcHeader->file_data_offset + mSizeOfMemPart, 0);
}
mDirectories = (SDIDirEntry*)((u32)mArcInfoBlock + mArcInfoBlock->node_offset);
mFileEntries = (SDIFileEntry*)((u32)mArcInfoBlock + mArcInfoBlock->file_entry_offset);
mStrTable = (const char*)((u32)mArcInfoBlock + mArcInfoBlock->string_table_offset);
_68 = arcHeader->header_length + arcHeader->file_data_offset;
}
break;
case JKRCOMPRESSION_YAY0:
u32 alignedSize = ALIGN_NEXT(mDvdFile->getFileSize(), 32);
alignment = ((mMountDirection == 1) ? 32 : -32);
u8* buf = (u8*)JKRAllocFromSysHeap(alignedSize, -alignment);
if (buf == nullptr) {
mMountMode = 0;
} else {
JKRDvdToMainRam(entryNum, buf, EXPAND_SWITCH_NONE, alignedSize, nullptr,
JKRDvdRipper::ALLOC_DIR_TOP, 0, nullptr);
u32 expandSize = ALIGN_NEXT(JKRDecompExpandSize(buf), 32);
u8* mem = (u8*)JKRAllocFromHeap(mHeap, expandSize, -alignment);
if (mem == nullptr) {
mMountMode = 0;
} else {
arcHeader = (SArcHeader*)mem;
JKRDecompress((u8*)buf, (u8*)mem, expandSize, 0);
JKRFreeToSysHeap(buf);
mArcInfoBlock = (SArcDataInfo*)JKRAllocFromHeap(
mHeap, arcHeader->file_data_offset + mSizeOfMemPart, alignment);
if (mArcInfoBlock == nullptr) {
mMountMode = 0;
} else {
// arcHeader + 1 should lead to 0x20, which is the data after the
// header
JKRHeap::copyMemory((u8*)mArcInfoBlock, arcHeader + 1,
(arcHeader->file_data_offset + mSizeOfMemPart));
_60 = (u32)mArcInfoBlock + arcHeader->file_data_offset;
if (mSizeOfAramPart != 0) {
mAramPart = JKRAllocFromAram(mSizeOfAramPart, JKRAramHeap::Head);
if (mAramPart == nullptr) {
mMountMode = 0;
} else {
JKRMainRamToAram((u8*)mem + arcHeader->header_length + arcHeader->file_data_offset +
mSizeOfMemPart,
mAramPart->getAddress(), mSizeOfAramPart, EXPAND_SWITCH_DEFAULT, 0,
nullptr, -1, nullptr);
}
}
}
}
}
mDirectories = (SDIDirEntry*)((u32)mArcInfoBlock + mArcInfoBlock->node_offset);
mFileEntries = (SDIFileEntry*)((u32)mArcInfoBlock + mArcInfoBlock->file_entry_offset);
mStrTable = (const char*)((u32)mArcInfoBlock + mArcInfoBlock->string_table_offset);
_68 = arcHeader->header_length + arcHeader->file_data_offset;
break;
}
else {
arcHeader = (SArcHeader*)mem;
JKRDecompress((u8*)buf, (u8*)mem, expandSize, 0);
JKRFreeToSysHeap(buf);
}
mArcInfoBlock = (SArcDataInfo*)JKRAllocFromHeap(
mHeap, arcHeader->file_data_offset + mSizeOfMemPart, alignment);
if (mArcInfoBlock == nullptr) {
mMountMode = 0;
}
else {
// arcHeader + 1 should lead to 0x20, which is the data after the
// header
JKRHeap::copyMemory(
(u8*)mArcInfoBlock, arcHeader + 1,
(arcHeader->file_data_offset + mSizeOfMemPart));
_60 = (u32)mArcInfoBlock + arcHeader->file_data_offset;
if (mSizeOfAramPart != 0) {
mAramPart =
JKRAllocFromAram(mSizeOfAramPart, JKRAramHeap::Head);
if (mAramPart == nullptr) {
mMountMode = 0;
}
else {
JKRMainRamToAram(
(u8*)mem + arcHeader->header_length +
arcHeader->file_data_offset + mSizeOfMemPart,
mAramPart->getAddress(), mSizeOfAramPart,
EXPAND_SWITCH_DEFAULT, 0, nullptr, -1, nullptr);
}
}
}
if (arcHeader) {
JKRFreeToHeap(mHeap, arcHeader);
}
if (mMountMode == 0) {
JREPORTF(0, ":::[%s: %d] Cannot alloc memory in mounting CompArchive\n", __FILE__, 567); // Macro?
if (mDvdFile) {
delete mDvdFile;
mDvdFile = nullptr;
}
}
mDirectories =
(SDIDirEntry*)((u32)mArcInfoBlock + mArcInfoBlock->node_offset);
mFileEntries = (SDIFileEntry*)((u32)mArcInfoBlock +
mArcInfoBlock->file_entry_offset);
mStrTable = (const char*)((u32)mArcInfoBlock +
mArcInfoBlock->string_table_offset);
_68 = arcHeader->header_length + arcHeader->file_data_offset;
break;
}
}
if (arcHeader) {
JKRFreeToHeap(mHeap, arcHeader);
}
if (mMountMode == 0) {
JREPORTF(0, ":::[%s: %d] Cannot alloc memory in mounting CompArchive\n",
__FILE__, 567); // Macro?
if (mDvdFile) {
delete mDvdFile;
mDvdFile = nullptr;
}
}
return mMountMode != 0;
return mMountMode != 0;
}
void* JKRCompArchive::fetchResource(SDIFileEntry* fileEntry, u32* pSize) {
JUT_ASSERT(isMounted());
JUT_ASSERT(isMounted());
u32 ptrSize;
u32 ptrSize;
if (fileEntry->mData == nullptr) {
u32 flag = fileEntry->mFlag >> 0x18;
if (flag & 0x10) {
fileEntry->mData = (void*)(_60 + fileEntry->mDataOffset);
if (pSize) *pSize = fileEntry->mSize;
if (fileEntry->mData == nullptr) {
u32 flag = fileEntry->mFlag >> 0x18;
if (flag & 0x10) {
fileEntry->mData = (void*)(_60 + fileEntry->mDataOffset);
if (pSize)
*pSize = fileEntry->mSize;
} else if (flag & 0x20) {
u32 address = mAramPart->getAddress();
int compression = JKRConvertAttrToCompressionType(fileEntry->mFlag >> 0x18);
u8* data;
u32 size = JKRAramArchive::fetchResource_subroutine(fileEntry->mDataOffset + address - mSizeOfMemPart,
fileEntry->mSize, mHeap, compression, &data);
if (pSize)
*pSize = size;
fileEntry->mData = data;
} else if (flag & 0x40) {
int compression = JKRConvertAttrToCompressionType(fileEntry->mFlag >> 0x18);
u8* data;
u32 size = JKRDvdArchive::fetchResource_subroutine(
mEntryNum, _68 + fileEntry->mDataOffset, fileEntry->mSize, mHeap, compression, mCompression, &data);
if (pSize)
*pSize = size;
fileEntry->mData = data;
}
} else if (pSize) {
*pSize = fileEntry->mSize;
}
else if (flag & 0x20) {
u32 address = mAramPart->getAddress();
int compression =
JKRConvertAttrToCompressionType(fileEntry->mFlag >> 0x18);
u8* data;
u32 size = JKRAramArchive::fetchResource_subroutine(
fileEntry->mDataOffset + address - mSizeOfMemPart, fileEntry->mSize,
mHeap, compression, &data);
if (pSize) *pSize = size;
fileEntry->mData = data;
}
else if (flag & 0x40) {
int compression =
JKRConvertAttrToCompressionType(fileEntry->mFlag >> 0x18);
u8* data;
u32 size = JKRDvdArchive::fetchResource_subroutine(
mEntryNum, _68 + fileEntry->mDataOffset, fileEntry->mSize, mHeap,
compression, mCompression, &data);
if (pSize) *pSize = size;
fileEntry->mData = data;
}
}
else if (pSize) {
*pSize = fileEntry->mSize;
}
return fileEntry->mData;
return fileEntry->mData;
}
void* JKRCompArchive::fetchResource(void* data, u32 compressedSize,
SDIFileEntry* fileEntry, u32* pSize,
JKRExpandSwitch expandSwitch) {
// u32 size = 0;
JUT_ASSERT(isMounted());
void* JKRCompArchive::fetchResource(void* data, u32 compressedSize, SDIFileEntry* fileEntry, u32* pSize,
JKRExpandSwitch expandSwitch) {
// u32 size = 0;
JUT_ASSERT(isMounted());
u32 size = ALIGN_NEXT(fileEntry->mSize, 32);
u32 expandSize = 0;
u32 size = ALIGN_NEXT(fileEntry->mSize, 32);
u32 expandSize = 0;
if (size == 0) JPANIC(651, ":::bad resource size. size = 0\n");
if (size == 0)
JPANIC(651, ":::bad resource size. size = 0\n");
if (fileEntry->mData) {
if (size > (compressedSize & ~31)) {
size = (compressedSize & ~31);
if (fileEntry->mData) {
if (size > (compressedSize & ~31)) {
size = (compressedSize & ~31);
}
JKRHeap::copyMemory(data, fileEntry->mData, size);
expandSize = size;
} else {
u32 fileFlag = fileEntry->mFlag >> 0x18;
int compression = JKRConvertAttrToCompressionType(fileFlag);
if (expandSwitch != EXPAND_SWITCH_DECOMPRESS)
compression = 0;
if (fileFlag & 0x10) {
if (size > (compressedSize & ~31)) {
size = (compressedSize & ~31);
}
if (FLAG_ON(fileFlag, 4)) {
JKRHeap::copyMemory(data, (void*)(_60 + fileEntry->mDataOffset), size);
} else {
u8* header = (u8*)(_60 + fileEntry->mDataOffset);
expandSize = JKRDecompExpandSize(header);
expandSize = (expandSize > compressedSize) ? compressedSize : expandSize;
JKRDecompress(header, (u8*)data, expandSize, 0);
}
expandSize = JKRMemArchive::fetchResource_subroutine((u8*)(_60 + fileEntry->mDataOffset), size, (u8*)data,
compressedSize, compression);
} else if (fileFlag & 0x20) {
expandSize = JKRAramArchive::fetchResource_subroutine(fileEntry->mDataOffset + mAramPart->getAddress() -
mSizeOfMemPart,
size, (u8*)data, compressedSize, compression);
} else if (fileFlag & 0x40) {
expandSize = JKRDvdArchive::fetchResource_subroutine(mEntryNum, _68 + fileEntry->mDataOffset, size,
(u8*)data, compressedSize, compression, mCompression);
} else {
JPANIC(731, ":::CompArchive: bad mode.");
}
}
JKRHeap::copyMemory(data, fileEntry->mData, size);
expandSize = size;
}
else {
u32 fileFlag = fileEntry->mFlag >> 0x18;
int compression = JKRConvertAttrToCompressionType(fileFlag);
if (expandSwitch != EXPAND_SWITCH_DECOMPRESS) compression = 0;
if (fileFlag & 0x10) {
if (size > (compressedSize & ~31)) {
size = (compressedSize & ~31);
}
if (FLAG_ON(fileFlag, 4)) {
JKRHeap::copyMemory(data, (void*)(_60 + fileEntry->mDataOffset), size);
}
else {
u8* header = (u8*)(_60 + fileEntry->mDataOffset);
expandSize = JKRDecompExpandSize(header);
expandSize =
(expandSize > compressedSize) ? compressedSize : expandSize;
JKRDecompress(header, (u8*)data, expandSize, 0);
}
expandSize = JKRMemArchive::fetchResource_subroutine(
(u8*)(_60 + fileEntry->mDataOffset), size, (u8*)data,
compressedSize, compression);
if (pSize) {
*pSize = expandSize;
}
else if (fileFlag & 0x20) {
expandSize = JKRAramArchive::fetchResource_subroutine(
fileEntry->mDataOffset + mAramPart->getAddress() - mSizeOfMemPart,
size, (u8*)data, compressedSize, compression);
}
else if (fileFlag & 0x40) {
expandSize = JKRDvdArchive::fetchResource_subroutine(
mEntryNum, _68 + fileEntry->mDataOffset, size, (u8*)data,
compressedSize, compression, mCompression);
}
else {
JPANIC(731, ":::CompArchive: bad mode.");
}
}
if (pSize) {
*pSize = expandSize;
}
return data;
return data;
}
void JKRCompArchive::removeResourceAll() {
if (mArcInfoBlock && mMountMode != MOUNT_MEM) {
SDIFileEntry* fileEntry = mFileEntries;
for (int i = 0; i < mArcInfoBlock->num_file_entries; i++) {
u32 flag = fileEntry->mFlag >> 0x18;
if (fileEntry->mData) {
if ((flag & 0x10) == 0) {
JKRFreeToHeap(mHeap, fileEntry->mData);
}
if (mArcInfoBlock && mMountMode != MOUNT_MEM) {
SDIFileEntry* fileEntry = mFileEntries;
for (int i = 0; i < mArcInfoBlock->num_file_entries; i++) {
u32 flag = fileEntry->mFlag >> 0x18;
if (fileEntry->mData) {
if ((flag & 0x10) == 0) {
JKRFreeToHeap(mHeap, fileEntry->mData);
}
fileEntry->mData = nullptr;
}
fileEntry->mData = nullptr;
}
}
}
}
}
bool JKRCompArchive::removeResource(void* resource) {
SDIFileEntry* fileEntry = findPtrResource(resource);
if (!fileEntry) return false;
SDIFileEntry* fileEntry = findPtrResource(resource);
if (!fileEntry)
return false;
if (((fileEntry->mFlag >> 0x18) & 0x10) == 0) {
JKRFreeToHeap(mHeap, resource);
}
if (((fileEntry->mFlag >> 0x18) & 0x10) == 0) {
JKRFreeToHeap(mHeap, resource);
}
fileEntry->mData = nullptr;
return true;
fileEntry->mData = nullptr;
return true;
}
+203 -218
View File
@@ -11,281 +11,266 @@ OSMessageQueue JKRDecomp::sMessageQueue = { 0 };
JKRDecomp* JKRDecomp::sDecompObject;
JKRDecomp* JKRDecomp::create(s32 decompPriority) {
if (JKRDecomp::sDecompObject == nullptr) {
JKRDecomp::sDecompObject =
new (JKRGetSystemHeap(), 0) JKRDecomp(decompPriority);
}
if (JKRDecomp::sDecompObject == nullptr) {
JKRDecomp::sDecompObject = new (JKRGetSystemHeap(), 0) JKRDecomp(decompPriority);
}
return JKRDecomp::sDecompObject;
return JKRDecomp::sDecompObject;
}
JKRDecomp::JKRDecomp(s32 priority)
: JKRThread(JKRDECOMP_STACK_SIZE, JKRDECOMP_THREAD_MSG_BUF_COUNT,
priority) {
OSResumeThread(this->mThreadRecord);
JKRDecomp::JKRDecomp(s32 priority) : JKRThread(JKRDECOMP_STACK_SIZE, JKRDECOMP_THREAD_MSG_BUF_COUNT, priority) {
OSResumeThread(this->mThreadRecord);
}
JKRDecomp::~JKRDecomp() {}
JKRDecomp::~JKRDecomp() {
}
void* JKRDecomp::run() {
OSMessage recMesg;
JKRDecompCommand* cmd;
OSInitMessageQueue(&JKRDecomp::sMessageQueue, JKRDecomp::sMessageBuffer,
JKRDECOMP_MSG_BUF_COUNT);
OSMessage recMesg;
JKRDecompCommand* cmd;
OSInitMessageQueue(&JKRDecomp::sMessageQueue, JKRDecomp::sMessageBuffer, JKRDECOMP_MSG_BUF_COUNT);
while (true) {
while (true) {
while (true) {
OSReceiveMessage(&JKRDecomp::sMessageQueue, &recMesg, OS_MESSAGE_BLOCK);
cmd = static_cast<JKRDecompCommand*>(recMesg);
JKRDecomp::decode(cmd->mSrcBuffer, cmd->mDstBuffer, cmd->mSrcLength,
cmd->mSkipCount);
while (true) {
while (true) {
OSReceiveMessage(&JKRDecomp::sMessageQueue, &recMesg, OS_MESSAGE_BLOCK);
cmd = static_cast<JKRDecompCommand*>(recMesg);
JKRDecomp::decode(cmd->mSrcBuffer, cmd->mDstBuffer, cmd->mSrcLength, cmd->mSkipCount);
if (cmd->transferType == JKRDecompCommand::MRAM) {
break;
if (cmd->transferType == JKRDecompCommand::MRAM) {
break;
}
if (cmd->transferType == JKRDecompCommand::ARAM) {
JKRAramPcs_SendCommand(cmd->mAMCommand);
}
}
if (cmd->mCallback == nullptr) {
break;
}
cmd->mCallback((u32)cmd);
}
if (cmd->transferType == JKRDecompCommand::ARAM) {
JKRAramPcs_SendCommand(cmd->mAMCommand);
if (cmd->pMesgQueue1C != nullptr) {
OSSendMessage(cmd->pMesgQueue1C, (OSMessage)1, OS_MESSAGE_NOBLOCK);
} else {
OSSendMessage(&cmd->mMesgQueue, (OSMessage)1, OS_MESSAGE_NOBLOCK);
}
}
if (cmd->mCallback == nullptr) {
break;
}
cmd->mCallback((u32)cmd);
}
if (cmd->pMesgQueue1C != nullptr) {
OSSendMessage(cmd->pMesgQueue1C, (OSMessage)1, OS_MESSAGE_NOBLOCK);
}
else {
OSSendMessage(&cmd->mMesgQueue, (OSMessage)1, OS_MESSAGE_NOBLOCK);
}
}
}
JKRDecompCommand* JKRDecomp::prepareCommand(u8* srcBuffer, u8* dstBuffer,
u32 srcLength, u32 skipCount,
DecompCallback* callback) {
JKRDecompCommand* cmd = new (JKRGetSystemHeap(), -4) JKRDecompCommand();
JKRDecompCommand* JKRDecomp::prepareCommand(u8* srcBuffer, u8* dstBuffer, u32 srcLength, u32 skipCount,
DecompCallback* callback) {
JKRDecompCommand* cmd = new (JKRGetSystemHeap(), -4) JKRDecompCommand();
cmd->mSrcBuffer = srcBuffer;
cmd->mDstBuffer = dstBuffer;
cmd->mSrcLength = srcLength;
cmd->mSkipCount = skipCount;
cmd->mCallback = callback;
cmd->mSrcBuffer = srcBuffer;
cmd->mDstBuffer = dstBuffer;
cmd->mSrcLength = srcLength;
cmd->mSkipCount = skipCount;
cmd->mCallback = callback;
return cmd;
return cmd;
}
BOOL JKRDecomp::sendCommand(JKRDecompCommand* cmd) {
BOOL res = OSSendMessage(&JKRDecomp::sMessageQueue, (OSMessage)cmd,
OS_MESSAGE_BLOCK);
BOOL res = OSSendMessage(&JKRDecomp::sMessageQueue, (OSMessage)cmd, OS_MESSAGE_BLOCK);
#ifdef JSYSTEM_DEBUG
if (res == FALSE) {
JPANIC(142, "Decomp MesgBuf FULL!");
}
if (res == FALSE) {
JPANIC(142, "Decomp MesgBuf FULL!");
}
#endif
return res;
return res;
}
JKRDecompCommand* JKRDecomp::orderAsync(u8* srcBuffer, u8* dstBuffer,
u32 srcLength, u32 skipCount,
DecompCallback* callback) {
JKRDecompCommand* cmd = JKRDecomp::prepareCommand(
srcBuffer, dstBuffer, srcLength, skipCount, callback);
JKRDecomp::sendCommand(cmd);
return cmd;
JKRDecompCommand* JKRDecomp::orderAsync(u8* srcBuffer, u8* dstBuffer, u32 srcLength, u32 skipCount,
DecompCallback* callback) {
JKRDecompCommand* cmd = JKRDecomp::prepareCommand(srcBuffer, dstBuffer, srcLength, skipCount, callback);
JKRDecomp::sendCommand(cmd);
return cmd;
}
bool JKRDecomp::sync(JKRDecompCommand* cmd, BOOL noBlock) {
OSMessage msg;
OSMessage msg;
if (!noBlock) {
OSReceiveMessage(&cmd->mMesgQueue, &msg, OS_MESSAGE_BLOCK);
return true;
}
else {
return OSReceiveMessage(&cmd->mMesgQueue, &msg, OS_MESSAGE_NOBLOCK) !=
FALSE;
}
if (!noBlock) {
OSReceiveMessage(&cmd->mMesgQueue, &msg, OS_MESSAGE_BLOCK);
return true;
} else {
return OSReceiveMessage(&cmd->mMesgQueue, &msg, OS_MESSAGE_NOBLOCK) != FALSE;
}
}
bool JKRDecomp::orderSync(u8* srcBuffer, u8* dstBuffer, u32 srcLength,
u32 skipCount) {
JKRDecompCommand* cmd = JKRDecomp::orderAsync(srcBuffer, dstBuffer, srcLength,
skipCount, nullptr);
bool res = JKRDecomp::sync(cmd, FALSE);
delete cmd;
return res;
bool JKRDecomp::orderSync(u8* srcBuffer, u8* dstBuffer, u32 srcLength, u32 skipCount) {
JKRDecompCommand* cmd = JKRDecomp::orderAsync(srcBuffer, dstBuffer, srcLength, skipCount, nullptr);
bool res = JKRDecomp::sync(cmd, FALSE);
delete cmd;
return res;
}
void JKRDecomp::decode(u8* srcBuffer, u8* dstBuffer, u32 srcLength,
u32 skipCount) {
CompressionMode mode = JKRDecomp::checkCompressed(srcBuffer);
if (mode == SZP) {
JKRDecomp::decodeSZP(srcBuffer, dstBuffer, srcLength, skipCount);
}
else if (mode == SZS) {
JKRDecomp::decodeSZS(srcBuffer, dstBuffer, srcLength, skipCount);
}
void JKRDecomp::decode(u8* srcBuffer, u8* dstBuffer, u32 srcLength, u32 skipCount) {
CompressionMode mode = JKRDecomp::checkCompressed(srcBuffer);
if (mode == SZP) {
JKRDecomp::decodeSZP(srcBuffer, dstBuffer, srcLength, skipCount);
} else if (mode == SZS) {
JKRDecomp::decodeSZS(srcBuffer, dstBuffer, srcLength, skipCount);
}
}
void JKRDecomp::decodeSZP(u8* src, u8* dst, u32 srcLength, u32 skipCount) {
int srcChunkOffset;
int count;
int dstOffset;
u32 length;
int linkInfo;
int offset;
int i;
int srcChunkOffset;
int count;
int dstOffset;
u32 length;
int linkInfo;
int offset;
int i;
int decodedSize = JKRDECOMP_READU32BE(src, 4);
int linkTableOffset = JKRDECOMP_READU32BE(src, 8);
int srcDataOffset = JKRDECOMP_READU32BE(src, 12);
int decodedSize = JKRDECOMP_READU32BE(src, 4);
int linkTableOffset = JKRDECOMP_READU32BE(src, 8);
int srcDataOffset = JKRDECOMP_READU32BE(src, 12);
dstOffset = 0;
u32 counter =
0; // curently counter gets assembled before the READ_U32 operations
srcChunkOffset = 16;
dstOffset = 0;
u32 counter = 0; // curently counter gets assembled before the READ_U32 operations
srcChunkOffset = 16;
u32 chunkBits;
if (srcLength == 0) return;
if (skipCount > decodedSize) return;
u32 chunkBits;
if (srcLength == 0)
return;
if (skipCount > decodedSize)
return;
length = srcLength;
do {
if (counter == 0) {
chunkBits = JKRDECOMP_READU32BE(src, srcChunkOffset);
srcChunkOffset += sizeof(u32);
counter = sizeof(u32) * 8;
}
if (chunkBits & 0x80000000) {
if (skipCount == 0) {
dst[dstOffset] = src[srcDataOffset];
length--;
if (length == 0) return;
}
else {
skipCount--;
}
dstOffset++;
srcDataOffset++;
}
else {
linkInfo = src[linkTableOffset] << 8 | src[linkTableOffset + 1];
linkTableOffset += sizeof(u16);
offset = dstOffset - (linkInfo & 0xFFF);
count = (linkInfo >> 12);
if (count == 0) {
count = (u32)src[srcDataOffset++] + 0x12;
}
else
count += 2;
if ((int)count > decodedSize - dstOffset) count = decodedSize - dstOffset;
for (i = 0; i < (int)count; i++, dstOffset++, offset++) {
if (skipCount == 0) {
dst[dstOffset] = dst[offset - 1];
length--;
if (length == 0) return;
length = srcLength;
do {
if (counter == 0) {
chunkBits = JKRDECOMP_READU32BE(src, srcChunkOffset);
srcChunkOffset += sizeof(u32);
counter = sizeof(u32) * 8;
}
else
skipCount--;
}
}
chunkBits <<= 1;
counter--;
} while (dstOffset < decodedSize);
if (chunkBits & 0x80000000) {
if (skipCount == 0) {
dst[dstOffset] = src[srcDataOffset];
length--;
if (length == 0)
return;
} else {
skipCount--;
}
dstOffset++;
srcDataOffset++;
} else {
linkInfo = src[linkTableOffset] << 8 | src[linkTableOffset + 1];
linkTableOffset += sizeof(u16);
offset = dstOffset - (linkInfo & 0xFFF);
count = (linkInfo >> 12);
if (count == 0) {
count = (u32)src[srcDataOffset++] + 0x12;
} else
count += 2;
if ((int)count > decodedSize - dstOffset)
count = decodedSize - dstOffset;
for (i = 0; i < (int)count; i++, dstOffset++, offset++) {
if (skipCount == 0) {
dst[dstOffset] = dst[offset - 1];
length--;
if (length == 0)
return;
} else
skipCount--;
}
}
chunkBits <<= 1;
counter--;
} while (dstOffset < decodedSize);
}
void JKRDecomp::decodeSZS(u8* src_buffer, u8* dst_buffer, u32 srcSize,
u32 skipCount) {
u8* decompEnd = dst_buffer + *(u32*)(src_buffer + 4) - skipCount;
u8* copyStart;
s32 copyByteCount;
s32 chunkBitsLeft = 0;
s32 chunkBits;
void JKRDecomp::decodeSZS(u8* src_buffer, u8* dst_buffer, u32 srcSize, u32 skipCount) {
u8* decompEnd = dst_buffer + *(u32*)(src_buffer + 4) - skipCount;
u8* copyStart;
s32 copyByteCount;
s32 chunkBitsLeft = 0;
s32 chunkBits;
if (srcSize == 0) return;
if (skipCount > *(u32*)src_buffer) return;
if (srcSize == 0)
return;
if (skipCount > *(u32*)src_buffer)
return;
u8* curSrcPos = src_buffer + 0x10;
do {
if (chunkBitsLeft == 0) {
chunkBits = *curSrcPos++;
chunkBitsLeft = 8;
}
if ((chunkBits & 0x80) != 0) {
if (skipCount == 0) {
*dst_buffer = *curSrcPos;
srcSize--;
dst_buffer++;
if (srcSize == 0) return;
}
else {
skipCount--;
}
curSrcPos++;
}
else {
u8 curVal = *curSrcPos;
copyStart = dst_buffer - (curSrcPos[1] | (curVal & 0xF) << 8);
curSrcPos += 2;
if (curVal >> 4 == 0) {
copyByteCount = *curSrcPos + 0x12;
curSrcPos++;
}
else {
copyByteCount = (curVal >> 4) + 2;
}
do {
if (skipCount == 0) {
*dst_buffer = *(copyStart - 1);
srcSize--;
dst_buffer++;
if (srcSize == 0) return;
u8* curSrcPos = src_buffer + 0x10;
do {
if (chunkBitsLeft == 0) {
chunkBits = *curSrcPos++;
chunkBitsLeft = 8;
}
else {
skipCount--;
if ((chunkBits & 0x80) != 0) {
if (skipCount == 0) {
*dst_buffer = *curSrcPos;
srcSize--;
dst_buffer++;
if (srcSize == 0)
return;
} else {
skipCount--;
}
curSrcPos++;
} else {
u8 curVal = *curSrcPos;
copyStart = dst_buffer - (curSrcPos[1] | (curVal & 0xF) << 8);
curSrcPos += 2;
if (curVal >> 4 == 0) {
copyByteCount = *curSrcPos + 0x12;
curSrcPos++;
} else {
copyByteCount = (curVal >> 4) + 2;
}
do {
if (skipCount == 0) {
*dst_buffer = *(copyStart - 1);
srcSize--;
dst_buffer++;
if (srcSize == 0)
return;
} else {
skipCount--;
}
copyByteCount--;
copyStart++;
} while (copyByteCount != 0);
}
copyByteCount--;
copyStart++;
} while (copyByteCount != 0);
}
chunkBits <<= 1;
chunkBitsLeft--;
} while (dst_buffer != decompEnd);
chunkBits <<= 1;
chunkBitsLeft--;
} while (dst_buffer != decompEnd);
}
JKRDecomp::CompressionMode JKRDecomp::checkCompressed(u8* buf) {
if (buf[0] == 'Y' && buf[1] == 'a' && buf[3] == '0') {
if (buf[2] == 'y') {
return SZP;
if (buf[0] == 'Y' && buf[1] == 'a' && buf[3] == '0') {
if (buf[2] == 'y') {
return SZP;
}
if (buf[2] == 'z') {
return SZS;
}
}
if (buf[2] == 'z') {
return SZS;
}
}
return NONE;
return NONE;
}
JKRDecompCommand::JKRDecompCommand() {
OSInitMessageQueue(&this->mMesgQueue, this->mMesgBuffer, 1);
this->mCallback = nullptr;
this->pMesgQueue1C = nullptr;
this->mCmd = this;
this->transferType = MRAM;
OSInitMessageQueue(&this->mMesgQueue, this->mMesgBuffer, 1);
this->mCallback = nullptr;
this->pMesgQueue1C = nullptr;
this->mCmd = this;
this->transferType = MRAM;
}
JKRDecompCommand::~JKRDecompCommand() {}
JKRDecompCommand::~JKRDecompCommand() {
}
+7 -7
View File
@@ -3,14 +3,14 @@
#include "JSystem/JKernel/JKRHeap.h"
JKRDisposer::JKRDisposer() : mPointerLinks(this) {
this->mRootHeap = JKRHeap::findFromRoot(this);
if (this->mRootHeap != nullptr) {
this->mRootHeap->appendDisposer(this);
}
this->mRootHeap = JKRHeap::findFromRoot(this);
if (this->mRootHeap != nullptr) {
this->mRootHeap->appendDisposer(this);
}
}
JKRDisposer::~JKRDisposer() {
if (this->mRootHeap != nullptr) {
this->mRootHeap->removeDisposer(this);
}
if (this->mRootHeap != nullptr) {
this->mRootHeap->removeDisposer(this);
}
}
+284 -282
View File
@@ -14,193 +14,181 @@ JSUList<JKRADCommand> JKRDvdAramRipper::sDvdAramAsyncList;
bool JKRDvdAramRipper::errorRetry = true;
int JKRDvdAramRipper::sSZSBufferSize = 0x400;
JKRAramBlock* JKRDvdAramRipper::loadToAram(s32 entrynum, u32 p2,
JKRExpandSwitch expSwitch, u32 p6,
u32 p7) {
JKRDvdFile dvdFile;
if (!dvdFile.open(entrynum))
return nullptr;
else
return loadToAram(&dvdFile, p2, expSwitch, p6, p7);
JKRAramBlock* JKRDvdAramRipper::loadToAram(s32 entrynum, u32 p2, JKRExpandSwitch expSwitch, u32 p6, u32 p7) {
JKRDvdFile dvdFile;
if (!dvdFile.open(entrynum))
return nullptr;
else
return loadToAram(&dvdFile, p2, expSwitch, p6, p7);
}
JKRAramBlock* JKRDvdAramRipper::loadToAram(JKRDvdFile* dvdFile, u32 p1,
JKRExpandSwitch p2, u32 p3, u32 p4) {
JKRADCommand* command = loadToAram_Async(dvdFile, p1, p2, nullptr, p3, p4);
syncAram(command, 0);
JKRAramBlock* JKRDvdAramRipper::loadToAram(JKRDvdFile* dvdFile, u32 p1, JKRExpandSwitch p2, u32 p3, u32 p4) {
JKRADCommand* command = loadToAram_Async(dvdFile, p1, p2, nullptr, p3, p4);
syncAram(command, 0);
if (p1) {
if (p1) {
delete command;
return (JKRAramBlock*)-1;
}
JKRAramBlock* result = command->mBlock;
delete command;
return (JKRAramBlock*)-1;
}
JKRAramBlock* result = command->mBlock;
delete command;
return result;
return result;
}
JKRADCommand* JKRDvdAramRipper::loadToAram_Async(JKRDvdFile* dvdFile, u32 p1,
JKRExpandSwitch expSwitch,
JKRADCommand::LoadCallback cb,
u32 p4, u32 p5) {
JKRADCommand* command = new (JKRGetSystemHeap(), -4) JKRADCommand();
command->mDvdFile = dvdFile;
command->_1C = p1;
command->mBlock = nullptr;
command->mExpandSwitch = expSwitch;
command->mCallBack = cb;
JKRADCommand* JKRDvdAramRipper::loadToAram_Async(JKRDvdFile* dvdFile, u32 p1, JKRExpandSwitch expSwitch,
JKRADCommand::LoadCallback cb, u32 p4, u32 p5) {
JKRADCommand* command = new (JKRGetSystemHeap(), -4) JKRADCommand();
command->mDvdFile = dvdFile;
command->_1C = p1;
command->mBlock = nullptr;
command->mExpandSwitch = expSwitch;
command->mCallBack = cb;
command->_14 = p4;
command->_18 = p5;
command->_14 = p4;
command->_18 = p5;
if (!callCommand_Async(command)) {
delete command;
return nullptr;
}
if (!callCommand_Async(command)) {
delete command;
return nullptr;
}
return command;
return command;
}
JKRADCommand* JKRDvdAramRipper::callCommand_Async(JKRADCommand* command) {
bool isCmdTrdNull = true;
JKRDvdFile* dvdFile = command->mDvdFile;
int compression = JKRCOMPRESSION_NONE;
OSLockMutex(&dvdFile->mAramMutex);
bool isCmdTrdNull = true;
JKRDvdFile* dvdFile = command->mDvdFile;
int compression = JKRCOMPRESSION_NONE;
OSLockMutex(&dvdFile->mAramMutex);
s32 uncompressedSize;
s32 uncompressedSize;
if (dvdFile->mAramThread) {
isCmdTrdNull = false;
}
else {
dvdFile->mAramThread = OSGetCurrentThread();
JSUFileInputStream* stream =
new (JKRGetSystemHeap(), -4) JSUFileInputStream(dvdFile);
dvdFile->mInputStream = stream;
u32 fileSize = dvdFile->getFileSize();
if (command->_18 && fileSize > command->_18) {
fileSize = command->_18;
}
fileSize = ALIGN_NEXT(fileSize, 0x20);
if (command->mExpandSwitch == EXPAND_SWITCH_DECOMPRESS) {
u8 buffer[0x40];
u8* bufPtr = (u8*)ALIGN_NEXT((u32)buffer, 0x20);
while (true) {
if (DVDReadPrio(dvdFile->getFileInfo(), bufPtr, 0x20, 0, 2) >= 0) {
break;
if (dvdFile->mAramThread) {
isCmdTrdNull = false;
} else {
dvdFile->mAramThread = OSGetCurrentThread();
JSUFileInputStream* stream = new (JKRGetSystemHeap(), -4) JSUFileInputStream(dvdFile);
dvdFile->mInputStream = stream;
u32 fileSize = dvdFile->getFileSize();
if (command->_18 && fileSize > command->_18) {
fileSize = command->_18;
}
fileSize = ALIGN_NEXT(fileSize, 0x20);
if (command->mExpandSwitch == EXPAND_SWITCH_DECOMPRESS) {
u8 buffer[0x40];
u8* bufPtr = (u8*)ALIGN_NEXT((u32)buffer, 0x20);
while (true) {
if (DVDReadPrio(dvdFile->getFileInfo(), bufPtr, 0x20, 0, 2) >= 0) {
break;
}
if (errorRetry == false) {
delete stream;
return nullptr;
}
VIWaitForRetrace();
}
compression = JKRCheckCompressed(bufPtr);
u32 expSize = JKRDecompExpandSize(bufPtr);
uncompressedSize = expSize;
if ((command->_18 != 0) && expSize > command->_18) {
uncompressedSize = command->_18;
}
}
if (errorRetry == false) {
delete stream;
return nullptr;
if (compression == JKRCOMPRESSION_NONE) {
command->mExpandSwitch = EXPAND_SWITCH_DEFAULT;
}
VIWaitForRetrace();
}
if (command->mExpandSwitch == EXPAND_SWITCH_DECOMPRESS) {
if (command->_1C == 0 && command->mBlock == nullptr) {
command->mBlock = JKRAram::getAramHeap()->alloc(uncompressedSize, JKRAramHeap::Head);
if (command->mBlock) {
command->_1C = command->mBlock->mAddress;
}
dvdFile->mAramBlock = command->mBlock;
}
compression = JKRCheckCompressed(bufPtr);
u32 expSize = JKRDecompExpandSize(bufPtr);
uncompressedSize = expSize;
if (command->mBlock) {
command->_1C = command->mBlock->mAddress;
}
if ((command->_18 != 0) && expSize > command->_18) {
uncompressedSize = command->_18;
}
}
if (command->_1C == 0) {
dvdFile->mAramThread = nullptr;
return nullptr;
}
} else {
if (command->_1C == 0 && !command->mBlock) {
command->mBlock = JKRAram::getAramHeap()->alloc(fileSize, JKRAramHeap::Head);
}
if (compression == JKRCOMPRESSION_NONE) {
command->mExpandSwitch = EXPAND_SWITCH_DEFAULT;
}
if (command->mBlock) {
command->_1C = command->mBlock->mAddress;
}
if (command->mExpandSwitch == EXPAND_SWITCH_DECOMPRESS) {
if (command->_1C == 0 && command->mBlock == nullptr) {
command->mBlock =
JKRAram::getAramHeap()->alloc(uncompressedSize, JKRAramHeap::Head);
if (command->mBlock) {
command->_1C = command->mBlock->mAddress;
if (command->_1C == 0) {
dvdFile->mAramThread = nullptr;
return nullptr;
}
}
dvdFile->mAramBlock = command->mBlock;
}
if (command->mBlock) {
command->_1C = command->mBlock->mAddress;
}
if (compression == 0) {
command->mStreamCommand =
JKRAramStream::write_StreamToAram_Async(stream, command->_1C, fileSize - command->_14, command->_14);
} else if (compression == JKRCOMPRESSION_YAY0) {
command->mStreamCommand =
JKRAramStream::write_StreamToAram_Async(stream, command->_1C, fileSize - command->_14, command->_14);
} else if (compression == JKRCOMPRESSION_YAZ0) {
command->mStreamCommand = nullptr;
JKRDecompressFromDVDToAram(command->mDvdFile, command->_1C, fileSize, uncompressedSize, command->_14, 0);
}
if (command->_1C == 0) {
dvdFile->mAramThread = nullptr;
return nullptr;
}
}
else {
if (command->_1C == 0 && !command->mBlock) {
command->mBlock =
JKRAram::getAramHeap()->alloc(fileSize, JKRAramHeap::Head);
}
if (command->mBlock) {
command->_1C = command->mBlock->mAddress;
}
if (command->_1C == 0) {
dvdFile->mAramThread = nullptr;
return nullptr;
}
if (!command->mCallBack) {
sDvdAramAsyncList.append(&command->mLink);
} else {
command->mCallBack((u32)command);
}
}
if (compression == 0) {
command->mStreamCommand = JKRAramStream::write_StreamToAram_Async(
stream, command->_1C, fileSize - command->_14, command->_14);
}
else if (compression == JKRCOMPRESSION_YAY0) {
command->mStreamCommand = JKRAramStream::write_StreamToAram_Async(
stream, command->_1C, fileSize - command->_14, command->_14);
}
else if (compression == JKRCOMPRESSION_YAZ0) {
command->mStreamCommand = nullptr;
JKRDecompressFromDVDToAram(command->mDvdFile, command->_1C, fileSize,
uncompressedSize, command->_14, 0);
}
if (!command->mCallBack) {
sDvdAramAsyncList.append(&command->mLink);
}
else {
command->mCallBack((u32)command);
}
}
OSUnlockMutex(&dvdFile->mAramMutex);
return isCmdTrdNull == true ? command : nullptr;
OSUnlockMutex(&dvdFile->mAramMutex);
return isCmdTrdNull == true ? command : nullptr;
}
bool JKRDvdAramRipper::syncAram(JKRADCommand* command, int p1) {
JKRDvdFile* dvdFile = command->mDvdFile;
OSLockMutex(&dvdFile->mAramMutex);
JKRDvdFile* dvdFile = command->mDvdFile;
OSLockMutex(&dvdFile->mAramMutex);
if (command->mStreamCommand) {
JKRAramStreamCommand* var1 =
JKRAramStream::sync(command->mStreamCommand, p1);
if (command->mStreamCommand) {
JKRAramStreamCommand* var1 = JKRAramStream::sync(command->mStreamCommand, p1);
if (p1 != 0 && var1 == nullptr) {
OSUnlockMutex(&dvdFile->mAramMutex);
return false;
if (p1 != 0 && var1 == nullptr) {
OSUnlockMutex(&dvdFile->mAramMutex);
return false;
}
}
}
sDvdAramAsyncList.remove(&command->mLink);
if (command->mStreamCommand) {
delete command->mStreamCommand;
}
sDvdAramAsyncList.remove(&command->mLink);
if (command->mStreamCommand) {
delete command->mStreamCommand;
}
delete dvdFile->mInputStream;
dvdFile->mAramThread = nullptr;
OSUnlockMutex(&dvdFile->mAramMutex);
return true;
delete dvdFile->mInputStream;
dvdFile->mAramThread = nullptr;
OSUnlockMutex(&dvdFile->mAramMutex);
return true;
}
JKRADCommand::JKRADCommand() : mLink(this) { _44 = 0; }
JKRADCommand::JKRADCommand() : mLink(this) {
_44 = 0;
}
JKRADCommand::~JKRADCommand() {
if (_44 == 1) delete mDvdFile;
if (_44 == 1)
delete mDvdFile;
}
static OSMutex decompMutex;
@@ -228,175 +216,189 @@ static u8* firstSrcData();
static u8* nextSrcData(u8*);
static u32 dmaBufferFlush(u32);
int JKRDecompressFromDVDToAram(JKRDvdFile* dvdFile, u32 address, u32 fileSize,
u32 _maxDest, u32 _fileOffset, u32 _srcOffset) {
int result = 0;
szpBuf = (u8*)JKRAllocFromSysHeap(SZP_BUFFERSIZE, 32);
JUT_ASSERT(szpBuf != 0);
szpEnd = szpBuf + SZP_BUFFERSIZE;
int JKRDecompressFromDVDToAram(JKRDvdFile* dvdFile, u32 address, u32 fileSize, u32 _maxDest, u32 _fileOffset,
u32 _srcOffset) {
int result = 0;
szpBuf = (u8*)JKRAllocFromSysHeap(SZP_BUFFERSIZE, 32);
JUT_ASSERT(szpBuf != 0);
szpEnd = szpBuf + SZP_BUFFERSIZE;
refBuf = (u8*)JKRAllocFromSysHeap(REF_BUFFERSIZE, 0);
JUT_ASSERT(refBuf != 0);
refEnd = refBuf + REF_BUFFERSIZE;
refCurrent = refBuf;
refBuf = (u8*)JKRAllocFromSysHeap(REF_BUFFERSIZE, 0);
JUT_ASSERT(refBuf != 0);
refEnd = refBuf + REF_BUFFERSIZE;
refCurrent = refBuf;
dmaBuf = (u8*)JKRAllocFromSysHeap(DMA_BUFFERSIZE, 32);
JUT_ASSERT(dmaBuf != 0);
dmaEnd = dmaBuf + DMA_BUFFERSIZE;
dmaCurrent = dmaBuf;
dmaBuf = (u8*)JKRAllocFromSysHeap(DMA_BUFFERSIZE, 32);
JUT_ASSERT(dmaBuf != 0);
dmaEnd = dmaBuf + DMA_BUFFERSIZE;
dmaCurrent = dmaBuf;
srcFile = dvdFile;
srcOffset = _srcOffset;
transLeft = fileSize - _srcOffset;
fileOffset = _fileOffset;
readCount = 0;
maxDest = _maxDest;
srcFile = dvdFile;
srcOffset = _srcOffset;
transLeft = fileSize - _srcOffset;
fileOffset = _fileOffset;
readCount = 0;
maxDest = _maxDest;
u8* first = firstSrcData();
if (first) result = decompSZS_subroutine(first, address);
u8* first = firstSrcData();
if (first)
result = decompSZS_subroutine(first, address);
JKRFree(szpBuf);
JKRFree(refBuf);
JKRFree(dmaBuf);
JKRFree(szpBuf);
JKRFree(refBuf);
JKRFree(dmaBuf);
return result;
return result;
}
int decompSZS_subroutine(u8* src, u32 dmaAddr) {
u32 endPtr;
u8* copySource;
s32 validBitCount = 0;
s32 currCodeByte = 0;
s32 numBytes;
u32 endPtr;
u8* copySource;
s32 validBitCount = 0;
s32 currCodeByte = 0;
s32 numBytes;
u32 dmaStart = dmaAddr;
u32 dmaStart = dmaAddr;
if (src[0] != 'Y' || src[1] != 'a' || src[2] != 'z' || src[3] != '0')
return -1;
if (src[0] != 'Y' || src[1] != 'a' || src[2] != 'z' || src[3] != '0')
return -1;
SYaz0Header* header = (SYaz0Header*)src;
endPtr = dmaAddr + (header->length - fileOffset);
if (endPtr > dmaAddr + maxDest) endPtr = dmaAddr + maxDest;
SYaz0Header* header = (SYaz0Header*)src;
endPtr = dmaAddr + (header->length - fileOffset);
if (endPtr > dmaAddr + maxDest)
endPtr = dmaAddr + maxDest;
src += 0x10;
src += 0x10;
do {
if (validBitCount == 0) {
if ((src > srcLimit) && transLeft) src = nextSrcData(src);
do {
if (validBitCount == 0) {
if ((src > srcLimit) && transLeft)
src = nextSrcData(src);
currCodeByte = *src++;
validBitCount = 8;
}
if (currCodeByte & 0x80) {
if (readCount >= fileOffset) {
dmaAddr++;
*dmaCurrent++ = *src;
if (dmaCurrent == dmaEnd) dmaStart += dmaBufferFlush(dmaStart);
if (dmaAddr == endPtr) break;
}
*(refCurrent++) = *src;
if (refCurrent == refEnd) refCurrent = refBuf;
src++;
readCount++;
}
else {
int t0 = src[0];
int t1 = src[1];
copySource = refCurrent - (t1 | (t0 & 0x0f) << 8) - 1;
numBytes = t0 >> 4;
src += 2;
if (copySource < refBuf) copySource = copySource + (refEnd - refBuf);
if (numBytes == 0)
numBytes = *src++ + 0x12;
else
numBytes += 2;
do {
if (readCount >= fileOffset) {
dmaAddr++;
*(dmaCurrent++) = *copySource;
if (dmaCurrent == dmaEnd) dmaStart += dmaBufferFlush(dmaStart);
if (dmaAddr == endPtr) break;
currCodeByte = *src++;
validBitCount = 8;
}
*(refCurrent++) = *copySource;
if (refCurrent == refEnd) refCurrent = refBuf;
if (currCodeByte & 0x80) {
if (readCount >= fileOffset) {
dmaAddr++;
*dmaCurrent++ = *src;
if (dmaCurrent == dmaEnd)
dmaStart += dmaBufferFlush(dmaStart);
copySource++;
if (dmaAddr == endPtr)
break;
}
*(refCurrent++) = *src;
if (refCurrent == refEnd)
refCurrent = refBuf;
if (copySource == refEnd) copySource = refBuf;
src++;
readCount++;
numBytes--;
} while (numBytes != 0);
}
currCodeByte <<= 1;
validBitCount--;
} while (dmaAddr < endPtr);
readCount++;
} else {
int t0 = src[0];
int t1 = src[1];
copySource = refCurrent - (t1 | (t0 & 0x0f) << 8) - 1;
numBytes = t0 >> 4;
src += 2;
if (copySource < refBuf)
copySource = copySource + (refEnd - refBuf);
dmaBufferFlush(dmaStart);
if (numBytes == 0)
numBytes = *src++ + 0x12;
else
numBytes += 2;
return 0;
do {
if (readCount >= fileOffset) {
dmaAddr++;
*(dmaCurrent++) = *copySource;
if (dmaCurrent == dmaEnd)
dmaStart += dmaBufferFlush(dmaStart);
if (dmaAddr == endPtr)
break;
}
*(refCurrent++) = *copySource;
if (refCurrent == refEnd)
refCurrent = refBuf;
copySource++;
if (copySource == refEnd)
copySource = refBuf;
readCount++;
numBytes--;
} while (numBytes != 0);
}
currCodeByte <<= 1;
validBitCount--;
} while (dmaAddr < endPtr);
dmaBufferFlush(dmaStart);
return 0;
}
u8* firstSrcData() {
srcLimit = szpEnd - 0x19;
u8* buf = szpBuf;
u32 max = (szpEnd - szpBuf);
u32 transSize = MIN(transLeft, max);
srcLimit = szpEnd - 0x19;
u8* buf = szpBuf;
u32 max = (szpEnd - szpBuf);
u32 transSize = MIN(transLeft, max);
while (true) {
if (0 <= DVDReadPrio(srcFile->getFileInfo(), buf, transSize, 0, 2)) break;
if (!JKRDvdAramRipper::isErrorRetry()) return nullptr;
VIWaitForRetrace();
}
srcOffset += transSize;
transLeft -= transSize;
return buf;
while (true) {
if (0 <= DVDReadPrio(srcFile->getFileInfo(), buf, transSize, 0, 2))
break;
if (!JKRDvdAramRipper::isErrorRetry())
return nullptr;
VIWaitForRetrace();
}
srcOffset += transSize;
transLeft -= transSize;
return buf;
}
u8* nextSrcData(u8* src) {
u32 limit = szpEnd - src;
u8* buf;
if (IS_NOT_ALIGNED(limit, 0x20))
buf = szpBuf + 0x20 - (limit & (0x20 - 1));
else
buf = szpBuf;
u32 limit = szpEnd - src;
u8* buf;
if (IS_NOT_ALIGNED(limit, 0x20))
buf = szpBuf + 0x20 - (limit & (0x20 - 1));
else
buf = szpBuf;
memcpy(buf, src, limit);
u32 transSize = (u32)(szpEnd - (buf + limit));
if (transSize > transLeft) transSize = transLeft;
memcpy(buf, src, limit);
u32 transSize = (u32)(szpEnd - (buf + limit));
if (transSize > transLeft)
transSize = transLeft;
JUT_ASSERT(transSize > 0);
while (true) {
int result = DVDReadPrio(srcFile->getFileInfo(), (buf + limit), transSize,
srcOffset, 2);
if (result >= 0) break;
JUT_ASSERT(transSize > 0);
while (true) {
int result = DVDReadPrio(srcFile->getFileInfo(), (buf + limit), transSize, srcOffset, 2);
if (result >= 0)
break;
if (!JKRDvdAramRipper::isErrorRetry()) return nullptr;
if (!JKRDvdAramRipper::isErrorRetry())
return nullptr;
VIWaitForRetrace();
}
VIWaitForRetrace();
}
srcOffset += transSize;
transLeft -= transSize;
if (transLeft == 0) srcLimit = transSize + (buf + limit);
srcOffset += transSize;
transLeft -= transSize;
if (transLeft == 0)
srcLimit = transSize + (buf + limit);
return buf;
return buf;
}
u32 dmaBufferFlush(u32 src) {
if (dmaCurrent == dmaBuf) {
return 0;
}
else {
u32 length = ALIGN_NEXT((u32)(dmaCurrent - dmaBuf), 32);
JKRAramPiece::orderSync(0, (u32)dmaBuf, src, length, nullptr);
dmaCurrent = dmaBuf;
return length;
}
if (dmaCurrent == dmaBuf) {
return 0;
} else {
u32 length = ALIGN_NEXT((u32)(dmaCurrent - dmaBuf), 32);
JKRAramPiece::orderSync(0, (u32)dmaBuf, src, length, nullptr);
dmaCurrent = dmaBuf;
return length;
}
}
+124 -190
View File
@@ -8,18 +8,14 @@
#include "JSystem/JSystem.h"
#include "JSystem/JUtility/JUTAssertion.h"
JKRDvdArchive::JKRDvdArchive() : JKRArchive() {}
JKRDvdArchive::JKRDvdArchive() : JKRArchive() {
}
JKRDvdArchive::JKRDvdArchive(s32 entryNum, EMountDirection mountDirection)
: JKRArchive(entryNum, MOUNT_DVD)
{
JKRDvdArchive::JKRDvdArchive(s32 entryNum, EMountDirection mountDirection) : JKRArchive(entryNum, MOUNT_DVD) {
mMountDirection = mountDirection;
if (!open(entryNum))
{
if (!open(entryNum)) {
return;
}
else
{
} else {
mVolumeType = 'RARC';
mVolumeName = &mStrTable[mDirectories->mOffset];
sVolumeList.prepend(&mFileLoaderLink);
@@ -27,17 +23,12 @@ JKRDvdArchive::JKRDvdArchive(s32 entryNum, EMountDirection mountDirection)
}
}
JKRDvdArchive::~JKRDvdArchive()
{
if (mIsMounted == true)
{
if (mArcInfoBlock)
{
JKRDvdArchive::~JKRDvdArchive() {
if (mIsMounted == true) {
if (mArcInfoBlock) {
SDIFileEntry* fileEntries = mFileEntries;
for (int i = 0; i < mArcInfoBlock->num_file_entries; i++)
{
if (fileEntries->mData != nullptr)
{
for (int i = 0; i < mArcInfoBlock->num_file_entries; i++) {
if (fileEntries->mData != nullptr) {
JKRFreeToHeap(mHeap, fileEntries->mData);
}
fileEntries++;
@@ -45,8 +36,7 @@ JKRDvdArchive::~JKRDvdArchive()
JKRFreeToHeap(mHeap, mArcInfoBlock);
}
if (mDvdFile)
{
if (mDvdFile) {
delete mDvdFile;
}
@@ -59,8 +49,7 @@ JKRDvdArchive::~JKRDvdArchive()
CW_FORCE_STRINGS(JKRDvdArchive_cpp, __FILE__, "isMounted()", "mMountCount == 1")
#endif
bool JKRDvdArchive::open(long entryNum)
{
bool JKRDvdArchive::open(long entryNum) {
mArcInfoBlock = nullptr;
_60 = 0;
mDirectories = nullptr;
@@ -68,254 +57,199 @@ bool JKRDvdArchive::open(long entryNum)
mStrTable = nullptr;
mDvdFile = new (JKRGetSystemHeap(), 0) JKRDvdFile(entryNum);
if (mDvdFile == nullptr)
{
if (mDvdFile == nullptr) {
mMountMode = 0;
return 0;
}
SDIFileEntry* mem = (SDIFileEntry*)JKRAllocFromSysHeap(
32, 32); // NOTE: unconfirmed if this struct was used here
if (mem == nullptr)
{
SDIFileEntry* mem = (SDIFileEntry*)JKRAllocFromSysHeap(32, 32); // NOTE: unconfirmed if this struct was used here
if (mem == nullptr) {
mMountMode = 0;
}
else
{
JKRDvdToMainRam(entryNum, (u8*)mem, EXPAND_SWITCH_DECOMPRESS, 32, nullptr,
JKRDvdRipper::ALLOC_DIR_TOP, 0, &mCompression);
} else {
JKRDvdToMainRam(entryNum, (u8*)mem, EXPAND_SWITCH_DECOMPRESS, 32, nullptr, JKRDvdRipper::ALLOC_DIR_TOP, 0,
&mCompression);
int alignment = mMountDirection == MOUNT_DIRECTION_HEAD ? 32 : -32;
mArcInfoBlock =
(SArcDataInfo*)JKRAllocFromHeap(mHeap, mem->mSize, alignment);
if (mArcInfoBlock == nullptr)
{
mArcInfoBlock = (SArcDataInfo*)JKRAllocFromHeap(mHeap, mem->mSize, alignment);
if (mArcInfoBlock == nullptr) {
mMountMode = 0;
}
else
{
JKRDvdToMainRam(entryNum, (u8*)mArcInfoBlock, EXPAND_SWITCH_DECOMPRESS,
mem->mSize, nullptr, JKRDvdRipper::ALLOC_DIR_TOP, 32,
nullptr);
} else {
JKRDvdToMainRam(entryNum, (u8*)mArcInfoBlock, EXPAND_SWITCH_DECOMPRESS, mem->mSize, nullptr,
JKRDvdRipper::ALLOC_DIR_TOP, 32, nullptr);
mDirectories =
(SDIDirEntry*)((u8*)mArcInfoBlock + mArcInfoBlock->node_offset);
mFileEntries = (SDIFileEntry*)((u8*)mArcInfoBlock +
mArcInfoBlock->file_entry_offset);
mStrTable = (const char*)((u8*)mArcInfoBlock +
mArcInfoBlock->string_table_offset);
mDirectories = (SDIDirEntry*)((u8*)mArcInfoBlock + mArcInfoBlock->node_offset);
mFileEntries = (SDIFileEntry*)((u8*)mArcInfoBlock + mArcInfoBlock->file_entry_offset);
mStrTable = (const char*)((u8*)mArcInfoBlock + mArcInfoBlock->string_table_offset);
_60 = mem->mDataOffset + mem->mSize; // End of data offset?
}
}
cleanup:
if (mem != nullptr)
{
if (mem != nullptr) {
JKRFreeToSysHeap(mem);
}
if (mMountMode == 0)
{
if (mMountMode == 0) {
JREPORTF(":::Cannot alloc memory [%s][%d]\n", __FILE__, 397); // Macro?
if (mDvdFile != nullptr)
{
if (mDvdFile != nullptr) {
delete mDvdFile;
}
}
return mMountMode != 0;
}
void* JKRDvdArchive::fetchResource(SDIFileEntry* fileEntry, u32* pSize)
{
void* JKRDvdArchive::fetchResource(SDIFileEntry* fileEntry, u32* pSize) {
JUT_ASSERT(isMounted());
u32 sizeRef;
u8* data;
if (fileEntry->mData == nullptr)
{
if (fileEntry->mData == nullptr) {
int compression = JKRConvertAttrToCompressionType(fileEntry->mFlag >> 0x18);
u32 size = fetchResource_subroutine(mEntryNum, _60 + fileEntry->mDataOffset,
fileEntry->mSize, mHeap,
(int)compression, mCompression, &data);
u32 size = fetchResource_subroutine(mEntryNum, _60 + fileEntry->mDataOffset, fileEntry->mSize, mHeap,
(int)compression, mCompression, &data);
if (pSize)
*pSize = size;
fileEntry->mData = data;
}
else if (pSize)
{
} else if (pSize) {
*pSize = fileEntry->mSize;
}
return fileEntry->mData;
}
void* JKRDvdArchive::fetchResource(void* data, u32 compressedSize,
SDIFileEntry* fileEntry, u32* pSize,
JKRExpandSwitch expandSwitch)
{
void* JKRDvdArchive::fetchResource(void* data, u32 compressedSize, SDIFileEntry* fileEntry, u32* pSize,
JKRExpandSwitch expandSwitch) {
JUT_ASSERT(isMounted());
u32 fileSize = compressedSize & -32;
u32 alignedSize = ALIGN_NEXT(fileEntry->mSize, 32);
if (alignedSize > fileSize)
{
if (alignedSize > fileSize) {
alignedSize = fileSize;
}
if (fileEntry->mData == nullptr)
{
if (fileEntry->mData == nullptr) {
int compression = JKRConvertAttrToCompressionType(fileEntry->mFlag >> 0x18);
if (expandSwitch != EXPAND_SWITCH_DECOMPRESS)
compression = 0;
alignedSize = fetchResource_subroutine(
mEntryNum, _60 + fileEntry->mDataOffset, fileEntry->mSize, (u8*)data,
fileSize, compression, mCompression);
}
else
{
alignedSize = fetchResource_subroutine(mEntryNum, _60 + fileEntry->mDataOffset, fileEntry->mSize, (u8*)data,
fileSize, compression, mCompression);
} else {
JKRHeap::copyMemory(data, fileEntry->mData, alignedSize);
}
if (pSize)
{
if (pSize) {
*pSize = alignedSize;
}
return data;
}
u32 JKRDvdArchive::fetchResource_subroutine(long entryNum, u32 offset, u32 size,
u8* data, u32 expandSize,
int fileCompression,
int archiveCompression)
{
u32 JKRDvdArchive::fetchResource_subroutine(long entryNum, u32 offset, u32 size, u8* data, u32 expandSize,
int fileCompression, int archiveCompression) {
u32 prevAlignedSize, alignedSize;
alignedSize = ALIGN_NEXT(size, 32);
prevAlignedSize = ALIGN_PREV(expandSize, 32);
switch (archiveCompression)
{
case JKRCOMPRESSION_NONE:
{
switch (fileCompression)
{
case JKRCOMPRESSION_NONE:
switch (archiveCompression) {
case JKRCOMPRESSION_NONE: {
switch (fileCompression) {
case JKRCOMPRESSION_NONE:
if (alignedSize > prevAlignedSize)
{
alignedSize = prevAlignedSize;
if (alignedSize > prevAlignedSize) {
alignedSize = prevAlignedSize;
}
JKRDvdRipper::loadToMainRAM(entryNum, data, EXPAND_SWITCH_DEFAULT, alignedSize, nullptr,
JKRDvdRipper::ALLOC_DIR_TOP, offset, nullptr);
return alignedSize;
case JKRCOMPRESSION_YAY0:
case JKRCOMPRESSION_YAZ0:
u8* header = (u8*)JKRAllocFromSysHeap(0x20, 0x20);
JKRDvdRipper::loadToMainRAM(entryNum, header, EXPAND_SWITCH_NONE, 0x20, nullptr,
JKRDvdRipper::ALLOC_DIR_TOP, offset, nullptr);
u32 expandFileSize = JKRDecompExpandSize(header);
JKRFreeToSysHeap(header);
alignedSize = ALIGN_NEXT(expandFileSize, 32);
if (alignedSize > prevAlignedSize) {
alignedSize = prevAlignedSize;
}
JKRDvdRipper::loadToMainRAM(entryNum, data, EXPAND_SWITCH_DECOMPRESS, alignedSize, nullptr,
JKRDvdRipper::ALLOC_DIR_TOP, offset, nullptr);
return expandFileSize;
}
JKRDvdRipper::loadToMainRAM(
entryNum, data, EXPAND_SWITCH_DEFAULT, alignedSize, nullptr,
JKRDvdRipper::ALLOC_DIR_TOP, offset, nullptr);
return alignedSize;
case JKRCOMPRESSION_YAY0:
case JKRCOMPRESSION_YAZ0:
u8* header = (u8*)JKRAllocFromSysHeap(0x20, 0x20);
JKRDvdRipper::loadToMainRAM(
entryNum, header, EXPAND_SWITCH_NONE, 0x20, nullptr,
JKRDvdRipper::ALLOC_DIR_TOP, offset, nullptr);
u32 expandFileSize = JKRDecompExpandSize(header);
JKRFreeToSysHeap(header);
alignedSize = ALIGN_NEXT(expandFileSize, 32);
if (alignedSize > prevAlignedSize)
{
alignedSize = prevAlignedSize;
}
case JKRCOMPRESSION_YAZ0: {
if (size > prevAlignedSize) {
size = prevAlignedSize;
}
JKRDvdRipper::loadToMainRAM(
entryNum, data, EXPAND_SWITCH_DECOMPRESS, alignedSize, nullptr,
JKRDvdRipper::ALLOC_DIR_TOP, offset, nullptr);
return expandFileSize;
JKRDvdRipper::loadToMainRAM(entryNum, data, EXPAND_SWITCH_DECOMPRESS, size, nullptr,
JKRDvdRipper::ALLOC_DIR_TOP, offset, nullptr);
return size;
}
}
case JKRCOMPRESSION_YAZ0:
{
if (size > prevAlignedSize)
{
size = prevAlignedSize;
case JKRCOMPRESSION_YAY0: {
JPANIC(537, "Sorry, not prepared for SZP archive.\n");
return 0;
}
JKRDvdRipper::loadToMainRAM(entryNum, data, EXPAND_SWITCH_DECOMPRESS,
size, nullptr, JKRDvdRipper::ALLOC_DIR_TOP,
offset, nullptr);
return size;
}
case JKRCOMPRESSION_YAY0:
{
JPANIC(537, "Sorry, not prepared for SZP archive.\n");
return 0;
}
default:
{
JPANIC(546, ":::??? bad sequence\n");
}
default: {
JPANIC(546, ":::??? bad sequence\n");
}
}
return 0;
}
u32 JKRDvdArchive::fetchResource_subroutine(long entryNum, u32 offset, u32 size,
JKRHeap* heap, int fileCompression,
int archiveCompression, u8** pBuf)
{
u32 JKRDvdArchive::fetchResource_subroutine(long entryNum, u32 offset, u32 size, JKRHeap* heap, int fileCompression,
int archiveCompression, u8** pBuf) {
u32 alignedSize = ALIGN_NEXT(size, 32);
u8* buffer;
switch (archiveCompression)
{
case JKRCOMPRESSION_NONE:
{
switch (fileCompression)
{
case JKRCOMPRESSION_NONE:
switch (archiveCompression) {
case JKRCOMPRESSION_NONE: {
switch (fileCompression) {
case JKRCOMPRESSION_NONE:
buffer = (u8*)JKRAllocFromHeap(heap, alignedSize, 32);
JUT_ASSERT(buffer != 0);
JKRDvdToMainRam(entryNum, buffer, EXPAND_SWITCH_DEFAULT, alignedSize, nullptr,
JKRDvdRipper::ALLOC_DIR_TOP, offset, nullptr);
*pBuf = buffer;
return alignedSize;
case JKRCOMPRESSION_YAY0:
case JKRCOMPRESSION_YAZ0:
u8* header = (u8*)JKRAllocFromHeap(heap, 0x20, 0x20);
JKRDvdToMainRam(entryNum, header, EXPAND_SWITCH_NONE, 0x20, nullptr, JKRDvdRipper::ALLOC_DIR_TOP,
offset, nullptr);
alignedSize = JKRDecompExpandSize(header);
JKRFreeToHeap(heap, header);
buffer = (u8*)JKRAllocFromHeap(heap, alignedSize, 0x20);
JUT_ASSERT(buffer);
JKRDvdToMainRam(entryNum, buffer, EXPAND_SWITCH_DECOMPRESS, alignedSize, nullptr,
JKRDvdRipper::ALLOC_DIR_TOP, offset, nullptr);
*pBuf = buffer;
return alignedSize;
}
}
case JKRCOMPRESSION_YAZ0: {
buffer = (u8*)JKRAllocFromHeap(heap, alignedSize, 32);
JUT_ASSERT(buffer != 0);
JKRDvdToMainRam(entryNum, buffer, EXPAND_SWITCH_DEFAULT, alignedSize,
nullptr, JKRDvdRipper::ALLOC_DIR_TOP, offset,
nullptr);
*pBuf = buffer;
return alignedSize;
case JKRCOMPRESSION_YAY0:
case JKRCOMPRESSION_YAZ0:
u8* header = (u8*)JKRAllocFromHeap(heap, 0x20, 0x20);
JKRDvdToMainRam(entryNum, header, EXPAND_SWITCH_NONE, 0x20, nullptr,
JKRDvdRipper::ALLOC_DIR_TOP, offset, nullptr);
alignedSize = JKRDecompExpandSize(header);
JKRFreeToHeap(heap, header);
buffer = (u8*)JKRAllocFromHeap(heap, alignedSize, 0x20);
JUT_ASSERT(buffer);
JKRDvdToMainRam(entryNum, buffer, EXPAND_SWITCH_DECOMPRESS,
alignedSize, nullptr, JKRDvdRipper::ALLOC_DIR_TOP,
offset, nullptr);
JKRDvdToMainRam(entryNum, buffer, EXPAND_SWITCH_DECOMPRESS, size, nullptr, JKRDvdRipper::ALLOC_DIR_TOP,
offset, nullptr);
*pBuf = buffer;
return alignedSize;
}
}
case JKRCOMPRESSION_YAZ0:
{
buffer = (u8*)JKRAllocFromHeap(heap, alignedSize, 32);
JUT_ASSERT(buffer);
JKRDvdToMainRam(entryNum, buffer, EXPAND_SWITCH_DECOMPRESS, size, nullptr,
JKRDvdRipper::ALLOC_DIR_TOP, offset, nullptr);
*pBuf = buffer;
return alignedSize;
}
case JKRCOMPRESSION_YAY0:
{
JPANIC(612, "Sorry, not prepared for SZP archive.\n");
return 0;
}
case JKRCOMPRESSION_YAY0: {
JPANIC(612, "Sorry, not prepared for SZP archive.\n");
return 0;
}
default:
{
JPANIC(617, ":::??? bad sequence\n");
}
default: {
JPANIC(617, ":::??? bad sequence\n");
}
}
return 0;
}
+72 -70
View File
@@ -2,115 +2,117 @@
JSUList<JKRDvdFile> JKRDvdFile::sDvdList;
JKRDvdFile::JKRDvdFile() : JKRFile(), mLink(this) { this->initiate(); }
JKRDvdFile::JKRDvdFile() : JKRFile(), mLink(this) {
this->initiate();
}
/* This method is confirmed to exist, but goes unused in AC. Retrieved from TP debug. */
JKRDvdFile::JKRDvdFile(const char* filename) : JKRFile(), mLink(this) {
this->initiate();
this->mFileOpen = this->open(filename);
this->initiate();
this->mFileOpen = this->open(filename);
if (this->isAvailable()) {
return;
}
if (this->isAvailable()) {
return;
}
}
JKRDvdFile::JKRDvdFile(s32 entrynum) : JKRFile(), mLink(this) {
this->initiate();
this->mFileOpen = this->open(entrynum);
this->initiate();
this->mFileOpen = this->open(entrynum);
if (this->isAvailable()) {
return;
}
if (this->isAvailable()) {
return;
}
}
JKRDvdFile::~JKRDvdFile() { this->close(); }
JKRDvdFile::~JKRDvdFile() {
this->close();
}
void JKRDvdFile::initiate() {
/* Reference to self. Used to retrieve reference in the DVDReadAsync
* DVDCallback func. */
this->mDvdFileInfo.mFile = this;
OSInitMutex(&this->mDvdMutex);
OSInitMutex(&this->mAramMutex);
OSInitMessageQueue(&this->mDvdMessageQueue, &this->mDvdMessage, 1);
OSInitMessageQueue(&this->mAramMessageQueue, &this->mAramMessage, 1);
this->mDvdThread = nullptr;
this->mAramThread = nullptr;
this->_58 = 0;
/* Reference to self. Used to retrieve reference in the DVDReadAsync
* DVDCallback func. */
this->mDvdFileInfo.mFile = this;
OSInitMutex(&this->mDvdMutex);
OSInitMutex(&this->mAramMutex);
OSInitMessageQueue(&this->mDvdMessageQueue, &this->mDvdMessage, 1);
OSInitMessageQueue(&this->mAramMessageQueue, &this->mAramMessage, 1);
this->mDvdThread = nullptr;
this->mAramThread = nullptr;
this->_58 = 0;
}
/* This method is confirmed to exist, but goes unused in AC. Retrieved from TP debug. */
bool JKRDvdFile::open(const char* filename) {
if (this->mFileOpen == false) {
this->mFileOpen = DVDOpen((char*)filename, &this->mDvdFileInfo);
if (this->mFileOpen) {
sDvdList.append(&this->mLink);
DVDGetFileInfoStatus(&this->mDvdFileInfo);
if (this->mFileOpen == false) {
this->mFileOpen = DVDOpen((char*)filename, &this->mDvdFileInfo);
if (this->mFileOpen) {
sDvdList.append(&this->mLink);
DVDGetFileInfoStatus(&this->mDvdFileInfo);
}
}
}
return this->mFileOpen;
return this->mFileOpen;
}
bool JKRDvdFile::open(s32 entrynum) {
if (this->mFileOpen == false) {
this->mFileOpen = DVDFastOpen(entrynum, &this->mDvdFileInfo);
if (this->mFileOpen) {
sDvdList.append(&this->mLink);
DVDGetFileInfoStatus(&this->mDvdFileInfo);
if (this->mFileOpen == false) {
this->mFileOpen = DVDFastOpen(entrynum, &this->mDvdFileInfo);
if (this->mFileOpen) {
sDvdList.append(&this->mLink);
DVDGetFileInfoStatus(&this->mDvdFileInfo);
}
}
}
return this->mFileOpen;
return this->mFileOpen;
}
bool JKRDvdFile::close() {
if (this->mFileOpen) {
if (DVDClose(&this->mDvdFileInfo)) {
this->mFileOpen = false;
return sDvdList.remove(&this->mLink);
if (this->mFileOpen) {
if (DVDClose(&this->mDvdFileInfo)) {
this->mFileOpen = false;
return sDvdList.remove(&this->mLink);
} else {
OSErrorLine(212, "cannot close DVD file\n"); /* JKRDvdFile.cpp line 212 */
}
}
else {
OSErrorLine(212, "cannot close DVD file\n"); /* JKRDvdFile.cpp line 212 */
}
}
}
int JKRDvdFile::readData(void* data, s32 length, s32 ofs) {
OSLockMutex(&this->mDvdMutex);
s32 retAddr;
OSLockMutex(&this->mDvdMutex);
s32 retAddr;
if (this->mDvdThread != nullptr) {
OSUnlockMutex(&this->mDvdMutex);
return -1;
}
else {
this->mDvdThread = OSGetCurrentThread();
retAddr = -1;
if (DVDReadAsync(&this->mDvdFileInfo, data, length, ofs,
JKRDvdFile::doneProcess)) {
retAddr = this->sync();
if (this->mDvdThread != nullptr) {
OSUnlockMutex(&this->mDvdMutex);
return -1;
} else {
this->mDvdThread = OSGetCurrentThread();
retAddr = -1;
if (DVDReadAsync(&this->mDvdFileInfo, data, length, ofs, JKRDvdFile::doneProcess)) {
retAddr = this->sync();
}
this->mDvdThread = nullptr;
OSUnlockMutex(&this->mDvdMutex);
}
this->mDvdThread = nullptr;
OSUnlockMutex(&this->mDvdMutex);
}
return retAddr;
return retAddr;
}
int JKRDvdFile::writeData(const void* data, s32 length, s32 ofs) { return -1; }
int JKRDvdFile::writeData(const void* data, s32 length, s32 ofs) {
return -1;
}
s32 JKRDvdFile::sync() {
OSMessage m;
OSMessage m;
OSLockMutex(&this->mDvdMutex);
OSReceiveMessage(&this->mDvdMessageQueue, &m, OS_MESSAGE_BLOCK);
this->mDvdThread = nullptr;
OSUnlockMutex(&this->mDvdMutex);
return (s32)m;
OSLockMutex(&this->mDvdMutex);
OSReceiveMessage(&this->mDvdMessageQueue, &m, OS_MESSAGE_BLOCK);
this->mDvdThread = nullptr;
OSUnlockMutex(&this->mDvdMutex);
return (s32)m;
}
void JKRDvdFile::doneProcess(s32 result, DVDFileInfo* info) {
OSSendMessage(&static_cast<JKRDvdFileInfo*>(info)->mFile->mDvdMessageQueue,
(OSMessage)result, OS_MESSAGE_NOBLOCK);
OSSendMessage(&static_cast<JKRDvdFileInfo*>(info)->mFile->mDvdMessageQueue, (OSMessage)result, OS_MESSAGE_NOBLOCK);
}
+338 -377
View File
@@ -15,190 +15,187 @@ static int decompSZS_subroutine(u8* src, u8* dest);
static u8* firstSrcData();
static u8* nextSrcData(u8* nowData);
void* JKRDvdRipper::loadToMainRAM(const char* file, u8* buf, JKRExpandSwitch expandSwitch, u32 maxDest, JKRHeap* heap, EAllocDirection allocDir, u32 offset, int* compressMode) {
JKRDvdFile dvdFile;
void* JKRDvdRipper::loadToMainRAM(const char* file, u8* buf, JKRExpandSwitch expandSwitch, u32 maxDest, JKRHeap* heap,
EAllocDirection allocDir, u32 offset, int* compressMode) {
JKRDvdFile dvdFile;
if (!dvdFile.open(file)) {
return nullptr;
}
else {
return JKRDvdRipper::loadToMainRAM(&dvdFile, buf, expandSwitch, maxDest, heap, allocDir, offset, compressMode);
}
}
void* JKRDvdRipper::loadToMainRAM(s32 entrynum, u8* buf, JKRExpandSwitch expandSwitch, u32 maxDest, JKRHeap* heap, EAllocDirection allocDir, u32 offset, int* compressMode) {
JKRDvdFile dvdFile;
if (!dvdFile.open(entrynum)) {
return nullptr;
}
else {
return JKRDvdRipper::loadToMainRAM(&dvdFile, buf, expandSwitch, maxDest, heap, allocDir, offset, compressMode);
}
}
void* JKRDvdRipper::loadToMainRAM(JKRDvdFile* file, u8* buf, JKRExpandSwitch expandSwitch, u32 maxDest, JKRHeap* heap, EAllocDirection allocDir, u32 offset, int* compressMode) {
u32 finalSize;
bool allocated = false;
JKRDecomp::CompressionMode fileCompressMode = JKRDecomp::NONE;
u8* mem = nullptr;
u32 fileSize = ALIGN_NEXT(file->getFileSize(), 32);
if (expandSwitch == EXPAND_SWITCH_DECOMPRESS) {
u8 buffer[64];
u8* aligned_buf = (u8*)ALIGN_NEXT((u32)buffer, 32);
while (true) {
if (DVDReadPrio(file->getFileInfo(), aligned_buf, 32, 0, 2) >= 0) {
break;
}
if (JKRDvdRipper::errorRetry == false) {
if (!dvdFile.open(file)) {
return nullptr;
}
} else {
return JKRDvdRipper::loadToMainRAM(&dvdFile, buf, expandSwitch, maxDest, heap, allocDir, offset, compressMode);
}
}
VIWaitForRetrace();
void* JKRDvdRipper::loadToMainRAM(s32 entrynum, u8* buf, JKRExpandSwitch expandSwitch, u32 maxDest, JKRHeap* heap,
EAllocDirection allocDir, u32 offset, int* compressMode) {
JKRDvdFile dvdFile;
if (!dvdFile.open(entrynum)) {
return nullptr;
} else {
return JKRDvdRipper::loadToMainRAM(&dvdFile, buf, expandSwitch, maxDest, heap, allocDir, offset, compressMode);
}
}
void* JKRDvdRipper::loadToMainRAM(JKRDvdFile* file, u8* buf, JKRExpandSwitch expandSwitch, u32 maxDest, JKRHeap* heap,
EAllocDirection allocDir, u32 offset, int* compressMode) {
u32 finalSize;
bool allocated = false;
JKRDecomp::CompressionMode fileCompressMode = JKRDecomp::NONE;
u8* mem = nullptr;
u32 fileSize = ALIGN_NEXT(file->getFileSize(), 32);
if (expandSwitch == EXPAND_SWITCH_DECOMPRESS) {
u8 buffer[64];
u8* aligned_buf = (u8*)ALIGN_NEXT((u32)buffer, 32);
while (true) {
if (DVDReadPrio(file->getFileInfo(), aligned_buf, 32, 0, 2) >= 0) {
break;
}
if (JKRDvdRipper::errorRetry == false) {
return nullptr;
}
VIWaitForRetrace();
}
fileCompressMode = JKRCheckCompressed(aligned_buf);
finalSize = JKRDecompExpandSize(aligned_buf);
}
fileCompressMode = JKRCheckCompressed(aligned_buf);
finalSize = JKRDecompExpandSize(aligned_buf);
}
if (compressMode != nullptr) {
*compressMode = fileCompressMode;
}
if (expandSwitch == EXPAND_SWITCH_DECOMPRESS && fileCompressMode != JKRDecomp::NONE) {
if (maxDest != 0 && finalSize > maxDest) {
finalSize = maxDest;
if (compressMode != nullptr) {
*compressMode = fileCompressMode;
}
if (buf == nullptr) {
buf = (u8*)JKRAllocFromHeap(heap, finalSize, allocDir == ALLOC_DIR_TOP ? 32 : -32);
allocated = true;
if (expandSwitch == EXPAND_SWITCH_DECOMPRESS && fileCompressMode != JKRDecomp::NONE) {
if (maxDest != 0 && finalSize > maxDest) {
finalSize = maxDest;
}
if (buf == nullptr) {
buf = (u8*)JKRAllocFromHeap(heap, finalSize, allocDir == ALLOC_DIR_TOP ? 32 : -32);
allocated = true;
}
if (buf == nullptr) {
return nullptr;
}
if (fileCompressMode == JKRDecomp::SZP) {
mem = (u8*)JKRAllocFromHeap(heap, fileSize, 32);
if (mem == nullptr && allocated == true) {
JKRFree(buf);
return nullptr;
}
}
} else {
if (buf == nullptr) {
buf = (u8*)JKRAllocFromHeap(heap, fileSize - offset, allocDir == ALLOC_DIR_TOP ? 32 : -32);
allocated = true;
}
if (buf == nullptr) {
return nullptr;
}
}
if (buf == nullptr) {
return nullptr;
if (fileCompressMode == JKRDecomp::NONE) {
JKRDecomp::CompressionMode subCompressMode = JKRDecomp::NONE;
if (offset != 0) {
u8 buffer[64];
u8* aligned_buf = (u8*)ALIGN_NEXT((u32)buffer, 32);
while (true) {
if (DVDReadPrio(file->getFileInfo(), aligned_buf, 32, offset, 2) >= 0) {
break;
}
if (JKRDvdRipper::errorRetry == false) {
return nullptr;
}
VIWaitForRetrace();
}
subCompressMode = JKRCheckCompressed(aligned_buf);
}
if (subCompressMode == JKRDecomp::NONE || expandSwitch == EXPAND_SWITCH_NONE ||
expandSwitch == EXPAND_SWITCH_DEFAULT) {
s32 readSize = fileSize - offset;
if (maxDest != 0 && maxDest < readSize) {
readSize = maxDest;
}
while (true) {
if (DVDReadPrio(file->getFileInfo(), buf, readSize, offset, 2) >= 0) {
break;
}
if (JKRDvdRipper::errorRetry == false) {
return nullptr;
}
VIWaitForRetrace();
}
return buf;
}
if (subCompressMode == JKRDecomp::SZS) {
JKRDecompressFromDVD(file, buf, fileSize, maxDest, 0, offset);
} else {
JPANIC(297, "Sorry, not prepared for SZP resource\n");
}
}
if (fileCompressMode == JKRDecomp::SZP) {
mem = (u8*)JKRAllocFromHeap(heap, fileSize, 32);
if (mem == nullptr && allocated == true) {
JKRFree(buf);
return nullptr;
}
}
}
else {
if (buf == nullptr) {
buf = (u8*)JKRAllocFromHeap(heap, fileSize - offset, allocDir == ALLOC_DIR_TOP ? 32 : -32);
allocated = true;
}
if (buf == nullptr) {
return nullptr;
}
}
if (fileCompressMode == JKRDecomp::NONE) {
JKRDecomp::CompressionMode subCompressMode = JKRDecomp::NONE;
if (offset != 0) {
u8 buffer[64];
u8* aligned_buf = (u8*)ALIGN_NEXT((u32)buffer, 32);
while (true) {
if (DVDReadPrio(file->getFileInfo(), aligned_buf, 32, offset, 2) >= 0) {
break;
if (offset != 0) {
JPANIC(306, ":::Not support SZP with offset read");
}
if (JKRDvdRipper::errorRetry == false) {
return nullptr;
}
VIWaitForRetrace();
}
subCompressMode = JKRCheckCompressed(aligned_buf);
}
if (subCompressMode == JKRDecomp::NONE || expandSwitch == EXPAND_SWITCH_NONE || expandSwitch == EXPAND_SWITCH_DEFAULT) {
s32 readSize = fileSize - offset;
if (maxDest != 0 && maxDest < readSize) {
readSize = maxDest;
}
while (true) {
if (DVDReadPrio(file->getFileInfo(), buf, readSize, offset, 2) >= 0) {
break;
}
if (JKRDvdRipper::errorRetry == false) {
return nullptr;
}
VIWaitForRetrace();
}
return buf;
}
if (subCompressMode == JKRDecomp::SZS) {
JKRDecompressFromDVD(file, buf, fileSize, maxDest, 0, offset);
}
else {
JPANIC(297, "Sorry, not prepared for SZP resource\n");
}
}
if (fileCompressMode == JKRDecomp::SZP) {
if (offset != 0) {
JPANIC(306, ":::Not support SZP with offset read");
}
/* Looks like a bug here */
/* Looks like a bug here */
#ifndef FIXES
if (DVDReadPrio(file->getFileInfo(), mem, fileSize, 0, 2) < 0) {
if (JKRDvdRipper::errorRetry == false) {
VIWaitForRetrace();
}
if (DVDReadPrio(file->getFileInfo(), mem, fileSize, 0, 2) < 0) {
if (JKRDvdRipper::errorRetry == false) {
VIWaitForRetrace();
}
JKRFree(mem);
return nullptr;
}
else {
JKRDecompress(mem, buf, finalSize, offset);
JKRFree(mem);
return buf;
}
JKRFree(mem);
return nullptr;
} else {
JKRDecompress(mem, buf, finalSize, offset);
JKRFree(mem);
return buf;
}
#else
while (DVDReadPrio(file->getFileInfo(), mem, fileSize, 0, 2) < 0) {
if (JKRDvdRipper::errorRetry == false) {
if (allocated) {
JKRFree(buf);
while (DVDReadPrio(file->getFileInfo(), mem, fileSize, 0, 2) < 0) {
if (JKRDvdRipper::errorRetry == false) {
if (allocated) {
JKRFree(buf);
}
JKRFree(mem);
return nullptr;
}
VIWaitForRetrace();
}
JKRDecompress(mem, buf, finalSize, 0);
JKRFree(mem);
return nullptr;
}
VIWaitForRetrace();
}
JKRDecompress(mem, buf, finalSize, 0);
JKRFree(mem);
#endif
}
else if (fileCompressMode == JKRDecomp::SZS) {
JKRDecompressFromDVD(file, buf, fileSize, finalSize, offset, 0);
return buf;
}
else {
if (allocated) {
JKRFree(buf);
} else if (fileCompressMode == JKRDecomp::SZS) {
JKRDecompressFromDVD(file, buf, fileSize, finalSize, offset, 0);
return buf;
} else {
if (allocated) {
JKRFree(buf);
}
return nullptr;
}
return nullptr;
}
return buf;
return buf;
}
static u8* szpBuf;
@@ -216,251 +213,215 @@ static u32 readCount;
static u32 maxDest;
int JKRDecompressFromDVD(JKRDvdFile* _srcFile, void* buf, u32 size, u32 _maxDest, u32 _fileOffset, u32 _srcOffset) {
int res = 0;
int res = 0;
szpBuf = (u8*)JKRAllocFromSysHeap(SZP_BUFFERSIZE, -32);
szpEnd = szpBuf + SZP_BUFFERSIZE;
szpBuf = (u8*)JKRAllocFromSysHeap(SZP_BUFFERSIZE, -32);
szpEnd = szpBuf + SZP_BUFFERSIZE;
if (_fileOffset != 0) {
refBuf = (u8*)JKRAllocFromSysHeap(REF_BUFFERSIZE, -4);
refEnd = refBuf + REF_BUFFERSIZE;
refCurrent = refBuf;
}
else {
refBuf = nullptr;
}
if (_fileOffset != 0) {
refBuf = (u8*)JKRAllocFromSysHeap(REF_BUFFERSIZE, -4);
refEnd = refBuf + REF_BUFFERSIZE;
refCurrent = refBuf;
} else {
refBuf = nullptr;
}
srcFile = _srcFile;
srcOffset = _srcOffset;
transLeft = size - _srcOffset;
fileOffset = _fileOffset;
readCount = 0;
maxDest = _maxDest;
srcFile = _srcFile;
srcOffset = _srcOffset;
transLeft = size - _srcOffset;
fileOffset = _fileOffset;
readCount = 0;
maxDest = _maxDest;
u8* src = firstSrcData();
if (src != nullptr) {
res = decompSZS_subroutine(src, (u8*)buf);
}
u8* src = firstSrcData();
if (src != nullptr) {
res = decompSZS_subroutine(src, (u8*)buf);
}
JKRFree(szpBuf);
JKRFree(szpBuf);
if (refBuf != nullptr) {
JKRFree(refBuf);
}
if (refBuf != nullptr) {
JKRFree(refBuf);
}
return res;
return res;
}
static int decompSZS_subroutine(u8* src, u8* dest) {
u8* endPtr;
s32 validBitCount = 0;
s32 currCodeByte = 0;
u32 ts = 0;
u8* endPtr;
s32 validBitCount = 0;
s32 currCodeByte = 0;
u32 ts = 0;
if ((s32)src[0] != 'Y' || (s32)src[1] != 'a' || (s32)src[2] != 'z' || (s32)src[3] != '0')
{
return -1;
}
SZPHeader* header = (SZPHeader*)src;
endPtr = dest + (header->decompSize - fileOffset);
if (endPtr > dest + maxDest)
{
endPtr = dest + maxDest;
}
src += 0x10;
do
{
if (validBitCount == 0)
{
if ((src > srcLimit) && transLeft)
{
src = nextSrcData(src);
if (!src)
{
return -1;
}
}
currCodeByte = *src;
validBitCount = 8;
src++;
if ((s32)src[0] != 'Y' || (s32)src[1] != 'a' || (s32)src[2] != 'z' || (s32)src[3] != '0') {
return -1;
}
if (currCodeByte & 0x80)
{
if (fileOffset != 0)
{
if (readCount >= fileOffset)
{
*dest = *src;
dest++;
ts++;
if (dest == endPtr)
{
break;
}
}
*(refCurrent++) = *src;
if (refCurrent == refEnd)
{
refCurrent = refBuf;
}
src++;
}
else
{
*dest = *src;
dest++;
src++;
ts++;
if (dest == endPtr)
{
break;
}
}
readCount++;
SZPHeader* header = (SZPHeader*)src;
endPtr = dest + (header->decompSize - fileOffset);
if (endPtr > dest + maxDest) {
endPtr = dest + maxDest;
}
else
{
u32 dist = src[1] | (src[0] & 0x0f) << 8;
s32 numBytes = src[0] >> 4;
src += 2;
u8* copySource;
if (fileOffset != 0)
{
copySource = refCurrent - dist - 1;
if (copySource < refBuf)
{
copySource += refEnd - refBuf;
}
}
else
{
copySource = dest - dist - 1;
}
if (numBytes == 0)
{
numBytes = *src + 0x12;
src += 1;
}
else
{
numBytes += 2;
}
if (fileOffset != 0)
{
do
{
if (readCount >= fileOffset)
{
*dest = *copySource;
dest++;
ts++;
if (dest == endPtr)
{
break;
src += 0x10;
do {
if (validBitCount == 0) {
if ((src > srcLimit) && transLeft) {
src = nextSrcData(src);
if (!src) {
return -1;
}
}
}
*(refCurrent++) = *copySource;
if (refCurrent == refEnd)
{
refCurrent = refBuf;
}
copySource++;
if (copySource == refEnd)
{
copySource = refBuf;
}
readCount++;
numBytes--;
} while (numBytes != 0);
}
else
{
do
{
*dest = *copySource;
dest++;
ts++;
if (dest == endPtr)
{
break;
}
readCount++;
numBytes--;
copySource++;
} while (numBytes != 0);
}
}
currCodeByte <<= 1;
validBitCount--;
} while (dest < endPtr);
currCodeByte = *src;
validBitCount = 8;
src++;
}
if (currCodeByte & 0x80) {
if (fileOffset != 0) {
if (readCount >= fileOffset) {
*dest = *src;
dest++;
ts++;
if (dest == endPtr) {
break;
}
}
*(refCurrent++) = *src;
if (refCurrent == refEnd) {
refCurrent = refBuf;
}
src++;
} else {
*dest = *src;
dest++;
src++;
ts++;
if (dest == endPtr) {
break;
}
}
readCount++;
} else {
u32 dist = src[1] | (src[0] & 0x0f) << 8;
s32 numBytes = src[0] >> 4;
src += 2;
u8* copySource;
if (fileOffset != 0) {
copySource = refCurrent - dist - 1;
if (copySource < refBuf) {
copySource += refEnd - refBuf;
}
} else {
copySource = dest - dist - 1;
}
if (numBytes == 0) {
numBytes = *src + 0x12;
src += 1;
} else {
numBytes += 2;
}
if (fileOffset != 0) {
do {
if (readCount >= fileOffset) {
*dest = *copySource;
dest++;
ts++;
if (dest == endPtr) {
break;
}
}
*(refCurrent++) = *copySource;
if (refCurrent == refEnd) {
refCurrent = refBuf;
}
copySource++;
if (copySource == refEnd) {
copySource = refBuf;
}
readCount++;
numBytes--;
} while (numBytes != 0);
} else {
do {
*dest = *copySource;
dest++;
ts++;
if (dest == endPtr) {
break;
}
readCount++;
numBytes--;
copySource++;
} while (numBytes != 0);
}
}
currCodeByte <<= 1;
validBitCount--;
} while (dest < endPtr);
return 0;
return 0;
}
static u8* firstSrcData() {
srcLimit = szpEnd - 0x19;
u8* buf = szpBuf;
u32 size = (szpEnd - szpBuf);
u32 transSize = MIN(transLeft, size);
srcLimit = szpEnd - 0x19;
u8* buf = szpBuf;
u32 size = (szpEnd - szpBuf);
u32 transSize = MIN(transLeft, size);
while (true) {
if (DVDReadPrio(srcFile->getFileInfo(), buf, transSize, srcOffset, 2) < 0) {
if (JKRDvdRipper::errorRetry == false) {
return nullptr;
}
VIWaitForRetrace();
while (true) {
if (DVDReadPrio(srcFile->getFileInfo(), buf, transSize, srcOffset, 2) < 0) {
if (JKRDvdRipper::errorRetry == false) {
return nullptr;
}
VIWaitForRetrace();
} else {
srcOffset += transSize;
transLeft -= transSize;
return buf;
}
}
else {
srcOffset += transSize;
transLeft -= transSize;
return buf;
}
}
}
static u8* nextSrcData(u8* nowData) {
u32 size = (szpEnd - nowData);
u8* dst;
if (JKR_ISNOTALIGNED32(size)) {
dst = szpBuf + 32 - (size & 31);
}
else {
dst = szpBuf;
}
memcpy(dst, nowData, size);
u32 n_size = (szpEnd - (dst + size));
if (n_size > transLeft) {
n_size = transLeft;
}
while (true) {
if (DVDReadPrio(srcFile->getFileInfo(), (dst + size), n_size, srcOffset, 2) >= 0) {
break;
u32 size = (szpEnd - nowData);
u8* dst;
if (JKR_ISNOTALIGNED32(size)) {
dst = szpBuf + 32 - (size & 31);
} else {
dst = szpBuf;
}
// Oopsies, forgot to call the function
memcpy(dst, nowData, size);
u32 n_size = (szpEnd - (dst + size));
if (n_size > transLeft) {
n_size = transLeft;
}
while (true) {
if (DVDReadPrio(srcFile->getFileInfo(), (dst + size), n_size, srcOffset, 2) >= 0) {
break;
}
// Oopsies, forgot to call the function
#ifndef FIXES
if (JKRDvdRipper::isErrorRetry == false) {
return nullptr;
}
if (JKRDvdRipper::isErrorRetry == false) {
return nullptr;
}
#else
if (JKRDvdRipper::isErrorRetry() == false) {
return nullptr;
}
if (JKRDvdRipper::isErrorRetry() == false) {
return nullptr;
}
#endif
VIWaitForRetrace();
}
VIWaitForRetrace();
}
srcOffset += n_size;
transLeft -= n_size;
srcOffset += n_size;
transLeft -= n_size;
if (transLeft == 0) {
srcLimit = (dst + size) + n_size;
}
if (transLeft == 0) {
srcLimit = (dst + size) + n_size;
}
return dst;
return dst;
}
File diff suppressed because it is too large Load Diff
+9 -9
View File
@@ -28,16 +28,16 @@
*/
void JKRFile::read(void* data, s32 length, s32 ofs) {
#ifdef JSYSTEM_DEBUG
if (!JKR_ISALIGNED(length, 32)) {
JUTAssertion::showAssert(JUTAssertion::getSDevice(), __FILE__, __LINE__, "( length & 0x1f ) == 0");
}
if (!JKR_ISALIGNED(length, 32)) {
JUTAssertion::showAssert(JUTAssertion::getSDevice(), __FILE__, __LINE__, "( length & 0x1f ) == 0");
}
#endif
while (true) {
if (this->readData(data, length, ofs) == length) {
return;
}
while (true) {
if (this->readData(data, length, ofs) == length) {
return;
}
VIWaitForRetrace();
}
VIWaitForRetrace();
}
}
+8 -16
View File
@@ -2,8 +2,7 @@
#include "JSystem/JKernel/JKRFileFinder.h"
#include "JSystem/JKernel/JKRArchive.h"
JKRArcFinder::JKRArcFinder(JKRArchive* archive, long startindex, long entries) : JKRFileFinder()
{
JKRArcFinder::JKRArcFinder(JKRArchive* archive, long startindex, long entries) : JKRFileFinder() {
mArchive = archive;
mIsAvailable = entries > 0;
@@ -14,13 +13,10 @@ JKRArcFinder::JKRArcFinder(JKRArchive* archive, long startindex, long entries) :
findNextFile();
}
bool JKRArcFinder::findNextFile()
{
if (mIsAvailable)
{
bool JKRArcFinder::findNextFile() {
if (mIsAvailable) {
mIsAvailable = (mNextIndex <= mEndIndex);
if (mIsAvailable)
{
if (mIsAvailable) {
JKRArchive::SDirEntry dirEntry;
mIsAvailable = mArchive->getDirEntry(&dirEntry, mNextIndex);
mBase.mFileName = dirEntry.mName;
@@ -35,22 +31,18 @@ bool JKRArcFinder::findNextFile()
}
// UNUSED
JKRDvdFinder::JKRDvdFinder(const char* path) : JKRFileFinder()
{
JKRDvdFinder::JKRDvdFinder(const char* path) : JKRFileFinder() {
mIsDvdOpen = DVDOpenDir(const_cast<char*>(path), &mDir);
mIsAvailable = mIsDvdOpen;
findNextFile();
}
// UNUSED, not sure if it matches
bool JKRDvdFinder::findNextFile()
{
if (mIsAvailable)
{
bool JKRDvdFinder::findNextFile() {
if (mIsAvailable) {
DVDDirEntry entry;
mIsAvailable = DVDReadDir(&mDir, &entry);
if (mIsAvailable)
{
if (mIsAvailable) {
mIsDir = (bool)entry.isDir;
mBase.mFileName = entry.name;
mBase.mFileIndex = entry.entryNum;
+25 -51
View File
@@ -5,55 +5,46 @@
JSUList<JKRFileLoader> JKRFileLoader::sVolumeList;
JKRFileLoader* JKRFileLoader::sCurrentVolume;
JKRFileLoader::JKRFileLoader() : JKRDisposer(), mFileLoaderLink(this)
{
JKRFileLoader::JKRFileLoader() : JKRDisposer(), mFileLoaderLink(this) {
mVolumeName = nullptr;
mVolumeType = 0;
mMountCount = 0;
}
JKRFileLoader::~JKRFileLoader()
{
JKRFileLoader::~JKRFileLoader() {
if (sCurrentVolume == this)
sCurrentVolume = nullptr;
}
void JKRFileLoader::unmount()
{
if (mMountCount != 0)
{
void JKRFileLoader::unmount() {
if (mMountCount != 0) {
if (--mMountCount == 0)
delete this;
}
}
void JKRFileLoader::changeDirectory(const char* dir)
{
void JKRFileLoader::changeDirectory(const char* dir) {
JKRFileLoader* vol = findVolume(&dir);
if (vol)
vol->becomeCurrent(dir);
}
void* JKRFileLoader::getGlbResource(const char* path)
{
void* JKRFileLoader::getGlbResource(const char* path) {
const char* components[2];
components[0] = path;
JKRFileLoader* loader = findVolume(components);
return (loader == nullptr) ? nullptr : loader->getResource(components[0]);
}
void* JKRFileLoader::getGlbResource(const char* name, JKRFileLoader* fileLoader)
{
void* JKRFileLoader::getGlbResource(const char* name, JKRFileLoader* fileLoader) {
void* resource = nullptr;
if (fileLoader)
{
if (fileLoader) {
return fileLoader->getResource(0, name);
}
JSUList<JKRFileLoader>& volumeList = getVolumeList();
JSUListIterator<JKRFileLoader> iterator;
for (iterator = volumeList.getFirst(); iterator != volumeList.getEnd(); ++iterator)
{
for (iterator = volumeList.getFirst(); iterator != volumeList.getEnd(); ++iterator) {
resource = iterator->getResource(0, name);
if (resource)
break;
@@ -61,24 +52,20 @@ void* JKRFileLoader::getGlbResource(const char* name, JKRFileLoader* fileLoader)
return resource;
}
size_t JKRFileLoader::readGlbResource(void* resBuf, u32 bufSize, const char* volumeName, JKRExpandSwitch expandSwitch)
{
size_t JKRFileLoader::readGlbResource(void* resBuf, u32 bufSize, const char* volumeName, JKRExpandSwitch expandSwitch) {
JKRFileLoader* vol = findVolume(&volumeName);
return vol == nullptr ? 0 : vol->readResource(resBuf, bufSize, volumeName, expandSwitch);
}
bool JKRFileLoader::removeResource(void* resourceBuffer, JKRFileLoader* fileLoader)
{
if (fileLoader)
{
bool JKRFileLoader::removeResource(void* resourceBuffer, JKRFileLoader* fileLoader) {
if (fileLoader) {
return fileLoader->removeResource(resourceBuffer);
}
JSUList<JKRFileLoader>& volumeList = getVolumeList();
JSUListIterator<JKRFileLoader> iterator;
for (iterator = volumeList.getFirst(); iterator != volumeList.getEnd(); ++iterator)
{
for (iterator = volumeList.getFirst(); iterator != volumeList.getEnd(); ++iterator) {
if (iterator->removeResource(resourceBuffer))
return true;
}
@@ -86,17 +73,14 @@ bool JKRFileLoader::removeResource(void* resourceBuffer, JKRFileLoader* fileLoad
return false;
}
bool JKRFileLoader::detachResource(void* resourceBuffer, JKRFileLoader* fileLoader)
{
if (fileLoader)
{
bool JKRFileLoader::detachResource(void* resourceBuffer, JKRFileLoader* fileLoader) {
if (fileLoader) {
return fileLoader->detachResource(resourceBuffer);
}
JSUList<JKRFileLoader>& volumeList = getVolumeList();
JSUListIterator<JKRFileLoader> iterator;
for (iterator = volumeList.getFirst(); iterator != volumeList.getEnd(); ++iterator)
{
for (iterator = volumeList.getFirst(); iterator != volumeList.getEnd(); ++iterator) {
if (iterator->detachResource(resourceBuffer))
return true;
}
@@ -104,10 +88,8 @@ bool JKRFileLoader::detachResource(void* resourceBuffer, JKRFileLoader* fileLoad
return false;
}
JKRFileLoader* JKRFileLoader::findVolume(const char** volumeName)
{
if (*volumeName[0] != '/')
{
JKRFileLoader* JKRFileLoader::findVolume(const char** volumeName) {
if (*volumeName[0] != '/') {
return sCurrentVolume;
}
@@ -116,16 +98,14 @@ JKRFileLoader* JKRFileLoader::findVolume(const char** volumeName)
JSUList<JKRFileLoader>& volumeList = sVolumeList;
JSUListIterator<JKRFileLoader> iterator;
for (iterator = volumeList.getFirst(); iterator != volumeList.getEnd(); ++iterator)
{
for (iterator = volumeList.getFirst(); iterator != volumeList.getEnd(); ++iterator) {
if (strcmp(volumeNameBuffer, iterator->mVolumeName) == 0)
return iterator.getObject();
}
return nullptr;
}
JKRFileFinder* JKRFileLoader::findFirstFile(const char* volumeName)
{
JKRFileFinder* JKRFileLoader::findFirstFile(const char* volumeName) {
JKRFileFinder* ret = nullptr;
JKRFileLoader* vol = findVolume(&volumeName);
@@ -135,21 +115,15 @@ JKRFileFinder* JKRFileLoader::findFirstFile(const char* volumeName)
return ret;
}
const char* JKRFileLoader::fetchVolumeName(char* buffer, long bufferSize, const char* path)
{
const char* JKRFileLoader::fetchVolumeName(char* buffer, long bufferSize, const char* path) {
static char rootPath[] = "/";
if (strcmp(path, "/") == 0)
{
if (strcmp(path, "/") == 0) {
strcpy(buffer, rootPath);
return rootPath;
}
else
{
} else {
path++;
while (*path != 0 && *path != '/')
{
if (1 < bufferSize)
{
while (*path != 0 && *path != '/') {
if (1 < bufferSize) {
*buffer = _tolower(*path);
buffer++;
bufferSize--;
+104 -165
View File
@@ -19,21 +19,16 @@ u32 JKRHeap::mMemorySize;
bool JKRHeap::sDefaultFillFlag = true;
JKRHeap::JKRHeap(void* data, u32 size, JKRHeap* heap, bool errorFlag) : JKRDisposer(),
mChildTree(this),
mDisposerList()
{
JKRHeap::JKRHeap(void* data, u32 size, JKRHeap* heap, bool errorFlag)
: JKRDisposer(), mChildTree(this), mDisposerList() {
OSInitMutex(&mMutex);
mSize = size;
mStart = (u8*)data;
mEnd = ((u8*)data + size);
if (heap == nullptr)
{
if (heap == nullptr) {
becomeSystemHeap();
becomeCurrentHeap();
}
else
{
} else {
heap->mChildTree.appendChild(&mChildTree);
if (sSystemHeap == sRootHeap)
becomeSystemHeap();
@@ -47,8 +42,7 @@ mDisposerList()
mInitFlag = false;
}
JKRHeap::~JKRHeap()
{
JKRHeap::~JKRHeap() {
mChildTree.getParent()->removeChild(&mChildTree);
JSUTree<JKRHeap>* nextRootHeap = sRootHeap->mChildTree.getFirstChild();
if (sCurrentHeap == this)
@@ -58,12 +52,10 @@ JKRHeap::~JKRHeap()
sSystemHeap = !nextRootHeap ? sRootHeap : nextRootHeap->getObject();
}
bool JKRHeap::initArena(char** outUserRamStart, u32* outUserRamSize, int numHeaps)
{
bool JKRHeap::initArena(char** outUserRamStart, u32* outUserRamSize, int numHeaps) {
void* arenaLo = OSGetArenaLo();
void* arenaHi = OSGetArenaHi();
if (arenaLo == arenaHi)
{
if (arenaLo == arenaHi) {
return false;
}
void* arenaStart = OSInitAlloc(arenaLo, arenaHi, numHeaps);
@@ -82,129 +74,111 @@ bool JKRHeap::initArena(char** outUserRamStart, u32* outUserRamSize, int numHeap
return true;
}
JKRHeap* JKRHeap::becomeSystemHeap()
{
JKRHeap* JKRHeap::becomeSystemHeap() {
JKRHeap* old = sSystemHeap;
sSystemHeap = this;
return old;
}
JKRHeap* JKRHeap::becomeCurrentHeap()
{
JKRHeap* JKRHeap::becomeCurrentHeap() {
JKRHeap* old = sCurrentHeap;
sCurrentHeap = this;
return old;
}
void JKRHeap::destroy(JKRHeap* heap)
{
#line 200
void JKRHeap::destroy(JKRHeap* heap) {
JUT_ASSERT(heap != 0);
heap->destroy();
}
void* JKRHeap::alloc(u32 byteCount, int padding, JKRHeap* heap)
{
void* JKRHeap::alloc(u32 byteCount, int padding, JKRHeap* heap) {
void* memory = nullptr;
if (heap)
{
if (heap) {
memory = heap->do_alloc(byteCount, padding);
}
else if (sCurrentHeap)
{
} else if (sCurrentHeap) {
memory = sCurrentHeap->do_alloc(byteCount, padding);
}
return memory;
}
void* JKRHeap::alloc(u32 byteCount, int padding)
{
JUT_WARNING_F(317, !mInitFlag, "alloc %x byte in heap %x", byteCount, this);
void* JKRHeap::alloc(u32 byteCount, int padding) {
JUT_WARNING_F(!mInitFlag, "alloc %x byte in heap %x", byteCount, this);
return do_alloc(byteCount, padding);
}
void JKRHeap::free(void* memory, JKRHeap* heap)
{
if ((heap) || (heap = findFromRoot(memory), heap))
{
void JKRHeap::free(void* memory, JKRHeap* heap) {
if ((heap) || (heap = findFromRoot(memory), heap)) {
heap->free(memory);
}
}
void JKRHeap::free(void* memory)
{
JUT_WARNING_F(365, !mInitFlag, "free %x in heap %x", memory, this);
void JKRHeap::free(void* memory) {
JUT_WARNING_F(!mInitFlag, "free %x in heap %x", memory, this);
do_free(memory);
}
void JKRHeap::callAllDisposer()
{
void JKRHeap::callAllDisposer() {
JSUListIterator<JKRDisposer> iterator;
while (iterator = mDisposerList.getFirst(), iterator != mDisposerList.getEnd())
{
while (iterator = mDisposerList.getFirst(), iterator != mDisposerList.getEnd()) {
iterator->~JKRDisposer();
}
}
void JKRHeap::freeAll()
{
JUT_WARNING_F(417, !mInitFlag, "freeAll in heap %x", this);
void JKRHeap::freeAll() {
JUT_WARNING_F(!mInitFlag, "freeAll in heap %x", this);
do_freeAll();
}
void JKRHeap::freeTail()
{
JUT_WARNING_F(431, !mInitFlag, "freeTail in heap %x", this);
void JKRHeap::freeTail() {
JUT_WARNING_F(!mInitFlag, "freeTail in heap %x", this);
do_freeTail();
}
void JKRHeap::resize(void* memoryBlock, u32 newSize)
{
JUT_WARNING_F(491, !mInitFlag, "resize block %x into %x in heap %x", memoryBlock, newSize, this);
void JKRHeap::resize(void* memoryBlock, u32 newSize) {
JUT_WARNING_F(!mInitFlag, "resize block %x into %x in heap %x", memoryBlock, newSize, this);
do_resize(memoryBlock, newSize);
}
s32 JKRHeap::getSize(void* memoryBlock, JKRHeap* heap)
{
if (heap == nullptr && (heap = findFromRoot(memoryBlock), heap == nullptr))
{
s32 JKRHeap::getSize(void* memoryBlock, JKRHeap* heap) {
if (heap == nullptr && (heap = findFromRoot(memoryBlock), heap == nullptr)) {
return -1;
}
else
} else
return heap->getSize(memoryBlock);
}
s32 JKRHeap::getSize(void* memoryBlock) { return do_getSize(memoryBlock); }
s32 JKRHeap::getFreeSize() { return do_getFreeSize(); }
s32 JKRHeap::getTotalFreeSize() { return do_getTotalFreeSize(); }
s32 JKRHeap::getSize(void* memoryBlock) {
return do_getSize(memoryBlock);
}
s32 JKRHeap::getFreeSize() {
return do_getFreeSize();
}
s32 JKRHeap::getTotalFreeSize() {
return do_getTotalFreeSize();
}
s32 JKRHeap::changeGroupID(u8 newGroupID)
{
JUT_WARNING_F(570, !mInitFlag, "change heap ID into %x in heap %x", newGroupID, this);
s32 JKRHeap::changeGroupID(u8 newGroupID) {
JUT_WARNING_F(!mInitFlag, "change heap ID into %x in heap %x", newGroupID, this);
return do_changeGroupID(newGroupID);
}
u8 JKRHeap::getCurrentGroupId() { return do_getCurrentGroupId(); }
u8 JKRHeap::getCurrentGroupId() {
return do_getCurrentGroupId();
}
JKRHeap* JKRHeap::findFromRoot(void* ptr)
{
JKRHeap* JKRHeap::findFromRoot(void* ptr) {
if (sRootHeap != nullptr)
return sRootHeap->find(ptr);
return nullptr;
}
JKRHeap* JKRHeap::find(void* memory) const
{
if ((mStart <= memory) && (memory <= mEnd))
{
if (mChildTree.getNumChildren() != 0)
{
for (JSUTreeIterator<JKRHeap> iterator(mChildTree.getFirstChild()); iterator != mChildTree.getEndChild(); ++iterator)
{
JKRHeap* JKRHeap::find(void* memory) const {
if ((mStart <= memory) && (memory <= mEnd)) {
if (mChildTree.getNumChildren() != 0) {
for (JSUTreeIterator<JKRHeap> iterator(mChildTree.getFirstChild()); iterator != mChildTree.getEndChild();
++iterator) {
JKRHeap* result = iterator->find(memory);
if (result)
{
if (result) {
return result;
}
}
@@ -214,22 +188,18 @@ JKRHeap* JKRHeap::find(void* memory) const
return nullptr;
}
JKRHeap* JKRHeap::findAllHeap(void* memory) const
{
if (mChildTree.getNumChildren() != 0)
{
for (JSUTreeIterator<JKRHeap> iterator(mChildTree.getFirstChild()); iterator != mChildTree.getEndChild(); ++iterator)
{
JKRHeap* JKRHeap::findAllHeap(void* memory) const {
if (mChildTree.getNumChildren() != 0) {
for (JSUTreeIterator<JKRHeap> iterator(mChildTree.getFirstChild()); iterator != mChildTree.getEndChild();
++iterator) {
JKRHeap* result = iterator->findAllHeap(memory);
if (result)
{
if (result) {
return result;
}
}
}
if (mStart <= memory && memory < mEnd)
{
if (mStart <= memory && memory < mEnd) {
return const_cast<JKRHeap*>(this);
}
@@ -237,31 +207,22 @@ JKRHeap* JKRHeap::findAllHeap(void* memory) const
}
// generates __as__25JSUTreeIterator<7JKRHeap>FP17JSUTree<7JKRHeap> and __ct__25JSUTreeIterator<7JKRHeap>Fv, remove this
void JKRHeap::dispose_subroutine(u32 begin, u32 end)
{
void JKRHeap::dispose_subroutine(u32 begin, u32 end) {
JSUListIterator<JKRDisposer> last_iterator;
JSUListIterator<JKRDisposer> next_iterator;
JSUListIterator<JKRDisposer> iterator;
for (iterator = mDisposerList.getFirst(); iterator != mDisposerList.getEnd();
iterator = next_iterator)
{
for (iterator = mDisposerList.getFirst(); iterator != mDisposerList.getEnd(); iterator = next_iterator) {
JKRDisposer* disposer = iterator.getObject();
if ((void*)begin <= disposer && disposer < (void*)end)
{
if ((void*)begin <= disposer && disposer < (void*)end) {
disposer->~JKRDisposer();
if (last_iterator == nullptr)
{
if (last_iterator == nullptr) {
next_iterator = mDisposerList.getFirst();
}
else
{
} else {
next_iterator = last_iterator;
next_iterator++;
}
}
else
{
} else {
last_iterator = iterator;
next_iterator = iterator;
next_iterator++;
@@ -269,36 +230,30 @@ void JKRHeap::dispose_subroutine(u32 begin, u32 end)
}
}
bool JKRHeap::dispose(void* memory, u32 size)
{
bool JKRHeap::dispose(void* memory, u32 size) {
u32 begin = (u32)memory;
u32 end = (u32)memory + size;
dispose_subroutine(begin, end);
return false;
}
void JKRHeap::dispose(void* begin, void* end)
{
void JKRHeap::dispose(void* begin, void* end) {
dispose_subroutine((u32)begin, (u32)end);
}
void JKRHeap::dispose()
{
void JKRHeap::dispose() {
JSUListIterator<JKRDisposer> iterator;
while (iterator = mDisposerList.getFirst(), iterator != mDisposerList.getEnd())
{
while (iterator = mDisposerList.getFirst(), iterator != mDisposerList.getEnd()) {
iterator->~JKRDisposer();
}
}
void JKRHeap::copyMemory(void* dst, void* src, u32 size)
{
void JKRHeap::copyMemory(void* dst, void* src, u32 size) {
u32 count = (size + 3) / 4;
u32* dst_32 = (u32*)dst;
u32* src_32 = (u32*)src;
while (count > 0)
{
while (count > 0) {
*dst_32 = *src_32;
dst_32++;
src_32++;
@@ -306,40 +261,33 @@ void JKRHeap::copyMemory(void* dst, void* src, u32 size)
}
}
void JKRDefaultMemoryErrorRoutine(void* heap, u32 size, int alignment)
{
// OSReport("Error: Cannot allocate memory %d(0x%x)byte in %d byte alignment from %08x\n", size, size, alignment, heap);
void JKRDefaultMemoryErrorRoutine(void* heap, u32 size, int alignment) {
// OSReport("Error: Cannot allocate memory %d(0x%x)byte in %d byte alignment from %08x\n", size, size, alignment,
// heap);
OSErrorLine(710, "abort\n");
}
JKRHeapErrorHandler* JKRHeap::setErrorHandler(JKRHeapErrorHandler* newHandler)
{
JKRHeapErrorHandler* JKRHeap::setErrorHandler(JKRHeapErrorHandler* newHandler) {
JKRHeapErrorHandler* oldHandler = mErrorHandler;
if (!newHandler)
{
if (!newHandler) {
newHandler = JKRDefaultMemoryErrorRoutine;
}
mErrorHandler = newHandler;
return oldHandler;
}
bool JKRHeap::isSubHeap(JKRHeap* heap) const
{
bool JKRHeap::isSubHeap(JKRHeap* heap) const {
if (!heap)
return false;
if (mChildTree.getNumChildren() != 0)
{
if (mChildTree.getNumChildren() != 0) {
JSUTreeIterator<JKRHeap> iterator;
for (iterator = mChildTree.getFirstChild(); iterator != mChildTree.getEndChild(); ++iterator)
{
if (iterator.getObject() == heap)
{
for (iterator = mChildTree.getFirstChild(); iterator != mChildTree.getEndChild(); ++iterator) {
if (iterator.getObject() == heap) {
return true;
}
if (iterator.getObject()->isSubHeap(heap))
{
if (iterator.getObject()->isSubHeap(heap)) {
return true;
}
}
@@ -348,35 +296,33 @@ bool JKRHeap::isSubHeap(JKRHeap* heap) const
return false;
}
void* operator new(u32 byteCount)
{
void* operator new(u32 byteCount) {
return JKRHeap::alloc(byteCount, 4, nullptr);
}
void* operator new(u32 byteCount, int alignment)
{
void* operator new(u32 byteCount, int alignment) {
return JKRHeap::alloc(byteCount, alignment, nullptr);
}
void* operator new(u32 byteCount, JKRHeap* heap, int alignment)
{
void* operator new(u32 byteCount, JKRHeap* heap, int alignment) {
return JKRHeap::alloc(byteCount, alignment, heap);
}
void* operator new[](u32 byteCount)
{
void* operator new[](u32 byteCount) {
return JKRHeap::alloc(byteCount, 4, nullptr);
}
void* operator new[](u32 byteCount, int alignment)
{
void* operator new[](u32 byteCount, int alignment) {
return JKRHeap::alloc(byteCount, alignment, nullptr);
}
void* operator new[](u32 byteCount, JKRHeap* heap, int alignment)
{
void* operator new[](u32 byteCount, JKRHeap* heap, int alignment) {
return JKRHeap::alloc(byteCount, alignment, heap);
}
// this is not needed without the other pragma and asm bs
void operator delete(void* memory) { JKRHeap::free(memory, nullptr); }
void operator delete[](void* memory) { JKRHeap::free(memory, nullptr); }
// this is not needed without the other pragma and asm bs
void operator delete(void* memory) {
JKRHeap::free(memory, nullptr);
}
void operator delete[](void* memory) {
JKRHeap::free(memory, nullptr);
}
/*JKRHeap::TState::TState(const JKRHeap::TState::TArgument &arg, const JKRHeap::TState::TLocation &location)
{
@@ -393,37 +339,30 @@ JKRHeap::TState::TState(const JKRHeap::TState &other, const JKRHeap::TState::TLo
// UNUSED FUNCTION
}*/
JKRHeap::TState::~TState()
{
JKRHeap::TState::~TState() {
// Unused, however might need it
}
void JKRHeap::state_register(JKRHeap::TState* p, u32) const
{
#line 1132
void JKRHeap::state_register(JKRHeap::TState* p, u32) const {
JUT_ASSERT(p != 0);
JUT_ASSERT(p->getHeap() == this);
}
bool JKRHeap::state_compare(const JKRHeap::TState& r1, const JKRHeap::TState& r2) const
{
#line 1141
bool JKRHeap::state_compare(const JKRHeap::TState& r1, const JKRHeap::TState& r2) const {
JUT_ASSERT(r1.getHeap() == r2.getHeap());
return (r1.getCheckCode() == r2.getCheckCode());
}
// fabricated, but probably matches(except for line numbers)
void JKRHeap::state_dumpDifference(const JKRHeap::TState& r1, const JKRHeap::TState& r2)
{
JUT_LOG_F(1157, "heap : %p / %p", r1.getHeap(), r2.getHeap());
JUT_LOG_F(1158, "check-code : 0x%08x / 0x%08x", r1.getCheckCode(), r2.getCheckCode());
JUT_LOG_F(1159, "id : 0x%08x / 0x%08x", r1.getId(), r2.getId());
JUT_LOG_F(1160, "used size : %10u / %10u", r1.getUsedSize(), r2.getUsedSize());
void JKRHeap::state_dumpDifference(const JKRHeap::TState& r1, const JKRHeap::TState& r2) {
JUT_LOG_F("heap : %p / %p", r1.getHeap(), r2.getHeap());
JUT_LOG_F("check-code : 0x%08x / 0x%08x", r1.getCheckCode(), r2.getCheckCode());
JUT_LOG_F("id : 0x%08x / 0x%08x", r1.getId(), r2.getId());
JUT_LOG_F("used size : %10u / %10u", r1.getUsedSize(), r2.getUsedSize());
}
void JKRHeap::state_dump(const TState& state) const
{
JUT_LOG_F(1165, "check-code : 0x%08x", state.getCheckCode());
JUT_LOG_F(1166, "id : 0x%08x", state.getId());
JUT_LOG_F(1167, "used size : %u", state.getUsedSize());
void JKRHeap::state_dump(const TState& state) const {
JUT_LOG_F("check-code : 0x%08x", state.getCheckCode());
JUT_LOG_F("id : 0x%08x", state.getId());
JUT_LOG_F("used size : %u", state.getUsedSize());
}
+60 -96
View File
@@ -7,18 +7,15 @@
#include "JSystem/JKernel/JKRDvdRipper.h"
#include "JSystem/JUtility/JUTAssertion.h"
JKRMemArchive::JKRMemArchive() : JKRArchive() {}
JKRMemArchive::JKRMemArchive() : JKRArchive() {
}
JKRMemArchive::JKRMemArchive(s32 entryNum, EMountDirection mountDirection) : JKRArchive(entryNum, MOUNT_MEM)
{
JKRMemArchive::JKRMemArchive(s32 entryNum, EMountDirection mountDirection) : JKRArchive(entryNum, MOUNT_MEM) {
mIsMounted = false;
mMountDirection = mountDirection;
if (!open(entryNum, mMountDirection))
{
if (!open(entryNum, mMountDirection)) {
return;
}
else
{
} else {
mVolumeType = 'RARC';
mVolumeName = &mStrTable[mDirectories->mOffset];
sVolumeList.prepend(&mFileLoaderLink);
@@ -26,15 +23,11 @@ JKRMemArchive::JKRMemArchive(s32 entryNum, EMountDirection mountDirection) : JKR
}
}
JKRMemArchive::JKRMemArchive(void* mem, u32 size, JKRMemBreakFlag breakFlag) : JKRArchive((s32)mem, MOUNT_MEM)
{
JKRMemArchive::JKRMemArchive(void* mem, u32 size, JKRMemBreakFlag breakFlag) : JKRArchive((s32)mem, MOUNT_MEM) {
mIsMounted = false;
if (!open(mem, size, breakFlag))
{
if (!open(mem, size, breakFlag)) {
return;
}
else
{
} else {
mVolumeType = 'RARC';
mVolumeName = &mStrTable[mDirectories->mOffset];
sVolumeList.prepend(&mFileLoaderLink);
@@ -42,10 +35,8 @@ JKRMemArchive::JKRMemArchive(void* mem, u32 size, JKRMemBreakFlag breakFlag) : J
}
}
JKRMemArchive::~JKRMemArchive()
{
if (mIsMounted == true)
{
JKRMemArchive::~JKRMemArchive() {
if (mIsMounted == true) {
if (mIsOpen && mArcHeader)
JKRFreeToHeap(mHeap, mArcHeader);
@@ -54,17 +45,16 @@ JKRMemArchive::~JKRMemArchive()
}
}
#if DEBUG // function is needed to generate certain strings first, however this is not what the original function looks like
void JKRMemArchive::fixedInit(s32)
{
#if DEBUG // function is needed to generate certain strings first, however this is not what the original function looks
// like
void JKRMemArchive::fixedInit(s32) {
JUT_ASSERT(isMounted());
JUT_PANIC("mMountCount == 1"); // some member is called mMountCount, if there's a game with this assert, fix
JUT_ASSERT(mArcHeader->signature == 'RARC');
}
#endif
bool JKRMemArchive::open(s32 entryNum, JKRArchive::EMountDirection mountDirection)
{
bool JKRMemArchive::open(s32 entryNum, JKRArchive::EMountDirection mountDirection) {
mArcHeader = nullptr;
mArcInfoBlock = nullptr;
mArchiveData = nullptr;
@@ -74,50 +64,39 @@ bool JKRMemArchive::open(s32 entryNum, JKRArchive::EMountDirection mountDirectio
mIsOpen = false;
mMountDirection = mountDirection;
if (mMountDirection == JKRArchive::MOUNT_DIRECTION_HEAD)
{
if (mMountDirection == JKRArchive::MOUNT_DIRECTION_HEAD) {
u32 loadedSize;
mArcHeader = (SArcHeader*)JKRDvdRipper::loadToMainRAM(
entryNum, nullptr, EXPAND_SWITCH_DECOMPRESS, 0, mHeap, JKRDvdRipper::ALLOC_DIR_TOP,
0, (int*)&mCompression);
mArcHeader = (SArcHeader*)JKRDvdRipper::loadToMainRAM(entryNum, nullptr, EXPAND_SWITCH_DECOMPRESS, 0, mHeap,
JKRDvdRipper::ALLOC_DIR_TOP, 0, (int*)&mCompression);
}
else
{
} else {
u32 loadedSize;
mArcHeader = (SArcHeader*)JKRDvdRipper::loadToMainRAM(
entryNum, nullptr, EXPAND_SWITCH_DECOMPRESS, 0, mHeap,
JKRDvdRipper::ALLOC_DIR_BOTTOM, 0, (int*)&mCompression);
mArcHeader = (SArcHeader*)JKRDvdRipper::loadToMainRAM(entryNum, nullptr, EXPAND_SWITCH_DECOMPRESS, 0, mHeap,
JKRDvdRipper::ALLOC_DIR_BOTTOM, 0, (int*)&mCompression);
}
if (!mArcHeader)
{
if (!mArcHeader) {
mMountMode = UNKNOWN_MOUNT_MODE;
}
else
{
} else {
JUT_ASSERT(mArcHeader->signature == 'RARC');
mArcInfoBlock = (SArcDataInfo*)((u8*)mArcHeader + mArcHeader->header_length);
mDirectories = (SDIDirEntry*)((u8*)&mArcInfoBlock->num_nodes + mArcInfoBlock->node_offset);
mFileEntries = (SDIFileEntry*)((u8*)&mArcInfoBlock->num_nodes + mArcInfoBlock->file_entry_offset);
mStrTable = (char*)((u8*)&mArcInfoBlock->num_nodes + mArcInfoBlock->string_table_offset);
mArchiveData =
(u8*)((u32)mArcHeader + mArcHeader->header_length + mArcHeader->file_data_offset);
mArchiveData = (u8*)((u32)mArcHeader + mArcHeader->header_length + mArcHeader->file_data_offset);
mIsOpen = true;
}
#if DEBUG
// OS Assert?
if (mMountMode == UNKNOWN_MOUNT_MODE)
{
if (mMountMode == UNKNOWN_MOUNT_MODE) {
OSReport(":::Cannot alloc memory [%s][%d]\n", __FILE__, 460);
}
#endif
return (mMountMode == UNKNOWN_MOUNT_MODE) ? false : true;
}
bool JKRMemArchive::open(void* buffer, u32 bufferSize, JKRMemBreakFlag flag)
{
bool JKRMemArchive::open(void* buffer, u32 bufferSize, JKRMemBreakFlag flag) {
mArcHeader = (SArcHeader*)buffer;
JUT_ASSERT(mArcHeader->signature == 'RARC');
mArcInfoBlock = (SArcDataInfo*)((u8*)mArcHeader + mArcHeader->header_length);
@@ -131,12 +110,11 @@ bool JKRMemArchive::open(void* buffer, u32 bufferSize, JKRMemBreakFlag flag)
return true;
}
void* JKRMemArchive::fetchResource(SDIFileEntry* fileEntry, u32* resourceSize)
{
void* JKRMemArchive::fetchResource(SDIFileEntry* fileEntry, u32* resourceSize) {
JUT_ASSERT(isMounted())
if (!fileEntry->mData)
fileEntry->mData = mArchiveData + fileEntry->mDataOffset;
if (!fileEntry->mData)
fileEntry->mData = mArchiveData + fileEntry->mDataOffset;
if (resourceSize)
*resourceSize = fileEntry->mSize;
@@ -144,43 +122,35 @@ void* JKRMemArchive::fetchResource(SDIFileEntry* fileEntry, u32* resourceSize)
return fileEntry->mData;
}
void* JKRMemArchive::fetchResource(void* buffer, u32 bufferSize, SDIFileEntry* fileEntry,
u32* resourceSize, JKRExpandSwitch expandSwitch)
{
void* JKRMemArchive::fetchResource(void* buffer, u32 bufferSize, SDIFileEntry* fileEntry, u32* resourceSize,
JKRExpandSwitch expandSwitch) {
JUT_ASSERT(isMounted())
bufferSize = (bufferSize & -32);
bufferSize = (bufferSize & -32);
u32 srcLength = ALIGN_NEXT(fileEntry->mSize, 32);
if (srcLength > bufferSize)
{
if (srcLength > bufferSize) {
srcLength = bufferSize;
}
if (fileEntry->mData != nullptr)
{
if (fileEntry->mData != nullptr) {
JKRHeap::copyMemory(buffer, fileEntry->mData, srcLength);
}
else
{
} else {
int compression = JKRConvertAttrToCompressionType(fileEntry->getAttr());
if (expandSwitch != EXPAND_SWITCH_DECOMPRESS)
compression = JKRCOMPRESSION_NONE;
void* data = mArchiveData + fileEntry->mDataOffset;
srcLength =
fetchResource_subroutine((u8*)data, srcLength, (u8*)buffer, bufferSize, compression);
srcLength = fetchResource_subroutine((u8*)data, srcLength, (u8*)buffer, bufferSize, compression);
}
if (resourceSize)
{
if (resourceSize) {
*resourceSize = srcLength;
}
return buffer;
}
void JKRMemArchive::removeResourceAll(void)
{
void JKRMemArchive::removeResourceAll(void) {
JUT_ASSERT(isMounted());
if (mArcInfoBlock == nullptr)
@@ -191,17 +161,14 @@ void JKRMemArchive::removeResourceAll(void)
// !@bug: looping over file entries without incrementing the fileEntry pointer. Thus, only the
// first fileEntry will clear/remove the resource data.
SDIFileEntry* fileEntry = mFileEntries;
for (int i = 0; i < mArcInfoBlock->num_file_entries; i++)
{
if (fileEntry->mData)
{
for (int i = 0; i < mArcInfoBlock->num_file_entries; i++) {
if (fileEntry->mData) {
fileEntry->mData = nullptr;
}
}
}
bool JKRMemArchive::removeResource(void* resource)
{
bool JKRMemArchive::removeResource(void* resource) {
JUT_ASSERT(isMounted());
SDIFileEntry* fileEntry = findPtrResource(resource);
@@ -212,35 +179,32 @@ bool JKRMemArchive::removeResource(void* resource)
return true;
}
u32 JKRMemArchive::fetchResource_subroutine(u8* src, u32 srcLength, u8* dst, u32 dstLength, int compression)
{
u32 JKRMemArchive::fetchResource_subroutine(u8* src, u32 srcLength, u8* dst, u32 dstLength, int compression) {
u32 alignedDst = dstLength & -32;
u32 alignedSrc = ALIGN_NEXT(srcLength, 32);
switch (compression)
{
case JKRCOMPRESSION_NONE:
if (alignedSrc > alignedDst)
alignedSrc = alignedDst;
switch (compression) {
case JKRCOMPRESSION_NONE:
if (alignedSrc > alignedDst)
alignedSrc = alignedDst;
JKRHeap::copyMemory(dst, src, alignedSrc);
return alignedSrc;
JKRHeap::copyMemory(dst, src, alignedSrc);
return alignedSrc;
case JKRCOMPRESSION_YAY0:
case JKRCOMPRESSION_YAZ0:
u32 expandSize = JKRDecompExpandSize(src);
case JKRCOMPRESSION_YAY0:
case JKRCOMPRESSION_YAZ0:
u32 expandSize = JKRDecompExpandSize(src);
if (expandSize > alignedDst) {
expandSize = alignedDst;
if (expandSize > alignedDst) {
expandSize = alignedDst;
}
JKRDecompress(src, dst, expandSize, 0);
return expandSize;
default: {
JPANIC(709, ":::??? bad sequence\n");
return 0;
}
JKRDecompress(src, dst, expandSize, 0);
return expandSize;
default:
{
JPANIC(709, ":::??? bad sequence\n");
return 0;
}
}
return alignedSrc;
+65 -80
View File
@@ -5,110 +5,95 @@
JSUList<JKRThread> JKRThread::sThreadList;
JKRThread::JKRThread(u32 stackSize, int msgCount, int threadPrio)
: mLink(this) {
this->mHeap = JKRHeap::findFromRoot(this);
if (this->mHeap == nullptr) {
this->mHeap = JKRHeap::sSystemHeap;
}
JKRThread::JKRThread(u32 stackSize, int msgCount, int threadPrio) : mLink(this) {
this->mHeap = JKRHeap::findFromRoot(this);
if (this->mHeap == nullptr) {
this->mHeap = JKRHeap::sSystemHeap;
}
this->mStackSize = JKR_ALIGN32(stackSize);
this->mStackMemory = JKRHeap::alloc(this->mStackSize, 32, this->mHeap);
this->mThreadRecord =
(OSThread*)JKRHeap::alloc(sizeof(OSThread), 32, this->mHeap);
OSCreateThread(this->mThreadRecord, &JKRThread::start, this,
(void*)((u32)this->mStackMemory + this->mStackSize),
this->mStackSize, threadPrio, OS_THREAD_ATTR_DETACH);
this->mMesgCount = msgCount;
this->mMesgBuffer = (OSMessage*)JKRHeap::alloc(
mMesgCount * sizeof(OSMessage), 0, this->mHeap);
OSInitMessageQueue(&this->mMesgQueue, this->mMesgBuffer, this->mMesgCount);
JKRThread::sThreadList.append(&this->mLink);
this->mStackSize = JKR_ALIGN32(stackSize);
this->mStackMemory = JKRHeap::alloc(this->mStackSize, 32, this->mHeap);
this->mThreadRecord = (OSThread*)JKRHeap::alloc(sizeof(OSThread), 32, this->mHeap);
OSCreateThread(this->mThreadRecord, &JKRThread::start, this, (void*)((u32)this->mStackMemory + this->mStackSize),
this->mStackSize, threadPrio, OS_THREAD_ATTR_DETACH);
this->mMesgCount = msgCount;
this->mMesgBuffer = (OSMessage*)JKRHeap::alloc(mMesgCount * sizeof(OSMessage), 0, this->mHeap);
OSInitMessageQueue(&this->mMesgQueue, this->mMesgBuffer, this->mMesgCount);
JKRThread::sThreadList.append(&this->mLink);
}
JKRThread::JKRThread(OSThread* threadRecord, int msgCount)
: mLink(this) {
this->mHeap = nullptr;
this->mThreadRecord = threadRecord;
this->mStackSize = (u32)threadRecord->stackEnd - (u32)threadRecord->stackBase;
this->mStackMemory = threadRecord->stackBase;
this->mMesgCount = msgCount;
this->mMesgBuffer = (OSMessage*)JKRHeap::sSystemHeap->alloc(
mMesgCount * sizeof(OSMessage), 4);
OSInitMessageQueue(&this->mMesgQueue, this->mMesgBuffer, this->mMesgCount);
JKRThread::sThreadList.append(&this->mLink);
JKRThread::JKRThread(OSThread* threadRecord, int msgCount) : mLink(this) {
this->mHeap = nullptr;
this->mThreadRecord = threadRecord;
this->mStackSize = (u32)threadRecord->stackEnd - (u32)threadRecord->stackBase;
this->mStackMemory = threadRecord->stackBase;
this->mMesgCount = msgCount;
this->mMesgBuffer = (OSMessage*)JKRHeap::sSystemHeap->alloc(mMesgCount * sizeof(OSMessage), 4);
OSInitMessageQueue(&this->mMesgQueue, this->mMesgBuffer, this->mMesgCount);
JKRThread::sThreadList.append(&this->mLink);
}
JKRThread::~JKRThread() {
JKRThread::sThreadList.remove(&this->mLink);
JKRThread::sThreadList.remove(&this->mLink);
if (this->mHeap != nullptr) {
if (!OSIsThreadTerminated(this->mThreadRecord)) {
OSDetachThread(this->mThreadRecord);
OSCancelThread(this->mThreadRecord);
if (this->mHeap != nullptr) {
if (!OSIsThreadTerminated(this->mThreadRecord)) {
OSDetachThread(this->mThreadRecord);
OSCancelThread(this->mThreadRecord);
}
JKRHeap::free(this->mStackMemory, this->mHeap);
JKRHeap::free(this->mThreadRecord, this->mHeap);
}
JKRHeap::free(this->mStackMemory, this->mHeap);
JKRHeap::free(this->mThreadRecord, this->mHeap);
}
JKRHeap::free(this->mMesgBuffer, nullptr);
JKRHeap::free(this->mMesgBuffer, nullptr);
}
void* JKRThread::start(void* thread) {
return static_cast<JKRThread*>(thread)->run();
return static_cast<JKRThread*>(thread)->run();
}
// UNUSED FUNCTIONS, REQUIRED FOR RTTI
JKRTask::JKRTask() : JKRThread(0x4000, 4, 31)
{
JKRTask::JKRTask() : JKRThread(0x4000, 4, 31) {
}
JKRTask::~JKRTask() { }
JKRTask::~JKRTask() {
}
JKRTask* JKRTask::create()
{
return new JKRTask();
JKRTask* JKRTask::create() {
return new JKRTask();
}
void JKRTask::destroy() {
delete this;
delete this;
}
void* JKRTask::run()
{
Request* req;
//OSInitFastCast();
while (true)
{
req = (Request*)waitMessageBlock();
if (req->mCb)
{
req->mCb(req->mArg);
if (mTaskMsgQueue)
{
OSSendMessage(mTaskMsgQueue, req->mMsg, OS_MESSAGE_NOBLOCK);
}
void* JKRTask::run() {
Request* req;
// OSInitFastCast();
while (true) {
req = (Request*)waitMessageBlock();
if (req->mCb) {
req->mCb(req->mArg);
if (mTaskMsgQueue) {
OSSendMessage(mTaskMsgQueue, req->mMsg, OS_MESSAGE_NOBLOCK);
}
}
req->mCb = nullptr;
}
req->mCb = nullptr;
}
}
bool JKRTask::request(RequestCallback callback, void* arg, void* msg)
{
Request* req = searchBlank();
if (req == nullptr)
{
return false;
}
req->mCb = callback;
req->mArg = arg;
req->mMsg = msg;
bool sendResult = OSSendMessage(&mMesgQueue, req, OS_MESSAGE_NOBLOCK);
if (!sendResult)
{
req->mCb = nullptr;
}
return sendResult;
bool JKRTask::request(RequestCallback callback, void* arg, void* msg) {
Request* req = searchBlank();
if (req == nullptr) {
return false;
}
req->mCb = callback;
req->mArg = arg;
req->mMsg = msg;
bool sendResult = OSSendMessage(&mMesgQueue, req, OS_MESSAGE_NOBLOCK);
if (!sendResult) {
req->mCb = nullptr;
}
return sendResult;
}
+36 -34
View File
@@ -1,51 +1,53 @@
#include "JSystem/JSupport/JSUStream.h"
JSUFileInputStream::JSUFileInputStream(JKRFile* file)
: mObject(file), mPosition(0) {}
JSUFileInputStream::JSUFileInputStream(JKRFile* file) : mObject(file), mPosition(0) {
}
int JSUFileInputStream::readData(void* buf, s32 len) {
int read = 0;
int read = 0;
if (((JKRFile*)this->mObject)->isAvailable()) {
/* Check if need to clamp length to EOF */
if ((u32)(this->mPosition + len) >
((JKRFile*)this->mObject)->getFileSize()) {
len = ((JKRFile*)this->mObject)->getFileSize() - this->mPosition;
if (((JKRFile*)this->mObject)->isAvailable()) {
/* Check if need to clamp length to EOF */
if ((u32)(this->mPosition + len) > ((JKRFile*)this->mObject)->getFileSize()) {
len = ((JKRFile*)this->mObject)->getFileSize() - this->mPosition;
}
if (len > 0) {
read = ((JKRFile*)this->mObject)->readData(buf, len, this->mPosition);
this->mPosition += read;
}
}
if (len > 0) {
read = ((JKRFile*)this->mObject)->readData(buf, len, this->mPosition);
this->mPosition += read;
}
}
return read;
return read;
}
int JSUFileInputStream::seekPos(s32 offset, JSUStreamSeekFrom from) {
int pos = this->mPosition;
int pos = this->mPosition;
switch (from) {
case SEEK_SET:
this->mPosition = offset;
break;
switch (from) {
case SEEK_SET:
this->mPosition = offset;
break;
case SEEK_END:
this->mPosition = ((JKRFile*)this->mObject)->getFileSize() - offset;
break;
case SEEK_END:
this->mPosition = ((JKRFile*)this->mObject)->getFileSize() - offset;
break;
case SEEK_CUR:
this->mPosition = pos + offset;
break;
}
case SEEK_CUR:
this->mPosition = pos + offset;
break;
}
if (this->mPosition < 0) {
this->mPosition = 0;
}
if (this->mPosition < 0) {
this->mPosition = 0;
}
if (this->mPosition > (s32)((JKRFile*)this->mObject)->getFileSize()) {
this->mPosition = ((JKRFile*)this->mObject)->getFileSize();
}
if (this->mPosition > (s32)((JKRFile*)this->mObject)->getFileSize()) {
this->mPosition = ((JKRFile*)this->mObject)->getFileSize();
}
return this->mPosition - pos;
return this->mPosition - pos;
}
JSUFileOutputStream::JSUFileOutputStream(JKRFile* file) {
}
+75 -75
View File
@@ -1,120 +1,120 @@
#include "JSystem/JSupport/JSUStream.h"
JSUInputStream::~JSUInputStream() { }
JSUInputStream::~JSUInputStream() {
}
int JSUInputStream::read(void* buf, s32 size) {
int len = this->readData(buf, size);
if (len != size) {
this->setState(EOF);
}
return len;
int len = this->readData(buf, size);
if (len != size) {
this->setState(EOF);
}
return len;
}
char* JSUInputStream::read(char* str) {
u16 size;
int len = this->readData(&size, sizeof(size));
if (len != sizeof(size)) {
str[0] = '\0';
this->setState(EOF);
str = nullptr;
}
else {
int strRead = this->readData(str, size);
str[strRead] = '\0';
if (strRead != size) {
this->setState(EOF);
u16 size;
int len = this->readData(&size, sizeof(size));
if (len != sizeof(size)) {
str[0] = '\0';
this->setState(EOF);
str = nullptr;
} else {
int strRead = this->readData(str, size);
str[strRead] = '\0';
if (strRead != size) {
this->setState(EOF);
}
}
}
return str;
return str;
}
/* @fabricated -- this method is confirmed to exist, but goes unused in AC */
char* JSUInputStream::readString() {
u16 len;
int r = this->readData(&len, sizeof(len));
if (r != sizeof(len)) {
this->setState(EOF);
return nullptr;
}
u16 len;
int r = this->readData(&len, sizeof(len));
if (r != sizeof(len)) {
this->setState(EOF);
return nullptr;
}
char* buf = new char[len+1];
r = this->readData(buf, len);
if (r != len) {
delete[] buf;
this->setState(EOF);
return nullptr;
}
char* buf = new char[len + 1];
r = this->readData(buf, len);
if (r != len) {
delete[] buf;
this->setState(EOF);
return nullptr;
}
buf[len] = '\0';
return buf;
buf[len] = '\0';
return buf;
}
/* @fabricated -- this method is confirmed to exist, but goes unused in AC */
char* JSUInputStream::readString(char* buf, u16 len) {
int r = this->readData(buf, len);
if (r != len) {
this->setState(EOF);
return nullptr;
}
int r = this->readData(buf, len);
if (r != len) {
this->setState(EOF);
return nullptr;
}
buf[len] = '\0';
return buf;
buf[len] = '\0';
return buf;
}
int JSUInputStream::skip(s32 amount) {
u8 _p;
int i;
u8 _p;
int i;
for (i = 0; i < amount; i++) {
if (this->readData(&_p, sizeof(_p)) != sizeof(_p)) {
this->setState(EOF);
break;
for (i = 0; i < amount; i++) {
if (this->readData(&_p, sizeof(_p)) != sizeof(_p)) {
this->setState(EOF);
break;
}
}
}
return i;
return i;
}
/* JSURandomInputStream */
int JSURandomInputStream::skip(s32 amount) {
int s = this->seekPos(amount, SEEK_CUR);
if (s != amount) {
this->setState(EOF);
}
return s;
int s = this->seekPos(amount, SEEK_CUR);
if (s != amount) {
this->setState(EOF);
}
return s;
}
/* This method is confirmed to exist, but goes unused in AC. Retrieved from TP debug. */
int JSURandomInputStream::align(s32 alignment) {
int pos = this->getPosition();
int aligned = ((alignment-1) + pos) & ~(alignment-1);
int change = aligned - pos;
int pos = this->getPosition();
int aligned = ((alignment - 1) + pos) & ~(alignment - 1);
int change = aligned - pos;
if (change != 0) {
int s = this->seekPos(aligned, SEEK_SET);
if (s != change) {
this->setState(EOF);
if (change != 0) {
int s = this->seekPos(aligned, SEEK_SET);
if (s != change) {
this->setState(EOF);
}
}
}
return change;
return change;
}
/* This method is confirmed to exist, but goes unused in AC. Retrieved from TP debug. */
int JSURandomInputStream::peek(void* buf, s32 len) {
int pos = this->getPosition();
int r = this->read(buf, len);
if (r != 0) {
this->seekPos(pos, SEEK_SET);
}
int pos = this->getPosition();
int r = this->read(buf, len);
if (r != 0) {
this->seekPos(pos, SEEK_SET);
}
return r;
}
return r;
}
int JSURandomInputStream::seek(s32 offset, JSUStreamSeekFrom from) {
int s = this->seekPos(offset, from);
this->clrState(EOF);
return s;
int s = this->seekPos(offset, from);
this->clrState(EOF);
return s;
}
+158
View File
@@ -0,0 +1,158 @@
#include "JSystem/JSupport/JSUList.h"
JSUPtrLink::JSUPtrLink(void* pData) {
mPtrList = 0;
mData = pData;
mPrev = 0;
mNext = 0;
}
JSUPtrLink::~JSUPtrLink() {
if (mPtrList) {
mPtrList->remove(this);
}
}
JSUPtrList::JSUPtrList(bool doInitialize) {
if (doInitialize) {
initiate();
}
}
JSUPtrList::~JSUPtrList() {
JSUPtrLink* curHead = mHead;
for (int i = 0; i < mLinkCount; i++) {
curHead->mPtrList = 0;
curHead = curHead->mNext;
}
}
void JSUPtrList::initiate() {
mHead = 0;
mTail = 0;
mLinkCount = 0;
}
void JSUPtrList::setFirst(JSUPtrLink* pLink) {
pLink->mPtrList = this;
pLink->mPrev = 0;
pLink->mNext = 0;
mTail = pLink;
mHead = pLink;
mLinkCount = 1;
}
bool JSUPtrList::append(JSUPtrLink* pLink) {
bool validity = (pLink->mPtrList == 0);
if (!validity) {
validity = pLink->mPtrList->remove(pLink);
}
if (validity) {
if (!mLinkCount) {
setFirst(pLink);
} else {
pLink->mPtrList = this;
pLink->mPrev = mTail;
pLink->mNext = 0;
mTail->mNext = pLink;
mTail = pLink;
mLinkCount = mLinkCount + 1;
}
}
return validity;
}
bool JSUPtrList::prepend(JSUPtrLink* pLink) {
bool validity = (pLink->mPtrList == 0);
if (!validity) {
validity = pLink->mPtrList->remove(pLink);
}
if (validity) {
if (!mLinkCount) {
setFirst(pLink);
} else {
pLink->mPtrList = this;
pLink->mPrev = 0;
pLink->mNext = mHead;
mHead->mPrev = pLink;
mHead = pLink;
mLinkCount = mLinkCount + 1;
}
}
return validity;
}
bool JSUPtrList::insert(JSUPtrLink* pLink_1, JSUPtrLink* pLink_2) {
if (pLink_1 == mHead) {
return prepend(pLink_2);
}
if (!pLink_1) {
return append(pLink_2);
}
if (pLink_1->mPtrList != this) {
return false;
}
JSUPtrList* link2PtrList = pLink_2->mPtrList;
bool validity = (link2PtrList == 0);
if (!validity) {
validity = link2PtrList->remove(pLink_2);
}
if (validity) {
JSUPtrLink* prev = pLink_1->mPrev;
pLink_2->mPtrList = this;
pLink_2->mPrev = prev;
pLink_2->mNext = pLink_1;
prev->mNext = pLink_2;
pLink_1->mPrev = pLink_2;
mLinkCount++;
}
return validity;
}
bool JSUPtrList::remove(JSUPtrLink* pLink) {
bool isSameList = (pLink->mPtrList == this);
if (isSameList) {
if (mLinkCount == 1) {
mHead = 0;
mTail = 0;
} else if (pLink == mHead) {
pLink->mNext->mPrev = 0;
mHead = pLink->mNext;
} else if (pLink == mTail) {
pLink->mPrev->mNext = 0;
mTail = pLink->mPrev;
} else {
pLink->mPrev->mNext = pLink->mNext;
pLink->mNext->mPrev = pLink->mPrev;
}
pLink->mPtrList = 0;
mLinkCount--;
}
return isSameList;
}
JSUPtrLink* JSUPtrList::getNthLink(u32 n) const {
if (n >= mLinkCount) {
return nullptr;
}
JSUPtrLink* curHead = mHead;
for (int i = 0; i < n; i++) {
curHead = curHead->mNext;
}
return curHead;
}
+64
View File
@@ -0,0 +1,64 @@
#include <dolphin/pad.h>
#include <dolphin/vi.h>
#include "JSystem/JUtility/JUTAssertion.h"
#include "JSystem/JUtility/JUTConsole.h"
#include "JSystem/JUtility/JUTDbPrint.h"
#include "JSystem/JUtility/JUTDirectPrint.h"
namespace JUTAssertion {
namespace {
static u32 sMessageLife;
static u32 sMessageOwner;
static bool mSynchro;
static char sMessageFileLine[64];
static char sMessageString[96];
static u32 sDisplayTime = -1;
static u32 sDevice = 3;
static bool sVisible = true;
} // namespace
void create() {
}
u32 flush_subroutine() {
if (sMessageLife == 0) {
return 0;
}
if (sMessageLife != -1) {
sMessageLife--;
}
if (sMessageLife < 5) {
return 0;
}
return sMessageLife;
}
void flushMessage() {
if (flush_subroutine() && sVisible == true) {
JUTDirectPrint::getManager()->drawString(16, 16, sMessageFileLine);
JUTDirectPrint::getManager()->drawString(16, 24, sMessageString);
}
}
void flushMessage_dbPrint() {
if (flush_subroutine() && sVisible == true && JUTDbPrint::getManager()) {
JUTFont* font = JUTDbPrint::getManager()->getFont();
if (font) {
u8 tmp = ((VIGetRetraceCount() & 60) << 2) | 0xF;
font->setGX();
font->setCharColor(JUtility::TColor(255, tmp, tmp, 255));
font->drawString(30, 36, sMessageFileLine, true);
font->drawString(30, 54, sMessageString, true);
}
}
}
void changeDisplayTime(u32 time) {
sDisplayTime = time;
}
void changeDevice(u32 device) {
sDevice = device;
}
} // namespace JUTAssertion
+478
View File
@@ -0,0 +1,478 @@
#include <MSL_C/printf.h>
#include <dolphin/os.h>
#include <dolphin/vi.h>
#include "JSystem/J2D/J2DGrafContext.h"
#include "JSystem/JKernel/JKRHeap.h"
#include "JSystem/JUtility/JUTConsole.h"
#include "JSystem/JUtility/JUTDirectPrint.h"
#include "JSystem/JUtility/JUTVideo.h"
#define OUTPUT_NONE 0
#define OUTPUT_CONSOLE 1
#define OUTPUT_OSREPORT 2
#define OUTPUT_ALL (OUTPUT_OSREPORT | OUTPUT_CONSOLE)
JUTConsoleManager* JUTConsoleManager::sManager;
JUTConsole* JUTConsole::create(uint param_0, uint maxLines, JKRHeap* pHeap) {
JUTConsoleManager* const pManager = JUTConsoleManager::getManager();
JUT_ASSERT(pManager != 0);
u8* buffer = (u8*)JKRAllocFromHeap(pHeap, getObjectSizeFromBufferSize(param_0, maxLines), 0);
JUTConsole* newConsole = new (buffer) JUTConsole(param_0, maxLines, true);
newConsole->mBuf = buffer + sizeof(JUTConsole);
newConsole->clear();
pManager->appendConsole(newConsole);
return newConsole;
}
JUTConsole* JUTConsole::create(uint param_0, void* buffer, u32 bufferSize) {
JUTConsoleManager* const pManager = JUTConsoleManager::getManager();
JUT_ASSERT(pManager != 0);
JUT_ASSERT(( (u32)buffer & 0x3 ) == 0);
u32 maxLines = getLineFromObjectSize(bufferSize, param_0);
JUTConsole* newConsole = new (buffer) JUTConsole(param_0, maxLines, false);
newConsole->mBuf = (u8*)buffer + sizeof(JUTConsole);
newConsole->clear();
pManager->appendConsole(newConsole);
return newConsole;
}
// unused
void JUTConsole::destroy(JUTConsole* console) {
JUT_ASSERT(console != 0);
delete console;
}
JUTConsole::JUTConsole(uint p1, uint maxLines, bool p3) {
_2C = p3;
_20 = p1;
mMaxLines = maxLines;
mPositionX = 30;
mPositionY = 50;
mHeight = 20;
if (mHeight > mMaxLines) {
mHeight = mMaxLines;
}
mFont = nullptr;
mIsVisible = true;
_65 = false;
_66 = false;
mOutput = 1;
_5C = JUtility::TColor(0, 0, 0, 100);
_60 = JUtility::TColor(0, 0, 0, 230);
}
JUTConsole::~JUTConsole() {
JUT_ASSERT(JUTConsoleManager::getManager())
JUTConsoleManager::getManager()->removeConsole(this);
}
size_t JUTConsole::getObjectSizeFromBufferSize(unsigned int p1, unsigned int maxLines) {
int objSize = (p1 + 2) * maxLines + sizeof(JUTConsole);
return objSize;
}
size_t JUTConsole::getLineFromObjectSize(u32 bufferSize, unsigned int param_1) {
bufferSize -= sizeof(JUTConsole);
int line = (bufferSize) / (param_1 + 2);
return line;
}
void JUTConsole::clear() {
_30 = 0;
_34 = 0;
_38 = 0;
_3C = 0;
for (int i = 0; i < mMaxLines; i++) {
setLineAttr(i, 0);
}
setLineAttr(0, -1);
*getLinePtr(0) = 0;
}
void JUTConsole::doDraw(JUTConsole::EConsoleType consoleType) const {
f32 font_yOffset;
s32 changeLine_1;
s32 changeLine_2;
if (mIsVisible && (mFont || consoleType == CONSOLE_TYPE_2)) {
if (mHeight != 0) {
bool isConsoleType0 = consoleType == CONSOLE_TYPE_0 ? true : false;
font_yOffset = 2.0f + mFontSizeY;
if (consoleType != CONSOLE_TYPE_2) {
if (!JUTVideo::getManager()) {
J2DOrthoGraph ortho(0.0f, 0.0f, 640.0f, 480.0f, -1.0f, 1.0f);
ortho.setPort();
} else {
f32 w = JUTVideo::getManager()->getFbWidth();
f32 h = JUTVideo::getManager()->getEfbHeight();
J2DOrthoGraph ortho(0.0f, 0.0f, w, h, -1.0f, 1.0f);
ortho.setPort();
}
const JUtility::TColor* color;
if (isConsoleType0) {
color = &_60;
} else {
color = &_5C;
}
J2DFillBox(mPositionX - 2, (int)(mPositionY - font_yOffset), (int)((mFontSizeX * _20) + 4.0f),
(int)(font_yOffset * mHeight), *color);
mFont->setGX();
if (isConsoleType0) {
s32 s = (diffIndex(_30, _38) - mHeight) + 1;
if (s <= 0) {
mFont->setCharColor(JUtility::TColor(255, 255, 255, 255));
} else if (_30 == _34) {
mFont->setCharColor(JUtility::TColor(255, 230, 230, 255));
} else {
mFont->setCharColor(JUtility::TColor(230, 230, 255, 255));
}
} else {
mFont->setCharColor(JUtility::TColor(230, 230, 230, 255));
}
} else {
JUTDirectPrint::getManager()->erase(mPositionX - 3, mPositionY - 2, (_20 * 6) + 6,
(int)(font_yOffset * mHeight) + 4);
}
char* linePtr;
s32 curLine = _30;
s32 yFactor = 0;
do {
linePtr = (char*)getLinePtr(curLine);
if ((u8)linePtr[-1] != 0) {
if (consoleType != CONSOLE_TYPE_2) {
mFont->drawString_scale(mPositionX, ((yFactor * font_yOffset) + mPositionY), mFontSizeX,
mFontSizeY, linePtr, true);
} else {
JUTDirectPrint::getManager()->drawString(mPositionX, ((yFactor * font_yOffset) + mPositionY),
linePtr);
}
changeLine_1 = curLine + 1;
changeLine_2 = ((((s32)changeLine_1) >= (s32)mMaxLines)) ? 0 : changeLine_1;
yFactor += 1;
curLine = changeLine_2;
} else {
break;
}
} while (yFactor < mHeight && changeLine_2 != _34);
}
}
}
void JUTConsole::print_f(char const* text, ...) {
va_list args;
va_start(args, text);
JUTConsole_print_f_va_(this, text, args);
va_end(args);
}
void JUTConsole::print(char const* param_0) {
if (mOutput & OUTPUT_OSREPORT) {
// JUT_REPORT_MSG("%s", param_0);
}
if (mOutput & OUTPUT_CONSOLE) {
const u8* r29 = (const u8*)param_0;
u8* r28 = getLinePtr(_38) + _3C;
while (*r29 != 0) {
if (_66 && _34 == nextIndex(_38)) {
break;
}
if (*r29 == '\n') {
r29++;
_3C = _20;
} else if (*r29 == '\t') {
r29++;
while (_3C < _20) {
*(r28++) = ' ';
_3C++;
if (_3C % 8 == 0) {
break;
}
}
} else if (mFont && mFont->isLeadByte(*r29)) {
if (_3C + 1 < _20) {
*(r28++) = *(r29++);
*(r28++) = *(r29++);
_3C++;
_3C++;
} else {
*(r28++) = 0;
_3C++;
}
} else {
*(r28++) = *(r29++);
_3C++;
}
if (_3C < _20) {
continue;
}
*r28 = 0;
_38 = nextIndex(_38);
_3C = 0;
setLineAttr(_38, 0xff);
r28 = getLinePtr(_38);
*r28 = 0;
int local_28 = diffIndex(_30, _38);
if (local_28 == mHeight) {
_30 = nextIndex(_30);
}
if (_38 == _34) {
_34 = nextIndex(_34);
}
if (_38 == _30) {
_30 = nextIndex(_30);
}
}
*r28 = 0;
}
}
void JUTConsole_print_f_va_(JUTConsole* console, const char* text, va_list args) {
char buf[1024];
JUT_ASSERT(console!=0);
vsnprintf(buf, sizeof(buf), text, args);
console->print(buf);
}
void JUTConsole::dumpToTerminal(unsigned int n) {
if (n == 0) {
return;
}
int lineNo = _34;
if (n != 0xffffffff) {
lineNo = _38;
while (n--) {
int prevIdx = prevIndex(lineNo);
if (!getLineAttr(prevIdx)) {
break;
}
lineNo = prevIdx;
if (prevIdx == _34) {
break;
}
}
}
// OSReport("\n:::dump of console[%x]--------------------------------\n", this);
int i = 0;
do {
u8* line = getLinePtr(lineNo);
if ((u8)line[-1] == 0) {
break;
}
if (_65) {
OSReport("[%03d] %s\n", i, line);
} else {
OSReport("%s\n", line);
}
lineNo = nextIndex(lineNo);
i++;
} while (lineNo != _34);
// OSReport(":::dump of console[%x] END----------------------------\n", this);
}
void JUTConsole::scroll(int scrollAmnt) {
if (scrollAmnt < 0) {
int diff = diffIndex(_34, _30);
if (scrollAmnt < -diff) {
scrollAmnt = -diff;
}
} else {
if (scrollAmnt > 0) {
if (diffIndex(_34, _38) + 1 <= mHeight) {
scrollAmnt = 0;
} else {
int diff = diffIndex(_30, _38) - mHeight + 1;
if (scrollAmnt > diff) {
scrollAmnt = diff;
}
}
}
}
_30 += scrollAmnt;
if (_30 < 0) {
_30 += mMaxLines;
}
if (_30 >= mMaxLines) {
_30 -= mMaxLines;
}
}
int JUTConsole::getUsedLine() const {
int usedLine = diffIndex(_34, _38);
return usedLine;
}
int JUTConsole::getLineOffset() const {
int offset = diffIndex(_34, _30);
return offset;
}
JUTConsoleManager::JUTConsoleManager() {
mActiveConsole = nullptr;
mDirectConsole = nullptr;
}
JUTConsoleManager* JUTConsoleManager::createManager(JKRHeap* pHeap) {
JUT_ASSERT(sManager == 0);
if (pHeap == nullptr) {
pHeap = JKRGetCurrentHeap();
}
sManager = new (pHeap, 0) JUTConsoleManager();
return sManager;
}
void JUTConsoleManager::appendConsole(JUTConsole* const console) {
JUT_ASSERT(sManager != 0 && console != 0);
JUT_ASSERT(soLink_.Find( console ) == soLink_.end());
soLink_.Push_back(console);
if (mActiveConsole == nullptr) {
mActiveConsole = console;
}
}
void JUTConsoleManager::removeConsole(JUTConsole* const console) {
JUT_ASSERT(sManager != 0 && console != 0);
JUT_ASSERT(soLink_.Find( console ) != soLink_.end());
if (mActiveConsole == console) {
if (soLink_.size() <= 1) {
mActiveConsole = nullptr;
} else {
mActiveConsole =
console != &soLink_.back() ? soLink_.Element_toValue(console->mNode.getNext()) : &soLink_.front();
}
}
if (JUTGetWarningConsole() == console)
JUTSetWarningConsole(nullptr);
if (JUTGetReportConsole() == console)
JUTSetReportConsole(nullptr);
soLink_.Remove(console);
}
void JUTConsoleManager::draw() const {
// this cast is needed to match release, luckily doesn't affect tp debug either, so maybe there's another temp or
// cast somewhere?
JGadget::TLinkList<JUTConsole, -24>::const_iterator it = ((const JUTConsoleManager*)this)->soLink_.begin();
JGadget::TLinkList<JUTConsole, -24>::const_iterator itEnd = soLink_.end();
for (; it != itEnd; ++it) {
const JUTConsole& console = *it;
if (&console != mActiveConsole) {
console.doDraw(JUTConsole::CONSOLE_TYPE_1);
}
}
if (mActiveConsole)
mActiveConsole->doDraw(JUTConsole::CONSOLE_TYPE_0);
}
void JUTConsoleManager::drawDirect(bool waitRetrace) const {
if (mDirectConsole) {
if (waitRetrace) {
BOOL interrupt = OSEnableInterrupts();
u32 retrace_count = VIGetRetraceCount();
do {
} while (retrace_count == VIGetRetraceCount());
OSRestoreInterrupts(interrupt);
}
mDirectConsole->doDraw(JUTConsole::CONSOLE_TYPE_2);
}
}
void JUTConsoleManager::setDirectConsole(JUTConsole* console) {
if (mDirectConsole != nullptr) {
appendConsole(mDirectConsole);
}
if (console != nullptr) {
removeConsole(console);
}
mDirectConsole = console;
}
static JUTConsole* sReportConsole;
static JUTConsole* sWarningConsole;
// C Functions
void JUTSetReportConsole(JUTConsole* console) {
sReportConsole = console;
}
JUTConsole* JUTGetReportConsole() {
return sReportConsole;
}
void JUTSetWarningConsole(JUTConsole* console) {
sWarningConsole = console;
}
JUTConsole* JUTGetWarningConsole() {
return sWarningConsole;
}
void JUTReportConsole_f_va(const char* text, va_list args) {
char buf[256];
if (!JUTGetReportConsole()) {
vsnprintf(buf, sizeof(buf), text, args);
// JUT_REPORT_MSG("%s", buf);
} else if (JUTGetReportConsole()->getOutput() & OUTPUT_ALL) {
vsnprintf(buf, sizeof(buf), text, args);
JUTGetReportConsole()->print(buf);
}
}
void JUTReportConsole_f(const char* text, ...) {
va_list vl;
va_start(vl, text);
JUTReportConsole_f_va(text, vl);
va_end(vl);
}
void JUTReportConsole(const char* text) {
JUTReportConsole_f("%s", text);
}
void JUTWarningConsole_f_va(const char* text, va_list args) {
char buf[256];
if (!JUTGetWarningConsole()) {
vsnprintf(buf, sizeof(buf), text, args);
OSReport("%s", buf);
} else if (JUTGetWarningConsole()->getOutput() & OUTPUT_ALL) {
vsnprintf(buf, sizeof(buf), text, args);
JUTGetWarningConsole()->print(buf);
}
}
void JUTWarningConsole_f(const char* text, ...) {
va_list vl;
va_start(vl, text);
JUTReportConsole_f_va(text, vl);
va_end(vl);
}
void JUTWarningConsole(const char* text) {
JUTReportConsole_f("%s", text);
}
+111
View File
@@ -0,0 +1,111 @@
#include "MSL_C/printf.h"
#include "JSystem/JUtility/JUTDbPrint.h"
#include "JSystem/J2D/J2DGrafContext.h"
#include "JSystem/JKernel/JKRHeap.h"
#include "JSystem/JUtility/JUTFont.h"
#include "JSystem/JUtility/JUTVideo.h"
#include "types.h"
JUTDbPrint* JUTDbPrint::sDebugPrint;
JUTDbPrint::JUTDbPrint(JUTFont* font, JKRHeap* heap) : mColor() {
mFont = font;
mList = nullptr;
mHeap = (heap) ? heap : JKRHeap::getCurrentHeap();
mColor = TCOLOR_WHITE;
mVisible = true;
}
JUTDbPrint::~JUTDbPrint() {
}
JUTDbPrint* JUTDbPrint::start(JUTFont* font, JKRHeap* heap) {
if (!sDebugPrint) {
if (!heap) {
heap = JKRHeap::getCurrentHeap();
}
sDebugPrint = new JUTDbPrint(font, heap);
}
return sDebugPrint;
}
JUTFont* JUTDbPrint::changeFont(JUTFont* newFont) {
JUTFont* oldFont = mFont;
if (newFont) {
mFont = newFont;
}
return oldFont;
}
void JUTDbPrint::enter(int x, int y, int duration, const char* txt, int len) {
if (len > 0) {
JUTDbPrintList* pList = (JUTDbPrintList*)JKRAllocFromHeap(mHeap, sizeof(JUTDbPrintList) + len, -4);
if (pList) {
pList->mX = x;
pList->mY = y;
pList->mDuration = duration;
pList->mLen = len;
strcpy((char*)&pList->mStr, txt);
pList->mNext = mList;
mList = pList;
}
}
}
void JUTDbPrint::flush() {
// eyebrow raise emoji
JUTDbPrintList* pList = (JUTDbPrintList*)&mList;
JUTDbPrintList* currList = mList;
if (mFont) {
if (currList) {
J2DOrthoGraph orthograph(0.0f, 0.0f, 640.0f, 480.0f, -1.0f, 1.0f);
orthograph.setPort();
mFont->setGX();
mFont->setCharColor(mColor);
while (currList) {
if (mVisible) {
drawString(currList->mX, currList->mY, currList->mLen, &currList->mStr);
}
if (--currList->mDuration <= 0) {
JUTDbPrintList* next = currList->mNext;
JKRFreeToHeap(mHeap, currList);
pList->mNext = next;
currList = next;
} else {
pList = currList;
currList = currList->mNext;
}
}
}
}
}
void JUTDbPrint::flush(int left, int top, int right, int bottom) {
}
void JUTDbPrint::drawString(int x, int y, int len, const unsigned char* str) {
mFont->drawString_size(x, y, reinterpret_cast<const char*>(str), len, true);
}
void JUTReport(int x, int y, const char* fmt, ...) {
va_list vl;
va_start(vl, fmt);
char buf[128];
s32 n = vsnprintf(buf, sizeof(buf), fmt, vl);
if (n >= 0) {
JUTDbPrint::getManager()->enter(x, y, 1, buf, n < 256 ? n : 255);
}
va_end();
}
void JUTReport(int x, int y, int duration, const char* fmt, ...) {
va_list vl;
va_start(vl, fmt);
char buf[256];
s32 n = vsnprintf(buf, sizeof(buf), fmt, vl);
if (n >= 0) {
JUTDbPrint::getManager()->enter(x, y, duration, buf, n < 256 ? n : 255);
}
va_end(vl);
}
@@ -0,0 +1,161 @@
#include <dolphin/os.h>
#include "JSystem/JUtility/JUTDirectFile.h"
int JUTDirectFile::fetch32byte() {
mToRead = mLength - ALIGN_PREV(mPos, DVD_MIN_TRANSFER_SIZE);
if (mToRead > JUTDF_BUFSIZE) {
mToRead = JUTDF_BUFSIZE;
}
int interrupts = OSEnableInterrupts();
int readRes = DVDReadAsync(&mFileInfo, mSectorStart, ALIGN_NEXT(mToRead, DVD_MIN_TRANSFER_SIZE),
ALIGN_PREV(mPos, DVD_MIN_TRANSFER_SIZE), nullptr);
OSRestoreInterrupts(interrupts);
if (!readRes) {
return -1;
} else {
interrupts = OSEnableInterrupts();
while (DVDGetCommandBlockStatus(&mFileInfo.cb)) {
;
}
OSRestoreInterrupts(interrupts);
return mToRead;
}
}
JUTDirectFile::JUTDirectFile() {
mLength = 0;
mPos = 0;
mToRead = 0;
mSectorStart = (u8*)ALIGN_NEXT((u32)mBuffer, DVD_MIN_TRANSFER_SIZE);
mIsOpen = false;
}
JUTDirectFile::~JUTDirectFile() {
mIsOpen = false;
}
bool JUTDirectFile::fopen(const char* filename) {
if (!filename) {
return false;
}
int interrupts = OSEnableInterrupts();
int dvdRes = DVDOpen(const_cast<char*>(filename), &mFileInfo);
OSRestoreInterrupts(interrupts);
if (!dvdRes) {
mIsOpen = false;
return false;
}
int interrupts2 = OSEnableInterrupts();
mLength = mFileInfo.length;
OSRestoreInterrupts(interrupts2);
mPos = 0;
mIsOpen = true;
return true;
}
void JUTDirectFile::fclose() {
if (mIsOpen) {
int interrupts = OSEnableInterrupts();
DVDClose(&mFileInfo);
OSRestoreInterrupts(interrupts);
mIsOpen = false;
}
}
/*
* Gets data of length 'len' and stores in 'buf'.
* Returns actual length gotten in bytes, or -1 if error.
*/
int JUTDirectFile::fgets(void* buf, int len) {
// if file isn't open, return error (-1).
if (!mIsOpen) {
return -1;
}
// if desired length to get is 0, get... 0 bytes.
if (len == 0) {
return 0;
}
// if desired length to get is 1, return 1.
// (final byte gotten is always 0, so len 1 is pointless).
if (len == 1) {
return 1;
}
// if buffer to read into doesn't exist, return error.
if (!buf) {
return -1;
}
// if we're already beyond the file length, return error.
if (mPos >= mLength) {
return -1;
}
int readMax;
u8* byteBuf = (u8*)buf;
readMax = len - 1; // desired bytes of data to get (last value is then 0).
int readCount = 0;
while (mPos < mLength) {
// if there's nothing left to read, return error.
if (mToRead == 0 && fetch32byte() < 0) {
return -1;
}
// read in each chunk.
u32 currPos = mPos & (JUTDF_BUFSIZE - 1);
u32 chunkSize = (mToRead - currPos);
if (readCount + chunkSize > readMax) {
chunkSize = len - readCount - 1;
}
BOOL isAtEnd = FALSE;
for (int i = 0; i < chunkSize; i++) {
u8 byte = mSectorStart[currPos++];
*byteBuf++ = byte;
// if we hit the end of a line, stop reading.
if (byte == '\n') {
chunkSize = i + 1;
isAtEnd = TRUE;
break;
}
}
// if we exceed the buffer size, stop reading.
if (currPos >= JUTDF_BUFSIZE) {
mToRead = 0;
}
// if we hit the end of a line, set final byte to 0 and stop reading.
if (isAtEnd == TRUE) {
readCount += chunkSize;
*byteBuf = 0;
mPos += chunkSize;
break;
}
// we should have read the full chunkSize, so update count/pos.
readCount += chunkSize;
mPos += chunkSize;
// if we're at (or beyond) our desired length, set final byte to 0 and stop reading.
if (readCount >= readMax) {
*byteBuf = 0;
break;
}
}
// if got to the end of the data, set final byte to 0.
if (mPos >= mLength) {
*byteBuf = 0;
}
return readCount;
}
@@ -0,0 +1,177 @@
#include <dolphin/os.h>
#include "MSL_C/printf.h"
#include "JSystem/JUtility/JUTDirectPrint.h"
JUTDirectPrint* JUTDirectPrint::sDirectPrint;
JUTDirectPrint::JUTDirectPrint() {
changeFrameBuffer(nullptr, 0, 0);
}
JUTDirectPrint* JUTDirectPrint::start() {
if (!sDirectPrint) {
sDirectPrint = new JUTDirectPrint();
}
return sDirectPrint;
}
void JUTDirectPrint::erase(int x, int y, int width, int height) {
if (!mFramebuffer) {
return;
}
if (400 < mFbWidth) {
x = x << 1;
width = width << 1;
}
if (300 < mFbHeight) {
y = y << 1;
height = height << 1;
}
u16* pixel = mFrameMemory + mStride * y + x;
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
*pixel = 0x1080;
pixel = pixel + 1;
}
pixel += mStride - width;
}
}
u8 JUTDirectPrint::sAsciiTable[128] = {
0x7A, 0x7A, 0x7A, 0x7A, 0x7A, 0x7A, 0x7A, 0x7A, 0x7A, 0xFD, 0xFE, 0x7A, 0x7A, 0x7A, 0x7A, 0x7A, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x29, 0x64, 0x65, 0x66, 0x2B,
0x67, 0x68, 0x25, 0x26, 0x69, 0x2A, 0x6A, 0x27, 0x2C, 0x6B, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
0x09, 0x24, 0x6C, 0x6D, 0x6E, 0x6F, 0x28, 0x70, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14,
0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x71, 0x72, 0x73, 0x74,
0x75, 0xFF, 0x7D, 0x7E, 0x7F, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D,
0x8E, 0x8F, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x76, 0x77, 0x78, 0x79, 0x7A,
};
u32 JUTDirectPrint::sFontData[64] = {
0x70871C30, 0x8988A250, 0x88808290, 0x88830C90, 0x888402F8, 0x88882210, 0x71CF9C10, 0xF9CF9C70,
0x8208A288, 0xF200A288, 0x0BC11C78, 0x0A222208, 0x8A222208, 0x71C21C70, 0x23C738F8, 0x5228A480,
0x8A282280, 0x8BC822F0, 0xFA282280, 0x8A28A480, 0x8BC738F8, 0xF9C89C08, 0x82288808, 0x82088808,
0xF2EF8808, 0x82288888, 0x82288888, 0x81C89C70, 0x8A08A270, 0x920DA288, 0xA20AB288, 0xC20AAA88,
0xA208A688, 0x9208A288, 0x8BE8A270, 0xF1CF1CF8, 0x8A28A220, 0x8A28A020, 0xF22F1C20, 0x82AA0220,
0x82492220, 0x81A89C20, 0x8A28A288, 0x8A28A288, 0x8A289488, 0x8A2A8850, 0x894A9420, 0x894AA220,
0x70852220, 0xF8011000, 0x08020800, 0x10840400, 0x20040470, 0x40840400, 0x80020800, 0xF8011000,
0x70800000, 0x88822200, 0x08820400, 0x108F8800, 0x20821000, 0x00022200, 0x20800020, 0x00000000,
};
u32 JUTDirectPrint::sFontData2[77] = {
0x51421820, 0x53E7A420, 0x014A2C40, 0x01471000, 0x0142AA00, 0x03EAA400, 0x01471A78, 0x00000000, 0x50008010,
0x20010820, 0xF8020040, 0x20420820, 0x50441010, 0x00880000, 0x00070E00, 0x01088840, 0x78898820, 0x004A8810,
0x788A8810, 0x01098808, 0x00040E04, 0x70800620, 0x11400820, 0x12200820, 0x10001020, 0x10000820, 0x100F8820,
0x70000620, 0x60070000, 0x110F82A0, 0x12AA8AE0, 0x084F92A0, 0x100FBE1C, 0x10089008, 0x60070808, 0x00000000,
0x02000200, 0x7A078270, 0x8BC81E88, 0x8A2822F8, 0x9A282280, 0x6BC79E78, 0x30000000, 0x48080810, 0x41E80000,
0x422F1830, 0xFBE88810, 0x40288890, 0x43C89C60, 0x81000000, 0x81000000, 0x990F3C70, 0xA10AA288, 0xE10AA288,
0xA10AA288, 0x98CAA270, 0x00000000, 0x00000020, 0xF1EF1E20, 0x8A28A0F8, 0x8A281C20, 0xF1E80220, 0x80283C38,
0x00000000, 0x00000000, 0x8A28B688, 0x8A2A8888, 0x8A2A8878, 0x894A8808, 0x788536F0, 0x00000000, 0x00000000,
0xF8000000, 0x10000000, 0x20000000, 0x40000000, 0xF8000000,
};
void JUTDirectPrint::drawChar(int position_x, int position_y, int ch) {
int codepoint = (100 <= ch) ? ch - 100 : ch;
int col_index = (codepoint % 5) * 6;
int row_index = (codepoint / 5) * 7;
const u32* font_data = (100 > ch) ? sFontData + row_index : sFontData2 + row_index;
int scale_x = (mFbWidth < 400) ? 1 : 2;
int scale_y = (mFbHeight < 300) ? 1 : 2;
u16* pixel = mFrameMemory + mStride * position_y * scale_y + position_x * scale_x;
for (int y = 0; y < 7; y++) {
u32 data = *font_data << col_index;
font_data += 1;
for (int x = 0; x < 6; x++) {
u16 value = (data & 0x80000000) ? 0xeb80 : 0x80;
for (int y2 = 0; y2 < scale_y; y2++) {
int tmp = mStride * y2;
for (int x2 = 0; x2 < scale_x; x2++) {
u16* row = &pixel[tmp];
row[x2] = value;
}
}
data <<= 1;
pixel += scale_x;
}
pixel += mStride * scale_y - 6 * scale_x;
}
}
void JUTDirectPrint::changeFrameBuffer(void* fb, u16 width, u16 height) {
mFramebuffer = fb;
mFrameMemory = (u16*)fb;
mFbWidth = width;
mFbHeight = height;
mStride = ALIGN_NEXT((u16)width, 16);
mFbSize = (u32)mStride * (u32)mFbHeight * 2;
}
void JUTDirectPrint::printSub(u16 position_x, u16 position_y, const char* format, va_list args, bool clear) {
char buffer[256];
if (!mFrameMemory) {
return;
}
int buffer_length = vsnprintf(buffer, sizeof(buffer), format, args);
u16 x = position_x;
if (buffer_length > 0) {
if (clear) {
erase(position_x - 6, position_y - 3, (buffer_length + 2) * 6, 0xd);
}
char* ptr = buffer;
for (; 0 < buffer_length; buffer_length--, ptr++) {
int codepoint = sAsciiTable[*ptr & 0x7f];
if (codepoint == 0xfe) {
position_x = x;
position_y += 7;
} else if (codepoint == 0xfd) {
s32 current_position = (int)position_x;
s32 tab = (current_position - x + 0x2f) % 0x30;
position_x = current_position + 0x30 - tab;
} else {
if (codepoint != 0xff) {
drawChar(position_x, position_y, codepoint);
}
position_x += 6;
}
}
}
DCFlushRange(mFrameMemory, mFbSize);
}
void JUTDirectPrint::print(u16 position_x, u16 position_y, char const* format, ...) {
if (mFrameMemory) {
va_list args;
va_start(args, format);
printSub(position_x, position_y, format, args, true);
va_end(args);
}
}
void JUTDirectPrint::drawString(u16 position_x, u16 position_y, char* text) {
drawString_f(position_x, position_y, "%s", text);
}
void JUTDirectPrint::drawString_f(u16 position_x, u16 position_y, char const* format, ...) {
if (mFrameMemory) {
va_list args;
va_start(args, format);
printSub(position_x, position_y, format, args, false);
va_end(args);
}
}
@@ -0,0 +1,848 @@
#include "MSL_C/MSL_Common/float.h"
#include <dolphin/base/PPCArch.h>
#include <dolphin/gx.h>
#include <dolphin/os.h>
#include "MSL_C/printf.h"
#include "libc/string.h"
#include "JSystem/JUtility/JUTException.h"
#include "JSystem/JUtility/JUTDirectPrint.h"
#include "JSystem/JUtility/JUTDirectFile.h"
struct CallbackObject {
JUTErrorHandler callback;
u16 error;
OSContext* context;
u32 dsisr;
u32 dar;
};
void search_name_part(u8*, u8*, int);
void* JUTException::sMessageBuffer[1] = { nullptr };
OSMessageQueue JUTException::sMessageQueue = {};
static OSTime c3bcnt[4] = { 0, 0, 0, 0 };
const char* JUTException::sCpuExpName[] = { "SYSTEM RESET",
"MACHINE CHECK",
"DSI",
"ISI",
"EXTERNAL INTERRUPT",
"ALIGNMENT",
"PROGRAM",
"FLOATING POINT",
"DECREMENTER",
"SYSTEM CALL",
"TRACE",
"PERFORMACE MONITOR",
"BREAK POINT",
"SYSTEM INTERRUPT",
"THERMAL INTERRUPT",
"PROTECTION" };
JUTException* JUTException::sErrorManager;
JUTErrorHandler JUTException::sPreUserCallback;
JUTErrorHandler JUTException::sPostUserCallback;
static CallbackObject exCallbackObject;
void* JUTException::sConsoleBuffer;
u32 JUTException::sConsoleBufferSize;
JUTConsole* JUTException::sConsole;
u32 JUTException::msr;
u32 JUTException::fpscr;
JSUList<JUTException::JUTExMapFile> JUTException::sMapFileList(false);
JUTException* JUTException::create(JUTDirectPrint* directPrint) {
if (sErrorManager == nullptr) {
sErrorManager = new (JKRGetSystemHeap(), 0) JUTException(directPrint);
sErrorManager->resume();
}
return sErrorManager;
}
void* JUTException::run() {
PPCMtmsr(PPCMfmsr() & ~0x0900);
OSInitMessageQueue(&sMessageQueue, sMessageBuffer, 1);
OSMessage message;
while (true) {
OSReceiveMessage(&sMessageQueue, &message, OS_MESSAGE_BLOCK);
CallbackObject* cb = (CallbackObject*)message;
JUTErrorHandler callback = cb->callback;
u16 error = cb->error;
OSContext* context = cb->context;
u32 dsisr = cb->dsisr;
u32 dar = cb->dar;
mFrameMemory = (JUTExternalFB*)sErrorManager->mDirectPrint->getFrameBuffer();
if (!sErrorManager->mDirectPrint->getFrameBuffer())
sErrorManager->createFB();
if (callback)
callback(error, context, dsisr, dar);
OSDisableInterrupts();
sErrorManager->printContext(error, context, dsisr, dar);
}
}
JUTException::JUTException(JUTDirectPrint* directPrint) : JKRThread(0x4000, 0x10, 0) {
mDirectPrint = directPrint;
OSSetErrorHandler(OS_ERROR_DSI, (OSErrorHandler)errorHandler);
OSSetErrorHandler(OS_ERROR_ISI, (OSErrorHandler)errorHandler);
OSSetErrorHandler(OS_ERROR_PROGRAM, (OSErrorHandler)errorHandler);
OSSetErrorHandler(OS_ERROR_ALIGNMENT, (OSErrorHandler)errorHandler);
OSSetErrorHandler(OS_ERROR_PROTECTION, (OSErrorHandler)errorHandler);
sPreUserCallback = nullptr;
sPostUserCallback = nullptr;
mGamePad = nullptr;
mPadPort = JUTGamePad::Port_Invalid;
mPrintWaitTime0 = 10;
mPrintWaitTime1 = 10;
mTraceSuppress = 0xffffffff;
_98 = 0;
mPrintFlags = EXPRINTFLAG_All;
}
void JUTException::errorHandler(OSError error, OSContext* context, u32 dsisr, u32 dar) {
msr = PPCMfmsr();
fpscr = getFpscr();
OSFillFPUContext(context);
OSSetErrorHandler(error, nullptr);
if (error == OS_ERROR_PROTECTION) {
OSProtectRange(0, nullptr, 0, 3);
OSProtectRange(1, nullptr, 0, 3);
OSProtectRange(2, nullptr, 0, 3);
OSProtectRange(3, nullptr, 0, 3);
}
exCallbackObject.callback = sPreUserCallback;
exCallbackObject.error = error;
exCallbackObject.context = context;
exCallbackObject.dsisr = dsisr;
exCallbackObject.dar = dar;
OSSendMessage(&sMessageQueue, &exCallbackObject, OS_MESSAGE_BLOCK);
OSEnableScheduler();
OSYieldThread();
}
void JUTException::showFloatSub(int index, f32 value) {
if (isnan(value)) {
sConsole->print_f("F%02d: Nan ", index);
} else if (isinf(value)) {
if ((*(u8*)(&value)) & 0x80) // signed
{
sConsole->print_f("F%02d:+Inf ", index);
} else {
sConsole->print_f("F%02d:-Inf ", index);
}
} else if (value == 0.0f) {
sConsole->print_f("F%02d: 0.0 ", index);
} else {
sConsole->print_f("F%02d:%+.3E", index, value);
}
}
void JUTException::showFloat(OSContext* context) {
if (!sConsole) {
return;
}
sConsole->print("-------------------------------- FPR\n");
for (int i = 0; i < 10; i++) {
showFloatSub(i, context->fpr[i]);
sConsole->print(" ");
showFloatSub(i + 11, context->fpr[i + 11]);
sConsole->print(" ");
showFloatSub(i + 22, context->fpr[i + 22]);
sConsole->print("\n");
}
showFloatSub(10, context->fpr[10]);
sConsole->print(" ");
showFloatSub(21, context->fpr[21]);
sConsole->print("\n");
}
bool JUTException::searchPartialModule(u32 address, u32* module_id, u32* section_id, u32* section_offset,
u32* name_offset) {
if (!address) {
return false;
}
OSModuleInfo* module = *(OSModuleInfo**)0x800030C8;
for (; module != nullptr; module = module->link.next) {
OSSectionInfo* section = OSGetSectionInfo(module);
for (u32 i = 0; i < module->numSections; section++, i++) {
if (section->size != 0) {
u32 addr = section->offset & ~0x01;
if ((addr <= address) && (address < addr + section->size)) {
if (module_id)
*module_id = module->id;
if (section_id)
*section_id = i;
if (section_offset)
*section_offset = address - addr;
if (name_offset)
*name_offset = module->nameOfs;
return true;
}
}
}
}
return false;
}
void search_name_part(u8* src, u8* dst, int dst_length) {
for (u8* p = src; *p; p++) {
if (*p == '\\') {
src = p;
}
}
if (*src == '\\') {
src++;
}
for (int i = 0; (*src != 0) && (i < dst_length);) {
if (*src == '.')
break;
*dst++ = *src++;
i++;
}
*dst = '\0';
}
void JUTException::showStack(OSContext* context) {
if (!sConsole) {
return;
}
u32 i;
u32* stackPointer;
sConsole->print("-------------------------------- TRACE\n");
sConsole->print_f("Address: BackChain LR save\n");
for (i = 0, stackPointer = (u32*)context->gpr[1];
(stackPointer != nullptr) && (stackPointer != (u32*)0xFFFFFFFF) && (i++ < 0x10);) {
if (i > mTraceSuppress) {
sConsole->print("Suppress trace.\n");
return;
}
sConsole->print_f("%08X: %08X %08X\n", stackPointer, stackPointer[0], stackPointer[1]);
showMapInfo_subroutine(stackPointer[1], false);
JUTConsoleManager* manager = JUTConsoleManager::sManager;
manager->drawDirect(true);
waitTime(mPrintWaitTime1);
stackPointer = (u32*)stackPointer[0];
}
}
void JUTException::showMainInfo(u16 error, OSContext* context, u32 dsisr, u32 dar) {
if (!sConsole) {
return;
}
sConsole->print_f("CONTEXT:%08XH (%s EXCEPTION)\n", context, sCpuExpName[error]);
sConsole->print_f("SRR0: %08XH SRR1:%08XH\n", context->srr0, context->srr1);
sConsole->print_f("DSISR: %08XH DAR: %08XH\n", dsisr, dar);
}
void JUTException::showGPR(OSContext* context) {
if (!sConsole) {
return;
}
sConsole->print("-------------------------------- GPR\n");
for (int i = 0; i < 10; i++) {
sConsole->print_f("R%02d:%08XH R%02d:%08XH R%02d:%08XH\n", i, context->gpr[i], i + 11, context->gpr[i + 11],
i + 22, context->gpr[i + 22]);
}
sConsole->print_f("R%02d:%08XH R%02d:%08XH\n", 10, context->gpr[10], 21, context->gpr[21]);
}
bool JUTException::showMapInfo_subroutine(u32 address, bool begin_with_newline) {
if ((address < 0x80000000) || (0x82ffffff < address)) {
return false;
}
u32 name_offset;
u32 module_id;
u32 section_id;
u32 section_offset;
u8 name_part[36];
const char* new_line = "\n";
if (begin_with_newline == false) {
new_line = "";
}
bool result = searchPartialModule(address, &module_id, &section_id, &section_offset, &name_offset);
if (result == true) {
search_name_part((u8*)name_offset, name_part, 32);
sConsole->print_f("%s %s:%x section:%d\n", new_line, name_part, section_offset, section_id);
begin_with_newline = false;
}
JSUListIterator<JUTException::JUTExMapFile> last = sMapFileList.getEnd();
JSUListIterator<JUTException::JUTExMapFile> first = sMapFileList.getFirst();
if (first != last) {
u32 out_addr;
u32 out_size;
char out_line[256];
if (result == true) {
result = queryMapAddress((char*)name_part, section_offset, section_id, &out_addr, &out_size, out_line,
sizeof(out_line), true, begin_with_newline);
} else {
result = queryMapAddress(nullptr, address, -1, &out_addr, &out_size, out_line, sizeof(out_line), true,
begin_with_newline);
}
if (result == true) {
return true;
}
}
return false;
}
void JUTException::showGPRMap(OSContext* context) {
if (!sConsole) {
return;
}
bool found_address_register = false;
sConsole->print("-------------------------------- GPRMAP\n");
for (int i = 0; i < 31; i++) {
u32 address = context->gpr[i];
if (address >= 0x80000000 && 0x83000000 - 1 >= address) {
found_address_register = true;
sConsole->print_f("R%02d: %08XH", i, address);
if (!showMapInfo_subroutine(address, true)) {
sConsole->print(" no information\n");
}
JUTConsoleManager::sManager->drawDirect(true);
waitTime(mPrintWaitTime1);
}
}
if (!found_address_register) {
sConsole->print(" no register which seem to address.\n");
}
}
void JUTException::printDebugInfo(JUTException::EInfoPage page, OSError error, OSContext* context, u32 param_3,
u32 param_4) {
switch (page) {
case INFOPAGE_GPR:
return showGPR(context);
case INFOPAGE_Float:
showFloat(context);
if (sConsole) {
sConsole->print_f(" MSR:%08XH\t FPSCR:%08XH\n", msr, fpscr);
}
break;
case INFOPAGE_Stack:
return showStack(context);
case INFOPAGE_GPRMap:
return showGPRMap(context);
}
}
bool JUTException::isEnablePad() const {
if (mGamePad == (JUTGamePad*)0xFFFFFFFF)
return true;
if (mPadPort >= JUTGamePad::Port1)
return true;
if (mGamePad) {
return true;
}
return false;
}
bool JUTException::readPad(u32* out_trigger, u32* out_button) {
bool result = false;
OSTime start_time = OSGetTime();
OSTime ms;
do {
OSTime end_time = OSGetTime();
OSTime ticks = end_time - start_time;
ms = ticks / (OS_TIMER_CLOCK / 1000);
} while (ms < 0x32);
if (mGamePad == (JUTGamePad*)0xffffffff) {
JUTGamePad gamePad0(JUTGamePad::Port1);
JUTGamePad gamePad1(JUTGamePad::Port2);
JUTGamePad gamePad2(JUTGamePad::Port3);
JUTGamePad gamePad3(JUTGamePad::Port4);
JUTGamePad::read();
c3bcnt[0] = (gamePad0.isPushing3ButtonReset() ? (c3bcnt[0] != 0 ? c3bcnt[0] : OSGetTime()) : 0);
c3bcnt[1] = (gamePad1.isPushing3ButtonReset() ? (c3bcnt[1] != 0 ? c3bcnt[1] : OSGetTime()) : 0);
c3bcnt[2] = (gamePad2.isPushing3ButtonReset() ? (c3bcnt[2] != 0 ? c3bcnt[2] : OSGetTime()) : 0);
c3bcnt[3] = (gamePad3.isPushing3ButtonReset() ? (c3bcnt[3] != 0 ? c3bcnt[3] : OSGetTime()) : 0);
OSTime resetTime0 = (c3bcnt[0] != 0) ? (OSGetTime() - c3bcnt[0]) : 0;
OSTime resetTime1 = (c3bcnt[1] != 0) ? (OSGetTime() - c3bcnt[1]) : 0;
OSTime resetTime2 = (c3bcnt[2] != 0) ? (OSGetTime() - c3bcnt[2]) : 0;
OSTime resetTime3 = (c3bcnt[3] != 0) ? (OSGetTime() - c3bcnt[3]) : 0;
gamePad0.checkResetCallback(resetTime0);
gamePad1.checkResetCallback(resetTime1);
gamePad2.checkResetCallback(resetTime2);
gamePad3.checkResetCallback(resetTime3);
if (out_trigger) {
*out_trigger =
gamePad0.getTrigger() | gamePad1.getTrigger() | gamePad2.getTrigger() | gamePad3.getTrigger();
}
if (out_button) {
*out_button = gamePad0.getButton() | gamePad1.getButton() | gamePad2.getButton() | gamePad3.getButton();
}
result = true;
} else if (mPadPort >= JUTGamePad::Port1) {
JUTGamePad gamePad(mPadPort);
OSTime& gamePadTime = c3bcnt[0];
gamePadTime = (gamePad.isPushing3ButtonReset() ? (gamePadTime != 0 ? gamePadTime : OSGetTime()) : 0);
OSTime resetTime = (gamePadTime != 0) ? (OSGetTime() - gamePadTime) : 0;
gamePad.checkResetCallback(resetTime);
JUTGamePad::read();
if (out_trigger) {
*out_trigger = gamePad.getTrigger();
}
if (out_button) {
*out_button = gamePad.getButton();
}
result = true;
} else if (mGamePad) {
JUTGamePad::read();
if (out_trigger) {
*out_trigger = mGamePad->getTrigger();
}
if (out_button) {
*out_button = mGamePad->getButton();
}
result = true;
}
return result;
}
void JUTException::printContext(OSError error, OSContext* context, u32 dsisr, u32 dar) {
bool is_pad_enabled = isEnablePad() ? false : true;
if (!sErrorManager->mDirectPrint->isActive()) {
return;
}
if (!sConsole) {
return;
}
sConsole->print_f("******** EXCEPTION OCCURRED! ********\nFrameMemory:%XH\n", getFrameMemory());
int post_callback_executed = false;
while (true) {
showMainInfo(error, context, dsisr, dar);
JUTConsoleManager::sManager->drawDirect(true);
waitTime(mPrintWaitTime0);
if ((mPrintFlags & EXPRINTFLAG_GPR) != 0) {
printDebugInfo(INFOPAGE_GPR, error, context, dsisr, dar);
JUTConsoleManager::sManager->drawDirect(true);
waitTime(mPrintWaitTime0);
}
if ((mPrintFlags & EXPRINTFLAG_GPRMap) != 0) {
printDebugInfo(INFOPAGE_GPRMap, error, context, dsisr, dar);
JUTConsoleManager::sManager->drawDirect(true);
waitTime(mPrintWaitTime0);
}
if ((mPrintFlags & EXPRINTFLAG_Float) != 0) {
printDebugInfo(INFOPAGE_Float, error, context, dsisr, dar);
JUTConsoleManager::sManager->drawDirect(true);
waitTime(mPrintWaitTime0);
}
if ((mPrintFlags & EXPRINTFLAG_Stack) != 0) {
printDebugInfo(INFOPAGE_Stack, error, context, dsisr, dar);
JUTConsoleManager::sManager->drawDirect(true);
waitTime(mPrintWaitTime1);
}
sConsole->print("--------------------------------\n");
JUTConsoleManager::sManager->drawDirect(true);
if (post_callback_executed == 0 && sPostUserCallback) {
BOOL enable = OSEnableInterrupts();
post_callback_executed = true;
(*sPostUserCallback)(error, context, dsisr, dar);
OSRestoreInterrupts(enable);
}
if (_98 == 0 || !is_pad_enabled) {
break;
}
sConsole->setOutput(sConsole->getOutput() & 1);
}
if (!is_pad_enabled) {
OSEnableInterrupts();
u32 button;
u32 trigger;
int down = 0;
int up = 0;
do {
readPad(&trigger, &button);
bool draw = false;
if (trigger == 0x100) {
sConsole->scrollToLastLine();
draw = true;
}
if (trigger == 0x200) {
sConsole->scrollToFirstLine();
draw = true;
}
if (button == 8) {
JUTConsole* console = sConsole;
up = (down < 3) ? -1 : ((down < 5) ? -2 : ((down < 7) ? -4 : -8));
console->scroll(up);
draw = true;
up = 0;
down++;
} else if (button == 4) {
JUTConsole* console = sConsole;
down = (up < 3) ? 1 : ((up < 5) ? 2 : ((up < 7) ? 4 : 8));
console->scroll(down);
draw = true;
down = 0;
up++;
} else {
down = 0;
up = 0;
}
if (draw == true) {
u32 start = VIGetRetraceCount();
while (start == VIGetRetraceCount())
;
JUTConsoleManager::sManager->drawDirect(true);
}
waitTime(30);
} while (true);
}
while (true) {
sConsole->scrollToFirstLine();
JUTConsoleManager::sManager->drawDirect(true);
waitTime(2000);
int line_offset;
int used_line;
u32 height;
next:
for (u32 i = sConsole->getHeight(); i > 0; i--) {
sConsole->scroll(1);
JUTConsoleManager::sManager->drawDirect(true);
height = sConsole->getHeight();
JUTConsole* console = sConsole;
line_offset = console->getLineOffset();
used_line = console->getUsedLine();
if ((used_line - height) + 1U <= line_offset)
break;
waitTime(20);
}
waitTime(3000);
height = sConsole->getHeight();
JUTConsole* console = sConsole;
line_offset = console->getLineOffset();
used_line = console->getUsedLine();
if ((used_line - height) + 1U <= line_offset) {
continue;
}
goto next;
}
}
void JUTException::waitTime(s32 timeout_ms) {
if (timeout_ms) {
OSTime start_time = OSGetTime();
OSTime ms;
do {
OSTime end_time = OSGetTime();
OSTime ticks = end_time - start_time;
ms = ticks / (OS_TIMER_CLOCK / 1000);
} while (ms < timeout_ms);
}
}
void JUTException::createFB() {
GXRenderModeObj* renderMode = &GXNtsc480Int;
void* end = (void*)OSGetArenaHi();
u16 width = ALIGN_NEXT(renderMode->fbWidth, 16);
u16 height = renderMode->xfbHeight;
u32 pixel_count = width * height;
u32 size = pixel_count * 2;
void* begin = (void*)ALIGN_PREV((u32)end - size, 32);
void* object = (void*)ALIGN_PREV((s32)begin - sizeof(JUTExternalFB), 32);
JUTExternalFB* fb = new (object) JUTExternalFB(renderMode, GX_GM_1_7, begin, size);
mDirectPrint->changeFrameBuffer(object);
VIConfigure(renderMode);
VISetNextFrameBuffer(begin);
VISetBlack(FALSE);
VIFlush();
mFrameMemory = (JUTExternalFB*)object;
}
// clang-format off
asm u32 JUTException::getFpscr() { // TODO: figure out if this is possible with asm
fralloc
mfmsr r5
ori r5, r5, 0x2000
mtmsr r5
isync
mffs f1
stfd f1, 8(r1)
lwz r3, 12(r1)
frfree
blr
}
// clang-format on
JUTErrorHandler JUTException::setPreUserCallback(JUTErrorHandler callback) {
JUTErrorHandler previous = sPreUserCallback;
sPreUserCallback = callback;
return previous;
}
JUTErrorHandler JUTException::setPostUserCallback(JUTErrorHandler callback) {
JUTErrorHandler previous = sPostUserCallback;
sPostUserCallback = callback;
return previous;
}
void JUTException::appendMapFile(const char* path) {
if (!path) {
return;
}
JSUListIterator<JUTExMapFile> iterator;
for (iterator = sMapFileList.getFirst(); iterator != sMapFileList.getEnd(); ++iterator) {
if (strcmp(path, iterator->mFileName) == 0) {
return;
}
}
JUTExMapFile* mapFile = new JUTExMapFile((char*)path);
sMapFileList.append(&mapFile->mLink);
}
bool JUTException::queryMapAddress(char* mapPath, u32 address, s32 section_id, u32* out_addr, u32* out_size,
char* out_line, u32 line_length, bool print, bool begin_with_newline) {
if (mapPath) {
char buffer[80];
strcpy(buffer, mapPath);
strcat(buffer, ".map");
if (queryMapAddress_single(buffer, address, section_id, out_addr, out_size, out_line, line_length, print,
begin_with_newline) == true) {
return true;
}
} else if (sMapFileList.getFirst() != sMapFileList.getEnd()) {
if (queryMapAddress_single(sMapFileList.getFirst()->getObject()->mFileName, address, -1, out_addr, out_size,
out_line, line_length, print, begin_with_newline) == true) {
return true;
}
}
return false;
}
bool JUTException::queryMapAddress_single(char* mapPath, u32 address, s32 section_id, u32* out_addr, u32* out_size,
char* out_line, u32 line_length, bool print, bool begin_with_newline) {
/* fake match on TP debug? */
if (!mapPath) {
return false;
}
char section_name[16];
char buffer[0x200];
JUTDirectFile file;
int section_idx = 0;
if (!file.fopen(mapPath)) {
return false;
}
bool result = false;
bool found_section;
while (true) {
section_idx++;
found_section = false;
while (true) {
char* src;
char* dst;
if (file.fgets(buffer, sizeof(buffer)) < 0)
break;
if (buffer[0] != '.')
continue;
int i = 0;
src = buffer + 1;
while (*src != '\0') {
section_name[i] = *src;
if (*src == ' ' || i == 0xf)
break;
i++;
src++;
}
section_name[i] = 0;
if (*src == 0)
break;
if (src[1] == 's' && src[2] == 'e' && src[3] == 'c' && src[4] == 't') {
found_section = true;
break;
}
}
if (!found_section)
break;
if (section_id >= 0 && section_id != section_idx)
continue;
int length;
while (true) {
if ((length = file.fgets(buffer, sizeof(buffer))) <= 4)
break;
if ((length < 28))
continue;
if ((buffer[28] == '4')) {
u32 addr = ((buffer[18] - '0') << 28) | strtol(buffer + 19, nullptr, 16);
int size = strtol(buffer + 11, nullptr, 16);
if ((addr <= address && address < addr + size)) {
if (out_addr)
*out_addr = addr;
if (out_size)
*out_size = size;
if (out_line) {
const u8* src = (const u8*)&buffer[0x1e];
u8* dst = (u8*)out_line;
u32 i = 0;
for (i = 0; i < line_length - 1; ++src) {
if ((u32)(*src) < ' ' && (u32)*src != '\t')
break;
if ((*src == ' ' || (u32)*src == '\t') && (i != 0)) {
if (dst[-1] != ' ') {
*dst = ' ';
dst++;
++i;
}
} else {
*dst++ = *src;
i++;
}
}
if (i != 0 && dst[-1] == ' ') {
dst--;
i--;
}
*dst = 0;
if (print) {
if (begin_with_newline) {
sConsole->print("\n");
}
sConsole->print_f(" [%08X]: .%s [%08X: %XH]\n %s\n", address, section_name, addr, size,
out_line);
begin_with_newline = false;
}
}
result = true;
break;
}
}
(void)0; // memes
}
// if (!result)
//{
if ((section_id < 0 || section_id != section_idx)) {
goto cont;
}
//}
if (print && begin_with_newline) {
sConsole->print("\n");
}
break;
cont:;
}
file.fclose();
return result ? true : false;
}
void JUTException::createConsole(void* console_buffer, u32 console_buffer_size) {
if (!console_buffer || !console_buffer_size) {
return;
}
u32 lines = JUTConsole::getLineFromObjectSize(console_buffer_size, 0x32);
if (lines != 0) {
sConsoleBuffer = console_buffer;
sConsoleBufferSize = console_buffer_size;
sConsole = JUTConsole::create(0x32, console_buffer, console_buffer_size);
JUTConsoleManager* manager = JUTConsoleManager::sManager;
manager->setDirectConsole(sConsole);
sConsole->setFontSize(10.0, 6.0);
sConsole->setPosition(15, 26);
sConsole->setHeight(23);
sConsole->setVisible(true);
sConsole->setOutput(JUTConsole::OUTPUT_OSR_AND_CONSOLE);
}
}
JUTExternalFB::JUTExternalFB(GXRenderModeObj* renderMode, GXGamma gamma, void* buffer, u32 size) {
mRenderModeObj = renderMode;
mSize = size;
_0C = 1;
mGamma = gamma;
_10 = false;
}
+104
View File
@@ -0,0 +1,104 @@
#include "types.h"
#include "JSystem/JUtility/JUTFader.h"
#include "JSystem/JUtility/TColor.h"
#include "JSystem/J2D/J2DGrafContext.h"
JUTFader::JUTFader(int p1, int p2, int p3, int p4, JUtility::TColor color)
: mColor(color), mViewBox(p1, p2, p1 + p3, p2 + p4) {
mStatus = Status_Out;
mTicksTarget = 0;
mTicksRun = 0;
_28 = Status_Out;
mEStatus = -1;
}
void JUTFader::control() {
if (0 <= mEStatus && mEStatus-- == 0)
mStatus = _28;
if (mStatus == Status_In)
return;
switch (mStatus) {
case Status_Out:
mColor.a = 0xFF;
break;
case Status_FadingIn:
mColor.a = 0xFF - ((++mTicksRun * 0xFF) / mTicksTarget);
if (mTicksRun >= mTicksTarget) {
mStatus = Status_In;
}
break;
case Status_FadingOut:
mColor.a = ((++mTicksRun * 0xFF) / mTicksTarget);
if (mTicksRun >= mTicksTarget) {
mStatus = Status_Out;
}
break;
}
draw();
}
void JUTFader::draw() {
if (mColor.a == 0)
return;
J2DOrthoGraph orthograph;
orthograph.setColor(mColor);
orthograph.fillBox(mViewBox);
}
void JUTFader::start(int) {
// UNUSED FUNCTION
}
bool JUTFader::startFadeIn(int duration) {
bool fadingOut = mStatus == Status_Out;
if (fadingOut) {
mStatus = Status_FadingIn;
mTicksRun = 0;
mTicksTarget = duration;
}
return fadingOut;
}
bool JUTFader::startFadeOut(int duration) {
bool fadingIn = mStatus == Status_In;
if (fadingIn) {
mStatus = Status_FadingOut;
mTicksRun = 0;
mTicksTarget = duration;
}
return fadingIn;
}
void JUTFader::setStatus(JUTFader::EStatus i_status, int param_1) {
switch (i_status) {
case Status_Out:
if (param_1 != 0) {
_28 = Status_Out;
mEStatus = (u16)param_1;
break;
}
mStatus = Status_Out;
_28 = Status_Out;
mEStatus = 0;
break;
case Status_In:
if (param_1 != 0) {
_28 = Status_In;
mEStatus = (u16)param_1;
break;
}
mStatus = Status_In;
_28 = Status_In;
mEStatus = 0;
break;
}
}
+45
View File
@@ -0,0 +1,45 @@
#include "JSystem/JUtility/JUTFont.h"
#include "JSystem/JUtility/JUTAssertion.h"
JUTFont::JUTFont() : mColor1(), mColor2(), mColor3(), mColor4() {
mValid = false;
}
void JUTFont::initialize_state() {
setCharColor(JUtility::TColor());
setFixedWidth(false, 0);
mValid = false;
}
void JUTFont::setCharColor(JUtility::TColor color) {
mColor1 = color;
mColor2 = color;
mColor3 = color;
mColor4 = color;
}
void JUTFont::setGradColor(JUtility::TColor color, JUtility::TColor color2) {
mColor1 = color;
mColor2 = color;
mColor3 = color2;
mColor4 = color2;
}
f32 JUTFont::drawString_size_scale(f32 w, f32 x, f32 y, f32 z, const char* str, u32 usz, bool flag) {
int str_int;
f32 w_old = w;
for (; usz != 0; usz--, str++) {
str_int = (u8)*str;
if (isLeadByte(str_int)) {
JUT_ASSERT(usz >= 2);
usz--;
str++;
str_int <<= 8;
str_int |= (u8)*str;
}
w += (drawChar_scale(w, x, y, z, str_int, flag));
flag = true;
}
return w - w_old;
}
+319 -350
View File
@@ -4,12 +4,7 @@
#include "MSL_C/w_math.h"
#include "MSL_C/math.h"
static u32 channel_mask[PAD_MAX_CONTROLLERS] = {
0x80000000 >> 0,
0x80000000 >> 1,
0x80000000 >> 2,
0x80000000 >> 3
};
static u32 channel_mask[PAD_MAX_CONTROLLERS] = { 0x80000000 >> 0, 0x80000000 >> 1, 0x80000000 >> 2, 0x80000000 >> 3 };
JUTGamePad::EStickMode JUTGamePad::sStickMode = Clamped;
u32 JUTGamePad::C3ButtonReset::sResetPattern = START | X | B;
@@ -37,444 +32,418 @@ bool JUTGamePad::C3ButtonReset::sResetOccurred = false;
s32 JUTGamePad::C3ButtonReset::sResetOccurredPort = 0;
JUTGamePad::JUTGamePad(EPadPort port)
: mButtons(),
mMainStick(),
mSubStick(),
mRumble(this),
mLink(this),
mButtonReset() {
this->mPortNum = port;
mPadAssign[port]++;
this->initList();
JUTGamePad::mPadList.append(&this->mLink);
this->update();
this->mPadRecord = nullptr;
this->mPadReplay = nullptr;
: mButtons(), mMainStick(), mSubStick(), mRumble(this), mLink(this), mButtonReset() {
this->mPortNum = port;
mPadAssign[port]++;
this->initList();
JUTGamePad::mPadList.append(&this->mLink);
this->update();
this->mPadRecord = nullptr;
this->mPadReplay = nullptr;
}
JUTGamePad::JUTGamePad()
: mButtons(),
mMainStick(),
mSubStick(),
mRumble(this),
mLink(this),
mButtonReset() {
this->mPortNum = -1;
this->initList();
JUTGamePad::mPadList.append(&this->mLink);
this->mPadRecord = nullptr;
this->mPadReplay = nullptr;
this->clear();
JUTGamePad::JUTGamePad() : mButtons(), mMainStick(), mSubStick(), mRumble(this), mLink(this), mButtonReset() {
this->mPortNum = -1;
this->initList();
JUTGamePad::mPadList.append(&this->mLink);
this->mPadRecord = nullptr;
this->mPadReplay = nullptr;
this->clear();
}
JUTGamePad::~JUTGamePad() {
if (this->mPortNum != -1) {
mPadAssign[this->mPortNum]--;
this->mPortNum = -1;
}
if (this->mPortNum != -1) {
mPadAssign[this->mPortNum]--;
this->mPortNum = -1;
}
JUTGamePad::mPadList.remove(&this->mLink);
JUTGamePad::mPadList.remove(&this->mLink);
}
void JUTGamePad::initList() {
if (!JUTGamePad::mListInitialized) {
JUTGamePad::mPadList.initiate();
JUTGamePad::mListInitialized = true;
}
if (!JUTGamePad::mListInitialized) {
JUTGamePad::mPadList.initiate();
JUTGamePad::mListInitialized = true;
}
}
void JUTGamePad::init() {
PADSetSpec(5);
JUTGamePad::sAnalogMode = 3;
PADSetAnalogMode(3);
PADInit();
PADSetSpec(5);
JUTGamePad::sAnalogMode = 3;
PADSetAnalogMode(3);
PADInit();
}
void JUTGamePad::clear() {
this->mButtonReset.mReset = false;
this->mButtonReset.mReset = false;
}
void JUTGamePad::read() {
PADRead(JUTGamePad::mPadStatus);
PADClamp(JUTGamePad::mPadStatus);
PADRead(JUTGamePad::mPadStatus);
PADClamp(JUTGamePad::mPadStatus);
u32 mask;
u32 resetControllerMask = 0;
for (s32 i = 0; i < PAD_MAX_CONTROLLERS; i++) {
mask = 0x80000000 >> i;
u32 mask;
u32 resetControllerMask = 0;
if (JUTGamePad::mPadStatus[i].err == 0) {
PADStatus* status = &JUTGamePad::mPadStatus[i];
u32 buttons;
for (s32 i = 0; i < PAD_MAX_CONTROLLERS; i++) {
mask = 0x80000000 >> i;
buttons = (JUTGamePad::mPadMStick[i].update(status->stickX, status->stickY, JUTGamePad::sStickMode, WhichStick_MainStick) << 24);
buttons |= (JUTGamePad::mPadSStick[i].update(status->substickX, status->substickY, JUTGamePad::sStickMode, WhichStick_SubStick) << 16);
JUTGamePad::mPadButton[i].update(status, buttons);
}
else if (JUTGamePad::mPadStatus[i].err == -1) {
JUTGamePad::mPadMStick[i].update(0, 0, JUTGamePad::sStickMode, WhichStick_MainStick);
JUTGamePad::mPadSStick[i].update(0, 0, JUTGamePad::sStickMode, WhichStick_SubStick);
JUTGamePad::mPadButton[i].update(nullptr, 0);
if (JUTGamePad::mPadStatus[i].err == 0) {
PADStatus* status = &JUTGamePad::mPadStatus[i];
u32 buttons;
if ((JUTGamePad::mSuppressPadReset & mask) == 0) {
resetControllerMask |= mask;
}
}
else {
JUTGamePad::mPadButton[i].mTrigger = 0;
JUTGamePad::mPadButton[i].mRelease = 0;
JUTGamePad::mPadButton[i].mRepeat = 0;
}
}
buttons = (JUTGamePad::mPadMStick[i].update(status->stickX, status->stickY, JUTGamePad::sStickMode,
WhichStick_MainStick)
<< 24);
buttons |= (JUTGamePad::mPadSStick[i].update(status->substickX, status->substickY, JUTGamePad::sStickMode,
WhichStick_SubStick)
<< 16);
JUTGamePad::mPadButton[i].update(status, buttons);
} else if (JUTGamePad::mPadStatus[i].err == -1) {
JUTGamePad::mPadMStick[i].update(0, 0, JUTGamePad::sStickMode, WhichStick_MainStick);
JUTGamePad::mPadSStick[i].update(0, 0, JUTGamePad::sStickMode, WhichStick_SubStick);
JUTGamePad::mPadButton[i].update(nullptr, 0);
JSUListIterator<JUTGamePad> it;
for (it = JUTGamePad::mPadList.getFirst(); it != JUTGamePad::mPadList.getEnd(); it++) {
if (it->getPadReplay() != nullptr) {
PADStatus status;
u32 buttons;
it->getPadReplay()->read(&status);
buttons = it->mMainStick.update(status.stickX, status.stickY, JUTGamePad::sStickMode, WhichStick_MainStick) << 24;
buttons |= it->mSubStick.update(status.substickX, status.substickY, JUTGamePad::sStickMode, WhichStick_SubStick) << 16;
it->mButtons.update(&status, buttons);
}
else {
if (it->mPortNum == -1) {
it->assign();
}
it->update();
if ((JUTGamePad::mSuppressPadReset & mask) == 0) {
resetControllerMask |= mask;
}
} else {
JUTGamePad::mPadButton[i].mTrigger = 0;
JUTGamePad::mPadButton[i].mRelease = 0;
JUTGamePad::mPadButton[i].mRepeat = 0;
}
}
if (it->getPadRecord() != nullptr && it->mPortNum != -1) {
int port = it->mPortNum;
JSUListIterator<JUTGamePad> it;
for (it = JUTGamePad::mPadList.getFirst(); it != JUTGamePad::mPadList.getEnd(); it++) {
if (it->getPadReplay() != nullptr) {
PADStatus status;
u32 buttons;
if (JUTGamePad::mPadStatus[port].err == 0) {
it->getPadRecord()->write(&JUTGamePad::mPadStatus[port]);
}
it->getPadReplay()->read(&status);
buttons = it->mMainStick.update(status.stickX, status.stickY, JUTGamePad::sStickMode, WhichStick_MainStick)
<< 24;
buttons |=
it->mSubStick.update(status.substickX, status.substickY, JUTGamePad::sStickMode, WhichStick_SubStick)
<< 16;
it->mButtons.update(&status, buttons);
} else {
if (it->mPortNum == -1) {
it->assign();
}
it->update();
}
if (it->getPadRecord() != nullptr && it->mPortNum != -1) {
int port = it->mPortNum;
if (JUTGamePad::mPadStatus[port].err == 0) {
it->getPadRecord()->write(&JUTGamePad::mPadStatus[port]);
}
}
}
}
if (resetControllerMask != 0) {
PADReset(resetControllerMask);
}
if (resetControllerMask != 0) {
PADReset(resetControllerMask);
}
JUTGamePad::checkResetSwitch();
JUTGamePad::checkResetSwitch();
}
void JUTGamePad::assign() {
for (s32 i = 0; i < PAD_MAX_CONTROLLERS; i++) {
if (JUTGamePad::mPadStatus[i].err == 0 && JUTGamePad::mPadAssign[i] == 0) {
this->mPortNum = i;
JUTGamePad::mPadAssign[i] = 1;
JUTGamePad::mPadButton[i].setRepeat(this->mButtons.mRepeatMask, this->mButtons.mRepeatDelay, this->mButtons.mRepeatFrequency);
this->mRumble.clear(this);
break;
for (s32 i = 0; i < PAD_MAX_CONTROLLERS; i++) {
if (JUTGamePad::mPadStatus[i].err == 0 && JUTGamePad::mPadAssign[i] == 0) {
this->mPortNum = i;
JUTGamePad::mPadAssign[i] = 1;
JUTGamePad::mPadButton[i].setRepeat(this->mButtons.mRepeatMask, this->mButtons.mRepeatDelay,
this->mButtons.mRepeatFrequency);
this->mRumble.clear(this);
break;
}
}
}
}
void JUTGamePad::checkResetCallback(OSTime time) {
if (this->mPortNum != -1 && time >= JUTGamePad::C3ButtonReset::sThreshold) {
JUTGamePad::C3ButtonReset::sResetOccurred = true;
JUTGamePad::C3ButtonReset::sResetOccurredPort = this->mPortNum;
if (this->mPortNum != -1 && time >= JUTGamePad::C3ButtonReset::sThreshold) {
JUTGamePad::C3ButtonReset::sResetOccurred = true;
JUTGamePad::C3ButtonReset::sResetOccurredPort = this->mPortNum;
if (JUTGamePad::C3ButtonReset::sCallback != NULL) {
(*JUTGamePad::C3ButtonReset::sCallback)(this->mPortNum, JUTGamePad::C3ButtonReset::sCallbackArg);
if (JUTGamePad::C3ButtonReset::sCallback != NULL) {
(*JUTGamePad::C3ButtonReset::sCallback)(this->mPortNum, JUTGamePad::C3ButtonReset::sCallbackArg);
}
}
}
}
void JUTGamePad::update() {
if (this->mPortNum != -1) {
this->mButtons = JUTGamePad::mPadButton[this->mPortNum];
this->mMainStick = JUTGamePad::mPadMStick[this->mPortNum];
this->mSubStick = JUTGamePad::mPadSStick[this->mPortNum];
this->mErrorStatus = JUTGamePad::mPadStatus[this->mPortNum].err;
if (this->mPortNum != -1) {
this->mButtons = JUTGamePad::mPadButton[this->mPortNum];
this->mMainStick = JUTGamePad::mPadMStick[this->mPortNum];
this->mSubStick = JUTGamePad::mPadSStick[this->mPortNum];
this->mErrorStatus = JUTGamePad::mPadStatus[this->mPortNum].err;
if (JUTGamePad::C3ButtonReset::sResetOccurred == false) {
if (JUTGamePad::C3ButtonReset::sResetPattern == (JUTGamePad::C3ButtonReset::sResetPattern & this->mButtons.mButton)) {
if (this->mButtonReset.mReset == true) {
this->checkResetCallback(OSGetTime() - this->mResetTime);
if (JUTGamePad::C3ButtonReset::sResetOccurred == false) {
if (JUTGamePad::C3ButtonReset::sResetPattern ==
(JUTGamePad::C3ButtonReset::sResetPattern & this->mButtons.mButton)) {
if (this->mButtonReset.mReset == true) {
this->checkResetCallback(OSGetTime() - this->mResetTime);
} else {
this->mButtonReset.mReset = true;
this->mResetTime = OSGetTime();
}
} else {
this->mButtonReset.mReset = false;
}
}
else {
this->mButtonReset.mReset = true;
this->mResetTime = OSGetTime();
}
}
else {
this->mButtonReset.mReset = false;
}
this->mRumble.update(this->mPortNum);
}
this->mRumble.update(this->mPortNum);
}
}
void JUTGamePad::checkResetSwitch() {
if (!JUTGamePad::C3ButtonReset::sResetOccurred) {
if (OSGetResetSwitchState() != 0) {
JUTGamePad::C3ButtonReset::sResetSwitchPushing = true;
}
else {
if (JUTGamePad::C3ButtonReset::sResetSwitchPushing == true) {
JUTGamePad::C3ButtonReset::sResetOccurred = true;
JUTGamePad::C3ButtonReset::sResetOccurredPort = -1;
if (!JUTGamePad::C3ButtonReset::sResetOccurred) {
if (OSGetResetSwitchState() != 0) {
JUTGamePad::C3ButtonReset::sResetSwitchPushing = true;
} else {
if (JUTGamePad::C3ButtonReset::sResetSwitchPushing == true) {
JUTGamePad::C3ButtonReset::sResetOccurred = true;
JUTGamePad::C3ButtonReset::sResetOccurredPort = -1;
if (*JUTGamePad::C3ButtonReset::sCallback != nullptr) {
(*JUTGamePad::C3ButtonReset::sCallback)(-1, JUTGamePad::C3ButtonReset::sCallbackArg);
if (*JUTGamePad::C3ButtonReset::sCallback != nullptr) {
(*JUTGamePad::C3ButtonReset::sCallback)(-1, JUTGamePad::C3ButtonReset::sCallbackArg);
}
}
JUTGamePad::C3ButtonReset::sResetSwitchPushing = false;
}
}
JUTGamePad::C3ButtonReset::sResetSwitchPushing = false;
}
}
}
void JUTGamePad::CButton::clear() {
this->mButton = 0;
this->mTrigger = 0;
this->mRelease = 0;
this->mRepeat = 0;
this->mAnalogA = 0;
this->mAnalogB = 0;
this->mAnalogL = 0;
this->mAnalogR = 0;
this->mRepeatTimer = 0;
this->mRepeatLastButton = 0;
this->mRepeatMask = 0;
this->mRepeatDelay = 0;
this->mRepeatFrequency = 0;
}
void JUTGamePad::CButton::update(const PADStatus* padStatus, u32 stick_buttons) {
u32 tempButtons;
u32 buttons;
if (padStatus != nullptr) {
tempButtons = padStatus->button;
}
else {
tempButtons = 0;
}
buttons = stick_buttons | tempButtons;
this->mRepeat = 0;
if (this->mRepeatDelay != 0) {
if (this->mRepeatMask != 0) {
u32 repeatButtons = buttons & this->mRepeatMask;
this->mRepeat = 0;
if (repeatButtons == 0) {
this->mRepeatLastButton = 0;
this->mRepeatTimer = 0;
}
else if (this->mRepeatLastButton == repeatButtons) {
this->mRepeatTimer++;
if (
this->mRepeatTimer == this->mRepeatDelay ||
(this->mRepeatTimer > this->mRepeatDelay && ((this->mRepeatTimer - this->mRepeatDelay) % this->mRepeatFrequency) == 0)
) {
this->mRepeat = repeatButtons;
}
}
else {
this->mRepeat = repeatButtons & (this->mRepeatLastButton ^ 0xFFFFFFFF);
this->mRepeatLastButton = repeatButtons;
this->mRepeatTimer = 0;
}
}
}
this->mTrigger = buttons & (buttons ^ this->mButton);
this->mRelease = this->mButton & (buttons ^ this->mButton);
this->mButton = buttons;
this->mRepeat |= (this->mRepeatMask ^ 0xFFFFFFFF) & this->mTrigger;
if (padStatus != nullptr) {
this->mAnalogA = padStatus->analogA;
this->mAnalogB = padStatus->analogB;
this->mAnalogL = padStatus->triggerLeft;
this->mAnalogR = padStatus->triggerRight;
}
else {
this->mButton = 0;
this->mTrigger = 0;
this->mRelease = 0;
this->mRepeat = 0;
this->mAnalogA = 0;
this->mAnalogB = 0;
this->mAnalogL = 0;
this->mAnalogR = 0;
}
this->mRepeatTimer = 0;
this->mRepeatLastButton = 0;
this->mRepeatMask = 0;
this->mRepeatDelay = 0;
this->mRepeatFrequency = 0;
}
this->mAnalogLf = (f32)(int)this->mAnalogL / 150.0f;
this->mAnalogRf = (f32)(int)this->mAnalogR / 150.0f;
void JUTGamePad::CButton::update(const PADStatus* padStatus, u32 stick_buttons) {
u32 tempButtons;
u32 buttons;
if (padStatus != nullptr) {
tempButtons = padStatus->button;
} else {
tempButtons = 0;
}
buttons = stick_buttons | tempButtons;
this->mRepeat = 0;
if (this->mRepeatDelay != 0) {
if (this->mRepeatMask != 0) {
u32 repeatButtons = buttons & this->mRepeatMask;
this->mRepeat = 0;
if (repeatButtons == 0) {
this->mRepeatLastButton = 0;
this->mRepeatTimer = 0;
} else if (this->mRepeatLastButton == repeatButtons) {
this->mRepeatTimer++;
if (this->mRepeatTimer == this->mRepeatDelay ||
(this->mRepeatTimer > this->mRepeatDelay &&
((this->mRepeatTimer - this->mRepeatDelay) % this->mRepeatFrequency) == 0)) {
this->mRepeat = repeatButtons;
}
} else {
this->mRepeat = repeatButtons & (this->mRepeatLastButton ^ 0xFFFFFFFF);
this->mRepeatLastButton = repeatButtons;
this->mRepeatTimer = 0;
}
}
}
this->mTrigger = buttons & (buttons ^ this->mButton);
this->mRelease = this->mButton & (buttons ^ this->mButton);
this->mButton = buttons;
this->mRepeat |= (this->mRepeatMask ^ 0xFFFFFFFF) & this->mTrigger;
if (padStatus != nullptr) {
this->mAnalogA = padStatus->analogA;
this->mAnalogB = padStatus->analogB;
this->mAnalogL = padStatus->triggerLeft;
this->mAnalogR = padStatus->triggerRight;
} else {
this->mAnalogA = 0;
this->mAnalogB = 0;
this->mAnalogL = 0;
this->mAnalogR = 0;
}
this->mAnalogLf = (f32)(int)this->mAnalogL / 150.0f;
this->mAnalogRf = (f32)(int)this->mAnalogR / 150.0f;
}
void JUTGamePad::CStick::clear() {
this->mX = 0.0f;
this->mY = 0.0f;
this->mValue = 0.0f;
this->mAngle = 0;
this->mX = 0.0f;
this->mY = 0.0f;
this->mValue = 0.0f;
this->mAngle = 0;
}
u32 JUTGamePad::CStick::update(s8 x, s8 y, EStickMode stickMode, EWhichStick whichStick) {
int stickMax = whichStick == WhichStick_MainStick ? 54 : 42;
this->mX = (f32)x / (f32)stickMax;
this->mY = (f32)y / (f32)stickMax;
this->mValue = sqrtf(this->mX * this->mX + this->mY * this->mY);
int stickMax = whichStick == WhichStick_MainStick ? 54 : 42;
if (this->mValue > 1.0f) {
if (stickMode == Clamped) {
this->mX /= this->mValue;
this->mY /= this->mValue;
this->mX = (f32)x / (f32)stickMax;
this->mY = (f32)y / (f32)stickMax;
this->mValue = sqrtf(this->mX * this->mX + this->mY * this->mY);
if (this->mValue > 1.0f) {
if (stickMode == Clamped) {
this->mX /= this->mValue;
this->mY /= this->mValue;
}
this->mValue = 1.0f;
}
this->mValue = 1.0f;
}
if (this->mValue > 0.0f) {
if (this->mY == 0.0f) {
if (this->mX > 0.0f) {
this->mAngle = 0x4000;
}
else {
this->mAngle = -0x4000;
}
if (this->mValue > 0.0f) {
if (this->mY == 0.0f) {
if (this->mX > 0.0f) {
this->mAngle = 0x4000;
} else {
this->mAngle = -0x4000;
}
} else {
f32 angle = atan2(this->mX, -this->mY);
this->mAngle = angle * 10430.379f; //((f32)0x8000 / F_PI);
}
}
else {
f32 angle = atan2(this->mX, -this->mY);
this->mAngle = angle * 10430.379f; //((f32)0x8000 / F_PI);
}
}
return this->getButton();
return this->getButton();
}
u32 JUTGamePad::CStick::getButton() {
u32 button = 0;
u32 button = 0;
if (-0.25f < this->mX && this->mX < 0.25f) {
button &= ~(DPAD_LEFT | DPAD_RIGHT);
}
else if (this->mX <= -0.5f) {
button |= DPAD_LEFT;
}
else if (this->mX >= 0.5f) {
button |= DPAD_RIGHT;
}
if (-0.25f < this->mX && this->mX < 0.25f) {
button &= ~(DPAD_LEFT | DPAD_RIGHT);
} else if (this->mX <= -0.5f) {
button |= DPAD_LEFT;
} else if (this->mX >= 0.5f) {
button |= DPAD_RIGHT;
}
if (-0.25f < this->mY && this->mY < 0.25f) {
button &= ~(DPAD_DOWN | DPAD_UP);
}
else if (this->mY <= -0.5f) {
button |= DPAD_DOWN;
}
else if (this->mY >= 0.5f) {
button |= DPAD_UP;
}
if (-0.25f < this->mY && this->mY < 0.25f) {
button &= ~(DPAD_DOWN | DPAD_UP);
} else if (this->mY <= -0.5f) {
button |= DPAD_DOWN;
} else if (this->mY >= 0.5f) {
button |= DPAD_UP;
}
return button;
return button;
}
void JUTGamePad::CRumble::clear() {
this->mFrame = 0;
this->mLength = 0;
this->mData = nullptr;
this->mFrameCount = 0;
JUTGamePad::CRumble::mEnabled = 0xF0000000;
}
void JUTGamePad::CRumble::clear(JUTGamePad* gamePad) {
if (0 <= gamePad->getPortNum() && gamePad->getPortNum() < PAD_MAX_CONTROLLERS) {
JUTGamePad::CRumble::mStatus[gamePad->getPortNum()] = 0;
this->stopMotorHard(gamePad->getPortNum());
}
this->clear();
}
void JUTGamePad::CRumble::startMotor(int port) {
if (JUTGamePad::CRumble::isEnabled(channel_mask[port])) {
PADControlMotor(port, PAD_MOTOR_RUMBLE);
JUTGamePad::CRumble::mStatus[port] = 1;
}
}
void JUTGamePad::CRumble::stopMotor(int port) {
if (JUTGamePad::CRumble::isEnabled(channel_mask[port])) {
PADControlMotor(port, PAD_MOTOR_STOP);
JUTGamePad::CRumble::mStatus[port] = 0;
}
}
void JUTGamePad::CRumble::stopMotorHard(int port) {
if (JUTGamePad::CRumble::isEnabled(channel_mask[port])) {
PADControlMotor(port, PAD_MOTOR_STOP_HARD);
JUTGamePad::CRumble::mStatus[port] = 0;
}
}
static inline u8 getNumBit(const u8* data, int bit) {
return (((0x80 >> (bit & 7)) & data[(u32)bit >> 3]) & 0xFF);
}
void JUTGamePad::CRumble::update(s16 port) {
if (!JUTGamePad::CRumble::isEnabled(channel_mask[port])) {
this->mFrame = 0;
this->mLength = 0;
this->mData = nullptr;
this->mFrameCount = 0;
}
JUTGamePad::CRumble::mEnabled = 0xF0000000;
}
if (this->mLength != 0) {
if (this->mFrame >= this->mLength) {
JUTGamePad::CRumble::stopMotorHard(port);
this->mLength = 0;
void JUTGamePad::CRumble::clear(JUTGamePad* gamePad) {
if (0 <= gamePad->getPortNum() && gamePad->getPortNum() < PAD_MAX_CONTROLLERS) {
JUTGamePad::CRumble::mStatus[gamePad->getPortNum()] = 0;
this->stopMotorHard(gamePad->getPortNum());
}
else {
if (this->mFrameCount == 0) {
if (JUTGamePad::CRumble::mStatus[port] == 0) {
JUTGamePad::CRumble::startMotor(port);
this->clear();
}
void JUTGamePad::CRumble::startMotor(int port) {
if (JUTGamePad::CRumble::isEnabled(channel_mask[port])) {
PADControlMotor(port, PAD_MOTOR_RUMBLE);
JUTGamePad::CRumble::mStatus[port] = 1;
}
}
void JUTGamePad::CRumble::stopMotor(int port) {
if (JUTGamePad::CRumble::isEnabled(channel_mask[port])) {
PADControlMotor(port, PAD_MOTOR_STOP);
JUTGamePad::CRumble::mStatus[port] = 0;
}
}
void JUTGamePad::CRumble::stopMotorHard(int port) {
if (JUTGamePad::CRumble::isEnabled(channel_mask[port])) {
PADControlMotor(port, PAD_MOTOR_STOP_HARD);
JUTGamePad::CRumble::mStatus[port] = 0;
}
}
static inline u8 getNumBit(const u8* data, int bit) {
return (((0x80 >> (bit & 7)) & data[(u32)bit >> 3]) & 0xFF);
}
void JUTGamePad::CRumble::update(s16 port) {
if (!JUTGamePad::CRumble::isEnabled(channel_mask[port])) {
this->mFrame = 0;
this->mLength = 0;
this->mData = nullptr;
this->mFrameCount = 0;
}
if (this->mLength != 0) {
if (this->mFrame >= this->mLength) {
JUTGamePad::CRumble::stopMotorHard(port);
this->mLength = 0;
} else {
if (this->mFrameCount == 0) {
if (JUTGamePad::CRumble::mStatus[port] == 0) {
JUTGamePad::CRumble::startMotor(port);
}
return;
}
u8 bit = getNumBit(this->mData, this->mFrame % this->mFrameCount);
if (bit != 0 && JUTGamePad::CRumble::mStatus[port] == 0) {
JUTGamePad::CRumble::startMotor(port);
} else if (bit == 0 && JUTGamePad::CRumble::mStatus[port] != 0) {
JUTGamePad::CRumble::stopMotorHard(port);
}
}
return;
}
u8 bit = getNumBit(this->mData, this->mFrame % this->mFrameCount);
if (bit != 0 && JUTGamePad::CRumble::mStatus[port] == 0) {
JUTGamePad::CRumble::startMotor(port);
}
else if (bit == 0 && JUTGamePad::CRumble::mStatus[port] != 0) {
JUTGamePad::CRumble::stopMotorHard(port);
}
this->mFrame++;
}
this->mFrame++;
}
}
void JUTGamePad::CButton::setRepeat(u32 repeatMask, u32 repeatDelay, u32 repeatFreq) {
this->mRepeatLastButton = 0;
this->mRepeatTimer = 0;
this->mRepeatMask = repeatMask;
this->mRepeatDelay = repeatDelay;
this->mRepeatFrequency = repeatFreq;
this->mRepeatLastButton = 0;
this->mRepeatTimer = 0;
this->mRepeatMask = repeatMask;
this->mRepeatDelay = repeatDelay;
this->mRepeatFrequency = repeatFreq;
}
bool JUTGamePad::recalibrate(u32 channels) {
u32 channelMasks[PAD_MAX_CONTROLLERS] = {
0x80000000 >> 0,
0x80000000 >> 1,
0x80000000 >> 2,
0x80000000 >> 3
};
u32 channelMasks[PAD_MAX_CONTROLLERS] = { 0x80000000 >> 0, 0x80000000 >> 1, 0x80000000 >> 2, 0x80000000 >> 3 };
for (int i = 0; i < PAD_MAX_CONTROLLERS; i++) {
if ((JUTGamePad::mSuppressPadReset & channelMasks[i]) != 0) {
channels &= channelMasks[i] ^ 0xFFFFFFFF;
for (int i = 0; i < PAD_MAX_CONTROLLERS; i++) {
if ((JUTGamePad::mSuppressPadReset & channelMasks[i]) != 0) {
channels &= channelMasks[i] ^ 0xFFFFFFFF;
}
}
}
return PADRecalibrate(channels);
return PADRecalibrate(channels);
}
@@ -0,0 +1,38 @@
#include <dolphin/gx.h>
#include "JSystem/JKernel/JKRHeap.h"
#include "JSystem/JUtility/JUTGraphFifo.h"
bool JUTGraphFifo::sInitiated;
JUTGraphFifo* JUTGraphFifo::sCurrentFifo;
GXBool JUTGraphFifo::mGpStatus[5];
JUTGraphFifo::JUTGraphFifo(u32 size) {
mSize = ALIGN_NEXT(size, 32);
if (sInitiated) {
mFifo = (GXFifoObj*)JKRAllocFromSysHeap(mSize + sizeof(GXFifoObj), 32);
mBase = mFifo + 1;
GXInitFifoBase(mFifo, mBase, mSize);
GXInitFifoPtrs(mFifo, mBase, mBase);
} else {
/** TODO: Figure out what has sizeof 0xA0. */
mBase = JKRAllocFromSysHeap(mSize + 0xA0, 32);
mBase = (void*)ALIGN_NEXT((u32)mBase, 32);
mFifo = GXInit(mBase, mSize);
sInitiated = true;
sCurrentFifo = this;
}
}
JUTGraphFifo::~JUTGraphFifo() {
sCurrentFifo->save();
while (isGPActive()) {
;
}
if (sCurrentFifo == this) {
sCurrentFifo = nullptr;
}
JKRFreeToSysHeap(mBase);
}
+294
View File
@@ -0,0 +1,294 @@
#include "JSystem/J2D/J2DGrafContext.h"
#include "JSystem/JUtility/JUTVideo.h"
#include "JSystem/JUtility/JUTProcBar.h"
JUTProcBar* JUTProcBar::sManager;
f32 oneFrameRate = 8.0f;
f32 oneFrameRateUser = 10.0f;
JUTProcBar::JUTProcBar() {
mVisible = true;
mHeapBarVisible = true;
_108 = 0;
u16 height = JUTVideo::getManager()->getXfbHeight();
if (JUTVideo::getManager()->getXfbHeight() > 400) {
mParams.setBarWidth(2);
mParams.setPosition(39, height - 40);
mParams.setWidth(562);
mParams.setUserPosition(height - 70);
} else {
mParams.setBarWidth(1);
mParams.setPosition(39, height - 20);
mParams.setWidth(562);
mParams.setUserPosition(height - 35);
}
_110 = 1;
_128 = 0;
mWatchHeap = nullptr;
}
JUTProcBar::~JUTProcBar() {
sManager = nullptr;
}
JUTProcBar* JUTProcBar::create() {
if (!sManager) {
sManager = new JUTProcBar();
}
return sManager;
}
void JUTProcBar::destroy() {
if (sManager) {
delete sManager;
}
sManager = nullptr;
}
void JUTProcBar::clear() {
sManager->idleStart();
sManager->cpuStart();
sManager->gpStart();
sManager->wholeLoopStart();
sManager->mCostFrame = 0;
oneFrameRate = 8.0f;
oneFrameRateUser = 10.0f;
}
// Matches
void JUTProcBar::bar_subroutine(int param_0, int param_1, int param_2, int param_3, int param_4, int param_5,
int param_6, JUtility::TColor param_7, JUtility::TColor param_8) {
int var2 = param_5 * param_3 / param_4;
int var1 = param_6 * param_3 / param_4;
J2DFillBox(param_0, param_1, var2, param_2, param_7);
if (var1 >= 0) {
if (var1 < 6)
J2DFillBox(param_0, param_1, var1, param_2, param_8);
else
J2DFillBox(param_0 + var1 - 6, param_1, 6.0f, param_2, param_8);
}
}
// Matched
// perhaps rewrite this function, kinda annoying to read
void JUTProcBar::adjustMeterLength(u32 param_0, f32* param_1, f32 param_2, f32 param_3, int* param_4) {
BOOL var2 = false;
float var1 = *param_1;
while (var1 > param_2) {
if (param_0 * var1 * 20.0f / 16666.0f <= mParams.mWidth - 30.0f)
break;
var1 -= 0.1f;
var2 = true;
}
if (var1 >= param_3)
*param_4 = 0;
if (var1 > param_3 - 0.2f)
var1 = param_3;
while (!var2 && var1 < param_3) {
(*param_4)++;
if (*param_4 < 0x1e)
break;
if ((param_0 * var1 * 20.0f / 16666.0f) < (mParams.mWidth - 60.0f))
var1 += 0.2f;
break;
}
*param_1 = var1;
}
void JUTProcBar::draw() {
drawProcessBar();
drawHeapBar();
}
/*
MKDD: https://decomp.me/scratch/1Q2Ke
TP: https://decomp.me/scratch/YKjcF
*/
void JUTProcBar::drawProcessBar() {
if (mVisible) {
int frameDuration = 16666; // duration in miliseconds? for how long a frame takes,
if (JUTVideo::getManager() &&
((JUTVideo::getManager()->getRenderMode()->viTVmode >> 2) & 0x0f) == VI_PAL) // possibly a define
frameDuration = 20000; // duration for PAL
static int cnt = 0;
adjustMeterLength(mWholeLoop.mCost, &oneFrameRate, 1.0f, 10.0f, &cnt);
int r28 = oneFrameRate * 20.0f;
int r27 = mParams.mBarWidth * 8;
int r26 = mParams.mBarWidth * 2;
int r25 = mParams.mBarWidth * 10;
int r24 = (mParams.mWidth - 4 + r28) / r28;
mIdle.accumePeek();
mGp.accumePeek();
mCpu.accumePeek();
u32 totalTime = (mGp.mCost - mGpWait.mCost) - mCpu.mCost; // unsure of types
u32 gpuTime = (mGp.mCost - mGpWait.mCost);
J2DFillBox(mParams.mPosX, mParams.mPosY, mParams.mWidth, r27, JUtility::TColor(0, 0, 50, 200));
J2DDrawFrame(mParams.mPosX, mParams.mPosY, mParams.mWidth, r27, JUtility::TColor(50, 50, 150, 255), 6);
if (mCostFrame > r24)
J2DFillBox(mParams.mPosX, mParams.mPosY + r27 + 1, mParams.mWidth, 1.0f, JUtility::TColor(250, 0, 0, 200));
else
J2DFillBox(mParams.mPosX, mParams.mPosY + r27 + 1, mCostFrame * r28 + 2, 1.0f,
JUtility::TColor(0, 250, 250, 200));
int stack92 = mWholeLoop.mCost * r28 / frameDuration;
if (stack92 > mParams.mWidth)
J2DFillBox(mParams.mPosX, mParams.mPosY, mParams.mWidth, 1.0f, JUtility::TColor(255, 100, 0, 255));
else
J2DFillBox(mParams.mPosX, mParams.mPosY, stack92, 1.0f, JUtility::TColor(50, 255, 0, 255));
if (_110 == 0) {
int r23 = mParams.mPosY + mParams.mBarWidth;
bar_subroutine(mParams.mPosX + 1, r23, r26, r28, frameDuration, mGp.mCost, mGp._08,
JUtility::TColor(80, 255, 80, 255), JUtility::TColor(100, 255, 120, 255));
r23 += mParams.mBarWidth * 2;
bar_subroutine(mParams.mPosX + 1, r23, r26, r28, frameDuration, mCpu.mCost, mCpu._08,
JUtility::TColor(255, 80, 80, 255), JUtility::TColor(255, 100, 100, 255));
r23 += mParams.mBarWidth * 2;
bar_subroutine(mParams.mPosX + 1, r23, r26, r28, frameDuration, mIdle.mCost, mIdle._08,
JUtility::TColor(180, 180, 160, 255), JUtility::TColor(200, 200, 200, 255));
} else {
int r22 = mParams.mPosY + mParams.mBarWidth;
int r21 = mParams.mPosX + 1;
bar_subroutine(r21, r22, r26, r28, frameDuration, gpuTime, -1, JUtility::TColor(80, 255, 80, 255),
JUtility::TColor(80, 255, 80, 255));
int thingy1 = gpuTime * r28 / frameDuration + r21;
J2DFillBox(thingy1, r22, mGpWait.calcBarSize(r28, frameDuration), r26, JUtility::TColor(0, 255, 0, 255));
int r30 = mGp.calcBarSize(r28, frameDuration) + r21;
r21 += totalTime * r28 / frameDuration;
r22 += mParams.mBarWidth * 2;
bar_subroutine(r21, r22, r26, r28, frameDuration, mCpu.mCost, -1, JUtility::TColor(255, 80, 80, 255),
JUtility::TColor(255, 80, 80, 255));
r22 += mParams.mBarWidth * 2;
bar_subroutine(r30, r22, r26, r28, frameDuration, mIdle.mCost, -1, JUtility::TColor(180, 180, 160, 255),
JUtility::TColor(180, 180, 160, 255));
}
for (int i = 1; i < r24; i++) {
int temp2 = mParams.mPosX + i * r28 + 1;
J2DDrawLine(temp2, mParams.mPosY + mParams.mBarWidth, temp2, mParams.mPosY + r27 - mParams.mBarWidth,
(i % 5) != 0 ? JUtility::TColor(100, 100, 255, 255) : JUtility::TColor(180, 255, 255, 255), 12);
}
u32 temp3 = 0;
for (int i = 0; i < 8; i++) {
CTime* time = &mUsers[i];
if (++time->_0C >= 0x10 || time->mCost > time->_08) {
time->_08 = time->mCost;
time->_0C = 0;
}
if (time->_08 > temp3)
temp3 = time->_08;
}
if ((temp3 ? true : false) == true) {
static int cntUser = 0;
adjustMeterLength(temp3, &oneFrameRateUser, 1.0f, 10.0f, &cntUser);
int r21 = oneFrameRateUser * 20.0f;
J2DFillBox(mParams.mPosX, mParams.mUserPosition, mParams.mWidth, r25, JUtility::TColor(0, 0, 50, 200));
J2DDrawFrame(mParams.mPosX, mParams.mUserPosition, mParams.mWidth, r25, JUtility::TColor(50, 50, 150, 255),
6);
for (int i = 0; i < 8; i++) {
CTime* time = &mUsers[i];
if (++time->_0C >= 0x10 || time->mCost > time->_08) {
time->_08 = time->mCost;
time->_0C = 0;
}
if (time->mCost != 0 || time->_08 != 0) {
int temp4 = time->mCost * r21 / frameDuration;
int temp5 = time->_08 * r21 / frameDuration;
time->mCost = 0;
J2DFillBox(mParams.mPosX + 1, mParams.mUserPosition + mParams.mBarWidth + i * mParams.mBarWidth,
temp4, mParams.mBarWidth, JUtility::TColor(time->mR, time->mG, time->mB, 255));
if (temp5 < 3u)
J2DFillBox(mParams.mPosX, mParams.mUserPosition + mParams.mBarWidth + i * mParams.mBarWidth,
temp5, mParams.mBarWidth, JUtility::TColor(255, 200, 50, 255));
else
J2DFillBox(mParams.mPosX + temp5 - 3,
mParams.mUserPosition + mParams.mBarWidth + i * mParams.mBarWidth, 3.0f,
mParams.mBarWidth, JUtility::TColor(255, 200, 50, 255));
}
}
int r22 = (mParams.mWidth - 4 + r21) / r21;
for (int i = 1; i < r22; i++) {
int temp6 = mParams.mPosX + i * r21 + 1;
J2DDrawLine(temp6, mParams.mUserPosition + mParams.mBarWidth, temp6,
mParams.mUserPosition + r25 - mParams.mBarWidth,
(i % 5) != 0 ? JUtility::TColor(100, 100, 255, 255) : JUtility::TColor(180, 255, 255, 255),
12);
}
}
_108 = 0;
}
}
int addrToXPos(void* param_0, int param_1) {
return param_1 * (((u32)param_0 - 0x80000000) / (float)JKRHeap::getMemorySize());
}
int byteToXLen(int param_0, int param_1) {
return param_1 * (param_0 / (float)JKRHeap::getMemorySize());
}
static void heapBar(JKRHeap* param_0, int param_1, int param_2, int param_3, int param_4, int param_5) {
int stack52 = param_1 + addrToXPos(param_0->getStartAddr(), param_4);
int var1 = param_1 + addrToXPos(param_0->getEndAddr(), param_4);
int stack36 = byteToXLen(param_0->getTotalFreeSize(), param_4);
J2DFillBox(stack52, param_2 - param_5 * 2 + param_5 / 2, var1 - stack52, param_5 / 2,
JUtility::TColor(255, 0, 200, 255));
J2DFillBox(stack52, param_2 - param_5 * 2 + param_5 / 2, stack36, param_5 / 2,
JUtility::TColor(255, 180, 250, 255));
}
/*
Probably close to TP Debug, currently matches TP and MKDD(pik2 probably too)
MKDD(Debug): https://decomp.me/scratch/BUM6J
MKDD(Releae) https://decomp.me/scratch/bxY1q
TP(O3): https://decomp.me/scratch/Mi52V
*/
void JUTProcBar::drawHeapBar() {
if (mHeapBarVisible) {
int start; // required/workaround for regswaps, end might be a shared variable too, however doesn't seem to be
// needed?
int posX = mParams.mPosX;
int posY = mParams.mPosY;
int barHeight = mParams.mBarWidth * 2;
int width = mParams.mWidth;
int height = mParams.mBarWidth * 2;
// draw main box in opaque bordeaux red and main frame in purple?
J2DFillBox(posX, posY - (height * 2), width, height, JUtility::TColor(100, 0, 50, 200));
J2DDrawFrame(posX, posY - (height * 2), width, height, JUtility::TColor(100, 50, 150, 255), 6);
// Draws a pink line that shows the size of the memstart to start of arenalow?
start = posX + addrToXPos(JKRHeap::getCodeStart(), width);
int codeEnd = posX + addrToXPos(JKRHeap::getCodeEnd(), width);
J2DFillBox(start, posY - (height * 2), codeEnd - start, height, JUtility::TColor(255, 50, 150, 255));
// draws a dark blue line that shows how much memory is free?
start = posX + addrToXPos(JKRHeap::getUserRamStart(), width);
int userEnd = posX + addrToXPos(JKRHeap::getUserRamEnd(), width);
J2DFillBox(start, posY - (height * 2), userEnd - start, height, JUtility::TColor(0, 50, 150, 255));
// draws a light blue line that shows how much memory is free in the root heap(blends to light pink, not sure
// how this works)
int size = byteToXLen(JKRHeap::getRootHeap()->getTotalFreeSize(), width);
J2DFillBox(start, posY - (height * 2), size, height / 2, JUtility::TColor(0, 250, 250, 255));
if (_128 == 0) {
// draws a line of either the watch heap(if available), otherwise draw the current heap
JKRHeap* heap = mWatchHeap ? mWatchHeap : JKRGetCurrentHeap();
if (heap != JKRHeap::getSystemHeap()) {
heapBar(heap, posX, posY, barHeight, width, height);
}
}
}
}
+463
View File
@@ -0,0 +1,463 @@
#include <dolphin/gx.h>
#include "JSystem/JKernel/JKRHeap.h"
#include "JSystem/JSupport.h"
#include "JSystem/JUtility/JUTConsole.h"
#include "JSystem/JUtility/JUTAssertion.h"
#include "JSystem/JUtility/JUTFont.h"
#include "types.h"
JUTFont::IsLeadByte const JUTResFont::saoAboutEncoding_[3] = { JUTFont::isLeadByte_1Byte, JUTFont::isLeadByte_2Byte,
JUTFont::isLeadByte_ShiftJIS };
const u32 suAboutEncoding_ = 3;
JUTResFont::JUTResFont() {
initialize_state();
}
JUTResFont::JUTResFont(const ResFONT* resource, JKRHeap* heap) {
initialize_state();
JUTResFont::initiate(resource, heap);
}
JUTResFont::~JUTResFont() {
if (mValid) {
deleteMemBlocks_ResFont();
initialize_state();
JUTFont::initialize_state();
}
}
void JUTResFont::deleteMemBlocks_ResFont() {
delete[] mMemBlocks;
}
void JUTResFont::initialize_state() {
mResource = nullptr;
mMemBlocks = nullptr;
mWidthBlocks = nullptr;
mGlyphBlocks = nullptr;
mMapBlocks = nullptr;
mWidth = 0;
mHeight = 0;
_44 = -1;
}
bool JUTResFont::initiate(const ResFONT* resource, JKRHeap* heap) {
if (!protected_initiate(resource, heap)) {
deleteMemBlocks_ResFont();
initialize_state();
JUTFont::initialize_state();
mValid = false;
return false;
}
return true;
}
bool JUTResFont::protected_initiate(const ResFONT* resource, JKRHeap* heap) {
void** blocks;
deleteMemBlocks_ResFont();
initialize_state();
JUTFont::initialize_state();
if (!resource) {
return false;
}
mResource = resource;
mValid = true;
countBlock();
u32 blockNum = mWidthBlockCount + mGlyphBlockCount + mMapBlockCount;
mMemBlocks = new (heap, 0) void*[blockNum];
blocks = mMemBlocks;
if (mMemBlocks == nullptr) {
return false;
} else {
if (mWidthBlockCount != 0) {
mWidthBlocks = (ResFONT::WidthBlock**)blocks;
blocks += mWidthBlockCount;
}
if (mGlyphBlockCount != 0) {
mGlyphBlocks = (ResFONT::GlyphBlock**)blocks;
blocks += mGlyphBlockCount;
}
if (mMapBlockCount != 0) {
mMapBlocks = (ResFONT::MapBlock**)blocks;
}
}
setBlock();
return true;
}
void JUTResFont::countBlock() {
mWidthBlockCount = 0;
mGlyphBlockCount = 0;
mMapBlockCount = 0;
BlockHeader* data = (BlockHeader*)mResource->mData;
for (u32 i = 0; i < mResource->mNumBlocks; i++, data = (BlockHeader*)data->getNext()) {
int magic = data->mMagic;
switch (magic) {
case 'WID1':
mWidthBlockCount++;
break;
case 'GLY1':
mGlyphBlockCount++;
break;
case 'MAP1':
mMapBlockCount++;
break;
case 'INF1':
// mInfoBlock;
break;
default:
JUTReportConsole("JUTResFont: Unknown data block\n");
}
};
}
void JUTResFont::setBlock() {
int widthNum = 0;
int glyphNum = 0;
int mapNum = 0;
mMaxCode = -1;
BlockHeader* data = (BlockHeader*)mResource->mData;
for (u32 i = 0; i < mResource->mNumBlocks; i++, data = (BlockHeader*)data->getNext()) {
int magic = data->mMagic;
switch (magic) {
case 'INF1':
mInfoBlock = (ResFONT::InfoBlock*)data;
u32 u = mInfoBlock->mFontType;
JUT_ASSERT(u < suAboutEncoding_);
mIsLeadByte = (IsLeadByte*)&saoAboutEncoding_[u];
break;
case 'WID1':
mWidthBlocks[widthNum] = (ResFONT::WidthBlock*)data;
widthNum++;
break;
case 'GLY1':
mGlyphBlocks[glyphNum] = (ResFONT::GlyphBlock*)data;
glyphNum++;
break;
case 'MAP1':
mMapBlocks[mapNum] = (ResFONT::MapBlock*)data;
if (mMaxCode > mMapBlocks[mapNum]->mStartCode) {
mMaxCode = mMapBlocks[mapNum]->mStartCode;
}
mapNum++;
break;
default:
JUTReportConsole("Unknown data block\n");
break;
}
}
}
void JUTResFont::setGX() {
GXSetNumChans(1);
GXSetNumTevStages(1);
GXSetNumTexGens(1);
GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR0A0);
GXSetChanCtrl(GX_COLOR0A0, GX_FALSE, GX_SRC_REG, GX_SRC_VTX, GX_LIGHT_NULL, GX_DF_NONE, GX_AF_NONE);
GXSetTevOp(GX_TEVSTAGE0, GX_MODULATE);
GXSetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_SET);
GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_CLR_RGBA, GX_RGBA4, 0);
GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_CLR0, GX_CLR_RGBA, GX_RGBA8, 0);
GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_CLR_RGBA, GX_RGBX8, 15);
GXClearVtxDesc();
GXSetVtxDesc(GX_VA_POS, GX_DIRECT);
GXSetVtxDesc(GX_VA_CLR0, GX_DIRECT);
GXSetVtxDesc(GX_VA_TEX0, GX_DIRECT);
}
void JUTResFont::setGX(JUtility::TColor color0, JUtility::TColor color1) {
if (u32(color0) == 0 && u32(color1) == -1) {
setGX();
} else {
GXSetNumChans(1);
GXSetNumTevStages(2);
GXSetNumTexGens(1);
GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR_NULL);
GXSetChanCtrl(GX_COLOR0A0, GX_FALSE, GX_SRC_REG, GX_SRC_VTX, GX_LIGHT_NULL, GX_DF_NONE, GX_AF_NONE);
GXSetTevColor(GX_TEVREG0, color0);
GXSetTevColor(GX_TEVREG1, color1);
GXSetTevColorIn(GX_TEVSTAGE0, GX_CC_C0, GX_CC_C1, GX_CC_TEXC, GX_CC_ZERO);
GXSetTevAlphaIn(GX_TEVSTAGE0, GX_CA_A0, GX_CA_A1, GX_CA_TEXA, GX_CA_ZERO);
GXSetTevColorOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV);
GXSetTevAlphaOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV);
GXSetTevOrder(GX_TEVSTAGE1, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR0A0);
GXSetTevColorIn(GX_TEVSTAGE1, GX_CC_ZERO, GX_CC_CPREV, GX_CC_RASC, GX_CC_ZERO);
GXSetTevAlphaIn(GX_TEVSTAGE1, GX_CA_ZERO, GX_CA_APREV, GX_CA_RASA, GX_CA_ZERO);
GXSetTevColorOp(GX_TEVSTAGE1, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV);
GXSetTevAlphaOp(GX_TEVSTAGE1, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV);
GXSetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_SET);
GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_S16, 0);
GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_CLR0, GX_CLR_RGBA, GX_RGBA8, 0);
GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_CLR_RGBA, GX_RGBX8, 15);
GXClearVtxDesc();
GXSetVtxDesc(GX_VA_POS, GX_DIRECT);
GXSetVtxDesc(GX_VA_CLR0, GX_DIRECT);
GXSetVtxDesc(GX_VA_TEX0, GX_DIRECT);
}
}
f32 JUTResFont::drawChar_scale(f32 pos_x, f32 pos_y, f32 scale_x, f32 scale_y, int chr, bool flag) {
JUTFont::TWidth width;
f32 posMinX;
// declaration order matters!
f32 posMinY, scaled_height;
f32 posMaxX;
JUT_ASSERT(mValid);
loadFont(chr, GX_TEXMAP0, &width);
if ((mFixed) || (!flag)) {
posMinX = pos_x;
} else {
posMinX = (pos_x - width.w0 * (scale_x / getCellWidth()));
}
f32 retval = mFixedWidth * (scale_x / getCellWidth());
if (!mFixed) {
if (!flag) {
retval = (width.w1 + width.w0) * (scale_x / getCellWidth());
} else {
retval = width.w1 * (scale_x / getCellWidth());
}
}
posMaxX = posMinX + scale_x;
// getAscent needs to be called before getHeight for the sake of weak function order
posMinY = pos_y - getAscent() * (scale_y / getHeight());
scaled_height = scale_y / getHeight();
f32 descent = getDescent();
f32 posMaxY = descent * scaled_height + pos_y;
// glyph section
ResFONT::GlyphBlock* used_glyphs = mGlyphBlocks[_66];
u16 tex_width = used_glyphs->mTextureWidth;
u16 tex_height = used_glyphs->mTextureHeight;
int t_width = mWidth;
int t_height = mHeight;
int shift_width = (t_width + used_glyphs->mCellWidth) << 15;
int texMinX = (t_width << 15) / tex_width;
int texMinY = (t_height << 15) / tex_height;
int shift_height = t_height + used_glyphs->mCellHeight << 15;
const u32 texMaxX = shift_width / tex_width;
const u32 texMaxY = shift_height / tex_height;
// end glyph section
GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_F32, 0);
GXBegin(GX_QUADS, GX_VTXFMT0, 4);
// Bottom left
GXPosition3f32(posMinX, posMinY, 0.0f);
GXColor1u32(mColor1);
GXPosition2u16(texMinX, texMinY);
// Bottom right
GXPosition3f32(posMaxX, posMinY, 0.0f);
GXColor1u32(mColor2);
GXPosition2u16(texMaxX, texMinY);
// Top right
GXPosition3f32(posMaxX, posMaxY, 0.0f);
GXColor1u32(mColor4);
GXPosition2u16(texMaxX, texMaxY);
// Top left
GXPosition3f32(posMinX, posMaxY, 0.0f);
GXColor1u32(mColor3);
GXPosition2u16(texMinX, texMaxY);
GXEnd();
GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_S16, 0);
return retval;
}
void JUTResFont::loadFont(int chr, GXTexMapID id, JUTFont::TWidth* width) {
if (width) {
getWidthEntry(chr, width);
}
int fontcode = getFontCode(chr);
loadImage(fontcode, id);
}
void JUTResFont::getWidthEntry(int chr, JUTFont::TWidth* width) const {
int fontcode = getFontCode(chr);
width->w0 = 0;
width->w1 = mInfoBlock->mWidth;
for (int i = 0; i < mWidthBlockCount; i++) {
if (mWidthBlocks[i]->mStartCode <= fontcode && fontcode <= mWidthBlocks[i]->mEndCode) {
*width = mWidthBlocks[i]->mChunkNum[(fontcode - mWidthBlocks[i]->mStartCode)];
break;
}
}
return;
}
int JUTResFont::getCellWidth() const {
ResFONT::GlyphBlock* glyph;
ResFONT::GlyphBlock** glyphs;
glyphs = mGlyphBlocks;
if (glyphs) {
glyph = *glyphs;
if (glyph) {
return glyph->mCellWidth;
}
}
return getWidth();
}
int JUTResFont::getCellHeight() const {
ResFONT::GlyphBlock* glyph;
ResFONT::GlyphBlock** glyphs;
glyphs = mGlyphBlocks;
if (glyphs) {
glyph = *glyphs;
if (glyph) {
return glyph->mCellHeight;
}
}
return getHeight();
}
bool JUTResFont::isLeadByte(int chr) const {
return (*mIsLeadByte)(chr);
}
// regswaps
int JUTResFont::getFontCode(int chr) const {
static const u16 halftofull[95] = {
0x8140, 0x8149, 0x8168, 0x8194, 0x8190, 0x8193, 0x8195, 0x8166, 0x8169, 0x816A, 0x8196, 0x817B, 0x8143, 0x817C,
0x8144, 0x815E, 0x824F, 0x8250, 0x8251, 0x8252, 0x8253, 0x8254, 0x8255, 0x8256, 0x8257, 0x8258, 0x8146, 0x8147,
0x8183, 0x8181, 0x8184, 0x8148, 0x8197, 0x8260, 0x8261, 0x8262, 0x8263, 0x8264, 0x8265, 0x8266, 0x8267, 0x8268,
0x8269, 0x826A, 0x826B, 0x826C, 0x826D, 0x826E, 0x826F, 0x8270, 0x8271, 0x8272, 0x8273, 0x8274, 0x8275, 0x8276,
0x8277, 0x8278, 0x8279, 0x816D, 0x818F, 0x816E, 0x814F, 0x8151, 0x8165, 0x8281, 0x8282, 0x8283, 0x8284, 0x8285,
0x8286, 0x8287, 0x8288, 0x8289, 0x828A, 0x828B, 0x828C, 0x828D, 0x828E, 0x828F, 0x8290, 0x8291, 0x8292, 0x8293,
0x8294, 0x8295, 0x8296, 0x8297, 0x8298, 0x8299, 0x829A, 0x816F, 0x8162, 0x8170, 0x8160,
};
int ret = mInfoBlock->mDefaultCode;
if ((getFontType() == 2) && (mMaxCode >= 0x8000U) && (chr >= 0x20) && (chr < 0x7FU)) {
chr = halftofull[chr - 32];
}
for (int i = 0; i < mMapBlockCount; i++) {
if ((mMapBlocks[i]->mStartCode <= chr) && (chr <= mMapBlocks[i]->mEndCode)) {
if (mMapBlocks[i]->mMappingMethod == 0) {
ret = chr - mMapBlocks[i]->mStartCode;
break;
} else if (mMapBlocks[i]->mMappingMethod == 2) {
ret = *(&mMapBlocks[i]->mLeading + ((chr - mMapBlocks[i]->mStartCode))); // type punning sin
break;
} else if (mMapBlocks[i]->mMappingMethod == 3) {
u16* leading_temp = &mMapBlocks[i]->mLeading;
int phi_r5 = 0;
int phi_r6_2 = mMapBlocks[i]->mNumEntries - 1;
while (phi_r6_2 >= phi_r5) {
int temp_r7 = (phi_r6_2 + phi_r5) / 2;
if (chr < leading_temp[temp_r7 * 2]) {
phi_r6_2 = temp_r7 - 1;
continue;
}
if (chr > leading_temp[temp_r7 * 2]) {
phi_r5 = temp_r7 + 1;
continue;
}
ret = leading_temp[temp_r7 * 2 + 1]; // jank? possibly type punning fuckery
break;
} // loop closes here
} else if (mMapBlocks[i]->mMappingMethod == 1) {
u16* phi_r5_2 = nullptr;
if (mMapBlocks[i]->mNumEntries == 1) {
phi_r5_2 = &mMapBlocks[i]->mLeading;
}
ret = JUTResFont::convertSjis(chr, phi_r5_2);
break;
}
break;
}
}
return ret;
}
void JUTResFont::loadImage(int code, GXTexMapID id) {
int i = 0;
for (; i < mGlyphBlockCount; i++) {
if (mGlyphBlocks[i]->mStartCode <= code && code <= mGlyphBlocks[i]->mEndCode) {
code -= mGlyphBlocks[i]->mStartCode;
break;
}
}
if (i == mGlyphBlockCount)
return;
s32 pageNumCells = mGlyphBlocks[i]->mNumRows * mGlyphBlocks[i]->mNumColumns;
s32 pageIdx = code / pageNumCells;
s32 cellIdxInPage = code % pageNumCells;
s32 cellCol = (cellIdxInPage % mGlyphBlocks[i]->mNumRows);
s32 cellRow = (cellIdxInPage / mGlyphBlocks[i]->mNumRows);
mWidth = cellCol * mGlyphBlocks[i]->mCellWidth;
mHeight = cellRow * mGlyphBlocks[i]->mCellHeight;
if (pageIdx != _44 || i != _66) {
GXInitTexObj(&_24, &mGlyphBlocks[i]->mData[pageIdx * mGlyphBlocks[i]->mTextureSize],
mGlyphBlocks[i]->mTextureWidth, mGlyphBlocks[i]->mTextureHeight,
(GXTexFmt)mGlyphBlocks[i]->mTextureFormat, GX_CLAMP, GX_CLAMP, 0);
GXInitTexObjLOD(&_24, GX_LINEAR, GX_LINEAR, 0.0f, 0.0f, 0.0f, 0U, 0U, GX_ANISO_1);
_44 = pageIdx;
_66 = i;
}
GXLoadTexObj(&_24, id);
}
// probably needs some work to match TP(debug)
int JUTResFont::convertSjis(int inChr, u16* inLead) const {
u8 hi = JSUHiByte(inChr);
u16 lead = JSULoByte(inChr);
int out = lead - 0x40;
if (0x40 <= out) {
out--;
}
lead = 0x31c;
if (inLead) {
lead = *inLead;
}
return out + (hi - 0x88) * 0xbc + -0x5e + lead;
}
+193
View File
@@ -0,0 +1,193 @@
#include <dolphin/vi.h>
#include "JSystem/JUtility/JUTDirectPrint.h"
#include "JSystem/JUtility/JUTVideo.h"
#include "JSystem/JUtility/JUTXfb.h"
JUTVideo* JUTVideo::sManager;
OSTick JUTVideo::sVideoLastTick;
OSTick JUTVideo::sVideoInterval;
bool sDrawWaiting;
JUTVideo* JUTVideo::createManager(const GXRenderModeObj* renderModeObj) {
if (sManager == nullptr) {
sManager = new JUTVideo(renderModeObj);
}
return sManager;
}
void JUTVideo::destroyManager() {
if (sManager != nullptr) {
delete sManager;
sManager = nullptr;
}
}
JUTVideo::JUTVideo(const GXRenderModeObj* renderModeObj) {
mRenderModeObj = nullptr;
VIInit();
setRenderMode(renderModeObj);
mIsSetBlack = true;
mSetBlackFrameCount = 2;
VISetBlack(TRUE);
VIFlush();
_08 = 0;
mRetraceCount = VIGetRetraceCount();
_10 = 1;
_18 = 0;
sVideoLastTick = OSGetTick();
sVideoInterval = 670000;
mPreviousPreRetraceCallback = VISetPreRetraceCallback(preRetraceProc);
mPreviousPostRetraceCallback = VISetPostRetraceCallback(postRetraceProc);
mPreRetraceCallback = nullptr;
mPostRetraceCallback = nullptr;
OSInitMessageQueue(&mMessageQueue, &mMessage, 1);
GXSetDrawDoneCallback(drawDoneCallback);
}
JUTVideo::~JUTVideo() {
VISetPreRetraceCallback(mPreviousPreRetraceCallback);
VISetPostRetraceCallback(mPreviousPostRetraceCallback);
}
void JUTVideo::preRetraceProc(u32 retrace_count) {
if (sManager->mPreRetraceCallback) {
(*sManager->mPreRetraceCallback)(retrace_count);
}
OSTick tick = OSGetTick();
sVideoInterval = OSDiffTick(tick, sVideoLastTick);
sVideoLastTick = tick;
JUTXfb* xfb = JUTXfb::getManager();
if (!xfb) {
VISetBlack(TRUE);
VIFlush();
return;
}
static void* frameBuffer = nullptr;
if (frameBuffer) {
JUTVideo* videoManager = JUTGetVideoManager();
const GXRenderModeObj* renderMode = videoManager->getRenderMode();
JUTDirectPrint* directPrint = JUTDirectPrint::getManager();
directPrint->changeFrameBuffer(frameBuffer, renderMode->fbWidth, renderMode->efbHeight);
}
if (sManager->mIsSetBlack == 1) {
s32 frame_count = sManager->mSetBlackFrameCount;
if (frame_count > 0) {
frame_count--;
}
sManager->mSetBlackFrameCount = frame_count;
sManager->mIsSetBlack = frame_count != 0 ? true : false;
VISetBlack(TRUE);
VIFlush();
return;
}
if (!xfb) {
VISetBlack(TRUE);
VIFlush();
return;
}
if (xfb->getBufferNum() == 3 || xfb->getBufferNum() == 2) {
if (!sDrawWaiting) {
s16 index = xfb->getDrawnXfbIndex();
xfb->setDisplayingXfbIndex(index);
if (index < 0) {
VISetBlack(TRUE);
VIFlush();
} else {
VISetBlack(FALSE);
VISetNextFrameBuffer(xfb->getDisplayingXfb());
VIFlush();
frameBuffer = xfb->getDisplayingXfb();
}
}
} else if (xfb->getBufferNum() == 1) {
if (xfb->getSDrawingFlag() == 0) {
s16 index = xfb->getDrawnXfbIndex();
if (index >= 0) {
xfb->setDisplayingXfbIndex(index);
GXCopyDisp(xfb->getDisplayingXfb(), GX_TRUE);
GXFlush();
xfb->setSDrawingFlag(2);
frameBuffer = xfb->getDisplayingXfb();
VISetBlack(FALSE);
} else {
VISetBlack(TRUE);
}
}
VIFlush();
}
}
void JUTVideo::drawDoneStart() {
sDrawWaiting = true;
GXSetDrawDone();
}
void JUTVideo::dummyNoDrawWait() {
sDrawWaiting = false;
}
void JUTVideo::drawDoneCallback() {
JUTXfb* xfb = JUTXfb::getManager();
if (!xfb) {
return;
}
sDrawWaiting = false;
if (xfb->getBufferNum() == JUTXfb::SingleBuffer && xfb->getSDrawingFlag() == 1) {
xfb->setSDrawingFlag(0);
if (xfb->getDrawnXfb()) {
VISetNextFrameBuffer(xfb->getDrawnXfb());
VIFlush();
}
}
}
void JUTVideo::postRetraceProc(u32 p1) {
if (sManager->mPostRetraceCallback != nullptr) {
sManager->mPostRetraceCallback(p1);
}
u32 retraceCount = VIGetRetraceCount();
OSSendMessage(&sManager->mMessageQueue, (void*)retraceCount, OS_MESSAGE_NOBLOCK);
}
void JUTVideo::setRenderMode(const GXRenderModeObj* newRenderModeObj) {
if (mRenderModeObj && newRenderModeObj->viTVmode != mRenderModeObj->viTVmode) {
mIsSetBlack = true;
mSetBlackFrameCount = 4;
}
mRenderModeObj = (GXRenderModeObj*)newRenderModeObj;
VIConfigure(mRenderModeObj);
VIFlush();
if (mIsSetBlack) {
VIWaitForRetrace();
VIWaitForRetrace();
}
}
void JUTVideo::waitRetraceIfNeed() {
}
VIRetraceCallback JUTVideo::setPreRetraceCallback(VIRetraceCallback newCB) {
VIRetraceCallback oldCB = mPreRetraceCallback;
mPreRetraceCallback = newCB;
return oldCB;
}
VIRetraceCallback JUTVideo::setPostRetraceCallback(VIRetraceCallback newCB) {
VIRetraceCallback oldCB = mPostRetraceCallback;
mPostRetraceCallback = newCB;
return oldCB;
}
+94
View File
@@ -0,0 +1,94 @@
#include <dolphin/gx.h>
#include <dolphin/vi.h>
#include "JSystem/JUtility/JUTAssertion.h"
#include "JSystem/JKernel/JKRHeap.h"
#include "JSystem/JUtility/JUTVideo.h"
#include "JSystem/JUtility/JUTXfb.h"
JUTXfb* JUTXfb::sManager;
void JUTXfb::clearIndex() {
mDrawingXfbIndex = -1;
mDrawnXfbIndex = -1;
mDisplayingXfbIndex = -1;
}
void JUTXfb::common_init(int xfbNum) {
mBufferNum = xfbNum;
clearIndex();
mSDrawingFlag = 99;
}
JUTXfb::JUTXfb(const GXRenderModeObj* rmode, JKRHeap* heap, JUTXfb::EXfbNumber number) {
common_init(number);
if (rmode) {
initiate(rmode->fbWidth, rmode->xfbHeight, heap, number);
} else {
u16 efbWidth = JUTVideo::getManager()->getRenderMode()->fbWidth;
u16 xfbHeight = JUTVideo::getManager()->getRenderMode()->xfbHeight;
u16 efbHeight = JUTVideo::getManager()->getRenderMode()->efbHeight;
initiate(efbWidth, xfbHeight, heap, number);
}
}
JUTXfb::~JUTXfb() {
for (int i = 0; i < 3; i++) {
delXfb(i);
}
sManager = nullptr;
}
void JUTXfb::delXfb(int xfbIdx) {
if (mXfbAllocated[xfbIdx] && mBuffer[xfbIdx]) {
delete mBuffer[xfbIdx];
}
}
JUTXfb* JUTXfb::createManager(const GXRenderModeObj* rmode, JKRHeap* heap, JUTXfb::EXfbNumber number) {
JUT_CONFIRM_MESSAGE(sManager == 0);
if (sManager == nullptr) {
sManager = new JUTXfb(rmode, heap, number);
}
return sManager;
}
void JUTXfb::destroyManager() {
JUT_CONFIRM_MESSAGE(sManager);
delete sManager;
sManager = nullptr;
}
void JUTXfb::initiate(u16 w, u16 h, JKRHeap* heap, JUTXfb::EXfbNumber number) {
if (heap == nullptr) {
heap = JKRGetSystemHeap();
}
u32 size = (u16)ALIGN_NEXT((u16)w, 16) * h;
mBuffer[0] = new (heap, 32) u16[size];
mXfbAllocated[0] = true;
if (number >= DoubleBuffer) {
mBuffer[1] = new (heap, 32) u16[size];
mXfbAllocated[1] = true;
} else {
mBuffer[1] = nullptr;
mXfbAllocated[1] = false;
}
if (number >= TripleBuffer) {
mBuffer[2] = new (heap, 32) u16[size];
mXfbAllocated[2] = true;
} else {
mBuffer[2] = nullptr;
mXfbAllocated[2] = false;
}
}
u32 JUTXfb::accumeXfbSize() {
JUTVideo* video = JUTVideo::getManager();
u16 height = video->getXfbHeight();
u16 width = video->getFbWidth();
return (u16)ALIGN_NEXT(width, 16) * height * 2;
}
+1 -1
View File
@@ -6,7 +6,7 @@
#include "dolphin/hw_regs.h"
// #include "va_args.h"
OSErrorHandler __OSErrorTable[16];
OSErrorHandler __OSErrorTable[OS_ERROR_MAX];
extern volatile __OSInterrupt __OSLastInterrupt;
extern volatile u32 __OSLastInterruptSrr0;
-2
View File
@@ -3,8 +3,6 @@
#include "dolphin/os/OSInterrupt.h"
#include "dolphin/hw_regs.h"
extern OSErrorHandler __OSErrorTable[16];
u32 OSGetConsoleSimulatedMemSize(void){
return(SIM_MEM);
}