Mercurial > wgsdk
diff src/main.c @ 0:d91dfd53b8b4
Initial commit
author | Paper <mrpapersonic@gmail.com> |
---|---|
date | Sun, 07 Aug 2022 07:26:27 -0400 |
parents | |
children | 7abb5d8b20ea |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/main.c Sun Aug 07 07:26:27 2022 -0400 @@ -0,0 +1,176 @@ +#include <assert.h> +#include <stdio.h> +#include <stdint.h> +#include <stdlib.h> +#include <time.h> +#include <Winamp/wa_ipc.h> +#include "main.h" +#include "discord_game_sdk.h" +#include "timer.h" +#include "config.h" +#include "dirtools.h" +#ifndef WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN +#endif +#include <windows.h> + +#define CLIENT_ID 969367220599803955 +#define DISCORD_REQUIRE(x) \ + assert(x == DiscordResult_Ok) + +#define GPPHDR_VER 0x10 + +winamp_general_purpose_plugin 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 + NULL, // function name which will be executed on config event + quit, // function name which will be executed on quit event + 0, // handle to Winamp main window, loaded by winamp when this dll is loaded + 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_t config = { + .display_title = 1, + .show_elapsed_time = 1 +}; + +struct DiscordActivity activity = { + .application_id = CLIENT_ID, + .name = "Winamp", + .instance = 0 +}; + +struct IDiscordActivityEvents activities_events; + +struct app_t app; + +void 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)"); + + if (playbackState == 1) { + 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 = dtn - SendMessage(g_plugin.hwndParent, WM_WA_IPC, 0, IPC_GETOUTPUTTIME) / 1000; + } else { + activity.timestamps.start = 0; + } + + char* detailsMessage = calloc(256, sizeof(char)); + //if (g_pluginSettings.DisplayTitleInStatus) + //{ + 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, detailsMessage, 256, NULL, NULL)); + //} + //else + //{ + // strcpy(activity.details, ""); + //} + strcpy(activity.details, detailsMessage); + free(detailsMessage); + + app.activities->update_activity(app.activities, &activity, &app, update_activity_callback); +} + +void report_idle_status(void) +{ + activity.timestamps.start = 0; + strcpy(activity.state, "(Idle)"); + + app.activities->update_activity(app.activities, &activity, &app, update_activity_callback); +} + +void update_rich_presence_details(void) +{ + LONG isPlayingResult = SendMessageW(g_plugin.hwndParent, WM_WA_IPC, 0, IPC_ISPLAYING); + + switch (isPlayingResult) { + case 1: + report_current_song_status(1); + break; + case 3: + report_current_song_status(3); + break; + case 0: + report_idle_status(); + break; + default: break; + } +} + +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) + { + // Notification sent from Winamp on any change in playback. + + update_rich_presence_details(); + } + + return CallWindowProc(g_lpWndProcOld, hwnd, message, wParam, lParam); +} + +int init() { + char* path = dirtools_concat_paths(getenv("APPDATA"), "Winamp\\Plugins\\wgsdk"); + printf("%s", path); + 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)); + + struct DiscordCreateParams params; + DiscordCreateParamsSetDefault(¶ms); + params.client_id = CLIENT_ID; + params.flags = DiscordCreateFlags_Default; + params.event_data = &app; + params.activity_events = &activities_events; + + DISCORD_REQUIRE(DiscordCreate(DISCORD_VERSION, ¶ms, &app.core)); + + app.activities = app.core->get_activity_manager(app.core); + + timer_init(&timer_callbacks, g_plugin.hwndParent, TimerProc); + timer_set(&timer_callbacks, g_plugin.hwndParent); + + cfg_load(&config); + + strcpy(activity.assets.large_image, "winamp-logo"); + + update_rich_presence_details(); + + return 0; +} + +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)); +} + +__declspec(dllexport) winamp_general_purpose_plugin* winampGetGeneralPurposePlugin() { + return &g_plugin; +}