Merge pull request #332 from M4xi1m3/omega-3ds-dev

[Feature] Port Omega to the 3DS
This commit is contained in:
Quentin
2020-06-12 23:00:28 +02:00
committed by GitHub
27 changed files with 20100 additions and 0 deletions

1
.gitignore vendored
View File

@@ -2,6 +2,7 @@
/build/artifacts/
build/device/**/*.pyc
epsilon.elf
epsilon.map
.vscode
.DS_Store
.gradle

View File

@@ -0,0 +1,5 @@
TOOLCHAIN = devkitarm
EXE = elf
HANDY_TARGETS_EXTENSIONS = 3dsx

View 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,$^)

View 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

View 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))

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

View File

@@ -0,0 +1,8 @@
#include "platform.h"
void IonSimulatorCallbackDidRefresh() {
}
void IonSimulatorCallbackDidScanKeyboard() {
}

View 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();
}
}
}
}

View 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

View 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;
}

View 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);
}
}

View 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

View 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;
}

View 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";
}
}

View 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;
}
}
}

View 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() {
}

View 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;
}
}
}

View 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;
}
}
}
}

View 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

View 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;
}
}
}

File diff suppressed because it is too large Load Diff

View 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();
}
}
}
}

View 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

View 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

View File

@@ -0,0 +1,15 @@
#include "platform.h"
namespace Ion {
namespace Simulator {
namespace Telemetry {
void init() {
}
void shutdown() {
}
}
}
}

View File

@@ -0,0 +1,4 @@
undefine sdl_src
undefine ion_simulator_sdl_src

View File

@@ -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");