Mercurial > wgsdk
diff src/main.c @ 7:be4835547dd0
clean up code, convert git files to hg, etc.
author | Paper |
---|---|
date | Fri, 16 Dec 2022 20:35:06 -0500 |
parents | 59bf702b2b21 |
children | 42ac054c0231 |
line wrap: on
line diff
--- a/src/main.c Sat Dec 17 01:48:13 2022 +0000 +++ b/src/main.c Fri Dec 16 20:35:06 2022 -0500 @@ -1,12 +1,15 @@ +/** + * wgsdk - Winamp plugin for Discord's GameSDK +**/ #include <assert.h> #include <stdio.h> #include <stdlib.h> #include <Winamp/wa_ipc.h> -#include "main.h" #include "discord_game_sdk.h" #include "timer.h" #include "config.h" #include "resource.h" +#include "utils.h" #ifndef WIN32_LEAN_AND_MEAN # define WIN32_LEAN_AND_MEAN #endif @@ -19,7 +22,22 @@ #define GPPHDR_VER 0x10 -winamp_general_purpose_plugin g_plugin = { +int init(); +void conf(); +void quit(); + +/* Winamp-specific stuff */ +struct winamp_gpp { + int version; // version of the plugin structure + char *description; // name/title of the plugin + int(*init)(); // function which will be executed on init event + void(*conf)(); // function which will be executed on config event + void(*quit)(); // function which will be executed on quit event + HWND hwndParent; // hwnd of the Winamp client main window (stored by Winamp when dll is loaded) + HINSTANCE hDllInstance; // hinstance of this plugin DLL. (stored by Winamp when dll is loaded) +}; + +struct winamp_gpp g_plugin = { GPPHDR_VER, // version of the plugin, defined in "gen_myplugin.h" "Discord GameSDK", // name/title of the plugin, defined in "gen_myplugin.h" init, // function name which will be executed on init event @@ -29,13 +47,7 @@ 0 // hinstance to this dll, loaded by winamp when this dll is loaded }; -WNDPROC g_lpWndProcOld = 0; - -struct timer_t timer_callbacks = { .interval = 16 }; -struct config config = { - .display_title = 1, - .show_elapsed_time = 1 -}; +/* Discord stuff */ struct DiscordActivity activity = { .application_id = CLIENT_ID, @@ -45,40 +57,42 @@ struct IDiscordActivityEvents activities_events; -struct app_t app; +struct application { + struct IDiscordCore* core; + struct IDiscordUsers* users; + struct IDiscordActivityManager* activities; +} app; + +/* Now we get to our built-in stuff */ + +struct timer timer_callbacks = { .interval = 16 }; -void update_activity_callback(void* data, enum EDiscordResult result) -{ +struct config config = { + .display_title = 1, + .show_elapsed_time = 1 +}; + +/* CallWindowProc is the *only* function that ever needs this. */ +WNDPROC _old_wnd_proc = 0; + +/* ------------------------------------ */ + +void DISCORD_CALLBACK update_activity_callback(void* data, enum EDiscordResult result) { DISCORD_REQUIRE(result); } -void report_current_song_status(int playbackState) -{ - assert(playbackState != 0); - activity.timestamps.start = 0; - strcpy(activity.state, playbackState == 1 ? "(Playing)" : "(Paused)"); +void report_current_song_status(int playback_state) { + assert(playback_state != 0); + strcpy(activity.state, playback_state == 1 ? "(Playing)" : "(Paused)"); - if (playbackState == 1 && config.show_elapsed_time) { - FILETIME ft; - GetSystemTimeAsFileTime(&ft); - ULARGE_INTEGER ul; - ul.LowPart = ft.dwLowDateTime; - ul.HighPart = ft.dwHighDateTime; - long long dtn = ((ul.QuadPart - 116444736000000000ULL)/10000000); + activity.timestamps.start = (playback_state == 1 && config.show_elapsed_time) + ? get_system_time_in_milliseconds() - SendMessage(g_plugin.hwndParent, WM_WA_IPC, 0, IPC_GETOUTPUTTIME) / 1000 + : 0; - activity.timestamps.start = dtn - SendMessage(g_plugin.hwndParent, WM_WA_IPC, 0, IPC_GETOUTPUTTIME) / 1000; - } else { - activity.timestamps.start = 0; - } - - char* details_message = calloc(256, sizeof(char)); if (config.display_title) { wchar_t* title = (wchar_t*)SendMessageW(g_plugin.hwndParent, WM_WA_IPC, 0, IPC_GET_PLAYING_TITLE); - assert(WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, title, -1, details_message, 256, NULL, NULL)); - free(title); + assert(WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, title, -1, activity.details, 256, NULL, NULL)); } - strcpy(activity.details, details_message); - free(details_message); app.activities->update_activity(app.activities, &activity, &app, update_activity_callback); } @@ -93,41 +107,43 @@ void update_rich_presence_details(void) { - LONG isPlayingResult = SendMessageW(g_plugin.hwndParent, WM_WA_IPC, 0, IPC_ISPLAYING); + LONG is_playing = SendMessageW(g_plugin.hwndParent, WM_WA_IPC, 0, IPC_ISPLAYING); - switch (isPlayingResult) { + switch (is_playing) { case 0: report_idle_status(); break; case 1: case 3: - report_current_song_status(isPlayingResult); + report_current_song_status(is_playing); default: break; } } -LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) -{ +void CALLBACK TimerProc(HWND, UINT, UINT_PTR, DWORD) { + DISCORD_REQUIRE(app.core->run_callbacks(app.core)); +} + +LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { if (message == WM_WA_IPC && lParam == IPC_CB_MISC && wParam == IPC_CB_MISC_STATUS) - { update_rich_presence_details(); - } - return CallWindowProc(g_lpWndProcOld, hwnd, message, wParam, lParam); + return CallWindowProc(_old_wnd_proc, hwnd, message, wParam, lParam); } +#define set_wnd_long(x) \ + (WNDPROC)SetWindowLong##x(g_plugin.hwndParent, GWLP_WNDPROC, (LONG)WndProc) int init() { memset(&app, 0, sizeof(app)); - if (IsWindowUnicode(g_plugin.hwndParent)) { - g_lpWndProcOld = (WNDPROC)SetWindowLongW(g_plugin.hwndParent, -4, (LONG)WndProc); - } else { - g_lpWndProcOld = (WNDPROC)SetWindowLongA(g_plugin.hwndParent, -4, (LONG)WndProc); - } - memset(&activity, 0, sizeof(activity)); memset(&activities_events, 0, sizeof(activities_events)); + if (IsWindowUnicode(g_plugin.hwndParent)) + _old_wnd_proc = set_wnd_long(W); + else + _old_wnd_proc = set_wnd_long(A); + struct DiscordCreateParams params; DiscordCreateParamsSetDefault(¶ms); params.client_id = CLIENT_ID; @@ -150,20 +166,17 @@ return 0; } +#undef set_wnd_long void quit() { assert(!cfg_save(config)); app.activities->clear_activity(app.activities, &app, update_activity_callback); } -void CALLBACK TimerProc(HWND, UINT, UINT_PTR, DWORD) { - DISCORD_REQUIRE(app.core->run_callbacks(app.core)); -} - void conf() { DialogBoxW(g_plugin.hDllInstance, (LPWSTR)DIALOG_CONFIG, g_plugin.hwndParent, (DLGPROC)cfg_win_proc); } -__declspec(dllexport) winamp_general_purpose_plugin* winampGetGeneralPurposePlugin() { +__declspec(dllexport) struct winamp_gpp* winampGetGeneralPurposePlugin() { return &g_plugin; }