mirror of
https://github.com/kichikuou/xsystem35-sdl2.git
synced 2026-09-22 22:48:08 +03:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b30fd71e4b | ||
|
|
99ad91306b | ||
|
|
ed96f26cea | ||
|
|
e6f71190ed | ||
|
|
8219feee6d | ||
|
|
bc8a85e046 | ||
|
|
67f62f02e6 | ||
|
|
471c65973b | ||
|
|
5ff7149dc1 | ||
|
|
80988e52cf | ||
|
|
ade76adda6 | ||
|
|
53d0e8ffef | ||
|
|
b2e14bd19a | ||
|
|
9c73a34c35 | ||
|
|
36e1dc152b | ||
|
|
f786db5a50 | ||
|
|
c515b21afb | ||
|
|
d3db3fa83e | ||
|
|
86068b0ab9 | ||
|
|
de4f3ebb0d | ||
|
|
187a3ced35 | ||
|
|
b7703b6270 | ||
|
|
b7d0efbe55 | ||
|
|
02fe55eb93 | ||
|
|
058789b435 | ||
|
|
c5dcb20ac3 | ||
|
|
cb08f7ca76 | ||
|
|
7a7d94e60f | ||
|
|
b7681982a6 | ||
|
|
fefaf6c343 | ||
|
|
42e994dfba | ||
|
|
a6aa50b5cf | ||
|
|
c4e8205d6c | ||
|
|
dd09f54329 | ||
|
|
435ceb31d3 | ||
|
|
e40de66821 | ||
|
|
73c79b7a2e | ||
|
|
a825ee80b3 | ||
|
|
eeeab6e054 | ||
|
|
875b233f32 | ||
|
|
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 | ||
|
|
22c6b8e963 | ||
|
|
576afecbfc | ||
|
|
4e28d92a2d | ||
|
|
22192c245f | ||
|
|
409fa83406 | ||
|
|
894b0592f4 | ||
|
|
370100a6f2 | ||
|
|
18cfbc90f2 | ||
|
|
cd51dc7f02 | ||
|
|
e2638ed840 | ||
|
|
6607815df3 | ||
|
|
77ed85aff7 | ||
|
|
3b1a311f32 | ||
|
|
1b3c2190b8 | ||
|
|
52e2d6095a | ||
|
|
47e2fcaec0 | ||
|
|
183ceb614a | ||
|
|
185e62010b | ||
|
|
6f647701dd | ||
|
|
a9c79b2e31 | ||
|
|
ba52fbf5e9 | ||
|
|
85d40701c4 | ||
|
|
7b535b371a | ||
|
|
c0dbae8202 | ||
|
|
ca03450b87 | ||
|
|
f795a500cf | ||
|
|
3314f00bf8 | ||
|
|
a2d79f045c | ||
|
|
f247495578 | ||
|
|
f6583330de | ||
|
|
4b15f45897 | ||
|
|
7bc433731f | ||
|
|
4c21570eb1 | ||
|
|
a3e7feffc2 | ||
|
|
a4c1dd1acf | ||
|
|
09086ccc85 | ||
|
|
53e39b7c11 | ||
|
|
f0ccfee40f | ||
|
|
10cdec98e6 | ||
|
|
c61afb4308 | ||
|
|
f6cf881e61 | ||
|
|
a8277e71a7 | ||
|
|
3482fb6440 | ||
|
|
3c81c8fec2 | ||
|
|
e090485b37 | ||
|
|
d7deaec972 | ||
|
|
30467371f4 | ||
|
|
e9a30f7493 | ||
|
|
d9e42dd4bb | ||
|
|
0e06cc1e22 | ||
|
|
89423c94f1 | ||
|
|
c694d2282c | ||
|
|
39e94afc44 | ||
|
|
e37a491908 | ||
|
|
43dff9a9e4 | ||
|
|
e6b3d6094d | ||
|
|
61ad4282e6 | ||
|
|
e4628d8bbb | ||
|
|
21bd4279a1 | ||
|
|
b6c33fd761 | ||
|
|
1b9d8c48f1 | ||
|
|
55ef307e07 | ||
|
|
894cd51e01 | ||
|
|
880244020e | ||
|
|
9c2f423399 | ||
|
|
654a489f49 | ||
|
|
912af592ae | ||
|
|
6d70439dff | ||
|
|
aec06f775a | ||
|
|
446ffe9466 | ||
|
|
02cad74568 | ||
|
|
33e1ff3b4a | ||
|
|
11f8f00072 | ||
|
|
b59d683fef | ||
|
|
b9f4c7c03a | ||
|
|
2d2c6aa373 | ||
|
|
850af6d140 | ||
|
|
da4cf017bf | ||
|
|
e88dfcdaa1 | ||
|
|
70a940b216 | ||
|
|
db2bb03fdd | ||
|
|
5ef949ae14 | ||
|
|
043028cf7d | ||
|
|
eace5d1dbd | ||
|
|
878bea69d6 | ||
|
|
ae8becc4a3 | ||
|
|
1d863cfb2e | ||
|
|
7bb2bee693 | ||
|
|
47e7f5542e | ||
|
|
8087d11b2b | ||
|
|
4f1521ac90 | ||
|
|
99632397da | ||
|
|
59283815d8 | ||
|
|
a32c901eb8 | ||
|
|
03b84b8ba7 | ||
|
|
720da4e42c | ||
|
|
c4dc799c94 | ||
|
|
ce271ae5eb | ||
|
|
526e5f8709 |
@@ -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
|
||||
@@ -15,14 +15,14 @@ jobs:
|
||||
run: |
|
||||
cd android
|
||||
echo "${{ secrets.KEYSTORE_BASE64 }}" | base64 -d > keystore.jks
|
||||
ANDROID_NDK_HOME=$ANDROID_SDK_ROOT/ndk-bundle ./gradlew assembleRelease
|
||||
JAVA_HOME=$JAVA_HOME_17_X64 ANDROID_NDK_HOME=$ANDROID_SDK_ROOT/ndk-bundle ./gradlew assembleRelease
|
||||
env:
|
||||
KEY_ALIAS: ${{ secrets.KEY_ALIAS }}
|
||||
KEY_PASSWORD: ${{ secrets.KEY_PASSWORD }}
|
||||
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.27
|
||||
EM_VERSION: latest
|
||||
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@v12
|
||||
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,19 +10,19 @@ jobs:
|
||||
|
||||
name: Linux ${{ matrix.build-type }}
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Install Deps
|
||||
run: |
|
||||
sudo apt update
|
||||
sudo apt install libgtk-3-dev libsdl2-dev libsdl2-ttf-dev libsdl2-mixer-dev libwebp-dev libportmidi-dev libcjson-dev
|
||||
sudo apt install libgtk-3-dev libsdl2-dev libsdl2-ttf-dev libsdl2-mixer-dev libwebp-dev libportmidi-dev libcjson-dev asciidoctor
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
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
|
||||
|
||||
@@ -5,10 +5,17 @@ jobs:
|
||||
build:
|
||||
runs-on: windows-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- { sys: MINGW32, installer: "xsystem35-32bit" }
|
||||
- { sys: MINGW64, installer: "xsystem35-64bit" }
|
||||
- sys: mingw32
|
||||
package: "xsystem35-32bit"
|
||||
cmake_args: "-DENABLE_DEBUGGER=no"
|
||||
deps: ""
|
||||
- sys: ucrt64
|
||||
package: "xsystem35-64bit"
|
||||
cmake_args: ""
|
||||
deps: "cjson:p"
|
||||
defaults:
|
||||
run:
|
||||
shell: msys2 {0}
|
||||
@@ -19,27 +26,32 @@ jobs:
|
||||
uses: msys2/setup-msys2@v2
|
||||
with:
|
||||
msystem: ${{ matrix.sys }}
|
||||
update: true
|
||||
pacboy: >-
|
||||
gcc:p
|
||||
cmake:p
|
||||
ninja:p
|
||||
SDL2:p
|
||||
SDL2_ttf:p
|
||||
SDL2_mixer:p
|
||||
libwebp:p
|
||||
cjson:p
|
||||
nsis:p
|
||||
ntldd-git:p
|
||||
portmidi:p
|
||||
${{ 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 asciidoctor:p
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
mkdir -p out/release
|
||||
cd out/release
|
||||
cmake -G"Ninja" -DCMAKE_BUILD_TYPE=Release ../../
|
||||
cmake -GNinja -DCMAKE_BUILD_TYPE=Release -DCMAKE_COMPILE_WARNING_AS_ERROR=YES ${{ matrix.cmake_args }} ../../
|
||||
ninja
|
||||
|
||||
- name: Test
|
||||
@@ -47,11 +59,12 @@ jobs:
|
||||
working-directory: out/release
|
||||
|
||||
- name: Package
|
||||
working-directory: tools/installer
|
||||
run: ./make-installer.sh ../../out/release ${{ matrix.installer }}.nsi
|
||||
run: |
|
||||
cp out/release/src/xsystem35.exe out/release/doc/*.html *.md COPYING xsys35rc.sample dist/
|
||||
|
||||
- name: Upload
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: ${{ matrix.installer }}
|
||||
path: tools/installer/${{ matrix.installer }}.exe
|
||||
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
|
||||
|
||||
+127
@@ -0,0 +1,127 @@
|
||||
# Changelog
|
||||
|
||||
## 2.13.0 - 2024-12-07
|
||||
- Windows: `Option` -> `Auto Copy Text to Clipboard` menu command has been added.
|
||||
When enabled, in-game text will be copied to the clipboard automatically. This
|
||||
can be used with text hooker tools that support clipboard monitoring.
|
||||
|
||||
## 2.12.1 - 2024-12-02
|
||||
- Windows: Fixed missing DLL error (#60)
|
||||
|
||||
## 2.12.0 - 2024-11-26
|
||||
- Implemented playback of the opening movie for 妻みぐい2.
|
||||
|
||||
## 2.11.7 - 2024-11-12
|
||||
- Fixed crash when canceling menu with two-finger touch (#58)
|
||||
- Fixed screen artifact in Rance 3 immediately after selecting "Game Start"
|
||||
|
||||
## 2.11.6 - 2024-07-22
|
||||
- Fixed strange behavior when canceling the battle selection menu in Kichikuou Rance. (#56)
|
||||
- Use system mouse cursors whenever possible. They look better on high dpi displays.
|
||||
- Added manual page for the xsystem35 command.
|
||||
|
||||
## 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.
|
||||
+119
-90
@@ -1,18 +1,19 @@
|
||||
cmake_minimum_required(VERSION 3.13)
|
||||
|
||||
# Rebuild external projects when download URL changes
|
||||
if (CMAKE_VERSION VERSION_GREATER_EQUAL "3.24.0")
|
||||
cmake_policy(SET CMP0135 NEW)
|
||||
endif()
|
||||
|
||||
project(xsystem35 LANGUAGES C)
|
||||
set(CMAKE_C_STANDARD 99)
|
||||
enable_testing()
|
||||
set(CMAKE_EXPORT_COMPILE_COMMANDS TRUE)
|
||||
|
||||
set(XSYSTEM35_VERSION "2.13.0")
|
||||
|
||||
include(CheckIncludeFile)
|
||||
include(CheckLibraryExists)
|
||||
include(CheckSymbolExists)
|
||||
|
||||
# In msys, `pkg-config --libs` returns `-lmingw32` but find_library() cannot
|
||||
# find it in default search paths.
|
||||
if (MSYS)
|
||||
list(APPEND CMAKE_LIBRARY_PATH $ENV{MINGW_PREFIX}/$ENV{MINGW_CHOST}/lib)
|
||||
endif ()
|
||||
include(FetchContent)
|
||||
|
||||
# A wrapper around pkg_check_modules() that skips the check if ENABLE_<prefix> is false
|
||||
macro (optional_pkg_check_modules prefix)
|
||||
@@ -22,19 +23,73 @@ macro (optional_pkg_check_modules prefix)
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
# Generates a static library from pkg_check_modules() result
|
||||
function(add_static_library name pkg)
|
||||
add_library(${name} INTERFACE)
|
||||
set_target_properties(${name}
|
||||
PROPERTIES
|
||||
INTERFACE_INCLUDE_DIRECTORIES "${${pkg}_STATIC_INCLUDE_DIRS}"
|
||||
INTERFACE_COMPILE_OPTIONS "${${pkg}_STATIC_CFLAGS_OTHER}"
|
||||
INTERFACE_LINK_LIBRARIES "${${pkg}_STATIC_LIBRARIES}"
|
||||
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)
|
||||
check_symbol_exists(uname "sys/utsname.h" HAVE_UNAME)
|
||||
|
||||
if (EMSCRIPTEN)
|
||||
function(add_emscripten_library name option)
|
||||
add_library(${name} INTERFACE)
|
||||
set_target_properties(${name} PROPERTIES
|
||||
INTERFACE_COMPILE_OPTIONS ${option}
|
||||
INTERFACE_LINK_OPTIONS ${option})
|
||||
endfunction()
|
||||
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)
|
||||
set(SDL2MIXER_FOUND 1)
|
||||
find_library(ndk_zlib z)
|
||||
add_library(sdl2 ALIAS SDL2)
|
||||
add_library(sdl2_ttf ALIAS SDL2_ttf)
|
||||
add_library(sdl2_mixer ALIAS SDL2_mixer)
|
||||
find_library(ndk_log log)
|
||||
else()
|
||||
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)
|
||||
set(ZLIB_USE_STATIC_LIBS ON)
|
||||
endif()
|
||||
find_package(ZLIB REQUIRED)
|
||||
add_library(zlib ALIAS ZLIB::ZLIB)
|
||||
|
||||
include(FindPkgConfig)
|
||||
optional_pkg_check_modules(GTK3 IMPORTED_TARGET gtk+-3.0)
|
||||
@@ -42,45 +97,70 @@ else()
|
||||
set(ENABLE_GTK 1)
|
||||
endif()
|
||||
|
||||
pkg_check_modules(SDL2 IMPORTED_TARGET sdl2)
|
||||
pkg_check_modules(SDL2TTF IMPORTED_TARGET SDL2_ttf)
|
||||
optional_pkg_check_modules(SDL2MIXER IMPORTED_TARGET SDL2_mixer)
|
||||
pkg_check_modules(SDL2 REQUIRED IMPORTED_TARGET sdl2)
|
||||
pkg_check_modules(SDL2TTF REQUIRED IMPORTED_TARGET SDL2_ttf)
|
||||
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++>)
|
||||
add_static_library(sdl2_mixer SDL2MIXER)
|
||||
else()
|
||||
add_library(sdl2 ALIAS PkgConfig::SDL2)
|
||||
add_library(sdl2_ttf ALIAS PkgConfig::SDL2TTF)
|
||||
add_library(sdl2_mixer ALIAS PkgConfig::SDL2MIXER)
|
||||
set(DEFAULT_FONT_PATH ${CMAKE_INSTALL_PREFIX}/share/xsystem35/fonts/)
|
||||
endif()
|
||||
|
||||
option(ENABLE_DEBUGGER "Enable built-in debugger" ON)
|
||||
if (ENABLE_DEBUGGER)
|
||||
pkg_check_modules(cJSON IMPORTED_TARGET libcjson)
|
||||
if (NOT cJSON_FOUND)
|
||||
if (cJSON_FOUND)
|
||||
if (WIN32)
|
||||
add_static_library(cJSON cJSON)
|
||||
else ()
|
||||
add_library(cJSON ALIAS PkgConfig::cJSON)
|
||||
endif()
|
||||
else ()
|
||||
# libcjson-dev of Debian buster / Ubuntu 20.04 does not install pkgconfig files.
|
||||
find_library(cJSON cjson)
|
||||
if (NOT cJSON)
|
||||
message(FATAL_ERROR "libcjson is required but not found.")
|
||||
endif()
|
||||
add_library(cJSON ALIAS ${cJSON})
|
||||
endif()
|
||||
endif()
|
||||
|
||||
optional_pkg_check_modules(WEBP IMPORTED_TARGET libwebp)
|
||||
if (WEBP_FOUND)
|
||||
set(HAVE_WEBP 1)
|
||||
if (WIN32)
|
||||
add_static_library(WebP WEBP)
|
||||
else()
|
||||
add_library(WebP ALIAS PkgConfig::WEBP)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
find_library(PORTMIDI portmidi)
|
||||
if (PORTMIDI)
|
||||
set(HAVE_PORTMIDI 1)
|
||||
set(ENABLE_MIDI_PORTMIDI 1)
|
||||
if (WIN32)
|
||||
optional_pkg_check_modules(PORTMIDI IMPORTED_TARGET portmidi)
|
||||
if (PORTMIDI_FOUND)
|
||||
set(HAVE_PORTMIDI 1)
|
||||
add_static_library(portmidi_static PORTMIDI)
|
||||
set(PORTMIDI portmidi_static)
|
||||
endif()
|
||||
else ()
|
||||
find_library(PORTMIDI portmidi)
|
||||
if (PORTMIDI)
|
||||
set(HAVE_PORTMIDI 1)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
set(DEFAULT_FONT_PATH ${CMAKE_INSTALL_PREFIX}/share/xsystem35/fonts/)
|
||||
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)
|
||||
@@ -90,91 +170,38 @@ 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)
|
||||
elseif (CMAKE_SYSTEM_NAME STREQUAL "Android")
|
||||
list(APPEND SRC_CDROM cdrom.android.c)
|
||||
list(APPEND SUMMARY_CDROM "Android")
|
||||
set(ENABLE_CDROM_ANDROID 1)
|
||||
else()
|
||||
list(APPEND SRC_CDROM cdrom.empty.c)
|
||||
endif()
|
||||
if (SDL2MIXER_FOUND AND NOT ANDROID)
|
||||
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()
|
||||
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)
|
||||
endif()
|
||||
list(APPEND SUMMARY_MIDI "SDL_mixer")
|
||||
set(ENABLE_MIDI_SDLMIXER 1)
|
||||
|
||||
if (CMAKE_SYSTEM_NAME STREQUAL "FreeBSD")
|
||||
check_symbol_exists(SNDCTL_SEQ_NRSYNTHS "machine/soundcard.h" ENABLE_MIDI_SEQMIDI)
|
||||
elseif (CMAKE_SYSTEM_NAME MATCHES "(NetBSD|OpenBSD)")
|
||||
check_symbol_exists(SNDCTL_SEQ_NRSYNTHS "soundcard.h" ENABLE_MIDI_SEQMIDI)
|
||||
else ()
|
||||
check_symbol_exists(SNDCTL_SEQ_NRSYNTHS "sys/soundcard.h" ENABLE_MIDI_SEQMIDI)
|
||||
endif()
|
||||
|
||||
if (ENABLE_MIDI_SEQMIDI)
|
||||
list(APPEND SUMMARY_MIDI "OSS sequencer")
|
||||
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()
|
||||
|
||||
@@ -197,12 +224,14 @@ 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)
|
||||
add_subdirectory(tools)
|
||||
add_subdirectory(fonts)
|
||||
if (NOT ANDROID AND NOT EMSCRIPTEN)
|
||||
add_subdirectory(doc)
|
||||
endif()
|
||||
if (ENABLE_NLS)
|
||||
add_subdirectory(po)
|
||||
endif()
|
||||
|
||||
@@ -3,22 +3,22 @@
|
||||
This is a multi-platform port of `xsystem35`, a free implementation of
|
||||
AliceSoft's System 3.x game engine.
|
||||
|
||||
## Compatiblity
|
||||
## Compatibility
|
||||
|
||||
See the [game compatibility table](game_compatibility.md) for a list of games
|
||||
that can be played on xsystem35-sdl2.
|
||||
that can be played with xsystem35-sdl2.
|
||||
|
||||
## Unique Features
|
||||
|
||||
In addition to the original System 3.x's functionalities, xsystem35-sdl2 has
|
||||
the following features.
|
||||
In addition to the original System 3.x functionalities, xsystem35-sdl2 offers
|
||||
the following features:
|
||||
|
||||
### Playing audio files as fake CD music
|
||||
### Playing Audio Files as Virtual CD Music
|
||||
|
||||
Many System 3.x games had music as audio tracks on the CD-ROM. Xsystem35 can
|
||||
play music from audio files instead, to avoid the hassle of inserting CDs. To
|
||||
use ripped audio files, create a file named `playlist.txt` in the game
|
||||
directory, and enter the paths to your tracks, one per line. For example:
|
||||
Many System 3.x games feature music as audio tracks on the CD-ROM. xsystem35
|
||||
can play music from audio files, eliminating the need to insert CDs. To use
|
||||
ripped audio files, create a file named `playlist.txt` in the game directory
|
||||
and list the paths to your tracks, one per line. For example:
|
||||
|
||||
```
|
||||
# The first line is not used
|
||||
@@ -27,89 +27,116 @@ BGM/track03.mp3
|
||||
...
|
||||
```
|
||||
|
||||
The first line is not used, because track 1 of game CD is usually a data track.
|
||||
The first line is not used because the first track on a game CD is typically a
|
||||
data track.
|
||||
|
||||
### Unicode translation support
|
||||
Some games have integrated music as MIDI. In such cases, the music won't play
|
||||
using the virtual CD feature. If you encounter a `Cannot load MIDI` error
|
||||
message, you might need to set the `SDL_SOUNDFONTS` environment variable to
|
||||
point to an `.sf2` file. For example:
|
||||
|
||||
The original System 3.x only supported Shift_JIS (a Japanese character
|
||||
encoding), but xsystem35 supports Unicode and is able to run games translated
|
||||
into languages other than Japanese and English.
|
||||
```
|
||||
SDL_SOUNDFONTS=/usr/share/soundfonts/GeneralUser.sf2 xsystem35
|
||||
```
|
||||
|
||||
See [xsys35c](https://github.com/kichikuou/xsys35c)'s document for how to
|
||||
build a game with Unicode mode.
|
||||
### Unicode Translation Support
|
||||
|
||||
While the original System 3.x only supported Shift_JIS (a Japanese character
|
||||
encoding), xsystem35 supports Unicode and can run games translated into
|
||||
languages other than Japanese and English.
|
||||
|
||||
For instructions on how to build a game with Unicode support, see the
|
||||
[xsys35c](https://github.com/kichikuou/xsys35c) documentation.
|
||||
|
||||
### Debugging
|
||||
|
||||
Xsystem35 has a built-in debugger that allows you to step through the game and
|
||||
examine / modify variables in the game. There are two ways to use the debugger:
|
||||
xsystem35 features a built-in debugger that allows you to step through the game
|
||||
and examine or modify game variables. There are two ways to use the debugger:
|
||||
|
||||
- Through [Visual Studio Code](https://code.visualstudio.com/) (recommended):
|
||||
The [vscode-system3x](https://github.com/kichikuou/vscode-system3x) extension
|
||||
provides graphical debugging interface for System 3.x.
|
||||
- Using CUI debugger: Running xsystem35 with `-debug` option will start the
|
||||
debugger with console interface. Type `help` to see a list of available
|
||||
commands.
|
||||
provides a graphical debugging interface for System 3.x.
|
||||
- Using the CLI Debugger: Running xsystem35 with the `-debug` option will
|
||||
launch the debugger with a console interface. Type `help` to see a list of
|
||||
available commands.
|
||||
|
||||
## Installing
|
||||
## Installation
|
||||
|
||||
Prebuilt packages for Windows and Android can be downloaded from the
|
||||
[Releases](https://github.com/kichikuou/xsystem35-sdl2/releases) page. For
|
||||
other platforms, see the [Building](#building) section.
|
||||
[Releases](https://github.com/kichikuou/xsystem35-sdl2/releases) page.
|
||||
|
||||
Note for Windows:
|
||||
- The 64-bit version supports Windows 10 or later. For older versions of
|
||||
Windows, please use the 32-bit version.
|
||||
- Debugging is supported only in the 64-bit version.
|
||||
|
||||
For other platforms, refer to the [Building](#building) section.
|
||||
|
||||
## Running
|
||||
### Windows
|
||||
|
||||
Execute `xsytem35`, and it will show a dialog to select a folder. Select the
|
||||
game folder (where the ALD files are located).
|
||||
Copy `xsystem35.exe` to the game folder and run it.
|
||||
|
||||
### Android
|
||||
|
||||
See [android/README.md](https://github.com/kichikuou/xsystem35-sdl2/blob/master/android/README.md#use).
|
||||
See [android/README.md](android/README.md#usage).
|
||||
|
||||
### Other Platforms
|
||||
|
||||
Run xsystem35 from within the game directory.
|
||||
|
||||
cd /path/to/game_directory
|
||||
xsystem35
|
||||
```bash
|
||||
$ cd /path/to/game_directory
|
||||
$ xsystem35
|
||||
```
|
||||
|
||||
See [xsystem35 command manual](doc/xsystem35.6.adoc) for detailed usage.
|
||||
|
||||
## Building
|
||||
### Linux (Debian / Ubuntu)
|
||||
|
||||
$ sudo apt install build-essential cmake libgtk-3-dev libsdl2-dev libsdl2-ttf-dev libsdl2-mixer-dev libwebp-dev libcjson-dev
|
||||
$ mkdir -p out/debug
|
||||
$ cd out/debug
|
||||
$ cmake -DCMAKE_BUILD_TYPE=Debug ../../
|
||||
$ make && make install
|
||||
```bash
|
||||
$ sudo apt install build-essential cmake libgtk-3-dev libsdl2-dev libsdl2-ttf-dev libsdl2-mixer-dev libwebp-dev libportmidi-dev libcjson-dev asciidoctor
|
||||
$ mkdir -p out/debug
|
||||
$ cd out/debug
|
||||
$ cmake -DCMAKE_BUILD_TYPE=Debug ../../
|
||||
$ make && make install
|
||||
```
|
||||
|
||||
### MacOS
|
||||
|
||||
[Homebrew](https://brew.sh/index_ja) is needed.
|
||||
[Homebrew](https://brew.sh/) is required.
|
||||
|
||||
$ brew install cmake pkg-config sdl2 sdl2_mixer sdl2_ttf webp cjson
|
||||
$ mkdir -p out/debug
|
||||
$ cd out/debug
|
||||
$ cmake -DCMAKE_BUILD_TYPE=Debug ../../
|
||||
$ make && make install
|
||||
```bash
|
||||
$ brew install cmake pkg-config sdl2 sdl2_mixer sdl2_ttf webp portmidi cjson asciidoctor
|
||||
$ mkdir -p out/debug
|
||||
$ cd out/debug
|
||||
$ cmake -DCMAKE_BUILD_TYPE=Debug ../../
|
||||
$ make && make install
|
||||
```
|
||||
|
||||
### Windows
|
||||
|
||||
[MSYS2](https://www.msys2.org) is needed.
|
||||
[MSYS2](https://www.msys2.org) is required.
|
||||
|
||||
$ pacman -S cmake mingw-w64-x86_64-cmake mingw-w64-x86_64-SDL2 mingw-w64-x86_64-SDL2_ttf mingw-w64-x86_64-SDL2_mixer mingw-w64-x86_64-libwebp mingw-w64-x86_64-cjson
|
||||
$ mkdir -p out/debug
|
||||
$ cd out/debug
|
||||
$ cmake -G"MSYS Makefiles" -DCMAKE_BUILD_TYPE=Debug ../../
|
||||
$ make
|
||||
```bash
|
||||
$ pacman -S cmake mingw-w64-ucrt-x86_64-gcc mingw-w64-ucrt-x86_64-cmake mingw-w64-ucrt-x86_64-SDL2 mingw-w64-ucrt-x86_64-SDL2_ttf mingw-w64-ucrt-x86_64-SDL2_mixer mingw-w64-ucrt-x86_64-libwebp mingw-w64-ucrt-x86_64-portmidi mingw-w64-ucrt-x86_64-cjson
|
||||
$ mkdir -p out/debug
|
||||
$ cd out/debug
|
||||
$ cmake -G"MSYS Makefiles" -DCMAKE_BUILD_TYPE=Debug ../../
|
||||
$ make
|
||||
```
|
||||
|
||||
### Emscripten
|
||||
|
||||
$ mkdir -p out/wasm
|
||||
$ cd out/wasm
|
||||
$ emcmake cmake -DCMAKE_BUILD_TYPE=MinSizeRel ../../
|
||||
$ make
|
||||
```bash
|
||||
$ mkdir -p out/wasm
|
||||
$ cd out/wasm
|
||||
$ emcmake cmake -DCMAKE_BUILD_TYPE=MinSizeRel ../../
|
||||
$ make
|
||||
```
|
||||
|
||||
To use the generated binary, checkout
|
||||
To use the generated binary, check out
|
||||
[Kichikuou on Web](https://github.com/kichikuou/web) and copy `out/xsystem35.*`
|
||||
into its `docs` directory.
|
||||
|
||||
|
||||
+34
-20
@@ -1,7 +1,8 @@
|
||||
# xsystem35 for Android
|
||||
|
||||
## Download
|
||||
Prebuilt APKs are [here](https://github.com/kichikuou/xsystem35-sdl2/releases).
|
||||
You can download prebuilt APKs
|
||||
[here](https://github.com/kichikuou/xsystem35-sdl2/releases).
|
||||
|
||||
## Build
|
||||
Prerequisites:
|
||||
@@ -11,10 +12,10 @@ Prerequisites:
|
||||
### Using Android Studio
|
||||
Open this directory as an Android Studio project.
|
||||
|
||||
### Command line build
|
||||
Configure environment variables and run the `gradlew` script in this folder.
|
||||
### Command Line Build
|
||||
Set environment variables and run the `gradlew` script in this directory.
|
||||
|
||||
Example build instructions (for Debian bullseye):
|
||||
Example build instructions (for Debian bookworm):
|
||||
```sh
|
||||
# Install necessary packages
|
||||
sudo apt install git wget unzip default-jdk-headless ninja-build
|
||||
@@ -22,38 +23,51 @@ sudo apt install git wget unzip default-jdk-headless ninja-build
|
||||
# Install Android SDK / NDK
|
||||
export ANDROID_SDK_ROOT=$HOME/android-sdk
|
||||
mkdir -p $ANDROID_SDK_ROOT/cmdline-tools
|
||||
wget https://dl.google.com/android/repository/commandlinetools-linux-8512546_latest.zip
|
||||
unzip commandlinetools-linux-8512546_latest.zip -d $ANDROID_SDK_ROOT/cmdline-tools
|
||||
wget https://dl.google.com/android/repository/commandlinetools-linux-10406996_latest.zip
|
||||
unzip commandlinetools-linux-10406996_latest.zip -d $ANDROID_SDK_ROOT/cmdline-tools
|
||||
mv $ANDROID_SDK_ROOT/cmdline-tools/cmdline-tools $ANDROID_SDK_ROOT/cmdline-tools/tools
|
||||
yes |$ANDROID_SDK_ROOT/cmdline-tools/tools/bin/sdkmanager --licenses
|
||||
yes | $ANDROID_SDK_ROOT/cmdline-tools/tools/bin/sdkmanager --licenses
|
||||
$ANDROID_SDK_ROOT/cmdline-tools/tools/bin/sdkmanager ndk-bundle 'cmake;3.22.1'
|
||||
export ANDROID_NDK_HOME=$ANDROID_SDK_ROOT/ndk-bundle
|
||||
|
||||
# Check out and build xsystem35
|
||||
# Clone and build xsystem35
|
||||
git clone https://github.com/kichikuou/xsystem35-sdl2.git
|
||||
cd xsystem35-sdl2/android
|
||||
./gradlew build # or ./gradlew installDebug if you have a connected device
|
||||
```
|
||||
|
||||
## Use
|
||||
## Usage
|
||||
### Basic Usage
|
||||
1. Create a ZIP file containing all the game files and BGM files (see [below](#preparing-a-zip) for details), and transfer it to your device.
|
||||
2. Open the app. A list of installed games is displayed. Since nothing has been installed yet, only the "Install from ZIP" button is displayed. Tap it.
|
||||
3. Select the ZIP file you created in 1.
|
||||
4. The game starts. To simulate right-click, tap the black bars on the left/right or top/bottom of the screen.
|
||||
1. Create a ZIP file containing all the game files and BGM files (see
|
||||
[below](#preparing-a-zip) for details), and transfer it to your device.
|
||||
2. Open the app. A list of installed games will be displayed. Since no games
|
||||
have been installed yet, only the "Install from ZIP" button will be visible.
|
||||
Tap it.
|
||||
3. Select the ZIP file you created in step 1.
|
||||
4. The game will start. To simulate a right-click, tap the black bars on either
|
||||
the left or right, or top or bottom of the screen.
|
||||
|
||||
### Preparing a ZIP
|
||||
- Include all files in the `GAMEDATA` folder (`.ALD` files and others). `.EXE` and `.DLL` are not really needed, but you can include them as well.
|
||||
- Music files (`.mp3`, `.ogg` or `.wav`) whose file names end with a number are recognized as BGM files. For example:
|
||||
- Include all files from the `GAMEDATA` folder (such as `.ALD` files and
|
||||
others). `.EXE` and `.DLL` files are not necessary, but you can include them
|
||||
if you want.
|
||||
- Music files (`.mp3`, `.ogg`, or `.wav`) whose filenames end with a number
|
||||
will be recognized as BGM files. For example:
|
||||
- `Track2.mp3`
|
||||
- `15.ogg`
|
||||
- `rance4_03.wav` (This shouldn't be `rance403.wav`, because it would be treated as the 403rd track)
|
||||
- `rance4_03.wav` (Note: The filename shouldn't be `rance403.wav`, as it
|
||||
would be treated as the 403rd track.)
|
||||
|
||||
Note: This form of ZIP can be used in [Kichikuou on Web](http://kichikuou.github.io/web/) as well.
|
||||
Note: This ZIP format is also compatible with
|
||||
[Kichikuou on Web](http://kichikuou.github.io/web/).
|
||||
|
||||
### Miscellaneous
|
||||
- You can export / import saved files using the option menu of the game list.
|
||||
- To uninstall a game, long-tap the title in the game list.
|
||||
- You can export or import save files via the game list's option menu.
|
||||
- To uninstall a game, long-tap its title in the game list.
|
||||
|
||||
## Known Issues
|
||||
- Android versions older than 7.0 cannot handle ZIPs containing Shift-JIS file names. This is the case with some ZIPs distributed on [retroc.net](http://retropc.net/alice/). If you get the error "This type of ZIP is not supported.", unzip the ZIP file on your PC and re-archive it with a modern ZIP creation software.
|
||||
- Android versions older than 7.0 cannot handle ZIP files containing Shift-JIS
|
||||
filenames. This issue occurs with some ZIP files distributed on
|
||||
[retroc.net](http://retropc.net/alice/). If you encounter the error message
|
||||
"This type of ZIP is not supported," unzip the file on your PC and re-archive
|
||||
it using modern ZIP creation software.
|
||||
|
||||
+14
-11
@@ -9,18 +9,18 @@ else {
|
||||
apply plugin: 'kotlin-android'
|
||||
|
||||
android {
|
||||
compileSdkVersion 31
|
||||
if (buildAsApplication) {
|
||||
namespace "io.github.kichikuou.xsystem35"
|
||||
}
|
||||
compileSdkVersion 34
|
||||
defaultConfig {
|
||||
if (buildAsApplication) {
|
||||
applicationId "io.github.kichikuou.xsystem35"
|
||||
}
|
||||
minSdkVersion 19
|
||||
targetSdkVersion 31
|
||||
versionCode 12
|
||||
versionName "2.7.0" + gitRevision()
|
||||
targetSdkVersion 34
|
||||
versionCode 28
|
||||
versionName "2.13.0" + gitRevision()
|
||||
externalNativeBuild {
|
||||
cmake {
|
||||
arguments "-DANDROID_APP_PLATFORM=android-16", "-DANDROID_STL=c++_static"
|
||||
arguments "-DANDROID_APP_PLATFORM=android-19", "-DANDROID_STL=c++_static"
|
||||
// abiFilters 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64'
|
||||
abiFilters 'armeabi-v7a', 'arm64-v8a'
|
||||
}
|
||||
@@ -38,7 +38,9 @@ android {
|
||||
release {
|
||||
minifyEnabled false
|
||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||
signingConfig signingConfigs.release
|
||||
if (rootProject.file('keystore.jks').exists()) {
|
||||
signingConfig signingConfigs.release
|
||||
}
|
||||
}
|
||||
}
|
||||
applicationVariants.all { variant ->
|
||||
@@ -62,10 +64,10 @@ android {
|
||||
}
|
||||
|
||||
}
|
||||
lintOptions {
|
||||
lint {
|
||||
abortOnError false
|
||||
}
|
||||
|
||||
|
||||
if (buildAsLibrary) {
|
||||
libraryVariants.all { variant ->
|
||||
variant.outputs.each { output ->
|
||||
@@ -82,6 +84,7 @@ android {
|
||||
dependencies {
|
||||
implementation fileTree(include: ['*.jar'], dir: 'libs')
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
|
||||
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4'
|
||||
}
|
||||
|
||||
static String gitRevision() {
|
||||
|
||||
@@ -1,50 +1,39 @@
|
||||
cmake_minimum_required(VERSION 3.13)
|
||||
cmake_minimum_required(VERSION 3.14)
|
||||
|
||||
project(GAME)
|
||||
set(PROJECT_ROOT_DIR ../../..)
|
||||
|
||||
# Compilation of SDL and companion libraries
|
||||
include(FetchContent)
|
||||
FetchContent_Declare(
|
||||
SDL
|
||||
URL https://github.com/libsdl-org/SDL/releases/download/release-2.26.1/SDL2-2.26.1.tar.gz
|
||||
URL_HASH SHA1=08a8cec21ffcebf44e4633a786d594a7811100d2
|
||||
URL https://github.com/libsdl-org/SDL/releases/download/release-2.30.9/SDL2-2.30.9.tar.gz
|
||||
URL_HASH SHA1=9403df0573d47f62f2de074b582b87576bb4abbc
|
||||
)
|
||||
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
|
||||
)
|
||||
|
||||
# Compilation of SDL and companion libraries
|
||||
FetchContent_GetProperties(SDL)
|
||||
if(NOT sdl_POPULATED)
|
||||
FetchContent_Populate(SDL)
|
||||
add_subdirectory(${sdl_SOURCE_DIR} ${sdl_BINARY_DIR})
|
||||
endif()
|
||||
FetchContent_GetProperties(SDL_ttf)
|
||||
if(NOT sdl_ttf_POPULATED)
|
||||
FetchContent_Populate(SDL_ttf)
|
||||
set(SDL2TTF_SAMPLES OFF CACHE BOOL "Build the SDL2_ttf sample program(s)" FORCE)
|
||||
set(SDL2TTF_INSTALL OFF CACHE BOOL "Enable SDL2_ttf install target" FORCE)
|
||||
set(SDL2TTF_VENDORED ON CACHE BOOL "Use vendored third-party libraries" FORCE)
|
||||
add_subdirectory(${sdl_ttf_SOURCE_DIR} ${sdl_ttf_BINARY_DIR})
|
||||
endif()
|
||||
FetchContent_GetProperties(SDL_mixer)
|
||||
if(NOT sdl_mixer_POPULATED)
|
||||
FetchContent_Populate(SDL_mixer)
|
||||
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_SAMPLES OFF CACHE BOOL "Build the SDL2_mixer sample program(s)" FORCE)
|
||||
set(SDL2MIXER_INSTALL OFF CACHE BOOL "Enable SDL2_mixer install target" FORCE)
|
||||
add_subdirectory(${sdl_mixer_SOURCE_DIR} ${sdl_mixer_BINARY_DIR})
|
||||
endif()
|
||||
set(SDL2TTF_SAMPLES OFF CACHE BOOL "Build the SDL2_ttf sample program(s)" FORCE)
|
||||
set(SDL2TTF_INSTALL OFF CACHE BOOL "Enable SDL2_ttf install target" FORCE)
|
||||
set(SDL2TTF_VENDORED ON CACHE BOOL "Use vendored third-party libraries" FORCE)
|
||||
|
||||
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 SDL_ttf SDL_mixer)
|
||||
|
||||
# The main CMakeLists.txt of xsystem35
|
||||
add_subdirectory(${PROJECT_ROOT_DIR} xsystem35)
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
-->
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
package="io.github.kichikuou.xsystem35"
|
||||
android:installLocation="auto">
|
||||
|
||||
<!-- OpenGL ES 2.0 -->
|
||||
@@ -81,7 +80,7 @@
|
||||
android:label="@string/app_name"
|
||||
android:alwaysRetainTaskState="true"
|
||||
android:configChanges="layoutDirection|locale|orientation|uiMode|screenLayout|screenSize|smallestScreenSize|keyboard|keyboardHidden|navigation"
|
||||
android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
|
||||
android:theme="@style/AppTheme"
|
||||
android:hardwareAccelerated="true"
|
||||
>
|
||||
|
||||
|
||||
@@ -30,31 +30,29 @@ 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"
|
||||
}
|
||||
|
||||
private lateinit var gameRoot: File
|
||||
private lateinit var cdda: CddaPlayer
|
||||
private val midi = MidiPlayer()
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
gameRoot = File(intent.getStringExtra(EXTRA_GAME_ROOT)!!)
|
||||
cdda = CddaPlayer(File(gameRoot, Launcher.PLAYLIST_FILE))
|
||||
}
|
||||
|
||||
override fun onStop() {
|
||||
super.onStop()
|
||||
cdda.onActivityStop()
|
||||
midi.onActivityStop()
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
cdda.onActivityResume()
|
||||
midi.onActivityResume()
|
||||
}
|
||||
|
||||
@@ -63,7 +61,9 @@ class GameActivity : SDLActivity() {
|
||||
}
|
||||
|
||||
override fun getArguments(): Array<String> {
|
||||
return arrayOf("-gamedir", intent.getStringExtra(EXTRA_GAME_ROOT)!!)
|
||||
return arrayOf(
|
||||
"-gamedir", intent.getStringExtra(EXTRA_GAME_ROOT)!!,
|
||||
"-savedir", intent.getStringExtra(EXTRA_SAVE_DIRECTORY)!!)
|
||||
}
|
||||
|
||||
override fun setTitle(title: CharSequence?) {
|
||||
@@ -120,9 +120,6 @@ class GameActivity : SDLActivity() {
|
||||
}
|
||||
|
||||
// The functions below are called in the SDL thread by JNI.
|
||||
@Suppress("unused") fun cddaStart(track: Int, loop: Boolean) = cdda.start(track, loop)
|
||||
@Suppress("unused") fun cddaStop() = cdda.stop()
|
||||
@Suppress("unused") fun cddaCurrentPosition() = cdda.currentPosition()
|
||||
@Suppress("unused") fun midiStart(path: String, loop: Boolean) = midi.start(path, loop)
|
||||
@Suppress("unused") fun midiStop() = midi.stop()
|
||||
@Suppress("unused") fun midiCurrentPosition() = midi.currentPosition()
|
||||
@@ -156,69 +153,6 @@ class GameActivity : SDLActivity() {
|
||||
}
|
||||
}
|
||||
|
||||
private class CddaPlayer(private val playlistPath: File) {
|
||||
private val playlist =
|
||||
try {
|
||||
playlistPath.readLines()
|
||||
} catch (e: IOException) {
|
||||
Log.e("loadPlaylist", "Cannot load $playlistPath", e)
|
||||
emptyList()
|
||||
}
|
||||
private var currentTrack = 0
|
||||
private val player = MediaPlayer()
|
||||
private var playerPaused = false
|
||||
|
||||
fun start(track: Int, loop: Boolean) {
|
||||
val f = playlist.elementAtOrNull(track - 1)
|
||||
if (f.isNullOrEmpty()) {
|
||||
Log.w("cddaStart", "No playlist entry for track $track")
|
||||
return
|
||||
}
|
||||
Log.v("cddaStart", "$f Loop:$loop")
|
||||
try {
|
||||
player.apply {
|
||||
reset()
|
||||
setDataSource(File(playlistPath.parent, f).path)
|
||||
isLooping = loop
|
||||
prepare()
|
||||
start()
|
||||
}
|
||||
currentTrack = track
|
||||
} catch (e: IOException) {
|
||||
Log.e("cddaStart", "Cannot play $f", e)
|
||||
player.reset()
|
||||
}
|
||||
}
|
||||
|
||||
fun stop() {
|
||||
if (currentTrack > 0 && player.isPlaying) {
|
||||
player.stop()
|
||||
currentTrack = 0
|
||||
}
|
||||
}
|
||||
|
||||
fun currentPosition(): Int {
|
||||
if (currentTrack == 0)
|
||||
return 0
|
||||
val frames = player.currentPosition * 75 / 1000
|
||||
return currentTrack or (frames shl 8)
|
||||
}
|
||||
|
||||
fun onActivityStop() {
|
||||
if (currentTrack > 0 && player.isPlaying) {
|
||||
player.pause()
|
||||
playerPaused = true
|
||||
}
|
||||
}
|
||||
|
||||
fun onActivityResume() {
|
||||
if (playerPaused) {
|
||||
player.start()
|
||||
playerPaused = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class MidiPlayer {
|
||||
private val player = MediaPlayer()
|
||||
private var playing = false
|
||||
|
||||
@@ -17,15 +17,15 @@
|
||||
*/
|
||||
package io.github.kichikuou.xsystem35
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.os.Build
|
||||
import android.os.Handler
|
||||
import android.os.Message
|
||||
import android.util.Log
|
||||
import kotlinx.coroutines.DelicateCoroutinesApi
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
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
|
||||
@@ -39,16 +39,13 @@ interface LauncherObserver {
|
||||
fun onInstallFailure(msgId: Int)
|
||||
}
|
||||
|
||||
private const val SAVE_DIR = "save"
|
||||
private const val PROGRESS = 0
|
||||
private const val SUCCESS = 1
|
||||
private const val FAILURE = 2
|
||||
|
||||
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) {
|
||||
@@ -74,31 +71,28 @@ class Launcher private constructor(private val rootDir: File) {
|
||||
updateGameList()
|
||||
}
|
||||
|
||||
@OptIn(DelicateCoroutinesApi::class)
|
||||
fun install(input: InputStream, archiveName: String?) {
|
||||
val dir = createDirForGame()
|
||||
@SuppressLint("HandlerLeak")
|
||||
val handler = object : Handler() {
|
||||
override fun handleMessage(msg: Message) {
|
||||
when (msg.what) {
|
||||
PROGRESS -> {
|
||||
observer?.onInstallProgress(msg.obj as String)
|
||||
}
|
||||
SUCCESS -> {
|
||||
isInstalling = false
|
||||
observer?.onInstallSuccess(msg.obj as File, archiveName)
|
||||
}
|
||||
FAILURE -> {
|
||||
isInstalling = false
|
||||
observer?.onInstallFailure(msg.obj as Int)
|
||||
isInstalling = true
|
||||
GlobalScope.launch(Dispatchers.Main) {
|
||||
try {
|
||||
val gameDir = withContext(Dispatchers.IO) {
|
||||
extractFiles(input, dir) { msg ->
|
||||
GlobalScope.launch(Dispatchers.Main) {
|
||||
observer?.onInstallProgress(msg)
|
||||
}
|
||||
}
|
||||
}
|
||||
observer?.onInstallSuccess(gameDir, archiveName)
|
||||
} catch (e: InstallFailureException) {
|
||||
observer?.onInstallFailure(e.msgId)
|
||||
} catch (e: Exception) {
|
||||
Log.e("launcher", "Failed to extract ZIP", e)
|
||||
observer?.onInstallFailure(R.string.zip_extraction_error)
|
||||
}
|
||||
isInstalling = false
|
||||
}
|
||||
val t = Thread {
|
||||
extractFiles(input, dir, handler)
|
||||
}
|
||||
t.start()
|
||||
isInstalling = true
|
||||
}
|
||||
|
||||
fun uninstall(id: Int) {
|
||||
@@ -118,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.
|
||||
@@ -183,108 +179,76 @@ class Launcher private constructor(private val rootDir: File) {
|
||||
}
|
||||
}
|
||||
|
||||
private fun extractFiles(input: InputStream, outDir: File, handler: Handler) {
|
||||
try {
|
||||
val configWriter = GameConfigWriter()
|
||||
val hadDecodeError = forEachZipEntry(input) { zipEntry, zip ->
|
||||
Log.i("extractFiles", zipEntry.name)
|
||||
val path = File(outDir, zipEntry.name)
|
||||
if (zipEntry.isDirectory)
|
||||
return@forEachZipEntry
|
||||
path.parentFile?.mkdirs()
|
||||
handler.sendMessage(handler.obtainMessage(PROGRESS, zipEntry.name))
|
||||
FileOutputStream(path).buffered().use {
|
||||
zip.copyTo(it)
|
||||
}
|
||||
configWriter.maybeAdd(zipEntry.name)
|
||||
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)
|
||||
val path = File(outDir, zipEntry.name)
|
||||
if (zipEntry.isDirectory)
|
||||
return@forEachZipEntry
|
||||
path.parentFile?.mkdirs()
|
||||
progressCallback(zipEntry.name)
|
||||
FileOutputStream(path).buffered().use {
|
||||
zip.copyTo(it)
|
||||
}
|
||||
if (!configWriter.readyToWrite()) {
|
||||
val msgId = if (hadDecodeError) R.string.unsupported_zip else R.string.cannot_find_ald
|
||||
handler.sendMessage(handler.obtainMessage(FAILURE, msgId))
|
||||
return
|
||||
}
|
||||
configWriter.write(outDir)
|
||||
handler.sendMessage(handler.obtainMessage(SUCCESS, outDir))
|
||||
} catch (e: IOException) {
|
||||
Log.e("launcher", "Failed to extract ZIP", e)
|
||||
handler.sendMessage(handler.obtainMessage(FAILURE, R.string.zip_extraction_error))
|
||||
configWriter.maybeAdd(zipEntry.name)
|
||||
}
|
||||
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.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()) {
|
||||
oldPlaylist.renameTo(File(dir, PLAYLIST_FILE))
|
||||
}
|
||||
}
|
||||
|
||||
// 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.
|
||||
private fun migratePlaylist(dir: File) {
|
||||
val oldPlaylist = File(dir, OLD_PLAYLIST_FILE)
|
||||
if (!oldPlaylist.exists())
|
||||
return
|
||||
var tracks = oldPlaylist.readLines()
|
||||
if (!tracks.isEmpty())
|
||||
tracks = tracks.subList(1, tracks.size)
|
||||
File(dir, PLAYLIST_FILE).writeText(tracks.joinToString("\n"))
|
||||
oldPlaylist.delete()
|
||||
}
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ import android.view.Menu
|
||||
import android.view.MenuItem
|
||||
import android.widget.ArrayAdapter
|
||||
import android.widget.ListView
|
||||
import android.widget.TextView
|
||||
import android.widget.Toast
|
||||
import java.io.*
|
||||
|
||||
@@ -34,10 +35,11 @@ private const val CONTENT_TYPE_ZIP = "application/zip"
|
||||
private const val INSTALL_REQUEST = 1
|
||||
private const val SAVEDATA_EXPORT_REQUEST = 2
|
||||
private const val SAVEDATA_IMPORT_REQUEST = 3
|
||||
private const val STATE_PROGRESS_TEXT = "progressText"
|
||||
|
||||
class LauncherActivity : Activity(), LauncherObserver {
|
||||
private lateinit var launcher: Launcher
|
||||
private var progressDialog: ProgressDialogFragment? = null
|
||||
private var progressDialog: Dialog? = null
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
@@ -46,7 +48,7 @@ class LauncherActivity : Activity(), LauncherObserver {
|
||||
launcher = Launcher.getInstance(filesDir)
|
||||
launcher.observer = this
|
||||
if (launcher.isInstalling) {
|
||||
showProgressDialog()
|
||||
showProgressDialog(savedInstanceState)
|
||||
}
|
||||
|
||||
onGameListChange()
|
||||
@@ -61,9 +63,17 @@ class LauncherActivity : Activity(), LauncherObserver {
|
||||
|
||||
override fun onDestroy() {
|
||||
launcher.observer = null
|
||||
dismissProgressDialog()
|
||||
super.onDestroy()
|
||||
}
|
||||
|
||||
override fun onSaveInstanceState(outState: Bundle) {
|
||||
progressDialog?.let {
|
||||
outState.putCharSequence(STATE_PROGRESS_TEXT, it.findViewById<TextView>(R.id.text).text)
|
||||
}
|
||||
super.onSaveInstanceState(outState)
|
||||
}
|
||||
|
||||
private fun onListItemClick(position: Int) {
|
||||
if (position < launcher.games.size) {
|
||||
startGame(launcher.games[position].path, null)
|
||||
@@ -153,7 +163,7 @@ class LauncherActivity : Activity(), LauncherObserver {
|
||||
}
|
||||
|
||||
override fun onInstallProgress(path: String) {
|
||||
progressDialog?.setProgress(getString(R.string.install_progress, path))
|
||||
progressDialog?.findViewById<TextView>(R.id.text)?.text = getString(R.string.install_progress, path)
|
||||
}
|
||||
|
||||
override fun onInstallSuccess(path: File, archiveName: String?) {
|
||||
@@ -170,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)
|
||||
}
|
||||
@@ -178,9 +189,17 @@ class LauncherActivity : Activity(), LauncherObserver {
|
||||
launcher.uninstall(id)
|
||||
}
|
||||
|
||||
private fun showProgressDialog() {
|
||||
progressDialog = ProgressDialogFragment()
|
||||
progressDialog!!.show(fragmentManager, "progress_dialog")
|
||||
private fun showProgressDialog(savedInstanceState: Bundle? = null) {
|
||||
progressDialog = Dialog(this)
|
||||
progressDialog!!.apply {
|
||||
setTitle(R.string.install_dialog_title)
|
||||
setCancelable(false)
|
||||
setContentView(R.layout.progress_dialog)
|
||||
savedInstanceState?.let {
|
||||
findViewById<TextView>(R.id.text)?.text = it.getCharSequence(STATE_PROGRESS_TEXT)
|
||||
}
|
||||
show()
|
||||
}
|
||||
}
|
||||
|
||||
private fun dismissProgressDialog() {
|
||||
@@ -209,18 +228,3 @@ class LauncherActivity : Activity(), LauncherObserver {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("DEPRECATION") // for ProgressDialog
|
||||
class ProgressDialogFragment : DialogFragment() {
|
||||
private lateinit var dialog: ProgressDialog
|
||||
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
||||
dialog = ProgressDialog(activity)
|
||||
return dialog.apply {
|
||||
setTitle(R.string.install_dialog_title)
|
||||
setCancelable(true)
|
||||
}
|
||||
}
|
||||
fun setProgress(msg: String) {
|
||||
dialog.setMessage(msg)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -186,7 +186,7 @@ class HIDDeviceBLESteamController extends BluetoothGattCallback implements HIDDe
|
||||
// Because on Chromebooks we show up as a dual-mode device, it will attempt to connect TRANSPORT_AUTO, which will use TRANSPORT_BREDR instead
|
||||
// of TRANSPORT_LE. Let's force ourselves to connect low energy.
|
||||
private BluetoothGatt connectGatt(boolean managed) {
|
||||
if (Build.VERSION.SDK_INT >= 23) {
|
||||
if (Build.VERSION.SDK_INT >= 23 /* Android 6.0 (M) */) {
|
||||
try {
|
||||
return mDevice.connectGatt(mManager.getContext(), managed, this, TRANSPORT_LE);
|
||||
} catch (Exception e) {
|
||||
@@ -429,7 +429,7 @@ class HIDDeviceBLESteamController extends BluetoothGattCallback implements HIDDe
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (newState == 0) {
|
||||
mIsConnected = false;
|
||||
}
|
||||
|
||||
@@ -170,7 +170,7 @@ public class HIDDeviceManager {
|
||||
Log.i(TAG," Interface protocol: " + mUsbInterface.getInterfaceProtocol());
|
||||
Log.i(TAG," Endpoint count: " + mUsbInterface.getEndpointCount());
|
||||
|
||||
// Get endpoint details
|
||||
// Get endpoint details
|
||||
for (int epi = 0; epi < mUsbInterface.getEndpointCount(); epi++)
|
||||
{
|
||||
UsbEndpoint mEndpoint = mUsbInterface.getEndpoint(epi);
|
||||
@@ -251,6 +251,8 @@ public class HIDDeviceManager {
|
||||
0x20d6, // PowerA
|
||||
0x24c6, // PowerA
|
||||
0x2c22, // Qanba
|
||||
0x2dc8, // 8BitDo
|
||||
0x9886, // ASTRO Gaming
|
||||
};
|
||||
|
||||
if (usbInterface.getInterfaceClass() == UsbConstants.USB_CLASS_VENDOR_SPEC &&
|
||||
@@ -271,15 +273,20 @@ public class HIDDeviceManager {
|
||||
final int XB1_IFACE_SUBCLASS = 71;
|
||||
final int XB1_IFACE_PROTOCOL = 208;
|
||||
final int[] SUPPORTED_VENDORS = {
|
||||
0x03f0, // HP
|
||||
0x044f, // Thrustmaster
|
||||
0x045e, // Microsoft
|
||||
0x0738, // Mad Catz
|
||||
0x0b05, // ASUS
|
||||
0x0e6f, // PDP
|
||||
0x0f0d, // Hori
|
||||
0x10f5, // Turtle Beach
|
||||
0x1532, // Razer Wildcat
|
||||
0x20d6, // PowerA
|
||||
0x24c6, // PowerA
|
||||
0x2dc8, /* 8BitDo */
|
||||
0x2dc8, // 8BitDo
|
||||
0x2e24, // Hyperkin
|
||||
0x3537, // GameSir
|
||||
};
|
||||
|
||||
if (usbInterface.getId() == 0 &&
|
||||
@@ -353,13 +360,19 @@ public class HIDDeviceManager {
|
||||
private void initializeBluetooth() {
|
||||
Log.d(TAG, "Initializing Bluetooth");
|
||||
|
||||
if (Build.VERSION.SDK_INT <= 30 &&
|
||||
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");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE) || (Build.VERSION.SDK_INT < 18)) {
|
||||
if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE) || (Build.VERSION.SDK_INT < 18 /* Android 4.3 (JELLY_BEAN_MR2) */)) {
|
||||
Log.d(TAG, "Couldn't initialize Bluetooth, this version of Android does not support Bluetooth LE");
|
||||
return;
|
||||
}
|
||||
@@ -524,7 +537,7 @@ public class HIDDeviceManager {
|
||||
for (HIDDevice device : mDevicesById.values()) {
|
||||
device.setFrozen(frozen);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -573,12 +586,18 @@ public class HIDDeviceManager {
|
||||
try {
|
||||
final int FLAG_MUTABLE = 0x02000000; // PendingIntent.FLAG_MUTABLE, but don't require SDK 31
|
||||
int flags;
|
||||
if (Build.VERSION.SDK_INT >= 31) {
|
||||
if (Build.VERSION.SDK_INT >= 31 /* Android 12.0 (S) */) {
|
||||
flags = FLAG_MUTABLE;
|
||||
} else {
|
||||
flags = 0;
|
||||
}
|
||||
mUsbManager.requestPermission(usbDevice, PendingIntent.getBroadcast(mContext, 0, new Intent(HIDDeviceManager.ACTION_USB_PERMISSION), flags));
|
||||
if (Build.VERSION.SDK_INT >= 33 /* Android 14.0 (U) */) {
|
||||
Intent intent = new Intent(HIDDeviceManager.ACTION_USB_PERMISSION);
|
||||
intent.setPackage(mContext.getPackageName());
|
||||
mUsbManager.requestPermission(usbDevice, PendingIntent.getBroadcast(mContext, 0, intent, flags));
|
||||
} else {
|
||||
mUsbManager.requestPermission(usbDevice, PendingIntent.getBroadcast(mContext, 0, new Intent(HIDDeviceManager.ACTION_USB_PERMISSION), flags));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.v(TAG, "Couldn't request permission for USB device " + usbDevice);
|
||||
HIDDeviceOpenResult(deviceID, false);
|
||||
|
||||
@@ -52,7 +52,7 @@ class HIDDeviceUSB implements HIDDevice {
|
||||
@Override
|
||||
public String getSerialNumber() {
|
||||
String result = null;
|
||||
if (Build.VERSION.SDK_INT >= 21) {
|
||||
if (Build.VERSION.SDK_INT >= 21 /* Android 5.0 (LOLLIPOP) */) {
|
||||
try {
|
||||
result = mDevice.getSerialNumber();
|
||||
}
|
||||
@@ -74,7 +74,7 @@ class HIDDeviceUSB implements HIDDevice {
|
||||
@Override
|
||||
public String getManufacturerName() {
|
||||
String result = null;
|
||||
if (Build.VERSION.SDK_INT >= 21) {
|
||||
if (Build.VERSION.SDK_INT >= 21 /* Android 5.0 (LOLLIPOP) */) {
|
||||
result = mDevice.getManufacturerName();
|
||||
}
|
||||
if (result == null) {
|
||||
@@ -86,7 +86,7 @@ class HIDDeviceUSB implements HIDDevice {
|
||||
@Override
|
||||
public String getProductName() {
|
||||
String result = null;
|
||||
if (Build.VERSION.SDK_INT >= 21) {
|
||||
if (Build.VERSION.SDK_INT >= 21 /* Android 5.0 (LOLLIPOP) */) {
|
||||
result = mDevice.getProductName();
|
||||
}
|
||||
if (result == null) {
|
||||
|
||||
@@ -29,6 +29,7 @@ public class SDL {
|
||||
|
||||
// This function stores the current activity (SDL or not)
|
||||
public static void setContext(Context context) {
|
||||
SDLAudioManager.setContext(context);
|
||||
mContext = context;
|
||||
}
|
||||
|
||||
@@ -37,6 +38,10 @@ public class SDL {
|
||||
}
|
||||
|
||||
public static void loadLibrary(String libraryName) throws UnsatisfiedLinkError, SecurityException, NullPointerException {
|
||||
loadLibrary(libraryName, mContext);
|
||||
}
|
||||
|
||||
public static void loadLibrary(String libraryName, Context context) throws UnsatisfiedLinkError, SecurityException, NullPointerException {
|
||||
|
||||
if (libraryName == null) {
|
||||
throw new NullPointerException("No library name provided.");
|
||||
@@ -52,10 +57,10 @@ public class SDL {
|
||||
// To use ReLinker, just add it as a dependency. For more information, see
|
||||
// https://github.com/KeepSafe/ReLinker for ReLinker's repository.
|
||||
//
|
||||
Class<?> relinkClass = mContext.getClassLoader().loadClass("com.getkeepsafe.relinker.ReLinker");
|
||||
Class<?> relinkListenerClass = mContext.getClassLoader().loadClass("com.getkeepsafe.relinker.ReLinker$LoadListener");
|
||||
Class<?> contextClass = mContext.getClassLoader().loadClass("android.content.Context");
|
||||
Class<?> stringClass = mContext.getClassLoader().loadClass("java.lang.String");
|
||||
Class<?> relinkClass = context.getClassLoader().loadClass("com.getkeepsafe.relinker.ReLinker");
|
||||
Class<?> relinkListenerClass = context.getClassLoader().loadClass("com.getkeepsafe.relinker.ReLinker$LoadListener");
|
||||
Class<?> contextClass = context.getClassLoader().loadClass("android.content.Context");
|
||||
Class<?> stringClass = context.getClassLoader().loadClass("java.lang.String");
|
||||
|
||||
// Get a 'force' instance of the ReLinker, so we can ensure libraries are reinstalled if
|
||||
// they've changed during updates.
|
||||
@@ -65,7 +70,7 @@ public class SDL {
|
||||
|
||||
// Actually load the library!
|
||||
Method loadMethod = relinkInstanceClass.getDeclaredMethod("loadLibrary", contextClass, stringClass, stringClass, relinkListenerClass);
|
||||
loadMethod.invoke(relinkInstance, mContext, libraryName, null, null);
|
||||
loadMethod.invoke(relinkInstance, context, libraryName, null, null);
|
||||
}
|
||||
catch (final Throwable e) {
|
||||
// Fall back
|
||||
|
||||
@@ -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 = 26;
|
||||
private static final int SDL_MICRO_VERSION = 1;
|
||||
private static final int SDL_MINOR_VERSION = 30;
|
||||
private static final int SDL_MICRO_VERSION = 9;
|
||||
/*
|
||||
// Display InputType.SOURCE/CLASS of events and devices
|
||||
//
|
||||
@@ -89,11 +89,11 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
||||
| InputDevice.SOURCE_CLASS_POSITION
|
||||
| InputDevice.SOURCE_CLASS_TRACKBALL);
|
||||
|
||||
if (s2 != 0) cls += "Some_Unkown";
|
||||
if (s2 != 0) cls += "Some_Unknown";
|
||||
|
||||
s2 = s_copy & InputDevice.SOURCE_ANY; // keep source only, no class;
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
if (Build.VERSION.SDK_INT >= 23) {
|
||||
tst = InputDevice.SOURCE_BLUETOOTH_STYLUS;
|
||||
if ((s & tst) == tst) src += " BLUETOOTH_STYLUS";
|
||||
s2 &= ~tst;
|
||||
@@ -107,7 +107,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
||||
if ((s & tst) == tst) src += " GAMEPAD";
|
||||
s2 &= ~tst;
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
if (Build.VERSION.SDK_INT >= 21) {
|
||||
tst = InputDevice.SOURCE_HDMI;
|
||||
if ((s & tst) == tst) src += " HDMI";
|
||||
s2 &= ~tst;
|
||||
@@ -146,7 +146,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
||||
if ((s & tst) == tst) src += " TOUCHSCREEN";
|
||||
s2 &= ~tst;
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
|
||||
if (Build.VERSION.SDK_INT >= 18) {
|
||||
tst = InputDevice.SOURCE_TOUCH_NAVIGATION;
|
||||
if ((s & tst) == tst) src += " TOUCH_NAVIGATION";
|
||||
s2 &= ~tst;
|
||||
@@ -163,14 +163,14 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
||||
if (s == FLAG_TAINTED) src += " FLAG_TAINTED";
|
||||
s2 &= ~FLAG_TAINTED;
|
||||
|
||||
if (s2 != 0) src += " Some_Unkown";
|
||||
if (s2 != 0) src += " Some_Unknown";
|
||||
|
||||
Log.v(TAG, prefix + "int=" + s_copy + " CLASS={" + cls + " } source(s):" + src);
|
||||
}
|
||||
*/
|
||||
|
||||
public static boolean mIsResumedCalled, mHasFocus;
|
||||
public static final boolean mHasMultiWindow = (Build.VERSION.SDK_INT >= 24);
|
||||
public static final boolean mHasMultiWindow = (Build.VERSION.SDK_INT >= 24 /* Android 7.0 (N) */);
|
||||
|
||||
// Cursor types
|
||||
// private static final int SDL_SYSTEM_CURSOR_NONE = -1;
|
||||
@@ -224,9 +224,9 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
||||
|
||||
protected static SDLGenericMotionListener_API12 getMotionListener() {
|
||||
if (mMotionListener == null) {
|
||||
if (Build.VERSION.SDK_INT >= 26) {
|
||||
if (Build.VERSION.SDK_INT >= 26 /* Android 8.0 (O) */) {
|
||||
mMotionListener = new SDLGenericMotionListener_API26();
|
||||
} else if (Build.VERSION.SDK_INT >= 24) {
|
||||
} else if (Build.VERSION.SDK_INT >= 24 /* Android 7.0 (N) */) {
|
||||
mMotionListener = new SDLGenericMotionListener_API24();
|
||||
} else {
|
||||
mMotionListener = new SDLGenericMotionListener_API12();
|
||||
@@ -281,7 +281,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
||||
// Load the .so
|
||||
public void loadLibraries() {
|
||||
for (String lib : getLibraries()) {
|
||||
SDL.loadLibrary(lib);
|
||||
SDL.loadLibrary(lib, this);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -393,7 +393,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
||||
mHIDDeviceManager = HIDDeviceManager.acquire(this);
|
||||
|
||||
// Set up the surface
|
||||
mSurface = createSDLSurface(getApplication());
|
||||
mSurface = createSDLSurface(this);
|
||||
|
||||
mLayout = new RelativeLayout(this);
|
||||
mLayout.addView(mSurface);
|
||||
@@ -404,7 +404,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
||||
SDLActivity.onNativeOrientationChanged(mCurrentOrientation);
|
||||
|
||||
try {
|
||||
if (Build.VERSION.SDK_INT < 24) {
|
||||
if (Build.VERSION.SDK_INT < 24 /* Android 7.0 (N) */) {
|
||||
mCurrentLocale = getContext().getResources().getConfiguration().locale;
|
||||
} else {
|
||||
mCurrentLocale = getContext().getResources().getConfiguration().getLocales().get(0);
|
||||
@@ -588,6 +588,8 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
||||
mHIDDeviceManager = null;
|
||||
}
|
||||
|
||||
SDLAudioManager.release(this);
|
||||
|
||||
if (SDLActivity.mBrokenLibraries) {
|
||||
super.onDestroy();
|
||||
return;
|
||||
@@ -766,7 +768,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
||||
}
|
||||
break;
|
||||
case COMMAND_CHANGE_WINDOW_STYLE:
|
||||
if (Build.VERSION.SDK_INT >= 19) {
|
||||
if (Build.VERSION.SDK_INT >= 19 /* Android 4.4 (KITKAT) */) {
|
||||
if (context instanceof Activity) {
|
||||
Window window = ((Activity) context).getWindow();
|
||||
if (window != null) {
|
||||
@@ -841,7 +843,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
||||
msg.obj = data;
|
||||
boolean result = commandHandler.sendMessage(msg);
|
||||
|
||||
if (Build.VERSION.SDK_INT >= 19) {
|
||||
if (Build.VERSION.SDK_INT >= 19 /* Android 4.4 (KITKAT) */) {
|
||||
if (command == COMMAND_CHANGE_WINDOW_STYLE) {
|
||||
// Ensure we don't return until the resize has actually happened,
|
||||
// or 500ms have passed.
|
||||
@@ -969,15 +971,18 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
||||
/* If set, hint "explicitly controls which UI orientations are allowed". */
|
||||
if (hint.contains("LandscapeRight") && hint.contains("LandscapeLeft")) {
|
||||
orientation_landscape = ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE;
|
||||
} else if (hint.contains("LandscapeRight")) {
|
||||
orientation_landscape = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
|
||||
} else if (hint.contains("LandscapeLeft")) {
|
||||
orientation_landscape = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
|
||||
} else if (hint.contains("LandscapeRight")) {
|
||||
orientation_landscape = ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE;
|
||||
}
|
||||
|
||||
if (hint.contains("Portrait") && hint.contains("PortraitUpsideDown")) {
|
||||
/* exact match to 'Portrait' to distinguish with PortraitUpsideDown */
|
||||
boolean contains_Portrait = hint.contains("Portrait ") || hint.endsWith("Portrait");
|
||||
|
||||
if (contains_Portrait && hint.contains("PortraitUpsideDown")) {
|
||||
orientation_portrait = ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT;
|
||||
} else if (hint.contains("Portrait")) {
|
||||
} else if (contains_Portrait) {
|
||||
orientation_portrait = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
|
||||
} else if (hint.contains("PortraitUpsideDown")) {
|
||||
orientation_portrait = ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT;
|
||||
@@ -990,8 +995,8 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
||||
/* No valid hint, nothing is explicitly allowed */
|
||||
if (!is_portrait_allowed && !is_landscape_allowed) {
|
||||
if (resizable) {
|
||||
/* All orientations are allowed */
|
||||
req = ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR;
|
||||
/* All orientations are allowed, respecting user orientation lock setting */
|
||||
req = ActivityInfo.SCREEN_ORIENTATION_FULL_USER;
|
||||
} else {
|
||||
/* Fixed window and nothing specified. Get orientation from w/h of created window */
|
||||
req = (w > h ? ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE : ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT);
|
||||
@@ -1000,8 +1005,8 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
||||
/* At least one orientation is allowed */
|
||||
if (resizable) {
|
||||
if (is_portrait_allowed && is_landscape_allowed) {
|
||||
/* hint allows both landscape and portrait, promote to full sensor */
|
||||
req = ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR;
|
||||
/* hint allows both landscape and portrait, promote to full user */
|
||||
req = ActivityInfo.SCREEN_ORIENTATION_FULL_USER;
|
||||
} else {
|
||||
/* Use the only one allowed "orientation" */
|
||||
req = (is_landscape_allowed ? orientation_landscape : orientation_portrait);
|
||||
@@ -1090,7 +1095,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
||||
// thus SDK version 27. If we are in DeX mode and not API 27 or higher, as a result,
|
||||
// we should stick to relative mode.
|
||||
//
|
||||
if ((Build.VERSION.SDK_INT < 27) && isDeXMode()) {
|
||||
if (Build.VERSION.SDK_INT < 27 /* Android 8.1 (O_MR1) */ && isDeXMode()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1180,7 +1185,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
||||
* This method is called by SDL using JNI.
|
||||
*/
|
||||
public static boolean isDeXMode() {
|
||||
if (Build.VERSION.SDK_INT < 24) {
|
||||
if (Build.VERSION.SDK_INT < 24 /* Android 7.0 (N) */) {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
@@ -1340,23 +1345,6 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
||||
}
|
||||
}
|
||||
|
||||
if ((source & InputDevice.SOURCE_KEYBOARD) == InputDevice.SOURCE_KEYBOARD) {
|
||||
if (event.getAction() == KeyEvent.ACTION_DOWN) {
|
||||
if (isTextInputEvent(event)) {
|
||||
if (ic != null) {
|
||||
ic.commitText(String.valueOf((char) event.getUnicodeChar()), 1);
|
||||
} else {
|
||||
SDLInputConnection.nativeCommitText(String.valueOf((char) event.getUnicodeChar()), 1);
|
||||
}
|
||||
}
|
||||
onNativeKeyDown(keyCode);
|
||||
return true;
|
||||
} else if (event.getAction() == KeyEvent.ACTION_UP) {
|
||||
onNativeKeyUp(keyCode);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if ((source & InputDevice.SOURCE_MOUSE) == InputDevice.SOURCE_MOUSE) {
|
||||
// on some devices key events are sent for mouse BUTTON_BACK/FORWARD presses
|
||||
// they are ignored here because sending them as mouse input to SDL is messy
|
||||
@@ -1371,6 +1359,21 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
||||
}
|
||||
}
|
||||
|
||||
if (event.getAction() == KeyEvent.ACTION_DOWN) {
|
||||
if (isTextInputEvent(event)) {
|
||||
if (ic != null) {
|
||||
ic.commitText(String.valueOf((char) event.getUnicodeChar()), 1);
|
||||
} else {
|
||||
SDLInputConnection.nativeCommitText(String.valueOf((char) event.getUnicodeChar()), 1);
|
||||
}
|
||||
}
|
||||
onNativeKeyDown(keyCode);
|
||||
return true;
|
||||
} else if (event.getAction() == KeyEvent.ACTION_UP) {
|
||||
onNativeKeyUp(keyCode);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1617,7 +1620,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
||||
private final Runnable rehideSystemUi = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (Build.VERSION.SDK_INT >= 19) {
|
||||
if (Build.VERSION.SDK_INT >= 19 /* Android 4.4 (KITKAT) */) {
|
||||
int flags = View.SYSTEM_UI_FLAG_FULLSCREEN |
|
||||
View.SYSTEM_UI_FLAG_HIDE_NAVIGATION |
|
||||
View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY |
|
||||
@@ -1670,7 +1673,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
||||
Bitmap bitmap = Bitmap.createBitmap(colors, width, height, Bitmap.Config.ARGB_8888);
|
||||
++mLastCursorID;
|
||||
|
||||
if (Build.VERSION.SDK_INT >= 24) {
|
||||
if (Build.VERSION.SDK_INT >= 24 /* Android 7.0 (N) */) {
|
||||
try {
|
||||
mCursors.put(mLastCursorID, PointerIcon.create(bitmap, hotSpotX, hotSpotY));
|
||||
} catch (Exception e) {
|
||||
@@ -1686,7 +1689,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
||||
* This method is called by SDL using JNI.
|
||||
*/
|
||||
public static void destroyCustomCursor(int cursorID) {
|
||||
if (Build.VERSION.SDK_INT >= 24) {
|
||||
if (Build.VERSION.SDK_INT >= 24 /* Android 7.0 (N) */) {
|
||||
try {
|
||||
mCursors.remove(cursorID);
|
||||
} catch (Exception e) {
|
||||
@@ -1700,7 +1703,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
||||
*/
|
||||
public static boolean setCustomCursor(int cursorID) {
|
||||
|
||||
if (Build.VERSION.SDK_INT >= 24) {
|
||||
if (Build.VERSION.SDK_INT >= 24 /* Android 7.0 (N) */) {
|
||||
try {
|
||||
mSurface.setPointerIcon(mCursors.get(cursorID));
|
||||
} catch (Exception e) {
|
||||
@@ -1755,7 +1758,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
||||
cursor_type = 1002; //PointerIcon.TYPE_HAND;
|
||||
break;
|
||||
}
|
||||
if (Build.VERSION.SDK_INT >= 24) {
|
||||
if (Build.VERSION.SDK_INT >= 24 /* Android 7.0 (N) */) {
|
||||
try {
|
||||
mSurface.setPointerIcon(PointerIcon.getSystemIcon(SDL.getContext(), cursor_type));
|
||||
} catch (Exception e) {
|
||||
@@ -1769,7 +1772,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
||||
* This method is called by SDL using JNI.
|
||||
*/
|
||||
public static void requestPermission(String permission, int requestCode) {
|
||||
if (Build.VERSION.SDK_INT < 23) {
|
||||
if (Build.VERSION.SDK_INT < 23 /* Android 6.0 (M) */) {
|
||||
nativePermissionResult(requestCode, true);
|
||||
return;
|
||||
}
|
||||
@@ -1798,7 +1801,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
||||
i.setData(Uri.parse(url));
|
||||
|
||||
int flags = Intent.FLAG_ACTIVITY_NO_HISTORY | Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
|
||||
if (Build.VERSION.SDK_INT >= 21) {
|
||||
if (Build.VERSION.SDK_INT >= 21 /* Android 5.0 (LOLLIPOP) */) {
|
||||
flags |= Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
|
||||
} else {
|
||||
flags |= Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET;
|
||||
@@ -2002,6 +2005,18 @@ class SDLInputConnection extends BaseInputConnection {
|
||||
|
||||
@Override
|
||||
public boolean deleteSurroundingText(int beforeLength, int afterLength) {
|
||||
if (Build.VERSION.SDK_INT <= 29 /* Android 10.0 (Q) */) {
|
||||
// Workaround to capture backspace key. Ref: http://stackoverflow.com/questions>/14560344/android-backspace-in-webview-baseinputconnection
|
||||
// and https://bugzilla.libsdl.org/show_bug.cgi?id=2265
|
||||
if (beforeLength > 0 && afterLength == 0) {
|
||||
// backspace(s)
|
||||
while (beforeLength-- > 0) {
|
||||
nativeGenerateScancodeForUnichar('\b');
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!super.deleteSurroundingText(beforeLength, afterLength)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
package org.libsdl.app;
|
||||
|
||||
import android.content.Context;
|
||||
import android.media.AudioDeviceCallback;
|
||||
import android.media.AudioDeviceInfo;
|
||||
import android.media.AudioFormat;
|
||||
import android.media.AudioManager;
|
||||
import android.media.AudioRecord;
|
||||
@@ -8,34 +11,67 @@ import android.media.MediaRecorder;
|
||||
import android.os.Build;
|
||||
import android.util.Log;
|
||||
|
||||
public class SDLAudioManager
|
||||
{
|
||||
import java.util.Arrays;
|
||||
|
||||
public class SDLAudioManager {
|
||||
protected static final String TAG = "SDLAudio";
|
||||
|
||||
protected static AudioTrack mAudioTrack;
|
||||
protected static AudioRecord mAudioRecord;
|
||||
protected static Context mContext;
|
||||
|
||||
private static final int[] NO_DEVICES = {};
|
||||
|
||||
private static AudioDeviceCallback mAudioDeviceCallback;
|
||||
|
||||
public static void initialize() {
|
||||
mAudioTrack = null;
|
||||
mAudioRecord = null;
|
||||
mAudioDeviceCallback = null;
|
||||
|
||||
if(Build.VERSION.SDK_INT >= 24 /* Android 7.0 (N) */)
|
||||
{
|
||||
mAudioDeviceCallback = new AudioDeviceCallback() {
|
||||
@Override
|
||||
public void onAudioDevicesAdded(AudioDeviceInfo[] addedDevices) {
|
||||
Arrays.stream(addedDevices).forEach(deviceInfo -> addAudioDevice(deviceInfo.isSink(), deviceInfo.getId()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAudioDevicesRemoved(AudioDeviceInfo[] removedDevices) {
|
||||
Arrays.stream(removedDevices).forEach(deviceInfo -> removeAudioDevice(deviceInfo.isSink(), deviceInfo.getId()));
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public static void setContext(Context context) {
|
||||
mContext = context;
|
||||
if (context != null) {
|
||||
registerAudioDeviceCallback();
|
||||
}
|
||||
}
|
||||
|
||||
public static void release(Context context) {
|
||||
unregisterAudioDeviceCallback(context);
|
||||
}
|
||||
|
||||
// Audio
|
||||
|
||||
protected static String getAudioFormatString(int audioFormat) {
|
||||
switch (audioFormat) {
|
||||
case AudioFormat.ENCODING_PCM_8BIT:
|
||||
return "8-bit";
|
||||
case AudioFormat.ENCODING_PCM_16BIT:
|
||||
return "16-bit";
|
||||
case AudioFormat.ENCODING_PCM_FLOAT:
|
||||
return "float";
|
||||
default:
|
||||
return Integer.toString(audioFormat);
|
||||
case AudioFormat.ENCODING_PCM_8BIT:
|
||||
return "8-bit";
|
||||
case AudioFormat.ENCODING_PCM_16BIT:
|
||||
return "16-bit";
|
||||
case AudioFormat.ENCODING_PCM_FLOAT:
|
||||
return "float";
|
||||
default:
|
||||
return Integer.toString(audioFormat);
|
||||
}
|
||||
}
|
||||
|
||||
protected static int[] open(boolean isCapture, int sampleRate, int audioFormat, int desiredChannels, int desiredFrames) {
|
||||
protected static int[] open(boolean isCapture, int sampleRate, int audioFormat, int desiredChannels, int desiredFrames, int deviceId) {
|
||||
int channelConfig;
|
||||
int sampleSize;
|
||||
int frameSize;
|
||||
@@ -43,14 +79,14 @@ public class SDLAudioManager
|
||||
Log.v(TAG, "Opening " + (isCapture ? "capture" : "playback") + ", requested " + desiredFrames + " frames of " + desiredChannels + " channel " + getAudioFormatString(audioFormat) + " audio at " + sampleRate + " Hz");
|
||||
|
||||
/* On older devices let's use known good settings */
|
||||
if (Build.VERSION.SDK_INT < 21) {
|
||||
if (Build.VERSION.SDK_INT < 21 /* Android 5.0 (LOLLIPOP) */) {
|
||||
if (desiredChannels > 2) {
|
||||
desiredChannels = 2;
|
||||
}
|
||||
}
|
||||
|
||||
/* AudioTrack has sample rate limitation of 48000 (fixed in 5.0.2) */
|
||||
if (Build.VERSION.SDK_INT < 22) {
|
||||
if (Build.VERSION.SDK_INT < 22 /* Android 5.1 (LOLLIPOP_MR1) */) {
|
||||
if (sampleRate < 8000) {
|
||||
sampleRate = 8000;
|
||||
} else if (sampleRate > 48000) {
|
||||
@@ -59,7 +95,7 @@ public class SDLAudioManager
|
||||
}
|
||||
|
||||
if (audioFormat == AudioFormat.ENCODING_PCM_FLOAT) {
|
||||
int minSDKVersion = (isCapture ? 23 : 21);
|
||||
int minSDKVersion = (isCapture ? 23 /* Android 6.0 (M) */ : 21 /* Android 5.0 (LOLLIPOP) */);
|
||||
if (Build.VERSION.SDK_INT < minSDKVersion) {
|
||||
audioFormat = AudioFormat.ENCODING_PCM_16BIT;
|
||||
}
|
||||
@@ -120,7 +156,7 @@ public class SDLAudioManager
|
||||
channelConfig = AudioFormat.CHANNEL_OUT_5POINT1 | AudioFormat.CHANNEL_OUT_BACK_CENTER;
|
||||
break;
|
||||
case 8:
|
||||
if (Build.VERSION.SDK_INT >= 23) {
|
||||
if (Build.VERSION.SDK_INT >= 23 /* Android 6.0 (M) */) {
|
||||
channelConfig = AudioFormat.CHANNEL_OUT_7POINT1_SURROUND;
|
||||
} else {
|
||||
Log.v(TAG, "Requested " + desiredChannels + " channels, getting 5.1 surround");
|
||||
@@ -201,6 +237,10 @@ public class SDLAudioManager
|
||||
return null;
|
||||
}
|
||||
|
||||
if (Build.VERSION.SDK_INT >= 24 /* Android 7.0 (N) */ && deviceId != 0) {
|
||||
mAudioRecord.setPreferredDevice(getOutputAudioDeviceInfo(deviceId));
|
||||
}
|
||||
|
||||
mAudioRecord.startRecording();
|
||||
}
|
||||
|
||||
@@ -224,6 +264,10 @@ public class SDLAudioManager
|
||||
return null;
|
||||
}
|
||||
|
||||
if (Build.VERSION.SDK_INT >= 24 /* Android 7.0 (N) */ && deviceId != 0) {
|
||||
mAudioTrack.setPreferredDevice(getInputAudioDeviceInfo(deviceId));
|
||||
}
|
||||
|
||||
mAudioTrack.play();
|
||||
}
|
||||
|
||||
@@ -238,11 +282,73 @@ public class SDLAudioManager
|
||||
return results;
|
||||
}
|
||||
|
||||
private static AudioDeviceInfo getInputAudioDeviceInfo(int deviceId) {
|
||||
if (Build.VERSION.SDK_INT >= 24 /* Android 7.0 (N) */) {
|
||||
AudioManager audioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
|
||||
return Arrays.stream(audioManager.getDevices(AudioManager.GET_DEVICES_INPUTS))
|
||||
.filter(deviceInfo -> deviceInfo.getId() == deviceId)
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static AudioDeviceInfo getOutputAudioDeviceInfo(int deviceId) {
|
||||
if (Build.VERSION.SDK_INT >= 24 /* Android 7.0 (N) */) {
|
||||
AudioManager audioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
|
||||
return Arrays.stream(audioManager.getDevices(AudioManager.GET_DEVICES_OUTPUTS))
|
||||
.filter(deviceInfo -> deviceInfo.getId() == deviceId)
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static void registerAudioDeviceCallback() {
|
||||
if (Build.VERSION.SDK_INT >= 24 /* Android 7.0 (N) */) {
|
||||
AudioManager audioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
|
||||
audioManager.registerAudioDeviceCallback(mAudioDeviceCallback, null);
|
||||
}
|
||||
}
|
||||
|
||||
private static void unregisterAudioDeviceCallback(Context context) {
|
||||
if (Build.VERSION.SDK_INT >= 24 /* Android 7.0 (N) */) {
|
||||
AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
|
||||
audioManager.unregisterAudioDeviceCallback(mAudioDeviceCallback);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called by SDL using JNI.
|
||||
*/
|
||||
public static int[] audioOpen(int sampleRate, int audioFormat, int desiredChannels, int desiredFrames) {
|
||||
return open(false, sampleRate, audioFormat, desiredChannels, desiredFrames);
|
||||
public static int[] getAudioOutputDevices() {
|
||||
if (Build.VERSION.SDK_INT >= 24 /* Android 7.0 (N) */) {
|
||||
AudioManager audioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
|
||||
return Arrays.stream(audioManager.getDevices(AudioManager.GET_DEVICES_OUTPUTS)).mapToInt(AudioDeviceInfo::getId).toArray();
|
||||
} else {
|
||||
return NO_DEVICES;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called by SDL using JNI.
|
||||
*/
|
||||
public static int[] getAudioInputDevices() {
|
||||
if (Build.VERSION.SDK_INT >= 24 /* Android 7.0 (N) */) {
|
||||
AudioManager audioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
|
||||
return Arrays.stream(audioManager.getDevices(AudioManager.GET_DEVICES_INPUTS)).mapToInt(AudioDeviceInfo::getId).toArray();
|
||||
} else {
|
||||
return NO_DEVICES;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called by SDL using JNI.
|
||||
*/
|
||||
public static int[] audioOpen(int sampleRate, int audioFormat, int desiredChannels, int desiredFrames, int deviceId) {
|
||||
return open(false, sampleRate, audioFormat, desiredChannels, desiredFrames, deviceId);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -254,6 +360,11 @@ public class SDLAudioManager
|
||||
return;
|
||||
}
|
||||
|
||||
if (android.os.Build.VERSION.SDK_INT < 21 /* Android 5.0 (LOLLIPOP) */) {
|
||||
Log.e(TAG, "Attempted to make an incompatible audio call with uninitialized audio! (floating-point output is supported since Android 5.0 Lollipop)");
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < buffer.length;) {
|
||||
int result = mAudioTrack.write(buffer, i, buffer.length - i, AudioTrack.WRITE_BLOCKING);
|
||||
if (result > 0) {
|
||||
@@ -326,18 +437,22 @@ public class SDLAudioManager
|
||||
/**
|
||||
* This method is called by SDL using JNI.
|
||||
*/
|
||||
public static int[] captureOpen(int sampleRate, int audioFormat, int desiredChannels, int desiredFrames) {
|
||||
return open(true, sampleRate, audioFormat, desiredChannels, desiredFrames);
|
||||
public static int[] captureOpen(int sampleRate, int audioFormat, int desiredChannels, int desiredFrames, int deviceId) {
|
||||
return open(true, sampleRate, audioFormat, desiredChannels, desiredFrames, deviceId);
|
||||
}
|
||||
|
||||
/** This method is called by SDL using JNI. */
|
||||
public static int captureReadFloatBuffer(float[] buffer, boolean blocking) {
|
||||
return mAudioRecord.read(buffer, 0, buffer.length, blocking ? AudioRecord.READ_BLOCKING : AudioRecord.READ_NON_BLOCKING);
|
||||
if (Build.VERSION.SDK_INT < 23 /* Android 6.0 (M) */) {
|
||||
return 0;
|
||||
} else {
|
||||
return mAudioRecord.read(buffer, 0, buffer.length, blocking ? AudioRecord.READ_BLOCKING : AudioRecord.READ_NON_BLOCKING);
|
||||
}
|
||||
}
|
||||
|
||||
/** This method is called by SDL using JNI. */
|
||||
public static int captureReadShortBuffer(short[] buffer, boolean blocking) {
|
||||
if (Build.VERSION.SDK_INT < 23) {
|
||||
if (Build.VERSION.SDK_INT < 23 /* Android 6.0 (M) */) {
|
||||
return mAudioRecord.read(buffer, 0, buffer.length);
|
||||
} else {
|
||||
return mAudioRecord.read(buffer, 0, buffer.length, blocking ? AudioRecord.READ_BLOCKING : AudioRecord.READ_NON_BLOCKING);
|
||||
@@ -346,7 +461,7 @@ public class SDLAudioManager
|
||||
|
||||
/** This method is called by SDL using JNI. */
|
||||
public static int captureReadByteBuffer(byte[] buffer, boolean blocking) {
|
||||
if (Build.VERSION.SDK_INT < 23) {
|
||||
if (Build.VERSION.SDK_INT < 23 /* Android 6.0 (M) */) {
|
||||
return mAudioRecord.read(buffer, 0, buffer.length);
|
||||
} else {
|
||||
return mAudioRecord.read(buffer, 0, buffer.length, blocking ? AudioRecord.READ_BLOCKING : AudioRecord.READ_NON_BLOCKING);
|
||||
@@ -391,4 +506,9 @@ public class SDLAudioManager
|
||||
}
|
||||
|
||||
public static native int nativeSetupJNI();
|
||||
|
||||
public static native void removeAudioDevice(boolean isCapture, int deviceId);
|
||||
|
||||
public static native void addAudioDevice(boolean isCapture, int deviceId);
|
||||
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ public class SDLControllerManager
|
||||
public static native int nativeAddJoystick(int device_id, String name, String desc,
|
||||
int vendor_id, int product_id,
|
||||
boolean is_accelerometer, int button_mask,
|
||||
int naxes, int nhats, int nballs);
|
||||
int naxes, int axis_mask, int nhats, int nballs);
|
||||
public static native int nativeRemoveJoystick(int device_id);
|
||||
public static native int nativeAddHaptic(int device_id, String name);
|
||||
public static native int nativeRemoveHaptic(int device_id);
|
||||
@@ -42,7 +42,7 @@ public class SDLControllerManager
|
||||
|
||||
public static void initialize() {
|
||||
if (mJoystickHandler == null) {
|
||||
if (Build.VERSION.SDK_INT >= 19) {
|
||||
if (Build.VERSION.SDK_INT >= 19 /* Android 4.4 (KITKAT) */) {
|
||||
mJoystickHandler = new SDLJoystickHandler_API19();
|
||||
} else {
|
||||
mJoystickHandler = new SDLJoystickHandler_API16();
|
||||
@@ -50,7 +50,7 @@ public class SDLControllerManager
|
||||
}
|
||||
|
||||
if (mHapticHandler == null) {
|
||||
if (Build.VERSION.SDK_INT >= 26) {
|
||||
if (Build.VERSION.SDK_INT >= 26 /* Android 8.0 (O) */) {
|
||||
mHapticHandler = new SDLHapticHandler_API26();
|
||||
} else {
|
||||
mHapticHandler = new SDLHapticHandler();
|
||||
@@ -168,6 +168,32 @@ class SDLJoystickHandler_API16 extends SDLJoystickHandler {
|
||||
arg1Axis = MotionEvent.AXIS_GAS;
|
||||
}
|
||||
|
||||
// Make sure the AXIS_Z is sorted between AXIS_RY and AXIS_RZ.
|
||||
// This is because the usual pairing are:
|
||||
// - AXIS_X + AXIS_Y (left stick).
|
||||
// - AXIS_RX, AXIS_RY (sometimes the right stick, sometimes triggers).
|
||||
// - AXIS_Z, AXIS_RZ (sometimes the right stick, sometimes triggers).
|
||||
// This sorts the axes in the above order, which tends to be correct
|
||||
// for Xbox-ish game pads that have the right stick on RX/RY and the
|
||||
// triggers on Z/RZ.
|
||||
//
|
||||
// Gamepads that don't have AXIS_Z/AXIS_RZ but use
|
||||
// AXIS_LTRIGGER/AXIS_RTRIGGER are unaffected by this.
|
||||
//
|
||||
// References:
|
||||
// - https://developer.android.com/develop/ui/views/touch-and-input/game-controllers/controller-input
|
||||
// - https://www.kernel.org/doc/html/latest/input/gamepad.html
|
||||
if (arg0Axis == MotionEvent.AXIS_Z) {
|
||||
arg0Axis = MotionEvent.AXIS_RZ - 1;
|
||||
} else if (arg0Axis > MotionEvent.AXIS_Z && arg0Axis < MotionEvent.AXIS_RZ) {
|
||||
--arg0Axis;
|
||||
}
|
||||
if (arg1Axis == MotionEvent.AXIS_Z) {
|
||||
arg1Axis = MotionEvent.AXIS_RZ - 1;
|
||||
} else if (arg1Axis > MotionEvent.AXIS_Z && arg1Axis < MotionEvent.AXIS_RZ) {
|
||||
--arg1Axis;
|
||||
}
|
||||
|
||||
return arg0Axis - arg1Axis;
|
||||
}
|
||||
}
|
||||
@@ -210,7 +236,7 @@ class SDLJoystickHandler_API16 extends SDLJoystickHandler {
|
||||
mJoysticks.add(joystick);
|
||||
SDLControllerManager.nativeAddJoystick(joystick.device_id, joystick.name, joystick.desc,
|
||||
getVendorId(joystickDevice), getProductId(joystickDevice), false,
|
||||
getButtonMask(joystickDevice), joystick.axes.size(), joystick.hats.size()/2, 0);
|
||||
getButtonMask(joystickDevice), joystick.axes.size(), getAxisMask(joystick.axes), joystick.hats.size()/2, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -291,6 +317,9 @@ class SDLJoystickHandler_API16 extends SDLJoystickHandler {
|
||||
public int getVendorId(InputDevice joystickDevice) {
|
||||
return 0;
|
||||
}
|
||||
public int getAxisMask(List<InputDevice.MotionRange> ranges) {
|
||||
return -1;
|
||||
}
|
||||
public int getButtonMask(InputDevice joystickDevice) {
|
||||
return -1;
|
||||
}
|
||||
@@ -308,6 +337,43 @@ class SDLJoystickHandler_API19 extends SDLJoystickHandler_API16 {
|
||||
return joystickDevice.getVendorId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAxisMask(List<InputDevice.MotionRange> ranges) {
|
||||
// For compatibility, keep computing the axis mask like before,
|
||||
// only really distinguishing 2, 4 and 6 axes.
|
||||
int axis_mask = 0;
|
||||
if (ranges.size() >= 2) {
|
||||
// ((1 << SDL_GAMEPAD_AXIS_LEFTX) | (1 << SDL_GAMEPAD_AXIS_LEFTY))
|
||||
axis_mask |= 0x0003;
|
||||
}
|
||||
if (ranges.size() >= 4) {
|
||||
// ((1 << SDL_GAMEPAD_AXIS_RIGHTX) | (1 << SDL_GAMEPAD_AXIS_RIGHTY))
|
||||
axis_mask |= 0x000c;
|
||||
}
|
||||
if (ranges.size() >= 6) {
|
||||
// ((1 << SDL_GAMEPAD_AXIS_LEFT_TRIGGER) | (1 << SDL_GAMEPAD_AXIS_RIGHT_TRIGGER))
|
||||
axis_mask |= 0x0030;
|
||||
}
|
||||
// Also add an indicator bit for whether the sorting order has changed.
|
||||
// This serves to disable outdated gamecontrollerdb.txt mappings.
|
||||
boolean have_z = false;
|
||||
boolean have_past_z_before_rz = false;
|
||||
for (InputDevice.MotionRange range : ranges) {
|
||||
int axis = range.getAxis();
|
||||
if (axis == MotionEvent.AXIS_Z) {
|
||||
have_z = true;
|
||||
} else if (axis > MotionEvent.AXIS_Z && axis < MotionEvent.AXIS_RZ) {
|
||||
have_past_z_before_rz = true;
|
||||
}
|
||||
}
|
||||
if (have_z && have_past_z_before_rz) {
|
||||
// If both these exist, the compare() function changed sorting order.
|
||||
// Set a bit to indicate this fact.
|
||||
axis_mask |= 0x8000;
|
||||
}
|
||||
return axis_mask;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getButtonMask(InputDevice joystickDevice) {
|
||||
int button_mask = 0;
|
||||
@@ -480,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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -743,7 +811,7 @@ class SDLGenericMotionListener_API26 extends SDLGenericMotionListener_API24 {
|
||||
|
||||
@Override
|
||||
public boolean supportsRelativeMouse() {
|
||||
return (!SDLActivity.isDeXMode() || (Build.VERSION.SDK_INT >= 27));
|
||||
return (!SDLActivity.isDeXMode() || Build.VERSION.SDK_INT >= 27 /* Android 8.1 (O_MR1) */);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -753,7 +821,7 @@ class SDLGenericMotionListener_API26 extends SDLGenericMotionListener_API24 {
|
||||
|
||||
@Override
|
||||
public boolean setRelativeMouseEnabled(boolean enabled) {
|
||||
if (!SDLActivity.isDeXMode() || (Build.VERSION.SDK_INT >= 27)) {
|
||||
if (!SDLActivity.isDeXMode() || Build.VERSION.SDK_INT >= 27 /* Android 8.1 (O_MR1) */) {
|
||||
if (enabled) {
|
||||
SDLActivity.getContentView().requestPointerCapture();
|
||||
} else {
|
||||
|
||||
@@ -116,7 +116,7 @@ public class SDLSurface extends SurfaceView implements SurfaceHolder.Callback,
|
||||
int nDeviceHeight = height;
|
||||
try
|
||||
{
|
||||
if (Build.VERSION.SDK_INT >= 17) {
|
||||
if (Build.VERSION.SDK_INT >= 17 /* Android 4.2 (JELLY_BEAN_MR1) */) {
|
||||
DisplayMetrics realMetrics = new DisplayMetrics();
|
||||
mDisplay.getRealMetrics( realMetrics );
|
||||
nDeviceWidth = realMetrics.widthPixels;
|
||||
@@ -163,7 +163,7 @@ public class SDLSurface extends SurfaceView implements SurfaceHolder.Callback,
|
||||
|
||||
// Don't skip in MultiWindow.
|
||||
if (skip) {
|
||||
if (Build.VERSION.SDK_INT >= 24) {
|
||||
if (Build.VERSION.SDK_INT >= 24 /* Android 7.0 (N) */) {
|
||||
if (SDLActivity.mSingleton.isInMultiWindowMode()) {
|
||||
Log.v("SDL", "Don't skip in Multi-Window");
|
||||
skip = false;
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:orientation="horizontal"
|
||||
android:padding="16dp"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<ProgressBar
|
||||
android:layout_marginEnd="8dp"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/text"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:textSize="16sp"/>
|
||||
</LinearLayout>
|
||||
@@ -1,8 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
|
||||
<!-- Base application theme. -->
|
||||
<style name="AppTheme" parent="android:Theme.Holo.Light.DarkActionBar">
|
||||
<style name="AppTheme" parent="android:Theme.NoTitleBar.Fullscreen">
|
||||
<!-- Customize your theme here. -->
|
||||
</style>
|
||||
|
||||
</resources>
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
||||
|
||||
buildscript {
|
||||
ext.kotlin_version = '1.6.20'
|
||||
ext.kotlin_version = '1.7.21'
|
||||
repositories {
|
||||
mavenCentral()
|
||||
google()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:7.3.1'
|
||||
classpath 'com.android.tools.build:gradle:8.1.1'
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||
|
||||
// NOTE: Do not place your application dependencies here; they belong
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
#Thu Nov 11 18:20:34 PST 2021
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.1.1-bin.zip
|
||||
distributionPath=wrapper/dists
|
||||
zipStorePath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
|
||||
Vendored
+2
-2
@@ -126,8 +126,8 @@ if $cygwin ; then
|
||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||
i=0
|
||||
for arg in "$@" ; do
|
||||
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
||||
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
||||
CHECK=`echo "$arg"|grep -E -c "$OURCYGPATTERN" -`
|
||||
CHECK2=`echo "$arg"|grep -E -c "^-"` ### Determine if an option
|
||||
|
||||
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
||||
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
||||
|
||||
+2
-15
@@ -1,33 +1,20 @@
|
||||
#cmakedefine PACKAGE "@PACKAGE@"
|
||||
#define VERSION "2.7.0"
|
||||
|
||||
#cmakedefine CMAKE_SYSTEM_NAME "@CMAKE_SYSTEM_NAME@"
|
||||
#define VERSION "@XSYSTEM35_VERSION@"
|
||||
|
||||
#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@
|
||||
#cmakedefine ENABLE_MIDI_SDLMIXER @ENABLE_MIDI_SDLMIXER@
|
||||
#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@"
|
||||
|
||||
#cmakedefine HAVE_GETLOGIN @HAVE_GETLOGIN@
|
||||
#cmakedefine HAVE_MMAP @HAVE_MMAP@
|
||||
#cmakedefine HAVE_SIGACTION @HAVE_SIGACTION@
|
||||
#cmakedefine HAVE_UNAME @HAVE_UNAME@
|
||||
#cmakedefine HAVE_WEBP @HAVE_WEBP@
|
||||
|
||||
#define DEFAULT_GOTHIC_TTF "@DEFAULT_FONT_PATH@MTLc3m.ttf"
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
set(SOURCES
|
||||
xsystem35.6.adoc
|
||||
xsystem35.gr.5.adoc
|
||||
)
|
||||
|
||||
find_program(ASCIIDOCTOR asciidoctor)
|
||||
if (NOT ASCIIDOCTOR)
|
||||
message(WARNING "asciidoctor not found, manpages will not be generated")
|
||||
else()
|
||||
if (WIN32)
|
||||
set(BACKEND html)
|
||||
else()
|
||||
set(BACKEND manpage)
|
||||
include(GNUInstallDirs)
|
||||
endif()
|
||||
|
||||
set(MANUALS "")
|
||||
foreach(SRC ${SOURCES})
|
||||
string(REGEX MATCH "^(.*)\\.([0-9])\\.adoc$" _ ${SRC})
|
||||
set(NAME ${CMAKE_MATCH_1})
|
||||
set(SECTION ${CMAKE_MATCH_2})
|
||||
if (WIN32)
|
||||
set(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${NAME}.html)
|
||||
else()
|
||||
set(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${NAME}.${SECTION})
|
||||
install(FILES ${OUTPUT} DESTINATION ${CMAKE_INSTALL_MANDIR}/man${SECTION})
|
||||
endif()
|
||||
add_custom_command(
|
||||
OUTPUT ${OUTPUT}
|
||||
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${SRC}
|
||||
COMMAND ${ASCIIDOCTOR}
|
||||
--attribute xsystem35-version=${XSYSTEM35_VERSION}
|
||||
--backend ${BACKEND}
|
||||
--out-file ${OUTPUT}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/${SRC}
|
||||
)
|
||||
list(APPEND MANUALS ${OUTPUT})
|
||||
endforeach()
|
||||
|
||||
add_custom_target(manual ALL DEPENDS ${MANUALS})
|
||||
endif()
|
||||
|
||||
@@ -1,80 +0,0 @@
|
||||
ゲームリソースファイル(*.gr)の書き方
|
||||
|
||||
|
||||
xsystem35ではゲームデータの置き場所をテキストファイルに保存しておき、
|
||||
それをxsystem35に指定してやる事でデータの置き場所を知らせます。
|
||||
|
||||
# このファイルのファイル名はxsystem35を起動する時に指定できますので、hoge.gr
|
||||
# である必要は無く、自由につける事が出来ます。
|
||||
|
||||
ここでは、このテキストファイル(ゲームリソースファイル)の書式を説明します。
|
||||
|
||||
|
||||
1つのデータにつき1行で記述します。例を見て下さい。
|
||||
|
||||
ScenarioA /home/chikama/game/rance4/rance4_sa.ald
|
||||
|
||||
キーワード データのフルパス
|
||||
|
||||
の順に書きます。キーワードは行の先頭から書き、データのフルパスとの間は半角
|
||||
スペースです。(セーブデータのみ、ホームディレクトリを表す ~ を評価します。)
|
||||
|
||||
キーワードには次の7つがあります。
|
||||
|
||||
Scenario : シナリオ
|
||||
Graphics : グラフィック
|
||||
Wave : PCMデータ
|
||||
Midi : MIDIデータ
|
||||
Data : その他データ
|
||||
Save : セーブデータ
|
||||
Resource : リソースファイル(マウスカーソル形状)
|
||||
Ain : DLL とその関数の情報のかかれた System39.ain
|
||||
BGM : BGMデータ(エスカレイヤー以降のBGMデータファイル)
|
||||
WAI : PCMデータの追加情報 (mixer channel 情報等)
|
||||
BGI : BGMデータの追加情報 (ループ位置等)
|
||||
SACT01 : SACT.DLL用データ (SACTEFAM.KLD)
|
||||
ALK : デモ用アーカイブファイル
|
||||
Init : System39.ini
|
||||
|
||||
同じ種類のデータが複数ある場合はキーワードの次にA,B,C...をつけます。
|
||||
(Ain を除く)
|
||||
|
||||
CD-ROM上のどれがどの種類のファイルかは、ファイル名で判別します。
|
||||
*SA.ALD ならシナリオの1番目、*GA.ALDはグラフィック、*WA.ALDはPCM、
|
||||
*MA.ALD はMIDI、*DA.ALDはその他データです。
|
||||
|
||||
Ain は System39.ain へのパスを書きます。例えば
|
||||
Ain /home/chikama/game/20cKaeru/System39.ain
|
||||
のように書きます。
|
||||
|
||||
Init は System39.ini へのパスを書きます。例えば
|
||||
Init /home/chikama/game/esuka/System39.ini
|
||||
のように書きます。
|
||||
|
||||
WAI/BGI は通常1ファイルだけですので
|
||||
WAIA /home/chikama/game/esuka/DOKI_WA.WAI
|
||||
BGIA /home/chikama/game/esuka/DOKI_BA.BGI
|
||||
のように書きます。
|
||||
|
||||
SACT01 は SACTシステム固有のデータファイル(SACTEFAM.KLD)へのパスを
|
||||
指定します。
|
||||
SACT01 /home/chikama/game/rance5d/SACTEFAM.KLD
|
||||
|
||||
ALK はデモ用のデータが入ったアーカイブファイルです。
|
||||
ALK01 /home/chikama/game/nd/NightDemonDemo1.alk
|
||||
ALK02 /home/chikama/game/nd/NightDemonDemo2.alk
|
||||
ALK03 /home/chikama/game/nd/NightDemonDemo3.alk
|
||||
のように書きます。
|
||||
|
||||
|
||||
また、これらの範疇にはいらないデータ、たとえば、かえるにょぱにょんの
|
||||
floor_1.mapなどはリソースファイルを介しませんので、ゲームリソース
|
||||
ファイルには書かず、「セーブデータを置いたディレクトリと同じ場所」に
|
||||
コピーして下さい。
|
||||
|
||||
また、Save? のみ、'~' (ホームディレクトリ)を評価しますので、
|
||||
SaveA ~/savedata/kichiku/kichiku_sa.ald
|
||||
のように書く事が出来ます。
|
||||
|
||||
コメントを書く場合は行頭に # をつけます。また空白行は無視されます。
|
||||
|
||||
-314
@@ -1,314 +0,0 @@
|
||||
|
||||
System 3.5 for X Window System Version 1.7 (開発版)
|
||||
|
||||
0. 目次
|
||||
|
||||
1. はじめに
|
||||
2. 開発環境と動作確認環境
|
||||
2.a. 開発環境
|
||||
2.b. 動作確認環境
|
||||
2.c. 多分動くと思われる環境
|
||||
3. xystem35の設定ファイル
|
||||
4. ゲームの実行と終了
|
||||
4.a. ゲームの実行
|
||||
4.b. ゲームの終了
|
||||
4.c. xsystem35メニュー
|
||||
4.d. キーボード操作
|
||||
5. コマンドラインオプション
|
||||
6. その他情報
|
||||
6.a. SYSV IPC
|
||||
6.b. SharedMemoryの大きさについて
|
||||
6.c. locale と X
|
||||
7. 著作権とライセンス
|
||||
8. サポート
|
||||
|
||||
|
||||
1. はじめに
|
||||
|
||||
このソフトは AliceSoft の Syetem3.5/3.6/3.8/3.9 上で動くゲームを
|
||||
X Window System 上で動かすためのプログラムです。
|
||||
|
||||
* 動作確認ゲーム
|
||||
|
||||
鬼畜王ランス
|
||||
ランス4 (for Win95)
|
||||
闘神都市II (for Win95)
|
||||
夢幻泡影 (for Win95)
|
||||
かえるにょぱにょ〜ん (初版、廉価版)
|
||||
いけないかつみ先生
|
||||
戦巫女 (初版、廉価版)
|
||||
零式 (館456版、廉価版)
|
||||
ATLACH=NACHA (館456版、廉価版)
|
||||
人間狩り
|
||||
王道勇者
|
||||
ディアボリカ (初版、廉価版)
|
||||
AmbivalenZ(for Win95)
|
||||
ぱすてるチャイム
|
||||
ぷろすちゅーでんとGood
|
||||
守り神様
|
||||
ママトト
|
||||
|
||||
アリスの館456
|
||||
DALK
|
||||
闘神都市
|
||||
DrStop!
|
||||
ランス1
|
||||
ランス2
|
||||
ランス3
|
||||
|
||||
アリスCD Ver 1.02
|
||||
メイドのすすめ
|
||||
ぶろぶろ
|
||||
学園漂流戦記
|
||||
|
||||
Hushaby Baby
|
||||
Darcrows
|
||||
PERSIOM
|
||||
隠れ月
|
||||
SeeIn青
|
||||
|
||||
20世紀アリス
|
||||
これDPS?
|
||||
かえるにょ国にょアリス
|
||||
|
||||
アリスCD Ver 2.02
|
||||
扉
|
||||
妖精
|
||||
|
||||
OnlyYou リ・クルス
|
||||
王子さま Lv1.5
|
||||
|
||||
* 動かないゲーム
|
||||
|
||||
夜が来る!
|
||||
王子さま Lv1
|
||||
DALK外伝 (System4)
|
||||
ままにょにょ (System4)
|
||||
|
||||
* 一部動作可能
|
||||
|
||||
大悪司 (オープニング不可)
|
||||
妻みぐい (オープニング不可)
|
||||
エスカレイヤー (オープニング不可)
|
||||
Rance5D
|
||||
妻みぐい2 (オープニング不可)
|
||||
シェル・クレイル
|
||||
NightDemon (オープニング不可)
|
||||
|
||||
|
||||
各ゲームについての補足事項は doc/GAMES.TXT を御覧ください。
|
||||
|
||||
また、ネット上で公開されているSYSTEM3.5用のゲームのうち、いくつかは
|
||||
動作が確認されています。くわしくは MISCGAME.TXT を御覧下さい。
|
||||
|
||||
|
||||
2. 開発環境と動作確認環境
|
||||
|
||||
2.a. 開発環境
|
||||
|
||||
Kondara-1.2 (Linux/i386)
|
||||
|
||||
2.b. 動作確認環境
|
||||
|
||||
DigitalUnix 4.0F (alpha)
|
||||
SunOS 5.8 (sparc)
|
||||
|
||||
2.c. 多分動くと思われる環境
|
||||
|
||||
Linux(!i386)
|
||||
FreeBSD/NetBSD/OpenBSD (i386 etc)
|
||||
Irix 6.X
|
||||
Solaris 2.X 以降 (sparc/i386)
|
||||
|
||||
|
||||
3. xystem35の設定ファイル
|
||||
|
||||
xsystem35ではフォントの設定などを、カレントディレクトリとホームディレクトリに
|
||||
ある .xsys35rcというファイルから読み込みます。カレントディレクトリの .xsys35rc
|
||||
に書かれた設定のほうが優先されるため、一般的な設定はホームディレクトリの
|
||||
.xsys35rcに書き、特定のゲームで書き換えたい項目はゲームを置いたディレクトリの
|
||||
.xsys35rcに書くといいでしょう。
|
||||
|
||||
サンプルとなるファイルを xsys35rc.sample として用意しました。
|
||||
|
||||
また、gtk widgetのリソースは ~/.gtk/gtkrc または ~/.gtkrc から読み込みます。
|
||||
読み込み先は .xsys35rc で指定できます。
|
||||
|
||||
ゲームで使用するフォントは X のフォントの仕組を使う方法と、TrueTypeFontを
|
||||
外部ライブラリを使って直接表示する方法の2種類が選べます。
|
||||
|
||||
~/.xsys35rc の ttfont_mincho: と ttfont_gothic: の場所にフォントファイルを
|
||||
指定し、font_device: ttf と指定してください。詳しくはサンプルファイル
|
||||
(xsys35rc.sample)を見て下さい。
|
||||
|
||||
|
||||
4. ゲームの実行と終了
|
||||
|
||||
4.a. ゲームの実行
|
||||
|
||||
instgameを使ってゲームデータをインストールすると、インストールした
|
||||
ディレクトリにの一つ上に ???????.gr というファイル(ゲームリソースファイル)
|
||||
が自動的に作成されますので
|
||||
|
||||
% xsystem35 -gamefile ~/game/???????.gr
|
||||
|
||||
のように実行します。-gamefile オプションをつけない場合は、カレントディレク
|
||||
トリの xsystem35.gr を参照します。
|
||||
|
||||
またいずれも見つからない場合は、カレントディレクトリにあるファイルをゲーム
|
||||
データとして設定します。例えば testSA.ALD というファイルがカレントディレク
|
||||
トリにあると、それをシナリオデータとして使います。またセーブデータは適当な
|
||||
名前で 10個確保されます。
|
||||
|
||||
ゲームリソースファイルの書き方については、doc/GRFMT.TXT を御覧下さい。
|
||||
|
||||
4.b. ゲームの終了
|
||||
|
||||
* 起動した端末で Ctrl+C を押すと、すぐに終了します。
|
||||
|
||||
* ゲーム中にマウスの真中のボタンを押すと、メニューが出て来ますので、
|
||||
そこから 'Exit' を選んで終了させて下さい。Window Manager のCloseボタンでも
|
||||
同じように動作します。
|
||||
|
||||
* ESC + SPACE + RET キーを同時に押すと、すぐに終了します。
|
||||
|
||||
4.c. xsystem35メニュー
|
||||
|
||||
ゲーム中にマウスの真中ボタンを押すとメニューが出て来ます。
|
||||
|
||||
メッセージスキップ(MessageSkip):
|
||||
次の選択肢までメッセージを飛ばします。マウスの右クリックで
|
||||
止まります。シナリオによっては停止しない場合もあります。
|
||||
|
||||
マウスカーソル移動(MouseAutoMove):
|
||||
選択ウィンドなどでマウスが自動的に移動するのを制御します。
|
||||
|
||||
ボリュームバランス(VolumeValance):
|
||||
SACTシステムで音声の人物毎に音量を変えることができます。
|
||||
(ゲームがそう出来るように対応している場合のみ)
|
||||
|
||||
情報(About):
|
||||
このゲームについて。
|
||||
|
||||
終了(Exit):
|
||||
ゲームを終了します。
|
||||
|
||||
4.d. キーボード操作
|
||||
|
||||
アリスソフトのゲームは有史来、基本的に上下左右キーに SPACE, RET, ESC, TAB
|
||||
キーしか使いません(一部のゲームはそれ以外のキーを使うこともあります)。
|
||||
XSystem35 では次のキー割当を特別に使っています。
|
||||
|
||||
F1: メッセージスキップ
|
||||
F4: フルスクリーン <-> Window表示の切替え
|
||||
|
||||
また、旧き良き時代の DOS への復帰キー (ESC + SPACE + RET) でゲームを確認なし
|
||||
で終了出来ます。
|
||||
|
||||
|
||||
5. コマンドラインオプション
|
||||
|
||||
-h : ヘルプを表示します。
|
||||
|
||||
-gamefile file : ゲームリソースファイルを file から読み込みます。
|
||||
|
||||
-no-shm : ネットワーク越しに起動する場合に指定します。
|
||||
|
||||
-devcd name : CD-ROM device名を name にします。
|
||||
-devmidi name : MIDI device名を name にします。
|
||||
|
||||
-M? : MIDI の出力の種類を選択します。
|
||||
-Me : External midi player (default)
|
||||
-Mr : Raw Midi device
|
||||
-Ms? : Sequencer device (?:device number)
|
||||
-M0 : disable midi
|
||||
|
||||
-devjoy n : n 番目の joystick のデバイスを使用します。
|
||||
|
||||
-version : バージョン情報を表示します。
|
||||
|
||||
-fullscreen : フルスクリーンでゲームを実行します。
|
||||
SDL 有効時には Widget にフォーカスが当たらないため Popup
|
||||
menu 等が使用できません。
|
||||
|
||||
-antialias : 常に文字にアンチエリアスをかけます。
|
||||
|
||||
-noantialias : 常に文字にアンチエリアスをかけません。シナリオ上でアンチ
|
||||
エリアスの指定があっても無視します。
|
||||
|
||||
-devfont : フォントデバイスを指定します。x11/ft2/sdl のいずれかが
|
||||
使えます。
|
||||
|
||||
-noimagecursor : リソースファイルによるカーソル形状の変更(Darcrows等)を無効
|
||||
にしたい場合に指定します。
|
||||
|
||||
|
||||
6. その他情報
|
||||
|
||||
6.a. SYSV IPC
|
||||
|
||||
カーネルに SYSV IPC (SharedMemory/MessageQueue/Semaphore)の機能が
|
||||
組み込まれている必要があります。
|
||||
|
||||
6.b. SharedMemoryの大きさについて
|
||||
|
||||
カーネルのSharedMemoryの大きさが十分大きい場合、MIT-SHMを利用して画面を
|
||||
高速に描画する事が出来ます。起動時にエラーが出る場合、カーネルパラメータを
|
||||
変更してみて下さい。(BSD 系はデフォルトの SharedMemory の大きさが小さい
|
||||
ようです)
|
||||
|
||||
6.b.1. FreeBSDの場合 /usr/src/sys/i386/conf/LINT 中の
|
||||
|
||||
options SHMALL=1025
|
||||
options "SHMMAX=(SHMMAXPGS*PAGE_SIZE+1)"
|
||||
options SHMMAXPGS=1025
|
||||
options SHMMIN=2
|
||||
options SHMMNI=33
|
||||
options SHMSEG=9
|
||||
「SHMMAXPGS」が関連項目です。
|
||||
|
||||
24bppで起動する場合は SHMMAXPGS=4096 くらいにするとよいようです。
|
||||
もちろん設定後はカーネルの再構築が必要です。
|
||||
|
||||
6.c. locale と X
|
||||
|
||||
libc に locale 機構が組み込まれていない環境の場合、libxpg4 などの
|
||||
ライブラリ(FreeBSD) や X の locale を使うことになります。
|
||||
|
||||
linux の libc5 な環境では configure 時に --with-locale=ja_JP.ujis として
|
||||
コンパイルしてください。
|
||||
|
||||
それ以外のほとんどの環境では考慮する必要はないでしょう。
|
||||
|
||||
|
||||
7. 著作権とライセンス
|
||||
|
||||
プログラムの著作権は作者(chikama)に属しますが、ソースコードはGPLに基づいて
|
||||
再配付できます。
|
||||
(一部のソースコードは私以外に著作権があります。詳しくは、ソースコードを御覧
|
||||
下さい)
|
||||
|
||||
ゲーム内で使われてるカーソルフォントの一部をqvwm(Windows95そっくりのWindow
|
||||
Manager)からいただきました。
|
||||
|
||||
|
||||
8. サポート
|
||||
|
||||
動作報告・バグ報告などは以下のメールアドレスまでお願いします。
|
||||
|
||||
E-Mail: chikama@nabal.aist-nara.ac.jp (private)
|
||||
masaki-c@is.aist-nara.ac.jp (official)
|
||||
|
||||
また最新版は以下のURLからダウンロードできます。
|
||||
|
||||
http://www.aist-nara.ac.jp/~masaki-c/private/unitbase/xsys35/index.html
|
||||
|
||||
バグレポートの際は、お使いの環境を出来るだけくわしく書いて下さい。
|
||||
また特定のゲームで動かない場合は、出来るだけセーブデータも添付して下さい。
|
||||
|
||||
プログラムやシナリオデータのバグで 'sigsegv caught @xxx,xxxxx' といって
|
||||
終了する場合は、そのメッセージの部分(xxx,xxxx)も送って下さい。
|
||||
|
||||
可能ならば、./configure で --enable-debug を付けてコンパイルしておき、
|
||||
デバッガ上で実行して segmentation fault で止まった時に、bt と打って出てくる
|
||||
メッセージを添付していただけるととても助かります。
|
||||
@@ -1,307 +0,0 @@
|
||||
|
||||
xsystem35 における音楽環境について
|
||||
|
||||
|
||||
0. もくじ
|
||||
1. MIDIについて
|
||||
a) 外部プレーヤーを使う方法
|
||||
1) xsystem35 側の準備
|
||||
2) プレイヤーの準備
|
||||
3) xsystem35へのリダイレクト
|
||||
4) 制限事項
|
||||
b) 外部 MIDI 音源を /dev/midi 経由で制御する方法
|
||||
1) xsystem35 側の準備
|
||||
2) 外部 MIDI 音源の準備
|
||||
c) Synthesizer 音源を /dev/sequencer 経由で制御する方法
|
||||
1) xsystem35 側の準備
|
||||
2) Synthesizer 音源の準備
|
||||
d) オプション一覧
|
||||
2. 効果音(WAV)について
|
||||
a) OSS 出力
|
||||
b) ALSA 出力
|
||||
c) ESD 出力
|
||||
3. CDオーディオについて
|
||||
a) CD-ROM コントロールによる演奏
|
||||
b) 外部プレイヤ(mp3など)による演奏
|
||||
4. PCM & MIDI(timidity) & CD-ROM(MP3) を1枚のサウンドカードで同時に使う方法
|
||||
|
||||
|
||||
1. MIDIについて
|
||||
|
||||
xsystem35 では MIDI の演奏に外部プレーヤーを使う方法と、サウンドカードの
|
||||
MIDI port を介して接続した外部 MIDI 機器を /dev/midi 経由で制御する方法、
|
||||
さらに、synthesizer device を OSS sequencer (/dev/sequencer) 経由で制御する
|
||||
方法の3種類が選択できます。
|
||||
|
||||
a) 外部プレーヤーを使う方法
|
||||
|
||||
1) xsystem35 側の準備
|
||||
xsystem35 の configure 実行時に --enable-midi=extp を付けてコンパイル
|
||||
しておきます。
|
||||
|
||||
2) プレイヤーの準備
|
||||
TiMidity や playmidi など、お好みのプレーヤーをお使いください。
|
||||
プレイヤーへはあらかじめパスを通しておき、~/.xsys35rc にプレイヤーと
|
||||
プレイヤーへの引数を記述します。
|
||||
|
||||
(例) TiMidity を esd 経由で出力する場合
|
||||
midi_player: timidity -A 100 -s 44100 -Oe
|
||||
|
||||
2a) xsystem35へのリダイレクト (オプション)
|
||||
TiMidity を使っている場合、TiMidity の PCM 出力を xsystem35 へとリダ
|
||||
イレクトして xsystem35 側で管理しているPCM デバイスに流す事が出来ます。
|
||||
~/.xsys35rc の MIDI プレーヤーの設定の際に先頭に '-' をつけて下さい。
|
||||
|
||||
(例)
|
||||
midi_player: -timidity -A 100 -s 44100 -Or -o-
|
||||
|
||||
この場合 timidity の出力は 44.1kHz, Stereo, 16bit 固定です。
|
||||
|
||||
3) 制限事項
|
||||
外部プレイヤーを 使用する場合、MIDIファイルに埋め込まれた system35 用の
|
||||
制御コマンドを実行することができず、リピート再生、ジャンプ再生などが出来
|
||||
ません。このため、ゲームの進行に支障が出ることがあります。
|
||||
|
||||
|
||||
b) 外部 MIDI 音源を /dev/midi 経由で制御する方法
|
||||
|
||||
1) xsystem35 側の準備
|
||||
xsystem35 の configure 実行時に --enable-midi=raw を付けてコンパイル
|
||||
しておきます。
|
||||
|
||||
2) 外部 MIDI 音源の準備
|
||||
外部 MIDI 音源(SC-88など)をサウンドカード の MIDI port を介して接続
|
||||
します。このポートは /dev/midi デバイスを介して制御できる必要があります。
|
||||
ALSA OSS Emulation 上で SB-Live の MIDI 端子に接続した SC-88 での動作を
|
||||
確認しています。
|
||||
|
||||
c) Synthesizer 音源を /dev/sequencer 経由で制御する方法
|
||||
|
||||
1) xsystem35 側の準備
|
||||
xsystem35 の configure 実行時に --enable-midi=seq を付けてコンパイル
|
||||
しておきます。
|
||||
|
||||
2) Synthesizer 音源の準備
|
||||
外部 MIDI 機器を接続するか、サウンドカード上に soundfont を load するか
|
||||
TiMidity を ALSA sequencer server として常駐させておいてください。
|
||||
|
||||
TiMidity を ALSA sequencer server にするには、コンパイル時にその機能を
|
||||
有効にしておき、timidity -iA で常駐させます。
|
||||
|
||||
d) オプション一覧
|
||||
|
||||
MIDI 出力に関する、 .xsys35rc の設定項目(A)とコマンドラインオプション(B)
|
||||
をまとめます。
|
||||
|
||||
1) MIDI プレイヤーの設定
|
||||
(A) ----> midi_player:
|
||||
(B) ----> -midiplayer
|
||||
|
||||
2) MIDI デバイスファイルの設定 (default: /dev/midi or /dev/sequencer)
|
||||
(A) ----> midi_device:
|
||||
(B) ----> -devmidi
|
||||
|
||||
3) MIDI 出力方法の選択 (default: e)
|
||||
(A) ----> midi_output_device: ?
|
||||
(B) ----> -M?
|
||||
|
||||
? .... e : 外部プレーヤ
|
||||
r : midi device 経由
|
||||
sX: sequencer device 経由 (X番目のポート)
|
||||
0 : (ゼロ) 無効化
|
||||
|
||||
コンパイル時に --enable-midi=extp,raw,seq とすることで、複数の方式を有効
|
||||
にし、実行時にいずれかを選択できます。その他のコンパイルオプションは
|
||||
INSTALL ドキュメントを御覧ください。
|
||||
|
||||
sequencer device の X 番目のポートは通常、0 ですが、複数のポートがある
|
||||
場合はそのポート番号を指定してください。ALSA の OSS emu では、
|
||||
$ cat /proc/asound/seq/oss
|
||||
と実行して出て来る
|
||||
midi ?: [xxxx] ALSA port aa:bb
|
||||
の ? の番号を指定します。
|
||||
|
||||
コマンドラインから外部MIDIプレイヤーを指定する場合は
|
||||
-midiplayer "timidity -A 100 -s 44100 -Oe" のようにします。
|
||||
|
||||
|
||||
2. 効果音(WAV)について
|
||||
|
||||
xsystem35ではオーディオインターフェイスとして、Linux/*BSD などで良く使われて
|
||||
いる OSS およびその互換インターフェイスに加えて、ALSA(Advanced Linux Sound
|
||||
Architecture) と ESD(Enligtened Sound Daemon)に対応しています。
|
||||
|
||||
a) OSS 出力
|
||||
|
||||
1) コンパイル
|
||||
configure 時に --enable-audio=oss オプションを付けてコンパイルします。
|
||||
|
||||
2) 実行時オプション
|
||||
コマンドライン: -Oo
|
||||
.xsys35rc : audio_output_device: o
|
||||
|
||||
3) dsp デバイス (default: /dev/dsp)
|
||||
コマンドライン: -devdsp
|
||||
.xsys35rc : dsp_device:
|
||||
|
||||
4) mixer デバイス (default: /dev/mixer)
|
||||
コマンドライン: -devmix
|
||||
.xsys35rc : mixer_device:
|
||||
|
||||
|
||||
b) ALSA 出力
|
||||
|
||||
1) コンパイル
|
||||
configure 時に --enable-audio=alsa オプションを付けてコンパイルします。
|
||||
|
||||
2) 実行時オプション
|
||||
コマンドライン: -Os
|
||||
.xsys35rc : audio_output_device: s
|
||||
|
||||
3) dsp デバイス (default: 0:0)
|
||||
コマンドライン: -devdsp
|
||||
.xsys35rc : dsp_device:
|
||||
|
||||
|
||||
c) ESD 出力
|
||||
|
||||
1) コンパイル
|
||||
configure 時に --enable-audio=esd オプションを付けてコンパイルします。
|
||||
|
||||
2) 実行時オプション
|
||||
コマンドライン: -Oe
|
||||
.xsys35rc : audio_output_device: e
|
||||
|
||||
OSS/ALSA/ESD をすべて有効にしてコンパイルし、実行時にどの出力を使用するか
|
||||
選択できます。configure 時に --enable-audio=oss,alsa,esd としてコンパイル
|
||||
してください。
|
||||
|
||||
|
||||
3. CDオーディオについて
|
||||
|
||||
CD-ROM の制御には Linux/FreeBSD/Irix のインターフェイスに対応しています。
|
||||
また、CD-ROM デバイスを直接制御する他に、外部プレイヤを使って mp3 file など
|
||||
を鳴らすことも出来ます。
|
||||
|
||||
a) CD-ROM コントロールによる演奏
|
||||
環境によって自動的に適切なドライブが選択されコンパイルされます。
|
||||
|
||||
b) 外部プレイヤ(mp3など)による演奏
|
||||
あらかじめ CD を MP3/WAV 化して起きます。また mpg123 などのプレイヤ
|
||||
を用意し、パスを通しておきます。
|
||||
|
||||
1) コンパイル
|
||||
configure 時に --enable-cdrom=mp3 オプションを追加します。CD-ROM
|
||||
コントロールを実行時に使い分けたい時は --enable-cdrom=linux,mp3 などと
|
||||
します。
|
||||
|
||||
3) プレイヤー名とファイルリストを書いた次のようなファイルを用意します。
|
||||
|
||||
% cat /game/kichiku.playlist
|
||||
mpg123-esd -quite
|
||||
/game/kichiku/mp3/trk02.mp3
|
||||
/game/kichiku/mp3/trk03.mp3
|
||||
/game/kichiku/mp3/trk04.mp3
|
||||
/game/kichiku/mp3/trk05.mp3
|
||||
/game/kichiku/mp3/trk06.mp3
|
||||
|
||||
というようなファイルを用意します。
|
||||
1行目はプレーヤーとそのオプション
|
||||
2行目以降はトラック2から順にファイルをならべます。(フルパスで指定します)
|
||||
|
||||
*) 適切に外部プレイヤーと演奏ファイルを用意すれば、データ形式は問いません。
|
||||
|
||||
3a) xsystem35 へのリダイレクト(オプション)
|
||||
|
||||
mpg123 などのプレイヤーのPCM 出力を xsystem35 へとリダイレクトして
|
||||
xsystem35 側で管理しているPCM デバイスに流す事が出来ます。
|
||||
上の kichiku.playlist ファイルのプレイヤの設定で先頭に '-' をつけて
|
||||
ください。
|
||||
|
||||
(例)
|
||||
-mpg123 -q -s
|
||||
|
||||
この場合 mpg123 の出力は 44.1kHz, Stereo, 16bit 固定です。
|
||||
|
||||
4) 実行時オプションに -devcd /game/kichiku.playlist と上で作成したファイル
|
||||
を指定します。
|
||||
|
||||
|
||||
|
||||
CD-ROM に関する .xsys35rc の設定項目(A) と コマンドラインオプション(B) を
|
||||
まとめます。
|
||||
|
||||
1) CD 出力方法の選択
|
||||
(A) ----> cdrom_device: ???
|
||||
(B) ----> -devcd ????
|
||||
|
||||
MP3 出力 => ???? にプレイリストを指定
|
||||
CD-ROM => ???? にデバイスファイルを指定
|
||||
|
||||
2) CD-ROM デバイスファイルの設定 (defult /dev/cdrom)
|
||||
(A) ----> cdrom_device: ???
|
||||
(B) ----> -devcd: ????
|
||||
|
||||
|
||||
4. PCM & MIDI(timidity) & CD-ROM(MP3) を1枚のサウンドカードで同時に使う方法
|
||||
(special thanks to Fumihiko Murata)
|
||||
|
||||
サウンドカードを選ばない方法としては esd を使うことです。esd は対応した複数
|
||||
のプログラムの音の出力を合成してサウンドカードに出力するプログラムです。
|
||||
xsystem35/timidity/mp3 player を esd 対応にコンパイルすることで合成が可能
|
||||
です。
|
||||
|
||||
また、Trident 4DWave DX/NX、SoundBlaster Live/ YAMAHA YMF724以降 などのサウ
|
||||
ンドカードは PCM チャンネルを複数持っていて、対応のサウンドドライバーがあれば
|
||||
PCMとMIDI(SoftwareMIDI)とMP3 を同時に鳴らすことが出来ます。たとえば
|
||||
SoundBlaster Live + ALSA では
|
||||
|
||||
$ cat /proc/asound/pcm
|
||||
00-00: emu10k1 : EMU10K1 : playback 32 : capture 1
|
||||
00-01: emu10k1 mic : EMU10K1 MIC : capture 1
|
||||
00-02: emu10k1 efx : EMU10K1 EFX : capture 1
|
||||
|
||||
のように PCM を 32 チャンネル持っていることが分かります。これは OSS でいうと
|
||||
ころの /dev/dspN に最大 32 の PCM がぶら下がっているように見え、同時に 32 回
|
||||
/dev/dspN を開くことが出来ます。
|
||||
|
||||
また Trident 4DWave DX/NX + ALSA では全部で64chあり、最大で32chを PCM playback
|
||||
に割り当てる事ができます。最大チャンネルはモジュールロード時に 設定され、設定
|
||||
数を使いきるまで同時に /dev/dspN を開く事ができます。
|
||||
|
||||
残りの 32ch は MIDI 用に設けられていて、PCM と MIDI の2つのバンクに分ける事
|
||||
ができます。個々のチャンネルには PCM front volume がありますが、2つのバンク
|
||||
をそれぞれ統括する Wave/Music Volume があり さらにそれらを合わせる PCM volume
|
||||
があります。(最後に Master Volume)
|
||||
|
||||
図にすると次のようになります。
|
||||
|
||||
PCM Volume + - Wave Volume + - front volume- PCM Playback 0
|
||||
| + - .. - PCM Playback 1
|
||||
| :
|
||||
| + - .. - PCM Playback 31
|
||||
|
|
||||
+ - Music Volume + - .. - PCM Playback 32
|
||||
:
|
||||
+ - .. - PCM Playback 63
|
||||
|
||||
|
||||
ES1370/1371 でも PCM 用 と MIDI 用に 2 チャンネルの PCM 出力があります。
|
||||
ALSA では
|
||||
|
||||
$ cat /proc/asound/pcm
|
||||
00-00: ES1371/1 : ES1371 DAC2/ADC : playback 1 : capture 1
|
||||
00-01: ES1371/2 : ES1371 DAC1 : playback 1
|
||||
|
||||
のように 0:0 と 0:1 のデバイスが再生用として使う事が出来ます。timidity 用に
|
||||
0:1 のデバイスを使うと良いでしょう。OSS では /dev/dsp0 と /dev/dsp1 に割り当
|
||||
てられ、 /dev/dsp1 を timidity で使います。
|
||||
|
||||
またその他のカードでも多チャンネル出力を持っているものもありますので、
|
||||
ドライバーのドキュメントを御覧下さい。
|
||||
|
||||
|
||||
(2003.1.23 追記)
|
||||
追記を書いている時点で手に入りやすい多チャンネルPCM出力をもつ音源カード
|
||||
としては SoundBlaster Live と YMF7xx くらいでしょうか。
|
||||
|
||||
@@ -1,57 +0,0 @@
|
||||
TODO (順番は特に無し)
|
||||
|
||||
* メンテナンス
|
||||
|
||||
-- obsolete
|
||||
|
||||
* TODOを増やさない
|
||||
* SYSTEM3の3.5への移植ものや、ネット上にあるSYSTEM3.5のデータへの対応
|
||||
* system 3.9への対応
|
||||
* Xのイベントハンドリングの改良
|
||||
* oringinal の savedata(v1/v2/v3?) を convert する tool
|
||||
* savedata を lt/bg でどっちでも読めるようにする
|
||||
* XIM 対応?
|
||||
* 関数/変数名の統一
|
||||
* 技術情報のドキュメント化
|
||||
* GUI付 installer (っていうか、CD-ROMの中の setup.infを直接使う)
|
||||
* 異常終了時に出来るだけプロセスが残らないようにする
|
||||
* global変数を減らす
|
||||
* 意図的な異常シナリオデータでもsegv.らないよう努力する
|
||||
* Tab/Spaceの混在などソースの見直し(随時)
|
||||
* CEの残りのコマンドをさっさと実装する
|
||||
* SDL を理解して cleanup
|
||||
* キー入力まわりの cleanup
|
||||
* UNIX+X 以外の環境へ移植しやすくする
|
||||
|
||||
|
||||
* 王子様1/16
|
||||
+ スケジュールを組む時に「もどる」「クリア」「OK!」の選択がうまくで
|
||||
きない。
|
||||
* ランス4
|
||||
+ プチハニーの爆風に巻き込まれると、キャラの上に「防」マークがつきっぱ
|
||||
なしになる。
|
||||
+ 戦闘シーンでたまに左上にモンスターのかけらが表示されることがある。
|
||||
|
||||
|
||||
DONE
|
||||
|
||||
* configure 化
|
||||
* gtk_setup.c rewrite
|
||||
* keyboard操作対応
|
||||
* cd/mp3の切替えをオプションで切替えられるようにする
|
||||
* packed 24bpp対応 (rewrite xcore.c)
|
||||
* music server cleanup
|
||||
* dri mmap化
|
||||
* 汎用 data cache 処理を作る。TTF フォントと展開済み CG で使おうか。
|
||||
* alphabelnd asm化
|
||||
* imgae.c をもうちょっとすっきりと。(depthで関数のテーブル化
|
||||
* ecopy のタイミングの最適化
|
||||
* wav が鳴らない事がしばしばある(open err)のを調査&修正
|
||||
* *.h の依存関係 cleanup, 特に xsystem35.h
|
||||
* xcore/imageの統合とcleanup
|
||||
* MIDIの自前のハンドリング(/dev/sequener ?)
|
||||
* FullScreen対応(with DGA)
|
||||
* 古いドキュメントをなんとかする。(FAQ/BUGS etc)
|
||||
* 大悪司
|
||||
+ SDLの時、MAP選択が正常に動かない。
|
||||
|
||||
@@ -0,0 +1,149 @@
|
||||
= xsystem35(6)
|
||||
:doctype: manpage
|
||||
:manmanual: xsystem35 manual
|
||||
:mansource: xsystem35 {xsystem35-version}
|
||||
|
||||
== Name
|
||||
|
||||
xsystem35 - play System 3.x games
|
||||
|
||||
== SYNOPSIS
|
||||
|
||||
*xsystem35* [_OPTION_]...
|
||||
|
||||
== DESCRIPTION
|
||||
|
||||
This man page describes *xsystem35-sdl2*, a multi-platform port of the
|
||||
AliceSoft's System3.5/3.6/3.8/3.9 game engine derived from the original
|
||||
*xsystem35*.
|
||||
|
||||
`xsystem35` reads the game resource file from the path specified by the
|
||||
`-gamefile` option, or from `xsystem35.gr` in the current directory if the
|
||||
option is not specified. If the game resource file is not found, `xsystem35`
|
||||
finds System 3.x game files (*.ALD) from the current directory.
|
||||
|
||||
== OPTIONS
|
||||
|
||||
*-gamefile* _file_::
|
||||
Load game resouce file from _file_. See <<FILES>> section for details.
|
||||
|
||||
*-game* _game_::
|
||||
Enables game-specific hacks. Usually auto-detected, but must be specified for
|
||||
games with modified / translated titles. Possible values are: `toushin2`,
|
||||
`rance3_eng`, `rance4_eng`, `rance4_v2`.
|
||||
|
||||
*-savedir* _dir_::
|
||||
Directory to save game state files. If _dir_ begins with '~', it is expanded
|
||||
to the user's home directory (`$HOME`).
|
||||
|
||||
*-saveformat* _fmt_::
|
||||
The format when writing save files. Possible values are: `xsystem35`,
|
||||
`system36`, `system39` (default).
|
||||
|
||||
*-texthook* _mode_::
|
||||
Set the text hook mode. Possible values are: `none` (default), `print` (print
|
||||
text to console), `copy` (copy text to clipboard).
|
||||
|
||||
*-texthook_suppress* _list_::
|
||||
Suppress text hook on specified scenario pages. _list_ is a comma-separated
|
||||
list of page numbers. Used to suppress system messages, etc.
|
||||
|
||||
*-renderer* _name_::
|
||||
Use the SDL rendering driver named _name_.
|
||||
|
||||
*-playlist* _file_::
|
||||
Load the CD playlist from _file_. The playlist is a text file with one
|
||||
filename per line, in the order of CD tracks. See <<FILES>> section for details.
|
||||
|
||||
*-Me*::
|
||||
Use SDL_mixer for MIDI playback.
|
||||
|
||||
**-Mp**_device_number_::
|
||||
Use ALSA (via PortMidi) for MIDI playback.
|
||||
|
||||
*-M0*::
|
||||
Disable MIDI playback.
|
||||
|
||||
*-devjoy* _device_index_::
|
||||
Use the joystick device with the given index.
|
||||
|
||||
*-ttfont_mincho* _file_::
|
||||
Use the given TrueType or OpenType font file for mincho (serif) text.
|
||||
|
||||
*-ttfont_gothic* _file_::
|
||||
Use the given TrueType or OpenType font file for gothic (sans-serif) text.
|
||||
|
||||
*-debuglv* _level_::
|
||||
Set the debug level to _level_. The higher the level, the more verbose
|
||||
the debug output.
|
||||
|
||||
*-debug*::
|
||||
Start with the debugger enabled.
|
||||
|
||||
*-noantialias*::
|
||||
Disable text antialiasing.
|
||||
|
||||
*-fullscreen*::
|
||||
Start in fullscreen mode.
|
||||
|
||||
*-integerscale*::
|
||||
Use integer scaling for the window.
|
||||
|
||||
*-noimagecursor*::
|
||||
Disable custom mouse cursor images.
|
||||
|
||||
*-version*::
|
||||
Print the version number and exit.
|
||||
|
||||
*-h, --help*::
|
||||
Print a help message and exit.
|
||||
|
||||
== FILES
|
||||
|
||||
*.xsys35rc*::
|
||||
`xsystem35` reads its configuration from `${HOME}/.xsys35rc` and `.xsys35rc`
|
||||
in the game directory. The latter takes precedence over the former, so you
|
||||
can put general settings in `${HOME}/.xsys35rc` and game-specific settings in
|
||||
`.xsys35rc` in the game directory. Options specified on the command line
|
||||
override both. See xsys35rc.sample for the format of the configuration file.
|
||||
|
||||
*playlist.txt*::
|
||||
`xsystem35` does not support playing BGM directly from a CD. Instead, it
|
||||
supports playing BGM from audio files on your filesystem. `xsystem35` reads
|
||||
the playlist from a file specified by the `-playlist` option, or from
|
||||
`playlist.txt` in the game directory. The first line is the path to the audio
|
||||
file for track 1, the second line is the path to the audio file for track 2,
|
||||
and so on. The first line is usually empty, because track 1 is not an audio
|
||||
track but a data track.
|
||||
|
||||
*xsystem35.gr*::
|
||||
Game resource file which lists the locations of various files needed to run
|
||||
a game. This is optional; `xsystem35` can automatically find the files it
|
||||
needs when run inside a game directory. See
|
||||
xref:xsystem35.gr.adoc[*xsystem35.gr(5)*] for the format of the game resource
|
||||
file.
|
||||
|
||||
== KEYBOARD SHORTCUTS
|
||||
|
||||
System 3.x games basically only use the UP, DOWN, LEFT, RIGHT, SPACE, RET, ESC,
|
||||
and TAB keys (some games use other keys). `xsystem35` uses the following
|
||||
special key assignments:
|
||||
|
||||
*F1*::
|
||||
Toggle message skip mode.
|
||||
|
||||
*F4*::
|
||||
Toggle fullscreen mode.
|
||||
|
||||
Also, in some platforms, the middle mouse button opens the menu.
|
||||
|
||||
== HISTORY
|
||||
|
||||
*xsystem35* was originally developed by Masaki Chikama (Wren)
|
||||
<masaki-c@is.aist-nara.ac.jp> between 1998 and 2006. The project was later
|
||||
forked by Kichikuou <KichikuouChrome@gmail.com> as *xsystem35-sdl2* and ported
|
||||
to SDL2.
|
||||
|
||||
== SEE ALSO
|
||||
|
||||
xsystem35-sdl2 project page: https://github.com/kichikuou/xsystem35-sdl2
|
||||
@@ -0,0 +1,103 @@
|
||||
= xsystem35.gr(5)
|
||||
:doctype: manpage
|
||||
:manmanual: xsystem35 manual
|
||||
:mansource: xsystem35 {xsystem35-version}
|
||||
|
||||
== Name
|
||||
|
||||
xsystem35.gr - game resource file for xsystem35
|
||||
|
||||
== DESCRIPTION
|
||||
|
||||
Game resource file is a plain text file that defines the locations of the
|
||||
various game data files for xsystem35. This file is only needed if you want to
|
||||
place game data files in a location other than the current directory.
|
||||
|
||||
The path to the game resource file is specified with the `-gamefile` option of
|
||||
xref:xsystem35.adoc[*xsystem35(6)*]. If it is not specified, xsystem35 reads
|
||||
`xsystem35.gr` in the current directory.
|
||||
|
||||
Each line of the file specifies a single data file and follows the format:
|
||||
|
||||
_keyword_ _path-to-data_
|
||||
|
||||
If multiple files of the same type exist, suffixes `A`, `B`, `C`... are
|
||||
appended to the _keyword_.
|
||||
|
||||
Comments can be added by starting the line with `#`. Blank lines are ignored.
|
||||
|
||||
== KEYWORDS
|
||||
|
||||
*Scenario*::
|
||||
Scenario files (`*S?.ALD`).
|
||||
|
||||
*Graphics*::
|
||||
Graphic files (`*G?.ALD`).
|
||||
|
||||
*Wave*::
|
||||
PCM data files (`*W?.ALD`).
|
||||
|
||||
*Midi*::
|
||||
MIDI data files (`*M?.ALD`).
|
||||
|
||||
*Data*::
|
||||
Miscellaneous data files (`*D?.ALD`).
|
||||
|
||||
*Resource*::
|
||||
Resource files (`*R?.ALD`).
|
||||
|
||||
*BGM*::
|
||||
BGM files (`*B?.ALD`).
|
||||
|
||||
*Save*::
|
||||
Save files (`*S?.ASD`). If the path begins with '`~`', it is expanded to the
|
||||
user's home directory (`$HOME`).
|
||||
|
||||
*Ain*::
|
||||
The `System39.ain` file.
|
||||
|
||||
*WAI*::
|
||||
Additional information for PCM data (`*WA.WAI`)
|
||||
|
||||
*BGI*::
|
||||
Additional information for BGM data (`*BA.BGI`)
|
||||
|
||||
*SACT01*::
|
||||
Data for SACT.DLL (`SACTEFAM.KLD`)
|
||||
|
||||
*ALK01* - *ALK09*::
|
||||
Archive files for demo data (`*1.ALK` - `*9.ALK`)
|
||||
|
||||
*Init*::
|
||||
The `System39.ini` file.
|
||||
|
||||
== NOTES
|
||||
|
||||
Data files not categorized under the above keywords (e.g., map files for
|
||||
Kaeru nyo Panyon) should not be listed in the game resource file, and should be
|
||||
placed in the same directory as the save files.
|
||||
|
||||
== EXAMPLES
|
||||
|
||||
The following is a game resource file for the English translation of Kichikuou
|
||||
Rance.
|
||||
|
||||
ScenarioA KICHIKUSA.ALD
|
||||
GraphicsA KICHIKUGA.ALD
|
||||
GraphicsB KICHIKUGB.ALD
|
||||
WaveA KICHIKUWA.ALD
|
||||
Ain System39.ain
|
||||
SaveA ~/.xsys35/saves/kichikuou/KICHIKUSA.ASD
|
||||
SaveB ~/.xsys35/saves/kichikuou/KICHIKUSB.ASD
|
||||
SaveC ~/.xsys35/saves/kichikuou/KICHIKUSC.ASD
|
||||
SaveD ~/.xsys35/saves/kichikuou/KICHIKUSD.ASD
|
||||
SaveE ~/.xsys35/saves/kichikuou/KICHIKUSE.ASD
|
||||
SaveF ~/.xsys35/saves/kichikuou/KICHIKUSF.ASD
|
||||
SaveG ~/.xsys35/saves/kichikuou/KICHIKUSG.ASD
|
||||
SaveH ~/.xsys35/saves/kichikuou/KICHIKUSH.ASD
|
||||
SaveI ~/.xsys35/saves/kichikuou/KICHIKUSI.ASD
|
||||
SaveJ ~/.xsys35/saves/kichikuou/KICHIKUSJ.ASD
|
||||
|
||||
== SEE ALSO
|
||||
|
||||
xref:xsystem35.adoc[*xsystem35(6)*]
|
||||
@@ -5,9 +5,11 @@ Game Compatibility
|
||||
| ------------------------------------------- | ----------- | ----- |
|
||||
| 鬼畜王ランス | Supported | |
|
||||
| Kichikuou Rance (EN) | Supported | |
|
||||
| RanceIV -教団の遺産- | Supported | Win95 edition, [Win10 edition](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). 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 |
|
||||
@@ -20,7 +22,7 @@ Game Compatibility
|
||||
| DALK | Supported | From ALICEの館4・5・6 |
|
||||
| 闘神都市 | Supported | From ALICEの館4・5・6 |
|
||||
| Dr.STOP | Supported | From ALICEの館4・5・6 |
|
||||
| 人間狩り | Unsupported | From ALICEの館4・5・6 / アリスCD |
|
||||
| 人間狩り | Supported | From ALICEの館4・5・6 / アリスCD |
|
||||
| 女の子図鑑 | Unknown | From ALICEの館4・5・6 |
|
||||
| 恋のおわり | Unknown | |
|
||||
| 王道勇者 | Supported | |
|
||||
@@ -53,7 +55,7 @@ Game Compatibility
|
||||
| Rance 5D - The Lonely Girl (MangaGamer) | Supported | |
|
||||
| 俺の下であがけ | Unknown | |
|
||||
| 楽園行 | Unknown | |
|
||||
| 妻みぐい2 | Supported | Opening demo is not supported |
|
||||
| 妻みぐい2 | Supported | |
|
||||
| シェル・クレイル | Supported | |
|
||||
| ナイトデーモン | Supported | |
|
||||
| 学園KING | Supported | From アリスCD |
|
||||
@@ -69,13 +71,13 @@ Game Compatibility
|
||||
| [扉] | Supported | From アリスCD |
|
||||
| 叩き殺し太郎 | Supported | From アリスCD |
|
||||
| バルーンぽっぷ | Supported | From アリスCD |
|
||||
| 高速ひよこ2 | Unsupported | From アリスCD |
|
||||
| 高速ひよこ2 | Supported | From アリスCD |
|
||||
| おせろっと | Supported | From アリスCD |
|
||||
| マスカレイド | 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 |
|
||||
| 弱肉狂食 | Unsupported | From アリスCD |
|
||||
| 弱肉狂食 | Supported | From アリスCD |
|
||||
| 眼鏡大戦2 | Supported | From アリスCD |
|
||||
| 妄想くん | Supported | From アリスCD |
|
||||
|
||||
+3
-16
@@ -98,20 +98,7 @@ endif()
|
||||
|
||||
target_compile_options(modules PRIVATE -Wno-pointer-sign)
|
||||
|
||||
if (EMSCRIPTEN)
|
||||
set(LIBS
|
||||
"SHELL:-s USE_ZLIB=1"
|
||||
"SHELL:-s USE_SDL=2")
|
||||
target_compile_options(modules PRIVATE ${LIBS})
|
||||
target_link_options(modules PRIVATE ${LIBS})
|
||||
elseif (ANDROID)
|
||||
target_link_libraries(modules PRIVATE ${ndk_zlib})
|
||||
if (SDL2MIXER_FOUND)
|
||||
target_link_libraries(modules PRIVATE SDL2 SDL2_mixer)
|
||||
endif()
|
||||
else()
|
||||
target_link_libraries(modules PRIVATE ZLIB::ZLIB)
|
||||
if (SDL2MIXER_FOUND)
|
||||
target_link_libraries(modules PRIVATE PkgConfig::SDL2MIXER)
|
||||
endif()
|
||||
target_link_libraries(modules PRIVATE sdl2 zlib)
|
||||
if (TARGET sdl2_mixer)
|
||||
target_link_libraries(modules PRIVATE sdl2_mixer)
|
||||
endif()
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
#include "menu.h"
|
||||
#include "input.h"
|
||||
#include "nact.h"
|
||||
#include "key.h"
|
||||
#include "night.h"
|
||||
#include "sprite.h"
|
||||
|
||||
@@ -33,7 +32,7 @@ static void cb_waitkey_simple(agsevent_t *e) {
|
||||
switch (e->type) {
|
||||
case AGSEVENT_BUTTON_RELEASE:
|
||||
case AGSEVENT_KEY_RELEASE:
|
||||
night.waitkey = e->d3;
|
||||
night.waitkey = e->code;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -59,15 +58,15 @@ void ntev_callback(agsevent_t *e) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (e->type == AGSEVENT_KEY_PRESS && e->d3 == KEY_CTRL) {
|
||||
if (e->type == AGSEVENT_KEY_PRESS && e->code == KEY_CTRL) {
|
||||
night.waitskiplv = 2;
|
||||
night.waitkey = e->d3;
|
||||
night.waitkey = e->code;
|
||||
return;
|
||||
}
|
||||
|
||||
if (e->type == AGSEVENT_KEY_RELEASE && e->d3 == KEY_CTRL) {
|
||||
if (e->type == AGSEVENT_KEY_RELEASE && e->code == KEY_CTRL) {
|
||||
night.waitskiplv = 0;
|
||||
night.waitkey = e->d3;
|
||||
night.waitkey = e->code;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -392,13 +392,11 @@ static void is_in_icon() {
|
||||
|
||||
|
||||
static void cb_keyrelease(agsevent_t *e) {
|
||||
int x = e->d1, y = e->d2;
|
||||
|
||||
switch (e->d3) {
|
||||
switch (e->code) {
|
||||
case AGSEVENT_BUTTON_LEFT:
|
||||
#if 0
|
||||
if (is_in_icon()) {
|
||||
do_icon(x, y);
|
||||
do_icon(e->mousex, e->mousey);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
@@ -408,19 +406,15 @@ static void cb_keyrelease(agsevent_t *e) {
|
||||
// unhide();
|
||||
break;
|
||||
}
|
||||
night.waitkey = e->d3;
|
||||
night.waitkey = e->code;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void cb_mousemove(agsevent_t *e) {
|
||||
int x = e->d1, y = e->d2;
|
||||
|
||||
// 音声mute/メッセージスキップ/メッセージ枠消去の領域に
|
||||
// マウスが移動したら、その部分のアイコンを変化させる
|
||||
|
||||
|
||||
}
|
||||
|
||||
// メッセージ表示時に、キー入力を促すアニメーションの設定
|
||||
|
||||
@@ -58,7 +58,7 @@ int nt_sp_eupdate(int no, int time, int cancel) {
|
||||
int edtime = curtime + time;
|
||||
|
||||
while ((curtime = sdl_getTicks()) < edtime) {
|
||||
sdl_effect_step(eff, (double)(curtime - sttime) / (edtime - sttime));
|
||||
sdl_effect_step(eff, (float)(curtime - sttime) / (edtime - sttime));
|
||||
int rest = 16 - (sdl_getTicks() - curtime);
|
||||
int key = sys_keywait(rest, cancel ? KEYWAIT_CANCELABLE : KEYWAIT_NONCANCELABLE);
|
||||
if (cancel && key)
|
||||
|
||||
@@ -73,6 +73,7 @@ static void ndd_run(int demonum) {
|
||||
if (sys_keywait(wait_ms, KEYWAIT_CANCELABLE))
|
||||
break;
|
||||
} else {
|
||||
sdl_updateScreen();
|
||||
if (sys_getInputInfo())
|
||||
break;
|
||||
}
|
||||
|
||||
+3
-1
@@ -25,6 +25,9 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#ifdef __EMSCRIPTEN__
|
||||
#include <emscripten.h>
|
||||
#endif
|
||||
|
||||
#include "portab.h"
|
||||
#include "system.h"
|
||||
@@ -32,7 +35,6 @@
|
||||
#include "input.h"
|
||||
#include "msgskip.h"
|
||||
#include "xsystem35.h"
|
||||
#include "gametitle.h"
|
||||
#include "message.h"
|
||||
#include "modules.h"
|
||||
#include "music.h"
|
||||
|
||||
@@ -33,7 +33,6 @@
|
||||
#include "menu.h"
|
||||
#include "input.h"
|
||||
#include "nact.h"
|
||||
#include "key.h"
|
||||
#include "sact.h"
|
||||
#include "sprite.h"
|
||||
#include "ngraph.h"
|
||||
|
||||
@@ -39,10 +39,12 @@
|
||||
#include "sdl_core.h"
|
||||
#include "randMT.h"
|
||||
|
||||
typedef void entrypoint (double step, int p1, int p2, int *retx, int *rety);
|
||||
#define M_PIf ((float)M_PI)
|
||||
|
||||
typedef void entrypoint (float step, int p1, int p2, int *retx, int *rety);
|
||||
|
||||
// 上下左右方向の揺らし
|
||||
static void quake0(double step, int ampx, int ampy, int *adjx, int *adjy) {
|
||||
static void quake0(float step, int ampx, int ampy, int *adjx, int *adjy) {
|
||||
static int i = 0;
|
||||
|
||||
*adjx = (int)(genrand() * ampx/2);
|
||||
@@ -53,12 +55,12 @@ static void quake0(double step, int ampx, int ampy, int *adjx, int *adjy) {
|
||||
}
|
||||
|
||||
// 回転の揺らし
|
||||
static void quake1(double curstep, int diam, int round, int *adjx, int *adjy) {
|
||||
double R = (1 - curstep) * diam / 2;
|
||||
double th = curstep * 2 * M_PI * round;
|
||||
static void quake1(float curstep, int diam, int round, int *adjx, int *adjy) {
|
||||
float R = (1 - curstep) * diam / 2;
|
||||
float th = curstep * 2 * M_PIf * round;
|
||||
|
||||
*adjx = (int)(R * cos(th));
|
||||
*adjy = (int)(R * sin(th));
|
||||
*adjx = (int)(R * cosf(th));
|
||||
*adjy = (int)(R * sinf(th));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -83,7 +85,7 @@ int sp_quake_screen(int type, int p1, int p2, int time, int cancel) {
|
||||
while ((curtime = sdl_getTicks()) < edtime) {
|
||||
int adjx, adjy;
|
||||
|
||||
cb[type]((double)(curtime - sttime)/(edtime - sttime), p1, p2, &adjx, &adjy);
|
||||
cb[type]((float)(curtime - sttime)/(edtime - sttime), p1, p2, &adjx, &adjy);
|
||||
ags_setViewArea(adjx, adjy, sf0->width, sf0->height);
|
||||
ags_updateFull();
|
||||
|
||||
|
||||
@@ -59,7 +59,7 @@ int sp_eupdate(int type, int time, int cancel) {
|
||||
int edtime = curtime + time * 10;
|
||||
|
||||
while ((curtime = sdl_getTicks()) < edtime) {
|
||||
sdl_effect_step(eff, (double)(curtime - sttime) / (edtime - sttime));
|
||||
sdl_effect_step(eff, (float)(curtime - sttime) / (edtime - sttime));
|
||||
int rest = 16 - (sdl_getTicks() - curtime);
|
||||
int key = sys_keywait(rest, cancel ? KEYWAIT_CANCELABLE : KEYWAIT_NONCANCELABLE);
|
||||
if (cancel && key)
|
||||
|
||||
+16
-14
@@ -24,6 +24,9 @@
|
||||
#include "config.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#ifdef __EMSCRIPTEN__
|
||||
#include <emscripten.h>
|
||||
#endif
|
||||
|
||||
#include "portab.h"
|
||||
#include "system.h"
|
||||
@@ -31,7 +34,6 @@
|
||||
#include "menu.h"
|
||||
#include "input.h"
|
||||
#include "nact.h"
|
||||
#include "key.h"
|
||||
#include "sact.h"
|
||||
#include "sprite.h"
|
||||
#include "sactsound.h"
|
||||
@@ -210,7 +212,7 @@ static void cb_waitkey_simple(agsevent_t *e) {
|
||||
|
||||
switch (e->type) {
|
||||
case AGSEVENT_KEY_PRESS:
|
||||
if (e->d3 == KEY_Z) {
|
||||
if (e->code == KEY_Z) {
|
||||
cur = sdl_getTicks();
|
||||
if (!sact.zhiding) {
|
||||
slist_foreach(sact.sp_zhide, cb_defocused_zkey, &update);
|
||||
@@ -239,7 +241,7 @@ static void cb_waitkey_simple(agsevent_t *e) {
|
||||
// fall through
|
||||
|
||||
case AGSEVENT_KEY_RELEASE:
|
||||
switch(e->d3) {
|
||||
switch(e->code) {
|
||||
case KEY_Z:
|
||||
cur = sdl_getTicks();
|
||||
if (500 < (cur - sact.zofftime) || !sact.zdooff) {
|
||||
@@ -255,7 +257,7 @@ static void cb_waitkey_simple(agsevent_t *e) {
|
||||
sact.waittype = KEYWAIT_BACKLOG;
|
||||
break;
|
||||
default:
|
||||
sact.waitkey = e->d3;
|
||||
sact.waitkey = e->code;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -289,7 +291,7 @@ void cb_waitkey_sprite(agsevent_t *e) {
|
||||
// 右クリックキャンセル
|
||||
// drag中でない時のみ、キャンセルを受け付ける
|
||||
if (e->type == AGSEVENT_BUTTON_RELEASE &&
|
||||
e->d3 == AGSEVENT_BUTTON_RIGHT) {
|
||||
e->code == AGSEVENT_BUTTON_RIGHT) {
|
||||
sact.waitkey = 0;
|
||||
return;
|
||||
}
|
||||
@@ -308,7 +310,7 @@ void cb_waitkey_sprite(agsevent_t *e) {
|
||||
// dragg中の sprite は無視する
|
||||
if (sp == sact.draggedsp) continue;
|
||||
|
||||
if (focused_sp == NULL && sp_is_insprite(sp, e->d1, e->d2)) {
|
||||
if (focused_sp == NULL && sp_is_insprite(sp, e->mousex, e->mousey)) {
|
||||
/*
|
||||
focusを得ている sprite
|
||||
*/
|
||||
@@ -385,8 +387,8 @@ static void cb_waitkey_selection(agsevent_t *e) {
|
||||
static void cb_waitkey_backlog(agsevent_t *e) {
|
||||
switch (e->type) {
|
||||
case AGSEVENT_KEY_RELEASE:
|
||||
switch (e->d3) {
|
||||
case KEY_ESC:
|
||||
switch (e->code) {
|
||||
case KEY_ESCAPE:
|
||||
sblog_end();
|
||||
sact.waittype = KEYWAIT_MESSAGE;
|
||||
break;
|
||||
@@ -406,14 +408,14 @@ static void cb_waitkey_backlog(agsevent_t *e) {
|
||||
break;
|
||||
|
||||
case AGSEVENT_BUTTON_RELEASE:
|
||||
if (e->d3 == AGSEVENT_BUTTON_RIGHT) {
|
||||
if (e->code == AGSEVENT_BUTTON_RIGHT) {
|
||||
sblog_end();
|
||||
sact.waittype = KEYWAIT_MESSAGE;
|
||||
}
|
||||
break;
|
||||
|
||||
case AGSEVENT_MOUSE_WHEEL:
|
||||
if (e->d3 > 0)
|
||||
if (e->code > 0)
|
||||
sblog_pagenext();
|
||||
else
|
||||
sblog_pagepre();
|
||||
@@ -431,15 +433,15 @@ void spev_callback(agsevent_t *e) {
|
||||
}
|
||||
|
||||
if (sact.waittype != KEYWAIT_BACKLOG) {
|
||||
if (e->type == AGSEVENT_KEY_PRESS && e->d3 == KEY_CTRL) {
|
||||
if (e->type == AGSEVENT_KEY_PRESS && e->code == KEY_CTRL) {
|
||||
sact.waitskiplv = 2;
|
||||
sact.waitkey = e->d3;
|
||||
sact.waitkey = e->code;
|
||||
return;
|
||||
}
|
||||
|
||||
if (e->type == AGSEVENT_KEY_RELEASE && e->d3 == KEY_CTRL) {
|
||||
if (e->type == AGSEVENT_KEY_RELEASE && e->code == KEY_CTRL) {
|
||||
sact.waitskiplv = 0;
|
||||
sact.waitkey = e->d3;
|
||||
sact.waitkey = e->code;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,12 +58,12 @@ static int eventCB_GET(sprite_t *sp, agsevent_t *e) {
|
||||
|
||||
switch(e->type) {
|
||||
case AGSEVENT_BUTTON_PRESS:
|
||||
if (e->d3 != AGSEVENT_BUTTON_LEFT) break;
|
||||
if (e->code != AGSEVENT_BUTTON_LEFT) break;
|
||||
|
||||
// drag開始時のマウスの位置記録
|
||||
sp->u.get.dragging = TRUE;
|
||||
sp->u.get.dragstart.x = e->d1;
|
||||
sp->u.get.dragstart.y = e->d2;
|
||||
sp->u.get.dragstart.x = e->mousex;
|
||||
sp->u.get.dragstart.y = e->mousey;
|
||||
|
||||
if (sp->cg3) {
|
||||
sp->curcg = sp->cg3;
|
||||
@@ -104,8 +104,8 @@ static int eventCB_GET(sprite_t *sp, agsevent_t *e) {
|
||||
// if (!sp->u.get.dragging) break;
|
||||
|
||||
// マウスの現在位置により新しい場所を計算
|
||||
newx = sp->loc.x + (e->d1 - sp->u.get.dragstart.x);
|
||||
newy = sp->loc.y + (e->d2 - sp->u.get.dragstart.y);
|
||||
newx = sp->loc.x + (e->mousex - sp->u.get.dragstart.x);
|
||||
newy = sp->loc.y + (e->mousey - sp->u.get.dragstart.y);
|
||||
if (newx != sp->cur.x || newy != sp->cur.y) {
|
||||
sp_updateme(sp);
|
||||
sp->cur.x = newx;
|
||||
|
||||
@@ -135,13 +135,13 @@ int sp_keywait(int *vOK, int *vRND, int *vD01, int *vD02, int *vD03, int timeout
|
||||
{
|
||||
// とりあえず、現在のマウス位置を送って、switch sprite の
|
||||
// 状態を更新しておく
|
||||
agsevent_t agse;
|
||||
MyPoint p;
|
||||
sys_getMouseInfo(&p, FALSE);
|
||||
agse.type = AGSEVENT_MOUSE_MOTION;
|
||||
agse.d1 = p.x;
|
||||
agse.d2 = p.y;
|
||||
agse.d3 = 0;
|
||||
agsevent_t agse = {
|
||||
.type = AGSEVENT_MOUSE_MOTION,
|
||||
.mousex = p.x,
|
||||
.mousey = p.y
|
||||
};
|
||||
spev_callback(&agse);
|
||||
}
|
||||
|
||||
|
||||
@@ -129,7 +129,7 @@ void spev_move_setup(void* data, void* userdata) {
|
||||
// speed から timeへ
|
||||
int dx = sp->move.to.x - sp->loc.x;
|
||||
int dy = sp->move.to.y - sp->loc.y;
|
||||
int d = (int)sqrt(dx*dx+dy*dy);
|
||||
int d = (int)sqrtf(dx*dx+dy*dy);
|
||||
sp->move.time = d * 100 / sp->move.speed;
|
||||
}
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ static int eventCB_PUT(sprite_t *sp, agsevent_t *e) {
|
||||
|
||||
switch(e->type) {
|
||||
case AGSEVENT_BUTTON_PRESS:
|
||||
if (e->d3 != AGSEVENT_BUTTON_LEFT) return 0;
|
||||
if (e->code != AGSEVENT_BUTTON_LEFT) return 0;
|
||||
|
||||
// ボタン押下時のスプライトがあれば、それを表示
|
||||
if (sp->cg3) {
|
||||
|
||||
@@ -31,7 +31,6 @@
|
||||
#include "nact.h"
|
||||
#include "ags.h"
|
||||
#include "input.h"
|
||||
#include "key.h"
|
||||
#include "sact.h"
|
||||
#include "sprite.h"
|
||||
#include "ngraph.h"
|
||||
@@ -77,7 +76,7 @@ static boolean sp_is_insprite2(sprite_t *sp, int x, int y, int margin) {
|
||||
|
||||
// マウスが移動したときの callback
|
||||
static void cb_select_move(agsevent_t *e) {
|
||||
int x = e->d1, y = e->d2;
|
||||
int x = e->mousex, y = e->mousey;
|
||||
sprite_t *sp = sact.sp[sact.sel.spno];
|
||||
boolean newstate;
|
||||
int newindex;
|
||||
@@ -115,12 +114,12 @@ static void cb_select_move(agsevent_t *e) {
|
||||
|
||||
// ボタンがリリースされたときの callback
|
||||
static void cb_select_release(agsevent_t *e) {
|
||||
int x = e->d1, y = e->d2;
|
||||
int x = e->mousex, y = e->mousey;
|
||||
sprite_t *sp = sact.sp[sact.sel.spno];
|
||||
boolean st;
|
||||
int iy;
|
||||
|
||||
switch (e->d3) {
|
||||
switch (e->code) {
|
||||
case AGSEVENT_BUTTON_LEFT:
|
||||
st = sp_is_insprite2(sp, x, y, sact.sel.frame_dot);
|
||||
iy = (y - (sp->cur.y + sact.sel.frame_dot)) / (sact.sel.font_size + sact.sel.linespace);
|
||||
@@ -198,8 +197,10 @@ static void setup_selwindow() {
|
||||
|
||||
// デフォルトで選択される選択肢がある場合、そこへカーソルを移動
|
||||
if (sact.sel.movecursor) {
|
||||
ags_setCursorLocation(sp->cur.x + sact.sel.frame_dot + 2,
|
||||
sp->cur.y + sact.sel.frame_dot + 2 + (sact.sel.font_size + sact.sel.linespace)*(sact.sel.movecursor -1), TRUE);
|
||||
int x = sp->cur.x + sact.sel.frame_dot + 2;
|
||||
int y = sp->cur.y + sact.sel.frame_dot + 2 +
|
||||
(sact.sel.font_size + sact.sel.linespace) * (sact.sel.movecursor - 1);
|
||||
ags_setCursorLocation(x, y, true, true);
|
||||
selected_item = (sact.sel.movecursor -1);
|
||||
oldstate = TRUE;
|
||||
oldindex = selected_item -1;
|
||||
|
||||
@@ -41,7 +41,7 @@ static int eventCB_switch(sprite_t *sp, agsevent_t *e) {
|
||||
|
||||
switch(e->type) {
|
||||
case AGSEVENT_BUTTON_PRESS:
|
||||
if (e->d3 != AGSEVENT_BUTTON_LEFT) return 0;
|
||||
if (e->code != AGSEVENT_BUTTON_LEFT) return 0;
|
||||
|
||||
// ボタン押下時のスプライトがあれば、それを表示
|
||||
if (sp->cg3) {
|
||||
@@ -53,7 +53,7 @@ static int eventCB_switch(sprite_t *sp, agsevent_t *e) {
|
||||
break;
|
||||
|
||||
case AGSEVENT_BUTTON_RELEASE:
|
||||
if (e->d3 != AGSEVENT_BUTTON_LEFT) return 0;
|
||||
if (e->code != AGSEVENT_BUTTON_LEFT) return 0;
|
||||
|
||||
// ここにくるときは forcusが当たっているときしかこないので、
|
||||
// curcg は cg2 に戻せばよい
|
||||
|
||||
@@ -1306,7 +1306,7 @@ static void ChangeSecretArray(void) { /* 53 */
|
||||
(*vAry) ^= ax; ax = (key[i&3] ^ *vAry);
|
||||
j ^= ax;
|
||||
if (i & 2) {
|
||||
ax = !ax ^ (i*3);
|
||||
ax = ~ax ^ (i*3);
|
||||
}
|
||||
if (i & 4) {
|
||||
ax = (ax >> 4) | (ax << 12);
|
||||
@@ -1328,13 +1328,12 @@ static void ChangeSecretArray(void) { /* 53 */
|
||||
*vAry ^= ax; ax = (key[i&3] ^ k);
|
||||
j ^= ax;
|
||||
if (i & 2) {
|
||||
ax = !ax ^ (i*3);
|
||||
ax = ~ax ^ (i*3);
|
||||
}
|
||||
if (i & 4) {
|
||||
ax = (ax >> 4) | (ax << 12);
|
||||
}
|
||||
vAry++;
|
||||
|
||||
}
|
||||
*vResult = j;
|
||||
}
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
#include "ags.h"
|
||||
#include "music.h"
|
||||
#include "sdl_core.h"
|
||||
#include "hacks.h"
|
||||
|
||||
#define SLOT 40
|
||||
|
||||
@@ -166,14 +167,14 @@ static void ChangeNotColor() {
|
||||
case 24:
|
||||
case 32:
|
||||
{
|
||||
uint32_t pic24s = PIX24(*src, *(src+1), *(src+2)) & 0xf0f0f0;
|
||||
uint32_t pic24d = PIX24(*dst, *(dst+1), *(dst+2)) & 0xf0f0f0;
|
||||
uint32_t pic24s = PIX24(*src, *(src+1), *(src+2));
|
||||
uint32_t pic24d = PIX24(*dst, *(dst+1), *(dst+2));
|
||||
uint32_t *yl;
|
||||
|
||||
for (y = 0; y < height; y++) {
|
||||
yl = (uint32_t *)(dp + y * dib->bytes_per_line);
|
||||
for (x = 0; x < width; x++) {
|
||||
if ((*yl & 0xf0f0f0) != pic24s) {
|
||||
if (*yl != pic24s) {
|
||||
*yl = pic24d;
|
||||
}
|
||||
yl++;
|
||||
@@ -182,6 +183,9 @@ static void ChangeNotColor() {
|
||||
break;
|
||||
}
|
||||
}
|
||||
// The CX command after ChangeNotColor (in FIGHT.ADV) must use a precise
|
||||
// calculation.
|
||||
daiakuji_cx_hack = true;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -585,14 +589,14 @@ static void copy_sprite(int sx, int sy, int width, int height, int dx, int dy, i
|
||||
case 24:
|
||||
case 32:
|
||||
{
|
||||
uint32_t pic24 = PIX24(r, g, b) & 0xf0f0f0;
|
||||
uint32_t pic24 = PIX24(r, g, b);
|
||||
uint32_t *yls, *yld;
|
||||
|
||||
for (y = 0; y < height; y++) {
|
||||
yls = (uint32_t *)(sp + y * dib->bytes_per_line);
|
||||
yld = (uint32_t *)(dp + y * dib->bytes_per_line);
|
||||
for (x = 0; x < width; x++) {
|
||||
if ((*yls & 0xf0f0f0) != pic24) {
|
||||
if (*yls != pic24) {
|
||||
*yld = *yls;
|
||||
}
|
||||
yls++; yld++;
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
#include "modules.h"
|
||||
#include "sdl_core.h"
|
||||
#include "sdl_private.h"
|
||||
#include "input.h"
|
||||
#include "menu.h"
|
||||
|
||||
// キー変換テーブル
|
||||
@@ -162,7 +163,7 @@ static void GetKeyStatus(void) {
|
||||
}
|
||||
|
||||
*var = 0;
|
||||
for (i = 0; i < 256; i++) {
|
||||
for (i = 0; i < NUM_KEYCODES; i++) {
|
||||
*var |= (keymap[no -1][i] * RawKeyInfo[i]);
|
||||
}
|
||||
|
||||
|
||||
@@ -89,7 +89,9 @@ static void SetWindowTitle(void) { /* 6 */
|
||||
int strno = getCaliValue();
|
||||
int p2 = getCaliValue(); /* ISys3xSystem */
|
||||
|
||||
ags_setWindowTitle(svar_get(strno));
|
||||
char *title_utf8 = toUTF8(svar_get(strno));
|
||||
ags_setWindowTitle(title_utf8);
|
||||
free(title_utf8);
|
||||
|
||||
DEBUG_COMMAND("ShString.SetWindowTitle: %d,%d:", strno, p2);
|
||||
}
|
||||
|
||||
@@ -140,7 +140,7 @@ void gr_drawimage16(surface_t *ds, cgdata *cg, int x, int y) {
|
||||
yl = (uint32_t *)(dp + y * ds->bytes_per_line);
|
||||
for (x = 0; x < dw; x++) {
|
||||
pic16 = *sp;
|
||||
*yl = PIX24(PIXR16(pic16), PIXG16(pic16), PIXB16(pic16));
|
||||
*yl = rgb565_to_rgb888(pic16);
|
||||
yl++; sp++;
|
||||
}
|
||||
sp += (cg->width - dw);
|
||||
|
||||
+72
-2
@@ -1,3 +1,23 @@
|
||||
/*
|
||||
* Copyright (C) 1997-1998 Masaki Chikama (Wren) <chikama@kasumi.ipl.mech.nagoya-u.ac.jp>
|
||||
* 1998- <masaki-c@is.aist-nara.ac.jp>
|
||||
* 2024 kichikuou <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 "config.h"
|
||||
|
||||
#include <stdio.h>
|
||||
@@ -7,6 +27,16 @@
|
||||
#include "xsystem35.h"
|
||||
#include "modules.h"
|
||||
#include "nact.h"
|
||||
#include "alk.h"
|
||||
#include "input.h"
|
||||
#include "bgm.h"
|
||||
#include "sdl_core.h"
|
||||
#include "ngraph.h"
|
||||
#include "cg.h"
|
||||
#include "jpeg.h"
|
||||
|
||||
#define TDEMO_MUSIC_NO 1
|
||||
#define FPS 30
|
||||
|
||||
static void Init() {
|
||||
int p1 = getCaliValue();
|
||||
@@ -16,7 +46,7 @@ static void Init() {
|
||||
|
||||
*var = 1;
|
||||
|
||||
DEBUG_COMMAND_YET("tDemo.Init %d,%d,%d,%p:", p1, p2, p3, var);
|
||||
DEBUG_COMMAND("tDemo.Init %d,%d,%d,%p:", p1, p2, p3, var);
|
||||
}
|
||||
|
||||
static void SetKeyCancelFlag() {
|
||||
@@ -33,7 +63,47 @@ static void SetLoopFlag() {
|
||||
}
|
||||
|
||||
static void Run() {
|
||||
DEBUG_COMMAND_YET("tDemo.Run:");
|
||||
alk_t *alk = alk_new("tDEMO.alk");
|
||||
if (!alk) {
|
||||
WARNING("Cannot open tDEMO.alk");
|
||||
return;
|
||||
}
|
||||
|
||||
while (sys_getInputInfo()); // wait for key up
|
||||
|
||||
musbgm_play(TDEMO_MUSIC_NO, 0, 100);
|
||||
|
||||
uint32_t start = sdl_getTicks();
|
||||
while (!nact->is_quit) {
|
||||
int i = (sdl_getTicks() - start) / (1000 / FPS);
|
||||
if (i >= alk->datanum)
|
||||
break;
|
||||
|
||||
cgdata *cg = jpeg_extract(alk->entries[i].data, alk->entries[i].size);
|
||||
if (cg) {
|
||||
gr_drawimage24(sf0, cg, 0, 0);
|
||||
ags_updateFull();
|
||||
cgdata_free(cg);
|
||||
} else {
|
||||
WARNING("Cannot decode CG %d", i);
|
||||
}
|
||||
|
||||
int wait_ms = (i + 1) * (1000 / FPS) - (sdl_getTicks() - start);
|
||||
if (wait_ms > 0) {
|
||||
if (sys_keywait(wait_ms, KEYWAIT_CANCELABLE))
|
||||
break;
|
||||
} else {
|
||||
sdl_updateScreen();
|
||||
if (sys_getInputInfo())
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
musbgm_stop(TDEMO_MUSIC_NO, 0);
|
||||
|
||||
alk_free(alk);
|
||||
|
||||
DEBUG_COMMAND("tDemo.Run:");
|
||||
}
|
||||
|
||||
static const ModuleFunc functions[] = {
|
||||
|
||||
+134
-82
@@ -11,6 +11,9 @@ if (ANDROID)
|
||||
add_library(xsystem35 SHARED)
|
||||
else()
|
||||
add_executable(xsystem35)
|
||||
if (WIN32)
|
||||
target_link_options(xsystem35 PRIVATE -static)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
target_compile_options(xsystem35 PRIVATE -Wno-pointer-sign $<$<CONFIG:Debug>:-Wall>)
|
||||
@@ -18,112 +21,168 @@ 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)
|
||||
|
||||
# Graphics
|
||||
|
||||
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)
|
||||
|
||||
# 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 PkgConfig::WEBP)
|
||||
if (EMSCRIPTEN)
|
||||
target_sources(xsystem35 PRIVATE pcm.emscripten.c bgm.emscripten.c)
|
||||
else()
|
||||
target_sources(xsystem35 PRIVATE pcm.sdlmixer.c bgm.sdlmixer.c)
|
||||
endif()
|
||||
|
||||
# Music
|
||||
target_sources(xsystem35 PRIVATE
|
||||
music.c music_cdrom.c music_midi.c midi.c cdrom.c)
|
||||
if (EMSCRIPTEN)
|
||||
target_sources(xsystem35 PRIVATE cdrom.emscripten.c)
|
||||
else()
|
||||
target_sources(xsystem35 PRIVATE cdrom.mp3.c)
|
||||
endif()
|
||||
|
||||
# Misc
|
||||
target_sources(xsystem35 PRIVATE
|
||||
input.c profile.c mt19937-1.c filecheck.c mmap.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_PORTMIDI)
|
||||
target_sources(xsystem35 PRIVATE midi.portmidi.c midifile.c)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# 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)
|
||||
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()
|
||||
|
||||
# Graphics
|
||||
target_sources(xsystem35 PRIVATE
|
||||
ags.c cg.c ecopy.c alpha_plane.c cursor.c)
|
||||
if (HAVE_WEBP)
|
||||
target_sources(xsystem35 PRIVATE webp.c)
|
||||
target_link_libraries(xsystem35 PRIVATE WebP)
|
||||
endif()
|
||||
|
||||
# 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)
|
||||
endif()
|
||||
|
||||
if (WIN32)
|
||||
target_sources(xsystem35 PRIVATE win/dialog.c win/resources.rc win/menubar.c win/console.c)
|
||||
target_sources(xsystem35 PRIVATE
|
||||
win/dialog.c win/resources.rc win/resources.c win/menubar.c win/console.c)
|
||||
endif()
|
||||
|
||||
target_link_libraries(src_lib PRIVATE sdl2 zlib)
|
||||
target_link_libraries(xsystem35 PRIVATE m zlib sdl2 sdl2_ttf)
|
||||
if (TARGET sdl2_mixer)
|
||||
target_link_libraries(xsystem35 PRIVATE sdl2_mixer)
|
||||
endif()
|
||||
|
||||
if (EMSCRIPTEN)
|
||||
|
||||
set(LIBS
|
||||
"SHELL:-s USE_ZLIB=1"
|
||||
"SHELL:-s USE_SDL=2"
|
||||
"SHELL:-s USE_SDL_TTF=2")
|
||||
target_compile_options(xsystem35 PRIVATE ${LIBS})
|
||||
target_link_options(xsystem35 PRIVATE ${LIBS})
|
||||
target_link_libraries(xsystem35 PRIVATE idbfs.js)
|
||||
|
||||
# Without optimizations, Asyncify generates very large code.
|
||||
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_RUNTIME_METHODS=getValue,addRunDependency,removeRunDependency")
|
||||
-sENVIRONMENT=web
|
||||
-sMODULARIZE=1
|
||||
-sEXPORT_ES6=1
|
||||
-sASYNCIFY=1
|
||||
-sASYNCIFY_IGNORE_INDIRECT=1
|
||||
-sASYNCIFY_REMOVE=SDL_Delay
|
||||
-sASYNCIFY_IMPORTS=wait_vsync
|
||||
# Functions that call an asynchronous function via a function pointer must
|
||||
# be added to ASYNCIFY_ADD, even if it had a direct call to another
|
||||
# asynchronous function, so that the indirect call itself is instrumented.
|
||||
-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=FS,IDBFS,getValue,addRunDependency,removeRunDependency,stringToUTF8OnStack
|
||||
--emit-tsd=xsystem35.d.ts
|
||||
)
|
||||
|
||||
elseif (ANDROID)
|
||||
|
||||
target_link_libraries(src_lib PRIVATE SDL2)
|
||||
target_link_libraries(xsystem35 PRIVATE SDL2 SDL2_ttf SDL2_mixer ${ndk_zlib} ${ndk_log})
|
||||
target_link_libraries(xsystem35 PRIVATE ${ndk_log})
|
||||
|
||||
else() # non-emscripten, non-android
|
||||
target_link_libraries(src_lib PRIVATE PkgConfig::SDL2)
|
||||
target_link_libraries(xsystem35 PRIVATE m ZLIB::ZLIB)
|
||||
target_link_libraries(xsystem35 PRIVATE PkgConfig::SDL2)
|
||||
target_link_libraries(xsystem35 PRIVATE PkgConfig::SDL2TTF)
|
||||
if (TARGET cJSON)
|
||||
target_link_libraries(xsystem35 PRIVATE cJSON)
|
||||
endif()
|
||||
if (GTK3_FOUND)
|
||||
target_link_libraries(xsystem35 PRIVATE PkgConfig::GTK3)
|
||||
endif()
|
||||
if (SDL2MIXER_FOUND)
|
||||
target_link_libraries(xsystem35 PRIVATE PkgConfig::SDL2MIXER)
|
||||
endif()
|
||||
if (ENABLE_DEBUGGER)
|
||||
if (cJSON_FOUND)
|
||||
target_link_libraries(xsystem35 PRIVATE PkgConfig::cJSON)
|
||||
else()
|
||||
target_link_libraries(xsystem35 PRIVATE ${cJSON})
|
||||
endif()
|
||||
endif()
|
||||
if (ENABLE_MIDI_PORTMIDI)
|
||||
target_link_libraries(xsystem35 PRIVATE ${PORTMIDI})
|
||||
endif()
|
||||
@@ -140,10 +199,3 @@ else() # non-emscripten, non-android
|
||||
add_test(NAME src_tests COMMAND src_tests)
|
||||
configure_file(testdata/test.gr ${CMAKE_CURRENT_BINARY_DIR}/testdata/test.gr COPYONLY)
|
||||
endif()
|
||||
|
||||
# FIXME: set up dependency for xsystem35 on this
|
||||
if (NOT EMSCRIPTEN AND NOT ANDROID)
|
||||
add_custom_target(sdl_keytable.h
|
||||
COMMAND perl ../tools/xsyskey.pl ${SDL2_INCLUDE_DIRS} > sdl_keytable.h
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
endif()
|
||||
|
||||
@@ -42,23 +42,44 @@
|
||||
#include "font.h"
|
||||
#include "cursor.h"
|
||||
#include "image.h"
|
||||
#include "debugger.h"
|
||||
|
||||
static Palette256 pal_256;
|
||||
static boolean need_update = TRUE;
|
||||
static boolean fade_outed = FALSE;
|
||||
static int cursor_move_time = 50; /* カーソル移動にかかる時間(ms) */
|
||||
|
||||
static void initPal(Palette256 *pal) {
|
||||
int i;
|
||||
for (i = 0; i < 256; i++) {
|
||||
pal->red[i] = 0; pal->green[i] = 0; pal->blue[i] = 0;
|
||||
}
|
||||
pal->red[0] = 0; pal->green[0] = 0; pal->blue[0] = 0;
|
||||
pal->red[7] = 255; pal->green[7] = 255; pal->blue[7] = 255;
|
||||
pal->red[15] = 255; pal->green[15] = 255; pal->blue[15] = 255;
|
||||
pal->red[255] = 255; pal->green[255] = 255; pal->blue[255] = 255;
|
||||
sdl_setPalette(pal, 0, 256);
|
||||
static void palette_changed(void) {
|
||||
nact->ags.pal_changed = TRUE;
|
||||
dbg_on_palette_change();
|
||||
}
|
||||
|
||||
static void initPal(void) {
|
||||
static const Color initial_palette[256] = {
|
||||
[ 0] = { 0, 0, 0},
|
||||
[ 1] = {128, 0, 0},
|
||||
[ 2] = { 0, 128, 0},
|
||||
[ 3] = {128, 128, 0},
|
||||
[ 4] = { 0, 0, 128},
|
||||
[ 5] = {128, 0, 128},
|
||||
[ 6] = { 0, 128, 128},
|
||||
[ 7] = {192, 192, 192},
|
||||
[ 8] = {192, 220, 192},
|
||||
[ 9] = {166, 202, 240},
|
||||
[ 15] = {255, 255, 255},
|
||||
[246] = {255, 251, 240},
|
||||
[247] = {160, 160, 164},
|
||||
[248] = {128, 128, 128},
|
||||
[249] = {255, 0, 0},
|
||||
[250] = { 0, 255, 0},
|
||||
[251] = {255, 255, 0},
|
||||
[252] = { 0, 0, 255},
|
||||
[253] = {255, 0, 255},
|
||||
[254] = { 0, 255, 255},
|
||||
[255] = {255, 255, 255},
|
||||
};
|
||||
memcpy(nact->ags.pal, initial_palette, sizeof(initial_palette));
|
||||
sdl_setPalette(nact->ags.pal, 0, 256);
|
||||
palette_changed();
|
||||
}
|
||||
|
||||
boolean ags_check_param(int *x, int *y, int *w, int *h) {
|
||||
@@ -99,9 +120,8 @@ boolean ags_check_param_xy(int *x, int *y) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void ags_init(const char *render_driver) {
|
||||
nact->ags.mouse_movesw = MOUSE_WARP_SMOOTH;
|
||||
nact->ags.pal = &pal_256;
|
||||
void ags_init(const char *render_driver, bool enable_zb) {
|
||||
nact->ags.mouse_warp_enabled = true;
|
||||
nact->ags.world_size.width = SYS35_DEFAULT_WIDTH;
|
||||
nact->ags.world_size.height = SYS35_DEFAULT_HEIGHT;
|
||||
nact->ags.world_depth = SYS35_DEFAULT_DEPTH;
|
||||
@@ -109,11 +129,14 @@ void ags_init(const char *render_driver) {
|
||||
nact->ags.view_area.y = 0;
|
||||
nact->ags.view_area.w = SYS35_DEFAULT_WIDTH;
|
||||
nact->ags.view_area.h = SYS35_DEFAULT_HEIGHT;
|
||||
|
||||
nact->ags.enable_zb = enable_zb;
|
||||
nact->ags.font_weight = enable_zb ? FONT_WEIGHT_BOLD : FONT_WEIGHT_NORMAL;
|
||||
|
||||
sdl_Initialize(render_driver);
|
||||
font_init();
|
||||
|
||||
initPal(&pal_256);
|
||||
initPal();
|
||||
cg_init();
|
||||
}
|
||||
|
||||
@@ -123,9 +146,9 @@ void ags_remove(void) {
|
||||
}
|
||||
|
||||
void ags_reset(void) {
|
||||
nact->ags.mouse_movesw = MOUSE_WARP_SMOOTH;
|
||||
nact->ags.mouse_warp_enabled = true;
|
||||
nact->ags.eventcb = NULL;
|
||||
initPal(&pal_256);
|
||||
initPal();
|
||||
cg_reset();
|
||||
}
|
||||
|
||||
@@ -151,7 +174,7 @@ void ags_setWorldSize(int width, int height, int depth) {
|
||||
|
||||
fade_outed = FALSE; /* thanx tajiri@wizard */
|
||||
|
||||
nact->ags.pal_changed = TRUE;
|
||||
palette_changed();
|
||||
}
|
||||
|
||||
void ags_setViewArea(int x, int y, int width, int height) {
|
||||
@@ -162,19 +185,10 @@ void ags_setViewArea(int x, int y, int width, int height) {
|
||||
sdl_setWindowSize(width, height);
|
||||
}
|
||||
|
||||
void ags_setWindowTitle(const char *src) {
|
||||
#define TITLEHEAD "XSystem35 Version "VERSION":"
|
||||
uint8_t *utf, *d;
|
||||
|
||||
utf = toUTF8(src);
|
||||
if (NULL == (d = malloc(strlen(utf) + strlen(TITLEHEAD) + 1))) {
|
||||
NOMEMERR();
|
||||
}
|
||||
strcpy(d, TITLEHEAD);
|
||||
strcat(d, utf);
|
||||
sdl_setWindowTitle(d);
|
||||
free(utf);
|
||||
free(d);
|
||||
void ags_setWindowTitle(const char *title_utf8) {
|
||||
char buf[256];
|
||||
snprintf(buf, sizeof(buf), "XSystem35 Version %s: %s", VERSION, title_utf8);
|
||||
sdl_setWindowTitle(buf);
|
||||
}
|
||||
|
||||
void ags_getDIBInfo(DispInfo *info) {
|
||||
@@ -225,21 +239,18 @@ void ags_updateFull() {
|
||||
sdl_updateArea(&r, &p);
|
||||
}
|
||||
|
||||
void ags_setPalettes(Palette256 *src_pal, int src, int dst, int cnt) {
|
||||
int i;
|
||||
for (i = 0; i < cnt; i++) {
|
||||
nact->ags.pal->red [dst + i] = src_pal->red [src + i];
|
||||
nact->ags.pal->green[dst + i] = src_pal->green[src + i];
|
||||
nact->ags.pal->blue [dst + i] = src_pal->blue [src + i];
|
||||
void ags_setPalettes(Color *src, int dst, int cnt) {
|
||||
for (int i = 0; i < cnt; i++) {
|
||||
nact->ags.pal[dst + i] = src[i];
|
||||
}
|
||||
nact->ags.pal_changed = TRUE;
|
||||
palette_changed();
|
||||
}
|
||||
|
||||
void ags_setPalette(int no, int red, int green, int blue) {
|
||||
nact->ags.pal->red[no] = red;
|
||||
nact->ags.pal->green[no] = green;
|
||||
nact->ags.pal->blue[no] = blue;
|
||||
nact->ags.pal_changed = TRUE;
|
||||
nact->ags.pal[no].r = red;
|
||||
nact->ags.pal[no].g = green;
|
||||
nact->ags.pal[no].b = blue;
|
||||
palette_changed();
|
||||
}
|
||||
|
||||
void ags_setPaletteToSystem(int src, int cnt) {
|
||||
@@ -359,15 +370,6 @@ void ags_putRegion(void *region, int x, int y) {
|
||||
sdl_putRegion(region, x, y);
|
||||
}
|
||||
|
||||
void ags_copyRegion(void *region, int sx, int sy , int w, int h, int dx, int dy) {
|
||||
if (region == NULL) return;
|
||||
|
||||
if (!ags_check_param_xy(&dx, &dy)) return;
|
||||
if (!ags_check_param(&dx, &dy, &w, &h)) return;
|
||||
|
||||
sdl_CopyRegion(region, sx, sy, w, h, dx, dy);
|
||||
}
|
||||
|
||||
void ags_delRegion(void *region) {
|
||||
if (region == NULL) return;
|
||||
|
||||
@@ -541,7 +543,7 @@ void ags_runEffect(int duration_ms, boolean cancelable, ags_EffectStepFunc step,
|
||||
unsigned wflags = cancelable ? KEYWAIT_CANCELABLE : KEYWAIT_NONCANCELABLE;
|
||||
int start = sdl_getTicks();
|
||||
for (int t = 0; t < duration_ms; t = sdl_getTicks() - start) {
|
||||
step(arg, (double)t / duration_ms);
|
||||
step(arg, (float)t / duration_ms);
|
||||
int key = sys_keywait(start + t + 16 - sdl_getTicks(), wflags);
|
||||
if (cancelable && key) {
|
||||
nact->waitcancel_key = key;
|
||||
@@ -564,65 +566,67 @@ static void fade(int duration, boolean cancelable, enum sdl_effect_type type) {
|
||||
}
|
||||
|
||||
void ags_fadeIn(int rate, boolean flag) {
|
||||
int duration = rate * 16 * 1000 / 60;
|
||||
if (!need_update)
|
||||
duration = 0;
|
||||
fade_outed = FALSE;
|
||||
|
||||
if (nact->ags.world_depth == 8)
|
||||
sdl_setPalette(nact->ags.pal, 0, 256);
|
||||
|
||||
if (!need_update)
|
||||
return;
|
||||
|
||||
int duration = rate * 16 * 1000 / 60;
|
||||
fade(duration, flag, nact->ags.world_depth == 8 ? EFFECT_FADEIN : EFFECT_DITHERING_FADEIN);
|
||||
|
||||
sdl_updateAll(&nact->ags.view_area);
|
||||
}
|
||||
|
||||
void ags_fadeOut(int rate, boolean flag) {
|
||||
int duration = rate * 16 * 1000 / 60;
|
||||
if (!need_update || fade_outed)
|
||||
duration = 0;
|
||||
if (need_update && !fade_outed) {
|
||||
int duration = rate * 16 * 1000 / 60;
|
||||
fade(duration, flag, nact->ags.world_depth == 8 ? EFFECT_FADEOUT : EFFECT_DITHERING_FADEOUT);
|
||||
}
|
||||
fade_outed = TRUE;
|
||||
|
||||
fade(duration, flag, nact->ags.world_depth == 8 ? EFFECT_FADEOUT : EFFECT_DITHERING_FADEOUT);
|
||||
|
||||
if (nact->ags.world_depth == 8) {
|
||||
Palette256 pal;
|
||||
Color pal[256];
|
||||
memset(&pal, 0, sizeof(pal));
|
||||
sdl_setPalette(&pal, 0, 256);
|
||||
sdl_setPalette(pal, 0, 256);
|
||||
}
|
||||
}
|
||||
|
||||
void ags_whiteIn(int rate, boolean flag) {
|
||||
int duration = rate * 16 * 1000 / 60;
|
||||
if (!need_update)
|
||||
duration = 0;
|
||||
fade_outed = FALSE;
|
||||
|
||||
if (nact->ags.world_depth == 8)
|
||||
sdl_setPalette(nact->ags.pal, 0, 256);
|
||||
|
||||
if (!need_update)
|
||||
return;
|
||||
|
||||
int duration = rate * 16 * 1000 / 60;
|
||||
fade(duration, flag, nact->ags.world_depth == 8 ? EFFECT_WHITEIN : EFFECT_DITHERING_WHITEIN);
|
||||
|
||||
sdl_updateAll(&nact->ags.view_area);
|
||||
}
|
||||
|
||||
void ags_whiteOut(int rate, boolean flag) {
|
||||
int duration = rate * 16 * 1000 / 60;
|
||||
if (!need_update || fade_outed)
|
||||
duration = 0;
|
||||
if (need_update && !fade_outed) {
|
||||
int duration = rate * 16 * 1000 / 60;
|
||||
fade(duration, flag, nact->ags.world_depth == 8 ? EFFECT_WHITEIN : EFFECT_DITHERING_WHITEOUT);
|
||||
}
|
||||
fade_outed = TRUE;
|
||||
|
||||
fade(duration, flag, nact->ags.world_depth == 8 ? EFFECT_WHITEIN : EFFECT_DITHERING_WHITEOUT);
|
||||
|
||||
if (nact->ags.world_depth == 8) {
|
||||
Palette256 pal;
|
||||
Color pal[256];
|
||||
memset(&pal, 255, sizeof(pal));
|
||||
sdl_setPalette(&pal, 0, 256);
|
||||
sdl_setPalette(pal, 0, 256);
|
||||
}
|
||||
}
|
||||
|
||||
void ags_setFont(int type, int size) {
|
||||
font_select(type, size);
|
||||
font_select(type, size, FONT_WEIGHT_NORMAL);
|
||||
}
|
||||
|
||||
void ags_setFontWithWeight(int type, int size, int weight) {
|
||||
font_select(type, size, weight);
|
||||
}
|
||||
|
||||
void ags_setCursorType(int type) {
|
||||
@@ -636,42 +640,42 @@ void ags_loadCursor(int p1,int p2) {
|
||||
}
|
||||
}
|
||||
|
||||
void ags_setCursorLocation(int x, int y, boolean is_dibgeo) {
|
||||
int dx[8], dy[8];
|
||||
int i, delx, dely;
|
||||
MyPoint p;
|
||||
void ags_setCursorLocation(int x, int y, bool is_dibgeo, bool for_selection) {
|
||||
if (!ags_check_param_xy(&x, &y)) return;
|
||||
|
||||
/* DIB 座表系か Window 座表系か */
|
||||
if (is_dibgeo) {
|
||||
// DIB coordinates -> Window coordinates
|
||||
x -= nact->ags.view_area.x;
|
||||
y -= nact->ags.view_area.y;
|
||||
}
|
||||
|
||||
switch(nact->ags.mouse_movesw) {
|
||||
case MOUSE_WARP_DISABLED:
|
||||
return;
|
||||
case MOUSE_WARP_DIRECT:
|
||||
sdl_setCursorLocation(x, y); break;
|
||||
case MOUSE_WARP_SMOOTH:
|
||||
sys_getMouseInfo(&p, is_dibgeo);
|
||||
delx = x - p.x;
|
||||
dely = y - p.y;
|
||||
|
||||
for (i = 1; i < 8; i++) {
|
||||
dx[i-1] = ((delx*i*i*i) >> 9) - ((3*delx*i*i)>> 6) + ((3*delx*i) >> 3) + p.x;
|
||||
dy[i-1] = ((dely*i*i*i) >> 9) - ((3*dely*i*i)>> 6) + ((3*dely*i) >> 3) + p.y;
|
||||
}
|
||||
dx[7] = x; dy[7] = y;
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
sdl_setCursorLocation(dx[i], dy[i]);
|
||||
usleep(cursor_move_time * 1000 / 8);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
if (!for_selection) {
|
||||
// We can't move the actual cursor in the browser, but can change the
|
||||
// internal mouse coordinates. This can help with keyboard/gamepad
|
||||
// navigation.
|
||||
sdl_setCursorInternalLocation(x, y);
|
||||
EM_ASM({ xsystem35.shell.showMouseMoveEffect($0, $1); }, x, y);
|
||||
sdl_sleep(cursor_move_time);
|
||||
}
|
||||
#else
|
||||
if (nact->ags.mouse_warp_enabled) {
|
||||
MyPoint p;
|
||||
sys_getMouseInfo(&p, is_dibgeo);
|
||||
int dx = x - p.x;
|
||||
int dy = y - p.y;
|
||||
for (int i = 1; i < 8; i++) {
|
||||
int xi = ((dx*i*i*i) >> 9) - ((3*dx*i*i)>> 6) + ((3*dx*i) >> 3) + p.x;
|
||||
int yi = ((dy*i*i*i) >> 9) - ((3*dy*i*i)>> 6) + ((3*dy*i) >> 3) + p.y;
|
||||
sdl_setCursorLocation(xi, yi);
|
||||
sdl_sleep(cursor_move_time / 7);
|
||||
}
|
||||
sdl_setCursorLocation(x, y);
|
||||
} else if (!for_selection) {
|
||||
sdl_setCursorInternalLocation(x, y);
|
||||
sdl_sleep(cursor_move_time);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE
|
||||
|
||||
@@ -78,33 +78,30 @@ typedef struct agsurface agsurface_t;
|
||||
// for SDL_surface
|
||||
#define PIXEL_AT(suf, x, y) ((suf)->pixels + (y) * (suf)->pitch + (x) * (suf)->format->BytesPerPixel)
|
||||
|
||||
struct _agsevent {
|
||||
typedef struct {
|
||||
int type;
|
||||
int d1, d2, d3;
|
||||
int code;
|
||||
int mousex, mousey;
|
||||
} agsevent_t;
|
||||
|
||||
enum agsevent_type {
|
||||
AGSEVENT_MOUSE_MOTION,
|
||||
AGSEVENT_BUTTON_PRESS,
|
||||
AGSEVENT_BUTTON_RELEASE,
|
||||
AGSEVENT_KEY_PRESS,
|
||||
AGSEVENT_KEY_RELEASE,
|
||||
AGSEVENT_TIMER,
|
||||
AGSEVENT_MOUSE_WHEEL,
|
||||
};
|
||||
typedef struct _agsevent agsevent_t;
|
||||
|
||||
|
||||
#define AGSEVENT_MOUSE_MOTION 1
|
||||
#define AGSEVENT_BUTTON_PRESS 2
|
||||
#define AGSEVENT_BUTTON_RELEASE 3
|
||||
#define AGSEVENT_KEY_PRESS 4
|
||||
#define AGSEVENT_KEY_RELEASE 5
|
||||
#define AGSEVENT_TIMER 6
|
||||
#define AGSEVENT_MOUSE_WHEEL 7
|
||||
|
||||
#define AGSEVENT_BUTTON_LEFT 1
|
||||
#define AGSEVENT_BUTTON_MID 2
|
||||
#define AGSEVENT_BUTTON_RIGHT 3
|
||||
|
||||
enum mouse_warp_mode {
|
||||
MOUSE_WARP_DISABLED,
|
||||
MOUSE_WARP_DIRECT,
|
||||
MOUSE_WARP_SMOOTH,
|
||||
enum agsevent_button {
|
||||
AGSEVENT_BUTTON_LEFT,
|
||||
AGSEVENT_BUTTON_MID,
|
||||
AGSEVENT_BUTTON_RIGHT,
|
||||
};
|
||||
|
||||
struct _ags {
|
||||
Palette256 *pal; /* system palette */
|
||||
Color pal[256]; /* system palette */
|
||||
boolean pal_changed; /* system palette has changed */
|
||||
|
||||
MyDimension world_size; /* size of off-screen */
|
||||
@@ -113,11 +110,13 @@ struct _ags {
|
||||
|
||||
int world_depth; /* depth of off-screen (bits per pixel) */
|
||||
|
||||
enum mouse_warp_mode mouse_movesw;
|
||||
|
||||
agsurface_t *dib; /* main surface */
|
||||
void (*eventcb)(agsevent_t *e); /* deliver event */
|
||||
|
||||
int font_weight;
|
||||
|
||||
bool mouse_warp_enabled;
|
||||
bool enable_zb;
|
||||
boolean noantialias; /* antialias を使用しない */
|
||||
boolean noimagecursor; /* リソースファイルのカーソルを読みこまない */
|
||||
};
|
||||
@@ -126,14 +125,14 @@ typedef struct _ags ags_t;
|
||||
|
||||
|
||||
/* 初期化関係 */
|
||||
void ags_init(const char *render_driver);
|
||||
void ags_init(const char *render_driver, bool enable_zb);
|
||||
void ags_remove(void);
|
||||
void ags_reset(void);
|
||||
|
||||
/* ウィンド関係 */
|
||||
extern void ags_setWorldSize(int width, int height, int depth);
|
||||
extern void ags_setViewArea(int x, int y, int width, int height);
|
||||
extern void ags_setWindowTitle(const char *str);
|
||||
extern void ags_setWindowTitle(const char *title_utf8);
|
||||
extern void ags_getDIBInfo(DispInfo *info);
|
||||
extern void ags_getWindowInfo(DispInfo *info);
|
||||
extern void ags_getViewAreaInfo(DispInfo *info);
|
||||
@@ -147,7 +146,7 @@ extern void ags_updateFull(void);
|
||||
extern void ags_updateArea(int x, int y, int width, int height);
|
||||
|
||||
/* パレット関係 */
|
||||
extern void ags_setPalettes(Palette256 *src_pal, int src, int dst, int cnt);
|
||||
extern void ags_setPalettes(Color *src, int dst, int cnt);
|
||||
extern void ags_setPalette(int no, int red, int green, int blue);
|
||||
extern void ags_setPaletteToSystem(int src, int cnt);
|
||||
|
||||
@@ -168,7 +167,6 @@ extern void ags_changeColorArea(int x, int y, int w, int h, int dst, int src, in
|
||||
extern void* ags_saveRegion(int x, int y, int w, int h);
|
||||
extern void ags_restoreRegion(void *region, int x, int y);
|
||||
extern void ags_putRegion(void *region, int x, int y);
|
||||
extern void ags_copyRegion(void *region, int sx, int sy, int w,int h,int dx,int dy);
|
||||
extern void ags_delRegion(void *region);
|
||||
|
||||
extern MyRectangle ags_drawString(int x, int y, const char *src, int col);
|
||||
@@ -179,7 +177,8 @@ extern void ags_copyArea_transparent(int sx, int sy, int w, int h, int dx, int d
|
||||
extern void ags_copyArea_alphaLevel(int sx, int sy, int w, int h, int dx, int dy, int lv);
|
||||
extern void ags_copyArea_alphaBlend(int sx, int sy, int w, int h, int dx, int dy, int lv);
|
||||
extern MyRectangle ags_floodFill(int x, int y, int col);
|
||||
extern void ags_eCopyArea(int sx, int sy, int w, int h, int dx, int dy, int type, int opt, boolean flg, int spCol);
|
||||
extern void ags_eCopyArea(int sx, int sy, int w, int h, int dx, int dy, int sw, int opt, bool cancel);
|
||||
extern void ags_eSpriteCopyArea(int sx, int sy, int w, int h, int dx, int dy, int sw, int opt, bool cancel, int spCol);
|
||||
|
||||
/* alpha channel 操作 */
|
||||
extern void ags_copyFromAlpha(int sx, int sy, int w, int h, int dx, int dy, ALPHA_DIB_COPY_TYPE flg);
|
||||
@@ -203,12 +202,13 @@ enum FontType {
|
||||
FONT_MINCHO,
|
||||
};
|
||||
extern void ags_setFont(int type, int size);
|
||||
extern void ags_setFontWithWeight(int type, int size, int weight);
|
||||
extern agsurface_t *ags_drawStringToSurface(const char *str);
|
||||
|
||||
/* カーソル関係 */
|
||||
extern void ags_setCursorType(int type);
|
||||
extern void ags_loadCursor(int ,int);
|
||||
extern void ags_setCursorLocation(int x, int y, boolean dibgeo);
|
||||
extern void ags_setCursorLocation(int x, int y, bool is_dibgeo, bool for_selection);
|
||||
extern void ags_setCursorMoveTime(int msec);
|
||||
extern int ags_getCursorMoveTime();
|
||||
|
||||
@@ -217,7 +217,7 @@ extern void ags_setAntialiasedStringMode(boolean mode);
|
||||
extern boolean ags_getAntialiasedStringMode();
|
||||
extern void ags_autorepeat(boolean enable);
|
||||
|
||||
typedef void (*ags_EffectStepFunc)(void *, double);
|
||||
typedef void (*ags_EffectStepFunc)(void *, float);
|
||||
void ags_runEffect(int duration_ms, boolean cancelable, ags_EffectStepFunc step, void *arg);
|
||||
|
||||
#define RMASK16 0xf800
|
||||
|
||||
+1
-1
@@ -108,5 +108,5 @@ void ald_init(int type, const char **file, int cnt, boolean use_mmap) {
|
||||
int ald_get_maxno(DRIFILETYPE type) {
|
||||
if (type >= DRIFILETYPEMAX || !dri[type])
|
||||
return 0;
|
||||
return dri[type]->nr_files;
|
||||
return dri[type]->maxno;
|
||||
}
|
||||
|
||||
@@ -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,12 +0,0 @@
|
||||
#define curbm0_width 32
|
||||
#define curbm0_height 32
|
||||
static char curbm0_bits[] = {
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,
|
||||
0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x28,0x00,0x00,0x00,0x48,0x00,0x00,0x00,
|
||||
0x88,0x00,0x00,0x00,0x08,0x01,0x00,0x00,0x08,0x02,0x00,0x00,0x08,0x04,0x00,
|
||||
0x00,0x08,0x08,0x00,0x00,0x08,0x10,0x00,0x00,0x08,0x3e,0x00,0x00,0x48,0x02,
|
||||
0x00,0x00,0xa8,0x04,0x00,0x00,0x98,0x04,0x00,0x00,0x08,0x09,0x00,0x00,0x00,
|
||||
0x09,0x00,0x00,0x00,0x12,0x00,0x00,0x00,0x12,0x00,0x00,0x00,0x0c,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
|
||||
@@ -1,12 +0,0 @@
|
||||
#define curbm1_width 32
|
||||
#define curbm1_height 32
|
||||
static char curbm1_bits[] = {
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xf3,0x9f,0xff,0xff,0xf5,0x5f,0xff,0xff,0xf6,0xdf,0xfe,
|
||||
0x7f,0x07,0xc0,0xfd,0xbf,0xff,0xff,0xfb,0x7f,0x07,0xc0,0xfd,0xff,0xf6,0xdf,
|
||||
0xfe,0xff,0xf5,0x5f,0xff,0xff,0xf3,0x9f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};
|
||||
@@ -1,12 +0,0 @@
|
||||
#define curbm2_width 32
|
||||
#define curbm2_height 32
|
||||
static char curbm2_bits[] = {
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,
|
||||
0xff,0xff,0xff,0xbf,0xfe,0xff,0xff,0xdf,0xfd,0xff,0xff,0xef,0xfb,0xff,0xff,
|
||||
0xf7,0xf7,0xff,0xff,0x87,0xf0,0xff,0xff,0xbf,0xfe,0xff,0xff,0xbf,0xfe,0xff,
|
||||
0xff,0xbf,0xfe,0xff,0xff,0xbf,0xfe,0xff,0xff,0xbf,0xfe,0xff,0xff,0xbf,0xfe,
|
||||
0xff,0xff,0xbf,0xfe,0xff,0xff,0xbf,0xfe,0xff,0xff,0x87,0xf0,0xff,0xff,0xf7,
|
||||
0xf7,0xff,0xff,0xef,0xfb,0xff,0xff,0xdf,0xfd,0xff,0xff,0xbf,0xfe,0xff,0xff,
|
||||
0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};
|
||||
@@ -1,12 +0,0 @@
|
||||
#define curbm3_width 32
|
||||
#define curbm3_height 32
|
||||
static char curbm3_bits[] = {
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x01,0xff,0xff,0xff,0x7d,0xff,0xff,0xff,
|
||||
0xbd,0xff,0xff,0xff,0xdd,0xff,0xff,0xff,0xad,0xff,0xff,0xff,0x55,0xff,0xff,
|
||||
0xff,0xb9,0xfe,0xff,0xff,0x7f,0xfd,0xff,0xff,0xff,0x3a,0xff,0xff,0xff,0x55,
|
||||
0xff,0xff,0xff,0x6b,0xff,0xff,0xff,0x77,0xff,0xff,0xff,0x7b,0xff,0xff,0xff,
|
||||
0x7d,0xff,0xff,0xff,0x01,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};
|
||||
@@ -1,12 +0,0 @@
|
||||
#define curbm4_width 32
|
||||
#define curbm4_height 32
|
||||
static char curbm4_bits[] = {
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x80,0xff,0xff,0xff,0xbe,0xff,0xff,
|
||||
0xff,0xbd,0xff,0xff,0xff,0xbb,0xff,0xff,0xff,0xb5,0xff,0xff,0xff,0xaa,0xff,
|
||||
0xff,0x7f,0x9d,0xff,0xff,0xbf,0xfe,0xff,0xff,0x5c,0xff,0xff,0xff,0xaa,0xff,
|
||||
0xff,0xff,0xd6,0xff,0xff,0xff,0xee,0xff,0xff,0xff,0xde,0xff,0xff,0xff,0xbe,
|
||||
0xff,0xff,0xff,0x80,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};
|
||||
@@ -1,12 +0,0 @@
|
||||
#define curbm5_width 32
|
||||
#define curbm5_height 32
|
||||
static char curbm5_bits[] = {
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0x00,0x80,0xff,0xff,0xfe,0xbf,0xff,0xff,0x06,0xb0,0xff,0xff,0xfe,
|
||||
0xbf,0xff,0xff,0x05,0xd0,0xff,0xff,0x05,0xd0,0xff,0xff,0xa5,0xd2,0xff,0xff,
|
||||
0x45,0xd1,0xff,0xff,0x8d,0xd8,0xff,0xff,0x1b,0xec,0xff,0xff,0xb7,0xf6,0xff,
|
||||
0xff,0x6f,0xfb,0xff,0xff,0x6f,0xfb,0xff,0xff,0x37,0xf6,0xff,0xff,0x9b,0xec,
|
||||
0xff,0xff,0x0d,0xd8,0xff,0xff,0x85,0xd0,0xff,0xff,0x45,0xd1,0xff,0xff,0xa5,
|
||||
0xd2,0xff,0xff,0x55,0xd5,0xff,0xff,0xfe,0xbf,0xff,0xff,0x06,0xb0,0xff,0xff,
|
||||
0xfe,0xbf,0xff,0xff,0x00,0x80,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};
|
||||
@@ -1,12 +0,0 @@
|
||||
#define curbm6_width 32
|
||||
#define curbm6_height 32
|
||||
static char curbm6_bits[] = {
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xfe,0xff,0xff,0x7f,0xfd,0xff,0xff,0xbf,0xfb,0xff,0xff,0xdf,
|
||||
0xf7,0xff,0xff,0xef,0xef,0xff,0xff,0x0f,0xe0,0xff,0xff,0x7f,0xfd,0xff,0xff,
|
||||
0x7f,0xfd,0xff,0xff,0x7c,0x7d,0xfe,0x7f,0x7d,0x7d,0xfd,0xbf,0x7d,0x7d,0xfb,
|
||||
0xdf,0x01,0x01,0xf7,0xef,0xfd,0x7f,0xef,0xdf,0x01,0x01,0xf7,0xbf,0x7d,0x7d,
|
||||
0xfb,0x7f,0x7d,0x7d,0xfd,0xff,0x7c,0x7d,0xfe,0xff,0x7f,0xfd,0xff,0xff,0x7f,
|
||||
0xfd,0xff,0xff,0x0f,0xe0,0xff,0xff,0xef,0xef,0xff,0xff,0xdf,0xf7,0xff,0xff,
|
||||
0xbf,0xfb,0xff,0xff,0x7f,0xfd,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};
|
||||
@@ -1,43 +0,0 @@
|
||||
/* XPM */
|
||||
static const char *cursor_arrow[] = {
|
||||
/* width height num_colors chars_per_pixel */
|
||||
" 32 32 3 1",
|
||||
/* colors */
|
||||
"X c #000000",
|
||||
". c #ffffff",
|
||||
" c None",
|
||||
/* pixels */
|
||||
"X ",
|
||||
"XX ",
|
||||
"X.X ",
|
||||
"X..X ",
|
||||
"X...X ",
|
||||
"X....X ",
|
||||
"X.....X ",
|
||||
"X......X ",
|
||||
"X.......X ",
|
||||
"X........X ",
|
||||
"X.....XXXXX ",
|
||||
"X..X..X ",
|
||||
"X.X X..X ",
|
||||
"XX X..X ",
|
||||
"X X..X ",
|
||||
" X..X ",
|
||||
" X..X ",
|
||||
" X..X ",
|
||||
" XX ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
"0,0"
|
||||
};
|
||||
@@ -1,42 +0,0 @@
|
||||
/* XPM */
|
||||
static const char *cursor_busy[] = {
|
||||
/* columns rows colors chars-per-pixel */
|
||||
"32 32 3 1",
|
||||
"X c #ffffff",
|
||||
". c #000000",
|
||||
" c None",
|
||||
/* pixels */
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" XXXXXXXXXXXXXXXXX ",
|
||||
" X...............X ",
|
||||
" X.XXXXXXXXXXXXX.X ",
|
||||
" X.XX.........XX.X ",
|
||||
" X.XXXXXXXXXXXXX.X ",
|
||||
" X.X.........X.X ",
|
||||
" X.X.........X.X ",
|
||||
" X.X..X.X.X..X.X ",
|
||||
" X.X...X.X...X.X ",
|
||||
" X.XX...X...XX.X ",
|
||||
" X.XX.....XX.X ",
|
||||
" X.XX.X.XX.X ",
|
||||
" X.XX.XX.X ",
|
||||
" X.XX.XX.X ",
|
||||
" X.XX...XX.X ",
|
||||
" X.XX..X..XX.X ",
|
||||
" X.XX.......XX.X ",
|
||||
" X.X....X....X.X ",
|
||||
" X.X...X.X...X.X ",
|
||||
" X.X..X.X.X..X.X ",
|
||||
" X.X.X.X.X.X.X.X ",
|
||||
" X.XXXXXXXXXXXXX.X ",
|
||||
" X.XX.........XX.X ",
|
||||
" X.XXXXXXXXXXXXX.X ",
|
||||
" X...............X ",
|
||||
" XXXXXXXXXXXXXXXXX ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
"15,15"
|
||||
};
|
||||
@@ -1,43 +0,0 @@
|
||||
/* XPM */
|
||||
static const char *cursor_cross[] = {
|
||||
/* width height num_colors chars_per_pixel */
|
||||
" 32 32 3 1",
|
||||
/* colors */
|
||||
"X c #000000",
|
||||
". c #ffffff",
|
||||
" c None",
|
||||
/* pixels */
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" XXXX ",
|
||||
" X..X ",
|
||||
" X..X ",
|
||||
" X..X ",
|
||||
" X..X ",
|
||||
" X..X ",
|
||||
" X..X ",
|
||||
" X..X ",
|
||||
" XXXXXXXXX..XXXXXXXXX ",
|
||||
" X..................X ",
|
||||
" X..................X ",
|
||||
" XXXXXXXXX..XXXXXXXXX ",
|
||||
" X..X ",
|
||||
" X..X ",
|
||||
" X..X ",
|
||||
" X..X ",
|
||||
" X..X ",
|
||||
" X..X ",
|
||||
" X..X ",
|
||||
" XXXX ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
"15,15"
|
||||
};
|
||||
@@ -1,43 +0,0 @@
|
||||
/* XPM */
|
||||
static const char *cursor_ibeam[] = {
|
||||
/* width height num_colors chars_per_pixel */
|
||||
" 32 32 3 1",
|
||||
/* colors */
|
||||
". c #000000",
|
||||
"X c #ffffff",
|
||||
" c None",
|
||||
/* pixels */
|
||||
" XXX XXX ",
|
||||
" XXX ",
|
||||
" X.X ",
|
||||
" X.X ",
|
||||
" X.X ",
|
||||
" X.X ",
|
||||
" X.X ",
|
||||
" X.X ",
|
||||
" X.X ",
|
||||
" X.X ",
|
||||
" X.X ",
|
||||
" X.X ",
|
||||
" X.X ",
|
||||
" X.X ",
|
||||
" X.X ",
|
||||
" X.X ",
|
||||
" X.X ",
|
||||
" X.X ",
|
||||
" X.X ",
|
||||
" X.X ",
|
||||
" X.X ",
|
||||
" X.X ",
|
||||
" X.X ",
|
||||
" X.X ",
|
||||
" X.X ",
|
||||
" X.X ",
|
||||
" X.X ",
|
||||
" X.X ",
|
||||
" X.X ",
|
||||
" XXX ",
|
||||
" XXX XXX ",
|
||||
" ",
|
||||
"15,15"
|
||||
};
|
||||
@@ -1,42 +0,0 @@
|
||||
/* XPM */
|
||||
static const char *cursor_move[] = {
|
||||
/* columns rows colors chars-per-pixel */
|
||||
"32 32 3 1",
|
||||
"X c #ffffff",
|
||||
". c #000000",
|
||||
" c None",
|
||||
/* pixels */
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" X ",
|
||||
" X.X ",
|
||||
" X...X ",
|
||||
" X.....X ",
|
||||
" X.......X ",
|
||||
" XXXXXXXXX ",
|
||||
" X.X ",
|
||||
" X.X ",
|
||||
" XX X.X XX ",
|
||||
" X.X X.X X.X ",
|
||||
" X..X X.X X..X ",
|
||||
" X...XXXXXXX.XXXXXXX...X ",
|
||||
" X....X.............X....X ",
|
||||
" X...XXXXXXX.XXXXXXX...X ",
|
||||
" X..X X.X X..X ",
|
||||
" X.X X.X X.X ",
|
||||
" XX X.X XX ",
|
||||
" X.X ",
|
||||
" X.X ",
|
||||
" XXXXXXXXX ",
|
||||
" X.......X ",
|
||||
" X.....X ",
|
||||
" X...X ",
|
||||
" X.X ",
|
||||
" X ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
"15,15"
|
||||
};
|
||||
@@ -1,42 +0,0 @@
|
||||
/* XPM */
|
||||
static const char *cursor_no[] = {
|
||||
/* columns rows colors chars-per-pixel */
|
||||
"32 32 3 1",
|
||||
"X c #ffffff",
|
||||
". c #000000",
|
||||
" c None",
|
||||
/* pixels */
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ...... ",
|
||||
" ..XXXXXX.. ",
|
||||
" .XXXXXXXXX . ",
|
||||
" .XXXX....XXX . ",
|
||||
" .XXX.. ..XXX. ",
|
||||
" .XXXXX. .XXX. ",
|
||||
" .XX.XXX. .XX. ",
|
||||
" .XXX..XXX. .XXX. ",
|
||||
" .XX. .XXX. .XX. ",
|
||||
" .XX. .XXX. .XX. ",
|
||||
" .XX. .XXX. .XX. ",
|
||||
" .XX. .XXX. .XX. ",
|
||||
" .XXX. .XXX..XXX. ",
|
||||
" .XX . .XX.XX. ",
|
||||
" .XXX. .XXXXX. ",
|
||||
" .XXX.. ..XXX. ",
|
||||
" .XXXX....XXXX. ",
|
||||
" .XXXXXXXXXX. ",
|
||||
" ..XXXXXX.. ",
|
||||
" ...... ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
"16,16"
|
||||
};
|
||||
@@ -1,42 +0,0 @@
|
||||
/* XPM */
|
||||
static const char *cursor_size_h[] = {
|
||||
/* columns rows colors chars-per-pixel */
|
||||
"32 32 3 1",
|
||||
". c #000000",
|
||||
"X c #ffffff",
|
||||
" c None",
|
||||
/* pixels */
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" XX XX ",
|
||||
" X.X X.X ",
|
||||
" X..X X..X ",
|
||||
" X...XXXXXXXXXXX...X ",
|
||||
" X...................X ",
|
||||
" X...XXXXXXXXXXX...X ",
|
||||
" X..X X..X ",
|
||||
" X.X X.X ",
|
||||
" XX XX ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
"15,15"
|
||||
};
|
||||
@@ -1,42 +0,0 @@
|
||||
/* XPM */
|
||||
static const char *cursor_size_l[] = {
|
||||
/* columns rows colors chars-per-pixel */
|
||||
"32 32 3 1",
|
||||
". c #000000",
|
||||
"X c #ffffff",
|
||||
" c None",
|
||||
/* pixels */
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" XXXXXXX ",
|
||||
" X.....X ",
|
||||
" X....X ",
|
||||
" X...X ",
|
||||
" X..X.X ",
|
||||
" X.X X.X ",
|
||||
" XX X.X ",
|
||||
" X.X ",
|
||||
" X.X XX ",
|
||||
" X.X X.X ",
|
||||
" X.X..X ",
|
||||
" X...X ",
|
||||
" X....X ",
|
||||
" X.... X ",
|
||||
" XXXXXXX ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
"15,15"
|
||||
};
|
||||
@@ -1,42 +0,0 @@
|
||||
/* XPM */
|
||||
static const char *cursor_size_r[] = {
|
||||
/* columns rows colors chars-per-pixel */
|
||||
"32 32 3 1",
|
||||
". c #000000",
|
||||
"X c #ffffff",
|
||||
" c None",
|
||||
/* pixels */
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" XXXXXXX ",
|
||||
" X.....X ",
|
||||
" X....X ",
|
||||
" X...X ",
|
||||
" X.X..X ",
|
||||
" X.X X.X ",
|
||||
" X.X XX ",
|
||||
" X.X ",
|
||||
" XX X.X ",
|
||||
" X.X X.X ",
|
||||
" X..X.X ",
|
||||
" X...X ",
|
||||
" X....X ",
|
||||
" X.....X ",
|
||||
" XXXXXXX ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
"15,15"
|
||||
};
|
||||
@@ -1,42 +0,0 @@
|
||||
/* XPM */
|
||||
static const char *cursor_size_v[] = {
|
||||
/* columns rows colors chars-per-pixel */
|
||||
"32 32 3 1",
|
||||
". c #000000",
|
||||
"X c #ffffff",
|
||||
" c None",
|
||||
/* pixels */
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" X ",
|
||||
" X.X ",
|
||||
" X...X ",
|
||||
" X.....X ",
|
||||
" X.......X ",
|
||||
" XXXX.XXXX ",
|
||||
" X.X ",
|
||||
" X.X ",
|
||||
" X.X ",
|
||||
" X.X ",
|
||||
" X.X ",
|
||||
" X.X ",
|
||||
" X.X ",
|
||||
" X.X ",
|
||||
" XXXX XXXX ",
|
||||
" X.......X ",
|
||||
" X.....X ",
|
||||
" X...X ",
|
||||
" X/X ",
|
||||
" X ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
"15,15"
|
||||
};
|
||||
@@ -1,12 +0,0 @@
|
||||
#define maskbm0_width 32
|
||||
#define maskbm0_height 32
|
||||
static char maskbm0_bits[] = {
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,
|
||||
0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x78,0x00,0x00,0x00,
|
||||
0xf8,0x00,0x00,0x00,0xf8,0x01,0x00,0x00,0xf8,0x03,0x00,0x00,0xf8,0x07,0x00,
|
||||
0x00,0xf8,0x0f,0x00,0x00,0xf8,0x1f,0x00,0x00,0xf8,0x3f,0x00,0x00,0xf8,0x03,
|
||||
0x00,0x00,0xb8,0x07,0x00,0x00,0x98,0x07,0x00,0x00,0x08,0x0f,0x00,0x00,0x00,
|
||||
0x0f,0x00,0x00,0x00,0x1e,0x00,0x00,0x00,0x1e,0x00,0x00,0x00,0x0c,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
|
||||
@@ -1,12 +0,0 @@
|
||||
#define maskbm1_width 32
|
||||
#define maskbm1_height 32
|
||||
static char maskbm1_bits[] = {
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x0c,0x60,0x00,0x00,0x0e,0xe0,0x00,0x00,0x0f,0xe0,0x01,
|
||||
0x80,0xff,0xff,0x03,0xc0,0xff,0xff,0x07,0x80,0xff,0xff,0x03,0x00,0x0f,0xe0,
|
||||
0x01,0x00,0x0e,0xe0,0x00,0x00,0x0c,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
|
||||
@@ -1,12 +0,0 @@
|
||||
#define maskbm2_width 32
|
||||
#define maskbm2_height 32
|
||||
static char maskbm2_bits[] = {
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,
|
||||
0x00,0x00,0x00,0xc0,0x01,0x00,0x00,0xe0,0x03,0x00,0x00,0xf0,0x07,0x00,0x00,
|
||||
0xf8,0x0f,0x00,0x00,0xf8,0x0f,0x00,0x00,0xc0,0x01,0x00,0x00,0xc0,0x01,0x00,
|
||||
0x00,0xc0,0x01,0x00,0x00,0xc0,0x01,0x00,0x00,0xc0,0x01,0x00,0x00,0xc0,0x01,
|
||||
0x00,0x00,0xc0,0x01,0x00,0x00,0xc0,0x01,0x00,0x00,0xf8,0x0f,0x00,0x00,0xf8,
|
||||
0x0f,0x00,0x00,0xf0,0x07,0x00,0x00,0xe0,0x03,0x00,0x00,0xc0,0x01,0x00,0x00,
|
||||
0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
|
||||
@@ -1,12 +0,0 @@
|
||||
#define maskbm3_width 32
|
||||
#define maskbm3_height 32
|
||||
static char maskbm3_bits[] = {
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0x00,0x00,0x00,0xfe,0x00,0x00,0x00,
|
||||
0x7e,0x00,0x00,0x00,0x3e,0x00,0x00,0x00,0x7e,0x00,0x00,0x00,0xee,0x00,0x00,
|
||||
0x00,0xc6,0x01,0x00,0x00,0x80,0x03,0x00,0x00,0x00,0xc7,0x00,0x00,0x00,0xee,
|
||||
0x00,0x00,0x00,0xfc,0x00,0x00,0x00,0xf8,0x00,0x00,0x00,0xfc,0x00,0x00,0x00,
|
||||
0xfe,0x00,0x00,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
|
||||
@@ -1,12 +0,0 @@
|
||||
#define maskbm4_width 32
|
||||
#define maskbm4_height 32
|
||||
static char maskbm4_bits[] = {
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7f,0x00,0x00,0x00,0x7f,0x00,0x00,
|
||||
0x00,0x7e,0x00,0x00,0x00,0x7c,0x00,0x00,0x00,0x7e,0x00,0x00,0x00,0x77,0x00,
|
||||
0x00,0x80,0x63,0x00,0x00,0xc0,0x01,0x00,0x00,0xe3,0x00,0x00,0x00,0x77,0x00,
|
||||
0x00,0x00,0x3f,0x00,0x00,0x00,0x1f,0x00,0x00,0x00,0x3f,0x00,0x00,0x00,0x7f,
|
||||
0x00,0x00,0x00,0x7f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
|
||||
@@ -1,12 +0,0 @@
|
||||
#define maskbm5_width 32
|
||||
#define maskbm5_height 32
|
||||
static char maskbm5_bits[] = {
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0xff,0x7f,0x00,0x00,0xff,0x7f,0x00,0x00,0xff,0x7f,0x00,0x00,0xff,
|
||||
0x7f,0x00,0x00,0xfe,0x3f,0x00,0x00,0xfe,0x3f,0x00,0x00,0xfe,0x3f,0x00,0x00,
|
||||
0xfe,0x3f,0x00,0x00,0xfe,0x3f,0x00,0x00,0xfc,0x1f,0x00,0x00,0xf8,0x0f,0x00,
|
||||
0x00,0xf0,0x07,0x00,0x00,0xf0,0x07,0x00,0x00,0xf8,0x0f,0x00,0x00,0xfc,0x1f,
|
||||
0x00,0x00,0xfe,0x3f,0x00,0x00,0xfe,0x3f,0x00,0x00,0xfe,0x3f,0x00,0x00,0xfe,
|
||||
0x3f,0x00,0x00,0xfe,0x3f,0x00,0x00,0xff,0x7f,0x00,0x00,0xff,0x7f,0x00,0x00,
|
||||
0xff,0x7f,0x00,0x00,0xff,0x7f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
|
||||
@@ -1,12 +0,0 @@
|
||||
#define maskbm6_width 32
|
||||
#define maskbm6_height 32
|
||||
static char maskbm6_bits[] = {
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x01,0x00,0x00,0x80,0x03,0x00,0x00,0xc0,0x07,0x00,0x00,0xe0,
|
||||
0x0f,0x00,0x00,0xf0,0x1f,0x00,0x00,0xf0,0x1f,0x00,0x00,0x80,0x03,0x00,0x00,
|
||||
0x80,0x03,0x00,0x00,0x83,0x83,0x01,0x80,0x83,0x83,0x03,0xc0,0x83,0x83,0x07,
|
||||
0xe0,0xff,0xff,0x0f,0xf0,0xff,0xff,0x1f,0xe0,0xff,0xff,0x0f,0xc0,0x83,0x83,
|
||||
0x07,0x80,0x83,0x83,0x03,0x00,0x83,0x83,0x01,0x00,0x80,0x03,0x00,0x00,0x80,
|
||||
0x03,0x00,0x00,0xf0,0x1f,0x00,0x00,0xf0,0x1f,0x00,0x00,0xe0,0x0f,0x00,0x00,
|
||||
0xc0,0x07,0x00,0x00,0x80,0x03,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
|
||||
@@ -36,7 +36,6 @@
|
||||
* static methods
|
||||
*/
|
||||
static bmp_header *extract_header(uint8_t *b);
|
||||
static void getpal(Palette256 *pal, uint8_t *b);
|
||||
static void extract_8bit(bmp_header *bmp, uint8_t *pic, uint8_t *b);
|
||||
static void extract_24bit(bmp_header *bmp, uint16_t *pic, uint8_t *b);
|
||||
|
||||
@@ -65,17 +64,16 @@ static bmp_header *extract_header(uint8_t *b) {
|
||||
|
||||
/*
|
||||
* Get palette from raw data
|
||||
* pal: palette to be stored
|
||||
* b : raw data (pointer to palette)
|
||||
*/
|
||||
static void getpal(Palette256 *pal, uint8_t *b) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 256; i++) {
|
||||
pal->blue[i] = *b++;
|
||||
pal->red[i] = *b++;
|
||||
pal->green[i] = *b++;
|
||||
static Color *getpal(uint8_t *b) {
|
||||
Color *pal = malloc(sizeof(Color) * 256);
|
||||
for (int i = 0; i < 256; i++) {
|
||||
pal[i].b = *b++;
|
||||
pal[i].r = *b++;
|
||||
pal[i].g = *b++;
|
||||
}
|
||||
return pal;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -168,8 +166,7 @@ cgdata *bmp256_extract(uint8_t *data) {
|
||||
bmp_header *bmp = extract_header(data);
|
||||
cgdata *cg = calloc(1, sizeof(cgdata));
|
||||
|
||||
cg->pal = malloc(sizeof(Palette256));
|
||||
getpal(cg->pal, data + bmp->bmpPp);
|
||||
cg->pal = getpal(data + bmp->bmpPp);
|
||||
|
||||
/* +10: margin for broken cg */
|
||||
cg->pic = malloc(sizeof(uint8_t) * ((bmp->bmpXW + 10) * (bmp->bmpYW + 10)));
|
||||
|
||||
@@ -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,102 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2020 <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 <SDL.h>
|
||||
#include <jni.h>
|
||||
#include "system.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_android
|
||||
cdromdevice_t cdrom = {
|
||||
cdrom_init,
|
||||
cdrom_exit,
|
||||
cdrom_reset,
|
||||
cdrom_start,
|
||||
cdrom_stop,
|
||||
cdrom_getPlayingInfo,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
int cdrom_init(char *name) {
|
||||
return OK;
|
||||
}
|
||||
|
||||
int cdrom_reset(void) {
|
||||
cdrom_stop();
|
||||
return OK;
|
||||
}
|
||||
|
||||
int cdrom_exit(void) {
|
||||
cdrom_stop();
|
||||
return OK;
|
||||
}
|
||||
|
||||
int cdrom_start(int trk, int loop) {
|
||||
JNIEnv *env = SDL_AndroidGetJNIEnv();
|
||||
if ((*env)->PushLocalFrame(env, 16) < 0) {
|
||||
WARNING("Failed to allocate JVM local references");
|
||||
return NG;
|
||||
}
|
||||
jobject context = SDL_AndroidGetActivity();
|
||||
jmethodID mid = (*env)->GetMethodID(env, (*env)->GetObjectClass(env, context),
|
||||
"cddaStart", "(IZ)V");
|
||||
(*env)->CallVoidMethod(env, context, mid, trk, loop == 0);
|
||||
(*env)->PopLocalFrame(env, NULL);
|
||||
return OK;
|
||||
}
|
||||
|
||||
int cdrom_stop() {
|
||||
JNIEnv *env = SDL_AndroidGetJNIEnv();
|
||||
if ((*env)->PushLocalFrame(env, 16) < 0) {
|
||||
WARNING("Failed to allocate JVM local references");
|
||||
return NG;
|
||||
}
|
||||
jobject context = SDL_AndroidGetActivity();
|
||||
jmethodID mid = (*env)->GetMethodID(env, (*env)->GetObjectClass(env, context),
|
||||
"cddaStop", "()V");
|
||||
(*env)->CallVoidMethod(env, context, mid);
|
||||
(*env)->PopLocalFrame(env, NULL);
|
||||
return OK;
|
||||
}
|
||||
|
||||
int cdrom_getPlayingInfo (cd_time *info) {
|
||||
JNIEnv *env = SDL_AndroidGetJNIEnv();
|
||||
if ((*env)->PushLocalFrame(env, 16) < 0) {
|
||||
WARNING("Failed to allocate JVM local references");
|
||||
return NG;
|
||||
}
|
||||
jobject context = SDL_AndroidGetActivity();
|
||||
jmethodID mid = (*env)->GetMethodID(env, (*env)->GetObjectClass(env, context),
|
||||
"cddaCurrentPosition", "()I");
|
||||
int t = (*env)->CallIntMethod(env, context, mid);
|
||||
(*env)->PopLocalFrame(env, NULL);
|
||||
|
||||
info->t = t & 0xff;
|
||||
FRAMES_TO_MSF(t >> 8, &info->m, &info->s, &info->f);
|
||||
return OK;
|
||||
}
|
||||
+4
-1
@@ -22,11 +22,14 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#include "cdrom.h"
|
||||
#include "ald_manager.h"
|
||||
#include "music.h"
|
||||
#include "music_private.h"
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
-75
@@ -1,75 +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
|
||||
|
||||
#elif defined(ENABLE_CDROM_ANDROID)
|
||||
extern cdromdevice_t cdrom_android;
|
||||
#define NATIVE_CD_DEVICE &cdrom_android
|
||||
|
||||
#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) || defined(ENABLE_CDROM_ANDROID)
|
||||
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 || ENABLE_CDROM_ANDROID
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
+22
-30
@@ -27,36 +27,7 @@
|
||||
|
||||
static int frame_of_getpos = -1;
|
||||
|
||||
static int cdrom_init(char *);
|
||||
static int cdrom_exit(void);
|
||||
static int cdrom_reset(void);
|
||||
extern int cdrom_start(int, int);
|
||||
extern int cdrom_stop();
|
||||
static int cdrom_getPlayingInfo(cd_time *);
|
||||
|
||||
#define cdrom cdrom_emscripten
|
||||
cdromdevice_t cdrom = {
|
||||
cdrom_init,
|
||||
cdrom_exit,
|
||||
cdrom_reset,
|
||||
cdrom_start,
|
||||
cdrom_stop,
|
||||
cdrom_getPlayingInfo,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
int cdrom_init(char *name) {
|
||||
return OK;
|
||||
}
|
||||
|
||||
int cdrom_exit(void) {
|
||||
cdrom_stop();
|
||||
return OK;
|
||||
}
|
||||
|
||||
int cdrom_reset(void) {
|
||||
cdrom_stop();
|
||||
int cdrom_init(char *playlist) {
|
||||
return OK;
|
||||
}
|
||||
|
||||
@@ -70,6 +41,16 @@ EM_JS(int, cdrom_stop, (), {
|
||||
return xsystem35.Status.OK;
|
||||
});
|
||||
|
||||
int cdrom_exit(void) {
|
||||
cdrom_stop();
|
||||
return OK;
|
||||
}
|
||||
|
||||
int cdrom_reset(void) {
|
||||
cdrom_stop();
|
||||
return OK;
|
||||
}
|
||||
|
||||
int cdrom_getPlayingInfo(cd_time *info) {
|
||||
if (nact->frame_count == frame_of_getpos)
|
||||
nact->wait_vsync = TRUE;
|
||||
@@ -82,3 +63,14 @@ int cdrom_getPlayingInfo(cd_time *info) {
|
||||
FRAMES_TO_MSF(t >> 8, &info->m, &info->s, &info->f);
|
||||
return OK;
|
||||
}
|
||||
|
||||
cdromdevice_t cdrom_emscripten = {
|
||||
cdrom_init,
|
||||
cdrom_exit,
|
||||
cdrom_reset,
|
||||
cdrom_start,
|
||||
cdrom_stop,
|
||||
cdrom_getPlayingInfo,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
@@ -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; \
|
||||
|
||||
+6
-1
@@ -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
|
||||
@@ -72,7 +75,9 @@ static int cdrom_init(char *playlist_path) {
|
||||
fp = fopen("_inmm.ini", "r");
|
||||
}
|
||||
if (!fp) {
|
||||
NOTICE("cdrom: Cannot open playlist %s", playlist_path);
|
||||
// If the game has MIDI music, lack of the playlist is not a problem.
|
||||
if (ald_get_maxno(DRIFILE_MIDI) == 0)
|
||||
NOTICE("cdrom: Cannot open playlist %s", playlist_path);
|
||||
return NG;
|
||||
}
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
#include "qnt.h"
|
||||
#include "jpeg.h"
|
||||
#include "ald_manager.h"
|
||||
#include "savedata.h"
|
||||
#include "filecheck.h"
|
||||
#include "cache.h"
|
||||
|
||||
/* VSPのパレット展開バンク */
|
||||
@@ -293,13 +293,8 @@ void cg_load(int no, int flg) {
|
||||
bank = cg_vspPB == -1 ? cg->vsp_bank : cg_vspPB;
|
||||
set_vspbank(cg->pic, bank << 4, cg->width, cg->height);
|
||||
/* copy palettes 0 -> bank */
|
||||
{
|
||||
int i, i_dst = bank << 4;
|
||||
for (i = 0; i < 16; i++) {
|
||||
cg->pal->red[i + i_dst] = cg->pal->red[i];
|
||||
cg->pal->green[i + i_dst] = cg->pal->green[i];
|
||||
cg->pal->blue[i + i_dst] = cg->pal->blue[i];
|
||||
}
|
||||
if (bank != 0) {
|
||||
memcpy(cg->pal + bank * 16, cg->pal, 16 * sizeof(cg->pal[0]));
|
||||
}
|
||||
if (flg != -1) {
|
||||
flg |= (bank << 4);
|
||||
@@ -310,22 +305,22 @@ void cg_load(int no, int flg) {
|
||||
if (GCMD_LOAD_PALETTE(cg_fflg)) {
|
||||
switch(cg->type) {
|
||||
case ALCG_VSP:
|
||||
ags_setPalettes(cg->pal, 0, bank << 4, 16);
|
||||
ags_setPalettes(cg->pal, bank << 4, 16);
|
||||
break;
|
||||
case ALCG_PMS8:
|
||||
// Avoid changing the Windows' reserved palette area (0-9, 246-255)
|
||||
if (cg->pms_bank & 1)
|
||||
ags_setPalettes(cg->pal, 10, 10, 6);
|
||||
ags_setPalettes(cg->pal + 10, 10, 6);
|
||||
if (cg->pms_bank & (1 << 15))
|
||||
//ags_setPalettes(cg->pal, 240, 240, 15);
|
||||
ags_setPalettes(cg->pal, 240, 240, 10);
|
||||
ags_setPalettes(cg->pal + 240, 240, 6);
|
||||
for (i = 1; i < 15; i++) {
|
||||
if (cg->pms_bank & (1 << i)) {
|
||||
ags_setPalettes(cg->pal, i * 16, i * 16, 16);
|
||||
ags_setPalettes(cg->pal + i * 16, i * 16, 16);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ALCG_BMP8:
|
||||
ags_setPalettes(cg->pal, 10, 10, 236);
|
||||
ags_setPalettes(cg->pal + 10, 10, 236);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -346,9 +341,9 @@ void cg_load(int no, int flg) {
|
||||
}
|
||||
/* draw cg pixel */
|
||||
display_cg(cg, p.x, p.y, flg, flg != -1);
|
||||
/* clear display offset */
|
||||
clear_display_loc();
|
||||
}
|
||||
/* clear display offset */
|
||||
clear_display_loc();
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -391,6 +386,41 @@ void cg_load_with_alpha(int cgno, int shadowno) {
|
||||
clear_display_loc();
|
||||
}
|
||||
|
||||
static uint8_t* load_cg_from_file(char *fname_utf8, int *status, long *filesize) {
|
||||
int size;
|
||||
FILE *fp;
|
||||
static uint8_t *tmp;
|
||||
|
||||
*status = 0;
|
||||
|
||||
if (NULL == (fp = fc_open(fname_utf8, 'r'))) {
|
||||
*status = SAVE_LOADERR; return NULL;
|
||||
}
|
||||
|
||||
fseek(fp, 0L, SEEK_END);
|
||||
*filesize = ftell(fp);
|
||||
if (*filesize == 0) {
|
||||
*status = SAVE_LOADERR; return NULL;
|
||||
}
|
||||
|
||||
tmp = (char *)malloc(*filesize);
|
||||
if (tmp == NULL) {
|
||||
WARNING("Out of memory");
|
||||
*status = SAVE_LOADERR; return NULL;
|
||||
}
|
||||
fseek(fp, 0L, SEEK_SET);
|
||||
size = fread(tmp, 1, *filesize,fp);
|
||||
|
||||
if (size != *filesize) {
|
||||
*status = SAVE_LOADSHORTAGE;
|
||||
} else {
|
||||
*status = SAVE_LOADOK;
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
/*
|
||||
* Load and display cg from file 'name' (not cached right now)
|
||||
* name: file name to be read
|
||||
@@ -405,7 +435,7 @@ int cg_load_with_filename(char *fname_utf8, int x, int y) {
|
||||
cgdata *cg = NULL;
|
||||
MyPoint p;
|
||||
|
||||
data = load_cg_with_file(fname_utf8, &status, &filesize);
|
||||
data = load_cg_from_file(fname_utf8, &status, &filesize);
|
||||
if (data == NULL) return status;
|
||||
|
||||
cg_set_display_location(x, y, OFFSET_ABSOLUTE_GC);
|
||||
@@ -428,7 +458,7 @@ int cg_load_with_filename(char *fname_utf8, int x, int y) {
|
||||
/* load palette if not extracted */
|
||||
if (cg->depth == 8) {
|
||||
if (GCMD_LOAD_PALETTE(cg_fflg))
|
||||
ags_setPalettes(cg->pal, 10, 10, 236);
|
||||
ags_setPalettes(cg->pal + 10, 10, 236);
|
||||
if (GCMD_SET_PALETTE(cg_fflg))
|
||||
ags_setPaletteToSystem(0, 256);
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user