Mercurial > projects > mde
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"); + } +}