view src/config.c @ 9:07f0e2f43204

*: add the restrict keyword when necessary also fixed some typos in the README
author Paper
date Fri, 16 Dec 2022 21:55:37 -0500
parents be4835547dd0
children 42ac054c0231
line wrap: on
line source

/**
 * config.c:
 *
 * Functions to load/save/edit the config.
**/

/**
 * example config:
 *
 * ----- wgsdk config ----
 * display_title=1
 * show_elapsed_time=1
**/
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "dirtools.h"
#include "config.h"
#include "resource.h"
#include "utils.h"
#ifndef WIN32_LEAN_AND_MEAN
#  define WIN32_LEAN_AND_MEAN
#endif
#include <windows.h>
#include <windowsx.h>
#define MAX_LINE_LENGTH 128

/* from main */
extern void update_rich_presence_details(void);
extern struct config config;

int cfg_load(struct config* restrict config) {
	char line[MAX_LINE_LENGTH] = {0},
	     *path = dirtools_concat_paths(getenv("APPDATA"), "Winamp\\Plugins\\wgsdk\\config.txt");
	FILE* config_fp = fopen(path, "r");
	if (config_fp == NULL) {
		free(path);
		return 1;
	}
	/* parse the config */
	while (fgets(line, MAX_LINE_LENGTH, config_fp)) {
		switch (crc32b((unsigned char*)strtok(line, "="))) {
			case 0x2a666380: // display_title
				config->display_title = !!atoi(strtok(NULL, "="));
				break;
			case 0xbb631f7f: // show_elapsed_time
				config->show_elapsed_time = !!atoi(strtok(NULL, "="));
				break;
			default:
				break;
		}
	}
	free(path);
	return 0;
}

int cfg_save(struct config config) {
	char* path = dirtools_concat_paths(getenv("APPDATA"), "Winamp\\Plugins\\wgsdk");
	assert(!dirtools_create_directory(path));
	free(path);

	path = dirtools_concat_paths(getenv("APPDATA"), "Winamp\\Plugins\\wgsdk\\config.txt");
	FILE* 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;
}

/* --------------------------------- */

#define conf_item_to_dlg(cons, var) \
	checkboxHwnd = GetDlgItem(hWnd, cons); \
	Button_SetCheck(checkboxHwnd, var)
#define dlg_item_to_conf(cons, var) \
	checkboxHwnd = GetDlgItem(hWnd, cons); \
	var = Button_GetCheck(checkboxHwnd)
void cfg_get_controls(HWND hWnd) {
	HWND checkboxHwnd;

	dlg_item_to_conf(TITLE_CHECK,        config.display_title);
	dlg_item_to_conf(ELAPSED_TIME_CHECK, config.show_elapsed_time);
}

void cfg_set_controls(HWND hWnd) {
	HWND checkboxHwnd;

	conf_item_to_dlg(TITLE_CHECK,        config.display_title);
	conf_item_to_dlg(ELAPSED_TIME_CHECK, config.show_elapsed_time);
}
#undef conf_item_to_dlg
#undef dlg_item_to_conf

void cfg_on_confirm_settings_dialog(HWND hWnd) {
	cfg_get_controls(hWnd);
	cfg_save(config);
	update_rich_presence_details();
}

BOOL CALLBACK cfg_win_proc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) {
	switch (msg) {
		case WM_INITDIALOG:
			/* do nothing if this is a child window (tab page) callback, pass to the parent */
			if (GetWindowLong(hWnd, GWL_STYLE) & WS_CHILD)
				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;
				case IDCANCEL:
					EndDialog(hWnd, 0);
					return TRUE;
			}
	}

	return FALSE;
}