Commit graph

210 commits

Author SHA1 Message Date
Andrei Alexeyev
b7f47e6580
replay/tsrtool: add a basic CLI replay editor 2023-06-17 21:53:48 +02:00
Andrei Alexeyev
b3025ad921
cli,main,progress: add --unlock-all flag for dev builds
Permanently unlocks all content
2023-05-29 00:48:50 +02:00
Andrei Alexeyev
a842150d6d
main: fix game exiting after intro
Broken by bad copypaste in e6fffc6b5f
2023-05-19 20:17:18 +02:00
Andrei Alexeyev
e6fffc6b5f
cli: add --populate-cache
Searches the VFS for resources and attempts to load them all, then
exits. Intended to fully populate the persistent cache.
2023-05-08 10:05:21 +02:00
Andrei Alexeyev
9dade8ad33
resource: lifetime management redesign (WIP) 2023-04-29 20:01:50 +02:00
Andrei Alexeyev
ad295005db
resource: more consistent API function names 2023-04-29 20:01:50 +02:00
Andrei Alexeyev
57a08d4c7a
replay/demoplayer: automatic "demo" playback when idling in menus
Currently the game comes with no demos; place your own replays into
$userdir/resources/demos if you want to test this.
2023-04-07 16:08:50 +02:00
Andrei Alexeyev
27a1a6fc7a
transition: use the callchain system for callbacks 2023-04-07 16:08:49 +02:00
Andrei Alexeyev
886ba290a9
util/callchain: split from eventloop 2023-04-07 16:08:49 +02:00
Andrei Alexeyev
df6b97caf7
stageobjects,objectpool: simplify and reimplement on top of arenas
All pools now allocate from the same arena that is initialized once with
8MB of initial space and never deallocated, only reset between stages.
2023-04-07 16:08:49 +02:00
Andrei Alexeyev
bae08cd0a0
main: init coroutines before log
Without this cotask_active() is called before co_main is set, which
trips up ASan.
2023-03-31 03:25:16 +02:00
Andrei Alexeyev
e957f11790
thread: add over-engineered wrapper for thread management 2023-03-29 20:47:27 +02:00
Andrei Alexeyev
76bd4d88b2
refs: nuke from orbit 2023-02-24 05:37:58 +01:00
Andrei Alexeyev
b6978178b1
memory: use custom memory allocation wrappers
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.
2023-01-18 13:23:22 +01:00
Andrei Alexeyev
26662582df
log: add categories and filtering functionality
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.
2022-09-01 06:02:29 +02:00
Andrei Alexeyev
90cc06b98e
main: disable SDL_HINT_EMSCRIPTEN_ASYNCIFY on emscripten
We don't rely on this functionality
2022-02-18 13:23:14 +02:00
Andrei Alexeyev
dcb630b37d
stageinfo,stage: implement stage hot-reloading
POSIX platforms only. Must be enabled via -Dstages_live_reload=true.
2022-02-05 17:58:42 +02:00
Andrei Alexeyev
8974f952f5
resource: groundwork for live reload support 2022-01-02 08:28:11 +02:00
Andrei Alexeyev
e629d927ba
filewatch: add filewatch module for basic file monitoring
Currently only an inotify-based backend is implemented.
2022-01-02 08:28:11 +02:00
Andrei Alexeyev
041f79561f
main: fix memleak when restarting in single-stage mode 2021-10-25 14:25:33 +03:00
Andrei Alexeyev
3d4226ce04
replay/cli: --rereplay option
"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.
2021-06-16 01:43:10 +03:00
Andrei Alexeyev
173c8c3cc6
replay: general refactor
* 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.
2021-06-16 01:43:10 +03:00
Andrei Alexeyev
806b0d8440
main: fix eventloop_run() being called twice
This was inconsequential for desktop, but breaks badly on emscripten
2021-04-21 04:44:24 +03:00
Andrei Alexeyev
248b96e95d
rwops_zlib: remove unused API 2021-03-23 09:46:26 +02:00
Andrei Alexeyev
9b5d515721
Cutscenes (#249)
* 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>
2020-11-28 12:11:10 +02:00
Andrei Alexeyev
103079496e
GameMode integration (#258) 2020-11-19 01:12:51 +02:00
Andrei Alexeyev
ae8194ae78
Various fixes & improvements for concurrent loading (#235)
- 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.
2020-06-09 03:01:53 +03:00
Andrei Alexeyev
00e4837827
Separate StageInfo-related APIs from game-stage code (#227) 2020-05-16 23:41:54 +03:00
Alice D
56e64498a6
Player Statistics (#219) 2020-04-26 22:27:13 +03:00
Andrei Alexeyev
0cbc86c66e
Add generic type-safe facility for dynamic arrays (#207)
Replace most ad-hoc opencoded dynamic arrays across the codebase
2020-04-05 05:51:00 +03:00
Andrei Alexeyev
0fdea86be1
Implement Robin Hood hashing (#200)
* 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.
2020-03-17 10:09:49 +02:00
Andrei Alexeyev
bdef62d7f4
Initial coroutine/task system implementation 2020-03-04 21:50:22 +02:00
Andrei Alexeyev
6a72d4a637
Add env variable TAISEI_SDL_LOG (enables SDL log at given priority) 2019-11-08 21:05:40 +02:00
Andrei Alexeyev
b88fc4ad2e
Support full-screen custom postprocessing
Works just like the viewport one, except the configuration goes in
shaders/global.pp instead. The player uniforms aren't available.
2019-08-09 21:42:04 +03:00
Andrei Alexeyev
5a23fb95fc
make upkeep script preserve existing copyrights 2019-08-03 20:44:22 +03:00
Andrei Alexeyev
3055901998
update my email 2019-07-03 21:00:56 +03:00
Andrei Alexeyev
c7ff531a63
fixup includes 2019-03-18 06:41:12 +02:00
Andrei Alexeyev
cc6514151a
Implement seeking in zip files without reading everything to memory
In particular, this greatly reduces memory usage for music tracks.
2019-03-16 22:11:37 +02:00
Andrei Alexeyev
75ee08535b
fix a few memory leaks 2019-03-09 23:58:42 +02:00
Andrei Alexeyev
180f9e3856
Emscripten compatibility (#161)
* 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
2019-03-09 21:32:32 +02:00
Andrei Alexeyev
abe4ddf260
refactor audio (module system like that of renderer) 2019-03-05 21:43:01 +02:00
Andrei Alexeyev
c8e057e388
basic emscripten compat and various fixes 2019-02-22 01:56:48 +02:00
Andrei Alexeyev
8fc5abb78a
The Powersurge game mechanic and scoring system (#159) 2019-02-22 01:56:03 +02:00
Andrei Alexeyev
b91b85c42a
Logging: colors, non-fatal error level, alt. format for log file
Also removed traceback support entirely as it never produced useful
output.
2019-02-15 01:58:40 +02:00
Andrei Alexeyev
fa802dbd94
Some refactoring
* 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
2019-01-24 22:24:43 +02:00
Andrei Alexeyev
4159ea1249
'upkeep' target for maintenance tasks; back to include guards; happy new year! 2019-01-23 22:10:43 +02:00
Andrei Alexeyev
69079f245a
dubious timing optimizations; try to sleep between frames; skip at constant speed 2019-01-09 05:25:10 +02:00
Andrei Alexeyev
3937618c84
Kick SDL_image's ass out and replace JPEG with WebP 2018-10-19 00:16:06 +03:00
Andrei Alexeyev
ed2fd0f969
fix -t segfault 2018-07-25 07:46:04 +03:00
Andrei Alexeyev
322edd0dce
Text rendering rewrite and optimizations; some refactoring (#129)
* 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
2018-06-30 00:36:51 +03:00