mirror of
https://github.com/philj56/gbcc-android.git
synced 2024-11-26 23:00:23 +00:00
Various cleanup and bug fixes.
- Remove hard-coded paths to emulator assets - instead, the app now `chdir()`s into the correct folder before starting the core emulator. - Replace all `findViewById()` calls with auto-generated variables. - Fix a potential crash from not re-initialising the window if the EGL context is lost for some reason.
This commit is contained in:
parent
edf493fa46
commit
5e8dc627bb
1
app/.gitignore
vendored
1
app/.gitignore
vendored
@ -1,2 +1,3 @@
|
||||
/build
|
||||
/release
|
||||
/debug
|
||||
|
@ -11,8 +11,8 @@ android {
|
||||
applicationId "com.philj56.gbcc"
|
||||
minSdkVersion 21
|
||||
targetSdkVersion 29
|
||||
versionCode 13
|
||||
versionName "beta13"
|
||||
versionCode 14
|
||||
versionName "beta14"
|
||||
archivesBaseName = "gbcc"
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
externalNativeBuild {
|
||||
|
@ -6,9 +6,19 @@
|
||||
android:glEsVersion="0x00030000"
|
||||
android:required="true" />
|
||||
|
||||
<!-- Hardware features -->
|
||||
<uses-feature
|
||||
android:name="android.hardware.audio.low_latency"
|
||||
android:required="false" />
|
||||
<uses-feature
|
||||
android:name="android.hardware.camera"
|
||||
android:required="false" />
|
||||
<uses-feature
|
||||
android:name="android.hardware.camera.any"
|
||||
android:required="false" />
|
||||
<uses-feature
|
||||
android:name="android.hardware.sensor.accelerometer"
|
||||
android:required="false" />
|
||||
|
||||
<uses-permission
|
||||
android:name="android.permission.VIBRATE" />
|
||||
@ -25,20 +35,27 @@
|
||||
android:roundIcon="@mipmap/ic_launcher_round"
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/AppThemeDayNight">
|
||||
|
||||
<activity android:name=".GLActivity"
|
||||
android:parentActivityName="MainActivity"
|
||||
android:theme="@style/AppThemeDayNight.NoActionBar"/>
|
||||
android:theme="@style/AppThemeDayNight.Fullscreen"/>
|
||||
|
||||
<activity android:name=".SettingsActivity"
|
||||
android:parentActivityName="MainActivity"
|
||||
android:label="@string/settings_title"
|
||||
android:theme="@style/SettingsThemeDayNight"/>
|
||||
|
||||
<activity android:name=".ArrangeActivity"
|
||||
android:parentActivityName=".SettingsActivity"/>
|
||||
android:parentActivityName=".SettingsActivity"
|
||||
android:theme="@style/AppThemeDayNight.Fullscreen"/>
|
||||
|
||||
<activity android:name=".LicenseListActivity"
|
||||
android:parentActivityName=".SettingsActivity"
|
||||
android:label="@string/license_title"/>
|
||||
|
||||
<activity android:name=".LicenseActivity"
|
||||
android:parentActivityName=".LicenseListActivity"/>
|
||||
|
||||
<activity android:name=".MainActivity"
|
||||
android:theme="@style/AppThemeDayNight.NoActionBar">
|
||||
<intent-filter>
|
||||
|
@ -25,10 +25,10 @@ set(GBCC_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../../libs/gbcc)
|
||||
include_directories(${GBCC_DIR}/src)
|
||||
|
||||
add_definitions(
|
||||
-DPRINTER_SOUND_PATH="/data/user/0/com.philj56.gbcc/files/print.wav"
|
||||
-DTILESET_PATH="/data/user/0/com.philj56.gbcc/files/tileset.png"
|
||||
-DCAMERA_PATH="/data/user/0/com.philj56.gbcc/files/camera.png"
|
||||
-DSHADER_PATH="/data/user/0/com.philj56.gbcc/files/shaders/"
|
||||
-DPRINTER_SOUND_PATH="print.wav"
|
||||
-DTILESET_PATH="tileset.png"
|
||||
-DCAMERA_PATH="camera.png"
|
||||
-DSHADER_PATH="shaders/"
|
||||
)
|
||||
|
||||
#set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -O3 -flto -fprofile-instr-use=${GBCC_DIR}/default.profdata")
|
||||
|
@ -18,14 +18,15 @@
|
||||
#include <android/log.h>
|
||||
#include <pthread.h>
|
||||
#include <semaphore.h>
|
||||
#include <unistd.h>
|
||||
|
||||
extern "C" {
|
||||
#pragma GCC visibility push(hidden)
|
||||
#include <gbcc.h>
|
||||
#include <camera/camera.h>
|
||||
#include <core.h>
|
||||
#include <camera/camera.h>
|
||||
#include <core.h>
|
||||
#include <save.h>
|
||||
#include <window.h>
|
||||
#include <window.h>
|
||||
#pragma GCC visibility pop
|
||||
}
|
||||
|
||||
@ -112,53 +113,68 @@ bool check_autoresume(JNIEnv *env, jobject prefs) {
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_philj56_gbcc_MyGLRenderer_initWindow(
|
||||
JNIEnv *env,
|
||||
jobject obj) {
|
||||
JNIEnv *env,
|
||||
jobject obj) {
|
||||
gbcc_window_initialise(&gbc);
|
||||
gbcc_window_use_shader(&gbc, shader);
|
||||
gbcc_menu_init(&gbc);
|
||||
gbcc_window_use_shader(&gbc, shader);
|
||||
gbcc_menu_init(&gbc);
|
||||
gbcc_menu_update(&gbc);
|
||||
}
|
||||
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_philj56_gbcc_MyGLSurfaceView_destroyWindow(
|
||||
JNIEnv *env,
|
||||
jobject obj) {
|
||||
gbcc_menu_destroy(&gbc);
|
||||
// Have to destroy the window manually, as the OpenGL context is likely to be gone by now
|
||||
gbc.window.initialised = false;
|
||||
gbcc_fontmap_destroy(&gbc.window.font);
|
||||
JNIEnv *env,
|
||||
jobject obj) {
|
||||
if (gbc.window.initialised) {
|
||||
gbcc_menu_destroy(&gbc);
|
||||
// Have to destroy the window manually, as the OpenGL context is likely to be gone by now
|
||||
gbc.window.initialised = false;
|
||||
gbcc_fontmap_destroy(&gbc.window.font);
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_philj56_gbcc_MyGLRenderer_updateWindow(
|
||||
JNIEnv *env,
|
||||
jobject obj) {
|
||||
JNIEnv *env,
|
||||
jobject obj) {
|
||||
if (gbc.core.initialised) {
|
||||
if (!gbc.window.initialised) {
|
||||
gbcc_window_initialise(&gbc);
|
||||
}
|
||||
gbcc_window_update(&gbc);
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_philj56_gbcc_MyGLRenderer_resizeWindow(
|
||||
JNIEnv *env,
|
||||
jobject obj,
|
||||
jint width,
|
||||
jint height) {
|
||||
JNIEnv *env,
|
||||
jobject obj,
|
||||
jint width,
|
||||
jint height) {
|
||||
gbc.window.width = width;
|
||||
gbc.window.height = height;
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_philj56_gbcc_GLActivity_chdir(
|
||||
JNIEnv *env,
|
||||
jobject obj,/* this */
|
||||
jstring dirName) {
|
||||
const char *path = env->GetStringUTFChars(dirName, nullptr);
|
||||
chdir(path);
|
||||
env->ReleaseStringUTFChars(dirName, path);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jboolean JNICALL
|
||||
Java_com_philj56_gbcc_GLActivity_loadRom(
|
||||
JNIEnv *env,
|
||||
jobject obj,/* this */
|
||||
jstring file,
|
||||
jint sampleRate,
|
||||
jint samplesPerBuffer,
|
||||
jstring saveDir,
|
||||
jobject prefs) {
|
||||
JNIEnv *env,
|
||||
jobject obj,/* this */
|
||||
jstring file,
|
||||
jint sampleRate,
|
||||
jint samplesPerBuffer,
|
||||
jstring saveDir,
|
||||
jobject prefs) {
|
||||
|
||||
const char *string = env->GetStringUTFChars(file, nullptr);
|
||||
|
||||
@ -203,8 +219,8 @@ Java_com_philj56_gbcc_GLActivity_getErrorMessage(
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_philj56_gbcc_GLActivity_quit(
|
||||
JNIEnv *env,
|
||||
jobject obj/* this */) {
|
||||
JNIEnv *env,
|
||||
jobject obj/* this */) {
|
||||
|
||||
gbc.quit = true;
|
||||
sem_post(&gbc.core.ppu.vsync_semaphore);
|
||||
@ -217,25 +233,25 @@ Java_com_philj56_gbcc_GLActivity_quit(
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_philj56_gbcc_GLActivity_toggleMenu(
|
||||
JNIEnv *env,
|
||||
jobject obj/* this */,
|
||||
jobject view) {
|
||||
JNIEnv *env,
|
||||
jobject obj/* this */,
|
||||
jobject view) {
|
||||
gbcc_input_process_key(&gbc, GBCC_KEY_MENU, true);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_philj56_gbcc_GLActivity_toggleTurbo(
|
||||
JNIEnv *env,
|
||||
jobject obj/* this */) {
|
||||
JNIEnv *env,
|
||||
jobject obj/* this */) {
|
||||
gbcc_input_process_key(&gbc, GBCC_KEY_TURBO, true);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_philj56_gbcc_GLActivity_press(
|
||||
JNIEnv *env,
|
||||
jobject obj/* this */,
|
||||
jint key,
|
||||
jboolean pressed) {
|
||||
JNIEnv *env,
|
||||
jobject obj/* this */,
|
||||
jint key,
|
||||
jboolean pressed) {
|
||||
switch (key) {
|
||||
case 0:
|
||||
gbcc_input_process_key(&gbc, GBCC_KEY_A, pressed);
|
||||
@ -268,9 +284,9 @@ Java_com_philj56_gbcc_GLActivity_press(
|
||||
|
||||
extern "C" JNIEXPORT jboolean JNICALL
|
||||
Java_com_philj56_gbcc_GLActivity_isPressed(
|
||||
JNIEnv *env,
|
||||
jobject obj/* this */,
|
||||
jint key) {
|
||||
JNIEnv *env,
|
||||
jobject obj/* this */,
|
||||
jint key) {
|
||||
switch (key) {
|
||||
case 0:
|
||||
return static_cast<jboolean>(gbc.core.keys.a);
|
||||
@ -295,24 +311,24 @@ Java_com_philj56_gbcc_GLActivity_isPressed(
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_philj56_gbcc_GLActivity_saveState(
|
||||
JNIEnv *env,
|
||||
jobject obj/* this */,
|
||||
jint state) {
|
||||
JNIEnv *env,
|
||||
jobject obj/* this */,
|
||||
jint state) {
|
||||
gbc.save_state = static_cast<int8_t>(state);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_philj56_gbcc_GLActivity_loadState(
|
||||
JNIEnv *env,
|
||||
jobject obj/* this */,
|
||||
jint state) {
|
||||
JNIEnv *env,
|
||||
jobject obj/* this */,
|
||||
jint state) {
|
||||
gbc.load_state = static_cast<int8_t>(state);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jboolean JNICALL
|
||||
Java_com_philj56_gbcc_GLActivity_checkVibrationFun(
|
||||
JNIEnv *env,
|
||||
jobject obj/* this */) {
|
||||
JNIEnv *env,
|
||||
jobject obj/* this */) {
|
||||
static bool last_rumble = false;
|
||||
bool rumble = gbc.core.cart.rumble_state;
|
||||
bool ret = (rumble != last_rumble);
|
||||
@ -322,10 +338,10 @@ Java_com_philj56_gbcc_GLActivity_checkVibrationFun(
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_philj56_gbcc_GLActivity_updateAccelerometer(
|
||||
JNIEnv *env,
|
||||
jobject obj/* this */,
|
||||
jfloat x,
|
||||
jfloat y) {
|
||||
JNIEnv *env,
|
||||
jobject obj/* this */,
|
||||
jfloat x,
|
||||
jfloat y) {
|
||||
const float g = 9.81;
|
||||
gbc.core.cart.mbc.accelerometer.real_x = static_cast<uint16_t>(0x81D0u + (0x70 * x / g));
|
||||
gbc.core.cart.mbc.accelerometer.real_y = static_cast<uint16_t>(0x81D0u - (0x70 * y / g));
|
||||
@ -333,124 +349,124 @@ Java_com_philj56_gbcc_GLActivity_updateAccelerometer(
|
||||
|
||||
extern "C" JNIEXPORT jboolean JNICALL
|
||||
Java_com_philj56_gbcc_GLActivity_hasRumble(
|
||||
JNIEnv *env,
|
||||
jobject obj/* this */) {
|
||||
JNIEnv *env,
|
||||
jobject obj/* this */) {
|
||||
return static_cast<jboolean>(gbc.core.cart.rumble);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jboolean JNICALL
|
||||
Java_com_philj56_gbcc_GLActivity_hasAccelerometer(
|
||||
JNIEnv *env,
|
||||
jobject obj/* this */) {
|
||||
JNIEnv *env,
|
||||
jobject obj/* this */) {
|
||||
return static_cast<jboolean>(gbc.core.cart.mbc.type == MBC7);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jboolean JNICALL
|
||||
Java_com_philj56_gbcc_GLActivity_isCamera(
|
||||
JNIEnv *env,
|
||||
jobject obj/* this */) {
|
||||
return static_cast<jboolean>(gbc.core.cart.mbc.type == CAMERA);
|
||||
JNIEnv *env,
|
||||
jobject obj/* this */) {
|
||||
return static_cast<jboolean>(gbc.core.cart.mbc.type == CAMERA);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_philj56_gbcc_GLActivity_updateCamera(
|
||||
JNIEnv *env,
|
||||
jobject obj/* this */,
|
||||
jbyteArray array,
|
||||
jint width,
|
||||
jint height,
|
||||
jint rotation,
|
||||
jint rowStride) {
|
||||
jbyte *image = env->GetByteArrayElements(array, NULL);
|
||||
JNIEnv *env,
|
||||
jobject obj/* this */,
|
||||
jbyteArray array,
|
||||
jint width,
|
||||
jint height,
|
||||
jint rotation,
|
||||
jint rowStride) {
|
||||
jbyte *image = env->GetByteArrayElements(array, NULL);
|
||||
|
||||
// Perform box-blur downsampling of the sensor image to get out 128x128 gb camera image
|
||||
int box_size = MIN(width, height) / 128 / 2 + 1;
|
||||
// Perform box-blur downsampling of the sensor image to get out 128x128 gb camera image
|
||||
int box_size = MIN(width, height) / 128 / 2 + 1;
|
||||
|
||||
// First we perform the horizontal blur
|
||||
uint8_t *new_row = static_cast<uint8_t *>(calloc(width, 1));
|
||||
for (int j = 0; j < height; j++) {
|
||||
jbyte *row = &image[j * rowStride];
|
||||
int sum = 0;
|
||||
int div = 0;
|
||||
// First we perform the horizontal blur
|
||||
uint8_t *new_row = static_cast<uint8_t *>(calloc(width, 1));
|
||||
for (int j = 0; j < height; j++) {
|
||||
jbyte *row = &image[j * rowStride];
|
||||
int sum = 0;
|
||||
int div = 0;
|
||||
|
||||
for (int i = -box_size; i < width; i++) {
|
||||
if (i < width - box_size) {
|
||||
sum += static_cast<uint8_t>(row[i + box_size]);
|
||||
} else {
|
||||
div--;
|
||||
}
|
||||
if (i >= box_size) {
|
||||
sum -= static_cast<uint8_t>(row[i - box_size]);
|
||||
} else {
|
||||
div++;
|
||||
}
|
||||
for (int i = -box_size; i < width; i++) {
|
||||
if (i < width - box_size) {
|
||||
sum += static_cast<uint8_t>(row[i + box_size]);
|
||||
} else {
|
||||
div--;
|
||||
}
|
||||
if (i >= box_size) {
|
||||
sum -= static_cast<uint8_t>(row[i - box_size]);
|
||||
} else {
|
||||
div++;
|
||||
}
|
||||
|
||||
if (i >= 0) {
|
||||
new_row[i] = static_cast<uint8_t>(sum / div);
|
||||
}
|
||||
}
|
||||
memcpy(row, new_row, width);
|
||||
}
|
||||
free(new_row);
|
||||
if (i >= 0) {
|
||||
new_row[i] = static_cast<uint8_t>(sum / div);
|
||||
}
|
||||
}
|
||||
memcpy(row, new_row, width);
|
||||
}
|
||||
free(new_row);
|
||||
|
||||
// Then the vertical blur
|
||||
uint8_t *new_col = static_cast<uint8_t *>(calloc(height, 1));
|
||||
for (int i = 0; i < width; i++) {
|
||||
int sum = 0;
|
||||
int div = 0;
|
||||
// Then the vertical blur
|
||||
uint8_t *new_col = static_cast<uint8_t *>(calloc(height, 1));
|
||||
for (int i = 0; i < width; i++) {
|
||||
int sum = 0;
|
||||
int div = 0;
|
||||
|
||||
for (int j = -box_size; j < height; j++) {
|
||||
if (j < height - box_size) {
|
||||
sum += static_cast<uint8_t>(image[(j + box_size) * rowStride + i]);
|
||||
} else {
|
||||
div--;
|
||||
}
|
||||
if (j >= box_size) {
|
||||
sum -= static_cast<uint8_t>(image[(j - box_size) * rowStride + i]);
|
||||
} else {
|
||||
div++;
|
||||
}
|
||||
for (int j = -box_size; j < height; j++) {
|
||||
if (j < height - box_size) {
|
||||
sum += static_cast<uint8_t>(image[(j + box_size) * rowStride + i]);
|
||||
} else {
|
||||
div--;
|
||||
}
|
||||
if (j >= box_size) {
|
||||
sum -= static_cast<uint8_t>(image[(j - box_size) * rowStride + i]);
|
||||
} else {
|
||||
div++;
|
||||
}
|
||||
|
||||
if (i >= 0) {
|
||||
new_col[j] = static_cast<uint8_t>(sum / div);
|
||||
}
|
||||
}
|
||||
for (int j = 0; j < height; j++) {
|
||||
image[j * rowStride + i] = new_col[j];
|
||||
}
|
||||
}
|
||||
free(new_col);
|
||||
if (i >= 0) {
|
||||
new_col[j] = static_cast<uint8_t>(sum / div);
|
||||
}
|
||||
}
|
||||
for (int j = 0; j < height; j++) {
|
||||
image[j * rowStride + i] = new_col[j];
|
||||
}
|
||||
}
|
||||
free(new_col);
|
||||
|
||||
// Then we nearest-neighbour downscale and rotate
|
||||
double scale = MIN(height, width) / 128.0;
|
||||
for (int j = 0; j < 128; j++) {
|
||||
for (int i = 0; i < 128; i++) {
|
||||
int src_idx = (int)(j * scale) * rowStride + (int)(i * scale);
|
||||
int dst_idx;
|
||||
if (rotation == 90) {
|
||||
dst_idx = i * 128 + (127 - j);
|
||||
} else if (rotation == 180) {
|
||||
dst_idx = (127 - j) * 128 + (127 - i);
|
||||
} else if (rotation == 270) {
|
||||
dst_idx = (127 - i) * 128 + j;
|
||||
} else {
|
||||
dst_idx = j * 128 + i;
|
||||
}
|
||||
// Then we nearest-neighbour downscale and rotate
|
||||
double scale = MIN(height, width) / 128.0;
|
||||
for (int j = 0; j < 128; j++) {
|
||||
for (int i = 0; i < 128; i++) {
|
||||
int src_idx = (int)(j * scale) * rowStride + (int)(i * scale);
|
||||
int dst_idx;
|
||||
if (rotation == 90) {
|
||||
dst_idx = i * 128 + (127 - j);
|
||||
} else if (rotation == 180) {
|
||||
dst_idx = (127 - j) * 128 + (127 - i);
|
||||
} else if (rotation == 270) {
|
||||
dst_idx = (127 - i) * 128 + j;
|
||||
} else {
|
||||
dst_idx = j * 128 + i;
|
||||
}
|
||||
|
||||
camera_image[dst_idx] = static_cast<uint8_t>(image[src_idx]);
|
||||
}
|
||||
}
|
||||
camera_image[dst_idx] = static_cast<uint8_t>(image[src_idx]);
|
||||
}
|
||||
}
|
||||
|
||||
env->ReleaseByteArrayElements(array, image, JNI_ABORT);
|
||||
env->ReleaseByteArrayElements(array, image, JNI_ABORT);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_philj56_gbcc_GLActivity_useNullCamera(
|
||||
JNIEnv *env,
|
||||
jobject obj/* this */) {
|
||||
gbcc_camera_default_image(camera_image);
|
||||
JNIEnv *env,
|
||||
jobject obj/* this */) {
|
||||
gbcc_camera_default_image(camera_image);
|
||||
}
|
||||
|
||||
void gbcc_camera_platform_capture_image(uint8_t image[GB_CAMERA_SENSOR_SIZE]) {
|
||||
memcpy(image, camera_image, GB_CAMERA_SENSOR_SIZE);
|
||||
}
|
||||
}
|
||||
|
@ -16,7 +16,6 @@ import android.content.res.Configuration
|
||||
import android.os.*
|
||||
import android.util.AttributeSet
|
||||
import android.view.*
|
||||
import android.widget.ImageView
|
||||
import android.widget.SeekBar
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.appcompat.app.AppCompatDelegate
|
||||
@ -24,6 +23,7 @@ import androidx.appcompat.widget.AppCompatImageView
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.content.edit
|
||||
import androidx.preference.PreferenceManager
|
||||
import kotlinx.android.synthetic.main.activity_arrange.*
|
||||
import kotlin.math.log
|
||||
import kotlin.math.min
|
||||
import kotlin.math.pow
|
||||
@ -35,16 +35,6 @@ class ArrangeActivity : AppCompatActivity() {
|
||||
|
||||
private lateinit var prefs : SharedPreferences
|
||||
|
||||
private lateinit var buttonA : ResizableImage
|
||||
private lateinit var buttonB : ResizableImage
|
||||
private lateinit var buttonStart : ResizableImage
|
||||
private lateinit var buttonSelect : ResizableImage
|
||||
private lateinit var dpad : ResizableImage
|
||||
|
||||
private lateinit var abSeekBar: SeekBar
|
||||
private lateinit var startSelectSeekBar: SeekBar
|
||||
private lateinit var dpadSeekBar: SeekBar
|
||||
|
||||
private fun updateLayout(gbc: Boolean) {
|
||||
val bgColor = when (gbc) {
|
||||
true -> when (prefs.getString("color", "Teal")) {
|
||||
@ -59,31 +49,21 @@ class ArrangeActivity : AppCompatActivity() {
|
||||
}
|
||||
window.setBackgroundDrawableResource(bgColor)
|
||||
|
||||
abSeekBar = findViewById(R.id.abSeekBar)
|
||||
startSelectSeekBar = findViewById(R.id.startSelectSeekBar)
|
||||
dpadSeekBar = findViewById(R.id.dpadSeekBar)
|
||||
|
||||
abSeekBar.setOnSeekBarChangeListener(seekBarListener)
|
||||
startSelectSeekBar.setOnSeekBarChangeListener(seekBarListener)
|
||||
dpadSeekBar.setOnSeekBarChangeListener(seekBarListener)
|
||||
|
||||
buttonA = findViewById(R.id.buttonA)
|
||||
buttonB = findViewById(R.id.buttonB)
|
||||
buttonStart = findViewById(R.id.buttonStart)
|
||||
buttonSelect = findViewById(R.id.buttonSelect)
|
||||
dpad = findViewById(R.id.dpad)
|
||||
|
||||
if (!gbc) {
|
||||
val screenBorderColor = ContextCompat.getColor(this, R.color.dmgScreenBorder)
|
||||
val borders = intArrayOf(
|
||||
R.id.screenBorderTop,
|
||||
R.id.screenBorderBottom,
|
||||
R.id.screenBorderLeft,
|
||||
R.id.screenBorderRight
|
||||
val borders = arrayOf(
|
||||
screenBorderTop,
|
||||
screenBorderBottom,
|
||||
screenBorderLeft,
|
||||
screenBorderRight
|
||||
)
|
||||
|
||||
borders.forEach { border ->
|
||||
findViewById<ImageView>(border).setColorFilter(
|
||||
borders.forEach {
|
||||
it.setColorFilter(
|
||||
screenBorderColor,
|
||||
android.graphics.PorterDuff.Mode.SRC_IN
|
||||
)
|
||||
@ -99,16 +79,14 @@ class ArrangeActivity : AppCompatActivity() {
|
||||
buttonSelect.rotation = -45f
|
||||
|
||||
if (resources.configuration.orientation == Configuration.ORIENTATION_PORTRAIT) {
|
||||
val bottomLeft = findViewById<ImageView>(R.id.bottomLeftCorner)
|
||||
val bottomRight = findViewById<ImageView>(R.id.bottomRightCorner)
|
||||
val px = (resources.displayMetrics.density + 0.5f).toInt()
|
||||
|
||||
bottomLeft.layoutParams.apply {
|
||||
bottomLeftCorner.layoutParams.apply {
|
||||
width = 16 * px
|
||||
height = width
|
||||
}
|
||||
|
||||
bottomRight.layoutParams.apply {
|
||||
bottomRightCorner.layoutParams.apply {
|
||||
width = 64 * px
|
||||
height = width
|
||||
}
|
||||
@ -144,9 +122,12 @@ class ArrangeActivity : AppCompatActivity() {
|
||||
delegate.localNightMode = AppCompatDelegate.MODE_NIGHT_YES
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
window.decorView.setOnSystemUiVisibilityChangeListener {
|
||||
hideNavigation()
|
||||
}
|
||||
|
||||
prefs = PreferenceManager.getDefaultSharedPreferences(this)
|
||||
requestedOrientation = prefs.getString("orientation", "-1")?.toInt() ?: -1
|
||||
requestWindowFeature(Window.FEATURE_NO_TITLE)
|
||||
|
||||
setContentView(R.layout.activity_arrange)
|
||||
|
||||
@ -159,21 +140,6 @@ class ArrangeActivity : AppCompatActivity() {
|
||||
)
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
|
||||
window.addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN)
|
||||
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
|
||||
window.decorView.apply {
|
||||
systemUiVisibility = (View.SYSTEM_UI_FLAG_LAYOUT_STABLE
|
||||
or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
|
||||
or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
|
||||
or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
|
||||
or View.SYSTEM_UI_FLAG_FULLSCREEN
|
||||
or View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onStop() {
|
||||
super.onStop()
|
||||
|
||||
@ -265,6 +231,22 @@ class ArrangeActivity : AppCompatActivity() {
|
||||
override fun onStopTrackingTouch(seekBar: SeekBar?) {
|
||||
}
|
||||
}
|
||||
|
||||
override fun onWindowFocusChanged(hasFocus: Boolean) {
|
||||
super.onWindowFocusChanged(hasFocus)
|
||||
if (hasFocus) {
|
||||
hideNavigation()
|
||||
}
|
||||
}
|
||||
|
||||
private fun hideNavigation() {
|
||||
window.decorView.systemUiVisibility = (View.SYSTEM_UI_FLAG_LAYOUT_STABLE
|
||||
or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
|
||||
or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
|
||||
or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
|
||||
or View.SYSTEM_UI_FLAG_FULLSCREEN
|
||||
or View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY)
|
||||
}
|
||||
}
|
||||
|
||||
class ResizableImage : AppCompatImageView {
|
||||
|
@ -28,7 +28,6 @@ import android.util.AttributeSet
|
||||
import android.util.Log
|
||||
import android.util.Size
|
||||
import android.view.*
|
||||
import android.widget.ImageButton
|
||||
import android.widget.ImageView
|
||||
import android.widget.Toast
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
@ -66,13 +65,8 @@ class GLActivity : AppCompatActivity(), SensorEventListener, LifecycleOwner {
|
||||
private var dpadState = 0
|
||||
private lateinit var saveDir : String
|
||||
|
||||
private lateinit var buttonA : ImageButton
|
||||
private lateinit var buttonB : ImageButton
|
||||
private lateinit var buttonStart : ImageButton
|
||||
private lateinit var buttonSelect : ImageButton
|
||||
private lateinit var dpad : View
|
||||
|
||||
external fun toggleMenu(view: View)
|
||||
private external fun chdir(dirName: String)
|
||||
private external fun loadRom(file: String, sampleRate: Int, samplesPerBuffer: Int, saveDir: String, prefs: SharedPreferences): Boolean
|
||||
private external fun getErrorMessage(): String
|
||||
private external fun quit()
|
||||
@ -174,15 +168,15 @@ class GLActivity : AppCompatActivity(), SensorEventListener, LifecycleOwner {
|
||||
|
||||
if (!gbc) {
|
||||
val screenBorderColor = ContextCompat.getColor(this, R.color.dmgScreenBorder)
|
||||
val borders = intArrayOf(
|
||||
R.id.screenBorderTop,
|
||||
R.id.screenBorderBottom,
|
||||
R.id.screenBorderLeft,
|
||||
R.id.screenBorderRight
|
||||
val borders = arrayOf(
|
||||
screenBorderTop,
|
||||
screenBorderBottom,
|
||||
screenBorderLeft,
|
||||
screenBorderRight
|
||||
)
|
||||
|
||||
borders.forEach { border ->
|
||||
findViewById<ImageView>(border).setColorFilter(
|
||||
borders.forEach {
|
||||
it.setColorFilter(
|
||||
screenBorderColor,
|
||||
android.graphics.PorterDuff.Mode.SRC_IN
|
||||
)
|
||||
@ -239,16 +233,19 @@ class GLActivity : AppCompatActivity(), SensorEventListener, LifecycleOwner {
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
chdir(filesDir.absolutePath)
|
||||
|
||||
window.decorView.setOnSystemUiVisibilityChangeListener {
|
||||
hideNavigation()
|
||||
}
|
||||
|
||||
val prefs = PreferenceManager.getDefaultSharedPreferences(this)
|
||||
requestedOrientation = prefs.getString("orientation", "-1")?.toInt() ?: -1
|
||||
setContentView(R.layout.activity_gl)
|
||||
|
||||
val save = filesDir.resolve("saves")
|
||||
save.mkdirs()
|
||||
saveDir = save.absolutePath
|
||||
val prefs = PreferenceManager.getDefaultSharedPreferences(this)
|
||||
requestedOrientation = prefs.getString("orientation", "-1")?.toInt() ?: -1
|
||||
requestWindowFeature(Window.FEATURE_NO_TITLE)
|
||||
|
||||
setContentView(R.layout.activity_gl)
|
||||
|
||||
val bundle = intent.extras
|
||||
filename = bundle?.getString("file") ?: ""
|
||||
if (filename == "") {
|
||||
@ -256,12 +253,6 @@ class GLActivity : AppCompatActivity(), SensorEventListener, LifecycleOwner {
|
||||
finish()
|
||||
}
|
||||
|
||||
buttonA = findViewById(R.id.buttonA)
|
||||
buttonB = findViewById(R.id.buttonB)
|
||||
buttonStart = findViewById(R.id.buttonStart)
|
||||
buttonSelect = findViewById(R.id.buttonSelect)
|
||||
dpad = findViewById(R.id.dpad)
|
||||
|
||||
updateLayout(
|
||||
when(prefs.getString("skin", "auto")) {
|
||||
"dmg" -> false
|
||||
@ -358,20 +349,25 @@ class GLActivity : AppCompatActivity(), SensorEventListener, LifecycleOwner {
|
||||
})
|
||||
}
|
||||
|
||||
override fun onWindowFocusChanged(hasFocus: Boolean) {
|
||||
super.onWindowFocusChanged(hasFocus)
|
||||
if (hasFocus) {
|
||||
hideNavigation()
|
||||
}
|
||||
}
|
||||
|
||||
private fun hideNavigation() {
|
||||
window.decorView.systemUiVisibility = (View.SYSTEM_UI_FLAG_LAYOUT_STABLE
|
||||
or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
|
||||
or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
|
||||
or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
|
||||
or View.SYSTEM_UI_FLAG_FULLSCREEN
|
||||
or View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY)
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
|
||||
window.addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN)
|
||||
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
|
||||
window.decorView.apply {
|
||||
systemUiVisibility = (View.SYSTEM_UI_FLAG_LAYOUT_STABLE
|
||||
or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
|
||||
or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
|
||||
or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
|
||||
or View.SYSTEM_UI_FLAG_FULLSCREEN
|
||||
or View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY)
|
||||
}
|
||||
|
||||
val am = getSystemService(Context.AUDIO_SERVICE) as AudioManager
|
||||
val sampleRate = am.getProperty(AudioManager.PROPERTY_OUTPUT_SAMPLE_RATE)?.let { str ->
|
||||
Integer.parseInt(str).takeUnless { it == 0 }
|
||||
@ -415,15 +411,13 @@ class GLActivity : AppCompatActivity(), SensorEventListener, LifecycleOwner {
|
||||
|
||||
override fun onPause() {
|
||||
screen.onPause()
|
||||
if (!loadedSuccessfully) {
|
||||
super.onPause()
|
||||
return
|
||||
if (loadedSuccessfully) {
|
||||
sensorManager.unregisterListener(this)
|
||||
handler.removeCallbacks(checkVibration)
|
||||
saveState(autoSaveState)
|
||||
quit()
|
||||
resume = true
|
||||
}
|
||||
sensorManager.unregisterListener(this)
|
||||
handler.removeCallbacks(checkVibration)
|
||||
saveState(autoSaveState)
|
||||
quit()
|
||||
resume = true
|
||||
super.onPause()
|
||||
}
|
||||
|
||||
@ -457,27 +451,30 @@ class GLActivity : AppCompatActivity(), SensorEventListener, LifecycleOwner {
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkCameraPermission() = (ContextCompat.checkSelfPermission(baseContext, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED)
|
||||
private fun checkCameraPermission() : Boolean {
|
||||
val permissionStatus = ContextCompat.checkSelfPermission(baseContext, Manifest.permission.CAMERA)
|
||||
return permissionStatus == PackageManager.PERMISSION_GRANTED
|
||||
}
|
||||
|
||||
private fun checkFiles() {
|
||||
val filePath = filesDir
|
||||
assets.open("tileset.png").use { iStream ->
|
||||
val file = File("$filePath/tileset.png")
|
||||
FileOutputStream(file).use { it.write(iStream.readBytes()) }
|
||||
FileOutputStream(file).use { iStream.copyTo(it) }
|
||||
}
|
||||
assets.open("camera.png").use { iStream ->
|
||||
val file = File("$filePath/camera.png")
|
||||
FileOutputStream(file).use { it.write(iStream.readBytes()) }
|
||||
FileOutputStream(file).use { iStream.copyTo(it) }
|
||||
}
|
||||
assets.open("print.wav").use { iStream ->
|
||||
val file = File("$filePath/print.wav")
|
||||
FileOutputStream(file).use { it.write(iStream.readBytes()) }
|
||||
FileOutputStream(file).use { iStream.copyTo(it) }
|
||||
}
|
||||
assets.list("shaders")?.forEach { shader ->
|
||||
File("$filePath/shaders").mkdirs()
|
||||
assets.open("shaders/$shader").use { iStream ->
|
||||
val file = File("$filePath/shaders/$shader")
|
||||
FileOutputStream(file).use { it.write(iStream.readBytes()) }
|
||||
FileOutputStream(file).use { iStream.copyTo(it) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -29,6 +29,10 @@
|
||||
<item name="windowNoTitle">true</item>
|
||||
</style>
|
||||
|
||||
<style name="AppThemeDayNight.Fullscreen" parent="AppThemeDayNight.NoActionBar">
|
||||
<item name="android:windowFullscreen">true</item>
|
||||
</style>
|
||||
|
||||
<!-- Colour the toolbar correctly. -->
|
||||
<style name="Toolbar">
|
||||
<item name="android:minHeight">?actionBarSize</item>
|
||||
|
Loading…
Reference in New Issue
Block a user