start SPU work
This commit is contained in:
parent
28cddadfbc
commit
8d66beba6b
47
src/NDS.cpp
47
src/NDS.cpp
|
@ -25,6 +25,7 @@
|
||||||
#include "DMA.h"
|
#include "DMA.h"
|
||||||
#include "FIFO.h"
|
#include "FIFO.h"
|
||||||
#include "GPU.h"
|
#include "GPU.h"
|
||||||
|
#include "SPU.h"
|
||||||
#include "SPI.h"
|
#include "SPI.h"
|
||||||
#include "RTC.h"
|
#include "RTC.h"
|
||||||
#include "Wifi.h"
|
#include "Wifi.h"
|
||||||
|
@ -37,11 +38,6 @@ namespace NDS
|
||||||
// * stick all the variables in a big structure?
|
// * stick all the variables in a big structure?
|
||||||
// would make it easier to deal with savestates
|
// would make it easier to deal with savestates
|
||||||
|
|
||||||
/*SchedEvent SchedBuffer[SCHED_BUF_LEN];
|
|
||||||
SchedEvent* SchedQueue;
|
|
||||||
|
|
||||||
bool NeedReschedule;*/
|
|
||||||
|
|
||||||
ARM* ARM9;
|
ARM* ARM9;
|
||||||
ARM* ARM7;
|
ARM* ARM7;
|
||||||
|
|
||||||
|
@ -108,8 +104,6 @@ u32 SqrtRes;
|
||||||
|
|
||||||
u32 KeyInput;
|
u32 KeyInput;
|
||||||
|
|
||||||
u16 _soundbias; // temp
|
|
||||||
|
|
||||||
bool Running;
|
bool Running;
|
||||||
|
|
||||||
|
|
||||||
|
@ -132,6 +126,7 @@ bool Init()
|
||||||
|
|
||||||
if (!NDSCart::Init()) return false;
|
if (!NDSCart::Init()) return false;
|
||||||
if (!GPU::Init()) return false;
|
if (!GPU::Init()) return false;
|
||||||
|
if (!SPU::Init()) return false;
|
||||||
if (!SPI::Init()) return false;
|
if (!SPI::Init()) return false;
|
||||||
if (!RTC::Init()) return false;
|
if (!RTC::Init()) return false;
|
||||||
|
|
||||||
|
@ -151,6 +146,7 @@ void DeInit()
|
||||||
|
|
||||||
NDSCart::DeInit();
|
NDSCart::DeInit();
|
||||||
GPU::DeInit();
|
GPU::DeInit();
|
||||||
|
SPU::DeInit();
|
||||||
SPI::DeInit();
|
SPI::DeInit();
|
||||||
RTC::DeInit();
|
RTC::DeInit();
|
||||||
}
|
}
|
||||||
|
@ -300,14 +296,6 @@ void Reset()
|
||||||
for (i = 0; i < 8; i++) DMAs[i]->Reset();
|
for (i = 0; i < 8; i++) DMAs[i]->Reset();
|
||||||
memset(DMA9Fill, 0, 4*4);
|
memset(DMA9Fill, 0, 4*4);
|
||||||
|
|
||||||
NDSCart::Reset();
|
|
||||||
GPU::Reset();
|
|
||||||
SPI::Reset();
|
|
||||||
RTC::Reset();
|
|
||||||
Wifi::Reset();
|
|
||||||
|
|
||||||
// memset(SchedBuffer, 0, sizeof(SchedEvent)*SCHED_BUF_LEN);
|
|
||||||
// SchedQueue = NULL;
|
|
||||||
memset(SchedList, 0, sizeof(SchedList));
|
memset(SchedList, 0, sizeof(SchedList));
|
||||||
SchedListMask = 0;
|
SchedListMask = 0;
|
||||||
|
|
||||||
|
@ -319,7 +307,12 @@ void Reset()
|
||||||
|
|
||||||
KeyInput = 0x007F03FF;
|
KeyInput = 0x007F03FF;
|
||||||
|
|
||||||
_soundbias = 0;
|
NDSCart::Reset();
|
||||||
|
GPU::Reset();
|
||||||
|
SPU::Reset();
|
||||||
|
SPI::Reset();
|
||||||
|
RTC::Reset();
|
||||||
|
Wifi::Reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
void LoadROM(const char* path, bool direct)
|
void LoadROM(const char* path, bool direct)
|
||||||
|
@ -1629,7 +1622,6 @@ void ARM9IOWrite16(u32 addr, u16 val)
|
||||||
{
|
{
|
||||||
SetIRQ(1, IRQ_IPCSync);
|
SetIRQ(1, IRQ_IPCSync);
|
||||||
}
|
}
|
||||||
//CompensateARM7();
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case 0x04000184:
|
case 0x04000184:
|
||||||
|
@ -1901,8 +1893,7 @@ u8 ARM7IORead8(u32 addr)
|
||||||
|
|
||||||
if (addr >= 0x04000400 && addr < 0x04000520)
|
if (addr >= 0x04000400 && addr < 0x04000520)
|
||||||
{
|
{
|
||||||
// sound I/O
|
return SPU::Read8(addr);
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("unknown ARM7 IO read8 %08X\n", addr);
|
printf("unknown ARM7 IO read8 %08X\n", addr);
|
||||||
|
@ -1972,14 +1963,11 @@ u16 ARM7IORead16(u32 addr)
|
||||||
case 0x04000300: return PostFlag7;
|
case 0x04000300: return PostFlag7;
|
||||||
case 0x04000304: return PowerControl7;
|
case 0x04000304: return PowerControl7;
|
||||||
case 0x04000308: return ARM7BIOSProt;
|
case 0x04000308: return ARM7BIOSProt;
|
||||||
|
|
||||||
case 0x04000504: return _soundbias;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (addr >= 0x04000400 && addr < 0x04000520)
|
if (addr >= 0x04000400 && addr < 0x04000520)
|
||||||
{
|
{
|
||||||
// sound I/O
|
return SPU::Read16(addr);
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("unknown ARM7 IO read16 %08X %08X\n", addr, ARM9->R[15]);
|
printf("unknown ARM7 IO read16 %08X %08X\n", addr, ARM9->R[15]);
|
||||||
|
@ -2057,8 +2045,7 @@ u32 ARM7IORead32(u32 addr)
|
||||||
|
|
||||||
if (addr >= 0x04000400 && addr < 0x04000520)
|
if (addr >= 0x04000400 && addr < 0x04000520)
|
||||||
{
|
{
|
||||||
// sound I/O
|
return SPU::Read32(addr);
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("unknown ARM7 IO read32 %08X\n", addr);
|
printf("unknown ARM7 IO read32 %08X\n", addr);
|
||||||
|
@ -2116,7 +2103,7 @@ void ARM7IOWrite8(u32 addr, u8 val)
|
||||||
|
|
||||||
if (addr >= 0x04000400 && addr < 0x04000520)
|
if (addr >= 0x04000400 && addr < 0x04000520)
|
||||||
{
|
{
|
||||||
// sound I/O
|
SPU::Write8(addr, val);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2228,15 +2215,11 @@ void ARM7IOWrite16(u32 addr, u16 val)
|
||||||
if (ARM7BIOSProt == 0)
|
if (ARM7BIOSProt == 0)
|
||||||
ARM7BIOSProt = val;
|
ARM7BIOSProt = val;
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case 0x04000504: // removeme
|
|
||||||
_soundbias = val & 0x3FF;
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (addr >= 0x04000400 && addr < 0x04000520)
|
if (addr >= 0x04000400 && addr < 0x04000520)
|
||||||
{
|
{
|
||||||
// sound I/O
|
SPU::Write16(addr, val);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2326,7 +2309,7 @@ void ARM7IOWrite32(u32 addr, u32 val)
|
||||||
|
|
||||||
if (addr >= 0x04000400 && addr < 0x04000520)
|
if (addr >= 0x04000400 && addr < 0x04000520)
|
||||||
{
|
{
|
||||||
// sound I/O
|
SPU::Write32(addr, val);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
28
src/NDS.h
28
src/NDS.h
|
@ -24,30 +24,11 @@
|
||||||
namespace NDS
|
namespace NDS
|
||||||
{
|
{
|
||||||
|
|
||||||
/*#define SCHED_BUF_LEN 64
|
|
||||||
|
|
||||||
typedef struct _SchedEvent
|
|
||||||
{
|
|
||||||
u32 Delay;
|
|
||||||
void (*Func)(u32);
|
|
||||||
u32 Param;
|
|
||||||
struct _SchedEvent* PrevEvent;
|
|
||||||
struct _SchedEvent* NextEvent;
|
|
||||||
|
|
||||||
} SchedEvent;*/
|
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
Event_LCD = 0,
|
Event_LCD = 0,
|
||||||
|
|
||||||
/*Event_Timer9_0,
|
Event_SPU,
|
||||||
Event_Timer9_1,
|
|
||||||
Event_Timer9_2,
|
|
||||||
Event_Timer9_3,
|
|
||||||
Event_Timer7_0,
|
|
||||||
Event_Timer7_1,
|
|
||||||
Event_Timer7_2,
|
|
||||||
Event_Timer7_3,*/
|
|
||||||
|
|
||||||
Event_MAX
|
Event_MAX
|
||||||
};
|
};
|
||||||
|
@ -95,7 +76,6 @@ typedef struct
|
||||||
u16 Cnt;
|
u16 Cnt;
|
||||||
u32 Counter;
|
u32 Counter;
|
||||||
u32 CycleShift;
|
u32 CycleShift;
|
||||||
//SchedEvent* Event;
|
|
||||||
|
|
||||||
} Timer;
|
} Timer;
|
||||||
|
|
||||||
|
@ -127,15 +107,9 @@ void ReleaseKey(u32 key);
|
||||||
void TouchScreen(u16 x, u16 y);
|
void TouchScreen(u16 x, u16 y);
|
||||||
void ReleaseScreen();
|
void ReleaseScreen();
|
||||||
|
|
||||||
/*SchedEvent* ScheduleEvent(s32 Delay, void (*Func)(u32), u32 Param);
|
|
||||||
void CancelEvent(SchedEvent* event);
|
|
||||||
void RunEvents(s32 cycles);*/
|
|
||||||
void ScheduleEvent(u32 id, bool periodic, s32 delay, void (*func)(u32), u32 param);
|
void ScheduleEvent(u32 id, bool periodic, s32 delay, void (*func)(u32), u32 param);
|
||||||
void CancelEvent(u32 id);
|
void CancelEvent(u32 id);
|
||||||
|
|
||||||
// DO NOT CALL FROM ARM7!!
|
|
||||||
void CompensateARM7();
|
|
||||||
|
|
||||||
void debug(u32 p);
|
void debug(u32 p);
|
||||||
|
|
||||||
void Halt();
|
void Halt();
|
||||||
|
|
265
src/SPU.cpp
265
src/SPU.cpp
|
@ -25,38 +25,269 @@
|
||||||
namespace SPU
|
namespace SPU
|
||||||
{
|
{
|
||||||
|
|
||||||
//SDL_AudioDeviceID device;
|
const u32 OutputBufferSize = 2*1024;
|
||||||
//
|
s16 OutputBuffer[2 * OutputBufferSize];
|
||||||
|
u32 OutputReadOffset;
|
||||||
|
u32 OutputWriteOffset;
|
||||||
|
|
||||||
|
|
||||||
|
u16 Cnt;
|
||||||
|
u8 MasterVolume;
|
||||||
|
u16 Bias;
|
||||||
|
|
||||||
|
Channel* Channels[16];
|
||||||
|
|
||||||
|
|
||||||
bool Init()
|
bool Init()
|
||||||
{
|
{
|
||||||
/*SDL_AudioSpec whatIwant, whatIget;
|
for (int i = 0; i < 16; i++)
|
||||||
|
Channels[i] = new Channel(i);
|
||||||
memset(&whatIwant, 0, sizeof(SDL_AudioSpec));
|
|
||||||
whatIwant.freq = 32824; // 32823.6328125
|
|
||||||
whatIwant.format = AUDIO_S16LSB;
|
|
||||||
whatIwant.channels = 2;
|
|
||||||
whatIwant.samples = 2048;
|
|
||||||
whatIwant.callback = zorp;
|
|
||||||
device = SDL_OpenAudioDevice(NULL, 0, &whatIwant, &whatIget, 0);
|
|
||||||
if (!device)
|
|
||||||
{
|
|
||||||
printf("Audio init failed: %s\n", SDL_GetError());
|
|
||||||
return false;
|
|
||||||
}*/
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeInit()
|
void DeInit()
|
||||||
{
|
{
|
||||||
//if (device) SDL_CloseAudioDevice(device);
|
for (int i = 0; i < 16; i++)
|
||||||
|
delete Channels[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
void Reset()
|
void Reset()
|
||||||
|
{
|
||||||
|
memset(OutputBuffer, 0, 2*OutputBufferSize*2);
|
||||||
|
OutputReadOffset = 0;
|
||||||
|
OutputWriteOffset = 0;
|
||||||
|
|
||||||
|
Cnt = 0;
|
||||||
|
MasterVolume = 0;
|
||||||
|
Bias = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < 16; i++)
|
||||||
|
Channels[i]->Reset();
|
||||||
|
|
||||||
|
NDS::ScheduleEvent(NDS::Event_SPU, true, 1024*16, Mix, 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Channel::Channel(u32 num)
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Channel::~Channel()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
void Channel::Reset()
|
||||||
|
{
|
||||||
|
SetCnt(0);
|
||||||
|
SrcAddr = 0;
|
||||||
|
TimerReload = 0;
|
||||||
|
LoopPos = 0;
|
||||||
|
Length = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Mix(u32 samples)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
|
||||||
|
NDS::ScheduleEvent(NDS::Event_SPU, true, 1024*16, Mix, 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ReadOutput(s16* data, int samples)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < samples; i++)
|
||||||
|
{
|
||||||
|
*data++ = OutputBuffer[OutputReadOffset];
|
||||||
|
*data++ = OutputBuffer[OutputReadOffset + 1];
|
||||||
|
|
||||||
|
if (OutputReadOffset != OutputWriteOffset)
|
||||||
|
{
|
||||||
|
OutputReadOffset += 2;
|
||||||
|
OutputReadOffset &= ((2*OutputBufferSize)-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
u8 Read8(u32 addr)
|
||||||
|
{
|
||||||
|
if (addr < 0x04000500)
|
||||||
|
{
|
||||||
|
Channel* chan = Channels[(addr >> 4) & 0xF];
|
||||||
|
|
||||||
|
switch (addr & 0xF)
|
||||||
|
{
|
||||||
|
case 0x0: return chan->Cnt & 0xFF;
|
||||||
|
case 0x1: return (chan->Cnt >> 8) & 0xFF;
|
||||||
|
case 0x2: return (chan->Cnt >> 16) & 0xFF;
|
||||||
|
case 0x3: return chan->Cnt >> 24;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
switch (addr)
|
||||||
|
{
|
||||||
|
case 0x04000500: return Cnt & 0x7F;
|
||||||
|
case 0x04000501: return Cnt >> 8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("unknown SPU read8 %08X\n", addr);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
u16 Read16(u32 addr)
|
||||||
|
{
|
||||||
|
if (addr < 0x04000500)
|
||||||
|
{
|
||||||
|
Channel* chan = Channels[(addr >> 4) & 0xF];
|
||||||
|
|
||||||
|
switch (addr & 0xF)
|
||||||
|
{
|
||||||
|
case 0x0: return chan->Cnt & 0xFFFF;
|
||||||
|
case 0x2: return chan->Cnt >> 16;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
switch (addr)
|
||||||
|
{
|
||||||
|
case 0x04000500: return Cnt;
|
||||||
|
case 0x04000504: return Bias;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("unknown SPU read16 %08X\n", addr);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 Read32(u32 addr)
|
||||||
|
{
|
||||||
|
if (addr < 0x04000500)
|
||||||
|
{
|
||||||
|
Channel* chan = Channels[(addr >> 4) & 0xF];
|
||||||
|
|
||||||
|
switch (addr & 0xF)
|
||||||
|
{
|
||||||
|
case 0x0: return chan->Cnt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
switch (addr)
|
||||||
|
{
|
||||||
|
case 0x04000500: return Cnt;
|
||||||
|
case 0x04000504: return Bias;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("unknown SPU read32 %08X\n", addr);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Write8(u32 addr, u8 val)
|
||||||
|
{
|
||||||
|
if (addr < 0x04000500)
|
||||||
|
{
|
||||||
|
Channel* chan = Channels[(addr >> 4) & 0xF];
|
||||||
|
|
||||||
|
switch (addr & 0xF)
|
||||||
|
{
|
||||||
|
case 0x0: chan->SetCnt((chan->Cnt & 0xFFFFFF00) | val); return;
|
||||||
|
case 0x1: chan->SetCnt((chan->Cnt & 0xFFFF00FF) | (val << 8)); return;
|
||||||
|
case 0x2: chan->SetCnt((chan->Cnt & 0xFF00FFFF) | (val << 16)); return;
|
||||||
|
case 0x3: chan->SetCnt((chan->Cnt & 0x00FFFFFF) | (val << 24)); return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
switch (addr)
|
||||||
|
{
|
||||||
|
case 0x04000500:
|
||||||
|
Cnt = (Cnt & 0xBF00) | (val & 0x7F);
|
||||||
|
MasterVolume = Cnt & 0x7F;
|
||||||
|
if (MasterVolume == 127) MasterVolume++;
|
||||||
|
return;
|
||||||
|
case 0x04000501:
|
||||||
|
Cnt = (Cnt & 0x007F) | ((val & 0xBF) << 8);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("unknown SPU write8 %08X %02X\n", addr, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Write16(u32 addr, u16 val)
|
||||||
|
{
|
||||||
|
if (addr < 0x04000500)
|
||||||
|
{
|
||||||
|
Channel* chan = Channels[(addr >> 4) & 0xF];
|
||||||
|
|
||||||
|
switch (addr & 0xF)
|
||||||
|
{
|
||||||
|
case 0x0: chan->SetCnt((chan->Cnt & 0xFFFF0000) | val); return;
|
||||||
|
case 0x2: chan->SetCnt((chan->Cnt & 0x0000FFFF) | (val << 16)); return;
|
||||||
|
case 0x8: chan->SetTimerReload(val); return;
|
||||||
|
case 0xA: chan->SetLoopPos(val); return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
switch (addr)
|
||||||
|
{
|
||||||
|
case 0x04000500:
|
||||||
|
Cnt = val & 0xBF7F;
|
||||||
|
MasterVolume = Cnt & 0x7F;
|
||||||
|
if (MasterVolume == 127) MasterVolume++;
|
||||||
|
return;
|
||||||
|
|
||||||
|
case 0x04000504:
|
||||||
|
Bias = val & 0x3FF;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("unknown SPU write16 %08X %04X\n", addr, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Write32(u32 addr, u32 val)
|
||||||
|
{
|
||||||
|
if (addr < 0x04000500)
|
||||||
|
{
|
||||||
|
Channel* chan = Channels[(addr >> 4) & 0xF];
|
||||||
|
|
||||||
|
switch (addr & 0xF)
|
||||||
|
{
|
||||||
|
case 0x0: chan->SetCnt(val); return;
|
||||||
|
case 0x4: chan->SetSrcAddr(val); return;
|
||||||
|
case 0x8:
|
||||||
|
chan->SetTimerReload(val & 0xFFFF);
|
||||||
|
chan->SetLoopPos(val >> 16);
|
||||||
|
return;
|
||||||
|
case 0xC: chan->SetLength(val); return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
switch (addr)
|
||||||
|
{
|
||||||
|
case 0x04000500:
|
||||||
|
Cnt = val & 0xBF7F;
|
||||||
|
MasterVolume = Cnt & 0x7F;
|
||||||
|
if (MasterVolume == 127) MasterVolume++;
|
||||||
|
return;
|
||||||
|
|
||||||
|
case 0x04000504:
|
||||||
|
Bias = val & 0x3FF;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("unknown SPU write32 %08X %08X\n", addr, val);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
35
src/SPU.h
35
src/SPU.h
|
@ -26,6 +26,41 @@ bool Init();
|
||||||
void DeInit();
|
void DeInit();
|
||||||
void Reset();
|
void Reset();
|
||||||
|
|
||||||
|
void Mix(u32 samples);
|
||||||
|
|
||||||
|
void ReadOutput(s16* data, int samples);
|
||||||
|
|
||||||
|
u8 Read8(u32 addr);
|
||||||
|
u16 Read16(u32 addr);
|
||||||
|
u32 Read32(u32 addr);
|
||||||
|
void Write8(u32 addr, u8 val);
|
||||||
|
void Write16(u32 addr, u16 val);
|
||||||
|
void Write32(u32 addr, u32 val);
|
||||||
|
|
||||||
|
class Channel
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Channel(u32 num);
|
||||||
|
~Channel();
|
||||||
|
void Reset();
|
||||||
|
|
||||||
|
u32 Cnt;
|
||||||
|
u32 SrcAddr;
|
||||||
|
u16 TimerReload;
|
||||||
|
u32 LoopPos;
|
||||||
|
u32 Length;
|
||||||
|
|
||||||
|
void SetCnt(u32 val)
|
||||||
|
{
|
||||||
|
Cnt = val & 0xFF7F837F;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetSrcAddr(u32 val) { SrcAddr = val & 0x07FFFFFF; }
|
||||||
|
void SetTimerReload(u32 val) { TimerReload = val & 0xFFFF; }
|
||||||
|
void SetLoopPos(u32 val) { LoopPos = (val & 0xFFFF) << 2; }
|
||||||
|
void SetLength(u32 val) { Length = (val & 0x001FFFFF) << 2; }
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // SPU_H
|
#endif // SPU_H
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#include "../Config.h"
|
#include "../Config.h"
|
||||||
#include "../NDS.h"
|
#include "../NDS.h"
|
||||||
#include "../GPU.h"
|
#include "../GPU.h"
|
||||||
|
#include "../SPU.h"
|
||||||
|
|
||||||
#include "InputConfig.h"
|
#include "InputConfig.h"
|
||||||
#include "EmuConfig.h"
|
#include "EmuConfig.h"
|
||||||
|
@ -313,6 +314,11 @@ EmuThread::~EmuThread()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void AudioCallback(void* data, Uint8* stream, int len)
|
||||||
|
{
|
||||||
|
SPU::ReadOutput((s16*)stream, len>>2);
|
||||||
|
}
|
||||||
|
|
||||||
wxThread::ExitCode EmuThread::Entry()
|
wxThread::ExitCode EmuThread::Entry()
|
||||||
{
|
{
|
||||||
emustatus = 3;
|
emustatus = 3;
|
||||||
|
@ -344,6 +350,23 @@ wxThread::ExitCode EmuThread::Entry()
|
||||||
botdst.x = 0; botdst.y = 192;
|
botdst.x = 0; botdst.y = 192;
|
||||||
botdst.w = 256; botdst.h = 192;
|
botdst.w = 256; botdst.h = 192;
|
||||||
|
|
||||||
|
SDL_AudioSpec whatIwant, whatIget;
|
||||||
|
memset(&whatIwant, 0, sizeof(SDL_AudioSpec));
|
||||||
|
whatIwant.freq = 32824; // 32823.6328125
|
||||||
|
whatIwant.format = AUDIO_S16LSB;
|
||||||
|
whatIwant.channels = 2;
|
||||||
|
whatIwant.samples = 1024;
|
||||||
|
whatIwant.callback = AudioCallback;
|
||||||
|
audio = SDL_OpenAudioDevice(NULL, 0, &whatIwant, &whatIget, 0);
|
||||||
|
if (!audio)
|
||||||
|
{
|
||||||
|
printf("Audio init failed: %s\n", SDL_GetError());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SDL_PauseAudioDevice(audio, 0);
|
||||||
|
}
|
||||||
|
|
||||||
Touching = false;
|
Touching = false;
|
||||||
axismask = 0;
|
axismask = 0;
|
||||||
|
|
||||||
|
@ -433,6 +456,8 @@ wxThread::ExitCode EmuThread::Entry()
|
||||||
|
|
||||||
emupaused = true;
|
emupaused = true;
|
||||||
|
|
||||||
|
if (audio) SDL_CloseAudioDevice(audio);
|
||||||
|
|
||||||
SDL_DestroyTexture(sdltex);
|
SDL_DestroyTexture(sdltex);
|
||||||
SDL_DestroyRenderer(sdlrend);
|
SDL_DestroyRenderer(sdlrend);
|
||||||
SDL_DestroyWindow(sdlwin);
|
SDL_DestroyWindow(sdlwin);
|
||||||
|
|
|
@ -105,6 +105,8 @@ protected:
|
||||||
SDL_Rect topsrc, topdst;
|
SDL_Rect topsrc, topdst;
|
||||||
SDL_Rect botsrc, botdst;
|
SDL_Rect botsrc, botdst;
|
||||||
|
|
||||||
|
SDL_AudioDeviceID audio;
|
||||||
|
|
||||||
bool Touching;
|
bool Touching;
|
||||||
int txoffset, tyoffset;
|
int txoffset, tyoffset;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue