Mercurial > projects > mde
changeset 21:a60cbb7359dd
Window settings now come from options, and may use OpenGL (enabled/disabled at compile time).
committer: Diggory Hardy <diggory.hardy@gmail.com>
author | Diggory Hardy <diggory.hardy@gmail.com> |
---|---|
date | Mon, 24 Mar 2008 17:53:28 +0000 |
parents | 838577503598 |
children | 249eb6620685 |
files | codeDoc/jobs.txt data/conf/options.mtt mde/SDL.d mde/events.d mde/mde.d mde/options.d mde/scheduler/Init.d mde/scheduler/InitStage.d |
diffstat | 8 files changed, 111 insertions(+), 36 deletions(-) [+] |
line wrap: on
line diff
--- a/codeDoc/jobs.txt Sat Mar 22 16:22:59 2008 +0000 +++ b/codeDoc/jobs.txt Mon Mar 24 17:53:28 2008 +0000 @@ -41,3 +41,4 @@ Done (for git log message): +Window settings now come from options. \ No newline at end of file
--- a/data/conf/options.mtt Sat Mar 22 16:22:59 2008 +0000 +++ b/data/conf/options.mtt Mon Mar 24 17:53:28 2008 +0000 @@ -3,3 +3,12 @@ <char[]|L10n="en-GB"> <bool|useThreads=true> <int|logLevel=1> + +{video} +<bool|noFrame=false> +<bool|resizable=false> +<bool|hardware=true> +<bool|fullscreen=true> +<int|height=1024> +<int|width=1280> +
--- a/mde/SDL.d Sat Mar 22 16:22:59 2008 +0000 +++ b/mde/SDL.d Mon Mar 24 17:53:28 2008 +0000 @@ -19,6 +19,7 @@ import mde.scheduler.InitStage; import mde.input.joystick; +import mde.options; import tango.util.log.Log : Log, Logger; import tango.stdc.stringz; @@ -36,6 +37,8 @@ } void initSdlAndGl() { // init2 func + logger.trace ("init2: initSdlAndGl() started"); + // Load SDL and GL dynamic libs try { DerelictSDL.load(); @@ -44,7 +47,7 @@ logger.fatal ("Loading dynamic library failed:"); logger.fatal (de.msg); - init2.setFailure (); + setInitFailure (); return; } logger.trace ("Derelict: loaded SDL and OpenGL"); @@ -55,7 +58,7 @@ char* msg = SDL_GetError (); logger.fatal (msg ? fromStringz(msg) : "no reason available"); - init2.setFailure (); + setInitFailure (); return; } @@ -65,23 +68,56 @@ // Must be called after SDL has been initialised, so cannot be a separate Init function. openJoysticks (); // after SDL init cleanup2.addFunc (&closeJoysticks); + + logger.trace ("init2: initSdlAndGl() finished"); } void setupWindow() { // init4 func + logger.trace ("init4: setupWindow() started"); + + // Window creation flags + /* NOTE: I'm getting an API mismatch error from the nvidia driver when using OpenGL, + * thus I've temporarily disabled it. */ + version (MDE_OPENGL) uint flags = SDL_OPENGL; + else uint flags = 0; + if (Options.video.fullscreen) flags |= SDL_FULLSCREEN; + else { + if (Options.video.resizable) flags |= SDL_RESIZABLE; + if (Options.video.noFrame) flags |= SDL_NOFRAME; + } + if (Options.video.hardware) flags |= SDL_HWSURFACE | SDL_DOUBLEBUF; + else flags |= SDL_SWSURFACE; + + version (MDE_OPENGL) { + // OpenGL attributes + SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8); + SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8); + SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8); + SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16); + SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER,1); + } + // Open a window - // FIXME: provide a way to re-set video mode and change settings - if (SDL_SetVideoMode (800, 600, 0, 0) is null) { // Can't open in windows!! + if (SDL_SetVideoMode (Options.video.width, Options.video.height, 32, flags) is null) { logger.fatal ("Unable to set video mode:"); char* msg = SDL_GetError (); logger.fatal (msg ? fromStringz(msg) : "no reason available"); - init4.setFailure (); + setInitFailure (); return; } + + // Window-manager settings + SDL_WM_SetCaption (toStringz ("mde"), null); + // SDL_WM_GrabInput (use later) + + logger.trace ("init4: setupWindow() finished"); } -void cleanupSDL () { +void cleanupSDL () { // cleanup2 func + logger.trace ("cleanup2: cleanupSDL() started"); SDL_Quit(); + logger.trace ("cleanup2: cleanupSDL() finished"); } /+ Load of info-printing stuff (currently doesn't have a use)
--- a/mde/events.d Sat Mar 22 16:22:59 2008 +0000 +++ b/mde/events.d Mon Mar 24 17:53:28 2008 +0000 @@ -36,14 +36,18 @@ } void initInput () { // init2 func + logger.trace ("init2: initInput() started"); + try { global.input = new Input(); global.input.loadConfig (); // (may also create instance) Scheduler.perFrame (&pollEvents); } catch (Exception e) { - init2.setFailure (); // must clean up properly + setInitFailure (); // must clean up properly } + + logger.trace ("init2: initInput() finished"); } void pollEvents (double) {
--- a/mde/mde.d Sat Mar 22 16:22:59 2008 +0000 +++ b/mde/mde.d Mon Mar 24 17:53:28 2008 +0000 @@ -44,7 +44,8 @@ //BEGIN Initialisation Logger logger = Log.getLogger ("mde.mde"); logger.info ("Starting mde..."); - + + scope Init init; try { init = new Init(); // initialisation } catch (InitException e) {
--- a/mde/options.d Sat Mar 22 16:22:59 2008 +0000 +++ b/mde/options.d Mon Mar 24 17:53:28 2008 +0000 @@ -79,6 +79,7 @@ //BEGIN Static // Each individual section static OptionsMisc misc; + static OptionsVideo video; /* Load/save options from file. * @@ -88,7 +89,8 @@ static void load () { // Create all uncreated sections now, so that if we return early they are still created. if (misc is null) misc = new OptionsMisc; - + if (video is null) video = new OptionsVideo; + // Check it exists (if not it should still be created on exit). // Don't bother checking it's not a folder, because it could still be a block or something. if (!confDir.exists (fileName)) return; @@ -100,6 +102,7 @@ /* Recognise each defined section, and return null for unrecognised sections. */ if (id == cast(ID) "misc") return misc; + else if (id == cast(ID) "video") return video; else return null; }; reader.read; @@ -108,12 +111,11 @@ logger.error (e.msg); throw new optionsLoadException ("Loading aborted: mergetag exception"); } - - if (misc is null) throw new optionsLoadException ("Loading failed: section \"misc\" not found"); } static void save () { DataSet ds = new DataSet(); ds.sec[cast(ID) "misc"] = misc; + ds.sec[cast(ID) "video"] = video; IWriter writer; try { @@ -146,3 +148,17 @@ optsInt = ["logLevel":&logLevel]; } } + +/** All video options. */ +class OptionsVideo : Options { + int width, height; // screen/window dimensions + bool fullscreen; + bool resizable; // when not fullscreen, window can be resized + bool noFrame; // when not fullscreen, don't draw the window decorations + bool hardware; // use a hardware surface. Relevant with OpenGL? + + this () { + optsBool = ["fullscreen"[]:&fullscreen, "hardware":&hardware, "noFrame":&noFrame, "resizable":&resizable]; + optsInt = ["height"[]:&height, "width":&width]; + } +}
--- a/mde/scheduler/Init.d Sat Mar 22 16:22:59 2008 +0000 +++ b/mde/scheduler/Init.d Mon Mar 24 17:53:28 2008 +0000 @@ -84,9 +84,6 @@ { } -// Global instance, since called init functions need to interact: -scope Init init; - /** * Init class * @@ -138,22 +135,26 @@ * Current method is to try using threads, and on failure assume no threads were actually * created and run functions in a non-threaded manner. */ - try { // init2 - cleanupStages ~= &cleanup2; // add appropriate cleanup stage - + // init2 + cleanupStages ~= &cleanup2; // add appropriate cleanup stage + try { + logger.trace ("Init: init2"); if (runStageThreaded (init2)) runStageForward (init2); } catch (InitStageException) { // This init stage failed. + logger.trace ("Init: init2 failed"); runCleanupStages(); throw new InitException ("Initialisation failed during stage init2"); } - try { // init4 - cleanupStages ~= &cleanup4; // add appropriate cleanup stage - + // init4 + cleanupStages ~= &cleanup4; // add appropriate cleanup stage + try { + logger.trace ("Init: init4"); if (runStageThreaded (init4)) runStageForward (init4); } catch (InitStageException) { // This init stage failed. + logger.trace ("Init: init4 failed"); runCleanupStages(); throw new InitException ("Initialisation failed during stage init4"); } @@ -181,24 +182,25 @@ private static { /* The following three functions, runStage*, each run all functions in a stage in some order, * catching any exceptions thrown by the functions (although this isn't guaranteed for threads), - * and throw an InitStageException on failure. */ + * and throw an InitStageException on initFailure. */ const UFE = "Unhandled exception from Init function:"; /* Runs all functions consecutively, first-to-last. * If any function fails, halts immediately. */ void runStageForward (InitStage s) { foreach (func; s.funcs) { - if (s.failure) break; + if (initFailure) break; try { func(); } catch (Exception e) { logger.fatal (UFE); logger.fatal (e.msg); - s.setFailure(); + setInitFailure(); } } - if (s.failure) throw new InitStageException; // Problem running; abort and cleanup from here. + + if (initFailure) throw new InitStageException; // Problem running; abort and cleanup from here. } /* Runs all functions consecutively, last-to-first. * If any function fails, continue until all have been run. */ @@ -210,10 +212,10 @@ logger.fatal (UFE); logger.fatal (e.msg); - s.setFailure(); + setInitFailure(); } } - if (s.failure) throw new InitStageException; // Problem running; abort and cleanup from here. + if (initFailure) throw new InitStageException; // Problem running; abort and cleanup from here. } /* Tries running functions in a threaded way. Returns false if successful, true if not but * functions should be run without threads. */ @@ -247,11 +249,11 @@ logger.fatal ("Unhandled exception from Init function:"); logger.fatal (e.msg); - s.setFailure (); // abort (but join other threads first) + setInitFailure (); // abort (but join other threads first) } } - - if (s.failure) throw new InitStageException; // Problem running; abort and cleanup from here. + + if (initFailure) throw new InitStageException; // Problem running; abort and cleanup from here. return false; // Done successfully } }
--- a/mde/scheduler/InitStage.d Sat Mar 22 16:22:59 2008 +0000 +++ b/mde/scheduler/InitStage.d Mon Mar 24 17:53:28 2008 +0000 @@ -21,6 +21,12 @@ */ module mde.scheduler.InitStage; +import tango.util.log.Log : Log, Logger; +private Logger logger; +static this() { + logger = Log.getLogger ("mde.scheduler.InitStage"); +} + /** Represents all functions to be called for a particular init stage. * * No code is included here to run the functions intentionally, to keep dependancies minimal. @@ -40,13 +46,7 @@ funcs ~= f; } - /** Should be called by an init function when a failure occurs. */ - void setFailure () { - synchronized failure = true; - } - - package InitFunction[] funcs = []; - package bool failure = false; + package InitFunction[] funcs = []; } /** Init can be divided up into these stages, each run in order: @@ -87,3 +87,9 @@ InitStage init4; /// ditto InitStage cleanup2; /// ditto InitStage cleanup4; /// ditto + +/** Should be called by an init function when a failure occurs. */ +void setInitFailure () { + initFailure = true; +} +package bool initFailure = false;