diff mde/setup/sdl.d @ 63:66d555da083e

Moved many modules/packages to better reflect usage.
author Diggory Hardy <diggory.hardy@gmail.com>
date Fri, 27 Jun 2008 18:35:33 +0100
parents mde/sdl.d@f3d8c0441408
children cc3763817b8a
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mde/setup/sdl.d	Fri Jun 27 18:35:33 2008 +0100
@@ -0,0 +1,195 @@
+/* LICENSE BLOCK
+Part of mde: a Modular D game-oriented Engine
+Copyright © 2007-2008 Diggory Hardy
+
+This program 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.
+
+This program 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 this program.  If not, see <http://www.gnu.org/licenses/>. */
+
+/** Just a temporary place to put SDL Init and Video stuff.
+*/
+module mde.setup.sdl;
+
+import mde.setup.initFunctions;
+import mde.input.joystick;
+import mde.lookup.Options;
+import mde.gl.basic;
+import imde = mde.imde;
+
+import tango.util.log.Log : Log, Logger;
+import tango.stdc.stringz;
+
+import derelict.sdl.sdl;
+import derelict.opengl.gl;	// for loading a later gl version
+import derelict.util.exception;
+
+private Logger logger;
+static this() {
+    logger = Log.getLogger ("mde.setup.sdl");
+    
+    init.addFunc (&initSdlAndGl, "initSdlAndGl");
+}
+
+private uint flags = 0;
+
+void initSdlAndGl() {   // init func
+    // Initialise SDL
+    if (SDL_Init (SDL_INIT_VIDEO | SDL_INIT_JOYSTICK /+| SDL_INIT_EVENTTHREAD+/)) {
+        logger.fatal ("SDL initialisation failed:");
+        char* msg = SDL_GetError ();
+        logger.fatal (msg ? fromStringz(msg) : "no reason available");
+        
+        setInitFailure ();
+        return;
+    }
+    
+    debug logger.trace ("SDL initialised");
+    
+    // Must be called after SDL has been initialised, so cannot be a separate Init function.
+    openJoysticks ();                   // after SDL init
+    cleanup.addFunc (&cleanupSDL, "cleanupSDL");
+    
+    setupWindow();
+}
+
+void setupWindow() {    // indirect init func (depends on initSdlAndGl)
+    // Window creation flags and size
+    flags = SDL_OPENGL;
+    if (vidOpts.hardware) flags |= SDL_HWSURFACE | SDL_DOUBLEBUF;
+    else flags |= SDL_SWSURFACE;
+    int w, h;
+    if (vidOpts.fullscreen) {
+        flags |= SDL_FULLSCREEN;
+        w = vidOpts.screenW;
+        h = vidOpts.screenH;
+    }
+    else {
+        if (vidOpts.resizable) flags |= SDL_RESIZABLE;
+        if (vidOpts.noFrame) flags |= SDL_NOFRAME;
+        w = vidOpts.windowW;
+        h = vidOpts.windowH;
+    }
+    
+    // OpenGL attributes
+    SDL_GL_SetAttribute(SDL_GL_RED_SIZE,    5);
+    SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE,  6);
+    SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE,   5);
+    SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE,  16);
+    SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER,1);
+    
+    // Open a window
+    debug logger.trace ("Opening a window (this can crash if the libraries are messed up)");
+    if (SDL_SetVideoMode (w, h, 32, flags) is null) {
+        logger.fatal ("Unable to set video mode:");
+        char* msg = SDL_GetError ();
+        logger.fatal (msg ? fromStringz(msg) : "no reason available");
+        
+        // Print a load of info:
+        logger.info ("Available video modes:");
+        char[128] tmp;
+        SDL_Rect** modes = SDL_ListModes (null, SDL_FULLSCREEN);
+        if (modes is null) logger.info ("None!");
+        else if (modes is cast(SDL_Rect**) -1) logger.info ("All modes are available");
+        else {
+            for (uint i = 0; modes[i] !is null; ++i) {
+                logger.info (logger.format (tmp, "\t{}x{}", modes[i].w, modes[i].h));
+            }
+        }
+    
+        SDL_VideoInfo* vi = SDL_GetVideoInfo ();
+        if (vi !is null) {
+            logger.info ("Video info:");
+            logger.info ("Hardware surface support: "~ (vi.flags & SDL_HWSURFACE ? "yes" : "no"));
+            logger.info (logger.format (tmp, "Video memory: {}", vi.video_mem));
+    
+            if (vi.vfmt !is null) {
+                logger.info ("Best video mode:");
+                logger.info (logger.format (tmp, "Bits per pixel: {}", vi.vfmt.BitsPerPixel));
+            }
+        }
+        
+        setInitFailure ();
+        return;
+    }
+    
+    /* Now (must be done after GL context is created) we can try to load later version.
+     * The initial loading provides opengl 1.1 features.
+     *
+     * 1.4 is now used for glBlendColor (coloured text).
+     *
+     * Currently the latest version used is 1.3; adjust this as necessary. However, before using
+     * features from any OpenGL version > 1.1 a check must be made on what was loaded by calling
+     * DerelictGL.availableVersion(). Note that availableVersion() could be used instead to load
+     * the highest supported version but this way we know what we're getting.
+     */
+    if (DerelictGL.availableVersion < GLVersion.Version13) {
+        logger.fatal ("Required at least OpenGL 1.3");
+        setInitFailure;
+        return;
+    }
+    /+try {
+        DerelictGL.loadVersions(GLVersion.Version14);
+    } catch (SharedLibProcLoadException e) {
+        logger.warn ("Loading OpenGL version 1.4 failed:");
+        logger.warn (e.msg);
+        
+        //NOTE: might be worth guaranteeing a minimal version to save later checks?
+        /+ Do this if you want the program to abort:
+        setInitFailure ();
+        return;
+        +/
+    }+/
+    
+    // OpenGL stuff:
+    glSetup();
+    setProjection (w, h);
+    
+    // Window-manager settings
+    SDL_WM_SetCaption (toStringz ("mde"), null);
+    // SDL_WM_GrabInput (use later)
+}
+
+void resizeWindow (int w, int h) {
+    if (vidOpts.fullscreen) {
+        Options.setInt ("video", "screenW", w);
+        Options.setInt ("video", "screenH", h);
+    } else {
+        Options.setInt ("video", "windowW", w);
+        Options.setInt ("video", "windowH", h);
+    }
+    
+    if (SDL_SetVideoMode (w, h, 32, flags) is null) {
+        logger.fatal ("Unable to reset video mode:");
+        char* msg = SDL_GetError ();
+        logger.fatal (msg ? fromStringz(msg) : "no reason available");
+        
+        imde.run = false;
+    }
+    
+    // Reset the projection and viewport
+    setProjection (w, h);
+}
+
+void cleanupSDL () {    // cleanup func
+    closeJoysticks();
+    SDL_Quit();
+}
+
+
+/** All video options. */
+OptionsVideo vidOpts;
+class OptionsVideo : Options {
+    mixin (impl!("bool fullscreen,hardware,resizable,noFrame; int screenW,screenH,windowW,windowH;"));
+    
+    static this() {
+        vidOpts = new OptionsVideo;
+        Options.addOptionsClass (vidOpts, "video");
+    }
+}