CMoviePlayer initial implementation

This commit is contained in:
Jack Andersen 2016-03-06 17:12:32 -10:00
parent 9cfe73d278
commit 6e160560fa
30 changed files with 1706 additions and 208 deletions

View File

@ -41,11 +41,12 @@ target_link_libraries(urde
RuntimeCommonInput
RuntimeCommonParticle
RuntimeCommonGraphics
RuntimeCommonAudio
RuntimeCommon
DNAMP3 DNAMP2 DNAMP1
DNACommon specter specter-fonts freetype ${DATA_SPEC_LIBS}
hecl-database hecl-backend hecl-frontend hecl-blender hecl-runtime hecl-common athena-core nod
logvisor athena-libyaml boo ${PNG_LIB} squish xxhash zeus
logvisor athena-libyaml boo ${PNG_LIB} libjpeg-turbo squish xxhash zeus
${ZLIB_LIBRARIES} ${LZO_LIB}
${BOO_SYS_LIBS})

View File

@ -47,9 +47,13 @@ bool ProjectManager::newProject(const hecl::SystemString& path)
return false;
}
m_vm.ProjectChanged(*m_proj);
m_vm.SetupEditorView();
saveProject();
m_vm.m_mainWindow->setTitle(m_proj->getProjectRootPath().getLastComponent());
hecl::SystemString windowTitle(m_proj->getProjectRootPath().getLastComponent());
windowTitle += _S(" - URDE");
m_vm.m_mainWindow->setTitle(windowTitle.c_str());
m_vm.DismissSplash();
m_vm.FadeInEditors();
@ -96,11 +100,17 @@ bool ProjectManager::openProject(const hecl::SystemString& path)
}
fclose(fp);
m_vm.ProjectChanged(*m_proj);
m_vm.SetupEditorView(r);
IndexMP1Resources();
m_vm.BuildTestPART(m_objStore);
m_vm.m_mainWindow->setTitle(m_proj->getProjectRootPath().getLastComponent());
{
hecl::SystemString windowTitle(m_proj->getProjectRootPath().getLastComponent());
windowTitle += _S(" - URDE");
m_vm.m_mainWindow->setTitle(windowTitle.c_str());
}
m_vm.DismissSplash();
m_vm.FadeInEditors();
@ -109,12 +119,15 @@ bool ProjectManager::openProject(const hecl::SystemString& path)
return true;
makeDefault:
m_vm.ProjectChanged(*m_proj);
m_vm.SetupEditorView();
saveProject();
hecl::SystemString windowTitle(m_proj->getProjectRootPath().getLastComponent());
windowTitle += _S(" - URDE");
m_vm.m_mainWindow->setTitle(windowTitle.c_str());
{
hecl::SystemString windowTitle(m_proj->getProjectRootPath().getLastComponent());
windowTitle += _S(" - URDE");
m_vm.m_mainWindow->setTitle(windowTitle.c_str());
}
m_vm.DismissSplash();
m_vm.FadeInEditors();
return true;

View File

@ -21,13 +21,17 @@ namespace urde
void ViewManager::BuildTestPART(urde::IObjectStore& objStore)
{
//m_partGenDesc = objStore.GetObj({hecl::FOURCC('PART'), 0x972A5CD2});
/*
m_partGenDesc = objStore.GetObj("BusterSparks");
m_partGen.reset(new urde::CElementGen(m_partGenDesc,
urde::CElementGen::EModelOrientationType::Normal,
urde::CElementGen::EOptionalSystemFlags::None));
m_partGen->SetGlobalScale({5.f, 5.f, 5.f});
m_particleView.reset(new ParticleView(*this, m_viewResources, *m_rootView));
m_lineRenderer.reset(new urde::CLineRenderer(urde::CLineRenderer::EPrimitiveMode::LineStrip, 4, nullptr, true));
*/
m_particleView.reset(new ParticleView(*this, m_viewResources, *m_rootView));
hecl::ProjectPath thpPath(m_projManager.project()->getProjectWorkingPath(), _S("out/MP1/Video/creditBG.thp"));
m_moviePlayer.reset(new CMoviePlayer(thpPath.getAbsolutePathUTF8().c_str(), 0.f, true, true));
//m_rootView->accessContentViews().clear();
m_rootView->accessContentViews().push_back(m_particleView.get());
@ -98,6 +102,12 @@ void ViewManager::RootSpaceViewBuilt(specter::View *view)
m_rootView->updateSize();
}
void ViewManager::ProjectChanged(hecl::Database::Project& proj)
{
CDvdFile::Shutdown();
CDvdFile::Initialize(hecl::ProjectPath(proj.getProjectWorkingPath(), _S("out/MP1")));
}
void ViewManager::SetupEditorView()
{
m_rootSpace.reset(new RootSpace(*this));
@ -224,9 +234,10 @@ void ViewManager::init(boo::IApplication* app)
m_mainWindow->setWaitCursor(false);
urde::CGraphics::InitializeBoo(gf, m_mainWindow->getCommandQueue(), root->renderTex());
urde::CElementGen::Initialize();
urde::CLineRenderer::Initialize();
CGraphics::InitializeBoo(gf, m_mainWindow->getCommandQueue(), root->renderTex());
CElementGen::Initialize();
CMoviePlayer::Initialize();
CLineRenderer::Initialize();
}
bool ViewManager::proc()
@ -277,8 +288,9 @@ bool ViewManager::proc()
void ViewManager::stop()
{
urde::CElementGen::Shutdown();
urde::CLineRenderer::Shutdown();
CElementGen::Shutdown();
CMoviePlayer::Shutdown();
CLineRenderer::Shutdown();
m_iconsToken.doDestroy();
m_viewResources.destroyResData();
m_fontCache.destroyAtlases();

View File

@ -7,6 +7,7 @@
#include "Runtime/Particle/CElementGen.hpp"
#include "Runtime/Graphics/CLineRenderer.hpp"
#include "Runtime/Graphics/CMoviePlayer.hpp"
namespace urde
{
@ -47,6 +48,7 @@ class ViewManager : public specter::IViewManager
urde::TLockedToken<urde::CGenDescription> m_partGenDesc;
std::unique_ptr<urde::CElementGen> m_partGen;
std::unique_ptr<urde::CLineRenderer> m_lineRenderer;
std::unique_ptr<urde::CMoviePlayer> m_moviePlayer;
hecl::SystemString m_recentProjectsPath;
std::vector<hecl::SystemString> m_recentProjects;
@ -60,6 +62,7 @@ class ViewManager : public specter::IViewManager
specter::RootView* SetupRootView();
SplashScreen* SetupSplashView();
void RootSpaceViewBuilt(specter::View* view);
void ProjectChanged(hecl::Database::Project& proj);
void SetupEditorView();
void SetupEditorView(ConfigReader& r);
void SaveEditorView(ConfigWriter& w);

View File

@ -1,6 +1,6 @@
The MIT License
Copyright (c) 2015 PathShagged Contributors
Copyright (c) 2015-2016 URDE Contributors
Original Authors: Jack Andersen and Phillip "Antidote" Stephens
Permission is hereby granted, free of charge, to any person obtaining a copy

View File

@ -2,4 +2,6 @@ add_library(RuntimeCommonAudio
CAudioSys.hpp CAudioSys.cpp
CAudioStateWin.hpp CAudioStateWin.cpp
CSfxManager.hpp CSfxManager.cpp
CSfxHandle.hpp CSfxHandle.cpp)
CSfxHandle.hpp CSfxHandle.cpp
dsp.c dsp.h
g721.c g721.h)

92
Runtime/Audio/dsp.c Normal file
View File

@ -0,0 +1,92 @@
#include "dsp.h"
static const int NibbleToInt[16] = {0,1,2,3,4,5,6,7,-8,-7,-6,-5,-4,-3,-2,-1};
static inline short SampClamp(int val)
{
if (val < -32768) val = -32768;
if (val > 32767) val = 32767;
return val;
}
void DSPDecompressFrame(int16_t* out, const uint8_t* in,
const int16_t coefs[8][2], int16_t* prev1, int16_t* prev2,
unsigned lastSample)
{
uint8_t cIdx = (in[0]>>4) & 0xf;
int16_t factor1 = coefs[cIdx][0];
int16_t factor2 = coefs[cIdx][1];
uint8_t exp = in[0] & 0xf;
for (int s=0 ; s<14 && s<lastSample ; ++s)
{
int sampleData = (s&1)?
NibbleToInt[(in[s/2+1])&0xf]:
NibbleToInt[(in[s/2+1]>>4)&0xf];
sampleData <<= exp;
sampleData <<= 11;
sampleData += 1024;
sampleData +=
factor1 * *prev1 +
factor2 * *prev2;
sampleData >>= 11;
sampleData = SampClamp(sampleData);
out[s] = sampleData;
*prev2 = *prev1;
*prev1 = sampleData;
}
}
void DSPDecompressFrameStereoStride(int16_t* out, const uint8_t* in,
const int16_t coefs[8][2], int16_t* prev1, int16_t* prev2,
unsigned lastSample)
{
uint8_t cIdx = (in[0]>>4) & 0xf;
int16_t factor1 = coefs[cIdx][0];
int16_t factor2 = coefs[cIdx][1];
uint8_t exp = in[0] & 0xf;
for (int s=0 ; s<14 && s<lastSample ; ++s)
{
int sampleData = (s&1)?
NibbleToInt[(in[s/2+1])&0xf]:
NibbleToInt[(in[s/2+1]>>4)&0xf];
sampleData <<= exp;
sampleData <<= 11;
sampleData += 1024;
sampleData +=
factor1 * *prev1 +
factor2 * *prev2;
sampleData >>= 11;
sampleData = SampClamp(sampleData);
out[s*2] = sampleData;
*prev2 = *prev1;
*prev1 = sampleData;
}
}
void DSPDecompressFrameStereoDupe(int16_t* out, const uint8_t* in,
const int16_t coefs[8][2], int16_t* prev1, int16_t* prev2,
unsigned lastSample)
{
uint8_t cIdx = (in[0]>>4) & 0xf;
int16_t factor1 = coefs[cIdx][0];
int16_t factor2 = coefs[cIdx][1];
uint8_t exp = in[0] & 0xf;
for (int s=0 ; s<14 && s<lastSample ; ++s)
{
int sampleData = (s&1)?
NibbleToInt[(in[s/2+1])&0xf]:
NibbleToInt[(in[s/2+1]>>4)&0xf];
sampleData <<= exp;
sampleData <<= 11;
sampleData += 1024;
sampleData +=
factor1 * *prev1 +
factor2 * *prev2;
sampleData >>= 11;
sampleData = SampClamp(sampleData);
out[s*2] = sampleData;
out[s*2+1] = sampleData;
*prev2 = *prev1;
*prev1 = sampleData;
}
}

24
Runtime/Audio/dsp.h Normal file
View File

@ -0,0 +1,24 @@
#ifndef _DSP_h
#define _DSP_h
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
void DSPDecompressFrame(int16_t* out, const uint8_t* in,
const int16_t coefs[8][2], int16_t* prev1, int16_t* prev2,
unsigned lastSample);
void DSPDecompressFrameStereoStride(int16_t* out, const uint8_t* in,
const int16_t coefs[8][2], int16_t* prev1, int16_t* prev2,
unsigned lastSample);
void DSPDecompressFrameStereoDupe(int16_t* out, const uint8_t* in,
const int16_t coefs[8][2], int16_t* prev1, int16_t* prev2,
unsigned lastSample);
#ifdef __cplusplus
}
#endif
#endif // _DSP_h

457
Runtime/Audio/g721.c Normal file
View File

@ -0,0 +1,457 @@
/* G.721 decoder, from Sun's public domain CCITT-ADPCM sources,
* retrieved from ftp://ftp.cwi.nl/pub/audio/ccitt-adpcm.tar.gz
*
* For reference, here's the original license:
*
* This source code is a product of Sun Microsystems, Inc. and is provided
* for unrestricted use. Users may copy or modify this source code without
* charge.
*
* SUN SOURCE CODE IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING
* THE WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
*
* Sun source code is provided with no support and without any obligation on
* the part of Sun Microsystems, Inc. to assist in its use, correction,
* modification or enhancement.
*
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THIS SOFTWARE
* OR ANY PART THEREOF.
*
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
* or profits or other special, indirect and consequential damages, even if
* Sun has been advised of the possibility of such damages.
*
* Sun Microsystems, Inc.
* 2550 Garcia Avenue
* Mountain View, California 94043
*
*/
#include <stdlib.h>
#include "g721.h"
static short power2[15] = {1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80,
0x100, 0x200, 0x400, 0x800, 0x1000, 0x2000, 0x4000};
/*
* quan()
*
* quantizes the input val against the table of size short integers.
* It returns i if table[i - 1] <= val < table[i].
*
* Using linear search for simple coding.
*/
static int
quan(
int val,
short *table,
int size)
{
int i;
for (i = 0; i < size; i++)
if (val < *table++)
break;
return (i);
}
/*
* fmult()
*
* returns the integer product of the 14-bit integer "an" and
* "floating point" representation (4-bit exponent, 6-bit mantessa) "srn".
*/
static int
fmult(
int an,
int srn)
{
short anmag, anexp, anmant;
short wanexp, wanmant;
short retval;
anmag = (an > 0) ? an : ((-an) & 0x1FFF);
anexp = quan(anmag, power2, 15) - 6;
anmant = (anmag == 0) ? 32 :
(anexp >= 0) ? anmag >> anexp : anmag << -anexp;
wanexp = anexp + ((srn >> 6) & 0xF) - 13;
wanmant = (anmant * (srn & 077) + 0x30) >> 4;
retval = (wanexp >= 0) ? ((wanmant << wanexp) & 0x7FFF) :
(wanmant >> -wanexp);
return (((an ^ srn) < 0) ? -retval : retval);
}
/*
* g72x_init_state()
*
* This routine initializes and/or resets the g72x_state structure
* pointed to by 'state_ptr'.
* All the initial state values are specified in the CCITT G.721 document.
*/
void
g72x_init_state(struct g72x_state *state_ptr)
{
int cnta;
state_ptr->yl = 34816;
state_ptr->yu = 544;
state_ptr->dms = 0;
state_ptr->dml = 0;
state_ptr->ap = 0;
for (cnta = 0; cnta < 2; cnta++) {
state_ptr->a[cnta] = 0;
state_ptr->pk[cnta] = 0;
state_ptr->sr[cnta] = 32;
}
for (cnta = 0; cnta < 6; cnta++) {
state_ptr->b[cnta] = 0;
state_ptr->dq[cnta] = 32;
}
state_ptr->td = 0;
}
/*
* predictor_zero()
*
* computes the estimated signal from 6-zero predictor.
*
*/
static int
predictor_zero(
struct g72x_state *state_ptr)
{
int i;
int sezi;
sezi = fmult(state_ptr->b[0] >> 2, state_ptr->dq[0]);
for (i = 1; i < 6; i++) /* ACCUM */
sezi += fmult(state_ptr->b[i] >> 2, state_ptr->dq[i]);
return (sezi);
}
/*
* predictor_pole()
*
* computes the estimated signal from 2-pole predictor.
*
*/
static int
predictor_pole(
struct g72x_state *state_ptr)
{
return (fmult(state_ptr->a[1] >> 2, state_ptr->sr[1]) +
fmult(state_ptr->a[0] >> 2, state_ptr->sr[0]));
}
/*
* step_size()
*
* computes the quantization step size of the adaptive quantizer.
*
*/
static long
step_size(
struct g72x_state *state_ptr)
{
long y;
long dif;
long al;
if (state_ptr->ap >= 256)
return (state_ptr->yu);
else {
y = state_ptr->yl >> 6;
dif = state_ptr->yu - y;
al = state_ptr->ap >> 2;
if (dif > 0)
y += (dif * al) >> 6;
else if (dif < 0)
y += (dif * al + 0x3F) >> 6;
return (y);
}
}
/*
* reconstruct()
*
* Returns reconstructed difference signal 'dq' obtained from
* codeword 'i' and quantization step size scale factor 'y'.
* Multiplication is performed in log base 2 domain as addition.
*/
static int
reconstruct(
int sign, /* 0 for non-negative value */
int dqln, /* G.72x codeword */
int y) /* Step size multiplier */
{
short dql; /* Log of 'dq' magnitude */
short dex; /* Integer part of log */
short dqt;
short dq; /* Reconstructed difference signal sample */
dql = dqln + (y >> 2); /* ADDA */
if (dql < 0) {
return ((sign) ? -0x8000 : 0);
} else { /* ANTILOG */
dex = (dql >> 7) & 15;
dqt = 128 + (dql & 127);
dq = (dqt << 7) >> (14 - dex);
return ((sign) ? (dq - 0x8000) : dq);
}
}
/*
* update()
*
* updates the state variables for each output code
*/
static void
update(
/*int code_size,*/ /* distinguish 723_40 with others */
int y, /* quantizer step size */
int wi, /* scale factor multiplier */
int fi, /* for long/short term energies */
int dq, /* quantized prediction difference */
int sr, /* reconstructed signal */
int dqsez, /* difference from 2-pole predictor */
struct g72x_state *state_ptr) /* coder state pointer */
{
int cnt;
short mag, exp; /* Adaptive predictor, FLOAT A */
short a2p; /* LIMC */
short a1ul; /* UPA1 */
short pks1; /* UPA2 */
short fa1;
char tr; /* tone/transition detector */
short ylint, thr2, dqthr;
short ylfrac, thr1;
short pk0;
pk0 = (dqsez < 0) ? 1 : 0; /* needed in updating predictor poles */
mag = dq & 0x7FFF; /* prediction difference magnitude */
/* TRANS */
ylint = state_ptr->yl >> 15; /* exponent part of yl */
ylfrac = (state_ptr->yl >> 10) & 0x1F; /* fractional part of yl */
thr1 = (32 + ylfrac) << ylint; /* threshold */
thr2 = (ylint > 9) ? 31 << 10 : thr1; /* limit thr2 to 31 << 10 */
dqthr = (thr2 + (thr2 >> 1)) >> 1; /* dqthr = 0.75 * thr2 */
if (state_ptr->td == 0) /* signal supposed voice */
tr = 0;
else if (mag <= dqthr) /* supposed data, but small mag */
tr = 0; /* treated as voice */
else /* signal is data (modem) */
tr = 1;
/*
* Quantizer scale factor adaptation.
*/
/* FUNCTW & FILTD & DELAY */
/* update non-steady state step size multiplier */
state_ptr->yu = y + ((wi - y) >> 5);
/* LIMB */
if (state_ptr->yu < 544) /* 544 <= yu <= 5120 */
state_ptr->yu = 544;
else if (state_ptr->yu > 5120)
state_ptr->yu = 5120;
/* FILTE & DELAY */
/* update steady state step size multiplier */
state_ptr->yl += state_ptr->yu + ((-state_ptr->yl) >> 6);
/*
* Adaptive predictor coefficients.
*/
if (tr == 1) { /* reset a's and b's for modem signal */
state_ptr->a[0] = 0;
state_ptr->a[1] = 0;
state_ptr->b[0] = 0;
state_ptr->b[1] = 0;
state_ptr->b[2] = 0;
state_ptr->b[3] = 0;
state_ptr->b[4] = 0;
state_ptr->b[5] = 0;
a2p=0; /* won't be used, clear warning */
} else { /* update a's and b's */
pks1 = pk0 ^ state_ptr->pk[0]; /* UPA2 */
/* update predictor pole a[1] */
a2p = state_ptr->a[1] - (state_ptr->a[1] >> 7);
if (dqsez != 0) {
fa1 = (pks1) ? state_ptr->a[0] : -state_ptr->a[0];
if (fa1 < -8191) /* a2p = function of fa1 */
a2p -= 0x100;
else if (fa1 > 8191)
a2p += 0xFF;
else
a2p += fa1 >> 5;
if (pk0 ^ state_ptr->pk[1])
/* LIMC */
if (a2p <= -12160)
a2p = -12288;
else if (a2p >= 12416)
a2p = 12288;
else
a2p -= 0x80;
else if (a2p <= -12416)
a2p = -12288;
else if (a2p >= 12160)
a2p = 12288;
else
a2p += 0x80;
}
/* TRIGB & DELAY */
state_ptr->a[1] = a2p;
/* UPA1 */
/* update predictor pole a[0] */
state_ptr->a[0] -= state_ptr->a[0] >> 8;
if (dqsez != 0) {
if (pks1 == 0)
state_ptr->a[0] += 192;
else
state_ptr->a[0] -= 192;
}
/* LIMD */
a1ul = 15360 - a2p;
if (state_ptr->a[0] < -a1ul)
state_ptr->a[0] = -a1ul;
else if (state_ptr->a[0] > a1ul)
state_ptr->a[0] = a1ul;
/* UPB : update predictor zeros b[6] */
for (cnt = 0; cnt < 6; cnt++) {
/*if (code_size == 5)*/ /* for 40Kbps G.723 */
/* state_ptr->b[cnt] -= state_ptr->b[cnt] >> 9;*/
/*else*/ /* for G.721 and 24Kbps G.723 */
state_ptr->b[cnt] -= state_ptr->b[cnt] >> 8;
if (dq & 0x7FFF) { /* XOR */
if ((dq ^ state_ptr->dq[cnt]) >= 0)
state_ptr->b[cnt] += 128;
else
state_ptr->b[cnt] -= 128;
}
}
}
for (cnt = 5; cnt > 0; cnt--)
state_ptr->dq[cnt] = state_ptr->dq[cnt-1];
/* FLOAT A : convert dq[0] to 4-bit exp, 6-bit mantissa f.p. */
if (mag == 0) {
state_ptr->dq[0] = (dq >= 0) ? 0x20 : 0xFC20;
} else {
exp = quan(mag, power2, 15);
state_ptr->dq[0] = (dq >= 0) ?
(exp << 6) + ((mag << 6) >> exp) :
(exp << 6) + ((mag << 6) >> exp) - 0x400;
}
state_ptr->sr[1] = state_ptr->sr[0];
/* FLOAT B : convert sr to 4-bit exp., 6-bit mantissa f.p. */
if (sr == 0) {
state_ptr->sr[0] = 0x20;
} else if (sr > 0) {
exp = quan(sr, power2, 15);
state_ptr->sr[0] = (exp << 6) + ((sr << 6) >> exp);
} else if (sr > -32768) {
mag = -sr;
exp = quan(mag, power2, 15);
state_ptr->sr[0] = (exp << 6) + ((mag << 6) >> exp) - 0x400;
} else
state_ptr->sr[0] = 0xFC20;
/* DELAY A */
state_ptr->pk[1] = state_ptr->pk[0];
state_ptr->pk[0] = pk0;
/* TONE */
if (tr == 1) /* this sample has been treated as data */
state_ptr->td = 0; /* next one will be treated as voice */
else if (a2p < -11776) /* small sample-to-sample correlation */
state_ptr->td = 1; /* signal may be data */
else /* signal is voice */
state_ptr->td = 0;
/*
* Adaptation speed control.
*/
state_ptr->dms += (fi - state_ptr->dms) >> 5; /* FILTA */
state_ptr->dml += (((fi << 2) - state_ptr->dml) >> 7); /* FILTB */
if (tr == 1)
state_ptr->ap = 256;
else if (y < 1536) /* SUBTC */
state_ptr->ap += (0x200 - state_ptr->ap) >> 4;
else if (state_ptr->td == 1)
state_ptr->ap += (0x200 - state_ptr->ap) >> 4;
else if (abs((state_ptr->dms << 2) - state_ptr->dml) >=
(state_ptr->dml >> 3))
state_ptr->ap += (0x200 - state_ptr->ap) >> 4;
else
state_ptr->ap += (-state_ptr->ap) >> 4;
}
/*
* Maps G.721 code word to reconstructed scale factor normalized log
* magnitude values.
*/
static short _dqlntab[16] = {-2048, 4, 135, 213, 273, 323, 373, 425,
425, 373, 323, 273, 213, 135, 4, -2048};
/* Maps G.721 code word to log of scale factor multiplier. */
static short _witab[16] = {-12, 18, 41, 64, 112, 198, 355, 1122,
1122, 355, 198, 112, 64, 41, 18, -12};
/*
* Maps G.721 code words to a set of values whose long and short
* term averages are computed and then compared to give an indication
* how stationary (steady state) the signal is.
*/
static short _fitab[16] = {0, 0, 0, 0x200, 0x200, 0x200, 0x600, 0xE00,
0xE00, 0x600, 0x200, 0x200, 0x200, 0, 0, 0};
/*
* g721_decoder()
*
* Description:
*
* Decodes a 4-bit code of G.721 encoded data of i and
* returns the resulting linear PCM, A-law or u-law value.
* return -1 for unknown out_coding value.
*/
int
g721_decoder(int i,
struct g72x_state *state_ptr)
{
short sezi, sei, sez, se; /* ACCUM */
short y; /* MIX */
short sr; /* ADDB */
short dq;
short dqsez;
i &= 0x0f; /* mask to get proper bits */
sezi = predictor_zero(state_ptr);
sez = sezi >> 1;
sei = sezi + predictor_pole(state_ptr);
se = sei >> 1; /* se = estimated signal */
y = step_size(state_ptr); /* dynamic quantizer step size */
dq = reconstruct(i & 0x08, _dqlntab[i], y); /* quantized diff. */
sr = (dq < 0) ? (se - (dq & 0x3FFF)) : se + dq; /* reconst. signal */
dqsez = sr - se + sez; /* pole prediction diff. */
update(y, _witab[i] << 5, _fitab[i], dq, sr, dqsez, state_ptr);
return (sr << 2); /* sr was 14-bit dynamic range */
}

45
Runtime/Audio/g721.h Normal file
View File

@ -0,0 +1,45 @@
#ifndef _g721_h
#define _g721_h
#ifdef __cplusplus
extern "C" {
#endif
struct g72x_state {
long yl; /* Locked or steady state step size multiplier. */
short yu; /* Unlocked or non-steady state step size multiplier. */
short dms; /* Short term energy estimate. */
short dml; /* Long term energy estimate. */
short ap; /* Linear weighting coefficient of 'yl' and 'yu'. */
short a[2]; /* Coefficients of pole portion of prediction filter. */
short b[6]; /* Coefficients of zero portion of prediction filter. */
short pk[2]; /*
* Signs of previous two samples of a partially
* reconstructed signal.
*/
short dq[6]; /*
* Previous 6 samples of the quantized difference
* signal represented in an internal floating point
* format.
*/
short sr[2]; /*
* Previous 2 samples of the quantized difference
* signal represented in an internal floating point
* format.
*/
char td; /* delayed tone detect, new in 1988 version */
};
void
g72x_init_state(struct g72x_state *state_ptr);
int
g721_decoder(int i,
struct g72x_state *state_ptr);
#ifdef __cplusplus
}
#endif
#endif

118
Runtime/CDvdFile.cpp Normal file
View File

@ -0,0 +1,118 @@
#include "CDvdFile.hpp"
#include "CDvdRequest.hpp"
namespace urde
{
hecl::ProjectPath CDvdFile::m_DvdRoot;
class CFileDvdRequest : public IDvdRequest
{
CDvdFile& m_dvdFile;
void* m_buf;
u32 m_len;
ESeekOrigin m_whence;
int m_offset;
bool m_cancel = false;
bool m_complete = false;
public:
~CFileDvdRequest()
{
PostCancelRequest();
}
void WaitUntilComplete()
{
while (!m_complete && !m_cancel)
{
std::unique_lock<std::mutex> lk(CDvdFile::m_WorkerMutex);
}
}
bool IsComplete() {return m_complete;}
void PostCancelRequest()
{
std::unique_lock<std::mutex> lk(CDvdFile::m_WorkerMutex);
m_cancel = true;
}
EMediaType GetMediaType() const
{
return EMediaType::File;
}
CFileDvdRequest(CDvdFile& file, void* buf, u32 len, ESeekOrigin whence, int off)
: m_dvdFile(file), m_buf(buf), m_len(len), m_whence(whence), m_offset(off) {}
void DoRequest()
{
if (m_cancel)
return;
if (m_whence == ESeekOrigin::Cur && m_offset == 0)
m_dvdFile.m_reader.readBytesToBuf(m_buf, m_len);
else
{
m_dvdFile.m_reader.seek(m_offset, athena::SeekOrigin(m_whence));
m_dvdFile.m_reader.readBytesToBuf(m_buf, m_len);
}
m_complete = true;
}
};
std::thread CDvdFile::m_WorkerThread;
std::mutex CDvdFile::m_WorkerMutex;
std::condition_variable CDvdFile::m_WorkerCV;
bool CDvdFile::m_WorkerRun = false;
std::vector<std::shared_ptr<IDvdRequest>> CDvdFile::m_RequestQueue;
void CDvdFile::WorkerProc()
{
while (m_WorkerRun)
{
std::unique_lock<std::mutex> lk(CDvdFile::m_WorkerMutex);
if (CDvdFile::m_RequestQueue.size())
{
std::vector<std::shared_ptr<IDvdRequest>> swapQueue;
swapQueue.swap(CDvdFile::m_RequestQueue);
lk.unlock();
for (std::shared_ptr<IDvdRequest>& req : swapQueue)
{
CFileDvdRequest& concreteReq = static_cast<CFileDvdRequest&>(*req);
concreteReq.DoRequest();
}
lk.lock();
}
m_WorkerCV.wait(lk);
}
}
std::shared_ptr<IDvdRequest> CDvdFile::AsyncSeekRead(void* buf, u32 len, ESeekOrigin whence, int off)
{
CFileDvdRequest* req = new CFileDvdRequest(*this, buf, len, whence, off);
std::shared_ptr<IDvdRequest> ret(req);
std::unique_lock<std::mutex> lk(CDvdFile::m_WorkerMutex);
m_RequestQueue.emplace_back(ret);
lk.unlock();
m_WorkerCV.notify_one();
return ret;
}
void CDvdFile::Initialize(const hecl::ProjectPath& path)
{
m_DvdRoot = path;
if (m_WorkerRun)
return;
m_WorkerRun = true;
m_WorkerThread = std::thread(WorkerProc);
}
void CDvdFile::Shutdown()
{
if (!m_WorkerRun)
return;
m_WorkerRun = false;
m_WorkerCV.notify_one();
if (m_WorkerThread.joinable())
m_WorkerThread.join();
m_RequestQueue.clear();
}
}

View File

@ -3,6 +3,10 @@
#include "RetroTypes.hpp"
#include <thread>
#include <mutex>
#include <condition_variable>
namespace urde
{
@ -24,18 +28,51 @@ class IDvdRequest;
class CDvdFile
{
friend class CResLoader;
std::string x18_name;
friend class CFileDvdRequest;
static hecl::ProjectPath m_DvdRoot;
static std::thread m_WorkerThread;
static std::mutex m_WorkerMutex;
static std::condition_variable m_WorkerCV;
static bool m_WorkerRun;
static std::vector<std::shared_ptr<IDvdRequest>> m_RequestQueue;
static void WorkerProc();
std::string x18_path;
athena::io::FileReader m_reader;
public:
CDvdFile(const char*) {}
void UpdateFilePos(int) {}
void CalcFileOffset(int, ESeekOrigin) {}
static void Initialize(const hecl::ProjectPath& path);
static void Shutdown();
CDvdFile(const char* path)
: x18_path(path), m_reader(hecl::ProjectPath(m_DvdRoot, path).getAbsolutePath()) {}
void UpdateFilePos(int pos)
{
m_reader.seek(pos, athena::SeekOrigin::Begin);
}
static void internalCallback(s32, DVDFileInfo*) {}
static bool FileExists(const char*) {return false;}
void CloseFile() {}
IDvdRequest* AsyncSeekRead(void*, u32, ESeekOrigin, int) {return nullptr;}
void SyncSeekRead(void*, u32, ESeekOrigin, int) {}
IDvdRequest* AsyncRead(void*, u32) {return nullptr;}
void SyncRead(void*, u32) {}
static bool FileExists(const char* path)
{
return hecl::ProjectPath(m_DvdRoot, path).getPathType() != hecl::ProjectPath::Type::File;
}
void CloseFile()
{
m_reader.close();
}
std::shared_ptr<IDvdRequest> AsyncSeekRead(void* buf, u32 len, ESeekOrigin whence, int off);
void SyncSeekRead(void* buf, u32 len, ESeekOrigin whence, int offset)
{
m_reader.seek(offset, athena::SeekOrigin(whence));
m_reader.readBytesToBuf(buf, len);
}
std::shared_ptr<IDvdRequest> AsyncRead(void* buf, u32 len)
{
return AsyncSeekRead(buf, len, ESeekOrigin::Cur, 0);
}
void SyncRead(void* buf, u32 len)
{
m_reader.readBytesToBuf(buf, len);
}
void StallForARAMFile() {}
void StartARAMFileLoad() {}
void PopARAMFileLoad() {}

View File

@ -1,17 +0,0 @@
#include "CDvdRequest.hpp"
namespace urde
{
void CDvdRequest::WaitUntilComplete()
{
}
bool CDvdRequest::IsComplete()
{
return false;
}
void CDvdRequest::PostCancelRequest()
{
}
}

View File

@ -7,6 +7,8 @@ namespace urde
class IDvdRequest
{
public:
virtual ~IDvdRequest() = default;
virtual void WaitUntilComplete()=0;
virtual bool IsComplete()=0;
virtual void PostCancelRequest()=0;
@ -15,28 +17,12 @@ public:
{
ARAM = 0,
Real = 1,
NOD = 2
File = 2,
NOD = 3
};
virtual EMediaType GetMediaType() const=0;
};
class CNODDvdRequest : public IDvdRequest
{
public:
void WaitUntilComplete();
bool IsComplete();
void PostCancelRequest();
EMediaType GetMediaType() const {return EMediaType::NOD;}
};
class CDvdRequest : public IDvdRequest
{
void WaitUntilComplete();
bool IsComplete();
void PostCancelRequest();
EMediaType GetMediaType() const { return EMediaType::Real; }
};
}
#endif // __PSHAG_CDVDREQUEST_HPP__

View File

@ -32,8 +32,8 @@ add_library(RuntimeCommon
CRandom16.hpp CRandom16.cpp
CResFactory.hpp CResFactory.cpp
CResLoader.hpp CResLoader.cpp
CDvdRequest.hpp CNODDvdRequest.cpp
CDvdFile.hpp CNODDvdFile.cpp
CDvdRequest.hpp
CDvdFile.hpp CDvdFile.cpp
CVirtualDvdFile.hpp CVirtualDvdFile.cpp
IObjectStore.hpp
CSimplePool.hpp CSimplePool.cpp
@ -63,7 +63,6 @@ add_library(RuntimeCommon
CMFGameBase.hpp
CInGameTweakManagerBase.hpp
CPlayMovieBase.hpp
CMoviePlayer.hpp CMoviePlayer.cpp
CGameDebug.hpp CGameDebug.cpp
rstl.hpp rstl.cpp
GameGlobalObjects.hpp

View File

@ -1,75 +0,0 @@
#include "CMoviePlayer.hpp"
namespace urde
{
CMoviePlayer::CMoviePlayer(const char* path, float startTime, bool flag)
: CDvdFile(path)
{
}
void CMoviePlayer::VerifyCallbackStatus()
{
}
void CMoviePlayer::DisableStaticAudio()
{
}
void CMoviePlayer::SetStaticAudioVolume(int vol)
{
}
void CMoviePlayer::SetStaticAudio(const void* data, u32 length, u32 loopStart, u32 loopEnd)
{
}
void CMoviePlayer::MixAudio(short* out, const short* in, u32 length)
{
}
void CMoviePlayer::MixStaticAudio(short* out, const short* in, u32 length)
{
}
void CMoviePlayer::StaticMyAudioCallback()
{
}
void CMoviePlayer::Rewind()
{
}
bool CMoviePlayer::GetIsMovieFinishedPlaying() const
{
return false;
}
bool CMoviePlayer::GetIsFullyCached() const
{
return false;
}
float CMoviePlayer::GetPlayedSeconds() const
{
return 0.0;
}
float CMoviePlayer::GetTotalSeconds() const
{
return 0.0;
}
void CMoviePlayer::SetPlayMode(EPlayMode mode)
{
}
void CMoviePlayer::DrawFrame(const CVector3f& a, const CVector3f& b,
const CVector3f& c, const CVector3f& d)
{
}
void CMoviePlayer::Update(float dt)
{
}
void CMoviePlayer::DecodeFromRead(const void* data)
{
}
void CMoviePlayer::ReadCompleted()
{
}
void CMoviePlayer::PostDVDReadRequestIfNeeded()
{
}
void CMoviePlayer::InitializeTextures()
{
}
}

View File

@ -1,44 +0,0 @@
#ifndef __PSHAG_CMOVIEPLAYER_HPP__
#define __PSHAG_CMOVIEPLAYER_HPP__
#include "RetroTypes.hpp"
#include "CDvdFile.hpp"
namespace urde
{
class CVector3f;
class CMoviePlayer : public CDvdFile
{
public:
enum class EPlayMode
{
};
CMoviePlayer(const char* path, float startTime, bool flag);
static void VerifyCallbackStatus();
static void DisableStaticAudio();
static void SetStaticAudioVolume(int vol);
static void SetStaticAudio(const void* data, u32 length, u32 loopStart, u32 loopEnd);
void MixAudio(short* out, const short* in, u32 length);
static void MixStaticAudio(short* out, const short* in, u32 length);
static void StaticMyAudioCallback();
void Rewind();
bool GetIsMovieFinishedPlaying() const;
bool GetIsFullyCached() const;
float GetPlayedSeconds() const;
float GetTotalSeconds() const;
void SetPlayMode(EPlayMode);
void DrawFrame(const CVector3f& a, const CVector3f& b, const CVector3f& c, const CVector3f& d);
void Update(float dt);
void DecodeFromRead(const void* data);
void ReadCompleted();
void PostDVDReadRequestIfNeeded();
void InitializeTextures();
};
}
#endif // __PSHAG_CMOVIEPLAYER_HPP__

View File

@ -1,17 +0,0 @@
#include "CDvdRequest.hpp"
namespace urde
{
void CNODDvdRequest::WaitUntilComplete()
{
}
bool CNODDvdRequest::IsComplete()
{
return false;
}
void CNODDvdRequest::PostCancelRequest()
{
}
}

View File

@ -2,7 +2,7 @@
#define __PSHAG_CPLAYMOVIEBASE_HPP__
#include "CIOWin.hpp"
#include "CMoviePlayer.hpp"
#include "Graphics/CMoviePlayer.hpp"
namespace urde
{
@ -12,7 +12,7 @@ class CPlayMovieBase : public CIOWin
CMoviePlayer x18_moviePlayer;
public:
CPlayMovieBase(const char* iowName, const char* path)
: CIOWin(iowName), x18_moviePlayer(path, 0.0, false) {}
: CIOWin(iowName), x18_moviePlayer(path, 0.0, false, false) {}
EMessageReturn OnMessage(const CArchitectureMessage&, CArchitectureQueue&) {return EMessageReturn::Normal;}
void Draw() const {}
};

View File

@ -10,7 +10,7 @@ const std::vector<u32>* CResLoader::GetTagListForFile(const std::string& name) c
{
std::string namePak = name + ".pak";
for (const std::unique_ptr<CPakFile>& pak : x1c_pakLoadedList)
if (!CStringExtras::CompareCaseInsensitive(namePak, pak->x18_name))
if (!CStringExtras::CompareCaseInsensitive(namePak, pak->x18_path))
return &pak->GetDepList();
return nullptr;
}
@ -100,13 +100,13 @@ CInputStream* CResLoader::LoadNewResourceSync(const SObjectTag& tag, void* extBu
return newStrm;
}
IDvdRequest* CResLoader::LoadResourcePartAsync(const SObjectTag& tag, int offset, int length, void* buf)
std::shared_ptr<IDvdRequest> CResLoader::LoadResourcePartAsync(const SObjectTag& tag, int offset, int length, void* buf)
{
return FindResourceForLoad(tag.id)->AsyncSeekRead(buf, length,
ESeekOrigin::Begin, x50_cachedResInfo->x4_offset + offset);
}
IDvdRequest* CResLoader::LoadResourceAsync(const SObjectTag& tag, void* buf)
std::shared_ptr<IDvdRequest> CResLoader::LoadResourceAsync(const SObjectTag& tag, void* buf)
{
return FindResourceForLoad(tag.id)->AsyncSeekRead(buf, ROUND_UP_32(x50_cachedResInfo->x8_size),
ESeekOrigin::Begin, x50_cachedResInfo->x4_offset);

View File

@ -29,8 +29,8 @@ public:
void LoadMemResourceSync(const SObjectTag& tag, void** bufOut, int* sizeOut);
CInputStream* LoadResourceFromMemorySync(const SObjectTag& tag, const void* buf);
CInputStream* LoadNewResourceSync(const SObjectTag& tag, void* extBuf=nullptr);
IDvdRequest* LoadResourcePartAsync(const SObjectTag& tag, int offset, int length, void* buf);
IDvdRequest* LoadResourceAsync(const SObjectTag& tag, void* buf);
std::shared_ptr<IDvdRequest> LoadResourcePartAsync(const SObjectTag& tag, int offset, int length, void* buf);
std::shared_ptr<IDvdRequest> LoadResourceAsync(const SObjectTag& tag, void* buf);
bool GetResourceCompression(const SObjectTag& tag);
u32 ResourceSize(const SObjectTag& tag);
bool ResourceExists(const SObjectTag& tag);

View File

@ -10,6 +10,10 @@ namespace urde
CGraphics::CProjectionState CGraphics::g_Proj;
float CGraphics::g_ProjAspect = 1.f;
u32 CGraphics::g_NumLightsActive = 0;
u32 CGraphics::g_NumBreakpointsWaiting = 0;
u32 CGraphics::g_FlippingState;
bool CGraphics::g_LastFrameUsedAbove = false;
bool CGraphics::g_InterruptLastFrameUsedAbove = false;
ERglLight CGraphics::g_LightActive = ERglLight::None;
ERglLight CGraphics::g_LightsWereOn = ERglLight::None;
zeus::CTransform CGraphics::g_GXModelView;
@ -61,6 +65,15 @@ void CGraphics::SetCullMode(ERglCullMode)
{
}
void CGraphics::EndScene()
{
/* Spinwait until g_NumBreakpointsWaiting is 0 */
/* ++g_NumBreakpointsWaiting; */
/* GXCopyDisp to g_CurrenFrameBuf with clear enabled */
/* Register next breakpoint with GP FIFO */
/* g_LastFrameUsedAbove = g_InterruptLastFrameUsedAbove; */
}
void CGraphics::SetAlphaCompare(ERglAlphaFunc comp0, u8 ref0, ERglAlphaOp op, ERglAlphaFunc comp1, u8 ref1)
{
}

View File

@ -150,6 +150,10 @@ public:
static CProjectionState g_Proj;
static float g_ProjAspect;
static u32 g_NumLightsActive;
static u32 g_NumBreakpointsWaiting;
static u32 g_FlippingState;
static bool g_LastFrameUsedAbove;
static bool g_InterruptLastFrameUsedAbove;
static ERglLight g_LightActive;
static ERglLight g_LightsWereOn;
static zeus::CTransform g_GXModelView;
@ -169,6 +173,7 @@ public:
static void SetDepthWriteMode(bool test, ERglEnum comp, bool write);
static void SetBlendMode(ERglBlendMode, ERglBlendFactor, ERglBlendFactor, ERglLogicOp);
static void SetCullMode(ERglCullMode);
static void EndScene();
static void SetAlphaCompare(ERglAlphaFunc