#author("2023-10-31T00:08:52+09:00","default:discord","discord") #author("2023-11-06T17:55:53+09:00","default:discord","discord") Software Design Specification for Suika2 |Author|ktabata| |Modified By|| |Organization|| |Updated|10th October 2023| |Created|29th October 2022| |Revision: 14.6.0| |Revision|14.6.0| ---- Table of Contents #contents ---- * Introduction [#i0223830] This document outlines the software design specification (SDS) for Suika2 in English. It is intended to help programmers understand Suika2's high-level design and get started quickly. ---- * Components [#ifc11971] Suika2 consists of the following components: - Platform Independent Layer (PIL) - Hardware Abstraction Layer (HAL) +---------------+ | cmd_*.c (PIL) | +---------------+ | main.c (PIL) | +---------------+ | event.c (PIL) | +---------------+ | HAL | +---------------+ | OS API | +---------------+ We don't use C++ classes to wrap OS API because: - Native language may not support C++ bindings - A layered structure is more simple than interrelationships between classes ---- * HAL [#q0213da4] A HAL is a component implemented on a per-platform basis. ** Supported Platforms [#wb90efbd] Currently, the project has six HALs. - Windows - macOS - Web (Emscripten) - iOS - Android (NDK) - Linux ** HAL Modules [#t5afd9df] The HALs consist of the following modules: - Windows -- "winmain.c" ... Entry Point -- "d3drender.cc" ... Direct3D Renderer -- "glrender.c" ... OpenGL Renderer -- "dsound.c" ... DirectSound Player -- "dsvideo.cc" ... DirectShow Video Player -- "tts_sapi.cc" ... Text-to-speech - macOS -- "nsmain.m" ... Entry Point -- "glrender.c" ... OpenGL Renderer -- "aunit.c" ... AudioUnit Player - Web (Emscripten) -- "emmain.c" ... Entry Point -- "glrender.c" ... OpenGL Renderer -- "emopenal.c" ... OpenAL Player - iOS -- "iosmain.m" ... Entry Point -- "glrender.c" ... OpenGL Renderer -- "emopenal.c" ... OpenAL Player - Android -- "ndkmain.c" ... Entry Point -- "ndkfile.c" ... File Operation -- "ndkwave.c" ... Sound Playback -- "glrender.c" ... OpenGL Renderer - Linux -- "x11main.c" ... Entry Point -- "glrender.c" ... OpenGL Renderer -- "asound.c" ... ALSA Player ** HAL Functionality [#bac9e654] A HAL must provide the following functionalities: - Initialization - Main Loop - Event Handling - Logging - Path Manipulation - GPU Operations - Time Measurement - Confirmation Dialogs - Sound Playback - Video Playback - Window Manipulation - System Locale ---- * PIL [#y97aa026] The PIL provides the following functionalities: - Main Flow -- Event Handlers ("event.c") -- Command Dispatcher ("main.c") -- Command Implementation ("cmd_*.c") - Common Process for Most Platforms -- File and Package ("file.c") - Common Process for All Platforms -- Rendering ("stage.c") -- Logging ("log.c") -- Config Parser ("config.c") -- Script Parser ("script.c") -- GUI Parser and Execution ("gui.c") -- Anime Parser and Execution ("anime.c") -- WMS Scripting ("wms*.c") ---- * Application Flow [#f9d5b6b4] A HAL runs a main loop. In a main loop, a HAL dispatches UI events to the functions implemented in "event.c". The following functions are for event handling and are implemented in "event.c" bool on_event_init(void); void on_event_cleanup(void); bool on_event_frame(int *x, int *y, int *w, int *h); void on_event_key_press(int key); void on_event_key_release(int key); void on_event_mouse_press(int button, int x, int y); void on_event_mouse_release(int button, int x, int y); void on_event_mouse_move(int x, int y); void on_event_mouse_scroll(int n); "on_event_frame()" function is called every frame. In this function, the program calls "game_loop_iter()" function that is implemented in "main.c". "game_loop_iter()" calls "dispatch_command()". In "dispatch_command()", each command implementation such as "message_command()" is called. ---- * Command Implementation Functions [#rec5167d] The command implementation functions are implemented in "cmd_*.c" files. A command implementation function is called every frames while the command is executed. A function, "is_in_command_repetition()", is provided to distinguish between the first frame and the frames that will be executed repeatedly after that. When a command quits, the command implementation function just calls "move_to_next_command()". ---- * How to add a command [#q0b4c290] - In "script.h": -- Add a constant to "enum command_type" -- The new constant shows a new command we'll add -- Create "enum xxx_command_param" -- Define command parameter indices like other "enum xxx_command_param" - In "script.c": -- Add a command to "struct insn_item insn_tbl[]" - In"main.h": -- Add a prototype declaration of "xxx_command()" - In "main.c": -- Add a command dispatch in "dispatch_command()" - In "cmd_xxx.c": -- Create a file - In "common.mk": -- Add "cmd_xxx.c"