Moved most android settings into the new gui
virtual gamepad editing and settings home directory setup during onboarding start content browser at app startup after getting permission Use imgui osd to display error messages (msgboxf) Added About tab in settings with version, git hash and Send logcat button (android)
This commit is contained in:
parent
71ea60cc36
commit
ca58c323cd
|
@ -260,7 +260,7 @@ bool rend_frame(TA_context* ctx, bool draw_osd) {
|
|||
bool do_swp = proc && renderer->Render();
|
||||
|
||||
if (do_swp && draw_osd)
|
||||
renderer->DrawOSD();
|
||||
renderer->DrawOSD(false);
|
||||
|
||||
return do_swp;
|
||||
}
|
||||
|
@ -273,14 +273,13 @@ bool rend_single_frame()
|
|||
// FIXME not here
|
||||
os_DoEvents();
|
||||
#if !defined(TARGET_NO_THREADS)
|
||||
if (gui_is_open())
|
||||
if (gui_is_open() || gui_state == VJoyEdit)
|
||||
{
|
||||
if (!rs.Wait(1000 / 60) || !rend_framePending()) // !rend_framePending() needed for OSX
|
||||
{
|
||||
gui_display_ui();
|
||||
FinishRender(NULL);
|
||||
return true;
|
||||
}
|
||||
gui_display_ui();
|
||||
if (gui_state == VJoyEdit && renderer != NULL)
|
||||
renderer->DrawOSD(true);
|
||||
FinishRender(NULL);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -381,10 +380,6 @@ void rend_term_renderer()
|
|||
|
||||
void* rend_thread(void* p)
|
||||
{
|
||||
#if FEAT_HAS_NIXPROF
|
||||
install_prof_handler(1);
|
||||
#endif
|
||||
|
||||
rend_init_renderer();
|
||||
|
||||
//we don't know if this is true, so let's not speculate here
|
||||
|
|
|
@ -45,7 +45,7 @@ struct Renderer
|
|||
|
||||
virtual void Present()=0;
|
||||
|
||||
virtual void DrawOSD() { }
|
||||
virtual void DrawOSD(bool clear_screen) { }
|
||||
|
||||
virtual u32 GetTexture(TSP tsp, TCW tcw) { return 0; }
|
||||
};
|
||||
|
|
|
@ -52,6 +52,7 @@ public:
|
|||
InputMapping *get_input_mapping() { return input_mapper; }
|
||||
void save_mapping();
|
||||
bool remappable() { return _remappable && input_mapper != NULL; }
|
||||
virtual bool is_virtual_gamepad() { return false; }
|
||||
|
||||
virtual void rumble(float power, float inclination, u32 duration_ms) {}
|
||||
virtual void update_rumble() {}
|
||||
|
|
|
@ -54,20 +54,6 @@
|
|||
#include "profiler/profiler.h"
|
||||
#endif
|
||||
|
||||
int msgboxf(const wchar* text, unsigned int type, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
wchar temp[2048];
|
||||
va_start(args, type);
|
||||
vsprintf(temp, text, args);
|
||||
va_end(args);
|
||||
|
||||
//printf(NULL,temp,VER_SHORTNAME,type | MB_TASKMODAL);
|
||||
puts(temp);
|
||||
return MBX_OK;
|
||||
}
|
||||
|
||||
void* x11_win = 0;
|
||||
void* x11_disp = 0;
|
||||
|
||||
|
|
|
@ -504,6 +504,7 @@ void InitSettings()
|
|||
|
||||
settings.input.MouseSensitivity = 100;
|
||||
settings.input.JammaSetup = 0;
|
||||
settings.input.VirtualGamepadVibration = 20;
|
||||
for (int i = 0; i < MAPLE_PORTS; i++)
|
||||
{
|
||||
settings.input.maple_devices[i] = i == 0 ? MDT_SegaController : MDT_None;
|
||||
|
@ -583,6 +584,7 @@ void LoadSettings(bool game_specific)
|
|||
|
||||
settings.input.MouseSensitivity = cfgLoadInt(input_section, "MouseSensitivity", settings.input.MouseSensitivity);
|
||||
settings.input.JammaSetup = cfgLoadInt(input_section, "JammaSetup", settings.input.JammaSetup);
|
||||
settings.input.VirtualGamepadVibration = cfgLoadInt(input_section, "VirtualGamepadVibration", settings.input.VirtualGamepadVibration);
|
||||
for (int i = 0; i < MAPLE_PORTS; i++)
|
||||
{
|
||||
char device_name[32];
|
||||
|
|
|
@ -954,12 +954,12 @@ struct gl4rend : Renderer
|
|||
|
||||
void Present() { gl_swap(); }
|
||||
|
||||
void DrawOSD()
|
||||
void DrawOSD(bool clear_screen)
|
||||
{
|
||||
glBindVertexArray(gl4.vbo.main_vao);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, gl4.vbo.geometry); glCheck();
|
||||
|
||||
OSD_DRAW();
|
||||
OSD_DRAW(clear_screen);
|
||||
}
|
||||
|
||||
virtual u32 GetTexture(TSP tsp, TCW tcw) {
|
||||
|
|
|
@ -1433,7 +1433,7 @@ static void osd_gen_vertices()
|
|||
#define OSD_TEX_W 512
|
||||
#define OSD_TEX_H 256
|
||||
|
||||
void OSD_DRAW()
|
||||
void OSD_DRAW(bool clear_screen)
|
||||
{
|
||||
#ifndef TARGET_PANDORA
|
||||
if (osd_tex)
|
||||
|
@ -1491,6 +1491,11 @@ void OSD_DRAW()
|
|||
glcache.Disable(GL_SCISSOR_TEST);
|
||||
glViewport(0, 0, screen_width, screen_height);
|
||||
|
||||
if (clear_screen)
|
||||
{
|
||||
glcache.ClearColor(0.7f, 0.7f, 0.7f, 1.f);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
}
|
||||
int dfa = osd_vertices.used() / 4;
|
||||
|
||||
for (int i = 0; i < dfa; i++)
|
||||
|
@ -1979,7 +1984,7 @@ struct glesrend : Renderer
|
|||
bool RenderLastFrame() { return render_output_framebuffer(); }
|
||||
void Present() { gl_swap(); glViewport(0, 0, screen_width, screen_height); }
|
||||
|
||||
void DrawOSD()
|
||||
void DrawOSD(bool clear_screen)
|
||||
{
|
||||
if (gl.gl_major >= 3)
|
||||
glBindVertexArray(gl.vbo.vao);
|
||||
|
@ -1993,7 +1998,7 @@ struct glesrend : Renderer
|
|||
glEnableVertexAttribArray(VERTEX_UV_ARRAY);
|
||||
glVertexAttribPointer(VERTEX_UV_ARRAY, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex,u));
|
||||
|
||||
OSD_DRAW();
|
||||
OSD_DRAW(clear_screen);
|
||||
}
|
||||
|
||||
virtual u32 GetTexture(TSP tsp, TCW tcw) {
|
||||
|
|
|
@ -579,4 +579,9 @@ void ImGui_ImplOpenGL3_DrawBackground()
|
|||
ImGui::GetWindowDrawList()->AddImage((ImTextureID)(uintptr_t)g_BackgroundTexture, ImVec2(0, 0), io.DisplaySize, ImVec2(0, 1), ImVec2(1, 0), 0xffffffff);
|
||||
ImGui::End();
|
||||
}
|
||||
else
|
||||
{
|
||||
glClearColor(0, 0, 0, 0);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include <dirent.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "gui.h"
|
||||
#include "oslib/oslib.h"
|
||||
#include "cfg/cfg.h"
|
||||
#include "hw/maple/maple_cfg.h"
|
||||
|
@ -32,6 +33,8 @@
|
|||
#include "input/keyboard_device.h"
|
||||
#include "linux-dist/main.h" // FIXME for kcode[]
|
||||
#include "gui_util.h"
|
||||
#include "gui_android.h"
|
||||
#include "version/version.h"
|
||||
|
||||
extern void dc_loadstate();
|
||||
extern void dc_savestate();
|
||||
|
@ -57,7 +60,7 @@ int screen_dpi = 96;
|
|||
|
||||
static bool inited = false;
|
||||
static float scaling = 1;
|
||||
static enum { Closed, Commands, Settings, ClosedNoResume, Main, Onboarding } gui_state = Main;
|
||||
GuiState gui_state = Main;
|
||||
static bool settings_opening;
|
||||
static bool touch_up;
|
||||
|
||||
|
@ -138,7 +141,7 @@ void gui_init()
|
|||
printf("Screen DPI is %d, size %d x %d. Scaling by %.2f\n", screen_dpi, screen_width, screen_height, scaling);
|
||||
}
|
||||
|
||||
static void ImGui_Impl_NewFrame()
|
||||
void ImGui_Impl_NewFrame()
|
||||
{
|
||||
ImGui_ImplOpenGL3_NewFrame();
|
||||
ImGui::GetIO().DisplaySize.x = screen_width;
|
||||
|
@ -272,11 +275,15 @@ void gui_open_settings()
|
|||
settings_opening = true;
|
||||
HideOSD();
|
||||
}
|
||||
else if (gui_state == VJoyEdit)
|
||||
{
|
||||
gui_state = VJoyEditCommands;
|
||||
}
|
||||
}
|
||||
|
||||
bool gui_is_open()
|
||||
{
|
||||
return gui_state != Closed;
|
||||
return gui_state != Closed && gui_state != VJoyEdit;
|
||||
}
|
||||
|
||||
static void gui_display_commands()
|
||||
|
@ -561,6 +568,32 @@ static void controller_mapping_popup(std::shared_ptr<GamepadDevice> gamepad)
|
|||
ImGui::PopStyleVar();
|
||||
}
|
||||
|
||||
static std::string error_msg;
|
||||
|
||||
static void error_popup()
|
||||
{
|
||||
if (!error_msg.empty())
|
||||
{
|
||||
if (ImGui::BeginPopupModal("Error", NULL, ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoMove))
|
||||
{
|
||||
ImGui::PushTextWrapPos(ImGui::GetCursorPos().x + 400.f * scaling);
|
||||
ImGui::TextWrapped(error_msg.c_str());
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(16 * scaling, 3 * scaling));
|
||||
float currentwidth = ImGui::GetContentRegionAvailWidth();
|
||||
ImGui::SetCursorPosX((currentwidth - 80.f * scaling) / 2.f + ImGui::GetStyle().WindowPadding.x);
|
||||
if (ImGui::Button("OK", ImVec2(80.f * scaling, 0.f)))
|
||||
{
|
||||
error_msg.clear();
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
ImGui::SetItemDefaultFocus();
|
||||
ImGui::PopStyleVar();
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
ImGui::OpenPopup("Error");
|
||||
}
|
||||
}
|
||||
|
||||
static bool game_list_done; // Set to false to refresh the game list
|
||||
|
||||
void directory_selected_callback(bool cancelled, std::string selection)
|
||||
|
@ -833,6 +866,18 @@ static void gui_display_settings()
|
|||
|
||||
controller_mapping_popup(gamepad);
|
||||
|
||||
#ifdef _ANDROID
|
||||
if (gamepad->is_virtual_gamepad())
|
||||
{
|
||||
if (ImGui::Button("Edit"))
|
||||
{
|
||||
vjoy_start_editing();
|
||||
gui_state = VJoyEdit;
|
||||
}
|
||||
ImGui::SameLine();
|
||||
ImGui::SliderInt("Haptic", &settings.input.VirtualGamepadVibration, 0, 60);
|
||||
}
|
||||
#endif
|
||||
ImGui::NextColumn();
|
||||
ImGui::PopID();
|
||||
}
|
||||
|
@ -969,6 +1014,78 @@ static void gui_display_settings()
|
|||
ImGui::PopStyleVar();
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
if (ImGui::BeginTabItem("About"))
|
||||
{
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, normal_padding);
|
||||
if (ImGui::CollapsingHeader("Reicast", ImGuiTreeNodeFlags_DefaultOpen))
|
||||
{
|
||||
ImGui::Text("Version: %s", version);
|
||||
ImGui::Text("Git Hash: %s", git_hash);
|
||||
ImGui::Text("Build Date: %s", build_date);
|
||||
ImGui::Text("Target: %s",
|
||||
#if DC_PLATFORM == DC_PLATFORM_DREAMCAST
|
||||
"Dreamcast"
|
||||
#elif DC_PLATFORM == DC_PLATFORM_NAOMI
|
||||
"Naomi"
|
||||
#elif DC_PLATFORM == DC_PLATFORM_ATOMISWAVE
|
||||
"Atomiswave"
|
||||
#else
|
||||
"Unknown"
|
||||
#endif
|
||||
);
|
||||
}
|
||||
if (ImGui::CollapsingHeader("Platform", ImGuiTreeNodeFlags_DefaultOpen))
|
||||
{
|
||||
ImGui::Text("CPU: %s",
|
||||
#if HOST_CPU == CPU_X86
|
||||
"x86"
|
||||
#elif HOST_CPU == CPU_ARM
|
||||
"ARM"
|
||||
#elif HOST_CPU == CPU_MIPS
|
||||
"MIPS"
|
||||
#elif HOST_CPU == CPU_X64
|
||||
"x86/64"
|
||||
#elif HOST_CPU == CPU_GENERIC
|
||||
"Generic"
|
||||
#elif HOST_CPU == CPU_ARM64
|
||||
"ARM64"
|
||||
#else
|
||||
"Unknown"
|
||||
#endif
|
||||
);
|
||||
ImGui::Text("Operating System: %s",
|
||||
#ifdef _ANDROID
|
||||
"Android"
|
||||
#elif HOST_OS == OS_LINUX
|
||||
"Linux"
|
||||
#elif HOST_OS == OS_DARWIN
|
||||
#if TARGET_IPHONE
|
||||
"iOS"
|
||||
#else
|
||||
"OSX"
|
||||
#endif
|
||||
#elif HOST_OS == OS_WINDOWS
|
||||
"Windows"
|
||||
#else
|
||||
"Unknown"
|
||||
#endif
|
||||
);
|
||||
}
|
||||
if (ImGui::CollapsingHeader("Open GL", ImGuiTreeNodeFlags_DefaultOpen))
|
||||
{
|
||||
ImGui::Text("Renderer: %s", (const char *)glGetString(GL_RENDERER));
|
||||
ImGui::Text("Version: %s", (const char *)glGetString(GL_VERSION));
|
||||
}
|
||||
#ifdef _ANDROID
|
||||
ImGui::Separator();
|
||||
if (ImGui::Button("Send Logs")) {
|
||||
void android_send_logs();
|
||||
android_send_logs();
|
||||
}
|
||||
#endif
|
||||
ImGui::PopStyleVar();
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
ImGui::EndTabBar();
|
||||
}
|
||||
ImGui::PopStyleVar();
|
||||
|
@ -1081,7 +1198,25 @@ static void gui_display_demo()
|
|||
|
||||
static void gui_start_game(const std::string& path)
|
||||
{
|
||||
dc_start_game(path.c_str());
|
||||
int rc = dc_start_game(path.c_str());
|
||||
if (rc != 0)
|
||||
{
|
||||
gui_state = Main;
|
||||
game_started = false;
|
||||
switch (rc) {
|
||||
case -3:
|
||||
error_msg = "Audio/video initialization failed";
|
||||
break;
|
||||
case -5:
|
||||
error_msg = "Cannot find BIOS files";
|
||||
break;
|
||||
case -6:
|
||||
error_msg = "Cannot load NAOMI rom";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void gui_display_content()
|
||||
|
@ -1124,8 +1259,8 @@ static void gui_display_content()
|
|||
ImGui::PushID(game.path.c_str());
|
||||
if (ImGui::Selectable(game.name.c_str()))
|
||||
{
|
||||
gui_start_game(game.path);
|
||||
gui_state = ClosedNoResume;
|
||||
gui_start_game(game.path);
|
||||
}
|
||||
ImGui::PopID();
|
||||
}
|
||||
|
@ -1135,6 +1270,8 @@ static void gui_display_content()
|
|||
ImGui::End();
|
||||
ImGui::PopStyleVar();
|
||||
|
||||
error_popup();
|
||||
|
||||
ImGui::Render();
|
||||
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData(), false);
|
||||
}
|
||||
|
@ -1149,7 +1286,9 @@ void systemdir_selected_callback(bool cancelled, std::string selection)
|
|||
{
|
||||
LoadSettings(false);
|
||||
gui_state = Main;
|
||||
// FIXME Save config dir in android app prefs
|
||||
if (settings.dreamcast.ContentPath.empty())
|
||||
settings.dreamcast.ContentPath.push_back(selection);
|
||||
SaveSettings();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1186,6 +1325,13 @@ void gui_display_ui()
|
|||
case Onboarding:
|
||||
gui_display_onboarding();
|
||||
break;
|
||||
case VJoyEdit:
|
||||
break;
|
||||
case VJoyEditCommands:
|
||||
#ifdef _ANDROID
|
||||
gui_display_vjoy_commands(screen_width, screen_height, scaling);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
if (gui_state == Closed)
|
||||
|
@ -1235,9 +1381,9 @@ static std::string getFPSNotification()
|
|||
LastFPSTime = now;
|
||||
lastFrameCount = FrameCount;
|
||||
}
|
||||
if (fps >= 0) {
|
||||
if (fps >= 0.f && fps < 9999.f) {
|
||||
char text[32];
|
||||
sprintf(text, "F:%.1f", fps);
|
||||
snprintf(text, sizeof(text), "F:%.1f", fps);
|
||||
|
||||
return std::string(text);
|
||||
}
|
||||
|
@ -1247,6 +1393,8 @@ static std::string getFPSNotification()
|
|||
|
||||
void gui_display_osd()
|
||||
{
|
||||
if (gui_state == VJoyEdit)
|
||||
return;
|
||||
double now = os_GetSeconds();
|
||||
if (!osd_message.empty())
|
||||
{
|
||||
|
@ -1290,3 +1438,18 @@ void gui_term()
|
|||
ImGui_ImplOpenGL3_Shutdown();
|
||||
ImGui::DestroyContext();
|
||||
}
|
||||
|
||||
int msgboxf(const wchar* text, unsigned int type, ...) {
|
||||
va_list args;
|
||||
|
||||
wchar temp[2048];
|
||||
va_start(args, type);
|
||||
vsnprintf(temp, sizeof(temp), text, args);
|
||||
va_end(args);
|
||||
printf("%s", temp);
|
||||
|
||||
gui_display_notification(temp, 2000);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
|
@ -28,3 +28,8 @@ void gui_open_onboarding();
|
|||
void gui_term();
|
||||
|
||||
extern int screen_dpi;
|
||||
|
||||
typedef enum { Closed, Commands, Settings, ClosedNoResume, Main, Onboarding, VJoyEdit, VJoyEditCommands } GuiState;
|
||||
extern GuiState gui_state;
|
||||
void ImGui_Impl_NewFrame();
|
||||
|
||||
|
|
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
Copyright 2019 flyinghead
|
||||
|
||||
This file is part of reicast.
|
||||
|
||||
reicast is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
reicast 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 reicast. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifdef _ANDROID
|
||||
|
||||
#include "gui_android.h"
|
||||
#include "gui.h"
|
||||
|
||||
#include "types.h"
|
||||
#include "stdclass.h"
|
||||
#include "imgui/imgui.h"
|
||||
#include "gles/imgui_impl_opengl3.h"
|
||||
|
||||
extern bool settings_opening;
|
||||
|
||||
void vjoy_reset_editing();
|
||||
void vjoy_stop_editing(bool canceled);
|
||||
|
||||
void gui_display_vjoy_commands(int screen_width, int screen_height, float scaling)
|
||||
{
|
||||
ImGui_Impl_NewFrame();
|
||||
ImGui::NewFrame();
|
||||
|
||||
ImGui::SetNextWindowPos(ImVec2(screen_width / 2.f, screen_height / 2.f), ImGuiCond_Always, ImVec2(0.5f, 0.5f));
|
||||
|
||||
ImGui::Begin("Virtual Joystick", NULL, ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse
|
||||
| ImGuiWindowFlags_NoMove | ImGuiWindowFlags_AlwaysAutoResize);
|
||||
|
||||
if (ImGui::Button("Save", ImVec2(150 * scaling, 50 * scaling)))
|
||||
{
|
||||
vjoy_stop_editing(false);
|
||||
gui_state = Settings;
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Reset", ImVec2(150 * scaling, 50 * scaling)))
|
||||
{
|
||||
vjoy_reset_editing();
|
||||
gui_state = VJoyEdit;
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Cancel", ImVec2(150 * scaling, 50 * scaling)))
|
||||
{
|
||||
vjoy_stop_editing(true);
|
||||
gui_state = Settings;
|
||||
}
|
||||
ImGui::End();
|
||||
|
||||
ImGui::Render();
|
||||
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData(), false);
|
||||
}
|
||||
|
||||
#endif // _ANDROID
|
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
Copyright 2019 flyinghead
|
||||
|
||||
This file is part of reicast.
|
||||
|
||||
reicast is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
reicast 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 reicast. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
void gui_display_vjoy_commands(int screen_width, int screen_height, float scaling);
|
||||
void vjoy_start_editing();
|
|
@ -117,6 +117,7 @@ void select_directory_popup(const char *prompt, float scaling, StringCallback ca
|
|||
while (home != NULL)
|
||||
{
|
||||
const char *pcolon = strchr(home, ':');
|
||||
// FIXME Java was doing this: String sdCardPath = sd.replace("mnt/media_rw", "storage");
|
||||
if (pcolon != NULL)
|
||||
{
|
||||
select_subfolders.push_back(std::string(home, pcolon - home));
|
||||
|
|
|
@ -815,6 +815,7 @@ struct settings_t
|
|||
// 4: dual I/O boards (4P), 5: Namco JYU board (Ninja Assault)
|
||||
int maple_devices[4];
|
||||
int maple_expansion_devices[4][2];
|
||||
int VirtualGamepadVibration;
|
||||
} input;
|
||||
};
|
||||
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
/version.cpp
|
|
@ -181,19 +181,6 @@ void SetupPath()
|
|||
set_user_data_dir(fn);
|
||||
}
|
||||
|
||||
int msgboxf(const wchar* text,unsigned int type,...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
wchar temp[2048];
|
||||
va_start(args, type);
|
||||
vsprintf(temp, text, args);
|
||||
va_end(args);
|
||||
|
||||
|
||||
return MessageBox(NULL,temp,VER_SHORTNAME,type | MB_TASKMODAL);
|
||||
}
|
||||
|
||||
// Gamepads
|
||||
u16 kcode[4] = { 0xffff, 0xffff, 0xffff, 0xffff };
|
||||
u32 vks[4];
|
||||
|
|
|
@ -68,7 +68,7 @@
|
|||
android:name="com.reicast.emulator.NativeGLActivity"
|
||||
android:configChanges="orientation|navigation|screenSize|screenLayout|uiMode|keyboard|keyboardHidden"
|
||||
android:screenOrientation="sensorLandscape"
|
||||
android:theme="@android:style/Theme.NoTitleBar.Fullscreen" >
|
||||
android:theme="@style/AppTheme.NoActionBar">
|
||||
</activity>
|
||||
<activity
|
||||
android:name="com.dropbox.client2.android.AuthActivity"
|
||||
|
@ -81,11 +81,6 @@
|
|||
<category android:name="android.intent.category.DEFAULT" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity
|
||||
android:name="com.reicast.emulator.config.EditVJoyActivity"
|
||||
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"
|
||||
|
|
|
@ -32,34 +32,6 @@ import javax.microedition.khronos.opengles.GL10;
|
|||
|
||||
public class FileUtils {
|
||||
|
||||
public void saveArray(String filename, List<String> output_field) {
|
||||
try {
|
||||
FileOutputStream fos = new FileOutputStream(filename);
|
||||
GZIPOutputStream gzos = new GZIPOutputStream(fos);
|
||||
ObjectOutputStream out = new ObjectOutputStream(gzos);
|
||||
out.writeObject(output_field);
|
||||
out.flush();
|
||||
out.close();
|
||||
} catch (IOException e) {
|
||||
e.getStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public List<String> loadArray(String filename) {
|
||||
try {
|
||||
FileInputStream fis = new FileInputStream(filename);
|
||||
GZIPInputStream gzis = new GZIPInputStream(fis);
|
||||
ObjectInputStream in = new ObjectInputStream(gzis);
|
||||
List<String> read_field = (List<String>) in.readObject();
|
||||
in.close();
|
||||
return read_field;
|
||||
} catch (Exception e) {
|
||||
e.getStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Collection<File> listFiles(File directory, FilenameFilter[] filter,
|
||||
int recurse) {
|
||||
|
||||
|
|
|
@ -1,209 +0,0 @@
|
|||
package com.reicast.emulator;
|
||||
|
||||
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.support.constraint.ConstraintLayout;
|
||||
import android.support.design.widget.Snackbar;
|
||||
import android.support.graphics.drawable.VectorDrawableCompat;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.view.Gravity;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ListView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.reicast.emulator.config.Config;
|
||||
import com.reicast.emulator.debug.GitAdapter;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
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;
|
||||
import java.util.HashMap;
|
||||
|
||||
import javax.net.ssl.HttpsURLConnection;
|
||||
|
||||
public class AboutFragment extends Fragment {
|
||||
|
||||
String buildId = "";
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
// Inflate the layout for this fragment
|
||||
return inflater.inflate(R.layout.about_fragment, container, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(View view, Bundle savedInstanceState) {
|
||||
|
||||
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);
|
||||
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();
|
||||
}
|
||||
|
||||
new retrieveGitTask(this).execute(Config.git_api);
|
||||
}
|
||||
|
||||
private static class retrieveGitTask extends
|
||||
AsyncTask<String, Integer, ArrayList<HashMap<String, String>>> {
|
||||
|
||||
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<>();
|
||||
try {
|
||||
JSONArray gitObject = getContent(paths[0]);
|
||||
for (int i = 0; i < gitObject.length(); i++) {
|
||||
JSONObject jsonObject = gitObject.getJSONObject(i);
|
||||
|
||||
JSONObject commitArray = jsonObject.getJSONObject("commit");
|
||||
|
||||
String date = commitArray.getJSONObject("committer")
|
||||
.getString("date").replace("T", " ").replace("Z", "");
|
||||
String author = commitArray.getJSONObject("author").getString("name");
|
||||
String committer = commitArray.getJSONObject("committer").getString("name");
|
||||
|
||||
String avatar;
|
||||
if (!jsonObject.getString("committer").equals("null")) {
|
||||
avatar = jsonObject.getJSONObject("committer").getString("avatar_url");
|
||||
committer = committer + " (" + jsonObject
|
||||
.getJSONObject("committer").getString("login") + ")";
|
||||
if (avatar.equals("null")) {
|
||||
avatar = "https://github.com/apple-touch-icon-144.png";
|
||||
}
|
||||
} else {
|
||||
avatar = "https://github.com/apple-touch-icon-144.png";
|
||||
}
|
||||
if (!jsonObject.getString("author").equals("null")) {
|
||||
author = author + " (" + jsonObject.getJSONObject(
|
||||
"author").getString("login") + ")";
|
||||
}
|
||||
String sha = jsonObject.getString("sha");
|
||||
String curl = jsonObject.getString("url")
|
||||
.replace("https://api.github.com/repos", "https://github.com")
|
||||
.replace("commits", "commit");
|
||||
|
||||
String title;
|
||||
String message = "No commit message attached";
|
||||
|
||||
if (commitArray.getString("message").contains("\n\n")) {
|
||||
String fullOutput = commitArray.getString("message");
|
||||
title = fullOutput.substring(0, fullOutput.indexOf("\n\n"));
|
||||
message = fullOutput.substring(
|
||||
fullOutput.indexOf("\n\n") + 1, fullOutput.length());
|
||||
} else {
|
||||
title = commitArray.getString("message");
|
||||
}
|
||||
|
||||
HashMap<String, String> map = new HashMap<>();
|
||||
map.put("Date", date);
|
||||
map.put("Committer", committer);
|
||||
map.put("Title", title);
|
||||
map.put("Message", message);
|
||||
map.put("Sha", sha);
|
||||
map.put("Url", curl);
|
||||
map.put("Author", author);
|
||||
map.put("Avatar", avatar);
|
||||
map.put("Build", ref.get().buildId);
|
||||
commitList.add(map);
|
||||
}
|
||||
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return commitList;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(
|
||||
ArrayList<HashMap<String, String>> commitList) {
|
||||
if (commitList != null && commitList.size() > 0) {
|
||||
ListView list = (ListView) ref.get().getView().findViewById(R.id.list);
|
||||
list.setSelector(R.drawable.list_selector);
|
||||
list.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
|
||||
GitAdapter adapter = new GitAdapter(ref.get().getActivity(), commitList);
|
||||
// Set adapter as specified collection
|
||||
list.setAdapter(adapter);
|
||||
} else {
|
||||
ref.get().showToastMessage(ref.get().getActivity().getString(
|
||||
R.string.git_broken), Snackbar.LENGTH_SHORT);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private JSONArray getContent(String urlString) throws IOException, JSONException {
|
||||
HttpURLConnection conn = (HttpURLConnection) new URL(urlString).openConnection();
|
||||
conn.setRequestMethod("GET");
|
||||
conn.setDoInput(true);
|
||||
|
||||
int responseCode = conn.getResponseCode();
|
||||
if (responseCode == HttpsURLConnection.HTTP_OK) {
|
||||
InputStream in = conn.getInputStream();
|
||||
BufferedReader streamReader = new BufferedReader(
|
||||
new InputStreamReader(in, "UTF-8"));
|
||||
StringBuilder responseStrBuilder = new StringBuilder();
|
||||
|
||||
String inputStr;
|
||||
while ((inputStr = streamReader.readLine()) != null)
|
||||
responseStrBuilder.append(inputStr);
|
||||
|
||||
in.close();
|
||||
return new JSONArray(responseStrBuilder.toString());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
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_info_outline, getActivity().getTheme());
|
||||
} else {
|
||||
drawable = VectorDrawableCompat.create(getResources(),
|
||||
R.drawable.ic_info_outline, getActivity().getTheme());
|
||||
}
|
||||
textView.setCompoundDrawablesWithIntrinsicBounds(drawable, null, null, null);
|
||||
textView.setCompoundDrawablePadding(getResources()
|
||||
.getDimensionPixelOffset(R.dimen.snackbar_icon_padding));
|
||||
snackbar.show();
|
||||
}
|
||||
}
|
|
@ -10,38 +10,18 @@ import android.view.SurfaceHolder;
|
|||
import com.reicast.emulator.emu.JNIdc;
|
||||
import com.reicast.emulator.emu.NativeGLView;
|
||||
|
||||
public class BaseNativeGLActivity extends Activity implements SurfaceHolder.Callback {
|
||||
protected boolean editVjoyMode;
|
||||
public class BaseNativeGLActivity extends Activity {
|
||||
protected NativeGLView mView;
|
||||
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
String fileName = null;
|
||||
if (getIntent().getAction().equals("com.reicast.EMULATOR"))
|
||||
fileName = Uri.decode(getIntent().getData().toString());
|
||||
|
||||
// Create the actual GL view
|
||||
try {
|
||||
mView = new NativeGLView(this, fileName, editVjoyMode);
|
||||
setContentView(mView);
|
||||
mView.getHolder().addCallback(this);
|
||||
} catch (NativeGLView.EmulatorInitFailed e) {
|
||||
finish();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
JNIdc.pause();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
JNIdc.resume();
|
||||
// mView = new NativeGLView(this);
|
||||
// setContentView(mView);
|
||||
setContentView(R.layout.nativegl_content);
|
||||
mView = (NativeGLView)findViewById(R.id.glView);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -51,25 +31,6 @@ public class BaseNativeGLActivity extends Activity implements SurfaceHolder.Call
|
|||
}
|
||||
|
||||
protected void stopEmulator() {
|
||||
if (mView != null) {
|
||||
mView.stop();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void surfaceCreated(SurfaceHolder holder) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
|
||||
//Log.i("BaseNativeGLActivity", "surfaceChanged: " + w + "x" + h);
|
||||
JNIdc.rendinitNative(holder.getSurface(), w, h);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void surfaceDestroyed(SurfaceHolder holder) {
|
||||
//Log.i("BaseNativeGLActivity", "surfaceDestroyed");
|
||||
JNIdc.rendinitNative(null, 0, 0);
|
||||
JNIdc.stop();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
package com.reicast.emulator;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.Application;
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
|
@ -9,41 +8,12 @@ import android.support.v7.app.AppCompatDelegate;
|
|||
import android.util.Log;
|
||||
|
||||
import com.reicast.emulator.config.Config;
|
||||
import com.reicast.emulator.emu.AudioBackend;
|
||||
import com.reicast.emulator.emu.JNIdc;
|
||||
|
||||
public class Emulator extends Application {
|
||||
private static Context context;
|
||||
|
||||
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_idleskip = "idle_skip";
|
||||
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_language = "dc_language";
|
||||
public static final String pref_limitfps = "limit_fps";
|
||||
public static final String pref_nosound = "sound_disabled";
|
||||
public static final String pref_nobatch = "nobatch";
|
||||
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";
|
||||
public static final String pref_pvrrender = "pvr_render";
|
||||
public static final String pref_syncedrender = "synced_render";
|
||||
public static final String pref_modvols = "modifier_volumes";
|
||||
public static final String pref_clipping = "clipping";
|
||||
public static final String pref_bootdisk = "boot_disk";
|
||||
public static final String pref_usereios = "use_reios";
|
||||
public static final String pref_customtextures = "custom_textures";
|
||||
public static final String pref_showfps = "show_fps";
|
||||
public static final String pref_RenderToTextureBuffer = "RenderToTextureBuffer";
|
||||
public static final String pref_RenderToTextureUpscale = "RenderToTextureUpscale";
|
||||
public static final String pref_TextureUpscale = "TextureUpscale";
|
||||
public static final String pref_MaxFilteredTextureSize= "MaxFilteredTextureSize";
|
||||
public static final String pref_MaxThreads = "MaxThreads";
|
||||
public static final String pref_controller_type = "controller_type";
|
||||
public static final String pref_peripheral_type = "peripheral_type";
|
||||
// see MapleDeviceType in hw/maple/maple_devs.h
|
||||
public static final int MDT_SegaController = 0;
|
||||
public static final int MDT_SegaVMU = 1;
|
||||
|
@ -56,34 +26,9 @@ public class Emulator extends Application {
|
|||
public static final int MDT_None = 8;
|
||||
public static final int MDT_Count = 9;
|
||||
|
||||
public static boolean dynarecopt = true;
|
||||
public static boolean idleskip = true;
|
||||
public static boolean unstableopt = false;
|
||||
public static boolean dynsafemode = true;
|
||||
public static int cable = 3;
|
||||
public static int dcregion = 3;
|
||||
public static int broadcast = 4;
|
||||
public static int language = 6;
|
||||
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 int frameskip = 0;
|
||||
public static int pvrrender = 0;
|
||||
public static boolean syncedrender = true;
|
||||
public static boolean modvols = true;
|
||||
public static boolean clipping = true;
|
||||
public static String bootdisk = null;
|
||||
public static boolean usereios = false;
|
||||
public static boolean customtextures = false;
|
||||
public static boolean showfps = false;
|
||||
public static boolean RenderToTextureBuffer = false;
|
||||
public static int RenderToTextureUpscale = 1;
|
||||
public static int TextureUpscale = 1;
|
||||
public static int MaxFilteredTextureSize = 256;
|
||||
public static int MaxThreads = 1;
|
||||
public static int vibrationDuration = 20;
|
||||
|
||||
public static int maple_devices[] = {
|
||||
MDT_SegaController,
|
||||
MDT_None,
|
||||
|
@ -98,91 +43,13 @@ public class Emulator extends Application {
|
|||
};
|
||||
|
||||
/**
|
||||
* Load the user configuration from preferences
|
||||
* Load the settings from native code
|
||||
*
|
||||
*/
|
||||
public void getConfigurationPrefs(SharedPreferences mPrefs) {
|
||||
Emulator.dynarecopt = mPrefs.getBoolean(pref_dynarecopt, dynarecopt);
|
||||
Emulator.unstableopt = mPrefs.getBoolean(pref_unstable, unstableopt);
|
||||
Emulator.dynsafemode = mPrefs.getBoolean(pref_dynsafemode, dynsafemode);
|
||||
Emulator.idleskip = mPrefs.getBoolean(pref_idleskip, idleskip);
|
||||
Emulator.cable = mPrefs.getInt(pref_cable, cable);
|
||||
Emulator.dcregion = mPrefs.getInt(pref_dcregion, dcregion);
|
||||
Emulator.broadcast = mPrefs.getInt(pref_broadcast, broadcast);
|
||||
Emulator.language = mPrefs.getInt(pref_language, language);
|
||||
Emulator.limitfps = mPrefs.getBoolean(pref_limitfps, limitfps);
|
||||
Emulator.nosound = mPrefs.getBoolean(pref_nosound, nosound);
|
||||
Emulator.nobatch = mPrefs.getBoolean(pref_nobatch, nobatch);
|
||||
Emulator.mipmaps = mPrefs.getBoolean(pref_mipmaps, mipmaps);
|
||||
Emulator.widescreen = mPrefs.getBoolean(pref_widescreen, widescreen);
|
||||
Emulator.frameskip = mPrefs.getInt(pref_frameskip, frameskip);
|
||||
Emulator.pvrrender = mPrefs.getInt(pref_pvrrender, pvrrender);
|
||||
Emulator.syncedrender = mPrefs.getBoolean(pref_syncedrender, syncedrender);
|
||||
Emulator.modvols = mPrefs.getBoolean(pref_modvols, modvols);
|
||||
Emulator.clipping = mPrefs.getBoolean(pref_clipping, clipping);
|
||||
Emulator.bootdisk = mPrefs.getString(pref_bootdisk, bootdisk);
|
||||
Emulator.usereios = mPrefs.getBoolean(pref_usereios, usereios);
|
||||
Emulator.customtextures = mPrefs.getBoolean(pref_customtextures, customtextures);
|
||||
Emulator.showfps = mPrefs.getBoolean(pref_showfps, showfps);
|
||||
Emulator.RenderToTextureBuffer = mPrefs.getBoolean(pref_RenderToTextureBuffer, RenderToTextureBuffer);
|
||||
Emulator.RenderToTextureUpscale = mPrefs.getInt(pref_RenderToTextureUpscale, RenderToTextureUpscale);
|
||||
Emulator.TextureUpscale = mPrefs.getInt(pref_TextureUpscale, TextureUpscale);
|
||||
Emulator.MaxFilteredTextureSize = mPrefs.getInt(pref_MaxFilteredTextureSize, MaxFilteredTextureSize);
|
||||
Emulator.MaxThreads = mPrefs.getInt(pref_MaxThreads, MaxThreads);
|
||||
for (int i = 0; i < maple_devices.length; i++) {
|
||||
maple_devices[i] = mPrefs.getInt(pref_controller_type + i, Emulator.maple_devices[i]);
|
||||
maple_expansion_devices[i][0] = mPrefs.getInt(pref_peripheral_type + i + "0", Emulator.maple_expansion_devices[i][0]);
|
||||
maple_expansion_devices[i][1] = mPrefs.getInt(pref_peripheral_type + i + "1", Emulator.maple_expansion_devices[i][1]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Write configuration settings to the emulator
|
||||
*
|
||||
*/
|
||||
public void loadConfigurationPrefs() {
|
||||
JNIdc.setDynarec(Emulator.dynarecopt);
|
||||
JNIdc.setIdleskip(Emulator.idleskip);
|
||||
JNIdc.setUnstable(Emulator.unstableopt);
|
||||
JNIdc.setSafemode(Emulator.dynsafemode);
|
||||
JNIdc.setCable(Emulator.cable);
|
||||
JNIdc.setRegion(Emulator.dcregion);
|
||||
JNIdc.setBroadcast(Emulator.broadcast);
|
||||
JNIdc.setLanguage(Emulator.language);
|
||||
JNIdc.setLimitfps(Emulator.limitfps);
|
||||
JNIdc.setNobatch(Emulator.nobatch);
|
||||
JNIdc.setNosound(Emulator.nosound);
|
||||
JNIdc.setMipmaps(Emulator.mipmaps);
|
||||
JNIdc.setWidescreen(Emulator.widescreen);
|
||||
JNIdc.setFrameskip(Emulator.frameskip);
|
||||
JNIdc.setPvrrender(Emulator.pvrrender);
|
||||
JNIdc.setSyncedrender(Emulator.syncedrender);
|
||||
JNIdc.setModvols(Emulator.modvols);
|
||||
JNIdc.setClipping(Emulator.clipping);
|
||||
JNIdc.setUsereios(Emulator.usereios);
|
||||
JNIdc.bootdisk(Emulator.bootdisk);
|
||||
JNIdc.setCustomtextures(Emulator.customtextures);
|
||||
JNIdc.setShowfps(Emulator.showfps);
|
||||
JNIdc.setRenderToTextureBuffer(Emulator.RenderToTextureBuffer);
|
||||
JNIdc.setRenderToTextureUpscale(Emulator.RenderToTextureUpscale);
|
||||
JNIdc.setTextureUpscale(Emulator.TextureUpscale);
|
||||
JNIdc.setMaxFilteredTextureSize(Emulator.MaxFilteredTextureSize);
|
||||
JNIdc.setMaxThreads(Emulator.MaxThreads);
|
||||
JNIdc.initControllers(maple_devices, maple_expansion_devices);
|
||||
}
|
||||
|
||||
public void loadGameConfiguration(String gameId) {
|
||||
SharedPreferences mPrefs = getSharedPreferences(gameId, Activity.MODE_PRIVATE);
|
||||
JNIdc.setDynarec(mPrefs.getBoolean(pref_dynarecopt, dynarecopt));
|
||||
JNIdc.setUnstable(mPrefs.getBoolean(pref_unstable, unstableopt));
|
||||
JNIdc.setSafemode(mPrefs.getBoolean(pref_dynsafemode, dynsafemode));
|
||||
JNIdc.setFrameskip(mPrefs.getInt(pref_frameskip, frameskip));
|
||||
JNIdc.setPvrrender(mPrefs.getInt(pref_pvrrender, pvrrender));
|
||||
JNIdc.setSyncedrender(mPrefs.getBoolean(pref_syncedrender, syncedrender));
|
||||
JNIdc.setModvols(mPrefs.getBoolean(pref_modvols, modvols));
|
||||
JNIdc.setClipping(mPrefs.getBoolean(pref_clipping, clipping));
|
||||
JNIdc.bootdisk(mPrefs.getString(pref_bootdisk, bootdisk));
|
||||
JNIdc.setCustomtextures(mPrefs.getBoolean(pref_customtextures, customtextures));
|
||||
public void getConfigurationPrefs() {
|
||||
Emulator.nosound = JNIdc.getNosound();
|
||||
Emulator.vibrationDuration = JNIdc.getVirtualGamepadVibration();
|
||||
JNIdc.getControllers(maple_devices, maple_expansion_devices);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -191,75 +58,19 @@ public class Emulator extends Application {
|
|||
*/
|
||||
public void SaveAndroidSettings(String homeDirectory)
|
||||
{
|
||||
Log.i("Emulator", "SaveAndroidSettings: saving preferences");
|
||||
Log.i("reicast", "SaveAndroidSettings: saving preferences");
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
|
||||
|
||||
Emulator.dynarecopt = JNIdc.getDynarec();
|
||||
Emulator.idleskip = JNIdc.getIdleskip();
|
||||
Emulator.unstableopt = JNIdc.getUnstable();
|
||||
Emulator.dynsafemode = JNIdc.getSafemode();
|
||||
Emulator.cable = JNIdc.getCable();
|
||||
Emulator.dcregion = JNIdc.getRegion();
|
||||
Emulator.broadcast = JNIdc.getBroadcast();
|
||||
Emulator.language = JNIdc.getLanguage();
|
||||
Emulator.limitfps = JNIdc.getLimitfps();
|
||||
Emulator.nobatch = JNIdc.getNobatch();
|
||||
Emulator.nosound = JNIdc.getNosound();
|
||||
Emulator.mipmaps = JNIdc.getMipmaps();
|
||||
Emulator.widescreen = JNIdc.getWidescreen();
|
||||
Emulator.frameskip = JNIdc.getFrameskip();
|
||||
Emulator.pvrrender = JNIdc.getPvrrender();
|
||||
Emulator.syncedrender = JNIdc.getSyncedrender();
|
||||
Emulator.modvols = JNIdc.getModvols();
|
||||
Emulator.clipping = JNIdc.getClipping();
|
||||
Emulator.usereios = JNIdc.getUsereios();
|
||||
//Emulator.bootdisk = JNIdc.getBootdisk();
|
||||
Emulator.customtextures = JNIdc.getCustomtextures();
|
||||
Emulator.showfps = JNIdc.getShowfps();
|
||||
Emulator.RenderToTextureBuffer = JNIdc.getRenderToTextureBuffer();
|
||||
Emulator.RenderToTextureUpscale = JNIdc.getRenderToTextureUpscale();
|
||||
Emulator.TextureUpscale = JNIdc.getTextureUpscale();
|
||||
Emulator.MaxFilteredTextureSize = JNIdc.getMaxFilteredTextureSize();
|
||||
Emulator.MaxThreads = JNIdc.getMaxThreads();
|
||||
Emulator.vibrationDuration = JNIdc.getVirtualGamepadVibration();
|
||||
JNIdc.getControllers(maple_devices, maple_expansion_devices);
|
||||
|
||||
SharedPreferences.Editor editor = prefs.edit()
|
||||
.putString(Config.pref_home, homeDirectory)
|
||||
.putBoolean(Emulator.pref_dynarecopt, Emulator.dynarecopt)
|
||||
.putBoolean(Emulator.pref_idleskip, Emulator.idleskip)
|
||||
.putBoolean(Emulator.pref_unstable, Emulator.unstableopt)
|
||||
.putBoolean(Emulator.pref_dynsafemode, Emulator.dynsafemode)
|
||||
.putInt(Emulator.pref_cable, Emulator.cable)
|
||||
.putInt(Emulator.pref_dcregion, Emulator.dcregion)
|
||||
.putInt(Emulator.pref_broadcast, Emulator.broadcast)
|
||||
.putInt(Emulator.pref_language, Emulator.language)
|
||||
.putBoolean(Emulator.pref_limitfps, Emulator.limitfps)
|
||||
.putBoolean(Emulator.pref_nobatch, Emulator.nobatch)
|
||||
.putBoolean(Emulator.pref_nosound, Emulator.nosound)
|
||||
.putBoolean(Emulator.pref_mipmaps, Emulator.mipmaps)
|
||||
.putBoolean(Emulator.pref_widescreen, Emulator.widescreen)
|
||||
.putInt(Emulator.pref_frameskip, Emulator.frameskip)
|
||||
.putInt(Emulator.pref_pvrrender, Emulator.pvrrender)
|
||||
.putBoolean(Emulator.pref_syncedrender, Emulator.syncedrender)
|
||||
.putBoolean(Emulator.pref_modvols, Emulator.modvols)
|
||||
.putBoolean(Emulator.pref_clipping, Emulator.clipping)
|
||||
.putBoolean(Emulator.pref_usereios, Emulator.usereios)
|
||||
.putBoolean(Emulator.pref_customtextures, Emulator.customtextures)
|
||||
.putBoolean(Emulator.pref_showfps, Emulator.showfps)
|
||||
.putBoolean(Emulator.pref_RenderToTextureBuffer, Emulator.RenderToTextureBuffer)
|
||||
.putInt(Emulator.pref_RenderToTextureUpscale, Emulator.RenderToTextureUpscale)
|
||||
.putInt(Emulator.pref_TextureUpscale, Emulator.TextureUpscale)
|
||||
.putInt(Emulator.pref_MaxFilteredTextureSize, Emulator.MaxFilteredTextureSize)
|
||||
.putInt(Emulator.pref_MaxThreads, Emulator.MaxThreads);
|
||||
for (int i = 0; i < maple_devices.length; i++) {
|
||||
editor.putInt(pref_controller_type + i, Emulator.maple_devices[i]);
|
||||
editor.putInt(pref_peripheral_type + i + "0", Emulator.maple_expansion_devices[i][0]);
|
||||
editor.putInt(pref_peripheral_type + i + "1", Emulator.maple_expansion_devices[i][1]);
|
||||
}
|
||||
editor.apply();
|
||||
prefs.edit()
|
||||
.putString(Config.pref_home, homeDirectory).apply();
|
||||
AudioBackend.getInstance().enableSound(!Emulator.nosound);
|
||||
}
|
||||
|
||||
public static boolean micPluggedIn() {
|
||||
JNIdc.getControllers(maple_devices, maple_expansion_devices);
|
||||
for (int i = 0; i < maple_expansion_devices.length; i++)
|
||||
if (maple_expansion_devices[i][0] == MDT_Microphone
|
||||
|| maple_expansion_devices[i][1] == MDT_Microphone)
|
||||
|
|
|
@ -26,7 +26,6 @@ import com.reicast.emulator.config.Config;
|
|||
import com.reicast.emulator.emu.GL2JNIView;
|
||||
import com.reicast.emulator.emu.JNIdc;
|
||||
import com.reicast.emulator.emu.OnScreenMenu;
|
||||
import com.reicast.emulator.emu.OnScreenMenu.FpsPopup;
|
||||
import com.reicast.emulator.periph.Gamepad;
|
||||
import com.reicast.emulator.periph.InputDeviceManager;
|
||||
import com.reicast.emulator.periph.SipEmulator;
|
||||
|
@ -37,8 +36,6 @@ import tv.ouya.console.api.OuyaController;
|
|||
|
||||
public class GL2JNIActivity extends Activity implements ActivityCompat.OnRequestPermissionsResultCallback {
|
||||
public GL2JNIView mView;
|
||||
OnScreenMenu menu;
|
||||
FpsPopup fpsPop;
|
||||
private SharedPreferences prefs;
|
||||
|
||||
private Gamepad pad = new Gamepad();
|
||||
|
@ -57,8 +54,7 @@ public class GL2JNIActivity extends Activity implements ActivityCompat.OnRequest
|
|||
InputDeviceManager.getInstance().startListening(getApplicationContext());
|
||||
|
||||
Emulator app = (Emulator)getApplicationContext();
|
||||
app.getConfigurationPrefs(prefs);
|
||||
menu = new OnScreenMenu(GL2JNIActivity.this, prefs);
|
||||
app.getConfigurationPrefs();
|
||||
|
||||
pad.isOuyaOrTV = pad.IsOuyaOrTV(GL2JNIActivity.this, false);
|
||||
|
||||
|
@ -89,7 +85,7 @@ public class GL2JNIActivity extends Activity implements ActivityCompat.OnRequest
|
|||
prefs.getString(Gamepad.pref_player4, null), 3);
|
||||
pad.deviceDescriptor_PlayerNum.remove(null);
|
||||
|
||||
JNIdc.initControllers(Emulator.maple_devices, Emulator.maple_expansion_devices);
|
||||
// JNIdc.initControllers(Emulator.maple_devices, Emulator.maple_expansion_devices);
|
||||
|
||||
int joys[] = InputDevice.getDeviceIds();
|
||||
for (int joy: joys) {
|
||||
|
@ -153,21 +149,10 @@ public class GL2JNIActivity extends Activity implements ActivityCompat.OnRequest
|
|||
pad.fullCompatibilityMode(prefs);
|
||||
}
|
||||
|
||||
app.loadConfigurationPrefs();
|
||||
|
||||
// When viewing a resource, pass its URI to the native code for opening
|
||||
if (getIntent().getAction().equals("com.reicast.EMULATOR"))
|
||||
fileName = Uri.decode(getIntent().getData().toString());
|
||||
|
||||
try {
|
||||
// Create the actual GLES view
|
||||
mView = new GL2JNIView(GL2JNIActivity.this, fileName, false,
|
||||
mView = new GL2JNIView(GL2JNIActivity.this, false,
|
||||
prefs.getInt(Config.pref_renderdepth, 24), 8, false);
|
||||
setContentView(mView);
|
||||
} catch (GL2JNIView.EmulatorInitFailed e) {
|
||||
finish();
|
||||
return;
|
||||
}
|
||||
setContentView(mView);
|
||||
|
||||
//setup mic
|
||||
if (Emulator.micPluggedIn()) {
|
||||
|
@ -183,27 +168,12 @@ public class GL2JNIActivity extends Activity implements ActivityCompat.OnRequest
|
|||
onRequestPermissionsResult(0, new String[] { Manifest.permission.RECORD_AUDIO }, new int[] { PackageManager.PERMISSION_GRANTED });
|
||||
}
|
||||
}
|
||||
|
||||
if (Emulator.showfps) {
|
||||
fpsPop = menu.new FpsPopup(this);
|
||||
mView.setFpsDisplay(fpsPop);
|
||||
mView.post(new Runnable() {
|
||||
public void run() {
|
||||
displayFPS();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public Gamepad getPad() {
|
||||
return pad;
|
||||
}
|
||||
|
||||
public void displayFPS() {
|
||||
fpsPop.showAtLocation(mView, Gravity.TOP | Gravity.LEFT, 20, 20);
|
||||
fpsPop.update(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
|
||||
}
|
||||
|
||||
public void screenGrab() {
|
||||
mView.screenGrab();
|
||||
}
|
||||
|
@ -313,7 +283,6 @@ public class GL2JNIActivity extends Activity implements ActivityCompat.OnRequest
|
|||
InputDeviceManager.getInstance().stopListening();
|
||||
if (mView != null) {
|
||||
mView.onDestroy();
|
||||
// FIXME This should be called to deinit what's been inited...
|
||||
JNIdc.destroy();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,56 +2,34 @@ 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;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.content.res.Configuration;
|
||||
import android.net.Uri;
|
||||
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.view.GravityCompat;
|
||||
import android.support.v4.widget.DrawerLayout;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.support.v7.widget.SearchView;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.util.Log;
|
||||
import android.view.Gravity;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.View.OnSystemUiVisibilityChangeListener;
|
||||
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.debug.GenerateLogs;
|
||||
import com.reicast.emulator.emu.JNIdc;
|
||||
|
||||
import java.lang.Thread.UncaughtExceptionHandler;
|
||||
import java.util.List;
|
||||
|
||||
public class MainActivity extends AppCompatActivity implements
|
||||
NavigationView.OnNavigationItemSelectedListener, FileBrowser.OnItemSelectedListener,
|
||||
OptionsFragment.OnClickListener, InputFragment.OnClickListener {
|
||||
public class MainActivity extends AppCompatActivity {
|
||||
private static final int PERMISSION_REQUEST = 1001;
|
||||
|
||||
private SharedPreferences mPrefs;
|
||||
private boolean hasAndroidMarket = false;
|
||||
private boolean activity_paused = false;
|
||||
private boolean renderer_started = false;
|
||||
private Uri gameUri;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
|
@ -76,39 +54,29 @@ public class MainActivity extends AppCompatActivity implements
|
|||
WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
||||
}
|
||||
|
||||
mPrefs = PreferenceManager.getDefaultSharedPreferences(this);
|
||||
final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
|
||||
|
||||
String prior_error = mPrefs.getString("prior_error", null);
|
||||
String prior_error = prefs.getString("prior_error", null);
|
||||
if (prior_error != null) {
|
||||
displayLogOutput(prior_error);
|
||||
mPrefs.edit().remove("prior_error").apply();
|
||||
} else {
|
||||
UncaughtExceptionHandler mUEHandler = new Thread.UncaughtExceptionHandler() {
|
||||
public void uncaughtException(Thread t, Throwable error) {
|
||||
if (error != null) {
|
||||
StringBuilder output = new StringBuilder();
|
||||
for (StackTraceElement trace : error.getStackTrace()) {
|
||||
output.append(trace.toString());
|
||||
output.append("\n");
|
||||
}
|
||||
mPrefs.edit().putString("prior_error", output.toString()).apply();
|
||||
error.printStackTrace();
|
||||
android.os.Process.killProcess(android.os.Process.myPid());
|
||||
System.exit(0);
|
||||
prefs.edit().remove("prior_error").apply();
|
||||
}
|
||||
UncaughtExceptionHandler mUEHandler = new Thread.UncaughtExceptionHandler() {
|
||||
public void uncaughtException(Thread t, Throwable error) {
|
||||
if (error != null) {
|
||||
StringBuilder output = new StringBuilder();
|
||||
for (StackTraceElement trace : error.getStackTrace()) {
|
||||
output.append(trace.toString());
|
||||
output.append("\n");
|
||||
}
|
||||
prefs.edit().putString("prior_error", output.toString()).apply();
|
||||
error.printStackTrace();
|
||||
android.os.Process.killProcess(android.os.Process.myPid());
|
||||
System.exit(0);
|
||||
}
|
||||
};
|
||||
Thread.setDefaultUncaughtExceptionHandler(mUEHandler);
|
||||
}
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
ActivityCompat.requestPermissions(MainActivity.this,
|
||||
new String[] {
|
||||
Manifest.permission.READ_EXTERNAL_STORAGE,
|
||||
Manifest.permission.WRITE_EXTERNAL_STORAGE
|
||||
},
|
||||
PERMISSION_REQUEST);
|
||||
}
|
||||
}
|
||||
};
|
||||
Thread.setDefaultUncaughtExceptionHandler(mUEHandler);
|
||||
|
||||
Intent market = new Intent(Intent.ACTION_VIEW, Uri.parse("market://search?q=dummy"));
|
||||
if (isCallable(market)) {
|
||||
|
@ -118,85 +86,28 @@ public class MainActivity extends AppCompatActivity implements
|
|||
if (!getFilesDir().exists()) {
|
||||
getFilesDir().mkdir();
|
||||
}
|
||||
String home_directory = mPrefs.getString(Config.pref_home, "");
|
||||
String result = JNIdc.initEnvironment((Emulator)getApplicationContext(), home_directory);
|
||||
if (result != null)
|
||||
showToastMessage("Initialization failed: " + result,
|
||||
Snackbar.LENGTH_LONG);
|
||||
|
||||
String android_home_directory = Environment.getExternalStorageDirectory().getAbsolutePath();
|
||||
JNIdc.config(android_home_directory);
|
||||
|
||||
// When viewing a resource, pass its URI to the native code for opening
|
||||
Intent intent = getIntent();
|
||||
if (intent.getAction() != null) {
|
||||
if (intent.getAction().equals(Intent.ACTION_VIEW)) {
|
||||
onGameSelected(Uri.parse(intent.getData().toString()));
|
||||
gameUri = Uri.parse(intent.getData().toString());
|
||||
// Flush the intent to prevent multiple calls
|
||||
getIntent().setData(null);
|
||||
setIntent(null);
|
||||
Config.externalIntent = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Check that the activity is using the layout version with
|
||||
// the fragment_container FrameLayout
|
||||
if (findViewById(R.id.fragment_container) != null) {
|
||||
onMainBrowseSelected(null, true, null);
|
||||
}
|
||||
|
||||
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
|
||||
setSupportActionBar(toolbar);
|
||||
|
||||
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
|
||||
android.support.v7.app.ActionBarDrawerToggle toggle = new android.support.v7.app.ActionBarDrawerToggle(
|
||||
this, drawer, toolbar, R.string.drawer_open, R.string.drawer_shut) {
|
||||
@Override
|
||||
public void onDrawerOpened(View drawerView) {
|
||||
|
||||
}
|
||||
@Override
|
||||
public void onDrawerClosed(View drawerView) {
|
||||
|
||||
}
|
||||
};
|
||||
//noinspection deprecation
|
||||
drawer.setDrawerListener(toggle);
|
||||
toggle.syncState();
|
||||
|
||||
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
|
||||
if (!hasAndroidMarket) {
|
||||
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);
|
||||
if (searchView != null) {
|
||||
searchView.setQueryHint(getString(R.string.search_hint));
|
||||
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
|
||||
@Override
|
||||
public boolean onQueryTextSubmit(String query) {
|
||||
onMainBrowseSelected(mPrefs.getString(Config.pref_games,
|
||||
Environment.getExternalStorageDirectory().getAbsolutePath()),
|
||||
true, query);
|
||||
searchView.onActionViewCollapsed();
|
||||
return false;
|
||||
}
|
||||
@Override
|
||||
public boolean onQueryTextChange(String s) {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
if (prior_error == null) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
ActivityCompat.requestPermissions(MainActivity.this,
|
||||
new String[]{
|
||||
Manifest.permission.READ_EXTERNAL_STORAGE,
|
||||
Manifest.permission.WRITE_EXTERNAL_STORAGE
|
||||
},
|
||||
PERMISSION_REQUEST);
|
||||
} else
|
||||
startNativeRenderer();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -218,308 +129,41 @@ public class MainActivity extends AppCompatActivity implements
|
|||
new DialogInterface.OnClickListener() {
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
generateErrorLog();
|
||||
startNativeRenderer();
|
||||
}
|
||||
});
|
||||
builder.setNegativeButton(R.string.dismiss,
|
||||
new DialogInterface.OnClickListener() {
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
dialog.dismiss();
|
||||
startNativeRenderer();
|
||||
}
|
||||
});
|
||||
builder.create();
|
||||
builder.show();
|
||||
}
|
||||
|
||||
public void onEditorSelected(Uri uri) {
|
||||
if (activity_paused)
|
||||
private void startNativeRenderer() {
|
||||
if (renderer_started)
|
||||
return;
|
||||
activity_paused = true;
|
||||
String home_directory = mPrefs.getString(Config.pref_home,
|
||||
Environment.getExternalStorageDirectory().getAbsolutePath());
|
||||
renderer_started = true;
|
||||
|
||||
//JNIdc.config(home_directory);
|
||||
|
||||
startActivity(new Intent("com.reicast.EMULATOR", uri,
|
||||
getApplicationContext(), EditVJoyActivity.class));
|
||||
}
|
||||
|
||||
public void onGameSelected(Uri uri) {
|
||||
if (activity_paused)
|
||||
return;
|
||||
activity_paused = true;
|
||||
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"));
|
||||
if (gameUri != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||
gameUri = Uri.parse(gameUri.toString().replace("content://"
|
||||
+ gameUri.getAuthority() + "/external_files", "/storage"));
|
||||
}
|
||||
|
||||
if (gameUri != null)
|
||||
JNIdc.setGameUri(gameUri.toString());
|
||||
Intent intent = new Intent("com.reicast.EMULATOR",
|
||||
// uri, getApplicationContext(), GL2JNIActivity.class);
|
||||
uri, getApplicationContext(), NativeGLActivity.class);
|
||||
gameUri, getApplicationContext(), NativeGLActivity.class);
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
|
||||
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
|
||||
startActivity(intent);
|
||||
}
|
||||
|
||||
public void onFolderSelected(Uri uri) {
|
||||
FileBrowser browserFrag = (FileBrowser) getSupportFragmentManager()
|
||||
.findFragmentByTag("MAIN_BROWSER");
|
||||
if (browserFrag != null) {
|
||||
if (browserFrag.isVisible()) {
|
||||
Log.d("reicast", "Main folder: " + uri.toString());
|
||||
// return;
|
||||
}
|
||||
}
|
||||
|
||||
OptionsFragment optsFrag = new OptionsFragment();
|
||||
getSupportFragmentManager().beginTransaction().replace(
|
||||
R.id.fragment_container, optsFrag, "OPTIONS_FRAG").commit();
|
||||
setTitle(R.string.settings);
|
||||
}
|
||||
|
||||
/**
|
||||
* Launch the browser activity with specified parameters
|
||||
*
|
||||
* @param path
|
||||
* The root path of the browser fragment
|
||||
* @param games
|
||||
* Conditional for viewing games or BIOS
|
||||
* @param query
|
||||
* Search parameters to limit list items
|
||||
*/
|
||||
public void onMainBrowseSelected(String path, boolean games, String query) {
|
||||
FileBrowser firstFragment = new FileBrowser();
|
||||
Bundle args = new Bundle();
|
||||
args.putString("browse_entry", path);
|
||||
// specify a path for selecting folder options
|
||||
args.putBoolean("games_entry", games);
|
||||
// specify if the desired path is for games or data
|
||||
args.putString("search_params", query);
|
||||
|
||||
firstFragment.setArguments(args);
|
||||
// In case this activity was started with special instructions from
|
||||
// an Intent, pass the Intent's extras to the fragment as arguments
|
||||
// firstFragment.setArguments(getIntent().getExtras());
|
||||
|
||||
// Add the fragment to the 'fragment_container' FrameLayout
|
||||
getSupportFragmentManager()
|
||||
.beginTransaction()
|
||||
.replace(R.id.fragment_container, firstFragment, "MAIN_BROWSER")
|
||||
.addToBackStack(null).commit();
|
||||
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);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onKeyDown(int keyCode, KeyEvent event) {
|
||||
if (keyCode == KeyEvent.KEYCODE_BACK) {
|
||||
Fragment fragment = getSupportFragmentManager().findFragmentByTag("MAIN_BROWSER");
|
||||
if (fragment != null && fragment.isVisible()) {
|
||||
boolean readyToQuit = true;
|
||||
if (fragment.getArguments() != null) {
|
||||
readyToQuit = fragment.getArguments().getBoolean(
|
||||
"games_entry", true);
|
||||
}
|
||||
if (readyToQuit) {
|
||||
MainActivity.this.finish();
|
||||
} else {
|
||||
launchMainFragment();
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
launchMainFragment();
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return super.onKeyDown(keyCode, event);
|
||||
}
|
||||
|
||||
private void launchMainFragment() {
|
||||
onMainBrowseSelected(null, true, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
activity_paused = false;
|
||||
|
||||
CloudFragment cloudfragment = (CloudFragment) getSupportFragmentManager()
|
||||
.findFragmentByTag("CLOUD_FRAG");
|
||||
if (cloudfragment != null && cloudfragment.isVisible()) {
|
||||
cloudfragment.onResume();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPostCreate(Bundle savedInstanceState) {
|
||||
super.onPostCreate(savedInstanceState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
|
||||
// Handle navigation view item clicks here.
|
||||
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
|
||||
|
||||
switch (item.getItemId()) {
|
||||
|
||||
case R.id.browser_menu:
|
||||
FileBrowser browseFrag = (FileBrowser) getSupportFragmentManager()
|
||||
.findFragmentByTag("MAIN_BROWSER");
|
||||
if (browseFrag != null) {
|
||||
if (browseFrag.isVisible()) {
|
||||
drawer.closeDrawer(GravityCompat.START);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
browseFrag = new FileBrowser();
|
||||
Bundle args = new Bundle();
|
||||
args.putString("browse_entry", null);
|
||||
// specify a path for selecting folder options
|
||||
args.putBoolean("games_entry", true);
|
||||
// specify if the desired path is for games or data
|
||||
browseFrag.setArguments(args);
|
||||
getSupportFragmentManager()
|
||||
.beginTransaction()
|
||||
.replace(R.id.fragment_container, browseFrag, "MAIN_BROWSER")
|
||||
.addToBackStack(null).commit();
|
||||
setTitle(R.string.browser);
|
||||
drawer.closeDrawer(GravityCompat.START);
|
||||
return true;
|
||||
|
||||
case R.id.settings_menu:
|
||||
OptionsFragment optionsFrag = (OptionsFragment) getSupportFragmentManager()
|
||||
.findFragmentByTag("OPTIONS_FRAG");
|
||||
if (optionsFrag != null) {
|
||||
if (optionsFrag.isVisible()) {
|
||||
drawer.closeDrawer(GravityCompat.START);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
optionsFrag = new OptionsFragment();
|
||||
getSupportFragmentManager()
|
||||
.beginTransaction()
|
||||
.replace(R.id.fragment_container, optionsFrag, "OPTIONS_FRAG")
|
||||
.addToBackStack(null).commit();
|
||||
setTitle(R.string.settings);
|
||||
drawer.closeDrawer(GravityCompat.START);
|
||||
return true;
|
||||
|
||||
case R.id.input_menu:
|
||||
InputFragment inputFrag = (InputFragment) getSupportFragmentManager()
|
||||
.findFragmentByTag("INPUT_FRAG");
|
||||
if (inputFrag != null) {
|
||||
if (inputFrag.isVisible()) {
|
||||
drawer.closeDrawer(GravityCompat.START);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
inputFrag = new InputFragment();
|
||||
getSupportFragmentManager()
|
||||
.beginTransaction()
|
||||
.replace(R.id.fragment_container, inputFrag, "INPUT_FRAG")
|
||||
.addToBackStack(null).commit();
|
||||
setTitle(R.string.input);
|
||||
drawer.closeDrawer(GravityCompat.START);
|
||||
return true;
|
||||
|
||||
case R.id.about_menu:
|
||||
AboutFragment aboutFrag = (AboutFragment) getSupportFragmentManager()
|
||||
.findFragmentByTag("ABOUT_FRAG");
|
||||
if (aboutFrag != null) {
|
||||
if (aboutFrag.isVisible()) {
|
||||
drawer.closeDrawer(GravityCompat.START);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
aboutFrag = new AboutFragment();
|
||||
getSupportFragmentManager()
|
||||
.beginTransaction()
|
||||
.replace(R.id.fragment_container, aboutFrag, "ABOUT_FRAG")
|
||||
.addToBackStack(null).commit();
|
||||
setTitle(R.string.about);
|
||||
drawer.closeDrawer(GravityCompat.START);
|
||||
return true;
|
||||
|
||||
case R.id.cloud_menu:
|
||||
CloudFragment cloudFrag = (CloudFragment) getSupportFragmentManager()
|
||||
.findFragmentByTag("CLOUD_FRAG");
|
||||
if (cloudFrag != null) {
|
||||
if (cloudFrag.isVisible()) {
|
||||
drawer.closeDrawer(GravityCompat.START);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
cloudFrag = new CloudFragment();
|
||||
getSupportFragmentManager()
|
||||
.beginTransaction()
|
||||
.replace(R.id.fragment_container, cloudFrag, "CLOUD_FRAG")
|
||||
.addToBackStack(null).commit();
|
||||
setTitle(R.string.cloud);
|
||||
drawer.closeDrawer(GravityCompat.START);
|
||||
return true;
|
||||
|
||||
case R.id.rateme_menu:
|
||||
// vib.vibrate(50);
|
||||
startActivity(new Intent(Intent.ACTION_VIEW,
|
||||
Uri.parse("market://details?id=" + getPackageName())));
|
||||
//setTitle(R.string.rateme);
|
||||
drawer.closeDrawer(GravityCompat.START);
|
||||
return true;
|
||||
|
||||
case R.id.message_menu:
|
||||
generateErrorLog();
|
||||
drawer.closeDrawer(GravityCompat.START);
|
||||
return true;
|
||||
|
||||
default:
|
||||
drawer.closeDrawer(GravityCompat.START);
|
||||
return true;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onWindowFocusChanged(boolean hasFocus) {
|
||||
super.onWindowFocusChanged(hasFocus);
|
||||
|
@ -533,33 +177,18 @@ public class MainActivity extends AppCompatActivity implements
|
|||
}
|
||||
}
|
||||
|
||||
public boolean isCallable(Intent intent) {
|
||||
private boolean isCallable(Intent intent) {
|
||||
List<ResolveInfo> list = getPackageManager().queryIntentActivities(
|
||||
intent, PackageManager.MATCH_DEFAULT_ONLY);
|
||||
return list.size() > 0;
|
||||
}
|
||||
|
||||
private void showToastMessage(String message, int duration) {
|
||||
ConstraintLayout layout = (ConstraintLayout) 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);
|
||||
textView.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_notification, 0, 0, 0);
|
||||
textView.setCompoundDrawablePadding(getResources()
|
||||
.getDimensionPixelOffset(R.dimen.snackbar_icon_padding));
|
||||
snackbar.show();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
|
||||
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
||||
if (permissions.length > 0 && (Manifest.permission.READ_EXTERNAL_STORAGE.equals(permissions[0]) || Manifest.permission.WRITE_EXTERNAL_STORAGE.equals(permissions[0]))
|
||||
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
|
||||
onGameSelected(Uri.parse("file://whatever"));
|
||||
startNativeRenderer();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,50 +1,77 @@
|
|||
package com.reicast.emulator;
|
||||
|
||||
import android.Manifest;
|
||||
import android.app.Activity;
|
||||
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.preference.PreferenceManager;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.constraint.ConstraintLayout;
|
||||
import android.support.design.widget.Snackbar;
|
||||
import android.support.v4.app.ActivityCompat;
|
||||
import android.util.Log;
|
||||
import android.view.Gravity;
|
||||
import android.view.InputDevice;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.SurfaceHolder;
|
||||
import android.view.View;
|
||||
import android.view.ViewConfiguration;
|
||||
import android.view.Window;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.reicast.emulator.config.Config;
|
||||
import com.reicast.emulator.debug.GenerateLogs;
|
||||
import com.reicast.emulator.emu.AudioBackend;
|
||||
import com.reicast.emulator.emu.JNIdc;
|
||||
import com.reicast.emulator.emu.NativeGLView;
|
||||
import com.reicast.emulator.periph.InputDeviceManager;
|
||||
import com.reicast.emulator.periph.SipEmulator;
|
||||
import com.reicast.emulator.periph.VJoy;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import tv.ouya.console.api.OuyaController;
|
||||
|
||||
public class NativeGLActivity extends BaseNativeGLActivity implements ActivityCompat.OnRequestPermissionsResultCallback {
|
||||
public final class NativeGLActivity extends BaseNativeGLActivity implements ActivityCompat.OnRequestPermissionsResultCallback {
|
||||
public static byte[] syms;
|
||||
private float[][] vjoy_d_cached; // Used for VJoy editing
|
||||
private AudioBackend audioBackend;
|
||||
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
requestWindowFeature(Window.FEATURE_NO_TITLE);
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
|
||||
InputDeviceManager.getInstance().startListening(getApplicationContext());
|
||||
|
||||
Emulator app = (Emulator)getApplicationContext();
|
||||
app.getConfigurationPrefs(prefs);
|
||||
app.getConfigurationPrefs();
|
||||
|
||||
OuyaController.init(this);
|
||||
JNIdc.initControllers(Emulator.maple_devices, Emulator.maple_expansion_devices);
|
||||
|
||||
app.loadConfigurationPrefs();
|
||||
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
|
||||
String home_directory = prefs.getString(Config.pref_home, "");
|
||||
String result = JNIdc.initEnvironment((Emulator)getApplicationContext(), home_directory);
|
||||
if (result != null)
|
||||
showToastMessage("Initialization failed: " + result, Snackbar.LENGTH_LONG);
|
||||
|
||||
String android_home_directory = Environment.getExternalStorageDirectory().getAbsolutePath();
|
||||
List<String> pathList = new ArrayList<>();
|
||||
pathList.add(android_home_directory);
|
||||
pathList.addAll(FileBrowser.getExternalMounts());
|
||||
Log.i("reicast", "External storage dirs: " + pathList);
|
||||
JNIdc.setExternalStorageDirectories(pathList.toArray());
|
||||
|
||||
register(this);
|
||||
|
||||
audioBackend = new AudioBackend();
|
||||
|
||||
// FIXME Maple microphone can be plugged at any time with in-game gui
|
||||
// so this perm may be required at any time as well
|
||||
//setup mic
|
||||
if (Emulator.micPluggedIn()) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
|
@ -124,6 +151,8 @@ public class NativeGLActivity extends BaseNativeGLActivity implements ActivityCo
|
|||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
InputDeviceManager.getInstance().stopListening();
|
||||
register(null);
|
||||
audioBackend.release();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -135,4 +164,46 @@ public class NativeGLActivity extends BaseNativeGLActivity implements ActivityCo
|
|||
JNIdc.setupMic(sip);
|
||||
}
|
||||
}
|
||||
|
||||
private void showToastMessage(String message, int duration) {
|
||||
View view = findViewById(android.R.id.content);
|
||||
Snackbar snackbar = Snackbar.make(view, message, duration);
|
||||
View snackbarLayout = snackbar.getView();
|
||||
TextView textView = (TextView) snackbarLayout.findViewById(
|
||||
android.support.design.R.id.snackbar_text);
|
||||
textView.setGravity(Gravity.CENTER_VERTICAL);
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1)
|
||||
textView.setTextAlignment(View.TEXT_ALIGNMENT_GRAVITY);
|
||||
textView.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_notification, 0, 0, 0);
|
||||
textView.setCompoundDrawablePadding(getResources()
|
||||
.getDimensionPixelOffset(R.dimen.snackbar_icon_padding));
|
||||
snackbar.show();
|
||||
}
|
||||
|
||||
// Called from native code
|
||||
private void VJoyStartEditing() {
|
||||
vjoy_d_cached = VJoy.readCustomVjoyValues(getApplicationContext());
|
||||
JNIdc.show_osd();
|
||||
mView.setEditVjoyMode(true);
|
||||
}
|
||||
// Called from native code
|
||||
private void VJoyResetEditing() {
|
||||
VJoy.resetCustomVjoyValues(getApplicationContext());
|
||||
mView.vjoy_d_custom = VJoy
|
||||
.readCustomVjoyValues(getApplicationContext());
|
||||
mView.resetEditMode();
|
||||
mView.requestLayout();
|
||||
}
|
||||
// Called from native code
|
||||
private void VJoyStopEditing(boolean canceled) {
|
||||
if (canceled)
|
||||
mView.restoreCustomVjoyValues(vjoy_d_cached);
|
||||
mView.setEditVjoyMode(false);
|
||||
}
|
||||
// Called from native code
|
||||
private void generateErrorLog() {
|
||||
new GenerateLogs(this).execute(getFilesDir().getAbsolutePath());
|
||||
}
|
||||
|
||||
private static native void register(NativeGLActivity activity);
|
||||
}
|
||||
|
|
|
@ -1,9 +1,5 @@
|
|||
package com.reicast.emulator.config;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
|
||||
public class Config {
|
||||
|
||||
public static final String pref_home = "home_directory";
|
||||
|
@ -15,42 +11,5 @@ public class Config {
|
|||
public static final String pref_rendertype = "render_type";
|
||||
public static final String pref_renderdepth = "depth_render";
|
||||
|
||||
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_vmu = "vmu_floating";
|
||||
|
||||
public static String git_api = "https://api.github.com/repos/reicast/reicast-emulator/commits?sha=fh/mymaster";
|
||||
public static String git_issues = "https://github.com/reicast/reicast-emulator/issues/";
|
||||
|
||||
public static boolean externalIntent = false;
|
||||
|
||||
/**
|
||||
* Read the output of a shell command
|
||||
*
|
||||
* @param command
|
||||
* The shell command being issued to the terminal
|
||||
*/
|
||||
public static String readOutput(String command) {
|
||||
try {
|
||||
Process p = Runtime.getRuntime().exec(command);
|
||||
InputStream is;
|
||||
if (p.waitFor() == 0) {
|
||||
is = p.getInputStream();
|
||||
} else {
|
||||
is = p.getErrorStream();
|
||||
}
|
||||
BufferedReader br = new BufferedReader(new InputStreamReader(is),2048);
|
||||
String line = br.readLine();
|
||||
br.close();
|
||||
return line;
|
||||
} catch (Exception ex) {
|
||||
return "ERROR: " + ex.getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,128 +0,0 @@
|
|||
package com.reicast.emulator.config;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.content.res.Configuration;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.Gravity;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.SurfaceHolder;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.view.ViewGroup.LayoutParams;
|
||||
import android.view.Window;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.ImageView.ScaleType;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.PopupWindow;
|
||||
|
||||
import com.reicast.emulator.BaseNativeGLActivity;
|
||||
import com.reicast.emulator.MainActivity;
|
||||
import com.reicast.emulator.R;
|
||||
import com.reicast.emulator.emu.JNIdc;
|
||||
import com.reicast.emulator.emu.NativeGLView;
|
||||
import com.reicast.emulator.emu.OnScreenMenu;
|
||||
import com.reicast.emulator.periph.VJoy;
|
||||
|
||||
public class EditVJoyActivity extends BaseNativeGLActivity {
|
||||
PopupWindow popUp;
|
||||
LayoutParams params;
|
||||
|
||||
private float[][] vjoy_d_cached;
|
||||
|
||||
View addbut(int x, OnClickListener ocl) {
|
||||
ImageButton but = new ImageButton(this);
|
||||
|
||||
but.setImageResource(x);
|
||||
but.setScaleType(ScaleType.FIT_CENTER);
|
||||
but.setOnClickListener(ocl);
|
||||
|
||||
return but;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle icicle) {
|
||||
requestWindowFeature(Window.FEATURE_NO_TITLE);
|
||||
|
||||
popUp = createVJoyPopup();
|
||||
|
||||
String fileName = null;
|
||||
|
||||
editVjoyMode = true;
|
||||
// Call parent onCreate()
|
||||
super.onCreate(icicle);
|
||||
|
||||
vjoy_d_cached = VJoy.readCustomVjoyValues(getApplicationContext());
|
||||
|
||||
JNIdc.show_osd();
|
||||
}
|
||||
|
||||
PopupWindow createVJoyPopup() {
|
||||
final PopupWindow popUp = new PopupWindow(this);
|
||||
int p = OnScreenMenu.getPixelsFromDp(60, this);
|
||||
params = new LayoutParams(p, p);
|
||||
|
||||
LinearLayout hlay = new LinearLayout(this);
|
||||
|
||||
hlay.setOrientation(LinearLayout.HORIZONTAL);
|
||||
|
||||
hlay.addView(addbut(R.drawable.apply, new OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
stopEmulator();
|
||||
Intent inte = new Intent(EditVJoyActivity.this, MainActivity.class);
|
||||
startActivity(inte);
|
||||
finish();
|
||||
}
|
||||
}), params);
|
||||
|
||||
hlay.addView(addbut(R.drawable.reset, new OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
// Reset VJoy positions and scale
|
||||
VJoy.resetCustomVjoyValues(getApplicationContext());
|
||||
mView.vjoy_d_custom = VJoy
|
||||
.readCustomVjoyValues(getApplicationContext());
|
||||
mView.resetEditMode();
|
||||
mView.requestLayout();
|
||||
popUp.dismiss();
|
||||
}
|
||||
}), params);
|
||||
|
||||
hlay.addView(addbut(R.drawable.close, new OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
mView.restoreCustomVjoyValues(vjoy_d_cached);
|
||||
popUp.dismiss();
|
||||
}
|
||||
}), params);
|
||||
|
||||
popUp.setContentView(hlay);
|
||||
return popUp;
|
||||
}
|
||||
|
||||
public boolean onKeyDown(int keyCode, KeyEvent event) {
|
||||
if (keyCode == KeyEvent.KEYCODE_MENU
|
||||
|| keyCode == KeyEvent.KEYCODE_BACK) {
|
||||
if (!popUp.isShowing()) {
|
||||
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);
|
||||
} else {
|
||||
popUp.dismiss();
|
||||
}
|
||||
|
||||
return true;
|
||||
} else
|
||||
return super.onKeyDown(keyCode, event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConfigurationChanged(Configuration newConfig) {
|
||||
super.onConfigurationChanged(newConfig);
|
||||
}
|
||||
}
|
|
@ -1,160 +0,0 @@
|
|||
package com.reicast.emulator.config;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.os.Environment;
|
||||
import android.os.Vibrator;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Button;
|
||||
import android.widget.CompoundButton;
|
||||
import android.widget.CompoundButton.OnCheckedChangeListener;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.SeekBar;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.reicast.emulator.Emulator;
|
||||
import com.reicast.emulator.R;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public class InputFragment extends Fragment {
|
||||
private OnClickListener mCallback;
|
||||
|
||||
private SharedPreferences mPrefs;
|
||||
private CompoundButton switchTouchVibrationEnabled;
|
||||
|
||||
Vibrator vib;
|
||||
|
||||
// Container Activity must implement this interface
|
||||
public interface OnClickListener {
|
||||
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
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
// Inflate the layout for this fragment
|
||||
return inflater.inflate(R.layout.input_fragment, container, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(View view, Bundle savedInstanceState) {
|
||||
mPrefs = PreferenceManager.getDefaultSharedPreferences(getActivity());
|
||||
|
||||
Config.vibrationDuration = mPrefs.getInt(Config.pref_vibrationDuration, 20);
|
||||
vib = (Vibrator) getActivity().getSystemService(Context.VIBRATOR_SERVICE);
|
||||
|
||||
final Button buttonLaunchEditor = (Button) getView().findViewById(R.id.buttonLaunchEditor);
|
||||
buttonLaunchEditor.setOnClickListener(new View.OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
buttonLaunchEditor.setEnabled(false);
|
||||
mCallback.onEditorSelected(Uri.EMPTY);
|
||||
}
|
||||
});
|
||||
|
||||
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 (mPrefs.getBoolean(Config.pref_touchvibe, true)) {
|
||||
vibLay.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
vibLay.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
duration.setText(String.valueOf(Config.vibrationDuration + " ms"));
|
||||
vibSeek.setProgress(Config.vibrationDuration);
|
||||
|
||||
vibSeek.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
|
||||
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
|
||||
duration.setText(String.valueOf(progress + 5 + " ms"));
|
||||
}
|
||||
|
||||
public void onStartTrackingTouch(SeekBar seekBar) {
|
||||
|
||||
}
|
||||
|
||||
public void onStopTrackingTouch(SeekBar seekBar) {
|
||||
int progress = seekBar.getProgress() + 5;
|
||||
mPrefs.edit().putInt(Config.pref_vibrationDuration, progress).apply();
|
||||
Config.vibrationDuration = progress;
|
||||
vib.vibrate(progress);
|
||||
}
|
||||
});
|
||||
|
||||
OnCheckedChangeListener touch_vibration = new OnCheckedChangeListener() {
|
||||
public void onCheckedChanged(CompoundButton buttonView,
|
||||
boolean isChecked) {
|
||||
mPrefs.edit().putBoolean(Config.pref_touchvibe, isChecked).apply();
|
||||
vibLay.setVisibility( isChecked ? View.VISIBLE : View.GONE );
|
||||
}
|
||||
};
|
||||
switchTouchVibrationEnabled = (CompoundButton) getView().findViewById(
|
||||
R.id.switchTouchVibrationEnabled);
|
||||
boolean vibrate = mPrefs.getBoolean(Config.pref_touchvibe, true);
|
||||
if (vibrate) {
|
||||
switchTouchVibrationEnabled.setChecked(true);
|
||||
} else {
|
||||
switchTouchVibrationEnabled.setChecked(false);
|
||||
}
|
||||
switchTouchVibrationEnabled.setOnCheckedChangeListener(touch_vibration);
|
||||
updateVibration();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
Button buttonLaunchEditor = (Button) getView().findViewById(R.id.buttonLaunchEditor);
|
||||
buttonLaunchEditor.setEnabled(isBIOSAvailable());
|
||||
}
|
||||
|
||||
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 = mPrefs.getBoolean(Config.pref_touchvibe, true);
|
||||
switchTouchVibrationEnabled.setChecked(touchVibrationEnabled);
|
||||
}
|
||||
|
||||
}
|
|
@ -124,7 +124,7 @@ public class OptionsFragment extends Fragment {
|
|||
|
||||
home_directory = mPrefs.getString(Config.pref_home, home_directory);
|
||||
Emulator app = (Emulator) getActivity().getApplicationContext();
|
||||
app.getConfigurationPrefs(mPrefs);
|
||||
app.getConfigurationPrefs();
|
||||
|
||||
// Generate the menu options and fill in existing settings
|
||||
|
||||
|
@ -422,53 +422,12 @@ public class OptionsFragment extends Fragment {
|
|||
}
|
||||
|
||||
private void resetEmuSettings() {
|
||||
mPrefs.edit().remove(Emulator.pref_usereios).apply();
|
||||
mPrefs.edit().remove(Config.pref_gamedetails).apply();
|
||||
mPrefs.edit().remove(Emulator.pref_dynarecopt).apply();
|
||||
mPrefs.edit().remove(Emulator.pref_unstable).apply();
|
||||
mPrefs.edit().remove(Emulator.pref_cable).apply();
|
||||
mPrefs.edit().remove(Emulator.pref_dcregion).apply();
|
||||
mPrefs.edit().remove(Emulator.pref_broadcast).apply();
|
||||
mPrefs.edit().remove(Emulator.pref_language).apply();
|
||||
mPrefs.edit().remove(Emulator.pref_limitfps).apply();
|
||||
mPrefs.edit().remove(Emulator.pref_mipmaps).apply();
|
||||
mPrefs.edit().remove(Emulator.pref_widescreen).apply();
|
||||
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_bootdisk).apply();
|
||||
mPrefs.edit().remove(Emulator.pref_showfps).apply();
|
||||
mPrefs.edit().remove(Config.pref_rendertype).apply();
|
||||
mPrefs.edit().remove(Emulator.pref_nosound).apply();
|
||||
mPrefs.edit().remove(Emulator.pref_nobatch).apply();
|
||||
mPrefs.edit().remove(Emulator.pref_customtextures).apply();
|
||||
mPrefs.edit().remove(Emulator.pref_modvols).apply();
|
||||
mPrefs.edit().remove(Emulator.pref_clipping).apply();
|
||||
mPrefs.edit().remove(Emulator.pref_dynsafemode).apply();
|
||||
mPrefs.edit().remove(Config.pref_renderdepth).apply();
|
||||
mPrefs.edit().remove(Config.pref_theme).apply();
|
||||
|
||||
|
||||
Emulator.usereios = false;
|
||||
Emulator.dynarecopt = true;
|
||||
Emulator.unstableopt = false;
|
||||
Emulator.cable = 3;
|
||||
Emulator.dcregion = 3;
|
||||
Emulator.broadcast = 4;
|
||||
Emulator.language = 6;
|
||||
Emulator.limitfps = true;
|
||||
Emulator.mipmaps = true;
|
||||
Emulator.widescreen = false;
|
||||
Emulator.frameskip = 0;
|
||||
Emulator.pvrrender = 0;
|
||||
Emulator.syncedrender = true;
|
||||
Emulator.bootdisk = null;
|
||||
Emulator.nosound = false;
|
||||
Emulator.nobatch = false;
|
||||
Emulator.customtextures = false;
|
||||
Emulator.modvols = true;
|
||||
Emulator.clipping = true;
|
||||
Emulator.dynsafemode = true;
|
||||
|
||||
getActivity().finish();
|
||||
}
|
||||
|
|
|
@ -1,399 +0,0 @@
|
|||
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 != null && 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;
|
||||
}
|
||||
});
|
||||
|
||||
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 != null && 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();
|
||||
}
|
||||
}
|
|
@ -93,7 +93,11 @@ public class GenerateLogs extends AsyncTask<String, Integer, String> {
|
|||
build_version = MM;
|
||||
} else if (build_sdk >= 24 && build_sdk < 26) {
|
||||
build_version = NT;
|
||||
} else if (build_sdk >= 26) {
|
||||
} else if (build_sdk >= 26 && build_sdk < 28) {
|
||||
build_version = "Oreo";
|
||||
} else if (build_sdk == 28) {
|
||||
build_version = "Pie";
|
||||
} else if (build_sdk > 28) {
|
||||
build_version = NL;
|
||||
}
|
||||
s += build_version + " (" + build_sdk + ")";
|
||||
|
@ -212,8 +216,8 @@ public class GenerateLogs extends AsyncTask<String, Integer, String> {
|
|||
}
|
||||
|
||||
private void showToastMessage(String message, int duration) {
|
||||
ConstraintLayout layout = (ConstraintLayout)
|
||||
((Activity) mContext.get()).findViewById(R.id.mainui_layout);
|
||||
View layout =
|
||||
((Activity) mContext.get()).findViewById(android.R.id.content);
|
||||
Snackbar snackbar = Snackbar.make(layout, message, duration);
|
||||
View snackbarLayout = snackbar.getView();
|
||||
ConstraintLayout.LayoutParams lp = new ConstraintLayout.LayoutParams(
|
||||
|
|
|
@ -0,0 +1,102 @@
|
|||
package com.reicast.emulator.emu;
|
||||
|
||||
import android.media.AudioFormat;
|
||||
import android.media.AudioManager;
|
||||
import android.media.AudioTrack;
|
||||
import android.os.Build;
|
||||
import android.util.Log;
|
||||
|
||||
import com.reicast.emulator.Emulator;
|
||||
|
||||
import static android.media.AudioTrack.STATE_INITIALIZED;
|
||||
|
||||
public final class AudioBackend {
|
||||
static { System.loadLibrary("dc"); }
|
||||
|
||||
private AudioTrack audioTrack;
|
||||
private long writePosition;
|
||||
private long size; //size in frames
|
||||
private static AudioBackend instance;
|
||||
|
||||
public AudioBackend() {
|
||||
setInstance(this);
|
||||
instance = this;
|
||||
enableSound(!Emulator.nosound);
|
||||
}
|
||||
|
||||
public static AudioBackend getInstance() {
|
||||
return instance;
|
||||
}
|
||||
public void release() {
|
||||
setInstance(null);
|
||||
instance = null;
|
||||
}
|
||||
|
||||
public void enableSound(boolean enable) {
|
||||
if (enable && audioTrack == null) {
|
||||
int min = AudioTrack.getMinBufferSize(44100, AudioFormat.CHANNEL_OUT_STEREO, AudioFormat.ENCODING_PCM_16BIT);
|
||||
|
||||
if (2048 > min)
|
||||
min = 2048;
|
||||
|
||||
audioTrack = new AudioTrack(
|
||||
AudioManager.STREAM_MUSIC,
|
||||
44100,
|
||||
AudioFormat.CHANNEL_OUT_STEREO,
|
||||
AudioFormat.ENCODING_PCM_16BIT,
|
||||
min,
|
||||
AudioTrack.MODE_STREAM
|
||||
);
|
||||
if (audioTrack.getState() != STATE_INITIALIZED) {
|
||||
audioTrack = null;
|
||||
release();
|
||||
Log.e("reicast", "Error initializing AudioTrack. Disabling sound");
|
||||
}
|
||||
else {
|
||||
size = min / 4;
|
||||
writePosition = 0;
|
||||
|
||||
Log.i("audcfg", "Audio streaming: buffer size " + min + " samples / " + min / 44100.0 + " ms");
|
||||
audioTrack.play();
|
||||
}
|
||||
}
|
||||
else if (!enable && audioTrack != null) {
|
||||
audioTrack.pause();
|
||||
audioTrack.flush();
|
||||
audioTrack.release();
|
||||
audioTrack = null;
|
||||
}
|
||||
}
|
||||
|
||||
// Called by native code
|
||||
private int writeBuffer(short[] samples, boolean wait)
|
||||
{
|
||||
if (audioTrack != null) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
audioTrack.write(samples, 0, samples.length, wait ? AudioTrack.WRITE_BLOCKING : AudioTrack.WRITE_NON_BLOCKING);
|
||||
} else {
|
||||
if (wait)
|
||||
{
|
||||
int newdata = samples.length / 2;
|
||||
|
||||
//user bytes = write-read
|
||||
//available = size - (write - play)
|
||||
long used = writePosition - audioTrack.getPlaybackHeadPosition();
|
||||
long avail = size - used;
|
||||
|
||||
//Log.i("audcfg", "u: " + used + " a: " + avail);
|
||||
if (avail < newdata)
|
||||
return 0;
|
||||
|
||||
writePosition += newdata;
|
||||
}
|
||||
|
||||
audioTrack.write(samples, 0, samples.length);
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
private static native void setInstance(AudioBackend backend);
|
||||
}
|
|
@ -1,101 +0,0 @@
|
|||
package com.reicast.emulator.emu;
|
||||
|
||||
import android.media.AudioFormat;
|
||||
import android.media.AudioManager;
|
||||
import android.media.AudioTrack;
|
||||
import android.util.Log;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
|
||||
class EmuThread extends Thread
|
||||
{
|
||||
private IEmulatorView view;
|
||||
AudioTrack Player;
|
||||
long pos; //write position
|
||||
long size; //size in frames
|
||||
private boolean sound;
|
||||
|
||||
EmuThread(IEmulatorView view) {
|
||||
this.view = view;
|
||||
this.sound = view.hasSound();
|
||||
}
|
||||
|
||||
@Override public void run()
|
||||
{
|
||||
if (sound) {
|
||||
int min=AudioTrack.getMinBufferSize(44100,AudioFormat.CHANNEL_OUT_STEREO,AudioFormat.ENCODING_PCM_16BIT);
|
||||
|
||||
if (2048>min)
|
||||
min=2048;
|
||||
|
||||
Player = new AudioTrack(
|
||||
AudioManager.STREAM_MUSIC,
|
||||
44100,
|
||||
AudioFormat.CHANNEL_OUT_STEREO,
|
||||
AudioFormat.ENCODING_PCM_16BIT,
|
||||
min,
|
||||
AudioTrack.MODE_STREAM
|
||||
);
|
||||
|
||||
size=min/4;
|
||||
pos=0;
|
||||
|
||||
Log.i("audcfg", "Audio streaming: buffer size " + min + " samples / " + min/44100.0 + " ms");
|
||||
Player.play();
|
||||
}
|
||||
|
||||
JNIdc.run(this);
|
||||
}
|
||||
|
||||
// Called by native code
|
||||
int WriteBuffer(short[] samples, int wait)
|
||||
{
|
||||
if (sound) {
|
||||
int newdata=samples.length/2;
|
||||
|
||||
if (wait==0)
|
||||
{
|
||||
//user bytes = write-read
|
||||
//available = size - (write - play)
|
||||
long used=pos-Player.getPlaybackHeadPosition();
|
||||
long avail=size-used;
|
||||
|
||||
//Log.i("audcfg", "u: " + used + " a: " + avail);
|
||||
if (avail<newdata)
|
||||
return 0;
|
||||
}
|
||||
|
||||
pos+=newdata;
|
||||
|
||||
Player.write(samples, 0, samples.length);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
private void showMessage(final String msg) {
|
||||
view.postMessage(msg);
|
||||
}
|
||||
|
||||
// Called by native code
|
||||
int coreMessage(byte[] msg) {
|
||||
try {
|
||||
showMessage(new String(msg, "UTF-8"));
|
||||
}
|
||||
catch (UnsupportedEncodingException e) {
|
||||
showMessage("coreMessage: Failed to display error");
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Called by native code
|
||||
void Die() {
|
||||
showMessage("Something went wrong and reicast crashed.\nPlease report this on the reicast forums.");
|
||||
view.finish();
|
||||
}
|
||||
|
||||
// Called by native code
|
||||
void reiosInfo(String reiosId, String reiosSoftware) {
|
||||
view.reiosInfo(reiosId, reiosSoftware);
|
||||
}
|
||||
}
|
|
@ -28,7 +28,6 @@ import com.reicast.emulator.Emulator;
|
|||
import com.reicast.emulator.GL2JNIActivity;
|
||||
import com.reicast.emulator.R;
|
||||
import com.reicast.emulator.config.Config;
|
||||
import com.reicast.emulator.emu.OnScreenMenu.FpsPopup;
|
||||
import com.reicast.emulator.periph.Gamepad;
|
||||
import com.reicast.emulator.periph.InputDeviceManager;
|
||||
import com.reicast.emulator.periph.VJoy;
|
||||
|
@ -56,15 +55,13 @@ import javax.microedition.khronos.opengles.GL10;
|
|||
* bit depths). Failure to do so would result in an EGL_BAD_MATCH error.
|
||||
*/
|
||||
|
||||
public class GL2JNIView extends GLSurfaceView implements IEmulatorView
|
||||
public class GL2JNIView extends GLSurfaceView
|
||||
{
|
||||
public static final boolean DEBUG = false;
|
||||
|
||||
public static final int LAYER_TYPE_SOFTWARE = 1;
|
||||
public static final int LAYER_TYPE_HARDWARE = 2;
|
||||
|
||||
private static String fileName;
|
||||
private EmuThread ethd;
|
||||
private Handler handler = new Handler();
|
||||
|
||||
Vibrator vib;
|
||||
|
@ -79,8 +76,6 @@ public class GL2JNIView extends GLSurfaceView implements IEmulatorView
|
|||
|
||||
Renderer rend;
|
||||
|
||||
private boolean touchVibrationEnabled;
|
||||
private int vibrationDuration;
|
||||
Context context;
|
||||
|
||||
public void restoreCustomVjoyValues(float[][] vjoy_d_cached) {
|
||||
|
@ -91,10 +86,6 @@ public class GL2JNIView extends GLSurfaceView implements IEmulatorView
|
|||
requestLayout();
|
||||
}
|
||||
|
||||
public void setFpsDisplay(FpsPopup fpsPop) {
|
||||
rend.fpsPop = fpsPop;
|
||||
}
|
||||
|
||||
public GL2JNIView(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
@ -104,7 +95,7 @@ public class GL2JNIView extends GLSurfaceView implements IEmulatorView
|
|||
}
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
|
||||
public GL2JNIView(final Context context, String newFileName, boolean translucent,
|
||||
public GL2JNIView(final Context context, boolean translucent,
|
||||
int depth, int stencil, boolean editVjoyMode) {
|
||||
super(context);
|
||||
this.context = context;
|
||||
|
@ -134,41 +125,15 @@ public class GL2JNIView extends GLSurfaceView implements IEmulatorView
|
|||
DisplayMetrics dm = context.getResources().getDisplayMetrics();
|
||||
JNIdc.screenDpi((int)Math.max(dm.xdpi, dm.ydpi));
|
||||
|
||||
//JNIdc.config(prefs.getString(Config.pref_home,
|
||||
// Environment.getExternalStorageDirectory().getAbsolutePath()));
|
||||
|
||||
ethd = new EmuThread(this);
|
||||
|
||||
touchVibrationEnabled = prefs.getBoolean(Config.pref_touchvibe, true);
|
||||
vibrationDuration = prefs.getInt(Config.pref_vibrationDuration, 20);
|
||||
|
||||
this.setLayerType(prefs.getInt(Config.pref_rendertype, LAYER_TYPE_HARDWARE), null);
|
||||
|
||||
vjoy_d_custom = VJoy.readCustomVjoyValues(context);
|
||||
|
||||
scaleGestureDetector = new ScaleGestureDetector(context, new OscOnScaleGestureListener());
|
||||
|
||||
// This is the game we are going to run
|
||||
fileName = newFileName;
|
||||
|
||||
if (GL2JNIActivity.syms != null)
|
||||
JNIdc.data(1, GL2JNIActivity.syms);
|
||||
|
||||
final String initStatus = JNIdc.init(fileName);
|
||||
if (initStatus != null)
|
||||
{
|
||||
handler.post(new Runnable() {
|
||||
public void run() {
|
||||
Log.e("initialization", "dc_init: " + initStatus);
|
||||
Toast.makeText(context, initStatus, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
throw new EmulatorInitFailed();
|
||||
}
|
||||
JNIdc.query(ethd);
|
||||
|
||||
// By default, GLSurfaceView() creates a RGB_565 opaque surface.
|
||||
// If we want a translucent one, we should change the surface's
|
||||
// format here, using PixelFormat.TRANSLUCENT for GL Surfaces
|
||||
|
@ -191,9 +156,6 @@ public class GL2JNIView extends GLSurfaceView implements IEmulatorView
|
|||
|
||||
// Set the renderer responsible for frame rendering
|
||||
setRenderer(rend = new Renderer(this));
|
||||
|
||||
ethd.start();
|
||||
|
||||
}
|
||||
|
||||
public GLSurfaceView.Renderer getRenderer()
|
||||
|
@ -364,8 +326,8 @@ public class GL2JNIView extends GLSurfaceView implements IEmulatorView
|
|||
if (y > vjoy[j][1] && y <= (vjoy[j][1] + vjoy[j][3])) {
|
||||
if (vjoy[j][4] >= -2) {
|
||||
if (vjoy[j][5] == 0)
|
||||
if (!editVjoyMode && touchVibrationEnabled)
|
||||
vib.vibrate(vibrationDuration);
|
||||
if (!editVjoyMode && Emulator.vibrationDuration > 0)
|
||||
vib.vibrate(Emulator.vibrationDuration);
|
||||
vjoy[j][5] = 2;
|
||||
}
|
||||
|
||||
|
@ -507,46 +469,11 @@ public class GL2JNIView extends GLSurfaceView implements IEmulatorView
|
|||
int joyy = get_anal(11, 1);
|
||||
InputDeviceManager.getInstance().virtualGamepadEvent(rv, joyx, joyy, left_trigger, right_trigger);
|
||||
// Only register the mouse event if no virtual gamepad button is down
|
||||
if (!editVjoyMode && rv == 0xFFFF)
|
||||
if ((!editVjoyMode && rv == 0xFFFF) || JNIdc.guiIsOpen())
|
||||
InputDeviceManager.getInstance().mouseEvent(mouse_pos[0], mouse_pos[1], mouse_btns);
|
||||
return(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasSound() {
|
||||
return !Emulator.nosound;
|
||||
}
|
||||
|
||||
@Override
|
||||
public 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]);
|
||||
mPrefs.edit().putString(Config.game_title, reiosSoftware.trim()).apply();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postMessage(final String msg) {
|
||||
handler.post(new Runnable() {
|
||||
public void run() {
|
||||
Log.d(context.getPackageName(), msg);
|
||||
Toast.makeText(context, msg, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finish() {
|
||||
((Activity) context).finish();
|
||||
}
|
||||
|
||||
private class OscOnScaleGestureListener extends
|
||||
SimpleOnScaleGestureListener {
|
||||
|
||||
|
@ -572,8 +499,6 @@ public class GL2JNIView extends GLSurfaceView implements IEmulatorView
|
|||
{
|
||||
|
||||
private GL2JNIView mView;
|
||||
private FPSCounter fps = new FPSCounter();
|
||||
private FpsPopup fpsPop;
|
||||
|
||||
Renderer (GL2JNIView mView) {
|
||||
this.mView = mView;
|
||||
|
@ -582,73 +507,32 @@ public class GL2JNIView extends GLSurfaceView implements IEmulatorView
|
|||
public void onDrawFrame(GL10 gl)
|
||||
{
|
||||
if (JNIdc.rendframeJava()) {
|
||||
if (fpsPop != null && fpsPop.isShowing()) {
|
||||
fps.logFrame();
|
||||
}
|
||||
}
|
||||
if(mView.takeScreenshot){
|
||||
mView.takeScreenshot = false;
|
||||
FileUtils.saveScreenshot(mView.getContext(), mView.getWidth(), mView.getHeight(), gl);
|
||||
}
|
||||
if (mView.ethd.getState() == Thread.State.TERMINATED) {
|
||||
JNIdc.rendtermJava();
|
||||
System.exit(0);
|
||||
// Ideally: ((Activity)mView.getContext()).finish();
|
||||
}
|
||||
}
|
||||
|
||||
public void onSurfaceChanged(GL10 gl,int width,int height)
|
||||
{
|
||||
gl.glViewport(0, 0, width, height);
|
||||
if (Emulator.widescreen) {
|
||||
// TODO Is this required? The renderer sets the viewport and scissor test correctly
|
||||
// if (Emulator.widescreen) {
|
||||
JNIdc.rendinitJava(width, height);
|
||||
} else {
|
||||
JNIdc.rendinitJava(height * (4 / 3), height);
|
||||
}
|
||||
// } else {
|
||||
// JNIdc.rendinitJava(height * (4 / 3), height);
|
||||
// }
|
||||
}
|
||||
|
||||
public void onSurfaceCreated(GL10 gl,EGLConfig config)
|
||||
{
|
||||
onSurfaceChanged(gl, 800, 480);
|
||||
}
|
||||
|
||||
class FPSCounter {
|
||||
long startTime = System.nanoTime();
|
||||
int frames = 0;
|
||||
|
||||
void logFrame() {
|
||||
frames++;
|
||||
if (System.nanoTime() - startTime >= 1000000000) {
|
||||
final int current_frames = frames;
|
||||
frames = 0;
|
||||
startTime = System.nanoTime();
|
||||
mView.post(new Runnable() {
|
||||
public void run() {
|
||||
fpsPop.setText(current_frames);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void audioDisable(boolean disabled) {
|
||||
if (disabled) {
|
||||
ethd.Player.pause();
|
||||
} else {
|
||||
ethd.Player.play();
|
||||
}
|
||||
}
|
||||
|
||||
public void fastForward(boolean enabled) {
|
||||
if (enabled) {
|
||||
ethd.setPriority(Thread.MIN_PRIORITY);
|
||||
} else {
|
||||
ethd.setPriority(Thread.NORM_PRIORITY);
|
||||
}
|
||||
}
|
||||
|
||||
public void onDestroy() {
|
||||
/*
|
||||
// Workaround for ANR when returning to menu
|
||||
System.exit(0);
|
||||
try {
|
||||
|
@ -656,6 +540,7 @@ public class GL2JNIView extends GLSurfaceView implements IEmulatorView
|
|||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
@TargetApi(19)
|
||||
|
@ -678,7 +563,4 @@ public class GL2JNIView extends GLSurfaceView implements IEmulatorView
|
|||
public void screenGrab() {
|
||||
takeScreenshot = true;
|
||||
}
|
||||
|
||||
public static class EmulatorInitFailed extends RuntimeException {
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
package com.reicast.emulator.emu;
|
||||
|
||||
public interface IEmulatorView {
|
||||
boolean hasSound();
|
||||
void reiosInfo(String reiosId, String reiosSoftware);
|
||||
void postMessage(String msg);
|
||||
void finish();
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
package com.reicast.emulator.emu;
|
||||
|
||||
import android.util.Log;
|
||||
import android.view.Surface;
|
||||
|
||||
import com.reicast.emulator.Emulator;
|
||||
|
@ -10,10 +11,8 @@ public final class JNIdc
|
|||
static { System.loadLibrary("dc"); }
|
||||
|
||||
public static native String initEnvironment(Emulator emulator, String homeDirectory);
|
||||
public static native void config(String dirName);
|
||||
public static native String init(String fileName);
|
||||
public static native void query(EmuThread thread);
|
||||
public static native void run(EmuThread thread);
|
||||
public static native void setExternalStorageDirectories(Object[] pathList);
|
||||
public static native void setGameUri(String fileName);
|
||||
public static native void pause();
|
||||
public static native void resume();
|
||||
public static native void stop();
|
||||
|
@ -31,65 +30,11 @@ public final class JNIdc
|
|||
public static native void vjoy(int id,float x, float y, float w, float h);
|
||||
|
||||
public static native void getControllers(int[] controllers, int[][] peripherals);
|
||||
public static native void initControllers(int[] controllers, int[][] peripherals);
|
||||
|
||||
public static native void setupMic(SipEmulator sip);
|
||||
public static native void diskSwap(String disk);
|
||||
public static native void vmuSwap();
|
||||
public static native void setupVmu(Object sip);
|
||||
public static native boolean getDynarec();
|
||||
public static native void setDynarec(boolean dynarec);
|
||||
public static native boolean getIdleskip();
|
||||
public static native void setIdleskip(boolean idleskip);
|
||||
public static native boolean getUnstable();
|
||||
public static native void setUnstable(boolean unstable);
|
||||
public static native boolean getSafemode();
|
||||
public static native void setSafemode(boolean safemode);
|
||||
public static native int getCable();
|
||||
public static native void setCable(int cable);
|
||||
public static native int getRegion();
|
||||
public static native void setRegion(int region);
|
||||
public static native int getBroadcast();
|
||||
public static native void setBroadcast(int broadcast);
|
||||
public static native int getLanguage();
|
||||
public static native void setLanguage(int language);
|
||||
public static native boolean getLimitfps();
|
||||
public static native void setLimitfps(boolean limiter);
|
||||
public static native boolean getNobatch();
|
||||
public static native void setNobatch(boolean nobatch);
|
||||
public static native boolean getNosound();
|
||||
public static native void setNosound(boolean noaudio);
|
||||
public static native boolean getMipmaps();
|
||||
public static native void setMipmaps(boolean mipmaps);
|
||||
public static native boolean getWidescreen();
|
||||
public static native void setWidescreen(boolean stretch);
|
||||
public static native int getFrameskip();
|
||||
public static native void setFrameskip(int frames);
|
||||
public static native int getPvrrender();
|
||||
public static native void setPvrrender(int render);
|
||||
public static native boolean getSyncedrender();
|
||||
public static native void setSyncedrender(boolean sync);
|
||||
public static native boolean getModvols();
|
||||
public static native void setModvols(boolean volumes);
|
||||
public static native boolean getClipping();
|
||||
public static native void setClipping(boolean clipping);
|
||||
public static native void bootdisk(String disk);
|
||||
public static native boolean getUsereios();
|
||||
public static native void setUsereios(boolean reios);
|
||||
public static native boolean getCustomtextures();
|
||||
public static native void setCustomtextures(boolean customtex);
|
||||
public static native boolean getShowfps();
|
||||
public static native void setShowfps(boolean showfps);
|
||||
public static native boolean getRenderToTextureBuffer();
|
||||
public static native void setRenderToTextureBuffer(boolean render);
|
||||
public static native int getRenderToTextureUpscale();
|
||||
public static native void setRenderToTextureUpscale(int upscale);
|
||||
public static native int getTextureUpscale();
|
||||
public static native void setTextureUpscale(int upscale);
|
||||
public static native int getMaxFilteredTextureSize();
|
||||
public static native void setMaxFilteredTextureSize(int maxSize);
|
||||
public static native int getMaxThreads();
|
||||
public static native void setMaxThreads(int maxThreads);
|
||||
public static native int getVirtualGamepadVibration();
|
||||
|
||||
public static native void screenDpi(int screenDpi);
|
||||
public static native void guiOpenSettings();
|
||||
|
@ -98,8 +43,4 @@ public final class JNIdc
|
|||
public static void show_osd() {
|
||||
JNIdc.vjoy(13, 1,0,0,0);
|
||||
}
|
||||
|
||||
public static void hide_osd() {
|
||||
JNIdc.vjoy(13, 0,0,0,0);
|
||||
} // FIXME use HideOSD()
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@ import android.util.Log;
|
|||
import android.view.InputDevice;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.ScaleGestureDetector;
|
||||
import android.view.SurfaceHolder;
|
||||
import android.view.SurfaceView;
|
||||
import android.view.View;
|
||||
import android.widget.Toast;
|
||||
|
@ -27,9 +28,7 @@ import com.reicast.emulator.config.Config;
|
|||
import com.reicast.emulator.periph.InputDeviceManager;
|
||||
import com.reicast.emulator.periph.VJoy;
|
||||
|
||||
public class NativeGLView extends SurfaceView implements IEmulatorView {
|
||||
private static String fileName;
|
||||
private EmuThread ethd;
|
||||
public class NativeGLView extends SurfaceView implements SurfaceHolder.Callback {
|
||||
private Handler handler = new Handler();
|
||||
|
||||
private Vibrator vib;
|
||||
|
@ -42,9 +41,8 @@ public class NativeGLView extends SurfaceView implements IEmulatorView {
|
|||
|
||||
private static final float[][] vjoy = VJoy.baseVJoy();
|
||||
|
||||
private boolean touchVibrationEnabled;
|
||||
private int vibrationDuration;
|
||||
private Context context;
|
||||
private boolean paused = false;
|
||||
|
||||
public void restoreCustomVjoyValues(float[][] vjoy_d_cached) {
|
||||
vjoy_d_custom = vjoy_d_cached;
|
||||
|
@ -54,19 +52,15 @@ public class NativeGLView extends SurfaceView implements IEmulatorView {
|
|||
requestLayout();
|
||||
}
|
||||
|
||||
public NativeGLView(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public NativeGLView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
|
||||
public NativeGLView(final Context context, String newFileName, boolean editVjoyMode) {
|
||||
super(context);
|
||||
public NativeGLView(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public NativeGLView(final Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
getHolder().addCallback(this);
|
||||
this.context = context;
|
||||
this.editVjoyMode = editVjoyMode;
|
||||
setKeepScreenOn(true);
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
||||
|
@ -90,56 +84,31 @@ public class NativeGLView extends SurfaceView implements IEmulatorView {
|
|||
DisplayMetrics dm = context.getResources().getDisplayMetrics();
|
||||
JNIdc.screenDpi((int)Math.max(dm.xdpi, dm.ydpi));
|
||||
|
||||
//JNIdc.config(prefs.getString(Config.pref_home,
|
||||
// Environment.getExternalStorageDirectory().getAbsolutePath()));
|
||||
|
||||
ethd = new EmuThread(this);
|
||||
|
||||
touchVibrationEnabled = prefs.getBoolean(Config.pref_touchvibe, true);
|
||||
vibrationDuration = prefs.getInt(Config.pref_vibrationDuration, 20);
|
||||
|
||||
this.setLayerType(prefs.getInt(Config.pref_rendertype, LAYER_TYPE_HARDWARE), null);
|
||||
|
||||
vjoy_d_custom = VJoy.readCustomVjoyValues(context);
|
||||
|
||||
scaleGestureDetector = new ScaleGestureDetector(context, new OscOnScaleGestureListener());
|
||||
|
||||
// This is the game we are going to run
|
||||
fileName = newFileName;
|
||||
|
||||
if (NativeGLActivity.syms != null)
|
||||
JNIdc.data(1, NativeGLActivity.syms);
|
||||
/*
|
||||
final String initStatus = JNIdc.init(fileName);
|
||||
if (initStatus != null)
|
||||
{
|
||||
handler.post(new Runnable() {
|
||||
public void run() {
|
||||
Log.e("initialization", "dc_init: " + initStatus);
|
||||
Toast.makeText(context, initStatus, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
});
|
||||
|
||||
throw new EmulatorInitFailed();
|
||||
}
|
||||
JNIdc.query(ethd);
|
||||
*/
|
||||
// Continuously render frames until the emulator stops
|
||||
startRendering();
|
||||
}
|
||||
|
||||
private void startRendering() {
|
||||
// Continuously render frames
|
||||
handler.removeCallbacksAndMessages(null);
|
||||
handler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
//if (ethd.getState() == Thread.State.TERMINATED)
|
||||
// ((Activity)getContext()).finish();
|
||||
//else
|
||||
if (!paused)
|
||||
{
|
||||
JNIdc.rendframeNative();
|
||||
handler.post(this);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
ethd.run(); // FIXME Not a thread anymore
|
||||
|
||||
}
|
||||
|
||||
private void reset_analog()
|
||||
|
@ -185,6 +154,10 @@ public class NativeGLView extends SurfaceView implements IEmulatorView {
|
|||
float a_x = -tx+ 24*scl;
|
||||
float a_y=- 24*scl;
|
||||
|
||||
// Not sure how this can happen
|
||||
if (vjoy_d_custom == null)
|
||||
return;
|
||||
|
||||
float[][] vjoy_d = VJoy.getVjoy_d(vjoy_d_custom);
|
||||
|
||||
for (int i=0;i<vjoy.length;i++)
|
||||
|
@ -305,8 +278,8 @@ public class NativeGLView extends SurfaceView implements IEmulatorView {
|
|||
if (y > vjoy[j][1] && y <= (vjoy[j][1] + vjoy[j][3])) {
|
||||
if (vjoy[j][4] >= -2) {
|
||||
if (vjoy[j][5] == 0)
|
||||
if (!editVjoyMode && touchVibrationEnabled)
|
||||
vib.vibrate(vibrationDuration);
|
||||
if (!editVjoyMode && Emulator.vibrationDuration > 0)
|
||||
vib.vibrate(Emulator.vibrationDuration);
|
||||
vjoy[j][5] = 2;
|
||||
}
|
||||
|
||||
|
@ -448,40 +421,37 @@ public class NativeGLView extends SurfaceView implements IEmulatorView {
|
|||
int joyy = get_anal(11, 1);
|
||||
InputDeviceManager.getInstance().virtualGamepadEvent(rv, joyx, joyy, left_trigger, right_trigger);
|
||||
// Only register the mouse event if no virtual gamepad button is down
|
||||
if (!editVjoyMode && rv == 0xFFFF)
|
||||
if ((!editVjoyMode && rv == 0xFFFF) || JNIdc.guiIsOpen())
|
||||
InputDeviceManager.getInstance().mouseEvent(mouse_pos[0], mouse_pos[1], mouse_btns);
|
||||
return(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasSound() {
|
||||
return !Emulator.nosound;
|
||||
public void surfaceCreated(SurfaceHolder surfaceHolder) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public 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);
|
||||
mPrefs.edit().putString(Config.game_title, reiosSoftware.trim()).apply();
|
||||
}
|
||||
public void surfaceChanged(SurfaceHolder surfaceHolder, int format, int w, int h) {
|
||||
//Log.i("reicast", "NativeGLView.surfaceChanged: " + w + "x" + h);
|
||||
JNIdc.rendinitNative(surfaceHolder.getSurface(), w, h);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postMessage(final String msg) {
|
||||
handler.post(new Runnable() {
|
||||
public void run() {
|
||||
Log.d(context.getPackageName(), msg);
|
||||
Toast.makeText(context, msg, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
});
|
||||
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
|
||||
//Log.i("reicast", "NativeGLView.surfaceDestroyed");
|
||||
JNIdc.rendinitNative(null, 0, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finish() {
|
||||
((Activity) context).finish();
|
||||
public void pause() {
|
||||
paused = true;
|
||||
JNIdc.pause();
|
||||
}
|
||||
|
||||
public void resume() {
|
||||
paused = false;
|
||||
JNIdc.resume();
|
||||
startRendering();
|
||||
}
|
||||
|
||||
private class OscOnScaleGestureListener extends
|
||||
|
@ -505,20 +475,6 @@ public class NativeGLView extends SurfaceView implements IEmulatorView {
|
|||
}
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
Log.i("NativeGLView", "Stopping emulator");
|
||||
//JNIdc.destroy();
|
||||
JNIdc.stop();
|
||||
/*
|
||||
try {
|
||||
ethd.join();
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
*/
|
||||
Log.i("NativeGLView", "Stopping emulator completed");
|
||||
}
|
||||
|
||||
@TargetApi(19)
|
||||
@Override
|
||||
public void onWindowFocusChanged(boolean hasFocus) {
|
||||
|
@ -535,6 +491,8 @@ public class NativeGLView extends SurfaceView implements IEmulatorView {
|
|||
}
|
||||
}
|
||||
|
||||
public static class EmulatorInitFailed extends RuntimeException {
|
||||
public void setEditVjoyMode(boolean editVjoyMode) {
|
||||
this.editVjoyMode = editVjoyMode;
|
||||
selectedVjoyElement = -1;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,49 +1,9 @@
|
|||
package com.reicast.emulator.emu;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.view.Gravity;
|
||||
import android.widget.PopupWindow;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.reicast.emulator.GL2JNIActivity;
|
||||
import com.reicast.emulator.R;
|
||||
|
||||
import java.util.Vector;
|
||||
|
||||
public class OnScreenMenu {
|
||||
|
||||
private Activity mContext;
|
||||
|
||||
public OnScreenMenu(Activity context, SharedPreferences prefs) {
|
||||
if (context instanceof GL2JNIActivity) {
|
||||
this.mContext = context;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public class FpsPopup extends PopupWindow {
|
||||
|
||||
private TextView fpsText;
|
||||
|
||||
public FpsPopup(Context c) {
|
||||
super(c);
|
||||
setBackgroundDrawable(null);
|
||||
fpsText = new TextView(mContext);
|
||||
fpsText.setTextAppearance(mContext, R.style.fpsOverlayText);
|
||||
fpsText.setGravity(Gravity.CENTER);
|
||||
fpsText.setText("XX");
|
||||
setContentView(fpsText);
|
||||
setFocusable(false);
|
||||
}
|
||||
|
||||
public void setText(int frames) {
|
||||
fpsText.setText(String.valueOf(frames));
|
||||
fpsText.invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
public static int getPixelsFromDp(float dps, Context context) {
|
||||
return (int) (dps * context.getResources().getDisplayMetrics().density + 0.5f);
|
||||
}
|
||||
|
|
|
@ -63,7 +63,7 @@ public final class InputDeviceManager implements InputManager.InputDeviceListene
|
|||
}
|
||||
|
||||
// Called from native code
|
||||
private boolean Rumble(int i, float power, float inclination, int duration_ms) {
|
||||
private boolean rumble(int i, float power, float inclination, int duration_ms) {
|
||||
Vibrator vibrator;
|
||||
if (i == VIRTUAL_GAMEPAD_ID) {
|
||||
vibrator = (Vibrator)Emulator.getAppContext().getSystemService(Context.VIBRATOR_SERVICE);
|
||||
|
|
|
@ -7,11 +7,10 @@
|
|||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <EGL/egl.h>
|
||||
#include <GLES2/gl2.h>
|
||||
#include <types.h>
|
||||
#include "types.h"
|
||||
#include <android/native_window.h>
|
||||
#include <android/native_window_jni.h>
|
||||
#include <types.h>
|
||||
|
||||
#include "hw/maple/maple_cfg.h"
|
||||
#include "hw/pvr/Renderer_if.h"
|
||||
|
@ -21,9 +20,9 @@
|
|||
#include "hw/maple/maple_if.h"
|
||||
#include "hw/naomi/naomi_cart.h"
|
||||
#include "oslib/audiobackend_android.h"
|
||||
#include "reios/reios.h"
|
||||
#include "imgread/common.h"
|
||||
#include "rend/gui.h"
|
||||
#include "cfg/cfg.h"
|
||||
|
||||
JavaVM* g_jvm;
|
||||
|
||||
|
@ -31,65 +30,58 @@ JavaVM* g_jvm;
|
|||
// Also attach the threads, and detach it on destruction, if needed.
|
||||
class JVMAttacher {
|
||||
public:
|
||||
JVMAttacher() : env(NULL), detach_thread(false) {
|
||||
if (g_jvm == NULL) {
|
||||
log_error("g_jvm == NULL");
|
||||
return;
|
||||
}
|
||||
int rc = g_jvm->GetEnv((void **)&env, JNI_VERSION_1_6);
|
||||
if (rc == JNI_EDETACHED) {
|
||||
if (g_jvm->AttachCurrentThread(&env, NULL) != 0) {
|
||||
log_error("AttachCurrentThread failed");
|
||||
return;
|
||||
JVMAttacher() : _env(NULL), _detach_thread(false) {
|
||||
}
|
||||
JNIEnv *getEnv()
|
||||
{
|
||||
if (_env == NULL)
|
||||
{
|
||||
if (g_jvm == NULL) {
|
||||
die("g_jvm == NULL");
|
||||
return NULL;
|
||||
}
|
||||
int rc = g_jvm->GetEnv((void **)&_env, JNI_VERSION_1_6);
|
||||
if (rc == JNI_EDETACHED) {
|
||||
if (g_jvm->AttachCurrentThread(&_env, NULL) != 0) {
|
||||
die("AttachCurrentThread failed");
|
||||
return NULL;
|
||||
}
|
||||
_detach_thread = true;
|
||||
}
|
||||
else if (rc == JNI_EVERSION) {
|
||||
die("JNI version error");
|
||||
return NULL;
|
||||
}
|
||||
detach_thread = true;
|
||||
}
|
||||
else if (rc == JNI_EVERSION) {
|
||||
log_error("JNI version error");
|
||||
return;
|
||||
}
|
||||
return _env;
|
||||
}
|
||||
|
||||
~JVMAttacher()
|
||||
{
|
||||
if (detach_thread)
|
||||
if (_detach_thread)
|
||||
g_jvm->DetachCurrentThread();
|
||||
}
|
||||
|
||||
bool failed() { return env == NULL; }
|
||||
|
||||
JNIEnv *env;
|
||||
|
||||
private:
|
||||
void log_error(const char *reason)
|
||||
{
|
||||
LOGE("JVMAttacher cannot attach to JVM: %s", reason);
|
||||
}
|
||||
|
||||
bool detach_thread = false;
|
||||
JNIEnv *_env;
|
||||
bool _detach_thread;
|
||||
};
|
||||
static thread_local JVMAttacher jvm_attacher;
|
||||
|
||||
#include "android_gamepad.h"
|
||||
|
||||
#define SETTINGS_ACCESSORS(jsetting, csetting, type) \
|
||||
JNIEXPORT type JNICALL Java_com_reicast_emulator_emu_JNIdc_get ## jsetting(JNIEnv *env, jobject obj) __attribute__((visibility("default"))); \
|
||||
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_set ## jsetting(JNIEnv *env, jobject obj, type v) __attribute__((visibility("default"))); \
|
||||
JNIEXPORT type JNICALL Java_com_reicast_emulator_emu_JNIdc_get ## jsetting(JNIEnv *env, jobject obj) \
|
||||
{ \
|
||||
return settings.csetting; \
|
||||
} \
|
||||
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_set ## jsetting(JNIEnv *env, jobject obj, type v) \
|
||||
{ \
|
||||
/* settings.csetting = v; */ \
|
||||
}
|
||||
|
||||
extern "C"
|
||||
{
|
||||
JNIEXPORT jstring JNICALL Java_com_reicast_emulator_emu_JNIdc_initEnvironment(JNIEnv *env, jobject obj, jobject emulator, jstring homeDirectory) __attribute__((visibility("default")));
|
||||
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_config(JNIEnv *env,jobject obj,jstring dirName) __attribute__((visibility("default")));
|
||||
JNIEXPORT jstring 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_setExternalStorageDirectories(JNIEnv *env, jobject obj, jobjectArray pathList) __attribute__((visibility("default")));
|
||||
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_setGameUri(JNIEnv *env,jobject obj,jstring fileName) __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_resume(JNIEnv *env,jobject obj) __attribute__((visibility("default")));
|
||||
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_stop(JNIEnv *env,jobject obj) __attribute__((visibility("default")));
|
||||
|
@ -104,45 +96,15 @@ JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_rendinitJava(JNIEnv *
|
|||
JNIEXPORT jboolean JNICALL Java_com_reicast_emulator_emu_JNIdc_rendframeJava(JNIEnv *env, jobject obj) __attribute__((visibility("default")));
|
||||
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_rendtermJava(JNIEnv *env, jobject obj) __attribute__((visibility("default")));
|
||||
|
||||
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 void JNICALL Java_com_reicast_emulator_emu_JNIdc_vjoy(JNIEnv * env, jobject obj,int id,float x, float y, float w, float h) __attribute__((visibility("default")));
|
||||
|
||||
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_initControllers(JNIEnv *env, jobject obj, jintArray controllers, jobjectArray peripherals) __attribute__((visibility("default")));
|
||||
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_getControllers(JNIEnv *env, jobject obj, jintArray 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 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")));
|
||||
|
||||
SETTINGS_ACCESSORS(Dynarec, dynarec.Enable, jboolean)
|
||||
SETTINGS_ACCESSORS(Idleskip, dynarec.idleskip, jboolean)
|
||||
SETTINGS_ACCESSORS(Unstable, dynarec.unstable_opt, jboolean)
|
||||
SETTINGS_ACCESSORS(Safemode, dynarec.safemode, jboolean)
|
||||
SETTINGS_ACCESSORS(Cable, dreamcast.cable, jint)
|
||||
SETTINGS_ACCESSORS(Region, dreamcast.region, jint)
|
||||
SETTINGS_ACCESSORS(Broadcast, dreamcast.broadcast, jint)
|
||||
SETTINGS_ACCESSORS(Language, dreamcast.language, jint)
|
||||
SETTINGS_ACCESSORS(Limitfps, aica.LimitFPS, jboolean)
|
||||
SETTINGS_ACCESSORS(Nobatch, aica.NoBatch, jboolean)
|
||||
SETTINGS_ACCESSORS(Nosound, aica.NoSound, jboolean)
|
||||
SETTINGS_ACCESSORS(Mipmaps, rend.UseMipmaps, jboolean)
|
||||
SETTINGS_ACCESSORS(Widescreen, rend.WideScreen, jboolean)
|
||||
SETTINGS_ACCESSORS(Frameskip, pvr.ta_skip, jint)
|
||||
SETTINGS_ACCESSORS(Pvrrender, pvr.rend, jint)
|
||||
SETTINGS_ACCESSORS(Syncedrender, pvr.SynchronousRender, jboolean)
|
||||
SETTINGS_ACCESSORS(Modvols, rend.ModifierVolumes, jboolean)
|
||||
SETTINGS_ACCESSORS(Clipping, rend.Clipping, jboolean)
|
||||
SETTINGS_ACCESSORS(Usereios, bios.UseReios, jboolean)
|
||||
SETTINGS_ACCESSORS(Customtextures, rend.CustomTextures, jboolean)
|
||||
SETTINGS_ACCESSORS(Showfps, rend.ShowFPS, jboolean)
|
||||
SETTINGS_ACCESSORS(RenderToTextureBuffer, rend.RenderToTextureBuffer, jboolean)
|
||||
SETTINGS_ACCESSORS(RenderToTextureUpscale, rend.RenderToTextureUpscale, jint)
|
||||
SETTINGS_ACCESSORS(TextureUpscale, rend.TextureUpscale, jint)
|
||||
SETTINGS_ACCESSORS(MaxFilteredTextureSize, rend.MaxFilteredTextureSize, jint)
|
||||
SETTINGS_ACCESSORS(MaxThreads, pvr.MaxThreads, jint)
|
||||
|
||||
JNIEXPORT jint JNICALL Java_com_reicast_emulator_emu_JNIdc_getBootdisk(JNIEnv *env,jobject obj) __attribute__((visibility("default")));
|
||||
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_bootdisk(JNIEnv *env,jobject obj, jstring disk) __attribute__((visibility("default")));
|
||||
SETTINGS_ACCESSORS(VirtualGamepadVibration, input.VirtualGamepadVibration, jint);
|
||||
|
||||
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_screenDpi(JNIEnv *env,jobject obj, jint screenDpi) __attribute__((visibility("default")));
|
||||
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_guiOpenSettings(JNIEnv *env,jobject obj) __attribute__((visibility("default")));
|
||||
|
@ -155,6 +117,10 @@ JNIEXPORT void JNICALL Java_com_reicast_emulator_periph_InputDeviceManager_virtu
|
|||
JNIEXPORT jboolean JNICALL Java_com_reicast_emulator_periph_InputDeviceManager_joystickButtonEvent(JNIEnv *env, jobject obj, jint id, jint key, jboolean pressed) __attribute__((visibility("default")));
|
||||
JNIEXPORT jboolean JNICALL Java_com_reicast_emulator_periph_InputDeviceManager_joystickAxisEvent(JNIEnv *env, jobject obj, jint id, jint key, jint value) __attribute__((visibility("default")));
|
||||
JNIEXPORT void JNICALL Java_com_reicast_emulator_periph_InputDeviceManager_mouseEvent(JNIEnv *env, jobject obj, jint xpos, jint ypos, jint buttons) __attribute__((visibility("default")));
|
||||
|
||||
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_AudioBackend_setInstance(JNIEnv *env, jobject obj, jobject instance) __attribute__((visibility("default")));
|
||||
|
||||
JNIEXPORT void JNICALL Java_com_reicast_emulator_NativeGLActivity_register(JNIEnv *env, jobject obj, jobject activity) __attribute__((visibility("default")));
|
||||
};
|
||||
|
||||
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_screenDpi(JNIEnv *env,jobject obj, jint screenDpi)
|
||||
|
@ -238,9 +204,14 @@ JNIEXPORT jstring JNICALL Java_com_reicast_emulator_emu_JNIdc_initEnvironment(JN
|
|||
// Initialize platform-specific stuff
|
||||
common_linux_setup();
|
||||
|
||||
bool first_init = false;
|
||||
|
||||
// Keep reference to global JVM and Emulator objects
|
||||
if (g_jvm == NULL)
|
||||
{
|
||||
first_init = true;
|
||||
env->GetJavaVM(&g_jvm);
|
||||
}
|
||||
if (g_emulator == NULL) {
|
||||
g_emulator = env->NewGlobalRef(emulator);
|
||||
saveAndroidSettingsMid = env->GetMethodID(env->GetObjectClass(emulator), "SaveAndroidSettings", "(Ljava/lang/String;)V");
|
||||
|
@ -254,27 +225,37 @@ JNIEXPORT jstring JNICALL Java_com_reicast_emulator_emu_JNIdc_initEnvironment(JN
|
|||
if (homeDirectory != NULL)
|
||||
env->ReleaseStringUTFChars(homeDirectory, path);
|
||||
|
||||
jstring msg = NULL;
|
||||
int rc = reicast_init(0, NULL);
|
||||
if (rc == -4)
|
||||
msg = env->NewStringUTF("Cannot find configuration");
|
||||
else if (rc == 69)
|
||||
msg = env->NewStringUTF("Invalid command line");
|
||||
else if (rc == -1)
|
||||
msg = env->NewStringUTF("Memory initialization failed");
|
||||
return msg;
|
||||
if (first_init)
|
||||
{
|
||||
// Do one-time initialization
|
||||
jstring msg = NULL;
|
||||
int rc = reicast_init(0, NULL);
|
||||
if (rc == -4)
|
||||
msg = env->NewStringUTF("Cannot find configuration");
|
||||
else if (rc == 69)
|
||||
msg = env->NewStringUTF("Invalid command line");
|
||||
else if (rc == -1)
|
||||
msg = env->NewStringUTF("Memory initialization failed");
|
||||
return msg;
|
||||
}
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_config(JNIEnv *env,jobject obj,jstring dirName)
|
||||
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_setExternalStorageDirectories(JNIEnv *env, jobject obj, jobjectArray pathList)
|
||||
{
|
||||
// Set home directory based on User config
|
||||
const char* D = dirName? env->GetStringUTFChars(dirName,0):0;
|
||||
// set_user_config_dir(D);
|
||||
// set_user_data_dir(D);
|
||||
// printf("Config dir is: %s\n", get_writable_config_path("").c_str());
|
||||
// printf("Data dir is: %s\n", get_writable_data_path("").c_str());
|
||||
setenv("REICAST_HOME", D, 1);
|
||||
env->ReleaseStringUTFChars(dirName,D);
|
||||
std::string paths;
|
||||
int obj_len = env->GetArrayLength(pathList);
|
||||
for (int i = 0; i < obj_len; ++i) {
|
||||
jstring dir = (jstring)env->GetObjectArrayElement(pathList, i);
|
||||
const char* p = env->GetStringUTFChars(dir, 0);
|
||||
if (!paths.empty())
|
||||
paths += ":";
|
||||
paths += p;
|
||||
env->ReleaseStringUTFChars(dir, p);
|
||||
env->DeleteLocalRef(dir);
|
||||
}
|
||||
setenv("REICAST_HOME", paths.c_str(), 1);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_bootdisk(JNIEnv *env,jobject obj, jstring disk) {
|
||||
|
@ -291,41 +272,19 @@ JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_bootdisk(JNIEnv *env,
|
|||
}
|
||||
}
|
||||
|
||||
JNIEXPORT jstring JNICALL Java_com_reicast_emulator_emu_JNIdc_init(JNIEnv *env,jobject obj,jstring fileName)
|
||||
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_setGameUri(JNIEnv *env,jobject obj,jstring fileName)
|
||||
{
|
||||
/* FIXME
|
||||
// Get filename string from Java
|
||||
const char* P = fileName ? env->GetStringUTFChars(fileName,0) : 0;
|
||||
if (!P) gamedisk[0] = '\0';
|
||||
else
|
||||
if (fileName != NULL)
|
||||
{
|
||||
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);
|
||||
// Get filename string from Java
|
||||
const char* file_path = env->GetStringUTFChars(fileName, 0);
|
||||
printf("Game Disk URI: '%s'\n", file_path);
|
||||
strncpy(gamedisk, strlen(file_path) >= 7 && !memcmp(file_path, "file://", 7) ? file_path + 7 : file_path, sizeof(gamedisk));
|
||||
gamedisk[sizeof(gamedisk) - 1] = '\0';
|
||||
env->ReleaseStringUTFChars(fileName, file_path);
|
||||
|
||||
cfgSetVirtual("config", "image", file_path);
|
||||
}
|
||||
|
||||
// Set configuration
|
||||
settings.profile.run_counts = 0;
|
||||
|
||||
// Run nullDC emulator
|
||||
int rc = dc_start_game(gamedisk);
|
||||
|
||||
jstring msg = NULL;
|
||||
if (rc == -5)
|
||||
msg = env->NewStringUTF("BIOS files cannot be found");
|
||||
else if (rc == -4)
|
||||
msg = env->NewStringUTF("Cannot find configuration");
|
||||
else if (rc == -3)
|
||||
msg = env->NewStringUTF("Sound/GPU initialization failed");
|
||||
else if (rc == 69)
|
||||
msg = env->NewStringUTF("Invalid command line");
|
||||
else if (rc == -1)
|
||||
msg = env->NewStringUTF("Memory initialization failed");
|
||||
|
||||
return msg;
|
||||
*/
|
||||
return NULL;
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_diskSwap(JNIEnv *env,jobject obj,jstring disk)
|
||||
|
@ -349,16 +308,6 @@ JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_diskSwap(JNIEnv *env,
|
|||
}
|
||||
}
|
||||
|
||||
#define SAMPLE_COUNT 512
|
||||
|
||||
JNIEnv* jenv; //we are abusing the f*** out of this poor guy
|
||||
//JavaVM* javaVM = NULL; //this seems like the right way to go
|
||||
//stuff for audio
|
||||
jshortArray jsamples;
|
||||
jmethodID writemid;
|
||||
jmethodID coreMessageMid;
|
||||
jmethodID dieMid;
|
||||
jobject emu;
|
||||
//stuff for microphone
|
||||
jobject sipemu;
|
||||
jmethodID getmicdata;
|
||||
|
@ -368,62 +317,11 @@ jbyteArray jpix = NULL;
|
|||
jmethodID updatevmuscreen;
|
||||
extern bool game_started;
|
||||
|
||||
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_query(JNIEnv *env,jobject obj,jobject emu_thread)
|
||||
{
|
||||
/* FIXME
|
||||
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);
|
||||
*/
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_run(JNIEnv *env,jobject obj,jobject emu_thread)
|
||||
{
|
||||
install_prof_handler(0);
|
||||
jenv = env;
|
||||
emu = env->NewGlobalRef(emu_thread); // FIXME Delete ref
|
||||
|
||||
jsamples=env->NewShortArray(SAMPLE_COUNT*2);
|
||||
jsamples = (jshortArray)env->NewGlobalRef(jsamples); // FIXME Delete ref
|
||||
writemid=env->GetMethodID(env->GetObjectClass(emu),"WriteBuffer","([SI)I");
|
||||
coreMessageMid=env->GetMethodID(env->GetObjectClass(emu),"coreMessage","([B)I");
|
||||
dieMid=env->GetMethodID(env->GetObjectClass(emu),"Die","()V");
|
||||
|
||||
//dc_run(NULL);
|
||||
|
||||
//env->DeleteGlobalRef(emu);
|
||||
//emu = NULL;
|
||||
}
|
||||
|
||||
int msgboxf(const wchar* text,unsigned int type,...) {
|
||||
va_list args;
|
||||
|
||||
wchar temp[2048];
|
||||
va_start(args, type);
|
||||
vsprintf(temp, text, args);
|
||||
va_end(args);
|
||||
LOGE("%s", temp);
|
||||
|
||||
if (emu == NULL)
|
||||
return 0;
|
||||
JVMAttacher attacher;
|
||||
if (attacher.failed())
|
||||
return 0;
|
||||
|
||||
int byteCount = strlen(temp);
|
||||
jbyteArray bytes = attacher.env->NewByteArray(byteCount);
|
||||
attacher.env->SetByteArrayRegion(bytes, 0, byteCount, (jbyte *) temp);
|
||||
|
||||
return (int)attacher.env->CallIntMethod(emu, coreMessageMid, bytes);
|
||||
}
|
||||
//stuff for audio
|
||||
#define SAMPLE_COUNT 512
|
||||
jshortArray jsamples;
|
||||
jmethodID writeBufferMid;
|
||||
static jobject g_audioBackend;
|
||||
|
||||
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_setupMic(JNIEnv *env,jobject obj,jobject sip)
|
||||
{
|
||||
|
@ -433,10 +331,8 @@ JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_setupMic(JNIEnv *env,
|
|||
|
||||
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_setupVmu(JNIEnv *env,jobject obj,jobject vmu)
|
||||
{
|
||||
//env->GetJavaVM(&javaVM);
|
||||
vmulcd = env->NewGlobalRef(vmu);
|
||||
updatevmuscreen = env->GetMethodID(env->GetObjectClass(vmu),"updateBytes","([B)V");
|
||||
//jpix=env->NewByteArray(1536);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_pause(JNIEnv *env,jobject obj)
|
||||
|
@ -577,7 +473,7 @@ JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_rendtermJava(JNIEnv *
|
|||
rend_term_renderer();
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_vjoy(JNIEnv * env, jobject obj,u32 id,float x, float y, float w, float h)
|
||||
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_vjoy(JNIEnv * env, jobject obj,int id,float x, float y, float w, float h)
|
||||
{
|
||||
if(id<sizeof(vjoy_pos)/sizeof(vjoy_pos[0]))
|
||||
{
|
||||
|
@ -588,23 +484,6 @@ 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, jintArray controllers, jobjectArray peripherals)
|
||||
{
|
||||
jint *controllers_body = env->GetIntArrayElements(controllers, 0);
|
||||
memcpy(settings.input.maple_devices, controllers_body, sizeof(settings.input.maple_devices));
|
||||
env->ReleaseIntArrayElements(controllers, controllers_body, 0);
|
||||
|
||||
int obj_len = env->GetArrayLength(peripherals);
|
||||
for (int i = 0; i < obj_len; ++i) {
|
||||
jintArray port = (jintArray) env->GetObjectArrayElement(peripherals, i);
|
||||
jint *items = env->GetIntArrayElements(port, 0);
|
||||
settings.input.maple_expansion_devices[i][0] = items[0];
|
||||
settings.input.maple_expansion_devices[i][1] = items[1];
|
||||
env->ReleaseIntArrayElements(port, items, 0);
|
||||
env->DeleteLocalRef(port);
|
||||
}
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_getControllers(JNIEnv *env, jobject obj, jintArray controllers, jobjectArray peripherals)
|
||||
{
|
||||
jint *controllers_body = env->GetIntArrayElements(controllers, 0);
|
||||
|
@ -636,12 +515,9 @@ JNIEXPORT jboolean JNICALL Java_com_reicast_emulator_emu_JNIdc_guiIsOpen(JNIEnv
|
|||
u32 androidaudio_push(void* frame, u32 amt, bool wait)
|
||||
{
|
||||
verify(amt==SAMPLE_COUNT);
|
||||
JVMAttacher attacher; // FIXME don't attach/detach every call...
|
||||
if (attacher.failed())
|
||||
return 0;
|
||||
//yeah, do some audio piping magic here !
|
||||
attacher.env->SetShortArrayRegion(jsamples, 0, amt * 2, (jshort *)frame);
|
||||
return attacher.env->CallIntMethod(emu, writemid, jsamples, wait);
|
||||
jvm_attacher.getEnv()->SetShortArrayRegion(jsamples, 0, amt * 2, (jshort *)frame);
|
||||
return jvm_attacher.getEnv()->CallIntMethod(g_audioBackend, writeBufferMid, jsamples, wait);
|
||||
}
|
||||
|
||||
void androidaudio_init()
|
||||
|
@ -662,15 +538,36 @@ audiobackend_t audiobackend_android = {
|
|||
&androidaudio_term
|
||||
};
|
||||
|
||||
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_AudioBackend_setInstance(JNIEnv *env, jobject obj, jobject instance)
|
||||
{
|
||||
if (g_audioBackend != NULL)
|
||||
env->DeleteGlobalRef(g_audioBackend);
|
||||
if (instance == NULL) {
|
||||
g_audioBackend = NULL;
|
||||
if (jsamples != NULL) {
|
||||
env->DeleteGlobalRef(jsamples);
|
||||
jsamples = NULL;
|
||||
}
|
||||
}
|
||||
else {
|
||||
g_audioBackend = env->NewGlobalRef(instance);
|
||||
writeBufferMid = env->GetMethodID(env->GetObjectClass(g_audioBackend), "writeBuffer", "([SZ)I");
|
||||
if (jsamples == NULL) {
|
||||
jsamples = env->NewShortArray(SAMPLE_COUNT * 2);
|
||||
jsamples = (jshortArray) env->NewGlobalRef(jsamples);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int get_mic_data(u8* buffer)
|
||||
{
|
||||
jbyteArray jdata = (jbyteArray)jenv->CallObjectMethod(sipemu,getmicdata);
|
||||
jbyteArray jdata = (jbyteArray)jvm_attacher.getEnv()->CallObjectMethod(sipemu,getmicdata);
|
||||
if(jdata==NULL){
|
||||
//LOGW("get_mic_data NULL");
|
||||
return 0;
|
||||
}
|
||||
jenv->GetByteArrayRegion(jdata, 0, SIZE_OF_MIC_DATA, (jbyte*)buffer);
|
||||
jenv->DeleteLocalRef(jdata);
|
||||
jvm_attacher.getEnv()->GetByteArrayRegion(jdata, 0, SIZE_OF_MIC_DATA, (jbyte*)buffer);
|
||||
jvm_attacher.getEnv()->DeleteLocalRef(jdata);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -679,13 +576,11 @@ int push_vmu_screen(u8* buffer)
|
|||
if(vmulcd==NULL){
|
||||
return 0;
|
||||
}
|
||||
JNIEnv *env = jenv;
|
||||
//javaVM->AttachCurrentThread(&env, NULL);
|
||||
if(jpix==NULL){
|
||||
jpix=env->NewByteArray(1536);
|
||||
jpix = jvm_attacher.getEnv()->NewByteArray(1536);
|
||||
}
|
||||
env->SetByteArrayRegion(jpix,0,1536,(jbyte*)buffer);
|
||||
env->CallVoidMethod(vmulcd,updatevmuscreen,jpix);
|
||||
jvm_attacher.getEnv()->SetByteArrayRegion(jpix, 0, 1536, (jbyte*)buffer);
|
||||
jvm_attacher.getEnv()->CallVoidMethod(vmulcd, updatevmuscreen, jpix);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -702,20 +597,16 @@ void os_DebugBreak()
|
|||
|
||||
void SaveAndroidSettings()
|
||||
{
|
||||
JVMAttacher attacher;
|
||||
if (attacher.failed())
|
||||
return;
|
||||
jstring homeDirectory = jvm_attacher.getEnv()->NewStringUTF(get_writable_config_path("").c_str());
|
||||
|
||||
jstring homeDirectory = attacher.env->NewStringUTF(get_writable_config_path("").c_str());
|
||||
|
||||
attacher.env->CallVoidMethod(g_emulator, saveAndroidSettingsMid, homeDirectory);
|
||||
attacher.env->DeleteLocalRef(homeDirectory);
|
||||
jvm_attacher.getEnv()->CallVoidMethod(g_emulator, saveAndroidSettingsMid, homeDirectory);
|
||||
jvm_attacher.getEnv()->DeleteLocalRef(homeDirectory);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_com_reicast_emulator_periph_InputDeviceManager_init(JNIEnv *env, jobject obj)
|
||||
{
|
||||
input_device_manager = env->NewGlobalRef(obj);
|
||||
input_device_manager_rumble = env->GetMethodID(env->GetObjectClass(obj), "Rumble", "(IFFI)Z");
|
||||
input_device_manager_rumble = env->GetMethodID(env->GetObjectClass(obj), "rumble", "(IFFI)Z");
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_com_reicast_emulator_periph_InputDeviceManager_joystickAdded(JNIEnv *env, jobject obj, jint id, jstring name, jint maple_port)
|
||||
|
@ -773,3 +664,45 @@ JNIEXPORT void JNICALL Java_com_reicast_emulator_periph_InputDeviceManager_mouse
|
|||
mouse_gamepad.gamepad_btn_input(2, (buttons & 2) != 0);
|
||||
mouse_gamepad.gamepad_btn_input(4, (buttons & 4) != 0);
|
||||
}
|
||||
|
||||
static jobject g_activity;
|
||||
static jmethodID VJoyStartEditingMID;
|
||||
static jmethodID VJoyStopEditingMID;
|
||||
static jmethodID VJoyResetEditingMID;
|
||||
|
||||
JNIEXPORT void JNICALL Java_com_reicast_emulator_NativeGLActivity_register(JNIEnv *env, jobject obj, jobject activity)
|
||||
{
|
||||
if (g_activity != NULL)
|
||||
{
|
||||
env->DeleteGlobalRef(g_activity);
|
||||
g_activity = NULL;
|
||||
}
|
||||
if (activity != NULL) {
|
||||
g_activity = env->NewGlobalRef(activity);
|
||||
VJoyStartEditingMID = env->GetMethodID(env->GetObjectClass(activity), "VJoyStartEditing", "()V");
|
||||
VJoyStopEditingMID = env->GetMethodID(env->GetObjectClass(activity), "VJoyStopEditing", "(Z)V");
|
||||
VJoyResetEditingMID = env->GetMethodID(env->GetObjectClass(activity), "VJoyResetEditing", "()V");
|
||||
}
|
||||
}
|
||||
|
||||
void vjoy_start_editing()
|
||||
{
|
||||
jvm_attacher.getEnv()->CallVoidMethod(g_activity, VJoyStartEditingMID);
|
||||
}
|
||||
|
||||
void vjoy_reset_editing()
|
||||
{
|
||||
jvm_attacher.getEnv()->CallVoidMethod(g_activity, VJoyResetEditingMID);
|
||||
}
|
||||
|
||||
void vjoy_stop_editing(bool canceled)
|
||||
{
|
||||
jvm_attacher.getEnv()->CallVoidMethod(g_activity, VJoyStopEditingMID, canceled);
|
||||
}
|
||||
|
||||
void android_send_logs()
|
||||
{
|
||||
JNIEnv *env = jvm_attacher.getEnv();
|
||||
jmethodID generateErrorLogMID = env->GetMethodID(env->GetObjectClass(g_activity), "generateErrorLog", "()V");
|
||||
env->CallVoidMethod(g_activity, generateErrorLogMID);
|
||||
}
|
||||
|
|
|
@ -143,12 +143,10 @@ public:
|
|||
|
||||
void rumble(float power, float inclination, u32 duration_ms) override
|
||||
{
|
||||
JVMAttacher jvm_attacher;
|
||||
if (jvm_attacher.failed())
|
||||
return;
|
||||
jboolean has_vibrator = jvm_attacher.env->CallBooleanMethod(input_device_manager, input_device_manager_rumble, android_id, power, inclination, duration_ms);
|
||||
jboolean has_vibrator = jvm_attacher.getEnv()->CallBooleanMethod(input_device_manager, input_device_manager_rumble, android_id, power, inclination, duration_ms);
|
||||
_rumble_enabled = has_vibrator;
|
||||
}
|
||||
bool is_virtual_gamepad() override { return android_id == VIRTUAL_GAMEPAD_ID; }
|
||||
|
||||
static const int VIRTUAL_GAMEPAD_ID = 0x12345678; // must match the Java definition
|
||||
|
||||
|
@ -198,7 +196,7 @@ public:
|
|||
if (!find_mapping())
|
||||
input_mapper = new MouseInputMapping();
|
||||
}
|
||||
virtual ~AndroidMouseGamepadDevice() {}
|
||||
|
||||
bool gamepad_btn_input(u32 code, bool pressed) override
|
||||
{
|
||||
if (gui_is_open())
|
||||
|
|
|
@ -1,43 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_horizontal"
|
||||
android:orientation="vertical" >
|
||||
|
||||
<TextView
|
||||
android:id="@+id/about_text"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="6dp"
|
||||
android:layout_marginTop="10dp"
|
||||
android:ems="12"
|
||||
android:gravity="center"
|
||||
android:text="@string/about_text" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/revision_text"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="6dp"
|
||||
android:layout_marginTop="10dp"
|
||||
android:ems="12"
|
||||
android:gravity="center"
|
||||
android:text="@string/revision_text" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/changelist"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginTop="10dp"
|
||||
android:orientation="vertical" >
|
||||
|
||||
<ListView
|
||||
android:id="@+id/list"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:divider="#b5b5b5"
|
||||
android:dividerHeight="1dp" />
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
|
@ -8,11 +8,6 @@
|
|||
android:fitsSystemWindows="false"
|
||||
tools:openDrawer="start">
|
||||
|
||||
<include
|
||||
layout="@layout/app_bar_main"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
|
||||
<android.support.design.widget.NavigationView
|
||||
android:id="@+id/nav_view"
|
||||
android:layout_width="wrap_content"
|
||||
|
|
|
@ -1,35 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
tools:context="com.reicast.emulator.MainActivity">
|
||||
|
||||
<android.support.design.widget.AppBarLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:theme="@style/AppTheme.AppBarOverlay">
|
||||
|
||||
<android.support.v7.widget.Toolbar
|
||||
android:id="@+id/toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?android:attr/actionBarSize"
|
||||
android:background="@android:color/black"
|
||||
app:popupTheme="@style/AppTheme.PopupOverlay">
|
||||
|
||||
<android.support.v7.widget.SearchView
|
||||
android:id="@+id/searchView"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:layout_gravity="right"
|
||||
android:iconifiedByDefault="true" />
|
||||
|
||||
</android.support.v7.widget.Toolbar>
|
||||
|
||||
</android.support.design.widget.AppBarLayout>
|
||||
|
||||
<include layout="@layout/content_main" />
|
||||
|
||||
</android.support.design.widget.CoordinatorLayout>
|
|
@ -6,8 +6,7 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
app:layout_behavior="@string/appbar_scrolling_view_behavior"
|
||||
tools:context=".MainActivity"
|
||||
tools:showIn="@layout/app_bar_main">
|
||||
tools:context=".MainActivity">
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/fragment_container"
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<android.support.design.widget.CoordinatorLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
tools:context="com.reicast.emulator.NativeGLActivity">
|
||||
<com.reicast.emulator.emu.NativeGLView
|
||||
android:id="@+id/glView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"/>
|
||||
</android.support.design.widget.CoordinatorLayout>
|
|
@ -23,21 +23,6 @@
|
|||
#include <unistd.h>
|
||||
#include "hw/maple/maple_cfg.h"
|
||||
|
||||
|
||||
int msgboxf(const wchar* text,unsigned int type,...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
wchar temp[2048];
|
||||
va_start(args, type);
|
||||
vsprintf(temp, text, args);
|
||||
va_end(args);
|
||||
|
||||
//printf(NULL,temp,VER_SHORTNAME,type | MB_TASKMODAL);
|
||||
puts(temp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int darw_printf(const wchar* text,...) {
|
||||
va_list args;
|
||||
|
||||
|
|
|
@ -20,19 +20,6 @@ OSXKeyboardDevice keyboard(0);
|
|||
static std::shared_ptr<OSXKbGamepadDevice> kb_gamepad(0);
|
||||
static std::shared_ptr<OSXMouseGamepadDevice> mouse_gamepad(0);
|
||||
|
||||
int msgboxf(const wchar* text,unsigned int type,...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
wchar temp[2048];
|
||||
va_start(args, type);
|
||||
vsprintf(temp, text, args);
|
||||
va_end(args);
|
||||
|
||||
puts(temp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int darw_printf(const wchar* text,...) {
|
||||
va_list args;
|
||||
|
||||
|
|
|
@ -82,8 +82,9 @@
|
|||
</TestAction>
|
||||
<LaunchAction
|
||||
buildConfiguration = "Release"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
selectedDebuggerIdentifier = ""
|
||||
selectedLauncherIdentifier = "Xcode.IDEFoundation.Launcher.PosixSpawn"
|
||||
language = ""
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
|
|
Loading…
Reference in New Issue