Merge pull request #1528 from reicast/fh/android-wipeout
Removing most of the java code and various bug fixes
109
core/build.h
|
@ -286,10 +286,6 @@
|
|||
#define FEAT_HAS_SOFTREND BUILD_COMPILER == COMPILER_VC //GCC wants us to enable sse4 globaly to enable intrins
|
||||
#endif
|
||||
|
||||
#define RAM_SIZE_MAX (32*1024*1024)
|
||||
#define VRAM_SIZE_MAX (16*1024*1024)
|
||||
#define ARAM_SIZE_MAX (8*1024*1024)
|
||||
|
||||
//Depricated build configs
|
||||
#ifdef HOST_NO_REC
|
||||
#error Dont use HOST_NO_REC
|
||||
|
@ -298,3 +294,108 @@
|
|||
#ifdef HOST_NO_AREC
|
||||
#error Dont use HOST_NO_AREC
|
||||
#endif
|
||||
|
||||
// TARGET PLATFORM
|
||||
|
||||
#define RAM_SIZE_MAX (32*1024*1024)
|
||||
#define VRAM_SIZE_MAX (16*1024*1024)
|
||||
#define ARAM_SIZE_MAX (8*1024*1024)
|
||||
|
||||
#if (DC_PLATFORM==DC_PLATFORM_DREAMCAST)
|
||||
|
||||
#define BUILD_DREAMCAST 1
|
||||
|
||||
//DC : 16 mb ram, 8 mb vram, 2 mb aram, 2 mb bios, 128k flash
|
||||
#define RAM_SIZE (16*1024*1024)
|
||||
#define VRAM_SIZE (8*1024*1024)
|
||||
#define ARAM_SIZE (2*1024*1024)
|
||||
#define BIOS_SIZE (2*1024*1024)
|
||||
#define FLASH_SIZE (128*1024)
|
||||
|
||||
#define ROM_PREFIX "dc_"
|
||||
#define ROM_NAMES
|
||||
#define NVR_OPTIONAL 0
|
||||
|
||||
#elif (DC_PLATFORM==DC_PLATFORM_DEV_UNIT)
|
||||
|
||||
#define BUILD_DEV_UNIT 1
|
||||
|
||||
//Devkit : 32 mb ram, 8? mb vram, 2? mb aram, 2? mb bios, ? flash
|
||||
#define RAM_SIZE (32*1024*1024)
|
||||
#define VRAM_SIZE (8*1024*1024)
|
||||
#define ARAM_SIZE (2*1024*1024)
|
||||
#define BIOS_SIZE (2*1024*1024)
|
||||
#define FLASH_SIZE (128*1024)
|
||||
|
||||
#define ROM_PREFIX "hkt_"
|
||||
#define ROM_NAMES
|
||||
#define NVR_OPTIONAL 0
|
||||
|
||||
#elif (DC_PLATFORM==DC_PLATFORM_NAOMI)
|
||||
|
||||
//Naomi : 32 mb ram, 16 mb vram, 8 mb aram, 2 mb bios, ? flash
|
||||
#define RAM_SIZE (32*1024*1024)
|
||||
#define VRAM_SIZE (16*1024*1024)
|
||||
#define ARAM_SIZE (8*1024*1024)
|
||||
#define BIOS_SIZE (2*1024*1024)
|
||||
#define BBSRAM_SIZE (32*1024)
|
||||
|
||||
#define ROM_PREFIX "naomi_"
|
||||
#define ROM_NAMES ";epr-21576d.bin"
|
||||
#define NVR_OPTIONAL 1
|
||||
|
||||
#elif (DC_PLATFORM==DC_PLATFORM_NAOMI2)
|
||||
|
||||
//Naomi2 : 32 mb ram, 16 mb vram, 8 mb aram, 2 mb bios, ? flash
|
||||
#define RAM_SIZE (32*1024*1024)
|
||||
#define VRAM_SIZE (16*1024*1024)
|
||||
#define ARAM_SIZE (8*1024*1024)
|
||||
#define BIOS_SIZE (2*1024*1024)
|
||||
#define BBSRAM_SIZE (32*1024)
|
||||
|
||||
#define ROM_PREFIX "n2_"
|
||||
#define ROM_NAMES
|
||||
#define NVR_OPTIONAL 1
|
||||
|
||||
#elif (DC_PLATFORM==DC_PLATFORM_ATOMISWAVE)
|
||||
|
||||
#define BUILD_ATOMISWAVE 1
|
||||
|
||||
//Atomiswave : 16 mb ram, 8 mb vram, 8 mb aram, 128kb bios on flash, 128kb battery-backed ram
|
||||
#define RAM_SIZE (16*1024*1024)
|
||||
#define VRAM_SIZE (8*1024*1024)
|
||||
#define ARAM_SIZE (8*1024*1024)
|
||||
#define BIOS_SIZE (128*1024)
|
||||
#define BBSRAM_SIZE (128*1024)
|
||||
|
||||
#define ROM_PREFIX "aw_"
|
||||
#define ROM_NAMES ";bios.ic23_l"
|
||||
#define NVR_OPTIONAL 1
|
||||
|
||||
#else
|
||||
#error invalid build config
|
||||
#endif
|
||||
|
||||
#define RAM_MASK (RAM_SIZE-1)
|
||||
#define VRAM_MASK (VRAM_SIZE-1)
|
||||
#define ARAM_MASK (ARAM_SIZE-1)
|
||||
#define BIOS_MASK (BIOS_SIZE-1)
|
||||
|
||||
#ifdef FLASH_SIZE
|
||||
#define FLASH_MASK (FLASH_SIZE-1)
|
||||
#endif
|
||||
|
||||
#ifdef BBSRAM_SIZE
|
||||
#define BBSRAM_MASK (BBSRAM_SIZE-1)
|
||||
#endif
|
||||
|
||||
#define GD_CLOCK 33868800 //GDROM XTAL -- 768fs
|
||||
|
||||
#define AICA_CORE_CLOCK (GD_CLOCK*4/3) //[45158400] GD->PLL 3:4 -> AICA CORE -- 1024fs
|
||||
#define ADAC_CLOCK (AICA_CORE_CLOCK/2) //[11289600] 44100*256, AICA CORE -> PLL 4:1 -> ADAC -- 256fs
|
||||
#define AICA_ARM_CLOCK (AICA_CORE_CLOCK/2) //[22579200] AICA CORE -> PLL 2:1 -> ARM
|
||||
#define AICA_SDRAM_CLOCK (GD_CLOCK*2) //[67737600] GD-> PLL 2 -> SDRAM
|
||||
#define SH4_MAIN_CLOCK (200*1000*1000) //[200000000] XTal(13.5) -> PLL (33.3) -> PLL 1:6 (200)
|
||||
#define SH4_RAM_CLOCK (100*1000*1000) //[100000000] XTal(13.5) -> PLL (33.3) -> PLL 1:3 (100) , also suplied to HOLLY chip
|
||||
#define G2_BUS_CLOCK (25*1000*1000) //[25000000] from Holly, from SH4_RAM_CLOCK w/ 2 2:1 plls
|
||||
|
||||
|
|
|
@ -499,8 +499,13 @@ __asm__ (
|
|||
".hidden arm_dispatch \n"
|
||||
"arm_dispatch: \n\t"
|
||||
"ldp w0, w1, [x28, #184] \n\t" // load Next PC, interrupt
|
||||
|
||||
"ubfx w2, w0, #2, #21 \n\t" // w2 = pc >> 2. Note: assuming address space <= 8 MB (23 bits)
|
||||
#if ARAM_SIZE == 2*1024*1024
|
||||
"ubfx w2, w0, #2, #19 \n\t" // w2 = pc >> 2. Note: assuming address space == 2 MB (21 bits)
|
||||
#elif ARAM_SIZE == 8*1024*1024
|
||||
"ubfx w2, w0, #2, #21 \n\t" // w2 = pc >> 2. Note: assuming address space == 8 MB (23 bits)
|
||||
#else
|
||||
#error Unsupported AICA RAM size
|
||||
#endif
|
||||
"cbnz w1, arm_dofiq \n\t" // if interrupt pending, handle it
|
||||
|
||||
"add x2, x26, x2, lsl #3 \n\t" // x2 = EntryPoints + pc << 1
|
||||
|
|
|
@ -256,6 +256,7 @@ void gd_set_state(gd_states state)
|
|||
|
||||
void gd_setdisc()
|
||||
{
|
||||
cdda.playing = false;
|
||||
DiscType newd = (DiscType)libGDR_GetDiscType();
|
||||
|
||||
switch(newd)
|
||||
|
|
|
@ -3,10 +3,22 @@
|
|||
#include <sstream>
|
||||
#include <algorithm>
|
||||
|
||||
// On windows, transform / to \\
|
||||
|
||||
string normalize_path_separator(string path)
|
||||
{
|
||||
#if HOST_OS == OS_WINDOWS
|
||||
std::replace(path.begin(), path.end(), '/', '\\');
|
||||
#endif
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
// given file/name.ext or file\name.ext returns file/ or file\, depending on the platform
|
||||
// given name.ext returns ./ or .\, depending on the platform
|
||||
string OS_dirname(string file)
|
||||
{
|
||||
file = normalize_path_separator(file);
|
||||
#if HOST_OS == OS_WINDOWS
|
||||
const char sep = '\\';
|
||||
#else
|
||||
|
@ -25,19 +37,6 @@ string OS_dirname(string file)
|
|||
return file.substr(0, last_slash + 1);
|
||||
}
|
||||
|
||||
// On windows, transform / to \\
|
||||
// On linux, transform \\ to /
|
||||
string normalize_path_separator(string path)
|
||||
{
|
||||
#if HOST_OS == OS_WINDOWS
|
||||
std::replace( path.begin(), path.end(), '/', '\\');
|
||||
#else
|
||||
std::replace( path.begin(), path.end(), '\\', '/');
|
||||
#endif
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
#if 0 // TODO: Move this to some tests, make it platform agnostic
|
||||
namespace {
|
||||
struct OS_dirname_Test {
|
||||
|
|
|
@ -53,8 +53,8 @@ enum DreamcastKey
|
|||
|
||||
// System axes
|
||||
EMU_AXIS_NONE = 0x00000,
|
||||
EMU_AXIS_DPAD1_X = 0x00001,
|
||||
EMU_AXIS_DPAD1_Y = 0x00002,
|
||||
EMU_AXIS_DPAD2_X = 0x00003,
|
||||
EMU_AXIS_DPAD2_Y = 0x00004,
|
||||
EMU_AXIS_DPAD1_X = DC_DPAD_LEFT,
|
||||
EMU_AXIS_DPAD1_Y = DC_DPAD_UP,
|
||||
EMU_AXIS_DPAD2_X = DC_DPAD2_LEFT,
|
||||
EMU_AXIS_DPAD2_Y = DC_DPAD2_RIGHT,
|
||||
};
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include <limits.h>
|
||||
#include "gamepad_device.h"
|
||||
#include "rend/gui.h"
|
||||
#include "oslib/oslib.h"
|
||||
|
||||
extern void dc_exit();
|
||||
|
||||
|
@ -32,7 +33,8 @@ std::mutex GamepadDevice::_gamepads_mutex;
|
|||
|
||||
bool GamepadDevice::gamepad_btn_input(u32 code, bool pressed)
|
||||
{
|
||||
if (_input_detected != NULL && _detecting_button && pressed)
|
||||
if (_input_detected != NULL && _detecting_button
|
||||
&& os_GetSeconds() >= _detection_start_time && pressed)
|
||||
{
|
||||
_input_detected(code);
|
||||
_input_detected = NULL;
|
||||
|
@ -84,7 +86,8 @@ bool GamepadDevice::gamepad_axis_input(u32 code, int value)
|
|||
v = (get_axis_min_value(code) + get_axis_range(code) - value) * 255 / get_axis_range(code) - 128;
|
||||
else
|
||||
v = (value - get_axis_min_value(code)) * 255 / get_axis_range(code) - 128; //-128 ... + 127 range
|
||||
if (_input_detected != NULL && !_detecting_button && (v >= 64 || v <= -64))
|
||||
if (_input_detected != NULL && !_detecting_button
|
||||
&& os_GetSeconds() >= _detection_start_time && (v >= 64 || v <= -64))
|
||||
{
|
||||
_input_detected(code);
|
||||
_input_detected = NULL;
|
||||
|
@ -235,3 +238,18 @@ void UpdateVibration(u32 port, float power, float inclination, u32 duration_ms)
|
|||
gamepad->rumble(power, inclination, duration_ms);
|
||||
}
|
||||
}
|
||||
|
||||
void GamepadDevice::detect_btn_input(input_detected_cb button_pressed)
|
||||
{
|
||||
_input_detected = button_pressed;
|
||||
_detecting_button = true;
|
||||
_detection_start_time = os_GetSeconds() + 0.2;
|
||||
}
|
||||
|
||||
void GamepadDevice::detect_axis_input(input_detected_cb axis_moved)
|
||||
{
|
||||
_input_detected = axis_moved;
|
||||
_detecting_button = false;
|
||||
_detection_start_time = os_GetSeconds() + 0.2;
|
||||
}
|
||||
|
||||
|
|
|
@ -35,16 +35,8 @@ public:
|
|||
bool gamepad_axis_input(u32 code, int value);
|
||||
virtual ~GamepadDevice() {}
|
||||
|
||||
void detect_btn_input(input_detected_cb button_pressed)
|
||||
{
|
||||
_input_detected = button_pressed;
|
||||
_detecting_button = true;
|
||||
}
|
||||
void detect_axis_input(input_detected_cb axis_moved)
|
||||
{
|
||||
_input_detected = axis_moved;
|
||||
_detecting_button = false;
|
||||
}
|
||||
void detect_btn_input(input_detected_cb button_pressed);
|
||||
void detect_axis_input(input_detected_cb axis_moved);
|
||||
void cancel_detect_input()
|
||||
{
|
||||
_input_detected = NULL;
|
||||
|
@ -104,6 +96,7 @@ private:
|
|||
std::string _api_name;
|
||||
int _maple_port;
|
||||
bool _detecting_button = false;
|
||||
double _detection_start_time;
|
||||
input_detected_cb _input_detected;
|
||||
bool _remappable;
|
||||
float _dead_zone = 0.1f;
|
||||
|
|
|
@ -58,6 +58,7 @@ bkpt #0
|
|||
bkpt
|
||||
#endif
|
||||
ubfx r0,r3,#5,#19 @ get vram offset
|
||||
@ should be only 18 bits for 8MB VRAM but it wraps around on dc
|
||||
add r3,r1,#0x04000000 @ get vram ptr from r1, part 1
|
||||
add r3,#512 @ get ram ptr from r1, part 2
|
||||
add r3,r0,lsl #5 @ ram + offset
|
||||
|
@ -180,6 +181,7 @@ CSYM(no_update): @ next_pc _MUST_ be on r4 *R4 NOT R0 anymore*
|
|||
#if RAM_SIZE_MAX == 33554432
|
||||
sub r2,r8,#0x4100000
|
||||
ubfx r1,r4,#1,#24 @ 24+1 bits: 32 MB
|
||||
@ RAM wraps around so if actual RAM size is 16MB, we won't overflow
|
||||
#elif RAM_SIZE_MAX == 16777216
|
||||
sub r2,r8,#0x2100000
|
||||
ubfx r1,r4,#1,#23 @ 23+1 bits: 16 MB
|
||||
|
@ -241,7 +243,13 @@ HIDDEN(arm_dispatch)
|
|||
CSYM(arm_dispatch):
|
||||
ldrd r0,r1,[r8,#184] @load: Next PC, interrupt
|
||||
|
||||
#if ARAM_SIZE == 2*1024*1024
|
||||
ubfx r2,r0,#2,#19 @ assuming 2 MB address space max (21 bits)
|
||||
#elif ARAM_SIZE == 8*1024*1024
|
||||
ubfx r2,r0,#2,#21 @ assuming 8 MB address space max (23 bits)
|
||||
#else
|
||||
#error Unsupported AICA RAM size
|
||||
#endif
|
||||
cmp r1,#0
|
||||
bne arm_dofiq
|
||||
|
||||
|
|
|
@ -617,31 +617,25 @@ public:
|
|||
break;
|
||||
|
||||
case shop_pref:
|
||||
Mov(w0, regalloc.MapRegister(op.rs1));
|
||||
if (op.flags != 0x1337)
|
||||
{
|
||||
Lsr(w1, regalloc.MapRegister(op.rs1), 26);
|
||||
Cmp(w1, 0x38);
|
||||
}
|
||||
Label not_sqw;
|
||||
B(¬_sqw, ne);
|
||||
Mov(w0, regalloc.MapRegister(op.rs1));
|
||||
|
||||
if (CCN_MMUCR.AT)
|
||||
{
|
||||
Ldr(x9, reinterpret_cast<uintptr_t>(&do_sqw_mmu));
|
||||
}
|
||||
else
|
||||
{
|
||||
Sub(x9, x28, offsetof(Sh4RCB, cntx) - offsetof(Sh4RCB, do_sqw_nommu));
|
||||
Ldr(x9, MemOperand(x9));
|
||||
Sub(x1, x28, offsetof(Sh4RCB, cntx) - offsetof(Sh4RCB, sq_buffer));
|
||||
}
|
||||
if (op.flags == 0x1337)
|
||||
if (CCN_MMUCR.AT)
|
||||
{
|
||||
Ldr(x9, reinterpret_cast<uintptr_t>(&do_sqw_mmu));
|
||||
}
|
||||
else
|
||||
{
|
||||
Sub(x9, x28, offsetof(Sh4RCB, cntx) - offsetof(Sh4RCB, do_sqw_nommu));
|
||||
Ldr(x9, MemOperand(x9));
|
||||
Sub(x1, x28, offsetof(Sh4RCB, cntx) - offsetof(Sh4RCB, sq_buffer));
|
||||
}
|
||||
Blr(x9);
|
||||
else
|
||||
{
|
||||
Label no_branch;
|
||||
B(&no_branch, ne);
|
||||
Blr(x9);
|
||||
Bind(&no_branch);
|
||||
Bind(¬_sqw);
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
|
@ -1488,3 +1488,10 @@ int msgboxf(const wchar* text, unsigned int type, ...) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
extern bool subfolders_read;
|
||||
|
||||
void gui_refresh_files()
|
||||
{
|
||||
game_list_done = false;
|
||||
subfolders_read = false;
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@ void gui_display_notification(const char *msg, int duration);
|
|||
void gui_display_osd();
|
||||
void gui_open_onboarding();
|
||||
void gui_term();
|
||||
void gui_refresh_files();
|
||||
|
||||
extern int screen_dpi;
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@ extern int screen_width, screen_height;
|
|||
|
||||
static std::string select_current_directory;
|
||||
static std::vector<std::string> select_subfolders;
|
||||
static bool subfolders_read;
|
||||
bool subfolders_read;
|
||||
#ifdef _WIN32
|
||||
static const std::string separators = "/\\";
|
||||
static const std::string native_separator = "\\";
|
||||
|
|
100
core/types.h
|
@ -204,106 +204,6 @@ struct vram_block
|
|||
void* userdata;
|
||||
};
|
||||
|
||||
|
||||
#if (DC_PLATFORM==DC_PLATFORM_DREAMCAST)
|
||||
|
||||
#define BUILD_DREAMCAST 1
|
||||
|
||||
//DC : 16 mb ram, 8 mb vram, 2 mb aram, 2 mb bios, 128k flash
|
||||
#define RAM_SIZE (16*1024*1024)
|
||||
#define VRAM_SIZE (8*1024*1024)
|
||||
#define ARAM_SIZE (2*1024*1024)
|
||||
#define BIOS_SIZE (2*1024*1024)
|
||||
#define FLASH_SIZE (128*1024)
|
||||
|
||||
#define ROM_PREFIX "dc_"
|
||||
#define ROM_NAMES
|
||||
#define NVR_OPTIONAL 0
|
||||
|
||||
#elif (DC_PLATFORM==DC_PLATFORM_DEV_UNIT)
|
||||
|
||||
#define BUILD_DEV_UNIT 1
|
||||
|
||||
//Devkit : 32 mb ram, 8? mb vram, 2? mb aram, 2? mb bios, ? flash
|
||||
#define RAM_SIZE (32*1024*1024)
|
||||
#define VRAM_SIZE (8*1024*1024)
|
||||
#define ARAM_SIZE (2*1024*1024)
|
||||
#define BIOS_SIZE (2*1024*1024)
|
||||
#define FLASH_SIZE (128*1024)
|
||||
|
||||
#define ROM_PREFIX "hkt_"
|
||||
#define ROM_NAMES
|
||||
#define NVR_OPTIONAL 0
|
||||
|
||||
#elif (DC_PLATFORM==DC_PLATFORM_NAOMI)
|
||||
|
||||
//Naomi : 32 mb ram, 16 mb vram, 8 mb aram, 2 mb bios, ? flash
|
||||
#define RAM_SIZE (32*1024*1024)
|
||||
#define VRAM_SIZE (16*1024*1024)
|
||||
#define ARAM_SIZE (8*1024*1024)
|
||||
#define BIOS_SIZE (2*1024*1024)
|
||||
#define BBSRAM_SIZE (32*1024)
|
||||
|
||||
#define ROM_PREFIX "naomi_"
|
||||
#define ROM_NAMES ";epr-21576d.bin"
|
||||
#define NVR_OPTIONAL 1
|
||||
|
||||
#elif (DC_PLATFORM==DC_PLATFORM_NAOMI2)
|
||||
|
||||
//Naomi2 : 32 mb ram, 16 mb vram, 8 mb aram, 2 mb bios, ? flash
|
||||
#define RAM_SIZE (32*1024*1024)
|
||||
#define VRAM_SIZE (16*1024*1024)
|
||||
#define ARAM_SIZE (8*1024*1024)
|
||||
#define BIOS_SIZE (2*1024*1024)
|
||||
#define BBSRAM_SIZE (32*1024)
|
||||
|
||||
#define ROM_PREFIX "n2_"
|
||||
#define ROM_NAMES
|
||||
#define NVR_OPTIONAL 1
|
||||
|
||||
#elif (DC_PLATFORM==DC_PLATFORM_ATOMISWAVE)
|
||||
|
||||
#define BUILD_ATOMISWAVE 1
|
||||
|
||||
//Atomiswave : 16 mb ram, 8 mb vram, 8 mb aram, 128kb bios on flash, 128kb battery-backed ram
|
||||
#define RAM_SIZE (16*1024*1024)
|
||||
#define VRAM_SIZE (8*1024*1024)
|
||||
#define ARAM_SIZE (8*1024*1024)
|
||||
#define BIOS_SIZE (128*1024)
|
||||
#define BBSRAM_SIZE (128*1024)
|
||||
|
||||
#define ROM_PREFIX "aw_"
|
||||
#define ROM_NAMES ";bios.ic23_l"
|
||||
#define NVR_OPTIONAL 1
|
||||
|
||||
#else
|
||||
#error invalid build config
|
||||
#endif
|
||||
|
||||
#define RAM_MASK (RAM_SIZE-1)
|
||||
#define VRAM_MASK (VRAM_SIZE-1)
|
||||
#define ARAM_MASK (ARAM_SIZE-1)
|
||||
#define BIOS_MASK (BIOS_SIZE-1)
|
||||
|
||||
#ifdef FLASH_SIZE
|
||||
#define FLASH_MASK (FLASH_SIZE-1)
|
||||
#endif
|
||||
|
||||
#ifdef BBSRAM_SIZE
|
||||
#define BBSRAM_MASK (BBSRAM_SIZE-1)
|
||||
#endif
|
||||
|
||||
#define GD_CLOCK 33868800 //GDROM XTAL -- 768fs
|
||||
|
||||
#define AICA_CORE_CLOCK (GD_CLOCK*4/3) //[45158400] GD->PLL 3:4 -> AICA CORE -- 1024fs
|
||||
#define ADAC_CLOCK (AICA_CORE_CLOCK/2) //[11289600] 44100*256, AICA CORE -> PLL 4:1 -> ADAC -- 256fs
|
||||
#define AICA_ARM_CLOCK (AICA_CORE_CLOCK/2) //[22579200] AICA CORE -> PLL 2:1 -> ARM
|
||||
#define AICA_SDRAM_CLOCK (GD_CLOCK*2) //[67737600] GD-> PLL 2 -> SDRAM
|
||||
#define SH4_MAIN_CLOCK (200*1000*1000) //[200000000] XTal(13.5) -> PLL (33.3) -> PLL 1:6 (200)
|
||||
#define SH4_RAM_CLOCK (100*1000*1000) //[100000000] XTal(13.5) -> PLL (33.3) -> PLL 1:3 (100) , also suplied to HOLLY chip
|
||||
#define G2_BUS_CLOCK (25*1000*1000) //[25000000] from Holly, from SH4_RAM_CLOCK w/ 2 2:1 plls
|
||||
|
||||
|
||||
enum ndc_error_codes
|
||||
{
|
||||
rv_ok = 0, //no error
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
xmlns:tools="http://schemas.android.com/tools">
|
||||
<application android:name="com.reicast.emulator.Emulator">
|
||||
<activity
|
||||
android:name="com.reicast.emulator.MainActivity">
|
||||
android:name="com.reicast.emulator.NativeGLActivity">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
android:name="com.reicast.emulator.Emulator"
|
||||
android:icon="@drawable/ic_launcher"
|
||||
android:label="@string/app_name"
|
||||
android:theme="@style/AppTheme"
|
||||
android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
|
||||
android:roundIcon="@drawable/ic_launcher"
|
||||
android:banner="@drawable/ic_banner"
|
||||
android:logo="@drawable/ic_banner"
|
||||
|
@ -45,12 +45,15 @@
|
|||
android:isGame="true">
|
||||
|
||||
<meta-data android:name="android.max_aspect" android:value="2.1" />
|
||||
|
||||
<activity
|
||||
android:name="com.reicast.emulator.MainActivity"
|
||||
android:name="com.reicast.emulator.GL2JNIActivity"
|
||||
android:configChanges="orientation|navigation|screenSize|screenLayout|uiMode|keyboard|keyboardHidden"
|
||||
android:label="@string/app_name"
|
||||
android:theme="@style/AppTheme.NoActionBar">
|
||||
android:screenOrientation="sensorLandscape">
|
||||
</activity>
|
||||
<activity
|
||||
android:name="com.reicast.emulator.NativeGLActivity"
|
||||
android:configChanges="orientation|navigation|screenSize|screenLayout|uiMode|keyboard|keyboardHidden"
|
||||
android:screenOrientation="sensorLandscape">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
|
@ -58,29 +61,6 @@
|
|||
<category android:name="android.intent.category.LEANBACK_LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity
|
||||
android:name="com.reicast.emulator.GL2JNIActivity"
|
||||
android:configChanges="orientation|navigation|screenSize|screenLayout|uiMode|keyboard|keyboardHidden"
|
||||
android:screenOrientation="sensorLandscape"
|
||||
android:theme="@android:style/Theme.NoTitleBar.Fullscreen" >
|
||||
</activity>
|
||||
<activity
|
||||
android:name="com.reicast.emulator.NativeGLActivity"
|
||||
android:configChanges="orientation|navigation|screenSize|screenLayout|uiMode|keyboard|keyboardHidden"
|
||||
android:screenOrientation="sensorLandscape"
|
||||
android:theme="@style/AppTheme.NoActionBar">
|
||||
</activity>
|
||||
<activity
|
||||
android:name="com.dropbox.client2.android.AuthActivity"
|
||||
android:configChanges="orientation|keyboard"
|
||||
android:launchMode="singleTask">
|
||||
<intent-filter>
|
||||
<data android:scheme="db-lowa9ps6h5k7zbo" />
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<provider
|
||||
android:name="android.support.v4.content.FileProvider"
|
||||
android:authorities="${applicationId}.provider"
|
||||
|
|
|
@ -12,50 +12,16 @@ import android.preference.PreferenceManager;
|
|||
import com.reicast.emulator.config.Config;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.FilenameFilter;
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.nio.IntBuffer;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Vector;
|
||||
import java.util.zip.GZIPInputStream;
|
||||
import java.util.zip.GZIPOutputStream;
|
||||
|
||||
import javax.microedition.khronos.opengles.GL10;
|
||||
|
||||
public class FileUtils {
|
||||
|
||||
public Collection<File> listFiles(File directory, FilenameFilter[] filter,
|
||||
int recurse) {
|
||||
|
||||
Vector<File> files = new Vector<>();
|
||||
|
||||
File[] entries = directory.listFiles();
|
||||
|
||||
if (entries != null) {
|
||||
for (File entry : entries) {
|
||||
for (FilenameFilter filefilter : filter) {
|
||||
if (filefilter.accept(directory, entry.getName())) {
|
||||
files.add(entry);
|
||||
}
|
||||
}
|
||||
if ((recurse <= -1) || (recurse > 0 && entry.isDirectory())) {
|
||||
recurse--;
|
||||
files.addAll(listFiles(entry, filter, recurse));
|
||||
recurse++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return files;
|
||||
}
|
||||
|
||||
public static void saveScreenshot(final Context c, int w, int h, GL10 gl){
|
||||
try {
|
||||
SharedPreferences mPrefs = PreferenceManager.getDefaultSharedPreferences(c);
|
||||
|
@ -80,7 +46,7 @@ public class FileUtils {
|
|||
}
|
||||
|
||||
//thank you stackoverflow
|
||||
public static Bitmap savePixels(int x, int y, int w, int h, GL10 gl)
|
||||
private static Bitmap savePixels(int x, int y, int w, int h, GL10 gl)
|
||||
{
|
||||
int b[]=new int[w*(y+h)];
|
||||
int bt[]=new int[w*h];
|
||||
|
|
|
@ -2,9 +2,12 @@ package com.reicast.emulator;
|
|||
|
||||
import android.Manifest;
|
||||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.Environment;
|
||||
|
@ -12,16 +15,13 @@ import android.os.Handler;
|
|||
import android.preference.PreferenceManager;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.design.widget.Snackbar;
|
||||
import android.support.v4.app.ActivityCompat;
|
||||
import android.util.Log;
|
||||
import android.view.Gravity;
|
||||
import android.view.InputDevice;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.ViewConfiguration;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.reicast.emulator.config.Config;
|
||||
import com.reicast.emulator.debug.GenerateLogs;
|
||||
|
@ -35,18 +35,27 @@ import java.util.List;
|
|||
|
||||
import tv.ouya.console.api.OuyaController;
|
||||
|
||||
public class BaseGLActivity extends Activity implements ActivityCompat.OnRequestPermissionsResultCallback {
|
||||
public abstract class BaseGLActivity extends Activity implements ActivityCompat.OnRequestPermissionsResultCallback {
|
||||
private static final int STORAGE_PERM_REQUEST = 1001;
|
||||
private static final int AUDIO_PERM_REQUEST = 1002;
|
||||
|
||||
protected View mView;
|
||||
protected SharedPreferences prefs;
|
||||
protected float[][] vjoy_d_cached; // Used for VJoy editing
|
||||
private AudioBackend audioBackend;
|
||||
private Handler handler = new Handler();
|
||||
public static byte[] syms;
|
||||
private boolean audioPermissionRequested;
|
||||
private boolean audioPermissionRequested = false;
|
||||
private boolean paused = true;
|
||||
private boolean resumedCalled = false;
|
||||
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
if (!getFilesDir().exists()) {
|
||||
getFilesDir().mkdir();
|
||||
}
|
||||
prefs = PreferenceManager.getDefaultSharedPreferences(this);
|
||||
|
||||
Emulator app = (Emulator)getApplicationContext();
|
||||
|
@ -57,32 +66,124 @@ public class BaseGLActivity extends Activity implements ActivityCompat.OnRequest
|
|||
|
||||
String home_directory = prefs.getString(Config.pref_home, "");
|
||||
String result = JNIdc.initEnvironment((Emulator)getApplicationContext(), home_directory);
|
||||
if (result != null)
|
||||
showToastMessage("Initialization failed: " + result, Snackbar.LENGTH_LONG);
|
||||
if (result != null) {
|
||||
AlertDialog.Builder dlgAlert = new AlertDialog.Builder(this);
|
||||
dlgAlert.setMessage("Initialization failed. Please try again and/or reinstall.\n\n"
|
||||
+ "Error: " + result);
|
||||
dlgAlert.setTitle("Reicast Error");
|
||||
dlgAlert.setPositiveButton("Exit",
|
||||
new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog,int id) {
|
||||
BaseGLActivity.this.finish();
|
||||
}
|
||||
});
|
||||
dlgAlert.setIcon(android.R.drawable.ic_dialog_alert);
|
||||
dlgAlert.setCancelable(false);
|
||||
dlgAlert.create().show();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
setStorageDirectories();
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
ActivityCompat.requestPermissions(this,
|
||||
new String[]{
|
||||
Manifest.permission.READ_EXTERNAL_STORAGE,
|
||||
Manifest.permission.WRITE_EXTERNAL_STORAGE
|
||||
},
|
||||
STORAGE_PERM_REQUEST);
|
||||
}
|
||||
|
||||
InputDeviceManager.getInstance().startListening(getApplicationContext());
|
||||
register(this);
|
||||
|
||||
audioBackend = new AudioBackend();
|
||||
|
||||
// When viewing a resource, pass its URI to the native code for opening
|
||||
Intent intent = getIntent();
|
||||
if (intent.getAction() != null) {
|
||||
if (intent.getAction().equals(Intent.ACTION_VIEW)) {
|
||||
Uri gameUri = Uri.parse(intent.getData().toString());
|
||||
// Flush the intent to prevent multiple calls
|
||||
getIntent().setData(null);
|
||||
setIntent(null);
|
||||
if (gameUri != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||
gameUri = Uri.parse(gameUri.toString().replace("content://"
|
||||
+ gameUri.getAuthority() + "/external_files", "/storage"));
|
||||
}
|
||||
if (gameUri != null)
|
||||
JNIdc.setGameUri(gameUri.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void setStorageDirectories()
|
||||
{
|
||||
String android_home_directory = Environment.getExternalStorageDirectory().getAbsolutePath();
|
||||
List<String> pathList = new ArrayList<>();
|
||||
pathList.add(android_home_directory);
|
||||
pathList.addAll(FileBrowser.getExternalMounts());
|
||||
Log.i("reicast", "External storage dirs: " + pathList);
|
||||
JNIdc.setExternalStorageDirectories(pathList.toArray());
|
||||
|
||||
InputDeviceManager.getInstance().startListening(getApplicationContext());
|
||||
register(this);
|
||||
|
||||
audioBackend = new AudioBackend();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
paused = true;
|
||||
InputDeviceManager.getInstance().stopListening();
|
||||
register(null);
|
||||
audioBackend.release();
|
||||
if (audioBackend != null)
|
||||
audioBackend.release();
|
||||
Emulator.setCurrentActivity(null);
|
||||
stopEmulator();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
resumedCalled = false;
|
||||
handleStateChange(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
resumedCalled = true;
|
||||
handleStateChange(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onWindowFocusChanged(boolean hasFocus) {
|
||||
super.onWindowFocusChanged(hasFocus);
|
||||
if (hasFocus) {
|
||||
handleStateChange(false);
|
||||
} else {
|
||||
handleStateChange(true);
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract void doPause();
|
||||
protected abstract void doResume();
|
||||
protected abstract boolean isSurfaceReady();
|
||||
|
||||
public void handleStateChange(boolean paused)
|
||||
{
|
||||
if (paused == this.paused)
|
||||
return;
|
||||
if (!paused && (!resumedCalled || !isSurfaceReady()))
|
||||
return;
|
||||
this.paused = paused;
|
||||
if (paused) {
|
||||
doPause();
|
||||
}
|
||||
else {
|
||||
doResume();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean showMenu() {
|
||||
JNIdc.guiOpenSettings();
|
||||
return true;
|
||||
|
@ -133,13 +234,7 @@ public class BaseGLActivity extends Activity implements ActivityCompat.OnRequest
|
|||
return true;
|
||||
}
|
||||
else if (JNIdc.guiIsContentBrowser()) {
|
||||
// Only if this is the main activity
|
||||
//finish();
|
||||
// so for now we hack it
|
||||
Intent startMain = new Intent(Intent.ACTION_MAIN);
|
||||
startMain.addCategory(Intent.CATEGORY_HOME);
|
||||
startMain.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
startActivity(startMain);
|
||||
finish();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -154,21 +249,6 @@ public class BaseGLActivity extends Activity implements ActivityCompat.OnRequest
|
|||
return super.onKeyDown(keyCode, event);
|
||||
}
|
||||
|
||||
private void showToastMessage(String message, int duration) {
|
||||
View view = findViewById(android.R.id.content);
|
||||
Snackbar snackbar = Snackbar.make(view, message, duration);
|
||||
View snackbarLayout = snackbar.getView();
|
||||
TextView textView = (TextView) snackbarLayout.findViewById(
|
||||
android.support.design.R.id.snackbar_text);
|
||||
textView.setGravity(Gravity.CENTER_VERTICAL);
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1)
|
||||
textView.setTextAlignment(View.TEXT_ALIGNMENT_GRAVITY);
|
||||
textView.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_notification, 0, 0, 0);
|
||||
textView.setCompoundDrawablePadding(getResources()
|
||||
.getDimensionPixelOffset(R.dimen.snackbar_icon_padding));
|
||||
snackbar.show();
|
||||
}
|
||||
|
||||
protected void stopEmulator() {
|
||||
JNIdc.stop();
|
||||
}
|
||||
|
@ -181,19 +261,18 @@ public class BaseGLActivity extends Activity implements ActivityCompat.OnRequest
|
|||
handler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
mView.setVisibility(View.INVISIBLE);
|
||||
ActivityCompat.requestPermissions(BaseGLActivity.this,
|
||||
new String[]{
|
||||
Manifest.permission.RECORD_AUDIO
|
||||
},
|
||||
0);
|
||||
AUDIO_PERM_REQUEST);
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
onRequestPermissionsResult(0, new String[] { Manifest.permission.RECORD_AUDIO },
|
||||
onRequestPermissionsResult(AUDIO_PERM_REQUEST, new String[] { Manifest.permission.RECORD_AUDIO },
|
||||
new int[] { PackageManager.PERMISSION_GRANTED });
|
||||
}
|
||||
}
|
||||
|
@ -201,12 +280,19 @@ public class BaseGLActivity extends Activity implements ActivityCompat.OnRequest
|
|||
@Override
|
||||
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
|
||||
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
||||
if (permissions.length > 0 && Manifest.permission.RECORD_AUDIO .equals(permissions[0]) && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
|
||||
if (requestCode == AUDIO_PERM_REQUEST && permissions.length > 0
|
||||
&& Manifest.permission.RECORD_AUDIO .equals(permissions[0]) && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
|
||||
SipEmulator sip = new SipEmulator();
|
||||
sip.startRecording();
|
||||
JNIdc.setupMic(sip);
|
||||
}
|
||||
mView.setVisibility(View.VISIBLE);
|
||||
else if (requestCode == STORAGE_PERM_REQUEST) {
|
||||
setStorageDirectories();
|
||||
//setup mic
|
||||
if (Emulator.micPluggedIn())
|
||||
requestRecordAudioPermission();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Called from native code
|
||||
|
@ -214,7 +300,20 @@ public class BaseGLActivity extends Activity implements ActivityCompat.OnRequest
|
|||
try {
|
||||
new GenerateLogs(this).execute(getFilesDir().getAbsolutePath());
|
||||
} catch (RuntimeException e) {
|
||||
showToastMessage("An error occurred retrieving the log file: " + e.getMessage(), Snackbar.LENGTH_LONG);
|
||||
AlertDialog.Builder dlgAlert = new AlertDialog.Builder(this);
|
||||
dlgAlert.setMessage("An error occurred retrieving the log file:\n\n"
|
||||
+ e.getMessage());
|
||||
dlgAlert.setTitle("Reicast Error");
|
||||
dlgAlert.setPositiveButton("Ok",
|
||||
new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog,int id) {
|
||||
dialog.cancel();
|
||||
}
|
||||
});
|
||||
dlgAlert.setIcon(android.R.drawable.ic_dialog_info);
|
||||
dlgAlert.setCancelable(false);
|
||||
dlgAlert.create().show();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
package com.reicast.emulator;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.Application;
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
|
@ -14,31 +13,23 @@ import com.reicast.emulator.emu.JNIdc;
|
|||
|
||||
public class Emulator extends Application {
|
||||
private static Context context;
|
||||
private static Activity currentActivity;
|
||||
private static BaseGLActivity currentActivity;
|
||||
|
||||
// see MapleDeviceType in hw/maple/maple_devs.h
|
||||
public static final int MDT_SegaController = 0;
|
||||
public static final int MDT_SegaVMU = 1;
|
||||
public static final int MDT_Microphone = 2;
|
||||
public static final int MDT_PurupuruPack = 3;
|
||||
public static final int MDT_Keyboard = 4;
|
||||
public static final int MDT_Mouse = 5;
|
||||
public static final int MDT_LightGun = 6;
|
||||
public static final int MDT_NaomiJamma = 7;
|
||||
public static final int MDT_None = 8;
|
||||
public static final int MDT_Count = 9;
|
||||
|
||||
public static boolean nosound = false;
|
||||
public static int vibrationDuration = 20;
|
||||
|
||||
public static int maple_devices[] = {
|
||||
MDT_SegaController,
|
||||
MDT_None,
|
||||
MDT_None,
|
||||
MDT_None,
|
||||
MDT_None
|
||||
};
|
||||
public static int maple_expansion_devices[][] = {
|
||||
{ MDT_SegaVMU, MDT_None },
|
||||
{ MDT_None, MDT_None },
|
||||
{ MDT_None, MDT_None },
|
||||
{ MDT_None, MDT_None },
|
||||
{ MDT_None, MDT_None },
|
||||
|
@ -56,7 +47,7 @@ public class Emulator extends Application {
|
|||
|
||||
/**
|
||||
* Fetch current configuration settings from the emulator and save them
|
||||
*
|
||||
* Called from JNI code
|
||||
*/
|
||||
public void SaveAndroidSettings(String homeDirectory)
|
||||
{
|
||||
|
@ -71,8 +62,8 @@ public class Emulator extends Application {
|
|||
AudioBackend.getInstance().enableSound(!Emulator.nosound);
|
||||
|
||||
FileBrowser.installButtons(prefs);
|
||||
if (micPluggedIn() && currentActivity instanceof NativeGLActivity) {
|
||||
((NativeGLActivity)currentActivity).requestRecordAudioPermission();
|
||||
if (micPluggedIn() && currentActivity instanceof BaseGLActivity) {
|
||||
((BaseGLActivity)currentActivity).requestRecordAudioPermission();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -95,11 +86,11 @@ public class Emulator extends Application {
|
|||
return Emulator.context;
|
||||
}
|
||||
|
||||
public static Activity getCurrentActivity() {
|
||||
public static BaseGLActivity getCurrentActivity() {
|
||||
return Emulator.currentActivity;
|
||||
}
|
||||
|
||||
public static void setCurrentActivity(Activity activity) {
|
||||
public static void setCurrentActivity(BaseGLActivity activity) {
|
||||
Emulator.currentActivity = activity;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,35 +1,9 @@
|
|||
package com.reicast.emulator;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.graphics.Typeface;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.net.Uri;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.Environment;
|
||||
import android.os.Vibrator;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.support.constraint.ConstraintLayout;
|
||||
import android.support.design.widget.Snackbar;
|
||||
import android.support.graphics.drawable.VectorDrawableCompat;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v4.content.FileProvider;
|
||||
import android.view.Gravity;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.ScrollView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.android.util.FileUtils;
|
||||
import com.reicast.emulator.config.Config;
|
||||
import com.reicast.emulator.emu.JNIdc;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
|
@ -37,56 +11,13 @@ import java.io.File;
|
|||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.FilenameFilter;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
public class FileBrowser extends Fragment {
|
||||
|
||||
private Vibrator vib;
|
||||
private boolean games;
|
||||
private String searchQuery = null;
|
||||
private OnItemSelectedListener mCallback;
|
||||
|
||||
private SharedPreferences mPrefs;
|
||||
private File sdcard = Environment.getExternalStorageDirectory();
|
||||
private String home_directory = sdcard.getAbsolutePath();
|
||||
private String game_directory = sdcard.getAbsolutePath();
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
mPrefs = PreferenceManager.getDefaultSharedPreferences(getActivity());
|
||||
home_directory = mPrefs.getString(Config.pref_home, home_directory);
|
||||
game_directory = mPrefs.getString(Config.pref_games, game_directory);
|
||||
|
||||
Bundle b = getArguments();
|
||||
if (b != null) {
|
||||
if (games = b.getBoolean("games_entry", false)) {
|
||||
if (b.getString("path_entry") != null) {
|
||||
home_directory = b.getString("path_entry");
|
||||
}
|
||||
} else {
|
||||
if (b.getString("path_entry") != null) {
|
||||
game_directory = b.getString("path_entry");
|
||||
}
|
||||
}
|
||||
if (b.getString("search_params") != null) {
|
||||
searchQuery = b.getString("search_params");
|
||||
}
|
||||
}
|
||||
}
|
||||
public class FileBrowser {
|
||||
android.support.v4.content.FileProvider provider; // To avoid ClassNotFoundException at runtime
|
||||
|
||||
public static HashSet<String> getExternalMounts() {
|
||||
final HashSet<String> out = new HashSet<>();
|
||||
|
@ -126,61 +57,6 @@ public class FileBrowser extends Fragment {
|
|||
return out;
|
||||
}
|
||||
|
||||
// Container Activity must implement this interface
|
||||
public interface OnItemSelectedListener {
|
||||
void onGameSelected(Uri uri);
|
||||
void onFolderSelected(Uri uri);
|
||||
}
|
||||
|
||||
@Override @SuppressWarnings("deprecation")
|
||||
public void onAttach(Activity activity) {
|
||||
super.onAttach(activity);
|
||||
|
||||
// This makes sure that the container activity has implemented
|
||||
// the callback interface. If not, it throws an exception
|
||||
try {
|
||||
mCallback = (OnItemSelectedListener) activity;
|
||||
} catch (ClassCastException e) {
|
||||
throw new ClassCastException(activity.toString()
|
||||
+ " must implement OnItemSelectedListener");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
return inflater.inflate(R.layout.browser_fragment, container, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(View view, Bundle savedInstanceState) {
|
||||
// setContentView(R.layout.activity_main);
|
||||
|
||||
vib = (Vibrator) getActivity().getSystemService(Context.VIBRATOR_SERVICE);
|
||||
|
||||
/*
|
||||
* OnTouchListener viblist=new OnTouchListener() {
|
||||
*
|
||||
* public boolean onTouch(View v, MotionEvent event) { if
|
||||
* (event.getActionMasked()==MotionEvent.ACTION_DOWN) vib.vibrate(50);
|
||||
* return false; } };
|
||||
*
|
||||
* findViewById(R.id.config).setOnTouchListener(viblist);
|
||||
* findViewById(R.id.about).setOnTouchListener(viblist);
|
||||
*/
|
||||
|
||||
String temp = mPrefs.getString(Config.pref_home, null);
|
||||
if (temp == null || !new File(temp).isDirectory()) {
|
||||
showToastMessage(getActivity().getString(R.string.config_home), Snackbar.LENGTH_LONG);
|
||||
}
|
||||
installButtons(mPrefs);
|
||||
if (!games) {
|
||||
new LocateGames(this, R.array.flash).execute(home_directory);
|
||||
} else {
|
||||
new LocateGames(this, R.array.images).execute(game_directory);
|
||||
}
|
||||
}
|
||||
|
||||
public static void installButtons(SharedPreferences prefs) {
|
||||
try {
|
||||
File buttons = null;
|
||||
|
@ -216,389 +92,4 @@ public class FileBrowser extends Fragment {
|
|||
ioe.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private static final class LocateGames extends AsyncTask<String, Integer, List<File>> {
|
||||
|
||||
private WeakReference<FileBrowser> browser;
|
||||
private int array;
|
||||
|
||||
LocateGames(FileBrowser context, int arrayType) {
|
||||
browser = new WeakReference<>(context);
|
||||
this.array = arrayType;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<File> doInBackground(String... paths) {
|
||||
File storage = new File(paths[0]);
|
||||
|
||||
// array of valid image file extensions
|
||||
String[] mediaTypes = browser.get().getActivity().getResources().getStringArray(array);
|
||||
FilenameFilter[] filter = new FilenameFilter[mediaTypes.length];
|
||||
|
||||
int i = 0;
|
||||
for (final String type : mediaTypes) {
|
||||
filter[i] = new FilenameFilter() {
|
||||
|
||||
public boolean accept(File dir, String name) {
|
||||
return !dir.getName().equals("obb") && !dir.getName().equals("cache")
|
||||
&& !dir.getName().startsWith(".") && !name.startsWith(".")
|
||||
&& (array != R.array.flash || name.startsWith("dc_"))
|
||||
&& (browser.get().searchQuery == null
|
||||
|| name.toLowerCase(Locale.getDefault()).contains(
|
||||
browser.get().searchQuery.toLowerCase(Locale.getDefault())))
|
||||
&& StringUtils.endsWithIgnoreCase(name, "." + type);
|
||||
}
|
||||
};
|
||||
i++;
|
||||
}
|
||||
|
||||
FileUtils fileUtils = new FileUtils();
|
||||
int recurse = 2;
|
||||
if (array == R.array.flash) {
|
||||
recurse = 4;
|
||||
}
|
||||
Collection<File> files = fileUtils.listFiles(storage, filter, recurse);
|
||||
return (List<File>) files;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(List<File> items) {
|
||||
LinearLayout list = (LinearLayout) browser.get().getActivity().findViewById(R.id.game_list);
|
||||
if (list.getChildCount() > 0) {
|
||||
list.removeAllViews();
|
||||
}
|
||||
|
||||
String heading = browser.get().getActivity().getString(R.string.games_listing);
|
||||
browser.get().createListHeader(heading, list, array == R.array.images);
|
||||
if (items != null && !items.isEmpty()) {
|
||||
for (int i = 0; i < items.size(); i++) {
|
||||
browser.get().createListItem(list, items.get(i), i, array == R.array.images);
|
||||
}
|
||||
|
||||
} else if (browser.get().searchQuery != null) {
|
||||
final View childview = browser.get().getActivity().getLayoutInflater().inflate(
|
||||
R.layout.browser_fragment_item, null, false);
|
||||
((TextView) childview.findViewById(R.id.item_name)).setText(R.string.no_games);
|
||||
((ImageView) childview.findViewById(R.id.item_icon))
|
||||
.setImageResource(R.mipmap.disk_missing);
|
||||
list.addView(childview);
|
||||
|
||||
} else {
|
||||
browser.get().browseStorage(array == R.array.images);
|
||||
}
|
||||
list.invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
private void browseStorage(boolean images) {
|
||||
if (images) {
|
||||
(new navigate(this)).executeOnExecutor(
|
||||
AsyncTask.THREAD_POOL_EXECUTOR, new File(home_directory));
|
||||
} else {
|
||||
if (game_directory.equals(sdcard.getAbsolutePath())) {
|
||||
HashSet<String> extStorage = FileBrowser.getExternalMounts();
|
||||
if (extStorage != null && !extStorage.isEmpty()) {
|
||||
for (String sd : extStorage) {
|
||||
String sdCardPath = sd.replace("mnt/media_rw", "storage");
|
||||
if (!sdCardPath.equals(sdcard.getAbsolutePath())) {
|
||||
if (new File(sdCardPath).canRead()) {
|
||||
(new navigate(this)).execute(new File(sdCardPath));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
(new navigate(this)).executeOnExecutor(
|
||||
AsyncTask.THREAD_POOL_EXECUTOR, new File(game_directory));
|
||||
}
|
||||
}
|
||||
|
||||
private void createListHeader(String header_text, View view, boolean hasBios) {
|
||||
if (hasBios && getResources().getString(R.string.flavor).equals("dreamcast")) {
|
||||
final View childview = getActivity().getLayoutInflater().inflate(
|
||||
R.layout.bios_list_item, null, false);
|
||||
|
||||
((TextView) childview.findViewById(R.id.item_name)).setText(R.string.boot_bios);
|
||||
ImageView icon = (ImageView) childview.findViewById(R.id.item_icon);
|
||||
icon.setImageResource(R.mipmap.disk_bios);
|
||||
configureTheme(childview, true);
|
||||
|
||||
childview.setTag(null);
|
||||
|
||||
childview.findViewById(R.id.childview).setOnClickListener(
|
||||
new OnClickListener() {
|
||||
public void onClick(View view) {
|
||||
vib.vibrate(50);
|
||||
mCallback.onGameSelected(Uri.EMPTY);
|
||||
vib.vibrate(250);
|
||||
}
|
||||
});
|
||||
((ViewGroup) view).addView(childview);
|
||||
}
|
||||
if (searchQuery != null) {
|
||||
final View childview = getActivity().getLayoutInflater().inflate(
|
||||
R.layout.bios_list_item, null, false);
|
||||
|
||||
((TextView) childview.findViewById(R.id.item_name)).setText(R.string.clear_search);
|
||||
ImageView icon = (ImageView) childview.findViewById(R.id.item_icon);
|
||||
icon.setImageResource(R.mipmap.disk_unknown);
|
||||
configureTheme(childview, true);
|
||||
|
||||
childview.setTag(null);
|
||||
|
||||
childview.findViewById(R.id.childview).setOnClickListener(
|
||||
new OnClickListener() {
|
||||
public void onClick(View view) {
|
||||
searchQuery = null;
|
||||
new LocateGames(FileBrowser.this,
|
||||
R.array.images).execute(game_directory);
|
||||
}
|
||||
});
|
||||
((ViewGroup) view).addView(childview);
|
||||
}
|
||||
|
||||
final View headerView = getActivity().getLayoutInflater().inflate(
|
||||
R.layout.browser_fragment_header, null, false);
|
||||
((ImageView) headerView.findViewById(R.id.item_icon))
|
||||
.setImageResource(R.drawable.open_folder);
|
||||
((TextView) headerView.findViewById(R.id.item_name))
|
||||
.setText(header_text);
|
||||
((TextView) headerView.findViewById(R.id.item_name))
|
||||
.setTypeface(Typeface.DEFAULT_BOLD);
|
||||
((ViewGroup) view).addView(headerView);
|
||||
|
||||
}
|
||||
|
||||
private void createListItem(LinearLayout list, final File game, final int index, final boolean isGame) {
|
||||
final View childview = getActivity().getLayoutInflater().inflate(
|
||||
R.layout.browser_fragment_item, null, false);
|
||||
|
||||
XMLParser xmlParser = new XMLParser(game, index, mPrefs);
|
||||
xmlParser.setViewParent(getActivity(), childview, mCallback);
|
||||
|
||||
childview.findViewById(R.id.childview).setOnClickListener(
|
||||
new OnClickListener() {
|
||||
public void onClick(View view) {
|
||||
if (isGame) {
|
||||
vib.vibrate(50);
|
||||
Uri gameUri = Uri.EMPTY;
|
||||
if (game != null) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||
gameUri = FileProvider.getUriForFile(getActivity(),
|
||||
"com.reicast.emulator.provider", game);
|
||||
} else {
|
||||
gameUri = Uri.fromFile(game);
|
||||
}
|
||||
}
|
||||
mCallback.onGameSelected(gameUri);
|
||||
vib.vibrate(250);
|
||||
} else {
|
||||
vib.vibrate(50);
|
||||
home_directory = game.getAbsolutePath().substring(0,
|
||||
game.getAbsolutePath().lastIndexOf(File.separator))
|
||||
.replace("/data", "");
|
||||
if (requireDataBIOS()) {
|
||||
showToastMessage(getActivity().getString(R.string.config_data,
|
||||
home_directory), Snackbar.LENGTH_LONG);
|
||||
}
|
||||
mPrefs.edit().putString(Config.pref_home, home_directory).apply();
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||
mCallback.onFolderSelected(FileProvider.getUriForFile(getActivity(),
|
||||
"com.reicast.emulator.provider", new File(home_directory)));
|
||||
} else {
|
||||
mCallback.onFolderSelected(
|
||||
Uri.fromFile(new File(home_directory)));
|
||||
}
|
||||
//JNIdc.config(home_directory);
|
||||
}
|
||||
}
|
||||
});
|
||||
configureTheme(childview, false);
|
||||
list.addView(childview);
|
||||
xmlParser.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, game.getName());
|
||||
}
|
||||
|
||||
private static class navigate extends AsyncTask<File, Integer, List<File>> {
|
||||
|
||||
private WeakReference<FileBrowser> browser;
|
||||
private String heading;
|
||||
private File parent;
|
||||
|
||||
navigate(FileBrowser context) {
|
||||
browser = new WeakReference<>(context);
|
||||
}
|
||||
|
||||
private final class DirSort implements Comparator<File> {
|
||||
@Override
|
||||
public int compare(File filea, File fileb) {
|
||||
return ((filea.isFile() ? "a" : "b") + filea.getName().toLowerCase(
|
||||
Locale.getDefault()))
|
||||
.compareTo((fileb.isFile() ? "a" : "b")
|
||||
+ fileb.getName().toLowerCase(Locale.getDefault()));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPreExecute() {
|
||||
LinearLayout listView = (LinearLayout)
|
||||
browser.get().getActivity().findViewById(R.id.game_list);
|
||||
if (listView.getChildCount() > 0)
|
||||
listView.removeAllViews();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<File> doInBackground(File... paths) {
|
||||
heading = paths[0].getAbsolutePath();
|
||||
|
||||
ArrayList<File> list = new ArrayList<>();
|
||||
|
||||
File flist[] = paths[0].listFiles();
|
||||
parent = paths[0].getParentFile();
|
||||
|
||||
list.add(null);
|
||||
|
||||
if (parent != null) {
|
||||
list.add(parent);
|
||||
}
|
||||
|
||||
if (flist != null) {
|
||||
Arrays.sort(flist, new DirSort());
|
||||
Collections.addAll(list, flist);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(List<File> list) {
|
||||
if (list != null && !list.isEmpty()) {
|
||||
LinearLayout listView = (LinearLayout)
|
||||
browser.get().getActivity().findViewById(R.id.game_list);
|
||||
browser.get().createListHeader(heading, listView, false);
|
||||
for (final File file : list) {
|
||||
if (file != null && !file.isDirectory() && !file.getAbsolutePath().equals("/data"))
|
||||
continue;
|
||||
final View childview = browser.get().getActivity().getLayoutInflater().inflate(
|
||||
R.layout.browser_fragment_item, null, false);
|
||||
|
||||
if (file == null) {
|
||||
((TextView) childview.findViewById(R.id.item_name)).setText(R.string.folder_select);
|
||||
} else if (file == parent)
|
||||
((TextView) childview.findViewById(R.id.item_name)).setText("..");
|
||||
else
|
||||
((TextView) childview.findViewById(R.id.item_name)).setText(file.getName());
|
||||
|
||||
ImageView icon = (ImageView) childview.findViewById(R.id.item_icon);
|
||||
icon.setImageResource(file == null
|
||||
? R.drawable.ic_settings: file.isDirectory()
|
||||
? R.drawable.ic_folder_black_24dp : R.drawable.disk_unknown);
|
||||
browser.get().configureTheme(childview, true);
|
||||
|
||||
childview.setTag(file);
|
||||
|
||||
// vw.findViewById(R.id.childview).setBackgroundColor(0xFFFFFFFF);
|
||||
|
||||
childview.findViewById(R.id.childview).setOnClickListener(
|
||||
new OnClickListener() {
|
||||
public void onClick(View view) {
|
||||
if (file != null && file.isDirectory()) {
|
||||
(new navigate(browser.get())).executeOnExecutor(
|
||||
AsyncTask.THREAD_POOL_EXECUTOR, file);
|
||||
ScrollView sv = (ScrollView) browser.get().getActivity()
|
||||
.findViewById(R.id.game_scroller);
|
||||
sv.scrollTo(0, 0);
|
||||
browser.get().vib.vibrate(50);
|
||||
} else if (view.getTag() == null) {
|
||||
browser.get().vib.vibrate(250);
|
||||
|
||||
if (browser.get().games) {
|
||||
browser.get().game_directory = heading;
|
||||
browser.get().mPrefs.edit().putString(
|
||||
Config.pref_games, heading).apply();
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||
browser.get().mCallback.onFolderSelected(FileProvider
|
||||
.getUriForFile(browser.get().getActivity(),
|
||||
"com.reicast.emulator.provider",
|
||||
new File(browser.get().game_directory)));
|
||||
} else {
|
||||
browser.get().mCallback.onFolderSelected(Uri.fromFile(
|
||||
new File(browser.get().game_directory)));
|
||||
}
|
||||
|
||||
|
||||
} else {
|
||||
browser.get().home_directory = heading
|
||||
.replace("/data", "");
|
||||
browser.get().mPrefs.edit().putString(
|
||||
Config.pref_home, browser.get().home_directory).apply();
|
||||
if (browser.get().requireDataBIOS()) {
|
||||
browser.get().showToastMessage(browser.get().getActivity()
|
||||
.getString(R.string.config_data, browser.get()
|
||||
.home_directory), Snackbar.LENGTH_LONG);
|
||||
}
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||
browser.get().mCallback.onFolderSelected(FileProvider
|
||||
.getUriForFile(browser.get().getActivity(),
|
||||
"com.reicast.emulator.provider",
|
||||
new File(browser.get().home_directory)));
|
||||
} else {
|
||||
browser.get().mCallback.onFolderSelected(Uri.fromFile(
|
||||
new File(browser.get().home_directory)));
|
||||
}
|
||||
//JNIdc.config(browser.get().home_directory);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
});
|
||||
listView.addView(childview);
|
||||
}
|
||||
listView.invalidate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean requireDataBIOS() {
|
||||
File data_directory = new File(home_directory, "data");
|
||||
if (data_directory.exists() && data_directory.isDirectory()) {
|
||||
File bios = new File(home_directory, "data/dc_boot.bin");
|
||||
File flash = new File(home_directory, "data/dc_flash.bin");
|
||||
return !(bios.exists() && flash.exists());
|
||||
} else {
|
||||
if (data_directory.mkdirs()) {
|
||||
File bios = new File(home_directory, "dc_boot.bin");
|
||||
if (bios.renameTo(new File(home_directory, "data/dc_boot.bin"))) {
|
||||
return !new File(home_directory, "dc_flash.bin").renameTo(
|
||||
new File(home_directory, "data/dc_flash.bin"));
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private void configureTheme(View childview, boolean useTint) {
|
||||
}
|
||||
|
||||
private void showToastMessage(String message, int duration) {
|
||||
ConstraintLayout layout = (ConstraintLayout) getActivity().findViewById(R.id.mainui_layout);
|
||||
Snackbar snackbar = Snackbar.make(layout, message, duration);
|
||||
View snackbarLayout = snackbar.getView();
|
||||
TextView textView = (TextView) snackbarLayout.findViewById(
|
||||
android.support.design.R.id.snackbar_text);
|
||||
textView.setGravity(Gravity.CENTER_VERTICAL);
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1)
|
||||
textView.setTextAlignment(View.TEXT_ALIGNMENT_GRAVITY);
|
||||
Drawable drawable;
|
||||
if (android.os.Build.VERSION.SDK_INT > Build.VERSION_CODES.M) {
|
||||
drawable = getResources().getDrawable(
|
||||
R.drawable.ic_subdirectory_arrow_right, getActivity().getTheme());
|
||||
} else {
|
||||
drawable = VectorDrawableCompat.create(getResources(),
|
||||
R.drawable.ic_subdirectory_arrow_right, getActivity().getTheme());
|
||||
}
|
||||
textView.setCompoundDrawablesWithIntrinsicBounds(drawable, null, null, null);
|
||||
textView.setCompoundDrawablePadding(getResources()
|
||||
.getDimensionPixelOffset(R.dimen.snackbar_icon_padding));
|
||||
snackbar.show();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,16 +2,19 @@ package com.reicast.emulator;
|
|||
|
||||
import android.os.Bundle;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.support.v4.app.ActivityCompat;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.Window;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.RelativeLayout;
|
||||
|
||||
import com.reicast.emulator.config.Config;
|
||||
import com.reicast.emulator.emu.GL2JNIView;
|
||||
import com.reicast.emulator.emu.JNIdc;
|
||||
import com.reicast.emulator.periph.VJoy;
|
||||
|
||||
public class GL2JNIActivity extends BaseGLActivity implements ActivityCompat.OnRequestPermissionsResultCallback {
|
||||
public class GL2JNIActivity extends BaseGLActivity {
|
||||
private static ViewGroup mLayout; // used for text input
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle icicle) {
|
||||
requestWindowFeature(Window.FEATURE_NO_TITLE);
|
||||
|
@ -28,11 +31,10 @@ public class GL2JNIActivity extends BaseGLActivity implements ActivityCompat.OnR
|
|||
// Create the actual GLES view
|
||||
mView = new GL2JNIView(GL2JNIActivity.this, false,
|
||||
prefs.getInt(Config.pref_renderdepth, 24), 8);
|
||||
setContentView(mView);
|
||||
mLayout = new RelativeLayout(this);
|
||||
mLayout.addView(mView);
|
||||
|
||||
//setup mic
|
||||
if (Emulator.micPluggedIn())
|
||||
requestRecordAudioPermission();
|
||||
setContentView(mLayout);
|
||||
}
|
||||
|
||||
public void screenGrab() {
|
||||
|
@ -40,23 +42,18 @@ public class GL2JNIActivity extends BaseGLActivity implements ActivityCompat.OnR
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
protected void doPause() {
|
||||
((GL2JNIView)mView).onPause();
|
||||
JNIdc.pause();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
if (mView != null) {
|
||||
((GL2JNIView)mView).onDestroy();
|
||||
}
|
||||
protected boolean isSurfaceReady() {
|
||||
return true; // FIXME
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
protected void doResume() {
|
||||
((GL2JNIView)mView).onResume();
|
||||
JNIdc.resume();
|
||||
}
|
||||
|
|
|
@ -1,195 +0,0 @@
|
|||
package com.reicast.emulator;
|
||||
|
||||
import android.Manifest;
|
||||
import android.app.AlertDialog;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v4.app.ActivityCompat;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.view.View;
|
||||
import android.view.View.OnSystemUiVisibilityChangeListener;
|
||||
import android.view.WindowManager;
|
||||
|
||||
import com.reicast.emulator.debug.GenerateLogs;
|
||||
import com.reicast.emulator.emu.JNIdc;
|
||||
|
||||
import java.lang.Thread.UncaughtExceptionHandler;
|
||||
import java.util.List;
|
||||
|
||||
public class MainActivity extends AppCompatActivity {
|
||||
private static final int PERMISSION_REQUEST = 1001;
|
||||
|
||||
private boolean hasAndroidMarket = false;
|
||||
private boolean renderer_started = false;
|
||||
private Uri gameUri;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_main);
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
||||
getWindow().getDecorView().setOnSystemUiVisibilityChangeListener (new OnSystemUiVisibilityChangeListener() {
|
||||
public void onSystemUiVisibilityChange(int visibility) {
|
||||
if ((visibility & View.SYSTEM_UI_FLAG_FULLSCREEN) == 0) {
|
||||
getWindow().getDecorView().setSystemUiVisibility(
|
||||
View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
|
||||
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
|
||||
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
|
||||
| View.SYSTEM_UI_FLAG_FULLSCREEN
|
||||
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
|
||||
}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
getWindow().setFlags (WindowManager.LayoutParams.FLAG_FULLSCREEN,
|
||||
WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
||||
}
|
||||
|
||||
final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
|
||||
|
||||
String prior_error = prefs.getString("prior_error", null);
|
||||
if (prior_error != null) {
|
||||
displayLogOutput(prior_error);
|
||||
prefs.edit().remove("prior_error").apply();
|
||||
}
|
||||
UncaughtExceptionHandler mUEHandler = new Thread.UncaughtExceptionHandler() {
|
||||
public void uncaughtException(Thread t, Throwable error) {
|
||||
if (error != null) {
|
||||
StringBuilder output = new StringBuilder();
|
||||
for (StackTraceElement trace : error.getStackTrace()) {
|
||||
output.append(trace.toString());
|
||||
output.append("\n");
|
||||
}
|
||||
prefs.edit().putString("prior_error", output.toString()).apply();
|
||||
error.printStackTrace();
|
||||
android.os.Process.killProcess(android.os.Process.myPid());
|
||||
System.exit(0);
|
||||
}
|
||||
}
|
||||
};
|
||||
Thread.setDefaultUncaughtExceptionHandler(mUEHandler);
|
||||
|
||||
Intent market = new Intent(Intent.ACTION_VIEW, Uri.parse("market://search?q=dummy"));
|
||||
if (isCallable(market)) {
|
||||
hasAndroidMarket = true;
|
||||
}
|
||||
|
||||
if (!getFilesDir().exists()) {
|
||||
getFilesDir().mkdir();
|
||||
}
|
||||
|
||||
// When viewing a resource, pass its URI to the native code for opening
|
||||
Intent intent = getIntent();
|
||||
if (intent.getAction() != null) {
|
||||
if (intent.getAction().equals(Intent.ACTION_VIEW)) {
|
||||
gameUri = Uri.parse(intent.getData().toString());
|
||||
// Flush the intent to prevent multiple calls
|
||||
getIntent().setData(null);
|
||||
setIntent(null);
|
||||
}
|
||||
}
|
||||
|
||||
if (prior_error == null) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
ActivityCompat.requestPermissions(MainActivity.this,
|
||||
new String[]{
|
||||
Manifest.permission.READ_EXTERNAL_STORAGE,
|
||||
Manifest.permission.WRITE_EXTERNAL_STORAGE
|
||||
},
|
||||
PERMISSION_REQUEST);
|
||||
} else
|
||||
startNativeRenderer();
|
||||
}
|
||||
}
|
||||
|
||||
public void generateErrorLog() {
|
||||
new GenerateLogs(MainActivity.this).execute(getFilesDir().getAbsolutePath());
|
||||
}
|
||||
|
||||
/**
|
||||
* Display a dialog to notify the user of prior crash
|
||||
*
|
||||
* @param error
|
||||
* A generalized summary of the crash cause
|
||||
*/
|
||||
private void displayLogOutput(final String error) {
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
|
||||
builder.setTitle(R.string.report_issue);
|
||||
builder.setMessage(error);
|
||||
builder.setPositiveButton(R.string.report,
|
||||
new DialogInterface.OnClickListener() {
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
generateErrorLog();
|
||||
startNativeRenderer();
|
||||
}
|
||||
});
|
||||
builder.setNegativeButton(R.string.dismiss,
|
||||
new DialogInterface.OnClickListener() {
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
dialog.dismiss();
|
||||
startNativeRenderer();
|
||||
}
|
||||
});
|
||||
builder.create();
|
||||
builder.show();
|
||||
}
|
||||
|
||||
private void startNativeRenderer() {
|
||||
if (renderer_started)
|
||||
return;
|
||||
renderer_started = true;
|
||||
|
||||
if (gameUri != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||
gameUri = Uri.parse(gameUri.toString().replace("content://"
|
||||
+ gameUri.getAuthority() + "/external_files", "/storage"));
|
||||
}
|
||||
|
||||
if (gameUri != null)
|
||||
JNIdc.setGameUri(gameUri.toString());
|
||||
Intent intent = new Intent("com.reicast.EMULATOR",
|
||||
//gameUri, getApplicationContext(), GL2JNIActivity.class);
|
||||
gameUri, getApplicationContext(), NativeGLActivity.class);
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
|
||||
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
|
||||
startActivity(intent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onWindowFocusChanged(boolean hasFocus) {
|
||||
super.onWindowFocusChanged(hasFocus);
|
||||
if (hasFocus && Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
||||
getWindow().getDecorView().setSystemUiVisibility(
|
||||
View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
|
||||
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
|
||||
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
|
||||
| View.SYSTEM_UI_FLAG_FULLSCREEN
|
||||
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isCallable(Intent intent) {
|
||||
List<ResolveInfo> list = getPackageManager().queryIntentActivities(
|
||||
intent, PackageManager.MATCH_DEFAULT_ONLY);
|
||||
return list.size() > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
|
||||
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
||||
if (permissions.length > 0 && (Manifest.permission.READ_EXTERNAL_STORAGE.equals(permissions[0]) || Manifest.permission.WRITE_EXTERNAL_STORAGE.equals(permissions[0]))
|
||||
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
|
||||
startNativeRenderer();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -2,7 +2,9 @@ package com.reicast.emulator;
|
|||
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.Window;
|
||||
import android.widget.RelativeLayout;
|
||||
|
||||
import com.reicast.emulator.emu.JNIdc;
|
||||
import com.reicast.emulator.emu.NativeGLView;
|
||||
|
@ -10,6 +12,8 @@ import com.reicast.emulator.periph.VJoy;
|
|||
|
||||
public final class NativeGLActivity extends BaseGLActivity {
|
||||
|
||||
private static ViewGroup mLayout; // used for text input
|
||||
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
requestWindowFeature(Window.FEATURE_NO_TITLE);
|
||||
|
@ -17,28 +21,28 @@ public final class NativeGLActivity extends BaseGLActivity {
|
|||
super.onCreate(savedInstanceState);
|
||||
|
||||
// Create the actual GL view
|
||||
// mView = new NativeGLView(this);
|
||||
// setContentView(mView);
|
||||
setContentView(R.layout.nativegl_content);
|
||||
mView = findViewById(R.id.glView);
|
||||
mView = new NativeGLView(this);
|
||||
mLayout = new RelativeLayout(this);
|
||||
mLayout.addView(mView);
|
||||
|
||||
//setup mic
|
||||
if (Emulator.micPluggedIn())
|
||||
requestRecordAudioPermission();
|
||||
setContentView(mLayout);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
protected void doPause() {
|
||||
((NativeGLView)mView).pause();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
protected void doResume() {
|
||||
((NativeGLView)mView).resume();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSurfaceReady() {
|
||||
return ((NativeGLView)mView).isSurfaceReady();
|
||||
}
|
||||
|
||||
// Called from native code
|
||||
private void VJoyStartEditing() {
|
||||
vjoy_d_cached = VJoy.readCustomVjoyValues(getApplicationContext());
|
||||
|
|
|
@ -1,368 +0,0 @@
|
|||
package com.reicast.emulator;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.drawable.BitmapDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.net.ConnectivityManager;
|
||||
import android.net.NetworkInfo;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Build;
|
||||
import android.view.View;
|
||||
import android.view.View.OnLongClickListener;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.reicast.emulator.FileBrowser.OnItemSelectedListener;
|
||||
import com.reicast.emulator.config.Config;
|
||||
|
||||
import org.apache.commons.io.FilenameUtils;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NodeList;
|
||||
import org.xml.sax.InputSource;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStream;
|
||||
import java.io.StringReader;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.Locale;
|
||||
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
|
||||
public class XMLParser extends AsyncTask<String, Integer, String> {
|
||||
|
||||
private SharedPreferences mPrefs;
|
||||
private File game;
|
||||
private int index;
|
||||
private OnItemSelectedListener mCallback;
|
||||
private String game_name;
|
||||
private Drawable game_icon;
|
||||
private String gameId;
|
||||
private String game_details;
|
||||
|
||||
private WeakReference<Context> mContext;
|
||||
private WeakReference<View> childview;
|
||||
|
||||
XMLParser(File game, int index, SharedPreferences mPrefs) {
|
||||
this.mPrefs = mPrefs;
|
||||
this.game = game;
|
||||
this.index = index;
|
||||
}
|
||||
|
||||
public void setViewParent(Context reference, View childview, OnItemSelectedListener mCallback) {
|
||||
this.mContext = new WeakReference<>(reference);
|
||||
this.childview = new WeakReference<>(childview);
|
||||
this.mCallback = mCallback;
|
||||
initializeDefaults();
|
||||
}
|
||||
|
||||
private void setGameID(String id) {
|
||||
this.gameId = id;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String doInBackground(String... params) {
|
||||
String filename = game_name = params[0];
|
||||
if (isNetworkAvailable() && mPrefs.getBoolean(Config.pref_gamedetails, false)) {
|
||||
String xmlUrl;
|
||||
if (gameId != null) {
|
||||
xmlUrl = "http://legacy.thegamesdb.net/api/GetGame.php?platform=sega+dreamcast&id=" + gameId;
|
||||
} else {
|
||||
filename = filename.substring(0, filename.lastIndexOf("."));
|
||||
try {
|
||||
filename = URLEncoder.encode(filename, "UTF-8");
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
filename = filename.replace(" ", "+");
|
||||
}
|
||||
xmlUrl = "http://legacy.thegamesdb.net/api/GetGamesList.php?platform=sega+dreamcast&name=" + filename;
|
||||
}
|
||||
|
||||
try {
|
||||
HttpURLConnection conn = (HttpURLConnection) new URL(xmlUrl).openConnection();
|
||||
conn.setRequestMethod("POST");
|
||||
conn.setDoInput(true);
|
||||
|
||||
InputStream in = conn.getInputStream();
|
||||
BufferedReader streamReader = new BufferedReader(
|
||||
new InputStreamReader(in, "UTF-8"));
|
||||
StringBuilder responseStrBuilder = new StringBuilder();
|
||||
|
||||
String inputStr;
|
||||
while ((inputStr = streamReader.readLine()) != null)
|
||||
responseStrBuilder.append(inputStr);
|
||||
|
||||
in.close();
|
||||
return responseStrBuilder.toString();
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(String gameData) {
|
||||
if (gameData != null) {
|
||||
try {
|
||||
Document doc = getDomElement(gameData);
|
||||
if (doc.getElementsByTagName("Game") != null) {
|
||||
Element root = (Element) doc.getElementsByTagName("Game").item(0);
|
||||
if (gameId == null) {
|
||||
XMLParser xmlParser = new XMLParser(game, index, mPrefs);
|
||||
xmlParser.setViewParent(mContext.get(), childview.get(), mCallback);
|
||||
xmlParser.setGameID(getValue(root, "id"));
|
||||
xmlParser.execute(game_name);
|
||||
} else if (root != null) {
|
||||
String name = getValue(root, "GameTitle");
|
||||
if (!name.equals(""))
|
||||
game_name = name + " [" + FilenameUtils.getExtension(
|
||||
game.getName()).toUpperCase(Locale.getDefault()) + "]";
|
||||
game_details = getValue(root, "Overview");
|
||||
getBoxart((Element) root.getElementsByTagName("Images").item(0));
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
if (childview.get() != null) {
|
||||
((TextView) childview.get().findViewById(R.id.item_name)).setText(game_name);
|
||||
|
||||
if (mPrefs.getBoolean(Config.pref_gamedetails, false)) {
|
||||
childview.get().findViewById(R.id.childview).setOnLongClickListener(
|
||||
new OnLongClickListener() {
|
||||
public boolean onLongClick(View view) {
|
||||
new AlertDialog.Builder(mContext.get()).setCancelable(true).setIcon(game_icon)
|
||||
.setTitle(mContext.get().getString(R.string.game_details, game_name))
|
||||
.setMessage(game_details).create().show();
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
childview.get().setTag(game_name);
|
||||
}
|
||||
}
|
||||
|
||||
private void getBoxart(Element images) {
|
||||
Element boxart = null;
|
||||
if (images.getElementsByTagName("boxart").getLength() > 1) {
|
||||
boxart = (Element) images.getElementsByTagName("boxart").item(1);
|
||||
} else if (images.getElementsByTagName("boxart").getLength() == 1) {
|
||||
boxart = (Element) images.getElementsByTagName("boxart").item(0);
|
||||
}
|
||||
if (boxart != null) {
|
||||
decodeBitmapIcon icon = new decodeBitmapIcon(mContext.get());
|
||||
icon.setListener(new decodeBitmapIcon.decodeBitmapIconListener() {
|
||||
@Override
|
||||
public void onDecodeBitmapIconFinished(Bitmap gameImage) {
|
||||
if (childview.get() != null && gameImage != null) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
((ImageView) childview.get().findViewById(
|
||||
R.id.item_icon)).setImageTintList(null);
|
||||
}
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
|
||||
game_icon = new BitmapDrawable(
|
||||
mContext.get().getResources(), gameImage);
|
||||
} else {
|
||||
//noinspection deprecation
|
||||
game_icon = new BitmapDrawable(gameImage);
|
||||
}
|
||||
((ImageView) childview.get().findViewById(
|
||||
R.id.item_icon)).setImageDrawable(game_icon);
|
||||
}
|
||||
}
|
||||
});
|
||||
icon.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR,
|
||||
"https://cdn.thegamesdb.net/images/thumb/"
|
||||
+ getElementValue(boxart)
|
||||
.replace("original/", ""));
|
||||
}
|
||||
}
|
||||
|
||||
private void initializeDefaults() {
|
||||
game_details = mContext.get().getString(R.string.info_unavailable);
|
||||
final String nameLower = game.getName().toLowerCase(Locale.getDefault());
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
game_icon = mContext.get().getResources().getDrawable(
|
||||
game.isDirectory() ? R.drawable.open_folder
|
||||
: nameLower.endsWith(".gdi") ? R.mipmap.disk_gdi
|
||||
: nameLower.endsWith(".chd") ? R.mipmap.disk_chd
|
||||
: nameLower.endsWith(".cdi") ? R.mipmap.disk_cdi
|
||||
: R.mipmap.disk_unknown);
|
||||
} else {
|
||||
game_icon = mContext.get().getResources().getDrawable(
|
||||
game.isDirectory() ? R.drawable.open_folder
|
||||
: nameLower.endsWith(".gdi") ? R.drawable.gdi
|
||||
: nameLower.endsWith(".chd") ? R.drawable.chd
|
||||
: nameLower.endsWith(".cdi") ? R.drawable.cdi
|
||||
: R.drawable.disk_unknown);
|
||||
}
|
||||
ImageView icon = (ImageView) childview.get().findViewById(R.id.item_icon);
|
||||
icon.setImageDrawable(game_icon);
|
||||
}
|
||||
|
||||
private boolean isNetworkAvailable() {
|
||||
ConnectivityManager connectivityManager = (ConnectivityManager) mContext.get()
|
||||
.getSystemService(Context.CONNECTIVITY_SERVICE);
|
||||
NetworkInfo mWifi = connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
|
||||
NetworkInfo mMobile = connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
|
||||
NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
|
||||
if (mMobile != null && mWifi != null) {
|
||||
return mMobile.isAvailable() || mWifi.isAvailable();
|
||||
} else {
|
||||
return activeNetworkInfo != null && activeNetworkInfo.isConnected();
|
||||
}
|
||||
}
|
||||
|
||||
private Document getDomElement(String xml) {
|
||||
Document doc = null;
|
||||
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
|
||||
try {
|
||||
|
||||
DocumentBuilder db = dbf.newDocumentBuilder();
|
||||
|
||||
InputSource is = new InputSource();
|
||||
is.setCharacterStream(new StringReader(xml));
|
||||
doc = db.parse(is);
|
||||
|
||||
} catch (ParserConfigurationException e) {
|
||||
|
||||
return null;
|
||||
} catch (SAXException e) {
|
||||
|
||||
return null;
|
||||
} catch (IOException e) {
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
return doc;
|
||||
}
|
||||
|
||||
private String getValue(Element item, String str) {
|
||||
if (item != null) {
|
||||
NodeList n = item.getElementsByTagName(str);
|
||||
return this.getElementValue(n.item(0));
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
private String getElementValue(Node elem) {
|
||||
Node child;
|
||||
if (elem != null) {
|
||||
if (elem.hasChildNodes()) {
|
||||
for (child = elem.getFirstChild(); child != null; child = child
|
||||
.getNextSibling()) {
|
||||
if (child.getNodeType() == Node.TEXT_NODE) {
|
||||
return child.getNodeValue();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
private static class decodeBitmapIcon extends AsyncTask<String, Integer, Bitmap> {
|
||||
private WeakReference<Context> mContext;
|
||||
private decodeBitmapIconListener listener;
|
||||
|
||||
decodeBitmapIcon(Context reference) {
|
||||
this.mContext = new WeakReference<>(reference);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Bitmap doInBackground(String... params) {
|
||||
try {
|
||||
String index = params[0].substring(params[0].lastIndexOf(
|
||||
"/") + 1, params[0].lastIndexOf("."));
|
||||
File file = new File(mContext.get().getExternalFilesDir(
|
||||
null) + "/images", index + ".png");
|
||||
if (file.exists()) {
|
||||
return BitmapFactory.decodeFile(file.getAbsolutePath());
|
||||
} else {
|
||||
URL updateURL = new URL(params[0]);
|
||||
URLConnection conn1 = updateURL.openConnection();
|
||||
InputStream im = conn1.getInputStream();
|
||||
BufferedInputStream bis = new BufferedInputStream(im, 512);
|
||||
BitmapFactory.Options options = new BitmapFactory.Options();
|
||||
options.inJustDecodeBounds = true;
|
||||
BitmapFactory.decodeStream(bis, null, options);
|
||||
int heightRatio = (int) Math.ceil(options.outHeight / (float) 72);
|
||||
int widthRatio = (int) Math.ceil(options.outWidth / (float) 72);
|
||||
if (heightRatio > 1 || widthRatio > 1) {
|
||||
if (heightRatio > widthRatio) {
|
||||
options.inSampleSize = heightRatio;
|
||||
} else {
|
||||
options.inSampleSize = widthRatio;
|
||||
}
|
||||
}
|
||||
options.inJustDecodeBounds = false;
|
||||
bis.close();
|
||||
im.close();
|
||||
conn1 = updateURL.openConnection();
|
||||
im = conn1.getInputStream();
|
||||
bis = new BufferedInputStream(im, 512);
|
||||
Bitmap bitmap = BitmapFactory.decodeStream(bis, null, options);
|
||||
bis.close();
|
||||
im.close();
|
||||
OutputStream fOut;
|
||||
if (!file.getParentFile().exists()) {
|
||||
file.getParentFile().mkdir();
|
||||
}
|
||||
try {
|
||||
fOut = new FileOutputStream(file, false);
|
||||
bitmap.compress(Bitmap.CompressFormat.PNG, 100, fOut);
|
||||
fOut.flush();
|
||||
fOut.close();
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
return bitmap;
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Bitmap gameImage) {
|
||||
super.onPostExecute(gameImage);
|
||||
if (listener != null) {
|
||||
listener.onDecodeBitmapIconFinished(gameImage);
|
||||
}
|
||||
}
|
||||
|
||||
void setListener(decodeBitmapIconListener listener) {
|
||||
this.listener = listener;
|
||||
}
|
||||
|
||||
public interface decodeBitmapIconListener {
|
||||
void onDecodeBitmapIconFinished(Bitmap gameImage);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -3,11 +3,8 @@ package com.reicast.emulator.config;
|
|||
public class Config {
|
||||
|
||||
public static final String pref_home = "home_directory";
|
||||
public static final String pref_games = "game_directory";
|
||||
public static final String pref_theme = "button_theme";
|
||||
|
||||
public static final String pref_gamedetails = "game_details";
|
||||
|
||||
public static final String pref_rendertype = "render_type";
|
||||
public static final String pref_renderdepth = "depth_render";
|
||||
|
||||
|
|
|
@ -1,653 +0,0 @@
|
|||
package com.reicast.emulator.config;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.app.Dialog;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.SharedPreferences;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.Matrix;
|
||||
import android.graphics.drawable.BitmapDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.view.InputDevice;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.AdapterView.OnItemSelectedListener;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.Button;
|
||||
import android.widget.CompoundButton;
|
||||
import android.widget.CompoundButton.OnCheckedChangeListener;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.Spinner;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.reicast.emulator.R;
|
||||
import com.reicast.emulator.periph.Gamepad;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import tv.ouya.console.api.OuyaController;
|
||||
|
||||
public class InputModFragment extends Fragment {
|
||||
|
||||
private SharedPreferences mPrefs;
|
||||
|
||||
private CompoundButton switchModifiedLayoutEnabled;
|
||||
private CompoundButton switchCompatibilityEnabled;
|
||||
private Spinner right_stick_spinner;
|
||||
private CompoundButton switchJoystickDpadEnabled;
|
||||
|
||||
private TextView a_button_text;
|
||||
private TextView b_button_text;
|
||||
private TextView x_button_text;
|
||||
private TextView y_button_text;
|
||||
private TextView l_button_text;
|
||||
private TextView r_button_text;
|
||||
private TextView dpad_up_text;
|
||||
private TextView dpad_down_text;
|
||||
private TextView dpad_left_text;
|
||||
private TextView dpad_right_text;
|
||||
private TextView start_button_text;
|
||||
private TextView select_button_text;
|
||||
private TextView joystick_x_text;
|
||||
private TextView joystick_y_text;
|
||||
|
||||
private String player = "_A";
|
||||
private int sS = 2;
|
||||
private int playerNum = -1;
|
||||
private mapKeyCode mKey;
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
// Inflate the layout for this fragment
|
||||
return inflater.inflate(R.layout.input_mod_fragment, container, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(View view, Bundle savedInstanceState) {
|
||||
|
||||
mPrefs = PreferenceManager.getDefaultSharedPreferences(getActivity());
|
||||
|
||||
final String[] controllers = getResources().getStringArray(R.array.controllers);
|
||||
|
||||
Bundle b = getArguments();
|
||||
if (b != null) {
|
||||
playerNum = b.getInt("portNumber", -1);
|
||||
}
|
||||
|
||||
switchJoystickDpadEnabled = (CompoundButton) getView().findViewById(
|
||||
R.id.switchJoystickDpadEnabled);
|
||||
switchModifiedLayoutEnabled = (CompoundButton) getView().findViewById(
|
||||
R.id.switchModifiedLayoutEnabled);
|
||||
switchCompatibilityEnabled = (CompoundButton) getView().findViewById(
|
||||
R.id.switchCompatibilityEnabled);
|
||||
|
||||
OnCheckedChangeListener joystick_mode = new OnCheckedChangeListener() {
|
||||
public void onCheckedChanged(CompoundButton buttonView,
|
||||
boolean isChecked) {
|
||||
mPrefs.edit().putBoolean(Gamepad.pref_js_merged + player, isChecked).apply();
|
||||
}
|
||||
};
|
||||
|
||||
switchJoystickDpadEnabled.setOnCheckedChangeListener(joystick_mode);
|
||||
|
||||
String[] rstick = getResources().getStringArray(R.array.right_stick);
|
||||
right_stick_spinner = (Spinner) getView().findViewById(R.id.rstick_spinner);
|
||||
ArrayAdapter<String> rstickAdapter = new ArrayAdapter<>(
|
||||
getActivity(), android.R.layout.simple_spinner_item, rstick);
|
||||
rstickAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||
right_stick_spinner.setAdapter(rstickAdapter);
|
||||
right_stick_spinner.setOnItemSelectedListener(new OnItemSelectedListener() {
|
||||
|
||||
public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
|
||||
mPrefs.edit().putInt(Gamepad.pref_js_rstick + player, pos).apply();
|
||||
}
|
||||
|
||||
public void onNothingSelected(AdapterView<?> arg0) {
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
OnCheckedChangeListener modified_layout = new OnCheckedChangeListener() {
|
||||
public void onCheckedChanged(CompoundButton buttonView,
|
||||
boolean isChecked) {
|
||||
mPrefs.edit().putBoolean(Gamepad.pref_js_modified + player, isChecked).apply();
|
||||
}
|
||||
};
|
||||
|
||||
switchModifiedLayoutEnabled.setOnCheckedChangeListener(modified_layout);
|
||||
|
||||
OnCheckedChangeListener compat_mode = new OnCheckedChangeListener() {
|
||||
public void onCheckedChanged(CompoundButton buttonView,
|
||||
boolean isChecked) {
|
||||
mPrefs.edit().putBoolean(Gamepad.pref_js_compat + player, isChecked).apply();
|
||||
if (isChecked) {
|
||||
selectController();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
switchCompatibilityEnabled.setOnCheckedChangeListener(compat_mode);
|
||||
|
||||
mKey = new mapKeyCode(getActivity());
|
||||
|
||||
ImageView a_button_icon = (ImageView) getView().findViewById(
|
||||
R.id.a_button_icon);
|
||||
a_button_icon.setImageDrawable(getButtonImage(448 / sS, 0));
|
||||
a_button_text = (TextView) getView().findViewById(R.id.a_button_key);
|
||||
Button a_button = (Button) getView().findViewById(R.id.a_button_edit);
|
||||
a_button.setOnClickListener(new View.OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
mKey.intiateSearch(Gamepad.pref_button_a, a_button_text);
|
||||
}
|
||||
});
|
||||
Button a_remove = (Button) getView().findViewById(R.id.remove_a_button);
|
||||
a_remove.setOnClickListener(new View.OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
remKeyCode(Gamepad.pref_button_a, a_button_text);
|
||||
}
|
||||
});
|
||||
|
||||
ImageView b_button_icon = (ImageView) getView().findViewById(
|
||||
R.id.b_button_icon);
|
||||
b_button_icon.setImageDrawable(getButtonImage(384 / sS, 0));
|
||||
b_button_text = (TextView) getView().findViewById(R.id.b_button_key);
|
||||
Button b_button = (Button) getView().findViewById(R.id.b_button_edit);
|
||||
b_button.setOnClickListener(new View.OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
mKey.intiateSearch(Gamepad.pref_button_b, b_button_text);
|
||||
}
|
||||
});
|
||||
Button b_remove = (Button) getView().findViewById(R.id.remove_b_button);
|
||||
b_remove.setOnClickListener(new View.OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
remKeyCode(Gamepad.pref_button_b, b_button_text);
|
||||
}
|
||||
});
|
||||
|
||||
ImageView x_button_icon = (ImageView) getView().findViewById(
|
||||
R.id.x_button_icon);
|
||||
x_button_icon.setImageDrawable(getButtonImage(256 / sS, 0));
|
||||
x_button_text = (TextView) getView().findViewById(R.id.x_button_key);
|
||||
Button x_button = (Button) getView().findViewById(R.id.x_button_edit);
|
||||
x_button.setOnClickListener(new View.OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
mKey.intiateSearch(Gamepad.pref_button_x, x_button_text);
|
||||
}
|
||||
});
|
||||
Button x_remove = (Button) getView().findViewById(R.id.remove_x_button);
|
||||
x_remove.setOnClickListener(new View.OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
remKeyCode(Gamepad.pref_button_x, x_button_text);
|
||||
}
|
||||
});
|
||||
|
||||
ImageView y_button_icon = (ImageView) getView().findViewById(
|
||||
R.id.y_button_icon);
|
||||
y_button_icon.setImageDrawable(getButtonImage(320 / sS, 0));
|
||||
y_button_text = (TextView) getView().findViewById(R.id.y_button_key);
|
||||
Button y_button = (Button) getView().findViewById(R.id.y_button_edit);
|
||||
y_button.setOnClickListener(new View.OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
mKey.intiateSearch(Gamepad.pref_button_y, y_button_text);
|
||||
}
|
||||
});
|
||||
Button y_remove = (Button) getView().findViewById(R.id.remove_y_button);
|
||||
y_remove.setOnClickListener(new View.OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
remKeyCode(Gamepad.pref_button_y, y_button_text);
|
||||
}
|
||||
});
|
||||
|
||||
ImageView l_button_icon = (ImageView) getView().findViewById(
|
||||
R.id.l_button_icon);
|
||||
l_button_icon.setImageDrawable(getButtonImage(78 / sS, 64 / sS));
|
||||
l_button_text = (TextView) getView().findViewById(R.id.l_button_key);
|
||||
Button l_button = (Button) getView().findViewById(R.id.l_button_edit);
|
||||
l_button.setOnClickListener(new View.OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
mKey.intiateSearch(Gamepad.pref_button_l, l_button_text);
|
||||
}
|
||||
});
|
||||
Button l_remove = (Button) getView().findViewById(R.id.remove_l_button);
|
||||
l_remove.setOnClickListener(new View.OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
remKeyCode(Gamepad.pref_button_l, l_button_text);
|
||||
}
|
||||
});
|
||||
|
||||
ImageView r_button_icon = (ImageView) getView().findViewById(
|
||||
R.id.r_button_icon);
|
||||
r_button_icon.setImageDrawable(getButtonImage(162 / sS, 64 / sS));
|
||||
r_button_text = (TextView) getView().findViewById(R.id.r_button_key);
|
||||
Button r_button = (Button) getView().findViewById(R.id.r_button_edit);
|
||||
r_button.setOnClickListener(new View.OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
mKey.intiateSearch(Gamepad.pref_button_r, r_button_text);
|
||||
}
|
||||
});
|
||||
Button r_remove = (Button) getView().findViewById(R.id.remove_r_button);
|
||||
r_remove.setOnClickListener(new View.OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
remKeyCode(Gamepad.pref_button_r, r_button_text);
|
||||
}
|
||||
});
|
||||
|
||||
dpad_up_text = (TextView) getView().findViewById(R.id.dpad_up_key);
|
||||
Button dpad_up = (Button) getView().findViewById(R.id.dpad_up_edit);
|
||||
dpad_up.setOnClickListener(new View.OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
mKey.intiateSearch(Gamepad.pref_dpad_up, dpad_up_text);
|
||||
}
|
||||
});
|
||||
Button up_remove = (Button) getView().findViewById(R.id.remove_dpad_up);
|
||||
up_remove.setOnClickListener(new View.OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
remKeyCode(Gamepad.pref_dpad_up, dpad_up_text);
|
||||
}
|
||||
});
|
||||
|
||||
dpad_down_text = (TextView) getView().findViewById(R.id.dpad_down_key);
|
||||
Button dpad_down = (Button) getView().findViewById(R.id.dpad_down_edit);
|
||||
dpad_down.setOnClickListener(new View.OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
mKey.intiateSearch(Gamepad.pref_dpad_down, dpad_down_text);
|
||||
}
|
||||
});
|
||||
Button down_remove = (Button) getView().findViewById(
|
||||
R.id.remove_dpad_down);
|
||||
down_remove.setOnClickListener(new View.OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
remKeyCode(Gamepad.pref_dpad_down, dpad_down_text);
|
||||
}
|
||||
});
|
||||
|
||||
dpad_left_text = (TextView) getView().findViewById(R.id.dpad_left_key);
|
||||
Button dpad_left = (Button) getView().findViewById(R.id.dpad_left_edit);
|
||||
dpad_left.setOnClickListener(new View.OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
mKey.intiateSearch(Gamepad.pref_dpad_left, dpad_left_text);
|
||||
}
|
||||
});
|
||||
Button left_remove = (Button) getView().findViewById(
|
||||
R.id.remove_dpad_left);
|
||||
left_remove.setOnClickListener(new View.OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
remKeyCode(Gamepad.pref_dpad_left, dpad_left_text);
|
||||
}
|
||||
});
|
||||
|
||||
dpad_right_text = (TextView) getView()
|
||||
.findViewById(R.id.dpad_right_key);
|
||||
Button dpad_right = (Button) getView().findViewById(
|
||||
R.id.dpad_right_edit);
|
||||
dpad_right.setOnClickListener(new View.OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
mKey.intiateSearch(Gamepad.pref_dpad_right, dpad_right_text);
|
||||
}
|
||||
});
|
||||
Button right_remove = (Button) getView().findViewById(
|
||||
R.id.remove_dpad_right);
|
||||
right_remove.setOnClickListener(new View.OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
remKeyCode(Gamepad.pref_dpad_right, dpad_right_text);
|
||||
}
|
||||
});
|
||||
|
||||
joystick_x_text = (TextView) getView().findViewById(
|
||||
R.id.joystick_x_axis);
|
||||
Button joystick_x = (Button) getView().findViewById(
|
||||
R.id.joystick_x_edit);
|
||||
joystick_x.setOnClickListener(new View.OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
mKey.mapAxis(Gamepad.pref_axis_x, joystick_x_text);
|
||||
}
|
||||
});
|
||||
Button joystick_x_remove = (Button) getView().findViewById(
|
||||
R.id.remove_joystick_x);
|
||||
joystick_x_remove.setOnClickListener(new View.OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
remKeyCode(Gamepad.pref_axis_x, joystick_x_text);
|
||||
}
|
||||
});
|
||||
|
||||
joystick_y_text = (TextView) getView().findViewById(
|
||||
R.id.joystick_y_axis);
|
||||
Button joystick_y = (Button) getView().findViewById(
|
||||
R.id.joystick_y_edit);
|
||||
joystick_y.setOnClickListener(new View.OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
mKey.mapAxis(Gamepad.pref_axis_y, joystick_y_text);
|
||||
}
|
||||
});
|
||||
Button joystick_y_remove = (Button) getView().findViewById(
|
||||
R.id.remove_joystick_y);
|
||||
joystick_y_remove.setOnClickListener(new View.OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
remKeyCode(Gamepad.pref_axis_y, joystick_y_text);
|
||||
}
|
||||
});
|
||||
|
||||
ImageView start_button_icon = (ImageView) getView().findViewById(
|
||||
R.id.start_button_icon);
|
||||
start_button_icon.setImageDrawable(getButtonImage(0, 64 / sS));
|
||||
start_button_text = (TextView) getView().findViewById(
|
||||
R.id.start_button_key);
|
||||
Button start_button = (Button) getView().findViewById(
|
||||
R.id.start_button_edit);
|
||||
start_button.setOnClickListener(new View.OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
mKey.intiateSearch(Gamepad.pref_button_start, start_button_text);
|
||||
}
|
||||
});
|
||||
Button start_remove = (Button) getView()
|
||||
.findViewById(R.id.remove_start);
|
||||
start_remove.setOnClickListener(new View.OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
remKeyCode(Gamepad.pref_button_start, start_button_text);
|
||||
}
|
||||
});
|
||||
|
||||
ImageView select_button_icon = (ImageView) getView().findViewById(
|
||||
R.id.select_button_icon);
|
||||
select_button_icon.setImageResource(R.drawable.ic_drawer);
|
||||
select_button_text = (TextView) getView().findViewById(
|
||||
R.id.select_button_key);
|
||||
Button select_button = (Button) getView().findViewById(
|
||||
R.id.select_button_edit);
|
||||
select_button.setOnClickListener(new View.OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
mKey.intiateSearch(Gamepad.pref_button_select,
|
||||
select_button_text);
|
||||
}
|
||||
});
|
||||
Button select_remove = (Button) getView().findViewById(
|
||||
R.id.remove_select);
|
||||
select_remove.setOnClickListener(new View.OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
remKeyCode(Gamepad.pref_button_select, select_button_text);
|
||||
}
|
||||
});
|
||||
|
||||
Spinner player_spnr = (Spinner) getView().findViewById(
|
||||
R.id.player_spinner);
|
||||
ArrayAdapter<String> playerAdapter = new ArrayAdapter<>(
|
||||
getActivity(), android.R.layout.simple_spinner_item,
|
||||
controllers);
|
||||
playerAdapter
|
||||
.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||
player_spnr.setAdapter(playerAdapter);
|
||||
if (playerNum != -1) {
|
||||
player_spnr.setSelection(playerNum, true);
|
||||
}
|
||||
player_spnr.setOnItemSelectedListener(new OnItemSelectedListener() {
|
||||
|
||||
public void onItemSelected(AdapterView<?> parent, View view,
|
||||
int pos, long id) {
|
||||
String selection = parent.getItemAtPosition(pos).toString();
|
||||
player = "_"
|
||||
+ selection.substring(selection.lastIndexOf(" ") + 1,
|
||||
selection.length());
|
||||
playerNum = pos;
|
||||
updateController(player);
|
||||
}
|
||||
|
||||
public void onNothingSelected(AdapterView<?> arg0) {
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
updateController(player);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve an image to serve as a visual representation
|
||||
*
|
||||
* @param x
|
||||
* The x start value of the image within the atlas
|
||||
* @param y
|
||||
* The y start value of the image within the atlas
|
||||
*/
|
||||
private Drawable getButtonImage(int x, int y) {
|
||||
Bitmap image = null;
|
||||
try {
|
||||
File buttons = null;
|
||||
InputStream bitmap;
|
||||
String theme = mPrefs.getString(Config.pref_theme, null);
|
||||
if (theme != null) {
|
||||
buttons = new File(theme);
|
||||
}
|
||||
if (buttons != null && buttons.exists()) {
|
||||
bitmap = new FileInputStream(buttons);
|
||||
} else {
|
||||
bitmap = getResources().getAssets().open("buttons.png");
|
||||
}
|
||||
BitmapFactory.Options options = new BitmapFactory.Options();
|
||||
options.inSampleSize = sS;
|
||||
image = BitmapFactory.decodeStream(bitmap, null, options);
|
||||
bitmap.close();
|
||||
Matrix matrix = new Matrix();
|
||||
matrix.postScale(32, 32);
|
||||
Bitmap resizedBitmap = Bitmap.createBitmap(image, x, y, 64 / sS,
|
||||
64 / sS, matrix, true);
|
||||
@SuppressWarnings("deprecation")
|
||||
BitmapDrawable bmd = new BitmapDrawable(resizedBitmap);
|
||||
image.recycle();
|
||||
image = null;
|
||||
return bmd;
|
||||
} catch (IOException e1) {
|
||||
e1.printStackTrace();
|
||||
} catch (OutOfMemoryError E) {
|
||||
if (sS == 2) {
|
||||
if (image != null) {
|
||||
image.recycle();
|
||||
}
|
||||
sS = 4;
|
||||
return getButtonImage(x, y);
|
||||
} else {
|
||||
E.printStackTrace();
|
||||
}
|
||||
}
|
||||
return getResources().getDrawable(R.drawable.input);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prompt the user to specify the controller to modify
|
||||
*
|
||||
*/
|
||||
private void selectController() {
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
|
||||
builder.setTitle(R.string.select_controller_title);
|
||||
builder.setMessage(getString(R.string.select_controller_message, player.replace("_", "")));
|
||||
builder.setNegativeButton(R.string.cancel,
|
||||
new DialogInterface.OnClickListener() {
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
dialog.dismiss();
|
||||
}
|
||||
});
|
||||
builder.setOnKeyListener(new Dialog.OnKeyListener() {
|
||||
public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
|
||||
mPrefs.edit().putInt("controller" + player, event.getDeviceId()).apply();
|
||||
dialog.dismiss();
|
||||
return true;
|
||||
}
|
||||
});
|
||||
builder.create();
|
||||
builder.show();
|
||||
}
|
||||
|
||||
private class mapKeyCode extends AlertDialog.Builder {
|
||||
|
||||
mapKeyCode(Context c) {
|
||||
super(c);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prompt the user for the button to be assigned
|
||||
*
|
||||
* @param button
|
||||
* The name of the emulator button being defined
|
||||
* @param output
|
||||
* The output display for the assigned button value
|
||||
*/
|
||||
public void intiateSearch(final String button, final TextView output) {
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
|
||||
builder.setTitle(R.string.map_keycode_title);
|
||||
builder.setMessage(getString(R.string.map_keycode_message, button.replace("_", " ")));
|
||||
builder.setNegativeButton(R.string.cancel,
|
||||
new DialogInterface.OnClickListener() {
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
dialog.dismiss();
|
||||
}
|
||||
});
|
||||
builder.setOnKeyListener(new Dialog.OnKeyListener() {
|
||||
public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
|
||||
mapButton(keyCode, button);
|
||||
dialog.dismiss();
|
||||
return getKeyCode(button, output);
|
||||
}
|
||||
});
|
||||
builder.create();
|
||||
builder.show();
|
||||
}
|
||||
|
||||
/**
|
||||
* Assign the user button to the emulator button
|
||||
*
|
||||
* @param keyCode
|
||||
* The keycode generated by the button being assigned
|
||||
* @param button
|
||||
* The label of the button being assigned
|
||||
*/
|
||||
private void mapButton(int keyCode, String button) {
|
||||
if (Build.MODEL.startsWith("R800")) {
|
||||
if (keyCode == KeyEvent.KEYCODE_MENU)
|
||||
return;
|
||||
} else {
|
||||
if (keyCode == KeyEvent.KEYCODE_BACK)
|
||||
return;
|
||||
}
|
||||
mPrefs.edit().putInt(button + player, keyCode).apply();
|
||||
}
|
||||
|
||||
private void mapAxis(final String button, final TextView output) {
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
|
||||
builder.setTitle(R.string.map_keycode_title);
|
||||
builder.setMessage(getString(R.string.map_keycode_message, button.replace("_", " ")));
|
||||
View view = getLayoutInflater().inflate(R.layout.joystick_dialog, null);
|
||||
builder.setView(view);
|
||||
builder.setCancelable(false);
|
||||
builder.create();
|
||||
final Dialog dialog = builder.show();
|
||||
view.findViewById(R.id.joystick_cancel_btn).setOnClickListener(new View.OnClickListener() {
|
||||
public void onClick(View view) {
|
||||
dialog.dismiss();
|
||||
}
|
||||
});
|
||||
view.requestFocusFromTouch();
|
||||
view.setOnGenericMotionListener(new View.OnGenericMotionListener() {
|
||||
@Override
|
||||
public boolean onGenericMotion(View view, MotionEvent event) {
|
||||
int axis = -1;
|
||||
if ((event.getSource() & InputDevice.SOURCE_JOYSTICK) ==
|
||||
InputDevice.SOURCE_JOYSTICK &&
|
||||
event.getAction() == MotionEvent.ACTION_MOVE) {
|
||||
if (event.getAxisValue(MotionEvent.AXIS_X) != 0) {
|
||||
axis = MotionEvent.AXIS_X;
|
||||
}
|
||||
if (event.getAxisValue(MotionEvent.AXIS_Y) != 0) {
|
||||
axis = MotionEvent.AXIS_Y;
|
||||
}
|
||||
if (event.getAxisValue(MotionEvent.AXIS_RX) != 0) {
|
||||
axis = MotionEvent.AXIS_RX;
|
||||
}
|
||||
if (event.getAxisValue(MotionEvent.AXIS_RY) != 0) {
|
||||
axis = MotionEvent.AXIS_RY;
|
||||
}
|
||||
if (event.getAxisValue(MotionEvent.AXIS_HAT_X) != 0) {
|
||||
axis = MotionEvent.AXIS_HAT_X;
|
||||
}
|
||||
if (event.getAxisValue(MotionEvent.AXIS_HAT_Y) != 0) {
|
||||
axis = MotionEvent.AXIS_HAT_Y;
|
||||
}
|
||||
if (new Gamepad().IsOuyaOrTV(getActivity(), true)) {
|
||||
if (event.getAxisValue(OuyaController.AXIS_LS_X) != 0) {
|
||||
axis = OuyaController.AXIS_LS_X;
|
||||
}
|
||||
if (event.getAxisValue(OuyaController.AXIS_LS_Y) != 0) {
|
||||
axis = OuyaController.AXIS_LS_Y;
|
||||
}
|
||||
}
|
||||
mPrefs.edit().putInt(button + player, axis).apply();
|
||||
dialog.dismiss();
|
||||
return getKeyCode(button, output);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void updateController(String player) {
|
||||
switchJoystickDpadEnabled.setChecked(mPrefs.getBoolean(
|
||||
Gamepad.pref_js_merged + player, false));
|
||||
right_stick_spinner.setSelection(mPrefs.getInt(Gamepad.pref_js_rstick + player, 0));
|
||||
switchModifiedLayoutEnabled.setChecked(mPrefs.getBoolean(
|
||||
Gamepad.pref_js_modified + player, false));
|
||||
switchCompatibilityEnabled.setChecked(mPrefs.getBoolean(
|
||||
Gamepad.pref_js_compat + player, false));
|
||||
getKeyCode(Gamepad.pref_button_a, a_button_text);
|
||||
getKeyCode(Gamepad.pref_button_b, b_button_text);
|
||||
getKeyCode(Gamepad.pref_button_x, x_button_text);
|
||||
getKeyCode(Gamepad.pref_button_y, y_button_text);
|
||||
getKeyCode(Gamepad.pref_button_l, l_button_text);
|
||||
getKeyCode(Gamepad.pref_button_r, r_button_text);
|
||||
getKeyCode(Gamepad.pref_dpad_up, dpad_up_text);
|
||||
getKeyCode(Gamepad.pref_dpad_down, dpad_down_text);
|
||||
getKeyCode(Gamepad.pref_dpad_left, dpad_left_text);
|
||||
getKeyCode(Gamepad.pref_dpad_right, dpad_right_text);
|
||||
getKeyCode(Gamepad.pref_axis_x, joystick_x_text);
|
||||
getKeyCode(Gamepad.pref_axis_y, joystick_y_text);
|
||||
getKeyCode(Gamepad.pref_button_start, start_button_text);
|
||||
getKeyCode(Gamepad.pref_button_select, select_button_text);
|
||||
}
|
||||
|
||||
private boolean getKeyCode(final String button, final TextView output) {
|
||||
int keyCode = mPrefs.getInt(button + player, -1);
|
||||
if (keyCode != -1) {
|
||||
String label = output.getText().toString();
|
||||
if (label.contains(":")) {
|
||||
label = label.substring(0, label.indexOf(":"));
|
||||
}
|
||||
label += ": " + keyCode;
|
||||
output.setText(label);
|
||||
return true;
|
||||
} else {
|
||||
String label = output.getText().toString();
|
||||
if (label.contains(":")) {
|
||||
label = label.substring(0, label.indexOf(":"));
|
||||
}
|
||||
output.setText(label);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private void remKeyCode(final String button, TextView output) {
|
||||
mPrefs.edit().remove(button + player).apply();
|
||||
getKeyCode(button, output);
|
||||
}
|
||||
}
|
|
@ -1,488 +0,0 @@
|
|||
package com.reicast.emulator.config;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.SharedPreferences;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.Environment;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.support.constraint.ConstraintLayout;
|
||||
import android.support.design.widget.Snackbar;
|
||||
import android.support.graphics.drawable.VectorDrawableCompat;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.view.Gravity;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.inputmethod.EditorInfo;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.AdapterView.OnItemSelectedListener;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.Button;
|
||||
import android.widget.CompoundButton;
|
||||
import android.widget.CompoundButton.OnCheckedChangeListener;
|
||||
import android.widget.EditText;
|
||||
import android.widget.Spinner;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.android.util.FileUtils;
|
||||
import com.reicast.emulator.Emulator;
|
||||
import com.reicast.emulator.FileBrowser;
|
||||
import com.reicast.emulator.R;
|
||||
import com.reicast.emulator.emu.GL2JNIView;
|
||||
import com.reicast.emulator.emu.JNIdc;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.FilenameFilter;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
|
||||
public class OptionsFragment extends Fragment {
|
||||
|
||||
private Spinner mSpnrThemes;
|
||||
private OnClickListener mCallback;
|
||||
|
||||
private SharedPreferences mPrefs;
|
||||
private File sdcard = Environment.getExternalStorageDirectory();
|
||||
private String home_directory = sdcard.getAbsolutePath();
|
||||
private String game_directory = sdcard.getAbsolutePath();
|
||||
|
||||
private String[] codes;
|
||||
|
||||
// Container Activity must implement this interface
|
||||
public interface OnClickListener {
|
||||
void recreateActivity();
|
||||
void onMainBrowseSelected(String path_entry, boolean games, String query);
|
||||
void launchBIOSdetection();
|
||||
void synchronousRenderingNotice();
|
||||
}
|
||||
|
||||
@Override @SuppressWarnings("deprecation")
|
||||
public void onAttach(Activity activity) {
|
||||
super.onAttach(activity);
|
||||
|
||||
// This makes sure that the container activity has implemented
|
||||
// the callback interface. If not, it throws an exception
|
||||
try {
|
||||
mCallback = (OnClickListener) activity;
|
||||
} catch (ClassCastException e) {
|
||||
throw new ClassCastException(activity.toString()
|
||||
+ " must implement OnClickListener");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAttach(Context context) {
|
||||
super.onAttach(context);
|
||||
|
||||
// This makes sure that the container activity has implemented
|
||||
// the callback interface. If not, it throws an exception
|
||||
try {
|
||||
mCallback = (OnClickListener) context;
|
||||
} catch (ClassCastException e) {
|
||||
throw new ClassCastException(context.getClass().toString()
|
||||
+ " must implement OnClickListener");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
// Inflate the layout for this fragment
|
||||
return inflater.inflate(R.layout.configure_fragment, container, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(View view, Bundle savedInstanceState) {
|
||||
|
||||
mPrefs = PreferenceManager.getDefaultSharedPreferences(getActivity());
|
||||
|
||||
// FIXME Specialized handler for devices with an extSdCard mount for external
|
||||
HashSet<String> extStorage = FileBrowser.getExternalMounts();
|
||||
if (extStorage != null && !extStorage.isEmpty()) {
|
||||
for (String sd : extStorage) {
|
||||
String sdCardPath = sd.replace("mnt/media_rw", "storage");
|
||||
if (!sdCardPath.equals(sdcard.getAbsolutePath())) {
|
||||
game_directory = sdCardPath;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
home_directory = mPrefs.getString(Config.pref_home, home_directory);
|
||||
Emulator app = (Emulator) getActivity().getApplicationContext();
|
||||
app.getConfigurationPrefs();
|
||||
|
||||
// Generate the menu options and fill in existing settings
|
||||
Button mainBrowse = (Button) getView().findViewById(R.id.browse_main_path);
|
||||
mSpnrThemes = (Spinner) getView().findViewById(R.id.pick_button_theme);
|
||||
new LocateThemes(this).execute(home_directory + "/themes");
|
||||
|
||||
final EditText editBrowse = (EditText) getView().findViewById(R.id.main_path);
|
||||
editBrowse.setText(home_directory);
|
||||
|
||||
mainBrowse.setOnClickListener(new View.OnClickListener() {
|
||||
public void onClick(View view) {
|
||||
mPrefs.edit().remove(Config.pref_home).apply();
|
||||
hideSoftKeyBoard();
|
||||
mCallback.launchBIOSdetection();
|
||||
}
|
||||
});
|
||||
editBrowse.setOnEditorActionListener(new EditText.OnEditorActionListener() {
|
||||
@Override
|
||||
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
|
||||
if (actionId == EditorInfo.IME_ACTION_DONE
|
||||
|| (event != null && event.getKeyCode() == KeyEvent.KEYCODE_ENTER
|
||||
&& event.getAction() == KeyEvent.ACTION_DOWN)) {
|
||||
if (event == null || !event.isShiftPressed()) {
|
||||
if (v.getText() != null) {
|
||||
home_directory = v.getText().toString();
|
||||
if (home_directory.endsWith("/data")) {
|
||||
home_directory.replace("/data", "");
|
||||
showToastMessage(getActivity().getString(R.string.data_folder),
|
||||
Snackbar.LENGTH_SHORT);
|
||||
}
|
||||
mPrefs.edit().putString(Config.pref_home, home_directory).apply();
|
||||
//JNIdc.config(home_directory);
|
||||
new LocateThemes(OptionsFragment.this).execute(home_directory + "/themes");
|
||||
}
|
||||
hideSoftKeyBoard();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
OnCheckedChangeListener details_options = new OnCheckedChangeListener() {
|
||||
|
||||
public void onCheckedChanged(CompoundButton buttonView,
|
||||
boolean isChecked) {
|
||||
mPrefs.edit().putBoolean(Config.pref_gamedetails, isChecked).apply();
|
||||
if (!isChecked) {
|
||||
File dir = new File(getActivity().getExternalFilesDir(null), "images");
|
||||
File[] files = dir == null ? null : dir.listFiles();
|
||||
if (files != null) {
|
||||
for (File file : files) {
|
||||
if (!file.isDirectory()) {
|
||||
file.delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
CompoundButton details_opt = (CompoundButton) getView().findViewById(R.id.details_option);
|
||||
details_opt.setChecked(mPrefs.getBoolean(Config.pref_gamedetails, false));
|
||||
details_opt.setOnCheckedChangeListener(details_options);
|
||||
|
||||
Button gameBrowse = (Button) getView().findViewById(R.id.browse_game_path);
|
||||
|
||||
final EditText editGames = (EditText) getView().findViewById(R.id.game_path);
|
||||
game_directory = mPrefs.getString(Config.pref_games, game_directory);
|
||||
editGames.setText(game_directory);
|
||||
|
||||
gameBrowse.setOnClickListener(new View.OnClickListener() {
|
||||
public void onClick(View view) {
|
||||
mPrefs.edit().remove(Config.pref_games).apply();
|
||||
if (editBrowse.getText() != null) {
|
||||
game_directory = editGames.getText().toString();
|
||||
}
|
||||
hideSoftKeyBoard();
|
||||
mCallback.onMainBrowseSelected(game_directory, true, null);
|
||||
}
|
||||
});
|
||||
editGames.setOnEditorActionListener(new EditText.OnEditorActionListener() {
|
||||
@Override
|
||||
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
|
||||
if (actionId == EditorInfo.IME_ACTION_DONE
|
||||
|| (event != null && event.getKeyCode() == KeyEvent.KEYCODE_ENTER
|
||||
&& event.getAction() == KeyEvent.ACTION_DOWN)) {
|
||||
if (event == null || !event.isShiftPressed()) {
|
||||
if (v.getText() != null) {
|
||||
game_directory = v.getText().toString();
|
||||
mPrefs.edit().putString(Config.pref_games, game_directory).apply();
|
||||
}
|
||||
hideSoftKeyBoard();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
CompoundButton force_software_opt = (CompoundButton) getView().findViewById(
|
||||
R.id.software_option);
|
||||
OnCheckedChangeListener force_software = new OnCheckedChangeListener() {
|
||||
|
||||
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
|
||||
mPrefs.edit().putInt(Config.pref_rendertype, isChecked ?
|
||||
GL2JNIView.LAYER_TYPE_SOFTWARE : GL2JNIView.LAYER_TYPE_HARDWARE).apply();
|
||||
}
|
||||
};
|
||||
int software = mPrefs.getInt(Config.pref_rendertype, GL2JNIView.LAYER_TYPE_HARDWARE);
|
||||
force_software_opt.setChecked(software == GL2JNIView.LAYER_TYPE_SOFTWARE);
|
||||
force_software_opt.setOnCheckedChangeListener(force_software);
|
||||
|
||||
String[] depths = getResources().getStringArray(R.array.depth);
|
||||
|
||||
Spinner depth_spnr = (Spinner) getView().findViewById(R.id.depth_spinner);
|
||||
ArrayAdapter<String> depthAdapter = new ArrayAdapter<>(
|
||||
getActivity(), R.layout.spinner_selected, depths);
|
||||
depthAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||
depth_spnr.setAdapter(depthAdapter);
|
||||
|
||||
setSpinner(R.array.depth, R.id.depth_spinner,
|
||||
Config.pref_renderdepth, 24, true);
|
||||
|
||||
Button resetEmu = (Button) getView().findViewById(R.id.reset_emu_btn);
|
||||
resetEmu.setOnClickListener(new View.OnClickListener() {
|
||||
public void onClick(View view) {
|
||||
AlertDialog.Builder b = new AlertDialog.Builder(getActivity());
|
||||
b.setIcon(android.R.drawable.ic_dialog_alert);
|
||||
b.setTitle(getActivity().getString(R.string.reset_emu_title) + "?");
|
||||
b.setMessage(getActivity().getString(R.string.reset_emu_details));
|
||||
b.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
|
||||
public void onClick(DialogInterface dialog, int id) {
|
||||
resetEmuSettings();
|
||||
}
|
||||
});
|
||||
b.setNegativeButton(android.R.string.no, null);
|
||||
b.show();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void setSpinner(int array, int view, final String pref, int def, final boolean parse) {
|
||||
String[] stringArray = getResources().getStringArray(array);
|
||||
Spinner spinner = (Spinner) getView().findViewById(view);
|
||||
ArrayAdapter<String> adapter = new ArrayAdapter<>(
|
||||
getActivity(), R.layout.spinner_selected, stringArray);
|
||||
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||
spinner.setAdapter(adapter);
|
||||
|
||||
if (parse) {
|
||||
String value = String.valueOf(mPrefs.getInt(pref, def));
|
||||
spinner.setSelection(adapter.getPosition(value), true);
|
||||
} else {
|
||||
spinner.setSelection(mPrefs.getInt(pref, def), true);
|
||||
}
|
||||
|
||||
spinner.setOnItemSelectedListener(new OnItemSelectedListener() {
|
||||
|
||||
public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
|
||||
if (parse) {
|
||||
int value = Integer.parseInt(parent.getItemAtPosition(pos).toString());
|
||||
mPrefs.edit().putInt(pref, value).apply();
|
||||
} else {
|
||||
mPrefs.edit().putInt(pref, pos).apply();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void onNothingSelected(AdapterView<?> arg0) {
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
private static class LocateThemes extends AsyncTask<String, Integer, List<File>> {
|
||||
private WeakReference<OptionsFragment> options;
|
||||
|
||||
LocateThemes(OptionsFragment context) {
|
||||
options = new WeakReference<>(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<File> doInBackground(String... paths) {
|
||||
File storage = new File(paths[0]);
|
||||
String[] mediaTypes = options.get().getResources().getStringArray(R.array.themes_ext);
|
||||
FilenameFilter[] filter = new FilenameFilter[mediaTypes.length];
|
||||
int i = 0;
|
||||
for (final String type : mediaTypes) {
|
||||
filter[i] = new FilenameFilter() {
|
||||
public boolean accept(File dir, String name) {
|
||||
return !dir.getName().startsWith(".") && !name.startsWith(".")
|
||||
&& StringUtils.endsWithIgnoreCase(name, "." + type);
|
||||
}
|
||||
};
|
||||
i++;
|
||||
}
|
||||
FileUtils fileUtils = new FileUtils();
|
||||
Collection<File> files = fileUtils.listFiles(storage, filter, 0);
|
||||
return (List<File>) files;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(List<File> items) {
|
||||
if (items != null && !items.isEmpty()) {
|
||||
String[] themes = new String[items.size() + 1];
|
||||
for (int i = 0; i < items.size(); i ++) {
|
||||
themes[i] = items.get(i).getName();
|
||||
}
|
||||
themes[items.size()] = "None";
|
||||
ArrayAdapter<String> themeAdapter = new ArrayAdapter<>(
|
||||
options.get().getActivity(), android.R.layout.simple_spinner_item, themes);
|
||||
themeAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||
options.get().mSpnrThemes.setAdapter(themeAdapter);
|
||||
options.get().mSpnrThemes.setOnItemSelectedListener(new OnItemSelectedListener() {
|
||||
@Override
|
||||
public void onItemSelected(AdapterView<?> parentView, View selectedItemView, int position, long id) {
|
||||
String theme = String.valueOf(parentView.getItemAtPosition(position));
|
||||
if (theme.equals("None")) {
|
||||
options.get().mPrefs.edit().remove(Config.pref_theme).apply();
|
||||
} else {
|
||||
String theme_path = options.get().home_directory + "/themes/" + theme;
|
||||
options.get().mPrefs.edit().putString(Config.pref_theme, theme_path).apply();
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void onNothingSelected(AdapterView<?> parentView) {
|
||||
|
||||
}
|
||||
});
|
||||
} else {
|
||||
options.get().mSpnrThemes.setEnabled(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void hideSoftKeyBoard() {
|
||||
try {
|
||||
InputMethodManager iMm = (InputMethodManager) getActivity()
|
||||
.getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||
if (iMm != null && iMm.isAcceptingText()) {
|
||||
iMm.hideSoftInputFromWindow(getActivity().getCurrentFocus().getWindowToken(), 0);
|
||||
}
|
||||
} catch (NullPointerException e) {
|
||||
// Keyboard may still be visible
|
||||
}
|
||||
}
|
||||
|
||||
private void copy(File src, File dst) throws IOException {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
||||
try (InputStream in = new FileInputStream(src)) {
|
||||
try (OutputStream out = new FileOutputStream(dst)) {
|
||||
// Transfer bytes from in to out
|
||||
byte[] buf = new byte[1024];
|
||||
int len;
|
||||
while ((len = in.read(buf)) > 0) {
|
||||
out.write(buf, 0, len);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
InputStream in = new FileInputStream(src);
|
||||
OutputStream out = new FileOutputStream(dst);
|
||||
try {
|
||||
// Transfer bytes from in to out
|
||||
byte[] buf = new byte[1024];
|
||||
int len;
|
||||
while ((len = in.read(buf)) > 0) {
|
||||
out.write(buf, 0, len);
|
||||
}
|
||||
} finally {
|
||||
in.close();
|
||||
out.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void flashBios(String localized) {
|
||||
File local = new File(home_directory, "data/dc_flash[" + localized
|
||||
+ "].bin");
|
||||
File flash = new File(home_directory, "data/dc_flash.bin");
|
||||
|
||||
if (local.exists()) {
|
||||
if (flash.exists()) {
|
||||
flash.delete();
|
||||
}
|
||||
try {
|
||||
copy(local, flash);
|
||||
} catch (IOException ex) {
|
||||
ex.printStackTrace();
|
||||
local.renameTo(flash);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void resetEmuSettings() {
|
||||
mPrefs.edit().remove(Config.pref_gamedetails).apply();
|
||||
mPrefs.edit().remove(Config.pref_rendertype).apply();
|
||||
mPrefs.edit().remove(Config.pref_renderdepth).apply();
|
||||
mPrefs.edit().remove(Config.pref_theme).apply();
|
||||
|
||||
Emulator.nosound = false;
|
||||
|
||||
getActivity().finish();
|
||||
}
|
||||
|
||||
private void showToastMessage(String message, int duration) {
|
||||
ConstraintLayout layout = (ConstraintLayout) getActivity().findViewById(R.id.mainui_layout);
|
||||
Snackbar snackbar = Snackbar.make(layout, message, duration);
|
||||
View snackbarLayout = snackbar.getView();
|
||||
TextView textView = (TextView) snackbarLayout.findViewById(
|
||||
android.support.design.R.id.snackbar_text);
|
||||
textView.setGravity(Gravity.CENTER_VERTICAL);
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1)
|
||||
textView.setTextAlignment(View.TEXT_ALIGNMENT_GRAVITY);
|
||||
Drawable drawable;
|
||||
if (android.os.Build.VERSION.SDK_INT > Build.VERSION_CODES.M) {
|
||||
drawable = getResources().getDrawable(
|
||||
R.drawable.ic_settings, getActivity().getTheme());
|
||||
} else {
|
||||
drawable = VectorDrawableCompat.create(getResources(),
|
||||
R.drawable.ic_settings, getActivity().getTheme());
|
||||
}
|
||||
textView.setCompoundDrawablesWithIntrinsicBounds(drawable, null, null, null);
|
||||
textView.setCompoundDrawablePadding(getResources()
|
||||
.getDimensionPixelOffset(R.dimen.snackbar_icon_padding));
|
||||
snackbar.show();
|
||||
}
|
||||
|
||||
private int getBroadcastValue(String broadcastName) {
|
||||
if (broadcastName.equals("NTSC-J"))
|
||||
return 0;
|
||||
else if (broadcastName.equals("NTSC-U"))
|
||||
return 4;
|
||||
else if (broadcastName.equals("PAL-M"))
|
||||
return 6;
|
||||
else if (broadcastName.equals("PAL-N"))
|
||||
return 7;
|
||||
else if (broadcastName.equals("PAL-E"))
|
||||
return 9;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
private String getBroadcastName(int broadcastValue) {
|
||||
if (broadcastValue == 0)
|
||||
return "NTSC-J";
|
||||
else if (broadcastValue == 4)
|
||||
return "NTSC-U";
|
||||
else if (broadcastValue == 6)
|
||||
return "PAL-M";
|
||||
else if (broadcastValue == 7)
|
||||
return "PAL-N";
|
||||
else if (broadcastValue == 9)
|
||||
return "PAL-E";
|
||||
else
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -1,170 +0,0 @@
|
|||
package com.reicast.emulator.debug;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.annotation.TargetApi;
|
||||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.SharedPreferences;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.os.Build;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.view.ViewGroup;
|
||||
import android.webkit.CookieManager;
|
||||
import android.webkit.CookieSyncManager;
|
||||
import android.webkit.WebSettings;
|
||||
import android.webkit.WebSettings.PluginState;
|
||||
import android.webkit.WebView;
|
||||
import android.webkit.WebViewClient;
|
||||
import android.widget.BaseAdapter;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.nostra13.universalimageloader.core.DisplayImageOptions;
|
||||
import com.nostra13.universalimageloader.core.ImageLoader;
|
||||
import com.nostra13.universalimageloader.core.ImageLoaderConfiguration;
|
||||
import com.nostra13.universalimageloader.core.assist.ImageScaleType;
|
||||
import com.reicast.emulator.R;
|
||||
import com.reicast.emulator.config.Config;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
||||
public class GitAdapter extends BaseAdapter {
|
||||
|
||||
private ArrayList<HashMap<String, String>> data;
|
||||
private LayoutInflater inflater;
|
||||
private DisplayImageOptions options;
|
||||
private SharedPreferences mPrefs;
|
||||
|
||||
public GitAdapter(Activity activity, ArrayList<HashMap<String, String>> d) {
|
||||
this.data = d;
|
||||
this.inflater = (LayoutInflater) activity
|
||||
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
||||
ImageLoaderConfiguration configicon = new ImageLoaderConfiguration.Builder(
|
||||
activity).memoryCacheExtraOptions(96, 96).build();
|
||||
this.options = new DisplayImageOptions.Builder()
|
||||
.showStubImage(R.drawable.ic_github)
|
||||
.showImageForEmptyUri(R.drawable.ic_github)
|
||||
.imageScaleType(ImageScaleType.EXACTLY_STRETCHED).build();
|
||||
|
||||
ImageLoader.getInstance().init(configicon);
|
||||
mPrefs = PreferenceManager.getDefaultSharedPreferences(activity);
|
||||
|
||||
}
|
||||
|
||||
public int getCount() {
|
||||
return this.data.size();
|
||||
}
|
||||
|
||||
public Object getItem(int position) {
|
||||
return position;
|
||||
}
|
||||
|
||||
public long getItemId(int position) {
|
||||
return position;
|
||||
}
|
||||
|
||||
public View getView(final int position, View convertView, ViewGroup parent) {
|
||||
View vi = convertView;
|
||||
if (convertView == null)
|
||||
vi = this.inflater.inflate(R.layout.change_item, null);
|
||||
TextView dateText = (TextView) vi.findViewById(R.id.date);
|
||||
TextView committerText = (TextView) vi.findViewById(R.id.committer);
|
||||
TextView titleText = (TextView) vi.findViewById(R.id.title);
|
||||
ImageView avatarIcon = (ImageView) vi.findViewById(R.id.avatar);
|
||||
|
||||
final HashMap<String, String> commit = this.data.get(position);
|
||||
final String date = commit.get("Date");
|
||||
final String committer = commit.get("Committer");
|
||||
final String title = commit.get("Title");
|
||||
final String message = commit.get("Message");
|
||||
final String sha = commit.get("Sha");
|
||||
final String url = commit.get("Url");
|
||||
final String author = commit.get("Author");
|
||||
final String avatar = commit.get("Avatar");
|
||||
final String current = commit.get("Build");
|
||||
|
||||
RelativeLayout item = (RelativeLayout) vi.findViewById(R.id.change);
|
||||
if (current != null && current.equals(sha.substring(0, 7))) {
|
||||
item.getBackground().setColorFilter(0xFF00FF00,
|
||||
PorterDuff.Mode.MULTIPLY);
|
||||
} else {
|
||||
item.getBackground().setColorFilter(null);
|
||||
}
|
||||
|
||||
dateText.setText(date);
|
||||
committerText.setText(committer);
|
||||
titleText.setText(title);
|
||||
ImageLoader.getInstance().displayImage(avatar, avatarIcon, this.options);
|
||||
|
||||
vi.setOnClickListener(new OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
System.gc();
|
||||
String output = title + "\n\n" + message + "\n\n" + " - " + author;
|
||||
displayCommit(sha, output, url, v.getContext());
|
||||
}
|
||||
});
|
||||
// Handle clicking individual item from list
|
||||
|
||||
return vi;
|
||||
}
|
||||
|
||||
private void displayCommit(final String sha, String message, String url,
|
||||
Context context) {
|
||||
final AlertDialog.Builder builder = new AlertDialog.Builder(context);
|
||||
builder.setCancelable(true);
|
||||
builder.setTitle(sha.substring(0,7));
|
||||
builder.setMessage(message);
|
||||
LayoutInflater infalter = LayoutInflater.from(context);
|
||||
final View popWebView = infalter.inflate(R.layout.webview, null);
|
||||
WebView mWebView = (WebView) popWebView.findViewById(R.id.webframe);
|
||||
mWebView = configureWebview(url, context, mWebView);
|
||||
builder.setView(popWebView);
|
||||
builder.setPositiveButton("Close",
|
||||
new DialogInterface.OnClickListener() {
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
dialog.dismiss();
|
||||
return;
|
||||
}
|
||||
});
|
||||
builder.create().show();
|
||||
}
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
|
||||
@SuppressLint("SetJavaScriptEnabled")
|
||||
@SuppressWarnings("deprecation")
|
||||
private WebView configureWebview(String url, Context context,
|
||||
WebView mWebView) {
|
||||
mWebView.getSettings().setSupportZoom(true);
|
||||
mWebView.getSettings().setBuiltInZoomControls(true);
|
||||
mWebView.getSettings().setDisplayZoomControls(false);
|
||||
mWebView.setInitialScale(1);
|
||||
mWebView.getSettings().setUseWideViewPort(true);
|
||||
mWebView.getSettings().setLoadWithOverviewMode(true);
|
||||
mWebView.getSettings().setJavaScriptEnabled(true);
|
||||
mWebView.getSettings().setPluginState(PluginState.ON);
|
||||
mWebView.getSettings().setCacheMode(WebSettings.LOAD_NO_CACHE);
|
||||
mWebView.clearHistory();
|
||||
mWebView.clearFormData();
|
||||
mWebView.clearCache(true);
|
||||
CookieSyncManager.createInstance(context);
|
||||
CookieManager cookieManager = CookieManager.getInstance();
|
||||
cookieManager.removeAllCookie();
|
||||
CookieSyncManager.getInstance().stopSync();
|
||||
mWebView.setWebViewClient(new WebViewClient() {
|
||||
@Override
|
||||
public boolean shouldOverrideUrlLoading(WebView view, String url) {
|
||||
view.loadUrl(url);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
mWebView.loadUrl(url);
|
||||
return mWebView;
|
||||
}
|
||||
}
|
|
@ -2,35 +2,21 @@ package com.reicast.emulator.emu;
|
|||
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.res.Configuration;
|
||||
import android.graphics.PixelFormat;
|
||||
import android.opengl.GLSurfaceView;
|
||||
import android.os.Build;
|
||||
import android.os.Environment;
|
||||
import android.os.Handler;
|
||||
import android.os.Vibrator;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.util.Log;
|
||||
import android.view.InputDevice;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.ScaleGestureDetector;
|
||||
import android.view.ScaleGestureDetector.SimpleOnScaleGestureListener;
|
||||
import android.view.View;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.android.util.FileUtils;
|
||||
import com.reicast.emulator.Emulator;
|
||||
import com.reicast.emulator.GL2JNIActivity;
|
||||
import com.reicast.emulator.R;
|
||||
import com.reicast.emulator.config.Config;
|
||||
import com.reicast.emulator.periph.Gamepad;
|
||||
import com.reicast.emulator.periph.InputDeviceManager;
|
||||
import com.reicast.emulator.periph.VJoy;
|
||||
|
||||
import javax.microedition.khronos.egl.EGLConfig;
|
||||
import javax.microedition.khronos.opengles.GL10;
|
||||
|
@ -189,12 +175,7 @@ public class GL2JNIView extends GLSurfaceView
|
|||
public void onSurfaceChanged(GL10 gl,int width,int height)
|
||||
{
|
||||
gl.glViewport(0, 0, width, height);
|
||||
// TODO Is this required? The renderer sets the viewport and scissor test correctly
|
||||
// if (Emulator.widescreen) {
|
||||
JNIdc.rendinitJava(width, height);
|
||||
// } else {
|
||||
// JNIdc.rendinitJava(height * (4 / 3), height);
|
||||
// }
|
||||
JNIdc.rendinitJava(width, height);
|
||||
}
|
||||
|
||||
public void onSurfaceCreated(GL10 gl,EGLConfig config)
|
||||
|
@ -203,16 +184,10 @@ public class GL2JNIView extends GLSurfaceView
|
|||
}
|
||||
}
|
||||
|
||||
public void onDestroy() {
|
||||
/*
|
||||
// Workaround for ANR when returning to menu
|
||||
System.exit(0);
|
||||
try {
|
||||
ethd.join();
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
*/
|
||||
@Override
|
||||
protected void onDetachedFromWindow() {
|
||||
super.onDetachedFromWindow();
|
||||
JNIdc.rendtermJava();
|
||||
}
|
||||
|
||||
@TargetApi(19)
|
||||
|
|
|
@ -14,12 +14,14 @@ import android.view.SurfaceHolder;
|
|||
import android.view.SurfaceView;
|
||||
import android.view.View;
|
||||
|
||||
import com.reicast.emulator.Emulator;
|
||||
import com.reicast.emulator.NativeGLActivity;
|
||||
import com.reicast.emulator.config.Config;
|
||||
|
||||
public class NativeGLView extends SurfaceView implements SurfaceHolder.Callback {
|
||||
private Handler handler = new Handler();
|
||||
|
||||
private boolean surfaceReady = false;
|
||||
private boolean paused = false;
|
||||
VirtualJoystickDelegate vjoyDelegate;
|
||||
|
||||
|
@ -36,6 +38,9 @@ public class NativeGLView extends SurfaceView implements SurfaceHolder.Callback
|
|||
super(context, attrs);
|
||||
getHolder().addCallback(this);
|
||||
setKeepScreenOn(true);
|
||||
setFocusable(true);
|
||||
setFocusableInTouchMode(true);
|
||||
requestFocus();
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
||||
setOnSystemUiVisibilityChangeListener (new OnSystemUiVisibilityChangeListener() {
|
||||
|
@ -105,13 +110,21 @@ public class NativeGLView extends SurfaceView implements SurfaceHolder.Callback
|
|||
@Override
|
||||
public void surfaceChanged(SurfaceHolder surfaceHolder, int format, int w, int h) {
|
||||
//Log.i("reicast", "NativeGLView.surfaceChanged: " + w + "x" + h);
|
||||
surfaceReady = true;
|
||||
JNIdc.rendinitNative(surfaceHolder.getSurface(), w, h);
|
||||
Emulator.getCurrentActivity().handleStateChange(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
|
||||
//Log.i("reicast", "NativeGLView.surfaceDestroyed");
|
||||
surfaceReady = false;
|
||||
JNIdc.rendinitNative(null, 0, 0);
|
||||
Emulator.getCurrentActivity().handleStateChange(true);
|
||||
}
|
||||
|
||||
public boolean isSurfaceReady() {
|
||||
return surfaceReady;
|
||||
}
|
||||
|
||||
public void pause() {
|
||||
|
@ -124,6 +137,9 @@ public class NativeGLView extends SurfaceView implements SurfaceHolder.Callback
|
|||
if (paused) {
|
||||
//Log.i("reicast", "NativeGLView.resume");
|
||||
paused = false;
|
||||
setFocusable(true);
|
||||
setFocusableInTouchMode(true);
|
||||
requestFocus();
|
||||
JNIdc.resume();
|
||||
}
|
||||
startRendering();
|
||||
|
|
|
@ -1,10 +0,0 @@
|
|||
package com.reicast.emulator.emu;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
public class OnScreenMenu {
|
||||
|
||||
public static int getPixelsFromDp(float dps, Context context) {
|
||||
return (int) (dps * context.getResources().getDisplayMetrics().density + 0.5f);
|
||||
}
|
||||
}
|
|
@ -1,210 +0,0 @@
|
|||
package com.reicast.emulator.periph;
|
||||
|
||||
import android.app.UiModeManager;
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.res.Configuration;
|
||||
import android.util.SparseArray;
|
||||
import android.util.SparseIntArray;
|
||||
import android.view.KeyEvent;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
import tv.ouya.console.api.OuyaController;
|
||||
import tv.ouya.console.api.OuyaFacade;
|
||||
|
||||
public class Gamepad {
|
||||
|
||||
public static final String pref_player1 = "device_descriptor_player_1";
|
||||
public static final String pref_player2 = "device_descriptor_player_2";
|
||||
public static final String pref_player3 = "device_descriptor_player_3";
|
||||
public static final String pref_player4 = "device_descriptor_player_4";
|
||||
private static final String pref_pad = "controller";
|
||||
|
||||
public static final String pref_mic = "mic_plugged_in";
|
||||
|
||||
public static final String p2_peripheral = "p2_peripheral";
|
||||
public static final String p3_peripheral = "p3_peripheral";
|
||||
public static final String p4_peripheral = "p4_peripheral";
|
||||
|
||||
public static final String pref_js_modified = "modified_key_layout";
|
||||
public static final String pref_js_compat = "controller_compat";
|
||||
public static final String pref_js_merged = "merged_joystick";
|
||||
public static final String pref_js_rstick = "right_joystick";
|
||||
|
||||
public static final String pref_button_a = "a_button";
|
||||
public static final String pref_button_b = "b_button";
|
||||
public static final String pref_button_x = "x_button";
|
||||
public static final String pref_button_y = "y_button";
|
||||
|
||||
public static final String pref_button_l = "l_button";
|
||||
public static final String pref_button_r = "r_button";
|
||||
|
||||
public static final String pref_dpad_up = "dpad_up";
|
||||
public static final String pref_dpad_down = "dpad_down";
|
||||
public static final String pref_dpad_left = "dpad_left";
|
||||
public static final String pref_dpad_right = "dpad_right";
|
||||
|
||||
public static final String pref_axis_x = "x_axis";
|
||||
public static final String pref_axis_y = "y_axis";
|
||||
|
||||
public static final String pref_button_start = "start_button";
|
||||
public static final String pref_button_select = "select_button";
|
||||
|
||||
public static final String controllers_sony = "Sony PLAYSTATION(R)3 Controller";
|
||||
public static final String controllers_xbox = "Microsoft X-Box 360 pad";
|
||||
public static final String controllers_shield = "NVIDIA Corporation NVIDIA Controller";
|
||||
public static final String controllers_gamekey = "gamekeyboard";
|
||||
public static final String controllers_moga = "Moga";
|
||||
|
||||
|
||||
public String[] portId = { "_A", "_B", "_C", "_D" };
|
||||
public boolean[] compat = { false, false, false, false };
|
||||
public boolean[] custom = { false, false, false, false };
|
||||
public boolean[] joystick = { false, false, false, false };
|
||||
public int[] name = { -1, -1, -1, -1 };
|
||||
public float[] globalLS_X = new float[4], globalLS_Y = new float[4],
|
||||
previousLS_X = new float[4], previousLS_Y = new float[4];
|
||||
public int map[][] = new int[4][];
|
||||
|
||||
public SparseArray<String> deviceId_deviceDescriptor = new SparseArray<>();
|
||||
public HashMap<String, Integer> deviceDescriptor_PlayerNum = new HashMap<>();
|
||||
|
||||
public boolean isOuyaOrTV;
|
||||
|
||||
private static final int key_CONT_B = 0x0002;
|
||||
private static final int key_CONT_A = 0x0004;
|
||||
private static final int key_CONT_START = 0x0008;
|
||||
private static final int key_CONT_DPAD_UP = 0x0010;
|
||||
private static final int key_CONT_DPAD_DOWN = 0x0020;
|
||||
private static final int key_CONT_DPAD_LEFT = 0x0040;
|
||||
private static final int key_CONT_DPAD_RIGHT = 0x0080;
|
||||
private static final int key_CONT_Y = 0x0200;
|
||||
private static final int key_CONT_X = 0x0400;
|
||||
|
||||
public int[] getConsoleController() {
|
||||
return new int[] {
|
||||
OuyaController.BUTTON_O, key_CONT_A,
|
||||
OuyaController.BUTTON_A, key_CONT_B,
|
||||
OuyaController.BUTTON_U, key_CONT_X,
|
||||
OuyaController.BUTTON_Y, key_CONT_Y,
|
||||
|
||||
OuyaController.BUTTON_DPAD_UP, key_CONT_DPAD_UP,
|
||||
OuyaController.BUTTON_DPAD_DOWN, key_CONT_DPAD_DOWN,
|
||||
OuyaController.BUTTON_DPAD_LEFT, key_CONT_DPAD_LEFT,
|
||||
OuyaController.BUTTON_DPAD_RIGHT, key_CONT_DPAD_RIGHT,
|
||||
|
||||
getStartButtonCode(), key_CONT_START,
|
||||
getSelectButtonCode(), getSelectButtonCode()
|
||||
// Redundant, but verifies it is mapped properly
|
||||
};
|
||||
}
|
||||
|
||||
public int[] getOUYAController() {
|
||||
return new int[] {
|
||||
OuyaController.BUTTON_O, key_CONT_A,
|
||||
OuyaController.BUTTON_A, key_CONT_B,
|
||||
OuyaController.BUTTON_U, key_CONT_X,
|
||||
OuyaController.BUTTON_Y, key_CONT_Y,
|
||||
|
||||
OuyaController.BUTTON_DPAD_UP, key_CONT_DPAD_UP,
|
||||
OuyaController.BUTTON_DPAD_DOWN, key_CONT_DPAD_DOWN,
|
||||
OuyaController.BUTTON_DPAD_LEFT, key_CONT_DPAD_LEFT,
|
||||
OuyaController.BUTTON_DPAD_RIGHT, key_CONT_DPAD_RIGHT,
|
||||
|
||||
getStartButtonCode(), key_CONT_START,
|
||||
OuyaController.BUTTON_R3, key_CONT_START
|
||||
};
|
||||
}
|
||||
|
||||
public int[] getMogaController() {
|
||||
return new int[] {
|
||||
KeyEvent.KEYCODE_BUTTON_A, key_CONT_A,
|
||||
KeyEvent.KEYCODE_BUTTON_B, key_CONT_B,
|
||||
KeyEvent.KEYCODE_BUTTON_X, key_CONT_X,
|
||||
KeyEvent.KEYCODE_BUTTON_Y, key_CONT_Y,
|
||||
|
||||
KeyEvent.KEYCODE_DPAD_UP, key_CONT_DPAD_UP,
|
||||
KeyEvent.KEYCODE_DPAD_DOWN, key_CONT_DPAD_DOWN,
|
||||
KeyEvent.KEYCODE_DPAD_LEFT, key_CONT_DPAD_LEFT,
|
||||
KeyEvent.KEYCODE_DPAD_RIGHT, key_CONT_DPAD_RIGHT,
|
||||
|
||||
getStartButtonCode(), key_CONT_START,
|
||||
getSelectButtonCode(), getSelectButtonCode()
|
||||
};
|
||||
}
|
||||
|
||||
private int[] setModifiedKeys(String id, SharedPreferences mPrefs) {
|
||||
return new int[] {
|
||||
mPrefs.getInt(pref_button_a + id, OuyaController.BUTTON_O), key_CONT_A,
|
||||
mPrefs.getInt(pref_button_b + id, OuyaController.BUTTON_A), key_CONT_B,
|
||||
mPrefs.getInt(pref_button_x + id, OuyaController.BUTTON_U), key_CONT_X,
|
||||
mPrefs.getInt(pref_button_y + id, OuyaController.BUTTON_Y), key_CONT_Y,
|
||||
|
||||
mPrefs.getInt(pref_dpad_up + id, OuyaController.BUTTON_DPAD_UP), key_CONT_DPAD_UP,
|
||||
mPrefs.getInt(pref_dpad_down + id, OuyaController.BUTTON_DPAD_DOWN), key_CONT_DPAD_DOWN,
|
||||
mPrefs.getInt(pref_dpad_left + id, OuyaController.BUTTON_DPAD_LEFT), key_CONT_DPAD_LEFT,
|
||||
mPrefs.getInt(pref_dpad_right + id, OuyaController.BUTTON_DPAD_RIGHT), key_CONT_DPAD_RIGHT,
|
||||
|
||||
mPrefs.getInt(pref_button_start + id, getStartButtonCode()), key_CONT_START,
|
||||
mPrefs.getInt(pref_button_select + id, getSelectButtonCode()), getSelectButtonCode()
|
||||
};
|
||||
}
|
||||
|
||||
public boolean IsOuyaOrTV(Context context, boolean ouya) {
|
||||
if (ouya) {
|
||||
return OuyaFacade.getInstance().isRunningOnOUYAHardware();
|
||||
} else {
|
||||
try {
|
||||
UiModeManager uiModeManager = (UiModeManager)
|
||||
context.getSystemService(Context.UI_MODE_SERVICE);
|
||||
if (uiModeManager.getCurrentModeType() == Configuration.UI_MODE_TYPE_TELEVISION) {
|
||||
return true;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// Not entirely important
|
||||
}
|
||||
PackageManager pMan = context.getPackageManager();
|
||||
return pMan.hasSystemFeature(PackageManager.FEATURE_TELEVISION)
|
||||
|| OuyaFacade.getInstance().isRunningOnOUYAHardware();
|
||||
}
|
||||
}
|
||||
|
||||
private int getStartButtonCode() {
|
||||
return KeyEvent.KEYCODE_BUTTON_START;
|
||||
}
|
||||
|
||||
public int getSelectButtonCode() {
|
||||
return KeyEvent.KEYCODE_BUTTON_SELECT;
|
||||
}
|
||||
|
||||
public void setCustomMapping(String id, int playerNum, SharedPreferences prefs) {
|
||||
map[playerNum] = setModifiedKeys(id, prefs);
|
||||
}
|
||||
|
||||
public void initJoyStickLayout(int playerNum) {
|
||||
if (!joystick[playerNum]) {
|
||||
globalLS_X[playerNum] = previousLS_X[playerNum] = 0.0f;
|
||||
globalLS_Y[playerNum] = previousLS_Y[playerNum] = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
public void fullCompatibilityMode(SharedPreferences prefs) {
|
||||
for (int joy = 0; joy < 4; joy++) {
|
||||
if (compat[joy]) {
|
||||
String id = portId[joy];
|
||||
joystick[joy] = prefs.getBoolean(Gamepad.pref_js_merged + id, false);
|
||||
getCompatibilityMap(joy, portId[joy], prefs);
|
||||
initJoyStickLayout(joy);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void getCompatibilityMap(int playerNum, String id, SharedPreferences prefs) {
|
||||
name[playerNum] = prefs.getInt(Gamepad.pref_pad + id, -1);
|
||||
if (name[playerNum] != -1) {
|
||||
map[playerNum] = setModifiedKeys(id, prefs);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -34,8 +34,10 @@ public final class InputDeviceManager implements InputManager.InputDeviceListene
|
|||
|
||||
public void stopListening()
|
||||
{
|
||||
inputManager.unregisterInputDeviceListener(this);
|
||||
inputManager = null;
|
||||
if (inputManager != null) {
|
||||
inputManager.unregisterInputDeviceListener(this);
|
||||
inputManager = null;
|
||||
}
|
||||
joystickRemoved(VIRTUAL_GAMEPAD_ID);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,51 +0,0 @@
|
|||
package com.reicast.emulator.periph;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Paint;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
|
||||
import com.reicast.emulator.emu.OnScreenMenu;
|
||||
|
||||
public class VmuLcd extends View {
|
||||
|
||||
public final static int w = 48;
|
||||
public final static int h = 32;
|
||||
|
||||
private int[] image = new int[w*h];
|
||||
private Bitmap current = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
|
||||
private float scale;
|
||||
private Paint paint;
|
||||
|
||||
public VmuLcd(Context context) {
|
||||
super(context);
|
||||
paint = new Paint();
|
||||
scale = (float)OnScreenMenu.getPixelsFromDp(60, getContext()) / w;
|
||||
Log.d("VmuLcd", "scale: "+scale);
|
||||
}
|
||||
|
||||
public void configureScale(int dp) {
|
||||
scale = (float)OnScreenMenu.getPixelsFromDp(dp, getContext()) / w;
|
||||
}
|
||||
|
||||
public void updateBytes(byte[] data){
|
||||
for(int i=0; i<h; i++){
|
||||
for(int j=0; j<w; j++){
|
||||
image[i*w+j] = data[(h-i-1)*w+j]==0x00?Color.BLACK:Color.WHITE;
|
||||
}
|
||||
}
|
||||
postInvalidate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDraw(Canvas c) {
|
||||
current.setPixels(image, 0, w, 0, 0, w, h);
|
||||
c.scale(scale, scale);
|
||||
paint.setFilterBitmap(true);
|
||||
c.drawBitmap(current, 0, 0, paint);
|
||||
}
|
||||
|
||||
}
|
|
@ -259,6 +259,7 @@ JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_setExternalStorageDir
|
|||
env->DeleteLocalRef(dir);
|
||||
}
|
||||
setenv("REICAST_HOME", paths.c_str(), 1);
|
||||
gui_refresh_files();
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_bootdisk(JNIEnv *env,jobject obj, jstring disk) {
|
||||
|
|
|
@ -67,6 +67,23 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
class ShieldRemoteInputMapping : public InputMapping
|
||||
{
|
||||
public:
|
||||
ShieldRemoteInputMapping()
|
||||
{
|
||||
name = "Default";
|
||||
set_button(DC_BTN_A, 23);
|
||||
set_button(DC_DPAD_UP, 19);
|
||||
set_button(DC_DPAD_DOWN, 20);
|
||||
set_button(DC_DPAD_LEFT, 21);
|
||||
set_button(DC_DPAD_RIGHT, 22);
|
||||
set_button(EMU_BTN_MENU, 4);
|
||||
|
||||
dirty = false;
|
||||
}
|
||||
};
|
||||
|
||||
class AndroidGamepadDevice : public GamepadDevice
|
||||
{
|
||||
public:
|
||||
|
@ -89,7 +106,10 @@ public:
|
|||
}
|
||||
else if (!find_mapping())
|
||||
{
|
||||
input_mapper = new DefaultInputMapping();
|
||||
if (_name == "SHIELD Remote")
|
||||
input_mapper = new ShieldRemoteInputMapping();
|
||||
else
|
||||
input_mapper = new DefaultInputMapping();
|
||||
save_mapping();
|
||||
printf("using default mapping\n");
|
||||
}
|
||||
|
|
|
@ -1,27 +1,6 @@
|
|||
#include <EGL/egl.h>
|
||||
#include <GLES2/gl2.h>
|
||||
extern "C" {
|
||||
#include "deps/libpng/png.h"
|
||||
}
|
||||
#include "types.h"
|
||||
#include "deps/libzip/zip.h"
|
||||
|
||||
#define TEXTURE_LOAD_ERROR 0
|
||||
|
||||
//Taken from http://en.wikibooks.org/wiki/OpenGL_Programming/Intermediate/Textures
|
||||
/** loadTexture
|
||||
* loads a png file into an opengl texture object, using cstdio , libpng, and opengl.
|
||||
*
|
||||
* \param filename : the png file to be loaded
|
||||
* \param width : width of png, to be updated as a side effect of this function
|
||||
* \param height : height of png, to be updated as a side effect of this function
|
||||
*
|
||||
* \return GLuint : an opengl texture id. Will be 0 if there is a major error,
|
||||
* should be validated by the client of this function.
|
||||
*
|
||||
*/
|
||||
zip_file* file;
|
||||
|
||||
zip* APKArchive;
|
||||
void setAPK (const char* apkPath) {
|
||||
LOGI("Loading APK %s", apkPath);
|
||||
|
@ -42,133 +21,3 @@ void setAPK (const char* apkPath) {
|
|||
LOGI("File %i : %s\n", i, name);
|
||||
}
|
||||
}
|
||||
|
||||
void png_zip_read(png_structp png_ptr, png_bytep data, png_size_t length) {
|
||||
zip_fread(file, data, length);
|
||||
}
|
||||
|
||||
GLuint loadTextureFromPNG(const char* filename, int &width, int &height) {
|
||||
file = zip_fopen(APKArchive, filename, 0);
|
||||
if (!file) {
|
||||
LOGE("Error opening %s from APK", filename);
|
||||
return TEXTURE_LOAD_ERROR;
|
||||
}
|
||||
|
||||
//header for testing if it is a png
|
||||
png_byte header[8];
|
||||
|
||||
//read the header
|
||||
zip_fread(file, header, 8);
|
||||
|
||||
//test if png
|
||||
int is_png = !png_sig_cmp(header, 0, 8);
|
||||
if (!is_png) {
|
||||
zip_fclose(file);
|
||||
LOGE("Not a png file : %s", filename);
|
||||
return TEXTURE_LOAD_ERROR;
|
||||
}
|
||||
|
||||
//create png struct
|
||||
png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
|
||||
if (!png_ptr) {
|
||||
zip_fclose(file);
|
||||
LOGE("Unable to create png struct : %s", filename);
|
||||
return (TEXTURE_LOAD_ERROR);
|
||||
}
|
||||
|
||||
//create png info struct
|
||||
png_infop info_ptr = png_create_info_struct(png_ptr);
|
||||
if (!info_ptr) {
|
||||
png_destroy_read_struct(&png_ptr, (png_infopp) NULL, (png_infopp) NULL);
|
||||
LOGE("Unable to create png info : %s", filename);
|
||||
zip_fclose(file);
|
||||
return (TEXTURE_LOAD_ERROR);
|
||||
}
|
||||
|
||||
//create png info struct
|
||||
png_infop end_info = png_create_info_struct(png_ptr);
|
||||
if (!end_info) {
|
||||
png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp) NULL);
|
||||
LOGE("Unable to create png end info : %s", filename);
|
||||
zip_fclose(file);
|
||||
return (TEXTURE_LOAD_ERROR);
|
||||
}
|
||||
|
||||
//png error stuff, not sure libpng man suggests this.
|
||||
if (setjmp(png_jmpbuf(png_ptr))) {
|
||||
zip_fclose(file);
|
||||
LOGE("Error during setjmp : %s", filename);
|
||||
png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
|
||||
return (TEXTURE_LOAD_ERROR);
|
||||
}
|
||||
|
||||
//init png reading
|
||||
//png_init_io(png_ptr, fp);
|
||||
png_set_read_fn(png_ptr, NULL, png_zip_read);
|
||||
|
||||
//let libpng know you already read the first 8 bytes
|
||||
png_set_sig_bytes(png_ptr, 8);
|
||||
|
||||
// read all the info up to the image data
|
||||
png_read_info(png_ptr, info_ptr);
|
||||
|
||||
//variables to pass to get info
|
||||
int bit_depth, color_type;
|
||||
png_uint_32 twidth, theight;
|
||||
|
||||
// get info about png
|
||||
png_get_IHDR(png_ptr, info_ptr, &twidth, &theight, &bit_depth, &color_type, NULL, NULL, NULL);
|
||||
|
||||
//update width and height based on png info
|
||||
width = twidth;
|
||||
height = theight;
|
||||
|
||||
// Update the png info struct.
|
||||
png_read_update_info(png_ptr, info_ptr);
|
||||
|
||||
// Row size in bytes.
|
||||
int rowbytes = png_get_rowbytes(png_ptr, info_ptr);
|
||||
|
||||
// Allocate the image_data as a big block, to be given to opengl
|
||||
png_byte *image_data = new png_byte[rowbytes * height];
|
||||
if (!image_data) {
|
||||
//clean up memory and close stuff
|
||||
png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
|
||||
LOGE("Unable to allocate image_data while loading %s ", filename);
|
||||
zip_fclose(file);
|
||||
return TEXTURE_LOAD_ERROR;
|
||||
}
|
||||
|
||||
//row_pointers is for pointing to image_data for reading the png with libpng
|
||||
png_bytep *row_pointers = new png_bytep[height];
|
||||
if (!row_pointers) {
|
||||
//clean up memory and close stuff
|
||||
png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
|
||||
delete[] image_data;
|
||||
LOGE("Unable to allocate row_pointer while loading %s ", filename);
|
||||
zip_fclose(file);
|
||||
return TEXTURE_LOAD_ERROR;
|
||||
}
|
||||
// set the individual row_pointers to point at the correct offsets of image_data
|
||||
for (int i = 0; i < height; ++i)
|
||||
row_pointers[height - 1 - i] = image_data + i * rowbytes;
|
||||
|
||||
//read the png into image_data through row_pointers
|
||||
png_read_image(png_ptr, row_pointers);
|
||||
|
||||
//Now generate the OpenGL texture object
|
||||
GLuint texture;
|
||||
glGenTextures(1, &texture);
|
||||
glBindTexture(GL_TEXTURE_2D, texture);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA,
|
||||
GL_UNSIGNED_BYTE, (GLvoid*) image_data);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
|
||||
//clean up memory and close stuff
|
||||
png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
|
||||
delete[] image_data;
|
||||
delete[] row_pointers;
|
||||
zip_fclose(file);
|
||||
|
||||
return texture;
|
||||
}
|
||||
|
|
|
@ -2,7 +2,5 @@
|
|||
#define UTILS_H_
|
||||
|
||||
void setAPK (const char* apkPath);
|
||||
//Filename will be looked up in the apk (should start with assets/ or res/
|
||||
GLuint loadTextureFromPNG (const char* filename, int &width, int &height);
|
||||
|
||||
#endif /* UTILS_H_ */
|
||||
|
|
Before Width: | Height: | Size: 3.0 KiB |
Before Width: | Height: | Size: 1.0 KiB |
Before Width: | Height: | Size: 8.5 KiB |
Before Width: | Height: | Size: 5.5 KiB |
Before Width: | Height: | Size: 2.8 KiB |
Before Width: | Height: | Size: 5.0 KiB |
Before Width: | Height: | Size: 3.6 KiB |
Before Width: | Height: | Size: 3.0 KiB |
Before Width: | Height: | Size: 2.8 KiB |
Before Width: | Height: | Size: 6.1 KiB |
Before Width: | Height: | Size: 4.2 KiB |
Before Width: | Height: | Size: 3.1 KiB |
Before Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 7.0 KiB |
Before Width: | Height: | Size: 47 KiB |
Before Width: | Height: | Size: 17 KiB |
Before Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 4.4 KiB |
|
@ -1,14 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item>
|
||||
<shape android:shape="rectangle" android:padding="10dp" >
|
||||
<solid android:color="#D0000000"/>
|
||||
</shape>
|
||||
</item>
|
||||
<item>
|
||||
<bitmap
|
||||
android:gravity="center"
|
||||
android:src="@drawable/menutile"
|
||||
android:tileMode="repeat" />
|
||||
</item>
|
||||
</layer-list>
|
|
@ -1,4 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:src="@mipmap/texture_blue"
|
||||
android:tileMode="repeat" />
|
|
@ -1,4 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:src="@mipmap/texture_light"
|
||||
android:tileMode="repeat" />
|
Before Width: | Height: | Size: 5.6 KiB |
Before Width: | Height: | Size: 5.6 KiB |
Before Width: | Height: | Size: 6.0 KiB |
Before Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 3.9 KiB |
Before Width: | Height: | Size: 23 KiB |
Before Width: | Height: | Size: 22 KiB |
Before Width: | Height: | Size: 2.5 KiB |
Before Width: | Height: | Size: 8.5 KiB |
Before Width: | Height: | Size: 4.9 KiB |
Before Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 5.4 KiB |
Before Width: | Height: | Size: 9.3 KiB |
Before Width: | Height: | Size: 8.6 KiB |
Before Width: | Height: | Size: 9.5 KiB |
Before Width: | Height: | Size: 9.3 KiB |
Before Width: | Height: | Size: 8.7 KiB |
|
@ -1,10 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<!-- Selector style for listrow -->
|
||||
<item android:drawable="@android:color/transparent" android:state_pressed="false" android:state_selected="false" android:state_focused="false"/>
|
||||
<item android:drawable="@drawable/gradient_bg_hover_blue" android:state_pressed="true"/>
|
||||
<item android:drawable="@drawable/gradient_bg_hover_blue" android:state_focused="true"/>
|
||||
<item android:drawable="@drawable/gradient_bg_hover_blue" android:state_pressed="false" android:state_selected="true"/>
|
||||
|
||||
</selector>
|
|
@ -1,10 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<!-- Selector style for listrow -->
|
||||
<item android:drawable="@android:color/transparent" android:state_pressed="false" android:state_selected="false" android:state_focused="false"/>
|
||||
<item android:drawable="@drawable/gradient_bg_hover_dark" android:state_pressed="true"/>
|
||||
<item android:drawable="@drawable/gradient_bg_hover_dark" android:state_focused="true"/>
|
||||
<item android:drawable="@drawable/gradient_bg_hover_dark" android:state_pressed="false" android:state_selected="true"/>
|
||||
|
||||
</selector>
|
|
@ -1,10 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<!-- Selector style for listrow -->
|
||||
<item android:drawable="@android:color/transparent" android:state_pressed="false" android:state_selected="false" android:state_focused="false"/>
|
||||
<item android:drawable="@drawable/gradient_bg_hover_dream" android:state_pressed="true"/>
|
||||
<item android:drawable="@drawable/gradient_bg_hover_dream" android:state_focused="true"/>
|
||||
<item android:drawable="@drawable/gradient_bg_hover_dream" android:state_pressed="false" android:state_selected="true"/>
|
||||
|
||||
</selector>
|
Before Width: | Height: | Size: 5.6 KiB |
|
@ -1,12 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle" >
|
||||
|
||||
<!-- Gradient Bg for listrow -->
|
||||
<gradient
|
||||
android:angle="270"
|
||||
android:centerColor="#e7e7e8"
|
||||
android:endColor="#cfcfcf"
|
||||
android:startColor="#f1f1f2" />
|
||||
|
||||
</shape>
|
|
@ -1,12 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle" >
|
||||
|
||||
<!-- Gradient BgColor for listrow Selected -->
|
||||
<gradient
|
||||
android:angle="270"
|
||||
android:centerColor="@color/colorBlueAccentDark"
|
||||
android:endColor="@color/colorBlueAccent"
|
||||
android:startColor="@color/colorBlueAccent" />
|
||||
|
||||
</shape>
|
|
@ -1,12 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle" >
|
||||
|
||||
<!-- Gradient BgColor for listrow Selected -->
|
||||
<gradient
|
||||
android:angle="270"
|
||||
android:centerColor="@color/colorDarkAccentDark"
|
||||
android:endColor="@color/colorDarkAccent"
|
||||
android:startColor="@color/colorDarkAccent" />
|
||||
|
||||
</shape>
|
|
@ -1,12 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle" >
|
||||
|
||||
<!-- Gradient BgColor for listrow Selected -->
|
||||
<gradient
|
||||
android:angle="270"
|
||||
android:centerColor="@color/colorDreamAccentLight"
|
||||
android:endColor="@color/colorDreamAccent"
|
||||
android:startColor="@color/colorDreamAccent" />
|
||||
|
||||
</shape>
|
|
@ -1,9 +0,0 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M19.35,10.04C18.67,6.59 15.64,4 12,4 9.11,4 6.6,5.64 5.35,8.04 2.34,8.36 0,10.91 0,14c0,3.31 2.69,6 6,6h13c2.76,0 5,-2.24 5,-5 0,-2.64 -2.05,-4.78 -4.65,-4.96zM19,18H6c-2.21,0 -4,-1.79 -4,-4s1.79,-4 4,-4h0.71C7.37,7.69 9.48,6 12,6c3.04,0 5.5,2.46 5.5,5.5v0.5H19c1.66,0 3,1.34 3,3s-1.34,3 -3,3z"/>
|
||||
</vector>
|
|
@ -1,4 +0,0 @@
|
|||
<vector android:height="40dp" android:viewportHeight="24.0"
|
||||
android:viewportWidth="24.0" android:width="40dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="#FF000000" android:pathData="M10,4H4c-1.1,0 -1.99,0.9 -1.99,2L2,18c0,1.1 0.9,2 2,2h16c1.1,0 2,-0.9 2,-2V8c0,-1.1 -0.9,-2 -2,-2h-8l-2,-2z"/>
|
||||
</vector>
|
|
@ -1,9 +0,0 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M11,17h2v-6h-2v6zM12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM12,20c-4.41,0 -8,-3.59 -8,-8s3.59,-8 8,-8 8,3.59 8,8 -3.59,8 -8,8zM11,9h2L13,7h-2v2z"/>
|
||||
</vector>
|
|
@ -1,9 +0,0 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M21,3.01H3c-1.1,0 -2,0.9 -2,2V9h2V4.99h18v14.03H3V15H1v4.01c0,1.1 0.9,1.98 2,1.98h18c1.1,0 2,-0.88 2,-1.98v-14c0,-1.11 -0.9,-2 -2,-2zM11,16l4,-4 -4,-4v3H1v2h10v3z"/>
|
||||
</vector>
|
|
@ -1,9 +0,0 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M20,2L4,2c-1.1,0 -1.99,0.9 -1.99,2L2,22l4,-4h14c1.1,0 2,-0.9 2,-2L22,4c0,-1.1 -0.9,-2 -2,-2zM6,14v-2.47l6.88,-6.88c0.2,-0.2 0.51,-0.2 0.71,0l1.77,1.77c0.2,0.2 0.2,0.51 0,0.71L8.47,14L6,14zM18,14h-7.5l2,-2L18,12v2z"/>
|
||||
</vector>
|
|
@ -1,9 +0,0 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M2.01,21L23,12 2.01,3 2,10l15,2 -15,2z"/>
|
||||
</vector>
|
|
@ -1,9 +0,0 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M19.43,12.98c0.04,-0.32 0.07,-0.64 0.07,-0.98s-0.03,-0.66 -0.07,-0.98l2.11,-1.65c0.19,-0.15 0.24,-0.42 0.12,-0.64l-2,-3.46c-0.12,-0.22 -0.39,-0.3 -0.61,-0.22l-2.49,1c-0.52,-0.4 -1.08,-0.73 -1.69,-0.98l-0.38,-2.65C14.46,2.18 14.25,2 14,2h-4c-0.25,0 -0.46,0.18 -0.49,0.42l-0.38,2.65c-0.61,0.25 -1.17,0.59 -1.69,0.98l-2.49,-1c-0.23,-0.09 -0.49,0 -0.61,0.22l-2,3.46c-0.13,0.22 -0.07,0.49 0.12,0.64l2.11,1.65c-0.04,0.32 -0.07,0.65 -0.07,0.98s0.03,0.66 0.07,0.98l-2.11,1.65c-0.19,0.15 -0.24,0.42 -0.12,0.64l2,3.46c0.12,0.22 0.39,0.3 0.61,0.22l2.49,-1c0.52,0.4 1.08,0.73 1.69,0.98l0.38,2.65c0.03,0.24 0.24,0.42 0.49,0.42h4c0.25,0 0.46,-0.18 0.49,-0.42l0.38,-2.65c0.61,-0.25 1.17,-0.59 1.69,-0.98l2.49,1c0.23,0.09 0.49,0 0.61,-0.22l2,-3.46c0.12,-0.22 0.07,-0.49 -0.12,-0.64l-2.11,-1.65zM12,15.5c-1.93,0 -3.5,-1.57 -3.5,-3.5s1.57,-3.5 3.5,-3.5 3.5,1.57 3.5,3.5 -1.57,3.5 -3.5,3.5z"/>
|
||||
</vector>
|
|
@ -1,9 +0,0 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M19,15l-6,6 -1.42,-1.42L15.17,16H4V4h2v10h9.17l-3.59,-3.58L13,9l6,6z"/>
|
||||
</vector>
|
|
@ -1,14 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
|
||||
|
||||
<item>
|
||||
<shape android:shape="rectangle" >
|
||||
<stroke
|
||||
android:width="1dp"
|
||||
android:color="#dbdbdc" />
|
||||
|
||||
<solid android:color="#FFFFFF" />
|
||||
</shape>
|
||||
</item>
|
||||
|
||||
</layer-list>
|
Before Width: | Height: | Size: 4.2 KiB |
|
@ -1,6 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<stroke android:width="1dp" android:color="#FFA0A0A0" />
|
||||
<padding android:left="0dp" android:top="1dp" android:right="0dp"
|
||||
android:bottom="1dp" />
|
||||
</shape>
|
|
@ -1,9 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<!-- Selector style for listrow -->
|
||||
<item android:drawable="@drawable/gradient_bg" android:state_pressed="false" android:state_selected="false"/>
|
||||
<item android:drawable="@drawable/gradient_bg_hover_blue" android:state_pressed="true"/>
|
||||
<item android:drawable="@drawable/gradient_bg_hover_blue" android:state_pressed="false" android:state_selected="true"/>
|
||||
|
||||
</selector>
|
|
@ -1,9 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<!-- Selector style for listrow -->
|
||||
<item android:drawable="@drawable/gradient_bg" android:state_pressed="false" android:state_selected="false"/>
|
||||
<item android:drawable="@drawable/gradient_bg_hover_dark" android:state_pressed="true"/>
|
||||
<item android:drawable="@drawable/gradient_bg_hover_dark" android:state_pressed="false" android:state_selected="true"/>
|
||||
|
||||
</selector>
|
|
@ -1,9 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<!-- Selector style for listrow -->
|
||||
<item android:drawable="@drawable/gradient_bg" android:state_pressed="false" android:state_selected="false"/>
|
||||
<item android:drawable="@drawable/gradient_bg_hover_dream" android:state_pressed="true"/>
|
||||
<item android:drawable="@drawable/gradient_bg_hover_dream" android:state_pressed="false" android:state_selected="true"/>
|
||||
|
||||
</selector>
|
Before Width: | Height: | Size: 26 KiB |
Before Width: | Height: | Size: 18 KiB |
Before Width: | Height: | Size: 9.3 KiB |