changeset 1:7abb5d8b20ea v1.0

Initial commit: part 2 I added a config GUI, and actual stuff to the README. The GUI was 'made' in Visual Studio, but I trimmed down the resource file because it had weird VS2010 skid marks all over it.
author Paper <mrpapersonic@gmail.com>
date Sun, 07 Aug 2022 10:23:10 -0400
parents d91dfd53b8b4
children 712c7fd6702a
files Makefile README.md src/config.c src/dirtools.c src/include/config.h src/include/dialog.rc src/include/main.h src/include/resource.h src/main.c src/timer.c
diffstat 10 files changed, 214 insertions(+), 37 deletions(-) [+]
line wrap: on
line diff
--- a/Makefile	Sun Aug 07 07:26:27 2022 -0400
+++ b/Makefile	Sun Aug 07 10:23:10 2022 -0400
@@ -1,4 +1,4 @@
-CFLAGS=-Wall -mdll -Isrc/include -I"discord_game_sdk/c"
+CFLAGS=-Wall -O2 -mdll -Isrc/include -I"discord_game_sdk/c"
 ifeq ($(PROCESSOR_ARCHITECTURE),x86)
 	ifeq ($(PROCESSOR_ARCHITEW6432),x86)
 		CFLAGS += -I"/c/Program Files/Winamp SDK" 
@@ -9,14 +9,19 @@
 	CFLAGS += -I"/c/Program Files (x86)/Winamp SDK"
 endif
 LDFLAGS=-L"discord_game_sdk/lib/x86" -ldiscord_game_sdk
-DEPS=src/include/config.h src/include/dirtools.h src/include/main.h src/include/timer.h
+DEPS=src/include/config.h src/include/dirtools.h src/include/main.h \
+     src/include/timer.h src/include/resource.h
+RC=src/include/dialog.rc
 OBJ=src/config.o src/dirtools.o src/main.o src/timer.o
 
+gen_DiscordGameSDK.dll: $(OBJ) src/include/dialog.o
+	gcc -o $@ $(CFLAGS) $^ $(LDFLAGS)
+
+src/include/dialog.o: src/include/dialog.rc
+	windres -i $< -o $@
+
 src/%.o: src/%.c $(DEPS)
 	gcc -c $(CFLAGS) $< -o $@
 
-gen_DiscordGameSDK.dll: $(OBJ)
-	gcc -o $@ $(CFLAGS) $^ $(LDFLAGS)
-
 clean:
 	rm -f src/*.o *.dll
\ No newline at end of file
--- a/README.md	Sun Aug 07 07:26:27 2022 -0400
+++ b/README.md	Sun Aug 07 10:23:10 2022 -0400
@@ -1,3 +1,34 @@
 # Discord GameSDK Winamp Plugin
 
-This plugin (largely based off of clandrew's [wdrp](https://github.com/clandrew/wdrp))
\ No newline at end of file
+This plugin is largely based off of clandrew's [wdrp](https://github.com/clandrew/wdrp). You can look at the screenshots in that repository, it looks pretty much identical.
+
+### Installing
+You'll want to put gen_DiscordGameSDK.dll into Plugins directory, and discord_game_sdk into the Winamp directory.
+
+### Configuration
+The config file is located at `%AppData%\Roaming\Winamp\Plugins\wgsdk\config.txt`. It's pretty straightforward how to edit it.
+
+### Differences to wdrp
+* uses GameSDK (obviously)
+* written in C instead of C++
+* uses GNU make instead of Visual Studio
+* several other coding differences (e.g. there's no classes in C)
+
+### How to compile
+(Disclaimer: This guide is written for Windows users.)
+
+First of all, you want to install the [Winamp SDK](http://forums.winamp.com/showthread.php?t=252090). Now you just need the [Discord GameSDK](https://discord.com/developers/docs/game-sdk/sdk-starter-guide#step-1-get-the-thing).
+
+Then, make sure the repository directory structure looks like this:
+
+```
+C:.
+├───discord_game_sdk
+│   ├───c
+│   ├───cpp
+│   └───...
+└───src
+    └───include
+```
+
+Now, just run `make`. If you have all the build tools properly installed it should work.
--- a/src/config.c	Sun Aug 07 07:26:27 2022 -0400
+++ b/src/config.c	Sun Aug 07 10:23:10 2022 -0400
@@ -4,12 +4,17 @@
 #include <string.h>
 #include "dirtools.h"
 #include "config.h"
+#include "main.h"
+#include "resource.h"
 #ifndef WIN32_LEAN_AND_MEAN
 #  define WIN32_LEAN_AND_MEAN
 #endif
 #include <windows.h>
+#include <windowsx.h>
 #define MAX_LINE_LENGTH 128
 
+extern struct config_t config; // from main
+
 static unsigned int crc32b(unsigned char *message) {
    int i, j;
    unsigned int byte, crc, mask;
@@ -29,10 +34,9 @@
 }
 
 int cfg_load(struct config_t* config) {
-	char* path = NULL;
-	char line[MAX_LINE_LENGTH] = {0};
+	char line[MAX_LINE_LENGTH] = {0}, 
+	     *path = dirtools_concat_paths(getenv("APPDATA"), "Winamp\\Plugins\\wgsdk\\config.txt");
 	FILE* config_fp;
-	path = dirtools_concat_paths(getenv("APPDATA"), "Winamp\\Plugins\\wgsdk\\config.txt");
 	config_fp = fopen(path, "r");
 	if (config_fp == NULL) {
 		free(path);
@@ -41,10 +45,10 @@
 	while (fgets(line, MAX_LINE_LENGTH, config_fp)) {
 		switch (crc32b((unsigned char*)strtok(line, "="))) {
 			case 0x2a666380: // display_title
-				config->display_title = atoi(strtok(NULL, "="));
+				config->display_title = !!atoi(strtok(NULL, "="));
 				break;
 			case 0xbb631f7f: // show_elapsed_time
-				config->show_elapsed_time = atoi(strtok(NULL, "="));
+				config->show_elapsed_time = !!atoi(strtok(NULL, "="));
 				break;
 			default:
 				break;
@@ -55,18 +59,75 @@
 }
 
 int cfg_save(struct config_t config) {
-	char* path = NULL;
+	char* path = dirtools_concat_paths(getenv("APPDATA"), "Winamp\\Plugins\\wgsdk");
 	FILE* config_fp;
-	path = dirtools_concat_paths(getenv("APPDATA"), "Winamp\\Plugins\\wgsdk");
-	assert(dirtools_create_directory(path));
+	assert(!dirtools_create_directory(path));
 	free(path);
 	path = dirtools_concat_paths(getenv("APPDATA"), "Winamp\\Plugins\\wgsdk\\config.txt");
 	config_fp = fopen(path, "w");
 	if (config_fp == NULL) {
 		return 1;
 	}
+	fprintf(config_fp, "----- wgsdk config ----\n");
 	fprintf(config_fp, "display_title=%d\n", config.display_title);
 	fprintf(config_fp, "show_elapsed_time=%d\n", config.show_elapsed_time);
 	fclose(config_fp);
 	return 0;
 }
+
+/* --------------------------------- */
+
+void cfg_dialog_to_struct(HWND hWnd) {
+	HWND checkboxHwnd = GetDlgItem(hWnd, TITLE_CHECK);
+	config.display_title = Button_GetCheck(checkboxHwnd);
+
+	checkboxHwnd = GetDlgItem(hWnd, ELAPSED_TIME_CHECK);
+	config.show_elapsed_time = Button_GetCheck(checkboxHwnd);
+}
+
+void cfg_on_confirm_settings_dialog(HWND hWnd)
+{
+    cfg_dialog_to_struct(hWnd);
+    cfg_save(config);
+	update_rich_presence_details();
+}
+
+void cfg_set_controls(HWND hWnd) {
+	HWND checkboxHwnd = GetDlgItem(hWnd, TITLE_CHECK);
+	Button_SetCheck(checkboxHwnd, config.display_title);
+
+	checkboxHwnd = GetDlgItem(hWnd, ELAPSED_TIME_CHECK);
+	Button_SetCheck(checkboxHwnd, config.show_elapsed_time);
+}
+
+BOOL CALLBACK cfg_win_proc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) {
+	switch (msg) {
+		case WM_INITDIALOG: {
+			if (GetWindowLong(hWnd, GWL_STYLE) & WS_CHILD)
+			{
+				// do nothing if this is a child window (tab page) callback, pass to the parent
+				return FALSE;
+			}
+
+			cfg_set_controls(hWnd);
+			return TRUE;
+		}
+
+		case WM_COMMAND:
+			switch (LOWORD(wParam)) {
+				case IDOK: {
+					cfg_on_confirm_settings_dialog(hWnd);
+					EndDialog(hWnd, 0);
+					return TRUE;
+					break;
+				}
+				case IDCANCEL: {
+					EndDialog(hWnd, 0);
+					return TRUE;
+					break;
+				}
+			}
+	}
+
+    return FALSE;
+}
--- a/src/dirtools.c	Sun Aug 07 07:26:27 2022 -0400
+++ b/src/dirtools.c	Sun Aug 07 10:23:10 2022 -0400
@@ -15,10 +15,17 @@
 	for (tok = strtok(path, "\\"); tok != NULL; tok = strtok(NULL, "\\")) {
 		strcat(alltoks, tok);
 		if (stat(alltoks, &st) == -1) {
-			CreateDirectoryA(alltoks, NULL);
+			if (!CreateDirectoryA(alltoks, NULL)) {
+				if (GetLastError() == ERROR_PATH_NOT_FOUND) {
+					/* ERROR_PATH_NOT_FOUND should NOT happen here */
+					return 1;
+				}
+			}
 		}
 	}
 
+	free(alltoks);
+
 	return 0;
 }
 
--- a/src/include/config.h	Sun Aug 07 07:26:27 2022 -0400
+++ b/src/include/config.h	Sun Aug 07 10:23:10 2022 -0400
@@ -1,5 +1,9 @@
 #ifndef __config_h
 #define __config_h
+#ifndef WIN32_LEAN_AND_MEAN
+#  define WIN32_LEAN_AND_MEAN
+#endif
+#include <windows.h>
 struct config_t {
 	int display_title;
 	int show_elapsed_time;
@@ -7,4 +11,5 @@
 
 int cfg_load(struct config_t* config);
 int cfg_save(struct config_t config);
+BOOL CALLBACK cfg_win_proc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
 #endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/include/dialog.rc	Sun Aug 07 10:23:10 2022 -0400
@@ -0,0 +1,52 @@
+#include "resource.h"
+#include "winres.h"
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+
+#ifdef APSTUDIO_INVOKED
+
+1 TEXTINCLUDE 
+BEGIN
+    "resource.h\0"
+END
+
+2 TEXTINCLUDE 
+BEGIN
+    "\0"
+END
+
+3 TEXTINCLUDE 
+BEGIN
+    "\r\n"
+    "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+DIALOG_CONFIG DIALOGEX 0, 0, 262, 71
+STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "GameSDK Config"
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+    DEFPUSHBUTTON   "OK",IDOK,149,50,50,14
+    PUSHBUTTON      "Cancel",IDCANCEL,205,50,50,14
+    CONTROL         "Show title in details",TITLE_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,7,77,10
+    CONTROL         "Show elapsed time in presence",ELAPSED_TIME_CHECK,
+                    "Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,20,114,10
+END
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO
+BEGIN
+    DIALOG_CONFIG, DIALOG
+    BEGIN
+        LEFTMARGIN, 7
+        RIGHTMARGIN, 255
+        TOPMARGIN, 7
+        BOTTOMMARGIN, 64
+    END
+END
+#endif    // APSTUDIO_INVOKED
+
+#endif
--- a/src/include/main.h	Sun Aug 07 07:26:27 2022 -0400
+++ b/src/include/main.h	Sun Aug 07 10:23:10 2022 -0400
@@ -9,7 +9,7 @@
     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(*config)();              // function which will be executed on config 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) 
@@ -23,5 +23,7 @@
 
 void CALLBACK TimerProc(HWND, UINT, UINT_PTR, DWORD);
 int init();
+void conf();
 void quit();
+void update_rich_presence_details(void);
 #endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/include/resource.h	Sun Aug 07 10:23:10 2022 -0400
@@ -0,0 +1,12 @@
+#define DIALOG_CONFIG                   101
+#define TITLE_CHECK                     1000
+#define ELAPSED_TIME_CHECK              1001
+
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE        102
+#define _APS_NEXT_COMMAND_VALUE         40001
+#define _APS_NEXT_CONTROL_VALUE         1002
+#define _APS_NEXT_SYMED_VALUE           101
+#endif
+#endif
--- a/src/main.c	Sun Aug 07 07:26:27 2022 -0400
+++ b/src/main.c	Sun Aug 07 10:23:10 2022 -0400
@@ -9,10 +9,12 @@
 #include "timer.h"
 #include "config.h"
 #include "dirtools.h"
+#include "resource.h"
 #ifndef WIN32_LEAN_AND_MEAN
 # define WIN32_LEAN_AND_MEAN
 #endif
 #include <windows.h>
+#include <windowsx.h>
 
 #define CLIENT_ID 969367220599803955
 #define DISCORD_REQUIRE(x) \
@@ -21,13 +23,13 @@
 #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
+	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
+	conf,      // 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;
@@ -50,7 +52,7 @@
 
 void update_activity_callback(void* data, enum EDiscordResult result)
 {
-    DISCORD_REQUIRE(result);
+	DISCORD_REQUIRE(result);
 }
 
 void report_current_song_status(int playbackState)
@@ -59,29 +61,26 @@
 	activity.timestamps.start = 0;
 	strcpy(activity.state, playbackState == 1 ? "(Playing)" : "(Paused)");
 
-	if (playbackState == 1) {
+	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 = 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)
-    //{
+	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, detailsMessage, 256, NULL, NULL));
-    //}
-    //else
-    //{
-    //    strcpy(activity.details, "");
-    //}
+	} else {
+		strcpy(activity.details, "");
+	}
 	strcpy(activity.details, detailsMessage);
 	free(detailsMessage);
 
@@ -118,8 +117,6 @@
 {
 	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();
     }
 
@@ -132,12 +129,12 @@
 	memset(&app, 0, sizeof(app));
 	if (IsWindowUnicode(g_plugin.hwndParent)) {
 		g_lpWndProcOld = (WNDPROC)SetWindowLongW(g_plugin.hwndParent, -4, (LONG)WndProc);
-    } else {
+	} else {
 		g_lpWndProcOld = (WNDPROC)SetWindowLongA(g_plugin.hwndParent, -4, (LONG)WndProc);
 	}
 
 	memset(&activity, 0, sizeof(activity));
-    memset(&activities_events, 0, sizeof(activities_events));
+	memset(&activities_events, 0, sizeof(activities_events));
 
 	struct DiscordCreateParams params;
 	DiscordCreateParamsSetDefault(&params);
@@ -171,6 +168,10 @@
 	DISCORD_REQUIRE(app.core->run_callbacks(app.core));
 }
 
+void conf() {
+	DialogBoxW(g_plugin.hDllInstance, (LPWSTR)DIALOG_CONFIG, g_plugin.hwndParent, &cfg_win_proc);
+}
+
 __declspec(dllexport) winamp_general_purpose_plugin* winampGetGeneralPurposePlugin() {
 	return &g_plugin;
 }
--- a/src/timer.c	Sun Aug 07 07:26:27 2022 -0400
+++ b/src/timer.c	Sun Aug 07 10:23:10 2022 -0400
@@ -4,6 +4,7 @@
 #endif
 #include <windows.h>
 #include "timer.h"
+
 void timer_init(struct timer_t* timer, HWND winampClientWindow, TIMERPROC timer_proc) {
 	timer->winampClientWindow = winampClientWindow;
 	timer->timer_proc = timer_proc;