mirror of
https://github.com/kichikuou/xsystem35-sdl2.git
synced 2026-09-22 22:48:08 +03:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bcaed3a687 | ||
|
|
894e8e26a6 | ||
|
|
7206b0a4f7 | ||
|
|
343f3bb7c5 | ||
|
|
d3650ce293 | ||
|
|
386cfeb60c | ||
|
|
9cd66c83ef | ||
|
|
065e16a082 | ||
|
|
3699aa5c2d | ||
|
|
20914970c9 | ||
|
|
3f2f555aa6 | ||
|
|
095da0bb86 | ||
|
|
7b8acd6e05 | ||
|
|
1b13e331e4 | ||
|
|
5621ab4d86 | ||
|
|
79805d9ea2 | ||
|
|
f427d50fa3 | ||
|
|
7c7768fba4 | ||
|
|
2b6267aeb9 | ||
|
|
16e7d3baf1 | ||
|
|
2d8d95ac6f | ||
|
|
d5899ff55a | ||
|
|
04037682ee | ||
|
|
cdb16f73a3 | ||
|
|
2895e338c0 | ||
|
|
1a2268e94b | ||
|
|
07643c82a4 | ||
|
|
a16156f8e4 | ||
|
|
ea5cef91fd | ||
|
|
48a41b9f82 | ||
|
|
c11c80d95d | ||
|
|
d7082a9d80 | ||
|
|
083cf885de | ||
|
|
7b1fef4ad7 | ||
|
|
f039baf061 |
@@ -6,7 +6,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Install Deps
|
||||
run: sudo apt install ninja-build
|
||||
@@ -22,7 +22,7 @@ jobs:
|
||||
KEYSTORE_PASSWORD: ${{ secrets.KEYSTORE_PASSWORD }}
|
||||
|
||||
- name: Upload artifacts
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: xsystem35-apk
|
||||
path: android/app/build/outputs/apk/release/app-release.apk
|
||||
|
||||
@@ -2,7 +2,7 @@ name: Emscripten Build
|
||||
on: [push, pull_request]
|
||||
|
||||
env:
|
||||
EM_VERSION: 3.1.50
|
||||
EM_VERSION: 3.1.54
|
||||
EM_CACHE_FOLDER: 'emsdk-cache'
|
||||
|
||||
jobs:
|
||||
@@ -10,17 +10,17 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Setup cache
|
||||
id: cache-system-libraries
|
||||
uses: actions/cache@v3
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ${{env.EM_CACHE_FOLDER}}
|
||||
key: ${{env.EM_VERSION}}-${{ runner.os }}
|
||||
|
||||
- name: Setup Emscripten toolchain
|
||||
uses: mymindstorm/setup-emsdk@v13
|
||||
uses: mymindstorm/setup-emsdk@v14
|
||||
with:
|
||||
version: ${{ env.EM_VERSION }}
|
||||
actions-cache-folder: ${{env.EM_CACHE_FOLDER}}
|
||||
@@ -29,13 +29,13 @@ jobs:
|
||||
run: |
|
||||
mkdir -p out/wasm
|
||||
cd out/wasm
|
||||
emcmake cmake -DCMAKE_BUILD_TYPE=MinSizeRel ../../
|
||||
make
|
||||
emcmake cmake -DCMAKE_BUILD_TYPE=MinSizeRel -DCMAKE_COMPILE_WARNING_AS_ERROR=YES ../../
|
||||
make -j4
|
||||
mkdir xsystem35
|
||||
mv src/xsystem35.* xsystem35/
|
||||
|
||||
- name: Upload artifacts
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: xsystem35-wasm
|
||||
path: out/wasm/xsystem35
|
||||
|
||||
@@ -10,7 +10,7 @@ jobs:
|
||||
|
||||
name: Linux ${{ matrix.build-type }}
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Install Deps
|
||||
run: |
|
||||
@@ -22,7 +22,7 @@ jobs:
|
||||
mkdir -p out/${{ matrix.build-type }}
|
||||
cd out/${{ matrix.build-type }}
|
||||
cmake -DCMAKE_BUILD_TYPE=${{ matrix.build-type }} ../../
|
||||
make
|
||||
make -j4
|
||||
|
||||
- name: Test
|
||||
run: ctest --output-on-failure
|
||||
|
||||
@@ -34,13 +34,14 @@ jobs:
|
||||
${{ matrix.deps }}
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Copy licenses
|
||||
run: |
|
||||
ls /${{ matrix.sys }}/share/licenses
|
||||
mkdir dist
|
||||
cp -r /${{ matrix.sys }}/share/licenses dist/
|
||||
cp fonts/*.license dist/licenses/
|
||||
|
||||
- name: Install dev dependencies
|
||||
run: pacboy --noconfirm -S --needed gcc:p cmake:p ninja:p
|
||||
@@ -49,7 +50,7 @@ jobs:
|
||||
run: |
|
||||
mkdir -p out/release
|
||||
cd out/release
|
||||
cmake -G"Ninja" -DCMAKE_BUILD_TYPE=Release ${{ matrix.cmake_args }} ../../
|
||||
cmake -GNinja -DCMAKE_BUILD_TYPE=Release -DCMAKE_COMPILE_WARNING_AS_ERROR=YES ${{ matrix.cmake_args }} ../../
|
||||
ninja
|
||||
|
||||
- name: Test
|
||||
@@ -61,7 +62,8 @@ jobs:
|
||||
cp out/release/src/xsystem35.exe *.md COPYING xsys35rc.sample dist/
|
||||
|
||||
- name: Upload
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: ${{ matrix.package }}
|
||||
path: dist
|
||||
compression-level: 9 # because we use it for releases
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
out
|
||||
android/.gradle
|
||||
android/.idea
|
||||
android/app/.cxx
|
||||
android/app/.externalNativeBuild
|
||||
android/app/build
|
||||
android/app/src/main/assets
|
||||
android/build
|
||||
android/keystore.jks
|
||||
android/local.properties
|
||||
.ccls-cache
|
||||
.dir-locals.el
|
||||
compile_commands.json
|
||||
|
||||
+107
@@ -0,0 +1,107 @@
|
||||
# Changelog
|
||||
|
||||
## 2.11.5 - 2024-06-10
|
||||
- Android: Fixed a black screen issue in the MangaGamer version of Rance 5D.
|
||||
- Fixed `fileCheckExist` command. (#55)
|
||||
|
||||
## 2.11.4 - 2024-05-22
|
||||
- Windows: In full-screen mode, the menu bar now appears only when the mouse pointer is at the top of the screen. (#53)
|
||||
- Fixed text rendering issue in Rance 3 intro. (#54)
|
||||
|
||||
## 2.11.3 - 2024-04-11
|
||||
- Android: Fixed a bug where save files from older versions could not be loaded in version 2.11.2.
|
||||
|
||||
## 2.11.2 - 2024-04-10
|
||||
- Added `-savedir` option to specify save directory.
|
||||
- Android: Fixed a bug where .xsys35rc in a subdirectory of ZIP was not loaded. (#51)
|
||||
|
||||
## 2.11.1 - 2024-02-18
|
||||
- Windows: Fixed a black screen issue in the MangaGamer version of Rance 5D (#45).
|
||||
- Fixed a crash bug in command-line debugger.
|
||||
|
||||
## 2.11.0 - 2024-01-20
|
||||
- Windows: Now `xsystem35.exe` is a standalone executable. You can just copy it to the game folder and run it.
|
||||
- Windows: The installer is no longer provided. If you have an earlier version installed, please uninstall it.
|
||||
- Windows: The debugger is no longer available in the 32-bit version. Please use the 64-bit version if you need it.
|
||||
- Added experimental `enable_zb` option (#44). See `xsys35rc.sample` for details.
|
||||
|
||||
## 2.10.1 - 2024-01-01
|
||||
- Windows: Added "Integer Scaling" menu option
|
||||
- Fixed initial palette colors (to match System3.9)
|
||||
- Fixed a bug where palette 246 to 249 were unintentionally changed after loading 256-color CGs
|
||||
|
||||
## 2.10.0 - 2023-12-09
|
||||
- Breaking change: A [bug](https://github.com/kichikuou/xsystem35-sdl2/issues/41) has been fixed in which save format for 大悪司 and かえるにょ国にょアリス was not compatible with System3.9. As a result, save files for these games created with older versions of xsystem35 are no longer usable. (Loading will not fail, but wrong values will be loaded.)
|
||||
- Now the 64-bit executable supports Windows 10 or later. For older Windows, please use the 32-bit version.
|
||||
- Fixed a problem with the download edition of Daiakuji requiring insertion of Disk 2. (#43)
|
||||
- Debugger: Added debug commands for monitoring the color palette.
|
||||
- Minor bug fixes.
|
||||
|
||||
## 2.9.1 - 2023-06-22
|
||||
- Fixed a bug where the `CX 1` command (copy with transparent color) did not work in some games (e.g. Daiakuji)
|
||||
- Debugger: Now breakpoints do not make the window completely unresponsive
|
||||
- Debugger: Fixed a conditional breakpoint crash bug
|
||||
|
||||
## 2.9.0 - 2023-05-04
|
||||
- Now xsystem35 uses the System3.9 save file format (unless `-saveformat` command line flag is specified). Old save files can still be loaded.
|
||||
- Changed the default naming convention for save files from `[a-z]sleep.asd` to `<gamename>s[a-z].asd`.
|
||||
- Fixed a bug where SACT games (e.g. Rance 5D) were not responding to touch.
|
||||
- Fixed memory leaks in debugger.
|
||||
|
||||
## 2.8.0 - 2023-02-12
|
||||
- Added support for Rance 4.1/4.2 ver1.05
|
||||
- Fixed movement animation in rooms in Rance 4 v2.05 (#35)
|
||||
- Added `-game` option which can be used to enable game-specific hacks in translated games
|
||||
|
||||
## 2.7.0 - 2023-01-28
|
||||
- Added support for Rance4 ver.2.05
|
||||
- Now supports BGM playback for the download edition of Daiakuji
|
||||
- Bug fixes
|
||||
|
||||
## 2.6.0 - 2023-01-01
|
||||
- Android: Introduced a new way to simulate right-click; tapping on the black bars at the left/right or top/bottom of the screen is treated as a right click. (Two-finger touch, the old way to simulate a right click, still works.)
|
||||
- Windows: Added a menu command to enable/disable automatic mouse movements.
|
||||
|
||||
## 2.5.1 - 2022-07-31
|
||||
- Implemented "palette shift" graphic effect (used in 闘神都市II).
|
||||
- Implemented `grDrawFillCircle` command (used in グレイメルカ).
|
||||
- Fixed color update bug in 256-color games.
|
||||
- Fixed crash by out-of-bounds variable access in debugger.
|
||||
|
||||
## 2.5.0 - 2022-07-17
|
||||
- Supported JPEG image format on Android.
|
||||
|
||||
## 2.4.0 - 2022-07-02
|
||||
- Windows: Added "Restart" menu command.
|
||||
- Fixed a bug where wrong music is played in Kichikuou Rance (System3.9 version). #32
|
||||
- Supported mouse wheel input.
|
||||
- Fixed a bug in `MF` command.
|
||||
- Implemented `grEffectMoveView` command.
|
||||
|
||||
## 2.3.0 - 2022-04-08
|
||||
- Code for screen transition effects have been substantially rewritten (but you probably wouldn't notice any difference).
|
||||
- Fixed bugs in System3.9 games.
|
||||
- Android: Enabled joystick input.
|
||||
- Debugger improvements.
|
||||
|
||||
## 2.2.0 - 2021-12-03
|
||||
From now on, the Android and Windows versions will use a common version number.
|
||||
|
||||
- Android: Use custom fonts specified in `.xsys35c`. (#20)
|
||||
- Supported "王子さまLv1".
|
||||
- Debugger improvements.
|
||||
- Fixed some bugs and compatibility issues.
|
||||
|
||||
## 2.1.0 - 2021-11-07
|
||||
- Fixed issues with MangaGamer version of Rance 5D.
|
||||
- Fixed garbled text in some System3.9 games with Unicode mode.
|
||||
- Display a message box on fatal errors.
|
||||
- Various debugger improvements.
|
||||
|
||||
## 2.0.1 - 2021-10-24
|
||||
- Fixed crash during shutdown.
|
||||
|
||||
## 2.0.0 - 2021-10-23
|
||||
- Added window menubar from which you can save screenshots, change fullscreen mode, and enable message skipping.
|
||||
- Added debugger support that can be used from Visual Studio Code. See [vscode-system3x](https://github.com/kichikuou/vscode-system3x) for details.
|
||||
- Many bug fixes and compatibility fixes.
|
||||
+42
-58
@@ -3,8 +3,10 @@ cmake_minimum_required(VERSION 3.13)
|
||||
project(xsystem35 LANGUAGES C)
|
||||
set(CMAKE_C_STANDARD 99)
|
||||
enable_testing()
|
||||
set(CMAKE_EXPORT_COMPILE_COMMANDS TRUE)
|
||||
|
||||
include(CheckSymbolExists)
|
||||
include(FetchContent)
|
||||
|
||||
# A wrapper around pkg_check_modules() that skips the check if ENABLE_<prefix> is false
|
||||
macro (optional_pkg_check_modules prefix)
|
||||
@@ -25,6 +27,27 @@ function(add_static_library name pkg)
|
||||
INTERFACE_LINK_OPTIONS "${${pkg}_STATIC_LDFLAGS_OTHER}")
|
||||
endfunction()
|
||||
|
||||
function(fetch_webp)
|
||||
FetchContent_Declare(
|
||||
libwebp
|
||||
URL https://storage.googleapis.com/downloads.webmproject.org/releases/webp/libwebp-1.4.0.tar.gz
|
||||
URL_HASH SHA1=0b1c8bea200caaa010182609dbaaa91aec69b64d
|
||||
)
|
||||
set(WEBP_BUILD_ANIM_UTILS OFF CACHE BOOL "Build animation utilities." FORCE)
|
||||
set(WEBP_BUILD_CWEBP OFF CACHE BOOL "Build the cwebp command line tool." FORCE)
|
||||
set(WEBP_BUILD_DWEBP OFF CACHE BOOL "Build the dwebp command line tool." FORCE)
|
||||
set(WEBP_BUILD_GIF2WEBP OFF CACHE BOOL "Build the gif2webp conversion tool." FORCE)
|
||||
set(WEBP_BUILD_IMG2WEBP OFF CACHE BOOL "Build the img2webp animation tool." FORCE)
|
||||
set(WEBP_BUILD_VWEBP OFF CACHE BOOL "Build the vwebp viewer tool." FORCE)
|
||||
set(WEBP_BUILD_WEBPINFO OFF CACHE BOOL "Build the webpinfo command line tool." FORCE)
|
||||
set(WEBP_BUILD_LIBWEBPMUX OFF CACHE BOOL "Build the libwebpmux library." FORCE)
|
||||
set(WEBP_BUILD_WEBPMUX OFF CACHE BOOL "Build the webpmux command line tool." FORCE)
|
||||
set(WEBP_BUILD_EXTRAS OFF CACHE BOOL "Build extras." FORCE)
|
||||
set(WEBP_BUILD_WEBP_JS OFF CACHE BOOL "Emscripten build of webp.js." FORCE)
|
||||
FetchContent_MakeAvailable(libwebp)
|
||||
add_library(WebP ALIAS webp)
|
||||
endfunction()
|
||||
|
||||
check_symbol_exists(getlogin "unistd.h" HAVE_GETLOGIN)
|
||||
check_symbol_exists(mmap "sys/mman.h" HAVE_MMAP)
|
||||
check_symbol_exists(sigaction "signal.h" HAVE_SIGACTION)
|
||||
@@ -36,20 +59,23 @@ if (EMSCRIPTEN)
|
||||
INTERFACE_COMPILE_OPTIONS ${option}
|
||||
INTERFACE_LINK_OPTIONS ${option})
|
||||
endfunction()
|
||||
add_emscripten_library(zlib "SHELL:-s USE_ZLIB=1")
|
||||
add_emscripten_library(sdl2 "SHELL:-s USE_SDL=2")
|
||||
add_emscripten_library(sdl2_ttf "SHELL:-s USE_SDL_TTF=2")
|
||||
add_emscripten_library(zlib -sUSE_ZLIB=1)
|
||||
add_emscripten_library(sdl2 -sUSE_SDL=2)
|
||||
add_emscripten_library(sdl2_ttf -sUSE_SDL_TTF=2)
|
||||
set(DEFAULT_FONT_PATH /fonts/)
|
||||
fetch_webp()
|
||||
set(HAVE_WEBP 1)
|
||||
|
||||
elseif (ANDROID)
|
||||
add_library(sdl2 ALIAS SDL2)
|
||||
add_library(sdl2_ttf ALIAS SDL2_ttf)
|
||||
add_library(sdl2_mixer ALIAS SDL2_mixer)
|
||||
set(SDL2MIXER_FOUND 1)
|
||||
find_library(ndk_log log)
|
||||
find_library(ndk_zlib z)
|
||||
add_library(zlib INTERFACE)
|
||||
set_target_properties(zlib PROPERTIES INTERFACE_LINK_LIBRARIES ${ndk_zlib})
|
||||
fetch_webp()
|
||||
set(HAVE_WEBP 1)
|
||||
|
||||
else() # non-emscripten, non-android
|
||||
if (WIN32)
|
||||
@@ -66,22 +92,18 @@ else() # non-emscripten, non-android
|
||||
|
||||
pkg_check_modules(SDL2 REQUIRED IMPORTED_TARGET sdl2)
|
||||
pkg_check_modules(SDL2TTF REQUIRED IMPORTED_TARGET SDL2_ttf)
|
||||
optional_pkg_check_modules(SDL2MIXER IMPORTED_TARGET SDL2_mixer)
|
||||
pkg_check_modules(SDL2MIXER REQUIRED IMPORTED_TARGET SDL2_mixer)
|
||||
if (WIN32)
|
||||
add_static_library(sdl2 SDL2)
|
||||
add_static_library(sdl2_ttf SDL2TTF)
|
||||
# Workaround for linking error
|
||||
set_property(TARGET sdl2_ttf PROPERTY INTERFACE_LINK_LIBRARIES
|
||||
$<LINK_GROUP:RESCAN,${SDL2TTF_STATIC_LIBRARIES} -lstdc++>)
|
||||
if (SDL2MIXER_FOUND)
|
||||
add_static_library(sdl2_mixer SDL2MIXER)
|
||||
endif()
|
||||
add_static_library(sdl2_mixer SDL2MIXER)
|
||||
else()
|
||||
add_library(sdl2 ALIAS PkgConfig::SDL2)
|
||||
add_library(sdl2_ttf ALIAS PkgConfig::SDL2TTF)
|
||||
if (SDL2MIXER_FOUND)
|
||||
add_library(sdl2_mixer ALIAS PkgConfig::SDL2MIXER)
|
||||
endif()
|
||||
add_library(sdl2_mixer ALIAS PkgConfig::SDL2MIXER)
|
||||
set(DEFAULT_FONT_PATH ${CMAKE_INSTALL_PREFIX}/share/xsystem35/fonts/)
|
||||
endif()
|
||||
|
||||
@@ -117,19 +139,12 @@ else() # non-emscripten, non-android
|
||||
find_library(PORTMIDI portmidi)
|
||||
if (PORTMIDI)
|
||||
set(HAVE_PORTMIDI 1)
|
||||
set(ENABLE_MIDI_PORTMIDI 1)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Menu
|
||||
|
||||
if (EMSCRIPTEN)
|
||||
set(SRC_MENU menu_emscripten.c)
|
||||
elseif (ANDROID)
|
||||
set(SRC_MENU menu_android.c)
|
||||
elseif (ENABLE_GTK)
|
||||
set(SRC_MENU menu.c menu_callback.c menu_gui.c s39init.c)
|
||||
|
||||
if (ENABLE_GTK)
|
||||
# i18n support (currently only menus are translated)
|
||||
include(FindIntl)
|
||||
include(FindGettext)
|
||||
@@ -139,60 +154,36 @@ elseif (ENABLE_GTK)
|
||||
include_directories(${Intl_INCLUDE_DIRS})
|
||||
link_libraries(${Intl_LIBRARIES})
|
||||
endif()
|
||||
else ()
|
||||
set(SRC_MENU menu_sdl.c sdl_input.c)
|
||||
endif()
|
||||
|
||||
# PCM audio
|
||||
|
||||
if (EMSCRIPTEN)
|
||||
list(APPEND SRC_AUDIO)
|
||||
list(APPEND SRC_AUDIO pcm.emscripten.c bgm.emscripten.c bgi.c)
|
||||
list(APPEND SUMMARY_AUDIO "Emscripten")
|
||||
elseif (SDL2MIXER_FOUND)
|
||||
list(APPEND SRC_AUDIO pcm.sdlmixer.c bgm.sdlmixer.c bgi.c)
|
||||
list(APPEND SUMMARY_AUDIO "SDL_mixer")
|
||||
set(ENABLE_SDLMIXER 1)
|
||||
else()
|
||||
list(APPEND SRC_AUDIO pcm.dummy.c bgm.dummy.c)
|
||||
list(APPEND SUMMARY_AUDIO "SDL_mixer")
|
||||
endif()
|
||||
|
||||
# CDROM
|
||||
|
||||
list(APPEND SRC_CDROM cdrom.bgm.c)
|
||||
if (CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
||||
list(APPEND SRC_CDROM cdrom.Linux.c)
|
||||
list(APPEND SUMMARY_CDROM "Linux ioctl")
|
||||
set(ENABLE_CDROM_LINUX 1)
|
||||
elseif (CMAKE_SYSTEM_NAME STREQUAL "FreeBSD")
|
||||
list(APPEND SRC_CDROM cdrom.FreeBSD.c)
|
||||
list(APPEND SUMMARY_CDROM "*BSD ioctl")
|
||||
set(ENABLE_CDROM_BSD 1)
|
||||
elseif (CMAKE_SYSTEM_NAME STREQUAL "Emscripten")
|
||||
list(APPEND SRC_CDROM cdrom.emscripten.c)
|
||||
if (EMSCRIPTEN)
|
||||
list(APPEND SUMMARY_CDROM "Emscripten")
|
||||
set(ENABLE_CDROM_EMSCRIPTEN 1)
|
||||
else()
|
||||
list(APPEND SRC_CDROM cdrom.empty.c)
|
||||
endif()
|
||||
if (SDL2MIXER_FOUND)
|
||||
list(APPEND SRC_CDROM cdrom.mp3.c)
|
||||
list(APPEND SUMMARY_CDROM "SDL_mixer (wav|mp3|ogg...)")
|
||||
set(ENABLE_CDROM_MP3 1)
|
||||
endif()
|
||||
set(CDROM_DEVICE "playlist.txt" CACHE STRING "CDROM Device Name")
|
||||
set(DEFAULT_PLAYLIST_PATH "playlist.txt" CACHE STRING "Default playlist path")
|
||||
|
||||
# MIDI
|
||||
|
||||
if (EMSCRIPTEN)
|
||||
list(APPEND SRC_MIDI midi.emscripten.c)
|
||||
list(APPEND SUMMARY_MIDI "Emscripten")
|
||||
elseif (ANDROID)
|
||||
list(APPEND SRC_MIDI midi.android.c)
|
||||
list(APPEND SUMMARY_MIDI "Android")
|
||||
else()
|
||||
list(APPEND SUMMARY_MIDI "SDL_mixer")
|
||||
set(ENABLE_MIDI_SDLMIXER 1)
|
||||
|
||||
if (HAVE_SIGACTION)
|
||||
list(APPEND SRC_MIDI midi.rawmidi.c midifile.c)
|
||||
list(APPEND SUMMARY_MIDI "raw")
|
||||
set(MIDI_DEVICE "/dev/midi" CACHE STRING "midi device")
|
||||
set(ENABLE_MIDI_RAWMIDI 1)
|
||||
@@ -211,15 +202,9 @@ else()
|
||||
set(SEQ_DEVICE "/dev/sequencer" CACHE STRING "sequencer device")
|
||||
endif()
|
||||
|
||||
if (SDL2MIXER_FOUND)
|
||||
list(APPEND SRC_MIDI midi.sdlmixer.c)
|
||||
list(APPEND SUMMARY_MIDI "SDL_mixer")
|
||||
set(ENABLE_MIDI_SDLMIXER 1)
|
||||
endif()
|
||||
|
||||
if (HAVE_PORTMIDI AND ENABLE_MIDI_PORTMIDI)
|
||||
list(APPEND SRC_MIDI midi.portmidi.c)
|
||||
if (HAVE_PORTMIDI)
|
||||
list(APPEND SUMMARY_MIDI "PortMidi")
|
||||
set(ENABLE_MIDI_PORTMIDI 1)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
@@ -242,7 +227,6 @@ message("------------------")
|
||||
set(PACKAGE ${PROJECT_NAME})
|
||||
configure_file(config.h.in config.h)
|
||||
include_directories(${CMAKE_CURRENT_BINARY_DIR})
|
||||
add_compile_definitions(HAVE_CONFIG_H)
|
||||
add_compile_definitions($<$<CONFIG:Debug>:DEBUG>)
|
||||
|
||||
add_subdirectory(src)
|
||||
|
||||
@@ -16,8 +16,8 @@ android {
|
||||
defaultConfig {
|
||||
minSdkVersion 19
|
||||
targetSdkVersion 34
|
||||
versionCode 18
|
||||
versionName "2.11.0" + gitRevision()
|
||||
versionCode 23
|
||||
versionName "2.11.5" + gitRevision()
|
||||
externalNativeBuild {
|
||||
cmake {
|
||||
arguments "-DANDROID_APP_PLATFORM=android-19", "-DANDROID_STL=c++_static"
|
||||
|
||||
@@ -7,18 +7,18 @@ set(PROJECT_ROOT_DIR ../../..)
|
||||
include(FetchContent)
|
||||
FetchContent_Declare(
|
||||
SDL
|
||||
URL https://github.com/libsdl-org/SDL/releases/download/release-2.28.5/SDL2-2.28.5.tar.gz
|
||||
URL_HASH SHA1=50af6b564890d702e57e2a72d6429b43778ed29a
|
||||
URL https://github.com/libsdl-org/SDL/releases/download/release-2.30.2/SDL2-2.30.2.tar.gz
|
||||
URL_HASH SHA1=37a0557fc39460dc2a4fbbf162d95f115d2c9be2
|
||||
)
|
||||
FetchContent_Declare(
|
||||
SDL_ttf
|
||||
URL https://github.com/libsdl-org/SDL_ttf/releases/download/release-2.20.1/SDL2_ttf-2.20.1.tar.gz
|
||||
URL_HASH SHA1=f774ff407915ae4afa3d03e5a9395283d9090f28
|
||||
URL https://github.com/libsdl-org/SDL_ttf/releases/download/release-2.22.0/SDL2_ttf-2.22.0.tar.gz
|
||||
URL_HASH SHA1=da5e86b601ad299a697878fab1af6f3be47b529d
|
||||
)
|
||||
FetchContent_Declare(
|
||||
SDL_mixer
|
||||
URL https://github.com/libsdl-org/SDL_mixer/releases/download/release-2.6.2/SDL2_mixer-2.6.2.tar.gz
|
||||
URL_HASH SHA1=036fc7839a6b8dc1af3dbfed4e2531224bbacdd7
|
||||
URL https://github.com/libsdl-org/SDL_mixer/releases/download/release-2.8.0/SDL2_mixer-2.8.0.tar.gz
|
||||
URL_HASH SHA1=a58c69f9d00e44833b9e00e1adb58d85759ca499
|
||||
)
|
||||
|
||||
set(SDL2TTF_SAMPLES OFF CACHE BOOL "Build the SDL2_ttf sample program(s)" FORCE)
|
||||
@@ -29,12 +29,11 @@ set(SDL2MIXER_OPUS OFF CACHE BOOL "Enable Opus music" FORCE)
|
||||
set(SDL2MIXER_FLAC OFF CACHE BOOL "Enable FLAC music" FORCE)
|
||||
set(SDL2MIXER_MOD OFF CACHE BOOL "Support loading MOD music" FORCE)
|
||||
set(SDL2MIXER_MIDI OFF CACHE BOOL "Enable MIDI music" FORCE)
|
||||
set(SDL2MIXER_WAVPACK OFF CACHE BOOL "Enable WavPack music" FORCE)
|
||||
set(SDL2MIXER_SAMPLES OFF CACHE BOOL "Build the SDL2_mixer sample program(s)" FORCE)
|
||||
set(SDL2MIXER_INSTALL OFF CACHE BOOL "Enable SDL2_mixer install target" FORCE)
|
||||
|
||||
FetchContent_MakeAvailable(SDL)
|
||||
FetchContent_MakeAvailable(SDL_ttf)
|
||||
FetchContent_MakeAvailable(SDL_mixer)
|
||||
FetchContent_MakeAvailable(SDL SDL_ttf SDL_mixer)
|
||||
|
||||
# The main CMakeLists.txt of xsystem35
|
||||
add_subdirectory(${PROJECT_ROOT_DIR} xsystem35)
|
||||
|
||||
@@ -30,9 +30,11 @@ import java.io.IOException
|
||||
|
||||
// Intent for this activity must have the following extra:
|
||||
// - EXTRA_GAME_ROOT (string): A path to the game installation.
|
||||
// - EXTRA_SAVE_DIRECTORY (string): A path to the save data directory.
|
||||
class GameActivity : SDLActivity() {
|
||||
companion object {
|
||||
const val EXTRA_GAME_ROOT = "GAME_ROOT"
|
||||
const val EXTRA_SAVE_DIRECTORY = "SAVE_DIRECTORY"
|
||||
const val EXTRA_ARCHIVE_NAME = "ARCHIVE_NAME"
|
||||
}
|
||||
|
||||
@@ -61,7 +63,7 @@ class GameActivity : SDLActivity() {
|
||||
override fun getArguments(): Array<String> {
|
||||
return arrayOf(
|
||||
"-gamedir", intent.getStringExtra(EXTRA_GAME_ROOT)!!,
|
||||
"-devcd", Launcher.PLAYLIST_FILE)
|
||||
"-savedir", intent.getStringExtra(EXTRA_SAVE_DIRECTORY)!!)
|
||||
}
|
||||
|
||||
override fun setTitle(title: CharSequence?) {
|
||||
|
||||
@@ -25,9 +25,7 @@ import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import java.io.*
|
||||
import java.lang.StringBuilder
|
||||
import java.nio.charset.Charset
|
||||
import java.util.*
|
||||
import java.util.zip.ZipEntry
|
||||
import java.util.zip.ZipInputStream
|
||||
import java.util.zip.ZipOutputStream
|
||||
@@ -41,13 +39,13 @@ interface LauncherObserver {
|
||||
fun onInstallFailure(msgId: Int)
|
||||
}
|
||||
|
||||
private const val SAVE_DIR = "save"
|
||||
|
||||
class Launcher private constructor(private val rootDir: File) {
|
||||
companion object {
|
||||
const val SAVE_DIR = "save"
|
||||
const val TITLE_FILE = "title.txt"
|
||||
const val PLAYLIST_FILE = "playlist2.txt"
|
||||
const val OLD_PLAYLIST_FILE = "playlist.txt"
|
||||
const val GAMEDIR_FILE = "game_directory.txt"
|
||||
const val PLAYLIST_FILE = "playlist.txt"
|
||||
const val OLD_PLAYLIST_FILE = "playlist2.txt"
|
||||
|
||||
fun getInstance(rootDir: File): Launcher {
|
||||
if (gLauncher == null) {
|
||||
@@ -79,14 +77,14 @@ class Launcher private constructor(private val rootDir: File) {
|
||||
isInstalling = true
|
||||
GlobalScope.launch(Dispatchers.Main) {
|
||||
try {
|
||||
withContext(Dispatchers.IO) {
|
||||
val gameDir = withContext(Dispatchers.IO) {
|
||||
extractFiles(input, dir) { msg ->
|
||||
GlobalScope.launch(Dispatchers.Main) {
|
||||
observer?.onInstallProgress(msg)
|
||||
}
|
||||
}
|
||||
}
|
||||
observer?.onInstallSuccess(dir, archiveName)
|
||||
observer?.onInstallSuccess(gameDir, archiveName)
|
||||
} catch (e: InstallFailureException) {
|
||||
observer?.onInstallFailure(e.msgId)
|
||||
} catch (e: Exception) {
|
||||
@@ -114,9 +112,11 @@ class Launcher private constructor(private val rootDir: File) {
|
||||
continue
|
||||
}
|
||||
try {
|
||||
val titleFile = File(path, TITLE_FILE)
|
||||
val gameDirFile = File(path, GAMEDIR_FILE)
|
||||
val gamePath = if (gameDirFile.exists()) File(path, gameDirFile.readText()) else path
|
||||
val titleFile = File(gamePath, TITLE_FILE)
|
||||
val title = titleFile.readText()
|
||||
games.add(Entry(path, title, titleFile.lastModified()))
|
||||
games.add(Entry(gamePath, title, titleFile.lastModified()))
|
||||
migratePlaylist(path)
|
||||
} catch (e: IOException) {
|
||||
// Incomplete game installation. Delete it.
|
||||
@@ -179,7 +179,7 @@ class Launcher private constructor(private val rootDir: File) {
|
||||
}
|
||||
}
|
||||
|
||||
private fun extractFiles(input: InputStream, outDir: File, progressCallback: (String) -> Unit) {
|
||||
private fun extractFiles(input: InputStream, outDir: File, progressCallback: (String) -> Unit): File {
|
||||
val configWriter = GameConfigWriter()
|
||||
val hadDecodeError = forEachZipEntry(input) { zipEntry, zip ->
|
||||
Log.i("extractFiles", zipEntry.name)
|
||||
@@ -193,90 +193,62 @@ class Launcher private constructor(private val rootDir: File) {
|
||||
}
|
||||
configWriter.maybeAdd(zipEntry.name)
|
||||
}
|
||||
if (!configWriter.readyToWrite()) {
|
||||
if (!configWriter.ready) {
|
||||
if (hadDecodeError)
|
||||
throw InstallFailureException(R.string.unsupported_zip)
|
||||
throw InstallFailureException(R.string.cannot_find_ald)
|
||||
}
|
||||
configWriter.write(outDir)
|
||||
return configWriter.gameDir?.let { File(outDir, it) } ?: outDir
|
||||
}
|
||||
|
||||
// Xsystem35-sdl2 <=2.2.0 had a bug where playlist had an extra empty line at
|
||||
// the beginning of the file. This migrates playlist.txt created by an old
|
||||
// version of xsystem35-sdl2 to playlist2.txt.
|
||||
// Xsystem35-sdl2 2.3.0 - 2.11.1 used playlist2.txt. Rename it to playlist.txt.
|
||||
private fun migratePlaylist(dir: File) {
|
||||
val oldPlaylist = File(dir, OLD_PLAYLIST_FILE)
|
||||
if (!oldPlaylist.exists())
|
||||
return
|
||||
var tracks = oldPlaylist.readLines()
|
||||
if (tracks.isNotEmpty())
|
||||
tracks = tracks.subList(1, tracks.size)
|
||||
File(dir, PLAYLIST_FILE).writeText(tracks.joinToString("\n"))
|
||||
oldPlaylist.delete()
|
||||
if (oldPlaylist.exists()) {
|
||||
oldPlaylist.renameTo(File(dir, PLAYLIST_FILE))
|
||||
}
|
||||
}
|
||||
|
||||
class InstallFailureException(val msgId: Int) : Exception()
|
||||
|
||||
// A helper class which generates xsystem35.gr and playlist.txt in the game root directory.
|
||||
// A helper class which generates GAMEDIR_FILE and PLAYLIST_FILE.
|
||||
private class GameConfigWriter {
|
||||
private val grb = StringBuilder()
|
||||
private var basename: String? = null
|
||||
private val aldRegex = """(.*?)([a-z])([a-z])\.(ald|wai|bgi)""".toRegex(RegexOption.IGNORE_CASE)
|
||||
private val aldType = mapOf(
|
||||
"b" to "BGM",
|
||||
"d" to "Data",
|
||||
"g" to "Graphics",
|
||||
"m" to "Midi",
|
||||
"r" to "Resource",
|
||||
"s" to "Scenario",
|
||||
"w" to "Wave")
|
||||
private val specialResources = mapOf(
|
||||
"system39.ain" to "Ain",
|
||||
"system39.ini" to "Init",
|
||||
"sactefam.kld" to "SACT01"
|
||||
)
|
||||
var ready = false
|
||||
private set
|
||||
var gameDir: String? = null
|
||||
private set
|
||||
private val aldRegex = """.*?s[a-z]\.ald""".toRegex(RegexOption.IGNORE_CASE)
|
||||
private val audioRegex = """.*?(\d+)\.(wav|mp3|ogg)""".toRegex(RegexOption.IGNORE_CASE)
|
||||
private val audioFiles: Array<String?> = arrayOfNulls(100)
|
||||
|
||||
fun maybeAdd(path: String) {
|
||||
val name = File(path).name
|
||||
|
||||
specialResources[name.lowercase(Locale.US)]?.let {
|
||||
grb.appendLine("$it $path")
|
||||
return
|
||||
aldRegex.matchEntire(path)?.let {
|
||||
gameDir = File(path).parent
|
||||
ready = true
|
||||
}
|
||||
aldRegex.matchEntire(name)?.let {
|
||||
val ext = it.groupValues[4].uppercase(Locale.US)
|
||||
val type = if (ext == "ALD") {
|
||||
aldType[it.groupValues[2].lowercase(Locale.US)]
|
||||
} else {
|
||||
ext
|
||||
}
|
||||
val id = it.groupValues[3].uppercase(Locale.US)
|
||||
if (type != null) {
|
||||
grb.appendLine("$type$id $path")
|
||||
basename = it.groupValues[1]
|
||||
}
|
||||
}
|
||||
audioRegex.matchEntire(name)?.let {
|
||||
audioRegex.matchEntire(path)?.let {
|
||||
val track = it.groupValues[1].toInt()
|
||||
if (0 < track && track <= audioFiles.size)
|
||||
audioFiles[track - 1] = path
|
||||
}
|
||||
}
|
||||
|
||||
fun readyToWrite() = basename != null
|
||||
|
||||
fun write(outDir: File) {
|
||||
for (id in 'A' .. 'Z') {
|
||||
grb.appendLine("Save$id ../save/${basename}s${id.lowercase(Locale.US)}.asd")
|
||||
// Generate GAMEDIR_FILE
|
||||
gameDir?.let {
|
||||
File(outDir, GAMEDIR_FILE).writeText(it)
|
||||
}
|
||||
// Generate PLAYLIST_FILE
|
||||
val absGameDir = gameDir?.let { File(outDir, it) } ?: outDir
|
||||
val playlistFile = File(absGameDir, PLAYLIST_FILE)
|
||||
if (!playlistFile.exists()) {
|
||||
val prefixToRemove = gameDir?.let { "$it/" } ?: ""
|
||||
val playlist = audioFiles.joinToString("\n") {
|
||||
it?.removePrefix(prefixToRemove) ?: ""
|
||||
}.trimEnd('\n')
|
||||
playlistFile.writeText(playlist)
|
||||
}
|
||||
val gr = grb.toString()
|
||||
Log.i("xsystem35.gr", gr)
|
||||
File(outDir, "xsystem35.gr").writeText(gr)
|
||||
|
||||
val playlist = audioFiles.joinToString("\n") { it ?: "" }.trimEnd('\n')
|
||||
File(outDir, PLAYLIST_FILE).writeText(playlist)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -180,6 +180,7 @@ class LauncherActivity : Activity(), LauncherObserver {
|
||||
val i = Intent()
|
||||
i.setClass(applicationContext, GameActivity::class.java)
|
||||
i.putExtra(GameActivity.EXTRA_GAME_ROOT, path.path)
|
||||
i.putExtra(GameActivity.EXTRA_SAVE_DIRECTORY, File(filesDir, Launcher.SAVE_DIR).path)
|
||||
i.putExtra(GameActivity.EXTRA_ARCHIVE_NAME, archiveName)
|
||||
startActivity(i)
|
||||
}
|
||||
|
||||
@@ -285,6 +285,7 @@ public class HIDDeviceManager {
|
||||
0x24c6, // PowerA
|
||||
0x2dc8, // 8BitDo
|
||||
0x2e24, // Hyperkin
|
||||
0x3537, // GameSir
|
||||
};
|
||||
|
||||
if (usbInterface.getId() == 0 &&
|
||||
@@ -358,6 +359,12 @@ public class HIDDeviceManager {
|
||||
private void initializeBluetooth() {
|
||||
Log.d(TAG, "Initializing Bluetooth");
|
||||
|
||||
if (Build.VERSION.SDK_INT >= 31 /* Android 12 */ &&
|
||||
mContext.getPackageManager().checkPermission(android.Manifest.permission.BLUETOOTH_CONNECT, mContext.getPackageName()) != PackageManager.PERMISSION_GRANTED) {
|
||||
Log.d(TAG, "Couldn't initialize Bluetooth, missing android.permission.BLUETOOTH_CONNECT");
|
||||
return;
|
||||
}
|
||||
|
||||
if (Build.VERSION.SDK_INT <= 30 /* Android 11.0 (R) */ &&
|
||||
mContext.getPackageManager().checkPermission(android.Manifest.permission.BLUETOOTH, mContext.getPackageName()) != PackageManager.PERMISSION_GRANTED) {
|
||||
Log.d(TAG, "Couldn't initialize Bluetooth, missing android.permission.BLUETOOTH");
|
||||
|
||||
@@ -60,8 +60,8 @@ import java.util.Locale;
|
||||
public class SDLActivity extends Activity implements View.OnSystemUiVisibilityChangeListener {
|
||||
private static final String TAG = "SDL";
|
||||
private static final int SDL_MAJOR_VERSION = 2;
|
||||
private static final int SDL_MINOR_VERSION = 28;
|
||||
private static final int SDL_MICRO_VERSION = 5;
|
||||
private static final int SDL_MINOR_VERSION = 30;
|
||||
private static final int SDL_MICRO_VERSION = 2;
|
||||
/*
|
||||
// Display InputType.SOURCE/CLASS of events and devices
|
||||
//
|
||||
|
||||
@@ -546,13 +546,15 @@ class SDLHapticHandler {
|
||||
if (haptic == null) {
|
||||
InputDevice device = InputDevice.getDevice(deviceIds[i]);
|
||||
Vibrator vib = device.getVibrator();
|
||||
if (vib.hasVibrator()) {
|
||||
haptic = new SDLHaptic();
|
||||
haptic.device_id = deviceIds[i];
|
||||
haptic.name = device.getName();
|
||||
haptic.vib = vib;
|
||||
mHaptics.add(haptic);
|
||||
SDLControllerManager.nativeAddHaptic(haptic.device_id, haptic.name);
|
||||
if (vib != null) {
|
||||
if (vib.hasVibrator()) {
|
||||
haptic = new SDLHaptic();
|
||||
haptic.device_id = deviceIds[i];
|
||||
haptic.name = device.getName();
|
||||
haptic.vib = vib;
|
||||
mHaptics.add(haptic);
|
||||
SDLControllerManager.nativeAddHaptic(haptic.device_id, haptic.name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+2
-8
@@ -1,13 +1,8 @@
|
||||
#cmakedefine PACKAGE "@PACKAGE@"
|
||||
#define VERSION "2.11.0"
|
||||
#define VERSION "2.11.5"
|
||||
|
||||
#cmakedefine CACHE_TOTALSIZE @CACHE_TOTALSIZE@
|
||||
|
||||
#cmakedefine ENABLE_CDROM_ANDROID @ENABLE_CDROM_ANDROID@
|
||||
#cmakedefine ENABLE_CDROM_BSD @ENABLE_CDROM_BSD@
|
||||
#cmakedefine ENABLE_CDROM_EMSCRIPTEN @ENABLE_CDROM_EMSCRIPTEN@
|
||||
#cmakedefine ENABLE_CDROM_LINUX @ENABLE_CDROM_LINUX@
|
||||
#cmakedefine ENABLE_CDROM_MP3 @ENABLE_CDROM_MP3@
|
||||
#cmakedefine ENABLE_DEBUGGER @ENABLE_DEBUGGER@
|
||||
#cmakedefine ENABLE_GTK @ENABLE_GTK@
|
||||
#cmakedefine ENABLE_MIDI_RAWMIDI @ENABLE_MIDI_RAWMIDI@
|
||||
@@ -15,9 +10,8 @@
|
||||
#cmakedefine ENABLE_MIDI_SEQMIDI @ENABLE_MIDI_SEQMIDI@
|
||||
#cmakedefine ENABLE_MIDI_PORTMIDI @ENABLE_MIDI_PORTMIDI@
|
||||
#cmakedefine ENABLE_NLS @ENABLE_NLS@
|
||||
#cmakedefine ENABLE_SDLMIXER @ENABLE_SDLMIXER@
|
||||
|
||||
#cmakedefine CDROM_DEVICE "@CDROM_DEVICE@"
|
||||
#cmakedefine DEFAULT_PLAYLIST_PATH "@DEFAULT_PLAYLIST_PATH@"
|
||||
#cmakedefine JOY_DEVICE "@JOY_DEVICE@"
|
||||
#cmakedefine MIDI_DEVICE "@MIDI_DEVICE@"
|
||||
#cmakedefine SEQ_DEVICE "@SEQ_DEVICE@"
|
||||
|
||||
@@ -5,11 +5,11 @@ Game Compatibility
|
||||
| ------------------------------------------- | ----------- | ----- |
|
||||
| 鬼畜王ランス | Supported | |
|
||||
| Kichikuou Rance (EN) | Supported | |
|
||||
| RanceIV -教団の遺産- | Supported | Win95 edition, [Ver2.05](https://hannylaboratory.blogspot.com/2023/01/blog-post_26.html) |
|
||||
| RanceIV -教団の遺産- | Supported | Win95 edition and [Ver2.05](https://hannylaboratory.blogspot.com/2023/01/blog-post_26.html) |
|
||||
| Rance4 -Legacy of the Sect- (EN) | Supported | |
|
||||
| 兰斯IV -教团的遗产- (CN) | Supported | |
|
||||
| ランス4.1 | Supported | [Ver1.05](https://hannylaboratory.blogspot.com/2023/02/blog-post_9.html) |
|
||||
| ランス4.2 | Supported | [Ver1.05](https://hannylaboratory.blogspot.com/2023/02/blog-post_9.html) |
|
||||
| ランス4.1 | Supported | [Ver1.05](https://hannylaboratory.blogspot.com/2023/02/blog-post_9.html). Use system3-sdl2 for older versions |
|
||||
| ランス4.2 | Supported | [Ver1.05](https://hannylaboratory.blogspot.com/2023/02/blog-post_9.html). Use system3-sdl2 for older versions |
|
||||
| いけないかつみ先生 | Supported | Emojis are not supported |
|
||||
| 闘神都市II | Supported | Win95 edition |
|
||||
| かえるにょ・ぱにょ~ん | Supported | Normal / Low-priced edition |
|
||||
@@ -76,7 +76,7 @@ Game Compatibility
|
||||
| マスカレイド | Supported | From アリスCD |
|
||||
| キャロル ~聖なる鐘が響く夜~ | Supported | From アリスCD, Online match is not supported |
|
||||
| できるかなー? | Supported | From アリスCD |
|
||||
| Child Assassin | Supported | From アリスCD |
|
||||
| Child Assassin | Unsupported | From アリスCD |
|
||||
| Klavier | Supported | From アリスCD |
|
||||
| 弱肉狂食 | Supported | From アリスCD |
|
||||
| 眼鏡大戦2 | Supported | From アリスCD |
|
||||
|
||||
+113
-49
@@ -21,57 +21,120 @@ target_include_directories(xsystem35 PRIVATE .)
|
||||
target_link_libraries(xsystem35 PRIVATE src_lib)
|
||||
|
||||
target_sources(xsystem35 PRIVATE
|
||||
xsystem35.c
|
||||
dri.c
|
||||
ags.c
|
||||
ald_manager.c
|
||||
alpha_plane.c
|
||||
bgi.c
|
||||
bmp.c
|
||||
cache.c
|
||||
${SRC_AUDIO}
|
||||
${SRC_CDROM}
|
||||
${SRC_MIDI}
|
||||
${SRC_MENU})
|
||||
cali.c
|
||||
cdrom.bgm.c
|
||||
cg.c
|
||||
cmd2F.c
|
||||
cmd2F60.c
|
||||
cmd_check.c
|
||||
cmdb.c
|
||||
cmdc.c
|
||||
cmdd.c
|
||||
cmde.c
|
||||
cmdf.c
|
||||
cmdg.c
|
||||
cmdh.c
|
||||
cmdi.c
|
||||
cmdj.c
|
||||
cmdk.c
|
||||
cmdl.c
|
||||
cmdm.c
|
||||
cmdn.c
|
||||
cmdo.c
|
||||
cmdp.c
|
||||
cmdq.c
|
||||
cmds.c
|
||||
cmdt.c
|
||||
cmdu.c
|
||||
cmdv.c
|
||||
cmdw.c
|
||||
cmdy.c
|
||||
cmdz.c
|
||||
cursor.c
|
||||
dri.c
|
||||
ecopy.c
|
||||
filecheck.c
|
||||
font.c
|
||||
hacks.c
|
||||
image.c
|
||||
input.c
|
||||
jpeg.c
|
||||
message.c
|
||||
midi.c
|
||||
mmap.c
|
||||
msgskip.c
|
||||
mt19937-1.c
|
||||
music.c
|
||||
music_cdrom.c
|
||||
music_midi.c
|
||||
nact.c
|
||||
network.c
|
||||
pms.c
|
||||
profile.c
|
||||
qnt.c
|
||||
s39ain.c
|
||||
savedata.c
|
||||
scenario.c
|
||||
sdl_cursor.c
|
||||
sdl_draw.c
|
||||
sdl_effect.c
|
||||
sdl_event.c
|
||||
sdl_image.c
|
||||
sdl_video.c
|
||||
selection.c
|
||||
texthook.c
|
||||
variable.c
|
||||
vsp.c
|
||||
xsystem35.c
|
||||
)
|
||||
|
||||
# System3.x commands
|
||||
target_sources(xsystem35 PRIVATE
|
||||
cmdb.c cmdc.c cmdd.c cmde.c cmdf.c cmdg.c cmdh.c cmdi.c cmdj.c
|
||||
cmdk.c cmdl.c cmdm.c cmdn.c cmdo.c cmdp.c cmdq.c cmds.c cmdt.c
|
||||
cmdu.c cmdv.c cmdw.c cmdy.c cmdz.c cmd2F.c cmd2F60.c)
|
||||
if (EMSCRIPTEN)
|
||||
target_sources(xsystem35 PRIVATE pcm.emscripten.c bgm.emscripten.c)
|
||||
else()
|
||||
target_sources(xsystem35 PRIVATE pcm.sdlmixer.c bgm.sdlmixer.c)
|
||||
endif()
|
||||
|
||||
# Graphics
|
||||
if (EMSCRIPTEN)
|
||||
target_sources(xsystem35 PRIVATE cdrom.emscripten.c)
|
||||
else()
|
||||
target_sources(xsystem35 PRIVATE cdrom.mp3.c)
|
||||
endif()
|
||||
|
||||
target_sources(xsystem35 PRIVATE
|
||||
sdl_video.c sdl_draw.c sdl_event.c sdl_image.c sdl_cursor.c sdl_effect.c
|
||||
image.c font.c)
|
||||
if (EMSCRIPTEN)
|
||||
target_sources(xsystem35 PRIVATE midi.emscripten.c)
|
||||
elseif (ANDROID)
|
||||
target_sources(xsystem35 PRIVATE midi.android.c)
|
||||
else()
|
||||
target_sources(xsystem35 PRIVATE midi.sdlmixer.c)
|
||||
if (ENABLE_MIDI_RAWMIDI)
|
||||
target_sources(xsystem35 PRIVATE midi.rawmidi.c midifile.c)
|
||||
endif()
|
||||
if (ENABLE_MIDI_PORTMIDI)
|
||||
target_sources(xsystem35 PRIVATE midi.portmidi.c)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if (EMSCRIPTEN)
|
||||
target_sources(xsystem35 PRIVATE menu_emscripten.c)
|
||||
elseif (ANDROID)
|
||||
target_sources(xsystem35 PRIVATE menu_android.c)
|
||||
elseif (ENABLE_GTK)
|
||||
target_sources(xsystem35 PRIVATE menu.c menu_callback.c menu_gui.c s39init.c)
|
||||
else ()
|
||||
target_sources(xsystem35 PRIVATE menu_sdl.c sdl_input.c)
|
||||
endif()
|
||||
|
||||
# CG
|
||||
target_sources(xsystem35 PRIVATE
|
||||
pms.c vsp.c bmp.c qnt.c jpeg.c)
|
||||
if (HAVE_WEBP)
|
||||
target_sources(xsystem35 PRIVATE webp.c)
|
||||
target_link_libraries(xsystem35 PRIVATE WebP)
|
||||
endif()
|
||||
|
||||
# Music
|
||||
target_sources(xsystem35 PRIVATE
|
||||
music.c music_cdrom.c music_midi.c midi.c cdrom.c)
|
||||
|
||||
# Misc
|
||||
target_sources(xsystem35 PRIVATE
|
||||
input.c profile.c mt19937-1.c filecheck.c mmap.c hacks.c)
|
||||
|
||||
# Scenario
|
||||
target_sources(xsystem35 PRIVATE
|
||||
cali.c scenario.c variable.c cmd_check.c nact.c
|
||||
selection.c message.c savedata.c s39ain.c texthook.c msgskip.c)
|
||||
|
||||
# Graphics
|
||||
target_sources(xsystem35 PRIVATE
|
||||
ags.c cg.c ecopy.c alpha_plane.c cursor.c)
|
||||
|
||||
# Network
|
||||
target_sources(xsystem35 PRIVATE
|
||||
network.c)
|
||||
|
||||
# Debugger
|
||||
if (ENABLE_DEBUGGER)
|
||||
target_sources(xsystem35 PRIVATE
|
||||
debug_symbol.c debugger.c debugger_cui.c debugger_dap.c)
|
||||
@@ -95,15 +158,16 @@ if (EMSCRIPTEN)
|
||||
list(APPEND CMAKE_EXE_LINKER_FLAGS_DEBUG "-O1")
|
||||
|
||||
target_link_options(xsystem35 PRIVATE
|
||||
"SHELL:-s ENVIRONMENT=web"
|
||||
"SHELL:-s ASYNCIFY=1 -s ASYNCIFY_IGNORE_INDIRECT=1"
|
||||
"SHELL:-s ASYNCIFY_REMOVE=SDL_Delay"
|
||||
"SHELL:-s ASYNCIFY_IMPORTS=muspcm_load_no,muspcm_load_data,muspcm_load_mixlr,muspcm_waitend,wait_vsync,load_mincho_font"
|
||||
"SHELL:-s ASYNCIFY_ADD=commands2F60,nact_main,send_agsevent,cb_waitkey_sprite"
|
||||
"SHELL:-s ALLOW_MEMORY_GROWTH=1"
|
||||
"SHELL:-s NO_EXIT_RUNTIME=1"
|
||||
"SHELL:-s EXPORTED_FUNCTIONS=_main,_malloc"
|
||||
"SHELL:-s EXPORTED_RUNTIME_METHODS=getValue,addRunDependency,removeRunDependency")
|
||||
-sENVIRONMENT=web
|
||||
-sASYNCIFY=1
|
||||
-sASYNCIFY_IGNORE_INDIRECT=1
|
||||
-sASYNCIFY_REMOVE=SDL_Delay
|
||||
-sASYNCIFY_IMPORTS=muspcm_load_no,muspcm_load_data,muspcm_load_mixlr,muspcm_waitend,wait_vsync,load_mincho_font
|
||||
-sASYNCIFY_ADD=commands2F60,nact_main,send_agsevent,cb_waitkey_sprite
|
||||
-sALLOW_MEMORY_GROWTH=1
|
||||
-sNO_EXIT_RUNTIME=1
|
||||
-sEXPORTED_FUNCTIONS=_main,_malloc
|
||||
-sEXPORTED_RUNTIME_METHODS=getValue,addRunDependency,removeRunDependency)
|
||||
|
||||
elseif (ANDROID)
|
||||
target_link_libraries(xsystem35 PRIVATE ${ndk_log})
|
||||
|
||||
@@ -1,75 +0,0 @@
|
||||
/*
|
||||
* bgm.dummy.c BGM (*BA.ALD) dummy implementation
|
||||
*
|
||||
* Copyright (C) 2019 <KichikuouChrome@gmail.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include "portab.h"
|
||||
#include "bgm.h"
|
||||
|
||||
int musbgm_init(DRIFILETYPE type, int base_no) {
|
||||
return NG;
|
||||
}
|
||||
|
||||
int musbgm_exit(void) {
|
||||
return NG;
|
||||
}
|
||||
|
||||
int musbgm_reset(void) {
|
||||
return NG;
|
||||
}
|
||||
|
||||
int musbgm_play(int no, int time, int vol) {
|
||||
WARNING("not implemented");
|
||||
return NG;
|
||||
}
|
||||
|
||||
int musbgm_stop(int no, int time) {
|
||||
WARNING("not implemented");
|
||||
return NG;
|
||||
}
|
||||
|
||||
int musbgm_fade(int no, int time, int vol) {
|
||||
WARNING("not implemented");
|
||||
return NG;
|
||||
}
|
||||
|
||||
int musbgm_getpos(int no) {
|
||||
WARNING("not implemented");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int musbgm_getlen(int no) {
|
||||
WARNING("not implemented");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int musbgm_isplaying(int no) {
|
||||
WARNING("not implemented");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int musbgm_stopall(int time) {
|
||||
WARNING("not implemented");
|
||||
return NG;
|
||||
}
|
||||
|
||||
int musbgm_wait(int no, int timeout) {
|
||||
WARNING("not implemented");
|
||||
return NG;
|
||||
}
|
||||
@@ -1,238 +0,0 @@
|
||||
/*
|
||||
* cdrom.FreeBSD.c CD-ROMアクセス
|
||||
*
|
||||
* Copyright (C) 1997-1998 Masaki Chikama (Wren) <chikama@kasumi.ipl.mech.nagoya-u.ac.jp>
|
||||
* 1998- <masaki-c@is.aist-nara.ac.jp>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
/* $Id: cdrom.FreeBSD.c,v 1.17 2002/08/18 09:35:29 chikama Exp $ */
|
||||
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/cdio.h>
|
||||
|
||||
#include "portab.h"
|
||||
#include "cdrom.h"
|
||||
#include "music_private.h"
|
||||
#include "system.h"
|
||||
|
||||
static int cdrom_init(char *);
|
||||
static int cdrom_exit(void);
|
||||
static int cdrom_reset(void);
|
||||
static int cdrom_start(int, int);
|
||||
static int cdrom_stop();
|
||||
static int cdrom_getPlayingInfo(cd_time *);
|
||||
|
||||
#define cdrom cdrom_bsd
|
||||
cdromdevice_t cdrom = {
|
||||
cdrom_init,
|
||||
cdrom_exit,
|
||||
cdrom_reset,
|
||||
cdrom_start,
|
||||
cdrom_stop,
|
||||
cdrom_getPlayingInfo,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
static int cd_fd;
|
||||
static boolean enabled = FALSE;
|
||||
static struct cd_toc_entry toc_buffer[100];
|
||||
static boolean msfmode = TRUE; /* default は MSFPLAY mode */
|
||||
static int lastindex; /* 最終トラック */
|
||||
|
||||
/* ioctlがエラーで帰って来る場合 IOCTL_RETRY_TIME 回リトライする */
|
||||
static int do_ioctl(int cmd, void *data) {
|
||||
int i;
|
||||
for (i = 0; i < CDROM_IOCTL_RETRY_TIME; i++) {
|
||||
if (0 <= ioctl(cd_fd, cmd, data)) {
|
||||
return 0;
|
||||
}
|
||||
usleep(CDROM_IOCTL_RETRY_INTERVAL * 100 * 1000);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* CD-ROM の目次を読み出しておく */
|
||||
static int get_cd_entry() {
|
||||
int endtrk, i;
|
||||
struct ioc_toc_header tochdr;
|
||||
struct ioc_read_toc_entry toc;
|
||||
struct ioc_play_msf msf;
|
||||
|
||||
/* 最終トラック番号を得る */
|
||||
if (do_ioctl(CDIOREADTOCHEADER, &tochdr) < 0) {
|
||||
WARNING("CDIOREADTOCHEADER: %s", strerror(errno));
|
||||
return NG;
|
||||
}
|
||||
|
||||
lastindex = endtrk = tochdr.ending_track;
|
||||
i = tochdr.ending_track - tochdr.starting_track + 1;
|
||||
if (endtrk <= 1) { /* 2トラック以上ないとダメ */
|
||||
WARNING("No CD-AUDIO in CD-ROM");
|
||||
return NG;
|
||||
}
|
||||
|
||||
prv.cd_maxtrk = lastindex;
|
||||
|
||||
/* すべてのトラックの目次を読みだしてキャッシュしておく */
|
||||
toc.address_format = CD_MSF_FORMAT;
|
||||
toc.starting_track = 0;
|
||||
toc.data_len = (i + 1) * sizeof(struct cd_toc_entry);
|
||||
toc.data = toc_buffer;
|
||||
if (do_ioctl(CDIOREADTOCENTRYS, &toc) < 0) {
|
||||
WARNING("CDIOREADTOCENTRYS: %s", strerror(errno));
|
||||
return NG;
|
||||
}
|
||||
|
||||
#ifdef CDROM_USE_TRKIND_ONLY
|
||||
msfmode = FALSE;
|
||||
return OK;
|
||||
#endif
|
||||
|
||||
/* CDROMPLAYMSF が有効かチェック */
|
||||
msf.start_m = toc_buffer[1].addr.msf.minute;
|
||||
msf.start_s = toc_buffer[1].addr.msf.second;
|
||||
msf.start_f = toc_buffer[1].addr.msf.frame;
|
||||
msf.end_m = toc_buffer[2].addr.msf.minute;
|
||||
msf.end_s = toc_buffer[2].addr.msf.second;
|
||||
msf.end_f = toc_buffer[2].addr.msf.frame;
|
||||
if (do_ioctl(CDIOCPLAYMSF, &msf) < 0) {
|
||||
WARNING("CDIOPLAYMSF: %s", strerror(errno));
|
||||
WARNING("CD-ROM: change TRKMODE");
|
||||
msfmode = FALSE;
|
||||
}
|
||||
/* stop */
|
||||
if (do_ioctl(CDIOCSTOP, NULL) < 0) {
|
||||
WARNING("CDIOCSTOP: %s", strerror(errno));
|
||||
return NG;
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
/* デバイスの初期化 */
|
||||
int cdrom_init(char *dev_cd) {
|
||||
if (dev_cd == NULL) return NG;
|
||||
|
||||
if ((cd_fd = open(dev_cd, O_RDONLY, 0)) < 0) {
|
||||
WARNING("CDROM_DEVICE OPEN: %s", strerror(errno));
|
||||
enabled = FALSE;
|
||||
return NG;
|
||||
}
|
||||
if (OK == get_cd_entry()) {
|
||||
enabled = TRUE;
|
||||
return OK;
|
||||
}
|
||||
enabled = FALSE;
|
||||
return NG;
|
||||
}
|
||||
|
||||
/* デバイスの後始末 */
|
||||
int cdrom_exit(void) {
|
||||
if (enabled) {
|
||||
cdrom_stop();
|
||||
close(cd_fd);
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
int cdrom_reset(void) {
|
||||
return cdrom_stop();
|
||||
}
|
||||
|
||||
/* トラック番号 trk の演奏 trk = 1~ */
|
||||
int cdrom_start(int trk, int loop) {
|
||||
struct ioc_play_msf msf;
|
||||
struct ioc_play_track track;
|
||||
|
||||
if (!enabled) return NG;
|
||||
|
||||
/* 曲数よりも多い指定は不可*/
|
||||
if (trk > lastindex) {
|
||||
return NG;
|
||||
}
|
||||
/* drive spin up */
|
||||
if (do_ioctl(CDIOCSTART, NULL) < 0) {
|
||||
WARNING("CDIOCSTART: %s", strerror(errno));
|
||||
return NG;
|
||||
}
|
||||
if (msfmode) {
|
||||
msf.start_m = toc_buffer[trk - 1].addr.msf.minute;
|
||||
msf.start_s = toc_buffer[trk - 1].addr.msf.second;
|
||||
msf.start_f = toc_buffer[trk - 1].addr.msf.frame;
|
||||
msf.end_m = toc_buffer[trk].addr.msf.minute;
|
||||
msf.end_s = toc_buffer[trk].addr.msf.second;
|
||||
msf.end_f = toc_buffer[trk].addr.msf.frame;
|
||||
if (do_ioctl(CDIOCPLAYMSF, &msf) < 0) {
|
||||
WARNING("CDIOPLAYMSF: %s", strerror(errno));
|
||||
return NG;
|
||||
}
|
||||
} else {
|
||||
track.start_track = track.end_track = trk;
|
||||
track.start_index = track.end_index = 0;
|
||||
if (do_ioctl(CDIOCPLAYTRACKS, &track) < 0) {
|
||||
WARNING("CDIOCPLAYTRACKS: %s", strerror(errno));
|
||||
return NG;
|
||||
}
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
/* 演奏停止 */
|
||||
int cdrom_stop() {
|
||||
if (enabled) {
|
||||
/* if (do_ioctl(CDIOCSTOP, NULL) < 0) { */
|
||||
if (do_ioctl(CDIOCPAUSE, NULL) < 0) {
|
||||
/* WARNING("CDIOCSTOP: %s", strerror(errno)); */
|
||||
WARNING("CDIOCPAUSE: %s", strerror(errno));
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
return NG;
|
||||
}
|
||||
|
||||
/* 現在演奏中のトラック情報の取得 */
|
||||
int cdrom_getPlayingInfo (cd_time *info) {
|
||||
struct ioc_read_subchannel s;
|
||||
struct cd_sub_channel_info data;
|
||||
|
||||
if (!enabled)
|
||||
return NG;
|
||||
memset(&s, 0, sizeof(s));
|
||||
|
||||
s.data = &data;
|
||||
s.data_len = sizeof (data);
|
||||
s.address_format = CD_MSF_FORMAT;
|
||||
s.data_format = CD_CURRENT_POSITION;
|
||||
if (do_ioctl(CDIOCREADSUBCHANNEL, &s) < 0) {
|
||||
WARNING("CDIOCREADSUBCHANNEL: %s", strerror(errno));
|
||||
return NG;
|
||||
}
|
||||
if (s.data->header.audio_status != CD_AS_PLAY_IN_PROGRESS) {
|
||||
return NG;
|
||||
}
|
||||
info->t = s.data->what.position.track_number;
|
||||
info->m = s.data->what.position.reladdr.msf.minute;
|
||||
info->s = s.data->what.position.reladdr.msf.second;
|
||||
info->f = s.data->what.position.reladdr.msf.frame;
|
||||
return OK;
|
||||
}
|
||||
@@ -1,268 +0,0 @@
|
||||
/*
|
||||
* cdrom.Linux.c CD-ROMアクセス
|
||||
*
|
||||
* Copyright (C) 1997-1998 Masaki Chikama (Wren) <chikama@kasumi.ipl.mech.nagoya-u.ac.jp>
|
||||
* 1998- <masaki-c@is.aist-nara.ac.jp>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
/* $Id: cdrom.Linux.c,v 1.18 2002/08/18 09:35:29 chikama Exp $ */
|
||||
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#if defined(sun)
|
||||
#include <sys/cdio.h>
|
||||
struct cdrom_msf0 {
|
||||
unsigned char minute; /* minute */
|
||||
unsigned char second; /* second */
|
||||
unsigned char frame; /* frame */
|
||||
};
|
||||
#else
|
||||
#include <linux/cdrom.h>
|
||||
#endif /* sun */
|
||||
|
||||
#include "portab.h"
|
||||
#include "cdrom.h"
|
||||
#include "music_private.h"
|
||||
#include "system.h"
|
||||
|
||||
static int cdrom_init(char *);
|
||||
static int cdrom_exit(void);
|
||||
static int cdrom_reset(void);
|
||||
static int cdrom_start(int, int);
|
||||
static int cdrom_stop();
|
||||
static int cdrom_getPlayingInfo(cd_time *);
|
||||
|
||||
#define cdrom cdrom_linux
|
||||
cdromdevice_t cdrom = {
|
||||
cdrom_init,
|
||||
cdrom_exit,
|
||||
cdrom_reset,
|
||||
cdrom_start,
|
||||
cdrom_stop,
|
||||
cdrom_getPlayingInfo,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
static int cd_fd;
|
||||
static boolean enabled = FALSE;
|
||||
static struct cdrom_msf0 tocmsf[100];
|
||||
static boolean msfmode = TRUE; /* default は MSFPLAY mode */
|
||||
static int lastindex; /* 最終トラック */
|
||||
|
||||
|
||||
/* ioctlがエラーで帰って来る場合 IOCTL_RETRY_TIME 回リトライする */
|
||||
static int do_ioctl(int cmd, void *data) {
|
||||
int i;
|
||||
for (i = 0; i < CDROM_IOCTL_RETRY_TIME; i++) {
|
||||
if (0 <= ioctl(cd_fd, cmd, data)) {
|
||||
return 0;
|
||||
}
|
||||
usleep(CDROM_IOCTL_RETRY_INTERVAL * 100 * 1000);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* CD-ROM の目次を読み出しておく */
|
||||
static int get_cd_entry() {
|
||||
int endtrk, i;
|
||||
struct cdrom_tochdr tochdr;
|
||||
struct cdrom_tocentry toc;
|
||||
struct cdrom_msf msf;
|
||||
|
||||
/* 最終トラック番号を得る */
|
||||
if (do_ioctl(CDROMREADTOCHDR, &tochdr) < 0) {
|
||||
WARNING("CDROMREADTOCHDR: %s", strerror(errno));
|
||||
return NG;
|
||||
}
|
||||
lastindex = endtrk = tochdr.cdth_trk1;
|
||||
if (endtrk <= 1) { /* 2トラック以上ないとダメ */
|
||||
WARNING("No CD-AUDIO in CD-ROM");
|
||||
return NG;
|
||||
}
|
||||
|
||||
prv.cd_maxtrk = lastindex;
|
||||
|
||||
/* すべてのトラックの目次を読みだしてキャッシュしておく */
|
||||
toc.cdte_format = CDROM_MSF;
|
||||
for (i = 1; i <= endtrk; i++) {
|
||||
toc.cdte_track = i;
|
||||
if (do_ioctl(CDROMREADTOCENTRY, &toc) < 0) {
|
||||
WARNING("CDROMREADTOCENTRY: %s", strerror(errno));
|
||||
return NG;
|
||||
}
|
||||
tocmsf[i - 1].minute = toc.cdte_addr.msf.minute;
|
||||
tocmsf[i - 1].second = toc.cdte_addr.msf.second;
|
||||
tocmsf[i - 1].frame = toc.cdte_addr.msf.frame;
|
||||
}
|
||||
/* リードアウトを読み出す */
|
||||
toc.cdte_track = CDROM_LEADOUT;
|
||||
if (do_ioctl(CDROMREADTOCENTRY, &toc) < 0) {
|
||||
WARNING("CDROMREADTOCENTRY: %s", strerror(errno));
|
||||
return NG;
|
||||
}
|
||||
|
||||
#ifdef PPC
|
||||
/* Linux PPC 対策 ;last track -1 frame */
|
||||
FRAMES_TO_MSF(MSF_TO_FRAMES(toc.cdte_addr.msf.minute,
|
||||
toc.cdte_addr.msf.second,
|
||||
toc.cdte_addr.msf.frame) - 1,
|
||||
&tocmsf[endtrk].minute,
|
||||
&tocmsf[endtrk].second,
|
||||
&tocmsf[endtrk].frame);
|
||||
#else
|
||||
tocmsf[endtrk].minute = toc.cdte_addr.msf.minute;
|
||||
tocmsf[endtrk].second = toc.cdte_addr.msf.second;
|
||||
tocmsf[endtrk].frame = toc.cdte_addr.msf.frame;
|
||||
#endif
|
||||
|
||||
#ifdef CDROM_USE_TRKIND_ONLY
|
||||
msfmode = FALSE;
|
||||
return OK;
|
||||
#endif
|
||||
|
||||
/* CDROMPLAYMSF が有効かチェック */
|
||||
msf.cdmsf_min0 = tocmsf[1].minute;
|
||||
msf.cdmsf_sec0 = tocmsf[1].second;
|
||||
msf.cdmsf_frame0 = tocmsf[1].frame;
|
||||
msf.cdmsf_min1 = tocmsf[2].minute;
|
||||
msf.cdmsf_sec1 = tocmsf[2].second;
|
||||
msf.cdmsf_frame1 = tocmsf[2].frame;
|
||||
if (do_ioctl(CDROMPLAYMSF, &msf) < 0) {
|
||||
WARNING("CDROMPLAYMSF: %s", strerror(errno));
|
||||
WARNING("CD-ROM: change TRKIND mode");
|
||||
msfmode = FALSE;
|
||||
}
|
||||
/* stop */
|
||||
if (do_ioctl(CDROMSTOP, NULL) < 0) {
|
||||
WARNING("CDROMSTOP: %s", strerror(errno));
|
||||
return NG;
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
/* デバイスの初期化 */
|
||||
static int cdrom_init(char *dev_cd) {
|
||||
if (dev_cd == NULL) return NG;
|
||||
|
||||
if ((cd_fd = open(dev_cd, O_RDONLY, 0)) < 0) {
|
||||
WARNING("CDROM_DEVICE OPEN: %s", strerror(errno));
|
||||
enabled = FALSE;
|
||||
return NG;
|
||||
}
|
||||
if (OK == get_cd_entry()) {
|
||||
enabled = TRUE;
|
||||
return OK;
|
||||
}
|
||||
enabled = FALSE;
|
||||
return NG;
|
||||
}
|
||||
|
||||
/* デバイスの後始末 */
|
||||
static int cdrom_exit(void) {
|
||||
if (enabled) {
|
||||
cdrom_stop();
|
||||
close(cd_fd);
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
static int cdrom_reset(void) {
|
||||
return cdrom_stop();
|
||||
}
|
||||
|
||||
/* トラック番号 trk の演奏 trk = 1~ */
|
||||
static int cdrom_start(int trk, int loop) {
|
||||
struct cdrom_msf msf;
|
||||
struct cdrom_ti ti;
|
||||
|
||||
if (!enabled) return NG;
|
||||
|
||||
/* 曲数よりも多い指定は不可*/
|
||||
if (trk > lastindex) {
|
||||
return NG;
|
||||
}
|
||||
/* drive spin up */
|
||||
if (do_ioctl(CDROMSTART, NULL) < 0) {
|
||||
WARNING("CDROMSTART: %s", strerror(errno));
|
||||
return NG;
|
||||
}
|
||||
|
||||
if (msfmode) {
|
||||
msf.cdmsf_min0 = tocmsf[trk - 1].minute;
|
||||
msf.cdmsf_sec0 = tocmsf[trk - 1].second;
|
||||
msf.cdmsf_frame0 = tocmsf[trk - 1].frame;
|
||||
msf.cdmsf_min1 = tocmsf[trk].minute;
|
||||
msf.cdmsf_sec1 = tocmsf[trk].second;
|
||||
msf.cdmsf_frame1 = tocmsf[trk].frame;
|
||||
if (do_ioctl(CDROMPLAYMSF, &msf) < 0) {
|
||||
WARNING("CDROMPLAYMSF: %s", strerror(errno));
|
||||
return NG;
|
||||
}
|
||||
return OK;
|
||||
} else {
|
||||
ti.cdti_trk0 = ti.cdti_trk1 = trk;
|
||||
ti.cdti_ind0 = ti.cdti_ind1 = 0;
|
||||
if (do_ioctl(CDROMPLAYTRKIND, &ti) < 0) {
|
||||
WARNING("CDROMPLAYTRKIND: %s", strerror(errno));
|
||||
return NG;
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
}
|
||||
|
||||
/* 演奏停止 */
|
||||
static int cdrom_stop() {
|
||||
if (enabled) {
|
||||
/* if (do_ioctl(CDROMSTOP, NULL) < 0) { */
|
||||
if (do_ioctl(CDROMPAUSE, NULL) < 0) {
|
||||
/* WARNING("CDROMSTOP: %s", strerror(errno)); */
|
||||
WARNING("CDROMPAUSE: %s", strerror(errno));
|
||||
return NG;
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
return NG;
|
||||
}
|
||||
|
||||
/* 現在演奏中のトラック情報の取得 */
|
||||
static int cdrom_getPlayingInfo (cd_time *info) {
|
||||
struct cdrom_subchnl sc;
|
||||
|
||||
if (!enabled)
|
||||
return NG;
|
||||
|
||||
sc.cdsc_format = CDROM_MSF;
|
||||
if (do_ioctl(CDROMSUBCHNL, &sc) < 0) {
|
||||
WARNING("CDROMSUBCHNL: %s", strerror(errno));
|
||||
return NG;
|
||||
}
|
||||
if (sc.cdsc_audiostatus != CDROM_AUDIO_PLAY) {
|
||||
return NG;
|
||||
}
|
||||
info->t = sc.cdsc_trk;
|
||||
info->m = sc.cdsc_reladdr.msf.minute;
|
||||
info->s = sc.cdsc_reladdr.msf.second;
|
||||
info->f = sc.cdsc_reladdr.msf.frame;
|
||||
return OK;
|
||||
}
|
||||
+1
-1
@@ -28,7 +28,7 @@
|
||||
|
||||
static int current_track;
|
||||
|
||||
static int cdrom_bgm_init(char *dev) {
|
||||
static int cdrom_bgm_init(char *playlist) {
|
||||
prv.cd_maxtrk = ald_get_maxno(DRIFILE_BGM) + 1;
|
||||
return OK;
|
||||
}
|
||||
|
||||
-71
@@ -1,71 +0,0 @@
|
||||
/*
|
||||
* cdrom.c CD-ROM control wrapper
|
||||
*
|
||||
* Copyright (C) 2000- Masaki Chikama (Wren) <masaki-c@is.aist-nara.ac.jp>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
/* $Id: cdrom.c,v 1.20 2002/08/18 09:35:29 chikama Exp $ */
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/stat.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "portab.h"
|
||||
#include "cdrom.h"
|
||||
#include "system.h"
|
||||
|
||||
#if defined(ENABLE_CDROM_LINUX)
|
||||
extern cdromdevice_t cdrom_linux;
|
||||
#define NATIVE_CD_DEVICE &cdrom_linux
|
||||
|
||||
#elif defined(ENABLE_CDROM_BSD)
|
||||
extern cdromdevice_t cdrom_bsd;
|
||||
#define NATIVE_CD_DEVICE &cdrom_bsd
|
||||
|
||||
#elif defined(ENABLE_CDROM_EMSCRIPTEN)
|
||||
extern cdromdevice_t cdrom_emscripten;
|
||||
#define NATIVE_CD_DEVICE &cdrom_emscripten
|
||||
|
||||
#else
|
||||
|
||||
extern cdromdevice_t cdrom_empty;
|
||||
#define NATIVE_CD_DEVICE &cdrom_empty
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_CDROM_MP3
|
||||
extern cdromdevice_t cdrom_mp3;
|
||||
#endif
|
||||
|
||||
cdromdevice_t *cd_init(const char *dev) {
|
||||
#if defined(ENABLE_CDROM_EMSCRIPTEN)
|
||||
return NATIVE_CD_DEVICE;
|
||||
#else
|
||||
struct stat st;
|
||||
if (dev && stat(dev, &st) && (S_ISBLK(st.st_mode) || S_ISCHR(st.st_mode)))
|
||||
return NATIVE_CD_DEVICE;
|
||||
|
||||
#ifdef ENABLE_CDROM_MP3
|
||||
return &cdrom_mp3;
|
||||
#else
|
||||
WARNING("no cdrom device available");
|
||||
return NULL;
|
||||
#endif
|
||||
#endif // ENABLE_CDROM_EMSCRIPTEN
|
||||
}
|
||||
@@ -1,69 +0,0 @@
|
||||
/*
|
||||
* cdrom.empty.c CD-ROMアクセス
|
||||
*
|
||||
* Copyright (C) 1997-1998 Masaki Chikama (Wren) <chikama@kasumi.ipl.mech.nagoya-u.ac.jp>
|
||||
* 1998- <masaki-c@is.aist-nara.ac.jp>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
/* $Id: cdrom.empty.c,v 1.8 2002/08/18 09:35:29 chikama Exp $ */
|
||||
|
||||
#include <unistd.h>
|
||||
#include "portab.h"
|
||||
#include "cdrom.h"
|
||||
|
||||
static int cdrom_init(char *);
|
||||
static int cdrom_exit(void);
|
||||
static int cdrom_reset(void);
|
||||
static int cdrom_start(int, int);
|
||||
static int cdrom_stop();
|
||||
static int cdrom_getPlayingInfo(cd_time *);
|
||||
|
||||
#define cdrom cdrom_empty
|
||||
cdromdevice_t cdrom = {
|
||||
cdrom_init,
|
||||
cdrom_exit,
|
||||
cdrom_reset,
|
||||
cdrom_start,
|
||||
cdrom_stop,
|
||||
cdrom_getPlayingInfo,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
int cdrom_init(char *name) {
|
||||
return NG;
|
||||
}
|
||||
|
||||
int cdrom_exit(void) {
|
||||
return OK;
|
||||
}
|
||||
|
||||
int cdrom_reset(void) {
|
||||
return OK;
|
||||
}
|
||||
|
||||
int cdrom_start(int trk, int loop) {
|
||||
return OK;
|
||||
}
|
||||
|
||||
int cdrom_stop() {
|
||||
return OK;
|
||||
}
|
||||
|
||||
int cdrom_getPlayingInfo (cd_time *info) {
|
||||
return NG;
|
||||
}
|
||||
@@ -27,7 +27,7 @@
|
||||
|
||||
static int frame_of_getpos = -1;
|
||||
|
||||
int cdrom_init(char *name) {
|
||||
int cdrom_init(char *playlist) {
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -51,8 +51,6 @@ typedef struct _cdromdevice cdromdevice_t;
|
||||
|
||||
extern cdromdevice_t cdrom_bgm;
|
||||
|
||||
extern cdromdevice_t *cd_init(const char *dev);
|
||||
|
||||
#define CD_FPS 75
|
||||
#define FRAMES_TO_MSF(f, M,S,F) { \
|
||||
int value = f; \
|
||||
|
||||
@@ -64,6 +64,9 @@ static int start_time;
|
||||
static int cdrom_init(char *playlist_path) {
|
||||
char buf[256];
|
||||
|
||||
if (!playlist_path || !playlist_path[0])
|
||||
return NG;
|
||||
|
||||
FILE *fp = fopen(playlist_path, "r");
|
||||
if (fp) {
|
||||
// Skip the first line
|
||||
|
||||
+18
-3
@@ -42,11 +42,14 @@
|
||||
#include "ald_manager.h"
|
||||
#include "LittleEndian.h"
|
||||
#include "hacks.h"
|
||||
#include "filecheck.h"
|
||||
|
||||
/* 選択 Window OPEN 時 callback */
|
||||
static int cb_sel_init_page = 0;
|
||||
static int cb_sel_init_address = 0;
|
||||
|
||||
static const char REGREADSTRING_RESULT[] = "*regReadString*";
|
||||
|
||||
extern INPUTSTRING_PARAM mi_param;
|
||||
|
||||
extern void commandH();
|
||||
@@ -1441,7 +1444,10 @@ void commands2F87() {
|
||||
int eBaneStrNum = getCaliValue();
|
||||
int eResultStrNum = getCaliValue();
|
||||
int *vResult = getCaliVariable();
|
||||
|
||||
|
||||
// This command is used to check if the game is installed, so we always
|
||||
// return 1 with the dummy string REGREADSTRING_RESULT.
|
||||
svar_set(eResultStrNum, REGREADSTRING_RESULT);
|
||||
*vResult = 1;
|
||||
|
||||
DEBUG_COMMAND("regReadString %d,%d,%d,%d:",
|
||||
@@ -1451,8 +1457,17 @@ void commands2F87() {
|
||||
void commands2F88() {
|
||||
int eFileNameStrNum = getCaliValue();
|
||||
int *vResult = getCaliVariable();
|
||||
|
||||
*vResult = 1;
|
||||
|
||||
const char *fname = svar_get(eFileNameStrNum);
|
||||
if (strcmp(fname, REGREADSTRING_RESULT) == 0) {
|
||||
// If this command is called with the result of regReadString, the game
|
||||
// is checking if the game CD is inserted. We return 1 in this case.
|
||||
*vResult = 1;
|
||||
} else {
|
||||
char *fname_utf8 = sjis2utf(fname);
|
||||
*vResult = fc_exists(fname_utf8) ? 1 : 0;
|
||||
free(fname_utf8);
|
||||
}
|
||||
|
||||
DEBUG_COMMAND("fileCheckExist %d,%d:", eFileNameStrNum, *vResult);
|
||||
}
|
||||
|
||||
+1
-1
@@ -72,7 +72,7 @@ void commandCX() {
|
||||
case 0:
|
||||
// In Daiakuji, the image after the blending is used as a source image
|
||||
// for sprite copy (CX 1). SDL's SIMD blending implementation has some
|
||||
// error (blending #ff00ff and #ff00ff results in #fd00fd), so the
|
||||
// error (https://github.com/libsdl-org/SDL/issues/3364), so the
|
||||
// resulting color may not match the colorkey of CX 1. To workaround
|
||||
// this, specify a small alpha mod so that SDL will use a "slow path"
|
||||
// that does accurate calculation.
|
||||
|
||||
+2
-2
@@ -33,7 +33,7 @@
|
||||
#include "ags.h"
|
||||
#include "message.h"
|
||||
#include "hankaku.h"
|
||||
|
||||
#include "hacks.h"
|
||||
|
||||
/* MI 用パラメータ */
|
||||
INPUTSTRING_PARAM mi_param;
|
||||
@@ -60,7 +60,7 @@ void commandMP() {
|
||||
char *str;
|
||||
|
||||
/* Patched English executable appends num2 spaces instead of truncating */
|
||||
if (nact->game == GAME_RANCE3_ENG || nact->game == GAME_RANCE4_ENG) {
|
||||
if (game_id == GAME_RANCE3_ENG || game_id == GAME_RANCE4_ENG) {
|
||||
str = calloc(strlen(src) + num2 * strlen(fullwidth_blank[nact->encoding]) + 1, 1);
|
||||
if (NULL == str) {
|
||||
NOMEMERR();
|
||||
|
||||
+2
-1
@@ -26,6 +26,7 @@
|
||||
#include "xsystem35.h"
|
||||
#include "scenario.h"
|
||||
#include "music.h"
|
||||
#include "hacks.h"
|
||||
|
||||
/* ぱにょ〜ん 異常シナリオ対策 */
|
||||
static boolean dummy_pcm_in_play = FALSE;
|
||||
@@ -272,7 +273,7 @@ void commandSU() {
|
||||
}
|
||||
}
|
||||
/* 闘神都市II 異常シナリオ対策 */
|
||||
if (nact->game == GAME_TT2) {
|
||||
if (game_id == GAME_TT2) {
|
||||
*var1 = *var2 = 0;
|
||||
}
|
||||
|
||||
|
||||
+2
-1
@@ -33,6 +33,7 @@
|
||||
#include "cmd_check.h"
|
||||
#include "sdl_core.h"
|
||||
#include "music_cdrom.h"
|
||||
#include "hacks.h"
|
||||
|
||||
unsigned Y3waitFlags = KEYWAIT_CANCELABLE;
|
||||
|
||||
@@ -126,7 +127,7 @@ void commandY() {
|
||||
default:
|
||||
if (p1 == 1003) {
|
||||
sys_key_releasewait(SYS35KEY_RET, FALSE);
|
||||
} else if (nact->game == GAME_RANCE4_V2 && p2 == 1) {
|
||||
} else if (game_id == GAME_RANCE4_V2 && p2 == 1) {
|
||||
// Return immediately if any key is pressed.
|
||||
sysVar[0] = sys_getInputInfo();
|
||||
if (sysVar[0])
|
||||
|
||||
+1
-1
@@ -531,7 +531,7 @@ void dbg_onsleep(void) {
|
||||
}
|
||||
|
||||
void dbg_on_palette_change(void) {
|
||||
if (dbg_impl)
|
||||
if (dbg_impl && dbg_impl->on_palette_change)
|
||||
dbg_impl->on_palette_change();
|
||||
}
|
||||
|
||||
|
||||
@@ -30,50 +30,48 @@
|
||||
#include "LittleEndian.h"
|
||||
#include "dri.h"
|
||||
|
||||
static bool read_index(int disk, drifiles *d, FILE *fp) {
|
||||
static bool read_index(int volume, drifiles *d, FILE *fp) {
|
||||
fseek(fp, 0L, SEEK_END);
|
||||
int filesize = ftell(fp);
|
||||
|
||||
// Get ptrsize and mapsize
|
||||
// Get the size of offsets table and link table.
|
||||
uint8_t hdr[6];
|
||||
fseek(fp, 0L, SEEK_SET);
|
||||
if (fread(hdr, 6, 1, fp) != 1)
|
||||
return false;
|
||||
int ptrsize = LittleEndian_get3B(hdr, 0) << 8;
|
||||
int mapsize = (LittleEndian_get3B(hdr, 3) << 8) - ptrsize;
|
||||
if (ptrsize <= 0 || mapsize <= 0 || ptrsize + mapsize > filesize)
|
||||
int ofssize = LittleEndian_get3B(hdr, 0) << 8;
|
||||
int linksize = (LittleEndian_get3B(hdr, 3) << 8) - ofssize;
|
||||
if (ofssize <= 0 || linksize <= 0 || ofssize + linksize > filesize)
|
||||
return false;
|
||||
|
||||
// Read the pointer table and the link table
|
||||
uint8_t *ptbl = malloc(ptrsize + mapsize);
|
||||
memcpy(ptbl, hdr, 6);
|
||||
if (fread(ptbl + 6, ptrsize + mapsize - 6, 1, fp) != 1) {
|
||||
free(ptbl);
|
||||
// Read the link table. In System 3.9, only the first volume's link table is
|
||||
// valid. It's different in System 3.8 and earlier, and games that depend
|
||||
// on the old behavior (e.g. Child Assassin in Alice CD 2.50) won't work.
|
||||
if (!d->link) {
|
||||
d->nr_files = linksize / 3;
|
||||
d->link = calloc(1, linksize);
|
||||
d->offset = calloc(sizeof(uint32_t), d->nr_files);
|
||||
fseek(fp, ofssize, SEEK_SET);
|
||||
if (fread(d->link, linksize, 1, fp) != 1)
|
||||
return false;
|
||||
}
|
||||
|
||||
// Read the offsets table.
|
||||
uint8_t *otbl = malloc(ofssize);
|
||||
fseek(fp, 0L, SEEK_SET);
|
||||
if (fread(otbl, ofssize, 1, fp) != 1) {
|
||||
free(otbl);
|
||||
return false;
|
||||
}
|
||||
uint8_t *ltbl = ptbl + ptrsize;
|
||||
|
||||
// (Re)allocate the index buffers
|
||||
int nr_files = mapsize / 3;
|
||||
if (d->nr_files < nr_files) {
|
||||
d->disk = realloc(d->disk, nr_files);
|
||||
d->offset = realloc(d->offset, sizeof(uint32_t) * nr_files);
|
||||
memset(d->disk + d->nr_files, 0, nr_files - d->nr_files);
|
||||
memset(d->offset + d->nr_files, 0, sizeof(uint32_t) * (nr_files - d->nr_files));
|
||||
d->nr_files = nr_files;
|
||||
}
|
||||
|
||||
// Parse the index
|
||||
for (int i = 0; i < nr_files; i++) {
|
||||
if (disk != ltbl[i * 3] - 1)
|
||||
for (int i = 0; i < d->nr_files; i++) {
|
||||
if (d->link[i * 3] != volume)
|
||||
continue;
|
||||
if (d->maxno < i)
|
||||
d->maxno = i;
|
||||
d->disk[i] = ltbl[i * 3];
|
||||
int ptr = LittleEndian_getW(ltbl, i * 3 + 1);
|
||||
d->offset[i] = LittleEndian_get3B(ptbl, ptr * 3) << 8;
|
||||
int offset_index = LittleEndian_getW(d->link, i * 3 + 1);
|
||||
d->offset[i] = LittleEndian_get3B(otbl, offset_index * 3) << 8;
|
||||
}
|
||||
free(ptbl);
|
||||
free(otbl);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -90,7 +88,7 @@ drifiles *dri_init(const char **file, int cnt, boolean use_mmap) {
|
||||
FILE *fp = fopen(file[i], "rb");
|
||||
if (!fp)
|
||||
SYSERROR("%s: %s", file[i], strerror(errno));
|
||||
if (!read_index(i, d, fp)) {
|
||||
if (!read_index(i + 1, d, fp)) {
|
||||
// Only errors in *A.ALD are fatal, because some games have
|
||||
// dummy (invalid) *[B-Z].ALD files.
|
||||
if (i == 0)
|
||||
@@ -117,18 +115,18 @@ drifiles *dri_init(const char **file, int cnt, boolean use_mmap) {
|
||||
}
|
||||
|
||||
dridata *dri_getdata(drifiles *d, int no) {
|
||||
if (no < 0 || no >= d->nr_files || !d->disk[no] || !d->offset[no])
|
||||
if (no < 0 || no >= d->nr_files || !d->link[no * 3] || !d->offset[no])
|
||||
return NULL;
|
||||
int disk = d->disk[no] - 1;
|
||||
int volume = d->link[no * 3];
|
||||
|
||||
uint8_t *data;
|
||||
int ptr, size;
|
||||
if (d->mmapped) {
|
||||
data = d->mmap[disk]->addr + d->offset[no];
|
||||
data = d->mmap[volume - 1]->addr + d->offset[no];
|
||||
ptr = LittleEndian_getDW(data, 0);
|
||||
size = LittleEndian_getDW(data, 4);
|
||||
} else {
|
||||
FILE *fp = fopen(d->fnames[disk], "rb");
|
||||
FILE *fp = fopen(d->fnames[volume - 1], "rb");
|
||||
if (!fp)
|
||||
return NULL;
|
||||
uint8_t entry_header[8];
|
||||
|
||||
@@ -35,7 +35,7 @@ struct _drifiles {
|
||||
char *fnames[DRIFILEMAX];
|
||||
int nr_files; // upper limit on how many files could be referenced by this archive
|
||||
int maxno;
|
||||
uint8_t *disk; // file numbers
|
||||
uint8_t *link; // link table
|
||||
uint32_t *offset; // offsets in file
|
||||
};
|
||||
typedef struct _drifiles drifiles;
|
||||
|
||||
+81
-2
@@ -21,15 +21,18 @@
|
||||
*/
|
||||
/* $Id: filecheck.c,v 1.5 2006/04/21 16:40:48 chikama Exp $ */
|
||||
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <dirent.h>
|
||||
#include <unistd.h>
|
||||
#ifdef _WIN32
|
||||
#include <direct.h>
|
||||
#include <windows.h>
|
||||
#undef min
|
||||
#undef max
|
||||
#endif
|
||||
|
||||
#include "filecheck.h"
|
||||
@@ -47,9 +50,65 @@ static char *get_fullpath(const char* dir, const char *filename) {
|
||||
return fn;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
static int make_dir(const char *path)
|
||||
{
|
||||
wchar_t wpath[PATH_MAX + 1];
|
||||
if (!MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, path, -1, wpath, PATH_MAX + 1)) {
|
||||
errno = EILSEQ;
|
||||
return -1;
|
||||
}
|
||||
return _wmkdir(wpath);
|
||||
}
|
||||
|
||||
#else
|
||||
#define make_dir(path) mkdir(path, S_IRWXU)
|
||||
#endif
|
||||
|
||||
// Adapted from http://stackoverflow.com/a/2336245/119527
|
||||
static int mkdir_p(const char *path)
|
||||
{
|
||||
const size_t len = strlen(path);
|
||||
char _path[PATH_MAX];
|
||||
char *p;
|
||||
|
||||
errno = 0;
|
||||
|
||||
// Copy string so its mutable
|
||||
if (len > sizeof(_path)-1) {
|
||||
errno = ENAMETOOLONG;
|
||||
return -1;
|
||||
}
|
||||
strcpy(_path, path);
|
||||
|
||||
// Iterate the string
|
||||
for (p = _path + 1; *p; p++) {
|
||||
if (*p == '/') {
|
||||
// Temporarily truncate
|
||||
*p = '\0';
|
||||
|
||||
if (make_dir(_path) != 0) {
|
||||
if (errno != EEXIST)
|
||||
return -1;
|
||||
}
|
||||
|
||||
*p = '/';
|
||||
}
|
||||
}
|
||||
|
||||
if (make_dir(_path) != 0) {
|
||||
if (errno != EEXIST)
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* list up file in current directory */
|
||||
/* name : save/load directory */
|
||||
void fc_init(const char *name) {
|
||||
mkdir_p(name);
|
||||
saveDataPath = strdup(name);
|
||||
}
|
||||
|
||||
@@ -66,6 +125,18 @@ char *fc_get_path(const char *fname_utf8) {
|
||||
return get_fullpath(saveDataPath, fname_utf8);
|
||||
}
|
||||
|
||||
bool fc_exists(const char *fname_utf8)
|
||||
{
|
||||
char *path = fc_get_path(fname_utf8);
|
||||
wchar_t wpath[PATH_MAX + 1];
|
||||
bool result = false;
|
||||
if (MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, path, -1, wpath, PATH_MAX + 1)) {
|
||||
result = _waccess(wpath, F_OK) != -1;
|
||||
}
|
||||
free(path);
|
||||
return result;
|
||||
}
|
||||
|
||||
FILE *fc_open(const char *fname_utf8, char type) {
|
||||
char *path = fc_get_path(fname_utf8);
|
||||
FILE *fp = fopen_utf8(path, type);
|
||||
@@ -102,6 +173,14 @@ char *fc_get_path(const char *fname_utf8) {
|
||||
return get_fullpath(saveDataPath, fname_utf8);
|
||||
}
|
||||
|
||||
bool fc_exists(const char *fname_utf8)
|
||||
{
|
||||
char *path = fc_get_path(fname_utf8);
|
||||
bool result = access(path, F_OK) != -1;
|
||||
free(path);
|
||||
return result;
|
||||
}
|
||||
|
||||
FILE *fc_open(const char *fname_utf8, char type) {
|
||||
char *fullpath = fc_search(fname_utf8, saveDataPath);
|
||||
if (!fullpath) {
|
||||
|
||||
+7
-4
@@ -24,9 +24,12 @@
|
||||
#ifndef __FILECHECK_H__
|
||||
#define __FILECHECK_H__
|
||||
|
||||
extern void fc_init(const char *name);
|
||||
extern char *fc_get_path(const char *fname_utf8);
|
||||
extern FILE *fc_open(const char *fname_utf8, char type);
|
||||
extern void fc_backup_oldfile(const char *filename);
|
||||
#include <stdbool.h>
|
||||
|
||||
void fc_init(const char *name);
|
||||
char *fc_get_path(const char *fname_utf8);
|
||||
bool fc_exists(const char *fname_utf8);
|
||||
FILE *fc_open(const char *fname_utf8, char type);
|
||||
void fc_backup_oldfile(const char *filename);
|
||||
|
||||
#endif /* !__FILECHECK_H__ */
|
||||
|
||||
+11
-2
@@ -36,6 +36,7 @@
|
||||
#include "system.h"
|
||||
#include "font.h"
|
||||
#include "sdl_private.h"
|
||||
#include "hacks.h"
|
||||
|
||||
typedef struct {
|
||||
int size;
|
||||
@@ -175,7 +176,15 @@ SDL_Rect font_draw_glyph(int x, int y, const char *str_utf8, uint8_t cl) {
|
||||
if (!fontset)
|
||||
return r_dst;
|
||||
|
||||
if (this.antialiase_on) {
|
||||
bool antialias = this.antialiase_on;
|
||||
// The post-effect in Rance 3 opening does not work properly if colors other
|
||||
// than the specified text color (32) are used.
|
||||
// https://github.com/kichikuou/xsystem35-sdl2/issues/54
|
||||
// In Rance 3, text color 32 is only used in the opening.
|
||||
if ((game_id == GAME_RANCE3 || game_id == GAME_RANCE3_ENG) && cl == 32)
|
||||
antialias = false;
|
||||
|
||||
if (antialias) {
|
||||
fs = TTF_RenderUTF8_Blended(fontset->id, str_utf8, sdl_col[cl]);
|
||||
} else {
|
||||
fs = TTF_RenderUTF8_Solid(fontset->id, str_utf8, sdl_col[cl]);
|
||||
@@ -190,7 +199,7 @@ SDL_Rect font_draw_glyph(int x, int y, const char *str_utf8, uint8_t cl) {
|
||||
y -= (TTF_FontHeight(fontset->id) - fontset->size) / 2;
|
||||
r_dst = (SDL_Rect){x, y, w, h};
|
||||
|
||||
if (sdl_dib->format->BitsPerPixel == 8 && this.antialiase_on) {
|
||||
if (sdl_dib->format->BitsPerPixel == 8 && antialias) {
|
||||
sdl_drawAntiAlias_8bpp(x, y, fs, cl);
|
||||
} else {
|
||||
r_src = (SDL_Rect){0, 0, w, h};
|
||||
|
||||
+20
-6
@@ -63,7 +63,7 @@ static void storeSaveName(GameResource *gr, int no, char *src) {
|
||||
if (path) free(path);
|
||||
}
|
||||
|
||||
boolean initGameResourceFromDir(GameResource *gr, DIR *dir, struct dirent *(*p_readdir)(DIR *)) {
|
||||
boolean initGameResourceFromDir(GameResource *gr, DIR *dir, const char *savedir, struct dirent *(*p_readdir)(DIR *)) {
|
||||
memset(gr, 0, sizeof(GameResource));
|
||||
|
||||
char *basename = NULL;
|
||||
@@ -121,14 +121,28 @@ boolean initGameResourceFromDir(GameResource *gr, DIR *dir, struct dirent *(*p_r
|
||||
found_xsleep = true;
|
||||
}
|
||||
}
|
||||
if (basename && !found_xsleep) {
|
||||
char *buf = malloc(strlen(basename) + 6);
|
||||
if (basename && (savedir || !found_xsleep)) {
|
||||
const char *dir = savedir ? savedir : "";
|
||||
const char *sep = savedir ? "/" : "";
|
||||
char *buf = malloc(strlen(dir) + strlen(sep) + strlen(basename) + 9);
|
||||
#if defined(__ANDROID__) || defined(__EMSCRIPTEN__)
|
||||
// Use lowercase 's[a-z].asd' in Android and Emscripten, for compatibility.
|
||||
basename[strlen(basename) - 1] = 's';
|
||||
int a = 'a';
|
||||
#else
|
||||
int a = basename[strlen(basename) - 1] == 'S' ? 'A' : 'a';
|
||||
#endif
|
||||
for (int i = 0; i < SAVE_MAXNUMBER; i++) {
|
||||
sprintf(buf, "%s%c.asd", basename, a + i);
|
||||
sprintf(buf, "%s%s%s%c.asd", dir, sep, basename, a + i);
|
||||
storeSaveName(gr, i, buf);
|
||||
}
|
||||
#ifdef __EMSCRIPTEN__
|
||||
basename[strlen(basename) - 1] = '\0';
|
||||
sprintf(buf, "%s%s%s.msgskip", dir, sep, basename);
|
||||
gr->msgskip = buf;
|
||||
#else
|
||||
free(buf);
|
||||
#endif
|
||||
} else {
|
||||
for (int i = 0; i < SAVE_MAXNUMBER; i++) {
|
||||
char buf[] = "asleep.asd";
|
||||
@@ -220,7 +234,7 @@ static boolean initGameResourceFromFile(GameResource *gr, FILE *fp, const char *
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
boolean initGameResource(GameResource *gr, const char *gr_fname) {
|
||||
boolean initGameResource(GameResource *gr, const char *gr_fname, const char *savedir) {
|
||||
FILE *fp = fopen(gr_fname, "r");
|
||||
if (fp) {
|
||||
boolean result = initGameResourceFromFile(gr, fp, gr_fname);
|
||||
@@ -229,7 +243,7 @@ boolean initGameResource(GameResource *gr, const char *gr_fname) {
|
||||
}
|
||||
DIR *dir = opendir(".");
|
||||
if (dir) {
|
||||
boolean result = initGameResourceFromDir(gr, dir, readdir);
|
||||
boolean result = initGameResourceFromDir(gr, dir, savedir, readdir);
|
||||
closedir(dir);
|
||||
return result;
|
||||
}
|
||||
|
||||
+2
-2
@@ -43,7 +43,7 @@ typedef struct {
|
||||
const char *msgskip;
|
||||
} GameResource;
|
||||
|
||||
boolean initGameResource(GameResource *gr, const char *gr_fname);
|
||||
boolean initGameResourceFromDir(GameResource *gr, DIR *dir, struct dirent *(*p_readdir)(DIR *));
|
||||
boolean initGameResource(GameResource *gr, const char *gr_fname, const char *savedir);
|
||||
boolean initGameResourceFromDir(GameResource *gr, DIR *dir, const char *savedir, struct dirent *(*p_readdir)(DIR *));
|
||||
|
||||
#endif /* !__GAMERESOURCE_H__ */
|
||||
|
||||
+20
-3
@@ -25,7 +25,7 @@
|
||||
|
||||
static void initGameResource_test(void) {
|
||||
GameResource gr;
|
||||
ASSERT_TRUE(initGameResource(&gr, "testdata/test.gr"));
|
||||
ASSERT_TRUE(initGameResource(&gr, "testdata/test.gr", NULL));
|
||||
|
||||
ASSERT_EQUAL(gr.cnt[DRIFILE_SCO], 1);
|
||||
ASSERT_STRCMP(gr.game_fname[DRIFILE_SCO][0], "fooSA.ALD");
|
||||
@@ -96,7 +96,7 @@ static void initGameResourceFromDir_test(void) {
|
||||
};
|
||||
const char **dir = files;
|
||||
GameResource gr;
|
||||
ASSERT_TRUE(initGameResourceFromDir(&gr, (DIR *)&dir, mockReaddir));
|
||||
ASSERT_TRUE(initGameResourceFromDir(&gr, (DIR *)&dir, NULL, mockReaddir));
|
||||
ASSERT_EQUAL(gr.cnt[DRIFILE_SCO], 2);
|
||||
ASSERT_STRCMP(gr.game_fname[DRIFILE_SCO][0], "FOOSA.ALD");
|
||||
ASSERT_STRCMP(gr.game_fname[DRIFILE_SCO][1], "FOOSB.ALD");
|
||||
@@ -120,6 +120,23 @@ static void initGameResourceFromDir_test(void) {
|
||||
for (int i = 2; i < 10; i++)
|
||||
ASSERT_NULL(gr.alk[i]);
|
||||
}
|
||||
{
|
||||
const char *files[] = {
|
||||
"foosa.ald",
|
||||
NULL
|
||||
};
|
||||
const char **dir = files;
|
||||
GameResource gr;
|
||||
ASSERT_TRUE(initGameResourceFromDir(&gr, (DIR *)&dir, "~/save", mockReaddir));
|
||||
ASSERT_EQUAL(gr.cnt[DRIFILE_SCO], 1);
|
||||
ASSERT_STRCMP(gr.game_fname[DRIFILE_SCO][0], "foosa.ald");
|
||||
for (int i = 0; i < 26; i++) {
|
||||
char buf[32];
|
||||
sprintf(buf, "/home/kichikuou/save/foos%c.asd", 'a' + i);
|
||||
ASSERT_STRCMP(gr.save_fname[i], buf);
|
||||
}
|
||||
ASSERT_STRCMP(gr.save_path, "/home/kichikuou/save");
|
||||
}
|
||||
{
|
||||
const char *files[] = {
|
||||
"ADISK.ALD",
|
||||
@@ -128,7 +145,7 @@ static void initGameResourceFromDir_test(void) {
|
||||
};
|
||||
const char **dir = files;
|
||||
GameResource gr;
|
||||
ASSERT_TRUE(initGameResourceFromDir(&gr, (DIR *)&dir, mockReaddir));
|
||||
ASSERT_TRUE(initGameResourceFromDir(&gr, (DIR *)&dir, NULL, mockReaddir));
|
||||
ASSERT_EQUAL(gr.cnt[DRIFILE_SCO], 1);
|
||||
ASSERT_STRCMP(gr.game_fname[DRIFILE_SCO][0], "ADISK.ALD");
|
||||
for (int i = 0; i < 26; i++) {
|
||||
|
||||
+15
-9
@@ -27,23 +27,27 @@
|
||||
#define GT_TOSHIN2 "闘神都市Ⅱ for Win95 "
|
||||
#define GT_RANCE4 "Rance4 -教団の遺産- For Win95 "
|
||||
#define GT_RANCE4_V2 "RanceⅣ -教団の遺産- for Windows "
|
||||
#define GT_RANCE3 "Rance3"
|
||||
#define GT_RANCE3_ENG "Rance3"
|
||||
#define GT_RANCE4_ENG "Rance4 -Legacy of the Sect- For Win95 "
|
||||
|
||||
/* defined by cmdy.c */
|
||||
extern boolean Y3waitFlags;
|
||||
|
||||
enum gameId game_id;
|
||||
bool daiakuji_cx_hack;
|
||||
|
||||
void enable_hack_by_gameid(const char *gameid) {
|
||||
if (!strcmp(gameid, "toushin2"))
|
||||
nact->game = GAME_TT2;
|
||||
game_id = GAME_TT2;
|
||||
else if (!strcmp(gameid, "rance3"))
|
||||
game_id = GAME_RANCE3;
|
||||
else if (!strcmp(gameid, "rance3_eng"))
|
||||
nact->game = GAME_RANCE3_ENG;
|
||||
game_id = GAME_RANCE3_ENG;
|
||||
else if (!strcmp(gameid, "rance4_eng"))
|
||||
nact->game = GAME_RANCE4_ENG;
|
||||
game_id = GAME_RANCE4_ENG;
|
||||
else if (!strcmp(gameid, "rance4_v2"))
|
||||
nact->game = GAME_RANCE4_V2;
|
||||
game_id = GAME_RANCE4_V2;
|
||||
else
|
||||
sys_error("Unknown game id \"%s\"", gameid);
|
||||
}
|
||||
@@ -52,15 +56,17 @@ void enable_hack_by_title(const char *title_utf8) {
|
||||
if (!strcmp(title_utf8, GT_RANCE4))
|
||||
Y3waitFlags = KEYWAIT_NONCANCELABLE;
|
||||
|
||||
if (nact->game != GAME_UNKNOWN)
|
||||
if (game_id != GAME_UNKNOWN)
|
||||
return;
|
||||
|
||||
if (!strcmp(title_utf8, GT_TOSHIN2))
|
||||
nact->game = GAME_TT2;
|
||||
game_id = GAME_TT2;
|
||||
else if (!strcmp(title_utf8, GT_RANCE4_V2))
|
||||
nact->game = GAME_RANCE4_V2;
|
||||
game_id = GAME_RANCE4_V2;
|
||||
else if (!strcmp(title_utf8, GT_RANCE3))
|
||||
game_id = GAME_RANCE3;
|
||||
else if (!strcmp(title_utf8, GT_RANCE3_ENG))
|
||||
nact->game = GAME_RANCE3_ENG;
|
||||
game_id = GAME_RANCE3_ENG;
|
||||
else if (!strcmp(title_utf8, GT_RANCE4_ENG))
|
||||
nact->game = GAME_RANCE4_ENG;
|
||||
game_id = GAME_RANCE4_ENG;
|
||||
}
|
||||
|
||||
@@ -25,11 +25,14 @@
|
||||
enum gameId {
|
||||
GAME_UNKNOWN = 0,
|
||||
GAME_TT2,
|
||||
GAME_RANCE3,
|
||||
GAME_RANCE3_ENG,
|
||||
GAME_RANCE4_ENG,
|
||||
GAME_RANCE4_V2,
|
||||
};
|
||||
|
||||
extern enum gameId game_id;
|
||||
|
||||
void enable_hack_by_gameid(const char *gameid);
|
||||
void enable_hack_by_title(const char *game_title_utf8);
|
||||
|
||||
|
||||
+3
-2
@@ -59,8 +59,9 @@ extern void menu_setSkipState(boolean enabled, boolean activated);
|
||||
|
||||
#ifdef _WIN32
|
||||
struct SDL_SysWMmsg;
|
||||
extern void win_menu_init(void);
|
||||
extern void win_menu_onsyswmevent(struct SDL_SysWMmsg* msg);
|
||||
void win_menu_init(void);
|
||||
void win_menu_onSysWMEvent(struct SDL_SysWMmsg* msg);
|
||||
void win_menu_onMouseMotion(int x, int y);
|
||||
#endif
|
||||
|
||||
#endif /* !__MENULL */
|
||||
|
||||
+1
-3
@@ -20,9 +20,7 @@
|
||||
*/
|
||||
/* $Id: menu_callback.c,v 1.11 2003/04/25 17:23:55 chikama Exp $ */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
#include "config.h"
|
||||
|
||||
#include "portab.h"
|
||||
#include "menu.h"
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
#include "config.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
+1
-3
@@ -54,9 +54,7 @@ static unsigned long mt[N]; /* the array for the state vector */
|
||||
static int mti=N+1; /* mti==N+1 means mt[N] is not initialized */
|
||||
|
||||
/* initializing the array with a NONZERO seed */
|
||||
void
|
||||
sgenrand(seed)
|
||||
unsigned long seed;
|
||||
void sgenrand(unsigned long seed)
|
||||
{
|
||||
/* setting initial seeds to mt[N] using */
|
||||
/* the generator Line 25 of Table 1 in */
|
||||
|
||||
+13
-9
@@ -30,11 +30,18 @@
|
||||
#include "music_cdrom.h"
|
||||
#include "cdrom.h"
|
||||
|
||||
static char *dev = CDROM_DEVICE;
|
||||
#ifdef __EMSCRIPTEN__
|
||||
extern cdromdevice_t cdrom_emscripten;
|
||||
#define NATIVE_CD_DEVICE &cdrom_emscripten
|
||||
#else
|
||||
extern cdromdevice_t cdrom_mp3;
|
||||
#define NATIVE_CD_DEVICE &cdrom_mp3
|
||||
#endif
|
||||
|
||||
void muscd_set_devicename(const char *name) {
|
||||
if (0 == strcmp("none", name)) dev = NULL;
|
||||
else dev = strdup(name);
|
||||
static char *playlist = DEFAULT_PLAYLIST_PATH;
|
||||
|
||||
void muscd_set_playlist(const char *name) {
|
||||
playlist = strdup(name);
|
||||
}
|
||||
|
||||
int muscd_init(void) {
|
||||
@@ -42,12 +49,9 @@ int muscd_init(void) {
|
||||
if (ald_get_maxno(DRIFILE_BGM) > 0) {
|
||||
prv.cddev = &cdrom_bgm;
|
||||
} else {
|
||||
prv.cddev = cd_init(dev);
|
||||
if (!prv.cddev) {
|
||||
return NG;
|
||||
}
|
||||
prv.cddev = NATIVE_CD_DEVICE;
|
||||
}
|
||||
prv.cddev->init(dev);
|
||||
prv.cddev->init(playlist);
|
||||
prv.cd_current_track = 0;
|
||||
return OK;
|
||||
}
|
||||
|
||||
+1
-1
@@ -27,7 +27,7 @@
|
||||
#include "portab.h"
|
||||
#include "ald_manager.h"
|
||||
|
||||
void muscd_set_devicename(const char *);
|
||||
void muscd_set_playlist(const char *);
|
||||
int muscd_init(void);
|
||||
int muscd_init_bgm(DRIFILETYPE type, int base_no);
|
||||
int muscd_exit(void);
|
||||
|
||||
@@ -110,9 +110,6 @@ typedef struct {
|
||||
int patch_emen; /* see patch_emen command */
|
||||
int patch_g0; /* see patch g0 command */
|
||||
|
||||
// For game-specific hacks.
|
||||
enum gameId game;
|
||||
|
||||
/* ain 関連 */
|
||||
S39AIN ain;
|
||||
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
/*
|
||||
* pcm.dummy.c Dummy PCM implementation
|
||||
*
|
||||
* Copyright (C) 2019 <KichikuouChrome@gmail.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
#include "portab.h"
|
||||
#include "music_pcm.h"
|
||||
|
||||
int muspcm_init(int audio_buffer_size) { return NG; }
|
||||
int muspcm_exit(void) { return NG; }
|
||||
int muspcm_reset(void) { return NG; }
|
||||
int muspcm_load_no(int slot, int no) { return NG; }
|
||||
int muspcm_load_mixlr(int slot, int noL, int noR) { return NG; }
|
||||
int muspcm_load_data(int slot, uint8_t *buf, uint32_t len) { return NG; }
|
||||
int muspcm_unload(int slot) { return NG; }
|
||||
int muspcm_start(int slot, int loop) { return NG; }
|
||||
int muspcm_stop(int slot) { return NG; }
|
||||
int muspcm_fadeout(int slot, int msec) { return NG; }
|
||||
int muspcm_pause(int slot) { return NG; }
|
||||
int muspcm_unpause(int slot) { return NG; }
|
||||
int muspcm_getpos(int slot) { return NG; }
|
||||
int muspcm_setvol(int dev, int slot, int lv) { return NG; }
|
||||
int muspcm_getwavelen(int slot) { return NG; }
|
||||
boolean muspcm_isplaying(int slot) { return FALSE; }
|
||||
int muspcm_waitend(int slot) { return NG; }
|
||||
+2
-1
@@ -81,7 +81,8 @@ void sdl_sleep(int msec) {
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
EM_JS(void, wait_vsync, (void), {
|
||||
Asyncify.handleSleep(function(wakeUp) {
|
||||
// We need a `return` here for JSPI support (ASYNCIFY=2).
|
||||
return Asyncify.handleSleep(function(wakeUp) {
|
||||
window.requestAnimationFrame(function() {
|
||||
wakeUp();
|
||||
});
|
||||
|
||||
+6
-2
@@ -40,6 +40,7 @@
|
||||
#include "menu.h"
|
||||
#include "input.h"
|
||||
#include "msgskip.h"
|
||||
#include "hacks.h"
|
||||
|
||||
static void sdl_getEvent(void);
|
||||
static void keyEventProsess(SDL_KeyboardEvent *e, boolean pressed);
|
||||
@@ -259,7 +260,7 @@ void sdl_handle_event(SDL_Event *e) {
|
||||
break;
|
||||
#ifdef _WIN32
|
||||
case SDL_SYSWMEVENT:
|
||||
win_menu_onsyswmevent(e->syswm.msg);
|
||||
win_menu_onSysWMEvent(e->syswm.msg);
|
||||
break;
|
||||
#endif
|
||||
case SDL_APP_DIDENTERFOREGROUND:
|
||||
@@ -281,6 +282,9 @@ void sdl_handle_event(SDL_Event *e) {
|
||||
break;
|
||||
case SDL_MOUSEMOTION:
|
||||
sdl_setCursorInternalLocation(e->motion.x, e->motion.y);
|
||||
#ifdef _WIN32
|
||||
win_menu_onMouseMotion(e->motion.x, e->motion.y);
|
||||
#endif
|
||||
break;
|
||||
|
||||
case SDL_MOUSEWHEEL:
|
||||
@@ -445,7 +449,7 @@ static void sdl_getEvent(void) {
|
||||
cmd_count_of_prev_input = nact->cmd_count;
|
||||
} else if (nact->cmd_count != cmd_count_of_prev_input) {
|
||||
nact->wait_vsync = TRUE;
|
||||
if (nact->game == GAME_RANCE4_V2)
|
||||
if (game_id == GAME_RANCE4_V2)
|
||||
rance4v2_hack();
|
||||
}
|
||||
}
|
||||
|
||||
+7
-4
@@ -136,6 +136,10 @@ static void window_init(const char *render_driver) {
|
||||
// indirectly, which does not work with ASYNCIFY_IGNORE_INDIRECT=1. For
|
||||
// details, see https://github.com/emscripten-core/emscripten/issues/10746.
|
||||
SDL_SetHint(SDL_HINT_EMSCRIPTEN_ASYNCIFY, "0");
|
||||
|
||||
const char *title = NULL; // Don't let SDL change document.title.
|
||||
#else
|
||||
const char title[] = "XSystem35 Version " VERSION;
|
||||
#endif
|
||||
|
||||
#ifdef __ANDROID__
|
||||
@@ -145,10 +149,9 @@ static void window_init(const char *render_driver) {
|
||||
#else
|
||||
Uint32 flags = SDL_WINDOW_RESIZABLE;
|
||||
#endif
|
||||
sdl_window = SDL_CreateWindow("XSystem35 Version "VERSION,
|
||||
SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
|
||||
SYS35_DEFAULT_WIDTH, SYS35_DEFAULT_HEIGHT,
|
||||
flags);
|
||||
sdl_window = SDL_CreateWindow(
|
||||
title, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
|
||||
SYS35_DEFAULT_WIDTH, SYS35_DEFAULT_HEIGHT, flags);
|
||||
sdl_renderer = SDL_CreateRenderer(sdl_window, -1, 0);
|
||||
SDL_SetRenderDrawColor(sdl_renderer, 0, 0, 0, SDL_ALPHA_OPAQUE);
|
||||
}
|
||||
|
||||
+12
-6
@@ -29,6 +29,8 @@
|
||||
#include "resources.h"
|
||||
#include "msgskip.h"
|
||||
|
||||
static HMENU hmenu;
|
||||
|
||||
static HWND get_hwnd(SDL_Window *window) {
|
||||
SDL_SysWMinfo info;
|
||||
SDL_VERSION(&info.version);
|
||||
@@ -60,9 +62,6 @@ static void saveScreenshot(void) {
|
||||
}
|
||||
|
||||
static bool toggle_menu_item(UINT id, bool *checked_out) {
|
||||
HWND hwnd = get_hwnd(sdl_window);
|
||||
HMENU hmenu = GetMenu(hwnd);
|
||||
|
||||
MENUITEMINFO menuitem = {
|
||||
.cbSize = sizeof(MENUITEMINFO),
|
||||
.fMask = MIIM_STATE,
|
||||
@@ -82,7 +81,7 @@ static bool toggle_menu_item(UINT id, bool *checked_out) {
|
||||
|
||||
void win_menu_init(void) {
|
||||
HINSTANCE hinst = (HINSTANCE)GetModuleHandle(NULL);
|
||||
HMENU hmenu = LoadMenu(hinst, MAKEINTRESOURCE(IDR_MENU1));
|
||||
hmenu = LoadMenu(hinst, MAKEINTRESOURCE(IDR_MENU1));
|
||||
SetMenu(get_hwnd(sdl_window), hmenu);
|
||||
SDL_EventState(SDL_SYSWMEVENT, SDL_ENABLE);
|
||||
// Let SDL recalc the window size, taking menu height into account.
|
||||
@@ -90,7 +89,7 @@ void win_menu_init(void) {
|
||||
CheckMenuItem(hmenu, ID_OPTION_MOUSE_MOVE, MF_BYCOMMAND | MFS_CHECKED);
|
||||
}
|
||||
|
||||
void win_menu_onsyswmevent(SDL_SysWMmsg* msg) {
|
||||
void win_menu_onSysWMEvent(SDL_SysWMmsg* msg) {
|
||||
bool checked;
|
||||
switch (msg->msg.win.msg) {
|
||||
case WM_COMMAND:
|
||||
@@ -106,9 +105,11 @@ void win_menu_onsyswmevent(SDL_SysWMmsg* msg) {
|
||||
break;
|
||||
case ID_SCREEN_WINDOW:
|
||||
sdl_setFullscreen(FALSE);
|
||||
SetMenu(get_hwnd(sdl_window), hmenu);
|
||||
break;
|
||||
case ID_SCREEN_FULL:
|
||||
sdl_setFullscreen(TRUE);
|
||||
SetMenu(get_hwnd(sdl_window), NULL);
|
||||
break;
|
||||
case ID_SCREEN_INTEGER_SCALING:
|
||||
if (toggle_menu_item(ID_SCREEN_INTEGER_SCALING, &checked))
|
||||
@@ -126,9 +127,14 @@ void win_menu_onsyswmevent(SDL_SysWMmsg* msg) {
|
||||
}
|
||||
}
|
||||
|
||||
void win_menu_onMouseMotion(int x, int y) {
|
||||
if (!sdl_isFullscreen())
|
||||
return;
|
||||
SetMenu(get_hwnd(sdl_window), y > 0 ? NULL : hmenu);
|
||||
}
|
||||
|
||||
void menu_setSkipState(boolean enabled, boolean activated) {
|
||||
HWND hwnd = get_hwnd(sdl_window);
|
||||
HMENU hmenu = GetMenu(hwnd);
|
||||
|
||||
EnableMenuItem(hmenu, ID_MSGSKIP, enabled ? MF_ENABLED : MF_GRAYED);
|
||||
|
||||
|
||||
+23
-7
@@ -96,6 +96,7 @@ static int audio_buffer_size = 0;
|
||||
static const char *fontname_tt[FONTTYPEMAX] = {DEFAULT_GOTHIC_TTF, DEFAULT_MINCHO_TTF};
|
||||
static char fontface[FONTTYPEMAX];
|
||||
|
||||
static const char *savedir;
|
||||
static boolean font_noantialias;
|
||||
static bool enable_zb = false;
|
||||
static bool integer_scaling = false;
|
||||
@@ -112,9 +113,10 @@ static void sys35_usage(boolean verbose) {
|
||||
puts("OPTIONS");
|
||||
puts(" -gamefile file : set game resource file to 'file'");
|
||||
puts(" -game game : enable game-specific hacks");
|
||||
puts(" -savedir dir : directory to save game state files");
|
||||
puts(" -saveformat fmt : save file format. 'xsystem35', 'system36' or 'system39' (default)");
|
||||
puts(" -renderer name : set rendering driver name to 'name'");
|
||||
puts(" -devcd device : set cdrom device name to 'device'");
|
||||
puts(" -playlist file : load CD playlist from 'file'");
|
||||
puts(" -devmidi device : set midi device name to 'device'");
|
||||
|
||||
puts(" -M? : select output midi methos");
|
||||
@@ -258,6 +260,13 @@ static void sys35_ParseOption(int *argc, char **argv) {
|
||||
}
|
||||
}
|
||||
for (i = 1; i < *argc; i++) {
|
||||
if (0 == strcmp(argv[i], "-savedir")) {
|
||||
if (i == *argc - 1) {
|
||||
fprintf(stderr, "xsystem35: The -savedir option requires directory name\n\n");
|
||||
sys35_usage(FALSE);
|
||||
}
|
||||
savedir = argv[++i];
|
||||
}
|
||||
if (0 == strcmp(argv[i], "-gamefile")) {
|
||||
if (i == *argc - 1) {
|
||||
fprintf(stderr, "xsystem35: The -gamefile option requires file value\n\n");
|
||||
@@ -275,9 +284,9 @@ static void sys35_ParseOption(int *argc, char **argv) {
|
||||
debugger_mode = DEBUGGER_DAP;
|
||||
} else if (0 == strcmp(argv[i], "-renderer")) {
|
||||
render_driver = argv[i + 1];
|
||||
} else if (0 == strcmp(argv[i], "-devcd")) {
|
||||
} else if (0 == strcmp(argv[i], "-playlist") || 0 == strcmp(argv[i], "-devcd")) {
|
||||
if (argv[i + 1] != NULL) {
|
||||
muscd_set_devicename(argv[i + 1]);
|
||||
muscd_set_playlist(argv[i + 1]);
|
||||
}
|
||||
} else if (0 == strcmp(argv[i], "-devmidi")) {
|
||||
if (argv[i + 1] != NULL) {
|
||||
@@ -333,6 +342,10 @@ static void sys35_ParseOption(int *argc, char **argv) {
|
||||
static void check_profile() {
|
||||
const char *param;
|
||||
|
||||
param = get_profile("savedir");
|
||||
if (param) {
|
||||
savedir = param;
|
||||
}
|
||||
/* ゴシックフォント(TT)の設定 */
|
||||
param = get_profile("ttfont_gothic");
|
||||
if (param) {
|
||||
@@ -374,11 +387,14 @@ static void check_profile() {
|
||||
render_driver = param;
|
||||
}
|
||||
|
||||
/* CD-ROM device name の設定 */
|
||||
param = get_profile("cdrom_device");
|
||||
/* CD-ROM playlist */
|
||||
param = get_profile("playlist");
|
||||
if (!param)
|
||||
param = get_profile("cdrom_device"); // For backwards compatibility
|
||||
if (param) {
|
||||
muscd_set_devicename(param);
|
||||
muscd_set_playlist(param);
|
||||
}
|
||||
|
||||
/* joystick device name の設定 */
|
||||
param = get_profile("joy_device");
|
||||
if (param) {
|
||||
@@ -481,7 +497,7 @@ int main(int argc, char **argv) {
|
||||
check_profile();
|
||||
sys35_ParseOption(&argc, argv);
|
||||
|
||||
if (!initGameResource(&nact->files, gameResourceFile)) {
|
||||
if (!initGameResource(&nact->files, gameResourceFile, savedir)) {
|
||||
#ifdef _WIN32
|
||||
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "xsystem35", "Cannot find scenario file (*SA.ALD)", NULL);
|
||||
exit(1);
|
||||
|
||||
+8
-2
@@ -44,9 +44,10 @@
|
||||
# Audio
|
||||
#
|
||||
|
||||
# CD-ROM device name.
|
||||
# Path to the CD playlist. The playlist is a text file with one filename per
|
||||
# line, in the order of CD tracks.
|
||||
|
||||
#cdrom_device: /dev/cdrom
|
||||
#playlist: playlist.txt
|
||||
|
||||
# device name of the raw midi device or sequencer device.
|
||||
|
||||
@@ -79,6 +80,11 @@
|
||||
# Miscellaneous
|
||||
#
|
||||
|
||||
# Directory to save game state files.
|
||||
# If it begins with '~', it is expanded to the user's home directory ($HOME).
|
||||
|
||||
#savedir: ~/.xsystem35-saves
|
||||
|
||||
# The format when writing save files.
|
||||
# xsystem35 : default
|
||||
# system36 : compatible with System3.5 v2 - System3.6
|
||||
|
||||
Reference in New Issue
Block a user