Compare commits

..
56 Commits
Author SHA1 Message Date
kichikuou 64edcfda29 Support loading system3.5 v1 save files 2023-03-18 09:51:58 +09:00
kichikuou 912af592ae Clean up savedata.c 2023-03-18 09:51:57 +09:00
kichikuou 6d70439dff Change how save file names are determined when no .gr file is specified
If `?sleep.asd` already exist, use them. Otherwise use `*s?.asd` as in
System3x.exe.
2023-03-18 09:51:51 +09:00
kichikuou aec06f775a Support the save format of original System3.x (except System3.5 v1)
Now xsystem35 can load ASD files created by System3.5 (v2+) - System3.9.
The format for saving can be configured with the -saveformat option.
2023-02-23 19:03:23 +09:00
kichikuou 446ffe9466 UG command: Fix order of popping variables 2023-02-22 17:35:45 +09:00
kichikuou 02cad74568 Allow resizing system page by DC command 2023-02-20 17:39:21 +09:00
kichikuou 33e1ff3b4a Increase system variable page size to 65537
To match System3.x.
2023-02-20 17:05:54 +09:00
kichikuou 11f8f00072 Match default message/selection window locations to System3.x 2023-02-20 16:32:32 +09:00
kichikuou b59d683fef Change the stack layout
Now we use the same stack structure as System3.9. In order to maintain
the compatibility of save files, it is converted to/from the old layout
when saving/loading.
2023-02-20 14:24:37 +09:00
kichikuou b9f4c7c03a Compatibility fix for Bx commands
These commands accept 0-127 as valid window numbers, which were 1-128
before this change.

To maintain savedata compatibility, window positions are saved in the
order 1,...,127,0.
2023-02-18 21:45:39 +09:00
kichikuou 2d2c6aa373 Remove strvar_len
The length limit of string variables was removed a long time ago, but it
was recorded in save files.

Now the first argument of MZ0 is completely ignored (as in System3.9).
The maxlen field in the save file is set to a constant so that older
versions of xsystem35 can load it.
2023-02-18 14:55:02 +09:00
kichikuou 850af6d140 Refactor implementation of LE and QE commands 2023-02-18 14:47:28 +09:00
kichikuou da4cf017bf Clean up savedata.h 2023-02-18 14:47:25 +09:00
kichikuou e88dfcdaa1 Move load_cg_with_file to cg.c 2023-02-18 09:27:21 +09:00
kichikuou 70a940b216 Version 2.8.0 2023-02-12 09:33:29 +09:00
kichikuou db2bb03fdd Add -help description for -game option 2023-02-12 09:12:09 +09:00
kichikuou 5ef949ae14 Refactor ags_setWindowTitle() 2023-02-11 21:40:14 +09:00
kichikuou 043028cf7d Update game_compatibility.md 2023-02-11 16:18:09 +09:00
kichikuou eace5d1dbd Refactor game-specific hacks, add -game option
It's now possible to enable certain game-specific hacks by using the
`-game` command line option or the `game` property in the .xsys35rc
file.
2023-02-11 15:27:38 +09:00
kichikuou 878bea69d6 Add a test for stack commands 2023-02-10 21:30:02 +09:00
kichikuou ae8becc4a3 Fix menuReturnGoto when stack top is not a return address 2023-02-10 21:24:13 +09:00
kichikuou 1d863cfb2e Implement UR command 2023-02-10 20:56:53 +09:00
kichikuou 7bb2bee693 Label return should pop TPx 2023-02-10 20:56:53 +09:00
kichikuou 47e7f5542e Remove sl_retFar2
In System39.exe `%0` drops stack frames for label calls (Rance4 v2
relies on this behavior), so it's the same as `UD 1`.
2023-02-10 20:56:53 +09:00
kichikuou 8087d11b2b Fix UC command
* UC0 should restore values pushed by US/TPx
* UC1 should stop when the stack top is a page call
* UC1/2 should restore status pushes by TPx
* UC1/2 should not consume the count for non-call stack frames
* Add support for UC3 command
2023-02-10 20:56:53 +09:00
kichikuou 4f1521ac90 TOx commands are no-op if the stack top is of an unexpected type 2023-02-10 20:56:53 +09:00
kichikuou 99632397da Enable the hack in Rance4v2 recompiled with System3.9
The System3.9 compiler compiles `MT` command to `0x2F28`, so the hack
must be enabled in commands2F28().

Fixes https://github.com/kichikuou/xsystem35-sdl2/issues/36.
2023-02-10 20:50:12 +09:00
kichikuou 59283815d8 Properly implement Y 1900 command
It is the same as patchEC, but can be used in SCO files less than
version 390.
2023-02-08 10:43:06 +09:00
kichikuou a32c901eb8 Tweak the Rance4v2 hack
This fixes https://github.com/kichikuou/xsystem35-sdl2/issues/35.
2023-02-08 10:15:06 +09:00
kichikuou 03b84b8ba7 Make UR command safer
It's still unimplemented, but clears the output variables for safety.
2023-02-07 22:12:35 +09:00
kichikuou 720da4e42c Fix UC1 command 2023-02-07 22:05:00 +09:00
kichikuou c4dc799c94 Change the condition for applying Rance4v2 hack
Now it's determined by the MT command argument.
2023-02-07 21:31:03 +09:00
kichikuou ce271ae5eb Fix CG positioning issue in Rance 4.x (TOTO port)
G command should reset the effect of J0/J1, even if pixel extraction is
disabled by PC command.
2023-02-05 18:37:50 +09:00
kichikuou 526e5f8709 Fix VSP palette issue
This fixes a palette problem when drawing a VSP image on a non-8-bit
surface after executing `ZC 0` command.

cg->vsp_bank can be overridden by the `ZC 0` command.
2023-02-05 18:08:41 +09:00
kichikuou c967e63be9 Version 2.7.0 2023-01-28 16:22:24 +09:00
kichikuou d4a32aee17 Update game_compatibility.md 2023-01-28 16:13:25 +09:00
kichikuou 1191723612 Update emscripten to 3.1.27 2023-01-28 14:30:45 +09:00
kichikuou addf2e3728 Add BGM support for Rance4 v2
In Rance4 v2, `SS n` command plays the audio file n+999 stored in
WB.ald. Support this by reusing the CD->BGM bridge.
2023-01-28 14:24:26 +09:00
kichikuou 4785c8c77c Add cdrom.bgm.c and use it when DRIFILE_BGM exists
This enables BGM playback in the download edition of Daiakuji, where S*
commands are plumbed to the music system (*BA.ald).
2023-01-28 13:06:38 +09:00
kichikuou b1ac106057 Refactor bgm abstructions 2023-01-28 12:51:38 +09:00
kichikuou acdc40ec60 Refactor cdrom abstructions 2023-01-28 12:51:34 +09:00
kichikuou d9f635a6d0 Implement SV command 2023-01-28 09:53:44 +09:00
kichikuou e8357c4e6f Add a hack to improve map navigation of Rance4 v2 2023-01-28 09:53:41 +09:00
kichikuou 8e44a87069 Support Y1003 command
Used in Rance4 ver2.05. Similar to Y3, but waits for key release.
2023-01-26 21:44:29 +09:00
kichikuou d1befbd355 Add stub for SV command
Used in Rance4 ver2.05.
2023-01-26 18:35:55 +09:00
kichikuou ec0bae5490 Inline LittleEndian functions
Using memcpy(). Compilers are smart enough to eliminate memcpy()
completely.
2023-01-21 17:22:24 +09:00
kichikuou f5b3b1a936 Support ShSound module on WASM 2023-01-21 16:40:26 +09:00
kichikuou 1b546e3bab Update README.md 2023-01-15 13:52:00 +09:00
kichikuou d454899048 Add game compatibility table 2023-01-15 13:39:07 +09:00
kichikuou 7aa704b3f4 midi_sdlmixer: Check playing status in midi_get_playing_info()
This fixes an infinite loop in Buroburo waiting for MIDI playback to
finish.
2023-01-15 13:07:51 +09:00
kichikuou 50d7d7ee33 Fix handling of multi-volume ALD with inconsistent indexes
When contents of the index table differ between ALD files, System3.x
uses information from the file containing the entry.

For example, if link_table[k] in SA.ALD is { file_nr = 2, ptr_no = 10 }
and link_table[k] in SB.ALD is { file_nr = 2, ptr_no = 11 }, the entry
body is in SB.ALD, so ptr_no = 11 should be used.

CA_G*.ALD of Child Assassin has this issue.
2023-01-15 12:42:38 +09:00
kichikuou 586a9c855e Implement LXX 5 command
Used in Child Assassin.
2023-01-14 16:13:57 +09:00
kichikuou 9600e34229 Android: Upgrade AGP to 7.3.1 2023-01-08 13:35:51 +09:00
kichikuou 001c97ea00 Android: Include git revision in version string 2023-01-08 13:20:23 +09:00
kichikuou b100dbe26c Android CI: Generate signed apk 2023-01-08 13:19:01 +09:00
kichikuou 55e38f9db2 Android: Add activities to display open source notices 2023-01-06 14:21:32 +09:00
96 changed files with 2629 additions and 2154 deletions
+7 -2
View File
@@ -14,10 +14,15 @@ jobs:
- name: Build
run: |
cd android
echo "${{ secrets.KEYSTORE_BASE64 }}" | base64 -d > keystore.jks
ANDROID_NDK_HOME=$ANDROID_SDK_ROOT/ndk-bundle ./gradlew assembleRelease
env:
KEY_ALIAS: ${{ secrets.KEY_ALIAS }}
KEY_PASSWORD: ${{ secrets.KEY_PASSWORD }}
KEYSTORE_PASSWORD: ${{ secrets.KEYSTORE_PASSWORD }}
- name: Upload artifacts
uses: actions/upload-artifact@v3
with:
name: xsystem35-release-unsigned-apk
path: android/app/build/outputs/apk/release/app-release-unsigned.apk
name: xsystem35-apk
path: android/app/build/outputs/apk/release/app-release.apk
+2 -2
View File
@@ -2,7 +2,7 @@ name: Emscripten Build
on: [push, pull_request]
env:
EM_VERSION: 3.1.15
EM_VERSION: 3.1.27
EM_CACHE_FOLDER: 'emsdk-cache'
jobs:
@@ -20,7 +20,7 @@ jobs:
key: ${{env.EM_VERSION}}-${{ runner.os }}
- name: Setup Emscripten toolchain
uses: mymindstorm/setup-emsdk@v11
uses: mymindstorm/setup-emsdk@v12
with:
version: ${{ env.EM_VERSION }}
actions-cache-folder: ${{env.EM_CACHE_FOLDER}}
+2
View File
@@ -2,7 +2,9 @@ out
android/.gradle
android/app/.externalNativeBuild
android/app/build
android/app/src/main/assets
android/build
android/keystore.jks
.ccls-cache
.dir-locals.el
compile_commands.json
+1
View File
@@ -110,6 +110,7 @@ endif()
# CDROM
list(APPEND SRC_CDROM cdrom.bgm.c)
if (CMAKE_SYSTEM_NAME STREQUAL "Linux")
list(APPEND SRC_CDROM cdrom.Linux.c)
list(APPEND SUMMARY_CDROM "Linux ioctl")
+5
View File
@@ -3,6 +3,11 @@
This is a multi-platform port of `xsystem35`, a free implementation of
AliceSoft's System 3.x game engine.
## Compatiblity
See the [game compatibility table](game_compatibility.md) for a list of games
that can be played on xsystem35-sdl2.
## Unique Features
In addition to the original System 3.x's functionalities, xsystem35-sdl2 has
+15 -3
View File
@@ -16,8 +16,8 @@ android {
}
minSdkVersion 19
targetSdkVersion 31
versionCode 11
versionName "2.6.0"
versionCode 13
versionName "2.8.0" + gitRevision()
externalNativeBuild {
cmake {
arguments "-DANDROID_APP_PLATFORM=android-16", "-DANDROID_STL=c++_static"
@@ -26,10 +26,19 @@ android {
}
}
}
signingConfigs {
release {
storeFile rootProject.file('keystore.jks')
storePassword System.getenv('KEYSTORE_PASSWORD')
keyAlias System.getenv('KEY_ALIAS')
keyPassword System.getenv('KEY_PASSWORD')
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.release
}
}
applicationVariants.all { variant ->
@@ -39,7 +48,6 @@ android {
if (!project.hasProperty('EXCLUDE_NATIVE_LIBS')) {
sourceSets.main {
jniLibs.srcDir 'libs'
assets.srcDir '../../fonts'
}
aaptOptions {
// Disable asset compression for fonts.
@@ -75,3 +83,7 @@ dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
}
static String gitRevision() {
' (git ' + "git rev-parse --short HEAD".execute().text.trim() + ')'
}
+16 -1
View File
@@ -1,6 +1,7 @@
cmake_minimum_required(VERSION 3.13)
project(GAME)
set(PROJECT_ROOT_DIR ../../..)
include(FetchContent)
FetchContent_Declare(
@@ -46,4 +47,18 @@ if(NOT sdl_mixer_POPULATED)
endif()
# The main CMakeLists.txt of xsystem35
add_subdirectory(../../.. xsystem35)
add_subdirectory(${PROJECT_ROOT_DIR} xsystem35)
# Copy asset files
set(ASSETS_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../src/main/assets)
file(MAKE_DIRECTORY ${ASSETS_DIR}/licenses)
file(COPY_FILE ${PROJECT_ROOT_DIR}/fonts/MTLc3m.ttf ${ASSETS_DIR}/MTLc3m.ttf)
file(COPY_FILE ${PROJECT_ROOT_DIR}/fonts/mincho.otf ${ASSETS_DIR}/mincho.otf)
file(COPY_FILE ${PROJECT_ROOT_DIR}/COPYING ${ASSETS_DIR}/licenses/xsystem35)
file(COPY_FILE ${PROJECT_ROOT_DIR}/fonts/MTLc3m.ttf.license ${ASSETS_DIR}/licenses/MTLc3m)
file(COPY_FILE ${PROJECT_ROOT_DIR}/fonts/mincho.otf.license ${ASSETS_DIR}/licenses/mincho)
file(COPY_FILE ${sdl_SOURCE_DIR}/LICENSE.txt ${ASSETS_DIR}/licenses/SDL)
file(COPY_FILE ${sdl_ttf_SOURCE_DIR}/LICENSE.txt ${ASSETS_DIR}/licenses/SDL_ttf)
file(COPY_FILE ${sdl_ttf_SOURCE_DIR}/external/freetype/docs/GPLv2.TXT ${ASSETS_DIR}/licenses/freetype)
file(COPY_FILE ${sdl_ttf_SOURCE_DIR}/external/harfbuzz/COPYING ${ASSETS_DIR}/licenses/harfbuzz)
file(COPY_FILE ${sdl_mixer_SOURCE_DIR}/LICENSE.txt ${ASSETS_DIR}/licenses/SDL_mixer)
+11
View File
@@ -94,6 +94,17 @@
</intent-filter>
-->
</activity>
<activity android:name=".LicensesMenuActivity"
android:label="@string/action_licenses"
android:parentActivityName=".LauncherActivity"
android:exported="false">
</activity>
<activity android:name=".LicensesActivity"
android:parentActivityName=".LicensesMenuActivity"
android:exported="false">
</activity>
</application>
</manifest>
@@ -106,6 +106,11 @@ class LauncherActivity : Activity(), LauncherObserver {
SAVEDATA_IMPORT_REQUEST)
true
}
R.id.licenses -> {
val intent = Intent(this, LicensesMenuActivity::class.java)
startActivity(intent)
true
}
else -> super.onOptionsItemSelected(item)
}
}
@@ -0,0 +1,23 @@
package io.github.kichikuou.xsystem35
import android.app.Activity
import android.os.Bundle
import android.widget.TextView
import java.io.BufferedReader
class LicensesActivity : Activity() {
companion object {
const val EXTRA_DISPLAY_NAME = "DISPLAY_NAME"
const val EXTRA_FILE_NAME = "FILE_NAME"
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_licenses)
actionBar?.title = intent.getStringExtra(EXTRA_DISPLAY_NAME)
val path = "licenses/" + intent.getStringExtra(EXTRA_FILE_NAME)
val text = assets.open(path).bufferedReader().use(BufferedReader::readText)
findViewById<TextView>(R.id.license_text).text = text
}
}
@@ -0,0 +1,38 @@
package io.github.kichikuou.xsystem35
import android.app.Activity
import android.content.Intent
import android.os.Bundle
import android.widget.ListView
import android.widget.SimpleAdapter
class LicensesMenuActivity : Activity() {
class Entry(val displayName: String, val fileName: String, val url: String)
private val entries: ArrayList<Entry> = arrayListOf(
Entry("xsystem35-sdl2", "xsystem35", "https://github.com/kichikuou/xsystem35-sdl2"),
Entry("SDL", "SDL", "https://www.libsdl.org/"),
Entry("SDL_mixer", "SDL_mixer", "https://github.com/libsdl-org/SDL_mixer"),
Entry("SDL_ttf", "SDL_ttf", "https://github.com/libsdl-org/SDL_ttf"),
Entry("FreeType", "freetype", "https://freetype.org/"),
Entry("HarfBuzz", "harfbuzz", "https://harfbuzz.github.io/"),
Entry("MotoyaLCedar W3 mono", "MTLc3m", "https://github.com/aosp-mirror/platform_frameworks_base/tree/lollipop-release/data/fonts"),
Entry("Source Han Serif", "mincho", "https://github.com/adobe-fonts/source-han-serif/"),
)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_licenses_menu)
val items = entries.map { mapOf("name" to it.displayName, "url" to it.url)}
val listView = findViewById<ListView>(R.id.list)
listView.adapter = SimpleAdapter(this, items, android.R.layout.simple_list_item_2,
arrayOf("name", "url"), intArrayOf(android.R.id.text1, android.R.id.text2))
listView.setOnItemClickListener { _, _, pos, _ ->
val intent = Intent(this, LicensesActivity::class.java).apply {
putExtra(LicensesActivity.EXTRA_DISPLAY_NAME, entries[pos].displayName)
putExtra(LicensesActivity.EXTRA_FILE_NAME, entries[pos].fileName)
}
startActivity(intent)
}
}
}
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView android:id="@+id/license_text"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:padding="20dp" />
</ScrollView>
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<ListView android:id="@+id/list"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</LinearLayout>
@@ -6,4 +6,7 @@
<item
android:id="@+id/import_savedata"
android:title="@string/action_import_save_data" />
<item
android:id="@+id/licenses"
android:title="@string/action_licenses" />
</menu>
@@ -3,6 +3,7 @@
<string name="app_name">xsystem35</string>
<string name="action_export_save_data">セーブデータをエクスポート</string>
<string name="action_import_save_data">セーブデータをインポート</string>
<string name="action_licenses">オープンソースライセンス</string>
<string name="cancel">キャンセル</string>
<string name="cannot_find_ald">System 3.x のファイル (*.ald) が見つかりません。</string>
<string name="choose_a_file">ファイルを選択</string>
@@ -2,6 +2,7 @@
<string name="app_name">xsystem35</string>
<string name="action_export_save_data">Export Save Files</string>
<string name="action_import_save_data">Import Save Files</string>
<string name="action_licenses">Open source licenses</string>
<string name="cancel">Cancel</string>
<string name="cannot_find_ald">Cannot find System 3.x game files (*.ald).</string>
<string name="choose_a_file">Choose a file</string>
+1 -2
View File
@@ -7,8 +7,7 @@ buildscript {
google()
}
dependencies {
// AGP 7.1.x cannot be used due to https://issuetracker.google.com/issues/206099937
classpath 'com.android.tools.build:gradle:7.0.4'
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-7.3-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-bin.zip
distributionPath=wrapper/dists
zipStorePath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
+1 -1
View File
@@ -1,5 +1,5 @@
#cmakedefine PACKAGE "@PACKAGE@"
#define VERSION "2.6.0"
#define VERSION "2.8.0"
#cmakedefine CMAKE_SYSTEM_NAME "@CMAKE_SYSTEM_NAME@"
-189
View File
@@ -1,189 +0,0 @@
それぞれのゲームに付いての注意書き
[鬼畜王ランス]
[ランス4(for Win95)]
[闘神都市2(for Win95)]
[いけないかつみ先生]
= 外字データには対応していません
[かえるにょぱにょ〜ん]
= フロアデータ(floor_1.map 〜 floor_16.map) はセーブデータと同じディレク
トリに置いてください。
= 一部のキャラの絵と説明が違う(金魚と????)
[戦巫女]
= 戦巫女は2枚組のCDで、Windows版では一部のデータをCD-ROMに置いたままゲーム
することになっていますが、xsystem35 では CD-Audio と CD-ROM上のデータを
同時に使用することは出来ません。ハードディスク等に全てのデータをインス
トールするか、あるいは CD-Audio 以外の演奏方法(MP3等)を使用してください。
CD-Audio を使う場合は2枚目の CD に音楽データが入っています。
[零式(アリスの館456版)]
= マップデータ(MAP_DATA.DAT, UR_DATA.DATA)はセーブデータと同じディレクトリに
置いてください。
[ATLACH=NACHA(アリスの館456版)]
[人間狩り(アリスの館456版)]
[アリスの館456]
- DALK
- 闘神都市
- DrStop!
- ランス1
- ランス2
- ランス3
[王道勇者]
[ディアボリカ]
[AmbivalenZ(for Win95)]
[夢幻泡影 (for Win95)]
[ぱすてるチャイム]
= ぱすてるチャイムでは明らかにシナリオにおかしいところがあります。
そこで、これに対するパッチを作成しました。
patch というディレクトリの下に pastel.diff というパッチ当てのスクリプト
がありますので、ゲームのシナリオデータのあるディレクトリにコピーして
そのディレクトリに移動した後、 ./pastel.diff (シナリオファイル名) と
実行してください。
(例)
> ./pastel.diff pastel_sa.ald
古いデータは pastel_sa.ald.org として保存されます。
シナリオデータは Ver 1.00 と Ver 1.01 に適用できます。
(廉価版では直っている?)
[ぷろすちゅーでんとGood]
[守り神様]
[ママトト]
[HushByBaby]
[Darcrows]
[PERSIOM]
= DirectSound(3D Sound) には対応していません。
[隠れ月]
[SeeIn青]
[廉価版・デアボリカ]
[廉価版・アトラクナクア]
[廉価版・かえるにょ・ぱにょん]
[廉価版・零式]
[かえるにょ国にょありす(20世紀アリス)]
= 外部MIDIプレイヤーモードでは音楽がリピートされません。
[これDPS?(20世紀アリス)]
[夜が来る!]
= 動きません
[王子さま Lv1]
[Only You 〜リ・クルス〜]
[大悪司]
= オープニングが動かない
[王子さま Lv1.5]
[妻みぐい]
= オープニングが動かない
[エスカレイヤー]
= オープニングが動かない
[Rance5D]
[妻みぐい2]
= オープニングが動かない
[DALK外伝]
[ままにょにょ]
= System4につき動きません
/*
* その他
*/
* センチメンタルシーズン (Aliceの館 CDをベースに UNITBASE が移植したもの)
= http://www4.big.or.jp/~unitbase/sys35sdk/games.html
* Intruder (Aliceの館 CDをベースに UNITBASE が移植したもの)
= まだ完了していません
* Crecent Moon がぁる (Aliceの館 CDをベースに UNITBASE が移植したもの)
= http://www4.big.or.jp/~unitbase/sys35sdk/games.html
* あぶない天狗伝説 (Aliceの館 CD2をベースに UNITBASE が移植したもの)
= 掲載許可が下りません
* OnlyYou (system3版をベースに TOTOさんが移植したもの)
= http://www1.interq.or.jp/t-takeda/index.html
* ランス4.1 (system3版をベースに TOTOさんが移植したもの)
= http://www1.interq.or.jp/t-takeda/index.html
= スプライトの色がおかしい
* ランス4.2 (system3版をベースに TOTOさんが移植したもの
= http://www1.interq.or.jp/t-takeda/index.html
= スプライトの色がおかしい
* アリスの館3 (system3版をベースに TOTOさんが移植したもの)
= http://www1.interq.or.jp/t-takeda/index.html
* 乙女戦記 (system3版をベースに TOTOさんが移植したもの)
= http://www1.interq.or.jp/t-takeda/index.html
* 闘神都市2外伝 (system3版をベースに TOTOさんが移植したもの)
= http://www1.interq.or.jp/t-takeda/index.html
* DPS全部 (system3版をベースに TOTOさんが移植したもの)
= http://www1.interq.or.jp/t-takeda/index.html
* ProStudentG (system3版をベースに TOTOさんが移植したもの)
= http://www1.interq.or.jp/t-takeda/index.html
* 学園KING (AliceCD Ver 1.??)
= CDが鳴らない
-> TOTOさんが、CD-DAに対応するためのシナリオパッチをつくっています。
http://www1.interq.or.jp/t-takeda/midi.html
* メイドのススメ (AliceCD Ver 1.02)
* ぶろぶろ (AliceCD Ver 1.02)
* 学園漂流戦記 (AliceCD Ver 1.02)
* 扉 (AliceCD Ver 2.02)
* 妖精 (AliceCD Ver 2.02)
/*
* 3rd party 製作 ゲーム
*/
#include "MISCGAME.TXT"
-58
View File
@@ -1,58 +0,0 @@
その他の SYSTEM 3.5 のゲームについて
README にある動作確認ゲーム以外にも、ネット上で公開されているSYSTEM3.5対応
のゲームのうち幾つかは動く事が確認されています。ここでは 1.4.0 preX での動作
状況です。1.4.0 公開時点で手に入るゲームを順次追加していっています。
また、XXXが動かないんだけど調べてください、XXXはちゃんと動きました、といった
情報もおよせください。
OKは問題なく動く。GOODが多少の問題あるもののゲームをやるぶんで気にはなるけど
耐えられる範囲のもの。BADは動かないものです。
(作者の敬称略)
【 ソフト名 】 【 ファイル名 】【 作者名 】【 動作 】
国立ファーブル図
書館司書〜
ブックルちゃん〜 SSYO_100.LZH 大塚ヒロ OK
バルーンぽっぷ BPOP_093.LZH 大塚ヒロ OK
Self self.lzh よこやまなおき OK
おせろっと othellotto.exe よこやまなおき OK
キャロル carol.lzh よこやまなおき GOOD(1)
積層四目並べ Te1.lzh 深叢 忍 OK
16Piece Puzzle 16p1.lzh 深叢 忍 OK
The Line Line0.lzh 深叢 忍 OK
Black Jack bj120.lzh かずき OK
マスカレイド (in AliceCD202) ちあぼう OK
戦娘ver2.12 ikusa212.lzh ちあぼう OK
できるかなー! (in AliceCD202) KIMM SOFT OK(2)
恋は計算どおり♪ koi.lzh SS OK
動体視力を鍛えるにょ game_191.lzh LazyRichField BAD(3)
集中力を鍛えるにょ game_22.lh LazyRichField GOOD(4)
1) 雪が降らない (grDrawFillCircle が未実装)
通信対戦が出来ない
2) メッセージサイズ300ドットの表示は 100 ドットに制限しています
3) DS 数字 となっている
4) 色がおかしい
最後にこれらのデータを公開している作者の方々のURLです。
大塚ヒロさん http://www.studioHIRO.com/
よこやまなおきさん http://www3.justnet.ne.jp/~naoki-yokoyama/
深叢 忍さん http://www2s.biglobe.ne.jp/~nin/
かずきさん http://www.din.or.jp/~kazuki/
桐ヶ屋 inc.(ちあぼう)さん http://www.eucaly.net/~kiri
KIMM SOFT/ネリワサヴィちーむ heavyd@syd.odn.ne.jp
SSさん http://www.sspzgr.net/
LazyRichFieldさん http://www2j.biglobe.ne.jp/~Lazy/staff/alice.htm
+83
View File
@@ -0,0 +1,83 @@
Game Compatibility
==================
| Game | Status | Notes |
| ------------------------------------------- | ----------- | ----- |
| 鬼畜王ランス | Supported | |
| Kichikuou Rance (EN) | Supported | |
| RanceIV -教団の遺産- | Supported | Win95 edition, [Ver2.05](https://hannylaboratory.blogspot.com/2023/01/blog-post_26.html) |
| Rance4 -Legacy of the Sect- (EN) | Supported | |
| 兰斯IV -教团的遗产- (CN) | Supported | |
| ランス4.1 | Supported | [Ver1.05](https://hannylaboratory.blogspot.com/2023/02/blog-post_9.html) |
| ランス4.2 | Supported | [Ver1.05](https://hannylaboratory.blogspot.com/2023/02/blog-post_9.html) |
| いけないかつみ先生 | Supported | Emojis are not supported |
| 闘神都市II | Supported | Win95 edition |
| かえるにょ・ぱにょ~ん | Supported | Normal / Low-priced edition |
| 戦巫女 | Supported | Normal / Low-priced edition |
| 零式 | Supported | From ALICEの館4・5・6 / Low-priced edition |
| アトラク=ナクア | Supported | From ALICEの館4・5・6 / Low-priced edition |
| Rance -光を求めて- | Supported | From ALICEの館4・5・6 |
| Rance II -反逆の少女達- | Supported | From ALICEの館4・5・6 |
| Rance III -リーザス陥落- | Supported | From ALICEの館4・5・6 |
| DALK | Supported | From ALICEの館4・5・6 |
| 闘神都市 | Supported | From ALICEの館4・5・6 |
| Dr.STOP | Supported | From ALICEの館4・5・6 |
| 人間狩り | Unsupported | From ALICEの館4・5・6 / アリスCD |
| 女の子図鑑 | Unknown | From ALICEの館4・5・6 |
| 恋のおわり | Unknown | |
| 王道勇者 | Supported | |
| AmbivalenZ | Supported | Win95 edition |
| DiaboLiQuE | Supported | Normal / Low-priced edition |
| 夢幻泡影 | Unknown | Win98 edition |
| ぱすてるチャイム | Supported | See [patch/README.TXT](patch/README.TXT) |
| ぷろすちゅーでんとGood | Supported | |
| 守り神様 | Supported | |
| ママトト | Supported | |
| HUSHABY BABY | Supported | |
| DARCROWS | Supported | |
| 隠れ月 | Supported | |
| PERSIOM | Supported | 3D sound is not supported |
| SeeIn青 | Supported | |
| かえるにょ国にょアリス | Supported | From 20世紀アリス |
| これD・P・S? | Supported | From 20世紀アリス |
| 夜が来る! | Unsupported | |
| Only you ~リ・クルス~ | Supported | |
| 大悪司 | Supported | Opening demo is not supported |
| 王子さまLv1 | Supported | |
| 王子さま1ヵ月後 | Supported | From 王子さまLV1.5 |
| 白鳳の子分叩き | Supported | From 王子さまLV1.5 |
| チェシャのお部屋1.5 | Supported | From 王子さまLV1.5 |
| 王子さま1/16 | Supported | From 王子さまLV1.5 |
| スパイ伊藤の「クイズ!俺にさぼらせろ」 | Supported | From 王子さまLV1.5 |
| 妻みぐい | Supported | Opening demo is not supported |
| 超昂天使エスカレイヤー | Supported | Opening demo is not supported |
| ランス5D | Supported | |
| Rance 5D - The Lonely Girl (MangaGamer) | Supported | |
| 俺の下であがけ | Unknown | |
| 楽園行 | Unknown | |
| 妻みぐい2 | Supported | Opening demo is not supported |
| シェル・クレイル | Supported | |
| ナイトデーモン | Supported | |
| 学園KING | Supported | From アリスCD |
| 学園KING 番外編 | Supported | From アリスCD |
| 蒼海に墜ちて | Supported | From アリスCD |
| ぶろぶろ | Supported | From アリスCD |
| 裸ぶろぶろ狂 | Supported | From アリスCD |
| メイドのススメ | Supported | From アリスCD |
| 学園漂流戦記 | Supported | From アリスCD |
| 学園漂流戦記2 | Supported | From アリスCD |
| 当たって!!KUDAKERO 予告編 | Supported | From アリスCD |
| 妖精 | Supported | From アリスCD |
| [扉] | Supported | From アリスCD |
| 叩き殺し太郎 | Supported | From アリスCD |
| バルーンぽっぷ | Supported | From アリスCD |
| 高速ひよこ2 | 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 |
| 弱肉狂食 | Unsupported | From アリスCD |
| 眼鏡大戦2 | Supported | From アリスCD |
| 妄想くん | Supported | From アリスCD |
-1
View File
@@ -26,7 +26,6 @@ add_library(modules STATIC
SACT/SACT.c
SACT/sactcg.c
SACT/sactsound.c
SACT/sactbgm.c
SACT/sacttimer.c
SACT/sactstring.c
SACT/sactcrypto.c
+1 -1
View File
@@ -23,7 +23,7 @@ void nt_voice_set(int no) {
}
void nt_cd_play(int no) {
mus_cdrom_start(no +1, 0);
muscd_start(no + 1, 0);
}
void nt_cd_stop(int msec) {
+2 -2
View File
@@ -51,7 +51,7 @@ static void ndd_run(int demonum) {
int mus = ndemo_mus[demonum];
if (mus)
mus_bgm_play(mus, 0, 100);
musbgm_play(mus, 0, 100);
uint32_t start = sdl_getTicks();
while (!nact->is_quit) {
@@ -79,7 +79,7 @@ static void ndd_run(int demonum) {
}
if (mus)
mus_bgm_stop(ndemo_mus[demonum], 0);
musbgm_stop(ndemo_mus[demonum], 0);
alk_free(alk);
}
+16 -11
View File
@@ -25,22 +25,25 @@
#include <stdio.h>
#include <string.h>
#ifdef __EMSCRIPTEN__
#include <emscripten.h>
#endif
#include "portab.h"
#include "system.h"
#include "ald_manager.h"
#include "input.h"
#include "msgskip.h"
#include "xsystem35.h"
#include "gametitle.h"
#include "message.h"
#include "modules.h"
#include "music.h"
#include "nact.h"
#include "sact.h"
#include "sprite.h"
#include "sactcg.h"
#include "sactstring.h"
#include "sactsound.h"
#include "sactbgm.h"
#include "sactcrypto.h"
#include "sactchart.h"
#include "ngraph.h"
@@ -1790,7 +1793,9 @@ static void MusicCheck() {
int wNum = getCaliValue();
int *vRND = getCaliVariable();
*vRND = smus_check(wNum);
dridata *dfile = ald_getdata(DRIFILE_BGM, wNum - 1);
*vRND = dfile ? 1 : 0;
ald_freedata(dfile);
DEBUG_COMMAND_YET("SACT.MusicCheck %d,%p:", wNum, vRND);
}
@@ -1805,7 +1810,7 @@ static void MusicGetLength() {
int wNum = getCaliValue();
int *vRND = getCaliVariable();
*vRND = smus_getlength(wNum);
*vRND = musbgm_getlen(wNum);
DEBUG_COMMAND_YET("SACT.MusicGetLength %d,%d:", wNum, *vRND);
}
@@ -1820,7 +1825,7 @@ static void MusicGetPos() {
int wNum = getCaliValue();
int *vRND = getCaliVariable();
*vRND = smus_getpos(wNum);
*vRND = musbgm_getpos(wNum);
DEBUG_COMMAND_YET("SACT.MusicGetPos %d,%d:", wNum, *vRND);
}
@@ -1837,7 +1842,7 @@ static void MusicPlay() {
int wFadeTime = getCaliValue();
int wVolume = getCaliValue();
smus_play(wNum, wFadeTime, wVolume);
musbgm_play(wNum, wFadeTime, wVolume);
DEBUG_COMMAND_YET("SACT.MusicPlay %d,%d,%d:", wNum, wFadeTime, wVolume);
}
@@ -1852,7 +1857,7 @@ static void MusicStop() {
int wNum = getCaliValue();
int wFadeTime = getCaliValue();
smus_stop(wNum, wFadeTime);
musbgm_stop(wNum, wFadeTime);
DEBUG_COMMAND_YET("SACT.MusicStop %d,%d:", wNum, wFadeTime);
}
@@ -1865,7 +1870,7 @@ static void MusicStop() {
static void MusicStopAll() {
int wFadeTime = getCaliValue();
smus_stopall(wFadeTime);
musbgm_stopall(wFadeTime);
DEBUG_COMMAND_YET("SACT.MusicStopAll %d:", wFadeTime);
}
@@ -1882,7 +1887,7 @@ static void MusicFade() {
int wFadeTime = getCaliValue();
int wVolume = getCaliValue();
smus_fade(wNum, wFadeTime, wVolume);
musbgm_fade(wNum, wFadeTime, wVolume);
DEBUG_COMMAND_YET("SACT.MusicFade %d,%d,%d:", wNum, wFadeTime, wVolume);
}
@@ -1901,7 +1906,7 @@ static void MusicWait() {
nTimeOut = getCaliValue();
}
smus_wait(wNum, nTimeOut);
musbgm_wait(wNum, nTimeOut);
DEBUG_COMMAND_YET("SACT.MusicWait %d,%d:", wNum, nTimeOut);
}
@@ -1917,7 +1922,7 @@ static void MusicWaitPos() {
int wNum = getCaliValue();
int wIndex = getCaliValue();
smus_waitpos(wNum, wIndex);
WARNING("SACT.MusicWatiPos not implemented");
DEBUG_COMMAND_YET("SACT.MusicWaitPos %d,%d:", wNum, wIndex);
}
-93
View File
@@ -1,93 +0,0 @@
/*
* sactbgm.c: SACT Music 関連
*
* Copyright (C) 1997-1998 Masaki Chikama (Wren) <chikama@kasumi.ipl.mech.nagoya-u.ac.jp>
* 1998- <masaki-c@is.aist-nara.ac.jp>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
/* $Id: sactbgm.c,v 1.4 2003/08/30 21:29:16 chikama Exp $ */
#include "config.h"
#include <stdio.h>
#include "portab.h"
#include "system.h"
#include "ald_manager.h"
#include "music.h"
// 指定の番号の音楽が存在するかチェック
int smus_check(int no) {
dridata *dfile = ald_getdata(DRIFILE_BGM, no -1);
int st = 0;
if (dfile == NULL) {
st = 0;
} else {
st = 1;
ald_freedata(dfile);
}
return st;
}
// 指定の番号の音楽の長さを取得
int smus_getlength(int no) {
return mus_bgm_getlength(no);
}
// 指定の番号の音楽の再生位置を取得
int smus_getpos(int no) {
return mus_bgm_getpos(no);
}
// 指定の番号の音楽の再生開始
int smus_play(int no, int time, int vol) {
mus_bgm_play(no, time, vol);
return OK;
}
// 指定の番号の音楽の再生停止
int smus_stop(int no, int fadetime) {
mus_bgm_stop(no, fadetime);
return OK;
}
// 指定の番号の音楽のボリュームフェード
int smus_fade(int no, int time, int vol) {
mus_bgm_fade(no, time, vol);
return OK;
}
// 指定の番号の音楽が終了するのを待つ
int smus_wait(int no, int timeout) {
mus_bgm_wait(no, timeout);
return OK;
}
// 指定の番号の音楽が指定の位置まで再生されるのを待つ
int smus_waitpos(int no, int index) {
mus_bgm_waitpos(no, index);
return OK;
}
// 全ての音楽の再生を停止
int smus_stopall(int time) {
mus_bgm_stopall(time);
return OK;
}
+3
View File
@@ -24,6 +24,9 @@
#include "config.h"
#include <stdio.h>
#ifdef __EMSCRIPTEN__
#include <emscripten.h>
#endif
#include "portab.h"
#include "system.h"
+89 -22
View File
@@ -26,8 +26,10 @@
#include <stdio.h>
#include <string.h>
#include <SDL.h>
#include "portab.h"
#include "LittleEndian.h"
#include "xsystem35.h"
#include "modules.h"
#include "nact.h"
@@ -35,12 +37,16 @@
#include "ald_manager.h"
#include "music.h"
#ifdef ENABLE_SDLMIXER
#include "pcm.sdlmixer.h"
#include "shpcmlib.c"
static struct {
SDL_AudioSpec spec; // must be 16-bit, stereo
uint8_t *buf;
uint32_t len;
} memwav;
static Mix_Chunk *chunk;
#endif
static void free_memory_wav(void) {
SDL_FreeWAV(memwav.buf);
memwav.buf = NULL;
}
static void Init() {
/*
@@ -117,10 +123,24 @@ static void wavLoadMemory() {
no: 読み込むファイル番号
*/
int no = getCaliValue();
#ifdef ENABLE_SDLMIXER
chunk = pcm_sdlmixer_load(no);
#endif
if (memwav.buf)
free_memory_wav();
dridata *dfile = ald_getdata(DRIFILE_WAVE, no - 1);
if (!dfile) {
WARNING("cannot open WAVE %d", no - 1);
return;
}
if (!SDL_LoadWAV_RW(SDL_RWFromConstMem(dfile->data, dfile->size), 1, &memwav.spec, &memwav.buf, &memwav.len)) {
WARNING("cannot load WAVE %d", no - 1);
return;
}
if (memwav.spec.channels != 2 || memwav.spec.format != AUDIO_S16LSB) {
WARNING("unexpected audio format");
free_memory_wav();
return;
}
DEBUG_COMMAND("ShSound.wavLoadMemory %d:", no);
}
@@ -133,12 +153,38 @@ static void wavSendMemory() {
*/
int slot = getCaliValue();
#ifdef ENABLE_SDLMIXER
if (chunk) {
pcm_sdlmixer_load_chunk(slot, chunk);
chunk = NULL;
if (!memwav.buf) {
WARNING("wave not loaded");
return;
}
#endif
const uint8_t wave_header[] = {
'R', 'I', 'F', 'F',
0, 0, 0, 0, // filesize - 8 (filled later)
'W', 'A', 'V', 'E',
'f', 'm', 't', ' ',
16, 0, 0, 0, // size of fmt chunk
1, 0, // PCM format
2, 0, // stereo
0, 0, 0, 0, // sampling rate (filled later)
0, 0, 0, 0, // bytes / sec (filled later)
4, 0, // block size
16, 0, // bits / sample
'd', 'a', 't', 'a',
0, 0, 0, 0, // size of data chunk (filled later)
};
uint32_t wav_size = sizeof(wave_header) + memwav.len;
uint8_t *wav_buf = malloc(wav_size);
memcpy(wav_buf, wave_header, sizeof(wave_header));
LittleEndian_putDW(wav_size - 8, wav_buf, 4);
LittleEndian_putDW(memwav.spec.freq, wav_buf, 24);
LittleEndian_putDW(memwav.spec.freq * 4, wav_buf, 28);
LittleEndian_putDW(memwav.len, wav_buf, 40);
memcpy(wav_buf + sizeof(wave_header), memwav.buf, memwav.len);
mus_wav_load_data(slot, wav_buf, wav_size);
free_memory_wav();
free(wav_buf);
DEBUG_COMMAND("ShSound.wavSendMemory %d:", slot);
}
@@ -153,11 +199,26 @@ static void wavFadeVolumeMemory() {
int start = getCaliValue();
int range = getCaliValue();
#ifdef ENABLE_SDLMIXER
if (chunk == NULL) return;
if (!memwav.buf)
return;
pcmlib_fade_volume_memory(chunk, start, range);
#endif
start *= memwav.spec.freq / 100; // 10ms -> sample
range *= memwav.spec.freq / 100; // 10ms -> sample
if (memwav.len / 4 < start + range)
return;
int16_t *buf = (int16_t*)memwav.buf + start * 2;
// 指定の場所から徐々に音量を下げる
for (int i = range; i > 0; i--) {
buf[0] = buf[0] * i / range;
buf[1] = buf[1] * i / range;
buf += 2;
}
// 残りは無音
memset(buf, 0, memwav.buf + memwav.len - (uint8_t*)buf);
DEBUG_COMMAND("ShSound.wavFadeVolumeMemory %d,%d:", start, range);
}
@@ -167,11 +228,17 @@ static void wavReversePanMemory() {
wavLoadMemoryで読み込んだデータの左右のチャンネルを反転
*/
#ifdef ENABLE_SDLMIXER
if (chunk == NULL) return;
if (!memwav.buf)
return;
pcmlib_reverse_pan_memory(chunk);
#endif
int16_t *buf = (int16_t*)memwav.buf;
int len = memwav.len / 4;
for (int i = 0; i < len; i++) {
int16_t tmp = buf[0];
buf[0] = buf[1];
buf[1] = tmp;
buf += 2;
}
DEBUG_COMMAND("ShSound.wavReversePanMemory:");
}
-70
View File
@@ -1,70 +0,0 @@
/*
* shpcmlib.c ShSound用 pcmlib
*
* Copyright (C) 1997-1998 Masaki Chikama (Wren) <chikama@kasumi.ipl.mech.nagoya-u.ac.jp>
* 1998- <masaki-c@is.aist-nara.ac.jp>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
/* $Id: shpcmlib.c,v 1.2 2003/08/02 13:10:32 chikama Exp $ */
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <SDL_mixer.h>
#include "portab.h"
/*
左右のチャンネルの入れ換え
*/
void pcmlib_reverse_pan_memory(Mix_Chunk *chunk) {
if (chunk == NULL) return;
short *buf = (short*)chunk->abuf;
int len = chunk->alen / 4;
for (int i = 0; i < len; i++) {
short tmp = buf[0];
buf[0] = buf[1];
buf[1] = tmp;
buf += 2;
}
}
/*
メモリ上の PCM データにフェード効果をかける
*/
void pcmlib_fade_volume_memory(Mix_Chunk *chunk, int start, int range) {
if (chunk == NULL) return;
start *= 441; // 10ms -> sample
range *= 441; // 10ms -> sample
if (chunk->alen / 4 < start + range)
return;
short *buf = (short*)chunk->abuf;
buf += start * 2;
// 指定の場所から徐々に音量を下げる
for (int i = range; i > 0; i--) {
buf[0] = buf[0] * i / range;
buf[1] = buf[1] * i / range;
buf += 2;
}
// 残りは無音
memset(buf, 0, chunk->abuf + chunk->alen - (Uint8*)buf);
}
+3 -1
View File
@@ -89,7 +89,9 @@ static void SetWindowTitle(void) { /* 6 */
int strno = getCaliValue();
int p2 = getCaliValue(); /* ISys3xSystem */
ags_setWindowTitle(svar_get(strno));
char *title_utf8 = toUTF8(svar_get(strno));
ags_setWindowTitle(title_utf8);
free(title_utf8);
DEBUG_COMMAND("ShString.SetWindowTitle: %d,%d:", strno, p2);
}
+2 -2
View File
@@ -49,14 +49,14 @@ static void Run() {
DEBUG_COMMAND_YET("dDemo.Run:");
#ifdef DDEMODEV
mus_cdrom_start(13, 1);
muscd_start(13, 1);
// ddemo_scene();
while(0 == sys_getInputInfo()) {
usleep(1000 * 100);
}
mus_cdrom_stop();
muscd_stop();
#endif
}
+2 -2
View File
@@ -53,7 +53,7 @@ target_sources(xsystem35 PRIVATE
# Misc
target_sources(xsystem35 PRIVATE
LittleEndian.c input.c profile.c mt19937-1.c filecheck.c mmap.c)
input.c profile.c mt19937-1.c filecheck.c mmap.c hacks.c)
# Scenario
target_sources(xsystem35 PRIVATE
@@ -95,7 +95,7 @@ if (EMSCRIPTEN)
"SHELL:-s ENVIRONMENT=web"
"SHELL:-s ASYNCIFY=1 -s ASYNCIFY_IGNORE_INDIRECT=1"
"SHELL:-s ASYNCIFY_REMOVE=SDL_Delay"
"SHELL:-s ASYNCIFY_IMPORTS=muspcm_load_no,muspcm_load_mixlr,muspcm_waitend,wait_vsync,load_mincho_font"
"SHELL:-s ASYNCIFY_IMPORTS=muspcm_load_no,muspcm_load_data,muspcm_load_mixlr,muspcm_waitend,wait_vsync,load_mincho_font"
"SHELL:-s ASYNCIFY_ADD=commands2F60,nact_main,send_agsevent,cb_waitkey_sprite"
"SHELL:-s ALLOW_MEMORY_GROWTH=1"
"SHELL:-s NO_EXIT_RUNTIME=1"
-62
View File
@@ -1,62 +0,0 @@
/*
* LittleEndian.c get little endian value
*
* Copyright (C) 1997-1998 Masaki Chikama (Wren) <chikama@kasumi.ipl.mech.nagoya-u.ac.jp>
* 1998- <masaki-c@is.aist-nara.ac.jp>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*
* @version 0.00 97/11/06 初版
*/
/* $Id: LittleEndian.c,v 1.5 2000/11/25 13:08:56 chikama Exp $ */
#include "portab.h"
int LittleEndian_getDW(const uint8_t *b,int index) {
int c0, c1, c2, c3;
int d0, d1;
c0 = *(b + index + 0);
c1 = *(b + index + 1);
c2 = *(b + index + 2);
c3 = *(b + index + 3);
d0 = c0 + (c1 << 8);
d1 = c2 + (c3 << 8);
return (uint32_t)(d0 + (d1 << 16));
}
int LittleEndian_get3B(const uint8_t *b,int index) {
int c0, c1, c2;
c0 = *(b + index + 0);
c1 = *(b + index + 1);
c2 = *(b + index + 2);
return c0 + (c1 << 8) + (c2 << 16);
}
int LittleEndian_getW(const uint8_t *b,int index) {
int c0, c1;
c0 = *(b + index + 0);
c1 = *(b + index + 1);
return c0 + (c1 << 8);
}
void LittleEndian_putW(int num, uint8_t *b, int index) {
int c0, c1;
num %= 65536;
c0 = num % 256;
c1 = num / 256;
b[index] = c0; b[index+1] = c1;
}
+29 -5
View File
@@ -26,11 +26,35 @@
#ifndef __LITTLEENDIAN__
#define __LITTLEENDIAN__
#include "portab.h"
#include <string.h>
#include <SDL_endian.h>
extern int LittleEndian_getDW(const uint8_t *b,int index);
extern int LittleEndian_get3B(const uint8_t *b,int index);
extern int LittleEndian_getW(const uint8_t *b,int index);
extern void LittleEndian_putW(int num, uint8_t *b, int index);
static inline int LittleEndian_getDW(const uint8_t *b, int index) {
uint32_t t;
memcpy(&t, b + index, sizeof t);
return SDL_SwapLE32(t);
}
static inline int LittleEndian_get3B(const uint8_t *b, int index) {
uint32_t t = 0;
memcpy(&t, b + index, 3);
return SDL_SwapLE32(t);
}
static inline int LittleEndian_getW(const uint8_t *b, int index) {
uint16_t t;
memcpy(&t, b + index, sizeof t);
return SDL_SwapLE16(t);
}
static inline void LittleEndian_putW(uint16_t num, uint8_t *b, int index) {
num = SDL_SwapLE16(num);
memcpy(b + index, &num, sizeof(num));
}
static inline void LittleEndian_putDW(uint32_t num, uint8_t *b, int index) {
num = SDL_SwapLE32(num);
memcpy(b + index, &num, sizeof(num));
}
#endif /* !__LITTLEENDIAN__ */
+4 -13
View File
@@ -162,19 +162,10 @@ void ags_setViewArea(int x, int y, int width, int height) {
sdl_setWindowSize(width, height);
}
void ags_setWindowTitle(const char *src) {
#define TITLEHEAD "XSystem35 Version "VERSION":"
uint8_t *utf, *d;
utf = toUTF8(src);
if (NULL == (d = malloc(strlen(utf) + strlen(TITLEHEAD) + 1))) {
NOMEMERR();
}
strcpy(d, TITLEHEAD);
strcat(d, utf);
sdl_setWindowTitle(d);
free(utf);
free(d);
void ags_setWindowTitle(const char *title_utf8) {
char buf[256];
snprintf(buf, sizeof(buf), "XSystem35 Version %s: %s", VERSION, title_utf8);
sdl_setWindowTitle(buf);
}
void ags_getDIBInfo(DispInfo *info) {
+1 -1
View File
@@ -133,7 +133,7 @@ void ags_reset(void);
/* ウィンド関係 */
extern void ags_setWorldSize(int width, int height, int depth);
extern void ags_setViewArea(int x, int y, int width, int height);
extern void ags_setWindowTitle(const char *str);
extern void ags_setWindowTitle(const char *title_utf8);
extern void ags_getDIBInfo(DispInfo *info);
extern void ags_getWindowInfo(DispInfo *info);
extern void ags_getViewAreaInfo(DispInfo *info);
+6 -5
View File
@@ -36,11 +36,6 @@ static drifiles *dri[DRIFILETYPEMAX];
/* cache handler for dri file */
static cacher *cacheid;
/*
* static maethods
*/
static void ald_free(dridata *dfile);
/*
* free dridata
* dfile: dridata to be free
@@ -109,3 +104,9 @@ void ald_init(int type, const char **file, int cnt, boolean use_mmap) {
cacheid = cache_new(ald_free);
}
}
int ald_get_maxno(DRIFILETYPE type) {
if (type >= DRIFILETYPEMAX || !dri[type])
return 0;
return dri[type]->nr_files;
}
+4 -3
View File
@@ -38,9 +38,10 @@ typedef enum {
DRIFILE_BGM =6 /* stream music data */
} DRIFILETYPE;
extern void ald_init(int type, const char **file, int cnt, boolean use_mmap);
extern dridata *ald_getdata(DRIFILETYPE type, int no);
extern void ald_freedata(dridata *data);
void ald_init(int type, const char **file, int cnt, boolean use_mmap);
dridata *ald_getdata(DRIFILETYPE type, int no);
void ald_freedata(dridata *data);
int ald_get_maxno(DRIFILETYPE type);
#endif /* !__ALD_MANAGER__ */
+1 -1
View File
@@ -22,7 +22,7 @@
#include "portab.h"
#include "bgm.h"
int musbgm_init(void) {
int musbgm_init(DRIFILETYPE type, int base_no) {
return NG;
}
+6 -2
View File
@@ -26,8 +26,12 @@
#include "bgi.h"
#include "sdl_core.h"
int musbgm_init(void) {
return bgi_read(nact->files.bgi);
int musbgm_init(DRIFILETYPE type, int base_no) {
if (type == DRIFILE_BGM)
return bgi_read(nact->files.bgi);
else
EM_ASM({ xsystem35.cdPlayer.setBGMLoader($0, $1); }, type, base_no);
return OK;
}
int musbgm_exit(void) {
+3 -1
View File
@@ -19,7 +19,9 @@
#ifndef __BGM_H__
#define __BGM_H__
int musbgm_init(void);
#include "ald_manager.h"
int musbgm_init(DRIFILETYPE type, int base_no);
int musbgm_exit(void);
int musbgm_reset(void);
int musbgm_play(int no, int time, int vol);
+12 -5
View File
@@ -36,6 +36,8 @@
#include "music_private.h"
#include "ald_manager.h"
static DRIFILETYPE dri_type;
static int base_no;
static int current_no;
static Mix_Music *mix_music;
static dridata* dfile;
@@ -56,9 +58,10 @@ static void free_music() {
static Mix_Music *bgm_load(int no) {
free_music();
dfile = ald_getdata(DRIFILE_BGM, no -1);
int ald_no = no + base_no - 1;
dfile = ald_getdata(dri_type, ald_no);
if (dfile == NULL) {
WARNING("DRIFILE_BGM fail to open %d", no -1);
WARNING("Failed to open BGM %d", ald_no);
return NULL;
}
@@ -66,7 +69,7 @@ static Mix_Music *bgm_load(int no) {
mix_music = Mix_LoadMUS_RW(rwops, SDL_TRUE /* freesrc */);
if (mix_music == NULL) {
WARNING("Failed to load BGM %d: %s", no, SDL_GetError());
WARNING("Failed to load BGM %d: %s", ald_no, SDL_GetError());
free_music();
return NULL;
}
@@ -75,8 +78,12 @@ static Mix_Music *bgm_load(int no) {
return mix_music;
}
int musbgm_init(void) {
return bgi_read(nact->files.bgi);
int musbgm_init(DRIFILETYPE type, int base) {
dri_type = type;
base_no = base;
if (type == DRIFILE_BGM)
return bgi_read(nact->files.bgi);
return OK;
}
int musbgm_exit(void) {
+72
View File
@@ -0,0 +1,72 @@
/*
* cdrom.bgm.c CD->bgm bridge
*
* Copyright (C) 2023 <KichikuouChrome@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#include <stdio.h>
#include "cdrom.h"
#include "music.h"
static int current_track;
static int cdrom_bgm_init(char *dev) {
return OK;
}
static int cdrom_bgm_exit(void) {
return OK;
}
static int cdrom_bgm_reset(void) {
return OK;
}
static int cdrom_bgm_start(int trk, int loop) {
if (musbgm_play(trk, 0, 100) != OK)
return NG;
current_track = trk;
return OK;
}
static int cdrom_bgm_stop(void) {
return musbgm_stop(current_track, 0);
}
static int cdrom_bgm_getPlayingInfo(cd_time *info) {
int t = musbgm_getpos(current_track); // in 10ms
if (!t)
return NG;
info->t = current_track;
info->m = t / (60*100); t %= (60*100);
info->s = t / 100; t %= 100;
info->f = t * CD_FPS / 100;
return OK;
}
cdromdevice_t cdrom_bgm = {
cdrom_bgm_init,
cdrom_bgm_exit,
cdrom_bgm_reset,
cdrom_bgm_start,
cdrom_bgm_stop,
cdrom_bgm_getPlayingInfo,
NULL,
NULL
};
+13 -51
View File
@@ -26,7 +26,6 @@
#include <sys/stat.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include "portab.h"
#include "cdrom.h"
@@ -34,80 +33,43 @@
#if defined(ENABLE_CDROM_LINUX)
extern cdromdevice_t cdrom_linux;
#define DEV_PLAY_MODE &cdrom_linux
#define NATIVE_CD_DEVICE &cdrom_linux
#elif defined(ENABLE_CDROM_BSD)
extern cdromdevice_t cdrom_bsd;
#define DEV_PLAY_MODE &cdrom_bsd
#define NATIVE_CD_DEVICE &cdrom_bsd
#elif defined(ENABLE_CDROM_EMSCRIPTEN)
extern cdromdevice_t cdrom_emscripten;
#define DEV_PLAY_MODE &cdrom_emscripten
#define NATIVE_CD_DEVICE &cdrom_emscripten
#elif defined(ENABLE_CDROM_ANDROID)
extern cdromdevice_t cdrom_android;
#define DEV_PLAY_MODE &cdrom_android
#define NATIVE_CD_DEVICE &cdrom_android
#else
extern cdromdevice_t cdrom_empty;
#define DEV_PLAY_MODE &cdrom_empty
#define NATIVE_CD_DEVICE &cdrom_empty
#endif
#ifdef ENABLE_CDROM_MP3
extern cdromdevice_t cdrom_mp3;
#endif
/*
temporary cdrom device name
default ... /dev/cdrom
FreeBSD ... /dev/acd0a
etc...
*/
static char *dev = CDROM_DEVICE;
/*
初期化
dev: cdromdevice に関する情報を格納する場所
RET: 成功 0
失敗 -1
*/
int cd_init(cdromdevice_t *cd) {
cdromdevice_t *cd_init(const char *dev) {
#if defined(ENABLE_CDROM_EMSCRIPTEN) || defined(ENABLE_CDROM_ANDROID)
memcpy(cd, DEV_PLAY_MODE, sizeof(cdromdevice_t));
return cd->init(dev);
return NATIVE_CD_DEVICE;
#else
struct stat st;
int ret = NG;
if (dev == NULL) return -1;
stat(dev, &st);
if (S_ISBLK(st.st_mode) | S_ISCHR(st.st_mode)) {
/* CDROM MODE */
memcpy(cd, DEV_PLAY_MODE, sizeof(cdromdevice_t));
ret = cd->init(dev);
}
else {
if (dev && stat(dev, &st) && (S_ISBLK(st.st_mode) || S_ISCHR(st.st_mode)))
return NATIVE_CD_DEVICE;
#ifdef ENABLE_CDROM_MP3
/* MP3 MODE */
memcpy(cd, &cdrom_mp3, sizeof(cdromdevice_t));
ret = cd->init(dev);
return &cdrom_mp3;
#else
/* error */
WARNING("no cdrom device available");
ret = NG;
WARNING("no cdrom device available");
return NULL;
#endif
}
return ret;
#endif // ENABLE_CDROM_EMSCRIPTEN || ENABLE_CDROM_ANDROID
}
void cd_set_devicename(char *name) {
if (0 == strcmp("none", name)) dev = NULL;
else dev = strdup(name);
}
+3 -2
View File
@@ -49,8 +49,9 @@ struct _cdromdevice {
};
typedef struct _cdromdevice cdromdevice_t;
extern int cd_init(cdromdevice_t *);
extern void cd_set_devicename(char *);
extern cdromdevice_t cdrom_bgm;
extern cdromdevice_t *cd_init(const char *dev);
#define CD_FPS 75
#define FRAMES_TO_MSF(f, M,S,F) { \
+39 -4
View File
@@ -35,7 +35,7 @@
#include "qnt.h"
#include "jpeg.h"
#include "ald_manager.h"
#include "savedata.h"
#include "filecheck.h"
#include "cache.h"
/* VSPのパレット展開バンク */
@@ -346,9 +346,9 @@ void cg_load(int no, int flg) {
}
/* draw cg pixel */
display_cg(cg, p.x, p.y, flg, flg != -1);
/* clear display offset */
clear_display_loc();
}
/* clear display offset */
clear_display_loc();
}
/*
@@ -391,6 +391,41 @@ void cg_load_with_alpha(int cgno, int shadowno) {
clear_display_loc();
}
static uint8_t* load_cg_from_file(char *fname_utf8, int *status, long *filesize) {
int size;
FILE *fp;
static uint8_t *tmp;
*status = 0;
if (NULL == (fp = fc_open(fname_utf8, 'r'))) {
*status = SAVE_LOADERR; return NULL;
}
fseek(fp, 0L, SEEK_END);
*filesize = ftell(fp);
if (*filesize == 0) {
*status = SAVE_LOADERR; return NULL;
}
tmp = (char *)malloc(*filesize);
if (tmp == NULL) {
WARNING("Out of memory");
*status = SAVE_LOADERR; return NULL;
}
fseek(fp, 0L, SEEK_SET);
size = fread(tmp, 1, *filesize,fp);
if (size != *filesize) {
*status = SAVE_LOADSHORTAGE;
} else {
*status = SAVE_LOADOK;
}
fclose(fp);
return tmp;
}
/*
* Load and display cg from file 'name' (not cached right now)
* name: file name to be read
@@ -405,7 +440,7 @@ int cg_load_with_filename(char *fname_utf8, int x, int y) {
cgdata *cg = NULL;
MyPoint p;
data = load_cg_with_file(fname_utf8, &status, &filesize);
data = load_cg_from_file(fname_utf8, &status, &filesize);
if (data == NULL) return status;
cg_set_display_location(x, y, OFFSET_ABSOLUTE_GC);
+23 -62
View File
@@ -41,14 +41,11 @@
#include "sdl_core.h"
#include "ald_manager.h"
#include "LittleEndian.h"
#include "gametitle.h"
#include "hacks.h"
#if HAVE_UNAME
#include <sys/utsname.h>
#endif
/* defined by cmdm.c */
extern boolean have_eng_mp_patch;
/* 選択 Window OPEN 時 callback */
static int cb_sel_init_page = 0;
static int cb_sel_init_address = 0;
@@ -68,82 +65,49 @@ static fncall_table fnctbl[FCTBL_MAX];
void commands2F00() {
/* テキストカラーをスタックからポップして設定する */
int data[3];
sl_popData(data, 3);
if (data[0] == TxxTEXTCOLOR) {
if (data[1] == 0) {
nact->msg.MsgFontColor = data[2];
} else {
nact->sel.MsgFontColor = data[2];
}
}
sl_popState(STACK_TEXTCOLOR);
DEBUG_COMMAND("TOC:");
}
void commands2F01() {
/* テキストフォントサイズをスタックからポップして設定する */
int data[3];
sl_popData(data, 3);
if (data[0] == TxxTEXTSIZE) {
if (data[1] == 0) {
nact->msg.MsgFontSize = data[2];
} else {
nact->sel.MsgFontSize = data[2];
}
}
sl_popState(STACK_TEXTSIZE);
DEBUG_COMMAND("TOS:");
}
void commands2F02() {
/* 現在のテキストカラーをスタックにプッシュする */
int exp = getCaliValue();
int data[] = {TxxTEXTCOLOR,0,0};
data[1] = exp;
data[2] = (exp == 0 ? nact->msg.MsgFontColor : nact->sel.MsgFontColor);
sl_pushData(data, 3);
int type = getCaliValue();
switch (type) {
case 0: sl_pushTextColor(type, nact->msg.MsgFontColor); break;
case 1: sl_pushTextColor(type, nact->sel.MsgFontColor); break;
default: WARNING("TPC: unknown type %d", type); break;
}
DEBUG_COMMAND("TPC %d", exp);
}
void commands2F03() {
/* 現在のテキストフォントサイズをスタックにプッシュする */
int exp = getCaliValue();
int data[] = {TxxTEXTSIZE, 0, 0};
data[1] = exp;
data[2] = (exp == 0 ? nact->msg.MsgFontSize : nact->sel.MsgFontSize);
sl_pushData(data, 3);
DEBUG_COMMAND("TPS %d:%s", exp, "");
int type = getCaliValue();
switch (type) {
case 0: sl_pushTextSize(type, nact->msg.MsgFontSize); break;
case 1: sl_pushTextSize(type, nact->sel.MsgFontSize); break;
default: WARNING("TPS: unknown type %d", type); break;
}
DEBUG_COMMAND("TPS %d", exp);
}
void commands2F04() {
/* テキスト表示位置をスタックからポップして設定する */
int data[3];
sl_popData(data, 3);
if (data[0] == TxxTEXTLOC) {
msg_setMessageLocation(data[1], data[2]);
}
sl_popState(STACK_TEXTLOC);
DEBUG_COMMAND("TOP:");
}
void commands2F05() {
/* 現在のテキスト表示位置をスタックにプッシュする */
int data[] = {TxxTEXTLOC, 0, 0};
MyPoint loc;
msg_getMessageLocation(&loc);
data[1] = loc.x;
data[2] = loc.y;
sl_pushData(data, 3);
sl_pushTextLoc(loc.x, loc.y);
DEBUG_COMMAND("TPP:");
}
@@ -394,7 +358,7 @@ void commands2F24() {
case 1:
var = getCaliValue();
cnt = getCaliValue();
sysVar[0] = save_load_str_with_file(fname_utf8, var, cnt);
sysVar[0] = load_strs_from_file(fname_utf8, var, cnt);
break;
default:
var = getCaliValue();
@@ -461,12 +425,9 @@ void commands2F28() {
free(nact->game_title_utf8);
nact->game_title_utf8 = toUTF8(title);
ags_setWindowTitle(title);
ags_setWindowTitle(nact->game_title_utf8);
if (0 == strcmp(nact->game_title_utf8, GT_RANCE3_ENG) ||
0 == strcmp(nact->game_title_utf8, GT_RANCE4_ENG)) {
have_eng_mp_patch = TRUE;
}
enable_hack_by_title(nact->game_title_utf8);
DEBUG_COMMAND("MT(new) %s:",title);
}
@@ -503,7 +464,7 @@ void commands2F2A() {
case 1:
var = getCaliValue();
cnt = getCaliValue();
sysVar[0] = save_save_str_with_file(fname_utf8, var, cnt);
sysVar[0] = save_strs_to_file(fname_utf8, var, cnt);
break;
default:
var = getCaliValue();
@@ -1290,7 +1251,7 @@ void commands2F72() {
void commands2F73() {
int *vTrack = getCaliVariable();
*vTrack = mus_cdrom_get_maxtrack();
*vTrack = muscd_get_maxtrack();
DEBUG_COMMAND("cdGetMaxTrack %d:", *vTrack);
}
+4
View File
@@ -773,6 +773,8 @@ void exec_command(void) {
commandLXR(); break;
case 'W':
commandLXW(); break;
case 'X':
commandLXX(); break;
default:
undeferr();
}
@@ -974,6 +976,8 @@ void exec_command(void) {
commandST(); break;
case 'U':
commandSU(); break;
case 'V':
commandSV(); break;
case 'W':
commandSW(); break;
case 'X':
+2 -1
View File
@@ -135,7 +135,7 @@ extern void commandLXS();
extern void commandLXP();
extern void commandLXR();
extern void commandLXW();
extern void commandLXX();
/* defined by cmdm.c */
extern void commandMA();
@@ -220,6 +220,7 @@ extern void commandSR();
extern void commandSS();
extern void commandST();
extern void commandSU();
extern void commandSV();
extern void commandSW();
extern void commandSX();
extern void commandSI();
+17 -17
View File
@@ -47,7 +47,7 @@ void commandB0() {
}
void commandB1() {
int num = getCaliValue() - 1;
int num = getCaliValue();
int X1 = getCaliValue();
int Y1 = getCaliValue();
int X2 = getCaliValue();
@@ -64,7 +64,7 @@ void commandB1() {
nact->sel.wininfo[num].height = Y2;
nact->sel.wininfo[num].save = (V == 0) ? false : true;
DEBUG_COMMAND("B1 %d,%d,%d,%d,%d,%d:", num + 1, X1, Y1, X2, Y2, V);
DEBUG_COMMAND("B1 %d,%d,%d,%d,%d,%d:", num, X1, Y1, X2, Y2, V);
}
void commandB2() {
@@ -75,13 +75,13 @@ void commandB2() {
int C3 = getCaliValue();
int dot = getCaliValue();
if (num < 1 || num - 1 >= SELWINMAX) {
if (num < 0 || num >= SELWINMAX) {
WARNING("commandB2(): Window number is out of range %d", num);
return;
}
nact->sel.winno = num;
nact->sel.win = &nact->sel.wininfo[num - 1];
nact->sel.win = &nact->sel.wininfo[num];
nact->sel.WindowFrameType = W;
nact->sel.FrameCgNoTop = C1;
@@ -93,7 +93,7 @@ void commandB2() {
}
void commandB3() {
int num = getCaliValue() - 1;
int num = getCaliValue();
int X1 = getCaliValue();
int Y1 = getCaliValue();
int X2 = getCaliValue();
@@ -110,7 +110,7 @@ void commandB3() {
nact->msg.wininfo[num].height = Y2;
nact->msg.wininfo[num].save = (V == 0) ? FALSE : TRUE;
DEBUG_COMMAND("B3 %d,%d,%d,%d,%d,%d:", num + 1, X1, Y1, X2, Y2, V);
DEBUG_COMMAND("B3 %d,%d,%d,%d,%d,%d:", num, X1, Y1, X2, Y2, V);
}
void commandB4() {
@@ -121,13 +121,13 @@ void commandB4() {
int N = getCaliValue();
int M = getCaliValue();
if (num < 1 || num - 1 >= MSGWINMAX) {
if (num < 0 || num >= MSGWINMAX) {
WARNING("commandB4(): Window number is out of range %d", num);
num = 0;
return;
}
nact->msg.winno = num;
nact->msg.win = &nact->msg.wininfo[num - 1];
nact->msg.win = &nact->msg.wininfo[num];
msg_openWindow(W, C1, C2, N, M);
DEBUG_COMMAND("B4 %d,%d,%d,%d,%d,%d:", num, W, C1, C2, N, M);
@@ -225,8 +225,8 @@ void commandB31() {
int *x_var = getCaliVariable();
int *y_var = getCaliVariable();
*x_var = nact->sel.wininfo[no - 1].x;
*y_var = nact->sel.wininfo[no - 1].y;
*x_var = nact->sel.wininfo[no].x;
*y_var = nact->sel.wininfo[no].y;
DEBUG_COMMAND("B31 %d,%d,%d:", no, *x_var, *y_var);
}
@@ -236,8 +236,8 @@ void commandB32() {
int *x_var_size = getCaliVariable();
int *y_var_size = getCaliVariable();
*x_var_size = nact->sel.wininfo[no - 1].width;
*y_var_size = nact->sel.wininfo[no - 1].height;
*x_var_size = nact->sel.wininfo[no].width;
*y_var_size = nact->sel.wininfo[no].height;
DEBUG_COMMAND("B32 %d,%d,%d:", no, *x_var_size, *y_var_size);
}
@@ -247,8 +247,8 @@ void commandB33() {
int *x_var = getCaliVariable();
int *y_var = getCaliVariable();
*x_var = nact->msg.wininfo[no - 1].x;
*y_var = nact->msg.wininfo[no - 1].y;
*x_var = nact->msg.wininfo[no].x;
*y_var = nact->msg.wininfo[no].y;
DEBUG_COMMAND("B33 %d,%d,%d:", no, *x_var, *y_var);
}
@@ -257,8 +257,8 @@ void commandB34() {
int *x_var_size = getCaliVariable();
int *y_var_size = getCaliVariable();
*x_var_size = nact->msg.wininfo[no - 1].width;
*y_var_size = nact->msg.wininfo[no - 1].height;
*x_var_size = nact->msg.wininfo[no].width;
*y_var_size = nact->msg.wininfo[no].height;
DEBUG_COMMAND("B34 %d,%d,%d:", no, *x_var_size, *y_var_size);
}
+62 -22
View File
@@ -72,13 +72,13 @@ void commandLT() {
struct stat buf;
struct tm *lc;
if (num <= 0) {
*var = 0;
*(var + 1) = 0;
*(var + 2) = 0;
*(var + 3) = 0;
*(var + 4) = 0;
*(var + 5) = 0;
if (num <= 0 || num > SAVE_MAXNUMBER) {
var[0] = 0;
var[1] = 0;
var[2] = 0;
var[3] = 0;
var[4] = 0;
var[5] = 0;
sysVar[0] = 255;
return;
}
@@ -86,21 +86,21 @@ void commandLT() {
status = stat(save_get_file(num - 1), &buf);
if (status) {
/* んなんどこにもかいてないやん! */
*var = 0;
*(var + 1) = 0;
*(var + 2) = 0;
*(var + 3) = 0;
*(var + 4) = 0;
*(var + 5) = 0;
var[0] = 0;
var[1] = 0;
var[2] = 0;
var[3] = 0;
var[4] = 0;
var[5] = 0;
sysVar[0] = 255;
} else {
lc = localtime(&buf.st_mtime);
*var = 1900 + lc->tm_year;
*(var + 1) = 1 + lc->tm_mon;
*(var + 2) = lc->tm_mday;
*(var + 3) = lc->tm_hour;
*(var + 4) = lc->tm_min;
*(var + 5) = lc->tm_sec;
var[0] = lc->tm_year + 1900;
var[1] = lc->tm_mon + 1;
var[2] = lc->tm_mday;
var[3] = lc->tm_hour;
var[4] = lc->tm_min;
var[5] = lc->tm_sec;
sysVar[0] = 0;
}
DEBUG_COMMAND("LT %d,%p",num, var);
@@ -114,16 +114,16 @@ void commandLE() {
char *fname_utf8 = toUTF8(filename);
switch (type) {
case 0: /* T2 */
case 0:
getCaliArray(&vref);
var = vref.var;
cnt = getCaliValue();
sysVar[0] = load_vars_from_file(fname_utf8, &vref, cnt);
break;
case 1: /* 456 */
case 1:
var = getCaliValue();
cnt = getCaliValue();
sysVar[0] = save_load_str_with_file(fname_utf8, var, cnt);
sysVar[0] = load_strs_from_file(fname_utf8, var, cnt);
break;
default:
var = getCaliValue();
@@ -336,3 +336,43 @@ void commandLXW() {
DEBUG_COMMAND_YET("LXW %d,%d,%d:",num,*var,size);
}
void commandLXX() {
/* Gets file timestamp to [var, var+6] */
int type = getCaliValue();
int num = getCaliValue();
int *var = getCaliVariable();
struct stat buf;
struct tm *lc;
switch (type) {
case 5: // save data
if (num <= 0 || num > SAVE_MAXNUMBER || stat(save_get_file(num - 1), &buf)) {
sysVar[0] = 255;
break;
}
lc = localtime(&buf.st_mtime);
var[0] = lc->tm_year + 1900;
var[1] = lc->tm_mon + 1;
var[2] = lc->tm_mday;
var[3] = lc->tm_hour;
var[4] = lc->tm_min;
var[5] = lc->tm_sec;
var[6] = lc->tm_wday;
sysVar[0] = 0;
break;
case 0: // scenario
case 1: // CG
case 2: // wave
case 3: // MIDI
case 4: // data
case 6: // resource
default:
DEBUG_COMMAND_YET("LXX %d,%d,%d:", type, num, *var);
return;
}
DEBUG_COMMAND("LXX %d,%d,%d:", type, num, *var);
}
+5 -25
View File
@@ -31,22 +31,13 @@
#include "utfsjis.h"
#include "menu.h"
#include "ags.h"
#include "input.h"
#include "message.h"
#include "gametitle.h"
#include "hankaku.h"
/* defined by cmds.c */
extern boolean dummy_pcm_su_flag;
/* defined by cmdy.c */
extern boolean Y3waitFlags;
/* MI 用パラメータ */
INPUTSTRING_PARAM mi_param;
boolean have_eng_mp_patch = FALSE;
void commandMS() {
/* Xコマンドで表示される文字列領域に文字列を入れる */
int num = getCaliValue();
@@ -69,7 +60,7 @@ void commandMP() {
char *str;
/* Patched English executable appends num2 spaces instead of truncating */
if (have_eng_mp_patch) {
if (nact->game == GAME_RANCE3_ENG || nact->game == GAME_RANCE4_ENG) {
str = calloc(strlen(src) + num2 * strlen(fullwidth_blank[nact->encoding]) + 1, 1);
if (NULL == str) {
NOMEMERR();
@@ -163,17 +154,9 @@ void commandMT() {
if (nact->game_title_utf8)
free(nact->game_title_utf8);
nact->game_title_utf8 = toUTF8(str);
ags_setWindowTitle(str);
ags_setWindowTitle(nact->game_title_utf8);
/* 闘神都市II 対策 */
if (0 == strcmp(nact->game_title_utf8, GT_TOSHIN2)) {
dummy_pcm_su_flag = TRUE;
}
/* Rance4 対策? */
if (0 == strcmp(nact->game_title_utf8, GT_RANCE4)) {
Y3waitFlags = KEYWAIT_NONCANCELABLE;
}
enable_hack_by_title(nact->game_title_utf8);
DEBUG_COMMAND("MT %s:",str);
}
@@ -266,16 +249,13 @@ void commandMF() {
void commandMZ0() {
/* 文字列変数の文字数・個数の設定の変更 */
int max_len = getCaliValue();
int max_len = getCaliValue(); // deprecated in System3.9
int max_num = getCaliValue();
int rsv = getCaliValue();
DEBUG_COMMAND("MZ0 %d,%d,%d:",max_len, max_num, rsv);
/* いつからか、文字列変数の最大長さは∞になったようだ */
if (max_len == 0) max_len = STRVAR_LEN * 2;
svar_init(max_num, max_len * 2 + 1);
svar_init(max_num);
}
void commandMG() {
+1 -1
View File
@@ -96,7 +96,7 @@ void commandQE() {
case 1:
var = getCaliValue();
cnt = getCaliValue();
sysVar[0] = save_save_str_with_file(fname_utf8, var, cnt);
sysVar[0] = save_strs_to_file(fname_utf8, var, cnt);
break;
default:
var = getCaliValue();
+16 -8
View File
@@ -29,8 +29,6 @@
/* ぱにょ〜ん 異常シナリオ対策 */
static boolean dummy_pcm_in_play = FALSE;
/* 闘神都市II 異常シナリオ対策 */
boolean dummy_pcm_su_flag = FALSE;
/* 次の cdrom の loop 回数 */
static int next_cdrom_loopcnt = 0;
@@ -41,9 +39,9 @@ void commandSS() {
DEBUG_COMMAND("SS %d:",num);
if (num == 0) {
mus_cdrom_stop();
muscd_stop();
} else {
mus_cdrom_start(num + 1, next_cdrom_loopcnt);
muscd_start(num + 1, next_cdrom_loopcnt);
}
next_cdrom_loopcnt = 0;
@@ -54,7 +52,7 @@ void commandSC() {
int *var = getCaliVariable();
int t, m, s, f;
if (mus_cdrom_get_playposition(&t, &m, &s, &f) == OK) {
if (muscd_getpos(&t, &m, &s, &f) == OK) {
*var++ = t - 1;
*var++ = m;
*var++ = s;
@@ -97,7 +95,7 @@ void commandSR() {
if (num == 0) {
int t, m, s, f;
if (mus_cdrom_get_playposition(&t, &m, &s, &f) == OK) {
if (muscd_getpos(&t, &m, &s, &f) == OK) {
// System3.5 returns the music number (track_no - 1),
// while System3.6 and later return the track number.
if (!memcmp(sl_sco, "S350", 4))
@@ -135,7 +133,7 @@ void commandSI() {
} else if (type == 1) { /* PCM */
*var = mus_pcm_get_state() == TRUE ? 1 : 0;
} else if (type == 2) { /* CD */
*var = mus_cdrom_get_state() == TRUE ? 1 : 0;
*var = muscd_is_available() ? 1 : 0;
}
DEBUG_COMMAND("SI %d,%d:",type,*var);
@@ -273,13 +271,23 @@ void commandSU() {
dummy_pcm_in_play = dummy_pcm_in_play ? FALSE : TRUE;
}
}
if (dummy_pcm_su_flag) {
/* 闘神都市II 異常シナリオ対策 */
if (nact->game == GAME_TT2) {
*var1 = *var2 = 0;
}
DEBUG_COMMAND("SU %d,%d:",*var1, *var2);
}
void commandSV() {
// Set volume (Rance4 v2)
int device = getCaliValue();
int volume = getCaliValue();
mus_mixer_set_level(device, volume);
DEBUG_COMMAND("SV %d,%d", device, volume);
}
void commandSQ() {
/* 左右別々のPCMデータを合成して演奏する */
int noL = getCaliValue();
+19 -6
View File
@@ -33,12 +33,16 @@ void commandUC() { /* 王道勇者 */
switch(mode) {
case 0:
sl_stackClear_allCall(); break;
sl_clearStack(true);
break;
case 1:
sl_stackClear_labelCall(num); break;
sl_dropLabelCalls(num);
break;
case 2:
sl_stackClear_pageCall(num); break;
default:
sl_dropPageCalls(num);
break;
case 3:
sl_clearStack(false);
break;
}
DEBUG_COMMAND("UC %d,%d:",mode,num);
@@ -51,7 +55,7 @@ void commandUD() {
case 0:
sl_reinit(); break;
case 1:
sl_retFar2(); break;
sl_retFar(); break;
default:
WARNING("UnKnown UD command %d", mode);
}
@@ -62,8 +66,17 @@ void commandUD() {
void commandUR() {
/* 最後に積まれたスタックの属性をリード */
int *var = getCaliVariable();
struct stack_info info;
sl_getStackInfo(&info);
var[0] = info.top_attr;
var[1] = info.page_calls;
var[2] = info.label_calls;
var[3] = info.var_pushes;
var[4] = info.label_calls_after_page_call;
var[5] = info.var_pushes_after_call;
DEBUG_COMMAND_YET("UR %p:",var);
DEBUG_COMMAND("UR %p:",var);
}
void commandUS() {
+37 -10
View File
@@ -32,6 +32,7 @@
#include "scenario.h"
#include "cmd_check.h"
#include "sdl_core.h"
#include "music_cdrom.h"
unsigned Y3waitFlags = KEYWAIT_CANCELABLE;
@@ -63,6 +64,9 @@ unsigned Y3waitFlags = KEYWAIT_CANCELABLE;
*
* To fix this, this hack processes `Y 3, 1:` followed by the IM command without
* delay, when a button is pressed.
*
* For Rance4 v2, this does not work because the UI loop also checks keyboard
* status, so we use a different hack. See rance4v2_hack() in sdl_event.c.
*/
static void rance4_Y3_IM_hack() {
static int count;
@@ -82,7 +86,8 @@ void commandY() {
unsigned int p1 = getCaliValue();
unsigned int p2 = getCaliValue();
if (p1 == 1) {
switch (p1) {
case 1:
if (p2 == 0) {
/* メッセージ領域の初期化と、文字の表示位置を左上端にセットする */
msg_nextPage(TRUE);
@@ -90,18 +95,23 @@ void commandY() {
/* メッセージ領域の文字の表示位置を左上端にセットする */
msg_nextPage(FALSE);
}
} else if (p1 == 2) {
break;
case 2:
/*システム変数 D01〜D20 までを初期化する */
for (i = 0; i < 20; i++) {
sysVar[i + 1] = 0;
}
} else if (p1 == 3) {
int orig_pc = sl_getIndex();
if (p2 == 1 && sl_getc() == 'I' && sl_getc() == 'M') {
rance4_Y3_IM_hack();
return;
break;
case 3:
case 1003: // Rance4 ver2.05
{
int orig_pc = sl_getIndex();
if (p2 == 1 && sl_getc() == 'I' && sl_getc() == 'M') {
rance4_Y3_IM_hack();
return;
}
sl_jmpNear(orig_pc);
}
sl_jmpNear(orig_pc);
switch (p2) {
case 10000:
@@ -114,18 +124,35 @@ void commandY() {
sysVar[0] = sys_getInputInfo();
break;
default:
if (p1 == 1003) {
sys_key_releasewait(SYS35KEY_RET, FALSE);
} else if (nact->game == GAME_RANCE4_V2 && p2 == 1) {
// Return immediately if any key is pressed.
sysVar[0] = sys_getInputInfo();
if (sysVar[0])
break;
}
sysVar[0] = sys_keywait(16 * p2, Y3waitFlags | KEYWAIT_SKIPPABLE);
break;
}
} else if (p1 == 4) {
break;
case 4:
/* 1 〜 n までの乱数を RND に返す。*/
if (p2 == 0 || p2 == 1) {
sysVar[0] = p2;
} else {
sysVar[0] = (int)(genrand() * p2) +1;
}
} else {
break;
case 1900:
nact->patch_ec = p2;
// We're sure this game was built for System3.9 v5.50, which by default
// routes CD-DA commands to DRIFILE_WAVE.
muscd_init_bgm(DRIFILE_WAVE, 999);
break;
default:
WARNING("Y undefined command %d", p1);
break;
}
DEBUG_COMMAND("Y %d,%d:",p1,p2);
}
+18 -40
View File
@@ -389,9 +389,6 @@ static void set_stack_frame(StackFrame *frame, int page, int addr, boolean is_re
}
StackTrace *dbg_stack_trace(void) {
int stack_size;
const int *stack_base = sl_getStackInfo(&stack_size);
int page = nact->current_page;
int cap = 16;
@@ -399,26 +396,17 @@ StackTrace *dbg_stack_trace(void) {
set_stack_frame(&trace->frames[0], page, nact->current_addr, false);
trace->nr_frame = 1;
const int *p = stack_base + stack_size - 1;
while (p >= stack_base) {
int addr = -1;
switch (*p) {
case STACK_NEARJMP:
addr = p[-2];
break;
case STACK_FARJMP:
page = p[-2];
addr = p[-3];
break;
struct stack_frame_info *sfi = NULL;
while ((sfi = sl_next_stack_frame(sfi)) != NULL) {
if (sfi->tag != STACK_NEARCALL && sfi->tag != STACK_FARCALL)
continue;
if (trace->nr_frame >= cap) {
cap *= 2;
trace = realloc(trace, sizeof(StackTrace) + cap * sizeof(StackFrame));
}
if (addr >= 0) {
if (trace->nr_frame >= cap) {
cap *= 2;
trace = realloc(trace, sizeof(StackTrace) + cap * sizeof(StackFrame));
}
set_stack_frame(&trace->frames[trace->nr_frame++], page, addr, true);
}
p -= p[-1] + 2;
if (sfi->tag == STACK_FARCALL)
page = sfi->page;
set_stack_frame(&trace->frames[trace->nr_frame++], page, sfi->addr, true);
}
return trace;
@@ -439,26 +427,16 @@ static boolean should_continue_step(void) {
void dbg_stepout(void) {
// Set an internal breakpoint at the return address of current frame.
int stack_size;
const int *stack_base = sl_getStackInfo(&stack_size);
const int *p = stack_base + stack_size - 1;
while (p >= stack_base) {
int page, addr = -1;
switch (*p) {
case STACK_NEARJMP:
page = nact->current_page;
addr = p[-2];
break;
case STACK_FARJMP:
page = p[-2];
addr = p[-3];
break;
}
if (addr >= 0) {
internal_breakpoint = dbg_set_breakpoint(page, addr, true);
struct stack_frame_info *sfi = NULL;
while ((sfi = sl_next_stack_frame(sfi)) != NULL) {
switch (sfi->tag) {
case STACK_NEARCALL:
internal_breakpoint = dbg_set_breakpoint(nact->current_page, sfi->addr, true);
return;
case STACK_FARCALL:
internal_breakpoint = dbg_set_breakpoint(sfi->page, sfi->addr, true);
return;
}
p -= p[-1] + 2;
}
// No parent frame found, continue execution.
}
+78 -181
View File
@@ -30,169 +30,76 @@
#include "LittleEndian.h"
#include "dri.h"
/*
* static maethods
*/
static long getfilesize(FILE *fp);
static boolean filecheck (FILE *fp);
static void get_filemap(drifiles *d, FILE *fp);
static void get_fileptr(drifiles *d, FILE *fp, int disk);
/*
* Get file size of FILE
* fp: FILE pointer
* return: filesize in byte
*/
static long getfilesize(FILE *fp) {
static bool read_index(int disk, drifiles *d, FILE *fp) {
fseek(fp, 0L, SEEK_END);
return ftell(fp);
}
int filesize = ftell(fp);
/*
* Check whether dri file type or not
* fp: FILE pointer
* return: TRUE if it's dri file
*/
static boolean filecheck (FILE *fp) {
uint8_t b[6];
int mapsize, ptrsize;
long filesize;
/* get filesize / 256 */
filesize = (getfilesize(fp) + 255) >> 8;
/* read top 6bytes */
// Get ptrsize and mapsize
uint8_t hdr[6];
fseek(fp, 0L, SEEK_SET);
fread(b, 1, 6, fp);
/* get ptrsize and mapsize */
ptrsize = LittleEndian_get3B(b, 0);
mapsize = LittleEndian_get3B(b, 3) - ptrsize;
/* must lager than 0 */
if (ptrsize < 0 || mapsize < 0) return FALSE;
/* must smaller than filesize */
if (ptrsize > (int)filesize || mapsize > (int)filesize ) {
return FALSE;
if (fread(hdr, 6, 1, fp) != 1)
return false;
int ptrsize = LittleEndian_get3B(hdr, 0) << 8;
int mapsize = (LittleEndian_get3B(hdr, 3) << 8) - ptrsize;
if (ptrsize <= 0 || mapsize <= 0 || ptrsize + mapsize > filesize)
return false;
// Read the pointer table and the link table
uint8_t *ptbl = malloc(ptrsize + mapsize);
memcpy(ptbl, hdr, 6);
if (fread(ptbl + 6, ptrsize + mapsize - 6, 1, fp) != 1) {
free(ptbl);
return false;
}
return TRUE;
}
uint8_t *ltbl = ptbl + ptrsize;
/*
* Get file map
* d : drifile object
* fp: FILE object
*/
static void get_filemap(drifiles *d, FILE *fp) {
uint8_t b[6], *_b;
int mapsize, ptrsize, i;
/* read top 6bytes */
fseek(fp, 0L, SEEK_SET);
fread(b, 1, 6, fp);
/* get ptrsize and mapsize */
ptrsize = LittleEndian_get3B(b, 0);
mapsize = LittleEndian_get3B(b, 3) - ptrsize;
/* allocate read buffer */
_b = malloc(sizeof(char) * (mapsize << 8));
/* read filemap */
fseek(fp, ptrsize << 8L , SEEK_SET);
fread(_b, 256, mapsize, fp);
/* get max file number from mapdata */
d->maxfile = (mapsize << 8) / 3;
/* map of disk */
d->map_disk = malloc(sizeof(char ) * d->maxfile);
/* map of data in disk */
d->map_ptr = malloc(sizeof(short) * d->maxfile);
for (i = 0; i < d->maxfile; i++) {
/* map_disk[?] and map_ptr[?] are from 0 */
*(d->map_disk + i) = _b[i * 3] - 1;
*(d->map_ptr + i) = LittleEndian_getW(_b, i * 3 + 1) - 1;
// (Re)allocate the index buffers
int nr_files = mapsize / 3;
if (d->nr_files < nr_files) {
d->disk = realloc(d->disk, nr_files);
d->offset = realloc(d->offset, sizeof(uint32_t) * nr_files);
memset(d->disk + d->nr_files, 0, nr_files - d->nr_files);
memset(d->offset + d->nr_files, 0, sizeof(uint32_t) * (nr_files - d->nr_files));
d->nr_files = nr_files;
}
free(_b);
return;
}
/*
* Get data pointer in file
* d : drifile object
* fp : FILE object
* disk: no in drifile object
*/
static void get_fileptr(drifiles *d, FILE *fp, int disk) {
char b[6], *_b;
int ptrsize, filecnt, i;
/* read top 6bytes */
fseek(fp, 0L, SEEK_SET);
fread(b, 1, 6, fp);
/* get pinter size */
ptrsize = LittleEndian_get3B(b,0);
/* estimate file number in file */
filecnt = (ptrsize << 8) / 3;
/* allocate read buffer */
_b = malloc(sizeof(char) * (ptrsize << 8));
/* read pointers */
fseek(fp, 0L, SEEK_SET);
fread(_b, 256, ptrsize, fp);
/* allocate pointers buffer */
d->fileptr[disk] = calloc(filecnt, sizeof(int));
/* store pointers */
for (i = 0; i < filecnt - 1; i++) {
*(d->fileptr[disk] + i) = (LittleEndian_get3B(_b, i * 3 + 3) << 8);
// Parse the index
for (int i = 0; i < nr_files; i++) {
if (disk != ltbl[i * 3] - 1)
continue;
d->disk[i] = ltbl[i * 3];
int ptr = LittleEndian_getW(ltbl, i * 3 + 1);
d->offset[i] = LittleEndian_get3B(ptbl, ptr * 3) << 8;
}
free(_b);
return;
free(ptbl);
return true;
}
drifiles *dri_init(const char **file, int cnt, boolean use_mmap) {
drifiles *d = calloc(1, sizeof(drifiles));
FILE *fp;
int i;
boolean gotmap = FALSE;
#ifndef HAVE_MEMORY_MAPPED_FILE
use_mmap = FALSE;
#endif
for (i = 0; i < cnt; i++) {
if (file[i] == NULL) continue;
/* open check */
if (NULL == (fp = fopen(file[i], "rb"))) {
SYSERROR("File %s is not found", file[i]);
for (int i = 0; i < cnt; i++) {
if (!file[i])
continue;
FILE *fp = fopen(file[i], "rb");
if (!fp)
SYSERROR("%s: %s", file[i], strerror(errno));
if (!read_index(i, d, fp)) {
// Only errors in *A.ALD are fatal, because some games have
// dummy (invalid) *[B-Z].ALD files.
if (i == 0)
SYSERROR("%s: not an ALD file", file[i]);
WARNING("%s: not an ALD file", file[i]);
fclose(fp);
continue;
}
/* check is drifile or noe */
if (!filecheck(fp)) {
SYSERROR("File %s is not dri file", file[i]);
}
/* get file map */
if (!gotmap) {
get_filemap(d, fp);
gotmap = TRUE;
}
/* get pointer */
get_fileptr(d, fp, i);
/* copy filenme */
d->fnames[i] = strdup(file[i]);
/* close */
fclose(fp);
/* mmap */
if (use_mmap) {
mmap_t *m = map_file(file[i]);
if (!m) {
@@ -207,54 +114,44 @@ drifiles *dri_init(const char **file, int cnt, boolean use_mmap) {
return d;
}
/*
* Get data
* d : drifile object
* no: drifile no ( >= 0 )
* return: dridata obhect
*/
dridata *dri_getdata(drifiles *d, int no) {
if (no < 0 || no >= d->nr_files || !d->disk[no] || !d->offset[no])
return NULL;
int disk = d->disk[no] - 1;
uint8_t *data;
dridata *dfile;
int disk, ptr, dataptr, dataptr2, size;
/* check no is lager than files which contains */
if (no > d->maxfile) return NULL;
/* check disk & ptr are negative, if negative, file does not exist */
disk = d->map_disk[no];
ptr = d->map_ptr[no];
if (disk < 0 || ptr < 0) return NULL;
/* no file registered */
if (d->fileptr[disk] == NULL) return NULL;
/* get pointer in file and size */
dataptr = *(d->fileptr[disk] + ptr);
dataptr2 = *(d->fileptr[disk] + ptr + 1);
if (dataptr == 0 || dataptr2 == 0) return NULL;
/* get data top */
int ptr, size;
if (d->mmapped) {
data = d->mmap[disk]->addr + dataptr;
data = d->mmap[disk]->addr + d->offset[no];
ptr = LittleEndian_getDW(data, 0);
size = LittleEndian_getDW(data, 4);
} else {
int readsize = dataptr2 - dataptr;
FILE *fp;
data = malloc(sizeof(char) * readsize);
fp = fopen(d->fnames[disk], "rb");
fseek(fp, dataptr, SEEK_SET);
fread(data, 1, readsize, fp);
FILE *fp = fopen(d->fnames[disk], "rb");
if (!fp)
return NULL;
uint8_t entry_header[8];
fseek(fp, d->offset[no], SEEK_SET);
if (fread(entry_header, sizeof(entry_header), 1, fp) != 1) {
fclose(fp);
return NULL;
}
ptr = LittleEndian_getDW(entry_header, 0);
size = LittleEndian_getDW(entry_header, 4);
data = malloc(ptr + size);
memcpy(data, entry_header, sizeof(entry_header));
if (fread(data + sizeof(entry_header), ptr + size - sizeof(entry_header), 1, fp) != 1) {
free(data);
fclose(fp);
return NULL;
}
fclose(fp);
}
/* get real data and size */
ptr = LittleEndian_getDW(data, 0);
size = LittleEndian_getDW(data, 4);
dfile = calloc(1, sizeof(dridata));
dridata *dfile = calloc(1, sizeof(dridata));
dfile->data_raw = data; /* dri data header */
dfile->data = data + ptr; /* real data */
dfile->size = size;
dfile->name = data + 16;
dfile->a = d; /* archive file */
return dfile;
}
+6 -13
View File
@@ -28,21 +28,14 @@
#include "mmap.h"
#define DRIFILEMAX 255 /* maximum file number for one data type */
#define DRIDATAMAX 65535 /* maximum file number in one file */
struct _drifiles {
/* for mmap */
boolean mmapped;
mmap_t *mmap[DRIFILEMAX];
/* for file access */
char *fnames[DRIFILEMAX];
/* max file number in files */
int maxfile;
/* file mapping */
char *map_disk;
short *map_ptr;
/* pointers in file */
int *fileptr[DRIFILEMAX];
boolean mmapped;
mmap_t *mmap[DRIFILEMAX];
char *fnames[DRIFILEMAX];
int nr_files; // upper limit on how many files could be referenced by this archive
uint8_t *disk; // file numbers
uint32_t *offset; // offsets in file
};
typedef struct _drifiles drifiles;
+23 -4
View File
@@ -66,6 +66,8 @@ static void storeSaveName(GameResource *gr, int no, char *src) {
boolean initGameResourceFromDir(GameResource *gr, DIR *dir, struct dirent *(*p_readdir)(DIR *)) {
memset(gr, 0, sizeof(GameResource));
char *basename = NULL;
bool found_xsleep = false;
struct dirent* d;
while ((d = p_readdir(dir))) {
char *filename = d->d_name;
@@ -91,6 +93,10 @@ boolean initGameResourceFromDir(GameResource *gr, DIR *dir, struct dirent *(*p_r
switch (toupper(filename[len - 6])) {
case 'S':
storeDataName(gr, DRIFILE_SCO, dno, filename);
if (!basename) {
basename = strdup(filename);
basename[len - 5] = '\0';
}
break;
case 'G':
storeDataName(gr, DRIFILE_CG, dno, filename);
@@ -111,13 +117,26 @@ boolean initGameResourceFromDir(GameResource *gr, DIR *dir, struct dirent *(*p_r
storeDataName(gr, DRIFILE_BGM, dno, filename);
break;
}
} else if (strcasecmp(filename + 1, "sleep.asd") == 0) {
found_xsleep = true;
}
}
for (int i = 0; i < SAVE_MAXNUMBER; i++) {
char buf[] = "asleep.asd";
buf[0] = 'a' + i;
storeSaveName(gr, i, buf);
if (basename && !found_xsleep) {
char *buf = malloc(strlen(basename) + 6);
int a = basename[strlen(basename) - 1] == 'S' ? 'A' : 'a';
for (int i = 0; i < SAVE_MAXNUMBER; i++) {
sprintf(buf, "%s%c.asd", basename, a + i);
storeSaveName(gr, i, buf);
}
free(buf);
} else {
for (int i = 0; i < SAVE_MAXNUMBER; i++) {
char buf[] = "asleep.asd";
buf[0] = 'a' + i;
storeSaveName(gr, i, buf);
}
}
free(basename);
return (gr->cnt[DRIFILE_SCO] > 0) ? TRUE : FALSE;
}
+62 -43
View File
@@ -74,50 +74,69 @@ static struct dirent *mockReaddir(DIR *dir) {
}
static void initGameResourceFromDir_test(void) {
const char *files[] = {
"ADISK.ALD",
"FOOSB.ALD",
"foogz.ald",
"WA.ALD",
"unknownXA.ald",
"a.ald",
".ald",
"a",
"SYSTEM39.AIN",
"foo_WA.WAI",
"foo_BA.BGI",
"SACTEFAM.KLD",
"System39.ini",
"foo1.alk",
"0.alk",
".alk",
NULL
};
const char **dir = files;
GameResource gr;
ASSERT_TRUE(initGameResourceFromDir(&gr, (DIR *)&dir, mockReaddir));
ASSERT_EQUAL(gr.cnt[DRIFILE_SCO], 2);
ASSERT_STRCMP(gr.game_fname[DRIFILE_SCO][0], "ADISK.ALD");
ASSERT_STRCMP(gr.game_fname[DRIFILE_SCO][1], "FOOSB.ALD");
ASSERT_EQUAL(gr.cnt[DRIFILE_CG], 26);
ASSERT_STRCMP(gr.game_fname[DRIFILE_CG][25], "foogz.ald");
ASSERT_EQUAL(gr.cnt[DRIFILE_WAVE], 1);
ASSERT_STRCMP(gr.game_fname[DRIFILE_WAVE][0], "WA.ALD");
for (int i = 0; i < 26; i++) {
char buf[16];
sprintf(buf, "%csleep.asd", 'a' + i);
ASSERT_STRCMP(gr.save_fname[i], buf);
{
const char *files[] = {
"FOOSA.ALD",
"FOOSB.ALD",
"foogz.ald",
"WA.ALD",
"unknownXA.ald",
"a.ald",
".ald",
"a",
"SYSTEM39.AIN",
"foo_WA.WAI",
"foo_BA.BGI",
"SACTEFAM.KLD",
"System39.ini",
"foo1.alk",
"0.alk",
".alk",
NULL
};
const char **dir = files;
GameResource gr;
ASSERT_TRUE(initGameResourceFromDir(&gr, (DIR *)&dir, mockReaddir));
ASSERT_EQUAL(gr.cnt[DRIFILE_SCO], 2);
ASSERT_STRCMP(gr.game_fname[DRIFILE_SCO][0], "FOOSA.ALD");
ASSERT_STRCMP(gr.game_fname[DRIFILE_SCO][1], "FOOSB.ALD");
ASSERT_EQUAL(gr.cnt[DRIFILE_CG], 26);
ASSERT_STRCMP(gr.game_fname[DRIFILE_CG][25], "foogz.ald");
ASSERT_EQUAL(gr.cnt[DRIFILE_WAVE], 1);
ASSERT_STRCMP(gr.game_fname[DRIFILE_WAVE][0], "WA.ALD");
for (int i = 0; i < 26; i++) {
char buf[16];
sprintf(buf, "FOOS%c.asd", 'A' + i);
ASSERT_STRCMP(gr.save_fname[i], buf);
}
ASSERT_STRCMP(gr.save_path, ".");
ASSERT_STRCMP(gr.ain, "SYSTEM39.AIN");
ASSERT_STRCMP(gr.wai, "foo_WA.WAI");
ASSERT_STRCMP(gr.bgi, "foo_BA.BGI");
ASSERT_STRCMP(gr.sact01, "SACTEFAM.KLD");
ASSERT_STRCMP(gr.init, "System39.ini");
ASSERT_STRCMP(gr.alk[0], "0.alk");
ASSERT_STRCMP(gr.alk[1], "foo1.alk");
for (int i = 2; i < 10; i++)
ASSERT_NULL(gr.alk[i]);
}
{
const char *files[] = {
"ADISK.ALD",
"asleep.asd",
NULL
};
const char **dir = files;
GameResource gr;
ASSERT_TRUE(initGameResourceFromDir(&gr, (DIR *)&dir, mockReaddir));
ASSERT_EQUAL(gr.cnt[DRIFILE_SCO], 1);
ASSERT_STRCMP(gr.game_fname[DRIFILE_SCO][0], "ADISK.ALD");
for (int i = 0; i < 26; i++) {
char buf[16];
sprintf(buf, "%csleep.asd", 'a' + i);
ASSERT_STRCMP(gr.save_fname[i], buf);
}
}
ASSERT_STRCMP(gr.save_path, ".");
ASSERT_STRCMP(gr.ain, "SYSTEM39.AIN");
ASSERT_STRCMP(gr.wai, "foo_WA.WAI");
ASSERT_STRCMP(gr.bgi, "foo_BA.BGI");
ASSERT_STRCMP(gr.sact01, "SACTEFAM.KLD");
ASSERT_STRCMP(gr.init, "System39.ini");
ASSERT_STRCMP(gr.alk[0], "0.alk");
ASSERT_STRCMP(gr.alk[1], "foo1.alk");
for (int i = 2; i < 10; i++)
ASSERT_NULL(gr.alk[i]);
}
void gameresource_test(void) {
-4
View File
@@ -1,4 +0,0 @@
#define GT_TOSHIN2 "闘神都市Ⅱ for Win95 "
#define GT_RANCE4 "Rance4 -教団の遺産- For Win95 "
#define GT_RANCE3_ENG "Rance3"
#define GT_RANCE4_ENG "Rance4 -Legacy of the Sect- For Win95 "
+64
View File
@@ -0,0 +1,64 @@
/*
* Copyright (C) 2023 kichikuou <KichikuouChrome@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#include <string.h>
#include "hacks.h"
#include "system.h"
#include "nact.h"
#include "input.h"
// Game titles.
#define GT_TOSHIN2 "闘神都市Ⅱ for Win95 "
#define GT_RANCE4 "Rance4 -教団の遺産- For Win95 "
#define GT_RANCE4_V2 "RanceⅣ -教団の遺産- for Windows "
#define GT_RANCE3_ENG "Rance3"
#define GT_RANCE4_ENG "Rance4 -Legacy of the Sect- For Win95 "
/* defined by cmdy.c */
extern boolean Y3waitFlags;
void enable_hack_by_gameid(const char *gameid) {
if (!strcmp(gameid, "toushin2"))
nact->game = GAME_TT2;
else if (!strcmp(gameid, "rance3_eng"))
nact->game = GAME_RANCE3_ENG;
else if (!strcmp(gameid, "rance4_eng"))
nact->game = GAME_RANCE4_ENG;
else if (!strcmp(gameid, "rance4_v2"))
nact->game = GAME_RANCE4_V2;
else
sys_error("Unknown game id \"%s\"", gameid);
}
void enable_hack_by_title(const char *title_utf8) {
if (!strcmp(title_utf8, GT_RANCE4))
Y3waitFlags = KEYWAIT_NONCANCELABLE;
if (nact->game != GAME_UNKNOWN)
return;
if (!strcmp(title_utf8, GT_TOSHIN2))
nact->game = GAME_TT2;
else if (!strcmp(title_utf8, GT_RANCE4_V2))
nact->game = GAME_RANCE4_V2;
else if (!strcmp(title_utf8, GT_RANCE3_ENG))
nact->game = GAME_RANCE3_ENG;
else if (!strcmp(title_utf8, GT_RANCE4_ENG))
nact->game = GAME_RANCE4_ENG;
}
+14 -17
View File
@@ -1,8 +1,5 @@
/*
* sactbgm.h: SACT Music 関連
*
* Copyright (C) 1997-1998 Masaki Chikama (Wren) <chikama@kasumi.ipl.mech.nagoya-u.ac.jp>
* 1998- <masaki-c@is.aist-nara.ac.jp>
* Copyright (C) 2023 kichikuou <KichikuouChrome@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -19,19 +16,19 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
/* $Id: sactbgm.h,v 1.1 2003/04/22 16:29:52 chikama Exp $ */
#ifndef __SACTBGM_H__
#define __SACTBGM_H__
#ifndef __HACKS_H_
#define __HACKS_H_
extern int smus_check(int no);
extern int smus_getlength(int no);
extern int smus_getpos(int no);
extern int smus_play(int no, int time, int vol);
extern int smus_stop(int no, int time);
extern int smus_fade(int no, int time, int vol);
extern int smus_wait(int no, int timeout);
extern int smus_waitpos(int no, int index);
extern int smus_stopall(int time);
enum gameId {
GAME_UNKNOWN = 0,
GAME_TT2,
GAME_RANCE3_ENG,
GAME_RANCE4_ENG,
GAME_RANCE4_V2,
};
#endif /* __SACTBGM_H__ */
void enable_hack_by_gameid(const char *gameid);
void enable_hack_by_title(const char *game_title_utf8);
#endif // __HACKS_H_
+8 -6
View File
@@ -93,13 +93,15 @@ void msg_init() {
}
memset(msg.wininfo, 0, sizeof(msg.wininfo));
for (int i = 0; i < MSGWINMAX; i++) {
msg.wininfo[i].x = 100;
msg.wininfo[i].y = 300;
msg.wininfo[i].width = 400;
msg.wininfo[i].height = 90;
}
msg.winno = 1;
msg.win = &msg.wininfo[0];
msg.wininfo[0].x = 8;
msg.wininfo[0].y = 311;
msg.wininfo[0].width = 616;
msg.wininfo[0].height = 80;
msg.wininfo[0].save = TRUE;
msg.win = &msg.wininfo[1];
msg.wininfo[1].save = TRUE;
// Private variables
msgDecorateColor = 0;
+1 -1
View File
@@ -123,7 +123,7 @@ static int midi_unpause(void) {
}
static int midi_get_playing_info(midiplaystate *st) {
if (!mix_music) {
if (!mix_music || !Mix_PlayingMusic()) {
st->in_play = FALSE;
st->loc_ms = 0;
return OK;
+17 -88
View File
@@ -28,7 +28,7 @@
struct _musprvdat musprv;
int mus_init(int audio_buffer_size) {
musbgm_init();
musbgm_init(DRIFILE_BGM, 0);
muscd_init();
musmidi_init();
prv.pcm_valid = muspcm_init(audio_buffer_size) == OK;
@@ -37,70 +37,18 @@ int mus_init(int audio_buffer_size) {
void mus_exit(void) {
musbgm_exit();
if (prv.cd_valid) muscd_exit();
muscd_exit();
if (prv.midi_valid) musmidi_exit();
if (prv.pcm_valid) muspcm_exit();
}
void mus_reset(void) {
musbgm_reset();
if (prv.cd_valid) muscd_reset();
muscd_reset();
if (prv.midi_valid) musmidi_reset();
if (prv.pcm_valid) muspcm_reset();
}
/*
* cdrom の演奏開始
* track: トラック番号 (第一トラックは 1)
* loop : 繰り返し回数 (0の場合は無限)
*/
int mus_cdrom_start(int track, int loop) {
if (!prv.cd_valid) return NG;
return muscd_start(track, loop);
}
/*
* cdrom の演奏停止
*/
int mus_cdrom_stop() {
if (!prv.cd_valid) return NG;
return muscd_stop();
}
/*
* cdrom の演奏時間(track/min/sec/frame)の取得
* 停止している場合は NG が返る
*/
int mus_cdrom_get_playposition(int *t, int *m, int *s, int *f) {
if (!prv.cd_valid) return NG;
cd_time info;
if (muscd_getpos(&info) != OK)
return NG;
*t = info.t;
*m = info.m;
*s = info.s;
*f = info.f;
return OK;
}
/*
* cdrom の最大トラック数の取得
*
*/
int mus_cdrom_get_maxtrack() {
if (!prv.cd_valid) return 0;
return prv.cd_maxtrk;
}
/*
* CDROM の有効/無効 フラグの取得
* return: FALASE -> 無効
* TRUE -> 有効
*/
boolean mus_cdrom_get_state() {
return prv.cd_valid;
}
/*
* midi の演奏開始
* no : ファイル番号( no >= 1)
@@ -309,6 +257,13 @@ int mus_mixer_get_level(int device) {
return 0;
}
bool mus_mixer_set_level(int device, int level) {
if (device == MIX_PCM)
return muspcm_setvol(0, level);
WARNING("not implemented");
return false;
}
/*
* 指定のチャンネルに wave file をロード
* ch : channel (0-127)
@@ -321,6 +276,13 @@ int mus_wav_load(int ch, int num) {
return muspcm_load_no(ch + 1, num);
}
int mus_wav_load_data(int ch, uint8_t *buf, uint32_t len) {
if (!prv.pcm_valid) return NG;
if (ch < 0 || ch > 128) return NG;
return muspcm_load_data(ch + 1, buf, len);
}
/*
* 指定のチャンネルから wave file を破棄
* ch : channel
@@ -447,39 +409,6 @@ int mus_wav_load_lrsw(int ch, int num) {
return NG;
}
int mus_bgm_play(int no, int time, int vol) {
return musbgm_play(no, time, vol);
}
int mus_bgm_stop(int no, int time) {
return musbgm_stop(no, time);
}
int mus_bgm_stopall(int time) {
return musbgm_stopall(time);
}
int mus_bgm_fade(int no, int time, int vol) {
return musbgm_fade(no, time, vol);
}
int mus_bgm_getpos(int no) {
return musbgm_getpos(no);
}
int mus_bgm_getlength(int no) {
return musbgm_getlen(no);
}
int mus_bgm_wait(int no, int timeout) {
return musbgm_wait(no, timeout);
}
int mus_bgm_waitpos(int no, int index) {
WARNING("not implemented");
return NG;
}
int mus_vol_set_valance(int *vols, int num) {
WARNING("not implemented");
return NG;
+5 -18
View File
@@ -25,7 +25,9 @@
#define __MUSIC_CLIENT_H__
#include "portab.h"
#include "bgm.h"
#include "midi.h"
#include "music_cdrom.h"
enum MixDevice {
MIX_MASTER,
@@ -39,13 +41,6 @@ extern int mus_init(int audio_buffer_size);
extern void mus_exit(void);
extern void mus_reset(void);
/* cdrom related function */
extern int mus_cdrom_start(int track, int loop);
extern int mus_cdrom_stop(void);
extern int mus_cdrom_get_playposition(int *t, int *m, int *s, int *f);
extern int mus_cdrom_get_maxtrack(void);
extern boolean mus_cdrom_get_state(void);
/* midi related function */
extern int mus_midi_start(int no, int loop);
extern int mus_midi_stop(void);
@@ -70,9 +65,11 @@ extern int mus_mixer_fadeout_start(int device, int time, int volume, int stop);
extern boolean mus_mixer_fadeout_get_state(int device);
extern int mus_mixer_fadeout_stop(int device);
extern int mus_mixer_get_level(int device);
extern bool mus_mixer_set_level(int device, int level);
/* wav (command2F) related function */
/* wav (command2F) / ShSound related function */
extern int mus_wav_load(int ch, int num);
extern int mus_wav_load_data(int ch, uint8_t *buf, uint32_t len);
extern int mus_wav_unload(int ch);
extern int mus_wav_play(int ch, int loop);
extern int mus_wav_stop(int ch);
@@ -85,16 +82,6 @@ extern int mus_wav_waittime(int ch, int time);
extern int mus_wav_wavtime(int ch);
extern int mus_wav_load_lrsw(int ch, int num);
/* Music Stream */
extern int mus_bgm_play(int no, int time, int vol);
extern int mus_bgm_stop(int no, int time);
extern int mus_bgm_stopall(int time);
extern int mus_bgm_fade(int no, int time, int vol);
extern int mus_bgm_getpos(int no);
extern int mus_bgm_getlength(int no);
extern int mus_bgm_wait(int no, int timeout);
extern int mus_bgm_waitpos(int no, int index);
/* volume valaner */
extern int mus_vol_set_valance(int *vols, int num);
+56 -14
View File
@@ -25,52 +25,94 @@
#include <string.h>
#include "portab.h"
#include "ald_manager.h"
#include "music_private.h"
#include "music_cdrom.h"
#include "cdrom.h"
static char *dev = CDROM_DEVICE;
void muscd_set_devicename(char *name) {
if (0 == strcmp("none", name)) dev = NULL;
else dev = strdup(name);
}
int muscd_init(void) {
int st = cd_init(&prv.cddev);
if (st == -1) {
prv.cd_valid = FALSE;
return NG;
// In the download edition of Daiakuji, SS command plays music from *BA.ald.
if (ald_get_maxno(DRIFILE_BGM) > 0) {
prv.cddev = &cdrom_bgm;
} else {
prv.cddev = cd_init(dev);
if (!prv.cddev) {
return NG;
}
}
prv.cd_valid = TRUE;
prv.cddev->init(dev);
prv.cd_current_track = 0;
return OK;
}
int muscd_init_bgm(DRIFILETYPE type, int base_no) {
muscd_exit();
prv.cddev = &cdrom_bgm;
return musbgm_init(type, base_no);
}
int muscd_exit(void) {
if (prv.cd_valid) {
prv.cddev.exit();
if (prv.cddev) {
prv.cddev->exit();
prv.cddev = NULL;
}
return OK;
}
int muscd_reset(void) {
if (prv.cd_valid) {
prv.cddev.reset();
if (prv.cddev) {
prv.cddev->reset();
prv.cd_current_track = 0;
}
return OK;
}
int muscd_start(int trk, int loop) {
if (!prv.cddev)
return NG;
if (trk == prv.cd_current_track)
return OK;
prv.cddev.stop();
prv.cddev->stop();
prv.cddev.start(trk, loop);
prv.cddev->start(trk, loop);
prv.cd_current_track = trk;
return OK;
}
int muscd_stop(void) {
prv.cddev.stop();
if (!prv.cddev)
return NG;
prv.cddev->stop();
prv.cd_current_track = 0;
return OK;
}
int muscd_getpos(cd_time *tm) {
return prv.cddev.getpos(tm);
int muscd_getpos(int *t, int *m, int *s, int *f) {
if (!prv.cddev)
return NG;
cd_time info;
if (prv.cddev->getpos(&info) != OK)
return NG;
*t = info.t;
*m = info.m;
*s = info.s;
*f = info.f;
return OK;
}
int muscd_get_maxtrack(void) {
if (!prv.cddev)
return 0;
return prv.cd_maxtrk;
}
bool muscd_is_available(void) {
return prv.cddev;
}
+6 -2
View File
@@ -25,13 +25,17 @@
#define __MUSIC_CDROM_H__
#include "portab.h"
#include "cdrom.h"
#include "ald_manager.h"
void muscd_set_devicename(char *);
int muscd_init(void);
int muscd_init_bgm(DRIFILETYPE type, int base_no);
int muscd_exit(void);
int muscd_reset(void);
int muscd_start(int trk, int loop);
int muscd_stop(void);
int muscd_getpos(cd_time *tm);
int muscd_getpos(int *t, int *m, int *s, int *f);
int muscd_get_maxtrack(void);
bool muscd_is_available(void);
#endif /* __MUSIC_CDROM_H__ */
+2 -1
View File
@@ -29,6 +29,7 @@ extern int muspcm_exit(void);
extern int muspcm_reset(void);
extern int muspcm_load_no(int slot, int no);
extern int muspcm_load_mixlr(int slot, int noL, int noR);
extern int muspcm_load_data(int slot, uint8_t *buf, uint32_t len);
extern int muspcm_unload(int slot);
extern int muspcm_start(int slot, int loop);
extern int muspcm_stop(int slot);
@@ -36,7 +37,7 @@ extern int muspcm_fadeout(int slot, int msec);
extern int muspcm_pause(int slot);
extern int muspcm_unpause(int slot);
extern int muspcm_getpos(int slot);
extern int muspcm_setvol(int dev, int slot, int lv);
extern int muspcm_setvol(int slot, int lv);
extern int muspcm_getwavelen(int slot);
extern boolean muspcm_isplaying(int slot);
extern int muspcm_waitend(int slot);
+1 -2
View File
@@ -32,11 +32,10 @@
#include "ald_manager.h"
struct _musprvdat {
boolean cd_valid;
boolean midi_valid;
boolean pcm_valid;
cdromdevice_t cddev;
cdromdevice_t *cddev;
mididevice_t mididev;
// ゲーム内での volume 設定 (%値)
+5 -1
View File
@@ -32,6 +32,7 @@
#include "message.h"
#include "ags.h"
#include "utfsjis.h"
#include "hacks.h"
#define toUTF8(s) codeconv(UTF8, nact->encoding, s)
#define toSJIS(s) codeconv(SHIFT_JIS, nact->encoding, s)
@@ -108,7 +109,10 @@ typedef struct {
int patch_ec; /* see patch_ec command */
int patch_emen; /* see patch_emen command */
int patch_g0; /* see patch g0 command */
// For game-specific hacks.
enum gameId game;
/* ain 関連 */
S39AIN ain;
+1
View File
@@ -26,6 +26,7 @@ int muspcm_exit(void) { return NG; }
int muspcm_reset(void) { return NG; }
int muspcm_load_no(int slot, int no) { return NG; }
int muspcm_load_mixlr(int slot, int noL, int noR) { return NG; }
int muspcm_load_data(int slot, uint8_t *buf, uint32_t len) { return NG; }
int muspcm_unload(int slot) { return NG; }
int muspcm_start(int slot, int loop) { return NG; }
int muspcm_stop(int slot) { return NG; }
+5 -1
View File
@@ -40,6 +40,10 @@ EM_JS(int, muspcm_load_no, (int slot, int no), { // async
return xsystem35.audio.pcm_load(slot, no);
});
EM_JS(int, muspcm_load_data, (int slot, uint8_t *buf, uint32_t len), { // async
return xsystem35.audio.pcm_load_data(slot, buf, len);
});
EM_JS(int, muspcm_load_mixlr, (int slot, int noL, int noR), { // async
return xsystem35.audio.pcm_load_mixlr(slot, noL, noR);
});
@@ -74,7 +78,7 @@ EM_JS(int, muspcm_getpos, (int slot), {
return xsystem35.audio.pcm_getpos(slot);
});
EM_JS(int, muspcm_setvol, (int dev, int slot, int lv), {
EM_JS(int, muspcm_setvol, (int slot, int lv), {
return xsystem35.audio.pcm_setvol(slot, lv);
});
+31 -24
View File
@@ -34,7 +34,6 @@
#include "dri.h"
#include "music_pcm.h"
#include "music_private.h"
#include "pcm.sdlmixer.h"
#include "sdl_core.h"
#include "nact.h"
#include "LittleEndian.h"
@@ -63,7 +62,7 @@ static mmap_t *wai_map;
* 指定の番号の .WAV|.OGG をロードする。
* @param no: DRIファイル番号
*/
Mix_Chunk *pcm_sdlmixer_load(int no) {
static Mix_Chunk *load_asset(int no) {
dridata *dfile = ald_getdata(DRIFILE_WAVE, no -1);
if (dfile == NULL) {
WARNING("DRIFILE_WAVE fail to open %d", no -1);
@@ -81,6 +80,17 @@ Mix_Chunk *pcm_sdlmixer_load(int no) {
return chunk;
}
static int load_chunk(int slot, Mix_Chunk *chunk) {
if ((unsigned)slot >= PCM_SLOTS)
return NG;
if (slots[slot].chunk)
muspcm_unload(slot);
slots[slot].chunk = chunk;
return OK;
}
/**
* noL と noR の .WAV をロードし、左右合成
*
@@ -89,8 +99,8 @@ Mix_Chunk *pcm_sdlmixer_load(int no) {
* @return : 合成後の Mix_Chunk
*/
static Mix_Chunk *pcm_mixlr(int noL, int noR) {
Mix_Chunk *chunkL = pcm_sdlmixer_load(noL);
Mix_Chunk *chunkR = pcm_sdlmixer_load(noR);
Mix_Chunk *chunkL = load_asset(noL);
Mix_Chunk *chunkR = load_asset(noR);
if (chunkL == NULL || chunkR == NULL) {
if (chunkL)
Mix_FreeChunk(chunkL);
@@ -153,7 +163,7 @@ int muspcm_load_no(int slot, int no) {
if ((unsigned)slot >= PCM_SLOTS)
return NG;
Mix_Chunk *chunk = pcm_sdlmixer_load(no);
Mix_Chunk *chunk = load_asset(no);
if (chunk == NULL) {
return NG;
}
@@ -166,7 +176,7 @@ int muspcm_load_no(int slot, int no) {
prv.vol_pcm_sub[slot] = 0;
}
return pcm_sdlmixer_load_chunk(slot, chunk);
return load_chunk(slot, chunk);
}
int muspcm_load_mixlr(int slot, int noL, int noR) {
@@ -179,7 +189,18 @@ int muspcm_load_mixlr(int slot, int noL, int noR) {
return NG;
}
return pcm_sdlmixer_load_chunk(slot, chunk);
return load_chunk(slot, chunk);
}
int muspcm_load_data(int slot, uint8_t *buf, uint32_t len) {
if ((unsigned)slot >= PCM_SLOTS)
return NG;
Mix_Chunk *chunk = Mix_LoadWAV_RW(SDL_RWFromConstMem(buf, len), 1);
if (!chunk)
return NG;
return load_chunk(slot, chunk);
}
// PCMデータのメモリ上からのアンロード
@@ -197,17 +218,6 @@ int muspcm_unload(int slot) {
return OK;
}
int pcm_sdlmixer_load_chunk(int slot, Mix_Chunk *chunk) {
if ((unsigned)slot >= PCM_SLOTS)
return NG;
if (slots[slot].chunk)
muspcm_unload(slot);
slots[slot].chunk = chunk;
return OK;
}
// PCMデータを再生
int muspcm_start(int slot, int loop) {
if ((unsigned)slot >= PCM_SLOTS)
@@ -274,15 +284,12 @@ int muspcm_getpos(int slot) {
return pos;
}
// PCMオブジェクトに対してボリュームをセット
int muspcm_setvol(int dev, int slot, int lv) {
// Set the volume for a channel.
int muspcm_setvol(int slot, int lv) {
if ((unsigned)slot >= PCM_SLOTS)
return NG;
if (!slots[slot].chunk)
return NG;
Mix_VolumeChunk(slots[slot].chunk, lv * MIX_MAX_VOLUME / 100);
Mix_Volume(slot, lv * MIX_MAX_VOLUME / 100);
return OK;
}
-4
View File
@@ -1,4 +0,0 @@
#include <SDL_mixer.h>
extern int pcm_sdlmixer_load_chunk(int slot, Mix_Chunk *chunk);
extern Mix_Chunk *pcm_sdlmixer_load(int no);
+639 -443
View File
File diff suppressed because it is too large Load Diff
+26 -93
View File
@@ -24,105 +24,38 @@
#ifndef __SAVEDATA__
#define __SAVEDATA__
#ifdef __EMSCRIPTEN__
#include <emscripten.h>
#else
typedef int emscripten_align1_int;
#endif
#include "portab.h"
#include "windowframe.h"
#define SAVE_MAXNUMBER (26)
#define SAVE_MAXNUMBER 26
#define SAVE_SAVEERR (255)
#define SAVE_LOADERR (255)
#define SAVE_LOADSHORTAGE (254)
#define SAVE_OTHERERR (201)
#define SAVE_LOADOK (0)
#define SAVE_SAVEOK1 (1)
#define SAVE_SAVEOK0 (0)
#define SAVE_SAVEERR 255
#define SAVE_LOADERR 255
#define SAVE_LOADSHORTAGE 254
#define SAVE_OTHERERR 201
#define SAVE_LOADOK 0
#define SAVE_SAVEOK1 1
#define SAVE_SAVEOK0 0
#define SAVE_DATAID "System3.5 SavaData(c)ALICE-SOFT"
#define SAVE_DATAVERSION 0x350200
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
};
typedef struct {
uint16_t x;
uint16_t y;
uint16_t width;
uint16_t height;
} RectangleW;
typedef struct {
char ID[32];
int version;
char gameName[28];
uint8_t selMsgSize;
uint8_t selMsgColor;
uint8_t selBackColor;
uint8_t selFrameColor;
uint8_t msgMsgSize;
uint8_t msgMsgColor;
uint8_t msgBackColor;
uint8_t msgFrameColor;
uint8_t rsvB1;
uint8_t rsvB2;
uint8_t rsvB3;
uint8_t rsvB4;
uint8_t rsvB5;
uint8_t rsvB6;
uint8_t rsvB7;
uint8_t rsvB8;
int scoPage;
int scoIndex;
int rsvI1;
int rsvI2;
RectangleW selWinInfo[SELWINMAX];
RectangleW msgWinInfo[MSGWINMAX];
int stackinfo;
int varStr;
int rsvI3;
int rsvI4;
int varSys[256];
int rsvI[228];
} Ald_baseHdr;
typedef struct {
int size;
int count;
int maxlen;
int rsv1;
} Ald_strVarHdr;
typedef struct {
int size;
int rsv1;
int rsv2;
int rsv3;
} Ald_stackHdr;
typedef struct {
emscripten_align1_int size;
emscripten_align1_int pageNo;
emscripten_align1_int rsv1;
emscripten_align1_int rsv2;
} Ald_sysVarHdr;
/* defined by variable.c */
extern int strvar_len;
struct VarRef;
extern int save_loadAll(int no);
extern int save_saveAll(int no);
extern int save_loadPartial(int no, struct VarRef *vref, int cnt);
extern int save_savePartial(int no, struct VarRef *vref, int cnt);
extern int save_copyAll(int dstno, int srcno);
extern int save_vars_to_file(char *fname_utf8, struct VarRef *src, int cnt);
extern int load_vars_from_file(char *fname_utf8, struct VarRef *dest, int cnt);
extern int save_save_str_with_file(char *fname_utf8, int start, int cnt);
extern int save_load_str_with_file(char *fname_utf8, int start, int cnt);
extern uint8_t* load_cg_with_file(char *fname_utf8, int *status, long *filesize);
extern const char *save_get_file(int index);
extern int save_delete_file(int index);
int save_setFormat(const char *format_name);
int save_loadAll(int no);
int save_saveAll(int no);
int save_loadPartial(int no, struct VarRef *vref, int cnt);
int save_savePartial(int no, struct VarRef *vref, int cnt);
int save_copyAll(int dstno, int srcno);
int save_vars_to_file(char *fname_utf8, struct VarRef *src, int cnt);
int load_vars_from_file(char *fname_utf8, struct VarRef *dest, int cnt);
int save_strs_to_file(char *fname_utf8, int start, int cnt);
int load_strs_from_file(char *fname_utf8, int start, int cnt);
const char *save_get_file(int index);
int save_delete_file(int index);
#endif /* __SAVEDATA__ */
+600 -296
View File
File diff suppressed because it is too large Load Diff
+35 -20
View File
@@ -27,20 +27,31 @@
#include "portab.h"
#include "system.h"
enum save_format;
struct VarRef;
// Warning: changing these enum values will break savedata compatibility.
enum stack_frame_type {
STACK_NEARJMP = 1,
STACK_FARJMP = 2,
STACK_VARIABLE = 3,
STACK_DATA = 4
// Stack frame tags. Changing these will break savedata compatibility.
#define STACK_FARCALL 0xFF
#define STACK_NEARCALL 0xEE
#define STACK_VARIABLE 0xDD
#define STACK_TEXTCOLOR 0xCC
#define STACK_TEXTSIZE 0xBB
#define STACK_TEXTLOC 0xAA
struct stack_info {
int top_attr; // always zero?
int page_calls;
int label_calls;
int var_pushes;
int label_calls_after_page_call;
int var_pushes_after_call;
};
enum txx_type {
TxxTEXTCOLOR = 1,
TxxTEXTSIZE = 2,
TxxTEXTLOC = 3
struct stack_frame_info {
uint8_t tag;
uint16_t page; // STACK_FARCALL
int addr; // STACK_FARCALL or STACK_NEARCALL
uint8_t *p; // for internal use
};
// Use functions below instead of accessing these variables directly.
@@ -68,19 +79,23 @@ void sl_retNear(void);
void sl_callFar(int page);
void sl_callFar2(int page, int address);
void sl_retFar(void);
void sl_retFar2(void);
void sl_stackClear_allCall(void);
void sl_stackClear_labelCall(int cnt);
void sl_stackClear_pageCall(int cnt);
void sl_pushVar(struct VarRef *vref, int cnt);
void sl_popVar(struct VarRef *vref, int cnt);
int *sl_getStackInfo(int *size);
void sl_putStackInfo(int *data, int size);
void sl_pushData(int *data, int cnt);
void sl_popData(int *data, int cnt);
void sl_dropLabelCalls(int cnt);
void sl_dropPageCalls(int cnt);
void *sl_setDataTable(int page, int index);
void sl_returnGoto(int address);
void sl_clearStack(bool restore);
void sl_pushVar(struct VarRef *vref, int cnt);
void sl_popVar(struct VarRef *vref, int cnt);
uint8_t *sl_saveStack(enum save_format format, int *size);
void sl_loadStack(enum save_format format, uint8_t *data, int size);
void sl_getStackInfo(struct stack_info *info);
void sl_pushTextColor(uint8_t type, uint8_t color);
void sl_pushTextSize(uint8_t type, int size);
void sl_pushTextLoc(int x, int y);
void sl_popState(uint8_t expected_type);
struct stack_frame_info *sl_next_stack_frame(struct stack_frame_info *frame_info);
static inline int sl_getIndex(void) { return sl_index; }
static inline int sl_getPage(void) { return sl_page; }
static inline int sl_getc(void) { return sl_sco[sl_index++]; }
+4 -9
View File
@@ -233,16 +233,11 @@ void sdl_drawImage8_fromData(cgdata *cg, int dx, int dy, int sprite_color) {
sdl_pal_check();
if (sdl_dib->format->BitsPerPixel > 8 && cg->pal) {
int i, i_st = 0, i_end = 256;
SDL_Color *c = s->format->palette->colors;
uint8_t *r = cg->pal->red, *g = cg->pal->green, *b = cg->pal->blue;
if (cg->type == ALCG_VSP) {
i_st = (cg->vsp_bank << 4);
i_end = i_st + 16;
c += i_st;
}
for (i = i_st; i < i_end; i++) {
uint8_t *r = cg->pal->red;
uint8_t *g = cg->pal->green;
uint8_t *b = cg->pal->blue;
for (int i = 0; i < 256; i++) {
c->r = *(r++);
c->g = *(g++);
c->b = *(b++);
+17
View File
@@ -27,6 +27,9 @@
#include <stdlib.h>
#include <unistd.h>
#include <SDL.h>
#ifdef __EMSCRIPTEN__
#include <emscripten.h>
#endif
#include "portab.h"
#include "system.h"
@@ -91,6 +94,18 @@ void send_agsevent(int type, int code) {
#endif
}
// Improves map navigation of Rance4 v2. See also the function comment of
// rance4_Y3_IM_hack() in cmdy.c.
static void rance4v2_hack(void) {
// Do not wait for vsync while a mouse button or an arrow key is pressed.
if (mouseb ||
(RawKeyInfo[KEY_UP] || RawKeyInfo[KEY_PAD_8]) ||
(RawKeyInfo[KEY_DOWN] || RawKeyInfo[KEY_PAD_2]) ||
(RawKeyInfo[KEY_LEFT] || RawKeyInfo[KEY_PAD_4]) ||
(RawKeyInfo[KEY_RIGHT] || RawKeyInfo[KEY_PAD_6]))
nact->wait_vsync = FALSE;
}
/* Event処理 */
static void sdl_getEvent(void) {
static int cmd_count_of_prev_input = -1;
@@ -260,6 +275,8 @@ static void sdl_getEvent(void) {
cmd_count_of_prev_input = nact->cmd_count;
} else if (nact->cmd_count != cmd_count_of_prev_input) {
nact->wait_vsync = TRUE;
if (nact->game == GAME_RANCE4_V2)
rance4v2_hack();
}
if (m2b) {
+1 -1
View File
@@ -148,7 +148,7 @@ static void window_init(const char *render_driver) {
#else
Uint32 flags = SDL_WINDOW_RESIZABLE;
#endif
sdl_window = SDL_CreateWindow("XSystem3.5 Version "VERSION,
sdl_window = SDL_CreateWindow("XSystem35 Version "VERSION,
SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
SYS35_DEFAULT_WIDTH, SYS35_DEFAULT_HEIGHT,
flags);
+8 -6
View File
@@ -116,13 +116,15 @@ void sel_init() {
}
memset(sel.wininfo, 0, sizeof(sel.wininfo));
for (int i = 0; i < SELWINMAX; i++) {
sel.wininfo[i].x = 450;
sel.wininfo[i].y = 100;
sel.wininfo[i].width = 150;
sel.wininfo[i].height = 100;
}
sel.winno = 1;
sel.win = &sel.wininfo[0];
sel.wininfo[0].x = 464;
sel.wininfo[0].y = 80;
sel.wininfo[0].width = 160;
sel.wininfo[0].height = 160;
sel.wininfo[0].save = TRUE;
sel.win = &sel.wininfo[1];
sel.wininfo[1].save = TRUE;
/* 選択肢を登録中 */
sel.in_setting = FALSE;
+19 -16
View File
@@ -29,6 +29,10 @@
#include "variable.h"
#include "xsystem35.h"
// For some reasons, System3.9's initial system page size is 65537.
#define SYSVAR_MAX 65537
#define STRVAR_MAX 5000
#define SYSVARLONG_MAX 128
#define PAGE_MAX 256
@@ -48,9 +52,7 @@ struct VarPage varPage[PAGE_MAX];
double longVar[SYSVARLONG_MAX];
/* 文字列変数 */
static char **strVar;
/* 文字列変数の属性(最大,1つあたりの大きさ) */
int strvar_cnt;
int strvar_len;
static int strvar_cnt;
const char *v_name(int var) {
if (var < nact->ain.varnum)
@@ -103,18 +105,20 @@ int *v_ref_indexed(int var, int index, struct VarRef *ref) {
// DC command
bool v_allocatePage(int page, int size, bool saveflag) {
if (page <= 0 || page >= PAGE_MAX) { return false; }
if (page < 0 || page >= PAGE_MAX) { return false; }
if (size <= 0 || size > 65536) { return false; }
void *buf = varPage[page].value;
if (buf != NULL)
buf = realloc(buf, size * sizeof(int));
else
buf = calloc(size, sizeof(int));
if (!buf)
NOMEMERR();
varPage[page].value = buf;
if (page != 0) {
void *buf = varPage[page].value;
if (buf != NULL)
buf = realloc(buf, size * sizeof(int));
else
buf = calloc(size, sizeof(int));
if (!buf)
NOMEMERR();
varPage[page].value = buf;
}
varPage[page].size = size;
varPage[page].saveflag = saveflag;
@@ -154,7 +158,7 @@ void v_getPageStatus(int page, int *in_use, int *size) {
}
/* 文字列変数の再初期化 */
void svar_init(int max_index, int len) {
void svar_init(int max_index) {
for (int i = max_index + 1; i < strvar_cnt; i++) {
if (strVar[i])
free(strVar[i]);
@@ -166,7 +170,6 @@ void svar_init(int max_index, int len) {
for (int i = strvar_cnt; i <= max_index; i++)
strVar[i] = NULL;
strvar_cnt = max_index + 1;
strvar_len = len;
}
int svar_maxindex(void) {
@@ -178,7 +181,7 @@ void v_init(void) {
varPage[0].value = sysVar;
varPage[0].size = SYSVAR_MAX;
varPage[0].saveflag = true;
svar_init(STRVAR_MAX - 1, STRVAR_LEN);
svar_init(STRVAR_MAX - 1);
}
void v_reset(void) {
+1 -5
View File
@@ -27,10 +27,6 @@
#include <sys/types.h>
#include "portab.h"
#define SYSVAR_MAX 65536
#define STRVAR_MAX 5000
#define STRVAR_LEN 101
struct VarPage {
int size;
boolean saveflag;
@@ -67,7 +63,7 @@ static inline int *v_ref(int var, struct VarRef *ref) {
return v_ref_indexed(var, -1, ref);
}
void svar_init(int max_index, int len);
void svar_init(int max_index);
int svar_maxindex(void);
const char *svar_get(int no);
void svar_set(int no, const char *str);
+49 -29
View File
@@ -63,7 +63,7 @@
#include "sdl_core.h"
#include "menu.h"
#include "music.h"
#include "cdrom.h"
#include "music_cdrom.h"
#include "savedata.h"
#include "scenario.h"
#include "variable.h"
@@ -109,45 +109,47 @@ static void sys35_usage(boolean verbose) {
}
puts("Usage: xsystem35 [OPTIONS]\n");
puts("OPTIONS");
puts(" -gamefile file : set game resource file to 'file'");
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'");
puts(" -gamefile file : set game resource file to 'file'");
puts(" -game game : enable game-specific hacks");
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'");
puts(" -M? : select output midi methos");
puts(" -M? : select output midi methos");
#ifdef ENABLE_MIDI_SDLMIXER
puts(" -Me : SDL_mixer midi player");
puts(" -Me : SDL_mixer midi player");
#endif
#ifdef ENABLE_MIDI_RAWMIDI
puts(" -Mr : Raw Midi device");
puts(" -Mr : Raw Midi device");
#endif
#ifdef ENABLE_MIDI_SEQMIDI
puts(" -Ms? : Sequenceer device (?:devicenumber)");
puts(" -Ms? : Sequenceer device (?:devicenumber)");
#endif
#ifdef ENABLE_MIDI_PORTMIDI
puts(" -Mp? : ALSA (via PortMidi) (?:devicenumber)");
puts(" -Mp? : ALSA (via PortMidi) (?:devicenumber)");
#endif
puts(" -M0 : Disable MIDI output");
puts(" -M0 : Disable MIDI output");
puts(" -devjoy device : joystick device index (0-)");
puts(" -devjoy device : joystick device index (0-)");
puts(" -ttfont_mincho: set TrueType font for mincho");
puts(" -ttfont_gothic: set TrueType font for mincho");
puts(" -ttfont_mincho : set TrueType font for mincho");
puts(" -ttfont_gothic : set TrueType font for mincho");
#ifdef DEBUG
puts(" -debuglv # : debug level");
puts(" : 1: warings");
puts(" : 2: unimplemented commands");
puts(" : 5: command trace");
puts(" : 6: message trace");
puts(" -debuglv # : debug level");
puts(" : 1: warings");
puts(" : 2: unimplemented commands");
puts(" : 5: command trace");
puts(" : 6: message trace");
#endif
puts(" -noantialias : never use antialiased string");
puts(" -fullscreen : start with fullscreen");
puts(" -integerscale : use integer scaling when resizing");
puts(" -noimagecursor : disable image cursor");
puts(" -version : show version");
puts(" -h : show this message");
puts(" --help : show this message");
puts(" -noantialias : never use antialiased string");
puts(" -fullscreen : start with fullscreen");
puts(" -integerscale : use integer scaling when resizing");
puts(" -noimagecursor : disable image cursor");
puts(" -version : show version");
puts(" -h : show this message");
puts(" --help : show this message");
exit(1);
}
@@ -271,7 +273,7 @@ static void sys35_ParseOption(int *argc, char **argv) {
render_driver = argv[i + 1];
} else if (0 == strcmp(argv[i], "-devcd")) {
if (argv[i + 1] != NULL) {
cd_set_devicename(argv[i + 1]);
muscd_set_devicename(argv[i + 1]);
}
} else if (0 == strcmp(argv[i], "-devmidi")) {
if (argv[i + 1] != NULL) {
@@ -308,8 +310,16 @@ static void sys35_ParseOption(int *argc, char **argv) {
} else if (0 == strcmp(argv[i], "-version")) {
puts(VERSION);
exit(0);
} else if (0 == strcmp(argv[i], "-integerscale")) {
} else if (0 == strcmp(argv[i], "-integerscale")) {
sdl_setIntegerScaling(TRUE);
} else if (0 == strcmp(argv[i], "-game")) {
if (argv[i + 1] != NULL) {
enable_hack_by_gameid(argv[i + 1]);
}
} else if (0 == strcmp(argv[i], "-saveformat")) {
if (argv[i + 1] != NULL) {
save_setFormat(argv[i + 1]);
}
}
}
}
@@ -359,7 +369,7 @@ static void check_profile() {
/* CD-ROM device name の設定 */
param = get_profile("cdrom_device");
if (param) {
cd_set_devicename(param);
muscd_set_devicename(param);
}
/* joystick device name の設定 */
param = get_profile("joy_device");
@@ -394,6 +404,16 @@ static void check_profile() {
sdl_setIntegerScaling(TRUE);
}
}
/* enable game-specific hacks */
param = get_profile("game");
if (param) {
enable_hack_by_gameid(param);
}
/* Save file format */
param = get_profile("saveformat");
if (param) {
save_setFormat(param);
}
}
#ifdef HAVE_SIGACTION
BIN
View File
Binary file not shown.
+67
View File
@@ -0,0 +1,67 @@
MS FILE,"stack.adv":
const word STACK_TOP_ATTR = 0:
const word NUM_PAGE_CALLS = 1:
const word NUM_LABEL_CALLS = 2:
const word NUM_VAR_PUSHES = 3:
const word NUM_LABEL_CALLS_AFTER_PAGE_CALL = 4:
const word NUM_VAR_PUSHES_AFTER_CALL = 5:
!D01 : 1!
!D02 : 2!
!D03 : 3!
US D01, 3:
UG D02, 3:
~AssertEquals D02, 1, __LINE__:
~AssertEquals D03, 2, __LINE__:
~AssertEquals D04, 3, __LINE__:
UR D01:
~AssertEquals D01[STACK_TOP_ATTR], 0, __LINE__:
~AssertEquals D01[NUM_PAGE_CALLS], 1, __LINE__:
~AssertEquals D01[NUM_LABEL_CALLS], 0, __LINE__:
~AssertEquals D01[NUM_VAR_PUSHES], 0, __LINE__:
~TestGlobalReturnFromLocalFunc:
%0:
**TestGlobalReturnFromLocalFunc:
UR D01:
~AssertEquals D01[STACK_TOP_ATTR], 0, __LINE__:
~AssertEquals D01[NUM_PAGE_CALLS], 2, __LINE__:
~AssertEquals D01[NUM_LABEL_CALLS], 0, __LINE__:
~AssertEquals D01[NUM_LABEL_CALLS_AFTER_PAGE_CALL], 0, __LINE__:
\LocalFunc:
; Unreachable
~Fail __LINE__:
%0:
*LocalFunc:
UR D01:
~AssertEquals D01[STACK_TOP_ATTR], 0, __LINE__:
~AssertEquals D01[NUM_PAGE_CALLS], 2, __LINE__:
~AssertEquals D01[NUM_LABEL_CALLS], 1, __LINE__:
~AssertEquals D01[NUM_LABEL_CALLS_AFTER_PAGE_CALL], 1, __LINE__:
~NestedGlobalFunc:
%0: ; This returns from TestGlobalReturnFromLocalFunc!
**NestedGlobalFunc:
US D01, 20:
UR D01:
~AssertEquals D01[STACK_TOP_ATTR], 0, __LINE__:
~AssertEquals D01[NUM_PAGE_CALLS], 3, __LINE__:
~AssertEquals D01[NUM_LABEL_CALLS], 1, __LINE__:
~AssertEquals D01[NUM_LABEL_CALLS_AFTER_PAGE_CALL], 0, __LINE__:
~AssertEquals D01[NUM_VAR_PUSHES], 20, __LINE__:
~AssertEquals D01[NUM_VAR_PUSHES_AFTER_CALL], 20, __LINE__:
\NestedLocalFunc:
%0:
*NestedLocalFunc:
UR D01:
~AssertEquals D01[STACK_TOP_ATTR], 0, __LINE__:
~AssertEquals D01[NUM_PAGE_CALLS], 3, __LINE__:
~AssertEquals D01[NUM_LABEL_CALLS], 2, __LINE__:
~AssertEquals D01[NUM_LABEL_CALLS_AFTER_PAGE_CALL], 1, __LINE__:
~AssertEquals D01[NUM_VAR_PUSHES], 20, __LINE__:
~AssertEquals D01[NUM_VAR_PUSHES_AFTER_CALL], 0, __LINE__:
\0:
+1
View File
@@ -11,6 +11,7 @@
%#array.adv:
%#strvar.adv:
%#stack.adv:
HH0,tests_passed: ' tests passed' R
HH0,tests_failed: ' tests failed' R
+1
View File
@@ -3,6 +3,7 @@ test.adv
util.adv
array.adv
strvar.adv
stack.adv
#DLLHeader
ShString.HEL
BIN
View File
Binary file not shown.
+6
View File
@@ -27,3 +27,9 @@ const word FILE = 1:
' actual: "' X actual: '"'
R
%0:
**Fail line:
inc tests_failed:
'[FAIL] ' X FILE: ':' HH0,line:
R
%0:
+21 -1
View File
@@ -18,7 +18,27 @@
# フォントのアンチエイリアスを無効にする
#antialias: No
# ----------------------------------------------------------
# ------------------------------------------------------------
# ------------------------------------------------------------
# Enables game-specific hacks. Usually auto-detected, but must be
# specified for games with modified / translated titles.
#
# Possible values are: toushin2, rance3_eng, rance4_eng, rance4_v2.
#game: rance4_v2
# ------------------------------------------------------------
# ------------------------------------------------------------
# The format when writing save files.
# xsystem35 : default
# system36 : compatible with System3.5 v2 - System3.6
# system39 : compatible with System3.8 - System3.9
#saveformat: xsystem35
# ------------------------------------------------------------
# ------------------------------------------------------------
# CD-ROM のデバイス名