diff --git a/README.md b/README.md
index 8df34df2..09216f4c 100644
--- a/README.md
+++ b/README.md
@@ -2,7 +2,7 @@
melonDS
-
+
diff --git a/melon.rc b/melon.rc
index dae2772c..23e3df70 100644
--- a/melon.rc
+++ b/melon.rc
@@ -6,8 +6,8 @@
//include version information in .exe, modify these values to match your needs
1 VERSIONINFO
-FILEVERSION 0,9,0,0
-PRODUCTVERSION 0,9,0,0
+FILEVERSION 0,9,1,0
+PRODUCTVERSION 0,9,1,0
FILETYPE VFT_APP
{
BLOCK "StringFileInfo"
@@ -15,14 +15,14 @@ FILETYPE VFT_APP
BLOCK "040904E4"
{
VALUE "CompanyName", "Melon Factory of Kuribo64"
- VALUE "FileVersion", "0.9"
+ VALUE "FileVersion", "0.9.1"
VALUE "FileDescription", "DS emulator, sorta. also 1st quality melon."
VALUE "InternalName", "SDnolem"
VALUE "LegalCopyright", "2016-2020 Arisotura & co."
VALUE "LegalTrademarks", ""
VALUE "OriginalFilename", "zafkflzdasd.exe"
VALUE "ProductName", "melonDS"
- VALUE "ProductVersion", "0.9"
+ VALUE "ProductVersion", "0.9.1"
}
}
BLOCK "VarFileInfo"
diff --git a/src/ARCodeFile.h b/src/ARCodeFile.h
index 374c56e5..56dfff7c 100644
--- a/src/ARCodeFile.h
+++ b/src/ARCodeFile.h
@@ -23,23 +23,21 @@
#include "types.h"
-typedef struct
+struct ARCode
{
char Name[128];
bool Enabled;
u32 CodeLen;
u32 Code[2*64];
-
-} ARCode;
+};
typedef std::list ARCodeList;
-typedef struct
+struct ARCodeCat
{
char Name[128];
ARCodeList Codes;
-
-} ARCodeCat;
+};
typedef std::list ARCodeCatList;
diff --git a/src/ARMJIT_A64/ARMJIT_Linkage.S b/src/ARMJIT_A64/ARMJIT_Linkage.S
index 78863155..58b53999 100644
--- a/src/ARMJIT_A64/ARMJIT_Linkage.S
+++ b/src/ARMJIT_A64/ARMJIT_Linkage.S
@@ -8,8 +8,13 @@
.p2align 4,,15
+#ifdef __APPLE__
+.global _ARM_Dispatch
+_ARM_Dispatch:
+#else
.global ARM_Dispatch
ARM_Dispatch:
+#endif
stp x19, x20, [sp, #-96]!
stp x21, x22, [sp, #16]
stp x23, x24, [sp, #32]
@@ -25,8 +30,13 @@ ARM_Dispatch:
.p2align 4,,15
+#ifdef __APPLE__
+.global _ARM_Ret
+_ARM_Ret:
+#else
.global ARM_Ret
ARM_Ret:
+#endif
str RCycles, [RCPU, ARM_Cycles_offset]
str RCPSR, [RCPU, ARM_CPSR_offset]
@@ -65,4 +75,4 @@ ARM_RestoreContext:
ldp x17, x18, [sp, #248]
mov sp, x17
- br x18
\ No newline at end of file
+ br x18
diff --git a/src/Config.h b/src/Config.h
index 9fd7488b..9671f16d 100644
--- a/src/Config.h
+++ b/src/Config.h
@@ -26,7 +26,7 @@
namespace Config
{
-typedef struct
+struct ConfigEntry
{
char Name[32];
int Type;
@@ -34,8 +34,7 @@ typedef struct
int DefaultInt;
const char* DefaultStr;
int StrLength; // should be set to actual array length minus one
-
-} ConfigEntry;
+};
FILE* GetConfigFile(const char* fileName, const char* permissions);
bool HasConfigFile(const char* fileName);
diff --git a/src/DSi_AES.cpp b/src/DSi_AES.cpp
index 8f5c3f3f..9153e907 100644
--- a/src/DSi_AES.cpp
+++ b/src/DSi_AES.cpp
@@ -38,8 +38,8 @@ bool OutputFlush;
u32 InputDMASize, OutputDMASize;
u32 AESMode;
-FIFO* InputFIFO;
-FIFO* OutputFIFO;
+FIFO InputFIFO;
+FIFO OutputFIFO;
u8 IV[16];
@@ -91,9 +91,6 @@ void ROL16(u8* val, u32 n)
bool Init()
{
- InputFIFO = new FIFO(16);
- OutputFIFO = new FIFO(16);
-
const u8 zero[16] = {0};
AES_init_ctx_iv(&Ctx, zero, zero);
@@ -102,8 +99,6 @@ bool Init()
void DeInit()
{
- delete InputFIFO;
- delete OutputFIFO;
}
void Reset()
@@ -119,8 +114,8 @@ void Reset()
OutputDMASize = 0;
AESMode = 0;
- InputFIFO->Clear();
- OutputFIFO->Clear();
+ InputFIFO.Clear();
+ OutputFIFO.Clear();
memset(IV, 0, sizeof(IV));
@@ -164,10 +159,10 @@ void ProcessBlock_CCM_Decrypt()
u8 data[16];
u8 data_rev[16];
- *(u32*)&data[0] = InputFIFO->Read();
- *(u32*)&data[4] = InputFIFO->Read();
- *(u32*)&data[8] = InputFIFO->Read();
- *(u32*)&data[12] = InputFIFO->Read();
+ *(u32*)&data[0] = InputFIFO.Read();
+ *(u32*)&data[4] = InputFIFO.Read();
+ *(u32*)&data[8] = InputFIFO.Read();
+ *(u32*)&data[12] = InputFIFO.Read();
//printf("AES-CCM: "); _printhex2(data, 16);
@@ -181,10 +176,10 @@ void ProcessBlock_CCM_Decrypt()
//printf(" -> "); _printhex2(data, 16);
- OutputFIFO->Write(*(u32*)&data[0]);
- OutputFIFO->Write(*(u32*)&data[4]);
- OutputFIFO->Write(*(u32*)&data[8]);
- OutputFIFO->Write(*(u32*)&data[12]);
+ OutputFIFO.Write(*(u32*)&data[0]);
+ OutputFIFO.Write(*(u32*)&data[4]);
+ OutputFIFO.Write(*(u32*)&data[8]);
+ OutputFIFO.Write(*(u32*)&data[12]);
}
void ProcessBlock_CCM_Encrypt()
@@ -192,10 +187,10 @@ void ProcessBlock_CCM_Encrypt()
u8 data[16];
u8 data_rev[16];
- *(u32*)&data[0] = InputFIFO->Read();
- *(u32*)&data[4] = InputFIFO->Read();
- *(u32*)&data[8] = InputFIFO->Read();
- *(u32*)&data[12] = InputFIFO->Read();
+ *(u32*)&data[0] = InputFIFO.Read();
+ *(u32*)&data[4] = InputFIFO.Read();
+ *(u32*)&data[8] = InputFIFO.Read();
+ *(u32*)&data[12] = InputFIFO.Read();
//printf("AES-CCM: "); _printhex2(data, 16);
@@ -209,10 +204,10 @@ void ProcessBlock_CCM_Encrypt()
//printf(" -> "); _printhex2(data, 16);
- OutputFIFO->Write(*(u32*)&data[0]);
- OutputFIFO->Write(*(u32*)&data[4]);
- OutputFIFO->Write(*(u32*)&data[8]);
- OutputFIFO->Write(*(u32*)&data[12]);
+ OutputFIFO.Write(*(u32*)&data[0]);
+ OutputFIFO.Write(*(u32*)&data[4]);
+ OutputFIFO.Write(*(u32*)&data[8]);
+ OutputFIFO.Write(*(u32*)&data[12]);
}
void ProcessBlock_CTR()
@@ -220,10 +215,10 @@ void ProcessBlock_CTR()
u8 data[16];
u8 data_rev[16];
- *(u32*)&data[0] = InputFIFO->Read();
- *(u32*)&data[4] = InputFIFO->Read();
- *(u32*)&data[8] = InputFIFO->Read();
- *(u32*)&data[12] = InputFIFO->Read();
+ *(u32*)&data[0] = InputFIFO.Read();
+ *(u32*)&data[4] = InputFIFO.Read();
+ *(u32*)&data[8] = InputFIFO.Read();
+ *(u32*)&data[12] = InputFIFO.Read();
//printf("AES-CTR: "); _printhex2(data, 16);
@@ -233,10 +228,10 @@ void ProcessBlock_CTR()
//printf(" -> "); _printhex(data, 16);
- OutputFIFO->Write(*(u32*)&data[0]);
- OutputFIFO->Write(*(u32*)&data[4]);
- OutputFIFO->Write(*(u32*)&data[8]);
- OutputFIFO->Write(*(u32*)&data[12]);
+ OutputFIFO.Write(*(u32*)&data[0]);
+ OutputFIFO.Write(*(u32*)&data[4]);
+ OutputFIFO.Write(*(u32*)&data[8]);
+ OutputFIFO.Write(*(u32*)&data[12]);
}
@@ -244,8 +239,8 @@ u32 ReadCnt()
{
u32 ret = Cnt;
- ret |= InputFIFO->Level();
- ret |= (OutputFIFO->Level() << 5);
+ ret |= InputFIFO.Level();
+ ret |= (OutputFIFO.Level() << 5);
return ret;
}
@@ -341,9 +336,9 @@ void WriteBlkCnt(u32 val)
u32 ReadOutputFIFO()
{
- if (OutputFIFO->IsEmpty()) printf("!!! AES OUTPUT FIFO EMPTY\n");
+ if (OutputFIFO.IsEmpty()) printf("!!! AES OUTPUT FIFO EMPTY\n");
- u32 ret = OutputFIFO->Read();
+ u32 ret = OutputFIFO.Read();
if (Cnt & (1<<31))
{
@@ -352,17 +347,17 @@ u32 ReadOutputFIFO()
}
else
{
- if (OutputFIFO->Level() > 0)
+ if (OutputFIFO.Level() > 0)
DSi::CheckNDMAs(1, 0x2B);
else
DSi::StopNDMAs(1, 0x2B);
- if (OutputMACDue && OutputFIFO->Level() <= 12)
+ if (OutputMACDue && OutputFIFO.Level() <= 12)
{
- OutputFIFO->Write(*(u32*)&OutputMAC[0]);
- OutputFIFO->Write(*(u32*)&OutputMAC[4]);
- OutputFIFO->Write(*(u32*)&OutputMAC[8]);
- OutputFIFO->Write(*(u32*)&OutputMAC[12]);
+ OutputFIFO.Write(*(u32*)&OutputMAC[0]);
+ OutputFIFO.Write(*(u32*)&OutputMAC[4]);
+ OutputFIFO.Write(*(u32*)&OutputMAC[8]);
+ OutputFIFO.Write(*(u32*)&OutputMAC[12]);
OutputMACDue = false;
}
}
@@ -374,9 +369,9 @@ void WriteInputFIFO(u32 val)
{
// TODO: add some delay to processing
- if (InputFIFO->IsFull()) printf("!!! AES INPUT FIFO FULL\n");
+ if (InputFIFO.IsFull()) printf("!!! AES INPUT FIFO FULL\n");
- InputFIFO->Write(val);
+ InputFIFO.Write(val);
if (!(Cnt & (1<<31))) return;
@@ -387,7 +382,7 @@ void CheckInputDMA()
{
if (RemBlocks == 0) return;
- if (InputFIFO->Level() <= InputDMASize)
+ if (InputFIFO.Level() <= InputDMASize)
{
// trigger input DMA
DSi::CheckNDMAs(1, 0x2A);
@@ -398,7 +393,7 @@ void CheckInputDMA()
void CheckOutputDMA()
{
- if (OutputFIFO->Level() >= OutputDMASize)
+ if (OutputFIFO.Level() >= OutputDMASize)
{
// trigger output DMA
DSi::CheckNDMAs(1, 0x2B);
@@ -407,7 +402,7 @@ void CheckOutputDMA()
void Update()
{
- while (InputFIFO->Level() >= 4 && OutputFIFO->Level() <= 12 && RemBlocks > 0)
+ while (InputFIFO.Level() >= 4 && OutputFIFO.Level() <= 12 && RemBlocks > 0)
{
switch (AESMode)
{
@@ -463,7 +458,7 @@ void Update()
if (Cnt & (1<<30)) NDS::SetIRQ2(NDS::IRQ2_DSi_AES);
DSi::StopNDMAs(1, 0x2A);
- if (OutputFIFO->Level() > 0)
+ if (!OutputFIFO.IsEmpty())
DSi::CheckNDMAs(1, 0x2B);
else
DSi::StopNDMAs(1, 0x2B);
diff --git a/src/DSi_Camera.cpp b/src/DSi_Camera.cpp
index 79cfe3fd..cfb3b8dd 100644
--- a/src/DSi_Camera.cpp
+++ b/src/DSi_Camera.cpp
@@ -303,7 +303,7 @@ u8 DSi_Camera::Read8(u32 addr)
}
u16 DSi_Camera::Read16(u32 addr)
-{printf("CAM READ %08X %08X\n", addr, NDS::GetPC(0));
+{
switch (addr)
{
case 0x04004200: return ModuleCnt;
@@ -313,15 +313,16 @@ u16 DSi_Camera::Read16(u32 addr)
printf("unknown DSi cam read16 %08X\n", addr);
return 0;
}
-u32 dorp = 0;
+
u32 DSi_Camera::Read32(u32 addr)
{
switch (addr)
{
case 0x04004204:
{
+ // TODO
return 0xFC00801F;
- if (!(Cnt & (1<<15))) return 0; // CHECKME
+ /*if (!(Cnt & (1<<15))) return 0; // CHECKME
u32 ret = *(u32*)&FrameBuffer[TransferPos];
TransferPos += 4;
if (TransferPos >= FrameLength) TransferPos = 0;
@@ -332,7 +333,7 @@ u32 DSi_Camera::Read32(u32 addr)
dorp = 0;
Cnt &= ~(1<<4);
}
- return ret;
+ return ret;*/
}
}
@@ -348,7 +349,7 @@ void DSi_Camera::Write8(u32 addr, u8 val)
}
void DSi_Camera::Write16(u32 addr, u16 val)
-{printf("CAM WRITE %08X %04X %08X\n", addr, val, NDS::GetPC(0));
+{
switch (addr)
{
case 0x04004200:
diff --git a/src/DSi_NWifi.cpp b/src/DSi_NWifi.cpp
index 54719cf7..8b659319 100644
--- a/src/DSi_NWifi.cpp
+++ b/src/DSi_NWifi.cpp
@@ -116,18 +116,20 @@ const u8 CIS1[256] =
DSi_NWifi* Ctx = nullptr;
-DSi_NWifi::DSi_NWifi(DSi_SDHost* host) : DSi_SDDevice(host)
+DSi_NWifi::DSi_NWifi(DSi_SDHost* host)
+ : DSi_SDDevice(host),
+ Mailbox
+ {
+ // HACK
+ // the mailboxes are supposed to be 0x80 bytes
+ // however, as we do things instantly, emulating this is meaningless
+ // and only adds complication
+ DynamicFIFO(0x600), DynamicFIFO(0x600), DynamicFIFO(0x600), DynamicFIFO(0x600),
+ DynamicFIFO(0x600), DynamicFIFO(0x600), DynamicFIFO(0x600), DynamicFIFO(0x600),
+ // mailbox 8: extra mailbox acting as a bigger RX buffer
+ DynamicFIFO(0x8000)
+ }
{
- // HACK
- // the mailboxes are supposed to be 0x80 bytes
- // however, as we do things instantly, emulating this is meaningless
- // and only adds complication
- for (int i = 0; i < 8; i++)
- Mailbox[i] = new FIFO(0x600);//0x80);
-
- // extra mailbox acting as a bigger RX buffer
- Mailbox[8] = new FIFO(0x8000);
-
// this seems to control whether the firmware upload is done
EEPROMReady = 0;
@@ -136,9 +138,6 @@ DSi_NWifi::DSi_NWifi(DSi_SDHost* host) : DSi_SDDevice(host)
DSi_NWifi::~DSi_NWifi()
{
- for (int i = 0; i < 9; i++)
- delete Mailbox[i];
-
NDS::CancelEvent(NDS::Event_DSi_NWifi);
Ctx = nullptr;
}
@@ -159,7 +158,7 @@ void DSi_NWifi::Reset()
WindowWriteAddr = 0;
for (int i = 0; i < 9; i++)
- Mailbox[i]->Clear();
+ Mailbox[i].Clear();
u8* mac = SPI_Firmware::GetWifiMAC();
printf("NWifi MAC: %02X:%02X:%02X:%02X:%02X:%02X\n",
@@ -250,10 +249,10 @@ void DSi_NWifi::UpdateIRQ_F1()
{
F1_IRQStatus = 0;
- if (!Mailbox[4]->IsEmpty()) F1_IRQStatus |= (1<<0);
- if (!Mailbox[5]->IsEmpty()) F1_IRQStatus |= (1<<1);
- if (!Mailbox[6]->IsEmpty()) F1_IRQStatus |= (1<<2);
- if (!Mailbox[7]->IsEmpty()) F1_IRQStatus |= (1<<3);
+ if (!Mailbox[4].IsEmpty()) F1_IRQStatus |= (1<<0);
+ if (!Mailbox[5].IsEmpty()) F1_IRQStatus |= (1<<1);
+ if (!Mailbox[6].IsEmpty()) F1_IRQStatus |= (1<<2);
+ if (!Mailbox[7].IsEmpty()) F1_IRQStatus |= (1<<3);
if (F1_IRQStatus_Counter & F1_IRQEnable_Counter) F1_IRQStatus |= (1<<4);
if (F1_IRQStatus_CPU & F1_IRQEnable_CPU) F1_IRQStatus |= (1<<6);
if (F1_IRQStatus_Error & F1_IRQEnable_Error) F1_IRQStatus |= (1<<7);
@@ -337,26 +336,26 @@ u8 DSi_NWifi::F1_Read(u32 addr)
{
if (addr < 0x100)
{
- u8 ret = Mailbox[4]->Read();
+ u8 ret = Mailbox[4].Read();
if (addr == 0xFF) DrainRXBuffer();
UpdateIRQ_F1();
return ret;
}
else if (addr < 0x200)
{
- u8 ret = Mailbox[5]->Read();
+ u8 ret = Mailbox[5].Read();
UpdateIRQ_F1();
return ret;
}
else if (addr < 0x300)
{
- u8 ret = Mailbox[6]->Read();
+ u8 ret = Mailbox[6].Read();
UpdateIRQ_F1();
return ret;
}
else if (addr < 0x400)
{
- u8 ret = Mailbox[7]->Read();
+ u8 ret = Mailbox[7].Read();
UpdateIRQ_F1();
return ret;
}
@@ -373,18 +372,18 @@ u8 DSi_NWifi::F1_Read(u32 addr)
{
u8 ret = 0;
- if (Mailbox[4]->Level() >= 4) ret |= (1<<0);
- if (Mailbox[5]->Level() >= 4) ret |= (1<<1);
- if (Mailbox[6]->Level() >= 4) ret |= (1<<2);
- if (Mailbox[7]->Level() >= 4) ret |= (1<<3);
+ if (Mailbox[4].Level() >= 4) ret |= (1<<0);
+ if (Mailbox[5].Level() >= 4) ret |= (1<<1);
+ if (Mailbox[6].Level() >= 4) ret |= (1<<2);
+ if (Mailbox[7].Level() >= 4) ret |= (1<<3);
return ret;
}
- case 0x00408: return Mailbox[4]->Peek(0);
- case 0x00409: return Mailbox[4]->Peek(1);
- case 0x0040A: return Mailbox[4]->Peek(2);
- case 0x0040B: return Mailbox[4]->Peek(3);
+ case 0x00408: return Mailbox[4].Peek(0);
+ case 0x00409: return Mailbox[4].Peek(1);
+ case 0x0040A: return Mailbox[4].Peek(2);
+ case 0x0040B: return Mailbox[4].Peek(3);
case 0x00418: return F1_IRQEnable;
case 0x00419: return F1_IRQEnable_CPU;
@@ -403,32 +402,32 @@ u8 DSi_NWifi::F1_Read(u32 addr)
}
else if (addr < 0x1000)
{
- u8 ret = Mailbox[4]->Read();
+ u8 ret = Mailbox[4].Read();
if (addr == 0xFFF) DrainRXBuffer();
UpdateIRQ_F1();
return ret;
}
else if (addr < 0x1800)
{
- u8 ret = Mailbox[5]->Read();
+ u8 ret = Mailbox[5].Read();
UpdateIRQ_F1();
return ret;
}
else if (addr < 0x2000)
{
- u8 ret = Mailbox[6]->Read();
+ u8 ret = Mailbox[6].Read();
UpdateIRQ_F1();
return ret;
}
else if (addr < 0x2800)
{
- u8 ret = Mailbox[7]->Read();
+ u8 ret = Mailbox[7].Read();
UpdateIRQ_F1();
return ret;
}
else
{
- u8 ret = Mailbox[4]->Read();
+ u8 ret = Mailbox[4].Read();
if (addr == 0x3FFF) DrainRXBuffer();
UpdateIRQ_F1();
return ret;
@@ -442,30 +441,30 @@ void DSi_NWifi::F1_Write(u32 addr, u8 val)
{
if (addr < 0x100)
{
- if (Mailbox[0]->IsFull()) printf("!!! NWIFI: MBOX0 FULL\n");
- Mailbox[0]->Write(val);
+ if (Mailbox[0].IsFull()) printf("!!! NWIFI: MBOX0 FULL\n");
+ Mailbox[0].Write(val);
if (addr == 0xFF) HandleCommand();
UpdateIRQ_F1();
return;
}
else if (addr < 0x200)
{
- if (Mailbox[1]->IsFull()) printf("!!! NWIFI: MBOX1 FULL\n");
- Mailbox[1]->Write(val);
+ if (Mailbox[1].IsFull()) printf("!!! NWIFI: MBOX1 FULL\n");
+ Mailbox[1].Write(val);
UpdateIRQ_F1();
return;
}
else if (addr < 0x300)
{
- if (Mailbox[2]->IsFull()) printf("!!! NWIFI: MBOX2 FULL\n");
- Mailbox[2]->Write(val);
+ if (Mailbox[2].IsFull()) printf("!!! NWIFI: MBOX2 FULL\n");
+ Mailbox[2].Write(val);
UpdateIRQ_F1();
return;
}
else if (addr < 0x400)
{
- if (Mailbox[3]->IsFull()) printf("!!! NWIFI: MBOX3 FULL\n");
- Mailbox[3]->Write(val);
+ if (Mailbox[3].IsFull()) printf("!!! NWIFI: MBOX3 FULL\n");
+ Mailbox[3].Write(val);
UpdateIRQ_F1();
return;
}
@@ -505,37 +504,37 @@ void DSi_NWifi::F1_Write(u32 addr, u8 val)
}
else if (addr < 0x1000)
{
- if (Mailbox[0]->IsFull()) printf("!!! NWIFI: MBOX0 FULL\n");
- Mailbox[0]->Write(val);
+ if (Mailbox[0].IsFull()) printf("!!! NWIFI: MBOX0 FULL\n");
+ Mailbox[0].Write(val);
if (addr == 0xFFF) HandleCommand();
UpdateIRQ_F1();
return;
}
else if (addr < 0x1800)
{
- if (Mailbox[1]->IsFull()) printf("!!! NWIFI: MBOX1 FULL\n");
- Mailbox[1]->Write(val);
+ if (Mailbox[1].IsFull()) printf("!!! NWIFI: MBOX1 FULL\n");
+ Mailbox[1].Write(val);
UpdateIRQ_F1();
return;
}
else if (addr < 0x2000)
{
- if (Mailbox[2]->IsFull()) printf("!!! NWIFI: MBOX2 FULL\n");
- Mailbox[2]->Write(val);
+ if (Mailbox[2].IsFull()) printf("!!! NWIFI: MBOX2 FULL\n");
+ Mailbox[2].Write(val);
UpdateIRQ_F1();
return;
}
else if (addr < 0x2800)
{
- if (Mailbox[3]->IsFull()) printf("!!! NWIFI: MBOX3 FULL\n");
- Mailbox[3]->Write(val);
+ if (Mailbox[3].IsFull()) printf("!!! NWIFI: MBOX3 FULL\n");
+ Mailbox[3].Write(val);
UpdateIRQ_F1();
return;
}
else
{
- if (Mailbox[0]->IsFull()) printf("!!! NWIFI: MBOX0 FULL\n");
- Mailbox[0]->Write(val);
+ if (Mailbox[0].IsFull()) printf("!!! NWIFI: MBOX0 FULL\n");
+ Mailbox[0].Write(val);
if (addr == 0x3FFF) HandleCommand(); // CHECKME
UpdateIRQ_F1();
return;
@@ -750,7 +749,7 @@ void DSi_NWifi::BMI_Command()
for (int i = 0; i < len; i++)
{
- u8 val = Mailbox[0]->Read();
+ u8 val = Mailbox[0].Read();
// TODO: do something with it!!
}
@@ -804,7 +803,7 @@ void DSi_NWifi::BMI_Command()
for (int i = 0; i < len; i++)
{
- u8 val = Mailbox[0]->Read();
+ u8 val = Mailbox[0].Read();
// TODO: do something with it!!
//fwrite(&val, 1, 1, f);
@@ -873,7 +872,7 @@ void DSi_NWifi::HTC_Command()
printf("unknown HTC command %04X\n", cmd);
for (int i = 0; i < len; i++)
{
- printf("%02X ", Mailbox[0]->Read());
+ printf("%02X ", Mailbox[0].Read());
if ((i&0xF)==0xF) printf("\n");
}
printf("\n");
@@ -926,7 +925,7 @@ void DSi_NWifi::WMI_Command()
case 0x0004: // synchronize
{
- Mailbox[0]->Read();
+ Mailbox[0].Read();
// TODO??
}
break;
@@ -944,8 +943,8 @@ void DSi_NWifi::WMI_Command()
u32 legacy = MB_Read32(0);
u32 scantime = MB_Read32(0);
u32 forceinterval = MB_Read32(0);
- u8 scantype = Mailbox[0]->Read();
- u8 nchannels = Mailbox[0]->Read();
+ u8 scantype = Mailbox[0].Read();
+ u8 nchannels = Mailbox[0].Read();
printf("WMI: start scan, forceFG=%d, legacy=%d, scanTime=%d, interval=%d, scanType=%d, chan=%d\n",
forcefg, legacy, scantime, forceinterval, scantype, nchannels);
@@ -969,10 +968,10 @@ void DSi_NWifi::WMI_Command()
case 0x0009: // set BSS filter
{
// TODO: do something with the params!!
- u8 bssfilter = Mailbox[0]->Read();
- Mailbox[0]->Read();
- Mailbox[0]->Read();
- Mailbox[0]->Read();
+ u8 bssfilter = Mailbox[0].Read();
+ Mailbox[0].Read();
+ Mailbox[0].Read();
+ Mailbox[0].Read();
u32 iemask = MB_Read32(0);
printf("WMI: set BSS filter, filter=%02X, iemask=%08X\n", bssfilter, iemask);
@@ -981,13 +980,13 @@ void DSi_NWifi::WMI_Command()
case 0x000A: // set probed BSSID
{
- u8 id = Mailbox[0]->Read();
- u8 flags = Mailbox[0]->Read();
- u8 len = Mailbox[0]->Read();
+ u8 id = Mailbox[0].Read();
+ u8 flags = Mailbox[0].Read();
+ u8 len = Mailbox[0].Read();
char ssid[33] = {0};
for (int i = 0; i < len && i < 32; i++)
- ssid[i] = Mailbox[0]->Read();
+ ssid[i] = Mailbox[0].Read();
// TODO: store it somewhere
printf("WMI: set probed SSID: id=%d, flags=%02X, len=%d, SSID=%s\n", id, flags, len, ssid);
@@ -996,7 +995,7 @@ void DSi_NWifi::WMI_Command()
case 0x000D: // set disconnect timeout
{
- Mailbox[0]->Read();
+ Mailbox[0].Read();
// TODO??
}
break;
@@ -1018,10 +1017,10 @@ void DSi_NWifi::WMI_Command()
case 0x0011: // set channel params
{
- Mailbox[0]->Read();
- u8 scan = Mailbox[0]->Read();
- u8 phymode = Mailbox[0]->Read();
- u8 len = Mailbox[0]->Read();
+ Mailbox[0].Read();
+ u8 scan = Mailbox[0].Read();
+ u8 phymode = Mailbox[0].Read();
+ u8 len = Mailbox[0].Read();
u16 channels[32];
for (int i = 0; i < len && i < 32; i++)
@@ -1037,13 +1036,13 @@ void DSi_NWifi::WMI_Command()
case 0x0012: // set power mode
{
- Mailbox[0]->Read();
+ Mailbox[0].Read();
// TODO??
}
break;
case 0x0017: // dummy?
- Mailbox[0]->Read();
+ Mailbox[0].Read();
break;
case 0x0022: // set error bitmask
@@ -1080,14 +1079,14 @@ void DSi_NWifi::WMI_Command()
case 0x003D: // set keepalive interval
{
- Mailbox[0]->Read();
+ Mailbox[0].Read();
// TODO??
}
break;
case 0x0041: // 'WMI_SET_WSC_STATUS_CMD'
{
- Mailbox[0]->Read();
+ Mailbox[0].Read();
// TODO??
}
break;
@@ -1102,8 +1101,8 @@ void DSi_NWifi::WMI_Command()
{
MB_Read32(0);
MB_Read32(0);
- Mailbox[0]->Read();
- Mailbox[0]->Read();
+ Mailbox[0].Read();
+ Mailbox[0].Read();
}
break;
@@ -1116,9 +1115,9 @@ void DSi_NWifi::WMI_Command()
case 0xF000: // set bitrate
{
// TODO!
- Mailbox[0]->Read();
- Mailbox[0]->Read();
- Mailbox[0]->Read();
+ Mailbox[0].Read();
+ Mailbox[0].Read();
+ Mailbox[0].Read();
}
break;
@@ -1126,7 +1125,7 @@ void DSi_NWifi::WMI_Command()
printf("unknown WMI command %04X (header: %04X:%04X:%04X)\n", cmd, h0, len, h2);
for (int i = 0; i < len-2; i++)
{
- printf("%02X ", Mailbox[0]->Read());
+ printf("%02X ", Mailbox[0].Read());
if ((i&0xF)==0xF) printf("\n");
}
printf("\n");
@@ -1142,18 +1141,18 @@ void DSi_NWifi::WMI_Command()
void DSi_NWifi::WMI_ConnectToNetwork()
{
- u8 type = Mailbox[0]->Read();
- u8 auth11 = Mailbox[0]->Read();
- u8 auth = Mailbox[0]->Read();
- u8 pCryptoType = Mailbox[0]->Read();
- u8 pCryptoLen = Mailbox[0]->Read();
- u8 gCryptoType = Mailbox[0]->Read();
- u8 gCryptoLen = Mailbox[0]->Read();
- u8 ssidLen = Mailbox[0]->Read();
+ u8 type = Mailbox[0].Read();
+ u8 auth11 = Mailbox[0].Read();
+ u8 auth = Mailbox[0].Read();
+ u8 pCryptoType = Mailbox[0].Read();
+ u8 pCryptoLen = Mailbox[0].Read();
+ u8 gCryptoType = Mailbox[0].Read();
+ u8 gCryptoLen = Mailbox[0].Read();
+ u8 ssidLen = Mailbox[0].Read();
char ssid[33] = {0};
for (int i = 0; i < 32; i++)
- ssid[i] = Mailbox[0]->Read();
+ ssid[i] = Mailbox[0].Read();
if (ssidLen <= 32)
ssid[ssidLen] = '\0';
@@ -1219,11 +1218,11 @@ void DSi_NWifi::WMI_SendPacket(u16 len)
{
printf("WMI: data sync\n");
- /*Mailbox[8]->Write(2); // eid
- Mailbox[8]->Write(0x00); // flags
+ /*Mailbox[8].Write(2); // eid
+ Mailbox[8].Write(0x00); // flags
MB_Write16(8, 2); // data length
- Mailbox[8]->Write(0); //
- Mailbox[8]->Write(0); //
+ Mailbox[8].Write(0); //
+ Mailbox[8].Write(0); //
MB_Write16(8, 0x0200); //
DrainRXBuffer();*/
@@ -1235,7 +1234,7 @@ void DSi_NWifi::WMI_SendPacket(u16 len)
printf("WMI: special frame %04X len=%d\n", hdr, len);
for (int i = 0; i < len-2; i++)
{
- printf("%02X ", Mailbox[0]->Read());
+ printf("%02X ", Mailbox[0].Read());
if ((i&0xF)==0xF) printf("\n");
}
printf("\n");
@@ -1279,7 +1278,7 @@ void DSi_NWifi::WMI_SendPacket(u16 len)
*(u16*)&LANBuffer[12] = ethertype; // type
for (int i = 0; i < lan_len-14; i++)
{
- LANBuffer[14+i] = Mailbox[0]->Read();
+ LANBuffer[14+i] = Mailbox[0].Read();
}
/*for (int i = 0; i < lan_len; i++)
@@ -1294,73 +1293,73 @@ void DSi_NWifi::WMI_SendPacket(u16 len)
void DSi_NWifi::SendWMIEvent(u8 ep, u16 id, u8* data, u32 len)
{
- if (!Mailbox[8]->CanFit(6+len+2+8))
+ if (!Mailbox[8].CanFit(6+len+2+8))
{
printf("NWifi: !! not enough space in RX buffer for WMI event %04X\n", id);
return;
}
- Mailbox[8]->Write(ep); // eid
- Mailbox[8]->Write(0x02); // flags (trailer)
+ Mailbox[8].Write(ep); // eid
+ Mailbox[8].Write(0x02); // flags (trailer)
MB_Write16(8, len+2+8); // data length (plus event ID and trailer)
- Mailbox[8]->Write(8); // trailer length
- Mailbox[8]->Write(0); //
+ Mailbox[8].Write(8); // trailer length
+ Mailbox[8].Write(0); //
MB_Write16(8, id); // event ID
for (int i = 0; i < len; i++)
{
- Mailbox[8]->Write(data[i]);
+ Mailbox[8].Write(data[i]);
}
// trailer
- Mailbox[8]->Write(0x02);
- Mailbox[8]->Write(0x06);
- Mailbox[8]->Write(0x00);
- Mailbox[8]->Write(0x00);
- Mailbox[8]->Write(0x00);
- Mailbox[8]->Write(0x00);
- Mailbox[8]->Write(0x00);
- Mailbox[8]->Write(0x00);
+ Mailbox[8].Write(0x02);
+ Mailbox[8].Write(0x06);
+ Mailbox[8].Write(0x00);
+ Mailbox[8].Write(0x00);
+ Mailbox[8].Write(0x00);
+ Mailbox[8].Write(0x00);
+ Mailbox[8].Write(0x00);
+ Mailbox[8].Write(0x00);
DrainRXBuffer();
}
void DSi_NWifi::SendWMIAck(u8 ep)
{
- if (!Mailbox[8]->CanFit(6+12))
+ if (!Mailbox[8].CanFit(6+12))
{
printf("NWifi: !! not enough space in RX buffer for WMI ack (ep #%d)\n", ep);
return;
}
- Mailbox[8]->Write(0); // eid
- Mailbox[8]->Write(0x02); // flags (trailer)
+ Mailbox[8].Write(0); // eid
+ Mailbox[8].Write(0x02); // flags (trailer)
MB_Write16(8, 0xC); // data length (plus trailer)
- Mailbox[8]->Write(0xC); // trailer length
- Mailbox[8]->Write(0); //
+ Mailbox[8].Write(0xC); // trailer length
+ Mailbox[8].Write(0); //
// credit report
- Mailbox[8]->Write(0x01);
- Mailbox[8]->Write(0x02);
- Mailbox[8]->Write(ep);
- Mailbox[8]->Write(0x01);
+ Mailbox[8].Write(0x01);
+ Mailbox[8].Write(0x02);
+ Mailbox[8].Write(ep);
+ Mailbox[8].Write(0x01);
// lookahead
- Mailbox[8]->Write(0x02);
- Mailbox[8]->Write(0x06);
- Mailbox[8]->Write(0x00);
- Mailbox[8]->Write(0x00);
- Mailbox[8]->Write(0x00);
- Mailbox[8]->Write(0x00);
- Mailbox[8]->Write(0x00);
- Mailbox[8]->Write(0x00);
+ Mailbox[8].Write(0x02);
+ Mailbox[8].Write(0x06);
+ Mailbox[8].Write(0x00);
+ Mailbox[8].Write(0x00);
+ Mailbox[8].Write(0x00);
+ Mailbox[8].Write(0x00);
+ Mailbox[8].Write(0x00);
+ Mailbox[8].Write(0x00);
DrainRXBuffer();
}
void DSi_NWifi::SendWMIBSSInfo(u8 type, u8* data, u32 len)
{
- if (!Mailbox[8]->CanFit(6+len+2+16))
+ if (!Mailbox[8].CanFit(6+len+2+16))
{
printf("NWifi: !! not enough space in RX buffer for WMI BSSINFO event\n");
return;
@@ -1369,16 +1368,16 @@ void DSi_NWifi::SendWMIBSSInfo(u8 type, u8* data, u32 len)
// TODO: check when version>=2 frame type is used?
// I observed the version<2 variant on my DSi
- Mailbox[8]->Write(1); // eid
- Mailbox[8]->Write(0x00); // flags
+ Mailbox[8].Write(1); // eid
+ Mailbox[8].Write(0x00); // flags
MB_Write16(8, len+2+16); // data length (plus event ID and trailer)
- Mailbox[8]->Write(0xFF); // trailer length
- Mailbox[8]->Write(0xFF); //
+ Mailbox[8].Write(0xFF); // trailer length
+ Mailbox[8].Write(0xFF); //
MB_Write16(8, 0x1004); // event ID
MB_Write16(8, 2437); // channel (6) (checkme!)
- Mailbox[8]->Write(type);
- Mailbox[8]->Write(0x1B); // 'snr'
+ Mailbox[8].Write(type);
+ Mailbox[8].Write(0x1B); // 'snr'
MB_Write16(8, 0xFFBC); // RSSI
MB_Write32(8, *(u32*)&WifiAP::APMac[0]);
MB_Write16(8, *(u16*)&WifiAP::APMac[4]);
@@ -1386,7 +1385,7 @@ void DSi_NWifi::SendWMIBSSInfo(u8 type, u8* data, u32 len)
for (int i = 0; i < len; i++)
{
- Mailbox[8]->Write(data[i]);
+ Mailbox[8].Write(data[i]);
}
DrainRXBuffer();
@@ -1394,7 +1393,7 @@ void DSi_NWifi::SendWMIBSSInfo(u8 type, u8* data, u32 len)
void DSi_NWifi::CheckRX()
{
- if (!Mailbox[8]->CanFit(2048))
+ if (!Mailbox[8].CanFit(2048))
return;
int rxlen = Platform::LAN_RecvPacket(LANBuffer);
@@ -1433,11 +1432,11 @@ void DSi_NWifi::CheckRX()
// TODO: not hardcode the endpoint ID!!
u8 ep = 2;
- Mailbox[8]->Write(ep);
- Mailbox[8]->Write(0x00);
+ Mailbox[8].Write(ep);
+ Mailbox[8].Write(0x00);
MB_Write16(8, 16 + 8 + datalen);
- Mailbox[8]->Write(0);
- Mailbox[8]->Write(0);
+ Mailbox[8].Write(0);
+ Mailbox[8].Write(0);
MB_Write16(8, hdr);
MB_Write32(8, *(u32*)&LANBuffer[0]);
@@ -1454,7 +1453,7 @@ void DSi_NWifi::CheckRX()
MB_Write16(8, *(u16*)&LANBuffer[12]);
for (int i = 0; i < datalen; i++)
- Mailbox[8]->Write(LANBuffer[14+i]);
+ Mailbox[8].Write(LANBuffer[14+i]);
DrainRXBuffer();
}
@@ -1541,25 +1540,25 @@ void DSi_NWifi::_MSTimer()
if (ConnectionStatus == 1)
{
- //if (Mailbox[4]->IsEmpty())
+ //if (Mailbox[4].IsEmpty())
CheckRX();
}
}
void DSi_NWifi::DrainRXBuffer()
{
- while (Mailbox[8]->Level() >= 6)
+ while (Mailbox[8].Level() >= 6)
{
- u16 len = Mailbox[8]->Peek(2) | (Mailbox[8]->Peek(3) << 8);
+ u16 len = Mailbox[8].Peek(2) | (Mailbox[8].Peek(3) << 8);
u32 totallen = len + 6;
u32 required = (totallen + 0x7F) & ~0x7F;
- if (!Mailbox[4]->CanFit(required))
+ if (!Mailbox[4].CanFit(required))
break;
u32 i = 0;
- for (; i < totallen; i++) Mailbox[4]->Write(Mailbox[8]->Read());
- for (; i < required; i++) Mailbox[4]->Write(0);
+ for (; i < totallen; i++) Mailbox[4].Write(Mailbox[8].Read());
+ for (; i < required; i++) Mailbox[4].Write(0);
}
UpdateIRQ_F1();
diff --git a/src/DSi_NWifi.h b/src/DSi_NWifi.h
index 7efd40c7..72780d1c 100644
--- a/src/DSi_NWifi.h
+++ b/src/DSi_NWifi.h
@@ -84,40 +84,40 @@ private:
u16 MB_Read16(int n)
{
- u16 ret = Mailbox[n]->Read();
- ret |= (Mailbox[n]->Read() << 8);
+ u16 ret = Mailbox[n].Read();
+ ret |= (Mailbox[n].Read() << 8);
return ret;
}
void MB_Write16(int n, u16 val)
{
- Mailbox[n]->Write(val & 0xFF); val >>= 8;
- Mailbox[n]->Write(val & 0xFF);
+ Mailbox[n].Write(val & 0xFF); val >>= 8;
+ Mailbox[n].Write(val & 0xFF);
}
u32 MB_Read32(int n)
{
- u32 ret = Mailbox[n]->Read();
- ret |= (Mailbox[n]->Read() << 8);
- ret |= (Mailbox[n]->Read() << 16);
- ret |= (Mailbox[n]->Read() << 24);
+ u32 ret = Mailbox[n].Read();
+ ret |= (Mailbox[n].Read() << 8);
+ ret |= (Mailbox[n].Read() << 16);
+ ret |= (Mailbox[n].Read() << 24);
return ret;
}
void MB_Write32(int n, u32 val)
{
- Mailbox[n]->Write(val & 0xFF); val >>= 8;
- Mailbox[n]->Write(val & 0xFF); val >>= 8;
- Mailbox[n]->Write(val & 0xFF); val >>= 8;
- Mailbox[n]->Write(val & 0xFF);
+ Mailbox[n].Write(val & 0xFF); val >>= 8;
+ Mailbox[n].Write(val & 0xFF); val >>= 8;
+ Mailbox[n].Write(val & 0xFF); val >>= 8;
+ Mailbox[n].Write(val & 0xFF);
}
void MB_Drain(int n)
{
- while (!Mailbox[n]->IsEmpty()) Mailbox[n]->Read();
+ while (!Mailbox[n].IsEmpty()) Mailbox[n].Read();
}
- FIFO* Mailbox[9];
+ DynamicFIFO Mailbox[9];
u8 F0_IRQEnable;
u8 F0_IRQStatus;
diff --git a/src/DSi_SD.cpp b/src/DSi_SD.cpp
index de82edb5..d6fd5f5e 100644
--- a/src/DSi_SD.cpp
+++ b/src/DSi_SD.cpp
@@ -52,20 +52,12 @@ DSi_SDHost::DSi_SDHost(u32 num)
{
Num = num;
- DataFIFO[0] = new FIFO(0x100);
- DataFIFO[1] = new FIFO(0x100);
- DataFIFO32 = new FIFO(0x80);
-
Ports[0] = NULL;
Ports[1] = NULL;
}
DSi_SDHost::~DSi_SDHost()
{
- delete DataFIFO[0];
- delete DataFIFO[1];
- delete DataFIFO32;
-
if (Ports[0]) delete Ports[0];
if (Ports[1]) delete Ports[1];
}
@@ -89,10 +81,10 @@ void DSi_SDHost::Reset()
Param = 0;
memset(ResponseBuffer, 0, sizeof(ResponseBuffer));
- DataFIFO[0]->Clear();
- DataFIFO[1]->Clear();
+ DataFIFO[0].Clear();
+ DataFIFO[1].Clear();
CurFIFO = 0;
- DataFIFO32->Clear();
+ DataFIFO32.Clear();
IRQStatus = 0;
IRQMask = 0x8B7F031D;
@@ -160,8 +152,8 @@ void DSi_SDHost::UpdateData32IRQ()
oldflags &= (Data32IRQ >> 11);
Data32IRQ &= ~0x0300;
- if (DataFIFO32->Level() >= (BlockLen32>>2)) Data32IRQ |= (1<<8);
- if (!DataFIFO32->IsEmpty()) Data32IRQ |= (1<<9);
+ if (DataFIFO32.Level() >= (BlockLen32>>2)) Data32IRQ |= (1<<8);
+ if (!DataFIFO32.IsEmpty()) Data32IRQ |= (1<<9);
u32 newflags = ((Data32IRQ >> 8) & 0x1) | (((~Data32IRQ) >> 8) & 0x2);
newflags &= (Data32IRQ >> 11);
@@ -256,7 +248,7 @@ u32 DSi_SDHost::DataRX(u8* data, u32 len)
u32 f = CurFIFO ^ 1;
for (u32 i = 0; i < len; i += 2)
- DataFIFO[f]->Write(*(u16*)&data[i]);
+ DataFIFO[f].Write(*(u16*)&data[i]);
//CurFIFO = f;
//SetIRQ(24);
@@ -304,9 +296,9 @@ u32 DSi_SDHost::DataTX(u8* data, u32 len)
if (DataMode == 1)
{
- if ((DataFIFO32->Level() << 2) < len)
+ if ((DataFIFO32.Level() << 2) < len)
{
- if (DataFIFO32->IsEmpty())
+ if (DataFIFO32.IsEmpty())
{
SetIRQ(25);
DSi::CheckNDMAs(1, Num ? 0x29 : 0x28);
@@ -316,16 +308,16 @@ u32 DSi_SDHost::DataTX(u8* data, u32 len)
// drain FIFO32 into FIFO16
- if (!DataFIFO[f]->IsEmpty()) printf("VERY BAD!! TRYING TO DRAIN FIFO32 INTO FIFO16 BUT IT CONTAINS SHIT ALREADY\n");
+ if (!DataFIFO[f].IsEmpty()) printf("VERY BAD!! TRYING TO DRAIN FIFO32 INTO FIFO16 BUT IT CONTAINS SHIT ALREADY\n");
for (;;)
{
u32 f = CurFIFO;
- if ((DataFIFO[f]->Level() << 1) >= BlockLen16) break;
- if (DataFIFO32->IsEmpty()) break;
+ if ((DataFIFO[f].Level() << 1) >= BlockLen16) break;
+ if (DataFIFO32.IsEmpty()) break;
- u32 val = DataFIFO32->Read();
- DataFIFO[f]->Write(val & 0xFFFF);
- DataFIFO[f]->Write(val >> 16);
+ u32 val = DataFIFO32.Read();
+ DataFIFO[f].Write(val & 0xFFFF);
+ DataFIFO[f].Write(val >> 16);
}
UpdateData32IRQ();
@@ -335,15 +327,15 @@ u32 DSi_SDHost::DataTX(u8* data, u32 len)
}
else
{
- if ((DataFIFO[f]->Level() << 1) < len)
+ if ((DataFIFO[f].Level() << 1) < len)
{
- if (DataFIFO[f]->IsEmpty()) SetIRQ(25);
+ if (DataFIFO[f].IsEmpty()) SetIRQ(25);
return 0;
}
}
for (u32 i = 0; i < len; i += 2)
- *(u16*)&data[i] = DataFIFO[f]->Read();
+ *(u16*)&data[i] = DataFIFO[f].Read();
CurFIFO ^= 1;
BlockCountInternal--;
@@ -392,13 +384,13 @@ void DSi_SDHost::CheckTX()
if (DataMode == 1)
{
- if ((DataFIFO32->Level() << 2) < BlockLen32)
+ if ((DataFIFO32.Level() << 2) < BlockLen32)
return;
}
else
{
u32 f = CurFIFO;
- if ((DataFIFO[f]->Level() << 1) < BlockLen16)
+ if ((DataFIFO[f].Level() << 1) < BlockLen16)
return;
}
@@ -481,7 +473,7 @@ u16 DSi_SDHost::Read(u32 addr)
u16 DSi_SDHost::ReadFIFO16()
{
u32 f = CurFIFO;
- if (DataFIFO[f]->IsEmpty())
+ if (DataFIFO[f].IsEmpty())
{
// TODO
// on hardware it seems to wrap around. underflow bit is set upon the first 'empty' read.
@@ -489,9 +481,9 @@ u16 DSi_SDHost::ReadFIFO16()
}
DSi_SDDevice* dev = Ports[PortSelect & 0x1];
- u16 ret = DataFIFO[f]->Read();
+ u16 ret = DataFIFO[f].Read();
- if (DataFIFO[f]->IsEmpty())
+ if (DataFIFO[f].IsEmpty())
{
CheckRX();
}
@@ -503,16 +495,16 @@ u32 DSi_SDHost::ReadFIFO32()
{
if (DataMode != 1) return 0;
- if (DataFIFO32->IsEmpty())
+ if (DataFIFO32.IsEmpty())
{
// TODO
return 0;
}
DSi_SDDevice* dev = Ports[PortSelect & 0x1];
- u32 ret = DataFIFO32->Read();
+ u32 ret = DataFIFO32.Read();
- if (DataFIFO32->IsEmpty())
+ if (DataFIFO32.IsEmpty())
{
CheckRX();
}
@@ -628,7 +620,7 @@ void DSi_SDHost::Write(u32 addr, u16 val)
case 0x100:
Data32IRQ = (val & 0x1802) | (Data32IRQ & 0x0300);
- if (val & (1<<10)) DataFIFO32->Clear();
+ if (val & (1<<10)) DataFIFO32.Clear();
DataMode = ((DataCtl >> 1) & 0x1) & ((Data32IRQ >> 1) & 0x1);
return;
case 0x102: return;
@@ -643,14 +635,14 @@ void DSi_SDHost::WriteFIFO16(u16 val)
{
DSi_SDDevice* dev = Ports[PortSelect & 0x1];
u32 f = CurFIFO;
- if (DataFIFO[f]->IsFull())
+ if (DataFIFO[f].IsFull())
{
// TODO
printf("!!!! %s FIFO (16) FULL\n", SD_DESC);
return;
}
- DataFIFO[f]->Write(val);
+ DataFIFO[f].Write(val);
CheckTX();
}
@@ -659,14 +651,14 @@ void DSi_SDHost::WriteFIFO32(u32 val)
{
if (DataMode != 1) return;
- if (DataFIFO32->IsFull())
+ if (DataFIFO32.IsFull())
{
// TODO
printf("!!!! %s FIFO (32) FULL\n", SD_DESC);
return;
}
- DataFIFO32->Write(val);
+ DataFIFO32.Write(val);
CheckTX();
@@ -679,21 +671,21 @@ void DSi_SDHost::UpdateFIFO32()
if (DataMode != 1) return;
- if (!DataFIFO32->IsEmpty()) printf("VERY BAD!! TRYING TO DRAIN FIFO16 INTO FIFO32 BUT IT CONTAINS SHIT ALREADY\n");
+ if (!DataFIFO32.IsEmpty()) printf("VERY BAD!! TRYING TO DRAIN FIFO16 INTO FIFO32 BUT IT CONTAINS SHIT ALREADY\n");
for (;;)
{
u32 f = CurFIFO;
- if ((DataFIFO32->Level() << 2) >= BlockLen32) break;
- if (DataFIFO[f]->IsEmpty()) break;
+ if ((DataFIFO32.Level() << 2) >= BlockLen32) break;
+ if (DataFIFO[f].IsEmpty()) break;
- u32 val = DataFIFO[f]->Read();
- val |= (DataFIFO[f]->Read() << 16);
- DataFIFO32->Write(val);
+ u32 val = DataFIFO[f].Read();
+ val |= (DataFIFO[f].Read() << 16);
+ DataFIFO32.Write(val);
}
UpdateData32IRQ();
- if ((DataFIFO32->Level() << 2) >= BlockLen32)
+ if ((DataFIFO32.Level() << 2) >= BlockLen32)
{
DSi::CheckNDMAs(1, Num ? 0x29 : 0x28);
}
@@ -704,8 +696,8 @@ void DSi_SDHost::CheckSwapFIFO()
// check whether we can swap the FIFOs
u32 f = CurFIFO;
- bool cur_empty = (DataMode == 1) ? DataFIFO32->IsEmpty() : DataFIFO[f]->IsEmpty();
- if (cur_empty && ((DataFIFO[f^1]->Level() << 1) >= BlockLen16))
+ bool cur_empty = (DataMode == 1) ? DataFIFO32.IsEmpty() : DataFIFO[f].IsEmpty();
+ if (cur_empty && ((DataFIFO[f^1].Level() << 1) >= BlockLen16))
{
CurFIFO ^= 1;
}
diff --git a/src/DSi_SD.h b/src/DSi_SD.h
index 43f5a98e..1f9243f6 100644
--- a/src/DSi_SD.h
+++ b/src/DSi_SD.h
@@ -85,12 +85,12 @@ private:
u32 Param;
u16 ResponseBuffer[8];
- FIFO* DataFIFO[2];
- u32 CurFIFO; // FIFO accessible for read/write
- FIFO* DataFIFO32;
-
DSi_SDDevice* Ports[2];
+ u32 CurFIFO; // FIFO accessible for read/write
+ FIFO DataFIFO[2];
+ FIFO DataFIFO32;
+
void UpdateData32IRQ();
void ClearIRQ(u32 irq);
void SetIRQ(u32 irq);
diff --git a/src/FIFO.h b/src/FIFO.h
index 2b2c1020..ca146100 100644
--- a/src/FIFO.h
+++ b/src/FIFO.h
@@ -21,18 +21,95 @@
#include "types.h"
-template
+template
class FIFO
{
public:
- FIFO(u32 num)
+ void Clear()
+ {
+ NumOccupied = 0;
+ ReadPos = 0;
+ WritePos = 0;
+ memset(&Entries[ReadPos], 0, sizeof(T));
+ }
+
+
+ void DoSavestate(Savestate* file)
+ {
+ file->Var32(&NumOccupied);
+ file->Var32(&ReadPos);
+ file->Var32(&WritePos);
+
+ file->VarArray(Entries, sizeof(T)*NumEntries);
+ }
+
+
+ void Write(T val)
+ {
+ if (IsFull()) return;
+
+ Entries[WritePos] = val;
+
+ WritePos++;
+ if (WritePos >= NumEntries)
+ WritePos = 0;
+
+ NumOccupied++;
+ }
+
+ T Read()
+ {
+ T ret = Entries[ReadPos];
+ if (IsEmpty())
+ return ret;
+
+ ReadPos++;
+ if (ReadPos >= NumEntries)
+ ReadPos = 0;
+
+ NumOccupied--;
+ return ret;
+ }
+
+ T Peek()
+ {
+ return Entries[ReadPos];
+ }
+
+ T Peek(u32 offset)
+ {
+ u32 pos = ReadPos + offset;
+ if (pos >= NumEntries)
+ pos -= NumEntries;
+
+ return Entries[pos];
+ }
+
+ u32 Level() { return NumOccupied; }
+ bool IsEmpty() { return NumOccupied == 0; }
+ bool IsFull() { return NumOccupied >= NumEntries; }
+
+ bool CanFit(u32 num) { return ((NumOccupied + num) <= NumEntries); }
+
+private:
+ T Entries[NumEntries] = {0};
+ u32 NumOccupied = 0;
+ u32 ReadPos = 0, WritePos = 0;
+};
+
+
+template
+class DynamicFIFO
+{
+public:
+ DynamicFIFO(u32 num)
{
NumEntries = num;
Entries = new T[num];
Clear();
}
- ~FIFO()
+ ~DynamicFIFO()
{
delete[] Entries;
}
diff --git a/src/GPU.cpp b/src/GPU.cpp
index 35ebaba1..ed73e297 100644
--- a/src/GPU.cpp
+++ b/src/GPU.cpp
@@ -142,6 +142,9 @@ u8 VRAMFlat_BOBJExtPal[8*1024];
u8 VRAMFlat_Texture[512*1024];
u8 VRAMFlat_TexPal[128*1024];
+u32 OAMDirty;
+u32 PaletteDirty;
+
bool Init()
{
GPU2D_A = new GPU2D_Soft(0);
@@ -272,6 +275,9 @@ void Reset()
ResetRenderer();
ResetVRAMCache();
+
+ OAMDirty = 0x3;
+ PaletteDirty = 0xF;
}
void Stop()
diff --git a/src/GPU.h b/src/GPU.h
index cc62e1ea..1bbb9fe2 100644
--- a/src/GPU.h
+++ b/src/GPU.h
@@ -147,14 +147,16 @@ bool MakeVRAMFlat_TexPalCoherent(NonStupidBitField<128*1024/VRAMDirtyGranularity
void SyncDirtyFlags();
-typedef struct
+extern u32 OAMDirty;
+extern u32 PaletteDirty;
+
+struct RenderSettings
{
bool Soft_Threaded;
int GL_ScaleFactor;
bool GL_BetterPolygons;
-
-} RenderSettings;
+};
bool Init();
@@ -509,6 +511,35 @@ T ReadVRAM_TexPal(u32 addr)
return ret;
}
+template
+T ReadPalette(u32 addr)
+{
+ return *(T*)&Palette[addr & 0x7FF];
+}
+
+template
+void WritePalette(u32 addr, T val)
+{
+ addr &= 0x7FF;
+
+ *(T*)&Palette[addr] = val;
+ PaletteDirty |= 1 << (addr / VRAMDirtyGranularity);
+}
+
+template
+T ReadOAM(u32 addr)
+{
+ return *(T*)&OAM[addr & 0x7FF];
+}
+
+template
+void WriteOAM(u32 addr, T val)
+{
+ addr &= 0x7FF;
+
+ *(T*)&OAM[addr] = val;
+ OAMDirty |= 1 << (addr / 1024);
+}
void SetPowerCnt(u32 val);
diff --git a/src/GPU3D.cpp b/src/GPU3D.cpp
index 7b304268..53fafb3e 100644
--- a/src/GPU3D.cpp
+++ b/src/GPU3D.cpp
@@ -99,7 +99,7 @@
namespace GPU3D
{
-const u32 CmdNumParams[256] =
+const u8 CmdNumParams[256] =
{
// 0x00
0,
@@ -147,10 +147,10 @@ typedef union
} CmdFIFOEntry;
-FIFO* CmdFIFO;
-FIFO* CmdPIPE;
+FIFO CmdFIFO;
+FIFO CmdPIPE;
-FIFO* CmdStallQueue;
+FIFO CmdStallQueue;
u32 NumCommands, CurCommand, ParamCount, TotalParams;
@@ -277,20 +277,11 @@ u32 FlushAttributes;
bool Init()
{
- CmdFIFO = new FIFO(256);
- CmdPIPE = new FIFO(4);
-
- CmdStallQueue = new FIFO(64);
-
return true;
}
void DeInit()
{
- delete CmdFIFO;
- delete CmdPIPE;
-
- delete CmdStallQueue;
}
void ResetRenderingState()
@@ -314,10 +305,10 @@ void ResetRenderingState()
void Reset()
{
- CmdFIFO->Clear();
- CmdPIPE->Clear();
+ CmdFIFO.Clear();
+ CmdPIPE.Clear();
- CmdStallQueue->Clear();
+ CmdStallQueue.Clear();
NumCommands = 0;
CurCommand = 0;
@@ -395,8 +386,8 @@ void DoSavestate(Savestate* file)
{
file->Section("GP3D");
- CmdFIFO->DoSavestate(file);
- CmdPIPE->DoSavestate(file);
+ CmdFIFO.DoSavestate(file);
+ CmdPIPE.DoSavestate(file);
file->Var32(&NumCommands);
file->Var32(&CurCommand);
@@ -593,7 +584,9 @@ void DoSavestate(Savestate* file)
}
}
- CmdStallQueue->DoSavestate(file);
+ // probably not worth storing the vblank-latched Renderxxxxxx variables
+ CmdStallQueue.DoSavestate(file);
+
file->Var32((u32*)&VertexPipeline);
file->Var32((u32*)&NormalPipeline);
file->Var32((u32*)&PolygonPipeline);
@@ -1731,24 +1724,24 @@ void VecTest(u32* params)
void CmdFIFOWrite(CmdFIFOEntry& entry)
{
- if (CmdFIFO->IsEmpty() && !CmdPIPE->IsFull())
+ if (CmdFIFO.IsEmpty() && !CmdPIPE.IsFull())
{
- CmdPIPE->Write(entry);
+ CmdPIPE.Write(entry);
}
else
{
- if (CmdFIFO->IsFull())
+ if (CmdFIFO.IsFull())
{
// store it to the stall queue. stall the system.
// worst case is if a STMxx opcode causes this, which is why our stall queue
// has 64 entries. this is less complicated than trying to make STMxx stall-able.
- CmdStallQueue->Write(entry);
+ CmdStallQueue.Write(entry);
NDS::GXFIFOStall();
return;
}
- CmdFIFO->Write(entry);
+ CmdFIFO.Write(entry);
}
GXStat |= (1<<27);
@@ -1767,27 +1760,27 @@ void CmdFIFOWrite(CmdFIFOEntry& entry)
CmdFIFOEntry CmdFIFORead()
{
- CmdFIFOEntry ret = CmdPIPE->Read();
+ CmdFIFOEntry ret = CmdPIPE.Read();
- if (CmdPIPE->Level() <= 2)
+ if (CmdPIPE.Level() <= 2)
{
- if (!CmdFIFO->IsEmpty())
- CmdPIPE->Write(CmdFIFO->Read());
- if (!CmdFIFO->IsEmpty())
- CmdPIPE->Write(CmdFIFO->Read());
+ if (!CmdFIFO.IsEmpty())
+ CmdPIPE.Write(CmdFIFO.Read());
+ if (!CmdFIFO.IsEmpty())
+ CmdPIPE.Write(CmdFIFO.Read());
// empty stall queue if needed
// CmdFIFO should not be full at this point.
- if (!CmdStallQueue->IsEmpty())
+ if (!CmdStallQueue.IsEmpty())
{
- while (!CmdStallQueue->IsEmpty())
+ while (!CmdStallQueue.IsEmpty())
{
- if (CmdFIFO->IsFull()) break;
- CmdFIFOEntry entry = CmdStallQueue->Read();
+ if (CmdFIFO.IsFull()) break;
+ CmdFIFOEntry entry = CmdStallQueue.Read();
CmdFIFOWrite(entry);
}
- if (CmdStallQueue->IsEmpty())
+ if (CmdStallQueue.IsEmpty())
NDS::GXFIFOUnstall();
}
@@ -1798,7 +1791,37 @@ CmdFIFOEntry CmdFIFORead()
return ret;
}
+inline void VertexPipelineSubmitCmd()
+{
+ // vertex commands 0x24, 0x25, 0x26, 0x27, 0x28
+ if (!(VertexSlotsFree & 0x1)) NextVertexSlot();
+ else AddCycles(1);
+ NormalPipeline = 0;
+}
+inline void VertexPipelineCmdDelayed6()
+{
+ // commands 0x20, 0x30, 0x31, 0x72 that can run 6 cycles after a vertex
+ if (VertexPipeline > 2) AddCycles((VertexPipeline - 2) + 1);
+ else AddCycles(NormalPipeline + 1);
+ NormalPipeline = 0;
+}
+
+inline void VertexPipelineCmdDelayed8()
+{
+ // commands 0x29, 0x2A, 0x2B, 0x33, 0x34, 0x41, 0x60, 0x71 that can run 8 cycles after a vertex
+ if (VertexPipeline > 0) AddCycles(VertexPipeline + 1);
+ else AddCycles(NormalPipeline + 1);
+ NormalPipeline = 0;
+}
+
+inline void VertexPipelineCmdDelayed4()
+{
+ // all other commands can run 4 cycles after a vertex
+ // no need to do much here since that is the minimum
+ AddCycles(NormalPipeline + 1);
+ NormalPipeline = 0;
+}
void ExecuteCommand()
{
@@ -1809,81 +1832,23 @@ void ExecuteCommand()
// each FIFO entry takes 1 cycle to be processed
// commands (presumably) run when all the needed parameters have been read
// which is where we add the remaining cycles if any
- if (ExecParamCount == 0)
+
+ u32 paramsRequiredCount = CmdNumParams[entry.Command];
+ if (paramsRequiredCount <= 1)
{
- // delay the first command entry as needed
- switch (entry.Command)
- {
- // commands that stall the polygon pipeline
- case 0x32: StallPolygonPipeline(8 + 1, 2); break; // 32 can run 6 cycles after a vertex
- case 0x40: StallPolygonPipeline(1, 0); break;
- case 0x70: StallPolygonPipeline(10 + 1, 0); break;
+ // fast path for command which only have a single parameter
- case 0x23:
- case 0x24:
- case 0x25:
- case 0x26:
- case 0x27:
- case 0x28:
- // vertex
- if (!(VertexSlotsFree & 0x1)) NextVertexSlot();
- else AddCycles(1);
- NormalPipeline = 0;
- break;
-
- case 0x20:
- case 0x30:
- case 0x31:
- case 0x72:
- // commands that can run 6 cycles after a vertex
- if (VertexPipeline > 2) AddCycles((VertexPipeline - 2) + 1);
- else AddCycles(NormalPipeline + 1);
- NormalPipeline = 0;
- break;
-
- case 0x29:
- case 0x2A:
- case 0x2B:
- case 0x33:
- case 0x34:
- case 0x41:
- case 0x60:
- case 0x71:
- // command that can run 8 cycles after a vertex
- if (VertexPipeline > 0) AddCycles(VertexPipeline + 1);
- else AddCycles(NormalPipeline + 1);
- NormalPipeline = 0;
- break;
-
- default:
- // all other commands can run 4 cycles after a vertex
- // no need to do much here since that is the minimum
- AddCycles(NormalPipeline + 1);
- NormalPipeline = 0;
- break;
- }
- }
- else
- AddCycles(1);
-
- ExecParams[ExecParamCount] = entry.Param;
- ExecParamCount++;
-
- if (ExecParamCount >= CmdNumParams[entry.Command])
- {
- /*printf("[GXS:%08X] 0x%02X, ", GXStat, entry.Command);
- for (int k = 0; k < ExecParamCount; k++) printf("0x%08X, ", ExecParams[k]);
- printf("\n");*/
-
- ExecParamCount = 0;
+ /*printf("[GXS:%08X] 0x%02X, 0x%08X", GXStat, entry.Command, entry.Param);*/
switch (entry.Command)
{
case 0x10: // matrix mode
- MatrixMode = ExecParams[0] & 0x3;
+ VertexPipelineCmdDelayed4();
+ MatrixMode = entry.Param & 0x3;
break;
case 0x11: // push matrix
+ VertexPipelineCmdDelayed4();
NumPushPopCommands--;
if (MatrixMode == 0)
{
@@ -1914,6 +1879,7 @@ void ExecuteCommand()
break;
case 0x12: // pop matrix
+ VertexPipelineCmdDelayed4();
NumPushPopCommands--;
if (MatrixMode == 0)
{
@@ -1936,7 +1902,7 @@ void ExecuteCommand()
}
else
{
- s32 offset = (s32)(ExecParams[0] << 26) >> 26;
+ s32 offset = (s32)(entry.Param << 26) >> 26;
PosMatrixStackPointer -= offset;
PosMatrixStackPointer &= 0x3F;
@@ -1950,6 +1916,7 @@ void ExecuteCommand()
break;
case 0x13: // store matrix
+ VertexPipelineCmdDelayed4();
if (MatrixMode == 0)
{
memcpy(ProjMatrixStack, ProjMatrix, 16*4);
@@ -1960,7 +1927,7 @@ void ExecuteCommand()
}
else
{
- u32 addr = ExecParams[0] & 0x1F;
+ u32 addr = entry.Param & 0x1F;
if (addr > 30) GXStat |= (1<<15);
memcpy(PosMatrixStack[addr], PosMatrix, 16*4);
@@ -1970,6 +1937,7 @@ void ExecuteCommand()
break;
case 0x14: // restore matrix
+ VertexPipelineCmdDelayed4();
if (MatrixMode == 0)
{
memcpy(ProjMatrix, ProjMatrixStack, 16*4);
@@ -1983,7 +1951,7 @@ void ExecuteCommand()
}
else
{
- u32 addr = ExecParams[0] & 0x1F;
+ u32 addr = entry.Param & 0x1F;
if (addr > 30) GXStat |= (1<<15);
memcpy(PosMatrix, PosMatrixStack[addr], 16*4);
@@ -1994,6 +1962,7 @@ void ExecuteCommand()
break;
case 0x15: // identity
+ VertexPipelineCmdDelayed4();
if (MatrixMode == 0)
{
MatrixLoadIdentity(ProjMatrix);
@@ -2012,173 +1981,10 @@ void ExecuteCommand()
}
break;
- case 0x16: // load 4x4
- if (MatrixMode == 0)
- {
- MatrixLoad4x4(ProjMatrix, (s32*)ExecParams);
- ClipMatrixDirty = true;
- AddCycles(18);
- }
- else if (MatrixMode == 3)
- {
- MatrixLoad4x4(TexMatrix, (s32*)ExecParams);
- AddCycles(10);
- }
- else
- {
- MatrixLoad4x4(PosMatrix, (s32*)ExecParams);
- if (MatrixMode == 2)
- MatrixLoad4x4(VecMatrix, (s32*)ExecParams);
- ClipMatrixDirty = true;
- AddCycles(18);
- }
- break;
-
- case 0x17: // load 4x3
- if (MatrixMode == 0)
- {
- MatrixLoad4x3(ProjMatrix, (s32*)ExecParams);
- ClipMatrixDirty = true;
- AddCycles(18);
- }
- else if (MatrixMode == 3)
- {
- MatrixLoad4x3(TexMatrix, (s32*)ExecParams);
- AddCycles(7);
- }
- else
- {
- MatrixLoad4x3(PosMatrix, (s32*)ExecParams);
- if (MatrixMode == 2)
- MatrixLoad4x3(VecMatrix, (s32*)ExecParams);
- ClipMatrixDirty = true;
- AddCycles(18);
- }
- break;
-
- case 0x18: // mult 4x4
- if (MatrixMode == 0)
- {
- MatrixMult4x4(ProjMatrix, (s32*)ExecParams);
- ClipMatrixDirty = true;
- AddCycles(35 - 16);
- }
- else if (MatrixMode == 3)
- {
- MatrixMult4x4(TexMatrix, (s32*)ExecParams);
- AddCycles(33 - 16);
- }
- else
- {
- MatrixMult4x4(PosMatrix, (s32*)ExecParams);
- if (MatrixMode == 2)
- {
- MatrixMult4x4(VecMatrix, (s32*)ExecParams);
- AddCycles(35 + 30 - 16);
- }
- else AddCycles(35 - 16);
- ClipMatrixDirty = true;
- }
- break;
-
- case 0x19: // mult 4x3
- if (MatrixMode == 0)
- {
- MatrixMult4x3(ProjMatrix, (s32*)ExecParams);
- ClipMatrixDirty = true;
- AddCycles(35 - 12);
- }
- else if (MatrixMode == 3)
- {
- MatrixMult4x3(TexMatrix, (s32*)ExecParams);
- AddCycles(33 - 12);
- }
- else
- {
- MatrixMult4x3(PosMatrix, (s32*)ExecParams);
- if (MatrixMode == 2)
- {
- MatrixMult4x3(VecMatrix, (s32*)ExecParams);
- AddCycles(35 + 30 - 12);
- }
- else AddCycles(35 - 12);
- ClipMatrixDirty = true;
- }
- break;
-
- case 0x1A: // mult 3x3
- if (MatrixMode == 0)
- {
- MatrixMult3x3(ProjMatrix, (s32*)ExecParams);
- ClipMatrixDirty = true;
- AddCycles(35 - 9);
- }
- else if (MatrixMode == 3)
- {
- MatrixMult3x3(TexMatrix, (s32*)ExecParams);
- AddCycles(33 - 9);
- }
- else
- {
- MatrixMult3x3(PosMatrix, (s32*)ExecParams);
- if (MatrixMode == 2)
- {
- MatrixMult3x3(VecMatrix, (s32*)ExecParams);
- AddCycles(35 + 30 - 9);
- }
- else AddCycles(35 - 9);
- ClipMatrixDirty = true;
- }
- break;
-
- case 0x1B: // scale
- if (MatrixMode == 0)
- {
- MatrixScale(ProjMatrix, (s32*)ExecParams);
- ClipMatrixDirty = true;
- AddCycles(35 - 3);
- }
- else if (MatrixMode == 3)
- {
- MatrixScale(TexMatrix, (s32*)ExecParams);
- AddCycles(33 - 3);
- }
- else
- {
- MatrixScale(PosMatrix, (s32*)ExecParams);
- ClipMatrixDirty = true;
- AddCycles(35 - 3);
- }
- break;
-
- case 0x1C: // translate
- if (MatrixMode == 0)
- {
- MatrixTranslate(ProjMatrix, (s32*)ExecParams);
- ClipMatrixDirty = true;
- AddCycles(35 - 3);
- }
- else if (MatrixMode == 3)
- {
- MatrixTranslate(TexMatrix, (s32*)ExecParams);
- AddCycles(33 - 3);
- }
- else
- {
- MatrixTranslate(PosMatrix, (s32*)ExecParams);
- if (MatrixMode == 2)
- {
- MatrixTranslate(VecMatrix, (s32*)ExecParams);
- AddCycles(35 + 30 - 3);
- }
- else AddCycles(35 - 3);
- ClipMatrixDirty = true;
- }
- break;
-
case 0x20: // vertex color
+ VertexPipelineCmdDelayed6();
{
- u32 c = ExecParams[0];
+ u32 c = entry.Param;
u32 r = c & 0x1F;
u32 g = (c >> 5) & 0x1F;
u32 b = (c >> 10) & 0x1F;
@@ -2189,15 +1995,17 @@ void ExecuteCommand()
break;
case 0x21: // normal
- Normal[0] = (s16)((ExecParams[0] & 0x000003FF) << 6) >> 6;
- Normal[1] = (s16)((ExecParams[0] & 0x000FFC00) >> 4) >> 6;
- Normal[2] = (s16)((ExecParams[0] & 0x3FF00000) >> 14) >> 6;
+ VertexPipelineCmdDelayed4();
+ Normal[0] = (s16)((entry.Param & 0x000003FF) << 6) >> 6;
+ Normal[1] = (s16)((entry.Param & 0x000FFC00) >> 4) >> 6;
+ Normal[2] = (s16)((entry.Param & 0x3FF00000) >> 14) >> 6;
CalculateLighting();
break;
case 0x22: // texcoord
- RawTexCoords[0] = ExecParams[0] & 0xFFFF;
- RawTexCoords[1] = ExecParams[0] >> 16;
+ VertexPipelineCmdDelayed4();
+ RawTexCoords[0] = entry.Param & 0xFFFF;
+ RawTexCoords[1] = entry.Param >> 16;
if ((TexParam >> 30) == 1)
{
TexCoords[0] = (RawTexCoords[0]*TexMatrix[0] + RawTexCoords[1]*TexMatrix[4] + TexMatrix[8] + TexMatrix[12]) >> 12;
@@ -2210,65 +2018,67 @@ void ExecuteCommand()
}
break;
- case 0x23: // full vertex
- CurVertex[0] = ExecParams[0] & 0xFFFF;
- CurVertex[1] = ExecParams[0] >> 16;
- CurVertex[2] = ExecParams[1] & 0xFFFF;
- SubmitVertex();
- break;
-
case 0x24: // 10-bit vertex
- CurVertex[0] = (ExecParams[0] & 0x000003FF) << 6;
- CurVertex[1] = (ExecParams[0] & 0x000FFC00) >> 4;
- CurVertex[2] = (ExecParams[0] & 0x3FF00000) >> 14;
+ VertexPipelineSubmitCmd();
+ CurVertex[0] = (entry.Param & 0x000003FF) << 6;
+ CurVertex[1] = (entry.Param & 0x000FFC00) >> 4;
+ CurVertex[2] = (entry.Param & 0x3FF00000) >> 14;
SubmitVertex();
break;
case 0x25: // vertex XY
- CurVertex[0] = ExecParams[0] & 0xFFFF;
- CurVertex[1] = ExecParams[0] >> 16;
+ VertexPipelineSubmitCmd();
+ CurVertex[0] = entry.Param & 0xFFFF;
+ CurVertex[1] = entry.Param >> 16;
SubmitVertex();
break;
case 0x26: // vertex XZ
- CurVertex[0] = ExecParams[0] & 0xFFFF;
- CurVertex[2] = ExecParams[0] >> 16;
+ VertexPipelineSubmitCmd();
+ CurVertex[0] = entry.Param & 0xFFFF;
+ CurVertex[2] = entry.Param >> 16;
SubmitVertex();
break;
case 0x27: // vertex YZ
- CurVertex[1] = ExecParams[0] & 0xFFFF;
- CurVertex[2] = ExecParams[0] >> 16;
+ VertexPipelineSubmitCmd();
+ CurVertex[1] = entry.Param & 0xFFFF;
+ CurVertex[2] = entry.Param >> 16;
SubmitVertex();
break;
case 0x28: // 10-bit delta vertex
- CurVertex[0] += (s16)((ExecParams[0] & 0x000003FF) << 6) >> 6;
- CurVertex[1] += (s16)((ExecParams[0] & 0x000FFC00) >> 4) >> 6;
- CurVertex[2] += (s16)((ExecParams[0] & 0x3FF00000) >> 14) >> 6;
+ VertexPipelineSubmitCmd();
+ CurVertex[0] += (s16)((entry.Param & 0x000003FF) << 6) >> 6;
+ CurVertex[1] += (s16)((entry.Param & 0x000FFC00) >> 4) >> 6;
+ CurVertex[2] += (s16)((entry.Param & 0x3FF00000) >> 14) >> 6;
SubmitVertex();
break;
case 0x29: // polygon attributes
- PolygonAttr = ExecParams[0];
+ VertexPipelineCmdDelayed8();
+ PolygonAttr = entry.Param;
break;
case 0x2A: // texture param
- TexParam = ExecParams[0];
+ VertexPipelineCmdDelayed8();
+ TexParam = entry.Param;
break;
case 0x2B: // texture palette
- TexPalette = ExecParams[0] & 0x1FFF;
+ VertexPipelineCmdDelayed8();
+ TexPalette = entry.Param & 0x1FFF;
break;
case 0x30: // diffuse/ambient material
- MatDiffuse[0] = ExecParams[0] & 0x1F;
- MatDiffuse[1] = (ExecParams[0] >> 5) & 0x1F;
- MatDiffuse[2] = (ExecParams[0] >> 10) & 0x1F;
- MatAmbient[0] = (ExecParams[0] >> 16) & 0x1F;
- MatAmbient[1] = (ExecParams[0] >> 21) & 0x1F;
- MatAmbient[2] = (ExecParams[0] >> 26) & 0x1F;
- if (ExecParams[0] & 0x8000)
+ VertexPipelineCmdDelayed6();
+ MatDiffuse[0] = entry.Param & 0x1F;
+ MatDiffuse[1] = (entry.Param >> 5) & 0x1F;
+ MatDiffuse[2] = (entry.Param >> 10) & 0x1F;
+ MatAmbient[0] = (entry.Param >> 16) & 0x1F;
+ MatAmbient[1] = (entry.Param >> 21) & 0x1F;
+ MatAmbient[2] = (entry.Param >> 26) & 0x1F;
+ if (entry.Param & 0x8000)
{
VertexColor[0] = MatDiffuse[0];
VertexColor[1] = MatDiffuse[1];
@@ -2278,23 +2088,25 @@ void ExecuteCommand()
break;
case 0x31: // specular/emission material
- MatSpecular[0] = ExecParams[0] & 0x1F;
- MatSpecular[1] = (ExecParams[0] >> 5) & 0x1F;
- MatSpecular[2] = (ExecParams[0] >> 10) & 0x1F;
- MatEmission[0] = (ExecParams[0] >> 16) & 0x1F;
- MatEmission[1] = (ExecParams[0] >> 21) & 0x1F;
- MatEmission[2] = (ExecParams[0] >> 26) & 0x1F;
- UseShininessTable = (ExecParams[0] & 0x8000) != 0;
+ VertexPipelineCmdDelayed6();
+ MatSpecular[0] = entry.Param & 0x1F;
+ MatSpecular[1] = (entry.Param >> 5) & 0x1F;
+ MatSpecular[2] = (entry.Param >> 10) & 0x1F;
+ MatEmission[0] = (entry.Param >> 16) & 0x1F;
+ MatEmission[1] = (entry.Param >> 21) & 0x1F;
+ MatEmission[2] = (entry.Param >> 26) & 0x1F;
+ UseShininessTable = (entry.Param & 0x8000) != 0;
AddCycles(3);
break;
case 0x32: // light direction
+ StallPolygonPipeline(8 + 1, 2); // 0x32 can run 6 cycles after a vertex
{
- u32 l = ExecParams[0] >> 30;
+ u32 l = entry.Param >> 30;
s16 dir[3];
- dir[0] = (s16)((ExecParams[0] & 0x000003FF) << 6) >> 6;
- dir[1] = (s16)((ExecParams[0] & 0x000FFC00) >> 4) >> 6;
- dir[2] = (s16)((ExecParams[0] & 0x3FF00000) >> 14) >> 6;
+ dir[0] = (s16)((entry.Param & 0x000003FF) << 6) >> 6;
+ dir[1] = (s16)((entry.Param & 0x000FFC00) >> 4) >> 6;
+ dir[2] = (s16)((entry.Param & 0x3FF00000) >> 14) >> 6;
LightDirection[l][0] = (dir[0]*VecMatrix[0] + dir[1]*VecMatrix[4] + dir[2]*VecMatrix[8]) >> 12;
LightDirection[l][1] = (dir[0]*VecMatrix[1] + dir[1]*VecMatrix[5] + dir[2]*VecMatrix[9]) >> 12;
LightDirection[l][2] = (dir[0]*VecMatrix[2] + dir[1]*VecMatrix[6] + dir[2]*VecMatrix[10]) >> 12;
@@ -2303,32 +2115,21 @@ void ExecuteCommand()
break;
case 0x33: // light color
+ VertexPipelineCmdDelayed8();
{
- u32 l = ExecParams[0] >> 30;
- LightColor[l][0] = ExecParams[0] & 0x1F;
- LightColor[l][1] = (ExecParams[0] >> 5) & 0x1F;
- LightColor[l][2] = (ExecParams[0] >> 10) & 0x1F;
+ u32 l = entry.Param >> 30;
+ LightColor[l][0] = entry.Param & 0x1F;
+ LightColor[l][1] = (entry.Param >> 5) & 0x1F;
+ LightColor[l][2] = (entry.Param >> 10) & 0x1F;
}
AddCycles(1);
break;
- case 0x34: // shininess table
- {
- for (int i = 0; i < 128; i += 4)
- {
- u32 val = ExecParams[i >> 2];
- ShininessTable[i + 0] = val & 0xFF;
- ShininessTable[i + 1] = (val >> 8) & 0xFF;
- ShininessTable[i + 2] = (val >> 16) & 0xFF;
- ShininessTable[i + 3] = val >> 24;
- }
- }
- break;
-
case 0x40: // begin polygons
+ StallPolygonPipeline(1, 0);
// TODO: check if there was a polygon being defined but incomplete
// such cases seem to freeze the GPU
- PolygonMode = ExecParams[0] & 0x3;
+ PolygonMode = entry.Param & 0x3;
VertexNum = 0;
VertexNumInPoly = 0;
NumConsecutivePolygons = 0;
@@ -2337,6 +2138,7 @@ void ExecuteCommand()
break;
case 0x41: // end polygons
+ VertexPipelineCmdDelayed8();
// TODO: research this?
// it doesn't seem to have any effect whatsoever, but
// its timing characteristics are different from those of other
@@ -2344,8 +2146,9 @@ void ExecuteCommand()
break;
case 0x50: // flush
+ VertexPipelineCmdDelayed4();
FlushRequest = 1;
- FlushAttributes = ExecParams[0] & 0x3;
+ FlushAttributes = entry.Param & 0x3;
CycleCount = 325;
// probably safe to just reset all pipelines
// but needs checked
@@ -2355,40 +2158,267 @@ void ExecuteCommand()
VertexSlotCounter = 0;
VertexSlotsFree = 1;
break;
-
+
case 0x60: // viewport x1,y1,x2,y2
+ VertexPipelineCmdDelayed8();
// note: viewport Y coordinates are upside-down
- Viewport[0] = ExecParams[0] & 0xFF; // x0
- Viewport[1] = (191 - ((ExecParams[0] >> 8) & 0xFF)) & 0xFF; // y0
- Viewport[2] = (ExecParams[0] >> 16) & 0xFF; // x1
- Viewport[3] = (191 - (ExecParams[0] >> 24)) & 0xFF; // y1
+ Viewport[0] = entry.Param & 0xFF; // x0
+ Viewport[1] = (191 - ((entry.Param >> 8) & 0xFF)) & 0xFF; // y0
+ Viewport[2] = (entry.Param >> 16) & 0xFF; // x1
+ Viewport[3] = (191 - (entry.Param >> 24)) & 0xFF; // y1
Viewport[4] = (Viewport[2] - Viewport[0] + 1) & 0x1FF; // width
Viewport[5] = (Viewport[1] - Viewport[3] + 1) & 0xFF; // height
break;
- case 0x70: // box test
- NumTestCommands -= 3;
- BoxTest(ExecParams);
- break;
-
- case 0x71: // pos test
- NumTestCommands -= 2;
- CurVertex[0] = ExecParams[0] & 0xFFFF;
- CurVertex[1] = ExecParams[0] >> 16;
- CurVertex[2] = ExecParams[1] & 0xFFFF;
- PosTest();
- break;
-
- case 0x72: // vec test
- NumTestCommands--;
- VecTest(ExecParams);
- break;
-
default:
+ VertexPipelineCmdDelayed4();
//printf("!! UNKNOWN GX COMMAND %02X %08X\n", entry.Command, entry.Param);
break;
}
}
+ else
+ {
+ ExecParams[ExecParamCount] = entry.Param;
+ ExecParamCount++;
+
+ if (ExecParamCount == 1)
+ {
+ // delay the first command entry as needed
+ switch (entry.Command)
+ {
+ // commands that stall the polygon pipeline
+ case 0x23: VertexPipelineSubmitCmd(); break;
+ case 0x34:
+ case 0x71:
+ VertexPipelineCmdDelayed8();
+ break;
+ case 0x70: StallPolygonPipeline(10 + 1, 0); break;
+ case 0x72: VertexPipelineCmdDelayed6(); break;
+ default: VertexPipelineCmdDelayed4(); break;
+ }
+ }
+ else
+ {
+ AddCycles(1);
+
+ if (ExecParamCount >= paramsRequiredCount)
+ {
+ /*printf("[GXS:%08X] 0x%02X, ", GXStat, entry.Command);
+ for (int k = 0; k < ExecParamCount; k++) printf("0x%08X, ", ExecParams[k]);
+ printf("\n");*/
+
+ ExecParamCount = 0;
+
+ switch (entry.Command)
+ {
+ case 0x16: // load 4x4
+ if (MatrixMode == 0)
+ {
+ MatrixLoad4x4(ProjMatrix, (s32*)ExecParams);
+ ClipMatrixDirty = true;
+ AddCycles(18);
+ }
+ else if (MatrixMode == 3)
+ {
+ MatrixLoad4x4(TexMatrix, (s32*)ExecParams);
+ AddCycles(10);
+ }
+ else
+ {
+ MatrixLoad4x4(PosMatrix, (s32*)ExecParams);
+ if (MatrixMode == 2)
+ MatrixLoad4x4(VecMatrix, (s32*)ExecParams);
+ ClipMatrixDirty = true;
+ AddCycles(18);
+ }
+ break;
+
+ case 0x17: // load 4x3
+ if (MatrixMode == 0)
+ {
+ MatrixLoad4x3(ProjMatrix, (s32*)ExecParams);
+ ClipMatrixDirty = true;
+ AddCycles(18);
+ }
+ else if (MatrixMode == 3)
+ {
+ MatrixLoad4x3(TexMatrix, (s32*)ExecParams);
+ AddCycles(7);
+ }
+ else
+ {
+ MatrixLoad4x3(PosMatrix, (s32*)ExecParams);
+ if (MatrixMode == 2)
+ MatrixLoad4x3(VecMatrix, (s32*)ExecParams);
+ ClipMatrixDirty = true;
+ AddCycles(18);
+ }
+ break;
+
+ case 0x18: // mult 4x4
+ if (MatrixMode == 0)
+ {
+ MatrixMult4x4(ProjMatrix, (s32*)ExecParams);
+ ClipMatrixDirty = true;
+ AddCycles(35 - 16);
+ }
+ else if (MatrixMode == 3)
+ {
+ MatrixMult4x4(TexMatrix, (s32*)ExecParams);
+ AddCycles(33 - 16);
+ }
+ else
+ {
+ MatrixMult4x4(PosMatrix, (s32*)ExecParams);
+ if (MatrixMode == 2)
+ {
+ MatrixMult4x4(VecMatrix, (s32*)ExecParams);
+ AddCycles(35 + 30 - 16);
+ }
+ else AddCycles(35 - 16);
+ ClipMatrixDirty = true;
+ }
+ break;
+
+ case 0x19: // mult 4x3
+ if (MatrixMode == 0)
+ {
+ MatrixMult4x3(ProjMatrix, (s32*)ExecParams);
+ ClipMatrixDirty = true;
+ AddCycles(35 - 12);
+ }
+ else if (MatrixMode == 3)
+ {
+ MatrixMult4x3(TexMatrix, (s32*)ExecParams);
+ AddCycles(33 - 12);
+ }
+ else
+ {
+ MatrixMult4x3(PosMatrix, (s32*)ExecParams);
+ if (MatrixMode == 2)
+ {
+ MatrixMult4x3(VecMatrix, (s32*)ExecParams);
+ AddCycles(35 + 30 - 12);
+ }
+ else AddCycles(35 - 12);
+ ClipMatrixDirty = true;
+ }
+ break;
+
+ case 0x1A: // mult 3x3
+ if (MatrixMode == 0)
+ {
+ MatrixMult3x3(ProjMatrix, (s32*)ExecParams);
+ ClipMatrixDirty = true;
+ AddCycles(35 - 9);
+ }
+ else if (MatrixMode == 3)
+ {
+ MatrixMult3x3(TexMatrix, (s32*)ExecParams);
+ AddCycles(33 - 9);
+ }
+ else
+ {
+ MatrixMult3x3(PosMatrix, (s32*)ExecParams);
+ if (MatrixMode == 2)
+ {
+ MatrixMult3x3(VecMatrix, (s32*)ExecParams);
+ AddCycles(35 + 30 - 9);
+ }
+ else AddCycles(35 - 9);
+ ClipMatrixDirty = true;
+ }
+ break;
+
+ case 0x1B: // scale
+ if (MatrixMode == 0)
+ {
+ MatrixScale(ProjMatrix, (s32*)ExecParams);
+ ClipMatrixDirty = true;
+ AddCycles(35 - 3);
+ }
+ else if (MatrixMode == 3)
+ {
+ MatrixScale(TexMatrix, (s32*)ExecParams);
+ AddCycles(33 - 3);
+ }
+ else
+ {
+ MatrixScale(PosMatrix, (s32*)ExecParams);
+ ClipMatrixDirty = true;
+ AddCycles(35 - 3);
+ }
+ break;
+
+ case 0x1C: // translate
+ if (MatrixMode == 0)
+ {
+ MatrixTranslate(ProjMatrix, (s32*)ExecParams);
+ ClipMatrixDirty = true;
+ AddCycles(35 - 3);
+ }
+ else if (MatrixMode == 3)
+ {
+ MatrixTranslate(TexMatrix, (s32*)ExecParams);
+ AddCycles(33 - 3);
+ }
+ else
+ {
+ MatrixTranslate(PosMatrix, (s32*)ExecParams);
+ if (MatrixMode == 2)
+ {
+ MatrixTranslate(VecMatrix, (s32*)ExecParams);
+ AddCycles(35 + 30 - 3);
+ }
+ else AddCycles(35 - 3);
+ ClipMatrixDirty = true;
+ }
+ break;
+
+ case 0x23: // full vertex
+ CurVertex[0] = ExecParams[0] & 0xFFFF;
+ CurVertex[1] = ExecParams[0] >> 16;
+ CurVertex[2] = ExecParams[1] & 0xFFFF;
+ SubmitVertex();
+ break;
+
+ case 0x34: // shininess table
+ {
+ for (int i = 0; i < 128; i += 4)
+ {
+ u32 val = ExecParams[i >> 2];
+ ShininessTable[i + 0] = val & 0xFF;
+ ShininessTable[i + 1] = (val >> 8) & 0xFF;
+ ShininessTable[i + 2] = (val >> 16) & 0xFF;
+ ShininessTable[i + 3] = val >> 24;
+ }
+ }
+ break;
+
+ case 0x71: // pos test
+ NumTestCommands -= 2;
+ CurVertex[0] = ExecParams[0] & 0xFFFF;
+ CurVertex[1] = ExecParams[0] >> 16;
+ CurVertex[2] = ExecParams[1] & 0xFFFF;
+ PosTest();
+ break;
+
+ case 0x70: // box test
+ NumTestCommands -= 3;
+ BoxTest(ExecParams);
+ break;
+
+ case 0x72: // vec test
+ NumTestCommands--;
+ VecTest(ExecParams);
+ break;
+
+ default:
+ __builtin_unreachable();
+ }
+ }
+ }
+ }
}
s32 CyclesToRunFor()
@@ -2414,7 +2444,7 @@ void FinishWork(s32 cycles)
void Run()
{
if (!GeometryEnabled || FlushRequest ||
- (CmdPIPE->IsEmpty() && !(GXStat & (1<<27))))
+ (CmdPIPE.IsEmpty() && !(GXStat & (1<<27))))
{
Timestamp = NDS::ARM9Timestamp >> NDS::ARM9ClockShift;
return;
@@ -2426,7 +2456,7 @@ void Run()
if (CycleCount <= 0)
{
- while (CycleCount <= 0 && !CmdPIPE->IsEmpty())
+ while (CycleCount <= 0 && !CmdPIPE.IsEmpty())
{
if (NumPushPopCommands == 0) GXStat &= ~(1<<14);
if (NumTestCommands == 0) GXStat &= ~(1<<0);
@@ -2435,7 +2465,7 @@ void Run()
}
}
- if (CycleCount <= 0 && CmdPIPE->IsEmpty())
+ if (CycleCount <= 0 && CmdPIPE.IsEmpty())
{
if (GXStat & (1<<27)) FinishWork(-CycleCount);
else CycleCount = 0;
@@ -2451,8 +2481,8 @@ void CheckFIFOIRQ()
bool irq = false;
switch (GXStat >> 30)
{
- case 1: irq = (CmdFIFO->Level() < 128); break;
- case 2: irq = CmdFIFO->IsEmpty(); break;
+ case 1: irq = (CmdFIFO.Level() < 128); break;
+ case 2: irq = CmdFIFO.IsEmpty(); break;
}
if (irq) NDS::SetIRQ(0, NDS::IRQ_GXFIFO);
@@ -2461,7 +2491,7 @@ void CheckFIFOIRQ()
void CheckFIFODMA()
{
- if (CmdFIFO->Level() < 128)
+ if (CmdFIFO.Level() < 128)
NDS::CheckDMAs(0, 0x07);
}
@@ -2668,7 +2698,7 @@ u8 Read8(u32 addr)
{
Run();
- u32 fifolevel = CmdFIFO->Level();
+ u32 fifolevel = CmdFIFO.Level();
return fifolevel & 0xFF;
}
@@ -2676,7 +2706,7 @@ u8 Read8(u32 addr)
{
Run();
- u32 fifolevel = CmdFIFO->Level();
+ u32 fifolevel = CmdFIFO.Level();
return ((GXStat >> 24) & 0xFF) |
(fifolevel >> 8) |
@@ -2711,7 +2741,7 @@ u16 Read16(u32 addr)
{
Run();
- u32 fifolevel = CmdFIFO->Level();
+ u32 fifolevel = CmdFIFO.Level();
return (GXStat >> 16) |
fifolevel |
@@ -2747,7 +2777,7 @@ u32 Read32(u32 addr)
{
Run();
- u32 fifolevel = CmdFIFO->Level();
+ u32 fifolevel = CmdFIFO.Level();
return GXStat |
((PosMatrixStackPointer & 0x1F) << 8) |
diff --git a/src/GPU3D.h b/src/GPU3D.h
index 69b67fa7..62fe92c9 100644
--- a/src/GPU3D.h
+++ b/src/GPU3D.h
@@ -25,7 +25,7 @@
namespace GPU3D
{
-typedef struct
+struct Vertex
{
s32 Position[4];
s32 Color[3];
@@ -43,9 +43,9 @@ typedef struct
// TODO maybe: hi-res color? (that survives clipping)
s32 HiresPosition[2];
-} Vertex;
+};
-typedef struct
+struct Polygon
{
Vertex* Vertices[10];
u32 NumVertices;
@@ -74,7 +74,7 @@ typedef struct
u32 SortKey;
-} Polygon;
+};
extern u32 RenderDispCnt;
extern u8 RenderAlphaRef;
diff --git a/src/GPU3D_OpenGL.cpp b/src/GPU3D_OpenGL.cpp
index 88ae77a9..eb8fa62e 100644
--- a/src/GPU3D_OpenGL.cpp
+++ b/src/GPU3D_OpenGL.cpp
@@ -70,7 +70,7 @@ struct
GLuint ShaderConfigUBO;
-typedef struct
+struct RendererPolygon
{
Polygon* PolyData;
@@ -82,8 +82,7 @@ typedef struct
u32 EdgeIndicesOffset;
u32 RenderKey;
-
-} RendererPolygon;
+};
RendererPolygon PolygonList[2048];
int NumFinalPolys, NumOpaqueFinalPolys;
diff --git a/src/GPU3D_Soft.cpp b/src/GPU3D_Soft.cpp
index d66eb76e..7fcafb18 100644
--- a/src/GPU3D_Soft.cpp
+++ b/src/GPU3D_Soft.cpp
@@ -538,7 +538,7 @@ private:
s32 ycoverage, ycov_incr;
};
-typedef struct
+struct RendererPolygon
{
Polygon* PolyData;
@@ -548,7 +548,7 @@ typedef struct
u32 CurVL, CurVR;
u32 NextVL, NextVR;
-} RendererPolygon;
+};
RendererPolygon PolygonList[2048];
diff --git a/src/GPU_OpenGL.cpp b/src/GPU_OpenGL.cpp
index 0c6cf004..fb04ca01 100644
--- a/src/GPU_OpenGL.cpp
+++ b/src/GPU_OpenGL.cpp
@@ -40,7 +40,13 @@ GLuint Comp3DXPosLoc[1];
GLuint CompVertexBufferID;
GLuint CompVertexArrayID;
-float CompVertices[2 * 3*2 * 2]; // position
+
+struct CompVertex
+{
+ float Position[2];
+ float Texcoord[2];
+};
+CompVertex CompVertices[2 * 3*2];
GLuint CompScreenInputTex;
GLuint CompScreenOutputTex;
@@ -59,6 +65,7 @@ bool Init()
GLint uni_id;
glBindAttribLocation(CompShader[i][2], 0, "vPosition");
+ glBindAttribLocation(CompShader[i][2], 1, "vTexcoord");
glBindFragDataLocation(CompShader[i][2], 0, "oColor");
if (!OpenGL::LinkShaderProgram(CompShader[i]))
@@ -74,25 +81,29 @@ bool Init()
glUniform1i(uni_id, 1);
}
-#define SETVERTEX(i, x, y) \
- CompVertices[2*(i) + 0] = x; \
- CompVertices[2*(i) + 1] = y;
+ // all this mess is to prevent bleeding
+#define SETVERTEX(i, x, y, offset) \
+ CompVertices[i].Position[0] = x; \
+ CompVertices[i].Position[1] = y + offset; \
+ CompVertices[i].Texcoord[0] = (x + 1.f) * (256.f / 2.f); \
+ CompVertices[i].Texcoord[1] = (y + 1.f) * (384.f / 2.f)
+ const float padOffset = 1.f/(192*2.f+2.f)*2.f;
// top screen
- SETVERTEX(0, -1, 1);
- SETVERTEX(1, 1, 0);
- SETVERTEX(2, 1, 1);
- SETVERTEX(3, -1, 1);
- SETVERTEX(4, -1, 0);
- SETVERTEX(5, 1, 0);
+ SETVERTEX(0, -1, 1, 0);
+ SETVERTEX(1, 1, 0, padOffset);
+ SETVERTEX(2, 1, 1, 0);
+ SETVERTEX(3, -1, 1, 0);
+ SETVERTEX(4, -1, 0, padOffset);
+ SETVERTEX(5, 1, 0, padOffset);
// bottom screen
- SETVERTEX(6, -1, 0);
- SETVERTEX(7, 1, -1);
- SETVERTEX(8, 1, 0);
- SETVERTEX(9, -1, 0);
- SETVERTEX(10, -1, -1);
- SETVERTEX(11, 1, -1);
+ SETVERTEX(6, -1, 0, -padOffset);
+ SETVERTEX(7, 1, -1, 0);
+ SETVERTEX(8, 1, 0, -padOffset);
+ SETVERTEX(9, -1, 0, -padOffset);
+ SETVERTEX(10, -1, -1, 0);
+ SETVERTEX(11, 1, -1, 0);
#undef SETVERTEX
@@ -103,7 +114,9 @@ bool Init()
glGenVertexArrays(1, &CompVertexArrayID);
glBindVertexArray(CompVertexArrayID);
glEnableVertexAttribArray(0); // position
- glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 2*4, (void*)(0));
+ glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(CompVertex), (void*)(offsetof(CompVertex, Position)));
+ glEnableVertexAttribArray(1); // texcoord
+ glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(CompVertex), (void*)(offsetof(CompVertex, Texcoord)));
glGenFramebuffers(1, &CompScreenOutputFB);
@@ -152,10 +165,14 @@ void SetRenderSettings(RenderSettings& settings)
Scale = scale;
ScreenW = 256 * scale;
- ScreenH = 384 * scale;
+ ScreenH = (384+2) * scale;
glBindTexture(GL_TEXTURE_2D, CompScreenOutputTex);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, ScreenW, ScreenH, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+ // fill the padding
+ u8 zeroPixels[ScreenW*2*scale*4];
+ memset(zeroPixels, 0, sizeof(zeroPixels));
+ glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 192*scale, ScreenW, 2*scale, GL_RGBA, GL_UNSIGNED_BYTE, zeroPixels);
GLenum fbassign[] = {GL_COLOR_ATTACHMENT0};
glBindFramebuffer(GL_FRAMEBUFFER, CompScreenOutputFB);
diff --git a/src/GPU_OpenGL_shaders.h b/src/GPU_OpenGL_shaders.h
index 03ddb7af..44be4d05 100644
--- a/src/GPU_OpenGL_shaders.h
+++ b/src/GPU_OpenGL_shaders.h
@@ -22,6 +22,7 @@
const char* kCompositorVS = R"(#version 140
in vec2 vPosition;
+in vec2 vTexcoord;
smooth out vec2 fTexcoord;
@@ -33,7 +34,7 @@ void main()
fpos.w = 1.0;
gl_Position = fpos;
- fTexcoord = (vPosition + vec2(1.0, 1.0)) * (vec2(256.0, 384.0) / 2.0);
+ fTexcoord = vTexcoord;
}
)";
diff --git a/src/NDS.cpp b/src/NDS.cpp
index 8b49328f..7131bae0 100644
--- a/src/NDS.cpp
+++ b/src/NDS.cpp
@@ -139,8 +139,8 @@ u32 DMA9Fill[4];
u16 IPCSync9, IPCSync7;
u16 IPCFIFOCnt9, IPCFIFOCnt7;
-FIFO* IPCFIFO9; // FIFO in which the ARM9 writes
-FIFO* IPCFIFO7;
+FIFO IPCFIFO9; // FIFO in which the ARM9 writes
+FIFO IPCFIFO7;
u16 DivCnt;
u32 DivNumerator[2];
@@ -190,9 +190,6 @@ bool Init()
DMAs[6] = new DMA(1, 2);
DMAs[7] = new DMA(1, 3);
- IPCFIFO9 = new FIFO(16);
- IPCFIFO7 = new FIFO(16);
-
if (!NDSCart::Init()) return false;
if (!GBACart::Init()) return false;
if (!GPU::Init()) return false;
@@ -220,9 +217,6 @@ void DeInit()
for (int i = 0; i < 8; i++)
delete DMAs[i];
- delete IPCFIFO9;
- delete IPCFIFO7;
-
NDSCart::DeInit();
GBACart::DeInit();
GPU::DeInit();
@@ -557,8 +551,8 @@ void Reset()
IPCSync7 = 0;
IPCFIFOCnt9 = 0;
IPCFIFOCnt7 = 0;
- IPCFIFO9->Clear();
- IPCFIFO7->Clear();
+ IPCFIFO9.Clear();
+ IPCFIFO7.Clear();
DivCnt = 0;
SqrtCnt = 0;
@@ -736,8 +730,8 @@ bool DoSavestate(Savestate* file)
file->Var16(&IPCSync7);
file->Var16(&IPCFIFOCnt9);
file->Var16(&IPCFIFOCnt7);
- IPCFIFO9->DoSavestate(file);
- IPCFIFO7->DoSavestate(file);
+ IPCFIFO9.DoSavestate(file);
+ IPCFIFO7.DoSavestate(file);
file->Var16(&DivCnt);
file->Var16(&SqrtCnt);
@@ -1881,7 +1875,7 @@ u8 ARM9Read8(u32 addr)
case 0x05000000:
if (!(PowerControl9 & ((addr & 0x400) ? (1<<9) : (1<<1)))) return 0;
- return *(u8*)&GPU::Palette[addr & 0x7FF];
+ return GPU::ReadPalette(addr);
case 0x06000000:
switch (addr & 0x00E00000)
@@ -1895,7 +1889,7 @@ u8 ARM9Read8(u32 addr)
case 0x07000000:
if (!(PowerControl9 & ((addr & 0x400) ? (1<<9) : (1<<1)))) return 0;
- return *(u8*)&GPU::OAM[addr & 0x7FF];
+ return GPU::ReadOAM(addr);
case 0x08000000:
case 0x09000000:
@@ -1946,7 +1940,7 @@ u16 ARM9Read16(u32 addr)
case 0x05000000:
if (!(PowerControl9 & ((addr & 0x400) ? (1<<9) : (1<<1)))) return 0;
- return *(u16*)&GPU::Palette[addr & 0x7FF];
+ return GPU::ReadPalette(addr);
case 0x06000000:
switch (addr & 0x00E00000)
@@ -1960,7 +1954,7 @@ u16 ARM9Read16(u32 addr)
case 0x07000000:
if (!(PowerControl9 & ((addr & 0x400) ? (1<<9) : (1<<1)))) return 0;
- return *(u16*)&GPU::OAM[addr & 0x7FF];
+ return GPU::ReadOAM(addr);
case 0x08000000:
case 0x09000000:
@@ -2011,7 +2005,7 @@ u32 ARM9Read32(u32 addr)
case 0x05000000:
if (!(PowerControl9 & ((addr & 0x400) ? (1<<9) : (1<<1)))) return 0;
- return *(u32*)&GPU::Palette[addr & 0x7FF];
+ return GPU::ReadPalette(addr);
case 0x06000000:
switch (addr & 0x00E00000)
@@ -2025,7 +2019,7 @@ u32 ARM9Read32(u32 addr)
case 0x07000000:
if (!(PowerControl9 & ((addr & 0x400) ? (1<<9) : (1<<1)))) return 0;
- return *(u32*)&GPU::OAM[addr & 0x7FF];
+ return GPU::ReadOAM(addr & 0x7FF);
case 0x08000000:
case 0x09000000:
@@ -2132,7 +2126,7 @@ void ARM9Write16(u32 addr, u16 val)
case 0x05000000:
if (!(PowerControl9 & ((addr & 0x400) ? (1<<9) : (1<<1)))) return;
- *(u16*)&GPU::Palette[addr & 0x7FF] = val;
+ GPU::WritePalette(addr, val);
return;
case 0x06000000:
@@ -2150,7 +2144,7 @@ void ARM9Write16(u32 addr, u16 val)
case 0x07000000:
if (!(PowerControl9 & ((addr & 0x400) ? (1<<9) : (1<<1)))) return;
- *(u16*)&GPU::OAM[addr & 0x7FF] = val;
+ GPU::WriteOAM(addr, val);
return;
case 0x08000000:
@@ -2207,7 +2201,7 @@ void ARM9Write32(u32 addr, u32 val)
case 0x05000000:
if (!(PowerControl9 & ((addr & 0x400) ? (1<<9) : (1<<1)))) return;
- *(u32*)&GPU::Palette[addr & 0x7FF] = val;
+ GPU::WritePalette(addr, val);
return;
case 0x06000000:
@@ -2225,7 +2219,7 @@ void ARM9Write32(u32 addr, u32 val)
case 0x07000000:
if (!(PowerControl9 & ((addr & 0x400) ? (1<<9) : (1<<1)))) return;
- *(u32*)&GPU::OAM[addr & 0x7FF] = val;
+ GPU::WriteOAM(addr, val);
return;
case 0x08000000:
@@ -2899,10 +2893,10 @@ u16 ARM9IORead16(u32 addr)
case 0x04000184:
{
u16 val = IPCFIFOCnt9;
- if (IPCFIFO9->IsEmpty()) val |= 0x0001;
- else if (IPCFIFO9->IsFull()) val |= 0x0002;
- if (IPCFIFO7->IsEmpty()) val |= 0x0100;
- else if (IPCFIFO7->IsFull()) val |= 0x0200;
+ if (IPCFIFO9.IsEmpty()) val |= 0x0001;
+ else if (IPCFIFO9.IsFull()) val |= 0x0002;
+ if (IPCFIFO7.IsEmpty()) val |= 0x0100;
+ else if (IPCFIFO7.IsFull()) val |= 0x0200;
return val;
}
@@ -3057,22 +3051,22 @@ u32 ARM9IORead32(u32 addr)
if (IPCFIFOCnt9 & 0x8000)
{
u32 ret;
- if (IPCFIFO7->IsEmpty())
+ if (IPCFIFO7.IsEmpty())
{
IPCFIFOCnt9 |= 0x4000;
- ret = IPCFIFO7->Peek();
+ ret = IPCFIFO7.Peek();
}
else
{
- ret = IPCFIFO7->Read();
+ ret = IPCFIFO7.Read();
- if (IPCFIFO7->IsEmpty() && (IPCFIFOCnt7 & 0x0004))
+ if (IPCFIFO7.IsEmpty() && (IPCFIFOCnt7 & 0x0004))
SetIRQ(1, IRQ_IPCSendDone);
}
return ret;
}
else
- return IPCFIFO7->Peek();
+ return IPCFIFO7.Peek();
case 0x04100010:
if (!(ExMemCnt[0] & (1<<11))) return NDSCart::ReadROMData();
@@ -3238,10 +3232,10 @@ void ARM9IOWrite16(u32 addr, u16 val)
case 0x04000184:
if (val & 0x0008)
- IPCFIFO9->Clear();
- if ((val & 0x0004) && (!(IPCFIFOCnt9 & 0x0004)) && IPCFIFO9->IsEmpty())
+ IPCFIFO9.Clear();
+ if ((val & 0x0004) && (!(IPCFIFOCnt9 & 0x0004)) && IPCFIFO9.IsEmpty())
SetIRQ(0, IRQ_IPCSendDone);
- if ((val & 0x0400) && (!(IPCFIFOCnt9 & 0x0400)) && (!IPCFIFO7->IsEmpty()))
+ if ((val & 0x0400) && (!(IPCFIFOCnt9 & 0x0400)) && (!IPCFIFO7.IsEmpty()))
SetIRQ(0, IRQ_IPCRecv);
if (val & 0x4000)
IPCFIFOCnt9 &= ~0x4000;
@@ -3407,12 +3401,12 @@ void ARM9IOWrite32(u32 addr, u32 val)
case 0x04000188:
if (IPCFIFOCnt9 & 0x8000)
{
- if (IPCFIFO9->IsFull())
+ if (IPCFIFO9.IsFull())
IPCFIFOCnt9 |= 0x4000;
else
{
- bool wasempty = IPCFIFO9->IsEmpty();
- IPCFIFO9->Write(val);
+ bool wasempty = IPCFIFO9.IsEmpty();
+ IPCFIFO9.Write(val);
if ((IPCFIFOCnt7 & 0x0400) && wasempty)
SetIRQ(1, IRQ_IPCRecv);
}
@@ -3590,10 +3584,10 @@ u16 ARM7IORead16(u32 addr)
case 0x04000184:
{
u16 val = IPCFIFOCnt7;
- if (IPCFIFO7->IsEmpty()) val |= 0x0001;
- else if (IPCFIFO7->IsFull()) val |= 0x0002;
- if (IPCFIFO9->IsEmpty()) val |= 0x0100;
- else if (IPCFIFO9->IsFull()) val |= 0x0200;
+ if (IPCFIFO7.IsEmpty()) val |= 0x0001;
+ else if (IPCFIFO7.IsFull()) val |= 0x0002;
+ if (IPCFIFO9.IsEmpty()) val |= 0x0100;
+ else if (IPCFIFO9.IsFull()) val |= 0x0200;
return val;
}
@@ -3689,22 +3683,22 @@ u32 ARM7IORead32(u32 addr)
if (IPCFIFOCnt7 & 0x8000)
{
u32 ret;
- if (IPCFIFO9->IsEmpty())
+ if (IPCFIFO9.IsEmpty())
{
IPCFIFOCnt7 |= 0x4000;
- ret = IPCFIFO9->Peek();
+ ret = IPCFIFO9.Peek();
}
else
{
- ret = IPCFIFO9->Read();
+ ret = IPCFIFO9.Read();
- if (IPCFIFO9->IsEmpty() && (IPCFIFOCnt9 & 0x0004))
+ if (IPCFIFO9.IsEmpty() && (IPCFIFOCnt9 & 0x0004))
SetIRQ(0, IRQ_IPCSendDone);
}
return ret;
}
else
- return IPCFIFO9->Peek();
+ return IPCFIFO9.Peek();
case 0x04100010:
if (ExMemCnt[0] & (1<<11)) return NDSCart::ReadROMData();
@@ -3841,10 +3835,10 @@ void ARM7IOWrite16(u32 addr, u16 val)
case 0x04000184:
if (val & 0x0008)
- IPCFIFO7->Clear();
- if ((val & 0x0004) && (!(IPCFIFOCnt7 & 0x0004)) && IPCFIFO7->IsEmpty())
+ IPCFIFO7.Clear();
+ if ((val & 0x0004) && (!(IPCFIFOCnt7 & 0x0004)) && IPCFIFO7.IsEmpty())
SetIRQ(1, IRQ_IPCSendDone);
- if ((val & 0x0400) && (!(IPCFIFOCnt7 & 0x0400)) && (!IPCFIFO9->IsEmpty()))
+ if ((val & 0x0400) && (!(IPCFIFOCnt7 & 0x0400)) && (!IPCFIFO9.IsEmpty()))
SetIRQ(1, IRQ_IPCRecv);
if (val & 0x4000)
IPCFIFOCnt7 &= ~0x4000;
@@ -3977,12 +3971,12 @@ void ARM7IOWrite32(u32 addr, u32 val)
case 0x04000188:
if (IPCFIFOCnt7 & 0x8000)
{
- if (IPCFIFO7->IsFull())
+ if (IPCFIFO7.IsFull())
IPCFIFOCnt7 |= 0x4000;
else
{
- bool wasempty = IPCFIFO7->IsEmpty();
- IPCFIFO7->Write(val);
+ bool wasempty = IPCFIFO7.IsEmpty();
+ IPCFIFO7.Write(val);
if ((IPCFIFOCnt9 & 0x0400) && wasempty)
SetIRQ(0, IRQ_IPCRecv);
}
diff --git a/src/NDS.h b/src/NDS.h
index 98a0f7d6..46a57a49 100644
--- a/src/NDS.h
+++ b/src/NDS.h
@@ -54,13 +54,12 @@ enum
Event_MAX
};
-typedef struct
+struct SchedEvent
{
void (*Func)(u32 param);
u64 Timestamp;
u32 Param;
-
-} SchedEvent;
+};
enum
{
@@ -121,21 +120,19 @@ enum
IRQ2_DSi_MicExt
};
-typedef struct
+struct Timer
{
u16 Reload;
u16 Cnt;
u32 Counter;
u32 CycleShift;
+};
-} Timer;
-
-typedef struct
+struct MemRegion
{
u8* Mem;
u32 Mask;
-
-} MemRegion;
+};
extern int ConsoleType;
extern int CurCPU;
diff --git a/src/NDSCart.cpp b/src/NDSCart.cpp
index 2d8396ad..fa235a4e 100644
--- a/src/NDSCart.cpp
+++ b/src/NDSCart.cpp
@@ -22,7 +22,6 @@
#include "DSi.h"
#include "NDSCart.h"
#include "ARM.h"
-#include "CRC32.h"
#include "DSi_AES.h"
#include "Platform.h"
#include "Config.h"
@@ -485,7 +484,6 @@ u8 TransferCmd[8];
bool CartInserted;
u8* CartROM;
u32 CartROMSize;
-u32 CartCRC;
u32 CartID;
bool CartIsHomebrew;
bool CartIsDSi;
@@ -932,9 +930,6 @@ bool LoadROM(const char* path, const char* sram, bool direct)
fclose(f);
//CartROM = f;
- CartCRC = CRC32(CartROM, CartROMSize);
- printf("ROM CRC32: %08X\n", CartCRC);
-
ROMListEntry romparams;
if (!ReadROMParams(gamecode, &romparams))
{
diff --git a/src/ROMList.h b/src/ROMList.h
index 03252bb0..685d8a5e 100644
--- a/src/ROMList.h
+++ b/src/ROMList.h
@@ -19,13 +19,12 @@
#ifndef ROMLIST_H
#define ROMLIST_H
-typedef struct
+struct ROMListEntry
{
u32 GameCode;
u32 ROMSize;
u32 SaveMemType;
-
-} ROMListEntry;
+};
ROMListEntry ROMList[] =
@@ -4006,6 +4005,7 @@ ROMListEntry ROMList[] =
{0x4A555143, 0x02000000, 0x00000002},
{0x4A555159, 0x08000000, 0x00000003},
{0x4A555241, 0x02000000, 0x00000003},
+ {0x4A555243, 0x10000000, 0x00000006},
{0x4A555259, 0x00800000, 0x00000001},
{0x4A555341, 0x04000000, 0x00000003},
{0x4A555359, 0x00800000, 0x00000003},
diff --git a/src/Wifi.cpp b/src/Wifi.cpp
index 29570076..4502f18c 100644
--- a/src/Wifi.cpp
+++ b/src/Wifi.cpp
@@ -55,7 +55,7 @@ u16 RFData1;
u16 RFData2;
u32 RFRegs[0x40];
-typedef struct
+struct TXSlot
{
u16 Addr;
u16 Length;
@@ -63,8 +63,7 @@ typedef struct
u8 CurPhase;
u32 CurPhaseTime;
u32 HalfwordTimeMask;
-
-} TXSlot;
+};
TXSlot TXSlots[6];
diff --git a/src/dolphin/Arm64Emitter.cpp b/src/dolphin/Arm64Emitter.cpp
index 289b20c5..ae6258d3 100644
--- a/src/dolphin/Arm64Emitter.cpp
+++ b/src/dolphin/Arm64Emitter.cpp
@@ -15,6 +15,10 @@
#include "../types.h"
#include "MathUtil.h"
+#ifdef __APPLE__
+ #include
+#endif
+
namespace Arm64Gen
{
namespace
@@ -384,7 +388,7 @@ void ARM64XEmitter::FlushIcacheSection(u8* start, u8* end)
if (start == end)
return;
-#if defined(IOS)
+#if defined(__APPLE__)
// Header file says this is equivalent to: sys_icache_invalidate(start, end - start);
sys_cache_control(kCacheFunctionPrepareForExecution, start, end - start);
#else
diff --git a/src/frontend/qt_sdl/LAN_PCap.h b/src/frontend/qt_sdl/LAN_PCap.h
index 250b8e90..f636e128 100644
--- a/src/frontend/qt_sdl/LAN_PCap.h
+++ b/src/frontend/qt_sdl/LAN_PCap.h
@@ -24,7 +24,7 @@
namespace LAN_PCap
{
-typedef struct
+struct AdapterData
{
char DeviceName[128];
char FriendlyName[128];
@@ -34,8 +34,7 @@ typedef struct
u8 IP_v4[4];
void* Internal;
-
-} AdapterData;
+};
extern AdapterData* Adapters;
diff --git a/src/frontend/qt_sdl/LAN_Socket.cpp b/src/frontend/qt_sdl/LAN_Socket.cpp
index 458c931d..c147e690 100644
--- a/src/frontend/qt_sdl/LAN_Socket.cpp
+++ b/src/frontend/qt_sdl/LAN_Socket.cpp
@@ -48,7 +48,7 @@ const u32 kClientIP = kSubnet | 0x10;
const u8 kServerMAC[6] = {0x00, 0xAB, 0x33, 0x28, 0x99, 0x44};
-FIFO* RXBuffer = nullptr;
+FIFO> 2)> RXBuffer;
u32 IPv4ID;
@@ -86,16 +86,16 @@ void RXEnqueue(const void* buf, int len)
int alignedlen = (len + 3) & ~3;
int totallen = alignedlen + 4;
- if (!RXBuffer->CanFit(totallen >> 2))
+ if (!RXBuffer.CanFit(totallen >> 2))
{
printf("slirp: !! NOT ENOUGH SPACE IN RX BUFFER\n");
return;
}
u32 header = (alignedlen & 0xFFFF) | (len << 16);
- RXBuffer->Write(header);
+ RXBuffer.Write(header);
for (int i = 0; i < alignedlen; i += 4)
- RXBuffer->Write(((u32*)buf)[i>>2]);
+ RXBuffer.Write(((u32*)buf)[i>>2]);
}
ssize_t SlirpCbSendPacket(const void* buf, size_t len, void* opaque)
@@ -202,8 +202,6 @@ bool Init()
//FDListSize = 0;
//memset(FDList, 0, sizeof(FDList));
- RXBuffer = new FIFO(0x8000 >> 2);
-
SlirpConfig cfg;
memset(&cfg, 0, sizeof(cfg));
cfg.version = 1;
@@ -228,12 +226,6 @@ void DeInit()
slirp_cleanup(Ctx);
Ctx = nullptr;
}
-
- if (RXBuffer)
- {
- delete RXBuffer;
- RXBuffer = nullptr;
- }
}
@@ -530,13 +522,13 @@ int RecvPacket(u8* data)
slirp_pollfds_poll(Ctx, res<0, SlirpCbGetREvents, nullptr);
}
- if (!RXBuffer->IsEmpty())
+ if (!RXBuffer.IsEmpty())
{
- u32 header = RXBuffer->Read();
+ u32 header = RXBuffer.Read();
u32 len = header & 0xFFFF;
for (int i = 0; i < len; i += 4)
- ((u32*)data)[i>>2] = RXBuffer->Read();
+ ((u32*)data)[i>>2] = RXBuffer.Read();
ret = header >> 16;
}
diff --git a/src/frontend/qt_sdl/PlatformConfig.cpp b/src/frontend/qt_sdl/PlatformConfig.cpp
index 98616623..46f8717f 100644
--- a/src/frontend/qt_sdl/PlatformConfig.cpp
+++ b/src/frontend/qt_sdl/PlatformConfig.cpp
@@ -72,6 +72,8 @@ char MicWavPath[1024];
char LastROMFolder[1024];
+char RecentROMList[10][1024];
+
int EnableCheats;
bool EnableJIT;
@@ -166,6 +168,17 @@ ConfigEntry PlatformConfigFile[] =
{"LastROMFolder", 1, LastROMFolder, 0, "", 1023},
+ {"RecentROM_0", 1, RecentROMList[0], 0, "", 1023},
+ {"RecentROM_1", 1, RecentROMList[1], 0, "", 1023},
+ {"RecentROM_2", 1, RecentROMList[2], 0, "", 1023},
+ {"RecentROM_3", 1, RecentROMList[3], 0, "", 1023},
+ {"RecentROM_4", 1, RecentROMList[4], 0, "", 1023},
+ {"RecentROM_5", 1, RecentROMList[5], 0, "", 1023},
+ {"RecentROM_6", 1, RecentROMList[6], 0, "", 1023},
+ {"RecentROM_7", 1, RecentROMList[7], 0, "", 1023},
+ {"RecentROM_8", 1, RecentROMList[8], 0, "", 1023},
+ {"RecentROM_9", 1, RecentROMList[9], 0, "", 1023},
+
{"EnableCheats", 0, &EnableCheats, 0, NULL, 0},
{"", -1, NULL, 0, NULL, 0}
diff --git a/src/frontend/qt_sdl/PlatformConfig.h b/src/frontend/qt_sdl/PlatformConfig.h
index ca03d80b..2d73dea0 100644
--- a/src/frontend/qt_sdl/PlatformConfig.h
+++ b/src/frontend/qt_sdl/PlatformConfig.h
@@ -86,6 +86,8 @@ extern char MicWavPath[1024];
extern char LastROMFolder[1024];
+extern char RecentROMList[10][1024];
+
extern int EnableCheats;
}
diff --git a/src/frontend/qt_sdl/VideoSettingsDialog.cpp b/src/frontend/qt_sdl/VideoSettingsDialog.cpp
index 1397ccd9..934090de 100644
--- a/src/frontend/qt_sdl/VideoSettingsDialog.cpp
+++ b/src/frontend/qt_sdl/VideoSettingsDialog.cpp
@@ -84,6 +84,14 @@ VideoSettingsDialog::VideoSettingsDialog(QWidget* parent) : QDialog(parent), ui(
ui->cbxGLResolution->setEnabled(true);
ui->cbBetterPolygons->setEnabled(true);
}
+
+ // sorry
+ ui->cbVSync->hide();
+ ui->cbVSync->setEnabled(false);
+ ui->sbVSyncInterval->hide();
+ ui->sbVSyncInterval->setEnabled(false);
+ ui->label_2->hide();
+ ui->groupBox->layout()->addItem(new QSpacerItem(1, 1, QSizePolicy::Minimum, QSizePolicy::Expanding));
}
VideoSettingsDialog::~VideoSettingsDialog()
diff --git a/src/frontend/qt_sdl/main.cpp b/src/frontend/qt_sdl/main.cpp
index a4730627..91e56f0a 100644
--- a/src/frontend/qt_sdl/main.cpp
+++ b/src/frontend/qt_sdl/main.cpp
@@ -875,22 +875,26 @@ void ScreenPanelGL::initializeGL()
screenShader->setUniformValue("ScreenTex", (GLint)0);
screenShader->release();
+ // to prevent bleeding between both parts of the screen
+ // with bilinear filtering enabled
+ const int paddedHeight = 192*2+2;
+ const float padPixels = 1.f / paddedHeight;
- float vertices[] =
+ const float vertices[] =
{
- 0, 0, 0, 0,
- 0, 192, 0, 0.5,
- 256, 192, 1, 0.5,
- 0, 0, 0, 0,
- 256, 192, 1, 0.5,
- 256, 0, 1, 0,
+ 0.f, 0.f, 0.f, 0.f,
+ 0.f, 192.f, 0.f, 0.5f - padPixels,
+ 256.f, 192.f, 1.f, 0.5f - padPixels,
+ 0.f, 0.f, 0.f, 0.f,
+ 256.f, 192.f, 1.f, 0.5f - padPixels,
+ 256.f, 0.f, 1.f, 0.f,
- 0, 0, 0, 0.5,
- 0, 192, 0, 1,
- 256, 192, 1, 1,
- 0, 0, 0, 0.5,
- 256, 192, 1, 1,
- 256, 0, 1, 0.5
+ 0.f, 0.f, 0.f, 0.5f + padPixels,
+ 0.f, 192.f, 0.f, 1.f,
+ 256.f, 192.f, 1.f, 1.f,
+ 0.f, 0.f, 0.f, 0.5f + padPixels,
+ 256.f, 192.f, 1.f, 1.f,
+ 256.f, 0.f, 1.f, 0.5f + padPixels
};
glGenBuffers(1, &screenVertexBuffer);
@@ -911,7 +915,11 @@ void ScreenPanelGL::initializeGL()
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 192*2, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, paddedHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+ // fill the padding
+ u8 zeroData[256*4*4];
+ memset(zeroData, 0, sizeof(zeroData));
+ glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 192, 256, 2, GL_RGBA, GL_UNSIGNED_BYTE, zeroData);
OSD::Init(this);
}
@@ -949,7 +957,7 @@ void ScreenPanelGL::paintGL()
{
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 256, 192, GL_RGBA,
GL_UNSIGNED_BYTE, GPU::Framebuffer[frontbuf][0]);
- glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 192, 256, 192, GL_RGBA,
+ glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 192+2, 256, 192, GL_RGBA,
GL_UNSIGNED_BYTE, GPU::Framebuffer[frontbuf][1]);
}
}
@@ -1021,6 +1029,14 @@ MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent)
actOpenROM = menu->addAction("Open ROM...");
connect(actOpenROM, &QAction::triggered, this, &MainWindow::onOpenFile);
+ recentMenu = menu->addMenu("Open Recent");
+ for(int i = 0; i < 10; ++i)
+ {
+ if(strlen(Config::RecentROMList[i]) > 0)
+ recentFileList.push_back(Config::RecentROMList[i]);
+ }
+ updateRecentFilesMenu();
+
//actBootFirmware = menu->addAction("Launch DS menu");
actBootFirmware = menu->addAction("Boot firmware");
connect(actBootFirmware, &QAction::triggered, this, &MainWindow::onBootFirmware);
@@ -1333,7 +1349,7 @@ void MainWindow::keyPressEvent(QKeyEvent* event)
if (event->isAutoRepeat()) return;
// TODO!! REMOVE ME IN RELEASE BUILDS!!
- if (event->key() == Qt::Key_F11) NDS::debug(0);
+ //if (event->key() == Qt::Key_F11) NDS::debug(0);
Input::KeyPress(event);
}
@@ -1457,7 +1473,20 @@ void MainWindow::onOpenFile()
"Open ROM",
Config::LastROMFolder,
"DS ROMs (*.nds *.dsi *.srl *.zip *.7z);;GBA ROMs (*.gba *.zip *.7z);;Other Compressed ROMs (*.zip *.7z *.rar *.tar *.tar.gz *.tar.xz *tar.bz2);;Any file (*.*)");
+
+ if (filename.isEmpty())
+ {
+ emuThread->emuUnpause();
+ return;
+ }
+void MainWindow::loadROM(QString filename)
+{
+ recentFileList.removeAll(filename);
+ recentFileList.prepend(filename);
+ updateRecentFilesMenu();
+
+
static const QSet compressedExts = {"zip", "7z", "rar", "tar", "tar.gz", "tar.xz", "tar.bz2"};
if (compressedExts.contains(QFileInfo(filename).completeSuffix()))
{
@@ -1502,13 +1531,7 @@ void MainWindow::onOpenFile()
}
}
-
- if (filename.isEmpty())
- {
- emuThread->emuUnpause();
- return;
- }
-
+
// TODO: validate the input file!!
// * check that it is a proper ROM
// * ensure the binary offsets are sane
@@ -1554,6 +1577,60 @@ void MainWindow::onOpenFile()
}
}
+void MainWindow::onOpenFile()
+{
+ emuThread->emuPause();
+
+ QString filename = QFileDialog::getOpenFileName(this,
+ "Open ROM",
+ Config::LastROMFolder,
+ "DS ROMs (*.nds *.dsi *.srl);;GBA ROMs (*.gba);;Any file (*.*)");
+ if (filename.isEmpty())
+ {
+ emuThread->emuUnpause();
+ return;
+ }
+
+ loadROM(filename);
+}
+
+void MainWindow::onClearRecentFiles()
+{
+ recentFileList.clear();
+ memset(Config::RecentROMList, 0, 10 * 1024);
+ updateRecentFilesMenu();
+}
+
+void MainWindow::updateRecentFilesMenu()
+{
+ recentMenu->clear();
+
+ for(int i = 0; i < recentFileList.size(); ++i)
+ {
+ QAction *actRecentFile_i = recentMenu->addAction(QString("%1. %2").arg(i+1).arg(recentFileList.at(i)));
+ actRecentFile_i->setData(recentFileList.at(i));
+ connect(actRecentFile_i, &QAction::triggered, this, &MainWindow::onClickRecentFile);
+
+ if(i < 10)
+ strncpy(Config::RecentROMList[i], recentFileList.at(i).toStdString().c_str(), 1024);
+ }
+
+ QAction *actClearRecentList = recentMenu->addAction("Clear");
+ connect(actClearRecentList, &QAction::triggered, this, &MainWindow::onClearRecentFiles);
+
+ if(recentFileList.empty())
+ actClearRecentList->setEnabled(false);
+
+ Config::Save();
+}
+
+void MainWindow::onClickRecentFile()
+{
+ emuThread->emuPause();
+ QAction *act = (QAction *)sender();
+ loadROM(act->data().toString());
+}
+
void MainWindow::onBootFirmware()
{
// TODO: check the whole GBA cart shito
diff --git a/src/frontend/qt_sdl/main.h b/src/frontend/qt_sdl/main.h
index 978df9e2..d31e7069 100644
--- a/src/frontend/qt_sdl/main.h
+++ b/src/frontend/qt_sdl/main.h
@@ -191,6 +191,8 @@ signals:
private slots:
void onOpenFile();
+ void onClickRecentFile();
+ void onClearRecentFiles();
void onBootFirmware();
void onSaveState();
void onLoadState();
@@ -236,6 +238,11 @@ private slots:
void onFullscreenToggled();
private:
+ QList recentFileList;
+ QMenu *recentMenu;
+ void updateRecentFilesMenu();
+ void loadROM(QString filename);
+
void createScreenPanel();
QString loadErrorStr(int error);
diff --git a/src/version.h b/src/version.h
index f0498d7f..54f60dfa 100644
--- a/src/version.h
+++ b/src/version.h
@@ -19,7 +19,7 @@
#ifndef VERSION_H
#define VERSION_H
-#define MELONDS_VERSION "0.9"
+#define MELONDS_VERSION "0.9.1"
#define MELONDS_URL "http://melonds.kuribo64.net/"