#include "common.h" #include "d/d_sys.h" #include "f/f_base.h" #include "f/f_profile.h" #include "f/f_profile_name.h" #include "m/m_color.h" #include "m/m_video.h" #include "rvl/OS/OSError.h" #include "nw4r/ut/ut_LockedCache.h" #include "m/m_heap.h" #include "m/m3d/m3d.h" #include "m/m_dvd.h" #include "d/d_heap.h" #include "THPPlayer/THPPlayer.h" #include "d/d_thp_player.h" #include "d/d_gfx.h" SPECIAL_BASE_PROFILE(THPPLAYER, dThpPlayer_c, fProfile::THPPLAYER, 0x3, 0x400); int dThpPlayer_c::create() { reallyCreate(mVideo::m_video->pRenderMode->fbWidth, mVideo::m_video->pRenderMode->efbHeight); return SUCCEEDED; } int dThpPlayer_c::doDelete() { if (destroy() == 0) { return NOT_READY; } else { THPPlayerQuit(); return SUCCEEDED; } } int dThpPlayer_c::execute() { reallyExecute(); return SUCCEEDED; } int dThpPlayer_c::draw() { dSys_c::setClearColor(mColor(0xFF)); mScreen.addToDrawList(); return SUCCEEDED; } dThpPlayer_c::dThpPlayer_c(): mDvdCallback(), mFilename(), mLoadAllAtOnce(0), mFilenameSet(0), mSetupDone(0), isPlaying(0), mBuffer(nullptr), mScreen(), mSpecialType(3) {} dThpPlayer_c::~dThpPlayer_c() { if (mBuffer != nullptr) { dHeap::work2Heap.heap->free(mBuffer); mBuffer = nullptr; } } void dThpPlayer_c::reallyCreate(u16 efbWidth, u16 efbHeight) { THPPlayerInit(1); isPlaying = 0; mBuffer = nullptr; mScreen.setEfbWidth(efbWidth); mScreen.setEfbHeight(efbHeight); m3d::resetMaterial(); } extern "C" { s32 THPVideoDecode(s32 p1, s32 p2, s32 p3, s32 p4, s32 p5); } void drawTHPFrame(u32 p1, u32 p2, u32 p3, u32 p4, u32 p5, u32 p6) { THPPlayerDrawCurrentFrame(p1, p2, p3, p4, p5, p6); THPPlayerPostDrawDone(); } static s32 callback(void* player) { ((dThpPlayer_c*) player)->open(); return 1; } void dThpPlayer_c::open() { if (!THPPlayerOpen(mFilename.mChars, mLoadAllAtOnce)) { mFilenameSet = 0; } } void dThpPlayer_c::setupFile(char* filename, s32 loadAllAtOnce) { if (destroy()) { mFilenameSet = 1; mFilename = filename; mLoadAllAtOnce = loadAllAtOnce; mDvdCallback = mDvd_callback_c::createOrDie((dvdReadCallback)callback, this); } } static const u8 SPECIAL_TYPES[] = {0x7A, 0x78, 0x78}; void dThpPlayer_c::reallyExecute() { if (mDvdCallback == nullptr || mDvdCallback->mStatus == 0 || !mFilenameSet || mSetupDone) { return; } if (mFilename == "THP/Demo01_01.thp") { mSpecialType = 0; } else if (mFilename == "THP/Demo01_02.thp") { mSpecialType = 1; } else if (mFilename == "THP/Demo78_01.thp") { mSpecialType = 2; } if (mSpecialType != 3) { THPPlayerSetVolume(SPECIAL_TYPES[mSpecialType], 0); } THPPlayerGetVideoInfo(&mVideoComponent); THPPlayerGetAudioInfo(&mAudioComponent); mScreen.setVideoDimensions( mVideoComponent.xSize, (mVideoComponent.ySize * (dGfx_c::getEFBHeightF() / dGfx_c::getCurrentScreenHeightF())) ); mBuffer = (u8*)dHeap::work2Heap.heap->alloc(THPPlayerCalcNeedMemory(), 0x20); if (mBuffer == nullptr) { #line 279 OSError("Can\'t allocate memory."); } else { THPPlayerSetBuffer(mBuffer); if (THPPlayerPrepare(0, 0, 0) == 0) { #line 288 OSError("Fail to prepare."); } else { mSetupDone = 1; } } } s32 dThpPlayer_c::play() { if (!mFilenameSet) { return true; } else if (!mSetupDone) { return false; } else { THPPlayerPlay(); isPlaying = 1; return true; } } s32 dThpPlayer_c::destroy() { if (mDvdCallback != nullptr) { if (mDvdCallback->mStatus == 0) { return NOT_READY; } THPPlayerStop(); THPPlayerClose(); if (mBuffer != nullptr) { dHeap::work2Heap.heap->free(mBuffer); mBuffer = nullptr; } mDvdCallback->do_delete(); mDvdCallback = nullptr; mFilenameSet = 0; mSetupDone = 0; isPlaying = 0; } return SUCCEEDED; } s32 dThpPlayer_c::isDone() { return THPPlayerGetState() == 3; } void ThpVideoScreen::draw() { drawTHPFrame(mEfbWidth, mEfbHeight, (mEfbWidth - mVideoWidth) / 2, (mEfbHeight - mVideoHeight) / 2, mVideoWidth, mVideoHeight); } // THPPlayer calls this instead of directly calling THPVideoDecode. extern "C" s32 THPVideoDecodeLC(s32 p1, s32 p2, s32 p3, s32 p4, s32 p5) { nw4r::ut::LC::Lock(); s32 result = THPVideoDecode(p1, p2, p3, p4, p5); nw4r::ut::LC::Unlock(); return result; }