Add Analog "GBA" Support
This allows hacked/homebrew DS games to read analog stick values from the emulator.
This commit is contained in:
parent
3ba3821228
commit
40d7d02d29
|
@ -0,0 +1,80 @@
|
|||
/*
|
||||
Copyright (C) 2021 LRFLEW
|
||||
Copyright (C) 2021 DeSmuME team
|
||||
|
||||
This file 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.
|
||||
|
||||
This file 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 the this software. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "../slot2.h"
|
||||
|
||||
#include <cmath>
|
||||
#include <cstring>
|
||||
|
||||
#include "../debug.h"
|
||||
|
||||
static u16 state[4];
|
||||
|
||||
class Slot2_Analog : public ISlot2Interface {
|
||||
public:
|
||||
Slot2Info const* info() override {
|
||||
static Slot2InfoSimple info("Analog Stick", "Analog Stick input for Modded SM64DS", 0x09);
|
||||
return &info;
|
||||
}
|
||||
|
||||
void connect() override {
|
||||
std::memset(state, 0, sizeof(state));
|
||||
}
|
||||
|
||||
u8 readByte(u8 PROCNUM, u32 addr) override {
|
||||
if ((addr & 0xFFFFFFF8) != 0x09000000)
|
||||
return 0xFF;
|
||||
else if ((addr & 1) == 0)
|
||||
return (u8) state[(addr & 6) >> 1];
|
||||
else
|
||||
return (u8) (state[(addr & 6) >> 1] >> 8);
|
||||
}
|
||||
|
||||
u16 readWord(u8 PROCNUM, u32 addr) override {
|
||||
if ((addr & 0xFFFFFFF8) != 0x09000000)
|
||||
return 0xFFFF;
|
||||
return state[(addr & 6) >> 1];
|
||||
}
|
||||
|
||||
u32 readLong(u8 PROCNUM, u32 addr) override {
|
||||
if ((addr & 0xFFFFFFF8) != 0x09000000)
|
||||
return 0xFFFFFFFF;
|
||||
int i = (addr & 4) >> 1;
|
||||
return ((u32) state[i]) | ((u32) state[i + 1] << 16);
|
||||
}
|
||||
};
|
||||
|
||||
ISlot2Interface* construct_Slot2_Analog() { return new Slot2_Analog(); }
|
||||
|
||||
void analog_setValue(float x, float y) {
|
||||
constexpr float angle_to_short = 10430.37835047f; // 2^15 / Pi
|
||||
constexpr float float_to_fixed = static_cast<float>(0x1000);
|
||||
|
||||
float mag = std::hypot(x, y);
|
||||
float ang = std::atan2(x, y);
|
||||
if (mag > 1.0f) {
|
||||
x /= mag;
|
||||
y /= mag;
|
||||
mag = 1.0f;
|
||||
}
|
||||
|
||||
state[0] = static_cast<u16>(std::lround(mag * float_to_fixed));
|
||||
state[1] = static_cast<u16>(std::lround( x * float_to_fixed));
|
||||
state[2] = static_cast<u16>(std::lround( y * float_to_fixed));
|
||||
state[3] = static_cast<u16>(std::lround(ang * angle_to_short));
|
||||
}
|
|
@ -58,6 +58,7 @@
|
|||
<ClCompile Include="..\..\addons\slot1_retail_auto.cpp" />
|
||||
<ClCompile Include="..\..\addons\slot1_retail_mcrom.cpp" />
|
||||
<ClCompile Include="..\..\addons\slot1_retail_mcrom_debug.cpp" />
|
||||
<ClCompile Include="..\..\addons\slot2_analog.cpp" />
|
||||
<ClCompile Include="..\..\addons\slot2_auto.cpp" />
|
||||
<ClCompile Include="..\..\addons\slot2_passme.cpp" />
|
||||
<ClCompile Include="..\..\addons\slot2_piano.cpp" />
|
||||
|
|
|
@ -930,6 +930,9 @@
|
|||
<ClCompile Include="display.cpp">
|
||||
<Filter>frontend\Windows</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\addons\slot2_analog.cpp">
|
||||
<Filter>addons</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\utils\guid.h">
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
#include <windowsx.h>
|
||||
#include <shlobj.h>
|
||||
#include <richedit.h>
|
||||
|
||||
#include "debug.h"
|
||||
#include "slot2.h"
|
||||
|
@ -42,6 +43,7 @@ bool _OKbutton = false;
|
|||
SGuitar tmp_Guitar;
|
||||
SPiano tmp_Piano;
|
||||
SPaddle tmp_Paddle;
|
||||
SAnalog tmp_Analog;
|
||||
|
||||
//these are the remembered preset values for directory and filename
|
||||
//they are named very verbosely to distinguish them from the currently-configured values in addons.cpp
|
||||
|
@ -467,6 +469,94 @@ INT_PTR CALLBACK GbaSlotPiano(HWND dialog, UINT msg,WPARAM wparam,LPARAM lparam)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
INT_PTR CALLBACK GbaSlotAnalog(HWND dialog, UINT msg, WPARAM wparam, LPARAM lparam) {
|
||||
int which = 0;
|
||||
|
||||
switch (msg) {
|
||||
case WM_INITDIALOG:
|
||||
{
|
||||
_OKbutton = TRUE;
|
||||
SendDlgItemMessage(dialog, IDC_ANALOG_X, WM_USER + 44, tmp_Analog.X, 0);
|
||||
SendDlgItemMessage(dialog, IDC_ANALOG_Y, WM_USER + 44, tmp_Analog.Y, 0);
|
||||
|
||||
std::string deadzone_val = std::to_string(tmp_Analog.Deadzone);
|
||||
SendDlgItemMessage(dialog, IDC_ANALOG_DEADZONE, EM_SETLIMITTEXT, 3, 0);
|
||||
SendDlgItemMessage(dialog, IDC_ANALOG_DEADZONE, EM_SETEVENTMASK, 0, ENM_UPDATE);
|
||||
SetWindowTextA(GetDlgItem(dialog, IDC_ANALOG_DEADZONE), deadzone_val.c_str());
|
||||
|
||||
SendDlgItemMessage(dialog, IDC_ANALOG_DEADZONE_SLIDER, TBM_SETRANGE, FALSE, MAKELONG(0, 100));
|
||||
SendDlgItemMessage(dialog, IDC_ANALOG_DEADZONE_SLIDER, TBM_SETPOS, TRUE, tmp_Analog.Deadzone);
|
||||
|
||||
CheckDlgButton(dialog, IDC_ANALOG_JOINED, tmp_Analog.Joined);
|
||||
CheckDlgButton(dialog, IDC_ANALOG_CIRCLE, tmp_Analog.Circle);
|
||||
EnableWindow(GetDlgItem(dialog, IDC_ANALOG_CIRCLE), tmp_Analog.Joined);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
case WM_USER + 46:
|
||||
SendDlgItemMessage(dialog, IDC_ANALOG_X, WM_USER + 44, tmp_Analog.X, 0);
|
||||
SendDlgItemMessage(dialog, IDC_ANALOG_Y, WM_USER + 44, tmp_Analog.Y, 0);
|
||||
return TRUE;
|
||||
|
||||
case WM_USER + 43:
|
||||
which = GetDlgCtrlID((HWND) lparam);
|
||||
switch (which) {
|
||||
case IDC_ANALOG_X:
|
||||
tmp_Analog.X = wparam;
|
||||
|
||||
break;
|
||||
case IDC_ANALOG_Y:
|
||||
tmp_Analog.Y = wparam;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
SendDlgItemMessage(dialog, IDC_ANALOG_X, WM_USER + 44, tmp_Analog.X, 0);
|
||||
SendDlgItemMessage(dialog, IDC_ANALOG_Y, WM_USER + 44, tmp_Analog.Y, 0);
|
||||
PostMessage(dialog, WM_NEXTDLGCTL, 0, 0);
|
||||
return TRUE;
|
||||
|
||||
case WM_COMMAND:
|
||||
switch (wparam) {
|
||||
case MAKELONG(IDC_ANALOG_DEADZONE, EN_UPDATE):
|
||||
{
|
||||
char text[4];
|
||||
WORD value = 0;
|
||||
bool dirty = false;
|
||||
HWND en = GetDlgItem(dialog, IDC_ANALOG_DEADZONE);
|
||||
GetWindowTextA(en, text, 4);
|
||||
if (text[0] != '\0') value = std::stoi(text);
|
||||
if (value < 0) value = 0, dirty = true;
|
||||
if (value > 100) value = 100, dirty = true;
|
||||
if (dirty) SetWindowTextA(en, std::to_string(value).c_str());
|
||||
if (tmp_Analog.Deadzone != value) {
|
||||
tmp_Analog.Deadzone = value;
|
||||
SendDlgItemMessage(dialog, IDC_ANALOG_DEADZONE_SLIDER, TBM_SETPOS, TRUE, value);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
case MAKELONG(IDC_ANALOG_JOINED, BN_CLICKED):
|
||||
case MAKELONG(IDC_ANALOG_CIRCLE, BN_CLICKED):
|
||||
tmp_Analog.Joined = IsDlgCheckboxChecked(dialog, IDC_ANALOG_JOINED);
|
||||
tmp_Analog.Circle = IsDlgCheckboxChecked(dialog, IDC_ANALOG_CIRCLE);
|
||||
EnableWindow(GetDlgItem(dialog, IDC_ANALOG_CIRCLE), tmp_Analog.Joined);
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
|
||||
case WM_NOTIFY:
|
||||
if (wparam == IDC_ANALOG_DEADZONE_SLIDER) {
|
||||
HWND en = GetDlgItem(dialog, IDC_ANALOG_DEADZONE);
|
||||
WORD value = (WORD) SendDlgItemMessage(dialog, IDC_ANALOG_DEADZONE_SLIDER, TBM_GETPOS, 0, 0);
|
||||
if (tmp_Analog.Deadzone != value) {
|
||||
tmp_Analog.Deadzone = value;
|
||||
SetWindowTextA(en, std::to_string(value).c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
u32 GBAslot_IDDs[NDS_SLOT2_COUNT] = {
|
||||
IDD_GBASLOT_NONE,
|
||||
IDD_GBASLOT_NONE,
|
||||
|
@ -478,6 +568,7 @@ u32 GBAslot_IDDs[NDS_SLOT2_COUNT] = {
|
|||
IDD_GBASLOT_PIANO,
|
||||
IDD_GBASLOT_PADDLE, //paddle
|
||||
IDD_GBASLOT_NONE, //PassME
|
||||
IDD_GBASLOT_ANALOG,
|
||||
};
|
||||
|
||||
DLGPROC GBAslot_Procs[NDS_SLOT2_COUNT] = {
|
||||
|
@ -490,7 +581,8 @@ DLGPROC GBAslot_Procs[NDS_SLOT2_COUNT] = {
|
|||
GbaSlotNone, //expmem
|
||||
GbaSlotPiano,
|
||||
GbaSlotPaddle,
|
||||
GbaSlotNone // PassME
|
||||
GbaSlotNone, // PassME
|
||||
GbaSlotAnalog,
|
||||
};
|
||||
|
||||
|
||||
|
@ -569,6 +661,7 @@ void GBAslotDialog(HWND hwnd)
|
|||
memcpy(&tmp_Guitar, &Guitar, sizeof(Guitar));
|
||||
memcpy(&tmp_Piano, &Piano, sizeof(Piano));
|
||||
memcpy(&tmp_Paddle, &Paddle, sizeof(Paddle));
|
||||
memcpy(&tmp_Analog, &Analog, sizeof(Analog));
|
||||
tmp_CFlashMode = CFlash_Mode;
|
||||
_OKbutton = false;
|
||||
|
||||
|
@ -633,6 +726,14 @@ void GBAslotDialog(HWND hwnd)
|
|||
break;
|
||||
case NDS_SLOT2_PASSME:
|
||||
break;
|
||||
case NDS_SLOT2_ANALOG:
|
||||
memcpy(&Analog, &tmp_Analog, sizeof(tmp_Analog));
|
||||
WritePrivateProfileInt("Slot2.Analog", "X", Analog.X, IniName);
|
||||
WritePrivateProfileInt("Slot2.Analog", "Y", Analog.Y, IniName);
|
||||
WritePrivateProfileInt("Slot2.Analog", "Deadzone", Analog.Deadzone, IniName);
|
||||
WritePrivateProfileBool("Slot2.Analog", "Joined", Analog.Joined, IniName);
|
||||
WritePrivateProfileBool("Slot2.Analog", "Circle", Analog.Circle, IniName);
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
@ -641,9 +742,10 @@ void GBAslotDialog(HWND hwnd)
|
|||
|
||||
WritePrivateProfileInt("Slot2", "id", slot2_List[(u8)slot2_GetCurrentType()]->info()->id(), IniName);
|
||||
|
||||
Guitar.Enabled = (slot2_GetCurrentType() == NDS_SLOT2_GUITARGRIP)?true:false;
|
||||
Piano.Enabled = (slot2_GetCurrentType() == NDS_SLOT2_EASYPIANO)?true:false;
|
||||
Paddle.Enabled = (slot2_GetCurrentType() == NDS_SLOT2_PADDLE)?true:false;
|
||||
Guitar.Enabled = slot2_GetCurrentType() == NDS_SLOT2_GUITARGRIP;
|
||||
Piano.Enabled = slot2_GetCurrentType() == NDS_SLOT2_EASYPIANO;
|
||||
Paddle.Enabled = slot2_GetCurrentType() == NDS_SLOT2_PADDLE;
|
||||
Analog.Enabled = slot2_GetCurrentType() == NDS_SLOT2_ANALOG;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -30,6 +30,8 @@
|
|||
|
||||
#include <tchar.h>
|
||||
#include <io.h>
|
||||
#include <cmath>
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
|
||||
#if (((defined(_MSC_VER) && _MSC_VER >= 1300)) || defined(__MINGW32__))
|
||||
|
@ -97,8 +99,8 @@
|
|||
// gaming buttons and axes
|
||||
#define GAMEDEVICE_JOYNUMPREFIX "(J%x)" // don't change this
|
||||
#define GAMEDEVICE_JOYBUTPREFIX "#[%d]" // don't change this
|
||||
#define GAMEDEVICE_XNEG "Left"
|
||||
#define GAMEDEVICE_XPOS "Right"
|
||||
#define GAMEDEVICE_XPOS "Left"
|
||||
#define GAMEDEVICE_XNEG "Right"
|
||||
#define GAMEDEVICE_YPOS "Up"
|
||||
#define GAMEDEVICE_YNEG "Down"
|
||||
#define GAMEDEVICE_POVLEFT "POV Left"
|
||||
|
@ -119,12 +121,12 @@
|
|||
#define GAMEDEVICE_VNEG "V Down"
|
||||
#define GAMEDEVICE_BUTTON "Button %d"
|
||||
|
||||
#define GAMEDEVICE_XROTPOS "X Rot Up"
|
||||
#define GAMEDEVICE_XROTNEG "X Rot Down"
|
||||
#define GAMEDEVICE_XROTPOS "X Rot Left"
|
||||
#define GAMEDEVICE_XROTNEG "X Rot Right"
|
||||
#define GAMEDEVICE_YROTPOS "Y Rot Up"
|
||||
#define GAMEDEVICE_YROTNEG "Y Rot Down"
|
||||
#define GAMEDEVICE_ZROTPOS "Z Rot Up"
|
||||
#define GAMEDEVICE_ZROTNEG "Z Rot Down"
|
||||
#define GAMEDEVICE_ZROTPOS "Z Rot +"
|
||||
#define GAMEDEVICE_ZROTNEG "Z Rot -"
|
||||
|
||||
// gaming general
|
||||
#define GAMEDEVICE_DISABLED "Disabled"
|
||||
|
@ -206,11 +208,13 @@ static TCHAR szClassName[] = _T("InputCustom");
|
|||
static TCHAR szHotkeysClassName[] = _T("InputCustomHot");
|
||||
static TCHAR szGuitarClassName[] = _T("InputCustomGuitar");
|
||||
static TCHAR szPaddleClassName[] = _T("InputCustomPaddle");
|
||||
static TCHAR szAnalogClassName[] = _T("InputCustomAnalog");
|
||||
|
||||
static LRESULT CALLBACK InputCustomWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
|
||||
static LRESULT CALLBACK HotInputCustomWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
|
||||
static LRESULT CALLBACK GuitarInputCustomWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
|
||||
static LRESULT CALLBACK PaddleInputCustomWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
|
||||
static LRESULT CALLBACK AnalogInputCustomWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
|
||||
|
||||
SJoyState Joystick [16];
|
||||
SJoyState JoystickF [16];
|
||||
|
@ -258,6 +262,9 @@ SPiano DefaultPiano = { false, 'Z', 'S', 'X', 'D', 'C', 'V', 'G', 'B', 'H', 'N',
|
|||
SPaddle Paddle;
|
||||
SPaddle DefaultPaddle = { false, 'K', 'L' };
|
||||
|
||||
SAnalog Analog;
|
||||
SAnalog DefaultAnalog = { false, 1, 2, 15, true, true };
|
||||
|
||||
bool killStylusTopScreen = false;
|
||||
bool killStylusOffScreen = false;
|
||||
bool allowUpAndDown = false;
|
||||
|
@ -390,6 +397,24 @@ static void ReadPaddleControl(const char* name, WORD& output)
|
|||
}
|
||||
}
|
||||
|
||||
static void ReadAnalogControl(const char* name, WORD& output)
|
||||
{
|
||||
UINT temp;
|
||||
temp = GetPrivateProfileInt("Slot2.Analog", name, -1, IniName);
|
||||
if (temp != -1) {
|
||||
output = temp;
|
||||
}
|
||||
}
|
||||
|
||||
static void ReadAnalogBool(const char* name, BOOL& output)
|
||||
{
|
||||
UINT temp;
|
||||
temp = GetPrivateProfileInt("Slot2.Analog", name, -1, IniName);
|
||||
if (temp != -1) {
|
||||
output = (BOOL) temp;
|
||||
}
|
||||
}
|
||||
|
||||
void LoadHotkeyConfig()
|
||||
{
|
||||
SCustomKey *key = &CustomKeys.key(0);
|
||||
|
@ -452,6 +477,17 @@ static void LoadPaddleConfig()
|
|||
ReadPaddleControl("INC", Paddle.INC);
|
||||
}
|
||||
|
||||
static void LoadAnalogConfig()
|
||||
{
|
||||
memcpy(&Analog, &DefaultAnalog, sizeof(Analog));
|
||||
|
||||
ReadAnalogControl("X", Analog.X);
|
||||
ReadAnalogControl("Y", Analog.Y);
|
||||
ReadAnalogControl("Deadzone", Analog.Deadzone);
|
||||
ReadAnalogBool("Joined", Analog.Joined);
|
||||
ReadAnalogBool("Circle", Analog.Circle);
|
||||
}
|
||||
|
||||
|
||||
static void LoadInputConfig()
|
||||
{
|
||||
|
@ -607,7 +643,7 @@ HWND funky;
|
|||
//WPARAM tid;
|
||||
|
||||
//
|
||||
void JoystickChanged( short ID, short Movement)
|
||||
void JoystickChanged( short ID, short Movement, short Axis)
|
||||
{
|
||||
// don't allow two changes to happen too close together in time
|
||||
{
|
||||
|
@ -625,12 +661,19 @@ void JoystickChanged( short ID, short Movement)
|
|||
}
|
||||
|
||||
WORD JoyKey;
|
||||
|
||||
JoyKey = 0x8000;
|
||||
JoyKey = 0x8000;
|
||||
JoyKey |= (WORD)(ID << 8);
|
||||
JoyKey |= Movement;
|
||||
SendMessage(funky,WM_USER+45,JoyKey,0);
|
||||
// KillTimer(funky,tid);
|
||||
|
||||
if (Axis > 0)
|
||||
{
|
||||
WORD JoyAxis;
|
||||
JoyAxis = (WORD)(ID << 8);
|
||||
JoyAxis |= Axis;
|
||||
SendMessage(funky,WM_USER+47,JoyAxis,0);
|
||||
}
|
||||
}
|
||||
|
||||
int FunkyNormalize(int cur, int min, int max)
|
||||
|
@ -652,7 +695,7 @@ int FunkyNormalize(int cur, int min, int max)
|
|||
|
||||
#define S9X_JOY_NEUTRAL 60
|
||||
|
||||
void CheckAxis (short joy, short control, int val,
|
||||
void CheckAxis (short joy, short control, short axis, int val,
|
||||
int min, int max,
|
||||
bool &first, bool &second)
|
||||
{
|
||||
|
@ -665,7 +708,7 @@ void CheckAxis (short joy, short control, int val,
|
|||
second = false;
|
||||
if (!first)
|
||||
{
|
||||
JoystickChanged (joy, control);
|
||||
JoystickChanged (joy, control, axis);
|
||||
first = true;
|
||||
|
||||
}
|
||||
|
@ -678,7 +721,7 @@ void CheckAxis (short joy, short control, int val,
|
|||
first = false;
|
||||
if (!second)
|
||||
{
|
||||
JoystickChanged (joy, (short) (control + 1));
|
||||
JoystickChanged (joy, (short) (control + 1), (short) (8 | axis));
|
||||
second = true;
|
||||
}
|
||||
}
|
||||
|
@ -733,6 +776,13 @@ void S9xUpdateJoyState()
|
|||
CheckAxis_game(JoyStatus.lRy,-10000,10000,Joystick[C].YRotMin,Joystick[C].YRotMax);
|
||||
CheckAxis_game(JoyStatus.lRz,-10000,10000,Joystick[C].ZRotMin,Joystick[C].ZRotMax);
|
||||
|
||||
Joystick[C].lX = JoyStatus.lX;
|
||||
Joystick[C].lY = JoyStatus.lY;
|
||||
Joystick[C].lZ = JoyStatus.lZ;
|
||||
Joystick[C].lRx = JoyStatus.lRx;
|
||||
Joystick[C].lRy = JoyStatus.lRy;
|
||||
Joystick[C].lRz = JoyStatus.lRz;
|
||||
|
||||
switch (JoyStatus.rgdwPOV[0])
|
||||
{
|
||||
case JOY_POVBACKWARD:
|
||||
|
@ -805,18 +855,18 @@ void di_poll_scan()
|
|||
if (FAILED(hr)) hr=pJoystick->Acquire();
|
||||
else
|
||||
{
|
||||
CheckAxis(C,0,JoyStatus.lX,-10000,10000,Joystick[C].Left,Joystick[C].Right);
|
||||
CheckAxis(C,2,JoyStatus.lY,-10000,10000,Joystick[C].Down,Joystick[C].Up);
|
||||
CheckAxis(C,41,JoyStatus.lZ,-10000,10000,Joystick[C].ZNeg,Joystick[C].ZPos);
|
||||
CheckAxis(C,53,JoyStatus.lRx,-10000,10000,Joystick[C].XRotMin,Joystick[C].XRotMax);
|
||||
CheckAxis(C,55,JoyStatus.lRy,-10000,10000,Joystick[C].YRotMin,Joystick[C].YRotMax);
|
||||
CheckAxis(C,57,JoyStatus.lRz,-10000,10000,Joystick[C].ZRotMin,Joystick[C].ZRotMax);
|
||||
CheckAxis(C,0,1,JoyStatus.lX,-10000,10000,Joystick[C].Left,Joystick[C].Right);
|
||||
CheckAxis(C,2,2,JoyStatus.lY,-10000,10000,Joystick[C].Down,Joystick[C].Up);
|
||||
CheckAxis(C,41,3,JoyStatus.lZ,-10000,10000,Joystick[C].ZNeg,Joystick[C].ZPos);
|
||||
CheckAxis(C,53,4,JoyStatus.lRx,-10000,10000,Joystick[C].XRotMin,Joystick[C].XRotMax);
|
||||
CheckAxis(C,55,5,JoyStatus.lRy,-10000,10000,Joystick[C].YRotMin,Joystick[C].YRotMax);
|
||||
CheckAxis(C,57,6,JoyStatus.lRz,-10000,10000,Joystick[C].ZRotMin,Joystick[C].ZRotMax);
|
||||
|
||||
switch (JoyStatus.rgdwPOV[0])
|
||||
{
|
||||
case JOY_POVBACKWARD:
|
||||
if( !JoystickF[C].PovDown)
|
||||
{ JoystickChanged( C, 7); }
|
||||
{ JoystickChanged( C, 7, -1); }
|
||||
|
||||
JoystickF[C].PovDown = true;
|
||||
JoystickF[C].PovUp = false;
|
||||
|
@ -829,7 +879,7 @@ void di_poll_scan()
|
|||
break;
|
||||
case 4500:
|
||||
if( !JoystickF[C].PovUpRight)
|
||||
{ JoystickChanged( C, 52); }
|
||||
{ JoystickChanged( C, 52, -1); }
|
||||
JoystickF[C].PovDown = false;
|
||||
JoystickF[C].PovUp = false;
|
||||
JoystickF[C].PovLeft = false;
|
||||
|
@ -841,7 +891,7 @@ void di_poll_scan()
|
|||
break;
|
||||
case 13500:
|
||||
if( !JoystickF[C].PovDnRight)
|
||||
{ JoystickChanged( C, 50); }
|
||||
{ JoystickChanged( C, 50, -1); }
|
||||
JoystickF[C].PovDown = false;
|
||||
JoystickF[C].PovUp = false;
|
||||
JoystickF[C].PovLeft = false;
|
||||
|
@ -853,7 +903,7 @@ void di_poll_scan()
|
|||
break;
|
||||
case 22500:
|
||||
if( !JoystickF[C].PovDnLeft)
|
||||
{ JoystickChanged( C, 49); }
|
||||
{ JoystickChanged( C, 49, -1); }
|
||||
JoystickF[C].PovDown = false;
|
||||
JoystickF[C].PovUp = false;
|
||||
JoystickF[C].PovLeft = false;
|
||||
|
@ -865,7 +915,7 @@ void di_poll_scan()
|
|||
break;
|
||||
case 31500:
|
||||
if( !JoystickF[C].PovUpLeft)
|
||||
{ JoystickChanged( C, 51); }
|
||||
{ JoystickChanged( C, 51, -1); }
|
||||
JoystickF[C].PovDown = false;
|
||||
JoystickF[C].PovUp = false;
|
||||
JoystickF[C].PovLeft = false;
|
||||
|
@ -878,7 +928,7 @@ void di_poll_scan()
|
|||
|
||||
case JOY_POVFORWARD:
|
||||
if( !JoystickF[C].PovUp)
|
||||
{ JoystickChanged( C, 6); }
|
||||
{ JoystickChanged( C, 6, -1); }
|
||||
|
||||
JoystickF[C].PovDown = false;
|
||||
JoystickF[C].PovUp = true;
|
||||
|
@ -892,7 +942,7 @@ void di_poll_scan()
|
|||
|
||||
case JOY_POVLEFT:
|
||||
if( !JoystickF[C].PovLeft)
|
||||
{ JoystickChanged( C, 4); }
|
||||
{ JoystickChanged( C, 4, -1); }
|
||||
|
||||
JoystickF[C].PovDown = false;
|
||||
JoystickF[C].PovUp = false;
|
||||
|
@ -906,7 +956,7 @@ void di_poll_scan()
|
|||
|
||||
case JOY_POVRIGHT:
|
||||
if( !JoystickF[C].PovRight)
|
||||
{ JoystickChanged( C, 5); }
|
||||
{ JoystickChanged( C, 5, -1); }
|
||||
|
||||
JoystickF[C].PovDown = false;
|
||||
JoystickF[C].PovUp = false;
|
||||
|
@ -935,7 +985,7 @@ void di_poll_scan()
|
|||
{
|
||||
if( !JoystickF[C].Button[B])
|
||||
{
|
||||
JoystickChanged( C, (short)(8+B));
|
||||
JoystickChanged( C, (short)(8+B), -1);
|
||||
JoystickF[C].Button[B] = true;
|
||||
}
|
||||
}
|
||||
|
@ -967,8 +1017,8 @@ void TranslateKey(WORD keyz,char *out)
|
|||
sprintf(out,GAMEDEVICE_JOYNUMPREFIX,((keyz>>8)&0xF));
|
||||
switch(keyz&0xFF)
|
||||
{
|
||||
case 0: strcat(out,GAMEDEVICE_XNEG); break;
|
||||
case 1: strcat(out,GAMEDEVICE_XPOS); break;
|
||||
case 0: strcat(out,GAMEDEVICE_XPOS); break;
|
||||
case 1: strcat(out,GAMEDEVICE_XNEG); break;
|
||||
case 2: strcat(out,GAMEDEVICE_YPOS); break;
|
||||
case 3: strcat(out,GAMEDEVICE_YNEG); break;
|
||||
case 4: strcat(out,GAMEDEVICE_POVLEFT); break;
|
||||
|
@ -1095,11 +1145,28 @@ void TranslateKey(WORD keyz,char *out)
|
|||
case VK_F11: sprintf(out,GAMEDEVICE_VK_F11); break;
|
||||
case VK_F12: sprintf(out,GAMEDEVICE_VK_F12); break;
|
||||
}
|
||||
}
|
||||
|
||||
return ;
|
||||
|
||||
void TranslateAnalog(WORD axis, char* out)
|
||||
{
|
||||
sprintf(out, GAMEDEVICE_JOYNUMPREFIX, ((axis >> 8) & 0xF));
|
||||
switch (axis & 0xF) {
|
||||
case 1: strcat(out, GAMEDEVICE_XPOS); break;
|
||||
case 2: strcat(out, GAMEDEVICE_YPOS); break;
|
||||
case 3: strcat(out, GAMEDEVICE_ZPOS); break;
|
||||
case 4: strcat(out, GAMEDEVICE_XROTPOS); break;
|
||||
case 5: strcat(out, GAMEDEVICE_YROTPOS); break;
|
||||
case 6: strcat(out, GAMEDEVICE_XROTPOS); break;
|
||||
|
||||
case 9: strcat(out, GAMEDEVICE_XNEG); break;
|
||||
case 10: strcat(out, GAMEDEVICE_YNEG); break;
|
||||
case 11: strcat(out, GAMEDEVICE_ZNEG); break;
|
||||
case 12: strcat(out, GAMEDEVICE_XROTNEG); break;
|
||||
case 13: strcat(out, GAMEDEVICE_YROTNEG); break;
|
||||
case 14: strcat(out, GAMEDEVICE_ZROTNEG); break;
|
||||
|
||||
default: strcat(out, "UNKNOWN"); break;
|
||||
}
|
||||
}
|
||||
|
||||
bool IsReserved (WORD Key, int modifiers)
|
||||
|
@ -1177,8 +1244,8 @@ int GetNumButtonsAssignedTo (WORD Key)
|
|||
if(Key == Joypad[J].Y) count++;
|
||||
if(Key == Joypad[J].L) count++;
|
||||
if(Key == Joypad[J].R) count++;
|
||||
if(Key == Joypad[J].Lid) count++;
|
||||
if(Key == Joypad[J].Debug) count++;
|
||||
if(Key == Joypad[J].Lid) count++;
|
||||
if(Key == Joypad[J].Debug) count++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
@ -1297,6 +1364,22 @@ static void InitCustomControls()
|
|||
|
||||
|
||||
RegisterClassEx(&wc);
|
||||
|
||||
wc.cbSize = sizeof(wc);
|
||||
wc.lpszClassName = szAnalogClassName;
|
||||
wc.hInstance = GetModuleHandle(0);
|
||||
wc.lpfnWndProc = AnalogInputCustomWndProc;
|
||||
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
|
||||
wc.hIcon = 0;
|
||||
wc.lpszMenuName = 0;
|
||||
wc.hbrBackground = (HBRUSH) GetSysColorBrush(COLOR_BTNFACE);
|
||||
wc.style = 0;
|
||||
wc.cbClsExtra = 0;
|
||||
wc.cbWndExtra = sizeof(InputCust*);
|
||||
wc.hIconSm = 0;
|
||||
|
||||
|
||||
RegisterClassEx(&wc);
|
||||
}
|
||||
|
||||
InputCust * GetInputCustom(HWND hwnd)
|
||||
|
@ -1782,6 +1865,136 @@ static LRESULT CALLBACK PaddleInputCustomWndProc(HWND hwnd, UINT msg, WPARAM wPa
|
|||
return DefWindowProc(hwnd, msg, wParam, lParam);
|
||||
}
|
||||
|
||||
static LRESULT CALLBACK AnalogInputCustomWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
|
||||
// retrieve the custom structure POINTER for THIS window
|
||||
InputCust* icp = GetInputCustom(hwnd);
|
||||
HWND pappy = (HWND__*) GetWindowLongPtr(hwnd, GWLP_HWNDPARENT);
|
||||
funky = hwnd;
|
||||
|
||||
static HWND selectedItem = NULL;
|
||||
|
||||
char temp[100];
|
||||
COLORREF col;
|
||||
switch (msg) {
|
||||
|
||||
case WM_GETDLGCODE:
|
||||
return DLGC_WANTARROWS | DLGC_WANTALLKEYS | DLGC_WANTCHARS;
|
||||
break;
|
||||
|
||||
|
||||
case WM_NCCREATE:
|
||||
|
||||
// Allocate a new CustCtrl structure for this window.
|
||||
icp = (InputCust*) malloc(sizeof(InputCust));
|
||||
|
||||
// Failed to allocate, stop window creation.
|
||||
if (icp == NULL) return FALSE;
|
||||
|
||||
// Initialize the CustCtrl structure.
|
||||
icp->hwnd = hwnd;
|
||||
icp->crForeGnd = GetSysColor(COLOR_WINDOWTEXT);
|
||||
icp->crBackGnd = GetSysColor(COLOR_WINDOW);
|
||||
icp->hFont = (HFONT__*) GetStockObject(DEFAULT_GUI_FONT);
|
||||
|
||||
// Assign the window text specified in the call to CreateWindow.
|
||||
SetWindowText(hwnd, ((CREATESTRUCT*) lParam)->lpszName);
|
||||
|
||||
// Attach custom structure to this window.
|
||||
SetInputCustom(hwnd, icp);
|
||||
|
||||
InvalidateRect(icp->hwnd, NULL, FALSE);
|
||||
UpdateWindow(icp->hwnd);
|
||||
|
||||
selectedItem = NULL;
|
||||
|
||||
SetTimer(hwnd, 777, 125, NULL);
|
||||
|
||||
// Continue with window creation.
|
||||
return TRUE;
|
||||
|
||||
// Clean up when the window is destroyed.
|
||||
case WM_NCDESTROY:
|
||||
free(icp);
|
||||
break;
|
||||
case WM_PAINT:
|
||||
return InputCustom_OnPaint(icp, wParam, lParam);
|
||||
break;
|
||||
case WM_ERASEBKGND:
|
||||
return 1;
|
||||
case WM_USER+47:
|
||||
TranslateAnalog(wParam, temp);
|
||||
icp->crForeGnd = RGB(0, 0, 0);
|
||||
icp->crBackGnd = RGB(255, 255, 255);
|
||||
SetWindowText(hwnd, temp);
|
||||
InvalidateRect(icp->hwnd, NULL, FALSE);
|
||||
UpdateWindow(icp->hwnd);
|
||||
SendMessage(pappy, WM_USER + 43, wParam, (LPARAM) hwnd);
|
||||
|
||||
break;
|
||||
|
||||
case WM_USER+44:
|
||||
TranslateAnalog(wParam, temp);
|
||||
if (IsWindowEnabled(hwnd)) {
|
||||
col = RGB(255, 255, 255);
|
||||
} else {
|
||||
col = RGB(192, 192, 192);
|
||||
}
|
||||
icp->crForeGnd = ((~col) & 0x00ffffff);
|
||||
icp->crBackGnd = col;
|
||||
SetWindowText(hwnd, temp);
|
||||
InvalidateRect(icp->hwnd, NULL, FALSE);
|
||||
UpdateWindow(icp->hwnd);
|
||||
|
||||
break;
|
||||
|
||||
case WM_SETFOCUS:
|
||||
{
|
||||
selectedItem = hwnd;
|
||||
col = RGB(0, 255, 0);
|
||||
icp->crForeGnd = ((~col) & 0x00ffffff);
|
||||
icp->crBackGnd = col;
|
||||
InvalidateRect(icp->hwnd, NULL, FALSE);
|
||||
UpdateWindow(icp->hwnd);
|
||||
// tid = wParam;
|
||||
|
||||
break;
|
||||
}
|
||||
case WM_KILLFOCUS:
|
||||
{
|
||||
selectedItem = NULL;
|
||||
SendMessage(pappy, WM_USER + 46, wParam, (LPARAM) hwnd); // refresh fields on deselect
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_TIMER:
|
||||
if (hwnd == selectedItem) {
|
||||
FunkyJoyStickTimer();
|
||||
}
|
||||
SetTimer(hwnd, 777, 125, NULL);
|
||||
break;
|
||||
case WM_LBUTTONDOWN:
|
||||
SetFocus(hwnd);
|
||||
break;
|
||||
case WM_ENABLE:
|
||||
COLORREF col;
|
||||
if (wParam) {
|
||||
col = RGB(255, 255, 255);
|
||||
icp->crForeGnd = ((~col) & 0x00ffffff);
|
||||
icp->crBackGnd = col;
|
||||
} else {
|
||||
col = RGB(192, 192, 192);
|
||||
icp->crForeGnd = ((~col) & 0x00ffffff);
|
||||
icp->crBackGnd = col;
|
||||
}
|
||||
InvalidateRect(icp->hwnd, NULL, FALSE);
|
||||
UpdateWindow(icp->hwnd);
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return DefWindowProc(hwnd, msg, wParam, lParam);
|
||||
}
|
||||
|
||||
static void TranslateKeyWithModifiers(int wParam, int modifiers, char * outStr)
|
||||
{
|
||||
|
||||
|
@ -2481,6 +2694,26 @@ void S9xWinScanJoypads(const bool willAcceptInput)
|
|||
}
|
||||
}
|
||||
|
||||
static float get_analog_float(WORD axis)
|
||||
{
|
||||
int J = axis >> 8;
|
||||
LONG val;
|
||||
|
||||
switch (axis & 0x7)
|
||||
{
|
||||
case 1: val = Joystick[J].lX; break;
|
||||
case 2: val = Joystick[J].lY; break;
|
||||
case 3: val = Joystick[J].lZ; break;
|
||||
case 4: val = Joystick[J].lRx; break;
|
||||
case 5: val = Joystick[J].lRy; break;
|
||||
case 6: val = Joystick[J].lRz; break;
|
||||
default: val = 0; break;
|
||||
}
|
||||
|
||||
if (axis & 8) val = -val;
|
||||
return (float) val / 10000.0f;
|
||||
}
|
||||
|
||||
//void S9xOldAutofireAndStuff ()
|
||||
//{
|
||||
// // stuff ripped out of Snes9x that's no longer functional, at least for now
|
||||
|
@ -2690,6 +2923,7 @@ void input_init()
|
|||
LoadGuitarConfig();
|
||||
LoadPianoConfig();
|
||||
LoadPaddleConfig();
|
||||
LoadAnalogConfig();
|
||||
|
||||
di_init();
|
||||
FeedbackON = input_feedback;
|
||||
|
@ -2816,6 +3050,23 @@ void input_acquire()
|
|||
if (inc) nds.paddle += 5;
|
||||
if (dec) nds.paddle -= 5;
|
||||
}
|
||||
|
||||
if (Analog.Enabled)
|
||||
{
|
||||
float deadzone = Analog.Deadzone / 100.0f;
|
||||
float x = get_analog_float(Analog.X);
|
||||
float y = get_analog_float(Analog.Y);
|
||||
|
||||
if (Analog.Joined) {
|
||||
float value = Analog.Circle ? std::hypot(x, y) : (std::max)(std::abs(x), std::abs(y));
|
||||
if (value < deadzone) x = y = 0.0f;
|
||||
} else {
|
||||
if (x < deadzone && x > -deadzone) x = 0.0f;
|
||||
if (y < deadzone && y > -deadzone) y = 0.0f;
|
||||
}
|
||||
|
||||
analog_setValue(x, y);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -2828,6 +3079,10 @@ void input_acquire()
|
|||
{
|
||||
piano_setKey(false, false, false, false, false, false, false, false, false, false, false, false, false);
|
||||
}
|
||||
|
||||
if (Analog.Enabled) {
|
||||
analog_setValue(0.0f, 0.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -119,6 +119,13 @@ struct SJoyState{
|
|||
bool Button[128];
|
||||
bool FeedBack;
|
||||
LPDIRECTINPUTEFFECT pEffect;
|
||||
|
||||
LONG lX;
|
||||
LONG lY;
|
||||
LONG lZ;
|
||||
LONG lRx;
|
||||
LONG lRy;
|
||||
LONG lRz;
|
||||
};
|
||||
|
||||
extern SJoypad Joypad[16];
|
||||
|
@ -153,9 +160,20 @@ struct SPaddle {
|
|||
WORD INC;
|
||||
};
|
||||
|
||||
struct SAnalog {
|
||||
BOOL Enabled;
|
||||
WORD X;
|
||||
WORD Y;
|
||||
|
||||
WORD Deadzone;
|
||||
BOOL Joined;
|
||||
BOOL Circle;
|
||||
};
|
||||
|
||||
extern SGuitar Guitar;
|
||||
extern SPiano Piano;
|
||||
extern SPaddle Paddle;
|
||||
extern SAnalog Analog;
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -1577,9 +1577,10 @@ static BOOL LoadROM(const char * filename, const char * physicalName, const char
|
|||
INFO("Loading %s was successful\n",logicalName);
|
||||
|
||||
NDS_SLOT2_TYPE selectedSlot2Type = slot2_GetSelectedType();
|
||||
Guitar.Enabled = (selectedSlot2Type == NDS_SLOT2_GUITARGRIP)?true:false;
|
||||
Piano.Enabled = (selectedSlot2Type == NDS_SLOT2_EASYPIANO)?true:false;
|
||||
Paddle.Enabled = (selectedSlot2Type == NDS_SLOT2_PADDLE)?true:false;
|
||||
Guitar.Enabled = selectedSlot2Type == NDS_SLOT2_GUITARGRIP;
|
||||
Piano.Enabled = selectedSlot2Type == NDS_SLOT2_EASYPIANO;
|
||||
Paddle.Enabled = selectedSlot2Type == NDS_SLOT2_PADDLE;
|
||||
Analog.Enabled = selectedSlot2Type == NDS_SLOT2_ANALOG;
|
||||
|
||||
LoadSaveStateInfo();
|
||||
lagframecounter=0;
|
||||
|
@ -2251,6 +2252,8 @@ int _main()
|
|||
break;
|
||||
case NDS_SLOT2_PASSME:
|
||||
break;
|
||||
case NDS_SLOT2_ANALOG:
|
||||
break;
|
||||
default:
|
||||
slot2_device_type = NDS_SLOT2_NONE;
|
||||
break;
|
||||
|
@ -2258,9 +2261,10 @@ int _main()
|
|||
|
||||
slot2_Change((NDS_SLOT2_TYPE)slot2_device_type);
|
||||
|
||||
Guitar.Enabled = (slot2_device_type == NDS_SLOT2_GUITARGRIP)?true:false;
|
||||
Piano.Enabled = (slot2_device_type == NDS_SLOT2_EASYPIANO)?true:false;
|
||||
Paddle.Enabled = (slot2_device_type == NDS_SLOT2_PADDLE)?true:false;
|
||||
Guitar.Enabled = slot2_device_type == NDS_SLOT2_GUITARGRIP;
|
||||
Piano.Enabled = slot2_device_type == NDS_SLOT2_EASYPIANO;
|
||||
Paddle.Enabled = slot2_device_type == NDS_SLOT2_PADDLE;
|
||||
Analog.Enabled = slot2_device_type == NDS_SLOT2_ANALOG;
|
||||
|
||||
CommonSettings.WifiBridgeDeviceID = GetPrivateProfileInt("Wifi", "BridgeAdapter", 0, IniName);
|
||||
|
||||
|
|
|
@ -514,15 +514,20 @@
|
|||
#define IDC_WIFI_ENABLED 1065
|
||||
#define IDC_STATIC_RANGE 1066
|
||||
#define IDC_WIFI_COMPAT 1066
|
||||
#define IDC_ANALOG_X 1066
|
||||
#define IDC_TEXSCALE 1067
|
||||
#define IDC_ANALOG_Y 1067
|
||||
#define IDC_BADD 1068
|
||||
#define IDC_LIST 1069
|
||||
#define IDC_ANALOG_DEADZONE_SLIDER 1069
|
||||
#define IDC_TEX_DEPOSTERIZE 1070
|
||||
#define IDC_ANALOG_DEADZONE 1070
|
||||
#define IDC_SNUMBER 1071
|
||||
#define IDC_TEX_SMOOTH 1072
|
||||
#define IDC_CHECK1 1074
|
||||
#define IDC_CHECK2 1075
|
||||
#define IDC_CAP0_SRC 1075
|
||||
#define IDC_ANALOG_CIRCLE 1075
|
||||
#define IDC_CHECK3 1076
|
||||
#define IDC_CAP0_ONESHOT 1076
|
||||
#define IDC_CHECK4 1077
|
||||
|
@ -531,6 +536,7 @@
|
|||
#define IDC_CHECK10 1079
|
||||
#define IDC_CAP0_RUNNING 1079
|
||||
#define IDC_BIG_ENDIAN 1079
|
||||
#define IDC_ANALOG_JOINED 1079
|
||||
#define IDC_CHECK6 1080
|
||||
#define IDC_CAP1_SRC 1080
|
||||
#define IDC_CAP1_ONESHOT 1081
|
||||
|
@ -923,6 +929,7 @@
|
|||
#define IDD_SLOT1_R4 10012
|
||||
#define IDD_SLOT1_DEBUG 10013
|
||||
#define IDD_GBASLOT_PADDLE 10014
|
||||
#define IDD_GBASLOT_ANALOG 10015
|
||||
#define IDM_FILE_STOPAVI 40000
|
||||
#define IDM_SCREENSEP_NONE 40000
|
||||
#define IDM_FILE_STOPWAV 40001
|
||||
|
@ -1154,9 +1161,9 @@
|
|||
#ifdef APSTUDIO_INVOKED
|
||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||
#define _APS_NO_MFC 1
|
||||
#define _APS_NEXT_RESOURCE_VALUE 128
|
||||
#define _APS_NEXT_RESOURCE_VALUE 130
|
||||
#define _APS_NEXT_COMMAND_VALUE 40159
|
||||
#define _APS_NEXT_CONTROL_VALUE 1066
|
||||
#define _APS_NEXT_CONTROL_VALUE 1071
|
||||
#define _APS_NEXT_SYMED_VALUE 101
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -1589,6 +1589,22 @@ BEGIN
|
|||
RTEXT "Decrease",-1,81,40,44,8
|
||||
END
|
||||
|
||||
IDD_GBASLOT_ANALOG DIALOGEX 7, 48, 302, 109
|
||||
STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_VISIBLE | WS_SYSMENU
|
||||
FONT 8, "MS Shell Dlg", 400, 0, 0x1
|
||||
BEGIN
|
||||
CONTROL " ",IDC_ANALOG_X,"InputCustomAnalog",WS_TABSTOP,75,17,71,12,WS_EX_CLIENTEDGE
|
||||
CONTROL " ",IDC_ANALOG_Y,"InputCustomAnalog",WS_TABSTOP,180,17,71,12,WS_EX_CLIENTEDGE
|
||||
RTEXT "Left",-1,47,20,24,8
|
||||
CTEXT "Analog Stick:",-1,137,2,51,12
|
||||
RTEXT "Up",-1,152,20,24,8
|
||||
CONTROL "",IDC_ANALOG_DEADZONE_SLIDER,"msctls_trackbar32",TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,147,41,100,15
|
||||
EDITTEXT IDC_ANALOG_DEADZONE,105,41,40,14,ES_AUTOHSCROLL | ES_NUMBER
|
||||
RTEXT "Deadzone",-1,61,41,38,14,SS_CENTERIMAGE
|
||||
CONTROL "Joined Deadzone",IDC_ANALOG_JOINED,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,66,63,71,10
|
||||
CONTROL "Circular Deadzone",IDC_ANALOG_CIRCLE,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,74,77,74,10
|
||||
END
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
|
@ -1968,11 +1984,23 @@ BEGIN
|
|||
BOTTOMMARGIN, 229
|
||||
END
|
||||
|
||||
IDD_GBASLOT, DIALOG
|
||||
BEGIN
|
||||
END
|
||||
|
||||
IDD_GBASLOT_CFLASH, DIALOG
|
||||
BEGIN
|
||||
BOTTOMMARGIN, 106
|
||||
END
|
||||
|
||||
IDD_GBASLOT_GBAGAME, DIALOG
|
||||
BEGIN
|
||||
END
|
||||
|
||||
IDD_GBASLOT_GUITARGRIP, DIALOG
|
||||
BEGIN
|
||||
END
|
||||
|
||||
IDD_MEM_VIEW, DIALOG
|
||||
BEGIN
|
||||
RIGHTMARGIN, 438
|
||||
|
@ -2066,6 +2094,14 @@ BEGIN
|
|||
TOPMARGIN, 7
|
||||
BOTTOMMARGIN, 34
|
||||
END
|
||||
|
||||
IDD_GBASLOT_PADDLE, DIALOG
|
||||
BEGIN
|
||||
END
|
||||
|
||||
IDD_GBASLOT_ANALOG, DIALOG
|
||||
BEGIN
|
||||
END
|
||||
END
|
||||
#endif // APSTUDIO_INVOKED
|
||||
|
||||
|
|
|
@ -58,6 +58,7 @@ void slot2_Init()
|
|||
extern TISlot2InterfaceConstructor construct_Slot2_EasyPiano;
|
||||
extern TISlot2InterfaceConstructor construct_Slot2_Paddle;
|
||||
extern TISlot2InterfaceConstructor construct_Slot2_PassME;
|
||||
extern TISlot2InterfaceConstructor construct_Slot2_Analog;
|
||||
|
||||
slot2_List[NDS_SLOT2_NONE] = construct_Slot2_None();
|
||||
slot2_List[NDS_SLOT2_AUTO] = construct_Slot2_Auto();
|
||||
|
@ -69,6 +70,7 @@ void slot2_Init()
|
|||
slot2_List[NDS_SLOT2_EASYPIANO] = construct_Slot2_EasyPiano();
|
||||
slot2_List[NDS_SLOT2_PADDLE] = construct_Slot2_Paddle();
|
||||
slot2_List[NDS_SLOT2_PASSME] = construct_Slot2_PassME();
|
||||
slot2_List[NDS_SLOT2_ANALOG] = construct_Slot2_Analog();
|
||||
|
||||
}
|
||||
|
||||
|
@ -252,6 +254,7 @@ NDS_SLOT2_TYPE slot2_DetermineTypeByGameCode(const char *theGameCode)
|
|||
{"CV8", NDS_SLOT2_PADDLE}, // Space Invaders Extreme 2
|
||||
{"AMH", NDS_SLOT2_RUMBLEPAK}, // Metroid Prime Hunters
|
||||
{"AP2", NDS_SLOT2_RUMBLEPAK}, // Metroid Prime Pinball
|
||||
{"ASM", NDS_SLOT2_ANALOG}, // Super Mario 64 DS
|
||||
};
|
||||
|
||||
for(size_t i = 0; i < ARRAY_SIZE(gameCodeDeviceTypes); i++)
|
||||
|
|
|
@ -97,6 +97,7 @@ enum NDS_SLOT2_TYPE
|
|||
NDS_SLOT2_EASYPIANO, // 0x06 - Easy Piano
|
||||
NDS_SLOT2_PADDLE, // 0x07 - Arkanoids DS paddle
|
||||
NDS_SLOT2_PASSME, // 0x08 - PassME/Homebrew
|
||||
NDS_SLOT2_ANALOG, // 0x09 - Analog Stick Hack
|
||||
NDS_SLOT2_COUNT // use for counter addons - MUST TO BE LAST!!!
|
||||
};
|
||||
|
||||
|
@ -157,4 +158,5 @@ void Paddle_SetValue(u16 theValue);
|
|||
|
||||
extern void guitarGrip_setKey(bool green, bool red, bool yellow, bool blue); // Guitar grip keys
|
||||
extern void piano_setKey(bool c, bool cs, bool d, bool ds, bool e, bool f, bool fs, bool g, bool gs, bool a, bool as, bool b, bool hic); //piano keys
|
||||
extern void analog_setValue(float x, float y); // Analog Stick State
|
||||
#endif //__SLOT_H__
|
||||
|
|
Loading…
Reference in New Issue