mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-01-18 16:27:34 +01:00
[build] Clean the different targets
This commit is contained in:
@@ -20,7 +20,9 @@ app_src += $(addprefix apps/,\
|
||||
empty_battery_window.cpp \
|
||||
exam_pop_up_controller.cpp \
|
||||
global_preferences.cpp \
|
||||
i18n.py \
|
||||
lock_view.cpp \
|
||||
main.cpp \
|
||||
math_toolbox.cpp \
|
||||
shift_alpha_lock_view.cpp \
|
||||
suspend_timer.cpp \
|
||||
@@ -83,18 +85,14 @@ $(BUILD_DIR)/apps/i18n.h: $(BUILD_DIR)/apps/i18n.cpp
|
||||
|
||||
$(eval $(call depends_on_image,apps/title_bar_view.cpp,apps/exam_icon.png))
|
||||
|
||||
# Handle epsilon-only sources
|
||||
# Other executables may want to do their own i18n and main. That's the case for
|
||||
# the test runner. Let's add those files to a specific epsilon-only src. When
|
||||
# building apps/i18n.o, the extension doesn't really matter since it'll be
|
||||
# processed by the object_for function.
|
||||
|
||||
epsilon_src += $(addprefix apps/, \
|
||||
main.cpp \
|
||||
i18n.py \
|
||||
)
|
||||
|
||||
all_app_src = $(app_src) $(epsilon_src) $(apps_launch_on_boarding_src) $(apps_launch_default_src) $(apps_prompt_none_src) $(apps_container_prompt_update) $(apps_prompt_beta_src) $(tests_src)
|
||||
|
||||
$(call object_for,$(all_app_src)): $(BUILD_DIR)/apps/i18n.h
|
||||
$(call object_for,$(all_app_src)): $(BUILD_DIR)/python/port/genhdr/qstrdefs.generated.h
|
||||
|
||||
apps_tests_src = $(app_calculation_test_src) $(app_probability_test_src) $(app_regression_test_src) $(app_sequence_test_src) $(app_shared_test_src) $(app_statistics_test_src) $(app_solver_test_src)
|
||||
|
||||
apps_default_src = $(app_src) $(apps_launch_default_src) $(apps_prompt_none_src);
|
||||
apps_onboarding_src = $(app_src) $(apps_launch_on_boarding_src) $(apps_prompt_none_src);
|
||||
apps_onboarding_update_src = $(app_src) $(apps_launch_on_boarding_src) $(apps_prompt_update_src);
|
||||
apps_onboarding_beta_src = $(app_src) $(apps_launch_on_boarding_src) $(apps_prompt_beta_src);
|
||||
|
||||
@@ -49,17 +49,17 @@ openocd:
|
||||
# fully filled
|
||||
$(BUILD_DIR)/flasher.%.$(EXE): LDFLAGS += -Lion/src/$(PLATFORM)/flasher
|
||||
$(BUILD_DIR)/flasher.%.$(EXE): LDSCRIPT = ion/src/$(PLATFORM)/shared/ram.ld
|
||||
flasher_objs = $(call object_for,$(ion_src) $(liba_src) $(kandinsky_src) $(flasher_src) $(ion_device_dfu_xip_src))
|
||||
$(BUILD_DIR)/flasher.light.$(EXE): $(BUILD_DIR)/ion/src/$(PLATFORM)/flasher/display_light.o $(flasher_objs)
|
||||
$(BUILD_DIR)/flasher.verbose.$(EXE): $(BUILD_DIR)/ion/src/$(PLATFORM)/flasher/display_verbose.o $(flasher_objs)
|
||||
flasher_base_src = $(ion_xip_src) $(liba_src) $(kandinsky_src)
|
||||
$(BUILD_DIR)/flasher.light.$(EXE): $(call object_for,$(flasher_base_src) $(ion_target_device_flasher_light_src))
|
||||
$(BUILD_DIR)/flasher.verbose.$(EXE): $(call object_for,$(flasher_base_src) $(ion_target_device_flasher_verbose_src))
|
||||
|
||||
#TODO Do not build all apps... Put elsewhere?
|
||||
$(BUILD_DIR)/bench.ram.$(EXE): LDFLAGS += -Lion/src/$(PLATFORM)/bench
|
||||
$(BUILD_DIR)/bench.ram.$(EXE): LDSCRIPT = ion/src/$(PLATFORM)/shared/ram.ld
|
||||
$(BUILD_DIR)/bench.flash.$(EXE): LDSCRIPT = ion/src/$(PLATFORM)/$(MODEL)/internal_flash.ld
|
||||
bench_objs = $(call object_for,$(ion_src) $(liba_src) $(kandinsky_src) $(ion_device_dfu_xip_src) $(poincare_src) $(libaxx_src) $(bench_src) $(app_shared_src))
|
||||
$(BUILD_DIR)/bench.ram.$(EXE): $(bench_objs)
|
||||
$(BUILD_DIR)/bench.flash.$(EXE): $(bench_objs)
|
||||
bench_src = $(ion_xip_src) $(liba_src) $(kandinsky_src) $(poincare_src) $(libaxx_src) $(app_shared_src) $(ion_target_device_bench_src)
|
||||
$(BUILD_DIR)/bench.ram.$(EXE): $(call object_for,$(bench_src))
|
||||
$(BUILD_DIR)/bench.flash.$(EXE): $(call object_for,$(bench_src))
|
||||
|
||||
.PHONY: %.two_binaries
|
||||
%.two_binaries: %.elf
|
||||
|
||||
@@ -1,13 +1,20 @@
|
||||
# Define standard Epsilon targets
|
||||
all_epsilon_common_src = $(ion_src) $(liba_src) $(kandinsky_src) $(epsilon_src) $(app_src) $(escher_src) $(libaxx_src) $(poincare_src) $(python_src) $(ion_device_dfu_relocated_src)
|
||||
all_epsilon_default_src = $(all_epsilon_common_src) $(apps_launch_default_src) $(apps_prompt_none_src)
|
||||
base_src = $(liba_src) $(kandinsky_src) $(escher_src) $(libaxx_src) $(poincare_src) $(python_src)
|
||||
|
||||
$(BUILD_DIR)/epsilon.$(EXE): $(call object_for,$(all_epsilon_default_src))
|
||||
$(BUILD_DIR)/epsilon.on-boarding.$(EXE): $(call object_for,$(all_epsilon_common_src) $(apps_launch_on_boarding_src) $(apps_prompt_none_src))
|
||||
$(BUILD_DIR)/epsilon.on-boarding.update.$(EXE): $(call object_for,$(all_epsilon_common_src) $(apps_launch_on_boarding_src) $(apps_prompt_update_src))
|
||||
$(BUILD_DIR)/epsilon.on-boarding.beta.$(EXE): $(call object_for,$(all_epsilon_common_src) $(apps_launch_on_boarding_src) $(apps_prompt_beta_src))
|
||||
epsilon_src = $(base_src) $(ion_default_src) $(apps_default_src)
|
||||
epsilon_onboarding_src = $(base_src) $(ion_default_src) $(apps_onboarding_src)
|
||||
epsilon_onboarding_update_src = $(base_src) $(ion_default_src) $(apps_onboarding_update_src)
|
||||
epsilon_onboarding_beta_src = $(base_src) $(ion_default_src) $(apps_onboarding_beta_src)
|
||||
|
||||
$(BUILD_DIR)/test.$(EXE): $(BUILD_DIR)/quiz/src/tests_symbols.o $(call object_for,$(ion_src) $(liba_src) $(kandinsky_src) $(escher_src) $(libaxx_src) $(poincare_src) $(python_src) $(ion_device_dfu_relocated_src) $(tests_src) $(runner_src) $(app_calculation_test_src) $(app_probability_test_src) $(app_regression_test_src) $(app_sequence_test_src) $(app_shared_test_src) $(app_statistics_test_src) $(app_solver_test_src))
|
||||
$(BUILD_DIR)/epsilon.$(EXE): $(call object_for,$(epsilon_src))
|
||||
$(BUILD_DIR)/epsilon.onboarding.$(EXE): $(call object_for,$(epsilon_onboarding_src))
|
||||
$(BUILD_DIR)/epsilon.onboarding.update.$(EXE): $(call object_for,$(epsilon_onboarding_update_src))
|
||||
$(BUILD_DIR)/epsilon.onboarding.beta.$(EXE): $(call object_for,$(epsilon_onboarding_beta_src))
|
||||
|
||||
test_base_src = $(base_src) $(apps_tests_src) $(runner_src) $(tests_src)
|
||||
|
||||
test_runner_src = $(test_base_src) $(ion_default_src)
|
||||
$(BUILD_DIR)/test.$(EXE): $(call object_for,$(test_runner_src))
|
||||
|
||||
# Define handy targets
|
||||
# Those can be built easily by simply invoking "make target.ext". The named file
|
||||
|
||||
@@ -1,14 +1,12 @@
|
||||
$(BUILD_DIR)/epsilon.packed.js: LDFLAGS += --memory-init-file 0
|
||||
$(BUILD_DIR)/epsilon.packed.js: $(call object_for,$(all_epsilon_default_src))
|
||||
# Headless targets
|
||||
epsilon_headless_src = $(base_src) $(ion_headless_src) $(apps_default_src)
|
||||
$(BUILD_DIR)/epsilon.headless.$(EXE): $(call object_for,$(epsilon_headless_src))
|
||||
$(BUILD_DIR)/epsilon.headless.$(EXE): LDFLAGS += `libpng-config --ldflags`
|
||||
|
||||
.PHONY: workshop_python_emulator
|
||||
workshop_python_emulator:
|
||||
make PLATFORM=simulator TARGET=web clean_for_apps_selection
|
||||
make PLATFORM=simulator TARGET=web EPSILON_APPS=code
|
||||
make PLATFORM=simulator TARGET=web clean_for_apps_selection
|
||||
test_runner_headless_src = $(test_base_src) $(ion_headless_src)
|
||||
$(BUILD_DIR)/test.headless.$(EXE): $(call object_for,$(test_runner_headless_src))
|
||||
$(BUILD_DIR)/test.headless.$(EXE): LDFLAGS += `libpng-config --ldflags`
|
||||
|
||||
.PHONY: clean_for_apps_selection
|
||||
clean_for_apps_selection:
|
||||
@echo "CLEAN BEFORE CHANGING EPSILON_APPS"
|
||||
$(Q) rm -f $(BUILD_DIR)/apps/apps_container_storage.o
|
||||
$(Q) rm -f $(BUILD_DIR)/apps/i18n.*
|
||||
HANDY_TARGETS += epsilon.headless test.headless
|
||||
|
||||
-include build/targets.simulator.$(TARGET).mak
|
||||
|
||||
17
build/targets.simulator.web.mak
Normal file
17
build/targets.simulator.web.mak
Normal file
@@ -0,0 +1,17 @@
|
||||
$(BUILD_DIR)/epsilon.js: EMSCRIPTEN_INIT_FILE = 1
|
||||
|
||||
$(BUILD_DIR)/test.headless.js: EMSCRIPTEN_MODULARIZE = 0
|
||||
|
||||
$(BUILD_DIR)/epsilon.packed.js: $(call object_for,$(epsilon_src))
|
||||
|
||||
.PHONY: workshop_python_emulator
|
||||
workshop_python_emulator:
|
||||
make PLATFORM=simulator TARGET=web clean_for_apps_selection
|
||||
make PLATFORM=simulator TARGET=web EPSILON_APPS=code
|
||||
make PLATFORM=simulator TARGET=web clean_for_apps_selection
|
||||
|
||||
.PHONY: clean_for_apps_selection
|
||||
clean_for_apps_selection:
|
||||
@echo "CLEAN BEFORE CHANGING EPSILON_APPS"
|
||||
$(Q) rm -f $(BUILD_DIR)/apps/apps_container_storage.o
|
||||
$(Q) rm -f $(BUILD_DIR)/apps/i18n.*
|
||||
@@ -110,7 +110,14 @@ EMFLAGS += -s SAFE_HEAP=1
|
||||
EMFLAGS += -s STACK_OVERFLOW_CHECK=1
|
||||
endif
|
||||
|
||||
EMFLAGS += -s WASM=0 -s MODULARIZE=1 -s 'EXPORT_NAME="Epsilon"'
|
||||
# Configure EMFLAGS
|
||||
EMFLAGS += -s WASM=0
|
||||
|
||||
# Configure LDFLAGS
|
||||
EMSCRIPTEN_MODULARIZE ?= 1
|
||||
LDFLAGS += -s MODULARIZE=$(EMSCRIPTEN_MODULARIZE) -s 'EXPORT_NAME="Epsilon"'
|
||||
EMSCRIPTEN_INIT_FILE ?= 0
|
||||
LDFLAGS += --memory-init-file $(EMSCRIPTEN_INIT_FILE)
|
||||
|
||||
SFLAGS += $(EMFLAGS)
|
||||
LDFLAGS += $(EMFLAGS) -Oz -s EXPORTED_FUNCTIONS='["_main", "_IonSimulatorKeyboardKeyDown", "_IonSimulatorKeyboardKeyUp", "_IonSimulatorEventsPushEvent", "_IonSoftwareVersion", "_IonPatchLevel"]' -s EXTRA_EXPORTED_RUNTIME_METHODS='["UTF8ToString"]'
|
||||
|
||||
@@ -15,6 +15,8 @@ include ion/src/$(PLATFORM)/Makefile
|
||||
-include ion/test/$(PLATFORM)/Makefile
|
||||
include ion/src/shared/tools/Makefile
|
||||
|
||||
ion_console_display_src += ion/src/shared/console_display.cpp
|
||||
|
||||
# We need to work around a GCC bug (concerning versions < 5.1). It is valid in
|
||||
# C++11 to initialize a character array by providing a string litteral (e.g.
|
||||
# char test[4]= "ab"; is valid and should initialize test to 'a','b',0,0).
|
||||
@@ -23,6 +25,7 @@ initializer_list = $(shell echo $(1) | sed "s/\(.\)/'\1',/g")0
|
||||
$(call object_for,ion/src/shared/platform_info.cpp): SFLAGS += -DPATCH_LEVEL="$(call initializer_list,$(PATCH_LEVEL))" -DEPSILON_VERSION="$(call initializer_list,$(EPSILON_VERSION))"
|
||||
|
||||
ion_src += $(addprefix ion/src/shared/, \
|
||||
console_line.cpp \
|
||||
crc32_eat_byte.cpp \
|
||||
decompress.cpp \
|
||||
events.cpp \
|
||||
@@ -46,3 +49,7 @@ tests_src += $(addprefix ion/test/,\
|
||||
ifdef ION_STORAGE_LOG
|
||||
SFLAGS += -DION_STORAGE_LOG=1
|
||||
endif
|
||||
|
||||
ion_default_src = $(ion_src) $(ion_simulator_sdl_src) $(ion_device_dfu_relocated_src) $(ion_console_display_src)
|
||||
ion_xip_src = $(ion_src) $(ion_simulator_sdl_src) $(ion_device_dfu_xip_src) $(ion_console_uart_src)
|
||||
ion_headless_src = $(ion_src) $(ion_simulator_headless_src) $(ion_device_dfu_relocated_src) $(ion_console_stdio_src)
|
||||
|
||||
@@ -19,7 +19,7 @@ ion_src += $(addprefix ion/src/shared/, \
|
||||
|
||||
ION_DEVICE_SFLAGS = -Iion/src/device/$(MODEL) -Iion/src/device/shared
|
||||
|
||||
$(call object_for,$(ion_device_src) $(dfu_src) $(flasher_src) $(usb_src) $(bench_src) $(ion_device_dfu_xip_src) $(ion_device_dfu_relocated_src)): SFLAGS += $(ION_DEVICE_SFLAGS)
|
||||
$(call object_for,$(ion_device_src) $(dfu_src) $(ion_target_device_flasher_light_src) $(ion_target_device_flasher_verbose_src) $(usb_src) $(ion_target_device_bench_src) $(ion_device_dfu_xip_src) $(ion_device_dfu_relocated_src) $(ion_console_uart_src)): SFLAGS += $(ION_DEVICE_SFLAGS)
|
||||
ion_src += $(ion_device_src)
|
||||
|
||||
# When using the register.h C++ file in production mode, we expect the compiler
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
bench_src += $(addprefix ion/src/device/bench/, \
|
||||
ion_target_device_bench_src += $(addprefix ion/src/device/bench/, \
|
||||
bench.cpp \
|
||||
command_handler.cpp \
|
||||
command_list.cpp \
|
||||
runner.cpp \
|
||||
)
|
||||
|
||||
bench_src += $(addprefix ion/src/device/bench/command/, \
|
||||
ion_target_device_bench_src += $(addprefix ion/src/device/bench/command/, \
|
||||
adc.cpp \
|
||||
backlight.cpp \
|
||||
charge.cpp \
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
flasher_src += $(addprefix ion/src/device/flasher/, \
|
||||
ion_target_device_flasher_light_src = $(addprefix ion/src/device/flasher/, \
|
||||
main.cpp \
|
||||
display_light.cpp \
|
||||
)
|
||||
|
||||
ion_target_device_flasher_verbose_src = $(addprefix ion/src/device/flasher/, \
|
||||
main.cpp \
|
||||
display_verbose.cpp \
|
||||
)
|
||||
|
||||
@@ -3,7 +3,6 @@ ion_device_src += $(addprefix ion/src/device/shared/drivers/, \
|
||||
battery.cpp \
|
||||
base64.cpp \
|
||||
board.cpp \
|
||||
console.cpp \
|
||||
crc32.cpp \
|
||||
display.cpp \
|
||||
events_keyboard_platform.cpp \
|
||||
@@ -20,3 +19,6 @@ ion_device_src += $(addprefix ion/src/device/shared/drivers/, \
|
||||
usb.cpp \
|
||||
wakeup.cpp \
|
||||
)
|
||||
|
||||
ion_console_uart_src = ion/src/device/shared/drivers/console.cpp
|
||||
ion_console_display_src += ion/src/device/shared/drivers/console_dummy.cpp
|
||||
|
||||
19
ion/src/device/shared/drivers/console_dummy.cpp
Normal file
19
ion/src/device/shared/drivers/console_dummy.cpp
Normal file
@@ -0,0 +1,19 @@
|
||||
#include "console.h"
|
||||
|
||||
namespace Ion {
|
||||
namespace Device {
|
||||
namespace Console {
|
||||
|
||||
void init() {
|
||||
}
|
||||
|
||||
void shutdown() {
|
||||
}
|
||||
|
||||
bool peerConnected() {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
29
ion/src/shared/console_display.cpp
Normal file
29
ion/src/shared/console_display.cpp
Normal file
@@ -0,0 +1,29 @@
|
||||
#include <ion/console.h>
|
||||
#include <kandinsky.h>
|
||||
#include <ion/display.h>
|
||||
|
||||
namespace Ion {
|
||||
namespace Console {
|
||||
|
||||
char readChar() {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static KDPoint cursor = KDPointZero;
|
||||
|
||||
void writeChar(char c) {
|
||||
char text[2] = {c, 0};
|
||||
KDContext * ctx = KDIonContext::sharedContext();
|
||||
cursor = ctx->drawString(text, cursor);
|
||||
if (cursor.y() > Ion::Display::Height) {
|
||||
cursor = KDPoint(cursor.x(), 0);
|
||||
}
|
||||
}
|
||||
|
||||
bool transmissionDone() {
|
||||
// Always true because we flush after each writeChar
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -17,13 +17,26 @@ ion_src += $(addprefix ion/src/shared/, \
|
||||
dummy/usb.cpp \
|
||||
)
|
||||
|
||||
ion_src += $(addprefix ion/src/simulator/shared/, \
|
||||
ion_simulator_sdl_src += $(addprefix ion/src/simulator/shared/, \
|
||||
display.cpp \
|
||||
events_keyboard_platform.cpp \
|
||||
keyboard.cpp \
|
||||
main.cpp \
|
||||
events_keyboard.cpp \
|
||||
framebuffer_base.cpp \
|
||||
keyboard_sdl.cpp \
|
||||
main_sdl.cpp \
|
||||
layout.cpp \
|
||||
)
|
||||
|
||||
ion_simulator_headless_src += $(addprefix ion/src/simulator/shared/, \
|
||||
events_stdin.cpp \
|
||||
framebuffer_base.cpp \
|
||||
framebuffer_png.cpp \
|
||||
keyboard_dummy.cpp \
|
||||
main_headless.cpp \
|
||||
)
|
||||
|
||||
$(call object_for,ion/src/simulator/shared/framebuffer_png.cpp): SFLAGS += `libpng-config --cflags`
|
||||
|
||||
ion_console_stdio_src = ion/src/simulator/shared/console_stdio.cpp
|
||||
|
||||
include ion/src/simulator/$(TARGET)/Makefile
|
||||
include ion/src/simulator/external/Makefile
|
||||
|
||||
@@ -1,52 +1,22 @@
|
||||
#include "display.h"
|
||||
#include "main.h"
|
||||
#include "framebuffer.h"
|
||||
#include <assert.h>
|
||||
#include <ion/display.h>
|
||||
#include <SDL.h>
|
||||
#include <string.h>
|
||||
|
||||
/* Drawing on an SDL texture
|
||||
* In SDL2, drawing bitmap data happens through textures, whose data lives in
|
||||
* the GPU's memory. Reading data back from a texture is not possible, so we
|
||||
* simply maintain a framebuffer in RAM since Ion::Display::pullRect expects to
|
||||
* be able to read pixel data back.
|
||||
* A side effect is that we rewrite the whole texture when redrawing the screen.
|
||||
* This might not be the most efficient way since sending pixels to the GPU is
|
||||
* rather expensive. */
|
||||
|
||||
static KDColor sPixels[Ion::Display::Width * Ion::Display::Height];
|
||||
|
||||
namespace Ion {
|
||||
namespace Display {
|
||||
|
||||
static KDFrameBuffer sFrameBuffer = KDFrameBuffer(sPixels, KDSize(Ion::Display::Width, Ion::Display::Height));
|
||||
|
||||
void pushRect(KDRect r, const KDColor * pixels) {
|
||||
SDL::Main::setNeedsRefresh();
|
||||
sFrameBuffer.pushRect(r, pixels);
|
||||
}
|
||||
|
||||
void pushRectUniform(KDRect r, KDColor c) {
|
||||
SDL::Main::setNeedsRefresh();
|
||||
sFrameBuffer.pushRectUniform(r, c);
|
||||
}
|
||||
|
||||
void pullRect(KDRect r, KDColor * pixels) {
|
||||
sFrameBuffer.pullRect(r, pixels);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
namespace Ion {
|
||||
namespace SDL {
|
||||
namespace Simulator {
|
||||
namespace Display {
|
||||
|
||||
static SDL_Texture * sFramebufferTexture = nullptr;
|
||||
|
||||
void init(SDL_Renderer * renderer) {
|
||||
Uint32 texturePixelFormat = SDL_PIXELFORMAT_RGB565;
|
||||
assert(sizeof(KDColor) == SDL_BYTESPERPIXEL(texturePixelFormat));
|
||||
sFramebufferTexture = SDL_CreateTexture(
|
||||
renderer,
|
||||
SDL_PIXELFORMAT_RGB565,
|
||||
texturePixelFormat,
|
||||
SDL_TEXTUREACCESS_STREAMING,
|
||||
Ion::Display::Width,
|
||||
Ion::Display::Height
|
||||
@@ -63,7 +33,7 @@ void draw(SDL_Renderer * renderer, SDL_Rect * rect) {
|
||||
void * pixels = nullptr;
|
||||
SDL_LockTexture(sFramebufferTexture, nullptr, &pixels, &pitch);
|
||||
assert(pitch == 2*Ion::Display::Width);
|
||||
memcpy(pixels, sPixels, sizeof(sPixels));
|
||||
memcpy(pixels, Framebuffer::address(), sizeof(KDColor)*Ion::Display::Width*Ion::Display::Height);
|
||||
SDL_UnlockTexture(sFramebufferTexture);
|
||||
|
||||
SDL_RenderCopy(renderer, sFramebufferTexture, nullptr, rect);
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
#ifndef ION_SDL_DISPLAY_H
|
||||
#define ION_SDL_DISPLAY_H
|
||||
#ifndef ION_SIMULATOR_DISPLAY_H
|
||||
#define ION_SIMULATOR_DISPLAY_H
|
||||
|
||||
#include <kandinsky.h>
|
||||
#include <SDL.h>
|
||||
|
||||
namespace Ion {
|
||||
namespace SDL {
|
||||
namespace Simulator {
|
||||
namespace Display {
|
||||
|
||||
void init(SDL_Renderer * renderer);
|
||||
|
||||
15
ion/src/simulator/shared/events.h
Normal file
15
ion/src/simulator/shared/events.h
Normal file
@@ -0,0 +1,15 @@
|
||||
#ifndef ION_SIMULATOR_EVENTS_H
|
||||
#define ION_SIMULATOR_EVENTS_H
|
||||
|
||||
namespace Ion {
|
||||
namespace Simulator {
|
||||
namespace Events {
|
||||
|
||||
void dumpEventCount(int i);
|
||||
void logAfter(int numberOfEvents);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -185,7 +185,7 @@ Event getPlatformEvent() {
|
||||
// The while is important: it'll do a fast-pass over all useless SDL events
|
||||
if (event.type == SDL_WINDOWEVENT) {
|
||||
if (event.window.event == SDL_WINDOWEVENT_RESIZED) {
|
||||
Ion::SDL::Main::relayout();
|
||||
Ion::Simulator::Main::relayout();
|
||||
}
|
||||
}
|
||||
if (event.type == SDL_QUIT) {
|
||||
58
ion/src/simulator/shared/events_stdin.cpp
Normal file
58
ion/src/simulator/shared/events_stdin.cpp
Normal file
@@ -0,0 +1,58 @@
|
||||
#include "main.h"
|
||||
#include "platform.h"
|
||||
#include "framebuffer.h"
|
||||
#include "events.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <ion/events.h>
|
||||
#include <string.h>
|
||||
|
||||
void IonSimulatorEventsPushEvent(int eventNumber) {
|
||||
}
|
||||
|
||||
static int sLogAfterNumberOfEvents = -1;
|
||||
static int sEventCount = 0;
|
||||
|
||||
namespace Ion {
|
||||
namespace Events {
|
||||
|
||||
Event getPlatformEvent() {
|
||||
Ion::Events::Event event = Ion::Events::None;
|
||||
while (!(event.isDefined() && event.isKeyboardEvent())) {
|
||||
int c = getchar();
|
||||
if (c == EOF) {
|
||||
printf("Finished processing %d events\n", sEventCount);
|
||||
event = Ion::Events::Termination;
|
||||
break;
|
||||
}
|
||||
event = Ion::Events::Event(c);
|
||||
}
|
||||
if (sEventCount++ > sLogAfterNumberOfEvents && sLogAfterNumberOfEvents >= 0) {
|
||||
char filename[32];
|
||||
sprintf(filename, "event%d.png", sEventCount);
|
||||
Ion::Simulator::Framebuffer::writeToFile(filename);
|
||||
#if DEBUG
|
||||
printf("Event %d is %s\n", sEventCount, event.name());
|
||||
#endif
|
||||
}
|
||||
return event;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
namespace Ion {
|
||||
namespace Simulator {
|
||||
namespace Events {
|
||||
|
||||
void dumpEventCount(int i) {
|
||||
printf("Current event index: %d\n", sEventCount);
|
||||
}
|
||||
|
||||
void logAfter(int numberOfEvents) {
|
||||
sLogAfterNumberOfEvents = numberOfEvents;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
18
ion/src/simulator/shared/framebuffer.h
Normal file
18
ion/src/simulator/shared/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
|
||||
61
ion/src/simulator/shared/framebuffer_base.cpp
Normal file
61
ion/src/simulator/shared/framebuffer_base.cpp
Normal file
@@ -0,0 +1,61 @@
|
||||
#include "framebuffer.h"
|
||||
#include <ion/display.h>
|
||||
#include "main.h"
|
||||
|
||||
/* Drawing on an SDL texture
|
||||
* In SDL2, drawing bitmap data happens through textures, whose data lives in
|
||||
* the GPU's memory. Reading data back from a texture is not possible, so we
|
||||
* simply maintain a framebuffer in RAM since Ion::Display::pullRect expects to
|
||||
* be able to read pixel data back.
|
||||
* A side effect is that we rewrite the whole texture when redrawing the screen.
|
||||
* This might not be the most efficient way since sending pixels to the GPU is
|
||||
* rather expensive.
|
||||
* This is also very useful when running headless because we can easily log the
|
||||
* framebuffer to a PNG file. */
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
53
ion/src/simulator/shared/framebuffer_png.cpp
Normal file
53
ion/src/simulator/shared/framebuffer_png.cpp
Normal file
@@ -0,0 +1,53 @@
|
||||
#include "framebuffer.h"
|
||||
#include <ion/display.h>
|
||||
#include <stdlib.h>
|
||||
#include <png.h>
|
||||
|
||||
typedef struct {
|
||||
uint8_t red;
|
||||
uint8_t green;
|
||||
uint8_t blue;
|
||||
} pixel_t;
|
||||
|
||||
void Ion::Simulator::Framebuffer::writeToFile(const char * filename) {
|
||||
FILE * file = fopen(filename, "wb"); // Write in binary mode
|
||||
//ENSURE(file != NULL, "Opening file %s", filename);
|
||||
|
||||
png_structp png = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
|
||||
//ENSURE(png != NULL, "Allocating PNG write structure");
|
||||
|
||||
png_infop info = png_create_info_struct(png);
|
||||
//ENSURE(info != NULL, "Allocating info structure");
|
||||
|
||||
png_init_io(png, file);
|
||||
|
||||
png_set_IHDR(png, info,
|
||||
Ion::Display::Width, Ion::Display::Height,
|
||||
8, // Number of bits per channel
|
||||
PNG_COLOR_TYPE_RGB,
|
||||
PNG_INTERLACE_NONE,
|
||||
PNG_COMPRESSION_TYPE_DEFAULT,
|
||||
PNG_FILTER_TYPE_DEFAULT);
|
||||
|
||||
png_write_info(png, info);
|
||||
|
||||
static_assert(sizeof(pixel_t) == 3, "pixel_t shall be 3 bytes long (RGB888 format)");
|
||||
pixel_t * row = (pixel_t *)malloc(3*Ion::Display::Width);
|
||||
const KDColor * pixels = address();
|
||||
for (int j=0;j<Ion::Display::Height;j++) {
|
||||
for (int i=0; i<Ion::Display::Width; i++) {
|
||||
KDColor c = pixels[i+Ion::Display::Width*j];
|
||||
row[i].red = c.red();
|
||||
row[i].green = c.green();
|
||||
row[i].blue = c.blue();
|
||||
}
|
||||
png_write_row(png, (png_bytep)row);
|
||||
}
|
||||
free(row);
|
||||
|
||||
png_write_end(png, NULL);
|
||||
|
||||
png_free_data(png, info, PNG_FREE_ALL, -1); // -1 = all items
|
||||
png_destroy_write_struct(&png, (png_infopp)NULL);
|
||||
fclose(file);
|
||||
}
|
||||
18
ion/src/simulator/shared/keyboard_dummy.cpp
Normal file
18
ion/src/simulator/shared/keyboard_dummy.cpp
Normal file
@@ -0,0 +1,18 @@
|
||||
#include <ion/keyboard.h>
|
||||
#include "platform.h"
|
||||
|
||||
void IonSimulatorKeyboardKeyDown(int keyNumber) {
|
||||
}
|
||||
|
||||
void IonSimulatorKeyboardKeyUp(int keyNumber) {
|
||||
}
|
||||
|
||||
namespace Ion {
|
||||
namespace Keyboard {
|
||||
|
||||
State scan() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -30,7 +30,7 @@ State scan() {
|
||||
IonSimulatorCallbackDidScanKeyboard();
|
||||
|
||||
// Grab this opportunity to refresh the display if needed
|
||||
SDL::Main::refresh();
|
||||
Simulator::Main::refresh();
|
||||
|
||||
#if EPSILON_SDL_SCREEN_ONLY
|
||||
// In this case, keyboard states will be sent over another channel
|
||||
@@ -43,7 +43,7 @@ State scan() {
|
||||
SDL_Point p;
|
||||
Uint32 mouseState = SDL_GetMouseState(&p.x, &p.y);
|
||||
if (mouseState & SDL_BUTTON(SDL_BUTTON_LEFT)) {
|
||||
Key k = SDL::Layout::keyAt(&p);
|
||||
Key k = Simulator::Layout::keyAt(&p);
|
||||
state.setKey(k);
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include "layout.h"
|
||||
|
||||
namespace Ion {
|
||||
namespace SDL {
|
||||
namespace Simulator {
|
||||
namespace Layout {
|
||||
|
||||
static constexpr int backgroundWidth = 1160;
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
#ifndef ION_SDL_LAYOUT_H
|
||||
#define ION_SDL_LAYOUT_H
|
||||
#ifndef ION_SIMULATOR_LAYOUT_H
|
||||
#define ION_SIMULATOR_LAYOUT_H
|
||||
|
||||
#include <ion/keyboard.h>
|
||||
#include <SDL.h>
|
||||
|
||||
namespace Ion {
|
||||
namespace SDL {
|
||||
namespace Simulator {
|
||||
namespace Layout {
|
||||
|
||||
void recompute(int width, int height);
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#ifndef ION_SDL_MAIN_H
|
||||
#define ION_SDL_MAIN_H
|
||||
#ifndef ION_SIMULATOR_MAIN_H
|
||||
#define ION_SIMULATOR_MAIN_H
|
||||
|
||||
namespace Ion {
|
||||
namespace SDL {
|
||||
namespace Simulator {
|
||||
namespace Main {
|
||||
|
||||
void init();
|
||||
|
||||
65
ion/src/simulator/shared/main_headless.cpp
Normal file
65
ion/src/simulator/shared/main_headless.cpp
Normal file
@@ -0,0 +1,65 @@
|
||||
#include "main.h"
|
||||
#include "display.h"
|
||||
#include "platform.h"
|
||||
#include "framebuffer.h"
|
||||
#include "events.h"
|
||||
|
||||
#include <ion.h>
|
||||
#include <ion/timing.h>
|
||||
#include <ion/events.h>
|
||||
#include <stdlib.h>
|
||||
#include <signal.h>
|
||||
#include <sys/resource.h>
|
||||
|
||||
constexpr int kHeapSize = 131072;
|
||||
constexpr int kStackSize = 32768;
|
||||
|
||||
char heap[kHeapSize];
|
||||
extern "C" {
|
||||
char * _heap_start = (char *)heap;
|
||||
char * _heap_end = _heap_start+kHeapSize;
|
||||
int main(int argc, char * argv[]);
|
||||
}
|
||||
|
||||
void Ion::Timing::msleep(uint32_t ms) {
|
||||
}
|
||||
|
||||
int main(int argc, char * argv[]) {
|
||||
Ion::Simulator::Framebuffer::setActive(false);
|
||||
// Parse command-line arguments
|
||||
for (int i=1; i<argc; i++) {
|
||||
if (strcmp(argv[i], "--logAfter") == 0 && argc > i+1) {
|
||||
Ion::Simulator::Framebuffer::setActive(true);
|
||||
Ion::Simulator::Events::logAfter(atoi(argv[i+1]));
|
||||
}
|
||||
}
|
||||
|
||||
// Handle signals
|
||||
signal(SIGABRT, Ion::Simulator::Events::dumpEventCount);
|
||||
|
||||
// Limit stack usage
|
||||
struct rlimit stackLimits = {kStackSize, kStackSize};
|
||||
setrlimit(RLIMIT_STACK, &stackLimits);
|
||||
|
||||
ion_main(argc, argv);
|
||||
return 0;
|
||||
}
|
||||
|
||||
namespace Ion {
|
||||
namespace Simulator {
|
||||
namespace Main {
|
||||
|
||||
void init() {
|
||||
}
|
||||
|
||||
void setNeedsRefresh() {
|
||||
}
|
||||
|
||||
void relayout() {
|
||||
}
|
||||
|
||||
void refresh() {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -25,17 +25,17 @@ int main(int argc, char * argv[]) {
|
||||
}
|
||||
|
||||
IonSimulatorTelemetryInit();
|
||||
Ion::SDL::Main::init();
|
||||
Ion::Simulator::Main::init();
|
||||
IonSimulatorTelemetryEvent("Calculator");
|
||||
ion_main(arguments.size(), &arguments[0]);
|
||||
Ion::SDL::Main::quit();
|
||||
Ion::Simulator::Main::quit();
|
||||
IonSimulatorTelemetryDeinit();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
namespace Ion {
|
||||
namespace SDL {
|
||||
namespace Simulator {
|
||||
namespace Main {
|
||||
|
||||
static SDL_Window * sWindow = nullptr;
|
||||
@@ -1,5 +1,5 @@
|
||||
#ifndef ION_SDL_PLATFORM_H
|
||||
#define ION_SDL_PLATFORM_H
|
||||
#ifndef ION_SIMULATOR_PLATFORM_H
|
||||
#define ION_SIMULATOR_PLATFORM_H
|
||||
|
||||
#include <SDL.h>
|
||||
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
SFLAGS += -Iquiz/include
|
||||
|
||||
QUIZ_USE_CONSOLE ?= 0
|
||||
$(call object_for,quiz/src/runner.cpp): SFLAGS += -DQUIZ_USE_CONSOLE=$(QUIZ_USE_CONSOLE)
|
||||
|
||||
define rule_for_quiz_symbols
|
||||
$$(BUILD_DIR)/quiz/src/$(subst _src,,$(1))_symbols.c: $$($(1)) | $$$$(@D)/.
|
||||
@ echo "AWK $$@"
|
||||
@@ -19,7 +16,7 @@ runner_src += $(addprefix quiz/src/, \
|
||||
runner.cpp \
|
||||
)
|
||||
|
||||
runner_src += $(symbols_file)
|
||||
runner_src += $(BUILD_DIR)/quiz/src/tests_symbols.c
|
||||
|
||||
$(call object_for,$(runner_src)): SFLAGS += -Iquiz/src
|
||||
$(BUILD_DIR)/quiz/src/%_symbols.o: SFLAGS += -Iquiz/src
|
||||
|
||||
@@ -8,20 +8,7 @@
|
||||
#include <poincare/exception_checkpoint.h>
|
||||
|
||||
void quiz_print(const char * message) {
|
||||
#if QUIZ_USE_CONSOLE
|
||||
Ion::Console::writeLine(message);
|
||||
#else
|
||||
static int line_y = 0;
|
||||
KDContext * ctx = KDIonContext::sharedContext();
|
||||
const KDFont * font = KDFont::LargeFont;
|
||||
int line_height = font->glyphSize().height();
|
||||
ctx->drawString(message, KDPoint(0, line_y), font);
|
||||
line_y += line_height;
|
||||
if (line_y + line_height > Ion::Display::Height) {
|
||||
line_y = 0;
|
||||
// Clear screen maybe?
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void ion_main_inner() {
|
||||
@@ -37,11 +24,6 @@ static inline void ion_main_inner() {
|
||||
i++;
|
||||
}
|
||||
quiz_print("ALL TESTS FINISHED");
|
||||
#if !QUIZ_USE_CONSOLE
|
||||
while (1) {
|
||||
Ion::Timing::msleep(1000);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void ion_main(int argc, char * argv[]) {
|
||||
@@ -59,10 +41,5 @@ void ion_main(int argc, char * argv[]) {
|
||||
Poincare::TreePool::sharedPool()->log();
|
||||
#endif
|
||||
quiz_assert(false);
|
||||
#if !QUIZ_USE_CONSOLE
|
||||
while (1) {
|
||||
Ion::Timing::msleep(1000);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user