mirror of
https://github.com/kichikuou/xsystem35-sdl2.git
synced 2026-09-22 22:48:08 +03:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
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 |
@@ -6,7 +6,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Install Deps
|
||||
run: sudo apt install ninja-build
|
||||
@@ -15,14 +15,14 @@ jobs:
|
||||
run: |
|
||||
cd android
|
||||
echo "${{ secrets.KEYSTORE_BASE64 }}" | base64 -d > keystore.jks
|
||||
ANDROID_NDK_HOME=$ANDROID_SDK_ROOT/ndk-bundle ./gradlew assembleRelease
|
||||
JAVA_HOME=$JAVA_HOME_17_X64 ANDROID_NDK_HOME=$ANDROID_SDK_ROOT/ndk-bundle ./gradlew assembleRelease
|
||||
env:
|
||||
KEY_ALIAS: ${{ secrets.KEY_ALIAS }}
|
||||
KEY_PASSWORD: ${{ secrets.KEY_PASSWORD }}
|
||||
KEYSTORE_PASSWORD: ${{ secrets.KEYSTORE_PASSWORD }}
|
||||
|
||||
- name: Upload artifacts
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: xsystem35-apk
|
||||
path: android/app/build/outputs/apk/release/app-release.apk
|
||||
|
||||
@@ -2,7 +2,7 @@ name: Emscripten Build
|
||||
on: [push, pull_request]
|
||||
|
||||
env:
|
||||
EM_VERSION: 3.1.34
|
||||
EM_VERSION: 3.1.54
|
||||
EM_CACHE_FOLDER: 'emsdk-cache'
|
||||
|
||||
jobs:
|
||||
@@ -10,17 +10,17 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Setup cache
|
||||
id: cache-system-libraries
|
||||
uses: actions/cache@v3
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ${{env.EM_CACHE_FOLDER}}
|
||||
key: ${{env.EM_VERSION}}-${{ runner.os }}
|
||||
|
||||
- name: Setup Emscripten toolchain
|
||||
uses: mymindstorm/setup-emsdk@v12
|
||||
uses: mymindstorm/setup-emsdk@v14
|
||||
with:
|
||||
version: ${{ env.EM_VERSION }}
|
||||
actions-cache-folder: ${{env.EM_CACHE_FOLDER}}
|
||||
@@ -29,13 +29,13 @@ jobs:
|
||||
run: |
|
||||
mkdir -p out/wasm
|
||||
cd out/wasm
|
||||
emcmake cmake -DCMAKE_BUILD_TYPE=MinSizeRel ../../
|
||||
make
|
||||
emcmake cmake -DCMAKE_BUILD_TYPE=MinSizeRel -DCMAKE_COMPILE_WARNING_AS_ERROR=YES ../../
|
||||
make -j4
|
||||
mkdir xsystem35
|
||||
mv src/xsystem35.* xsystem35/
|
||||
|
||||
- name: Upload artifacts
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: xsystem35-wasm
|
||||
path: out/wasm/xsystem35
|
||||
|
||||
@@ -10,7 +10,7 @@ jobs:
|
||||
|
||||
name: Linux ${{ matrix.build-type }}
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Install Deps
|
||||
run: |
|
||||
@@ -22,7 +22,7 @@ jobs:
|
||||
mkdir -p out/${{ matrix.build-type }}
|
||||
cd out/${{ matrix.build-type }}
|
||||
cmake -DCMAKE_BUILD_TYPE=${{ matrix.build-type }} ../../
|
||||
make
|
||||
make -j4
|
||||
|
||||
- name: Test
|
||||
run: ctest --output-on-failure
|
||||
|
||||
@@ -5,10 +5,17 @@ jobs:
|
||||
build:
|
||||
runs-on: windows-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- { sys: MINGW32, installer: "xsystem35-32bit" }
|
||||
- { sys: MINGW64, installer: "xsystem35-64bit" }
|
||||
- sys: mingw32
|
||||
package: "xsystem35-32bit"
|
||||
cmake_args: "-DENABLE_DEBUGGER=no"
|
||||
deps: ""
|
||||
- sys: ucrt64
|
||||
package: "xsystem35-64bit"
|
||||
cmake_args: ""
|
||||
deps: "cjson:p"
|
||||
defaults:
|
||||
run:
|
||||
shell: msys2 {0}
|
||||
@@ -19,27 +26,31 @@ jobs:
|
||||
uses: msys2/setup-msys2@v2
|
||||
with:
|
||||
msystem: ${{ matrix.sys }}
|
||||
update: true
|
||||
pacboy: >-
|
||||
gcc:p
|
||||
cmake:p
|
||||
ninja:p
|
||||
SDL2:p
|
||||
SDL2_ttf:p
|
||||
SDL2_mixer:p
|
||||
libwebp:p
|
||||
cjson:p
|
||||
nsis:p
|
||||
ntldd-git:p
|
||||
${{ matrix.deps }}
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Copy licenses
|
||||
run: |
|
||||
ls /${{ matrix.sys }}/share/licenses
|
||||
mkdir dist
|
||||
cp -r /${{ matrix.sys }}/share/licenses dist/
|
||||
cp fonts/*.license dist/licenses/
|
||||
|
||||
- name: Install dev dependencies
|
||||
run: pacboy --noconfirm -S --needed gcc:p cmake:p ninja:p
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
mkdir -p out/release
|
||||
cd out/release
|
||||
cmake -G"Ninja" -DCMAKE_BUILD_TYPE=Release ../../
|
||||
cmake -GNinja -DCMAKE_BUILD_TYPE=Release -DCMAKE_COMPILE_WARNING_AS_ERROR=YES ${{ matrix.cmake_args }} ../../
|
||||
ninja
|
||||
|
||||
- name: Test
|
||||
@@ -47,11 +58,12 @@ jobs:
|
||||
working-directory: out/release
|
||||
|
||||
- name: Package
|
||||
working-directory: tools/installer
|
||||
run: ./make-installer.sh ../../out/release ${{ matrix.installer }}.nsi
|
||||
run: |
|
||||
cp out/release/src/xsystem35.exe *.md COPYING xsys35rc.sample dist/
|
||||
|
||||
- name: Upload
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: ${{ matrix.installer }}
|
||||
path: tools/installer/${{ matrix.installer }}.exe
|
||||
name: ${{ matrix.package }}
|
||||
path: dist
|
||||
compression-level: 9 # because we use it for releases
|
||||
|
||||
+72
-65
@@ -3,17 +3,10 @@ cmake_minimum_required(VERSION 3.13)
|
||||
project(xsystem35 LANGUAGES C)
|
||||
set(CMAKE_C_STANDARD 99)
|
||||
enable_testing()
|
||||
set(CMAKE_EXPORT_COMPILE_COMMANDS TRUE)
|
||||
|
||||
include(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 ()
|
||||
|
||||
# A wrapper around pkg_check_modules() that skips the check if ENABLE_<prefix> is false
|
||||
macro (optional_pkg_check_modules prefix)
|
||||
option(ENABLE_${prefix} "Use ${prefix} if available" ON)
|
||||
@@ -22,19 +15,48 @@ 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()
|
||||
|
||||
check_symbol_exists(getlogin "unistd.h" HAVE_GETLOGIN)
|
||||
check_symbol_exists(mmap "sys/mman.h" HAVE_MMAP)
|
||||
check_symbol_exists(sigaction "signal.h" HAVE_SIGACTION)
|
||||
check_symbol_exists(uname "sys/utsname.h" HAVE_UNAME)
|
||||
|
||||
if (EMSCRIPTEN)
|
||||
function(add_emscripten_library name option)
|
||||
add_library(${name} INTERFACE)
|
||||
set_target_properties(${name} PROPERTIES
|
||||
INTERFACE_COMPILE_OPTIONS ${option}
|
||||
INTERFACE_LINK_OPTIONS ${option})
|
||||
endfunction()
|
||||
add_emscripten_library(zlib -sUSE_ZLIB=1)
|
||||
add_emscripten_library(sdl2 -sUSE_SDL=2)
|
||||
add_emscripten_library(sdl2_ttf -sUSE_SDL_TTF=2)
|
||||
set(DEFAULT_FONT_PATH /fonts/)
|
||||
|
||||
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})
|
||||
|
||||
else() # non-emscripten, non-android
|
||||
if (WIN32)
|
||||
set(ZLIB_USE_STATIC_LIBS ON)
|
||||
endif()
|
||||
find_package(ZLIB REQUIRED)
|
||||
add_library(zlib ALIAS ZLIB::ZLIB)
|
||||
|
||||
include(FindPkgConfig)
|
||||
optional_pkg_check_modules(GTK3 IMPORTED_TARGET gtk+-3.0)
|
||||
@@ -42,45 +64,61 @@ else()
|
||||
set(ENABLE_GTK 1)
|
||||
endif()
|
||||
|
||||
pkg_check_modules(SDL2 IMPORTED_TARGET sdl2)
|
||||
pkg_check_modules(SDL2TTF IMPORTED_TARGET SDL2_ttf)
|
||||
optional_pkg_check_modules(SDL2MIXER IMPORTED_TARGET SDL2_mixer)
|
||||
pkg_check_modules(SDL2 REQUIRED IMPORTED_TARGET sdl2)
|
||||
pkg_check_modules(SDL2TTF REQUIRED IMPORTED_TARGET SDL2_ttf)
|
||||
pkg_check_modules(SDL2MIXER REQUIRED IMPORTED_TARGET SDL2_mixer)
|
||||
if (WIN32)
|
||||
add_static_library(sdl2 SDL2)
|
||||
add_static_library(sdl2_ttf SDL2TTF)
|
||||
# Workaround for linking error
|
||||
set_property(TARGET sdl2_ttf PROPERTY INTERFACE_LINK_LIBRARIES
|
||||
$<LINK_GROUP:RESCAN,${SDL2TTF_STATIC_LIBRARIES} -lstdc++>)
|
||||
add_static_library(sdl2_mixer SDL2MIXER)
|
||||
else()
|
||||
add_library(sdl2 ALIAS PkgConfig::SDL2)
|
||||
add_library(sdl2_ttf ALIAS PkgConfig::SDL2TTF)
|
||||
add_library(sdl2_mixer ALIAS PkgConfig::SDL2MIXER)
|
||||
set(DEFAULT_FONT_PATH ${CMAKE_INSTALL_PREFIX}/share/xsystem35/fonts/)
|
||||
endif()
|
||||
|
||||
option(ENABLE_DEBUGGER "Enable built-in debugger" ON)
|
||||
if (ENABLE_DEBUGGER)
|
||||
pkg_check_modules(cJSON IMPORTED_TARGET libcjson)
|
||||
if (NOT cJSON_FOUND)
|
||||
if (cJSON_FOUND)
|
||||
if (WIN32)
|
||||
add_static_library(cJSON cJSON)
|
||||
else ()
|
||||
add_library(cJSON ALIAS PkgConfig::cJSON)
|
||||
endif()
|
||||
else ()
|
||||
# libcjson-dev of Debian buster / Ubuntu 20.04 does not install pkgconfig files.
|
||||
find_library(cJSON cjson)
|
||||
if (NOT cJSON)
|
||||
message(FATAL_ERROR "libcjson is required but not found.")
|
||||
endif()
|
||||
add_library(cJSON ALIAS ${cJSON})
|
||||
endif()
|
||||
endif()
|
||||
|
||||
optional_pkg_check_modules(WEBP IMPORTED_TARGET libwebp)
|
||||
if (WEBP_FOUND)
|
||||
set(HAVE_WEBP 1)
|
||||
if (WIN32)
|
||||
add_static_library(WebP WEBP)
|
||||
else()
|
||||
add_library(WebP ALIAS PkgConfig::WEBP)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
find_library(PORTMIDI portmidi)
|
||||
if (PORTMIDI)
|
||||
set(HAVE_PORTMIDI 1)
|
||||
set(ENABLE_MIDI_PORTMIDI 1)
|
||||
endif()
|
||||
|
||||
set(DEFAULT_FONT_PATH ${CMAKE_INSTALL_PREFIX}/share/xsystem35/fonts/)
|
||||
endif()
|
||||
|
||||
# Menu
|
||||
|
||||
if (EMSCRIPTEN)
|
||||
set(SRC_MENU menu_emscripten.c)
|
||||
elseif (ANDROID)
|
||||
set(SRC_MENU menu_android.c)
|
||||
elseif (ENABLE_GTK)
|
||||
set(SRC_MENU menu.c menu_callback.c menu_gui.c s39init.c)
|
||||
|
||||
if (ENABLE_GTK)
|
||||
# i18n support (currently only menus are translated)
|
||||
include(FindIntl)
|
||||
include(FindGettext)
|
||||
@@ -90,60 +128,36 @@ elseif (ENABLE_GTK)
|
||||
include_directories(${Intl_INCLUDE_DIRS})
|
||||
link_libraries(${Intl_LIBRARIES})
|
||||
endif()
|
||||
else ()
|
||||
set(SRC_MENU menu_sdl.c sdl_input.c)
|
||||
endif()
|
||||
|
||||
# PCM audio
|
||||
|
||||
if (EMSCRIPTEN)
|
||||
list(APPEND SRC_AUDIO)
|
||||
list(APPEND SRC_AUDIO pcm.emscripten.c bgm.emscripten.c bgi.c)
|
||||
list(APPEND SUMMARY_AUDIO "Emscripten")
|
||||
elseif (SDL2MIXER_FOUND)
|
||||
list(APPEND SRC_AUDIO pcm.sdlmixer.c bgm.sdlmixer.c bgi.c)
|
||||
list(APPEND SUMMARY_AUDIO "SDL_mixer")
|
||||
set(ENABLE_SDLMIXER 1)
|
||||
else()
|
||||
list(APPEND SRC_AUDIO pcm.dummy.c bgm.dummy.c)
|
||||
list(APPEND SUMMARY_AUDIO "SDL_mixer")
|
||||
endif()
|
||||
|
||||
# CDROM
|
||||
|
||||
list(APPEND SRC_CDROM cdrom.bgm.c)
|
||||
if (CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
||||
list(APPEND SRC_CDROM cdrom.Linux.c)
|
||||
list(APPEND SUMMARY_CDROM "Linux ioctl")
|
||||
set(ENABLE_CDROM_LINUX 1)
|
||||
elseif (CMAKE_SYSTEM_NAME STREQUAL "FreeBSD")
|
||||
list(APPEND SRC_CDROM cdrom.FreeBSD.c)
|
||||
list(APPEND SUMMARY_CDROM "*BSD ioctl")
|
||||
set(ENABLE_CDROM_BSD 1)
|
||||
elseif (CMAKE_SYSTEM_NAME STREQUAL "Emscripten")
|
||||
list(APPEND SRC_CDROM cdrom.emscripten.c)
|
||||
if (EMSCRIPTEN)
|
||||
list(APPEND SUMMARY_CDROM "Emscripten")
|
||||
set(ENABLE_CDROM_EMSCRIPTEN 1)
|
||||
else()
|
||||
list(APPEND SRC_CDROM cdrom.empty.c)
|
||||
endif()
|
||||
if (SDL2MIXER_FOUND)
|
||||
list(APPEND SRC_CDROM cdrom.mp3.c)
|
||||
list(APPEND SUMMARY_CDROM "SDL_mixer (wav|mp3|ogg...)")
|
||||
set(ENABLE_CDROM_MP3 1)
|
||||
endif()
|
||||
set(CDROM_DEVICE "playlist.txt" CACHE STRING "CDROM Device Name")
|
||||
set(DEFAULT_PLAYLIST_PATH "playlist.txt" CACHE STRING "Default playlist path")
|
||||
|
||||
# MIDI
|
||||
|
||||
if (EMSCRIPTEN)
|
||||
list(APPEND SRC_MIDI midi.emscripten.c)
|
||||
list(APPEND SUMMARY_MIDI "Emscripten")
|
||||
elseif (ANDROID)
|
||||
list(APPEND SRC_MIDI midi.android.c)
|
||||
list(APPEND SUMMARY_MIDI "Android")
|
||||
else()
|
||||
list(APPEND SUMMARY_MIDI "SDL_mixer")
|
||||
set(ENABLE_MIDI_SDLMIXER 1)
|
||||
|
||||
if (HAVE_SIGACTION)
|
||||
list(APPEND SRC_MIDI midi.rawmidi.c midifile.c)
|
||||
list(APPEND SUMMARY_MIDI "raw")
|
||||
set(MIDI_DEVICE "/dev/midi" CACHE STRING "midi device")
|
||||
set(ENABLE_MIDI_RAWMIDI 1)
|
||||
@@ -162,15 +176,9 @@ else()
|
||||
set(SEQ_DEVICE "/dev/sequencer" CACHE STRING "sequencer device")
|
||||
endif()
|
||||
|
||||
if (SDL2MIXER_FOUND)
|
||||
list(APPEND SRC_MIDI midi.sdlmixer.c)
|
||||
list(APPEND SUMMARY_MIDI "SDL_mixer")
|
||||
set(ENABLE_MIDI_SDLMIXER 1)
|
||||
endif()
|
||||
|
||||
if (HAVE_PORTMIDI AND ENABLE_MIDI_PORTMIDI)
|
||||
list(APPEND SRC_MIDI midi.portmidi.c)
|
||||
if (HAVE_PORTMIDI)
|
||||
list(APPEND SUMMARY_MIDI "PortMidi")
|
||||
set(ENABLE_MIDI_PORTMIDI 1)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
@@ -193,7 +201,6 @@ message("------------------")
|
||||
set(PACKAGE ${PROJECT_NAME})
|
||||
configure_file(config.h.in config.h)
|
||||
include_directories(${CMAKE_CURRENT_BINARY_DIR})
|
||||
add_compile_definitions(HAVE_CONFIG_H)
|
||||
add_compile_definitions($<$<CONFIG:Debug>:DEBUG>)
|
||||
|
||||
add_subdirectory(src)
|
||||
|
||||
@@ -3,22 +3,22 @@
|
||||
This is a multi-platform port of `xsystem35`, a free implementation of
|
||||
AliceSoft's System 3.x game engine.
|
||||
|
||||
## Compatiblity
|
||||
## Compatibility
|
||||
|
||||
See the [game compatibility table](game_compatibility.md) for a list of games
|
||||
that can be played on xsystem35-sdl2.
|
||||
that can be played with xsystem35-sdl2.
|
||||
|
||||
## Unique Features
|
||||
|
||||
In addition to the original System 3.x's functionalities, xsystem35-sdl2 has
|
||||
the following features.
|
||||
In addition to the original System 3.x functionalities, xsystem35-sdl2 offers
|
||||
the following features:
|
||||
|
||||
### Playing audio files as fake CD music
|
||||
### Playing Audio Files as Virtual CD Music
|
||||
|
||||
Many System 3.x games had music as audio tracks on the CD-ROM. Xsystem35 can
|
||||
play music from audio files instead, to avoid the hassle of inserting CDs. To
|
||||
use ripped audio files, create a file named `playlist.txt` in the game
|
||||
directory, and enter the paths to your tracks, one per line. For example:
|
||||
Many System 3.x games feature music as audio tracks on the CD-ROM. xsystem35
|
||||
can play music from audio files, eliminating the need to insert CDs. To use
|
||||
ripped audio files, create a file named `playlist.txt` in the game directory
|
||||
and list the paths to your tracks, one per line. For example:
|
||||
|
||||
```
|
||||
# The first line is not used
|
||||
@@ -27,89 +27,108 @@ BGM/track03.mp3
|
||||
...
|
||||
```
|
||||
|
||||
The first line is not used, because track 1 of game CD is usually a data track.
|
||||
The first line is not used because the first track on a game CD is typically a
|
||||
data track.
|
||||
|
||||
### Unicode translation support
|
||||
Some games have integrated music as MIDI. In such cases, the music won't play
|
||||
using the virtual CD feature. If you encounter a `Cannot load MIDI` error
|
||||
message, you might need to set the `SDL_SOUNDFONTS` environment variable to
|
||||
point to an `.sf2` file. For example:
|
||||
|
||||
The original System 3.x only supported Shift_JIS (a Japanese character
|
||||
encoding), but xsystem35 supports Unicode and is able to run games translated
|
||||
into languages other than Japanese and English.
|
||||
```
|
||||
SDL_SOUNDFONTS=/usr/share/soundfonts/GeneralUser.sf2 xsystem35
|
||||
```
|
||||
|
||||
See [xsys35c](https://github.com/kichikuou/xsys35c)'s document for how to
|
||||
build a game with Unicode mode.
|
||||
### Unicode Translation Support
|
||||
|
||||
While the original System 3.x only supported Shift_JIS (a Japanese character
|
||||
encoding), xsystem35 supports Unicode and can run games translated into
|
||||
languages other than Japanese and English.
|
||||
|
||||
For instructions on how to build a game with Unicode support, see the
|
||||
[xsys35c](https://github.com/kichikuou/xsys35c) documentation.
|
||||
|
||||
### Debugging
|
||||
|
||||
Xsystem35 has a built-in debugger that allows you to step through the game and
|
||||
examine / modify variables in the game. There are two ways to use the debugger:
|
||||
xsystem35 features a built-in debugger that allows you to step through the game
|
||||
and examine or modify game variables. There are two ways to use the debugger:
|
||||
|
||||
- Through [Visual Studio Code](https://code.visualstudio.com/) (recommended):
|
||||
The [vscode-system3x](https://github.com/kichikuou/vscode-system3x) extension
|
||||
provides graphical debugging interface for System 3.x.
|
||||
- Using CUI debugger: Running xsystem35 with `-debug` option will start the
|
||||
debugger with console interface. Type `help` to see a list of available
|
||||
commands.
|
||||
provides a graphical debugging interface for System 3.x.
|
||||
- Using the CLI Debugger: Running xsystem35 with the `-debug` option will
|
||||
launch the debugger with a console interface. Type `help` to see a list of
|
||||
available commands.
|
||||
|
||||
## Installing
|
||||
## Installation
|
||||
|
||||
Prebuilt packages for Windows and Android can be downloaded from the
|
||||
[Releases](https://github.com/kichikuou/xsystem35-sdl2/releases) page. For
|
||||
other platforms, see the [Building](#building) section.
|
||||
other platforms, refer to the [Building](#building) section.
|
||||
|
||||
## Running
|
||||
### Windows
|
||||
|
||||
Execute `xsytem35`, and it will show a dialog to select a folder. Select the
|
||||
game folder (where the ALD files are located).
|
||||
Copy `xsystem35.exe` to the game folder and run it.
|
||||
|
||||
### Android
|
||||
|
||||
See [android/README.md](https://github.com/kichikuou/xsystem35-sdl2/blob/master/android/README.md#use).
|
||||
See [android/README.md](android/README.md#use).
|
||||
|
||||
### Other Platforms
|
||||
|
||||
Run xsystem35 from within the game directory.
|
||||
|
||||
cd /path/to/game_directory
|
||||
xsystem35
|
||||
```bash
|
||||
$ cd /path/to/game_directory
|
||||
$ xsystem35
|
||||
```
|
||||
|
||||
## 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 libcjson-dev
|
||||
$ mkdir -p out/debug
|
||||
$ cd out/debug
|
||||
$ cmake -DCMAKE_BUILD_TYPE=Debug ../../
|
||||
$ make && make install
|
||||
```
|
||||
|
||||
### MacOS
|
||||
|
||||
[Homebrew](https://brew.sh/index_ja) is needed.
|
||||
[Homebrew](https://brew.sh/) is required.
|
||||
|
||||
$ brew install cmake pkg-config sdl2 sdl2_mixer sdl2_ttf webp cjson
|
||||
$ mkdir -p out/debug
|
||||
$ cd out/debug
|
||||
$ cmake -DCMAKE_BUILD_TYPE=Debug ../../
|
||||
$ make && make install
|
||||
```bash
|
||||
$ brew install cmake pkg-config sdl2 sdl2_mixer sdl2_ttf webp cjson
|
||||
$ mkdir -p out/debug
|
||||
$ cd out/debug
|
||||
$ cmake -DCMAKE_BUILD_TYPE=Debug ../../
|
||||
$ make && make install
|
||||
```
|
||||
|
||||
### Windows
|
||||
|
||||
[MSYS2](https://www.msys2.org) is needed.
|
||||
[MSYS2](https://www.msys2.org) is required.
|
||||
|
||||
$ pacman -S cmake mingw-w64-x86_64-cmake mingw-w64-x86_64-SDL2 mingw-w64-x86_64-SDL2_ttf mingw-w64-x86_64-SDL2_mixer mingw-w64-x86_64-libwebp mingw-w64-x86_64-cjson
|
||||
$ mkdir -p out/debug
|
||||
$ cd out/debug
|
||||
$ cmake -G"MSYS Makefiles" -DCMAKE_BUILD_TYPE=Debug ../../
|
||||
$ make
|
||||
```bash
|
||||
$ pacman -S cmake mingw-w64-ucrt-x86_64-gcc mingw-w64-ucrt-x86_64-cmake mingw-w64-ucrt-x86_64-SDL2 mingw-w64-ucrt-x86_64-SDL2_ttf mingw-w64-ucrt-x86_64-SDL2_mixer mingw-w64-ucrt-x86_64-libwebp mingw-w64-ucrt-x86_64-cjson
|
||||
$ mkdir -p out/debug
|
||||
$ cd out/debug
|
||||
$ cmake -G"MSYS Makefiles" -DCMAKE_BUILD_TYPE=Debug ../../
|
||||
$ make
|
||||
```
|
||||
|
||||
### Emscripten
|
||||
|
||||
$ mkdir -p out/wasm
|
||||
$ cd out/wasm
|
||||
$ emcmake cmake -DCMAKE_BUILD_TYPE=MinSizeRel ../../
|
||||
$ make
|
||||
```bash
|
||||
$ mkdir -p out/wasm
|
||||
$ cd out/wasm
|
||||
$ emcmake cmake -DCMAKE_BUILD_TYPE=MinSizeRel ../../
|
||||
$ make
|
||||
```
|
||||
|
||||
To use the generated binary, checkout
|
||||
To use the generated binary, check out
|
||||
[Kichikuou on Web](https://github.com/kichikuou/web) and copy `out/xsystem35.*`
|
||||
into its `docs` directory.
|
||||
|
||||
|
||||
+34
-20
@@ -1,7 +1,8 @@
|
||||
# xsystem35 for Android
|
||||
|
||||
## Download
|
||||
Prebuilt APKs are [here](https://github.com/kichikuou/xsystem35-sdl2/releases).
|
||||
You can download prebuilt APKs
|
||||
[here](https://github.com/kichikuou/xsystem35-sdl2/releases).
|
||||
|
||||
## Build
|
||||
Prerequisites:
|
||||
@@ -11,10 +12,10 @@ Prerequisites:
|
||||
### Using Android Studio
|
||||
Open this directory as an Android Studio project.
|
||||
|
||||
### Command line build
|
||||
Configure environment variables and run the `gradlew` script in this folder.
|
||||
### Command Line Build
|
||||
Set environment variables and run the `gradlew` script in this directory.
|
||||
|
||||
Example build instructions (for Debian bullseye):
|
||||
Example build instructions (for Debian bookworm):
|
||||
```sh
|
||||
# Install necessary packages
|
||||
sudo apt install git wget unzip default-jdk-headless ninja-build
|
||||
@@ -22,38 +23,51 @@ sudo apt install git wget unzip default-jdk-headless ninja-build
|
||||
# Install Android SDK / NDK
|
||||
export ANDROID_SDK_ROOT=$HOME/android-sdk
|
||||
mkdir -p $ANDROID_SDK_ROOT/cmdline-tools
|
||||
wget https://dl.google.com/android/repository/commandlinetools-linux-8512546_latest.zip
|
||||
unzip commandlinetools-linux-8512546_latest.zip -d $ANDROID_SDK_ROOT/cmdline-tools
|
||||
wget https://dl.google.com/android/repository/commandlinetools-linux-10406996_latest.zip
|
||||
unzip commandlinetools-linux-10406996_latest.zip -d $ANDROID_SDK_ROOT/cmdline-tools
|
||||
mv $ANDROID_SDK_ROOT/cmdline-tools/cmdline-tools $ANDROID_SDK_ROOT/cmdline-tools/tools
|
||||
yes |$ANDROID_SDK_ROOT/cmdline-tools/tools/bin/sdkmanager --licenses
|
||||
yes | $ANDROID_SDK_ROOT/cmdline-tools/tools/bin/sdkmanager --licenses
|
||||
$ANDROID_SDK_ROOT/cmdline-tools/tools/bin/sdkmanager ndk-bundle 'cmake;3.22.1'
|
||||
export ANDROID_NDK_HOME=$ANDROID_SDK_ROOT/ndk-bundle
|
||||
|
||||
# Check out and build xsystem35
|
||||
# Clone and build xsystem35
|
||||
git clone https://github.com/kichikuou/xsystem35-sdl2.git
|
||||
cd xsystem35-sdl2/android
|
||||
./gradlew build # or ./gradlew installDebug if you have a connected device
|
||||
```
|
||||
|
||||
## Use
|
||||
## Usage
|
||||
### Basic Usage
|
||||
1. Create a ZIP file containing all the game files and BGM files (see [below](#preparing-a-zip) for details), and transfer it to your device.
|
||||
2. Open the app. A list of installed games is displayed. Since nothing has been installed yet, only the "Install from ZIP" button is displayed. Tap it.
|
||||
3. Select the ZIP file you created in 1.
|
||||
4. The game starts. To simulate right-click, tap the black bars on the left/right or top/bottom of the screen.
|
||||
1. Create a ZIP file containing all the game files and BGM files (see
|
||||
[below](#preparing-a-zip) for details), and transfer it to your device.
|
||||
2. Open the app. A list of installed games will be displayed. Since no games
|
||||
have been installed yet, only the "Install from ZIP" button will be visible.
|
||||
Tap it.
|
||||
3. Select the ZIP file you created in step 1.
|
||||
4. The game will start. To simulate a right-click, tap the black bars on either
|
||||
the left or right, or top or bottom of the screen.
|
||||
|
||||
### Preparing a ZIP
|
||||
- Include all files in the `GAMEDATA` folder (`.ALD` files and others). `.EXE` and `.DLL` are not really needed, but you can include them as well.
|
||||
- Music files (`.mp3`, `.ogg` or `.wav`) whose file names end with a number are recognized as BGM files. For example:
|
||||
- Include all files from the `GAMEDATA` folder (such as `.ALD` files and
|
||||
others). `.EXE` and `.DLL` files are not necessary, but you can include them
|
||||
if you want.
|
||||
- Music files (`.mp3`, `.ogg`, or `.wav`) whose filenames end with a number
|
||||
will be recognized as BGM files. For example:
|
||||
- `Track2.mp3`
|
||||
- `15.ogg`
|
||||
- `rance4_03.wav` (This shouldn't be `rance403.wav`, because it would be treated as the 403rd track)
|
||||
- `rance4_03.wav` (Note: The filename shouldn't be `rance403.wav`, as it
|
||||
would be treated as the 403rd track.)
|
||||
|
||||
Note: This form of ZIP can be used in [Kichikuou on Web](http://kichikuou.github.io/web/) as well.
|
||||
Note: This ZIP format is also compatible with
|
||||
[Kichikuou on Web](http://kichikuou.github.io/web/).
|
||||
|
||||
### Miscellaneous
|
||||
- You can export / import saved files using the option menu of the game list.
|
||||
- To uninstall a game, long-tap the title in the game list.
|
||||
- You can export or import save files via the game list's option menu.
|
||||
- To uninstall a game, long-tap its title in the game list.
|
||||
|
||||
## Known Issues
|
||||
- Android versions older than 7.0 cannot handle ZIPs containing Shift-JIS file names. This is the case with some ZIPs distributed on [retroc.net](http://retropc.net/alice/). If you get the error "This type of ZIP is not supported.", unzip the ZIP file on your PC and re-archive it with a modern ZIP creation software.
|
||||
- Android versions older than 7.0 cannot handle ZIP files containing Shift-JIS
|
||||
filenames. This issue occurs with some ZIP files distributed on
|
||||
[retroc.net](http://retropc.net/alice/). If you encounter the error message
|
||||
"This type of ZIP is not supported," unzip the file on your PC and re-archive
|
||||
it using modern ZIP creation software.
|
||||
|
||||
+13
-11
@@ -9,18 +9,18 @@ else {
|
||||
apply plugin: 'kotlin-android'
|
||||
|
||||
android {
|
||||
compileSdkVersion 31
|
||||
if (buildAsApplication) {
|
||||
namespace "io.github.kichikuou.xsystem35"
|
||||
}
|
||||
compileSdkVersion 34
|
||||
defaultConfig {
|
||||
if (buildAsApplication) {
|
||||
applicationId "io.github.kichikuou.xsystem35"
|
||||
}
|
||||
minSdkVersion 19
|
||||
targetSdkVersion 31
|
||||
versionCode 14
|
||||
versionName "2.9.0" + gitRevision()
|
||||
targetSdkVersion 34
|
||||
versionCode 21
|
||||
versionName "2.11.3" + gitRevision()
|
||||
externalNativeBuild {
|
||||
cmake {
|
||||
arguments "-DANDROID_APP_PLATFORM=android-16", "-DANDROID_STL=c++_static"
|
||||
arguments "-DANDROID_APP_PLATFORM=android-19", "-DANDROID_STL=c++_static"
|
||||
// abiFilters 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64'
|
||||
abiFilters 'armeabi-v7a', 'arm64-v8a'
|
||||
}
|
||||
@@ -38,7 +38,9 @@ android {
|
||||
release {
|
||||
minifyEnabled false
|
||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||
signingConfig signingConfigs.release
|
||||
if (rootProject.file('keystore.jks').exists()) {
|
||||
signingConfig signingConfigs.release
|
||||
}
|
||||
}
|
||||
}
|
||||
applicationVariants.all { variant ->
|
||||
@@ -62,10 +64,10 @@ android {
|
||||
}
|
||||
|
||||
}
|
||||
lintOptions {
|
||||
lint {
|
||||
abortOnError false
|
||||
}
|
||||
|
||||
|
||||
if (buildAsLibrary) {
|
||||
libraryVariants.all { variant ->
|
||||
variant.outputs.each { output ->
|
||||
|
||||
@@ -1,50 +1,41 @@
|
||||
cmake_minimum_required(VERSION 3.13)
|
||||
cmake_minimum_required(VERSION 3.14)
|
||||
|
||||
project(GAME)
|
||||
set(PROJECT_ROOT_DIR ../../..)
|
||||
|
||||
# Compilation of SDL and companion libraries
|
||||
include(FetchContent)
|
||||
FetchContent_Declare(
|
||||
SDL
|
||||
URL https://github.com/libsdl-org/SDL/releases/download/release-2.26.1/SDL2-2.26.1.tar.gz
|
||||
URL_HASH SHA1=08a8cec21ffcebf44e4633a786d594a7811100d2
|
||||
URL https://github.com/libsdl-org/SDL/releases/download/release-2.30.2/SDL2-2.30.2.tar.gz
|
||||
URL_HASH SHA1=37a0557fc39460dc2a4fbbf162d95f115d2c9be2
|
||||
)
|
||||
FetchContent_Declare(
|
||||
SDL_ttf
|
||||
URL https://github.com/libsdl-org/SDL_ttf/releases/download/release-2.20.1/SDL2_ttf-2.20.1.tar.gz
|
||||
URL_HASH SHA1=f774ff407915ae4afa3d03e5a9395283d9090f28
|
||||
URL https://github.com/libsdl-org/SDL_ttf/releases/download/release-2.22.0/SDL2_ttf-2.22.0.tar.gz
|
||||
URL_HASH SHA1=da5e86b601ad299a697878fab1af6f3be47b529d
|
||||
)
|
||||
FetchContent_Declare(
|
||||
SDL_mixer
|
||||
URL https://github.com/libsdl-org/SDL_mixer/releases/download/release-2.6.2/SDL2_mixer-2.6.2.tar.gz
|
||||
URL_HASH SHA1=036fc7839a6b8dc1af3dbfed4e2531224bbacdd7
|
||||
URL https://github.com/libsdl-org/SDL_mixer/releases/download/release-2.8.0/SDL2_mixer-2.8.0.tar.gz
|
||||
URL_HASH SHA1=a58c69f9d00e44833b9e00e1adb58d85759ca499
|
||||
)
|
||||
|
||||
# Compilation of SDL and companion libraries
|
||||
FetchContent_GetProperties(SDL)
|
||||
if(NOT sdl_POPULATED)
|
||||
FetchContent_Populate(SDL)
|
||||
add_subdirectory(${sdl_SOURCE_DIR} ${sdl_BINARY_DIR})
|
||||
endif()
|
||||
FetchContent_GetProperties(SDL_ttf)
|
||||
if(NOT sdl_ttf_POPULATED)
|
||||
FetchContent_Populate(SDL_ttf)
|
||||
set(SDL2TTF_SAMPLES OFF CACHE BOOL "Build the SDL2_ttf sample program(s)" FORCE)
|
||||
set(SDL2TTF_INSTALL OFF CACHE BOOL "Enable SDL2_ttf install target" FORCE)
|
||||
set(SDL2TTF_VENDORED ON CACHE BOOL "Use vendored third-party libraries" FORCE)
|
||||
add_subdirectory(${sdl_ttf_SOURCE_DIR} ${sdl_ttf_BINARY_DIR})
|
||||
endif()
|
||||
FetchContent_GetProperties(SDL_mixer)
|
||||
if(NOT sdl_mixer_POPULATED)
|
||||
FetchContent_Populate(SDL_mixer)
|
||||
set(SDL2MIXER_OPUS OFF CACHE BOOL "Enable Opus music" FORCE)
|
||||
set(SDL2MIXER_FLAC OFF CACHE BOOL "Enable FLAC music" FORCE)
|
||||
set(SDL2MIXER_MOD OFF CACHE BOOL "Support loading MOD music" FORCE)
|
||||
set(SDL2MIXER_MIDI OFF CACHE BOOL "Enable MIDI music" FORCE)
|
||||
set(SDL2MIXER_SAMPLES OFF CACHE BOOL "Build the SDL2_mixer sample program(s)" FORCE)
|
||||
set(SDL2MIXER_INSTALL OFF CACHE BOOL "Enable SDL2_mixer install target" FORCE)
|
||||
add_subdirectory(${sdl_mixer_SOURCE_DIR} ${sdl_mixer_BINARY_DIR})
|
||||
endif()
|
||||
set(SDL2TTF_SAMPLES OFF CACHE BOOL "Build the SDL2_ttf sample program(s)" FORCE)
|
||||
set(SDL2TTF_INSTALL OFF CACHE BOOL "Enable SDL2_ttf install target" FORCE)
|
||||
set(SDL2TTF_VENDORED ON CACHE BOOL "Use vendored third-party libraries" FORCE)
|
||||
|
||||
set(SDL2MIXER_OPUS OFF CACHE BOOL "Enable Opus music" FORCE)
|
||||
set(SDL2MIXER_FLAC OFF CACHE BOOL "Enable FLAC music" FORCE)
|
||||
set(SDL2MIXER_MOD OFF CACHE BOOL "Support loading MOD music" FORCE)
|
||||
set(SDL2MIXER_MIDI OFF CACHE BOOL "Enable MIDI music" FORCE)
|
||||
set(SDL2MIXER_WAVPACK OFF CACHE BOOL "Enable WavPack music" FORCE)
|
||||
set(SDL2MIXER_SAMPLES OFF CACHE BOOL "Build the SDL2_mixer sample program(s)" FORCE)
|
||||
set(SDL2MIXER_INSTALL OFF CACHE BOOL "Enable SDL2_mixer install target" FORCE)
|
||||
|
||||
FetchContent_MakeAvailable(SDL)
|
||||
FetchContent_MakeAvailable(SDL_ttf)
|
||||
FetchContent_MakeAvailable(SDL_mixer)
|
||||
|
||||
# The main CMakeLists.txt of xsystem35
|
||||
add_subdirectory(${PROJECT_ROOT_DIR} xsystem35)
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
-->
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
package="io.github.kichikuou.xsystem35"
|
||||
android:installLocation="auto">
|
||||
|
||||
<!-- OpenGL ES 2.0 -->
|
||||
|
||||
@@ -30,9 +30,11 @@ import java.io.IOException
|
||||
|
||||
// Intent for this activity must have the following extra:
|
||||
// - EXTRA_GAME_ROOT (string): A path to the game installation.
|
||||
// - EXTRA_SAVE_DIRECTORY (string): A path to the save data directory.
|
||||
class GameActivity : SDLActivity() {
|
||||
companion object {
|
||||
const val EXTRA_GAME_ROOT = "GAME_ROOT"
|
||||
const val EXTRA_SAVE_DIRECTORY = "SAVE_DIRECTORY"
|
||||
const val EXTRA_ARCHIVE_NAME = "ARCHIVE_NAME"
|
||||
}
|
||||
|
||||
@@ -61,7 +63,7 @@ class GameActivity : SDLActivity() {
|
||||
override fun getArguments(): Array<String> {
|
||||
return arrayOf(
|
||||
"-gamedir", intent.getStringExtra(EXTRA_GAME_ROOT)!!,
|
||||
"-devcd", Launcher.PLAYLIST_FILE)
|
||||
"-savedir", intent.getStringExtra(EXTRA_SAVE_DIRECTORY)!!)
|
||||
}
|
||||
|
||||
override fun setTitle(title: CharSequence?) {
|
||||
|
||||
@@ -25,9 +25,7 @@ import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import java.io.*
|
||||
import java.lang.StringBuilder
|
||||
import java.nio.charset.Charset
|
||||
import java.util.*
|
||||
import java.util.zip.ZipEntry
|
||||
import java.util.zip.ZipInputStream
|
||||
import java.util.zip.ZipOutputStream
|
||||
@@ -41,13 +39,13 @@ interface LauncherObserver {
|
||||
fun onInstallFailure(msgId: Int)
|
||||
}
|
||||
|
||||
private const val SAVE_DIR = "save"
|
||||
|
||||
class Launcher private constructor(private val rootDir: File) {
|
||||
companion object {
|
||||
const val SAVE_DIR = "save"
|
||||
const val TITLE_FILE = "title.txt"
|
||||
const val PLAYLIST_FILE = "playlist2.txt"
|
||||
const val OLD_PLAYLIST_FILE = "playlist.txt"
|
||||
const val GAMEDIR_FILE = "game_directory.txt"
|
||||
const val PLAYLIST_FILE = "playlist.txt"
|
||||
const val OLD_PLAYLIST_FILE = "playlist2.txt"
|
||||
|
||||
fun getInstance(rootDir: File): Launcher {
|
||||
if (gLauncher == null) {
|
||||
@@ -79,14 +77,14 @@ class Launcher private constructor(private val rootDir: File) {
|
||||
isInstalling = true
|
||||
GlobalScope.launch(Dispatchers.Main) {
|
||||
try {
|
||||
withContext(Dispatchers.IO) {
|
||||
val gameDir = withContext(Dispatchers.IO) {
|
||||
extractFiles(input, dir) { msg ->
|
||||
GlobalScope.launch(Dispatchers.Main) {
|
||||
observer?.onInstallProgress(msg)
|
||||
}
|
||||
}
|
||||
}
|
||||
observer?.onInstallSuccess(dir, archiveName)
|
||||
observer?.onInstallSuccess(gameDir, archiveName)
|
||||
} catch (e: InstallFailureException) {
|
||||
observer?.onInstallFailure(e.msgId)
|
||||
} catch (e: Exception) {
|
||||
@@ -114,9 +112,11 @@ class Launcher private constructor(private val rootDir: File) {
|
||||
continue
|
||||
}
|
||||
try {
|
||||
val titleFile = File(path, TITLE_FILE)
|
||||
val gameDirFile = File(path, GAMEDIR_FILE)
|
||||
val gamePath = if (gameDirFile.exists()) File(path, gameDirFile.readText()) else path
|
||||
val titleFile = File(gamePath, TITLE_FILE)
|
||||
val title = titleFile.readText()
|
||||
games.add(Entry(path, title, titleFile.lastModified()))
|
||||
games.add(Entry(gamePath, title, titleFile.lastModified()))
|
||||
migratePlaylist(path)
|
||||
} catch (e: IOException) {
|
||||
// Incomplete game installation. Delete it.
|
||||
@@ -179,7 +179,7 @@ class Launcher private constructor(private val rootDir: File) {
|
||||
}
|
||||
}
|
||||
|
||||
private fun extractFiles(input: InputStream, outDir: File, progressCallback: (String) -> Unit) {
|
||||
private fun extractFiles(input: InputStream, outDir: File, progressCallback: (String) -> Unit): File {
|
||||
val configWriter = GameConfigWriter()
|
||||
val hadDecodeError = forEachZipEntry(input) { zipEntry, zip ->
|
||||
Log.i("extractFiles", zipEntry.name)
|
||||
@@ -193,90 +193,62 @@ class Launcher private constructor(private val rootDir: File) {
|
||||
}
|
||||
configWriter.maybeAdd(zipEntry.name)
|
||||
}
|
||||
if (!configWriter.readyToWrite()) {
|
||||
if (!configWriter.ready) {
|
||||
if (hadDecodeError)
|
||||
throw InstallFailureException(R.string.unsupported_zip)
|
||||
throw InstallFailureException(R.string.cannot_find_ald)
|
||||
}
|
||||
configWriter.write(outDir)
|
||||
return configWriter.gameDir?.let { File(outDir, it) } ?: outDir
|
||||
}
|
||||
|
||||
// Xsystem35-sdl2 <=2.2.0 had a bug where playlist had an extra empty line at
|
||||
// the beginning of the file. This migrates playlist.txt created by an old
|
||||
// version of xsystem35-sdl2 to playlist2.txt.
|
||||
// Xsystem35-sdl2 2.3.0 - 2.11.1 used playlist2.txt. Rename it to playlist.txt.
|
||||
private fun migratePlaylist(dir: File) {
|
||||
val oldPlaylist = File(dir, OLD_PLAYLIST_FILE)
|
||||
if (!oldPlaylist.exists())
|
||||
return
|
||||
var tracks = oldPlaylist.readLines()
|
||||
if (tracks.isNotEmpty())
|
||||
tracks = tracks.subList(1, tracks.size)
|
||||
File(dir, PLAYLIST_FILE).writeText(tracks.joinToString("\n"))
|
||||
oldPlaylist.delete()
|
||||
if (oldPlaylist.exists()) {
|
||||
oldPlaylist.renameTo(File(dir, PLAYLIST_FILE))
|
||||
}
|
||||
}
|
||||
|
||||
class InstallFailureException(val msgId: Int) : Exception()
|
||||
|
||||
// A helper class which generates xsystem35.gr and playlist.txt in the game root directory.
|
||||
// A helper class which generates GAMEDIR_FILE and PLAYLIST_FILE.
|
||||
private class GameConfigWriter {
|
||||
private val grb = StringBuilder()
|
||||
private var basename: String? = null
|
||||
private val aldRegex = """(.*?)([a-z])([a-z])\.(ald|wai|bgi)""".toRegex(RegexOption.IGNORE_CASE)
|
||||
private val aldType = mapOf(
|
||||
"b" to "BGM",
|
||||
"d" to "Data",
|
||||
"g" to "Graphics",
|
||||
"m" to "Midi",
|
||||
"r" to "Resource",
|
||||
"s" to "Scenario",
|
||||
"w" to "Wave")
|
||||
private val specialResources = mapOf(
|
||||
"system39.ain" to "Ain",
|
||||
"system39.ini" to "Init",
|
||||
"sactefam.kld" to "SACT01"
|
||||
)
|
||||
var ready = false
|
||||
private set
|
||||
var gameDir: String? = null
|
||||
private set
|
||||
private val aldRegex = """.*?s[a-z]\.ald""".toRegex(RegexOption.IGNORE_CASE)
|
||||
private val audioRegex = """.*?(\d+)\.(wav|mp3|ogg)""".toRegex(RegexOption.IGNORE_CASE)
|
||||
private val audioFiles: Array<String?> = arrayOfNulls(100)
|
||||
|
||||
fun maybeAdd(path: String) {
|
||||
val name = File(path).name
|
||||
|
||||
specialResources[name.lowercase(Locale.US)]?.let {
|
||||
grb.appendLine("$it $path")
|
||||
return
|
||||
aldRegex.matchEntire(path)?.let {
|
||||
gameDir = File(path).parent
|
||||
ready = true
|
||||
}
|
||||
aldRegex.matchEntire(name)?.let {
|
||||
val ext = it.groupValues[4].uppercase(Locale.US)
|
||||
val type = if (ext == "ALD") {
|
||||
aldType[it.groupValues[2].lowercase(Locale.US)]
|
||||
} else {
|
||||
ext
|
||||
}
|
||||
val id = it.groupValues[3].uppercase(Locale.US)
|
||||
if (type != null) {
|
||||
grb.appendLine("$type$id $path")
|
||||
basename = it.groupValues[1]
|
||||
}
|
||||
}
|
||||
audioRegex.matchEntire(name)?.let {
|
||||
audioRegex.matchEntire(path)?.let {
|
||||
val track = it.groupValues[1].toInt()
|
||||
if (0 < track && track <= audioFiles.size)
|
||||
audioFiles[track - 1] = path
|
||||
}
|
||||
}
|
||||
|
||||
fun readyToWrite() = basename != null
|
||||
|
||||
fun write(outDir: File) {
|
||||
for (id in 'A' .. 'Z') {
|
||||
grb.appendLine("Save$id ../save/${basename}s${id.lowercase(Locale.US)}.asd")
|
||||
// Generate GAMEDIR_FILE
|
||||
gameDir?.let {
|
||||
File(outDir, GAMEDIR_FILE).writeText(it)
|
||||
}
|
||||
// Generate PLAYLIST_FILE
|
||||
val absGameDir = gameDir?.let { File(outDir, it) } ?: outDir
|
||||
val playlistFile = File(absGameDir, PLAYLIST_FILE)
|
||||
if (!playlistFile.exists()) {
|
||||
val prefixToRemove = gameDir?.let { "$it/" } ?: ""
|
||||
val playlist = audioFiles.joinToString("\n") {
|
||||
it?.removePrefix(prefixToRemove) ?: ""
|
||||
}.trimEnd('\n')
|
||||
playlistFile.writeText(playlist)
|
||||
}
|
||||
val gr = grb.toString()
|
||||
Log.i("xsystem35.gr", gr)
|
||||
File(outDir, "xsystem35.gr").writeText(gr)
|
||||
|
||||
val playlist = audioFiles.joinToString("\n") { it ?: "" }.trimEnd('\n')
|
||||
File(outDir, PLAYLIST_FILE).writeText(playlist)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -180,6 +180,7 @@ class LauncherActivity : Activity(), LauncherObserver {
|
||||
val i = Intent()
|
||||
i.setClass(applicationContext, GameActivity::class.java)
|
||||
i.putExtra(GameActivity.EXTRA_GAME_ROOT, path.path)
|
||||
i.putExtra(GameActivity.EXTRA_SAVE_DIRECTORY, File(filesDir, Launcher.SAVE_DIR).path)
|
||||
i.putExtra(GameActivity.EXTRA_ARCHIVE_NAME, archiveName)
|
||||
startActivity(i)
|
||||
}
|
||||
|
||||
@@ -186,7 +186,7 @@ class HIDDeviceBLESteamController extends BluetoothGattCallback implements HIDDe
|
||||
// Because on Chromebooks we show up as a dual-mode device, it will attempt to connect TRANSPORT_AUTO, which will use TRANSPORT_BREDR instead
|
||||
// of TRANSPORT_LE. Let's force ourselves to connect low energy.
|
||||
private BluetoothGatt connectGatt(boolean managed) {
|
||||
if (Build.VERSION.SDK_INT >= 23) {
|
||||
if (Build.VERSION.SDK_INT >= 23 /* Android 6.0 (M) */) {
|
||||
try {
|
||||
return mDevice.connectGatt(mManager.getContext(), managed, this, TRANSPORT_LE);
|
||||
} catch (Exception e) {
|
||||
@@ -429,7 +429,7 @@ class HIDDeviceBLESteamController extends BluetoothGattCallback implements HIDDe
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (newState == 0) {
|
||||
mIsConnected = false;
|
||||
}
|
||||
|
||||
@@ -170,7 +170,7 @@ public class HIDDeviceManager {
|
||||
Log.i(TAG," Interface protocol: " + mUsbInterface.getInterfaceProtocol());
|
||||
Log.i(TAG," Endpoint count: " + mUsbInterface.getEndpointCount());
|
||||
|
||||
// Get endpoint details
|
||||
// Get endpoint details
|
||||
for (int epi = 0; epi < mUsbInterface.getEndpointCount(); epi++)
|
||||
{
|
||||
UsbEndpoint mEndpoint = mUsbInterface.getEndpoint(epi);
|
||||
@@ -251,6 +251,8 @@ public class HIDDeviceManager {
|
||||
0x20d6, // PowerA
|
||||
0x24c6, // PowerA
|
||||
0x2c22, // Qanba
|
||||
0x2dc8, // 8BitDo
|
||||
0x9886, // ASTRO Gaming
|
||||
};
|
||||
|
||||
if (usbInterface.getInterfaceClass() == UsbConstants.USB_CLASS_VENDOR_SPEC &&
|
||||
@@ -271,15 +273,19 @@ 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
|
||||
0x0e6f, // PDP
|
||||
0x0f0d, // Hori
|
||||
0x10f5, // Turtle Beach
|
||||
0x1532, // Razer Wildcat
|
||||
0x20d6, // PowerA
|
||||
0x24c6, // PowerA
|
||||
0x2dc8, /* 8BitDo */
|
||||
0x2dc8, // 8BitDo
|
||||
0x2e24, // Hyperkin
|
||||
0x3537, // GameSir
|
||||
};
|
||||
|
||||
if (usbInterface.getId() == 0 &&
|
||||
@@ -353,13 +359,19 @@ public class HIDDeviceManager {
|
||||
private void initializeBluetooth() {
|
||||
Log.d(TAG, "Initializing Bluetooth");
|
||||
|
||||
if (Build.VERSION.SDK_INT <= 30 &&
|
||||
if (Build.VERSION.SDK_INT >= 31 /* Android 12 */ &&
|
||||
mContext.getPackageManager().checkPermission(android.Manifest.permission.BLUETOOTH_CONNECT, mContext.getPackageName()) != PackageManager.PERMISSION_GRANTED) {
|
||||
Log.d(TAG, "Couldn't initialize Bluetooth, missing android.permission.BLUETOOTH_CONNECT");
|
||||
return;
|
||||
}
|
||||
|
||||
if (Build.VERSION.SDK_INT <= 30 /* Android 11.0 (R) */ &&
|
||||
mContext.getPackageManager().checkPermission(android.Manifest.permission.BLUETOOTH, mContext.getPackageName()) != PackageManager.PERMISSION_GRANTED) {
|
||||
Log.d(TAG, "Couldn't initialize Bluetooth, missing android.permission.BLUETOOTH");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE) || (Build.VERSION.SDK_INT < 18)) {
|
||||
if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE) || (Build.VERSION.SDK_INT < 18 /* Android 4.3 (JELLY_BEAN_MR2) */)) {
|
||||
Log.d(TAG, "Couldn't initialize Bluetooth, this version of Android does not support Bluetooth LE");
|
||||
return;
|
||||
}
|
||||
@@ -524,7 +536,7 @@ public class HIDDeviceManager {
|
||||
for (HIDDevice device : mDevicesById.values()) {
|
||||
device.setFrozen(frozen);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -573,7 +585,7 @@ public class HIDDeviceManager {
|
||||
try {
|
||||
final int FLAG_MUTABLE = 0x02000000; // PendingIntent.FLAG_MUTABLE, but don't require SDK 31
|
||||
int flags;
|
||||
if (Build.VERSION.SDK_INT >= 31) {
|
||||
if (Build.VERSION.SDK_INT >= 31 /* Android 12.0 (S) */) {
|
||||
flags = FLAG_MUTABLE;
|
||||
} else {
|
||||
flags = 0;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -60,8 +60,8 @@ import java.util.Locale;
|
||||
public class SDLActivity extends Activity implements View.OnSystemUiVisibilityChangeListener {
|
||||
private static final String TAG = "SDL";
|
||||
private static final int SDL_MAJOR_VERSION = 2;
|
||||
private static final int SDL_MINOR_VERSION = 26;
|
||||
private static final int SDL_MICRO_VERSION = 1;
|
||||
private static final int SDL_MINOR_VERSION = 30;
|
||||
private static final int SDL_MICRO_VERSION = 2;
|
||||
/*
|
||||
// Display InputType.SOURCE/CLASS of events and devices
|
||||
//
|
||||
@@ -93,7 +93,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
||||
|
||||
s2 = s_copy & InputDevice.SOURCE_ANY; // keep source only, no class;
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
if (Build.VERSION.SDK_INT >= 23) {
|
||||
tst = InputDevice.SOURCE_BLUETOOTH_STYLUS;
|
||||
if ((s & tst) == tst) src += " BLUETOOTH_STYLUS";
|
||||
s2 &= ~tst;
|
||||
@@ -107,7 +107,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
||||
if ((s & tst) == tst) src += " GAMEPAD";
|
||||
s2 &= ~tst;
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
if (Build.VERSION.SDK_INT >= 21) {
|
||||
tst = InputDevice.SOURCE_HDMI;
|
||||
if ((s & tst) == tst) src += " HDMI";
|
||||
s2 &= ~tst;
|
||||
@@ -146,7 +146,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
||||
if ((s & tst) == tst) src += " TOUCHSCREEN";
|
||||
s2 &= ~tst;
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
|
||||
if (Build.VERSION.SDK_INT >= 18) {
|
||||
tst = InputDevice.SOURCE_TOUCH_NAVIGATION;
|
||||
if ((s & tst) == tst) src += " TOUCH_NAVIGATION";
|
||||
s2 &= ~tst;
|
||||
@@ -170,7 +170,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
||||
*/
|
||||
|
||||
public static boolean mIsResumedCalled, mHasFocus;
|
||||
public static final boolean mHasMultiWindow = (Build.VERSION.SDK_INT >= 24);
|
||||
public static final boolean mHasMultiWindow = (Build.VERSION.SDK_INT >= 24 /* Android 7.0 (N) */);
|
||||
|
||||
// Cursor types
|
||||
// private static final int SDL_SYSTEM_CURSOR_NONE = -1;
|
||||
@@ -224,9 +224,9 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
||||
|
||||
protected static SDLGenericMotionListener_API12 getMotionListener() {
|
||||
if (mMotionListener == null) {
|
||||
if (Build.VERSION.SDK_INT >= 26) {
|
||||
if (Build.VERSION.SDK_INT >= 26 /* Android 8.0 (O) */) {
|
||||
mMotionListener = new SDLGenericMotionListener_API26();
|
||||
} else if (Build.VERSION.SDK_INT >= 24) {
|
||||
} else if (Build.VERSION.SDK_INT >= 24 /* Android 7.0 (N) */) {
|
||||
mMotionListener = new SDLGenericMotionListener_API24();
|
||||
} else {
|
||||
mMotionListener = new SDLGenericMotionListener_API12();
|
||||
@@ -393,7 +393,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
||||
mHIDDeviceManager = HIDDeviceManager.acquire(this);
|
||||
|
||||
// Set up the surface
|
||||
mSurface = createSDLSurface(getApplication());
|
||||
mSurface = createSDLSurface(this);
|
||||
|
||||
mLayout = new RelativeLayout(this);
|
||||
mLayout.addView(mSurface);
|
||||
@@ -404,7 +404,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
||||
SDLActivity.onNativeOrientationChanged(mCurrentOrientation);
|
||||
|
||||
try {
|
||||
if (Build.VERSION.SDK_INT < 24) {
|
||||
if (Build.VERSION.SDK_INT < 24 /* Android 7.0 (N) */) {
|
||||
mCurrentLocale = getContext().getResources().getConfiguration().locale;
|
||||
} else {
|
||||
mCurrentLocale = getContext().getResources().getConfiguration().getLocales().get(0);
|
||||
@@ -588,6 +588,8 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
||||
mHIDDeviceManager = null;
|
||||
}
|
||||
|
||||
SDLAudioManager.release(this);
|
||||
|
||||
if (SDLActivity.mBrokenLibraries) {
|
||||
super.onDestroy();
|
||||
return;
|
||||
@@ -766,7 +768,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
||||
}
|
||||
break;
|
||||
case COMMAND_CHANGE_WINDOW_STYLE:
|
||||
if (Build.VERSION.SDK_INT >= 19) {
|
||||
if (Build.VERSION.SDK_INT >= 19 /* Android 4.4 (KITKAT) */) {
|
||||
if (context instanceof Activity) {
|
||||
Window window = ((Activity) context).getWindow();
|
||||
if (window != null) {
|
||||
@@ -841,7 +843,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
||||
msg.obj = data;
|
||||
boolean result = commandHandler.sendMessage(msg);
|
||||
|
||||
if (Build.VERSION.SDK_INT >= 19) {
|
||||
if (Build.VERSION.SDK_INT >= 19 /* Android 4.4 (KITKAT) */) {
|
||||
if (command == COMMAND_CHANGE_WINDOW_STYLE) {
|
||||
// Ensure we don't return until the resize has actually happened,
|
||||
// or 500ms have passed.
|
||||
@@ -969,15 +971,18 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
||||
/* If set, hint "explicitly controls which UI orientations are allowed". */
|
||||
if (hint.contains("LandscapeRight") && hint.contains("LandscapeLeft")) {
|
||||
orientation_landscape = ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE;
|
||||
} else if (hint.contains("LandscapeRight")) {
|
||||
orientation_landscape = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
|
||||
} else if (hint.contains("LandscapeLeft")) {
|
||||
orientation_landscape = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
|
||||
} else if (hint.contains("LandscapeRight")) {
|
||||
orientation_landscape = ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE;
|
||||
}
|
||||
|
||||
if (hint.contains("Portrait") && hint.contains("PortraitUpsideDown")) {
|
||||
/* exact match to 'Portrait' to distinguish with PortraitUpsideDown */
|
||||
boolean contains_Portrait = hint.contains("Portrait ") || hint.endsWith("Portrait");
|
||||
|
||||
if (contains_Portrait && hint.contains("PortraitUpsideDown")) {
|
||||
orientation_portrait = ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT;
|
||||
} else if (hint.contains("Portrait")) {
|
||||
} else if (contains_Portrait) {
|
||||
orientation_portrait = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
|
||||
} else if (hint.contains("PortraitUpsideDown")) {
|
||||
orientation_portrait = ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT;
|
||||
@@ -1090,7 +1095,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
||||
// thus SDK version 27. If we are in DeX mode and not API 27 or higher, as a result,
|
||||
// we should stick to relative mode.
|
||||
//
|
||||
if ((Build.VERSION.SDK_INT < 27) && isDeXMode()) {
|
||||
if (Build.VERSION.SDK_INT < 27 /* Android 8.1 (O_MR1) */ && isDeXMode()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1180,7 +1185,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
||||
* This method is called by SDL using JNI.
|
||||
*/
|
||||
public static boolean isDeXMode() {
|
||||
if (Build.VERSION.SDK_INT < 24) {
|
||||
if (Build.VERSION.SDK_INT < 24 /* Android 7.0 (N) */) {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
@@ -1340,23 +1345,6 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
||||
}
|
||||
}
|
||||
|
||||
if ((source & InputDevice.SOURCE_KEYBOARD) == InputDevice.SOURCE_KEYBOARD) {
|
||||
if (event.getAction() == KeyEvent.ACTION_DOWN) {
|
||||
if (isTextInputEvent(event)) {
|
||||
if (ic != null) {
|
||||
ic.commitText(String.valueOf((char) event.getUnicodeChar()), 1);
|
||||
} else {
|
||||
SDLInputConnection.nativeCommitText(String.valueOf((char) event.getUnicodeChar()), 1);
|
||||
}
|
||||
}
|
||||
onNativeKeyDown(keyCode);
|
||||
return true;
|
||||
} else if (event.getAction() == KeyEvent.ACTION_UP) {
|
||||
onNativeKeyUp(keyCode);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if ((source & InputDevice.SOURCE_MOUSE) == InputDevice.SOURCE_MOUSE) {
|
||||
// on some devices key events are sent for mouse BUTTON_BACK/FORWARD presses
|
||||
// they are ignored here because sending them as mouse input to SDL is messy
|
||||
@@ -1371,6 +1359,21 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
||||
}
|
||||
}
|
||||
|
||||
if (event.getAction() == KeyEvent.ACTION_DOWN) {
|
||||
if (isTextInputEvent(event)) {
|
||||
if (ic != null) {
|
||||
ic.commitText(String.valueOf((char) event.getUnicodeChar()), 1);
|
||||
} else {
|
||||
SDLInputConnection.nativeCommitText(String.valueOf((char) event.getUnicodeChar()), 1);
|
||||
}
|
||||
}
|
||||
onNativeKeyDown(keyCode);
|
||||
return true;
|
||||
} else if (event.getAction() == KeyEvent.ACTION_UP) {
|
||||
onNativeKeyUp(keyCode);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1617,7 +1620,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
||||
private final Runnable rehideSystemUi = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (Build.VERSION.SDK_INT >= 19) {
|
||||
if (Build.VERSION.SDK_INT >= 19 /* Android 4.4 (KITKAT) */) {
|
||||
int flags = View.SYSTEM_UI_FLAG_FULLSCREEN |
|
||||
View.SYSTEM_UI_FLAG_HIDE_NAVIGATION |
|
||||
View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY |
|
||||
@@ -1670,7 +1673,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
||||
Bitmap bitmap = Bitmap.createBitmap(colors, width, height, Bitmap.Config.ARGB_8888);
|
||||
++mLastCursorID;
|
||||
|
||||
if (Build.VERSION.SDK_INT >= 24) {
|
||||
if (Build.VERSION.SDK_INT >= 24 /* Android 7.0 (N) */) {
|
||||
try {
|
||||
mCursors.put(mLastCursorID, PointerIcon.create(bitmap, hotSpotX, hotSpotY));
|
||||
} catch (Exception e) {
|
||||
@@ -1686,7 +1689,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
||||
* This method is called by SDL using JNI.
|
||||
*/
|
||||
public static void destroyCustomCursor(int cursorID) {
|
||||
if (Build.VERSION.SDK_INT >= 24) {
|
||||
if (Build.VERSION.SDK_INT >= 24 /* Android 7.0 (N) */) {
|
||||
try {
|
||||
mCursors.remove(cursorID);
|
||||
} catch (Exception e) {
|
||||
@@ -1700,7 +1703,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
||||
*/
|
||||
public static boolean setCustomCursor(int cursorID) {
|
||||
|
||||
if (Build.VERSION.SDK_INT >= 24) {
|
||||
if (Build.VERSION.SDK_INT >= 24 /* Android 7.0 (N) */) {
|
||||
try {
|
||||
mSurface.setPointerIcon(mCursors.get(cursorID));
|
||||
} catch (Exception e) {
|
||||
@@ -1755,7 +1758,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
||||
cursor_type = 1002; //PointerIcon.TYPE_HAND;
|
||||
break;
|
||||
}
|
||||
if (Build.VERSION.SDK_INT >= 24) {
|
||||
if (Build.VERSION.SDK_INT >= 24 /* Android 7.0 (N) */) {
|
||||
try {
|
||||
mSurface.setPointerIcon(PointerIcon.getSystemIcon(SDL.getContext(), cursor_type));
|
||||
} catch (Exception e) {
|
||||
@@ -1769,7 +1772,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
||||
* This method is called by SDL using JNI.
|
||||
*/
|
||||
public static void requestPermission(String permission, int requestCode) {
|
||||
if (Build.VERSION.SDK_INT < 23) {
|
||||
if (Build.VERSION.SDK_INT < 23 /* Android 6.0 (M) */) {
|
||||
nativePermissionResult(requestCode, true);
|
||||
return;
|
||||
}
|
||||
@@ -1798,7 +1801,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
||||
i.setData(Uri.parse(url));
|
||||
|
||||
int flags = Intent.FLAG_ACTIVITY_NO_HISTORY | Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
|
||||
if (Build.VERSION.SDK_INT >= 21) {
|
||||
if (Build.VERSION.SDK_INT >= 21 /* Android 5.0 (LOLLIPOP) */) {
|
||||
flags |= Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
|
||||
} else {
|
||||
flags |= Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET;
|
||||
@@ -2002,6 +2005,18 @@ class SDLInputConnection extends BaseInputConnection {
|
||||
|
||||
@Override
|
||||
public boolean deleteSurroundingText(int beforeLength, int afterLength) {
|
||||
if (Build.VERSION.SDK_INT <= 29 /* Android 10.0 (Q) */) {
|
||||
// Workaround to capture backspace key. Ref: http://stackoverflow.com/questions>/14560344/android-backspace-in-webview-baseinputconnection
|
||||
// and https://bugzilla.libsdl.org/show_bug.cgi?id=2265
|
||||
if (beforeLength > 0 && afterLength == 0) {
|
||||
// backspace(s)
|
||||
while (beforeLength-- > 0) {
|
||||
nativeGenerateScancodeForUnichar('\b');
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!super.deleteSurroundingText(beforeLength, afterLength)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
package org.libsdl.app;
|
||||
|
||||
import android.content.Context;
|
||||
import android.media.AudioDeviceCallback;
|
||||
import android.media.AudioDeviceInfo;
|
||||
import android.media.AudioFormat;
|
||||
import android.media.AudioManager;
|
||||
import android.media.AudioRecord;
|
||||
@@ -8,34 +11,67 @@ import android.media.MediaRecorder;
|
||||
import android.os.Build;
|
||||
import android.util.Log;
|
||||
|
||||
public class SDLAudioManager
|
||||
{
|
||||
import java.util.Arrays;
|
||||
|
||||
public class SDLAudioManager {
|
||||
protected static final String TAG = "SDLAudio";
|
||||
|
||||
protected static AudioTrack mAudioTrack;
|
||||
protected static AudioRecord mAudioRecord;
|
||||
protected static Context mContext;
|
||||
|
||||
private static final int[] NO_DEVICES = {};
|
||||
|
||||
private static AudioDeviceCallback mAudioDeviceCallback;
|
||||
|
||||
public static void initialize() {
|
||||
mAudioTrack = null;
|
||||
mAudioRecord = null;
|
||||
mAudioDeviceCallback = null;
|
||||
|
||||
if(Build.VERSION.SDK_INT >= 24 /* Android 7.0 (N) */)
|
||||
{
|
||||
mAudioDeviceCallback = new AudioDeviceCallback() {
|
||||
@Override
|
||||
public void onAudioDevicesAdded(AudioDeviceInfo[] addedDevices) {
|
||||
Arrays.stream(addedDevices).forEach(deviceInfo -> addAudioDevice(deviceInfo.isSink(), deviceInfo.getId()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAudioDevicesRemoved(AudioDeviceInfo[] removedDevices) {
|
||||
Arrays.stream(removedDevices).forEach(deviceInfo -> removeAudioDevice(deviceInfo.isSink(), deviceInfo.getId()));
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public static void setContext(Context context) {
|
||||
mContext = context;
|
||||
if (context != null) {
|
||||
registerAudioDeviceCallback();
|
||||
}
|
||||
}
|
||||
|
||||
public static void release(Context context) {
|
||||
unregisterAudioDeviceCallback(context);
|
||||
}
|
||||
|
||||
// Audio
|
||||
|
||||
protected static String getAudioFormatString(int audioFormat) {
|
||||
switch (audioFormat) {
|
||||
case AudioFormat.ENCODING_PCM_8BIT:
|
||||
return "8-bit";
|
||||
case AudioFormat.ENCODING_PCM_16BIT:
|
||||
return "16-bit";
|
||||
case AudioFormat.ENCODING_PCM_FLOAT:
|
||||
return "float";
|
||||
default:
|
||||
return Integer.toString(audioFormat);
|
||||
case AudioFormat.ENCODING_PCM_8BIT:
|
||||
return "8-bit";
|
||||
case AudioFormat.ENCODING_PCM_16BIT:
|
||||
return "16-bit";
|
||||
case AudioFormat.ENCODING_PCM_FLOAT:
|
||||
return "float";
|
||||
default:
|
||||
return Integer.toString(audioFormat);
|
||||
}
|
||||
}
|
||||
|
||||
protected static int[] open(boolean isCapture, int sampleRate, int audioFormat, int desiredChannels, int desiredFrames) {
|
||||
protected static int[] open(boolean isCapture, int sampleRate, int audioFormat, int desiredChannels, int desiredFrames, int deviceId) {
|
||||
int channelConfig;
|
||||
int sampleSize;
|
||||
int frameSize;
|
||||
@@ -43,14 +79,14 @@ public class SDLAudioManager
|
||||
Log.v(TAG, "Opening " + (isCapture ? "capture" : "playback") + ", requested " + desiredFrames + " frames of " + desiredChannels + " channel " + getAudioFormatString(audioFormat) + " audio at " + sampleRate + " Hz");
|
||||
|
||||
/* On older devices let's use known good settings */
|
||||
if (Build.VERSION.SDK_INT < 21) {
|
||||
if (Build.VERSION.SDK_INT < 21 /* Android 5.0 (LOLLIPOP) */) {
|
||||
if (desiredChannels > 2) {
|
||||
desiredChannels = 2;
|
||||
}
|
||||
}
|
||||
|
||||
/* AudioTrack has sample rate limitation of 48000 (fixed in 5.0.2) */
|
||||
if (Build.VERSION.SDK_INT < 22) {
|
||||
if (Build.VERSION.SDK_INT < 22 /* Android 5.1 (LOLLIPOP_MR1) */) {
|
||||
if (sampleRate < 8000) {
|
||||
sampleRate = 8000;
|
||||
} else if (sampleRate > 48000) {
|
||||
@@ -59,7 +95,7 @@ public class SDLAudioManager
|
||||
}
|
||||
|
||||
if (audioFormat == AudioFormat.ENCODING_PCM_FLOAT) {
|
||||
int minSDKVersion = (isCapture ? 23 : 21);
|
||||
int minSDKVersion = (isCapture ? 23 /* Android 6.0 (M) */ : 21 /* Android 5.0 (LOLLIPOP) */);
|
||||
if (Build.VERSION.SDK_INT < minSDKVersion) {
|
||||
audioFormat = AudioFormat.ENCODING_PCM_16BIT;
|
||||
}
|
||||
@@ -120,7 +156,7 @@ public class SDLAudioManager
|
||||
channelConfig = AudioFormat.CHANNEL_OUT_5POINT1 | AudioFormat.CHANNEL_OUT_BACK_CENTER;
|
||||
break;
|
||||
case 8:
|
||||
if (Build.VERSION.SDK_INT >= 23) {
|
||||
if (Build.VERSION.SDK_INT >= 23 /* Android 6.0 (M) */) {
|
||||
channelConfig = AudioFormat.CHANNEL_OUT_7POINT1_SURROUND;
|
||||
} else {
|
||||
Log.v(TAG, "Requested " + desiredChannels + " channels, getting 5.1 surround");
|
||||
@@ -201,6 +237,10 @@ public class SDLAudioManager
|
||||
return null;
|
||||
}
|
||||
|
||||
if (Build.VERSION.SDK_INT >= 24 /* Android 7.0 (N) */ && deviceId != 0) {
|
||||
mAudioRecord.setPreferredDevice(getOutputAudioDeviceInfo(deviceId));
|
||||
}
|
||||
|
||||
mAudioRecord.startRecording();
|
||||
}
|
||||
|
||||
@@ -224,6 +264,10 @@ public class SDLAudioManager
|
||||
return null;
|
||||
}
|
||||
|
||||
if (Build.VERSION.SDK_INT >= 24 /* Android 7.0 (N) */ && deviceId != 0) {
|
||||
mAudioTrack.setPreferredDevice(getInputAudioDeviceInfo(deviceId));
|
||||
}
|
||||
|
||||
mAudioTrack.play();
|
||||
}
|
||||
|
||||
@@ -238,11 +282,73 @@ public class SDLAudioManager
|
||||
return results;
|
||||
}
|
||||
|
||||
private static AudioDeviceInfo getInputAudioDeviceInfo(int deviceId) {
|
||||
if (Build.VERSION.SDK_INT >= 24 /* Android 7.0 (N) */) {
|
||||
AudioManager audioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
|
||||
return Arrays.stream(audioManager.getDevices(AudioManager.GET_DEVICES_INPUTS))
|
||||
.filter(deviceInfo -> deviceInfo.getId() == deviceId)
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static AudioDeviceInfo getOutputAudioDeviceInfo(int deviceId) {
|
||||
if (Build.VERSION.SDK_INT >= 24 /* Android 7.0 (N) */) {
|
||||
AudioManager audioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
|
||||
return Arrays.stream(audioManager.getDevices(AudioManager.GET_DEVICES_OUTPUTS))
|
||||
.filter(deviceInfo -> deviceInfo.getId() == deviceId)
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static void registerAudioDeviceCallback() {
|
||||
if (Build.VERSION.SDK_INT >= 24 /* Android 7.0 (N) */) {
|
||||
AudioManager audioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
|
||||
audioManager.registerAudioDeviceCallback(mAudioDeviceCallback, null);
|
||||
}
|
||||
}
|
||||
|
||||
private static void unregisterAudioDeviceCallback(Context context) {
|
||||
if (Build.VERSION.SDK_INT >= 24 /* Android 7.0 (N) */) {
|
||||
AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
|
||||
audioManager.unregisterAudioDeviceCallback(mAudioDeviceCallback);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called by SDL using JNI.
|
||||
*/
|
||||
public static int[] audioOpen(int sampleRate, int audioFormat, int desiredChannels, int desiredFrames) {
|
||||
return open(false, sampleRate, audioFormat, desiredChannels, desiredFrames);
|
||||
public static int[] getAudioOutputDevices() {
|
||||
if (Build.VERSION.SDK_INT >= 24 /* Android 7.0 (N) */) {
|
||||
AudioManager audioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
|
||||
return Arrays.stream(audioManager.getDevices(AudioManager.GET_DEVICES_OUTPUTS)).mapToInt(AudioDeviceInfo::getId).toArray();
|
||||
} else {
|
||||
return NO_DEVICES;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called by SDL using JNI.
|
||||
*/
|
||||
public static int[] getAudioInputDevices() {
|
||||
if (Build.VERSION.SDK_INT >= 24 /* Android 7.0 (N) */) {
|
||||
AudioManager audioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
|
||||
return Arrays.stream(audioManager.getDevices(AudioManager.GET_DEVICES_INPUTS)).mapToInt(AudioDeviceInfo::getId).toArray();
|
||||
} else {
|
||||
return NO_DEVICES;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called by SDL using JNI.
|
||||
*/
|
||||
public static int[] audioOpen(int sampleRate, int audioFormat, int desiredChannels, int desiredFrames, int deviceId) {
|
||||
return open(false, sampleRate, audioFormat, desiredChannels, desiredFrames, deviceId);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -254,6 +360,11 @@ public class SDLAudioManager
|
||||
return;
|
||||
}
|
||||
|
||||
if (android.os.Build.VERSION.SDK_INT < 21 /* Android 5.0 (LOLLIPOP) */) {
|
||||
Log.e(TAG, "Attempted to make an incompatible audio call with uninitialized audio! (floating-point output is supported since Android 5.0 Lollipop)");
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < buffer.length;) {
|
||||
int result = mAudioTrack.write(buffer, i, buffer.length - i, AudioTrack.WRITE_BLOCKING);
|
||||
if (result > 0) {
|
||||
@@ -326,18 +437,22 @@ public class SDLAudioManager
|
||||
/**
|
||||
* This method is called by SDL using JNI.
|
||||
*/
|
||||
public static int[] captureOpen(int sampleRate, int audioFormat, int desiredChannels, int desiredFrames) {
|
||||
return open(true, sampleRate, audioFormat, desiredChannels, desiredFrames);
|
||||
public static int[] captureOpen(int sampleRate, int audioFormat, int desiredChannels, int desiredFrames, int deviceId) {
|
||||
return open(true, sampleRate, audioFormat, desiredChannels, desiredFrames, deviceId);
|
||||
}
|
||||
|
||||
/** This method is called by SDL using JNI. */
|
||||
public static int captureReadFloatBuffer(float[] buffer, boolean blocking) {
|
||||
return mAudioRecord.read(buffer, 0, buffer.length, blocking ? AudioRecord.READ_BLOCKING : AudioRecord.READ_NON_BLOCKING);
|
||||
if (Build.VERSION.SDK_INT < 23 /* Android 6.0 (M) */) {
|
||||
return 0;
|
||||
} else {
|
||||
return mAudioRecord.read(buffer, 0, buffer.length, blocking ? AudioRecord.READ_BLOCKING : AudioRecord.READ_NON_BLOCKING);
|
||||
}
|
||||
}
|
||||
|
||||
/** This method is called by SDL using JNI. */
|
||||
public static int captureReadShortBuffer(short[] buffer, boolean blocking) {
|
||||
if (Build.VERSION.SDK_INT < 23) {
|
||||
if (Build.VERSION.SDK_INT < 23 /* Android 6.0 (M) */) {
|
||||
return mAudioRecord.read(buffer, 0, buffer.length);
|
||||
} else {
|
||||
return mAudioRecord.read(buffer, 0, buffer.length, blocking ? AudioRecord.READ_BLOCKING : AudioRecord.READ_NON_BLOCKING);
|
||||
@@ -346,7 +461,7 @@ public class SDLAudioManager
|
||||
|
||||
/** This method is called by SDL using JNI. */
|
||||
public static int captureReadByteBuffer(byte[] buffer, boolean blocking) {
|
||||
if (Build.VERSION.SDK_INT < 23) {
|
||||
if (Build.VERSION.SDK_INT < 23 /* Android 6.0 (M) */) {
|
||||
return mAudioRecord.read(buffer, 0, buffer.length);
|
||||
} else {
|
||||
return mAudioRecord.read(buffer, 0, buffer.length, blocking ? AudioRecord.READ_BLOCKING : AudioRecord.READ_NON_BLOCKING);
|
||||
@@ -391,4 +506,9 @@ public class SDLAudioManager
|
||||
}
|
||||
|
||||
public static native int nativeSetupJNI();
|
||||
|
||||
public static native void removeAudioDevice(boolean isCapture, int deviceId);
|
||||
|
||||
public static native void addAudioDevice(boolean isCapture, int deviceId);
|
||||
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ public class SDLControllerManager
|
||||
public static native int nativeAddJoystick(int device_id, String name, String desc,
|
||||
int vendor_id, int product_id,
|
||||
boolean is_accelerometer, int button_mask,
|
||||
int naxes, int nhats, int nballs);
|
||||
int naxes, int axis_mask, int nhats, int nballs);
|
||||
public static native int nativeRemoveJoystick(int device_id);
|
||||
public static native int nativeAddHaptic(int device_id, String name);
|
||||
public static native int nativeRemoveHaptic(int device_id);
|
||||
@@ -42,7 +42,7 @@ public class SDLControllerManager
|
||||
|
||||
public static void initialize() {
|
||||
if (mJoystickHandler == null) {
|
||||
if (Build.VERSION.SDK_INT >= 19) {
|
||||
if (Build.VERSION.SDK_INT >= 19 /* Android 4.4 (KITKAT) */) {
|
||||
mJoystickHandler = new SDLJoystickHandler_API19();
|
||||
} else {
|
||||
mJoystickHandler = new SDLJoystickHandler_API16();
|
||||
@@ -50,7 +50,7 @@ public class SDLControllerManager
|
||||
}
|
||||
|
||||
if (mHapticHandler == null) {
|
||||
if (Build.VERSION.SDK_INT >= 26) {
|
||||
if (Build.VERSION.SDK_INT >= 26 /* Android 8.0 (O) */) {
|
||||
mHapticHandler = new SDLHapticHandler_API26();
|
||||
} else {
|
||||
mHapticHandler = new SDLHapticHandler();
|
||||
@@ -168,6 +168,32 @@ class SDLJoystickHandler_API16 extends SDLJoystickHandler {
|
||||
arg1Axis = MotionEvent.AXIS_GAS;
|
||||
}
|
||||
|
||||
// Make sure the AXIS_Z is sorted between AXIS_RY and AXIS_RZ.
|
||||
// This is because the usual pairing are:
|
||||
// - AXIS_X + AXIS_Y (left stick).
|
||||
// - AXIS_RX, AXIS_RY (sometimes the right stick, sometimes triggers).
|
||||
// - AXIS_Z, AXIS_RZ (sometimes the right stick, sometimes triggers).
|
||||
// This sorts the axes in the above order, which tends to be correct
|
||||
// for Xbox-ish game pads that have the right stick on RX/RY and the
|
||||
// triggers on Z/RZ.
|
||||
//
|
||||
// Gamepads that don't have AXIS_Z/AXIS_RZ but use
|
||||
// AXIS_LTRIGGER/AXIS_RTRIGGER are unaffected by this.
|
||||
//
|
||||
// References:
|
||||
// - https://developer.android.com/develop/ui/views/touch-and-input/game-controllers/controller-input
|
||||
// - https://www.kernel.org/doc/html/latest/input/gamepad.html
|
||||
if (arg0Axis == MotionEvent.AXIS_Z) {
|
||||
arg0Axis = MotionEvent.AXIS_RZ - 1;
|
||||
} else if (arg0Axis > MotionEvent.AXIS_Z && arg0Axis < MotionEvent.AXIS_RZ) {
|
||||
--arg0Axis;
|
||||
}
|
||||
if (arg1Axis == MotionEvent.AXIS_Z) {
|
||||
arg1Axis = MotionEvent.AXIS_RZ - 1;
|
||||
} else if (arg1Axis > MotionEvent.AXIS_Z && arg1Axis < MotionEvent.AXIS_RZ) {
|
||||
--arg1Axis;
|
||||
}
|
||||
|
||||
return arg0Axis - arg1Axis;
|
||||
}
|
||||
}
|
||||
@@ -210,7 +236,7 @@ class SDLJoystickHandler_API16 extends SDLJoystickHandler {
|
||||
mJoysticks.add(joystick);
|
||||
SDLControllerManager.nativeAddJoystick(joystick.device_id, joystick.name, joystick.desc,
|
||||
getVendorId(joystickDevice), getProductId(joystickDevice), false,
|
||||
getButtonMask(joystickDevice), joystick.axes.size(), joystick.hats.size()/2, 0);
|
||||
getButtonMask(joystickDevice), joystick.axes.size(), getAxisMask(joystick.axes), joystick.hats.size()/2, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -291,6 +317,9 @@ class SDLJoystickHandler_API16 extends SDLJoystickHandler {
|
||||
public int getVendorId(InputDevice joystickDevice) {
|
||||
return 0;
|
||||
}
|
||||
public int getAxisMask(List<InputDevice.MotionRange> ranges) {
|
||||
return -1;
|
||||
}
|
||||
public int getButtonMask(InputDevice joystickDevice) {
|
||||
return -1;
|
||||
}
|
||||
@@ -308,6 +337,43 @@ class SDLJoystickHandler_API19 extends SDLJoystickHandler_API16 {
|
||||
return joystickDevice.getVendorId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAxisMask(List<InputDevice.MotionRange> ranges) {
|
||||
// For compatibility, keep computing the axis mask like before,
|
||||
// only really distinguishing 2, 4 and 6 axes.
|
||||
int axis_mask = 0;
|
||||
if (ranges.size() >= 2) {
|
||||
// ((1 << SDL_GAMEPAD_AXIS_LEFTX) | (1 << SDL_GAMEPAD_AXIS_LEFTY))
|
||||
axis_mask |= 0x0003;
|
||||
}
|
||||
if (ranges.size() >= 4) {
|
||||
// ((1 << SDL_GAMEPAD_AXIS_RIGHTX) | (1 << SDL_GAMEPAD_AXIS_RIGHTY))
|
||||
axis_mask |= 0x000c;
|
||||
}
|
||||
if (ranges.size() >= 6) {
|
||||
// ((1 << SDL_GAMEPAD_AXIS_LEFT_TRIGGER) | (1 << SDL_GAMEPAD_AXIS_RIGHT_TRIGGER))
|
||||
axis_mask |= 0x0030;
|
||||
}
|
||||
// Also add an indicator bit for whether the sorting order has changed.
|
||||
// This serves to disable outdated gamecontrollerdb.txt mappings.
|
||||
boolean have_z = false;
|
||||
boolean have_past_z_before_rz = false;
|
||||
for (InputDevice.MotionRange range : ranges) {
|
||||
int axis = range.getAxis();
|
||||
if (axis == MotionEvent.AXIS_Z) {
|
||||
have_z = true;
|
||||
} else if (axis > MotionEvent.AXIS_Z && axis < MotionEvent.AXIS_RZ) {
|
||||
have_past_z_before_rz = true;
|
||||
}
|
||||
}
|
||||
if (have_z && have_past_z_before_rz) {
|
||||
// If both these exist, the compare() function changed sorting order.
|
||||
// Set a bit to indicate this fact.
|
||||
axis_mask |= 0x8000;
|
||||
}
|
||||
return axis_mask;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getButtonMask(InputDevice joystickDevice) {
|
||||
int button_mask = 0;
|
||||
@@ -480,13 +546,15 @@ class SDLHapticHandler {
|
||||
if (haptic == null) {
|
||||
InputDevice device = InputDevice.getDevice(deviceIds[i]);
|
||||
Vibrator vib = device.getVibrator();
|
||||
if (vib.hasVibrator()) {
|
||||
haptic = new SDLHaptic();
|
||||
haptic.device_id = deviceIds[i];
|
||||
haptic.name = device.getName();
|
||||
haptic.vib = vib;
|
||||
mHaptics.add(haptic);
|
||||
SDLControllerManager.nativeAddHaptic(haptic.device_id, haptic.name);
|
||||
if (vib != null) {
|
||||
if (vib.hasVibrator()) {
|
||||
haptic = new SDLHaptic();
|
||||
haptic.device_id = deviceIds[i];
|
||||
haptic.name = device.getName();
|
||||
haptic.vib = vib;
|
||||
mHaptics.add(haptic);
|
||||
SDLControllerManager.nativeAddHaptic(haptic.device_id, haptic.name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -743,7 +811,7 @@ class SDLGenericMotionListener_API26 extends SDLGenericMotionListener_API24 {
|
||||
|
||||
@Override
|
||||
public boolean supportsRelativeMouse() {
|
||||
return (!SDLActivity.isDeXMode() || (Build.VERSION.SDK_INT >= 27));
|
||||
return (!SDLActivity.isDeXMode() || Build.VERSION.SDK_INT >= 27 /* Android 8.1 (O_MR1) */);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -753,7 +821,7 @@ class SDLGenericMotionListener_API26 extends SDLGenericMotionListener_API24 {
|
||||
|
||||
@Override
|
||||
public boolean setRelativeMouseEnabled(boolean enabled) {
|
||||
if (!SDLActivity.isDeXMode() || (Build.VERSION.SDK_INT >= 27)) {
|
||||
if (!SDLActivity.isDeXMode() || Build.VERSION.SDK_INT >= 27 /* Android 8.1 (O_MR1) */) {
|
||||
if (enabled) {
|
||||
SDLActivity.getContentView().requestPointerCapture();
|
||||
} else {
|
||||
|
||||
@@ -116,7 +116,7 @@ public class SDLSurface extends SurfaceView implements SurfaceHolder.Callback,
|
||||
int nDeviceHeight = height;
|
||||
try
|
||||
{
|
||||
if (Build.VERSION.SDK_INT >= 17) {
|
||||
if (Build.VERSION.SDK_INT >= 17 /* Android 4.2 (JELLY_BEAN_MR1) */) {
|
||||
DisplayMetrics realMetrics = new DisplayMetrics();
|
||||
mDisplay.getRealMetrics( realMetrics );
|
||||
nDeviceWidth = realMetrics.widthPixels;
|
||||
@@ -163,7 +163,7 @@ public class SDLSurface extends SurfaceView implements SurfaceHolder.Callback,
|
||||
|
||||
// Don't skip in MultiWindow.
|
||||
if (skip) {
|
||||
if (Build.VERSION.SDK_INT >= 24) {
|
||||
if (Build.VERSION.SDK_INT >= 24 /* Android 7.0 (N) */) {
|
||||
if (SDLActivity.mSingleton.isInMultiWindowMode()) {
|
||||
Log.v("SDL", "Don't skip in Multi-Window");
|
||||
skip = false;
|
||||
|
||||
@@ -7,7 +7,7 @@ buildscript {
|
||||
google()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:7.3.1'
|
||||
classpath 'com.android.tools.build:gradle:8.1.1'
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||
|
||||
// NOTE: Do not place your application dependencies here; they belong
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
#Thu Nov 11 18:20:34 PST 2021
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.1.1-bin.zip
|
||||
distributionPath=wrapper/dists
|
||||
zipStorePath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
|
||||
Vendored
+2
-2
@@ -126,8 +126,8 @@ if $cygwin ; then
|
||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||
i=0
|
||||
for arg in "$@" ; do
|
||||
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
||||
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
||||
CHECK=`echo "$arg"|grep -E -c "$OURCYGPATTERN" -`
|
||||
CHECK2=`echo "$arg"|grep -E -c "^-"` ### Determine if an option
|
||||
|
||||
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
||||
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
||||
|
||||
+2
-11
@@ -1,15 +1,8 @@
|
||||
#cmakedefine PACKAGE "@PACKAGE@"
|
||||
#define VERSION "2.9.0"
|
||||
|
||||
#cmakedefine CMAKE_SYSTEM_NAME "@CMAKE_SYSTEM_NAME@"
|
||||
#define VERSION "2.11.3"
|
||||
|
||||
#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@
|
||||
@@ -17,9 +10,8 @@
|
||||
#cmakedefine ENABLE_MIDI_SEQMIDI @ENABLE_MIDI_SEQMIDI@
|
||||
#cmakedefine ENABLE_MIDI_PORTMIDI @ENABLE_MIDI_PORTMIDI@
|
||||
#cmakedefine ENABLE_NLS @ENABLE_NLS@
|
||||
#cmakedefine ENABLE_SDLMIXER @ENABLE_SDLMIXER@
|
||||
|
||||
#cmakedefine CDROM_DEVICE "@CDROM_DEVICE@"
|
||||
#cmakedefine DEFAULT_PLAYLIST_PATH "@DEFAULT_PLAYLIST_PATH@"
|
||||
#cmakedefine JOY_DEVICE "@JOY_DEVICE@"
|
||||
#cmakedefine MIDI_DEVICE "@MIDI_DEVICE@"
|
||||
#cmakedefine SEQ_DEVICE "@SEQ_DEVICE@"
|
||||
@@ -27,7 +19,6 @@
|
||||
#cmakedefine HAVE_GETLOGIN @HAVE_GETLOGIN@
|
||||
#cmakedefine HAVE_MMAP @HAVE_MMAP@
|
||||
#cmakedefine HAVE_SIGACTION @HAVE_SIGACTION@
|
||||
#cmakedefine HAVE_UNAME @HAVE_UNAME@
|
||||
#cmakedefine HAVE_WEBP @HAVE_WEBP@
|
||||
|
||||
#define DEFAULT_GOTHIC_TTF "@DEFAULT_FONT_PATH@MTLc3m.ttf"
|
||||
|
||||
@@ -22,7 +22,7 @@ Game Compatibility
|
||||
| DALK | Supported | From ALICEの館4・5・6 |
|
||||
| 闘神都市 | Supported | From ALICEの館4・5・6 |
|
||||
| Dr.STOP | Supported | From ALICEの館4・5・6 |
|
||||
| 人間狩り | Unsupported | From ALICEの館4・5・6 / アリスCD |
|
||||
| 人間狩り | Supported | From ALICEの館4・5・6 / アリスCD |
|
||||
| 女の子図鑑 | Unknown | From ALICEの館4・5・6 |
|
||||
| 恋のおわり | Unknown | |
|
||||
| 王道勇者 | Supported | |
|
||||
@@ -71,13 +71,13 @@ Game Compatibility
|
||||
| [扉] | Supported | From アリスCD |
|
||||
| 叩き殺し太郎 | Supported | From アリスCD |
|
||||
| バルーンぽっぷ | Supported | From アリスCD |
|
||||
| 高速ひよこ2 | Unsupported | From アリスCD |
|
||||
| 高速ひよこ2 | Supported | From アリスCD |
|
||||
| おせろっと | Supported | From アリスCD |
|
||||
| マスカレイド | Supported | From アリスCD |
|
||||
| キャロル ~聖なる鐘が響く夜~ | Supported | From アリスCD, Online match is not supported |
|
||||
| できるかなー? | Supported | From アリスCD |
|
||||
| Child Assassin | Supported | From アリスCD |
|
||||
| Child Assassin | Unsupported | From アリスCD |
|
||||
| Klavier | Supported | From アリスCD |
|
||||
| 弱肉狂食 | Unsupported | From アリスCD |
|
||||
| 弱肉狂食 | Supported | From アリスCD |
|
||||
| 眼鏡大戦2 | Supported | From アリスCD |
|
||||
| 妄想くん | Supported | From アリスCD |
|
||||
|
||||
+3
-16
@@ -98,20 +98,7 @@ endif()
|
||||
|
||||
target_compile_options(modules PRIVATE -Wno-pointer-sign)
|
||||
|
||||
if (EMSCRIPTEN)
|
||||
set(LIBS
|
||||
"SHELL:-s USE_ZLIB=1"
|
||||
"SHELL:-s USE_SDL=2")
|
||||
target_compile_options(modules PRIVATE ${LIBS})
|
||||
target_link_options(modules PRIVATE ${LIBS})
|
||||
elseif (ANDROID)
|
||||
target_link_libraries(modules PRIVATE ${ndk_zlib})
|
||||
if (SDL2MIXER_FOUND)
|
||||
target_link_libraries(modules PRIVATE SDL2 SDL2_mixer)
|
||||
endif()
|
||||
else()
|
||||
target_link_libraries(modules PRIVATE ZLIB::ZLIB)
|
||||
if (SDL2MIXER_FOUND)
|
||||
target_link_libraries(modules PRIVATE PkgConfig::SDL2MIXER)
|
||||
endif()
|
||||
target_link_libraries(modules PRIVATE sdl2 zlib)
|
||||
if (TARGET sdl2_mixer)
|
||||
target_link_libraries(modules PRIVATE sdl2_mixer)
|
||||
endif()
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
#include "menu.h"
|
||||
#include "input.h"
|
||||
#include "nact.h"
|
||||
#include "key.h"
|
||||
#include "night.h"
|
||||
#include "sprite.h"
|
||||
|
||||
|
||||
@@ -33,7 +33,6 @@
|
||||
#include "menu.h"
|
||||
#include "input.h"
|
||||
#include "nact.h"
|
||||
#include "key.h"
|
||||
#include "sact.h"
|
||||
#include "sprite.h"
|
||||
#include "ngraph.h"
|
||||
|
||||
@@ -34,7 +34,6 @@
|
||||
#include "menu.h"
|
||||
#include "input.h"
|
||||
#include "nact.h"
|
||||
#include "key.h"
|
||||
#include "sact.h"
|
||||
#include "sprite.h"
|
||||
#include "sactsound.h"
|
||||
@@ -389,7 +388,7 @@ static void cb_waitkey_backlog(agsevent_t *e) {
|
||||
switch (e->type) {
|
||||
case AGSEVENT_KEY_RELEASE:
|
||||
switch (e->code) {
|
||||
case KEY_ESC:
|
||||
case KEY_ESCAPE:
|
||||
sblog_end();
|
||||
sact.waittype = KEYWAIT_MESSAGE;
|
||||
break;
|
||||
|
||||
@@ -31,7 +31,6 @@
|
||||
#include "nact.h"
|
||||
#include "ags.h"
|
||||
#include "input.h"
|
||||
#include "key.h"
|
||||
#include "sact.h"
|
||||
#include "sprite.h"
|
||||
#include "ngraph.h"
|
||||
@@ -198,8 +197,10 @@ static void setup_selwindow() {
|
||||
|
||||
// デフォルトで選択される選択肢がある場合、そこへカーソルを移動
|
||||
if (sact.sel.movecursor) {
|
||||
ags_setCursorLocation(sp->cur.x + sact.sel.frame_dot + 2,
|
||||
sp->cur.y + sact.sel.frame_dot + 2 + (sact.sel.font_size + sact.sel.linespace)*(sact.sel.movecursor -1), TRUE);
|
||||
int x = sp->cur.x + sact.sel.frame_dot + 2;
|
||||
int y = sp->cur.y + sact.sel.frame_dot + 2 +
|
||||
(sact.sel.font_size + sact.sel.linespace) * (sact.sel.movecursor - 1);
|
||||
ags_setCursorLocation(x, y, true, true);
|
||||
selected_item = (sact.sel.movecursor -1);
|
||||
oldstate = TRUE;
|
||||
oldindex = selected_item -1;
|
||||
|
||||
@@ -1306,7 +1306,7 @@ static void ChangeSecretArray(void) { /* 53 */
|
||||
(*vAry) ^= ax; ax = (key[i&3] ^ *vAry);
|
||||
j ^= ax;
|
||||
if (i & 2) {
|
||||
ax = !ax ^ (i*3);
|
||||
ax = ~ax ^ (i*3);
|
||||
}
|
||||
if (i & 4) {
|
||||
ax = (ax >> 4) | (ax << 12);
|
||||
@@ -1328,13 +1328,12 @@ static void ChangeSecretArray(void) { /* 53 */
|
||||
*vAry ^= ax; ax = (key[i&3] ^ k);
|
||||
j ^= ax;
|
||||
if (i & 2) {
|
||||
ax = !ax ^ (i*3);
|
||||
ax = ~ax ^ (i*3);
|
||||
}
|
||||
if (i & 4) {
|
||||
ax = (ax >> 4) | (ax << 12);
|
||||
}
|
||||
vAry++;
|
||||
|
||||
}
|
||||
*vResult = j;
|
||||
}
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
#include "ags.h"
|
||||
#include "music.h"
|
||||
#include "sdl_core.h"
|
||||
#include "hacks.h"
|
||||
|
||||
#define SLOT 40
|
||||
|
||||
@@ -166,14 +167,14 @@ static void ChangeNotColor() {
|
||||
case 24:
|
||||
case 32:
|
||||
{
|
||||
uint32_t pic24s = PIX24(*src, *(src+1), *(src+2)) & 0xf0f0f0;
|
||||
uint32_t pic24d = PIX24(*dst, *(dst+1), *(dst+2)) & 0xf0f0f0;
|
||||
uint32_t pic24s = PIX24(*src, *(src+1), *(src+2));
|
||||
uint32_t pic24d = PIX24(*dst, *(dst+1), *(dst+2));
|
||||
uint32_t *yl;
|
||||
|
||||
for (y = 0; y < height; y++) {
|
||||
yl = (uint32_t *)(dp + y * dib->bytes_per_line);
|
||||
for (x = 0; x < width; x++) {
|
||||
if ((*yl & 0xf0f0f0) != pic24s) {
|
||||
if (*yl != pic24s) {
|
||||
*yl = pic24d;
|
||||
}
|
||||
yl++;
|
||||
@@ -182,6 +183,9 @@ static void ChangeNotColor() {
|
||||
break;
|
||||
}
|
||||
}
|
||||
// The CX command after ChangeNotColor (in FIGHT.ADV) must use a precise
|
||||
// calculation.
|
||||
daiakuji_cx_hack = true;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -585,14 +589,14 @@ static void copy_sprite(int sx, int sy, int width, int height, int dx, int dy, i
|
||||
case 24:
|
||||
case 32:
|
||||
{
|
||||
uint32_t pic24 = PIX24(r, g, b) & 0xf0f0f0;
|
||||
uint32_t pic24 = PIX24(r, g, b);
|
||||
uint32_t *yls, *yld;
|
||||
|
||||
for (y = 0; y < height; y++) {
|
||||
yls = (uint32_t *)(sp + y * dib->bytes_per_line);
|
||||
yld = (uint32_t *)(dp + y * dib->bytes_per_line);
|
||||
for (x = 0; x < width; x++) {
|
||||
if ((*yls & 0xf0f0f0) != pic24) {
|
||||
if (*yls != pic24) {
|
||||
*yld = *yls;
|
||||
}
|
||||
yls++; yld++;
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
#include "modules.h"
|
||||
#include "sdl_core.h"
|
||||
#include "sdl_private.h"
|
||||
#include "input.h"
|
||||
#include "menu.h"
|
||||
|
||||
// キー変換テーブル
|
||||
@@ -162,7 +163,7 @@ static void GetKeyStatus(void) {
|
||||
}
|
||||
|
||||
*var = 0;
|
||||
for (i = 0; i < 256; i++) {
|
||||
for (i = 0; i < NUM_KEYCODES; i++) {
|
||||
*var |= (keymap[no -1][i] * RawKeyInfo[i]);
|
||||
}
|
||||
|
||||
|
||||
@@ -140,7 +140,7 @@ void gr_drawimage16(surface_t *ds, cgdata *cg, int x, int y) {
|
||||
yl = (uint32_t *)(dp + y * ds->bytes_per_line);
|
||||
for (x = 0; x < dw; x++) {
|
||||
pic16 = *sp;
|
||||
*yl = PIX24(PIXR16(pic16), PIXG16(pic16), PIXB16(pic16));
|
||||
*yl = rgb565_to_rgb888(pic16);
|
||||
yl++; sp++;
|
||||
}
|
||||
sp += (cg->width - dw);
|
||||
|
||||
+130
-84
@@ -11,6 +11,9 @@ if (ANDROID)
|
||||
add_library(xsystem35 SHARED)
|
||||
else()
|
||||
add_executable(xsystem35)
|
||||
if (WIN32)
|
||||
target_link_options(xsystem35 PRIVATE -static)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
target_compile_options(xsystem35 PRIVATE -Wno-pointer-sign $<$<CONFIG:Debug>:-Wall>)
|
||||
@@ -18,114 +21,164 @@ target_include_directories(xsystem35 PRIVATE .)
|
||||
target_link_libraries(xsystem35 PRIVATE src_lib)
|
||||
|
||||
target_sources(xsystem35 PRIVATE
|
||||
xsystem35.c
|
||||
dri.c
|
||||
ags.c
|
||||
ald_manager.c
|
||||
alpha_plane.c
|
||||
bgi.c
|
||||
bmp.c
|
||||
cache.c
|
||||
${SRC_AUDIO}
|
||||
${SRC_CDROM}
|
||||
${SRC_MIDI}
|
||||
${SRC_MENU})
|
||||
cali.c
|
||||
cdrom.bgm.c
|
||||
cg.c
|
||||
cmd2F.c
|
||||
cmd2F60.c
|
||||
cmd_check.c
|
||||
cmdb.c
|
||||
cmdc.c
|
||||
cmdd.c
|
||||
cmde.c
|
||||
cmdf.c
|
||||
cmdg.c
|
||||
cmdh.c
|
||||
cmdi.c
|
||||
cmdj.c
|
||||
cmdk.c
|
||||
cmdl.c
|
||||
cmdm.c
|
||||
cmdn.c
|
||||
cmdo.c
|
||||
cmdp.c
|
||||
cmdq.c
|
||||
cmds.c
|
||||
cmdt.c
|
||||
cmdu.c
|
||||
cmdv.c
|
||||
cmdw.c
|
||||
cmdy.c
|
||||
cmdz.c
|
||||
cursor.c
|
||||
dri.c
|
||||
ecopy.c
|
||||
filecheck.c
|
||||
font.c
|
||||
hacks.c
|
||||
image.c
|
||||
input.c
|
||||
jpeg.c
|
||||
message.c
|
||||
midi.c
|
||||
mmap.c
|
||||
msgskip.c
|
||||
mt19937-1.c
|
||||
music.c
|
||||
music_cdrom.c
|
||||
music_midi.c
|
||||
nact.c
|
||||
network.c
|
||||
pms.c
|
||||
profile.c
|
||||
qnt.c
|
||||
s39ain.c
|
||||
savedata.c
|
||||
scenario.c
|
||||
sdl_cursor.c
|
||||
sdl_draw.c
|
||||
sdl_effect.c
|
||||
sdl_event.c
|
||||
sdl_image.c
|
||||
sdl_video.c
|
||||
selection.c
|
||||
texthook.c
|
||||
variable.c
|
||||
vsp.c
|
||||
xsystem35.c
|
||||
)
|
||||
|
||||
# System3.x commands
|
||||
target_sources(xsystem35 PRIVATE
|
||||
cmdb.c cmdc.c cmdd.c cmde.c cmdf.c cmdg.c cmdh.c cmdi.c cmdj.c
|
||||
cmdk.c cmdl.c cmdm.c cmdn.c cmdo.c cmdp.c cmdq.c cmds.c cmdt.c
|
||||
cmdu.c cmdv.c cmdw.c cmdy.c cmdz.c cmd2F.c cmd2F60.c)
|
||||
|
||||
# Graphics
|
||||
|
||||
target_sources(xsystem35 PRIVATE
|
||||
sdl_video.c sdl_draw.c sdl_event.c sdl_image.c sdl_cursor.c sdl_effect.c
|
||||
image.c font.c)
|
||||
|
||||
# CG
|
||||
target_sources(xsystem35 PRIVATE
|
||||
pms.c vsp.c bmp.c qnt.c jpeg.c)
|
||||
if (HAVE_WEBP)
|
||||
target_sources(xsystem35 PRIVATE webp.c)
|
||||
target_link_libraries(xsystem35 PRIVATE PkgConfig::WEBP)
|
||||
if (EMSCRIPTEN)
|
||||
target_sources(xsystem35 PRIVATE pcm.emscripten.c bgm.emscripten.c)
|
||||
else()
|
||||
target_sources(xsystem35 PRIVATE pcm.sdlmixer.c bgm.sdlmixer.c)
|
||||
endif()
|
||||
|
||||
# Music
|
||||
target_sources(xsystem35 PRIVATE
|
||||
music.c music_cdrom.c music_midi.c midi.c cdrom.c)
|
||||
if (EMSCRIPTEN)
|
||||
target_sources(xsystem35 PRIVATE cdrom.emscripten.c)
|
||||
else()
|
||||
target_sources(xsystem35 PRIVATE cdrom.mp3.c)
|
||||
endif()
|
||||
|
||||
# Misc
|
||||
target_sources(xsystem35 PRIVATE
|
||||
input.c profile.c mt19937-1.c filecheck.c mmap.c hacks.c)
|
||||
if (EMSCRIPTEN)
|
||||
target_sources(xsystem35 PRIVATE midi.emscripten.c)
|
||||
elseif (ANDROID)
|
||||
target_sources(xsystem35 PRIVATE midi.android.c)
|
||||
else()
|
||||
target_sources(xsystem35 PRIVATE midi.sdlmixer.c)
|
||||
if (ENABLE_MIDI_RAWMIDI)
|
||||
target_sources(xsystem35 PRIVATE midi.rawmidi.c midifile.c)
|
||||
endif()
|
||||
if (ENABLE_MIDI_PORTMIDI)
|
||||
target_sources(xsystem35 PRIVATE midi.portmidi.c)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Scenario
|
||||
target_sources(xsystem35 PRIVATE
|
||||
cali.c scenario.c variable.c cmd_check.c nact.c
|
||||
selection.c message.c savedata.c s39ain.c texthook.c msgskip.c)
|
||||
if (EMSCRIPTEN)
|
||||
target_sources(xsystem35 PRIVATE menu_emscripten.c)
|
||||
elseif (ANDROID)
|
||||
target_sources(xsystem35 PRIVATE menu_android.c)
|
||||
elseif (ENABLE_GTK)
|
||||
target_sources(xsystem35 PRIVATE menu.c menu_callback.c menu_gui.c s39init.c)
|
||||
else ()
|
||||
target_sources(xsystem35 PRIVATE menu_sdl.c sdl_input.c)
|
||||
endif()
|
||||
|
||||
# Graphics
|
||||
target_sources(xsystem35 PRIVATE
|
||||
ags.c cg.c ecopy.c alpha_plane.c cursor.c)
|
||||
if (HAVE_WEBP)
|
||||
target_sources(xsystem35 PRIVATE webp.c)
|
||||
target_link_libraries(xsystem35 PRIVATE WebP)
|
||||
endif()
|
||||
|
||||
# Network
|
||||
target_sources(xsystem35 PRIVATE
|
||||
network.c)
|
||||
|
||||
# Debugger
|
||||
if (ENABLE_DEBUGGER)
|
||||
target_sources(xsystem35 PRIVATE
|
||||
debug_symbol.c debugger.c debugger_cui.c debugger_dap.c)
|
||||
endif()
|
||||
|
||||
if (WIN32)
|
||||
target_sources(xsystem35 PRIVATE win/dialog.c win/resources.rc win/menubar.c win/console.c)
|
||||
target_sources(xsystem35 PRIVATE
|
||||
win/dialog.c win/resources.rc win/resources.c win/menubar.c win/console.c)
|
||||
endif()
|
||||
|
||||
target_link_libraries(src_lib PRIVATE sdl2 zlib)
|
||||
target_link_libraries(xsystem35 PRIVATE m zlib sdl2 sdl2_ttf)
|
||||
if (TARGET sdl2_mixer)
|
||||
target_link_libraries(xsystem35 PRIVATE sdl2_mixer)
|
||||
endif()
|
||||
|
||||
if (EMSCRIPTEN)
|
||||
|
||||
set(LIBS
|
||||
"SHELL:-s USE_ZLIB=1"
|
||||
"SHELL:-s USE_SDL=2"
|
||||
"SHELL:-s USE_SDL_TTF=2")
|
||||
target_compile_options(src_lib PRIVATE ${LIBS})
|
||||
target_compile_options(xsystem35 PRIVATE ${LIBS})
|
||||
target_link_options(xsystem35 PRIVATE ${LIBS})
|
||||
target_link_libraries(xsystem35 PRIVATE idbfs.js)
|
||||
|
||||
# Without optimizations, Asyncify generates very large code.
|
||||
list(APPEND CMAKE_EXE_LINKER_FLAGS_DEBUG "-O1")
|
||||
|
||||
target_link_options(xsystem35 PRIVATE
|
||||
"SHELL:-s ENVIRONMENT=web"
|
||||
"SHELL:-s ASYNCIFY=1 -s ASYNCIFY_IGNORE_INDIRECT=1"
|
||||
"SHELL:-s ASYNCIFY_REMOVE=SDL_Delay"
|
||||
"SHELL:-s ASYNCIFY_IMPORTS=muspcm_load_no,muspcm_load_data,muspcm_load_mixlr,muspcm_waitend,wait_vsync,load_mincho_font"
|
||||
"SHELL:-s ASYNCIFY_ADD=commands2F60,nact_main,send_agsevent,cb_waitkey_sprite"
|
||||
"SHELL:-s ALLOW_MEMORY_GROWTH=1"
|
||||
"SHELL:-s NO_EXIT_RUNTIME=1"
|
||||
"SHELL:-s EXPORTED_FUNCTIONS=_main,_malloc"
|
||||
"SHELL:-s EXPORTED_RUNTIME_METHODS=getValue,addRunDependency,removeRunDependency")
|
||||
-sENVIRONMENT=web
|
||||
-sASYNCIFY=1
|
||||
-sASYNCIFY_IGNORE_INDIRECT=1
|
||||
-sASYNCIFY_REMOVE=SDL_Delay
|
||||
-sASYNCIFY_IMPORTS=muspcm_load_no,muspcm_load_data,muspcm_load_mixlr,muspcm_waitend,wait_vsync,load_mincho_font
|
||||
-sASYNCIFY_ADD=commands2F60,nact_main,send_agsevent,cb_waitkey_sprite
|
||||
-sALLOW_MEMORY_GROWTH=1
|
||||
-sNO_EXIT_RUNTIME=1
|
||||
-sEXPORTED_FUNCTIONS=_main,_malloc
|
||||
-sEXPORTED_RUNTIME_METHODS=getValue,addRunDependency,removeRunDependency)
|
||||
|
||||
elseif (ANDROID)
|
||||
|
||||
target_link_libraries(src_lib PRIVATE SDL2)
|
||||
target_link_libraries(xsystem35 PRIVATE SDL2 SDL2_ttf SDL2_mixer ${ndk_zlib} ${ndk_log})
|
||||
target_link_libraries(xsystem35 PRIVATE ${ndk_log})
|
||||
|
||||
else() # non-emscripten, non-android
|
||||
target_link_libraries(src_lib PRIVATE PkgConfig::SDL2)
|
||||
target_link_libraries(xsystem35 PRIVATE m ZLIB::ZLIB)
|
||||
target_link_libraries(xsystem35 PRIVATE PkgConfig::SDL2)
|
||||
target_link_libraries(xsystem35 PRIVATE PkgConfig::SDL2TTF)
|
||||
if (TARGET cJSON)
|
||||
target_link_libraries(xsystem35 PRIVATE cJSON)
|
||||
endif()
|
||||
if (GTK3_FOUND)
|
||||
target_link_libraries(xsystem35 PRIVATE PkgConfig::GTK3)
|
||||
endif()
|
||||
if (SDL2MIXER_FOUND)
|
||||
target_link_libraries(xsystem35 PRIVATE PkgConfig::SDL2MIXER)
|
||||
endif()
|
||||
if (ENABLE_DEBUGGER)
|
||||
if (cJSON_FOUND)
|
||||
target_link_libraries(xsystem35 PRIVATE PkgConfig::cJSON)
|
||||
else()
|
||||
target_link_libraries(xsystem35 PRIVATE ${cJSON})
|
||||
endif()
|
||||
endif()
|
||||
if (ENABLE_MIDI_PORTMIDI)
|
||||
target_link_libraries(xsystem35 PRIVATE ${PORTMIDI})
|
||||
endif()
|
||||
@@ -142,10 +195,3 @@ else() # non-emscripten, non-android
|
||||
add_test(NAME src_tests COMMAND src_tests)
|
||||
configure_file(testdata/test.gr ${CMAKE_CURRENT_BINARY_DIR}/testdata/test.gr COPYONLY)
|
||||
endif()
|
||||
|
||||
# FIXME: set up dependency for xsystem35 on this
|
||||
if (NOT EMSCRIPTEN AND NOT ANDROID)
|
||||
add_custom_target(sdl_keytable.h
|
||||
COMMAND perl ../tools/xsyskey.pl ${SDL2_INCLUDE_DIRS} > sdl_keytable.h
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
endif()
|
||||
|
||||
@@ -42,23 +42,44 @@
|
||||
#include "font.h"
|
||||
#include "cursor.h"
|
||||
#include "image.h"
|
||||
#include "debugger.h"
|
||||
|
||||
static Palette256 pal_256;
|
||||
static boolean need_update = TRUE;
|
||||
static boolean fade_outed = FALSE;
|
||||
static int cursor_move_time = 50; /* カーソル移動にかかる時間(ms) */
|
||||
|
||||
static void initPal(Palette256 *pal) {
|
||||
int i;
|
||||
for (i = 0; i < 256; i++) {
|
||||
pal->red[i] = 0; pal->green[i] = 0; pal->blue[i] = 0;
|
||||
}
|
||||
pal->red[0] = 0; pal->green[0] = 0; pal->blue[0] = 0;
|
||||
pal->red[7] = 255; pal->green[7] = 255; pal->blue[7] = 255;
|
||||
pal->red[15] = 255; pal->green[15] = 255; pal->blue[15] = 255;
|
||||
pal->red[255] = 255; pal->green[255] = 255; pal->blue[255] = 255;
|
||||
sdl_setPalette(pal, 0, 256);
|
||||
static void palette_changed(void) {
|
||||
nact->ags.pal_changed = TRUE;
|
||||
dbg_on_palette_change();
|
||||
}
|
||||
|
||||
static void initPal(void) {
|
||||
static const Color initial_palette[256] = {
|
||||
[ 0] = { 0, 0, 0},
|
||||
[ 1] = {128, 0, 0},
|
||||
[ 2] = { 0, 128, 0},
|
||||
[ 3] = {128, 128, 0},
|
||||
[ 4] = { 0, 0, 128},
|
||||
[ 5] = {128, 0, 128},
|
||||
[ 6] = { 0, 128, 128},
|
||||
[ 7] = {192, 192, 192},
|
||||
[ 8] = {192, 220, 192},
|
||||
[ 9] = {166, 202, 240},
|
||||
[ 15] = {255, 255, 255},
|
||||
[246] = {255, 251, 240},
|
||||
[247] = {160, 160, 164},
|
||||
[248] = {128, 128, 128},
|
||||
[249] = {255, 0, 0},
|
||||
[250] = { 0, 255, 0},
|
||||
[251] = {255, 255, 0},
|
||||
[252] = { 0, 0, 255},
|
||||
[253] = {255, 0, 255},
|
||||
[254] = { 0, 255, 255},
|
||||
[255] = {255, 255, 255},
|
||||
};
|
||||
memcpy(nact->ags.pal, initial_palette, sizeof(initial_palette));
|
||||
sdl_setPalette(nact->ags.pal, 0, 256);
|
||||
palette_changed();
|
||||
}
|
||||
|
||||
boolean ags_check_param(int *x, int *y, int *w, int *h) {
|
||||
@@ -99,9 +120,8 @@ boolean ags_check_param_xy(int *x, int *y) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void ags_init(const char *render_driver) {
|
||||
nact->ags.mouse_movesw = MOUSE_WARP_SMOOTH;
|
||||
nact->ags.pal = &pal_256;
|
||||
void ags_init(const char *render_driver, bool enable_zb) {
|
||||
nact->ags.mouse_warp_enabled = true;
|
||||
nact->ags.world_size.width = SYS35_DEFAULT_WIDTH;
|
||||
nact->ags.world_size.height = SYS35_DEFAULT_HEIGHT;
|
||||
nact->ags.world_depth = SYS35_DEFAULT_DEPTH;
|
||||
@@ -109,11 +129,14 @@ void ags_init(const char *render_driver) {
|
||||
nact->ags.view_area.y = 0;
|
||||
nact->ags.view_area.w = SYS35_DEFAULT_WIDTH;
|
||||
nact->ags.view_area.h = SYS35_DEFAULT_HEIGHT;
|
||||
|
||||
nact->ags.enable_zb = enable_zb;
|
||||
nact->ags.font_weight = enable_zb ? FONT_WEIGHT_BOLD : FONT_WEIGHT_NORMAL;
|
||||
|
||||
sdl_Initialize(render_driver);
|
||||
font_init();
|
||||
|
||||
initPal(&pal_256);
|
||||
initPal();
|
||||
cg_init();
|
||||
}
|
||||
|
||||
@@ -123,9 +146,9 @@ void ags_remove(void) {
|
||||
}
|
||||
|
||||
void ags_reset(void) {
|
||||
nact->ags.mouse_movesw = MOUSE_WARP_SMOOTH;
|
||||
nact->ags.mouse_warp_enabled = true;
|
||||
nact->ags.eventcb = NULL;
|
||||
initPal(&pal_256);
|
||||
initPal();
|
||||
cg_reset();
|
||||
}
|
||||
|
||||
@@ -151,7 +174,7 @@ void ags_setWorldSize(int width, int height, int depth) {
|
||||
|
||||
fade_outed = FALSE; /* thanx tajiri@wizard */
|
||||
|
||||
nact->ags.pal_changed = TRUE;
|
||||
palette_changed();
|
||||
}
|
||||
|
||||
void ags_setViewArea(int x, int y, int width, int height) {
|
||||
@@ -216,21 +239,18 @@ void ags_updateFull() {
|
||||
sdl_updateArea(&r, &p);
|
||||
}
|
||||
|
||||
void ags_setPalettes(Palette256 *src_pal, int src, int dst, int cnt) {
|
||||
int i;
|
||||
for (i = 0; i < cnt; i++) {
|
||||
nact->ags.pal->red [dst + i] = src_pal->red [src + i];
|
||||
nact->ags.pal->green[dst + i] = src_pal->green[src + i];
|
||||
nact->ags.pal->blue [dst + i] = src_pal->blue [src + i];
|
||||
void ags_setPalettes(Color *src, int dst, int cnt) {
|
||||
for (int i = 0; i < cnt; i++) {
|
||||
nact->ags.pal[dst + i] = src[i];
|
||||
}
|
||||
nact->ags.pal_changed = TRUE;
|
||||
palette_changed();
|
||||
}
|
||||
|
||||
void ags_setPalette(int no, int red, int green, int blue) {
|
||||
nact->ags.pal->red[no] = red;
|
||||
nact->ags.pal->green[no] = green;
|
||||
nact->ags.pal->blue[no] = blue;
|
||||
nact->ags.pal_changed = TRUE;
|
||||
nact->ags.pal[no].r = red;
|
||||
nact->ags.pal[no].g = green;
|
||||
nact->ags.pal[no].b = blue;
|
||||
palette_changed();
|
||||
}
|
||||
|
||||
void ags_setPaletteToSystem(int src, int cnt) {
|
||||
@@ -577,9 +597,9 @@ void ags_fadeOut(int rate, boolean flag) {
|
||||
fade(duration, flag, nact->ags.world_depth == 8 ? EFFECT_FADEOUT : EFFECT_DITHERING_FADEOUT);
|
||||
|
||||
if (nact->ags.world_depth == 8) {
|
||||
Palette256 pal;
|
||||
Color pal[256];
|
||||
memset(&pal, 0, sizeof(pal));
|
||||
sdl_setPalette(&pal, 0, 256);
|
||||
sdl_setPalette(pal, 0, 256);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -606,14 +626,18 @@ void ags_whiteOut(int rate, boolean flag) {
|
||||
fade(duration, flag, nact->ags.world_depth == 8 ? EFFECT_WHITEIN : EFFECT_DITHERING_WHITEOUT);
|
||||
|
||||
if (nact->ags.world_depth == 8) {
|
||||
Palette256 pal;
|
||||
Color pal[256];
|
||||
memset(&pal, 255, sizeof(pal));
|
||||
sdl_setPalette(&pal, 0, 256);
|
||||
sdl_setPalette(pal, 0, 256);
|
||||
}
|
||||
}
|
||||
|
||||
void ags_setFont(int type, int size) {
|
||||
font_select(type, size);
|
||||
font_select(type, size, FONT_WEIGHT_NORMAL);
|
||||
}
|
||||
|
||||
void ags_setFontWithWeight(int type, int size, int weight) {
|
||||
font_select(type, size, weight);
|
||||
}
|
||||
|
||||
void ags_setCursorType(int type) {
|
||||
@@ -627,42 +651,42 @@ void ags_loadCursor(int p1,int p2) {
|
||||
}
|
||||
}
|
||||
|
||||
void ags_setCursorLocation(int x, int y, boolean is_dibgeo) {
|
||||
int dx[8], dy[8];
|
||||
int i, delx, dely;
|
||||
MyPoint p;
|
||||
void ags_setCursorLocation(int x, int y, bool is_dibgeo, bool for_selection) {
|
||||
if (!ags_check_param_xy(&x, &y)) return;
|
||||
|
||||
/* DIB 座表系か Window 座表系か */
|
||||
if (is_dibgeo) {
|
||||
// DIB coordinates -> Window coordinates
|
||||
x -= nact->ags.view_area.x;
|
||||
y -= nact->ags.view_area.y;
|
||||
}
|
||||
|
||||
switch(nact->ags.mouse_movesw) {
|
||||
case MOUSE_WARP_DISABLED:
|
||||
return;
|
||||
case MOUSE_WARP_DIRECT:
|
||||
sdl_setCursorLocation(x, y); break;
|
||||
case MOUSE_WARP_SMOOTH:
|
||||
sys_getMouseInfo(&p, is_dibgeo);
|
||||
delx = x - p.x;
|
||||
dely = y - p.y;
|
||||
|
||||
for (i = 1; i < 8; i++) {
|
||||
dx[i-1] = ((delx*i*i*i) >> 9) - ((3*delx*i*i)>> 6) + ((3*delx*i) >> 3) + p.x;
|
||||
dy[i-1] = ((dely*i*i*i) >> 9) - ((3*dely*i*i)>> 6) + ((3*dely*i) >> 3) + p.y;
|
||||
}
|
||||
dx[7] = x; dy[7] = y;
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
sdl_setCursorLocation(dx[i], dy[i]);
|
||||
usleep(cursor_move_time * 1000 / 8);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
if (!for_selection) {
|
||||
// We can't move the actual cursor in the browser, but can change the
|
||||
// internal mouse coordinates. This can help with keyboard/gamepad
|
||||
// navigation.
|
||||
sdl_setCursorInternalLocation(x, y);
|
||||
EM_ASM({ xsystem35.shell.showMouseMoveEffect($0, $1); }, x, y);
|
||||
sdl_sleep(cursor_move_time);
|
||||
}
|
||||
#else
|
||||
if (nact->ags.mouse_warp_enabled) {
|
||||
MyPoint p;
|
||||
sys_getMouseInfo(&p, is_dibgeo);
|
||||
int dx = x - p.x;
|
||||
int dy = y - p.y;
|
||||
for (int i = 1; i < 8; i++) {
|
||||
int xi = ((dx*i*i*i) >> 9) - ((3*dx*i*i)>> 6) + ((3*dx*i) >> 3) + p.x;
|
||||
int yi = ((dy*i*i*i) >> 9) - ((3*dy*i*i)>> 6) + ((3*dy*i) >> 3) + p.y;
|
||||
sdl_setCursorLocation(xi, yi);
|
||||
sdl_sleep(cursor_move_time / 7);
|
||||
}
|
||||
sdl_setCursorLocation(x, y);
|
||||
} else if (!for_selection) {
|
||||
sdl_setCursorInternalLocation(x, y);
|
||||
sdl_sleep(cursor_move_time);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE
|
||||
|
||||
@@ -100,14 +100,8 @@ enum agsevent_button {
|
||||
AGSEVENT_BUTTON_RIGHT,
|
||||
};
|
||||
|
||||
enum mouse_warp_mode {
|
||||
MOUSE_WARP_DISABLED,
|
||||
MOUSE_WARP_DIRECT,
|
||||
MOUSE_WARP_SMOOTH,
|
||||
};
|
||||
|
||||
struct _ags {
|
||||
Palette256 *pal; /* system palette */
|
||||
Color pal[256]; /* system palette */
|
||||
boolean pal_changed; /* system palette has changed */
|
||||
|
||||
MyDimension world_size; /* size of off-screen */
|
||||
@@ -116,11 +110,13 @@ struct _ags {
|
||||
|
||||
int world_depth; /* depth of off-screen (bits per pixel) */
|
||||
|
||||
enum mouse_warp_mode mouse_movesw;
|
||||
|
||||
agsurface_t *dib; /* main surface */
|
||||
void (*eventcb)(agsevent_t *e); /* deliver event */
|
||||
|
||||
int font_weight;
|
||||
|
||||
bool mouse_warp_enabled;
|
||||
bool enable_zb;
|
||||
boolean noantialias; /* antialias を使用しない */
|
||||
boolean noimagecursor; /* リソースファイルのカーソルを読みこまない */
|
||||
};
|
||||
@@ -129,7 +125,7 @@ typedef struct _ags ags_t;
|
||||
|
||||
|
||||
/* 初期化関係 */
|
||||
void ags_init(const char *render_driver);
|
||||
void ags_init(const char *render_driver, bool enable_zb);
|
||||
void ags_remove(void);
|
||||
void ags_reset(void);
|
||||
|
||||
@@ -150,7 +146,7 @@ extern void ags_updateFull(void);
|
||||
extern void ags_updateArea(int x, int y, int width, int height);
|
||||
|
||||
/* パレット関係 */
|
||||
extern void ags_setPalettes(Palette256 *src_pal, int src, int dst, int cnt);
|
||||
extern void ags_setPalettes(Color *src, int dst, int cnt);
|
||||
extern void ags_setPalette(int no, int red, int green, int blue);
|
||||
extern void ags_setPaletteToSystem(int src, int cnt);
|
||||
|
||||
@@ -206,12 +202,13 @@ enum FontType {
|
||||
FONT_MINCHO,
|
||||
};
|
||||
extern void ags_setFont(int type, int size);
|
||||
extern void ags_setFontWithWeight(int type, int size, int weight);
|
||||
extern agsurface_t *ags_drawStringToSurface(const char *str);
|
||||
|
||||
/* カーソル関係 */
|
||||
extern void ags_setCursorType(int type);
|
||||
extern void ags_loadCursor(int ,int);
|
||||
extern void ags_setCursorLocation(int x, int y, boolean dibgeo);
|
||||
extern void ags_setCursorLocation(int x, int y, bool is_dibgeo, bool for_selection);
|
||||
extern void ags_setCursorMoveTime(int msec);
|
||||
extern int ags_getCursorMoveTime();
|
||||
|
||||
|
||||
+1
-1
@@ -108,5 +108,5 @@ void ald_init(int type, const char **file, int cnt, boolean use_mmap) {
|
||||
int ald_get_maxno(DRIFILETYPE type) {
|
||||
if (type >= DRIFILETYPEMAX || !dri[type])
|
||||
return 0;
|
||||
return dri[type]->nr_files;
|
||||
return dri[type]->maxno;
|
||||
}
|
||||
|
||||
@@ -1,75 +0,0 @@
|
||||
/*
|
||||
* bgm.dummy.c BGM (*BA.ALD) dummy implementation
|
||||
*
|
||||
* Copyright (C) 2019 <KichikuouChrome@gmail.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include "portab.h"
|
||||
#include "bgm.h"
|
||||
|
||||
int musbgm_init(DRIFILETYPE type, int base_no) {
|
||||
return NG;
|
||||
}
|
||||
|
||||
int musbgm_exit(void) {
|
||||
return NG;
|
||||
}
|
||||
|
||||
int musbgm_reset(void) {
|
||||
return NG;
|
||||
}
|
||||
|
||||
int musbgm_play(int no, int time, int vol) {
|
||||
WARNING("not implemented");
|
||||
return NG;
|
||||
}
|
||||
|
||||
int musbgm_stop(int no, int time) {
|
||||
WARNING("not implemented");
|
||||
return NG;
|
||||
}
|
||||
|
||||
int musbgm_fade(int no, int time, int vol) {
|
||||
WARNING("not implemented");
|
||||
return NG;
|
||||
}
|
||||
|
||||
int musbgm_getpos(int no) {
|
||||
WARNING("not implemented");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int musbgm_getlen(int no) {
|
||||
WARNING("not implemented");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int musbgm_isplaying(int no) {
|
||||
WARNING("not implemented");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int musbgm_stopall(int time) {
|
||||
WARNING("not implemented");
|
||||
return NG;
|
||||
}
|
||||
|
||||
int musbgm_wait(int no, int timeout) {
|
||||
WARNING("not implemented");
|
||||
return NG;
|
||||
}
|
||||
@@ -36,7 +36,6 @@
|
||||
* static methods
|
||||
*/
|
||||
static bmp_header *extract_header(uint8_t *b);
|
||||
static void getpal(Palette256 *pal, uint8_t *b);
|
||||
static void extract_8bit(bmp_header *bmp, uint8_t *pic, uint8_t *b);
|
||||
static void extract_24bit(bmp_header *bmp, uint16_t *pic, uint8_t *b);
|
||||
|
||||
@@ -65,17 +64,16 @@ static bmp_header *extract_header(uint8_t *b) {
|
||||
|
||||
/*
|
||||
* Get palette from raw data
|
||||
* pal: palette to be stored
|
||||
* b : raw data (pointer to palette)
|
||||
*/
|
||||
static void getpal(Palette256 *pal, uint8_t *b) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 256; i++) {
|
||||
pal->blue[i] = *b++;
|
||||
pal->red[i] = *b++;
|
||||
pal->green[i] = *b++;
|
||||
static Color *getpal(uint8_t *b) {
|
||||
Color *pal = malloc(sizeof(Color) * 256);
|
||||
for (int i = 0; i < 256; i++) {
|
||||
pal[i].b = *b++;
|
||||
pal[i].r = *b++;
|
||||
pal[i].g = *b++;
|
||||
}
|
||||
return pal;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -168,8 +166,7 @@ cgdata *bmp256_extract(uint8_t *data) {
|
||||
bmp_header *bmp = extract_header(data);
|
||||
cgdata *cg = calloc(1, sizeof(cgdata));
|
||||
|
||||
cg->pal = malloc(sizeof(Palette256));
|
||||
getpal(cg->pal, data + bmp->bmpPp);
|
||||
cg->pal = getpal(data + bmp->bmpPp);
|
||||
|
||||
/* +10: margin for broken cg */
|
||||
cg->pic = malloc(sizeof(uint8_t) * ((bmp->bmpXW + 10) * (bmp->bmpYW + 10)));
|
||||
|
||||
@@ -1,238 +0,0 @@
|
||||
/*
|
||||
* cdrom.FreeBSD.c CD-ROMアクセス
|
||||
*
|
||||
* Copyright (C) 1997-1998 Masaki Chikama (Wren) <chikama@kasumi.ipl.mech.nagoya-u.ac.jp>
|
||||
* 1998- <masaki-c@is.aist-nara.ac.jp>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
/* $Id: cdrom.FreeBSD.c,v 1.17 2002/08/18 09:35:29 chikama Exp $ */
|
||||
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/cdio.h>
|
||||
|
||||
#include "portab.h"
|
||||
#include "cdrom.h"
|
||||
#include "music_private.h"
|
||||
#include "system.h"
|
||||
|
||||
static int cdrom_init(char *);
|
||||
static int cdrom_exit(void);
|
||||
static int cdrom_reset(void);
|
||||
static int cdrom_start(int, int);
|
||||
static int cdrom_stop();
|
||||
static int cdrom_getPlayingInfo(cd_time *);
|
||||
|
||||
#define cdrom cdrom_bsd
|
||||
cdromdevice_t cdrom = {
|
||||
cdrom_init,
|
||||
cdrom_exit,
|
||||
cdrom_reset,
|
||||
cdrom_start,
|
||||
cdrom_stop,
|
||||
cdrom_getPlayingInfo,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
static int cd_fd;
|
||||
static boolean enabled = FALSE;
|
||||
static struct cd_toc_entry toc_buffer[100];
|
||||
static boolean msfmode = TRUE; /* default は MSFPLAY mode */
|
||||
static int lastindex; /* 最終トラック */
|
||||
|
||||
/* ioctlがエラーで帰って来る場合 IOCTL_RETRY_TIME 回リトライする */
|
||||
static int do_ioctl(int cmd, void *data) {
|
||||
int i;
|
||||
for (i = 0; i < CDROM_IOCTL_RETRY_TIME; i++) {
|
||||
if (0 <= ioctl(cd_fd, cmd, data)) {
|
||||
return 0;
|
||||
}
|
||||
usleep(CDROM_IOCTL_RETRY_INTERVAL * 100 * 1000);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* CD-ROM の目次を読み出しておく */
|
||||
static int get_cd_entry() {
|
||||
int endtrk, i;
|
||||
struct ioc_toc_header tochdr;
|
||||
struct ioc_read_toc_entry toc;
|
||||
struct ioc_play_msf msf;
|
||||
|
||||
/* 最終トラック番号を得る */
|
||||
if (do_ioctl(CDIOREADTOCHEADER, &tochdr) < 0) {
|
||||
WARNING("CDIOREADTOCHEADER: %s", strerror(errno));
|
||||
return NG;
|
||||
}
|
||||
|
||||
lastindex = endtrk = tochdr.ending_track;
|
||||
i = tochdr.ending_track - tochdr.starting_track + 1;
|
||||
if (endtrk <= 1) { /* 2トラック以上ないとダメ */
|
||||
WARNING("No CD-AUDIO in CD-ROM");
|
||||
return NG;
|
||||
}
|
||||
|
||||
prv.cd_maxtrk = lastindex;
|
||||
|
||||
/* すべてのトラックの目次を読みだしてキャッシュしておく */
|
||||
toc.address_format = CD_MSF_FORMAT;
|
||||
toc.starting_track = 0;
|
||||
toc.data_len = (i + 1) * sizeof(struct cd_toc_entry);
|
||||
toc.data = toc_buffer;
|
||||
if (do_ioctl(CDIOREADTOCENTRYS, &toc) < 0) {
|
||||
WARNING("CDIOREADTOCENTRYS: %s", strerror(errno));
|
||||
return NG;
|
||||
}
|
||||
|
||||
#ifdef CDROM_USE_TRKIND_ONLY
|
||||
msfmode = FALSE;
|
||||
return OK;
|
||||
#endif
|
||||
|
||||
/* CDROMPLAYMSF が有効かチェック */
|
||||
msf.start_m = toc_buffer[1].addr.msf.minute;
|
||||
msf.start_s = toc_buffer[1].addr.msf.second;
|
||||
msf.start_f = toc_buffer[1].addr.msf.frame;
|
||||
msf.end_m = toc_buffer[2].addr.msf.minute;
|
||||
msf.end_s = toc_buffer[2].addr.msf.second;
|
||||
msf.end_f = toc_buffer[2].addr.msf.frame;
|
||||
if (do_ioctl(CDIOCPLAYMSF, &msf) < 0) {
|
||||
WARNING("CDIOPLAYMSF: %s", strerror(errno));
|
||||
WARNING("CD-ROM: change TRKMODE");
|
||||
msfmode = FALSE;
|
||||
}
|
||||
/* stop */
|
||||
if (do_ioctl(CDIOCSTOP, NULL) < 0) {
|
||||
WARNING("CDIOCSTOP: %s", strerror(errno));
|
||||
return NG;
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
/* デバイスの初期化 */
|
||||
int cdrom_init(char *dev_cd) {
|
||||
if (dev_cd == NULL) return NG;
|
||||
|
||||
if ((cd_fd = open(dev_cd, O_RDONLY, 0)) < 0) {
|
||||
WARNING("CDROM_DEVICE OPEN: %s", strerror(errno));
|
||||
enabled = FALSE;
|
||||
return NG;
|
||||
}
|
||||
if (OK == get_cd_entry()) {
|
||||
enabled = TRUE;
|
||||
return OK;
|
||||
}
|
||||
enabled = FALSE;
|
||||
return NG;
|
||||
}
|
||||
|
||||
/* デバイスの後始末 */
|
||||
int cdrom_exit(void) {
|
||||
if (enabled) {
|
||||
cdrom_stop();
|
||||
close(cd_fd);
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
int cdrom_reset(void) {
|
||||
return cdrom_stop();
|
||||
}
|
||||
|
||||
/* トラック番号 trk の演奏 trk = 1~ */
|
||||
int cdrom_start(int trk, int loop) {
|
||||
struct ioc_play_msf msf;
|
||||
struct ioc_play_track track;
|
||||
|
||||
if (!enabled) return NG;
|
||||
|
||||
/* 曲数よりも多い指定は不可*/
|
||||
if (trk > lastindex) {
|
||||
return NG;
|
||||
}
|
||||
/* drive spin up */
|
||||
if (do_ioctl(CDIOCSTART, NULL) < 0) {
|
||||
WARNING("CDIOCSTART: %s", strerror(errno));
|
||||
return NG;
|
||||
}
|
||||
if (msfmode) {
|
||||
msf.start_m = toc_buffer[trk - 1].addr.msf.minute;
|
||||
msf.start_s = toc_buffer[trk - 1].addr.msf.second;
|
||||
msf.start_f = toc_buffer[trk - 1].addr.msf.frame;
|
||||
msf.end_m = toc_buffer[trk].addr.msf.minute;
|
||||
msf.end_s = toc_buffer[trk].addr.msf.second;
|
||||
msf.end_f = toc_buffer[trk].addr.msf.frame;
|
||||
if (do_ioctl(CDIOCPLAYMSF, &msf) < 0) {
|
||||
WARNING("CDIOPLAYMSF: %s", strerror(errno));
|
||||
return NG;
|
||||
}
|
||||
} else {
|
||||
track.start_track = track.end_track = trk;
|
||||
track.start_index = track.end_index = 0;
|
||||
if (do_ioctl(CDIOCPLAYTRACKS, &track) < 0) {
|
||||
WARNING("CDIOCPLAYTRACKS: %s", strerror(errno));
|
||||
return NG;
|
||||
}
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
/* 演奏停止 */
|
||||
int cdrom_stop() {
|
||||
if (enabled) {
|
||||
/* if (do_ioctl(CDIOCSTOP, NULL) < 0) { */
|
||||
if (do_ioctl(CDIOCPAUSE, NULL) < 0) {
|
||||
/* WARNING("CDIOCSTOP: %s", strerror(errno)); */
|
||||
WARNING("CDIOCPAUSE: %s", strerror(errno));
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
return NG;
|
||||
}
|
||||
|
||||
/* 現在演奏中のトラック情報の取得 */
|
||||
int cdrom_getPlayingInfo (cd_time *info) {
|
||||
struct ioc_read_subchannel s;
|
||||
struct cd_sub_channel_info data;
|
||||
|
||||
if (!enabled)
|
||||
return NG;
|
||||
memset(&s, 0, sizeof(s));
|
||||
|
||||
s.data = &data;
|
||||
s.data_len = sizeof (data);
|
||||
s.address_format = CD_MSF_FORMAT;
|
||||
s.data_format = CD_CURRENT_POSITION;
|
||||
if (do_ioctl(CDIOCREADSUBCHANNEL, &s) < 0) {
|
||||
WARNING("CDIOCREADSUBCHANNEL: %s", strerror(errno));
|
||||
return NG;
|
||||
}
|
||||
if (s.data->header.audio_status != CD_AS_PLAY_IN_PROGRESS) {
|
||||
return NG;
|
||||
}
|
||||
info->t = s.data->what.position.track_number;
|
||||
info->m = s.data->what.position.reladdr.msf.minute;
|
||||
info->s = s.data->what.position.reladdr.msf.second;
|
||||
info->f = s.data->what.position.reladdr.msf.frame;
|
||||
return OK;
|
||||
}
|
||||
@@ -1,268 +0,0 @@
|
||||
/*
|
||||
* cdrom.Linux.c CD-ROMアクセス
|
||||
*
|
||||
* Copyright (C) 1997-1998 Masaki Chikama (Wren) <chikama@kasumi.ipl.mech.nagoya-u.ac.jp>
|
||||
* 1998- <masaki-c@is.aist-nara.ac.jp>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
/* $Id: cdrom.Linux.c,v 1.18 2002/08/18 09:35:29 chikama Exp $ */
|
||||
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#if defined(sun)
|
||||
#include <sys/cdio.h>
|
||||
struct cdrom_msf0 {
|
||||
unsigned char minute; /* minute */
|
||||
unsigned char second; /* second */
|
||||
unsigned char frame; /* frame */
|
||||
};
|
||||
#else
|
||||
#include <linux/cdrom.h>
|
||||
#endif /* sun */
|
||||
|
||||
#include "portab.h"
|
||||
#include "cdrom.h"
|
||||
#include "music_private.h"
|
||||
#include "system.h"
|
||||
|
||||
static int cdrom_init(char *);
|
||||
static int cdrom_exit(void);
|
||||
static int cdrom_reset(void);
|
||||
static int cdrom_start(int, int);
|
||||
static int cdrom_stop();
|
||||
static int cdrom_getPlayingInfo(cd_time *);
|
||||
|
||||
#define cdrom cdrom_linux
|
||||
cdromdevice_t cdrom = {
|
||||
cdrom_init,
|
||||
cdrom_exit,
|
||||
cdrom_reset,
|
||||
cdrom_start,
|
||||
cdrom_stop,
|
||||
cdrom_getPlayingInfo,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
static int cd_fd;
|
||||
static boolean enabled = FALSE;
|
||||
static struct cdrom_msf0 tocmsf[100];
|
||||
static boolean msfmode = TRUE; /* default は MSFPLAY mode */
|
||||
static int lastindex; /* 最終トラック */
|
||||
|
||||
|
||||
/* ioctlがエラーで帰って来る場合 IOCTL_RETRY_TIME 回リトライする */
|
||||
static int do_ioctl(int cmd, void *data) {
|
||||
int i;
|
||||
for (i = 0; i < CDROM_IOCTL_RETRY_TIME; i++) {
|
||||
if (0 <= ioctl(cd_fd, cmd, data)) {
|
||||
return 0;
|
||||
}
|
||||
usleep(CDROM_IOCTL_RETRY_INTERVAL * 100 * 1000);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* CD-ROM の目次を読み出しておく */
|
||||
static int get_cd_entry() {
|
||||
int endtrk, i;
|
||||
struct cdrom_tochdr tochdr;
|
||||
struct cdrom_tocentry toc;
|
||||
struct cdrom_msf msf;
|
||||
|
||||
/* 最終トラック番号を得る */
|
||||
if (do_ioctl(CDROMREADTOCHDR, &tochdr) < 0) {
|
||||
WARNING("CDROMREADTOCHDR: %s", strerror(errno));
|
||||
return NG;
|
||||
}
|
||||
lastindex = endtrk = tochdr.cdth_trk1;
|
||||
if (endtrk <= 1) { /* 2トラック以上ないとダメ */
|
||||
WARNING("No CD-AUDIO in CD-ROM");
|
||||
return NG;
|
||||
}
|
||||
|
||||
prv.cd_maxtrk = lastindex;
|
||||
|
||||
/* すべてのトラックの目次を読みだしてキャッシュしておく */
|
||||
toc.cdte_format = CDROM_MSF;
|
||||
for (i = 1; i <= endtrk; i++) {
|
||||
toc.cdte_track = i;
|
||||
if (do_ioctl(CDROMREADTOCENTRY, &toc) < 0) {
|
||||
WARNING("CDROMREADTOCENTRY: %s", strerror(errno));
|
||||
return NG;
|
||||
}
|
||||
tocmsf[i - 1].minute = toc.cdte_addr.msf.minute;
|
||||
tocmsf[i - 1].second = toc.cdte_addr.msf.second;
|
||||
tocmsf[i - 1].frame = toc.cdte_addr.msf.frame;
|
||||
}
|
||||
/* リードアウトを読み出す */
|
||||
toc.cdte_track = CDROM_LEADOUT;
|
||||
if (do_ioctl(CDROMREADTOCENTRY, &toc) < 0) {
|
||||
WARNING("CDROMREADTOCENTRY: %s", strerror(errno));
|
||||
return NG;
|
||||
}
|
||||
|
||||
#ifdef PPC
|
||||
/* Linux PPC 対策 ;last track -1 frame */
|
||||
FRAMES_TO_MSF(MSF_TO_FRAMES(toc.cdte_addr.msf.minute,
|
||||
toc.cdte_addr.msf.second,
|
||||
toc.cdte_addr.msf.frame) - 1,
|
||||
&tocmsf[endtrk].minute,
|
||||
&tocmsf[endtrk].second,
|
||||
&tocmsf[endtrk].frame);
|
||||
#else
|
||||
tocmsf[endtrk].minute = toc.cdte_addr.msf.minute;
|
||||
tocmsf[endtrk].second = toc.cdte_addr.msf.second;
|
||||
tocmsf[endtrk].frame = toc.cdte_addr.msf.frame;
|
||||
#endif
|
||||
|
||||
#ifdef CDROM_USE_TRKIND_ONLY
|
||||
msfmode = FALSE;
|
||||
return OK;
|
||||
#endif
|
||||
|
||||
/* CDROMPLAYMSF が有効かチェック */
|
||||
msf.cdmsf_min0 = tocmsf[1].minute;
|
||||
msf.cdmsf_sec0 = tocmsf[1].second;
|
||||
msf.cdmsf_frame0 = tocmsf[1].frame;
|
||||
msf.cdmsf_min1 = tocmsf[2].minute;
|
||||
msf.cdmsf_sec1 = tocmsf[2].second;
|
||||
msf.cdmsf_frame1 = tocmsf[2].frame;
|
||||
if (do_ioctl(CDROMPLAYMSF, &msf) < 0) {
|
||||
WARNING("CDROMPLAYMSF: %s", strerror(errno));
|
||||
WARNING("CD-ROM: change TRKIND mode");
|
||||
msfmode = FALSE;
|
||||
}
|
||||
/* stop */
|
||||
if (do_ioctl(CDROMSTOP, NULL) < 0) {
|
||||
WARNING("CDROMSTOP: %s", strerror(errno));
|
||||
return NG;
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
/* デバイスの初期化 */
|
||||
static int cdrom_init(char *dev_cd) {
|
||||
if (dev_cd == NULL) return NG;
|
||||
|
||||
if ((cd_fd = open(dev_cd, O_RDONLY, 0)) < 0) {
|
||||
WARNING("CDROM_DEVICE OPEN: %s", strerror(errno));
|
||||
enabled = FALSE;
|
||||
return NG;
|
||||
}
|
||||
if (OK == get_cd_entry()) {
|
||||
enabled = TRUE;
|
||||
return OK;
|
||||
}
|
||||
enabled = FALSE;
|
||||
return NG;
|
||||
}
|
||||
|
||||
/* デバイスの後始末 */
|
||||
static int cdrom_exit(void) {
|
||||
if (enabled) {
|
||||
cdrom_stop();
|
||||
close(cd_fd);
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
static int cdrom_reset(void) {
|
||||
return cdrom_stop();
|
||||
}
|
||||
|
||||
/* トラック番号 trk の演奏 trk = 1~ */
|
||||
static int cdrom_start(int trk, int loop) {
|
||||
struct cdrom_msf msf;
|
||||
struct cdrom_ti ti;
|
||||
|
||||
if (!enabled) return NG;
|
||||
|
||||
/* 曲数よりも多い指定は不可*/
|
||||
if (trk > lastindex) {
|
||||
return NG;
|
||||
}
|
||||
/* drive spin up */
|
||||
if (do_ioctl(CDROMSTART, NULL) < 0) {
|
||||
WARNING("CDROMSTART: %s", strerror(errno));
|
||||
return NG;
|
||||
}
|
||||
|
||||
if (msfmode) {
|
||||
msf.cdmsf_min0 = tocmsf[trk - 1].minute;
|
||||
msf.cdmsf_sec0 = tocmsf[trk - 1].second;
|
||||
msf.cdmsf_frame0 = tocmsf[trk - 1].frame;
|
||||
msf.cdmsf_min1 = tocmsf[trk].minute;
|
||||
msf.cdmsf_sec1 = tocmsf[trk].second;
|
||||
msf.cdmsf_frame1 = tocmsf[trk].frame;
|
||||
if (do_ioctl(CDROMPLAYMSF, &msf) < 0) {
|
||||
WARNING("CDROMPLAYMSF: %s", strerror(errno));
|
||||
return NG;
|
||||
}
|
||||
return OK;
|
||||
} else {
|
||||
ti.cdti_trk0 = ti.cdti_trk1 = trk;
|
||||
ti.cdti_ind0 = ti.cdti_ind1 = 0;
|
||||
if (do_ioctl(CDROMPLAYTRKIND, &ti) < 0) {
|
||||
WARNING("CDROMPLAYTRKIND: %s", strerror(errno));
|
||||
return NG;
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
}
|
||||
|
||||
/* 演奏停止 */
|
||||
static int cdrom_stop() {
|
||||
if (enabled) {
|
||||
/* if (do_ioctl(CDROMSTOP, NULL) < 0) { */
|
||||
if (do_ioctl(CDROMPAUSE, NULL) < 0) {
|
||||
/* WARNING("CDROMSTOP: %s", strerror(errno)); */
|
||||
WARNING("CDROMPAUSE: %s", strerror(errno));
|
||||
return NG;
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
return NG;
|
||||
}
|
||||
|
||||
/* 現在演奏中のトラック情報の取得 */
|
||||
static int cdrom_getPlayingInfo (cd_time *info) {
|
||||
struct cdrom_subchnl sc;
|
||||
|
||||
if (!enabled)
|
||||
return NG;
|
||||
|
||||
sc.cdsc_format = CDROM_MSF;
|
||||
if (do_ioctl(CDROMSUBCHNL, &sc) < 0) {
|
||||
WARNING("CDROMSUBCHNL: %s", strerror(errno));
|
||||
return NG;
|
||||
}
|
||||
if (sc.cdsc_audiostatus != CDROM_AUDIO_PLAY) {
|
||||
return NG;
|
||||
}
|
||||
info->t = sc.cdsc_trk;
|
||||
info->m = sc.cdsc_reladdr.msf.minute;
|
||||
info->s = sc.cdsc_reladdr.msf.second;
|
||||
info->f = sc.cdsc_reladdr.msf.frame;
|
||||
return OK;
|
||||
}
|
||||
+4
-1
@@ -22,11 +22,14 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#include "cdrom.h"
|
||||
#include "ald_manager.h"
|
||||
#include "music.h"
|
||||
#include "music_private.h"
|
||||
|
||||
static int current_track;
|
||||
|
||||
static int cdrom_bgm_init(char *dev) {
|
||||
static int cdrom_bgm_init(char *playlist) {
|
||||
prv.cd_maxtrk = ald_get_maxno(DRIFILE_BGM) + 1;
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
-71
@@ -1,71 +0,0 @@
|
||||
/*
|
||||
* cdrom.c CD-ROM control wrapper
|
||||
*
|
||||
* Copyright (C) 2000- Masaki Chikama (Wren) <masaki-c@is.aist-nara.ac.jp>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
/* $Id: cdrom.c,v 1.20 2002/08/18 09:35:29 chikama Exp $ */
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/stat.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "portab.h"
|
||||
#include "cdrom.h"
|
||||
#include "system.h"
|
||||
|
||||
#if defined(ENABLE_CDROM_LINUX)
|
||||
extern cdromdevice_t cdrom_linux;
|
||||
#define NATIVE_CD_DEVICE &cdrom_linux
|
||||
|
||||
#elif defined(ENABLE_CDROM_BSD)
|
||||
extern cdromdevice_t cdrom_bsd;
|
||||
#define NATIVE_CD_DEVICE &cdrom_bsd
|
||||
|
||||
#elif defined(ENABLE_CDROM_EMSCRIPTEN)
|
||||
extern cdromdevice_t cdrom_emscripten;
|
||||
#define NATIVE_CD_DEVICE &cdrom_emscripten
|
||||
|
||||
#else
|
||||
|
||||
extern cdromdevice_t cdrom_empty;
|
||||
#define NATIVE_CD_DEVICE &cdrom_empty
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_CDROM_MP3
|
||||
extern cdromdevice_t cdrom_mp3;
|
||||
#endif
|
||||
|
||||
cdromdevice_t *cd_init(const char *dev) {
|
||||
#if defined(ENABLE_CDROM_EMSCRIPTEN)
|
||||
return NATIVE_CD_DEVICE;
|
||||
#else
|
||||
struct stat st;
|
||||
if (dev && stat(dev, &st) && (S_ISBLK(st.st_mode) || S_ISCHR(st.st_mode)))
|
||||
return NATIVE_CD_DEVICE;
|
||||
|
||||
#ifdef ENABLE_CDROM_MP3
|
||||
return &cdrom_mp3;
|
||||
#else
|
||||
WARNING("no cdrom device available");
|
||||
return NULL;
|
||||
#endif
|
||||
#endif // ENABLE_CDROM_EMSCRIPTEN
|
||||
}
|
||||
@@ -1,69 +0,0 @@
|
||||
/*
|
||||
* cdrom.empty.c CD-ROMアクセス
|
||||
*
|
||||
* Copyright (C) 1997-1998 Masaki Chikama (Wren) <chikama@kasumi.ipl.mech.nagoya-u.ac.jp>
|
||||
* 1998- <masaki-c@is.aist-nara.ac.jp>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
/* $Id: cdrom.empty.c,v 1.8 2002/08/18 09:35:29 chikama Exp $ */
|
||||
|
||||
#include <unistd.h>
|
||||
#include "portab.h"
|
||||
#include "cdrom.h"
|
||||
|
||||
static int cdrom_init(char *);
|
||||
static int cdrom_exit(void);
|
||||
static int cdrom_reset(void);
|
||||
static int cdrom_start(int, int);
|
||||
static int cdrom_stop();
|
||||
static int cdrom_getPlayingInfo(cd_time *);
|
||||
|
||||
#define cdrom cdrom_empty
|
||||
cdromdevice_t cdrom = {
|
||||
cdrom_init,
|
||||
cdrom_exit,
|
||||
cdrom_reset,
|
||||
cdrom_start,
|
||||
cdrom_stop,
|
||||
cdrom_getPlayingInfo,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
int cdrom_init(char *name) {
|
||||
return NG;
|
||||
}
|
||||
|
||||
int cdrom_exit(void) {
|
||||
return OK;
|
||||
}
|
||||
|
||||
int cdrom_reset(void) {
|
||||
return OK;
|
||||
}
|
||||
|
||||
int cdrom_start(int trk, int loop) {
|
||||
return OK;
|
||||
}
|
||||
|
||||
int cdrom_stop() {
|
||||
return OK;
|
||||
}
|
||||
|
||||
int cdrom_getPlayingInfo (cd_time *info) {
|
||||
return NG;
|
||||
}
|
||||
@@ -27,7 +27,7 @@
|
||||
|
||||
static int frame_of_getpos = -1;
|
||||
|
||||
int cdrom_init(char *name) {
|
||||
int cdrom_init(char *playlist) {
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -51,8 +51,6 @@ typedef struct _cdromdevice cdromdevice_t;
|
||||
|
||||
extern cdromdevice_t cdrom_bgm;
|
||||
|
||||
extern cdromdevice_t *cd_init(const char *dev);
|
||||
|
||||
#define CD_FPS 75
|
||||
#define FRAMES_TO_MSF(f, M,S,F) { \
|
||||
int value = f; \
|
||||
|
||||
+6
-1
@@ -64,6 +64,9 @@ static int start_time;
|
||||
static int cdrom_init(char *playlist_path) {
|
||||
char buf[256];
|
||||
|
||||
if (!playlist_path || !playlist_path[0])
|
||||
return NG;
|
||||
|
||||
FILE *fp = fopen(playlist_path, "r");
|
||||
if (fp) {
|
||||
// Skip the first line
|
||||
@@ -72,7 +75,9 @@ static int cdrom_init(char *playlist_path) {
|
||||
fp = fopen("_inmm.ini", "r");
|
||||
}
|
||||
if (!fp) {
|
||||
NOTICE("cdrom: Cannot open playlist %s", playlist_path);
|
||||
// If the game has MIDI music, lack of the playlist is not a problem.
|
||||
if (ald_get_maxno(DRIFILE_MIDI) == 0)
|
||||
NOTICE("cdrom: Cannot open playlist %s", playlist_path);
|
||||
return NG;
|
||||
}
|
||||
|
||||
|
||||
@@ -293,13 +293,8 @@ void cg_load(int no, int flg) {
|
||||
bank = cg_vspPB == -1 ? cg->vsp_bank : cg_vspPB;
|
||||
set_vspbank(cg->pic, bank << 4, cg->width, cg->height);
|
||||
/* copy palettes 0 -> bank */
|
||||
{
|
||||
int i, i_dst = bank << 4;
|
||||
for (i = 0; i < 16; i++) {
|
||||
cg->pal->red[i + i_dst] = cg->pal->red[i];
|
||||
cg->pal->green[i + i_dst] = cg->pal->green[i];
|
||||
cg->pal->blue[i + i_dst] = cg->pal->blue[i];
|
||||
}
|
||||
if (bank != 0) {
|
||||
memcpy(cg->pal + bank * 16, cg->pal, 16 * sizeof(cg->pal[0]));
|
||||
}
|
||||
if (flg != -1) {
|
||||
flg |= (bank << 4);
|
||||
@@ -310,22 +305,22 @@ void cg_load(int no, int flg) {
|
||||
if (GCMD_LOAD_PALETTE(cg_fflg)) {
|
||||
switch(cg->type) {
|
||||
case ALCG_VSP:
|
||||
ags_setPalettes(cg->pal, 0, bank << 4, 16);
|
||||
ags_setPalettes(cg->pal, bank << 4, 16);
|
||||
break;
|
||||
case ALCG_PMS8:
|
||||
// Avoid changing the Windows' reserved palette area (0-9, 246-255)
|
||||
if (cg->pms_bank & 1)
|
||||
ags_setPalettes(cg->pal, 10, 10, 6);
|
||||
ags_setPalettes(cg->pal + 10, 10, 6);
|
||||
if (cg->pms_bank & (1 << 15))
|
||||
//ags_setPalettes(cg->pal, 240, 240, 15);
|
||||
ags_setPalettes(cg->pal, 240, 240, 10);
|
||||
ags_setPalettes(cg->pal + 240, 240, 6);
|
||||
for (i = 1; i < 15; i++) {
|
||||
if (cg->pms_bank & (1 << i)) {
|
||||
ags_setPalettes(cg->pal, i * 16, i * 16, 16);
|
||||
ags_setPalettes(cg->pal + i * 16, i * 16, 16);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ALCG_BMP8:
|
||||
ags_setPalettes(cg->pal, 10, 10, 236);
|
||||
ags_setPalettes(cg->pal + 10, 10, 236);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -463,7 +458,7 @@ int cg_load_with_filename(char *fname_utf8, int x, int y) {
|
||||
/* load palette if not extracted */
|
||||
if (cg->depth == 8) {
|
||||
if (GCMD_LOAD_PALETTE(cg_fflg))
|
||||
ags_setPalettes(cg->pal, 10, 10, 236);
|
||||
ags_setPalettes(cg->pal + 10, 10, 236);
|
||||
if (GCMD_SET_PALETTE(cg_fflg))
|
||||
ags_setPaletteToSystem(0, 256);
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@ typedef struct {
|
||||
|
||||
uint8_t *pic; // extracted pixel data
|
||||
uint8_t *alpha; // extracted alpha data if exists
|
||||
Palette256 *pal; // extracted palette data if exists
|
||||
Color *pal; // 256-color palette if exists
|
||||
|
||||
int vsp_bank; // palette bank for vsp
|
||||
int pms_bank; // palette bank for pms
|
||||
@@ -87,4 +87,11 @@ extern int cg_fflg;
|
||||
extern int *cg_loadCountVar;
|
||||
extern int cg_brightness;
|
||||
|
||||
static inline uint32_t rgb565_to_rgb888(uint16_t rgb) {
|
||||
uint32_t r = rgb >> 11;
|
||||
uint32_t g = (rgb >> 5) & 0x3f;
|
||||
uint32_t b = rgb & 0x1f;
|
||||
return (r << 19) | (r >> 2 << 16) | (g << 10) | (g >> 4 << 8) | (b << 3) | (b >> 2);
|
||||
}
|
||||
|
||||
#endif /* !__CG__ */
|
||||
|
||||
+2
-16
@@ -42,9 +42,6 @@
|
||||
#include "ald_manager.h"
|
||||
#include "LittleEndian.h"
|
||||
#include "hacks.h"
|
||||
#if HAVE_UNAME
|
||||
#include <sys/utsname.h>
|
||||
#endif
|
||||
|
||||
/* 選択 Window OPEN 時 callback */
|
||||
static int cb_sel_init_page = 0;
|
||||
@@ -829,20 +826,9 @@ void commands2F52() {
|
||||
int eNum = getCaliValue();
|
||||
if (eNum <= 0) return;
|
||||
|
||||
#if HAVE_UNAME
|
||||
struct utsname un;
|
||||
char s[256];
|
||||
if (uname(&un) < 0) return;
|
||||
NOTICE("sysname %s nodename %s release %s version %s machine %s",
|
||||
un.sysname, un.nodename, un.release, un.version, un.machine);
|
||||
sprintf(s,"%s %s %s",
|
||||
un.sysname, un.release, un.machine);
|
||||
#else
|
||||
const char *s = CMAKE_SYSTEM_NAME;
|
||||
#endif
|
||||
|
||||
const char *s = SDL_GetPlatform();
|
||||
svar_set(eNum, s);
|
||||
DEBUG_COMMAND("sysGetOsName %d: %s", eNum, s);
|
||||
DEBUG_COMMAND("sysGetOSName %d: %s", eNum, s);
|
||||
}
|
||||
|
||||
void commands2F53() {
|
||||
|
||||
+2
-2
@@ -46,9 +46,9 @@ void commands2F60() {
|
||||
SYSERROR("No DLL initilized");
|
||||
}
|
||||
|
||||
if (dll + type == NULL) goto eexit;
|
||||
if (type < 0 || type >= nact->ain.dllnum) goto eexit;
|
||||
|
||||
if (dll[type].function_num < fnum) goto eexit;
|
||||
if (fnum < 0 || fnum >= dll[type].function_num) goto eexit;
|
||||
|
||||
if (dll[type].function[fnum].entrypoint == NULL) goto eexit;
|
||||
|
||||
|
||||
+12
-1
@@ -27,6 +27,7 @@
|
||||
#include "xsystem35.h"
|
||||
#include "scenario.h"
|
||||
#include "ags.h"
|
||||
#include "hacks.h"
|
||||
|
||||
void commandCC() {
|
||||
int src_x = getCaliValue();
|
||||
@@ -69,7 +70,16 @@ void commandCX() {
|
||||
|
||||
switch(mode) {
|
||||
case 0:
|
||||
ags_copyArea_shadow(src_x, src_y, width, height, dst_x, dst_y);
|
||||
// In Daiakuji, the image after the blending is used as a source image
|
||||
// for sprite copy (CX 1). SDL's SIMD blending implementation has some
|
||||
// error (blending #ff00ff and #ff00ff results in #fd00fd), so the
|
||||
// resulting color may not match the colorkey of CX 1. To workaround
|
||||
// this, specify a small alpha mod so that SDL will use a "slow path"
|
||||
// that does accurate calculation.
|
||||
if (daiakuji_cx_hack)
|
||||
ags_copyArea_shadow_withrate(src_x, src_y, width, height, dst_x, dst_y, 254);
|
||||
else
|
||||
ags_copyArea_shadow(src_x, src_y, width, height, dst_x, dst_y);
|
||||
ags_updateArea(dst_x, dst_y, width, height);
|
||||
break;
|
||||
case 1:
|
||||
@@ -94,6 +104,7 @@ void commandCX() {
|
||||
DEBUG_COMMAND_YET("CX %d,%d,%d,%d,%d,%d,%d,%d:", mode, src_x, src_y, width, height, dst_x, dst_y, col);
|
||||
break;
|
||||
}
|
||||
daiakuji_cx_hack = false;
|
||||
|
||||
DEBUG_COMMAND("CX %d,%d,%d,%d,%d,%d,%d,%d:", mode, src_x, src_y, width, height, dst_x, dst_y, col);
|
||||
}
|
||||
|
||||
+1
-1
@@ -127,7 +127,7 @@ void commandIZ() {
|
||||
int x = getCaliValue();
|
||||
int y = getCaliValue();
|
||||
|
||||
ags_setCursorLocation(x, y, TRUE);
|
||||
ags_setCursorLocation(x, y, true, false);
|
||||
DEBUG_COMMAND("IZ %d,%d:", x, y);
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -326,7 +326,7 @@ void commandMJ() {
|
||||
mj_param.h = h;
|
||||
mj_param.oldstring = t1;
|
||||
|
||||
ags_setCursorLocation(x, y, FALSE); /* XXX */
|
||||
ags_setCursorLocation(x, y, false, false);
|
||||
menu_inputstring2(&mj_param);
|
||||
if (mj_param.newstring == NULL) return;
|
||||
|
||||
|
||||
+3
-3
@@ -112,9 +112,9 @@ void commandPG() { /* T2 */
|
||||
int i;
|
||||
|
||||
for (i = 0; i < num2; i++) {
|
||||
*var = nact->ags.pal->red[num1 + i]; var++;
|
||||
*var = nact->ags.pal->green[num1 + i]; var++;
|
||||
*var = nact->ags.pal->blue[num1 + i]; var++;
|
||||
*var++ = nact->ags.pal[num1 + i].r;
|
||||
*var++ = nact->ags.pal[num1 + i].g;
|
||||
*var++ = nact->ags.pal[num1 + i].b;
|
||||
}
|
||||
DEBUG_COMMAND("PG %p,%d,%d:", var, num1, num2);
|
||||
}
|
||||
|
||||
+6
-5
@@ -113,11 +113,12 @@ void commandZS() {
|
||||
|
||||
void commandZB() {
|
||||
/* メッセージ文字を太さを設定 */
|
||||
int size = getCaliValue();
|
||||
|
||||
nact->msg.MsgFontBoldSize = size;
|
||||
|
||||
DEBUG_COMMAND("ZB %d:",size);
|
||||
int weight = getCaliValue();
|
||||
|
||||
if (nact->ags.enable_zb)
|
||||
nact->ags.font_weight = weight;
|
||||
|
||||
DEBUG_COMMAND("ZB %d:", weight);
|
||||
}
|
||||
|
||||
void commandZH() {
|
||||
|
||||
+10
-3
@@ -360,21 +360,23 @@ void dbg_delete_breakpoints_in_page(int page) {
|
||||
}
|
||||
|
||||
uint8_t dbg_handle_breakpoint(int page, int addr) {
|
||||
uint8_t restore_op = BREAKPOINT;
|
||||
for (Breakpoint *bp = breakpoints; bp; bp = bp->next) {
|
||||
if (bp->phys->page != page || bp->phys->addr != addr)
|
||||
continue;
|
||||
restore_op = bp->phys->restore_op;
|
||||
if (bp->condition && !eval_condition(bp->condition))
|
||||
continue;
|
||||
|
||||
dbg_state = bp->no == INTERNAL_BREAKPOINT_NO ?
|
||||
DBG_STOPPED_NEXT : DBG_STOPPED_BREAKPOINT;
|
||||
|
||||
uint8_t restore_op = bp->phys->restore_op;
|
||||
dbg_main(bp->no); // this may destroy bp
|
||||
return restore_op;
|
||||
}
|
||||
SYSERROR("Illegal BREAKPOINT instruction");
|
||||
return BREAKPOINT;
|
||||
if (restore_op == BREAKPOINT)
|
||||
SYSERROR("Illegal BREAKPOINT instruction");
|
||||
return restore_op;
|
||||
}
|
||||
|
||||
static void set_stack_frame(StackFrame *frame, int page, int addr, boolean is_return_addr) {
|
||||
@@ -528,6 +530,11 @@ void dbg_onsleep(void) {
|
||||
dbg_impl->onsleep();
|
||||
}
|
||||
|
||||
void dbg_on_palette_change(void) {
|
||||
if (dbg_impl && dbg_impl->on_palette_change)
|
||||
dbg_impl->on_palette_change();
|
||||
}
|
||||
|
||||
boolean dbg_console_vprintf(int lv, const char *format, va_list ap) {
|
||||
if (!dbg_impl || !dbg_impl->console_output)
|
||||
return false;
|
||||
|
||||
@@ -45,8 +45,10 @@ void dbg_init(const char *symbols_path, boolean use_dap);
|
||||
void dbg_quit(void);
|
||||
void dbg_main(int bp_no);
|
||||
void dbg_onsleep(void);
|
||||
void dbg_on_palette_change(void);
|
||||
uint8_t dbg_handle_breakpoint(int page, int addr);
|
||||
boolean dbg_console_vprintf(int lv, const char *format, va_list ap);
|
||||
void dbg_post_command(void *data);
|
||||
|
||||
#else // ENABLE_DEBUGGER
|
||||
|
||||
@@ -55,8 +57,10 @@ boolean dbg_console_vprintf(int lv, const char *format, va_list ap);
|
||||
#define dbg_quit()
|
||||
#define dbg_main(bp_no)
|
||||
#define dbg_onsleep()
|
||||
#define dbg_on_palette_change()
|
||||
#define dbg_handle_breakpoint(page, addr) BREAKPOINT
|
||||
#define dbg_console_vprintf(lv, format, ap) false
|
||||
#define dbg_post_command(data)
|
||||
|
||||
#endif // ENABLE_DEBUGGER
|
||||
|
||||
|
||||
+60
-14
@@ -51,6 +51,7 @@ static char *symbols_path;
|
||||
static char *src_dir;
|
||||
static struct msgq *queue;
|
||||
static bool break_on_warnings;
|
||||
static uint32_t palette_version;
|
||||
|
||||
cJSON *create_source(const char *name) {
|
||||
cJSON *source = cJSON_CreateObject();
|
||||
@@ -67,7 +68,7 @@ cJSON *create_source(const char *name) {
|
||||
static void send_json(cJSON *json) {
|
||||
static int seq = 0;
|
||||
|
||||
cJSON_AddNumberToObject(json, "seq", seq);
|
||||
cJSON_AddNumberToObject(json, "seq", ++seq);
|
||||
char *str = cJSON_PrintUnformatted(json);
|
||||
printf("Content-Length: %zu\r\n\r\n%s", strlen(str), str);
|
||||
fflush(stdout);
|
||||
@@ -480,6 +481,20 @@ static void cmd_disconnect(cJSON *args, cJSON *resp) {
|
||||
sys_exit(0);
|
||||
}
|
||||
|
||||
static void cmd_palette(cJSON *args, cJSON *resp) {
|
||||
cJSON *body, *palette;
|
||||
cJSON_AddBoolToObject(resp, "success", true);
|
||||
cJSON_AddItemToObjectCS(resp, "body", body = cJSON_CreateObject());
|
||||
cJSON_AddNumberToObject(body, "version", palette_version);
|
||||
cJSON_AddItemToObjectCS(body, "palette", palette = cJSON_CreateArray());
|
||||
for (int i = 0; i < 256; i++) {
|
||||
int val = nact->ags.pal[i].r << 16 |
|
||||
nact->ags.pal[i].g << 8 |
|
||||
nact->ags.pal[i].b;
|
||||
cJSON_AddItemToArray(palette, cJSON_CreateNumber(val));
|
||||
}
|
||||
}
|
||||
|
||||
static boolean handle_request(cJSON *request) {
|
||||
boolean continue_repl = true;
|
||||
|
||||
@@ -536,8 +551,15 @@ static boolean handle_request(cJSON *request) {
|
||||
cmd_setVariable(args, resp);
|
||||
} else if (!strcmp(command->valuestring, "disconnect")) {
|
||||
cmd_disconnect(args, resp);
|
||||
} else if (!strcmp(command->valuestring, "xsystem35.palette")) {
|
||||
cmd_palette(args, resp);
|
||||
} else {
|
||||
fprintf(stderr, "unknown command \"%s\"\n", command->valuestring);
|
||||
cJSON_AddBoolToObject(resp, "success", false);
|
||||
char *buf = malloc(strlen(command->valuestring) + 30);
|
||||
sprintf(buf, "unknown request \"%s\"", command->valuestring);
|
||||
cJSON_AddStringToObject(resp, "message", buf);
|
||||
fprintf(stderr, "%s\n", buf);
|
||||
free(buf);
|
||||
}
|
||||
send_json(resp);
|
||||
return continue_repl;
|
||||
@@ -567,13 +589,13 @@ static int read_command_thread(void *data) {
|
||||
}
|
||||
char *buf = malloc(content_length);
|
||||
fread(buf, content_length, 1, stdin);
|
||||
msgq_enqueue(queue, buf);
|
||||
sdl_post_debugger_command(buf);
|
||||
content_length = -1;
|
||||
} else {
|
||||
fprintf(stderr, "Unknown Debug Adapter Protocol header: %s", header);
|
||||
}
|
||||
}
|
||||
msgq_enqueue(queue, NULL); // EOF
|
||||
sdl_post_debugger_command(NULL); // end of messages
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -588,11 +610,16 @@ static void dbg_dap_init(const char *path) {
|
||||
|
||||
SDL_CreateThread(read_command_thread, "Debugger", NULL);
|
||||
|
||||
while (!initialized) {
|
||||
char *msg = msgq_dequeue(queue);
|
||||
if (!msg)
|
||||
break;
|
||||
handle_message(msg);
|
||||
while (!initialized && !nact->is_quit) {
|
||||
SDL_Event e;
|
||||
SDL_WaitEvent(&e);
|
||||
sdl_handle_event(&e);
|
||||
while (!msgq_isempty(queue)) {
|
||||
char *msg = msgq_dequeue(queue);
|
||||
if (!msg)
|
||||
return;
|
||||
handle_message(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -605,11 +632,16 @@ static void dbg_dap_repl(int bp_no) {
|
||||
dbg_state = DBG_RUNNING;
|
||||
|
||||
boolean continue_repl = true;
|
||||
while (continue_repl) {
|
||||
char *msg = msgq_dequeue(queue);
|
||||
if (!msg)
|
||||
break;
|
||||
continue_repl = handle_message(msg);
|
||||
while (continue_repl && !nact->is_quit) {
|
||||
SDL_Event e;
|
||||
SDL_WaitEvent(&e);
|
||||
sdl_handle_event(&e);
|
||||
while (!msgq_isempty(queue)) {
|
||||
char *msg = msgq_dequeue(queue);
|
||||
if (!msg)
|
||||
return;
|
||||
continue_repl = handle_message(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -624,10 +656,24 @@ static void dbg_dap_onsleep(void) {
|
||||
dbg_main(0);
|
||||
}
|
||||
|
||||
static void dbg_dap_on_palette_change(void) {
|
||||
cJSON *event = cJSON_CreateObject(), *body;
|
||||
cJSON_AddStringToObject(event, "type", "event");
|
||||
cJSON_AddStringToObject(event, "event", "xsystem35.paletteChanged");
|
||||
cJSON_AddItemToObjectCS(event, "body", body = cJSON_CreateObject());
|
||||
cJSON_AddNumberToObject(body, "version", ++palette_version);
|
||||
send_json(event);
|
||||
}
|
||||
|
||||
void dbg_post_command(void *data) {
|
||||
msgq_enqueue(queue, data);
|
||||
}
|
||||
|
||||
DebuggerImpl dbg_dap_impl = {
|
||||
.init = dbg_dap_init,
|
||||
.quit = dbg_dap_quit,
|
||||
.repl = dbg_dap_repl,
|
||||
.onsleep = dbg_dap_onsleep,
|
||||
.on_palette_change = dbg_dap_on_palette_change,
|
||||
.console_output = emit_output_event,
|
||||
};
|
||||
|
||||
@@ -58,6 +58,7 @@ typedef struct {
|
||||
void (*quit)(void);
|
||||
void (*repl)(int bp_no);
|
||||
void (*onsleep)(void);
|
||||
void (*on_palette_change)(void);
|
||||
void (*console_output)(int lv, const char *output);
|
||||
} DebuggerImpl;
|
||||
|
||||
|
||||
@@ -30,48 +30,48 @@
|
||||
#include "LittleEndian.h"
|
||||
#include "dri.h"
|
||||
|
||||
static bool read_index(int disk, drifiles *d, FILE *fp) {
|
||||
static bool read_index(int volume, drifiles *d, FILE *fp) {
|
||||
fseek(fp, 0L, SEEK_END);
|
||||
int filesize = ftell(fp);
|
||||
|
||||
// Get ptrsize and mapsize
|
||||
// Get the size of offsets table and link table.
|
||||
uint8_t hdr[6];
|
||||
fseek(fp, 0L, SEEK_SET);
|
||||
if (fread(hdr, 6, 1, fp) != 1)
|
||||
return false;
|
||||
int ptrsize = LittleEndian_get3B(hdr, 0) << 8;
|
||||
int mapsize = (LittleEndian_get3B(hdr, 3) << 8) - ptrsize;
|
||||
if (ptrsize <= 0 || mapsize <= 0 || ptrsize + mapsize > filesize)
|
||||
int ofssize = LittleEndian_get3B(hdr, 0) << 8;
|
||||
int linksize = (LittleEndian_get3B(hdr, 3) << 8) - ofssize;
|
||||
if (ofssize <= 0 || linksize <= 0 || ofssize + linksize > filesize)
|
||||
return false;
|
||||
|
||||
// Read the pointer table and the link table
|
||||
uint8_t *ptbl = malloc(ptrsize + mapsize);
|
||||
memcpy(ptbl, hdr, 6);
|
||||
if (fread(ptbl + 6, ptrsize + mapsize - 6, 1, fp) != 1) {
|
||||
free(ptbl);
|
||||
// Read the link table. In System 3.9, only the first volume's link table is
|
||||
// valid. It's different in System 3.8 and earlier, and games that depend
|
||||
// on the old behavior (e.g. Child Assassin in Alice CD 2.50) won't work.
|
||||
if (!d->link) {
|
||||
d->nr_files = linksize / 3;
|
||||
d->link = calloc(1, linksize);
|
||||
d->offset = calloc(sizeof(uint32_t), d->nr_files);
|
||||
fseek(fp, ofssize, SEEK_SET);
|
||||
if (fread(d->link, linksize, 1, fp) != 1)
|
||||
return false;
|
||||
}
|
||||
|
||||
// Read the offsets table.
|
||||
uint8_t *otbl = malloc(ofssize);
|
||||
fseek(fp, 0L, SEEK_SET);
|
||||
if (fread(otbl, ofssize, 1, fp) != 1) {
|
||||
free(otbl);
|
||||
return false;
|
||||
}
|
||||
uint8_t *ltbl = ptbl + ptrsize;
|
||||
|
||||
// (Re)allocate the index buffers
|
||||
int nr_files = mapsize / 3;
|
||||
if (d->nr_files < nr_files) {
|
||||
d->disk = realloc(d->disk, nr_files);
|
||||
d->offset = realloc(d->offset, sizeof(uint32_t) * nr_files);
|
||||
memset(d->disk + d->nr_files, 0, nr_files - d->nr_files);
|
||||
memset(d->offset + d->nr_files, 0, sizeof(uint32_t) * (nr_files - d->nr_files));
|
||||
d->nr_files = nr_files;
|
||||
}
|
||||
|
||||
// Parse the index
|
||||
for (int i = 0; i < nr_files; i++) {
|
||||
if (disk != ltbl[i * 3] - 1)
|
||||
for (int i = 0; i < d->nr_files; i++) {
|
||||
if (d->link[i * 3] != volume)
|
||||
continue;
|
||||
d->disk[i] = ltbl[i * 3];
|
||||
int ptr = LittleEndian_getW(ltbl, i * 3 + 1);
|
||||
d->offset[i] = LittleEndian_get3B(ptbl, ptr * 3) << 8;
|
||||
if (d->maxno < i)
|
||||
d->maxno = i;
|
||||
int offset_index = LittleEndian_getW(d->link, i * 3 + 1);
|
||||
d->offset[i] = LittleEndian_get3B(otbl, offset_index * 3) << 8;
|
||||
}
|
||||
free(ptbl);
|
||||
free(otbl);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -88,7 +88,7 @@ drifiles *dri_init(const char **file, int cnt, boolean use_mmap) {
|
||||
FILE *fp = fopen(file[i], "rb");
|
||||
if (!fp)
|
||||
SYSERROR("%s: %s", file[i], strerror(errno));
|
||||
if (!read_index(i, d, fp)) {
|
||||
if (!read_index(i + 1, d, fp)) {
|
||||
// Only errors in *A.ALD are fatal, because some games have
|
||||
// dummy (invalid) *[B-Z].ALD files.
|
||||
if (i == 0)
|
||||
@@ -115,18 +115,18 @@ drifiles *dri_init(const char **file, int cnt, boolean use_mmap) {
|
||||
}
|
||||
|
||||
dridata *dri_getdata(drifiles *d, int no) {
|
||||
if (no < 0 || no >= d->nr_files || !d->disk[no] || !d->offset[no])
|
||||
if (no < 0 || no >= d->nr_files || !d->link[no * 3] || !d->offset[no])
|
||||
return NULL;
|
||||
int disk = d->disk[no] - 1;
|
||||
int volume = d->link[no * 3];
|
||||
|
||||
uint8_t *data;
|
||||
int ptr, size;
|
||||
if (d->mmapped) {
|
||||
data = d->mmap[disk]->addr + d->offset[no];
|
||||
data = d->mmap[volume - 1]->addr + d->offset[no];
|
||||
ptr = LittleEndian_getDW(data, 0);
|
||||
size = LittleEndian_getDW(data, 4);
|
||||
} else {
|
||||
FILE *fp = fopen(d->fnames[disk], "rb");
|
||||
FILE *fp = fopen(d->fnames[volume - 1], "rb");
|
||||
if (!fp)
|
||||
return NULL;
|
||||
uint8_t entry_header[8];
|
||||
|
||||
@@ -34,7 +34,8 @@ struct _drifiles {
|
||||
mmap_t *mmap[DRIFILEMAX];
|
||||
char *fnames[DRIFILEMAX];
|
||||
int nr_files; // upper limit on how many files could be referenced by this archive
|
||||
uint8_t *disk; // file numbers
|
||||
int maxno;
|
||||
uint8_t *link; // link table
|
||||
uint32_t *offset; // offsets in file
|
||||
};
|
||||
typedef struct _drifiles drifiles;
|
||||
|
||||
@@ -21,12 +21,16 @@
|
||||
*/
|
||||
/* $Id: filecheck.c,v 1.5 2006/04/21 16:40:48 chikama Exp $ */
|
||||
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <dirent.h>
|
||||
#ifdef _WIN32
|
||||
#include <direct.h>
|
||||
#include <windows.h>
|
||||
#undef min
|
||||
#undef max
|
||||
@@ -47,9 +51,65 @@ static char *get_fullpath(const char* dir, const char *filename) {
|
||||
return fn;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
static int make_dir(const char *path)
|
||||
{
|
||||
wchar_t wpath[PATH_MAX + 1];
|
||||
if (!MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, path, -1, wpath, PATH_MAX + 1)) {
|
||||
errno = EILSEQ;
|
||||
return -1;
|
||||
}
|
||||
return _wmkdir(wpath);
|
||||
}
|
||||
|
||||
#else
|
||||
#define make_dir(path) mkdir(path, S_IRWXU)
|
||||
#endif
|
||||
|
||||
// Adapted from http://stackoverflow.com/a/2336245/119527
|
||||
static int mkdir_p(const char *path)
|
||||
{
|
||||
const size_t len = strlen(path);
|
||||
char _path[PATH_MAX];
|
||||
char *p;
|
||||
|
||||
errno = 0;
|
||||
|
||||
// Copy string so its mutable
|
||||
if (len > sizeof(_path)-1) {
|
||||
errno = ENAMETOOLONG;
|
||||
return -1;
|
||||
}
|
||||
strcpy(_path, path);
|
||||
|
||||
// Iterate the string
|
||||
for (p = _path + 1; *p; p++) {
|
||||
if (*p == '/') {
|
||||
// Temporarily truncate
|
||||
*p = '\0';
|
||||
|
||||
if (make_dir(_path) != 0) {
|
||||
if (errno != EEXIST)
|
||||
return -1;
|
||||
}
|
||||
|
||||
*p = '/';
|
||||
}
|
||||
}
|
||||
|
||||
if (make_dir(_path) != 0) {
|
||||
if (errno != EEXIST)
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* list up file in current directory */
|
||||
/* name : save/load directory */
|
||||
void fc_init(const char *name) {
|
||||
mkdir_p(name);
|
||||
saveDataPath = strdup(name);
|
||||
}
|
||||
|
||||
|
||||
+12
-1
@@ -23,6 +23,11 @@
|
||||
#include <math.h>
|
||||
#include <SDL.h>
|
||||
#include <SDL_ttf.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include "win/resources.h"
|
||||
#endif
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
#include <emscripten.h>
|
||||
#endif
|
||||
@@ -73,7 +78,7 @@ static FontTable *font_lookup(int size, int type) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void font_select(int type, int size) {
|
||||
void font_select(int type, int size, int weight) {
|
||||
FontTable *tbl;
|
||||
|
||||
if (NULL == (tbl = font_lookup(size, type))) {
|
||||
@@ -89,6 +94,11 @@ void font_select(int type, int size) {
|
||||
if (fp)
|
||||
fs = TTF_OpenFontIndexRW(SDL_RWFromFP(fp, true), true, size, this.face[type]);
|
||||
}
|
||||
#endif
|
||||
#ifdef _WIN32
|
||||
SDL_RWops *r = open_resource(this.name[type], "fonts");
|
||||
if (r)
|
||||
fs = TTF_OpenFontIndexRW(r, true, size, this.face[type]);
|
||||
#endif
|
||||
if (!fs)
|
||||
SYSERROR("Cannot open font %s", this.name[type]);
|
||||
@@ -98,6 +108,7 @@ void font_select(int type, int size) {
|
||||
} else {
|
||||
fontset = tbl;
|
||||
}
|
||||
TTF_SetFontStyle(fontset->id, weight > 5 ? TTF_STYLE_BOLD : TTF_STYLE_NORMAL);
|
||||
}
|
||||
|
||||
SDL_Surface *font_get_glyph(const char *str_utf8) {
|
||||
|
||||
+4
-1
@@ -31,11 +31,14 @@
|
||||
/* font の種類 */
|
||||
#define FONTTYPEMAX 2
|
||||
|
||||
#define FONT_WEIGHT_NORMAL 4
|
||||
#define FONT_WEIGHT_BOLD 7
|
||||
|
||||
extern void font_init(void);
|
||||
extern void font_set_name_and_index(int type, const char *name, int index);
|
||||
extern void font_set_antialias(boolean enable);
|
||||
extern boolean font_get_antialias(void);
|
||||
extern void font_select(int type, int size);
|
||||
extern void font_select(int type, int size, int weight);
|
||||
extern struct SDL_Surface *font_get_glyph(const char *str_utf8);
|
||||
extern SDL_Rect font_draw_glyph(int x, int y, const char *str_utf8, uint8_t col);
|
||||
|
||||
|
||||
+20
-6
@@ -63,7 +63,7 @@ static void storeSaveName(GameResource *gr, int no, char *src) {
|
||||
if (path) free(path);
|
||||
}
|
||||
|
||||
boolean initGameResourceFromDir(GameResource *gr, DIR *dir, struct dirent *(*p_readdir)(DIR *)) {
|
||||
boolean initGameResourceFromDir(GameResource *gr, DIR *dir, const char *savedir, struct dirent *(*p_readdir)(DIR *)) {
|
||||
memset(gr, 0, sizeof(GameResource));
|
||||
|
||||
char *basename = NULL;
|
||||
@@ -121,14 +121,28 @@ boolean initGameResourceFromDir(GameResource *gr, DIR *dir, struct dirent *(*p_r
|
||||
found_xsleep = true;
|
||||
}
|
||||
}
|
||||
if (basename && !found_xsleep) {
|
||||
char *buf = malloc(strlen(basename) + 6);
|
||||
if (basename && (savedir || !found_xsleep)) {
|
||||
const char *dir = savedir ? savedir : "";
|
||||
const char *sep = savedir ? "/" : "";
|
||||
char *buf = malloc(strlen(dir) + strlen(sep) + strlen(basename) + 9);
|
||||
#if defined(__ANDROID__) || defined(__EMSCRIPTEN__)
|
||||
// Use lowercase 's[a-z].asd' in Android and Emscripten, for compatibility.
|
||||
basename[strlen(basename) - 1] = 's';
|
||||
int a = 'a';
|
||||
#else
|
||||
int a = basename[strlen(basename) - 1] == 'S' ? 'A' : 'a';
|
||||
#endif
|
||||
for (int i = 0; i < SAVE_MAXNUMBER; i++) {
|
||||
sprintf(buf, "%s%c.asd", basename, a + i);
|
||||
sprintf(buf, "%s%s%s%c.asd", dir, sep, basename, a + i);
|
||||
storeSaveName(gr, i, buf);
|
||||
}
|
||||
#ifdef __EMSCRIPTEN__
|
||||
basename[strlen(basename) - 1] = '\0';
|
||||
sprintf(buf, "%s%s%s.msgskip", dir, sep, basename);
|
||||
gr->msgskip = buf;
|
||||
#else
|
||||
free(buf);
|
||||
#endif
|
||||
} else {
|
||||
for (int i = 0; i < SAVE_MAXNUMBER; i++) {
|
||||
char buf[] = "asleep.asd";
|
||||
@@ -220,7 +234,7 @@ static boolean initGameResourceFromFile(GameResource *gr, FILE *fp, const char *
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
boolean initGameResource(GameResource *gr, const char *gr_fname) {
|
||||
boolean initGameResource(GameResource *gr, const char *gr_fname, const char *savedir) {
|
||||
FILE *fp = fopen(gr_fname, "r");
|
||||
if (fp) {
|
||||
boolean result = initGameResourceFromFile(gr, fp, gr_fname);
|
||||
@@ -229,7 +243,7 @@ boolean initGameResource(GameResource *gr, const char *gr_fname) {
|
||||
}
|
||||
DIR *dir = opendir(".");
|
||||
if (dir) {
|
||||
boolean result = initGameResourceFromDir(gr, dir, readdir);
|
||||
boolean result = initGameResourceFromDir(gr, dir, savedir, readdir);
|
||||
closedir(dir);
|
||||
return result;
|
||||
}
|
||||
|
||||
+2
-2
@@ -43,7 +43,7 @@ typedef struct {
|
||||
const char *msgskip;
|
||||
} GameResource;
|
||||
|
||||
boolean initGameResource(GameResource *gr, const char *gr_fname);
|
||||
boolean initGameResourceFromDir(GameResource *gr, DIR *dir, struct dirent *(*p_readdir)(DIR *));
|
||||
boolean initGameResource(GameResource *gr, const char *gr_fname, const char *savedir);
|
||||
boolean initGameResourceFromDir(GameResource *gr, DIR *dir, const char *savedir, struct dirent *(*p_readdir)(DIR *));
|
||||
|
||||
#endif /* !__GAMERESOURCE_H__ */
|
||||
|
||||
+20
-3
@@ -25,7 +25,7 @@
|
||||
|
||||
static void initGameResource_test(void) {
|
||||
GameResource gr;
|
||||
ASSERT_TRUE(initGameResource(&gr, "testdata/test.gr"));
|
||||
ASSERT_TRUE(initGameResource(&gr, "testdata/test.gr", NULL));
|
||||
|
||||
ASSERT_EQUAL(gr.cnt[DRIFILE_SCO], 1);
|
||||
ASSERT_STRCMP(gr.game_fname[DRIFILE_SCO][0], "fooSA.ALD");
|
||||
@@ -96,7 +96,7 @@ static void initGameResourceFromDir_test(void) {
|
||||
};
|
||||
const char **dir = files;
|
||||
GameResource gr;
|
||||
ASSERT_TRUE(initGameResourceFromDir(&gr, (DIR *)&dir, mockReaddir));
|
||||
ASSERT_TRUE(initGameResourceFromDir(&gr, (DIR *)&dir, NULL, mockReaddir));
|
||||
ASSERT_EQUAL(gr.cnt[DRIFILE_SCO], 2);
|
||||
ASSERT_STRCMP(gr.game_fname[DRIFILE_SCO][0], "FOOSA.ALD");
|
||||
ASSERT_STRCMP(gr.game_fname[DRIFILE_SCO][1], "FOOSB.ALD");
|
||||
@@ -120,6 +120,23 @@ static void initGameResourceFromDir_test(void) {
|
||||
for (int i = 2; i < 10; i++)
|
||||
ASSERT_NULL(gr.alk[i]);
|
||||
}
|
||||
{
|
||||
const char *files[] = {
|
||||
"foosa.ald",
|
||||
NULL
|
||||
};
|
||||
const char **dir = files;
|
||||
GameResource gr;
|
||||
ASSERT_TRUE(initGameResourceFromDir(&gr, (DIR *)&dir, "~/save", mockReaddir));
|
||||
ASSERT_EQUAL(gr.cnt[DRIFILE_SCO], 1);
|
||||
ASSERT_STRCMP(gr.game_fname[DRIFILE_SCO][0], "foosa.ald");
|
||||
for (int i = 0; i < 26; i++) {
|
||||
char buf[32];
|
||||
sprintf(buf, "/home/kichikuou/save/foos%c.asd", 'a' + i);
|
||||
ASSERT_STRCMP(gr.save_fname[i], buf);
|
||||
}
|
||||
ASSERT_STRCMP(gr.save_path, "/home/kichikuou/save");
|
||||
}
|
||||
{
|
||||
const char *files[] = {
|
||||
"ADISK.ALD",
|
||||
@@ -128,7 +145,7 @@ static void initGameResourceFromDir_test(void) {
|
||||
};
|
||||
const char **dir = files;
|
||||
GameResource gr;
|
||||
ASSERT_TRUE(initGameResourceFromDir(&gr, (DIR *)&dir, mockReaddir));
|
||||
ASSERT_TRUE(initGameResourceFromDir(&gr, (DIR *)&dir, NULL, mockReaddir));
|
||||
ASSERT_EQUAL(gr.cnt[DRIFILE_SCO], 1);
|
||||
ASSERT_STRCMP(gr.game_fname[DRIFILE_SCO][0], "ADISK.ALD");
|
||||
for (int i = 0; i < 26; i++) {
|
||||
|
||||
+4
-4
@@ -28,10 +28,10 @@
|
||||
#include <SDL_rect.h>
|
||||
|
||||
typedef struct {
|
||||
uint8_t red[256];
|
||||
uint8_t green[256];
|
||||
uint8_t blue[256];
|
||||
} Palette256;
|
||||
uint8_t r;
|
||||
uint8_t g;
|
||||
uint8_t b;
|
||||
} Color;
|
||||
|
||||
typedef struct {
|
||||
uint8_t r,g,b;
|
||||
|
||||
@@ -33,6 +33,8 @@
|
||||
/* defined by cmdy.c */
|
||||
extern boolean Y3waitFlags;
|
||||
|
||||
bool daiakuji_cx_hack;
|
||||
|
||||
void enable_hack_by_gameid(const char *gameid) {
|
||||
if (!strcmp(gameid, "toushin2"))
|
||||
nact->game = GAME_TT2;
|
||||
|
||||
@@ -20,6 +20,8 @@
|
||||
#ifndef __HACKS_H_
|
||||
#define __HACKS_H_
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
enum gameId {
|
||||
GAME_UNKNOWN = 0,
|
||||
GAME_TT2,
|
||||
@@ -31,4 +33,6 @@ enum gameId {
|
||||
void enable_hack_by_gameid(const char *gameid);
|
||||
void enable_hack_by_title(const char *game_title_utf8);
|
||||
|
||||
extern bool daiakuji_cx_hack;
|
||||
|
||||
#endif // __HACKS_H_
|
||||
|
||||
+117
@@ -41,6 +41,123 @@
|
||||
#define KEYWAIT_CANCELABLE 1
|
||||
#define KEYWAIT_SKIPPABLE 2
|
||||
|
||||
// System3.x key codes (IG command, etc.)
|
||||
// These are originated from Windows virtual key codes (VK_*).
|
||||
#define NUM_KEYCODES 256
|
||||
enum keycode {
|
||||
KEY_MOUSE_LEFT = 0x01, // マウスの左ボタン
|
||||
KEY_MOUSE_RIGHT = 0x02, // マウスの右ボタン
|
||||
KEY_CONTROL = 0x03, // コントロール ブレーク処理に使用
|
||||
KEY_MOUSE_MIDDLE = 0x04, // マウスの中央ボタン (3つボタンのマウス)
|
||||
KEY_BACKSPACE = 0x08, // BackSpaceキー
|
||||
KEY_TAB = 0x09, // Tabキー
|
||||
KEY_CLEAR = 0x0c, // Clearキー
|
||||
KEY_RETURN = 0x0d, // Enterキー
|
||||
KEY_SHIFT = 0x10, // Shiftキー
|
||||
KEY_CTRL = 0x11, // Ctrlキー
|
||||
KEY_ALT = 0x12, // Altキー
|
||||
KEY_PAUSE = 0x13, // Pauseキー
|
||||
KEY_CAPSLOCK = 0x14, // Caps Lockキー
|
||||
KEY_KANAKAN = 0x15, // 英数カナキー
|
||||
KEY_ESCAPE = 0x1b, // Escキー
|
||||
KEY_SPACE = 0x20, // Spaceキー
|
||||
KEY_PAGEUP = 0x21, // Page Upキー
|
||||
KEY_PAGEDOWN = 0x22, // Page Downキー
|
||||
KEY_END = 0x23, // Endキー
|
||||
KEY_HOME = 0x24, // Homeキー
|
||||
KEY_LEFT = 0x25, // ←キー
|
||||
KEY_UP = 0x26, // ↑キー
|
||||
KEY_RIGHT = 0x27, // →キー
|
||||
KEY_DOWN = 0x28, // ↓キー
|
||||
KEY_SELECT = 0x29, // Selectキー
|
||||
KEY_EXECUTE = 0x2b, // Executeキー
|
||||
KEY_PRINTSCREEN = 0x2c, // Print Screenキー (Windows 3.0以降用)
|
||||
KEY_INSERT = 0x2d, // Insキー
|
||||
KEY_DELETE = 0x2e, // Delキー
|
||||
KEY_HELP = 0x2f, // Helpキー
|
||||
KEY_0 = 0x30, // 0キー
|
||||
KEY_1 = 0x31, // 1キー
|
||||
KEY_2 = 0x32, // 2キー
|
||||
KEY_3 = 0x33, // 3キー
|
||||
KEY_4 = 0x34, // 4キー
|
||||
KEY_5 = 0x35, // 5キー
|
||||
KEY_6 = 0x36, // 6キー
|
||||
KEY_7 = 0x37, // 7キー
|
||||
KEY_8 = 0x38, // 8キー
|
||||
KEY_9 = 0x39, // 9キー
|
||||
KEY_PAD_EQUALS = 0x3d,
|
||||
KEY_A = 0x41, // Aキー
|
||||
KEY_B = 0x42, // Bキー
|
||||
KEY_C = 0x43, // Cキー
|
||||
KEY_D = 0x44, // Dキー
|
||||
KEY_E = 0x45, // Eキー
|
||||
KEY_F = 0x46, // Fキー
|
||||
KEY_G = 0x47, // Gキー
|
||||
KEY_H = 0x48, // Hキー
|
||||
KEY_I = 0x49, // Iキー
|
||||
KEY_J = 0x4a, // Jキー
|
||||
KEY_K = 0x4b, // Kキー
|
||||
KEY_L = 0x4c, // Lキー
|
||||
KEY_M = 0x4d, // Mキー
|
||||
KEY_N = 0x4e, // Nキー
|
||||
KEY_O = 0x4f, // Oキー
|
||||
KEY_P = 0x50, // Pキー
|
||||
KEY_Q = 0x51, // Qキー
|
||||
KEY_R = 0x52, // Rキー
|
||||
KEY_S = 0x53, // Sキー
|
||||
KEY_T = 0x54, // Tキー
|
||||
KEY_U = 0x55, // Uキー
|
||||
KEY_V = 0x56, // Vキー
|
||||
KEY_W = 0x57, // Wキー
|
||||
KEY_X = 0x58, // Xキー
|
||||
KEY_Y = 0x59, // Yキー
|
||||
KEY_Z = 0x5a, // Zキー
|
||||
KEY_PAD_0 = 0x60, // テンキーの0キー
|
||||
KEY_PAD_1 = 0x61, // テンキーの1キー
|
||||
KEY_PAD_2 = 0x62, // テンキーの2キー
|
||||
KEY_PAD_3 = 0x63, // テンキーの3キー
|
||||
KEY_PAD_4 = 0x64, // テンキーの4キー
|
||||
KEY_PAD_5 = 0x65, // テンキーの5キー
|
||||
KEY_PAD_6 = 0x66, // テンキーの6キー
|
||||
KEY_PAD_7 = 0x67, // テンキーの7キー
|
||||
KEY_PAD_8 = 0x68, // テンキーの8キー
|
||||
KEY_PAD_9 = 0x69, // テンキーの9キー
|
||||
KEY_PAD_MULTIPLY = 0x6a, // テンキーの*キー
|
||||
KEY_PAD_PLUS = 0x6b, // テンキーの+キー
|
||||
KEY_SEPARATOR = 0x6c, // Separatorキー
|
||||
KEY_PAD_MINUS = 0x6d, // テンキーの-キー
|
||||
KEY_PAD_PERIOD = 0x6e, // テンキーの.キー
|
||||
KEY_PAD_DIVIDE = 0x6f, // テンキーの/キー
|
||||
KEY_F1 = 0x70, // F1キー
|
||||
KEY_F2 = 0x71, // F2キー
|
||||
KEY_F3 = 0x72, // F3キー
|
||||
KEY_F4 = 0x73, // F4キー
|
||||
KEY_F5 = 0x74, // F5キー
|
||||
KEY_F6 = 0x75, // F6キー
|
||||
KEY_F7 = 0x76, // F7キー
|
||||
KEY_F8 = 0x77, // F8キー
|
||||
KEY_F9 = 0x78, // F9キー
|
||||
KEY_F10 = 0x79, // F10キー
|
||||
KEY_F11 = 0x7a, // F11キー
|
||||
KEY_F12 = 0x7b, // F12キー
|
||||
KEY_F13 = 0x7c, // F13キー
|
||||
KEY_F14 = 0x7d, // F14キー
|
||||
KEY_F15 = 0x7e, // F15キー
|
||||
KEY_F16 = 0x7f, // F16キー
|
||||
KEY_F17 = 0x80, // F17キー
|
||||
KEY_F18 = 0x81, // F18キー
|
||||
KEY_F19 = 0x82, // F19キー
|
||||
KEY_F20 = 0x83, // F20キー
|
||||
KEY_F21 = 0x84, // F21キー
|
||||
KEY_F22 = 0x85, // F22キー
|
||||
KEY_F23 = 0x86, // F23キー
|
||||
KEY_F24 = 0x87, // F24キー
|
||||
KEY_NUMLOCK = 0x90, // Num Lockキー
|
||||
KEY_SCROLLLOCK = 0x91, // Scroll Lockキー
|
||||
};
|
||||
|
||||
extern boolean RawKeyInfo[NUM_KEYCODES];
|
||||
|
||||
extern int sys_keywait(int msec, unsigned flags);
|
||||
extern int sys_getMouseInfo(MyPoint *p, boolean is_dibgeo);
|
||||
extern int sys_getInputInfo(void);
|
||||
|
||||
@@ -1,153 +0,0 @@
|
||||
/*
|
||||
* key.h keycode definition
|
||||
*
|
||||
* Copyright (C) 2000- Masaki Chikama (Wren) <masaki-c@is.aist-nara.ac.jp>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
/* $Id: key.h,v 1.2 2000/08/11 18:55:51 chikama Exp $ */
|
||||
|
||||
#ifndef __KEYCODE__
|
||||
#define __KEYCODE__
|
||||
|
||||
#define KEY_UNDEFINED (0x00)
|
||||
#define KEY_MOUSE_LEFT (0x01)
|
||||
#define KEY_MOUSE_RIGHT (0x02)
|
||||
#define KEY_CONTROL (0x03)
|
||||
#define KEY_MOUSE_MIDDLE (0x04)
|
||||
#define KEY_BS (0x08)
|
||||
#define KEY_BACKSPACE (0x08)
|
||||
#define KEY_TAB (0x09)
|
||||
#define KEY_CLEAR (0x0c)
|
||||
#define KEY_ENTER (0x0d)
|
||||
#define KEY_PAD_ENTER (0x0d)
|
||||
#define KEY_RETURN (0x0d)
|
||||
#define KEY_SHIFT (0x10)
|
||||
#define KEY_LSHIFT (0x10)
|
||||
#define KEY_RSHIFT (0x10)
|
||||
#define KEY_CTRL (0x11)
|
||||
#define KEY_LCTRL (0x11)
|
||||
#define KEY_RCTRL (0x11)
|
||||
#define KEY_ALT (0x12)
|
||||
#define KEY_LALT (0x12)
|
||||
#define KEY_RALT (0x12)
|
||||
#define KEY_PAUSE (0x13)
|
||||
#define KEY_CAPSLOCK (0x14)
|
||||
#define KEY_KANAKAN (0x15)
|
||||
#define KEY_ESC (0x1b)
|
||||
#define KEY_ESCAPE (0x1b)
|
||||
#define KEY_SPACE (0x20)
|
||||
#define KEY_PAGEUP (0x21)
|
||||
#define KEY_PAGEDOWN (0x22)
|
||||
#define KEY_END (0x23)
|
||||
#define KEY_HOME (0x24)
|
||||
#define KEY_LEFT (0x25)
|
||||
#define KEY_UP (0x26)
|
||||
#define KEY_RIGHT (0x27)
|
||||
#define KEY_DOWN (0x28)
|
||||
#define KEY_SELECT (0x29)
|
||||
#define KEY_EXECUTE (0x2b)
|
||||
#define KEY_PRINTSCREEN (0x2c)
|
||||
#define KEY_INS (0x2d)
|
||||
#define KEY_INSERT (0x2d)
|
||||
#define KEY_DEL (0x2e)
|
||||
#define KEY_DELETE (0x2e)
|
||||
#define KEY_HELP (0x2f)
|
||||
#define KEY_0 (0x30)
|
||||
#define KEY_1 (0x31)
|
||||
#define KEY_2 (0x32)
|
||||
#define KEY_3 (0x33)
|
||||
#define KEY_4 (0x34)
|
||||
#define KEY_5 (0x35)
|
||||
#define KEY_6 (0x36)
|
||||
#define KEY_7 (0x37)
|
||||
#define KEY_8 (0x38)
|
||||
#define KEY_9 (0x39)
|
||||
#define KEY_PAD_EQUALS (0x3d)
|
||||
#define KEY_A (0x41)
|
||||
#define KEY_B (0x42)
|
||||
#define KEY_C (0x43)
|
||||
#define KEY_D (0x44)
|
||||
#define KEY_E (0x45)
|
||||
#define KEY_F (0x46)
|
||||
#define KEY_G (0x47)
|
||||
#define KEY_H (0x48)
|
||||
#define KEY_I (0x49)
|
||||
#define KEY_J (0x4a)
|
||||
#define KEY_K (0x4b)
|
||||
#define KEY_L (0x4c)
|
||||
#define KEY_M (0x4d)
|
||||
#define KEY_N (0x4e)
|
||||
#define KEY_O (0x4f)
|
||||
#define KEY_P (0x50)
|
||||
#define KEY_Q (0x51)
|
||||
#define KEY_R (0x52)
|
||||
#define KEY_S (0x53)
|
||||
#define KEY_T (0x54)
|
||||
#define KEY_U (0x55)
|
||||
#define KEY_V (0x56)
|
||||
#define KEY_W (0x57)
|
||||
#define KEY_X (0x58)
|
||||
#define KEY_Y (0x59)
|
||||
#define KEY_Z (0x5a)
|
||||
#define KEY_PAD_0 (0x60)
|
||||
#define KEY_PAD_1 (0x61)
|
||||
#define KEY_PAD_2 (0x62)
|
||||
#define KEY_PAD_3 (0x63)
|
||||
#define KEY_PAD_4 (0x64)
|
||||
#define KEY_PAD_5 (0x65)
|
||||
#define KEY_PAD_6 (0x66)
|
||||
#define KEY_PAD_7 (0x67)
|
||||
#define KEY_PAD_8 (0x68)
|
||||
#define KEY_PAD_9 (0x69)
|
||||
#define KEY_PAD_STAR (0x6a)
|
||||
#define KEY_PAD_MULTIPLY (0x6a)
|
||||
#define KEY_PAD_PLUS (0x6b)
|
||||
#define KEY_PAD_SEP (0x6c)
|
||||
#define KEY_PAD_MINUS (0x6d)
|
||||
#define KEY_PAD_DOT (0x6e)
|
||||
#define KEY_PAD_PERIOD (0x6e)
|
||||
#define KEY_PAD_SLASH (0x6f)
|
||||
#define KEY_PAD_DIVIDE (0x6f)
|
||||
#define KEY_F1 (0x70)
|
||||
#define KEY_F2 (0x71)
|
||||
#define KEY_F3 (0x72)
|
||||
#define KEY_F4 (0x73)
|
||||
#define KEY_F5 (0x74)
|
||||
#define KEY_F6 (0x75)
|
||||
#define KEY_F7 (0x76)
|
||||
#define KEY_F8 (0x77)
|
||||
#define KEY_F9 (0x78)
|
||||
#define KEY_F10 (0x79)
|
||||
#define KEY_F11 (0x7a)
|
||||
#define KEY_F12 (0x7b)
|
||||
#define KEY_F13 (0x7c)
|
||||
#define KEY_F14 (0x7d)
|
||||
#define KEY_F15 (0x7e)
|
||||
#define KEY_F16 (0x7f)
|
||||
#define KEY_F17 (0x80)
|
||||
#define KEY_F18 (0x81)
|
||||
#define KEY_F19 (0x82)
|
||||
#define KEY_F20 (0x83)
|
||||
#define KEY_F21 (0x84)
|
||||
#define KEY_F22 (0x85)
|
||||
#define KEY_F23 (0x86)
|
||||
#define KEY_F24 (0x87)
|
||||
#define KEY_NUMLOCK (0x90)
|
||||
#define KEY_SCROLL_LOCK (0x91)
|
||||
#define KEY_SCROLLOCK (0x91)
|
||||
|
||||
#endif /* __KEYCODE__ */
|
||||
+3
-5
@@ -20,9 +20,7 @@
|
||||
*/
|
||||
/* $Id: menu_callback.c,v 1.11 2003/04/25 17:23:55 chikama Exp $ */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
#include "config.h"
|
||||
|
||||
#include "portab.h"
|
||||
#include "menu.h"
|
||||
@@ -87,7 +85,7 @@ void
|
||||
on_item5_activate (GtkMenuItem *menuitem,
|
||||
gpointer user_data)
|
||||
{
|
||||
nact->ags.mouse_movesw = MOUSE_WARP_SMOOTH;
|
||||
nact->ags.mouse_warp_enabled = true;
|
||||
gtk_menu_popdown(GTK_MENU(menu_window_popup));
|
||||
}
|
||||
|
||||
@@ -97,7 +95,7 @@ void
|
||||
on_item6_activate (GtkMenuItem *menuitem,
|
||||
gpointer user_data)
|
||||
{
|
||||
nact->ags.mouse_movesw = MOUSE_WARP_DISABLED;
|
||||
nact->ags.mouse_warp_enabled = false;
|
||||
gtk_menu_popdown(GTK_MENU(menu_window_popup));
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
#include "config.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
+4
-4
@@ -64,9 +64,8 @@ static void msgget_at_a();
|
||||
|
||||
void msg_init() {
|
||||
/* メッセージフォントの大きさ */
|
||||
msg.MsgFontSize = 16;
|
||||
msg.MsgFontBoldSize = 0;
|
||||
msg.MsgFont = FONT_GOTHIC;
|
||||
msg.MsgFontSize = 16;
|
||||
msg.MsgFont = FONT_GOTHIC;
|
||||
|
||||
/* 各種色 */
|
||||
msg.MsgFontColor = 255;
|
||||
@@ -141,7 +140,8 @@ void msg_putMessage(const char *m) {
|
||||
// fprintf(stdout, "x=%d, y = %d, msg=%s\n", msgcur.x,msgcur.y,msg);
|
||||
if (!msg.mg_dspMsg) return;
|
||||
|
||||
ags_setFont(msg.MsgFont, msg.MsgFontSize);
|
||||
ags_setFontWithWeight(msg.MsgFont, msg.MsgFontSize, nact->ags.font_weight);
|
||||
|
||||
switch(msgDecorateType) {
|
||||
case 0:
|
||||
default:
|
||||
|
||||
@@ -44,7 +44,6 @@ extern void msg_mg6_command(int cmd);
|
||||
struct __message {
|
||||
/* メッセージフォントの大きさ */
|
||||
int MsgFontSize;
|
||||
int MsgFontBoldSize;
|
||||
int MsgFont;
|
||||
|
||||
/* 各種色 */
|
||||
|
||||
+1
-1
@@ -90,7 +90,7 @@ int midi_init(mididevice_t *midi) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
void midi_set_devicename(char *name) {
|
||||
void midi_set_devicename(const char *name) {
|
||||
if (dev) free(dev);
|
||||
if (0 == strcmp("none", name)) dev = NULL;
|
||||
else dev = strdup(name);
|
||||
|
||||
+1
-1
@@ -52,7 +52,7 @@ struct mididevice {
|
||||
};
|
||||
|
||||
extern int midi_init(mididevice_t *);
|
||||
extern void midi_set_devicename(char *);
|
||||
extern void midi_set_devicename(const char *);
|
||||
extern void midi_set_output_device(int mode);
|
||||
|
||||
#endif /* __MIDI_H__ */
|
||||
|
||||
+4
-1
@@ -89,10 +89,13 @@ static int midi_start(int no, int loop, char *data, int datalen) {
|
||||
|
||||
SDL_RWops *rwops = SDL_RWFromConstMem(data, datalen);
|
||||
mix_music = Mix_LoadMUSType_RW(rwops, MUS_MID, SDL_TRUE /* freesrc */);
|
||||
if (!mix_music)
|
||||
if (!mix_music) {
|
||||
WARNING("Cannot load MIDI: %s", SDL_GetError());
|
||||
return NG;
|
||||
}
|
||||
|
||||
if (Mix_PlayMusic(mix_music, loop ? loop : -1) != 0) {
|
||||
WARNING("Cannot play MIDI: %s", SDL_GetError());
|
||||
Mix_FreeMusic(mix_music);
|
||||
mix_music = NULL;
|
||||
return NG;
|
||||
|
||||
+1
-3
@@ -54,9 +54,7 @@ static unsigned long mt[N]; /* the array for the state vector */
|
||||
static int mti=N+1; /* mti==N+1 means mt[N] is not initialized */
|
||||
|
||||
/* initializing the array with a NONZERO seed */
|
||||
void
|
||||
sgenrand(seed)
|
||||
unsigned long seed;
|
||||
void sgenrand(unsigned long seed)
|
||||
{
|
||||
/* setting initial seeds to mt[N] using */
|
||||
/* the generator Line 25 of Table 1 in */
|
||||
|
||||
+13
-9
@@ -30,11 +30,18 @@
|
||||
#include "music_cdrom.h"
|
||||
#include "cdrom.h"
|
||||
|
||||
static char *dev = CDROM_DEVICE;
|
||||
#ifdef __EMSCRIPTEN__
|
||||
extern cdromdevice_t cdrom_emscripten;
|
||||
#define NATIVE_CD_DEVICE &cdrom_emscripten
|
||||
#else
|
||||
extern cdromdevice_t cdrom_mp3;
|
||||
#define NATIVE_CD_DEVICE &cdrom_mp3
|
||||
#endif
|
||||
|
||||
void muscd_set_devicename(char *name) {
|
||||
if (0 == strcmp("none", name)) dev = NULL;
|
||||
else dev = strdup(name);
|
||||
static char *playlist = DEFAULT_PLAYLIST_PATH;
|
||||
|
||||
void muscd_set_playlist(const char *name) {
|
||||
playlist = strdup(name);
|
||||
}
|
||||
|
||||
int muscd_init(void) {
|
||||
@@ -42,12 +49,9 @@ int muscd_init(void) {
|
||||
if (ald_get_maxno(DRIFILE_BGM) > 0) {
|
||||
prv.cddev = &cdrom_bgm;
|
||||
} else {
|
||||
prv.cddev = cd_init(dev);
|
||||
if (!prv.cddev) {
|
||||
return NG;
|
||||
}
|
||||
prv.cddev = NATIVE_CD_DEVICE;
|
||||
}
|
||||
prv.cddev->init(dev);
|
||||
prv.cddev->init(playlist);
|
||||
prv.cd_current_track = 0;
|
||||
return OK;
|
||||
}
|
||||
|
||||
+1
-1
@@ -27,7 +27,7 @@
|
||||
#include "portab.h"
|
||||
#include "ald_manager.h"
|
||||
|
||||
void muscd_set_devicename(char *);
|
||||
void muscd_set_playlist(const char *);
|
||||
int muscd_init(void);
|
||||
int muscd_init_bgm(DRIFILETYPE type, int base_no);
|
||||
int muscd_exit(void);
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
/*
|
||||
* pcm.dummy.c Dummy PCM implementation
|
||||
*
|
||||
* Copyright (C) 2019 <KichikuouChrome@gmail.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
#include "portab.h"
|
||||
#include "music_pcm.h"
|
||||
|
||||
int muspcm_init(int audio_buffer_size) { return NG; }
|
||||
int muspcm_exit(void) { return NG; }
|
||||
int muspcm_reset(void) { return NG; }
|
||||
int muspcm_load_no(int slot, int no) { return NG; }
|
||||
int muspcm_load_mixlr(int slot, int noL, int noR) { return NG; }
|
||||
int muspcm_load_data(int slot, uint8_t *buf, uint32_t len) { return NG; }
|
||||
int muspcm_unload(int slot) { return NG; }
|
||||
int muspcm_start(int slot, int loop) { return NG; }
|
||||
int muspcm_stop(int slot) { return NG; }
|
||||
int muspcm_fadeout(int slot, int msec) { return NG; }
|
||||
int muspcm_pause(int slot) { return NG; }
|
||||
int muspcm_unpause(int slot) { return NG; }
|
||||
int muspcm_getpos(int slot) { return NG; }
|
||||
int muspcm_setvol(int dev, int slot, int lv) { return NG; }
|
||||
int muspcm_getwavelen(int slot) { return NG; }
|
||||
boolean muspcm_isplaying(int slot) { return FALSE; }
|
||||
int muspcm_waitend(int slot) { return NG; }
|
||||
@@ -44,7 +44,6 @@
|
||||
* static methods
|
||||
*/
|
||||
static pms_header *extract_header(uint8_t *b);
|
||||
static void getpal(Palette256 *pal, uint8_t *b);
|
||||
static void extract_8bit(pms_header *pms, uint8_t *pic, uint8_t *b);
|
||||
static void extract_16bit(pms_header *pms, uint16_t *pic, uint8_t *b);
|
||||
|
||||
@@ -75,17 +74,16 @@ static pms_header *extract_header(uint8_t *b) {
|
||||
|
||||
/*
|
||||
* Get palette from raw data
|
||||
* pal: palette to be stored
|
||||
* b : raw data (pointer to palette)
|
||||
*/
|
||||
static void getpal(Palette256 *pal, uint8_t *b) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 256; i++) {
|
||||
pal->red[i] = *b++;
|
||||
pal->green[i] = *b++;
|
||||
pal->blue[i] = *b++;
|
||||
static Color *getpal(uint8_t *b) {
|
||||
Color *pal = malloc(sizeof(Color) * 256);
|
||||
for (int i = 0; i < 256; i++) {
|
||||
pal[i].r = *b++;
|
||||
pal[i].g = *b++;
|
||||
pal[i].b = *b++;
|
||||
}
|
||||
return pal;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -227,8 +225,7 @@ cgdata *pms256_extract(uint8_t *data) {
|
||||
cgdata *cg = calloc(1, sizeof(cgdata));
|
||||
pms_header *pms = extract_header(data);
|
||||
|
||||
cg->pal = malloc(sizeof(Palette256));
|
||||
getpal(cg->pal, data + pms->pmsPp);
|
||||
cg->pal = getpal(data + pms->pmsPp);
|
||||
|
||||
/* +10: margin for broken cg */
|
||||
cg->pic = malloc(sizeof(uint8_t) * ((pms->pmsXW + 10) * (pms->pmsYW + 10)));
|
||||
|
||||
+28
-39
@@ -28,12 +28,6 @@
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <limits.h>
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#include "win/resources.h"
|
||||
#undef min
|
||||
#undef max
|
||||
#endif
|
||||
|
||||
#include "portab.h"
|
||||
#include "profile.h"
|
||||
@@ -41,7 +35,6 @@
|
||||
|
||||
#define RC_NAME ".xsys35rc"
|
||||
#define RC_LINE_CHARS_MAX 256
|
||||
#define REGKEY_PROFILE XSYSTEM35_REGKEY "\\profile"
|
||||
|
||||
struct profile_kv {
|
||||
char *name;
|
||||
@@ -138,39 +131,14 @@ static int load_rc_file(const char *profile_path)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
static void load_profile_from_registry(HKEY rootKey)
|
||||
{
|
||||
HKEY hKey;
|
||||
LSTATUS err = RegOpenKeyEx(rootKey, REGKEY_PROFILE, 0, KEY_QUERY_VALUE, &hKey);
|
||||
if (err != ERROR_SUCCESS)
|
||||
return;
|
||||
|
||||
for (DWORD index = 0;; index++) {
|
||||
char name[64];
|
||||
BYTE value[RC_LINE_CHARS_MAX];
|
||||
DWORD name_size = sizeof(name);
|
||||
DWORD value_size = sizeof(value);
|
||||
DWORD type;
|
||||
err = RegEnumValue(hKey, index, name, &name_size, NULL, &type, value, &value_size);
|
||||
if (err != ERROR_SUCCESS)
|
||||
break;
|
||||
if (type != REG_SZ)
|
||||
continue;
|
||||
insert_profile(name, value);
|
||||
}
|
||||
}
|
||||
#endif // _WIN32
|
||||
|
||||
int load_profile(void)
|
||||
{
|
||||
char *home_dir = getenv("HOME");
|
||||
#ifdef _WIN32
|
||||
load_profile_from_registry(HKEY_LOCAL_MACHINE);
|
||||
load_profile_from_registry(HKEY_CURRENT_USER);
|
||||
#endif // _WIN32
|
||||
|
||||
char *home_dir;
|
||||
if ((home_dir = getenv("HOME"))) {
|
||||
if (!home_dir)
|
||||
home_dir = getenv("USERPROFILE");
|
||||
#endif
|
||||
if (home_dir) {
|
||||
char profile_path[PATH_MAX];
|
||||
sprintf(profile_path, "%s/%s", home_dir, RC_NAME);
|
||||
load_rc_file(profile_path);
|
||||
@@ -178,11 +146,32 @@ int load_profile(void)
|
||||
return load_rc_file(RC_NAME);
|
||||
}
|
||||
|
||||
char *get_profile(const char *name)
|
||||
{
|
||||
const char *get_profile(const char *name) {
|
||||
struct profile_kv *kv;
|
||||
|
||||
if (!(kv = check_profile(name)))
|
||||
return NULL;
|
||||
return kv->value;
|
||||
}
|
||||
|
||||
bool get_boolean_profile(const char *name, bool *out) {
|
||||
const char *value = get_profile(name);
|
||||
if (!value)
|
||||
return false;
|
||||
const char *yes_values[] = {"yes", "true", "on", "1", NULL};
|
||||
const char *no_values[] = {"no", "false", "off", "0", NULL};
|
||||
for (int i = 0; yes_values[i]; i++) {
|
||||
if (!strcasecmp(value, yes_values[i])) {
|
||||
*out = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
for (int i = 0; no_values[i]; i++) {
|
||||
if (!strcasecmp(value, no_values[i])) {
|
||||
*out = false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
WARNING("invalid profile value for %s: \"%s\"\n", name, value);
|
||||
return false;
|
||||
}
|
||||
|
||||
+4
-1
@@ -25,7 +25,10 @@
|
||||
#ifndef __PROFILE_H__
|
||||
#define __PROFILE_H__
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
int load_profile(void);
|
||||
char *get_profile(const char *name);
|
||||
const char *get_profile(const char *name);
|
||||
bool get_boolean_profile(const char *name, bool *out);
|
||||
|
||||
#endif /* __PROFILE_H__ */
|
||||
|
||||
+5
-2
@@ -25,6 +25,7 @@
|
||||
|
||||
#include "config.h"
|
||||
#include <sys/types.h>
|
||||
#include <SDL_events.h>
|
||||
#include <SDL_surface.h>
|
||||
#include "portab.h"
|
||||
#include "ags.h"
|
||||
@@ -54,7 +55,7 @@ extern void sdl_updateAll(MyRectangle *view_rect);
|
||||
extern void sdl_updateScreen(void);
|
||||
|
||||
/* パレット関係 */
|
||||
extern void sdl_setPalette(Palette256 *pal, int first, int count);
|
||||
extern void sdl_setPalette(Color *pal, int first, int count);
|
||||
|
||||
/* 描画関係 */
|
||||
extern void sdl_drawRectangle(int x, int y, int w, int h, uint8_t c);
|
||||
@@ -94,6 +95,7 @@ void sdl_effect_finish(struct sdl_effect *eff);
|
||||
/* key/pointer 関係 */
|
||||
extern void sdl_setJoyDeviceIndex(int index);
|
||||
extern void sdl_setCursorLocation(int x, int y);
|
||||
extern void sdl_setCursorInternalLocation(int x, int y);
|
||||
extern void sdl_setCursorType(int type);
|
||||
extern boolean sdl_cursorNew(uint8_t* data, int no, CursorImage *cursorImage, TCursorDirEntry *cursordirentry);
|
||||
extern int sdl_getKeyInfo();
|
||||
@@ -106,10 +108,11 @@ extern MyPoint sdl_translateMouseCoords(int x, int y);
|
||||
|
||||
/* misc */
|
||||
extern void sdl_mainIteration();
|
||||
extern boolean RawKeyInfo[];
|
||||
extern uint32_t sdl_getTicks(void);
|
||||
extern void sdl_sleep(int msec);
|
||||
extern void sdl_wait_vsync();
|
||||
extern boolean sdl_inputString(struct inputstring_param *);
|
||||
extern void sdl_post_debugger_command(void *data);
|
||||
extern void sdl_handle_event(SDL_Event *e);
|
||||
|
||||
#endif /* !__SDL_CORE__ */
|
||||
|
||||
+11
-20
@@ -81,7 +81,8 @@ void sdl_sleep(int msec) {
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
EM_JS(void, wait_vsync, (void), {
|
||||
Asyncify.handleSleep(function(wakeUp) {
|
||||
// We need a `return` here for JSPI support (ASYNCIFY=2).
|
||||
return Asyncify.handleSleep(function(wakeUp) {
|
||||
window.requestAnimationFrame(function() {
|
||||
wakeUp();
|
||||
});
|
||||
@@ -118,11 +119,11 @@ void sdl_updateAll(MyRectangle *view_rect) {
|
||||
}
|
||||
|
||||
/* Color の複数個指定 */
|
||||
void sdl_setPalette(Palette256 *pal, int first, int count) {
|
||||
void sdl_setPalette(Color *pal, int first, int count) {
|
||||
for (int i = 0; i < count; i++) {
|
||||
sdl_col[first + i].r = pal->red [first + i];
|
||||
sdl_col[first + i].g = pal->green[first + i];
|
||||
sdl_col[first + i].b = pal->blue [first + i];
|
||||
sdl_col[first + i].r = pal[first + i].r;
|
||||
sdl_col[first + i].g = pal[first + i].g;
|
||||
sdl_col[first + i].b = pal[first + i].b;
|
||||
}
|
||||
if (sdl_dib->format->BitsPerPixel == 8)
|
||||
SDL_SetPaletteColors(sdl_dib->format->palette, &sdl_col[first], first, count);
|
||||
@@ -207,14 +208,7 @@ void sdl_copyArea(int sx, int sy, int w, int h, int dx, int dy) {
|
||||
void sdl_copyAreaSP(int sx, int sy, int w, int h, int dx, int dy, uint8_t sp) {
|
||||
sdl_pal_check();
|
||||
|
||||
Uint32 col = sp;
|
||||
if (sdl_dib->format->BitsPerPixel > 8) {
|
||||
col = SDL_MapRGB(sdl_dib->format,
|
||||
sdl_col[sp].r & 0xf8,
|
||||
sdl_col[sp].g & 0xfc,
|
||||
sdl_col[sp].b & 0xf8);
|
||||
}
|
||||
|
||||
Uint32 col = palette_color(sp);
|
||||
SDL_SetColorKey(sdl_dib, SDL_TRUE, col);
|
||||
|
||||
SDL_Rect r_src = {sx, sy, w, h};
|
||||
@@ -234,13 +228,10 @@ void sdl_drawImage8_fromData(cgdata *cg, int dx, int dy, int sprite_color) {
|
||||
|
||||
if (sdl_dib->format->BitsPerPixel > 8 && cg->pal) {
|
||||
SDL_Color *c = s->format->palette->colors;
|
||||
uint8_t *r = cg->pal->red;
|
||||
uint8_t *g = cg->pal->green;
|
||||
uint8_t *b = cg->pal->blue;
|
||||
for (int i = 0; i < 256; i++) {
|
||||
c->r = *(r++);
|
||||
c->g = *(g++);
|
||||
c->b = *(b++);
|
||||
c->r = cg->pal[i].r;
|
||||
c->g = cg->pal[i].g;
|
||||
c->b = cg->pal[i].b;
|
||||
c++;
|
||||
}
|
||||
} else {
|
||||
@@ -321,7 +312,7 @@ SDL_Rect sdl_drawString(int x, int y, const char *str_utf8, uint8_t col) {
|
||||
* 指定範囲にパレット col を rate の割合で重ねる CK1
|
||||
*/
|
||||
void sdl_wrapColor(int sx, int sy, int w, int h, uint8_t c, int rate) {
|
||||
SDL_Surface *s = SDL_CreateRGBSurface(0, w, h, sdl_dib->format->BitsPerPixel, 0, 0, 0, 0);
|
||||
SDL_Surface *s = SDL_CreateRGBSurfaceWithFormat(0, w, h, sdl_dib->format->BitsPerPixel, sdl_dib->format->format);
|
||||
assert(s->format->BitsPerPixel > 8);
|
||||
|
||||
SDL_Rect r_src = {0, 0, w, h};
|
||||
|
||||
+334
-186
@@ -33,14 +33,13 @@
|
||||
|
||||
#include "portab.h"
|
||||
#include "system.h"
|
||||
#include "debugger.h"
|
||||
#include "nact.h"
|
||||
#include "sdl_core.h"
|
||||
#include "sdl_private.h"
|
||||
#include "key.h"
|
||||
#include "menu.h"
|
||||
#include "input.h"
|
||||
#include "msgskip.h"
|
||||
#include "sdl_keytable.h"
|
||||
|
||||
static void sdl_getEvent(void);
|
||||
static void keyEventProsess(SDL_KeyboardEvent *e, boolean pressed);
|
||||
@@ -49,6 +48,7 @@ static uint32_t custom_event_type = (uint32_t)-1;
|
||||
|
||||
enum CustomEventCode {
|
||||
SIMULATE_RIGHT_BUTTON,
|
||||
DEBUGGER_COMMAND,
|
||||
};
|
||||
|
||||
/* pointer の状態 */
|
||||
@@ -59,6 +59,128 @@ boolean RawKeyInfo[256];
|
||||
/* SDL Joystick */
|
||||
static int joyinfo=0;
|
||||
|
||||
static int sdl_keytable[SDL_NUM_SCANCODES] = {
|
||||
[SDL_SCANCODE_A] = KEY_A,
|
||||
[SDL_SCANCODE_B] = KEY_B,
|
||||
[SDL_SCANCODE_C] = KEY_C,
|
||||
[SDL_SCANCODE_D] = KEY_D,
|
||||
[SDL_SCANCODE_E] = KEY_E,
|
||||
[SDL_SCANCODE_F] = KEY_F,
|
||||
[SDL_SCANCODE_G] = KEY_G,
|
||||
[SDL_SCANCODE_H] = KEY_H,
|
||||
[SDL_SCANCODE_I] = KEY_I,
|
||||
[SDL_SCANCODE_J] = KEY_J,
|
||||
[SDL_SCANCODE_K] = KEY_K,
|
||||
[SDL_SCANCODE_L] = KEY_L,
|
||||
[SDL_SCANCODE_M] = KEY_M,
|
||||
[SDL_SCANCODE_N] = KEY_N,
|
||||
[SDL_SCANCODE_O] = KEY_O,
|
||||
[SDL_SCANCODE_P] = KEY_P,
|
||||
[SDL_SCANCODE_Q] = KEY_Q,
|
||||
[SDL_SCANCODE_R] = KEY_R,
|
||||
[SDL_SCANCODE_S] = KEY_S,
|
||||
[SDL_SCANCODE_T] = KEY_T,
|
||||
[SDL_SCANCODE_U] = KEY_U,
|
||||
[SDL_SCANCODE_V] = KEY_V,
|
||||
[SDL_SCANCODE_W] = KEY_W,
|
||||
[SDL_SCANCODE_X] = KEY_X,
|
||||
[SDL_SCANCODE_Y] = KEY_Y,
|
||||
[SDL_SCANCODE_Z] = KEY_Z,
|
||||
[SDL_SCANCODE_1] = KEY_1,
|
||||
[SDL_SCANCODE_2] = KEY_2,
|
||||
[SDL_SCANCODE_3] = KEY_3,
|
||||
[SDL_SCANCODE_4] = KEY_4,
|
||||
[SDL_SCANCODE_5] = KEY_5,
|
||||
[SDL_SCANCODE_6] = KEY_6,
|
||||
[SDL_SCANCODE_7] = KEY_7,
|
||||
[SDL_SCANCODE_8] = KEY_8,
|
||||
[SDL_SCANCODE_9] = KEY_9,
|
||||
[SDL_SCANCODE_0] = KEY_0,
|
||||
[SDL_SCANCODE_RETURN] = KEY_RETURN,
|
||||
[SDL_SCANCODE_ESCAPE] = KEY_ESCAPE,
|
||||
[SDL_SCANCODE_BACKSPACE] = KEY_BACKSPACE,
|
||||
[SDL_SCANCODE_TAB] = KEY_TAB,
|
||||
[SDL_SCANCODE_SPACE] = KEY_SPACE,
|
||||
// SDL_SCANCODE_MINUS
|
||||
// SDL_SCANCODE_EQUALS
|
||||
// SDL_SCANCODE_LEFTBRACKET
|
||||
// SDL_SCANCODE_RIGHTBRACKET
|
||||
// SDL_SCANCODE_BACKSLASH
|
||||
// SDL_SCANCODE_NONUSHASH
|
||||
// SDL_SCANCODE_SEMICOLON
|
||||
// SDL_SCANCODE_APOSTROPHE
|
||||
// SDL_SCANCODE_GRAVE
|
||||
// SDL_SCANCODE_COMMA
|
||||
// SDL_SCANCODE_PERIOD
|
||||
// SDL_SCANCODE_SLASH
|
||||
[SDL_SCANCODE_CAPSLOCK] = KEY_CAPSLOCK,
|
||||
[SDL_SCANCODE_F1] = KEY_F1,
|
||||
[SDL_SCANCODE_F2] = KEY_F2,
|
||||
[SDL_SCANCODE_F3] = KEY_F3,
|
||||
[SDL_SCANCODE_F4] = KEY_F4,
|
||||
[SDL_SCANCODE_F5] = KEY_F5,
|
||||
[SDL_SCANCODE_F6] = KEY_F6,
|
||||
[SDL_SCANCODE_F7] = KEY_F7,
|
||||
[SDL_SCANCODE_F8] = KEY_F8,
|
||||
[SDL_SCANCODE_F9] = KEY_F9,
|
||||
[SDL_SCANCODE_F10] = KEY_F10,
|
||||
[SDL_SCANCODE_F11] = KEY_F11,
|
||||
[SDL_SCANCODE_F12] = KEY_F12,
|
||||
[SDL_SCANCODE_PRINTSCREEN] = KEY_PRINTSCREEN,
|
||||
[SDL_SCANCODE_SCROLLLOCK] = KEY_SCROLLLOCK,
|
||||
[SDL_SCANCODE_PAUSE] = KEY_PAUSE,
|
||||
[SDL_SCANCODE_INSERT] = KEY_INSERT,
|
||||
[SDL_SCANCODE_HOME] = KEY_HOME,
|
||||
[SDL_SCANCODE_PAGEUP] = KEY_PAGEUP,
|
||||
[SDL_SCANCODE_DELETE] = KEY_DELETE,
|
||||
[SDL_SCANCODE_END] = KEY_END,
|
||||
[SDL_SCANCODE_PAGEDOWN] = KEY_PAGEDOWN,
|
||||
[SDL_SCANCODE_RIGHT] = KEY_RIGHT,
|
||||
[SDL_SCANCODE_LEFT] = KEY_LEFT,
|
||||
[SDL_SCANCODE_DOWN] = KEY_DOWN,
|
||||
[SDL_SCANCODE_UP] = KEY_UP,
|
||||
[SDL_SCANCODE_KP_DIVIDE] = KEY_PAD_DIVIDE,
|
||||
[SDL_SCANCODE_KP_MULTIPLY] = KEY_PAD_MULTIPLY,
|
||||
[SDL_SCANCODE_KP_MINUS] = KEY_PAD_MINUS,
|
||||
[SDL_SCANCODE_KP_PLUS] = KEY_PAD_PLUS,
|
||||
[SDL_SCANCODE_KP_ENTER] = KEY_RETURN,
|
||||
[SDL_SCANCODE_KP_1] = KEY_PAD_1,
|
||||
[SDL_SCANCODE_KP_2] = KEY_PAD_2,
|
||||
[SDL_SCANCODE_KP_3] = KEY_PAD_3,
|
||||
[SDL_SCANCODE_KP_4] = KEY_PAD_4,
|
||||
[SDL_SCANCODE_KP_5] = KEY_PAD_5,
|
||||
[SDL_SCANCODE_KP_6] = KEY_PAD_6,
|
||||
[SDL_SCANCODE_KP_7] = KEY_PAD_7,
|
||||
[SDL_SCANCODE_KP_8] = KEY_PAD_8,
|
||||
[SDL_SCANCODE_KP_9] = KEY_PAD_9,
|
||||
[SDL_SCANCODE_KP_0] = KEY_PAD_0,
|
||||
[SDL_SCANCODE_KP_PERIOD] = KEY_PAD_PERIOD,
|
||||
[SDL_SCANCODE_KP_EQUALS] = KEY_PAD_EQUALS,
|
||||
[SDL_SCANCODE_F13] = KEY_F13,
|
||||
[SDL_SCANCODE_F14] = KEY_F14,
|
||||
[SDL_SCANCODE_F15] = KEY_F15,
|
||||
[SDL_SCANCODE_F16] = KEY_F16,
|
||||
[SDL_SCANCODE_F17] = KEY_F17,
|
||||
[SDL_SCANCODE_F18] = KEY_F18,
|
||||
[SDL_SCANCODE_F19] = KEY_F19,
|
||||
[SDL_SCANCODE_F20] = KEY_F20,
|
||||
[SDL_SCANCODE_F21] = KEY_F21,
|
||||
[SDL_SCANCODE_F22] = KEY_F22,
|
||||
[SDL_SCANCODE_F23] = KEY_F23,
|
||||
[SDL_SCANCODE_F24] = KEY_F24,
|
||||
[SDL_SCANCODE_EXECUTE] = KEY_EXECUTE,
|
||||
[SDL_SCANCODE_HELP] = KEY_HELP,
|
||||
[SDL_SCANCODE_SELECT] = KEY_SELECT,
|
||||
[SDL_SCANCODE_CLEAR] = KEY_CLEAR,
|
||||
[SDL_SCANCODE_SEPARATOR] = KEY_SEPARATOR,
|
||||
[SDL_SCANCODE_LCTRL] = KEY_CTRL,
|
||||
[SDL_SCANCODE_LSHIFT] = KEY_SHIFT,
|
||||
[SDL_SCANCODE_LALT] = KEY_ALT,
|
||||
[SDL_SCANCODE_RCTRL] = KEY_CTRL,
|
||||
[SDL_SCANCODE_RSHIFT] = KEY_SHIFT,
|
||||
[SDL_SCANCODE_RALT] = KEY_ALT,
|
||||
};
|
||||
|
||||
void sdl_event_init(void) {
|
||||
if (custom_event_type == (uint32_t)-1)
|
||||
custom_event_type = SDL_RegisterEvents(1);
|
||||
@@ -101,6 +223,12 @@ void send_agsevent(enum agsevent_type type, int code) {
|
||||
nact->ags.eventcb(&agse); // Async in emscripten
|
||||
}
|
||||
|
||||
void sdl_setCursorInternalLocation(int x, int y) {
|
||||
mousex = x;
|
||||
mousey = y;
|
||||
send_agsevent(AGSEVENT_MOUSE_MOTION, 0);
|
||||
}
|
||||
|
||||
// Improves map navigation of Rance4 v2. See also the function comment of
|
||||
// rance4_Y3_IM_hack() in cmdy.c.
|
||||
static void rance4v2_hack(void) {
|
||||
@@ -113,190 +241,205 @@ static void rance4v2_hack(void) {
|
||||
nact->wait_vsync = FALSE;
|
||||
}
|
||||
|
||||
void sdl_handle_event(SDL_Event *e) {
|
||||
if (sdl_custom_event_handler && sdl_custom_event_handler(e))
|
||||
return;
|
||||
|
||||
switch (e->type) {
|
||||
case SDL_QUIT:
|
||||
menu_quitmenu_open();
|
||||
break;
|
||||
|
||||
case SDL_WINDOWEVENT:
|
||||
switch (e->window.event) {
|
||||
case SDL_WINDOWEVENT_EXPOSED:
|
||||
sdl_dirty = TRUE;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
#ifdef _WIN32
|
||||
case SDL_SYSWMEVENT:
|
||||
win_menu_onsyswmevent(e->syswm.msg);
|
||||
break;
|
||||
#endif
|
||||
case SDL_APP_DIDENTERFOREGROUND:
|
||||
sdl_dirty = TRUE;
|
||||
break;
|
||||
case SDL_KEYDOWN:
|
||||
keyEventProsess(&e->key, TRUE);
|
||||
break;
|
||||
case SDL_KEYUP:
|
||||
keyEventProsess(&e->key, FALSE);
|
||||
switch (e->key.keysym.sym) {
|
||||
case SDLK_F1:
|
||||
msgskip_activate(!msgskip_isActivated());
|
||||
break;
|
||||
case SDLK_F4:
|
||||
sdl_setFullscreen(!sdl_fs_on);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case SDL_MOUSEMOTION:
|
||||
sdl_setCursorInternalLocation(e->motion.x, e->motion.y);
|
||||
break;
|
||||
|
||||
case SDL_MOUSEWHEEL:
|
||||
{
|
||||
int y = e->wheel.y * (e->wheel.direction == SDL_MOUSEWHEEL_FLIPPED ? -1 : 1);
|
||||
if (y > 0)
|
||||
mouse_wheel_up += y;
|
||||
else if (y < 0)
|
||||
mouse_wheel_down -= y;
|
||||
send_agsevent(AGSEVENT_MOUSE_WHEEL, y);
|
||||
break;
|
||||
}
|
||||
|
||||
case SDL_MOUSEBUTTONDOWN:
|
||||
mouseb |= (1 << e->button.button);
|
||||
RawKeyInfo[mouse_to_rawkey(e->button.button)] = TRUE;
|
||||
send_agsevent(AGSEVENT_BUTTON_PRESS, mouse_to_agsevent(e->button.button));
|
||||
break;
|
||||
|
||||
case SDL_MOUSEBUTTONUP:
|
||||
mouseb &= (0xffffffff ^ (1 << e->button.button));
|
||||
RawKeyInfo[mouse_to_rawkey(e->button.button)] = FALSE;
|
||||
send_agsevent(AGSEVENT_BUTTON_RELEASE, mouse_to_agsevent(e->button.button));
|
||||
if (e->button.button == 2) {
|
||||
menu_open();
|
||||
}
|
||||
break;
|
||||
|
||||
case SDL_FINGERDOWN:
|
||||
if (SDL_GetNumTouchFingers(e->tfinger.touchId) >= 2) {
|
||||
mouseb &= ~(1 << SDL_BUTTON_LEFT);
|
||||
mouseb |= 1 << SDL_BUTTON_RIGHT;
|
||||
RawKeyInfo[mouse_to_rawkey(SDL_BUTTON_LEFT)] = FALSE;
|
||||
RawKeyInfo[mouse_to_rawkey(SDL_BUTTON_RIGHT)] = TRUE;
|
||||
send_agsevent(AGSEVENT_BUTTON_PRESS, AGSEVENT_BUTTON_RIGHT);
|
||||
} else {
|
||||
// SDL_RendererEventWatch clamps touch locations outside of the
|
||||
// viewport to 0.0-1.0. Treat such events as right-clicks.
|
||||
int button;
|
||||
if (e->tfinger.x == 0.0f || e->tfinger.x == 1.0f || e->tfinger.y == 0.0f || e->tfinger.y == 1.0f) {
|
||||
button = SDL_BUTTON_RIGHT;
|
||||
} else {
|
||||
button = SDL_BUTTON_LEFT;
|
||||
mousex = e->tfinger.x * view_w;
|
||||
mousey = e->tfinger.y * view_h;
|
||||
send_agsevent(AGSEVENT_MOUSE_MOTION, 0);
|
||||
}
|
||||
mouseb |= 1 << button;
|
||||
RawKeyInfo[mouse_to_rawkey(button)] = TRUE;
|
||||
send_agsevent(AGSEVENT_BUTTON_PRESS, mouse_to_agsevent(button));
|
||||
}
|
||||
break;
|
||||
|
||||
case SDL_FINGERUP:
|
||||
if (SDL_GetNumTouchFingers(e->tfinger.touchId) == 0) {
|
||||
int ags_button = (mouseb & 1 << SDL_BUTTON_LEFT) ? AGSEVENT_BUTTON_LEFT : AGSEVENT_BUTTON_RIGHT;
|
||||
mouseb &= ~(1 << SDL_BUTTON_LEFT | 1 << SDL_BUTTON_RIGHT);
|
||||
RawKeyInfo[mouse_to_rawkey(SDL_BUTTON_LEFT)] = FALSE;
|
||||
RawKeyInfo[mouse_to_rawkey(SDL_BUTTON_RIGHT)] = FALSE;
|
||||
mousex = e->tfinger.x * view_w;
|
||||
mousey = e->tfinger.y * view_h;
|
||||
send_agsevent(AGSEVENT_BUTTON_RELEASE, ags_button);
|
||||
}
|
||||
break;
|
||||
|
||||
case SDL_FINGERMOTION:
|
||||
mousex = e->tfinger.x * view_w;
|
||||
mousey = e->tfinger.y * view_h;
|
||||
send_agsevent(AGSEVENT_MOUSE_MOTION, 0);
|
||||
break;
|
||||
|
||||
case SDL_JOYDEVICEADDED:
|
||||
sdl_joy_open(e->jdevice.which);
|
||||
break;
|
||||
|
||||
case SDL_JOYAXISMOTION:
|
||||
if (abs(e->jaxis.value) < 0x4000) {
|
||||
joyinfo &= e->jaxis.axis == 0 ? ~0xc : ~3;
|
||||
} else {
|
||||
int i = (e->jaxis.axis == 0 ? 2 : 0) +
|
||||
(e->jaxis.value > 0 ? 1 : 0);
|
||||
joyinfo |= 1 << i;
|
||||
}
|
||||
break;
|
||||
|
||||
case SDL_JOYBALLMOTION:
|
||||
break;
|
||||
|
||||
case SDL_JOYHATMOTION:
|
||||
joyinfo &= ~(SYS35KEY_UP | SYS35KEY_DOWN | SYS35KEY_LEFT | SYS35KEY_RIGHT);
|
||||
switch (e->jhat.value) {
|
||||
case SDL_HAT_UP: joyinfo |= SYS35KEY_UP; break;
|
||||
case SDL_HAT_DOWN: joyinfo |= SYS35KEY_DOWN; break;
|
||||
case SDL_HAT_LEFT: joyinfo |= SYS35KEY_LEFT; break;
|
||||
case SDL_HAT_RIGHT: joyinfo |= SYS35KEY_RIGHT; break;
|
||||
case SDL_HAT_LEFTUP: joyinfo |= SYS35KEY_LEFT | SYS35KEY_UP; break;
|
||||
case SDL_HAT_RIGHTUP: joyinfo |= SYS35KEY_RIGHT | SYS35KEY_UP; break;
|
||||
case SDL_HAT_LEFTDOWN: joyinfo |= SYS35KEY_LEFT | SYS35KEY_DOWN; break;
|
||||
case SDL_HAT_RIGHTDOWN: joyinfo |= SYS35KEY_RIGHT | SYS35KEY_DOWN; break;
|
||||
}
|
||||
break;
|
||||
|
||||
case SDL_JOYBUTTONDOWN:
|
||||
case SDL_JOYBUTTONUP:
|
||||
{
|
||||
int mask = 0;
|
||||
switch (e->jbutton.button) {
|
||||
case 0: case 1: case 2: case 3:
|
||||
mask = 1 << (e->jbutton.button + 4);
|
||||
break;
|
||||
#ifdef __EMSCRIPTEN__
|
||||
// Gamepads known to browsers get a "standard" mapping where D-pad
|
||||
// keys are mapped to buttons 12-15.
|
||||
case 12: mask = SYS35KEY_UP; break;
|
||||
case 13: mask = SYS35KEY_DOWN; break;
|
||||
case 14: mask = SYS35KEY_LEFT; break;
|
||||
case 15: mask = SYS35KEY_RIGHT; break;
|
||||
#endif
|
||||
}
|
||||
if (mask) {
|
||||
if (e->jbutton.state == SDL_PRESSED)
|
||||
joyinfo |= mask;
|
||||
else
|
||||
joyinfo &= ~mask;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (e->type == custom_event_type) {
|
||||
switch (e->user.code) {
|
||||
case SIMULATE_RIGHT_BUTTON:
|
||||
if ((intptr_t)e->user.data1) {
|
||||
mouseb |= 1 << SDL_BUTTON_RIGHT;
|
||||
RawKeyInfo[KEY_MOUSE_RIGHT] = TRUE;
|
||||
send_agsevent(AGSEVENT_BUTTON_PRESS, AGSEVENT_BUTTON_RIGHT);
|
||||
} else {
|
||||
mouseb &= ~(1 << SDL_BUTTON_RIGHT);
|
||||
RawKeyInfo[KEY_MOUSE_RIGHT] = FALSE;
|
||||
send_agsevent(AGSEVENT_BUTTON_RELEASE, AGSEVENT_BUTTON_RIGHT);
|
||||
}
|
||||
break;
|
||||
case DEBUGGER_COMMAND:
|
||||
dbg_post_command(e->user.data1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Event処理 */
|
||||
static void sdl_getEvent(void) {
|
||||
static int cmd_count_of_prev_input = -1;
|
||||
SDL_Event e;
|
||||
boolean m2b = FALSE, msg_skip = FALSE;
|
||||
boolean had_input = false;
|
||||
|
||||
SDL_Event e;
|
||||
while (SDL_PollEvent(&e)) {
|
||||
had_input = true;
|
||||
|
||||
if (sdl_custom_event_handler && sdl_custom_event_handler(&e))
|
||||
continue;
|
||||
|
||||
switch (e.type) {
|
||||
case SDL_QUIT:
|
||||
menu_quitmenu_open();
|
||||
break;
|
||||
|
||||
case SDL_WINDOWEVENT:
|
||||
switch (e.window.event) {
|
||||
case SDL_WINDOWEVENT_EXPOSED:
|
||||
sdl_dirty = TRUE;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
#ifdef _WIN32
|
||||
case SDL_SYSWMEVENT:
|
||||
win_menu_onsyswmevent(e.syswm.msg);
|
||||
break;
|
||||
#endif
|
||||
case SDL_APP_DIDENTERFOREGROUND:
|
||||
sdl_dirty = TRUE;
|
||||
break;
|
||||
case SDL_KEYDOWN:
|
||||
keyEventProsess(&e.key, TRUE);
|
||||
break;
|
||||
case SDL_KEYUP:
|
||||
keyEventProsess(&e.key, FALSE);
|
||||
switch (e.key.keysym.sym) {
|
||||
case SDLK_F1:
|
||||
msg_skip = TRUE;
|
||||
break;
|
||||
case SDLK_F4:
|
||||
sdl_setFullscreen(!sdl_fs_on);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case SDL_MOUSEMOTION:
|
||||
mousex = e.motion.x;
|
||||
mousey = e.motion.y;
|
||||
send_agsevent(AGSEVENT_MOUSE_MOTION, 0);
|
||||
break;
|
||||
|
||||
case SDL_MOUSEWHEEL:
|
||||
{
|
||||
int y = e.wheel.y * (e.wheel.direction == SDL_MOUSEWHEEL_FLIPPED ? -1 : 1);
|
||||
if (y > 0)
|
||||
mouse_wheel_up += y;
|
||||
else if (y < 0)
|
||||
mouse_wheel_down -= y;
|
||||
send_agsevent(AGSEVENT_MOUSE_WHEEL, y);
|
||||
break;
|
||||
}
|
||||
|
||||
case SDL_MOUSEBUTTONDOWN:
|
||||
mouseb |= (1 << e.button.button);
|
||||
RawKeyInfo[mouse_to_rawkey(e.button.button)] = TRUE;
|
||||
send_agsevent(AGSEVENT_BUTTON_PRESS, mouse_to_agsevent(e.button.button));
|
||||
break;
|
||||
|
||||
case SDL_MOUSEBUTTONUP:
|
||||
mouseb &= (0xffffffff ^ (1 << e.button.button));
|
||||
RawKeyInfo[mouse_to_rawkey(e.button.button)] = FALSE;
|
||||
send_agsevent(AGSEVENT_BUTTON_RELEASE, mouse_to_agsevent(e.button.button));
|
||||
if (e.button.button == 2) {
|
||||
m2b = TRUE;
|
||||
}
|
||||
break;
|
||||
|
||||
case SDL_FINGERDOWN:
|
||||
if (SDL_GetNumTouchFingers(e.tfinger.touchId) >= 2) {
|
||||
mouseb &= ~(1 << SDL_BUTTON_LEFT);
|
||||
mouseb |= 1 << SDL_BUTTON_RIGHT;
|
||||
RawKeyInfo[mouse_to_rawkey(SDL_BUTTON_LEFT)] = FALSE;
|
||||
RawKeyInfo[mouse_to_rawkey(SDL_BUTTON_RIGHT)] = TRUE;
|
||||
send_agsevent(AGSEVENT_BUTTON_PRESS, AGSEVENT_BUTTON_RIGHT);
|
||||
} else {
|
||||
// SDL_RendererEventWatch clamps touch locations outside of the
|
||||
// viewport to 0.0-1.0. Treat such events as right-clicks.
|
||||
int button;
|
||||
if (e.tfinger.x == 0.0f || e.tfinger.x == 1.0f || e.tfinger.y == 0.0f || e.tfinger.y == 1.0f) {
|
||||
button = SDL_BUTTON_RIGHT;
|
||||
} else {
|
||||
button = SDL_BUTTON_LEFT;
|
||||
mousex = e.tfinger.x * view_w;
|
||||
mousey = e.tfinger.y * view_h;
|
||||
send_agsevent(AGSEVENT_MOUSE_MOTION, 0);
|
||||
}
|
||||
mouseb |= 1 << button;
|
||||
RawKeyInfo[mouse_to_rawkey(button)] = TRUE;
|
||||
send_agsevent(AGSEVENT_BUTTON_PRESS, mouse_to_agsevent(button));
|
||||
}
|
||||
break;
|
||||
|
||||
case SDL_FINGERUP:
|
||||
if (SDL_GetNumTouchFingers(e.tfinger.touchId) == 0) {
|
||||
int ags_button = (mouseb & 1 << SDL_BUTTON_LEFT) ? AGSEVENT_BUTTON_LEFT : AGSEVENT_BUTTON_RIGHT;
|
||||
mouseb &= ~(1 << SDL_BUTTON_LEFT | 1 << SDL_BUTTON_RIGHT);
|
||||
RawKeyInfo[mouse_to_rawkey(SDL_BUTTON_LEFT)] = FALSE;
|
||||
RawKeyInfo[mouse_to_rawkey(SDL_BUTTON_RIGHT)] = FALSE;
|
||||
mousex = e.tfinger.x * view_w;
|
||||
mousey = e.tfinger.y * view_h;
|
||||
send_agsevent(AGSEVENT_BUTTON_RELEASE, ags_button);
|
||||
}
|
||||
break;
|
||||
|
||||
case SDL_FINGERMOTION:
|
||||
mousex = e.tfinger.x * view_w;
|
||||
mousey = e.tfinger.y * view_h;
|
||||
send_agsevent(AGSEVENT_MOUSE_MOTION, 0);
|
||||
break;
|
||||
|
||||
case SDL_JOYDEVICEADDED:
|
||||
sdl_joy_open(e.jdevice.which);
|
||||
break;
|
||||
|
||||
case SDL_JOYAXISMOTION:
|
||||
if (abs(e.jaxis.value) < 0x4000) {
|
||||
joyinfo &= e.jaxis.axis == 0 ? ~0xc : ~3;
|
||||
} else {
|
||||
int i = (e.jaxis.axis == 0 ? 2 : 0) +
|
||||
(e.jaxis.value > 0 ? 1 : 0);
|
||||
joyinfo |= 1 << i;
|
||||
}
|
||||
break;
|
||||
|
||||
case SDL_JOYBALLMOTION:
|
||||
break;
|
||||
|
||||
case SDL_JOYHATMOTION:
|
||||
joyinfo &= ~(SYS35KEY_UP | SYS35KEY_DOWN | SYS35KEY_LEFT | SYS35KEY_RIGHT);
|
||||
switch (e.jhat.value) {
|
||||
case SDL_HAT_UP: joyinfo |= SYS35KEY_UP; break;
|
||||
case SDL_HAT_DOWN: joyinfo |= SYS35KEY_DOWN; break;
|
||||
case SDL_HAT_LEFT: joyinfo |= SYS35KEY_LEFT; break;
|
||||
case SDL_HAT_RIGHT: joyinfo |= SYS35KEY_RIGHT; break;
|
||||
case SDL_HAT_LEFTUP: joyinfo |= SYS35KEY_LEFT | SYS35KEY_UP; break;
|
||||
case SDL_HAT_RIGHTUP: joyinfo |= SYS35KEY_RIGHT | SYS35KEY_UP; break;
|
||||
case SDL_HAT_LEFTDOWN: joyinfo |= SYS35KEY_LEFT | SYS35KEY_DOWN; break;
|
||||
case SDL_HAT_RIGHTDOWN: joyinfo |= SYS35KEY_RIGHT | SYS35KEY_DOWN; break;
|
||||
}
|
||||
break;
|
||||
|
||||
case SDL_JOYBUTTONDOWN:
|
||||
case SDL_JOYBUTTONUP:
|
||||
if (e.jbutton.button < 4) {
|
||||
int i = 1 << (e.jbutton.button+4);
|
||||
if (e.jbutton.state == SDL_PRESSED)
|
||||
joyinfo |= i;
|
||||
else
|
||||
joyinfo &= ~i;
|
||||
} else {
|
||||
if (e.jbutton.state == SDL_RELEASED) {
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (e.type == custom_event_type) {
|
||||
switch (e.user.code) {
|
||||
case SIMULATE_RIGHT_BUTTON:
|
||||
if ((intptr_t)e.user.data1) {
|
||||
mouseb |= 1 << SDL_BUTTON_RIGHT;
|
||||
RawKeyInfo[KEY_MOUSE_RIGHT] = TRUE;
|
||||
send_agsevent(AGSEVENT_BUTTON_PRESS, AGSEVENT_BUTTON_RIGHT);
|
||||
} else {
|
||||
mouseb &= ~(1 << SDL_BUTTON_RIGHT);
|
||||
RawKeyInfo[KEY_MOUSE_RIGHT] = FALSE;
|
||||
send_agsevent(AGSEVENT_BUTTON_RELEASE, AGSEVENT_BUTTON_RIGHT);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
sdl_handle_event(&e);
|
||||
}
|
||||
if (had_input) {
|
||||
cmd_count_of_prev_input = nact->cmd_count;
|
||||
@@ -305,12 +448,6 @@ static void sdl_getEvent(void) {
|
||||
if (nact->game == GAME_RANCE4_V2)
|
||||
rance4v2_hack();
|
||||
}
|
||||
|
||||
if (m2b) {
|
||||
menu_open();
|
||||
}
|
||||
|
||||
if (msg_skip) msgskip_activate(!msgskip_isActivated());
|
||||
}
|
||||
|
||||
/* キー情報の取得 */
|
||||
@@ -331,7 +468,7 @@ int sdl_getKeyInfo() {
|
||||
((RawKeyInfo[KEY_RIGHT] || RawKeyInfo[KEY_PAD_6]) << 3) |
|
||||
(RawKeyInfo[KEY_RETURN] << 4) |
|
||||
(RawKeyInfo[KEY_SPACE ] << 5) |
|
||||
(RawKeyInfo[KEY_ESC] << 6) |
|
||||
(RawKeyInfo[KEY_ESCAPE] << 6) |
|
||||
(RawKeyInfo[KEY_TAB] << 7));
|
||||
|
||||
return rt;
|
||||
@@ -368,6 +505,17 @@ int sdl_getJoyInfo(void) {
|
||||
return joyinfo;
|
||||
}
|
||||
|
||||
void sdl_post_debugger_command(void *data) {
|
||||
SDL_Event event = {
|
||||
.user = {
|
||||
.type = custom_event_type,
|
||||
.code = DEBUGGER_COMMAND,
|
||||
.data1 = data
|
||||
}
|
||||
};
|
||||
SDL_PushEvent(&event);
|
||||
}
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
EMSCRIPTEN_KEEPALIVE
|
||||
void simulate_right_button(int pressed) {
|
||||
|
||||
+44
-79
@@ -34,8 +34,6 @@
|
||||
#include "alpha_plane.h"
|
||||
#include "image.h"
|
||||
|
||||
static unsigned char shlv_tbl[256*256];
|
||||
|
||||
/*
|
||||
* dib内での拡大・縮小コピー
|
||||
*/
|
||||
@@ -47,7 +45,7 @@ void sdl_scaledCopyArea(int sx, int sy, int sw, int sh, int dx, int dy, int dw,
|
||||
SDL_Surface *src = sdl_dib;
|
||||
SDL_Surface *dst = sdl_dib;
|
||||
|
||||
ss = SDL_CreateRGBSurface(0, dw, dh, dst->format->BitsPerPixel, 0, 0, 0, 0);
|
||||
ss = SDL_CreateRGBSurfaceWithFormat(0, dw, dh, dst->format->BitsPerPixel, dst->format->format);
|
||||
|
||||
if (dst->format->BitsPerPixel == 8) {
|
||||
memcpy(ss->format->palette->colors, dst->format->palette->colors,
|
||||
@@ -142,40 +140,43 @@ void sdl_drawImage16_fromData(cgdata *cg, int dx, int dy, int brightness, bool a
|
||||
int w = cg->width;
|
||||
int h = cg->height;
|
||||
|
||||
SDL_Surface *s;
|
||||
if (cg->alpha && alpha_blend) {
|
||||
unsigned short *p_src = (uint16_t *)cg->pic;
|
||||
uint32_t *p_ds, *p_dst;
|
||||
if (cg->alpha) {
|
||||
uint8_t *a_src = cg->alpha;
|
||||
uint8_t *adata = GETOFFSET_ALPHA(sdl_dibinfo, dx, dy);
|
||||
int x, y, l;
|
||||
|
||||
s = SDL_CreateRGBSurfaceWithFormat(0, w, h, 32, SDL_PIXELFORMAT_ARGB8888);
|
||||
p_ds = s->pixels;
|
||||
l = s->pitch/4;
|
||||
for (y = 0; y < h; y++) {
|
||||
p_dst = p_ds;
|
||||
|
||||
for (int i = 0; i < h; i++) {
|
||||
memcpy(adata, a_src, w);
|
||||
for (x = 0; x < w; x++) {
|
||||
*p_dst++ = *a_src++ << 24 | PIX24(PIXR16(*p_src), PIXG16(*p_src), PIXB16(*p_src));
|
||||
p_src++;
|
||||
}
|
||||
p_ds += l;
|
||||
adata += sdl_dibinfo->width;
|
||||
a_src += cg->width;
|
||||
}
|
||||
}
|
||||
|
||||
SDL_Surface *s;
|
||||
if (cg->alpha && alpha_blend) {
|
||||
uint16_t *p_src = (uint16_t *)cg->pic;
|
||||
uint8_t *a_src = cg->alpha;
|
||||
s = SDL_CreateRGBSurfaceWithFormat(0, w, h, 32, SDL_PIXELFORMAT_ARGB8888);
|
||||
for (int y = 0; y < h; y++) {
|
||||
uint32_t *dst = (uint32_t *)(((uint8_t *)s->pixels) + y * s->pitch);
|
||||
for (int x = 0; x < w; x++) {
|
||||
*dst++ = rgb565_to_rgb888(*p_src++) | *a_src++ << 24;
|
||||
}
|
||||
}
|
||||
} else if (sdl_dibinfo->depth > 16) {
|
||||
// Convert to RGB888 by ourselves. SDL blit functions use a slightly
|
||||
// different mapping, so the color expanded by SDL may not match the
|
||||
// color key specified in the CX command.
|
||||
uint16_t *src = (uint16_t *)cg->pic;
|
||||
s = SDL_CreateRGBSurfaceWithFormat(0, w, h, 32, SDL_PIXELFORMAT_RGB888);
|
||||
for (int y = 0; y < h; y++) {
|
||||
uint32_t *dst = (uint32_t *)(((uint8_t *)s->pixels) + y * s->pitch);
|
||||
for (int x = 0; x < w; x++) {
|
||||
*dst++ = rgb565_to_rgb888(*src++);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
s = SDL_CreateRGBSurfaceWithFormatFrom(
|
||||
cg->pic, cg->width, cg->height, 16, cg->width * 2, SDL_PIXELFORMAT_RGB565);
|
||||
if (cg->alpha) {
|
||||
uint8_t *a_src = cg->alpha;
|
||||
uint8_t *adata = GETOFFSET_ALPHA(sdl_dibinfo, dx, dy);
|
||||
|
||||
for (int i = 0; i < h; i++) {
|
||||
memcpy(adata, a_src, w);
|
||||
adata += sdl_dibinfo->width;
|
||||
a_src += cg->width;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (brightness != 255)
|
||||
@@ -203,65 +204,31 @@ void sdl_drawImage24_fromData(cgdata *cg, int x, int y, int brightness) {
|
||||
SDL_FreeSurface(s);
|
||||
}
|
||||
|
||||
/*
|
||||
* 16bit専用の dib の指定領域コピー alphaつき
|
||||
*/
|
||||
void sdl_shadow_init(void) {
|
||||
int i, j;
|
||||
unsigned char *c = shlv_tbl;
|
||||
|
||||
for (i = 0; i < 255; i++) {
|
||||
for (j = 0; j < 256; j++) {
|
||||
*(c++) = (unsigned char)(i * j / 255);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void sdl_copyAreaSP16_shadow(int sx, int sy, int w, int h, int dx, int dy, int lv) {
|
||||
uint8_t *adata = GETOFFSET_ALPHA(sdl_dibinfo, sx, sy);
|
||||
uint8_t *p_src, *p_dst, *p_ds;
|
||||
|
||||
SDL_Surface *s = SDL_CreateRGBSurfaceWithFormat(0, w, h, 32, SDL_PIXELFORMAT_ARGB8888);
|
||||
int x, y;
|
||||
|
||||
SDL_Rect r_src = {sx, sy, w, h};
|
||||
SDL_Rect r_tmp = { 0, 0, w, h};
|
||||
SDL_BlitSurface(sdl_dib, &r_src, s, &r_tmp);
|
||||
|
||||
#if SDL_BYTEORDER == SDL_LIL_ENDIAN
|
||||
p_ds = s->pixels + 3;
|
||||
uint8_t *p_ds = s->pixels + 3;
|
||||
#else
|
||||
p_ds = s->pixels;
|
||||
uint8_t *p_ds = s->pixels;
|
||||
#endif
|
||||
switch(lv) {
|
||||
case 255:
|
||||
for (y = 0; y < h; y++) {
|
||||
p_src = adata;
|
||||
p_dst = p_ds;
|
||||
for (x = 0; x < w; x++) {
|
||||
*p_dst = *(p_src++);
|
||||
p_dst += 4;
|
||||
}
|
||||
adata += sdl_dibinfo->width;
|
||||
p_ds += s->pitch;
|
||||
uint8_t *adata = GETOFFSET_ALPHA(sdl_dibinfo, sx, sy);
|
||||
for (int y = 0; y < h; y++) {
|
||||
uint8_t *p_src = adata;
|
||||
uint8_t *p_dst = p_ds;
|
||||
for (int x = 0; x < w; x++) {
|
||||
*p_dst = *(p_src++);
|
||||
p_dst += 4;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
{
|
||||
unsigned char *lvtbl = shlv_tbl + lv * 256;
|
||||
for (y = 0; y < h; y++) {
|
||||
p_src = adata;
|
||||
p_dst = p_ds;
|
||||
for (x = 0; x < w; x++) {
|
||||
*p_dst = lvtbl[(int)(*(p_src++))];
|
||||
p_dst += 4;
|
||||
}
|
||||
adata += sdl_dibinfo->width;
|
||||
p_ds += s->pitch;
|
||||
}
|
||||
}
|
||||
break;
|
||||
adata += sdl_dibinfo->width;
|
||||
p_ds += s->pitch;
|
||||
}
|
||||
if (lv < 255)
|
||||
SDL_SetSurfaceAlphaMod(s, lv);
|
||||
|
||||
SDL_Rect r_dst = {dx, dy, w, h};
|
||||
SDL_BlitSurface(s, &r_tmp, sdl_dib, &r_dst);
|
||||
@@ -334,9 +301,7 @@ void sdl_getPixel(int x, int y, Palette *cell) {
|
||||
* dib から領域の切り出し
|
||||
*/
|
||||
void* sdl_saveRegion(int x, int y, int w, int h) {
|
||||
SDL_Surface *s = SDL_CreateRGBSurface(0, w, h, sdl_dib->format->BitsPerPixel,
|
||||
sdl_dib->format->Rmask, sdl_dib->format->Gmask,
|
||||
sdl_dib->format->Bmask, sdl_dib->format->Amask);
|
||||
SDL_Surface *s = SDL_CreateRGBSurfaceWithFormat(0, w, h, sdl_dib->format->BitsPerPixel, sdl_dib->format->format);
|
||||
if (sdl_dib->format->BitsPerPixel == 8)
|
||||
memcpy(s->format->palette->colors, sdl_dib->format->palette->colors,
|
||||
sizeof(SDL_Color) * sdl_dib->format->palette->ncolors);
|
||||
|
||||
@@ -1,73 +0,0 @@
|
||||
static int sdl_keytable[SDL_NUM_SCANCODES] = {
|
||||
0, KEY_UNDEFINED, KEY_UNDEFINED, KEY_UNDEFINED,
|
||||
KEY_A, KEY_B, KEY_C, KEY_D,
|
||||
KEY_E, KEY_F, KEY_G, KEY_H,
|
||||
KEY_I, KEY_J, KEY_K, KEY_L,
|
||||
KEY_M, KEY_N, KEY_O, KEY_P,
|
||||
KEY_Q, KEY_R, KEY_S, KEY_T,
|
||||
KEY_U, KEY_V, KEY_W, KEY_X,
|
||||
KEY_Y, KEY_Z, KEY_1, KEY_2,
|
||||
KEY_3, KEY_4, KEY_5, KEY_6,
|
||||
KEY_7, KEY_8, KEY_9, KEY_0,
|
||||
KEY_RETURN, KEY_ESCAPE, KEY_BACKSPACE, KEY_TAB,
|
||||
KEY_SPACE, 45, 46, 47,
|
||||
48, 49, 50, 51,
|
||||
52, 53, 54, 55,
|
||||
56, KEY_CAPSLOCK, KEY_F1, KEY_F2,
|
||||
KEY_F3, KEY_F4, KEY_F5, KEY_F6,
|
||||
KEY_F7, KEY_F8, KEY_F9, KEY_F10,
|
||||
KEY_F11, KEY_F12, KEY_PRINTSCREEN, 71,
|
||||
KEY_PAUSE, KEY_INSERT, KEY_HOME, KEY_PAGEUP,
|
||||
KEY_DELETE, KEY_END, KEY_PAGEDOWN, KEY_RIGHT,
|
||||
KEY_LEFT, KEY_DOWN, KEY_UP, 83,
|
||||
KEY_PAD_DIVIDE, KEY_PAD_MULTIPLY, KEY_PAD_MINUS, KEY_PAD_PLUS,
|
||||
KEY_PAD_ENTER, KEY_PAD_1, KEY_PAD_2, KEY_PAD_3,
|
||||
KEY_PAD_4, KEY_PAD_5, KEY_PAD_6, KEY_PAD_7,
|
||||
KEY_PAD_8, KEY_PAD_9, KEY_PAD_0, KEY_PAD_PERIOD,
|
||||
0 /* SDL_NONUSBACKSLASH */, 0 /* SDL_APPLICATION */, 0 /* SDL_POWER */, KEY_PAD_EQUALS,
|
||||
KEY_F13, KEY_F14, KEY_F15, KEY_F16,
|
||||
KEY_F17, KEY_F18, KEY_F19, KEY_F20,
|
||||
KEY_F21, KEY_F22, KEY_F23, KEY_F24,
|
||||
KEY_EXECUTE, KEY_HELP, 0 /* SDL_MENU */, KEY_SELECT,
|
||||
0 /* SDL_STOP */, 0 /* SDL_AGAIN */, 0 /* SDL_UNDO */, 0 /* SDL_CUT */,
|
||||
0 /* SDL_COPY */, 0 /* SDL_PASTE */, 0 /* SDL_FIND */, 0 /* SDL_MUTE */,
|
||||
0 /* SDL_VOLUMEUP */, 0 /* SDL_VOLUMEDOWN */, 0 /* SDL_LOCKINGCAPSLOCK */, 0 /* SDL_LOCKINGNUMLOCK */,
|
||||
0 /* SDL_LOCKINGSCROLLLOCK */, 0 /* SDL_PAD_COMMA */, 0 /* SDL_PAD_EQUALSAS400 */, 0 /* SDL_INTERNATIONAL1 */,
|
||||
0 /* SDL_INTERNATIONAL2 */, 0 /* SDL_INTERNATIONAL3 */, 0 /* SDL_INTERNATIONAL4 */, 0 /* SDL_INTERNATIONAL5 */,
|
||||
0 /* SDL_INTERNATIONAL6 */, 0 /* SDL_INTERNATIONAL7 */, 0 /* SDL_INTERNATIONAL8 */, 0 /* SDL_INTERNATIONAL9 */,
|
||||
0 /* SDL_LANG1 */, 0 /* SDL_LANG2 */, 0 /* SDL_LANG3 */, 0 /* SDL_LANG4 */,
|
||||
0 /* SDL_LANG5 */, 0 /* SDL_LANG6 */, 0 /* SDL_LANG7 */, 0 /* SDL_LANG8 */,
|
||||
0 /* SDL_LANG9 */, 0 /* SDL_ALTERASE */, 0 /* SDL_SYSREQ */, 0 /* SDL_CANCEL */,
|
||||
KEY_CLEAR, 0 /* SDL_PRIOR */, 0 /* SDL_RETURN2 */, 0 /* SDL_SEPARATOR */,
|
||||
0 /* SDL_OUT */, 0 /* SDL_OPER */, 0 /* SDL_CLEARAGAIN */, 0 /* SDL_CRSEL */,
|
||||
0 /* SDL_EXSEL */, KEY_UNDEFINED, KEY_UNDEFINED, KEY_UNDEFINED,
|
||||
KEY_UNDEFINED, KEY_UNDEFINED, KEY_UNDEFINED, KEY_UNDEFINED,
|
||||
KEY_UNDEFINED, KEY_UNDEFINED, KEY_UNDEFINED, KEY_UNDEFINED,
|
||||
0 /* SDL_PAD_00 */, 0 /* SDL_PAD_000 */, 0 /* SDL_THOUSANDSSEPARATOR */, 0 /* SDL_DECIMALSEPARATOR */,
|
||||
0 /* SDL_CURRENCYUNIT */, 0 /* SDL_CURRENCYSUBUNIT */, 0 /* SDL_PAD_LEFTPAREN */, 0 /* SDL_PAD_RIGHTPAREN */,
|
||||
0 /* SDL_PAD_LEFTBRACE */, 0 /* SDL_PAD_RIGHTBRACE */, 0 /* SDL_PAD_TAB */, 0 /* SDL_PAD_BACKSPACE */,
|
||||
0 /* SDL_PAD_A */, 0 /* SDL_PAD_B */, 0 /* SDL_PAD_C */, 0 /* SDL_PAD_D */,
|
||||
0 /* SDL_PAD_E */, 0 /* SDL_PAD_F */, 0 /* SDL_PAD_XOR */, 0 /* SDL_PAD_POWER */,
|
||||
0 /* SDL_PAD_PERCENT */, 0 /* SDL_PAD_LESS */, 0 /* SDL_PAD_GREATER */, 0 /* SDL_PAD_AMPERSAND */,
|
||||
0 /* SDL_PAD_DBLAMPERSAND */, 0 /* SDL_PAD_VERTICALBAR */, 0 /* SDL_PAD_DBLVERTICALBAR */, 0 /* SDL_PAD_COLON */,
|
||||
0 /* SDL_PAD_HASH */, 0 /* SDL_PAD_SPACE */, 0 /* SDL_PAD_AT */, 0 /* SDL_PAD_EXCLAM */,
|
||||
0 /* SDL_PAD_MEMSTORE */, 0 /* SDL_PAD_MEMRECALL */, 0 /* SDL_PAD_MEMCLEAR */, 0 /* SDL_PAD_MEMADD */,
|
||||
0 /* SDL_PAD_MEMSUBTRACT */, 0 /* SDL_PAD_MEMMULTIPLY */, 0 /* SDL_PAD_MEMDIVIDE */, 0 /* SDL_PAD_PLUSMINUS */,
|
||||
0 /* SDL_PAD_CLEAR */, 0 /* SDL_PAD_CLEARENTRY */, 0 /* SDL_PAD_BINARY */, 0 /* SDL_PAD_OCTAL */,
|
||||
0 /* SDL_PAD_DECIMAL */, 0 /* SDL_PAD_HEXADECIMAL */, KEY_UNDEFINED, KEY_UNDEFINED,
|
||||
KEY_RCTRL, KEY_RSHIFT, KEY_RALT, 0 /* SDL_LGUI */,
|
||||
KEY_RCTRL, KEY_RSHIFT, KEY_RALT, 0 /* SDL_RGUI */,
|
||||
KEY_UNDEFINED, KEY_UNDEFINED, KEY_UNDEFINED, KEY_UNDEFINED,
|
||||
KEY_UNDEFINED, KEY_UNDEFINED, KEY_UNDEFINED, KEY_UNDEFINED,
|
||||
KEY_UNDEFINED, KEY_UNDEFINED, KEY_UNDEFINED, KEY_UNDEFINED,
|
||||
KEY_UNDEFINED, KEY_UNDEFINED, KEY_UNDEFINED, KEY_UNDEFINED,
|
||||
KEY_UNDEFINED, KEY_UNDEFINED, KEY_UNDEFINED, KEY_UNDEFINED,
|
||||
KEY_UNDEFINED, KEY_UNDEFINED, KEY_UNDEFINED, KEY_UNDEFINED,
|
||||
KEY_UNDEFINED, 0 /* SDL_MODE */, 0 /* SDL_AUDIONEXT */, 0 /* SDL_AUDIOPREV */,
|
||||
0 /* SDL_AUDIOSTOP */, 0 /* SDL_AUDIOPLAY */, 0 /* SDL_AUDIOMUTE */, 0 /* SDL_MEDIASELECT */,
|
||||
0 /* SDL_WWW */, 0 /* SDL_MAIL */, 0 /* SDL_CALCULATOR */, 0 /* SDL_COMPUTER */,
|
||||
0 /* SDL_AC_SEARCH */, 0 /* SDL_AC_HOME */, 0 /* SDL_AC_BACK */, 0 /* SDL_AC_FORWARD */,
|
||||
0 /* SDL_AC_STOP */, 0 /* SDL_AC_REFRESH */, 0 /* SDL_AC_BOOKMARKS */, 0 /* SDL_BRIGHTNESSDOWN */,
|
||||
0 /* SDL_BRIGHTNESSUP */, 0 /* SDL_DISPLAYSWITCH */, 0 /* SDL_KBDILLUMTOGGLE */, 0 /* SDL_KBDILLUMDOWN */,
|
||||
0 /* SDL_KBDILLUMUP */, 0 /* SDL_EJECT */, 0 /* SDL_SLEEP */, 0 /* SDL_APP1 */,
|
||||
0 /* SDL_APP2 */, };
|
||||
@@ -54,7 +54,6 @@ struct sdl_private_data {
|
||||
|
||||
void sdl_event_init(void);
|
||||
void sdl_cursor_init(void);
|
||||
void sdl_shadow_init(void);
|
||||
int sdl_nearest_color(int r, int g, int b);
|
||||
boolean sdl_joy_open(int index);
|
||||
|
||||
|
||||
+26
-14
@@ -41,7 +41,6 @@ static void makeDIB(int width, int height, int depth);
|
||||
|
||||
struct sdl_private_data *sdl_videodev;
|
||||
static int joy_device_index = -1;
|
||||
static boolean integer_scaling = FALSE;
|
||||
|
||||
static SDL_Joystick *js;
|
||||
|
||||
@@ -86,8 +85,6 @@ int sdl_Initialize(const char *render_driver) {
|
||||
|
||||
sdl_setWindowSize(SYS35_DEFAULT_WIDTH, SYS35_DEFAULT_HEIGHT);
|
||||
|
||||
sdl_shadow_init();
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
// Prevent SDL from calling emscripten_exit_fullscreen on visibilitychange
|
||||
emscripten_set_visibilitychange_callback(NULL, 0, NULL);
|
||||
@@ -139,6 +136,10 @@ static void window_init(const char *render_driver) {
|
||||
// indirectly, which does not work with ASYNCIFY_IGNORE_INDIRECT=1. For
|
||||
// details, see https://github.com/emscripten-core/emscripten/issues/10746.
|
||||
SDL_SetHint(SDL_HINT_EMSCRIPTEN_ASYNCIFY, "0");
|
||||
|
||||
const char *title = NULL; // Don't let SDL change document.title.
|
||||
#else
|
||||
const char title[] = "XSystem35 Version " VERSION;
|
||||
#endif
|
||||
|
||||
#ifdef __ANDROID__
|
||||
@@ -148,13 +149,11 @@ static void window_init(const char *render_driver) {
|
||||
#else
|
||||
Uint32 flags = SDL_WINDOW_RESIZABLE;
|
||||
#endif
|
||||
sdl_window = SDL_CreateWindow("XSystem35 Version "VERSION,
|
||||
SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
|
||||
SYS35_DEFAULT_WIDTH, SYS35_DEFAULT_HEIGHT,
|
||||
flags);
|
||||
sdl_window = SDL_CreateWindow(
|
||||
title, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
|
||||
SYS35_DEFAULT_WIDTH, SYS35_DEFAULT_HEIGHT, flags);
|
||||
sdl_renderer = SDL_CreateRenderer(sdl_window, -1, 0);
|
||||
SDL_SetRenderDrawColor(sdl_renderer, 0, 0, 0, SDL_ALPHA_OPAQUE);
|
||||
SDL_RenderSetIntegerScale(sdl_renderer, integer_scaling);
|
||||
}
|
||||
|
||||
static void makeDIB(int width, int height, int depth) {
|
||||
@@ -162,12 +161,25 @@ static void makeDIB(int width, int height, int depth) {
|
||||
if (sdl_dib) {
|
||||
SDL_FreeSurface(sdl_dib);
|
||||
}
|
||||
|
||||
// Graphic routines in modules/ assume 4 bytes/pixel mode for 24-bit surfaces.
|
||||
if (depth == 24)
|
||||
depth = 32;
|
||||
|
||||
sdl_dib = SDL_CreateRGBSurface(0, width, height, depth, 0, 0, 0, 0);
|
||||
uint32_t format;
|
||||
switch (depth) {
|
||||
case 8:
|
||||
format = SDL_PIXELFORMAT_INDEX8;
|
||||
break;
|
||||
case 16:
|
||||
format = SDL_PIXELFORMAT_RGB565;
|
||||
break;
|
||||
case 24:
|
||||
format = SDL_PIXELFORMAT_RGB888;
|
||||
// Graphic routines in modules/ assume 4 bytes/pixel mode for 24-bit surfaces.
|
||||
depth = 32;
|
||||
break;
|
||||
default:
|
||||
SYSERROR("invalid pixel depth %d", depth);
|
||||
}
|
||||
|
||||
sdl_dib = SDL_CreateRGBSurfaceWithFormat(0, width, height, depth, format);
|
||||
|
||||
if (sdl_dib->format->BitsPerPixel == 8) {
|
||||
memset(sdl_dib->format->palette->colors, 0, sizeof(SDL_Color)*256);
|
||||
@@ -263,7 +275,7 @@ void sdl_setJoyDeviceIndex(int index) {
|
||||
}
|
||||
|
||||
void sdl_setIntegerScaling(boolean enable) {
|
||||
integer_scaling = enable;
|
||||
SDL_RenderSetIntegerScale(sdl_renderer, enable);
|
||||
}
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
|
||||
+12
-14
@@ -301,7 +301,7 @@ static void init_selwindow() {
|
||||
NOTICE("frameType is Default");
|
||||
break;
|
||||
}
|
||||
ags_setFont(FONT_GOTHIC, sel.MsgFontSize);
|
||||
ags_setFontWithWeight(FONT_GOTHIC, sel.MsgFontSize, nact->ags.font_weight);
|
||||
for (i = 0; i < regnum; i++) {
|
||||
DEBUG_MESSAGE("%d:%s\n", i +1, elm[i]);
|
||||
ags_drawString(r.x +2, r.y + i * (sel.MsgFontSize +2) +1, elm[i], sel.MsgFontColor);
|
||||
@@ -309,28 +309,26 @@ static void init_selwindow() {
|
||||
ags_updateArea(saveArea.x, saveArea.y, saveArea.w, saveArea.h);
|
||||
|
||||
/* マウスカーソルの自動移動 */
|
||||
int x = r.x + r.w * MOUSE_INIT_X_RATIO/100;
|
||||
if (default_element == 0) {
|
||||
MyPoint p;
|
||||
sys_getMouseInfo(&p, TRUE);
|
||||
if (p.y < r.y) {
|
||||
ags_setCursorLocation(r.x + r.w * MOUSE_INIT_X_RATIO/100,
|
||||
r.y + (sel.MsgFontSize +2) * MOUSE_INIT_Y_RATIO/100,
|
||||
TRUE);
|
||||
int y = r.y + (sel.MsgFontSize +2) * MOUSE_INIT_Y_RATIO/100;
|
||||
ags_setCursorLocation(x, y, true, true);
|
||||
} else if (p.y > (r.y + r.h)) {
|
||||
ags_setCursorLocation(r.x + r.w * MOUSE_INIT_X_RATIO/100,
|
||||
r.y + (sel.MsgFontSize +2) * regnum * MOUSE_INIT_Y_RATIO/100,
|
||||
TRUE);
|
||||
int y = r.y + (sel.MsgFontSize +2) * regnum * MOUSE_INIT_Y_RATIO/100;
|
||||
ags_setCursorLocation(x, y, true, true);
|
||||
} else {
|
||||
ags_setCursorLocation(r.x + r.w * MOUSE_INIT_X_RATIO/100,
|
||||
p.y * MOUSE_INIT_Y_RATIO/100,
|
||||
TRUE);
|
||||
int y = p.y * MOUSE_INIT_Y_RATIO/100;
|
||||
ags_setCursorLocation(x, y, true, true);
|
||||
}
|
||||
} else if (default_element < regnum) {
|
||||
ags_setCursorLocation(r.x + r.w * MOUSE_INIT_X_RATIO/100,
|
||||
r.y + (sel.MsgFontSize +2) * default_element * MOUSE_INIT_Y_RATIO/100, TRUE);
|
||||
int y = r.y + (sel.MsgFontSize +2) * default_element * MOUSE_INIT_Y_RATIO/100;
|
||||
ags_setCursorLocation(x, y, true, true);
|
||||
} else if (default_element < 1000) {
|
||||
ags_setCursorLocation(r.x + r.w * MOUSE_INIT_X_RATIO/100,
|
||||
r.y + (sel.MsgFontSize +2) * regnum * MOUSE_INIT_Y_RATIO/100, TRUE);
|
||||
int y = r.y + (sel.MsgFontSize +2) * regnum * MOUSE_INIT_Y_RATIO/100;
|
||||
ags_setCursorLocation(x, y, true, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -53,7 +53,7 @@ struct _selection {
|
||||
int FrameCgNoBot;
|
||||
int Framedot;
|
||||
|
||||
/* メッセージフォントの大きさ */
|
||||
/* メッセージフォントの大きさ */
|
||||
int MsgFontSize;
|
||||
|
||||
/* 各種色 */
|
||||
|
||||
@@ -42,7 +42,6 @@
|
||||
* static methods
|
||||
*/
|
||||
static vsp_header *extract_header(uint8_t *b);
|
||||
static void getpal(Palette256 *pal, uint8_t *b);
|
||||
static void extract(vsp_header *vsp, uint8_t *pic, uint8_t *b);
|
||||
|
||||
/*
|
||||
@@ -66,15 +65,16 @@ static vsp_header *extract_header(uint8_t *b) {
|
||||
|
||||
/*
|
||||
* Get palette from raw data
|
||||
* pal: palette to be stored
|
||||
* b : raw data (pointer to palette)
|
||||
*/
|
||||
static void getpal(Palette256 *pal, uint8_t *b) {
|
||||
static Color *getpal(uint8_t *b) {
|
||||
Color *pal = malloc(sizeof(Color) * 256);
|
||||
for (int i = 0; i < 16; i++) {
|
||||
pal->blue[i] = b[i * 3 + 0] * 17;
|
||||
pal->red[i] = b[i * 3 + 1] * 17;
|
||||
pal->green[i] = b[i * 3 + 2] * 17;
|
||||
pal[i].b = b[i * 3 + 0] * 17;
|
||||
pal[i].r = b[i * 3 + 1] * 17;
|
||||
pal[i].g = b[i * 3 + 2] * 17;
|
||||
}
|
||||
return pal;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -196,8 +196,7 @@ cgdata *vsp_extract(uint8_t *data) {
|
||||
cgdata *cg = calloc(1, sizeof(cgdata));
|
||||
vsp_header *vsp = extract_header(data);
|
||||
|
||||
cg->pal = malloc(sizeof(Palette256));
|
||||
getpal(cg->pal, data + vsp->vspPp);
|
||||
cg->pal = getpal(data + vsp->vspPp);
|
||||
|
||||
/* +10: margin for broken cg */
|
||||
cg->pic = malloc(sizeof(uint8_t) * ((vsp->vspXW * 8 + 10) * (vsp->vspYW + 10)));
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
*
|
||||
*/
|
||||
#include <windows.h>
|
||||
#include <shlobj.h>
|
||||
#undef min
|
||||
#undef max
|
||||
#include <SDL_syswm.h>
|
||||
@@ -25,8 +24,6 @@
|
||||
#include "sdl_private.h"
|
||||
#include "resources.h"
|
||||
|
||||
#define REGVAL_RECENT_FOLDER "RecentFolder"
|
||||
|
||||
static HWND get_hwnd(SDL_Window *window) {
|
||||
SDL_SysWMinfo info;
|
||||
SDL_VERSION(&info.version);
|
||||
@@ -34,49 +31,6 @@ static HWND get_hwnd(SDL_Window *window) {
|
||||
return info.info.win.window;
|
||||
}
|
||||
|
||||
static int CALLBACK select_game_callback(HWND hwnd, UINT uMsg, LPARAM lParam, LPARAM lpData) {
|
||||
if (uMsg == BFFM_INITIALIZED)
|
||||
SendMessage(hwnd, BFFM_SETSELECTION, (WPARAM)TRUE, lpData);
|
||||
return 0;
|
||||
}
|
||||
|
||||
boolean current_folder_has_ald(void) {
|
||||
WIN32_FIND_DATA find_data;
|
||||
HANDLE hFind = FindFirstFile("*.ALD", &find_data);
|
||||
if (hFind == INVALID_HANDLE_VALUE)
|
||||
return FALSE;
|
||||
FindClose(hFind);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
boolean select_game_folder(void) {
|
||||
char title[256];
|
||||
LoadString(GetModuleHandle(NULL), IDS_CHOOSE_GAME_FOLDER, title, sizeof(title));
|
||||
|
||||
char path[MAX_PATH] = "";
|
||||
DWORD value_size = sizeof(path);
|
||||
RegGetValue(HKEY_CURRENT_USER, XSYSTEM35_REGKEY, REGVAL_RECENT_FOLDER,
|
||||
RRF_RT_REG_SZ, NULL, path, &value_size);
|
||||
|
||||
BROWSEINFO bi = {
|
||||
.lpszTitle = title,
|
||||
.ulFlags = BIF_RETURNONLYFSDIRS,
|
||||
.lpfn = &select_game_callback,
|
||||
.lParam = (LPARAM)path,
|
||||
};
|
||||
LPITEMIDLIST pidl = SHBrowseForFolder(&bi);
|
||||
if (!pidl)
|
||||
return FALSE;
|
||||
SHGetPathFromIDList(pidl, path);
|
||||
CoTaskMemFree(pidl);
|
||||
if (!SetCurrentDirectory(path))
|
||||
return FALSE;
|
||||
|
||||
RegSetKeyValue(HKEY_CURRENT_USER, XSYSTEM35_REGKEY, REGVAL_RECENT_FOLDER,
|
||||
REG_SZ, path, strlen(path) + 1);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static INT_PTR CALLBACK text_dialog_proc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
static INPUTSTRING_PARAM *p;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user