Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Wii U: Use VPad/KPad instead of SDL input #1

Merged
merged 7 commits into from
Aug 12, 2020
7 changes: 6 additions & 1 deletion src/pc/configfile.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,9 @@ unsigned int configKeyStickUp = 0x11;
unsigned int configKeyStickDown = 0x1F;
unsigned int configKeyStickLeft = 0x1E;
unsigned int configKeyStickRight = 0x20;

#ifdef TARGET_WII_U
bool configN64FaceButtons = 0;
#endif

static const struct ConfigOption options[] = {
{.name = "fullscreen", .type = CONFIG_TYPE_BOOL, .boolValue = &configFullscreen},
Expand All @@ -61,6 +63,9 @@ static const struct ConfigOption options[] = {
{.name = "key_stickdown", .type = CONFIG_TYPE_UINT, .uintValue = &configKeyStickDown},
{.name = "key_stickleft", .type = CONFIG_TYPE_UINT, .uintValue = &configKeyStickLeft},
{.name = "key_stickright", .type = CONFIG_TYPE_UINT, .uintValue = &configKeyStickRight},
#ifdef TARGET_WII_U
{.name = "n64_face_buttons", .type = CONFIG_TYPE_BOOL, .boolValue = &configN64FaceButtons}
#endif
};

// Reads an entire line from a file (excluding the newline character) and returns an allocated string
Expand Down
3 changes: 3 additions & 0 deletions src/pc/configfile.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ extern unsigned int configKeyStickUp;
extern unsigned int configKeyStickDown;
extern unsigned int configKeyStickLeft;
extern unsigned int configKeyStickRight;
#ifdef TARGET_WII_U
extern bool configN64FaceButtons;
#endif

void configfile_load(const char *filename);
void configfile_save(const char *filename);
Expand Down
6 changes: 4 additions & 2 deletions src/pc/controller/controller_entry_point.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@

#if defined(_WIN32) || defined(_WIN64)
#include "controller_xinput.h"
#elif defined(TARGET_WII_U)
#include "controller_wiiu.h"
#else
#include "controller_sdl.h"
#endif
Expand All @@ -20,15 +22,15 @@ static struct ControllerAPI *controller_implementations[] = {
&controller_recorded_tas,
#if defined(_WIN32) || defined(_WIN64)
&controller_xinput,
#elif defined(__WIIU__)
&controller_wiiu,
#else
&controller_sdl,
#endif
#ifdef __linux__
&controller_wup,
#endif
#ifndef __WIIU__
&controller_keyboard,
#endif
};

s32 osContInit(UNUSED OSMesgQueue *mq, u8 *controllerBits, UNUSED OSContStatus *status) {
Expand Down
4 changes: 0 additions & 4 deletions src/pc/controller/controller_keyboard.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
#ifndef __WIIU__

#include <stdbool.h>
#include <ultra64.h>

Expand Down Expand Up @@ -88,5 +86,3 @@ struct ControllerAPI controller_keyboard = {
keyboard_init,
keyboard_read
};

#endif
2 changes: 1 addition & 1 deletion src/pc/controller/controller_sdl.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#if !defined(_WIN32) && !defined(_WIN64)
#if !defined(_WIN32) && !defined(_WIN64) && !defined(TARGET_WII_U)

#include <stdio.h>
#include <stdint.h>
Expand Down
175 changes: 175 additions & 0 deletions src/pc/controller/controller_wiiu.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
#include <stdint.h>
#include <stdbool.h>
#include <math.h>

#include <ultra64.h>

#include <vpad/input.h>
#include <padscore/wpad.h>
#include <padscore/kpad.h>

#include "controller_api.h"
#include "../configfile.h"

uint32_t vpad_jump_buttons = VPAD_BUTTON_B | VPAD_BUTTON_A;
uint32_t classic_jump_buttons = WPAD_CLASSIC_BUTTON_B | WPAD_CLASSIC_BUTTON_A;
uint32_t pro_jump_buttons = WPAD_PRO_BUTTON_B | WPAD_PRO_BUTTON_A;
uint32_t vpad_punch_buttons = VPAD_BUTTON_Y | VPAD_BUTTON_X;
uint32_t classic_punch_buttons = WPAD_CLASSIC_BUTTON_Y | WPAD_CLASSIC_BUTTON_X;
uint32_t pro_punch_buttons = WPAD_PRO_BUTTON_Y | WPAD_PRO_BUTTON_X;

struct WiiUKeymap {
uint32_t n64Button;
uint32_t vpadButton;
uint32_t classicButton;
uint32_t proButton;
};

typedef struct Vec2D {
float x, y;
} Vec2D;

// Button shortcuts
#define VB(btn) VPAD_BUTTON_##btn
#define CB(btn) WPAD_CLASSIC_BUTTON_##btn
#define PB(btn) WPAD_PRO_BUTTON_##btn
#define PT(btn) WPAD_PRO_TRIGGER_##btn

// Stick emulation
#define SE(dir) VPAD_STICK_R_EMULATION_##dir, WPAD_CLASSIC_STICK_R_EMULATION_##dir, WPAD_PRO_STICK_R_EMULATION_##dir

struct WiiUKeymap map[] = {
{ B_BUTTON, VB(B) | VB(Y), CB(B) | CB(Y), PB(B) | PB(Y) },
{ A_BUTTON, VB(A) | VB(X), CB(A) | CB(X), PB(A) | PB(X) },
{ START_BUTTON, VB(PLUS), CB(PLUS), PB(PLUS) },
{ Z_TRIG, VB(L) | VB(ZL), CB(L) | CB(ZL), PT(L) | PT(ZL) },
{ R_TRIG, VB(R) | VB(ZR), CB(R) | CB(ZR), PT(R) | PT(ZR) },
{ U_CBUTTONS, SE(UP) },
{ D_CBUTTONS, SE(DOWN) },
{ L_CBUTTONS, SE(LEFT) },
{ R_CBUTTONS, SE(RIGHT) }
};
size_t num_buttons = sizeof(map) / sizeof(map[0]);

static void controller_wiiu_init(void) {
VPADInit();
KPADInit();
WPADEnableURCC(1);
WPADEnableWiiRemote(1);

if (configN64FaceButtons) {
map[0] = (struct WiiUKeymap) { B_BUTTON, VB(Y) | VB(X), CB(Y) | CB(X), PB(Y) | PB(X) };
map[1] = (struct WiiUKeymap) { A_BUTTON, VB(B) | VB(A), CB(B) | CB(A), PB(B) | PB(A) };
}
}

static Vec2D read_vpad(OSContPad *pad) {
VPADStatus status;
VPADReadError err;
uint32_t v;

VPADRead(VPAD_CHAN_0, &status, 1, &err);

if (err != 0)
return (Vec2D) { 0, 0 };

v = status.hold;

for (size_t i = 0; i < num_buttons; i++) {
if (v & map[i].vpadButton) {
pad->button |= map[i].n64Button;
}
}

return (Vec2D) { status.leftStick.x, status.leftStick.y };
}

static Vec2D read_wpad(OSContPad* pad) {
// Disconnect any extra controllers
for (int i = 1; i < 4; i++) {
WPADExtensionType ext;
int res = WPADProbe(i, &ext);
if (res == 0) {
WPADDisconnect(i);
}
}

KPADStatus status;
int err;
int read = KPADReadEx(WPAD_CHAN_0, &status, 1, &err);
if (read == 0)
return (Vec2D) { 0, 0 };

uint32_t wm = status.hold;
KPADVec2D stick;
bool disconnect = false;
if (status.hold & WPAD_BUTTON_MINUS)
disconnect = true;

if (status.extensionType == WPAD_EXT_NUNCHUK || status.extensionType == WPAD_EXT_MPLUS_NUNCHUK) {
uint32_t ext = status.nunchuck.hold;
stick = status.nunchuck.stick;

if (wm & WPAD_BUTTON_A) pad->button |= A_BUTTON;
if (wm & WPAD_BUTTON_B) pad->button |= B_BUTTON;
if (wm & WPAD_BUTTON_PLUS) pad->button |= START_BUTTON;
if (wm & WPAD_BUTTON_UP) pad->button |= U_CBUTTONS;
if (wm & WPAD_BUTTON_DOWN) pad->button |= D_CBUTTONS;
if (wm & WPAD_BUTTON_LEFT) pad->button |= L_CBUTTONS;
if (wm & WPAD_BUTTON_RIGHT) pad->button |= R_CBUTTONS;
if (ext & WPAD_NUNCHUK_BUTTON_C) pad->button |= R_TRIG;
if (ext & WPAD_NUNCHUK_BUTTON_Z) pad->button |= Z_TRIG;
} else if (status.extensionType == WPAD_EXT_CLASSIC || status.extensionType == WPAD_EXT_MPLUS_CLASSIC) {
uint32_t ext = status.classic.hold;
stick = status.classic.leftStick;
for (size_t i = 0; i < num_buttons; i++) {
if (ext & map[i].classicButton) {
pad->button |= map[i].n64Button;
}
}
if (ext & WPAD_CLASSIC_BUTTON_MINUS) {
disconnect = true;
}
} else if (status.extensionType == WPAD_EXT_PRO_CONTROLLER) {
uint32_t ext = status.pro.hold;
stick = status.pro.leftStick;
for (size_t i = 0; i < num_buttons; i++) {
if (ext & map[i].proButton) {
pad->button |= map[i].n64Button;
}
}
if (ext & WPAD_PRO_BUTTON_MINUS) {
disconnect = true;
}
}

if (disconnect)
WPADDisconnect(WPAD_CHAN_0);

return (Vec2D) { stick.x, stick.y };
}

static void controller_wiiu_read(OSContPad* pad) {
Vec2D vstick = read_vpad(pad);
Vec2D wstick = read_wpad(pad);

Vec2D stick = wstick;
if (vstick.x != 0 && vstick.y != 0) {
stick = vstick;
}

if (stick.x < 0)
pad->stick_x = (s8) (stick.x * 128);
else
pad->stick_x = (s8) (stick.x * 127);

if (stick.y < 0)
pad->stick_y = (s8) (stick.y * 128);
else
pad->stick_y = (s8) (stick.y * 127);
}

struct ControllerAPI controller_wiiu = {
controller_wiiu_init,
controller_wiiu_read
};
8 changes: 8 additions & 0 deletions src/pc/controller/controller_wiiu.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#ifndef CONTROLLER_WIIU_H
#define CONTROLLER_WIIU_H

#include "controller_api.h"

extern struct ControllerAPI controller_wiiu;

#endif
23 changes: 6 additions & 17 deletions src/pc/pc_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -163,21 +163,6 @@ void main_func(void) {
main_pool_init(pool, pool + sizeof(pool) / sizeof(pool[0]));
gEffectsMemoryPool = mem_pool_init(0x4000, MEMORY_POOL_LEFT);

#ifdef TARGET_WII_U
WHBLogPrint("Main pool initialized.");

rendering_api = &gfx_whb_api;
wm_api = &gfx_sdl;
configFullscreen = true;

gfx_init(wm_api, rendering_api, "Super Mario 64 PC-Port", true);

WHBLogPrint("Gfx initialized.");

wm_api->set_fullscreen_changed_callback(NULL);
wm_api->set_keyboard_callbacks(NULL, NULL, NULL);

#else
configfile_load(CONFIG_FILE);
atexit(save_config);

Expand All @@ -186,7 +171,12 @@ void main_func(void) {
request_anim_frame(on_anim_frame);
#endif

#if defined(ENABLE_DX12)
#if defined(TARGET_WII_U)
WHBLogPrint("Main pool initialized.");
rendering_api = &gfx_whb_api;
wm_api = &gfx_sdl;
configFullscreen = true;
#elif defined(ENABLE_DX12)
rendering_api = &gfx_direct3d12_api;
wm_api = &gfx_dxgi_api;
#elif defined(ENABLE_DX11)
Expand All @@ -206,7 +196,6 @@ void main_func(void) {
wm_api->set_fullscreen_changed_callback(on_fullscreen_changed);
wm_api->set_keyboard_callbacks(keyboard_on_key_down, keyboard_on_key_up, keyboard_on_all_keys_up);

#endif

#if HAVE_WASAPI
if (audio_api == NULL && audio_wasapi.init()) {
Expand Down