Raylib build for web + minimal front-end page, stand alone story-vm project

This commit is contained in:
anthony@rabine.fr 2025-01-07 10:26:24 +01:00
parent 19b78b17a1
commit 318547f351
18 changed files with 2062 additions and 168 deletions

164
.gitignore vendored
View file

@ -95,3 +95,167 @@ story-player-raylib/build/
story-player/linux/flutter/generated_plugin_registrant.cc
story-player/linux/flutter/generated_plugins.cmake
story-player-raylib/build-web/cmake_install.cmake
story-player-raylib/build-web/CMakeCache.txt
story-player-raylib/build-web/compile_commands.json
story-player-raylib/build-web/CPackConfig.cmake
story-player-raylib/build-web/CPackSourceConfig.cmake
story-player-raylib/build-web/cpm-package-lock.cmake
story-player-raylib/build-web/Makefile
story-player-raylib/build-web/CMakeFiles/cmake.check_cache
story-player-raylib/build-web/CMakeFiles/CMakeConfigureLog.yaml
story-player-raylib/build-web/CMakeFiles/CMakeDirectoryInformation.cmake
story-player-raylib/build-web/CMakeFiles/CMakeRuleHashes.txt
story-player-raylib/build-web/CMakeFiles/Makefile.cmake
story-player-raylib/build-web/CMakeFiles/Makefile2
story-player-raylib/build-web/CMakeFiles/progress.marks
story-player-raylib/build-web/CMakeFiles/TargetDirectories.txt
story-player-raylib/build-web/CMakeFiles/3.30.3/CMakeCCompiler.cmake
story-player-raylib/build-web/CMakeFiles/3.30.3/CMakeCXXCompiler.cmake
story-player-raylib/build-web/CMakeFiles/3.30.3/CMakeSystem.cmake
story-player-raylib/build-web/CMakeFiles/pkgRedirects/raylib-config.cmake
story-player-raylib/build-web/CMakeFiles/pkgRedirects/raylib-version.cmake
story-player-raylib/build-web/CMakeFiles/story-player.dir/build.make
story-player-raylib/build-web/CMakeFiles/story-player.dir/cmake_clean.cmake
story-player-raylib/build-web/CMakeFiles/story-player.dir/compiler_depend.internal
story-player-raylib/build-web/CMakeFiles/story-player.dir/compiler_depend.make
story-player-raylib/build-web/CMakeFiles/story-player.dir/compiler_depend.ts
story-player-raylib/build-web/CMakeFiles/story-player.dir/depend.make
story-player-raylib/build-web/CMakeFiles/story-player.dir/DependInfo.cmake
story-player-raylib/build-web/CMakeFiles/story-player.dir/flags.make
story-player-raylib/build-web/CMakeFiles/story-player.dir/includes_C.rsp
story-player-raylib/build-web/CMakeFiles/story-player.dir/includes_CXX.rsp
story-player-raylib/build-web/CMakeFiles/story-player.dir/link.txt
story-player-raylib/build-web/CMakeFiles/story-player.dir/linkLibs.rsp
story-player-raylib/build-web/CMakeFiles/story-player.dir/main.c.o
story-player-raylib/build-web/CMakeFiles/story-player.dir/main.c.o.d
story-player-raylib/build-web/CMakeFiles/story-player.dir/objects1.rsp
story-player-raylib/build-web/CMakeFiles/story-player.dir/progress.make
story-player-raylib/build-web/CMakeFiles/story-player.dir/mnt/work/git/open-story-teller/firmware/chip32/chip32_assembler.cpp.o
story-player-raylib/build-web/CMakeFiles/story-player.dir/mnt/work/git/open-story-teller/firmware/chip32/chip32_assembler.cpp.o.d
story-player-raylib/build-web/CMakeFiles/story-player.dir/mnt/work/git/open-story-teller/firmware/chip32/chip32_vm.c.o
story-player-raylib/build-web/CMakeFiles/story-player.dir/mnt/work/git/open-story-teller/firmware/chip32/chip32_vm.c.o.d
story-player-raylib/build-web/_deps/raylib-build/cmake_install.cmake
story-player-raylib/build-web/_deps/raylib-build/cmake_uninstall.cmake
story-player-raylib/build-web/_deps/raylib-build/CTestTestfile.cmake
story-player-raylib/build-web/_deps/raylib-build/Makefile
story-player-raylib/build-web/_deps/raylib-build/CMakeFiles/CMakeDirectoryInformation.cmake
story-player-raylib/build-web/_deps/raylib-build/CMakeFiles/progress.marks
story-player-raylib/build-web/_deps/raylib-build/CMakeFiles/uninstall.dir/build.make
story-player-raylib/build-web/_deps/raylib-build/CMakeFiles/uninstall.dir/cmake_clean.cmake
story-player-raylib/build-web/_deps/raylib-build/CMakeFiles/uninstall.dir/compiler_depend.make
story-player-raylib/build-web/_deps/raylib-build/CMakeFiles/uninstall.dir/compiler_depend.ts
story-player-raylib/build-web/_deps/raylib-build/CMakeFiles/uninstall.dir/DependInfo.cmake
story-player-raylib/build-web/_deps/raylib-build/CMakeFiles/uninstall.dir/progress.make
story-player-raylib/build-web/_deps/raylib-build/raylib/cmake_install.cmake
story-player-raylib/build-web/_deps/raylib-build/raylib/CTestTestfile.cmake
story-player-raylib/build-web/_deps/raylib-build/raylib/libraylib.a
story-player-raylib/build-web/_deps/raylib-build/raylib/Makefile
story-player-raylib/build-web/_deps/raylib-build/raylib/raylib-config-version.cmake
story-player-raylib/build-web/_deps/raylib-build/raylib/raylib.pc
story-player-raylib/build-web/_deps/raylib-build/raylib/CMakeFiles/CMakeDirectoryInformation.cmake
story-player-raylib/build-web/_deps/raylib-build/raylib/CMakeFiles/progress.marks
story-player-raylib/build-web/_deps/raylib-build/raylib/CMakeFiles/raylib.dir/build.make
story-player-raylib/build-web/_deps/raylib-build/raylib/CMakeFiles/raylib.dir/cmake_clean_target.cmake
story-player-raylib/build-web/_deps/raylib-build/raylib/CMakeFiles/raylib.dir/cmake_clean.cmake
story-player-raylib/build-web/_deps/raylib-build/raylib/CMakeFiles/raylib.dir/compiler_depend.internal
story-player-raylib/build-web/_deps/raylib-build/raylib/CMakeFiles/raylib.dir/compiler_depend.make
story-player-raylib/build-web/_deps/raylib-build/raylib/CMakeFiles/raylib.dir/compiler_depend.ts
story-player-raylib/build-web/_deps/raylib-build/raylib/CMakeFiles/raylib.dir/depend.make
story-player-raylib/build-web/_deps/raylib-build/raylib/CMakeFiles/raylib.dir/DependInfo.cmake
story-player-raylib/build-web/_deps/raylib-build/raylib/CMakeFiles/raylib.dir/flags.make
story-player-raylib/build-web/_deps/raylib-build/raylib/CMakeFiles/raylib.dir/includes_C.rsp
story-player-raylib/build-web/_deps/raylib-build/raylib/CMakeFiles/raylib.dir/link.txt
story-player-raylib/build-web/_deps/raylib-build/raylib/CMakeFiles/raylib.dir/progress.make
story-player-raylib/build-web/_deps/raylib-build/raylib/CMakeFiles/raylib.dir/raudio.c.o
story-player-raylib/build-web/_deps/raylib-build/raylib/CMakeFiles/raylib.dir/raudio.c.o.d
story-player-raylib/build-web/_deps/raylib-build/raylib/CMakeFiles/raylib.dir/rcore.c.o
story-player-raylib/build-web/_deps/raylib-build/raylib/CMakeFiles/raylib.dir/rcore.c.o.d
story-player-raylib/build-web/_deps/raylib-build/raylib/CMakeFiles/raylib.dir/rmodels.c.o
story-player-raylib/build-web/_deps/raylib-build/raylib/CMakeFiles/raylib.dir/rmodels.c.o.d
story-player-raylib/build-web/_deps/raylib-build/raylib/CMakeFiles/raylib.dir/rshapes.c.o
story-player-raylib/build-web/_deps/raylib-build/raylib/CMakeFiles/raylib.dir/rshapes.c.o.d
story-player-raylib/build-web/_deps/raylib-build/raylib/CMakeFiles/raylib.dir/rtext.c.o
story-player-raylib/build-web/_deps/raylib-build/raylib/CMakeFiles/raylib.dir/rtext.c.o.d
story-player-raylib/build-web/_deps/raylib-build/raylib/CMakeFiles/raylib.dir/rtextures.c.o
story-player-raylib/build-web/_deps/raylib-build/raylib/CMakeFiles/raylib.dir/rtextures.c.o.d
story-player-raylib/build-web/_deps/raylib-build/raylib/CMakeFiles/raylib.dir/utils.c.o
story-player-raylib/build-web/_deps/raylib-build/raylib/CMakeFiles/raylib.dir/utils.c.o.d
story-player-raylib/build-web/_deps/raylib-build/raylib/include/raylib.h
story-player-raylib/build-web/_deps/raylib-build/raylib/include/raymath.h
story-player-raylib/build-web/_deps/raylib-build/raylib/include/rlgl.h
story-player-raylib/build-web/_deps/raylib-subbuild/cmake_install.cmake
story-player-raylib/build-web/_deps/raylib-subbuild/CMakeCache.txt
story-player-raylib/build-web/_deps/raylib-subbuild/CMakeLists.txt
story-player-raylib/build-web/_deps/raylib-subbuild/Makefile
story-player-raylib/build-web/_deps/raylib-subbuild/CMakeFiles/cmake.check_cache
story-player-raylib/build-web/_deps/raylib-subbuild/CMakeFiles/CMakeConfigureLog.yaml
story-player-raylib/build-web/_deps/raylib-subbuild/CMakeFiles/CMakeDirectoryInformation.cmake
story-player-raylib/build-web/_deps/raylib-subbuild/CMakeFiles/CMakeRuleHashes.txt
story-player-raylib/build-web/_deps/raylib-subbuild/CMakeFiles/Makefile.cmake
story-player-raylib/build-web/_deps/raylib-subbuild/CMakeFiles/Makefile2
story-player-raylib/build-web/_deps/raylib-subbuild/CMakeFiles/progress.marks
story-player-raylib/build-web/_deps/raylib-subbuild/CMakeFiles/raylib-populate-complete
story-player-raylib/build-web/_deps/raylib-subbuild/CMakeFiles/TargetDirectories.txt
story-player-raylib/build-web/_deps/raylib-subbuild/CMakeFiles/3.30.3/CMakeSystem.cmake
story-player-raylib/build-web/_deps/raylib-subbuild/CMakeFiles/raylib-populate.dir/build.make
story-player-raylib/build-web/_deps/raylib-subbuild/CMakeFiles/raylib-populate.dir/cmake_clean.cmake
story-player-raylib/build-web/_deps/raylib-subbuild/CMakeFiles/raylib-populate.dir/compiler_depend.make
story-player-raylib/build-web/_deps/raylib-subbuild/CMakeFiles/raylib-populate.dir/compiler_depend.ts
story-player-raylib/build-web/_deps/raylib-subbuild/CMakeFiles/raylib-populate.dir/DependInfo.cmake
story-player-raylib/build-web/_deps/raylib-subbuild/CMakeFiles/raylib-populate.dir/Labels.json
story-player-raylib/build-web/_deps/raylib-subbuild/CMakeFiles/raylib-populate.dir/Labels.txt
story-player-raylib/build-web/_deps/raylib-subbuild/CMakeFiles/raylib-populate.dir/progress.make
story-player-raylib/build-web/_deps/raylib-subbuild/raylib-populate-prefix/src/5.5.tar.gz
story-player-raylib/build-web/_deps/raylib-subbuild/raylib-populate-prefix/src/raylib-populate-stamp/download-raylib-populate.cmake
story-player-raylib/build-web/_deps/raylib-subbuild/raylib-populate-prefix/src/raylib-populate-stamp/extract-raylib-populate.cmake
story-player-raylib/build-web/_deps/raylib-subbuild/raylib-populate-prefix/src/raylib-populate-stamp/raylib-populate-build
story-player-raylib/build-web/_deps/raylib-subbuild/raylib-populate-prefix/src/raylib-populate-stamp/raylib-populate-configure
story-player-raylib/build-web/_deps/raylib-subbuild/raylib-populate-prefix/src/raylib-populate-stamp/raylib-populate-done
story-player-raylib/build-web/_deps/raylib-subbuild/raylib-populate-prefix/src/raylib-populate-stamp/raylib-populate-download
story-player-raylib/build-web/_deps/raylib-subbuild/raylib-populate-prefix/src/raylib-populate-stamp/raylib-populate-install
story-player-raylib/build-web/_deps/raylib-subbuild/raylib-populate-prefix/src/raylib-populate-stamp/raylib-populate-mkdir
story-player-raylib/build-web/_deps/raylib-subbuild/raylib-populate-prefix/src/raylib-populate-stamp/raylib-populate-patch
story-player-raylib/build-web/_deps/raylib-subbuild/raylib-populate-prefix/src/raylib-populate-stamp/raylib-populate-patch-info.txt
story-player-raylib/build-web/_deps/raylib-subbuild/raylib-populate-prefix/src/raylib-populate-stamp/raylib-populate-test
story-player-raylib/build-web/_deps/raylib-subbuild/raylib-populate-prefix/src/raylib-populate-stamp/raylib-populate-update
story-player-raylib/build-web/_deps/raylib-subbuild/raylib-populate-prefix/src/raylib-populate-stamp/raylib-populate-update-info.txt
story-player-raylib/build-web/_deps/raylib-subbuild/raylib-populate-prefix/src/raylib-populate-stamp/raylib-populate-urlinfo.txt
story-player-raylib/build-web/_deps/raylib-subbuild/raylib-populate-prefix/src/raylib-populate-stamp/verify-raylib-populate.cmake
story-player-raylib/build-web/_deps/raylib-subbuild/raylib-populate-prefix/tmp/raylib-populate-cfgcmd.txt
story-player-raylib/build-web/_deps/raylib-subbuild/raylib-populate-prefix/tmp/raylib-populate-mkdirs.cmake
story-vm/build/cmake_install.cmake
story-vm/build/CMakeCache.txt
story-vm/build/libstoryvm.a
story-vm/build/Makefile
story-vm/build/CMakeFiles/cmake.check_cache
story-vm/build/CMakeFiles/CMakeConfigureLog.yaml
story-vm/build/CMakeFiles/CMakeDirectoryInformation.cmake
story-vm/build/CMakeFiles/Makefile.cmake
story-vm/build/CMakeFiles/Makefile2
story-vm/build/CMakeFiles/progress.marks
story-vm/build/CMakeFiles/TargetDirectories.txt
story-vm/build/CMakeFiles/3.30.3/CMakeCCompiler.cmake
story-vm/build/CMakeFiles/3.30.3/CMakeCXXCompiler.cmake
story-vm/build/CMakeFiles/3.30.3/CMakeSystem.cmake
story-vm/build/CMakeFiles/storyvm.dir/build.make
story-vm/build/CMakeFiles/storyvm.dir/cmake_clean_target.cmake
story-vm/build/CMakeFiles/storyvm.dir/cmake_clean.cmake
story-vm/build/CMakeFiles/storyvm.dir/compiler_depend.internal
story-vm/build/CMakeFiles/storyvm.dir/compiler_depend.make
story-vm/build/CMakeFiles/storyvm.dir/compiler_depend.ts
story-vm/build/CMakeFiles/storyvm.dir/depend.make
story-vm/build/CMakeFiles/storyvm.dir/DependInfo.cmake
story-vm/build/CMakeFiles/storyvm.dir/flags.make
story-vm/build/CMakeFiles/storyvm.dir/includes_C.rsp
story-vm/build/CMakeFiles/storyvm.dir/includes_CXX.rsp
story-vm/build/CMakeFiles/storyvm.dir/link.txt
story-vm/build/CMakeFiles/storyvm.dir/objects1.rsp
story-vm/build/CMakeFiles/storyvm.dir/progress.make
story-vm/build/CMakeFiles/storyvm.dir/storyvm.cpp.o
story-vm/build/CMakeFiles/storyvm.dir/storyvm.cpp.o.d
story-vm/build/CMakeFiles/storyvm.dir/mnt/work/git/open-story-teller/firmware/chip32/chip32_vm.c.o
story-vm/build/CMakeFiles/storyvm.dir/mnt/work/git/open-story-teller/firmware/chip32/chip32_vm.c.o.d
story-player-raylib/bin/story-player.data
story-player-raylib/bin/story-player.js
story-player-raylib/bin/story-player.wasm

28
.vscode/launch.json vendored
View file

@ -39,6 +39,34 @@
}
]
},
{
"name": "Debug Story Player (Raylib)",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/story-player-raylib/build/story-player", // Remplacez par le chemin de votre exécutable
"args": [],
"stopAtEntry": false,
"cwd": "${workspaceFolder}/story-player-raylib",
"environment": [],
"externalConsole": false,
"linux": {
"MIMode": "gdb",
"miDebuggerPath": "/usr/bin/gdb"
},
"osx": {
"MIMode": "lldb",
"miDebuggerPath": "/Users/user936511/.vscode/extensions/ms-vscode.cpptools-1.18.5-darwin-arm64/debugAdapters/lldb-mi/bin/lldb-mi"
},
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
}
]
},
{
"name": "Black Magic Probe",

View file

@ -2,7 +2,7 @@
"cmake.sourceDirectory": [
"${workspaceFolder}/story-editor",
"${workspaceFolder}/story-player",
"${workspaceFolder}/story-player-raylib",
"${workspaceFolder}/software"
],
"files.associations": {

View file

@ -63,6 +63,22 @@ The Story plater is a purely software implementation of a simple story player. I
![editor](art/story_player.png)
There are multiple implementations in this directory (Flutter, SDL, Raylib). The one that will be maintain is probably the Raylib version besause this framework is the easiest one to port on multiple platforms.
# Developer corner
## Build the Story Player
### Web version
Emscripten must be installed.
```
mkdir build-web && cd build-web
emcmake cmake .. -DPLATFORM=Web -DCMAKE_BUILD_TYPE=Debug
emmake make
```
# License

View file

@ -0,0 +1 @@
{"requests":[{"kind":"cache","version":2},{"kind":"codemodel","version":2},{"kind":"toolchains","version":1},{"kind":"cmakeFiles","version":1}]}

View file

@ -222,7 +222,7 @@ DockSpace ID=0x08BD597D Window=0x1BBC0F80 Pos=60,26 Size=1220,694 Split=Y
DockNode ID=0x00000005 Parent=0x08BD597D SizeRef=1220,504 Split=X
DockNode ID=0x00000002 Parent=0x00000005 SizeRef=531,694 CentralNode=1 Selected=0xBB79A587
DockNode ID=0x00000001 Parent=0x00000005 SizeRef=687,694 Split=Y Selected=0x63869CAF
DockNode ID=0x00000003 Parent=0x00000001 SizeRef=543,294 Selected=0x63869CAF
DockNode ID=0x00000003 Parent=0x00000001 SizeRef=543,294 Selected=0x4B07C626
DockNode ID=0x00000004 Parent=0x00000001 SizeRef=543,372 Selected=0x7563A968
DockNode ID=0x00000006 Parent=0x08BD597D SizeRef=1220,297 Selected=0xEA83D666

View file

@ -4,37 +4,37 @@ project(story-player)
# Generate compile_commands.json
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# Dependencies
set(RAYLIB_VERSION 4.5.0)
find_package(raylib ${RAYLIB_VERSION} QUIET) # QUIET or REQUIRED
if (NOT raylib_FOUND) # If there's none, fetch and build raylib
include(FetchContent)
FetchContent_Declare(
raylib
URL https://github.com/raysan5/raylib/archive/refs/tags/${RAYLIB_VERSION}.tar.gz
)
FetchContent_GetProperties(raylib)
if (NOT raylib_POPULATED) # Have we downloaded raylib yet?
set(FETCHCONTENT_QUIET NO)
FetchContent_Populate(raylib)
set(BUILD_EXAMPLES OFF CACHE BOOL "" FORCE) # don't build the supplied examples
add_subdirectory(${raylib_SOURCE_DIR} ${raylib_BINARY_DIR})
endif()
endif()
include(cmake/CPM.cmake)
# Our Project
# =========================================================================================================================
# RAYLIB
# =========================================================================================================================
set(RAYLIB_VERSION 5.5.0)
CPMAddPackage(
NAME raylib
URL https://github.com/raysan5/raylib/archive/5.5.tar.gz
OPTIONS
"BUILD_EXAMPLES OFF"
"BUILD_GAMES OFF"
"GLFW_BUILD_WAYLAND ON"
"GLFW_BUILD_X11 ON"
)
# =========================================================================================================================
# EXECUTABLE
# =========================================================================================================================
add_executable(${PROJECT_NAME}
main.c
raygui.h
../software/chip32/chip32_assembler.cpp
../software/chip32/chip32_vm.c
../software/chip32/chip32_assembler.h
../software/chip32/chip32_vm.h
../firmware/chip32/chip32_assembler.cpp
../firmware/chip32/chip32_vm.c
)
include_directories(../software/chip32)
include_directories(../software/library)
include_directories(../firmware/chip32)
include_directories(../firmware/library)
#set(raylib_VERBOSE 1)
target_link_libraries(${PROJECT_NAME} raylib)
@ -47,3 +47,15 @@ if (APPLE)
target_link_libraries(${PROJECT_NAME} "-framework OpenGL")
endif()
if (${PLATFORM} STREQUAL "Web")
# Tell Emscripten to build an .html file.
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Os")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s USE_GLFW=3 -s ASYNCIFY=1 -s ASSERTIONS=1 -s WASM=1 -Os -Wall -s TOTAL_MEMORY=67108864 -s FORCE_FILESYSTEM=1 --preload-file ../assets/")
set_target_properties(${PROJECT_NAME} PROPERTIES
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/../bin"
)
target_compile_definitions(${PROJECT_NAME} PUBLIC ASSETS_PATH="/assets/") # Set the asset path macro in release mode to a relative path that assumes the assets folder is in the same directory as the game executable
endif()

View file

Before

Width:  |  Height:  |  Size: 116 KiB

After

Width:  |  Height:  |  Size: 116 KiB

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,70 @@
<!doctype html>
<html lang="en-us">
<head>
<meta charset="utf-8">
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="title" content="OpenStoryTeller Web Player">
<meta name="description" content="OpenStoryTeller Web Player">
<meta name="keywords" content="story, player, teller">
<title>OpenStoryTeller Web Player</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@picocss/pico@2/css/pico.min.css">
<!-- Favicon -->
<link rel="shortcut icon" href="https://www.raylib.com/favicon.ico">
<style>
/* body {
margin: 0px;
text-align: center;
} */
canvas.emscripten { border: 0px none; background-color: black; display: inline; }
#canvas-container {
width: 100%;
text-align:center;
}
</style>
</head>
<body>
<main class="container-fluid">
<vertical-menu></vertical-menu>
<div id="canvas-container">
<canvas class=emscripten id=canvas oncontextmenu=event.preventDefault() tabindex=-1></canvas>
</div>
<p id="output" />
</main>
<script>
var Module = {
print: (function() {
var element = document.getElementById('output');
if (element) element.value = ''; // clear browser cache
return function(text) {
if (arguments.length > 1) text = Array.prototype.slice.call(arguments).join(' ');
console.log(text);
if (element) {
element.value += text + "\n";
element.scrollTop = element.scrollHeight; // focus on bottom
}
};
})(),
canvas: (function() {
var canvas = document.getElementById('canvas');
return canvas;
})(),
locateFile: function(s) {
return 'bin/' + s;
}
};
</script>
<script async type="text/javascript" src="bin/story-player.js"></script>
<script src="vertical-menu.js" type="module"></script>
</body>
</html>

View file

@ -27,6 +27,11 @@
#include "chip32_vm.h"
#include <stdbool.h>
#if defined(PLATFORM_WEB)
#include <emscripten/emscripten.h>
#endif
int set_filename_from_memory(chip32_ctx_t *ctx, uint32_t addr, char *filename_mem)
{
int valid = 0;
@ -147,7 +152,7 @@ uint8_t story_player_syscall(chip32_ctx_t *ctx, uint8_t code)
gMusic.looping = false;
gMusicLoaded = true;
if (IsMusicReady(gMusic))
if (IsMusicValid(gMusic))
{
PlayMusicStream(gMusic);
}
@ -163,17 +168,158 @@ uint8_t story_player_syscall(chip32_ctx_t *ctx, uint8_t code)
return retCode;
}
// VM Stuff
//---------------------------------------------------------------------------------------
uint8_t rom_data[16*1024];
uint8_t ram_data[16*1024];
chip32_ctx_t chip32_ctx;
chip32_result_t run_result = VM_FINISHED;
// Directories
//---------------------------------------------------------------------------------------
char homedir[MAX_PATH];
GuiFileDialogState fileDialogState;
Texture2D logoTexture;
int screenWidth = 400;
int screenHeight = 560;
bool exitWindow = false;
char fileNameToLoad[512] = { 0 };
void UpdateDrawFrame(void)
{
// Update
//----------------------------------------------------------------------------------
exitWindow = WindowShouldClose();
if (fileDialogState.SelectFilePressed)
{
if (IsFileExtension(fileDialogState.fileNameText, ".c32"))
{
strcpy(fileNameToLoad, TextFormat("%s/%s", fileDialogState.dirPathText, fileDialogState.fileNameText));
run_result = vm_load_script(&chip32_ctx, fileNameToLoad);
get_parent_dir(fileNameToLoad, root_dir);
printf("Root directory: %s\n", root_dir);
}
fileDialogState.SelectFilePressed = false;
}
// VM next instruction
if (run_result == VM_OK)
{
run_result = chip32_step(&chip32_ctx);
}
if (gMusicLoaded)
{
UpdateMusicStream(gMusic);
if (!IsMusicStreamPlaying(gMusic))
{
StopMusicStream(gMusic);
UnloadMusicStream(gMusic);
gMusicLoaded = false;
run_result = VM_OK; // continue VM execution
}
}
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(GetColor(GuiGetStyle(DEFAULT, BACKGROUND_COLOR)));
DrawTextureEx(logoTexture, (Vector2){ (float)10, (float)450 }, 0, 0.15, WHITE);
// Image de l'histoire
DrawRectangle(40, 25, 320, 240, WHITE);
DrawTexture(texture, 220, 25, WHITE);
GuiSetIconScale(3);
const int yBottomScreen = 275;
// ICON_ARROW_LEFT
if (GuiButton((Rectangle){ 40, yBottomScreen, 60, 60 }, "#114#"))
{
if (run_result == VM_WAIT_EVENT)
{
chip32_ctx.registers[R0] = EV_BUTTON_LEFT;
run_result = VM_OK;
}
}
// ICON_OK_TICK
if (GuiButton((Rectangle){ 40 + 65, yBottomScreen, 60, 60 }, "#112#"))
{
if (run_result == VM_WAIT_EVENT)
{
chip32_ctx.registers[R0] = EV_BUTTON_OK;
run_result = VM_OK;
}
}
// ICON_ARROW_RIGHT
if (GuiButton((Rectangle){ 40 + 2*65, yBottomScreen, 60, 60 }, "#115#"))
{
if (run_result == VM_WAIT_EVENT)
{
chip32_ctx.registers[R0] = EV_BUTTON_RIGHT;
run_result = VM_OK;
}
}
// ICON_PLAYER_PAUSE
if (GuiButton((Rectangle){ 180 + 65, 450, 60, 60 }, "#132#"))
{
}
// ICON_HOUSE
if (GuiButton((Rectangle){ 180 + 2*65, 450, 60, 60 }, "#185#"))
{
}
// raygui: controls drawing
//----------------------------------------------------------------------------------
if (fileDialogState.windowActive) GuiLock();
GuiUnlock();
// GUI: Dialog Window
//--------------------------------------------------------------------------------
GuiSetIconScale(1);
GuiFileDialog(&fileDialogState);
//--------------------------------------------------------------------------------
//----------------------------------------------------------------------------------
EndDrawing();
//----------------------------------------------------------------------------------
}
//------------------------------------------------------------------------------------
// Program main entry point
//------------------------------------------------------------------------------------
int main()
{
// VM Stuff
//---------------------------------------------------------------------------------------
uint8_t rom_data[16*1024];
uint8_t ram_data[16*1024];
chip32_ctx_t chip32_ctx;
chip32_ctx.stack_size = 512;
@ -187,23 +333,17 @@ int main()
chip32_ctx.syscall = story_player_syscall;
chip32_result_t run_result = VM_FINISHED;
// Directories
//---------------------------------------------------------------------------------------
char homedir[MAX_PATH];
get_home_path(homedir);
// Initialization
//---------------------------------------------------------------------------------------
int screenWidth = 800;
int screenHeight = 560;
InitWindow(screenWidth, screenHeight, "OpenStoryTeller - Player");
SetExitKey(0);
Font fontTtf = LoadFontEx("Inter-Regular.ttf", 14, 0, 0);
Font fontTtf = LoadFontEx("assets/Inter-Regular.ttf", 14, 0, 0);
GuiSetStyle(DEFAULT, BACKGROUND_COLOR, 0x133D42ff);
GuiSetStyle(DEFAULT, TEXT_SIZE, 14);
@ -219,142 +359,30 @@ int main()
GuiSetFont(fontTtf);
// Custom file dialog
GuiFileDialogState fileDialogState = InitGuiFileDialog(GetWorkingDirectory());
fileDialogState = InitGuiFileDialog(GetWorkingDirectory());
strcpy(fileDialogState.filterExt, ".c32");
strcpy(fileDialogState.dirPathText, homedir);
Texture2D logoTexture = LoadTexture("logo-color2.png");
bool exitWindow = false;
char fileNameToLoad[512] = { 0 };
logoTexture = LoadTexture("assets/logo-color.png");
InitAudioDevice();
UnloadMusicStream(gMusic);
SetTargetFPS(60);
//--------------------------------------------------------------------------------------
// Main game loop
while (!exitWindow) // Detect window close button or ESC key
{
// Update
//----------------------------------------------------------------------------------
exitWindow = WindowShouldClose();
#if defined(PLATFORM_WEB)
emscripten_set_main_loop(UpdateDrawFrame, 0, 1);
#else
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
//--------------------------------------------------------------------------------------
if (fileDialogState.SelectFilePressed)
{
if (IsFileExtension(fileDialogState.fileNameText, ".c32"))
{
strcpy(fileNameToLoad, TextFormat("%s/%s", fileDialogState.dirPathText, fileDialogState.fileNameText));
run_result = vm_load_script(&chip32_ctx, fileNameToLoad);
get_parent_dir(fileNameToLoad, root_dir);
printf("Root directory: %s\n", root_dir);
}
fileDialogState.SelectFilePressed = false;
}
// VM next instruction
if (run_result == VM_OK)
{
run_result = chip32_step(&chip32_ctx);
}
if (gMusicLoaded)
{
UpdateMusicStream(gMusic);
if (!IsMusicStreamPlaying(gMusic))
{
StopMusicStream(gMusic);
UnloadMusicStream(gMusic);
gMusicLoaded = false;
run_result = VM_OK; // continue VM execution
}
}
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(GetColor(GuiGetStyle(DEFAULT, BACKGROUND_COLOR)));
DrawTextureEx(logoTexture, (Vector2){ (float)10, (float)10 }, 0, 0.15, WHITE);
// Image de l'histoire
DrawRectangle(220, 25, 320, 240, WHITE);
DrawTexture(texture, 220, 25, WHITE);
GuiSetIconScale(3);
if (GuiButton((Rectangle){ 20, 140, 60, 60 }, "#05#"))
{
fileDialogState.windowActive = true;
}
// ICON_PLAYER_PAUSE
if (GuiButton((Rectangle){ 20 + 65, 140, 60, 60 }, "#132#"))
{
}
// ICON_HOUSE
if (GuiButton((Rectangle){ 20 + 2*65, 140, 60, 60 }, "#185#"))
{
}
// ICON_ARROW_LEFT
if (GuiButton((Rectangle){ 20, 205, 60, 60 }, "#114#"))
{
if (run_result == VM_WAIT_EVENT)
{
chip32_ctx.registers[R0] = EV_BUTTON_LEFT;
run_result = VM_OK;
}
}
// ICON_OK_TICK
if (GuiButton((Rectangle){ 20 + 65, 205, 60, 60 }, "#112#"))
{
if (run_result == VM_WAIT_EVENT)
{
chip32_ctx.registers[R0] = EV_BUTTON_OK;
run_result = VM_OK;
}
}
// ICON_ARROW_RIGHT
if (GuiButton((Rectangle){ 20 + 2*65, 205, 60, 60 }, "#115#"))
{
if (run_result == VM_WAIT_EVENT)
{
chip32_ctx.registers[R0] = EV_BUTTON_RIGHT;
run_result = VM_OK;
}
}
// raygui: controls drawing
//----------------------------------------------------------------------------------
if (fileDialogState.windowActive) GuiLock();
GuiUnlock();
// GUI: Dialog Window
//--------------------------------------------------------------------------------
GuiSetIconScale(1);
GuiFileDialog(&fileDialogState);
//--------------------------------------------------------------------------------
//----------------------------------------------------------------------------------
EndDrawing();
//----------------------------------------------------------------------------------
}
// Main game loop
while (!WindowShouldClose()) // Detect window close button or ESC key
{
UpdateDrawFrame();
}
#endif
// De-Initialization
//--------------------------------------------------------------------------------------

View file

@ -0,0 +1,27 @@
class VerticalMenu extends HTMLElement {
constructor() {
super();
// Create a wrapper nav element using Bulma
this.innerHTML = `
<nav>
<ul>
<li><strong>OpenStoryTeller</strong></li>
</ul>
<ul>
<li><a href="#">Paramètres</a></li>
<li><a href="#">À propos</a></li>
</ul>
</nav>
`;
}
connectedCallback() {
}
}
// Define the new element
customElements.define('vertical-menu', VerticalMenu);

16
story-vm/CMakeLists.txt Normal file
View file

@ -0,0 +1,16 @@
cmake_minimum_required(VERSION 3.10)
project(storyvm LANGUAGES CXX C)
add_executable(storyvm
./storyvm.cpp
../firmware/chip32/chip32_vm.c
)
include_directories(../firmware/chip32 ../shared)
# Spécifier les options de compilation pour Emscripten
set_target_properties(storyvm PROPERTIES
COMPILE_FLAGS "-s WASM=1"
LINK_FLAGS "-s WASM=1 -s EXPORTED_FUNCTIONS='[\"_storyvm_start\", \"_storyvm_send_event\"]' -s EXPORTED_RUNTIME_METHODS='[\"ccall\", \"cwrap\"]'"
)

18
story-vm/dlib_export.h Normal file
View file

@ -0,0 +1,18 @@
#pragma once
#if defined(_MSC_VER)
// Microsoft
#define DLIB_EXPORT __declspec(dllexport)
#elif defined(__GNUC__)
// GCC
#define DLIB_EXPORT __attribute__((visibility("default")))
#else
// do nothing and hope for the best?
#define DLIB_EXPORT
#pragma warning Unknown dynamic link import/export semantics.
#endif

11
story-vm/index.html Normal file
View file

@ -0,0 +1,11 @@
<!DOCTYPE html>
<html>
<head>
<title>Open Story Teller</title>
</head>
<body>
<h1>Open Story Teller</h1>
<script src="storyvm.js"></script>
<script src="main.js"></script>
</body>
</html>

9
story-vm/main.js Normal file
View file

@ -0,0 +1,9 @@
Module.onRuntimeInitialized = function() {
// Créer une instance de WebServer
var startVm = Module.cwrap('storyvm_start', 'void', ['number', 'number']);
console.log("Starting VM with story");
startVm(0, 0);
};

209
story-vm/storyvm.cpp Normal file
View file

@ -0,0 +1,209 @@
// testffi/libs/api.cpp
#include <cstring>
#include <cstdio>
#include <thread>
#include <atomic>
#include <iostream>
#include <chrono>
#include <stdbool.h>
#include "chip32_vm.h"
#include "dlib_export.h"
#include "story_machine.h"
static char root_dir[260];
static bool gMusicLoaded = false;
char fileNameToLoad[512] = { 0 };
typedef void (*media_callback)(int32_t, const char*);
static media_callback gMediaCallback = nullptr;
//---------------------------------------------------------------------------------------
// VM Stuff
//---------------------------------------------------------------------------------------
static uint8_t rom_data[16*1024];
static uint8_t ram_data[16*1024];
static chip32_ctx_t chip32_ctx;
static chip32_result_t run_result;
static uint32_t event_mask = 0;
static uint8_t IndexBuf[260];
static uint8_t ImageBuf[100];
static uint8_t SoundBuf[100];
static bool IsValidEvent(uint32_t event) {
return (event_mask & event) != 0;
}
int get_filename_from_memory(chip32_ctx_t *ctx, uint32_t addr, char *filename_mem)
{
int valid = 0;
// Test if address is valid
bool isRam = addr & 0x80000000;
addr &= 0xFFFF; // mask the RAM/ROM bit, ensure 16-bit addressing
if (isRam) {
strcpy(&filename_mem[0], (const char *)&ctx->ram.mem[addr]);
} else {
strcpy(&filename_mem[0], (const char *)&ctx->rom.mem[addr]);
}
return valid;
}
uint8_t story_player_syscall(chip32_ctx_t *ctx, uint8_t code)
{
uint8_t retCode = SYSCALL_RET_OK;
static char image_path[260];
static char sound_path[260];
if (code == 1) // // Execute media
{
std::cout << "[STORYVM] Syscall 1" << std::endl;
// for (int i = 0; i< REGISTER_COUNT; i++) {
// std::cout << "[STORYVM] Reg: " << i << ", value: " << (int)ctx->registers[i] << std::endl;
// }
if (ctx->registers[R0] != 0)
{
// sound file name address is in R1
char image[100];
get_filename_from_memory(ctx, ctx->registers[R0], image);
if (gMediaCallback)
{
std::cout << "[STORYVM] Execute callback (image)" << std::endl;
gMediaCallback(0, image);
}
}
else
{
std::cout << "[STORYVM] No image" << std::endl;
}
if (ctx->registers[R1] != 0)
{
// sound file name address is in R1
char sound[100];
get_filename_from_memory(ctx, ctx->registers[R1], sound);
if (gMediaCallback)
{
std::cout << "[STORYVM] Execute callback (sound)" << std::endl;
gMediaCallback(1, sound);
}
}
else
{
std::cout << "[STORYVM] No sound" << std::endl;
}
retCode = SYSCALL_RET_OK; // set the VM in pause
}
else if (code == 2) // Wait Event
{
std::cout << "[STORYVM] Syscall 2 (wait for event)" << std::endl;
event_mask = ctx->registers[R0];
retCode = SYSCALL_RET_WAIT_EV; // set the VM in pause
}
else if (code == 3) // Signal
{
if (ctx->registers[R0] == 1)
{
// EXIT
std::cout << "[STORYVM] Syscall 3 (exit)" << std::endl;
if (gMediaCallback)
{
std::cout << "[STORYVM] Execute callback (sound)" << std::endl;
gMediaCallback(2, "");
}
}
}
return retCode;
}
extern "C" void storyvm_run()
{
// VM next instruction
if (run_result == VM_OK)
{
run_result = chip32_step(&chip32_ctx);
// for (int i = 0; i< REGISTER_COUNT; i++) {
// std::cout << "[STORYVM] Reg: " << i << ", value: " << (int)chip32_ctx.registers[i] << std::endl;
// }
}
}
extern "C" void storyvm_stop()
{
std::cout << "[STORYVM] Stop: " << std::endl;
run_result = VM_FINISHED;
}
extern "C" void storyvm_initialize(media_callback cb)
{
std::cout << "[STORYVM] Initialize: " << (void *)cb << std::endl;
gMediaCallback = cb;
chip32_ctx.stack_size = 512;
chip32_ctx.rom.mem = rom_data;
chip32_ctx.rom.addr = 0;
chip32_ctx.rom.size = sizeof(rom_data);
chip32_ctx.ram.mem = ram_data;
chip32_ctx.ram.addr = sizeof(rom_data);
chip32_ctx.ram.size = sizeof(ram_data);
chip32_ctx.syscall = story_player_syscall;
run_result = VM_FINISHED;
storyvm_stop();
}
extern "C" DLIB_EXPORT void storyvm_send_event(int event)
{
if (IsValidEvent(event))
{
chip32_ctx.registers[R0] = event;
run_result = VM_OK;
}
else
{
std::cout << "[STORYVM] Invalid event" << std::endl;
}
}
extern "C" DLIB_EXPORT void storyvm_start(const uint8_t *data, uint32_t size)
{
if (size <= chip32_ctx.rom.size)
{
memcpy(chip32_ctx.rom.mem, data, size);
run_result = VM_OK;
chip32_initialize(&chip32_ctx);
std::cout << "[STORYVM] Start" << std::endl;
}
else
{
run_result = VM_FINISHED;
std::cout << "[STORYVM] Not started (not enough memory)" << std::endl;
}
}