mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-03-18 21:30:38 +01:00
Merge pull request #332 from M4xi1m3/omega-3ds-dev
[Feature] Port Omega to the 3DS
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -2,6 +2,7 @@
|
||||
/build/artifacts/
|
||||
build/device/**/*.pyc
|
||||
epsilon.elf
|
||||
epsilon.map
|
||||
.vscode
|
||||
.DS_Store
|
||||
.gradle
|
||||
|
||||
5
build/platform.simulator.3ds.mak
Normal file
5
build/platform.simulator.3ds.mak
Normal file
@@ -0,0 +1,5 @@
|
||||
TOOLCHAIN = devkitarm
|
||||
EXE = elf
|
||||
|
||||
HANDY_TARGETS_EXTENSIONS = 3dsx
|
||||
|
||||
9
build/targets.simulator.3ds.mak
Normal file
9
build/targets.simulator.3ds.mak
Normal file
@@ -0,0 +1,9 @@
|
||||
|
||||
%.smdh: ion/src/simulator/3ds/assets/logo.png
|
||||
$(Q) echo "SMDH $(notdir $@)"
|
||||
$(Q) smdhtool --create "Epsilon" "A Numworks in your 3DS!" "Numworks" ion/src/simulator/3ds/assets/logo.png $@
|
||||
|
||||
$(BUILD_DIR)/%.3dsx: $(BUILD_DIR)/%.elf $(BUILD_DIR)/%.smdh
|
||||
$(Q) echo "3DSX $(notdir $@)"
|
||||
$(Q) 3dsxtool $< $@ --smdh=$(word 2,$^)
|
||||
|
||||
70
build/toolchain.devkitarm.mak
Normal file
70
build/toolchain.devkitarm.mak
Normal file
@@ -0,0 +1,70 @@
|
||||
|
||||
ifeq ($(strip $(DEVKITARM)),)
|
||||
$(error "Please set DEVKITARM in your environment. export DEVKITARM=<path to>devkitARM")
|
||||
endif
|
||||
|
||||
ifeq ($(strip $(DEVKITPRO)),)
|
||||
$(error "Please set DEVKITPRO in your environment. export DEVKITPRO=<path to>devkitPro)
|
||||
endif
|
||||
|
||||
DEVKITPATH=$(shell echo "$(DEVKITPRO)" | sed -e 's/^\([a-zA-Z]\):/\/\1/')
|
||||
|
||||
PREFIX = $(DEVKITPATH)/devkitARM/bin/arm-none-eabi-
|
||||
|
||||
CC = $(PREFIX)gcc
|
||||
CXX = $(PREFIX)g++
|
||||
LD = $(CXX)
|
||||
GDB = $(PREFIX)gdb
|
||||
OBJCOPY = $(PREFIX)objcopy
|
||||
SIZE = $(PREFIX)size
|
||||
|
||||
|
||||
ARCH = -march=armv6k -mtune=mpcore -mfloat-abi=hard -mtp=soft
|
||||
|
||||
CFLAGS = -g -Wall -O2 -mword-relocations \
|
||||
-ffunction-sections \
|
||||
$(ARCH)
|
||||
|
||||
|
||||
LIBDIRS := $(DEVKITPRO)/libctru
|
||||
|
||||
INCLUDE = $(foreach dir,$(LIBDIRS),-I$(dir)/include) \
|
||||
-I$(CURDIR)/$(BUILD)
|
||||
|
||||
CFLAGS += $(INCLUDE) -DARM11 -D_3DS
|
||||
|
||||
CXXFLAGS = $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++11
|
||||
|
||||
ASFLAGS = -g $(ARCH)
|
||||
LDFLAGS = -specs=3dsx.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map)
|
||||
|
||||
LIBS = -lctru -lm
|
||||
|
||||
|
||||
# Always generate debug information
|
||||
SFLAGS += -ggdb3
|
||||
|
||||
# Put data/code symbols in their own subsection
|
||||
# This allows the linker script to precisely place a given symbol
|
||||
SFLAGS += -fdata-sections -ffunction-sections
|
||||
|
||||
ifeq ($(DEBUG),1)
|
||||
LTO ?= 0
|
||||
else
|
||||
LTO ?= 1
|
||||
endif
|
||||
|
||||
ifeq ($(LTO),1)
|
||||
# Use link-time optimization if LTO=1
|
||||
SFLAGS += -flto
|
||||
endif
|
||||
|
||||
# Get rid of unused symbols. This is also useful even if LTO=1.
|
||||
LDFLAGS += -Wl,--gc-sections
|
||||
|
||||
LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib)
|
||||
|
||||
LDFLAGS += $(SFLAGS) $(LIBPATHS) $(LIBS) -lgcc
|
||||
|
||||
# To debug linker scripts, add the following line
|
||||
# LDFLAGS += -Wl,-M
|
||||
33
ion/src/simulator/3ds/Makefile
Normal file
33
ion/src/simulator/3ds/Makefile
Normal file
@@ -0,0 +1,33 @@
|
||||
|
||||
ion_src += $(addprefix ion/src/simulator/3ds/, \
|
||||
main.cpp \
|
||||
callback.cpp \
|
||||
display.cpp \
|
||||
framebuffer.cpp \
|
||||
telemetry_init.cpp \
|
||||
keyboard.cpp \
|
||||
events_keyboard.cpp \
|
||||
driver/display.cpp \
|
||||
driver/language.cpp \
|
||||
driver/led.cpp \
|
||||
driver/usb.cpp \
|
||||
driver/battery.cpp \
|
||||
driver/common.cpp \
|
||||
)
|
||||
|
||||
sdl_simu_needs_to_be_removed += $(addprefix ion/src/simulator/shared/, \
|
||||
dummy/display.cpp \
|
||||
dummy/led.cpp \
|
||||
dummy/usb.cpp \
|
||||
dummy/battery.cpp \
|
||||
display.cpp:-headless \
|
||||
events_keyboard.cpp:-headless \
|
||||
framebuffer_base.cpp \
|
||||
keyboard_sdl.cpp:-headless \
|
||||
main_sdl.cpp:-headless \
|
||||
layout.cpp:-headless \
|
||||
)
|
||||
|
||||
# Remove the dummy diplay (re-implemented) and the SDL simulator stuff.
|
||||
ion_src := $(filter-out $(sdl_simu_needs_to_be_removed),$(ion_src))
|
||||
|
||||
BIN
ion/src/simulator/3ds/assets/logo.png
Normal file
BIN
ion/src/simulator/3ds/assets/logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.4 KiB |
8
ion/src/simulator/3ds/callback.cpp
Normal file
8
ion/src/simulator/3ds/callback.cpp
Normal file
@@ -0,0 +1,8 @@
|
||||
#include "platform.h"
|
||||
|
||||
void IonSimulatorCallbackDidRefresh() {
|
||||
}
|
||||
|
||||
void IonSimulatorCallbackDidScanKeyboard() {
|
||||
}
|
||||
|
||||
50
ion/src/simulator/3ds/display.cpp
Normal file
50
ion/src/simulator/3ds/display.cpp
Normal file
@@ -0,0 +1,50 @@
|
||||
#include "display.h"
|
||||
#include "framebuffer.h"
|
||||
#include <assert.h>
|
||||
#include <ion/display.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "keyboard.h"
|
||||
|
||||
namespace Ion {
|
||||
namespace Simulator {
|
||||
namespace Display {
|
||||
|
||||
void* pixels;
|
||||
|
||||
void init() {
|
||||
// gfxSetScreenFormat(GFX_TOP, GSP_BGR8_OES);
|
||||
// gfxSetScreenFormat(GFX_BOTTOM, GSP_BGR8_OES);
|
||||
gfxSetDoubleBuffering(GFX_BOTTOM, false);
|
||||
pixels = nullptr;
|
||||
}
|
||||
|
||||
void quit() {
|
||||
pixels = nullptr;
|
||||
}
|
||||
|
||||
void draw() {
|
||||
pixels = gfxGetFramebuffer(GFX_TOP, GFX_LEFT, NULL, NULL);
|
||||
|
||||
|
||||
for(int i = 0; i < Ion::Display::Width; i++) {
|
||||
for(int j = 0; j < Ion::Display::Height; j++) {
|
||||
u32 pixel = 239*3 - j*3 + i*3*240 + 3*240*40;
|
||||
((u8*)pixels)[pixel + 0] = Framebuffer::address()[i + j * Ion::Display::Width].blue();
|
||||
((u8*)pixels)[pixel + 1] = Framebuffer::address()[i + j * Ion::Display::Width].green();
|
||||
((u8*)pixels)[pixel + 2] = Framebuffer::address()[i + j * Ion::Display::Width].red();
|
||||
}
|
||||
}
|
||||
|
||||
u8* fb = gfxGetFramebuffer(GFX_BOTTOM, GFX_LEFT, NULL, NULL);
|
||||
memcpy(fb, keyboard_bgr, keyboard_bgr_len);
|
||||
|
||||
gfxFlushBuffers();
|
||||
gfxSwapBuffers();
|
||||
|
||||
gspWaitForVBlank();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
20
ion/src/simulator/3ds/display.h
Normal file
20
ion/src/simulator/3ds/display.h
Normal file
@@ -0,0 +1,20 @@
|
||||
#ifndef ION_SIMULATOR_DISPLAY_H
|
||||
#define ION_SIMULATOR_DISPLAY_H
|
||||
|
||||
#include <kandinsky.h>
|
||||
#include <3ds.h>
|
||||
|
||||
namespace Ion {
|
||||
namespace Simulator {
|
||||
namespace Display {
|
||||
|
||||
void init();
|
||||
void quit();
|
||||
|
||||
void draw();
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
15
ion/src/simulator/3ds/driver/battery.cpp
Normal file
15
ion/src/simulator/3ds/driver/battery.cpp
Normal file
@@ -0,0 +1,15 @@
|
||||
#include <ion/battery.h>
|
||||
|
||||
#include "common.h"
|
||||
|
||||
bool Ion::Battery::isCharging() {
|
||||
return Ion::Simulator::CommonDriver::isCharging();
|
||||
}
|
||||
|
||||
Ion::Battery::Charge Ion::Battery::level() {
|
||||
return Ion::Simulator::CommonDriver::getLevel();
|
||||
}
|
||||
|
||||
float Ion::Battery::voltage() {
|
||||
return 0.0f;
|
||||
}
|
||||
88
ion/src/simulator/3ds/driver/common.cpp
Normal file
88
ion/src/simulator/3ds/driver/common.cpp
Normal file
@@ -0,0 +1,88 @@
|
||||
#include <3ds.h>
|
||||
#include <string.h>
|
||||
#include "common.h"
|
||||
|
||||
static bool plugged = false;
|
||||
static bool battery_charging = false;
|
||||
static Ion::Battery::Charge battery_level = Ion::Battery::Charge::FULL;
|
||||
static time_t last_pull = 0;
|
||||
|
||||
static Handle ptmsysmHandle = 0;
|
||||
|
||||
static Result common_ptmsysmInit() {
|
||||
return srvGetServiceHandle(&ptmsysmHandle, "ptm:sysm");
|
||||
}
|
||||
|
||||
static Result common_ptmsysmExit() {
|
||||
return svcCloseHandle(ptmsysmHandle);
|
||||
}
|
||||
|
||||
Result Ion::Simulator::CommonDriver::common_ptmsysmSetInfoLedPattern(RGBLedPattern pattern) {
|
||||
if (ptmsysmHandle == 0)
|
||||
return -1;
|
||||
|
||||
u32* ipc = getThreadCommandBuffer();
|
||||
ipc[0] = 0x8010640;
|
||||
memcpy(&ipc[1], &pattern, 0x64);
|
||||
Result ret = svcSendSyncRequest(ptmsysmHandle);
|
||||
if(ret < 0) return ret;
|
||||
return ipc[1];
|
||||
}
|
||||
|
||||
void Ion::Simulator::CommonDriver::init() {
|
||||
common_ptmsysmInit();
|
||||
}
|
||||
|
||||
void Ion::Simulator::CommonDriver::deinit() {
|
||||
common_ptmsysmExit();
|
||||
}
|
||||
|
||||
bool Ion::Simulator::CommonDriver::isPlugged() {
|
||||
pullData();
|
||||
return plugged;
|
||||
}
|
||||
|
||||
bool Ion::Simulator::CommonDriver::isCharging() {
|
||||
pullData();
|
||||
return battery_charging;
|
||||
}
|
||||
|
||||
Ion::Battery::Charge Ion::Simulator::CommonDriver::getLevel() {
|
||||
pullData();
|
||||
return battery_level;
|
||||
}
|
||||
|
||||
void Ion::Simulator::CommonDriver::pullData() {
|
||||
time_t current = time(NULL);
|
||||
|
||||
if (difftime(current, last_pull) >= PULL_DELAY) {
|
||||
PTMU_GetAdapterState(&plugged);
|
||||
|
||||
u8 bat_level = 0;
|
||||
PTMU_GetBatteryLevel(&bat_level);
|
||||
|
||||
switch(bat_level) {
|
||||
case 5:
|
||||
battery_level = Ion::Battery::Charge::FULL;
|
||||
break;
|
||||
case 4:
|
||||
case 3:
|
||||
battery_level = Ion::Battery::Charge::SOMEWHERE_INBETWEEN;
|
||||
break;
|
||||
case 2:
|
||||
case 1:
|
||||
battery_level = Ion::Battery::Charge::LOW;
|
||||
break;
|
||||
case 0:
|
||||
default:
|
||||
battery_level = Ion::Battery::Charge::EMPTY;
|
||||
break;
|
||||
}
|
||||
|
||||
u8 bat_charging = 0;
|
||||
PTMU_GetBatteryChargeState(&bat_charging);
|
||||
battery_charging = (bool) bat_charging;
|
||||
last_pull = time(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
33
ion/src/simulator/3ds/driver/common.h
Normal file
33
ion/src/simulator/3ds/driver/common.h
Normal file
@@ -0,0 +1,33 @@
|
||||
#ifndef ION_DRIVER_COMMON_H
|
||||
#define ION_DRIVER_COMMON_H
|
||||
|
||||
#include <ion/battery.h>
|
||||
#include <time.h>
|
||||
#include <3ds.h>
|
||||
|
||||
#define PULL_DELAY 1.0f
|
||||
|
||||
typedef struct {
|
||||
u32 ani;
|
||||
u8 r[32];
|
||||
u8 g[32];
|
||||
u8 b[32];
|
||||
} RGBLedPattern;
|
||||
|
||||
namespace Ion {
|
||||
namespace Simulator {
|
||||
namespace CommonDriver {
|
||||
|
||||
void init();
|
||||
void deinit();
|
||||
void pullData();
|
||||
bool isPlugged();
|
||||
bool isCharging();
|
||||
Ion::Battery::Charge getLevel();
|
||||
Result common_ptmsysmSetInfoLedPattern(RGBLedPattern pattern);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
19
ion/src/simulator/3ds/driver/display.cpp
Normal file
19
ion/src/simulator/3ds/driver/display.cpp
Normal file
@@ -0,0 +1,19 @@
|
||||
#include <ion/display.h>
|
||||
|
||||
#include <3ds.h>
|
||||
|
||||
void Ion::Display::POSTPushMulticolor(int rootNumberTiles, int tileSize) {
|
||||
}
|
||||
|
||||
int Ion::Display::displayUniformTilingSize10(KDColor c) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Ion::Display::displayColoredTilingSize10() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool Ion::Display::waitForVBlank() {
|
||||
gspWaitForVBlank();
|
||||
return true;
|
||||
}
|
||||
25
ion/src/simulator/3ds/driver/language.cpp
Normal file
25
ion/src/simulator/3ds/driver/language.cpp
Normal file
@@ -0,0 +1,25 @@
|
||||
#include "../platform.h"
|
||||
|
||||
#include <3ds.h>
|
||||
|
||||
const char* IonSimulatorGetLanguageCode() {
|
||||
u8 lang = 0;
|
||||
|
||||
CFGU_GetSystemLanguage(&lang);
|
||||
|
||||
switch(lang) {
|
||||
case CFG_LANGUAGE_FR:
|
||||
return "fr";
|
||||
case CFG_LANGUAGE_ES:
|
||||
return "es";
|
||||
case CFG_LANGUAGE_DE:
|
||||
return "de";
|
||||
case CFG_LANGUAGE_PT:
|
||||
return "pt";
|
||||
|
||||
// en fr es de pt hu
|
||||
default:
|
||||
return "en";
|
||||
}
|
||||
}
|
||||
|
||||
80
ion/src/simulator/3ds/driver/led.cpp
Normal file
80
ion/src/simulator/3ds/driver/led.cpp
Normal file
@@ -0,0 +1,80 @@
|
||||
#include <ion/led.h>
|
||||
#include <ion/battery.h>
|
||||
#include <ion/usb.h>
|
||||
#include <ion/exam_mode.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <3ds.h>
|
||||
#include "common.h"
|
||||
|
||||
static KDColor sLedColor = KDColorBlack;
|
||||
|
||||
namespace Ion {
|
||||
namespace LED {
|
||||
|
||||
KDColor getColor() {
|
||||
return sLedColor;
|
||||
}
|
||||
|
||||
void setColor(KDColor c) {
|
||||
sLedColor = c;
|
||||
|
||||
/*
|
||||
* According to https://www.3dbrew.org/wiki/MCURTC:SetInfoLEDPattern
|
||||
* annimation pattern is as follow
|
||||
* u8 ??? | u8 loop_delay | u8 smoothing | u8 delay
|
||||
*/
|
||||
RGBLedPattern pat;
|
||||
memset(&pat, 0, sizeof(pat));
|
||||
|
||||
for(int i = 0; i < 32; i++) {
|
||||
pat.r[i] = sLedColor.red();
|
||||
pat.g[i] = sLedColor.green();
|
||||
pat.b[i] = sLedColor.blue();
|
||||
}
|
||||
|
||||
pat.ani = 0x20;
|
||||
|
||||
Ion::Simulator::CommonDriver::common_ptmsysmSetInfoLedPattern(pat);
|
||||
}
|
||||
|
||||
void setBlinking(uint16_t period, float dutyCycle) {
|
||||
uint8_t period_3ds = (uint8_t)((float)(period)*0.016f);
|
||||
uint8_t duty_3ds = (uint8_t)(dutyCycle*32.0f);
|
||||
|
||||
/*
|
||||
* According to https://www.3dbrew.org/wiki/MCURTC:SetInfoLEDPattern
|
||||
* annimation pattern is as follow
|
||||
* u8 ??? | u8 loop_delay | u8 smoothing | u8 delay
|
||||
*
|
||||
* Se, we seet ??? to 0, loop_delay to 0 (to have it loop)
|
||||
*/
|
||||
RGBLedPattern pat;
|
||||
memset(&pat, 0, sizeof(pat));
|
||||
|
||||
for(int i = 0; i < duty_3ds && i < 32; i++) {
|
||||
pat.r[i] = (sLedColor.red() > 0) ? 255 : 0;
|
||||
pat.g[i] = (sLedColor.green() > 0) ? 255 : 0;
|
||||
pat.b[i] = (sLedColor.blue() > 0) ? 255 : 0;
|
||||
}
|
||||
|
||||
pat.ani = period_3ds;
|
||||
|
||||
Ion::Simulator::CommonDriver::common_ptmsysmSetInfoLedPattern(pat);
|
||||
}
|
||||
|
||||
KDColor updateColorWithPlugAndCharge() {
|
||||
KDColor ledColor = getColor();
|
||||
if (ExamMode::FetchExamMode() == 0) { // If exam mode is on, we do not update the LED with the plugged/charging state
|
||||
if (USB::isPlugged()) {
|
||||
ledColor = Battery::isCharging() ? KDColorOrange : KDColorGreen;
|
||||
} else {
|
||||
ledColor = KDColorBlack;
|
||||
}
|
||||
setColor(ledColor);
|
||||
}
|
||||
return ledColor;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
23
ion/src/simulator/3ds/driver/usb.cpp
Normal file
23
ion/src/simulator/3ds/driver/usb.cpp
Normal file
@@ -0,0 +1,23 @@
|
||||
#include <ion/usb.h>
|
||||
|
||||
#include "common.h"
|
||||
|
||||
bool Ion::USB::isPlugged() {
|
||||
return Ion::Simulator::CommonDriver::isPlugged();
|
||||
}
|
||||
|
||||
bool Ion::USB::isEnumerated() {
|
||||
return false;
|
||||
}
|
||||
|
||||
void Ion::USB::clearEnumerationInterrupt() {
|
||||
}
|
||||
|
||||
void Ion::USB::DFU() {
|
||||
}
|
||||
|
||||
void Ion::USB::enable() {
|
||||
}
|
||||
|
||||
void Ion::USB::disable() {
|
||||
}
|
||||
38
ion/src/simulator/3ds/events_keyboard.cpp
Normal file
38
ion/src/simulator/3ds/events_keyboard.cpp
Normal file
@@ -0,0 +1,38 @@
|
||||
#include "main.h"
|
||||
#include "platform.h"
|
||||
#include "driver/common.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <ion/events.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <3ds.h>
|
||||
|
||||
static bool was_plugged = false;
|
||||
|
||||
namespace Ion {
|
||||
namespace Events {
|
||||
|
||||
|
||||
Event getPlatformEvent() {
|
||||
Event result = None;
|
||||
|
||||
if (Ion::Simulator::CommonDriver::isPlugged() && !was_plugged) {
|
||||
was_plugged = true;
|
||||
return USBPlug;
|
||||
}
|
||||
|
||||
if (!Ion::Simulator::CommonDriver::isPlugged() && was_plugged) {
|
||||
was_plugged = false;
|
||||
}
|
||||
|
||||
|
||||
if (!aptMainLoop()) {
|
||||
result = Termination;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
50
ion/src/simulator/3ds/framebuffer.cpp
Normal file
50
ion/src/simulator/3ds/framebuffer.cpp
Normal file
@@ -0,0 +1,50 @@
|
||||
#include "framebuffer.h"
|
||||
#include <ion/display.h>
|
||||
#include "main.h"
|
||||
|
||||
static KDColor sPixels[Ion::Display::Width * Ion::Display::Height];
|
||||
static bool sFrameBufferActive = true;
|
||||
|
||||
namespace Ion {
|
||||
namespace Display {
|
||||
|
||||
static KDFrameBuffer sFrameBuffer = KDFrameBuffer(sPixels, KDSize(Ion::Display::Width, Ion::Display::Height));
|
||||
|
||||
void pushRect(KDRect r, const KDColor * pixels) {
|
||||
if (sFrameBufferActive) {
|
||||
Simulator::Main::setNeedsRefresh();
|
||||
sFrameBuffer.pushRect(r, pixels);
|
||||
}
|
||||
}
|
||||
|
||||
void pushRectUniform(KDRect r, KDColor c) {
|
||||
if (sFrameBufferActive) {
|
||||
Simulator::Main::setNeedsRefresh();
|
||||
sFrameBuffer.pushRectUniform(r, c);
|
||||
}
|
||||
}
|
||||
|
||||
void pullRect(KDRect r, KDColor * pixels) {
|
||||
if (sFrameBufferActive) {
|
||||
sFrameBuffer.pullRect(r, pixels);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
namespace Ion {
|
||||
namespace Simulator {
|
||||
namespace Framebuffer {
|
||||
|
||||
const KDColor * address() {
|
||||
return sPixels;
|
||||
}
|
||||
|
||||
void setActive(bool enabled) {
|
||||
sFrameBufferActive = enabled;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
18
ion/src/simulator/3ds/framebuffer.h
Normal file
18
ion/src/simulator/3ds/framebuffer.h
Normal file
@@ -0,0 +1,18 @@
|
||||
#ifndef ION_SIMULATOR_FRAMEBUFFER_H
|
||||
#define ION_SIMULATOR_FRAMEBUFFER_H
|
||||
|
||||
#include <kandinsky.h>
|
||||
|
||||
namespace Ion {
|
||||
namespace Simulator {
|
||||
namespace Framebuffer {
|
||||
|
||||
const KDColor * address();
|
||||
void setActive(bool enabled);
|
||||
void writeToFile(const char * filename);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
142
ion/src/simulator/3ds/keyboard.cpp
Normal file
142
ion/src/simulator/3ds/keyboard.cpp
Normal file
@@ -0,0 +1,142 @@
|
||||
#include <ion/keyboard.h>
|
||||
#include "platform.h"
|
||||
#include "main.h"
|
||||
|
||||
#include <3ds.h>
|
||||
#include <stdio.h>
|
||||
|
||||
void IonSimulatorKeyboardKeyDown(int keyNumber) {
|
||||
}
|
||||
|
||||
void IonSimulatorKeyboardKeyUp(int keyNumber) {
|
||||
}
|
||||
|
||||
#define DETECT_KEY(x1, y1, w, h, key) \
|
||||
if (touch.px >= (x1) && touch.py >= (y1) && touch.px <= ((x1) + (w) - 1) && touch.py <= ((y1) + (h) - 1)) state.setKey(key);
|
||||
|
||||
namespace Ion {
|
||||
namespace Keyboard {
|
||||
|
||||
bool m_heldLastFrame = false;
|
||||
|
||||
State scan() {
|
||||
Simulator::Main::refresh();
|
||||
|
||||
hidScanInput();
|
||||
touchPosition touch;
|
||||
hidTouchRead(&touch);
|
||||
|
||||
State state;
|
||||
|
||||
|
||||
if (touch.px == 0 && touch.py == 0) {
|
||||
if (m_heldLastFrame) {
|
||||
m_heldLastFrame = false;
|
||||
}
|
||||
|
||||
} else {
|
||||
if (!m_heldLastFrame) {
|
||||
m_heldLastFrame = true;
|
||||
|
||||
DETECT_KEY(271, 13 , 31, 31, Key::OK)
|
||||
DETECT_KEY(271, 46 , 31, 31, Key::Back)
|
||||
DETECT_KEY(227, 16 , 37, 25, Key::Home)
|
||||
DETECT_KEY(227, 48 , 37, 25, Key::OnOff)
|
||||
|
||||
DETECT_KEY(174, 9 , 22, 23, Key::Up)
|
||||
DETECT_KEY(174, 54 , 22, 23, Key::Down)
|
||||
DETECT_KEY(151, 32 , 23, 22, Key::Left)
|
||||
DETECT_KEY(196, 32 , 23, 22, Key::Right)
|
||||
|
||||
|
||||
DETECT_KEY(3 , 30 , 41, 27, Key::LeftParenthesis)
|
||||
DETECT_KEY(52 , 30 , 41, 27, Key::RightParenthesis)
|
||||
DETECT_KEY(101, 30 , 41, 27, Key::Plus)
|
||||
|
||||
DETECT_KEY(3 , 66 , 41, 27, Key::Multiplication)
|
||||
DETECT_KEY(52 , 66 , 41, 27, Key::Division)
|
||||
DETECT_KEY(101, 66 , 41, 27, Key::Minus)
|
||||
|
||||
DETECT_KEY(3 , 102, 41, 27, Key::Seven)
|
||||
DETECT_KEY(52 , 102, 41, 27, Key::Eight)
|
||||
DETECT_KEY(101, 102, 41, 27, Key::Nine)
|
||||
|
||||
DETECT_KEY(3 , 138, 41, 27, Key::Four)
|
||||
DETECT_KEY(52 , 138, 41, 27, Key::Five)
|
||||
DETECT_KEY(101, 138, 41, 27, Key::Six)
|
||||
|
||||
DETECT_KEY(3 , 174, 41, 27, Key::One)
|
||||
DETECT_KEY(52 , 174, 41, 27, Key::Two)
|
||||
DETECT_KEY(101, 174, 41, 27, Key::Three)
|
||||
|
||||
DETECT_KEY(3 , 210, 41, 27, Key::Zero)
|
||||
DETECT_KEY(52 , 210, 41, 27, Key::Dot)
|
||||
DETECT_KEY(101, 210, 41, 27, Key::EE)
|
||||
DETECT_KEY(150, 210, 41, 27, Key::Ans)
|
||||
DETECT_KEY(199, 210, 41, 27, Key::EXE)
|
||||
|
||||
|
||||
DETECT_KEY(149, 82 , 34, 23, Key::Sqrt)
|
||||
DETECT_KEY(189, 82 , 34, 23, Key::Square)
|
||||
DETECT_KEY(229, 82 , 34, 23, Key::Comma)
|
||||
DETECT_KEY(269, 82 , 34, 23, Key::Power)
|
||||
|
||||
DETECT_KEY(149, 114, 34, 23, Key::Shift)
|
||||
DETECT_KEY(189, 114, 34, 23, Key::Alpha)
|
||||
DETECT_KEY(229, 114, 34, 23, Key::XNT)
|
||||
DETECT_KEY(269, 114, 34, 23, Key::Var)
|
||||
|
||||
DETECT_KEY(149, 146, 34, 23, Key::Exp)
|
||||
DETECT_KEY(189, 146, 34, 23, Key::Ln)
|
||||
DETECT_KEY(229, 146, 34, 23, Key::Log)
|
||||
DETECT_KEY(269, 146, 34, 23, Key::Imaginary)
|
||||
|
||||
DETECT_KEY(149, 178, 34, 23, Key::Sine)
|
||||
DETECT_KEY(189, 178, 34, 23, Key::Cosine)
|
||||
DETECT_KEY(229, 178, 34, 23, Key::Tangent)
|
||||
DETECT_KEY(269, 178, 34, 23, Key::Pi)
|
||||
|
||||
|
||||
DETECT_KEY(245, 212, 34, 23, Key::Toolbox)
|
||||
DETECT_KEY(285, 212, 34, 23, Key::Backspace)
|
||||
}
|
||||
}
|
||||
|
||||
u32 kDown = hidKeysDown();
|
||||
|
||||
if (kDown & KEY_DUP) {
|
||||
state.setKey(Key::Up);
|
||||
}
|
||||
if (kDown & KEY_DDOWN) {
|
||||
state.setKey(Key::Down);
|
||||
}
|
||||
if (kDown & KEY_DLEFT) {
|
||||
state.setKey(Key::Left);
|
||||
}
|
||||
if (kDown & KEY_DRIGHT) {
|
||||
state.setKey(Key::Right);
|
||||
}
|
||||
if (kDown & KEY_A) {
|
||||
state.setKey(Key::OK);
|
||||
}
|
||||
if (kDown & KEY_B) {
|
||||
state.setKey(Key::Back);
|
||||
}
|
||||
if (kDown & KEY_Y) {
|
||||
state.setKey(Key::Shift);
|
||||
}
|
||||
if (kDown & KEY_X) {
|
||||
state.setKey(Key::Alpha);
|
||||
}
|
||||
if (kDown & KEY_START) {
|
||||
state.setKey(Key::Home);
|
||||
}
|
||||
if (kDown & KEY_SELECT) {
|
||||
state.setKey(Key::OnOff);
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
19203
ion/src/simulator/3ds/keyboard.h
Normal file
19203
ion/src/simulator/3ds/keyboard.h
Normal file
File diff suppressed because it is too large
Load Diff
101
ion/src/simulator/3ds/main.cpp
Normal file
101
ion/src/simulator/3ds/main.cpp
Normal file
@@ -0,0 +1,101 @@
|
||||
#include "main.h"
|
||||
#include "display.h"
|
||||
#include "platform.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <vector>
|
||||
|
||||
#include <ion.h>
|
||||
#include <ion/timing.h>
|
||||
#include <ion/events.h>
|
||||
|
||||
#include <3ds.h>
|
||||
|
||||
#include "driver/common.h"
|
||||
|
||||
void Ion::Timing::msleep(uint32_t ms) {
|
||||
svcSleepThread((s64) ms * 1000);
|
||||
}
|
||||
|
||||
int main(int argc, char * argv[]) {
|
||||
Ion::Simulator::Main::init();
|
||||
|
||||
std::vector<const char *> arguments(argv, argv + argc);
|
||||
|
||||
const char * language = IonSimulatorGetLanguageCode();
|
||||
if (language != nullptr) {
|
||||
arguments.push_back("--language");
|
||||
arguments.push_back(language);
|
||||
}
|
||||
|
||||
ion_main(arguments.size(), &arguments[0]);
|
||||
Ion::Simulator::Main::quit();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
namespace Ion {
|
||||
namespace Simulator {
|
||||
namespace Main {
|
||||
|
||||
static bool sNeedsRefresh = false;
|
||||
|
||||
void init() {
|
||||
gfxInitDefault();
|
||||
cfguInit();
|
||||
Ion::Simulator::CommonDriver::init();
|
||||
// mcuHwcInit();
|
||||
ptmuInit();
|
||||
relayout();
|
||||
}
|
||||
|
||||
void relayout() {
|
||||
int windowWidth = 800;
|
||||
int windowHeight = 240;
|
||||
|
||||
// Keep original aspect ration in screen_only mode.
|
||||
/*
|
||||
float scale = (float)(Ion::Display::Width) / (float)(Ion::Display::Height);
|
||||
if ((float)(windowHeight) * scale > float(windowWidth)) {
|
||||
sScreenRect.w = windowWidth;
|
||||
sScreenRect.h = (int)((float)(windowWidth) / scale);
|
||||
} else {
|
||||
sScreenRect.w = (int)((float)(windowHeight) * scale);
|
||||
sScreenRect.h = windowHeight;
|
||||
}
|
||||
|
||||
sScreenRect.x = (windowWidth - sScreenRect.w) / 2;
|
||||
sScreenRect.y = (windowHeight - sScreenRect.h) / 2;
|
||||
*/
|
||||
|
||||
setNeedsRefresh();
|
||||
}
|
||||
|
||||
void setNeedsRefresh() {
|
||||
sNeedsRefresh = true;
|
||||
}
|
||||
|
||||
void refresh() {
|
||||
if (!sNeedsRefresh) {
|
||||
return;
|
||||
}
|
||||
|
||||
Display::draw();
|
||||
|
||||
sNeedsRefresh = false;
|
||||
}
|
||||
|
||||
void quit() {
|
||||
// mcuHwcExit();
|
||||
ptmuExit();
|
||||
cfguExit();
|
||||
Ion::Simulator::CommonDriver::deinit();
|
||||
gfxExit();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
19
ion/src/simulator/3ds/main.h
Normal file
19
ion/src/simulator/3ds/main.h
Normal file
@@ -0,0 +1,19 @@
|
||||
#ifndef ION_SIMULATOR_MAIN_H
|
||||
#define ION_SIMULATOR_MAIN_H
|
||||
|
||||
namespace Ion {
|
||||
namespace Simulator {
|
||||
namespace Main {
|
||||
|
||||
void init();
|
||||
void quit();
|
||||
|
||||
void setNeedsRefresh();
|
||||
void refresh();
|
||||
void relayout();
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
23
ion/src/simulator/3ds/platform.h
Normal file
23
ion/src/simulator/3ds/platform.h
Normal file
@@ -0,0 +1,23 @@
|
||||
#ifndef ION_SIMULATOR_PLATFORM_H
|
||||
#define ION_SIMULATOR_PLATFORM_H
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Those functions should be implemented per-platform.
|
||||
* They are defined as C function for easier interop. */
|
||||
|
||||
const char * IonSimulatorGetLanguageCode();
|
||||
|
||||
void IonSimulatorKeyboardKeyDown(int keyNumber);
|
||||
void IonSimulatorKeyboardKeyUp(int keyNumber);
|
||||
void IonSimulatorEventsPushEvent(int eventNumber);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
15
ion/src/simulator/3ds/telemetry_init.cpp
Normal file
15
ion/src/simulator/3ds/telemetry_init.cpp
Normal file
@@ -0,0 +1,15 @@
|
||||
#include "platform.h"
|
||||
|
||||
namespace Ion {
|
||||
namespace Simulator {
|
||||
namespace Telemetry {
|
||||
|
||||
void init() {
|
||||
}
|
||||
|
||||
void shutdown() {
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
4
ion/src/simulator/external/config.3ds.mak
vendored
Normal file
4
ion/src/simulator/external/config.3ds.mak
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
|
||||
undefine sdl_src
|
||||
undefine ion_simulator_sdl_src
|
||||
|
||||
@@ -13,11 +13,19 @@ class LayoutNode;
|
||||
class Integer;
|
||||
struct IntegerDivision;
|
||||
|
||||
#ifdef _3DS
|
||||
typedef unsigned short half_native_uint_t;
|
||||
typedef int native_int_t;
|
||||
typedef long long int double_native_int_t;
|
||||
typedef unsigned int native_uint_t;
|
||||
typedef unsigned long long int double_native_uint_t;
|
||||
#else
|
||||
typedef uint16_t half_native_uint_t;
|
||||
typedef int32_t native_int_t;
|
||||
typedef int64_t double_native_int_t;
|
||||
typedef uint32_t native_uint_t;
|
||||
typedef uint64_t double_native_uint_t;
|
||||
#endif
|
||||
|
||||
static_assert(sizeof(double_native_int_t) <= sizeof(double_native_uint_t), "double_native_int_t type has not the right size compared to double_native_uint_t");
|
||||
static_assert(sizeof(native_int_t) == sizeof(native_uint_t), "native_int_t type has not the right size compared to native_uint_t");
|
||||
|
||||
Reference in New Issue
Block a user