Embed resource files for native build, break out config.

This commit is contained in:
Mahlon E. Smith 2025-08-21 16:57:23 -07:00
parent 1450302e06
commit e01dc377a7
Signed by: mahlon
SSH key fingerprint: SHA256:dP84sRGKZRpOOiPD/+GuOq+SHSxEw9qi5BWLQobaHm0
7 changed files with 138 additions and 23 deletions

0
.SRCINFO Normal file
View file

View file

@ -32,5 +32,6 @@ when defined( emscripten ):
# --passL:"-s JSPI" # async support (new) # --passL:"-s JSPI" # async support (new)
# --passL:"-s ALLOW_MEMORY_GROWTH=1" # --passL:"-s ALLOW_MEMORY_GROWTH=1"
--passL:"--preload-file resources" --passL:"--preload-file resources"
--passL:"--use-preload-cache"
--passL:"-o build/nimtest.js" --passL:"-o build/nimtest.js"

View file

@ -9,9 +9,23 @@ srcDir = "src"
requires "nim >= 2.2.4" requires "nim >= 2.2.4"
requires "naylib >= 25.33.0" requires "naylib >= 25.33.0"
requires "nimhttpd >= 1.5.1" requires "nimhttpd >= 1.5.1"
requires "zippy >= 0.10.16"
before make:
exec "tar -C resources -cvzf resources.tgz ."
after make:
exec "rm -f resources.tgz"
task make, "Native build": task make, "Native build":
exec "mkdir -p build && nim c --outdir:build -d:release --opt:speed src/nim_wasm_test.nim" exec """
mkdir -p build && nim c --outdir:build -d:release --opt:speed src/nim_wasm_test.nim
"""
task makedebug, "Native debugging build":
exec """
tar -C resources -cvzf resources.tgz . &&
mkdir -p build && nim c --outdir:build -d:debug src/nim_wasm_test.nim
"""
task makeweb, "Emscripten build": task makeweb, "Emscripten build":
exec """ exec """
@ -23,3 +37,4 @@ task runweb, "Run a local webserver for the wasm build":
exec "nimhttpd -H:'Cross-Origin-Opener-Policy: same-origin' -H:'Cross-Origin-Embedder-Policy: require-corp' build/" exec "nimhttpd -H:'Cross-Origin-Opener-Policy: same-origin' -H:'Cross-Origin-Embedder-Policy: require-corp' build/"

BIN
resources.tgz Normal file

Binary file not shown.

23
src/lib/configuration.nim Normal file
View file

@ -0,0 +1,23 @@
# vim: set et sta sw=4 ts=4 :
#
# Expose a global configuration INI file.
import
std/parsecfg,
std/strutils
import
embeddedfs
var conf*: Config
try:
conf = loadConfig( embeddedFs.confFile.string )
except IOError:
echo "No config file, using defaults."
conf = newConfig()
func fps*( c: Config ): int32 =
let fps = c.getSectionValue( "Performance", "fps", defaultVal = "60" )
return fps.parseInt.int32

70
src/lib/embeddedfs.nim Normal file
View file

@ -0,0 +1,70 @@
# vim: set et sta sw=4 ts=4 :
#
# This module exposes an "embeddedFs" object, that can
# return file handles for either native use (extracted on first run)
# or wasm (via preload-files).
import
std/os,
std/files,
std/paths,
std/strformat,
std/tempfiles
type
EmbeddedFS* = object
EmbeddedFSError* = object of CatchableError
let embeddedFs* = EmbeddedFS()
when not defined( emscripten ):
import zippy/tarballs
const ROOT = Path( currentSourcePath() ).parentDir.parentDir.parentDir
const RESOURCES = staticRead( $(ROOT / Path("resources.tgz")) )
let appname = extractFilename( getAppFileName() )
let dataDir = Path(getDataDir()) / Path( appname )
let confDir = Path(getConfigDir()) / Path( appname )
let confFile* = confDir / Path("config.ini")
else:
let dataDir = Path( "resources" )
let confDir = Path( "resources" )
let confFile* = confDir / Path("config.ini")
proc path*( data: EmbeddedFS, path: string ): Path =
## Returns the path of an embedded file.
return dataDir / Path( path )
proc `[]`*( data: EmbeddedFS, path: string ): string =
## Returns the contents of an embedded file.
if not fileExists( data.path(path) ):
raise newException( EmbeddedFSError, "No such file: {path}".fmt )
let f = open( $data.path(path) )
defer: f.close
return f.readAll
# TODO: version check, extract over old stuff
# no-op if versions match
#
proc update*( e: EmbeddedFS ) =
when not defined( emscripten ):
createDir( getDataDir() )
createDir( $confDir )
# check existing path / version
let ( tarball, path ) = createTempFile( "{appname}_resources_".fmt, ".tgz" )
tarball.write( RESOURCES )
tarball.close
extractAll( path, $dataDir )
removeFile( path )
let source = dataDir / Path( "config.ini" )
if not fileExists( confFile ): moveFile( source, confFile )

View file

@ -1,19 +1,15 @@
# vim: set et sta sw=4 ts=4 : # vim: set et sta sw=4 ts=4 :
import import
std/parsecfg, std/strformat
std/strformat,
std/strutils import reasings
import raylib import raylib
var conf: Config import
try: lib/configuration,
conf = loadConfig( "resources/config.ini" ) lib/embeddedfs
except IOError:
echo "No config file, using defaults."
conf = newConfig()
var fps = conf.getSectionValue( "Performance", "fps", defaultVal = "60").parseInt
# Emscripten specific imports # Emscripten specific imports
proc emscripten_set_main_loop( f: proc() {.cdecl.}, a: cint, b: bool ) {.importc.} proc emscripten_set_main_loop( f: proc() {.cdecl.}, a: cint, b: bool ) {.importc.}
@ -27,6 +23,14 @@ var camera = Camera(
projection: Perspective # Defines projection type, see CameraProjection projection: Perspective # Defines projection type, see CameraProjection
) )
var count = 0
let duration = 3000
let startPositionX: float32 = 45.0
let finalPositionX: float32 = 120.0
var currentPositionX = startPositionX
# This only works with: # This only works with:
# --passL:"-s EXPORT_FUNCTIONS=_nativeGreet", but it breaks raylib loading. # --passL:"-s EXPORT_FUNCTIONS=_nativeGreet", but it breaks raylib loading.
# hmmmmm. EXPORT_ALL=1 is also a no go. # hmmmmm. EXPORT_ALL=1 is also a no go.
@ -41,23 +45,26 @@ proc mainLoop() {.cdecl.} =
defer: closeWindow() defer: closeWindow()
initWindow( 800, 600, "raylib nim playground" ) initWindow( 800, 600, "raylib nim playground" )
setTargetFPS( fps.int32 ); setTargetFPS( conf.fps )
var count = 0
while not windowShouldClose(): while not windowShouldClose():
beginDrawing(); beginDrawing()
clearBackground( WHITE ); clearBackground( WHITE )
beginMode3D( camera ); beginMode3D( camera )
drawGrid( 10, 1.0f );
endMode3D(); if camera.fovy < finalPositionX:
camera.fovy = bounceInOut( count.float32, startPositionX,
finalPositionX - startPositionX, duration.float32 )
drawGrid( 10, 1.0f )
endMode3D()
var col = if isCursorOnScreen(): BLUE else: GRAY var col = if isCursorOnScreen(): BLUE else: GRAY
drawText( "OH SNAP IT'S WORKING\n{count}".fmt, 10, 10, 20, col ); drawText( "OH SNAP IT'S WORKING\n{count}".fmt, 10, 10, 20, col )
endDrawing(); endDrawing()
count = count + 1 count.inc
when defined( emscripten ): when defined( emscripten ):
@ -65,4 +72,3 @@ when defined( emscripten ):
else: else:
mainLoop() mainLoop()