view mde/sdl.d @ 41:b3a6ca4516b4

The renderer now controls which parts of the window border allow resizing. committer: Diggory Hardy <diggory.hardy@gmail.com>
author Diggory Hardy <diggory.hardy@gmail.com>
date Tue, 13 May 2008 12:02:36 +0100
parents 57d000574d75
children 0fd51d2c6c8a
line wrap: on
line source

/* 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.sdl;

import mde.scheduler.initFunctions;
import mde.input.joystick;
import mde.Options;
import mde.gl.basic;
import imde = mde.imde;

import tango.util.log.Log : Log, Logger;
import tango.stdc.stringz;

import derelict.sdl.sdl;

private Logger logger;
static this() {
    logger = Log.getLogger ("mde.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,    8);
    SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE,  8);
    SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE,   8);
    SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE,  24);
    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");
        
        setInitFailure ();
        return;
    }
    
    // Now (must be done after GL context is created) try to load later version:
    /+ No later GL features are currently used.
    try {
        DerelictGL.loadVersions(GLVersion.Version21);
    } catch (DerelictException de) {
        logger.fatal ("Loading OpenGL version > 1.1 failed:");
        logger.fatal (de.msg);
        
        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();
}

    /+ Load of info-printing stuff (currently doesn't have a use)
    // 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));
    }
    }
    +/


/** All video options. */
OptionsVideo vidOpts;
class OptionsVideo : Options {
    alias store!("fullscreen","hardware","resizable","noFrame") BOOL;
    alias store!("screenW","screenH","windowW","windowH") INT;
    //alias store!() CHARA;
    
    mixin (decBool!(BOOL.a));
    mixin (decInt!(INT.a));
    //mixin (decCharA!(CHARA.a));
    
    this () {
        mixin (aaBool!(BOOL.a));
        mixin (aaInt!(INT.a));
        //mixin (aaCharA!(CHARA.a));
    }
    
    static this() {
        vidOpts = new OptionsVideo;
        Options.addOptionsClass (vidOpts, "video");
    }
}