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(&params);
 	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;
 }