Assorted cleanup, perf counter logging, and minor fixes that have been accumulating on my hdd :p
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@3663 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
parent
7ec0a3a5e8
commit
90a2096a24
|
@ -299,10 +299,14 @@ bool CBoot::BootUp()
|
||||||
}
|
}
|
||||||
|
|
||||||
// load image or create virtual drive from directory
|
// load image or create virtual drive from directory
|
||||||
if (!_StartupPara.m_strDVDRoot.empty())
|
if (!_StartupPara.m_strDVDRoot.empty()) {
|
||||||
|
NOTICE_LOG(BOOT, "Setting DVDroot %s", _StartupPara.m_strDefaultGCM.c_str());
|
||||||
VolumeHandler::SetVolumeDirectory(_StartupPara.m_strDVDRoot, elfWii);
|
VolumeHandler::SetVolumeDirectory(_StartupPara.m_strDVDRoot, elfWii);
|
||||||
else if (!_StartupPara.m_strDefaultGCM.empty())
|
}
|
||||||
|
else if (!_StartupPara.m_strDefaultGCM.empty()) {
|
||||||
|
NOTICE_LOG(BOOT, "Loading default ISO %s", _StartupPara.m_strDefaultGCM.c_str());
|
||||||
VolumeHandler::SetVolumeName(_StartupPara.m_strDefaultGCM);
|
VolumeHandler::SetVolumeName(_StartupPara.m_strDefaultGCM);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
VolumeHandler::SetVolumeDirectory(_StartupPara.m_strFilename, elfWii);
|
VolumeHandler::SetVolumeDirectory(_StartupPara.m_strFilename, elfWii);
|
||||||
|
|
||||||
|
@ -313,6 +317,9 @@ bool CBoot::BootUp()
|
||||||
Boot_ELF(_StartupPara.m_strFilename.c_str());
|
Boot_ELF(_StartupPara.m_strFilename.c_str());
|
||||||
UpdateDebugger_MapLoaded();
|
UpdateDebugger_MapLoaded();
|
||||||
Debugger::AddAutoBreakpoints();
|
Debugger::AddAutoBreakpoints();
|
||||||
|
|
||||||
|
|
||||||
|
HLE::PatchFunctions();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
|
@ -342,10 +342,7 @@ THREAD_RETURN CpuThread(void *pArg)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Initalize plugins and create emulation thread
|
// Initalize plugins and create emulation thread
|
||||||
|
|
||||||
// Call browser: Init():g_EmuThread(). See the BootManager.cpp file description for a complete call schedule.
|
// Call browser: Init():g_EmuThread(). See the BootManager.cpp file description for a complete call schedule.
|
||||||
THREAD_RETURN EmuThread(void *pArg)
|
THREAD_RETURN EmuThread(void *pArg)
|
||||||
{
|
{
|
||||||
|
@ -387,7 +384,6 @@ THREAD_RETURN EmuThread(void *pArg)
|
||||||
VideoInitialize.pBBox = &PixelEngine::bbox[0];
|
VideoInitialize.pBBox = &PixelEngine::bbox[0];
|
||||||
VideoInitialize.pBBoxActive = &PixelEngine::bbox_active;
|
VideoInitialize.pBBoxActive = &PixelEngine::bbox_active;
|
||||||
|
|
||||||
|
|
||||||
// May be needed for Stop and Start
|
// May be needed for Stop and Start
|
||||||
#ifdef SETUP_FREE_VIDEO_PLUGIN_ON_BOOT
|
#ifdef SETUP_FREE_VIDEO_PLUGIN_ON_BOOT
|
||||||
Plugins.FreeVideo();
|
Plugins.FreeVideo();
|
||||||
|
@ -414,6 +410,7 @@ THREAD_RETURN EmuThread(void *pArg)
|
||||||
dspInit.pEmulatorState = (int *)PowerPC::GetStatePtr();
|
dspInit.pEmulatorState = (int *)PowerPC::GetStatePtr();
|
||||||
dspInit.bWii = _CoreParameter.bWii;
|
dspInit.bWii = _CoreParameter.bWii;
|
||||||
dspInit.bOnThread = _CoreParameter.bDSPThread;
|
dspInit.bOnThread = _CoreParameter.bDSPThread;
|
||||||
|
|
||||||
// May be needed for Stop and Start
|
// May be needed for Stop and Start
|
||||||
#ifdef SETUP_FREE_DSP_PLUGIN_ON_BOOT
|
#ifdef SETUP_FREE_DSP_PLUGIN_ON_BOOT
|
||||||
Plugins.FreeDSP();
|
Plugins.FreeDSP();
|
||||||
|
|
|
@ -263,6 +263,7 @@ void Read16(u16& _rReturnValue, const u32 _Address)
|
||||||
, m_CPStatusReg.UnderflowLoWatermark ? "ON" : "OFF"
|
, m_CPStatusReg.UnderflowLoWatermark ? "ON" : "OFF"
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case CTRL_REGISTER: _rReturnValue = m_CPCtrlReg.Hex; return;
|
case CTRL_REGISTER: _rReturnValue = m_CPCtrlReg.Hex; return;
|
||||||
case CLEAR_REGISTER: _rReturnValue = m_CPClearReg.Hex; return;
|
case CLEAR_REGISTER: _rReturnValue = m_CPClearReg.Hex; return;
|
||||||
|
|
||||||
|
@ -286,55 +287,59 @@ void Read16(u16& _rReturnValue, const u32 _Address)
|
||||||
//_rReturnValue = ReadLow (fifo.CPReadWriteDistance);
|
//_rReturnValue = ReadLow (fifo.CPReadWriteDistance);
|
||||||
// hack: CPU will always believe fifo is empty and on idle
|
// hack: CPU will always believe fifo is empty and on idle
|
||||||
_rReturnValue = 0;
|
_rReturnValue = 0;
|
||||||
DEBUG_LOG(COMMANDPROCESSOR,"read FIFO_RW_DISTANCE_LO : %04x", _rReturnValue);
|
DEBUG_LOG(COMMANDPROCESSOR, "read FIFO_RW_DISTANCE_LO : %04x", _rReturnValue);
|
||||||
return;
|
return;
|
||||||
case FIFO_RW_DISTANCE_HI:
|
case FIFO_RW_DISTANCE_HI:
|
||||||
//_rReturnValue = ReadHigh(fifo.CPReadWriteDistance);
|
//_rReturnValue = ReadHigh(fifo.CPReadWriteDistance);
|
||||||
// hack: CPU will always believe fifo is empty and on idle
|
// hack: CPU will always believe fifo is empty and on idle
|
||||||
_rReturnValue = 0;
|
_rReturnValue = 0;
|
||||||
DEBUG_LOG(COMMANDPROCESSOR,"read FIFO_RW_DISTANCE_HI : %04x", _rReturnValue);
|
DEBUG_LOG(COMMANDPROCESSOR, "read FIFO_RW_DISTANCE_HI : %04x", _rReturnValue);
|
||||||
return;
|
return;
|
||||||
case FIFO_WRITE_POINTER_LO:
|
case FIFO_WRITE_POINTER_LO:
|
||||||
_rReturnValue = ReadLow (fifo.CPWritePointer);
|
_rReturnValue = ReadLow (fifo.CPWritePointer);
|
||||||
DEBUG_LOG(COMMANDPROCESSOR,"read FIFO_WRITE_POINTER_LO : %04x", _rReturnValue);
|
DEBUG_LOG(COMMANDPROCESSOR, "read FIFO_WRITE_POINTER_LO : %04x", _rReturnValue);
|
||||||
return;
|
return;
|
||||||
case FIFO_WRITE_POINTER_HI:
|
case FIFO_WRITE_POINTER_HI:
|
||||||
_rReturnValue = ReadHigh(fifo.CPWritePointer);
|
_rReturnValue = ReadHigh(fifo.CPWritePointer);
|
||||||
DEBUG_LOG(COMMANDPROCESSOR,"read FIFO_WRITE_POINTER_HI : %04x", _rReturnValue);
|
DEBUG_LOG(COMMANDPROCESSOR, "read FIFO_WRITE_POINTER_HI : %04x", _rReturnValue);
|
||||||
return;
|
return;
|
||||||
case FIFO_READ_POINTER_LO:
|
case FIFO_READ_POINTER_LO:
|
||||||
//_rReturnValue = ReadLow (fifo.CPReadPointer);
|
//_rReturnValue = ReadLow (fifo.CPReadPointer);
|
||||||
// hack: CPU will always believe fifo is empty and on idle
|
// hack: CPU will always believe fifo is empty and on idle
|
||||||
_rReturnValue = ReadLow (fifo.CPWritePointer);
|
_rReturnValue = ReadLow (fifo.CPWritePointer);
|
||||||
DEBUG_LOG(COMMANDPROCESSOR,"read FIFO_READ_POINTER_LO : %04x", _rReturnValue);
|
DEBUG_LOG(COMMANDPROCESSOR, "read FIFO_READ_POINTER_LO : %04x", _rReturnValue);
|
||||||
return;
|
return;
|
||||||
case FIFO_READ_POINTER_HI:
|
case FIFO_READ_POINTER_HI:
|
||||||
//_rReturnValue = ReadHigh(fifo.CPReadPointer);
|
//_rReturnValue = ReadHigh(fifo.CPReadPointer);
|
||||||
// hack: CPU will always believe fifo is empty and on idle
|
// hack: CPU will always believe fifo is empty and on idle
|
||||||
_rReturnValue = ReadHigh(fifo.CPWritePointer);
|
_rReturnValue = ReadHigh(fifo.CPWritePointer);
|
||||||
DEBUG_LOG(COMMANDPROCESSOR,"read FIFO_READ_POINTER_HI : %04x", _rReturnValue);
|
DEBUG_LOG(COMMANDPROCESSOR, "read FIFO_READ_POINTER_HI : %04x", _rReturnValue);
|
||||||
return;
|
return;
|
||||||
case FIFO_BP_LO: _rReturnValue = ReadLow (fifo.CPBreakpoint); return;
|
|
||||||
case FIFO_BP_HI: _rReturnValue = ReadHigh(fifo.CPBreakpoint); return;
|
|
||||||
|
|
||||||
// case 0x42: // first metric reg (I guess) read in case of "fifo unknown state"
|
case FIFO_BP_LO: _rReturnValue = ReadLow (fifo.CPBreakpoint); return;
|
||||||
// Crash();
|
case FIFO_BP_HI: _rReturnValue = ReadHigh(fifo.CPBreakpoint); return;
|
||||||
// return;
|
|
||||||
|
case CP_PERF0_L: _rReturnValue = 0; WARN_LOG(COMMANDPROCESSOR, "Read from PERF0_L: %04x", _rReturnValue); break; // XF counters
|
||||||
|
case CP_PERF0_H: _rReturnValue = 0; WARN_LOG(COMMANDPROCESSOR, "Read from PERF0_H: %04x", _rReturnValue); break;
|
||||||
|
|
||||||
|
case CP_PERF1_L: _rReturnValue = 0; WARN_LOG(COMMANDPROCESSOR, "Read from PERF1_L: %04x", _rReturnValue); break;
|
||||||
|
case CP_PERF1_H: _rReturnValue = 0; WARN_LOG(COMMANDPROCESSOR, "Read from PERF1_H: %04x", _rReturnValue); break;
|
||||||
|
|
||||||
|
case CP_PERF2_L: _rReturnValue = 0; WARN_LOG(COMMANDPROCESSOR, "Read from PERF2_L: %04x", _rReturnValue); break;
|
||||||
|
case CP_PERF2_H: _rReturnValue = 0; WARN_LOG(COMMANDPROCESSOR, "Read from PERF2_H: %04x", _rReturnValue); break;
|
||||||
|
|
||||||
|
case CP_PERF3_L: _rReturnValue = 0; WARN_LOG(COMMANDPROCESSOR, "Read from PERF3_L: %04x", _rReturnValue); break;
|
||||||
|
case CP_PERF3_H: _rReturnValue = 0; WARN_LOG(COMMANDPROCESSOR, "Read from PERF3_H: %04x", _rReturnValue); break;
|
||||||
|
|
||||||
// case 0x64:
|
// case 0x64:
|
||||||
// return 4; //Number of clocks per vertex.. todo: calculate properly
|
// return 4; //Number of clocks per vertex.. todo: calculate properly
|
||||||
|
|
||||||
//add all the other regs here? are they ever read?
|
//add all the other regs here? are they ever read?
|
||||||
default:
|
default:
|
||||||
{
|
WARN_LOG(COMMANDPROCESSOR, "(r16) unknown CP reg @ %08x", _Address);
|
||||||
// char szTemp[111];
|
|
||||||
// sprintf(szTemp, "CCommandProcessor 0x%x", (_Address&0xFFF));
|
|
||||||
// MessageBox(NULL, szTemp, "mm", MB_OK);
|
|
||||||
}
|
|
||||||
_rReturnValue = 0;
|
_rReturnValue = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AllowIdleSkipping()
|
bool AllowIdleSkipping()
|
||||||
|
@ -462,11 +467,18 @@ void Write16(const u16 _Value, const u32 _Address)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case PERF_SELECT:
|
||||||
|
{
|
||||||
|
WARN_LOG(COMMANDPROCESSOR, "write to PERF_SELECT: %04x", _Value);
|
||||||
|
// Seems to select which set of perf counters should be exposed.
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case CLEAR_REGISTER:
|
case CLEAR_REGISTER:
|
||||||
{
|
{
|
||||||
|
// ????
|
||||||
UCPClearReg tmpClearReg(_Value);
|
UCPClearReg tmpClearReg(_Value);
|
||||||
m_CPClearReg.Hex = 0;
|
m_CPClearReg.Hex = 0;
|
||||||
|
|
||||||
INFO_LOG(COMMANDPROCESSOR,"\t write to CLEAR_REGISTER : %04x",_Value);
|
INFO_LOG(COMMANDPROCESSOR,"\t write to CLEAR_REGISTER : %04x",_Value);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -556,6 +568,8 @@ void Write16(const u16 _Value, const u32 _Address)
|
||||||
//WriteLow((u32 &)fifo.CPReadWriteDistance, _Value);
|
//WriteLow((u32 &)fifo.CPReadWriteDistance, _Value);
|
||||||
DEBUG_LOG(COMMANDPROCESSOR,"try to write to FIFO_RW_DISTANCE_LO : %04x", _Value);
|
DEBUG_LOG(COMMANDPROCESSOR,"try to write to FIFO_RW_DISTANCE_LO : %04x", _Value);
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
WARN_LOG(COMMANDPROCESSOR, "(w16) unknown CP reg write %04x @ %08x", _Value, _Address);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(mb2): better. Check if it help: avoid CPReadPointer overwrites when stupidly done like in Super Monkey Ball
|
// TODO(mb2): better. Check if it help: avoid CPReadPointer overwrites when stupidly done like in Super Monkey Ball
|
||||||
|
|
|
@ -31,6 +31,7 @@ enum
|
||||||
STATUS_REGISTER = 0x00,
|
STATUS_REGISTER = 0x00,
|
||||||
CTRL_REGISTER = 0x02,
|
CTRL_REGISTER = 0x02,
|
||||||
CLEAR_REGISTER = 0x04,
|
CLEAR_REGISTER = 0x04,
|
||||||
|
PERF_SELECT = 0x06,
|
||||||
FIFO_TOKEN_REGISTER = 0x0E,
|
FIFO_TOKEN_REGISTER = 0x0E,
|
||||||
FIFO_BOUNDING_BOX_LEFT = 0x10,
|
FIFO_BOUNDING_BOX_LEFT = 0x10,
|
||||||
FIFO_BOUNDING_BOX_RIGHT = 0x12,
|
FIFO_BOUNDING_BOX_RIGHT = 0x12,
|
||||||
|
@ -51,7 +52,15 @@ enum
|
||||||
FIFO_READ_POINTER_LO = 0x38,
|
FIFO_READ_POINTER_LO = 0x38,
|
||||||
FIFO_READ_POINTER_HI = 0x3A,
|
FIFO_READ_POINTER_HI = 0x3A,
|
||||||
FIFO_BP_LO = 0x3C,
|
FIFO_BP_LO = 0x3C,
|
||||||
FIFO_BP_HI = 0x3E
|
FIFO_BP_HI = 0x3E,
|
||||||
|
CP_PERF0_L = 0x40,
|
||||||
|
CP_PERF0_H = 0x42,
|
||||||
|
CP_PERF1_L = 0x44,
|
||||||
|
CP_PERF1_H = 0x46,
|
||||||
|
CP_PERF2_L = 0x48,
|
||||||
|
CP_PERF2_H = 0x4a,
|
||||||
|
CP_PERF3_L = 0x4c,
|
||||||
|
CP_PERF3_H = 0x4e,
|
||||||
};
|
};
|
||||||
|
|
||||||
extern SCPFifoStruct fifo;
|
extern SCPFifoStruct fifo;
|
||||||
|
|
|
@ -216,6 +216,21 @@ void Read16(u16& _uReturnValue, const u32 _iAddress)
|
||||||
case PE_BBOX_TOP: _uReturnValue = bbox[2]; INFO_LOG(PIXELENGINE, "R: BBOX_TOP = %i", bbox[2]); bbox_active = false; break;
|
case PE_BBOX_TOP: _uReturnValue = bbox[2]; INFO_LOG(PIXELENGINE, "R: BBOX_TOP = %i", bbox[2]); bbox_active = false; break;
|
||||||
case PE_BBOX_BOTTOM: _uReturnValue = bbox[3]; INFO_LOG(PIXELENGINE, "R: BBOX_BOTTOM = %i", bbox[3]); bbox_active = false; break;
|
case PE_BBOX_BOTTOM: _uReturnValue = bbox[3]; INFO_LOG(PIXELENGINE, "R: BBOX_BOTTOM = %i", bbox[3]); bbox_active = false; break;
|
||||||
|
|
||||||
|
case PE_PERF_0L:
|
||||||
|
case PE_PERF_0H:
|
||||||
|
case PE_PERF_1L:
|
||||||
|
case PE_PERF_1H:
|
||||||
|
case PE_PERF_2L:
|
||||||
|
case PE_PERF_2H:
|
||||||
|
case PE_PERF_3L:
|
||||||
|
case PE_PERF_3H:
|
||||||
|
case PE_PERF_4L:
|
||||||
|
case PE_PERF_4H:
|
||||||
|
case PE_PERF_5L:
|
||||||
|
case PE_PERF_5H:
|
||||||
|
WARN_LOG(PIXELENGINE, "(r16) perf counter @ %08x", _iAddress);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
WARN_LOG(PIXELENGINE, "(r16) unknown @ %08x", _iAddress);
|
WARN_LOG(PIXELENGINE, "(r16) unknown @ %08x", _iAddress);
|
||||||
_uReturnValue = 1;
|
_uReturnValue = 1;
|
||||||
|
|
|
@ -35,6 +35,20 @@ enum
|
||||||
PE_BBOX_RIGHT = 0x12, // Flip Right
|
PE_BBOX_RIGHT = 0x12, // Flip Right
|
||||||
PE_BBOX_TOP = 0x14, // Flip Top
|
PE_BBOX_TOP = 0x14, // Flip Top
|
||||||
PE_BBOX_BOTTOM = 0x16, // Flip Bottom
|
PE_BBOX_BOTTOM = 0x16, // Flip Bottom
|
||||||
|
|
||||||
|
// These have not yet been RE:d. They are the perf counters.
|
||||||
|
PE_PERF_0L = 0x18,
|
||||||
|
PE_PERF_0H = 0x1a,
|
||||||
|
PE_PERF_1L = 0x1c,
|
||||||
|
PE_PERF_1H = 0x1e,
|
||||||
|
PE_PERF_2L = 0x20,
|
||||||
|
PE_PERF_2H = 0x22,
|
||||||
|
PE_PERF_3L = 0x24,
|
||||||
|
PE_PERF_3H = 0x26,
|
||||||
|
PE_PERF_4L = 0x28,
|
||||||
|
PE_PERF_4H = 0x2a,
|
||||||
|
PE_PERF_5L = 0x2c,
|
||||||
|
PE_PERF_5H = 0x2e,
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace PixelEngine
|
namespace PixelEngine
|
||||||
|
|
|
@ -1,32 +1,32 @@
|
||||||
# -*- python -*-
|
# -*- python -*-
|
||||||
|
|
||||||
Import('env')
|
Import('env')
|
||||||
|
|
||||||
files = [
|
files = [
|
||||||
"assemble.cpp",
|
"assemble.cpp",
|
||||||
"disassemble.cpp",
|
"disassemble.cpp",
|
||||||
"DSPAccelerator.cpp",
|
"DSPAccelerator.cpp",
|
||||||
"DSPBreakpoints.cpp",
|
"DSPBreakpoints.cpp",
|
||||||
"DSPIntCCUtil.cpp",
|
"DSPIntCCUtil.cpp",
|
||||||
"DSPIntExtOps.cpp",
|
"DSPIntExtOps.cpp",
|
||||||
"DSPHWInterface.cpp",
|
"DSPHWInterface.cpp",
|
||||||
"DSPInterpreter.cpp",
|
"DSPInterpreter.cpp",
|
||||||
"DSPMemoryMap.cpp",
|
"DSPMemoryMap.cpp",
|
||||||
"DSPStacks.cpp",
|
"DSPStacks.cpp",
|
||||||
"DSPAnalyzer.cpp",
|
"DSPAnalyzer.cpp",
|
||||||
"DspIntArithmetic.cpp",
|
"DspIntArithmetic.cpp",
|
||||||
"DspIntBranch.cpp",
|
"DspIntBranch.cpp",
|
||||||
"DspIntLoadStore.cpp",
|
"DspIntLoadStore.cpp",
|
||||||
"DspIntMisc.cpp",
|
"DspIntMisc.cpp",
|
||||||
"DspIntMultiplier.cpp",
|
"DspIntMultiplier.cpp",
|
||||||
"DSPJit.cpp",
|
"DSPJit.cpp",
|
||||||
"DSPCodeUtil.cpp",
|
"DSPCodeUtil.cpp",
|
||||||
"LabelMap.cpp",
|
"LabelMap.cpp",
|
||||||
"DSPCore.cpp",
|
"DSPCore.cpp",
|
||||||
"DSPTables.cpp",
|
"DSPTables.cpp",
|
||||||
]
|
]
|
||||||
|
|
||||||
acenv = env.Clone()
|
acenv = env.Clone()
|
||||||
acenv.Append(CXXFLAGS = [ '-fPIC' ])
|
acenv.Append(CXXFLAGS = [ '-fPIC' ])
|
||||||
|
|
||||||
acenv.StaticLibrary(env['local_libs'] + 'dspcore', files, LIBS = [ 'common'] )
|
acenv.StaticLibrary(env['local_libs'] + 'dspcore', files, LIBS = [ 'common'] )
|
||||||
|
|
|
@ -22,7 +22,6 @@
|
||||||
#define _GLOBALS_H
|
#define _GLOBALS_H
|
||||||
|
|
||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
#include "svnrev.h"
|
|
||||||
|
|
||||||
// Constant Colors
|
// Constant Colors
|
||||||
const unsigned long COLOR_GRAY = 0xDCDCDC;
|
const unsigned long COLOR_GRAY = 0xDCDCDC;
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
// Official SVN repository and contact information can be found at
|
// Official SVN repository and contact information can be found at
|
||||||
// http://code.google.com/p/dolphin-emu/
|
// http://code.google.com/p/dolphin-emu/
|
||||||
|
|
||||||
|
#include "svnrev.h"
|
||||||
#include "Globals.h"
|
#include "Globals.h"
|
||||||
#include "InfoWindow.h"
|
#include "InfoWindow.h"
|
||||||
#include "CPUDetect.h"
|
#include "CPUDetect.h"
|
||||||
|
|
|
@ -26,6 +26,8 @@
|
||||||
|
|
||||||
// Mash together all the inputs that contribute to the code of a generated pixel shader into
|
// Mash together all the inputs that contribute to the code of a generated pixel shader into
|
||||||
// a unique identifier, basically containing all the bits. Yup, it's a lot ....
|
// a unique identifier, basically containing all the bits. Yup, it's a lot ....
|
||||||
|
// It would likely be a lot more efficient to build this incrementally as the attributes
|
||||||
|
// are set...
|
||||||
void GetPixelShaderId(PIXELSHADERUID &uid, u32 s_texturemask, u32 dstAlphaEnable)
|
void GetPixelShaderId(PIXELSHADERUID &uid, u32 s_texturemask, u32 dstAlphaEnable)
|
||||||
{
|
{
|
||||||
u32 projtexcoords = 0;
|
u32 projtexcoords = 0;
|
||||||
|
@ -90,7 +92,7 @@ void GetPixelShaderId(PIXELSHADERUID &uid, u32 s_texturemask, u32 dstAlphaEnable
|
||||||
if ((bpmem.genMode.numtevstages + 1) & 1) { // odd
|
if ((bpmem.genMode.numtevstages + 1) & 1) { // odd
|
||||||
u32 val0;
|
u32 val0;
|
||||||
if (bpmem.tevorders[bpmem.genMode.numtevstages/2].hex & 0x40)
|
if (bpmem.tevorders[bpmem.genMode.numtevstages/2].hex & 0x40)
|
||||||
val0 = bpmem.tevorders[bpmem.genMode.numtevstages/2].hex&0x3ff;
|
val0 = bpmem.tevorders[bpmem.genMode.numtevstages/2].hex & 0x3ff;
|
||||||
else
|
else
|
||||||
val0 = bpmem.tevorders[bpmem.genMode.numtevstages/2].hex & 0x380;
|
val0 = bpmem.tevorders[bpmem.genMode.numtevstages/2].hex & 0x380;
|
||||||
|
|
||||||
|
@ -104,11 +106,11 @@ void GetPixelShaderId(PIXELSHADERUID &uid, u32 s_texturemask, u32 dstAlphaEnable
|
||||||
if ((bpmem.genMode.numtevstages % 3) != 2)
|
if ((bpmem.genMode.numtevstages % 3) != 2)
|
||||||
++pcurvalue;
|
++pcurvalue;
|
||||||
|
|
||||||
uid.tevstages = (u32)(pcurvalue-&uid.values[0]-hdr);
|
uid.tevstages = (u32)(pcurvalue - &uid.values[0] - hdr);
|
||||||
|
|
||||||
for (u32 i = 0; i < bpmem.genMode.numindstages; ++i) {
|
for (u32 i = 0; i < bpmem.genMode.numindstages; ++i) {
|
||||||
u32 val = bpmem.tevind[i].hex & 0x1fffff; // 21 bits
|
u32 val = bpmem.tevind[i].hex & 0x1fffff; // 21 bits
|
||||||
switch (i%3) {
|
switch (i % 3) {
|
||||||
case 0: pcurvalue[0] = val; break;
|
case 0: pcurvalue[0] = val; break;
|
||||||
case 1: pcurvalue[0] |= val << 21; pcurvalue[1] = val >> 11; ++pcurvalue; break;
|
case 1: pcurvalue[0] |= val << 21; pcurvalue[1] = val >> 11; ++pcurvalue; break;
|
||||||
case 2: pcurvalue[0] |= val << 10; ++pcurvalue; break;
|
case 2: pcurvalue[0] |= val << 10; ++pcurvalue; break;
|
||||||
|
@ -320,8 +322,8 @@ static const char *tevAInputTable2[] = // CA
|
||||||
|
|
||||||
static const char *tevRasTable[] =
|
static const char *tevRasTable[] =
|
||||||
{
|
{
|
||||||
"colors[0]",
|
"colors_0",
|
||||||
"colors[1]",
|
"colors_1",
|
||||||
"ERROR", //2
|
"ERROR", //2
|
||||||
"ERROR", //3
|
"ERROR", //3
|
||||||
"ERROR", //4
|
"ERROR", //4
|
||||||
|
@ -356,7 +358,6 @@ static char text[16384];
|
||||||
|
|
||||||
static void BuildSwapModeTable()
|
static void BuildSwapModeTable()
|
||||||
{
|
{
|
||||||
//bpmem.tevregs[0].
|
|
||||||
for (int i = 0; i < 4; i++)
|
for (int i = 0; i < 4; i++)
|
||||||
{
|
{
|
||||||
swapModeTable[i][0] = swapColors[bpmem.tevksel[i*2].swap1];
|
swapModeTable[i][0] = swapColors[bpmem.tevksel[i*2].swap1];
|
||||||
|
@ -442,7 +443,7 @@ const char *GeneratePixelShader(u32 texture_mask, bool dstAlphaEnable, bool HLSL
|
||||||
WRITE(p, " in float%d uv%d : TEXCOORD%d, \n", i<4?4:3, i, i);
|
WRITE(p, " in float%d uv%d : TEXCOORD%d, \n", i<4?4:3, i, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
WRITE(p, " in float4 colors[2] : COLOR0){\n");
|
WRITE(p, " in float4 colors_0 : COLOR0, in float4 colors_1 : COLOR1){\n");
|
||||||
|
|
||||||
char* pmainstart = p;
|
char* pmainstart = p;
|
||||||
|
|
||||||
|
@ -628,7 +629,7 @@ static void WriteStage(char *&p, int n, u32 texture_mask)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
WRITE(p, "rastemp=%s.%s;\n",tevRasTable[bpmem.tevorders[n/2].getColorChan(n&1)],rasswap);
|
WRITE(p, "rastemp=%s.%s;\n", tevRasTable[bpmem.tevorders[n / 2].getColorChan(n & 1)],rasswap);
|
||||||
|
|
||||||
if (bpmem.tevorders[n/2].getEnable(n&1)) {
|
if (bpmem.tevorders[n/2].getEnable(n&1)) {
|
||||||
int texmap = bpmem.tevorders[n/2].getTexMap(n&1);
|
int texmap = bpmem.tevorders[n/2].getTexMap(n&1);
|
||||||
|
|
|
@ -107,11 +107,16 @@ void LOADERDECL UpdateBoundingBox()
|
||||||
t[2] = p[0] * world_matrix[8] + p[1] * world_matrix[9] + p[2] * world_matrix[10] + world_matrix[11];
|
t[2] = p[0] * world_matrix[8] + p[1] * world_matrix[9] + p[2] * world_matrix[10] + world_matrix[11];
|
||||||
|
|
||||||
float o[4];
|
float o[4];
|
||||||
|
o[2] = t[0] * proj_matrix[8] + t[1] * proj_matrix[9] + t[2] * proj_matrix[10] + proj_matrix[11];
|
||||||
|
// Depth culling
|
||||||
|
if (o[2] < 0.0) {
|
||||||
|
// No pixels are likely to be drawn - don't update bounding box.
|
||||||
|
return;
|
||||||
|
}
|
||||||
o[0] = t[0] * proj_matrix[0] + t[1] * proj_matrix[1] + t[2] * proj_matrix[2] + proj_matrix[3];
|
o[0] = t[0] * proj_matrix[0] + t[1] * proj_matrix[1] + t[2] * proj_matrix[2] + proj_matrix[3];
|
||||||
o[1] = t[0] * proj_matrix[4] + t[1] * proj_matrix[5] + t[2] * proj_matrix[6] + proj_matrix[7];
|
o[1] = t[0] * proj_matrix[4] + t[1] * proj_matrix[5] + t[2] * proj_matrix[6] + proj_matrix[7];
|
||||||
o[2] = t[0] * proj_matrix[8] + t[1] * proj_matrix[9] + t[2] * proj_matrix[10] + proj_matrix[11];
|
|
||||||
o[3] = t[0] * proj_matrix[12] + t[1] * proj_matrix[13] + t[2] * proj_matrix[14] + proj_matrix[15];
|
o[3] = t[0] * proj_matrix[12] + t[1] * proj_matrix[13] + t[2] * proj_matrix[14] + proj_matrix[15];
|
||||||
|
|
||||||
o[0] /= o[3];
|
o[0] /= o[3];
|
||||||
o[1] /= o[3];
|
o[1] /= o[3];
|
||||||
|
|
||||||
|
|
|
@ -668,6 +668,10 @@
|
||||||
<Filter
|
<Filter
|
||||||
Name="UCode Zelda"
|
Name="UCode Zelda"
|
||||||
>
|
>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\docs\DSP\DSP_UC_Zelda.txt"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\Src\UCodes\UCode_Zelda.cpp"
|
RelativePath=".\Src\UCodes\UCode_Zelda.cpp"
|
||||||
>
|
>
|
||||||
|
@ -684,6 +688,10 @@
|
||||||
RelativePath=".\Src\UCodes\UCode_Zelda_ADPCM.h"
|
RelativePath=".\Src\UCodes\UCode_Zelda_ADPCM.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\Src\UCodes\UCode_Zelda_Obsolete.txt"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\Src\UCodes\UCode_Zelda_Synth.cpp"
|
RelativePath=".\Src\UCodes\UCode_Zelda_Synth.cpp"
|
||||||
>
|
>
|
||||||
|
|
|
@ -30,28 +30,41 @@
|
||||||
#include "WaveFile.h"
|
#include "WaveFile.h"
|
||||||
|
|
||||||
CUCode_Zelda::CUCode_Zelda(CMailHandler& _rMailHandler, u32 _CRC)
|
CUCode_Zelda::CUCode_Zelda(CMailHandler& _rMailHandler, u32 _CRC)
|
||||||
: IUCode(_rMailHandler)
|
:
|
||||||
, m_CRC(_CRC)
|
IUCode(_rMailHandler),
|
||||||
, m_bSyncInProgress(false)
|
m_CRC(_CRC),
|
||||||
, m_MaxVoice(0)
|
|
||||||
, m_NumVoices(0)
|
m_bSyncInProgress(0),
|
||||||
, m_bSyncCmdPending(false)
|
m_MaxVoice(0),
|
||||||
, m_CurVoice(0)
|
|
||||||
, m_CurBuffer(0)
|
m_NumVoices(0),
|
||||||
, m_NumBuffers(0)
|
|
||||||
, m_VoicePBsAddr(0)
|
m_bSyncCmdPending(0),
|
||||||
, m_UnkTableAddr(0)
|
m_CurVoice(0),
|
||||||
, m_AFCCoefTableAddr(0)
|
m_CurBuffer(0),
|
||||||
, m_ReverbPBsAddr(0)
|
m_NumBuffers(0),
|
||||||
, m_RightBuffersAddr(0)
|
|
||||||
, m_LeftBuffersAddr(0)
|
m_VoicePBsAddr(0),
|
||||||
, m_pos(0)
|
m_UnkTableAddr(0),
|
||||||
, m_DMABaseAddr(0)
|
m_ReverbPBsAddr(0),
|
||||||
, m_numSteps(0)
|
|
||||||
, m_bListInProgress(false)
|
m_RightBuffersAddr(0),
|
||||||
, m_step(0)
|
m_LeftBuffersAddr(0),
|
||||||
, m_readOffset(0)
|
m_pos(0),
|
||||||
, m_MailState(WaitForMail)
|
|
||||||
|
m_DMABaseAddr(0),
|
||||||
|
|
||||||
|
m_numSteps(0),
|
||||||
|
m_bListInProgress(0),
|
||||||
|
m_step(0),
|
||||||
|
|
||||||
|
m_readOffset(0),
|
||||||
|
|
||||||
|
m_MailState(WaitForMail),
|
||||||
|
|
||||||
|
m_NumPBs(0),
|
||||||
|
m_PBAddress(0),
|
||||||
|
m_PBAddress2(0)
|
||||||
{
|
{
|
||||||
DEBUG_LOG(DSPHLE, "UCode_Zelda - add boot mails for handshake");
|
DEBUG_LOG(DSPHLE, "UCode_Zelda - add boot mails for handshake");
|
||||||
m_rMailHandler.PushMail(DSP_INIT);
|
m_rMailHandler.PushMail(DSP_INIT);
|
||||||
|
@ -65,6 +78,7 @@ CUCode_Zelda::CUCode_Zelda(CMailHandler& _rMailHandler, u32 _CRC)
|
||||||
memset(m_Buffer, 0, sizeof(m_Buffer));
|
memset(m_Buffer, 0, sizeof(m_Buffer));
|
||||||
memset(m_SyncFlags, 0, sizeof(m_SyncFlags));
|
memset(m_SyncFlags, 0, sizeof(m_SyncFlags));
|
||||||
memset(m_AFCCoefTable, 0, sizeof(m_AFCCoefTable));
|
memset(m_AFCCoefTable, 0, sizeof(m_AFCCoefTable));
|
||||||
|
memset(m_PBMask, 0, sizeof(m_PBMask));
|
||||||
}
|
}
|
||||||
|
|
||||||
CUCode_Zelda::~CUCode_Zelda()
|
CUCode_Zelda::~CUCode_Zelda()
|
||||||
|
@ -76,186 +90,6 @@ CUCode_Zelda::~CUCode_Zelda()
|
||||||
delete [] m_RightBuffer;
|
delete [] m_RightBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
void CUCode_Zelda::UpdatePB(ZPB& _rPB, int *templbuffer, int *temprbuffer, u32 _Size)
|
|
||||||
{
|
|
||||||
u16* pTest = (u16*)&_rPB;
|
|
||||||
|
|
||||||
// Checks at 0293
|
|
||||||
if (pTest[0x00] == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (pTest[0x01] != 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
|
|
||||||
if (pTest[0x06] != 0x00)
|
|
||||||
{
|
|
||||||
// probably pTest[0x06] == 0 -> AFC (and variants)
|
|
||||||
// See 02a4
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
switch (_rPB.type) // or Bytes per Sample
|
|
||||||
{
|
|
||||||
case 0x05:
|
|
||||||
case 0x09:
|
|
||||||
{
|
|
||||||
// initialize "decoder" if the sample is played the first time
|
|
||||||
if (pTest[0x04] != 0)
|
|
||||||
{
|
|
||||||
// This is 0717_ReadOutPBStuff
|
|
||||||
|
|
||||||
// increment 4fb
|
|
||||||
|
|
||||||
// zelda:
|
|
||||||
// perhaps init or "has played before"
|
|
||||||
pTest[0x32] = 0x00;
|
|
||||||
pTest[0x66] = 0x00; // history1
|
|
||||||
pTest[0x67] = 0x00; // history2
|
|
||||||
|
|
||||||
// samplerate? length? num of samples? i dunno...
|
|
||||||
// Likely length...
|
|
||||||
pTest[0x3a] = pTest[0x8a];
|
|
||||||
pTest[0x3b] = pTest[0x8b];
|
|
||||||
|
|
||||||
// Copy ARAM addr from r to rw area.
|
|
||||||
pTest[0x38] = pTest[0x8c];
|
|
||||||
pTest[0x39] = pTest[0x8d];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pTest[0x01] != 0) // 0747 early out... i dunno if this can happen because we filter it above
|
|
||||||
return;
|
|
||||||
|
|
||||||
u32 ARAMAddr = (pTest[0x38] << 16) | pTest[0x39];
|
|
||||||
u32 NumberOfSamples = (pTest[0x3a] << 16) | pTest[0x3b];
|
|
||||||
|
|
||||||
// round upwards how many samples we need to copy, 0759
|
|
||||||
NumberOfSamples = (NumberOfSamples + 0xf) >> 4; // i think the lower 4 are the fraction
|
|
||||||
u32 frac = NumberOfSamples & 0xF;
|
|
||||||
|
|
||||||
u8 inBuffer[9];
|
|
||||||
short outbuf[16];
|
|
||||||
u32 sampleCount = 0;
|
|
||||||
|
|
||||||
// It must be something like this:
|
|
||||||
|
|
||||||
// The PB contains a small sample buffer of 0x4D decoded samples.
|
|
||||||
// If it's empty or "used", decode to it.
|
|
||||||
// Then, resample from this buffer to the output as you go. When it needs
|
|
||||||
// wrapping, decode more.
|
|
||||||
|
|
||||||
#define USE_RESAMPLE
|
|
||||||
#if !defined(USE_RESAMPLE)
|
|
||||||
for (int s = 0; s < _Size/16; s++)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < 9; i++)
|
|
||||||
{
|
|
||||||
inBuffer[i] = g_dspInitialize.pARAM_Read_U8(ARAMAddr);
|
|
||||||
ARAMAddr++;
|
|
||||||
}
|
|
||||||
|
|
||||||
AFCdecodebuffer((char*)inBuffer, outbuf, (short*)&pTest[0x66], (short*)&pTest[0x67]);
|
|
||||||
|
|
||||||
for (int i = 0; i < 16; i++)
|
|
||||||
{
|
|
||||||
templbuffer[sampleCount] += outbuf[i];
|
|
||||||
temprbuffer[sampleCount] += outbuf[i];
|
|
||||||
sampleCount++;
|
|
||||||
}
|
|
||||||
|
|
||||||
NumberOfSamples--;
|
|
||||||
|
|
||||||
if (NumberOfSamples<=0)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
while (NumberOfSamples > 0)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < 9; i++)
|
|
||||||
{
|
|
||||||
inBuffer[i] = g_dspInitialize.pARAM_Read_U8(ARAMAddr);
|
|
||||||
ARAMAddr++;
|
|
||||||
}
|
|
||||||
|
|
||||||
AFCdecodebuffer(m_AFCCoefTable, (char*)inBuffer, outbuf, (short*)&pTest[0x66], (short*)&pTest[0x67], 9);
|
|
||||||
CResampler Sampler(outbuf, 16, 48000);
|
|
||||||
|
|
||||||
while (Sampler.m_queueSize > 0)
|
|
||||||
{
|
|
||||||
int sample = Sampler.sample_queue.front();
|
|
||||||
Sampler.sample_queue.pop();
|
|
||||||
Sampler.m_queueSize -= 1;
|
|
||||||
|
|
||||||
templbuffer[sampleCount] += sample;
|
|
||||||
temprbuffer[sampleCount] += sample;
|
|
||||||
sampleCount++;
|
|
||||||
|
|
||||||
if (sampleCount > _Size)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sampleCount > _Size)
|
|
||||||
break;
|
|
||||||
|
|
||||||
NumberOfSamples--;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
if (NumberOfSamples == 0)
|
|
||||||
{
|
|
||||||
pTest[0x01] = 1; // we are done ??
|
|
||||||
}
|
|
||||||
|
|
||||||
// write back
|
|
||||||
NumberOfSamples = (NumberOfSamples << 4); // missing fraction
|
|
||||||
|
|
||||||
pTest[0x38] = ARAMAddr >> 16;
|
|
||||||
pTest[0x39] = ARAMAddr & 0xFFFF;
|
|
||||||
pTest[0x3a] = NumberOfSamples >> 16;
|
|
||||||
pTest[0x3b] = NumberOfSamples & 0xFFFF;
|
|
||||||
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
NumberOfSamples = (NumberOfSamples + 0xf) >> 4;
|
|
||||||
|
|
||||||
static u8 Buffer[500000];
|
|
||||||
for (int i =0; i<NumberOfSamples*9; i++)
|
|
||||||
{
|
|
||||||
Buffer[i] = g_dspInitialize.pARAM_Read_U8(ARAMAddr+i);
|
|
||||||
}
|
|
||||||
|
|
||||||
// yes, the dumps are really zelda sound ;)
|
|
||||||
DumpAFC(Buffer, NumberOfSamples*9, 0x3d00);
|
|
||||||
|
|
||||||
DumpPB(_rPB);
|
|
||||||
|
|
||||||
// exit(1);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// i think pTest[0x3a] and pTest[0x3b] got an update after you have decoded some samples...
|
|
||||||
// just decrement them with the number of samples you have played
|
|
||||||
// and incrrease the ARAM Offset in pTest[0x38], pTest[0x39]
|
|
||||||
|
|
||||||
|
|
||||||
// end of block (Zelda 03b2)
|
|
||||||
if (pTest[0x06] == 0)
|
|
||||||
{
|
|
||||||
// 02a4
|
|
||||||
//
|
|
||||||
|
|
||||||
pTest[0x04] = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
ERROR_LOG(DSPHLE, "Zelda Ucode: Unknown PB type %i", _rPB.type);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void CUCode_Zelda::Update(int cycles)
|
void CUCode_Zelda::Update(int cycles)
|
||||||
{
|
{
|
||||||
if (m_rMailHandler.GetNextMail() == DSP_FRAME_END)
|
if (m_rMailHandler.GetNextMail() == DSP_FRAME_END)
|
||||||
|
@ -552,36 +386,42 @@ void CUCode_Zelda::MixAdd(short* _Buffer, int _Size)
|
||||||
}
|
}
|
||||||
|
|
||||||
void CUCode_Zelda::DoState(PointerWrap &p) {
|
void CUCode_Zelda::DoState(PointerWrap &p) {
|
||||||
//p.Do(m_MailState);
|
p.Do(m_CRC);
|
||||||
//p.Do(m_PBMask);
|
|
||||||
//p.Do(m_NumPBs);
|
|
||||||
//p.Do(m_PBAddress);
|
|
||||||
//p.Do(m_MaxSyncedPB);
|
|
||||||
//p.Do(m_PBs);
|
|
||||||
p.Do(m_readOffset);
|
|
||||||
//p.Do(m_NumberOfFramesToRender);
|
|
||||||
//p.Do(m_CurrentFrameToRender);
|
|
||||||
p.Do(m_numSteps);
|
|
||||||
p.Do(m_step);
|
|
||||||
p.Do(m_Buffer);
|
|
||||||
/*p.Do(m_CRC);
|
|
||||||
p.Do(m_bSyncInProgress);
|
p.Do(m_bSyncInProgress);
|
||||||
p.Do(m_MaxVoice);
|
p.Do(m_MaxVoice);
|
||||||
|
p.Do(m_SyncFlags);
|
||||||
|
|
||||||
p.Do(m_NumVoices);
|
p.Do(m_NumVoices);
|
||||||
|
|
||||||
p.Do(m_bSyncCmdPending);
|
p.Do(m_bSyncCmdPending);
|
||||||
p.Do(m_CurVoice);
|
p.Do(m_CurVoice);
|
||||||
p.Do(m_CurBuffer);
|
p.Do(m_CurBuffer);
|
||||||
p.Do(m_NumBuffers);
|
p.Do(m_NumBuffers);
|
||||||
|
|
||||||
p.Do(m_VoicePBsAddr);
|
p.Do(m_VoicePBsAddr);
|
||||||
p.Do(m_UnkTableAddr);
|
p.Do(m_UnkTableAddr);
|
||||||
p.Do(m_AFCCoefTableAddr);
|
p.Do(m_AFCCoefTableAddr);
|
||||||
p.Do(m_ReverbPBsAddr);
|
p.Do(m_ReverbPBsAddr);
|
||||||
|
|
||||||
p.Do(m_RightBuffersAddr);
|
p.Do(m_RightBuffersAddr);
|
||||||
p.Do(m_LeftBuffersAddr);
|
p.Do(m_LeftBuffersAddr);
|
||||||
|
p.Do(m_pos);
|
||||||
|
|
||||||
p.Do(m_DMABaseAddr);
|
p.Do(m_DMABaseAddr);
|
||||||
|
|
||||||
p.Do(m_numSteps);
|
p.Do(m_numSteps);
|
||||||
|
p.Do(m_bListInProgress);
|
||||||
p.Do(m_step);
|
p.Do(m_step);
|
||||||
|
p.Do(m_Buffer);
|
||||||
|
|
||||||
p.Do(m_readOffset);
|
p.Do(m_readOffset);
|
||||||
p.Do(m_MailState);*/
|
|
||||||
|
p.Do(m_MailState);
|
||||||
|
p.Do(m_PBMask);
|
||||||
|
|
||||||
|
p.Do(m_NumPBs);
|
||||||
|
p.Do(m_PBAddress);
|
||||||
|
p.Do(m_PBAddress2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -152,11 +152,14 @@ private:
|
||||||
|
|
||||||
u32 m_CRC;
|
u32 m_CRC;
|
||||||
|
|
||||||
|
// These are the only dynamically allocated things allowed in the ucode.
|
||||||
s32* m_TempBuffer;
|
s32* m_TempBuffer;
|
||||||
|
|
||||||
s32* m_LeftBuffer;
|
s32* m_LeftBuffer;
|
||||||
s32* m_RightBuffer;
|
s32* m_RightBuffer;
|
||||||
|
|
||||||
|
|
||||||
|
// If you add variables, remember to keep DoState() and the constructor up to date.
|
||||||
|
|
||||||
s16 m_AFCCoefTable[32];
|
s16 m_AFCCoefTable[32];
|
||||||
|
|
||||||
bool m_bSyncInProgress;
|
bool m_bSyncInProgress;
|
||||||
|
@ -190,7 +193,6 @@ private:
|
||||||
bool m_bListInProgress;
|
bool m_bListInProgress;
|
||||||
u32 m_step;
|
u32 m_step;
|
||||||
u8 m_Buffer[1024];
|
u8 m_Buffer[1024];
|
||||||
void ExecuteList();
|
|
||||||
|
|
||||||
u32 m_readOffset;
|
u32 m_readOffset;
|
||||||
|
|
||||||
|
@ -205,14 +207,11 @@ private:
|
||||||
EMailState m_MailState;
|
EMailState m_MailState;
|
||||||
u16 m_PBMask[0x10];
|
u16 m_PBMask[0x10];
|
||||||
|
|
||||||
|
|
||||||
u32 m_NumPBs;
|
u32 m_NumPBs;
|
||||||
u32 m_PBAddress; // The main param block array
|
u32 m_PBAddress; // The main param block array
|
||||||
u32 m_PBAddress2; // 4 smaller param blocks
|
u32 m_PBAddress2; // 4 smaller param blocks
|
||||||
|
|
||||||
u32 m_MixingBufferLeft;
|
void ExecuteList();
|
||||||
u32 m_MixingBufferRight;
|
|
||||||
|
|
||||||
|
|
||||||
void ReadVoicePB(u32 _Addr, ZeldaVoicePB& PB);
|
void ReadVoicePB(u32 _Addr, ZeldaVoicePB& PB);
|
||||||
void WritebackVoicePB(u32 _Addr, ZeldaVoicePB& PB);
|
void WritebackVoicePB(u32 _Addr, ZeldaVoicePB& PB);
|
||||||
|
|
|
@ -0,0 +1,180 @@
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
void CUCode_Zelda::UpdatePB(ZPB& _rPB, int *templbuffer, int *temprbuffer, u32 _Size)
|
||||||
|
{
|
||||||
|
u16* pTest = (u16*)&_rPB;
|
||||||
|
|
||||||
|
// Checks at 0293
|
||||||
|
if (pTest[0x00] == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (pTest[0x01] != 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
|
||||||
|
if (pTest[0x06] != 0x00)
|
||||||
|
{
|
||||||
|
// probably pTest[0x06] == 0 -> AFC (and variants)
|
||||||
|
// See 02a4
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
switch (_rPB.type) // or Bytes per Sample
|
||||||
|
{
|
||||||
|
case 0x05:
|
||||||
|
case 0x09:
|
||||||
|
{
|
||||||
|
// initialize "decoder" if the sample is played the first time
|
||||||
|
if (pTest[0x04] != 0)
|
||||||
|
{
|
||||||
|
// This is 0717_ReadOutPBStuff
|
||||||
|
|
||||||
|
// increment 4fb
|
||||||
|
|
||||||
|
// zelda:
|
||||||
|
// perhaps init or "has played before"
|
||||||
|
pTest[0x32] = 0x00;
|
||||||
|
pTest[0x66] = 0x00; // history1
|
||||||
|
pTest[0x67] = 0x00; // history2
|
||||||
|
|
||||||
|
// samplerate? length? num of samples? i dunno...
|
||||||
|
// Likely length...
|
||||||
|
pTest[0x3a] = pTest[0x8a];
|
||||||
|
pTest[0x3b] = pTest[0x8b];
|
||||||
|
|
||||||
|
// Copy ARAM addr from r to rw area.
|
||||||
|
pTest[0x38] = pTest[0x8c];
|
||||||
|
pTest[0x39] = pTest[0x8d];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pTest[0x01] != 0) // 0747 early out... i dunno if this can happen because we filter it above
|
||||||
|
return;
|
||||||
|
|
||||||
|
u32 ARAMAddr = (pTest[0x38] << 16) | pTest[0x39];
|
||||||
|
u32 NumberOfSamples = (pTest[0x3a] << 16) | pTest[0x3b];
|
||||||
|
|
||||||
|
// round upwards how many samples we need to copy, 0759
|
||||||
|
NumberOfSamples = (NumberOfSamples + 0xf) >> 4; // i think the lower 4 are the fraction
|
||||||
|
u32 frac = NumberOfSamples & 0xF;
|
||||||
|
|
||||||
|
u8 inBuffer[9];
|
||||||
|
short outbuf[16];
|
||||||
|
u32 sampleCount = 0;
|
||||||
|
|
||||||
|
// It must be something like this:
|
||||||
|
|
||||||
|
// The PB contains a small sample buffer of 0x4D decoded samples.
|
||||||
|
// If it's empty or "used", decode to it.
|
||||||
|
// Then, resample from this buffer to the output as you go. When it needs
|
||||||
|
// wrapping, decode more.
|
||||||
|
|
||||||
|
#define USE_RESAMPLE
|
||||||
|
#if !defined(USE_RESAMPLE)
|
||||||
|
for (int s = 0; s < _Size/16; s++)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < 9; i++)
|
||||||
|
{
|
||||||
|
inBuffer[i] = g_dspInitialize.pARAM_Read_U8(ARAMAddr);
|
||||||
|
ARAMAddr++;
|
||||||
|
}
|
||||||
|
|
||||||
|
AFCdecodebuffer((char*)inBuffer, outbuf, (short*)&pTest[0x66], (short*)&pTest[0x67]);
|
||||||
|
|
||||||
|
for (int i = 0; i < 16; i++)
|
||||||
|
{
|
||||||
|
templbuffer[sampleCount] += outbuf[i];
|
||||||
|
temprbuffer[sampleCount] += outbuf[i];
|
||||||
|
sampleCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
NumberOfSamples--;
|
||||||
|
|
||||||
|
if (NumberOfSamples<=0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
while (NumberOfSamples > 0)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < 9; i++)
|
||||||
|
{
|
||||||
|
inBuffer[i] = g_dspInitialize.pARAM_Read_U8(ARAMAddr);
|
||||||
|
ARAMAddr++;
|
||||||
|
}
|
||||||
|
|
||||||
|
AFCdecodebuffer(m_AFCCoefTable, (char*)inBuffer, outbuf, (short*)&pTest[0x66], (short*)&pTest[0x67], 9);
|
||||||
|
CResampler Sampler(outbuf, 16, 48000);
|
||||||
|
|
||||||
|
while (Sampler.m_queueSize > 0)
|
||||||
|
{
|
||||||
|
int sample = Sampler.sample_queue.front();
|
||||||
|
Sampler.sample_queue.pop();
|
||||||
|
Sampler.m_queueSize -= 1;
|
||||||
|
|
||||||
|
templbuffer[sampleCount] += sample;
|
||||||
|
temprbuffer[sampleCount] += sample;
|
||||||
|
sampleCount++;
|
||||||
|
|
||||||
|
if (sampleCount > _Size)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sampleCount > _Size)
|
||||||
|
break;
|
||||||
|
|
||||||
|
NumberOfSamples--;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if (NumberOfSamples == 0)
|
||||||
|
{
|
||||||
|
pTest[0x01] = 1; // we are done ??
|
||||||
|
}
|
||||||
|
|
||||||
|
// write back
|
||||||
|
NumberOfSamples = (NumberOfSamples << 4); // missing fraction
|
||||||
|
|
||||||
|
pTest[0x38] = ARAMAddr >> 16;
|
||||||
|
pTest[0x39] = ARAMAddr & 0xFFFF;
|
||||||
|
pTest[0x3a] = NumberOfSamples >> 16;
|
||||||
|
pTest[0x3b] = NumberOfSamples & 0xFFFF;
|
||||||
|
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
NumberOfSamples = (NumberOfSamples + 0xf) >> 4;
|
||||||
|
|
||||||
|
static u8 Buffer[500000];
|
||||||
|
for (int i =0; i<NumberOfSamples*9; i++)
|
||||||
|
{
|
||||||
|
Buffer[i] = g_dspInitialize.pARAM_Read_U8(ARAMAddr+i);
|
||||||
|
}
|
||||||
|
|
||||||
|
// yes, the dumps are really zelda sound ;)
|
||||||
|
DumpAFC(Buffer, NumberOfSamples*9, 0x3d00);
|
||||||
|
|
||||||
|
DumpPB(_rPB);
|
||||||
|
|
||||||
|
// exit(1);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// i think pTest[0x3a] and pTest[0x3b] got an update after you have decoded some samples...
|
||||||
|
// just decrement them with the number of samples you have played
|
||||||
|
// and incrrease the ARAM Offset in pTest[0x38], pTest[0x39]
|
||||||
|
|
||||||
|
|
||||||
|
// end of block (Zelda 03b2)
|
||||||
|
if (pTest[0x06] == 0)
|
||||||
|
{
|
||||||
|
// 02a4
|
||||||
|
//
|
||||||
|
|
||||||
|
pTest[0x04] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
ERROR_LOG(DSPHLE, "Zelda Ucode: Unknown PB type %i", _rPB.type);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
|
@ -192,8 +192,9 @@ void GLVertexFormat::SetupVertexPointers() const {
|
||||||
if (vtx_decl.color_offset[i] != -1) {
|
if (vtx_decl.color_offset[i] != -1) {
|
||||||
if (i == 0)
|
if (i == 0)
|
||||||
glColorPointer(4, GL_UNSIGNED_BYTE, vtx_decl.stride, (void *)vtx_decl.color_offset[i]);
|
glColorPointer(4, GL_UNSIGNED_BYTE, vtx_decl.stride, (void *)vtx_decl.color_offset[i]);
|
||||||
else
|
else {
|
||||||
glSecondaryColorPointer(4, GL_UNSIGNED_BYTE, vtx_decl.stride, (void *)vtx_decl.color_offset[i]);
|
glSecondaryColorPointer(4, GL_UNSIGNED_BYTE, vtx_decl.stride, (void *)vtx_decl.color_offset[i]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -252,7 +253,7 @@ void GLVertexFormat::EnableComponents(u32 components)
|
||||||
{
|
{
|
||||||
if ((components & (VB_HAS_COL0 << i)) != (s_prevcomponents & (VB_HAS_COL0 << i)))
|
if ((components & (VB_HAS_COL0 << i)) != (s_prevcomponents & (VB_HAS_COL0 << i)))
|
||||||
{
|
{
|
||||||
if (components & (VB_HAS_COL0 << 0))
|
if (components & (VB_HAS_COL0 << i))
|
||||||
glEnableClientState(i ? GL_SECONDARY_COLOR_ARRAY : GL_COLOR_ARRAY);
|
glEnableClientState(i ? GL_SECONDARY_COLOR_ARRAY : GL_COLOR_ARRAY);
|
||||||
else
|
else
|
||||||
glDisableClientState(i ? GL_SECONDARY_COLOR_ARRAY : GL_COLOR_ARRAY);
|
glDisableClientState(i ? GL_SECONDARY_COLOR_ARRAY : GL_COLOR_ARRAY);
|
||||||
|
|
|
@ -190,7 +190,7 @@ void Flush()
|
||||||
GL_REPORT_ERRORD();
|
GL_REPORT_ERRORD();
|
||||||
|
|
||||||
// setup the pointers
|
// setup the pointers
|
||||||
if(g_nativeVertexFmt)
|
if (g_nativeVertexFmt)
|
||||||
g_nativeVertexFmt->SetupVertexPointers();
|
g_nativeVertexFmt->SetupVertexPointers();
|
||||||
GL_REPORT_ERRORD();
|
GL_REPORT_ERRORD();
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue