Merge remote-tracking branch 'origin/master' into fh/mymaster

This commit is contained in:
Flyinghead 2018-09-20 17:28:41 +02:00
commit 7ce4fccb37
152 changed files with 6595 additions and 5025 deletions

30
.gitignore vendored
View File

@ -1,12 +1,15 @@
.DS_Store
*.class
*.orig
*build_obj
Workdir/data
Workdir/reicast*
Workdir/vmu*
Workdir/webui*
Workdir/emu.cfg
Workdir/lib*ant.properties
bin/
gen/
obj/
# iOS/Xcode general stuff
# iOS General
.DS_Store
*/build/*
**/build/*
@ -39,17 +42,30 @@ Workdir/vmu*
Workdir/webui*
Workdir/emu.cfg
Workdir/lib*ant.properties
reicast-ios.xccheckout
# Linux stuff
# Linux General
shell/linux/.map
shell/linux/nosym-reicast.elf
shell/linux/reicast.elf
reicast-ios.xccheckout
# Visual Studio
generated
.vs
# Android General
bin/
gen/
obj/
build/*
*.so
local.properties
ant.properties
# Android Studio
.gradle
.idea
*.iml
.externalNativeBuild
gradle.properties
shell/android-studio/reicast/src/main/assets/build

View File

@ -44,7 +44,7 @@ install:
- test -z "$encrypted_c726d225a9d9_key" || mv debug.keystore ~/.android/debug.keystore
before_script:
script:
- git fetch --unshallow
- git fetch --depth 250
- cd shell/android-studio
- export NUMBER_OF_PROCESSORS=2
- sudo chmod 755 travis-build.sh

View File

@ -139,7 +139,7 @@ Development/Beta versions
| Platform | Status | Downloads
| -------------------------------------------------- | -------------- | ---------
| ![Android](http://i.imgur.com/nK9exQe.jpg) Android | [![Build Status](https://travis-ci.org/reicast/reicast-emulator.svg?branch=master)](https://travis-ci.org/reicast/reicast-emulator) | [Reicast CI Builds](http://builds.reicast.com)
| ![iOS](http://i.imgur.com/6bvAUUj.png) iOS | [![Build Status](https://app.bitrise.io/app/d082ed2fb1bdeeef.svg?token=39zhSBFh-b9YVJw8q91omw) | *TODO*
| ![iOS](http://i.imgur.com/6bvAUUj.png) iOS | [![Build Status](https://app.bitrise.io/app/d082ed2fb1bdeeef.svg?token=39zhSBFh-b9YVJw8q91omw)](https://app.bitrise.io/app/d082ed2fb1bdeeef#/builds) | *TODO*
| ![Windows](http://i.imgur.com/hAuMmjF.png) Windows | [![Build status](https://ci.appveyor.com/api/projects/status/353mwl73ki74tb58/branch/master?svg=true)](https://ci.appveyor.com/project/skmp/reicast-emulator/branch/master) | [Reicast CI Builds](http://builds.reicast.com)
| ![Linux](http://i.imgur.com/19aAoQD.png) Linux | [![wercker status](https://app.wercker.com/status/bcabca642a2de044c6f58203b975878b/s/master "wercker status")](https://app.wercker.com/project/bykey/bcabca642a2de044c6f58203b975878b) | *TODO*
| ![OSX](http://i.imgur.com/0YoI5Vm.png) OSX | *TODO* | *TODO*

View File

@ -302,10 +302,9 @@ function reset() {
}
socket_lm.onmessage =function got_packet(msg) {
j = msg.data.split(';');
f = 0;
var j = msg.data.split(';'), f = 0;
while (f < j.length - 1) {
i = j[f].split(' ');
var i = j[f].split(' ');
if (i[0] == 'd') {
ctx.strokeStyle = i[1];
ctx.beginPath();

View File

@ -160,6 +160,15 @@ s32 cfgLoadInt(const wchar * Section, const wchar * Key,s32 Default)
return cfgdb.get_int(string(Section), string(Key), Default);
}
s32 cfgGameInt(const wchar * Section, const wchar * Key,s32 Default)
{
if(cfgdb.has_entry(string(Section), string(Key)))
{
return cfgdb.get_int(string(Section), string(Key), Default);
}
return Default;
}
void cfgSaveBool(const wchar * Section, const wchar * Key, bool BoolValue)
{
cfgdb.set_bool(string(Section), string(Key), BoolValue);

View File

@ -11,6 +11,7 @@
bool cfgOpen();
s32 cfgLoadInt(const wchar * lpSection, const wchar * lpKey,s32 Default);
s32 cfgGameInt(const wchar * lpSection, const wchar * lpKey,s32 Default);
void cfgSaveInt(const wchar * lpSection, const wchar * lpKey, s32 Int);
void cfgLoadStr(const wchar * lpSection, const wchar * lpKey, wchar * lpReturn,const wchar* lpDefault);
string cfgLoadStr(const wchar * Section, const wchar * Key, const wchar* Default);

View File

@ -281,9 +281,6 @@ int core_fclose(core_file* fc)
if (f->f) {
fclose(f->f);
}
else {
}
delete f;

View File

@ -44,11 +44,13 @@ struct ifaddrs {
#define ifa_broadaddr ifa_dstaddr /* broadcast address interface */
#endif
#include <sys/cdefs.h>
__BEGIN_DECLS
#ifdef _cplusplus
extern "C" {
#endif
extern int getifaddrs(struct ifaddrs **ifap);
extern void freeifaddrs(struct ifaddrs *ifa);
__END_DECLS
#ifdef _cplusplus
}
#endif
#endif

View File

@ -157,7 +157,7 @@ elf64_getSectionName(void *elfFile, int i)
struct Elf64_Shdr *sections = elf64_getSectionTable((Elf64_Header*)elfFile);
char *str_table = elf64_getSegmentStringTable((Elf64_Header*)elfFile);
if (str_table == NULL) {
return "<corrupted>";
return (char*)"<corrupted>";
} else {
return str_table + sections[i].sh_name;
}

View File

@ -396,8 +396,7 @@ int lws_client_socket_service(struct libwebsocket_context *context,
* definitively ready from browser pov.
*/
len = 1;
while (wsi->u.hdr.parser_state != WSI_PARSING_COMPLETE &&
len > 0) {
while (wsi->u.hdr.parser_state != WSI_PARSING_COMPLETE) {
n = lws_ssl_capable_read(wsi, &c, 1);
lws_latency(context, wsi, "send lws_issue_raw", n, n == 1);
switch (n) {

View File

@ -1,4 +1,4 @@
#pragma once
#include "deps/zlib/zlib.h"
#define DEFLATE_FRAME_COMPRESSION_LEVEL_SERVER 1

View File

@ -24,7 +24,6 @@
#ifdef __cplusplus
extern "C" {
#include <cstddef>
#endif
#ifdef CMAKE_BUILD
@ -36,6 +35,7 @@ extern "C" {
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stddef.h>

View File

@ -18,7 +18,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
#pragma once
#include "build.h"
/* The Libwebsocket version */
@ -203,7 +203,6 @@ typedef unsigned __int64 u_int64_t;
#else
#include <sys/stat.h>
#include <sys/cdefs.h>
#include <sys/time.h>
#if defined(__APPLE__)

View File

@ -99,8 +99,6 @@ static const unsigned int _K[] =
sha1_step(ctxt); \
}
static void sha1_step __P((struct sha1_ctxt *));
static void
sha1_step(struct sha1_ctxt *ctxt)
{

View File

@ -1,6 +1,9 @@
#pragma once
#include "types.h"
#include "x86_op_classes.h"
#if HOST_OS == OS_DARWIN
#include <TargetConditionals.h>
#endif
using namespace std;
//Oh god , x86 is a sooo badly designed opcode arch -_-
@ -230,7 +233,7 @@ struct /*__declspec(dllexport)*/ x86_ptr_imm
}
#if HOST_CPU != CPU_X64
#ifndef WIN32
#if !defined(WIN32) && !defined(TARGET_OS_MAC)
template<typename Rv, typename ...Args>
x86_ptr_imm(Rv(* ptr)(Args...))
{

View File

@ -73,10 +73,28 @@ void mcfg_Create(MapleDeviceType type,u32 bus,u32 port)
MapleDevices[bus][port] = dev;
}
void mcfg_CreateDevices()
void mcfg_CreateNAOMIJamma()
{
mcfg_Create(MDT_NaomiJamma, 0, 5);
}
void mcfg_CreateController(u32 bus, MapleDeviceType maple_type1, MapleDeviceType maple_type2)
{
mcfg_Create(MDT_SegaController, bus, 5);
if (maple_type1 != MDT_None)
mcfg_Create(maple_type1, bus, 0);
if (maple_type2 != MDT_None)
mcfg_Create(maple_type2, bus, 1);
}
void mcfg_CreateDevicesFromConfig()
{
// Create the configure controller count
int numberOfControl = cfgLoadInt("players", "nb", 1);
#if DC_PLATFORM == DC_PLATFORM_DREAMCAST
if (numberOfControl <= 0)
numberOfControl = 1;
if (numberOfControl > 4)
@ -90,11 +108,9 @@ int numberOfControl = cfgLoadInt("players", "nb", 1);
if (settings.input.DCMouse != 0 && numberOfControl < 4)
mcfg_Create(MDT_Mouse, numberOfControl++, 5);
// Default to two VMUs on controller 1
mcfg_Create(MDT_SegaVMU, 0, 0);
mcfg_Create(MDT_SegaVMU, 0, 1);
#else
mcfg_Create(MDT_NaomiJamma, 0, 5);
#endif
}
void mcfg_DestroyDevices()

View File

@ -1,5 +1,6 @@
#pragma once
#include "types.h"
#include "maple_devs.h"
enum PlainJoystickButtonId
{
@ -63,9 +64,11 @@ struct IMapleConfigMap
virtual ~IMapleConfigMap() {}
};
#ifndef _ANDROID
void mcfg_CreateDevices();
#if DC_PLATFORM == DC_PLATFORM_DREAMCAST
void mcfg_CreateDevicesFromConfig();
void mcfg_CreateController(u32 bus, MapleDeviceType maple_type1, MapleDeviceType maple_type2);
#else
void mcfg_CreateDevices();
void mcfg_CreateNAOMIJamma();
#endif
void mcfg_DestroyDevices();

View File

@ -274,6 +274,20 @@ struct maple_sega_vmu: maple_base
u8 lcd_data[192];
u8 lcd_data_decoded[48*32];
// creates an empty VMU
bool init_emptyvmu()
{
printf("Initialising empty VMU...\n");
uLongf dec_sz = sizeof(flash_data);
int rv = uncompress(flash_data, &dec_sz, vmu_default, sizeof(vmu_default));
verify(rv == Z_OK);
verify(dec_sz == sizeof(flash_data));
return (rv == Z_OK && dec_sz == sizeof(flash_data));
}
virtual void OnSetup()
{
memset(flash_data, 0, sizeof(flash_data));
@ -288,10 +302,15 @@ struct maple_sega_vmu: maple_base
printf("Unable to open VMU save file \"%s\", creating new file\n",apath.c_str());
file = fopen(apath.c_str(), "wb");
if (file) {
if (!init_emptyvmu())
printf("Failed to initialize an empty VMU, you should reformat it using the BIOS\n");
fwrite(flash_data, sizeof(flash_data), 1, file);
fseek(file, 0, SEEK_SET);
} else {
printf("Unable to create vmu\n");
}
else
{
printf("Unable to create VMU!\n");
}
}
@ -309,12 +328,25 @@ struct maple_sega_vmu: maple_base
sum |= flash_data[i];
if (sum == 0) {
printf("Initialising empty vmu...\n");
uLongf dec_sz = sizeof(flash_data);
int rv=uncompress(flash_data, &dec_sz, vmu_default, sizeof(vmu_default));
// This means the existing VMU file is completely empty and needs to be recreated
verify(rv == Z_OK);
verify(dec_sz == sizeof(flash_data));
if (init_emptyvmu())
{
if (!file)
file = fopen(apath.c_str(), "wb");
if (file) {
fwrite(flash_data, sizeof(flash_data), 1, file);
fseek(file, 0, SEEK_SET);
}
else {
printf("Unable to create VMU!\n");
}
}
else
{
printf("Failed to initialize an empty VMU, you should reformat it using the BIOS\n");
}
}
}

View File

@ -4,6 +4,7 @@
enum MapleDeviceType
{
MDT_SegaController,
MDT_SegaVMU,
MDT_Microphone,
MDT_PurupuruPack,
@ -12,6 +13,7 @@ enum MapleDeviceType
MDT_NaomiJamma,
MDT_None,
MDT_Count
};

View File

@ -1,4 +1,3 @@
#include "_vmem.h"
#include "hw/aica/aica_if.h"
#include "hw/sh4/dyna/blockmanager.h"

View File

@ -188,7 +188,7 @@ bool naomi_cart_LoadRom(char* file)
char* eon = strstr(line, "\n");
if (!eon)
printf("+Loading naomi rom that has no name\n", line);
printf("+Loading naomi rom that has no name\n");
else
*eon = 0;

View File

@ -1,5 +1,10 @@
#ifndef NAOMI_CART_H
#define NAOMI_CART_H
#include "types.h"
bool naomi_cart_Read(u32 offset, u32 size, void* dst);
void* naomi_cart_GetPtr(u32 offset, u32 size);
bool naomi_cart_SelectFile(void* handle);
#endif //NAOMI_CART_H

View File

@ -366,7 +366,6 @@ void rend_start_render()
}
if (fCheckFrames) {
u8 v;
u8 digest2[16];
int ch = fgetc(fCheckFrames);
@ -420,7 +419,8 @@ void rend_start_render()
#if HOST_OS==OS_WINDOWS && 0
printf("max: idx: %d, vtx: %d, op: %d, pt: %d, tr: %d, mvo: %d, modt: %d, ov: %d\n", max_idx, max_vtx, max_op, max_pt, max_tr, max_mvo, max_modt, ovrn);
#endif
if (QueueRender(ctx)) {
if (QueueRender(ctx))
{
palette_update();
#if !defined(TARGET_NO_THREADS)
rs.Set();
@ -472,11 +472,11 @@ void rend_end_wait()
bool rend_init()
{
if (fLogFrames = fopen(settings.pvr.HashLogFile.c_str(), "wb")) {
if ((fLogFrames = fopen(settings.pvr.HashLogFile.c_str(), "wb"))) {
printf("Saving frame hashes to: '%s'\n", settings.pvr.HashLogFile.c_str());
}
if (fCheckFrames = fopen(settings.pvr.HashCheckFile.c_str(), "rb")) {
if ((fCheckFrames = fopen(settings.pvr.HashCheckFile.c_str(), "rb"))) {
printf("Comparing frame hashes against: '%s'\n", settings.pvr.HashCheckFile.c_str());
}

View File

@ -16,7 +16,6 @@
#include "pvr_regs.h"
#include "pvr_mem.h"
#include "Renderer_if.h"
#include <algorithm>
void libPvr_LockedBlockWrite (vram_block* block,u32 addr)

View File

@ -13,7 +13,6 @@
//TODO : move code later to a plugin
//TODO : Fix registers arrays , they must be smaller now doe to the way SB registers are handled
#include "types.h"
#include "hw/holly/holly_intc.h"
@ -251,7 +250,6 @@ void TAWrite(u32 address,u32* data,u32 count)
}
#include "hw/sh4/sh4_mmr.h"
#include "hw/pvr/ta.h"
void NOINLINE MemWrite32(void* dst, void* src)
{

View File

@ -9,7 +9,6 @@
#include "hw/sh4/modules/dmac.h"
#include "hw/sh4/sh4_mem.h"
#include "pvr_sb_regs.h"
#include "types.h"
#include "hw/sh4/sh4_mmr.h"
#include "ta.h"

View File

@ -150,7 +150,7 @@ bool QueueRender(TA_context* ctx)
bool too_fast = (cycle_span / time_span) > (SH4_MAIN_CLOCK * 1.2);
if (rqueue && too_fast && settings.pvr.SynchronousRendering) {
if (rqueue && too_fast && settings.pvr.SynchronousRender) {
//wait for a frame if
// we have another one queue'd and
// sh4 run at > 120% on the last slice

View File

@ -122,7 +122,7 @@ RuntimeBlockInfo* bm_GetBlock(void* dynarec_code)
}
else
{
printf("bm_GetBlock(%08X) failed ..\n",dynarec_code);
printf("bm_GetBlock(%08x) failed ..\n",dynarec_code);
return 0;
}
}
@ -510,7 +510,7 @@ void bm_PrintTopBlocks()
sel_hops+=all_blocks[i]->host_opcodes*all_blocks[i]->runs;
}
printf(" >-< %.2f%% covered in top 1% blocks\n",sel_hops/total_hops);
printf(" >-< %.2f%% covered in top 1%% blocks\n",sel_hops/total_hops);
size_t i;
for (i=all_blocks.size()/100;sel_hops/total_hops<50;i++)

View File

@ -694,7 +694,7 @@ u32 MatchDiv32(u32 pc , Sh4RegType &reg1,Sh4RegType &reg2 , Sh4RegType &reg3)
}
bool MatchDiv32u(u32 op,u32 pc)
{
if (settings.dynarec.DisableDivMatching)
if (settings.dynarec.safemode)
return false;
div_som_reg1=NoReg;
@ -716,7 +716,7 @@ bool MatchDiv32u(u32 op,u32 pc)
bool MatchDiv32s(u32 op,u32 pc)
{
if (settings.dynarec.DisableDivMatching)
if (settings.dynarec.safemode)
return false;
u32 n = GetN(op);

View File

@ -2,7 +2,6 @@
#include "interpr/sh4_opcodes.h"
#include "sh4_opcode_list.h"
#include "dyna/decoder_opcodes.h"
#include "types.h"
#include "hw/sh4/dyna/shil.h"
#include "reios/reios.h"

View File

@ -1,3 +1,6 @@
#ifndef SH4_SCHED_H
#define SH4_SCHED_H
#include "types.h"
/*
@ -45,3 +48,5 @@ int sh4_sched_elapsed(int id);
void sh4_sched_tick(int cycles);
extern u32 sh4_sched_intr;
#endif //SH4_SCHED_H

View File

@ -68,7 +68,7 @@ Disc* cdi_parse(const wchar* file)
case 2 :
default: printf("Mode2/"); break;
}
printf("%d ",track.sector_size);
printf("%lu ",track.sector_size);
printf("Pregap: %-3ld ",track.pregap_length);
printf("Size: %-6ld ",track.length);
@ -122,7 +122,7 @@ Disc* cdi_parse(const wchar* file)
else
{
printf("Track position: %d\n",track.position + track.pregap_length * track.sector_size);
printf("Track position: %lu\n",track.position + track.pregap_length * track.sector_size);
core_fseek(fsource, track.position, SEEK_SET);
// fseek(fsource, track->pregap_length * track->sector_size, SEEK_CUR);
// fseek(fsource, track->length * track->sector_size, SEEK_CUR);

View File

@ -140,7 +140,7 @@ bool CHDDisc::TryOpen(const wchar* file)
if (total_frames!=549300 || tracks.size()<3)
{
printf("WARNING: chd: Total frames is wrong: %d frames in %d tracks\n",total_frames,tracks.size());
printf("WARNING: chd: Total frames is wrong: %u frames in %u tracks\n",total_frames,tracks.size());
#ifndef NOT_REICAST
msgboxf("This is an improper dump!",MBX_ICONEXCLAMATION);
#endif

View File

@ -131,9 +131,21 @@ bool ConvertSector(u8* in_buff , u8* out_buff , int from , int to,int sector)
Disc* OpenDisc(const wchar* fn)
{
Disc* rv;
Disc* rv = nullptr;
for (int i=0;drivers[i] && !(rv=drivers[i](fn));i++) ;
for (unat i=0; drivers[i] && !rv; i++) { // ;drivers[i] && !(rv=drivers[i](fn));
rv = drivers[i](fn);
if (rv && cdi_parse == drivers[i]) {
const wchar warn_str[] = "Warning: CDI Image Loaded!\n Many CDI images are known to be defective, GDI or CHD format is preferred. Please only file bug reports when using images known to be good (GDI or CHD).";
#ifdef _ANDROID
printf(warn_str);
#else
msgboxf(warn_str, MBX_ICONASTERISK);// if (OS_DlgYes!=os_Dialog(OS_DialogYesNo, cdiWarn_S)) rv=0;
#endif
break;
}
}
return rv;
}
@ -171,7 +183,7 @@ bool InitDrive(u32 fileflags)
printf("Loading default image \"%s\"\n",settings.imgread.DefaultImage);
if (!InitDrive_(settings.imgread.DefaultImage))
{
msgboxf("Default image \"%s\" failed to load",MBX_ICONERROR);
msgboxf("Default image \"%s\" failed to load",MBX_ICONERROR,settings.imgread.DefaultImage);
return false;
}
else
@ -231,7 +243,7 @@ bool DiscSwap(u32 fileflags)
printf("Loading default image \"%s\"\n",settings.imgread.DefaultImage);
if (!InitDrive_(settings.imgread.DefaultImage))
{
msgboxf("Default image \"%s\" failed to load",MBX_ICONERROR);
msgboxf("Default image \"%s\" failed to load",MBX_ICONERROR,settings.imgread.DefaultImage);
return false;
}
else

View File

@ -37,7 +37,7 @@ void dispmanx_window_create()
src_rect.width = window_width << 16;
src_rect.height = window_height << 16;
if(settings.dispmanx.Maintain_Aspect)
if(settings.dispmanx.Keep_Aspect)
{
float screen_aspect = (float)screen_width / screen_height;
float window_aspect = (float)window_width / window_height;

View File

@ -3,6 +3,9 @@
#include <linux/input.h>
#include "linux-dist/evdev.h"
#include "linux-dist/main.h"
#include "hw/maple/maple_devs.h"
#include "hw/maple/maple_cfg.h"
#include "cfg/cfg.h"
#include "cfg/ini.h"
#include <vector>
#include <map>
@ -16,17 +19,25 @@
libevdev_func1_t libevdev_event_code_from_name;
libevdev_func2_t libevdev_event_code_get_name;
/* evdev input */
static EvdevController evdev_controllers[4] = {
{ -1, NULL },
{ -1, NULL },
{ -1, NULL },
{ -1, NULL }
};
void dc_stop(void);
void load_libevdev()
{
if (libevdev_tried)
{
return;
}
libevdev_tried = true;
void* lib_handle = dlopen("libevdev.so", RTLD_NOW);
void* lib_handle = dlopen("libevdev.so.2", RTLD_NOW);
if (!lib_handle) // libevdev.so.2 not found, fallback to libevdev.so
lib_handle = dlopen("libevdev.so", RTLD_NOW);
bool failed = false;
@ -107,6 +118,46 @@
this->rumble_effect_id = -1;
}
MapleDeviceType GetMapleDeviceType(int value, int port)
{
switch (value)
{
case 0:
#if defined(_DEBUG) || defined(DEBUG)
printf("Maple Device: None\n");
#endif
return MDT_None;
case 1:
#if defined(_DEBUG) || defined(DEBUG)
printf("Maple Device: VMU\n");
#endif
return MDT_SegaVMU;
case 2:
#if defined(_DEBUG) || defined(DEBUG)
printf("Maple Device: Microphone\n");
#endif
return MDT_Microphone;
case 3:
#if defined(_DEBUG) || defined(DEBUG)
printf("Maple Device: PuruPuruPack\n");
#endif
return MDT_PurupuruPack;
default:
MapleDeviceType result = MDT_None;
string result_type = "None";
// Controller in port 0 (player1) defaults to VMU for Maple device, all other to None
if (port == 0)
{
result_type = "VMU";
result = MDT_SegaVMU;
}
printf("Unsupported configuration (%d) for Maple Device, using %s\n", value, result_type.c_str());
return result;
}
}
std::map<std::string, EvdevControllerMapping> loaded_mappings;
int load_keycode(ConfigFile* cfg, string section, string dc_key)
@ -123,6 +174,7 @@
int type = ((strstr(keycode.c_str(), "ABS_") != NULL) ? EV_ABS : EV_KEY);
code = libevdev_event_code_from_name(type, keycode.c_str());
}
if (code < 0)
{
printf("evdev: failed to find keycode for '%s'\n", keycode.c_str());
@ -131,18 +183,20 @@
{
printf("%s = %s (%d)\n", dc_key.c_str(), keycode.c_str(), code);
}
return code;
}
else
{
code = cfg->get_int(section, dc_key, -1);
if(code >= 0)
{
char* name = NULL;
if (libevdev_available)
{
int type = ((strstr(dc_key.c_str(), "axis_") != NULL) ? EV_ABS : EV_KEY);
name = (char*)libevdev_event_code_get_name(type, code);
}
if (name != NULL)
{
printf("%s = %s (%d)\n", dc_key.c_str(), name, code);
@ -152,6 +206,11 @@
printf("%s = %d\n", dc_key.c_str(), code);
}
}
}
if (code < 0)
printf("WARNING: %s/%s not configured!\n", section.c_str(), dc_key.c_str());
return code;
}
@ -192,13 +251,19 @@
mf.get_bool("compat", "axis_x_inverted", false),
mf.get_bool("compat", "axis_y_inverted", false),
mf.get_bool("compat", "axis_trigger_left_inverted", false),
mf.get_bool("compat", "axis_trigger_right_inverted", false)
mf.get_bool("compat", "axis_trigger_right_inverted", false),
mf.get_int("dreamcast", "maple_device1", -1),
mf.get_int("dreamcast", "maple_device2", -1)
};
return mapping;
}
bool input_evdev_button_assigned(EvdevControllerMapping* mapping, int button)
{
// Don't check unassigned buttons
if (button == -1)
return false;
return ((mapping->Btn_A == button)
|| (mapping->Btn_B == button)
|| (mapping->Btn_C == button)
@ -369,10 +434,78 @@
}
}
void start_shutdown(void);
bool input_evdev_handle(EvdevController* controller, u32 port)
void input_evdev_init()
{
int evdev_device_id[4] = { -1, -1, -1, -1 };
size_t size_needed;
int port, i;
char* evdev_device;
for (port = 0; port < 4; port++)
{
size_needed = snprintf(NULL, 0, EVDEV_DEVICE_CONFIG_KEY, port+1) + 1;
char* evdev_config_key = (char*)malloc(size_needed);
sprintf(evdev_config_key, EVDEV_DEVICE_CONFIG_KEY, port+1);
evdev_device_id[port] = cfgLoadInt("input", evdev_config_key, EVDEV_DEFAULT_DEVICE_ID(port+1));
free(evdev_config_key);
// Check if the same device is already in use on another port
if (evdev_device_id[port] < 0)
{
printf("evdev: Controller %d disabled by config.\n", port + 1);
}
else
{
size_needed = snprintf(NULL, 0, EVDEV_DEVICE_STRING, evdev_device_id[port]) + 1;
evdev_device = (char*)malloc(size_needed);
sprintf(evdev_device, EVDEV_DEVICE_STRING, evdev_device_id[port]);
size_needed = snprintf(NULL, 0, EVDEV_MAPPING_CONFIG_KEY, port+1) + 1;
evdev_config_key = (char*)malloc(size_needed);
sprintf(evdev_config_key, EVDEV_MAPPING_CONFIG_KEY, port+1);
string tmp;
const char* mapping = (cfgExists("input", evdev_config_key) == 2 ? (tmp = cfgLoadStr("input", evdev_config_key, "")).c_str() : NULL);
free(evdev_config_key);
input_evdev_init(&evdev_controllers[port], evdev_device, mapping);
free(evdev_device);
for (i = 0; i < port; i++)
{
if (evdev_device_id[port] == evdev_device_id[i])
{
// Multiple controllers with the same device, check for multiple button assignments
if (input_evdev_button_duplicate_button(evdev_controllers[i].mapping, evdev_controllers[port].mapping))
{
printf("WARNING: One or more button(s) of this device is also used in the configuration of input device %d (mapping: %s)\n", i, evdev_controllers[i].mapping->name.c_str());
}
}
}
#if DC_PLATFORM == DC_PLATFORM_DREAMCAST
mcfg_CreateController(port, GetMapleDeviceType(evdev_controllers[port].mapping->Maple_Device1, port), GetMapleDeviceType(evdev_controllers[port].mapping->Maple_Device2, port));
#endif
}
}
}
void input_evdev_close()
{
for (int port = 0; port < 4 ; port++)
{
if (evdev_controllers[port].fd >= 0)
{
close(evdev_controllers[port].fd);
}
}
}
bool input_evdev_handle(u32 port)
{
EvdevController* controller = &evdev_controllers[port];
#define SET_FLAG(field, mask, expr) field =((expr) ? (field & ~mask) : (field | mask))
if (controller->fd < 0 || controller->mapping == NULL)
{
@ -521,8 +654,10 @@
return true;
}
void input_evdev_rumble(EvdevController* controller, u16 pow_strong, u16 pow_weak)
void input_evdev_rumble(u32 port, u16 pow_strong, u16 pow_weak)
{
EvdevController* controller = &evdev_controllers[port];
if (controller->fd < 0 || controller->rumble_effect_id == -2)
{
// Either the controller is not used or previous rumble effect failed

View File

@ -4,7 +4,7 @@
struct EvdevControllerMapping
{
const std::string name;
const string name;
const int Btn_A;
const int Btn_B;
const int Btn_C;
@ -36,6 +36,8 @@ struct EvdevControllerMapping
const bool Axis_Analog_Y_Inverted;
const bool Axis_Trigger_Left_Inverted;
const bool Axis_Trigger_Right_Inverted;
const int Maple_Device1;
const int Maple_Device2;
};
struct EvdevAxisData
@ -71,7 +73,7 @@ struct EvdevController
#define EVDEV_DEFAULT_DEVICE_ID(port) (port == 1 ? EVDEV_DEFAULT_DEVICE_ID_1 : -1)
extern int input_evdev_init(EvdevController* controller, const char* device, const char* mapping_fname);
extern bool input_evdev_handle(EvdevController* controller, u32 port);
extern void input_evdev_rumble(EvdevController* controller, u16 pow_strong, u16 pow_weak);
extern bool input_evdev_button_duplicate_button(EvdevControllerMapping* mapping1, EvdevControllerMapping* mapping2);
extern void input_evdev_init();
extern void input_evdev_close();
extern bool input_evdev_handle(u32 port);
extern void input_evdev_rumble(u32 port, u16 pow_strong, u16 pow_weak);

77
core/linux-dist/main.cpp Executable file → Normal file
View File

@ -88,74 +88,15 @@ s8 joyx[4], joyy[4];
void emit_WriteCodeCache();
#if defined(USE_EVDEV)
/* evdev input */
static EvdevController evdev_controllers[4] = {
{ -1, NULL },
{ -1, NULL },
{ -1, NULL },
{ -1, NULL }
};
#endif
#if defined(USE_JOYSTICK)
/* legacy joystick input */
static int joystick_fd = -1; // Joystick file descriptor
#endif
void SetupInput()
void os_SetupInput()
{
#if defined(USE_EVDEV)
int evdev_device_id[4] = { -1, -1, -1, -1 };
size_t size_needed;
int port, i;
char* evdev_device;
for (port = 0; port < 4; port++)
{
size_needed = snprintf(NULL, 0, EVDEV_DEVICE_CONFIG_KEY, port+1) + 1;
char* evdev_config_key = (char*)malloc(size_needed);
sprintf(evdev_config_key, EVDEV_DEVICE_CONFIG_KEY, port+1);
evdev_device_id[port] = cfgLoadInt("input", evdev_config_key, EVDEV_DEFAULT_DEVICE_ID(port+1));
free(evdev_config_key);
// Check if the same device is already in use on another port
if (evdev_device_id[port] < 0)
{
printf("evdev: Controller %d disabled by config.\n", port + 1);
}
else
{
size_needed = snprintf(NULL, 0, EVDEV_DEVICE_STRING, evdev_device_id[port]) + 1;
evdev_device = (char*)malloc(size_needed);
sprintf(evdev_device, EVDEV_DEVICE_STRING, evdev_device_id[port]);
size_needed = snprintf(NULL, 0, EVDEV_MAPPING_CONFIG_KEY, port+1) + 1;
evdev_config_key = (char*)malloc(size_needed);
sprintf(evdev_config_key, EVDEV_MAPPING_CONFIG_KEY, port+1);
string tmp;
const char* mapping = (cfgExists("input", evdev_config_key) == 2 ? (tmp = cfgLoadStr("input", evdev_config_key, "")).c_str() : NULL);
free(evdev_config_key);
input_evdev_init(&evdev_controllers[port], evdev_device, mapping);
free(evdev_device);
for (i = 0; i < port; i++)
{
if (evdev_device_id[port] == evdev_device_id[i])
{
// Multiple controllers with the same device, check for multiple button assignments
if (input_evdev_button_duplicate_button(evdev_controllers[i].mapping, evdev_controllers[port].mapping))
{
printf("WARNING: One or more button(s) of this device is also used in the configuration of input device %d (mapping: %s)\n", i, evdev_controllers[i].mapping->name);
}
}
}
}
}
input_evdev_init();
#endif
#if defined(USE_JOYSTICK)
@ -193,7 +134,7 @@ void UpdateInputState(u32 port)
#endif
#if defined(USE_EVDEV)
input_evdev_handle(&evdev_controllers[port], port);
input_evdev_handle(port);
#endif
#if defined(USE_SDL)
@ -218,7 +159,7 @@ void UpdateVibration(u32 port, u32 value)
u16 pow_strong = (u16)(65535 * pow_l);
u16 pow_weak = (u16)(65535 * pow_r);
input_evdev_rumble(&evdev_controllers[port], pow_strong, pow_weak);
input_evdev_rumble(port, pow_strong, pow_weak);
#endif
}
@ -468,8 +409,6 @@ int main(int argc, wchar* argv[])
dc_init(argc,argv);
SetupInput();
#if !defined(TARGET_EMSCRIPTEN)
#if FEAT_HAS_NIXPROF
install_prof_handler(0);
@ -486,13 +425,7 @@ int main(int argc, wchar* argv[])
dc_term();
#if defined(USE_EVDEV)
for (int port = 0; port < 4 ; port++)
{
if(evdev_controllers[port].fd >= 0)
{
close(evdev_controllers[port].fd);
}
}
input_evdev_close();
#endif
#if defined(SUPPORT_X11)

View File

@ -731,12 +731,14 @@ void x11_window_destroy()
}
if (x11_disp)
{
#if !defined(GLES)
if (x11_glc)
{
glXMakeCurrent((Display*)x11_disp, None, NULL);
glXDestroyContext((Display*)x11_disp, (GLXContext)x11_glc);
x11_glc = NULL;
}
#endif
XCloseDisplay((Display*)x11_disp);
x11_disp = NULL;
}

View File

@ -5,6 +5,7 @@
#if HOST_OS == OS_DARWIN
#define _XOPEN_SOURCE 1
#define __USE_GNU 1
#include <TargetConditionals.h>
#endif
#if !defined(TARGET_NACL32)
#include <poll.h>
@ -93,7 +94,7 @@ void fault_handler (int sn, siginfo_t * si, void *segfault_ctx)
#endif
else
{
printf("SIGSEGV @ %p (fault_handler+0x%p) ... %p -> was not in vram\n", ctx.pc, ctx.pc - (unat)fault_handler, si->si_addr);
printf("SIGSEGV @ %u (fault_handler+0x%u) ... %p -> was not in vram\n", ctx.pc, ctx.pc - (unat)fault_handler, si->si_addr);
die("segfault");
signal(SIGSEGV, SIG_DFL);
}
@ -194,7 +195,7 @@ void VArray2::LockRegion(u32 offset,u32 size)
u32 rv=mprotect (data+offset-inpage, size+inpage, PROT_READ );
if (rv!=0)
{
printf("mprotect(%08X,%08X,R) failed: %d | %d\n",data+offset-inpage,size+inpage,rv,errno);
printf("mprotect(%8s,%08X,R) failed: %d | %d\n",data+offset-inpage,size+inpage,rv,errno);
die("mprotect failed ..\n");
}
@ -292,7 +293,7 @@ void enable_runfast()
}
void linux_fix_personality() {
#if !defined(TARGET_BSD) && !defined(_ANDROID) && !defined(TARGET_NACL32) && !defined(TARGET_EMSCRIPTEN) && HOST_OS != OS_DARWIN
#if !defined(TARGET_BSD) && !defined(_ANDROID) && !defined(TARGET_OS_MAC) && !defined(TARGET_NACL32) && !defined(TARGET_EMSCRIPTEN)
printf("Personality: %08X\n", personality(0xFFFFFFFF));
personality(~READ_IMPLIES_EXEC & personality(0xFFFFFFFF));
printf("Updated personality: %08X\n", personality(0xFFFFFFFF));
@ -328,7 +329,7 @@ void common_linux_setup()
settings.profile.run_counts=0;
printf("Linux paging: %08X %08X %08X\n",sysconf(_SC_PAGESIZE),PAGE_SIZE,PAGE_MASK);
printf("Linux paging: %ld %08X %08X\n",sysconf(_SC_PAGESIZE),PAGE_SIZE,PAGE_MASK);
verify(PAGE_MASK==(sysconf(_SC_PAGESIZE)-1));
}
#endif

View File

@ -15,6 +15,7 @@
#include "ppapi/utility/completion_callback_factory.h"
#include "types.h"
#include "maple_cfg.h"
#include <GLES2/gl2.h>
@ -252,6 +253,11 @@ void os_DoEvents() {
}
void os_SetupInput() {
#if DC_PLATFORM == DC_PLATFORM_DREAMCAST
mcfg_CreateDevicesFromConfig();
#endif
}
void UpdateInputState(u32 port) {

View File

@ -156,12 +156,18 @@ void LoadSpecialSettings()
// Surf Rocket Racers
|| !strncmp("T40216N", reios_product_number, 7))
{
printf("Disabling Div Matching for game %s\n", reios_product_number);
settings.dynarec.DisableDivMatching = true;
printf("Enabling Dynarec safe mode for game %s\n", reios_product_number);
settings.dynarec.safemode = 1;
}
}
#if defined(_ANDROID)
int reios_init_value;
void reios_init(int argc,wchar* argv[])
#else
int dc_init(int argc,wchar* argv[])
#endif
{
setbuf(stdin,0);
setbuf(stdout,0);
@ -169,7 +175,12 @@ int dc_init(int argc,wchar* argv[])
if (!_vmem_reserve())
{
printf("Failed to alloc mem\n");
#if defined(_ANDROID)
reios_init_value = -1;
return;
#else
return -1;
#endif
}
#if !defined(TARGET_NO_WEBUI) && !defined(TARGET_NO_THREADS)
@ -178,12 +189,22 @@ int dc_init(int argc,wchar* argv[])
if(ParseCommandLine(argc,argv))
{
#if defined(_ANDROID)
reios_init_value = 69;
return;
#else
return 69;
#endif
}
if(!cfgOpen())
{
msgboxf("Unable to open config file",MBX_ICONERROR);
#if defined(_ANDROID)
reios_init_value = -4;
return;
#else
return -4;
#endif
}
LoadSettings();
#ifndef _ANDROID
@ -201,10 +222,33 @@ int dc_init(int argc,wchar* argv[])
if (settings.bios.UseReios || !LoadRomFiles(get_readonly_data_path(DATA_PATH)))
{
if (!LoadHle(get_readonly_data_path(DATA_PATH)))
{
#if defined(_ANDROID)
reios_init_value = -4;
return;
#else
return -3;
#endif
}
else
{
printf("Did not load bios, using reios\n");
}
}
plugins_Init();
#if defined(_ANDROID)
}
int dc_init()
{
int rv = 0;
if (reios_init_value != 0)
return reios_init_value;
#else
LoadCustom();
#endif
#if FEAT_SHREC != DYNAREC_NONE
if(settings.dynarec.Enable)
@ -224,28 +268,19 @@ int dc_init(int argc,wchar* argv[])
sh4_cpu.Init();
mem_Init();
plugins_Init();
mem_map_default();
#ifndef _ANDROID
mcfg_CreateDevices();
#else
mcfg_CreateDevices();
os_SetupInput();
#if DC_PLATFORM == DC_PLATFORM_NAOMI
mcfg_CreateNAOMIJamma();
#endif
plugins_Reset(false);
mem_Reset(false);
sh4_cpu.Reset(false);
const char* bootfile = reios_locate_ip();
if (!bootfile || !reios_locate_bootfile("1ST_READ.BIN"))
printf("Failed to locate bootfile.\n");
LoadSpecialSettings();
return rv;
}
@ -295,7 +330,7 @@ void LoadSettings()
settings.dynarec.Enable = cfgLoadInt("config","Dynarec.Enabled", 1)!=0;
settings.dynarec.idleskip = cfgLoadInt("config","Dynarec.idleskip",1)!=0;
settings.dynarec.unstable_opt = cfgLoadInt("config","Dynarec.unstable-opt",0);
settings.dynarec.DisableDivMatching = cfgLoadInt("config", "Dynarec.DisableDivMatching", 0);
settings.dynarec.safemode = cfgLoadInt("config", "Dynarec.safe-mode", 0);
//disable_nvmem can't be loaded, because nvmem init is before cfg load
settings.dreamcast.cable = cfgLoadInt("config","Dreamcast.Cable",3);
settings.dreamcast.RTC = cfgLoadInt("config","Dreamcast.RTC",GetRTC_now());
@ -326,7 +361,7 @@ void LoadSettings()
settings.pvr.rend = cfgLoadInt("config","pvr.rend",0);
settings.pvr.MaxThreads = cfgLoadInt("config", "pvr.MaxThreads", 3);
settings.pvr.SynchronousRendering = cfgLoadInt("config", "pvr.SynchronousRendering", 0);
settings.pvr.SynchronousRender = cfgLoadInt("config", "pvr.SynchronousRendering", 0);
settings.debug.SerialConsole = cfgLoadInt("config", "Debug.SerialConsoleEnabled", 0) != 0;
@ -342,6 +377,9 @@ void LoadSettings()
// TODO Expose this with JNI
settings.rend.Clipping = 1;
settings.rend.ExtraDepthScale = 1.f;
// Configured on a per-game basis
settings.dynarec.safemode = 0;
#endif
settings.pvr.HashLogFile = cfgLoadStr("testing", "ta.HashLogFile", "");
@ -350,7 +388,7 @@ void LoadSettings()
#if SUPPORT_DISPMANX
settings.dispmanx.Width = cfgLoadInt("dispmanx","width",640);
settings.dispmanx.Height = cfgLoadInt("dispmanx","height",480);
settings.dispmanx.Maintain_Aspect = cfgLoadBool("dispmanx","maintain_aspect",true);
settings.dispmanx.Keep_Aspect = cfgLoadBool("dispmanx","maintain_aspect",true);
#endif
#if (HOST_OS != OS_LINUX || defined(_ANDROID) || defined(TARGET_PANDORA))
@ -371,6 +409,31 @@ void LoadSettings()
settings.dreamcast.broadcast= min(max(settings.dreamcast.broadcast,0),4);
*/
}
void LoadCustom()
{
char *reios_id = reios_disk_id();
LoadSpecialSettings(); // Default per-game settings
if (reios_software_name[0] != '\0')
cfgSaveStr(reios_id, "software.name", reios_software_name);
settings.dynarec.Enable = cfgGameInt(reios_id,"Dynarec.Enabled", settings.dynarec.Enable ? 1 : 0) != 0;
settings.dynarec.idleskip = cfgGameInt(reios_id,"Dynarec.idleskip", settings.dynarec.idleskip ? 1 : 0) != 0;
settings.dynarec.unstable_opt = cfgGameInt(reios_id,"Dynarec.unstable-opt", settings.dynarec.unstable_opt);
settings.dynarec.safemode = cfgGameInt(reios_id,"Dynarec.safemode", settings.dynarec.safemode);
settings.rend.ModifierVolumes = cfgGameInt(reios_id,"rend.ModifierVolumes", settings.rend.ModifierVolumes);
settings.rend.Clipping = cfgGameInt(reios_id,"rend.Clipping", settings.rend.Clipping);
settings.pvr.subdivide_transp = cfgGameInt(reios_id,"pvr.Subdivide", settings.pvr.subdivide_transp);
settings.pvr.ta_skip = cfgGameInt(reios_id,"ta.skip", settings.pvr.ta_skip);
settings.pvr.rend = cfgGameInt(reios_id,"pvr.rend", settings.pvr.rend);
settings.pvr.MaxThreads = cfgGameInt(reios_id, "pvr.MaxThreads", settings.pvr.MaxThreads);
settings.pvr.SynchronousRender = cfgGameInt(reios_id, "pvr.SynchronousRendering", settings.pvr.SynchronousRender);
}
void SaveSettings()
{
cfgSaveInt("config","Dynarec.Enabled", settings.dynarec.Enable);

View File

@ -0,0 +1,49 @@
#include "oslib/audiobackend_libao.h"
#ifdef USE_LIBAO
#include <ao/ao.h>
static ao_device *aodevice;
static ao_sample_format aoformat;
static void libao_init()
{
ao_initialize();
memset(&aoformat, 0, sizeof(aoformat));
aoformat.bits = 16;
aoformat.channels = 2;
aoformat.rate = 44100;
aoformat.byte_format = AO_FMT_LITTLE;
aodevice = ao_open_live(ao_default_driver_id(), &aoformat, NULL); // Live output
if (!aodevice)
aodevice = ao_open_live(ao_driver_id("null"), &aoformat, NULL);
}
static u32 libao_push(void* frame, u32 samples, bool wait)
{
if (aodevice)
ao_play(aodevice, (char*)frame, samples * 4);
return 1;
}
static void libao_term()
{
if (aodevice)
{
ao_close(aodevice);
ao_shutdown();
}
}
audiobackend_t audiobackend_libao = {
"libao", // Slug
"libao", // Name
&libao_init,
&libao_push,
&libao_term
};
#endif

View File

@ -0,0 +1,4 @@
#pragma once
#include "oslib/audiostream.h"
extern audiobackend_t audiobackend_libao;

View File

@ -2,11 +2,7 @@
#ifdef USE_OSS
#include <sys/ioctl.h>
#include <sys/fcntl.h>
#ifdef TARGET_BSD
#include <unistd.h>
#else
#include <sys/unistd.h>
#endif
#include <sys/soundcard.h>
static int oss_audio_fd = -1;

View File

@ -9,6 +9,7 @@
#include "oslib/audiobackend_pulseaudio.h"
#include "oslib/audiobackend_coreaudio.h"
#include "oslib/audiobackend_omx.h"
#include "oslib/audiobackend_libao.h"
struct SoundFrame { s16 l;s16 r; };
#define SAMPLE_COUNT 512
@ -90,6 +91,9 @@ void RegisterAllAudioBackends() {
#if USE_PULSEAUDIO
RegisterAudioBackend(&audiobackend_pulseaudio);
#endif
#if USE_LIBAO
RegisterAudioBackend(&audiobackend_libao);
#endif
#if HOST_OS == OS_DARWIN
RegisterAudioBackend(&audiobackend_coreaudio);
#endif

View File

@ -7,6 +7,7 @@ double os_GetSeconds();
void os_DoEvents();
void os_CreateWindow();
void os_SetupInput();
void WriteSample(s16 right, s16 left);
#if BUILD_COMPILER==COMPILER_VC

View File

@ -20,7 +20,6 @@
#define SHIL_MODE 2
#include "hw/sh4/dyna/shil_canonical.h"
#define MIPS_COUNTER 0
struct DynaRBI : RuntimeBlockInfo
@ -35,8 +34,6 @@ struct DynaRBI : RuntimeBlockInfo
}
};
int cycle_counter;
extern int mips_counter;

View File

@ -93,7 +93,7 @@ ngen_mainloop:
push ebp
push ebx
mov ecx,0xA0000000
mov ecx,[eax-184] # PC - was 0xA0000000
mov dword ptr cycle_counter, 448 #SH4_TIMESLICE
lea eax, no_update

View File

@ -71,7 +71,7 @@ naked void ngen_mainloop(void* cntx)
push ebp;
push ebx;
mov ecx,0xA0000000;
mov ecx,[eax-184]; //# PC - was #0xA0000000
mov [cycle_counter],SH4_TIMESLICE;
mov [loop_no_update],offset no_update;

View File

@ -1,3 +1,8 @@
#ifndef DESCRAMBL_H
#define DESCRAMBL_H
#include "types.h"
void descrambl_file(u32 FAD, u32 file_size, u8* dst);
#endif //DESCRAMBL_H

View File

@ -110,7 +110,7 @@ void GD_HLE_Command(u32 cc, u32 prm)
switch(cc)
{
case GDCC_GETTOC:
printf("GDROM:\t*FIXME* CMD GETTOC PRM:%X\n",cc,prm);
printf("GDROM:\t*FIXME* CMD GETTOC CC:%X PRM:%X\n",cc,prm);
break;
case GDCC_GETTOC2:
@ -118,12 +118,12 @@ void GD_HLE_Command(u32 cc, u32 prm)
break;
case GDCC_GETSES:
debugf("GDROM:\tGETSES PRM:%X\n", cc, prm);
debugf("GDROM:\tGETSES CC:%X PRM:%X\n", cc, prm);
GDROM_HLE_ReadSES(r[5]);
break;
case GDCC_INIT:
printf("GDROM:\tCMD INIT PRM:%X\n",cc,prm);
printf("GDROM:\tCMD INIT CC:%X PRM:%X\n",cc,prm);
break;
case GDCC_PIOREAD:
@ -131,30 +131,30 @@ void GD_HLE_Command(u32 cc, u32 prm)
break;
case GDCC_DMAREAD:
debugf("GDROM:\tCMD DMAREAD PRM:%X\n", cc, prm);
debugf("GDROM:\tCMD DMAREAD CC:%X PRM:%X\n", cc, prm);
GDROM_HLE_ReadDMA(r[5]);
break;
case GDCC_PLAY_SECTOR:
printf("GDROM:\tCMD PLAYSEC? PRM:%X\n",cc,prm);
printf("GDROM:\tCMD PLAYSEC? CC:%X PRM:%X\n",cc,prm);
break;
case GDCC_RELEASE:
printf("GDROM:\tCMD RELEASE? PRM:%X\n",cc,prm);
printf("GDROM:\tCMD RELEASE? CC:%X PRM:%X\n",cc,prm);
break;
case GDCC_STOP: printf("GDROM:\tCMD STOP PRM:%X\n",cc,prm); break;
case GDCC_SEEK: printf("GDROM:\tCMD SEEK PRM:%X\n",cc,prm); break;
case GDCC_PLAY: printf("GDROM:\tCMD PLAY PRM:%X\n",cc,prm); break;
case GDCC_PAUSE:printf("GDROM:\tCMD PAUSE PRM:%X\n",cc,prm); break;
case GDCC_STOP: printf("GDROM:\tCMD STOP CC:%X PRM:%X\n",cc,prm); break;
case GDCC_SEEK: printf("GDROM:\tCMD SEEK CC:%X PRM:%X\n",cc,prm); break;
case GDCC_PLAY: printf("GDROM:\tCMD PLAY CC:%X PRM:%X\n",cc,prm); break;
case GDCC_PAUSE:printf("GDROM:\tCMD PAUSE CC:%X PRM:%X\n",cc,prm); break;
case GDCC_READ:
printf("GDROM:\tCMD READ PRM:%X\n",cc,prm);
printf("GDROM:\tCMD READ CC:%X PRM:%X\n",cc,prm);
break;
case GDCC_GETSCD:
debugf("GDROM:\tGETSCD PRM:%X\n",cc,prm);
debugf("GDROM:\tGETSCD CC:%X PRM:%X\n",cc,prm);
GDCC_HLE_GETSCD(r[5]);
break;

View File

@ -101,33 +101,40 @@ bool reios_locate_bootfile(const char* bootfile="1ST_READ.BIN") {
return false;
}
char reios_bootfile[32];
char ip_bin[256];
static char reios_hardware_id[17];
static char reios_maker_id[17];
static char reios_device_info[17];
static char reios_area_symbols[9];
static char reios_peripherals[9];
char reios_hardware_id[17];
char reios_maker_id[17];
char reios_device_info[17];
char reios_area_symbols[9];
char reios_peripherals[9];
char reios_product_number[11];
static char reios_product_version[7];
static char reios_releasedate[17];
static char reios_boot_filename[17];
static char reios_software_company[17];
static char reios_software_name[129];
char reios_product_version[7];
char reios_releasedate[17];
char reios_boot_filename[17];
char reios_software_company[17];
char reios_software_name[129];
char reios_bootfile[32];
const char* reios_locate_ip() {
bool pre_init = false;
void reios_pre_init()
{
if (libGDR_GetDiscType() == GdRom) {
base_fad = 45150;
descrambl = false;
}
else {
} else {
u8 ses[6];
libGDR_GetSessionInfo(ses, 0);
libGDR_GetSessionInfo(ses, ses[2]);
base_fad = (ses[3] << 16) | (ses[4] << 8) | (ses[5] << 0);
descrambl = true;
}
pre_init = true;
}
char* reios_disk_id() {
if (!pre_init) reios_pre_init();
libGDR_ReadSector(GetMemPtr(0x8c008000, 0), base_fad, 256, 2048);
memset(ip_bin, 0, sizeof(ip_bin));
@ -144,35 +151,8 @@ const char* reios_locate_ip() {
memcpy(&reios_software_company[0], &ip_bin[112], 16 * sizeof(char));
memcpy(&reios_software_name[0], &ip_bin[128], 128 * sizeof(char));
printf("reios: Hardware ID is: %s\n", reios_hardware_id);
printf("reios: Maker ID is: %s\n", reios_maker_id);
printf("reios: Device info is: %s\n", reios_device_info);
printf("reios: Area symbols is: %s\n", reios_area_symbols);
printf("reios: Peripherals is: %s\n", reios_peripherals);
printf("reios: Product number is: %s\n", reios_product_number);
printf("reios: Product version is: %s\n", reios_product_version);
printf("reios: Release date is: %s\n", reios_releasedate);
printf("reios: Boot filename is: %s\n", reios_boot_filename);
printf("reios: Software company is: %s\n", reios_software_company);
printf("reios: Software name is: %s\n", reios_software_name);
printf("reios: loading ip.bin from FAD: %d\n", base_fad);
libGDR_ReadSector(GetMemPtr(0x8c008000, 0), base_fad, 16, 2048);
memset(reios_bootfile, 0, sizeof(reios_bootfile));
memcpy(reios_bootfile, GetMemPtr(0x8c008060, 0), 16);
printf("reios: bootfile is '%s'\n", reios_bootfile);
for (int i = 15; i >= 0; i--) {
if (reios_bootfile[i] != ' ')
break;
reios_bootfile[i] = 0;
return reios_product_number;
}
return reios_bootfile;
}
void reios_sys_system() {
debugf("reios_sys_system\n");

View File

@ -1,5 +1,7 @@
#include "types.h"
#ifndef REIOS_H
#define REIOS_H
#include "types.h"
bool reios_init(u8* rom, u8* flash);
@ -9,8 +11,10 @@ void reios_term();
void DYNACALL reios_trap(u32 op);
const char* reios_locate_ip(void);
bool reios_locate_bootfile(const char* bootfile);
char* reios_disk_id();
extern char reios_software_name[129];
extern char reios_product_number[11];
#define REIOS_OPCODE 0x085B
#endif //REIOS_H

View File

@ -1,3 +1,8 @@
#ifndef REIOS_ELF_H
#define REIOS_ELF_H
#include "types.h"
bool reios_loadElf(const string& elf);
#endif //REIOS_ELF_H

View File

@ -496,7 +496,7 @@ GLuint fogTextureId;
screen_width=w;
screen_height=h;
printf("EGL config: %08X, %08X, %08X %dx%d\n",gl.setup.context,gl.setup.display,gl.setup.surface,w,h);
printf("EGL config: %p, %08X, %08X %dx%d\n",gl.setup.context,gl.setup.display,gl.setup.surface,w,h);
return true;
}
@ -780,8 +780,6 @@ GLuint gl_CompileShader(const char* shader,GLuint type)
if (!result && compile_log_len>0)
{
if (compile_log_len==0)
compile_log_len=1;
char* compile_log=(char*)malloc(compile_log_len);
*compile_log=0;
@ -825,8 +823,6 @@ GLuint gl_CompileAndLink(const char* VertexShader, const char* FragmentShader)
if (!result && compile_log_len>0)
{
if (compile_log_len==0)
compile_log_len=1;
compile_log_len+= 1024;
char* compile_log=(char*)malloc(compile_log_len);
*compile_log=0;

View File

@ -1207,7 +1207,7 @@ struct softrend : Renderer
BitBlt(hdc, x, y, 640 , 480 , hmem, 0, 0, SRCCOPY);
ReleaseDC(hWnd, hdc);
#else
#elif defined(SUPPORT_X11)
extern Window x11_win;
extern Display* x11_disp;
extern Visual* x11_vis;
@ -1224,6 +1224,9 @@ struct softrend : Renderer
XPutImage(x11_disp, x11_win, gc, ximage, 0, 0, (x11_width - width)/2, (x11_height - height)/2, width, height);
XFree(ximage);
XFreeGC(x11_disp, gc);
#else
// TODO softrend without X11 (SDL f.e.)
#error Cannot use softrend without X11
#endif
}
};

View File

@ -120,7 +120,7 @@ void input_sdl_init()
void input_sdl_handle(u32 port)
{
static int keys[13];
#define SET_FLAG(field, mask, expr) field =((expr) ? (field & ~mask) : (field | mask))
static int mouse_use = 0;
SDL_Event event;
int k, value;
@ -131,30 +131,59 @@ void input_sdl_handle(u32 port)
switch (event.type)
{
case SDL_QUIT:
die("death by SDL request");
dc_stop();
break;
case SDL_KEYDOWN:
case SDL_KEYUP:
k = event.key.keysym.sym;
value = (event.type == SDL_KEYDOWN) ? 1 : 0;
//printf("type %i key %i \n", event.type, k);
printf("type %i key %i \n", event.type, k);
switch (k) {
//TODO: Better keymaps for non-pandora platforms
case SDLK_SPACE: keys[0] = value; break;
case SDLK_UP: keys[1] = value; break;
case SDLK_DOWN: keys[2] = value; break;
case SDLK_LEFT: keys[3] = value; break;
case SDLK_RIGHT: keys[4] = value; break;
case SDLK_PAGEUP: keys[5] = value; break;
case SDLK_PAGEDOWN: keys[6] = value; break;
case SDLK_END: keys[7] = value; break;
case SDLK_HOME: keys[8] = value; break;
case SDLK_SPACE:
SET_FLAG(kcode[port], DC_BTN_C, value);
break;
case SDLK_UP:
SET_FLAG(kcode[port], DC_DPAD_UP, value);
break;
case SDLK_DOWN:
SET_FLAG(kcode[port], DC_DPAD_DOWN, value);
break;
case SDLK_LEFT:
SET_FLAG(kcode[port], DC_DPAD_LEFT, value);
break;
case SDLK_RIGHT:
SET_FLAG(kcode[port], DC_DPAD_RIGHT, value);
break;
case SDLK_PAGEUP:
SET_FLAG(kcode[port], DC_BTN_Y, value);
break;
case SDLK_PAGEDOWN:
SET_FLAG(kcode[port], DC_BTN_A, value);
break;
case SDLK_END:
SET_FLAG(kcode[port], DC_BTN_B, value);
break;
case SDLK_HOME:
SET_FLAG(kcode[port], DC_BTN_X, value);
break;
case SDLK_MENU:
case SDLK_ESCAPE: keys[9] = value; break;
case SDLK_RSHIFT: keys[11] = value; break;
case SDLK_RCTRL: keys[10] = value; break;
case SDLK_LALT: keys[12] = value; break;
case SDLK_k: KillTex = true; break;
case SDLK_ESCAPE:
dc_stop();
break;
case SDLK_RSHIFT:
lt[port] = (value ? 255 : 0);
break;
case SDLK_RCTRL:
rt[port] = (value ? 255 : 0);;
break;
case SDLK_LALT:
SET_FLAG(kcode[port], DC_BTN_START, value);
break;
case SDLK_k:
SET_FLAG(kcode[port], DC_BTN_A, value);
break;
#if defined(TARGET_PANDORA)
case SDLK_n:
if (value)
@ -361,29 +390,6 @@ void input_sdl_handle(u32 port)
break;
}
}
if (keys[0]) { kcode[port] &= ~DC_BTN_C; }
if (keys[6]) { kcode[port] &= ~DC_BTN_A; }
if (keys[7]) { kcode[port] &= ~DC_BTN_B; }
if (keys[5]) { kcode[port] &= ~DC_BTN_Y; }
if (keys[8]) { kcode[port] &= ~DC_BTN_X; }
if (keys[1]) { kcode[port] &= ~DC_DPAD_UP; }
if (keys[2]) { kcode[port] &= ~DC_DPAD_DOWN; }
if (keys[3]) { kcode[port] &= ~DC_DPAD_LEFT; }
if (keys[4]) { kcode[port] &= ~DC_DPAD_RIGHT; }
if (keys[12]){ kcode[port] &= ~DC_BTN_START; }
if (keys[9])
{
dc_stop();
}
if (keys[10])
{
rt[port] = 255;
}
if (keys[11])
{
lt[port] = 255;
}
}
void sdl_window_set_text(const char* text)

View File

@ -635,8 +635,8 @@ struct settings_t
bool Enable;
bool idleskip;
bool unstable_opt;
bool safemode;
bool disable_nvmem;
bool DisableDivMatching;
} dynarec;
struct
@ -679,7 +679,7 @@ struct settings_t
{
u32 Width;
u32 Height;
bool Maintain_Aspect;
bool Keep_Aspect;
} dispmanx;
#endif
@ -726,7 +726,7 @@ struct settings_t
u32 rend;
u32 MaxThreads;
u32 SynchronousRendering;
u32 SynchronousRender;
string HashLogFile;
string HashCheckFile;
@ -750,6 +750,7 @@ struct settings_t
extern settings_t settings;
void LoadSettings();
void LoadCustom();
void SaveSettings();
u32 GetRTC_now();
extern u32 patchRB;

View File

@ -6,6 +6,7 @@
#include <windows.h>
#include <Xinput.h>
#include "hw\maple\maple_cfg.h"
#pragma comment(lib, "XInput9_1_0.lib")
PCHAR*
@ -109,6 +110,13 @@ bool ngen_Rewrite(unat& addr,unat retadr,unat acc);
bool BM_LockedWrite(u8* address);
void UpdateController(u32 port);
void os_SetupInput()
{
#if DC_PLATFORM == DC_PLATFORM_DREAMCAST
mcfg_CreateDevicesFromConfig();
#endif
}
LONG ExeptionHandler(EXCEPTION_POINTERS *ExceptionInfo)
{
EXCEPTION_POINTERS* ep = ExceptionInfo;

View File

@ -1,11 +1,20 @@
apply plugin: 'com.android.application'
apply plugin: 'com.github.triplet.play'
def getVersionCode = { ->
def getBuildId = { ->
def build_id = System.getenv("TRAVIS_JOB_ID") ?: "8"
return Integer.parseInt( build_id )
}
def getVersionHash = { ->
def stdout = new ByteArrayOutputStream()
exec {
commandLine 'git', 'rev-parse', '--short', 'HEAD'
standardOutput = stdout
}
return stdout.toString().trim()
}
def getVersionName = { ->
def stdout = new ByteArrayOutputStream()
exec {
@ -23,7 +32,7 @@ android {
applicationId "com.reicast.emulator"
minSdkVersion 16
targetSdkVersion 25
versionCode getVersionCode()
versionCode getBuildId()
versionName getVersionName()
vectorDrawables.useSupportLibrary = true
@ -45,8 +54,14 @@ android {
}
buildTypes {
debug {
debuggable true
zipAlignEnabled true
}
release {
debuggable false
minifyEnabled false
zipAlignEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
signingConfig signingConfigs.release
}
@ -66,14 +81,8 @@ android {
afterEvaluate {
android.applicationVariants.all { v ->
if (v.buildType.name == "release") {
def hashtag = new ByteArrayOutputStream()
exec {
commandLine "git", "rev-parse", "HEAD"
standardOutput = hashtag
}
hashtag = hashtag.toString().trim()
v.outputs[0].outputFileName = "reicast-android-" + hashtag.substring(0,7) + ".apk"
file('src/main/assets/build').text = hashtag
def hashtag = getVersionHash()
v.outputs[0].outputFileName = "reicast-android-" + hashtag + ".apk"
}
}
}

View File

@ -16,7 +16,6 @@
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_SERVICE" />
<uses-feature
android:glEsVersion="0x00020000"
@ -45,6 +44,8 @@
android:hardwareAccelerated="true"
android:isGame="true">
<meta-data android:name="android.max_aspect" android:value="2.1" />
<activity
android:name=".MainActivity"
android:configChanges="orientation|navigation|screenSize|screenLayout|uiMode|keyboard|keyboardHidden"
@ -122,6 +123,15 @@
android:configChanges="orientation|navigation|screenSize|screenLayout|uiMode|keyboard|keyboardHidden"
android:screenOrientation="sensorLandscape"
android:theme="@android:style/Theme.NoTitleBar.Fullscreen" />
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="${applicationId}.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths"/>
</provider>
</application>

View File

@ -4,13 +4,10 @@ import java.util.Calendar;
public class DreamTime {
private static long dreamRTC = ((20 * 365 + 5) * 86400) - 1;
public static long getDreamtime() {
long dreamRTC = ((20 * 365 + 5) * 86400) - 1;
Calendar cal = Calendar.getInstance();
int utcOffset = cal.get(Calendar.ZONE_OFFSET)
+ cal.get(Calendar.DST_OFFSET);
return (System.currentTimeMillis() / 1000) + dreamRTC
+ (utcOffset / 1000);
int utcOffset = cal.get(Calendar.ZONE_OFFSET) + cal.get(Calendar.DST_OFFSET);
return (System.currentTimeMillis() / 1000) + dreamRTC + (utcOffset / 1000);
}
}

View File

@ -9,7 +9,6 @@ import android.net.Uri;
import android.os.Environment;
import android.preference.PreferenceManager;
import com.reicast.emulator.MainActivity;
import com.reicast.emulator.config.Config;
import java.io.File;
@ -24,6 +23,7 @@ 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;
@ -63,15 +63,14 @@ public class FileUtils {
public Collection<File> listFiles(File directory, FilenameFilter[] filter,
int recurse) {
Vector<File> files = new Vector<File>();
Vector<File> files = new Vector<>();
File[] entries = directory.listFiles();
if (entries != null) {
for (File entry : entries) {
for (FilenameFilter filefilter : filter) {
if (filter == null
|| filefilter.accept(directory, entry.getName())) {
if (filefilter.accept(directory, entry.getName())) {
files.add(entry);
}
}
@ -90,7 +89,7 @@ public class FileUtils {
SharedPreferences mPrefs = PreferenceManager.getDefaultSharedPreferences(c);
File dir = new File(mPrefs.getString(Config.pref_home,
Environment.getExternalStorageDirectory().getAbsolutePath()));
SimpleDateFormat s = new SimpleDateFormat("yyyyMMddHHmmss");
SimpleDateFormat s = new SimpleDateFormat("yyyyMMddHHmmss", Locale.getDefault());
String timestamp = s.format(new Date());
File f = new File(dir.getAbsolutePath(), timestamp+".jpeg");
FileOutputStream out = new FileOutputStream(f);
@ -129,8 +128,6 @@ public class FileUtils {
bt[(h-k-1)*w+j]=pix1;
}
}
Bitmap sb=Bitmap.createBitmap(bt, w, h, Bitmap.Config.ARGB_8888);
return sb;
return Bitmap.createBitmap(bt, w, h, Bitmap.Config.ARGB_8888);
}
}

View File

@ -1,26 +1,19 @@
package com.reicast.emulator;
import android.annotation.TargetApi;
import android.content.pm.PackageManager.NameNotFoundException;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
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.text.util.Linkify;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ListView;
import android.widget.SlidingDrawer;
import android.widget.SlidingDrawer.OnDrawerOpenListener;
import android.widget.TextView;
import com.reicast.emulator.config.Config;
@ -34,6 +27,7 @@ import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.ref.WeakReference;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
@ -44,10 +38,6 @@ import javax.net.ssl.HttpsURLConnection;
public class AboutFragment extends Fragment {
String buildId = "";
SlidingDrawer slidingGithub;
private ListView list;
private GitAdapter adapter;
private Handler handler;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
@ -59,63 +49,36 @@ public class AboutFragment extends Fragment {
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
try {
InputStream file = getResources().getAssets().open("build");
if (file != null) {
BufferedReader reader = new BufferedReader(new InputStreamReader(file));
buildId = reader.readLine();
file.close();
}
} catch (IOException ioe) {
ioe.printStackTrace();
}
try {
String versionName = getActivity().getPackageManager()
.getPackageInfo(getActivity().getPackageName(), 0).versionName;
int versionCode = getActivity().getPackageManager()
.getPackageInfo(getActivity().getPackageName(), 0).versionCode;
TextView version = (TextView) getView().findViewById(R.id.revision_text);
String revision = getString(R.string.revision_text,
versionName, String.valueOf(versionCode));
if (!buildId.equals("")) {
revision = getActivity().getString(R.string.revision_text,
versionName, buildId.substring(0,7));
}
version.setText(revision);
version.setText(getString(R.string.revision_text,
versionName, String.valueOf(versionCode)));
int start = versionName.lastIndexOf("-");
buildId = versionName.substring(start + 2, start + 9);
} catch (NameNotFoundException e) {
e.printStackTrace();
}
TextView website = (TextView) getView().findViewById(
R.id.site_text);
Linkify.addLinks(website, Linkify.ALL);
handler = new Handler();
slidingGithub = (SlidingDrawer) getView().findViewById(
R.id.slidingGithub);
slidingGithub.setOnDrawerOpenListener(new OnDrawerOpenListener() {
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public void onDrawerOpened() {
new retrieveGitTask().execute(Config.git_api);
}
});
new retrieveGitTask(this).execute(Config.git_api);
}
public class retrieveGitTask extends
private static class retrieveGitTask extends
AsyncTask<String, Integer, ArrayList<HashMap<String, String>>> {
@Override
protected void onPreExecute() {
private WeakReference<AboutFragment> ref;
retrieveGitTask(AboutFragment context) {
ref = new WeakReference<>(context);
}
@Override
protected ArrayList<HashMap<String, String>> doInBackground(
String... paths) {
ArrayList<HashMap<String, String>> commitList = new ArrayList<HashMap<String, String>>();
ArrayList<HashMap<String, String>> commitList = new ArrayList<>();
try {
JSONArray gitObject = getContent(paths[0]);
for (int i = 0; i < gitObject.length(); i++) {
@ -128,7 +91,7 @@ public class AboutFragment extends Fragment {
String author = commitArray.getJSONObject("author").getString("name");
String committer = commitArray.getJSONObject("committer").getString("name");
String avatar = null;
String avatar;
if (!jsonObject.getString("committer").equals("null")) {
avatar = jsonObject.getJSONObject("committer").getString("avatar_url");
committer = committer + " (" + jsonObject
@ -148,7 +111,7 @@ public class AboutFragment extends Fragment {
.replace("https://api.github.com/repos", "https://github.com")
.replace("commits", "commit");
String title = "No commit heading attached";
String title;
String message = "No commit message attached";
if (commitArray.getString("message").contains("\n\n")) {
@ -160,7 +123,7 @@ public class AboutFragment extends Fragment {
title = commitArray.getString("message");
}
HashMap<String, String> map = new HashMap<String, String>();
HashMap<String, String> map = new HashMap<>();
map.put("Date", date);
map.put("Committer", committer);
map.put("Title", title);
@ -169,28 +132,15 @@ public class AboutFragment extends Fragment {
map.put("Url", curl);
map.put("Author", author);
map.put("Avatar", avatar);
map.put("Build", buildId);
map.put("Build", ref.get().buildId);
commitList.add(map);
}
} catch (JSONException e) {
handler.post(new Runnable() {
public void run() {
showToastMessage(getActivity().getString(R.string.git_broken), Snackbar.LENGTH_SHORT);
slidingGithub.close();
}
});
e.printStackTrace();
} catch (Exception e) {
handler.post(new Runnable() {
public void run() {
showToastMessage(getActivity().getString(R.string.git_broken), Snackbar.LENGTH_SHORT);
slidingGithub.close();
}
});
e.printStackTrace();
}
return commitList;
}
@ -198,19 +148,15 @@ public class AboutFragment extends Fragment {
protected void onPostExecute(
ArrayList<HashMap<String, String>> commitList) {
if (commitList != null && commitList.size() > 0) {
list = (ListView) getView().findViewById(R.id.list);
ListView list = (ListView) ref.get().getView().findViewById(R.id.list);
list.setSelector(R.drawable.list_selector);
list.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
adapter = new GitAdapter(getActivity(), commitList);
GitAdapter adapter = new GitAdapter(ref.get().getActivity(), commitList);
// Set adapter as specified collection
list.setAdapter(adapter);
list.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
slidingGithub.open();
}
});
} else {
ref.get().showToastMessage(ref.get().getActivity().getString(
R.string.git_broken), Snackbar.LENGTH_SHORT);
}
}

View File

@ -212,13 +212,9 @@ class DropBoxClient {
Editor edit = prefs.edit();
edit.putString("DBoxKey", key);
edit.putString("DBoxSecret", secret);
edit.commit();
edit.apply();
}
private AndroidAuthSession buildSession() {
AppKeyPair appKeyPair = new AppKeyPair(APP_KEY, APP_SECRET);
AndroidAuthSession session;

View File

@ -1,9 +1,8 @@
package com.reicast.emulator;
import android.app.Activity;
import android.app.Application;
import android.content.Context;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import android.support.v7.app.AppCompatDelegate;
import com.android.util.DreamTime;
@ -14,11 +13,13 @@ public class Emulator extends Application {
public static final String pref_nativeact = "enable_native";
public static final String pref_dynarecopt = "dynarec_opt";
public static final String pref_unstable = "unstable_opt";
public static final String pref_dynsafemode = "dyn_safemode";
public static final String pref_cable = "dc_cable";
public static final String pref_dcregion = "dc_region";
public static final String pref_broadcast = "dc_broadcast";
public static final String pref_limitfps = "limit_fps";
public static final String pref_nosound = "sound_disabled";
public static final String pref_interrupt = "delay_interrupt";
public static final String pref_mipmaps = "use_mipmaps";
public static final String pref_widescreen = "stretch_view";
public static final String pref_frameskip = "frame_skip";
@ -31,12 +32,14 @@ public class Emulator extends Application {
public static boolean dynarecopt = true;
public static boolean idleskip = true;
public static boolean unstableopt = false;
public static boolean dynsafemode = false;
public static int cable = 3;
public static int dcregion = 3;
public static int broadcast = 4;
public static boolean limitfps = true;
public static boolean nobatch = false;
public static boolean nosound = false;
public static boolean interrupt = false;
public static boolean mipmaps = true;
public static boolean widescreen = false;
public static boolean subdivide = false;
@ -44,7 +47,7 @@ public class Emulator extends Application {
public static boolean pvrrender = false;
public static boolean syncedrender = false;
public static boolean modvols = true;
public static String bootdisk = "null";
public static String bootdisk = null;
public static boolean usereios = false;
public static boolean nativeact = false;
@ -65,7 +68,6 @@ public class Emulator extends Application {
Emulator.frameskip = mPrefs.getInt(pref_frameskip, frameskip);
Emulator.pvrrender = mPrefs.getBoolean(pref_pvrrender, pvrrender);
Emulator.syncedrender = mPrefs.getBoolean(pref_syncedrender, syncedrender);
Emulator.modvols = mPrefs.getBoolean(pref_modvols, modvols);
Emulator.bootdisk = mPrefs.getString(pref_bootdisk, bootdisk);
Emulator.usereios = mPrefs.getBoolean(pref_usereios, usereios);
Emulator.nativeact = mPrefs.getBoolean(pref_nativeact, nativeact);
@ -79,12 +81,14 @@ public class Emulator extends Application {
JNIdc.dynarec(Emulator.dynarecopt ? 1 : 0);
JNIdc.idleskip(Emulator.idleskip ? 1 : 0);
JNIdc.unstable(Emulator.unstableopt ? 1 : 0);
JNIdc.safemode(Emulator.dynsafemode ? 1 : 0);
JNIdc.cable(Emulator.cable);
JNIdc.region(Emulator.dcregion);
JNIdc.broadcast(Emulator.broadcast);
JNIdc.limitfps(Emulator.limitfps ? 1 : 0);
JNIdc.nobatch(Emulator.nobatch ? 1 : 0);
JNIdc.nosound(Emulator.nosound ? 1 : 0);
JNIdc.delayinterrupt(Emulator.interrupt ? 1 : 0);
JNIdc.mipmaps(Emulator.mipmaps ? 1 : 0);
JNIdc.widescreen(Emulator.widescreen ? 1 : 0);
JNIdc.subdivide(Emulator.subdivide ? 1 : 0);
@ -97,6 +101,19 @@ public class Emulator extends Application {
JNIdc.dreamtime(DreamTime.getDreamtime());
}
public void loadGameConfiguration(String gameId) {
SharedPreferences mPrefs = getSharedPreferences(gameId, Activity.MODE_PRIVATE);
JNIdc.dynarec(mPrefs.getBoolean(pref_dynarecopt, dynarecopt) ? 1 : 0);
JNIdc.unstable(mPrefs.getBoolean(pref_unstable, unstableopt) ? 1 : 0);
JNIdc.safemode(mPrefs.getBoolean(pref_dynsafemode, dynsafemode) ? 1 : 0);
JNIdc.delayinterrupt(mPrefs.getBoolean(pref_interrupt, interrupt) ? 1 : 0);
JNIdc.frameskip(mPrefs.getInt(pref_frameskip, frameskip));
JNIdc.pvrrender(mPrefs.getBoolean(pref_pvrrender, pvrrender) ? 1 : 0);
JNIdc.syncedrender(mPrefs.getBoolean(pref_syncedrender, syncedrender) ? 1 : 0);
JNIdc.modvols(mPrefs.getBoolean(pref_modvols, modvols) ? 1 : 0);
JNIdc.bootdisk(mPrefs.getString(pref_bootdisk, bootdisk));
}
static {
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
}

View File

@ -16,6 +16,7 @@ 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.MotionEvent;
@ -57,7 +58,6 @@ public class FileBrowser extends Fragment {
private Vibrator vib;
private Drawable orig_bg;
private boolean ImgBrowse;
private boolean games;
private String searchQuery = null;
private OnItemSelectedListener mCallback;
@ -77,7 +77,6 @@ public class FileBrowser extends Fragment {
Bundle b = getArguments();
if (b != null) {
ImgBrowse = b.getBoolean("ImgBrowse", true);
if (games = b.getBoolean("games_entry", false)) {
if (b.getString("path_entry") != null) {
home_directory = b.getString("path_entry");
@ -94,7 +93,7 @@ public class FileBrowser extends Fragment {
}
public static HashSet<String> getExternalMounts() {
final HashSet<String> out = new HashSet<String>();
final HashSet<String> out = new HashSet<>();
String reg = "(?i).*vold.*(vfat|ntfs|exfat|fat32|ext3|ext4|fuse|sdfat).*rw.*";
StringBuilder s = new StringBuilder();
try {
@ -135,7 +134,7 @@ public class FileBrowser extends Fragment {
void onFolderSelected(Uri uri);
}
@Override
@Override @SuppressWarnings("deprecation")
public void onAttach(Activity activity) {
super.onAttach(activity);
@ -175,13 +174,12 @@ public class FileBrowser extends Fragment {
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);
} else {
installButtons();
}
if (!ImgBrowse && !games) {
new LocateGames(R.array.flash).execute(home_directory);
installButtons();
if (!games) {
new LocateGames(this, R.array.flash).execute(home_directory);
} else {
new LocateGames(R.array.images).execute(game_directory);
new LocateGames(this, R.array.images).execute(game_directory);
}
}
@ -219,11 +217,13 @@ public class FileBrowser extends Fragment {
}
}
private final class LocateGames extends AsyncTask<String, Integer, List<File>> {
private static final class LocateGames extends AsyncTask<String, Integer, List<File>> {
private WeakReference<FileBrowser> browser;
private int array;
public LocateGames(int arrayType) {
LocateGames(FileBrowser context, int arrayType) {
browser = new WeakReference<>(context);
this.array = arrayType;
}
@ -232,7 +232,7 @@ public class FileBrowser extends Fragment {
File storage = new File(paths[0]);
// array of valid image file extensions
String[] mediaTypes = getActivity().getResources().getStringArray(array);
String[] mediaTypes = browser.get().getActivity().getResources().getStringArray(array);
FilenameFilter[] filter = new FilenameFilter[mediaTypes.length];
int i = 0;
@ -240,18 +240,14 @@ public class FileBrowser extends Fragment {
filter[i] = new FilenameFilter() {
public boolean accept(File dir, String name) {
if (dir.getName().equals("obb") || dir.getName().equals("cache")
|| dir.getName().startsWith(".") || name.startsWith(".")) {
return false;
} else if (array == R.array.flash && !name.startsWith("dc_")) {
return false;
} else if (searchQuery == null || name.toLowerCase(Locale.getDefault())
.contains(searchQuery.toLowerCase(Locale.getDefault())))
return StringUtils.endsWithIgnoreCase(name, "." + type);
else
return false;
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++;
}
@ -268,19 +264,19 @@ public class FileBrowser extends Fragment {
@Override
protected void onPostExecute(List<File> items) {
if (items != null && !items.isEmpty()) {
LinearLayout list = (LinearLayout) getActivity().findViewById(R.id.game_list);
LinearLayout list = (LinearLayout) browser.get().getActivity().findViewById(R.id.game_list);
if (list.getChildCount() > 0) {
list.removeAllViews();
}
String heading = getActivity().getString(R.string.games_listing);
createListHeader(heading, list, array == R.array.images);
String heading = browser.get().getActivity().getString(R.string.games_listing);
browser.get().createListHeader(heading, list, array == R.array.images);
for (int i = 0; i < items.size(); i++) {
createListItem(list, items.get(i), i, array == R.array.images);
browser.get().createListItem(list, items.get(i), i, array == R.array.images);
}
list.invalidate();
} else {
browseStorage(array == R.array.images);
browser.get().browseStorage(array == R.array.images);
}
}
}
@ -293,8 +289,8 @@ public class FileBrowser extends Fragment {
if (game_directory.equals(sdcard.getAbsolutePath())) {
HashSet<String> extStorage = FileBrowser.getExternalMounts();
if (extStorage != null && !extStorage.isEmpty()) {
for (Iterator<String> sd = extStorage.iterator(); sd.hasNext();) {
String sdCardPath = sd.next().replace("mnt/media_rw", "storage");
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));
@ -314,8 +310,7 @@ public class FileBrowser extends Fragment {
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);
((TextView) childview.findViewById(R.id.item_name)).setText(R.string.boot_bios);
childview.setTag(null);
@ -324,10 +319,8 @@ public class FileBrowser extends Fragment {
childview.findViewById(R.id.childview).setOnClickListener(
new OnClickListener() {
public void onClick(View view) {
File f = (File) view.getTag();
vib.vibrate(50);
mCallback.onGameSelected(f != null ? Uri
.fromFile(f) : Uri.EMPTY);
mCallback.onGameSelected(Uri.EMPTY);
vib.vibrate(250);
}
});
@ -375,19 +368,34 @@ public class FileBrowser extends Fragment {
public void onClick(View view) {
if (isGame) {
vib.vibrate(50);
mCallback.onGameSelected(game != null ? Uri
.fromFile(game) : Uri.EMPTY);
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 (!DataDirectoryBIOS()) {
showToastMessage(getActivity().getString(R.string.config_data, home_directory),
Snackbar.LENGTH_LONG);
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();
mCallback.onFolderSelected(Uri.fromFile(new File(home_directory)));
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);
}
}
@ -417,7 +425,7 @@ public class FileBrowser extends Fragment {
private String heading;
private File parent;
public navigate(FileBrowser context) {
navigate(FileBrowser context) {
browser = new WeakReference<>(context);
}
@ -443,7 +451,7 @@ public class FileBrowser extends Fragment {
protected List<File> doInBackground(File... paths) {
heading = paths[0].getAbsolutePath();
ArrayList<File> list = new ArrayList<File>();
ArrayList<File> list = new ArrayList<>();
File flist[] = paths[0].listFiles();
parent = paths[0].getParentFile();
@ -482,7 +490,7 @@ public class FileBrowser extends Fragment {
((ImageView) childview.findViewById(R.id.item_icon)).setImageResource(file == null
? R.drawable.ic_settings: file.isDirectory()
? R.drawable.ic_folder_black_24dp : R.drawable.disk_unknown);;
? R.drawable.ic_folder_black_24dp : R.drawable.disk_unknown);
childview.setTag(file);
@ -507,21 +515,36 @@ public class FileBrowser extends Fragment {
browser.get().game_directory = heading;
browser.get().mPrefs.edit().putString(
Config.pref_games, heading).apply();
browser.get().mCallback.onFolderSelected(
Uri.fromFile(new File(browser.get().game_directory)));
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().home_directory = heading.replace("/data", "");
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().DataDirectoryBIOS()) {
browser.get().showToastMessage(
browser.get().getActivity().getString(
R.string.config_data,
browser.get().home_directory),
Snackbar.LENGTH_LONG);
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)));
}
browser.get().mCallback.onFolderSelected(
Uri.fromFile(new File(browser.get().home_directory)));
JNIdc.config(browser.get().home_directory);
}
@ -551,20 +574,21 @@ public class FileBrowser extends Fragment {
}
}
private boolean DataDirectoryBIOS() {
private boolean requireDataBIOS() {
File data_directory = new File(home_directory, "data");
if (!data_directory.exists() || !data_directory.isDirectory()) {
data_directory.mkdirs();
File bios = new File(home_directory, "dc_boot.bin");
if (bios.renameTo(new File(home_directory, "data/dc_boot.bin"))) {
File flash = new File(home_directory, "dc_flash.bin");
return flash.renameTo(new File(home_directory, "data/dc_flash.bin"));
}
return false;
} else {
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());
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;
}
}

View File

@ -1,8 +1,7 @@
package com.reicast.emulator;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.ActivityManager;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.net.Uri;
@ -28,7 +27,6 @@ import com.reicast.emulator.emu.OnScreenMenu.FpsPopup;
import com.reicast.emulator.emu.OnScreenMenu.MainPopup;
import com.reicast.emulator.emu.OnScreenMenu.VmuPopup;
import com.reicast.emulator.periph.Gamepad;
import com.reicast.emulator.periph.MOGAInput;
import com.reicast.emulator.periph.SipEmulator;
import java.util.Arrays;
@ -42,7 +40,6 @@ public class GL2JNIActivity extends Activity {
public MainPopup popUp;
VmuPopup vmuPop;
FpsPopup fpsPop;
MOGAInput moga = new MOGAInput();
private SharedPreferences prefs;
private Gamepad pad = new Gamepad();
@ -63,7 +60,7 @@ public class GL2JNIActivity extends Activity {
app.getConfigurationPrefs(prefs);
menu = new OnScreenMenu(GL2JNIActivity.this, prefs);
pad.isOuyaOrTV = pad.IsOuyaOrTV(GL2JNIActivity.this);
pad.isOuyaOrTV = pad.IsOuyaOrTV(GL2JNIActivity.this, false);
// pad.isNvidiaShield = pad.IsNvidiaShield();
/*
@ -76,13 +73,6 @@ public class GL2JNIActivity extends Activity {
* catch (IOException e) { e.getMessage(); e.printStackTrace(); }
*/
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
pad.compat[0] = true;
pad.compat[1] = true;
pad.compat[2] = true;
pad.compat[3] = true;
}
String fileName = null;
// Call parent onCreate()
@ -100,12 +90,25 @@ public class GL2JNIActivity extends Activity {
prefs.getString(Gamepad.pref_player4, null), 3);
pad.deviceDescriptor_PlayerNum.remove(null);
moga.onCreate(this, pad);
moga.mListener.setPlayerNum(1);
boolean controllerTwoConnected = false;
boolean controllerThreeConnected = false;
boolean controllerFourConnected = false;
boolean player2connected = false;
boolean player3connected = false;
boolean player4connected = false;
int p1periphs[] = {
1, // Hardcoded VMU
prefs.getBoolean(Gamepad.pref_mic, false) ? 2 : 1
};
int p2periphs[] = {
prefs.getInt(Gamepad.p2_peripheral + 1, 0),
prefs.getInt(Gamepad.p2_peripheral + 2, 0)
};
int p3periphs[] = {
prefs.getInt(Gamepad.p3_peripheral + 1, 0),
prefs.getInt(Gamepad.p3_peripheral + 2, 0)
};
int p4periphs[] = {
prefs.getInt(Gamepad.p4_peripheral + 1, 0),
prefs.getInt(Gamepad.p4_peripheral + 2, 0)
};
for (HashMap.Entry<String, Integer> e : pad.deviceDescriptor_PlayerNum.entrySet()) {
String descriptor = e.getKey();
@ -114,24 +117,25 @@ public class GL2JNIActivity extends Activity {
switch (playerNum) {
case 1:
if (descriptor != null)
controllerTwoConnected = true;
player2connected = true;
break;
case 2:
if (descriptor != null)
controllerThreeConnected = true;
player3connected = true;
break;
case 3:
if (descriptor != null)
controllerFourConnected = true;
player4connected = true;
break;
}
}
JNIdc.initControllers(new boolean[] { controllerTwoConnected,
controllerThreeConnected, controllerFourConnected });
JNIdc.initControllers(
new boolean[] { player2connected, player3connected, player4connected },
new int[][] { p1periphs, p2periphs, p3periphs, p4periphs });
int joys[] = InputDevice.getDeviceIds();
for (int joy: joys) {
String descriptor = null;
String descriptor;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
descriptor = InputDevice.getDevice(joy).getDescriptor();
} else {
@ -145,11 +149,13 @@ public class GL2JNIActivity extends Activity {
pad.deviceId_deviceDescriptor.put(joy, descriptor);
}
boolean detected = false;
for (int joy : joys) {
Integer playerNum = pad.deviceDescriptor_PlayerNum
.get(pad.deviceId_deviceDescriptor.get(joy));
if (playerNum != null) {
detected = true;
String id = pad.portId[playerNum];
pad.custom[playerNum] = prefs.getBoolean(Gamepad.pref_js_modified + id, false);
pad.compat[playerNum] = prefs.getBoolean(Gamepad.pref_js_compat + id, false);
@ -173,18 +179,19 @@ public class GL2JNIActivity extends Activity {
} else if (InputDevice.getDevice(joy).getName()
.contains(Gamepad.controllers_shield)) {
pad.map[playerNum] = pad.getConsoleController();
} else if (!pad.isActiveMoga[playerNum]) { // Ouya controller
} else if (InputDevice.getDevice(joy).getName()
.startsWith(Gamepad.controllers_moga)) {
pad.map[playerNum] = pad.getMogaController();
} else { // Ouya controller
pad.map[playerNum] = pad.getOUYAController();
}
} else {
pad.getCompatibilityMap(playerNum, id, prefs);
}
pad.initJoyStickLayout(playerNum);
} else {
pad.runCompatibilityMode(joy, prefs);
}
}
if (joys.length == 0) {
if (joys.length == 0 || !detected) {
pad.fullCompatibilityMode(prefs);
}
@ -200,7 +207,7 @@ public class GL2JNIActivity extends Activity {
setContentView(mView);
//setup mic
boolean micPluggedIn = prefs.getBoolean(Config.pref_mic, false);
boolean micPluggedIn = prefs.getBoolean(Gamepad.pref_mic, false);
if (micPluggedIn) {
SipEmulator sip = new SipEmulator();
sip.startRecording();
@ -232,185 +239,8 @@ public class GL2JNIActivity extends Activity {
}
}
@Override
public boolean onGenericMotionEvent(MotionEvent event) {
Integer playerNum = Arrays.asList(pad.name).indexOf(event.getDeviceId());
if (playerNum == -1) {
playerNum = pad.deviceDescriptor_PlayerNum
.get(pad.deviceId_deviceDescriptor.get(event.getDeviceId()));
} else {
playerNum = -1;
}
if (playerNum == null || playerNum == -1)
return false;
if (!pad.compat[playerNum]) {
// Joystick
if ((event.getSource() & InputDevice.SOURCE_CLASS_JOYSTICK) != 0) {
// do other things with joystick
float LS_X = event.getAxisValue(OuyaController.AXIS_LS_X);
float LS_Y = event.getAxisValue(OuyaController.AXIS_LS_Y);
float RS_X = event.getAxisValue(OuyaController.AXIS_RS_X);
float RS_Y = event.getAxisValue(OuyaController.AXIS_RS_Y);
float L2 = event.getAxisValue(OuyaController.AXIS_L2);
float R2 = event.getAxisValue(OuyaController.AXIS_R2);
if (!pad.joystick[playerNum]) {
pad.previousLS_X[playerNum] = pad.globalLS_X[playerNum];
pad.previousLS_Y[playerNum] = pad.globalLS_Y[playerNum];
pad.globalLS_X[playerNum] = LS_X;
pad.globalLS_Y[playerNum] = LS_Y;
}
GL2JNIView.jx[playerNum] = (int) (LS_X * 126);
GL2JNIView.jy[playerNum] = (int) (LS_Y * 126);
GL2JNIView.lt[playerNum] = (int) (L2 * 255);
GL2JNIView.rt[playerNum] = (int) (R2 * 255);
if (prefs.getBoolean(Gamepad.pref_js_rbuttons + pad.portId[playerNum], true)) {
if (RS_Y > 0.25) {
handle_key(playerNum, pad.map[playerNum][0]/* A */, true);
pad.wasKeyStick[playerNum] = true;
} else if (RS_Y < 0.25) {
handle_key(playerNum, pad.map[playerNum][1]/* B */, true);
pad.wasKeyStick[playerNum] = true;
} else if (pad.wasKeyStick[playerNum]){
handle_key(playerNum, pad.map[playerNum][0], false);
handle_key(playerNum, pad.map[playerNum][1], false);
pad.wasKeyStick[playerNum] = false;
}
} else {
if (RS_Y > 0.25) {
GL2JNIView.rt[playerNum] = (int) (RS_Y * 255);
GL2JNIView.lt[playerNum] = (int) (L2 * 255);
} else if (RS_Y < 0.25) {
GL2JNIView.rt[playerNum] = (int) (R2 * 255);
GL2JNIView.lt[playerNum] = (int) (-(RS_Y) * 255);
}
}
}
}
mView.pushInput();
// Only handle Left Stick on an Xbox 360 controller if there was
// some actual motion on the stick,
// so otherwise the event can be handled as a DPAD event
return (pad.joystick[playerNum] || (!(pad.globalLS_X[playerNum] == pad.previousLS_X[playerNum])
|| !(pad.globalLS_Y[playerNum] == pad.previousLS_Y[playerNum])))
&& (!(pad.previousLS_X[playerNum] == 0.0f) || !(pad.previousLS_Y[playerNum] == 0.0f));
}
public boolean motionEventHandler(Integer playerNum, com.bda.controller.MotionEvent event) {
if (playerNum == null || playerNum == -1)
return false;
if (!pad.compat[playerNum]) {
// do other things with joystick
float LS_X = event.getAxisValue(OuyaController.AXIS_LS_X);
float LS_Y = event.getAxisValue(OuyaController.AXIS_LS_Y);
float RS_X = event.getAxisValue(OuyaController.AXIS_RS_X);
float RS_Y = event.getAxisValue(OuyaController.AXIS_RS_Y);
float L2 = event.getAxisValue(OuyaController.AXIS_L2);
float R2 = event.getAxisValue(OuyaController.AXIS_R2);
if (!pad.joystick[playerNum]) {
pad.previousLS_X[playerNum] = pad.globalLS_X[playerNum];
pad.previousLS_Y[playerNum] = pad.globalLS_Y[playerNum];
pad.globalLS_X[playerNum] = LS_X;
pad.globalLS_Y[playerNum] = LS_Y;
}
GL2JNIView.jx[playerNum] = (int) (LS_X * 126);
GL2JNIView.jy[playerNum] = (int) (LS_Y * 126);
GL2JNIView.lt[playerNum] = (int) (L2 * 255);
GL2JNIView.rt[playerNum] = (int) (R2 * 255);
if (prefs.getBoolean(Gamepad.pref_js_rbuttons + pad.portId[playerNum], true)) {
if (RS_Y > 0.25) {
handle_key(playerNum, pad.map[playerNum][0]/* A */, true);
pad.wasKeyStick[playerNum] = true;
} else if (RS_Y < 0.25) {
handle_key(playerNum, pad.map[playerNum][1]/* B */, true);
pad.wasKeyStick[playerNum] = true;
} else if (pad.wasKeyStick[playerNum]){
handle_key(playerNum, pad.map[playerNum][0], false);
handle_key(playerNum, pad.map[playerNum][1], false);
pad.wasKeyStick[playerNum] = false;
}
} else {
if (RS_Y > 0.25) {
GL2JNIView.rt[playerNum] = (int) (RS_Y * 255);
GL2JNIView.lt[playerNum] = (int) (L2 * 255);
} else if (RS_Y < 0.25) {
GL2JNIView.rt[playerNum] = (int) (R2 * 255);
GL2JNIView.lt[playerNum] = (int) (-(RS_Y) * 255);
}
}
}
mView.pushInput();
// Only handle Left Stick on an Xbox 360 controller if there was
// some actual motion on the stick,
// so otherwise the event can be handled as a DPAD event
return (pad.joystick[playerNum] || (!(pad.globalLS_X[playerNum] == pad.previousLS_X[playerNum])
|| !(pad.globalLS_Y[playerNum] == pad.previousLS_Y[playerNum])))
&& (!(pad.previousLS_X[playerNum] == 0.0f) || !(pad.previousLS_Y[playerNum] == 0.0f));
}
public boolean simulatedTouchEvent(int playerNum, float L2, float R2) {
GL2JNIView.lt[playerNum] = (int) (L2 * 255);
GL2JNIView.rt[playerNum] = (int) (R2 * 255);
mView.pushInput();
return true;
}
public boolean handle_key(Integer playerNum, int kc, boolean down) {
if (playerNum == null || playerNum == -1)
return false;
if (kc == pad.getSelectButtonCode()) {
return false;
}
boolean rav = false;
for (int i = 0; i < pad.map[playerNum].length; i += 2) {
if (pad.map[playerNum][i + 0] == kc) {
if (down)
GL2JNIView.kcode_raw[playerNum] &= ~pad.map[playerNum][i + 1];
else
GL2JNIView.kcode_raw[playerNum] |= pad.map[playerNum][i + 1];
rav = true;
break;
}
}
mView.pushInput();
return rav;
}
public void displayPopUp(PopupWindow popUp) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
popUp.showAtLocation(mView, Gravity.BOTTOM, 0, 60);
} else {
popUp.showAtLocation(mView, Gravity.BOTTOM, 0, 0);
}
popUp.update(LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT);
}
public void displayDebug(PopupWindow popUpDebug) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
popUpDebug.showAtLocation(mView, Gravity.BOTTOM, 0, 60);
} else {
popUpDebug.showAtLocation(mView, Gravity.BOTTOM, 0, 0);
}
popUpDebug.update(LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT);
public Gamepad getPad() {
return pad;
}
public void displayFPS() {
@ -418,6 +248,7 @@ public class GL2JNIActivity extends Activity {
fpsPop.update(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
}
@SuppressLint("RtlHardcoded")
public void toggleVmu() {
boolean showFloating = !prefs.getBoolean(Config.pref_vmu, false);
if (showFloating) {
@ -440,6 +271,20 @@ public class GL2JNIActivity extends Activity {
prefs.edit().putBoolean(Config.pref_vmu, showFloating).apply();
}
public void screenGrab() {
mView.screenGrab();
}
public void displayPopUp(PopupWindow popUp) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
popUp.showAtLocation(mView, Gravity.BOTTOM, 0, 60);
} else {
popUp.showAtLocation(mView, Gravity.BOTTOM, 0, 0);
}
popUp.update(LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT);
}
public void displayConfig(PopupWindow popUpConfig) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
popUpConfig.showAtLocation(mView, Gravity.BOTTOM, 0, 60);
@ -450,6 +295,159 @@ public class GL2JNIActivity extends Activity {
LayoutParams.WRAP_CONTENT);
}
public void displayDebug(PopupWindow popUpDebug) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
popUpDebug.showAtLocation(mView, Gravity.BOTTOM, 0, 60);
} else {
popUpDebug.showAtLocation(mView, Gravity.BOTTOM, 0, 0);
}
popUpDebug.update(LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT);
}
private boolean showMenu() {
if (popUp != null) {
if (menu.dismissPopUps()) {
popUp.dismiss();
} else {
if (!popUp.isShowing()) {
displayPopUp(popUp);
} else {
popUp.dismiss();
}
}
}
return true;
}
float getAxisValues(MotionEvent event, int axis, int historyPos) {
return historyPos < 0 ? event.getAxisValue(axis) :
event.getHistoricalAxisValue(axis, historyPos);
}
private void processJoystickInput(MotionEvent event, Integer playerNum, int historyPos) {
float LS_X = getAxisValues(event, prefs.getInt(
Gamepad.pref_axis_x, MotionEvent.AXIS_X), historyPos);
float LS_Y = getAxisValues(event, prefs.getInt(
Gamepad.pref_axis_y, MotionEvent.AXIS_Y), historyPos);
float RS_X = getAxisValues(event, MotionEvent.AXIS_RX, historyPos);
float RS_Y = getAxisValues(event, MotionEvent.AXIS_RY, historyPos);
float L2 = getAxisValues(event, MotionEvent.AXIS_LTRIGGER, historyPos);
float R2 = getAxisValues(event, MotionEvent.AXIS_RTRIGGER, historyPos);
if (pad.IsOuyaOrTV(GL2JNIActivity.this, true)) {
LS_X = getAxisValues(event, prefs.getInt(Gamepad.pref_axis_x,
OuyaController.AXIS_LS_X), historyPos);
LS_Y = getAxisValues(event, prefs.getInt(Gamepad.pref_axis_y,
OuyaController.AXIS_LS_Y), historyPos);
RS_X = getAxisValues(event, OuyaController.AXIS_RS_X, historyPos);
RS_Y = getAxisValues(event, OuyaController.AXIS_RS_Y, historyPos);
L2 = getAxisValues(event, OuyaController.AXIS_L2, historyPos);
R2 = getAxisValues(event, OuyaController.AXIS_R2, historyPos);
}
if (!pad.joystick[playerNum]) {
pad.previousLS_X[playerNum] = pad.globalLS_X[playerNum];
pad.previousLS_Y[playerNum] = pad.globalLS_Y[playerNum];
pad.globalLS_X[playerNum] = LS_X;
pad.globalLS_Y[playerNum] = LS_Y;
}
GL2JNIView.jx[playerNum] = (int) (LS_X * 126);
GL2JNIView.jy[playerNum] = (int) (LS_Y * 126);
if (prefs.getInt(Gamepad.pref_js_rstick + pad.portId[playerNum], 0) == 1) {
float R2Sum = RS_Y > 0.25 ? RS_Y : R2;
GL2JNIView.rt[playerNum] = (int) (R2Sum * 255);
float L2Sum = RS_Y < -0.25 ? -(RS_Y) : L2;
GL2JNIView.lt[playerNum] = (int) (L2Sum * 255);
} else {
GL2JNIView.lt[playerNum] = (int) (L2 * 255);
GL2JNIView.rt[playerNum] = (int) (R2 * 255);
}
if (prefs.getInt(Gamepad.pref_js_rstick + pad.portId[playerNum], 0) == 2) {
if (RS_Y > 0.25) {
handle_key(playerNum, pad.map[playerNum][0]/* A */, true);
pad.wasKeyStick[playerNum] = true;
} else if (RS_Y < 0.25) {
handle_key(playerNum, pad.map[playerNum][1]/* B */, true);
pad.wasKeyStick[playerNum] = true;
} else if (pad.wasKeyStick[playerNum]) {
handle_key(playerNum, pad.map[playerNum][0], false);
handle_key(playerNum, pad.map[playerNum][1], false);
pad.wasKeyStick[playerNum] = false;
}
}
mView.pushInput();
}
@Override
public boolean onGenericMotionEvent(MotionEvent event) {
Integer playerNum = Arrays.asList(pad.name).indexOf(event.getDeviceId());
if (playerNum == -1) {
playerNum = pad.deviceDescriptor_PlayerNum
.get(pad.deviceId_deviceDescriptor.get(event.getDeviceId()));
} else {
playerNum = -1;
}
if (playerNum == null || playerNum == -1)
return false;
if (!pad.compat[playerNum]) {
if ((event.getSource() & InputDevice.SOURCE_JOYSTICK) ==
InputDevice.SOURCE_JOYSTICK &&
event.getAction() == MotionEvent.ACTION_MOVE) {
final int historySize = event.getHistorySize();
for (int i = 0; i < historySize; i++) {
processJoystickInput(event, playerNum, i);
}
processJoystickInput(event, playerNum, -1);
}
}
// Only handle Left Stick on an Xbox 360 controller if there was actual
// motion on the stick, otherwise event can be handled as a DPAD event
return (pad.joystick[playerNum] || (pad.globalLS_X[playerNum] != pad.previousLS_X[playerNum]
|| pad.globalLS_Y[playerNum] != pad.previousLS_Y[playerNum]))
&& (pad.previousLS_X[playerNum] != 0.0f || pad.previousLS_Y[playerNum] != 0.0f);
}
public boolean simulatedLTouchEvent(int playerNum, float L2) {
GL2JNIView.lt[playerNum] = (int) (L2 * 255);
mView.pushInput();
return true;
}
public boolean simulatedRTouchEvent(int playerNum, float R2) {
GL2JNIView.rt[playerNum] = (int) (R2 * 255);
mView.pushInput();
return true;
}
public boolean handle_key(Integer playerNum, int kc, boolean down) {
if (playerNum == null || playerNum == -1)
return false;
if (kc == pad.getSelectButtonCode()) {
return false;
}
boolean rav = false;
for (int i = 0; i < pad.map[playerNum].length; i += 2) {
if (pad.map[playerNum][i] == kc) {
if (down)
GL2JNIView.kcode_raw[playerNum] &= ~pad.map[playerNum][i + 1];
else
GL2JNIView.kcode_raw[playerNum] |= pad.map[playerNum][i + 1];
rav = true;
break;
}
}
mView.pushInput();
return rav;
}
public boolean onKeyUp(int keyCode, KeyEvent event) {
Integer playerNum = Arrays.asList(pad.name).indexOf(event.getDeviceId());
if (playerNum == -1) {
@ -462,17 +460,14 @@ public class GL2JNIActivity extends Activity {
if (playerNum != null && playerNum != -1) {
if (pad.compat[playerNum] || pad.custom[playerNum]) {
String id = pad.portId[playerNum];
if (keyCode == prefs.getInt(Gamepad.pref_button_l + id,
KeyEvent.KEYCODE_BUTTON_L1)
|| keyCode == prefs.getInt(Gamepad.pref_button_r + id,
KeyEvent.KEYCODE_BUTTON_R1)) {
return simulatedTouchEvent(playerNum, 0.0f, 0.0f);
}
if (keyCode == prefs.getInt(Gamepad.pref_button_l + id, KeyEvent.KEYCODE_BUTTON_L1))
return simulatedLTouchEvent(playerNum, 0.0f);
if (keyCode == prefs.getInt(Gamepad.pref_button_r + id, KeyEvent.KEYCODE_BUTTON_R1))
return simulatedRTouchEvent(playerNum, 0.0f);
}
}
return handle_key(playerNum, keyCode, false)
|| super.onKeyUp(keyCode, event);
return handle_key(playerNum, keyCode, false) || super.onKeyUp(keyCode, event);
}
public boolean onKeyDown(int keyCode, KeyEvent event) {
@ -488,10 +483,10 @@ public class GL2JNIActivity extends Activity {
if (pad.compat[playerNum] || pad.custom[playerNum]) {
String id = pad.portId[playerNum];
if (keyCode == prefs.getInt(Gamepad.pref_button_l + id, KeyEvent.KEYCODE_BUTTON_L1)) {
return simulatedTouchEvent(playerNum, 1.0f, 0.0f);
return simulatedLTouchEvent(playerNum, 1.0f);
}
if (keyCode == prefs.getInt(Gamepad.pref_button_r + id, KeyEvent.KEYCODE_BUTTON_R1)) {
return simulatedTouchEvent(playerNum, 0.0f, 1.0f);
return simulatedRTouchEvent(playerNum, 1.0f);
}
}
}
@ -516,51 +511,11 @@ public class GL2JNIActivity extends Activity {
return super.onKeyDown(keyCode, event);
}
public GL2JNIView getGameView() {
return mView;
}
public void screenGrab() {
mView.screenGrab();
}
private boolean showMenu() {
if (popUp != null) {
if (!menu.dismissPopUps()) {
if (!popUp.isShowing()) {
displayPopUp(popUp);
} else {
popUp.dismiss();
}
} else {
popUp.dismiss();
}
}
return true;
}
public boolean serviceRunning(Class<?> javaclass) {
ActivityManager manager = (ActivityManager)
getSystemService(Context.ACTIVITY_SERVICE);
try {
for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
if (javaclass.getName().equals(
service.service.getClassName())) {
return true;
}
}
} catch (NullPointerException e) {
e.printStackTrace();
}
return false;
}
@Override
protected void onPause() {
super.onPause();
mView.onPause();
JNIdc.pause();
moga.onPause();
}
@Override
@ -568,7 +523,6 @@ public class GL2JNIActivity extends Activity {
super.onDestroy();
mView.onDestroy();
JNIdc.destroy();
moga.onDestroy();
}
@Override
@ -580,6 +534,5 @@ public class GL2JNIActivity extends Activity {
protected void onResume() {
super.onResume();
mView.onResume();
moga.onResume();
}
}

View File

@ -1,5 +1,6 @@
package com.reicast.emulator;
import android.annotation.SuppressLint;
import android.app.NativeActivity;
import android.content.SharedPreferences;
import android.content.res.Configuration;
@ -28,7 +29,6 @@ import com.reicast.emulator.emu.OnScreenMenu.FpsPopup;
import com.reicast.emulator.emu.OnScreenMenu.MainPopup;
import com.reicast.emulator.emu.OnScreenMenu.VmuPopup;
import com.reicast.emulator.periph.Gamepad;
import com.reicast.emulator.periph.MOGAInput;
import com.reicast.emulator.periph.SipEmulator;
import java.util.Arrays;
@ -42,7 +42,6 @@ public class GL2JNINative extends NativeActivity {
public MainPopup popUp;
VmuPopup vmuPop;
FpsPopup fpsPop;
MOGAInput moga = new MOGAInput();
private SharedPreferences prefs;
private Gamepad pad = new Gamepad();
@ -66,7 +65,7 @@ public class GL2JNINative extends NativeActivity {
}
getWindow().takeSurface(null);
pad.isOuyaOrTV = pad.IsOuyaOrTV(GL2JNINative.this);
pad.isOuyaOrTV = pad.IsOuyaOrTV(GL2JNINative.this, false);
// isNvidiaShield = Gamepad.IsNvidiaShield();
RegisterNative(false);
@ -75,13 +74,6 @@ public class GL2JNINative extends NativeActivity {
app.getConfigurationPrefs(prefs);
menu = new OnScreenMenu(GL2JNINative.this, prefs);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
pad.compat[0] = true;
pad.compat[1] = true;
pad.compat[2] = true;
pad.compat[3] = true;
}
String fileName = null;
// Call parent onCreate()
@ -99,12 +91,25 @@ public class GL2JNINative extends NativeActivity {
prefs.getString(Gamepad.pref_player4, null), 3);
pad.deviceDescriptor_PlayerNum.remove(null);
moga.onCreate(this, pad);
moga.mListener.setPlayerNum(1);
boolean controllerTwoConnected = false;
boolean controllerThreeConnected = false;
boolean controllerFourConnected = false;
boolean player2connected = false;
boolean player3connected = false;
boolean player4connected = false;
int p1periphs[] = {
1, // Hardcoded VMU
prefs.getBoolean(Gamepad.pref_mic, false) ? 2 : 1
};
int p2periphs[] = {
prefs.getInt(Gamepad.p2_peripheral + 1, 0),
prefs.getInt(Gamepad.p2_peripheral + 2, 0)
};
int p3periphs[] = {
prefs.getInt(Gamepad.p3_peripheral + 1, 0),
prefs.getInt(Gamepad.p3_peripheral + 2, 0)
};
int p4periphs[] = {
prefs.getInt(Gamepad.p4_peripheral + 1, 0),
prefs.getInt(Gamepad.p4_peripheral + 2, 0)
};
for (HashMap.Entry<String, Integer> e : pad.deviceDescriptor_PlayerNum
.entrySet()) {
@ -114,49 +119,47 @@ public class GL2JNINative extends NativeActivity {
switch (playerNum) {
case 1:
if (descriptor != null)
controllerTwoConnected = true;
player2connected = true;
break;
case 2:
if (descriptor != null)
controllerThreeConnected = true;
player3connected = true;
break;
case 3:
if (descriptor != null)
controllerFourConnected = true;
player4connected = true;
break;
}
}
JNIdc.initControllers(new boolean[] { controllerTwoConnected,
controllerThreeConnected, controllerFourConnected });
JNIdc.initControllers(
new boolean[] { player2connected, player3connected, player4connected },
new int[][] { p1periphs, p2periphs, p3periphs, p4periphs });
int joys[] = InputDevice.getDeviceIds();
for (int joy : joys) {
String descriptor = descriptor = InputDevice.getDevice(joy).getDescriptor();
String descriptor = InputDevice.getDevice(joy).getDescriptor();
Log.d("reicast", "InputDevice ID: " + joy);
Log.d("reicast", "InputDevice Name: " + InputDevice.getDevice(joy).getName());
Log.d("reicast", "InputDevice Descriptor: " + descriptor);
pad.deviceId_deviceDescriptor.put(joy, descriptor);
}
boolean detected = false;
for (int joy : joys) {
Integer playerNum = pad.deviceDescriptor_PlayerNum
.get(pad.deviceId_deviceDescriptor.get(joy));
if (playerNum != null) {
detected = true;
String id = pad.portId[playerNum];
pad.custom[playerNum] = prefs.getBoolean(Gamepad.pref_js_modified + id, false);
pad.compat[playerNum] = prefs.getBoolean(Gamepad.pref_js_compat + id, false);
pad.joystick[playerNum] = prefs.getBoolean(Gamepad.pref_js_merged + id, false);
if (InputDevice.getDevice(joy).getName()
.contains(Gamepad.controllers_gamekey)) {
// if (pad.custom[playerNum]) {
// setCustomMapping(id, playerNum);
// } else {
// pad.map[playerNum] = pad.getConsoleController();
// }
if (InputDevice.getDevice(joy).getName().contains(Gamepad.controllers_gamekey)) {
new Handler().post(new Runnable() {
public void run() {
Toast.makeText(getApplicationContext(), R.string.controller_unavailable,
Toast.makeText(getApplicationContext(),
R.string.controller_unavailable,
Toast.LENGTH_SHORT).show();
finish();
}
@ -173,7 +176,10 @@ public class GL2JNINative extends NativeActivity {
} else if (InputDevice.getDevice(joy).getName()
.contains(Gamepad.controllers_shield)) {
pad.map[playerNum] = pad.getConsoleController();
} else if (!pad.isActiveMoga[playerNum]) { // Ouya controller
} else if (InputDevice.getDevice(joy).getName()
.startsWith(Gamepad.controllers_moga)) {
pad.map[playerNum] = pad.getMogaController();
} else { // Ouya controller
pad.map[playerNum] = pad.getOUYAController();
}
} else{
@ -181,10 +187,11 @@ public class GL2JNINative extends NativeActivity {
}
pad.initJoyStickLayout(playerNum);
pad.playerNumX.put(joy, playerNum);
} else {
pad.runCompatibilityMode(joy, prefs);
}
}
if (joys.length == 0 || !detected) {
pad.fullCompatibilityMode(prefs);
}
app.loadConfigurationPrefs();
@ -193,12 +200,12 @@ public class GL2JNINative extends NativeActivity {
fileName = Uri.decode(getIntent().getData().toString());
// Create the actual GLES view
mView = new GL2JNIView(getApplication(), fileName, false,
mView = new GL2JNIView(GL2JNINative.this, fileName, false,
prefs.getInt(Config.pref_renderdepth, 24), 8, false);
setContentView(mView);
//setup mic
boolean micPluggedIn = prefs.getBoolean(Config.pref_mic, false);
boolean micPluggedIn = prefs.getBoolean(Gamepad.pref_mic, false);
if(micPluggedIn){
SipEmulator sip = new SipEmulator();
sip.startRecording();
@ -230,33 +237,11 @@ public class GL2JNINative extends NativeActivity {
}
}
public boolean simulatedTouchEvent(int playerNum, float L2, float R2) {
GL2JNIView.lt[playerNum] = (int) (L2 * 255);
GL2JNIView.rt[playerNum] = (int) (R2 * 255);
mView.pushInput();
return true;
}
public void displayPopUp(PopupWindow popUp) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
popUp.showAtLocation(mView, Gravity.BOTTOM, 0, 60);
} else {
popUp.showAtLocation(mView, Gravity.BOTTOM, 0, 0);
}
popUp.update(LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT);
}
public void displayDebug(PopupWindow popUpDebug) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
popUpDebug.showAtLocation(mView, Gravity.BOTTOM, 0, 60);
} else {
popUpDebug.showAtLocation(mView, Gravity.BOTTOM, 0, 0);
}
popUpDebug.update(LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT);
public Gamepad getPad() {
return pad;
}
@SuppressLint("RtlHardcoded")
public void displayFPS() {
fpsPop.showAtLocation(mView, Gravity.TOP | Gravity.LEFT, 20, 20);
fpsPop.update(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
@ -284,6 +269,20 @@ public class GL2JNINative extends NativeActivity {
prefs.edit().putBoolean(Config.pref_vmu, showFloating).apply();
}
public void screenGrab() {
mView.screenGrab();
}
public void displayPopUp(PopupWindow popUp) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
popUp.showAtLocation(mView, Gravity.BOTTOM, 0, 60);
} else {
popUp.showAtLocation(mView, Gravity.BOTTOM, 0, 0);
}
popUp.update(LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT);
}
public void displayConfig(PopupWindow popUpConfig) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
popUpConfig.showAtLocation(mView, Gravity.BOTTOM, 0, 60);
@ -294,19 +293,56 @@ public class GL2JNINative extends NativeActivity {
LayoutParams.WRAP_CONTENT);
}
public boolean motionEventHandler(Integer playerNum, com.bda.controller.MotionEvent event) {
if (playerNum == null || playerNum == -1)
return false;
public void displayDebug(PopupWindow popUpDebug) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
popUpDebug.showAtLocation(mView, Gravity.BOTTOM, 0, 60);
} else {
popUpDebug.showAtLocation(mView, Gravity.BOTTOM, 0, 0);
}
popUpDebug.update(LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT);
}
if (!pad.compat[playerNum]) {
private boolean showMenu() {
if (popUp != null) {
if (menu.dismissPopUps()) {
popUp.dismiss();
} else {
if (!popUp.isShowing()) {
displayPopUp(popUp);
} else {
popUp.dismiss();
}
}
}
return true;
}
// do other things with joystick
float LS_X = event.getAxisValue(OuyaController.AXIS_LS_X);
float LS_Y = event.getAxisValue(OuyaController.AXIS_LS_Y);
float RS_X = event.getAxisValue(OuyaController.AXIS_RS_X);
float RS_Y = event.getAxisValue(OuyaController.AXIS_RS_Y);
float L2 = event.getAxisValue(OuyaController.AXIS_L2);
float R2 = event.getAxisValue(OuyaController.AXIS_R2);
float getAxisValues(MotionEvent event, int axis, int historyPos) {
return historyPos < 0 ? event.getAxisValue(axis) :
event.getHistoricalAxisValue(axis, historyPos);
}
private void processJoystickInput(MotionEvent event, Integer playerNum, int historyPos) {
float LS_X = getAxisValues(event, prefs.getInt(
Gamepad.pref_axis_x, MotionEvent.AXIS_X), historyPos);
float LS_Y = getAxisValues(event, prefs.getInt(
Gamepad.pref_axis_y, MotionEvent.AXIS_Y), historyPos);
float RS_X = getAxisValues(event, MotionEvent.AXIS_RX, historyPos);
float RS_Y = getAxisValues(event, MotionEvent.AXIS_RY, historyPos);
float L2 = getAxisValues(event, MotionEvent.AXIS_LTRIGGER, historyPos);
float R2 = getAxisValues(event, MotionEvent.AXIS_RTRIGGER, historyPos);
if (pad.IsOuyaOrTV(GL2JNINative.this, true)) {
LS_X = getAxisValues(event, prefs.getInt(Gamepad.pref_axis_x,
OuyaController.AXIS_LS_X), historyPos);
LS_Y = getAxisValues(event, prefs.getInt(Gamepad.pref_axis_y,
OuyaController.AXIS_LS_Y), historyPos);
RS_X = getAxisValues(event, OuyaController.AXIS_RS_X, historyPos);
RS_Y = getAxisValues(event, OuyaController.AXIS_RS_Y, historyPos);
L2 = getAxisValues(event, OuyaController.AXIS_L2, historyPos);
R2 = getAxisValues(event, OuyaController.AXIS_R2, historyPos);
}
if (!pad.joystick[playerNum]) {
pad.previousLS_X[playerNum] = pad.globalLS_X[playerNum];
@ -318,10 +354,16 @@ public class GL2JNINative extends NativeActivity {
GL2JNIView.jx[playerNum] = (int) (LS_X * 126);
GL2JNIView.jy[playerNum] = (int) (LS_Y * 126);
if (prefs.getInt(Gamepad.pref_js_rstick + pad.portId[playerNum], 0) == 1) {
float R2Sum = R2 > 0.25 ? R2 : RS_Y;
GL2JNIView.rt[playerNum] = (int) (R2Sum * 255);
float L2Sum = L2 > 0.25 ? L2 : -(RS_Y);
GL2JNIView.lt[playerNum] = (int) (L2Sum * 255);
} else {
GL2JNIView.lt[playerNum] = (int) (L2 * 255);
GL2JNIView.rt[playerNum] = (int) (R2 * 255);
if (prefs.getBoolean(Gamepad.pref_js_rbuttons + pad.portId[playerNum], true)) {
}
if (prefs.getInt(Gamepad.pref_js_rstick + pad.portId[playerNum], 0) == 2) {
if (RS_Y > 0.25) {
handle_key(playerNum, pad.map[playerNum][0]/* A */, true);
pad.wasKeyStick[playerNum] = true;
@ -333,24 +375,9 @@ public class GL2JNINative extends NativeActivity {
handle_key(playerNum, pad.map[playerNum][1], false);
pad.wasKeyStick[playerNum] = false;
}
} else {
if (RS_Y > 0.25) {
GL2JNIView.rt[playerNum] = (int) (RS_Y * 255);
GL2JNIView.lt[playerNum] = (int) (L2 * 255);
} else if (RS_Y < 0.25) {
GL2JNIView.rt[playerNum] = (int) (R2 * 255);
GL2JNIView.lt[playerNum] = (int) (-(RS_Y) * 255);
}
}
}
mView.pushInput();
// Only handle Left Stick on an Xbox 360 controller if there was
// some actual motion on the stick,
// so otherwise the event can be handled as a DPAD event
return (pad.joystick[playerNum] || (!(pad.globalLS_X[playerNum] == pad.previousLS_X[playerNum])
|| !(pad.globalLS_Y[playerNum] == pad.previousLS_Y[playerNum])))
&& (!(pad.previousLS_X[playerNum] == 0.0f) || !(pad.previousLS_Y[playerNum] == 0.0f));
}
@Override
@ -371,66 +398,33 @@ public class GL2JNINative extends NativeActivity {
return false;
}
if (!pad.compat[playerNum]) {
// Joystick
if ((event.getSource() & InputDevice.SOURCE_CLASS_JOYSTICK) != 0) {
// do other things with joystick
float LS_X = event.getAxisValue(OuyaController.AXIS_LS_X);
float LS_Y = event.getAxisValue(OuyaController.AXIS_LS_Y);
float RS_X = event.getAxisValue(OuyaController.AXIS_RS_X);
float RS_Y = event.getAxisValue(OuyaController.AXIS_RS_Y);
float L2 = event.getAxisValue(OuyaController.AXIS_L2);
float R2 = event.getAxisValue(OuyaController.AXIS_R2);
if (!pad.joystick[playerNum]) {
pad.previousLS_X[playerNum] = pad.globalLS_X[playerNum];
pad.previousLS_Y[playerNum] = pad.globalLS_Y[playerNum];
pad.globalLS_X[playerNum] = LS_X;
pad.globalLS_Y[playerNum] = LS_Y;
if ((event.getSource() & InputDevice.SOURCE_JOYSTICK) ==
InputDevice.SOURCE_JOYSTICK &&
event.getAction() == MotionEvent.ACTION_MOVE) {
final int historySize = event.getHistorySize();
for (int i = 0; i < historySize; i++) {
processJoystickInput(event, playerNum, i);
}
GL2JNIView.jx[playerNum] = (int) (LS_X * 126);
GL2JNIView.jy[playerNum] = (int) (LS_Y * 126);
GL2JNIView.lt[playerNum] = (int) (L2 * 255);
GL2JNIView.rt[playerNum] = (int) (R2 * 255);
if (prefs.getBoolean(Gamepad.pref_js_rbuttons + pad.portId[playerNum], true)) {
if (RS_Y > 0.25) {
handle_key(playerNum, pad.map[playerNum][0]/* A */, true);
pad.wasKeyStick[playerNum] = true;
} else if (RS_Y < 0.25) {
handle_key(playerNum, pad.map[playerNum][1]/* B */, true);
pad.wasKeyStick[playerNum] = true;
} else if (pad.wasKeyStick[playerNum]){
handle_key(playerNum, pad.map[playerNum][0], false);
handle_key(playerNum, pad.map[playerNum][1], false);
pad.wasKeyStick[playerNum] = false;
}
} else {
if (RS_Y > 0.25) {
GL2JNIView.rt[playerNum] = (int) (RS_Y * 255);
GL2JNIView.lt[playerNum] = (int) (L2 * 255);
} else if (RS_Y < 0.25) {
GL2JNIView.rt[playerNum] = (int) (R2 * 255);
GL2JNIView.lt[playerNum] = (int) (-(RS_Y) * 255);
processJoystickInput(event, playerNum, -1);
}
}
return (pad.joystick[playerNum] || (pad.globalLS_X[playerNum] != pad.previousLS_X[playerNum]
|| pad.globalLS_Y[playerNum] != pad.previousLS_Y[playerNum]))
&& (pad.previousLS_X[playerNum] != 0.0f || pad.previousLS_Y[playerNum] != 0.0f);
}
}
mView.pushInput();
if (!pad.joystick[playerNum] && (pad.globalLS_X[playerNum] == pad.previousLS_X[playerNum] && pad.globalLS_Y[playerNum] == pad.previousLS_Y[playerNum])
|| (pad.previousLS_X[playerNum] == 0.0f && pad.previousLS_Y[playerNum] == 0.0f))
// Only handle Left Stick on an Xbox 360 controller if there was
// some actual motion on the stick,
// so otherwise the event can be handled as a DPAD event
return false;
else
}
public boolean simulatedLTouchEvent(int playerNum, float L2) {
GL2JNIView.lt[playerNum] = (int) (L2 * 255);
mView.pushInput();
return true;
}
return false;
public boolean simulatedRTouchEvent(int playerNum, float R2) {
GL2JNIView.rt[playerNum] = (int) (R2 * 255);
mView.pushInput();
return true;
}
public boolean handle_key(Integer playerNum, int kc, boolean down) {
@ -439,13 +433,10 @@ public class GL2JNINative extends NativeActivity {
if (kc == pad.getSelectButtonCode()) {
return false;
}
if (pad.isActiveMoga[playerNum]) {
return false;
}
boolean rav = false;
for (int i = 0; i < pad.map[playerNum].length; i += 2) {
if (pad.map[playerNum][i + 0] == kc) {
if (pad.map[playerNum][i] == kc) {
if (down)
GL2JNIView.kcode_raw[playerNum] &= ~pad.map[playerNum][i + 1];
else
@ -483,39 +474,35 @@ public class GL2JNINative extends NativeActivity {
public boolean OnNativeKeyPress(int device, int keyCode, int action, int metaState) {
Integer playerNum = pad.playerNumX.get(device);
if (playerNum != null && playerNum != -1) {
if (playerNum != -1) {
String id = pad.portId[playerNum];
if (action == KeyEvent.ACTION_DOWN) {
if (keyCode == prefs.getInt(Gamepad.pref_button_l + id, KeyEvent.KEYCODE_BUTTON_L1)) {
return simulatedTouchEvent(playerNum, 1.0f, 0.0f);
} else if (keyCode == prefs.getInt(Gamepad.pref_button_r + id, KeyEvent.KEYCODE_BUTTON_R1)) {
return simulatedTouchEvent(playerNum, 0.0f, 1.0f);
} else if (handle_key(playerNum, keyCode, true)) {
if (keyCode == prefs.getInt(Gamepad.pref_button_l + id, KeyEvent.KEYCODE_BUTTON_L1))
return simulatedLTouchEvent(playerNum, 1.0f);
if (keyCode == prefs.getInt(Gamepad.pref_button_r + id, KeyEvent.KEYCODE_BUTTON_R1))
return simulatedRTouchEvent(playerNum, 1.0f);
if (handle_key(playerNum, keyCode, true)) {
if (playerNum == 0)
JNIdc.hide_osd();
return true;
}
}
if (action == KeyEvent.ACTION_UP) {
if (keyCode == prefs.getInt(Gamepad.pref_button_l + id,
KeyEvent.KEYCODE_BUTTON_L1)
|| keyCode == prefs.getInt(Gamepad.pref_button_r + id,
KeyEvent.KEYCODE_BUTTON_R1)) {
return simulatedTouchEvent(playerNum, 0.0f, 0.0f);
} else {
if (keyCode == prefs.getInt(Gamepad.pref_button_l + id, KeyEvent.KEYCODE_BUTTON_L1))
return simulatedLTouchEvent(playerNum, 0.0f);
if (keyCode == prefs.getInt(Gamepad.pref_button_r + id, KeyEvent.KEYCODE_BUTTON_R1))
return simulatedRTouchEvent(playerNum, 0.0f);
return handle_key(playerNum, keyCode, false);
}
}
}
return false;
}
// public boolean OnNativeMotion(int device, int source, int action, int x,
// int y, boolean newEvent) {
public boolean OnNativeMotion(int device, int source, int action, int x,
int y) {
public boolean OnNativeMotion(int device, int source, int action, int x, int y) {
Integer playerNum = pad.playerNumX.get(device);
if (playerNum != null && playerNum != -1) {
if (playerNum != -1) {
Log.d("reicast", playerNum + " - " + device + ": " + source);
// if (newEvent && source == Gamepad.Xperia_Touchpad) {
if (source == Gamepad.Xperia_Touchpad) {
@ -538,8 +525,8 @@ public class GL2JNINative extends NativeActivity {
// The y-axis is inverted from normal layout
// Imagine it as a small MacBook touch mouse
GL2JNIView.jx[playerNum] = (int) (x * 126);
GL2JNIView.jy[playerNum] = (int) (y * 126);
GL2JNIView.jx[playerNum] = x * 126;
GL2JNIView.jy[playerNum] = y * 126;
mView.pushInput();
return true;
}
@ -547,35 +534,11 @@ public class GL2JNINative extends NativeActivity {
return false;
}
public GL2JNIView getGameView() {
return mView;
}
public void screenGrab() {
mView.screenGrab();
}
private boolean showMenu() {
if (popUp != null) {
if (!menu.dismissPopUps()) {
if (!popUp.isShowing()) {
displayPopUp(popUp);
} else {
popUp.dismiss();
}
} else {
popUp.dismiss();
}
}
return true;
}
@Override
protected void onPause() {
super.onPause();
mView.onPause();
JNIdc.pause();
moga.onPause();
}
@Override
@ -583,7 +546,6 @@ public class GL2JNINative extends NativeActivity {
super.onDestroy();
mView.onDestroy();
JNIdc.destroy();
moga.onDestroy();
}
@Override
@ -595,6 +557,5 @@ public class GL2JNINative extends NativeActivity {
protected void onResume() {
super.onResume();
mView.onResume();
moga.onResume();
}
}

View File

@ -2,6 +2,7 @@ package com.reicast.emulator;
import android.Manifest;
import android.app.AlertDialog;
import android.app.UiModeManager;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
@ -13,13 +14,12 @@ import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.preference.PreferenceManager;
import android.support.annotation.NonNull;
import android.support.constraint.ConstraintLayout;
import android.support.design.widget.NavigationView;
import android.support.design.widget.Snackbar;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.AppCompatActivity;
@ -35,28 +35,24 @@ import android.view.WindowManager;
import android.widget.TextView;
import com.reicast.emulator.config.Config;
import com.reicast.emulator.config.EditVJoyActivity;
import com.reicast.emulator.config.InputFragment;
import com.reicast.emulator.config.OptionsFragment;
import com.reicast.emulator.config.PGConfigFragment;
import com.reicast.emulator.debug.GenerateLogs;
import com.reicast.emulator.emu.JNIdc;
import com.reicast.emulator.periph.Gamepad;
import java.io.File;
import java.lang.Thread.UncaughtExceptionHandler;
import java.util.List;
public class MainActivity extends AppCompatActivity implements
FileBrowser.OnItemSelectedListener, OptionsFragment.OnClickListener,
NavigationView.OnNavigationItemSelectedListener {
NavigationView.OnNavigationItemSelectedListener, FileBrowser.OnItemSelectedListener,
OptionsFragment.OnClickListener, InputFragment.OnClickListener {
private static final int PERMISSION_REQUEST = 1001;
private SharedPreferences mPrefs;
private boolean hasAndroidMarket = false;
private UncaughtExceptionHandler mUEHandler;
Gamepad pad = new Gamepad();
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@ -67,7 +63,6 @@ public class MainActivity extends AppCompatActivity implements
public void onSystemUiVisibilityChange(int visibility) {
if ((visibility & View.SYSTEM_UI_FLAG_FULLSCREEN) == 0) {
getWindow().getDecorView().setSystemUiVisibility(
// View.SYSTEM_UI_FLAG_LAYOUT_STABLE |
View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
@ -88,12 +83,13 @@ public class MainActivity extends AppCompatActivity implements
displayLogOutput(prior_error);
mPrefs.edit().remove("prior_error").apply();
} else {
mUEHandler = new Thread.UncaughtExceptionHandler() {
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() + "\n");
output.append(trace.toString());
output.append("\n");
}
mPrefs.edit().putString("prior_error", output.toString()).apply();
error.printStackTrace();
@ -138,7 +134,7 @@ public class MainActivity extends AppCompatActivity implements
// Check that the activity is using the layout version with
// the fragment_container FrameLayout
if (findViewById(R.id.fragment_container) != null) {
onMainBrowseSelected(true, null, false, null);
onMainBrowseSelected(null, true, null);
}
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
@ -156,6 +152,7 @@ public class MainActivity extends AppCompatActivity implements
}
};
//noinspection deprecation
drawer.setDrawerListener(toggle);
toggle.syncState();
@ -164,6 +161,15 @@ public class MainActivity extends AppCompatActivity implements
navigationView.getMenu().findItem(R.id.rateme_menu).setEnabled(false);
navigationView.getMenu().findItem(R.id.rateme_menu).setVisible(false);
}
try {
UiModeManager uiModeManager = (UiModeManager) getSystemService(UI_MODE_SERVICE);
if (uiModeManager.getCurrentModeType() == Configuration.UI_MODE_TYPE_TELEVISION) {
View header = navigationView.getHeaderView(0);
((TextView) header.findViewById(R.id.project_link)).setVisibility(View.GONE);
}
} catch (Exception e) {
// They require a check, so they can fix their API
}
navigationView.setNavigationItemSelectedListener(this);
final SearchView searchView = (SearchView) findViewById(R.id.searchView);
@ -172,7 +178,7 @@ public class MainActivity extends AppCompatActivity implements
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
onMainBrowseSelected(true, mPrefs.getString(Config.pref_games,
onMainBrowseSelected(mPrefs.getString(Config.pref_games,
Environment.getExternalStorageDirectory().getAbsolutePath()),
true, query);
searchView.onActionViewCollapsed();
@ -216,65 +222,44 @@ public class MainActivity extends AppCompatActivity implements
builder.show();
}
public static boolean isBiosExisting(String home_directory) {
return new File (home_directory, "data/dc_boot.bin").exists();
}
public static boolean isFlashExisting(String home_directory) {
return new File (home_directory, "data/dc_flash.bin").exists();
}
public void onGameSelected(Uri uri) {
if (Config.readOutput("uname -a").equals(getString(R.string.error_kernel))) {
showToastMessage(getString(R.string.unsupported), Snackbar.LENGTH_SHORT);
}
public void onEditorSelected(Uri uri) {
String home_directory = mPrefs.getString(Config.pref_home,
Environment.getExternalStorageDirectory().getAbsolutePath());
if (!isBiosExisting(home_directory)) {
launchBIOSdetection();
return;
}
if (!isFlashExisting(home_directory)) {
launchBIOSdetection();
return;
JNIdc.config(home_directory);
startActivity(new Intent("com.reicast.EMULATOR", uri,
getApplicationContext(), EditVJoyActivity.class));
}
public void onGameSelected(Uri uri) {
String home_directory = mPrefs.getString(Config.pref_home,
Environment.getExternalStorageDirectory().getAbsolutePath());
JNIdc.config(home_directory);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
uri = Uri.parse(uri.toString().replace("content://"
+ uri.getAuthority() + "/external_files", "/storage"));
}
Emulator.nativeact = PreferenceManager.getDefaultSharedPreferences(
getApplicationContext()).getBoolean(Emulator.pref_nativeact, Emulator.nativeact);
if (Emulator.nativeact) {
startActivity(new Intent("com.reicast.EMULATOR", uri, getApplicationContext(),
GL2JNINative.class));
Intent intent = new Intent("com.reicast.EMULATOR",
uri, getApplicationContext(), GL2JNINative.class);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
startActivity(intent);
} else {
startActivity(new Intent("com.reicast.EMULATOR", uri, getApplicationContext(),
GL2JNIActivity.class));
Intent intent = new Intent("com.reicast.EMULATOR",
uri, getApplicationContext(), GL2JNIActivity.class);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
startActivity(intent);
}
}
private void launchBIOSdetection() {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(R.string.bios_selection);
builder.setPositiveButton(R.string.browse,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
String home_directory = mPrefs.getString(Config.pref_home,
Environment.getExternalStorageDirectory().getAbsolutePath());
onMainBrowseSelected(false, home_directory, false, null);
}
});
builder.setNegativeButton(R.string.gdrive,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
showToastMessage(getString(R.string.require_bios),
Snackbar.LENGTH_SHORT);
}
});
builder.create();
builder.show();
}
public void onFolderSelected(Uri uri) {
FileBrowser browserFrag = (FileBrowser) getSupportFragmentManager()
.findFragmentByTag("MAIN_BROWSER");
@ -289,14 +274,11 @@ public class MainActivity extends AppCompatActivity implements
getSupportFragmentManager().beginTransaction().replace(
R.id.fragment_container, optsFrag, "OPTIONS_FRAG").commit();
setTitle(R.string.settings);
return;
}
/**
* Launch the browser activity with specified parameters
*
* @param browse
* Conditional for image files or folders
* @param path
* The root path of the browser fragment
* @param games
@ -304,12 +286,9 @@ public class MainActivity extends AppCompatActivity implements
* @param query
* Search parameters to limit list items
*/
public void onMainBrowseSelected(boolean browse, String path, boolean games, String query) {
public void onMainBrowseSelected(String path, boolean games, String query) {
FileBrowser firstFragment = new FileBrowser();
Bundle args = new Bundle();
// args.putBoolean("ImgBrowse", false);
args.putBoolean("ImgBrowse", browse);
// specify ImgBrowse option. true = images, false = folders only
args.putString("browse_entry", path);
// specify a path for selecting folder options
args.putBoolean("games_entry", games);
@ -329,6 +308,28 @@ public class MainActivity extends AppCompatActivity implements
setTitle(R.string.browser);
}
public void launchBIOSdetection() {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(R.string.bios_selection);
builder.setPositiveButton(R.string.browse,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
String home_directory = mPrefs.getString(Config.pref_home,
Environment.getExternalStorageDirectory().getAbsolutePath());
onMainBrowseSelected(home_directory, false, null);
}
});
builder.setNegativeButton(R.string.gdrive,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
showToastMessage(getString(R.string.require_bios),
Snackbar.LENGTH_SHORT);
}
});
builder.create();
builder.show();
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
@ -337,13 +338,12 @@ public class MainActivity extends AppCompatActivity implements
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
Fragment fragment = (FileBrowser) getSupportFragmentManager()
.findFragmentByTag("MAIN_BROWSER");
Fragment fragment = getSupportFragmentManager().findFragmentByTag("MAIN_BROWSER");
if (fragment != null && fragment.isVisible()) {
boolean readyToQuit = true;
if (fragment.getArguments() != null) {
readyToQuit = fragment.getArguments().getBoolean(
"ImgBrowse", true);
"games_entry", true);
}
if (readyToQuit) {
MainActivity.this.finish();
@ -362,53 +362,22 @@ public class MainActivity extends AppCompatActivity implements
}
private void launchMainFragment() {
onMainBrowseSelected(true, null, false, null);
}
public void onSettingsReload(Fragment options) {
getSupportFragmentManager().beginTransaction().remove(options).commit();
OptionsFragment optionsFrag = new OptionsFragment();
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.fragment_container, optionsFrag, "OPTIONS_FRAG")
.addToBackStack(null).commit();
onMainBrowseSelected(null, true, null);
}
@Override
protected void onPause() {
super.onPause();
InputFragment fragment = (InputFragment) getSupportFragmentManager()
.findFragmentByTag("INPUT_FRAG");
if (fragment != null && fragment.isVisible()) {
if (fragment.moga != null) {
fragment.moga.onPause();
}
}
}
@Override
protected void onDestroy() {
InputFragment fragment = (InputFragment) getSupportFragmentManager()
.findFragmentByTag("INPUT_FRAG");
if (fragment != null && fragment.isVisible()) {
if (fragment.moga != null) {
fragment.moga.onDestroy();
}
}
super.onDestroy();
}
@Override
protected void onResume() {
super.onResume();
InputFragment fragment = (InputFragment) getSupportFragmentManager()
.findFragmentByTag("INPUT_FRAG");
if (fragment != null && fragment.isVisible()) {
if (fragment.moga != null) {
fragment.moga.onResume();
}
}
CloudFragment cloudfragment = (CloudFragment) getSupportFragmentManager()
.findFragmentByTag("CLOUD_FRAG");
if (cloudfragment != null && cloudfragment.isVisible()) {
@ -421,9 +390,8 @@ public class MainActivity extends AppCompatActivity implements
super.onPostCreate(savedInstanceState);
}
@SuppressWarnings("StatementWithEmptyBody")
@Override
public boolean onNavigationItemSelected(MenuItem item) {
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
// Handle navigation view item clicks here.
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
@ -440,10 +408,9 @@ public class MainActivity extends AppCompatActivity implements
}
browseFrag = new FileBrowser();
Bundle args = new Bundle();
args.putBoolean("ImgBrowse", true);
args.putString("browse_entry", null);
// specify a path for selecting folder options
args.putBoolean("games_entry", false);
args.putBoolean("games_entry", true);
// specify if the desired path is for games or data
browseFrag.setArguments(args);
getSupportFragmentManager()
@ -472,6 +439,24 @@ public class MainActivity extends AppCompatActivity implements
drawer.closeDrawer(GravityCompat.START);
return true;
case R.id.pgconfig_menu:
PGConfigFragment pgconfigFrag = (PGConfigFragment) getSupportFragmentManager()
.findFragmentByTag("PGCONFIG_FRAG");
if (pgconfigFrag != null) {
if (pgconfigFrag.isVisible()) {
drawer.closeDrawer(GravityCompat.START);
return true;
}
}
pgconfigFrag = new PGConfigFragment();
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.fragment_container, pgconfigFrag, "PGCONFIG_FRAG")
.addToBackStack(null).commit();
setTitle(R.string.pgconfig);
drawer.closeDrawer(GravityCompat.START);
return true;
case R.id.input_menu:
InputFragment inputFrag = (InputFragment) getSupportFragmentManager()
.findFragmentByTag("INPUT_FRAG");

View File

@ -2,7 +2,6 @@ package com.reicast.emulator;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
@ -10,10 +9,8 @@ import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Vibrator;
import android.view.View;
import android.view.View.OnLongClickListener;
import android.widget.ImageView;
@ -22,7 +19,7 @@ import android.widget.TextView;
import com.reicast.emulator.FileBrowser.OnItemSelectedListener;
import com.reicast.emulator.config.Config;
import org.json.JSONArray;
import org.apache.commons.io.FilenameUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
@ -32,7 +29,6 @@ import org.xml.sax.SAXException;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
@ -41,6 +37,7 @@ 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;
@ -56,42 +53,39 @@ public class XMLParser extends AsyncTask<String, Integer, String> {
private SharedPreferences mPrefs;
private File game;
private int index;
private View childview;
private OnItemSelectedListener mCallback;
private Context mContext;
private String game_name;
private Bitmap coverart;
private Drawable game_icon;
private String gameId;
private String game_details;
private String game_index = "http://thegamesdb.net/api/GetGamesList.php?platform=sega+dreamcast&name=";
private String game_id = "http://thegamesdb.net/api/GetGame.php?platform=sega+dreamcast&id=";
private WeakReference<Context> mContext;
private WeakReference<View> childview;
public XMLParser(File game, int index, SharedPreferences mPrefs) {
XMLParser(File game, int index, SharedPreferences mPrefs) {
this.mPrefs = mPrefs;
this.game = game;
this.index = index;
}
public void setViewParent(Context mContext, View childview, OnItemSelectedListener mCallback) {
this.mContext = mContext;
this.childview = childview;
public void setViewParent(Context reference, View childview, OnItemSelectedListener mCallback) {
this.mContext = new WeakReference<>(reference);
this.childview = new WeakReference<>(childview);
this.mCallback = mCallback;
initializeDefaults();
}
public void setGameID(String id) {
private void setGameID(String id) {
this.gameId = id;
initializeDefaults();
}
@Override
protected String doInBackground(String... params) {
String filename = game_name = params[0];
if (isNetworkAvailable() && mPrefs.getBoolean(Config.pref_gamedetails, false)) {
String xmlUrl = "";
String xmlUrl;
if (gameId != null) {
xmlUrl = game_id + gameId;
xmlUrl = "http://legacy.thegamesdb.net/api/GetGame.php?platform=sega+dreamcast&id=" + gameId;
} else {
filename = filename.substring(0, filename.lastIndexOf("."));
try {
@ -99,7 +93,7 @@ public class XMLParser extends AsyncTask<String, Integer, String> {
} catch (UnsupportedEncodingException e) {
filename = filename.replace(" ", "+");
}
xmlUrl = game_index + filename;
xmlUrl = "http://legacy.thegamesdb.net/api/GetGamesList.php?platform=sega+dreamcast&name=" + filename;
}
try {
@ -119,9 +113,9 @@ public class XMLParser extends AsyncTask<String, Integer, String> {
in.close();
return responseStrBuilder.toString();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
@ -136,13 +130,43 @@ public class XMLParser extends AsyncTask<String, Integer, String> {
Element root = (Element) doc.getElementsByTagName("Game").item(0);
if (gameId == null) {
XMLParser xmlParser = new XMLParser(game, index, mPrefs);
xmlParser.setViewParent(mContext, childview, mCallback);
xmlParser.setViewParent(mContext.get(), childview.get(), mCallback);
xmlParser.setGameID(getValue(root, "id"));
xmlParser.execute(game_name);
} else {
game_name = getValue(root, "GameTitle");
} 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");
Element images = (Element) root.getElementsByTagName("Images").item(0);
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);
@ -150,74 +174,57 @@ public class XMLParser extends AsyncTask<String, Integer, String> {
boxart = (Element) images.getElementsByTagName("boxart").item(0);
}
if (boxart != null) {
(new decodeBitmapIcon()).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR,
"http://thegamesdb.net/banners/" + getElementValue(boxart));
game_icon = new BitmapDrawable(coverart);
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);
}
}
}
} catch (Exception e) {
}
}
((TextView) childview.findViewById(R.id.item_name)).setText(game_name);
if (Build.VERSION.SDK_INT < 21) {
((ImageView) childview.findViewById(R.id.item_icon)).setImageDrawable(game_icon);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
game_icon = new BitmapDrawable(
mContext.get().getResources(), gameImage);
} else {
((ImageView) childview.findViewById(R.id.item_icon)).setImageBitmap(coverart);
//noinspection deprecation
game_icon = new BitmapDrawable(gameImage);
}
((ImageView) childview.get().findViewById(
R.id.item_icon)).setImageDrawable(game_icon);
}
if (mPrefs.getBoolean(Config.pref_gamedetails, false)) {
childview.findViewById(R.id.childview).setOnLongClickListener(
new OnLongClickListener() {
public boolean onLongClick(View view) {
final AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
builder.setCancelable(true);
builder.setTitle(mContext.getString(R.string.game_details, game_name));
builder.setMessage(game_details);
builder.setIcon(game_icon);
builder.setNegativeButton("Close",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
return;
}
});
builder.setPositiveButton("Launch",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
mCallback.onGameSelected(game != null ? Uri.fromFile(game) : Uri.EMPTY);
((Vibrator) mContext.getSystemService(Context.VIBRATOR_SERVICE)).vibrate(250);
return;
icon.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR,
"https://cdn.thegamesdb.net/images/thumb/"
+ getElementValue(boxart)
.replace("original/", ""));
}
});
builder.create().show();
return true;
}
});
}
childview.setTag(game_name);
}
private void initializeDefaults() {
game_details = mContext.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.getResources().getDrawable(
game.isDirectory() ? R.drawable.open_folder : nameLower
.endsWith(".gdi") ? R.drawable.gdi : nameLower
.endsWith(".chd") ? R.drawable.chd
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) childview.get().findViewById(R.id.item_icon)).setImageDrawable(game_icon);
}
public boolean isNetworkAvailable() {
ConnectivityManager connectivityManager = (ConnectivityManager) mContext
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);
@ -229,23 +236,7 @@ public class XMLParser extends AsyncTask<String, Integer, String> {
}
}
public Drawable getGameIcon() {
return game_icon;
}
public Bitmap getGameCover() {
return coverart;
}
public String getGameTitle() {
return game_name;
}
public String getGameDetails() {
return game_details;
}
public Document getDomElement(String xml) {
private Document getDomElement(String xml) {
Document doc = null;
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
try {
@ -270,12 +261,16 @@ public class XMLParser extends AsyncTask<String, Integer, String> {
return doc;
}
public String getValue(Element item, String str) {
private String getValue(Element item, String str) {
if (item != null) {
NodeList n = item.getElementsByTagName(str);
return this.getElementValue(n.item(0));
} else {
return "";
}
}
public final String getElementValue(Node elem) {
private String getElementValue(Node elem) {
Node child;
if (elem != null) {
if (elem.hasChildNodes()) {
@ -290,12 +285,21 @@ public class XMLParser extends AsyncTask<String, Integer, String> {
return "";
}
private class decodeBitmapIcon extends AsyncTask<String, Integer, Bitmap> {
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.getExternalFilesDir(null) + "/images", index + ".png");
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 {
@ -305,7 +309,7 @@ public class XMLParser extends AsyncTask<String, Integer, String> {
BufferedInputStream bis = new BufferedInputStream(im, 512);
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
Bitmap bitmap = BitmapFactory.decodeStream(bis, null, options);
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) {
@ -321,12 +325,10 @@ public class XMLParser extends AsyncTask<String, Integer, String> {
conn1 = updateURL.openConnection();
im = conn1.getInputStream();
bis = new BufferedInputStream(im, 512);
bitmap = BitmapFactory.decodeStream(bis, null, options);
Bitmap bitmap = BitmapFactory.decodeStream(bis, null, options);
bis.close();
im.close();
bis = null;
im = null;
OutputStream fOut = null;
OutputStream fOut;
if (!file.getParentFile().exists()) {
file.getParentFile().mkdir();
}
@ -348,8 +350,18 @@ public class XMLParser extends AsyncTask<String, Integer, String> {
@Override
protected void onPostExecute(Bitmap gameImage) {
coverart = gameImage;
game_icon = new BitmapDrawable(gameImage);
super.onPostExecute(gameImage);
if (listener != null) {
listener.onDecodeBitmapIconFinished(gameImage);
}
}
void setListener(decodeBitmapIconListener listener) {
this.listener = listener;
}
public interface decodeBitmapIconListener {
void onDecodeBitmapIconFinished(Bitmap gameImage);
}
}
}

View File

@ -19,9 +19,10 @@ public class Config {
public static final String pref_touchvibe = "touch_vibration_enabled";
public static final String pref_vibrationDuration = "vibration_duration";
public static final String game_title = "game_title";
public static int vibrationDuration = 20;
public static final String pref_mic = "mic_plugged_in";
public static final String pref_vmu = "vmu_floating";
public static String git_api = "https://api.github.com/repos/reicast/reicast-emulator/commits";

View File

@ -4,6 +4,7 @@ import android.app.Activity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.preference.PreferenceManager;
@ -18,7 +19,6 @@ import android.widget.ImageView.ScaleType;
import android.widget.LinearLayout;
import android.widget.PopupWindow;
import com.reicast.emulator.Emulator;
import com.reicast.emulator.MainActivity;
import com.reicast.emulator.R;
import com.reicast.emulator.emu.GL2JNIView;
@ -49,16 +49,21 @@ public class EditVJoyActivity extends Activity {
popUp = createVJoyPopup();
String fileName = null;
// Call parent onCreate()
super.onCreate(icicle);
SharedPreferences prefs = PreferenceManager
.getDefaultSharedPreferences(this);
Emulator app = (Emulator)getApplicationContext();
app.getConfigurationPrefs(prefs);
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
JNIdc.initControllers(new boolean[] { false, false, false },
new int[][] { {1, 1}, {0, 0}, {0, 0}, {0, 0} });
if (getIntent().getAction().equals("com.reicast.EMULATOR"))
fileName = Uri.decode(getIntent().getData().toString());
// Create the actual GLES view
mView = new GL2JNIView(EditVJoyActivity.this, null, false,
mView = new GL2JNIView(EditVJoyActivity.this, fileName, false,
prefs.getInt(Config.pref_renderdepth, 24), 0, true);
mView.setFpsDisplay(null);
setContentView(mView);

View File

@ -1,19 +1,20 @@
package com.reicast.emulator.config;
import android.Manifest;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
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;
import android.os.Handler;
import android.os.Vibrator;
import android.preference.PreferenceManager;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.InputDevice;
@ -21,40 +22,67 @@ import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.SeekBar;
import android.widget.TableLayout;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;
import com.bda.controller.Controller;
import com.bda.controller.ControllerListener;
import com.bda.controller.MotionEvent;
import com.bda.controller.StateEvent;
import com.reicast.emulator.MainActivity;
import com.reicast.emulator.Emulator;
import com.reicast.emulator.R;
import com.reicast.emulator.periph.Gamepad;
import com.reicast.emulator.periph.MOGAInput;
import java.io.File;
public class InputFragment extends Fragment {
private static final int PERMISSION_REQUEST = 1001;
private OnClickListener mCallback;
private int listenForButton = 0;
private AlertDialog alertDialogSelectController;
private SharedPreferences sharedPreferences;
private SharedPreferences mPrefs;
private CompoundButton switchTouchVibrationEnabled;
private CompoundButton micPluggedIntoFirstController;
private Gamepad pad = new Gamepad();
public MOGAInput moga = new MOGAInput();
Vibrator vib;
// Container Activity must implement this interface
public interface OnClickListener {
void onMainBrowseSelected(String path_entry, boolean games);
void onEditorSelected(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 = (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
@ -66,15 +94,12 @@ public class InputFragment extends Fragment {
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
moga.onCreate(getActivity(), pad);
moga.mListener.setPlayerNum(1);
mPrefs = PreferenceManager.getDefaultSharedPreferences(getActivity());
sharedPreferences = PreferenceManager
.getDefaultSharedPreferences(getActivity());
Config.vibrationDuration = sharedPreferences.getInt(Config.pref_vibrationDuration, 20);
Config.vibrationDuration = mPrefs.getInt(Config.pref_vibrationDuration, 20);
vib = (Vibrator) getActivity().getSystemService(Context.VIBRATOR_SERVICE);
try {
ImageView icon_a = (ImageView) getView().findViewById(
R.id.controller_icon_a);
icon_a.setAlpha(0.8f);
@ -87,28 +112,24 @@ public class InputFragment extends Fragment {
ImageView icon_d = (ImageView) getView().findViewById(
R.id.controller_icon_d);
icon_d.setAlpha(0.8f);
} catch (NullPointerException ex) {
// Couldn't find images, so leave them opaque
}
Button buttonLaunchEditor = (Button) getView().findViewById(
R.id.buttonLaunchEditor);
Button buttonLaunchEditor = (Button) getView().findViewById(R.id.buttonLaunchEditor);
buttonLaunchEditor.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Intent inte = new Intent(getActivity(), EditVJoyActivity.class);
startActivity(inte);
mCallback.onEditorSelected(Uri.EMPTY);
}
});
SharedPreferences mPrefs = PreferenceManager.getDefaultSharedPreferences(getActivity());
String home_directory = mPrefs.getString(Config.pref_home,
Environment.getExternalStorageDirectory().getAbsolutePath());
if (!MainActivity.isBiosExisting(home_directory) || !MainActivity.isFlashExisting(home_directory))
buttonLaunchEditor.setEnabled(false);
buttonLaunchEditor.setEnabled(isBIOSAvailable());
final TextView duration = (TextView) getView().findViewById(R.id.vibDuration_current);
final LinearLayout vibLay = (LinearLayout) getView().findViewById(R.id.vibDuration_layout);
final SeekBar vibSeek = (SeekBar) getView().findViewById(R.id.vib_seekBar);
if (sharedPreferences.getBoolean(Config.pref_touchvibe, true)) {
if (mPrefs.getBoolean(Config.pref_touchvibe, true)) {
vibLay.setVisibility(View.VISIBLE);
} else {
vibLay.setVisibility(View.GONE);
@ -123,12 +144,12 @@ public class InputFragment extends Fragment {
}
public void onStartTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}
public void onStopTrackingTouch(SeekBar seekBar) {
int progress = seekBar.getProgress() + 5;
sharedPreferences.edit().putInt(Config.pref_vibrationDuration, progress).apply();
mPrefs.edit().putInt(Config.pref_vibrationDuration, progress).apply();
Config.vibrationDuration = progress;
vib.vibrate(progress);
}
@ -137,14 +158,13 @@ public class InputFragment extends Fragment {
OnCheckedChangeListener touch_vibration = new OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
sharedPreferences.edit()
.putBoolean(Config.pref_touchvibe, isChecked).apply();
mPrefs.edit().putBoolean(Config.pref_touchvibe, isChecked).apply();
vibLay.setVisibility( isChecked ? View.VISIBLE : View.GONE );
}
};
switchTouchVibrationEnabled = (CompoundButton) getView().findViewById(
R.id.switchTouchVibrationEnabled);
boolean vibrate = sharedPreferences.getBoolean(Config.pref_touchvibe, true);
boolean vibrate = mPrefs.getBoolean(Config.pref_touchvibe, true);
if (vibrate) {
switchTouchVibrationEnabled.setChecked(true);
} else {
@ -152,23 +172,26 @@ public class InputFragment extends Fragment {
}
switchTouchVibrationEnabled.setOnCheckedChangeListener(touch_vibration);
micPluggedIntoFirstController = (CompoundButton) getView().findViewById(
R.id.micInPort2);
boolean micPluggedIn = sharedPreferences.getBoolean(Config.pref_mic,
false);
micPluggedIntoFirstController.setChecked(micPluggedIn);
if (getActivity().getPackageManager().hasSystemFeature(
PackageManager.FEATURE_MICROPHONE)) {
CompoundButton micPluggedIntoController = (CompoundButton) getView().findViewById(R.id.micEnabled);
boolean micPluggedIn = mPrefs.getBoolean(Gamepad.pref_mic, false);
micPluggedIntoController.setChecked(micPluggedIn);
if (getActivity().getPackageManager().hasSystemFeature(PackageManager.FEATURE_MICROPHONE)) {
// Microphone is present on the device
micPluggedIntoFirstController
micPluggedIntoController
.setOnCheckedChangeListener(new OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
sharedPreferences.edit().putBoolean(Config.pref_mic, isChecked).apply();
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
mPrefs.edit().putBoolean(Gamepad.pref_mic, isChecked).apply();
if (isChecked && Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
ActivityCompat.requestPermissions(getActivity(),
new String[] {
Manifest.permission.RECORD_AUDIO
},
PERMISSION_REQUEST);
}
}
});
} else {
micPluggedIntoFirstController.setEnabled(false);
micPluggedIntoController.setEnabled(false);
}
Button buttonKeycodeEditor = (Button) getView().findViewById(
@ -177,10 +200,9 @@ public class InputFragment extends Fragment {
public void onClick(View v) {
InputModFragment inputModFrag = new InputModFragment();
getActivity()
.getSupportFragmentManager()
.beginTransaction()
.replace(R.id.fragment_container, inputModFrag,
"INPUT_MOD_FRAG").addToBackStack(null).commit();
.getSupportFragmentManager().beginTransaction()
.replace(R.id.fragment_container, inputModFrag, "INPUT_MOD_FRAG")
.addToBackStack(null).commit();
}
});
@ -258,21 +280,23 @@ public class InputFragment extends Fragment {
updateVibration();
}
private boolean isBIOSAvailable() {
String home_directory = mPrefs.getString(Config.pref_home,
Environment.getExternalStorageDirectory().getAbsolutePath());
return new File(home_directory, "data/dc_flash.bin").exists()
|| mPrefs.getBoolean(Emulator.pref_usereios, false);
}
private void updateVibration() {
boolean touchVibrationEnabled = sharedPreferences.getBoolean(
Config.pref_touchvibe, true);
boolean touchVibrationEnabled = mPrefs.getBoolean(Config.pref_touchvibe, true);
switchTouchVibrationEnabled.setChecked(touchVibrationEnabled);
}
private void updateControllers() {
String deviceDescriptorPlayer1 = sharedPreferences.getString(
Gamepad.pref_player1, null);
String deviceDescriptorPlayer2 = sharedPreferences.getString(
Gamepad.pref_player2, null);
String deviceDescriptorPlayer3 = sharedPreferences.getString(
Gamepad.pref_player3, null);
String deviceDescriptorPlayer4 = sharedPreferences.getString(
Gamepad.pref_player4, null);
String deviceDescriptorPlayer1 = mPrefs.getString(Gamepad.pref_player1, null);
String deviceDescriptorPlayer2 = mPrefs.getString(Gamepad.pref_player2, null);
String deviceDescriptorPlayer3 = mPrefs.getString(Gamepad.pref_player3, null);
String deviceDescriptorPlayer4 = mPrefs.getString(Gamepad.pref_player4, null);
String labelPlayer1 = null, labelPlayer2 = null, labelPlayer3 = null, labelPlayer4 = null;
@ -301,9 +325,8 @@ public class InputFragment extends Fragment {
buttonRemoveControllerPlayer1.setEnabled(true);
} else {
if (deviceDescriptorPlayer1 != null) {
textViewDeviceDescriptorPlayer1
.setText(getString(R.string.controller_not_connected)
+ " (" + deviceDescriptorPlayer1 + ")");
textViewDeviceDescriptorPlayer1.setText(getString(R.string.controller_not_connected,
"(" + deviceDescriptorPlayer1 + ")"));
buttonRemoveControllerPlayer1.setEnabled(true);
} else {
textViewDeviceDescriptorPlayer1
@ -321,9 +344,8 @@ public class InputFragment extends Fragment {
buttonRemoveControllerPlayer2.setEnabled(true);
} else {
if (deviceDescriptorPlayer2 != null) {
textViewDeviceDescriptorPlayer2
.setText(getString(R.string.controller_not_connected)
+ " (" + deviceDescriptorPlayer2 + ")");
textViewDeviceDescriptorPlayer2.setText(getString(R.string.controller_not_connected,
"(" + deviceDescriptorPlayer2 + ")"));
buttonRemoveControllerPlayer2.setEnabled(true);
} else {
textViewDeviceDescriptorPlayer2
@ -332,6 +354,48 @@ public class InputFragment extends Fragment {
}
}
String[] periphs = getResources().getStringArray(R.array.peripherals);
Spinner p2periph1spnr = (Spinner) getView().findViewById(R.id.spnr_player2_periph1);
ArrayAdapter<String> p2periph1Adapter = new ArrayAdapter<>(
getActivity(), R.layout.spinner_selected, periphs);
p2periph1Adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
p2periph1spnr.setAdapter(p2periph1Adapter);
p2periph1spnr.setSelection(mPrefs.getInt(
Gamepad.p2_peripheral + 1, 0), true);
p2periph1spnr.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
mPrefs.edit().putInt(Gamepad.p2_peripheral + 1, pos).apply();
}
public void onNothingSelected(AdapterView<?> arg0) {
}
});
Spinner p2periph2spnr = (Spinner) getView().findViewById(R.id.spnr_player2_periph2);
ArrayAdapter<String> p2periph2Adapter = new ArrayAdapter<>(
getActivity(), R.layout.spinner_selected, periphs);
p2periph2Adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
p2periph2spnr.setAdapter(p2periph2Adapter);
p2periph2spnr.setSelection(mPrefs.getInt(
Gamepad.p2_peripheral + 2, 0), true);
p2periph2spnr.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
mPrefs.edit().putInt(Gamepad.p2_peripheral + 2, pos).apply();
}
public void onNothingSelected(AdapterView<?> arg0) {
}
});
TextView textViewDeviceDescriptorPlayer3 = (TextView) getView()
.findViewById(R.id.textViewDeviceDescriptorPlayer3);
Button buttonRemoveControllerPlayer3 = (Button) getView().findViewById(
@ -341,9 +405,8 @@ public class InputFragment extends Fragment {
buttonRemoveControllerPlayer3.setEnabled(true);
} else {
if (deviceDescriptorPlayer3 != null) {
textViewDeviceDescriptorPlayer3
.setText(getString(R.string.controller_not_connected)
+ " (" + deviceDescriptorPlayer3 + ")");
textViewDeviceDescriptorPlayer3.setText(getString(R.string.controller_not_connected,
"(" + deviceDescriptorPlayer3 + ")"));
buttonRemoveControllerPlayer3.setEnabled(true);
} else {
textViewDeviceDescriptorPlayer3
@ -352,6 +415,46 @@ public class InputFragment extends Fragment {
}
}
Spinner p3periph1spnr = (Spinner) getView().findViewById(R.id.spnr_player3_periph1);
ArrayAdapter<String> p3periph1Adapter = new ArrayAdapter<>(
getActivity(), R.layout.spinner_selected, periphs);
p3periph1Adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
p3periph1spnr.setAdapter(p3periph1Adapter);
p3periph1spnr.setSelection(mPrefs.getInt(
Gamepad.p3_peripheral + 1, 0), true);
p3periph1spnr.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
mPrefs.edit().putInt(Gamepad.p3_peripheral + 1, pos).apply();
}
public void onNothingSelected(AdapterView<?> arg0) {
}
});
Spinner p3periph2spnr = (Spinner) getView().findViewById(R.id.spnr_player3_periph2);
ArrayAdapter<String> p3periph2Adapter = new ArrayAdapter<>(
getActivity(), R.layout.spinner_selected, periphs);
p3periph2Adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
p3periph2spnr.setAdapter(p3periph2Adapter);
p3periph2spnr.setSelection(mPrefs.getInt(
Gamepad.p3_peripheral + 2, 0), true);
p3periph2spnr.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
mPrefs.edit().putInt(Gamepad.p3_peripheral + 2, pos).apply();
}
public void onNothingSelected(AdapterView<?> arg0) {
}
});
TextView textViewDeviceDescriptorPlayer4 = (TextView) getView()
.findViewById(R.id.textViewDeviceDescriptorPlayer4);
Button buttonRemoveControllerPlayer4 = (Button) getView().findViewById(
@ -361,9 +464,8 @@ public class InputFragment extends Fragment {
buttonRemoveControllerPlayer4.setEnabled(true);
} else {
if (deviceDescriptorPlayer4 != null) {
textViewDeviceDescriptorPlayer4
.setText(getString(R.string.controller_not_connected)
+ " (" + deviceDescriptorPlayer4 + ")");
textViewDeviceDescriptorPlayer4.setText(getString(R.string.controller_not_connected,
"(" + deviceDescriptorPlayer4 + ")"));
buttonRemoveControllerPlayer4.setEnabled(true);
} else {
textViewDeviceDescriptorPlayer4
@ -371,6 +473,46 @@ public class InputFragment extends Fragment {
buttonRemoveControllerPlayer4.setEnabled(false);
}
}
Spinner p4periph1spnr = (Spinner) getView().findViewById(R.id.spnr_player4_periph1);
ArrayAdapter<String> p4periph1Adapter = new ArrayAdapter<>(
getActivity(), R.layout.spinner_selected, periphs);
p4periph1Adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
p4periph1spnr.setAdapter(p4periph1Adapter);
String p4periph1 = String.valueOf(mPrefs.getInt(Gamepad.p4_peripheral + 1, 0));
p4periph1spnr.setSelection(p2periph2Adapter.getPosition(p4periph1), true);
p4periph1spnr.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
mPrefs.edit().putInt(Gamepad.p4_peripheral + 1, pos).apply();
}
public void onNothingSelected(AdapterView<?> arg0) {
}
});
Spinner p4periph2spnr = (Spinner) getView().findViewById(R.id.spnr_player4_periph2);
ArrayAdapter<String> p4periph2Adapter = new ArrayAdapter<>(
getActivity(), R.layout.spinner_selected, periphs);
p4periph2Adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
p4periph2spnr.setAdapter(p4periph2Adapter);
String p4periph2 = String.valueOf(mPrefs.getInt(Gamepad.p4_peripheral + 2, 0));
p4periph2spnr.setSelection(p2periph2Adapter.getPosition(p4periph2), true);
p4periph2spnr.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
mPrefs.edit().putInt(Gamepad.p4_peripheral + 2, pos).apply();
}
public void onNothingSelected(AdapterView<?> arg0) {
}
});
}
private void selectController(int playerNum) {
@ -422,25 +564,15 @@ public class InputFragment extends Fragment {
if (keyCode == KeyEvent.KEYCODE_BACK)
return false;
String descriptor = null;
if (pad.isActiveMoga[listenForButton]) {
MogaListener config = new MogaListener(listenForButton);
moga.mController.setListener(config, new Handler());
descriptor = config.getController();
}
descriptor = InputDevice.getDevice(event.getDeviceId()).getDescriptor();
String descriptor = InputDevice.getDevice(event.getDeviceId()).getDescriptor();
if (descriptor == null)
return false;
String deviceDescriptorPlayer1 = sharedPreferences.getString(
Gamepad.pref_player1, null);
String deviceDescriptorPlayer2 = sharedPreferences.getString(
Gamepad.pref_player2, null);
String deviceDescriptorPlayer3 = sharedPreferences.getString(
Gamepad.pref_player3, null);
String deviceDescriptorPlayer4 = sharedPreferences.getString(
Gamepad.pref_player4, null);
String deviceDescriptorPlayer1 = mPrefs.getString(Gamepad.pref_player1, null);
String deviceDescriptorPlayer2 = mPrefs.getString(Gamepad.pref_player2, null);
String deviceDescriptorPlayer3 = mPrefs.getString(Gamepad.pref_player3, null);
String deviceDescriptorPlayer4 = mPrefs.getString(Gamepad.pref_player4, null);
if (descriptor.equals(deviceDescriptorPlayer1)
|| descriptor.equals(deviceDescriptorPlayer2)
@ -455,16 +587,16 @@ public class InputFragment extends Fragment {
case 0:
return false;
case 1:
sharedPreferences.edit().putString(Gamepad.pref_player1, descriptor).apply();
mPrefs.edit().putString(Gamepad.pref_player1, descriptor).apply();
break;
case 2:
sharedPreferences.edit().putString(Gamepad.pref_player2, descriptor).apply();
mPrefs.edit().putString(Gamepad.pref_player2, descriptor).apply();
break;
case 3:
sharedPreferences.edit().putString(Gamepad.pref_player3, descriptor).apply();
mPrefs.edit().putString(Gamepad.pref_player3, descriptor).apply();
break;
case 4:
sharedPreferences.edit().putString(Gamepad.pref_player4, descriptor).apply();
mPrefs.edit().putString(Gamepad.pref_player4, descriptor).apply();
break;
}
@ -480,55 +612,19 @@ public class InputFragment extends Fragment {
private void removeController(int playerNum) {
switch (playerNum) {
case 1:
sharedPreferences.edit().putString(Gamepad.pref_player1, null).apply();
mPrefs.edit().putString(Gamepad.pref_player1, null).apply();
break;
case 2:
sharedPreferences.edit().putString(Gamepad.pref_player2, null).apply();
mPrefs.edit().putString(Gamepad.pref_player2, null).apply();
break;
case 3:
sharedPreferences.edit().putString(Gamepad.pref_player3, null).apply();
mPrefs.edit().putString(Gamepad.pref_player3, null).apply();
break;
case 4:
sharedPreferences.edit().putString(Gamepad.pref_player4, null).apply();
mPrefs.edit().putString(Gamepad.pref_player4, null).apply();
break;
}
updateControllers();
}
private final class MogaListener implements ControllerListener {
private int playerNum;
private String controllerId;
public MogaListener(int playerNum) {
this.playerNum = playerNum;
}
public void onKeyEvent(com.bda.controller.KeyEvent event) {
controllerId = String.valueOf(event.getControllerId());
}
public void onMotionEvent(MotionEvent arg0) {
}
public String getController() {
return controllerId;
}
public void onStateEvent(StateEvent event) {
if (event.getState() == StateEvent.STATE_CONNECTION &&
event.getAction() == MOGAInput.ACTION_CONNECTED) {
int mControllerVersion = moga.mController
.getState(Controller.STATE_CURRENT_PRODUCT_VERSION);
if (mControllerVersion == Controller.ACTION_VERSION_MOGA ||
mControllerVersion == Controller.ACTION_VERSION_MOGAPRO) {
pad.isActiveMoga[playerNum] = true;
}
}
}
}
}

View File

@ -1,6 +1,5 @@
package com.reicast.emulator.config;
import android.annotation.TargetApi;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
@ -39,14 +38,16 @@ 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 switchJoystickDpadEnabled;
private CompoundButton switchRightStickLREnabled;
private CompoundButton switchModifiedLayoutEnabled;
private CompoundButton switchCompatibilityEnabled;
private Spinner right_stick_spinner;
private CompoundButton switchJoystickDpadEnabled;
private TextView a_button_text;
private TextView b_button_text;
@ -60,17 +61,14 @@ public class InputModFragment extends Fragment {
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;
// Container Activity must implement this interface
public interface OnClickListener {
void onMainBrowseSelected(String path_entry, boolean games);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
@ -92,8 +90,6 @@ public class InputModFragment extends Fragment {
switchJoystickDpadEnabled = (CompoundButton) getView().findViewById(
R.id.switchJoystickDpadEnabled);
switchRightStickLREnabled = (CompoundButton) getView().findViewById(
R.id.switchRightStickLREnabled);
switchModifiedLayoutEnabled = (CompoundButton) getView().findViewById(
R.id.switchModifiedLayoutEnabled);
switchCompatibilityEnabled = (CompoundButton) getView().findViewById(
@ -108,14 +104,23 @@ public class InputModFragment extends Fragment {
switchJoystickDpadEnabled.setOnCheckedChangeListener(joystick_mode);
OnCheckedChangeListener rstick_mode = new OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
mPrefs.edit().putBoolean(Gamepad.pref_js_rbuttons + player, isChecked).apply();
}
};
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() {
switchRightStickLREnabled.setOnCheckedChangeListener(rstick_mode);
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,
@ -303,6 +308,40 @@ public class InputModFragment extends Fragment {
}
});
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));
@ -346,7 +385,7 @@ public class InputModFragment extends Fragment {
Spinner player_spnr = (Spinner) getView().findViewById(
R.id.player_spinner);
ArrayAdapter<String> playerAdapter = new ArrayAdapter<String>(
ArrayAdapter<String> playerAdapter = new ArrayAdapter<>(
getActivity(), android.R.layout.simple_spinner_item,
controllers);
playerAdapter
@ -387,7 +426,7 @@ public class InputModFragment extends Fragment {
Bitmap image = null;
try {
File buttons = null;
InputStream bitmap = null;
InputStream bitmap;
String theme = mPrefs.getString(Config.pref_theme, null);
if (theme != null) {
buttons = new File(theme);
@ -401,7 +440,6 @@ public class InputModFragment extends Fragment {
options.inSampleSize = sS;
image = BitmapFactory.decodeStream(bitmap, null, options);
bitmap.close();
bitmap = null;
Matrix matrix = new Matrix();
matrix.postScale(32, 32);
Bitmap resizedBitmap = Bitmap.createBitmap(image, x, y, 64 / sS,
@ -417,7 +455,6 @@ public class InputModFragment extends Fragment {
if (sS == 2) {
if (image != null) {
image.recycle();
image = null;
}
sS = 4;
return getButtonImage(x, y);
@ -454,11 +491,8 @@ public class InputModFragment extends Fragment {
}
private class mapKeyCode extends AlertDialog.Builder {
private String button;
private TextView output;
private boolean isMapping;
public mapKeyCode(Context c) {
mapKeyCode(Context c) {
super(c);
}
@ -471,23 +505,18 @@ public class InputModFragment extends Fragment {
* The output display for the assigned button value
*/
public void intiateSearch(final String button, final TextView output) {
this.button = button;
this.output = output;
isMapping = true;
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) {
isMapping = false;
dialog.dismiss();
}
});
builder.setOnKeyListener(new Dialog.OnKeyListener() {
public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
mapButton(keyCode, event);
isMapping = false;
mapButton(keyCode, button);
dialog.dismiss();
return getKeyCode(button, output);
}
@ -501,68 +530,82 @@ public class InputModFragment extends Fragment {
*
* @param keyCode
* The keycode generated by the button being assigned
* @param event
* The keyevent generated by the button being assigned
* @param button
* The label of the button being assigned
*/
private int mapButton(int keyCode, KeyEvent event) {
private void mapButton(int keyCode, String button) {
if (Build.MODEL.startsWith("R800")) {
if (keyCode == KeyEvent.KEYCODE_MENU)
return -1;
return;
} else {
if (keyCode == KeyEvent.KEYCODE_BACK)
return -1;
return;
}
mPrefs.edit().putInt(button + player, keyCode).apply();
return keyCode;
}
public boolean dispatchTouchEvent(MotionEvent ev) {
if (isMapping) {
if ((ev.getSource() & InputDevice.SOURCE_CLASS_JOYSTICK) != 0) {
if (ev.getAxisValue(MotionEvent.AXIS_HAT_X) != 0) {
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();
}
if (ev.getAxisValue(MotionEvent.AXIS_HAT_Y) != 0) {
});
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 (ev.getAxisValue(MotionEvent.AXIS_Z) != 0) {
if (event.getAxisValue(MotionEvent.AXIS_Y) != 0) {
axis = MotionEvent.AXIS_Y;
}
if (ev.getAxisValue(MotionEvent.AXIS_RZ) != 0) {
if (event.getAxisValue(MotionEvent.AXIS_RX) != 0) {
axis = MotionEvent.AXIS_RX;
}
if (ev.getAxisValue(MotionEvent.AXIS_RTRIGGER) != 0) {
if (event.getAxisValue(MotionEvent.AXIS_RY) != 0) {
axis = MotionEvent.AXIS_RY;
}
if (ev.getAxisValue(MotionEvent.AXIS_LTRIGGER) != 0) {
if (event.getAxisValue(MotionEvent.AXIS_HAT_X) != 0) {
axis = MotionEvent.AXIS_HAT_X;
}
if (ev.getAxisValue(MotionEvent.AXIS_THROTTLE) != 0) {
if (event.getAxisValue(MotionEvent.AXIS_HAT_Y) != 0) {
axis = MotionEvent.AXIS_HAT_Y;
}
if (ev.getAxisValue(MotionEvent.AXIS_BRAKE) != 0) {
if (new Gamepad().IsOuyaOrTV(getActivity(), true)) {
if (event.getAxisValue(OuyaController.AXIS_LS_X) != 0) {
axis = OuyaController.AXIS_LS_X;
}
String label = output.getText().toString();
if (label.contains(":")) {
label = label.substring(0, label.indexOf(":"));
if (event.getAxisValue(OuyaController.AXIS_LS_Y) != 0) {
axis = OuyaController.AXIS_LS_Y;
}
output.setText(label + ": " + ev.getAction());
}
mPrefs.edit().putInt(button + player, axis).apply();
dialog.dismiss();
return getKeyCode(button, output);
}
return dispatchTouchEvent(ev);
return true;
}
});
}
}
private void updateController(String player) {
switchJoystickDpadEnabled.setChecked(mPrefs.getBoolean(
Gamepad.pref_js_merged + player, false));
switchRightStickLREnabled.setChecked(mPrefs.getBoolean(
Gamepad.pref_js_rbuttons + player, true));
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(
@ -577,6 +620,8 @@ public class InputModFragment extends Fragment {
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);
}
@ -588,7 +633,8 @@ public class InputModFragment extends Fragment {
if (label.contains(":")) {
label = label.substring(0, label.indexOf(":"));
}
output.setText(label + ": " + keyCode);
label += ": " + keyCode;
output.setText(label);
return true;
} else {
String label = output.getText().toString();

View File

@ -15,12 +15,12 @@ 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.text.Editable;
import android.text.TextWatcher;
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;
@ -50,6 +50,7 @@ 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.Iterator;
@ -69,11 +70,11 @@ public class OptionsFragment extends Fragment {
// Container Activity must implement this interface
public interface OnClickListener {
void onMainBrowseSelected(boolean browse, String path_entry, boolean games, String query);
void onSettingsReload(Fragment options);
void onMainBrowseSelected(String path_entry, boolean games, String query);
void launchBIOSdetection();
}
@Override
@Override @SuppressWarnings("deprecation")
public void onAttach(Activity activity) {
super.onAttach(activity);
@ -116,8 +117,8 @@ public class OptionsFragment extends Fragment {
// Specialized handler for devices with an extSdCard mount for external
HashSet<String> extStorage = FileBrowser.getExternalMounts();
if (extStorage != null && !extStorage.isEmpty()) {
for (Iterator<String> sd = extStorage.iterator(); sd.hasNext();) {
String sdCardPath = sd.next().replace("mnt/media_rw", "storage");
for (String sd : extStorage) {
String sdCardPath = sd.replace("mnt/media_rw", "storage");
if (!sdCardPath.equals(sdcard.getAbsolutePath())) {
game_directory = sdCardPath;
}
@ -132,7 +133,7 @@ public class OptionsFragment extends Fragment {
Button mainBrowse = (Button) getView().findViewById(R.id.browse_main_path);
mSpnrThemes = (Spinner) getView().findViewById(R.id.pick_button_theme);
new LocateThemes().execute(home_directory + "/themes");
new LocateThemes(this).execute(home_directory + "/themes");
final EditText editBrowse = (EditText) getView().findViewById(R.id.main_path);
editBrowse.setText(home_directory);
@ -141,14 +142,18 @@ public class OptionsFragment extends Fragment {
public void onClick(View view) {
mPrefs.edit().remove(Config.pref_home).apply();
hideSoftKeyBoard();
mCallback.onMainBrowseSelected(false, home_directory, false, null);
mCallback.launchBIOSdetection();
}
});
editBrowse.addTextChangedListener(new TextWatcher() {
public void afterTextChanged(Editable s) {
if (editBrowse.getText() != null) {
home_directory = editBrowse.getText().toString();
editBrowse.setOnEditorActionListener(new EditText.OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if (actionId == EditorInfo.IME_ACTION_DONE
|| (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),
@ -156,14 +161,13 @@ public class OptionsFragment extends Fragment {
}
mPrefs.edit().putString(Config.pref_home, home_directory).apply();
JNIdc.config(home_directory);
new LocateThemes().execute(home_directory + "/themes");
new LocateThemes(OptionsFragment.this).execute(home_directory + "/themes");
}
hideSoftKeyBoard();
return true;
}
}
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
public void onTextChanged(CharSequence s, int start, int before, int count) {
return false;
}
});
@ -174,8 +178,7 @@ public class OptionsFragment extends Fragment {
mPrefs.edit().putBoolean(Emulator.pref_usereios, isChecked).apply();
}
};
CompoundButton reios_opt = (CompoundButton) getView().findViewById(
R.id.reios_option);
CompoundButton reios_opt = (CompoundButton) getView().findViewById(R.id.reios_option);
reios_opt.setChecked(mPrefs.getBoolean(Emulator.pref_usereios, false));
reios_opt.setOnCheckedChangeListener(reios_options);
@ -194,15 +197,13 @@ public class OptionsFragment extends Fragment {
}
}
};
CompoundButton details_opt = (CompoundButton) getView().findViewById(
R.id.details_option);
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);
final EditText editGames = (EditText) getView().findViewById(R.id.game_path);
game_directory = mPrefs.getString(Config.pref_games, game_directory);
editGames.setText(game_directory);
@ -213,40 +214,40 @@ public class OptionsFragment extends Fragment {
game_directory = editGames.getText().toString();
}
hideSoftKeyBoard();
mCallback.onMainBrowseSelected(false, game_directory, true, null);
mCallback.onMainBrowseSelected(game_directory, true, null);
}
});
editGames.addTextChangedListener(new TextWatcher() {
public void afterTextChanged(Editable s) {
if (editBrowse.getText() != null) {
game_directory = editGames.getText().toString();
editGames.setOnEditorActionListener(new EditText.OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if (actionId == EditorInfo.IME_ACTION_DONE
|| (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;
}
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
public void onTextChanged(CharSequence s, int start, int before, int count) {
return false;
}
});
String[] bios = getResources().getStringArray(R.array.bios);
codes = getResources().getStringArray(R.array.bioscode);
Spinner bios_spnr = (Spinner) getView().findViewById(
R.id.bios_spinner);
ArrayAdapter<String> biosAdapter = new ArrayAdapter<String>(
Spinner bios_spnr = (Spinner) getView().findViewById(R.id.bios_spinner);
ArrayAdapter<String> biosAdapter = new ArrayAdapter<>(
getActivity(), android.R.layout.simple_spinner_item, bios);
biosAdapter
.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
biosAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
bios_spnr.setAdapter(biosAdapter);
String region = mPrefs.getString("localized", codes[4]);
bios_spnr.setSelection(biosAdapter.getPosition(region), true);
bios_spnr.setOnItemSelectedListener(new OnItemSelectedListener() {
public void onItemSelected(AdapterView<?> parent, View view,
int pos, long id) {
public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
flashBios(codes[pos]);
}
@ -261,12 +262,10 @@ public class OptionsFragment extends Fragment {
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
mPrefs.edit().putBoolean(Emulator.pref_nativeact, isChecked).apply();
Emulator.nativeact = isChecked;
}
};
CompoundButton native_opt = (CompoundButton) getView().findViewById(
R.id.native_option);
native_opt.setChecked(Emulator.nativeact);
CompoundButton native_opt = (CompoundButton) getView().findViewById(R.id.native_option);
native_opt.setChecked(mPrefs.getBoolean(Emulator.pref_nativeact, Emulator.nativeact));
native_opt.setOnCheckedChangeListener(native_options);
OnCheckedChangeListener dynarec_options = new OnCheckedChangeListener() {
@ -274,11 +273,9 @@ public class OptionsFragment extends Fragment {
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
mPrefs.edit().putBoolean(Emulator.pref_dynarecopt, isChecked).apply();
Emulator.dynarecopt = isChecked;
}
};
CompoundButton dynarec_opt = (CompoundButton) getView().findViewById(
R.id.dynarec_option);
CompoundButton dynarec_opt = (CompoundButton) getView().findViewById(R.id.dynarec_option);
dynarec_opt.setChecked(Emulator.dynarecopt);
dynarec_opt.setOnCheckedChangeListener(dynarec_options);
@ -287,36 +284,27 @@ public class OptionsFragment extends Fragment {
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
mPrefs.edit().putBoolean(Emulator.pref_unstable, isChecked).apply();
Emulator.unstableopt = isChecked;
}
};
CompoundButton unstable_opt = (CompoundButton) getView().findViewById(
R.id.unstable_option);
if (Emulator.unstableopt) {
unstable_opt.setChecked(true);
} else {
unstable_opt.setChecked(false);
}
CompoundButton unstable_opt = (CompoundButton) getView().findViewById(R.id.unstable_option);
unstable_opt.setChecked(mPrefs.getBoolean(Emulator.pref_unstable, Emulator.unstableopt));
unstable_opt.setOnCheckedChangeListener(unstable_option);
String[] cables = getResources().getStringArray(
R.array.cable);
Spinner cable_spnr = (Spinner) getView().findViewById(
R.id.cable_spinner);
ArrayAdapter<String> cableAdapter = new ArrayAdapter<String>(
String[] cables = getResources().getStringArray(R.array.cable);
Spinner cable_spnr = (Spinner) getView().findViewById(R.id.cable_spinner);
ArrayAdapter<String> cableAdapter = new ArrayAdapter<>(
getActivity(), R.layout.spinner_selected, cables);
cableAdapter
.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
cableAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
cable_spnr.setAdapter(cableAdapter);
cable_spnr.setSelection(Emulator.cable - 1, true);
cable_spnr.setSelection(mPrefs.getInt(
Emulator.pref_cable, Emulator.cable) - 1, true);
cable_spnr.setOnItemSelectedListener(new OnItemSelectedListener() {
public void onItemSelected(AdapterView<?> parent, View view,
int pos, long id) {
mPrefs.edit().putInt(Emulator.pref_cable, pos + 1).apply();
Emulator.cable = pos + 1;
}
public void onNothingSelected(AdapterView<?> arg0) {
@ -325,19 +313,16 @@ public class OptionsFragment extends Fragment {
});
// String[] regions = ArrayUtils.remove(parentActivity.getResources()
// .getStringArray(R.array.region), 4);
String[] regions = getResources().getStringArray(R.array.region);
Spinner region_spnr = (Spinner) getView().findViewById(R.id.region_spinner);
ArrayAdapter<String> regionAdapter = new ArrayAdapter<String>(
ArrayAdapter<String> regionAdapter = new ArrayAdapter<>(
getActivity(), R.layout.spinner_selected, regions);
regionAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
region_spnr.setAdapter(regionAdapter);
region_spnr.setSelection(Emulator.dcregion, true);
region_spnr.setSelection(mPrefs.getInt(Emulator.pref_dcregion, Emulator.dcregion), true);
region_spnr.setOnItemSelectedListener(new OnItemSelectedListener() {
public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
mPrefs.edit().putInt(Emulator.pref_dcregion, pos).apply();
Emulator.dcregion = pos;
}
@ -348,13 +333,13 @@ public class OptionsFragment extends Fragment {
String[] broadcasts = getResources().getStringArray(R.array.broadcast);
Spinner broadcast_spnr = (Spinner) getView().findViewById(R.id.broadcast_spinner);
ArrayAdapter<String> broadcastAdapter = new ArrayAdapter<String>(
ArrayAdapter<String> broadcastAdapter = new ArrayAdapter<>(
getActivity(), R.layout.spinner_selected, broadcasts);
broadcastAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
broadcast_spnr.setAdapter(broadcastAdapter);
int select = 0;
String cast = String.valueOf(Emulator.broadcast);
String cast = String.valueOf(mPrefs.getInt(Emulator.pref_broadcast, Emulator.broadcast));
for (int i = 0; i < broadcasts.length; i++) {
if (broadcasts[i].startsWith(cast + " - "))
select = i;
@ -367,7 +352,6 @@ public class OptionsFragment extends Fragment {
String item = parent.getItemAtPosition(pos).toString();
String selection = item.substring(0, item.indexOf(" - "));
mPrefs.edit().putInt(Emulator.pref_broadcast, Integer.parseInt(selection)).apply();
Emulator.broadcast = Integer.parseInt(selection);
}
@ -380,40 +364,39 @@ public class OptionsFragment extends Fragment {
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
mPrefs.edit().putBoolean(Emulator.pref_limitfps, isChecked).apply();
Emulator.limitfps = isChecked;
}
};
CompoundButton limit_fps = (CompoundButton) getView().findViewById(R.id.limitfps_option);
limit_fps.setChecked(Emulator.limitfps);
limit_fps.setChecked(mPrefs.getBoolean(Emulator.pref_limitfps, Emulator.limitfps));
limit_fps.setOnCheckedChangeListener(limitfps_option);
OnCheckedChangeListener mipmaps_option = new OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
mPrefs.edit().putBoolean(Emulator.pref_mipmaps, isChecked).apply();
Emulator.mipmaps = isChecked;
}
};
CompoundButton mipmap_opt = (CompoundButton) getView().findViewById(R.id.mipmaps_option);
mipmap_opt.setChecked(Emulator.mipmaps);
mipmap_opt.setChecked(mPrefs.getBoolean(Emulator.pref_mipmaps, Emulator.mipmaps));
mipmap_opt.setOnCheckedChangeListener(mipmaps_option);
OnCheckedChangeListener full_screen = new OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
mPrefs.edit().putBoolean(Emulator.pref_widescreen, isChecked).apply();
Emulator.widescreen = isChecked;
}
};
CompoundButton stretch_view = (CompoundButton) getView().findViewById(R.id.stretch_option);
stretch_view.setChecked(Emulator.widescreen);
stretch_view.setChecked(mPrefs.getBoolean(Emulator.pref_widescreen, Emulator.widescreen));
stretch_view.setOnCheckedChangeListener(full_screen);
int frameskip = mPrefs.getInt(Emulator.pref_frameskip, Emulator.frameskip);
final EditText mainFrames = (EditText) getView().findViewById(R.id.current_frames);
mainFrames.setText(String.valueOf(Emulator.frameskip));
mainFrames.setText(String.valueOf(frameskip));
final SeekBar frameSeek = (SeekBar) getView().findViewById(R.id.frame_seekbar);
frameSeek.setProgress(Emulator.frameskip);
frameSeek.setProgress(frameskip);
frameSeek.setIndeterminate(false);
frameSeek.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
@ -427,24 +410,25 @@ public class OptionsFragment extends Fragment {
public void onStopTrackingTouch(SeekBar seekBar) {
int progress = seekBar.getProgress();
mPrefs.edit().putInt(Emulator.pref_frameskip, progress).apply();
Emulator.frameskip = progress;
}
});
mainFrames.addTextChangedListener(new TextWatcher() {
public void afterTextChanged(Editable s) {
Editable frameText = mainFrames.getText();
if (frameText != null) {
int frames = Integer.parseInt(frameText.toString());
mainFrames.setOnEditorActionListener(new EditText.OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if (actionId == EditorInfo.IME_ACTION_DONE
|| (event.getKeyCode() == KeyEvent.KEYCODE_ENTER
&& event.getAction() == KeyEvent.ACTION_DOWN)) {
if (event == null || !event.isShiftPressed()) {
if (v.getText() != null) {
int frames = Integer.parseInt(v.getText().toString());
frameSeek.setProgress(frames);
mPrefs.edit().putInt(Emulator.pref_frameskip, frames).apply();
Emulator.frameskip = frames;
}
hideSoftKeyBoard();
return true;
}
}
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
public void onTextChanged(CharSequence s, int start, int before, int count) {
return false;
}
});
@ -452,64 +436,56 @@ public class OptionsFragment extends Fragment {
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
mPrefs.edit().putBoolean(Emulator.pref_pvrrender, isChecked).apply();
Emulator.pvrrender = isChecked;
}
};
CompoundButton pvr_render = (CompoundButton) getView().findViewById(R.id.render_option);
pvr_render.setChecked(Emulator.pvrrender);
pvr_render.setChecked(mPrefs.getBoolean(Emulator.pref_pvrrender, Emulator.pvrrender));
pvr_render.setOnCheckedChangeListener(pvr_rendering);
OnCheckedChangeListener synchronous = new OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
mPrefs.edit().putBoolean(Emulator.pref_syncedrender, isChecked).apply();
Emulator.syncedrender = isChecked;
}
};
CompoundButton synced_render = (CompoundButton) getView().findViewById(R.id.syncrender_option);
synced_render.setChecked(Emulator.syncedrender);
synced_render.setChecked(mPrefs.getBoolean(Emulator.pref_syncedrender, Emulator.syncedrender));
synced_render.setOnCheckedChangeListener(synchronous);
OnCheckedChangeListener mod_volumes = new OnCheckedChangeListener() {
final EditText bootdiskEdit = (EditText) getView().findViewById(R.id.boot_disk);
bootdiskEdit.setText(mPrefs.getString(Emulator.pref_bootdisk, Emulator.bootdisk));
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
mPrefs.edit().putBoolean(Emulator.pref_modvols, isChecked).apply();
Emulator.modvols = isChecked;
bootdiskEdit.setOnEditorActionListener(new EditText.OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if (actionId == EditorInfo.IME_ACTION_DONE
|| (event.getKeyCode() == KeyEvent.KEYCODE_ENTER
&& event.getAction() == KeyEvent.ACTION_DOWN)) {
if (event == null || !event.isShiftPressed()) {
String disk = null;
if (v.getText() != null) {
disk = v.getText().toString();
if (disk.equals("") || disk.substring(
disk.lastIndexOf("/") + 1).length() == 0) {
disk = null;
} else {
if (!disk.contains("/"))
disk = game_directory + "/" + disk;
if (!new File(disk).exists())
disk = null;
}
};
CompoundButton modifier_volumes = (CompoundButton) getView().findViewById(R.id.modvols_option);
modifier_volumes.setChecked(Emulator.modvols);
modifier_volumes.setOnCheckedChangeListener(mod_volumes);
// final EditText bootdiskEdit = (EditText) getView().findViewById(R.id.boot_disk);
// String disk = Emulator.bootdisk;
// if (disk != null && disk.contains("/")) {
// bootdiskEdit.setText(disk.substring(disk.lastIndexOf("/"),
// disk.length()));
// } else {
// bootdiskEdit.setText(disk);
// }
//
// bootdiskEdit.addTextChangedListener(new TextWatcher() {
// public void afterTextChanged(Editable s) {
// if (bootdiskEdit.getText() != null) {
// String disk = bootdiskEdit.getText().toString();
// if (disk.contains("/")) {
// bootdiskEdit.setText(disk.substring(disk.lastIndexOf("/"),
// disk.length()));
// } else {
// bootdiskEdit.setText(disk);
// }
// mPrefs.edit().putString(Emulator.pref_bootdisk, disk).apply();
// Emulator.bootdisk = disk;
// }
// }
//
// public void beforeTextChanged(CharSequence s, int start, int count, int after) {
// }
//
// public void onTextChanged(CharSequence s, int start, int before, int count) {
// }
// });
v.setText(disk);
}
if (disk == null)
mPrefs.edit().remove(Emulator.pref_bootdisk).apply();
else
mPrefs.edit().putString(Emulator.pref_bootdisk, disk).apply();
hideSoftKeyBoard();
return true;
}
}
return false;
}
});
final CompoundButton fps_opt = (CompoundButton) getView().findViewById(R.id.fps_option);
OnCheckedChangeListener fps_options = new OnCheckedChangeListener() {
@ -541,7 +517,6 @@ public class OptionsFragment extends Fragment {
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
mPrefs.edit().putBoolean(Emulator.pref_nosound, isChecked).apply();
Emulator.nosound = isChecked;
}
};
boolean sound = mPrefs.getBoolean(Emulator.pref_nosound, false);
@ -551,7 +526,7 @@ public class OptionsFragment extends Fragment {
String[] depths = getResources().getStringArray(R.array.depth);
Spinner depth_spnr = (Spinner) getView().findViewById(R.id.depth_spinner);
ArrayAdapter<String> depthAdapter = new ArrayAdapter<String>(
ArrayAdapter<String> depthAdapter = new ArrayAdapter<>(
getActivity(), R.layout.spinner_selected, depths);
depthAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
depth_spnr.setAdapter(depthAdapter);
@ -571,7 +546,7 @@ public class OptionsFragment extends Fragment {
}
});
Button resetEmu = (Button) getView().findViewById(R.id.reset_emu_settings);
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());
@ -589,23 +564,24 @@ public class OptionsFragment extends Fragment {
});
}
private final class LocateThemes extends AsyncTask<String, Integer, List<File>> {
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 = getResources().getStringArray(R.array.themes);
String[] mediaTypes = options.get().getResources().getStringArray(R.array.themes);
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) {
if (dir.getName().startsWith(".")
|| name.startsWith(".")) {
return false;
} else {
return StringUtils.endsWithIgnoreCase(name, "."
+ type);
}
return !dir.getName().startsWith(".") && !name.startsWith(".")
&& StringUtils.endsWithIgnoreCase(name, "." + type);
}
};
i++;
@ -623,19 +599,19 @@ public class OptionsFragment extends Fragment {
themes[i] = items.get(i).getName();
}
themes[items.size()] = "None";
ArrayAdapter<String> themeAdapter = new ArrayAdapter<String>(
getActivity(), android.R.layout.simple_spinner_item, themes);
ArrayAdapter<String> themeAdapter = new ArrayAdapter<>(
options.get().getActivity(), android.R.layout.simple_spinner_item, themes);
themeAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
mSpnrThemes.setAdapter(themeAdapter);
mSpnrThemes.setOnItemSelectedListener(new OnItemSelectedListener() {
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")) {
mPrefs.edit().remove(Config.pref_theme).apply();
options.get().mPrefs.edit().remove(Config.pref_theme).apply();
} else {
String theme_path = home_directory + "/themes/" + theme;
mPrefs.edit().putString(Config.pref_theme, theme_path).apply();
String theme_path = options.get().home_directory + "/themes/" + theme;
options.get().mPrefs.edit().putString(Config.pref_theme, theme_path).apply();
}
}
@Override
@ -644,17 +620,21 @@ public class OptionsFragment extends Fragment {
}
});
} else {
mSpnrThemes.setEnabled(false);
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 {
@ -720,15 +700,14 @@ public class OptionsFragment extends Fragment {
mPrefs.edit().remove(Emulator.pref_frameskip).apply();
mPrefs.edit().remove(Emulator.pref_pvrrender).apply();
mPrefs.edit().remove(Emulator.pref_syncedrender).apply();
mPrefs.edit().remove(Emulator.pref_modvols).apply();
// mPrefs.edit().remove(Emulator.pref_bootdisk).apply();
mPrefs.edit().remove(Emulator.pref_bootdisk).apply();
mPrefs.edit().remove(Config.pref_showfps).apply();
mPrefs.edit().remove(Config.pref_rendertype).apply();
mPrefs.edit().remove(Emulator.pref_nosound).apply();
mPrefs.edit().remove(Config.pref_renderdepth).apply();
mPrefs.edit().remove(Config.pref_theme).apply();
mCallback.onSettingsReload(this);
getActivity().finish();
}
private void showToastMessage(String message, int duration) {

View File

@ -0,0 +1,400 @@
package com.reicast.emulator.config;
import android.app.Activity;
import android.content.Context;
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.util.Log;
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.ArrayAdapter;
import android.widget.Button;
import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.Spinner;
import android.widget.TextView;
import com.android.util.FileUtils;
import com.reicast.emulator.Emulator;
import com.reicast.emulator.R;
import com.reicast.emulator.periph.Gamepad;
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.HashMap;
import java.util.List;
import java.util.Map;
public class PGConfigFragment extends Fragment {
private Spinner mSpnrConfigs;
private CompoundButton switchJoystickDpadEnabled;
private CompoundButton dynarec_opt;
private CompoundButton unstable_opt;
private CompoundButton safemode_opt;
private EditText mainFrames;
private SeekBar frameSeek;
private CompoundButton pvr_render;
private CompoundButton synced_render;
private CompoundButton modifier_volumes;
private CompoundButton interrupt_opt;
private EditText bootdiskEdit;
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.pgconfig_fragment, container, false);
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
Emulator app = (Emulator) getActivity().getApplicationContext();
app.getConfigurationPrefs(PreferenceManager.getDefaultSharedPreferences(getActivity()));
mSpnrConfigs = (Spinner) getView().findViewById(R.id.config_spinner);
new LocateConfigs(PGConfigFragment.this).execute("/data/data/"
+ getActivity().getPackageName() + "/shared_prefs/");
switchJoystickDpadEnabled = (CompoundButton) getView().findViewById(
R.id.switchJoystickDpadEnabled);
dynarec_opt = (CompoundButton) getView().findViewById(R.id.dynarec_option);
unstable_opt = (CompoundButton) getView().findViewById(R.id.unstable_option);
safemode_opt = (CompoundButton) getView().findViewById(R.id.dynarec_safemode);
mainFrames = (EditText) getView().findViewById(R.id.current_frames);
frameSeek = (SeekBar) getView().findViewById(R.id.frame_seekbar);
pvr_render = (CompoundButton) getView().findViewById(R.id.render_option);
synced_render = (CompoundButton) getView().findViewById(R.id.syncrender_option);
modifier_volumes = (CompoundButton) getView().findViewById(R.id.modvols_option);
interrupt_opt = (CompoundButton) getView().findViewById(R.id.interrupt_option);
bootdiskEdit = (EditText) getView().findViewById(R.id.boot_disk);
}
private void saveSettings(SharedPreferences mPrefs) {
mPrefs.edit()
.putBoolean(Gamepad.pref_js_merged + "_A", switchJoystickDpadEnabled.isChecked())
.putBoolean(Emulator.pref_dynarecopt, dynarec_opt.isChecked())
.putBoolean(Emulator.pref_unstable, unstable_opt.isChecked())
.putBoolean(Emulator.pref_dynsafemode, safemode_opt.isChecked())
.putInt(Emulator.pref_frameskip, frameSeek.getProgress())
.putBoolean(Emulator.pref_pvrrender, pvr_render.isChecked())
.putBoolean(Emulator.pref_syncedrender, synced_render.isChecked())
.putBoolean(Emulator.pref_modvols, modifier_volumes.isChecked())
.putBoolean(Emulator.pref_interrupt, interrupt_opt.isChecked()).apply();
if (bootdiskEdit.getText() != null)
mPrefs.edit().putString(Emulator.pref_bootdisk,
bootdiskEdit.getText().toString()).apply();
else
mPrefs.edit().remove(Emulator.pref_bootdisk).apply();
showToastMessage(getActivity().getString(R.string.pgconfig_saved), Snackbar.LENGTH_SHORT);
}
private void clearSettings(SharedPreferences mPrefs, String gameId) {
mPrefs.edit() // Prevent clear() removing title
.remove(Gamepad.pref_js_merged + "_A")
.remove(Emulator.pref_dynarecopt)
.remove(Emulator.pref_unstable)
.remove(Emulator.pref_dynsafemode)
.remove(Emulator.pref_frameskip)
.remove(Emulator.pref_pvrrender)
.remove(Emulator.pref_syncedrender)
.remove(Emulator.pref_modvols)
.remove(Emulator.pref_interrupt)
.remove(Emulator.pref_bootdisk).apply();
showToastMessage(getActivity().getString(R.string.pgconfig_cleared), Snackbar.LENGTH_SHORT);
configureViewByGame(gameId);
}
private void configureViewByGame(final String gameId) {
final SharedPreferences mPrefs = getActivity()
.getSharedPreferences(gameId, Activity.MODE_PRIVATE);
switchJoystickDpadEnabled.setChecked(mPrefs.getBoolean(
Gamepad.pref_js_merged + "_A", false));
dynarec_opt.setChecked(mPrefs.getBoolean(Emulator.pref_dynarecopt, Emulator.dynarecopt));
unstable_opt.setChecked(mPrefs.getBoolean(Emulator.pref_unstable, Emulator.unstableopt));
safemode_opt.setChecked(mPrefs.getBoolean(Emulator.pref_dynsafemode, Emulator.dynsafemode));
int frameskip = mPrefs.getInt(Emulator.pref_frameskip, Emulator.frameskip);
mainFrames.setText(String.valueOf(frameskip));
frameSeek.setProgress(frameskip);
frameSeek.setIndeterminate(false);
frameSeek.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
mainFrames.setText(String.valueOf(progress));
}
public void onStartTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
mainFrames.setOnEditorActionListener(new EditText.OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if (actionId == EditorInfo.IME_ACTION_DONE
|| (event.getKeyCode() == KeyEvent.KEYCODE_ENTER
&& event.getAction() == KeyEvent.ACTION_DOWN)) {
if (event == null || !event.isShiftPressed()) {
if (v.getText() != null) {
int frames = Integer.parseInt(v.getText().toString());
frameSeek.setProgress(frames);
}
hideSoftKeyBoard();
return true;
}
}
return false;
}
});
pvr_render.setChecked(mPrefs.getBoolean(Emulator.pref_pvrrender, Emulator.pvrrender));
synced_render.setChecked(mPrefs.getBoolean(Emulator.pref_syncedrender, Emulator.syncedrender));
modifier_volumes.setChecked(mPrefs.getBoolean(Emulator.pref_modvols, Emulator.modvols));
interrupt_opt.setChecked(mPrefs.getBoolean(Emulator.pref_interrupt, Emulator.interrupt));
bootdiskEdit.setText(mPrefs.getString(Emulator.pref_bootdisk, Emulator.bootdisk));
bootdiskEdit.setOnEditorActionListener(new EditText.OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if (actionId == EditorInfo.IME_ACTION_DONE
|| (event.getKeyCode() == KeyEvent.KEYCODE_ENTER
&& event.getAction() == KeyEvent.ACTION_DOWN)) {
if (event == null || !event.isShiftPressed()) {
String disk;
if (v.getText() != null) {
disk = v.getText().toString();
if (disk.equals("") || disk.substring(
disk.lastIndexOf("/") + 1).length() == 0) {
disk = null;
} else {
if (!disk.contains("/"))
disk = mPrefs.getString(Config.pref_games,
Environment.getExternalStorageDirectory()
.getAbsolutePath()) + "/" + disk;
if (!new File(disk).exists())
disk = null;
}
v.setText(disk);
}
hideSoftKeyBoard();
return true;
}
}
return false;
}
});
Button savePGC = (Button) getView().findViewById(R.id.save_pg_btn);
savePGC.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
saveSettings(mPrefs);
}
});
Button importPGC = (Button) getView().findViewById(R.id.import_pg_btn);
importPGC.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
try {
File xml = new File("/data/data/"
+ getActivity().getPackageName(),"/shared_prefs/");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
xml = new File(getActivity().getDataDir(),
"/shared_prefs/" + gameId + ".xml");
}
copy(new File(getActivity().getExternalFilesDir(null),
gameId + ".xml"), xml);
showToastMessage(getActivity().getString(
R.string.pgconfig_imported), Snackbar.LENGTH_SHORT);
configureViewByGame(gameId);
} catch (Exception e) {
e.printStackTrace();
}
}
});
Button exportPGC = (Button) getView().findViewById(R.id.export_pg_btn);
exportPGC.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
try {
File xml = new File("/data/data/"
+ getActivity().getPackageName(),"/shared_prefs/");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
xml = new File(getActivity().getDataDir(),
"/shared_prefs/" + gameId + ".xml");
}
copy(xml, new File(getActivity().getExternalFilesDir(null),
gameId + ".xml"));
showToastMessage(getActivity().getString(
R.string.pgconfig_exported), Snackbar.LENGTH_SHORT);
} catch (Exception e) {
e.printStackTrace();
}
}
});
Button clearPGC = (Button) getView().findViewById(R.id.clear_pg_btn);
clearPGC.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
clearSettings(mPrefs, gameId);
}
});
}
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 static class LocateConfigs extends AsyncTask<String, Integer, List<File>> {
private WeakReference<PGConfigFragment> options;
LocateConfigs(PGConfigFragment context) {
options = new WeakReference<>(context);
}
@Override
protected List<File> doInBackground(String... paths) {
File storage = new File(paths[0]);
Log.d("Files", storage.getAbsolutePath());
FilenameFilter[] filter = new FilenameFilter[1];
filter[0] = new FilenameFilter() {
public boolean accept(File dir, String name) {
return !name.endsWith("_preferences.xml");
}
};
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()) {
final Map<String, String> gameMap = new HashMap<>();
String[] titles = new String[items.size()];
for (int i = 0; i < items.size(); i ++) {
String filename = items.get(i).getName();
String gameFile = filename.substring(0, filename.length() - 4);
SharedPreferences mPrefs = options.get().getActivity()
.getSharedPreferences(gameFile, Activity.MODE_PRIVATE);
titles[i] = mPrefs.getString(Config.game_title, "Title Unavailable");
gameMap.put(titles[i], gameFile);
}
ArrayAdapter<String> configAdapter = new ArrayAdapter<String>(
options.get().getActivity(), android.R.layout.simple_spinner_item, titles);
configAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
options.get().mSpnrConfigs.setAdapter(configAdapter);
options.get().mSpnrConfigs.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View select, int pos, long id) {
options.get().configureViewByGame(gameMap.get(
String.valueOf(parent.getItemAtPosition(pos))
));
}
@Override
public void onNothingSelected(AdapterView<?> parentView) {
}
});
} else {
options.get().mSpnrConfigs.setEnabled(false);
}
}
}
private void hideSoftKeyBoard() {
InputMethodManager iMm = (InputMethodManager) getActivity()
.getSystemService(Context.INPUT_METHOD_SERVICE);
if (iMm != null && iMm.isAcceptingText()) {
iMm.hideSoftInputFromWindow(getActivity().getCurrentFocus().getWindowToken(), 0);
}
}
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();
}
}

View File

@ -3,8 +3,8 @@ package com.reicast.emulator.debug;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Build;
import android.support.constraint.ConstraintLayout;
@ -13,7 +13,6 @@ import android.support.graphics.drawable.VectorDrawableCompat;
import android.view.Gravity;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
import com.reicast.emulator.R;
import com.reicast.emulator.config.Config;
@ -26,34 +25,34 @@ import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.ref.WeakReference;
public class GenerateLogs extends AsyncTask<String, Integer, String> {
private WeakReference<Context> mContext;
public static final String build_model = android.os.Build.MODEL;
public static final String build_device = android.os.Build.DEVICE;
public static final String build_board = android.os.Build.BOARD;
public static final int build_sdk = android.os.Build.VERSION.SDK_INT;
private static final String build_device = android.os.Build.DEVICE;
private static final String build_board = android.os.Build.BOARD;
private static final int build_sdk = android.os.Build.VERSION.SDK_INT;
public static final String DN = "Donut";
public static final String EC = "Eclair";
public static final String FR = "Froyo";
public static final String GB = "Gingerbread";
public static final String HC = "Honeycomb";
public static final String IC = "Ice Cream Sandwich";
public static final String JB = "JellyBean";
public static final String KK = "KitKat";
public static final String LP = "L Preview";
public static final String LL = "Lollipop";
public static final String NL = "New / No Label";
public static final String NF = "Not Found";
private static final String DN = "Donut";
private static final String EC = "Eclair";
private static final String FR = "Froyo";
private static final String GB = "Gingerbread";
private static final String HC = "Honeycomb";
private static final String IC = "Ice Cream Sandwich";
private static final String JB = "JellyBean";
private static final String KK = "KitKat";
private static final String LL = "Lollipop";
private static final String MM = "Marshmallow";
private static final String NT = "Nougat";
private static final String NL = "New / No Label";
private static final String NF = "Not Found";
private String currentTime;
private String unHandledIOE;
private Context mContext;
private String currentTime;
public GenerateLogs(Context mContext) {
this.mContext = mContext;
public GenerateLogs(Context reference) {
this.mContext = new WeakReference<>(reference);
this.currentTime = String.valueOf(System.currentTimeMillis());
}
@ -68,7 +67,7 @@ public class GenerateLogs extends AsyncTask<String, Integer, String> {
s += "\r\n";
s += "BOARD: " + build_board;
s += "\r\n";
if (String.valueOf(build_sdk) != null) {
if (!String.valueOf(build_sdk).equals("")) {
String build_version = NF;
if (String.valueOf(build_sdk).equals("L")) {
build_version = "LP";
@ -88,9 +87,13 @@ public class GenerateLogs extends AsyncTask<String, Integer, String> {
build_version = JB;
} else if (build_sdk >= 19 && build_sdk < 21) {
build_version = KK;
} else if (build_sdk >= 21 && build_sdk < 22) {
} else if (build_sdk >= 21 && build_sdk < 23) {
build_version = LL;
} else if (build_sdk >= 22) {
} else if (build_sdk >= 23 && build_sdk < 24) {
build_version = MM;
} else if (build_sdk >= 24 && build_sdk < 26) {
build_version = NT;
} else if (build_sdk >= 26) {
build_version = NL;
}
s += build_version + " (" + build_sdk + ")";
@ -152,40 +155,7 @@ public class GenerateLogs extends AsyncTask<String, Integer, String> {
log.append(unHandledIOE);
}
try {
mLogcatProc = Runtime.getRuntime().exec(
new String[] { "logcat", "-ds", "AndroidRuntime:E" });
reader = new BufferedReader(new InputStreamReader(
mLogcatProc.getInputStream()));
String line;
log.append(separator);
log.append(separator);
log.append("AndroidRuntime Output");
log.append(separator);
log.append(separator);
while ((line = reader.readLine()) != null) {
log.append(line);
log.append(separator);
}
reader.close();
mLogcatProc = null;
reader = null;
int PID = android.os.Process.getUidForName("com.reicast.emulator");
mLogcatProc = Runtime.getRuntime().exec(
new String[] { "logcat", "-d", "|", "grep " + PID });
reader = new BufferedReader(new InputStreamReader(
mLogcatProc.getInputStream()));
log.append(separator);
log.append(separator);
log.append("Application Core Output");
log.append(separator);
log.append(separator);
while ((line = reader.readLine()) != null) {
log.append(line);
log.append(separator);
}
reader.close();
mLogcatProc = null;
reader = null;
mLogcatProc = Runtime.getRuntime().exec(
new String[] { "logcat", "-ds", "reicast:V" });
reader = new BufferedReader(new InputStreamReader(
@ -200,25 +170,7 @@ public class GenerateLogs extends AsyncTask<String, Integer, String> {
log.append(separator);
}
reader.close();
mLogcatProc = null;
reader = null;
mLogcatProc = Runtime.getRuntime().exec(
new String[] { "logcat", "-ds", "GL2JNIView:E" });
reader = new BufferedReader(new InputStreamReader(
mLogcatProc.getInputStream()));
log.append(separator);
log.append(separator);
log.append("Open GLES View Output");
log.append(separator);
log.append(separator);
while ((line = reader.readLine()) != null) {
log.append(line);
log.append(separator);
}
reader.close();
mLogcatProc = null;
reader = null;
File memory = new File(mContext.getFilesDir(), "mem_alloc.txt");
File memory = new File(mContext.get().getFilesDir(), "mem_alloc.txt");
if (memory.exists()) {
log.append(separator);
log.append(separator);
@ -232,9 +184,7 @@ public class GenerateLogs extends AsyncTask<String, Integer, String> {
log.append(separator);
}
fis.close();
fis = null;
reader.close();
reader = null;
}
BufferedWriter writer = new BufferedWriter(new FileWriter(logFile));
writer.write(log.toString());
@ -242,7 +192,8 @@ public class GenerateLogs extends AsyncTask<String, Integer, String> {
writer.close();
return log.toString();
} catch (IOException e) {
// Could not generate log file
// Writing a log is redundant
}
return null;
}
@ -250,19 +201,19 @@ public class GenerateLogs extends AsyncTask<String, Integer, String> {
@Override
protected void onPostExecute(final String response) {
if (response != null) {
showToastMessage(mContext.getString(R.string.log_saved), Snackbar.LENGTH_LONG);
android.content.ClipboardManager clipboard = (android.content.ClipboardManager) mContext
showToastMessage(mContext.get().getString(R.string.log_saved), Snackbar.LENGTH_LONG);
android.content.ClipboardManager clipboard = (android.content.ClipboardManager) mContext.get()
.getSystemService(Context.CLIPBOARD_SERVICE);
android.content.ClipData clip = android.content.ClipData.newPlainText("logcat", response);
clipboard.setPrimaryClip(clip);
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(Config.git_issues));
mContext.startActivity(browserIntent);
mContext.get().startActivity(browserIntent);
}
}
private void showToastMessage(String message, int duration) {
ConstraintLayout layout = (ConstraintLayout)
((Activity) mContext).findViewById(R.id.mainui_layout);
((Activity) mContext.get()).findViewById(R.id.mainui_layout);
Snackbar snackbar = Snackbar.make(layout, message, duration);
View snackbarLayout = snackbar.getView();
ConstraintLayout.LayoutParams lp = new ConstraintLayout.LayoutParams(
@ -278,14 +229,14 @@ public class GenerateLogs extends AsyncTask<String, Integer, String> {
textView.setTextAlignment(View.TEXT_ALIGNMENT_GRAVITY);
Drawable drawable;
if (android.os.Build.VERSION.SDK_INT > Build.VERSION_CODES.M) {
drawable = mContext.getResources().getDrawable(
R.drawable.ic_send, ((Activity) mContext).getTheme());
drawable = mContext.get().getResources().getDrawable(
R.drawable.ic_send, ((Activity) mContext.get()).getTheme());
} else {
drawable = VectorDrawableCompat.create(mContext.getResources(),
R.drawable.ic_send, ((Activity) mContext).getTheme());
drawable = VectorDrawableCompat.create(mContext.get().getResources(),
R.drawable.ic_send, ((Activity) mContext.get()).getTheme());
}
textView.setCompoundDrawablesWithIntrinsicBounds(drawable, null, null, null);
textView.setCompoundDrawablePadding(mContext.getResources()
textView.setCompoundDrawablePadding(mContext.get().getResources()
.getDimensionPixelOffset(R.dimen.snackbar_icon_padding));
snackbar.show();
}

View File

@ -34,13 +34,11 @@ import java.util.HashMap;
public class GitAdapter extends BaseAdapter {
private static Activity activity;
private ArrayList<HashMap<String, String>> data;
private LayoutInflater inflater = null;
private DisplayImageOptions options;
public GitAdapter(Activity a, ArrayList<HashMap<String, String>> d) {
activity = a;
public GitAdapter(Activity activity, ArrayList<HashMap<String, String>> d) {
this.data = d;
this.inflater = (LayoutInflater) activity
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
@ -88,7 +86,7 @@ public class GitAdapter extends BaseAdapter {
final String current = commit.get("Build");
RelativeLayout item = (RelativeLayout) vi.findViewById(R.id.change);
if (current != null && !current.equals("") && current.equals(sha)) {
if (current != null && current.equals(sha.substring(0, 7))) {
item.getBackground().setColorFilter(0xFF00FF00,
PorterDuff.Mode.MULTIPLY);
} else {
@ -98,8 +96,7 @@ public class GitAdapter extends BaseAdapter {
dateText.setText(date);
committerText.setText(committer);
titleText.setText(title);
ImageLoader.getInstance()
.displayImage(avatar, avatarIcon, this.options);
ImageLoader.getInstance().displayImage(avatar, avatarIcon, this.options);
vi.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
@ -141,16 +138,10 @@ public class GitAdapter extends BaseAdapter {
WebView mWebView) {
mWebView.getSettings().setSupportZoom(true);
mWebView.getSettings().setBuiltInZoomControls(true);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
mWebView.getSettings().setDisplayZoomControls(false);
}
mWebView.setInitialScale(1);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ECLAIR) {
mWebView.getSettings().setUseWideViewPort(true);
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ECLAIR_MR1) {
mWebView.getSettings().setLoadWithOverviewMode(true);
}
mWebView.getSettings().setJavaScriptEnabled(true);
mWebView.getSettings().setPluginState(PluginState.ON);
mWebView.getSettings().setCacheMode(WebSettings.LOAD_NO_CACHE);

View File

@ -17,13 +17,11 @@ 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.MotionEvent;
import android.view.ScaleGestureDetector;
import android.view.ScaleGestureDetector.SimpleOnScaleGestureListener;
import android.view.View;
import android.view.WindowManager;
import android.widget.Toast;
import com.android.util.FileUtils;
@ -32,6 +30,7 @@ import com.reicast.emulator.GL2JNIActivity;
import com.reicast.emulator.GL2JNINative;
import com.reicast.emulator.config.Config;
import com.reicast.emulator.emu.OnScreenMenu.FpsPopup;
import com.reicast.emulator.periph.Gamepad;
import com.reicast.emulator.periph.VJoy;
import java.io.UnsupportedEncodingException;
@ -67,13 +66,9 @@ public class GL2JNIView extends GLSurfaceView
public static final int LAYER_TYPE_HARDWARE = 2;
private static String fileName;
//private AudioThread audioThread;
private EmuThread ethd;
private Handler handler = new Handler();
private static int sWidth;
private static int sHeight;
Vibrator vib;
private boolean editVjoyMode = false;
@ -111,8 +106,8 @@ public class GL2JNIView extends GLSurfaceView
}
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public GL2JNIView(Context context, String newFileName,
boolean translucent, int depth, int stencil, boolean editVjoyMode) {
public GL2JNIView(Context context, String newFileName, boolean translucent,
int depth, int stencil, boolean editVjoyMode) {
super(context);
this.context = context;
this.editVjoyMode = editVjoyMode;
@ -136,14 +131,6 @@ public class GL2JNIView extends GLSurfaceView
vib = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
DisplayMetrics metrics = new DisplayMetrics();
//((Activity) context).getWindowManager().getDefaultDisplay().getMetrics(metrics);
((WindowManager) context.getSystemService(Context.WINDOW_SERVICE))
.getDefaultDisplay().getMetrics(metrics);
final float scale = context.getResources().getDisplayMetrics().density;
sWidth = (int) (metrics.widthPixels * scale + 0.5f);
sHeight = (int) (metrics.heightPixels * scale + 0.5f);
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
JNIdc.config(prefs.getString(Config.pref_home,
@ -170,8 +157,8 @@ public class GL2JNIView extends GLSurfaceView
if (GL2JNIActivity.syms != null)
JNIdc.data(1, GL2JNIActivity.syms);
}
JNIdc.init(fileName);
JNIdc.query(ethd);
// By default, GLSurfaceView() creates a RGB_565 opaque surface.
// If we want a translucent one, we should change the surface's
@ -190,7 +177,8 @@ public class GL2JNIView extends GLSurfaceView
// our surface exactly. This is going to be done in our
// custom config chooser. See ConfigChooser class definition
// below.
setEGLConfigChooser(new GLCFactory.ConfigChooser(8, 8, 8, translucent ? 8 : 0, depth, stencil));
setEGLConfigChooser(new GLCFactory.ConfigChooser(
8, 8, 8, translucent ? 8 : 0, depth, stencil));
// Set the renderer responsible for frame rendering
setRenderer(rend = new Renderer(this));
@ -390,9 +378,8 @@ public class GL2JNIView extends GLSurfaceView
JNIdc.vjoy(j+1, vjoy[j+1][0], vjoy[j+1][1] , vjoy[j+1][2], vjoy[j+1][3]);
anal_id=event.getPointerId(i);
}
}
else if (vjoy[j][4]==-4);
else if(vjoy[j][4]==-1) {
} else if (vjoy[j][4] != -4) {
if (vjoy[j][4] == -1) {
if (editVjoyMode) {
selectedVjoyElement = 3; // Left Trigger
resetEditMode();
@ -400,8 +387,7 @@ public class GL2JNIView extends GLSurfaceView
lt[0] = pre;
lt_id = event.getPointerId(i);
}
}
else if (vjoy[j][4]==-2) {
} else if (vjoy[j][4] == -2) {
if (editVjoyMode) {
selectedVjoyElement = 4; // Right Trigger
resetEditMode();
@ -409,8 +395,7 @@ public class GL2JNIView extends GLSurfaceView
rt[0] = pre;
rt_id = event.getPointerId(i);
}
}
else {
} else {
if (editVjoyMode) {
selectedVjoyElement = getElementIdFromButtonId(j);
resetEditMode();
@ -421,8 +406,7 @@ public class GL2JNIView extends GLSurfaceView
}
}
}
else
{
} else {
if (x<vjoy[11][0])
x=vjoy[11][0];
else if (x>(vjoy[11][0]+vjoy[11][2]))
@ -528,7 +512,7 @@ public class GL2JNIView extends GLSurfaceView
private FPSCounter fps = new FPSCounter();
private FpsPopup fpsPop;
public Renderer (GL2JNIView mView) {
Renderer (GL2JNIView mView) {
this.mView = mView;
}
@ -547,7 +531,11 @@ public class GL2JNIView extends GLSurfaceView
public void onSurfaceChanged(GL10 gl,int width,int height)
{
gl.glViewport(0, 0, width, height);
if (Emulator.widescreen) {
JNIdc.rendinit(width, height);
} else {
JNIdc.rendinit(height * (4 / 3), height);
}
}
public void onSurfaceCreated(GL10 gl,EGLConfig config)
@ -555,11 +543,11 @@ public class GL2JNIView extends GLSurfaceView
onSurfaceChanged(gl, 800, 480);
}
public class FPSCounter {
class FPSCounter {
long startTime = System.nanoTime();
int frames = 0;
public void logFrame() {
void logFrame() {
frames++;
if (System.nanoTime() - startTime >= 1000000000) {
mView.post(new Runnable() {
@ -599,7 +587,7 @@ public class GL2JNIView extends GLSurfaceView
long size; //size in frames
private boolean sound;
public EmuThread(boolean sound) {
EmuThread(boolean sound) {
this.sound = sound;
}
@ -658,19 +646,20 @@ public class GL2JNIView extends GLSurfaceView
void showMessage(final String msg) {
handler.post(new Runnable() {
public void run() {
Log.d(context.getApplicationContext().getPackageName(), msg);
Log.d(context.getPackageName(), msg);
Toast.makeText(context, msg, Toast.LENGTH_SHORT).show();
}
});
}
void coreMessage(byte[] msg) {
int coreMessage(byte[] msg) {
try {
showMessage(new String(msg, "UTF-8"));
}
catch (UnsupportedEncodingException e) {
showMessage("coreMessage: Failed to display error");
}
return 1;
}
void Die() {
@ -678,6 +667,23 @@ public class GL2JNIView extends GLSurfaceView
((Activity) context).finish();
}
void reiosInfo(String reiosId, String reiosSoftware) {
if (fileName != null) {
String gameId = reiosId.replaceAll("[^a-zA-Z0-9]+", "").toLowerCase();
SharedPreferences mPrefs = context.getSharedPreferences(gameId, Activity.MODE_PRIVATE);
Emulator app = (Emulator) context.getApplicationContext();
app.loadGameConfiguration(gameId);
if (context instanceof GL2JNIActivity)
((GL2JNIActivity) context).getPad().joystick[0] = mPrefs.getBoolean(
Gamepad.pref_js_merged + "_A",
((GL2JNIActivity) context).getPad().joystick[0]);
if (context instanceof GL2JNINative)
((GL2JNINative) context).getPad().joystick[0] = mPrefs.getBoolean(
Gamepad.pref_js_merged + "_A",
((GL2JNINative) context).getPad().joystick[0]);
mPrefs.edit().putString(Config.game_title, reiosSoftware.trim()).apply();
}
}
}
public void onDestroy() {

View File

@ -161,7 +161,7 @@ public class GLCFactory14 {
if (r == mRedSize && g == mGreenSize && b == mBlueSize
&& a == mAlphaSize)
if (GL2JNIView.DEBUG) {
LOGW(String.format("Configuration %d:", i));
LOGW(String.format(Locale.ENGLISH, "Configuration %d:", i));
printConfig(display, configs[i]);
}
return config;

View File

@ -7,6 +7,7 @@ public final class JNIdc
public static native void config(String dirName);
public static native void init(String fileName);
public static native void query(Object thread);
public static native void run(Object track);
public static native void pause();
public static native void destroy();
@ -22,7 +23,7 @@ public final class JNIdc
public static native void vjoy(int id,float x, float y, float w, float h);
//public static native int play(short result[],int size);
public static native void initControllers(boolean[] controllers);
public static native void initControllers(boolean[] controllers, int[][] peripherals);
public static native void setupMic(Object sip);
public static native void diskSwap(String disk);
@ -31,12 +32,14 @@ public final class JNIdc
public static native void dynarec(int dynarec);
public static native void idleskip(int idleskip);
public static native void unstable(int unstable);
public static native void safemode(int safemode);
public static native void cable(int cable);
public static native void region(int region);
public static native void broadcast(int broadcast);
public static native void limitfps(int limiter);
public static native void nobatch(int nobatch);
public static native void nosound(int noaudio);
public static native void delayinterrupt(int delayed);
public static native void mipmaps(int mipmaps);
public static native void widescreen(int stretch);
public static native void subdivide(int subdivide);

View File

@ -1,12 +1,12 @@
package com.reicast.emulator.emu;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.Environment;
import android.view.Gravity;
import android.view.View;
import android.view.View.OnClickListener;
@ -25,7 +25,6 @@ import com.reicast.emulator.R;
import com.reicast.emulator.config.Config;
import com.reicast.emulator.periph.VmuLcd;
import java.io.File;
import java.util.Vector;
public class OnScreenMenu {
@ -46,12 +45,12 @@ public class OnScreenMenu {
public OnScreenMenu(Activity context, SharedPreferences prefs) {
if (context instanceof GL2JNINative) {
this.mContext = (GL2JNINative) context;
this.mContext = context;
}
if (context instanceof GL2JNIActivity) {
this.mContext = (GL2JNIActivity) context;
this.mContext = context;
}
popups = new Vector<PopupWindow>();
popups = new Vector<>();
if (prefs != null) {
masteraudio = !Emulator.nosound;
audio = masteraudio;
@ -70,7 +69,7 @@ public class OnScreenMenu {
});
}
void displayDebugPopup(final PopupWindow popUp) {
private void displayDebugPopup() {
if (mContext instanceof GL2JNINative) {
((GL2JNINative) mContext).displayDebug(new DebugPopup(mContext));
}
@ -116,8 +115,9 @@ public class OnScreenMenu {
public class DebugPopup extends PopupWindow {
public DebugPopup(Context c) {
DebugPopup(Context c) {
super(c);
//noinspection deprecation
setBackgroundDrawable(new BitmapDrawable());
View shell = mContext.getLayoutInflater().inflate(R.layout.menu_popup_debug, null);
@ -173,7 +173,7 @@ public class OnScreenMenu {
}
}
void displayConfigPopup(final PopupWindow popUp) {
private void displayConfigPopup() {
if (mContext instanceof GL2JNINative) {
((GL2JNINative) mContext).displayConfig(new ConfigPopup(mContext));
}
@ -191,8 +191,9 @@ public class OnScreenMenu {
private Button fdown;
private Button fup;
public ConfigPopup(Context c) {
ConfigPopup(Context c) {
super(c);
//noinspection deprecation
setBackgroundDrawable(new BitmapDrawable());
View shell = mContext.getLayoutInflater().inflate(R.layout.menu_popup_config, null);
@ -473,6 +474,7 @@ public class OnScreenMenu {
private LinearLayout vmuIcon;
LinearLayout.LayoutParams params;
@SuppressLint("RtlHardcoded")
private LinearLayout.LayoutParams setVmuParams() {
int vpX = getPixelsFromDp(72, mContext);
int vpY = getPixelsFromDp(52, mContext);
@ -486,6 +488,7 @@ public class OnScreenMenu {
public MainPopup(Context c) {
super(c);
//noinspection deprecation
setBackgroundDrawable(new BitmapDrawable());
View shell = mContext.getLayoutInflater().inflate(R.layout.menu_popup_main, null);
@ -498,6 +501,7 @@ public class OnScreenMenu {
OnClickListener clickDisk = new OnClickListener() {
public void onClick(View v) {
if (Emulator.bootdisk != null)
JNIdc.diskSwap(null);
dismiss();
}
@ -516,7 +520,7 @@ public class OnScreenMenu {
OnClickListener clickOptions = new OnClickListener() {
public void onClick(View v) {
displayConfigPopup(MainPopup.this);
displayConfigPopup();
popups.remove(MainPopup.this);
dismiss();
}
@ -526,7 +530,7 @@ public class OnScreenMenu {
OnClickListener clickDebugging = new OnClickListener() {
public void onClick(View v) {
displayDebugPopup(MainPopup.this);
displayDebugPopup();
popups.remove(MainPopup.this);
dismiss();
}
@ -553,11 +557,11 @@ public class OnScreenMenu {
OnClickListener clickExit = new OnClickListener() {
public void onClick(View v) {
if (Config.externalIntent) {
((Activity) mContext).finish();
mContext.finish();
} else {
Intent inte = new Intent(mContext, MainActivity.class);
mContext.startActivity(inte);
((Activity) mContext).finish();
mContext.finish();
}
}
};

View File

@ -5,7 +5,6 @@ import android.content.Context;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.os.Build;
import android.util.SparseArray;
import android.util.SparseIntArray;
import android.view.KeyEvent;
@ -21,12 +20,18 @@ public class Gamepad {
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";
public static final String pref_pad = "controller";
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_rbuttons = "right_buttons";
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";
@ -41,6 +46,9 @@ public class Gamepad {
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";
@ -48,6 +56,8 @@ public class Gamepad {
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 };
@ -62,9 +72,6 @@ public class Gamepad {
public SparseArray<String> deviceId_deviceDescriptor = new SparseArray<>();
public HashMap<String, Integer> deviceDescriptor_PlayerNum = new HashMap<>();
public boolean isActiveMoga[] = { false, false, false, false };
public boolean isMogaPro[] = { false, false, false, false };
public SparseIntArray playerNumX = new SparseIntArray();
public boolean isOuyaOrTV;
@ -72,15 +79,15 @@ public class Gamepad {
public static final int Xperia_Touchpad = 1048584;
public static final int key_CONT_B = 0x0002;
public static final int key_CONT_A = 0x0004;
public static final int key_CONT_START = 0x0008;
public static final int key_CONT_DPAD_UP = 0x0010;
public static final int key_CONT_DPAD_DOWN = 0x0020;
public static final int key_CONT_DPAD_LEFT = 0x0040;
public static final int key_CONT_DPAD_RIGHT = 0x0080;
public static final int key_CONT_Y = 0x0200;
public static final int key_CONT_X = 0x0400;
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[] {
@ -134,7 +141,7 @@ public class Gamepad {
};
}
public int[] setModifiedKeys(String id, int playerNum, SharedPreferences mPrefs) {
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,
@ -151,18 +158,26 @@ public class Gamepad {
};
}
public boolean IsOuyaOrTV(Context context) {
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();
}
}
public int getStartButtonCode() {
private int getStartButtonCode() {
return KeyEvent.KEYCODE_BUTTON_START;
}
@ -177,7 +192,7 @@ public class Gamepad {
}
public void setCustomMapping(String id, int playerNum, SharedPreferences prefs) {
map[playerNum] = setModifiedKeys(id, playerNum, prefs);
map[playerNum] = setModifiedKeys(id, prefs);
}
public void initJoyStickLayout(int playerNum) {
@ -187,27 +202,21 @@ public class Gamepad {
}
}
public void runCompatibilityMode(int joy, SharedPreferences prefs) {
for (int n = 0; n < 4; n++) {
if (compat[n]) {
String id = portId[n];
joystick[n] = prefs.getBoolean(Gamepad.pref_js_merged + id, false);
getCompatibilityMap(n, portId[n], prefs);
initJoyStickLayout(n);
}
}
}
public void fullCompatibilityMode(SharedPreferences prefs) {
for (int n = 0; n < 4; n++) {
runCompatibilityMode(n, 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, playerNum, prefs);
map[playerNum] = setModifiedKeys(id, prefs);
}
}
}

View File

@ -1,224 +0,0 @@
package com.reicast.emulator.periph;
/******************************************************************************/
import android.app.Activity;
import android.content.SharedPreferences;
import android.os.Build;
import android.os.Handler;
import android.preference.PreferenceManager;
import android.util.Log;
import com.bda.controller.Controller;
import com.bda.controller.ControllerListener;
import com.bda.controller.KeyEvent;
import com.bda.controller.MotionEvent;
import com.bda.controller.StateEvent;
import com.reicast.emulator.GL2JNIActivity;
import com.reicast.emulator.GL2JNINative;
import com.reicast.emulator.R;
import java.util.Arrays;
/******************************************************************************/
/*
*/
public final class MOGAInput
{
private SharedPreferences prefs;
static final int DELAY = 1000 / 50; // 50 Hz
public static final int ACTION_CONNECTED = Controller.ACTION_CONNECTED;
static final int ACTION_DISCONNECTED = Controller.ACTION_DISCONNECTED;
static final int ACTION_VERSION_MOGA = Controller.ACTION_VERSION_MOGA;
static final int ACTION_VERSION_MOGAPRO = Controller.ACTION_VERSION_MOGAPRO;
public Controller mController = null;
public ExampleControllerListener mListener;
private String notify;
private Gamepad pad;
private Activity act;
public MOGAInput()
{
/*
mStates.put(StateEvent.STATE_CONNECTION, new ExampleInteger("STATE_CONNECTION......"));
mStates.put(StateEvent.STATE_POWER_LOW, new ExampleInteger("STATE_POWER_LOW......"));
mStates.put(StateEvent.STATE_CURRENT_PRODUCT_VERSION, new ExampleInteger("STATE_CURRENT_PRODUCT_VERSION"));
mStates.put(StateEvent.STATE_SUPPORTED_PRODUCT_VERSION, new ExampleInteger("STATE_SUPPORTED_PRODUCT_VERSION"));
mKeys.put(KeyEvent.KEYCODE_DPAD_UP, new ExampleInteger("KEYCODE_DPAD_UP......"));
mKeys.put(KeyEvent.KEYCODE_DPAD_DOWN, new ExampleInteger("KEYCODE_DPAD_DOWN......"));
mKeys.put(KeyEvent.KEYCODE_DPAD_LEFT, new ExampleInteger("KEYCODE_DPAD_LEFT......"));
mKeys.put(KeyEvent.KEYCODE_DPAD_RIGHT, new ExampleInteger("KEYCODE_DPAD_RIGHT......"));
mKeys.put(KeyEvent.KEYCODE_BUTTON_A, new ExampleInteger("KEYCODE_BUTTON_A......"));
mKeys.put(KeyEvent.KEYCODE_BUTTON_B, new ExampleInteger("KEYCODE_BUTTON_B......"));
mKeys.put(KeyEvent.KEYCODE_BUTTON_X, new ExampleInteger("KEYCODE_BUTTON_X......"));
mKeys.put(KeyEvent.KEYCODE_BUTTON_Y, new ExampleInteger("KEYCODE_BUTTON_Y......"));
mKeys.put(KeyEvent.KEYCODE_BUTTON_L1, new ExampleInteger("KEYCODE_BUTTON_L1......"));
mKeys.put(KeyEvent.KEYCODE_BUTTON_R1, new ExampleInteger("KEYCODE_BUTTON_R1......"));
mKeys.put(KeyEvent.KEYCODE_BUTTON_L2, new ExampleInteger("KEYCODE_BUTTON_L2......"));
mKeys.put(KeyEvent.KEYCODE_BUTTON_R2, new ExampleInteger("KEYCODE_BUTTON_R2......"));
mKeys.put(KeyEvent.KEYCODE_BUTTON_THUMBL, new ExampleInteger("KEYCODE_BUTTON_THUMBL......"));
mKeys.put(KeyEvent.KEYCODE_BUTTON_THUMBR, new ExampleInteger("KEYCODE_BUTTON_THUMBR......"));
mKeys.put(KeyEvent.KEYCODE_BUTTON_START, new ExampleInteger("KEYCODE_BUTTON_START......"));
mKeys.put(KeyEvent.KEYCODE_BUTTON_SELECT, new ExampleInteger("KEYCODE_BUTTON_SELECT......"));
mMotions.put(MotionEvent.AXIS_X, new ExampleFloat("AXIS_X........."));
mMotions.put(MotionEvent.AXIS_Y, new ExampleFloat("AXIS_Y........."));
mMotions.put(MotionEvent.AXIS_Z, new ExampleFloat("AXIS_Z........."));
mMotions.put(MotionEvent.AXIS_RZ, new ExampleFloat("AXIS_RZ......."));
mMotions.put(MotionEvent.AXIS_LTRIGGER, new ExampleFloat("AXIS_LTRIGGER........."));
mMotions.put(MotionEvent.AXIS_RTRIGGER, new ExampleFloat("AXIS_RTRIGGER........."));
*/
}
public void onCreate(Activity act, Gamepad pad) {
this.act = act;
this.pad = pad;
prefs = PreferenceManager
.getDefaultSharedPreferences(act.getApplicationContext());
mController = Controller.getInstance(act);
// mController.init();
MogaHack.init(mController, this.act);
mListener = new ExampleControllerListener();
mController.setListener(mListener, new Handler());
}
public void onDestroy()
{
mController.exit();
}
public void onPause()
{
mController.onPause();
}
public void onResume()
{
mController.onResume();
/*
for(final Entry<Integer, ExampleInteger> entry : mStates.entrySet())
{
final int key = entry.getKey();
final ExampleInteger value = entry.getValue();
value.mValue = mController.getState(key);
}
for(final Entry<Integer, ExampleInteger> entry : mKeys.entrySet())
{
final int key = entry.getKey();
final ExampleInteger value = entry.getValue();
value.mValue = mController.getKeyCode(key);
}
for(final Entry<Integer, ExampleFloat> entry : mMotions.entrySet())
{
final int key = entry.getKey();
final ExampleFloat value = entry.getValue();
value.mValue = mController.getAxisValue(key);
}
*/
}
public class ExampleControllerListener implements ControllerListener
{
int playerNum;
public void setPlayerNum(int playerNum) {
this.playerNum = playerNum;
}
public void onKeyEvent(KeyEvent event)
{
boolean keydown = false;
if (event.getAction() == KeyEvent.ACTION_DOWN) {
keydown = true;
}
if (act instanceof GL2JNIActivity) {
((GL2JNIActivity) act).handle_key(playerNum, event.getKeyCode(), keydown);
}
if (act instanceof GL2JNINative) {
((GL2JNINative) act).handle_key(playerNum, event.getKeyCode(), keydown);
}
}
public void onMotionEvent(MotionEvent event)
{
if (act instanceof GL2JNIActivity) {
((GL2JNIActivity) act).motionEventHandler(playerNum, event);
}
if (act instanceof GL2JNINative) {
((GL2JNINative) act).motionEventHandler(playerNum, event);
}
}
private void getCompatibilityMap(int playerNum, String id) {
pad.name[playerNum] = prefs.getInt("controller" + id, -1);
if (pad.name[playerNum] != -1) {
pad.map[playerNum] = pad.setModifiedKeys(id, playerNum, prefs);
}
}
private void initJoyStickLayout(int playerNum) {
pad.globalLS_X[playerNum] = pad.previousLS_X[playerNum] = 0.0f;
pad.globalLS_Y[playerNum] = pad.previousLS_Y[playerNum] = 0.0f;
}
private void notifyMogaConnected(final String notify, int playerNum) {
String id = pad.portId[playerNum];
pad.custom[playerNum] = prefs.getBoolean("modified_key_layout" + id, false);
pad.compat[playerNum] = prefs.getBoolean("controller_compat" + id, false);
pad.joystick[playerNum] = prefs.getBoolean("separate_joystick" + id, false);
if (pad.compat[playerNum]) {
getCompatibilityMap(playerNum, id);
} else if (pad.custom[playerNum]) {
pad.map[playerNum] = pad.setModifiedKeys(id, playerNum, prefs);
} else {
pad.map[playerNum] = pad.getMogaController();
}
initJoyStickLayout(playerNum);
}
public void onStateEvent(StateEvent event)
{
Integer playerNum = Arrays.asList(pad.name).indexOf(event.getControllerId());
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD && playerNum == -1) {
playerNum = pad.deviceDescriptor_PlayerNum
.get(pad.deviceId_deviceDescriptor.get(event.getControllerId()));
} else {
playerNum = -1;
}
if (playerNum == null || playerNum == -1) {
return;
}
if (event.getState() == StateEvent.STATE_CONNECTION && event.getAction() == ACTION_CONNECTED) {
int mControllerVersion = mController.getState(Controller.STATE_CURRENT_PRODUCT_VERSION);
if (mControllerVersion == Controller.ACTION_VERSION_MOGAPRO) {
pad.isMogaPro[playerNum] = true;
pad.isActiveMoga[playerNum] = true;
Log.d("com.reicast.emulator", act.getString(R.string.moga_pro_connect));
} else if (mControllerVersion == Controller.ACTION_VERSION_MOGA) {
pad.isMogaPro[playerNum] = false;
pad.isActiveMoga[playerNum] = true;
Log.d("com.reicast.emulator", act.getString(R.string.moga_connect));
}
if (pad.isActiveMoga[playerNum]) {
notifyMogaConnected(notify, playerNum);
}
}
}
}
}

View File

@ -1,118 +0,0 @@
/**
* Mupen64PlusAE, an N64 emulator for the Android platform
*
* Copyright (C) 2013 Paul Lamb
*
* This file is part of Mupen64PlusAE.
*
* Mupen64PlusAE is free software: you can redistribute it and/or modify it under the terms of the
* GNU General Public License as published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* Mupen64PlusAE is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with Mupen64PlusAE. If
* not, see <http://www.gnu.org/licenses/>.
*
* Authors: Paul Lamb
*/
package com.reicast.emulator.periph;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
import android.os.Build;
import android.util.Log;
import com.bda.controller.Controller;
import com.bda.controller.IControllerService;
import java.util.List;
/**
* Temporary hack for crash in MOGA library on Lollipop. This hack can be removed once MOGA fixes
* their library. The actual issue is caused by the use of implicit service intents, which are
* illegal in Lollipop, as seen in the logcat message below.
*
* <pre>
* {@code Service Intent must be explicit: Intent { act=com.bda.controller.IControllerService } }
* </pre>
*
* @see <a href="http://www.mogaanywhere.com/developers/">MOGA developer site</a>
* @see <a href="http://commonsware.com/blog/2014/06/29/dealing-deprecations-bindservice.html">
* Discussion on explicit intents</a>
*/
public class MogaHack
{
public static void init( Controller controller, Context context )
{
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.KITKAT)
{
boolean mIsBound = false;
java.lang.reflect.Field fIsBound = null;
android.content.ServiceConnection mServiceConnection = null;
java.lang.reflect.Field fServiceConnection = null;
try
{
Class<?> cMogaController = controller.getClass();
fIsBound = cMogaController.getDeclaredField( "mIsBound" );
fIsBound.setAccessible( true );
mIsBound = fIsBound.getBoolean( controller );
fServiceConnection = cMogaController.getDeclaredField( "mServiceConnection" );
fServiceConnection.setAccessible( true );
mServiceConnection = ( android.content.ServiceConnection ) fServiceConnection.get( controller );
}
catch( NoSuchFieldException e )
{
Log.e( "MogaHack", "MOGA Lollipop Hack NoSuchFieldException (get)", e );
}
catch( IllegalAccessException e )
{
Log.e( "MogaHack", "MOGA Lollipop Hack IllegalAccessException (get)", e );
}
catch( IllegalArgumentException e )
{
Log.e( "MogaHack", "MOGA Lollipop Hack IllegalArgumentException (get)", e );
}
if( ( !mIsBound ) && ( mServiceConnection != null ) )
{
// Convert implicit intent to explicit intent, see http://stackoverflow.com/a/26318757
Intent intent = new Intent( IControllerService.class.getName() );
List<ResolveInfo> resolveInfos = context.getPackageManager().queryIntentServices( intent, 0 );
if( resolveInfos == null || resolveInfos.size() != 1 )
{
Log.e( "MogaHack", "Somebody is trying to intercept our intent. Disabling MOGA controller for security." );
return;
}
ServiceInfo serviceInfo = resolveInfos.get( 0 ).serviceInfo;
String packageName = serviceInfo.packageName;
String className = serviceInfo.name;
intent.setComponent( new ComponentName( packageName, className ) );
// Start the service explicitly
context.startService( intent );
context.bindService( intent, mServiceConnection, 1 );
try
{
fIsBound.setBoolean( controller, true );
}
catch( IllegalAccessException e )
{
Log.e( "MogaHack", "MOGA Lollipop Hack IllegalAccessException (set)", e );
}
catch( IllegalArgumentException e )
{
Log.e( "MogaHack", "MOGA Lollipop Hack IllegalArgumentException (set)", e );
}
}
}
else
{
controller.init();
}
}
}

View File

@ -9,14 +9,14 @@ import java.util.concurrent.ConcurrentLinkedQueue;
public class SipEmulator extends Thread {
static final String TAG = "SipEmulator";
private static final String TAG = "SipEmulator";
//one second of audio data in bytes
static final int BUFFER_SIZE = 22050;
private static final int BUFFER_SIZE = 22050;
//this needs to get set to the amount the mic normally sends per data request
//...cant be bigger than a maple packet
// 240 16 (or 14) bit samples
static final int ONE_BLIP_SIZE = 480; //ALSO DEFINED IN maple_devs.h
private static final int ONE_BLIP_SIZE = 480; //ALSO DEFINED IN maple_devs.h
private AudioRecord record;
private ConcurrentLinkedQueue<byte[]> bytesReadBuffer;
@ -48,7 +48,7 @@ public class SipEmulator extends Thread {
AudioFormat.ENCODING_PCM_16BIT,
BUFFER_SIZE);
bytesReadBuffer = new ConcurrentLinkedQueue<byte[]>();
bytesReadBuffer = new ConcurrentLinkedQueue<>();
continueRecording = false;
firstGet = true;

View File

@ -16,20 +16,17 @@ public class VJoy {
public static final int key_CONT_Y = 0x0200;
public static final int key_CONT_X = 0x0400;
public static final int LAYER_TYPE_SOFTWARE = 1;
public static final int LAYER_TYPE_HARDWARE = 2;
public static int VJoyCount = 13;
public static float[][] baseVJoy() {
return new float[][] {
new float[] { 24+0, 24+64, 64,64, VJoy.key_CONT_DPAD_LEFT, 0},
new float[] { 24+64, 24+0, 64,64, VJoy.key_CONT_DPAD_UP, 0},
new float[] { 24, 24+64, 64,64, VJoy.key_CONT_DPAD_LEFT, 0},
new float[] { 24+64, 24, 64,64, VJoy.key_CONT_DPAD_UP, 0},
new float[] { 24+128, 24+64, 64,64, VJoy.key_CONT_DPAD_RIGHT, 0},
new float[] { 24+64, 24+128, 64,64, VJoy.key_CONT_DPAD_DOWN, 0},
new float[] { 440+0, 280+64, 64,64, VJoy.key_CONT_X, 0},
new float[] { 440+64, 280+0, 64,64, VJoy.key_CONT_Y, 0},
new float[] { 440, 280+64, 64,64, VJoy.key_CONT_X, 0},
new float[] { 440+64, 280, 64,64, VJoy.key_CONT_Y, 0},
new float[] { 440+128, 280+64, 64,64, VJoy.key_CONT_B, 0},
new float[] { 440+64, 280+128,64,64, VJoy.key_CONT_A, 0},
@ -41,9 +38,9 @@ public class VJoy {
new float[] { 0, 128+224,128,128,-3, 0},
new float[] { 96, 320, 32,32, -4, 0},
new float[] { 20+0 , 288+0 , 64,64, key_CONT_DPAD_LEFT|key_CONT_DPAD_UP, 0},
new float[] { 20+128, 288+0 , 64,64, key_CONT_DPAD_RIGHT|key_CONT_DPAD_UP, 0},
new float[] { 20+0 , 288+128, 64,64, key_CONT_DPAD_LEFT|key_CONT_DPAD_DOWN, 0},
new float[] { 20, 288, 64,64, key_CONT_DPAD_LEFT|key_CONT_DPAD_UP, 0},
new float[] { 20+128, 288, 64,64, key_CONT_DPAD_RIGHT|key_CONT_DPAD_UP, 0},
new float[] { 20, 288+128,64,64, key_CONT_DPAD_LEFT|key_CONT_DPAD_DOWN, 0},
new float[] { 20+128, 288+128,64,64, key_CONT_DPAD_RIGHT|key_CONT_DPAD_DOWN, 0},
};
}
@ -81,28 +78,45 @@ public class VJoy {
public static float[][] getVjoy_d(float[][] vjoy_d_custom) {
return new float[][] {
new float[] { 20+0*vjoy_d_custom[0][2]+vjoy_d_custom[0][0], 288+64*vjoy_d_custom[0][2]+vjoy_d_custom[0][1], 64*vjoy_d_custom[0][2],64*vjoy_d_custom[0][2], key_CONT_DPAD_LEFT},
new float[] { 20+64*vjoy_d_custom[0][2]+vjoy_d_custom[0][0], 288+0*vjoy_d_custom[0][2]+vjoy_d_custom[0][1], 64*vjoy_d_custom[0][2],64*vjoy_d_custom[0][2], key_CONT_DPAD_UP},
new float[] { 20+128*vjoy_d_custom[0][2]+vjoy_d_custom[0][0], 288+64*vjoy_d_custom[0][2]+vjoy_d_custom[0][1], 64*vjoy_d_custom[0][2],64*vjoy_d_custom[0][2], key_CONT_DPAD_RIGHT},
new float[] { 20+64*vjoy_d_custom[0][2]+vjoy_d_custom[0][0], 288+128*vjoy_d_custom[0][2]+vjoy_d_custom[0][1], 64*vjoy_d_custom[0][2],64*vjoy_d_custom[0][2], key_CONT_DPAD_DOWN},
new float[] { 20+0*vjoy_d_custom[0][2]+vjoy_d_custom[0][0], 288+64*vjoy_d_custom[0][2]+vjoy_d_custom[0][1],
64*vjoy_d_custom[0][2],64*vjoy_d_custom[0][2], key_CONT_DPAD_LEFT},
new float[] { 20+64*vjoy_d_custom[0][2]+vjoy_d_custom[0][0], 288+0*vjoy_d_custom[0][2]+vjoy_d_custom[0][1],
64*vjoy_d_custom[0][2],64*vjoy_d_custom[0][2], key_CONT_DPAD_UP},
new float[] { 20+128*vjoy_d_custom[0][2]+vjoy_d_custom[0][0], 288+64*vjoy_d_custom[0][2]+vjoy_d_custom[0][1],
64*vjoy_d_custom[0][2],64*vjoy_d_custom[0][2], key_CONT_DPAD_RIGHT},
new float[] { 20+64*vjoy_d_custom[0][2]+vjoy_d_custom[0][0], 288+128*vjoy_d_custom[0][2]+vjoy_d_custom[0][1],
64*vjoy_d_custom[0][2],64*vjoy_d_custom[0][2], key_CONT_DPAD_DOWN},
new float[] { 448+0*vjoy_d_custom[1][2]+vjoy_d_custom[1][0], 288+64*vjoy_d_custom[1][2]+vjoy_d_custom[1][1], 64*vjoy_d_custom[1][2],64*vjoy_d_custom[1][2], key_CONT_X},
new float[] { 448+64*vjoy_d_custom[1][2]+vjoy_d_custom[1][0], 288+0*vjoy_d_custom[1][2]+vjoy_d_custom[1][1], 64*vjoy_d_custom[1][2],64*vjoy_d_custom[1][2], key_CONT_Y},
new float[] { 448+128*vjoy_d_custom[1][2]+vjoy_d_custom[1][0], 288+64*vjoy_d_custom[1][2]+vjoy_d_custom[1][1], 64*vjoy_d_custom[1][2],64*vjoy_d_custom[1][2], key_CONT_B},
new float[] { 448+64*vjoy_d_custom[1][2]+vjoy_d_custom[1][0], 288+128*vjoy_d_custom[1][2]+vjoy_d_custom[1][1], 64*vjoy_d_custom[1][2],64*vjoy_d_custom[1][2], key_CONT_A},
new float[] { 448+0*vjoy_d_custom[1][2]+vjoy_d_custom[1][0], 288+64*vjoy_d_custom[1][2]+vjoy_d_custom[1][1],
64*vjoy_d_custom[1][2],64*vjoy_d_custom[1][2], key_CONT_X},
new float[] { 448+64*vjoy_d_custom[1][2]+vjoy_d_custom[1][0], 288+0*vjoy_d_custom[1][2]+vjoy_d_custom[1][1],
64*vjoy_d_custom[1][2],64*vjoy_d_custom[1][2], key_CONT_Y},
new float[] { 448+128*vjoy_d_custom[1][2]+vjoy_d_custom[1][0], 288+64*vjoy_d_custom[1][2]+vjoy_d_custom[1][1],
64*vjoy_d_custom[1][2],64*vjoy_d_custom[1][2], key_CONT_B},
new float[] { 448+64*vjoy_d_custom[1][2]+vjoy_d_custom[1][0], 288+128*vjoy_d_custom[1][2]+vjoy_d_custom[1][1],
64*vjoy_d_custom[1][2],64*vjoy_d_custom[1][2], key_CONT_A},
new float[] { 320-32+vjoy_d_custom[2][0], 288+128+vjoy_d_custom[2][1], 64*vjoy_d_custom[2][2],64*vjoy_d_custom[2][2], key_CONT_START},
new float[] { 320-32+vjoy_d_custom[2][0], 288+128+vjoy_d_custom[2][1],
64*vjoy_d_custom[2][2],64*vjoy_d_custom[2][2], key_CONT_START},
new float[] { 440+vjoy_d_custom[3][0], 200+vjoy_d_custom[3][1], 90*vjoy_d_custom[3][2],64*vjoy_d_custom[3][2], -1},
new float[] { 542+vjoy_d_custom[4][0], 200+vjoy_d_custom[4][1], 90*vjoy_d_custom[4][2],64*vjoy_d_custom[4][2], -2},
new float[] { 440+vjoy_d_custom[3][0], 200+vjoy_d_custom[3][1],
90*vjoy_d_custom[3][2],64*vjoy_d_custom[3][2], -1},
new float[] { 542+vjoy_d_custom[4][0], 200+vjoy_d_custom[4][1],
90*vjoy_d_custom[4][2],64*vjoy_d_custom[4][2], -2},
new float[] { 16+vjoy_d_custom[5][0], 24+32+vjoy_d_custom[5][1], 128*vjoy_d_custom[5][2],128*vjoy_d_custom[5][2], -3},
new float[] { 96+vjoy_d_custom[5][0], 320+vjoy_d_custom[5][1], 32*vjoy_d_custom[5][2],32*vjoy_d_custom[5][2], -4},
new float[] { 16+vjoy_d_custom[5][0], 24+32+vjoy_d_custom[5][1],
128*vjoy_d_custom[5][2],128*vjoy_d_custom[5][2],-3},
new float[] { 96+vjoy_d_custom[5][0], 320+vjoy_d_custom[5][1],
32*vjoy_d_custom[5][2],32*vjoy_d_custom[5][2], -4},
new float[] { 20+0*vjoy_d_custom[0][2]+vjoy_d_custom[0][0], 288+0*vjoy_d_custom[0][2]+vjoy_d_custom[0][1], 64*vjoy_d_custom[0][2],64*vjoy_d_custom[0][2], key_CONT_DPAD_LEFT|key_CONT_DPAD_UP},
new float[] { 20+128*vjoy_d_custom[0][2]+vjoy_d_custom[0][0], 288+0*vjoy_d_custom[0][2]+vjoy_d_custom[0][1], 64*vjoy_d_custom[0][2],64*vjoy_d_custom[0][2], key_CONT_DPAD_RIGHT|key_CONT_DPAD_UP},
new float[] { 20+0*vjoy_d_custom[0][2]+vjoy_d_custom[0][0], 288+128*vjoy_d_custom[0][2]+vjoy_d_custom[0][1], 64*vjoy_d_custom[0][2],64*vjoy_d_custom[0][2], key_CONT_DPAD_LEFT|key_CONT_DPAD_DOWN},
new float[] { 20+128*vjoy_d_custom[0][2]+vjoy_d_custom[0][0], 288+128*vjoy_d_custom[0][2]+vjoy_d_custom[0][1], 64*vjoy_d_custom[0][2],64*vjoy_d_custom[0][2], key_CONT_DPAD_RIGHT|key_CONT_DPAD_DOWN},
new float[] { 20+0*vjoy_d_custom[0][2]+vjoy_d_custom[0][0], 288+0*vjoy_d_custom[0][2]+vjoy_d_custom[0][1],
64*vjoy_d_custom[0][2],64*vjoy_d_custom[0][2], key_CONT_DPAD_LEFT|key_CONT_DPAD_UP},
new float[] { 20+128*vjoy_d_custom[0][2]+vjoy_d_custom[0][0], 288+0*vjoy_d_custom[0][2]+vjoy_d_custom[0][1],
64*vjoy_d_custom[0][2],64*vjoy_d_custom[0][2], key_CONT_DPAD_RIGHT|key_CONT_DPAD_UP},
new float[] { 20+0*vjoy_d_custom[0][2]+vjoy_d_custom[0][0], 288+128*vjoy_d_custom[0][2]+vjoy_d_custom[0][1],
64*vjoy_d_custom[0][2],64*vjoy_d_custom[0][2], key_CONT_DPAD_LEFT|key_CONT_DPAD_DOWN},
new float[] { 20+128*vjoy_d_custom[0][2]+vjoy_d_custom[0][0], 288+128*vjoy_d_custom[0][2]+vjoy_d_custom[0][1],
64*vjoy_d_custom[0][2],64*vjoy_d_custom[0][2], key_CONT_DPAD_RIGHT|key_CONT_DPAD_DOWN},
};
}

View File

@ -8,22 +8,22 @@
#include <EGL/egl.h>
#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
#include <types.h>
#include "types.h"
#include "hw/maple/maple_cfg.h"
#include "profiler/profiler.h"
#include "cfg/cfg.h"
#include "rend/TexCache.h"
#include "hw/maple/maple_devs.h"
#include "hw/maple/maple_if.h"
#include "oslib/audiobackend_android.h"
#include "utils.h"
#include "reios/reios.h"
#include "imgread/common.h"
extern "C"
{
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_config(JNIEnv *env,jobject obj,jstring dirName) __attribute__((visibility("default")));
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_init(JNIEnv *env,jobject obj,jstring fileName) __attribute__((visibility("default")));
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_query(JNIEnv *env,jobject obj,jobject emu_thread) __attribute__((visibility("default")));
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_run(JNIEnv *env,jobject obj,jobject emu_thread) __attribute__((visibility("default")));
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_pause(JNIEnv *env,jobject obj) __attribute__((visibility("default")));
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_destroy(JNIEnv *env,jobject obj) __attribute__((visibility("default")));
@ -38,22 +38,24 @@ extern "C"
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_vjoy(JNIEnv * env, jobject obj,u32 id,float x, float y, float w, float h) __attribute__((visibility("default")));
//JNIEXPORT jint JNICALL Java_com_reicast_emulator_emu_JNIdc_play(JNIEnv *env,jobject obj,jshortArray result,jint size);
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_initControllers(JNIEnv *env, jobject obj, jbooleanArray controllers) __attribute__((visibility("default")));
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_initControllers(JNIEnv *env, jobject obj, jbooleanArray controllers, jobjectArray peripherals) __attribute__((visibility("default")));
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_setupMic(JNIEnv *env,jobject obj,jobject sip) __attribute__((visibility("default")));
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_diskSwap(JNIEnv *env,jobject obj, jstring newdisk) __attribute__((visibility("default")));
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_diskSwap(JNIEnv *env,jobject obj,jstring disk) __attribute__((visibility("default")));
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_vmuSwap(JNIEnv *env,jobject obj) __attribute__((visibility("default")));
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_setupVmu(JNIEnv *env,jobject obj,jobject sip) __attribute__((visibility("default")));
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_dynarec(JNIEnv *env,jobject obj, jint dynarec) __attribute__((visibility("default")));
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_idleskip(JNIEnv *env,jobject obj, jint idleskip) __attribute__((visibility("default")));
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_unstable(JNIEnv *env,jobject obj, jint unstable) __attribute__((visibility("default")));
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_safemode(JNIEnv *env,jobject obj, jint safemode) __attribute__((visibility("default")));
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_cable(JNIEnv *env,jobject obj, jint cable) __attribute__((visibility("default")));
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_region(JNIEnv *env,jobject obj, jint region) __attribute__((visibility("default")));
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_broadcast(JNIEnv *env,jobject obj, jint broadcast) __attribute__((visibility("default")));
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_limitfps(JNIEnv *env,jobject obj, jint limiter) __attribute__((visibility("default")));
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_nobatch(JNIEnv *env,jobject obj, jint nobatch) __attribute__((visibility("default")));
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_nosound(JNIEnv *env,jobject obj, jint noaudio) __attribute__((visibility("default")));
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_delayinterrupt(JNIEnv *env,jobject obj, jint delayed) __attribute__((visibility("default")));
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_mipmaps(JNIEnv *env,jobject obj, jint mipmaps) __attribute__((visibility("default")));
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_widescreen(JNIEnv *env,jobject obj, jint stretch) __attribute__((visibility("default")));
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_subdivide(JNIEnv *env,jobject obj, jint subdivide) __attribute__((visibility("default")));
@ -81,6 +83,11 @@ JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_unstable(JNIEnv *env,
settings.dynarec.unstable_opt = unstable;
}
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_safemode(JNIEnv *env,jobject obj, jint safemode)
{
settings.dynarec.safemode = safemode;
}
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_cable(JNIEnv *env,jobject obj, jint cable)
{
settings.dreamcast.cable = cable;
@ -111,6 +118,11 @@ JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_nosound(JNIEnv *env,j
settings.aica.NoSound = noaudio;
}
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_delayinterrupt(JNIEnv *env,jobject obj, jint delayed)
{
settings.aica.DelayInterrupt = delayed;
}
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_mipmaps(JNIEnv *env,jobject obj, jint mipmaps)
{
settings.rend.UseMipmaps = mipmaps;
@ -138,19 +150,15 @@ JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_pvrrender(JNIEnv *env
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_syncedrender(JNIEnv *env,jobject obj, jint sync)
{
settings.pvr.SynchronousRendering = sync;
settings.pvr.SynchronousRender = sync;
}
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_modvols(JNIEnv *env,jobject obj, jint volumes)
{
settings.rend.ModifierVolumes = volumes;
}
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_bootdisk(JNIEnv *env,jobject obj, jstring disk)
{
}
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_usereios(JNIEnv *env,jobject obj, jint reios)
{
settings.bios.UseReios = reios;
@ -163,7 +171,8 @@ JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_dreamtime(JNIEnv *env
void egl_stealcntx();
void SetApplicationPath(wchar *path);
int dc_init(int argc,wchar* argv[]);
void reios_init(int argc,wchar* argv[]);
int dc_init();
void dc_run();
void dc_pause();
void dc_term();
@ -178,10 +187,11 @@ bool gles_init();
extern int screen_width,screen_height;
static u64 tvs_base;
static char CurFileName[256];
static char gamedisk[256];
// Additonal controllers 2, 3 and 4 connected ?
static bool add_controllers[3] = { false, false, false };
int **controller_periphs;
u16 kcode[4];
u32 vks[4];
@ -218,15 +228,8 @@ static void *ThreadHandler(void *UserData)
strcat(Args[2],P);
}
// Add additonal controllers
for (int i = 0; i < 3; i++)
{
if (add_controllers[i])
mcfg_Create(MDT_SegaController,i+1,5);
}
// Run nullDC emulator
dc_init(Args[2]? 3:1,Args);
reios_init(Args[2]? 3:1,Args);
return 0;
}
@ -259,6 +262,38 @@ void *libPvr_GetRenderSurface()
void common_linux_setup();
MapleDeviceType GetMapleDeviceType(int value)
{
switch (value)
{
case 1:
return MDT_SegaVMU;
case 2:
return MDT_Microphone;
case 3:
return MDT_PurupuruPack;
default:
return MDT_None;
}
}
void os_SetupInput()
{
#if DC_PLATFORM == DC_PLATFORM_DREAMCAST
// Create first controller
mcfg_CreateController(0, MDT_SegaVMU, GetMapleDeviceType(controller_periphs[0][1]));
// Add additonal controllers
for (int i = 0; i < 3; i++)
{
if (add_controllers[i])
mcfg_CreateController(i + 1,
GetMapleDeviceType(controller_periphs[i + 1][0]),
GetMapleDeviceType(controller_periphs[i + 1][1]));
}
#endif
}
void os_SetWindowText(char const *Text)
{
putinf("%s",Text);
@ -273,21 +308,34 @@ JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_config(JNIEnv *env,jo
printf("Data dir is: %s\n", get_writable_data_path("/").c_str());
env->ReleaseStringUTFChars(dirName,D);
}
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_bootdisk(JNIEnv *env,jobject obj, jstring disk) {
if (disk != NULL) {
settings.imgread.LoadDefaultImage = true;
const char *P = env->GetStringUTFChars(disk, 0);
if (!P) settings.imgread.DefaultImage[0] = '\0';
else {
printf("Boot Disk URI: '%s'\n", P);
strncpy(settings.imgread.DefaultImage,(strlen(P)>=7)&&!memcmp(
P,"file://",7)? P+7:P,sizeof(settings.imgread.DefaultImage));
settings.imgread.DefaultImage[sizeof(settings.imgread.DefaultImage) - 1] = '\0';
}
}
}
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_init(JNIEnv *env,jobject obj,jstring fileName)
{
// Get filename string from Java
const char* P = fileName ? env->GetStringUTFChars(fileName,0) : 0;
if(!P) CurFileName[0] = '\0';
if (!P) gamedisk[0] = '\0';
else
{
printf("Got URI: '%s'\n",P);
strncpy(CurFileName,(strlen(P)>=7)&&!memcmp(P,"file://",7)? P+7:P,sizeof(CurFileName));
CurFileName[sizeof(CurFileName)-1] = '\0';
printf("Game Disk URI: '%s'\n",P);
strncpy(gamedisk,(strlen(P)>=7)&&!memcmp(P,"file://",7)? P+7:P,sizeof(gamedisk));
gamedisk[sizeof(gamedisk)-1] = '\0';
env->ReleaseStringUTFChars(fileName,P);
}
printf("Opening file: '%s'\n",CurFileName);
// Initialize platform-specific stuff
common_linux_setup();
@ -303,7 +351,28 @@ JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_init(JNIEnv *env,jobj
pthread_attr_destroy(&PTAttr);
*/
ThreadHandler(CurFileName);
ThreadHandler(gamedisk);
}
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_diskSwap(JNIEnv *env,jobject obj,jstring disk)
{
if (settings.imgread.LoadDefaultImage) {
strncpy(settings.imgread.DefaultImage, gamedisk, sizeof(settings.imgread.DefaultImage));
settings.imgread.DefaultImage[sizeof(settings.imgread.DefaultImage) - 1] = '\0';
DiscSwap();
} else if (disk != NULL) {
settings.imgread.LoadDefaultImage = true;
const char *P = env->GetStringUTFChars(disk, 0);
if (!P) settings.imgread.DefaultImage[0] = '\0';
else {
printf("Swap Disk URI: '%s'\n", P);
strncpy(settings.imgread.DefaultImage,(strlen(P)>=7)&&!memcmp(
P,"file://",7)? P+7:P,sizeof(settings.imgread.DefaultImage));
settings.imgread.DefaultImage[sizeof(settings.imgread.DefaultImage) - 1] = '\0';
env->ReleaseStringUTFChars(disk, P);
}
DiscSwap();
}
}
#define SAMPLE_COUNT 512
@ -324,6 +393,22 @@ jobject vmulcd = NULL;
jbyteArray jpix = NULL;
jmethodID updatevmuscreen;
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_query(JNIEnv *env,jobject obj,jobject emu_thread)
{
jmethodID reiosInfoMid=env->GetMethodID(env->GetObjectClass(emu_thread),"reiosInfo","(Ljava/lang/String;Ljava/lang/String;)V");
char *id = (char*)malloc(11);
strcpy(id, reios_disk_id());
jstring reios_id = env->NewStringUTF(id);
char *name = (char*)malloc(129);
strcpy(name, reios_software_name);
jstring reios_name = env->NewStringUTF(name);
env->CallVoidMethod(emu_thread, reiosInfoMid, reios_id, reios_name);
dc_init();
}
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_run(JNIEnv *env,jobject obj,jobject emu_thread)
{
@ -334,38 +419,31 @@ JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_run(JNIEnv *env,jobje
jsamples=env->NewShortArray(SAMPLE_COUNT*2);
writemid=env->GetMethodID(env->GetObjectClass(emu),"WriteBuffer","([SI)I");
coreMessageMid=env->GetMethodID(env->GetObjectClass(emu),"coreMessage","([B)V");
coreMessageMid=env->GetMethodID(env->GetObjectClass(emu),"coreMessage","([B)I");
dieMid=env->GetMethodID(env->GetObjectClass(emu),"Die","()V");
// msgboxf("HELLO!", MBX_OK);
dc_run();
}
int msgboxf(const wchar* Text,unsigned int Type,...)
{
wchar S[2048];
va_list Args;
int msgboxf(const wchar* text,unsigned int type,...) {
va_list args;
va_start(Args,Type);
vsnprintf(S, 2048,Text,Args);
va_end(Args);
puts(S);
wchar temp[2048];
va_start(args, type);
vsprintf(temp, text, args);
va_end(args);
int byteCount = strlen(S);
int byteCount = strlen(temp);
jbyteArray bytes = jenv->NewByteArray(byteCount);
jenv->SetByteArrayRegion(bytes, 0, byteCount, (jbyte*)S);
jenv->SetByteArrayRegion(bytes, 0, byteCount, (jbyte *) temp);
jenv->CallVoidMethod(emu,coreMessageMid,bytes);
return (MBX_OK);
return jenv->CallIntMethod(emu, coreMessageMid, bytes);
}
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_setupMic(JNIEnv *env,jobject obj,jobject sip)
{
sipemu = env->NewGlobalRef(sip);
getmicdata = env->GetMethodID(env->GetObjectClass(sipemu),"getData","()[B");
delete MapleDevices[0][1];
mcfg_Create(MDT_Microphone,0,1);
}
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_setupVmu(JNIEnv *env,jobject obj,jobject vmu)
@ -386,11 +464,6 @@ JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_destroy(JNIEnv *env,j
dc_term();
}
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_diskSwap(JNIEnv *env,jobject obj, jstring newdisk)
{
// Needs actual code to swap a disk
}
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_vmuSwap(JNIEnv *env,jobject obj)
{
maple_device* olda = MapleDevices[0][0];
@ -507,11 +580,30 @@ JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_vjoy(JNIEnv * env, jo
}
}
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_initControllers(JNIEnv *env, jobject obj, jbooleanArray controllers)
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_initControllers(JNIEnv *env, jobject obj, jbooleanArray controllers, jobjectArray peripherals)
{
jboolean *controllers_body = env->GetBooleanArrayElements(controllers, 0);
memcpy(add_controllers, controllers_body, 3);
env->ReleaseBooleanArrayElements(controllers, controllers_body, 0);
int obj_len = env->GetArrayLength(peripherals);
jintArray port = (jintArray) env->GetObjectArrayElement(peripherals, 0);
int port_len = env->GetArrayLength(port);
controller_periphs = new int*[obj_len];
for (int i = 0; i < obj_len; ++i) {
port = (jintArray) env->GetObjectArrayElement(peripherals, i);
jint *items = env->GetIntArrayElements(port, 0);
controller_periphs[i] = new int[port_len];
for (int j = 0; j < port_len; ++j) {
controller_periphs[i][j]= items[j];
}
}
for (int i = 0; i < obj_len; i++) {
jintArray port = (jintArray) env->GetObjectArrayElement(peripherals, i);
jint *items = env->GetIntArrayElements(port, 0);
env->ReleaseIntArrayElements(port, items, 0);
env->DeleteLocalRef(port);
}
}
// Audio Stuff

View File

@ -1,6 +1,5 @@
#include <EGL/egl.h>
#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
extern "C" {
#include "deps/libpng/png.h"
}
@ -70,8 +69,7 @@ GLuint loadTextureFromPNG(const char* filename, int &width, int &height) {
}
//create png struct
png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL,
NULL, NULL);
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);
@ -119,8 +117,7 @@ GLuint loadTextureFromPNG(const char* filename, int &width, int &height) {
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);
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;

View File

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 26 KiB

View File

@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="rectangle" android:padding="10dp" >
<solid android:color="#D0000000"/>
@ -9,7 +8,7 @@
<item>
<bitmap
android:gravity="center"
app:srcCompat="@drawable/menutile"
android:src="@drawable/menutile"
android:tileMode="repeat" />
</item>
</layer-list>

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.6 KiB

After

Width:  |  Height:  |  Size: 6.0 KiB

View File

@ -495,7 +495,7 @@
<Spinner
android:id="@+id/depth_spinner"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_height="0dp"
android:layout_weight="1"
android:ems="10" />
</LinearLayout>
@ -571,7 +571,7 @@
<Spinner
android:id="@+id/cable_spinner"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_height="0dp"
android:layout_weight="1"
android:ems="10" />
</LinearLayout>
@ -600,7 +600,7 @@
<Spinner
android:id="@+id/region_spinner"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_height="0dp"
android:layout_weight="1"
android:ems="10" />
</LinearLayout>
@ -629,7 +629,7 @@
<Spinner
android:id="@+id/broadcast_spinner"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_height="0dp"
android:layout_weight="1"
android:ems="10" />
</LinearLayout>
@ -719,62 +719,34 @@
</LinearLayout>
</TableRow>
<TableRow
android:layout_marginTop="10dp"
android:gravity="center_vertical" >
<TextView
android:id="@+id/modvols_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0.5"
android:ems="10"
android:gravity="center_vertical|left"
android:text="@string/select_modvols" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="right"
android:layout_marginTop="10dp"
android:orientation="vertical" >
<Switch
android:id="@+id/modvols_option"
<TextView
android:id="@+id/boot_disk_text"
android:layout_width="wrap_content"
android:layout_height="0dip"
android:layout_weight="1"
android:text="@string/boot_disk" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:focusable="true" />
android:orientation="vertical" >
<EditText
android:id="@+id/boot_disk"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:ems="10"
android:inputType="text" >
</EditText>
</LinearLayout>
</LinearLayout>
</TableRow>
<!--<LinearLayout-->
<!--android:layout_width="match_parent"-->
<!--android:layout_height="wrap_content"-->
<!--android:layout_marginTop="10dp"-->
<!--android:orientation="vertical" >-->
<!--<TextView-->
<!--android:id="@+id/boot_disk_text"-->
<!--android:layout_width="wrap_content"-->
<!--android:layout_height="0dip"-->
<!--android:layout_weight="1"-->
<!--android:text="@string/boot_disk" />-->
<!--<LinearLayout-->
<!--android:layout_width="match_parent"-->
<!--android:layout_height="wrap_content"-->
<!--android:orientation="vertical" >-->
<!--<EditText-->
<!--android:id="@+id/boot_disk"-->
<!--android:layout_width="match_parent"-->
<!--android:layout_height="wrap_content"-->
<!--android:layout_weight="1"-->
<!--android:ems="10"-->
<!--android:inputType="textPersonName" >-->
<!--</EditText>-->
<!--</LinearLayout>-->
<!--</LinearLayout>-->
<TableRow
android:layout_marginTop="10dp"
@ -797,7 +769,7 @@
android:orientation="vertical" >
<Button
android:id="@+id/reset_emu_settings"
android:id="@+id/reset_emu_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/reset_emu" />

View File

@ -22,6 +22,7 @@
android:layout_height="wrap_content"
android:layout_weight="1"
android:ems="10"
android:layout_marginLeft="4dp"
android:text="@string/customize_touch_controls" />
<LinearLayout
@ -34,7 +35,7 @@
<Button
android:id="@+id/buttonLaunchEditor"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_height="0dp"
android:layout_weight="1"
android:ems="8"
android:text="@string/launch_editor" />
@ -50,6 +51,7 @@
android:layout_height="wrap_content"
android:layout_weight="0.5"
android:ems="10"
android:layout_marginLeft="4dp"
android:gravity="center_vertical|left"
android:text="@string/touch_vibration" />
@ -85,6 +87,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginLeft="4dp"
android:text="@string/vibration_duration" />
<LinearLayout
@ -130,6 +133,7 @@
android:layout_height="wrap_content"
android:layout_weight="1"
android:ems="10"
android:layout_marginLeft="4dp"
android:text="@string/customize_physical_controls" />
<LinearLayout
@ -142,7 +146,7 @@
<Button
android:id="@+id/buttonKeycodeEditor"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_height="0dp"
android:layout_weight="1"
android:ems="8"
android:text="@string/launch_editor" />
@ -168,13 +172,13 @@
android:scaleType="fitCenter" />
<TextView
android:layout_width="wrap_content"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.5"
android:ems="10"
android:gravity="center_vertical|left"
android:layout_marginLeft="6dp"
android:text="@string/mic_in_port_2" />
android:text="@string/enable_microphone" />
</LinearLayout>
<LinearLayout
@ -185,7 +189,7 @@
android:orientation="vertical" >
<Switch
android:id="@+id/micInPort2"
android:id="@+id/micEnabled"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:focusable="true" />
@ -237,7 +241,7 @@
</RelativeLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginLeft="6dp"
android:layout_weight="1"
@ -255,6 +259,15 @@
android:layout_height="wrap_content"
android:ems="10"
android:text="@string/controller_none_selected" />
<TextView
android:id="@+id/textViewPeripheralsPlayer1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:layout_marginLeft="5dp"
android:ems="10"
android:text="@string/controller_1_vmu" />
</LinearLayout>
</LinearLayout>
@ -319,7 +332,7 @@
</RelativeLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginLeft="6dp"
android:layout_weight="1"
@ -337,6 +350,29 @@
android:layout_height="wrap_content"
android:ems="10"
android:text="@string/controller_none_selected" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:orientation="horizontal" >
<Spinner
android:id="@+id/spnr_player2_periph1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:ems="6"
android:entries="@array/peripherals" />
<Spinner
android:id="@+id/spnr_player2_periph2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:ems="6"
android:entries="@array/peripherals" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
@ -401,7 +437,7 @@
</RelativeLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginLeft="6dp"
android:layout_weight="1"
@ -419,6 +455,29 @@
android:layout_height="wrap_content"
android:ems="10"
android:text="@string/controller_none_selected" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:orientation="horizontal" >
<Spinner
android:id="@+id/spnr_player3_periph1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:ems="6"
android:entries="@array/peripherals" />
<Spinner
android:id="@+id/spnr_player3_periph2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:ems="6"
android:entries="@array/peripherals" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
@ -483,7 +542,7 @@
</RelativeLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginLeft="6dp"
android:layout_weight="1"
@ -501,6 +560,29 @@
android:layout_height="wrap_content"
android:ems="10"
android:text="@string/controller_none_selected" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:orientation="horizontal" >
<Spinner
android:id="@+id/spnr_player4_periph1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:ems="6"
android:entries="@array/peripherals" />
<Spinner
android:id="@+id/spnr_player4_periph2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:ems="6"
android:entries="@array/peripherals" />
</LinearLayout>
</LinearLayout>
</LinearLayout>

View File

@ -5,11 +5,6 @@
android:layout_height="match_parent"
android:orientation="vertical" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<TableLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
@ -39,6 +34,7 @@
android:layout_height="wrap_content"
android:layout_weight="0.5"
android:ems="10"
android:layout_marginLeft="4dp"
android:gravity="center_vertical|left"
android:text="@string/modified_layout" />
@ -66,6 +62,7 @@
android:layout_height="wrap_content"
android:layout_weight="0.5"
android:ems="10"
android:layout_marginLeft="4dp"
android:gravity="center_vertical|left"
android:text="@string/controller_compat" />
@ -84,61 +81,6 @@
</LinearLayout>
</TableRow>
<TableRow
android:layout_marginTop="25dp"
android:gravity="center_vertical" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0.5"
android:ems="10"
android:gravity="center_vertical|left"
android:text="@string/rstick_mode" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="right"
android:orientation="vertical" >
<Switch
android:id="@+id/switchRightStickLREnabled"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:focusable="true" />
</LinearLayout>
</TableRow>
<TableRow
android:layout_marginTop="25dp"
android:gravity="center_vertical" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0.5"
android:ems="10"
android:gravity="center_vertical|left"
android:text="@string/joystick_layout" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="right"
android:orientation="vertical" >
<Switch
android:id="@+id/switchJoystickDpadEnabled"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:focusable="true" />
</LinearLayout>
</TableRow>
<TableRow
android:layout_marginTop="25dp"
android:gravity="center_vertical" >
@ -147,6 +89,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginLeft="6dp"
android:gravity="center_vertical|left"
android:orientation="horizontal" >
@ -162,7 +105,7 @@
android:layout_height="wrap_content"
android:layout_marginLeft="4dp"
android:ems="10"
android:text="A button" />
android:text="@string/a_button" />
</LinearLayout>
<LinearLayout
@ -198,6 +141,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginLeft="6dp"
android:gravity="center_vertical|left"
android:orientation="horizontal" >
@ -213,7 +157,7 @@
android:layout_height="wrap_content"
android:layout_marginLeft="4dp"
android:ems="10"
android:text="B button" />
android:text="@string/b_button" />
</LinearLayout>
<LinearLayout
@ -249,6 +193,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginLeft="6dp"
android:gravity="center_vertical|left"
android:orientation="horizontal" >
@ -264,7 +209,7 @@
android:layout_height="wrap_content"
android:layout_marginLeft="4dp"
android:ems="10"
android:text="X button" />
android:text="@string/x_button" />
</LinearLayout>
<LinearLayout
@ -300,6 +245,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginLeft="6dp"
android:gravity="center_vertical|left"
android:orientation="horizontal" >
@ -315,7 +261,7 @@
android:layout_height="wrap_content"
android:layout_marginLeft="4dp"
android:ems="10"
android:text="Y button" />
android:text="@string/y_button" />
</LinearLayout>
<LinearLayout
@ -351,6 +297,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginLeft="6dp"
android:gravity="center_vertical|left"
android:orientation="horizontal" >
@ -366,7 +313,7 @@
android:layout_height="wrap_content"
android:layout_marginLeft="4dp"
android:ems="10"
android:text="L button" />
android:text="@string/left_button" />
</LinearLayout>
<LinearLayout
@ -402,6 +349,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginLeft="6dp"
android:gravity="center_vertical|left"
android:orientation="horizontal" >
@ -417,7 +365,7 @@
android:layout_height="wrap_content"
android:layout_marginLeft="4dp"
android:ems="10"
android:text="R button" />
android:text="@string/right_button" />
</LinearLayout>
<LinearLayout
@ -445,6 +393,151 @@
</LinearLayout>
</TableRow>
<TableRow
android:layout_marginTop="25dp"
android:gravity="center_vertical" >
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center_vertical|left"
android:orientation="horizontal" >
<TextView
android:id="@+id/rstick_mode"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="4dp"
android:ems="10"
android:text="@string/rstick_mode" />
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="right"
android:orientation="vertical" >
<Spinner
android:id="@+id/rstick_spinner"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:ems="6"
android:entries="@array/right_stick" >
<requestFocus />
</Spinner>
</LinearLayout>
</TableRow>
<TableRow
android:layout_marginTop="25dp"
android:gravity="center_vertical" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0.5"
android:ems="10"
android:layout_marginLeft="4dp"
android:gravity="center_vertical|left"
android:text="@string/joystick_layout" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="right"
android:orientation="vertical" >
<Switch
android:id="@+id/switchJoystickDpadEnabled"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:focusable="true" />
</LinearLayout>
</TableRow>
<TableRow
android:layout_marginTop="25dp"
android:gravity="center_vertical" >
<TextView
android:id="@+id/joystick_x_axis"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="4dp"
android:layout_weight="1"
android:ems="10"
android:text="@string/joystick_x" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="right"
android:orientation="vertical" >
<Button
android:id="@+id/joystick_x_edit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:ems="6"
android:text="@string/select" />
<Button
android:id="@+id/remove_joystick_x"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:ems="6"
android:text="@string/remove" />
</LinearLayout>
</TableRow>
<TableRow
android:layout_marginTop="25dp"
android:gravity="center_vertical" >
<TextView
android:id="@+id/joystick_y_axis"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="4dp"
android:layout_weight="1"
android:ems="10"
android:text="@string/joystick_y" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="right"
android:orientation="vertical" >
<Button
android:id="@+id/joystick_y_edit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:ems="6"
android:text="@string/select" />
<Button
android:id="@+id/remove_joystick_y"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:ems="6"
android:text="@string/remove" />
</LinearLayout>
</TableRow>
<TableRow
android:layout_marginTop="25dp"
android:gravity="center_vertical" >
@ -456,7 +549,7 @@
android:layout_marginLeft="4dp"
android:layout_weight="1"
android:ems="10"
android:text="DPad Up" />
android:text="@string/dpad_up" />
<LinearLayout
android:layout_width="wrap_content"
@ -494,7 +587,7 @@
android:layout_marginLeft="4dp"
android:layout_weight="1"
android:ems="10"
android:text="DPad Down" />
android:text="@string/dpad_down" />
<LinearLayout
android:layout_width="wrap_content"
@ -532,7 +625,7 @@
android:layout_marginLeft="4dp"
android:layout_weight="1"
android:ems="10"
android:text="DPad Left" />
android:text="@string/dpad_left" />
<LinearLayout
android:layout_width="wrap_content"
@ -570,7 +663,7 @@
android:layout_marginLeft="4dp"
android:layout_weight="1"
android:ems="10"
android:text="DPad Right" />
android:text="@string/dpad_right" />
<LinearLayout
android:layout_width="wrap_content"
@ -605,6 +698,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginLeft="6dp"
android:gravity="center_vertical|left"
android:orientation="horizontal" >
@ -620,7 +714,7 @@
android:layout_height="wrap_content"
android:layout_marginLeft="4dp"
android:ems="10"
android:text="Start Button" />
android:text="@string/start_button" />
</LinearLayout>
<LinearLayout
@ -656,6 +750,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginLeft="14dp"
android:gravity="center_vertical|left"
android:orientation="horizontal" >
@ -669,9 +764,8 @@
android:id="@+id/select_button_key"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="4dp"
android:ems="10"
android:text="Select Button" />
android:text="@string/select_button" />
</LinearLayout>
<LinearLayout
@ -699,6 +793,5 @@
</LinearLayout>
</TableRow>
</TableLayout>
</LinearLayout>
</ScrollView>

View File

@ -0,0 +1,412 @@
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:id="@+id/pgc_docs"
android:layout_width="match_parent"
android:layout_height="0dip"
android:layout_weight="1"
android:layout_marginTop="10dp"
android:gravity="center"
android:text="@string/pgc_doc" />
<TableLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="6dp"
android:stretchColumns="*" >
<TableRow
android:layout_marginTop="10dp"
android:gravity="center_vertical" >
<TextView
android:id="@+id/textView3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0.5"
android:ems="10"
android:gravity="center_vertical|left"
android:text="@string/pgc_select_game" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="right"
android:orientation="vertical" >
<Spinner
android:id="@+id/config_spinner"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_weight="1"
android:ems="10" >
<requestFocus />
</Spinner>
</LinearLayout>
</TableRow>
<TableRow
android:layout_marginTop="25dp"
android:gravity="center_vertical" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0.5"
android:ems="10"
android:gravity="center_vertical|left"
android:text="@string/joystick_layout" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="right"
android:orientation="vertical" >
<Switch
android:id="@+id/switchJoystickDpadEnabled"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:focusable="true" />
</LinearLayout>
</TableRow>
<TableRow
android:layout_marginTop="10dp"
android:gravity="center_vertical" >
<TextView
android:id="@+id/unstable_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0.5"
android:ems="10"
android:gravity="center_vertical|left"
android:text="@string/select_unstable" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="right"
android:orientation="vertical" >
<Switch
android:id="@+id/unstable_option"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:focusable="true" />
</LinearLayout>
</TableRow>
<TableRow
android:layout_marginTop="10dp"
android:gravity="center_vertical" >
<TextView
android:id="@+id/frameskip_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center_vertical|left"
android:text="@string/set_frameskip" />
<EditText
android:id="@+id/current_frames"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="5dp"
android:layout_weight="1"
android:ems="10"
android:gravity="right"
android:inputType="number" >
</EditText>
</TableRow>
<TableRow
android:layout_marginTop="5dp"
android:gravity="center_vertical" >
<SeekBar
android:id="@+id/frame_seekbar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:ems="10"
android:gravity="center_vertical|left"
android:max="5"
android:progress="0" />
</TableRow>
<TableRow
android:layout_marginTop="20dp"
android:gravity="center_vertical" >
<TextView
android:id="@+id/experimental_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:ems="10"
android:gravity="center_vertical"
android:text="@string/experimental_opts" />
</TableRow>
<View
android:layout_width="match_parent"
android:layout_height="2dp"
android:background="@drawable/list_item_border" />
<TableRow
android:layout_marginTop="20dp"
android:gravity="center_vertical" >
<TextView
android:id="@+id/dynarec_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0.5"
android:ems="10"
android:gravity="center_vertical|left"
android:text="@string/select_dynarec" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="right"
android:orientation="vertical" >
<Switch
android:id="@+id/dynarec_option"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:focusable="true" />
</LinearLayout>
</TableRow>
<TableRow
android:layout_marginTop="10dp"
android:gravity="center_vertical" >
<TextView
android:id="@+id/safemode_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0.5"
android:ems="10"
android:gravity="center_vertical|left"
android:text="@string/select_safemode" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="right"
android:orientation="vertical" >
<Switch
android:id="@+id/dynarec_safemode"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:focusable="true" />
</LinearLayout>
</TableRow>
<TableRow
android:layout_marginTop="10dp"
android:gravity="center_vertical" >
<TextView
android:id="@+id/render_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0.5"
android:ems="10"
android:gravity="center_vertical|left"
android:text="@string/select_render" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="right"
android:orientation="vertical" >
<Switch
android:id="@+id/render_option"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:focusable="true" />
</LinearLayout>
</TableRow>
<TableRow
android:layout_marginTop="10dp"
android:gravity="center_vertical" >
<TextView
android:id="@+id/syncrender_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0.5"
android:ems="10"
android:gravity="center_vertical|left"
android:text="@string/select_syncrender" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="right"
android:orientation="vertical" >
<Switch
android:id="@+id/syncrender_option"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:focusable="true" />
</LinearLayout>
</TableRow>
<TableRow
android:layout_marginTop="10dp"
android:gravity="center_vertical" >
<TextView
android:id="@+id/modvols_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0.5"
android:ems="10"
android:gravity="center_vertical|left"
android:text="@string/select_modvols" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="right"
android:orientation="vertical" >
<Switch
android:id="@+id/modvols_option"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:focusable="true" />
</LinearLayout>
</TableRow>
<TableRow
android:layout_marginTop="10dp"
android:gravity="center_vertical" >
<TextView
android:id="@+id/interrupt_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0.5"
android:ems="10"
android:gravity="center_vertical|left"
android:text="@string/select_interrupt" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="right"
android:orientation="vertical" >
<Switch
android:id="@+id/interrupt_option"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:focusable="true" />
</LinearLayout>
</TableRow>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:orientation="vertical" >
<TextView
android:id="@+id/boot_disk_text"
android:layout_width="wrap_content"
android:layout_height="0dip"
android:layout_weight="1"
android:text="@string/boot_disk" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<EditText
android:id="@+id/boot_disk"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:ems="10"
android:inputType="text" >
</EditText>
</LinearLayout>
</LinearLayout>
<TableRow
android:layout_marginTop="10dp"
android:gravity="center_vertical"
android:layout_marginRight="6dp" >
<Button
android:id="@+id/clear_pg_btn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/clear_pgc" />
<Button
android:id="@+id/save_pg_btn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/save_pgc" />
</TableRow>
<TableRow
android:layout_marginTop="10dp"
android:gravity="center_vertical"
android:layout_marginRight="6dp" >
<Button
android:id="@+id/import_pg_btn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/import_pgc" />
<Button
android:id="@+id/export_pg_btn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/export_pgc" />
</TableRow>
</TableLayout>
</LinearLayout>
</ScrollView>

Some files were not shown because too many files have changed in this diff Show More