diff --git a/libstarlight/source/starlight/ui/DebugConsole.cpp b/libstarlight/source/starlight/ui/DebugConsole.cpp new file mode 100644 index 0000000..2c9e9ed --- /dev/null +++ b/libstarlight/source/starlight/ui/DebugConsole.cpp @@ -0,0 +1,101 @@ +#include "DebugConsole.h" + +#include "starlight/GFXManager.h" +#include "starlight/gfx/RenderCore.h" + +#include "sys/iosupport.h" + +using starlight::GFXManager; +using starlight::TextConfig; + +using starlight::gfx::RenderCore; + +using starlight::ui::DebugConsole; + +namespace { + bool csInit = false; + //std::weak_ptr curDC = std::shared_ptr(nullptr); + DebugConsole* cs = nullptr; + + // TODO: figure out how the fuck to make this not svcBreak on hardware!? + ssize_t consoleWrite(struct _reent* r, void* fd, const char* ptr, size_t len) { + if (!ptr) return -1; + + //if (curDC.expired()) return -1; + + //auto cs = curDC.lock(); + if (cs == nullptr) return -1; // nullref but not expired??? + cs->text.append("buh");//(ptr, len); + cs->buffer.reset(); + + return len; + } + + const devoptab_t devoptab_console = { + "con", + 0, + NULL, + NULL, + consoleWrite, + NULL, + NULL, + NULL + }; +} + +DebugConsole::DebugConsole(VRect rect) { + this->rect = rect; +} + +DebugConsole::~DebugConsole() { + if (cs == this) cs = nullptr; +} + +void DebugConsole::Start() { + //curDC = std::static_pointer_cast(shared_from_this()); + cs = this; + if (!csInit) { + csInit = true; + + devoptab_list[STD_OUT] = &devoptab_console; + devoptab_list[STD_ERR] = &devoptab_console; + + setvbuf(stdout, NULL , _IONBF, 0); + setvbuf(stderr, NULL , _IONBF, 0); + + } + text = "foop?\n"; +} + +void DebugConsole::PreDrawOffscreen() { + buffer.reset(); // I guess? +} + +void DebugConsole::PreDraw() { + if (!buffer) { + static TextConfig textConfig = ThemeManager::GetMetric("/textPresets/normal.12", TextConfig()); + textConfig.font = ThemeManager::GetFont("mono.12"); + textConfig.justification = Vector2(0, 1); + textConfig.borderColor = Color::black; + + // clip text at top left corner + Vector2 measure = textConfig.Measure(text, rect.size.x); + if (measure.y > rect.size.y) { + unsigned int cfp = textConfig.GetCursorFromPoint(rect, text, Vector2(0, measure.y - (rect.size.y + 16))); + text = text.substr(cfp); + } + + buffer = std::make_unique(rect.size + Vector2(0, 8)); + buffer->Clear(); + GFXManager::PushContext(buffer.get()); + textConfig.Print(buffer->rect, text); + GFXManager::PopContext(); + } +} + +void DebugConsole::Draw() { + auto rect = (this->rect + GFXManager::GetOffset()).IntSnap(); + if (buffer) { + buffer->Draw(VRect(rect.pos, buffer->rect.size)); + } +} diff --git a/libstarlight/source/starlight/ui/DebugConsole.h b/libstarlight/source/starlight/ui/DebugConsole.h new file mode 100644 index 0000000..96b97da --- /dev/null +++ b/libstarlight/source/starlight/ui/DebugConsole.h @@ -0,0 +1,37 @@ +#pragma once +#include "starlight/_global.h" + +#include +#include + +#include "starlight/datatypes/Optional.h" + +#include "starlight/ThemeManager.h" +#include "starlight/gfx/ThemeRef.h" + +#include "starlight/gfx/DrawContextCanvas.h" + +#include "starlight/ui/UIElement.h" + +namespace starlight { + namespace ui { + class DebugConsole : public UIElement { + private: + // + + public: + std::string text = ""; + + std::unique_ptr buffer; + + DebugConsole(VRect rect); + ~DebugConsole() override; + + void Start(); + + void PreDrawOffscreen() override; + void PreDraw() override; + void Draw() override; + }; + } +} diff --git a/libstarlight/todo.txt b/libstarlight/todo.txt index c8e39b9..5c6da49 100644 --- a/libstarlight/todo.txt +++ b/libstarlight/todo.txt @@ -11,6 +11,8 @@ roadmap to v0.5.1 { - masking } + libctru console as ui element (label subclass? container with a label?) + - fix the hang on osk when pressing (L|R)+up+left figure out what (else) to put on the left side of the keyboard (opposite backspace and enter) temporary drawable loading, local themeref, discard etc. @@ -56,6 +58,8 @@ roadmap to v0.5.1 { SOUND. + UI heirarchy from json + quick includes for all UI elements, etc. } diff --git a/maketest.sh b/maketest.sh index ed1f89b..74d2b3a 100644 --- a/maketest.sh +++ b/maketest.sh @@ -4,7 +4,9 @@ function abort { exit } mode=send -if [ "$1" = "c" ]; then +if [ "$1" = "sc" ]; then + mode=send-cia +elif [ "$1" = "c" ]; then mode=run fi cd libstarlight diff --git a/testbed/Makefile b/testbed/Makefile index b441b31..7abbd47 100644 --- a/testbed/Makefile +++ b/testbed/Makefile @@ -44,6 +44,8 @@ APP_TITLE := Starlight Testbed APP_DESCRIPTION := Test application for libstarlight APP_AUTHOR := zetaPRIME +3DSIP := 10.0.0.5 + #--------------------------------------------------------------------------------- # options for code generation #--------------------------------------------------------------------------------- @@ -168,6 +170,10 @@ cia: $(TARGET)-strip.elf send: $(BUILD) @3dslink $(TARGET).3dsx || 3dslink $(TARGET).3dsx || 3dslink $(TARGET).3dsx || 3dslink $(TARGET).3dsx || 3dslink $(TARGET).3dsx #--------------------------------------------------------------------------------- +send-cia: $(TARGET)-strip.elf + @makerom -f cia -o $(TARGET).cia -elf $(TARGET)-strip.elf -rsf resources/$(TARGET).rsf -icon resources/icon.icn -banner resources/banner.bnr -exefslogo -target t + @sockme $(TARGET).cia $(3DSIP) +#--------------------------------------------------------------------------------- run: $(BUILD) @citra $(TARGET).3dsx #--------------------------------------------------------------------------------- diff --git a/testbed/resources/audio_3ds.wav b/testbed/resources/audio_3ds.wav new file mode 100644 index 0000000..8bdb0e1 Binary files /dev/null and b/testbed/resources/audio_3ds.wav differ diff --git a/testbed/resources/banner.bnr b/testbed/resources/banner.bnr new file mode 100644 index 0000000..d609f51 Binary files /dev/null and b/testbed/resources/banner.bnr differ diff --git a/testbed/resources/banner_3ds.png b/testbed/resources/banner_3ds.png new file mode 100644 index 0000000..9267a0c Binary files /dev/null and b/testbed/resources/banner_3ds.png differ diff --git a/testbed/resources/icon.icn b/testbed/resources/icon.icn new file mode 100644 index 0000000..a5c33da Binary files /dev/null and b/testbed/resources/icon.icn differ diff --git a/testbed/resources/icon_3ds.png b/testbed/resources/icon_3ds.png new file mode 100644 index 0000000..ea440f9 Binary files /dev/null and b/testbed/resources/icon_3ds.png differ diff --git a/testbed/resources/starlight-testbed.rsf b/testbed/resources/starlight-testbed.rsf new file mode 100644 index 0000000..47ba419 --- /dev/null +++ b/testbed/resources/starlight-testbed.rsf @@ -0,0 +1,236 @@ +BasicInfo: + Title : "starlight-testbed" + CompanyCode : "00" + ProductCode : "CTR-N-SLTB" + ContentType : Application # Application / SystemUpdate / Manual / Child / Trial + Logo : Homebrew # Nintendo / Licensed / Distributed / iQue / iQueForSystem + +RomFs: + # Specifies the root path of the file system to include in the ROM. + RootPath : "$(ROMFS_ROOT)" + + +TitleInfo: + UniqueId : 0xf1001 # same as sf2d test because meh + Category : Application # Application / SystemApplication / Applet / Firmware / Base / DlpChild / Demo / Contents / SystemContents / SharedContents / AddOnContents / Patch / AutoUpdateContents + +#CardInfo: +# MediaSize : 128MB # 128MB / 256MB / 512MB / 1GB / 2GB / 4GB / 8GB / 16GB / 32GB +# MediaType : Card1 # Card1 / Card2 +# CardDevice : None # NorFlash / None + + +Option: + UseOnSD : true # true if App is to be installed to SD + EnableCompress : false # Compresses exefs code + FreeProductCode : true # Removes limitations on ProductCode + EnableCrypt : false # Enables encryption for NCCH and CIA + MediaFootPadding : false # If true CCI files are created with padding + +#ExeFs: # these are the program segments from the ELF, check your elf for the appropriate segment names +# ReadOnly: +# - .rodata +# - RO +# ReadWrite: +# - .data +# - RO +# Text: +# - .init +# - .text +# - STUP_ENTRY + +#PlainRegion: # only used with SDK ELFs +# # - .module_id + +AccessControlInfo: + # UseOtherVariationSaveData : true + # UseExtSaveData : true + # ExtSaveDataId: 0xffffffff + # SystemSaveDataId1: 0x220 + # SystemSaveDataId2: 0x00040010 + # OtherUserSaveDataId1: 0x220 + # OtherUserSaveDataId2: 0x330 + # OtherUserSaveDataId3: 0x440 + # UseExtendedSaveDataAccessControl: true + # AccessibleSaveDataIds: [0x101, 0x202, 0x303, 0x404, 0x505, 0x606] + FileSystemAccess: + # - CategorySystemApplication + # - CategoryHardwareCheck + # - CategoryFileSystemTool + - Debug + # - TwlCardBackup + # - TwlNandData + # - Boss + - DirectSdmc + # - Core + # - CtrNandRo + # - CtrNandRw + # - CtrNandRoWrite + # - CategorySystemSettings + # - CardBoard + # - ExportImportIvs + # - DirectSdmcWrite + # - SwitchCleanup + # - SaveDataMove + # - Shop + # - Shell + # - CategoryHomeMenu + IoAccessControl: + # - FsMountNand + # - FsMountNandRoWrite + # - FsMountTwln + # - FsMountWnand + # - FsMountCardSpi + # - UseSdif3 + # - CreateSeed + # - UseCardSpi + + IdealProcessor : 0 + AffinityMask : 1 + + Priority : 16 + + MaxCpu : 0x9E # Default + + DisableDebug : true + EnableForceDebug : false + CanWriteSharedPage : true + CanUsePrivilegedPriority : false + CanUseNonAlphabetAndNumber : true + PermitMainFunctionArgument : true + CanShareDeviceMemory : true + RunnableOnSleep : false + SpecialMemoryArrange : true + + CoreVersion : 2 + DescVersion : 2 + + ReleaseKernelMajor : "02" + ReleaseKernelMinor : "33" + MemoryType : Application # Application / System / Base + HandleTableSize: 512 + IORegisterMapping: + - 1ff50000-1ff57fff + - 1ff70000-1ff77fff + MemoryMapping: + - 1f000000-1f5fffff:r + SystemCallAccess: + ArbitrateAddress: 34 + Break: 60 + CancelTimer: 28 + ClearEvent: 25 + ClearTimer: 29 + CloseHandle: 35 + ConnectToPort: 45 + ControlMemory: 1 + CreateAddressArbiter: 33 + CreateEvent: 23 + CreateMemoryBlock: 30 + CreateMutex: 19 + CreateSemaphore: 21 + CreateThread: 8 + CreateTimer: 26 + DuplicateHandle: 39 + ExitProcess: 3 + ExitThread: 9 + GetCurrentProcessorNumber: 17 + GetHandleInfo: 41 + GetProcessId: 53 + GetProcessIdOfThread: 54 + GetProcessIdealProcessor: 6 + GetProcessInfo: 43 + GetResourceLimit: 56 + GetResourceLimitCurrentValues: 58 + GetResourceLimitLimitValues: 57 + GetSystemInfo: 42 + GetSystemTick: 40 + GetThreadContext: 59 + GetThreadId: 55 + GetThreadIdealProcessor: 15 + GetThreadInfo: 44 + GetThreadPriority: 11 + MapMemoryBlock: 31 + OutputDebugString: 61 + QueryMemory: 2 + ReleaseMutex: 20 + ReleaseSemaphore: 22 + SendSyncRequest1: 46 + SendSyncRequest2: 47 + SendSyncRequest3: 48 + SendSyncRequest4: 49 + SendSyncRequest: 50 + SetThreadPriority: 12 + SetTimer: 27 + SignalEvent: 24 + SleepThread: 10 + UnmapMemoryBlock: 32 + WaitSynchronization1: 36 + WaitSynchronizationN: 37 + InterruptNumbers: + ServiceAccessControl: + - APT:U + - $hioFIO + - $hostio0 + - $hostio1 + - ac:u + - boss:U + - cam:u + - cecd:u + - cfg:u + - dlp:FKCL + - dlp:SRVR + - dsp::DSP + - frd:u + - fs:USER + - gsp::Gpu + - hid:USER + - http:C + - mic:u + - ndm:u + - news:u + - nwm::UDS + - ptm:u + - pxi:dev + - soc:U + - ssl:C + - y2r:u + - ldr:ro + - ir:USER + + +SystemControlInfo: + SaveDataSize: 0KB # It doesn't use any save data. + RemasterVersion: 2 + StackSize: 0x40000 + # JumpId: 0 + Dependency: + ac: 0x0004013000002402L + am: 0x0004013000001502L + boss: 0x0004013000003402L + camera: 0x0004013000001602L + cecd: 0x0004013000002602L + cfg: 0x0004013000001702L + codec: 0x0004013000001802L + csnd: 0x0004013000002702L + dlp: 0x0004013000002802L + dsp: 0x0004013000001a02L + friends: 0x0004013000003202L + gpio: 0x0004013000001b02L + gsp: 0x0004013000001c02L + hid: 0x0004013000001d02L + http: 0x0004013000002902L + i2c: 0x0004013000001e02L + ir: 0x0004013000003302L + mcu: 0x0004013000001f02L + mic: 0x0004013000002002L + ndm: 0x0004013000002b02L + news: 0x0004013000003502L + nim: 0x0004013000002c02L + nwm: 0x0004013000002d02L + pdn: 0x0004013000002102L + ps: 0x0004013000003102L + ptm: 0x0004013000002202L + ro: 0x0004013000003702L + socket: 0x0004013000002e02L + spi: 0x0004013000002302L + ssl: 0x0004013000002f02L diff --git a/testbed/source/Core.cpp b/testbed/source/Core.cpp index 8e5ad4d..8b60f85 100644 --- a/testbed/source/Core.cpp +++ b/testbed/source/Core.cpp @@ -17,6 +17,8 @@ #include "starlight/ui/Button.h" #include "starlight/ui/TextBox.h" #include "starlight/ui/Label.h" +#include "starlight/ui/Image.h" +#include "starlight/ui/DebugConsole.h" #include "starlight/dialog/Backdrop.h" #include "starlight/dialog/MessageBox.h" @@ -38,7 +40,11 @@ using starlight::util::Path; using starlight::Application; void Core::Init() { - //consoleInit(GFX_TOP, consoleGetDefault()); + /*clearColor = Color(0,0,0.5); + auto img = touchScreen->AddNew(Vector2(32, 32), "sdmc:/snes9x_3ds_top.png"); + auto lbl = touchScreen->AddNew(VRect(0,0,320,240)); + lbl->SetText("text go here\ntest test test\nnickelpickle"); + return;*/ auto container = std::make_shared(VRect(0,0,320-0,240-0)); touchScreen->Add(container); @@ -55,11 +61,20 @@ void Core::Init() { // assemble and open a basic form auto form = std::make_shared(true); - auto label = std::make_shared(VRect(0,0,320,0)); + auto tbtn = form->touchScreen->AddNew(VRect(4, 28, 80, 24)); + tbtn->SetText("print something"); + tbtn->eOnTap = [](auto& btn){ + printf("pickles!\n"); + }; + + /*auto label = std::make_shared(VRect(0,0,320,0)); label->textConfig->justification = Vector2::half; label->autoSizeV = true; label->SetText("This is a form, coming in and nuking the non-form UI elements. Whoops."); - form->touchScreen->Add(label); + form->touchScreen->Add(label);*/ + + //auto console = form->topScreen->AddNew(VRect::topScreen); + //console->Start(); auto xbtn = std::make_shared(VRect(320-96,28,32,24)); xbtn->eOnTap = [](auto& btn){ @@ -68,13 +83,13 @@ void Core::Init() { xbtn->SetText("(exit)"); form->touchScreen->Add(xbtn); - auto tlbl = std::make_shared(VRect(2, 2, 396, 0)); + /*auto tlbl = std::make_shared(VRect(2, 2, 396, 0)); tlbl->autoSizeV = true; tlbl->SetPreset("normal.16"); tlbl->textConfig->justification = Vector2::zero; tlbl->textConfig->borderColor = Color::black; tlbl->SetText("3DS:~# sudo make me a sandwich_"); - form->topScreen->Add(tlbl); + form->topScreen->Add(tlbl);*/ auto tb = std::make_shared(VRect(0, 64, 320, 24).Expand(-16, 0)); tb->text = "Single-line TextBox widget example. Tap me!"; @@ -118,7 +133,7 @@ void Core::Init() { cc.Json()["panini"] = "yes please!"; cc.Save(); - // + //*/ } void Core::End() { diff --git a/testbed/starlight-testbed.cia b/testbed/starlight-testbed.cia new file mode 100644 index 0000000..08b6412 Binary files /dev/null and b/testbed/starlight-testbed.cia differ