Commits

Anonymous committed 462cc48

* ajout des fonctions "graphics" ( drawLine, drawBox, flipSurface, etc... )
* debug : outils de l'éditeur ne se disparaissaient pas lors d'une sortie sans sélection
* debug : remis la sortie de l'éditeur par esc ( les boites de dialogues ne peuvent plus se fermer par [escape] )
* bug toujours pas corrigé : Panel dans Panel ne se positionne pas correctement.

Comments (0)

Files changed (6)

 		<Unit filename="src/gameobjects/updatedgameobject.d" />
 		<Unit filename="src/gameobjects/wall.d" />
 		<Unit filename="src/gamepart.d" />
+		<Unit filename="src/graphics.d" />
 		<Unit filename="src/gui.d" />
 		<Unit filename="src/inputactions.d" />
 		<Unit filename="src/inputconfiguration.d" />
-########################################
-#                                      #
-#                                      #
-#                                      #
-#                                      #
-#   X        @                         #
-# ===============                      #
-# ===============                      #
-#                                      #
-#                                      #
-#                                      #
-#                                      #
-#                                      #
-#                                      #
-#                                      #
-#                                      #
-#                                      #
-#                                      #
-#                                      #
-#                                      #
-########################################
+#####################
+#        u u        #
+#     ==     v      #
+#     ==            #
+#     12      12    #
+#   X 34j @   34 J  #
+# =#=#=#=#=#=#=#=#=##
+# #=#=#=#=#=#=#=#=#=#
+#                   #
+#                   #
+#                   #
+#                   #
+#                   #
+#                   #
+#                   #
+#####################
 		}
 
 		// do action if click
-		if( gInputManager.isMouseButtonUp(SDL_BUTTON_LEFT) ) {
+		if( gInputManager.isMouseButtonPressed(SDL_BUTTON_LEFT) ) {
 			switch( mAction ) {
 				case ActionType.INSERT_COLUMN:
 					gMap.insertColumn( xMap + xOffset );
 		GUI.instance.update( x,y, gInputManager.isMouseButtonUp(SDL_BUTTON_LEFT) );
 
 		if( gInputManager.isMouseButtonUp(SDL_BUTTON_MIDDLE) ) {
+			delete(mTools);
 			fMode = &editMode;
 			return;
 		}
 
 				case ActionType.SAVE_MAP:
 					if( gMap.name != "" ) {
-						gMap.save();
-						fPreviousMode = &editMode;
-						fMode = &alertMode;
-						mAlert = new Alert("Map saved !");
+						saveMap();
 					}
 					else {
 						mMapNameDialog = new MapNameDialog();
 		if( mInGame && gInputManager.isReleased(IMA_TOGGLE_EDITOR) ) {
 			quit();
 		}
+		if( gInputManager.isReleased( IMA_BACK )) {
+			quit();
+		}
 	}
 
 
 		if( mMapNameDialog.done() ) {
 			if( mMapNameDialog.ok && mMapNameDialog.text != "" ) {
 				gMap.name= std.string.strip(mMapNameDialog.text)~".txt";
-				if( gMap.save() ) {
-					mAlert = new Alert( "map '"~mMapNameDialog.text~"' saved !" );
-				}
-				else {
-					mAlert = new Alert( "Error while saving map" );
-				}
-				fMode = &alertMode;
-				fPreviousMode = &editMode;
+				saveMap();
 			}
 			else {
 				fMode = &editMode;
 
 	}
 
+	void saveMap() {
+		if( gMap.save() ) {
+			mAlert = new Alert( "map '"~mMapNameDialog.text~"' saved !" );
+		}
+		else {
+			mAlert = new Alert( "Error while saving map !", "" );
+		}
+		fMode = &alertMode;
+		fPreviousMode = &editMode;
+	}
 
 	void mapLoadMode() {
 		injectMouse();

src/editortools.d

 
 	void initTiles() {
 
-		mTiles ~= Tile( "wall1.png", '=' );
-		mTiles ~= Tile( "wall2.png", '#' );
+		mTiles ~= Tile( "wall1.png", '#' );
+		mTiles ~= Tile( "wall2.png", '=' );
 		mTiles ~= Tile( "bigwall1_1.png", '1' );
 		mTiles ~= Tile( "bigwall1_2.png", '2' );
 		mTiles ~= Tile( "bigwall1_3.png", '3');
+module graphics;
+
+import screen;
+import derelict.sdl.sdl;
+import std.math;
+
+class Graphics {
+
+    uint mColor = 0xFFFFFFFF;
+    int mTranslateX,mTranslateY;
+
+    void drawImage( SDL_Surface* img, int x, int y ) {
+        SDL_Rect dest = {
+        	cast(short)(x + mTranslateX),
+        	cast(short)(y + mTranslateY),
+        	cast(ushort)img.w,
+        	cast(ushort)img.h };
+
+        SDL_BlitSurface( img, null, gScreen.mSurface, &dest );
+
+    }
+
+    void translate( int dx, int dy ) {
+        mTranslateX = dx;
+        mTranslateY = dy;
+
+    }
+
+    void setColor( uint c ) {
+        mColor = c;
+    }
+
+    void fillRect( int x, int y, int w, int h) {
+
+        SDL_Rect rect = { cast(short)x,cast(short)y,cast(ushort)w,cast(ushort)h};
+        SDL_FillRect( gScreen.mSurface, &rect, mColor );
+
+    }
+
+	SDL_Surface* createTransparentSurface( uint width, uint height , ubyte alpha, uint color=0xFFFFFFFF ) {
+
+		SDL_Surface* s = SDL_CreateRGBSurface(
+			SDL_HWSURFACE,
+			width, height, 32,
+			0x00, 0x00, 0x00, 0x00 );
+		SDL_FillRect( s, null, color );
+		SDL_SetAlpha( s, SDL_SRCALPHA, alpha );
+
+		return( s );
+	}
+
+    void drawLine(short x, short y, short x2, short y2 ) {
+        // for Bullets
+        lineColor( gScreen.mSurface, x, y, x2, y2, mColor );
+    }
+
+	void drawBox( SDL_Rect r ) {
+		drawBox( r.x, r.y, r.w, r.h );
+	}
+
+	void drawBox( short x, short y, ushort w, ushort h ) {
+		lineColor( gScreen.mSurface, x, y, x+w, y, mColor );
+		lineColor( gScreen.mSurface, x+w, y, x+w, y+h, mColor );
+		lineColor( gScreen.mSurface, x, y+h, x+w, y+h, mColor );
+		lineColor( gScreen.mSurface, x, y, x, y+h, mColor );
+	}
+
+    /*
+     * Return the pixel value at (x, y)
+     * NOTE: The surface must be locked before calling this!
+     */
+    Uint32 getPixel(SDL_Surface *surface, int x, int y) {
+        int bpp = surface.format.BytesPerPixel;
+        /* Here p is the address to the pixel we want to retrieve */
+        Uint8 *p = cast(Uint8 *)surface.pixels + y * surface.pitch + x * bpp;
+
+        switch(bpp) {
+        case 1:
+            return *p;
+
+        case 2:
+            return *p;
+
+        case 3:
+            if(SDL_BYTEORDER == SDL_BIG_ENDIAN)
+                return p[0] << 16 | p[1] << 8 | p[2];
+            else
+                return p[0] | p[1] << 8 | p[2] << 16;
+
+        case 4:
+            return p[0] << 16 | p[1] << 8 | p[2];
+//    	return p[0] | p[1] << 8 | p[2] << 16;
+            //return (*cast(Uint32*)(surface.pixels + y * surface.pitch + x * bpp) );
+
+
+        default:
+            return 0;       /* shouldn't happen, but avoids warnings */
+        }
+    }
+
+
+    SDL_Surface* scaleSurface(SDL_Surface *Surface, uint scale ) {
+
+        if ( Surface is null || scale<=0 ) return(null);
+
+        int Width = Surface.w * scale;
+        int Height = Surface.h * scale;
+
+        SDL_Surface *_ret = SDL_CreateRGBSurface(Surface.flags, Width, Height, Surface.format.BitsPerPixel,
+                            Surface.format.Rmask, Surface.format.Gmask, Surface.format.Bmask, Surface.format.Amask);
+
+        if( _zoomSurfaceRGBA( Surface, _ret, 0, 0, 0 ) )
+            return( null );
+
+        return _ret;
+    }
+
+    SDL_Surface* flipSurface(SDL_Surface *Surface, bool flipx, bool flipy ) {
+
+        if ( Surface is null ) return(null);
+
+        int Width = Surface.w;
+        int Height = Surface.h;
+
+        SDL_Surface *_ret = SDL_CreateRGBSurface(Surface.flags, Width, Height, Surface.format.BitsPerPixel,
+                            Surface.format.Rmask, Surface.format.Gmask, Surface.format.Bmask, Surface.format.Amask);
+
+        if( _zoomSurfaceRGBA( Surface, _ret, flipx, flipy, 0 ) )
+            return( null );
+
+        return _ret;
+    }
+
+
+
+    struct tColorRGBA {
+        Uint8 r;
+        Uint8 g;
+        Uint8 b;
+        Uint8 a;
+    }
+
+
+// ripped from SDL_gfx; SDL_rotozoom.c
+    int _zoomSurfaceRGBA(SDL_Surface * src, SDL_Surface * dst, int flipx, int flipy, int smooth) {
+        int x, y, sx, sy;
+        int* sax,say,csax,csay;
+        int csx, csy, ex, ey, t1, t2, sstep, lx, ly;
+        tColorRGBA* c00, c01, c10, c11, cswap;
+        tColorRGBA* sp, csp, dp;
+        int dgap;
+
+        /*
+        * Variable setup
+        */
+        if (smooth) {
+            /*
+            * For interpolation: assume source dimension is one pixel
+            */
+            /*
+            * smaller to avoid overflow on right and bottom edge.
+            */
+            sx = cast(int) (65536.0 * cast(float) (src.w - 1) / cast(float) dst.w);
+            sy = cast(int) (65536.0 * cast(float) (src.h - 1) / cast(float) dst.h);
+        } else {
+            sx = cast(int) (65536.0 * cast(float) src.w / cast(float) dst.w);
+            sy = cast(int) (65536.0 * cast(float) src.h / cast(float) dst.h);
+        }
+
+        /*
+        * Allocate memory for row increments
+        */
+        if ((sax = cast(int *) std.c.stdlib.malloc((dst.w + 1) * Uint32.sizeof)) == null ) {
+            return (-1);
+        }
+        if ((say = cast(int *) std.c.stdlib.malloc((dst.h + 1) * Uint32.sizeof)) == null ) {
+            std.c.stdlib.free(sax);
+            return (-1);
+        }
+
+        /*
+        * Precalculate row increments
+        */
+        sp = csp = cast(tColorRGBA *) src.pixels;
+        dp = cast(tColorRGBA *) dst.pixels;
+
+        if (flipx) csp += (src.w-1);
+        if (flipy) csp += (src.pitch*(src.h-1));
+
+        csx = 0;
+        csax = sax;
+        for (x = 0; x <= dst.w; x++) {
+            *csax = csx;
+            csax++;
+            csx &= 0xffff;
+            csx += sx;
+        }
+        csy = 0;
+        csay = say;
+        for (y = 0; y <= dst.h; y++) {
+            *csay = csy;
+            csay++;
+            csy &= 0xffff;
+            csy += sy;
+        }
+
+        dgap = dst.pitch - dst.w * 4;
+
+        /*
+        * Switch between interpolating and non-interpolating code
+        */
+        if (smooth) {
+
+            /*
+            * Interpolating Zoom
+            */
+
+            /*
+            * Scan destination
+            */
+            ly = 0;
+            csay = say;
+            for (y = 0; y < dst.h; y++) {
+                /*
+                * Setup color source pointers
+                */
+                c00 = csp;
+                c01 = csp;
+                c01++;
+                c10 = cast(tColorRGBA *) (cast(Uint8 *) csp + src.pitch);
+                c11 = c10;
+                c11++;
+                csax = sax;
+                if (flipx) {
+                    cswap = c00;
+                    c00=c01;
+                    c01=cswap;
+                    cswap = c10;
+                    c10=c11;
+                    c11=cswap;
+                }
+                if (flipy) {
+                    cswap = c00;
+                    c00=c10;
+                    c10=cswap;
+                    cswap = c01;
+                    c01=c11;
+                    c11=cswap;
+                }
+                lx = 0;
+                for (x = 0; x < dst.w; x++) {
+                    /*
+                    * Interpolate colors
+                    */
+                    ex = (*csax & 0xffff);
+                    ey = (*csay & 0xffff);
+                    t1 = ((((c01.r - c00.r) * ex) >> 16) + c00.r) & 0xff;
+                    t2 = ((((c11.r - c10.r) * ex) >> 16) + c10.r) & 0xff;
+                    dp.r = (((t2 - t1) * ey) >> 16) + t1;
+                    t1 = ((((c01.g - c00.g) * ex) >> 16) + c00.g) & 0xff;
+                    t2 = ((((c11.g - c10.g) * ex) >> 16) + c10.g) & 0xff;
+                    dp.g = (((t2 - t1) * ey) >> 16) + t1;
+                    t1 = ((((c01.b - c00.b) * ex) >> 16) + c00.b) & 0xff;
+                    t2 = ((((c11.b - c10.b) * ex) >> 16) + c10.b) & 0xff;
+                    dp.b = (((t2 - t1) * ey) >> 16) + t1;
+                    t1 = ((((c01.a - c00.a) * ex) >> 16) + c00.a) & 0xff;
+                    t2 = ((((c11.a - c10.a) * ex) >> 16) + c10.a) & 0xff;
+                    dp.a = (((t2 - t1) * ey) >> 16) + t1;
+
+                    /*
+                    * Advance source pointers
+                    */
+                    csax++;
+                    sstep = (*csax >> 16);
+                    lx += sstep;
+                    if (lx >= src.w) sstep = 0;
+                    if (flipx) sstep = -sstep;
+                    c00 += sstep;
+                    c01 += sstep;
+                    c10 += sstep;
+                    c11 += sstep;
+                    /*
+                    * Advance destination pointer
+                    */
+                    dp++;
+                }
+                /*
+                * Advance source pointer
+                */
+                csay++;
+                sstep = (*csay >> 16);
+                ly += sstep;
+                if (ly >= src.h) sstep = 0;
+                sstep *= src.pitch;
+                if (flipy) sstep = -sstep;
+                csp = cast(tColorRGBA *) (cast(Uint8 *) csp + sstep);
+
+                /*
+                * Advance destination pointers
+                */
+                dp = cast(tColorRGBA *) (cast(Uint8 *) dp + dgap);
+            }
+        } else {
+
+            /*
+            * Non-Interpolating Zoom
+            */
+
+            csay = say;
+            for (y = 0; y < dst.h; y++) {
+                sp = csp;
+                csax = sax;
+                for (x = 0; x < dst.w; x++) {
+                    /*
+                    * Draw
+                    */
+                    *dp = *sp;
+                    /*
+                    * Advance source pointers
+                    */
+                    csax++;
+                    sstep = (*csax >> 16);
+                    if (flipx) sstep = -sstep;
+                    sp += sstep;
+                    /*
+                    * Advance destination pointer
+                    */
+                    dp++;
+                }
+                /*
+                * Advance source pointer
+                */
+                csay++;
+                sstep = (*csay >> 16) * src.pitch;
+                if (flipy) sstep = -sstep;
+                csp = cast(tColorRGBA *) (cast(Uint8 *) csp + sstep);
+
+                /*
+                * Advance destination pointers
+                */
+                dp = cast(tColorRGBA *) (cast(Uint8 *) dp + dgap);
+            }
+        }
+
+        /*
+        * Remove temp arrays
+        */
+        std.c.stdlib.free(sax);
+        std.c.stdlib.free(say);
+
+        return (0);
+    }
+
+// =====================================================================
+// =====================================================================
+// =====================================================================
+//  Line drawing stuffs ripped from SDL_Gfx : SDLgfxPrimitives.c
+// =====================================================================
+
+
+ int clip_xmin( SDL_Surface* s ) { return s.clip_rect.x; }
+ int clip_xmax( SDL_Surface* s ) { return s.clip_rect.x+ s.clip_rect.w-1; }
+ int clip_ymin( SDL_Surface* s ) { return s.clip_rect.y; }
+ int clip_ymax( SDL_Surface* s ) { return s.clip_rect.y+ s.clip_rect.h-1; }
+
+    /*!
+    \brief Internal pixel drawing function with alpha blending where input color in in destination format.
+
+    Contains two alternative 32 bit alpha blending routines which can be enabled at the source
+    level with the defines DEFAULT_ALPHA_PIXEL_ROUTINE or EXPERIMENTAL_ALPHA_PIXEL_ROUTINE.
+    Only the bits up to the surface depth are significant in the color value.
+
+    \param dst The surface to draw on.
+    \param x The horizontal coordinate of the pixel.
+    \param y The vertical position of the pixel.
+    \param color The color value of the pixel to draw.
+    \param alpha The blend factor to apply while drawing.
+
+    \returns Returns 0 on success, -1 on failure.
+    */
+    int _putPixelAlpha(SDL_Surface *dst, Sint16 x, Sint16 y, Uint32 color, Uint8 alpha) {
+        SDL_PixelFormat *format;
+        Uint32 Rmask, Gmask, Bmask, Amask;
+        Uint32 Rshift, Gshift, Bshift, Ashift;
+        Uint32 R, G, B, A;
+
+        if (dst == null) {
+            return (-1);
+        }
+
+        if (x >= clip_xmin(dst) && x <= clip_xmax(dst) &&
+                y >= clip_ymin(dst) && y <= clip_ymax(dst)) {
+
+            format = dst.format;
+
+            switch (format.BytesPerPixel) {
+            case 1: {
+                /* Assuming 8-bpp */
+                if (alpha == 255) {
+                    *(cast(Uint8 *) dst.pixels + y * dst.pitch + x) = cast(ubyte)color;
+                } else {
+                    Uint8 *pixel = cast(Uint8 *) dst.pixels + y * dst.pitch + x;
+                    SDL_Palette *palette = format.palette;
+                    SDL_Color *colors = palette.colors;
+                    SDL_Color dColor = colors[*pixel];
+                    SDL_Color sColor = colors[color];
+                    Uint8 dR = dColor.r;
+                    Uint8 dG = dColor.g;
+                    Uint8 dB = dColor.b;
+                    Uint8 sR = sColor.r;
+                    Uint8 sG = sColor.g;
+                    Uint8 sB = sColor.b;
+
+                    dR = dR + ((sR - dR) * alpha >> 8);
+                    dG = dG + ((sG - dG) * alpha >> 8);
+                    dB = dB + ((sB - dB) * alpha >> 8);
+
+                    *pixel = cast(ubyte)SDL_MapRGB(format, dR, dG, dB);
+                }
+            }
+            break;
+
+            case 2: {
+                /* Probably 15-bpp or 16-bpp */
+                if (alpha == 255) {
+                    *(cast(Uint16 *) dst.pixels + y * dst.pitch / 2 + x) = cast(ushort)color;
+                } else {
+                    Uint16 *pixel = cast(Uint16 *) dst.pixels + y * dst.pitch / 2 + x;
+                    Uint32 dc = *pixel;
+
+                    Rmask = format.Rmask;
+                    Gmask = format.Gmask;
+                    Bmask = format.Bmask;
+                    Amask = format.Amask;
+                    R = ((dc & Rmask) + (((color & Rmask) - (dc & Rmask)) * alpha >> 8)) & Rmask;
+                    G = ((dc & Gmask) + (((color & Gmask) - (dc & Gmask)) * alpha >> 8)) & Gmask;
+                    B = ((dc & Bmask) + (((color & Bmask) - (dc & Bmask)) * alpha >> 8)) & Bmask;
+                    if (Amask) {
+                        A = ((dc & Amask) + (((color & Amask) - (dc & Amask)) * alpha >> 8)) & Amask;
+                    }
+                    *pixel = cast(ushort)(R | G | B | A);
+                }
+            }
+            break;
+
+            case 3: {
+                /* Slow 24-bpp mode, usually not used */
+                Uint8 Rshift8, Gshift8, Bshift8, Ashift8;
+                Uint8 *pixel = cast(Uint8 *) dst.pixels + y * dst.pitch + x * 3;
+
+                Rshift = format.Rshift;
+                Gshift = format.Gshift;
+                Bshift = format.Bshift;
+                Ashift = format.Ashift;
+
+                Rshift8 = cast(ubyte)(Rshift / 8);
+                Gshift8 = cast(ubyte)(Gshift / 8);
+                Bshift8 = cast(ubyte)(Bshift / 8);
+                Ashift8 = cast(ubyte)(Ashift / 8);
+
+                if (alpha == 255) {
+                    *(pixel + Rshift8) = cast(ubyte)(color >> Rshift);
+                    *(pixel + Gshift8) = cast(ubyte)(color >> Gshift);
+                    *(pixel + Bshift8) = cast(ubyte)(color >> Bshift);
+                    *(pixel + Ashift8) = cast(ubyte)(color >> Ashift);
+                } else {
+                    Uint8 dR, dG, dB, dA = 0;
+                    Uint8 sR, sG, sB, sA = 0;
+
+                    dR = *((pixel) + Rshift8);
+                    dG = *((pixel) + Gshift8);
+                    dB = *((pixel) + Bshift8);
+                    dA = *((pixel) + Ashift8);
+
+                    sR = cast(ubyte)((color >> Rshift) & 0xff);
+                    sG = cast(ubyte)((color >> Gshift) & 0xff);
+                    sB = cast(ubyte)((color >> Bshift) & 0xff);
+                    sA = cast(ubyte)((color >> Ashift) & 0xff);
+
+                    dR = dR + ((sR - dR) * alpha >> 8);
+                    dG = dG + ((sG - dG) * alpha >> 8);
+                    dB = dB + ((sB - dB) * alpha >> 8);
+                    dA = dA + ((sA - dA) * alpha >> 8);
+
+                    *((pixel) + Rshift8) = dR;
+                    *((pixel) + Gshift8) = dG;
+                    *((pixel) + Bshift8) = dB;
+                    *((pixel) + Ashift8) = dA;
+                }
+            }
+            break;
+
+
+            version(EXPERIMENTAL_ALPHA_PIXEL_ROUTINE) {
+				default:
+                case 4: {		/* Probably :-) 32-bpp */
+                    if (alpha == 255) {
+                        *(cast(Uint32 *) dst.pixels + y * dst.pitch / 4 + x) = color;
+                    } else {
+                        Uint32 *pixel = cast(Uint32 *) dst.pixels + y * dst.pitch / 4 + x;
+                        Uint32 dR, dG, dB, dA;
+                        Uint32 dc = *pixel;
+
+                        Uint32 surfaceAlpha, preMultR, preMultG, preMultB;
+                        Uint32 aTmp;
+
+                        Rmask = format.Rmask;
+                        Gmask = format.Gmask;
+                        Bmask = format.Bmask;
+                        Amask = format.Amask;
+
+                        dR = (color & Rmask);
+                        dG = (color & Gmask);
+                        dB = (color & Bmask);
+                        dA = (color & Amask);
+
+                        Rshift = format.Rshift;
+                        Gshift = format.Gshift;
+                        Bshift = format.Bshift;
+                        Ashift = format.Ashift;
+
+                        preMultR = (alpha * (dR >> Rshift));
+                        preMultG = (alpha * (dG >> Gshift));
+                        preMultB = (alpha * (dB >> Bshift));
+
+                        surfaceAlpha = ((dc & Amask) >> Ashift);
+                        aTmp = (255 - alpha);
+                        if (A = 255 - ((aTmp * (255 - surfaceAlpha)) >> 8 )) {
+                            aTmp *= surfaceAlpha;
+                            R = (preMultR + ((aTmp * ((dc & Rmask) >> Rshift)) >> 8)) / A << Rshift & Rmask;
+                            G = (preMultG + ((aTmp * ((dc & Gmask) >> Gshift)) >> 8)) / A << Gshift & Gmask;
+                            B = (preMultB + ((aTmp * ((dc & Bmask) >> Bshift)) >> 8)) / A << Bshift & Bmask;
+                        }
+                        *pixel = R | G | B | (A << Ashift & Amask);
+
+                    }
+                }
+                break;
+            }
+            else {
+                //version(DEFAULT_ALPHA_PIXEL_ROUTINE) {
+				default:
+                case 4: {
+                    /* Probably :-) 32-bpp */
+                    if (alpha == 255) {
+                        *(cast(Uint32 *) dst.pixels + y * dst.pitch / 4 + x) = color;
+                    } else {
+                        Uint32 *pixel = cast(Uint32 *) dst.pixels + y * dst.pitch / 4 + x;
+                        Uint32 dc = *pixel;
+
+                        Rmask = format.Rmask;
+                        Gmask = format.Gmask;
+                        Bmask = format.Bmask;
+                        Amask = format.Amask;
+
+                        Rshift = format.Rshift;
+                        Gshift = format.Gshift;
+                        Bshift = format.Bshift;
+                        Ashift = format.Ashift;
+
+                        A = 0;
+                        R = ((dc & Rmask) + (((((color & Rmask) - (dc & Rmask)) >> Rshift) * alpha >> 8) << Rshift)) & Rmask;
+                        G = ((dc & Gmask) + (((((color & Gmask) - (dc & Gmask)) >> Gshift) * alpha >> 8) << Gshift)) & Gmask;
+                        B = ((dc & Bmask) + (((((color & Bmask) - (dc & Bmask)) >> Bshift) * alpha >> 8) << Bshift)) & Bmask;
+                        if (Amask) {
+                            A = ((dc & Amask) + (((((color & Amask) - (dc & Amask)) >> Ashift) * alpha >> 8) << Ashift)) & Amask;
+                        }
+                        *pixel = R | G | B | A;
+                    }
+                }
+                break;
+            }
+
+
+            }
+
+            return (0);
+        }
+		return( -1 );
+    }
+
+/*!
+\brief Pixel draw with blending enabled if a<255 - no surface locking.
+
+\param dst The surface to draw on.
+\param x X (horizontal) coordinate of the pixel.
+\param y Y (vertical) coordinate of the pixel.
+\param color The color value of the pixel to draw (0xRRGGBBAA).
+
+\returns Returns 0 on success, -1 on failure.
+*/
+int pixelColorNolock(SDL_Surface * dst, Sint16 x, Sint16 y, Uint32 color)
+{
+	Uint8 alpha;
+	Uint32 mcolor;
+	int result = 0;
+
+	/*
+	* Setup color
+	*/
+	alpha = cast(ubyte)(color & 0x000000ff);
+	mcolor =
+		SDL_MapRGBA(dst.format, cast(ubyte)((color & 0xff000000) >> 24),
+		cast(ubyte)((color & 0x00ff0000) >> 16), cast(ubyte)((color & 0x0000ff00) >> 8), alpha);
+
+	/*
+	* Draw
+	*/
+	result = _putPixelAlpha(dst, x, y, mcolor, alpha);
+
+	return (result);
+}
+
+
+
+    /*!
+    \brief Pixel draw with blending enabled if a<255.
+
+    \param dst The surface to draw on.
+    \param x X (horizontal) coordinate of the pixel.
+    \param y Y (vertical) coordinate of the pixel.
+    \param color The color value of the pixel to draw (0xRRGGBBAA).
+
+    \returns Returns 0 on success, -1 on failure.
+    */
+    int pixelColor(SDL_Surface * dst, Sint16 x, Sint16 y, Uint32 color) {
+        Uint8 alpha;
+        Uint32 mcolor;
+        int result = 0;
+
+        /*
+        * Lock the surface
+        */
+        if (SDL_MUSTLOCK(dst)) {
+            if (SDL_LockSurface(dst) < 0) {
+                return (-1);
+            }
+        }
+
+        /*
+        * Setup color
+        */
+        alpha = cast(ubyte)(color & 0x000000ff);
+        mcolor =
+            SDL_MapRGBA(dst.format,
+				cast(ubyte)((color & 0xff000000) >> 24),
+                cast(ubyte)((color & 0x00ff0000) >> 16),
+                cast(ubyte)((color & 0x0000ff00) >> 8), alpha);
+
+        /*
+        * Draw
+        */
+        result = _putPixelAlpha(dst, x, y, mcolor, alpha);
+
+        /*
+        * Unlock the surface
+        */
+        if (SDL_MUSTLOCK(dst)) {
+            SDL_UnlockSurface(dst);
+        }
+
+        return (result);
+    }
+
+
+/*
+#define CLIP_LEFT_EDGE   0x1
+#define CLIP_RIGHT_EDGE  0x2
+#define CLIP_BOTTOM_EDGE 0x4
+#define CLIP_TOP_EDGE    0x8
+#define CLIP_INSIDE(a)   (!a)
+#define CLIP_REJECT(a,b) (a&b)
+#define CLIP_ACCEPT(a,b) (!(a|b))
+*/
+enum { CLIP_LEFT_EDGE=0x1,CLIP_RIGHT_EDGE=0x2, CLIP_BOTTOM_EDGE=0x4 ,CLIP_TOP_EDGE=0x8 };
+
+
+/*!
+\brief Internal clip-encoding routine.
+
+Calculates a segement-based clipping encoding for a point against a rectangle.
+
+\param x X coordinate of point.
+\param y Y coordinate of point.
+\param left X coordinate of left edge of the rectangle.
+\param top Y coordinate of top edge of the rectangle.
+\param right X coordinate of right edge of the rectangle.
+\param bottom Y coordinate of bottom edge of the rectangle.
+*/
+static int _clipEncode(Sint16 x, Sint16 y, Sint16 left, Sint16 top, Sint16 right, Sint16 bottom)
+{
+	int code = 0;
+
+	if (x < left) {
+		code |= CLIP_LEFT_EDGE;
+	} else if (x > right) {
+		code |= CLIP_RIGHT_EDGE;
+	}
+	if (y < top) {
+		code |= CLIP_TOP_EDGE;
+	} else if (y > bottom) {
+		code |= CLIP_BOTTOM_EDGE;
+	}
+	return code;
+}
+
+
+
+
+
+
+
+/*!
+\brief Clip line to a the clipping rectangle of a surface.
+
+\param dst Target surface to draw on.
+\param x1 Pointer to X coordinate of first point of line.
+\param y1 Pointer to Y coordinate of first point of line.
+\param x2 Pointer to X coordinate of second point of line.
+\param y2 Pointer to Y coordinate of second point of line.
+*/
+static int _clipLine(SDL_Surface * dst, Sint16 * x1, Sint16 * y1, Sint16 * x2, Sint16 * y2)
+{
+	Sint16 left, right, top, bottom;
+	int code1, code2;
+	int draw = 0;
+	Sint16 swaptmp;
+	float m;
+
+	/*
+	* Get clipping boundary
+	*/
+	left = dst.clip_rect.x;
+	right = dst.clip_rect.x + dst.clip_rect.w - 1;
+	top = dst.clip_rect.y;
+	bottom = dst.clip_rect.y + dst.clip_rect.h - 1;
+
+	while (1) {
+		code1 = _clipEncode(*x1, *y1, left, top, right, bottom);
+		code2 = _clipEncode(*x2, *y2, left, top, right, bottom);
+		if ( !(code1 | code2) ) { // CLIP_ACCEPT(code1, code2)) {
+			draw = 1;
+			break;
+		} else if (code1 & code2 ) // (CLIP_REJECT(code1, code2))
+			break;
+		else {
+			if ( !code1 ) { // CLIP_INSIDE(code1)) {
+				swaptmp = *x2;
+				*x2 = *x1;
+				*x1 = swaptmp;
+				swaptmp = *y2;
+				*y2 = *y1;
+				*y1 = swaptmp;
+				swaptmp = cast(short)code2;
+				code2 = code1;
+				code1 = swaptmp;
+			}
+			if (*x2 != *x1) {
+				m = (*y2 - *y1) / cast(float)(*x2 - *x1);
+			} else {
+				m = 1.0f;
+			}
+			if (code1 & CLIP_LEFT_EDGE) {
+				*y1 += cast(Sint16) ((left - *x1) * m);
+				*x1 = left;
+			} else if (code1 & CLIP_RIGHT_EDGE) {
+				*y1 += cast(Sint16) ((right - *x1) * m);
+				*x1 = right;
+			} else if (code1 & CLIP_BOTTOM_EDGE) {
+				if (*x2 != *x1) {
+					*x1 += cast(Sint16) ((bottom - *y1) / m);
+				}
+				*y1 = bottom;
+			} else if (code1 & CLIP_TOP_EDGE) {
+				if (*x2 != *x1) {
+					*x1 += cast(Sint16) ((top - *y1) / m);
+				}
+				*y1 = top;
+			}
+		}
+	}
+
+	return draw;
+}
+
+
+    /*!
+    \brief Draw line with alpha blending.
+
+    \param dst The surface to draw on.
+    \param x1 X coordinate of the first point of the line.
+    \param y1 Y coordinate of the first point of the line.
+    \param x2 X coordinate of the second point of the line.
+    \param y2 Y coordinate of the second point of the line.
+    \param color The color value of the line to draw (0xRRGGBBAA).
+
+    \returns Returns 0 on success, -1 on failure.
+    */
+    int lineColor(SDL_Surface * dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color) {
+        int pixx, pixy;
+        int x, y;
+        int dx, dy;
+        int ax, ay;
+        int sx, sy;
+        int swaptmp;
+        Uint8 *pixel;
+        Uint8 *colorptr;
+
+        /*
+        * Clip line and test if we have to draw
+        */
+        if (!(_clipLine(dst, &x1, &y1, &x2, &y2))) {
+            return (0);
+        }
+
+        /*
+        * Test for special cases of straight lines or single point
+        */
+        /*
+        if (x1 == x2) {
+            if (y1 < y2) {
+                return (vlineColor(dst, x1, y1, y2, color));
+            } else if (y1 > y2) {
+                return (vlineColor(dst, x1, y2, y1, color));
+            } else {
+                return (pixelColor(dst, x1, y1, color));
+            }
+        }
+        if (y1 == y2) {
+            if (x1 < x2) {
+                return (hlineColor(dst, x1, x2, y1, color));
+            } else if (x1 > x2) {
+                return (hlineColor(dst, x2, x1, y1, color));
+            }
+        }
+		*/
+        /*
+        * Variable setup
+        */
+        dx = x2 - x1;
+        dy = y2 - y1;
+        sx = (dx >= 0) ? 1 : -1;
+        sy = (dy >= 0) ? 1 : -1;
+
+        /* Lock surface */
+        if (SDL_MUSTLOCK(dst)) {
+            if (SDL_LockSurface(dst) < 0) {
+                return (-1);
+            }
+        }
+
+        /*
+        * Check for alpha blending
+        */
+        if ((color & 255) == 255) {
+
+            /*
+            * No alpha blending - use fast pixel routines
+            */
+
+            /*
+            * Setup color
+            */
+            colorptr = cast(Uint8 *) & color;
+            if (SDL_BYTEORDER == SDL_BIG_ENDIAN) {
+                color = SDL_MapRGBA(dst.format, colorptr[0], colorptr[1], colorptr[2], colorptr[3]);
+            } else {
+                color = SDL_MapRGBA(dst.format, colorptr[3], colorptr[2], colorptr[1], colorptr[0]);
+            }
+
+            /*
+            * More variable setup
+            */
+            dx = sx * dx + 1;
+            dy = sy * dy + 1;
+            pixx = dst.format.BytesPerPixel;
+            pixy = dst.pitch;
+            pixel = (cast(Uint8 *) dst.pixels) + pixx * cast(int) x1 + pixy * cast(int) y1;
+            pixx *= sx;
+            pixy *= sy;
+            if (dx < dy) {
+                swaptmp = dx;
+                dx = dy;
+                dy = swaptmp;
+                swaptmp = pixx;
+                pixx = pixy;
+                pixy = swaptmp;
+            }
+
+            /*
+            * Draw
+            */
+            x = 0;
+            y = 0;
+            switch (dst.format.BytesPerPixel) {
+            case 1:
+                for (; x < dx; x++, pixel += pixx) {
+                    *pixel = cast(ubyte)color;
+                    y += dy;
+                    if (y >= dx) {
+                        y -= dx;
+                        pixel += pixy;
+                    }
+                }
+                break;
+            case 2:
+                for (; x < dx; x++, pixel += pixx) {
+                    *cast(Uint16 *) pixel = cast(ushort)color;
+                    y += dy;
+                    if (y >= dx) {
+                        y -= dx;
+                        pixel += pixy;
+                    }
+                }
+                break;
+            case 3:
+                for (; x < dx; x++, pixel += pixx) {
+                    if (SDL_BYTEORDER == SDL_BIG_ENDIAN) {
+                        pixel[0] = cast(ubyte)((color >> 16) & 0xff);
+                        pixel[1] = cast(ubyte)((color >> 8) & 0xff);
+                        pixel[2] = cast(ubyte)(color & 0xff);
+                    } else {
+                        pixel[0] = cast(ubyte)(color & 0xff);
+                        pixel[1] = cast(ubyte)((color >> 8) & 0xff);
+                        pixel[2] = cast(ubyte)((color >> 16) & 0xff);
+                    }
+                    y += dy;
+                    if (y >= dx) {
+                        y -= dx;
+                        pixel += pixy;
+                    }
+                }
+                break;
+            default:		/* case 4 */
+                for (; x < dx; x++, pixel += pixx) {
+                    *cast(Uint32 *) pixel = color;
+                    y += dy;
+                    if (y >= dx) {
+                        y -= dx;
+                        pixel += pixy;
+                    }
+                }
+                break;
+            }
+
+        } else {
+
+            /*
+            * Alpha blending required - use single-pixel blits
+            */
+
+            ax = std.math.abs(dx) << 1;
+            ay = std.math.abs(dy) << 1;
+            x = x1;
+            y = y1;
+            if (ax > ay) {
+                int d = ay - (ax >> 1);
+
+                while (x != x2) {
+                    pixelColorNolock (dst, cast(short)x, cast(short)y, color);
+                    if (d > 0 || (d == 0 && sx == 1)) {
+                        y += sy;
+                        d -= ax;
+                    }
+                    x += sx;
+                    d += ay;
+                }
+            } else {
+                int d = ax - (ay >> 1);
+
+                while (y != y2) {
+                    pixelColorNolock (dst, cast(short)x, cast(short)y, color);
+                    if (d > 0 || ((d == 0) && (sy == 1))) {
+                        x += sx;
+                        d -= ay;
+                    }
+                    y += sy;
+                    d += ax;
+                }
+            }
+            pixelColorNolock (dst, cast(short)x, cast(short)y, color);
+
+        }
+
+        /* Unlock surface */
+        if (SDL_MUSTLOCK(dst)) {
+            SDL_UnlockSurface(dst);
+        }
+
+        return (0);
+    }
+
+
+
+
+
+}
+
+
+
 import inputmanager;
 import gameconstants;
 import std.stdio;
+import graphics;
 
 class GUI {
 
 		void render() {
 			super.render();
 			mCaret.draw( mX+mW, mY );
+			mGraphics.drawBox( cast(short)mX-2, cast(short)mY-2, cast(ushort)mWidth+4, cast(ushort)mH+4 );
 		}
 	}
 
 		}
 
 		void buildHighlight( ubyte power=64 ) {
+
+			mHl = mGraphics.createTransparentSurface( mW, mH, power );
+			/*
 			mHl = SDL_CreateRGBSurface(
 				SDL_HWSURFACE,
 				mW, mH, 32,
 				0x00, 0x00, 0x00, 0x00 );
 			SDL_FillRect( mHl, null, 0xFFFFFFFF );
-			SDL_SetAlpha( mHl, SDL_SRCALPHA, power );
+			SDL_SetAlpha( mHl, SDL_SRCALPHA, power ); */
 		}
 
 		bool isIn( int x, int y ) {
 
 		void render() {
 			if( mHighlighted) SDL_BlitSurface( mHl, null, gScreen.mSurface, &mRect );
+			//mGraphics.drawBox( cast(short)mX-2, cast(short)mY-2, cast(ushort)mW+4, cast(ushort)mH+4 );
 		}
 
 		void notifyListener() {
 		TextInput addTextInput( uint width, string text, string fontid="" ) {
 			TextInput ti = new TextInput( this, mXInsert, mYInsert, width, text, fontid );
 			mTextInputs ~= ti;
-			resize( ti.width, ti.height );
+			resize( ti.mWidth, ti.height );
 			return(ti);
 		}
 
 
 			if( updateBg ) {
 				if( mBg != null ) SDL_FreeSurface( mBg );
-				mBg = SDL_CreateRGBSurface(
-					SDL_HWSURFACE,
-					mW, mH, 32, 0,0,0,0 );
+				mBg = mGraphics.createTransparentSurface( mW, mH, 0xA0, 0x000000 );
 
 				mRect.w =cast(ushort)mW;
 				mRect.h =cast(ushort)mH;
 			if( mHAlign == ALIGN.FREE ) mX = x; { moved = true; }
 			if( mVAlign == ALIGN.FREE ) mY = y; { moved = true; }
 
-			//moved = doAlign( mX, mHAlign, mW, gScreen.WIDTH ) || moved;
-			//moved = doAlign( mY, mVAlign, mH, gScreen.HEIGHT ) || moved;
-			doAlign( mX, mHAlign, mW, gScreen.WIDTH );
-			doAlign( mY, mVAlign, mH, gScreen.HEIGHT );
+			moved = doAlign( mX, mHAlign, mW, gScreen.WIDTH ) || moved;
+			moved = doAlign( mY, mVAlign, mH, gScreen.HEIGHT ) || moved;
 
-			//if( moved ) {
+			if( moved ) {
 				mRect.x = cast(short)mX;
 				mRect.y = cast(short)mY;
 
 				foreach( inout p; mPanels ) {
 					p.move( mX + offX, mY + offY );
 				}
-			//}
+			}
 		}
 
 		void setVerticalAlign( ALIGN vAlign ) {
 
 		void render() {
 			if( mBg != null )
-				SDL_BlitSurface( mBg, null, gScreen.mSurface, &mRect );
+				//SDL_BlitSurface( mBg, null, gScreen.mSurface, &mRect );
+				mGraphics.drawImage( mBg, mX, mY ); // Rect.x, mRect.y );
 
 			foreach( b; mButtons ) { b.render(); }
 			foreach( l; mLabels ) { l.render(); }
 			foreach( ti; mTextInputs ) { ti.render(); }
 			foreach( p; mPanels ) { p.render(); }
+
+			mGraphics.drawBox( cast(short)mX, cast(short)mY, cast(ushort)mW, cast(ushort)mH );
 		}
 
 		void checkButtons( int x, int y, bool clicked ) {
 	PanelList mPanels;
 //	SList!(Menu) mMenus;
 	static GUI mInstance;
+	Graphics mGraphics;
 
 	public static GUI instance() {
 		if( mInstance is null ) mInstance = new GUI();
 		mPointerHidden = false;
 		changePointer( "pointer.png" );
 		mPanels = new PanelList;
+
+		mGraphics = new Graphics();
+		mGraphics.setColor( 0xAAAAAAFF );
 	}
 
 	public static void destroy() {