├── .gitignore
├── LICENSE.txt
├── README.md
├── libstarlight
├── Makefile
├── source
│ └── starlight
│ │ ├── Application.cpp
│ │ ├── Application.h
│ │ ├── ConfigManager.cpp
│ │ ├── ConfigManager.h
│ │ ├── GFXManager.cpp
│ │ ├── GFXManager.h
│ │ ├── InputManager.cpp
│ │ ├── InputManager.h
│ │ ├── ThemeManager.cpp
│ │ ├── ThemeManager.h
│ │ ├── _global.h
│ │ ├── _incLib
│ │ ├── _stringfix.h
│ │ ├── json.hpp
│ │ ├── json_extensions.hpp
│ │ ├── json_fwd.hpp
│ │ ├── lodepng.cpp
│ │ └── lodepng.h
│ │ ├── datatypes
│ │ ├── Color.cpp
│ │ ├── Color.h
│ │ ├── OptRef.h
│ │ ├── Optional.h
│ │ ├── VRect.cpp
│ │ ├── VRect.h
│ │ ├── Vector2.cpp
│ │ └── Vector2.h
│ │ ├── dialog
│ │ ├── Backdrop.cpp
│ │ ├── Backdrop.h
│ │ ├── MessageBox.cpp
│ │ ├── MessageBox.h
│ │ ├── OSK.cpp
│ │ ├── OSK.h
│ │ └── osk
│ │ │ ├── InputHandler.cpp
│ │ │ └── InputHandler.h
│ │ ├── gfx
│ │ ├── BitmapFont.cpp
│ │ ├── BitmapFont.h
│ │ ├── DisplayList.cpp
│ │ ├── DisplayList.h
│ │ ├── DrawContext.cpp
│ │ ├── DrawContext.h
│ │ ├── DrawContextCanvas.cpp
│ │ ├── DrawContextCanvas.h
│ │ ├── DrawContextTopScreen.cpp
│ │ ├── DrawContextTopScreen.h
│ │ ├── DrawContextTouchscreen.cpp
│ │ ├── DrawContextTouchscreen.h
│ │ ├── Drawable.cpp
│ │ ├── Drawable.h
│ │ ├── DrawableImage.cpp
│ │ ├── DrawableImage.h
│ │ ├── DrawableNinePatch.cpp
│ │ ├── DrawableNinePatch.h
│ │ ├── DrawableTest.cpp
│ │ ├── DrawableTest.h
│ │ ├── Enums.h
│ │ ├── Font.cpp
│ │ ├── Font.h
│ │ ├── FontBMF.cpp
│ │ ├── FontBMF.h
│ │ ├── FontNull.h
│ │ ├── RenderCore.cpp
│ │ ├── RenderCore.h
│ │ ├── ThemeRef.h
│ │ └── basic_shader.v.pica
│ │ ├── threading
│ │ ├── Thread.cpp
│ │ └── Thread.h
│ │ ├── ui
│ │ ├── Button.cpp
│ │ ├── Button.h
│ │ ├── DebugConsole.cpp
│ │ ├── DebugConsole.h
│ │ ├── DrawLayerProxy.cpp
│ │ ├── DrawLayerProxy.h
│ │ ├── Form.cpp
│ │ ├── Form.h
│ │ ├── Image.cpp
│ │ ├── Image.h
│ │ ├── Label.cpp
│ │ ├── Label.h
│ │ ├── ParallaxLayer.cpp
│ │ ├── ParallaxLayer.h
│ │ ├── ScrollField.cpp
│ │ ├── ScrollField.h
│ │ ├── TextBox.cpp
│ │ ├── TextBox.h
│ │ ├── TopScreenCanvas.cpp
│ │ ├── TopScreenCanvas.h
│ │ ├── TouchScreenCanvas.cpp
│ │ ├── TouchScreenCanvas.h
│ │ ├── UICanvas.cpp
│ │ ├── UICanvas.h
│ │ ├── UIContainer.cpp
│ │ ├── UIContainer.h
│ │ ├── UIElement.cpp
│ │ └── UIElement.h
│ │ └── util
│ │ ├── FSHelper.cpp
│ │ ├── FSHelper.h
│ │ ├── FrameTimer.cpp
│ │ ├── FrameTimer.h
│ │ ├── JsonConversions.cpp
│ │ ├── JsonConversions.h
│ │ ├── Path.cpp
│ │ ├── Path.h
│ │ ├── Profiler.cpp
│ │ ├── Profiler.h
│ │ ├── WorkerThread.cpp
│ │ └── WorkerThread.h
└── todo.txt
├── maketest.sh
├── testbed
├── Makefile
├── resources
│ ├── audio_3ds.wav
│ ├── banner.bnr
│ ├── banner_3ds.png
│ ├── logo.bcma.lz
│ └── starlight-testbed.rsf
├── source
│ ├── Core.cpp
│ ├── Core.h
│ ├── ThreadTest.cpp
│ ├── ThreadTest.h
│ └── main.cpp
└── starlight-testbed.xml
└── themes
└── default
├── about.txt
├── controls
├── button.idle.json
├── button.idle.png
├── button.press.json
├── button.press.png
├── button.xcf
├── textBox.json
├── textBox.png
└── textBox.xcf
├── decorations
├── dialog.modal-cover.png
├── dialog.modal-cover.xcf
├── generic backdrop.png
├── generic backdrop.xcf
├── osk.background.png
├── osk.background.xcf
├── panel.bg.json
└── panel.bg.png
├── fonts
├── credit.txt
├── default.12.border.png
├── default.12.json
├── default.12.png
├── default.16.border.png
├── default.16.json
├── default.16.png
├── mono.12.border.png
├── mono.12.json
├── mono.12.png
├── mono.16.border.png
├── mono.16.json
└── mono.16.png
├── glyphs
├── backspace.large.png
├── backspace.small.png
├── backspace.xcf
├── enter.large.png
├── enter.small.png
├── enter.xcf
├── shift.large.png
├── shift.small.png
└── shift.xcf
└── metrics.json
/.gitignore:
--------------------------------------------------------------------------------
1 | # Prerequisites
2 | *.d
3 |
4 | # Compiled Object files
5 | *.slo
6 | *.lo
7 | *.o
8 | *.obj
9 |
10 | # Precompiled Headers
11 | *.gch
12 | *.pch
13 |
14 | # Compiled Dynamic libraries
15 | *.so
16 | *.dylib
17 | *.dll
18 |
19 | # Fortran module files
20 | *.mod
21 | *.smod
22 |
23 | # Compiled Static libraries
24 | *.lai
25 | *.la
26 | *.a
27 | *.lib
28 |
29 | # Executables
30 | *.exe
31 | *.out
32 | *.app
33 | *.elf
34 | *.3dsx
35 | *.cia
36 | # ...and icons
37 | *.smdh
38 |
39 | # section-specifics
40 |
41 | # libstarlight main
42 | libstarlight/build/
43 | libstarlight/lib/
44 | libstarlight/include/
45 | libstarlight/lib*.tar.bz2
46 |
47 | # testbed
48 | testbed/build/
49 |
--------------------------------------------------------------------------------
/LICENSE.txt:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2017 Beau Jessee ("zetaPRIME")
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
23 | // Bundled dependencies (see _incLib) have their own terms and/or notices, as listed in their respective files.
24 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 | #
- libstarlight -
3 |
4 | ###
3DS Homebrew Application Framework
5 | ---
6 | (Pardon the dust, both the library and this readme are still a work in progress)
7 |
8 | ## What is this?
9 | libstarlight is a fully-featured application framework for 3DS homebrew written in C++14.
10 |
11 | Features include:
12 | * Fully themable UI framework with rich widgets designed for the 3DS's touchscreen
13 | * Underlying graphics framework built on citro3d, using premultiplied alpha blending
14 |
(textures automatically converted on load)
15 | * Streamlined, easy-to-use onscreen keyboard
16 | * Centralized configuration system for application-specific settings and storage, complete with optional auto-saving on exit
17 | * Filesystem helpers to streamline working with SD and romfs contents
18 | * Various basic datatypes for convenience and interoperability
19 |
20 | Please keep in mind that while libstarlight is still in beta (pre-1.0.0) not everything is final. Expect occasional (usually minor) breaking changes as things settle.
21 |
22 | ## Requirements
23 | libstarlight requires devkitARM r46 or later, along with:
24 | * reasonably up-to-date libctru
25 | * citro3d
26 |
27 | Additionally, libstarlight contains versions of the following bundled within:
28 | * [lodepng](https://github.com/lvandeve/lodepng)
29 | * [nlohmann::json (JSON For Modern C++)](https://github.com/nlohmann/json)
30 |
31 | ## Okay, so how do I use this?
32 | (section WIP, take a look at the testbed for a slightly scattered example)
33 |
34 | To ensure your application runs properly without themes installed to the SD card, it is recommended to include a copy of the default theme (or any theme with no fallback) at `romfs:/.fallback_theme/`.
35 |
36 | (Themes on SD go in `sdmc:/.starlight/themes/`)
37 |
38 | ## License
39 | * MIT (see [license.md](license.md))
40 |
41 | Bundled dependencies (see [\_incLib](libstarlight/source/starlight/_incLib)) have their own terms and/or notices, as listed in their respective files.
42 |
--------------------------------------------------------------------------------
/libstarlight/Makefile:
--------------------------------------------------------------------------------
1 | #---------------------------------------------------------------------------------
2 | .SUFFIXES:
3 | #---------------------------------------------------------------------------------
4 |
5 | ifeq ($(strip $(DEVKITARM)),)
6 | $(error "Please set DEVKITARM in your environment. export DEVKITARM=devkitARM")
7 | endif
8 |
9 | include $(DEVKITARM)/3ds_rules
10 |
11 | VERSION := 0.1.0
12 |
13 | #---------------------------------------------------------------------------------
14 | # TARGET is the name of the output
15 | # BUILD is the directory where object files & intermediate files will be placed
16 | # SOURCES is a list of directories containing source code
17 | # DATA is a list of directories containing data files
18 | # INCLUDES is a list of directories containing header files
19 | #---------------------------------------------------------------------------------
20 | TARGET := starlight
21 | BUILD := build
22 | SOURCES := $(sort $(dir $(wildcard source/*/ source/*/*/ source/*/*/*/ source/*/*/*/*/ source/*/*/*/*/*/)))
23 |
24 | DATA := data
25 | INCLUDES := include
26 |
27 | #---------------------------------------------------------------------------------
28 | # options for code generation
29 | #---------------------------------------------------------------------------------
30 | ARCH := -march=armv6k -mtune=mpcore -mfloat-abi=hard -mtp=soft
31 |
32 | # why was -Werror here?
33 | CFLAGS := -g -Wall -Wno-psabi -O2 -mword-relocations \
34 | -ffunction-sections \
35 | -fomit-frame-pointer \
36 | $(ARCH)
37 |
38 | CFLAGS += $(INCLUDE) -DARM11 -D_3DS
39 |
40 | # json requires exception support, nuke -fno-exceptions
41 | CXXFLAGS := $(CFLAGS) -fno-rtti -std=c++17
42 |
43 | ASFLAGS := -g $(ARCH)
44 |
45 | LIBS := -lcitro3d -lctru -lm
46 |
47 | #---------------------------------------------------------------------------------
48 | # list of directories containing libraries, this must be the top level containing
49 | # include and lib
50 | #---------------------------------------------------------------------------------
51 | LIBDIRS := $(CTRULIB) $(PORTLIBS)
52 |
53 | #---------------------------------------------------------------------------------
54 | # no real need to edit anything past this point unless you need to add additional
55 | # rules for different file extensions
56 | #---------------------------------------------------------------------------------
57 | ifneq ($(BUILD),$(notdir $(CURDIR)))
58 | #---------------------------------------------------------------------------------
59 |
60 | export OUTPUT := $(CURDIR)/lib/lib$(TARGET).a
61 |
62 | export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \
63 | $(foreach dir,$(DATA),$(CURDIR)/$(dir))
64 |
65 | export DEPSDIR := $(CURDIR)/$(BUILD)
66 |
67 | CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))
68 | CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp)))
69 | SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
70 | PICAFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.v.pica)))
71 | SHLISTFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.shlist)))
72 | BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*)))
73 |
74 | #---------------------------------------------------------------------------------
75 | # use CXX for linking C++ projects, CC for standard C
76 | #---------------------------------------------------------------------------------
77 | ifeq ($(strip $(CPPFILES)),)
78 | #---------------------------------------------------------------------------------
79 | export LD := $(CC)
80 | #---------------------------------------------------------------------------------
81 | else
82 | #---------------------------------------------------------------------------------
83 | export LD := $(CXX)
84 | #---------------------------------------------------------------------------------
85 | endif
86 | #---------------------------------------------------------------------------------
87 |
88 | export OFILES := $(addsuffix .o,$(BINFILES)) \
89 | $(PICAFILES:.v.pica=.shbin.o) $(SHLISTFILES:.shlist=.shbin.o) \
90 | $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o)
91 |
92 | export INCLUDE := -I$(CURDIR)/source $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \
93 | $(foreach dir,$(LIBDIRS),-I$(dir)/include) \
94 | -I$(CURDIR)/$(BUILD)
95 |
96 | export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib)
97 |
98 | .PHONY: $(BUILD) clean all
99 |
100 | #---------------------------------------------------------------------------------
101 | all: $(BUILD)
102 |
103 | dist-bin: all
104 | @rm -rf include/
105 | @rsync -a --include '*/' --include '*.h' --include '*.hpp' --exclude '*' source/ include/
106 | @tar --exclude=*~ -cjf libstarlight-$(VERSION).tar.bz2 include lib
107 |
108 | dist-src:
109 | @rm -rf include/
110 | @rsync -a --include '*/' --include '*.h' --include '*.hpp' --exclude '*' source/ include/
111 | @tar --exclude=*~ -cjf libstarlight-src-$(VERSION).tar.bz2 include source data Makefile Doxyfile Doxyfile.internal
112 |
113 | dist: dist-src dist-bin
114 |
115 | install: dist-bin
116 | @rm -rf $(DEVKITPRO)/libstarlight
117 | @mkdir -p $(DEVKITPRO)/libstarlight
118 | bzip2 -cd libstarlight-$(VERSION).tar.bz2 | tar -xf - -C $(DEVKITPRO)/libstarlight
119 |
120 | dox:
121 | @doxygen Doxyfile
122 | @doxygen Doxyfile.internal
123 |
124 | lib:
125 | @[ -d $@ ] || mkdir -p $@
126 |
127 | $(BUILD): lib
128 | @[ -d $@ ] || mkdir -p $@
129 | @$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
130 |
131 | #---------------------------------------------------------------------------------
132 | clean:
133 | @echo clean ...
134 | @rm -fr $(BUILD) lib include docs internal_docs
135 |
136 | #---------------------------------------------------------------------------------
137 | else
138 |
139 | DEPENDS := $(OFILES:.o=.d)
140 |
141 | #---------------------------------------------------------------------------------
142 | # main targets
143 | #---------------------------------------------------------------------------------
144 | $(OUTPUT) : $(OFILES)
145 |
146 | #---------------------------------------------------------------------------------
147 | %.bin.o : %.bin
148 | #---------------------------------------------------------------------------------
149 | @echo $(notdir $<)
150 | @$(bin2o)
151 |
152 | #---------------------------------------------------------------------------------
153 | # rules for assembling GPU shaders
154 | #---------------------------------------------------------------------------------
155 | define shader-as
156 | $(eval CURBIN := $(patsubst %.shbin.o,%.shbin,$(notdir $@)))
157 | picasso -o $(CURBIN) $1
158 | bin2s $(CURBIN) | $(AS) -o $@
159 | echo "extern const u8" `(echo $(CURBIN) | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`"_end[];" > `(echo $(CURBIN) | tr . _)`.h
160 | echo "extern const u8" `(echo $(CURBIN) | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`"[];" >> `(echo $(CURBIN) | tr . _)`.h
161 | echo "extern const u32" `(echo $(CURBIN) | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`_size";" >> `(echo $(CURBIN) | tr . _)`.h
162 | endef
163 |
164 | %.shbin.o : %.v.pica %.g.pica
165 | @echo $(notdir $^)
166 | @$(call shader-as,$^)
167 |
168 | %.shbin.o : %.v.pica
169 | @echo $(notdir $<)
170 | @$(call shader-as,$<)
171 |
172 | %.shbin.o : %.shlist
173 | @echo $(notdir $<)
174 | @$(call shader-as,$(foreach file,$(shell cat $<),$(dir $<)/$(file)))
175 |
176 | -include $(DEPENDS)
177 |
178 | #---------------------------------------------------------------------------------------
179 | endif
180 | #---------------------------------------------------------------------------------------
181 |
--------------------------------------------------------------------------------
/libstarlight/source/starlight/Application.cpp:
--------------------------------------------------------------------------------
1 | #include "Application.h"
2 |
3 | #include <3ds.h>
4 |
5 | #include "starlight/GFXManager.h"
6 | #include "starlight/ConfigManager.h"
7 | #include "starlight/ThemeManager.h"
8 | #include "starlight/InputManager.h"
9 | #include "starlight/gfx/RenderCore.h"
10 |
11 | using std::string;
12 |
13 | using starlight::GFXManager;
14 | using starlight::ConfigManager;
15 | using starlight::Config;
16 | using starlight::ThemeManager;
17 | using starlight::InputManager;
18 | using starlight::gfx::RenderCore;
19 |
20 | using starlight::threading::Thread;
21 | using starlight::threading::ThreadState;
22 |
23 | using starlight::ui::TouchScreenCanvas;
24 | using starlight::ui::TopScreenCanvas;
25 |
26 | using starlight::ui::Form;
27 | using starlight::ui::FormFlags;
28 |
29 | using starlight::Application;
30 |
31 | ////////////////////
32 | // STATIC MEMBERS //
33 | ////////////////////
34 |
35 | Application* Application::_currentApp = nullptr;
36 | unsigned long long Application::ftime = 0;
37 |
38 | bool Application::Quit() {
39 | if (_currentApp == nullptr) return false;
40 | _currentApp->_appQuit = true;
41 | return _currentApp->_appQuit;
42 | }
43 |
44 | Config& Application::GetConfig(const string& path) {
45 | const string& appId = (_currentApp != nullptr) ? _currentApp->appId : "null";
46 | string np(path.length() + appId.length() + 4 + 1, ' ');
47 | np.clear();
48 | np.append("app/"); np.append(appId); np.append("/"); np.append(path);
49 | return ConfigManager::Get(np);
50 | }
51 |
52 | string Application::AppName() {
53 | return (_currentApp != nullptr) ? _currentApp->appId : "null";
54 | }
55 |
56 | //////////////////////
57 | // INSTANCE MEMBERS //
58 | //////////////////////
59 |
60 | void Application::Run() {
61 | if (_currentApp != nullptr) return; // don't run two at once!
62 | _currentApp = this;
63 |
64 | _init();
65 | while (!_appQuit && aptMainLoop()) _mainLoop();
66 | _end();
67 |
68 | _currentApp = nullptr;
69 | }
70 |
71 | void Application::_init() {
72 | srand(time(NULL));
73 | romfsInit();
74 | ConfigManager::Init();
75 | RenderCore::Open();
76 | ThemeManager::Init();
77 |
78 | touchScreen = std::make_shared();
79 | topScreen = std::make_shared();
80 | formTouchScreen = touchScreen.get();
81 | formTopScreen = topScreen.get();
82 |
83 | Init();
84 | }
85 |
86 | void Application::_end() {
87 | End();
88 |
89 | for (auto& thread : threads) thread->Exit();
90 | threads.clear();
91 |
92 | //for (auto& f : forms) f->Close();
93 | forms.clear(); // not sure why, but not doing this results in a data abort if any forms are active
94 |
95 | // force cleanup! let's not softlock, mmkay?
96 | formTouchScreen = nullptr;
97 | formTopScreen = nullptr;
98 | touchScreen.reset();
99 | topScreen.reset();
100 |
101 | ThemeManager::End();
102 | RenderCore::Close();
103 | ConfigManager::End();
104 | }
105 |
106 | void Application::_mainLoop() {
107 | RenderCore::SyncFrame(); // sync to vblank here for more accurate timing
108 | frameTimer.FrameStart();
109 |
110 | if (!forms.empty()) {
111 | if (_sFormState) {
112 | _sFormState = false;
113 |
114 | // sort open forms
115 | forms.sort(Form::OrderedCompare);
116 |
117 | // reconstruct ui container heirarchy
118 | bool otouch = false, otop = false;
119 | formTouchScreen->RemoveAll();
120 | formTopScreen->RemoveAll();
121 |
122 | for (auto it = forms.rbegin(); it != forms.rend(); ++it) {
123 | if ((*it)->IsVisible()) {
124 | if (!otouch) formTouchScreen->Add((*it)->touchScreen, true);
125 | if (!otop) formTopScreen->Add((*it)->topScreen, true);
126 | if ((*it)->GetFlag(FormFlags::canOcclude)) {
127 | if ((*it)->GetFlag(FormFlags::occludeTouch)) otouch = true;
128 | if ((*it)->GetFlag(FormFlags::occludeTop)) otop = true;
129 | }
130 | }
131 | }
132 | //
133 | }
134 | }
135 |
136 | // update step
137 | ftime = osGetTime();
138 |
139 | InputManager::Update();
140 | Update();
141 | { // update loop for forms, guarded from snap-outs
142 | auto it = forms.begin();
143 | while (it != forms.end()) {
144 | auto next = std::next(it);
145 | (*it)->Update(*it == forms.back());
146 | it = next;
147 | }
148 | }
149 | touchScreen->Update();
150 | topScreen->Update();
151 | PostUpdate();
152 |
153 | // draw step
154 | RenderCore::BeginFrame();
155 | RenderCore::targetBottom->Clear(clearColor);
156 | RenderCore::targetTopLeft->Clear(clearColor);
157 | RenderCore::targetTopRight->Clear(clearColor);
158 |
159 | Draw();
160 | touchScreen->PreDraw();
161 | topScreen->PreDraw();
162 | touchScreen->Draw();
163 | topScreen->Draw();
164 | PostDraw();
165 | RenderCore::EndFrame();
166 |
167 | while (!threads.empty() && frameTimer.GetSubframe() < 0.9) {
168 | auto thread = threads.front();
169 | thread->Resume();
170 | if (thread->state != ThreadState::Finished) threads.splice(threads.end(), threads, threads.begin()); // move to back of queue
171 | else threads.pop_front(); // or just discard if already exited
172 | }
173 | }
174 |
175 | void Application::EnqueueThread(std::shared_ptr thread) {
176 | threads.push_back(thread);
177 | thread->Start();
178 | }
179 |
--------------------------------------------------------------------------------
/libstarlight/source/starlight/Application.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include "starlight/_global.h"
3 |
4 | #include
5 | #include
6 | #include
7 |
8 | #include "starlight/datatypes/Vector2.h"
9 | #include "starlight/datatypes/VRect.h"
10 | #include "starlight/datatypes/Color.h"
11 |
12 | #include "starlight/util/FrameTimer.h"
13 |
14 | #include "starlight/threading/Thread.h"
15 |
16 | #include "starlight/ui/TouchScreenCanvas.h"
17 | #include "starlight/ui/TopScreenCanvas.h"
18 |
19 | #include "starlight/ui/Form.h"
20 |
21 | #include "starlight/ConfigManager.h"
22 |
23 | namespace starlight {
24 | class Application {
25 | ////////////////////
26 | // STATIC MEMBERS //
27 | ////////////////////
28 | private:
29 | static Application* _currentApp;
30 | static unsigned long long ftime;
31 |
32 | public:
33 | static bool Quit();
34 | static Config& GetConfig(const std::string& path);
35 | static std::string AppName();
36 | static inline Application* Current() { return _currentApp; }
37 | static inline unsigned long long GetTime() { return ftime; }
38 |
39 | //////////////////////
40 | // INSTANCE MEMBERS //
41 | //////////////////////
42 | private:
43 | bool _appQuit = false;
44 | bool _sFormState = false;
45 | void _init();
46 | void _mainLoop();
47 | void _end();
48 |
49 | std::list> threads;
50 | util::FrameTimer frameTimer;
51 |
52 | public:
53 | const std::string appId;
54 |
55 | Color clearColor = Color::black;
56 |
57 | std::shared_ptr touchScreen = nullptr;
58 | std::shared_ptr topScreen = nullptr;
59 |
60 | std::list> forms;
61 | ui::UIContainer* formTouchScreen = nullptr;
62 | ui::UIContainer* formTopScreen = nullptr;
63 |
64 | Application() = delete;
65 | Application(std::string id) : appId(id) { }
66 | virtual ~Application() = default;
67 |
68 | void Run();
69 |
70 | void EnqueueThread(std::shared_ptr thread);
71 | inline void SignalFormState() { _sFormState = true; }
72 |
73 | virtual void Init() { }
74 | virtual void Update() { }
75 | virtual void PostUpdate() { }
76 | virtual void Draw() { }
77 | virtual void PostDraw() { }
78 | virtual void End() { }
79 | };
80 | }
81 |
--------------------------------------------------------------------------------
/libstarlight/source/starlight/ConfigManager.cpp:
--------------------------------------------------------------------------------
1 | #include "ConfigManager.h"
2 |
3 | #include
4 | #include
5 |
6 | #include
7 | #include
8 |
9 | #include "starlight/_incLib/json.hpp"
10 |
11 | #include "starlight/Application.h"
12 |
13 | #include "starlight/util/FSHelper.h"
14 |
15 | using std::string;
16 | using std::ifstream;
17 | using std::ofstream;
18 |
19 | using starlight::Application;
20 |
21 | using starlight::util::FSHelper;
22 | using starlight::util::Path;
23 |
24 | using starlight::Config;
25 | using starlight::ConfigManager;
26 |
27 | // helper stuff
28 | namespace {
29 | //
30 | }
31 |
32 | ////////////
33 | // Config //
34 | ////////////
35 |
36 | Config::Config(const string& path) : path(path) {
37 | /*static const constexpr char* cpfx = "sdmc:/.starlight/config/";
38 | constexpr std::size_t cpfx_s = std::strlen(cpfx);
39 | // reserve string size
40 | string xfsPath(path.length() + cpfx_s + 5, ' '); xfsPath.clear();
41 | // and build
42 | xfsPath.append(cpfx); xfsPath.append(path); xfsPath.append(".json");
43 | fsPath = Path(xfsPath);*/
44 | fsPath = Path("sdmc:/.starlight/config", true).Combine(path + ".json");
45 |
46 | // init json
47 | this->json = std::make_shared();
48 |
49 | Reload();
50 | }
51 | Config::~Config() { }
52 |
53 | void Config::Reload() {
54 | ifstream load = fsPath.OpenI();
55 | if (load.good()) load >> *json;
56 | }
57 |
58 | void Config::Save() {
59 | ofstream save = fsPath.OpenO();
60 | if (save.good()) save << *json;
61 | }
62 |
63 | ///////////////////
64 | // ConfigManager //
65 | ///////////////////
66 |
67 | std::unordered_map> ConfigManager::cfg;
68 |
69 | void ConfigManager::Init() {
70 | //FSHelper::AssertDirPath("sdmc:/.starlight/config/app/" + Application::AppName());
71 | Get("user").autoSave = true;
72 | }
73 |
74 | void ConfigManager::End() {
75 | for (auto it : cfg) {
76 | auto& c = *it.second.get();
77 | if (c.autoSave) c.Save();
78 | }
79 | // actualy, don't clear in case something uses a static get
80 | // in the future, perhaps discard contents
81 | }
82 |
83 | Config& ConfigManager::Get(const string& path) {
84 | auto const& itr = cfg.find(path);
85 | if (itr == cfg.end()) {
86 | return *cfg.insert(std::make_pair(path, std::make_shared(path))).first->second;
87 | } else return *itr->second;
88 | }
89 |
--------------------------------------------------------------------------------
/libstarlight/source/starlight/ConfigManager.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include "starlight/_global.h"
3 |
4 | #include
5 | #include
6 |
7 | //#include "starlight/_incLib/json_fwd.hpp"
8 | #include "starlight/_incLib/json.hpp"
9 |
10 | #include "starlight/util/Path.h"
11 |
12 | //#include "starlight/gfx/DrawContext.h"
13 |
14 | namespace starlight {
15 | class Config {
16 | private:
17 | util::Path fsPath;
18 | std::shared_ptr json;
19 | public:
20 | const std::string path;
21 | bool autoSave = false;
22 |
23 | Config(const std::string& path);
24 | ~Config();
25 |
26 | void Reload();
27 | void Save();
28 |
29 | nlohmann::json& Json() { return *json; }
30 |
31 | template
32 | T Get(const std::string& path, T defVal, bool writeDefault = false) {
33 | auto jp = nlohmann::json::json_pointer(path);
34 | auto& js = (*json)[jp];
35 | if (js.is_null()) {
36 | if (writeDefault) js = defVal;
37 | return defVal;
38 | }
39 | return js;
40 | }
41 |
42 | template
43 | void Set(const std::string& path, T val) {
44 | (*json)[nlohmann::json::json_pointer(path)] = val;
45 | }
46 | };
47 |
48 | class ConfigManager {
49 | private:
50 | static std::unordered_map> cfg;
51 |
52 | public:
53 | ConfigManager() = delete;
54 |
55 | static void Init();
56 | static void End();
57 |
58 | static Config& Get(const std::string& path);
59 | };
60 | }
61 |
--------------------------------------------------------------------------------
/libstarlight/source/starlight/GFXManager.cpp:
--------------------------------------------------------------------------------
1 | #include "GFXManager.h"
2 |
3 | using starlight::Vector2;
4 | using starlight::GFXManager;
5 | using starlight::gfx::DrawContext;
6 |
7 | std::forward_list GFXManager::ctxStack;
8 | std::forward_list GFXManager::offsetStack;
9 |
10 | float GFXManager::parallax = 0;
11 |
12 | void GFXManager::PushContext(DrawContext* context) {
13 | if (!ctxStack.empty()) ctxStack.front()->Close();
14 | ctxStack.push_front(context);
15 | context->Open();
16 | PushOffset(Vector2::zero);
17 | }
18 |
19 | DrawContext* GFXManager::PopContext() {
20 | //if (ctxStack.empty()) return nullptr;
21 | DrawContext* context = ctxStack.front();
22 | PopOffset();
23 | context->Close();
24 | ctxStack.pop_front();
25 | if (!ctxStack.empty()) ctxStack.front()->Open();
26 | return context;
27 | }
28 |
29 | DrawContext* GFXManager::GetContext() { return !ctxStack.empty() ? ctxStack.front() : nullptr; }
30 |
31 | void GFXManager::PushOffset(Vector2 offset) { offsetStack.push_front(offset); }
32 | void GFXManager::PushOffsetAdd(Vector2 add) { offsetStack.push_front(GetOffset() + add); }
33 | Vector2 GFXManager::PopOffset() {
34 | Vector2 r = GetOffset();
35 | offsetStack.pop_front();
36 | return r;
37 | }
38 | Vector2 GFXManager::GetOffset() { return !offsetStack.empty() ? offsetStack.front() : Vector2::zero; }
39 |
40 | void GFXManager::Reset() {
41 | ctxStack.clear();
42 | offsetStack.clear();
43 | }
44 |
45 | bool GFXManager::PrepareForDrawing() {
46 | if (ctxStack.empty()) return false;
47 | auto context = ctxStack.front();
48 | if (context->drawReady) return true;
49 | return context->Prepare();
50 | }
51 |
52 |
--------------------------------------------------------------------------------
/libstarlight/source/starlight/GFXManager.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include "starlight/_global.h"
3 |
4 | #include
5 |
6 | #include "starlight/gfx/DrawContext.h"
7 |
8 | namespace starlight {
9 | class GFXManager {
10 | private:
11 | static std::forward_list ctxStack;
12 | static std::forward_list offsetStack;
13 | public:
14 | static float parallax;
15 |
16 | GFXManager() = delete;
17 |
18 | static void PushContext(gfx::DrawContext* context);
19 | static gfx::DrawContext* PopContext();
20 | static gfx::DrawContext* GetContext();
21 |
22 | static void PushOffset(Vector2 offset);
23 | static void PushOffsetAdd(Vector2 add);
24 | static Vector2 PopOffset();
25 | static Vector2 GetOffset();
26 |
27 | static void Reset();
28 |
29 | static bool PrepareForDrawing();
30 | };
31 | }
32 |
--------------------------------------------------------------------------------
/libstarlight/source/starlight/InputManager.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include <3ds.h>
8 |
9 | #include "starlight/datatypes/Vector2.h"
10 |
11 | #include "starlight/dialog/OSK.h"
12 |
13 | #include "InputManager.h"
14 |
15 | using starlight::Vector2;
16 | using starlight::ui::UIElement;
17 |
18 | using starlight::dialog::OSK;
19 | using starlight::dialog::osk::InputHandler;
20 |
21 | using starlight::DragHandle;
22 | using starlight::InputManager;
23 |
24 | namespace {
25 | unsigned int heldLast = 0;
26 | unsigned int heldNow = 0;
27 |
28 | Vector2 stickLeftLast;
29 | Vector2 stickLeftNow;
30 | Vector2 stickRightLast;
31 | Vector2 stickRightNow;
32 |
33 | Vector2 touchLast;
34 | Vector2 touchNow;
35 | Vector2 touchStart;
36 | int touchTime;
37 |
38 | Vector2 stickVec(circlePosition cpos) {
39 | Vector2 v (cpos.dx, -cpos.dy);
40 |
41 | float mag = std::min(v.Length() / 150.0f, 1.0f);
42 | mag = std::max(mag * 1.1f - 0.1f, 0.0f);
43 |
44 | v = v.Normalized() * mag;
45 |
46 | return v;
47 | }
48 | }
49 |
50 | void InputManager::Update() {
51 | hidScanInput();
52 | circlePosition cp;
53 | touchPosition tp;
54 |
55 | heldLast = heldNow;
56 | heldNow = hidKeysHeld();
57 |
58 | stickLeftLast = stickLeftNow;
59 | hidCircleRead(&cp);
60 | stickLeftNow = stickVec(cp);
61 | stickRightLast = stickRightNow;
62 | hidCstickRead(&cp);
63 | stickRightNow = stickVec(cp);
64 |
65 | touchLast = touchNow;
66 | hidTouchRead(&tp);
67 | if (Held(Keys::Touch)) touchNow = Vector2(tp.px, tp.py);
68 |
69 | if (Pressed(Keys::Touch)) touchStart = touchLast = touchNow;
70 |
71 | if (!Held(Keys::Touch) && !Released(Keys::Touch)) touchTime = 0;
72 | else touchTime++;
73 |
74 | }
75 |
76 | float InputManager::DepthSlider() { return (*(float*)0x1FF81080); }
77 |
78 | Vector2 InputManager::CirclePad() { return stickLeftNow; }
79 | Vector2 InputManager::CStick() { return stickRightNow; }
80 |
81 | bool InputManager::Held(unsigned int mask) { return heldNow & mask; }
82 | bool InputManager::Pressed(unsigned int mask) { return (heldNow & ~heldLast) & mask; }
83 | bool InputManager::Released(unsigned int mask) { return (heldLast & ~heldNow) & mask; }
84 |
85 | Vector2 InputManager::TouchPos() { return touchNow; }
86 | Vector2 InputManager::TouchDelta() { return touchNow - touchLast; }
87 | Vector2 InputManager::TouchStart() { return touchStart; }
88 | Vector2 InputManager::TouchDragDist() { return touchNow - touchStart; }
89 | int InputManager::TouchTime() { return touchTime; }
90 |
91 | // drag stuff!
92 | DragHandle InputManager::drag;
93 | DragHandle& DragHandle::Grab(UIElement* e) {
94 | if (rptr == e) return *this;
95 | Release();
96 | rptr = e;
97 | wptr = e->shared_from_this();
98 | e->OnDragStart();
99 | return *this;
100 | }
101 |
102 | DragHandle& DragHandle::PassUp(bool releaseOnFail) {
103 | if (!valid()) return *this; // invalid
104 | UIElement* e = rptr;
105 | while (true) {
106 | if (auto p = e->parent.lock()) {
107 | e = p.get();
108 | if (e->OnDragPassed()) {
109 | return Grab(e);
110 | }
111 | continue;
112 | } else {
113 | if (releaseOnFail) Release();
114 | return *this;
115 | }
116 | break;
117 | }
118 | }
119 |
120 | #define err(nth, wat) *((unsigned int*)0x00100000+(nth))=wat;
121 | #define ded(wat) err(0,wat)
122 | void DragHandle::Release() {
123 | if (!valid()) return; // nothing to release
124 | UIElement* e = rptr;
125 | rptr = nullptr;
126 | wptr = std::shared_ptr(nullptr);
127 | e->OnDragRelease();
128 | }
129 |
130 | void InputManager::OpenKeyboard(InputHandler* handler) {
131 | // todo: open different keyboard type depending on user settings
132 | OSK::New(handler)->Open();
133 | }
134 |
--------------------------------------------------------------------------------
/libstarlight/source/starlight/InputManager.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include "starlight/_global.h"
3 |
4 | #include
5 |
6 | #include "starlight/datatypes/Vector2.h"
7 |
8 | #include "starlight/ui/UIElement.h"
9 |
10 | // based on ctrulib's enum
11 | #ifndef BIT
12 | #define BIT(n) (1U<<(n))
13 | #endif
14 | enum class Keys : unsigned int {
15 | A = BIT(0), ///< A
16 | B = BIT(1), ///< B
17 | Select = BIT(2), ///< Select
18 | Start = BIT(3), ///< Start
19 | DPadRight = BIT(4), ///< D-Pad Right
20 | DPadLeft = BIT(5), ///< D-Pad Left
21 | DPadUp = BIT(6), ///< D-Pad Up
22 | DPadDown = BIT(7), ///< D-Pad Down
23 | R = BIT(8), ///< R
24 | L = BIT(9), ///< L
25 | X = BIT(10), ///< X
26 | Y = BIT(11), ///< Y
27 | ZL = BIT(14), ///< ZL (New 3DS only)
28 | ZR = BIT(15), ///< ZR (New 3DS only)
29 | Touch = BIT(20), ///< Touch (Not actually provided by HID)
30 | CStickRight = BIT(24), ///< C-Stick Right (New 3DS only)
31 | CStickLeft = BIT(25), ///< C-Stick Left (New 3DS only)
32 | CStickUp = BIT(26), ///< C-Stick Up (New 3DS only)
33 | CStickDown = BIT(27), ///< C-Stick Down (New 3DS only)
34 | CPadRight = BIT(28), ///< Circle Pad Right
35 | CPadLeft = BIT(29), ///< Circle Pad Left
36 | CPadUp = BIT(30), ///< Circle Pad Up
37 | CPadDown = BIT(31), ///< Circle Pad Down
38 |
39 | // Generic catch-all directions
40 | Up = DPadUp | CPadUp, ///< D-Pad Up or Circle Pad Up
41 | Down = DPadDown | CPadDown, ///< D-Pad Down or Circle Pad Down
42 | Left = DPadLeft | CPadLeft, ///< D-Pad Left or Circle Pad Left
43 | Right = DPadRight | CPadRight, ///< D-Pad Right or Circle Pad Right
44 | };
45 |
46 | inline constexpr unsigned int operator*(Keys k) { return static_cast(k); }
47 | inline constexpr Keys operator|(Keys k1, Keys k2) { return static_cast(*k1 | *k2); }
48 |
49 | namespace starlight {
50 | // forward declare this for OpenKeyboard
51 | namespace dialog {
52 | namespace osk {
53 | class InputHandler;
54 | }
55 | }
56 |
57 | class InputManager;
58 | class DragHandle {
59 | friend class starlight::InputManager;
60 | private:
61 |
62 | protected:
63 |
64 | public:
65 | std::weak_ptr wptr;
66 | starlight::ui::UIElement* rptr = nullptr;
67 |
68 | DragHandle() { }
69 | DragHandle(const DragHandle&) = delete;
70 | ~DragHandle() { }
71 |
72 | DragHandle& Grab(starlight::ui::UIElement* e);
73 | DragHandle& PassUp(bool releaseOnFail = false);
74 | void Release();
75 |
76 | inline starlight::ui::UIElement* get() const { if (wptr.expired()) return nullptr; return rptr; }
77 | inline bool valid() const { return rptr != nullptr && !wptr.expired(); };
78 |
79 | inline explicit operator bool() const { return rptr != nullptr && !wptr.expired(); }
80 | inline bool operator ==(starlight::ui::UIElement* e) const { return rptr == e; }
81 | //starlight::ui::UIElement& operator *() const { return *rptr; } // as with optref, do *not* call without checking first
82 | };
83 |
84 | class InputManager {
85 | private:
86 | static DragHandle drag;
87 |
88 | public:
89 | static constexpr const float dragThreshold = 8.0f;
90 | static constexpr const float flingThreshold = 5.0f;
91 |
92 | static void Update();
93 |
94 | static float DepthSlider();
95 |
96 | static Vector2 CirclePad();
97 | static Vector2 CStick();
98 |
99 | static bool Held(unsigned int mask);
100 | static inline bool Held(Keys mask) { return Held(*mask); }
101 | static bool Pressed(unsigned int mask);
102 | static inline bool Pressed(Keys mask) { return Pressed(*mask); }
103 | static bool Released(unsigned int mask);
104 | static inline bool Released(Keys mask) { return Released(*mask); }
105 |
106 | static Vector2 TouchPos();
107 | static Vector2 TouchDelta();
108 | static Vector2 TouchStart();
109 | static Vector2 TouchDragDist();
110 | static int TouchTime();
111 |
112 | static DragHandle& GetDragHandle() { return InputManager::drag; }
113 |
114 | static void OpenKeyboard(dialog::osk::InputHandler* handler);
115 |
116 | private:
117 | InputManager() {}
118 | };
119 | }
120 |
--------------------------------------------------------------------------------
/libstarlight/source/starlight/ThemeManager.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include "starlight/_global.h"
3 |
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 |
10 | #include "starlight/_incLib/json_fwd.hpp"
11 |
12 | #include "starlight/util/Path.h"
13 |
14 | #include "starlight/gfx/Drawable.h"
15 | #include "starlight/gfx/Font.h"
16 |
17 | namespace starlight {
18 | // forward declare
19 | namespace gfx {
20 | template class ThemeRefContainer;
21 | template class ThemeRef;
22 | }
23 |
24 | struct ThemeInfo {
25 | public:
26 | std::string name;
27 | util::Path basePath;
28 |
29 | std::shared_ptr meta;
30 | std::shared_ptr metrics;
31 |
32 | ThemeInfo() = default;
33 | ThemeInfo(const std::string& name);
34 | ThemeInfo(const util::Path& path, const std::string& name = "");
35 | ~ThemeInfo() = default;
36 | };
37 |
38 | class ThemeManager {
39 | template
40 | friend class starlight::gfx::ThemeRefContainer;
41 | private:
42 | static std::unordered_map> drawables;
43 | static std::unordered_map> fonts;
44 | static std::list> tq;
45 | protected:
46 | static std::list themeData;
47 |
48 | static void Fulfill(gfx::ThemeRefContainer& ref);
49 | static void Fulfill(gfx::ThemeRefContainer& ref);
50 |
51 | static std::shared_ptr LoadAsset(std::string& path, gfx::ThemeRefContainer& ref);
52 | public:
53 | ThemeManager() = delete; // "static" class
54 |
55 | static void Init();
56 | static void End();
57 |
58 | static void GC();
59 |
60 | static gfx::ThemeRef GetAsset(const std::string& name);
61 | static gfx::ThemeRef GetFont(const std::string& name);
62 |
63 | static void LoadProc();
64 |
65 | static std::string ResolveAssetPath(const std::string& id);
66 | static std::string ResolveFontPath(const std::string& id);
67 |
68 | static inline std::string GetThemeName() { return themeData.front().name; }
69 | static nlohmann::json& GetMetric(const std::string& path);
70 | template static T GetMetric(const std::string& path, const T& defaultValue);
71 | template static T GetMetric(const std::string& path);
72 | };
73 | }
74 |
75 | // post-include dependency
76 | #include "starlight/gfx/ThemeRef.h"
77 |
78 | // and some metrics types depending on ThemeRef
79 | namespace starlight {
80 | struct TextConfig {
81 | gfx::ThemeRef font = ThemeManager::GetFont("default.12");
82 | Color textColor = Color::white;
83 | Color borderColor = Color::transparent;
84 | Vector2 justification = Vector2::zero;
85 |
86 | TextConfig() = default;
87 | TextConfig(const std::string& fontName, Color text, Color border = Color::transparent);
88 | ~TextConfig() = default;
89 |
90 | TextConfig(const TextConfig& o) : textColor(o.textColor), borderColor(o.borderColor), justification(o.justification) { font = o.font; }
91 | TextConfig(const TextConfig&& o) : textColor(o.textColor), borderColor(o.borderColor), justification(o.justification) { font = o.font; }
92 | TextConfig& operator =(const TextConfig& o) {
93 | font = o.font; textColor = o.textColor; borderColor = o.borderColor; justification = o.justification;
94 | return *this;
95 | }
96 | TextConfig& operator =(const TextConfig&& o) {
97 | font = o.font; textColor = o.textColor; borderColor = o.borderColor; justification = o.justification;
98 | return *this;
99 | }
100 |
101 | void Print(Vector2 position, const std::string& text, Vector2 justification = Vector2::invalid);
102 | void Print(VRect rect, const std::string& text, Vector2 justification = Vector2::invalid);
103 |
104 | Vector2 Measure(const std::string& text, float maxWidth = 65536*64);
105 |
106 | Vector2 GetCursorPosition(VRect rect, const std::string& text, unsigned int end);
107 | unsigned int GetCursorFromPoint(VRect rect, const std::string& text, Vector2 pt);
108 | };
109 | }
110 |
--------------------------------------------------------------------------------
/libstarlight/source/starlight/_global.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | // set up namespace shorthand
4 | namespace starlight {}
5 | namespace sl = starlight;
6 |
--------------------------------------------------------------------------------
/libstarlight/source/starlight/_incLib/_stringfix.h:
--------------------------------------------------------------------------------
1 | // okay, this is super ugly, but as of right now devkitARM seems to be missing some string conversion functions :(
2 |
3 | #pragma once
4 |
5 | // !! UNCOMMENT if using devkitARM r45 or earlier !!
6 | //#include
7 | //#include
8 |
9 | // add in missing string functions
10 | #if defined(_GLIBCXX_STRING) && !defined(_GLIBCXX_USE_C99)
11 | // !! UNCOMMENT if using devkitARM r45 or earlier !!
12 | /*namespace std { // whee ugly hacks!
13 | template
14 | std::string to_string(T value) {
15 | std::ostringstream os;
16 | os << value;
17 | return os.str();
18 | }
19 | int stoi(const string& str) {
20 | stringstream ss(str);
21 | int N;
22 | ss<>N;
24 | return N;
25 | }
26 | float strtof(const string& str) {
27 | stringstream ss(str);
28 | float N;
29 | ss<>N;
31 | return N;
32 | }
33 | double strtod(const string& str) {
34 | stringstream ss(str);
35 | double N;
36 | ss<>N;
38 | return N;
39 | }
40 | long double strtold(const string& str) {
41 | stringstream ss(str);
42 | long double N;
43 | ss<>N;
45 | return N;
46 | }
47 | }//*/
48 | #endif
49 |
--------------------------------------------------------------------------------
/libstarlight/source/starlight/_incLib/json_extensions.hpp:
--------------------------------------------------------------------------------
1 | // libstarlight extensions for nlohmann::json (include nested within basic_json)
2 |
3 | // try_get: reads out if applicable, else leaves the target alone
4 | void try_get(int& v) { if (is_number()) v = get(); }
5 | void try_get(float& v) { if (is_number()) v = get(); }
6 | void try_get(std::string& v) { if (is_string()) v = get(); }
7 |
8 | /*bool has(std::string& idx) const {
9 | return find(idx) != end();
10 | }*/
11 |
--------------------------------------------------------------------------------
/libstarlight/source/starlight/_incLib/json_fwd.hpp:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #ifndef NLOHMANN_JSON_FWD_HPP
4 | #define NLOHMANN_JSON_FWD_HPP
5 |
6 | #include
7 | #include