diff --git a/binaries/data/mods/public/gui/pregame/mainmenu.js b/binaries/data/mods/public/gui/pregame/mainmenu.js index aeaa629..4f49f87 100644 --- a/binaries/data/mods/public/gui/pregame/mainmenu.js +++ b/binaries/data/mods/public/gui/pregame/mainmenu.js @@ -1,6 +1,8 @@ function init() { global.curr_music = newRandomSound("music", "menu"); + global.curr_music.setGain (options.getOption("audio.musicvolume")); + global.curr_music.setDisabled (options.getOption("audio.musicdisable")); if (global.curr_music) global.curr_music.loop(); } diff --git a/binaries/data/mods/public/gui/pregame/mainmenu.xml b/binaries/data/mods/public/gui/pregame/mainmenu.xml index 6860eb2..27f8c3c 100644 --- a/binaries/data/mods/public/gui/pregame/mainmenu.xml +++ b/binaries/data/mods/public/gui/pregame/mainmenu.xml @@ -165,7 +165,7 @@ Watch for updates or get involved in the development: http://wildfiregames.com/0 sprite_over="pgOptionsOver" sprite_disabled="pgOptionsDisabled" tooltip="This will take you to the options menu. It does not work now, but someday it might." - enabled="false" + enabled="true" > Mute All @@ -407,7 +394,7 @@ Watch for updates or get involved in the development: http://wildfiregames.com/0 text_valign="center" > @@ -421,7 +408,7 @@ Watch for updates or get involved in the development: http://wildfiregames.com/0 guiModifyCaption ("pgOptionsAudioMusicGain", -.1, 1); global.curr_music.setGain (getGUIObjectByName ("pgOptionsAudioMusicGain").caption); - g_ConfigDB.system["sound.mastergain"] = getGUIObjectByName ("pgOptionsAudioMusicGain").caption; + options.setOption("audio.musicvolume", getGUIObjectByName ("pgOptionsAudioMusicGain").caption); ]]> @@ -435,7 +422,7 @@ Watch for updates or get involved in the development: http://wildfiregames.com/0 guiModifyCaption ("pgOptionsAudioMusicGain", .1, 1); global.curr_music.setGain (getGUIObjectByName ("pgOptionsAudioMusicGain").caption); - g_ConfigDB.system["sound.mastergain"] = getGUIObjectByName ("pgOptionsAudioMusicGain").caption; + options.setOption("audio.musicvolume", getGUIObjectByName ("pgOptionsAudioMusicGain").caption); ]]> @@ -444,19 +431,12 @@ Watch for updates or get involved in the development: http://wildfiregames.com/0 type="checkbox" size="60% 30% 60%+50 35%" >Mute + diff --git a/binaries/data/mods/public/gui/session_new/session.xml b/binaries/data/mods/public/gui/session_new/session.xml index 5d962dd..adcea08 100644 --- a/binaries/data/mods/public/gui/session_new/session.xml +++ b/binaries/data/mods/public/gui/session_new/session.xml @@ -279,16 +279,16 @@ > Enable Shadows - - if (renderer.shadows) this.checked = true; else this.checked = false; - renderer.shadows = this.checked; + ++ this.checked = options.getOption("shadows"); ++ options.setOption("shadows", this.checked); Enable Water Reflections - if (renderer.fancyWater) this.checked = true; else this.checked = false; - renderer.fancyWater = this.checked; + this.checked = options.getOption("fancywater"); ++ options.setOption("fancywater", this.checked); diff --git a/build/premake/premake.lua b/build/premake/premake.lua index 8fa9737..37a3b71 100644 --- a/build/premake/premake.lua +++ b/build/premake/premake.lua @@ -541,6 +541,7 @@ function setup_all_libs () "libjpg", "valgrind", "cxxtest", + "spidermonkey" } -- CPU architecture-specific diff --git a/source/graphics/GameView.cpp b/source/graphics/GameView.cpp index 8a367e7..85e05e1 100644 --- a/source/graphics/GameView.cpp +++ b/source/graphics/GameView.cpp @@ -39,6 +39,7 @@ #include "maths/Matrix3D.h" #include "maths/Quaternion.h" #include "ps/ConfigDB.h" +#include "ps/PSOptions.h" #include "ps/Game.h" #include "ps/Globals.h" #include "ps/Hotkey.h" @@ -54,8 +55,6 @@ #include "simulation2/Simulation2.h" #include "simulation2/components/ICmpPosition.h" -extern int g_xres, g_yres; - const float CGameView::defaultFOV = DEGTORAD(20.f); const float CGameView::defaultNear = 4.f; const float CGameView::defaultFar = 4096.f; @@ -285,8 +284,8 @@ CGameView::CGameView(CGame *pGame): SViewPort vp; vp.m_X=0; vp.m_Y=0; - vp.m_Width=g_xres; - vp.m_Height=g_yres; + vp.m_Width=g_graphicsXRes; + vp.m_Height=g_graphicsYRes; m->ViewCamera.SetViewPort(vp); m->ViewCamera.SetProjection(defaultNear, defaultFar, defaultFOV); @@ -621,12 +620,12 @@ void CGameView::Update(float DeltaTime) if (g_mouse_active) { - if (g_mouse_x >= g_xres - 2 && g_mouse_x < g_xres) + if (g_mouse_x >= g_graphicsXRes - 2 && g_mouse_x < g_graphicsXRes) moveRightward += m->ViewScrollSpeed * DeltaTime; else if (g_mouse_x <= 3 && g_mouse_x >= 0) moveRightward -= m->ViewScrollSpeed * DeltaTime; - if (g_mouse_y >= g_yres - 2 && g_mouse_y < g_yres) + if (g_mouse_y >= g_graphicsYRes - 2 && g_mouse_y < g_graphicsYRes) moveForward -= m->ViewScrollSpeed * DeltaTime; else if (g_mouse_y <= 3 && g_mouse_y >= 0) moveForward += m->ViewScrollSpeed * DeltaTime; diff --git a/source/gui/CTooltip.cpp b/source/gui/CTooltip.cpp index f2868e0..b55f0da 100644 --- a/source/gui/CTooltip.cpp +++ b/source/gui/CTooltip.cpp @@ -21,6 +21,7 @@ #include "CTooltip.h" #include "CGUI.h" +#include "PS/PSOptions.h" #include @@ -116,9 +117,7 @@ void CTooltip::SetupText() // Reposition the tooltip if it's falling off the screen: - - extern int g_xres, g_yres; - float screenw = (float)g_xres, screenh = (float)g_yres; + float screenw = (float)g_graphicsXRes, screenh = (float)g_graphicsYRes; if (size.pixel.top < 0.f) size.pixel.bottom -= size.pixel.top, size.pixel.top = 0.f; diff --git a/source/gui/GUIutil.cpp b/source/gui/GUIutil.cpp index b0a4d11..2692c12 100644 --- a/source/gui/GUIutil.cpp +++ b/source/gui/GUIutil.cpp @@ -24,8 +24,8 @@ GUI utilities #include "GUIManager.h" #include "ps/Parser.h" #include "ps/i18n.h" +#include "ps/PSOptions.h" -extern int g_yres; #include "ps/CLogger.h" #define LOG_CATEGORY L"gui" @@ -258,7 +258,7 @@ bool __ParseString(const CStrW& UNUSED(Value), CGUIList& UNUSED(Output void guiLoadIdentity() { glLoadIdentity(); - glTranslatef(0.0f, (GLfloat)g_yres, -1000.0f); + glTranslatef(0.0f, (GLfloat)g_graphicsYRes, -1000.0f); glScalef(1.0f, -1.f, 1.0f); } diff --git a/source/gui/IGUIObject.cpp b/source/gui/IGUIObject.cpp index 8ba2809..562aa04 100644 --- a/source/gui/IGUIObject.cpp +++ b/source/gui/IGUIObject.cpp @@ -29,11 +29,9 @@ IGUIObject #include "scriptinterface/ScriptVal.h" #include "ps/CLogger.h" +#include "ps/PSOptions.h" #define LOG_CATEGORY L"gui" -extern int g_xres, g_yres; - - //------------------------------------------------------------------- // Implementation Macros //------------------------------------------------------------------- @@ -349,7 +347,7 @@ void IGUIObject::UpdateCachedSize() if (absolute == false && m_pParent && !IsRootObject()) m_CachedActualSize = ca.GetClientArea(m_pParent->m_CachedActualSize); else - m_CachedActualSize = ca.GetClientArea(CRect(0.f, 0.f, (float)g_xres, (float)g_yres)); + m_CachedActualSize = ca.GetClientArea(CRect(0.f, 0.f, (float)g_graphicsXRes, (float)g_graphicsYRes)); // In a few cases, GUI objects have to resize to fill the screen // but maintain a constant aspect ratio. diff --git a/source/gui/scripting/JSInterface_IGUIObject.cpp b/source/gui/scripting/JSInterface_IGUIObject.cpp index 4205af0..860df20 100644 --- a/source/gui/scripting/JSInterface_IGUIObject.cpp +++ b/source/gui/scripting/JSInterface_IGUIObject.cpp @@ -416,14 +416,16 @@ JSBool JSI_IGUIObject::setProperty(JSContext* cx, JSObject* obj, jsval id, jsval case GUIST_bool: { + if (JSVAL_IS_BOOLEAN(*vp)) { JSBool value; if (JS_ValueToBoolean(cx, *vp, &value) == JS_TRUE) - GUI::SetSetting(e, propName, value||0); // ||0 to avoid int-to-bool compiler warnings + GUI::SetSetting(e, propName, (value == JS_TRUE)); // ||0 to avoid int-to-bool compiler warnings else { JS_ReportError(cx, "Cannot convert value to bool"); return JS_FALSE; } + } break; } diff --git a/source/lib/res/sound/snd_mgr.cpp b/source/lib/res/sound/snd_mgr.cpp index 78469b6..e2570b2 100644 --- a/source/lib/res/sound/snd_mgr.cpp +++ b/source/lib/res/sound/snd_mgr.cpp @@ -52,6 +52,8 @@ #include "lib/external_libraries/openal.h" #include "lib/sysdep/cpu.h" // cpu_CAS +#include "ps/PSOptions.h" // cpu_CAS + #include "ogg.h" // HACK: OpenAL loads and unloads certain DLLs several times on Windows. @@ -710,26 +712,19 @@ static bool snd_disabled = false; */ static LibError snd_init() { - // (note: each VSrc_reload and therefore snd_open will fail) - if(snd_disabled) - return ERR::AGAIN; // NOWARN - return al_init(); } LibError snd_disable(bool disabled) { - snd_disabled = disabled; + if (g_audioDisableAudio) + alListenerf(AL_GAIN, 0.0f); + else + alListenerf(AL_GAIN, 1.0f); - if(snd_disabled) - { - debug_assert(!al_initialized); // already initialized => disable is pointless return INFO::OK; } - else - return snd_init(); // note: won't return ERR::AGAIN, since snd_disabled == false -} /** diff --git a/source/lib/sysdep/os/win/wsdl.cpp b/source/lib/sysdep/os/win/wsdl.cpp index e8a4cc5..81ac3a0 100644 --- a/source/lib/sysdep/os/win/wsdl.cpp +++ b/source/lib/sysdep/os/win/wsdl.cpp @@ -44,6 +44,8 @@ #include "lib/sysdep/os/win/winit.h" #include "lib/sysdep/os/win/wmi.h" // for SDL_GetVideoInfo +#include "ps/PSOptions.h" + #if MSC_VERSION #pragma comment(lib, "user32.lib") #pragma comment(lib, "gdi32.lib") @@ -55,10 +57,6 @@ WINIT_REGISTER_LATE_INIT(wsdl_Init); WINIT_REGISTER_EARLY_SHUTDOWN(wsdl_Shutdown); -// in fullscreen mode, i.e. not windowed. -// video mode will be restored when app is deactivated. -static bool fullscreen; - // the app is shutting down. // if set, ignore further Windows messages for clean shutdown. static bool is_quitting; @@ -218,6 +216,23 @@ static void wnd_UpdateWindowDimensions(DWORD windowStyle, int& w, int& h) } } +// Windows Key Hook to allow processing of key events +// before windows processes them. +LRESULT CALLBACK LowLevelKeyEventProc( + int nCode, + WPARAM wParam, + LPARAM lParam) +{ + if (nCode >= 0) { + KBDLLHOOKSTRUCT* msgInfo = (KBDLLHOOKSTRUCT*)lParam; + if (g_gameDisableWindowsKey.Get() && (msgInfo->vkCode == VK_LWIN || msgInfo->vkCode == VK_RWIN)) { + PostMessage(NULL, wParam, msgInfo->vkCode, (msgInfo->scanCode & 0xff) << 16); + return 1; + } + } + return CallNextHookEx(NULL, nCode, wParam, lParam); +} + static LRESULT CALLBACK wndproc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); @@ -244,7 +259,7 @@ static HWND wnd_CreateWindow(int w, int h) return 0; } - const DWORD windowStyle = wnd_ChooseWindowStyle(fullscreen); + const DWORD windowStyle = wnd_ChooseWindowStyle(g_graphicsFullscreen); wnd_UpdateWindowDimensions(windowStyle, w, h); // note: you can override the hardcoded window name via SDL_WM_SetCaption. @@ -345,7 +360,7 @@ SDL_Surface* SDL_SetVideoMode(int w, int h, int bpp, Uint32 flags) { WinScopedPreserveLastError s; // OpenGL and GDI - fullscreen = (flags & SDL_FULLSCREEN) != 0; + g_graphicsFullscreen = (flags & SDL_FULLSCREEN) != 0; // get current mode settings memset(&dm, 0, sizeof(dm)); @@ -357,7 +372,7 @@ SDL_Surface* SDL_SetVideoMode(int w, int h, int bpp, Uint32 flags) dm.dmBitsPerPel = bpp; dm.dmFields = DM_BITSPERPEL; - if(video_NeedsChange(w,h, cur_w,cur_h, fullscreen)) + if(video_NeedsChange(w,h, cur_w,cur_h, g_graphicsFullscreen)) { dm.dmPelsWidth = (DWORD)w; dm.dmPelsHeight = (DWORD)h; @@ -386,17 +401,17 @@ SDL_Surface* SDL_SetVideoMode(int w, int h, int bpp, Uint32 flags) } else // update the existing window { - const DWORD windowStyle = wnd_ChooseWindowStyle(fullscreen, g_hWnd); + const DWORD windowStyle = wnd_ChooseWindowStyle(g_graphicsFullscreen, g_hWnd); wnd_UpdateWindowDimensions(windowStyle, w, h); UINT swp_flags = SWP_FRAMECHANGED|SWP_NOZORDER|SWP_NOACTIVATE; - if(!fullscreen) // windowed: preserve the top-left corner + if(!g_graphicsFullscreen) // windowed: preserve the top-left corner swp_flags |= SWP_NOMOVE; WARN_IF_FALSE(SetWindowLongW(g_hWnd, GWL_STYLE, windowStyle)); WARN_IF_FALSE(SetWindowPos(g_hWnd, 0, 0, 0, w, h, swp_flags)); - if(fullscreen) + if(g_graphicsFullscreen) { ShowWindow(g_hWnd, SW_RESTORE); ChangeDisplaySettings(&dm, CDS_FULLSCREEN); @@ -427,7 +442,7 @@ SDL_Surface* SDL_SetVideoMode(int w, int h, int bpp, Uint32 flags) static void video_Shutdown() { - if(fullscreen) + if(g_graphicsFullscreen) { LONG status = ChangeDisplaySettings(0, 0); debug_assert(status == DISP_CHANGE_SUCCESSFUL); @@ -518,6 +533,10 @@ static SDLKey g_SDLKeyForVK[256]; // g_SDLKeyForVK[vk] == SDLK static void key_Init() { + + SetWindowsHookEx(WH_KEYBOARD_LL, &LowLevelKeyEventProc, GetModuleHandle(0), 0); + + // Map the VK keysyms for(int i = 0; i < ARRAY_SIZE(g_SDLKeyForVK); i++) g_SDLKeyForVK[i] = SDLK_UNKNOWN; @@ -737,7 +756,7 @@ static LRESULT OnActivate(HWND hWnd, UINT state, HWND UNUSED(hWndActDeact), BOOL SetFocus(hWnd); gammaRamp.Latch(); - if(fullscreen) + if(g_graphicsFullscreen) { ShowWindow(g_hWnd, SW_RESTORE); ChangeDisplaySettings(&dm, CDS_FULLSCREEN); @@ -757,7 +776,7 @@ static LRESULT OnActivate(HWND hWnd, UINT state, HWND UNUSED(hWndActDeact), BOOL key_ResetAll(); gammaRamp.RestoreOriginal(); - if(fullscreen) + if(g_graphicsFullscreen) { ChangeDisplaySettings(0, 0); ShowWindow(g_hWnd, SW_MINIMIZE); @@ -1078,7 +1097,7 @@ static bool ResizeEventEnabled(int clientWidth, int clientHeight) // if fullscreen, interaction with other topmost windows causes // minimization and a spurious resize. however, the app only // expects resizing events if !fullscreen. - if(fullscreen) + if(g_graphicsFullscreen) return false; // this happens during minimization, which results in an @@ -1160,7 +1179,7 @@ static LRESULT CALLBACK wndproc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPar // prevent selecting menu in fullscreen mode case WM_NCHITTEST: - if(fullscreen) + if(g_graphicsFullscreen) return HTCLIENT; break; @@ -1175,7 +1194,7 @@ static LRESULT CALLBACK wndproc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPar case SC_SIZE: case SC_MAXIMIZE: case SC_MONITORPOWER: - if(fullscreen) + if(g_graphicsFullscreen) return 1; break; diff --git a/source/ps/CConsole.cpp b/source/ps/CConsole.cpp index eaaa52c..e3d5a31 100644 --- a/source/ps/CConsole.cpp +++ b/source/ps/CConsole.cpp @@ -716,7 +716,7 @@ void CConsole::SaveHistory() g_VFS->CreateFile(m_sHistoryFile, buffer.Data(), buffer.Size()); } -void CConsole::SendChatMessage(const wchar_t *pText) +void CConsole::SendChatMessage(const wchar_t *UNUSED(pText)) { if (g_NetClient) { diff --git a/source/ps/CLogger.cpp b/source/ps/CLogger.cpp index ee679bd..6bf441a 100644 --- a/source/ps/CLogger.cpp +++ b/source/ps/CLogger.cpp @@ -27,6 +27,7 @@ #include "lib/res/graphics/unifont.h" #include "lib/sysdep/sysdep.h" #include "ps/Font.h" +#include "ps/PSOptions.h" #include #include @@ -46,8 +47,6 @@ static const size_t RENDER_LIMIT = 20; // maximum messages on screen at once static const size_t BUFFER_SIZE = 1024; -extern int g_xres, g_yres; - // Set up a default logger that throws everything away, because that's // better than crashing. (This is particularly useful for unit tests which // don't care about any log output.) @@ -316,7 +315,7 @@ void CLogger::Render() glPushMatrix(); glScalef(1.0f, -1.0f, 1.0f); - glTranslatef(4.0f, 4.0f + (float)lineSpacing - g_yres, 0.0f); + glTranslatef(4.0f, 4.0f + (float)lineSpacing - g_graphicsYRes, 0.0f); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); diff --git a/source/ps/CVariable.cpp b/source/ps/CVariable.cpp new file mode 100644 index 0000000..a06d405 --- /dev/null +++ b/source/ps/CVariable.cpp @@ -0,0 +1,212 @@ +/* Copyright (C) 2009 Wildfire Games. + * This file is part of 0 A.D. + * + * 0 A.D. is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * 0 A.D. is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with 0 A.D. If not, see . + */ + +#include "precompiled.h" +#include "CVariable.h" +#include "Parser.h" +#include "Filesystem.h" +#include "PSOptions.h" + +#include "lib/timer.h" +#include "lib/utf8.h" + +#include + +static const CStrW c_configNewFilePath[NVariable::CFG_COMMAND] = { + L"config/default.config", + L"config/local.config", + L"config/mod.config", + L"user.config", +}; + +static IVariable::VariableMap* s_variableMap = NULL; +static bool intialize = false; + +namespace NVariable { + + void InitVars () { + TIMER(L"InitVars"); + + CParser parser; + CParserLine parserLine; + parser.InputTaskType("Assignment", "_$ident_=<_[-$arg(_minus)]_$value_,>_[-$arg(_minus)]_$value[[;]$rest]"); + parser.InputTaskType("CommentOrBlank", "_[;[$rest]]"); + + for (int i = 0; i <= NVariable::CFG_COMMAND; ++i) { + // Open file with VFS + shared_ptr buffer; size_t buflen; + { + VfsPath path = VfsPath(c_configNewFilePath[i]); + if (EVariableNamespace(i) == CFG_USER) { + path = VfsPath(L"config/profiles") / wstring_from_utf8(g_gameActiveProfile); + path = VfsPath(path / L"settings/user.config"); + } + // Handle missing files quietly + if (g_VFS->GetFileInfo(path, NULL) < 0) + { + continue; + } + else + { + LibError ret = g_VFS->LoadFile(path, buffer, buflen); + if (ret != INFO::OK) + { + continue; + } + } + } + + if (buflen == 0) + continue; + + char *filebuf=(char *)buffer.get(); + char *filebufend=filebuf+buflen; + + // Read file line by line + char *next=filebuf-1; + do + { + char *pos=next+1; + next=(char *)memchr(pos, '\n', filebufend-pos); + if (!next) next=filebufend; + + char *lend=next; + if (*(lend-1) == '\r') lend--; + + // Send line to parser + bool parseOk=parserLine.ParseString(parser, std::string(pos, lend)); + // Get name and value from parser + std::string name; + std::string value; + + if (parseOk && + parserLine.GetArgCount()>=2 && + parserLine.GetArgString(0, name) && + parserLine.GetArgString(1, value)) + { + // Add name and value to the map + size_t argCount = parserLine.GetArgCount(); + + for( size_t t = 0; t < argCount; t++ ) + { + if( !parserLine.GetArgString( (int)t + 1, value ) ) + continue; + } + + IVariable::VariableMap::iterator iter = s_variableMap->find(name); + if (iter != s_variableMap->end()) { + (*iter).second->fromValue(value); + } + } + } + while (next < filebufend); + } + } + + void Shutdown () { + std::stringstream fileArray[NVariable::CFG_COMMAND]; + + for (IVariable::VariableMap::iterator it = s_variableMap->begin(); it != s_variableMap->end(); ++it) { + NVariable::EVariableNamespace level = (*it).second->getSaveLevel(); + + // We do not want to save READONLY vars + if (level == NVariable::CFG_READONLY) + continue; + + // We always save everything in the default that way it for whatever + // reason they cannot save or do not have a user.config file they will + // still have the settings saved. + fileArray[NVariable::CFG_DEFAULT] << (*it).second->getName().c_str() << " = " << (*it).second->toValue().c_str() << " \n"; + + // Save to the local setting storage + if (level != NVariable::CFG_DEFAULT) + fileArray[level] << (*it).second->getName().c_str() << " = " << (*it).second->toValue().c_str() << " \n"; + } + + + for (int i = 0; i < NVariable::CFG_COMMAND; ++i) { + + // Allocate this stupid shared PTR :/ + shared_ptr buf = io_Allocate(1*MiB); + size_t length = fileArray[i].str().length(); + + // This makes me very sad, I do not know why + // we have to use a shared_ptr object when all + // I want to do is write some bytes to a file + fileArray[i].str().copy((char*)buf.get(), length); + + if (length == 0) + continue; + + // Get me some file path love + VfsPath path = VfsPath(c_configNewFilePath[i]); + if (i == CFG_USER) { + path = VfsPath(L"config/profiles") / wstring_from_utf8(g_gameActiveProfile); + path = path / L"settings/user.config"; + } + + // Jackpot! + LibError ret = g_VFS->CreateFile(path, buf, length); + if(ret < 0) + continue;; + } + } + + IVariable* GetVariable(const CStr& variableName) { + if (variableName == "") + return NULL; + + IVariable::VariableMap::iterator iter = s_variableMap->find(variableName); + return (*iter).second; + } +} + +IVariable::IVariable( + const char* categoryName, + const char* commandName, + const char* commandHelp, + NVariable::EVariableNamespace saveLevel +) { + + if(!intialize) { + s_variableMap = new VariableMap; + intialize = true; + } + VariableMap::iterator iter = s_variableMap->find(commandName); + if (iter == s_variableMap->end()) { + m_categoryName = categoryName; + m_commandName = commandName; + m_helpString = commandHelp; + m_saveLevel = saveLevel; + (*s_variableMap)[commandName] = this; + } +} + +IVariable::~IVariable () { + for (VariableMap::iterator iter = s_variableMap->begin(); iter != s_variableMap->end(); iter++) + { + if ((*iter).second == this) { + s_variableMap->erase (iter); + if (!s_variableMap->size()) { + delete s_variableMap; + s_variableMap = NULL; + intialize = false; + } + break; + } + } +} diff --git a/source/ps/CVariable.h b/source/ps/CVariable.h new file mode 100644 index 0000000..9887bec --- /dev/null +++ b/source/ps/CVariable.h @@ -0,0 +1,216 @@ +/* Copyright (C) 2009 Wildfire Games. + * This file is part of 0 A.D. + * + * 0 A.D. is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * 0 A.D. is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with 0 A.D. If not, see . + */ + +#ifndef INCLUDED_CVARIABLE +#define INCLUDED_CVARIABLE + +#include +#include +#include +#include "CStr.h" + +#include "scripting/ScriptableObject.h" + +#include "lib/types.h" + +#define CONVERT_VARGS(_dest,_format,_size) \ + char _cstring[_size]; \ + va_list _args; \ + va_start (_args, _format); \ + int _res = vsnprintf (_cstring, _size-1, _format, _args); \ + if (_res == -1 || _res == _size-1) \ +{ \ + _cstring[_size-1] = '\0'; \ +} \ + va_end (_args); \ + _dest = _cstring + +namespace NMisc { + + inline CStr toString(const char *format, ...) { + std::string Result; + CONVERT_VARGS(Result, format, 256); + return Result; + } + + template + CStr toString(const T &obj) { + return obj.toString(); + } + + inline CStr toString(const u8 &val) { return toString("%hu", (u16)val); } + inline CStr toString(const i8 &val) { return toString("%hd", (i16)val); } + inline CStr toString(const u16 &val) { return toString("%hu", val); } + inline CStr toString(const i16 &val) { return toString("%hd", val); } + inline CStr toString(const u32 &val) { return toString("%u", val); } + inline CStr toString(const i32 &val) { return toString("%d", val); } + + inline CStr toString(const float &val) { return toString("%f", val); } + inline CStr toString(const double &val) { return toString("%lf", val); } + inline CStr toString(const bool &val) { return toString("%u", val?1:0); } + inline CStr toString(const CStr &val) { return val; } + inline CStr toString(const CStrW &val) { return CStr(val); } + + template + bool fromString(const CStr &str, T &obj) { + return obj.fromString(str); + } + + inline bool fromString(const CStr &str, u32 &val) { if (str.find('-') != std::string::npos) { val = 0; return false; } char *end; unsigned long v; errno = 0; v = strtoul(str.c_str(), &end, 10); if (errno || v > UINT_MAX || end == str.c_str()) { val = 0; return false; } else { val = (u32)v; return true; } } + inline bool fromString(const CStr &str, i32 &val) { char *end; long v; errno = 0; v = strtol(str.c_str(), &end, 10); if (errno || v > INT_MAX || v < INT_MIN || end == str.c_str()) { val = 0; return false; } else { val = (i32)v; return true; } } + inline bool fromString(const CStr &str, u8 &val) { char *end; long v; errno = 0; v = strtol(str.c_str(), &end, 10); if (errno || v > UCHAR_MAX || v < 0 || end == str.c_str()) { val = 0; return false; } else { val = (u8)v; return true; } } + inline bool fromString(const CStr &str, i8 &val) { char *end; long v; errno = 0; v = strtol(str.c_str(), &end, 10); if (errno || v > SCHAR_MAX || v < SCHAR_MIN || end == str.c_str()) { val = 0; return false; } else { val = (i8)v; return true; } } + inline bool fromString(const CStr &str, u16 &val) { char *end; long v; errno = 0; v = strtol(str.c_str(), &end, 10); if (errno || v > USHRT_MAX || v < 0 || end == str.c_str()) { val = 0; return false; } else { val = (u16)v; return true; } } + inline bool fromString(const CStr &str, i16 &val) { char *end; long v; errno = 0; v = strtol(str.c_str(), &end, 10); if (errno || v > SHRT_MAX || v < SHRT_MIN || end == str.c_str()) { val = 0; return false; } else { val = (i16)v; return true; } } + inline bool fromString(const CStr &str, float &val) { bool ret = sscanf(str.c_str(), "%f", &val) == 1; if (!ret) val = 0.0f; return ret; } + inline bool fromString(const CStr &str, double &val) { bool ret = sscanf(str.c_str(), "%lf", &val) == 1; if (!ret) val = 0.0; return ret; } + inline bool fromString(const CStr &str, bool &val) { + if (str.length() > 1) + val = (str.length() > 1) && str[0] != 'f'; + else + val = (str.length() == 1) && str[0] != '0'; + + bool ret = ((str.length() == 1) && (str[0] == '0' || str[0] == '1')) || + ((str.length() > 1) && (str[0] == 'f' || str[0] == 't')); + + return ret; + } + inline bool fromString(const CStr &str, CStr &val) { val = str; return true; } + inline bool fromString(const CStr &str, CStrW &val) { val = CStrW(str); return true; } +} + +class IVariable; + +namespace NVariable { + enum EVariableNamespace { + CFG_READONLY = -1, + CFG_DEFAULT, + CFG_SYSTEM, + CFG_MOD, + CFG_USER, + CFG_COMMAND, + CFG_LAST + }; + + void InitVars (); + void Shutdown (); + IVariable* GetVariable(const CStr& variableName); +} + +class IVariable +{ +public : + IVariable ( + const char* categoryName, + const char* commandName, + const char* commandHelp, + NVariable::EVariableNamespace saveLevel = NVariable::CFG_DEFAULT); + + virtual ~IVariable(); + + typedef std::map VariableMap; + typedef std::vector VariableVector; + + CStr getName () { return m_commandName; } + CStr getHelpString () { return m_helpString; } + NVariable::EVariableNamespace getSaveLevel () { return m_saveLevel; } + virtual bool fromValue(const CStr &val) = 0; + + virtual CStr toValue() const = 0; + + virtual jsval_t JSI_GetValue(JSContext*) = 0; + virtual bool JSI_SetValue(JSContext* ctx, jsval newval) = 0; + +protected: + CStr m_categoryName; + CStr m_helpString; + CStr m_commandName; + NVariable::EVariableNamespace m_saveLevel; +}; + +template +class CVariable : IVariable +{ + typedef void (*OnChange)(CVariable&, T&); + +public: + CVariable ( + const char* categoryName, + const char* commandName, + const char* commandHelp, + const T& defaultValue, + NVariable::EVariableNamespace saveLevel= NVariable::CFG_DEFAULT, + OnChange callback = NULL) : + IVariable(categoryName, commandName, commandHelp, saveLevel), + m_initialized(false) +{ + m_callback = callback; + Set(defaultValue); + m_initialized = true; +} + + operator T () const { + return Get (); + } + + CVariable &operator= (const T &val) { + Set(val); + return *this; + } + + void Set(const T& inValue) { + T oldValue = m_value; + m_value = inValue; + + if(m_callback && m_initialized) + m_callback(*this, oldValue); + } + + const T& Get() const { return m_value; } + + virtual bool fromValue(const CStr &val) { + T v; + bool ret = NMisc::fromString(val, v); + Set(v); + return ret; + } + + virtual CStr toValue() const { + return NMisc::toString(m_value); + } + + jsval_t JSI_GetValue(JSContext*) { + return jsval_t(ToJSVal(m_value)); + }; + + bool JSI_SetValue(JSContext* ctx, jsval newval){ + T v; + if(!ToPrimitive(ctx, newval, v)) + return false; + + Set(v); + return true; + } + +private: + T m_value; + OnChange m_callback; + bool m_initialized; + +}; + +#endif diff --git a/source/ps/Game.cpp b/source/ps/Game.cpp index bba29d0..52bc3b3 100644 --- a/source/ps/Game.cpp +++ b/source/ps/Game.cpp @@ -80,7 +80,8 @@ CGame::CGame(bool disableGraphics): m_Simulation2->LoadDefaultScripts(); m_Simulation2->ResetState(); - CScriptVal initData; // TODO: ought to get this from the GUI, somehow + // TODO: If this function is even needed now, get initData + CScriptVal initData; m_Simulation2->InitGame(initData); } diff --git a/source/ps/GameSetup/Config.cpp b/source/ps/GameSetup/Config.cpp index bdc53e7..cef4d4a 100644 --- a/source/ps/GameSetup/Config.cpp +++ b/source/ps/GameSetup/Config.cpp @@ -18,6 +18,7 @@ #include "precompiled.h" #include "ps/ConfigDB.h" +#include "ps/PSOptions.h" #include "ps/CConsole.h" #include "ps/GameSetup/CmdLineArgs.h" #include "lib/timer.h" @@ -29,38 +30,8 @@ // (these variables are documented in the header.) CStrW g_CursorName = L"test"; -CStr g_ActiveProfile = "default"; - -bool g_NoGLS3TC = false; -bool g_NoGLAutoMipmap = false; -bool g_NoGLVBO = false; -bool g_NoGLFramebufferObject = false; - -bool g_Shadows = false; -bool g_FancyWater = false; - -float g_LodBias = 0.0f; -float g_Gamma = 1.0f; - -bool g_EntGraph = false; -CStr g_RenderPath = "default"; - -int g_xres, g_yres; -bool g_VSync = false; - -bool g_Quickstart = false; -bool g_DisableAudio = false; - -// flag to switch on drawing terrain overlays -bool g_ShowPathfindingOverlay = false; - -// flag to switch on triangulation pathfinding -bool g_TriPathfind = false; - - -// If non-empty, specified map will be automatically loaded -CStr g_AutostartMap = ""; +static CVariable s_soundGain("Sound", "gain", "", -1.0f, NVariable::CFG_READONLY); //---------------------------------------------------------------------------- // config and profile @@ -83,28 +54,14 @@ static void LoadProfile( const CStr& profile ) // Fill in the globals from the config files. static void LoadGlobals() { - CFG_GET_SYS_VAL("profile", String, g_ActiveProfile); // Now load the profile before trying to retrieve the values of the rest of these. - LoadProfile( g_ActiveProfile ); - - CFG_GET_USER_VAL("vsync", Bool, g_VSync); - - CFG_GET_USER_VAL("nos3tc", Bool, g_NoGLS3TC); - CFG_GET_USER_VAL("noautomipmap", Bool, g_NoGLAutoMipmap); - CFG_GET_USER_VAL("novbo", Bool, g_NoGLVBO); - CFG_GET_USER_VAL("noframebufferobject", Bool, g_NoGLFramebufferObject); - CFG_GET_USER_VAL("shadows", Bool, g_Shadows); - CFG_GET_USER_VAL("fancywater", Bool, g_FancyWater); - CFG_GET_USER_VAL("renderpath", String, g_RenderPath); - - CFG_GET_USER_VAL("lodbias", Float, g_LodBias); + LoadProfile( g_gameActiveProfile ); - float gain = -1.0f; - CFG_GET_USER_VAL("sound.mastergain", Float, gain); - if(gain >= 0.0f) - WARN_ERR(snd_set_master_gain(gain)); + s_soundGain = -1.0f; + if(s_soundGain >= 0.0f) + WARN_ERR(snd_set_master_gain(s_soundGain)); } @@ -135,13 +92,13 @@ static void ProcessCommandLineArgs(const CmdLineArgs& args) } if (args.Has("entgraph")) - g_EntGraph = true; + g_graphicsEntGraph = true; if (args.Has("g")) { - g_Gamma = (float)atof(args.Get("g")); - if (g_Gamma == 0.0f) - g_Gamma = 1.0f; + g_graphicsGamma = (float)atof(args.Get("g")); + if (g_graphicsGamma == 0.0f) + g_graphicsGamma = 1.0f; } // if (args.Has("listfiles")) @@ -152,24 +109,24 @@ static void ProcessCommandLineArgs(const CmdLineArgs& args) if (args.Has("quickstart")) { - g_Quickstart = true; - g_DisableAudio = true; // do this for backward-compatibility with user expectations + g_gameQuickStart = true; + g_audioDisableAudio = true; // do this for backward-compatibility with user expectations } if (args.Has("nosound")) - g_DisableAudio = true; + g_audioDisableAudio = true; if (args.Has("shadows")) - g_ConfigDB.CreateValue(CFG_COMMAND, "shadows")->m_String = "true"; + g_graphicsShadows = true; if (args.Has("xres")) - g_ConfigDB.CreateValue(CFG_COMMAND, "xres")->m_String = args.Get("xres"); + g_graphicsXRes.fromValue(args.Get("xres")); if (args.Has("yres")) - g_ConfigDB.CreateValue(CFG_COMMAND, "yres")->m_String = args.Get("yres"); + g_graphicsYRes.fromValue(args.Get("yres")); if (args.Has("vsync")) - g_ConfigDB.CreateValue(CFG_COMMAND, "vsync")->m_String = "true"; + g_graphicsVSync = true; } diff --git a/source/ps/GameSetup/Config.h b/source/ps/GameSetup/Config.h index 87c0be5..712414e 100644 --- a/source/ps/GameSetup/Config.h +++ b/source/ps/GameSetup/Config.h @@ -25,43 +25,6 @@ // prevent various OpenGL features from being used. this allows working // around issues like buggy drivers. -// when loading S3TC-compressed texture files, do not pass them directly to -// OpenGL; instead, decompress them via software to regular textures. -// (necessary on JW's S3 laptop graphics card -- oh, the irony) -extern bool g_NoGLS3TC; - -// do not ask OpenGL to create mipmaps; instead, generate them in software -// and upload them all manually. (potentially helpful for PT's system, where -// Mesa falsely reports full S3TC support but isn't able to generate mipmaps -// for them) -extern bool g_NoGLAutoMipmap; - -// don't use VBOs. (RC: that was necessary on laptop Radeon cards) -extern bool g_NoGLVBO; - -// disable FBO extension in case the driver is flaky -extern bool g_NoGLFramebufferObject; - -//----------------------------------------------------------------------------- - -// flag to switch on shadows -extern bool g_Shadows; -// flag to switch on reflective/refractive water -extern bool g_FancyWater; - -extern float g_LodBias; -extern float g_Gamma; -extern bool g_EntGraph; -// name of configured render path (depending on OpenGL extensions, this may not be -// the render path that is actually in use right now) -extern CStr g_RenderPath; - -extern int g_xres, g_yres; -extern bool g_VSync; - -extern bool g_Quickstart; -extern bool g_DisableAudio; - extern CStrW g_CursorName; class CmdLineArgs; diff --git a/source/ps/GameSetup/GameSetup.cpp b/source/ps/GameSetup/GameSetup.cpp index 830b010..94f4aad 100644 --- a/source/ps/GameSetup/GameSetup.cpp +++ b/source/ps/GameSetup/GameSetup.cpp @@ -39,6 +39,7 @@ #include "ps/CConsole.h" #include "ps/CLogger.h" #include "ps/ConfigDB.h" +#include "ps/PSOptions.h" #include "ps/Filesystem.h" #include "ps/Font.h" #include "ps/Game.h" @@ -228,7 +229,7 @@ void Render() glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); - glOrtho(0.f, (float)g_xres, 0.f, (float)g_yres, -1.f, 1000.f); + glOrtho(0.f, (float)g_graphicsXRes, 0.f, (float)g_graphicsYRes, -1.f, 1000.f); glMatrixMode(GL_MODELVIEW); glPushMatrix(); @@ -282,9 +283,9 @@ void Render() // Draw the cursor (or set the Windows cursor, on Windows) CStrW cursorName = g_CursorName; if (cursorName.empty()) - cursor_draw(g_VFS, NULL, g_mouse_x, g_yres-g_mouse_y); + cursor_draw(g_VFS, NULL, g_mouse_x, g_graphicsYRes-g_mouse_y); else - cursor_draw(g_VFS, cursorName.c_str(), g_mouse_x, g_yres-g_mouse_y); + cursor_draw(g_VFS, cursorName.c_str(), g_mouse_x, g_graphicsXRes-g_mouse_y); // restore glMatrixMode(GL_PROJECTION); @@ -464,13 +465,13 @@ static void InitPs(bool setup_gui, const CStrW& gui_page) // console TIMER(L"ps_console"); - g_Console->UpdateScreenSize(g_xres, g_yres); + g_Console->UpdateScreenSize(g_graphicsXRes, g_graphicsYRes); // Calculate and store the line spacing CFont font(CONSOLE_FONT); g_Console->m_iFontHeight = font.GetLineSpacing(); g_Console->m_iFontWidth = font.GetCharacterWidth(L'C'); - g_Console->m_charsPerPage = (size_t)(g_xres / g_Console->m_iFontWidth); + g_Console->m_charsPerPage = (size_t)(g_graphicsXRes / g_Console->m_iFontWidth); // Offset by an arbitrary amount, to make it fit more nicely g_Console->m_iFontOffset = 7; } @@ -479,9 +480,7 @@ static void InitPs(bool setup_gui, const CStrW& gui_page) { TIMER(L"ps_lang_hotkeys"); - std::string lang = "english"; - CFG_GET_SYS_VAL("language", String, lang); - I18n::LoadLanguage(lang.c_str()); + I18n::LoadLanguage(g_systemLanguage.Get().c_str()); LoadHotkeys(); } @@ -546,7 +545,7 @@ static void ShutdownPs() SAFE_DELETE(g_Console); // disable the special Windows cursor, or free textures for OGL cursors - cursor_draw(g_VFS, 0, g_mouse_x, g_yres-g_mouse_y); + cursor_draw(g_VFS, 0, g_mouse_x, g_graphicsYRes-g_mouse_y); // Unload the real language (since it depends on the scripting engine, // which is going to be killed later) and use the English fallback messages @@ -558,21 +557,21 @@ static void InitRenderer() { TIMER(L"InitRenderer"); - if(g_NoGLS3TC) + if(g_graphicsNoGLS3TC) ogl_tex_override(OGL_TEX_S3TC, OGL_TEX_DISABLE); - if(g_NoGLAutoMipmap) + if(g_graphicsNoGLAutoMipmap) ogl_tex_override(OGL_TEX_AUTO_MIPMAP_GEN, OGL_TEX_DISABLE); // create renderer new CRenderer; // set renderer options from command line options - NOVBO must be set before opening the renderer - g_Renderer.SetOptionBool(CRenderer::OPT_NOVBO,g_NoGLVBO); - g_Renderer.SetOptionBool(CRenderer::OPT_NOFRAMEBUFFEROBJECT,g_NoGLFramebufferObject); - g_Renderer.SetOptionBool(CRenderer::OPT_SHADOWS,g_Shadows); - g_Renderer.SetOptionBool(CRenderer::OPT_FANCYWATER,g_FancyWater); - g_Renderer.SetRenderPath(CRenderer::GetRenderPathByName(g_RenderPath)); - g_Renderer.SetOptionFloat(CRenderer::OPT_LODBIAS, g_LodBias); + g_Renderer.SetOptionBool(CRenderer::OPT_NOVBO,g_graphicsNoGLVBO); + g_Renderer.SetOptionBool(CRenderer::OPT_NOFRAMEBUFFEROBJECT,g_graphicsNoGLFrameBufferObject); + g_Renderer.SetOptionBool(CRenderer::OPT_SHADOWS,g_graphicsShadows); + g_Renderer.SetOptionBool(CRenderer::OPT_FANCYWATER,g_graphicsFancyWater); + g_Renderer.SetRenderPath(CRenderer::GetRenderPathByName(g_graphicsRenderPath)); + g_Renderer.SetOptionFloat(CRenderer::OPT_LODBIAS, g_graphicsLodBias); // create terrain related stuff new CTerrainTextureManager; @@ -581,7 +580,7 @@ static void InitRenderer() new CMaterialManager; MICROLOG(L"init renderer"); - g_Renderer.Open(g_xres,g_yres); + g_Renderer.Open(g_graphicsXRes,g_graphicsYRes); // Setup lighting environment. Since the Renderer accesses the // lighting environment through a pointer, this has to be done before @@ -593,8 +592,8 @@ static void InitRenderer() SViewPort vp; vp.m_X=0; vp.m_Y=0; - vp.m_Width=g_xres; - vp.m_Height=g_yres; + vp.m_Width=g_graphicsXRes; + vp.m_Height=g_graphicsYRes; g_Renderer.SetViewport(vp); ColorActivateFastImpl(); @@ -637,6 +636,11 @@ void Shutdown(int UNUSED(flags)) in_reset_handlers(); + // destroy the variable system + NVariable::Shutdown(); + delete &g_PSOptions; + + // destroy actor related stuff TIMER_BEGIN(L"shutdown actor stuff"); delete &g_MaterialManager; @@ -786,8 +790,6 @@ void Init(const CmdLineArgs& args, int flags) // and fonts are set later in InitPs()) g_Console = new CConsole(); - CNetHost::Initialize(); - new CProfileViewer; new CProfileManager; // before any script code @@ -797,6 +799,12 @@ void Init(const CmdLineArgs& args, int flags) MICROLOG(L"init scripting"); InitScripting(); // before GUI + CNetHost::Initialize(); + + new PSOptions; + NVariable::InitVars(); + + // g_ConfigDB, command line args, globals CONFIG_Init(args); } @@ -804,7 +812,6 @@ void Init(const CmdLineArgs& args, int flags) void InitGraphics(const CmdLineArgs& args, int flags) { const bool setup_vmode = (flags & INIT_HAVE_VMODE) == 0; - if(setup_vmode) { InitSDL(); @@ -822,19 +829,19 @@ void InitGraphics(const CmdLineArgs& args, int flags) // needed by ogl_tex to detect broken gfx card/driver combos, // but takes a while due to WMI startup, so make it optional. - if(!g_Quickstart) + if(!g_gameQuickStart) gfx_detect(); ogl_WarnIfError(); - if(!g_Quickstart) + if(!g_gameQuickStart) { WriteSystemInfo(); // note: no longer vfs_display here. it's dog-slow due to unbuffered // file output and very rarely needed. } - if(g_DisableAudio) + if(g_audioDisableAudio) { // speed up startup by disabling all sound // (OpenAL init will be skipped). @@ -870,10 +877,9 @@ void InitGraphics(const CmdLineArgs& args, int flags) L"The GL_ARB_texture_env_crossbar extension doesn't appear to be available on your computer." L" Shadows are not available and overall graphics quality might suffer." L" You are advised to try installing newer drivers and/or upgrade your graphics card."); - g_Shadows = false; + g_graphicsShadows = false; } - ogl_WarnIfError(); InitRenderer(); InitInput(); diff --git a/source/ps/PSOptions.cpp b/source/ps/PSOptions.cpp new file mode 100644 index 0000000..5254bb4 --- /dev/null +++ b/source/ps/PSOptions.cpp @@ -0,0 +1,161 @@ +/* Copyright (C) 2009 Wildfire Games. + * This file is part of 0 A.D. + * + * 0 A.D. is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * 0 A.D. is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with 0 A.D. If not, see . + */ + +#include "precompiled.h" + +#include "PSOptions.h" + +#include "renderer/Renderer.h" +#include "lib/res/sound/snd_mgr.h" +#include "i18n.h" + +using namespace NVariable; + +PSOptions::PSOptions () { + ScriptInit(); +} + +//----------------------------------------------------------------------------- +jsval_t PSOptions::GetOption( JSContext* cx, uintN argc, jsval* argv ) { + debug_assert(argc >= 1); + CStr name; + ToPrimitive(cx, argv[0], name); + + IVariable* var = NVariable::GetVariable(name); + if (var) { + return var->JSI_GetValue(NULL); + } + + return jsval_t(0); +} + +//----------------------------------------------------------------------------- +bool PSOptions::SetOption( JSContext* cx, uintN argc, jsval* argv ) { + debug_assert(argc >= 1); + CStr name; + ToPrimitive(cx, argv[0], name); + + IVariable* var = NVariable::GetVariable(name); + if (var) + return var->JSI_SetValue(cx, argv[1]); + + return false; +} + +//----------------------------------------------------------------------------- +void PSOptions::ScriptInit () { + AddMethod("getOption", 0); + AddMethod("setOption", 1); + + PSOptions::ScriptingInit("Options"); +} + +//----------------------------------------------------------------------------- +void OnWindowChange(CVariable& currentValue, bool& oldValue) { + if (oldValue) + return; +} + +//----------------------------------------------------------------------------- +void OnWindowXResChange(CVariable& currentValue, int& oldValue) { + if (oldValue) + return; +} + +//----------------------------------------------------------------------------- +void OnWindowYResChange(CVariable& currentValue, int& oldValue) { + if (oldValue) + return; +} + +//----------------------------------------------------------------------------- +void OnWindowBppChange(CVariable& currentValue, int& oldValue) { + if (oldValue) + return; +} + +//----------------------------------------------------------------------------- +void OnWindowKeyDisabledChange(CVariable& currentValue, bool& oldValue) { + if (oldValue) + return; +} + +//----------------------------------------------------------------------------- +void OnFancyWaterChange(CVariable& currentValue, bool& oldValue) { + if (CRenderer::IsInitialised()) + g_Renderer.SetOptionBool(CRenderer::OPT_FANCYWATER, currentValue); +} + +//----------------------------------------------------------------------------- +void OnShadowChange(CVariable& currentValue, bool& oldValue) { + if (CRenderer::IsInitialised()) + g_Renderer.SetOptionBool(CRenderer::OPT_SHADOWS, currentValue); +} + +//----------------------------------------------------------------------------- +void OnVSyncChange(CVariable& currentValue, bool& oldValue) { + +} + +//----------------------------------------------------------------------------- +void OnLocaleChange(CVariable& currentValue, CStr& oldValue) { + I18n::LoadLanguage(currentValue.Get().c_str()); +} + +//----------------------------------------------------------------------------- +void OnSoundDisableChange(CVariable& currentValue, bool& oldValue) { + snd_disable(currentValue); +} + +// graphics +CVariable g_graphicsFullscreen("Graphics", "fullscreen", "enables/disabled fullscreen", true, CFG_USER, OnWindowChange); +CVariable g_graphicsYRes("Graphics", "yres", "Y resolution", 0, CFG_DEFAULT, OnWindowXResChange); +CVariable g_graphicsXRes("Graphics", "xres", "X resolution", 0, CFG_DEFAULT, OnWindowYResChange); +CVariable g_graphicsBPP("Graphics", "bpp", "", 0, CFG_DEFAULT, OnWindowBppChange); +CVariable g_graphicsNoGLS3TC("Graphics", "nos3tc", "", false, CFG_DEFAULT ); +CVariable g_graphicsNoGLAutoMipmap("Graphics", "noautomipmap", "", false, CFG_DEFAULT); +CVariable g_graphicsNoGLVBO("Graphics", "novbo", "", false, CFG_DEFAULT); +CVariable g_graphicsNoGLFrameBufferObject("Graphics", "noframebufferobject", "", false, CFG_DEFAULT); +CVariable g_graphicsFancyWater("Graphics", "fancywater", "enable/disable fancy water", true, CFG_DEFAULT, OnFancyWaterChange); +CVariable g_graphicsShadows("Graphics", "shadows", "enable/disable shadows", true, CFG_DEFAULT, OnShadowChange); +CVariable g_graphicsVSync("Graphics", "vsync", "enable/disable vsync", false, CFG_DEFAULT, OnVSyncChange); +CVariable g_graphicsLodBias("Graphics", "lodbias", "", 0.0f, CFG_DEFAULT); +CVariable g_graphicsGamma("Graphics", "gamma", "", 1.0f, CFG_DEFAULT); +CVariable g_graphicsEntGraph("Graphics", "entgraph", "", false, CFG_DEFAULT); +CVariable g_graphicsRenderPath("Graphics", "renderPath", "", "default", CFG_DEFAULT); +CVariable g_graphicsShowPathFindingOverlay("Graphics", "show.pathfinding.overlay", "", false, CFG_DEFAULT); +CVariable g_graphicsTriPathFind("Graphics", "tripathfind", "", false, CFG_DEFAULT); +CVariable g_graphicsForceS3TCEnabled("Graphics", "forceS3TCEnabled", "", true, CFG_DEFAULT); + +// Gameplay +CVariable g_gameQuickStart("Gameplay", "quickstart", "", false, CFG_DEFAULT); +CVariable g_gameCursorName("Gameplay", "cursorname", "", L"test", CFG_DEFAULT); +CVariable g_gameAutoStartMap("Gameplay", "autostartmap", "", "", CFG_DEFAULT); +CVariable g_gameActiveProfile("Gameplay", "profile", "", "default", CFG_DEFAULT); +CVariable g_gameDisableWindowsKey("Gameplay", "disable.windowskey", "", false, CFG_USER, OnWindowKeyDisabledChange); // disabled windows key + +// Sound +extern CVariable g_audioDisableAudio("Audio", "audio.disable", "", false, CFG_USER, OnSoundDisableChange); // disabled windows key +extern CVariable g_audioMasterGain("Audio", "audio.mastergain", "", 1.0, CFG_USER); // disabled windows key +extern CVariable g_audioMusicVolume("Audio", "audio.musicvolume", "", 1.0, CFG_USER); // disabled windows key +extern CVariable g_audioDisableMusic("Audio", "audio.musicdisable", "", false, CFG_USER); // disabled windows key + +// System +CVariable g_systemLanguage("System", "language", "", "english", CFG_DEFAULT, OnLocaleChange); +CVariable g_systemFontDefault("System", "font.console", "", L"console", CFG_DEFAULT); +CVariable g_systemFontConsole("System", "font.default", "", L"palatino12", CFG_DEFAULT); +CVariable g_systemFontMisc("System", "font.misc", "", L"verdana16", CFG_DEFAULT); diff --git a/source/ps/PSOptions.h b/source/ps/PSOptions.h new file mode 100644 index 0000000..846bc7b --- /dev/null +++ b/source/ps/PSOptions.h @@ -0,0 +1,105 @@ +/* Copyright (C) 2009 Wildfire Games. + * This file is part of 0 A.D. + * + * 0 A.D. is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * 0 A.D. is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with 0 A.D. If not, see . + */ + +#ifndef INCLUDED_PSOPTIONS +#define INCLUDED_PSOPTIONS + +#include "CStr.h" +#include "CVariable.h" +#include "Singleton.h" + + +#include "scripting/ScriptableObject.h" + +#define g_PSOptions PSOptions::GetSingleton() + +class PSOptions : + public CJSObject, + public Singleton +{ +public: + PSOptions (); + ~PSOptions() {} + + void LoadProfile(); + static void ScriptInit(); + +protected: + jsval_t GetOption( JSContext* cx, uintN argc, jsval* argv ); + bool SetOption( JSContext* cx, uintN argc, jsval* argv ); + +}; + +// Graphics +extern CVariable g_graphicsFullscreen; // enable fullscreen +extern CVariable g_graphicsYRes; +extern CVariable g_graphicsXRes; +extern CVariable g_graphicsBPP; + +// when loading S3TC-compressed texture files, do not pass them directly to +// OpenGL; instead, decompress them via software to regular textures. +// (necessary on JW's S3 laptop graphics card -- oh, the irony) +extern CVariable g_graphicsNoGLS3TC; + +// do not ask OpenGL to create mipmaps; instead, generate them in software +// and upload them all manually. (potentially helpful for PT's system, where +// Mesa falsely reports full S3TC support but isn't able to generate mipmaps +// for them) +extern CVariable g_graphicsNoGLAutoMipmap; + +// don't use VBOs. (RC: that was necessary on laptop Radeon cards) +extern CVariable g_graphicsNoGLVBO; + +// disable FBO extension in case the driver is flaky +extern CVariable g_graphicsNoGLFrameBufferObject; +extern CVariable g_graphicsFancyWater; +extern CVariable g_graphicsShadows; +extern CVariable g_graphicsVSync; +extern CVariable g_graphicsLodBias; +extern CVariable g_graphicsGamma; +extern CVariable g_graphicsEntGraph; +extern CVariable g_graphicsRenderPath; +extern CVariable g_graphicsShowPathFindingOverlay; +extern CVariable g_graphicsTriPathFind; + +// Linux only: Set the driconf force_s3tc_enable option at startup, +// for compressed texture support +extern CVariable g_graphicsForceS3TCEnabled; + +// GamePlay +extern CVariable g_gameQuickStart; +extern CVariable g_gameDisableWindowsKey; // disable windowskey +extern CVariable g_gameCursorName; +extern CVariable g_gameAutoStartMap; +extern CVariable g_gameActiveProfile; + +// Audio +extern CVariable g_audioDisableAudio; +extern CVariable g_audioMasterGain; +extern CVariable g_audioDisableMusic; +extern CVariable g_audioMusicVolume; + +// System +extern CVariable g_systemLanguage; +extern CVariable g_systemFontDefault; +extern CVariable g_systemFontConsole; +extern CVariable g_systemFontMisc; + + + + +#endif diff --git a/source/ps/ProfileViewer.cpp b/source/ps/ProfileViewer.cpp index f7787ed..82bd737 100644 --- a/source/ps/ProfileViewer.cpp +++ b/source/ps/ProfileViewer.cpp @@ -28,6 +28,7 @@ #include "ProfileViewer.h" #include "ps/CLogger.h" +#include "ps/PSOptions.h" #include "ps/Filesystem.h" #include "ps/Font.h" #include "ps/Hotkey.h" @@ -37,8 +38,6 @@ #include "lib/res/graphics/unifont.h" #include "renderer/Renderer.h" -extern int g_xres, g_yres; - struct CProfileViewerInternals { CProfileViewerInternals() {} @@ -186,16 +185,16 @@ void CProfileViewer::RenderProfile() glDisable(GL_TEXTURE_2D); glColor4ub(0,0,0,128); glBegin(GL_QUADS); - glVertex2i(0, g_yres); - glVertex2i(estimate_width, g_yres); - glVertex2i(estimate_width, g_yres-estimate_height); - glVertex2i(0, g_yres-estimate_height); + glVertex2i(0, g_graphicsYRes); + glVertex2i(estimate_width, g_graphicsYRes); + glVertex2i(estimate_width, g_graphicsYRes-estimate_height); + glVertex2i(0, g_graphicsYRes-estimate_height); glEnd(); glEnable(GL_TEXTURE_2D); // Print table and column titles glPushMatrix(); - glTranslatef(2.0f, g_yres - lineSpacing, 0.0f ); + glTranslatef(2.0f, g_graphicsYRes - lineSpacing, 0.0f ); glScalef(1.0f, -1.0f, 1.0f); glColor3ub(255, 255, 255); diff --git a/source/ps/Util.cpp b/source/ps/Util.cpp index 1504ed1..047ac1f 100644 --- a/source/ps/Util.cpp +++ b/source/ps/Util.cpp @@ -33,7 +33,7 @@ #include "lib/tex/tex.h" #include "lib/file/io/io_align.h" // BLOCK_SIZE -#include "ps/GameSetup/Config.h" +#include "ps/PSOptions.h" #include "ps/GameSetup/GameSetup.h" #include "ps/Game.h" #include "ps/Filesystem.h" @@ -231,7 +231,7 @@ void WriteScreenshot(const std::wstring& extension) VfsPath filename; fs_util::NextNumberedFilename(g_VFS, filenameFormat, s_nextScreenshotNumber, filename); - const size_t w = (size_t)g_xres, h = (size_t)g_yres; + const size_t w = (size_t)g_graphicsXRes, h = (size_t)g_graphicsYRes; const size_t bpp = 24; GLenum fmt = GL_RGB; int flags = TEX_BOTTOM_UP; @@ -273,7 +273,7 @@ void WriteBigScreenshot(const std::wstring& extension, int tiles) // Slightly ugly and inflexible: Always draw 640*480 tiles onto the screen, and // hope the screen is actually large enough for that. const int tile_w = 640, tile_h = 480; - debug_assert(g_xres >= tile_w && g_yres >= tile_h); + debug_assert(g_graphicsXRes >= tile_w && g_graphicsYRes >= tile_h); const int img_w = tile_w*tiles, img_h = tile_h*tiles; const int bpp = 24; @@ -359,8 +359,8 @@ void WriteBigScreenshot(const std::wstring& extension, int tiles) // Restore the viewport settings { - g_Renderer.Resize(g_xres, g_yres); - SViewPort vp = { 0, 0, g_xres, g_yres }; + g_Renderer.Resize(g_graphicsXRes, g_graphicsYRes); + SViewPort vp = { 0, 0, g_graphicsXRes, g_graphicsYRes }; g_Game->GetView()->GetCamera()->SetViewPort(vp); g_Game->GetView()->GetCamera()->SetProjection(CGameView::defaultNear, CGameView::defaultFar, CGameView::defaultFOV); diff --git a/source/ps/VideoMode.cpp b/source/ps/VideoMode.cpp index f1ded0b..4f72e87 100644 --- a/source/ps/VideoMode.cpp +++ b/source/ps/VideoMode.cpp @@ -28,6 +28,7 @@ #include "ps/CConsole.h" #include "ps/CLogger.h" #include "ps/ConfigDB.h" +#include "ps/PSOptions.h" #include "ps/Game.h" #include "ps/GameSetup/Config.h" #include "renderer/Renderer.h" @@ -43,25 +44,12 @@ CVideoMode g_VideoMode; CVideoMode::CVideoMode() : m_IsInitialised(false), m_PreferredW(0), m_PreferredH(0), m_PreferredBPP(0), m_PreferredFreq(0), - m_ConfigW(0), m_ConfigH(0), m_ConfigBPP(0), m_ConfigFullscreen(false), m_ConfigForceS3TCEnable(true), m_WindowedW(DEFAULT_WINDOW_W), m_WindowedH(DEFAULT_WINDOW_H) { // (m_ConfigFullscreen defaults to false, so users don't get stuck if // e.g. half the filesystem is missing and the config files aren't loaded) } -void CVideoMode::ReadConfig() -{ - bool windowed = !m_ConfigFullscreen; - CFG_GET_USER_VAL("windowed", Bool, windowed); - m_ConfigFullscreen = !windowed; - - CFG_GET_USER_VAL("xres", Int, m_ConfigW); - CFG_GET_USER_VAL("yres", Int, m_ConfigH); - CFG_GET_USER_VAL("bpp", Int, m_ConfigBPP); - CFG_GET_USER_VAL("force_s3tc_enable", Bool, m_ConfigForceS3TCEnable); -} - bool CVideoMode::SetVideoMode(int w, int h, int bpp, bool fullscreen) { Uint32 flags = SDL_OPENGL; @@ -97,15 +85,13 @@ bool CVideoMode::SetVideoMode(int w, int h, int bpp, bool fullscreen) else SDL_WM_GrabInput(SDL_GRAB_OFF); - m_IsFullscreen = fullscreen; - // Grab the current video settings m_CurrentW = screen->w; m_CurrentH = screen->h; m_CurrentBPP = bpp; // getting bpp from surface not supported in wsdl - g_xres = m_CurrentW; - g_yres = m_CurrentH; + g_graphicsXRes = m_CurrentW; + g_graphicsYRes = m_CurrentH; return true; } @@ -114,18 +100,16 @@ bool CVideoMode::InitSDL() { debug_assert(!m_IsInitialised); - ReadConfig(); - EnableS3TC(); // preferred video mode = current desktop settings // (command line params may override these) gfx_get_video_mode(&m_PreferredW, &m_PreferredH, &m_PreferredBPP, &m_PreferredFreq); - int w = m_ConfigW; - int h = m_ConfigH; + int w = g_graphicsXRes; + int h = g_graphicsYRes; - if (m_ConfigFullscreen) + if (g_graphicsFullscreen) { // If fullscreen and no explicit size set, default to the desktop resolution if (w == 0 || h == 0) @@ -146,15 +130,15 @@ bool CVideoMode::InitSDL() SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); - SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, g_VSync ? 1 : 0); + SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, g_graphicsVSync ? 1 : 0); - if (!SetVideoMode(w, h, bpp, m_ConfigFullscreen)) + if (!SetVideoMode(w, h, bpp, g_graphicsFullscreen)) { // Fall back to a smaller depth buffer // (The rendering may be ugly but this helps when running in VMware) SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16); - if (!SetVideoMode(w, h, bpp, m_ConfigFullscreen)) + if (!SetVideoMode(w, h, bpp, g_graphicsFullscreen)) return false; } @@ -171,12 +155,12 @@ bool CVideoMode::InitSDL() ogl_Init(); // required after each mode change // (TODO: does that mean we need to call this when toggling fullscreen later?) - if (SDL_SetGamma(g_Gamma, g_Gamma, g_Gamma) < 0) + if (SDL_SetGamma(g_graphicsGamma, g_graphicsGamma, g_graphicsGamma) < 0) LOGWARNING(L"SDL_SetGamma failed"); m_IsInitialised = true; - if (!m_ConfigFullscreen) + if (!g_graphicsFullscreen) { m_WindowedW = w; m_WindowedH = h; @@ -189,8 +173,6 @@ bool CVideoMode::InitNonSDL() { debug_assert(!m_IsInitialised); - ReadConfig(); - EnableS3TC(); m_IsInitialised = true; @@ -215,7 +197,7 @@ void CVideoMode::EnableS3TC() // so we just unconditionally set it (unless our config file explicitly disables it). #if !(OS_WIN || OS_MACOSX) // (assume Mesa is used for all non-Windows non-Mac platforms) - if (m_ConfigForceS3TCEnable) + if (g_graphicsForceS3TCEnabled) setenv("force_s3tc_enable", "true", 0); #endif } @@ -225,7 +207,7 @@ bool CVideoMode::ResizeWindow(int w, int h) debug_assert(m_IsInitialised); // Ignore if not windowed - if (m_IsFullscreen) + if (g_graphicsFullscreen) return true; // Ignore if the size hasn't changed @@ -250,20 +232,20 @@ bool CVideoMode::SetFullscreen(bool fullscreen) debug_assert(m_IsInitialised); // Check whether this is actually a change - if (fullscreen == m_IsFullscreen) + if (fullscreen == g_graphicsFullscreen) return true; - if (!m_IsFullscreen) + if (!g_graphicsFullscreen) { // Windowed -> fullscreen: int w = 0, h = 0; // If a fullscreen size was configured, use that; else use the desktop size; else use a default - if (m_ConfigFullscreen) + if (g_graphicsFullscreen) { - w = m_ConfigW; - h = m_ConfigH; + w = g_graphicsXRes; + h = g_graphicsYRes; } if (w == 0 || h == 0) { @@ -305,7 +287,7 @@ bool CVideoMode::SetFullscreen(bool fullscreen) bool CVideoMode::ToggleFullscreen() { - return SetFullscreen(!m_IsFullscreen); + return SetFullscreen(!g_graphicsFullscreen); } void CVideoMode::UpdateRenderer(int w, int h) @@ -313,8 +295,8 @@ void CVideoMode::UpdateRenderer(int w, int h) if (w < 2) w = 2; // avoid GL errors caused by invalid sizes if (h < 2) h = 2; - g_xres = w; - g_yres = h; + g_graphicsXRes = w; + g_graphicsYRes = h; SViewPort vp = { 0, 0, w, h }; @@ -331,8 +313,9 @@ void CVideoMode::UpdateRenderer(int w, int h) int CVideoMode::GetBestBPP() { - if (m_ConfigBPP) - return m_ConfigBPP; + if (g_graphicsBPP) + return g_graphicsBPP; + if (m_PreferredBPP) return m_PreferredBPP; return 32; @@ -341,17 +324,17 @@ int CVideoMode::GetBestBPP() int CVideoMode::GetXRes() { debug_assert(m_IsInitialised); - return m_CurrentW; + return g_graphicsXRes; } int CVideoMode::GetYRes() { debug_assert(m_IsInitialised); - return m_CurrentH; + return g_graphicsYRes; } int CVideoMode::GetBPP() { debug_assert(m_IsInitialised); - return m_CurrentBPP; + return g_graphicsBPP; } diff --git a/source/ps/VideoMode.h b/source/ps/VideoMode.h index 507bb85..b496ade 100644 --- a/source/ps/VideoMode.h +++ b/source/ps/VideoMode.h @@ -62,7 +62,7 @@ public: int GetBPP(); private: - void ReadConfig(); + int GetBestBPP(); bool SetVideoMode(int w, int h, int bpp, bool fullscreen); void EnableS3TC(); @@ -75,21 +75,11 @@ private: int m_PreferredBPP; int m_PreferredFreq; - // Config file settings (0 if unspecified) - int m_ConfigW; - int m_ConfigH; - int m_ConfigBPP; - bool m_ConfigFullscreen; - bool m_ConfigForceS3TCEnable; - // If we're fullscreen, size of window when we were last windowed (or the default window size // if we started fullscreen), to support switching back to the old window size int m_WindowedW; int m_WindowedH; - // Whether we're currently being displayed fullscreen - bool m_IsFullscreen; - // The last mode selected int m_CurrentW; int m_CurrentH; diff --git a/source/scripting/ScriptGlue.cpp b/source/scripting/ScriptGlue.cpp index d652481..909a905 100644 --- a/source/scripting/ScriptGlue.cpp +++ b/source/scripting/ScriptGlue.cpp @@ -43,6 +43,7 @@ #include "network/NetServer.h" #include "ps/CConsole.h" #include "ps/CLogger.h" +#include "ps/PSOptions.h" #include "ps/CStr.h" #include "ps/Game.h" #include "ps/Globals.h" // g_frequencyFilter @@ -444,6 +445,15 @@ JSBool GetRenderer( JSContext* UNUSED(cx), JSObject* UNUSED(obj), jsval UNUSED(i return( JS_TRUE ); } +JSBool GetOptions( JSContext* UNUSED(cx), JSObject* UNUSED(obj), jsval UNUSED(id), jsval* vp ) +{ + if (PSOptions::IsInitialised()) + *vp = OBJECT_TO_JSVAL( g_PSOptions.GetScript() ); + else + *vp = JSVAL_NULL; + return( JS_TRUE ); +} + enum ScriptGlobalTinyIDs { @@ -461,6 +471,7 @@ JSPropertySpec ScriptGlobalTable[] = { "lightenv" , GLOBAL_LIGHTENV, JSPROP_PERMANENT, JSI_LightEnv::getLightEnv, JSI_LightEnv::setLightEnv }, { "gameView" , 0, JSPROP_PERMANENT|JSPROP_READONLY, GetGameView, 0 }, { "renderer" , 0, JSPROP_PERMANENT|JSPROP_READONLY, GetRenderer, 0 }, + { "options" , 0, JSPROP_PERMANENT|JSPROP_READONLY, GetOptions, 0 }, // end of table marker { 0, 0, 0, 0, 0 }, diff --git a/source/scriptinterface/ScriptConversions.cpp b/source/scriptinterface/ScriptConversions.cpp index d2ec1df..e3593d1 100644 --- a/source/scriptinterface/ScriptConversions.cpp +++ b/source/scriptinterface/ScriptConversions.cpp @@ -18,6 +18,7 @@ #include "precompiled.h" #include "ScriptInterface.h" +#include "ps/CStr.h" #include "ps/utf16string.h" #include "ps/CLogger.h" @@ -92,6 +93,31 @@ template<> bool ScriptInterface::FromJSVal(JSContext* cx, jsva return true; } +template<> bool ScriptInterface::FromJSVal(JSContext* cx, jsval v, CStrW& out) +{ + WARN_IF_NOT(JSVAL_IS_STRING(v)); + JSString* ret = JS_ValueToString(cx, v); + if (!ret) + FAIL("Argument must be convertible to a string"); + jschar* ch = JS_GetStringChars(ret); + out = std::wstring(ch, ch + JS_GetStringLength(ret)); + return true; +} + +template<> bool ScriptInterface::FromJSVal(JSContext* cx, jsval v, CStr& out) +{ + WARN_IF_NOT(JSVAL_IS_STRING(v)); + JSString* ret = JS_ValueToString(cx, v); + if (!ret) + FAIL("Argument must be convertible to a string"); + char* ch = JS_GetStringBytes(ret); + out = std::string(ch, ch + JS_GetStringLength(ret)); + // TODO: if JS_GetStringBytes fails it'll return a zero-length string + // and we'll overflow its bounds by using JS_GetStringLength - should + // use one of the new SpiderMonkey 1.8 functions instead + return true; +} + template<> bool ScriptInterface::FromJSVal(JSContext* cx, jsval v, std::wstring& out) { WARN_IF_NOT(JSVAL_IS_STRING(v)); diff --git a/source/simulation2/components/CCmpObstructionManager.cpp b/source/simulation2/components/CCmpObstructionManager.cpp index 0419d1c..15c943b 100644 --- a/source/simulation2/components/CCmpObstructionManager.cpp +++ b/source/simulation2/components/CCmpObstructionManager.cpp @@ -712,7 +712,7 @@ void CCmpObstructionManager::GetObstructionsInRange(const IObstructionTestFilter } } -bool CCmpObstructionManager::FindMostImportantObstruction(const IObstructionTestFilter& filter, entity_pos_t x, entity_pos_t z, entity_pos_t r, ObstructionSquare& square) +bool CCmpObstructionManager::FindMostImportantObstruction(const IObstructionTestFilter& filter, entity_pos_t x, entity_pos_t z, entity_pos_t UNUSED(r), ObstructionSquare& square) { std::vector squares; diff --git a/source/sound/JSI_Sound.cpp b/source/sound/JSI_Sound.cpp index a527394..a691ac7 100644 --- a/source/sound/JSI_Sound.cpp +++ b/source/sound/JSI_Sound.cpp @@ -22,6 +22,7 @@ #include "lib/res/sound/snd_mgr.h" #include "lib/res/h_mgr.h" // h_filename #include "ps/Filesystem.h" +#include "ps/PSOptions.h" JSI_Sound::JSI_Sound(const VfsPath& pathname) @@ -128,6 +129,22 @@ bool JSI_Sound::Fade(JSContext* cx, uintN argc, jsval* argv) return true; } +bool JSI_Sound::SetDisable(JSContext* cx, uintN argc, jsval* argv) { + if (! m_Handle) + return false; + + bool disabled = false; + if (!ToPrimitive(cx, argv[0], disabled)) + return false; + + if (disabled) + (void)snd_set_gain(m_Handle, 0.0f); + else + (void)snd_set_gain(m_Handle, g_audioMusicVolume); + + return true; +} + // start playing the sound (one-shot). // it will automatically be freed when done. bool JSI_Sound::Play(JSContext* UNUSED(cx), uintN UNUSED(argc), jsval* UNUSED(argv)) @@ -181,6 +198,7 @@ void JSI_Sound::ScriptingInit() AddMethod("setPitch", 0); AddMethod("setPosition", 0); AddMethod("fade", 0); + AddMethod("setDisabled", 0); CJSObject::ScriptingInit("Sound", &JSI_Sound::Construct, 1); } diff --git a/source/sound/JSI_Sound.h b/source/sound/JSI_Sound.h index 2b6c3ca..9ee27e2 100644 --- a/source/sound/JSI_Sound.h +++ b/source/sound/JSI_Sound.h @@ -70,6 +70,8 @@ public: bool Fade ( JSContext* cx, uintN argc, jsval* argv ); + bool SetDisable (JSContext* cx, uintN argc, jsval* argv); + static JSBool Construct( JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval ); static void ScriptingInit(); diff --git a/source/tools/atlas/GameInterface/ActorViewer.cpp b/source/tools/atlas/GameInterface/ActorViewer.cpp index d2f236d..c613e3d 100644 --- a/source/tools/atlas/GameInterface/ActorViewer.cpp +++ b/source/tools/atlas/GameInterface/ActorViewer.cpp @@ -32,7 +32,7 @@ #include "graphics/UnitManager.h" #include "maths/MathUtil.h" #include "ps/Font.h" -#include "ps/GameSetup/Config.h" +#include "ps/PSOptions.h" #include "ps/ProfileViewer.h" #include "renderer/Renderer.h" #include "renderer/Scene.h" @@ -314,7 +314,7 @@ void ActorViewer::Render() glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); - glOrtho(0.f, (float)g_xres, 0.f, (float)g_yres, -1.f, 1000.f); + glOrtho(0.f, (float)g_graphicsXRes, 0.f, (float)g_graphicsYRes, -1.f, 1000.f); glMatrixMode(GL_MODELVIEW); glPushMatrix(); diff --git a/source/tools/atlas/GameInterface/Handlers/GraphicsSetupHandlers.cpp b/source/tools/atlas/GameInterface/Handlers/GraphicsSetupHandlers.cpp index 978f01e..c3dc279 100644 --- a/source/tools/atlas/GameInterface/Handlers/GraphicsSetupHandlers.cpp +++ b/source/tools/atlas/GameInterface/Handlers/GraphicsSetupHandlers.cpp @@ -29,6 +29,7 @@ #include "lib/external_libraries/sdl.h" #include "maths/MathUtil.h" #include "ps/CConsole.h" +#include "ps/PSOptions.h" #include "ps/Game.h" #include "ps/VideoMode.h" #include "ps/GameSetup/Config.h" @@ -43,7 +44,7 @@ MESSAGEHANDLER(Init) { UNUSED2(msg); - g_Quickstart = true; + g_gameQuickStart = true; Init(g_GameLoop->args, g_InitFlags); diff --git a/source/tools/atlas/GameInterface/Handlers/MiscHandlers.cpp b/source/tools/atlas/GameInterface/Handlers/MiscHandlers.cpp index fc32629..5963b50 100644 --- a/source/tools/atlas/GameInterface/Handlers/MiscHandlers.cpp +++ b/source/tools/atlas/GameInterface/Handlers/MiscHandlers.cpp @@ -30,7 +30,7 @@ #include "maths/MathUtil.h" #include "ps/Game.h" #include "ps/Util.h" -#include "ps/GameSetup/Config.h" +#include "ps/PSOptions.h" #include "ps/GameSetup/GameSetup.h" #include "renderer/Renderer.h" @@ -110,8 +110,8 @@ QUERYHANDLER(CinemaRecord) // Restore viewport { - g_Renderer.Resize(g_xres, g_yres); - SViewPort vp = { 0, 0, g_xres, g_yres }; + g_Renderer.Resize(g_graphicsXRes, g_graphicsYRes); + SViewPort vp = { 0, 0, g_graphicsXRes, g_graphicsYRes }; g_Game->GetView()->GetCamera()->SetViewPort(vp); g_Game->GetView()->GetCamera()->SetProjection(CGameView::defaultNear, CGameView::defaultFar, CGameView::defaultFOV); } @@ -161,8 +161,8 @@ MESSAGEHANDLER(GuiMouseButtonEvent) ev.ev.button.state = msg->pressed ? SDL_PRESSED : SDL_RELEASED; float x, y; msg->pos->GetScreenSpace(x, y); - ev.ev.button.x = (u16)clamp((int)x, 0, g_xres); - ev.ev.button.y = (u16)clamp((int)y, 0, g_yres); + ev.ev.button.x = (u16)clamp((int)x, 0, g_graphicsXRes.Get()); + ev.ev.button.y = (u16)clamp((int)y, 0, g_graphicsYRes.Get()); in_dispatch_event(&ev); } @@ -172,8 +172,8 @@ MESSAGEHANDLER(GuiMouseMotionEvent) ev.ev.type = SDL_MOUSEMOTION; float x, y; msg->pos->GetScreenSpace(x, y); - ev.ev.motion.x = (u16)clamp((int)x, 0, g_xres); - ev.ev.motion.y = (u16)clamp((int)y, 0, g_yres); + ev.ev.motion.x = (u16)clamp((int)x, 0, g_graphicsXRes.Get()); + ev.ev.motion.y = (u16)clamp((int)y, 0, g_graphicsYRes.Get()); in_dispatch_event(&ev); } diff --git a/source/tools/atlas/GameInterface/Handlers/ObjectHandlers.cpp b/source/tools/atlas/GameInterface/Handlers/ObjectHandlers.cpp index 21a86bc..2d8f18a 100644 --- a/source/tools/atlas/GameInterface/Handlers/ObjectHandlers.cpp +++ b/source/tools/atlas/GameInterface/Handlers/ObjectHandlers.cpp @@ -234,7 +234,7 @@ BEGIN_COMMAND(SetObjectSettings) } private: - void Set(player_id_t player, const std::set& selections) + void Set(player_id_t player, const std::set& UNUSED(selections)) { View* view = View::GetView(msg->view); CSimulation2* simulation = view->GetSimulation2(); diff --git a/source/tools/atlas/GameInterface/View.cpp b/source/tools/atlas/GameInterface/View.cpp index a9b9beb..4869ecb 100644 --- a/source/tools/atlas/GameInterface/View.cpp +++ b/source/tools/atlas/GameInterface/View.cpp @@ -31,6 +31,7 @@ #include "lib/timer.h" #include "lib/utf8.h" #include "ps/Game.h" +#include "ps/PSOptions.h" #include "ps/GameSetup/GameSetup.h" #include "ps/World.h" #include "renderer/Renderer.h" @@ -41,8 +42,6 @@ extern void (*Atlas_GLSwapBuffers)(void* context); -extern int g_xres, g_yres; - ////////////////////////////////////////////////////////////////////////// void View::SetParam(const std::wstring& UNUSED(name), bool UNUSED(value)) @@ -76,7 +75,7 @@ void ViewActor::Update(float frameLength) void ViewActor::Render() { - SViewPort vp = { 0, 0, g_xres, g_yres }; + SViewPort vp = { 0, 0, g_graphicsXRes, g_graphicsYRes }; CCamera& camera = GetCamera(); camera.SetViewPort(vp); camera.SetProjection(CGameView::defaultNear, CGameView::defaultFar, CGameView::defaultFOV); @@ -209,7 +208,7 @@ void ViewGame::Update(float frameLength) void ViewGame::Render() { - SViewPort vp = { 0, 0, g_xres, g_yres }; + SViewPort vp = { 0, 0, g_graphicsXRes, g_graphicsYRes }; CCamera& camera = GetCamera(); camera.SetViewPort(vp); camera.SetProjection(CGameView::defaultNear, CGameView::defaultFar, CGameView::defaultFOV);