mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-01-19 00:37:25 +01:00
[ion/simulator] Add actions
This commit is contained in:
@@ -9,18 +9,23 @@ SFLAGS += -Iion/src/simulator/linux/include
|
||||
|
||||
ion_src += $(addprefix ion/src/simulator/linux/, \
|
||||
assets.s \
|
||||
platform_files.cpp \
|
||||
platform_images.cpp \
|
||||
platform_language.cpp \
|
||||
)
|
||||
|
||||
ion_src += $(addprefix ion/src/simulator/shared/, \
|
||||
dummy/callback.cpp \
|
||||
dummy/haptics_enabled.cpp \
|
||||
dummy/keyboard_callback.cpp \
|
||||
dummy/window_callback.cpp \
|
||||
actions.cpp \
|
||||
clipboard_helper.cpp \
|
||||
collect_registers_x86_64.s \
|
||||
collect_registers.cpp \
|
||||
haptics.cpp \
|
||||
journal.cpp \
|
||||
platform_action_modifier_ctrl.cpp \
|
||||
state_file.cpp \
|
||||
)
|
||||
|
||||
ifeq ($(EPSILON_TELEMETRY),1)
|
||||
|
||||
21
ion/src/simulator/linux/platform_files.cpp
Normal file
21
ion/src/simulator/linux/platform_files.cpp
Normal file
@@ -0,0 +1,21 @@
|
||||
#include "../shared/platform.h"
|
||||
|
||||
namespace Ion {
|
||||
namespace Simulator {
|
||||
namespace Platform {
|
||||
|
||||
const char * filePathForReading(const char * extension) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const char * filePathForWriting(const char * extension) {
|
||||
static char path[64];
|
||||
if (snprintf(path, sizeof(path), "/tmp/epsilon.%s", extension) < 0) {
|
||||
return nullptr;
|
||||
}
|
||||
return path;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
ion_src += $(addprefix ion/src/simulator/macos/, \
|
||||
platform_files.mm \
|
||||
platform_images.mm \
|
||||
)
|
||||
|
||||
@@ -10,8 +11,10 @@ ion_src += $(addprefix ion/src/simulator/shared/, \
|
||||
clipboard_helper.cpp \
|
||||
collect_registers_x86_64.s \
|
||||
collect_registers.cpp \
|
||||
actions.cpp \
|
||||
haptics.cpp \
|
||||
journal.cpp \
|
||||
state_file.cpp \
|
||||
)
|
||||
|
||||
ifeq ($(EPSILON_TELEMETRY),1)
|
||||
|
||||
32
ion/src/simulator/macos/platform_files.mm
Normal file
32
ion/src/simulator/macos/platform_files.mm
Normal file
@@ -0,0 +1,32 @@
|
||||
#include "../shared/platform.h"
|
||||
#include <AppKit/AppKit.h>
|
||||
|
||||
namespace Ion {
|
||||
namespace Simulator {
|
||||
namespace Platform {
|
||||
|
||||
static const char * getPath(NSSavePanel * panel, const char * extension) {
|
||||
[panel setAllowedFileTypes:[NSArray arrayWithObject:[NSString stringWithUTF8String:extension]]];
|
||||
static NSString * path = nil;
|
||||
[path release]; path = nil; // Discard previous path if any
|
||||
NSWindow * mainWindow = [[NSApplication sharedApplication] keyWindow];
|
||||
if ([panel runModal] == NSFileHandlingPanelOKButton) {
|
||||
path = [[[panel URL] path] retain];
|
||||
}
|
||||
[mainWindow makeKeyAndOrderFront:nil];
|
||||
return [path UTF8String];
|
||||
}
|
||||
|
||||
const char * filePathForReading(const char * extension) {
|
||||
NSOpenPanel * panel = [NSOpenPanel openPanel];
|
||||
return getPath(panel, extension);
|
||||
}
|
||||
|
||||
const char * filePathForWriting(const char * extension) {
|
||||
NSSavePanel * panel = [NSSavePanel savePanel];
|
||||
return getPath(panel, extension);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
38
ion/src/simulator/shared/actions.cpp
Normal file
38
ion/src/simulator/shared/actions.cpp
Normal file
@@ -0,0 +1,38 @@
|
||||
#include "actions.h"
|
||||
#include "framebuffer.h"
|
||||
#include "platform.h"
|
||||
#include "state_file.h"
|
||||
|
||||
namespace Ion {
|
||||
namespace Simulator {
|
||||
namespace Actions {
|
||||
|
||||
constexpr const char * kStateFileExtension = "nws";
|
||||
|
||||
void saveState() {
|
||||
const char * path = Platform::filePathForWriting(kStateFileExtension);
|
||||
if (path != nullptr) {
|
||||
StateFile::save(path);
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
void loadState() {
|
||||
// We would need to be able to perform a reset for this to be callable anytime
|
||||
const char * path = Platform::filePathForReading(kStateFileExtension);
|
||||
if (path != nullptr) {
|
||||
StateFile::load(path);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void takeScreenshot() {
|
||||
const char * path = Platform::filePathForWriting("png");
|
||||
if (path != nullptr) {
|
||||
// Framebuffer::writeToFile(path);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
17
ion/src/simulator/shared/actions.h
Normal file
17
ion/src/simulator/shared/actions.h
Normal file
@@ -0,0 +1,17 @@
|
||||
#ifndef ION_SIMULATOR_ACTIONS_H
|
||||
#define ION_SIMULATOR_ACTIONS_H
|
||||
|
||||
#include <SDL.h>
|
||||
|
||||
namespace Ion {
|
||||
namespace Simulator {
|
||||
namespace Actions {
|
||||
|
||||
void saveState();
|
||||
void takeScreenshot();
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
22
ion/src/simulator/shared/dummy/actions.cpp
Normal file
22
ion/src/simulator/shared/dummy/actions.cpp
Normal file
@@ -0,0 +1,22 @@
|
||||
#include "../actions.h"
|
||||
|
||||
namespace Ion {
|
||||
namespace Simulator {
|
||||
namespace Actions {
|
||||
|
||||
bool actionForEvent(SDL_KeyboardEvent event) {
|
||||
return false;
|
||||
}
|
||||
|
||||
void saveState() {
|
||||
}
|
||||
|
||||
void loadState() {
|
||||
}
|
||||
|
||||
void takeScreenshot() {
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
17
ion/src/simulator/shared/dummy/platform_files.cpp
Normal file
17
ion/src/simulator/shared/dummy/platform_files.cpp
Normal file
@@ -0,0 +1,17 @@
|
||||
#include "../platform.h"
|
||||
|
||||
namespace Ion {
|
||||
namespace Simulator {
|
||||
namespace Platform {
|
||||
|
||||
const char * filePathForReading(const char * extension) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const char * filePathForWriting(const char * extension) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
95
ion/src/simulator/shared/dummy/state_file.cpp
Normal file
95
ion/src/simulator/shared/dummy/state_file.cpp
Normal file
@@ -0,0 +1,95 @@
|
||||
#include <ion.h>
|
||||
#include <ion/events.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "journal.h"
|
||||
|
||||
namespace Ion {
|
||||
namespace Simulator {
|
||||
namespace StateFile {
|
||||
|
||||
static constexpr const char * sHeader = "NWSF";
|
||||
static constexpr int sHeaderLength = 4;
|
||||
static constexpr int sVersionLength = 8;
|
||||
|
||||
/* File format: * "NWSF" + "XXXXXXXX" (version) + EVENTS... */
|
||||
|
||||
static inline bool load(FILE * f) {
|
||||
char buffer[sVersionLength+1];
|
||||
|
||||
// Header
|
||||
buffer[sHeaderLength] = 0;
|
||||
if (fread(buffer, sHeaderLength, 1, f) != 1) {
|
||||
return false;
|
||||
}
|
||||
printf("READ\n");
|
||||
if (strcmp(buffer, sHeader) != 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Software version
|
||||
buffer[sVersionLength] = 0;
|
||||
if (fread(buffer, sVersionLength, 1, f) != 1) {
|
||||
return false;
|
||||
}
|
||||
if (strcmp(buffer, softwareVersion()) != 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Events
|
||||
Ion::Events::Journal * journal = Journal::replayJournal();
|
||||
while (fread(buffer, 1, 1, f) == 1) {
|
||||
Ion::Events::Event e = Ion::Events::Event(buffer[0]);
|
||||
journal->pushEvent(e);
|
||||
}
|
||||
Ion::Events::replayFrom(journal);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void load(const char * filename) {
|
||||
FILE * f = nullptr;
|
||||
if (strcmp(filename, "-") == 0) {
|
||||
f = stdin;
|
||||
} else {
|
||||
f = fopen(filename, "rb");
|
||||
}
|
||||
if (f == nullptr) {
|
||||
return;
|
||||
}
|
||||
load(f);
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
static inline bool save(FILE * f) {
|
||||
if (fwrite(sHeader, sHeaderLength, 1, f) != 1) {
|
||||
return false;
|
||||
}
|
||||
if (fwrite(softwareVersion(), sVersionLength, 1, f) != 1) {
|
||||
return false;
|
||||
}
|
||||
Ion::Events::Journal * journal = Journal::logJournal();
|
||||
Ion::Events::Event e;
|
||||
while (!journal->isEmpty()) {
|
||||
Ion::Events::Event e = journal->popEvent();
|
||||
uint8_t code = static_cast<uint8_t>(e);
|
||||
if (fwrite(&code, 1, 1, f) != 1) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void save(const char * filename) {
|
||||
printf("Saving to \"%s\"\n", filename);
|
||||
FILE * f = fopen(filename, "w");
|
||||
if (f == nullptr) {
|
||||
return;
|
||||
}
|
||||
save(f);
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,8 @@
|
||||
#include "actions.h"
|
||||
#include "events.h"
|
||||
#include "keyboard.h"
|
||||
#include "layout.h"
|
||||
#include "events.h"
|
||||
#include "state_file.h"
|
||||
#include "window.h"
|
||||
|
||||
#include <assert.h>
|
||||
@@ -12,7 +14,7 @@
|
||||
namespace Ion {
|
||||
namespace Events {
|
||||
|
||||
static Event eventFromSDLKeyboardEvent(SDL_KeyboardEvent event) {
|
||||
static inline Event eventFromSDLKeyboardEvent(SDL_KeyboardEvent event) {
|
||||
/* If an event is detected, we want to remove the Shift modifier to mimic the
|
||||
* device behaviour. If no event was detected, we restore the previous
|
||||
* ShiftAlphaStatus. */
|
||||
@@ -120,8 +122,7 @@ static Event eventFromSDLTextInputEvent(SDL_TextInputEvent event) {
|
||||
Event getPlatformEvent() {
|
||||
SDL_Event event;
|
||||
Event result = None;
|
||||
while (SDL_PollEvent(&event)) {
|
||||
// The while is important: it'll do a fast-pass over all useless SDL events
|
||||
while (SDL_PollEvent(&event)) { // That "while" is important: it'll do a fast-pass over all useless SDL events
|
||||
if (event.type == SDL_WINDOWEVENT) {
|
||||
Ion::Simulator::Window::relayout();
|
||||
break;
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#include "journal.h"
|
||||
#include "platform.h"
|
||||
#include "random.h"
|
||||
#include "state_file.h"
|
||||
#include "telemetry.h"
|
||||
#include "window.h"
|
||||
#include <algorithm>
|
||||
|
||||
13
ion/src/simulator/shared/platform_action_modifier_ctrl.cpp
Normal file
13
ion/src/simulator/shared/platform_action_modifier_ctrl.cpp
Normal file
@@ -0,0 +1,13 @@
|
||||
#include "../shared/platform.h"
|
||||
|
||||
namespace Ion {
|
||||
namespace Simulator {
|
||||
namespace Platform {
|
||||
|
||||
SDL_Keymod actionModifier() {
|
||||
return static_cast<SDL_Keymod>(KMOD_CTRL);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
13
ion/src/simulator/shared/platform_action_modifier_gui.cpp
Normal file
13
ion/src/simulator/shared/platform_action_modifier_gui.cpp
Normal file
@@ -0,0 +1,13 @@
|
||||
#include "../shared/platform.h"
|
||||
|
||||
namespace Ion {
|
||||
namespace Simulator {
|
||||
namespace Platform {
|
||||
|
||||
SDL_Keymod actionModifier() {
|
||||
return KMOD_GUI;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -21,6 +21,7 @@ ion_src += $(addprefix ion/src/simulator/web/, \
|
||||
)
|
||||
|
||||
ion_src += $(addprefix ion/src/simulator/shared/, \
|
||||
dummy/actions.cpp \
|
||||
dummy/language.cpp \
|
||||
dummy/haptics_enabled.cpp \
|
||||
haptics.cpp \
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include "exports.h"
|
||||
#include "../shared/events_journal.h"
|
||||
#include "../shared/journal.h"
|
||||
#include "../shared/keyboard.h"
|
||||
#include "../shared/window.h"
|
||||
#include <ion.h>
|
||||
|
||||
const char * IonSoftwareVersion() {
|
||||
@@ -27,7 +28,7 @@ void IonSimulatorKeyboardKeyUp(int keyNumber) {
|
||||
}
|
||||
|
||||
void IonSimulatorEventsPushEvent(int eventNumber) {
|
||||
Ion::Events::Journal * j = Ion::Simulator::Events::replayJournal();
|
||||
Ion::Events::Journal * j = Ion::Simulator::Journal::replayJournal();
|
||||
if (j != nullptr) {
|
||||
Ion::Events::Event event(eventNumber);
|
||||
j->pushEvent(event);
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
ion_src += $(addprefix ion/src/simulator/windows/, \
|
||||
platform_files.cpp \
|
||||
platform_images.cpp \
|
||||
platform_language.cpp \
|
||||
resources.rc \
|
||||
@@ -8,9 +9,12 @@ ion_src += $(addprefix ion/src/simulator/shared/, \
|
||||
dummy/haptics_enabled.cpp \
|
||||
dummy/keyboard_callback.cpp \
|
||||
dummy/window_callback.cpp \
|
||||
actions.cpp \
|
||||
clipboard_helper.cpp \
|
||||
haptics.cpp \
|
||||
journal.cpp \
|
||||
platform_action_modifier_ctrl.cpp \
|
||||
state_file.cpp \
|
||||
)
|
||||
|
||||
ion_src += ion/src/shared/collect_registers.cpp
|
||||
|
||||
51
ion/src/simulator/windows/platform_files.cpp
Normal file
51
ion/src/simulator/windows/platform_files.cpp
Normal file
@@ -0,0 +1,51 @@
|
||||
#include "../shared/platform.h"
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
|
||||
namespace Ion {
|
||||
namespace Simulator {
|
||||
namespace Platform {
|
||||
|
||||
static OPENFILENAME * getOFN(const char * extension) {
|
||||
static OPENFILENAME ofn;
|
||||
memset(&ofn, 0, sizeof(ofn)); // Zero-out ofn
|
||||
|
||||
static char path[PATH_MAX];
|
||||
path[0] = 0; // Reset the path
|
||||
|
||||
static char filter[32];
|
||||
if (snprintf(filter, sizeof(filter), "%s%c*.%s%c%c", extension, 0, extension, 0, 0) < 0) {
|
||||
/* Note: We cannot use litteral \0 in the format string, otherwise snprintf
|
||||
* will think the format string is finished... */
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ofn.lStructSize = sizeof(ofn);
|
||||
ofn.lpstrFile = path;
|
||||
ofn.nMaxFile = sizeof(path);
|
||||
ofn.lpstrFilter = filter;
|
||||
ofn.nFilterIndex = 1;
|
||||
ofn.lpstrDefExt = extension;
|
||||
|
||||
return &ofn;
|
||||
}
|
||||
|
||||
const char * filePathForReading(const char * extension) {
|
||||
OPENFILENAME * ofn = getOFN(extension);
|
||||
if (ofn != nullptr && GetOpenFileName(ofn)) {
|
||||
return ofn->lpstrFile;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const char * filePathForWriting(const char * extension) {
|
||||
OPENFILENAME * ofn = getOFN(extension);
|
||||
if (ofn != nullptr && GetSaveFileName(ofn)) {
|
||||
return ofn->lpstrFile;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user