mirror of
https://github.com/kichikuou/xsystem35-sdl2.git
synced 2026-09-22 22:48:08 +03:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6c692e44e5 | ||
|
|
ec071d4e8a | ||
|
|
904e10daa7 | ||
|
|
65b6da3f2a | ||
|
|
3f495b72c1 | ||
|
|
90670477c6 | ||
|
|
566ebb503f | ||
|
|
6feab51a5d | ||
|
|
15d0b44ab9 | ||
|
|
a0f20caa77 | ||
|
|
39712ee46e | ||
|
|
dcdbe7bb76 | ||
|
|
01a4255b83 | ||
|
|
d978a24a5e | ||
|
|
ed196f72b9 | ||
|
|
c9fd1dcfd0 | ||
|
|
c1018d9e0f | ||
|
|
cb8a48cdec | ||
|
|
6bf6a5c86a | ||
|
|
790aa07130 | ||
|
|
fa74a4744c | ||
|
|
fb68b03a4f | ||
|
|
75228cc4c8 | ||
|
|
8c13361164 | ||
|
|
d05dc83e67 | ||
|
|
c9f21c4547 | ||
|
|
f053f25397 | ||
|
|
f673708a3f | ||
|
|
aab63adac2 | ||
|
|
6f09a999d2 | ||
|
|
2ed44dab6d | ||
|
|
a8f46453d8 | ||
|
|
baa4a3158f | ||
|
|
8328b93227 | ||
|
|
6665416683 | ||
|
|
cf5e899632 | ||
|
|
51954c6bd4 | ||
|
|
f282c02376 | ||
|
|
e2c75fbd9d | ||
|
|
b28e3ef2fd | ||
|
|
215de5511e | ||
|
|
f669804573 | ||
|
|
9c6423bf99 | ||
|
|
4f3b73c1ac | ||
|
|
8ee53accf9 | ||
|
|
6b646b3857 | ||
|
|
dec1649882 | ||
|
|
6b9c3475a0 | ||
|
|
1335a12065 | ||
|
|
93bd8ca737 | ||
|
|
5bae0c16c5 | ||
|
|
d551cdbb70 | ||
|
|
e711d5786e | ||
|
|
64abb3c582 | ||
|
|
bf26f1b0c0 | ||
|
|
f4f1a99372 | ||
|
|
53f0a5ce2a | ||
|
|
c621a5dddb | ||
|
|
42faf38a47 | ||
|
|
c50a563e80 | ||
|
|
996f63f55f | ||
|
|
fb77b229ea | ||
|
|
886d55057a | ||
|
|
7f645d6bd1 | ||
|
|
f8d59e5fc0 | ||
|
|
78ebbf40f4 | ||
|
|
dccd75113b | ||
|
|
d063655b25 | ||
|
|
5e0844e9ea | ||
|
|
386c3c0fcd | ||
|
|
2857c13e15 | ||
|
|
d14b42c146 | ||
|
|
29988d0d6c | ||
|
|
bc5d72b6fe | ||
|
|
03f9b36ff0 | ||
|
|
afb9f96a1a | ||
|
|
28e685818c | ||
|
|
51eca5c8c0 | ||
|
|
1699fbda6c | ||
|
|
abbe8b9be1 | ||
|
|
10735b8be6 | ||
|
|
e9d8a9d1a6 | ||
|
|
780d30c01f | ||
|
|
d6adb3241c | ||
|
|
3594fc19dc | ||
|
|
883f538709 | ||
|
|
c280fc719b | ||
|
|
7da9e64ab6 | ||
|
|
bba602ab04 | ||
|
|
78dc226d13 | ||
|
|
a2792d502e | ||
|
|
e800a23e1d | ||
|
|
e731b4ec95 | ||
|
|
dde697d3b4 | ||
|
|
c4d4f85ae4 | ||
|
|
84e3666a66 | ||
|
|
c2f11ecfbe | ||
|
|
85d69aa5f0 | ||
|
|
7beb558140 | ||
|
|
49126c506d | ||
|
|
4c57c98e67 | ||
|
|
e464d92164 | ||
|
|
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 | ||
|
|
c967e63be9 | ||
|
|
d4a32aee17 | ||
|
|
1191723612 | ||
|
|
addf2e3728 | ||
|
|
4785c8c77c | ||
|
|
b1ac106057 | ||
|
|
acdc40ec60 | ||
|
|
d9f635a6d0 | ||
|
|
e8357c4e6f | ||
|
|
8e44a87069 | ||
|
|
d1befbd355 | ||
|
|
ec0bae5490 | ||
|
|
f5b3b1a936 | ||
|
|
1b546e3bab | ||
|
|
d454899048 | ||
|
|
7aa704b3f4 | ||
|
|
50d7d7ee33 | ||
|
|
586a9c855e | ||
|
|
9600e34229 | ||
|
|
001c97ea00 | ||
|
|
b100dbe26c | ||
|
|
55e38f9db2 | ||
|
|
ddf6fba393 | ||
|
|
83fa5db82c | ||
|
|
1807cf0c26 | ||
|
|
5906079d3f | ||
|
|
7fba19fe18 | ||
|
|
8de86e276d | ||
|
|
64a5f47258 | ||
|
|
29a139c8a1 | ||
|
|
b53c82e072 | ||
|
|
307bb2623b | ||
|
|
d1712ab7b4 | ||
|
|
7c24ba276d | ||
|
|
c8f9880efb | ||
|
|
d508676c70 | ||
|
|
92506d6a94 | ||
|
|
0a37920c95 | ||
|
|
fa44889047 | ||
|
|
cee18a572e | ||
|
|
652d284628 | ||
|
|
d2661e97f1 | ||
|
|
0e9afe7c0a | ||
|
|
fbe8af5f7b | ||
|
|
0c1f8f8450 | ||
|
|
078525e2c2 | ||
|
|
d4a4022894 | ||
|
|
dc89c92139 | ||
|
|
4f351fc767 | ||
|
|
02ef4a1771 | ||
|
|
4a20d74f1a | ||
|
|
c9663c5cfc | ||
|
|
5c7e92391c | ||
|
|
0a15e6490f | ||
|
|
fe294bd34b | ||
|
|
e26779a189 | ||
|
|
f9b5fec03d | ||
|
|
d63e3503e7 | ||
|
|
3dd38959a3 | ||
|
|
f56ec88cda | ||
|
|
9706f516f9 | ||
|
|
b15690d9b7 | ||
|
|
26db7f46f5 | ||
|
|
1cf0dbc7e2 | ||
|
|
3f36eeee4c | ||
|
|
ff62533faf | ||
|
|
f60b21bc19 | ||
|
|
8fac291e84 | ||
|
|
782a9e5925 | ||
|
|
c8f1ef2b9e | ||
|
|
6184e93965 | ||
|
|
3377441caf | ||
|
|
d243358b48 | ||
|
|
9e82445ace | ||
|
|
a6109b6210 | ||
|
|
901a3bb28c | ||
|
|
f1b80d7086 | ||
|
|
f1fb50841c | ||
|
|
f97259bc30 | ||
|
|
3eccaa6165 | ||
|
|
42b9d43a70 | ||
|
|
a7800e652c | ||
|
|
1c2e395e88 | ||
|
|
c67198cc0e | ||
|
|
fc80275944 | ||
|
|
76db37756b | ||
|
|
4c022cf505 | ||
|
|
1c3dccb349 | ||
|
|
63c456329f | ||
|
|
141b754340 | ||
|
|
45612feb79 | ||
|
|
605de284e9 | ||
|
|
0b71a84bb0 | ||
|
|
933cf5b6a3 | ||
|
|
c15e7233b4 | ||
|
|
bad6b90e23 | ||
|
|
83989f1a0e | ||
|
|
cc9aa1e7c0 | ||
|
|
d1d943d2a5 | ||
|
|
6c59122c59 | ||
|
|
a6cbf243c7 | ||
|
|
a89ed4ba29 | ||
|
|
135cd6b8c4 | ||
|
|
b6a69deab7 | ||
|
|
eea1f9c93a | ||
|
|
47d23d4ee7 | ||
|
|
10b414fb4e | ||
|
|
49e707e40e | ||
|
|
9655a9106d | ||
|
|
d35a24f142 | ||
|
|
d945dfe77d | ||
|
|
a224d89233 | ||
|
|
debabaf686 | ||
|
|
bc97e4c826 | ||
|
|
c4d74d659a | ||
|
|
4daaa5ede5 | ||
|
|
9ea1a81cc1 | ||
|
|
0a1d0a5a76 | ||
|
|
5fefd74d4a | ||
|
|
d03568c3ff | ||
|
|
8dc49fee71 | ||
|
|
1b907e904f | ||
|
|
82963e8293 | ||
|
|
3ccf59a94e | ||
|
|
2f9ce8cec8 | ||
|
|
3ff022c73e | ||
|
|
9ad1059ced | ||
|
|
2d026c6122 | ||
|
|
b68c217554 | ||
|
|
7e09c14660 | ||
|
|
2db403a692 | ||
|
|
850fa96933 | ||
|
|
e1e1e5cacc | ||
|
|
d7dd98a8ca | ||
|
|
f11dbc7400 | ||
|
|
3b52efb752 | ||
|
|
93f01efdb5 |
@@ -10,6 +10,7 @@ assignees: ''
|
||||
### Environment
|
||||
- xsystem35 version:
|
||||
- OS:
|
||||
- Game title:
|
||||
|
||||
### Steps to reproduce the behavior
|
||||
1.
|
||||
@@ -22,3 +23,4 @@ assignees: ''
|
||||
<!-- If applicable, add screenshots to help explain your problem. -->
|
||||
|
||||
### Additional context
|
||||
<!-- Note: Please do not post copyrighted game files. -->
|
||||
|
||||
@@ -6,24 +6,23 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Install Deps
|
||||
run: sudo apt install ninja-build
|
||||
|
||||
# Workaround for https://github.com/actions/virtual-environments/issues/3078
|
||||
- name: Setup cmake
|
||||
uses: jwlawson/actions-setup-cmake@v1.9
|
||||
with:
|
||||
cmake-version: '3.19.x'
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
cd android
|
||||
ANDROID_NDK_HOME=$ANDROID_SDK_ROOT/ndk-bundle ./gradlew assembleRelease
|
||||
echo "${{ secrets.KEYSTORE_BASE64 }}" | base64 -d > keystore.jks
|
||||
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@v1
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: xsystem35-release-unsigned-apk
|
||||
path: android/app/build/outputs/apk/release/app-release-unsigned.apk
|
||||
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: 2.0.34
|
||||
EM_VERSION: latest
|
||||
EM_CACHE_FOLDER: 'emsdk-cache'
|
||||
|
||||
jobs:
|
||||
@@ -10,17 +10,17 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Setup cache
|
||||
id: cache-system-libraries
|
||||
uses: actions/cache@v2
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ${{env.EM_CACHE_FOLDER}}
|
||||
key: ${{env.EM_VERSION}}-${{ runner.os }}
|
||||
|
||||
- name: Setup Emscripten toolchain
|
||||
uses: mymindstorm/setup-emsdk@v10
|
||||
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@v2
|
||||
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@v2
|
||||
- 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
|
||||
|
||||
@@ -3,58 +3,68 @@ on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: windows-2019
|
||||
runs-on: windows-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
mingw: ["MINGW32", "MINGW64"]
|
||||
include:
|
||||
- mingw: "MINGW32"
|
||||
package: "mingw-w64-i686"
|
||||
installer: "xsystem35-32bit"
|
||||
- mingw: "MINGW64"
|
||||
package: "mingw-w64-x86_64"
|
||||
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: bash.exe --login -eo pipefail "{0}"
|
||||
env:
|
||||
MSYSTEM: ${{ matrix.mingw }}
|
||||
CHERE_INVOKING: 1
|
||||
name: MSYS2 ${{ matrix.mingw }}
|
||||
shell: msys2 {0}
|
||||
name: MSYS2 ${{ matrix.sys }}
|
||||
steps:
|
||||
|
||||
- name: Set up shell
|
||||
run: echo "C:\msys64\usr\bin\" >> $env:GITHUB_PATH
|
||||
shell: pwsh
|
||||
|
||||
- name: Print system version
|
||||
run: |
|
||||
uname
|
||||
echo PATH: $PATH
|
||||
|
||||
- name: Install Deps
|
||||
run: pacman -S --noconfirm ${{ matrix.package }}-SDL2 ${{ matrix.package }}-SDL2_ttf ${{ matrix.package }}-SDL2_mixer ${{ matrix.package }}-libjpeg-turbo ${{ matrix.package }}-libwebp ${{ matrix.package }}-cjson ${{ matrix.package }}-nsis ${{ matrix.package }}-ntldd-git
|
||||
- name: Set up MSYS2
|
||||
uses: msys2/setup-msys2@v2
|
||||
with:
|
||||
msystem: ${{ matrix.sys }}
|
||||
pacboy: >-
|
||||
SDL2:p
|
||||
SDL2_ttf:p
|
||||
SDL2_mixer:p
|
||||
libwebp:p
|
||||
portmidi:p
|
||||
${{ matrix.deps }}
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
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"MSYS Makefiles" -DCMAKE_BUILD_TYPE=Release ../../
|
||||
make
|
||||
cmake -GNinja -DCMAKE_BUILD_TYPE=Release -DCMAKE_COMPILE_WARNING_AS_ERROR=YES ${{ matrix.cmake_args }} ../../
|
||||
ninja
|
||||
|
||||
- name: Test
|
||||
run: ctest --output-on-failure
|
||||
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@v2
|
||||
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,8 +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
|
||||
|
||||
+152
@@ -0,0 +1,152 @@
|
||||
# Changelog
|
||||
|
||||
## 2.15.1 - 2024-05-14
|
||||
- Fixed a text rendering issue in Rance 5D (#66)
|
||||
|
||||
## 2.15.0 - 2024-04-21
|
||||
- Fixed color palette bug introduced in v2.14.2.
|
||||
- Fixed uncancellable message waiting mode.
|
||||
- Android: "Install from ZIP" button is moved to the top-right option menu.
|
||||
- Android: Improved extraction logic of track numbers from audio file names.
|
||||
|
||||
## 2.14.3 - 2024-04-01
|
||||
- Fixed build for big endian architectures.
|
||||
|
||||
## 2.14.2 - 2024-03-09
|
||||
- Android: Back button to exit the game (#50)
|
||||
- Improved touch input usability in ママトト (#64)
|
||||
|
||||
## 2.14.1 - 2024-02-07
|
||||
- Fixed font selection and text decoration not working in selection menus.
|
||||
- Fixed a graphic issue in DALK intro.
|
||||
|
||||
## 2.14.0 - 2024-01-09
|
||||
- New supported games: 俺の下であがけ and 楽園行.
|
||||
- Windows: On Windows 10 version 1903 or above, now xsystem35 can handle
|
||||
Japanese filenames correctly even if the system locale is not Japanese.
|
||||
|
||||
## 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
-104
@@ -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.15.1")
|
||||
|
||||
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,20 +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.5.0.tar.gz
|
||||
URL_HASH SHA1=b21aa842136dc59a72a38776a5aa73f4d0b00ac5
|
||||
)
|
||||
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)
|
||||
set(HAVE_JPEG 1)
|
||||
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)
|
||||
@@ -43,50 +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()
|
||||
|
||||
include(FindJPEG)
|
||||
if (JPEG_FOUND)
|
||||
set(HAVE_JPEG 1)
|
||||
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)
|
||||
@@ -96,101 +170,41 @@ 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
|
||||
|
||||
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()
|
||||
|
||||
# Joystick
|
||||
|
||||
if (NOT EMSCRIPTEN AND NOT ANDROID)
|
||||
set(HAVE_SDLJOY 1)
|
||||
endif()
|
||||
|
||||
# TODO: MMX
|
||||
|
||||
function (print_summary name)
|
||||
if (ARGN)
|
||||
list(JOIN ARGN ", " MSG)
|
||||
@@ -205,18 +219,19 @@ message("------------------")
|
||||
print_summary(audio ${SUMMARY_AUDIO})
|
||||
print_summary(cdrom ${SUMMARY_CDROM})
|
||||
print_summary(midi ${SUMMARY_MIDI})
|
||||
print_summary(joystick ${SUMMARY_JOYSTICK})
|
||||
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,17 +3,22 @@
|
||||
This is a multi-platform port of `xsystem35`, a free implementation of
|
||||
AliceSoft's System 3.x game engine.
|
||||
|
||||
## Compatibility
|
||||
|
||||
See the [game compatibility table](game_compatibility.md) for a list of games
|
||||
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
|
||||
@@ -22,90 +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 `-debugger` 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
|
||||
|
||||
Make a Zip file containing all the game files, copy it to your device, and load
|
||||
it.
|
||||
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 libjpeg 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-libjpeg-turbo 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.
|
||||
|
||||
|
||||
+52
-39
@@ -1,60 +1,73 @@
|
||||
# xsystem35 for Android
|
||||
|
||||
## Download
|
||||
Prebuilt APKs are [here](https://github.com/kichikuou/xsystem35-sdl2/releases).
|
||||
Minimum supported Android version: 5.0
|
||||
|
||||
## Build
|
||||
Prerequisites:
|
||||
- CMake >=3.13
|
||||
- Android SDK >=28
|
||||
- Android NDK >=r15c
|
||||
## Download
|
||||
You can download prebuilt APKs
|
||||
[here](https://github.com/kichikuou/xsystem35-sdl2/releases).
|
||||
|
||||
## 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. Tap the option menu (three dots in the top right corner) and
|
||||
select "Install from ZIP".
|
||||
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 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 have a number either
|
||||
at the beginning or just before the extension are recognized as BGM files.
|
||||
For example:
|
||||
- `Track2.mp3`
|
||||
- `15.ogg`
|
||||
- `02 - Title.mp3`
|
||||
- `rance4_03.wav` (Note: The filename shouldn't be `rance403.wav`, as it
|
||||
would be treated as the 403rd track.)
|
||||
|
||||
Note: This ZIP format is also compatible with
|
||||
[Kichikuou on Web](http://kichikuou.github.io/web/).
|
||||
|
||||
### Miscellaneous
|
||||
- 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 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.
|
||||
|
||||
## Building from Source
|
||||
|
||||
### 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 buster):
|
||||
Example build instructions (for Debian bookworm):
|
||||
```sh
|
||||
# Install necessary packages
|
||||
sudo apt install git wget unzip default-jdk-headless cmake ninja-build
|
||||
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-7302050_latest.zip
|
||||
unzip commandlinetools-linux-7302050_latest.zip -d $ANDROID_SDK_ROOT/cmdline-tools
|
||||
wget https://dl.google.com/android/repository/commandlinetools-linux-11076708_latest.zip
|
||||
unzip commandlinetools-linux-11076708_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
|
||||
$ANDROID_SDK_ROOT/cmdline-tools/tools/bin/sdkmanager ndk-bundle
|
||||
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
|
||||
### 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. Two-finger touch is treated as a right click.
|
||||
|
||||
### 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:
|
||||
- `Track2.mp3`
|
||||
- `15.ogg`
|
||||
- `rance4_03.wav` (This shouldn't be `rance403.wav`, because 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.
|
||||
|
||||
### 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.
|
||||
|
||||
## 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.
|
||||
|
||||
+30
-17
@@ -9,33 +9,47 @@ else {
|
||||
apply plugin: 'kotlin-android'
|
||||
|
||||
android {
|
||||
compileSdkVersion 28
|
||||
if (buildAsApplication) {
|
||||
namespace "io.github.kichikuou.xsystem35"
|
||||
}
|
||||
compileSdkVersion 34
|
||||
defaultConfig {
|
||||
if (buildAsApplication) {
|
||||
applicationId "io.github.kichikuou.xsystem35"
|
||||
}
|
||||
minSdkVersion 19
|
||||
targetSdkVersion 28
|
||||
versionCode 6
|
||||
versionName "2.2.0"
|
||||
minSdkVersion 21
|
||||
targetSdkVersion 34
|
||||
versionCode 34
|
||||
versionName "2.15.1" + 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'
|
||||
}
|
||||
}
|
||||
}
|
||||
signingConfigs {
|
||||
release {
|
||||
storeFile rootProject.file('keystore.jks')
|
||||
storePassword System.getenv('KEYSTORE_PASSWORD')
|
||||
keyAlias System.getenv('KEY_ALIAS')
|
||||
keyPassword System.getenv('KEY_PASSWORD')
|
||||
}
|
||||
}
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled false
|
||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||
if (rootProject.file('keystore.jks').exists()) {
|
||||
signingConfig signingConfigs.release
|
||||
}
|
||||
}
|
||||
}
|
||||
applicationVariants.all { variant ->
|
||||
tasks["merge${variant.name.capitalize()}Assets"]
|
||||
.dependsOn("externalNativeBuild${variant.name.capitalize()}")
|
||||
}
|
||||
if (!project.hasProperty('EXCLUDE_NATIVE_LIBS')) {
|
||||
sourceSets.main {
|
||||
jniLibs.srcDir 'libs'
|
||||
assets.srcDir '../../fonts'
|
||||
}
|
||||
aaptOptions {
|
||||
// Disable asset compression for fonts.
|
||||
@@ -44,18 +58,16 @@ android {
|
||||
}
|
||||
externalNativeBuild {
|
||||
cmake {
|
||||
// xsystem35 requires CMake >=3.13, so SDK-bundled CMake
|
||||
// (3.6 or 3.10.2) cannot be used.
|
||||
version getInstalledCmakeVersion()
|
||||
version '3.22.1'
|
||||
path 'jni/CMakeLists.txt'
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
lintOptions {
|
||||
lint {
|
||||
abortOnError false
|
||||
}
|
||||
|
||||
|
||||
if (buildAsLibrary) {
|
||||
libraryVariants.all { variant ->
|
||||
variant.outputs.each { output ->
|
||||
@@ -72,8 +84,9 @@ 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 getInstalledCmakeVersion() {
|
||||
('cmake --version'.execute().text =~ /cmake version ([0-9.]+)/)[0][1]
|
||||
static String gitRevision() {
|
||||
' (git ' + "git rev-parse --short HEAD".execute().text.trim() + ')'
|
||||
}
|
||||
|
||||
@@ -1,49 +1,53 @@
|
||||
cmake_minimum_required(VERSION 3.13)
|
||||
cmake_minimum_required(VERSION 3.14)
|
||||
|
||||
project(GAME)
|
||||
set(PROJECT_ROOT_DIR ../../..)
|
||||
|
||||
# armeabi-v7a requires cpufeatures library
|
||||
# include(AndroidNdkModules)
|
||||
# android_ndk_import_module_cpufeatures()
|
||||
|
||||
# Compilation of SDL and companion libraries
|
||||
include(FetchContent)
|
||||
FetchContent_Declare(
|
||||
SDL
|
||||
URL https://libsdl.org/release/SDL2-2.0.16.tar.gz
|
||||
URL_HASH SHA1=57825428174adb2ac947e4014080c262505aa972
|
||||
PATCH_COMMAND patch -p1 -i ${CMAKE_CURRENT_LIST_DIR}/SDL.patch
|
||||
URL https://github.com/libsdl-org/SDL/releases/download/release-2.32.4/SDL2-2.32.4.tar.gz
|
||||
URL_HASH SHA1=4fb68f43891ca4def414cc7cf0f3b2a053cb6aaf
|
||||
)
|
||||
# TODO: Use SDL2_ttf 2.0.16 once released
|
||||
FetchContent_Declare(
|
||||
SDL_ttf
|
||||
GIT_REPOSITORY https://github.com/libsdl-org/SDL_ttf.git
|
||||
GIT_TAG 11722a2bb4335d489d724c08cfdbb45f97d07aa7
|
||||
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
|
||||
)
|
||||
# TODO: Use SDL2_mixer 2.0.5 once released
|
||||
FetchContent_Declare(
|
||||
SDL_mixer
|
||||
GIT_REPOSITORY https://github.com/libsdl-org/SDL_mixer.git
|
||||
GIT_TAG 20433729fb318f7b6f773a42ffa410114cb067f2
|
||||
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)
|
||||
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(SUPPORT_OGG ON CACHE BOOL "Enable OGG support in SDL_mixer" FORCE)
|
||||
add_subdirectory(${sdl_mixer_SOURCE_DIR} ${sdl_mixer_BINARY_DIR})
|
||||
target_compile_definitions(SDL2_mixer PRIVATE MUSIC_WAV)
|
||||
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(../../.. xsystem35)
|
||||
add_subdirectory(${PROJECT_ROOT_DIR} xsystem35)
|
||||
|
||||
# Copy asset files
|
||||
set(ASSETS_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../src/main/assets)
|
||||
file(MAKE_DIRECTORY ${ASSETS_DIR}/licenses)
|
||||
file(COPY_FILE ${PROJECT_ROOT_DIR}/fonts/MTLc3m.ttf ${ASSETS_DIR}/MTLc3m.ttf)
|
||||
file(COPY_FILE ${PROJECT_ROOT_DIR}/fonts/mincho.otf ${ASSETS_DIR}/mincho.otf)
|
||||
file(COPY_FILE ${PROJECT_ROOT_DIR}/COPYING ${ASSETS_DIR}/licenses/xsystem35)
|
||||
file(COPY_FILE ${PROJECT_ROOT_DIR}/fonts/MTLc3m.ttf.license ${ASSETS_DIR}/licenses/MTLc3m)
|
||||
file(COPY_FILE ${PROJECT_ROOT_DIR}/fonts/mincho.otf.license ${ASSETS_DIR}/licenses/mincho)
|
||||
file(COPY_FILE ${sdl_SOURCE_DIR}/LICENSE.txt ${ASSETS_DIR}/licenses/SDL)
|
||||
file(COPY_FILE ${sdl_ttf_SOURCE_DIR}/LICENSE.txt ${ASSETS_DIR}/licenses/SDL_ttf)
|
||||
file(COPY_FILE ${sdl_ttf_SOURCE_DIR}/external/freetype/docs/GPLv2.TXT ${ASSETS_DIR}/licenses/freetype)
|
||||
file(COPY_FILE ${sdl_ttf_SOURCE_DIR}/external/harfbuzz/COPYING ${ASSETS_DIR}/licenses/harfbuzz)
|
||||
file(COPY_FILE ${sdl_mixer_SOURCE_DIR}/LICENSE.txt ${ASSETS_DIR}/licenses/SDL_mixer)
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
diff --git a/CMakeLists.txt b/CMakeLists.txt
|
||||
index e7ab00feb..d86f0087a 100644
|
||||
--- a/CMakeLists.txt
|
||||
+++ b/CMakeLists.txt
|
||||
@@ -2053,6 +2053,12 @@ if(SDL_SHARED)
|
||||
set_property(TARGET SDL2 APPEND_STRING PROPERTY COMPILE_FLAGS "-fobjc-arc")
|
||||
target_compile_definitions(SDL2 PRIVATE IOS_DYLIB=1)
|
||||
endif()
|
||||
+ if (ANDROID)
|
||||
+ # Link the cpufeatures library in Android NDK.
|
||||
+ # Since we don't use a SDK-bundled CMAKE, AndroidNdkModules module cannot be used.
|
||||
+ target_include_directories(SDL2 PRIVATE ${ANDROID_NDK}/sources/android/cpufeatures)
|
||||
+ target_sources(SDL2 PRIVATE ${ANDROID_NDK}/sources/android/cpufeatures/cpu-features.c)
|
||||
+ endif()
|
||||
endif()
|
||||
|
||||
if(ANDROID)
|
||||
@@ -13,6 +13,6 @@ LOCAL_SRC_FILES := YourSourceHere.c
|
||||
|
||||
LOCAL_SHARED_LIBRARIES := SDL2
|
||||
|
||||
LOCAL_LDLIBS := -lGLESv1_CM -lGLESv2 -llog
|
||||
LOCAL_LDLIBS := -lGLESv1_CM -lGLESv2 -lOpenSLES -llog -landroid
|
||||
|
||||
include $(BUILD_SHARED_LIBRARY)
|
||||
|
||||
Vendored
+81
@@ -15,3 +15,84 @@
|
||||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||
# public *;
|
||||
#}
|
||||
|
||||
-keep,includedescriptorclasses,allowoptimization class org.libsdl.app.SDLInputConnection {
|
||||
void nativeCommitText(java.lang.String, int);
|
||||
void nativeGenerateScancodeForUnichar(char);
|
||||
}
|
||||
|
||||
-keep,includedescriptorclasses class org.libsdl.app.SDLActivity {
|
||||
# for some reason these aren't compatible with allowoptimization modifier
|
||||
boolean supportsRelativeMouse();
|
||||
void setWindowStyle(boolean);
|
||||
}
|
||||
|
||||
-keep,includedescriptorclasses,allowoptimization class org.libsdl.app.SDLActivity {
|
||||
java.lang.String nativeGetHint(java.lang.String); # Java-side doesn't use this, so it gets minified, but C-side still tries to register it
|
||||
boolean onNativeSoftReturnKey();
|
||||
void onNativeKeyboardFocusLost();
|
||||
boolean isScreenKeyboardShown();
|
||||
android.util.DisplayMetrics getDisplayDPI();
|
||||
java.lang.String clipboardGetText();
|
||||
boolean clipboardHasText();
|
||||
void clipboardSetText(java.lang.String);
|
||||
int createCustomCursor(int[], int, int, int, int);
|
||||
void destroyCustomCursor(int);
|
||||
android.content.Context getContext();
|
||||
boolean getManifestEnvironmentVariables();
|
||||
android.view.Surface getNativeSurface();
|
||||
void initTouch();
|
||||
boolean isAndroidTV();
|
||||
boolean isChromebook();
|
||||
boolean isDeXMode();
|
||||
boolean isTablet();
|
||||
void manualBackButton();
|
||||
int messageboxShowMessageBox(int, java.lang.String, java.lang.String, int[], int[], java.lang.String[], int[]);
|
||||
void minimizeWindow();
|
||||
int openURL(java.lang.String);
|
||||
void requestPermission(java.lang.String, int);
|
||||
int showToast(java.lang.String, int, int, int, int);
|
||||
boolean sendMessage(int, int);
|
||||
boolean setActivityTitle(java.lang.String);
|
||||
boolean setCustomCursor(int);
|
||||
void setOrientation(int, int, boolean, java.lang.String);
|
||||
boolean setRelativeMouseEnabled(boolean);
|
||||
boolean setSystemCursor(int);
|
||||
boolean shouldMinimizeOnFocusLoss();
|
||||
boolean showTextInput(int, int, int, int);
|
||||
}
|
||||
|
||||
-keep,includedescriptorclasses,allowoptimization class org.libsdl.app.HIDDeviceManager {
|
||||
boolean initialize(boolean, boolean);
|
||||
boolean openDevice(int);
|
||||
int sendOutputReport(int, byte[]);
|
||||
int sendFeatureReport(int, byte[]);
|
||||
boolean getFeatureReport(int, byte[]);
|
||||
void closeDevice(int);
|
||||
}
|
||||
|
||||
-keep,includedescriptorclasses,allowoptimization class org.libsdl.app.SDLAudioManager {
|
||||
int[] getAudioOutputDevices();
|
||||
int[] getAudioInputDevices();
|
||||
int[] audioOpen(int, int, int, int, int);
|
||||
void audioWriteFloatBuffer(float[]);
|
||||
void audioWriteShortBuffer(short[]);
|
||||
void audioWriteByteBuffer(byte[]);
|
||||
void audioClose();
|
||||
int[] captureOpen(int, int, int, int, int);
|
||||
int captureReadFloatBuffer(float[], boolean);
|
||||
int captureReadShortBuffer(short[], boolean);
|
||||
int captureReadByteBuffer(byte[], boolean);
|
||||
void captureClose();
|
||||
void audioSetThreadPriority(boolean, int);
|
||||
native int nativeSetupJNI();
|
||||
native void removeAudioDevice(boolean, int);
|
||||
native void addAudioDevice(boolean, int);
|
||||
}
|
||||
|
||||
-keep,includedescriptorclasses,allowoptimization class org.libsdl.app.SDLControllerManager {
|
||||
void pollInputDevices();
|
||||
void pollHapticDevices();
|
||||
void hapticRun(int, float, int);
|
||||
void hapticStop(int);
|
||||
}
|
||||
|
||||
@@ -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 -->
|
||||
@@ -37,10 +36,14 @@
|
||||
android:name="android.hardware.microphone"
|
||||
android:required="false" /> -->
|
||||
|
||||
<!-- Allow writing to external storage -->
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||
<!-- Allow downloading to the external storage on Android 5.1 and older -->
|
||||
<!-- <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="22" /> -->
|
||||
|
||||
<!-- Allow access to Bluetooth devices -->
|
||||
<!-- <uses-permission android:name="android.permission.BLUETOOTH" /> -->
|
||||
<!-- Currently this is just for Steam Controller support and requires setting SDL_HINT_JOYSTICK_HIDAPI_STEAM -->
|
||||
<!-- <uses-permission android:name="android.permission.BLUETOOTH" android:maxSdkVersion="30" /> -->
|
||||
<!-- <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" /> -->
|
||||
|
||||
<!-- Allow access to the vibrator -->
|
||||
<!-- <uses-permission android:name="android.permission.VIBRATE" /> -->
|
||||
|
||||
@@ -64,7 +67,9 @@
|
||||
<meta-data android:name="SDL_ENV.SDL_ACCELEROMETER_AS_JOYSTICK" android:value="0"/>
|
||||
-->
|
||||
|
||||
<activity android:name=".LauncherActivity">
|
||||
<activity android:name=".LauncherActivity"
|
||||
android:exported="true">
|
||||
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
@@ -75,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"
|
||||
>
|
||||
|
||||
@@ -88,6 +93,17 @@
|
||||
</intent-filter>
|
||||
-->
|
||||
</activity>
|
||||
|
||||
<activity android:name=".LicensesMenuActivity"
|
||||
android:label="@string/action_licenses"
|
||||
android:parentActivityName=".LauncherActivity"
|
||||
android:exported="false">
|
||||
</activity>
|
||||
|
||||
<activity android:name=".LicensesActivity"
|
||||
android:parentActivityName=".LicensesMenuActivity"
|
||||
android:exported="false">
|
||||
</activity>
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
|
||||
@@ -30,40 +30,40 @@ 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))
|
||||
gameRoot = File(intent.getStringExtra(EXTRA_GAME_ROOT)!!)
|
||||
}
|
||||
|
||||
override fun onStop() {
|
||||
super.onStop()
|
||||
cdda.onActivityStop()
|
||||
midi.onActivityStop()
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
cdda.onActivityResume()
|
||||
midi.onActivityResume()
|
||||
}
|
||||
|
||||
override fun getLibraries(): Array<String> {
|
||||
return arrayOf("hidapi", "SDL2", "xsystem35")
|
||||
return arrayOf("SDL2", "xsystem35")
|
||||
}
|
||||
|
||||
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<String>()
|
||||
}
|
||||
private var currentTrack = 0
|
||||
private val player = MediaPlayer()
|
||||
private var playerPaused = false
|
||||
|
||||
fun start(track: Int, loop: Boolean) {
|
||||
val f = playlist.elementAtOrNull(track)
|
||||
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,15 +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 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) {
|
||||
@@ -73,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) {
|
||||
@@ -109,7 +104,7 @@ class Launcher private constructor(private val rootDir: File) {
|
||||
private fun updateGameList() {
|
||||
var saveDirFound = false
|
||||
games.clear()
|
||||
for (path in rootDir.listFiles()) {
|
||||
for (path in rootDir.listFiles() ?: emptyArray()) {
|
||||
if (!path.isDirectory)
|
||||
continue
|
||||
if (path.name == SAVE_DIR) {
|
||||
@@ -117,9 +112,12 @@ 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.
|
||||
path.deleteRecursively()
|
||||
@@ -129,6 +127,7 @@ class Launcher private constructor(private val rootDir: File) {
|
||||
if (!saveDirFound) {
|
||||
File(rootDir, SAVE_DIR).mkdir()
|
||||
}
|
||||
observer?.onGameListChange()
|
||||
}
|
||||
|
||||
private fun createDirForGame(): File {
|
||||
@@ -144,7 +143,7 @@ class Launcher private constructor(private val rootDir: File) {
|
||||
// Throws IOException
|
||||
fun exportSaveData(output: OutputStream) {
|
||||
ZipOutputStream(output.buffered()).use { zip ->
|
||||
for (path in File(rootDir, SAVE_DIR).listFiles()) {
|
||||
for (path in File(rootDir, SAVE_DIR).listFiles() ?: emptyArray()) {
|
||||
if (path.isDirectory || path.name.endsWith(".asd."))
|
||||
continue
|
||||
val pathInZip = "${SAVE_DIR}/${path.name}"
|
||||
@@ -181,94 +180,77 @@ 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))
|
||||
}
|
||||
}
|
||||
|
||||
// A helper class which generates xsystem35.gr and playlist.txt in the game root directory.
|
||||
class InstallFailureException(val msgId: Int) : Exception()
|
||||
|
||||
// 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"
|
||||
)
|
||||
private val audioRegex = """.*?(\d+)\.(wav|mp3|ogg)""".toRegex(RegexOption.IGNORE_CASE)
|
||||
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+).*|.*?(\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.toLowerCase(Locale.US)]?.let {
|
||||
grb.appendln("$it $path")
|
||||
return
|
||||
}
|
||||
aldRegex.matchEntire(name)?.let {
|
||||
val ext = it.groupValues[4].toUpperCase(Locale.US)
|
||||
val type = if (ext == "ALD") {
|
||||
aldType[it.groupValues[2].toLowerCase(Locale.US)]
|
||||
} else {
|
||||
ext
|
||||
}
|
||||
val id = it.groupValues[3].toUpperCase(Locale.US)
|
||||
if (type != null) {
|
||||
grb.appendln("$type$id $path")
|
||||
basename = it.groupValues[1]
|
||||
}
|
||||
gameDir = File(path).parent
|
||||
ready = true
|
||||
}
|
||||
audioRegex.matchEntire(name)?.let {
|
||||
val track = it.groupValues[1].toInt()
|
||||
if (track < audioFiles.size)
|
||||
audioFiles[track] = path
|
||||
val track = it.groupValues[2].toIntOrNull() ?: it.groupValues[3].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.appendln("Save$id ../save/${basename}s${id.toLowerCase()}.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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,13 +22,13 @@ import android.content.Intent
|
||||
import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import android.provider.OpenableColumns
|
||||
import android.text.Html
|
||||
import android.util.Log
|
||||
import android.view.Menu
|
||||
import android.view.MenuItem
|
||||
import android.view.View
|
||||
import android.widget.AdapterView
|
||||
import android.widget.ArrayAdapter
|
||||
import android.widget.ListView
|
||||
import android.widget.TextView
|
||||
import android.widget.Toast
|
||||
import java.io.*
|
||||
|
||||
@@ -36,48 +36,57 @@ 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 : ListActivity(), AdapterView.OnItemLongClickListener, LauncherObserver {
|
||||
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)
|
||||
setContentView(R.layout.launcher)
|
||||
|
||||
launcher = Launcher.getInstance(filesDir)
|
||||
launcher.observer = this
|
||||
if (launcher.isInstalling) {
|
||||
showProgressDialog()
|
||||
showProgressDialog(savedInstanceState)
|
||||
}
|
||||
|
||||
onGameListChange()
|
||||
listView.onItemLongClickListener = this
|
||||
val listView = findViewById<ListView>(R.id.list)
|
||||
listView.emptyView = findViewById(R.id.empty)
|
||||
findViewById<TextView>(R.id.usage).text = Html.fromHtml(getString(R.string.usage))
|
||||
listView.setOnItemClickListener { _, _, position, _ ->
|
||||
onListItemClick(position)
|
||||
}
|
||||
listView.setOnItemLongClickListener { _, _, position, _ ->
|
||||
onItemLongClick(position)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
launcher.observer = null
|
||||
dismissProgressDialog()
|
||||
super.onDestroy()
|
||||
}
|
||||
|
||||
override fun onListItemClick(l: ListView?, v: View?, position: Int, id: Long) {
|
||||
super.onListItemClick(l, v, position, id)
|
||||
if (position < launcher.games.size) {
|
||||
startGame(launcher.games[position].path, null)
|
||||
} else {
|
||||
val i = Intent(Intent.ACTION_GET_CONTENT)
|
||||
i.type = CONTENT_TYPE_ZIP
|
||||
startActivityForResult(Intent.createChooser(i, getString(R.string.choose_a_file)), INSTALL_REQUEST)
|
||||
override fun onSaveInstanceState(outState: Bundle) {
|
||||
progressDialog?.let {
|
||||
outState.putCharSequence(STATE_PROGRESS_TEXT, it.findViewById<TextView>(R.id.text).text)
|
||||
}
|
||||
super.onSaveInstanceState(outState)
|
||||
}
|
||||
|
||||
override fun onItemLongClick(a: AdapterView<*>?, v: View?, position: Int, id: Long): Boolean {
|
||||
if (position < launcher.games.size) {
|
||||
AlertDialog.Builder(this).setTitle(R.string.uninstall_dialog_title)
|
||||
.setMessage(getString(R.string.uninstall_dialog_message, launcher.games[position].title))
|
||||
.setPositiveButton(R.string.ok) {_, _ -> uninstall(position)}
|
||||
.setNegativeButton(R.string.cancel) {_, _ -> }
|
||||
.show()
|
||||
}
|
||||
private fun onListItemClick(position: Int) {
|
||||
startGame(launcher.games[position].path, null)
|
||||
}
|
||||
|
||||
private fun onItemLongClick(position: Int): Boolean {
|
||||
AlertDialog.Builder(this).setTitle(R.string.uninstall_dialog_title)
|
||||
.setMessage(getString(R.string.uninstall_dialog_message, launcher.games[position].title))
|
||||
.setPositiveButton(R.string.ok) {_, _ -> uninstall(position)}
|
||||
.setNegativeButton(R.string.cancel) {_, _ -> }
|
||||
.show()
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -88,6 +97,12 @@ class LauncherActivity : ListActivity(), AdapterView.OnItemLongClickListener, La
|
||||
|
||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||
return when (item.itemId) {
|
||||
R.id.install_from_zip -> {
|
||||
val i = Intent(Intent.ACTION_GET_CONTENT)
|
||||
i.type = CONTENT_TYPE_ZIP
|
||||
startActivityForResult(Intent.createChooser(i, getString(R.string.choose_a_file)), INSTALL_REQUEST)
|
||||
true
|
||||
}
|
||||
R.id.export_savedata -> {
|
||||
val i = Intent(Intent.ACTION_CREATE_DOCUMENT)
|
||||
i.type = CONTENT_TYPE_ZIP
|
||||
@@ -102,6 +117,17 @@ class LauncherActivity : ListActivity(), AdapterView.OnItemLongClickListener, La
|
||||
SAVEDATA_IMPORT_REQUEST)
|
||||
true
|
||||
}
|
||||
R.id.help -> {
|
||||
AlertDialog.Builder(this)
|
||||
.setMessage(Html.fromHtml(getString(R.string.usage)))
|
||||
.show()
|
||||
true
|
||||
}
|
||||
R.id.licenses -> {
|
||||
val intent = Intent(this, LicensesMenuActivity::class.java)
|
||||
startActivity(intent)
|
||||
true
|
||||
}
|
||||
else -> super.onOptionsItemSelected(item)
|
||||
}
|
||||
}
|
||||
@@ -138,12 +164,12 @@ class LauncherActivity : ListActivity(), AdapterView.OnItemLongClickListener, La
|
||||
|
||||
override fun onGameListChange() {
|
||||
val items = launcher.titles.toMutableList()
|
||||
items.add(getString(R.string.install_from_zip))
|
||||
listAdapter = ArrayAdapter(this, android.R.layout.simple_list_item_1, items)
|
||||
val listView = findViewById<ListView>(R.id.list)
|
||||
listView.adapter = ArrayAdapter(this, android.R.layout.simple_list_item_1, items)
|
||||
}
|
||||
|
||||
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?) {
|
||||
@@ -160,6 +186,7 @@ class LauncherActivity : ListActivity(), AdapterView.OnItemLongClickListener, La
|
||||
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)
|
||||
}
|
||||
@@ -168,9 +195,17 @@ class LauncherActivity : ListActivity(), AdapterView.OnItemLongClickListener, La
|
||||
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() {
|
||||
@@ -189,25 +224,13 @@ class LauncherActivity : ListActivity(), AdapterView.OnItemLongClickListener, La
|
||||
val cursor = contentResolver.query(uri, null, null, null, null, null)
|
||||
cursor?.use {
|
||||
if (it.moveToFirst()) {
|
||||
val fname = it.getString(it.getColumnIndex(OpenableColumns.DISPLAY_NAME))
|
||||
return if (fname.endsWith(".zip", true)) fname.dropLast(4) else fname
|
||||
val column = it.getColumnIndex(OpenableColumns.DISPLAY_NAME)
|
||||
if (column >= 0) {
|
||||
val fname = it.getString(column)
|
||||
return if (fname.endsWith(".zip", true)) fname.dropLast(4) else fname
|
||||
}
|
||||
}
|
||||
}
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
package io.github.kichikuou.xsystem35
|
||||
|
||||
import android.app.Activity
|
||||
import android.os.Bundle
|
||||
import android.widget.TextView
|
||||
import java.io.BufferedReader
|
||||
|
||||
class LicensesActivity : Activity() {
|
||||
companion object {
|
||||
const val EXTRA_DISPLAY_NAME = "DISPLAY_NAME"
|
||||
const val EXTRA_FILE_NAME = "FILE_NAME"
|
||||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_licenses)
|
||||
|
||||
actionBar?.title = intent.getStringExtra(EXTRA_DISPLAY_NAME)
|
||||
val path = "licenses/" + intent.getStringExtra(EXTRA_FILE_NAME)
|
||||
val text = assets.open(path).bufferedReader().use(BufferedReader::readText)
|
||||
findViewById<TextView>(R.id.license_text).text = text
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package io.github.kichikuou.xsystem35
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.widget.ListView
|
||||
import android.widget.SimpleAdapter
|
||||
|
||||
class LicensesMenuActivity : Activity() {
|
||||
class Entry(val displayName: String, val fileName: String, val url: String)
|
||||
private val entries: ArrayList<Entry> = arrayListOf(
|
||||
Entry("xsystem35-sdl2", "xsystem35", "https://github.com/kichikuou/xsystem35-sdl2"),
|
||||
Entry("SDL", "SDL", "https://www.libsdl.org/"),
|
||||
Entry("SDL_mixer", "SDL_mixer", "https://github.com/libsdl-org/SDL_mixer"),
|
||||
Entry("SDL_ttf", "SDL_ttf", "https://github.com/libsdl-org/SDL_ttf"),
|
||||
Entry("FreeType", "freetype", "https://freetype.org/"),
|
||||
Entry("HarfBuzz", "harfbuzz", "https://harfbuzz.github.io/"),
|
||||
Entry("MotoyaLCedar W3 mono", "MTLc3m", "https://github.com/aosp-mirror/platform_frameworks_base/tree/lollipop-release/data/fonts"),
|
||||
Entry("Source Han Serif", "mincho", "https://github.com/adobe-fonts/source-han-serif/"),
|
||||
)
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_licenses_menu)
|
||||
|
||||
val items = entries.map { mapOf("name" to it.displayName, "url" to it.url)}
|
||||
val listView = findViewById<ListView>(R.id.list)
|
||||
listView.adapter = SimpleAdapter(this, items, android.R.layout.simple_list_item_2,
|
||||
arrayOf("name", "url"), intArrayOf(android.R.id.text1, android.R.id.text2))
|
||||
listView.setOnItemClickListener { _, _, pos, _ ->
|
||||
val intent = Intent(this, LicensesActivity::class.java).apply {
|
||||
putExtra(LicensesActivity.EXTRA_DISPLAY_NAME, entries[pos].displayName)
|
||||
putExtra(LicensesActivity.EXTRA_FILE_NAME, entries[pos].fileName)
|
||||
}
|
||||
startActivity(intent)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -564,10 +564,10 @@ class HIDDeviceBLESteamController extends BluetoothGattCallback implements HIDDe
|
||||
return "Steam Controller";
|
||||
}
|
||||
|
||||
@Override
|
||||
@Override
|
||||
public UsbDevice getDevice() {
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean open() {
|
||||
|
||||
@@ -105,36 +105,6 @@ public class HIDDeviceManager {
|
||||
private HIDDeviceManager(final Context context) {
|
||||
mContext = context;
|
||||
|
||||
// Make sure we have the HIDAPI library loaded with the native functions
|
||||
try {
|
||||
SDL.loadLibrary("hidapi");
|
||||
} catch (Throwable e) {
|
||||
Log.w(TAG, "Couldn't load hidapi: " + e.toString());
|
||||
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(context);
|
||||
builder.setCancelable(false);
|
||||
builder.setTitle("SDL HIDAPI Error");
|
||||
builder.setMessage("Please report the following error to the SDL maintainers: " + e.getMessage());
|
||||
builder.setNegativeButton("Quit", new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
try {
|
||||
// If our context is an activity, exit rather than crashing when we can't
|
||||
// call our native functions.
|
||||
Activity activity = (Activity)context;
|
||||
|
||||
activity.finish();
|
||||
}
|
||||
catch (ClassCastException cce) {
|
||||
// Context wasn't an activity, there's nothing we can do. Give up and return.
|
||||
}
|
||||
}
|
||||
});
|
||||
builder.show();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
HIDDeviceRegisterCallback();
|
||||
|
||||
mSharedPreferences = mContext.getSharedPreferences("hidapi", Context.MODE_PRIVATE);
|
||||
@@ -149,9 +119,6 @@ public class HIDDeviceManager {
|
||||
{
|
||||
mNextDeviceId = mSharedPreferences.getInt("next_device_id", 0);
|
||||
}
|
||||
|
||||
initializeUSB();
|
||||
initializeBluetooth();
|
||||
}
|
||||
|
||||
public Context getContext() {
|
||||
@@ -174,6 +141,9 @@ public class HIDDeviceManager {
|
||||
|
||||
private void initializeUSB() {
|
||||
mUsbManager = (UsbManager)mContext.getSystemService(Context.USB_SERVICE);
|
||||
if (mUsbManager == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
// Logging
|
||||
@@ -200,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);
|
||||
@@ -278,7 +248,11 @@ public class HIDDeviceManager {
|
||||
0x1689, // Razer Onza
|
||||
0x1949, // Lab126, Inc.
|
||||
0x1bad, // Harmonix
|
||||
0x20d6, // PowerA
|
||||
0x24c6, // PowerA
|
||||
0x2c22, // Qanba
|
||||
0x2dc8, // 8BitDo
|
||||
0x9886, // ASTRO Gaming
|
||||
};
|
||||
|
||||
if (usbInterface.getInterfaceClass() == UsbConstants.USB_CLASS_VENDOR_SPEC &&
|
||||
@@ -299,13 +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
|
||||
0x2e24, // Hyperkin
|
||||
0x3537, // GameSir
|
||||
};
|
||||
|
||||
if (usbInterface.getId() == 0 &&
|
||||
@@ -379,12 +360,19 @@ public class HIDDeviceManager {
|
||||
private void initializeBluetooth() {
|
||||
Log.d(TAG, "Initializing Bluetooth");
|
||||
|
||||
if (mContext.getPackageManager().checkPermission(android.Manifest.permission.BLUETOOTH, mContext.getPackageName()) != PackageManager.PERMISSION_GRANTED) {
|
||||
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;
|
||||
}
|
||||
@@ -549,7 +537,7 @@ public class HIDDeviceManager {
|
||||
for (HIDDevice device : mDevicesById.values()) {
|
||||
device.setFrozen(frozen);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -571,6 +559,18 @@ public class HIDDeviceManager {
|
||||
////////// JNI interface functions
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public boolean initialize(boolean usb, boolean bluetooth) {
|
||||
Log.v(TAG, "initialize(" + usb + ", " + bluetooth + ")");
|
||||
|
||||
if (usb) {
|
||||
initializeUSB();
|
||||
}
|
||||
if (bluetooth) {
|
||||
initializeBluetooth();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean openDevice(int deviceID) {
|
||||
Log.v(TAG, "openDevice deviceID=" + deviceID);
|
||||
HIDDevice device = getDevice(deviceID);
|
||||
@@ -584,7 +584,20 @@ public class HIDDeviceManager {
|
||||
if (usbDevice != null && !mUsbManager.hasPermission(usbDevice)) {
|
||||
HIDDeviceOpenPending(deviceID);
|
||||
try {
|
||||
mUsbManager.requestPermission(usbDevice, PendingIntent.getBroadcast(mContext, 0, new Intent(HIDDeviceManager.ACTION_USB_PERMISSION), 0));
|
||||
final int FLAG_MUTABLE = 0x02000000; // PendingIntent.FLAG_MUTABLE, but don't require SDK 31
|
||||
int flags;
|
||||
if (Build.VERSION.SDK_INT >= 31 /* Android 12.0 (S) */) {
|
||||
flags = FLAG_MUTABLE;
|
||||
} else {
|
||||
flags = 0;
|
||||
}
|
||||
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
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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,10 +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 /* Android 5.1 (LOLLIPOP_MR1) */) {
|
||||
if (sampleRate < 8000) {
|
||||
sampleRate = 8000;
|
||||
} else if (sampleRate > 48000) {
|
||||
@@ -55,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;
|
||||
}
|
||||
@@ -116,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");
|
||||
@@ -197,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();
|
||||
}
|
||||
|
||||
@@ -220,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();
|
||||
}
|
||||
|
||||
@@ -234,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);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -250,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) {
|
||||
@@ -322,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);
|
||||
@@ -342,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);
|
||||
@@ -387,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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -255,23 +281,21 @@ class SDLJoystickHandler_API16 extends SDLJoystickHandler {
|
||||
|
||||
@Override
|
||||
public boolean handleMotionEvent(MotionEvent event) {
|
||||
if ((event.getSource() & InputDevice.SOURCE_JOYSTICK) != 0) {
|
||||
int actionPointerIndex = event.getActionIndex();
|
||||
int action = event.getActionMasked();
|
||||
if (action == MotionEvent.ACTION_MOVE) {
|
||||
SDLJoystick joystick = getJoystick(event.getDeviceId());
|
||||
if (joystick != null) {
|
||||
for (int i = 0; i < joystick.axes.size(); i++) {
|
||||
InputDevice.MotionRange range = joystick.axes.get(i);
|
||||
/* Normalize the value to -1...1 */
|
||||
float value = (event.getAxisValue(range.getAxis(), actionPointerIndex) - range.getMin()) / range.getRange() * 2.0f - 1.0f;
|
||||
SDLControllerManager.onNativeJoy(joystick.device_id, i, value);
|
||||
}
|
||||
for (int i = 0; i < joystick.hats.size() / 2; i++) {
|
||||
int hatX = Math.round(event.getAxisValue(joystick.hats.get(2 * i).getAxis(), actionPointerIndex));
|
||||
int hatY = Math.round(event.getAxisValue(joystick.hats.get(2 * i + 1).getAxis(), actionPointerIndex));
|
||||
SDLControllerManager.onNativeHat(joystick.device_id, i, hatX, hatY);
|
||||
}
|
||||
int actionPointerIndex = event.getActionIndex();
|
||||
int action = event.getActionMasked();
|
||||
if (action == MotionEvent.ACTION_MOVE) {
|
||||
SDLJoystick joystick = getJoystick(event.getDeviceId());
|
||||
if (joystick != null) {
|
||||
for (int i = 0; i < joystick.axes.size(); i++) {
|
||||
InputDevice.MotionRange range = joystick.axes.get(i);
|
||||
/* Normalize the value to -1...1 */
|
||||
float value = (event.getAxisValue(range.getAxis(), actionPointerIndex) - range.getMin()) / range.getRange() * 2.0f - 1.0f;
|
||||
SDLControllerManager.onNativeJoy(joystick.device_id, i, value);
|
||||
}
|
||||
for (int i = 0; i < joystick.hats.size() / 2; i++) {
|
||||
int hatX = Math.round(event.getAxisValue(joystick.hats.get(2 * i).getAxis(), actionPointerIndex));
|
||||
int hatY = Math.round(event.getAxisValue(joystick.hats.get(2 * i + 1).getAxis(), actionPointerIndex));
|
||||
SDLControllerManager.onNativeHat(joystick.device_id, i, hatX, hatY);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -293,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;
|
||||
}
|
||||
@@ -310,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;
|
||||
@@ -319,6 +383,7 @@ class SDLJoystickHandler_API19 extends SDLJoystickHandler_API16 {
|
||||
KeyEvent.KEYCODE_BUTTON_X,
|
||||
KeyEvent.KEYCODE_BUTTON_Y,
|
||||
KeyEvent.KEYCODE_BACK,
|
||||
KeyEvent.KEYCODE_MENU,
|
||||
KeyEvent.KEYCODE_BUTTON_MODE,
|
||||
KeyEvent.KEYCODE_BUTTON_START,
|
||||
KeyEvent.KEYCODE_BUTTON_THUMBL,
|
||||
@@ -360,6 +425,7 @@ class SDLJoystickHandler_API19 extends SDLJoystickHandler_API16 {
|
||||
(1 << 2), // X -> X
|
||||
(1 << 3), // Y -> Y
|
||||
(1 << 4), // BACK -> BACK
|
||||
(1 << 6), // MENU -> START
|
||||
(1 << 5), // MODE -> GUIDE
|
||||
(1 << 6), // START -> START
|
||||
(1 << 7), // THUMBL -> LEFTSTICK
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -560,8 +628,6 @@ class SDLGenericMotionListener_API12 implements View.OnGenericMotionListener {
|
||||
|
||||
switch ( event.getSource() ) {
|
||||
case InputDevice.SOURCE_JOYSTICK:
|
||||
case InputDevice.SOURCE_GAMEPAD:
|
||||
case InputDevice.SOURCE_DPAD:
|
||||
return SDLControllerManager.handleJoystickMotionEvent(event);
|
||||
|
||||
case InputDevice.SOURCE_MOUSE:
|
||||
@@ -691,8 +757,6 @@ class SDLGenericMotionListener_API26 extends SDLGenericMotionListener_API24 {
|
||||
|
||||
switch ( event.getSource() ) {
|
||||
case InputDevice.SOURCE_JOYSTICK:
|
||||
case InputDevice.SOURCE_GAMEPAD:
|
||||
case InputDevice.SOURCE_DPAD:
|
||||
return SDLControllerManager.handleJoystickMotionEvent(event);
|
||||
|
||||
case InputDevice.SOURCE_MOUSE:
|
||||
@@ -747,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
|
||||
@@ -757,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 {
|
||||
|
||||
@@ -0,0 +1,405 @@
|
||||
package org.libsdl.app;
|
||||
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.hardware.Sensor;
|
||||
import android.hardware.SensorEvent;
|
||||
import android.hardware.SensorEventListener;
|
||||
import android.hardware.SensorManager;
|
||||
import android.os.Build;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.util.Log;
|
||||
import android.view.Display;
|
||||
import android.view.InputDevice;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.Surface;
|
||||
import android.view.SurfaceHolder;
|
||||
import android.view.SurfaceView;
|
||||
import android.view.View;
|
||||
import android.view.WindowManager;
|
||||
|
||||
|
||||
/**
|
||||
SDLSurface. This is what we draw on, so we need to know when it's created
|
||||
in order to do anything useful.
|
||||
|
||||
Because of this, that's where we set up the SDL thread
|
||||
*/
|
||||
public class SDLSurface extends SurfaceView implements SurfaceHolder.Callback,
|
||||
View.OnKeyListener, View.OnTouchListener, SensorEventListener {
|
||||
|
||||
// Sensors
|
||||
protected SensorManager mSensorManager;
|
||||
protected Display mDisplay;
|
||||
|
||||
// Keep track of the surface size to normalize touch events
|
||||
protected float mWidth, mHeight;
|
||||
|
||||
// Is SurfaceView ready for rendering
|
||||
public boolean mIsSurfaceReady;
|
||||
|
||||
// Startup
|
||||
public SDLSurface(Context context) {
|
||||
super(context);
|
||||
getHolder().addCallback(this);
|
||||
|
||||
setFocusable(true);
|
||||
setFocusableInTouchMode(true);
|
||||
requestFocus();
|
||||
setOnKeyListener(this);
|
||||
setOnTouchListener(this);
|
||||
|
||||
mDisplay = ((WindowManager)context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
|
||||
mSensorManager = (SensorManager)context.getSystemService(Context.SENSOR_SERVICE);
|
||||
|
||||
setOnGenericMotionListener(SDLActivity.getMotionListener());
|
||||
|
||||
// Some arbitrary defaults to avoid a potential division by zero
|
||||
mWidth = 1.0f;
|
||||
mHeight = 1.0f;
|
||||
|
||||
mIsSurfaceReady = false;
|
||||
}
|
||||
|
||||
public void handlePause() {
|
||||
enableSensor(Sensor.TYPE_ACCELEROMETER, false);
|
||||
}
|
||||
|
||||
public void handleResume() {
|
||||
setFocusable(true);
|
||||
setFocusableInTouchMode(true);
|
||||
requestFocus();
|
||||
setOnKeyListener(this);
|
||||
setOnTouchListener(this);
|
||||
enableSensor(Sensor.TYPE_ACCELEROMETER, true);
|
||||
}
|
||||
|
||||
public Surface getNativeSurface() {
|
||||
return getHolder().getSurface();
|
||||
}
|
||||
|
||||
// Called when we have a valid drawing surface
|
||||
@Override
|
||||
public void surfaceCreated(SurfaceHolder holder) {
|
||||
Log.v("SDL", "surfaceCreated()");
|
||||
SDLActivity.onNativeSurfaceCreated();
|
||||
}
|
||||
|
||||
// Called when we lose the surface
|
||||
@Override
|
||||
public void surfaceDestroyed(SurfaceHolder holder) {
|
||||
Log.v("SDL", "surfaceDestroyed()");
|
||||
|
||||
// Transition to pause, if needed
|
||||
SDLActivity.mNextNativeState = SDLActivity.NativeState.PAUSED;
|
||||
SDLActivity.handleNativeState();
|
||||
|
||||
mIsSurfaceReady = false;
|
||||
SDLActivity.onNativeSurfaceDestroyed();
|
||||
}
|
||||
|
||||
// Called when the surface is resized
|
||||
@Override
|
||||
public void surfaceChanged(SurfaceHolder holder,
|
||||
int format, int width, int height) {
|
||||
Log.v("SDL", "surfaceChanged()");
|
||||
|
||||
if (SDLActivity.mSingleton == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
mWidth = width;
|
||||
mHeight = height;
|
||||
int nDeviceWidth = width;
|
||||
int nDeviceHeight = height;
|
||||
try
|
||||
{
|
||||
if (Build.VERSION.SDK_INT >= 17 /* Android 4.2 (JELLY_BEAN_MR1) */) {
|
||||
DisplayMetrics realMetrics = new DisplayMetrics();
|
||||
mDisplay.getRealMetrics( realMetrics );
|
||||
nDeviceWidth = realMetrics.widthPixels;
|
||||
nDeviceHeight = realMetrics.heightPixels;
|
||||
}
|
||||
} catch(Exception ignored) {
|
||||
}
|
||||
|
||||
synchronized(SDLActivity.getContext()) {
|
||||
// In case we're waiting on a size change after going fullscreen, send a notification.
|
||||
SDLActivity.getContext().notifyAll();
|
||||
}
|
||||
|
||||
Log.v("SDL", "Window size: " + width + "x" + height);
|
||||
Log.v("SDL", "Device size: " + nDeviceWidth + "x" + nDeviceHeight);
|
||||
SDLActivity.nativeSetScreenResolution(width, height, nDeviceWidth, nDeviceHeight, mDisplay.getRefreshRate());
|
||||
SDLActivity.onNativeResize();
|
||||
|
||||
// Prevent a screen distortion glitch,
|
||||
// for instance when the device is in Landscape and a Portrait App is resumed.
|
||||
boolean skip = false;
|
||||
int requestedOrientation = SDLActivity.mSingleton.getRequestedOrientation();
|
||||
|
||||
if (requestedOrientation == ActivityInfo.SCREEN_ORIENTATION_PORTRAIT || requestedOrientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT) {
|
||||
if (mWidth > mHeight) {
|
||||
skip = true;
|
||||
}
|
||||
} else if (requestedOrientation == ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE || requestedOrientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE) {
|
||||
if (mWidth < mHeight) {
|
||||
skip = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Special Patch for Square Resolution: Black Berry Passport
|
||||
if (skip) {
|
||||
double min = Math.min(mWidth, mHeight);
|
||||
double max = Math.max(mWidth, mHeight);
|
||||
|
||||
if (max / min < 1.20) {
|
||||
Log.v("SDL", "Don't skip on such aspect-ratio. Could be a square resolution.");
|
||||
skip = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Don't skip in MultiWindow.
|
||||
if (skip) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (skip) {
|
||||
Log.v("SDL", "Skip .. Surface is not ready.");
|
||||
mIsSurfaceReady = false;
|
||||
return;
|
||||
}
|
||||
|
||||
/* If the surface has been previously destroyed by onNativeSurfaceDestroyed, recreate it here */
|
||||
SDLActivity.onNativeSurfaceChanged();
|
||||
|
||||
/* Surface is ready */
|
||||
mIsSurfaceReady = true;
|
||||
|
||||
SDLActivity.mNextNativeState = SDLActivity.NativeState.RESUMED;
|
||||
SDLActivity.handleNativeState();
|
||||
}
|
||||
|
||||
// Key events
|
||||
@Override
|
||||
public boolean onKey(View v, int keyCode, KeyEvent event) {
|
||||
return SDLActivity.handleKeyEvent(v, keyCode, event, null);
|
||||
}
|
||||
|
||||
// Touch events
|
||||
@Override
|
||||
public boolean onTouch(View v, MotionEvent event) {
|
||||
/* Ref: http://developer.android.com/training/gestures/multi.html */
|
||||
int touchDevId = event.getDeviceId();
|
||||
final int pointerCount = event.getPointerCount();
|
||||
int action = event.getActionMasked();
|
||||
int pointerFingerId;
|
||||
int i = -1;
|
||||
float x,y,p;
|
||||
|
||||
/*
|
||||
* Prevent id to be -1, since it's used in SDL internal for synthetic events
|
||||
* Appears when using Android emulator, eg:
|
||||
* adb shell input mouse tap 100 100
|
||||
* adb shell input touchscreen tap 100 100
|
||||
*/
|
||||
if (touchDevId < 0) {
|
||||
touchDevId -= 1;
|
||||
}
|
||||
|
||||
// 12290 = Samsung DeX mode desktop mouse
|
||||
// 12290 = 0x3002 = 0x2002 | 0x1002 = SOURCE_MOUSE | SOURCE_TOUCHSCREEN
|
||||
// 0x2 = SOURCE_CLASS_POINTER
|
||||
if (event.getSource() == InputDevice.SOURCE_MOUSE || event.getSource() == (InputDevice.SOURCE_MOUSE | InputDevice.SOURCE_TOUCHSCREEN)) {
|
||||
int mouseButton = 1;
|
||||
try {
|
||||
Object object = event.getClass().getMethod("getButtonState").invoke(event);
|
||||
if (object != null) {
|
||||
mouseButton = (Integer) object;
|
||||
}
|
||||
} catch(Exception ignored) {
|
||||
}
|
||||
|
||||
// We need to check if we're in relative mouse mode and get the axis offset rather than the x/y values
|
||||
// if we are. We'll leverage our existing mouse motion listener
|
||||
SDLGenericMotionListener_API12 motionListener = SDLActivity.getMotionListener();
|
||||
x = motionListener.getEventX(event);
|
||||
y = motionListener.getEventY(event);
|
||||
|
||||
SDLActivity.onNativeMouse(mouseButton, action, x, y, motionListener.inRelativeMode());
|
||||
} else {
|
||||
switch(action) {
|
||||
case MotionEvent.ACTION_MOVE:
|
||||
for (i = 0; i < pointerCount; i++) {
|
||||
pointerFingerId = event.getPointerId(i);
|
||||
x = event.getX(i) / mWidth;
|
||||
y = event.getY(i) / mHeight;
|
||||
p = event.getPressure(i);
|
||||
if (p > 1.0f) {
|
||||
// may be larger than 1.0f on some devices
|
||||
// see the documentation of getPressure(i)
|
||||
p = 1.0f;
|
||||
}
|
||||
SDLActivity.onNativeTouch(touchDevId, pointerFingerId, action, x, y, p);
|
||||
}
|
||||
break;
|
||||
|
||||
case MotionEvent.ACTION_UP:
|
||||
case MotionEvent.ACTION_DOWN:
|
||||
// Primary pointer up/down, the index is always zero
|
||||
i = 0;
|
||||
/* fallthrough */
|
||||
case MotionEvent.ACTION_POINTER_UP:
|
||||
case MotionEvent.ACTION_POINTER_DOWN:
|
||||
// Non primary pointer up/down
|
||||
if (i == -1) {
|
||||
i = event.getActionIndex();
|
||||
}
|
||||
|
||||
pointerFingerId = event.getPointerId(i);
|
||||
x = event.getX(i) / mWidth;
|
||||
y = event.getY(i) / mHeight;
|
||||
p = event.getPressure(i);
|
||||
if (p > 1.0f) {
|
||||
// may be larger than 1.0f on some devices
|
||||
// see the documentation of getPressure(i)
|
||||
p = 1.0f;
|
||||
}
|
||||
SDLActivity.onNativeTouch(touchDevId, pointerFingerId, action, x, y, p);
|
||||
break;
|
||||
|
||||
case MotionEvent.ACTION_CANCEL:
|
||||
for (i = 0; i < pointerCount; i++) {
|
||||
pointerFingerId = event.getPointerId(i);
|
||||
x = event.getX(i) / mWidth;
|
||||
y = event.getY(i) / mHeight;
|
||||
p = event.getPressure(i);
|
||||
if (p > 1.0f) {
|
||||
// may be larger than 1.0f on some devices
|
||||
// see the documentation of getPressure(i)
|
||||
p = 1.0f;
|
||||
}
|
||||
SDLActivity.onNativeTouch(touchDevId, pointerFingerId, MotionEvent.ACTION_UP, x, y, p);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Sensor events
|
||||
public void enableSensor(int sensortype, boolean enabled) {
|
||||
// TODO: This uses getDefaultSensor - what if we have >1 accels?
|
||||
if (enabled) {
|
||||
mSensorManager.registerListener(this,
|
||||
mSensorManager.getDefaultSensor(sensortype),
|
||||
SensorManager.SENSOR_DELAY_GAME, null);
|
||||
} else {
|
||||
mSensorManager.unregisterListener(this,
|
||||
mSensorManager.getDefaultSensor(sensortype));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAccuracyChanged(Sensor sensor, int accuracy) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSensorChanged(SensorEvent event) {
|
||||
if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
|
||||
|
||||
// Since we may have an orientation set, we won't receive onConfigurationChanged events.
|
||||
// We thus should check here.
|
||||
int newOrientation;
|
||||
|
||||
float x, y;
|
||||
switch (mDisplay.getRotation()) {
|
||||
case Surface.ROTATION_90:
|
||||
x = -event.values[1];
|
||||
y = event.values[0];
|
||||
newOrientation = SDLActivity.SDL_ORIENTATION_LANDSCAPE;
|
||||
break;
|
||||
case Surface.ROTATION_270:
|
||||
x = event.values[1];
|
||||
y = -event.values[0];
|
||||
newOrientation = SDLActivity.SDL_ORIENTATION_LANDSCAPE_FLIPPED;
|
||||
break;
|
||||
case Surface.ROTATION_180:
|
||||
x = -event.values[0];
|
||||
y = -event.values[1];
|
||||
newOrientation = SDLActivity.SDL_ORIENTATION_PORTRAIT_FLIPPED;
|
||||
break;
|
||||
case Surface.ROTATION_0:
|
||||
default:
|
||||
x = event.values[0];
|
||||
y = event.values[1];
|
||||
newOrientation = SDLActivity.SDL_ORIENTATION_PORTRAIT;
|
||||
break;
|
||||
}
|
||||
|
||||
if (newOrientation != SDLActivity.mCurrentOrientation) {
|
||||
SDLActivity.mCurrentOrientation = newOrientation;
|
||||
SDLActivity.onNativeOrientationChanged(newOrientation);
|
||||
}
|
||||
|
||||
SDLActivity.onNativeAccel(-x / SensorManager.GRAVITY_EARTH,
|
||||
y / SensorManager.GRAVITY_EARTH,
|
||||
event.values[2] / SensorManager.GRAVITY_EARTH);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// Captured pointer events for API 26.
|
||||
public boolean onCapturedPointerEvent(MotionEvent event)
|
||||
{
|
||||
int action = event.getActionMasked();
|
||||
|
||||
float x, y;
|
||||
switch (action) {
|
||||
case MotionEvent.ACTION_SCROLL:
|
||||
x = event.getAxisValue(MotionEvent.AXIS_HSCROLL, 0);
|
||||
y = event.getAxisValue(MotionEvent.AXIS_VSCROLL, 0);
|
||||
SDLActivity.onNativeMouse(0, action, x, y, false);
|
||||
return true;
|
||||
|
||||
case MotionEvent.ACTION_HOVER_MOVE:
|
||||
case MotionEvent.ACTION_MOVE:
|
||||
x = event.getX(0);
|
||||
y = event.getY(0);
|
||||
SDLActivity.onNativeMouse(0, action, x, y, true);
|
||||
return true;
|
||||
|
||||
case MotionEvent.ACTION_BUTTON_PRESS:
|
||||
case MotionEvent.ACTION_BUTTON_RELEASE:
|
||||
|
||||
// Change our action value to what SDL's code expects.
|
||||
if (action == MotionEvent.ACTION_BUTTON_PRESS) {
|
||||
action = MotionEvent.ACTION_DOWN;
|
||||
} else { /* MotionEvent.ACTION_BUTTON_RELEASE */
|
||||
action = MotionEvent.ACTION_UP;
|
||||
}
|
||||
|
||||
x = event.getX(0);
|
||||
y = event.getY(0);
|
||||
int button = event.getButtonState();
|
||||
|
||||
SDLActivity.onNativeMouse(button, action, x, y, true);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
<TextView android:id="@+id/license_text"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="20dp" />
|
||||
</ScrollView>
|
||||
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent">
|
||||
<ListView android:id="@+id/list"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent" />
|
||||
</LinearLayout>
|
||||
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
<ListView android:id="@+id/list"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
<ScrollView android:id="@+id/empty"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
<TextView android:id="@+id/usage"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="20dp" />
|
||||
</ScrollView>
|
||||
</LinearLayout>
|
||||
@@ -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,9 +1,18 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item
|
||||
android:id="@+id/install_from_zip"
|
||||
android:title="@string/action_install_from_zip" />
|
||||
<item
|
||||
android:id="@+id/export_savedata"
|
||||
android:title="@string/action_export_save_data" />
|
||||
<item
|
||||
android:id="@+id/import_savedata"
|
||||
android:title="@string/action_import_save_data" />
|
||||
<item
|
||||
android:id="@+id/help"
|
||||
android:title="@string/action_help" />
|
||||
<item
|
||||
android:id="@+id/licenses"
|
||||
android:title="@string/action_licenses" />
|
||||
</menu>
|
||||
@@ -2,13 +2,15 @@
|
||||
<resources>
|
||||
<string name="app_name">xsystem35</string>
|
||||
<string name="action_export_save_data">セーブデータをエクスポート</string>
|
||||
<string name="action_help">使い方</string>
|
||||
<string name="action_import_save_data">セーブデータをインポート</string>
|
||||
<string name="action_install_from_zip">ZIPからインストール</string>
|
||||
<string name="action_licenses">オープンソースライセンス</string>
|
||||
<string name="cancel">キャンセル</string>
|
||||
<string name="cannot_find_ald">System 3.x のファイル (*.ald) が見つかりません。</string>
|
||||
<string name="choose_a_file">ファイルを選択</string>
|
||||
<string name="error_dialog_title">エラー</string>
|
||||
<string name="install_dialog_title">インストール中…</string>
|
||||
<string name="install_from_zip">ZIP からインストール</string>
|
||||
<string name="install_progress">%s を展開中</string>
|
||||
<string name="no_data_to_import">ZIP アーカイブ中に save/ フォルダが見つかりません。</string>
|
||||
<string name="save_data_export_error">セーブデータのエクスポートに失敗しました。</string>
|
||||
@@ -18,4 +20,21 @@
|
||||
<string name="uninstall_dialog_title">確認</string>
|
||||
<string name="unsupported_zip">この形式の ZIP はサポートしていません。</string>
|
||||
<string name="zip_extraction_error">ZIP の展開に失敗しました。</string>
|
||||
<string name="usage">
|
||||
<![CDATA[
|
||||
<h1>ゲームのインストール方法</h1>
|
||||
<p>1. PC上で、ゲームのファイルが入ったZIPを用意します。例えば以下のようなファイルを含めます:</p>
|
||||
<div>
|
||||
・鬼畜王SA.ALD<br>
|
||||
・鬼畜王GA.ALD<br>
|
||||
・鬼畜王GB.ALD<br>
|
||||
・鬼畜王WA.ALD<br>
|
||||
・02.mp3<br>
|
||||
・03.mp3<br>
|
||||
・…<br>
|
||||
</div>
|
||||
<p>2. ZIPファイルを (例えばUSB経由で) PCからデバイスに転送します。</p>
|
||||
<p>3. この画面の右上のメニューボタンをタップして「ZIPからインストール」を選択し、転送したZIPを選びます。</p>
|
||||
]]>
|
||||
</string>
|
||||
</resources>
|
||||
@@ -1,13 +1,15 @@
|
||||
<resources>
|
||||
<string name="app_name">xsystem35</string>
|
||||
<string name="action_export_save_data">Export Save Files</string>
|
||||
<string name="action_help">Help</string>
|
||||
<string name="action_import_save_data">Import Save Files</string>
|
||||
<string name="action_install_from_zip">Install from ZIP</string>
|
||||
<string name="action_licenses">Open source licenses</string>
|
||||
<string name="cancel">Cancel</string>
|
||||
<string name="cannot_find_ald">Cannot find System 3.x game files (*.ald).</string>
|
||||
<string name="choose_a_file">Choose a file</string>
|
||||
<string name="error_dialog_title">Error</string>
|
||||
<string name="install_dialog_title">Installing…</string>
|
||||
<string name="install_from_zip">Install from ZIP</string>
|
||||
<string name="install_progress">Extracting %s</string>
|
||||
<string name="no_data_to_import">No save/ folder in the ZIP archive.</string>
|
||||
<string name="ok">OK</string>
|
||||
@@ -18,4 +20,22 @@
|
||||
<string name="uninstall_dialog_title">Confirm</string>
|
||||
<string name="unsupported_zip">This type of ZIP is not supported.</string>
|
||||
<string name="zip_extraction_error">Failed to extract ZIP.</string>
|
||||
<string name="usage">
|
||||
<![CDATA[
|
||||
<h1>How to install a game</h1>
|
||||
<p>1. On your PC, prepare a ZIP containing the game files. For example, it should contain the following files:</p>
|
||||
<div>
|
||||
* KICHIKUSA.ALD<br>
|
||||
* KICHIKUGA.ALD<br>
|
||||
* KICHIKUGB.ALD<br>
|
||||
* KICHIKUWA.ALD<br>
|
||||
* System39.ain<br>
|
||||
* 02.mp3<br>
|
||||
* 03.mp3<br>
|
||||
* …<br>
|
||||
</div>
|
||||
<p>2. Transfer the ZIP file from your PC to the device (e.g. via USB).</p>
|
||||
<p>3. Tap the menu button at the upper-right of this screen, select "Install from ZIP," and choose the ZIP you transferred.</p>
|
||||
]]>
|
||||
</string>
|
||||
</resources>
|
||||
|
||||
@@ -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.3.72'
|
||||
ext.kotlin_version = '1.7.21'
|
||||
repositories {
|
||||
mavenCentral()
|
||||
google()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:4.0.1'
|
||||
classpath 'com.android.tools.build:gradle:8.7.3'
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||
|
||||
// NOTE: Do not place your application dependencies here; they belong
|
||||
|
||||
BIN
Binary file not shown.
+3
-3
@@ -1,6 +1,6 @@
|
||||
#Mon Aug 10 12:24:31 JST 2020
|
||||
#Thu Nov 11 18:20:34 PST 2021
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-bin.zip
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-all.zip
|
||||
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
-17
@@ -1,35 +1,20 @@
|
||||
#cmakedefine PACKAGE "@PACKAGE@"
|
||||
#define VERSION "2.2.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_JPEG @HAVE_JPEG@
|
||||
#cmakedefine HAVE_MMAP @HAVE_MMAP@
|
||||
#cmakedefine HAVE_SDLJOY @HAVE_SDLJOY@
|
||||
#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()
|
||||
|
||||
-189
@@ -1,189 +0,0 @@
|
||||
それぞれのゲームに付いての注意書き
|
||||
|
||||
[鬼畜王ランス]
|
||||
|
||||
[ランス4(for Win95)]
|
||||
|
||||
[闘神都市2(for Win95)]
|
||||
|
||||
[いけないかつみ先生]
|
||||
= 外字データには対応していません
|
||||
|
||||
[かえるにょぱにょ〜ん]
|
||||
= フロアデータ(floor_1.map 〜 floor_16.map) はセーブデータと同じディレク
|
||||
トリに置いてください。
|
||||
= 一部のキャラの絵と説明が違う(金魚と????)
|
||||
|
||||
[戦巫女]
|
||||
= 戦巫女は2枚組のCDで、Windows版では一部のデータをCD-ROMに置いたままゲーム
|
||||
することになっていますが、xsystem35 では CD-Audio と CD-ROM上のデータを
|
||||
同時に使用することは出来ません。ハードディスク等に全てのデータをインス
|
||||
トールするか、あるいは CD-Audio 以外の演奏方法(MP3等)を使用してください。
|
||||
CD-Audio を使う場合は2枚目の CD に音楽データが入っています。
|
||||
|
||||
[零式(アリスの館456版)]
|
||||
= マップデータ(MAP_DATA.DAT, UR_DATA.DATA)はセーブデータと同じディレクトリに
|
||||
置いてください。
|
||||
|
||||
[ATLACH=NACHA(アリスの館456版)]
|
||||
|
||||
[人間狩り(アリスの館456版)]
|
||||
|
||||
[アリスの館456]
|
||||
- DALK
|
||||
|
||||
- 闘神都市
|
||||
|
||||
- DrStop!
|
||||
|
||||
- ランス1
|
||||
|
||||
- ランス2
|
||||
|
||||
- ランス3
|
||||
|
||||
[王道勇者]
|
||||
|
||||
[ディアボリカ]
|
||||
|
||||
[AmbivalenZ(for Win95)]
|
||||
|
||||
[夢幻泡影 (for Win95)]
|
||||
|
||||
[ぱすてるチャイム]
|
||||
= ぱすてるチャイムでは明らかにシナリオにおかしいところがあります。
|
||||
そこで、これに対するパッチを作成しました。
|
||||
|
||||
patch というディレクトリの下に pastel.diff というパッチ当てのスクリプト
|
||||
がありますので、ゲームのシナリオデータのあるディレクトリにコピーして
|
||||
そのディレクトリに移動した後、 ./pastel.diff (シナリオファイル名) と
|
||||
実行してください。
|
||||
(例)
|
||||
> ./pastel.diff pastel_sa.ald
|
||||
|
||||
古いデータは pastel_sa.ald.org として保存されます。
|
||||
シナリオデータは Ver 1.00 と Ver 1.01 に適用できます。
|
||||
|
||||
(廉価版では直っている?)
|
||||
|
||||
[ぷろすちゅーでんとGood]
|
||||
|
||||
[守り神様]
|
||||
|
||||
[ママトト]
|
||||
|
||||
[HushByBaby]
|
||||
|
||||
[Darcrows]
|
||||
|
||||
[PERSIOM]
|
||||
= DirectSound(3D Sound) には対応していません。
|
||||
|
||||
[隠れ月]
|
||||
|
||||
[SeeIn青]
|
||||
|
||||
[廉価版・デアボリカ]
|
||||
|
||||
[廉価版・アトラクナクア]
|
||||
|
||||
[廉価版・かえるにょ・ぱにょん]
|
||||
|
||||
[廉価版・零式]
|
||||
|
||||
[かえるにょ国にょありす(20世紀アリス)]
|
||||
= 外部MIDIプレイヤーモードでは音楽がリピートされません。
|
||||
|
||||
[これDPS?(20世紀アリス)]
|
||||
|
||||
[夜が来る!]
|
||||
= 動きません
|
||||
|
||||
[王子さま Lv1]
|
||||
|
||||
[Only You 〜リ・クルス〜]
|
||||
|
||||
[大悪司]
|
||||
= オープニングが動かない
|
||||
|
||||
[王子さま Lv1.5]
|
||||
|
||||
[妻みぐい]
|
||||
= オープニングが動かない
|
||||
|
||||
[エスカレイヤー]
|
||||
= オープニングが動かない
|
||||
|
||||
[Rance5D]
|
||||
|
||||
[妻みぐい2]
|
||||
= オープニングが動かない
|
||||
|
||||
[DALK外伝]
|
||||
[ままにょにょ]
|
||||
= System4につき動きません
|
||||
|
||||
|
||||
/*
|
||||
* その他
|
||||
*/
|
||||
|
||||
* センチメンタルシーズン (Aliceの館 CDをベースに UNITBASE が移植したもの)
|
||||
= http://www4.big.or.jp/~unitbase/sys35sdk/games.html
|
||||
|
||||
* Intruder (Aliceの館 CDをベースに UNITBASE が移植したもの)
|
||||
= まだ完了していません
|
||||
|
||||
* Crecent Moon がぁる (Aliceの館 CDをベースに UNITBASE が移植したもの)
|
||||
= http://www4.big.or.jp/~unitbase/sys35sdk/games.html
|
||||
|
||||
* あぶない天狗伝説 (Aliceの館 CD2をベースに UNITBASE が移植したもの)
|
||||
= 掲載許可が下りません
|
||||
|
||||
* OnlyYou (system3版をベースに TOTOさんが移植したもの)
|
||||
= http://www1.interq.or.jp/t-takeda/index.html
|
||||
|
||||
* ランス4.1 (system3版をベースに TOTOさんが移植したもの)
|
||||
= http://www1.interq.or.jp/t-takeda/index.html
|
||||
= スプライトの色がおかしい
|
||||
|
||||
* ランス4.2 (system3版をベースに TOTOさんが移植したもの
|
||||
= http://www1.interq.or.jp/t-takeda/index.html
|
||||
= スプライトの色がおかしい
|
||||
|
||||
* アリスの館3 (system3版をベースに TOTOさんが移植したもの)
|
||||
= http://www1.interq.or.jp/t-takeda/index.html
|
||||
|
||||
* 乙女戦記 (system3版をベースに TOTOさんが移植したもの)
|
||||
= http://www1.interq.or.jp/t-takeda/index.html
|
||||
|
||||
* 闘神都市2外伝 (system3版をベースに TOTOさんが移植したもの)
|
||||
= http://www1.interq.or.jp/t-takeda/index.html
|
||||
|
||||
* DPS全部 (system3版をベースに TOTOさんが移植したもの)
|
||||
= http://www1.interq.or.jp/t-takeda/index.html
|
||||
|
||||
* ProStudentG (system3版をベースに TOTOさんが移植したもの)
|
||||
= http://www1.interq.or.jp/t-takeda/index.html
|
||||
|
||||
* 学園KING (AliceCD Ver 1.??)
|
||||
= CDが鳴らない
|
||||
-> TOTOさんが、CD-DAに対応するためのシナリオパッチをつくっています。
|
||||
http://www1.interq.or.jp/t-takeda/midi.html
|
||||
|
||||
|
||||
* メイドのススメ (AliceCD Ver 1.02)
|
||||
|
||||
* ぶろぶろ (AliceCD Ver 1.02)
|
||||
|
||||
* 学園漂流戦記 (AliceCD Ver 1.02)
|
||||
|
||||
* 扉 (AliceCD Ver 2.02)
|
||||
|
||||
* 妖精 (AliceCD Ver 2.02)
|
||||
|
||||
/*
|
||||
* 3rd party 製作 ゲーム
|
||||
*/
|
||||
|
||||
#include "MISCGAME.TXT"
|
||||
@@ -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
|
||||
のように書く事が出来ます。
|
||||
|
||||
コメントを書く場合は行頭に # をつけます。また空白行は無視されます。
|
||||
|
||||
@@ -1,58 +0,0 @@
|
||||
|
||||
その他の SYSTEM 3.5 のゲームについて
|
||||
|
||||
README にある動作確認ゲーム以外にも、ネット上で公開されているSYSTEM3.5対応
|
||||
のゲームのうち幾つかは動く事が確認されています。ここでは 1.4.0 preX での動作
|
||||
状況です。1.4.0 公開時点で手に入るゲームを順次追加していっています。
|
||||
また、XXXが動かないんだけど調べてください、XXXはちゃんと動きました、といった
|
||||
情報もおよせください。
|
||||
|
||||
OKは問題なく動く。GOODが多少の問題あるもののゲームをやるぶんで気にはなるけど
|
||||
耐えられる範囲のもの。BADは動かないものです。
|
||||
|
||||
|
||||
(作者の敬称略)
|
||||
【 ソフト名 】 【 ファイル名 】【 作者名 】【 動作 】
|
||||
国立ファーブル図
|
||||
書館司書〜
|
||||
ブックルちゃん〜 SSYO_100.LZH 大塚ヒロ OK
|
||||
バルーンぽっぷ BPOP_093.LZH 大塚ヒロ OK
|
||||
|
||||
Self self.lzh よこやまなおき OK
|
||||
おせろっと othellotto.exe よこやまなおき OK
|
||||
キャロル carol.lzh よこやまなおき GOOD(1)
|
||||
|
||||
積層四目並べ Te1.lzh 深叢 忍 OK
|
||||
16Piece Puzzle 16p1.lzh 深叢 忍 OK
|
||||
The Line Line0.lzh 深叢 忍 OK
|
||||
|
||||
Black Jack bj120.lzh かずき OK
|
||||
|
||||
マスカレイド (in AliceCD202) ちあぼう OK
|
||||
戦娘ver2.12 ikusa212.lzh ちあぼう OK
|
||||
|
||||
できるかなー! (in AliceCD202) KIMM SOFT OK(2)
|
||||
|
||||
恋は計算どおり♪ koi.lzh SS OK
|
||||
|
||||
動体視力を鍛えるにょ game_191.lzh LazyRichField BAD(3)
|
||||
集中力を鍛えるにょ game_22.lh LazyRichField GOOD(4)
|
||||
|
||||
|
||||
1) 雪が降らない (grDrawFillCircle が未実装)
|
||||
通信対戦が出来ない
|
||||
2) メッセージサイズ300ドットの表示は 100 ドットに制限しています
|
||||
3) DS 数字 となっている
|
||||
4) 色がおかしい
|
||||
|
||||
最後にこれらのデータを公開している作者の方々のURLです。
|
||||
|
||||
大塚ヒロさん http://www.studioHIRO.com/
|
||||
よこやまなおきさん http://www3.justnet.ne.jp/~naoki-yokoyama/
|
||||
深叢 忍さん http://www2s.biglobe.ne.jp/~nin/
|
||||
かずきさん http://www.din.or.jp/~kazuki/
|
||||
桐ヶ屋 inc.(ちあぼう)さん http://www.eucaly.net/~kiri
|
||||
KIMM SOFT/ネリワサヴィちーむ heavyd@syd.odn.ne.jp
|
||||
SSさん http://www.sspzgr.net/
|
||||
LazyRichFieldさん http://www2j.biglobe.ne.jp/~Lazy/staff/alice.htm
|
||||
|
||||
-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,150 @@
|
||||
= 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`,
|
||||
`rance2`, `rance3`, `rance3_eng`, `rance4_eng`, `rance4_v2`, `persiom`,
|
||||
`agake`.
|
||||
|
||||
*-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)*]
|
||||
@@ -10,12 +10,9 @@ find_program(PYFTSUBSET_FOUND pyftsubset)
|
||||
|
||||
if (PYFTSUBSET_FOUND)
|
||||
add_custom_target(fonts
|
||||
pyftsubset SourceHanSerifJP-Regular.otf --text-file=uchars.txt --output-file=${CMAKE_CURRENT_SOURCE_DIR}/mincho.otf
|
||||
DEPENDS uchars.txt SourceHanSerifJP-Regular.otf)
|
||||
|
||||
add_custom_command(OUTPUT uchars.txt
|
||||
COMMAND uchars > uchars.txt)
|
||||
|
||||
add_custom_command(OUTPUT SourceHanSerifJP-Regular.otf
|
||||
COMMAND wget -O SourceHanSerifJP-Regular.otf https://github.com/adobe-fonts/source-han-serif/blob/release/SubsetOTF/JP/SourceHanSerifJP-Regular.otf?raw=true)
|
||||
COMMAND uchars > uchars.txt
|
||||
COMMAND wget -O SourceHanSerifJP-Regular.otf https://github.com/adobe-fonts/source-han-serif/blob/release/SubsetOTF/JP/SourceHanSerifJP-Regular.otf?raw=true
|
||||
COMMAND pyftsubset SourceHanSerifJP-Regular.otf --text-file=uchars.txt --output-file=subset.otf
|
||||
COMMAND python3 ${CMAKE_CURRENT_SOURCE_DIR}/adjust_metrics.py subset.otf ${CMAKE_CURRENT_SOURCE_DIR}/mincho.otf
|
||||
)
|
||||
endif()
|
||||
|
||||
Executable
+22
@@ -0,0 +1,22 @@
|
||||
#!/usr/bin/env python3
|
||||
import sys
|
||||
from fontTools.ttLib import TTFont
|
||||
|
||||
if len(sys.argv) != 3:
|
||||
print('Usage: adjust_metrics.py infile outfile')
|
||||
exit(1)
|
||||
|
||||
font = TTFont(sys.argv[1])
|
||||
|
||||
hhea = font['hhea']
|
||||
os2 = font['OS/2']
|
||||
|
||||
if hhea.ascent != os2.sTypoAscender:
|
||||
print(f'Changing hhea.ascent from {hhea.ascent} to {os2.sTypoAscender}')
|
||||
hhea.ascent = os2.sTypoAscender
|
||||
|
||||
if hhea.descent != os2.sTypoDescender:
|
||||
print(f'Changing hhea.descent from {hhea.descent} to {os2.sTypoDescender}')
|
||||
hhea.descent = os2.sTypoDescender
|
||||
|
||||
font.save(sys.argv[2])
|
||||
Binary file not shown.
@@ -0,0 +1,85 @@
|
||||
Game Compatibility
|
||||
==================
|
||||
|
||||
| Game | Status | Notes |
|
||||
| ------------------------------------------- | ----------- | ----- |
|
||||
| 鬼畜王ランス | Supported | |
|
||||
| Kichikuou Rance (EN) | Supported | Fan translation |
|
||||
| RanceIV -教団の遺産- | Supported | Win95 edition and [Ver2.05](https://hannylaboratory.blogspot.com/2023/01/blog-post_26.html) |
|
||||
| Rance4 -Legacy of the Sect- (EN) | Supported | Fan translation |
|
||||
| 兰斯IV -教团的遗产- (CN) | Supported | Fan translation |
|
||||
| ランス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 |
|
||||
| 戦巫女 | Supported | Normal / Low-priced edition |
|
||||
| 零式 | Supported | From ALICEの館4・5・6 / Low-priced edition |
|
||||
| アトラク=ナクア | Supported | From ALICEの館4・5・6 / Low-priced edition |
|
||||
| Rance -光を求めて- | Supported | From ALICEの館4・5・6 |
|
||||
| Rance II -反逆の少女達- | Supported | From ALICEの館4・5・6 |
|
||||
| Rance III -リーザス陥落- | Supported | From ALICEの館4・5・6 |
|
||||
| DALK | Supported | From ALICEの館4・5・6 |
|
||||
| 闘神都市 | Supported | From ALICEの館4・5・6 |
|
||||
| Dr.STOP | Supported | From ALICEの館4・5・6 |
|
||||
| 人間狩り | Supported | From ALICEの館4・5・6 / アリスCD |
|
||||
| 女の子図鑑 | Unknown | From ALICEの館4・5・6 |
|
||||
| 恋のおわり | Unknown | |
|
||||
| 王道勇者 | Supported | |
|
||||
| AmbivalenZ | Supported | Win95 edition |
|
||||
| DiaboLiQuE | Supported | Normal / Low-priced edition |
|
||||
| 夢幻泡影 | Unknown | Win98 edition |
|
||||
| ぱすてるチャイム | Supported | See [patch/README.TXT](patch/README.TXT) |
|
||||
| ぷろすちゅーでんとGood | Supported | |
|
||||
| 守り神様 | Supported | |
|
||||
| ママトト | Supported | |
|
||||
| HUSHABY BABY | Supported | |
|
||||
| DARCROWS | Supported | |
|
||||
| 隠れ月 | Supported | |
|
||||
| PERSIOM | Supported | 3D sound is not supported |
|
||||
| SeeIn青 | Supported | |
|
||||
| かえるにょ国にょアリス | Supported | From 20世紀アリス |
|
||||
| これD・P・S? | Supported | From 20世紀アリス |
|
||||
| 夜が来る! | Unsupported | |
|
||||
| Only you ~リ・クルス~ | Supported | |
|
||||
| 大悪司 | Supported | Opening demo is not supported |
|
||||
| 王子さまLv1 | Supported | |
|
||||
| 王子さま1ヵ月後 | Supported | From 王子さまLV1.5 |
|
||||
| 白鳳の子分叩き | Supported | From 王子さまLV1.5 |
|
||||
| チェシャのお部屋1.5 | Supported | From 王子さまLV1.5 |
|
||||
| 王子さま1/16 | Supported | From 王子さまLV1.5 |
|
||||
| スパイ伊藤の「クイズ!俺にさぼらせろ」 | Supported | From 王子さまLV1.5 |
|
||||
| 妻みぐい | Supported | Opening demo is not supported |
|
||||
| 超昂天使エスカレイヤー | Supported | Opening demo is not supported |
|
||||
| ランス5D | Supported | |
|
||||
| Rance 5D - The Lonely Girl (EN) | Supported | MangaGamer version |
|
||||
| 俺の下であがけ | Supported | |
|
||||
| 楽園行 | Supported | |
|
||||
| 妻みぐい2 | Supported | |
|
||||
| シェル・クレイル | Supported | |
|
||||
| ナイトデーモン | Supported | |
|
||||
| Nor | Unsupported | |
|
||||
| 翡翠の眸 | Unsupported | |
|
||||
| 学園KING | Supported | From アリスCD |
|
||||
| 学園KING 番外編 | Supported | From アリスCD |
|
||||
| 蒼海に墜ちて | Supported | From アリスCD |
|
||||
| ぶろぶろ | Supported | From アリスCD |
|
||||
| 裸ぶろぶろ狂 | Supported | From アリスCD |
|
||||
| メイドのススメ | Supported | From アリスCD |
|
||||
| 学園漂流戦記 | Supported | From アリスCD |
|
||||
| 学園漂流戦記2 | Supported | From アリスCD |
|
||||
| 当たって!!KUDAKERO 予告編 | Supported | From アリスCD |
|
||||
| 妖精 | Supported | From アリスCD |
|
||||
| [扉] | Supported | From アリスCD |
|
||||
| 叩き殺し太郎 | Supported | From アリスCD |
|
||||
| バルーンぽっぷ | Supported | 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 | Unsupported | From アリスCD |
|
||||
| Klavier | Supported | From アリスCD |
|
||||
| 弱肉狂食 | Supported | From アリスCD |
|
||||
| 眼鏡大戦2 | Supported | From アリスCD |
|
||||
| 妄想くん | Supported | From アリスCD |
|
||||
@@ -16,21 +16,21 @@ static void Init() {
|
||||
|
||||
*var = 1;
|
||||
|
||||
DEBUG_COMMAND_YET("AliceLogo.Init %d,%d,%d,%p:\n", p1, p2, p3, var);
|
||||
TRACE_UNIMPLEMENTED("AliceLogo.Init %d,%d,%d,%p:", p1, p2, p3, var);
|
||||
}
|
||||
|
||||
static void SetWaveNum() {
|
||||
int p1 = getCaliValue();
|
||||
int p2 = getCaliValue();
|
||||
|
||||
DEBUG_COMMAND_YET("AliceLogo.SetWaveNum %d,%d:\n", p1, p2);
|
||||
TRACE_UNIMPLEMENTED("AliceLogo.SetWaveNum %d,%d:", p1, p2);
|
||||
}
|
||||
|
||||
static void Run() {
|
||||
int p1 = getCaliValue();
|
||||
int p2 = getCaliValue();
|
||||
|
||||
DEBUG_COMMAND_YET("AliceLogo.Run %d,%d:\n", p1, p2);
|
||||
TRACE_UNIMPLEMENTED("AliceLogo.Run %d,%d:", p1, p2);
|
||||
}
|
||||
|
||||
static const ModuleFunc functions[] = {
|
||||
|
||||
+9
-49
@@ -5,7 +5,12 @@ add_library(modules STATIC
|
||||
AliceLogo/AliceLogo.c
|
||||
Confirm/Confirm.c
|
||||
Gpx/Gpx.c
|
||||
Gpx/cg.c
|
||||
Gpx/effectcopy.c
|
||||
Gpx/graph_copy_amap.c
|
||||
Gpx/graph_fillrect_amap.c
|
||||
Gpx/graph.c
|
||||
Gpx/surface.c
|
||||
Math/Math.c
|
||||
MsgSkip/MsgSkip.c
|
||||
NIGHTDLL/NIGHTDLL.c
|
||||
@@ -23,10 +28,10 @@ add_library(modules STATIC
|
||||
NIGHTDLL/nt_sound.c
|
||||
NightDemonDemo/NightDemonDemo.c
|
||||
RandMT/RandMT.c
|
||||
S3xMusic/S3xMusic.c
|
||||
SACT/SACT.c
|
||||
SACT/sactcg.c
|
||||
SACT/sactsound.c
|
||||
SACT/sactbgm.c
|
||||
SACT/sacttimer.c
|
||||
SACT/sactstring.c
|
||||
SACT/sactcrypto.c
|
||||
@@ -61,29 +66,8 @@ add_library(modules STATIC
|
||||
eeDemo/eeDemo.c
|
||||
lib/alk.c
|
||||
lib/drawtext.c
|
||||
lib/graph.c
|
||||
lib/list.c
|
||||
lib/surface.c
|
||||
lib/cg.c
|
||||
lib/graph_expandcolor_blend.c
|
||||
lib/graph_fillrect.c
|
||||
lib/graph_fillrect_amap.c
|
||||
lib/graph_fillrect_acolor.c
|
||||
lib/graph_rect.c
|
||||
lib/graph_copy.c
|
||||
lib/graph_copy_amap.c
|
||||
lib/graph_copy_bright.c
|
||||
lib/graph_copy_whiteout.c
|
||||
lib/graph_blend_amap.c
|
||||
lib/graph_blend_screen.c
|
||||
lib/graph_saturadd_amap.c
|
||||
lib/graph_draw_amap.c
|
||||
lib/graph_stretch.c
|
||||
lib/graph_cg.c
|
||||
lib/graph_buller.c
|
||||
lib/gre_blend_useamap.c
|
||||
lib/gre_blend.c
|
||||
lib/gre_blend_screen.c
|
||||
nDEMO/nDEMO.c
|
||||
nDEMOE/nDEMOE.c
|
||||
oDEMO/oDEMO.c
|
||||
@@ -101,31 +85,7 @@ endif()
|
||||
|
||||
target_compile_options(modules PRIVATE -Wno-pointer-sign)
|
||||
|
||||
if (EMSCRIPTEN)
|
||||
set(LIBS
|
||||
"SHELL:-s USE_ZLIB=1"
|
||||
"SHELL:-s USE_LIBJPEG=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()
|
||||
endif()
|
||||
|
||||
if (HAVE_JPEG)
|
||||
target_sources(modules PRIVATE
|
||||
NightDemonDemo/ndd.c
|
||||
NightDemonDemo/jpeg2surface.c
|
||||
)
|
||||
if (NOT EMSCRIPTEN)
|
||||
target_link_libraries(modules PRIVATE JPEG::JPEG)
|
||||
endif()
|
||||
target_link_libraries(modules PRIVATE sdl2 zlib)
|
||||
if (TARGET sdl2_mixer)
|
||||
target_link_libraries(modules PRIVATE sdl2_mixer)
|
||||
endif()
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
static void Init() {
|
||||
int p1 = getCaliValue();
|
||||
|
||||
DEBUG_COMMAND_YET("Confirm.Init %d:\n", p1);
|
||||
TRACE_UNIMPLEMENTED("Confirm.Init %d:", p1);
|
||||
}
|
||||
|
||||
static void ExistKeyFile() {
|
||||
@@ -20,7 +20,7 @@ static void ExistKeyFile() {
|
||||
|
||||
*var = 1;
|
||||
|
||||
DEBUG_COMMAND_YET("Confirm.ExistKeyFile %s,%p,%p:\n",p1, p2, var);
|
||||
TRACE_UNIMPLEMENTED("Confirm.ExistKeyFile %s,%p,%p:",p1, p2, var);
|
||||
}
|
||||
|
||||
static void CheckProtectFile() {
|
||||
@@ -30,7 +30,7 @@ static void CheckProtectFile() {
|
||||
|
||||
*var = 1;
|
||||
|
||||
DEBUG_COMMAND_YET("Confirm.CheckProtectFile %s,%p,%p:\n", p1,p2,var);
|
||||
TRACE_UNIMPLEMENTED("Confirm.CheckProtectFile %s,%p,%p:", p1,p2,var);
|
||||
}
|
||||
|
||||
static void CreateKeyFile() {
|
||||
@@ -40,7 +40,7 @@ static void CreateKeyFile() {
|
||||
|
||||
*var = 1;
|
||||
|
||||
DEBUG_COMMAND_YET("Confirm.CreateKeyFile %s,%p,%p:\n", p1,p2,var);
|
||||
TRACE_UNIMPLEMENTED("Confirm.CreateKeyFile %s,%p,%p:", p1,p2,var);
|
||||
}
|
||||
|
||||
static const ModuleFunc functions[] = {
|
||||
|
||||
+122
-152
@@ -42,7 +42,7 @@
|
||||
// #include "alpha_plane.h"
|
||||
#include "surface.h"
|
||||
#include "graph.h"
|
||||
// #include "graph2.h"
|
||||
#include "graph_blend_amap.h"
|
||||
|
||||
#include "effectcopy.h"
|
||||
#include "ngraph.h"
|
||||
@@ -68,37 +68,19 @@ static int find_null_surface() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sf_free_one(int no) {
|
||||
surface_t *s;
|
||||
if (no == 0) return NG;
|
||||
|
||||
s = suf[no];
|
||||
if (s == NULL) return NG;
|
||||
|
||||
if (s->pixel) free(s->pixel);
|
||||
if (s->alpha) free(s->alpha);
|
||||
free(s);
|
||||
|
||||
static void sf_free_one(int no) {
|
||||
if (no == 0 || !suf[no]) return;
|
||||
sf_free(suf[no]);
|
||||
suf[no] = NULL;
|
||||
pre_freesurfno = no;
|
||||
return OK;
|
||||
}
|
||||
|
||||
static int sf_free_all() {
|
||||
int i;
|
||||
surface_t *s;
|
||||
|
||||
for (i = 1; i < MAX_SURFACE; i++) {
|
||||
if (suf[i] == NULL) continue;
|
||||
s = suf[i];
|
||||
if (s->pixel) free(s->pixel);
|
||||
if (s->alpha) free(s->alpha);
|
||||
free(s);
|
||||
static void sf_free_all() {
|
||||
for (int i = 1; i < MAX_SURFACE; i++) {
|
||||
sf_free(suf[i]);
|
||||
suf[i] = NULL;
|
||||
}
|
||||
|
||||
pre_freesurfno = 1;
|
||||
return OK;
|
||||
}
|
||||
|
||||
static surface_t *sf_get(int no) {
|
||||
@@ -113,7 +95,7 @@ static int load_cg_main(int no) {
|
||||
int sno;
|
||||
|
||||
if (sf == NULL) {
|
||||
WARNING("load fail(cg==NULL,no=%d)\n", no);
|
||||
WARNING("load fail(cg==NULL,no=%d)", no);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -136,7 +118,11 @@ static void Init() {
|
||||
// surface0 を pre_freesurfno として返さないように。
|
||||
pre_freesurfno = 1;
|
||||
|
||||
DEBUG_COMMAND("Gpx.Init %d:\n", p1);
|
||||
TRACE("Gpx.Init %d:", p1);
|
||||
}
|
||||
|
||||
static void Gpx_reset(void) {
|
||||
sf_free_all();
|
||||
}
|
||||
|
||||
static void Create() {
|
||||
@@ -147,18 +133,15 @@ static void Create() {
|
||||
作成に失敗した場合は 0 を返す
|
||||
width : surface の幅
|
||||
height: surface の高さ
|
||||
bpp : surface の深さ(オリジナルでは24bppのみサポート,
|
||||
xsystem35 では display の depth と同じ)
|
||||
bpp : surface の深さ(24bppのみサポート)
|
||||
*/
|
||||
int *var = getCaliVariable();
|
||||
int width = getCaliValue();
|
||||
int height = getCaliValue();
|
||||
int bpp = getCaliValue();
|
||||
surface_t *s;
|
||||
|
||||
//get_surface0();
|
||||
s = sf_create_surface(width, height, sf_get(0)->depth);
|
||||
|
||||
|
||||
surface_t *s = sf_create_surface(width, height);
|
||||
|
||||
if (s == NULL) {
|
||||
*var = 0;
|
||||
} else {
|
||||
@@ -167,7 +150,7 @@ static void Create() {
|
||||
suf[no] = s;
|
||||
}
|
||||
|
||||
DEBUG_COMMAND("Gpx.Create %p,%d,%d,%d:\n", var, width, height, bpp);
|
||||
TRACE("Gpx.Create %p,%d,%d,%d:", var, width, height, bpp);
|
||||
}
|
||||
|
||||
static void CreatePixelOnly() {
|
||||
@@ -183,10 +166,9 @@ static void CreatePixelOnly() {
|
||||
int width = getCaliValue();
|
||||
int height = getCaliValue();
|
||||
int bpp = getCaliValue();
|
||||
surface_t *s;
|
||||
|
||||
s = sf_create_pixel(width, height, sf_get(0)->depth);
|
||||
|
||||
|
||||
surface_t *s = sf_create_pixel(width, height);
|
||||
|
||||
if (s == NULL) {
|
||||
*var = 0;
|
||||
} else {
|
||||
@@ -195,7 +177,7 @@ static void CreatePixelOnly() {
|
||||
suf[no] = s;
|
||||
}
|
||||
|
||||
DEBUG_COMMAND("Gpx.CreatePixelOnly %d,%d,%d,%d:\n", *var, width, height, bpp);
|
||||
TRACE("Gpx.CreatePixelOnly %d,%d,%d,%d:", *var, width, height, bpp);
|
||||
}
|
||||
|
||||
static void CreateAMapOnly() {
|
||||
@@ -221,30 +203,22 @@ static void CreateAMapOnly() {
|
||||
suf[no] = s;
|
||||
}
|
||||
|
||||
DEBUG_COMMAND("Gpx.CreateAMapOnly %p,%d,%d:\n", var, width, height);
|
||||
TRACE("Gpx.CreateAMapOnly %p,%d,%d:", var, width, height);
|
||||
}
|
||||
|
||||
static void IsSurface() {
|
||||
/*
|
||||
Gpx.IsSurface(): 指定の番号の surface が surface かどうか
|
||||
(pixel と alpha の両方のデータを持つ)を調べる
|
||||
Gpx.IsSurface(): 指定の番号が surface かどうかを調べる
|
||||
|
||||
p1 : surface 番号
|
||||
var : 結果を返す変数。surface ならば 1, !surface ならば 0
|
||||
*/
|
||||
int p1 = getCaliValue();
|
||||
int *var = getCaliVariable();
|
||||
surface_t *s;
|
||||
|
||||
s = sf_get(p1);
|
||||
|
||||
if (s == NULL) {
|
||||
*var = 0;
|
||||
} else {
|
||||
*var = (s->alpha && s->pixel) ? 1 : 0;
|
||||
}
|
||||
|
||||
DEBUG_COMMAND("Gpx.IsSurface %d,%p:\n", p1, var);
|
||||
|
||||
*var = sf_get(p1) ? 1 : 0;
|
||||
|
||||
TRACE("Gpx.IsSurface %d,%p:", p1, var);
|
||||
}
|
||||
|
||||
static void IsPixel() {
|
||||
@@ -263,10 +237,10 @@ static void IsPixel() {
|
||||
if (s == NULL) {
|
||||
*var = 0;
|
||||
} else {
|
||||
*var = s->pixel ? 1 : 0;
|
||||
*var = s->sdl_surface ? 1 : 0;
|
||||
}
|
||||
|
||||
DEBUG_COMMAND("Gpx.IsPixel %d,%p:\n", p1, var);
|
||||
TRACE("Gpx.IsPixel %d,%p:", p1, var);
|
||||
}
|
||||
|
||||
static void IsAlpha() {
|
||||
@@ -288,7 +262,7 @@ static void IsAlpha() {
|
||||
*var = s->alpha ? 1 : 0;
|
||||
}
|
||||
|
||||
DEBUG_COMMAND("Gpx.IsAlpha %d,%p:\n", p1, var);
|
||||
TRACE("Gpx.IsAlpha %d,%p:", p1, var);
|
||||
}
|
||||
|
||||
static void GetWidth() {
|
||||
@@ -310,7 +284,7 @@ static void GetWidth() {
|
||||
*var = s->width;
|
||||
}
|
||||
|
||||
DEBUG_COMMAND("Gpx.GetWidth %d,%d:\n", p1, *var);
|
||||
TRACE("Gpx.GetWidth %d,%d:", p1, *var);
|
||||
}
|
||||
|
||||
static void GetHeight() {
|
||||
@@ -332,13 +306,13 @@ static void GetHeight() {
|
||||
*var = s->height;
|
||||
}
|
||||
|
||||
DEBUG_COMMAND("Gpx.GetHeight %d,%d:\n", p1, *var);
|
||||
TRACE("Gpx.GetHeight %d,%d:", p1, *var);
|
||||
}
|
||||
|
||||
static void GetCreatedSurface() { /* not used ? */
|
||||
int *var = getCaliVariable();
|
||||
|
||||
DEBUG_COMMAND_YET("Gpx.GetCreatedSurface %p:\n", var);
|
||||
TRACE_UNIMPLEMENTED("Gpx.GetCreatedSurface %p:", var);
|
||||
}
|
||||
|
||||
static void LoadCG() {
|
||||
@@ -353,21 +327,21 @@ static void LoadCG() {
|
||||
|
||||
*var = load_cg_main(p1 -1);
|
||||
|
||||
DEBUG_COMMAND("Gpx.LoadCG %p,%d (%d):\n", var, p1, *var);
|
||||
TRACE("Gpx.LoadCG %p,%d (%d):", var, p1, *var);
|
||||
}
|
||||
|
||||
static void GetCGPosX() { /* not useed ? */
|
||||
int *var = getCaliVariable();
|
||||
int p1 = getCaliValue();
|
||||
|
||||
DEBUG_COMMAND_YET("Gpx.GetCgPosX %p,%d:\n", var, p1);
|
||||
TRACE_UNIMPLEMENTED("Gpx.GetCgPosX %p,%d:", var, p1);
|
||||
}
|
||||
|
||||
static void GetCGPosY() { /* not useed ? */
|
||||
int *var = getCaliVariable();
|
||||
int p1 = getCaliValue();
|
||||
|
||||
DEBUG_COMMAND_YET("Gpx.GetCgPosY %p,%d:\n", var, p1);
|
||||
TRACE_UNIMPLEMENTED("Gpx.GetCgPosY %p,%d:", var, p1);
|
||||
}
|
||||
|
||||
static void Free() {
|
||||
@@ -378,7 +352,7 @@ static void Free() {
|
||||
*/
|
||||
int p1 = getCaliValue();
|
||||
|
||||
DEBUG_COMMAND("Gpx.Free %d:\n", p1);
|
||||
TRACE("Gpx.Free %d:", p1);
|
||||
|
||||
if (p1 != 0) {
|
||||
sf_free_one(p1);
|
||||
@@ -391,7 +365,7 @@ static void FreeAll() {
|
||||
*/
|
||||
sf_free_all();
|
||||
|
||||
DEBUG_COMMAND("Gpx.FreeAll:\n");
|
||||
TRACE("Gpx.FreeAll:");
|
||||
}
|
||||
|
||||
static void Copy() {
|
||||
@@ -417,25 +391,29 @@ static void Copy() {
|
||||
int sh = getCaliValue();
|
||||
surface_t *src, *dst;
|
||||
|
||||
DEBUG_COMMAND("Gpx.Copy %d,%d,%d,%d,%d,%d,%d,%d:\n", ds, dx, dy, ss, sx, sy, sw, sh);
|
||||
TRACE("Gpx.Copy %d,%d,%d,%d,%d,%d,%d,%d:", ds, dx, dy, ss, sx, sy, sw, sh);
|
||||
|
||||
src = sf_get(ss);
|
||||
dst = sf_get(ds);
|
||||
gr_copy(dst, dx, dy, src, sx, sy, sw, sh);
|
||||
}
|
||||
|
||||
static void CopyBright() { /* not used ? */
|
||||
int p1 = getCaliValue();
|
||||
int p2 = getCaliValue();
|
||||
int p3 = getCaliValue();
|
||||
int p4 = getCaliValue();
|
||||
int p5 = getCaliValue();
|
||||
int p6 = getCaliValue();
|
||||
int p7 = getCaliValue();
|
||||
int p8 = getCaliValue();
|
||||
int p9 = getCaliValue();
|
||||
static void CopyBright(void) {
|
||||
int ds = getCaliValue();
|
||||
int dx = getCaliValue();
|
||||
int dy = getCaliValue();
|
||||
int ss = getCaliValue();
|
||||
int sx = getCaliValue();
|
||||
int sy = getCaliValue();
|
||||
int w = getCaliValue();
|
||||
int h = getCaliValue();
|
||||
int lv = getCaliValue();
|
||||
|
||||
DEBUG_COMMAND_YET("Gpx.CopyBright %d,%d,%d,%d,%d,%d,%d,%d,%d:\n", p1, p2, p3, p4, p5, p6, p7, p8, p9);
|
||||
surface_t *dst = sf_get(ds);
|
||||
surface_t *src = sf_get(ss);
|
||||
gr_copy_bright(dst, dx, dy, src, sx, sy, w, h, lv);
|
||||
|
||||
TRACE("Gpx.CopyBright %d,%d,%d,%d,%d,%d,%d,%d,%d:", ds, dx, dy, ss, sx, sy, w, h, lv);
|
||||
}
|
||||
|
||||
static void CopyAMap() {
|
||||
@@ -461,25 +439,29 @@ static void CopyAMap() {
|
||||
int sh = getCaliValue();
|
||||
surface_t *src, *dst;
|
||||
|
||||
DEBUG_COMMAND("Gpx.CopyAMap %d,%d,%d,%d,%d,%d,%d,%d:\n", da, dx, dy, sa, sx, sy, sw, sh);
|
||||
TRACE("Gpx.CopyAMap %d,%d,%d,%d,%d,%d,%d,%d:", da, dx, dy, sa, sx, sy, sw, sh);
|
||||
|
||||
src = sf_get(sa);
|
||||
dst = sf_get(da);
|
||||
gr_copy_alpha_map(dst, dx, dy, src, sx, sy, sw, sh);
|
||||
}
|
||||
|
||||
static void Blend() { /* not used ? */
|
||||
int p1 = getCaliValue();
|
||||
int p2 = getCaliValue();
|
||||
int p3 = getCaliValue();
|
||||
int p4 = getCaliValue();
|
||||
int p5 = getCaliValue();
|
||||
int p6 = getCaliValue();
|
||||
int p7 = getCaliValue();
|
||||
int p8 = getCaliValue();
|
||||
int p9 = getCaliValue();
|
||||
|
||||
DEBUG_COMMAND_YET("Gpx.Blend %d,%d,%d,%d,%d,%d,%d,%d,%d:\n", p1, p2, p3, p4, p5, p6, p7, p8, p9);
|
||||
static void Blend(void) {
|
||||
int ds = getCaliValue();
|
||||
int dx = getCaliValue();
|
||||
int dy = getCaliValue();
|
||||
int ss = getCaliValue();
|
||||
int sx = getCaliValue();
|
||||
int sy = getCaliValue();
|
||||
int w = getCaliValue();
|
||||
int h = getCaliValue();
|
||||
int lv = getCaliValue();
|
||||
|
||||
surface_t *dst = sf_get(ds);
|
||||
surface_t *src = sf_get(ss);
|
||||
gr_blend(dst, dx, dy, src, sx, sy, w, h, lv);
|
||||
|
||||
TRACE("Gpx.Blend %d,%d,%d,%d,%d,%d,%d,%d,%d:", ds, dx, dy, ss, sx, sy, w, h, lv);
|
||||
}
|
||||
|
||||
static void BlendSrcBright() { /* not used ? */
|
||||
@@ -494,7 +476,7 @@ static void BlendSrcBright() { /* not used ? */
|
||||
int p9 = getCaliValue();
|
||||
int p10 = getCaliValue();
|
||||
|
||||
DEBUG_COMMAND_YET("Gpx.BlendSrcBright %d,%d,%d,%d,%d,%d,%d,%d,%d,%d:\n", p1, p2, p3, p4, p5, p6, p7, p8, p9, p10);
|
||||
TRACE_UNIMPLEMENTED("Gpx.BlendSrcBright %d,%d,%d,%d,%d,%d,%d,%d,%d,%d:", p1, p2, p3, p4, p5, p6, p7, p8, p9, p10);
|
||||
}
|
||||
|
||||
static void BlendAddSatur() { /* not used ? */
|
||||
@@ -507,7 +489,7 @@ static void BlendAddSatur() { /* not used ? */
|
||||
int p7 = getCaliValue();
|
||||
int p8 = getCaliValue();
|
||||
|
||||
DEBUG_COMMAND_YET("Gpx.BlendAddStatur %d,%d,%d,%d,%d,%d,%d,%d:\n", p1, p2, p3, p4, p5, p6, p7, p8);
|
||||
TRACE_UNIMPLEMENTED("Gpx.BlendAddStatur %d,%d,%d,%d,%d,%d,%d,%d:", p1, p2, p3, p4, p5, p6, p7, p8);
|
||||
}
|
||||
|
||||
static void BlendAMap() {
|
||||
@@ -533,7 +515,7 @@ static void BlendAMap() {
|
||||
int sh = getCaliValue();
|
||||
surface_t *src, *dst;
|
||||
|
||||
DEBUG_COMMAND("Gpx.BlendAMap %d,%d,%d,%d,%d,%d,%d,%d:\n", ds, dx, dy, ss, sx, sy, sw, sh);
|
||||
TRACE("Gpx.BlendAMap %d,%d,%d,%d,%d,%d,%d,%d:", ds, dx, dy, ss, sx, sy, sw, sh);
|
||||
|
||||
src = sf_get(ss);
|
||||
dst = sf_get(ds);
|
||||
@@ -550,7 +532,7 @@ static void BlendAMapSrcOnly() { /* not used ? */
|
||||
int p7 = getCaliValue();
|
||||
int p8 = getCaliValue();
|
||||
|
||||
DEBUG_COMMAND_YET("Gpx.BlendAMapSrcOnly %d,%d,%d,%d,%d,%d,%d,%d:\n", p1, p2, p3, p4, p5, p6, p7, p8);
|
||||
TRACE_UNIMPLEMENTED("Gpx.BlendAMapSrcOnly %d,%d,%d,%d,%d,%d,%d,%d:", p1, p2, p3, p4, p5, p6, p7, p8);
|
||||
}
|
||||
|
||||
static void BlendAMapColor() { /* not used ? */
|
||||
@@ -566,7 +548,7 @@ static void BlendAMapColor() { /* not used ? */
|
||||
int p10 = getCaliValue();
|
||||
int p11 = getCaliValue();
|
||||
|
||||
DEBUG_COMMAND_YET("Gpx.BlendAMapColor %d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d:\n", p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11);
|
||||
TRACE_UNIMPLEMENTED("Gpx.BlendAMapColor %d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d:", p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11);
|
||||
}
|
||||
|
||||
static void BlendAMapColorAlpha() { /* not used ? */
|
||||
@@ -583,7 +565,7 @@ static void BlendAMapColorAlpha() { /* not used ? */
|
||||
int p11 = getCaliValue();
|
||||
int p12 = getCaliValue();
|
||||
|
||||
DEBUG_COMMAND_YET("Gpx.BlendAMapColorAlpha %d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d:\n", p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12);
|
||||
TRACE_UNIMPLEMENTED("Gpx.BlendAMapColorAlpha %d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d:", p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12);
|
||||
}
|
||||
|
||||
static void BlendAMapAlpha() { /* not used ? */
|
||||
@@ -597,7 +579,7 @@ static void BlendAMapAlpha() { /* not used ? */
|
||||
int p8 = getCaliValue();
|
||||
int p9 = getCaliValue();
|
||||
|
||||
DEBUG_COMMAND_YET("Gpx.BlendAMapAlpha %d,%d,%d,%d,%d,%d,%d,%d,%d:\n", p1, p2, p3, p4, p5, p6, p7, p8, p9);
|
||||
TRACE_UNIMPLEMENTED("Gpx.BlendAMapAlpha %d,%d,%d,%d,%d,%d,%d,%d,%d:", p1, p2, p3, p4, p5, p6, p7, p8, p9);
|
||||
}
|
||||
|
||||
static void BlendAMapBright() { /* not used ? */
|
||||
@@ -611,7 +593,7 @@ static void BlendAMapBright() { /* not used ? */
|
||||
int p8 = getCaliValue();
|
||||
int p9 = getCaliValue();
|
||||
|
||||
DEBUG_COMMAND_YET("Gpx.BlendAMapBright %d,%d,%d,%d,%d,%d,%d,%d,%d:\n", p1, p2, p3, p4, p5, p6, p7, p8, p9);
|
||||
TRACE_UNIMPLEMENTED("Gpx.BlendAMapBright %d,%d,%d,%d,%d,%d,%d,%d,%d:", p1, p2, p3, p4, p5, p6, p7, p8, p9);
|
||||
}
|
||||
|
||||
static void BlendAMapAlphaSrcBright() { /* not used ? */
|
||||
@@ -626,7 +608,7 @@ static void BlendAMapAlphaSrcBright() { /* not used ? */
|
||||
int p9 = getCaliValue();
|
||||
int p10 = getCaliValue();
|
||||
|
||||
DEBUG_COMMAND_YET("Gpx.BlendAMapBright %d,%d,%d,%d,%d,%d,%d,%d,%d,%d:\n", p1, p2, p3, p4, p5, p6, p7, p8, p9, p10);
|
||||
TRACE_UNIMPLEMENTED("Gpx.BlendAMapBright %d,%d,%d,%d,%d,%d,%d,%d,%d,%d:", p1, p2, p3, p4, p5, p6, p7, p8, p9, p10);
|
||||
}
|
||||
|
||||
static void BlendUseAMapColor() { /* not used ? */
|
||||
@@ -643,7 +625,7 @@ static void BlendUseAMapColor() { /* not used ? */
|
||||
int p11 = getCaliValue();
|
||||
int p12 = getCaliValue();
|
||||
|
||||
DEBUG_COMMAND_YET("Gpx.BlendUseAMapColor %d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d:\n", p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12);
|
||||
TRACE_UNIMPLEMENTED("Gpx.BlendUseAMapColor %d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d:", p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12);
|
||||
}
|
||||
|
||||
static void BlendScreen() { /* not used ? */
|
||||
@@ -656,7 +638,7 @@ static void BlendScreen() { /* not used ? */
|
||||
int p7 = getCaliValue();
|
||||
int p8 = getCaliValue();
|
||||
|
||||
DEBUG_COMMAND_YET("Gpx.BlendScreen %d,%d,%d,%d,%d,%d,%d,%d:\n", p1, p2, p3, p4, p5, p6, p7, p8);
|
||||
TRACE_UNIMPLEMENTED("Gpx.BlendScreen %d,%d,%d,%d,%d,%d,%d,%d:", p1, p2, p3, p4, p5, p6, p7, p8);
|
||||
}
|
||||
|
||||
static void BlendMultiply() { /* not used ? */
|
||||
@@ -669,7 +651,7 @@ static void BlendMultiply() { /* not used ? */
|
||||
int p7 = getCaliValue();
|
||||
int p8 = getCaliValue();
|
||||
|
||||
DEBUG_COMMAND_YET("Gpx.BlendMultiply %d,%d,%d,%d,%d,%d,%d,%d:\n", p1, p2, p3, p4, p5, p6, p7, p8);
|
||||
TRACE_UNIMPLEMENTED("Gpx.BlendMultiply %d,%d,%d,%d,%d,%d,%d,%d:", p1, p2, p3, p4, p5, p6, p7, p8);
|
||||
}
|
||||
|
||||
static void BlendScreenAlpha() { /* not used ? */
|
||||
@@ -683,7 +665,7 @@ static void BlendScreenAlpha() { /* not used ? */
|
||||
int p8 = getCaliValue();
|
||||
int p9 = getCaliValue();
|
||||
|
||||
DEBUG_COMMAND_YET("Gpx.BlendScreenAlpha %d,%d,%d,%d,%d,%d,%d,%d,%d:\n", p1, p2, p3, p4, p5, p6, p7, p8, p9);
|
||||
TRACE_UNIMPLEMENTED("Gpx.BlendScreenAlpha %d,%d,%d,%d,%d,%d,%d,%d,%d:", p1, p2, p3, p4, p5, p6, p7, p8, p9);
|
||||
}
|
||||
|
||||
static void Fill() {
|
||||
@@ -709,7 +691,7 @@ static void Fill() {
|
||||
int b = getCaliValue();
|
||||
surface_t *dst;
|
||||
|
||||
DEBUG_COMMAND("Gpx.Fill %d,%d,%d,%d,%d,%d,%d,%d:\n", ds, dx, dy, dw, dh, r, g, b);
|
||||
TRACE("Gpx.Fill %d,%d,%d,%d,%d,%d,%d,%d:", ds, dx, dy, dw, dh, r, g, b);
|
||||
|
||||
dst = sf_get(ds);
|
||||
gr_fill(dst, dx, dy, dw, dh, r, g, b);
|
||||
@@ -727,21 +709,24 @@ static void FillAlphaColor() { /* not used ? */
|
||||
int lv = getCaliValue();
|
||||
surface_t *dst;
|
||||
|
||||
DEBUG_COMMAND_YET("Gpx.FillAlphaColor %d,%d,%d,%d,%d,%d,%d,%d,%d:\n", ds, dx, dy, dw, dh, r, g, b, lv);
|
||||
TRACE("Gpx.FillAlphaColor %d,%d,%d,%d,%d,%d,%d,%d,%d:", ds, dx, dy, dw, dh, r, g, b, lv);
|
||||
|
||||
dst = sf_get(ds);
|
||||
gr_fill_alpha_color(dst, dx, dy, dw, dh, r, g, b, lv);
|
||||
}
|
||||
|
||||
static void FillAMap() { /* not used ? */
|
||||
int p1 = getCaliValue();
|
||||
int p2 = getCaliValue();
|
||||
int p3 = getCaliValue();
|
||||
int p4 = getCaliValue();
|
||||
int p5 = getCaliValue();
|
||||
int p6 = getCaliValue();
|
||||
|
||||
DEBUG_COMMAND_YET("Gpx.FillAMap %d,%d,%d,%d,%d,%d:\n", p1, p2, p3, p4, p5, p6);
|
||||
static void FillAMap(void) {
|
||||
int ds = getCaliValue();
|
||||
int x = getCaliValue();
|
||||
int y = getCaliValue();
|
||||
int w = getCaliValue();
|
||||
int h = getCaliValue();
|
||||
int lv = getCaliValue();
|
||||
|
||||
surface_t *dst = sf_get(ds);
|
||||
gr_fill_alpha_map(dst, x, y, w, h, lv);
|
||||
|
||||
TRACE("Gpx.FillAMap %d,%d,%d,%d,%d,%d:", ds, x, y, w, h, lv);
|
||||
}
|
||||
|
||||
static void FillAMapOverBorder() {
|
||||
@@ -766,7 +751,7 @@ static void FillAMapOverBorder() {
|
||||
int d = getCaliValue();
|
||||
surface_t *dst;
|
||||
|
||||
DEBUG_COMMAND("Gpx.FillAMapOverBorder %d,%d,%d,%d,%d,%d,%d:\n", ds, dx, dy, dw, dh, s, d);
|
||||
TRACE("Gpx.FillAMapOverBorder %d,%d,%d,%d,%d,%d,%d:", ds, dx, dy, dw, dh, s, d);
|
||||
|
||||
dst = sf_get(ds);
|
||||
gr_fill_alpha_overborder(dst, dx, dy, dw, dh, s, d);
|
||||
@@ -781,7 +766,7 @@ static void FillAMapUnderBorder() { /* not used ? */
|
||||
int p6 = getCaliValue();
|
||||
int p7 = getCaliValue();
|
||||
|
||||
DEBUG_COMMAND_YET("Gpx.FillAMapUnderBorder %d,%d,%d,%d,%d,%d,%d:\n", p1, p2, p3, p4, p5, p6, p7);
|
||||
TRACE_UNIMPLEMENTED("Gpx.FillAMapUnderBorder %d,%d,%d,%d,%d,%d,%d:", p1, p2, p3, p4, p5, p6, p7);
|
||||
}
|
||||
|
||||
static void SaturDP_DPxSA() { /* not used ? */
|
||||
@@ -794,7 +779,7 @@ static void SaturDP_DPxSA() { /* not used ? */
|
||||
int p7 = getCaliValue();
|
||||
int p8 = getCaliValue();
|
||||
|
||||
DEBUG_COMMAND_YET("Gpx.SaturDP_DPxSA %d,%d,%d,%d,%d,%d,%d,%d:\n", p1, p2, p3, p4, p5, p6, p7, p8);
|
||||
TRACE_UNIMPLEMENTED("Gpx.SaturDP_DPxSA %d,%d,%d,%d,%d,%d,%d,%d:", p1, p2, p3, p4, p5, p6, p7, p8);
|
||||
}
|
||||
|
||||
static void ScreenDA_DAxSA() { /* not used ? */
|
||||
@@ -807,7 +792,7 @@ static void ScreenDA_DAxSA() { /* not used ? */
|
||||
int p7 = getCaliValue();
|
||||
int p8 = getCaliValue();
|
||||
|
||||
DEBUG_COMMAND_YET("Gpx.ScreenDA_DAxSA %d,%d,%d,%d,%d,%d,%d,%d:\n", p1, p2, p3, p4, p5, p6, p7, p8);
|
||||
TRACE_UNIMPLEMENTED("Gpx.ScreenDA_DAxSA %d,%d,%d,%d,%d,%d,%d,%d:", p1, p2, p3, p4, p5, p6, p7, p8);
|
||||
}
|
||||
|
||||
static void AddDA_DAxSA() { /* not used ? */
|
||||
@@ -820,7 +805,7 @@ static void AddDA_DAxSA() { /* not used ? */
|
||||
int p7 = getCaliValue();
|
||||
int p8 = getCaliValue();
|
||||
|
||||
DEBUG_COMMAND_YET("Gpx.AddDA_DAxSA %d,%d,%d,%d,%d,%d,%d,%d:\n", p1, p2, p3, p4, p5, p6, p7, p8);
|
||||
TRACE_UNIMPLEMENTED("Gpx.AddDA_DAxSA %d,%d,%d,%d,%d,%d,%d,%d:", p1, p2, p3, p4, p5, p6, p7, p8);
|
||||
}
|
||||
|
||||
static void SpriteCopyAMap() {
|
||||
@@ -848,7 +833,7 @@ static void SpriteCopyAMap() {
|
||||
int cl = getCaliValue();
|
||||
surface_t *src, *dst;
|
||||
|
||||
DEBUG_COMMAND("Gpx.SpriteCopyAMap %d,%d,%d,%d,%d,%d,%d,%d,%d:\n", da, dx, dy, sa, sx, sy, sw, sh, cl);
|
||||
TRACE("Gpx.SpriteCopyAMap %d,%d,%d,%d,%d,%d,%d,%d,%d:", da, dx, dy, sa, sx, sy, sw, sh, cl);
|
||||
|
||||
src = sf_get(sa);
|
||||
dst = sf_get(da);
|
||||
@@ -875,7 +860,7 @@ static void BrightDestOnly() {
|
||||
int r = getCaliValue();
|
||||
surface_t *dst;
|
||||
|
||||
DEBUG_COMMAND("Gpx.BrightDestOnly %d,%d,%d,%d,%d,%d:\n", ds, dx, dy, dw, dh, r);
|
||||
TRACE("Gpx.BrightDestOnly %d,%d,%d,%d,%d,%d:", ds, dx, dy, dw, dh, r);
|
||||
|
||||
dst = sf_get(ds);
|
||||
|
||||
@@ -896,7 +881,7 @@ static void CopyTextureWrap() { /* not used ? */
|
||||
int p11 = getCaliValue();
|
||||
int p12 = getCaliValue();
|
||||
|
||||
DEBUG_COMMAND_YET("Gpx.CopyTextureWrap %d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d:\n", p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12);
|
||||
TRACE_UNIMPLEMENTED("Gpx.CopyTextureWrap %d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d:", p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12);
|
||||
}
|
||||
|
||||
static void CopyTextureWrapAlpha() { /* not used ? */
|
||||
@@ -914,7 +899,7 @@ static void CopyTextureWrapAlpha() { /* not used ? */
|
||||
int p12 = getCaliValue();
|
||||
int p13 = getCaliValue();
|
||||
|
||||
DEBUG_COMMAND_YET("Gpx.CopyTextureWrapAlpha %d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d:\n", p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13);
|
||||
TRACE_UNIMPLEMENTED("Gpx.CopyTextureWrapAlpha %d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d:", p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13);
|
||||
}
|
||||
|
||||
static void CopyStretch() {
|
||||
@@ -944,7 +929,7 @@ static void CopyStretch() {
|
||||
int sh = getCaliValue();
|
||||
surface_t *src, *dst;
|
||||
|
||||
DEBUG_COMMAND_YET("Gpx.CopyStretch %d,%d,%d,%d,%d,%d,%d,%d,%d,%d:\n", ds, dx, dy, dw, dh, ss, sx, sy, sw, sh);
|
||||
TRACE("Gpx.CopyStretch %d,%d,%d,%d,%d,%d,%d,%d,%d,%d:", ds, dx, dy, dw, dh, ss, sx, sy, sw, sh);
|
||||
|
||||
src = sf_get(ss);
|
||||
dst = sf_get(ds);
|
||||
@@ -964,7 +949,7 @@ static void CopyStretchBlend() { /* not used ? */
|
||||
int p10 = getCaliValue();
|
||||
int p11 = getCaliValue();
|
||||
|
||||
DEBUG_COMMAND_YET("Gpx.CopyStretchBlend %d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d:\n", p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11);
|
||||
TRACE_UNIMPLEMENTED("Gpx.CopyStretchBlend %d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d:", p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11);
|
||||
}
|
||||
|
||||
static void CopyStretchBlendAMap() {
|
||||
@@ -994,7 +979,7 @@ static void CopyStretchBlendAMap() {
|
||||
int sh = getCaliValue();
|
||||
surface_t *src, *dst;
|
||||
|
||||
DEBUG_COMMAND("Gpx.CopyStretchBlendAMap %d,%d,%d,%d,%d,%d,%d,%d,%d,%d:\n", ds, dx, dy, dw, dh, ss, sx, sy, sw, sh);
|
||||
TRACE("Gpx.CopyStretchBlendAMap %d,%d,%d,%d,%d,%d,%d,%d,%d,%d:", ds, dx, dy, dw, dh, ss, sx, sy, sw, sh);
|
||||
|
||||
src = sf_get(ss);
|
||||
dst = sf_get(ds);
|
||||
@@ -1011,7 +996,7 @@ static void StretchBlendScreen2x2() { /* not used ? */
|
||||
int p7 = getCaliValue();
|
||||
int p8 = getCaliValue();
|
||||
|
||||
DEBUG_COMMAND_YET("Gpx.StretchBlendScreen2x2 %d,%d,%d,%d,%d,%d,%d,%d:\n", p1, p2, p3, p4, p5, p6, p7, p8);
|
||||
TRACE_UNIMPLEMENTED("Gpx.StretchBlendScreen2x2 %d,%d,%d,%d,%d,%d,%d,%d:", p1, p2, p3, p4, p5, p6, p7, p8);
|
||||
}
|
||||
|
||||
|
||||
@@ -1045,7 +1030,7 @@ static void StretchBlendScreen2x2WDS() {
|
||||
int sh = getCaliValue();
|
||||
surface_t *src1, *src2, *dst;
|
||||
|
||||
DEBUG_COMMAND("Gpx.StretchBlendScreen2x2WDS %d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d:\n", ds, dx, dy, ss1, sx1, sy1, ss2, sx2, sy2, sw, sh);
|
||||
TRACE("Gpx.StretchBlendScreen2x2WDS %d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d:", ds, dx, dy, ss1, sx1, sy1, ss2, sx2, sy2, sw, sh);
|
||||
|
||||
src1 = sf_get(ss1);
|
||||
src2 = sf_get(ss2);
|
||||
@@ -1082,7 +1067,7 @@ static void BlendScreenWDS() {
|
||||
int sh = getCaliValue();
|
||||
surface_t *src1, *src2, *dst;
|
||||
|
||||
DEBUG_COMMAND("Gpx.BlendScreenWDS %d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d:\n", ds, dx, dy, ss1, sx1, sy1, ss2, sx2, sy2, sw, sh);
|
||||
TRACE("Gpx.BlendScreenWDS %d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d:", ds, dx, dy, ss1, sx1, sy1, ss2, sx2, sy2, sw, sh);
|
||||
|
||||
src1 = sf_get(ss1);
|
||||
src2 = sf_get(ss2);
|
||||
@@ -1133,34 +1118,19 @@ static void EffectCopy() {
|
||||
int sh = getCaliValue();
|
||||
int time = getCaliValue();
|
||||
int *var = getCaliVariable();
|
||||
surface_t *dib, *dst, *src;
|
||||
|
||||
switch(no) {
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
case 4:
|
||||
case 5:
|
||||
case 7:
|
||||
case 11:
|
||||
case 12:
|
||||
case 13:
|
||||
DEBUG_COMMAND("Gpx.EffectCopy %d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%p:\n", no, dx, dy, ss1, sx1, sy1, ss2, sx2, sy2, sw, sh, time, var);
|
||||
break;
|
||||
default:
|
||||
DEBUG_COMMAND_YET("Gpx.EffectCopy %d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%p:\n", no, dx, dy, ss1, sx1, sy1, ss2, sx2, sy2, sw, sh, time, var);
|
||||
}
|
||||
dib = sf_get(0);
|
||||
dst = sf_get(ss1);
|
||||
src = sf_get(ss2);
|
||||
gpx_effect(no, dib, dx, dy, dst, sx1, sy1, src, sx2, sy2, sw, sh, time, var);
|
||||
|
||||
TRACE("Gpx.EffectCopy %d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%p:", no, dx, dy, ss1, sx1, sy1, ss2, sx2, sy2, sw, sh, time, var);
|
||||
|
||||
surface_t *dst = sf_get(ss1);
|
||||
surface_t *src = sf_get(ss2);
|
||||
gpx_effect(no, dx, dy, dst, sx1, sy1, src, sx2, sy2, sw, sh, time, var);
|
||||
|
||||
}
|
||||
|
||||
static void SetClickCancelFlag() { /* not used ? */
|
||||
int p1 = getCaliValue();
|
||||
|
||||
DEBUG_COMMAND_YET("Gpx.SetClikCancelFlag %d:\n", p1);
|
||||
TRACE_UNIMPLEMENTED("Gpx.SetClikCancelFlag %d:", p1);
|
||||
}
|
||||
|
||||
static const ModuleFunc functions[] = {
|
||||
@@ -1218,4 +1188,4 @@ static const ModuleFunc functions[] = {
|
||||
{"StretchBlendScreen2x2WDS", StretchBlendScreen2x2WDS},
|
||||
};
|
||||
|
||||
const Module module_Gpx = {"Gpx", functions, sizeof(functions) / sizeof(ModuleFunc)};
|
||||
const Module module_Gpx = {"Gpx", functions, sizeof(functions) / sizeof(ModuleFunc), Gpx_reset};
|
||||
|
||||
@@ -33,9 +33,7 @@
|
||||
#include "ags.h"
|
||||
#include "pms.h"
|
||||
#include "qnt.h"
|
||||
#ifdef HAVE_WEBP
|
||||
#include "webp.h"
|
||||
#endif
|
||||
#include "sdl_core.h"
|
||||
#include "ngraph.h"
|
||||
#include "dri.h"
|
||||
#include "ald_manager.h"
|
||||
@@ -46,17 +44,13 @@
|
||||
* @param data: データ列
|
||||
* @return CGの種類(QNT/PMS8/PMS16のいずれか)
|
||||
*/
|
||||
static CG_TYPE check_cgformat(BYTE *data) {
|
||||
static CG_TYPE check_cgformat(uint8_t *data) {
|
||||
if (qnt_checkfmt(data)) {
|
||||
return ALCG_QNT;
|
||||
} else if (pms256_checkfmt(data)) {
|
||||
return ALCG_PMS8;
|
||||
} else if (pms64k_checkfmt(data)) {
|
||||
return ALCG_PMS16;
|
||||
#ifdef HAVE_WEBP
|
||||
} else if (webp_checkfmt(data)) {
|
||||
return ALCG_WEBP;
|
||||
#endif
|
||||
}
|
||||
return ALCG_UNKNOWN;
|
||||
}
|
||||
@@ -68,71 +62,39 @@ static CG_TYPE check_cgformat(BYTE *data) {
|
||||
* @return CG が展開された surface
|
||||
* 未知の形式のときは NULL が返る
|
||||
*/
|
||||
surface_t *sf_getcg(void *b, size_t size) {
|
||||
surface_t *sf = NULL;
|
||||
int type;
|
||||
cgdata *cg = NULL;
|
||||
|
||||
type = check_cgformat(b);
|
||||
switch(type) {
|
||||
static surface_t *sf_getcg(void *b, size_t size) {
|
||||
surface_t *sf;
|
||||
cgdata *cg;
|
||||
|
||||
switch(check_cgformat(b)) {
|
||||
case ALCG_PMS8:
|
||||
// Load as an alpha map
|
||||
cg = pms256_extract(b);
|
||||
cg->alpha = cg->pic;
|
||||
cg->pic = NULL;
|
||||
sf = sf_create_alpha(cg->width, cg->height);
|
||||
sdl_drawImageAlphaMap(cg, sf, 0, 0);
|
||||
break;
|
||||
case ALCG_PMS16:
|
||||
cg = pms64k_extract(b);
|
||||
sf = cg->alpha
|
||||
? sf_create_surface(cg->width, cg->height)
|
||||
: sf_create_pixel(cg->width, cg->height);
|
||||
sdl_drawImage16(cg, sf, 0, 0, 255, false);
|
||||
break;
|
||||
case ALCG_QNT:
|
||||
cg = qnt_extract(b);
|
||||
sf = cg->alpha
|
||||
? sf_create_surface(cg->width, cg->height)
|
||||
: sf_create_pixel(cg->width, cg->height);
|
||||
sdl_drawImage24(cg, sf, 0, 0, 255);
|
||||
break;
|
||||
#ifdef HAVE_WEBP
|
||||
case ALCG_WEBP:
|
||||
cg = webp_extract(b, size);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (cg == NULL) {
|
||||
WARNING("Unknown Cg Type\n");
|
||||
WARNING("Unknown Cg Type");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
switch(type) {
|
||||
case ALCG_PMS8:
|
||||
sf = sf_create_alpha(cg->width, cg->height);
|
||||
gr_draw_amap(sf, cg->x, cg->y, cg->pic, cg->width, cg->height, cg->width);
|
||||
break;
|
||||
|
||||
case ALCG_PMS16:
|
||||
if (cg->alpha) {
|
||||
sf = sf_create_surface(cg->width, cg->height, sf0->depth);
|
||||
gr_drawimage16(sf, cg, cg->x, cg->y);
|
||||
gr_draw_amap(sf, cg->x, cg->y, cg->alpha, cg->width, cg->height, cg->width);
|
||||
} else {
|
||||
sf = sf_create_pixel(cg->width, cg->height, sf0->depth);
|
||||
gr_drawimage16(sf, cg, cg->x, cg->y);
|
||||
}
|
||||
break;
|
||||
|
||||
case ALCG_QNT:
|
||||
case ALCG_WEBP:
|
||||
if (cg->alpha) {
|
||||
sf = sf_create_surface(cg->width, cg->height, sf0->depth);
|
||||
gr_drawimage24(sf, cg, cg->x, cg->y);
|
||||
gr_draw_amap(sf, cg->x, cg->y, cg->alpha, cg->width, cg->height, cg->width);
|
||||
} else {
|
||||
sf = sf_create_pixel(cg->width, cg->height, sf0->depth);
|
||||
gr_drawimage24(sf, cg, cg->x, cg->y);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (cg->pic) free(cg->pic);
|
||||
if (cg->pal) free(cg->pal);
|
||||
if (cg->alpha) free(cg->alpha);
|
||||
free(cg);
|
||||
|
||||
|
||||
cgdata_free(cg);
|
||||
return sf;
|
||||
}
|
||||
|
||||
+23
-375
@@ -5,399 +5,47 @@
|
||||
#include "portab.h"
|
||||
#include "system.h"
|
||||
#include "surface.h"
|
||||
// #include "gleffectcopy.h"
|
||||
#include "sdl_core.h"
|
||||
#include "ags.h"
|
||||
#include "input.h"
|
||||
#include "graph.h"
|
||||
#include "ngraph.h"
|
||||
|
||||
/* saved parameter */
|
||||
struct ecopyparam {
|
||||
surface_t *src;
|
||||
int sx;
|
||||
int sy;
|
||||
surface_t *dst;
|
||||
int dx;
|
||||
int dy;
|
||||
int w;
|
||||
int h;
|
||||
surface_t *write;
|
||||
int wx;
|
||||
int wy;
|
||||
int time;
|
||||
boolean cancel;
|
||||
int spCol;
|
||||
int extp[10];
|
||||
|
||||
// for ec11
|
||||
surface_t *ss[8];
|
||||
surface_t *sd[8];
|
||||
};
|
||||
typedef struct ecopyparam ecopyparam_t;
|
||||
static ecopyparam_t ecp;
|
||||
|
||||
|
||||
|
||||
#define ECA7_D 16
|
||||
#define ECA12_D 256
|
||||
|
||||
static void ec1_cb(int step);
|
||||
static void ec2_cb(int step);
|
||||
static void ec3_cb(int step);
|
||||
static void ec4_cb(int step);
|
||||
static void ec5_cb(int step);
|
||||
static void ec7_cb();
|
||||
static void ec11_cb(int step);
|
||||
static void ec11_prepare(void);
|
||||
static void ec12_cb(int step);
|
||||
static void ec13_cb(int step);
|
||||
|
||||
#if 0
|
||||
void gle_set_check_clik() {
|
||||
}
|
||||
void gle_set_itimer() {
|
||||
}
|
||||
#endif
|
||||
|
||||
void gpx_effect(int no,
|
||||
surface_t *write, int wx, int wy,
|
||||
int wx, int wy,
|
||||
surface_t *dst, int dx, int dy,
|
||||
surface_t *src, int sx, int sy,
|
||||
int width, int height,
|
||||
int time,
|
||||
int *endtype) {
|
||||
|
||||
ags_faderinfo_t i;
|
||||
|
||||
surface_t *write = nact->ags.dib;
|
||||
if (!gr_clip(dst, &dx, &dy, &width, &height, write, &wx, &wy)) return;
|
||||
if (!gr_clip(src, &sx, &sy, &width, &height, write, &wx, &wy)) return;
|
||||
|
||||
ecp.write = write;
|
||||
ecp.wx = wx;
|
||||
ecp.wy = wy;
|
||||
ecp.dst = dst;
|
||||
ecp.dx = dx;
|
||||
ecp.dy = dy;
|
||||
ecp.src = src;
|
||||
ecp.sx = sx;
|
||||
ecp.sy = sy;
|
||||
ecp.w = width;
|
||||
ecp.h = height;
|
||||
ecp.time = time;
|
||||
|
||||
switch(no) {
|
||||
case 1:
|
||||
i.step_max = 64;
|
||||
i.effect_time = time == 0 ? 2700 : time;
|
||||
i.cancel = FALSE;
|
||||
i.callback = ec1_cb;
|
||||
ags_fader(&i);
|
||||
|
||||
*endtype = 0;
|
||||
|
||||
enum sdl_effect_type type = from_sact_effect(no);
|
||||
if (type == EFFECT_INVALID) {
|
||||
WARNING("Unimplemented effect %d", no);
|
||||
type = EFFECT_CROSSFADE;
|
||||
}
|
||||
SDL_Rect rect = { wx, wy, width, height };
|
||||
struct sdl_effect *eff = sdl_effect_init(&rect, dst, dx, dy, src, sx, sy, type);
|
||||
if (!time)
|
||||
time = (no == SACT_EFFECT_CROSSFADE_DOWN || no == SACT_EFFECT_CROSSFADE_UP) ? 1150 : 2700;
|
||||
ags_runEffect(time, false, (ags_EffectStepFunc)sdl_effect_step, eff);
|
||||
sdl_effect_finish(eff);
|
||||
|
||||
switch (no) {
|
||||
case SACT_EFFECT_FADEOUT:
|
||||
gr_fill(write, wx, wy, width, height, 0, 0, 0);
|
||||
break;
|
||||
case 2:
|
||||
i.step_max = 64;
|
||||
i.effect_time = time == 0 ? 2700 : time;
|
||||
i.cancel = FALSE;
|
||||
i.callback = ec2_cb;
|
||||
ags_fader(&i);
|
||||
break;
|
||||
case 3:
|
||||
i.step_max = 64;
|
||||
i.effect_time = time == 0 ? 2700 : time;
|
||||
i.cancel = FALSE;
|
||||
i.callback = ec3_cb;
|
||||
ags_fader(&i);
|
||||
break;
|
||||
case 4:
|
||||
i.step_max = 64;
|
||||
i.effect_time = time == 0 ? 2700 : time;
|
||||
i.cancel = FALSE;
|
||||
i.callback = ec4_cb;
|
||||
ags_fader(&i);
|
||||
break;
|
||||
case 5:
|
||||
i.step_max = 64;
|
||||
i.effect_time = time == 0 ? 2700 : time;
|
||||
i.cancel = FALSE;
|
||||
i.callback = ec5_cb;
|
||||
ags_fader(&i);
|
||||
break;
|
||||
case 7:
|
||||
ec7_cb();
|
||||
break;
|
||||
case 11:
|
||||
ec11_prepare();
|
||||
i.step_max = 6;
|
||||
i.effect_time = time == 0 ? 2700 : time;
|
||||
i.cancel = FALSE;
|
||||
i.callback = ec11_cb;
|
||||
ags_fader(&i);
|
||||
break;
|
||||
case 12:
|
||||
i.step_max = ECA12_D + ecp.h;
|
||||
i.effect_time = time == 0 ? 1150 : time;
|
||||
i.cancel = FALSE;
|
||||
i.callback = ec12_cb;
|
||||
ags_fader(&i);
|
||||
break;
|
||||
case 13:
|
||||
i.step_max = ECA12_D + ecp.h;
|
||||
i.effect_time = time == 0 ? 1150 : time;
|
||||
i.cancel = FALSE;
|
||||
i.callback = ec13_cb;
|
||||
ags_fader(&i);
|
||||
case SACT_EFFECT_WHITEOUT:
|
||||
gr_fill(write, wx, wy, width, height, 255, 255, 255);
|
||||
break;
|
||||
default:
|
||||
gr_copy(write, wx, wy, src, sx, sy, width, height);
|
||||
ags_updateArea(wx, wy, width, height);
|
||||
}
|
||||
|
||||
*endtype = 0;
|
||||
|
||||
}
|
||||
|
||||
void sf_blend_white_level(surface_t *dst, int dx, int dy, surface_t *src, int sx, int sy, int sw, int sh, int lv) {
|
||||
|
||||
int x, y;
|
||||
BYTE *sp, *dp;
|
||||
|
||||
sp = GETOFFSET_PIXEL(src, sx, sy);
|
||||
dp = GETOFFSET_PIXEL(dst, dx, dy);
|
||||
|
||||
switch(dst->depth) {
|
||||
case 16:
|
||||
{
|
||||
WORD *yls, *yld;
|
||||
|
||||
for (y = 0; y < sh; y++) {
|
||||
yls = (WORD *)(sp + y * src->bytes_per_line);
|
||||
yld = (WORD *)(dp + y * dst->bytes_per_line);
|
||||
|
||||
for (x = 0; x < sw; x++) {
|
||||
*yld = WHITELEVEL16(*yls, lv);
|
||||
yls++; yld++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 24:
|
||||
case 32:
|
||||
{
|
||||
DWORD *yls, *yld;
|
||||
|
||||
for (y = 0; y < sh; y++) {
|
||||
yls = (DWORD *)(sp + y * src->bytes_per_line);
|
||||
yld = (DWORD *)(dp + y * dst->bytes_per_line);
|
||||
|
||||
for (x = 0; x < sw; x++) {
|
||||
*yld = WHITELEVEL24(*yls, lv);
|
||||
yls++; yld++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void ec1_cb(int step) {
|
||||
if (step == 64) {
|
||||
gr_copy(ecp.write, ecp.wx, ecp.wy, ecp.src, ecp.sx, ecp.sy, ecp.w, ecp.h);
|
||||
} else {
|
||||
gre_Blend(ecp.write, ecp.wx, ecp.wy, ecp.dst, ecp.dx, ecp.dy, ecp.src, ecp.sx, ecp.sy, ecp.w, ecp.h, step * 4);
|
||||
}
|
||||
ags_updateArea(ecp.wx, ecp.wy, ecp.w, ecp.h);
|
||||
}
|
||||
|
||||
static void ec2_cb(int step) {
|
||||
if (step == 0) {
|
||||
gr_copy_bright(ecp.write, ecp.wx, ecp.wy, ecp.dst, ecp.dx, ecp.dy, ecp.w, ecp.h, 255);
|
||||
} else if (step == 64) {
|
||||
gr_copy_bright(ecp.write, ecp.wx, ecp.wy, ecp.dst, ecp.dx, ecp.dy, ecp.w, ecp.h, 0);
|
||||
} else {
|
||||
gr_copy_bright(ecp.write, ecp.wx, ecp.wy, ecp.dst, ecp.dx, ecp.dy, ecp.w, ecp.h, 255 - step * 4);
|
||||
}
|
||||
ags_updateArea(ecp.wx, ecp.wy, ecp.w, ecp.h);
|
||||
}
|
||||
|
||||
static void ec3_cb(int step) {
|
||||
if (step != 64) {
|
||||
gr_copy_bright(ecp.write, ecp.wx, ecp.wy, ecp.src, ecp.sx, ecp.sy, ecp.w, ecp.h, step * 4);
|
||||
} else {
|
||||
gr_copy_bright(ecp.write, ecp.wx, ecp.wy, ecp.src, ecp.sx, ecp.sy, ecp.w, ecp.h, 255);
|
||||
}
|
||||
ags_updateArea(ecp.wx, ecp.wy, ecp.w, ecp.h);
|
||||
}
|
||||
|
||||
static void ec4_cb(int step) {
|
||||
if (step != 64) {
|
||||
sf_blend_white_level(ecp.write, ecp.wx, ecp.wy, ecp.dst, ecp.dx, ecp.dy, ecp.w, ecp.h, step * 4);
|
||||
} else {
|
||||
sf_blend_white_level(ecp.write, ecp.wx, ecp.wy, ecp.dst, ecp.dx, ecp.dy, ecp.w, ecp.h, 255);
|
||||
}
|
||||
ags_updateArea(ecp.wx, ecp.wy, ecp.w, ecp.h);
|
||||
}
|
||||
|
||||
static void ec5_cb(int step) {
|
||||
if (step == 0) {
|
||||
sf_blend_white_level(ecp.write, ecp.wx, ecp.wy, ecp.src, ecp.sx, ecp.sy, ecp.w, ecp.h, 255);
|
||||
} else if (step == 64) {
|
||||
sf_blend_white_level(ecp.write, ecp.wx, ecp.wy, ecp.src, ecp.sx, ecp.sy, ecp.w, ecp.h, 0);
|
||||
} else {
|
||||
sf_blend_white_level(ecp.write, ecp.wx, ecp.wy, ecp.src, ecp.sx, ecp.sy, ecp.w, ecp.h, 255 - step * 4);
|
||||
}
|
||||
ags_updateArea(ecp.wx, ecp.wy, ecp.w, ecp.h);
|
||||
}
|
||||
|
||||
#define EC_WAIT \
|
||||
if ((key |= sys_getInputInfo()) && ecp.cancel) break; \
|
||||
key = sys_keywait(cnt - sdl_getTicks(), ecp.cancel);
|
||||
|
||||
static void ec7_cb() {
|
||||
int i, j, y, key = 0, cnt;
|
||||
int waitcnt = ecp.time == 0 ? 40 : (ecp.time/60);
|
||||
|
||||
cnt = sdl_getTicks();
|
||||
for (i = 0; i < ECA7_D + ecp.h / ECA7_D -1; i++) {
|
||||
cnt += waitcnt;
|
||||
for (j = 0; j < min(i + 1, ECA7_D); j++) {
|
||||
y = j + ECA7_D * (i-j);
|
||||
if (y < 0 || y >= ecp.h) continue;
|
||||
gr_copy(ecp.write, ecp.wx, ecp.wy + y, ecp.src, ecp.sx, ecp.sy + y, ecp.w, 1);
|
||||
}
|
||||
ags_updateArea(ecp.wx, ecp.wy, ecp.w, ecp.h);
|
||||
EC_WAIT;
|
||||
}
|
||||
|
||||
ags_updateArea(ecp.wx, ecp.wy, ecp.w, ecp.h);
|
||||
}
|
||||
|
||||
static void ec11_prepare() {
|
||||
int i;
|
||||
|
||||
ecp.ss[0] = sf_create_surface(ecp.w, ecp.h, ecp.write->depth);
|
||||
ecp.sd[0] = sf_create_surface(ecp.w, ecp.h, ecp.write->depth);
|
||||
gr_buller(ecp.ss[0], 0, 0, ecp.src, ecp.sx, ecp.sy, ecp.w, ecp.h, 1 << 2);
|
||||
gr_buller(ecp.sd[0], 0, 0, ecp.dst, ecp.dx, ecp.dy, ecp.w, ecp.h, 1 << 2);
|
||||
|
||||
for (i = 1; i < 6; i++) {
|
||||
ecp.ss[i] = sf_create_surface(ecp.w, ecp.h, ecp.write->depth);
|
||||
ecp.sd[i] = sf_create_surface(ecp.w, ecp.h, ecp.write->depth);
|
||||
gr_buller(ecp.ss[i], 0, 0, ecp.ss[i-1], 0, 0, ecp.w, ecp.h, 1 << (i+2));
|
||||
gr_buller(ecp.sd[i], 0, 0, ecp.sd[i-1], 0, 0, ecp.w, ecp.h, 1 << (i+2));
|
||||
}
|
||||
}
|
||||
|
||||
static void ec11_cb(int step) {
|
||||
int i;
|
||||
|
||||
if (step == 6) {
|
||||
for (i = 0; i < 6; i++) {
|
||||
sf_free(ecp.ss[i]);
|
||||
sf_free(ecp.sd[i]);
|
||||
}
|
||||
gr_copy(ecp.write, ecp.wx, ecp.wy, ecp.src, ecp.sx, ecp.sy, ecp.w, ecp.h);
|
||||
ags_updateArea(ecp.wx, ecp.wy, ecp.w, ecp.h);
|
||||
return;
|
||||
}
|
||||
|
||||
gre_Blend(ecp.write, ecp.wx, ecp.wy, ecp.sd[step], 0, 0, ecp.ss[5-step], 0, 0, ecp.w, ecp.h, ((step+1)*256)/7);
|
||||
|
||||
ags_updateArea(ecp.wx, ecp.wy, ecp.w, ecp.h);
|
||||
}
|
||||
|
||||
#if 0
|
||||
static void ec11_cb(int step) {
|
||||
static surface_t *ss;
|
||||
static surface_t *sd;
|
||||
|
||||
if (step == 0) {
|
||||
ss = sf_create_surface(ecp.w, ecp.h, ecp.write->depth);
|
||||
sd = sf_create_surface(ecp.w, ecp.h, ecp.write->depth);
|
||||
gr_copy(ss, 0, 0, ecp.src, ecp.sx, ecp.sy, ecp.w, ecp.h);
|
||||
gr_copy(sd, 0, 0, ecp.dst, ecp.dx, ecp.dy, ecp.w, ecp.h);
|
||||
return;
|
||||
}
|
||||
if (step == 6) {
|
||||
sf_free(ss);
|
||||
sf_free(sd);
|
||||
gr_copy(ecp.write, ecp.wx, ecp.wy, ecp.src, ecp.sx, ecp.sy, ecp.w, ecp.h);
|
||||
ags_updateArea(ecp.wx, ecp.wy, ecp.w, ecp.h);
|
||||
return;
|
||||
}
|
||||
|
||||
gr_buller(ss, 0, 0, ecp.src, ecp.sx, ecp.sy, ecp.w, ecp.h, 1 << (7-step));
|
||||
gr_buller(sd, 0, 0, ecp.dst, ecp.dx, ecp.dy, ecp.w, ecp.h, 1 << (step+1));
|
||||
gre_Blend(ecp.write, ecp.wx, ecp.wy, sd, 0, 0, ss, 0, 0, ecp.w, ecp.h, (step*256)/6);
|
||||
ags_updateArea(ecp.wx, ecp.wy, ecp.w, ecp.h);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void ec12_cb(int step) {
|
||||
int j, l;
|
||||
int st_i, ed_i;
|
||||
static int last_i = 0;
|
||||
|
||||
if (step == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (step == ECA12_D + ecp.h) {
|
||||
gr_copy(ecp.write, ecp.wx, ecp.wy, ecp.src, ecp.sx, ecp.sy, ecp.w, ecp.h);
|
||||
ags_updateArea(ecp.wx, ecp.wy, ecp.w, ecp.h);
|
||||
return;
|
||||
}
|
||||
|
||||
st_i = max(0, step - ECA12_D + 1);
|
||||
ed_i = min(ecp.h - 1, step);
|
||||
l = ed_i - st_i + 1;
|
||||
|
||||
for (j = st_i; j < ed_i; j++) {
|
||||
gre_Blend(ecp.write, ecp.wx, ecp.wy + j, ecp.dst, ecp.dx, ecp.dy + j, ecp.src, ecp.sx, ecp.sy + j, ecp.w, 1, step - j);
|
||||
}
|
||||
|
||||
if ((st_i - last_i) > 1) {
|
||||
gr_copy(ecp.write, ecp.wx, ecp.wy + last_i, ecp.src, ecp.sx, ecp.sy+last_i, ecp.w, st_i - last_i);
|
||||
ags_updateArea(ecp.wx, ecp.wy + last_i, ecp.w, st_i - last_i);
|
||||
}
|
||||
|
||||
ags_updateArea(ecp.wx, ecp.wy + st_i, ecp.w, l);
|
||||
|
||||
last_i = st_i;
|
||||
}
|
||||
|
||||
static void ec13_cb(int step) {
|
||||
int j, l;
|
||||
int st_i,ed_i;
|
||||
static int last_i = 0;
|
||||
int syy1 = ecp.dy + ecp.h -1;
|
||||
int syy2 = ecp.sy + ecp.h -1;
|
||||
int dyy = ecp.wy + ecp.h -1;
|
||||
|
||||
if (step == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (step == ECA12_D + ecp.h) {
|
||||
gr_copy(ecp.write, ecp.wx, ecp.wy, ecp.src, ecp.sx, ecp.sy, ecp.w, ecp.h);
|
||||
ags_updateArea(ecp.wx, ecp.wy, ecp.w, ecp.h);
|
||||
return;
|
||||
}
|
||||
|
||||
st_i = max(0, step - ECA12_D + 1);
|
||||
ed_i = min(ecp.h -1, step);
|
||||
l = ed_i - st_i+1;
|
||||
|
||||
for (j = st_i; j <= ed_i; j++) {
|
||||
gre_Blend(ecp.write, ecp.wx, dyy - j, ecp.dst, ecp.dx, syy1 - j, ecp.src, ecp.sx, syy2 - j, ecp.w, 1, step - j);
|
||||
}
|
||||
|
||||
if ((st_i - last_i) > 1) {
|
||||
gr_copy(ecp.write, ecp.wx, dyy - st_i + 1, ecp.src, ecp.sx, syy2 - st_i + 1, ecp.w, st_i - last_i);
|
||||
ags_updateArea(ecp.wx, dyy - st_i + 1, ecp.w, st_i - last_i);
|
||||
}
|
||||
|
||||
ags_updateArea(ecp.wx, dyy-ed_i, ecp.w, l);
|
||||
|
||||
last_i = st_i;
|
||||
ags_updateArea(wx, wy, width, height);
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#include "surface.h"
|
||||
|
||||
extern void gpx_effect(int no,
|
||||
surface_t *write, int wx, int wy,
|
||||
int wx, int wy,
|
||||
surface_t *dst, int dx, int dy,
|
||||
surface_t *src, int sx, int sy,
|
||||
int width, int height,
|
||||
|
||||
@@ -3,25 +3,15 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <SDL.h>
|
||||
|
||||
#include "portab.h"
|
||||
#include "system.h"
|
||||
#include "surface.h"
|
||||
#include "graph.h"
|
||||
#include "ngraph.h"
|
||||
#include "nact.h"
|
||||
|
||||
/*
|
||||
gr_xxxx はクリッピングあり
|
||||
gre_xxxx はクリッピングなし
|
||||
*/
|
||||
|
||||
#undef WARNING
|
||||
#define WARNING(...)
|
||||
|
||||
#undef NOTICE
|
||||
#define NOTICE(...)
|
||||
|
||||
#include "ags.h"
|
||||
#include "sdl_core.h"
|
||||
|
||||
/**
|
||||
* surface から surface にコピーなどをする際に、転送元と転送先のsurface
|
||||
@@ -36,80 +26,16 @@
|
||||
* @param ds: 転送先surface
|
||||
* @param dx: 転送先X座標
|
||||
* @param dy: 転送先Y座標
|
||||
* @return TRUE -> 描画領域がある
|
||||
* FALSE-> 転送領域の高さや幅が0以下になったり、転送元、転送先の座標が
|
||||
* @return true -> 描画領域がある
|
||||
* false-> 転送領域の高さや幅が0以下になったり、転送元、転送先の座標が
|
||||
* surfaceの範囲外になり、描画領域がなくなった。
|
||||
* それぞれの引数は適宜変更されている
|
||||
*/
|
||||
boolean gr_clip(surface_t *ss, int *sx, int *sy, int *sw, int *sh, surface_t *ds, int *dx, int *dy) {
|
||||
int w, h;
|
||||
|
||||
if (ss == NULL) {
|
||||
WARNING("ss surface is null\n");
|
||||
return FALSE;
|
||||
}
|
||||
if (ss == NULL) {
|
||||
WARNING("ss surface is null\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (*sx > ss->width) {
|
||||
WARNING("sx is too large (sx=%d,width=%d)\n", *sx, ss->width);
|
||||
return FALSE;
|
||||
}
|
||||
if (*sy > ss->height) {
|
||||
WARNING("sy is too large (sy=%d,height=%d)\n", *sy, ss->height);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (*sx < 0) {
|
||||
WARNING("sx is too small (sx=%d)\n", *sx);
|
||||
return FALSE;
|
||||
}
|
||||
if (*sy < 0) {
|
||||
WARNING("sy is too small (sy=%d)\n", *sy);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (*dx > ds->width) {
|
||||
WARNING("dx is too large (dx=%d,width=%d)\n", *dx, ds->width);
|
||||
return FALSE;
|
||||
}
|
||||
if (*dy > ds->height) {
|
||||
WARNING("dy is too large (dy=%d,height=%d)\n", *dy, ds->height);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
w = *sw;
|
||||
h = *sh;
|
||||
|
||||
if (*dx < 0) {
|
||||
*sx -= *dx; *sw += *dx; *dx = 0;
|
||||
}
|
||||
if (*dy < 0) {
|
||||
*sy -= *dy; *sh += *dy; *dy = 0;
|
||||
}
|
||||
|
||||
*sw = min(ss->width - *sx, min(ds->width - *dx, *sw));
|
||||
*sh = min(ss->height - *sy, min(ds->height - *dy, *sh));
|
||||
|
||||
if (*sw <= 0) {
|
||||
WARNING("sw become <=0\n");
|
||||
return FALSE;
|
||||
}
|
||||
if (*sh <= 0) {
|
||||
WARNING("sh become <=0\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (*sw != w) {
|
||||
NOTICE("width change %d -> %d\n", w, *sw);
|
||||
}
|
||||
if (*sh != h) {
|
||||
NOTICE("height change %d -> %d\n", h, *sh);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
bool gr_clip(surface_t *ss, int *sx, int *sy, int *sw, int *sh, surface_t *ds, int *dx, int *dy) {
|
||||
if (!ss || !ds) return false;
|
||||
MyRectangle src_window = { 0, 0, ss->width, ss->height };
|
||||
MyRectangle dst_window = { 0, 0, ds->width, ds->height };
|
||||
return ags_clipCopyRect(&src_window, &dst_window, sx, sy, dx, dy, sw, sh);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -120,67 +46,75 @@ boolean gr_clip(surface_t *ss, int *sx, int *sy, int *sw, int *sh, surface_t *ds
|
||||
* @param sy: 描画開始Y座標
|
||||
* @param sw: 描画幅
|
||||
* @param sh: 描画高さ
|
||||
* @return TRUE -> 描画領域がある
|
||||
* FALSE-> 描画領域の高さや幅が0以下になったり、描画開始座標が
|
||||
* @return true -> 描画領域がある
|
||||
* false-> 描画領域の高さや幅が0以下になったり、描画開始座標が
|
||||
* surfaceの範囲外になり、描画領域がなくなった。
|
||||
* それぞれの引数は適宜変更されている
|
||||
*/
|
||||
boolean gr_clip_xywh(surface_t *ss, int *sx, int *sy, int *sw, int *sh) {
|
||||
int w, h;
|
||||
|
||||
if (ss == NULL) {
|
||||
WARNING("ss surface is null\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (*sx > ss->width) {
|
||||
WARNING("sx is too large (sx=%d,width=%d)\n", *sx, ss->width);
|
||||
return FALSE;
|
||||
}
|
||||
if (*sy > ss->height) {
|
||||
WARNING("sy is too large (sy=%d,height=%d)\n", *sy, ss->height);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
w = *sw;
|
||||
h = *sh;
|
||||
|
||||
if (*sx < 0) {
|
||||
*sw += *sx; *sx = 0;
|
||||
}
|
||||
if (*sy < 0) {
|
||||
*sh += *sy; *sy = 0;
|
||||
}
|
||||
|
||||
*sw = min(ss->width - *sx, *sw);
|
||||
*sh = min(ss->height - *sy, *sh);
|
||||
|
||||
if (*sw <= 0) {
|
||||
WARNING("sw become <=0\n");
|
||||
return FALSE;
|
||||
}
|
||||
if (*sh <= 0) {
|
||||
WARNING("sh become <=0\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (*sw != w) {
|
||||
NOTICE("width change %d -> %d\n", w, *sw);
|
||||
}
|
||||
if (*sh != h) {
|
||||
NOTICE("height change %d -> %d\n", h, *sh);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
bool gr_clip_xywh(surface_t *ss, int *sx, int *sy, int *sw, int *sh) {
|
||||
if (!ss) return false;
|
||||
SDL_Rect rect = {*sx, *sy, *sw, *sh};
|
||||
if (!SDL_IntersectRect(&rect, &(SDL_Rect){ 0, 0, ss->width, ss->height }, &rect))
|
||||
return false;
|
||||
*sx = rect.x;
|
||||
*sy = rect.y;
|
||||
*sw = rect.w;
|
||||
*sh = rect.h;
|
||||
return true;
|
||||
}
|
||||
|
||||
void gr_init() {
|
||||
}
|
||||
|
||||
void gr_copy(surface_t *dst, int dx, int dy, surface_t *src, int sx, int sy, int sw, int sh) {
|
||||
if (!dst->sdl_surface || !src->sdl_surface) return;
|
||||
if (!gr_clip(src, &sx, &sy, &sw, &sh, dst, &dx, &dy)) return;
|
||||
|
||||
SDL_Rect src_rect = {sx, sy, sw, sh};
|
||||
SDL_Rect dst_rect = {dx, dy, sw, sh};
|
||||
if (dst == src) {
|
||||
SDL_Rect r;
|
||||
if (SDL_IntersectRect(&src_rect, &dst_rect, &r)) {
|
||||
SDL_Surface *view = sdl_createSurfaceView(src->sdl_surface, sx, sy, sw, sh);
|
||||
SDL_Surface *tmp = SDL_ConvertSurface(view, dst->sdl_surface->format, 0);
|
||||
src_rect.x = 0;
|
||||
src_rect.y = 0;
|
||||
SDL_LowerBlit(tmp, &src_rect, dst->sdl_surface, &dst_rect);
|
||||
SDL_FreeSurface(tmp);
|
||||
SDL_FreeSurface(view);
|
||||
return;
|
||||
}
|
||||
}
|
||||
SDL_LowerBlit(src->sdl_surface, &src_rect, dst->sdl_surface, &dst_rect);
|
||||
}
|
||||
|
||||
// Copy the specified surface area with brightness lv/255 times
|
||||
void gr_copy_bright(surface_t *dst, int dx, int dy, surface_t *src, int sx, int sy, int width, int height, int lv) {
|
||||
SDL_Rect src_rect = {sx, sy, width, height};
|
||||
SDL_Rect dst_rect = {dx, dy, width, height};
|
||||
SDL_SetSurfaceColorMod(src->sdl_surface, lv, lv, lv);
|
||||
SDL_BlitSurface(src->sdl_surface, &src_rect, dst->sdl_surface, &dst_rect);
|
||||
SDL_SetSurfaceColorMod(src->sdl_surface, 255, 255, 255);
|
||||
}
|
||||
|
||||
void gr_fill(surface_t *dst, int dx, int dy, int dw, int dh, int r, int g, int b) {
|
||||
SDL_Rect rect = {dx, dy, dw, dh};
|
||||
uint32_t color = SDL_MapRGB(dst->sdl_surface->format, r, g, b);
|
||||
SDL_FillRect(dst->sdl_surface, &rect, color);
|
||||
}
|
||||
|
||||
void gr_copy_stretch(surface_t *dst, int dx, int dy, int dw, int dh, surface_t *src, int sx, int sy, int sw, int sh) {
|
||||
SDL_Rect srcrect = {sx, sy, sw, sh};
|
||||
SDL_Rect dstrect = {dx, dy, dw, dh};
|
||||
SDL_BlitScaled(src->sdl_surface, &srcrect, dst->sdl_surface, &dstrect);
|
||||
}
|
||||
|
||||
void gr_blend(surface_t *dst, int dx, int dy, surface_t *src, int sx, int sy, int width, int height, int lv) {
|
||||
|
||||
|
||||
SDL_SetSurfaceBlendMode(src->sdl_surface, SDL_BLENDMODE_BLEND);
|
||||
SDL_SetSurfaceAlphaMod(src->sdl_surface, lv);
|
||||
SDL_BlitSurface(src->sdl_surface, &(SDL_Rect){sx, sy, width, height}, dst->sdl_surface, &(SDL_Rect){dx, dy, width, height});
|
||||
SDL_SetSurfaceAlphaMod(src->sdl_surface, 255);
|
||||
SDL_SetSurfaceBlendMode(src->sdl_surface, SDL_BLENDMODE_NONE);
|
||||
}
|
||||
|
||||
void gr_blend_src_bright(surface_t *dst, int dx, int dy, surface_t *src, int sx, int sy, int width, int height, int alpha, int rate) {
|
||||
@@ -246,7 +180,7 @@ void gr_copy_stretch_blend_alpha_map(surface_t *dst, int dx, int dy, int dw, int
|
||||
float a1, a2, xd, yd;
|
||||
int *row, *col;
|
||||
int x, y;
|
||||
BYTE *sp, *dp, *sa;
|
||||
uint8_t *sp, *dp, *sa;
|
||||
|
||||
if (!gr_clip_xywh(dst, &dx, &dy, &dw, &dh)) return;
|
||||
if (!gr_clip_xywh(src, &sx, &sy, &sw, &sh)) return;
|
||||
@@ -271,56 +205,34 @@ void gr_copy_stretch_blend_alpha_map(surface_t *dst, int dx, int dy, int dw, int
|
||||
row[x] = xd; xd += a1;
|
||||
}
|
||||
|
||||
switch(dst->depth) {
|
||||
case 16:
|
||||
{
|
||||
WORD *yls, *yld;
|
||||
BYTE *yla;
|
||||
|
||||
for (y = 0; y < dh; y++) {
|
||||
yls = (WORD *)(sp + *(y + col) * src->bytes_per_line);
|
||||
yld = (WORD *)(dp + y * dst->bytes_per_line);
|
||||
yla = (BYTE *)(sa + *(y + col) * src->width);
|
||||
for (x = 0; x < dw; x++) {
|
||||
*(yld + x) = ALPHABLEND16(*(yls+ *(row + x)), *(yld+x), *(yla+*(row+x)));
|
||||
}
|
||||
while(*(col + y) == *(col + y + 1)) {
|
||||
yld += dst->width;
|
||||
for (x = 0; x < dw; x++) {
|
||||
*(yld + x) = ALPHABLEND16(*(yls+ *(row+x)), *(yld+x), *(yla+*(row+x)));
|
||||
}
|
||||
y++;
|
||||
}
|
||||
for (y = 0; y < dh; y++) {
|
||||
uint32_t *yls = (uint32_t *)(sp + *(y + col) * src->sdl_surface->pitch);
|
||||
uint32_t *yld = (uint32_t *)(dp + y * dst->sdl_surface->pitch);
|
||||
uint8_t *yla = (uint8_t *)(sa + *(y + col) * src->width);
|
||||
for (x = 0; x < dw; x++) {
|
||||
*(yld + x) = ALPHABLEND24(*(yls+ *(row + x)), *(yld+x), *(yla+*(row+x)));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 24:
|
||||
case 32:
|
||||
{
|
||||
DWORD *yls, *yld;
|
||||
BYTE *yla;
|
||||
|
||||
for (y = 0; y < dh; y++) {
|
||||
yls = (DWORD *)(sp + *(y + col) * src->bytes_per_line);
|
||||
yld = (DWORD *)(dp + y * dst->bytes_per_line);
|
||||
yla = (BYTE *)(sa + *(y + col) * src->width);
|
||||
while (y < dh - 1 && *(col + y) == *(col + y + 1)) {
|
||||
yld += dst->width;
|
||||
for (x = 0; x < dw; x++) {
|
||||
*(yld + x) = ALPHABLEND24(*(yls+ *(row + x)), *(yld+x), *(yla+*(row+x)));
|
||||
}
|
||||
while(*(col + y) == *(col + y + 1)) {
|
||||
yld += dst->width;
|
||||
for (x = 0; x < dw; x++) {
|
||||
*(yld + x) = ALPHABLEND24(*(yls+ *(row+x)), *(yld+x), *(yla+*(row+x)));
|
||||
}
|
||||
y++;
|
||||
*(yld + x) = ALPHABLEND24(*(yls+ *(row+x)), *(yld+x), *(yla+*(row+x)));
|
||||
}
|
||||
y++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
free(row);
|
||||
free(col);
|
||||
}
|
||||
|
||||
// Fill the rectangle with the specified color (rgb) and blend rate (lv)
|
||||
void gr_fill_alpha_color(surface_t *dst, int dx, int dy, int dw, int dh, int r, int g, int b, int lv) {
|
||||
SDL_Surface *src = SDL_CreateRGBSurfaceWithFormat(0, dw, dh, 32, SDL_PIXELFORMAT_ARGB8888);
|
||||
SDL_FillRect(src, NULL, SDL_MapRGBA(src->format, r, g, b, lv));
|
||||
SDL_SetSurfaceBlendMode(src, SDL_BLENDMODE_BLEND);
|
||||
SDL_Rect dstrect = {dx, dy, dw, dh};
|
||||
SDL_BlitSurface(src, NULL, dst->sdl_surface, &dstrect);
|
||||
SDL_FreeSurface(src);
|
||||
}
|
||||
|
||||
#include "graph2.c"
|
||||
@@ -0,0 +1,23 @@
|
||||
#ifndef __GRAPH_H__
|
||||
#define __GRAPH_H__
|
||||
|
||||
#include "config.h"
|
||||
#include "surface.h"
|
||||
|
||||
void gr_init();
|
||||
|
||||
void gr_copy(surface_t *dst, int dx, int dy, surface_t *src, int sx, int sy, int sw, int sh);
|
||||
void gr_copy_bright(surface_t *dst, int dx, int dy, surface_t *src, int sx, int sy, int width, int height, int lv);
|
||||
void gr_fill(surface_t *dst, int dx, int dy, int dw, int dh, int r, int g, int b);
|
||||
void gr_copy_stretch(surface_t *dst, int dx, int dy, int dw, int dh, surface_t *src, int sx, int sy, int sw, int sh);
|
||||
void gr_blend(surface_t *dst, int dx, int dy, surface_t *src, int sx, int sy, int width, int height, int lv);
|
||||
void gr_copy_stretch_blend_alpha_map(surface_t *dst, int dx, int dy, int dw, int dh, surface_t *src, int sx, int sy, int sw, int sh);
|
||||
void gr_fill_alpha_color(surface_t *dst, int dx, int dy, int dw, int dh, int r, int g, int b, int lv);
|
||||
void gr_fill_alpha_overborder(surface_t *dst, int dx, int dy, int dw, int dh, int s, int d);
|
||||
void gr_fill_alpha_underborder(surface_t *dst, int dx, int dy, int dw, int dh, int s, int d);
|
||||
void gr_copy_alpha_map_sprite(surface_t *dst, int dx, int dy, surface_t *src, int sx, int sy, int sw, int sh, int cl);
|
||||
void gr_blend_alpha_wds_stretch2x2(surface_t *src1, int sx1, int sy1, surface_t *src2, int sx2, int sy2, int sw, int sh, surface_t *dst, int dx, int dy);
|
||||
void gr_blend_alpha_wds(surface_t *src1, int sx1, int sy1, surface_t *src2, int sx2, int sy2, int sw, int sh, surface_t *dst, int dx, int dy);
|
||||
|
||||
#endif /* __GRAPH_H__ */
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
void gr_fill_alpha_overborder(surface_t *dst, int dx, int dy, int dw, int dh, int s, int d) {
|
||||
BYTE *dp;
|
||||
uint8_t *dp;
|
||||
int x, y;
|
||||
|
||||
if (dst == NULL) return;
|
||||
@@ -10,14 +10,14 @@ void gr_fill_alpha_overborder(surface_t *dst, int dx, int dy, int dw, int dh, in
|
||||
|
||||
for (y = 0; y < dh; y++) {
|
||||
for (x = 0; x < dw; x++) {
|
||||
if (*(dp + x) >= (BYTE)s) *(dp + x) = (BYTE)d;
|
||||
if (*(dp + x) >= (uint8_t)s) *(dp + x) = (uint8_t)d;
|
||||
}
|
||||
dp += dst->width;
|
||||
}
|
||||
}
|
||||
|
||||
void gr_fill_alpha_underborder(surface_t *dst, int dx, int dy, int dw, int dh, int s, int d) {
|
||||
BYTE *dp;
|
||||
uint8_t *dp;
|
||||
int x, y;
|
||||
|
||||
if (dst == NULL) return;
|
||||
@@ -28,14 +28,14 @@ void gr_fill_alpha_underborder(surface_t *dst, int dx, int dy, int dw, int dh, i
|
||||
|
||||
for (y = 0; y < dh; y++) {
|
||||
for (x = 0; x < dw; x++) {
|
||||
if (*(dp + x) <= (BYTE)s) *(dp + x) = (BYTE)d;
|
||||
if (*(dp + x) <= (uint8_t)s) *(dp + x) = (uint8_t)d;
|
||||
}
|
||||
dp += dst->width;
|
||||
}
|
||||
}
|
||||
|
||||
void gr_copy_alpha_map_sprite(surface_t *dst, int dx, int dy, surface_t *src, int sx, int sy, int sw, int sh, int cl) {
|
||||
BYTE *sp, *dp;
|
||||
uint8_t *sp, *dp;
|
||||
int x, y;
|
||||
|
||||
if (!gr_clip(src, &sx, &sy, &sw, &sh, dst, &dx, &dy)) return;
|
||||
@@ -75,7 +75,7 @@ void gr_copy_alpha_map_sprite(surface_t *dst, int dx, int dy, surface_t *src, in
|
||||
}
|
||||
|
||||
void gr_blend_alpha_wds_stretch2x2(surface_t *src1, int sx1, int sy1, surface_t *src2, int sx2, int sy2, int sw, int sh, surface_t *dst, int dx, int dy) {
|
||||
surface_t *t = sf_create_surface(sw * 2, sh * 2, dst->depth);
|
||||
surface_t *t = sf_create_surface(sw * 2, sh * 2);
|
||||
|
||||
gr_copy_stretch(t, 0, 0, sw * 2, sh * 2, src2, sx2, sy2, sw, sh);
|
||||
gr_blend_alpha_wds(t, 0, 0, src1, sx1, sy1, sw * 2, sh * 2, dst, dx, dy);
|
||||
@@ -86,61 +86,23 @@ void gr_blend_alpha_wds_stretch2x2(surface_t *src1, int sx1, int sy1, surface_t
|
||||
|
||||
void gr_blend_alpha_wds(surface_t *src1, int sx1, int sy1, surface_t *src2, int sx2, int sy2, int sw, int sh, surface_t *dst, int dx, int dy) {
|
||||
int x, y;
|
||||
BYTE *sp1, *sp2, *dp, *sa;
|
||||
uint8_t *sp1, *sp2, *dp, *sa;
|
||||
|
||||
sp1 = GETOFFSET_PIXEL(src1, sx1, sy1);
|
||||
sp2 = GETOFFSET_PIXEL(src2, sx2, sy2);
|
||||
sa = GETOFFSET_ALPHA(src1, sx1, sy1);
|
||||
dp = GETOFFSET_PIXEL(dst, dx, dy);
|
||||
|
||||
switch(dst->depth) {
|
||||
case 16:
|
||||
// if (nact->mmx_is_ok) {
|
||||
if (0) {
|
||||
#ifdef ENABLE_MMX
|
||||
ablend16_wds_pppp(dp, sp1, sp2, sa, sw, sh,
|
||||
dst->bytes_per_line,
|
||||
src1->bytes_per_line,
|
||||
src2->bytes_per_line,
|
||||
src1->width);
|
||||
#endif
|
||||
} else {
|
||||
WORD *yls1, *yls2, *yld;
|
||||
BYTE *yla;
|
||||
|
||||
for (y = 0; y < sh; y++) {
|
||||
yls1 = (WORD *)(sp1 + y * src1->bytes_per_line);
|
||||
yls2 = (WORD *)(sp2 + y * src2->bytes_per_line);
|
||||
yld = (WORD *)(dp + y * dst->bytes_per_line);
|
||||
yla = (BYTE *)(sa + y * src1->width);
|
||||
|
||||
for (x = 0; x < sw; x++) {
|
||||
*yld = SUTURADD16(*yls1, ALPHABLEND16(*yls1, *yls2, *yla));
|
||||
//*yld = SUTURADD16(*yls1, ALPHALEVEL16(*yls2, *yla));
|
||||
yls1++; yls2++; yld++; yla++;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 24:
|
||||
case 32:
|
||||
{
|
||||
DWORD *yls1, *yls2, *yld;
|
||||
BYTE *yla;
|
||||
for (y = 0; y < sh; y++) {
|
||||
uint32_t *yls1 = (uint32_t *)(sp1 + y * src1->sdl_surface->pitch);
|
||||
uint32_t *yls2 = (uint32_t *)(sp2 + y * src2->sdl_surface->pitch);
|
||||
uint32_t *yld = (uint32_t *)(dp + y * dst->sdl_surface->pitch);
|
||||
uint8_t *yla = (uint8_t *)(sa + y * src1->width);
|
||||
|
||||
for (y = 0; y < sh; y++) {
|
||||
yls1 = (DWORD *)(sp1 + y * src1->bytes_per_line);
|
||||
yls2 = (DWORD *)(sp2 + y * src2->bytes_per_line);
|
||||
yld = (DWORD *)(dp + y * dst->bytes_per_line);
|
||||
yla = (BYTE *)(sa + y * src1->width);
|
||||
|
||||
for (x = 0; x < sw; x++) {
|
||||
*yld = SUTURADD24(*yls1, ALPHABLEND24(*yls1, *yls2, *yla));
|
||||
yls1++; yls2++; yld++; yla++;
|
||||
}
|
||||
for (x = 0; x < sw; x++) {
|
||||
*yld = SUTURADD24(*yls1, ALPHABLEND24(*yls1, *yls2, *yla));
|
||||
yls1++; yls2++; yld++; yla++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,22 +41,22 @@
|
||||
* @param sw: 転送幅
|
||||
* @param sh: 転送高さ
|
||||
*/
|
||||
int gr_copy_alpha_map(surface_t *dst, int dx, int dy, surface_t *src, int sx, int sy, int sw, int sh) {
|
||||
BYTE *sp, *dp;
|
||||
void gr_copy_alpha_map(surface_t *dst, int dx, int dy, surface_t *src, int sx, int sy, int sw, int sh) {
|
||||
uint8_t *sp, *dp;
|
||||
|
||||
if (!gr_clip(src, &sx, &sy, &sw, &sh, dst, &dx, &dy)) return NG;
|
||||
if (!gr_clip(src, &sx, &sy, &sw, &sh, dst, &dx, &dy)) return;
|
||||
|
||||
sp = GETOFFSET_ALPHA(src, sx, sy);
|
||||
dp = GETOFFSET_ALPHA(dst, dx, dy);
|
||||
|
||||
if (sp == NULL) {
|
||||
WARNING("src alpha NULL\n");
|
||||
return NG;
|
||||
WARNING("src alpha NULL");
|
||||
return;
|
||||
}
|
||||
|
||||
if (dp == NULL) {
|
||||
WARNING("dst alpha NULL\n");
|
||||
return NG;
|
||||
WARNING("dst alpha NULL");
|
||||
return;
|
||||
}
|
||||
|
||||
if (src == dst) {
|
||||
@@ -82,6 +82,4 @@ int gr_copy_alpha_map(surface_t *dst, int dx, int dy, surface_t *src, int sx, in
|
||||
dp += dst->width;
|
||||
}
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
@@ -6,11 +6,11 @@
|
||||
#include "ngraph.h"
|
||||
#include "ags.h"
|
||||
|
||||
int gr_fill_alpha_map(surface_t *dst, int dx, int dy, int dw, int dh, int lv) {
|
||||
BYTE *a;
|
||||
void gr_fill_alpha_map(surface_t *dst, int dx, int dy, int dw, int dh, int lv) {
|
||||
uint8_t *a;
|
||||
|
||||
if (!gr_clip_xywh(dst, &dx, &dy, &dw, &dh)) {
|
||||
return NG;
|
||||
return;
|
||||
}
|
||||
|
||||
a = GETOFFSET_ALPHA(dst, dx, dy);
|
||||
@@ -19,6 +19,4 @@ int gr_fill_alpha_map(surface_t *dst, int dx, int dy, int dw, int dh, int lv) {
|
||||
memset(a, lv, dw);
|
||||
a += dst->width;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
#ifndef __NGRAPH_H__
|
||||
#define __NGRAPH_H__
|
||||
|
||||
#include "portab.h"
|
||||
#include "nact.h"
|
||||
#include "ags.h"
|
||||
#include "surface.h"
|
||||
#include "graph.h"
|
||||
|
||||
#define sf0 nact->ags.dib
|
||||
|
||||
struct SDL_Surface;
|
||||
|
||||
// DLL 用 graphic 関連関数
|
||||
|
||||
/* in graph.c */
|
||||
bool gr_clip(surface_t *ss, int *sx, int *sy, int *sw, int *sh, surface_t *ds, int *dx, int *dy);
|
||||
bool gr_clip_xywh(surface_t *ss, int *sx, int *sy, int *sw, int *sh);
|
||||
|
||||
/* in graph_fillrect_amap.c */
|
||||
void gr_fill_alpha_map(surface_t *dst, int dx, int dy, int dw, int dh, int lv);
|
||||
|
||||
/* in graph_copy_amap.c */
|
||||
void gr_copy_alpha_map(surface_t *dst, int dx, int dy, surface_t *src, int sx, int sy, int sw, int sh);
|
||||
|
||||
// /* in graph_bright_dst_only.c */
|
||||
#define gr_bright_dst_only(dst,dx,dy,w,h,lv) gr_copy_bright(dst,dx,dy,dst,dx,dy,w,h,lv)
|
||||
// void gr_bright_dst_only(surface_t *dst, int dx, int dy, int w, int h, int lv);
|
||||
|
||||
/* defined in cg.c */
|
||||
surface_t *sf_loadcg_no(int no);
|
||||
|
||||
#endif /* __GRAPH_H__ */
|
||||
@@ -0,0 +1,80 @@
|
||||
#include "config.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <SDL.h>
|
||||
|
||||
#include "portab.h"
|
||||
#include "surface.h"
|
||||
#include "system.h"
|
||||
|
||||
static surface_t *create(int width, int height, bool has_pixel, bool has_alpha) {
|
||||
surface_t *s = calloc(1, sizeof(surface_t));
|
||||
s->width = width;
|
||||
s->height = height;
|
||||
|
||||
if (has_pixel) {
|
||||
s->sdl_surface = SDL_CreateRGBSurfaceWithFormat(0, width, height, 32, SDL_PIXELFORMAT_RGB888);
|
||||
}
|
||||
|
||||
if (has_alpha) {
|
||||
s->alpha = calloc(width * (height +1), sizeof(uint8_t));
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
// Create a surface with pixel and alpha data
|
||||
surface_t *sf_create_surface(int width, int height) {
|
||||
return create(width, height, true, true);
|
||||
}
|
||||
|
||||
// Create a surface with alpha data only
|
||||
surface_t *sf_create_alpha(int width, int height) {
|
||||
return create(width, height, false, true);
|
||||
}
|
||||
|
||||
// Create a surface with pixel data only
|
||||
surface_t *sf_create_pixel(int width, int height) {
|
||||
return create(width, height, true, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* surfaceオブジェクトの開放
|
||||
* @param s: 開放するオブジェクト
|
||||
* @return: なし
|
||||
*/
|
||||
void sf_free(surface_t *s) {
|
||||
if (s == NULL) return;
|
||||
if (s->sdl_surface) SDL_FreeSurface(s->sdl_surface);
|
||||
if (s->alpha) free(s->alpha);
|
||||
free(s);
|
||||
}
|
||||
|
||||
/**
|
||||
* surface の複製を作成(dupulicate)
|
||||
* @param in: 複製もと
|
||||
* @return : 複製したsurface
|
||||
*/
|
||||
surface_t *sf_dup(surface_t *in) {
|
||||
surface_t *sf;
|
||||
int len;
|
||||
|
||||
if (in == NULL) return NULL;
|
||||
|
||||
sf = malloc(sizeof(surface_t));
|
||||
memcpy(sf, in, sizeof(surface_t));
|
||||
|
||||
if (in->sdl_surface) {
|
||||
sf->sdl_surface = SDL_ConvertSurface(in->sdl_surface, in->sdl_surface->format, 0);
|
||||
}
|
||||
|
||||
if (in->alpha) {
|
||||
len = sf->width * sf->height;
|
||||
sf->alpha = malloc(sizeof(uint8_t) * (len + sf->width));
|
||||
memcpy(sf->alpha, in->alpha, len);
|
||||
}
|
||||
|
||||
return sf;
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
#ifndef __SURFACE_H__
|
||||
#define __SURFACE_H__
|
||||
|
||||
#include "portab.h"
|
||||
#include "ags.h"
|
||||
|
||||
extern surface_t *sf_create_surface(int width, int height);
|
||||
extern surface_t *sf_create_alpha(int width, int height);
|
||||
extern surface_t *sf_create_pixel(int width, int height);
|
||||
extern void sf_free(surface_t *s);
|
||||
extern surface_t *sf_dup(surface_t *in);
|
||||
|
||||
#endif /* __SURFACE_H__ */
|
||||
+4
-4
@@ -42,7 +42,7 @@ static void RandMTInit() {
|
||||
*/
|
||||
int p1 = getCaliValue(); /* ITimer */
|
||||
|
||||
DEBUG_COMMAND("Math.RandMTInit %d:\n", p1);
|
||||
TRACE("Math.RandMTInit %d:", p1);
|
||||
}
|
||||
|
||||
static void RandMTGet() {
|
||||
@@ -61,7 +61,7 @@ static void RandMTGet() {
|
||||
*var = (int)(genrand() * num) + 1;
|
||||
}
|
||||
|
||||
DEBUG_COMMAND("Math.RandMTGet %d,%p:\n", num, var);
|
||||
TRACE("Math.RandMTGet %d,%p:", num, var);
|
||||
}
|
||||
|
||||
static void RandMTMakeNumTable() {
|
||||
@@ -74,7 +74,7 @@ static void RandMTMakeNumTable() {
|
||||
|
||||
numtblmax = p1;
|
||||
|
||||
DEBUG_COMMAND("Math.RandMTMakeNumTable %d:\n", p1);
|
||||
TRACE("Math.RandMTMakeNumTable %d:", p1);
|
||||
}
|
||||
|
||||
static void RandMTGetNumTable() {
|
||||
@@ -87,7 +87,7 @@ static void RandMTGetNumTable() {
|
||||
|
||||
*var = (int)(genrand() * numtblmax) + 1;
|
||||
|
||||
DEBUG_COMMAND("Math.RandMTGetNumTable %d:\n", *var);
|
||||
TRACE("Math.RandMTGetNumTable %d:", *var);
|
||||
}
|
||||
|
||||
static const ModuleFunc functions[] = {
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
#include "msgskip.h"
|
||||
#include "utfsjis.h"
|
||||
|
||||
static boolean valid;
|
||||
static bool valid;
|
||||
static int action;
|
||||
|
||||
static void Init() {
|
||||
@@ -26,7 +26,7 @@ static void Init() {
|
||||
valid = true;
|
||||
*p1 = 0;
|
||||
|
||||
DEBUG_COMMAND("MsgSkip.Init %p,%d,%d,%d:\n", p1, p2, p3, p4);
|
||||
TRACE("MsgSkip.Init %p,%d,%d,%d:", p1, p2, p3, p4);
|
||||
}
|
||||
|
||||
static void Start() {
|
||||
@@ -39,7 +39,7 @@ static void Start() {
|
||||
free(path);
|
||||
free(fname_utf8);
|
||||
|
||||
DEBUG_COMMAND("MsgSkip.Start %p,%d:\n", p1, p2);
|
||||
TRACE("MsgSkip.Start %p,%d:", p1, p2);
|
||||
}
|
||||
|
||||
static void SetValid() {
|
||||
@@ -48,7 +48,7 @@ static void SetValid() {
|
||||
valid = p1;
|
||||
msgskip_pause(!valid);
|
||||
|
||||
DEBUG_COMMAND("MsgSkip.SetValid %d:\n", p1);
|
||||
TRACE("MsgSkip.SetValid %d:", p1);
|
||||
}
|
||||
|
||||
static void GetValid() {
|
||||
@@ -56,7 +56,7 @@ static void GetValid() {
|
||||
|
||||
*p1 = valid;
|
||||
|
||||
DEBUG_COMMAND("MsgSkip.GetValid %p:\n", p1);
|
||||
TRACE("MsgSkip.GetValid %p:", p1);
|
||||
}
|
||||
|
||||
static void SetAction() {
|
||||
@@ -64,7 +64,7 @@ static void SetAction() {
|
||||
|
||||
action = p1;
|
||||
|
||||
DEBUG_COMMAND("MsgSkip.SetAcion %d:\n", p1);
|
||||
TRACE("MsgSkip.SetAcion %d:", p1);
|
||||
}
|
||||
|
||||
static void GetAction() {
|
||||
@@ -72,19 +72,19 @@ static void GetAction() {
|
||||
|
||||
*p1 = action;
|
||||
|
||||
DEBUG_COMMAND("MsgSkip.GetAcion %p:\n", p1);
|
||||
TRACE("MsgSkip.GetAcion %p:", p1);
|
||||
}
|
||||
|
||||
static void PushStr() {
|
||||
int p1 = getCaliValue();
|
||||
|
||||
DEBUG_COMMAND_YET("MsgSkip.PushStr %d:\n", p1);
|
||||
TRACE_UNIMPLEMENTED("MsgSkip.PushStr %d:", p1);
|
||||
}
|
||||
|
||||
static void PopStr() {
|
||||
int p1 = getCaliValue();
|
||||
|
||||
DEBUG_COMMAND_YET("MsgSkip.PopStr %d:\n", p1);
|
||||
TRACE_UNIMPLEMENTED("MsgSkip.PopStr %d:", p1);
|
||||
}
|
||||
|
||||
static const ModuleFunc functions[] = {
|
||||
|
||||
+84
-72
@@ -13,6 +13,7 @@
|
||||
#include "nt_scenario.h"
|
||||
#include "nt_msg.h"
|
||||
#include "nt_event.h"
|
||||
#include "sactcg.h"
|
||||
|
||||
#include "sactstring.h"
|
||||
|
||||
@@ -35,11 +36,22 @@ static void Init(void) { /* 0 */
|
||||
|
||||
*var = 1;
|
||||
|
||||
DEBUG_COMMAND_YET("NIGHTDLL.Init %p:\n", var);
|
||||
TRACE_UNIMPLEMENTED("NIGHTDLL.Init %p:", var);
|
||||
}
|
||||
|
||||
static void NIGHTDLL_reset(void) {
|
||||
nt_sstr_reset();
|
||||
nt_sp_clear_updatelist();
|
||||
for (int i = 0; i < SPRITEMAX; i++) {
|
||||
if (night.sp[i])
|
||||
nt_sp_free(night.sp[i]);
|
||||
}
|
||||
nt_scg_freeall();
|
||||
memset(&night, 0, sizeof(night));
|
||||
}
|
||||
|
||||
static void InitGame() { /* 1 */
|
||||
ags_setAntialiasedStringMode(TRUE);
|
||||
ags_setAntialiasedStringMode(true);
|
||||
sys_setHankakuMode(2);
|
||||
|
||||
nact->msgout = ntmsg_add;
|
||||
@@ -50,7 +62,7 @@ static void InitGame() { /* 1 */
|
||||
ntmsg_init();
|
||||
nt_sstr_init();
|
||||
|
||||
DEBUG_COMMAND_YET("NIGHTDLL.InitGame:\n");
|
||||
TRACE_UNIMPLEMENTED("NIGHTDLL.InitGame:");
|
||||
}
|
||||
|
||||
// メッセージの枠の表示
|
||||
@@ -59,7 +71,7 @@ static void SetMsgFrame() { /* 2 */
|
||||
|
||||
ntmsg_set_frame(p1);
|
||||
|
||||
DEBUG_COMMAND_YET("NIGHTDLL.SetMsgFram %d:\n", p1);
|
||||
TRACE_UNIMPLEMENTED("NIGHTDLL.SetMsgFram %d:", p1);
|
||||
}
|
||||
|
||||
// メッセージの表示位置の設定
|
||||
@@ -68,21 +80,21 @@ static void SetMsgPlaceMethod(void) { /* 3 */
|
||||
// 2=メッセージ枠+顔つき
|
||||
ntmsg_set_place(p1);
|
||||
|
||||
DEBUG_COMMAND_YET("NIGHTDLL.SetMsgPlaceMethod %d:\n", p1);
|
||||
TRACE_UNIMPLEMENTED("NIGHTDLL.SetMsgPlaceMethod %d:", p1);
|
||||
}
|
||||
|
||||
// 未実装?
|
||||
static void SetMsgDrawEffect(void) { /* 4 */
|
||||
int p1 = getCaliValue(); // 0, 1, 2, 3 (実際にはどれも機能しない?)
|
||||
|
||||
DEBUG_COMMAND_YET("NIGHTDLL.SetMsgDrawEffect %d:\n", p1);
|
||||
TRACE_UNIMPLEMENTED("NIGHTDLL.SetMsgDrawEffect %d:", p1);
|
||||
}
|
||||
|
||||
// 未実装?
|
||||
static void SetMsgClearEffect(void) { /* 5 */
|
||||
int p1 = getCaliValue(); // 0, 1, 2, 4 (実際にはどれも機能しない?)
|
||||
|
||||
DEBUG_COMMAND_YET("NIGHTDLL.SetMsgClearEffect %d:\n", p1);
|
||||
TRACE_UNIMPLEMENTED("NIGHTDLL.SetMsgClearEffect %d:", p1);
|
||||
}
|
||||
|
||||
// 壁紙CGの設定
|
||||
@@ -91,7 +103,7 @@ static void SetWallPaper(void) { /* 6 */
|
||||
|
||||
nt_gr_set_wallpaper(p1);
|
||||
|
||||
DEBUG_COMMAND_YET("NIGHTDLL.SetWallPaper %d:\n", p1);
|
||||
TRACE_UNIMPLEMENTED("NIGHTDLL.SetWallPaper %d:", p1);
|
||||
}
|
||||
|
||||
// 背景CGの設定
|
||||
@@ -100,7 +112,7 @@ static void SetScenery(void) { /* 7 */
|
||||
|
||||
nt_gr_set_scenery(p1);
|
||||
|
||||
DEBUG_COMMAND_YET("NIGHTDLL.SetScenery %d:\n", p1);
|
||||
TRACE_UNIMPLEMENTED("NIGHTDLL.SetScenery %d:", p1);
|
||||
}
|
||||
|
||||
// 顔CGの設定
|
||||
@@ -109,7 +121,7 @@ static void SetFace(void) { /* 8 */
|
||||
|
||||
nt_gr_set_face(p1);
|
||||
|
||||
DEBUG_COMMAND_YET("NIGHTDLL.SetFace %d:\n", p1);
|
||||
TRACE_UNIMPLEMENTED("NIGHTDLL.SetFace %d:", p1);
|
||||
}
|
||||
|
||||
// 立ち絵左の設定
|
||||
@@ -118,7 +130,7 @@ static void SetSpriteL(void) { /* 9 */
|
||||
|
||||
nt_gr_set_spL(p1);
|
||||
|
||||
DEBUG_COMMAND_YET("NIGHTDLL.SetSpriteL %d:\n", p1);
|
||||
TRACE_UNIMPLEMENTED("NIGHTDLL.SetSpriteL %d:", p1);
|
||||
}
|
||||
|
||||
// 立ち絵中央の設定
|
||||
@@ -127,7 +139,7 @@ static void SetSpriteM(void) { /* 10 */
|
||||
|
||||
nt_gr_set_spM(p1);
|
||||
|
||||
DEBUG_COMMAND_YET("NIGHTDLL.SetSpriteM %d:\n", p1);
|
||||
TRACE_UNIMPLEMENTED("NIGHTDLL.SetSpriteM %d:", p1);
|
||||
}
|
||||
|
||||
// 立ち絵右の設定
|
||||
@@ -136,7 +148,7 @@ static void SetSpriteR(void) { /* 11 */
|
||||
|
||||
nt_gr_set_spR(p1);
|
||||
|
||||
DEBUG_COMMAND_YET("NIGHTDLL.SetSpriteR %d:\n", p1);
|
||||
TRACE_UNIMPLEMENTED("NIGHTDLL.SetSpriteR %d:", p1);
|
||||
}
|
||||
|
||||
// 立ち絵左の設定(季節違い?)
|
||||
@@ -145,7 +157,7 @@ static void SetSpriteSeasonL(void) { /* 12 */
|
||||
|
||||
nt_gr_set_spsL(p1);
|
||||
|
||||
DEBUG_COMMAND_YET("NIGHTDLL.SetSpriteSeasonL %d:\n", p1);
|
||||
TRACE_UNIMPLEMENTED("NIGHTDLL.SetSpriteSeasonL %d:", p1);
|
||||
}
|
||||
|
||||
// 立ち絵中央の設定(季節違い?)
|
||||
@@ -154,7 +166,7 @@ static void SetSpriteSeasonM(void) { /* 13 */
|
||||
|
||||
nt_gr_set_spM(p1);
|
||||
|
||||
DEBUG_COMMAND_YET("NIGHTDLL.SetSpriteSeasonM %d:\n", p1);
|
||||
TRACE_UNIMPLEMENTED("NIGHTDLL.SetSpriteSeasonM %d:", p1);
|
||||
}
|
||||
|
||||
// 立ち絵右の設定(季節違い?)
|
||||
@@ -163,14 +175,14 @@ static void SetSpriteSeasonR(void) { /* 14 */
|
||||
|
||||
nt_gr_set_spsR(p1);
|
||||
|
||||
DEBUG_COMMAND_YET("NIGHTDLL.SetSpriteSeasonR %d:\n", p1);
|
||||
TRACE_UNIMPLEMENTED("NIGHTDLL.SetSpriteSeasonR %d:", p1);
|
||||
}
|
||||
|
||||
// 改行
|
||||
static void StartNewLine(void) { /* 15 */
|
||||
ntmsg_newline();
|
||||
|
||||
DEBUG_COMMAND_YET("NIGHTDLL.StartNewLine:\n");
|
||||
TRACE_UNIMPLEMENTED("NIGHTDLL.StartNewLine:");
|
||||
}
|
||||
|
||||
// メッセージフォントサイズの設定
|
||||
@@ -179,7 +191,7 @@ static void SetFontSize(void) { /* 16 */
|
||||
|
||||
night.fontsize = p1;
|
||||
|
||||
DEBUG_COMMAND_YET("NIGHTDLL.SetFontSize %d:\n", p1);
|
||||
TRACE_UNIMPLEMENTED("NIGHTDLL.SetFontSize %d:", p1);
|
||||
}
|
||||
|
||||
// フォントの種類の設定
|
||||
@@ -188,7 +200,7 @@ static void SetFont(void) { /* 17 */
|
||||
|
||||
night.fonttype = p1;
|
||||
|
||||
DEBUG_COMMAND_YET("NIGHTDLL.SetFont %d:\n", p1);
|
||||
TRACE_UNIMPLEMENTED("NIGHTDLL.SetFont %d:", p1);
|
||||
}
|
||||
|
||||
// 選択肢モード ON
|
||||
@@ -197,7 +209,7 @@ static void SetSelMode(void) { /* 18 */
|
||||
|
||||
night.selmode = p1;
|
||||
|
||||
DEBUG_COMMAND_YET("NIGHTDLL.SetSelMode %d:\n", p1);
|
||||
TRACE_UNIMPLEMENTED("NIGHTDLL.SetSelMode %d:", p1);
|
||||
}
|
||||
|
||||
// キー入力待ち後、改ページ
|
||||
@@ -206,7 +218,7 @@ static void AnalyzeMessage(void) { /* 19 */
|
||||
|
||||
*var = ntmsg_ana();
|
||||
|
||||
DEBUG_COMMAND_YET("NIGHTDLL.AnalyzeMessage %p:\n", var);
|
||||
TRACE_UNIMPLEMENTED("NIGHTDLL.AnalyzeMessage %p:", var);
|
||||
}
|
||||
|
||||
// ~DRAWの効果時間
|
||||
@@ -215,7 +227,7 @@ static void SetDrawTime(void) { /* 20 */
|
||||
|
||||
nt_gr_set_drawtime(p1);
|
||||
|
||||
DEBUG_COMMAND_YET("NIGHTDLL.SetDrawTime %d:\n", p1);
|
||||
TRACE_UNIMPLEMENTED("NIGHTDLL.SetDrawTime %d:", p1);
|
||||
}
|
||||
|
||||
// 効果つき画面更新
|
||||
@@ -224,7 +236,7 @@ static void Draw(void) { /* 21 */
|
||||
|
||||
nt_gr_draw(p1);
|
||||
|
||||
DEBUG_COMMAND_YET("NIGHTDLL.Draw %d:\n", p1);
|
||||
TRACE_UNIMPLEMENTED("NIGHTDLL.Draw %d:", p1);
|
||||
}
|
||||
|
||||
// 音声データを再生
|
||||
@@ -233,21 +245,21 @@ static void SetVoice(void) { /* 22 */
|
||||
|
||||
nt_voice_set(p1);
|
||||
|
||||
DEBUG_COMMAND_YET("NIGHTDLL.SetVoice %d:\n", p1);
|
||||
TRACE_UNIMPLEMENTED("NIGHTDLL.SetVoice %d:", p1);
|
||||
}
|
||||
|
||||
// 未使用
|
||||
static void WaitKey(void) { /* 23 */
|
||||
int p1 = getCaliValue(); //
|
||||
|
||||
DEBUG_COMMAND_YET("NIGHTDLL.WaitKey %d:\n", p1);
|
||||
TRACE_UNIMPLEMENTED("NIGHTDLL.WaitKey %d:", p1);
|
||||
}
|
||||
|
||||
static void AddFeeling(void) { /* 24 */
|
||||
int p1 = getCaliValue(); // person(1:新開,2:星川,3:百瀬,4:いずみ,5:鏡花,6:真言美,7:マコト
|
||||
int p2 = getCaliValue(); // val
|
||||
|
||||
DEBUG_COMMAND_YET("NIGHTDLL.AddFeeling %d:\n", p1);
|
||||
TRACE_UNIMPLEMENTED("NIGHTDLL.AddFeeling %d:", p1);
|
||||
|
||||
}
|
||||
|
||||
@@ -255,7 +267,7 @@ static void SubFeeling(void) { /* 25 */
|
||||
int p1 = getCaliValue(); // person
|
||||
int p2 = getCaliValue(); // val
|
||||
|
||||
DEBUG_COMMAND_YET("NIGHTDLL.SubFeeling %d:\n", p1);
|
||||
TRACE_UNIMPLEMENTED("NIGHTDLL.SubFeeling %d:", p1);
|
||||
}
|
||||
|
||||
static void CallEvent(void) { /* 26 */
|
||||
@@ -263,7 +275,7 @@ static void CallEvent(void) { /* 26 */
|
||||
|
||||
nt_sco_callevent(p1);
|
||||
|
||||
DEBUG_COMMAND_YET("NIGHTDLL.CallEvent %d:\n", p1);
|
||||
TRACE_UNIMPLEMENTED("NIGHTDLL.CallEvent %d:", p1);
|
||||
}
|
||||
|
||||
static void ScreenCG(void) { /* 27 */
|
||||
@@ -282,7 +294,7 @@ static void ScreenCG(void) { /* 27 */
|
||||
|
||||
nt_gr_screencg(no, x, y);
|
||||
|
||||
DEBUG_COMMAND_YET("NIGHTDLL.ScreenCG %d,%d,%d:\n", x, y, no);
|
||||
TRACE_UNIMPLEMENTED("NIGHTDLL.ScreenCG %d,%d,%d:", x, y, no);
|
||||
}
|
||||
|
||||
static void RunGameMain(void) { /* 28 */
|
||||
@@ -298,7 +310,7 @@ static void RunGameMain(void) { /* 28 */
|
||||
|
||||
*p1 = nt_sco_main(p5);
|
||||
|
||||
DEBUG_COMMAND_YET("NIGHTDLL.RunGameMain %p,%d,%d,%d,%d:\n", p1, p2, p3, p4, p5);
|
||||
TRACE_UNIMPLEMENTED("NIGHTDLL.RunGameMain %p,%d,%d,%d,%d:", p1, p2, p3, p4, p5);
|
||||
}
|
||||
|
||||
static void CheckNewGame(void) { /* 29 */
|
||||
@@ -306,21 +318,21 @@ static void CheckNewGame(void) { /* 29 */
|
||||
|
||||
*p1 = 0;
|
||||
|
||||
DEBUG_COMMAND_YET("NIGHTDLL.CheckNewGame %p:\n", p1);
|
||||
TRACE_UNIMPLEMENTED("NIGHTDLL.CheckNewGame %p:", p1);
|
||||
}
|
||||
|
||||
static void SaveStartData(void) { /* 30 */
|
||||
DEBUG_COMMAND_YET("NIGHTDLL.SaveStartData:\n");
|
||||
TRACE_UNIMPLEMENTED("NIGHTDLL.SaveStartData:");
|
||||
}
|
||||
|
||||
static void PrintExitSystem(void) { /* 31 */
|
||||
DEBUG_COMMAND_YET("NIGHTDLL.PrintExitSystem:\n");
|
||||
TRACE_UNIMPLEMENTED("NIGHTDLL.PrintExitSystem:");
|
||||
}
|
||||
|
||||
static void SetCalendar(void) { /* 32 */
|
||||
int p1 = getCaliValue(); // 0, 1, 2
|
||||
|
||||
DEBUG_COMMAND_YET("NIGHTDLL.SetCalendar %d:\n", p1);
|
||||
TRACE_UNIMPLEMENTED("NIGHTDLL.SetCalendar %d:", p1);
|
||||
}
|
||||
|
||||
static void SetDate(void) { /* 33 */
|
||||
@@ -332,7 +344,7 @@ static void SetDate(void) { /* 33 */
|
||||
night.Day = p2;
|
||||
night.DayOfWeek = p3;
|
||||
|
||||
DEBUG_COMMAND_YET("NIGHTDLL.SetDate %d,%d,%d:\n", p1, p2, p3);
|
||||
TRACE_UNIMPLEMENTED("NIGHTDLL.SetDate %d,%d,%d:", p1, p2, p3);
|
||||
}
|
||||
|
||||
static void GetDate(void) { /* 34 */
|
||||
@@ -344,11 +356,11 @@ static void GetDate(void) { /* 34 */
|
||||
*p2 = night.Day;
|
||||
*p3 = night.DayOfWeek;
|
||||
|
||||
DEBUG_COMMAND_YET("NIGHTDLL.GetDate %p,%p,%p:\n", p1, p2, p3);
|
||||
TRACE_UNIMPLEMENTED("NIGHTDLL.GetDate %p,%p,%p:", p1, p2, p3);
|
||||
}
|
||||
|
||||
static void SelectGameLevel(void) { /* 35 */
|
||||
DEBUG_COMMAND_YET("NIGHTDLL.SelectGameLevel:\n");
|
||||
TRACE_UNIMPLEMENTED("NIGHTDLL.SelectGameLevel:");
|
||||
}
|
||||
|
||||
static void RunEventDungeon(void) { /* 36 */
|
||||
@@ -357,13 +369,13 @@ static void RunEventDungeon(void) { /* 36 */
|
||||
|
||||
*p1 = 1;
|
||||
|
||||
DEBUG_COMMAND_YET("NIGHTDLL.RunEventDungeon %p,%d:\n", p1, p2);
|
||||
TRACE_UNIMPLEMENTED("NIGHTDLL.RunEventDungeon %p,%d:", p1, p2);
|
||||
}
|
||||
|
||||
static void RunEventBattle(void) { /* 37 */
|
||||
int p1 = getCaliValue(); // 実際には機能しない?
|
||||
|
||||
DEBUG_COMMAND_YET("NIGHTDLL.RunEventBattle %d:\n", p1);
|
||||
TRACE_UNIMPLEMENTED("NIGHTDLL.RunEventBattle %d:", p1);
|
||||
}
|
||||
|
||||
// CD再生開始
|
||||
@@ -372,7 +384,7 @@ static void CDPlay(void) { /* 38 */
|
||||
|
||||
nt_cd_play(p1);
|
||||
|
||||
DEBUG_COMMAND_YET("NIGHTDLL.CDPlay %d:\n", p1);
|
||||
TRACE_UNIMPLEMENTED("NIGHTDLL.CDPlay %d:", p1);
|
||||
}
|
||||
|
||||
// CD再生停止
|
||||
@@ -381,16 +393,16 @@ static void CDStop(void) { /* 39 */
|
||||
|
||||
nt_cd_stop(p1);
|
||||
|
||||
DEBUG_COMMAND_YET("NIGHTDLL.CDStop %d:\n", p1);
|
||||
TRACE_UNIMPLEMENTED("NIGHTDLL.CDStop %d:", p1);
|
||||
}
|
||||
|
||||
// CDのmute
|
||||
static void CDMute(void) { /* 40 */
|
||||
int p1 = getCaliValue(); // 0: mute off, 1: mute on
|
||||
|
||||
nt_cd_mute(p1 == 0 ? FALSE : TRUE);
|
||||
nt_cd_mute(p1 != 0);
|
||||
|
||||
DEBUG_COMMAND_YET("NIGHTDLL.CDMute %d:\n", p1);
|
||||
TRACE_UNIMPLEMENTED("NIGHTDLL.CDMute %d:", p1);
|
||||
}
|
||||
|
||||
// ch に効果音番号をセット
|
||||
@@ -400,7 +412,7 @@ static void SoundEffectSetWave(void) { /* 41 */
|
||||
|
||||
nt_snd_setwave(p1, p2);
|
||||
|
||||
DEBUG_COMMAND_YET("NIGHTDLL.SoundEffectSetWave %d,%d:\n", p1, p2);
|
||||
TRACE_UNIMPLEMENTED("NIGHTDLL.SoundEffectSetWave %d,%d:", p1, p2);
|
||||
}
|
||||
|
||||
// ch にくり返し数をセット
|
||||
@@ -410,7 +422,7 @@ static void SoundEffectSetLoop(void) { /* 42 */
|
||||
|
||||
nt_snd_setloop(p1, p2);
|
||||
|
||||
DEBUG_COMMAND_YET("NIGHTDLL.SoundEffectSetLoop %d,%d:\n", p1, p2);
|
||||
TRACE_UNIMPLEMENTED("NIGHTDLL.SoundEffectSetLoop %d,%d:", p1, p2);
|
||||
}
|
||||
|
||||
// ch に音量をセット
|
||||
@@ -420,7 +432,7 @@ static void SoundEffectSetVolume(void) { /* 43 */
|
||||
|
||||
nt_snd_setvol(p1, p2);
|
||||
|
||||
DEBUG_COMMAND_YET("NIGHTDLL.SoundEffectSetVolue %d,%d:\n", p1, p2);
|
||||
TRACE_UNIMPLEMENTED("NIGHTDLL.SoundEffectSetVolue %d,%d:", p1, p2);
|
||||
}
|
||||
|
||||
// 効果音の再生を終るまで待つか待たないか?
|
||||
@@ -428,9 +440,9 @@ static void SoundEffectSetSyncFlag(void) { /* 44 */
|
||||
int p1 = getCaliValue(); // ch
|
||||
int p2 = getCaliValue(); // 0: 終るまで待たない, 1: 待つ
|
||||
|
||||
nt_snd_waitend(p1, p2 == 0 ? FALSE : TRUE);
|
||||
nt_snd_waitend(p1, p2 != 0);
|
||||
|
||||
DEBUG_COMMAND_YET("NIGHTDLL.SoundEffectSetSyncFlag %d,%d:\n", p1, p2);
|
||||
TRACE_UNIMPLEMENTED("NIGHTDLL.SoundEffectSetSyncFlag %d,%d:", p1, p2);
|
||||
}
|
||||
|
||||
// ch の効果音を再生
|
||||
@@ -439,7 +451,7 @@ static void SoundEffectPlay(void) { /* 45 */
|
||||
|
||||
nt_snd_play(p1);
|
||||
|
||||
DEBUG_COMMAND_YET("NIGHTDLL.SoundEffectPlay %d:\n", p1);
|
||||
TRACE_UNIMPLEMENTED("NIGHTDLL.SoundEffectPlay %d:", p1);
|
||||
}
|
||||
|
||||
// ch の効果音を停止
|
||||
@@ -449,7 +461,7 @@ static void SoundEffectStop(void) { /* 46 */
|
||||
|
||||
nt_snd_stop(p1, p2);
|
||||
|
||||
DEBUG_COMMAND_YET("NIGHTDLL.SoundEffectStop %d,%d:\n", p1,p2);
|
||||
TRACE_UNIMPLEMENTED("NIGHTDLL.SoundEffectStop %d,%d:", p1,p2);
|
||||
}
|
||||
|
||||
// 全てのチャンネルの再生を停止
|
||||
@@ -458,86 +470,86 @@ static void SoundEffectStopAll(void) { /* 47 */
|
||||
|
||||
nt_snd_stopall(p1);
|
||||
|
||||
DEBUG_COMMAND_YET("NIGHTDLL.SoundEffectStopAll %d:\n", p1);
|
||||
TRACE_UNIMPLEMENTED("NIGHTDLL.SoundEffectStopAll %d:", p1);
|
||||
}
|
||||
|
||||
static void RunSoundMode(void) { /* 48 */
|
||||
|
||||
DEBUG_COMMAND_YET("NIGHTDLL.RunSoundMode:\n");
|
||||
TRACE_UNIMPLEMENTED("NIGHTDLL.RunSoundMode:");
|
||||
}
|
||||
|
||||
static void RunMapEditor(void) { /* 49 */
|
||||
int *p1 = getCaliVariable();
|
||||
|
||||
DEBUG_COMMAND_YET("NIGHTDLL.RunMapEditor %p:\n", p1);
|
||||
TRACE_UNIMPLEMENTED("NIGHTDLL.RunMapEditor %p:", p1);
|
||||
}
|
||||
|
||||
static void VisualListClear(void) { /* 50 */
|
||||
|
||||
DEBUG_COMMAND_YET("NIGHTDLL.VisualListClear:\n");
|
||||
TRACE_UNIMPLEMENTED("NIGHTDLL.VisualListClear:");
|
||||
}
|
||||
|
||||
static void VisualListAdd(void) { /* 51 */
|
||||
int p1 = getCaliValue();
|
||||
|
||||
DEBUG_COMMAND_YET("NIGHTDLL.VisualListAdd %d:\n", p1);
|
||||
TRACE_UNIMPLEMENTED("NIGHTDLL.VisualListAdd %d:", p1);
|
||||
}
|
||||
|
||||
static void GetLocalCountCG(void) { /* 52 */
|
||||
int *p1 = getCaliVariable();
|
||||
int p2 = getCaliValue();
|
||||
|
||||
DEBUG_COMMAND_YET("NIGHTDLL.GetLocalCountCG %p,%d:\n", p1, p2);
|
||||
TRACE_UNIMPLEMENTED("NIGHTDLL.GetLocalCountCG %p,%d:", p1, p2);
|
||||
}
|
||||
|
||||
static void PlayMemory(void) { /* 53 */
|
||||
int *p1 = getCaliVariable(); // 回想ページ
|
||||
int *p2 = getCaliVariable(); // 回想RESULT
|
||||
|
||||
DEBUG_COMMAND_YET("NIGHTDLL.PlayMemory %p,%p:\n", p1, p2);
|
||||
TRACE_UNIMPLEMENTED("NIGHTDLL.PlayMemory %p,%p:", p1, p2);
|
||||
}
|
||||
|
||||
static void GetEventFlagTotal(void) { /* 54 */
|
||||
int *p1 = getCaliVariable();
|
||||
int p2 = getCaliValue();
|
||||
|
||||
DEBUG_COMMAND_YET("NIGHTDLL.GetEventFlagTotal %p,%d:\n", p1, p2);
|
||||
TRACE_UNIMPLEMENTED("NIGHTDLL.GetEventFlagTotal %p,%d:", p1, p2);
|
||||
}
|
||||
|
||||
static void SetPlayerName(void) { /* 55 */
|
||||
int p1 = getCaliValue();
|
||||
|
||||
DEBUG_COMMAND_YET("NIGHTDLL.SetPlayerName %d:\n", p1);
|
||||
TRACE_UNIMPLEMENTED("NIGHTDLL.SetPlayerName %d:", p1);
|
||||
}
|
||||
|
||||
static void GetPlayerName(void) { /* 56 */
|
||||
int p1 = getCaliValue();
|
||||
|
||||
DEBUG_COMMAND_YET("NIGHTDLL.GetPlayerName %d:\n", p1);
|
||||
TRACE_UNIMPLEMENTED("NIGHTDLL.GetPlayerName %d:", p1);
|
||||
}
|
||||
|
||||
static void SaveGame(void) { /* 57 */
|
||||
int *p1 = getCaliVariable();
|
||||
|
||||
DEBUG_COMMAND_YET("NIGHTDLL.SaveGame %p:\n", p1);
|
||||
TRACE_UNIMPLEMENTED("NIGHTDLL.SaveGame %p:", p1);
|
||||
}
|
||||
|
||||
static void LoadGame(void) { /* 58 */
|
||||
int *p1 = getCaliVariable();
|
||||
|
||||
DEBUG_COMMAND_YET("NIGHTDLL.LoadGame %p:\n", p1);
|
||||
TRACE_UNIMPLEMENTED("NIGHTDLL.LoadGame %p:", p1);
|
||||
}
|
||||
|
||||
static void ExistSaveData(void) { /* 59 */
|
||||
int *p1 = getCaliVariable();
|
||||
|
||||
DEBUG_COMMAND_YET("NIGHTDLL.ExistSaveData %p:\n", p1);
|
||||
TRACE_UNIMPLEMENTED("NIGHTDLL.ExistSaveData %p:", p1);
|
||||
}
|
||||
|
||||
static void ExistStartData(void) { /* 60 */
|
||||
int *p1 = getCaliVariable();
|
||||
|
||||
DEBUG_COMMAND_YET("NIGHTDLL.ExistStartData %p:\n", p1);
|
||||
TRACE_UNIMPLEMENTED("NIGHTDLL.ExistStartData %p:", p1);
|
||||
}
|
||||
|
||||
static void SetAreaData(void) { /* 61 */
|
||||
@@ -545,27 +557,27 @@ static void SetAreaData(void) { /* 61 */
|
||||
int p2 = getCaliValue();
|
||||
int p3 = getCaliValue();
|
||||
|
||||
DEBUG_COMMAND_YET("NIGHTDLL.SetAreaData %d,%d,%d:\n", p1, p2, p3);
|
||||
TRACE_UNIMPLEMENTED("NIGHTDLL.SetAreaData %d,%d,%d:", p1, p2, p3);
|
||||
}
|
||||
|
||||
static void RunBattleTest(void) { /* 62 */
|
||||
DEBUG_COMMAND_YET("NIGHTDLL.RunBattleTest:\n");
|
||||
TRACE_UNIMPLEMENTED("NIGHTDLL.RunBattleTest:");
|
||||
}
|
||||
|
||||
static void RunTrainingTest(void) { /* 63 */
|
||||
DEBUG_COMMAND_YET("NIGHTDLL.RunTrainingTest:\n");
|
||||
TRACE_UNIMPLEMENTED("NIGHTDLL.RunTrainingTest:");
|
||||
}
|
||||
|
||||
static void TestEventCall(void) { /* 64 */
|
||||
DEBUG_COMMAND_YET("NIGHTDLL.TestEventCall:\n");
|
||||
TRACE_UNIMPLEMENTED("NIGHTDLL.TestEventCall:");
|
||||
}
|
||||
|
||||
static void Test(void) { /* 65 */
|
||||
DEBUG_COMMAND_YET("NIGHTDLL.Test:\n");
|
||||
TRACE_UNIMPLEMENTED("NIGHTDLL.Test:");
|
||||
}
|
||||
|
||||
static void DebugScenario(void) { /* 66 */
|
||||
DEBUG_COMMAND_YET("NIGHTDLL.DebugScenario:\n");
|
||||
TRACE_UNIMPLEMENTED("NIGHTDLL.DebugScenario:");
|
||||
}
|
||||
|
||||
static void GetDLLTime(void) { /* 67 */
|
||||
@@ -577,7 +589,7 @@ static void GetDLLTime(void) { /* 67 */
|
||||
int *p6 = getCaliVariable();
|
||||
int *p7 = getCaliVariable();
|
||||
|
||||
DEBUG_COMMAND_YET("NIGHTDLL.GetDLLTime %p,%p,%p,%p,%p,%p,%p:\n", p1, p2, p3, p4, p5, p6, p7);
|
||||
TRACE_UNIMPLEMENTED("NIGHTDLL.GetDLLTime %p,%p,%p,%p,%p,%p,%p:", p1, p2, p3, p4, p5, p6, p7);
|
||||
}
|
||||
|
||||
static const ModuleFunc functions[] = {
|
||||
@@ -651,4 +663,4 @@ static const ModuleFunc functions[] = {
|
||||
{"WaitKey", WaitKey},
|
||||
};
|
||||
|
||||
const Module module_NIGHTDLL = {"NIGHTDLL", functions, sizeof(functions) / sizeof(ModuleFunc)};
|
||||
const Module module_NIGHTDLL = {"NIGHTDLL", functions, sizeof(functions) / sizeof(ModuleFunc), NIGHTDLL_reset};
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
#include "config.h"
|
||||
#include "portab.h"
|
||||
#include "graphics.h"
|
||||
#include "surface.h"
|
||||
#include "ags.h"
|
||||
#include "sprite.h"
|
||||
|
||||
@@ -45,7 +44,7 @@ struct _night {
|
||||
|
||||
MyRectangle updaterect;
|
||||
|
||||
int fonttype;
|
||||
FontType fonttype;
|
||||
int fontsize;
|
||||
|
||||
sprite_t *sp[SPRITEMAX];
|
||||
@@ -55,7 +54,7 @@ struct _night {
|
||||
|
||||
// msg
|
||||
char msgbuf[MSGBUFMAX];
|
||||
boolean zhiding;
|
||||
bool zhiding;
|
||||
struct {
|
||||
void (* cbmove)(agsevent_t *);
|
||||
void (* cbrelease)(agsevent_t *);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
+12
-19
@@ -1,11 +1,10 @@
|
||||
#include <stdio.h>
|
||||
#include <SDL.h>
|
||||
|
||||
#include "portab.h"
|
||||
#include "system.h"
|
||||
#include "cg.h"
|
||||
#include "ags.h"
|
||||
#include "surface.h"
|
||||
#include "ngraph.h"
|
||||
#include "night.h"
|
||||
#include "sprite.h"
|
||||
#include "nt_scenario.h"
|
||||
@@ -54,8 +53,8 @@ void nt_gr_set_wallpaper(int no) {
|
||||
sp = nt_sp_new(SPNO_WALL, no, 0, 0, SPRITE_WP);
|
||||
nt_sp_add_updatelist(sp);
|
||||
if (no == 0) {
|
||||
sp->cursize.width = sf0->width;
|
||||
sp->cursize.height = sf0->height;
|
||||
sp->cursize.width = main_surface->w;
|
||||
sp->cursize.height = main_surface->h;
|
||||
sp->update = nt_sp_draw_wall;
|
||||
}
|
||||
|
||||
@@ -178,28 +177,22 @@ void nt_gr_draw(int effectno) {
|
||||
// 全消し
|
||||
break;
|
||||
case 1:
|
||||
nt_sp_update_all(TRUE);
|
||||
nt_sp_update_all(true);
|
||||
break;
|
||||
default:
|
||||
if (night.waitskiplv > 1) {
|
||||
nt_sp_update_all(TRUE);
|
||||
nt_sp_update_all(true);
|
||||
break;
|
||||
}
|
||||
//nt_sp_eupdate(effectno, effecttime, TRUE);
|
||||
nt_sp_eupdate(effectno, 1000, TRUE);
|
||||
//nt_sp_eupdate(effectno, effecttime, true);
|
||||
nt_sp_eupdate(effectno, 1000, true);
|
||||
}
|
||||
}
|
||||
|
||||
void nt_gr_screencg(int no, int x, int y) {
|
||||
surface_t *sf;
|
||||
|
||||
sf = sf_loadcg_no(no -1);
|
||||
|
||||
gre_BlendScreen(sf0, x, y, sf0, x, y, sf, 0, 0, sf->width, sf->height);
|
||||
|
||||
ags_updateArea(x, y, sf->width, sf->height);
|
||||
|
||||
sf_free(sf);
|
||||
SDL_Surface *sf = cg_load_as_sdlsurface(no - 1);
|
||||
SDL_SetSurfaceBlendMode(sf, SDL_BLENDMODE_ADD);
|
||||
SDL_BlitSurface(sf, NULL, main_surface, &(SDL_Rect){x, y, sf->w, sf->h});
|
||||
ags_updateArea(x, y, sf->w, sf->h);
|
||||
SDL_FreeSurface(sf);
|
||||
}
|
||||
|
||||
|
||||
|
||||
+83
-108
@@ -3,6 +3,7 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <SDL.h>
|
||||
|
||||
#include "portab.h"
|
||||
#include "system.h"
|
||||
@@ -11,7 +12,6 @@
|
||||
#include "ags.h"
|
||||
#include "nact.h"
|
||||
#include "input.h"
|
||||
#include "ngraph.h"
|
||||
#include "drawtext.h"
|
||||
#include "night.h"
|
||||
#include "nt_msg.h"
|
||||
@@ -25,23 +25,29 @@ extern int ntsel_dosel(void);
|
||||
#define SNAME_RYO "亮 "
|
||||
#define SNAME_RYO_DEF "亮"
|
||||
|
||||
// 通常メッセージ表示位置と大きさ
|
||||
#define MSGFRAME_0_X 6
|
||||
#define MSGFRAME_0_Y 347
|
||||
#define MSGFRAME_0_WIDTH 628
|
||||
#define MSGFRAME_0_HEIGHT 125
|
||||
// Normal message window
|
||||
static const SDL_Rect msgframe_0 = {
|
||||
.x = 6,
|
||||
.y = 347,
|
||||
.w = 628,
|
||||
.h = 125
|
||||
};
|
||||
|
||||
// 画面全体メッセージ表示位置と大きさ
|
||||
#define MSGFRAME_1_X 0
|
||||
#define MSGFRAME_1_Y 0
|
||||
#define MSGFRAME_1_WIDTH 640
|
||||
#define MSGFRAME_1_HEIGHT 480
|
||||
// Full screen message window
|
||||
static const SDL_Rect msgframe_1 = {
|
||||
.x = 0,
|
||||
.y = 0,
|
||||
.w = 640,
|
||||
.h = 480
|
||||
};
|
||||
|
||||
// 通常メッセージ(顔つき)表示位置と大きさ
|
||||
#define MSGFRAME_2_X (6+160)
|
||||
#define MSGFRAME_2_Y 347
|
||||
#define MSGFRAME_2_WIDTH (628-160)
|
||||
#define MSGFRAME_2_HEIGHT 125
|
||||
// Normal message (with face) window
|
||||
static const SDL_Rect msgframe_2 = {
|
||||
.x = 6 + 160,
|
||||
.y = 347,
|
||||
.w = 628 - 160,
|
||||
.h = 125
|
||||
};
|
||||
|
||||
// キー入力アニメーション位置
|
||||
#define HAKANIM_LOC_X 620
|
||||
@@ -55,7 +61,7 @@ extern int ntsel_dosel(void);
|
||||
|
||||
static void ntmsg_out(int wNum, int wSize, int wColorR, int wColorG, int wColorB, int wFont, int wSpeed, int wLineSpace);
|
||||
static void set_align(char *msg, sprite_t *sp, int wSize);
|
||||
static BYTE *get_char(BYTE *msg, char *mbuf, int bufmax);
|
||||
static uint8_t *get_char(uint8_t *msg, char *mbuf, int bufmax);
|
||||
static void cb_keyrelease(agsevent_t *e);
|
||||
static void cb_mousemove(agsevent_t *e);
|
||||
static void setup_hakanim();
|
||||
@@ -69,7 +75,7 @@ void ntmsg_init() {
|
||||
sprite_t *sp;
|
||||
|
||||
// メッセージスプライト
|
||||
sp = night.sp[SPNO_MSGFRAME_FG] = nt_sp_msg_new(SPNO_MSGFRAME_FG, 0, 0, sf0->width, sf0->height);
|
||||
sp = night.sp[SPNO_MSGFRAME_FG] = nt_sp_msg_new(SPNO_MSGFRAME_FG, 0, 0, main_surface->w, main_surface->h);
|
||||
nt_sp_add_updatelist(sp);
|
||||
|
||||
// メッセージ背景用CG
|
||||
@@ -78,7 +84,7 @@ void ntmsg_init() {
|
||||
|
||||
// 文字背景CG作成
|
||||
nt_scg_create(CGNO_MSGFR_BG,
|
||||
sf0->width, sf0->height,
|
||||
main_surface->w, main_surface->h,
|
||||
0, 0, 0, 255);
|
||||
// night.cg[CGNO_MSGFR_BG]->refcnt++;
|
||||
|
||||
@@ -95,7 +101,7 @@ void ntmsg_init() {
|
||||
sp->u.anime.interval = HAKANIM_INTERVAL;
|
||||
nt_sp_add_updatelist(sp);
|
||||
nt_sp_set_loc(sp, HAKANIM_LOC_X, HAKANIM_LOC_Y);
|
||||
nt_sp_set_show(sp, FALSE);
|
||||
nt_sp_set_show(sp, false);
|
||||
sp->update = nt_sp_draw_scg;
|
||||
|
||||
|
||||
@@ -121,45 +127,34 @@ void ntmsg_init() {
|
||||
// type=1 枠あり
|
||||
// type=2 中央
|
||||
void ntmsg_set_frame(int type) {
|
||||
surface_t *sf;
|
||||
|
||||
night.msgframe = type;
|
||||
|
||||
sf = night.sp[SPNO_MSGBG]->curcg->sf;
|
||||
memset(sf->pixel, 0, sf->bytes_per_line * sf->height);
|
||||
memset(sf->alpha, 0, sf->width * sf->height);
|
||||
SDL_Surface *sf = night.sp[SPNO_MSGBG]->curcg->sf;
|
||||
SDL_FillRect(sf, NULL, 0);
|
||||
|
||||
switch(type) {
|
||||
case 0:
|
||||
nt_sp_set_show(night.sp[SPNO_MSGBG], FALSE);
|
||||
nt_sp_set_show(night.sp[SPNO_MSGFRAME_BG], FALSE);
|
||||
nt_sp_set_show(night.sp[SPNO_MSGFRAME_FG], FALSE);
|
||||
nt_sp_set_show(night.sp[SPNO_MSGBG], false);
|
||||
nt_sp_set_show(night.sp[SPNO_MSGFRAME_BG], false);
|
||||
nt_sp_set_show(night.sp[SPNO_MSGFRAME_FG], false);
|
||||
break;
|
||||
case 1:
|
||||
nt_sp_set_show(night.sp[SPNO_MSGBG], TRUE);
|
||||
nt_sp_set_show(night.sp[SPNO_MSGFRAME_BG], TRUE);
|
||||
nt_sp_set_show(night.sp[SPNO_MSGFRAME_FG], TRUE);
|
||||
nt_sp_set_show(night.sp[SPNO_MSGBG], true);
|
||||
nt_sp_set_show(night.sp[SPNO_MSGFRAME_BG], true);
|
||||
nt_sp_set_show(night.sp[SPNO_MSGFRAME_FG], true);
|
||||
|
||||
gr_fill(sf, MSGFRAME_0_X, MSGFRAME_0_Y,
|
||||
MSGFRAME_0_WIDTH, MSGFRAME_0_HEIGHT,
|
||||
16, 32, 64);
|
||||
gr_fill_alpha_map(sf, MSGFRAME_0_X, MSGFRAME_0_Y,
|
||||
MSGFRAME_0_WIDTH, MSGFRAME_0_HEIGHT, 192);
|
||||
SDL_FillRect(sf, &msgframe_0, SDL_MapRGBA(sf->format, 16, 32, 64, 192));
|
||||
ntmsg_clear(SPNO_MSGFRAME_FG);
|
||||
nt_sp_update_all(TRUE);
|
||||
nt_sp_update_all(true);
|
||||
break;
|
||||
case 2:
|
||||
nt_sp_set_show(night.sp[SPNO_MSGBG], TRUE);
|
||||
nt_sp_set_show(night.sp[SPNO_MSGFRAME_BG], FALSE);
|
||||
nt_sp_set_show(night.sp[SPNO_MSGFRAME_FG], TRUE);
|
||||
nt_sp_set_show(night.sp[SPNO_MSGBG], true);
|
||||
nt_sp_set_show(night.sp[SPNO_MSGFRAME_BG], false);
|
||||
nt_sp_set_show(night.sp[SPNO_MSGFRAME_FG], true);
|
||||
|
||||
gr_fill(sf, MSGFRAME_1_X, MSGFRAME_1_Y,
|
||||
MSGFRAME_1_WIDTH, MSGFRAME_1_HEIGHT,
|
||||
32, 32, 32);
|
||||
gr_fill_alpha_map(sf, MSGFRAME_1_X, MSGFRAME_1_Y,
|
||||
MSGFRAME_1_WIDTH, MSGFRAME_1_HEIGHT, 128);
|
||||
SDL_FillRect(sf, &msgframe_1, SDL_MapRGBA(sf->format, 32, 32, 32, 128));
|
||||
ntmsg_clear(SPNO_MSGFRAME_FG);
|
||||
nt_sp_update_all(TRUE);
|
||||
nt_sp_update_all(true);
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -177,20 +172,20 @@ void ntmsg_set_place(int type) {
|
||||
}
|
||||
|
||||
void ntmsg_newline() {
|
||||
BYTE buf[2] = {'\n', '\0'};
|
||||
uint8_t buf[2] = {'\n', '\0'};
|
||||
ntmsg_add(buf);
|
||||
}
|
||||
|
||||
void ntmsg_add(const char *msg) {
|
||||
int len;
|
||||
|
||||
SACT_DEBUG("len = %d\n", strlen(msg));
|
||||
SACT_DEBUG("len = %d", strlen(msg));
|
||||
|
||||
if (msg[0] == '\0') return;
|
||||
|
||||
len = MSGBUFMAX - (int)strlen(night.msgbuf);
|
||||
if (len < 0) {
|
||||
WARNING("buf shortage (%d)\n", len);
|
||||
WARNING("buf shortage (%d)", len);
|
||||
return;
|
||||
}
|
||||
strncat(night.msgbuf, msg, len);
|
||||
@@ -221,7 +216,7 @@ int ntmsg_ana(void) {
|
||||
static void ntmsg_out(int wNum, int wSize, int wColorR, int wColorG, int wColorB, int wFont, int wSpeed, int wLineSpace) {
|
||||
char *msg;
|
||||
sprite_t *sp;
|
||||
boolean needupdate = FALSE;
|
||||
bool needupdate = false;
|
||||
MyRectangle uparea = {0,0,0,0};
|
||||
int savex;
|
||||
|
||||
@@ -260,7 +255,7 @@ static void ntmsg_out(int wNum, int wSize, int wColorR, int wColorG, int wColorB
|
||||
mbuf,
|
||||
wColorR, wColorG, wColorB);
|
||||
|
||||
needupdate = TRUE;
|
||||
needupdate = true;
|
||||
|
||||
if (wSpeed > 0) {
|
||||
nt_sp_updateme_part(sp,
|
||||
@@ -269,7 +264,7 @@ static void ntmsg_out(int wNum, int wSize, int wColorR, int wColorG, int wColorB
|
||||
cw,
|
||||
wSize);
|
||||
nt_sp_update_clipped();
|
||||
needupdate = FALSE;
|
||||
needupdate = false;
|
||||
|
||||
// keywait
|
||||
delta = sdl_getTicks() - wcnt;
|
||||
@@ -304,7 +299,10 @@ static void ntmsg_out(int wNum, int wSize, int wColorR, int wColorG, int wColorB
|
||||
static int ntmsg_keywait() {
|
||||
int i = 0;
|
||||
|
||||
if (night.waitskiplv > 0) return 0;
|
||||
if (night.waitskiplv > 0) {
|
||||
sys_getInputInfo();
|
||||
return 0;
|
||||
}
|
||||
|
||||
// アニメパターンの初期化
|
||||
setup_hakanim();
|
||||
@@ -334,8 +332,8 @@ static void set_align(char *msg, sprite_t *sp, int wSize) {
|
||||
|
||||
switch(night.msgplace) {
|
||||
case 0:
|
||||
sp->u.msg.dspcur.x = MSGFRAME_0_X;
|
||||
sp->u.msg.dspcur.y = MSGFRAME_0_Y + 8;
|
||||
sp->u.msg.dspcur.x = msgframe_0.x;
|
||||
sp->u.msg.dspcur.y = msgframe_0.y + 8;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
@@ -361,21 +359,21 @@ static void set_align(char *msg, sprite_t *sp, int wSize) {
|
||||
sp->u.msg.dspcur.y = (sp->cursize.height - (line * (wSize+2))) /2;
|
||||
break;
|
||||
case 2:
|
||||
sp->u.msg.dspcur.x = MSGFRAME_2_X;
|
||||
sp->u.msg.dspcur.y = MSGFRAME_2_Y + 8;
|
||||
sp->u.msg.dspcur.x = msgframe_2.x;
|
||||
sp->u.msg.dspcur.y = msgframe_2.y + 8;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static BYTE *get_char(BYTE *msg, char *mbuf, int bufmax) {
|
||||
static uint8_t *get_char(uint8_t *msg, char *mbuf, int bufmax) {
|
||||
if (msg[0] == '\n') {
|
||||
mbuf[0] = '\n';
|
||||
mbuf[1] = '\0';
|
||||
return msg +1;
|
||||
}
|
||||
|
||||
BYTE *p = advance_char(msg, nact->encoding);
|
||||
uint8_t *p = advance_char(msg, nact->encoding);
|
||||
while (msg < p)
|
||||
*mbuf++ = *msg++;
|
||||
*mbuf = '\0';
|
||||
@@ -389,13 +387,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
|
||||
@@ -405,19 +401,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/メッセージスキップ/メッセージ枠消去の領域に
|
||||
// マウスが移動したら、その部分のアイコンを変化させる
|
||||
|
||||
|
||||
}
|
||||
|
||||
// メッセージ表示時に、キー入力を促すアニメーションの設定
|
||||
@@ -427,7 +419,7 @@ static void setup_hakanim() {
|
||||
// メッセージ表示時のキー入力を促すアニメーション
|
||||
static void hakanim(int i) {
|
||||
sprite_t *sp;
|
||||
boolean show;
|
||||
bool show;
|
||||
|
||||
sp = night.sp[SPNO_MSG_KEYANIM];
|
||||
if (sp == NULL) return;
|
||||
@@ -437,60 +429,43 @@ static void hakanim(int i) {
|
||||
} else {
|
||||
sp->curcg = sp->cg2;
|
||||
}
|
||||
sp->show = TRUE;
|
||||
sp->show = true;
|
||||
nt_sp_updateme(sp);
|
||||
nt_sp_update_clipped();
|
||||
|
||||
sp->show = show;
|
||||
}
|
||||
|
||||
int ntmsg_update(sprite_t *sp, MyRectangle *r) {
|
||||
int sx, sy, w, h, dx, dy;
|
||||
surface_t update;
|
||||
|
||||
// canvas が clean のときはなにもしない
|
||||
// -> 説明スプライトのように、SetShowされたときに対応できないからだめ
|
||||
//if (sact.msgbufempty) return OK;
|
||||
|
||||
update.width = r->w;
|
||||
update.height = r->h;
|
||||
|
||||
dx = sp->cur.x - r->x;
|
||||
dy = sp->cur.y - r->y;
|
||||
|
||||
w = sp->cursize.width;
|
||||
h = sp->cursize.height;
|
||||
|
||||
sx = 0; sy = 0;
|
||||
|
||||
if (!gr_clip(sp->u.msg.canvas, &sx, &sy, &w, &h, &update, &dx, &dy)) {
|
||||
return NG;
|
||||
void ntmsg_update(sprite_t *sp, MyRectangle *r) {
|
||||
SDL_Rect sp_rect = {0, 0, sp->cursize.width, sp->cursize.height};
|
||||
int sx = 0;
|
||||
int sy = 0;
|
||||
int dx = sp->cur.x;
|
||||
int dy = sp->cur.y;
|
||||
int w = sp->cursize.width;
|
||||
int h = sp->cursize.height;
|
||||
if (!ags_clipCopyRect(&sp_rect, r, &sx, &sy, &dx, &dy, &w, &h)) {
|
||||
return;
|
||||
}
|
||||
|
||||
dx += r->x;
|
||||
dy += r->y;
|
||||
|
||||
gre_BlendUseAMap(sf0, dx, dy, sf0, dx, dy, sp->u.msg.canvas, sx, sy, w, h, sp->u.msg.canvas, sx, sy, sp->blendrate);
|
||||
|
||||
SACT_DEBUG("do update no=%d, sx=%d, sy=%d, w=%d, h=%d, dx=%d, dy=%d\n",
|
||||
|
||||
SDL_SetSurfaceBlendMode(sp->u.msg.canvas, SDL_BLENDMODE_BLEND);
|
||||
SDL_SetSurfaceAlphaMod(sp->u.msg.canvas, sp->blendrate);
|
||||
SDL_BlitSurface(sp->u.msg.canvas, &(SDL_Rect){sx, sy, w, h}, main_surface, &(SDL_Rect){dx, dy, w, h});
|
||||
|
||||
SACT_DEBUG("do update no=%d, sx=%d, sy=%d, w=%d, h=%d, dx=%d, dy=%d",
|
||||
sp->no, sx, sy, w, h, dx, dy);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
static void ntmsg_clear(int wNum) {
|
||||
sprite_t *sp = night.sp[wNum];
|
||||
surface_t *sf;
|
||||
|
||||
|
||||
sp->u.msg.dspcur.x = 0;
|
||||
sp->u.msg.dspcur.y = 0;
|
||||
|
||||
night.msgbuf[0] = '\0';
|
||||
|
||||
// キャンバスのクリア
|
||||
sf = sp->u.msg.canvas;
|
||||
memset(sf->pixel, 0, sf->bytes_per_line * sf->height);
|
||||
memset(sf->alpha, 0, sf->width * sf->height);
|
||||
|
||||
|
||||
// Clear the canvas
|
||||
SDL_FillRect(sp->u.msg.canvas, NULL, 0);
|
||||
|
||||
nt_sp_updateme(sp);
|
||||
}
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
#ifndef __NT_MSG_H__
|
||||
#define __NT_MSG_H__
|
||||
|
||||
extern void ntmsg_init();
|
||||
extern void ntmsg_set_frame(int type);
|
||||
extern void ntmsg_set_place(int type);
|
||||
extern void ntmsg_newline();
|
||||
extern void ntmsg_add(const char *msg);
|
||||
extern int ntmsg_ana(void);
|
||||
extern int ntmsg_update(sprite_t *sp, MyRectangle *r);
|
||||
void ntmsg_init();
|
||||
void ntmsg_set_frame(int type);
|
||||
void ntmsg_set_place(int type);
|
||||
void ntmsg_newline();
|
||||
void ntmsg_add(const char *msg);
|
||||
int ntmsg_ana(void);
|
||||
void ntmsg_update(sprite_t *sp, MyRectangle *r);
|
||||
|
||||
#endif /* __NT_MSG_H__ */
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "system.h"
|
||||
#include "input.h"
|
||||
#include "sdl_core.h"
|
||||
#include "scheduler.h"
|
||||
#include "xsystem35.h"
|
||||
#include "nact.h"
|
||||
#include "scenario.h"
|
||||
@@ -30,7 +31,7 @@ static struct _scoadr scene2adr(int no) {
|
||||
struct _scoadr adr = {0, 0};
|
||||
|
||||
snprintf(label, 7, "E%05d", no);
|
||||
SACT_DEBUG("seaching %6s\n", label);
|
||||
SACT_DEBUG("seaching %6s", label);
|
||||
for (i = 0; i < nact->ain.fncnum; i++) {
|
||||
if (0 == strncmp(nact->ain.fnc[i].name, label, 6)) {
|
||||
adr.page = nact->ain.fnc[i].page;
|
||||
@@ -39,7 +40,7 @@ static struct _scoadr scene2adr(int no) {
|
||||
}
|
||||
}
|
||||
|
||||
WARNING("no scene %d\n", no);
|
||||
WARNING("no scene %d", no);
|
||||
return adr;
|
||||
}
|
||||
|
||||
@@ -52,8 +53,9 @@ static void ntmain(struct _scoadr inadr) {
|
||||
struct _scoadr curadr;
|
||||
|
||||
while (!nact->is_quit) {
|
||||
for (int cnt = 0; !nact->wait_vsync && cnt < 10000; cnt++) {
|
||||
//SACT_DEBUG("%d:%x\n", sl_getPage(), sl_getIndex());
|
||||
while (!nact->is_quit && !is_yield_requested()) {
|
||||
scheduler_on_command();
|
||||
//SACT_DEBUG("%d:%x", sl_getPage(), sl_getIndex());
|
||||
if (!nact->popupmenu_opened) {
|
||||
exec_command();
|
||||
if (sl_getPage() == inadr.page &&
|
||||
@@ -70,12 +72,8 @@ static void ntmain(struct _scoadr inadr) {
|
||||
}
|
||||
nact->callback();
|
||||
}
|
||||
if (!nact->is_message_locked) {
|
||||
sys_getInputInfo();
|
||||
}
|
||||
sdl_wait_vsync();
|
||||
nact->frame_count++;
|
||||
nact->wait_vsync = FALSE;
|
||||
sys_getInputInfo();
|
||||
scheduler_yield();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -109,9 +107,9 @@ void nt_sco_callevent(int ev) {
|
||||
}
|
||||
|
||||
|
||||
boolean nt_sco_is_natsu() {
|
||||
if (night.Month < 6 || night.Month > 9) return FALSE;
|
||||
if (night.Month == 6 && night.Day < 11) return FALSE;
|
||||
return TRUE;
|
||||
bool nt_sco_is_natsu() {
|
||||
if (night.Month < 6 || night.Month > 9) return false;
|
||||
if (night.Month == 6 && night.Day < 11) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
extern void nt_sco_init();
|
||||
extern int nt_sco_main(int mode);
|
||||
extern boolean nt_sco_is_natsu();
|
||||
extern bool nt_sco_is_natsu();
|
||||
extern void nt_sco_callevent(int ev);
|
||||
|
||||
#endif /* __NT_SCENARIO_H__ */
|
||||
|
||||
@@ -10,7 +10,7 @@ struct _ntsnd {
|
||||
int no;
|
||||
int vol;
|
||||
int loop;
|
||||
boolean waitend;
|
||||
bool waitend;
|
||||
};
|
||||
static struct _ntsnd ntsnd[10];
|
||||
|
||||
@@ -23,19 +23,18 @@ void nt_voice_set(int no) {
|
||||
}
|
||||
|
||||
void nt_cd_play(int no) {
|
||||
mus_cdrom_stop();
|
||||
mus_cdrom_start(no +1, 0);
|
||||
muscd_start(no + 1, 0);
|
||||
}
|
||||
|
||||
void nt_cd_stop(int msec) {
|
||||
mus_mixer_fadeout_start(MIX_CD, msec, 0, TRUE);
|
||||
mus_mixer_fadeout_start(MIX_CD, msec, 0, true);
|
||||
}
|
||||
|
||||
void nt_cd_mute(boolean mute) {
|
||||
void nt_cd_mute(bool mute) {
|
||||
if (mute) {
|
||||
mus_mixer_fadeout_start(MIX_CD, 0, 0, FALSE);
|
||||
mus_mixer_fadeout_start(MIX_CD, 0, 0, false);
|
||||
} else {
|
||||
mus_mixer_fadeout_start(MIX_CD, 0, 100, FALSE);
|
||||
mus_mixer_fadeout_start(MIX_CD, 0, 100, false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,7 +56,7 @@ void nt_snd_setvol(int ch, int vol) {
|
||||
ntsnd[ch -1].vol = vol;
|
||||
}
|
||||
|
||||
void nt_snd_waitend(int ch, boolean waitend) {
|
||||
void nt_snd_waitend(int ch, bool waitend) {
|
||||
if (ch < 1) return;
|
||||
|
||||
ntsnd[ch -1].waitend = waitend;
|
||||
@@ -75,13 +74,13 @@ void nt_snd_play(int ch) {
|
||||
void nt_snd_stop(int ch, int msec) {
|
||||
if (ch < 1) return;
|
||||
|
||||
mus_wav_fadeout_start(ch, msec, 0, TRUE);
|
||||
mus_wav_fadeout_start(ch, msec, 0, true);
|
||||
}
|
||||
|
||||
void nt_snd_stopall(int msec) {
|
||||
int i;
|
||||
|
||||
for (i = 1; i <= 10; i++) {
|
||||
mus_wav_fadeout_start(i, msec, 0, TRUE);
|
||||
mus_wav_fadeout_start(i, msec, 0, true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,11 +6,11 @@
|
||||
extern void nt_voice_set(int no);
|
||||
extern void nt_cd_play(int no);
|
||||
extern void nt_cd_stop(int msec);
|
||||
extern void nt_cd_mute(boolean mute);
|
||||
extern void nt_cd_mute(bool mute);
|
||||
extern void nt_snd_setwave(int ch, int no);
|
||||
extern void nt_snd_setloop(int ch, int num);
|
||||
extern void nt_snd_setvol(int ch, int vol);
|
||||
extern void nt_snd_waitend(int ch, boolean waitend);
|
||||
extern void nt_snd_waitend(int ch, bool waitend);
|
||||
extern void nt_snd_play(int ch);
|
||||
extern void nt_snd_stop(int ch, int msec);
|
||||
extern void nt_snd_stopall(int msec);
|
||||
|
||||
+24
-223
@@ -26,29 +26,25 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <SDL.h>
|
||||
|
||||
#include "portab.h"
|
||||
#include "nact.h"
|
||||
#include "system.h"
|
||||
#include "ags.h"
|
||||
#include "surface.h"
|
||||
#include "ngraph.h"
|
||||
#include "cg.h"
|
||||
#include "sactcg.h"
|
||||
|
||||
#define CGMAX 65536
|
||||
static cginfo_t *cgs[CGMAX];
|
||||
|
||||
#include "sactcg_stretch.c"
|
||||
#include "sactcg_blend.c"
|
||||
|
||||
|
||||
#define spcg_assert_no(no) \
|
||||
#define SPCG_ASSERT_NO(no) \
|
||||
if ((no) > (CGMAX -1)) { \
|
||||
WARNING("no is too large (should be %d < %d)\n", (no), CGMAX); \
|
||||
return NG; \
|
||||
WARNING("no is too large (should be %d < %d)", (no), CGMAX); \
|
||||
return; \
|
||||
} \
|
||||
|
||||
static cginfo_t *nt_scg_new(enum cgtype type, int no, surface_t *sf) {
|
||||
static cginfo_t *nt_scg_new(enum cgtype type, int no, SDL_Surface *sf) {
|
||||
cginfo_t *info = calloc(1, sizeof(cginfo_t));
|
||||
info->type = type;
|
||||
info->no = no;
|
||||
@@ -71,16 +67,16 @@ static cginfo_t *nt_scg_new(enum cgtype type, int no, surface_t *sf) {
|
||||
*/
|
||||
static cginfo_t *nt_scg_get(int no) {
|
||||
if (no >= (CGMAX -1)) {
|
||||
WARNING("no is too large (should be %d < %d)\n", (no), CGMAX);
|
||||
WARNING("no is too large (should be %d < %d)", (no), CGMAX);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (cgs[no] != NULL)
|
||||
return cgs[no];
|
||||
|
||||
surface_t *sf = sf_loadcg_no(no - 1);
|
||||
SDL_Surface *sf = cg_load_as_sdlsurface(no - 1);
|
||||
if (!sf) {
|
||||
WARNING("load fail (%d)\n", no -1);
|
||||
WARNING("load fail (%d)", no -1);
|
||||
return NULL;
|
||||
}
|
||||
return nt_scg_new(CG_LINKED, no, sf);
|
||||
@@ -98,248 +94,53 @@ void nt_scg_deref(cginfo_t *cg) {
|
||||
return;
|
||||
|
||||
if (cg->sf)
|
||||
sf_free(cg->sf);
|
||||
SDL_FreeSurface(cg->sf);
|
||||
free(cg);
|
||||
}
|
||||
|
||||
// 指定の大きさ、色の矩形の CG を作成
|
||||
int nt_scg_create(int wNumCG, int wWidth, int wHeight, int wR, int wG, int wB, int wBlendRate) {
|
||||
spcg_assert_no(wNumCG);
|
||||
void nt_scg_create(int wNumCG, int wWidth, int wHeight, int wR, int wG, int wB, int wBlendRate) {
|
||||
SPCG_ASSERT_NO(wNumCG);
|
||||
|
||||
surface_t *sf = sf_create_surface(wWidth, wHeight, sf0->depth);
|
||||
gr_fill(sf, 0, 0, wWidth, wHeight, wR, wG, wB);
|
||||
gr_fill_alpha_map(sf, 0, 0, wWidth, wHeight, wBlendRate);
|
||||
SDL_Surface *sf = SDL_CreateRGBSurfaceWithFormat(0, wWidth, wHeight, 32, SDL_PIXELFORMAT_ARGB8888);
|
||||
SDL_FillRect(sf, NULL, SDL_MapRGBA(sf->format, wR, wG, wB, wBlendRate));
|
||||
nt_scg_new(CG_SET, wNumCG, sf);
|
||||
return OK;
|
||||
}
|
||||
|
||||
// 指定のCGを反転させたCGを作成
|
||||
int nt_scg_create_reverse(int wNumCG, int wNumSrcCG, int wReverseX, int wReverseY) {
|
||||
spcg_assert_no(wNumCG);
|
||||
spcg_assert_no(wNumSrcCG);
|
||||
|
||||
cginfo_t *src = nt_scg_get(wNumSrcCG);
|
||||
if (!src)
|
||||
return NG;
|
||||
|
||||
surface_t *sf = stretch(src->sf, src->sf->width, src->sf->height, (wReverseX << 1) | wReverseY);
|
||||
nt_scg_new(CG_REVERSE, wNumCG, sf);
|
||||
return OK;
|
||||
}
|
||||
|
||||
// 指定のCGを拡大/縮小したCGを作成
|
||||
int nt_scg_create_stretch(int wNumCG, int wWidth, int wHeight, int wNumSrcCG) {
|
||||
spcg_assert_no(wNumCG);
|
||||
spcg_assert_no(wNumSrcCG);
|
||||
|
||||
cginfo_t *src = nt_scg_get(wNumSrcCG);
|
||||
if (!src)
|
||||
return NG;
|
||||
|
||||
surface_t *sf = stretch(src->sf, wWidth, wHeight, 0);
|
||||
nt_scg_new(CG_STRETCH, wNumCG, sf);
|
||||
return OK;
|
||||
}
|
||||
|
||||
// ベースCGの上にブレンドCGを重ねた CG を作成
|
||||
int nt_scg_create_blend(int wNumDstCG, int wNumBaseCG, int wX, int wY, int wNumBlendCG, int wAlphaMapMode) {
|
||||
spcg_assert_no(wNumDstCG);
|
||||
spcg_assert_no(wNumBaseCG);
|
||||
spcg_assert_no(wNumBlendCG);
|
||||
|
||||
cginfo_t *basecg = nt_scg_get(wNumBaseCG);
|
||||
cginfo_t *blendcg = nt_scg_get(wNumBlendCG);
|
||||
if (!basecg || !blendcg) return NG;
|
||||
|
||||
surface_t *sf = blend(basecg->sf, wX, wY, blendcg->sf, wAlphaMapMode);
|
||||
nt_scg_new(CG_SET, wNumDstCG, sf);
|
||||
return OK;
|
||||
}
|
||||
|
||||
// 指定の文字列のCGを作成
|
||||
int nt_scg_create_text(int wNumCG, int wSize, int wR, int wG, int wB, char *cText) {
|
||||
spcg_assert_no(wNumCG);
|
||||
|
||||
// 勝手に出ていいのかな?
|
||||
if (strlen(cText) == 0) return OK;
|
||||
|
||||
ags_setFont(FONT_GOTHIC, wSize);
|
||||
agsurface_t *glyph = ags_drawStringToSurface(cText);
|
||||
|
||||
surface_t *sf = sf_create_surface(glyph->width, wSize, nact->ags.dib->depth);
|
||||
gr_fill(sf, 0, 0, glyph->width, wSize, wR, wG, wB);
|
||||
gr_draw_amap(sf, 0, 0, glyph->pixel, glyph->width, wSize, glyph->bytes_per_line);
|
||||
|
||||
nt_scg_new(CG_SET, wNumCG, sf);
|
||||
return OK;
|
||||
}
|
||||
|
||||
// 数字文字列のCGを作成
|
||||
int nt_scg_create_textnum(int wNumCG, int wSize, int wR, int wG, int wB, int wFigs, int wZeroPadding, int wValue) {
|
||||
spcg_assert_no(wNumCG);
|
||||
|
||||
char s[256], ss[256];
|
||||
if (wZeroPadding) {
|
||||
char *sss = "%%0%dd";
|
||||
sprintf(ss, sss, wFigs);
|
||||
} else {
|
||||
char *sss = "%%%dd";
|
||||
sprintf(ss, sss, wFigs);
|
||||
}
|
||||
sprintf(s, ss, wValue);
|
||||
|
||||
ags_setFont(FONT_GOTHIC, wSize);
|
||||
agsurface_t *glyph = ags_drawStringToSurface(s);
|
||||
|
||||
surface_t *sf = sf_create_surface(glyph->width, wSize, nact->ags.dib->depth);
|
||||
gr_fill(sf, 0, 0, glyph->width, wSize, wR, wG, wB);
|
||||
gr_draw_amap(sf, 0, 0, glyph->pixel, glyph->width, wSize, glyph->bytes_per_line);
|
||||
|
||||
nt_scg_new(CG_SET, wNumCG, sf);
|
||||
return OK;
|
||||
}
|
||||
|
||||
// CGを複製
|
||||
int nt_scg_copy(int wNumDstCG, int wNumSrcCG) {
|
||||
spcg_assert_no(wNumDstCG);
|
||||
spcg_assert_no(wNumSrcCG);
|
||||
|
||||
cginfo_t *src = nt_scg_get(wNumSrcCG);
|
||||
if (!src)
|
||||
return NG;
|
||||
|
||||
nt_scg_new(CG_SET, wNumDstCG, sf_dup(src->sf));
|
||||
return OK;
|
||||
}
|
||||
|
||||
// CGの一部を切りぬいたCGを作成
|
||||
int nt_scg_cut(int wNumDstCG, int wNumSrcCG, int wX, int wY, int wWidth, int wHeight) {
|
||||
spcg_assert_no(wNumDstCG);
|
||||
spcg_assert_no(wNumSrcCG);
|
||||
void nt_scg_cut(int wNumDstCG, int wNumSrcCG, int wX, int wY, int wWidth, int wHeight) {
|
||||
SPCG_ASSERT_NO(wNumDstCG);
|
||||
SPCG_ASSERT_NO(wNumSrcCG);
|
||||
|
||||
cginfo_t *src = nt_scg_get(wNumSrcCG);
|
||||
if (!src)
|
||||
return NG;
|
||||
return;
|
||||
|
||||
surface_t *sf = src->sf->alpha
|
||||
? sf_create_surface(wWidth, wHeight, src->sf->depth)
|
||||
: sf_create_pixel(wWidth, wHeight, src->sf->depth);
|
||||
|
||||
if (src->sf->pixel)
|
||||
gr_copy(sf, 0, 0, src->sf, wX, wY, wWidth, wHeight);
|
||||
if (src->sf->alpha)
|
||||
gr_copy_alpha_map(sf, 0, 0, src->sf, wX, wY, wWidth, wHeight);
|
||||
SDL_Surface *sf = SDL_CreateRGBSurfaceWithFormat(0, wWidth, wHeight, src->sf->format->BitsPerPixel, src->sf->format->format);
|
||||
SDL_BlitSurface(src->sf, &(SDL_Rect){wX, wY, wWidth, wHeight}, sf, NULL);
|
||||
|
||||
nt_scg_new(CG_SET, wNumDstCG, sf);
|
||||
return OK;
|
||||
}
|
||||
|
||||
// 元のCGの一部を切りぬいたCGを作成
|
||||
int nt_scg_partcopy(int wNumDstCG, int wNumSrcCG, int wX, int wY, int wWidth, int wHeight) {
|
||||
spcg_assert_no(wNumDstCG);
|
||||
spcg_assert_no(wNumSrcCG);
|
||||
|
||||
cginfo_t *src = nt_scg_get(wNumSrcCG);
|
||||
if (!src)
|
||||
return NG;
|
||||
|
||||
surface_t *sf;
|
||||
if (src->sf->alpha) {
|
||||
sf = sf_create_surface(src->sf->width, src->sf->height, src->sf->depth);
|
||||
gr_fill_alpha_map(sf, 0, 0, src->sf->width, src->sf->height, 255);
|
||||
} else {
|
||||
sf = sf_create_pixel(src->sf->width, src->sf->height, src->sf->depth);
|
||||
}
|
||||
|
||||
if (src->sf->pixel)
|
||||
gr_copy(sf, wX, wY, src->sf, wX, wY, wWidth, wHeight);
|
||||
if (src->sf->alpha)
|
||||
gr_copy_alpha_map(sf, wX, wY, src->sf, wX, wY, wWidth, wHeight);
|
||||
|
||||
nt_scg_new(CG_SET, wNumDstCG, sf);
|
||||
return OK;
|
||||
}
|
||||
|
||||
// 全てのCGの開放
|
||||
int nt_scg_freeall() {
|
||||
void nt_scg_freeall(void) {
|
||||
int i;
|
||||
|
||||
for (i = 1; i < CGMAX; i++) {
|
||||
nt_scg_free(i);
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* 指定の番号の CG をオブジェクトリストから消し、オブジェクトがどこからも参照
|
||||
* されていない(参照数が0の)場合のみ、オブジェクトを削除
|
||||
*/
|
||||
int nt_scg_free(int no) {
|
||||
spcg_assert_no(no);
|
||||
void nt_scg_free(int no) {
|
||||
SPCG_ASSERT_NO(no);
|
||||
|
||||
cginfo_t *cg = cgs[no];
|
||||
if (!cg) return NG;
|
||||
if (!cg) return;
|
||||
|
||||
nt_scg_deref(cg);
|
||||
cgs[no] = NULL;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
// CGの種類を取得
|
||||
int nt_scg_querytype(int wNumCG, int *ret) {
|
||||
if (wNumCG >= (CGMAX -1)) goto errexit;
|
||||
if (cgs[wNumCG] == NULL) goto errexit;
|
||||
|
||||
*ret = cgs[wNumCG]->type;
|
||||
|
||||
return OK;
|
||||
|
||||
errexit:
|
||||
*ret = CG_NOTUSED;
|
||||
return NG;
|
||||
}
|
||||
|
||||
// CGの大きさを取得
|
||||
int nt_scg_querysize(int wNumCG, int *w, int *h) {
|
||||
if (wNumCG >= (CGMAX -1)) goto errexit;
|
||||
if (cgs[wNumCG] == NULL) goto errexit;
|
||||
if (cgs[wNumCG]->sf == NULL) goto errexit;
|
||||
|
||||
*w = cgs[wNumCG]->sf->width;
|
||||
*h = cgs[wNumCG]->sf->height;
|
||||
|
||||
return OK;
|
||||
|
||||
errexit:
|
||||
*w = *h = 0;
|
||||
return NG;
|
||||
}
|
||||
|
||||
// CGのBPPを取得
|
||||
int nt_scg_querybpp(int wNumCG, int *ret) {
|
||||
if (wNumCG >= (CGMAX -1)) goto errexit;
|
||||
if (cgs[wNumCG] == NULL) goto errexit;
|
||||
if (cgs[wNumCG]->sf == NULL) goto errexit;
|
||||
|
||||
*ret = cgs[wNumCG]->sf->depth;
|
||||
|
||||
return OK;
|
||||
|
||||
errexit:
|
||||
*ret = 0;
|
||||
return NG;
|
||||
}
|
||||
|
||||
// CGの alphamap が存在するかを取得
|
||||
int nt_scg_existalphamap(int wNumCG, int *ret) {
|
||||
if (wNumCG >= (CGMAX -1)) goto errexit;
|
||||
if (cgs[wNumCG] == NULL) goto errexit;
|
||||
if (cgs[wNumCG]->sf == NULL) goto errexit;
|
||||
|
||||
*ret = cgs[wNumCG]->sf->alpha ? 1 : 0;
|
||||
|
||||
errexit:
|
||||
*ret = 0;
|
||||
return NG;
|
||||
}
|
||||
|
||||
@@ -27,23 +27,11 @@
|
||||
#include "portab.h"
|
||||
#include "night.h"
|
||||
|
||||
extern cginfo_t *nt_scg_addref(int no);
|
||||
extern void nt_scg_deref(cginfo_t *cg);
|
||||
extern int nt_scg_create(int wNumCG, int wWidth, int wHeight, int wR, int wG, int wB, int wBlendRate);
|
||||
extern int nt_scg_create_reverse(int NumCG, int wNumSrcCG, int wReverseX, int wReverseY);
|
||||
extern int nt_scg_create_stretch(int wNumCG, int wWidth, int wHeight, int wNumSrcCG);
|
||||
extern int nt_scg_create_blend(int wNumDstCG, int wNumBaseCG, int wX, int wY, int wNumBlendCG, int wAlphaMapMode);
|
||||
extern int nt_scg_create_text(int wNumCG, int wSize, int wR, int wG, int wB, char *cText);
|
||||
extern int nt_scg_create_textnum(int wNumCG, int wSize, int wR, int wG, int wB, int wFigs, int wZeroPadding, int wValue);
|
||||
extern int nt_scg_copy(int wNumDstCG, int wNumSrcCG);
|
||||
extern int nt_scg_cut(int wNumDstCG, int wNumSrcCG, int wX, int wY, int wWidth, int wHeight);
|
||||
extern int nt_scg_partcopy(int wNumDstCG, int wNumSrcCG, int wX, int wY, int wWidth, int wHeight);
|
||||
extern int nt_scg_freeall();
|
||||
extern int nt_scg_free(int cg);
|
||||
extern int nt_scg_querytype(int wNumCG, int *ret);
|
||||
extern int nt_scg_querysize(int wNumCG, int *w, int *h);
|
||||
extern int nt_scg_querybpp(int wNumCG, int *ret);
|
||||
extern int nt_scg_existalphamap(int wNumCG, int *ret);
|
||||
extern int nt_scg_linkcgfree(int no);
|
||||
cginfo_t *nt_scg_addref(int no);
|
||||
void nt_scg_deref(cginfo_t *cg);
|
||||
void nt_scg_create(int wNumCG, int wWidth, int wHeight, int wR, int wG, int wB, int wBlendRate);
|
||||
void nt_scg_cut(int wNumDstCG, int wNumSrcCG, int wX, int wY, int wWidth, int wHeight);
|
||||
void nt_scg_freeall(void);
|
||||
void nt_scg_free(int cg);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
//
|
||||
static surface_t *blend(surface_t *base, int x, int y, surface_t *blend, int mode) {
|
||||
surface_t *dst = sf_create_surface(base->width, base->height, base->depth);
|
||||
|
||||
gr_copy(dst, 0, 0, base, 0, 0, base->width, base->height);
|
||||
|
||||
if (base->alpha) {
|
||||
// ベースに alpha map がある場合はそれをコピー
|
||||
gr_copy_alpha_map(dst, 0, 0, base, 0, 0, base->width, base->height);
|
||||
} else {
|
||||
// 無い場合は全て 255 の map を作成
|
||||
gr_fill_alpha_map(dst, 0, 0, base->width, base->height, 255);
|
||||
}
|
||||
|
||||
if (blend->alpha) {
|
||||
// 重ね合わせ先の alpha map があるときはそれを使う
|
||||
gre_BlendUseAMap(dst, x, y, base, x, y, blend, 0, 0, blend->width, blend->height, blend, 0, 0, 255);
|
||||
} else {
|
||||
// 無いときは dst の alpha map を使う
|
||||
gre_BlendUseAMap(dst, x, y, base, x, y, blend, 0, 0, blend->width, blend->height, dst, x, y, 255);
|
||||
}
|
||||
|
||||
// alpha 作成モードが dst + blend の時は飽和加算
|
||||
if (mode == 1) {
|
||||
gr_saturadd_alpha_map(dst, x, y, blend, 0, 0, blend->width, blend->height);
|
||||
}
|
||||
|
||||
return dst;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,114 +0,0 @@
|
||||
// 拡大縮小
|
||||
static surface_t *stretch(surface_t *src, int dw, int dh, int mirror) {
|
||||
surface_t *dst = calloc(1, sizeof(surface_t));
|
||||
float a1, a2, xd, yd;
|
||||
int sw, sh;
|
||||
int *row, *col;
|
||||
int x, y;
|
||||
BYTE *sdata, *ddata;
|
||||
|
||||
dst->width = dw;
|
||||
dst->height = dh;
|
||||
dst->depth = src->depth;
|
||||
dst->bytes_per_line = dw * src->bytes_per_pixel;
|
||||
dst->bytes_per_pixel = src->bytes_per_pixel;
|
||||
|
||||
if (src->pixel) {
|
||||
dst->pixel = malloc(dh * dst->bytes_per_line);
|
||||
}
|
||||
if (src->alpha) {
|
||||
dst->alpha = malloc(dw * dh);
|
||||
}
|
||||
|
||||
|
||||
sdata = GETOFFSET_PIXEL(src, 0, 0);
|
||||
ddata = GETOFFSET_PIXEL(dst, 0, 0);
|
||||
sw = src->width;
|
||||
sh = src->height;
|
||||
|
||||
a1 = (float)sw / (float)dw;
|
||||
a2 = (float)sh / (float)dh;
|
||||
row = malloc(sizeof(int) * dw);
|
||||
// 1おおきくして初期化しないと col[dw-1]とcol[dw]が同じになる
|
||||
// 可能性がある。
|
||||
col = calloc(dh +1, sizeof(int));
|
||||
|
||||
if (mirror & 1) {
|
||||
/* 上下反転 added by tajiri@wizard */
|
||||
for (yd = sh - a2, y = 0; y < dh; y++) {
|
||||
col[y] = yd; yd -= a2;
|
||||
}
|
||||
} else {
|
||||
for (yd = 0.0, y = 0; y < dh; y++) {
|
||||
col[y] = yd; yd += a2;
|
||||
}
|
||||
}
|
||||
if (mirror & 2) {
|
||||
/* 左右反転 added by tajiri@wizard */
|
||||
for (xd = sw - a1, x = 0; x < dw; x++) {
|
||||
row[x] = xd; xd -= a1;
|
||||
}
|
||||
} else {
|
||||
for (xd = 0.0, x = 0; x < dw; x++) {
|
||||
row[x] = xd; xd += a1;
|
||||
}
|
||||
}
|
||||
|
||||
#define SCALEDCOPYAREA(type) { \
|
||||
int x, y; \
|
||||
type *sl, *dl; \
|
||||
BYTE *_sl, *_dl; \
|
||||
for (y = 0; y < dh; y++) { \
|
||||
sl = (type *)(sdata + *(y + col) * src->bytes_per_line);\
|
||||
dl = (type *)(ddata + y * dst->bytes_per_line);\
|
||||
for (x = 0; x < dw; x++) { \
|
||||
*(dl + x) = *(sl + *(row + x)); \
|
||||
} \
|
||||
_dl = (BYTE *)dl; \
|
||||
while(*(col + y) == *(col + y + 1)) { \
|
||||
_sl = _dl; \
|
||||
_dl += dst->bytes_per_line; \
|
||||
memcpy(_dl, _sl, dw * sizeof(type)); \
|
||||
y++; \
|
||||
} \
|
||||
}}
|
||||
|
||||
switch(dst->depth) {
|
||||
case 8:
|
||||
SCALEDCOPYAREA(BYTE); break;
|
||||
case 16:
|
||||
SCALEDCOPYAREA(WORD); break;
|
||||
case 24:
|
||||
case 32:
|
||||
SCALEDCOPYAREA(DWORD); break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (src->alpha) {
|
||||
int x, y;
|
||||
BYTE *sl, *dl;
|
||||
BYTE *_sl, *_dl;
|
||||
sdata = GETOFFSET_ALPHA(src, 0, 0);
|
||||
ddata = GETOFFSET_ALPHA(dst, 0, 0);
|
||||
for (y = 0; y < dh; y++) {
|
||||
sl = (BYTE *)(sdata + *(y + col) * src->width);
|
||||
dl = (BYTE *)(ddata + y * dst->width);
|
||||
for (x = 0; x < dw; x++) {
|
||||
*(dl + x) = *(sl + *(row + x));
|
||||
}
|
||||
_dl = (BYTE *)dl;
|
||||
while(*(col + y) == *(col + y + 1)) {
|
||||
_sl = _dl;
|
||||
_dl += dst->width;
|
||||
memcpy(_dl, _sl, dw);
|
||||
y++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
free(row);
|
||||
free(col);
|
||||
|
||||
return dst;
|
||||
}
|
||||
@@ -51,39 +51,27 @@ static char *replacedst;
|
||||
/**
|
||||
* 文字列変数スタックの初期化
|
||||
*/
|
||||
int nt_sstr_init() {
|
||||
void nt_sstr_init(void) {
|
||||
stack = malloc(sizeof(char *) * DEFSTACKSIZE);
|
||||
idx = 0;
|
||||
idxmax = DEFSTACKSIZE;
|
||||
return OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* 文字列変数スタックに文字列を積む
|
||||
* @param strno: シナリオ上での文字列変数番号
|
||||
*/
|
||||
int nt_sstr_push(char *str) {
|
||||
if (idx >= idxmax) {
|
||||
stack = realloc(stack, sizeof(char *) * idx*2);
|
||||
idxmax = idx*2;
|
||||
void nt_sstr_reset(void) {
|
||||
for (int i = 0; i < idx; i++)
|
||||
free(stack[i]);
|
||||
idx = 0;
|
||||
free(stack);
|
||||
stack = NULL;
|
||||
|
||||
for (SList *l = strreplace; l; l = l->next) {
|
||||
strexchange_t *ex = l->data;
|
||||
free(ex->src);
|
||||
free(ex->dst);
|
||||
free(ex);
|
||||
}
|
||||
|
||||
stack[idx++] = strdup(str);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* 文字列変数スタックから文字列を取り出す
|
||||
* @param strno: スタックから戻した文字列を格納する文字列変数番号
|
||||
*/
|
||||
int nt_sstr_pop(char *str, int maxlen) {
|
||||
if (idx == 0) return NG;
|
||||
|
||||
strncpy(str, stack[--idx], maxlen);
|
||||
free(stack[idx]);
|
||||
|
||||
return OK;
|
||||
slist_free(strreplace);
|
||||
strreplace = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -91,36 +79,15 @@ int nt_sstr_pop(char *str, int maxlen) {
|
||||
* @param sstrno: 変換元文字列変数番号
|
||||
* @param dstrno: 変換先文字列変数番号
|
||||
*/
|
||||
int nt_sstr_regist_replace(char *sstr, char *dstr) {
|
||||
void nt_sstr_regist_replace(char *sstr, char *dstr) {
|
||||
strexchange_t *ex;
|
||||
|
||||
if (sstr == dstr) return NG;
|
||||
if (sstr == dstr) return;
|
||||
|
||||
ex = malloc(sizeof(strexchange_t));
|
||||
ex->src = sstr;
|
||||
ex->dst = dstr;
|
||||
strreplace = slist_append(strreplace, ex);
|
||||
return OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* 数値 -> 文字列化
|
||||
*/
|
||||
int nt_sstr_num2str(int strno, int fig, int nzeropad, int num) {
|
||||
char s[256], ss[256];
|
||||
|
||||
if (nzeropad) {
|
||||
char *sss = "%%0%dd";
|
||||
sprintf(ss, sss, fig);
|
||||
} else {
|
||||
char *sss = "%%%dd";
|
||||
sprintf(ss, sss, fig);
|
||||
}
|
||||
|
||||
sprintf(s, ss, num);
|
||||
svar_set(strno, s);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
// 文字列の置き換え処理
|
||||
@@ -133,7 +100,7 @@ static void replacestr_cb(void* data, void* userdata) {
|
||||
start = replacesrc;
|
||||
out = replacedst;
|
||||
|
||||
while (TRUE) {
|
||||
while (true) {
|
||||
next = strstr(start, ex->src);
|
||||
if (next == NULL) break;
|
||||
strncat(out, start, (size_t)(next - start));
|
||||
|
||||
@@ -24,12 +24,10 @@
|
||||
#ifndef __SACTSTRING_H__
|
||||
#define __SACTSTRING_H__
|
||||
|
||||
extern int nt_sstr_init();
|
||||
extern int nt_sstr_push(char *str);
|
||||
extern int nt_sstr_pop(char *str, int maxlen);
|
||||
extern int nt_sstr_regist_replace(char *sstr, char *dstr);
|
||||
extern int nt_sstr_num2str(int strno, int fig, int nzeropad, int num);
|
||||
extern char *nt_sstr_replacestr(char *msg);
|
||||
void nt_sstr_init(void);
|
||||
void nt_sstr_reset(void);
|
||||
void nt_sstr_regist_replace(char *sstr, char *dstr);
|
||||
char *nt_sstr_replacestr(char *msg);
|
||||
|
||||
|
||||
#endif /* __SACTSTRING_H__ */
|
||||
|
||||
+11
-12
@@ -1,12 +1,11 @@
|
||||
#include "config.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <SDL.h>
|
||||
|
||||
#include "portab.h"
|
||||
#include "sprite.h"
|
||||
#include "sactcg.h"
|
||||
#include "surface.h"
|
||||
#include "ngraph.h"
|
||||
#include "nt_msg.h"
|
||||
|
||||
sprite_t *nt_sp_new(int no, int cg1, int cg2, int cg3, int type) {
|
||||
@@ -22,7 +21,7 @@ sprite_t *nt_sp_new(int no, int cg1, int cg2, int cg3, int type) {
|
||||
sp->cg3 = cg3 ? nt_scg_addref(cg3) : NULL;
|
||||
|
||||
sp->curcg = sp->cg1;
|
||||
sp->show = TRUE;
|
||||
sp->show = true;
|
||||
sp->blendrate = 255;
|
||||
sp->loc.x = 0;
|
||||
sp->loc.y = 0;
|
||||
@@ -32,8 +31,8 @@ sprite_t *nt_sp_new(int no, int cg1, int cg2, int cg3, int type) {
|
||||
sp->cursize.width = 0;
|
||||
sp->cursize.height = 0;
|
||||
} else {
|
||||
sp->cursize.width = sp->curcg->sf->width;
|
||||
sp->cursize.height = sp->curcg->sf->height;
|
||||
sp->cursize.width = sp->curcg->sf->w;
|
||||
sp->cursize.height = sp->curcg->sf->h;
|
||||
}
|
||||
sp->update = DEFAULT_UPDATE;
|
||||
|
||||
@@ -54,7 +53,7 @@ sprite_t *nt_sp_msg_new(int no, int x, int y, int width, int height) {
|
||||
|
||||
sp->no = no;
|
||||
sp->type = SPRITE_MSG;
|
||||
sp->show = TRUE;
|
||||
sp->show = true;
|
||||
sp->blendrate = 255;
|
||||
sp->loc.x = x;
|
||||
sp->loc.y = y;
|
||||
@@ -63,7 +62,7 @@ sprite_t *nt_sp_msg_new(int no, int x, int y, int width, int height) {
|
||||
sp->cursize.height = height;
|
||||
sp->u.msg.dspcur.x = 0;
|
||||
sp->u.msg.dspcur.y = 0;
|
||||
sp->u.msg.canvas = sf_create_surface(width, height, sf0->depth);
|
||||
sp->u.msg.canvas = SDL_CreateRGBSurfaceWithFormat(0, width, height, 32, SDL_PIXELFORMAT_ARGB8888);
|
||||
sp->update = ntmsg_update;
|
||||
|
||||
return sp;
|
||||
@@ -77,14 +76,14 @@ void nt_sp_free(sprite_t *sp) {
|
||||
if (sp->cg3) nt_scg_deref(sp->cg3);
|
||||
|
||||
if (sp->type == SPRITE_MSG) {
|
||||
sf_free(sp->u.msg.canvas);
|
||||
SDL_FreeSurface(sp->u.msg.canvas);
|
||||
}
|
||||
|
||||
free(sp);
|
||||
}
|
||||
|
||||
void nt_sp_set_show(sprite_t *sp, boolean show) {
|
||||
boolean oldshow;
|
||||
void nt_sp_set_show(sprite_t *sp, bool show) {
|
||||
bool oldshow;
|
||||
|
||||
if (sp == NULL) return;
|
||||
|
||||
@@ -111,8 +110,8 @@ void nt_sp_set_cg(sprite_t *sp, int no) {
|
||||
sp->cursize.width = 0;
|
||||
sp->cursize.height = 0;
|
||||
} else {
|
||||
sp->cursize.width = cg->sf->width;
|
||||
sp->cursize.height = cg->sf->height;
|
||||
sp->cursize.width = cg->sf->w;
|
||||
sp->cursize.height = cg->sf->h;
|
||||
}
|
||||
|
||||
sp->curcg = cg;
|
||||
|
||||
+21
-23
@@ -3,7 +3,6 @@
|
||||
#define __SPRITE_H__
|
||||
|
||||
#include "portab.h"
|
||||
#include "surface.h"
|
||||
#include "graphics.h"
|
||||
|
||||
#define DEFAULT_UPDATE nt_sp_draw
|
||||
@@ -54,7 +53,7 @@ enum cgtype {
|
||||
struct _cginfo {
|
||||
enum cgtype type; // CGの種類, 0: 未使用, 1:リンクされている, ...
|
||||
int no; // CGの番号
|
||||
surface_t *sf; // CG本体
|
||||
struct SDL_Surface *sf;
|
||||
int refcnt; // 参照カウンタ。0になったら開放してもよい。
|
||||
};
|
||||
typedef struct _cginfo cginfo_t;
|
||||
@@ -78,7 +77,7 @@ struct _sprite {
|
||||
cginfo_t *curcg;
|
||||
cginfo_t *cg1, *cg2, *cg3;
|
||||
|
||||
boolean show;
|
||||
bool show;
|
||||
|
||||
int blendrate;
|
||||
|
||||
@@ -86,7 +85,7 @@ struct _sprite {
|
||||
|
||||
MyPoint cur;
|
||||
|
||||
int (* update)(struct _sprite *sp, MyRectangle *updatearea);
|
||||
void (* update)(struct _sprite *sp, MyRectangle *updatearea);
|
||||
|
||||
union {
|
||||
struct {
|
||||
@@ -97,7 +96,7 @@ struct _sprite {
|
||||
} anime;
|
||||
|
||||
struct {
|
||||
surface_t *canvas;
|
||||
struct SDL_Surface *canvas;
|
||||
MyPoint dspcur;
|
||||
} msg;
|
||||
} u;
|
||||
@@ -107,30 +106,29 @@ typedef struct _sprite sprite_t;
|
||||
|
||||
|
||||
/* in nt_sprite.c */
|
||||
extern sprite_t *nt_sp_new(int no, int cg1, int cg2, int cg3, int type);
|
||||
extern sprite_t *nt_sp_msg_new(int no, int x, int y, int width, int height);
|
||||
extern void nt_sp_free(sprite_t *sp);
|
||||
extern void nt_sp_set_show(sprite_t *sp, boolean show);
|
||||
// extern void nt_sp_set_cg(sprite_t *sp, int no);
|
||||
extern void nt_sp_set_loc(sprite_t *sp, int x, int y);
|
||||
sprite_t *nt_sp_new(int no, int cg1, int cg2, int cg3, int type);
|
||||
sprite_t *nt_sp_msg_new(int no, int x, int y, int width, int height);
|
||||
void nt_sp_free(sprite_t *sp);
|
||||
void nt_sp_set_show(sprite_t *sp, bool show);
|
||||
// void nt_sp_set_cg(sprite_t *sp, int no);
|
||||
void nt_sp_set_loc(sprite_t *sp, int x, int y);
|
||||
|
||||
/* in nt_sprite_update.c */
|
||||
extern int nt_sp_update_clipped();
|
||||
extern int nt_sp_update_all(boolean syncscreen);
|
||||
extern int nt_sp_updateme(sprite_t *sp);
|
||||
extern int nt_sp_updateme_part(sprite_t *sp, int x, int y, int w, int h);
|
||||
extern void nt_sp_add_updatelist(sprite_t *sp);
|
||||
extern void nt_sp_remove_updatelist(sprite_t *sp);
|
||||
extern int nt_sp_draw_wall(sprite_t *sp, MyRectangle *r);
|
||||
void nt_sp_update_clipped();
|
||||
void nt_sp_update_all(bool syncscreen);
|
||||
void nt_sp_updateme(sprite_t *sp);
|
||||
void nt_sp_updateme_part(sprite_t *sp, int x, int y, int w, int h);
|
||||
void nt_sp_add_updatelist(sprite_t *sp);
|
||||
void nt_sp_remove_updatelist(sprite_t *sp);
|
||||
void nt_sp_draw_wall(sprite_t *sp, MyRectangle *r);
|
||||
void nt_sp_clear_updatelist(void);
|
||||
|
||||
/* in nt_sprite_draw.c */
|
||||
extern int nt_sp_draw(sprite_t *sp, MyRectangle *r);
|
||||
extern int nt_sp_draw2(sprite_t *sp, cginfo_t *cg, MyRectangle *r);
|
||||
extern void nt_sp_draw_dmap(void* data, void* userdata);
|
||||
extern int nt_sp_draw_scg(sprite_t *sp, MyRectangle *r);
|
||||
void nt_sp_draw(sprite_t *sp, MyRectangle *r);
|
||||
void nt_sp_draw_scg(sprite_t *sp, MyRectangle *r);
|
||||
|
||||
/* in nt_sprite_eupdate.c */
|
||||
extern int nt_sp_eupdate(int type, int time, int cancel);
|
||||
void nt_sp_eupdate(int type, int time, int cancel);
|
||||
|
||||
|
||||
#endif /* __SPRITE_H__ */
|
||||
|
||||
@@ -24,13 +24,12 @@
|
||||
#include "config.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <SDL.h>
|
||||
|
||||
#include "portab.h"
|
||||
#include "system.h"
|
||||
#include "ags.h"
|
||||
#include "graphics.h"
|
||||
#include "surface.h"
|
||||
#include "ngraph.h"
|
||||
#include "sprite.h"
|
||||
|
||||
/*
|
||||
@@ -38,106 +37,60 @@
|
||||
@param sp: 描画するスプライト
|
||||
@param r : 再描画する領域
|
||||
*/
|
||||
int nt_sp_draw(sprite_t *sp, MyRectangle *r) {
|
||||
if (sp == NULL) return NG;
|
||||
|
||||
return nt_sp_draw2(sp, sp->curcg, r);
|
||||
}
|
||||
|
||||
/*
|
||||
指定の spriteの指定のCGを surface0 に書く
|
||||
(このインターフェイスはもう不要?)
|
||||
|
||||
@param sp: 描画するスプライト
|
||||
@param cg: 描画するCG
|
||||
@param r : 再描画する領域
|
||||
*/
|
||||
int nt_sp_draw2(sprite_t *sp, cginfo_t *cg, MyRectangle *r) {
|
||||
surface_t update;
|
||||
int sx, sy, w, h, dx, dy;
|
||||
|
||||
if (cg == NULL) return NG;
|
||||
if (cg->sf == NULL) return NG;
|
||||
void nt_sp_draw(sprite_t *sp, MyRectangle *r) {
|
||||
if (sp == NULL) return;
|
||||
cginfo_t *cg = sp->curcg;
|
||||
if (cg == NULL) return;
|
||||
if (cg->sf == NULL) return;
|
||||
|
||||
// 更新領域の確定
|
||||
update.width = r->w;
|
||||
update.height = r->h;
|
||||
sx = 0;
|
||||
sy = 0;
|
||||
dx = sp->cur.x - r->x;
|
||||
dy = sp->cur.y - r->y;
|
||||
w = cg->sf->width;
|
||||
h = cg->sf->height;
|
||||
SDL_Rect cg_rect = {0, 0, cg->sf->w, cg->sf->h};
|
||||
int sx = 0;
|
||||
int sy = 0;
|
||||
int dx = sp->cur.x;
|
||||
int dy = sp->cur.y;
|
||||
int w = cg->sf->w;
|
||||
int h = cg->sf->h;
|
||||
|
||||
if (!gr_clip(cg->sf, &sx, &sy, &w, &h, &update, &dx, &dy)) {
|
||||
return NG;
|
||||
if (!ags_clipCopyRect(&cg_rect, r, &sx, &sy, &dx, &dy, &w, &h)) {
|
||||
return;
|
||||
}
|
||||
|
||||
dx += r->x;
|
||||
dy += r->y;
|
||||
|
||||
if (cg->sf->alpha) {
|
||||
// alpha map がある場合
|
||||
gre_BlendUseAMap(sf0, dx, dy,
|
||||
sf0, dx, dy,
|
||||
cg->sf, sx, sy, w, h,
|
||||
cg->sf, sx, sy,
|
||||
sp->blendrate);
|
||||
|
||||
if (SDL_ISPIXELFORMAT_ALPHA(cg->sf->format->format) || sp->blendrate < 255) {
|
||||
SDL_SetSurfaceBlendMode(cg->sf, SDL_BLENDMODE_BLEND);
|
||||
SDL_SetSurfaceAlphaMod(cg->sf, sp->blendrate);
|
||||
} else {
|
||||
if (sp->blendrate == 255) {
|
||||
// alpha値指定が無い場合
|
||||
gr_copy(sf0, dx, dy, cg->sf, sx, sy, w, h);
|
||||
} else if (sp->blendrate > 0) {
|
||||
// alpha値指定がある場合
|
||||
gre_Blend(sf0, dx, dy,
|
||||
sf0, dx, dy,
|
||||
cg->sf, sx, sy, w, h,
|
||||
sp->blendrate);
|
||||
}
|
||||
SDL_SetSurfaceBlendMode(cg->sf, SDL_BLENDMODE_NONE);
|
||||
}
|
||||
SDL_BlitSurface(cg->sf, &(SDL_Rect){sx, sy, w, h}, main_surface, &(SDL_Rect){dx, dy, w, h});
|
||||
|
||||
SACT_DEBUG("do update no=%d, sx=%d, sy=%d, w=%d, h=%d, dx=%d, dy=%d\n",
|
||||
SACT_DEBUG("do update no=%d, sx=%d, sy=%d, w=%d, h=%d, dx=%d, dy=%d",
|
||||
sp->no, sx, sy, w, h, dx, dy);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
// BlendScreenによる描画
|
||||
int nt_sp_draw_scg(sprite_t *sp, MyRectangle *r) {
|
||||
surface_t update;
|
||||
cginfo_t *cg;
|
||||
int sx, sy, w, h, dx, dy;
|
||||
|
||||
if (sp == NULL) return NG;
|
||||
|
||||
cg = sp->curcg;
|
||||
|
||||
if (cg == NULL) return NG;
|
||||
if (cg->sf == NULL) return NG;
|
||||
void nt_sp_draw_scg(sprite_t *sp, MyRectangle *r) {
|
||||
if (sp == NULL) return;
|
||||
cginfo_t *cg = sp->curcg;
|
||||
if (cg == NULL) return;
|
||||
if (cg->sf == NULL) return;
|
||||
|
||||
// 更新領域の確定
|
||||
update.width = r->w;
|
||||
update.height = r->h;
|
||||
sx = 0;
|
||||
sy = 0;
|
||||
dx = sp->cur.x - r->x;
|
||||
dy = sp->cur.y - r->y;
|
||||
w = cg->sf->width;
|
||||
h = cg->sf->height;
|
||||
SDL_Rect cg_rect = {0, 0, cg->sf->w, cg->sf->h};
|
||||
int sx = 0;
|
||||
int sy = 0;
|
||||
int dx = sp->cur.x;
|
||||
int dy = sp->cur.y;
|
||||
int w = cg->sf->w;
|
||||
int h = cg->sf->h;
|
||||
|
||||
if (!gr_clip(cg->sf, &sx, &sy, &w, &h, &update, &dx, &dy)) {
|
||||
return NG;
|
||||
if (!ags_clipCopyRect(&cg_rect, r, &sx, &sy, &dx, &dy, &w, &h)) {
|
||||
return;
|
||||
}
|
||||
|
||||
dx += r->x;
|
||||
dy += r->y;
|
||||
|
||||
gre_BlendScreen(sf0, dx, dy,
|
||||
sf0, dx, dy,
|
||||
cg->sf, sx, sy, w, h);
|
||||
SDL_SetSurfaceBlendMode(cg->sf, SDL_BLENDMODE_ADD);
|
||||
SDL_BlitSurface(cg->sf, &(SDL_Rect){sx, sy, w, h}, main_surface, &(SDL_Rect){dx, dy, w, h});
|
||||
|
||||
SACT_DEBUG("do update no=%d, sx=%d, sy=%d, w=%d, h=%d, dx=%d, dy=%d\n",
|
||||
SACT_DEBUG("do update no=%d, sx=%d, sy=%d, w=%d, h=%d, dx=%d, dy=%d",
|
||||
sp->no, sx, sy, w, h, dx, dy);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
@@ -23,423 +23,46 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "portab.h"
|
||||
#include "system.h"
|
||||
#include "ngraph.h"
|
||||
#include "ags.h"
|
||||
#include "nact.h"
|
||||
#include "input.h"
|
||||
#include "sprite.h"
|
||||
#include "surface.h"
|
||||
#include "sactcg.h"
|
||||
#include "sdl_core.h"
|
||||
|
||||
|
||||
static void ec1_cb(surface_t *, surface_t *);
|
||||
static void ec6_cb(surface_t *, surface_t *);
|
||||
static void ec7_cb(surface_t *, surface_t *);
|
||||
static void ec8_cb(surface_t *, surface_t *);
|
||||
static void ec9_cb(surface_t *, surface_t *);
|
||||
static void ec11_cb(surface_t *, surface_t *);
|
||||
static void ec12_cb(surface_t *, surface_t *);
|
||||
static void ec13_cb(surface_t *, surface_t *);
|
||||
static void ec14_cb(surface_t *, surface_t *);
|
||||
static void ec15_cb(surface_t *, surface_t *);
|
||||
static void ec16_cb(surface_t *, surface_t *);
|
||||
static void ec17_cb(surface_t *, surface_t *);
|
||||
static void ec_dummy_cb(surface_t *, surface_t *);
|
||||
|
||||
struct ecopyparam {
|
||||
int sttime;
|
||||
int curtime;
|
||||
int edtime;
|
||||
int curstep;
|
||||
int oldstep;
|
||||
};
|
||||
typedef struct ecopyparam ecopyparam_t;
|
||||
static ecopyparam_t ecp;
|
||||
|
||||
// #include "sprite_eupdate_perspect.c"
|
||||
// #include "sprite_eupdate_mosaic.c"
|
||||
// #include "sprite_eupdate_aff.c"
|
||||
// #include "sprite_eupdate_uneune.c"
|
||||
#include "sprite_eupdate_buller.c"
|
||||
// #include "sprite_eupdate_zmbbul.c"
|
||||
|
||||
typedef void entrypoint (surface_t *, surface_t *);
|
||||
|
||||
static void ec_dummy_cb(surface_t *sfsrc, surface_t *sfdst) {
|
||||
WARNING("NOT IMPLEMENTED\n");
|
||||
}
|
||||
|
||||
// クロスフェード
|
||||
static void ec1_cb(surface_t *sfsrc, surface_t *sfdst) {
|
||||
int curstep;
|
||||
|
||||
curstep = 255 * (ecp.curtime - ecp.sttime) / (ecp.edtime - ecp.sttime);
|
||||
if (ecp.oldstep == curstep) {
|
||||
usleep(0);
|
||||
return;
|
||||
}
|
||||
gre_Blend(sf0, 0, 0, sfsrc, 0, 0, sfdst, 0, 0, sfsrc->width, sfsrc->height, curstep);
|
||||
|
||||
// SACT_DEBUG("step = %d\n", curstep);
|
||||
ags_updateFull();
|
||||
|
||||
ecp.oldstep = curstep;
|
||||
}
|
||||
|
||||
// すだれ落ち
|
||||
static void ec7_cb(surface_t *sfsrc, surface_t *sfdst) {
|
||||
#define EC7DELTA 16
|
||||
int curstep, maxstep = sfsrc->height / EC7DELTA + EC7DELTA;
|
||||
int i, t, y;
|
||||
|
||||
curstep = maxstep * (ecp.curtime - ecp.sttime)/ (ecp.edtime - ecp.sttime);
|
||||
//SACT_DEBUG("step = %d\n", curstep);
|
||||
|
||||
if (ecp.oldstep == curstep) {
|
||||
usleep(0);
|
||||
return;
|
||||
}
|
||||
t = ecp.oldstep;
|
||||
while(t < curstep) {
|
||||
for (i = 0; i < min(t + 1, EC7DELTA); i++) {
|
||||
y = i + EC7DELTA * (t - i);
|
||||
if (y < 0 || y >= sfsrc->height) continue;
|
||||
gr_copy(sf0, 0, y,
|
||||
sfdst, 0, y, sfsrc->width, 1);
|
||||
}
|
||||
t++;
|
||||
}
|
||||
|
||||
ecp.oldstep = curstep;
|
||||
ags_updateFull();
|
||||
}
|
||||
|
||||
// すだれ左->右
|
||||
static void ec8_cb(surface_t *sfsrc, surface_t *sfdst) {
|
||||
#define EC8DELTA 16
|
||||
int curstep, maxstep = sfsrc->width / EC8DELTA + EC8DELTA;
|
||||
int i, t, x;
|
||||
|
||||
curstep = maxstep * (ecp.curtime - ecp.sttime) / (ecp.edtime - ecp.sttime);
|
||||
//SACT_DEBUG("step = %d\n", curstep);
|
||||
|
||||
if (ecp.oldstep == curstep) {
|
||||
usleep(0);
|
||||
return;
|
||||
}
|
||||
t = ecp.oldstep;
|
||||
while(t < curstep) {
|
||||
for (i = 0; i < min(t + 1, EC8DELTA); i++) {
|
||||
x = i + EC8DELTA * (t - i);
|
||||
if (x < 0 || x >= sfsrc->width) continue;
|
||||
gr_copy(sf0, x, 0,
|
||||
sfdst, x, 0, 1, sfsrc->height);
|
||||
}
|
||||
t++;
|
||||
}
|
||||
|
||||
ecp.oldstep = curstep;
|
||||
ags_updateFull();
|
||||
}
|
||||
|
||||
// すだれ落ち&左->右
|
||||
static void ec9_cb(surface_t *sfsrc, surface_t *sfdst) {
|
||||
#define EC9DELTA 16
|
||||
int curstep, maxstep;
|
||||
int i, t, x, y;
|
||||
|
||||
maxstep = max(sfsrc->height / EC9DELTA + EC9DELTA,
|
||||
sfsrc->width / EC9DELTA + EC9DELTA);
|
||||
|
||||
curstep = maxstep * (ecp.curtime - ecp.sttime)/ (ecp.edtime - ecp.sttime);
|
||||
//SACT_DEBUG("step = %d\n", curstep);
|
||||
|
||||
if (ecp.oldstep == curstep) {
|
||||
usleep(0);
|
||||
return;
|
||||
}
|
||||
t = ecp.oldstep;
|
||||
while(t < curstep) {
|
||||
for (i = 0; i < min(t + 1, EC9DELTA); i++) {
|
||||
y = i + EC9DELTA * (t - i);
|
||||
if (y < 0 || y >= sfsrc->height) continue;
|
||||
gr_copy(sf0, 0, y,
|
||||
sfdst, 0, y, sfsrc->width, 1);
|
||||
}
|
||||
for (i = 0; i < min(t + 1, EC9DELTA); i++) {
|
||||
x = i + EC9DELTA * (t - i);
|
||||
if (x < 0 || x >= sfsrc->width) continue;
|
||||
gr_copy(sf0, x, 0,
|
||||
sfdst, x, 0, 1, sfsrc->height);
|
||||
}
|
||||
t++;
|
||||
}
|
||||
|
||||
ecp.oldstep = curstep;
|
||||
ags_updateFull();
|
||||
}
|
||||
|
||||
// 上->下クロスフェード
|
||||
static void ec12_cb(surface_t *src, surface_t *dst) {
|
||||
#define EC12DELTA 256
|
||||
int curstep, maxstep = src->height + EC12DELTA;
|
||||
int j, st_i, ed_i, l;
|
||||
|
||||
curstep = maxstep * (ecp.curtime - ecp.sttime)/ (ecp.edtime - ecp.sttime);
|
||||
SACT_DEBUG("step = %d\n", curstep);
|
||||
|
||||
if (ecp.oldstep == curstep) {
|
||||
usleep(0); return;
|
||||
}
|
||||
|
||||
st_i = max(0, curstep - EC12DELTA + 1);
|
||||
ed_i = min(src->height -1, curstep);
|
||||
l = ed_i - st_i + 1;
|
||||
for (j = st_i; j < ed_i; j++) {
|
||||
gre_Blend(sf0, 0, j, src, 0, j, dst, 0, j, src->width, 1, curstep - j);
|
||||
}
|
||||
if ((st_i - ecp.oldstep) > 1) {
|
||||
gr_copy(sf0, 0, ecp.oldstep, dst, 0, ecp.oldstep, src->width, st_i - ecp.oldstep);
|
||||
ags_updateArea(0, ecp.oldstep, src->width, st_i - ecp.oldstep);
|
||||
}
|
||||
|
||||
ags_updateArea(0, st_i, src->width, l);
|
||||
ecp.oldstep = st_i;
|
||||
}
|
||||
|
||||
// 下->上クロスフェード
|
||||
static void ec13_cb(surface_t *src, surface_t *dst) {
|
||||
#define EC13DELTA 256
|
||||
int curstep, maxstep = src->height + EC12DELTA;
|
||||
int j, st_i, ed_i, l;
|
||||
int syy1 = 0 + dst->height -1;
|
||||
int syy2 = 0 + src->height -1;
|
||||
int dyy = 0 + sf0->height -1;
|
||||
|
||||
curstep = maxstep * (ecp.curtime - ecp.sttime)/ (ecp.edtime - ecp.sttime);
|
||||
SACT_DEBUG("step = %d\n", curstep);
|
||||
|
||||
if (ecp.oldstep == curstep) {
|
||||
usleep(0); return;
|
||||
}
|
||||
|
||||
st_i = max(0, curstep - EC13DELTA + 1);
|
||||
ed_i = min(src->height -1, curstep);
|
||||
l = ed_i - st_i + 1;
|
||||
for (j = st_i; j < ed_i; j++) {
|
||||
gre_Blend(sf0, 0, dyy - j, src, 0, syy1-j, dst, 0, syy2-j, src->width, 1, curstep - j);
|
||||
}
|
||||
if ((st_i - ecp.oldstep) > 1) {
|
||||
gr_copy(sf0, 0, dyy-ecp.oldstep, dst, 0, syy2-ecp.oldstep, src->width, st_i - ecp.oldstep);
|
||||
ags_updateArea(0, dyy-ecp.oldstep, src->width, st_i - ecp.oldstep);
|
||||
}
|
||||
|
||||
ags_updateArea(0, dyy-ed_i, src->width, l);
|
||||
ecp.oldstep = st_i;
|
||||
}
|
||||
|
||||
// 五芒星 (内->外)
|
||||
static void ec14_cb(surface_t *sfsrc, surface_t *sfdst) {
|
||||
int curstep, maxstep;
|
||||
maxstep = 256;
|
||||
curstep = maxstep * (ecp.curtime - ecp.sttime)/ (ecp.edtime - ecp.sttime);
|
||||
|
||||
if (ecp.oldstep == 0) {
|
||||
sf_copyall(sf0, sfdst);
|
||||
}
|
||||
sdl_maskupdate(0, 0, sfsrc->width, sfsrc->height, 0, 0, 44, curstep);
|
||||
ecp.oldstep = curstep;
|
||||
}
|
||||
|
||||
// 五芒星 (外->内)
|
||||
static void ec15_cb(surface_t *sfsrc, surface_t *sfdst) {
|
||||
int curstep, maxstep;
|
||||
maxstep = 256;
|
||||
curstep = maxstep * (ecp.curtime - ecp.sttime)/ (ecp.edtime - ecp.sttime);
|
||||
|
||||
if (ecp.oldstep == 0) {
|
||||
sf_copyall(sf0, sfdst);
|
||||
}
|
||||
sdl_maskupdate(0, 0, sfsrc->width, sfsrc->height, 0, 0, 45, curstep);
|
||||
ecp.oldstep = curstep;
|
||||
}
|
||||
|
||||
// 六芒星 (内->外)
|
||||
static void ec16_cb(surface_t *sfsrc, surface_t *sfdst) {
|
||||
int curstep, maxstep;
|
||||
maxstep = 256;
|
||||
curstep = maxstep * (ecp.curtime - ecp.sttime)/ (ecp.edtime - ecp.sttime);
|
||||
|
||||
if (ecp.oldstep == 0) {
|
||||
sf_copyall(sf0, sfdst);
|
||||
}
|
||||
sdl_maskupdate(0, 0, sfsrc->width, sfsrc->height, 0, 0, 46, curstep);
|
||||
ecp.oldstep = curstep;
|
||||
}
|
||||
|
||||
// 六芒星 (外->内)
|
||||
static void ec17_cb(surface_t *sfsrc, surface_t *sfdst) {
|
||||
int curstep, maxstep;
|
||||
maxstep = 256;
|
||||
curstep = maxstep * (ecp.curtime - ecp.sttime)/ (ecp.edtime - ecp.sttime);
|
||||
|
||||
if (ecp.oldstep == 0) {
|
||||
sf_copyall(sf0, sfdst);
|
||||
}
|
||||
sdl_maskupdate(0, 0, sfsrc->width, sfsrc->height, 0, 0, 47, curstep);
|
||||
ecp.oldstep = curstep;
|
||||
}
|
||||
|
||||
// フェードイン
|
||||
static void ec_fadein_cb(surface_t *sfsrc, surface_t *sfdst) {
|
||||
int curstep;
|
||||
|
||||
curstep = 255 * (ecp.curtime - ecp.sttime) / (ecp.edtime - ecp.sttime);
|
||||
if (ecp.oldstep == curstep) {
|
||||
usleep(0);
|
||||
return;
|
||||
}
|
||||
|
||||
gr_copy_bright(sf0, 0, 0, sfsrc, 0, 0, sfsrc->width, sfsrc->height, curstep);
|
||||
ags_updateFull();
|
||||
ecp.oldstep = curstep;
|
||||
}
|
||||
|
||||
static void ec_fadeout_cb(surface_t *sfsrc, surface_t *sfdst) {
|
||||
int curstep;
|
||||
|
||||
curstep = 255 * (ecp.curtime - ecp.sttime) / (ecp.edtime - ecp.sttime);
|
||||
if (ecp.oldstep == curstep) {
|
||||
usleep(0);
|
||||
return;
|
||||
}
|
||||
|
||||
gr_copy_bright(sf0, 0, 0, sfsrc, 0, 0, sfsrc->width, sfsrc->height, 255-curstep);
|
||||
ags_updateFull();
|
||||
ecp.oldstep = curstep;
|
||||
}
|
||||
|
||||
// ホワイトイン
|
||||
static void ec_whitein_cb(surface_t *sfsrc, surface_t *sfdst) {
|
||||
int curstep;
|
||||
|
||||
curstep = 255 * (ecp.curtime - ecp.sttime) / (ecp.edtime - ecp.sttime);
|
||||
if (ecp.oldstep == curstep) {
|
||||
usleep(0);
|
||||
return;
|
||||
}
|
||||
|
||||
gr_copy_whiteout(sf0, 0, 0, sfsrc, 0, 0, sfsrc->width, sfsrc->height, 255 - curstep);
|
||||
ags_updateFull();
|
||||
ecp.oldstep = curstep;
|
||||
}
|
||||
|
||||
static void ec_whiteout_cb(surface_t *sfsrc, surface_t *sfdst) {
|
||||
int curstep;
|
||||
|
||||
curstep = 255 * (ecp.curtime - ecp.sttime) / (ecp.edtime - ecp.sttime);
|
||||
if (ecp.oldstep == curstep) {
|
||||
usleep(0);
|
||||
return;
|
||||
}
|
||||
|
||||
gr_copy_whiteout(sf0, 0, 0, sfsrc, 0, 0, sfsrc->width, sfsrc->height, curstep);
|
||||
ags_updateFull();
|
||||
ecp.oldstep = curstep;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
効果つき画面更新
|
||||
@param type: 効果の種類
|
||||
@param no: 効果の種類
|
||||
@param time: 実行時間(msec)
|
||||
@param cancel: キー抜け(0:なし, 1:あり)
|
||||
*/
|
||||
int nt_sp_eupdate(int type, int time, int cancel) {
|
||||
surface_t *sfsrc, *sfdst;
|
||||
int key;
|
||||
entrypoint *cb;
|
||||
|
||||
// 現在の sf0 をセーブ
|
||||
sfsrc = sf_dup(sf0);
|
||||
|
||||
nt_sp_update_all(FALSE);
|
||||
|
||||
sfdst = sf_dup(sf0);
|
||||
|
||||
sf_copyall(sf0, sfsrc); // 全部の効果タイプにこの処理は要らないんだけど
|
||||
|
||||
ecp.sttime = ecp.curtime = sdl_getTicks();
|
||||
ecp.edtime = ecp.curtime + time;
|
||||
ecp.oldstep = 0;
|
||||
|
||||
switch(type) {
|
||||
case 10:
|
||||
cb = ec_dummy_cb;
|
||||
break;
|
||||
case 101: // クロスフェード
|
||||
cb = ec1_cb;
|
||||
break;
|
||||
case 102: // フェードアウト
|
||||
cb = ec_fadeout_cb;
|
||||
break;
|
||||
case 103: // フェードイン
|
||||
cb = ec_fadein_cb;
|
||||
break;
|
||||
case 104: // ホワイトアウト
|
||||
cb = ec_whiteout_cb;
|
||||
break;
|
||||
case 105: // ホワイトイン
|
||||
cb = ec_whitein_cb;
|
||||
break;
|
||||
case 107: // 簾落ち
|
||||
cb = ec7_cb;
|
||||
break;
|
||||
case 108: // 左->右すだれ
|
||||
cb = ec8_cb;
|
||||
break;
|
||||
case 111: // 線形ぼかし
|
||||
ec11_prepare(sfsrc, sfdst);
|
||||
cb = ec11_cb;
|
||||
break;
|
||||
case 1011:
|
||||
cb = ec_dummy_cb;
|
||||
break;
|
||||
case 1013:
|
||||
nt_sp_update_all(TRUE); return OK;
|
||||
// cb = ec_dummy_cb;
|
||||
break;
|
||||
default:
|
||||
cb = ec_dummy_cb;
|
||||
break;
|
||||
void nt_sp_eupdate(int no, int time, int cancel) {
|
||||
if (no == 1013) {
|
||||
nt_sp_update_all(true);
|
||||
return;
|
||||
}
|
||||
|
||||
nt_sp_update_all(false);
|
||||
|
||||
while ((ecp.curtime = sdl_getTicks()) < ecp.edtime) {
|
||||
int rest;
|
||||
|
||||
cb(sfsrc, sfdst);
|
||||
rest = 15 - (sdl_getTicks() - ecp.curtime);
|
||||
key = sys_keywait(rest, cancel ? KEYWAIT_CANCELABLE : KEYWAIT_NONCANCELABLE);
|
||||
|
||||
if (cancel && key) break;
|
||||
enum sdl_effect_type type = from_sact_effect(no - 100);
|
||||
if (type == EFFECT_INVALID) {
|
||||
WARNING("Unimplemented effect %d", no);
|
||||
type = EFFECT_CROSSFADE;
|
||||
}
|
||||
|
||||
sf_copyall(sf0, sfdst);
|
||||
SDL_Rect rect = { 0, 0, main_surface->w, main_surface->h };
|
||||
struct sdl_effect *eff = sdl_effect_init(&rect, NULL, 0, 0, sdl_getDIB(), 0, 0, type);
|
||||
|
||||
int sttime, curtime;
|
||||
sttime = curtime = sdl_getTicks();
|
||||
int edtime = curtime + time;
|
||||
|
||||
while ((curtime = sdl_getTicks()) < edtime) {
|
||||
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)
|
||||
break;
|
||||
}
|
||||
sdl_effect_finish(eff);
|
||||
ags_updateFull();
|
||||
sf_free(sfsrc);
|
||||
sf_free(sfdst);
|
||||
|
||||
if (type == 111) {
|
||||
ec11_drain(sfsrc, sfdst);
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
@@ -1,66 +0,0 @@
|
||||
// 11 と 19 で共有
|
||||
static surface_t *ec11_ss[6];
|
||||
static surface_t *ec11_sd[6];
|
||||
|
||||
// 線形ブラー
|
||||
static void ec11_cb(surface_t *sfsrc, surface_t *sfdst) {
|
||||
int curstep, maxstep = 6;
|
||||
curstep = maxstep * (ecp.curtime - ecp.sttime)/ (ecp.edtime - ecp.sttime);
|
||||
if (curstep < 6) {
|
||||
gre_Blend(sf0, 0, 0, ec11_ss[curstep], 0, 0, ec11_sd[5-curstep], 0, 0, sfsrc->width, sfsrc->height, (curstep+1)*256/7);
|
||||
ags_updateFull();
|
||||
}
|
||||
}
|
||||
|
||||
static void ec11_prepare(surface_t *src, surface_t *dst) {
|
||||
int i;
|
||||
|
||||
ec11_ss[0] = sf_create_surface(src->width, src->height, src->depth);
|
||||
ec11_sd[0] = sf_create_surface(src->width, src->height, src->depth);
|
||||
gr_buller(ec11_ss[0], 0, 0, src, 0, 0, src->width, src->height, 1 << 2);
|
||||
gr_buller(ec11_sd[0], 0, 0, dst, 0, 0, dst->width, dst->height, 1 << 2);
|
||||
for (i = 1; i < 6; i++) {
|
||||
ec11_ss[i] = sf_create_surface(src->width, src->height, src->depth);
|
||||
ec11_sd[i] = sf_create_surface(dst->width, dst->height, dst->depth);
|
||||
gr_buller(ec11_ss[i], 0, 0, ec11_ss[i-1], 0, 0, src->width, src->height, 1 << (i+2));
|
||||
gr_buller(ec11_sd[i], 0, 0, ec11_sd[i-1], 0, 0, dst->width, dst->height, 1 << (i+2));
|
||||
}
|
||||
}
|
||||
|
||||
static void ec11_drain(surface_t *src, surface_t *dst) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 6; i++) {
|
||||
sf_free(ec11_ss[i]);
|
||||
sf_free(ec11_sd[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// 縦線形ブラー
|
||||
static void ec19_cb(surface_t *sfsrc, surface_t *sfdst) {
|
||||
ec11_cb(sfsrc, sfdst);
|
||||
}
|
||||
|
||||
static void ec19_prepare(surface_t *src, surface_t *dst) {
|
||||
int i;
|
||||
|
||||
ec11_ss[0] = sf_create_surface(src->width, src->height, src->depth);
|
||||
ec11_sd[0] = sf_create_surface(src->width, src->height, src->depth);
|
||||
gr_buller_v(ec11_ss[0], 0, 0, src, 0, 0, src->width, src->height, 1 << 2);
|
||||
gr_buller_v(ec11_sd[0], 0, 0, dst, 0, 0, dst->width, dst->height, 1 << 2);
|
||||
for (i = 1; i < 6; i++) {
|
||||
ec11_ss[i] = sf_create_surface(src->width, src->height, src->depth);
|
||||
ec11_sd[i] = sf_create_surface(dst->width, dst->height, dst->depth);
|
||||
gr_buller_v(ec11_ss[i], 0, 0, ec11_ss[i-1], 0, 0, src->width, src->height, 1 << (i+2));
|
||||
gr_buller_v(ec11_sd[i], 0, 0, ec11_sd[i-1], 0, 0, dst->width, dst->height, 1 << (i+2));
|
||||
}
|
||||
}
|
||||
|
||||
static void ec19_drain(surface_t *src, surface_t *dst) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 6; i++) {
|
||||
sf_free(ec11_ss[i]);
|
||||
sf_free(ec11_sd[i]);
|
||||
}
|
||||
}
|
||||
@@ -25,15 +25,13 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <SDL.h>
|
||||
|
||||
#include "portab.h"
|
||||
#include "system.h"
|
||||
#include "list.h"
|
||||
#include "ags.h"
|
||||
#include "graphics.h"
|
||||
// #include "sact.h"
|
||||
#include "surface.h"
|
||||
#include "ngraph.h"
|
||||
#include "sprite.h"
|
||||
|
||||
// スプライト再描画間の間に変更のあったスプライトの領域の和
|
||||
@@ -57,7 +55,7 @@ static void disjunction(void* region, void* data) {
|
||||
// 更新の必要なスプライトの領域の和をとってクリッピングする
|
||||
static MyRectangle get_updatearea() {
|
||||
MyRectangle clip = {0, 0, 0, 0};
|
||||
MyRectangle rsf0 = {0, 0, sf0->width, sf0->height};
|
||||
MyRectangle screen = {0, 0, main_surface->w, main_surface->h};
|
||||
MyRectangle result;
|
||||
|
||||
slist_foreach(updatearea, disjunction, &clip);
|
||||
@@ -66,9 +64,9 @@ static MyRectangle get_updatearea() {
|
||||
updatearea = NULL;
|
||||
|
||||
// surface0との領域の積をとる
|
||||
SDL_IntersectRect(&rsf0, &clip, &result);
|
||||
SDL_IntersectRect(&screen, &clip, &result);
|
||||
|
||||
SACT_DEBUG("clipped area x=%d y=%d w=%d h=%d\n",
|
||||
SACT_DEBUG("clipped area x=%d y=%d w=%d h=%d",
|
||||
result.x, result.y, result.w, result.h);
|
||||
|
||||
return result;
|
||||
@@ -92,9 +90,9 @@ static void do_update_each(void* data, void* userdata) {
|
||||
画面全体の更新
|
||||
@param syncscreen: surface0 に描画したものを Screen に反映させるかどうか
|
||||
*/
|
||||
int nt_sp_update_all(boolean syncscreen) {
|
||||
void nt_sp_update_all(bool syncscreen) {
|
||||
// 画面全体を更新領域に
|
||||
MyRectangle r = {0, 0, sf0->width, sf0->height };
|
||||
MyRectangle r = {0, 0, main_surface->w, main_surface->h };
|
||||
|
||||
// updatelistに登録してあるスプライトを再描画
|
||||
// updatelistはスプライトの番号順に並んでいる
|
||||
@@ -106,41 +104,37 @@ int nt_sp_update_all(boolean syncscreen) {
|
||||
if (syncscreen) {
|
||||
ags_updateFull();
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/*
|
||||
画面の一部を更新
|
||||
updateme(_part)で登録した更新が必要なspriteの和の領域をupdate
|
||||
*/
|
||||
int nt_sp_update_clipped() {
|
||||
void nt_sp_update_clipped() {
|
||||
MyRectangle r;
|
||||
|
||||
// 更新領域の確定
|
||||
r = get_updatearea();
|
||||
|
||||
if (SDL_RectEmpty(&r))
|
||||
return OK;
|
||||
return;
|
||||
|
||||
// 更新領域に入っているスプライトの再描画
|
||||
slist_foreach(updatelist, do_update_each, &r);
|
||||
|
||||
// 更新領域を Window に転送
|
||||
ags_updateArea(r.x, r.y, r.w, r.h);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/*
|
||||
sprite全体の更新を登録
|
||||
@param sp: 更新するスプライト
|
||||
*/
|
||||
int nt_sp_updateme(sprite_t *sp) {
|
||||
void nt_sp_updateme(sprite_t *sp) {
|
||||
MyRectangle *r;
|
||||
|
||||
if (sp == NULL) return NG;
|
||||
if (sp->cursize.width == 0 || sp->cursize.height == 0) return NG;
|
||||
if (sp == NULL) return;
|
||||
if (sp->cursize.width == 0 || sp->cursize.height == 0) return;
|
||||
|
||||
r = malloc(sizeof(MyRectangle));
|
||||
r->x = sp->cur.x;
|
||||
@@ -150,10 +144,8 @@ int nt_sp_updateme(sprite_t *sp) {
|
||||
|
||||
updatearea = slist_append(updatearea, r);
|
||||
|
||||
SACT_DEBUG("x = %d, y = %d, spno = %d w=%d,h=%d\n",
|
||||
SACT_DEBUG("x = %d, y = %d, spno = %d w=%d,h=%d",
|
||||
r->x, r->y, sp->no, r->w, r->h);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -164,11 +156,11 @@ int nt_sp_updateme(sprite_t *sp) {
|
||||
@param w: 更新領域幅
|
||||
@param h: 更新領域高さ
|
||||
*/
|
||||
int nt_sp_updateme_part(sprite_t *sp, int x, int y, int w, int h) {
|
||||
void nt_sp_updateme_part(sprite_t *sp, int x, int y, int w, int h) {
|
||||
MyRectangle *r;
|
||||
|
||||
if (sp == NULL) return NG;
|
||||
if (w == 0 || h == 0) return NG;
|
||||
if (sp == NULL) return;
|
||||
if (w == 0 || h == 0) return;
|
||||
|
||||
r = malloc(sizeof(MyRectangle));
|
||||
r->x = sp->cur.x + x;
|
||||
@@ -178,10 +170,8 @@ int nt_sp_updateme_part(sprite_t *sp, int x, int y, int w, int h) {
|
||||
|
||||
updatearea = slist_append(updatearea, r);
|
||||
|
||||
SACT_DEBUG("x = %d, y = %d, spno = %d w=%d,h=%d\n",
|
||||
SACT_DEBUG("x = %d, y = %d, spno = %d w=%d,h=%d",
|
||||
r->x, r->y, sp->no, r->w, r->h);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
// スプライトの番号順に更新するためにリストに順番に要れるためのcallbck
|
||||
@@ -206,19 +196,14 @@ void nt_sp_remove_updatelist(sprite_t *sp) {
|
||||
updatelist = slist_remove(updatelist, sp);
|
||||
}
|
||||
|
||||
// デフォルトの壁紙update
|
||||
int nt_sp_draw_wall(sprite_t *sp, MyRectangle *area) {
|
||||
int sx, sy, w, h;
|
||||
|
||||
sx = area->x;
|
||||
sy = area->y;
|
||||
w = area->w;
|
||||
h = area->h;
|
||||
gr_fill(sf0, sx, sy, w, h, 0, 0, 0);
|
||||
|
||||
SACT_DEBUG("do update no=%d, sx=%d, sy=%d, w=%d, h=%d, \n",
|
||||
sp->no, sx, sy, w, h);
|
||||
|
||||
return OK;
|
||||
void nt_sp_clear_updatelist(void) {
|
||||
slist_free(updatelist);
|
||||
updatelist = NULL;
|
||||
slist_free(updatearea);
|
||||
updatearea = NULL;
|
||||
}
|
||||
|
||||
// デフォルトの壁紙update
|
||||
void nt_sp_draw_wall(sprite_t *sp, MyRectangle *area) {
|
||||
SDL_FillRect(main_surface, area, SDL_MapRGB(main_surface->format, 0, 0, 0));
|
||||
}
|
||||
|
||||
@@ -30,9 +30,61 @@
|
||||
#include "xsystem35.h"
|
||||
#include "modules.h"
|
||||
#include "nact.h"
|
||||
#include "alk.h"
|
||||
#include "music.h"
|
||||
#include "sdl_core.h"
|
||||
#include "input.h"
|
||||
#include "cg.h"
|
||||
#include "jpeg.h"
|
||||
|
||||
extern void ndd_init(const char *files[], int n);
|
||||
extern void ndd_run(int demonum);
|
||||
#define FPS 30
|
||||
|
||||
static const int ndemo_mus[3] = {0, 1, 85};
|
||||
|
||||
static void ndd_run(int demonum) {
|
||||
const char *alk_path = nact->files.alk[demonum + 1];
|
||||
alk_t *alk = alk_new(alk_path);
|
||||
if (alk == NULL) return;
|
||||
|
||||
while (sys_getInputInfo()); // wait for key up
|
||||
|
||||
int mus = ndemo_mus[demonum];
|
||||
if (mus)
|
||||
musbgm_play(mus, 0, 100, 0);
|
||||
|
||||
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) {
|
||||
SDL_Surface *sf = SDL_CreateRGBSurfaceWithFormatFrom(cg->pic, cg->width, cg->height, 24, cg->width * 3, SDL_PIXELFORMAT_RGB24);
|
||||
SDL_BlitSurface(sf, NULL, main_surface, NULL);
|
||||
ags_updateFull();
|
||||
SDL_FreeSurface(sf);
|
||||
cgdata_free(cg);
|
||||
} else {
|
||||
WARNING("Cannot decode CG %d in %s", i, alk_path);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
if (mus)
|
||||
musbgm_stop(ndemo_mus[demonum], 0);
|
||||
|
||||
alk_free(alk);
|
||||
}
|
||||
|
||||
static void Init() {
|
||||
int p1 = getCaliValue(); /* ISys3x */
|
||||
@@ -40,23 +92,18 @@ static void Init() {
|
||||
int p3 = getCaliValue(); /* ITimer */
|
||||
int *var = getCaliVariable();
|
||||
|
||||
#ifdef HAVE_JPEG
|
||||
ndd_init(nact->files.alk, 4);
|
||||
#endif
|
||||
*var = 1;
|
||||
|
||||
DEBUG_COMMAND("NightDemonDemo.Init %d,%d,%d,%p:\n", p1, p2, p3, var);
|
||||
TRACE("NightDemonDemo.Init %d,%d,%d,%p:", p1, p2, p3, var);
|
||||
}
|
||||
|
||||
static void Run() {
|
||||
int p1 = getCaliValue(); // デモ番号 0,1,2
|
||||
int p2 = getCaliValue();
|
||||
|
||||
#ifdef HAVE_JPEG
|
||||
ndd_run(p1);
|
||||
#endif
|
||||
|
||||
DEBUG_COMMAND("NightDemonDemo.Run %d,%d:\n", p1, p2);
|
||||
TRACE("NightDemonDemo.Run %d,%d:", p1, p2);
|
||||
}
|
||||
|
||||
static const ModuleFunc functions[] = {
|
||||
|
||||
@@ -1,97 +0,0 @@
|
||||
/*
|
||||
* jpeg2surface.c:
|
||||
*
|
||||
* 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: jpeg2surface.c,v 1.2 2003/11/09 15:06:12 chikama Exp $ */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <jpeglib.h>
|
||||
#undef max
|
||||
#undef min
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "portab.h"
|
||||
#include "ags.h"
|
||||
#include "surface.h"
|
||||
#include "ngraph.h"
|
||||
|
||||
static void ppm2surface(surface_t *sf, int curscanline, unsigned char *src, int width) {
|
||||
BYTE *dp = GETOFFSET_PIXEL(sf, 0, curscanline);
|
||||
|
||||
switch (sf->depth) {
|
||||
case 16:
|
||||
{
|
||||
WORD *dst = (WORD *)dp;
|
||||
while (width--) {
|
||||
*dst = PIX16(*src, *(src +1), *(src +2));
|
||||
dst++; src+= 3;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 24:
|
||||
case 32:
|
||||
{
|
||||
DWORD *dst = (DWORD *)dp;
|
||||
while (width--) {
|
||||
*dst = PIX24(*src, *(src +1), *(src +2));
|
||||
dst++; src+= 3;
|
||||
}
|
||||
break;
|
||||
}}
|
||||
}
|
||||
|
||||
// sf0 に直接描く(それでも遅いけど)
|
||||
surface_t *jpeg2surface(FILE *fp, int offset) {
|
||||
struct jpeg_decompress_struct cinfo;
|
||||
struct jpeg_error_mgr jerr;
|
||||
int row_stride;
|
||||
surface_t *sf;
|
||||
JSAMPARRAY buffer;
|
||||
|
||||
fseek(fp, offset, SEEK_SET);
|
||||
|
||||
cinfo.err = jpeg_std_error(&jerr);
|
||||
jpeg_create_decompress(&cinfo);
|
||||
|
||||
jpeg_stdio_src(&cinfo, fp);
|
||||
jpeg_read_header(&cinfo, TRUE);
|
||||
|
||||
cinfo.do_fancy_upsampling = FALSE;
|
||||
cinfo.do_block_smoothing = FALSE;
|
||||
|
||||
jpeg_start_decompress(&cinfo);
|
||||
//fprintf(stderr, "width = %d, height = %d\n", cinfo.output_width, cinfo.output_height);
|
||||
|
||||
//sf = sf_create_pixel(cinfo.output_width, cinfo.output_height, sf0->depth);
|
||||
sf = sf0;
|
||||
|
||||
row_stride = cinfo.output_width * cinfo.output_components;
|
||||
buffer = (*cinfo.mem->alloc_sarray)((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1);
|
||||
|
||||
while (cinfo.output_scanline < cinfo.output_height) {
|
||||
jpeg_read_scanlines(&cinfo, buffer, 1);
|
||||
ppm2surface(sf, cinfo.output_scanline -1, buffer[0], cinfo.output_width);
|
||||
}
|
||||
jpeg_finish_decompress(&cinfo);
|
||||
jpeg_destroy_decompress(&cinfo);
|
||||
|
||||
return sf;
|
||||
}
|
||||
@@ -1,110 +0,0 @@
|
||||
/*
|
||||
* ndd.c:
|
||||
*
|
||||
* 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: ndd.c,v 1.2 2003/11/09 15:06:12 chikama Exp $ */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "portab.h"
|
||||
#include "ags.h"
|
||||
#include "alk.h"
|
||||
#include "system.h"
|
||||
#include "surface.h"
|
||||
#include "music.h"
|
||||
#include "sdl_core.h"
|
||||
#include "ngraph.h"
|
||||
#include "input.h"
|
||||
|
||||
// 0: AliceSoft
|
||||
// 1: Opening
|
||||
// 2: Meteo
|
||||
|
||||
struct nddemo {
|
||||
const char **fn;
|
||||
alk_t *alk;
|
||||
surface_t *sf[10];
|
||||
};
|
||||
|
||||
static struct nddemo ndd;
|
||||
static int ndemo_alk[3] = {2, 3, 4};
|
||||
static int ndemo_mus[3] = {0, 1, 85};
|
||||
static int ndemo_nums[3] = {150, 603, 467};
|
||||
|
||||
extern surface_t *jpeg2surface(FILE *fp, int offset);
|
||||
|
||||
// ALKファイルの登録
|
||||
void ndd_init(const char *files[], int n) {
|
||||
int i;
|
||||
ndd.fn = malloc(sizeof(char *) * n);
|
||||
|
||||
for (i = 1; i <= n; i++) {
|
||||
ndd.fn[i] = files[i];
|
||||
}
|
||||
}
|
||||
|
||||
// デモ本体
|
||||
void ndd_run(int demonum) {
|
||||
FILE *fp;
|
||||
alk_t *alk;
|
||||
int i, start, ct;
|
||||
|
||||
// ファイルオフセットだけ alk からもらう
|
||||
alk = alk_new(ndd.fn[ndemo_alk[demonum]]);
|
||||
if (alk == NULL) return;
|
||||
|
||||
// libjpeg には FILE* を渡す
|
||||
if (NULL == (fp = fopen(ndd.fn[ndemo_alk[demonum]], "rb"))) {
|
||||
WARNING("%s not found\n", ndd.fn[ndemo_alk[demonum]]);
|
||||
return;
|
||||
}
|
||||
|
||||
// wait keyup
|
||||
while (sys_getInputInfo());
|
||||
|
||||
mus_bgm_play(ndemo_mus[demonum], 0, 100);
|
||||
start = sdl_getTicks();
|
||||
ct = 0;
|
||||
for (i = 0; i <= ndemo_nums[demonum];) {
|
||||
int offset;
|
||||
int cur1, cur = sdl_getTicks();
|
||||
|
||||
offset = alk->offset[i];
|
||||
|
||||
jpeg2surface(fp, offset); ct++;
|
||||
ags_updateFull();
|
||||
|
||||
cur1 = sdl_getTicks();
|
||||
if (cur1 - cur < 33) {
|
||||
if (sys_keywait(33 - (cur1 - cur), KEYWAIT_CANCELABLE)) break;
|
||||
} else {
|
||||
if (sys_getInputInfo()) break;
|
||||
}
|
||||
|
||||
i = (cur - start) / 33;
|
||||
}
|
||||
|
||||
NOTICE("%d/%d processed\n", ct, ndemo_nums[demonum]);
|
||||
mus_bgm_stop(ndemo_mus[demonum], 0);
|
||||
|
||||
fclose(fp);
|
||||
alk_free(alk);
|
||||
}
|
||||
@@ -40,7 +40,7 @@ static void Init() {
|
||||
*/
|
||||
int p1 = getCaliValue(); /* ITimer */
|
||||
|
||||
DEBUG_COMMAND_YET("RandMT.Init %p:\n", p1);
|
||||
TRACE_UNIMPLEMENTED("RandMT.Init %p:", p1);
|
||||
}
|
||||
|
||||
static void Get() {
|
||||
@@ -59,7 +59,7 @@ static void Get() {
|
||||
*var = (int)(genrand() * num) + 1;
|
||||
}
|
||||
|
||||
DEBUG_COMMAND("RandMT.Get %d,%p:\n", num, var);
|
||||
TRACE("RandMT.Get %d,%p:", num, var);
|
||||
}
|
||||
|
||||
static void GetNoOverlap() {
|
||||
@@ -69,7 +69,7 @@ static void GetNoOverlap() {
|
||||
|
||||
*var = (int)(genrand() * n) + min;
|
||||
|
||||
DEBUG_COMMAND("RandMT.GetNoOverlap %d,%d,%p:\n", min, n, var);
|
||||
TRACE("RandMT.GetNoOverlap %d,%d,%p:", min, n, var);
|
||||
}
|
||||
|
||||
static const ModuleFunc functions[] = {
|
||||
|
||||
@@ -0,0 +1,238 @@
|
||||
/*
|
||||
* Copyright (C) 2025 <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 "modules.h"
|
||||
#include "nact.h"
|
||||
#include "bgm.h"
|
||||
#include "music.h"
|
||||
#include "music_pcm.h"
|
||||
|
||||
#define SLOT 128
|
||||
|
||||
static int current_no = 0;
|
||||
|
||||
static void Init(void) {
|
||||
int isys3x = getCaliValue();
|
||||
TRACE("S3xMusic.Init %d:", isys3x);
|
||||
}
|
||||
|
||||
static void CreateChannel(void) {
|
||||
int nr_channels = getCaliValue();
|
||||
if (nr_channels != 2)
|
||||
SYSERROR("Unsupported number of channels: %d", nr_channels);
|
||||
TRACE("S3xMusic.CreateChannel %d:", nr_channels);
|
||||
}
|
||||
|
||||
static void Prepare(void) {
|
||||
int ch = getCaliValue();
|
||||
int no = getCaliValue();
|
||||
int *result = getCaliVariable();
|
||||
|
||||
if (ch == 0) {
|
||||
current_no = no;
|
||||
*result = 1;
|
||||
} else {
|
||||
*result = muspcm_load_bgm(SLOT, no) ? 1 : 0;
|
||||
}
|
||||
TRACE("S3xMusic.Prepare %d, %d => %d:", ch, no, *result);
|
||||
}
|
||||
|
||||
static void Unprepare(void) {
|
||||
int ch = getCaliValue();
|
||||
|
||||
if (ch == 0) {
|
||||
if (current_no) {
|
||||
musbgm_stop(current_no, 0);
|
||||
current_no = 0;
|
||||
}
|
||||
} else {
|
||||
muspcm_unload(SLOT);
|
||||
}
|
||||
TRACE("S3xMusic.Unprepare %d:", ch);
|
||||
}
|
||||
|
||||
static void Play(void) {
|
||||
int p1 = getCaliValue();
|
||||
int p2 = getCaliValue();
|
||||
TRACE_UNIMPLEMENTED("S3xMusic.Play %d, %d:", p1, p2);
|
||||
}
|
||||
|
||||
static void FadePlay(void) {
|
||||
int ch = getCaliValue();
|
||||
int fadein_time = getCaliValue();
|
||||
int volume = getCaliValue();
|
||||
int loop_count = getCaliValue(); // 0 = infinite
|
||||
|
||||
if (ch == 0) {
|
||||
musbgm_play(current_no, fadein_time, volume, loop_count);
|
||||
} else {
|
||||
muspcm_start(SLOT, loop_count == 0 ? -1 : loop_count);
|
||||
}
|
||||
TRACE("S3xMusic.FadePlay %d, %d, %d, %d:", ch, fadein_time, volume, loop_count);
|
||||
}
|
||||
|
||||
static void PlayPosSample(void) {
|
||||
int p1 = getCaliValue();
|
||||
int p2 = getCaliValue();
|
||||
int p3 = getCaliValue();
|
||||
int p4 = getCaliValue();
|
||||
TRACE_UNIMPLEMENTED("S3xMusic.PlayPosSample %d, %d, %d, %d:", p1, p2, p3, p4);
|
||||
}
|
||||
|
||||
static void IsPlay(void) {
|
||||
int ch = getCaliValue();
|
||||
int *result = getCaliVariable();
|
||||
|
||||
if (ch == 0) {
|
||||
*result = current_no && musbgm_isplaying(current_no);
|
||||
} else {
|
||||
*result = muspcm_isplaying(SLOT);
|
||||
}
|
||||
TRACE("S3xMusic.IsPlay %d => %d:", ch, *result);
|
||||
}
|
||||
|
||||
static void Stop(void) {
|
||||
int ch = getCaliValue();
|
||||
|
||||
if (ch == 0) {
|
||||
if (current_no)
|
||||
musbgm_stop(current_no, 0);
|
||||
current_no = 0;
|
||||
} else {
|
||||
muspcm_stop(SLOT);
|
||||
}
|
||||
TRACE("S3xMusic.Stop %d:", ch);
|
||||
}
|
||||
|
||||
static void Restart(void) {
|
||||
int p1 = getCaliValue();
|
||||
TRACE_UNIMPLEMENTED("S3xMusic.Restart %d:", p1);
|
||||
}
|
||||
|
||||
static void GetPlayPos(void) {
|
||||
int ch = getCaliValue();
|
||||
int *hour = getCaliVariable();
|
||||
int *min = getCaliVariable();
|
||||
int *sec = getCaliVariable();
|
||||
int *msec = getCaliVariable();
|
||||
if (ch == 0) {
|
||||
int time = musbgm_getpos(current_no);
|
||||
*hour = time / 360000;
|
||||
*min = (time / 6000) % 60;
|
||||
*sec = (time / 100) % 60;
|
||||
*msec = (time % 100) * 10;
|
||||
} else {
|
||||
// not implemented
|
||||
*hour = 0;
|
||||
*min = 0;
|
||||
*sec = 0;
|
||||
*msec = 0;
|
||||
}
|
||||
TRACE("S3xMusic.GetPlayPos %d => %d, %d, %d, %d:", ch, *hour, *min, *sec, *msec);
|
||||
}
|
||||
|
||||
static void GetPlayPosSample(void) {
|
||||
int p1 = getCaliValue();
|
||||
int *var1 = getCaliVariable();
|
||||
int *var2 = getCaliVariable();
|
||||
TRACE_UNIMPLEMENTED("S3xMusic.GetPlayPosSample %d, %p, %p:", p1, var1, var2);
|
||||
}
|
||||
|
||||
static void SetRepeatStart(void) {
|
||||
int p1 = getCaliValue();
|
||||
int p2 = getCaliValue();
|
||||
int p3 = getCaliValue();
|
||||
TRACE_UNIMPLEMENTED("S3xMusic.SetRepeatStart %d, %d, %d:", p1, p2, p3);
|
||||
}
|
||||
|
||||
static void SetRepeatEnd(void) {
|
||||
int p1 = getCaliValue();
|
||||
int p2 = getCaliValue();
|
||||
int p3 = getCaliValue();
|
||||
TRACE_UNIMPLEMENTED("S3xMusic.SetRepeatEnd %d, %d, %d:", p1, p2, p3);
|
||||
}
|
||||
|
||||
static void FadeVolume(void) {
|
||||
int ch = getCaliValue();
|
||||
int time = getCaliValue();
|
||||
int volume = getCaliValue();
|
||||
int stop_after_fade = getCaliValue();
|
||||
|
||||
if (ch == 0) {
|
||||
if (stop_after_fade) {
|
||||
musbgm_stop(current_no, time / 10);
|
||||
} else {
|
||||
musbgm_fade(current_no, time / 10, volume);
|
||||
}
|
||||
} else {
|
||||
if (stop_after_fade) {
|
||||
muspcm_fadeout(SLOT, time);
|
||||
} else {
|
||||
muspcm_setvol(SLOT, volume);
|
||||
}
|
||||
}
|
||||
TRACE("S3xMusic.FadeVolume %d, %d, %d, %d:", ch, time, volume, stop_after_fade);
|
||||
}
|
||||
|
||||
static void IsFade(void) {
|
||||
int ch = getCaliValue();
|
||||
int *result = getCaliVariable();
|
||||
*result = 0;
|
||||
TRACE_UNIMPLEMENTED("S3xMusic.IsFade %d => %d:", ch, *result);
|
||||
}
|
||||
|
||||
static void StopFade(void) {
|
||||
int ch = getCaliValue();
|
||||
TRACE_UNIMPLEMENTED("S3xMusic.StopFade %d:", ch);
|
||||
}
|
||||
|
||||
static void WaitEnd(void) {
|
||||
int p1 = getCaliValue();
|
||||
int p2 = getCaliValue(); // IWinMsg
|
||||
TRACE_UNIMPLEMENTED("S3xMusic.WaitEnd %d, %d:", p1, p2);
|
||||
}
|
||||
|
||||
static void sleep(void) {
|
||||
int p1 = getCaliValue(); // IWinMsg
|
||||
TRACE_UNIMPLEMENTED("S3xMusic.sleep %d:", p1);
|
||||
}
|
||||
|
||||
static const ModuleFunc functions[] = {
|
||||
{"CreateChannel", CreateChannel},
|
||||
{"FadePlay", FadePlay},
|
||||
{"FadeVolume", FadeVolume},
|
||||
{"GetPlayPos", GetPlayPos},
|
||||
{"GetPlayPosSample", GetPlayPosSample},
|
||||
{"Init", Init},
|
||||
{"IsFade", IsFade},
|
||||
{"IsPlay", IsPlay},
|
||||
{"Play", Play},
|
||||
{"PlayPosSample", PlayPosSample},
|
||||
{"Prepare", Prepare},
|
||||
{"Restart", Restart},
|
||||
{"SetRepeatEnd", SetRepeatEnd},
|
||||
{"SetRepeatStart", SetRepeatStart},
|
||||
{"Stop", Stop},
|
||||
{"StopFade", StopFade},
|
||||
{"Unprepare", Unprepare},
|
||||
{"WaitEnd", WaitEnd},
|
||||
{"sleep", sleep},
|
||||
};
|
||||
|
||||
const Module module_S3xMusic = {"S3xMusic", functions, sizeof(functions) / sizeof(ModuleFunc)};
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user