From 0562410de25266f70d16045987c9b39fd8366057 Mon Sep 17 00:00:00 2001 From: StapleButter Date: Tue, 7 Feb 2017 22:23:46 +0100 Subject: [PATCH] * lay base for 3D engine * add failure reporting to Init functions, and DeInit functions * GPU-related notes * readme update --- GPU.cpp | 15 ++++++++++++++- GPU.h | 4 +++- GPU2D.cpp | 38 ++++++++++++++++++++++++++++++++++++++ GPU3D.cpp | 44 ++++++++++++++++++++++++++++++++++++++++++++ GPU3D.h | 31 +++++++++++++++++++++++++++++++ NDS.cpp | 30 ++++++++++++++++++++++++------ NDS.h | 3 ++- NDSCart.cpp | 23 +++++++++++++++++++---- NDSCart.h | 3 ++- README.md | 21 ++++++++++++++++++--- RTC.cpp | 7 ++++++- RTC.h | 3 ++- SPI.cpp | 48 +++++++++++++++++++++++++++++++++++++++++------- SPI.h | 3 ++- main.cpp | 4 ++++ melonDS.cbp | 2 ++ melonDS.depend | 35 ++++++++++++++++++++++------------- 17 files changed, 274 insertions(+), 40 deletions(-) create mode 100644 GPU3D.cpp create mode 100644 GPU3D.h diff --git a/GPU.cpp b/GPU.cpp index 7ef03570..e153c4d2 100644 --- a/GPU.cpp +++ b/GPU.cpp @@ -68,10 +68,20 @@ GPU2D* GPU2D_A; GPU2D* GPU2D_B; -void Init() +bool Init() { GPU2D_A = new GPU2D(0); GPU2D_B = new GPU2D(1); + if (!GPU3D::Init()) return false; + + return true; +} + +void DeInit() +{ + delete GPU2D_A; + delete GPU2D_B; + GPU3D::DeInit(); } void Reset() @@ -118,6 +128,7 @@ void Reset() GPU2D_A->Reset(); GPU2D_B->Reset(); + GPU3D::Reset(); GPU2D_A->SetFramebuffer(&Framebuffer[256*192]); GPU2D_B->SetFramebuffer(&Framebuffer[256*0]); @@ -147,6 +158,8 @@ void Reset() // ARM7 (TODO) // extended palette (mirroring doesn't apply) // texture/texpal (does mirroring apply?) +// -> trying to use extpal/texture/texpal with no VRAM mapped. +// would likely read all black, but has to be tested. // // overlap: // when reading: values are read from each bank and ORed together diff --git a/GPU.h b/GPU.h index ee852b9f..18661ca2 100644 --- a/GPU.h +++ b/GPU.h @@ -20,6 +20,7 @@ #define GPU_H #include "GPU2D.h" +#include "GPU3D.h" namespace GPU { @@ -53,7 +54,8 @@ extern GPU2D* GPU2D_A; extern GPU2D* GPU2D_B; -void Init(); +bool Init(); +void DeInit(); void Reset(); void MapVRAM_AB(u32 bank, u8 cnt); diff --git a/GPU2D.cpp b/GPU2D.cpp index 8e59c0e2..6b4594ec 100644 --- a/GPU2D.cpp +++ b/GPU2D.cpp @@ -22,6 +22,43 @@ #include "GPU.h" +// notes on color conversion +// +// * BLDCNT special effects are applied on 18bit colors +// -> layers are converted to 18bit before being composited +// * colors are converted as follows: 18bit = 15bit * 2 +// -> white comes out as 62,62,62 and not 63,63,63 +// * VRAM/FIFO display modes convert colors the same way +// * 3D engine converts colors differently (18bit = 15bit * 2 + 1, except 0 = 0) +// * 'screen disabled' white is 63,63,63 +// +// oh also, changing DISPCNT bit16-17 midframe doesn't work (ignored? applied for next frame?) +// TODO, eventually: check whether other DISPCNT bits can be changed midframe +// +// sprite blending rules +// * destination must be selected as 2nd target +// * sprite must be semitransparent or bitmap sprite +// * blending is applied instead of the selected color effect, even if it is 'none'. +// * for bitmap sprites: EVA = alpha+1, EVB = 16-EVA +// * for bitmap sprites: alpha=0 is always transparent, even if blending doesn't apply +// +// 3D blending rules +// +// 3D/3D blending seems to follow these equations: +// dstColor = srcColor*srcAlpha + dstColor*(1-srcAlpha) +// dstAlpha = max(srcAlpha, dstAlpha) +// blending isn't applied if dstAlpha is zero. +// +// 3D/2D blending rules +// * if destination selected as 2nd target: +// blending is applied instead of the selected color effect, using full 31bit alpha from 3D layer +// this even if the selected color effect is 'none'. +// apparently this works even if BG0 isn't selected as 1st target +// * if BG0 is selected as 1st target, destination not selected as 2nd target: +// brightness up/down effect is applied if selected. if blending is selected, it doesn't apply. +// * 3D layer pixels with alpha=0 are always transparent. + + GPU2D::GPU2D(u32 num) { Num = num; @@ -49,6 +86,7 @@ void GPU2D::SetFramebuffer(u16* buf) { // framebuffer is 256x192 16bit. // might eventually support other framebuffer types/sizes + // TODO: change this. the DS uses 18bit color Framebuffer = buf; } diff --git a/GPU3D.cpp b/GPU3D.cpp new file mode 100644 index 00000000..c4b7ee89 --- /dev/null +++ b/GPU3D.cpp @@ -0,0 +1,44 @@ +/* + Copyright 2016-2017 StapleButter + + This file is part of melonDS. + + melonDS is free software: you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation, either version 3 of the License, or (at your option) + any later version. + + melonDS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with melonDS. If not, see http://www.gnu.org/licenses/. +*/ + +#include +#include +#include "NDS.h" +#include "GPU.h" + + +namespace GPU3D +{ + +bool Init() +{ + return true; +} + +void DeInit() +{ + // +} + +void Reset() +{ + // +} + +} + diff --git a/GPU3D.h b/GPU3D.h new file mode 100644 index 00000000..175b0ff6 --- /dev/null +++ b/GPU3D.h @@ -0,0 +1,31 @@ +/* + Copyright 2016-2017 StapleButter + + This file is part of melonDS. + + melonDS is free software: you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation, either version 3 of the License, or (at your option) + any later version. + + melonDS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with melonDS. If not, see http://www.gnu.org/licenses/. +*/ + +#ifndef GPU3D_H +#define GPU3D_H + +namespace GPU3D +{ + +bool Init(); +void DeInit(); +void Reset(); + +} + +#endif diff --git a/NDS.cpp b/NDS.cpp index 422264e4..b2d51ca7 100644 --- a/NDS.cpp +++ b/NDS.cpp @@ -111,7 +111,7 @@ u16 _soundbias; // temp bool Running; -void Init() +bool Init() { ARM9 = new ARM(0); ARM7 = new ARM(1); @@ -128,12 +128,30 @@ void Init() IPCFIFO9 = new FIFO(16); IPCFIFO7 = new FIFO(16); - NDSCart::Init(); - GPU::Init(); - SPI::Init(); - RTC::Init(); + if (!NDSCart::Init()) return false; + if (!GPU::Init()) return false; + if (!SPI::Init()) return false; + if (!RTC::Init()) return false; Reset(); + return true; +} + +void DeInit() +{ + delete ARM9; + delete ARM7; + + for (int i = 0; i < 8; i++) + delete DMAs[i]; + + delete IPCFIFO9; + delete IPCFIFO7; + + NDSCart::DeInit(); + GPU::DeInit(); + SPI::DeInit(); + RTC::DeInit(); } @@ -289,7 +307,7 @@ void Reset() // test //LoadROM(); //LoadFirmware(); - NDSCart::LoadROM("rom/sm64ds.nds"); + NDSCart::LoadROM("rom/mkds.nds"); Running = true; // hax } diff --git a/NDS.h b/NDS.h index 2b84513f..6f46e931 100644 --- a/NDS.h +++ b/NDS.h @@ -112,7 +112,8 @@ extern u8 ROMSeed1[2*8]; extern u8 ARM9BIOS[0x1000]; extern u8 ARM7BIOS[0x4000]; -void Init(); +bool Init(); +void DeInit(); void Reset(); void SetupDirectBoot(); diff --git a/NDSCart.cpp b/NDSCart.cpp index 523f5750..8553991d 100644 --- a/NDSCart.cpp +++ b/NDSCart.cpp @@ -53,15 +53,21 @@ void Write_Flash(u8 val, bool islast); void Write_Discover(u8 val, bool islast); -void Init() +bool Init() { SRAM = NULL; Discover_Buffer = NULL; + return true; +} + +void DeInit() +{ + if (SRAM) delete[] SRAM; + if (Discover_Buffer) delete[] Discover_Buffer; } void Reset() { - // } void LoadSave(char* path) @@ -69,6 +75,8 @@ void LoadSave(char* path) if (SRAM) delete[] SRAM; if (Discover_Buffer) delete[] Discover_Buffer; + Discover_Buffer = NULL; + strncpy(SRAMPath, path, 255); SRAMPath[255] = '\0'; @@ -553,9 +561,16 @@ void Key2_Encrypt(u8* data, u32 len) } -void Init() +bool Init() { - NDSCart_SRAM::Init(); + if (!NDSCart_SRAM::Init()) return false; + + return true; +} + +void DeInit() +{ + NDSCart_SRAM::DeInit(); } void Reset() diff --git a/NDSCart.h b/NDSCart.h index 54ccfc63..ccde9233 100644 --- a/NDSCart.h +++ b/NDSCart.h @@ -36,7 +36,8 @@ extern u8 EncSeed1[5]; extern u8* CartROM; extern u32 CartROMSize; -void Init(); +bool Init(); +void DeInit(); void Reset(); void LoadROM(char* path); diff --git a/README.md b/README.md index 3eebbe7a..f2545aab 100644 --- a/README.md +++ b/README.md @@ -13,11 +13,26 @@ LOVE MELONS NO ASKING ROMZ!! ILLEGAL -license will eventually be GPL or some crap. don't steal the code and make money off of it or claim it as your own or be an asshole. +license is GPL. don't steal the code. + + +how to use: + +melonDS requires BIOS/firmware copies from a DS. Files required: + * bios7.bin, 16KB: ARM7 BIOS + * bios9.bin, 4KB: ARM9 BIOS + * firmware.bin, 256KB: firmware + +note: the DS-mode firmware in the 3DS isn't bootable, it only contains the bare minimum to run games. + +ROM filename is currently hardcoded, check NDS.cpp for the required filename. this will eventually be addressed. TODO LIST - * take code fetch waitstates into account when fetching instructions, and during branches (pipeline shit) (tricky, some code fetches are nonsequential) - * \ No newline at end of file + * sorta-UI (ie not hardcode ROM name) + * 3D engine + * sound + * wifi + * other non-core shit (debugger, graphics viewers, cheat crapo, etc) \ No newline at end of file diff --git a/RTC.cpp b/RTC.cpp index c5b9d505..842fdae6 100644 --- a/RTC.cpp +++ b/RTC.cpp @@ -44,7 +44,12 @@ u8 ClockAdjust; u8 FreeReg; -void Init() +bool Init() +{ + return true; +} + +void DeInit() { } diff --git a/RTC.h b/RTC.h index b61dbabc..6ada5c18 100644 --- a/RTC.h +++ b/RTC.h @@ -24,7 +24,8 @@ namespace RTC { -void Init(); +bool Init(); +void DeInit(); void Reset(); u16 Read(); diff --git a/SPI.cpp b/SPI.cpp index ba79a66f..618dcf5b 100644 --- a/SPI.cpp +++ b/SPI.cpp @@ -69,16 +69,31 @@ bool VerifyCRC16(u32 start, u32 offset, u32 len, u32 crcoffset) } -void Init() +bool Init() { Firmware = NULL; + return true; +} + +void DeInit() +{ + if (Firmware) delete[] Firmware; } void Reset() { if (Firmware) delete[] Firmware; + Firmware = NULL; FILE* f = fopen("firmware.bin", "rb"); + if (!f) + { + printf("firmware.bin not found\n"); + + // TODO: generate default firmware + return; + } + fseek(f, 0, SEEK_END); FirmwareLength = (u32)ftell(f); Firmware = new u8[FirmwareLength]; @@ -220,7 +235,12 @@ u8 Registers[8]; u8 RegMasks[8]; -void Init() +bool Init() +{ + return true; +} + +void DeInit() { } @@ -295,7 +315,12 @@ u16 ConvResult; u16 TouchX, TouchY; -void Init() +bool Init() +{ + return true; +} + +void DeInit() { } @@ -366,11 +391,20 @@ u16 Cnt; u32 CurDevice; -void Init() +bool Init() { - SPI_Firmware::Init(); - SPI_Powerman::Init(); - SPI_TSC::Init(); + if (!SPI_Firmware::Init()) return false; + if (!SPI_Powerman::Init()) return false; + if (!SPI_TSC::Init()) return false; + + return true; +} + +void DeInit() +{ + SPI_Firmware::DeInit(); + SPI_Powerman::DeInit(); + SPI_TSC::DeInit(); } void Reset() diff --git a/SPI.h b/SPI.h index b98d771c..73a4180d 100644 --- a/SPI.h +++ b/SPI.h @@ -31,7 +31,8 @@ namespace SPI extern u16 Cnt; -void Init(); +bool Init(); +void DeInit(); void Reset(); u16 ReadCnt(); diff --git a/main.cpp b/main.cpp index 909ac657..600cdbfe 100644 --- a/main.cpp +++ b/main.cpp @@ -167,6 +167,8 @@ int main() instance = GetModuleHandle(NULL); + //SetThreadAffinityMask(GetCurrentThread(), 0x8); + // god this shit sucks WNDCLASSEX shit; shit.cbSize = sizeof(shit); @@ -256,5 +258,7 @@ int main() } } + NDS::DeInit(); + return 0; } diff --git a/melonDS.cbp b/melonDS.cbp index 7fd7889f..702a9a8c 100644 --- a/melonDS.cbp +++ b/melonDS.cbp @@ -57,6 +57,8 @@ + + diff --git a/melonDS.depend b/melonDS.depend index c6090ecd..cce24162 100644 --- a/melonDS.depend +++ b/melonDS.depend @@ -1,16 +1,16 @@ # depslib dependency file v1.0 -1486141269 source:c:\documents\sources\melonds\main.cpp +1486502416 source:c:\documents\sources\melonds\main.cpp "NDS.h" "GPU.h" -1486142800 c:\documents\sources\melonds\nds.h +1486502049 c:\documents\sources\melonds\nds.h "types.h" 1481161027 c:\documents\sources\melonds\types.h -1486333824 source:c:\documents\sources\melonds\nds.cpp +1486502137 source:c:\documents\sources\melonds\nds.cpp "NDS.h" @@ -78,7 +78,7 @@ "ARM.h" "CP15.h" -1485900740 c:\documents\sources\melonds\spi.h +1486502258 c:\documents\sources\melonds\spi.h 1486163389 source:c:\documents\sources\melonds\spi.cpp @@ -86,7 +86,7 @@ "NDS.h" "SPI.h" -1486315323 source:c:\documents\sources\melonds\gpu2d.cpp +1486489354 source:c:\documents\sources\melonds\gpu2d.cpp "NDS.h" @@ -102,10 +102,10 @@ "NDS.h" "Wifi.h" -1484613078 source:c:\documents\sources\melonds\fifo.cpp +1486501225 source:c:\documents\sources\melonds\fifo.cpp "FIFO.h" -1484612398 c:\documents\sources\melonds\fifo.h +1486501199 c:\documents\sources\melonds\fifo.h "types.h" 1486309616 source:c:\documents\sources\melonds\dma.cpp @@ -117,29 +117,38 @@ 1484698068 c:\documents\sources\melonds\dma.h "types.h" -1486152626 source:c:\documents\sources\melonds\gpu.cpp +1486502073 source:c:\documents\sources\melonds\gpu.cpp "NDS.h" "GPU.h" -1485989497 c:\documents\sources\melonds\gpu.h +1486501976 c:\documents\sources\melonds\gpu.h "GPU2D.h" + "GPU3D.h" -1484848282 c:\documents\sources\melonds\rtc.h +1486502440 c:\documents\sources\melonds\rtc.h "types.h" -1486244121 source:c:\documents\sources\melonds\rtc.cpp +1486502457 source:c:\documents\sources\melonds\rtc.cpp "RTC.h" -1485980863 c:\documents\sources\melonds\ndscart.h +1486502165 c:\documents\sources\melonds\ndscart.h "types.h" -1486313011 source:c:\documents\sources\melonds\ndscart.cpp +1486502488 source:c:\documents\sources\melonds\ndscart.cpp "NDS.h" "NDSCart.h" +1486501964 c:\documents\sources\melonds\gpu3d.h + +1486502427 source:c:\documents\sources\melonds\gpu3d.cpp + + + "NDS.h" + "GPU.h" +