diff --git a/src/DMA.cpp b/src/DMA.cpp index d4e6d702..9a17f416 100644 --- a/src/DMA.cpp +++ b/src/DMA.cpp @@ -189,7 +189,7 @@ void DMA::Start() // special path for cart DMA. this is a gross hack. // emulating it properly requires emulating cart transfer delays, so uh... TODO if (CurSrcAddr==0x04100010 && RemCount==1 && (Cnt & 0x07E00000)==0x07000000 && - StartMode==0x05 || StartMode==0x12) + (StartMode==0x05 || StartMode==0x12)) { NDSCart::DMA(CurDstAddr); Cnt &= ~0x80000000; diff --git a/src/GPU.cpp b/src/GPU.cpp index c9ab6a0d..d486e0c8 100644 --- a/src/GPU.cpp +++ b/src/GPU.cpp @@ -66,22 +66,10 @@ u32 VRAMMap_BBGExtPal[4]; u32 VRAMMap_BOBJExtPal; u32 VRAMMap_Texture[4]; -u32 VRAMMap_TexPal[6]; +u32 VRAMMap_TexPal[8]; u32 VRAMMap_ARM7[2]; -/*u8* VRAM_ABG[128]; -u8* VRAM_AOBJ[128]; -u8* VRAM_BBG[128]; -u8* VRAM_BOBJ[128]; -u8* VRAM_LCD[128];*/ -/*u8* VRAM_ARM7[2]; - -u8* VRAM_ABGExtPal[4]; -u8* VRAM_AOBJExtPal; -u8* VRAM_BBGExtPal[4]; -u8* VRAM_BOBJExtPal;*/ - u32 Framebuffer[256*192*2]; GPU2D* GPU2D_A; @@ -147,21 +135,6 @@ void Reset() VRAMMap_ARM7[0] = 0; VRAMMap_ARM7[1] = 0; - //memset(VRAM_Base, 0, sizeof(VRAM_Base)); - //memset(VRAM_Mask, 0, sizeof(VRAM_Mask)); - - /*memset(VRAM_ABG, 0, sizeof(u8*)*128); - memset(VRAM_AOBJ, 0, sizeof(u8*)*128); - memset(VRAM_BBG, 0, sizeof(u8*)*128); - memset(VRAM_BOBJ, 0, sizeof(u8*)*128); - memset(VRAM_LCD, 0, sizeof(u8*)*128);*/ - /*memset(VRAM_ARM7, 0, sizeof(u8*)*2); - - memset(VRAM_ABGExtPal, 0, sizeof(u8*)*4); - VRAM_AOBJExtPal = NULL; - memset(VRAM_BBGExtPal, 0, sizeof(u8*)*4); - VRAM_BOBJExtPal = NULL;*/ - for (int i = 0; i < 256*192*2; i++) { Framebuffer[i] = 0xFFFFFFFF; @@ -452,8 +425,7 @@ void MapVRAM_FG(u32 bank, u8 cnt) case 4: // ABG ext palette VRAMMap_ABGExtPal[((oldofs & 0x1) << 1)] &= ~bankmask; VRAMMap_ABGExtPal[((oldofs & 0x1) << 1) + 1] &= ~bankmask; - GPU2D_A->BGExtPalDirty(0); - GPU2D_A->BGExtPalDirty(2); + GPU2D_A->BGExtPalDirty((oldofs & 0x1) << 1); break; case 5: // AOBJ ext palette @@ -488,8 +460,7 @@ void MapVRAM_FG(u32 bank, u8 cnt) case 4: // ABG ext palette VRAMMap_ABGExtPal[((ofs & 0x1) << 1)] |= bankmask; VRAMMap_ABGExtPal[((ofs & 0x1) << 1) + 1] |= bankmask; - GPU2D_A->BGExtPalDirty(0); - GPU2D_A->BGExtPalDirty(2); + GPU2D_A->BGExtPalDirty((ofs & 0x1) << 1); break; case 5: // AOBJ ext palette diff --git a/src/GPU.h b/src/GPU.h index a77f6c08..7009b868 100644 --- a/src/GPU.h +++ b/src/GPU.h @@ -57,7 +57,7 @@ extern u32 VRAMMap_AOBJExtPal; extern u32 VRAMMap_BBGExtPal[4]; extern u32 VRAMMap_BOBJExtPal; extern u32 VRAMMap_Texture[4]; -extern u32 VRAMMap_TexPal[6]; +extern u32 VRAMMap_TexPal[8]; extern u32 VRAMMap_ARM7[2]; extern u32 Framebuffer[256*192*2]; @@ -372,7 +372,6 @@ template T ReadVRAM_TexPal(u32 addr) { u32 ret = 0; - if (addr >= 0x18000) return 0; u32 mask = VRAMMap_TexPal[(addr >> 14) & 0x7]; if (mask & (1<<4)) ret |= *(T*)&VRAM_E[addr & 0xFFFF]; diff --git a/src/GPU2D.cpp b/src/GPU2D.cpp index 799714a2..27de6ced 100644 --- a/src/GPU2D.cpp +++ b/src/GPU2D.cpp @@ -698,7 +698,7 @@ void GPU2D::DrawScanlineBGMode(u32 line, u32* spritebuf, u32* dst) if (bgmode >= 3) DrawBG_Extended(line, dst, 3); else if (bgmode >= 1) - {} // todo: rotscale + DrawBG_Affine(line, dst, 3); else DrawBG_Text(line, dst, 3); } @@ -710,7 +710,7 @@ void GPU2D::DrawScanlineBGMode(u32 line, u32* spritebuf, u32* dst) if (bgmode == 5) DrawBG_Extended(line, dst, 2); else if (bgmode == 4 || bgmode == 2) - {} // todo: rotscale + DrawBG_Affine(line, dst, 2); else DrawBG_Text(line, dst, 2); } @@ -1071,6 +1071,79 @@ void GPU2D::DrawBG_Text(u32 line, u32* dst, u32 bgnum) } } +void GPU2D::DrawBG_Affine(u32 line, u32* dst, u32 bgnum) +{ + u16 bgcnt = BGCnt[bgnum]; + + u32 tilesetaddr, tilemapaddr; + u16* pal; + + u32 coordmask; + u32 yshift; + switch (bgcnt & 0xC000) + { + case 0x0000: coordmask = 0x07800; yshift = 7; break; + case 0x4000: coordmask = 0x0F800; yshift = 8; break; + case 0x8000: coordmask = 0x1F800; yshift = 9; break; + case 0xC000: coordmask = 0x3F800; yshift = 10; break; + } + + u32 overflowmask; + if (bgcnt & 0x2000) overflowmask = 0; + else overflowmask = ~(coordmask | 0x7FF); + + s16 rotA = BGRotA[bgnum-2]; + s16 rotB = BGRotB[bgnum-2]; + s16 rotC = BGRotC[bgnum-2]; + s16 rotD = BGRotD[bgnum-2]; + + s32 rotX = BGXRefInternal[bgnum-2]; + s32 rotY = BGYRefInternal[bgnum-2]; + + if (Num) + { + tilesetaddr = 0x06200000 + ((bgcnt & 0x003C) << 12); + tilemapaddr = 0x06200000 + ((bgcnt & 0x1F00) << 3); + + pal = (u16*)&GPU::Palette[0x400]; + } + else + { + tilesetaddr = 0x06000000 + ((DispCnt & 0x07000000) >> 8) + ((bgcnt & 0x003C) << 12); + tilemapaddr = 0x06000000 + ((DispCnt & 0x38000000) >> 11) + ((bgcnt & 0x1F00) << 3); + + pal = (u16*)&GPU::Palette[0]; + } + + u16 curtile; + + yshift -= 3; + + for (int i = 0; i < 256; i++) + { + if (!((rotX|rotY) & overflowmask)) + { + curtile = GPU::ReadVRAM_BG(tilemapaddr + ((((rotY & coordmask) >> 11) << yshift) + ((rotX & coordmask) >> 11))); + + // draw pixel + u8 color; + u32 tilexoff = (rotX >> 8) & 0x7; + u32 tileyoff = (rotY >> 8) & 0x7; + + color = GPU::ReadVRAM_BG(tilesetaddr + (curtile << 6) + (tileyoff << 3) + tilexoff); + + if (color) + DrawPixel(&dst[i], pal[color], 0x01000000<> 10) & 0x3; u32 ytilefactor; - if (DispCnt & 0x10) - { - tilenum <<= ((DispCnt >> 20) & 0x3); - ytilefactor = (width >> 3) << ((attrib[0] & 0x2000) ? 1:0); - } - else - { - ytilefactor = 0x20; - } s32 centerX = boundwidth >> 1; s32 centerY = boundheight >> 1; @@ -1349,18 +1413,71 @@ void GPU2D::DrawSprite_Rotscale(u16* attrib, u16* rotparams, u32 boundwidth, u32 if (spritemode == 3) { - // TODO - u32 alpha = attrib[2] >> 12; if (!alpha) return; alpha++; prio |= (0xC0000000 | (alpha << 24)); - // TODO + if (DispCnt & 0x40) + { + if (DispCnt & 0x20) + { + // TODO ("reserved") + } + else + { + tilenum <<= (7 + ((DispCnt >> 22) & 0x1)); + ytilefactor = ((width >> 8) * 2); + } + } + else + { + if (DispCnt & 0x20) + { + tilenum = ((tilenum & 0x01F) << 4) + ((tilenum & 0x3E0) << 7); + ytilefactor = (256 * 2); + } + else + { + tilenum = ((tilenum & 0x00F) << 4) + ((tilenum & 0x3F0) << 7); + ytilefactor = (128 * 2); + } + } + + u32 pixelsaddr = (Num ? 0x06600000 : 0x06400000) + tilenum; + + for (; xoff < boundwidth;) + { + if ((u32)rotX < width && (u32)rotY < height) + { + u8 color; + + // blaaaarg + color = GPU::ReadVRAM_OBJ(pixelsaddr + ((rotY >> 8) * ytilefactor) + ((rotX >> 8) << 1)); + + if (color & 0x8000) + dst[xpos] = color | prio; + } + + rotX += rotA; + rotY += rotC; + xoff++; + xpos++; + } } else { + if (DispCnt & 0x10) + { + tilenum <<= ((DispCnt >> 20) & 0x3); + ytilefactor = (width >> 11) << ((attrib[0] & 0x2000) ? 1:0); + } + else + { + ytilefactor = 0x20; + } + if (spritemode == 1) prio |= 0x80000000; else prio |= 0x10000000; @@ -1459,6 +1576,12 @@ void GPU2D::DrawSprite_Normal(u16* attrib, u32 width, s32 xpos, u32 ypos, u32* d { // bitmap sprite + u32 alpha = attrib[2] >> 12; + if (!alpha) return; + alpha++; + + prio |= (0xC0000000 | (alpha << 24)); + if (DispCnt & 0x40) { if (DispCnt & 0x20) @@ -1485,12 +1608,6 @@ void GPU2D::DrawSprite_Normal(u16* attrib, u32 width, s32 xpos, u32 ypos, u32* d } } - u32 alpha = attrib[2] >> 12; - if (!alpha) return; - alpha++; - - prio |= (0xC0000000 | (alpha << 24)); - u32 pixelsaddr = (Num ? 0x06600000 : 0x06400000) + tilenum; pixelsaddr += (xoff << 1); diff --git a/src/GPU2D.h b/src/GPU2D.h index 9a0d1027..38cbe7ee 100644 --- a/src/GPU2D.h +++ b/src/GPU2D.h @@ -89,6 +89,7 @@ private: void DrawBG_3D(u32 line, u32* dst); void DrawBG_Text(u32 line, u32* dst, u32 num); + void DrawBG_Affine(u32 line, u32* dst, u32 bgnum); void DrawBG_Extended(u32 line, u32* dst, u32 bgnum); void InterleaveSprites(u32* buf, u32 prio, u32* dst); diff --git a/src/NDSCart.cpp b/src/NDSCart.cpp index 386af212..15775730 100644 --- a/src/NDSCart.cpp +++ b/src/NDSCart.cpp @@ -193,6 +193,7 @@ void SetMemoryType() CurCmd = prev_cmd; delete[] Discover_Buffer; + Discover_Buffer = NULL; } void Write_Discover(u8 val, bool islast) diff --git a/src/wx/InputConfig.cpp b/src/wx/InputConfig.cpp index ea5f1c88..b4785fe4 100644 --- a/src/wx/InputConfig.cpp +++ b/src/wx/InputConfig.cpp @@ -22,6 +22,37 @@ wxBEGIN_EVENT_TABLE(InputConfigDialog, wxDialog) + EVT_COMMAND(1001, wxEVT_BUTTON, InputConfigDialog::OnDerp) + + EVT_COMMAND(100, wxEVT_BUTTON, InputConfigDialog::OnConfigureKey) + EVT_COMMAND(101, wxEVT_BUTTON, InputConfigDialog::OnConfigureKey) + EVT_COMMAND(102, wxEVT_BUTTON, InputConfigDialog::OnConfigureKey) + EVT_COMMAND(103, wxEVT_BUTTON, InputConfigDialog::OnConfigureKey) + EVT_COMMAND(104, wxEVT_BUTTON, InputConfigDialog::OnConfigureKey) + EVT_COMMAND(105, wxEVT_BUTTON, InputConfigDialog::OnConfigureKey) + EVT_COMMAND(106, wxEVT_BUTTON, InputConfigDialog::OnConfigureKey) + EVT_COMMAND(107, wxEVT_BUTTON, InputConfigDialog::OnConfigureKey) + EVT_COMMAND(108, wxEVT_BUTTON, InputConfigDialog::OnConfigureKey) + EVT_COMMAND(109, wxEVT_BUTTON, InputConfigDialog::OnConfigureKey) + EVT_COMMAND(110, wxEVT_BUTTON, InputConfigDialog::OnConfigureKey) + EVT_COMMAND(111, wxEVT_BUTTON, InputConfigDialog::OnConfigureKey) + + EVT_COMMAND(200, wxEVT_BUTTON, InputConfigDialog::OnConfigureJoy) + EVT_COMMAND(201, wxEVT_BUTTON, InputConfigDialog::OnConfigureJoy) + EVT_COMMAND(202, wxEVT_BUTTON, InputConfigDialog::OnConfigureJoy) + EVT_COMMAND(203, wxEVT_BUTTON, InputConfigDialog::OnConfigureJoy) + EVT_COMMAND(204, wxEVT_BUTTON, InputConfigDialog::OnConfigureJoy) + EVT_COMMAND(205, wxEVT_BUTTON, InputConfigDialog::OnConfigureJoy) + EVT_COMMAND(206, wxEVT_BUTTON, InputConfigDialog::OnConfigureJoy) + EVT_COMMAND(207, wxEVT_BUTTON, InputConfigDialog::OnConfigureJoy) + EVT_COMMAND(208, wxEVT_BUTTON, InputConfigDialog::OnConfigureJoy) + EVT_COMMAND(209, wxEVT_BUTTON, InputConfigDialog::OnConfigureJoy) + EVT_COMMAND(210, wxEVT_BUTTON, InputConfigDialog::OnConfigureJoy) + EVT_COMMAND(211, wxEVT_BUTTON, InputConfigDialog::OnConfigureJoy) + + EVT_TIMER(wxID_ANY, InputConfigDialog::OnPoll) + + EVT_KEY_DOWN(InputConfigDialog::OnKeyDown) wxEND_EVENT_TABLE() @@ -31,6 +62,9 @@ InputConfigDialog::InputConfigDialog(wxWindow* parent) int keyorder[12] = {0, 1, 10, 11, 5, 4, 6, 7, 9, 8, 3, 2}; char keylabels[12][8] = {"A:", "B:", "Select:", "Start:", "Right:", "Left:", "Up:", "Down:", "R:", "L:", "X:", "Y:"}; + memcpy(keymapping, Config::KeyMapping, 12*sizeof(int)); + memcpy(joymapping, Config::JoyMapping, 12*sizeof(int)); + wxBoxSizer* vboxmain = new wxBoxSizer(wxVERTICAL); { @@ -39,24 +73,52 @@ InputConfigDialog::InputConfigDialog(wxWindow* parent) wxStaticBox* kbdside = new wxStaticBox(p, wxID_ANY, "Keyboard"); { - wxGridSizer* grid = new wxGridSizer(2, 3, 0); + wxBoxSizer* sizer = new wxBoxSizer(wxVERTICAL); + wxPanel* p = new wxPanel(kbdside); + wxFlexGridSizer* grid = new wxFlexGridSizer(2, 3, 8); for (int i = 0; i < 12; i++) { int j = keyorder[i]; - wxStaticText* label = new wxStaticText(kbdside, wxID_ANY, keylabels[j]); - grid->Add(label); + wxStaticText* label = new wxStaticText(p, wxID_ANY, keylabels[j]); + grid->Add(label, 0, wxALIGN_RIGHT|wxALIGN_CENTRE_VERTICAL); - const char* keyname = SDL_GetKeyName(SDL_GetKeyFromScancode((SDL_Scancode)Config::KeyMapping[j])); - wxButton* btn = new wxButton(kbdside, 100+i, keyname); + const char* keyname = SDL_GetScancodeName((SDL_Scancode)Config::KeyMapping[j]); + wxButton* btn = new wxButton(p, 100+j, keyname); grid->Add(btn); } - kbdside->SetSizer(grid); + p->SetSizer(grid); + sizer->Add(p, 0, wxALL, 15); + kbdside->SetSizer(sizer); } sizer->Add(kbdside); + wxStaticBox* joyside = new wxStaticBox(p, wxID_ANY, "Joystick"); + { + wxBoxSizer* sizer = new wxBoxSizer(wxVERTICAL); + wxPanel* p = new wxPanel(joyside); + wxFlexGridSizer* grid = new wxFlexGridSizer(2, 3, 8); + + for (int i = 0; i < 12; i++) + { + int j = keyorder[i]; + + wxStaticText* label = new wxStaticText(p, wxID_ANY, keylabels[j]); + grid->Add(label, 0, wxALIGN_RIGHT|wxALIGN_CENTRE_VERTICAL); + + const char* keyname = "zorp";//SDL_GetKeyName(SDL_GetKeyFromScancode((SDL_Scancode)Config::KeyMapping[j])); + wxButton* btn = new wxButton(p, 200+j, keyname); + grid->Add(btn); + } + + p->SetSizer(grid); + sizer->Add(p, 0, wxALL, 15); + joyside->SetSizer(sizer); + } + sizer->Add(joyside); + p->SetSizer(sizer); vboxmain->Add(p, 0, wxALL&(~wxBOTTOM), 15); } @@ -78,4 +140,83 @@ InputConfigDialog::InputConfigDialog(wxWindow* parent) SetSizer(vboxmain); Fit(); + + polltimer = new wxTimer(this); + pollid = 0; + + keystate = SDL_GetKeyboardState(&nkeys); +} + +InputConfigDialog::~InputConfigDialog() +{ + delete polltimer; +} + +void InputConfigDialog::OnDerp(wxCommandEvent& event) +{ + printf("OnDerp %d\n", event.GetId()); +} + +void InputConfigDialog::OnConfigureKey(wxCommandEvent& event) +{ + pollid = event.GetId(); + //pollbtn = (wxButton*)event.GetOwner(); + polltimer->Start(100); +} + +void InputConfigDialog::OnConfigureJoy(wxCommandEvent& event) +{ + pollid = event.GetId(); + //pollbtn = (wxButton*)event.GetSource(); + polltimer->Start(100); +} + +void InputConfigDialog::OnPoll(wxTimerEvent& event) +{ + if (pollid < 100) return; + + SDL_PumpEvents(); + keystate = SDL_GetKeyboardState(&nkeys); + + if (keystate[SDL_SCANCODE_ESCAPE]) + { + polltimer->Stop(); + //pollbtn->Enable(true); + pollid = 0; + return; + } + + if (pollid >= 200) + { + // + } + else + {printf("poll kbd %d, %d, %d\n", pollid, nkeys, keystate[SDL_SCANCODE_A]); + int id = pollid - 100; + if (id >= 12) return; + + for (int i = 0; i < nkeys; i++) + { + if (keystate[i]) + { + keymapping[id] = i; + + //pollbtn->Enable(true); + + const char* keyname = SDL_GetScancodeName((SDL_Scancode)i); + //pollbtn->SetText(keyname); + printf("%s\n", keyname); + + polltimer->Stop(); + pollid = 0; + + break; + } + } + } +} + +void InputConfigDialog::OnKeyDown(wxKeyEvent& event) +{ + printf("!!\n"); } diff --git a/src/wx/InputConfig.h b/src/wx/InputConfig.h index c0a60e79..c1bc64b4 100644 --- a/src/wx/InputConfig.h +++ b/src/wx/InputConfig.h @@ -30,9 +30,29 @@ class InputConfigDialog : public wxDialog { public: InputConfigDialog(wxWindow* parent); + ~InputConfigDialog(); private: wxDECLARE_EVENT_TABLE(); + + void OnDerp(wxCommandEvent& event); + + void OnConfigureKey(wxCommandEvent& event); + void OnConfigureJoy(wxCommandEvent& event); + + void OnPoll(wxTimerEvent& event); + + void OnKeyDown(wxKeyEvent& event); + + const u8* keystate; + int nkeys; + + wxTimer* polltimer; + int pollid; + wxButton* pollbtn; + + int keymapping[12]; + int joymapping[12]; }; #endif // WX_INPUTCONFIG_H diff --git a/src/wx/main.cpp b/src/wx/main.cpp index 058808fe..a5fd725d 100644 --- a/src/wx/main.cpp +++ b/src/wx/main.cpp @@ -130,10 +130,18 @@ MainFrame::MainFrame() void MainFrame::OnClose(wxCloseEvent& event) { - emustatus = 0; - emustatuschangemutex->Lock(); - emustatuschange->Signal(); - emustatuschangemutex->Unlock(); + if (emustatus == 1) + { + emustatus = 0; + emustop->Wait(); + } + else + { + emustatus = 0; + emustatuschangemutex->Lock(); + emustatuschange->Signal(); + emustatuschangemutex->Unlock(); + } emuthread->Wait(); delete emuthread;