diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d1a80d4..97e1e4d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -13,16 +13,15 @@ jobs: steps: - name: Checkout the Git repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Update packages run: bash ./.github/workflows/update.sh - name: Build application run: | - mkdir --parents build - /opt/devkitpro/portlibs/wiiu/bin/powerpc-eabi-cmake -B build - cmake --build build -j $(nproc) + /opt/devkitpro/portlibs/wiiu/bin/powerpc-eabi-cmake -B $GITHUB_WORKSPACE/build + cmake --build $GITHUB_WORKSPACE/build -j $(nproc) - name: Prepare artifact run: | @@ -31,7 +30,7 @@ jobs: mv --verbose build/MiisendU-Wii-U.wuhb artifact/MiisendU-Wii-U/MiisendU-Wii-U.wuhb cp --verbose meta/* artifact/MiisendU-Wii-U - - uses: actions/upload-artifact@v3 + - uses: actions/upload-artifact@v4 with: name: MiisendU-Wii-U path: artifact/ diff --git a/CHANGELOG.md b/CHANGELOG.md index e499127..dae9e69 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,8 +2,9 @@ All notable changes to this project will be documented in this file. -## [Unreleased] +## [1.3.0] - 2024-03-17 +- Send USB Gamecube Controller Adapter button states to UsendMii. - Remove code for emulated buttons. ## [1.2.0] - 2023-05-12 @@ -46,7 +47,7 @@ All notable changes to this project will be documented in this file. - Initial release. -[unreleased]: https://github.com/Crayon2000/MiisendU-Wii-U/compare/v1.2.0...HEAD +[1.3.0]: https://github.com/Crayon2000/MiisendU-Wii-U/compare/v1.2.0...HEAD [1.2.0]: https://github.com/Crayon2000/MiisendU-Wii-U/compare/v1.1.0...v1.2.0 [1.1.0]: https://github.com/Crayon2000/MiisendU-Wii-U/compare/v1.0.0...v1.1.0 [1.0.0]: https://github.com/Crayon2000/MiisendU-Wii-U/compare/v0.3.0...v1.0.0 diff --git a/README.md b/README.md index 3ff4cf0..fe0efa9 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,6 @@ Prerequisites: To compile: ```bash -mkdir --parents build /opt/devkitpro/portlibs/wiiu/bin/powerpc-eabi-cmake -B build cmake --build build ``` diff --git a/meta/meta.xml b/meta/meta.xml index ed9fe0b..68e2e59 100644 --- a/meta/meta.xml +++ b/meta/meta.xml @@ -2,8 +2,8 @@ MiisendU Wii U Crayon - 1.2.0 - 20230512000000 + 1.3.0 + 20240317000000 A UsendMii client A UsendMii client for Wii U. diff --git a/source/main.c b/source/main.c index 39b4ec7..25de1d9 100644 --- a/source/main.c +++ b/source/main.c @@ -62,7 +62,7 @@ static void PrintHeader(OSScreenID bufferNum) OSScreenPutFontEx(bufferNum, -4, 0, " __ __ _ _ _ _ _ __ ___ _ _ _ "); OSScreenPutFontEx(bufferNum, -4, 1, "| \\/ (_|_)___ ___ _ _ __| | | | | \\ \\ / (_|_) | | | |"); OSScreenPutFontEx(bufferNum, -4, 2, "| |\\/| | | (_-= 0) + { + pad_data.hpad[0] = &hpad_data1[0]; + } + if(hpad_error2 >= 0) + { + pad_data.hpad[1] = &hpad_data2[0]; + } + if(hpad_error3 >= 0) + { + pad_data.hpad[2] = &hpad_data3[0]; + } + if(hpad_error4 >= 0) + { + pad_data.hpad[3] = &hpad_data4[0]; + } pad_to_json(pad_data, msg_data, sizeof(msg_data)); // Send the message @@ -315,6 +342,9 @@ int main(int argc, char **argv) } free(IP_ADDRESS); + VPADShutdown(); + KPADShutdown(); + HPADShutdown(); WHBUnmountSdCard(); ConsoleFree(); WHBProcShutdown(); diff --git a/source/vpad_to_json.cpp b/source/vpad_to_json.cpp index b5fb2f6..de4a895 100644 --- a/source/vpad_to_json.cpp +++ b/source/vpad_to_json.cpp @@ -1,7 +1,34 @@ #include #include +#include #include "vpad_to_json.h" +/** + * Mask for the Gamecube Controller. + */ +static const std::map gcmask = { + std::pair{HPAD_BUTTON_LEFT, 0x0001}, + {HPAD_BUTTON_RIGHT, 0x0002}, + {HPAD_BUTTON_DOWN, 0x0004}, + {HPAD_BUTTON_UP, 0x0008}, + {HPAD_TRIGGER_Z, 0x0010}, + {HPAD_TRIGGER_R, 0x0020}, + {HPAD_TRIGGER_L, 0x0040}, + {HPAD_BUTTON_A, 0x0100}, + {HPAD_BUTTON_B, 0x0200}, + {HPAD_BUTTON_X, 0x0400}, + {HPAD_BUTTON_Y, 0x0800}, + {HPAD_BUTTON_START, 0x1000}, +}; + +/** + * Change the range. + */ +[[nodiscard]] static constexpr int change_range(int value, int oldMin, int oldMax, int newMin, int newMax) +{ + return static_cast((static_cast(value - oldMin) / (oldMax - oldMin)) * (newMax - newMin) + newMin); +} + /** * Convert GamePad data to JSON string used by UsendMii. * @param[in] pad_data Controllers data. @@ -48,16 +75,16 @@ void pad_to_json(PADData pad_data, char* out, uint32_t out_size) json_object_set_new_nocheck(wiiugamepad, "dirZz", json_real(pad_data.vpad->direction.z.z)); // Wii Remotes / Wii U Pro Controllers - if(pad_data.kpad[0] != NULL || - pad_data.kpad[1] != NULL || - pad_data.kpad[2] != NULL || - pad_data.kpad[3] != NULL) + if(pad_data.kpad[0] != nullptr || + pad_data.kpad[1] != nullptr || + pad_data.kpad[2] != nullptr || + pad_data.kpad[3] != nullptr) { json_t *wiiremotes = json_array(); json_t *wiiuprocontrollers = json_array(); for(int i = 0; i < 4; ++i) { - if(pad_data.kpad[i] != NULL) + if(pad_data.kpad[i] != nullptr) { if(pad_data.kpad[i]->extensionType != WPAD_EXT_PRO_CONTROLLER) { // Wii Remote with or without an extension @@ -132,6 +159,55 @@ void pad_to_json(PADData pad_data, char* out, uint32_t out_size) } } + // USB Gamecube Controller Adapter + if(pad_data.hpad[0] != nullptr || + pad_data.hpad[1] != nullptr || + pad_data.hpad[2] != nullptr || + pad_data.hpad[3] != nullptr) + { + json_t *gccontrollers = json_array(); + for(int i = 0; i < 4; ++i) + { + if(pad_data.hpad[i] == nullptr) + { + continue; + } + int32_t holdgc = 0; + const int32_t badgc = pad_data.hpad[i]->hold; + for (auto const& [oldid, newid] : gcmask) + { + if(badgc & oldid) { + holdgc |= newid; + } + } + + json_t *gccontroller = json_object(); + json_object_set_new_nocheck(gccontroller, "order", json_integer(i + 1)); + json_object_set_new_nocheck(gccontroller, "hold", json_integer(holdgc)); + json_object_set_new_nocheck(gccontroller, "ctrlStickX", json_integer( + change_range(pad_data.hpad[i]->stickX, HPAD_STICK_AXIS_MIN, HPAD_STICK_AXIS_MAX, -128, 127))); + json_object_set_new_nocheck(gccontroller, "ctrlStickY", json_integer( + change_range(pad_data.hpad[i]->stickY, HPAD_STICK_AXIS_MIN, HPAD_STICK_AXIS_MAX, -128, 127))); + json_object_set_new_nocheck(gccontroller, "cStickX", json_integer( + change_range(pad_data.hpad[i]->substickX, HPAD_SUBSTICK_AXIS_MIN, HPAD_SUBSTICK_AXIS_MAX, -128, 127))); + json_object_set_new_nocheck(gccontroller, "cStickY", json_integer( + change_range(pad_data.hpad[i]->substickY, HPAD_SUBSTICK_AXIS_MIN, HPAD_SUBSTICK_AXIS_MAX, -128, 127))); + json_object_set_new_nocheck(gccontroller, "lTrigger", json_integer( + change_range(pad_data.hpad[i]->triggerL, HPAD_TRIGGER_MIN, HPAD_TRIGGER_MAX, 0, 255))); + json_object_set_new_nocheck(gccontroller, "rTrigger", json_integer( + change_range(pad_data.hpad[i]->triggerR, HPAD_TRIGGER_MIN, HPAD_TRIGGER_MAX, 0, 255))); + json_array_append(gccontrollers, gccontroller); + } + if(json_array_size(gccontrollers) > 0) + { + json_object_set_new_nocheck(root, "gameCubeControllers", gccontrollers); + } + else + { + json_delete(gccontrollers); + } + } + // Convert to string char* s = json_dumps(root, JSON_COMPACT | JSON_REAL_PRECISION(10)); strncpy(out, s, out_size); diff --git a/source/vpad_to_json.h b/source/vpad_to_json.h index a04f797..b32374a 100644 --- a/source/vpad_to_json.h +++ b/source/vpad_to_json.h @@ -4,6 +4,7 @@ #include #include #include +#include #ifdef __cplusplus extern "C" { @@ -15,6 +16,7 @@ extern "C" { typedef struct { VPADStatus* vpad; /**< Wii U Gamepad. */ KPADStatus* kpad[4]; /**< Wii Remotes. */ + HPADStatus* hpad[4]; /**< USB Gamecube Controller Adapter. */ } PADData; void pad_to_json(PADData pad_data, char* out, uint32_t out_size);