Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Config for Soundfont, Font and "Focus Lost" #3168

Merged
merged 39 commits into from
Jul 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
bddc3c5
Settings: Add configuring MIDI devices
Ghabry Dec 1, 2023
8a00b7c
Config Param: Simplify code via constexpr if
Ghabry Dec 1, 2023
d3577f5
Ui: Add OpenURL to SDL2
Ghabry Dec 4, 2023
1cbf5e7
Settings: Make "Pause when focus lost" a setting instead of a compile…
Ghabry Dec 4, 2023
ff6d8cd
Settings: Code improvements for MIDI
Ghabry Dec 4, 2023
3e5d648
Settings: Allow configuring the default fonts
Ghabry Dec 4, 2023
988719e
Add live reload of Fluidsynth soundfont
Ghabry Dec 6, 2023
62533fc
Message Window: Only change the font when a new page starts
Ghabry Dec 6, 2023
59cbcb0
Window Help: Support optional scrolling when the text does not fit in…
Ghabry Dec 6, 2023
c43c5af
Settings: Add a font preview and mark the active font
Ghabry Dec 6, 2023
1069008
Emscripten: Add Soundfont and Font upload
Ghabry Dec 20, 2023
62d7f35
Settings: Do not allow disabling of FmMidi
Ghabry Dec 20, 2023
9ffb9b4
Fix build when Fluidsynth is missing or Fluidlite is used
Ghabry Dec 20, 2023
e63b72b
Update help/manual
Ghabry Dec 21, 2023
b6e397b
Fluidsynth: Only try /usr/share on desktop Linux/BSD/macOS systems
Ghabry Dec 21, 2023
fb71fe4
Settings: Prevent changing the font when the game has a custom font
Ghabry Dec 21, 2023
5a91e42
Settings: Fix memory corruption after Push
Ghabry Dec 21, 2023
833abef
Emscripten: Sanitize (Sound)fonts
Ghabry Dec 21, 2023
349b7e2
FluidSynth: Change SF when the MIDI changes
Ghabry Dec 22, 2023
05572a0
FreeType: Calculate font size correctly depending on whether it is a …
Ghabry Dec 24, 2023
8f3d3c3
MIDI: Report the device status
Ghabry Dec 1, 2023
645881e
FtFont: Improve error handling
Ghabry Dec 24, 2023
7d55c28
Settings: Add Spanish pangram
Ghabry Dec 24, 2023
40387f0
Settings: Only show "Open folder" on Windows, Linux, macOS
Ghabry Mar 11, 2024
0c7d9bb
Settings: Support ".soundfont"
Ghabry Mar 11, 2024
e8c2138
MidiOut: Support volume settings
Ghabry Mar 11, 2024
a0635e4
FluidLite: Use upstream target name
Ghabry Mar 12, 2024
20ffb14
Settings: Reset font size of bottom help window and font settings whe…
Ghabry Mar 12, 2024
a6f224d
Settings: The font size can now be altered directly with left/right w…
Ghabry Mar 12, 2024
c787b97
Audio: Add Api to get the shared Midi Out Instance
Ghabry Mar 26, 2024
000f534
Config: Namespace all the enums to reduce global scope pollution
Ghabry Mar 27, 2024
1f36f77
Config: Unify FPS show settings.
Ghabry Mar 27, 2024
2bd7bc5
Font: Unify the rendering functions for shaped and non-shaped fonts
Ghabry Apr 17, 2024
f16cc6b
Font: Resize the mask when the glyph is too large
Ghabry Apr 17, 2024
b8fa21c
Do transparent blitting of the system graphic frame
Ghabry Apr 19, 2024
0fd4a05
MIDI: Only call seq->play in the Update function. Otherwise can cause…
Ghabry May 13, 2024
914abbb
Unlock the font settings when returning to the Game Browser
Ghabry May 13, 2024
7f6f381
Audio Generic: memset was not clearing all the data (works on bytes, …
Ghabry May 21, 2024
57cddd1
Settings: Do not play Decision SE twice
Ghabry May 21, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1052,7 +1052,7 @@ if(${PLAYER_AUDIO_BACKEND} MATCHES "^(SDL2|SDL1|libretro|psvita|3ds|switch|wii|a
player_find_package(NAME FluidLite
CONDITION PLAYER_WITH_FLUIDLITE
DEFINITION HAVE_FLUIDLITE
TARGET FluidLite::fluidlite)
TARGET "fluidlite::fluidlite;fluidlite::fluidlite-static")
endif()

# xmp (lite)
Expand Down Expand Up @@ -1506,7 +1506,7 @@ if(${PLAYER_AUDIO_BACKEND} MATCHES "^(SDL2|SDL1|libretro|psvita|3ds|switch|wii)$
if(TARGET FluidSynth::libfluidsynth)
list(APPEND MIDI_LIBS "FluidSynth")
endif()
if(TARGET FluidLite::fluidlite)
if(TARGET fluidlite::fluidlite OR TARGET fluidlite::fluidlite-static)
list(APPEND MIDI_LIBS "FluidLite")
endif()
if(TARGET WildMidi::libwildmidi OR TARGET WildMidi::libwildmidi-static)
Expand Down
8 changes: 4 additions & 4 deletions builds/cmake/Modules/FindFluidLite.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
#
# This module defines the following :prop_tgt:`IMPORTED` targets:
#
# ``FluidLite::fluidlite``
# ``fluidlite::fluidlite``
# The ``FluidLite`` library, if found.
#
# Result Variables
Expand Down Expand Up @@ -53,9 +53,9 @@ if(FLUIDLITE_FOUND)
set(FLUIDLITE_LIBRARIES ${FLUIDLITE_LIBRARIES})
endif()

if(NOT TARGET FluidLite::fluidlite)
add_library(FluidLite::fluidlite UNKNOWN IMPORTED)
set_target_properties(FluidLite::fluidlite PROPERTIES
if(NOT TARGET fluidlite::fluidlite)
add_library(fluidlite::fluidlite UNKNOWN IMPORTED)
set_target_properties(fluidlite::fluidlite PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${FLUIDLITE_INCLUDE_DIRS}"
IMPORTED_LOCATION "${FLUIDLITE_LIBRARY}")
endif()
Expand Down
74 changes: 54 additions & 20 deletions resources/emscripten/emscripten-post.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ if (Module.saveFs === undefined) {
}

Module.initApi = function() {
Module.api_private.download_js = function(buffer, size, filename) {
Module.api_private.download_js = function (buffer, size, filename) {
const blob = new Blob([Module.HEAPU8.slice(buffer, buffer + size)]);
const link = document.createElement('a');
link.href = window.URL.createObjectURL(blob);
Expand All @@ -23,28 +23,62 @@ Module.initApi = function() {
link.remove();
}

Module.api_private.uploadSavegame_js = function(slot) {
let saveFile = document.getElementById('easyrpg_saveFile');
if (saveFile == null) {
saveFile = document.createElement('input');
saveFile.type = 'file';
saveFile.id = 'easyrpg_saveFile';
saveFile.style.display = 'none';
saveFile.addEventListener('change', function(evt) {
const save = evt.target.files[0];
Module.api_private.createInputElement_js = function (id, event) {
let file = document.getElementById(id);
if (file == null) {
file = document.createElement('input');
file.type = 'file';
file.id = id;
file.style.display = 'none';
file.addEventListener('change', function (evt) {
const selected_file = evt.target.files[0];
const reader = new FileReader();
reader.onload = function (file) {
const result = new Uint8Array(file.currentTarget.result);
var buf = Module._malloc(result.length);
Module.HEAPU8.set(result, buf);
Module.api_private.uploadSavegameStep2(slot, buf, result.length);
Module._free(buf);
Module.api.refreshScene();
};
reader.readAsArrayBuffer(save);
reader.onload = function(file) {
event(file, selected_file.name);
}
reader.readAsArrayBuffer(selected_file);
});
}
saveFile.click();
file.click();
}

Module.api_private.uploadSavegame_js = function (slot) {
Module.api_private.createInputElement_js('easyrpg_saveFile', function (file) {
const result = new Uint8Array(file.currentTarget.result);
var buf = Module._malloc(result.length);
Module.HEAPU8.set(result, buf);
Module.api_private.uploadSavegameStep2(slot, buf, result.length);
Module._free(buf);
Module.api.refreshScene();
});
}

Module.api_private.uploadSoundfont_js = function () {
Module.api_private.createInputElement_js('easyrpg_sfFile', function (file, name) {
const result = new Uint8Array(file.currentTarget.result);
//const name_buf = Module._malloc(name.length + 1);
//stringToUTF8(name, name_buf, name.length + 1);
const content_buf = Module._malloc(result.length);
Module.HEAPU8.set(result, content_buf);
Module.api_private.uploadSoundfontStep2(name, content_buf, result.length);
//Module._free(name_buf);
Module._free(content_buf);
Module.api.refreshScene();
});
}

Module.api_private.uploadFont_js = function () {
Module.api_private.createInputElement_js('easyrpg_sfFile', function (file, name) {
const result = new Uint8Array(file.currentTarget.result);
//const name_buf = Module._malloc(name.length + 1);
//stringToUTF8(name, name_buf, name.length + 1);
const content_buf = Module._malloc(result.length);
Module.HEAPU8.set(result, content_buf);
Module.api_private.uploadFontStep2(name, content_buf, result.length);
//Module._free(name_buf);
Module._free(content_buf);
Module.api.refreshScene();
});
}
}

Expand Down
2 changes: 1 addition & 1 deletion resources/unix/bash-completion/easyrpg-player
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ _easyrpg-player ()

# all possible options
ouropts='--autobattle-algo --battle-test --disable-audio --disable-rtp \
--encoding --enemyai-algo --engine --fps-limit --fps-render-window --fullscreen -h --help \
--encoding --enemyai-algo --engine --fps-limit --fullscreen -h --help \
--hide-title --load-game-id --new-game --no-vsync --project-path --rtp-path --record-input \
--replay-input --save-path --seed --show-fps --start-map-id --start-party --no-log-color \
--start-position --test-play --window -v --version'
Expand Down
33 changes: 31 additions & 2 deletions resources/unix/easyrpg-player.6.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,25 @@ NOTE: For games that only use ASCII (English games) use '1252'.
- 'rpg2k3v105' - RPG Maker 2003 (v1.05 - v1.09a)
- 'rpg2k3e' - RPG Maker 2003 RPG Maker 2003 (English release, v1.12)

*--font1* _FILE_::
Path to a font to use for the first font. The system graphic of the game
determines whether font 1 or 2 is used. When no font is selected or the
selected font lacks certain glyphs the built-in pixel font is used.

*--font1-size* _PX_::
Size of font 1 in pixel. The default value is 12.

*--font2* _FILE_::
Path to a font to use for the second font. See font 1 for further information.

*--font2-size* _PX_::
Size of font 2 in pixel. The default value is 12.

*--font-path* _PATH_::
Configures the path where the settings scene looks for fonts. The user can
choose from any font in the directory. This is more flexible than using
*--font1* or *--font2* directly. The default path is 'config-path/Font'.

*--language* _LANG_::
Loads the game translation in language/'LANG' folder.

Expand Down Expand Up @@ -166,6 +185,10 @@ NOTE: When using the game browser all games will share the same save directory!
- 'widescreen' - 416x240 (16:9)
- 'ultrawide' - 560x240 (21:9)

*--pause-focus-lost*::
Pause the game when the window has no focus. Can be disabled with
*--no-pause-focus-lost*.

*--scaling* _MODE_::
How the video output is scaled. Possible options:
- 'nearest' - Scale to screen size using nearest neighbour algorithm.
Expand All @@ -175,8 +198,10 @@ NOTE: When using the game browser all games will share the same save directory!
- 'bilinear' - Like 'nearest' but apply a bilinear filter to avoid the
artifacts.
*--show-fps*::
Enable display of the frames per second counter. Can be disabled with
*--no-show-fps*.
Enable display of the frames per second counter. When in windowed mode it is
shown inside the window. When in fullscreen mode it is shown in the titlebar.
Use *--fps-render-window* to always show the counter inside the window. Can be
disabled with *--no-show-fps*.

*--stretch*::
Ignore the aspect ratio and stretch video output to the entire width of the
Expand Down Expand Up @@ -206,6 +231,10 @@ NOTE: When using the game browser all games will share the same save directory!
Adds 'FILE' to the list of soundfonts used for playing MIDI files and use
this one with highest precedence. The soundfont must be in SF2 format.

*--soundfont-path* _P_::
Configures the path where the settings scene looks for soundfonts. The user
can choose from any soundfont in the directory. This is more flexible than
using *--soundfont* directly. The default path is 'config-path/Soundfont'.

=== Debug options

Expand Down
49 changes: 49 additions & 0 deletions src/audio.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

// Headers
#include "audio.h"
#include "audio_midi.h"
#include "system.h"
#include "baseui.h"
#include "player.h"
Expand Down Expand Up @@ -70,6 +71,21 @@ AudioInterface::AudioInterface(const Game_ConfigAudio& cfg) : cfg(cfg) {
Game_ConfigAudio AudioInterface::GetConfig() const {
auto acfg = cfg;
acfg.Hide();

#if !defined(HAVE_FLUIDSYNTH) && !defined(HAVE_FLUIDLITE)
acfg.fluidsynth_midi.SetOptionVisible(false);
acfg.soundfont.SetOptionVisible(false);
#endif
#ifndef HAVE_LIBWILDMIDI
acfg.wildmidi_midi.SetOptionVisible(false);
#endif
#ifndef HAVE_NATIVE_MIDI
acfg.native_midi.SetOptionVisible(false);
#endif
#ifndef WANT_FMMIDI
acfg.fmmidi_midi.SetOptionVisible(false);
#endif

vGetConfig(acfg);
return acfg;
}
Expand All @@ -89,3 +105,36 @@ int AudioInterface::SE_GetGlobalVolume() const {
void AudioInterface::SE_SetGlobalVolume(int volume) {
cfg.sound_volume.Set(volume);
}

bool AudioInterface::GetFluidsynthEnabled() const {
return cfg.fluidsynth_midi.Get();
}

void AudioInterface::SetFluidsynthEnabled(bool enable) {
cfg.fluidsynth_midi.Set(enable);
}

bool AudioInterface::GetWildMidiEnabled() const {
return cfg.wildmidi_midi.Get();
}

void AudioInterface::SetWildMidiEnabled(bool enable) {
cfg.wildmidi_midi.Set(enable);
}

bool AudioInterface::GetNativeMidiEnabled() const {
return cfg.native_midi.Get();
}

void AudioInterface::SetNativeMidiEnabled(bool enable) {
cfg.native_midi.Set(enable);
}

std::string AudioInterface::GetFluidsynthSoundfont() const {
return cfg.soundfont.Get();
}

void AudioInterface::SetFluidsynthSoundfont(StringView sf) {
cfg.soundfont.Set(ToString(sf));
MidiDecoder::ChangeFluidsynthSoundfont(sf);
}
22 changes: 22 additions & 0 deletions src/audio.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

// Headers
#include <string>
#include "audio_generic_midiout.h"
#include "filesystem_stream.h"
#include "audio_secache.h"
#include "game_config.h"
Expand All @@ -39,6 +40,15 @@ struct AudioInterface {

virtual void vGetConfig(Game_ConfigAudio& cfg) const = 0;

/**
* Instantiates and returns the Native Midi Out device.
* The Midi Out device is usually an exclusive resource.
* Implementing classes should only create one Midi Out and return the
* shared instance.
* @return Native Midi Out Device or nullptr on error
*/
virtual GenericAudioMidiOut* CreateAndGetMidiOut() { return nullptr; }

/**
* Update audio. Must be called each frame.
*/
Expand Down Expand Up @@ -133,6 +143,18 @@ struct AudioInterface {
int SE_GetGlobalVolume() const;
void SE_SetGlobalVolume(int volume);

bool GetFluidsynthEnabled() const;
void SetFluidsynthEnabled(bool enable);

bool GetWildMidiEnabled() const;
void SetWildMidiEnabled(bool enable);

bool GetNativeMidiEnabled() const;
void SetNativeMidiEnabled(bool enable);

std::string GetFluidsynthSoundfont() const;
void SetFluidsynthSoundfont(StringView sf);

protected:
Game_ConfigAudio cfg;
};
Expand Down
Loading