Mercurial > wgsdk
view src/config.c @ 10:42ac054c0231
*: huge refactoring
dirtools now uses wchar (wayyy overdue)
the timer doesn't have a stupid design anymore
we don't use windows.h at all now
...
author | Paper <paper@paper.us.eu.org> |
---|---|
date | Sun, 11 Feb 2024 19:43:31 -0500 |
parents | 07f0e2f43204 |
children | e6a594f16403 |
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 "dirtools.h" #include "config.h" #include "resource.h" #include "utils.h" #include <shlobj.h> #include <shlwapi.h> #include <assert.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #define MAX_LINE_LENGTH 256 /* from main */ extern void update_rich_presence_details(void); extern struct config config; /* must be free'd by the caller */ LPWSTR cfg_get_path() { /* get location of appdata folder */ LPWSTR appdata_folder; SHGetKnownFolderPath(&FOLDERID_RoamingAppData, 0, NULL, &appdata_folder); /* compatibility with WACUP, falls back to Winamp */ WCHAR exe_name[MAX_PATH] = {L'\0'}; if (GetModuleFileNameW(NULL, (LPWSTR)&exe_name, MAX_PATH)) { PathStripPathW(exe_name); PathRemoveExtensionW(exe_name); } else { // fail memset(exe_name, '\0', MAX_PATH * sizeof(WCHAR)); wcscpy(exe_name, L"Winamp"); } /* concat until we get the final path */ LPWSTR path = dirtools_concat_paths(appdata_folder, exe_name); CoTaskMemFree(appdata_folder); LPWSTR final = dirtools_concat_paths(path, L"Plugins\\wgsdk"); free(path); return final; } int cfg_load(struct config* restrict config) { LPWSTR fold_path = cfg_get_path(); LPWSTR path = dirtools_concat_paths(fold_path, L"config.txt"); free(fold_path); /* find some real win32 replacement for this */ FILE* config_fp = _wfopen(path, L"r"); if (config_fp == NULL) { free(path); return 1; } /* parse the config */ char line[MAX_LINE_LENGTH] = {0}; while (fgets(line, MAX_LINE_LENGTH, config_fp)) { /* strtok is okay here. */ 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) { LPWSTR fold_path = cfg_get_path(); assert(!dirtools_create_directory(fold_path)); LPWSTR path = dirtools_concat_paths(fold_path, L"config.txt"); free(fold_path); FILE* config_fp = _wfopen(path, L"w"); if (config_fp == NULL) { free(path); 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); free(path); return 0; } /* --------------------------------- */ #define conf_item_to_dlg(hwnd, cons, var) \ { \ HWND checkboxHwnd = GetDlgItem(hwnd, cons); \ SendMessage(checkboxHwnd, BM_SETCHECK, (var) ? BST_CHECKED : BST_UNCHECKED, 0); \ } #define dlg_item_to_conf(hwnd, cons, var) \ { \ HWND checkboxHwnd = GetDlgItem(hwnd, cons); \ (var) = (SendMessage(checkboxHwnd, BM_GETCHECK, 0, 0) == BST_CHECKED); \ } void cfg_get_controls(HWND hWnd) { dlg_item_to_conf(hWnd, TITLE_CHECK, config.display_title); dlg_item_to_conf(hWnd, ELAPSED_TIME_CHECK, config.show_elapsed_time); } void cfg_set_controls(HWND hWnd) { conf_item_to_dlg(hWnd, TITLE_CHECK, config.display_title); conf_item_to_dlg(hWnd, 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; }