mirror of
https://github.com/ACreTeam/ac-decomp
synced 2026-07-09 12:37:22 -04:00
Merge pull request #502 from SwareJonge/JSystem
Implement all of JSystem
This commit is contained in:
@@ -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);
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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() {
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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--;
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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, §ion_id, §ion_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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
#include "dolphin/os/OSInterrupt.h"
|
||||
#include "dolphin/hw_regs.h"
|
||||
|
||||
extern OSErrorHandler __OSErrorTable[16];
|
||||
|
||||
u32 OSGetConsoleSimulatedMemSize(void){
|
||||
return(SIM_MEM);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user