/* * Copyright (c) 2002-2023 Julien Nadeau Carriere * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * A "GUI Preferences" dialog for application-global Agar settings. */ #include #ifdef AG_WIDGETS #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* * CPU-specific architecture extension names. */ AG_FlagDescrRO agArchExtnNames[] = { { AG_EXT_CPUID, N_(AGSI_CODE "CPUID" AGSI_RST " Instruction") }, { AG_EXT_MMX, "MMX" }, { AG_EXT_MMX_EXT, N_("MMX + AMD extensions") }, { AG_EXT_3DNOW, "3dNow!" }, { AG_EXT_3DNOW_EXT, N_("3dNow! + extensions") }, { AG_EXT_3DNOW_PREFETCH, "3dNow! " AGSI_CODE "PREFETCH" }, { AG_EXT_ALTIVEC, "AltiVec" }, { AG_EXT_SSE, "SSE" }, { AG_EXT_SSE2, "SSE2" }, { AG_EXT_SSE3, "SSE3" }, { AG_EXT_SSSE3, "SSSE3" }, { AG_EXT_SSE4A, "SSE4a" }, { AG_EXT_SSE41, "SSE41" }, { AG_EXT_SSE42, "SSE42" }, { AG_EXT_SSE5A, "SSE5a" }, { AG_EXT_SSE_MISALIGNED, N_("Misaligned SSE Mode") }, { AG_EXT_LONG_MODE, N_("Long Mode") }, { AG_EXT_RDTSCP, N_(AGSI_CODE "RDTSCP" AGSI_RST " Instruction") }, { AG_EXT_FXSR, "FXSR" }, { AG_EXT_PAGE_NX, "PAGE_NX (W^X)" }, { AG_EXT_ONCHIP_FPU, N_("On-chip FPU") }, { AG_EXT_TSC, N_("Time Stamp Counter") }, { AG_EXT_CMOV, N_("Conditional Move") }, { AG_EXT_CLFLUSH, N_("Cache-Line Flush") }, { AG_EXT_HTT, N_("Hyper-Threading Technology") }, { AG_EXT_MON, N_(AGSI_CODE "MONITOR/MWAIT" AGSI_RST " Instructions") }, { AG_EXT_VMX, N_("Virtual Machine Extensions") }, { 0, NULL } }; static AG_Font *agConfigSelectedFont = NULL; static void SaveConfig(AG_Event *_Nonnull event) { if (AG_ObjectSave(agConfig) == -1) { AG_TextMsgFromError(); } else { #ifdef AG_TIMERS AG_TextTmsg(AG_MSG_INFO, 750, _("Configuration settings saved successfully.")); #endif } } static void SetDefaultFont(AG_Event *event) { if (agConfigSelectedFont == NULL) { return; } AG_SetDefaultFont(agConfigSelectedFont); if (AG_ConfigSave() == 0) { AG_TextTmsg(AG_MSG_INFO, 1000, "Default font has changed."); } else { AG_TextMsgFromError(); } } #ifdef HAVE_SDL2 static void PollJoysticks(AG_Event *_Nonnull event) { AG_Tlist *tl = AG_TLIST_SELF(); const int nJoysticks = SDL_NumJoysticks(); int i; AG_TlistBegin(tl); for (i = 0; i < nJoysticks; i++) { AG_TlistItem *it; if (SDL_IsGameController(i)) { const char *name = SDL_GameControllerNameForIndex(i); it = AG_TlistAdd(tl, NULL, AGSI_IDEOGRAM AGSI_GAME_CONTROLLER AGSI_RST " %d) %s", i, name); } else { const char *name = SDL_JoystickNameForIndex(i); it = AG_TlistAdd(tl, NULL, AGSI_IDEOGRAM AGSI_JOYSTICK AGSI_RST " %d) %s", i, name); } it->p1 = NULL; } if (nJoysticks == 0) { AG_TlistAddS(tl, NULL, _("(no controllers detected)")); } AG_TlistEnd(tl); } #endif /* HAVE_SDL2 */ static void ExpandArchExts(AG_Event *_Nonnull event) { AG_UCombo *com = AG_UCOMBO_SELF(); AG_Tlist *tl = com->list; AG_FlagDescrRO *fd; for (fd = &agArchExtnNames[0]; fd->bitmask != 0; fd++) { if (agCPU.ext & fd->bitmask) AG_TlistAddS(tl, NULL, _(fd->descr)); } } static void SelectedArchExt(AG_Event *_Nonnull event) { AG_UCombo *com = AG_UCOMBO_SELF(); AG_ButtonText(com->button, _("Extensions...")); } /* * Configuration dialog for general Agar settings. */ static AG_Window *_Nullable AG_DEV_ConfigWindow(AG_Config *_Nullable cfg) { AG_Window *win; AG_Box *box; AG_Notebook *nb; AG_NotebookTab *tab; const AG_Driver *drv; AG_Checkbox *cb; if ((win = AG_WindowNewNamedS(0, "DEV_Config")) == NULL) { return (NULL); } drv = AGWIDGET(win)->drv; AG_WindowSetCaptionS(win, _("GUI Preferences")); AG_WindowSetCloseAction(win, AG_WINDOW_DETACH); AG_SetPadding(win, "5"); nb = AG_NotebookNew(win, AG_NOTEBOOK_EXPAND); tab = AG_NotebookAdd(nb, _(AGSI_IDEOGRAM AGSI_AGAR_AG AGSI_RST " Settings"), AG_BOX_VERT); AG_SetPadding(tab, "8"); { AG_Box *boxCPU; AG_UCombo *com; char iconText[16]; Uint32 uch[2]; /* * Agar Driver. */ uch[0] = AGOBJECT_CLASS(drv)->ver.unicode; uch[1] = '\0'; if (AG_ExportUnicode("UTF-8", iconText, uch, sizeof(iconText)) == -1) { iconText[0] = '\0'; } AG_LabelNew(tab, AG_LABEL_HFILL, _("Driver: " AGSI_IDEOGRAM "%s" AGSI_RST AGSI_MONOALGUE "%s" AGSI_RST " (%d bpp%s%s)."), iconText, OBJECT_CLASS(drv)->name, (drv->videoFmt) ? drv->videoFmt->BitsPerPixel : 32, (AGDRIVER_CLASS(drv)->flags & AG_DRIVER_SDL) ? ", " AGSI_IDEOGRAM AGSI_SDL AGSI_RST : "", (AGDRIVER_CLASS(drv)->flags & AG_DRIVER_OPENGL) ? ", " AGSI_IDEOGRAM AGSI_OPENGL AGSI_RST : ""); /* * CPU Architecture. */ boxCPU = AG_BoxNewHoriz(tab, 0); AG_SetPadding(boxCPU, 0); { if (agCPU.icon != 0) { uch[0] = agCPU.icon; uch[1] = '\0'; if (AG_ExportUnicode("UTF-8", iconText, uch, sizeof(iconText)) == -1) { iconText[0] = '\0'; } AG_LabelNew(boxCPU, AG_LABEL_HFILL, _("Platform: " AGSI_LEAGUE_SPARTAN " %s " AGSI_RST AGSI_IDEOGRAM "%s" AGSI_RST AGSI_ITALIC "\"%s\"" AGSI_RST), (agCPU.arch[0] != '\0') ? agCPU.arch : _("Unknown"), iconText, agCPU.vendorID); } else { AG_LabelNew(boxCPU, 0, _("Platform: " AGSI_LEAGUE_SPARTAN "%s " AGSI_RST AGSI_ITALIC "\"%s\"" AGSI_RST), (agCPU.arch[0]!='\0') ? agCPU.arch : _("Unknown"), agCPU.vendorID); } com = AG_UComboNew(boxCPU, 0); AG_SetEvent(com, "ucombo-expanded", ExpandArchExts, NULL); AG_SetEvent(com, "ucombo-selected", SelectedArchExt, NULL); AG_ButtonTextS(com->button, _("Extensions...")); } AG_SeparatorNewHoriz(tab); cb = AG_CheckboxNewInt(tab, 0, _("Enable Clipboard Integration"), &agClipboardIntegration); AG_WidgetFocus(cb); if (AGDRIVER_CLASS(drv)->flags & AG_DRIVER_OPENGL) { AG_CheckboxNewInt(tab, 0, _("Enable " AGSI_CODE "GL_DEBUG_OUTPUT" AGSI_RST), &agGLdebugOutput); cb = AG_CheckboxNewInt(tab, 0, _("Enable Stereo Vision"), &agStereo); AG_WidgetDisable(cb); cb = AG_CheckboxNewInt(tab, 0, _("Use Non-Power-Of-Two Textures"), &agGLuseNPOT); #ifndef ENABLE_GL_NO_NPOT AG_WidgetDisable(cb); #endif } #ifdef AG_DEBUG { const char *debugLvlNames[] = { N_("0) No Debugging"), N_("1) Debug Objects"), N_("2) Debug Variables"), NULL }; if (OBJECT(drv)->cid == AGC_DRIVER_GLX) { cb = AG_CheckboxNewInt(tab, 0, _("Use Synchronous X Events"), &agXsync); AG_WidgetDisable(cb); } AG_SeparatorNewHoriz(tab); AG_LabelNewS(tab, 0, _("Debug Level:")); AG_RadioNewInt(tab, 0, _(debugLvlNames), &agDebugLvl); } #endif } tab = AG_NotebookAdd(nb, _(AGSI_IDEOGRAM AGSI_TYPOGRAPHY AGSI_RST " Font"), AG_BOX_VERT); { AG_FontSelector *fs; fs = AG_FontSelectorNew(tab, AG_FONTSELECTOR_EXPAND); agConfigSelectedFont = agDefaultFont; AG_BindPointer(fs, "font", (void *)&agConfigSelectedFont); (void)fs; box = AG_BoxNewHoriz(tab, AG_BOX_HFILL | AG_BOX_HOMOGENOUS); AG_ButtonNewFn(box, 0, _("Set As Default Font"), SetDefaultFont,NULL); } tab = AG_NotebookAdd(nb, _(AGSI_IDEOGRAM AGSI_KEYBOARD_KEY AGSI_RST " Keyboard"), AG_BOX_VERT); { AG_SetPadding(tab, "8"); AG_NumericalNewIntR(tab, AG_NUMERICAL_HFILL, "ms", _("Cursor Blink Rate: "), &agTextBlinkRate, 0, 500); AG_SpacerNewHoriz(tab); AG_NumericalNewIntR(tab, AG_NUMERICAL_HFILL, "ms", _("Key Repeat Delay: "), &agKbdDelay, 1, 1000); AG_NumericalNewIntR(tab, AG_NUMERICAL_HFILL, "ms", _("Key Repeat Interval: "), &agKbdRepeat, 1, 500); AG_SpacerNewHoriz(tab); AG_NumericalNewIntR(tab, AG_NUMERICAL_HFILL, "ms", _("Autocomplete Delay: "), &agAutocompleteDelay, 1, 5000); AG_NumericalNewIntR(tab, AG_NUMERICAL_HFILL, "ms", _("Autocomplete Rate: "), &agAutocompleteRate, 1, 1000); AG_SpacerNewHoriz(tab); AG_CheckboxNewInt(tab, 0, _("Latin Character Input " "(with " AGSI_COURIER "Alt/Shift" AGSI_RST ")"), &agLatinInput); AG_CheckboxNewInt(tab, 0, _("Latin Character Composition"), &agLatinComposition); } tab = AG_NotebookAdd(nb, _(AGSI_IDEOGRAM AGSI_TWO_BUTTON_MOUSE AGSI_RST " Mouse"), AG_BOX_VERT); { AG_Checkbox *cb; AG_Numerical *num; AG_SetPadding(tab, "8"); num = AG_NumericalNewIntR(tab, AG_NUMERICAL_HFILL, "ms", _("Double Click Threshold: "), &agMouseDblclickDelay, 1, 10000); AG_SetMargin(num, "0 0 10 0"); AG_NumericalNewIntR(tab, AG_NUMERICAL_HFILL, "ms", _("Spin Delay: "), &agMouseSpinDelay, 1, 10000); AG_NumericalNewIntR(tab, AG_NUMERICAL_HFILL, "ms", _("Spin Interval: "), &agMouseSpinIval, 1, 10000); AG_NumericalNewIntR(tab, AG_NUMERICAL_HFILL, "ms", _("Scroll Interval: "), &agMouseScrollIval, 1, 10000); cb = AG_CheckboxNewInt(tab, 0, _("Zoom with " AGSI_CODE "Ctrl" AGSI_RST " + Mouse Wheel"), &agCtrlMouseWheelAction); AG_SetMargin(cb, "10 0 0 0"); } tab = AG_NotebookAdd(nb, _(AGSI_IDEOGRAM AGSI_GAME_CONTROLLER AGSI_RST " Controllers"), AG_BOX_VERT); { #ifdef HAVE_SDL2 AG_Driver *drv = WIDGET(win)->drv; #endif AG_Tlist *tl; box = AG_BoxNewVert(tab, AG_BOX_EXPAND); #ifdef HAVE_SDL2 if (OBJECT(drv)->cid == AGC_DRIVER_SDL2MW || OBJECT(drv)->cid == AGC_DRIVER_SDL2GL || OBJECT(drv)->cid == AGC_DRIVER_SDL2FB) { AG_LabelNewS(box, 0, _("Joystick support is available.")); tl = AG_TlistNewPolled(box, AG_TLIST_POLL | AG_TLIST_EXPAND, PollJoysticks, NULL); AG_TlistSizeHint(tl, "", 8); } else #endif { AG_LabelNew(box, 0, _(AGSI_IDEOGRAM AGSI_TRI_CONSTRUCTION_SIGN AGSI_RST " Joystick support is not available in " AGSI_CODE AGSI_CYAN "%s" AGSI_WHT "(3)" AGSI_RST " at this time.\n" "To use joysticks or game controllers, restart " "with one of:\n\n" AGSI_CODE " -d 'sdl2mw(ctrl)'\n" " -d 'sdl2gl(ctrl)'\n" " -d 'sdl2fb(ctrl)'\n"), AGOBJECT_CLASS(WIDGET(win)->drv)->name); AG_PushDisabledState(box); tl = AG_TlistNew(box, AG_TLIST_EXPAND); AG_TlistAddS(tl, NULL, "(No joystick support)"); AG_PopDisabledState(box); } } box = AG_BoxNewHoriz(win, AG_BOX_HOMOGENOUS | AG_BOX_HFILL); { AG_ButtonNewFn(box, 0, _("Close"), AGWINDETACH(win)); AG_ButtonNewFn(box, 0, _("Save"), SaveConfig, NULL); } AG_WindowSetMinSize(win, 400, 250); AG_WindowSetPosition(win, AG_WINDOW_MC, 0); return (win); } void AG_DEV_ConfigShow(void) { AG_Window *win; if ((win = AG_DEV_ConfigWindow(agConfig)) != NULL) AG_WindowShow(win); } #endif /* AG_WIDGETS */