[build] Clean the different targets

This commit is contained in:
Romain Goyet
2019-10-01 14:15:26 +02:00
committed by Ecco
parent 5acda9069c
commit e81426f93b
33 changed files with 463 additions and 128 deletions

View File

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

View File

@@ -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

View File

@@ -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

View 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

View 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.*

View File

@@ -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"]'

View File

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

View File

@@ -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

View File

@@ -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 \

View File

@@ -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 \
)

View File

@@ -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

View File

@@ -0,0 +1,19 @@
#include "console.h"
namespace Ion {
namespace Device {
namespace Console {
void init() {
}
void shutdown() {
}
bool peerConnected() {
return false;
}
}
}
}

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

View File

@@ -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

View File

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

View File

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

View 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

View File

@@ -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) {

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

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

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

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

View File

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

View File

@@ -1,7 +1,7 @@
#include "layout.h"
namespace Ion {
namespace SDL {
namespace Simulator {
namespace Layout {
static constexpr int backgroundWidth = 1160;

View File

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

View File

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

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

View File

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

View File

@@ -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>

View File

@@ -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

View File

@@ -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
}
}