[CF-Devel] Patch to enable SDL support in the Gtk client

Scott MacFiggen smurf at CSUA.Berkeley.EDU
Fri Jun 15 23:13:56 CDT 2001


The following patch enables the Gtk client to use SDL to blit 
png images instead of using GdkPixbuf. Initial tests on my machines
show about a 30% increase in blit speeds but I'm pretty sure that
will be very machine dependent.  The code isn't all that optimized
yet either. In particular, when the map scrolls the whole screen
image is regenerated instead of just memcpy'ed.

This patch also provides the same interpolated darkness that the
-pngximage option uses. An option in the config menu allows 
dynamic switching between this per-pixel darkness and tile based
darkness. The tile based option uses an alpha blended surface,
not stipple maps like the older clients. 

Thier is also an option to turn on a grid overlay, I was using this
to help debug a few things and left it in, might be useful to someone
someday. 

To use this patch, you must have SDL 1.1.3 installed and SDL_image 1.x.
The configure scripts check for the proper version of SDL and 
that the SDL_image library has the proper PNG image loading routine.

Default is to use SDL if available, if not it falls back to Gtk.
It is a compile time option, once compiled in you can't use 
pngximage and vice versa. If you have SDL but don't want to use it,
pass configure the --disable-sdl option.  I left 'configure' out of
the patch so you'll have to run aclocal;autoconf;automake to 
regenerate it.

Current state of the code is 'works for me'. I have only tested it on
32 bit displays although code is in place for 16 bit displays.  

SDL_image has very poor support for XPM images so this patch will only
work with PNG images. We are dropping XPM anyway right?

umm.. Oh yeah, the patch is against the lastest CVS code.

	-Scott
-------------- next part --------------
Common subdirectories: client/CVS and /home/smf/projects/crossfire/cvs/client/CVS
diff -c5 --exclude-from=exclude client/client.man /home/smf/projects/crossfire/cvs/client/client.man
*** client/client.man	Mon Jun  4 23:24:14 2001
--- /home/smf/projects/crossfire/cvs/client/client.man	Fri Jun 15 17:05:35 2001
***************
*** 79,98 ****
--- 79,102 ----
  further down.)  Png have all the same features of XPM, but are
  slightly larger (32x32 instead of 24x24), appear better, and do the the
  efficiency of the png format, actually take less bandwidth to transmit
  than the xpm images.  Using the png images require that the client
  has been compiled with png support.
+ Note: If the client is compiled with SDL support, -png is the only
+ supported image type
  
  .TP
  .B -pngximage
  gcfclient only.  This option is only meaningful if png graphics are
  being used.  It uses a GdkRgb structure - this allows much
  better effects (especially darkness).  Performance may be worse
  when using this option - this depends on many factors.  Like
  the mapsize option above, it is suggested the experimentation is
  done to make performance is still acceptable.  This option does
  not affect bandwidth - it only affects cpu performancs.
+ Note: This option is not available if compiled with SDL support
+ but all the functionality exists in the SDL client.
  
  .TP
  .B -showicon
  This shows a little icon next to items in your inventory that contains
  a brief description of some of the item properties (magic, cursed,
***************
*** 266,275 ****
--- 270,280 ----
  .PP
  Please let me know about any bugs you find in the client.
  .SH AUTHOR
  Copyright (C) 1994,2000 Mark Wedel (
     
     mwedel at scruz.net
     
     )
  GTK port by David Sundqvist (
     
     azzie at netpolicy.com
     
     )
+ SDL support added by Scott MacFiggen (
     
     smurf at CSUA.Berkeley.EDU
     
     )
  
  There are a great many other contributors to both the client and server
  that are not mentioned here.
  
  .ft R
diff -c5 --exclude-from=exclude client/config.h.in /home/smf/projects/crossfire/cvs/client/config.h.in
*** client/config.h.in	Mon Jun  4 20:01:48 2001
--- /home/smf/projects/crossfire/cvs/client/config.h.in	Fri Jun 15 13:43:59 2001
***************
*** 70,79 ****
--- 70,81 ----
  #undef HAVE_LIBM
  
  /* Define if you have the png library (-lpng).  */
  #undef HAVE_LIBPNG
  
+ #undef HAVE_SDL
+ 
  /* Name of package */
  #undef PACKAGE
  
  /* Version number of package */
  #undef VERSION
diff -c5 --exclude-from=exclude client/configure.in /home/smf/projects/crossfire/cvs/client/configure.in
*** client/configure.in	Thu Jun  7 16:20:12 2001
--- /home/smf/projects/crossfire/cvs/client/configure.in	Fri Jun 15 15:47:46 2001
***************
*** 72,81 ****
--- 72,85 ----
  		gtk=no, gtk=yes )
  
  AC_ARG_ENABLE(gnome, [  --disable-gnome         don't make gnome client [default=make gnome client if available]],
  		gnome=no, gnome=yes )
  
+ AC_ARG_ENABLE(sdl, [  --disable-sdl              Disable linking with the SDL library, default is to use it if available ],
+                 use_sdl=no, use_sdl=yes)
+ 
+ 
  AC_PROG_CC
  
  AC_C_BIGENDIAN
  
  networklibs="yes"
***************
*** 221,230 ****
--- 225,255 ----
  AC_SUBST(GUI_SRCS)
  AC_SUBST(SND_LIBS)
  AC_SUBST(LDFLAGS)
  AC_SUBST(TARGET)
  
+ dnl Check for SDL 1.1.3 and sdl_image
+ dnl note SDL_image does not ship with an sdl-image-config
+ dnl so I'll just assume it is in the same dir as SDL
+ if eval "test x$use_sdl = xyes"; then
+   AM_PATH_SDL(1.1.3)
+   if eval "test x$no_sdl = x"; then
+       AC_CHECK_LIB( SDL_image, IMG_LoadPNG_RW, 
+                     have_sdlimage="yes", have_sdlimage="no", $SDL_CFLAGS) 
+       if eval "test x$have_sdlimage = xyes"; then
+           SDL_LIBS="$SDL_LIBS -lSDL_image"
+       else
+           no_sdl= "yes"
+       fi
+   fi
+ 
+   if eval "test x$no_sdl = x"; then
+           AC_DEFINE(HAVE_SDL)
+           CFLAGS="$CFLAGS $SDL_CFLAGS"
+           LIBS="$LIBS $SDL_LIBS"
+   fi
+ fi
  
  dnl The following hacks for modifying CFLAGS were borrowed from the GIMP.
  if test -n "$DEBUGFLAG"; then
    CFLAGS="$DEBUGFLAG $CFLAGS"
  fi
diff -c5 --exclude-from=exclude client/gx11.c /home/smf/projects/crossfire/cvs/client/gx11.c
*** client/gx11.c	Wed Jun 13 00:01:20 2001
--- /home/smf/projects/crossfire/cvs/client/gx11.c	Fri Jun 15 20:54:06 2001
***************
*** 109,118 ****
--- 109,140 ----
  #ifdef HAVE_LIBPNG
  #define PNG_GDK
  #include "png.c"
  #endif
  
+ #ifdef HAVE_SDL
+ #include <SDL.h>
+ #include <SDL_image.h>
+ 
+ static void do_SDL_error( gchar* SDL_function, gchar* file, int line)
+ {
+   fprintf( stderr, "ERROR on %s in file %s line %d\n%s\n", SDL_function,
+ 	   file, line, SDL_GetError());
+   SDL_Quit();
+   exit( 1);
+ }
+ 
+ typedef struct 
+ {
+   SDL_Surface *surface;
+ } SurfaceInfo;
+ 
+ static int per_pixel_lighting= 1;
+ static int per_tile_lighting= 0;
+ static int show_grid= FALSE;
+ #endif /* HAVE_SDL */
+ 
  #define MAXPIXMAPNUM 10000
  #define GDK_XUTIL
  
  static int image_size=24;
  
***************
*** 248,258 ****
--- 270,285 ----
  #define MAX_INFO_WIDTH 80
  #define MAXNAMELENGTH 50
  
  static int gargc;
  
+ #ifdef HAVE_SDL
+ Display_Mode display_mode = Png_Display;
+ #else
  Display_Mode display_mode = DISPLAY_MODE;
+ #endif
+ 
  
  static uint8	
      split_windows=FALSE,
      cache_images=FALSE,
      nopopups=FALSE, 
***************
*** 319,328 ****
--- 346,364 ----
  static GdkGC *map_gc;
  static GtkWidget *mapvbox;
  
  
  static struct PixmapInfo pixmaps[MAXPIXMAPNUM];
+ 
+ #ifdef HAVE_SDL
+ static SurfaceInfo surfaces[MAXPIXMAPNUM];
+ 
+ /* Actual SDL surface the game view is painted on */
+ static SDL_Surface* mapsurface;
+ static SDL_Surface* lightmap;
+ #endif
+ 
  #define INFOLINELEN 500
  #define XPMGCS 100
  
  static GtkWidget *ccheckbutton1;
  static GtkWidget *ccheckbutton2;
***************
*** 332,341 ****
--- 368,383 ----
  static GtkWidget *ccheckbutton6;
  static GtkWidget *ccheckbutton7;
  static GtkWidget *ccheckbutton8;
  static GtkWidget *inv_notebook;
  
+ #ifdef HAVE_SDL
+ static GtkWidget *cradiobutton1;
+ static GtkWidget *cradiobutton2;
+ static GtkWidget *ccheckbutton9;
+ #endif
+ 
  static GtkTooltips *tooltips;
  
  static GtkWidget *dialogtext;
  static GtkWidget *dialog_window;
  static GtkWidget *drawingarea;
***************
*** 429,445 ****
  #define BPP	3
  
  /* Pixels representing entire viewable screen.  This amounts to about <BPP> mb */
  
  #define SCREEN_SIZE MAP_MAX_SIZE * MAP_MAX_SIZE*32*32*BPP
  static uint8 screen[SCREEN_SIZE];
! 
! 
  static guchar map_did_scroll=0;
  
  #include "xutil.c"
  
  void create_windows (void);
  
  
  /* Convert xpm memory buffer to xpm data (needed since GTK/GDK doesnt have a
   * function to create from buffer rather than data
--- 471,571 ----
  #define BPP	3
  
  /* Pixels representing entire viewable screen.  This amounts to about <BPP> mb */
  
  #define SCREEN_SIZE MAP_MAX_SIZE * MAP_MAX_SIZE*32*32*BPP
+ #ifndef HAVE_SDL
  static uint8 screen[SCREEN_SIZE];
! #endif
  static guchar map_did_scroll=0;
  
  #include "xutil.c"
  
+ #ifdef HAVE_SDL
+ /*
+  * Takes two args, the first is the GtkWindow to draw on, this should always
+  * be 'drawingarea'. The second is a boolean, if 0 then the whole
+  * SDL system in initialized or reinited if already run once before,
+  * if non zero then only the lightmap is rebuilt, if we switch between
+  * per-pixel or per-tile lighting 
+  */
+ static void init_SDL( GtkWidget* sdl_window, int just_lightmap)
+ {
+ 
+   char SDL_windowhack[32];
+ 
+   if( just_lightmap == 0)
+     {
+ 
+       g_assert( sdl_window != NULL);
+       if( SDL_WasInit( SDL_INIT_VIDEO) != 0)
+ 	{
+ 	  if( lightmap)
+ 	    SDL_FreeSurface( lightmap);
+ 	  if( mapsurface)
+ 	    SDL_FreeSurface( mapsurface);
+ 	  
+ 	  SDL_Quit();
+ 	}
+ 
+       /* 
+        * SDL hack to tell SDL which xwindow to paint onto 
+        */
+       sprintf( SDL_windowhack, "SDL_WINDOWID=%ld",
+ 	       GDK_WINDOW_XWINDOW(sdl_window->window) );
+       putenv( SDL_windowhack);
+       
+       if( SDL_Init( SDL_INIT_VIDEO) < 0)
+ 	{
+ 	  fprintf( stderr, "Could not initialize SDL: %s\n", SDL_GetError());
+ 	  gtk_main_quit();
+ 	}
+ 
+       mapsurface= SDL_SetVideoMode( image_size*mapx, image_size*mapy, 0, SDL_HWSURFACE|SDL_DOUBLEBUF);
+       
+       if( mapsurface == NULL)
+ 	{
+ 	  do_SDL_error( "SetVideoMode", __FILE__, __LINE__);
+ 	}
+     }
+ 
+   if( just_lightmap != 0)
+     {
+       if( lightmap) SDL_FreeSurface( lightmap);
+     }
+   
+   
+   lightmap= SDL_CreateRGBSurface( SDL_HWSURFACE|SDL_SRCALPHA, image_size,
+ 				  image_size,
+ 				  mapsurface->format->BitsPerPixel,
+ 				  mapsurface->format->Rmask,
+ 				  mapsurface->format->Gmask,
+ 				  mapsurface->format->Bmask,
+ 				  mapsurface->format->Amask);
+   if( lightmap == NULL)
+     {
+       do_SDL_error( "SDL_CreateRGBSurface", __FILE__, __LINE__);
+     }
+   
+   if( per_pixel_lighting)
+     {
+       /* Convert surface to have a full alpha channel if we are doing
+        * per-pixel lighting */
+       lightmap= SDL_DisplayFormatAlpha( lightmap);
+       if( lightmap == NULL)
+ 	{
+ 	  do_SDL_error( "DisplayFormatAlpha", __FILE__, __LINE__);
+ 	}
+     }
+ 
+   if( show_grid == TRUE)
+     {
+       overlay_grid( TRUE, 0, 0);
+     }
+ }
+ #endif
+ 
  void create_windows (void);
  
  
  /* Convert xpm memory buffer to xpm data (needed since GTK/GDK doesnt have a
   * function to create from buffer rather than data
***************
*** 729,745 ****
--- 855,897 ----
      pixmaps[0].gdkpixmap = gdk_pixmap_create_from_xpm_d(gtkwin_root->window,
  							&pixmaps[0].gdkmask,
  							&style->bg[GTK_STATE_NORMAL],
  							(gchar **)question);
      
+ #ifdef HAVE_SDL
+     /* SDL has totally lame support for loading XPM images, its rgb.txt database
+      * consists of 6 colors so we will just use a blue tile or something
+      * instead of a question mark
+      */
+     surfaces[0].surface= SDL_CreateRGBSurface( SDL_HWSURFACE,
+ 					       image_size,
+ 					       image_size,
+ 					       mapsurface->format->BitsPerPixel,
+ 					       mapsurface->format->Rmask,
+ 					       mapsurface->format->Gmask,
+ 					       mapsurface->format->Bmask,
+ 					       mapsurface->format->Amask);
+ 
+     if( surfaces[0].surface == NULL)
+       do_SDL_error( "CreateRGBSurface", __FILE__, __LINE__);
+ 
+     if ( SDL_FillRect( surfaces[0].surface, NULL, 
+ 		       SDL_MapRGB( mapsurface->format, 0, 0, 255)) < 0)
+       do_SDL_error( "FillRect", __FILE__, __LINE__);
+     
+ #endif
+ 
      pixmaps[0].bg = 0;
      pixmaps[0].fg = 1;
      facetoname[0]=NULL;
  
      /* Initialize all the images to be of the same value. */
      for (i=1; i<MAXPIXMAPNUM; i++)  {
  	pixmaps[i]=pixmaps[0];
+ #ifdef HAVE_SDL
+ 	surfaces[i]= surfaces[0];
+ #endif
  	facetoname[i]=NULL;
      }
  
  #ifdef IMAGECACHEDIR
      strcpy(facecachedir, IMAGECACHEDIR);
***************
*** 902,945 ****
  
  static gint
  configure_event (GtkWidget *widget, GdkEventConfigure *event)
  {
  
      mapgc = gdk_gc_new (drawingarea->window);
      display_map_doneupdate(TRUE);
      return TRUE;
  }
  
  
  
  /* Redraw the screen from the backing pixmap */
  static gint
  expose_event (GtkWidget *widget, GdkEventExpose *event)
  {
      display_map_doneupdate(TRUE);
      return FALSE;
  }
  
  /*
   * Sets up player game view window, implemented as a gtk table. Cells are initialized
   * with the bg.xpm pixmap to avoid resizes and to initialize GC's and everything for the
   * actual drawing routines later.
   */
  
- 
- 
- 
- 
  static int get_game_display(GtkWidget *frame) {
    GtkWidget *gtvbox, *gthbox;
-   
    gtvbox = gtk_vbox_new (FALSE, 0);
    gtk_container_add (GTK_CONTAINER (frame), gtvbox);
    gthbox = gtk_hbox_new (FALSE, 0);
    gtk_box_pack_start (GTK_BOX (gtvbox), gthbox, FALSE, FALSE, 1);
!   
!   drawingarea = gtk_drawing_area_new();
    gtk_drawing_area_size(GTK_DRAWING_AREA(drawingarea), image_size*mapx,image_size*mapy);
    /* Add mouseclick events to the drawing area */
  
    gtk_widget_set_events (drawingarea, GDK_BUTTON_PRESS_MASK);
  
--- 1054,1102 ----
  
  static gint
  configure_event (GtkWidget *widget, GdkEventConfigure *event)
  {
  
+ #ifdef HAVE_SDL
+   if( mapsurface)
+     SDL_UpdateRect( mapsurface, 0, 0, 0, 0);
+ #else
      mapgc = gdk_gc_new (drawingarea->window);
      display_map_doneupdate(TRUE);
+ #endif
      return TRUE;
  }
  
  
  
  /* Redraw the screen from the backing pixmap */
  static gint
  expose_event (GtkWidget *widget, GdkEventExpose *event)
  {
+ #ifdef HAVE_SDL
+   if( mapsurface)
+     SDL_UpdateRect( mapsurface, 0, 0, 0, 0);
+ #else
      display_map_doneupdate(TRUE);
+ #endif
      return FALSE;
  }
  
  /*
   * Sets up player game view window, implemented as a gtk table. Cells are initialized
   * with the bg.xpm pixmap to avoid resizes and to initialize GC's and everything for the
   * actual drawing routines later.
   */
  
  static int get_game_display(GtkWidget *frame) {
    GtkWidget *gtvbox, *gthbox;
    gtvbox = gtk_vbox_new (FALSE, 0);
    gtk_container_add (GTK_CONTAINER (frame), gtvbox);
    gthbox = gtk_hbox_new (FALSE, 0);
    gtk_box_pack_start (GTK_BOX (gtvbox), gthbox, FALSE, FALSE, 1);
! 
!   drawingarea = gtk_drawing_area_new(); 
    gtk_drawing_area_size(GTK_DRAWING_AREA(drawingarea), image_size*mapx,image_size*mapy);
    /* Add mouseclick events to the drawing area */
  
    gtk_widget_set_events (drawingarea, GDK_BUTTON_PRESS_MASK);
  
***************
*** 961,971 ****
--- 1118,1140 ----
    
    gtk_widget_show(drawingarea);
  
    gtk_widget_show(gthbox);
    gtk_widget_show(gtvbox);
+ 
+ 
+   gtk_signal_connect (GTK_OBJECT (frame), "expose_event",
+ 		      (GtkSignalFunc) expose_event, NULL);
+   gtk_signal_connect (GTK_OBJECT(frame),"configure_event",	
+ 		      (GtkSignalFunc) configure_event, NULL);
+ 
    gtk_widget_show (frame);
+ 
+ 
+ #ifdef HAVE_SDL
+   /*  init_SDL( drawingarea, 0); */
+ #endif
    return 0;
  }
  
  
  
***************
*** 3378,3387 ****
--- 3547,3584 ----
      if (nopopups) {
         gtk_tooltips_disable(tooltips);
        nopopups=FALSE;
      }
    }
+ #ifdef HAVE_SDL
+   if( GTK_TOGGLE_BUTTON( cradiobutton1)->active) {
+     if( per_pixel_lighting == 0)
+       {
+ 	per_pixel_lighting= 1;
+ 	per_tile_lighting= 0;
+ 	init_SDL( NULL, 1);
+ 	if( csocket.fd)
+ 	  cs_write_string( csocket.fd, "mapredraw", 9);
+       }
+   } else {
+     if( per_pixel_lighting == 1)
+       {
+ 	per_pixel_lighting= 0;
+ 	per_tile_lighting= 1;
+ 	init_SDL( NULL, 1);
+ 	if( csocket.fd)
+ 	  cs_write_string( csocket.fd, "mapredraw", 9);
+       }
+   }
+   if( GTK_TOGGLE_BUTTON( ccheckbutton9)->active) {
+     if( show_grid == FALSE)
+       show_grid= TRUE;
+   } else {
+     if( show_grid == TRUE)
+       show_grid= FALSE;
+   }
+ #endif
  }
  
  /* Ok, here it sets the config and saves it. This is sorta dangerous, and I'm not sure
   * if it's actually possible to do dynamic reconfiguration of everything this way.
   */
***************
*** 3490,3499 ****
--- 3687,3724 ----
      if (nopopups) {
        gtk_tooltips_disable(tooltips);
        nopopups=FALSE;
      }
    }
+ #ifdef HAVE_SDL
+   if( GTK_TOGGLE_BUTTON( cradiobutton1)->active) {
+     if( per_pixel_lighting == 0)
+       {
+ 	per_pixel_lighting= 1;
+ 	per_tile_lighting= 0;
+ 	init_SDL( NULL, 1);
+ 	if( csocket.fd)
+ 	  cs_write_string( csocket.fd, "mapredraw", 9);
+       }
+   } else {
+     if( per_pixel_lighting == 1)
+       {
+ 	per_pixel_lighting= 0;
+ 	per_tile_lighting= 1;
+ 	init_SDL( NULL, 1);
+ 	if( csocket.fd)
+ 	  cs_write_string( csocket.fd, "mapredraw", 9);
+       }
+   }
+   if( GTK_TOGGLE_BUTTON( ccheckbutton9)->active) {
+     if( show_grid == FALSE)
+       show_grid= TRUE;
+   } else {
+     if( show_grid == TRUE)
+       show_grid= FALSE;
+   }
+ #endif
    save_defaults();
  }
  
  /*void cknumentry_callback (GtkWidget *widget, GdkEventKey *event, GtkWidget *window) {
    gtk_entry_set_text (GTK_ENTRY(ckeyentrytext),  XKeysymToString(event->keyval));
***************
*** 3735,3745 ****
  
    if(!gtkwin_config) {
      
      gtkwin_config = gtk_window_new (GTK_WINDOW_DIALOG);
      gtk_window_position (GTK_WINDOW (gtkwin_config), GTK_WIN_POS_CENTER);
!     gtk_widget_set_usize (gtkwin_config,450,360);
      gtk_window_set_title (GTK_WINDOW (gtkwin_config), "Crossfire Configure");
      gtk_window_set_policy (GTK_WINDOW (gtkwin_config), TRUE, TRUE, FALSE);
  
      gtk_signal_connect (GTK_OBJECT (gtkwin_config), "destroy", GTK_SIGNAL_FUNC(gtk_widget_destroyed), &gtkwin_config);
      
--- 3960,3970 ----
  
    if(!gtkwin_config) {
      
      gtkwin_config = gtk_window_new (GTK_WINDOW_DIALOG);
      gtk_window_position (GTK_WINDOW (gtkwin_config), GTK_WIN_POS_CENTER);
!     gtk_widget_set_usize (gtkwin_config,450,400);
      gtk_window_set_title (GTK_WINDOW (gtkwin_config), "Crossfire Configure");
      gtk_window_set_policy (GTK_WINDOW (gtkwin_config), TRUE, TRUE, FALSE);
  
      gtk_signal_connect (GTK_OBJECT (gtkwin_config), "destroy", GTK_SIGNAL_FUNC(gtk_widget_destroyed), &gtkwin_config);
      
***************
*** 3827,3844 ****
--- 4052,4111 ----
        gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(ccheckbutton8), TRUE);
      } else {
        gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(ccheckbutton8), FALSE);
      }
  
+ #ifdef HAVE_SDL
+     {
+       GtkWidget* label;
+       GtkWidget* separator = gtk_hseparator_new ();
+       gtk_box_pack_start (GTK_BOX (vbox1), separator, FALSE, TRUE, 0);
+ 
+ 
+       label= gtk_label_new((gchar*)"Lighting options, per pixel is prettier, per tile is faster");
+       gtk_box_pack_start( GTK_BOX( vbox1), label, FALSE, FALSE, 0);
+ 
+ 
+ 
+       cradiobutton1= gtk_radio_button_new_with_label( NULL, (gchar*)"Per Pixel Lighting");
+       cradiobutton2 = gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(cradiobutton1),
+ 								  (gchar*)"Per Tile Lighting");
+       
+       gtk_box_pack_start( GTK_BOX( vbox1), cradiobutton1, FALSE, FALSE, 0);
+       gtk_box_pack_start( GTK_BOX( vbox1), cradiobutton2, FALSE, FALSE, 0);
+ 
+       gtk_widget_show( separator);
+       gtk_widget_show( label);
+ 
+       separator= gtk_hseparator_new();
+       gtk_box_pack_start( GTK_BOX( vbox1), separator, FALSE, TRUE, 0);
+       gtk_widget_show( separator);
+ 
+       ccheckbutton9= gtk_check_button_new_with_label( "Print Grid Overlay -- Slow, only really useful for debugging/development");
+       gtk_box_pack_start( GTK_BOX(vbox1), ccheckbutton9, FALSE, FALSE, 0);
+       if( show_grid) {
+ 	gtk_toggle_button_set_state( GTK_TOGGLE_BUTTON( ccheckbutton9), TRUE);
+       } else {
+ 	gtk_toggle_button_set_state( GTK_TOGGLE_BUTTON( ccheckbutton9), FALSE);
+       }
+     }
+ 
+ #endif /* HAVE_SDL */
+ 
      gtk_widget_show (ccheckbutton1);
      gtk_widget_show (ccheckbutton2);
      gtk_widget_show (ccheckbutton3);
      gtk_widget_show (ccheckbutton4);
      gtk_widget_show (ccheckbutton5);
      gtk_widget_show (ccheckbutton6);
      gtk_widget_show (ccheckbutton7);
      gtk_widget_show (ccheckbutton8);
+ #ifdef HAVE_SDL
+     gtk_widget_show (cradiobutton1);
+     gtk_widget_show (cradiobutton2);
+     gtk_widget_show (ccheckbutton9);
+ #endif
  
      gtk_widget_show (vbox1);
      gtk_widget_show (frame1);
      gtk_widget_show (vbox2);
   
***************
*** 4758,4768 ****
  	gtk_paned_add1 (GTK_PANED (game_bar_vpane), gameframe);
      
      get_game_display (gameframe);
      
      gtk_widget_show (gameframe);
!     
      /* stats frame */
      stat_frame = gtk_frame_new (NULL);
      gtk_frame_set_shadow_type (GTK_FRAME(stat_frame), GTK_SHADOW_ETCHED_IN);
      if (bigmap)
  	gtk_paned_add1 (GTK_PANED (game_bar_vpane), stat_frame);
--- 5025,5035 ----
  	gtk_paned_add1 (GTK_PANED (game_bar_vpane), gameframe);
      
      get_game_display (gameframe);
      
      gtk_widget_show (gameframe);
! 
      /* stats frame */
      stat_frame = gtk_frame_new (NULL);
      gtk_frame_set_shadow_type (GTK_FRAME(stat_frame), GTK_SHADOW_ETCHED_IN);
      if (bigmap)
  	gtk_paned_add1 (GTK_PANED (game_bar_vpane), stat_frame);
***************
*** 4811,4821 ****
      gtk_signal_connect_object (GTK_OBJECT (gtkwin_root), "key_press_event",
  			       GTK_SIGNAL_FUNC(keyfunc), GTK_OBJECT(gtkwin_root));
      gtk_signal_connect_object (GTK_OBJECT (gtkwin_root), "key_release_event",
  			       GTK_SIGNAL_FUNC(keyrelfunc), GTK_OBJECT(gtkwin_root));
      gtk_widget_show (gtkwin_root);
!     
  
    } else { /* split window mode */
  
   
    /* game window */
--- 5078,5091 ----
      gtk_signal_connect_object (GTK_OBJECT (gtkwin_root), "key_press_event",
  			       GTK_SIGNAL_FUNC(keyfunc), GTK_OBJECT(gtkwin_root));
      gtk_signal_connect_object (GTK_OBJECT (gtkwin_root), "key_release_event",
  			       GTK_SIGNAL_FUNC(keyrelfunc), GTK_OBJECT(gtkwin_root));
      gtk_widget_show (gtkwin_root);
! 
! #ifdef HAVE_SDL
!     init_SDL( drawingarea, 0);
! #endif
  
    } else { /* split window mode */
  
   
    /* game window */
***************
*** 4825,4835 ****
      gtk_widget_set_uposition (gtkwin_root, 300, 160);
      gtk_widget_set_usize (gtkwin_root,(image_size*mapx)+6,(image_size*mapy)+6);
      gtk_window_set_title (GTK_WINDOW (gtkwin_root), "Crossfire - view");
      gtk_window_set_policy (GTK_WINDOW (gtkwin_root), TRUE, TRUE, FALSE);
      gtk_signal_connect (GTK_OBJECT (gtkwin_root), "destroy", GTK_SIGNAL_FUNC(gtk_widget_destroyed), &gtkwin_root);
!     
      gtk_container_border_width (GTK_CONTAINER (gtkwin_root), 0);
      
   
      rootvbox = gtk_vbox_new(FALSE, 0);
      gtk_container_add (GTK_CONTAINER (gtkwin_root), rootvbox);
--- 5095,5106 ----
      gtk_widget_set_uposition (gtkwin_root, 300, 160);
      gtk_widget_set_usize (gtkwin_root,(image_size*mapx)+6,(image_size*mapy)+6);
      gtk_window_set_title (GTK_WINDOW (gtkwin_root), "Crossfire - view");
      gtk_window_set_policy (GTK_WINDOW (gtkwin_root), TRUE, TRUE, FALSE);
      gtk_signal_connect (GTK_OBJECT (gtkwin_root), "destroy", GTK_SIGNAL_FUNC(gtk_widget_destroyed), &gtkwin_root);
! 
! 
      gtk_container_border_width (GTK_CONTAINER (gtkwin_root), 0);
      
   
      rootvbox = gtk_vbox_new(FALSE, 0);
      gtk_container_add (GTK_CONTAINER (gtkwin_root), rootvbox);
***************
*** 4876,4886 ****
      gtkwin_info = gtk_window_new (GTK_WINDOW_TOPLEVEL);
      gtk_widget_set_events (gtkwin_info, GDK_KEY_RELEASE_MASK);
      gtk_widget_set_uposition (gtkwin_info, 570, 0);
      gtk_widget_set_usize (gtkwin_info,400,600);
      gtk_window_set_title (GTK_WINDOW (gtkwin_info), "Crossfire - info");
!      gtk_window_set_policy (GTK_WINDOW (gtkwin_info), TRUE, TRUE, FALSE);
      gtk_signal_connect (GTK_OBJECT (gtkwin_info), "destroy", GTK_SIGNAL_FUNC(gtk_widget_destroyed), &gtkwin_info);
      
      gtk_container_border_width (GTK_CONTAINER (gtkwin_info), 0);
      
      /* Alloc colors - not entirely necessary, really, since GTK should do this */
--- 5147,5157 ----
      gtkwin_info = gtk_window_new (GTK_WINDOW_TOPLEVEL);
      gtk_widget_set_events (gtkwin_info, GDK_KEY_RELEASE_MASK);
      gtk_widget_set_uposition (gtkwin_info, 570, 0);
      gtk_widget_set_usize (gtkwin_info,400,600);
      gtk_window_set_title (GTK_WINDOW (gtkwin_info), "Crossfire - info");
!     gtk_window_set_policy (GTK_WINDOW (gtkwin_info), TRUE, TRUE, FALSE);
      gtk_signal_connect (GTK_OBJECT (gtkwin_info), "destroy", GTK_SIGNAL_FUNC(gtk_widget_destroyed), &gtkwin_info);
      
      gtk_container_border_width (GTK_CONTAINER (gtkwin_info), 0);
      
      /* Alloc colors - not entirely necessary, really, since GTK should do this */
***************
*** 4997,5014 ****
--- 5268,5291 ----
  
      gtk_signal_connect_object (GTK_OBJECT (gtkwin_stats), "key_press_event",
  			       GTK_SIGNAL_FUNC(keyfunc), GTK_OBJECT(gtkwin_stats));
      gtk_signal_connect_object (GTK_OBJECT (gtkwin_stats), "key_release_event",
  			       GTK_SIGNAL_FUNC(keyrelfunc), GTK_OBJECT(gtkwin_stats));
+ 
+ #ifdef HAVE_SDL
+     init_SDL( drawingarea, 0);
+ #endif
+ 
    } /* else split windows */
  
    /* load window positions from file */
    set_window_pos();
    gtk_tooltips_set_delay(tooltips, 1000 );
    if (tool_tips) {
      gtk_tooltips_enable(tooltips);
    }
+ 
  }
  
  int sync_display = 0;
  static int get_root_display(char *display_name,int gargc, char **gargv) {
      gtk_init (&gargc,&gargv);
***************
*** 5021,5031 ****
       */
      if (display_mode == Png_Display) {
  	gdk_rgb_init();
      }
      create_windows();
!   
      return 0;
  }
   
  /* null procedures. gtk does this for us. */
  
--- 5298,5308 ----
       */
      if (display_mode == Png_Display) {
  	gdk_rgb_init();
      }
      create_windows();
! 
      return 0;
  }
   
  /* null procedures. gtk does this for us. */
  
***************
*** 5552,5563 ****
      puts("-port <number>   - Use port <number> instead of the standard port number");
      puts("-display <name>  - Use <name> instead if DISPLAY environment variable.\n");
      puts("-split           - Use split windows.");
      puts("-echo            - Echo the bound commands");
  #ifdef Xpm_Pix
      puts("-xpm             - Use color pixmaps (XPM) for display.");
! #endif
  #ifdef HAVE_LIBPNG
      puts("-png             - Use png images for display.");
  #endif
      puts("-showicon        - Print status icons in inventory window");
      puts("-scrolllines <number>    - number of lines for scrollback");
--- 5829,5842 ----
      puts("-port <number>   - Use port <number> instead of the standard port number");
      puts("-display <name>  - Use <name> instead if DISPLAY environment variable.\n");
      puts("-split           - Use split windows.");
      puts("-echo            - Echo the bound commands");
  #ifdef Xpm_Pix
+ #ifndef HAVE_SDL
      puts("-xpm             - Use color pixmaps (XPM) for display.");
! #endif /* HAVE_SDL */
! #endif /* Xpm_Pix */
  #ifdef HAVE_LIBPNG
      puts("-png             - Use png images for display.");
  #endif
      puts("-showicon        - Print status icons in inventory window");
      puts("-scrolllines <number>    - number of lines for scrollback");
***************
*** 5570,5580 ****
--- 5849,5861 ----
      puts("-keepcache       - Keep already cached images even if server has different ones.");
      puts("-pngfile <name>  - Use <name> for source of images");
      puts("-nopopups        - Don't use pop up windows for input");
      puts("-splitinfo       - Use two information windows, segregated by information type.");
      puts("-mapsize xXy     - Set the mapsize to be X by Y spaces.");
+ #ifndef HAVE_SDL
      puts("-pngximage       - Use ximage for drawing png (may not work on all hardware");
+ #endif
  
      exit(0);
  }
  
  /* init_windows:  This initiliazes all the windows - it is an
***************
*** 5769,5788 ****
--- 6050,6087 ----
  
  /* Do the pixmap copy with gc to tile it onto the stack in the cell */
  
  static void gen_draw_face(int face,int x,int y)
  {
+ #ifdef HAVE_SDL
+ 
+   SDL_Rect dst;
+   dst.x= x* image_size;
+   dst.y= y* image_size;
+   dst.w= image_size;
+   dst.h= image_size;
+ 
+   if( SDL_BlitSurface( surfaces[ facecachemap[face]].surface, NULL,
+ 		       mapsurface, &dst) < 0)
+     {
+       do_SDL_error( "BlitSurface", __FILE__, __LINE__);
+     }
+   return;
+ 
+ #else 
+ 
      if (face == 0) fprintf(stderr,"gen draw face called with 0 face");
  
  #if 0
      if (pixmaps[0].gdkpixmap == pixmaps[facecachemap[face]].gdkpixmap)
  	fprintf(stderr,"gen_draw_face - called with ? pixmap - num = %d, (%d,%d)\n", face, x,y);
  #endif
      gdk_gc_set_clip_mask (mapgc, pixmaps[facecachemap[face]].gdkmask);
      gdk_gc_set_clip_origin (mapgc, image_size*x, image_size*y);
      gdk_window_copy_area (drawingarea->window, mapgc, image_size*x, image_size*y, 
  			  pixmaps[facecachemap[face]].gdkpixmap,0,0,image_size,image_size);
+ #endif /* else NO SDL */
  }
  
  
  /* Draw the tiled pixmap tiles in the mapcell */
  
***************
*** 5805,5814 ****
--- 6104,6265 ----
  
  /* this differs from below in that we use one big image struture
   * for the entire screen.  That is the 'screen' value above.
   */
  
+ #ifdef HAVE_SDL
+ int sdl_add_png_faces( int ax, int ay, int *faces, int num_faces, int dark[5])
+ {
+ 
+   int x, y, darkness, on_face, darkx[32], darky;
+   Uint32 pixel;
+   SDL_PixelFormat *fmt;
+   int semi= 0;
+   SDL_Rect dst;
+ 
+   dst.x= ax* image_size;
+   dst.y= ay* image_size;
+   dst.w= image_size;
+   dst.h= image_size;
+ 
+ 
+ 
+   /* Nothing to draw here, so paint a black square */
+   if( !num_faces)
+     {
+       if( SDL_FillRect( mapsurface, &dst, 
+ 			SDL_MapRGB( mapsurface->format, 0, 0, 0)) < 0)
+ 	do_SDL_error( "FillRect", __FILE__, __LINE__);
+       return 0;
+     }
+ 
+   for( on_face= num_faces -1; on_face > -1; on_face--)
+     {
+       if( SDL_BlitSurface( surfaces[faces[on_face]].surface, NULL,
+ 			   mapsurface, &dst) < 0)
+ 	{
+ 	  do_SDL_error( "BlitSurface", __FILE__, __LINE__);
+ 	}
+     }
+ 
+   if( per_tile_lighting)
+     {
+       if( dark[0] == 255)
+ 	{
+ 	  /* Fully bright, no reason to blit a light map */
+ 	  return 0;
+ 	}
+       else if( dark[0] == 0)
+ 	{
+ 	  /* Fully dark, just paint black */
+ 	  SDL_FillRect( lightmap, NULL, 
+ 			SDL_MapRGB( lightmap->format, 0, 0, 0));
+ 	  SDL_BlitSurface( lightmap, NULL, mapsurface, &dst);
+ 
+ 	  return 0;
+ 	}
+       else {
+ 	SDL_FillRect( lightmap, NULL, 
+ 		      SDL_MapRGB( lightmap->format, 0, 0, 0));
+ 	/* Set per surface alpha channel */
+ 	SDL_SetAlpha( lightmap, SDL_SRCALPHA, SDL_ALPHA_OPAQUE - dark[0]);
+ 	SDL_BlitSurface( lightmap, NULL, mapsurface, &dst);
+ 
+ 	return 0;
+       }
+ 
+     }
+   else if( per_pixel_lighting) 
+     {
+       for( x= 0; x < 16; x++)
+ 	{
+ 	  darkx[x]= (dark[4]*(16-x) + dark[0]*x) / 16;
+ 	}
+       for( x= 16; x < 32; x++)
+ 	{
+ 	  darkx[x] = (dark[0]*(32-x) + dark[2]*(x-16)) / 16;
+ 	}
+ 
+       /* 
+        * Make sure lightmap in initialized to full bright
+        */
+       SDL_FillRect( lightmap, NULL,
+ 		    SDL_MapRGBA( lightmap->format, 0, 0, 0, 
+                                  SDL_ALPHA_TRANSPARENT));
+ 
+       fmt= lightmap->format;
+       SDL_LockSurface( lightmap);
+       for( y= 0; y < image_size; y++)
+ 	{
+ 	  if( y < 16)
+ 	    {
+ 	      darky = ((dark[1]*((image_size/2)-y)) + dark[0]*y) / 
+                        (image_size / 2);
+ 	    }
+ 	  else 
+ 	    {
+ 	      darky= (dark[0]*(image_size-y) + dark[3]*(y-(image_size/2))) /
+ 		      (image_size / 2);
+ 	    }
+ 	  
+ 	  for( x= 0; x < image_size; x++)
+ 	    {
+ 	      
+ 	      darkness= (darkx[x] + darky) / 2;
+ 	      if( darkness == 255)
+ 		continue;
+ 	      else 
+ 		semi++;
+ 	      
+ 	      /* Need to invert the transparancy level.. */
+ 	      pixel= SDL_MapRGBA( fmt, 0, 0, 0, SDL_ALPHA_OPAQUE - darkness);
+ 	      
+ 	      switch (fmt->BytesPerPixel) 
+ 		{
+ 		case 1:
+ 		  *((Uint8 *)lightmap->pixels+y*lightmap->pitch+x) = pixel;
+ 		  break;
+ 		case 2:
+ 		  *((Uint16 *)lightmap->pixels+y*lightmap->pitch/2+x) = pixel;
+ 		  break;
+ 		case 3:
+ 		  /* Don't think we will get here if we have a full alpha 
+                    * channel. If so that implies 6|6|6|6 RGBA packing which 
+                    * is kinda weird..  
+                    */
+ 		  ((Uint8 *)lightmap->pixels+y*lightmap->pitch+x)[0] = 0;
+ 		  ((Uint8 *)lightmap->pixels+y*lightmap->pitch+x)[1] = 0;
+ 		  ((Uint8 *)lightmap->pixels+y*lightmap->pitch+x)[2] = 0;
+ 		  break;
+ 		case 4:
+ 		  *((Uint32 *)lightmap->pixels+y*lightmap->pitch/4+x) = pixel;
+ 		  break;
+ 		}
+ 	    }
+ 	}
+       SDL_UnlockSurface( lightmap);
+       
+       if( semi > 0)
+ 	{
+ 	  if( SDL_BlitSurface( lightmap, NULL, mapsurface, &dst) < 0)
+ 	    {
+ 	      do_SDL_error( "BlitSurface", __FILE__, __LINE__);
+ 	    }
+ 	}
+     }
+   else
+     {
+       /* Unknown lighting style */
+       fprintf( stderr, "Error, unknowing lighting style in %s at line %d\n",
+ 	       __FILE__, __LINE__);
+     }
+ 
+   return 0;
+ }
+ 
+ #else /* HAVE_SDL */
+ 
  int add_png_faces(int ax, int ay, int *faces, int num_faces, int dark[5]) 
  {
      int x,y, a, darkness ,pos=0, on_face,darkx[32], darky, screen_pos, rowy;
  
      /* If we don't have png_data, can't proceed further */
***************
*** 5942,5960 ****
  	    pos+=4;
  	} /* for x loop */
      }
      return 0;
  }
! 
  
  void display_mapcell_pixmap(int ax,int ay)
  {
!     int k, got_face=0, faces[MAXFACES],num_faces, darkness[5];
  
      /* we use a different logic in this mode */
      if (display_mode == Png_Display && pngximage) {
! 
  	num_faces=0;
  	if (map1cmd) {
  	    for(k=the_map.cells[ax][ay].count-1;k>-1;k--) {
  		if (the_map.cells[ax][ay].faces[k] >0 )
  		    faces[num_faces++] = the_map.cells[ax][ay].faces[k];
--- 6393,6417 ----
  	    pos+=4;
  	} /* for x loop */
      }
      return 0;
  }
! #endif /* HAVE_SDL */
  
  void display_mapcell_pixmap(int ax,int ay)
  {
!     int k, faces[MAXFACES],num_faces, darkness[5];
! #ifndef HAVE_SDL
!     int got_face= 0;
! #endif
  
      /* we use a different logic in this mode */
+ #ifndef HAVE_SDL
      if (display_mode == Png_Display && pngximage) {
! #else
!     if (display_mode == Png_Display) {
! #endif
  	num_faces=0;
  	if (map1cmd) {
  	    for(k=the_map.cells[ax][ay].count-1;k>-1;k--) {
  		if (the_map.cells[ax][ay].faces[k] >0 )
  		    faces[num_faces++] = the_map.cells[ax][ay].faces[k];
***************
*** 5981,5994 ****
--- 6438,6456 ----
  		faces[num_faces++] = the_map.cells[ax][ay].faces[k];
  	    }
  	    /* old mode doesn't have darkness, so just set to full bright */
  	    darkness[0]=255;darkness[1]=255;darkness[2]=255;darkness[3]=255;darkness[4]=255;
  	}
+ #ifndef HAVE_SDL
  	if (add_png_faces(ax,ay, faces, num_faces,darkness)) goto bail;
+ #else
+ 	sdl_add_png_faces( ax, ay, faces, num_faces, darkness);
+ #endif
  	return;
      }
  
+ #ifndef HAVE_SDL
  bail:
  #if 0
      /* commenting this out eliminates flickering you will otherwise see.
       * The problem is that if there are any maps that still don't have
       * floors, this probably won't draw objects on top properly.
***************
*** 6023,6036 ****
  	}
      }
      else for(k=the_map.cells[ax][ay].count-1;k>-1;k--) {
  	gen_draw_face(the_map.cells[ax][ay].faces[k], ax,ay);
      }
  }
  
  
- 
  /* Do the map drawing */
  void display_map_doneupdate(int redraw)
  {
      int ax,ay, need_updates=0;
  
--- 6485,6498 ----
  	}
      }
      else for(k=the_map.cells[ax][ay].count-1;k>-1;k--) {
  	gen_draw_face(the_map.cells[ax][ay].faces[k], ax,ay);
      }
+ #endif
  }
  
  
  /* Do the map drawing */
  void display_map_doneupdate(int redraw)
  {
      int ax,ay, need_updates=0;
  
***************
*** 6044,6053 ****
--- 6506,6527 ----
  	updatelock++;
  
  	/* draw black on all non-visible squares, and tile pixmaps on the others */
  	for(ax=0;ax<mapx;ax++) {
  	    for(ay=0;ay<mapy;ay++) { 
+ #ifdef HAVE_SDL
+ 	      if( the_map.cells[ax][ay].need_update)
+ 		{
+ 		  display_mapcell_pixmap( ax, ay);
+ 		  if( show_grid == TRUE)
+ 		  {
+ 		    overlay_grid( FALSE, ax, ay);
+ 		  }
+ 		  need_updates++;
+ 		  the_map.cells[ax][ay].need_update= 0;
+ 		}
+ #else
  		if (pngximage) {
  		    if (the_map.cells[ax][ay].need_update) {
  			display_mapcell_pixmap(ax,ay);
  			need_updates++;
  		    }
***************
*** 6062,6076 ****
--- 6536,6561 ----
  		    } else {
  			display_mapcell_pixmap(ax,ay);
  		    }
  		    the_map.cells[ax][ay].need_update=0;
  		}
+ #endif
+ 
  	    } /* for ay */
  	} /* for ax */
+ #ifdef HAVE_SDL
+ 	if( need_updates > 0 || map_did_scroll) {
+ 	  if( SDL_Flip( mapsurface) == 1 )
+ 	    do_SDL_error( "Flip", __FILE__, __LINE__);
+ 
+ 	  map_did_scroll= 0;
+ 	}
+ #endif
  #ifdef TIME_MAP_REDRAW
  	gettimeofday(&tv2, NULL);
  #endif
+ #ifndef HAVE_SDL
  	if (pngximage) {
  	    int draw_each_space=1;
  	    /* if we need to redraw the entire thing or the number of changed spaces is
  	     * more than a quarter of the map, just put the the entire image to the
  	     * screen.
***************
*** 6109,6118 ****
--- 6594,6604 ----
  		    the_map.cells[ax][ay].need_update=0;
  		}
  	    }
  	    map_did_scroll=0;
  	}
+ #endif /* ! HAVE_SDL */
      } /* if updatelock */
  #ifdef TIME_MAP_REDRAW
      /* this else branches fro the if updatelock above - without it
       * tv2 is uninitialized.
       */
***************
*** 6157,6166 ****
--- 6643,6653 ----
  	 * narrow, we then will have the stats on top, with message down below
  	 * the map window.  IF the map window is wide, we put these side
  	 * by side at the top
  	 */
  	if (bigmap && x<15) {
+ 
  	    /* reverse of below basically. */
  	    GtkWidget	*newpane;   /* will take place of game_bar_vpane */
  
  	    bigmap =FALSE;
  
***************
*** 6186,6207 ****
  	    gtk_widget_ref(gameframe);
  	    gtk_container_remove(GTK_CONTAINER(stat_game_vpane), gameframe);
  	    gtk_paned_add1(GTK_PANED(newpane), gameframe);
  	    gtk_widget_unref(gameframe);
  
- 
  	    gtk_paned_add2(GTK_PANED(stat_game_vpane), newpane);
  
  	    gtk_widget_show(newpane);
  	    /* This should also destroy it */
  	    gtk_widget_unref(game_bar_vpane);
  	    game_bar_vpane = newpane;
  
  	} else if (!bigmap && x>=15) {
  	    GtkWidget	*newpane;   /* will take place of game_bar_vpane */
  	    bigmap=TRUE;
- 
  	    newpane = gtk_hpaned_new();
  
  	    /* We need to remove this here - the game pane is goind to
  	     * take game_bar_vpane as second position in the stat_game_vpane.
  	     * add a refcount so it isn't destroyed.
--- 6673,6693 ----
  	    gtk_widget_ref(gameframe);
  	    gtk_container_remove(GTK_CONTAINER(stat_game_vpane), gameframe);
  	    gtk_paned_add1(GTK_PANED(newpane), gameframe);
  	    gtk_widget_unref(gameframe);
  
  	    gtk_paned_add2(GTK_PANED(stat_game_vpane), newpane);
  
  	    gtk_widget_show(newpane);
  	    /* This should also destroy it */
  	    gtk_widget_unref(game_bar_vpane);
  	    game_bar_vpane = newpane;
  
  	} else if (!bigmap && x>=15) {
+ 
  	    GtkWidget	*newpane;   /* will take place of game_bar_vpane */
  	    bigmap=TRUE;
  	    newpane = gtk_hpaned_new();
  
  	    /* We need to remove this here - the game pane is goind to
  	     * take game_bar_vpane as second position in the stat_game_vpane.
  	     * add a refcount so it isn't destroyed.
***************
*** 6238,6249 ****
  	    gtk_widget_unref(game_bar_vpane);
  	    game_bar_vpane = newpane;
  	}
  	gtk_widget_set_usize (gameframe, (image_size*mapx)+6, (image_size*mapy)+6);
      } else {
! 	gtk_widget_set_usize (gtkwin_root,(image_size*mapx)+6,(image_size*mapy)+6);
      }
  }
  
  /* If we are using ximage logic, we use a different mechanism to load the
   * image.
   */
--- 6724,6741 ----
  	    gtk_widget_unref(game_bar_vpane);
  	    game_bar_vpane = newpane;
  	}
  	gtk_widget_set_usize (gameframe, (image_size*mapx)+6, (image_size*mapy)+6);
      } else {
!       gtk_widget_set_usize (gtkwin_root,(image_size*mapx)+6,(image_size*mapy)+6);
      }
+ 
+ #ifdef HAVE_SDL
+     init_SDL( drawingarea, FALSE);
+ #endif
+ 
+ 
  }
  
  /* If we are using ximage logic, we use a different mechanism to load the
   * image.
   */
***************
*** 6270,6280 ****
      if (pngximage) {
  	if (!(pixmaps[face].png_data = png_to_data(buf, (int)buflen))) {
  	    fprintf(stderr,"unable to create image %ld\n", face);
  	}
      }
!     /* even if using pngximage, we standard image for the inventory list */
      if (png_to_gdkpixmap(gtkwin_root->window, buf, buflen,
  			 &pixmaps[face].gdkpixmap, &pixmaps[face].gdkmask,
  			 gtk_widget_get_colormap(gtkwin_root))) {
  	    fprintf(stderr,"Got error on png_to_gdkpixmap\n");
      }
--- 6762,6788 ----
      if (pngximage) {
  	if (!(pixmaps[face].png_data = png_to_data(buf, (int)buflen))) {
  	    fprintf(stderr,"unable to create image %ld\n", face);
  	}
      }
! #ifdef HAVE_SDL
!     {
!       SDL_RWops* ops= SDL_RWFromMem( buf, (int)buflen);
!       surfaces[face].surface= IMG_LoadTyped_RW( ops, 1, (char*)"PNG");
!       if( surfaces[face].surface == NULL)
! 	{
! 	  do_SDL_error( "IMG_LoadTyped_RW", __FILE__, __LINE__);
! 	}
!       /* If this surface has transparent elements, enable RLE acceleration */
!       if( (surfaces[face].surface->flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY)
!         {
! 	  SDL_SetColorKey( surfaces[face].surface, SDL_SRCCOLORKEY|SDL_RLEACCEL, 
! 			   surfaces[face].surface->format->colorkey);
! 	}
!     }
! #endif
!     /* even if using pngximage or SDL, we standard image for the inventory list */
      if (png_to_gdkpixmap(gtkwin_root->window, buf, buflen,
  			 &pixmaps[face].gdkpixmap, &pixmaps[face].gdkmask,
  			 gtk_widget_get_colormap(gtkwin_root))) {
  	    fprintf(stderr,"Got error on png_to_gdkpixmap\n");
      }
***************
*** 6380,6389 ****
--- 6888,6901 ----
  	}
  	if (cache_images && facetoname[i]!=NULL) {
  	    free(facetoname[i]);
  	    facetoname[i]=NULL;
  	}
+ #ifdef HAVE_SDL
+ 	if( surfaces[i].surface && (surfaces[i].surface != surfaces[0].surface) )
+ 	  SDL_FreeSurface( surfaces[i].surface);
+ #endif
      }
      memset(&the_map, 0, sizeof(struct Map));
      look_list.env=cpl.below;
  }
  
Common subdirectories: client/help and /home/smf/projects/crossfire/cvs/client/help
Common subdirectories: client/macros and /home/smf/projects/crossfire/cvs/client/macros
Common subdirectories: client/pixmaps and /home/smf/projects/crossfire/cvs/client/pixmaps
Common subdirectories: client/utils and /home/smf/projects/crossfire/cvs/client/utils
diff -c5 --exclude-from=exclude client/xutil.c /home/smf/projects/crossfire/cvs/client/xutil.c
*** client/xutil.c	Wed Jun 13 00:01:20 2001
--- /home/smf/projects/crossfire/cvs/client/xutil.c	Fri Jun 15 19:34:21 2001
***************
*** 269,283 ****
  		requestface(pnum, face, buf);
  	    }
      }
      else if (display_mode == Png_Display) {
  #ifdef HAVE_LIBPNG
  	if (pngximage && !(pixmaps[pnum].png_data = png_to_data(data, (int)len))) {
  	    fprintf(stderr,"Got error on png_to_data, file=%s\n",buf);
  	    requestface(pnum, face, buf);
  	}
! 	/* even if using pngximage, we standard image for the inventory list */
  	if (png_to_gdkpixmap(gtkwin_root->window, data, len, &pixmaps[pnum].gdkpixmap, 
  		 &pixmaps[pnum].gdkmask,gtk_widget_get_colormap(gtkwin_root))) {
  	    fprintf(stderr,"Got error on png_to_gdkpixmap, file=%s\n",buf);
  	    requestface(pnum, face, buf);
  	}
--- 269,303 ----
  		requestface(pnum, face, buf);
  	    }
      }
      else if (display_mode == Png_Display) {
  #ifdef HAVE_LIBPNG
+ #ifndef HAVE_SDL
  	if (pngximage && !(pixmaps[pnum].png_data = png_to_data(data, (int)len))) {
  	    fprintf(stderr,"Got error on png_to_data, file=%s\n",buf);
  	    requestface(pnum, face, buf);
  	}
! #else
!       fprintf( stdout, "Getting PNG face %d data from memory\n", pnum);
!       {
! 	SDL_RWops *ops= SDL_RWFromMem( data, len);
! 	surfaces[pnum].surface= IMG_LoadTyped_RW( ops, 1, (char*)"PNG");
! 	
! 	/*
! 	 * Not sure if this is an error condition or not...
! 	 * below it makes a call to requestface but if he does it,
! 	 * we don't have to.
! 	 */
! 	if( surfaces[pnum].surface == NULL)
! 	  {
! 	  }
! 	else 
! 	  {
! 	  }
!       }
! #endif /* HAVE_SDL */
! 	/* even if using pngximage or SDL we still need standard image for the inventory list */
  	if (png_to_gdkpixmap(gtkwin_root->window, data, len, &pixmaps[pnum].gdkpixmap, 
  		 &pixmaps[pnum].gdkmask,gtk_widget_get_colormap(gtkwin_root))) {
  	    fprintf(stderr,"Got error on png_to_gdkpixmap, file=%s\n",buf);
  	    requestface(pnum, face, buf);
  	}
***************
*** 306,316 ****
  	    requestface(pnum, face, buf);
  	} else {
  	    pixmaps[pnum].pixmap = pixmap;
  	    pixmaps[pnum].mask = mask;
  	}
! #endif
      } else if (display_mode==Pix_Display) {
  	pixmaps[pnum].bitmap = XCreateBitmapFromData(display,
  		RootWindow(display,DefaultScreen(display)),
  		(char*)data,24,24);
  	pixmaps[pnum].fg = (data[24] << 24) + (data[25] << 16) + (data[26] << 8) +
--- 326,359 ----
  	    requestface(pnum, face, buf);
  	} else {
  	    pixmaps[pnum].pixmap = pixmap;
  	    pixmaps[pnum].mask = mask;
  	}
! 
! #ifdef GDK_XUTIL
! #ifdef HAVE_SDL
!       fprintf( stdout, "Getting PNG face %d data from memory\n", pnum);
!       {
! 	SDL_RWops *ops= SDL_RWFromMem( data, len);
! 	surfaces[pnum].surface= IMG_LoadTyped_RW( ops, 1, (char*)"PNG");
! 	
! 	/*
! 	 * Not sure if this is an error condition or not...
! 	 * below it makes a call to requestface but if he does it,
! 	 * we don't have to.
! 	 */
! 	if( surfaces[pnum].surface == NULL)
! 	  {
! 	  }
! 	else 
! 	  {
! 	  }
!       }
! #endif /* HAVE_SDL */
! #endif /* GDK_XUTIL */
! 
! #endif /* HAVE_LIBPNG */
      } else if (display_mode==Pix_Display) {
  	pixmaps[pnum].bitmap = XCreateBitmapFromData(display,
  		RootWindow(display,DefaultScreen(display)),
  		(char*)data,24,24);
  	pixmaps[pnum].fg = (data[24] << 24) + (data[25] << 16) + (data[26] << 8) +
***************
*** 1496,1505 ****
--- 1539,1565 ----
  	if (!strcmp(inbuf,"nopopups")) {
  	  if (!strcmp(cp,"True")) nopopups=TRUE;
  	  else nopopups=FALSE;
  	  continue;
  	}  
+ #ifdef HAVE_SDL
+ 	if( !strcmp( inbuf,"Lighting")) {
+ 	  if( !strcmp( cp, "per_pixel")) {
+ 	    per_pixel_lighting= 1;
+ 	    per_tile_lighting= 0;
+ 	  } else if( !strcmp( cp, "per_tile")) {
+ 	    per_pixel_lighting= 0;
+ 	    per_tile_lighting= 1;
+ 	  }
+ 	  continue;
+ 	}
+ 	if( !strcmp( inbuf,"show_grid")) {
+ 	  if( !strcmp( cp, "True")) show_grid = TRUE;
+ 	  else show_grid = FALSE;
+ 	  continue;
+ 	}
+ #endif
  #endif
  	fprintf(stderr,"Got line we did not understand: %s: %s\n", inbuf, cp);
      }
      fclose(fp);
  }
***************
*** 1550,1560 ****
      fprintf(fp,"colorinv: %s\n", color_inv?"True":"False");
      fprintf(fp,"colortext: %s\n", color_text?"True":"False");
      fprintf(fp,"tooltips: %s\n", color_text?"True":"False");
      fprintf(fp,"splitinfo: %s\n", splitinfo?"True":"False");
      fprintf(fp,"nopopups: %s\n", nopopups?"True":"False");
! #endif
      fclose(fp);
      sprintf(buf,"Defaults saved to %s",path);
      draw_info(buf,NDI_BLUE);
  }
  
--- 1610,1628 ----
      fprintf(fp,"colorinv: %s\n", color_inv?"True":"False");
      fprintf(fp,"colortext: %s\n", color_text?"True":"False");
      fprintf(fp,"tooltips: %s\n", color_text?"True":"False");
      fprintf(fp,"splitinfo: %s\n", splitinfo?"True":"False");
      fprintf(fp,"nopopups: %s\n", nopopups?"True":"False");
! #ifdef HAVE_SDL
!     if( per_pixel_lighting)
!       fprintf( fp, "Lighting: per_pixel\n");
!     else
!       fprintf( fp, "Lighting: per_tile\n");
!     fprintf( fp,"show_grid: %s\n", show_grid?"True":"False");
! #endif /* HAVE_SDL */
! #endif /* GDK_XUTIL */
! 
      fclose(fp);
      sprintf(buf,"Defaults saved to %s",path);
      draw_info(buf,NDI_BLUE);
  }
  
***************
*** 1756,1765 ****
--- 1824,1952 ----
      the_map.cells[x][y].have_darkness = 0;
      for (i=0; i<MAXFACES; i++)
  	the_map.cells[x][y].faces[i] = -1;  /* empty/blank face */
  }
  
+ void print_darkness()
+ {
+ 
+   int x= 0;
+   int y= 0;
+ 
+   for( y= 0; y < mapy; y++)
+     {
+       for( x= 0; x < mapx; x++)
+ 	{
+ 	  if( the_map.cells[x][y].count== 0)
+ 	    fprintf( stderr, "[ - ]");
+ 	  else
+ 	    fprintf( stderr, "[%3d]", the_map.cells[x][y].darkness);
+ 	}
+       fprintf( stderr, "\n");
+     }
+ }
+ #ifdef GDK_XUTIL
+ #ifdef HAVE_SDL
+ void overlay_grid( int re_init, int ax, int ay)
+ {
+ 
+   static SDL_Surface* grid_overlay;
+ 
+   static int first_pass;
+ 
+   int x= 0;
+   int y= 0;
+   SDL_Rect dst;
+   Uint32 *pixel;
+   SDL_PixelFormat* fmt;
+ 
+   if( re_init == TRUE)
+     {
+       if( grid_overlay)
+ 	SDL_FreeSurface( grid_overlay);
+ 
+       first_pass= 0;
+       grid_overlay= NULL;
+     }
+ 
+   if( grid_overlay == NULL)
+     {
+       grid_overlay= SDL_CreateRGBSurface( SDL_HWSURFACE|SDL_SRCALPHA, 
+ 					  mapx*image_size,
+ 					  mapy*image_size,
+ 					  mapsurface->format->BitsPerPixel,
+ 					  mapsurface->format->Rmask,
+ 					  mapsurface->format->Gmask,
+ 					  mapsurface->format->Bmask,
+ 					  mapsurface->format->Amask);
+       if( grid_overlay == NULL)
+ 	abort();
+ 
+       grid_overlay= SDL_DisplayFormatAlpha( grid_overlay);
+ 
+       first_pass= 0;
+     }
+ 
+   /* 
+    * If this is our first time drawing the grid, we need to build up the 
+    * grid overlay
+    */
+   if( first_pass== 0)
+     {
+ 
+       /* Red pixels around the edge and along image borders
+        * fully transparent pixels everywhere else
+        */
+       
+       fmt= grid_overlay->format;
+       for( x= 0; x < image_size*mapx; x++)
+ 	{
+ 	  for( y= 0; y < image_size*mapy; y++)
+ 	    {
+ 	      /* FIXME: Only works for 32 bit displays right now */
+ 	      pixel= (Uint32*)grid_overlay->pixels+y*grid_overlay->pitch/4+x;
+ 
+ 	      if( x == 0 || y == 0 || 
+ 		  ((x % image_size) == 0) || ((y % image_size) == 0 ) )
+ 		{
+ 		  *pixel= SDL_MapRGBA( fmt, 255, 0, 0, SDL_ALPHA_OPAQUE);
+ 		}
+ 	      else 
+ 		{
+ 		  *pixel= SDL_MapRGBA( fmt, 0, 0, 0, SDL_ALPHA_TRANSPARENT);
+ 		}
+ 	    }
+ 	}
+       first_pass= 1;
+ 
+       /* 
+        * If this is our first pass then we need to overlay the entire grid
+        * now. Otherwise we just update the tile we are on
+        */
+       dst.x= 0;
+       dst.y= 0;
+       dst.w= image_size*mapx;
+       dst.h= image_size*mapy;
+       SDL_BlitSurface( grid_overlay, NULL, mapsurface, &dst);
+     } 
+   else 
+     {
+       dst.x= ax* image_size;
+       dst.y= ay* image_size;
+       dst.w= image_size;
+       dst.h= image_size;
+       /* One to one pixel mapping of grid and mapsurface so we
+        * can share the SDL_Rect
+        */
+       SDL_BlitSurface( grid_overlay, &dst, mapsurface, &dst);
+     }
+ 
+   return;
+ }
+ #endif
+ #endif
+ 
  void set_map_darkness(int x, int y, uint8 darkness)
  {
      the_map.cells[x][y].have_darkness = 1;
      if (darkness != (255 - the_map.cells[x][y].darkness )) {
  	the_map.cells[x][y].darkness = 255 - darkness;
***************
*** 1768,1784 ****
  	/* pretty ugly - since the light code with pngximage uses
  	 * neighboring spaces to adjust the darkness, we now need to
  	 * let the neighbors know they should update their darkness
  	 * now.
  	 */
  	if (pngximage) {
  	    if (x-1>0) the_map.cells[x-1][y].need_update = 1;
  	    if (y-1>0) the_map.cells[x][y-1].need_update = 1;
  	    if (x+1<mapx) the_map.cells[x+1][y].need_update = 1;
  	    if (y+1<mapy) the_map.cells[x][y+1].need_update = 1;
  	}
! #endif
      }
  }
  
  /* sets the face at layer to some value.  We just can't
   * restact arbitrarily, as the server now sends faces only
--- 1955,1979 ----
  	/* pretty ugly - since the light code with pngximage uses
  	 * neighboring spaces to adjust the darkness, we now need to
  	 * let the neighbors know they should update their darkness
  	 * now.
  	 */
+ #ifndef HAVE_SDL
  	if (pngximage) {
  	    if (x-1>0) the_map.cells[x-1][y].need_update = 1;
  	    if (y-1>0) the_map.cells[x][y-1].need_update = 1;
  	    if (x+1<mapx) the_map.cells[x+1][y].need_update = 1;
  	    if (y+1<mapy) the_map.cells[x][y+1].need_update = 1;
  	}
! #else
! 	if (x-1>0) the_map.cells[x-1][y].need_update = 1;
! 	if (y-1>0) the_map.cells[x][y-1].need_update = 1;
! 	if (x+1<mapx) the_map.cells[x+1][y].need_update = 1;
! 	if (y+1<mapy) the_map.cells[x][y+1].need_update = 1;
! #endif /* HAVE_SDL */
! 
! #endif /* GDK_XUTIL */
      }
  }
  
  /* sets the face at layer to some value.  We just can't
   * restact arbitrarily, as the server now sends faces only
***************
*** 1835,1844 ****
--- 2030,2040 ----
  	    }
  	}
      }
      memcpy((char*)&the_map,(char*)&newmap,sizeof(struct Map));
  #ifdef GDK_XUTIL
+ #ifndef HAVE_SDL
      if (pngximage ) {
  	/* move the screen data around - this is more efficient than re-calculating it all 
  	 * memmove does support moving around overlapping data, so this is safe.
  	 * 
  	 */
***************
*** 1865,1873 ****
--- 2061,2070 ----
  	    }
  	}
  	map_did_scroll=1;
      }
  /*    fprintf(stderr,"scroll command: %d %d\n", dx, dy);*/
+ #endif
  #endif
  }
  
  
    
    


More information about the crossfire mailing list