487 lines
17 KiB
Text
487 lines
17 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.
|
|
|
|
- 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
|
|
-----
|
|
|
|
- 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 Apple silicon 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.
|
|
|