689 lines
29 KiB
Text
689 lines
29 KiB
Text
SINGE 3.00
|
|
==========
|
|
|
|
Unreleased
|
|
|
|
|
|
API Changes
|
|
-----------
|
|
|
|
- The name now expands to "SINGE Is Not a Game Emulator", in the banner,
|
|
the manual, INSTALL, and the Windows file description.
|
|
|
|
- Framework.singe applies the legacy sprite argument order once even when
|
|
a game loads it more than once.
|
|
|
|
- lfs.dir, lfs.attributes and lfs.symlinkattributes see inside a packed
|
|
game (the union of its loose directory, its data overlay and the
|
|
database), and lfs.mkdir and lfs.rmdir act on its data overlay, so
|
|
frameworks that list or create their own directories work packed.
|
|
|
|
- Physics. Any scene node can carry a rigid body on Jolt Physics:
|
|
static, kinematic (follows its node and pushes) or dynamic (drives its
|
|
node), shaped as a box, sphere, capsule, cylinder, a convex hull of the
|
|
node's mesh or the mesh's triangles; mass, friction, bounce,
|
|
velocities, forces and impulses; triggers; hinge, ball and slider
|
|
joints with limits; a raycast; onCollision and onTrigger callbacks.
|
|
The world steps at a fixed 60 Hz between animation and rendering and
|
|
pauses with the game. physicsSet2D keeps bodies in a plane for 2D
|
|
games, which need no GPU (nodes now exist on every machine, so a
|
|
Raspberry Pi 3 gets 2D physics without 3D). New calls: body*,
|
|
joint*, physics*, and the
|
|
BODY_*, SHAPE_* and JOINT_* constants; see the Physics chapter. Needs
|
|
SSE4.1 on x86 (2008 and later); the engine's first C++ (one wrapper
|
|
file and the library), statically linked, no runtime to install.
|
|
|
|
- Soft bodies. softNew makes cloth or a pressure body from a node's
|
|
mesh (particles from its welded vertices, Jolt's stretch, shear and
|
|
bend constraints, pressure for balloons) or a rope from the node to a
|
|
point with a tube mesh the engine makes; they collide with everything
|
|
rigid and the mesh is rewritten every frame. softPin holds particles
|
|
in place or to nodes; stiffness, mass, damping and pressure are
|
|
tunable. meshPlane takes subdivisions; nodeSetMaterial changes a
|
|
material without the mesh. New calls: soft*, and the SOFT_*
|
|
constants; see Soft bodies in the Physics chapter.
|
|
|
|
- Ragdolls. ragdollNew derives capsules and swing-twist joints from a
|
|
skinned model's skeleton; ragdollActivate hands the skeleton to
|
|
physics from its current pose and the mesh follows the bones as it
|
|
falls; motors (ragdollSetStrength) pull it back toward that pose;
|
|
ragdollApplyImpulse shoves a bone; ragdollDeactivate returns it to
|
|
animation. New calls: ragdoll*; see Ragdolls in the Physics chapter.
|
|
|
|
- Water. bodySetWater fills a static body with water: dynamic bodies
|
|
inside float, sink and drift by Jolt's buoyancy against its surface,
|
|
with drag and a current (bodySetCurrent, bodySetBuoyancy per body);
|
|
players swim in it (playerIsSwimming, playerSetSwim, three-axis
|
|
playerMove); a buoyant hull with vehicleNew(node, VEHICLE_BOAT) gets
|
|
a propeller and a rudder (vehicleSetThrust, vehicleSetRudder).
|
|
|
|
- Vehicles. A dynamic body becomes a car, a motorcycle or a tank on
|
|
Jolt's vehicle constraint: wheels are nodes the engine poses (spin,
|
|
steer, suspension), the script drives with throttle, steering, brake
|
|
and hand brake, and engine, gears, suspension, steering, brakes and
|
|
anti-roll bars are tunable. Motorcycles lean and balance with a spring
|
|
scaled to the chassis; tanks pivot on the spot. New calls: vehicle*,
|
|
and the VEHICLE_* constants; see Vehicles in the Physics chapter.
|
|
|
|
- Point lights inside geometry. A bulb in a closed room, under a shade
|
|
or inside a cabinet now shadows correctly: cube faces render depth
|
|
two-sided so closed meshes cast from inside, every shadow tap picks its
|
|
own cube face so the seams along the cube edges are gone, the depth
|
|
range fits the casters round the light instead of the scene centre,
|
|
the bias grows with distance and grazing angle, and each face draws
|
|
only what it can see. nodeSetShadow excuses a mesh from casting.
|
|
|
|
- Character controller. playerNew puts Jolt's CharacterVirtual on a
|
|
node, as a capsule or any convex bodyNew shape: it walks where
|
|
playerMove says, climbs steps, slides along walls, refuses steep
|
|
slopes, falls, jumps from the ground, rides kinematic platforms and
|
|
shoves light dynamic bodies; onCollision and onTrigger report it like
|
|
a body. Works in 2D worlds as a platformer character, with tolerances
|
|
scaled to the shape. New calls: player*; see Players in the Physics
|
|
chapter.
|
|
|
|
- Linear lighting. The scene is lit in linear light on a 16-bit float
|
|
target and brought to the screen by a post pass with an exposure
|
|
control (sceneSetExposure, in stops) and a tone curve (sceneSetTonemap:
|
|
TONEMAP_NEUTRAL, TONEMAP_ACES, TONEMAP_NONE). Colours given as 0-255
|
|
are sRGB and decoded on the way in; textures are sampled as sRGB;
|
|
bright light compresses instead of clipping. Specular highlights are
|
|
GGX with Fresnel, so roughness and metallic behave as they do in glTF
|
|
viewers. Existing scenes look a little different: the same numbers
|
|
now mean what they mean everywhere else.
|
|
|
|
- Physics debug drawing. physicsSetDebug(DEBUG_*) draws the bodies in
|
|
wireframe (coloured by motion state), joints and their limits, contact
|
|
points and velocities as lines over the scene each frame, static shapes
|
|
too with DEBUG_STATIC; lineDraw draws a script's own world-space lines
|
|
for a frame, navDraw the baked navigation mesh.
|
|
|
|
- Compressed textures. KTX2 files (Basis Universal, from
|
|
util/compressTextures.py) stay compressed on the GPU in the block
|
|
format the machine has (BC7, ASTC, BC3, or plain RGBA where nothing
|
|
else exists), a quarter of the memory of PNGs or less. A model whose
|
|
file uses KHR_texture_basisu loads them on its own; materialSetTexture
|
|
and the map calls take a .ktx2 name in place of a sprite; sceneGetStats
|
|
reports the texture memory in use. The Sponza test scene went from
|
|
393 MB of textures to 99 MB.
|
|
|
|
- Hot reload. singe --reload (-R) watches the game's loose script files
|
|
and runs the game again from its script when one changes; F5 does the
|
|
same, and singeReload() from a script. The engine (window, GPU, disc,
|
|
controllers) stays; everything the script made is remade by the script.
|
|
|
|
- Terrain. meshHeightmap makes rolling ground from a greyscale image,
|
|
materialSetTiling repeats a texture across it, a SHAPE_MESH body on it
|
|
becomes a Jolt height field, and terrainGetHeight reads the ground
|
|
height at a point.
|
|
|
|
- Sprites and text in the scene. nodeSetSprite shows a loaded sprite on
|
|
a node as a lit quad (nodeSetSpriteFrame picks a frame), nodeSetText a
|
|
line of text in the selected font, and nodeSetBillboard turns any node
|
|
to face the camera squarely or about its own up axis (BILLBOARD_*).
|
|
|
|
- Navigation. navNew, navAddNode and navBuild bake a walkable mesh from
|
|
the scene's geometry on Recast; navPath, navNearest, navRaycast and
|
|
navRandomPoint query it on Detour; agents (navAgentNew, navAgentMoveTo,
|
|
navAgentStop, navAgentGetVelocity, navAgentIsArrived, navAgentSetPlayer)
|
|
walk it on DetourCrowd without walking through each other, moving their
|
|
nodes or driving a player controller, with onNavArrived when they get
|
|
there; navSave and navLoad keep a baked mesh. Recast Navigation is
|
|
vendored under thirdparty/recastnavigation (zlib licence).
|
|
|
|
- Bloom and views. sceneSetBloom makes everything brighter than a
|
|
threshold glow, blurred over a half-size chain before the tone curve.
|
|
viewNew renders a second camera to a texture every frame (viewSetCamera
|
|
points it) that materialSetView shows on any surface: monitors,
|
|
mirrors, portals.
|
|
|
|
- Particle extras. Trails (emitterSetTrail: a fading ribbon behind
|
|
each particle, 2D and 3D), collisions with a floor or, by ray cast,
|
|
the physics world (emitterSetCollide, COLLIDE_*), lit particles shaded
|
|
by the lights and sky (emitterSetLit) and soft particles that fade
|
|
where they meet geometry (emitterSetSoftness).
|
|
|
|
- Culling and instancing. Meshes outside the camera's view are skipped,
|
|
and copies of one mesh with one material draw as a single instanced
|
|
call (their matrices in a per-frame buffer the vertex shaders read), in
|
|
the shadow passes too. sceneGetStats reports the draws collected, the
|
|
draws in view and the draw calls made.
|
|
|
|
- Cascaded shadows. A directional light's shadow is split into up to
|
|
four maps along the view (sceneSetShadowCascades, three by default),
|
|
each fitted to a slice of the camera's view out to
|
|
sceneSetShadowDistance and snapped to its texels, so shadows in a
|
|
large level are sharp up close and steady as the camera moves.
|
|
|
|
- Sky, environment light and fog. sceneSetSky wraps the scene in an
|
|
equirectangular panorama (Radiance .hdr, PNG or JPEG) drawn behind
|
|
everything and lighting it: its diffuse light replaces the ambient and
|
|
its reflections show on metals and glossy surfaces, blurred by
|
|
roughness (sceneSetEnvironment switches that off, sceneSetSkyIntensity
|
|
scales it). sceneSetFog fades meshes and particles toward a colour
|
|
between two distances.
|
|
|
|
- Positional sound. A playing channel can follow a scene node
|
|
(soundSetNode) or sit at a point (soundSetPosition) and is then panned
|
|
and faded by distance (soundSetRange) as heard from the camera or a
|
|
chosen node (soundSetListener); soundGetPosition reports where it lies;
|
|
soundSetPan pans a channel for 2D games; soundPlay takes a loop count.
|
|
|
|
- Animation blending. animationPlay takes a fade in seconds and
|
|
crossfades from the clip that was playing, or from the pose the nodes
|
|
are in when nothing was (so a ragdoll eases back up); up to four clips
|
|
play on layers above the base (animationPlayLayer), each with a weight
|
|
(animationSetLayerWeight) and an optional mask limiting it to part of
|
|
the skeleton (animationSetLayerMask); animationStop takes a layer.
|
|
|
|
- Material maps. A material can carry a normal map, an occlusion map, a
|
|
metallic-roughness map (glTF's packing) and an emissive map beside its
|
|
base texture, and a loaded model brings its own. Every mesh has
|
|
tangents: a model's when the file carries them, computed from the UVs
|
|
otherwise. New calls: materialSetNormalMap, materialSetOcclusionMap,
|
|
materialSetMetallicRoughnessMap, materialSetEmissiveMap.
|
|
|
|
- Mipmaps. Every scene texture carries a full mipmap chain generated on
|
|
the GPU at load and is sampled with anisotropic filtering, so textures
|
|
seen small or at a grazing angle no longer sparkle or moire.
|
|
materialSetFilter(material, FILTER_NEAREST) keeps pixel art crisp.
|
|
|
|
- Particles. Emitters spawn, move and age particles from a recipe (rate,
|
|
life, speed, direction and spread, gravity, drag, size, colour and spin
|
|
over life, a birth radius, a pool cap) in the overlay and in the 3D
|
|
scene alike. A 2D emitter draws on the GPU above or beneath the
|
|
overlay when the script asks (emitterDraw); a 3D emitter sits on a node
|
|
and draws camera-facing billboards after every mesh, depth tested, in
|
|
world units. Any loaded sprite is the picture (a random frame per
|
|
particle from an animated one); without one, a soft disc. Normal or
|
|
additive blending. New calls: emitter*, and the PARTICLE_* constants;
|
|
see the Particles chapter.
|
|
|
|
- 3D scenes. A game can draw a 3D scene between the disc video and the
|
|
overlay: primitive meshes and script-built geometry, materials with
|
|
colour, textures from sprites, the disc or a loaded video, metallic and
|
|
roughness, up to eight lights each able to cast shadows (cube maps for
|
|
point lights), any node as the camera, and glTF 2.0
|
|
models (.glb, self-contained) with node animation, skinning and morph
|
|
targets, placed any number of times. Everything is a node in one tree. New calls:
|
|
scene*, node*, mesh*, material*, light*, camera*, model*, animation*,
|
|
and the LIGHT_* constants; see the 3D Scenes chapter of the manual.
|
|
Needs a GPU with Vulkan, Direct3D 12 or Metal; the Raspberry Pi 4 is
|
|
the minimum Pi (the Pi 3 has no Vulkan driver). 2D games run as
|
|
before without one. The renderer now runs on
|
|
SDL's GPU device where there is one.
|
|
|
|
- A game can be one file: singe --pack DIRECTORY GAME.game writes the game's
|
|
scripts, art, sounds, fonts, and video into an SQLite database, and
|
|
singe GAME.game (or the menu, which lists every .game file beside the game
|
|
directories) runs it. Nothing in a game has to change to be packed:
|
|
every name a script uses (dofile, require, io.open and friends,
|
|
spriteLoad, soundLoad, fontLoad, videoLoad, framefiles, controls.cfg)
|
|
goes through one lookup that tries a loose directory named like the
|
|
database, then the game's data directory, then the database, so
|
|
packed games can be modded by dropping files beside them and files a
|
|
game writes land under data/<game>/files. Inside a database names
|
|
are matched without regard to case and a leading own-directory prefix
|
|
("DLe/Cfg/x") is ignored. singe --unpack GAME.game DIRECTORY restores
|
|
the files and singe --patch GAME.game SOURCE replaces files from a
|
|
directory or a patch database in one transaction. --entry=N picks
|
|
which games.dat entry a .game launch runs. Loose games are
|
|
untouched by all of this. Scripts get SQLite for their own data with
|
|
require("sqlite3"). The archive installer (.game, .tool, and .patch
|
|
archives dropped beside the binary) is gone along with libarchive; a
|
|
game is a .game file or a directory, copied into place.
|
|
|
|
- Video is decoded by libavcodec directly; FFMS2 is gone. Seeking is still
|
|
frame exact, indexing is faster, and the index files in the data
|
|
directory use a new format (old ones are rebuilt automatically).
|
|
Multi-channel audio is downmixed to stereo instead of refused. Indexing
|
|
is a few seconds at most, so the indexing screen and its artwork are gone.
|
|
Video is
|
|
decoded by the platform's hardware decoder when there is one (VA-API or
|
|
VDPAU on Linux, D3D11VA on Windows, VideoToolbox on macOS) and falls
|
|
back to software otherwise; --softwarevideo forces software.
|
|
|
|
- Singe is built on SDL3 (SDL 3.4, SDL3_image, SDL3_mixer 3.2, SDL3_ttf)
|
|
instead of SDL2. Nothing changes for scripts: the same functions,
|
|
constants, scancodes, and controls.cfg names. SDL2_gfx is gone; sprite
|
|
and video rotation and scaling are done by the engine itself.
|
|
|
|
- The sprite handle is now the FIRST argument of spriteDraw(), spriteLoop(),
|
|
spriteQuality(), spriteRotate(), spriteRotateAndScale(), spriteScale(), and
|
|
spriteSetFrame(), matching the video*() functions. Move the last argument
|
|
of each call to the front. Games that cannot be edited can set
|
|
SINGE_LEGACY_SPRITE_ARGS = true before loading the framework, or add
|
|
LEGACY_SPRITE_ARGS = true to their games.dat entry. See "Migrating from
|
|
Singe 2.10" in the manual.
|
|
|
|
- Singe is no longer laserdisc only. A games.dat entry with a VIDEO is a
|
|
laserdisc game; one with the line missing or blank runs without a
|
|
disc, on a canvas sized by CANVAS_X/CANVAS_Y (default 720x480), the
|
|
disc functions become harmless, and discGetState() returns the new
|
|
DISC_EJECTED. On the command line --disc (implied by --framefile)
|
|
declares the disc, since a video found beside the script no longer
|
|
does; --canvas=WxH sizes the canvas. Existing games.dat files need no
|
|
change. Scripts can test SINGE_DISC.
|
|
|
|
- mouseSetEnabled(bool) and singeSetPauseKeyEnabled(bool) added. The old
|
|
mouseEnable/mouseDisable and singeEnablePauseKey/singeDisablePauseKey are
|
|
now aliases defined in Framework.singe.
|
|
|
|
- Handles, counts, and frame numbers are returned as Lua integers.
|
|
videoIsPlaying() returns a boolean. mouseSetMode() returns nothing.
|
|
|
|
- onControllerMoved() receives the controller index (0 to 3), not SDL's
|
|
instance ID. onMouseMoved() in MANY_MOUSE mode receives real relative
|
|
motion in its third and fourth arguments.
|
|
|
|
- Runtime errors inside callbacks now end the game with a traceback, the way
|
|
argument errors always have.
|
|
|
|
- Held keys no longer auto-repeat in MODE_NORMAL.
|
|
|
|
- The engine parks the disc on frame 1 before the script runs; the framework
|
|
no longer seeks when it is loaded, so threaded games keep their own
|
|
startup positioning.
|
|
|
|
- The pause key now pauses the whole game. The engine freezes the script
|
|
(no callbacks, no singeMain), holds sound completions, releases and later
|
|
re-presses held inputs, and draws a PAUSED indicator. It acts on the key
|
|
press, and SWITCH_PAUSE reaches the script only when the key is disabled
|
|
with singeSetPauseKeyEnabled(false). singeSetPauseFlag() still pauses
|
|
media without freezing the script. Gamepad and mouse buttons mapped to
|
|
pause, quit, screenshot, or grab now work in MODE_FULL too; keyboard
|
|
mappings stay raw there.
|
|
|
|
- Video decoding runs on its own thread per video, so a discSearch() far
|
|
from a keyframe no longer stalls the game loop; the previous frame stays
|
|
on screen until the new one is ready. The laserdisc and framefile videos
|
|
are handed to the GPU as YUV and converted there instead of on the CPU,
|
|
and each video reports its keyframe spacing to the program trace when
|
|
loaded, with a warning there when seeks may be slow.
|
|
|
|
- Constants that used to be duplicated in Framework.singe (SWITCH_*,
|
|
FONT_QUALITY_*, MODE_*, MOUSE_*, OVERLAY_*, RENDER_*, SOUND_ERROR_*) are
|
|
now defined by the engine. New: DISC_STOPPED/DISC_PLAYING/DISC_PAUSED
|
|
for discGetState(), SINGE_VERSION_MAJOR/MINOR/STRING, and the SINGE_*
|
|
input code layout that Framework.singe builds GAMEPAD_N and MOUSE_N from.
|
|
|
|
- Audio and video are kept in sync from the audio clock. The engine
|
|
measures the audio device's queue at startup instead of guessing, uses
|
|
small mixer buffers, and honours a container whose first video frame is
|
|
timestamped after its first audio sample. For delay the engine cannot
|
|
see (receivers, Bluetooth, DACs) there is singeSetAudioDelay(ms) /
|
|
singeGetAudioDelay(), the games.dat key AUDIO_DELAY, and
|
|
--audiodelay=MS; positive values mean the audio is heard late.
|
|
|
|
- The menu has an audio delay calibration screen for the machine's own
|
|
delay (DAC, receiver, Bluetooth, display). Press the service key on
|
|
the game list; a click plays once a second and the screen flashes.
|
|
Adjust with the stick until the flash and the click coincide, then
|
|
press button 1 to save. The value is kept in audio.cfg in the data
|
|
root and applied to every game on the machine, from the menu or the
|
|
command line, on top of any per-game AUDIO_DELAY. Scripts can read and
|
|
set it with singeGetAudioCalibration() / singeSetAudioCalibration(),
|
|
read the measured device queue with singeGetAudioLatency(), and now
|
|
have singeGetTicks() for a wall clock in milliseconds (os.clock() is
|
|
processor time and drifts).
|
|
|
|
|
|
Fixes
|
|
-----
|
|
|
|
- The manual's 3D Scenes, Physics and Particles chapters are rewritten as
|
|
sections in a learning order with worked examples, every reference
|
|
entry now shows each form the call accepts with a realistic example,
|
|
and prose spelling is American throughout. Manual.pdf and Manual.html
|
|
are rendered into .builddir/ by the build and by build-docs.sh alike,
|
|
and the binary embeds the PDF from there.
|
|
|
|
- controllerGetButton() never worked; it rejected every framework button
|
|
code.
|
|
|
|
- The five argument form of spriteDraw() always failed.
|
|
|
|
- spriteSetFrame() on a still image crashed.
|
|
|
|
- Unloading the selected font left later fontPrint() calls using freed
|
|
memory.
|
|
|
|
- overlayCircle() drew around the origin instead of the requested center.
|
|
|
|
- overlaySetResolution() broke mouse coordinates and vldpGetPixel() because
|
|
the overlay scale was computed with integer division.
|
|
|
|
- mouseGetPosition() always returned 0,0 and controllerGetAxis() read the
|
|
wrong controller because the axis cache was indexed two different ways.
|
|
|
|
- Analog stick release events fired with a stale input code. Controllers
|
|
that were unplugged and replugged shifted their codes.
|
|
|
|
- The -o/--audio option was lost when the configuration was copied.
|
|
|
|
- --option=value forms of numeric options, and options after the script
|
|
name, were not accepted.
|
|
|
|
- Running "singe game.singe" from the game's own directory wrote its data
|
|
to the filesystem root.
|
|
|
|
- Framefile playback never advanced past the first segment, and switching
|
|
segments dropped the selected audio track.
|
|
|
|
- Video timing accumulated main loop latency, drifting behind the audio.
|
|
Audio is now the master clock: the picture follows the samples the sound
|
|
device has actually consumed, so the two cannot drift apart and the
|
|
mixer's buffering latency is accounted for. Silent videos follow the wall
|
|
clock. The first frame after a seek was shown one update late.
|
|
|
|
- Video without an audio track crashed on the first update.
|
|
|
|
- The video audio stream was shared with the mixer thread without a lock.
|
|
|
|
- onSoundCompleted was called from the audio thread. It is now delivered
|
|
from the game loop.
|
|
|
|
- Screenshots read the frame buffer through the window surface, which SDL
|
|
forbids alongside a renderer, and could corrupt memory on shutdown.
|
|
|
|
- .patch archives crashed the installer. Archives without an explicit top
|
|
level directory entry were rejected. Extraction now refuses paths that
|
|
escape the installation directory.
|
|
|
|
- The Sinden gun arguments could overflow the configuration structure.
|
|
|
|
- Support files in the Singe directory are refreshed when the installed
|
|
copy differs from the running build. Upgrading the binary used to keep
|
|
the old Framework.singe and Menu.singe forever.
|
|
|
|
- The menu background video is encoded with a keyframe every second, so
|
|
the menu's jump to the game list is instant.
|
|
|
|
- Framefiles whose first line is a relative directory produced garbage
|
|
video paths (the directory string was freed before use); a lone "." now
|
|
means the framefile's own directory.
|
|
|
|
- A crash prints a backtrace to the console (Linux and macOS) so a report
|
|
can say where it happened; run with --program and send trace.txt too.
|
|
|
|
- Mouse positions are delivered in the video's coordinates again (SDL3
|
|
stopped scaling them for us), so crosshairs follow the pointer.
|
|
|
|
- os.clock() in scripts now returns wall time rather than processor time.
|
|
Nearly every existing game times its input debounces and prompts with
|
|
it; once the GPU decodes the video the engine mostly sleeps, and those
|
|
timers ran seconds slow. A game that wanted processor time is not
|
|
known to exist. This diverges from stock Lua and from other Singe
|
|
runtimes; new code that must be portable should use singeGetTicks().
|
|
|
|
- A key or button still held when a game exits no longer counts as a
|
|
press in the script that follows. Confirming Exit in a game with
|
|
button 1 used to relaunch it from the menu.
|
|
|
|
- Audio ran late by the device queue depth on most Linux audio servers:
|
|
the clock assumed one mixer buffer of latency where PulseAudio and
|
|
PipeWire hold several. See the audio sync entry above.
|
|
|
|
- Windows builds now carry the icon and version resource, with the version
|
|
number encoded correctly.
|
|
|
|
- The build no longer depends on lyx, upx, or xxd; embedded resources, the
|
|
version header, and the manual are generated by CMake. The manual is
|
|
embedded again and extracted as Singe/Manual.pdf.
|
|
|
|
- One command builds Singe from a clean checkout on a Debian based
|
|
system: ./build-all.sh <platform> <arch> installs the host packages,
|
|
then CMake fetches zig (the compiler for every target), the Pi's
|
|
platform packages and the macOS SDK into .builddir/toolchains and
|
|
builds every library and Singe itself. The results are a Linux binary
|
|
that runs on glibc 2.28 or newer, a Windows 10 or newer binary, a
|
|
64-bit Raspberry Pi OS (bullseye or newer) binary and a macOS 13 or
|
|
newer universal (Apple silicon and Intel) binary. The toolchains repository is no longer
|
|
needed. See INSTALL.
|
|
|
|
|
|
SINGE 2.10
|
|
==========
|
|
|
|
Released March 26th, 2024
|
|
|
|
|
|
New Features
|
|
------------
|
|
|
|
- spriteDraw() now has two more forms. In addition to being able to draw
|
|
regular sprites and stretched sprites it can now draw both using the
|
|
sprite's center as the anchor instead of the upper left. This is highly
|
|
useful when dealing with rotated sprites.
|
|
|
|
- Animated sprites! Both animated GIF and WEBP images are supported.
|
|
|
|
- Sprite anti-aliasing, scaling and rotation! Optional separate X & Y scaling.
|
|
|
|
- Video anti-aliasing, scaling and rotation! Optional separate X & Y scaling.
|
|
|
|
- Multiple audio track support for videos. New command line options to select
|
|
which default audio track you want (-o or --audio). For games with multiple
|
|
languages, you can specify AUDIO_TRACK in the games.dat as well.
|
|
|
|
- New keyboard methods to make handling input easier, especially multiple
|
|
keypresses for diagonal movement.
|
|
|
|
- controllerGetButton() added.
|
|
|
|
- SINGE_DEAD_ZONE global variable now available based on the DEAD_ZONE
|
|
controller configuration option.
|
|
|
|
- SINGE_FRAMEWORK_VERSION variable added.
|
|
|
|
- DIR variable added providing directory to the running script.
|
|
|
|
- All new Lua library handling. Previously Singe "injected" libraries
|
|
directly into the script context. Now there is a proper Lua module search
|
|
handler. Scripts can properly require() modules from the following:
|
|
- Lua Standard Library
|
|
- Lua Auxiliary Library
|
|
- LuaFileSystem
|
|
- LuaSocket
|
|
- LuaSec
|
|
- LuaRS232
|
|
- timerwheel
|
|
- binaryheap
|
|
- Copas
|
|
- json
|
|
|
|
- New command line option: -p (or --program). This is similar to the
|
|
existing -t (or --trace) option. Where "trace" displays and logs script
|
|
execution, "program" displays and logs Singe internals. This should make
|
|
troubleshooting difficult setups and odd script crashes easier.
|
|
|
|
- Auto-installer for the new GAME, TOOL, and PATCH archive formats to make
|
|
managing games easier.
|
|
|
|
- ZeroBrane Studio (https://studio.zerobrane.com) integration for live
|
|
debugging of running Singe scripts! A full IDE for developing games!
|
|
|
|
|
|
Fixes
|
|
-----
|
|
|
|
- USB controllers now work in games launched from the included menu.
|
|
|
|
- Default controller DEAD_ZONE increased.
|
|
|
|
- Framework.singe was missing keyboard mode constants. MODE_NORMAL and
|
|
MODE_FULL are now included.
|
|
|
|
- SINGE 2.00 added two new input events but never had them in the framework.
|
|
SWITCH_BUTTON4 and SWITCH_TILT are now available.
|
|
|
|
- Taking screenshots could sometimes crash Singe.
|
|
|
|
- PNG files no longer generate warnings on the console.
|
|
|
|
- Non-VLDP videos now honor command line volume settings.
|
|
|
|
- Menu system now performs "natural sorting" of game titles instead of brain
|
|
dead "computer sorting". It should make a lot more sense paging through
|
|
games now.
|
|
|
|
- Building Singe depended on a lot of undocumented software cobbled together
|
|
from other projects. This has been vastly improved and should be usable by
|
|
actual humans now. Humans running Linux anyway.
|
|
|
|
|
|
------------------------------------------------------------------------------
|
|
|
|
|
|
SINGE 2.00
|
|
==========
|
|
|
|
Released October 25th, 2020
|
|
|
|
|
|
New Features
|
|
------------
|
|
|
|
- Complete rewrite! No more dependency on Daphne.
|
|
|
|
- Support for almost every (non-patent encumbered) video and audio format
|
|
that can be played by FFMPEG.
|
|
|
|
- High definition video.
|
|
|
|
- 32 bit color.
|
|
|
|
- Additional videos can be played on top the laserdisc video.
|
|
|
|
- Scaled sprites.
|
|
|
|
- Graphics overlay resolution no longer dependent on video resolution.
|
|
|
|
- Analog controllers.
|
|
|
|
- LuaSocket and LuaFileSystem added to runtime.
|
|
|
|
- Ability to chain scripts together for menus or launchers.
|
|
|
|
- Specify if you want gun games to display on-screen crosshairs or not.
|
|
|
|
- Menu for launching games included.
|
|
|
|
- Many updates to Framework.singe to support the new APIs.
|
|
|
|
- New APIs:
|
|
- controllerGetAxis
|
|
- discGetHeight
|
|
- discGetWidth
|
|
- fontUnload
|
|
- mouseGetPosition
|
|
- mouseSetCaptured
|
|
- overlayBox
|
|
- overlayCircle
|
|
- overlayEllipse
|
|
- overlayLine
|
|
- overlayPlot
|
|
- overlaySetResolution
|
|
- scriptExecute
|
|
- scriptPush
|
|
- singeWantsCrosshairs
|
|
- soundUnload
|
|
- spriteGetHeight
|
|
- spriteGetWidth
|
|
- spriteUnload
|
|
- videoDraw
|
|
- videoGetFrame
|
|
- videoGetFrameCount
|
|
- videoGetHeight
|
|
- videoGetVolume
|
|
- videoGetWidth
|
|
- videoIsPlaying
|
|
- videoLoad
|
|
- videoPause
|
|
- videoPlay
|
|
- videoSeek
|
|
- videoSetVolume
|
|
- videoUnload
|
|
|
|
|
|
------------------------------------------------------------------------------
|
|
|
|
|
|
SINGE 1.14 - 1.19
|
|
=================
|
|
|
|
Released ?
|
|
|
|
|
|
Notes
|
|
-----
|
|
|
|
- Unofficial fan builds.
|
|
- Stand-alone releases.
|
|
|
|
|
|
New Features
|
|
------------
|
|
|
|
- New API functions:
|
|
- discPauseAtFrame
|
|
- mouseEnable
|
|
- mouseDisable
|
|
- mouseHowMany
|
|
- mouseSetMode
|
|
- singeDisablePauseKey
|
|
- singeEnablePauseKey
|
|
- singeGetScriptPath
|
|
- singeSetGameName
|
|
- soundFullStop
|
|
- soundGetVolume
|
|
- soundIsPlaying
|
|
- soundPause
|
|
- soundResume
|
|
|
|
|
|
------------------------------------------------------------------------------
|
|
|
|
|
|
SINGE 1.10 - 1.14
|
|
=================
|
|
|
|
Released ?
|
|
|
|
|
|
Notes
|
|
-----
|
|
|
|
- Unofficial fan builds.
|
|
- DLL releases for Daphne.
|
|
|
|
|
|
New Features
|
|
------------
|
|
|
|
- New API functions:
|
|
- discGetState
|
|
- keyboardGetMode
|
|
- keyboardSetMode
|
|
- singeGetPauseFlag
|
|
- singeSetPauseFlag
|
|
- singeQuit
|
|
- singeVersion
|
|
- soundStop
|
|
|
|
|
|
------------------------------------------------------------------------------
|
|
|
|
|
|
SINGE 1.00
|
|
==========
|
|
|
|
Released 2006
|
|
|
|
|
|
Notes
|
|
-----
|
|
|
|
- Original add-on for Daphne.
|
|
- Shipped with the ActionMax "emulator" and games.
|
|
|