Compare commits

..
1 Commits
Author SHA1 Message Date
kichikuou 64edcfda29 Support loading system3.5 v1 save files 2023-03-18 09:51:58 +09:00
77 changed files with 1558 additions and 1410 deletions
+1 -1
View File
@@ -15,7 +15,7 @@ jobs:
run: |
cd android
echo "${{ secrets.KEYSTORE_BASE64 }}" | base64 -d > keystore.jks
JAVA_HOME=$JAVA_HOME_17_X64 ANDROID_NDK_HOME=$ANDROID_SDK_ROOT/ndk-bundle ./gradlew assembleRelease
ANDROID_NDK_HOME=$ANDROID_SDK_ROOT/ndk-bundle ./gradlew assembleRelease
env:
KEY_ALIAS: ${{ secrets.KEY_ALIAS }}
KEY_PASSWORD: ${{ secrets.KEY_PASSWORD }}
+1 -1
View File
@@ -2,7 +2,7 @@ name: Emscripten Build
on: [push, pull_request]
env:
EM_VERSION: 3.1.34
EM_VERSION: 3.1.27
EM_CACHE_FOLDER: 'emsdk-cache'
jobs:
+3 -2
View File
@@ -8,7 +8,7 @@ jobs:
matrix:
include:
- { sys: MINGW32, installer: "xsystem35-32bit" }
- { sys: UCRT64, installer: "xsystem35-64bit" }
- { sys: MINGW64, installer: "xsystem35-64bit" }
defaults:
run:
shell: msys2 {0}
@@ -19,6 +19,7 @@ jobs:
uses: msys2/setup-msys2@v2
with:
msystem: ${{ matrix.sys }}
update: true
pacboy: >-
gcc:p
cmake:p
@@ -29,7 +30,7 @@ jobs:
libwebp:p
cjson:p
nsis:p
ntldd:p
ntldd-git:p
- name: Checkout
uses: actions/checkout@v3
+5 -1
View File
@@ -123,10 +123,14 @@ elseif (CMAKE_SYSTEM_NAME STREQUAL "Emscripten")
list(APPEND SRC_CDROM cdrom.emscripten.c)
list(APPEND SUMMARY_CDROM "Emscripten")
set(ENABLE_CDROM_EMSCRIPTEN 1)
elseif (CMAKE_SYSTEM_NAME STREQUAL "Android")
list(APPEND SRC_CDROM cdrom.android.c)
list(APPEND SUMMARY_CDROM "Android")
set(ENABLE_CDROM_ANDROID 1)
else()
list(APPEND SRC_CDROM cdrom.empty.c)
endif()
if (SDL2MIXER_FOUND)
if (SDL2MIXER_FOUND AND NOT ANDROID)
list(APPEND SRC_CDROM cdrom.mp3.c)
list(APPEND SUMMARY_CDROM "SDL_mixer (wav|mp3|ogg...)")
set(ENABLE_CDROM_MP3 1)
+51 -71
View File
@@ -3,22 +3,22 @@
This is a multi-platform port of `xsystem35`, a free implementation of
AliceSoft's System 3.x game engine.
## Compatibility
## Compatiblity
See the [game compatibility table](game_compatibility.md) for a list of games
that can be played with xsystem35-sdl2.
that can be played on xsystem35-sdl2.
## Unique Features
In addition to the original System 3.x functionalities, xsystem35-sdl2 offers
the following features:
In addition to the original System 3.x's functionalities, xsystem35-sdl2 has
the following features.
### Playing Audio Files as Virtual CD Music
### Playing audio files as fake CD music
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:
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:
```
# The first line is not used
@@ -27,109 +27,89 @@ BGM/track03.mp3
...
```
The first line is not used because the first track on a game CD is typically a
data track.
The first line is not used, because track 1 of game CD is usually a data track.
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:
### Unicode translation support
```
SDL_SOUNDFONTS=/usr/share/soundfonts/GeneralUser.sf2 xsystem35
```
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.
### 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.
See [xsys35c](https://github.com/kichikuou/xsys35c)'s document for how to
build a game with Unicode mode.
### Debugging
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:
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:
- Through [Visual Studio Code](https://code.visualstudio.com/) (recommended):
The [vscode-system3x](https://github.com/kichikuou/vscode-system3x) extension
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.
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.
## Installation
## Installing
Prebuilt packages for Windows and Android can be downloaded from the
[Releases](https://github.com/kichikuou/xsystem35-sdl2/releases) page. For
other platforms, refer to the [Building](#building) section.
other platforms, see the [Building](#building) section.
## Running
### Windows
Execute `xsystem35`, and a dialog will appear for you to select a folder.
Choose the game folder (where the ALD files are located).
Execute `xsytem35`, and it will show a dialog to select a folder. Select the
game folder (where the ALD files are located).
### Android
See [android/README.md](android/README.md#use).
See [android/README.md](https://github.com/kichikuou/xsystem35-sdl2/blob/master/android/README.md#use).
### Other Platforms
Run xsystem35 from within the game directory.
```bash
$ cd /path/to/game_directory
$ xsystem35
```
cd /path/to/game_directory
xsystem35
## Building
### Linux (Debian / Ubuntu)
```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
```
$ 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/) is required.
[Homebrew](https://brew.sh/index_ja) is needed.
```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
```
$ 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 required.
[MSYS2](https://www.msys2.org) is needed.
```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
```
$ 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
### Emscripten
```bash
$ mkdir -p out/wasm
$ cd out/wasm
$ emcmake cmake -DCMAKE_BUILD_TYPE=MinSizeRel ../../
$ make
```
$ mkdir -p out/wasm
$ cd out/wasm
$ emcmake cmake -DCMAKE_BUILD_TYPE=MinSizeRel ../../
$ make
To use the generated binary, check out
To use the generated binary, checkout
[Kichikuou on Web](https://github.com/kichikuou/web) and copy `out/xsystem35.*`
into its `docs` directory.
+20 -34
View File
@@ -1,8 +1,7 @@
# xsystem35 for Android
## Download
You can download prebuilt APKs
[here](https://github.com/kichikuou/xsystem35-sdl2/releases).
Prebuilt APKs are [here](https://github.com/kichikuou/xsystem35-sdl2/releases).
## Build
Prerequisites:
@@ -12,10 +11,10 @@ Prerequisites:
### Using Android Studio
Open this directory as an Android Studio project.
### Command Line Build
Set environment variables and run the `gradlew` script in this directory.
### Command line build
Configure environment variables and run the `gradlew` script in this folder.
Example build instructions (for Debian bookworm):
Example build instructions (for Debian bullseye):
```sh
# Install necessary packages
sudo apt install git wget unzip default-jdk-headless ninja-build
@@ -23,51 +22,38 @@ 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-10406996_latest.zip
unzip commandlinetools-linux-10406996_latest.zip -d $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
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
# Clone and build xsystem35
# Check out 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
```
## Usage
## Use
### Basic Usage
1. Create a ZIP file containing all the game files and BGM files (see
[below](#preparing-a-zip) for details), and transfer it to your device.
2. Open the app. A list of installed games 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.
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.
### Preparing a ZIP
- Include all files from the `GAMEDATA` folder (such as `.ALD` files and
others). `.EXE` and `.DLL` files are not necessary, but you can include them
if you want.
- Music files (`.mp3`, `.ogg`, or `.wav`) whose filenames end with a number
will be recognized as BGM files. For example:
- Include all files in the `GAMEDATA` folder (`.ALD` files and others). `.EXE` and `.DLL` are not really needed, but you can include them as well.
- Music files (`.mp3`, `.ogg` or `.wav`) whose file names end with a number are recognized as BGM files. For example:
- `Track2.mp3`
- `15.ogg`
- `rance4_03.wav` (Note: The filename shouldn't be `rance403.wav`, as it
would be treated as the 403rd track.)
- `rance4_03.wav` (This shouldn't be `rance403.wav`, because it would be treated as the 403rd track)
Note: This ZIP format is also compatible with
[Kichikuou on Web](http://kichikuou.github.io/web/).
Note: This form of ZIP can be used in [Kichikuou on Web](http://kichikuou.github.io/web/) as well.
### Miscellaneous
- You can export or import save files via the game list's option menu.
- To uninstall a game, long-tap its title in the game list.
- You can export / import saved files using the option menu of the game list.
- To uninstall a game, long-tap the title in the game list.
## Known Issues
- Android versions older than 7.0 cannot handle 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.
- 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.
+11 -14
View File
@@ -9,18 +9,18 @@ else {
apply plugin: 'kotlin-android'
android {
if (buildAsApplication) {
namespace "io.github.kichikuou.xsystem35"
}
compileSdkVersion 34
compileSdkVersion 31
defaultConfig {
if (buildAsApplication) {
applicationId "io.github.kichikuou.xsystem35"
}
minSdkVersion 19
targetSdkVersion 34
versionCode 16
versionName "2.10.0" + gitRevision()
targetSdkVersion 31
versionCode 13
versionName "2.8.0" + gitRevision()
externalNativeBuild {
cmake {
arguments "-DANDROID_APP_PLATFORM=android-19", "-DANDROID_STL=c++_static"
arguments "-DANDROID_APP_PLATFORM=android-16", "-DANDROID_STL=c++_static"
// abiFilters 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64'
abiFilters 'armeabi-v7a', 'arm64-v8a'
}
@@ -38,9 +38,7 @@ android {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
if (rootProject.file('keystore.jks').exists()) {
signingConfig signingConfigs.release
}
signingConfig signingConfigs.release
}
}
applicationVariants.all { variant ->
@@ -64,10 +62,10 @@ android {
}
}
lint {
lintOptions {
abortOnError false
}
if (buildAsLibrary) {
libraryVariants.all { variant ->
variant.outputs.each { output ->
@@ -84,7 +82,6 @@ android {
dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4'
}
static String gitRevision() {
+2 -2
View File
@@ -6,8 +6,8 @@ set(PROJECT_ROOT_DIR ../../..)
include(FetchContent)
FetchContent_Declare(
SDL
URL https://github.com/libsdl-org/SDL/releases/download/release-2.28.5/SDL2-2.28.5.tar.gz
URL_HASH SHA1=50af6b564890d702e57e2a72d6429b43778ed29a
URL https://github.com/libsdl-org/SDL/releases/download/release-2.26.1/SDL2-2.26.1.tar.gz
URL_HASH SHA1=08a8cec21ffcebf44e4633a786d594a7811100d2
)
FetchContent_Declare(
SDL_ttf
+1
View File
@@ -4,6 +4,7 @@
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="io.github.kichikuou.xsystem35"
android:installLocation="auto">
<!-- OpenGL ES 2.0 -->
@@ -37,20 +37,24 @@ class GameActivity : SDLActivity() {
}
private lateinit var gameRoot: File
private lateinit var cdda: CddaPlayer
private val midi = MidiPlayer()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
gameRoot = File(intent.getStringExtra(EXTRA_GAME_ROOT)!!)
cdda = CddaPlayer(File(gameRoot, Launcher.PLAYLIST_FILE))
}
override fun onStop() {
super.onStop()
cdda.onActivityStop()
midi.onActivityStop()
}
override fun onResume() {
super.onResume()
cdda.onActivityResume()
midi.onActivityResume()
}
@@ -59,9 +63,7 @@ class GameActivity : SDLActivity() {
}
override fun getArguments(): Array<String> {
return arrayOf(
"-gamedir", intent.getStringExtra(EXTRA_GAME_ROOT)!!,
"-devcd", Launcher.PLAYLIST_FILE)
return arrayOf("-gamedir", intent.getStringExtra(EXTRA_GAME_ROOT)!!)
}
override fun setTitle(title: CharSequence?) {
@@ -118,6 +120,9 @@ class GameActivity : SDLActivity() {
}
// The functions below are called in the SDL thread by JNI.
@Suppress("unused") fun cddaStart(track: Int, loop: Boolean) = cdda.start(track, loop)
@Suppress("unused") fun cddaStop() = cdda.stop()
@Suppress("unused") fun cddaCurrentPosition() = cdda.currentPosition()
@Suppress("unused") fun midiStart(path: String, loop: Boolean) = midi.start(path, loop)
@Suppress("unused") fun midiStop() = midi.stop()
@Suppress("unused") fun midiCurrentPosition() = midi.currentPosition()
@@ -151,6 +156,69 @@ class GameActivity : SDLActivity() {
}
}
private class CddaPlayer(private val playlistPath: File) {
private val playlist =
try {
playlistPath.readLines()
} catch (e: IOException) {
Log.e("loadPlaylist", "Cannot load $playlistPath", e)
emptyList()
}
private var currentTrack = 0
private val player = MediaPlayer()
private var playerPaused = false
fun start(track: Int, loop: Boolean) {
val f = playlist.elementAtOrNull(track - 1)
if (f.isNullOrEmpty()) {
Log.w("cddaStart", "No playlist entry for track $track")
return
}
Log.v("cddaStart", "$f Loop:$loop")
try {
player.apply {
reset()
setDataSource(File(playlistPath.parent, f).path)
isLooping = loop
prepare()
start()
}
currentTrack = track
} catch (e: IOException) {
Log.e("cddaStart", "Cannot play $f", e)
player.reset()
}
}
fun stop() {
if (currentTrack > 0 && player.isPlaying) {
player.stop()
currentTrack = 0
}
}
fun currentPosition(): Int {
if (currentTrack == 0)
return 0
val frames = player.currentPosition * 75 / 1000
return currentTrack or (frames shl 8)
}
fun onActivityStop() {
if (currentTrack > 0 && player.isPlaying) {
player.pause()
playerPaused = true
}
}
fun onActivityResume() {
if (playerPaused) {
player.start()
playerPaused = false
}
}
}
private class MidiPlayer {
private val player = MediaPlayer()
private var playing = false
@@ -17,13 +17,11 @@
*/
package io.github.kichikuou.xsystem35
import android.annotation.SuppressLint
import android.os.Build
import android.os.Handler
import android.os.Message
import android.util.Log
import kotlinx.coroutines.DelicateCoroutinesApi
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.io.*
import java.lang.StringBuilder
import java.nio.charset.Charset
@@ -42,6 +40,9 @@ interface LauncherObserver {
}
private const val SAVE_DIR = "save"
private const val PROGRESS = 0
private const val SUCCESS = 1
private const val FAILURE = 2
class Launcher private constructor(private val rootDir: File) {
companion object {
@@ -73,28 +74,31 @@ class Launcher private constructor(private val rootDir: File) {
updateGameList()
}
@OptIn(DelicateCoroutinesApi::class)
fun install(input: InputStream, archiveName: String?) {
val dir = createDirForGame()
isInstalling = true
GlobalScope.launch(Dispatchers.Main) {
try {
withContext(Dispatchers.IO) {
extractFiles(input, dir) { msg ->
GlobalScope.launch(Dispatchers.Main) {
observer?.onInstallProgress(msg)
}
@SuppressLint("HandlerLeak")
val handler = object : Handler() {
override fun handleMessage(msg: Message) {
when (msg.what) {
PROGRESS -> {
observer?.onInstallProgress(msg.obj as String)
}
SUCCESS -> {
isInstalling = false
observer?.onInstallSuccess(msg.obj as File, archiveName)
}
FAILURE -> {
isInstalling = false
observer?.onInstallFailure(msg.obj as Int)
}
}
observer?.onInstallSuccess(dir, archiveName)
} catch (e: InstallFailureException) {
observer?.onInstallFailure(e.msgId)
} catch (e: Exception) {
Log.e("launcher", "Failed to extract ZIP", e)
observer?.onInstallFailure(R.string.zip_extraction_error)
}
isInstalling = false
}
val t = Thread {
extractFiles(input, dir, handler)
}
t.start()
isInstalling = true
}
fun uninstall(id: Int) {
@@ -179,26 +183,32 @@ class Launcher private constructor(private val rootDir: File) {
}
}
private fun extractFiles(input: InputStream, outDir: File, progressCallback: (String) -> Unit) {
val configWriter = GameConfigWriter()
val hadDecodeError = forEachZipEntry(input) { zipEntry, zip ->
Log.i("extractFiles", zipEntry.name)
val path = File(outDir, zipEntry.name)
if (zipEntry.isDirectory)
return@forEachZipEntry
path.parentFile?.mkdirs()
progressCallback(zipEntry.name)
FileOutputStream(path).buffered().use {
zip.copyTo(it)
private fun extractFiles(input: InputStream, outDir: File, handler: Handler) {
try {
val configWriter = GameConfigWriter()
val hadDecodeError = forEachZipEntry(input) { zipEntry, zip ->
Log.i("extractFiles", zipEntry.name)
val path = File(outDir, zipEntry.name)
if (zipEntry.isDirectory)
return@forEachZipEntry
path.parentFile?.mkdirs()
handler.sendMessage(handler.obtainMessage(PROGRESS, zipEntry.name))
FileOutputStream(path).buffered().use {
zip.copyTo(it)
}
configWriter.maybeAdd(zipEntry.name)
}
configWriter.maybeAdd(zipEntry.name)
if (!configWriter.readyToWrite()) {
val msgId = if (hadDecodeError) R.string.unsupported_zip else R.string.cannot_find_ald
handler.sendMessage(handler.obtainMessage(FAILURE, msgId))
return
}
configWriter.write(outDir)
handler.sendMessage(handler.obtainMessage(SUCCESS, outDir))
} catch (e: IOException) {
Log.e("launcher", "Failed to extract ZIP", e)
handler.sendMessage(handler.obtainMessage(FAILURE, R.string.zip_extraction_error))
}
if (!configWriter.readyToWrite()) {
if (hadDecodeError)
throw InstallFailureException(R.string.unsupported_zip)
throw InstallFailureException(R.string.cannot_find_ald)
}
configWriter.write(outDir)
}
// Xsystem35-sdl2 <=2.2.0 had a bug where playlist had an extra empty line at
@@ -209,14 +219,12 @@ class Launcher private constructor(private val rootDir: File) {
if (!oldPlaylist.exists())
return
var tracks = oldPlaylist.readLines()
if (tracks.isNotEmpty())
if (!tracks.isEmpty())
tracks = tracks.subList(1, tracks.size)
File(dir, PLAYLIST_FILE).writeText(tracks.joinToString("\n"))
oldPlaylist.delete()
}
class InstallFailureException(val msgId: Int) : Exception()
// A helper class which generates xsystem35.gr and playlist.txt in the game root directory.
private class GameConfigWriter {
private val grb = StringBuilder()
@@ -27,7 +27,6 @@ import android.view.Menu
import android.view.MenuItem
import android.widget.ArrayAdapter
import android.widget.ListView
import android.widget.TextView
import android.widget.Toast
import java.io.*
@@ -35,11 +34,10 @@ private const val CONTENT_TYPE_ZIP = "application/zip"
private const val INSTALL_REQUEST = 1
private const val SAVEDATA_EXPORT_REQUEST = 2
private const val SAVEDATA_IMPORT_REQUEST = 3
private const val STATE_PROGRESS_TEXT = "progressText"
class LauncherActivity : Activity(), LauncherObserver {
private lateinit var launcher: Launcher
private var progressDialog: Dialog? = null
private var progressDialog: ProgressDialogFragment? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@@ -48,7 +46,7 @@ class LauncherActivity : Activity(), LauncherObserver {
launcher = Launcher.getInstance(filesDir)
launcher.observer = this
if (launcher.isInstalling) {
showProgressDialog(savedInstanceState)
showProgressDialog()
}
onGameListChange()
@@ -63,17 +61,9 @@ class LauncherActivity : Activity(), LauncherObserver {
override fun onDestroy() {
launcher.observer = null
dismissProgressDialog()
super.onDestroy()
}
override fun onSaveInstanceState(outState: Bundle) {
progressDialog?.let {
outState.putCharSequence(STATE_PROGRESS_TEXT, it.findViewById<TextView>(R.id.text).text)
}
super.onSaveInstanceState(outState)
}
private fun onListItemClick(position: Int) {
if (position < launcher.games.size) {
startGame(launcher.games[position].path, null)
@@ -163,7 +153,7 @@ class LauncherActivity : Activity(), LauncherObserver {
}
override fun onInstallProgress(path: String) {
progressDialog?.findViewById<TextView>(R.id.text)?.text = getString(R.string.install_progress, path)
progressDialog?.setProgress(getString(R.string.install_progress, path))
}
override fun onInstallSuccess(path: File, archiveName: String?) {
@@ -188,17 +178,9 @@ class LauncherActivity : Activity(), LauncherObserver {
launcher.uninstall(id)
}
private fun showProgressDialog(savedInstanceState: Bundle? = null) {
progressDialog = Dialog(this)
progressDialog!!.apply {
setTitle(R.string.install_dialog_title)
setCancelable(false)
setContentView(R.layout.progress_dialog)
savedInstanceState?.let {
findViewById<TextView>(R.id.text)?.text = it.getCharSequence(STATE_PROGRESS_TEXT)
}
show()
}
private fun showProgressDialog() {
progressDialog = ProgressDialogFragment()
progressDialog!!.show(fragmentManager, "progress_dialog")
}
private fun dismissProgressDialog() {
@@ -227,3 +209,18 @@ class LauncherActivity : Activity(), LauncherObserver {
return null
}
}
@Suppress("DEPRECATION") // for ProgressDialog
class ProgressDialogFragment : DialogFragment() {
private lateinit var dialog: ProgressDialog
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
dialog = ProgressDialog(activity)
return dialog.apply {
setTitle(R.string.install_dialog_title)
setCancelable(true)
}
}
fun setProgress(msg: String) {
dialog.setMessage(msg)
}
}
@@ -186,7 +186,7 @@ class HIDDeviceBLESteamController extends BluetoothGattCallback implements HIDDe
// Because on Chromebooks we show up as a dual-mode device, it will attempt to connect TRANSPORT_AUTO, which will use TRANSPORT_BREDR instead
// of TRANSPORT_LE. Let's force ourselves to connect low energy.
private BluetoothGatt connectGatt(boolean managed) {
if (Build.VERSION.SDK_INT >= 23 /* Android 6.0 (M) */) {
if (Build.VERSION.SDK_INT >= 23) {
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,8 +251,6 @@ public class HIDDeviceManager {
0x20d6, // PowerA
0x24c6, // PowerA
0x2c22, // Qanba
0x2dc8, // 8BitDo
0x9886, // ASTRO Gaming
};
if (usbInterface.getInterfaceClass() == UsbConstants.USB_CLASS_VENDOR_SPEC &&
@@ -273,17 +271,14 @@ 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
};
@@ -358,13 +353,13 @@ public class HIDDeviceManager {
private void initializeBluetooth() {
Log.d(TAG, "Initializing Bluetooth");
if (Build.VERSION.SDK_INT <= 30 /* Android 11.0 (R) */ &&
if (Build.VERSION.SDK_INT <= 30 &&
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 /* Android 4.3 (JELLY_BEAN_MR2) */)) {
if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE) || (Build.VERSION.SDK_INT < 18)) {
Log.d(TAG, "Couldn't initialize Bluetooth, this version of Android does not support Bluetooth LE");
return;
}
@@ -529,7 +524,7 @@ public class HIDDeviceManager {
for (HIDDevice device : mDevicesById.values()) {
device.setFrozen(frozen);
}
}
}
}
//////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -578,7 +573,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 /* Android 12.0 (S) */) {
if (Build.VERSION.SDK_INT >= 31) {
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 /* Android 5.0 (LOLLIPOP) */) {
if (Build.VERSION.SDK_INT >= 21) {
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 /* Android 5.0 (LOLLIPOP) */) {
if (Build.VERSION.SDK_INT >= 21) {
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 /* Android 5.0 (LOLLIPOP) */) {
if (Build.VERSION.SDK_INT >= 21) {
result = mDevice.getProductName();
}
if (result == null) {
@@ -29,7 +29,6 @@ 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 = 28;
private static final int SDL_MICRO_VERSION = 5;
private static final int SDL_MINOR_VERSION = 26;
private static final int SDL_MICRO_VERSION = 1;
/*
// 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 >= 23) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
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 >= 21) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
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 >= 18) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
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 /* Android 7.0 (N) */);
public static final boolean mHasMultiWindow = (Build.VERSION.SDK_INT >= 24);
// 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 /* Android 8.0 (O) */) {
if (Build.VERSION.SDK_INT >= 26) {
mMotionListener = new SDLGenericMotionListener_API26();
} else if (Build.VERSION.SDK_INT >= 24 /* Android 7.0 (N) */) {
} else if (Build.VERSION.SDK_INT >= 24) {
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(this);
mSurface = createSDLSurface(getApplication());
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 /* Android 7.0 (N) */) {
if (Build.VERSION.SDK_INT < 24) {
mCurrentLocale = getContext().getResources().getConfiguration().locale;
} else {
mCurrentLocale = getContext().getResources().getConfiguration().getLocales().get(0);
@@ -588,8 +588,6 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
mHIDDeviceManager = null;
}
SDLAudioManager.release(this);
if (SDLActivity.mBrokenLibraries) {
super.onDestroy();
return;
@@ -768,7 +766,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
}
break;
case COMMAND_CHANGE_WINDOW_STYLE:
if (Build.VERSION.SDK_INT >= 19 /* Android 4.4 (KITKAT) */) {
if (Build.VERSION.SDK_INT >= 19) {
if (context instanceof Activity) {
Window window = ((Activity) context).getWindow();
if (window != null) {
@@ -843,7 +841,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
msg.obj = data;
boolean result = commandHandler.sendMessage(msg);
if (Build.VERSION.SDK_INT >= 19 /* Android 4.4 (KITKAT) */) {
if (Build.VERSION.SDK_INT >= 19) {
if (command == COMMAND_CHANGE_WINDOW_STYLE) {
// Ensure we don't return until the resize has actually happened,
// or 500ms have passed.
@@ -971,18 +969,15 @@ 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("LandscapeLeft")) {
orientation_landscape = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
} else if (hint.contains("LandscapeRight")) {
orientation_landscape = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
} else if (hint.contains("LandscapeLeft")) {
orientation_landscape = ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE;
}
/* exact match to 'Portrait' to distinguish with PortraitUpsideDown */
boolean contains_Portrait = hint.contains("Portrait ") || hint.endsWith("Portrait");
if (contains_Portrait && hint.contains("PortraitUpsideDown")) {
if (hint.contains("Portrait") && hint.contains("PortraitUpsideDown")) {
orientation_portrait = ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT;
} else if (contains_Portrait) {
} else if (hint.contains("Portrait")) {
orientation_portrait = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
} else if (hint.contains("PortraitUpsideDown")) {
orientation_portrait = ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT;
@@ -1095,7 +1090,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 /* Android 8.1 (O_MR1) */ && isDeXMode()) {
if ((Build.VERSION.SDK_INT < 27) && isDeXMode()) {
return false;
}
@@ -1185,7 +1180,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 /* Android 7.0 (N) */) {
if (Build.VERSION.SDK_INT < 24) {
return false;
}
try {
@@ -1345,6 +1340,23 @@ 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
@@ -1359,21 +1371,6 @@ 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;
}
@@ -1620,7 +1617,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 /* Android 4.4 (KITKAT) */) {
if (Build.VERSION.SDK_INT >= 19) {
int flags = View.SYSTEM_UI_FLAG_FULLSCREEN |
View.SYSTEM_UI_FLAG_HIDE_NAVIGATION |
View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY |
@@ -1673,7 +1670,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 /* Android 7.0 (N) */) {
if (Build.VERSION.SDK_INT >= 24) {
try {
mCursors.put(mLastCursorID, PointerIcon.create(bitmap, hotSpotX, hotSpotY));
} catch (Exception e) {
@@ -1689,7 +1686,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 /* Android 7.0 (N) */) {
if (Build.VERSION.SDK_INT >= 24) {
try {
mCursors.remove(cursorID);
} catch (Exception e) {
@@ -1703,7 +1700,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
*/
public static boolean setCustomCursor(int cursorID) {
if (Build.VERSION.SDK_INT >= 24 /* Android 7.0 (N) */) {
if (Build.VERSION.SDK_INT >= 24) {
try {
mSurface.setPointerIcon(mCursors.get(cursorID));
} catch (Exception e) {
@@ -1758,7 +1755,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
cursor_type = 1002; //PointerIcon.TYPE_HAND;
break;
}
if (Build.VERSION.SDK_INT >= 24 /* Android 7.0 (N) */) {
if (Build.VERSION.SDK_INT >= 24) {
try {
mSurface.setPointerIcon(PointerIcon.getSystemIcon(SDL.getContext(), cursor_type));
} catch (Exception e) {
@@ -1772,7 +1769,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 /* Android 6.0 (M) */) {
if (Build.VERSION.SDK_INT < 23) {
nativePermissionResult(requestCode, true);
return;
}
@@ -1801,7 +1798,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 /* Android 5.0 (LOLLIPOP) */) {
if (Build.VERSION.SDK_INT >= 21) {
flags |= Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
} else {
flags |= Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET;
@@ -2005,18 +2002,6 @@ 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,8 +1,5 @@
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;
@@ -11,67 +8,34 @@ import android.media.MediaRecorder;
import android.os.Build;
import android.util.Log;
import java.util.Arrays;
public class SDLAudioManager {
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, int deviceId) {
protected static int[] open(boolean isCapture, int sampleRate, int audioFormat, int desiredChannels, int desiredFrames) {
int channelConfig;
int sampleSize;
int frameSize;
@@ -79,14 +43,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 /* Android 5.0 (LOLLIPOP) */) {
if (Build.VERSION.SDK_INT < 21) {
if (desiredChannels > 2) {
desiredChannels = 2;
}
}
/* AudioTrack has sample rate limitation of 48000 (fixed in 5.0.2) */
if (Build.VERSION.SDK_INT < 22 /* Android 5.1 (LOLLIPOP_MR1) */) {
if (Build.VERSION.SDK_INT < 22) {
if (sampleRate < 8000) {
sampleRate = 8000;
} else if (sampleRate > 48000) {
@@ -95,7 +59,7 @@ public class SDLAudioManager {
}
if (audioFormat == AudioFormat.ENCODING_PCM_FLOAT) {
int minSDKVersion = (isCapture ? 23 /* Android 6.0 (M) */ : 21 /* Android 5.0 (LOLLIPOP) */);
int minSDKVersion = (isCapture ? 23 : 21);
if (Build.VERSION.SDK_INT < minSDKVersion) {
audioFormat = AudioFormat.ENCODING_PCM_16BIT;
}
@@ -156,7 +120,7 @@ public class SDLAudioManager {
channelConfig = AudioFormat.CHANNEL_OUT_5POINT1 | AudioFormat.CHANNEL_OUT_BACK_CENTER;
break;
case 8:
if (Build.VERSION.SDK_INT >= 23 /* Android 6.0 (M) */) {
if (Build.VERSION.SDK_INT >= 23) {
channelConfig = AudioFormat.CHANNEL_OUT_7POINT1_SURROUND;
} else {
Log.v(TAG, "Requested " + desiredChannels + " channels, getting 5.1 surround");
@@ -237,10 +201,6 @@ public class SDLAudioManager {
return null;
}
if (Build.VERSION.SDK_INT >= 24 /* Android 7.0 (N) */ && deviceId != 0) {
mAudioRecord.setPreferredDevice(getOutputAudioDeviceInfo(deviceId));
}
mAudioRecord.startRecording();
}
@@ -264,10 +224,6 @@ public class SDLAudioManager {
return null;
}
if (Build.VERSION.SDK_INT >= 24 /* Android 7.0 (N) */ && deviceId != 0) {
mAudioTrack.setPreferredDevice(getInputAudioDeviceInfo(deviceId));
}
mAudioTrack.play();
}
@@ -282,73 +238,11 @@ 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[] 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);
public static int[] audioOpen(int sampleRate, int audioFormat, int desiredChannels, int desiredFrames) {
return open(false, sampleRate, audioFormat, desiredChannels, desiredFrames);
}
/**
@@ -360,11 +254,6 @@ 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) {
@@ -437,22 +326,18 @@ public class SDLAudioManager {
/**
* This method is called by SDL using JNI.
*/
public static int[] captureOpen(int sampleRate, int audioFormat, int desiredChannels, int desiredFrames, int deviceId) {
return open(true, sampleRate, audioFormat, desiredChannels, desiredFrames, deviceId);
public static int[] captureOpen(int sampleRate, int audioFormat, int desiredChannels, int desiredFrames) {
return open(true, sampleRate, audioFormat, desiredChannels, desiredFrames);
}
/** This method is called by SDL using JNI. */
public static int captureReadFloatBuffer(float[] buffer, boolean 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);
}
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 /* Android 6.0 (M) */) {
if (Build.VERSION.SDK_INT < 23) {
return mAudioRecord.read(buffer, 0, buffer.length);
} else {
return mAudioRecord.read(buffer, 0, buffer.length, blocking ? AudioRecord.READ_BLOCKING : AudioRecord.READ_NON_BLOCKING);
@@ -461,7 +346,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 /* Android 6.0 (M) */) {
if (Build.VERSION.SDK_INT < 23) {
return mAudioRecord.read(buffer, 0, buffer.length);
} else {
return mAudioRecord.read(buffer, 0, buffer.length, blocking ? AudioRecord.READ_BLOCKING : AudioRecord.READ_NON_BLOCKING);
@@ -506,9 +391,4 @@ 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 axis_mask, int nhats, int nballs);
int naxes, 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 /* Android 4.4 (KITKAT) */) {
if (Build.VERSION.SDK_INT >= 19) {
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 /* Android 8.0 (O) */) {
if (Build.VERSION.SDK_INT >= 26) {
mHapticHandler = new SDLHapticHandler_API26();
} else {
mHapticHandler = new SDLHapticHandler();
@@ -168,32 +168,6 @@ 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;
}
}
@@ -236,7 +210,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(), getAxisMask(joystick.axes), joystick.hats.size()/2, 0);
getButtonMask(joystickDevice), joystick.axes.size(), joystick.hats.size()/2, 0);
}
}
}
@@ -317,9 +291,6 @@ 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;
}
@@ -337,43 +308,6 @@ 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;
@@ -809,7 +743,7 @@ class SDLGenericMotionListener_API26 extends SDLGenericMotionListener_API24 {
@Override
public boolean supportsRelativeMouse() {
return (!SDLActivity.isDeXMode() || Build.VERSION.SDK_INT >= 27 /* Android 8.1 (O_MR1) */);
return (!SDLActivity.isDeXMode() || (Build.VERSION.SDK_INT >= 27));
}
@Override
@@ -819,7 +753,7 @@ class SDLGenericMotionListener_API26 extends SDLGenericMotionListener_API24 {
@Override
public boolean setRelativeMouseEnabled(boolean enabled) {
if (!SDLActivity.isDeXMode() || Build.VERSION.SDK_INT >= 27 /* Android 8.1 (O_MR1) */) {
if (!SDLActivity.isDeXMode() || (Build.VERSION.SDK_INT >= 27)) {
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 /* Android 4.2 (JELLY_BEAN_MR1) */) {
if (Build.VERSION.SDK_INT >= 17) {
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 /* Android 7.0 (N) */) {
if (Build.VERSION.SDK_INT >= 24) {
if (SDLActivity.mSingleton.isInMultiWindowMode()) {
Log.v("SDL", "Don't skip in Multi-Window");
skip = false;
@@ -1,19 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:padding="16dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ProgressBar
android:layout_marginEnd="8dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:id="@+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:textSize="16sp"/>
</LinearLayout>
+2 -2
View File
@@ -1,13 +1,13 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
ext.kotlin_version = '1.7.21'
ext.kotlin_version = '1.6.20'
repositories {
mavenCentral()
google()
}
dependencies {
classpath 'com.android.tools.build:gradle:8.1.1'
classpath 'com.android.tools.build:gradle:7.3.1'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
// NOTE: Do not place your application dependencies here; they belong
+1 -1
View File
@@ -1,6 +1,6 @@
#Thu Nov 11 18:20:34 PST 2021
distributionBase=GRADLE_USER_HOME
distributionUrl=https\://services.gradle.org/distributions/gradle-8.1.1-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-bin.zip
distributionPath=wrapper/dists
zipStorePath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
+2 -2
View File
@@ -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"|grep -E -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|grep -E -c "^-"` ### Determine if an option
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -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"`
+1 -1
View File
@@ -1,5 +1,5 @@
#cmakedefine PACKAGE "@PACKAGE@"
#define VERSION "2.10.0"
#define VERSION "2.8.0"
#cmakedefine CMAKE_SYSTEM_NAME "@CMAKE_SYSTEM_NAME@"
+3 -3
View File
@@ -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 |
| 人間狩り | Supported | From ALICEの館4・5・6 / アリスCD |
| 人間狩り | Unsupported | 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 | Supported | From アリスCD |
| 高速ひよこ2 | Unsupported | From アリスCD |
| おせろっと | Supported | From アリスCD |
| マスカレイド | Supported | From アリスCD |
| キャロル ~聖なる鐘が響く夜~ | Supported | From アリスCD, Online match is not supported |
| できるかなー? | Supported | From アリスCD |
| Child Assassin | Supported | From アリスCD |
| Klavier | Supported | From アリスCD |
| 弱肉狂食 | Supported | From アリスCD |
| 弱肉狂食 | Unsupported | From アリスCD |
| 眼鏡大戦2 | Supported | From アリスCD |
| 妄想くん | Supported | From アリスCD |
+6 -5
View File
@@ -7,6 +7,7 @@
#include "menu.h"
#include "input.h"
#include "nact.h"
#include "key.h"
#include "night.h"
#include "sprite.h"
@@ -32,7 +33,7 @@ static void cb_waitkey_simple(agsevent_t *e) {
switch (e->type) {
case AGSEVENT_BUTTON_RELEASE:
case AGSEVENT_KEY_RELEASE:
night.waitkey = e->code;
night.waitkey = e->d3;
break;
}
}
@@ -58,15 +59,15 @@ void ntev_callback(agsevent_t *e) {
return;
}
if (e->type == AGSEVENT_KEY_PRESS && e->code == KEY_CTRL) {
if (e->type == AGSEVENT_KEY_PRESS && e->d3 == KEY_CTRL) {
night.waitskiplv = 2;
night.waitkey = e->code;
night.waitkey = e->d3;
return;
}
if (e->type == AGSEVENT_KEY_RELEASE && e->code == KEY_CTRL) {
if (e->type == AGSEVENT_KEY_RELEASE && e->d3 == KEY_CTRL) {
night.waitskiplv = 0;
night.waitkey = e->code;
night.waitkey = e->d3;
return;
}
+9 -3
View File
@@ -392,11 +392,13 @@ static void is_in_icon() {
static void cb_keyrelease(agsevent_t *e) {
switch (e->code) {
int x = e->d1, y = e->d2;
switch (e->d3) {
case AGSEVENT_BUTTON_LEFT:
#if 0
if (is_in_icon()) {
do_icon(e->mousex, e->mousey);
do_icon(x, y);
break;
}
#endif
@@ -406,15 +408,19 @@ static void cb_keyrelease(agsevent_t *e) {
// unhide();
break;
}
night.waitkey = e->code;
night.waitkey = e->d3;
break;
}
}
static void cb_mousemove(agsevent_t *e) {
int x = e->d1, y = e->d2;
// 音声mute/メッセージスキップ/メッセージ枠消去の領域に
// マウスが移動したら、その部分のアイコンを変化させる
}
// メッセージ表示時に、キー入力を促すアニメーションの設定
+1
View File
@@ -33,6 +33,7 @@
#include "menu.h"
#include "input.h"
#include "nact.h"
#include "key.h"
#include "sact.h"
#include "sprite.h"
#include "ngraph.h"
+14 -13
View File
@@ -34,6 +34,7 @@
#include "menu.h"
#include "input.h"
#include "nact.h"
#include "key.h"
#include "sact.h"
#include "sprite.h"
#include "sactsound.h"
@@ -212,7 +213,7 @@ static void cb_waitkey_simple(agsevent_t *e) {
switch (e->type) {
case AGSEVENT_KEY_PRESS:
if (e->code == KEY_Z) {
if (e->d3 == KEY_Z) {
cur = sdl_getTicks();
if (!sact.zhiding) {
slist_foreach(sact.sp_zhide, cb_defocused_zkey, &update);
@@ -241,7 +242,7 @@ static void cb_waitkey_simple(agsevent_t *e) {
// fall through
case AGSEVENT_KEY_RELEASE:
switch(e->code) {
switch(e->d3) {
case KEY_Z:
cur = sdl_getTicks();
if (500 < (cur - sact.zofftime) || !sact.zdooff) {
@@ -257,7 +258,7 @@ static void cb_waitkey_simple(agsevent_t *e) {
sact.waittype = KEYWAIT_BACKLOG;
break;
default:
sact.waitkey = e->code;
sact.waitkey = e->d3;
break;
}
}
@@ -291,7 +292,7 @@ void cb_waitkey_sprite(agsevent_t *e) {
// 右クリックキャンセル
// drag中でない時のみ、キャンセルを受け付ける
if (e->type == AGSEVENT_BUTTON_RELEASE &&
e->code == AGSEVENT_BUTTON_RIGHT) {
e->d3 == AGSEVENT_BUTTON_RIGHT) {
sact.waitkey = 0;
return;
}
@@ -310,7 +311,7 @@ void cb_waitkey_sprite(agsevent_t *e) {
// dragg中の sprite は無視する
if (sp == sact.draggedsp) continue;
if (focused_sp == NULL && sp_is_insprite(sp, e->mousex, e->mousey)) {
if (focused_sp == NULL && sp_is_insprite(sp, e->d1, e->d2)) {
/*
focusを得ている sprite
*/
@@ -387,8 +388,8 @@ static void cb_waitkey_selection(agsevent_t *e) {
static void cb_waitkey_backlog(agsevent_t *e) {
switch (e->type) {
case AGSEVENT_KEY_RELEASE:
switch (e->code) {
case KEY_ESCAPE:
switch (e->d3) {
case KEY_ESC:
sblog_end();
sact.waittype = KEYWAIT_MESSAGE;
break;
@@ -408,14 +409,14 @@ static void cb_waitkey_backlog(agsevent_t *e) {
break;
case AGSEVENT_BUTTON_RELEASE:
if (e->code == AGSEVENT_BUTTON_RIGHT) {
if (e->d3 == AGSEVENT_BUTTON_RIGHT) {
sblog_end();
sact.waittype = KEYWAIT_MESSAGE;
}
break;
case AGSEVENT_MOUSE_WHEEL:
if (e->code > 0)
if (e->d3 > 0)
sblog_pagenext();
else
sblog_pagepre();
@@ -433,15 +434,15 @@ void spev_callback(agsevent_t *e) {
}
if (sact.waittype != KEYWAIT_BACKLOG) {
if (e->type == AGSEVENT_KEY_PRESS && e->code == KEY_CTRL) {
if (e->type == AGSEVENT_KEY_PRESS && e->d3 == KEY_CTRL) {
sact.waitskiplv = 2;
sact.waitkey = e->code;
sact.waitkey = e->d3;
return;
}
if (e->type == AGSEVENT_KEY_RELEASE && e->code == KEY_CTRL) {
if (e->type == AGSEVENT_KEY_RELEASE && e->d3 == KEY_CTRL) {
sact.waitskiplv = 0;
sact.waitkey = e->code;
sact.waitkey = e->d3;
return;
}
}
+5 -5
View File
@@ -58,12 +58,12 @@ static int eventCB_GET(sprite_t *sp, agsevent_t *e) {
switch(e->type) {
case AGSEVENT_BUTTON_PRESS:
if (e->code != AGSEVENT_BUTTON_LEFT) break;
if (e->d3 != AGSEVENT_BUTTON_LEFT) break;
// drag開始時のマウスの位置記録
sp->u.get.dragging = TRUE;
sp->u.get.dragstart.x = e->mousex;
sp->u.get.dragstart.y = e->mousey;
sp->u.get.dragstart.x = e->d1;
sp->u.get.dragstart.y = e->d2;
if (sp->cg3) {
sp->curcg = sp->cg3;
@@ -104,8 +104,8 @@ static int eventCB_GET(sprite_t *sp, agsevent_t *e) {
// if (!sp->u.get.dragging) break;
// マウスの現在位置により新しい場所を計算
newx = sp->loc.x + (e->mousex - sp->u.get.dragstart.x);
newy = sp->loc.y + (e->mousey - sp->u.get.dragstart.y);
newx = sp->loc.x + (e->d1 - sp->u.get.dragstart.x);
newy = sp->loc.y + (e->d2 - sp->u.get.dragstart.y);
if (newx != sp->cur.x || newy != sp->cur.y) {
sp_updateme(sp);
sp->cur.x = newx;
+5 -5
View File
@@ -135,13 +135,13 @@ int sp_keywait(int *vOK, int *vRND, int *vD01, int *vD02, int *vD03, int timeout
{
// とりあえず、現在のマウス位置を送って、switch sprite の
// 状態を更新しておく
agsevent_t agse;
MyPoint p;
sys_getMouseInfo(&p, FALSE);
agsevent_t agse = {
.type = AGSEVENT_MOUSE_MOTION,
.mousex = p.x,
.mousey = p.y
};
agse.type = AGSEVENT_MOUSE_MOTION;
agse.d1 = p.x;
agse.d2 = p.y;
agse.d3 = 0;
spev_callback(&agse);
}
+1 -1
View File
@@ -40,7 +40,7 @@ static int eventCB_PUT(sprite_t *sp, agsevent_t *e) {
switch(e->type) {
case AGSEVENT_BUTTON_PRESS:
if (e->code != AGSEVENT_BUTTON_LEFT) return 0;
if (e->d3 != AGSEVENT_BUTTON_LEFT) return 0;
// ボタン押下時のスプライトがあれば、それを表示
if (sp->cg3) {
+6 -7
View File
@@ -31,6 +31,7 @@
#include "nact.h"
#include "ags.h"
#include "input.h"
#include "key.h"
#include "sact.h"
#include "sprite.h"
#include "ngraph.h"
@@ -76,7 +77,7 @@ static boolean sp_is_insprite2(sprite_t *sp, int x, int y, int margin) {
// マウスが移動したときの callback
static void cb_select_move(agsevent_t *e) {
int x = e->mousex, y = e->mousey;
int x = e->d1, y = e->d2;
sprite_t *sp = sact.sp[sact.sel.spno];
boolean newstate;
int newindex;
@@ -114,12 +115,12 @@ static void cb_select_move(agsevent_t *e) {
// ボタンがリリースされたときの callback
static void cb_select_release(agsevent_t *e) {
int x = e->mousex, y = e->mousey;
int x = e->d1, y = e->d2;
sprite_t *sp = sact.sp[sact.sel.spno];
boolean st;
int iy;
switch (e->code) {
switch (e->d3) {
case AGSEVENT_BUTTON_LEFT:
st = sp_is_insprite2(sp, x, y, sact.sel.frame_dot);
iy = (y - (sp->cur.y + sact.sel.frame_dot)) / (sact.sel.font_size + sact.sel.linespace);
@@ -197,10 +198,8 @@ static void setup_selwindow() {
// デフォルトで選択される選択肢がある場合、そこへカーソルを移動
if (sact.sel.movecursor) {
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);
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);
selected_item = (sact.sel.movecursor -1);
oldstate = TRUE;
oldindex = selected_item -1;
+2 -2
View File
@@ -41,7 +41,7 @@ static int eventCB_switch(sprite_t *sp, agsevent_t *e) {
switch(e->type) {
case AGSEVENT_BUTTON_PRESS:
if (e->code != AGSEVENT_BUTTON_LEFT) return 0;
if (e->d3 != AGSEVENT_BUTTON_LEFT) return 0;
// ボタン押下時のスプライトがあれば、それを表示
if (sp->cg3) {
@@ -53,7 +53,7 @@ static int eventCB_switch(sprite_t *sp, agsevent_t *e) {
break;
case AGSEVENT_BUTTON_RELEASE:
if (e->code != AGSEVENT_BUTTON_LEFT) return 0;
if (e->d3 != AGSEVENT_BUTTON_LEFT) return 0;
// ここにくるときは forcusが当たっているときしかこないので、
// curcg は cg2 に戻せばよい
+3 -2
View File
@@ -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,12 +1328,13 @@ 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;
}
+5 -9
View File
@@ -37,7 +37,6 @@
#include "ags.h"
#include "music.h"
#include "sdl_core.h"
#include "hacks.h"
#define SLOT 40
@@ -167,14 +166,14 @@ static void ChangeNotColor() {
case 24:
case 32:
{
uint32_t pic24s = PIX24(*src, *(src+1), *(src+2));
uint32_t pic24d = PIX24(*dst, *(dst+1), *(dst+2));
uint32_t pic24s = PIX24(*src, *(src+1), *(src+2)) & 0xf0f0f0;
uint32_t pic24d = PIX24(*dst, *(dst+1), *(dst+2)) & 0xf0f0f0;
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 != pic24s) {
if ((*yl & 0xf0f0f0) != pic24s) {
*yl = pic24d;
}
yl++;
@@ -183,9 +182,6 @@ static void ChangeNotColor() {
break;
}
}
// The CX command after ChangeNotColor (in FIGHT.ADV) must use a precise
// calculation.
daiakuji_cx_hack = true;
}
/*
@@ -589,14 +585,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);
uint32_t pic24 = PIX24(r, g, b) & 0xf0f0f0;
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 != pic24) {
if ((*yls & 0xf0f0f0) != pic24) {
*yld = *yls;
}
yls++; yld++;
+1 -2
View File
@@ -37,7 +37,6 @@
#include "modules.h"
#include "sdl_core.h"
#include "sdl_private.h"
#include "input.h"
#include "menu.h"
// キー変換テーブル
@@ -163,7 +162,7 @@ static void GetKeyStatus(void) {
}
*var = 0;
for (i = 0; i < NUM_KEYCODES; i++) {
for (i = 0; i < 256; i++) {
*var |= (keymap[no -1][i] * RawKeyInfo[i]);
}
+1 -1
View File
@@ -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 = rgb565_to_rgb888(pic16);
*yl = PIX24(PIXR16(pic16), PIXG16(pic16), PIXB16(pic16));
yl++; sp++;
}
sp += (cg->width - dw);
+7 -2
View File
@@ -84,7 +84,6 @@ if (EMSCRIPTEN)
"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)
@@ -100,7 +99,6 @@ if (EMSCRIPTEN)
"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")
elseif (ANDROID)
@@ -142,3 +140,10 @@ 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()
+33 -39
View File
@@ -42,18 +42,12 @@
#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 palette_changed(void) {
nact->ags.pal_changed = TRUE;
dbg_on_palette_change();
}
static void initPal(Palette256 *pal) {
int i;
for (i = 0; i < 256; i++) {
@@ -64,7 +58,7 @@ static void initPal(Palette256 *pal) {
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);
palette_changed();
nact->ags.pal_changed = TRUE;
}
boolean ags_check_param(int *x, int *y, int *w, int *h) {
@@ -106,7 +100,7 @@ boolean ags_check_param_xy(int *x, int *y) {
}
void ags_init(const char *render_driver) {
nact->ags.mouse_warp_enabled = true;
nact->ags.mouse_movesw = MOUSE_WARP_SMOOTH;
nact->ags.pal = &pal_256;
nact->ags.world_size.width = SYS35_DEFAULT_WIDTH;
nact->ags.world_size.height = SYS35_DEFAULT_HEIGHT;
@@ -129,7 +123,7 @@ void ags_remove(void) {
}
void ags_reset(void) {
nact->ags.mouse_warp_enabled = true;
nact->ags.mouse_movesw = MOUSE_WARP_SMOOTH;
nact->ags.eventcb = NULL;
initPal(&pal_256);
cg_reset();
@@ -157,7 +151,7 @@ void ags_setWorldSize(int width, int height, int depth) {
fade_outed = FALSE; /* thanx tajiri@wizard */
palette_changed();
nact->ags.pal_changed = TRUE;
}
void ags_setViewArea(int x, int y, int width, int height) {
@@ -229,14 +223,14 @@ void ags_setPalettes(Palette256 *src_pal, int src, int dst, int cnt) {
nact->ags.pal->green[dst + i] = src_pal->green[src + i];
nact->ags.pal->blue [dst + i] = src_pal->blue [src + i];
}
palette_changed();
nact->ags.pal_changed = TRUE;
}
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;
palette_changed();
nact->ags.pal_changed = TRUE;
}
void ags_setPaletteToSystem(int src, int cnt) {
@@ -633,42 +627,42 @@ void ags_loadCursor(int p1,int p2) {
}
}
void ags_setCursorLocation(int x, int y, bool is_dibgeo, bool for_selection) {
void ags_setCursorLocation(int x, int y, boolean is_dibgeo) {
int dx[8], dy[8];
int i, delx, dely;
MyPoint p;
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;
}
#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;
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);
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);
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;
}
sdl_setCursorLocation(x, y);
} else if (!for_selection) {
sdl_setCursorInternalLocation(x, y);
sdl_sleep(cursor_move_time);
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;
}
#endif
}
EMSCRIPTEN_KEEPALIVE
+23 -19
View File
@@ -78,26 +78,29 @@ typedef struct agsurface agsurface_t;
// for SDL_surface
#define PIXEL_AT(suf, x, y) ((suf)->pixels + (y) * (suf)->pitch + (x) * (suf)->format->BytesPerPixel)
typedef struct {
struct _agsevent {
int type;
int code;
int mousex, mousey;
} agsevent_t;
enum agsevent_type {
AGSEVENT_MOUSE_MOTION,
AGSEVENT_BUTTON_PRESS,
AGSEVENT_BUTTON_RELEASE,
AGSEVENT_KEY_PRESS,
AGSEVENT_KEY_RELEASE,
AGSEVENT_TIMER,
AGSEVENT_MOUSE_WHEEL,
int d1, d2, d3;
};
typedef struct _agsevent agsevent_t;
enum agsevent_button {
AGSEVENT_BUTTON_LEFT,
AGSEVENT_BUTTON_MID,
AGSEVENT_BUTTON_RIGHT,
#define AGSEVENT_MOUSE_MOTION 1
#define AGSEVENT_BUTTON_PRESS 2
#define AGSEVENT_BUTTON_RELEASE 3
#define AGSEVENT_KEY_PRESS 4
#define AGSEVENT_KEY_RELEASE 5
#define AGSEVENT_TIMER 6
#define AGSEVENT_MOUSE_WHEEL 7
#define AGSEVENT_BUTTON_LEFT 1
#define AGSEVENT_BUTTON_MID 2
#define AGSEVENT_BUTTON_RIGHT 3
enum mouse_warp_mode {
MOUSE_WARP_DISABLED,
MOUSE_WARP_DIRECT,
MOUSE_WARP_SMOOTH,
};
struct _ags {
@@ -110,10 +113,11 @@ 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 */
bool mouse_warp_enabled;
boolean noantialias; /* antialias を使用しない */
boolean noimagecursor; /* リソースファイルのカーソルを読みこまない */
};
@@ -204,7 +208,7 @@ 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, bool is_dibgeo, bool for_selection);
extern void ags_setCursorLocation(int x, int y, boolean dibgeo);
extern void ags_setCursorMoveTime(int msec);
extern int ags_getCursorMoveTime();
+102
View File
@@ -0,0 +1,102 @@
/*
* Copyright (C) 2020 <KichikuouChrome@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#include <SDL.h>
#include <jni.h>
#include "system.h"
#include "portab.h"
#include "cdrom.h"
static int cdrom_init(char *);
static int cdrom_exit(void);
static int cdrom_reset(void);
static int cdrom_start(int, int);
static int cdrom_stop();
static int cdrom_getPlayingInfo(cd_time *);
#define cdrom cdrom_android
cdromdevice_t cdrom = {
cdrom_init,
cdrom_exit,
cdrom_reset,
cdrom_start,
cdrom_stop,
cdrom_getPlayingInfo,
NULL,
NULL
};
int cdrom_init(char *name) {
return OK;
}
int cdrom_reset(void) {
cdrom_stop();
return OK;
}
int cdrom_exit(void) {
cdrom_stop();
return OK;
}
int cdrom_start(int trk, int loop) {
JNIEnv *env = SDL_AndroidGetJNIEnv();
if ((*env)->PushLocalFrame(env, 16) < 0) {
WARNING("Failed to allocate JVM local references");
return NG;
}
jobject context = SDL_AndroidGetActivity();
jmethodID mid = (*env)->GetMethodID(env, (*env)->GetObjectClass(env, context),
"cddaStart", "(IZ)V");
(*env)->CallVoidMethod(env, context, mid, trk, loop == 0);
(*env)->PopLocalFrame(env, NULL);
return OK;
}
int cdrom_stop() {
JNIEnv *env = SDL_AndroidGetJNIEnv();
if ((*env)->PushLocalFrame(env, 16) < 0) {
WARNING("Failed to allocate JVM local references");
return NG;
}
jobject context = SDL_AndroidGetActivity();
jmethodID mid = (*env)->GetMethodID(env, (*env)->GetObjectClass(env, context),
"cddaStop", "()V");
(*env)->CallVoidMethod(env, context, mid);
(*env)->PopLocalFrame(env, NULL);
return OK;
}
int cdrom_getPlayingInfo (cd_time *info) {
JNIEnv *env = SDL_AndroidGetJNIEnv();
if ((*env)->PushLocalFrame(env, 16) < 0) {
WARNING("Failed to allocate JVM local references");
return NG;
}
jobject context = SDL_AndroidGetActivity();
jmethodID mid = (*env)->GetMethodID(env, (*env)->GetObjectClass(env, context),
"cddaCurrentPosition", "()I");
int t = (*env)->CallIntMethod(env, context, mid);
(*env)->PopLocalFrame(env, NULL);
info->t = t & 0xff;
FRAMES_TO_MSF(t >> 8, &info->m, &info->s, &info->f);
return OK;
}
+6 -2
View File
@@ -43,6 +43,10 @@ extern cdromdevice_t cdrom_bsd;
extern cdromdevice_t cdrom_emscripten;
#define NATIVE_CD_DEVICE &cdrom_emscripten
#elif defined(ENABLE_CDROM_ANDROID)
extern cdromdevice_t cdrom_android;
#define NATIVE_CD_DEVICE &cdrom_android
#else
extern cdromdevice_t cdrom_empty;
@@ -54,7 +58,7 @@ extern cdromdevice_t cdrom_mp3;
#endif
cdromdevice_t *cd_init(const char *dev) {
#if defined(ENABLE_CDROM_EMSCRIPTEN)
#if defined(ENABLE_CDROM_EMSCRIPTEN) || defined(ENABLE_CDROM_ANDROID)
return NATIVE_CD_DEVICE;
#else
struct stat st;
@@ -67,5 +71,5 @@ cdromdevice_t *cd_init(const char *dev) {
WARNING("no cdrom device available");
return NULL;
#endif
#endif // ENABLE_CDROM_EMSCRIPTEN
#endif // ENABLE_CDROM_EMSCRIPTEN || ENABLE_CDROM_ANDROID
}
+29 -21
View File
@@ -27,10 +27,39 @@
static int frame_of_getpos = -1;
static int cdrom_init(char *);
static int cdrom_exit(void);
static int cdrom_reset(void);
extern int cdrom_start(int, int);
extern int cdrom_stop();
static int cdrom_getPlayingInfo(cd_time *);
#define cdrom cdrom_emscripten
cdromdevice_t cdrom = {
cdrom_init,
cdrom_exit,
cdrom_reset,
cdrom_start,
cdrom_stop,
cdrom_getPlayingInfo,
NULL,
NULL
};
int cdrom_init(char *name) {
return OK;
}
int cdrom_exit(void) {
cdrom_stop();
return OK;
}
int cdrom_reset(void) {
cdrom_stop();
return OK;
}
EM_JS(int, cdrom_start, (int trk, int loop), {
xsystem35.cdPlayer.play(trk, loop == 0 ? 1 : 0);
return xsystem35.Status.OK;
@@ -41,16 +70,6 @@ EM_JS(int, cdrom_stop, (), {
return xsystem35.Status.OK;
});
int cdrom_exit(void) {
cdrom_stop();
return OK;
}
int cdrom_reset(void) {
cdrom_stop();
return OK;
}
int cdrom_getPlayingInfo(cd_time *info) {
if (nact->frame_count == frame_of_getpos)
nact->wait_vsync = TRUE;
@@ -63,14 +82,3 @@ int cdrom_getPlayingInfo(cd_time *info) {
FRAMES_TO_MSF(t >> 8, &info->m, &info->s, &info->f);
return OK;
}
cdromdevice_t cdrom_emscripten = {
cdrom_init,
cdrom_exit,
cdrom_reset,
cdrom_start,
cdrom_stop,
cdrom_getPlayingInfo,
NULL,
NULL
};
+1 -3
View File
@@ -72,9 +72,7 @@ static int cdrom_init(char *playlist_path) {
fp = fopen("_inmm.ini", "r");
}
if (!fp) {
// 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);
NOTICE("cdrom: Cannot open playlist %s", playlist_path);
return NG;
}
-7
View File
@@ -87,11 +87,4 @@ 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__ */
+1 -12
View File
@@ -27,7 +27,6 @@
#include "xsystem35.h"
#include "scenario.h"
#include "ags.h"
#include "hacks.h"
void commandCC() {
int src_x = getCaliValue();
@@ -70,16 +69,7 @@ void commandCX() {
switch(mode) {
case 0:
// In Daiakuji, the image after the blending is used as a source image
// for sprite copy (CX 1). SDL's SIMD blending implementation has some
// error (blending #ff00ff and #ff00ff results in #fd00fd), so the
// 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_copyArea_shadow(src_x, src_y, width, height, dst_x, dst_y);
ags_updateArea(dst_x, dst_y, width, height);
break;
case 1:
@@ -104,7 +94,6 @@ 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
View File
@@ -127,7 +127,7 @@ void commandIZ() {
int x = getCaliValue();
int y = getCaliValue();
ags_setCursorLocation(x, y, true, false);
ags_setCursorLocation(x, y, TRUE);
DEBUG_COMMAND("IZ %d,%d:", x, y);
}
+1 -1
View File
@@ -326,7 +326,7 @@ void commandMJ() {
mj_param.h = h;
mj_param.oldstring = t1;
ags_setCursorLocation(x, y, false, false);
ags_setCursorLocation(x, y, FALSE); /* XXX */
menu_inputstring2(&mj_param);
if (mj_param.newstring == NULL) return;
+4 -2
View File
@@ -345,8 +345,10 @@ void commandZZ0() {
sys_exit(sysVar[0]);
#endif
} else if (sw == 1) {
while (!nact->is_quit)
sys_keywait(1000, 0);
while (TRUE) {
usleep(1000*1000);
sys_getInputInfo();
}
}
}
+3 -10
View File
@@ -360,23 +360,21 @@ 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;
}
if (restore_op == BREAKPOINT)
SYSERROR("Illegal BREAKPOINT instruction");
return restore_op;
SYSERROR("Illegal BREAKPOINT instruction");
return BREAKPOINT;
}
static void set_stack_frame(StackFrame *frame, int page, int addr, boolean is_return_addr) {
@@ -530,11 +528,6 @@ void dbg_onsleep(void) {
dbg_impl->onsleep();
}
void dbg_on_palette_change(void) {
if (dbg_impl)
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;
-4
View File
@@ -45,10 +45,8 @@ 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
@@ -57,10 +55,8 @@ void dbg_post_command(void *data);
#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
+17 -63
View File
@@ -51,7 +51,6 @@ 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();
@@ -68,12 +67,12 @@ 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);
free(str);
cJSON_Delete(json);
cJSON_free(json);
}
static void emit_initialized_event(void) {
@@ -481,20 +480,6 @@ 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->red[i] << 16 |
nact->ags.pal->green[i] << 8 |
nact->ags.pal->blue[i];
cJSON_AddItemToArray(palette, cJSON_CreateNumber(val));
}
}
static boolean handle_request(cJSON *request) {
boolean continue_repl = true;
@@ -509,7 +494,7 @@ static boolean handle_request(cJSON *request) {
if (!cJSON_IsString(command)) {
fprintf(stderr, "protocol error: command is not a string\n");
// FIXME: return an error response
cJSON_Delete(resp);
cJSON_free(resp);
return continue_repl;
}
@@ -551,15 +536,8 @@ 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 {
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);
fprintf(stderr, "unknown command \"%s\"\n", command->valuestring);
}
send_json(resp);
return continue_repl;
@@ -571,7 +549,7 @@ static boolean handle_message(char *msg) {
boolean continue_repl = true;
if (cJSON_IsString(type) && !strcmp(type->valuestring, "request"))
continue_repl = handle_request(json);
cJSON_Delete(json);
cJSON_free(json);
free(msg);
return continue_repl;
}
@@ -589,13 +567,13 @@ static int read_command_thread(void *data) {
}
char *buf = malloc(content_length);
fread(buf, content_length, 1, stdin);
sdl_post_debugger_command(buf);
msgq_enqueue(queue, buf);
content_length = -1;
} else {
fprintf(stderr, "Unknown Debug Adapter Protocol header: %s", header);
}
}
sdl_post_debugger_command(NULL); // end of messages
msgq_enqueue(queue, NULL); // EOF
return 0;
}
@@ -610,16 +588,11 @@ static void dbg_dap_init(const char *path) {
SDL_CreateThread(read_command_thread, "Debugger", NULL);
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);
}
while (!initialized) {
char *msg = msgq_dequeue(queue);
if (!msg)
break;
handle_message(msg);
}
}
@@ -632,16 +605,11 @@ static void dbg_dap_repl(int bp_no) {
dbg_state = DBG_RUNNING;
boolean continue_repl = true;
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);
}
while (continue_repl) {
char *msg = msgq_dequeue(queue);
if (!msg)
break;
continue_repl = handle_message(msg);
}
}
@@ -656,24 +624,10 @@ 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,
};
-1
View File
@@ -58,7 +58,6 @@ 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;
-2
View File
@@ -33,8 +33,6 @@
/* 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;
-4
View File
@@ -20,8 +20,6 @@
#ifndef __HACKS_H_
#define __HACKS_H_
#include <stdbool.h>
enum gameId {
GAME_UNKNOWN = 0,
GAME_TT2,
@@ -33,6 +31,4 @@ 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
View File
@@ -41,123 +41,6 @@
#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);
+153
View File
@@ -0,0 +1,153 @@
/*
* 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__ */
+2 -2
View File
@@ -87,7 +87,7 @@ void
on_item5_activate (GtkMenuItem *menuitem,
gpointer user_data)
{
nact->ags.mouse_warp_enabled = true;
nact->ags.mouse_movesw = MOUSE_WARP_SMOOTH;
gtk_menu_popdown(GTK_MENU(menu_window_popup));
}
@@ -97,7 +97,7 @@ void
on_item6_activate (GtkMenuItem *menuitem,
gpointer user_data)
{
nact->ags.mouse_warp_enabled = false;
nact->ags.mouse_movesw = MOUSE_WARP_DISABLED;
gtk_menu_popdown(GTK_MENU(menu_window_popup));
}
+38 -22
View File
@@ -24,15 +24,43 @@
#include "portab.h"
#include "midi.h"
static int midi_initilize(char *pname, int subdev);
static int midi_exit(void);
static int midi_reset(void);
static int midi_start(int no, int loop, char *data, int datalen);
static int midi_stop();
extern int midi_pause(void);
extern int midi_unpause(void);
static int midi_get_playing_info(midiplaystate *st);
static int midi_getflag(int mode, int index);
static int midi_setflag(int mode, int index, int val);
extern int midi_setvol(int vol);
extern int midi_getvol();
extern int midi_fadestart(int time, int volume, int stop);
extern boolean midi_fading();
#define midi midi_emscripten
mididevice_t midi = {
midi_initilize,
midi_exit,
midi_reset,
midi_start,
midi_stop,
midi_pause,
midi_unpause,
midi_get_playing_info,
midi_getflag,
midi_setflag,
midi_setvol,
midi_getvol,
midi_fadestart,
midi_fading
};
static int midi_initilize(char *pname, int subdev) {
return OK;
}
EM_JS(int, midi_stop, (void), {
xsystem35.midiPlayer.stop();
return xsystem35.Status.OK;
});
static int midi_exit(void) {
midi_stop();
return OK;
@@ -48,6 +76,11 @@ static int midi_start(int no, int loop, char *data, int datalen) {
return OK;
}
static int midi_stop() {
EM_ASM( xsystem35.midiPlayer.stop(); );
return OK;
}
EM_JS(int, midi_pause, (void), {
xsystem35.midiPlayer.pause();
return xsystem35.Status.OK;
@@ -94,20 +127,3 @@ EM_JS(int, midi_fadestart, (int time, int volume, int stop), {
EM_JS(boolean, midi_fading, (), {
return xsystem35.midiPlayer.isFading();
});
mididevice_t midi_emscripten = {
midi_initilize,
midi_exit,
midi_reset,
midi_start,
midi_stop,
midi_pause,
midi_unpause,
midi_get_playing_info,
midi_getflag,
midi_setflag,
midi_setvol,
midi_getvol,
midi_fadestart,
midi_fading
};
+1 -4
View File
@@ -89,13 +89,10 @@ 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) {
WARNING("Cannot load MIDI: %s", SDL_GetError());
if (!mix_music)
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;
+212 -18
View File
@@ -23,6 +23,7 @@
#include "config.h"
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -44,6 +45,7 @@ typedef int emscripten_align1_int;
#include "message.h"
const char *save_signature[] = {
[SAVEFMT_SYS35] = "This is save data for System3.5 Win95 For NACT/ADV system (C) 1996 ALICE-SOFT",
[SAVEFMT_XSYS35] = "System3.5 SavaData(c)ALICE-SOFT",
[SAVEFMT_SYS36] = "System3.5 SaveData(c)ALICE-SOFT",
[SAVEFMT_SYS38] = "System3.8 SaveData(c)ALICE-SOFT",
@@ -113,11 +115,7 @@ typedef struct {
emscripten_align1_int rsv2;
} asd_varPageHdr;
#ifdef __EMSCRIPTEN__
static enum save_format save_format = SAVEFMT_XSYS35;
#else
static enum save_format save_format = SAVEFMT_SYS38;
#endif
#ifdef __EMSCRIPTEN__
EM_JS(void, scheduleSync, (), {
@@ -477,19 +475,83 @@ int save_copyAll(int dstno, int srcno) {
return status;
}
static int loadpartial_sys35(char *saveTop, int filesize, struct VarRef *vref, int cnt) {
if (filesize < 0xb0)
return SAVE_LOADERR;
cnt = min(cnt, v_sliceSize(vref));
int *var = v_resolveRef(vref);
if (vref->page == 0) {
// SysVar section
int section_offset = LittleEndian_getDW(saveTop, 0x90);
int section_length = LittleEndian_getDW(saveTop, 0x94);
if (section_offset + 16 + section_length > filesize)
return SAVE_LOADERR;
int sysvar_count = LittleEndian_getDW(saveTop, section_offset);
if (sysvar_count > varPage[0].size)
return SAVE_LOADERR; // resizing system page is not supported in sys3.5
int offset = section_offset + 16 + vref->index * 2;
for (int i = 0; i < cnt; i++) {
var[i] = LittleEndian_getW(saveTop, offset);
offset += 2;
}
return SAVE_LOADOK;
}
// Arrays section
int section_offset = LittleEndian_getDW(saveTop, 0xa0);
int section_length = LittleEndian_getDW(saveTop, 0xa4);
if (section_offset + 16 + section_length > filesize)
return SAVE_LOADERR;
int page_count = LittleEndian_getDW(saveTop, section_offset + 4);
int offset = section_offset + 16;
// TODO: section size check
for (int i = 0; i < page_count; i++) {
int page = LittleEndian_getDW(saveTop, offset); offset += 4;
int count = LittleEndian_getDW(saveTop, offset); offset += 4;
int content_offset = LittleEndian_getDW(saveTop, offset); offset += 4;
offset += 4;
if (page != vref->page)
continue;
// TODO page resize
// TODO: section size check
content_offset += vref->index * 2;
for (int j = 0; j < cnt; j++) {
var[j] = LittleEndian_getW(saveTop, content_offset + j * 2);
}
return SAVE_LOADOK;
}
return SAVE_LOADERR;
}
/* データの一部ロード */
int save_loadPartial(int no, struct VarRef *vref, int cnt) {
if (no >= SAVE_MAXNUMBER)
return SAVE_SAVEERR;
cnt = min(cnt, v_sliceSize(vref));
int *var = v_resolveRef(vref);
int status, filesize;
char *saveTop = loadGameData(no, &status, &filesize);
if (!saveTop)
return status;
if (filesize < 0x60)
goto errexit;
enum save_format format = (enum save_format)-1;
for (int i = 0; i < sizeof(save_signature) / sizeof(save_signature[0]); i++) {
if (!strcmp(save_signature[i], saveTop)) {
format = i;
break;
}
}
if (format < 0) {
WARNING("unrecognized save format");
goto errexit;
}
if (format == SAVEFMT_SYS35) {
int result = loadpartial_sys35(saveTop, filesize, vref, cnt);
free(saveTop);
return result;
}
if (filesize <= sizeof(asd_baseHdr))
goto errexit;
@@ -499,6 +561,8 @@ int save_loadPartial(int no, struct VarRef *vref, int cnt) {
goto errexit;
}
cnt = min(cnt, v_sliceSize(vref));
int *var = v_resolveRef(vref);
if (save_base->varSys[vref->page] == 0)
goto errexit;
@@ -519,9 +583,11 @@ int save_loadPartial(int no, struct VarRef *vref, int cnt) {
/* データの一部セーブ */
int save_savePartial(int no, struct VarRef *vref, int cnt) {
if (no >= SAVE_MAXNUMBER || !varPage[vref->page].saveflag)
if (no >= SAVE_MAXNUMBER) {
return SAVE_SAVEERR;
}
if (!varPage[vref->page].saveflag)
goto errexit;
cnt = min(cnt, v_sliceSize(vref));
int *var = v_resolveRef(vref);
@@ -553,6 +619,125 @@ int save_savePartial(int no, struct VarRef *vref, int cnt) {
return SAVE_SAVEERR;
}
static int loadall_sys35(char *saveTop, int filesize) {
if (filesize < 0xb0)
return SAVE_LOADERR;
int page = LittleEndian_getDW(saveTop, 0x80);
int addr = LittleEndian_getDW(saveTop, 0x84);
sl_jmpFar2(page - 1, addr);
// SysVar section
int section_offset = LittleEndian_getDW(saveTop, 0x90);
int section_length = LittleEndian_getDW(saveTop, 0x94);
if (section_offset + 16 + section_length > filesize)
return SAVE_LOADERR;
int sysvar_count = LittleEndian_getDW(saveTop, section_offset);
if (sysvar_count > varPage[0].size)
return SAVE_LOADERR; // resizing system page is not supported in sys3.5
int offset = section_offset + 16;
for (int i = 0; i < sysvar_count; i++) {
varPage[0].value[i] = LittleEndian_getW(saveTop, offset);
offset += 2;
}
nact->sel.MsgFontSize = LittleEndian_getW(saveTop, offset); offset += 2;
nact->msg.MsgFontSize = LittleEndian_getW(saveTop, offset); offset += 2;
cg_vspPB = LittleEndian_getW(saveTop, offset); offset += 2;
nact->msg.MsgFontColor = LittleEndian_getW(saveTop, offset); offset += 2;
nact->sel.MsgFontColor = LittleEndian_getW(saveTop, offset); offset += 2;
nact->sel.WinFrameColor = LittleEndian_getW(saveTop, offset); offset += 2;
nact->sel.WinBackgroundColor = LittleEndian_getW(saveTop, offset); offset += 2;
nact->msg.WinFrameColor = LittleEndian_getW(saveTop, offset); offset += 2;
nact->msg.WinBackgroundColor = LittleEndian_getW(saveTop, offset); offset += 2;
int left = section_offset + 16 + section_length - offset;
WARNING("0x%x bytes for window info", left);
if (left < 0)
return SAVE_LOADERR;
int win_info_count = left / 32;
if (win_info_count >= SELWINMAX)
return SAVE_LOADERR;
for (int i = 1; i <= win_info_count; i++) {
offset += 2;
nact->sel.wininfo[i].x = LittleEndian_getW(saveTop, offset); offset += 2;
nact->sel.wininfo[i].y = LittleEndian_getW(saveTop, offset); offset += 2;
int ex = LittleEndian_getW(saveTop, offset); offset += 2;
int ey = LittleEndian_getW(saveTop, offset); offset += 2;
nact->sel.wininfo[i].width = ex + 1 - nact->sel.wininfo[i].x;
nact->sel.wininfo[i].height = ey + 1 - nact->sel.wininfo[i].y;
offset += 6;
}
for (int i = 1; i <= win_info_count; i++) {
offset += 2;
nact->msg.wininfo[i].x = LittleEndian_getW(saveTop, offset); offset += 2;
nact->msg.wininfo[i].y = LittleEndian_getW(saveTop, offset); offset += 2;
int ex = LittleEndian_getW(saveTop, offset); offset += 2;
int ey = LittleEndian_getW(saveTop, offset); offset += 2;
nact->msg.wininfo[i].width = ex + 1 - nact->msg.wininfo[i].x;
nact->msg.wininfo[i].height = ey + 1 - nact->msg.wininfo[i].y;
offset += 6;
}
//assert(offset == section_offset + 16 + section_length);
// Strings section
section_offset = LittleEndian_getDW(saveTop, 0x98);
section_length = LittleEndian_getDW(saveTop, 0x9c);
if (section_offset + 16 + section_length > filesize)
return SAVE_LOADERR;
int strvar_count = LittleEndian_getDW(saveTop, section_offset);
int strvar_length = LittleEndian_getDW(saveTop, section_offset + 4);
offset = section_offset + 16;
if (section_length != strvar_count * strvar_length)
return SAVE_LOADERR;
if (strvar_count > svar_maxindex())
strvar_count = svar_maxindex();
char *buf = malloc(strvar_length + 1);
buf[strvar_length] = '\0';
for (int i = 1; i <= strvar_count; i++) {
memcpy(buf, saveTop + offset, strvar_length);
svar_set(i, buf);
offset += strvar_length;
}
// Arrays section
section_offset = LittleEndian_getDW(saveTop, 0xa0);
section_length = LittleEndian_getDW(saveTop, 0xa4);
if (section_offset + 16 + section_length > filesize)
return SAVE_LOADERR;
int array_total_size = LittleEndian_getDW(saveTop, section_offset);
int page_count = LittleEndian_getDW(saveTop, section_offset + 4);
offset = section_offset + 16;
// TODO: section size check
int total = 0;
for (int i = 0; i < page_count; i++) {
int page = LittleEndian_getDW(saveTop, offset); offset += 4;
int count = LittleEndian_getDW(saveTop, offset); offset += 4;
int content_offset = LittleEndian_getDW(saveTop, offset); offset += 4;
offset += 4;
total += count;
// TODO page resize
// TODO: section size check
for (int j = 0; j < count; j++) {
varPage[page].value[j] = LittleEndian_getW(saveTop, content_offset + j * 2);
}
}
if (total != array_total_size) {
WARNING("wrong array total size");
} else {
WARNING("correct array total size");
}
// Stack section
section_offset = LittleEndian_getDW(saveTop, 0xa8);
section_length = LittleEndian_getDW(saveTop, 0xac);
if (section_offset + section_length > filesize)
return SAVE_LOADERR;
sl_loadStack(SAVEFMT_SYS35, saveTop + section_offset, section_length);
return SAVE_LOADOK;
}
/* データのロード */
int save_loadAll(int no) {
@@ -563,17 +748,11 @@ int save_loadAll(int no) {
char *saveTop = loadGameData(no, &status, &filesize);
if (!saveTop)
return status;
if (filesize <= sizeof(asd_baseHdr))
if (filesize < 0x60)
goto errexit;
/* 各種データの反映 */
asd_baseHdr *save_base = (asd_baseHdr *)saveTop;
if (save_base->version != SAVE_DATAVERSION) {
WARNING("endian mismatch");
goto errexit;
}
enum save_format format = (enum save_format)-1;
for (int i = 0; i < sizeof(save_signature) / sizeof(save_signature[0]); i++) {
if (!strcmp(save_signature[i], save_base->ID)) {
if (!strcmp(save_signature[i], saveTop)) {
format = i;
break;
}
@@ -583,6 +762,21 @@ int save_loadAll(int no) {
goto errexit;
}
if (format == SAVEFMT_SYS35) {
int result = loadall_sys35(saveTop, filesize);
free(saveTop);
return result;
}
if (filesize <= sizeof(asd_baseHdr))
goto errexit;
/* 各種データの反映 */
asd_baseHdr *save_base = (asd_baseHdr *)saveTop;
if (save_base->version != SAVE_DATAVERSION) {
WARNING("endian mismatch");
goto errexit;
}
nact->sel.MsgFontSize = save_base->selMsgSize;
nact->sel.MsgFontColor = save_base->selMsgColor;
nact->sel.WinBackgroundColor = save_base->selBackColor;
+1
View File
@@ -38,6 +38,7 @@
enum save_format {
SAVEFMT_XSYS35,
SAVEFMT_SYS35, // System3.5 v1.x
SAVEFMT_SYS36, // System3.5 v2.x - System3.6
SAVEFMT_SYS38, // System3.8 - System3.9
};
+121 -36
View File
@@ -354,7 +354,7 @@ void sl_popVar(struct VarRef *vref, int cnt) {
}
}
enum save_stack_frame_type {
enum xsys35_stack_frame_type {
SAVE_NEARJMP = 1,
SAVE_FARJMP = 2,
SAVE_VARIABLE = 3,
@@ -367,15 +367,15 @@ enum txx_type {
TxxTEXTLOC = 3
};
struct save_stack_frame {
struct save_stack_frame *next;
struct xsys35_stack_frame {
struct xsys35_stack_frame *next;
int len;
int buf[];
};
struct save_stack_frame *push_save_stack_frame(int size, struct save_stack_frame *next) {
struct save_stack_frame *f =
malloc(sizeof(struct save_stack_frame) + sizeof(int) * size);
struct xsys35_stack_frame *push_xsys35_stack_frame(int size, struct xsys35_stack_frame *next) {
struct xsys35_stack_frame *f =
malloc(sizeof(struct xsys35_stack_frame) + sizeof(int) * size);
f->next = next;
f->len = size;
return f;
@@ -391,13 +391,13 @@ uint8_t *sl_saveStack(enum save_format format, int *size_out) {
}
// Serialize to the stack format used in old versions of xsystem35.
struct save_stack_frame *frame = NULL;
struct xsys35_stack_frame *frame = NULL;
uint8_t *sp = stack_top;
while (sp > stack_buf) {
switch (sp[-1]) {
case STACK_FARCALL:
sp -= 7;
frame = push_save_stack_frame(4, frame);
frame = push_xsys35_stack_frame(4, frame);
frame->buf[3] = SAVE_FARJMP;
frame->buf[2] = 2;
frame->buf[1] = LittleEndian_getW(sp, 0) - 1; // page
@@ -405,7 +405,7 @@ uint8_t *sl_saveStack(enum save_format format, int *size_out) {
break;
case STACK_NEARCALL:
sp -= 5;
frame = push_save_stack_frame(3, frame);
frame = push_xsys35_stack_frame(3, frame);
frame->buf[2] = SAVE_NEARJMP;
frame->buf[1] = 1;
frame->buf[0] = LittleEndian_getDW(sp, 0); // addr
@@ -422,7 +422,7 @@ uint8_t *sl_saveStack(enum save_format format, int *size_out) {
int base = frame->buf[frame->len - 4];
// Merge into existing SAVE_VARIABLE frame.
if (page == fpage && index == base - 1) {
frame = realloc(frame, sizeof(struct save_stack_frame) + sizeof(int) * (frame->len + 1));
frame = realloc(frame, sizeof(struct xsys35_stack_frame) + sizeof(int) * (frame->len + 1));
frame->len++;
frame->buf[frame->len - 1] = SAVE_VARIABLE;
frame->buf[frame->len - 2] = count + 1;
@@ -432,7 +432,7 @@ uint8_t *sl_saveStack(enum save_format format, int *size_out) {
break;
}
}
frame = push_save_stack_frame(5, frame);
frame = push_xsys35_stack_frame(5, frame);
frame->buf[4] = SAVE_VARIABLE;
frame->buf[3] = 3;
frame->buf[2] = page;
@@ -442,7 +442,7 @@ uint8_t *sl_saveStack(enum save_format format, int *size_out) {
break;
case STACK_TEXTCOLOR:
sp -= 3;
frame = push_save_stack_frame(5, frame);
frame = push_xsys35_stack_frame(5, frame);
frame->buf[4] = SAVE_TXXSTATE;
frame->buf[3] = 3;
frame->buf[2] = TxxTEXTCOLOR;
@@ -451,7 +451,7 @@ uint8_t *sl_saveStack(enum save_format format, int *size_out) {
break;
case STACK_TEXTSIZE:
sp -= 6;
frame = push_save_stack_frame(5, frame);
frame = push_xsys35_stack_frame(5, frame);
frame->buf[4] = SAVE_TXXSTATE;
frame->buf[3] = 3;
frame->buf[2] = TxxTEXTSIZE;
@@ -460,7 +460,7 @@ uint8_t *sl_saveStack(enum save_format format, int *size_out) {
break;
case STACK_TEXTLOC:
sp -= 9;
frame = push_save_stack_frame(5, frame);
frame = push_xsys35_stack_frame(5, frame);
frame->buf[4] = SAVE_TXXSTATE;
frame->buf[3] = 3;
frame->buf[2] = TxxTEXTLOC;
@@ -472,15 +472,15 @@ uint8_t *sl_saveStack(enum save_format format, int *size_out) {
}
}
int total_len = 0;
for (struct save_stack_frame *f = frame; f; f = f->next)
for (struct xsys35_stack_frame *f = frame; f; f = f->next)
total_len += f->len;
int *buf = malloc(total_len * sizeof(int));
int *p = buf;
for (struct save_stack_frame *f = frame; f;) {
for (struct xsys35_stack_frame *f = frame; f;) {
memcpy(p, f->buf, f->len * sizeof(int));
p += f->len;
struct save_stack_frame *next = f->next;
struct xsys35_stack_frame *next = f->next;
free(f);
f = next;
}
@@ -510,36 +510,22 @@ uint8_t *sl_saveStack(enum save_format format, int *size_out) {
return (uint8_t *)buf;
}
void sl_loadStack(enum save_format format, uint8_t *unaligned_data, int size) {
if (format != SAVEFMT_XSYS35) {
if (size > stack_size) {
while (size > stack_size)
stack_size *= 2;
free(stack_buf);
stack_buf = malloc(stack_size);
if (!stack_buf)
NOMEMERR();
}
memcpy(stack_buf, unaligned_data, size);
stack_top = stack_buf + size;
return;
}
static void load_stack_xsys35(uint8_t *unaligned_data, int size) {
// Deserialize from the stack format used in old versions of xsystem35.
int *data = malloc(size);
memcpy(data, unaligned_data, size);
struct save_stack_frame *frame = NULL;
struct xsys35_stack_frame *frame = NULL;
for (int *p = data + size / sizeof(int); p > data;) {
int len = p[-2] + 2;
p -= len;
frame = push_save_stack_frame(len, frame);
frame = push_xsys35_stack_frame(len, frame);
memcpy(frame->buf, p, len * sizeof(int));
}
free(data);
stack_top = stack_buf;
for (struct save_stack_frame *f = frame; f;) {
for (struct xsys35_stack_frame *f = frame; f;) {
switch (f->buf[f->len - 1]) {
case SAVE_NEARJMP:
if (f->len != 3)
@@ -601,12 +587,111 @@ void sl_loadStack(enum save_format format, uint8_t *unaligned_data, int size) {
default:
SYSERROR("broken stack data");
}
struct save_stack_frame *next = f->next;
struct xsys35_stack_frame *next = f->next;
free(f);
f = next;
}
}
struct asdv1_stack_frame {
struct asdv1_stack_frame *next;
int len;
uint8_t buf[];
};
struct asdv1_stack_frame *push_asdv1_stack_frame(int size, struct asdv1_stack_frame *next) {
struct asdv1_stack_frame *f =
malloc(sizeof(struct asdv1_stack_frame) + size);
f->next = next;
f->len = size;
return f;
}
static void load_stack_sys35(uint8_t *data, int size) {
struct asdv1_stack_frame *frame = NULL;
for (uint8_t *p = data + size; p > data;) {
int frame_size = 0;
switch (p[-1]) {
case STACK_FARCALL:
frame_size = 13;
break;
case 0xee:
frame_size = 5;
break;
case 0xdd:
frame_size = LittleEndian_getW(p, -3) * 2 + 5;
break;
}
if (!frame_size)
break; // System3.5 save files has some junk data at the stack bottom.
p -= frame_size;
frame = push_asdv1_stack_frame(frame_size, frame);
memcpy(frame->buf, p, frame_size);
}
stack_top = stack_buf;
for (struct asdv1_stack_frame *f = frame; f;) {
switch (f->buf[f->len - 1]) {
case STACK_FARCALL:
stack_reserve(2 + 4 + 1);
if (LittleEndian_getDW(f->buf, 0) != 0)
WARNING("unexpected stack structure");
stack_push_word(LittleEndian_getDW(f->buf, 4));
stack_push_dword(LittleEndian_getDW(f->buf, 8));
stack_push_byte(STACK_FARCALL);
break;
case STACK_NEARCALL:
stack_reserve(4 + 1);
stack_push_dword(LittleEndian_getDW(f->buf, 0));
stack_push_byte(STACK_NEARCALL);
break;
case STACK_VARIABLE:
{
int count = LittleEndian_getW(f->buf, f->len - 3);
int base = LittleEndian_getW(f->buf, f->len - 5);
stack_reserve((2 + 2 + 2 + 1) * count);
for (int i = 0; i < count; i++) {
stack_push_word(base + 1);
stack_push_word(0); // page
stack_push_word(LittleEndian_getW(f->buf, i * 2));
stack_push_byte(STACK_VARIABLE);
}
}
break;
}
struct asdv1_stack_frame *next = f->next;
free(f);
f = next;
}
}
static void load_stack_sys39(uint8_t *data, int size) {
if (size > stack_size) {
while (size > stack_size)
stack_size *= 2;
free(stack_buf);
stack_buf = malloc(stack_size);
if (!stack_buf)
NOMEMERR();
}
memcpy(stack_buf, data, size);
stack_top = stack_buf + size;
}
void sl_loadStack(enum save_format format, uint8_t *unaligned_data, int size) {
switch (format) {
case SAVEFMT_XSYS35:
load_stack_xsys35(unaligned_data, size);
break;
case SAVEFMT_SYS35:
load_stack_sys35(unaligned_data, size);
break;
default:
load_stack_sys39(unaligned_data, size);
break;
}
}
void sl_getStackInfo(struct stack_info *info) {
memset(info, 0, sizeof(struct stack_info));
+1 -4
View File
@@ -25,7 +25,6 @@
#include "config.h"
#include <sys/types.h>
#include <SDL_events.h>
#include <SDL_surface.h>
#include "portab.h"
#include "ags.h"
@@ -95,7 +94,6 @@ 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();
@@ -108,11 +106,10 @@ 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__ */
+9 -2
View File
@@ -207,7 +207,14 @@ 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 = palette_color(sp);
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);
}
SDL_SetColorKey(sdl_dib, SDL_TRUE, col);
SDL_Rect r_src = {sx, sy, w, h};
@@ -314,7 +321,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_CreateRGBSurfaceWithFormat(0, w, h, sdl_dib->format->BitsPerPixel, sdl_dib->format->format);
SDL_Surface *s = SDL_CreateRGBSurface(0, w, h, sdl_dib->format->BitsPerPixel, 0, 0, 0, 0);
assert(s->format->BitsPerPixel > 8);
SDL_Rect r_src = {0, 0, w, h};
+176 -365
View File
@@ -33,24 +33,18 @@
#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);
static uint32_t custom_event_type = (uint32_t)-1;
enum CustomEventCode {
SIMULATE_RIGHT_BUTTON,
DEBUGGER_COMMAND,
};
/* pointer の状態 */
static int mousex, mousey, mouseb;
static int mouse_wheel_up, mouse_wheel_down;
@@ -59,133 +53,6 @@ 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);
}
static int mouse_to_rawkey(int button) {
switch(button) {
case SDL_BUTTON_LEFT:
@@ -211,22 +78,20 @@ static int mouse_to_agsevent(int button) {
}
EMSCRIPTEN_KEEPALIVE
void send_agsevent(enum agsevent_type type, int code) {
void send_agsevent(int type, int code) {
if (!nact->ags.eventcb)
return;
agsevent_t agse = {
.type = type,
.code = code,
.mousex = mousex,
.mousey = mousey
};
agsevent_t agse;
agse.type = type;
agse.d1 = mousex;
agse.d2 = mousey;
agse.d3 = 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);
#ifdef __EMSCRIPTEN__
// HACK: this ensures that callers of this function are instrumented.
emscripten_sleep(0);
#endif
}
// Improves map navigation of Rance4 v2. See also the function comment of
@@ -241,205 +106,170 @@ 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;
sdl_handle_event(&e);
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;
} else {
// SDL_RendererEventWatch clamps touch locations outside of the
// viewport to 0.0-1.0. Treat such events as right-clicks.
if (e.tfinger.x == 0.0f || e.tfinger.x == 1.0f || e.tfinger.y == 0.0f || e.tfinger.y == 1.0f) {
mouseb |= 1 << SDL_BUTTON_RIGHT;
RawKeyInfo[mouse_to_rawkey(SDL_BUTTON_RIGHT)] = TRUE;
} else {
mouseb |= 1 << SDL_BUTTON_LEFT;
RawKeyInfo[mouse_to_rawkey(SDL_BUTTON_LEFT)] = TRUE;
}
mousex = e.tfinger.x * view_w;
mousey = e.tfinger.y * view_h;
}
break;
case SDL_FINGERUP:
if (SDL_GetNumTouchFingers(e.tfinger.touchId) == 0) {
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;
}
break;
case SDL_FINGERMOTION:
mousex = e.tfinger.x * view_w;
mousey = e.tfinger.y * view_h;
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:
NOTICE("ev %x", e.type);
break;
}
}
if (had_input) {
cmd_count_of_prev_input = nact->cmd_count;
@@ -448,6 +278,12 @@ static void sdl_getEvent(void) {
if (nact->game == GAME_RANCE4_V2)
rance4v2_hack();
}
if (m2b) {
menu_open();
}
if (msg_skip) msgskip_activate(!msgskip_isActivated());
}
/* キー情報の取得 */
@@ -468,7 +304,7 @@ int sdl_getKeyInfo() {
((RawKeyInfo[KEY_RIGHT] || RawKeyInfo[KEY_PAD_6]) << 3) |
(RawKeyInfo[KEY_RETURN] << 4) |
(RawKeyInfo[KEY_SPACE ] << 5) |
(RawKeyInfo[KEY_ESCAPE] << 6) |
(RawKeyInfo[KEY_ESC] << 6) |
(RawKeyInfo[KEY_TAB] << 7));
return rt;
@@ -504,28 +340,3 @@ int sdl_getJoyInfo(void) {
sdl_getEvent();
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) {
SDL_Event event = {
.user = {
.type = custom_event_type,
.code = SIMULATE_RIGHT_BUTTON,
.data1 = (void*)pressed
}
};
SDL_PushEvent(&event);
}
#endif
+78 -43
View File
@@ -34,6 +34,8 @@
#include "alpha_plane.h"
#include "image.h"
static unsigned char shlv_tbl[256*256];
/*
* dib内での拡大・縮小コピー
*/
@@ -45,7 +47,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_CreateRGBSurfaceWithFormat(0, dw, dh, dst->format->BitsPerPixel, dst->format->format);
ss = SDL_CreateRGBSurface(0, dw, dh, dst->format->BitsPerPixel, 0, 0, 0, 0);
if (dst->format->BitsPerPixel == 8) {
memcpy(ss->format->palette->colors, dst->format->palette->colors,
@@ -140,43 +142,40 @@ void sdl_drawImage16_fromData(cgdata *cg, int dx, int dy, int brightness, bool a
int w = cg->width;
int h = cg->height;
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;
}
}
SDL_Surface *s;
if (cg->alpha && alpha_blend) {
uint16_t *p_src = (uint16_t *)cg->pic;
unsigned short *p_src = (uint16_t *)cg->pic;
uint32_t *p_ds, *p_dst;
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);
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++);
p_ds = s->pixels;
l = s->pitch/4;
for (y = 0; y < h; y++) {
p_dst = p_ds;
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;
}
} 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)
@@ -204,31 +203,65 @@ 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
uint8_t *p_ds = s->pixels + 3;
p_ds = s->pixels + 3;
#else
uint8_t *p_ds = s->pixels;
p_ds = s->pixels;
#endif
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;
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;
}
adata += sdl_dibinfo->width;
p_ds += s->pitch;
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;
}
if (lv < 255)
SDL_SetSurfaceAlphaMod(s, lv);
SDL_Rect r_dst = {dx, dy, w, h};
SDL_BlitSurface(s, &r_tmp, sdl_dib, &r_dst);
@@ -301,7 +334,9 @@ 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_CreateRGBSurfaceWithFormat(0, w, h, sdl_dib->format->BitsPerPixel, sdl_dib->format->format);
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);
if (sdl_dib->format->BitsPerPixel == 8)
memcpy(s->format->palette->colors, sdl_dib->format->palette->colors,
sizeof(SDL_Color) * sdl_dib->format->palette->ncolors);
+73
View File
@@ -0,0 +1,73 @@
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 */, };
+1 -1
View File
@@ -52,8 +52,8 @@ struct sdl_private_data {
boolean (*custom_event_handler)(const SDL_Event *);
};
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);
+7 -18
View File
@@ -81,11 +81,13 @@ int sdl_Initialize(const char *render_driver) {
/* offscreen Pixmap */
makeDIB(SYS35_DEFAULT_WIDTH, SYS35_DEFAULT_HEIGHT, SYS35_DEFAULT_DEPTH);
sdl_event_init();
/* init cursor */
sdl_cursor_init();
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);
@@ -160,25 +162,12 @@ static void makeDIB(int width, int height, int depth) {
if (sdl_dib) {
SDL_FreeSurface(sdl_dib);
}
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.
// Graphic routines in modules/ assume 4 bytes/pixel mode for 24-bit surfaces.
if (depth == 24)
depth = 32;
break;
default:
SYSERROR("invalid pixel depth %d", depth);
}
sdl_dib = SDL_CreateRGBSurfaceWithFormat(0, width, height, depth, format);
sdl_dib = SDL_CreateRGBSurface(0, width, height, depth, 0, 0, 0, 0);
if (sdl_dib->format->BitsPerPixel == 8) {
memset(sdl_dib->format->palette->colors, 0, sizeof(SDL_Color)*256);
+13 -11
View File
@@ -309,26 +309,28 @@ 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) {
int y = r.y + (sel.MsgFontSize +2) * MOUSE_INIT_Y_RATIO/100;
ags_setCursorLocation(x, y, true, true);
ags_setCursorLocation(r.x + r.w * MOUSE_INIT_X_RATIO/100,
r.y + (sel.MsgFontSize +2) * MOUSE_INIT_Y_RATIO/100,
TRUE);
} else if (p.y > (r.y + r.h)) {
int y = r.y + (sel.MsgFontSize +2) * regnum * MOUSE_INIT_Y_RATIO/100;
ags_setCursorLocation(x, y, true, true);
ags_setCursorLocation(r.x + r.w * MOUSE_INIT_X_RATIO/100,
r.y + (sel.MsgFontSize +2) * regnum * MOUSE_INIT_Y_RATIO/100,
TRUE);
} else {
int y = p.y * MOUSE_INIT_Y_RATIO/100;
ags_setCursorLocation(x, y, true, true);
ags_setCursorLocation(r.x + r.w * MOUSE_INIT_X_RATIO/100,
p.y * MOUSE_INIT_Y_RATIO/100,
TRUE);
}
} else if (default_element < regnum) {
int y = r.y + (sel.MsgFontSize +2) * default_element * MOUSE_INIT_Y_RATIO/100;
ags_setCursorLocation(x, y, true, true);
ags_setCursorLocation(r.x + r.w * MOUSE_INIT_X_RATIO/100,
r.y + (sel.MsgFontSize +2) * default_element * MOUSE_INIT_Y_RATIO/100, TRUE);
} else if (default_element < 1000) {
int y = r.y + (sel.MsgFontSize +2) * regnum * MOUSE_INIT_Y_RATIO/100;
ags_setCursorLocation(x, y, true, true);
ags_setCursorLocation(r.x + r.w * MOUSE_INIT_X_RATIO/100,
r.y + (sel.MsgFontSize +2) * regnum * MOUSE_INIT_Y_RATIO/100, TRUE);
}
}
+2 -2
View File
@@ -71,10 +71,10 @@ static void toggle_mouse_warp_mode(void) {
return;
if (menuitem.fState & MFS_CHECKED) {
nact->ags.mouse_warp_enabled = false;
nact->ags.mouse_movesw = MOUSE_WARP_DISABLED;
CheckMenuItem(hmenu, ID_OPTION_MOUSE_MOVE, MF_BYCOMMAND | MFS_UNCHECKED);
} else {
nact->ags.mouse_warp_enabled = true;
nact->ags.mouse_movesw = MOUSE_WARP_SMOOTH;
CheckMenuItem(hmenu, ID_OPTION_MOUSE_MOVE, MF_BYCOMMAND | MFS_CHECKED);
}
}
+1 -1
View File
@@ -111,7 +111,7 @@ static void sys35_usage(boolean verbose) {
puts("OPTIONS");
puts(" -gamefile file : set game resource file to 'file'");
puts(" -game game : enable game-specific hacks");
puts(" -saveformat fmt : save file format. 'xsystem35', 'system36' or 'system39' (default)");
puts(" -saveformat fmt : save file format. 'xsystem35' (default), 'system36' or 'system39'");
puts(" -renderer name : set rendering driver name to 'name'");
puts(" -devcd device : set cdrom device name to 'device'");
puts(" -devmidi device : set midi device name to 'device'");
+3 -3
View File
@@ -1,6 +1,6 @@
#!/bin/sh
# To use this script in MSYS2 shell, install mingw-w64-ucrt-x86_64-nsis and
# mingw-w64-ucrt-x86_64-ntldd packages.
# To use this script in MSYS2 shell, install mingw-w64-x86_64-nsis and
# mingw-w64-x86_64-ntldd-git packages.
if [ $# -ne 2 ]; then
echo 'Usage: make-installer.sh <build-dir> <nsi>'
@@ -11,7 +11,7 @@ builddir=$1
nsi=$2
echo 'dlls.nsi:'
ntldd -R $builddir/src/xsystem35.exe |perl -ne 'print "File \"$1\"\n" if /=> (.*) \(/' |grep 'mingw32\|ucrt64' |tee $builddir/dlls.nsi
ntldd -R $builddir/src/xsystem35.exe |perl -ne 'print "File \"$1\"\n" if /=> (.*) \(/' |grep mingw |tee $builddir/dlls.nsi
echo
echo 'dlls-uninstall.nsi:'
+50
View File
@@ -0,0 +1,50 @@
#! /usr/bin/perl
@key_list=();
%keyh_list=();
open(FX,"<key.h") || exit;
while(<FX>) {
if( /^#define KEY_([^\s]*)\s+[(]([^)]*)[)]/ ) {
$key_list[eval($2)]="$1";
$keyh_list{$1}=eval($2);
}
}
close(fp);
@sdlk_list=();
open(FS,"<$ARGV[0]/SDL_scancode.h") || exit;
while(<FS>) {
if( /SDL_SCANCODE_([^\s]+)\s+=\s*([^,]*),/ ) {
$sdlk_list[eval($2)]="$1";
}
}
close(FS);
print "static int sdl_keytable[SDL_NUM_SCANCODES] = {\n\t";
for( $i = 0 ; $i < scalar(@sdlk_list) ; $i ++ ) {
#print "$i @sdlk_list[$i] $keyh_list{@sdlk_list[$i]}\n";
$x = @sdlk_list[$i];
if( length($x) == 0 ) {
print "KEY_UNDEFINED, ";
} elsif ( $keyh_list{$x} ) {
print "KEY_@key_list[$keyh_list{$x}], ";
} elsif ( $x =~ /[a-z]/ ) {
print "KEY_".uc($x).", ";
} elsif ( $x =~ /KP_/ ) {
$x =~ s/^KP_/PAD_/;
if ( $keyh_list{$x} ) {
print "KEY_$x, ";
} else {
print "0 /* SDL_$x */, ";
}
} elsif ( $i < 0x61) {
print "$i, ";
} else {
print "0 /* SDL_$x */, ";
}
if(($i % 4) == 3 ) {
print "\n\t";
}
}
print "};\n";