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), >kwin_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), >kwin_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), >kwin_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), >kwin_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), >kwin_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), >kwin_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 }