Introduces wrappers around memory allocation functions in `memory.h`
that should be used instead of the standard C ones.
These never return NULL and, with the exception of `mem_realloc()`,
zero-initialize the allocated memory like `calloc()` does.
All allocations made with the memory.h API must be deallocated with
`mem_free()`. Although standard `free()` will work on some platforms,
it's not portable (currently it won't work on Windows). Likewise,
`mem_free()` must not be used to free foreign allocations.
The standard C allocation functions are now diagnosed as deprecated.
They are, however, available with the `libc_` prefix in case interfacing
with foreign APIs is required. So far they are only used to implement
`memory.h`.
Perhaps the most important change is the introduction of the `ALLOC()`,
`ALLOC_ARRAY()`, and `ALLOC_FLEX()` macros. They take a type as a
parameter, and allocate enough memory with the correct alignment for
that type. That includes overaligned types as well. In most
circumstances you should prefer to use these macros. See the `memory.h`
header for some usage examples.
A "category" (or "module") is now displayed with each log message
together with the source function. The name of the category is derived
from the source file name (see modname() in log.c).
Taisei now also loads a "logfilter" file from the storage directory that
controls which messages are propagated to the console. You can filter by
log level, category, and function. Simple glob pattern matching is
supported. Each line contains a new rule; empty lines and lines starting
with # are ignored. Rules are processed from top to bottom.
Example logfilter file:
# [mask] [category] [function]
# Hide debug messages by default:
-d * *
# Show debug messages from all of the rendering-related modules:
+d renderer/* *
# Also show debug messages from my specific function:
+d * my_function
# Hide info about resource loading/unloading:
-i resource unload_resource
-i resource load_resource_finish
# Suppress everything from a specific module:
-a spam *
Note that only the console output is filtered; the log file still
contains all messages. In addition to that, the log file now also
contains the filename and line number of the original log call with
every message.
"Re-records" a replay into a file. TAISEI_REPLAY_DESYNC_CHECK_FREQUENCY
is defaulted to 1 in this mode, but may be overriden as normal. Requires
-r or -R; in case of -R will not stop even if a desync is encountered.
* Split replay.c into multiple files under replay/; improve logical
separation of replay-related code.
* Separate replay playback state from data.
* Get rid of global static replay struct and avoid unnecessary replay
copying.
* Replay playback and recording are now independent and may occur
simultaneously, although this functionality is not yet exposed. This
enables replay "re-recording" while synthesizing new desync check
events, possibly at a different rate from the original replay.
* Rate of recorded desync check events can now be controlled with the
TAISEI_REPLAY_DESYNC_CHECK_FREQUENCY environment variable. The default
value is 300 as before.
* Probably other stuff I forgot about.
* WIP cutscenes
* cutscene tweaks
* cutscene: erase background drawing under text
* Make text outlines thicker
* Prepare an interface for adding new cutscenes
* Basic progress tracking for cutscenes
* cutscene: support specifying scene name and BGM
* cutscene: exit with transition after scene ends
* Implement --cutscene ID and --list-cutscenes CLI flags
* fix progress_write_cmd_unlock_cutscenes
* Play intro cutscene before entering main menu for the first time
Also added --intro parameter in dev builds to force playing the intro
cutscene
* Add intro cutscene
* cutscenes: update opening/01 scene
* add Reimu Good End
* remove Bonus Data
* split up a bit of dialogue, revert an image change in intro
* small typo
* most cutscenes complete
* smartquotify
* finish Extra intros
* new cutscenes routed into main game
* fix ENDING_ID
* rough 'mediaroom' menu
* fix cutscene menu crash
* derp
* PR changes
* fixing imports
* more PR fixes
* PR fixes, including updating the script to #255
* add in newlines for readability
Co-authored-by: Alice D <alice@starwitch.productions>
- RESF_UNSAFE is removed.
- Resources that don't have to be finalized on the main thread can load
completely asynchronously.
- A thread waiting for a concurrent task to complete can start executing
that task itself if it hasn't started yet.
- Refactor the resource loading interface, add support for load-time
dependencies.
- Main-thread finalization of asynchronously loaded resources is now
spread out across multiple frames to mitigate frametime spikes.
- Remove some archaisms from the resource management code.
- Fix potential hashtable synchronization issue.
- Fix some deadlock edge cases.
- Don't spawn more worker threads than there are CPU cores (degrades
performance).
- Add TAISEI_AGGRESSIVE_PRELOAD env variable to attempt to aggressively
discover and preload every possible resource.
- Make r_texture_fill{,_region} expect optimal pixmaps, so that it's
never forced to convert them on the main thread. The optimal format may
be queried with the new r_texture_optimal_pixmap_format_for_type API.
These functions will also no longer needlessly copy the entire image
into a staging buffer - previously they did this even if no conversion
was needed.
- Other random changes to facilitate the stuff above.
The overall effect is somewhat faster load times.
Of course it's still all terrible and full of lock contention because I
suck at concurrent programming, but it's not worse than it was.
Probably.
* Implement Robin Hood hashing
This replaces the previous separate chaining implementation. This
approach is more memory-efficient, cache-friendly, and puts much less
stress on the memory allocator.
* Replace crc32 with fnva1
Also attempt to make the compiler pre-hash as much stuff as possible at
build time.
* Major refactoring of the main loop(s) and control flow (WIP)
run_at_fps() is gone 🦀
Instead of nested blocking event loops, there is now an eventloop API
that manages an explicit stack of scenes. This makes Taisei a lot more
portable to async environments where spinning a loop forever without
yielding control simply is not an option, and that is the entire point
of this change.
A prime example of such an environment is the Web (via emscripten).
Taisei was able to run there through a terrible hack: inserting
emscripten_sleep calls into the loop, which would yield to the browser.
This has several major drawbacks: first of all, every function that
could possibly call emscripten_sleep must be compiled into a special
kind of bytecode, which then has to be interpreted at runtime, *much*
slower than JITed WebAssembly. And that includes *everything* down the
call stack, too! For more information, see
https://emscripten.org/docs/porting/emterpreter.html
Even though that method worked well enough for experimenting, despite
suboptimal performance, there is another obvious drawback:
emscripten_sleep is implemented via setTimeout(), which can be very
imprecise and is generally not reliable for fluid animation. Browsers
actually have an API specifically for that use case:
window.requestAnimationFrame(), but Taisei's original blocking control
flow style is simply not compatible with it. Emscripten exposes this API
with its emscripten_set_main_loop(), which the eventloop backend now
uses on that platform.
Unfortunately, C is still C, with no fancy closures or coroutines.
With blocking calls into menu/scene loops gone, the control flow is
reimplemented via so-called (pun intended) "call chains". That is
basically an euphemism for callback hell. With manual memory management
and zero type-safety. Not that the menu system wasn't shitty enough
already. I'll just keep telling myself that this is all temporary and
will be replaced with scripts in v1.4.
* improve build system for emscripten + various fixes
* squish menu bugs
* improve emscripten event loop; disable EMULATE_FUNCTION_POINTER_CASTS
Note that stock freetype does not work without
EMULATE_FUNCTION_POINTER_CASTS; use a patched version from the
"emscripten" branch here:
https://github.com/taisei-project/freetype2/tree/emscripten
* Enable -Wcast-function-type
Calling functions through incompatible pointers is nasal demons and
doesn't work in WASM.
* webgl: workaround a crash on some browsers
* emscripten improvements:
* Persist state (config, progress, replays, ...) in local IndexDB
* Simpler HTML shell (temporary)
* Enable more optimizations
* fix build if validate_glsl=false
* emscripten: improve asset packaging, with local cache
Note that even though there are rules to build audio bundles, audio
does *not* work yet. It looks like SDL2_mixer can not work without
threads, which is a problem. Yet another reason to write an OpenAL
backend - emscripten supports that natively.
* emscripten: customize the html shell
* emscripten: force "show log" checkbox unchecked initially
* emscripten: remove quit shortcut from main menu (since there's no quit)
* emscripten: log area fixes
* emscripten/webgl: workaround for fullscreen viewport issue
* emscripten: implement frameskip
* emscripter: improve framerate limiter
* align List to at least 8 bytes (shut up warnings)
* fix non-emscripten builds
* improve fullscreen handling, mainly for emscripten
* Workaround to make audio work in chromium
emscripten-core/emscripten#6511
* emscripten: better vsync handling; enable vsync & disable fxaa by default
* Added (and fixed) a few useful warnings
* Removed some dead code
* Cleaned up the build system files a bit
* Once again separated ZIP support from data packaging
* Converted macOS cross-compilation options into cross-file properties
* wip font rendering stuff; hashtable monstrosity is temporary
* various text rendering fixes/improvements
* HashTables™ 3.0
* Add some comments to aid navigating the hashtable macro maze
* overhaul text rendering API; add default and example shaders
* text: implement text_render for spellcard effect; misc fixes
* README: update dependencies
Bye SDL_ttf, hello freetype2.
* text_draw: fix resolution/scale-dependent bugs
* make text_draw fallback to the current shader, fix hud and stagetext
* repair the bgm loading
* fix spell practice mode
* fix walloftext
forgot one site of text_draw earlier
* fix wrapped text rendering
* fix and simplify the hud text shader
* dynamic glyph cache
* implement font size change on window resize/quality setting change/etc.
* rename text shaders for consistency
* preloads for fonts and text shaders
* make the stagetext shader look somewhat better
* text_render: attempt to normalize height
* small improvement for stagetext