Commits

Anonymous committed 52d687e

* removed SDL_GrabInput from editor ( was filtering X inputs like Alt-Tab )
* GUI now update the mouse coordinates by itself ( which are now absolute coordinates )
* The boss now has an animation
* the input configuration items are now sorted ( by value of they enum )
* reworked a bit the internals of InputManager
* added a moveRelative() method to view

  • Participants
  • Parent commits 6a631f7

Comments (0)

Files changed (16)

File data/boss2_01.png

Added
New image

File data/boss2_02.png

Added
New image

File data/boss2_03.png

Added
New image

File data/boss2_04.png

Added
New image

File data/boss2_05.png

Added
New image

File data/boss2_06.png

Added
New image

File rwkc.conf

-
-INPUT {
-   UP {
-      METHOD = key
-      KEYCODE = 273
-   }
-
-   DOWN {
-      METHOD = key
-      KEYCODE = 274
-   }
-
-   LEFT {
-      METHOD = key
-      KEYCODE = 276
-   }
-
-   RIGHT {
-      METHOD = key
-      KEYCODE = 275
-   }
-
-   ESCAPE {
-      METHOD = key
-      KEYCODE = 27
-   }
-
-   CROUCH {
-      METHOD = key
-      KEYCODE = 99
-   }
- ; c
-
-   FIRE {
-      METHOD = key
-      KEYCODE = 120
-   }
- ; x
-
-   ENTER {
-      METHOD = key
-      KEYCODE = 13
-   }
- ; return
-
-   PAUSE {
-      METHOD = key
-      KEYCODE = 19
-   }
- ; p
-
-   VOLUME_UP {
-      METHOD = key
-      KEYCODE = 280
-   }
- ; page up
-
-   VOLUME_DOWN {
-      METHOD = key
-      KEYCODE = 281
-   }
- ; page down
-
-   EDITOR {
-      METHOD = key
-      KEYCODE = 290
-   }
- ; F12
-
-}
- ;    /* The keyboard syms have been cleverly chosen to map to ASCII */
- ;    SDLK_BACKSPACE      = 8,
- ;    SDLK_TAB        = 9,
- ;    SDLK_CLEAR      = 12,
- ;    SDLK_RETURN     = 13,
- ;    SDLK_PAUSE      = 19,
- ;    SDLK_ESCAPE     = 27,
- ;    SDLK_SPACE      = 32,
- ;    SDLK_EXCLAIM        = 33,
- ;    SDLK_QUOTEDBL       = 34,
- ;    SDLK_HASH       = 35,
- ;    SDLK_DOLLAR     = 36,
- ;    SDLK_AMPERSAND      = 38,
- ;    SDLK_QUOTE      = 39,
- ;    SDLK_LEFTPAREN      = 40,
- ;    SDLK_RIGHTPAREN     = 41,
- ;    SDLK_ASTERISK       = 42,
- ;    SDLK_PLUS       = 43,
- ;    SDLK_COMMA      = 44,
- ;    SDLK_MINUS      = 45,
- ;    SDLK_PERIOD     = 46,
- ;    SDLK_SLASH      = 47,
- ;    SDLK_0          = 48,
- ;    SDLK_1          = 49,
- ;    SDLK_2          = 50,
- ;    SDLK_3          = 51,
- ;    SDLK_4          = 52,
- ;    SDLK_5          = 53,
- ;    SDLK_6          = 54,
- ;    SDLK_7          = 55,
- ;    SDLK_8          = 56,
- ;    SDLK_9          = 57,
- ;    SDLK_COLON      = 58,
- ;    SDLK_SEMICOLON      = 59,
- ;    SDLK_LESS       = 60,
- ;    SDLK_EQUALS     = 61,
- ;    SDLK_GREATER        = 62,
- ;    SDLK_QUESTION       = 63,
- ;    SDLK_AT         = 64,
- ;    /*
- ;       Skip uppercase letters
- ;     */
- ;    SDLK_LEFTBRACKET    = 91,
- ;    SDLK_BACKSLASH      = 92,
- ;    SDLK_RIGHTBRACKET   = 93,
- ;    SDLK_CARET      = 94,
- ;    SDLK_UNDERSCORE     = 95,
- ;    SDLK_BACKQUOTE      = 96,
- ;    SDLK_a          = 97,
- ;    SDLK_b          = 98,
- ;    SDLK_c          = 99,
- ;    SDLK_d          = 100,
- ;    SDLK_e          = 101,
- ;    SDLK_f          = 102,
- ;    SDLK_g          = 103,
- ;    SDLK_h          = 104,
- ;    SDLK_i          = 105,
- ;    SDLK_j          = 106,
- ;    SDLK_k          = 107,
- ;    SDLK_l          = 108,
- ;    SDLK_m          = 109,
- ;    SDLK_n          = 110,
- ;    SDLK_o          = 111,
- ;    SDLK_p          = 112,
- ;    SDLK_q          = 113,
- ;    SDLK_r          = 114,
- ;    SDLK_s          = 115,
- ;    SDLK_t          = 116,
- ;    SDLK_u          = 117,
- ;    SDLK_v          = 118,
- ;    SDLK_w          = 119,
- ;    SDLK_x          = 120,
- ;    SDLK_y          = 121,
- ;    SDLK_z          = 122,
- ;    SDLK_DELETE     = 127,
- ;    /* End of ASCII mapped keysyms */
- ;
- ;    /* Numeric keypad */
- ;    SDLK_KP0        = 256,
- ;    SDLK_KP1        = 257,
- ;    SDLK_KP2        = 258,
- ;    SDLK_KP3        = 259,
- ;    SDLK_KP4        = 260,
- ;    SDLK_KP5        = 261,
- ;    SDLK_KP6        = 262,
- ;    SDLK_KP7        = 263,
- ;    SDLK_KP8        = 264,
- ;    SDLK_KP9        = 265,
- ;    SDLK_KP_PERIOD      = 266,
- ;    SDLK_KP_DIVIDE      = 267,
- ;    SDLK_KP_MULTIPLY    = 268,
- ;    SDLK_KP_MINUS       = 269,
- ;    SDLK_KP_PLUS        = 270,
- ;    SDLK_KP_ENTER       = 271,
- ;    SDLK_KP_EQUALS      = 272,
- ;
- ;    /* Arrows + Home/End pad */
- ;    SDLK_UP         = 273,
- ;    SDLK_DOWN       = 274,
- ;    SDLK_RIGHT      = 275,
- ;    SDLK_LEFT       = 276,
- ;    SDLK_INSERT     = 277,
- ;    SDLK_HOME       = 278,
- ;    SDLK_END        = 279,
- ;    SDLK_PAGEUP     = 280,
- ;    SDLK_PAGEDOWN       = 281,
- ;
- ;    /* Function keys */
- ;    SDLK_F1         = 282,
- ;    SDLK_F2         = 283,
- ;    SDLK_F3         = 284,
- ;    SDLK_F4         = 285,
- ;    SDLK_F5         = 286,
- ;    SDLK_F6         = 287,
- ;    SDLK_F7         = 288,
- ;    SDLK_F8         = 289,
- ;    SDLK_F9         = 290,
- ;    SDLK_F10        = 291,
- ;    SDLK_F11        = 292,
- ;    SDLK_F12        = 293,
- ;    SDLK_F13        = 294,
- ;    SDLK_F14        = 295,
- ;    SDLK_F15        = 296,
- ;
- ;    /* Key state modifier keys */
- ;    SDLK_NUMLOCK        = 300,
- ;    SDLK_CAPSLOCK       = 301,
- ;    SDLK_SCROLLOCK      = 302,
- ;    SDLK_RSHIFT     = 303,
- ;    SDLK_LSHIFT     = 304,
- ;    SDLK_RCTRL      = 305,
- ;    SDLK_LCTRL      = 306,
- ;    SDLK_RALT       = 307,
- ;    SDLK_LALT       = 308,
- ;    SDLK_RMETA      = 309,
- ;    SDLK_LMETA      = 310,
- ;    SDLK_LSUPER     = 311,      /* Left "Windows" key */
- ;    SDLK_RSUPER     = 312,      /* Right "Windows" key */
- ;    SDLK_MODE       = 313,      /* "Alt Gr" key */
- ;    SDLK_COMPOSE        = 314,      /* Multi-key compose key */
- ;
- ;    /* Miscellaneous function keys */
- ;    SDLK_HELP       = 315,
- ;    SDLK_PRINT      = 316,
- ;    SDLK_SYSREQ     = 317,
- ;    SDLK_BREAK      = 318,
- ;    SDLK_MENU       = 319,
- ;    SDLK_POWER      = 320,      /* Power Macintosh power key */
- ;    SDLK_EURO       = 321,      /* Some european keyboards */
- ;    SDLK_UNDO       = 322,      /* Atari keyboard has Undo */
- ;

File src/editor.d

 	GAMEPART_STATE mState;
 	SDL_Surface* mBg;
 
-	float mVx = 0;
-	float mVy = 0;
-
 	EditorTools mTools;
 	ActionType mAction;
 	string mPointerIcon;
 	string mPreviousPointer;
 	Alert mAlert;
 
+	int mMouseX, mMouseY;
+
 	void delegate() fMode;
 	void delegate() fPreviousMode;
 
 	this( bool fromGame=false ) {
-		SDL_WM_GrabInput(SDL_GRAB_ON);
 
 		// if coming from game ( test mode ), reload the map
 		// else load an empty map.
 
 		gView.setTarget( null );
 
-		gView.setPosition( mVx,mVy );
-
 		mBg = gTextureManager.get( "background.png" );
 
 		mAction = ActionType.NOTHING;
 	}
 
 	~this() {
-		SDL_WM_GrabInput(SDL_GRAB_OFF);
 		if( mTools !is null ) delete( mTools );
 		if( mHighlight != null ) SDL_FreeSurface( mHighlight );
 	}
 		gView.update();
 		gView.draw();
 		fMode();
-		//checkQuit();
 	}
 
 	void editMode() {
-		int x,y;
-		gInputManager.getMousePositionRelative( x,y );
-		GUI.instance.update( x,y, gInputManager.isMouseButtonUp(SDL_BUTTON_LEFT) );
+		GUI.instance.update();
 
 		checkEscapeToQuit();
 
 			return;
 		}
 
-		if ( gInputManager.isMouseButtonPressed(SDL_BUTTON_RIGHT) ) {
+		if ( gInputManager.isMouseButtonDown(SDL_BUTTON_RIGHT) ) {
 			GUI.instance.hidePointer();
 			fPreviousMode = &editMode;
 			fMode = &moveMode;
+
+			gInputManager.getMousePosition( mMouseX, mMouseY );
+			SDL_WarpMouse( gScreen.WIDTH/2, gScreen.HEIGHT/2 );
 			return;
 		}
 
 		// highligtht action
+		int x,y;
 		GUI.instance.getPointerPosition( x, y );
 		int xOffset = cast(int)gView.mX / gMap.TILE_WIDTH;
 		int yOffset = cast(int)gView.mY / gMap.TILE_HEIGHT;
 	}
 
 	void moveMode() {
-		int x,y;
-		gInputManager.getMousePositionRelative( x,y );
 
-		if ( gInputManager.isMouseButtonPressed(SDL_BUTTON_RIGHT) ) {
-			mVx += x;
-			mVy += y;
-			gView.setPosition( mVx, mVy );
-		}
-		else {
+		if ( gInputManager.isMouseButtonUp(SDL_BUTTON_RIGHT) ) {
+			SDL_WarpMouse( cast(ushort)mMouseX, cast(ushort)mMouseY );
 			GUI.instance.showPointer();
 			fMode = fPreviousMode;
 		}
+		else {
+
+			// movement relative to the center of the screen
+			// manually computed because of the SDL relative events generated by
+			// WarpMouse...
+			gView.moveRelative(
+				(gInputManager.mouseX-gScreen.WIDTH/2),
+				(gInputManager.mouseY-gScreen.HEIGHT/2) );
+
+			SDL_WarpMouse( gScreen.WIDTH/2, gScreen.HEIGHT/2 );
+		}
+
 	}
 
+
 	void toolsMode() {
 		int x,y;
 		gInputManager.getMousePositionRelative( x,y );
 			return;
 		}
 
-		GUI.instance.update( x,y, gInputManager.isMouseButtonUp(SDL_BUTTON_LEFT) );
+		GUI.instance.update();
 
 		if( gInputManager.isMouseButtonUp(SDL_BUTTON_MIDDLE) ) {
 			delete(mTools);
 		if( mTools.done() ) {
 			mAction = mTools.getAction();
 
-
 			switch( mAction ) {
 				case ActionType.LOAD_MAP:
 					mMapListDialog = new MapListDialog();
 		}
 	}
 
-	/*
-	void checkQuit() {
-		if( gInputManager.isReleased(IMA_TOGGLE_EDITOR) ) {
-			quit();
-		}
-		//if( gInputManager.isReleased( IMA_BACK )) {	quit();	}
-	}
-	*/
 
 	void checkEscapeToQuit() {
 		if( gInputManager.isReleased( IMA_BACK )) {	quit();	}
 
 	void saveAsMode() {
 
-		injectMouse();
+		GUI.instance.update();
 
 		if( mMapNameDialog.done() ) {
 			if( mMapNameDialog.ok && mMapNameDialog.text != "" ) {
 	}
 
 	void mapLoadMode() {
-		injectMouse();
+
+		GUI.instance.update();
 		if( mMapListDialog.done() ) {
 			if( mMapListDialog.ok() && mMapListDialog.getMapName().length > 0 ) {
 				delete(gMap);
 	}
 
 	void alertMode() {
-		injectMouse();
+		GUI.instance.update();
 		if( mAlert && mAlert.done() ) {
 			delete( mAlert );
 			fMode = fPreviousMode;
 
 
 	void paramsMode() {
-		injectMouse();
+		GUI.instance.update();
 		if( mParamsDialog.done() ) {
 
 			if( mParamsDialog.ok ) {
 		}
 	}
 
-	void injectMouse() {
-		int x,y;
-		gInputManager.getMousePositionRelative( x,y );
-		GUI.instance.update( x,y, gInputManager.isMouseButtonUp(SDL_BUTTON_LEFT) );
-	}
-
 
 	GAMEPART_STATE getState() {
 		return( mState );
 	}
 
+
 	void highlight( int x, int y, int w, int h ) {
 		if( mHighlightRect.w != w || mHighlightRect.h != h || mHighlight == null ) {
 			mHighlightRect.w = cast(ushort)w;
 			mHighlightRect.h = cast(ushort)h;
 			if( mHighlight != null ) SDL_FreeSurface( mHighlight );
-			mHighlight = SDL_CreateRGBSurface( SDL_HWSURFACE, w, h, 32, 0,0,0,0 );
+			mHighlight = SDL_CreateRGBSurface( SDL_HWSURFACE, w, h, 32, 0, 0, 0, 0 );
 			SDL_FillRect( mHighlight, null, 0xFFFFFFFF );
 			SDL_SetAlpha( mHighlight, SDL_SRCALPHA, 128 );
 		}

File src/gameobjects/boss.d

 
 		// TODO: change animation
 		if( mAnimBase is null ) {
-			mAnimBase = new Anim( 0.075 );
-			//mAnimBase.addFrame( "boss_000004.png" );
-			//mAnimBase.addFrame( "boss_000003.png" );
-			//mAnimBase.addFrame( "boss_000002.png" );
-			//mAnimBase.addFrame( "boss_000001.png" );
-			mAnimBase.addFrame( "boss3.png" );
+			mAnimBase = new Anim( 0.075 );
+			mAnimBase.addFrame( "boss2_01.png" );
+			mAnimBase.addFrame( "boss2_02.png" );
+			mAnimBase.addFrame( "boss2_03.png" );
+			mAnimBase.addFrame( "boss2_04.png" );
+			mAnimBase.addFrame( "boss2_05.png" );
+			mAnimBase.addFrame( "boss2_06.png" );
+			mAnimBase.addFrame( "boss2_05.png" );
+			mAnimBase.addFrame( "boss2_04.png" );
+			mAnimBase.addFrame( "boss2_03.png" );
+			mAnimBase.addFrame( "boss2_02.png" );
+			mAnimBase.addFrame( "boss2_01.png" );
+			//mAnimBase.addFrame( "boss3.png" );
 		}
 		mAnim = new AnimInstance( mAnimBase );
 
 module gui;
 
 import derelict.sdl.sdl;
+import gameconstants;
+import graphics;
+import inputmanager;
+import time;
+import std.stdio;
+import slist;
 import texturemanager;
+import textsurface;
 import screen;
-import std.stdio;
-import textsurface;
-import slist;
-import inputmanager;
-import gameconstants;
-import std.stdio;
-import graphics;
-import time;
 
+/**
+ * GUI
+ *
+ * The GUI class manages the top-level Panels and the mouse pointer.
+ *
+ * Widgets (Buttons, Labels, Text Inputs, Panels...  )
+ * can only be added in Panels and they are added in a
+ * text-editor style ( add, add, new_line, add, etc... )
+ * You can't modify the position or size of the widgets
+ * ( one exception : the Menus width can be forced at initialisation )
+ *
+ * Top-level Panels can be auto-aligned relative to the screen ( see: Panel.setAlign() )
+ *
+ *
+ * Menus are specialisation of Panels, containing only TextButtons,
+ *	vertically aligned and managed automatically by keyboard or mouse input
+ *
+ */
 class GUI {
 
 	class Widget {
 				else
 					tb = this.addTextButton( label, "", this );
 				mItems ~= tb;
+				//mButtons ~= tb;
 				this.nl();
 			}
+			// automatically hightlight the first button.
+			if( mItems.length > 0 ) {
+				mItems[0].highlight(true);
+				mSelectedItem = 0;
+				mHighlighted = mItems[0];
+			}
 		}
 
 		void setListener( MenuListener listener ) {
 			mSelectedItem += dir;
 			if( mSelectedItem < 0) mSelectedItem = mItems.length-1;
 			if( mSelectedItem > mItems.length-1 ) mSelectedItem = 0;
-
 			if( mHighlighted ) mHighlighted.highlight(false);
 			mItems[mSelectedItem].highlight(true);
 			mHighlighted = mItems[mSelectedItem];
 
 	private ~this() {
 		if( mPointer != null ) SDL_FreeSurface( mPointer );
+		delete( mGraphics );
 	}
 
 	void showPointer() {
 		y = mPy;
 	}
 
-	void update( int relx, int rely, bool click ) {
+	void update() {
 
-		mPx += relx;
-		mPy += rely;
+		bool moved;
+		if( mPx != gInputManager.mouseX || mPy != gInputManager.mouseY ) {
+			moved = true;
+			mPx = gInputManager.mouseX;
+			mPy = gInputManager.mouseY;
+		}
+		bool click = gInputManager.isMouseButtonUp( SDL_BUTTON_LEFT );
+
+
 		if( mPx < 0 ) mPx = 0;
 		if( mPy < 0 ) mPy = 0;
 		if( mPx > 640 ) mPx = 640;
 
 		foreach( p; mPanels ) {
 			if( !p.hidden ) {
-				if( (relx || rely) || click )
+				if( moved || click )
 					p.checkButtons( mPx, mPy, click );
 				else
 					p.checkButtons( -1, -1, click );
 
 	}
 
+
 	Panel addPanel( int x, int y ) {
 		Panel p = new Panel( null, x, y );
 		//mPanels ~= p;

File src/inputconfigurationdialog.d

 
 module inputconfigurationdialog;
 
+import derelict.sdl.sdl;
+import gameconstants;
 import gui;
 import inputmanager;
 import inputconfiguration;
 import inputactions;
-import derelict.sdl.sdl;
+
 debug import std.stdio;
 
+
 class InputConfigurationDialog: GUI.ButtonListener, GUI.MenuListener {
 
 	GUI.Panel mPanel;
 			recreatePanel();
 		}
 
+		if( gInputManager.isReleased( IMA_BACK )) {
+			mDone = true;
+		}
+
 		return mDone;
 	};
 
 			mDone = true;
 			return;
 		}
+
 	}
 
 	void onSelectedItem( int item ) {

File src/inputmanager.d

     bool[8] mMouseButtonsUp;
     bool[8] mMouseButtonsDown;
 
+	ubyte mMouseButtonsState; // bitfield of mouse buttons states
+	int mMouseRelX, mMouseRelY; // relative mouse position
+	int mMouseX, mMouseY; // absolute mouse position
+
     this( char[] configFilename ) {
         gInputManager = this;
 
     }
 
     char[][] getActions() {
-        return( mBindings.keys );
+
+        //return( mBindings.keys );
+        string[] actions;
+        actions.length = mBindings.length;
+        foreach( k, v; mBindings ) {
+        	actions[v] = k;
+        }
+        return( actions );
     }
 
     void bind( uint actionId, char[] actionName ) {
             throw new Error("Error while loading \"" ~ mConfigFilename ~ "\"");
     }
 
+
     void update() {
         SDL_Event event;
         mSDLKeys = SDL_GetKeyState(null);
         while ( SDL_PollEvent(&event) ) {
 
             switch ( event.type ) {
-            case SDL_QUIT:
-                throw new Error( "quitting" );  // *tousse* *tousse*
+				case SDL_QUIT:
+					throw new Error( "quitting" );  // *tousse* *tousse*
 
-            case SDL_MOUSEBUTTONUP:
-                mMouseButtonsUp[event.button.button] = true;
-                break;
+				case SDL_MOUSEBUTTONUP:
+					writefln( "mouse up ", event.button.button );
+					mMouseButtonsUp[event.button.button] = true;
+					break;
 
-            case SDL_MOUSEBUTTONDOWN:
-                mMouseButtonsDown[event.button.button] = true;
-                break;
+				case SDL_MOUSEBUTTONDOWN:
+					writefln( "mouse down ", event.button.button );
+					mMouseButtonsDown[event.button.button] = true;
+					break;
 
-            case SDL_KEYDOWN:
-                mLastPressedKeyChar = getKeyValue( event.key.keysym.unicode);
-                mLastPressedKeySym = event.key.keysym.sym;
-                break;
+				case SDL_KEYDOWN:
+					mLastPressedKeyChar = getKeyValue( event.key.keysym.unicode);
+					mLastPressedKeySym = event.key.keysym.sym;
+					break;
 
-            default:
-                break;
-            }
+				default:
+					break;
+				}
         }
-    }
+
+		mMouseButtonsState = SDL_GetMouseState( &mMouseX, &mMouseY);
+		SDL_GetRelativeMouseState( &mMouseRelX, &mMouseRelY );
+
+	}
+
 
 	ubyte getKeyValue( ushort unicode ) {
 		char ch;
 		}
 	}
 
+	/// returns the english name for the indicated scancode ( SDL keysym ).
 	string getKeyName( int sdlkeysym ) {
 		return( std.string.toString( SDL_GetKeyName( sdlkeysym ) ));
 	}
 
-
+	/// returns the array of key states ( by scancode (SDL keysym ))
     ubyte* getKeys() {
         return( mSDLKeys );
     }
 
+	/// returns the character of the last pressed key ( first byte of the unicode )
     ubyte getKeyDown() {
         return( mLastPressedKeyChar );
     }
 
+	/// returns the "scancode" ( SDL keysym ) of the last pressed key.
 	uint getKeyDownCode() {
 		return( mLastPressedKeySym );
 	}
 
     void getMousePositionRelative( out int x, out int y ) {
-        SDL_GetRelativeMouseState( &x, &y );
+        x = mMouseRelX;
+        y = mMouseRelY;
     }
 
+	int mouseRelX() { return mMouseRelX; }
+	int mouseRelY() { return mMouseRelY; }
+
     void getMousePosition( out int x, out int y ) {
-        SDL_GetMouseState( &x, & y);
+        x = mMouseX;
+        y = mMouseY;
     }
 
+	int mouseX() { return mMouseX; }
+	int mouseY() { return mMouseY; }
+
     bool isMouseButtonUp( ubyte button ) {
         // button is one of SDL_BUTTON_LEFT, _RIGHT, _MIDDLE, _WHEELUP, etc..
         return( mMouseButtonsUp[button] );
     }
 
     bool isMouseButtonPressed( ubyte button ) {
-        ubyte state = SDL_GetMouseState( null, null );
         switch ( button ) {
-        case SDL_BUTTON_LEFT:
-            return( (state & SDL_BUTTON_LMASK)!=0 );
+			case SDL_BUTTON_LEFT:
+				return( (mMouseButtonsState & SDL_BUTTON_LMASK)!=0 );
 
-        case SDL_BUTTON_RIGHT:
-            return( (state & SDL_BUTTON_RMASK)!=0 );
+			case SDL_BUTTON_RIGHT:
+				return( (mMouseButtonsState & SDL_BUTTON_RMASK)!=0 );
 
-        case SDL_BUTTON_MIDDLE:
-            return( (state & SDL_BUTTON_MMASK)!=0 );
+			case SDL_BUTTON_MIDDLE:
+				return( (mMouseButtonsState & SDL_BUTTON_MMASK)!=0 );
 
-        default:
-            return( false );
+			default:
+				return( false );
         }
     }
 
 
 		int x, y;
 		gInputManager.getMousePositionRelative( x,y );
-		GUI.instance.update( x,y, gInputManager.isMouseButtonUp(SDL_BUTTON_LEFT) );
+		GUI.instance.update();
 	}
 
 	abstract void onSelectedItem( int item );

File src/screen.d

 
 	void toggleFullscreen() {
 		mFullscreen = !mFullscreen;
+
 		if( mFullscreen ) {
 			const uint videoflags = SDL_HWSURFACE|SDL_DOUBLEBUF|SDL_FULLSCREEN;
+			// try fullscreen with a WIDTHxHEIGHT mode :
 			mSurface = SDL_SetVideoMode(WIDTH, HEIGHT, 0, videoflags);
+			if( mSurface == null ) {
+				//try with current (desktop) video mode
+				mSurface = SDL_SetVideoMode(0, 0, 0, videoflags);
+				if( mSurface == null ) {
+					// fallback on windowed mode
+					toggleFullscreen();
+				}
+			}
 		}
 		else {
 			const uint videoflags = SDL_HWSURFACE|SDL_DOUBLEBUF|SDL_ANYFORMAT;
 			mSurface = SDL_SetVideoMode(WIDTH, HEIGHT, 0, videoflags);
 		}
+
+		//SDL_WM_ToggleFullScreen(mSurface);
 	}
 
 	void vsync() {

File src/textsurface.d

 	char[] mText;
 
 	static TTF_Font* mFont;
-
+
 
 	this( char[] text = "" ) {
 		if( !mFont ) {
 
 
 	void setPosition( float x, float y ) {
-
 		mX = x;
 		mY = y;
 		clampPosition();
-
 	}
+
+	void moveRelative( float relx, float rely ) {
+		mX += relx;
+		mY += rely;
+		clampPosition();
+	}
 
 
 	void clampPosition() {