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)
#endif
extern bool fast_forward_mode;
//Sound generation, mixin, and channel regs emulation
//x.15
s32 volume_lut[16];
@ -1479,7 +1481,8 @@ void AICA_Sample32()
pl=mixl;
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;
}

View File

@ -42,6 +42,7 @@ enum DreamcastKey
EMU_BTN_TRIGGER_LEFT = 1 << 17,
EMU_BTN_TRIGGER_RIGHT = 1 << 18,
EMU_BTN_MENU = 1 << 19,
EMU_BTN_FFORWARD = 1 << 20,
// Real axes
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::mutex GamepadDevice::_gamepads_mutex;
bool fast_forward_mode;
#ifdef TEST_AUTOMATION
#include "hw/sh4/sh4_sched.h"
@ -108,6 +109,10 @@ bool GamepadDevice::gamepad_btn_input(u32 code, bool pressed)
if (pressed)
gui_open_settings();
break;
case EMU_BTN_FFORWARD:
if (pressed)
fast_forward_mode = !fast_forward_mode;
break;
case EMU_BTN_TRIGGER_LEFT:
lt[_maple_port] = pressed ? 255 : 0;
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;
}

View File

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

View File

@ -88,7 +88,7 @@ class IdentityInputMapping : public InputMapping
public:
IdentityInputMapping() {
name = "Default";
for (int i = 0; i < 16; i++)
for (int i = 0; i < 32; i++)
set_button((DreamcastKey)(1 << i), 1 << i);
set_axis(DC_AXIS_X, DC_AXIS_X, 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_RIGHT, KEY_V);
set_button(EMU_BTN_MENU, KEY_TAB);
set_button(EMU_BTN_FFORWARD, KEY_SPACE);
dirty = false;
}

View File

@ -32,6 +32,8 @@ void LoadCustom();
void* dc_run(void*);
void dc_resume();
extern bool fast_forward_mode;
settings_t settings;
// Set if game has corresponding option by default, so that it's not saved in the config
static bool rtt_to_buffer_game;
@ -152,7 +154,7 @@ void LoadSpecialSettings()
|| !strncmp("T26702N", prod_id, 7)) // PBA Tour Bowling 2001
{
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;
settings.dreamcast.FullMMU = true;
settings.aica.NoBatch = true;
@ -577,6 +579,7 @@ void dc_start_game(const char *path)
saved_screen_stretching = -1;
}
}
fast_forward_mode = false;
game_started = true;
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 u8 rt[4],lt[4];
#define VJOY_VISIBLE 14
#if defined(__ANDROID__)
extern float vjoy_pos[14][8];
extern float vjoy_pos[15][8];
#else
float vjoy_pos[14][8]=
float vjoy_pos[15][8]=
{
{24+0,24+64,64,64}, //LEFT
{24+64,24+0,64,64}, //UP
@ -1421,29 +1423,27 @@ float vjoy_pos[14][8]=
{320-32,360+32,64,64}, //Start
{440,200,90,64}, //RT
{542,200,90,64}, //LT
{440,200,90,64}, //LT
{542,200,90,64}, //RT
{-24,128+224,128,128}, //ANALOG_RING
{96,320,64,64}, //ANALOG_POINT
{1}
{320-32,24,64,64}, // FFORWARD
{1} // VJOY_VISIBLE
};
#endif // !__ANDROID__
static List<Vertex> osd_vertices;
static bool osd_vertices_overrun;
static const float vjoy_sz[2][14] = {
{ 64,64,64,64, 64,64,64,64, 64, 90,90, 128, 64 },
{ 64,64,64,64, 64,64,64,64, 64, 64,64, 128, 64 },
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, 64, 64,64, 128, 64, 64 },
};
void HideOSD()
{
vjoy_pos[13][0] = 0;
vjoy_pos[13][1] = 0;
vjoy_pos[13][2] = 0;
vjoy_pos[13][3] = 0;
vjoy_pos[VJOY_VISIBLE][0] = 0;
}
static void DrawButton(float* xy, u32 state)
@ -1452,11 +1452,11 @@ static void DrawButton(float* xy, u32 state)
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[12],0);
DrawButton2(vjoy_pos[13], 0);
}
#define OSD_TEX_W 512
@ -1517,7 +1519,7 @@ void OSD_DRAW(bool clear_screen)
float u=0;
float v=0;
for (int i=0;i<13;i++)
for (int i = 0; i < 14; i++)
{
//umin,vmin,umax,vmax
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 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 };
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" };
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" };
@ -1587,6 +1587,7 @@ static float fps = -1;
static std::string osd_message;
static double osd_message_end;
extern bool fast_forward_mode;
void gui_display_notification(const char *msg, int duration)
{
@ -1606,12 +1607,12 @@ static std::string getFPSNotification()
}
if (fps >= 0.f && fps < 9999.f) {
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("");
return std::string(fast_forward_mode ? ">>" : "");
}
void gui_display_osd()

View File

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

View File

@ -222,6 +222,7 @@ public:
set_button(EMU_BTN_TRIGGER_LEFT, 'F');
set_button(EMU_BTN_TRIGGER_RIGHT, 'V');
set_button(EMU_BTN_MENU, VK_TAB);
set_button(EMU_BTN_FFORWARD, VK_SPACE);
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 float[][] vjoy_d_cached; // Used for VJoy editing
private AudioBackend audioBackend;
private Handler handler = new Handler();
protected Handler handler = new Handler();
public static byte[] syms;
private boolean audioPermissionRequested = false;
private boolean paused = true;
@ -127,6 +127,7 @@ public abstract class BaseGLActivity extends Activity implements ActivityCompat.
pathList.addAll(FileBrowser.getExternalMounts());
Log.i("flycast", "External storage dirs: " + pathList);
JNIdc.setExternalStorageDirectories(pathList.toArray());
FileBrowser.installButtons(prefs);
}
@Override

View File

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

View File

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

View File

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

View File

@ -18,7 +18,7 @@ public class VirtualJoystickDelegate {
private VibratorThread vibratorThread;
private boolean editVjoyMode = false;
private int selectedVjoyElement = -1;
private int selectedVjoyElement = VJoy.ELEM_NONE;
private ScaleGestureDetector scaleGestureDetector;
private Handler handler = new Handler();
@ -98,8 +98,8 @@ public class VirtualJoystickDelegate {
float scl_dc = height / 480.0f;
float tx = (width - 640.0f * scl_dc) / 2 / scl_dc;
float a_x = -tx+ 24*scl;
float a_y=- 24*scl;
float a_x = -tx + 24 * scl;
float a_y = -24 * scl;
// Not sure how this can happen
if (vjoy_d_custom == null)
@ -109,6 +109,7 @@ public class VirtualJoystickDelegate {
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)
vjoy[i][0] = vjoy_d[i][0];
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) {
if (buttonId <= 3)
return 0; // DPAD
return VJoy.ELEM_DPAD; // DPAD
else if (buttonId <= 7)
return 1; // X, Y, B, A Buttons
return VJoy.ELEM_BUTTONS; // X, Y, B, A Buttons
else if (buttonId == 8)
return 2; // Start
return VJoy.ELEM_START; // Start
else if (buttonId == 9)
return 3; // Left Trigger
return VJoy.ELEM_LTRIG; // Left Trigger
else if (buttonId == 10)
return 4; // Right Trigger
return VJoy.ELEM_RTRIG; // Right Trigger
else if (buttonId <= 12)
return 5; // Analog
return VJoy.ELEM_ANALOG; // Analog
else if (buttonId == 13)
return VJoy.ELEM_FFORWARD; // Fast-forward
else
return 0; // DPAD diagonials
return VJoy.ELEM_DPAD; // DPAD diagonals
}
private static int left_trigger = 0;
@ -167,7 +170,8 @@ public class VirtualJoystickDelegate {
return false;
JNIdc.show_osd();
this.handler.removeCallbacks(hideOsdRunnable);
this.handler.postDelayed(hideOsdRunnable, 10000);
if (!editVjoyMode)
this.handler.postDelayed(hideOsdRunnable, 10000);
scaleGestureDetector.onTouchEvent(event);
@ -175,13 +179,13 @@ public class VirtualJoystickDelegate {
float scl = height / 480.0f;
float tx = (width - 640.0f * scl) / 2;
int rv = 0xFFFF;
int rv = 0xFFFFFFFF;
int aid = event.getActionMasked();
int pid = event.getActionIndex();
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 y = (event.getY() - ty) / scl;
@ -207,25 +211,14 @@ public class VirtualJoystickDelegate {
if (anal_id != event.getPointerId(i)) {
if (aid == MotionEvent.ACTION_POINTER_UP && pid == i)
continue;
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;
pre*=7;
}
if (pre>255) pre=255;
*/
int pre = 255;
if (y > vjoy[j][1] && y <= (vjoy[j][1] + vjoy[j][3])) {
if (vjoy[j][4] >= -2) {
for (int j = 0; j < vjoy.length; j++)
{
if (x > vjoy[j][0] && x <= (vjoy[j][0] + vjoy[j][2]))
{
if (y > vjoy[j][1] && y <= (vjoy[j][1] + vjoy[j][3]))
{
if (vjoy[j][4] >= VJoy.BTN_RTRIG) {
// Not for analog
if (vjoy[j][5] == 0)
if (!editVjoyMode) {
vibratorThread.vibrate();
@ -234,9 +227,9 @@ public class VirtualJoystickDelegate {
}
if (vjoy[j][4] == -3) {
if (vjoy[j][4] == VJoy.BTN_ANARING) {
if (editVjoyMode) {
selectedVjoyElement = 5; // Analog
selectedVjoyElement = VJoy.ELEM_ANALOG;
resetEditMode();
} else {
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]);
anal_id = event.getPointerId(i);
}
} else if (vjoy[j][4] != -4) {
if (vjoy[j][4] == -1) {
} else if (vjoy[j][4] != VJoy.BTN_ANAPOINT) {
if (vjoy[j][4] == VJoy.BTN_LTRIG) {
if (editVjoyMode) {
selectedVjoyElement = 3; // Left Trigger
selectedVjoyElement = VJoy.ELEM_LTRIG;
resetEditMode();
} else {
left_trigger = pre;
left_trigger = 255;
lt_id = event.getPointerId(i);
}
} else if (vjoy[j][4] == -2) {
} else if (vjoy[j][4] == VJoy.BTN_RTRIG) {
if (editVjoyMode) {
selectedVjoyElement = 4; // Right Trigger
selectedVjoyElement = VJoy.ELEM_RTRIG;
resetEditMode();
} else {
right_trigger = pre;
right_trigger = 255;
rt_id = event.getPointerId(i);
}
} else {
@ -308,7 +301,7 @@ public class VirtualJoystickDelegate {
selectedVjoyElement = -1;
reset_analog();
anal_id = -1;
rv = 0xFFFF;
rv = 0xFFFFFFFF;
right_trigger = 0;
left_trigger = 0;
lt_id = -1;
@ -362,16 +355,11 @@ public class VirtualJoystickDelegate {
}
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 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) || JNIdc.guiIsOpen())
if ((!editVjoyMode && rv == 0xFFFFFFFF) || JNIdc.guiIsOpen())
InputDeviceManager.getInstance().mouseEvent(mouse_pos[0], mouse_pos[1], mouse_btns);
return(true);
}
@ -379,6 +367,9 @@ public class VirtualJoystickDelegate {
public void setEditVjoyMode(boolean editVjoyMode) {
this.editVjoyMode = editVjoyMode;
selectedVjoyElement = -1;
if (editVjoyMode)
this.handler.removeCallbacks(hideOsdRunnable);
resetEditMode();
}
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_Y = 0x0200;
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() {
return new float[][] {
new float[] { 24, 24+64, 64,64, VJoy.key_CONT_DPAD_LEFT, 0},
new float[] { 24+64, 24, 64,64, VJoy.key_CONT_DPAD_UP, 0},
new float[] { 24+128, 24+64, 64,64, VJoy.key_CONT_DPAD_RIGHT, 0},
new float[] { 24+64, 24+128, 64,64, VJoy.key_CONT_DPAD_DOWN, 0},
new float[] { 24, 24+64, 64,64, key_CONT_DPAD_LEFT, 0},
new float[] { 24+64, 24, 64,64, key_CONT_DPAD_UP, 0},
new float[] { 24+128, 24+64, 64,64, key_CONT_DPAD_RIGHT, 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+64, 280, 64,64, VJoy.key_CONT_Y, 0},
new float[] { 440+128, 280+64, 64,64, VJoy.key_CONT_B, 0},
new float[] { 440+64, 280+128,64,64, VJoy.key_CONT_A, 0},
new float[] { 440, 280+64, 64,64, key_CONT_X, 0},
new float[] { 440+64, 280, 64,64, key_CONT_Y, 0},
new float[] { 440+128, 280+64, 64,64, key_CONT_B, 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[] { 542, 200, 90,64, -2, 0},
new float[] { 440, 200, 90,64, BTN_LTRIG, 0}, // LT
new float[] { 542, 200, 90,64, BTN_RTRIG, 0}, // RT
new float[] { 0, 128+224,128,128,-3, 0},
new float[] { 96, 320, 32,32, -4, 0},
new float[] { 0, 128+224,128,128,BTN_ANARING, 0}, // Analog ring
new float[] { 96, 320, 32,32, BTN_ANAPOINT, 0}, // Analog point
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},
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, 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},
@ -48,6 +65,7 @@ public class VJoy {
public static float[][] readCustomVjoyValues(Context context) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
return new float[][] {
// x-shift, y-shift, sizing-factor
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),
prefs.getFloat("touch_y_shift_analog", 0),
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) {
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],
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],
@ -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],
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],
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],
@ -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],
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],
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],
90*vjoy_d_custom[3][2],64*vjoy_d_custom[3][2], -1},
new float[] { 542+vjoy_d_custom[4][0], 200+vjoy_d_custom[4][1],
90*vjoy_d_custom[4][2],64*vjoy_d_custom[4][2], -2},
// Analog ring and point
new float[] { 16+vjoy_d_custom[5][0], 24+32+vjoy_d_custom[5][1],
128*vjoy_d_custom[5][2],128*vjoy_d_custom[5][2],-3},
new float[] { 96+vjoy_d_custom[5][0], 320+vjoy_d_custom[5][1],
32*vjoy_d_custom[5][2],32*vjoy_d_custom[5][2], -4},
// 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],
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],
@ -147,6 +179,10 @@ public class VJoy {
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_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) {
@ -175,5 +211,9 @@ public class VJoy {
prefs.edit().remove("touch_x_shift_analog").apply();
prefs.edit().remove("touch_y_shift_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 };
s8 joyx[4],joyy[4];
u8 rt[4],lt[4];
float vjoy_pos[14][8];
float vjoy_pos[15][8];
extern s32 mo_x_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)
{
if(id<sizeof(vjoy_pos)/sizeof(vjoy_pos[0]))
if (id < ARRAY_SIZE(vjoy_pos))
{
vjoy_pos[id][0] = x;
vjoy_pos[id][1] = y;

View File

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

View File

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