Add fast-forward mode

Fix buttons.png not being created if not first run
This commit is contained in:
Flyinghead 2019-09-27 14:15:29 +02:00
parent 219a001631
commit ae4f378747
21 changed files with 168 additions and 106 deletions

View File

@ -39,6 +39,8 @@ using namespace std;
#define clip_verify(x) #define clip_verify(x)
#endif #endif
extern bool fast_forward_mode;
//Sound generation, mixin, and channel regs emulation //Sound generation, mixin, and channel regs emulation
//x.15 //x.15
s32 volume_lut[16]; s32 volume_lut[16];
@ -1479,7 +1481,8 @@ void AICA_Sample32()
pl=mixl; pl=mixl;
pr=mixr; pr=mixr;
if (!settings.aica.NoSound) WriteSample(mixr,mixl); if (!fast_forward_mode && !settings.aica.NoSound)
WriteSample(mixr,mixl);
} }
} }
@ -1531,7 +1534,7 @@ void AICA_Sample()
} }
} }
if (settings.aica.NoSound) if (fast_forward_mode || settings.aica.NoSound)
{ {
return; return;
} }

View File

@ -42,6 +42,7 @@ enum DreamcastKey
EMU_BTN_TRIGGER_LEFT = 1 << 17, EMU_BTN_TRIGGER_LEFT = 1 << 17,
EMU_BTN_TRIGGER_RIGHT = 1 << 18, EMU_BTN_TRIGGER_RIGHT = 1 << 18,
EMU_BTN_MENU = 1 << 19, EMU_BTN_MENU = 1 << 19,
EMU_BTN_FFORWARD = 1 << 20,
// Real axes // Real axes
DC_AXIS_LT = 0x10000, DC_AXIS_LT = 0x10000,

View File

@ -33,6 +33,7 @@ extern s8 joyx[4], joyy[4];
std::vector<std::shared_ptr<GamepadDevice>> GamepadDevice::_gamepads; std::vector<std::shared_ptr<GamepadDevice>> GamepadDevice::_gamepads;
std::mutex GamepadDevice::_gamepads_mutex; std::mutex GamepadDevice::_gamepads_mutex;
bool fast_forward_mode;
#ifdef TEST_AUTOMATION #ifdef TEST_AUTOMATION
#include "hw/sh4/sh4_sched.h" #include "hw/sh4/sh4_sched.h"
@ -108,6 +109,10 @@ bool GamepadDevice::gamepad_btn_input(u32 code, bool pressed)
if (pressed) if (pressed)
gui_open_settings(); gui_open_settings();
break; break;
case EMU_BTN_FFORWARD:
if (pressed)
fast_forward_mode = !fast_forward_mode;
break;
case EMU_BTN_TRIGGER_LEFT: case EMU_BTN_TRIGGER_LEFT:
lt[_maple_port] = pressed ? 255 : 0; lt[_maple_port] = pressed ? 255 : 0;
break; break;
@ -119,7 +124,7 @@ bool GamepadDevice::gamepad_btn_input(u32 code, bool pressed)
} }
} }
//printf("%d: BUTTON %s %x -> %d. kcode=%x\n", _maple_port, pressed ? "down" : "up", code, key, kcode[_maple_port]); DEBUG_LOG(INPUT, "%d: BUTTON %s %x -> %d. kcode=%x", _maple_port, pressed ? "down" : "up", code, key, kcode[_maple_port]);
return true; return true;
} }

View File

@ -45,6 +45,7 @@ button_list[] =
{ DC_DPAD2_DOWN, "dreamcast", "btn_dpad2_down" }, { DC_DPAD2_DOWN, "dreamcast", "btn_dpad2_down" },
{ EMU_BTN_ESCAPE, "emulator", "btn_escape" }, { EMU_BTN_ESCAPE, "emulator", "btn_escape" },
{ EMU_BTN_MENU, "emulator", "btn_menu" }, { EMU_BTN_MENU, "emulator", "btn_menu" },
{ EMU_BTN_FFORWARD, "emulator", "btn_fforward" },
{ EMU_BTN_TRIGGER_LEFT, "compat", "btn_trigger_left" }, { EMU_BTN_TRIGGER_LEFT, "compat", "btn_trigger_left" },
{ EMU_BTN_TRIGGER_RIGHT, "compat", "btn_trigger_right" } { EMU_BTN_TRIGGER_RIGHT, "compat", "btn_trigger_right" }
}; };

View File

@ -88,7 +88,7 @@ class IdentityInputMapping : public InputMapping
public: public:
IdentityInputMapping() { IdentityInputMapping() {
name = "Default"; name = "Default";
for (int i = 0; i < 16; i++) for (int i = 0; i < 32; i++)
set_button((DreamcastKey)(1 << i), 1 << i); set_button((DreamcastKey)(1 << i), 1 << i);
set_axis(DC_AXIS_X, DC_AXIS_X, false); set_axis(DC_AXIS_X, DC_AXIS_X, false);
set_axis(DC_AXIS_Y, DC_AXIS_Y, false); set_axis(DC_AXIS_Y, DC_AXIS_Y, false);

View File

@ -170,6 +170,7 @@ public:
set_button(EMU_BTN_TRIGGER_LEFT, KEY_F); set_button(EMU_BTN_TRIGGER_LEFT, KEY_F);
set_button(EMU_BTN_TRIGGER_RIGHT, KEY_V); set_button(EMU_BTN_TRIGGER_RIGHT, KEY_V);
set_button(EMU_BTN_MENU, KEY_TAB); set_button(EMU_BTN_MENU, KEY_TAB);
set_button(EMU_BTN_FFORWARD, KEY_SPACE);
dirty = false; dirty = false;
} }

View File

@ -32,6 +32,8 @@ void LoadCustom();
void* dc_run(void*); void* dc_run(void*);
void dc_resume(); void dc_resume();
extern bool fast_forward_mode;
settings_t settings; settings_t settings;
// Set if game has corresponding option by default, so that it's not saved in the config // Set if game has corresponding option by default, so that it's not saved in the config
static bool rtt_to_buffer_game; static bool rtt_to_buffer_game;
@ -152,7 +154,7 @@ void LoadSpecialSettings()
|| !strncmp("T26702N", prod_id, 7)) // PBA Tour Bowling 2001 || !strncmp("T26702N", prod_id, 7)) // PBA Tour Bowling 2001
{ {
INFO_LOG(BOOT, "Enabling Full MMU and Extra depth scaling for Windows CE game"); INFO_LOG(BOOT, "Enabling Full MMU and Extra depth scaling for Windows CE game");
settings.rend.ExtraDepthScale = 0.1; settings.rend.ExtraDepthScale = 0.1; // taxi 2 needs 0.01 for FMV (amd, per-tri)
extra_depth_game = true; extra_depth_game = true;
settings.dreamcast.FullMMU = true; settings.dreamcast.FullMMU = true;
settings.aica.NoBatch = true; settings.aica.NoBatch = true;
@ -577,6 +579,7 @@ void dc_start_game(const char *path)
saved_screen_stretching = -1; saved_screen_stretching = -1;
} }
} }
fast_forward_mode = false;
game_started = true; game_started = true;
dc_resume(); dc_resume();
} }

View File

@ -1403,11 +1403,13 @@ void UpdateFogTexture(u8 *fog_table, GLenum texture_slot, GLint fog_image_format
extern u16 kcode[4]; extern u16 kcode[4];
extern u8 rt[4],lt[4]; extern u8 rt[4],lt[4];
#define VJOY_VISIBLE 14
#if defined(__ANDROID__) #if defined(__ANDROID__)
extern float vjoy_pos[14][8]; extern float vjoy_pos[15][8];
#else #else
float vjoy_pos[14][8]= float vjoy_pos[15][8]=
{ {
{24+0,24+64,64,64}, //LEFT {24+0,24+64,64,64}, //LEFT
{24+64,24+0,64,64}, //UP {24+64,24+0,64,64}, //UP
@ -1421,29 +1423,27 @@ float vjoy_pos[14][8]=
{320-32,360+32,64,64}, //Start {320-32,360+32,64,64}, //Start
{440,200,90,64}, //RT {440,200,90,64}, //LT
{542,200,90,64}, //LT {542,200,90,64}, //RT
{-24,128+224,128,128}, //ANALOG_RING {-24,128+224,128,128}, //ANALOG_RING
{96,320,64,64}, //ANALOG_POINT {96,320,64,64}, //ANALOG_POINT
{1} {320-32,24,64,64}, // FFORWARD
{1} // VJOY_VISIBLE
}; };
#endif // !__ANDROID__ #endif // !__ANDROID__
static List<Vertex> osd_vertices; static List<Vertex> osd_vertices;
static bool osd_vertices_overrun; static bool osd_vertices_overrun;
static const float vjoy_sz[2][14] = { static const float vjoy_sz[2][15] = {
{ 64,64,64,64, 64,64,64,64, 64, 90,90, 128, 64 }, { 64,64,64,64, 64,64,64,64, 64, 90,90, 128, 64, 64 },
{ 64,64,64,64, 64,64,64,64, 64, 64,64, 128, 64 }, { 64,64,64,64, 64,64,64,64, 64, 64,64, 128, 64, 64 },
}; };
void HideOSD() void HideOSD()
{ {
vjoy_pos[13][0] = 0; vjoy_pos[VJOY_VISIBLE][0] = 0;
vjoy_pos[13][1] = 0;
vjoy_pos[13][2] = 0;
vjoy_pos[13][3] = 0;
} }
static void DrawButton(float* xy, u32 state) static void DrawButton(float* xy, u32 state)
@ -1452,11 +1452,11 @@ static void DrawButton(float* xy, u32 state)
vtx.z = 1; vtx.z = 1;
vtx.col[0]=vtx.col[1]=vtx.col[2]=(0x7F-0x40*state/255)*vjoy_pos[13][0]; vtx.col[0]=vtx.col[1]=vtx.col[2]=(0x7F-0x40*state/255)*vjoy_pos[VJOY_VISIBLE][0];
vtx.col[3]=0xA0*vjoy_pos[13][4]; vtx.col[3]=0xA0*vjoy_pos[VJOY_VISIBLE][4];
vjoy_pos[13][4]+=(vjoy_pos[13][0]-vjoy_pos[13][4])/2; vjoy_pos[VJOY_VISIBLE][4]+=(vjoy_pos[VJOY_VISIBLE][0]-vjoy_pos[VJOY_VISIBLE][4])/2;
@ -1500,6 +1500,8 @@ static void osd_gen_vertices()
DrawButton2(vjoy_pos[11],1); DrawButton2(vjoy_pos[11],1);
DrawButton2(vjoy_pos[12],0); DrawButton2(vjoy_pos[12],0);
DrawButton2(vjoy_pos[13], 0);
} }
#define OSD_TEX_W 512 #define OSD_TEX_W 512
@ -1517,7 +1519,7 @@ void OSD_DRAW(bool clear_screen)
float u=0; float u=0;
float v=0; float v=0;
for (int i=0;i<13;i++) for (int i = 0; i < 14; i++)
{ {
//umin,vmin,umax,vmax //umin,vmin,umax,vmax
vjoy_pos[i][4]=(u+1)/OSD_TEX_W; vjoy_pos[i][4]=(u+1)/OSD_TEX_W;

View File

@ -431,10 +431,10 @@ static const char *maple_expansion_device_name(MapleDeviceType type)
const char *maple_ports[] = { "None", "A", "B", "C", "D" }; const char *maple_ports[] = { "None", "A", "B", "C", "D" };
const DreamcastKey button_keys[] = { DC_BTN_START, DC_BTN_A, DC_BTN_B, DC_BTN_X, DC_BTN_Y, DC_DPAD_UP, DC_DPAD_DOWN, DC_DPAD_LEFT, DC_DPAD_RIGHT, const DreamcastKey button_keys[] = { DC_BTN_START, DC_BTN_A, DC_BTN_B, DC_BTN_X, DC_BTN_Y, DC_DPAD_UP, DC_DPAD_DOWN, DC_DPAD_LEFT, DC_DPAD_RIGHT,
EMU_BTN_MENU, EMU_BTN_ESCAPE, EMU_BTN_TRIGGER_LEFT, EMU_BTN_TRIGGER_RIGHT, EMU_BTN_MENU, EMU_BTN_ESCAPE, EMU_BTN_FFORWARD, EMU_BTN_TRIGGER_LEFT, EMU_BTN_TRIGGER_RIGHT,
DC_BTN_C, DC_BTN_D, DC_BTN_Z, DC_DPAD2_UP, DC_DPAD2_DOWN, DC_DPAD2_LEFT, DC_DPAD2_RIGHT }; DC_BTN_C, DC_BTN_D, DC_BTN_Z, DC_DPAD2_UP, DC_DPAD2_DOWN, DC_DPAD2_LEFT, DC_DPAD2_RIGHT };
const char *button_names[] = { "Start", "A", "B", "X", "Y", "DPad Up", "DPad Down", "DPad Left", "DPad Right", const char *button_names[] = { "Start", "A", "B", "X", "Y", "DPad Up", "DPad Down", "DPad Left", "DPad Right",
"Menu", "Exit", "Left Trigger", "Right Trigger", "Menu", "Exit", "Fast-forward", "Left Trigger", "Right Trigger",
"C", "D", "Z", "Right Dpad Up", "Right DPad Down", "Right DPad Left", "Right DPad Right" }; "C", "D", "Z", "Right Dpad Up", "Right DPad Down", "Right DPad Left", "Right DPad Right" };
const DreamcastKey axis_keys[] = { DC_AXIS_X, DC_AXIS_Y, DC_AXIS_LT, DC_AXIS_RT, EMU_AXIS_DPAD1_X, EMU_AXIS_DPAD1_Y, EMU_AXIS_DPAD2_X, EMU_AXIS_DPAD2_Y }; const DreamcastKey axis_keys[] = { DC_AXIS_X, DC_AXIS_Y, DC_AXIS_LT, DC_AXIS_RT, EMU_AXIS_DPAD1_X, EMU_AXIS_DPAD1_Y, EMU_AXIS_DPAD2_X, EMU_AXIS_DPAD2_Y };
const char *axis_names[] = { "Stick X", "Stick Y", "Left Trigger", "Right Trigger", "DPad X", "DPad Y", "Right DPad X", "Right DPad Y" }; const char *axis_names[] = { "Stick X", "Stick Y", "Left Trigger", "Right Trigger", "DPad X", "DPad Y", "Right DPad X", "Right DPad Y" };
@ -1587,6 +1587,7 @@ static float fps = -1;
static std::string osd_message; static std::string osd_message;
static double osd_message_end; static double osd_message_end;
extern bool fast_forward_mode;
void gui_display_notification(const char *msg, int duration) void gui_display_notification(const char *msg, int duration)
{ {
@ -1606,12 +1607,12 @@ static std::string getFPSNotification()
} }
if (fps >= 0.f && fps < 9999.f) { if (fps >= 0.f && fps < 9999.f) {
char text[32]; char text[32];
snprintf(text, sizeof(text), "F:%.1f", fps); snprintf(text, sizeof(text), "F:%.1f%s", fps, fast_forward_mode ? " >>" : "");
return std::string(text); return std::string(text);
} }
} }
return std::string(""); return std::string(fast_forward_mode ? ">>" : "");
} }
void gui_display_osd() void gui_display_osd()

View File

@ -172,6 +172,7 @@ public:
set_button(EMU_BTN_TRIGGER_LEFT, SDLK_f); set_button(EMU_BTN_TRIGGER_LEFT, SDLK_f);
set_button(EMU_BTN_TRIGGER_RIGHT, SDLK_v); set_button(EMU_BTN_TRIGGER_RIGHT, SDLK_v);
set_button(EMU_BTN_MENU, SDLK_TAB); set_button(EMU_BTN_MENU, SDLK_TAB);
set_button(EMU_BTN_FFORWARD, SDLK_SPACE);
dirty = false; dirty = false;
} }

View File

@ -222,6 +222,7 @@ public:
set_button(EMU_BTN_TRIGGER_LEFT, 'F'); set_button(EMU_BTN_TRIGGER_LEFT, 'F');
set_button(EMU_BTN_TRIGGER_RIGHT, 'V'); set_button(EMU_BTN_TRIGGER_RIGHT, 'V');
set_button(EMU_BTN_MENU, VK_TAB); set_button(EMU_BTN_MENU, VK_TAB);
set_button(EMU_BTN_FFORWARD, VK_SPACE);
dirty = false; dirty = false;
} }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 43 KiB

After

Width:  |  Height:  |  Size: 43 KiB

View File

@ -43,7 +43,7 @@ public abstract class BaseGLActivity extends Activity implements ActivityCompat.
protected SharedPreferences prefs; protected SharedPreferences prefs;
protected float[][] vjoy_d_cached; // Used for VJoy editing protected float[][] vjoy_d_cached; // Used for VJoy editing
private AudioBackend audioBackend; private AudioBackend audioBackend;
private Handler handler = new Handler(); protected Handler handler = new Handler();
public static byte[] syms; public static byte[] syms;
private boolean audioPermissionRequested = false; private boolean audioPermissionRequested = false;
private boolean paused = true; private boolean paused = true;
@ -127,6 +127,7 @@ public abstract class BaseGLActivity extends Activity implements ActivityCompat.
pathList.addAll(FileBrowser.getExternalMounts()); pathList.addAll(FileBrowser.getExternalMounts());
Log.i("flycast", "External storage dirs: " + pathList); Log.i("flycast", "External storage dirs: " + pathList);
JNIdc.setExternalStorageDirectories(pathList.toArray()); JNIdc.setExternalStorageDirectories(pathList.toArray());
FileBrowser.installButtons(prefs);
} }
@Override @Override

View File

@ -61,10 +61,10 @@ public class FileBrowser {
try { try {
File buttons = null; File buttons = null;
// TODO button themes // TODO button themes
String theme = prefs.getString(Config.pref_theme, null); //String theme = prefs.getString(Config.pref_theme, null);
if (theme != null) { //if (theme != null) {
buttons = new File(theme); // buttons = new File(theme);
} //}
String home_directory = prefs.getString(Config.pref_home, Environment.getExternalStorageDirectory().getAbsolutePath()); String home_directory = prefs.getString(Config.pref_home, Environment.getExternalStorageDirectory().getAbsolutePath());
File file = new File(home_directory, "data/buttons.png"); File file = new File(home_directory, "data/buttons.png");
InputStream in = null; InputStream in = null;

View File

@ -54,12 +54,22 @@ public final class NativeGLActivity extends BaseGLActivity {
VJoy.resetCustomVjoyValues(getApplicationContext()); VJoy.resetCustomVjoyValues(getApplicationContext());
((NativeGLView)mView).readCustomVjoyValues(); ((NativeGLView)mView).readCustomVjoyValues();
((NativeGLView)mView).resetEditMode(); ((NativeGLView)mView).resetEditMode();
handler.post(new Runnable() {
@Override
public void run() {
mView.requestLayout(); mView.requestLayout();
} }
});
}
// Called from native code // Called from native code
private void VJoyStopEditing(boolean canceled) { private void VJoyStopEditing(final boolean canceled) {
handler.post(new Runnable() {
@Override
public void run() {
if (canceled) if (canceled)
((NativeGLView)mView).restoreCustomVjoyValues(vjoy_d_cached); ((NativeGLView) mView).restoreCustomVjoyValues(vjoy_d_cached);
((NativeGLView)mView).setEditVjoyMode(false); ((NativeGLView) mView).setEditVjoyMode(false);
}
});
} }
} }

View File

@ -41,7 +41,7 @@ public final class JNIdc
public static native boolean guiIsContentBrowser(); public static native boolean guiIsContentBrowser();
public static void show_osd() { public static void show_osd() {
JNIdc.vjoy(13, 1,0,0,0); JNIdc.vjoy(14, 1, 0, 0, 0);
} }
public static native void hideOsd(); public static native void hideOsd();
} }

View File

@ -18,7 +18,7 @@ public class VirtualJoystickDelegate {
private VibratorThread vibratorThread; private VibratorThread vibratorThread;
private boolean editVjoyMode = false; private boolean editVjoyMode = false;
private int selectedVjoyElement = -1; private int selectedVjoyElement = VJoy.ELEM_NONE;
private ScaleGestureDetector scaleGestureDetector; private ScaleGestureDetector scaleGestureDetector;
private Handler handler = new Handler(); private Handler handler = new Handler();
@ -98,8 +98,8 @@ public class VirtualJoystickDelegate {
float scl_dc = height / 480.0f; float scl_dc = height / 480.0f;
float tx = (width - 640.0f * scl_dc) / 2 / scl_dc; float tx = (width - 640.0f * scl_dc) / 2 / scl_dc;
float a_x = -tx+ 24*scl; float a_x = -tx + 24 * scl;
float a_y=- 24*scl; float a_y = -24 * scl;
// Not sure how this can happen // Not sure how this can happen
if (vjoy_d_custom == null) if (vjoy_d_custom == null)
@ -109,6 +109,7 @@ public class VirtualJoystickDelegate {
for (int i=0;i<vjoy.length;i++) for (int i=0;i<vjoy.length;i++)
{ {
// FIXME this hack causes the slight "jump" when first moving a screen-centered button
if (vjoy_d[i][0] == 288) if (vjoy_d[i][0] == 288)
vjoy[i][0] = vjoy_d[i][0]; vjoy[i][0] = vjoy_d[i][0];
else if (vjoy_d[i][0]-vjoy_d_custom[getElementIdFromButtonId(i)][0] < 320) else if (vjoy_d[i][0]-vjoy_d_custom[getElementIdFromButtonId(i)][0] < 320)
@ -138,19 +139,21 @@ public class VirtualJoystickDelegate {
private static int getElementIdFromButtonId(int buttonId) { private static int getElementIdFromButtonId(int buttonId) {
if (buttonId <= 3) if (buttonId <= 3)
return 0; // DPAD return VJoy.ELEM_DPAD; // DPAD
else if (buttonId <= 7) else if (buttonId <= 7)
return 1; // X, Y, B, A Buttons return VJoy.ELEM_BUTTONS; // X, Y, B, A Buttons
else if (buttonId == 8) else if (buttonId == 8)
return 2; // Start return VJoy.ELEM_START; // Start
else if (buttonId == 9) else if (buttonId == 9)
return 3; // Left Trigger return VJoy.ELEM_LTRIG; // Left Trigger
else if (buttonId == 10) else if (buttonId == 10)
return 4; // Right Trigger return VJoy.ELEM_RTRIG; // Right Trigger
else if (buttonId <= 12) else if (buttonId <= 12)
return 5; // Analog return VJoy.ELEM_ANALOG; // Analog
else if (buttonId == 13)
return VJoy.ELEM_FFORWARD; // Fast-forward
else else
return 0; // DPAD diagonials return VJoy.ELEM_DPAD; // DPAD diagonals
} }
private static int left_trigger = 0; private static int left_trigger = 0;
@ -167,6 +170,7 @@ public class VirtualJoystickDelegate {
return false; return false;
JNIdc.show_osd(); JNIdc.show_osd();
this.handler.removeCallbacks(hideOsdRunnable); this.handler.removeCallbacks(hideOsdRunnable);
if (!editVjoyMode)
this.handler.postDelayed(hideOsdRunnable, 10000); this.handler.postDelayed(hideOsdRunnable, 10000);
scaleGestureDetector.onTouchEvent(event); scaleGestureDetector.onTouchEvent(event);
@ -175,13 +179,13 @@ public class VirtualJoystickDelegate {
float scl = height / 480.0f; float scl = height / 480.0f;
float tx = (width - 640.0f * scl) / 2; float tx = (width - 640.0f * scl) / 2;
int rv = 0xFFFF; int rv = 0xFFFFFFFF;
int aid = event.getActionMasked(); int aid = event.getActionMasked();
int pid = event.getActionIndex(); int pid = event.getActionIndex();
if (!JNIdc.guiIsOpen()) { if (!JNIdc.guiIsOpen()) {
if (editVjoyMode && selectedVjoyElement != -1 && aid == MotionEvent.ACTION_MOVE && !scaleGestureDetector.isInProgress()) { if (editVjoyMode && selectedVjoyElement != VJoy.ELEM_NONE && aid == MotionEvent.ACTION_MOVE && !scaleGestureDetector.isInProgress()) {
float x = (event.getX() - tx) / scl; float x = (event.getX() - tx) / scl;
float y = (event.getY() - ty) / scl; float y = (event.getY() - ty) / scl;
@ -207,25 +211,14 @@ public class VirtualJoystickDelegate {
if (anal_id != event.getPointerId(i)) { if (anal_id != event.getPointerId(i)) {
if (aid == MotionEvent.ACTION_POINTER_UP && pid == i) if (aid == MotionEvent.ACTION_POINTER_UP && pid == i)
continue; continue;
for (int j = 0; j < vjoy.length; j++) { for (int j = 0; j < vjoy.length; j++)
if (x > vjoy[j][0] && x <= (vjoy[j][0] + vjoy[j][2])) {
/*
//Disable pressure sensitive R/L
//Doesn't really work properly
int pre=(int)(event.getPressure(i)*255);
if (pre>20)
{ {
pre-=20; if (x > vjoy[j][0] && x <= (vjoy[j][0] + vjoy[j][2]))
pre*=7; {
} if (y > vjoy[j][1] && y <= (vjoy[j][1] + vjoy[j][3]))
if (pre>255) pre=255; {
*/ if (vjoy[j][4] >= VJoy.BTN_RTRIG) {
// Not for analog
int pre = 255;
if (y > vjoy[j][1] && y <= (vjoy[j][1] + vjoy[j][3])) {
if (vjoy[j][4] >= -2) {
if (vjoy[j][5] == 0) if (vjoy[j][5] == 0)
if (!editVjoyMode) { if (!editVjoyMode) {
vibratorThread.vibrate(); vibratorThread.vibrate();
@ -234,9 +227,9 @@ public class VirtualJoystickDelegate {
} }
if (vjoy[j][4] == -3) { if (vjoy[j][4] == VJoy.BTN_ANARING) {
if (editVjoyMode) { if (editVjoyMode) {
selectedVjoyElement = 5; // Analog selectedVjoyElement = VJoy.ELEM_ANALOG;
resetEditMode(); resetEditMode();
} else { } else {
vjoy[j + 1][0] = x - vjoy[j + 1][2] / 2; vjoy[j + 1][0] = x - vjoy[j + 1][2] / 2;
@ -245,21 +238,21 @@ public class VirtualJoystickDelegate {
JNIdc.vjoy(j + 1, vjoy[j + 1][0], vjoy[j + 1][1], vjoy[j + 1][2], vjoy[j + 1][3]); JNIdc.vjoy(j + 1, vjoy[j + 1][0], vjoy[j + 1][1], vjoy[j + 1][2], vjoy[j + 1][3]);
anal_id = event.getPointerId(i); anal_id = event.getPointerId(i);
} }
} else if (vjoy[j][4] != -4) { } else if (vjoy[j][4] != VJoy.BTN_ANAPOINT) {
if (vjoy[j][4] == -1) { if (vjoy[j][4] == VJoy.BTN_LTRIG) {
if (editVjoyMode) { if (editVjoyMode) {
selectedVjoyElement = 3; // Left Trigger selectedVjoyElement = VJoy.ELEM_LTRIG;
resetEditMode(); resetEditMode();
} else { } else {
left_trigger = pre; left_trigger = 255;
lt_id = event.getPointerId(i); lt_id = event.getPointerId(i);
} }
} else if (vjoy[j][4] == -2) { } else if (vjoy[j][4] == VJoy.BTN_RTRIG) {
if (editVjoyMode) { if (editVjoyMode) {
selectedVjoyElement = 4; // Right Trigger selectedVjoyElement = VJoy.ELEM_RTRIG;
resetEditMode(); resetEditMode();
} else { } else {
right_trigger = pre; right_trigger = 255;
rt_id = event.getPointerId(i); rt_id = event.getPointerId(i);
} }
} else { } else {
@ -308,7 +301,7 @@ public class VirtualJoystickDelegate {
selectedVjoyElement = -1; selectedVjoyElement = -1;
reset_analog(); reset_analog();
anal_id = -1; anal_id = -1;
rv = 0xFFFF; rv = 0xFFFFFFFF;
right_trigger = 0; right_trigger = 0;
left_trigger = 0; left_trigger = 0;
lt_id = -1; lt_id = -1;
@ -362,16 +355,11 @@ public class VirtualJoystickDelegate {
} }
break; break;
} }
if (context.getResources().getString(R.string.flavor).equals("naomi")) // FIXME
{
if (left_trigger != 0)
rv &= ~VJoy.key_CONT_C; // Service key/coin
}
int joyx = get_anal(11, 0); int joyx = get_anal(11, 0);
int joyy = get_anal(11, 1); int joyy = get_anal(11, 1);
InputDeviceManager.getInstance().virtualGamepadEvent(rv, joyx, joyy, left_trigger, right_trigger); InputDeviceManager.getInstance().virtualGamepadEvent(rv, joyx, joyy, left_trigger, right_trigger);
// Only register the mouse event if no virtual gamepad button is down // Only register the mouse event if no virtual gamepad button is down
if ((!editVjoyMode && rv == 0xFFFF) || JNIdc.guiIsOpen()) if ((!editVjoyMode && rv == 0xFFFFFFFF) || JNIdc.guiIsOpen())
InputDeviceManager.getInstance().mouseEvent(mouse_pos[0], mouse_pos[1], mouse_btns); InputDeviceManager.getInstance().mouseEvent(mouse_pos[0], mouse_pos[1], mouse_btns);
return(true); return(true);
} }
@ -379,6 +367,9 @@ public class VirtualJoystickDelegate {
public void setEditVjoyMode(boolean editVjoyMode) { public void setEditVjoyMode(boolean editVjoyMode) {
this.editVjoyMode = editVjoyMode; this.editVjoyMode = editVjoyMode;
selectedVjoyElement = -1; selectedVjoyElement = -1;
if (editVjoyMode)
this.handler.removeCallbacks(hideOsdRunnable);
resetEditMode();
} }
private class OscOnScaleGestureListener extends private class OscOnScaleGestureListener extends

View File

@ -16,30 +16,47 @@ public class VJoy {
public static final int key_CONT_DPAD_RIGHT = 0x0080; public static final int key_CONT_DPAD_RIGHT = 0x0080;
public static final int key_CONT_Y = 0x0200; public static final int key_CONT_Y = 0x0200;
public static final int key_CONT_X = 0x0400; public static final int key_CONT_X = 0x0400;
public static final int key_CONT_FFORWARD = 0x100000;
public static int VJoyCount = 13; public static final int BTN_LTRIG = -1;
public static final int BTN_RTRIG = -2;
public static final int BTN_ANARING = -3;
public static final int BTN_ANAPOINT = -4;
public static final int ELEM_NONE = -1;
public static final int ELEM_DPAD = 0;
public static final int ELEM_BUTTONS = 1;
public static final int ELEM_START = 2;
public static final int ELEM_LTRIG = 3;
public static final int ELEM_RTRIG = 4;
public static final int ELEM_ANALOG = 5;
public static final int ELEM_FFORWARD = 6;
public static int VJoyCount = 14;
public static float[][] baseVJoy() { public static float[][] baseVJoy() {
return new float[][] { return new float[][] {
new float[] { 24, 24+64, 64,64, VJoy.key_CONT_DPAD_LEFT, 0}, new float[] { 24, 24+64, 64,64, key_CONT_DPAD_LEFT, 0},
new float[] { 24+64, 24, 64,64, VJoy.key_CONT_DPAD_UP, 0}, new float[] { 24+64, 24, 64,64, key_CONT_DPAD_UP, 0},
new float[] { 24+128, 24+64, 64,64, VJoy.key_CONT_DPAD_RIGHT, 0}, new float[] { 24+128, 24+64, 64,64, key_CONT_DPAD_RIGHT, 0},
new float[] { 24+64, 24+128, 64,64, VJoy.key_CONT_DPAD_DOWN, 0}, new float[] { 24+64, 24+128, 64,64, key_CONT_DPAD_DOWN, 0},
new float[] { 440, 280+64, 64,64, VJoy.key_CONT_X, 0}, new float[] { 440, 280+64, 64,64, key_CONT_X, 0},
new float[] { 440+64, 280, 64,64, VJoy.key_CONT_Y, 0}, new float[] { 440+64, 280, 64,64, key_CONT_Y, 0},
new float[] { 440+128, 280+64, 64,64, VJoy.key_CONT_B, 0}, new float[] { 440+128, 280+64, 64,64, key_CONT_B, 0},
new float[] { 440+64, 280+128,64,64, VJoy.key_CONT_A, 0}, new float[] { 440+64, 280+128,64,64, key_CONT_A, 0},
new float[] { 320-32, 360+32, 64,64, VJoy.key_CONT_START, 0}, new float[] { 320-32, 360+32, 64,64, key_CONT_START, 0},
new float[] { 440, 200, 90,64, -1, 0}, new float[] { 440, 200, 90,64, BTN_LTRIG, 0}, // LT
new float[] { 542, 200, 90,64, -2, 0}, new float[] { 542, 200, 90,64, BTN_RTRIG, 0}, // RT
new float[] { 0, 128+224,128,128,-3, 0}, new float[] { 0, 128+224,128,128,BTN_ANARING, 0}, // Analog ring
new float[] { 96, 320, 32,32, -4, 0}, new float[] { 96, 320, 32,32, BTN_ANAPOINT, 0}, // Analog point
new float[] { 20, 288, 64,64, key_CONT_DPAD_LEFT|key_CONT_DPAD_UP, 0}, new float[] { 320-32, 12, 64,64, key_CONT_FFORWARD, 0}, // Fast-forward
new float[] { 20, 288, 64,64, key_CONT_DPAD_LEFT|key_CONT_DPAD_UP, 0}, // DPad diagonals
new float[] { 20+128, 288, 64,64, key_CONT_DPAD_RIGHT|key_CONT_DPAD_UP, 0}, new float[] { 20+128, 288, 64,64, key_CONT_DPAD_RIGHT|key_CONT_DPAD_UP, 0},
new float[] { 20, 288+128,64,64, key_CONT_DPAD_LEFT|key_CONT_DPAD_DOWN, 0}, new float[] { 20, 288+128,64,64, key_CONT_DPAD_LEFT|key_CONT_DPAD_DOWN, 0},
new float[] { 20+128, 288+128,64,64, key_CONT_DPAD_RIGHT|key_CONT_DPAD_DOWN, 0}, new float[] { 20+128, 288+128,64,64, key_CONT_DPAD_RIGHT|key_CONT_DPAD_DOWN, 0},
@ -48,6 +65,7 @@ public class VJoy {
public static float[][] readCustomVjoyValues(Context context) { public static float[][] readCustomVjoyValues(Context context) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
return new float[][] { return new float[][] {
// x-shift, y-shift, sizing-factor // x-shift, y-shift, sizing-factor
new float[] { prefs.getFloat("touch_x_shift_dpad", 0), new float[] { prefs.getFloat("touch_x_shift_dpad", 0),
@ -73,12 +91,17 @@ public class VJoy {
new float[] { prefs.getFloat("touch_x_shift_analog", 0), new float[] { prefs.getFloat("touch_x_shift_analog", 0),
prefs.getFloat("touch_y_shift_analog", 0), prefs.getFloat("touch_y_shift_analog", 0),
prefs.getFloat("touch_scale_analog", 1) prefs.getFloat("touch_scale_analog", 1)
} // Analog Stick }, // Analog Stick
new float[] { prefs.getFloat("touch_x_shift_fforward", 0),
prefs.getFloat("touch_y_shift_fforward", 0),
prefs.getFloat("touch_scale_fforward", 1)
} // Fast-forward
}; };
} }
public static float[][] getVjoy_d(float[][] vjoy_d_custom) { public static float[][] getVjoy_d(float[][] vjoy_d_custom) {
return new float[][] { return new float[][] {
// LEFT, UP, RIGHT, DOWN
new float[] { 20+0*vjoy_d_custom[0][2]+vjoy_d_custom[0][0], 288+64*vjoy_d_custom[0][2]+vjoy_d_custom[0][1], new float[] { 20+0*vjoy_d_custom[0][2]+vjoy_d_custom[0][0], 288+64*vjoy_d_custom[0][2]+vjoy_d_custom[0][1],
64*vjoy_d_custom[0][2],64*vjoy_d_custom[0][2], key_CONT_DPAD_LEFT}, 64*vjoy_d_custom[0][2],64*vjoy_d_custom[0][2], key_CONT_DPAD_LEFT},
new float[] { 20+64*vjoy_d_custom[0][2]+vjoy_d_custom[0][0], 288+0*vjoy_d_custom[0][2]+vjoy_d_custom[0][1], new float[] { 20+64*vjoy_d_custom[0][2]+vjoy_d_custom[0][0], 288+0*vjoy_d_custom[0][2]+vjoy_d_custom[0][1],
@ -88,6 +111,7 @@ public class VJoy {
new float[] { 20+64*vjoy_d_custom[0][2]+vjoy_d_custom[0][0], 288+128*vjoy_d_custom[0][2]+vjoy_d_custom[0][1], new float[] { 20+64*vjoy_d_custom[0][2]+vjoy_d_custom[0][0], 288+128*vjoy_d_custom[0][2]+vjoy_d_custom[0][1],
64*vjoy_d_custom[0][2],64*vjoy_d_custom[0][2], key_CONT_DPAD_DOWN}, 64*vjoy_d_custom[0][2],64*vjoy_d_custom[0][2], key_CONT_DPAD_DOWN},
// X, Y, B, A
new float[] { 448+0*vjoy_d_custom[1][2]+vjoy_d_custom[1][0], 288+64*vjoy_d_custom[1][2]+vjoy_d_custom[1][1], new float[] { 448+0*vjoy_d_custom[1][2]+vjoy_d_custom[1][0], 288+64*vjoy_d_custom[1][2]+vjoy_d_custom[1][1],
64*vjoy_d_custom[1][2],64*vjoy_d_custom[1][2], key_CONT_X}, 64*vjoy_d_custom[1][2],64*vjoy_d_custom[1][2], key_CONT_X},
new float[] { 448+64*vjoy_d_custom[1][2]+vjoy_d_custom[1][0], 288+0*vjoy_d_custom[1][2]+vjoy_d_custom[1][1], new float[] { 448+64*vjoy_d_custom[1][2]+vjoy_d_custom[1][0], 288+0*vjoy_d_custom[1][2]+vjoy_d_custom[1][1],
@ -97,19 +121,27 @@ public class VJoy {
new float[] { 448+64*vjoy_d_custom[1][2]+vjoy_d_custom[1][0], 288+128*vjoy_d_custom[1][2]+vjoy_d_custom[1][1], new float[] { 448+64*vjoy_d_custom[1][2]+vjoy_d_custom[1][0], 288+128*vjoy_d_custom[1][2]+vjoy_d_custom[1][1],
64*vjoy_d_custom[1][2],64*vjoy_d_custom[1][2], key_CONT_A}, 64*vjoy_d_custom[1][2],64*vjoy_d_custom[1][2], key_CONT_A},
// START
new float[] { 320-32+vjoy_d_custom[2][0], 288+128+vjoy_d_custom[2][1], new float[] { 320-32+vjoy_d_custom[2][0], 288+128+vjoy_d_custom[2][1],
64*vjoy_d_custom[2][2],64*vjoy_d_custom[2][2], key_CONT_START}, 64*vjoy_d_custom[2][2],64*vjoy_d_custom[2][2], key_CONT_START},
// LT, RT
new float[] { 440+vjoy_d_custom[3][0], 200+vjoy_d_custom[3][1], new float[] { 440+vjoy_d_custom[3][0], 200+vjoy_d_custom[3][1],
90*vjoy_d_custom[3][2],64*vjoy_d_custom[3][2], -1}, 90*vjoy_d_custom[3][2],64*vjoy_d_custom[3][2], -1},
new float[] { 542+vjoy_d_custom[4][0], 200+vjoy_d_custom[4][1], new float[] { 542+vjoy_d_custom[4][0], 200+vjoy_d_custom[4][1],
90*vjoy_d_custom[4][2],64*vjoy_d_custom[4][2], -2}, 90*vjoy_d_custom[4][2],64*vjoy_d_custom[4][2], -2},
// Analog ring and point
new float[] { 16+vjoy_d_custom[5][0], 24+32+vjoy_d_custom[5][1], new float[] { 16+vjoy_d_custom[5][0], 24+32+vjoy_d_custom[5][1],
128*vjoy_d_custom[5][2],128*vjoy_d_custom[5][2],-3}, 128*vjoy_d_custom[5][2],128*vjoy_d_custom[5][2],-3},
new float[] { 96+vjoy_d_custom[5][0], 320+vjoy_d_custom[5][1], new float[] { 96+vjoy_d_custom[5][0], 320+vjoy_d_custom[5][1],
32*vjoy_d_custom[5][2],32*vjoy_d_custom[5][2], -4}, 32*vjoy_d_custom[5][2],32*vjoy_d_custom[5][2], -4},
// Fast-forward
new float[] { 320-32+vjoy_d_custom[6][0], 12+vjoy_d_custom[6][1],
64*vjoy_d_custom[6][2],64*vjoy_d_custom[6][2], -5},
// DPad diagonals
new float[] { 20+0*vjoy_d_custom[0][2]+vjoy_d_custom[0][0], 288+0*vjoy_d_custom[0][2]+vjoy_d_custom[0][1], new float[] { 20+0*vjoy_d_custom[0][2]+vjoy_d_custom[0][0], 288+0*vjoy_d_custom[0][2]+vjoy_d_custom[0][1],
64*vjoy_d_custom[0][2],64*vjoy_d_custom[0][2], key_CONT_DPAD_LEFT|key_CONT_DPAD_UP}, 64*vjoy_d_custom[0][2],64*vjoy_d_custom[0][2], key_CONT_DPAD_LEFT|key_CONT_DPAD_UP},
new float[] { 20+128*vjoy_d_custom[0][2]+vjoy_d_custom[0][0], 288+0*vjoy_d_custom[0][2]+vjoy_d_custom[0][1], new float[] { 20+128*vjoy_d_custom[0][2]+vjoy_d_custom[0][0], 288+0*vjoy_d_custom[0][2]+vjoy_d_custom[0][1],
@ -147,6 +179,10 @@ public class VJoy {
prefs.edit().putFloat("touch_x_shift_analog", vjoy_d_custom[5][0]).apply(); prefs.edit().putFloat("touch_x_shift_analog", vjoy_d_custom[5][0]).apply();
prefs.edit().putFloat("touch_y_shift_analog", vjoy_d_custom[5][1]).apply(); prefs.edit().putFloat("touch_y_shift_analog", vjoy_d_custom[5][1]).apply();
prefs.edit().putFloat("touch_scale_analog", vjoy_d_custom[5][2]).apply(); prefs.edit().putFloat("touch_scale_analog", vjoy_d_custom[5][2]).apply();
prefs.edit().putFloat("touch_x_shift_fforward", vjoy_d_custom[6][0]).apply();
prefs.edit().putFloat("touch_y_shift_fforward", vjoy_d_custom[6][1]).apply();
prefs.edit().putFloat("touch_scale_fforward", vjoy_d_custom[6][2]).apply();
} }
public static void resetCustomVjoyValues(Context context) { public static void resetCustomVjoyValues(Context context) {
@ -175,5 +211,9 @@ public class VJoy {
prefs.edit().remove("touch_x_shift_analog").apply(); prefs.edit().remove("touch_x_shift_analog").apply();
prefs.edit().remove("touch_y_shift_analog").apply(); prefs.edit().remove("touch_y_shift_analog").apply();
prefs.edit().remove("touch_scale_analog").apply(); prefs.edit().remove("touch_scale_analog").apply();
prefs.edit().remove("touch_x_shift_fforward").apply();
prefs.edit().remove("touch_y_shift_fforward").apply();
prefs.edit().remove("touch_scale_fforward").apply();
} }
} }

View File

@ -145,7 +145,7 @@ static char gamedisk[256];
u16 kcode[4] = { 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF }; u16 kcode[4] = { 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF };
s8 joyx[4],joyy[4]; s8 joyx[4],joyy[4];
u8 rt[4],lt[4]; u8 rt[4],lt[4];
float vjoy_pos[14][8]; float vjoy_pos[15][8];
extern s32 mo_x_abs; extern s32 mo_x_abs;
extern s32 mo_y_abs; extern s32 mo_y_abs;
@ -453,7 +453,7 @@ JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_rendtermJava(JNIEnv *
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_vjoy(JNIEnv * env, jobject obj,int 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])) if (id < ARRAY_SIZE(vjoy_pos))
{ {
vjoy_pos[id][0] = x; vjoy_pos[id][0] = x;
vjoy_pos[id][1] = y; vjoy_pos[id][1] = y;

View File

@ -148,11 +148,11 @@ public:
// No virtual gamepad when the GUI is open: touch events only // No virtual gamepad when the GUI is open: touch events only
if (gui_is_open()) if (gui_is_open())
{ {
kcode = 0xffff; kcode = 0xffffffff;
joyx = joyy = rt = lt = 0; joyx = joyy = rt = lt = 0;
} }
u16 changes = kcode ^ previous_kcode; u32 changes = kcode ^ previous_kcode;
for (int i = 0; i < 16; i++) for (int i = 0; i < 32; i++)
if (changes & (1 << i)) if (changes & (1 << i))
gamepad_btn_input(1 << i, (kcode & (1 << i)) == 0); gamepad_btn_input(1 << i, (kcode & (1 << i)) == 0);
gamepad_axis_input(DC_AXIS_X, joyx); gamepad_axis_input(DC_AXIS_X, joyx);
@ -189,7 +189,7 @@ protected:
private: private:
int android_id; int android_id;
static std::map<int, std::shared_ptr<AndroidGamepadDevice>> android_gamepads; static std::map<int, std::shared_ptr<AndroidGamepadDevice>> android_gamepads;
u16 previous_kcode = 0xffff; u32 previous_kcode = 0xffffffff;
}; };
std::map<int, std::shared_ptr<AndroidGamepadDevice>> AndroidGamepadDevice::android_gamepads; std::map<int, std::shared_ptr<AndroidGamepadDevice>> AndroidGamepadDevice::android_gamepads;

View File

@ -25,6 +25,7 @@ public:
set_button(EMU_BTN_TRIGGER_LEFT, kVK_ANSI_F); set_button(EMU_BTN_TRIGGER_LEFT, kVK_ANSI_F);
set_button(EMU_BTN_TRIGGER_RIGHT, kVK_ANSI_V); set_button(EMU_BTN_TRIGGER_RIGHT, kVK_ANSI_V);
set_button(EMU_BTN_MENU, kVK_Tab); set_button(EMU_BTN_MENU, kVK_Tab);
set_button(EMU_BTN_FFORWARD, kVK_Space);
dirty = false; dirty = false;
} }