diff --git a/Cargo.toml b/Cargo.toml
index 593db8d..fd9b443 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -56,12 +56,10 @@ android = []
byteorder = "1.4"
case_insensitive_hashmap = "1.0.0"
chrono = { version = "0.4", default-features = false, features = ["clock", "std"] }
-#cpal = "0.14"
-cpal = { git = "https://github.com/doukutsu-rs/cpal", branch = "horizon" }
+cpal = { git = "https://github.com/doukutsu-rs/cpal", rev = "9d269d8724102404e73a61e9def0c0cbc921b676" }
directories = "3"
downcast = "0.11"
-#glutin = { git = "https://github.com/doukutsu-rs/glutin.git", rev = "8dd457b9adb7dbac7ade337246b6356c784272d9", optional = true, default_features = false, features = ["x11"] }
-glutin = { version = "0.30", optional = true, default_features = false, features = ["x11"] }
+glutin = { git = "https://github.com/doukutsu-rs/glutin.git", rev = "2dd95f042e6e090d36f577cbea125560dd99bd27", optional = true, default_features = false, features = ["x11"] }
imgui = "0.8"
image = { version = "0.24", default-features = false, features = ["png", "bmp"] }
itertools = "0.10"
@@ -86,8 +84,7 @@ strum_macros = "0.24"
# remove and replace when drain_filter is in stable
vec_mut_scan = "0.4"
webbrowser = { version = "0.8", optional = true }
-#winit = { git = "https://github.com/alula/winit.git", rev = "6acf76ff192dd8270aaa119b9f35716c03685f9f", optional = true, default_features = false, features = ["x11"] }
-winit = { version = "0.27", optional = true, default_features = false, features = ["x11"] }
+winit = { git = "https://github.com/doukutsu-rs/winit.git", rev = "878f206d19af01b0977277929eee5e32667453c0", optional = true, default_features = false, features = ["x11"] }
xmltree = "0.10"
[target.'cfg(target_os = "windows")'.dependencies]
diff --git a/app/.gitignore b/app/.gitignore
index bd3a20d..043795d 100644
--- a/app/.gitignore
+++ b/app/.gitignore
@@ -231,3 +231,4 @@ fabric.properties
!/gradle/wrapper/gradle-wrapper.jar
# End of https://www.toptal.com/developers/gitignore/api/androidstudio,gradle,android
+app/release/
\ No newline at end of file
diff --git a/app/app/build.gradle b/app/app/build.gradle
index 6bdca86..b0184d5 100644
--- a/app/app/build.gradle
+++ b/app/app/build.gradle
@@ -4,21 +4,23 @@ plugins {
}
android {
- compileSdkVersion 30
- buildToolsVersion "30.0.3"
- ndkVersion "22.1.7171670"
+ namespace "io.github.doukutsu_rs"
+ compileSdkVersion 33
+ buildToolsVersion "33.0.0"
+ ndkVersion "25.0.8775105"
defaultConfig {
applicationId "io.github.doukutsu_rs"
minSdkVersion 24
- targetSdkVersion 30
- versionCode 1
- versionName "1.0"
+ targetSdkVersion 33
+ versionCode 2
+ versionName "0.100.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
ndk {
abiFilters 'x86', 'arm64-v8a', 'armeabi-v7a'
+ stl = "c++_shared"
}
externalNativeBuild {
@@ -61,12 +63,10 @@ android {
}
dependencies {
- implementation 'com.android.support:support-annotations:28.0.0'
- implementation 'com.android.support:appcompat-v7:28.0.0'
- implementation 'com.android.support:design:28.0.0'
- implementation 'com.android.support.constraint:constraint-layout:2.0.1'
- implementation 'android.arch.navigation:navigation-fragment:1.0.0'
- implementation 'android.arch.navigation:navigation-ui:1.0.0'
+ implementation 'androidx.annotation:annotation:1.5.0'
+ implementation 'androidx.appcompat:appcompat:1.6.0'
+ implementation 'com.google.android.material:material:1.8.0-rc01'
+ implementation 'androidx.constraintlayout:constraintlayout:2.1.1'
}
println("cargo target: ${project.buildDir.getAbsolutePath()}/rust-target")
diff --git a/app/app/src/main/AndroidManifest.xml b/app/app/src/main/AndroidManifest.xml
index 8297b6e..d5a5a13 100644
--- a/app/app/src/main/AndroidManifest.xml
+++ b/app/app/src/main/AndroidManifest.xml
@@ -1,15 +1,25 @@
-
+
-
-
-
+
@@ -19,8 +29,10 @@
-
@@ -28,4 +40,4 @@
-
+
\ No newline at end of file
diff --git a/app/app/src/main/cpp/CMakeLists.txt b/app/app/src/main/cpp/CMakeLists.txt
index 8625d7b..f480dc3 100644
--- a/app/app/src/main/cpp/CMakeLists.txt
+++ b/app/app/src/main/cpp/CMakeLists.txt
@@ -1,8 +1,8 @@
# Sets the minimum version of CMake required to build your native library.
# This ensures that a certain set of CMake features is available to
# your build.
-
-cmake_minimum_required(VERSION 3.10)
+project(doukutsu-rs)
+cmake_minimum_required(VERSION 3.18)
# Copy shared STL files to Android Studio output directory so they can be
# packaged in the APK.
@@ -21,7 +21,7 @@ cmake_minimum_required(VERSION 3.10)
function(configure_shared_stl lib_path so_base)
message("Configuring STL ${so_base} for ${ANDROID_ABI}")
configure_file(
- "${ANDROID_NDK}/sources/cxx-stl/${lib_path}/libs/${ANDROID_ABI}/lib${so_base}.so"
+ "${ANDROID_NDK}/toolchains/llvm/prebuilt/${ANDROID_HOST_TAG}/sysroot/usr/lib/${CMAKE_LIBRARY_ARCHITECTURE}/lib${so_base}.so"
"${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/lib${so_base}.so"
COPYONLY)
endfunction()
@@ -50,4 +50,4 @@ endif()
# and CMake builds them for you. When you build your app, Gradle
# automatically packages shared libraries with your APK.
-#add_library(dummy SHARED dummy.cpp)
+add_library(dummy SHARED dummy.cpp)
diff --git a/app/app/src/main/java/io/github/doukutsu_rs/DoukutsuDocumentsProvider.java b/app/app/src/main/java/io/github/doukutsu_rs/DoukutsuDocumentsProvider.java
index 01fe368..d06b8fc 100644
--- a/app/app/src/main/java/io/github/doukutsu_rs/DoukutsuDocumentsProvider.java
+++ b/app/app/src/main/java/io/github/doukutsu_rs/DoukutsuDocumentsProvider.java
@@ -3,6 +3,7 @@ package io.github.doukutsu_rs;
import android.database.Cursor;
import android.database.MatrixCursor;
import android.database.MatrixCursor.RowBuilder;
+import android.os.Build;
import android.os.CancellationSignal;
import android.os.ParcelFileDescriptor;
import android.provider.DocumentsContract.Document;
@@ -17,6 +18,8 @@ import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.file.Files;
+import static android.os.Build.VERSION.SDK_INT;
+
public class DoukutsuDocumentsProvider extends DocumentsProvider {
private final static String[] DEFAULT_ROOT_PROJECTION =
new String[]{
@@ -187,7 +190,13 @@ public class DoukutsuDocumentsProvider extends DocumentsProvider {
File newPath = new File(file.getParentFile().getAbsolutePath() + "/" + displayName);
try {
- Files.move(file.toPath(), newPath.toPath());
+ if (SDK_INT >= Build.VERSION_CODES.O) {
+ Files.move(file.toPath(), newPath.toPath());
+ } else {
+ if (!file.renameTo(newPath)) {
+ throw new IOException("Couldn't rename file: " + file.getAbsolutePath());
+ }
+ }
} catch (IOException e) {
throw new FileNotFoundException(e.getMessage());
}
@@ -205,8 +214,18 @@ public class DoukutsuDocumentsProvider extends DocumentsProvider {
File[] files = file.listFiles();
if (files != null) {
for (File f : files) {
- if (!Files.isSymbolicLink(f.toPath())) {
- deleteRecursive(f);
+ if (SDK_INT >= Build.VERSION_CODES.O) {
+ if (!Files.isSymbolicLink(f.toPath())) {
+ deleteRecursive(f);
+ }
+ } else {
+ try {
+ if (!f.getAbsolutePath().equals(f.getCanonicalPath())) {
+ deleteRecursive(f);
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
}
}
}
diff --git a/app/app/src/main/java/io/github/doukutsu_rs/DownloadActivity.java b/app/app/src/main/java/io/github/doukutsu_rs/DownloadActivity.java
index 0a1c873..595cc98 100644
--- a/app/app/src/main/java/io/github/doukutsu_rs/DownloadActivity.java
+++ b/app/app/src/main/java/io/github/doukutsu_rs/DownloadActivity.java
@@ -2,7 +2,7 @@ package io.github.doukutsu_rs;
import android.content.Intent;
import android.os.Bundle;
-import android.support.v7.app.AppCompatActivity;
+import androidx.appcompat.app.AppCompatActivity;
import android.widget.ProgressBar;
import android.widget.TextView;
diff --git a/app/app/src/main/res/layout/activity_download.xml b/app/app/src/main/res/layout/activity_download.xml
index 4f29a5f..97f1db2 100644
--- a/app/app/src/main/res/layout/activity_download.xml
+++ b/app/app/src/main/res/layout/activity_download.xml
@@ -1,5 +1,6 @@
-
-
+
\ No newline at end of file
diff --git a/app/build.gradle b/app/build.gradle
index 6a8063d..079dfea 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -2,13 +2,13 @@
buildscript {
repositories {
google()
- jcenter()
+ mavenCentral()
maven {
url "https://plugins.gradle.org/m2/"
}
}
dependencies {
- classpath "com.android.tools.build:gradle:4.2.0"
+ classpath "com.android.tools.build:gradle:7.4.0"
classpath "gradle.plugin.com.github.willir.rust:plugin:0.3.4"
// NOTE: Do not place your application dependencies here; they belong
@@ -19,7 +19,7 @@ buildscript {
allprojects {
repositories {
google()
- jcenter()
+ mavenCentral()
}
}
diff --git a/app/gradle/wrapper/gradle-wrapper.properties b/app/gradle/wrapper/gradle-wrapper.properties
index bb9bece..5c2f040 100644
--- a/app/gradle/wrapper/gradle-wrapper.properties
+++ b/app/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
#Wed Feb 17 23:16:31 CET 2021
distributionBase=GRADLE_USER_HOME
-distributionUrl=https\://services.gradle.org/distributions/gradle-6.7.1-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip
distributionPath=wrapper/dists
zipStorePath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
diff --git a/drsandroid/Cargo.toml b/drsandroid/Cargo.toml
index 348588a..7b8ad81 100644
--- a/drsandroid/Cargo.toml
+++ b/drsandroid/Cargo.toml
@@ -4,6 +4,10 @@ description = "doukutsu-rs targeted for Android"
version = "0.1.0"
edition = "2021"
+[profile.release]
+opt-level = 3
+incremental = true
+
[lib]
crate-type = ["cdylib"]
diff --git a/drsandroid/src/lib.rs b/drsandroid/src/lib.rs
index 2b0addc..095fc7a 100644
--- a/drsandroid/src/lib.rs
+++ b/drsandroid/src/lib.rs
@@ -3,5 +3,5 @@
pub fn android_main() {
let options = doukutsu_rs::game::LaunchOptions { server_mode: false, editor: false };
- doukutsu_rs::init(options).unwrap();
+ doukutsu_rs::game::init(options).unwrap();
}
diff --git a/src/engine_constants/mod.rs b/src/engine_constants/mod.rs
index 517c04b..5514f5c 100644
--- a/src/engine_constants/mod.rs
+++ b/src/engine_constants/mod.rs
@@ -308,7 +308,7 @@ impl GamepadConsts {
base,
Rect::new(base.left + 64, base.top, base.right + 64, base.bottom),
Rect::new(base.left + 128, base.top, base.right + 128, base.bottom),
- Rect::new(base.left + 192, base.top, base.right + 192, base.bottom),
+ Rect::new(base.left + 64, base.top + 128, base.right + 64, base.bottom + 128),
]
}
}
diff --git a/src/framework/backend_glutin.rs b/src/framework/backend_glutin.rs
index 8c7e44b..40fb991 100644
--- a/src/framework/backend_glutin.rs
+++ b/src/framework/backend_glutin.rs
@@ -10,7 +10,8 @@ use glutin::event_loop::{ControlFlow, EventLoop};
use glutin::window::WindowBuilder;
use imgui::{DrawCmdParams, DrawData, DrawIdx, DrawVert};
-use crate::{Game, GAME_SUSPENDED};
+use crate::game::Game;
+use crate::game::GAME_SUSPENDED;
use crate::common::Rect;
use crate::framework::backend::{Backend, BackendEventLoop, BackendRenderer, BackendTexture, SpriteBatchCommand};
use crate::framework::context::Context;
@@ -112,18 +113,21 @@ fn request_android_redraw() {
#[cfg(target_os = "android")]
fn get_insets() -> GameResult<(f32, f32, f32, f32)> {
unsafe {
+ use jni::objects::JObject;
+ use jni::JavaVM;
+
let vm_ptr = ndk_glue::native_activity().vm();
- let vm = unsafe { jni::JavaVM::from_raw(vm_ptr) }?;
+ let vm = JavaVM::from_raw(vm_ptr)?;
let vm_env = vm.attach_current_thread()?;
//let class = vm_env.find_class("io/github/doukutsu_rs/MainActivity")?;
- let class = vm_env.new_global_ref(ndk_glue::native_activity().activity())?;
+ let class = vm_env.new_global_ref(JObject::from_raw(ndk_glue::native_activity().activity()))?;
let field = vm_env.get_field(class.as_obj(), "displayInsets", "[I")?.to_jni().l as jni::sys::jintArray;
let mut elements = [0; 4];
vm_env.get_int_array_region(field, 0, &mut elements)?;
- vm_env.delete_local_ref(field.into());
+ vm_env.delete_local_ref(JObject::from_raw(field));
Ok((elements[0] as f32, elements[1] as f32, elements[2] as f32, elements[3] as f32))
}
diff --git a/src/framework/backend_horizon.rs b/src/framework/backend_horizon.rs
index d2f7cc7..4b47ed1 100644
--- a/src/framework/backend_horizon.rs
+++ b/src/framework/backend_horizon.rs
@@ -293,8 +293,8 @@ pub struct HorizonEventLoop {
const GAMEPAD_KEYMAP: [Button; 16] = [
Button::South,
Button::East,
- Button::North,
Button::West,
+ Button::North,
Button::LeftStick,
Button::RightStick,
Button::LeftShoulder,
@@ -351,6 +351,14 @@ impl HorizonEventLoop {
let button = GAMEPAD_KEYMAP[i];
let mask = 1 << i;
+ if i == 8 {
+ ctx.gamepad_context.set_axis_value(id as u32, Axis::TriggerLeft, if buttons_down & mask != 0 { 1.0 } else { 0.0 });
+ continue;
+ } else if i == 9 {
+ ctx.gamepad_context.set_axis_value(id as u32, Axis::TriggerRight, if buttons_down & mask != 0 { 1.0 } else { 0.0 });
+ continue;
+ }
+
if buttons_down & mask != 0 {
ctx.gamepad_context.set_button(id as u32, button, true);
}
@@ -363,10 +371,11 @@ impl HorizonEventLoop {
let analog_x = pad.sticks[0].x as f64 / 32768.0;
let analog_y = -pad.sticks[0].y as f64 / 32768.0;
- ctx.gamepad_context.set_axis_value(id as u32, Axis::LeftX, analog_x.clamp(0.0, 1.0));
- ctx.gamepad_context.set_axis_value(id as u32, Axis::LeftY, analog_y.clamp(0.0, 1.0));
- ctx.gamepad_context.set_axis_value(id as u32, Axis::RightX, (-analog_x).clamp(0.0, 1.0));
- ctx.gamepad_context.set_axis_value(id as u32, Axis::RightY, (-analog_y).clamp(0.0, 1.0));
+ ctx.gamepad_context.set_axis_value(id as u32, Axis::LeftX, (analog_x).clamp(-1.0, 1.0));
+ ctx.gamepad_context.set_axis_value(id as u32, Axis::LeftY, (analog_y).clamp(-1.0, 1.0));
+ ctx.gamepad_context.set_axis_value(id as u32, Axis::RightX, (analog_x).clamp(-1.0, 1.0));
+ ctx.gamepad_context.set_axis_value(id as u32, Axis::RightY, (analog_y).clamp(-1.0, 1.0));
+ ctx.gamepad_context.update_axes(id as u32);
}
}
}
diff --git a/src/game/settings.rs b/src/game/settings.rs
index 437ee57..044f838 100644
--- a/src/game/settings.rs
+++ b/src/game/settings.rs
@@ -527,12 +527,12 @@ pub fn player_default_controller_button_map() -> PlayerControllerButtonMap {
down: PlayerControllerInputType::Either(Button::DPadDown, Axis::LeftY, AxisDirection::Down),
prev_weapon: PlayerControllerInputType::ButtonInput(Button::LeftShoulder),
next_weapon: PlayerControllerInputType::ButtonInput(Button::RightShoulder),
- jump: PlayerControllerInputType::ButtonInput(Button::South),
- shoot: PlayerControllerInputType::ButtonInput(Button::West),
- skip: PlayerControllerInputType::AxisInput(Axis::TriggerLeft, AxisDirection::Either),
+ jump: PlayerControllerInputType::ButtonInput(Button::East),
+ shoot: PlayerControllerInputType::ButtonInput(Button::South),
+ skip: PlayerControllerInputType::ButtonInput(Button::West),
strafe: PlayerControllerInputType::AxisInput(Axis::TriggerRight, AxisDirection::Either),
- inventory: PlayerControllerInputType::ButtonInput(Button::North),
- map: PlayerControllerInputType::ButtonInput(Button::East),
+ inventory: PlayerControllerInputType::ButtonInput(Button::West),
+ map: PlayerControllerInputType::ButtonInput(Button::North),
menu_ok: PlayerControllerInputType::ButtonInput(Button::South),
menu_back: PlayerControllerInputType::ButtonInput(Button::East),
}
diff --git a/src/input/touch_player_controller.rs b/src/input/touch_player_controller.rs
index f86ee29..b990380 100644
--- a/src/input/touch_player_controller.rs
+++ b/src/input/touch_player_controller.rs
@@ -291,8 +291,7 @@ impl PlayerController for TouchPlayerController {
}
fn skip(&self) -> bool {
- // TODO
- false
+ self.state.inventory()
}
fn strafe(&self) -> bool {
@@ -341,8 +340,7 @@ impl PlayerController for TouchPlayerController {
}
fn trigger_skip(&self) -> bool {
- // TODO
- false
+ self.trigger.inventory()
}
fn trigger_strafe(&self) -> bool {
diff --git a/src/menu/settings_menu.rs b/src/menu/settings_menu.rs
index ff3ae59..5393e91 100644
--- a/src/menu/settings_menu.rs
+++ b/src/menu/settings_menu.rs
@@ -48,8 +48,8 @@ impl Default for MainMenuEntry {
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
enum GraphicsMenuEntry {
- WindowMode,
VSyncMode,
+ WindowMode,
LightingEffects,
WeaponLightCone,
ScreenShake,
@@ -63,7 +63,7 @@ enum GraphicsMenuEntry {
impl Default for GraphicsMenuEntry {
fn default() -> Self {
- GraphicsMenuEntry::WindowMode
+ GraphicsMenuEntry::VSyncMode
}
}
@@ -182,19 +182,6 @@ impl SettingsMenu {
}
pub fn init(&mut self, state: &mut SharedGameState, ctx: &mut Context) -> GameResult {
- #[cfg(not(target_os = "android"))]
- self.graphics.push_entry(
- GraphicsMenuEntry::WindowMode,
- MenuEntry::Options(
- state.loc.t("menus.options_menu.graphics_menu.window_mode.entry").to_owned(),
- state.settings.window_mode as usize,
- vec![
- state.loc.t("menus.options_menu.graphics_menu.window_mode.windowed").to_owned(),
- state.loc.t("menus.options_menu.graphics_menu.window_mode.fullscreen").to_owned(),
- ],
- ),
- );
-
self.graphics.push_entry(
GraphicsMenuEntry::VSyncMode,
MenuEntry::DescriptiveOptions(
@@ -216,6 +203,18 @@ impl SettingsMenu {
],
),
);
+ #[cfg(not(all(target_os = "android", target_os = "horizon")))]
+ self.graphics.push_entry(
+ GraphicsMenuEntry::WindowMode,
+ MenuEntry::Options(
+ state.loc.t("menus.options_menu.graphics_menu.window_mode.entry").to_owned(),
+ state.settings.window_mode as usize,
+ vec![
+ state.loc.t("menus.options_menu.graphics_menu.window_mode.windowed").to_owned(),
+ state.loc.t("menus.options_menu.graphics_menu.window_mode.fullscreen").to_owned(),
+ ],
+ ),
+ );
self.graphics.push_entry(
GraphicsMenuEntry::LightingEffects,
MenuEntry::Toggle(
diff --git a/src/sound/mod.rs b/src/sound/mod.rs
index 8e42d8e..73a4aab 100644
--- a/src/sound/mod.rs
+++ b/src/sound/mod.rs
@@ -4,7 +4,6 @@ use std::str::FromStr;
use std::sync::mpsc;
use std::sync::mpsc::{Receiver, Sender};
-use cpal::Sample;
use cpal::traits::{DeviceTrait, HostTrait, StreamTrait};
#[cfg(feature = "ogg-playback")]
use lewton::inside_ogg::OggStreamReader;
@@ -123,9 +122,17 @@ impl SoundManager {
let config = config_result.unwrap();
let res = match config.sample_format() {
- cpal::SampleFormat::F32 => run::(rx, soundbank.to_owned(), device, config.into()),
+ cpal::SampleFormat::I8 => run::(rx, soundbank.to_owned(), device, config.into()),
cpal::SampleFormat::I16 => run::(rx, soundbank.to_owned(), device, config.into()),
+ cpal::SampleFormat::I32 => run::(rx, soundbank.to_owned(), device, config.into()),
+ cpal::SampleFormat::I64 => run::(rx, soundbank.to_owned(), device, config.into()),
+ cpal::SampleFormat::U8 => run::(rx, soundbank.to_owned(), device, config.into()),
cpal::SampleFormat::U16 => run::(rx, soundbank.to_owned(), device, config.into()),
+ cpal::SampleFormat::U32 => run::(rx, soundbank.to_owned(), device, config.into()),
+ cpal::SampleFormat::U64 => run::(rx, soundbank.to_owned(), device, config.into()),
+ cpal::SampleFormat::F32 => run::(rx, soundbank.to_owned(), device, config.into()),
+ cpal::SampleFormat::F64 => run::(rx, soundbank.to_owned(), device, config.into()),
+ _ => Err(AudioError("Unsupported sample format.".to_owned())),
};
if let Err(res) = &res {
@@ -584,7 +591,7 @@ fn run(
config: cpal::StreamConfig,
) -> GameResult
where
- T: cpal::Sample,
+ T: cpal::SizedSample + cpal::FromSample,
{
let sample_rate = config.sample_rate.0 as f32;
let channels = config.channels as usize;
@@ -821,8 +828,8 @@ fn run(
) as u16
^ 0x8000;
- frame[0] = Sample::from::(&sample_l);
- frame[1] = Sample::from::(&sample_r);
+ frame[0] = T::from_sample(sample_l);
+ frame[1] = T::from_sample(sample_r);
} else {
let sample = clamp(
((((bgm_sample_l ^ 0x8000) as i16) + ((bgm_sample_r ^ 0x8000) as i16)) as f32 * bgm_vol / 2.0)
@@ -833,11 +840,12 @@ fn run(
) as u16
^ 0x8000;
- frame[0] = Sample::from::(&sample);
+ frame[0] = T::from_sample(sample);
}
}
},
err_fn,
+ None
);
if stream_result.is_err() {