diff options
Diffstat (limited to 'src/main-gtk2.c')
-rw-r--r-- | src/main-gtk2.c | 3077 |
1 files changed, 14 insertions, 3063 deletions
diff --git a/src/main-gtk2.c b/src/main-gtk2.c index 4830638a..ca3eff60 100644 --- a/src/main-gtk2.c +++ b/src/main-gtk2.c @@ -30,60 +30,14 @@ * and reorganised the file a bit. */ -#include "angband.h" +#include "files.h" +#include "util.h" +#include "variable.h" /* * Activate variant-specific features - * - * Angband 2.9.3 and close variants don't require any. - * - * Angband 2.9.4 alpha and later removed the short-lived - * can_save flag, so please #define can_save TRUE, or remove - * all the references to it. They also changed long-lived - * z-virt macro names. Find C_FREE/C_KILL and replace them - * with FREE/KILL, which takes one pointer parameter. - * - * [Z]-based variants (Gum and Cth, for example) usually need - * ANG293_COMPAT, ANG291_COMPAT and ANG281_RESET_VISUALS. - * - * [O] needs ANG293_COMPAT and ZANG_SAVE_GAME. - * - * ZAngband has its own enhanced main-gtk.c as mentioned above, and - * you *should* use it :-) - * - */ -#define TOME - -#ifdef TOME -# define ANG293_COMPAT /* Requires V2.9.3 compatibility code */ -# define ANG291_COMPAT /* Requires V2.9.1 compatibility code */ -# define ANG281_RESET_VISUALS /* The old style reset_visuals() */ -# define SAVEFILE_SCREEN /* New/Open integrated into the game */ -# define USE_DOUBLE_TILES /* Mogami's bigtile patch */ -#endif /* TOME */ - -/* - * Some examples */ -#ifdef ANGBAND300 -# define can_save TRUE /* Mimick the short-lived flag */ -# define C_FREE(P, N, T) FREE(P) /* Emulate the long-lived macro */ -#endif /* ANGBAND300 */ - -#ifdef GUMBAND -# define ANG293_COMPAT /* Requires V2.9.3 compatibility code */ -# define ANG291_COMPAT /* Requires V2.9.1 compatibility code */ -# define ANG281_RESET_VISUALS /* The old style reset_visuals() */ -# define OLD_SAVEFILE_CODE /* See also SAVEFILE_MUTABLE in files.c */ -# define NO_REDRAW_SECTION /* Doesn't have Term_redraw_section() */ -#endif /* GUMBAND */ - -#ifdef OANGBAND -# define ANG293_COMPAT /* Requires V2.9.3 compatibility code */ -# define ZANG_SAVE_GAME /* do_cmd_save_game with auto_save parameter */ -#endif /* OANGBAND */ - #ifdef USE_GTK2 @@ -99,19 +53,7 @@ #include <sys/stat.h> #include <unistd.h> #include <dirent.h> - -/* /me pffts Solaris */ -#ifndef NAME_MAX -#define NAME_MAX _POSIX_NAME_MAX -#endif - - -/* - * Include some helpful X11 code. - */ -#ifndef ANG293_COMPAT -# include "maid-x11.h" -#endif /* !ANG293_COMPAT */ +#include <assert.h> /* @@ -134,22 +76,6 @@ * back to the term_data structure. */ -#ifdef USE_GRAPHICS - -/* - * Since GdkRGB doesn't provide us some useful functions... - */ -typedef struct GdkRGBImage GdkRGBImage; - -struct GdkRGBImage -{ - gint width; - gint height; - gint ref_count; - guchar *image; -}; - -#endif /* USE_GRAPHICS */ /* @@ -176,18 +102,8 @@ struct term_data int rows; int cols; -#ifdef USE_GRAPHICS - - int tile_wid; - int tile_hgt; - - GdkRGBImage *tiles; - guint32 bg_pixel; - GdkRGBImage *trans_buf; -#endif /* USE_GRAPHICS */ - - cptr name; + char *name; }; @@ -210,36 +126,6 @@ if ((td)->backing_store) gdk_draw_pixmap( \ (hgt) * (td)->font_hgt) -#if 0 - -/* Compile time option version */ - -# ifdef USE_BACKING_STORE - -# define TERM_DATA_DRAWABLE(td) (td)->backing_store - -# define TERM_DATA_REFRESH(td, x, y, wid, hgt) \ -gdk_draw_pixmap( \ -(td)->drawing_area->window, \ -(td)->gc, \ -(td)->backing_store, \ -(x) * (td)->font_wid, \ -(y) * (td)->font_hgt, \ -(x) * (td)->font_wid, \ -(y) * (td)->font_hgt, \ -(wid) * (td)->font_wid, \ -(hgt) * (td)->font_hgt) - -# else /* USE_BACKING_STORE */ - -# define TERM_DATA_DRAWABLE(td) (td)->drawing_area->window -# define TERM_DATA_REFRESH(td, x, y, wid, hgt) - -# endif /* USE_BACKING_STORE */ - -#endif /* 0 */ - - /* * An array of "term_data" structures, one for each "sub-window" */ @@ -277,8 +163,6 @@ static bool_ use_backing_store = TRUE; /**** Vanilla compatibility functions ****/ -#ifdef ANG293_COMPAT - /* * Look up some environment variables to find font name for each window. */ @@ -309,69 +193,11 @@ static cptr get_default_font(int term) } -# ifndef SAVEFILE_SCREEN - -/* - * In [V]2.9.3, this frees all dynamically allocated memory - */ -static void cleanup_angband(void) -{ - /* XXX XXX XXX */ -} - -# endif /* !SAVEFILE_SCREEN */ - /* * New global flag to indicate if it's safe to save now */ #define can_save TRUE -#endif /* ANG293_COMPAT */ - - -#ifdef ANG291_COMPAT - -/* - * The standard game uses this to implement lighting effects - * for 16x16 tiles in cave.c... - * - * Because of the way it is implemented in X11 ports, - * we can set this to TRUE even if we are using the 8x8 tileset. - */ -static bool_ use_transparency = TRUE; - -#endif /* ANG291_COMPAT */ - - - - -/**** Low level routines - memory allocation ****/ - -/* - * Hook to "release" memory - */ -#ifdef ANGBAND300 -static vptr hook_rnfree(vptr v) -#else -static vptr hook_rnfree(vptr v, huge size) -#endif /* ANGBAND300 */ -{ - /* Dispose */ - g_free(v); - - /* Success */ - return (NULL); -} - - -/* - * Hook to "allocate" memory - */ -static vptr hook_ralloc(huge size) -{ - /* Make a new pointer */ - return (g_malloc(size)); -} @@ -425,1868 +251,6 @@ static void term_data_set_fg(term_data *td, byte attr) } -#ifdef USE_GRAPHICS - -/* - * Graphics mode selector - current setting and requested value - */ -#define GRAF_MODE_NONE 0 -#define GRAF_MODE_OLD 1 -#define GRAF_MODE_NEW 2 - -static int graf_mode = GRAF_MODE_NONE; -static int graf_mode_request = GRAF_MODE_NONE; - -/* - * Use smooth rescaling? - */ -static bool_ smooth_rescaling = TRUE; -static bool_ smooth_rescaling_request = TRUE; - -/* - * Dithering - */ -static GdkRgbDither dith_mode = GDK_RGB_DITHER_NORMAL; - -/* - * Need to reload and resize tiles when fonts are changed. - */ -static bool_ resize_request = FALSE; - -/* - * Numbers of columns and rows in current tileset - * calculated and set by the tile loading code in graf_init() - * and used by Term_pict_gtk() - */ -static int tile_rows; -static int tile_cols; - - -/* - * Directory name(s) - */ -static cptr ANGBAND_DIR_XTRA_GRAF; - - -/* - * Be nice to old graphics hardwares -- using GdkRGB. - * - * We don't have colour allocation failure any longer this way, - * even with 8bpp X servers. Gimp *does* work with 8bpp, why not Angband? - * - * Initialisation (before any widgets are created) - * gdk_rgb_init(); - * gtk_widget_set_default_colormap (gdk_rgb_get_cmap()); - * gtk_widget_set_default_visual (gdk_rgb_get_visual()); - * - * Setting fg/bg colours - * void gdk_rgb_gc_set_foreground(GdkGC *gc, guint32 rgb); - * void gdk_rgb_gc_set_background(GdkGC *gc, guint32 rgb); - * where rgb is 0xRRGGBB. - * - * Drawing rgb images - * void gdk_draw_rgb_image( - * GdkDrawable *drawable, - * GdkGC *gc, - * gint x, gint y, - * gint width, gint height, - * GdkRgbDither dith, - * guchar *rgb_buf, - * gint rowstride); - * - * dith: - * GDK_RGB_DITHER_NORMAL : dither if 8bpp or below - * GDK_RGB_DITHER_MAX : dither if 16bpp or below. - * - * for 0 <= i < width and 0 <= j < height, - * the pixel (x + i, y + j) is colored with - * red value rgb_buf[j * rowstride + i * 3], - * green value rgb_buf[j * rowstride + i * 3 + 1], and - * blue value rgb_buf[j * rowstride + i * 3 + 2]. - */ - -/* - * gdk_image compatibility functions - should be part of gdk, IMHO. - */ - -/* - * Create GdkRGBImage of width * height and return pointer - * to it. Returns NULL on failure - */ -static GdkRGBImage *gdk_rgb_image_new( - gint width, - gint height) -{ - GdkRGBImage *result; - - /* Allocate a struct */ - result = g_new(GdkRGBImage, 1); - - /* Oops */ - if (result == NULL) return (NULL); - - /* Allocate buffer */ - result->image = g_new0(guchar, width * height * 3); - - /* Oops */ - if (result->image == NULL) - { - g_free(result); - return (NULL); - } - - /* Initialise size fields */ - result->width = width; - result->height = height; - - /* Initialise reference count */ - result->ref_count = 1; - - /* Success */ - return (result); -} - -/* - * Free a GdkRGBImage - */ -static void gdk_rgb_image_destroy( - GdkRGBImage *im) -{ - /* Paranoia */ - if (im == NULL) return; - - /* Free the RGB buffer */ - g_free(im->image); - - /* Free the structure */ - g_free(im); -} - - -#if 0 - -/* - * Unref a GdkRGBImage - */ -static void gdk_rgb_image_unref( - GdkRGBImage *im) -{ - /* Paranoia */ - g_return_if_fail(im != NULL); - - /* Decrease reference count by 1 */ - im->ref_count--; - - /* Free if nobody's using it */ - if (im->ref_count <= 0) gdk_rgb_image_destroy(im); -} - - -/* - * Reference a GdkRGBImage - */ -static void gdk_rgb_image_ref( - GdkRGBImage *im) -{ - /* Paranoia */ - g_return_if_fail(im != NULL); - - /* Increase reference count by 1 */ - im->ref_count++; -} - -#endif /* 0 */ - - -/* - * Write RGB pixel of the format 0xRRGGBB to (x, y) in GdkRGBImage - */ -static void gdk_rgb_image_put_pixel( - GdkRGBImage *im, - gint x, - gint y, - guint32 pixel) -{ - guchar *rgbp; - - /* Paranoia */ - g_return_if_fail(im != NULL); - - /* Paranoia */ - if ((x < 0) || (x >= im->width)) return; - - /* Paranoia */ - if ((y < 0) || (y >= im->height)) return; - - /* Access RGB data */ - rgbp = &im->image[(y * im->width * 3) + (x * 3)]; - - /* Red */ - *rgbp++ = (pixel >> 16) & 0xFF; - /* Green */ - *rgbp++ = (pixel >> 8) & 0xFF; - /* Blue */ - *rgbp = pixel & 0xFF; -} - - -/* - * Returns RGB pixel (0xRRGGBB) at (x, y) in GdkRGBImage - */ -static guint32 gdk_rgb_image_get_pixel( - GdkRGBImage *im, - gint x, - gint y) -{ - guchar *rgbp; - - /* Paranoia */ - if (im == NULL) return (0); - - /* Paranoia - returns black */ - if ((x < 0) || (x >= im->width)) return (0); - - /* Paranoia */ - if ((y < 0) || (y >= im->height)) return (0); - - /* Access RGB data */ - rgbp = &im->image[(y * im->width * 3) + (x * 3)]; - - /* Return result */ - return ((rgbp[0] << 16) | (rgbp[1] << 8) | (rgbp[2])); -} - - -/* - * Since gdk_draw_rgb_image is a bit harder to use than it's - * GdkImage counterpart, I wrote a grue function that takes - * exactly the same parameters as gdk_draw_image, with - * the GdkImage parameter replaced with GdkRGBImage. - */ -static void gdk_draw_rgb_image_2( - GdkDrawable *drawable, - GdkGC *gc, - GdkRGBImage *image, - gint xsrc, - gint ysrc, - gint xdest, - gint ydest, - gint width, - gint height) -{ - /* Paranoia */ - g_return_if_fail(drawable != NULL); - g_return_if_fail(image != NULL); - - /* Paranoia */ - if (xsrc < 0 || (xsrc + width - 1) >= image->width) return; - if (ysrc < 0 || (ysrc + height - 1) >= image->height) return; - - /* Draw the image at (xdest, ydest), with dithering if bpp <= 8/16 */ - gdk_draw_rgb_image( - drawable, - gc, - xdest, - ydest, - width, - height, - dith_mode, - &image->image[(ysrc * image->width * 3) + (xsrc * 3)], - image->width * 3); -} - - -/* - * Code for smooth icon rescaling from Uwe Siems, Jan 2000 - * - * XXX XXX Duplication of maid-x11.c, again. It doesn't do any colour - * allocation, either. - */ - -/* - * to save ourselves some labour, define a maximum expected icon width here: - */ -#define MAX_ICON_WIDTH 32 - - -/* - * Each pixel is kept in this structure during smooth rescaling - * calculations, to make things a bit easier - */ -typedef struct rgb_type rgb_type; - -struct rgb_type -{ - guint32 red; - guint32 green; - guint32 blue; -}; - -/* - * Because there are many occurences of this, and because - * it's logical to do so... - */ -#define pixel_to_rgb(pix, rgb_buf) \ -(rgb_buf)->red = ((pix) >> 16) & 0xFF; \ -(rgb_buf)->green = ((pix) >> 8) & 0xFF; \ -(rgb_buf)->blue = (pix) & 0xFF - - -/* - * get_scaled_row reads a scan from the given GdkRGBImage, scales it smoothly - * and returns the red, green and blue values in arrays. - * The values in this arrays must be divided by a certain value that is - * calculated in scale_icon. - * x, y is the position, iw is the input width and ow the output width - * scan must be sufficiently sized - */ -static void get_scaled_row( - GdkRGBImage *im, - int x, - int y, - int iw, - int ow, - rgb_type *scan) -{ - int xi, si, sifrac, ci, cifrac, add_whole, add_frac; - guint32 pix; - rgb_type prev; - rgb_type next; - bool_ get_next_pix; - - /* Unscaled */ - if (iw == ow) - { - for (xi = 0; xi < ow; xi++) - { - pix = gdk_rgb_image_get_pixel(im, x + xi, y); - pixel_to_rgb(pix, &scan[xi]); - } - } - - /* Scaling by subsampling (grow) */ - else if (iw < ow) - { - iw--; - ow--; - - /* read first pixel: */ - pix = gdk_rgb_image_get_pixel(im, x, y); - pixel_to_rgb(pix, &next); - prev = next; - - /* si and sifrac give the subsampling position: */ - si = x; - sifrac = 0; - - /* get_next_pix tells us, that we need the next pixel */ - get_next_pix = TRUE; - - for (xi = 0; xi <= ow; xi++) - { - if (get_next_pix) - { - prev = next; - if (xi < ow) - { - /* only get next pixel if in same icon */ - pix = gdk_rgb_image_get_pixel(im, si + 1, y); - pixel_to_rgb(pix, &next); - } - } - - /* calculate subsampled color values: */ - /* division by ow occurs in scale_icon */ - scan[xi].red = prev.red * (ow - sifrac) + next.red * sifrac; - scan[xi].green = prev.green * (ow - sifrac) + next.green * sifrac; - scan[xi].blue = prev.blue * (ow - sifrac) + next.blue * sifrac; - - /* advance sampling position: */ - sifrac += iw; - if (sifrac >= ow) - { - si++; - sifrac -= ow; - get_next_pix = TRUE; - } - else - { - get_next_pix = FALSE; - } - - } - } - - /* Scaling by averaging (shrink) */ - else - { - /* width of an output pixel in input pixels: */ - add_whole = iw / ow; - add_frac = iw % ow; - - /* start position of the first output pixel: */ - si = x; - sifrac = 0; - - /* get first input pixel: */ - pix = gdk_rgb_image_get_pixel(im, x, y); - pixel_to_rgb(pix, &next); - - for (xi = 0; xi < ow; xi++) - { - /* find endpoint of the current output pixel: */ - ci = si + add_whole; - cifrac = sifrac + add_frac; - if (cifrac >= ow) - { - ci++; - cifrac -= ow; - } - - /* take fraction of current input pixel (starting segment): */ - scan[xi].red = next.red * (ow - sifrac); - scan[xi].green = next.green * (ow - sifrac); - scan[xi].blue = next.blue * (ow - sifrac); - si++; - - /* add values for whole pixels: */ - while (si < ci) - { - rgb_type tmp_rgb; - - pix = gdk_rgb_image_get_pixel(im, si, y); - pixel_to_rgb(pix, &tmp_rgb); - scan[xi].red += tmp_rgb.red * ow; - scan[xi].green += tmp_rgb.green * ow; - scan[xi].blue += tmp_rgb.blue * ow; - si++; - } - - /* add fraction of current input pixel (ending segment): */ - if (xi < ow - 1) - { - /* only get next pixel if still in icon: */ - pix = gdk_rgb_image_get_pixel(im, si, y); - pixel_to_rgb(pix, &next); - } - - sifrac = cifrac; - if (sifrac > 0) - { - scan[xi].red += next.red * sifrac; - scan[xi].green += next.green * sifrac; - scan[xi].blue += next.blue * sifrac; - } - } - } -} - - -/* - * put_rgb_scan takes arrays for red, green and blue and writes pixel values - * according to this values in the GdkRGBImage-structure. w is the number of - * pixels to write and div is the value by which all red/green/blue values - * are divided first. - */ -static void put_rgb_scan( - GdkRGBImage *im, - int x, - int y, - int w, - int div, - rgb_type *scan) -{ - int xi; - guint32 pix; - guint32 adj = div / 2; - - for (xi = 0; xi < w; xi++) - { - byte r, g, b; - - /* un-factor the RGB values */ - r = (scan[xi].red + adj) / div; - g = (scan[xi].green + adj) / div; - b = (scan[xi].blue + adj) / div; - - /* Make a (virtual) 24-bit pixel */ - pix = (r << 16) | (g << 8) | (b); - - /* Draw it into image */ - gdk_rgb_image_put_pixel(im, x + xi, y, pix); - } -} - - -/* - * scale_icon transfers an area from GdkRGBImage im_in, locate (x1,y1) to - * im_out, locate (x2, y2). Source size is (ix, iy) and destination size - * is (ox, oy). - * - * It does this by getting icon scan line from get_scaled_scan and handling - * them the same way as pixels are handled in get_scaled_scan. - * This even allows icons to be scaled differently in horizontal and - * vertical directions (eg. shrink horizontal, grow vertical). - */ -static void scale_icon( - GdkRGBImage *im_in, - GdkRGBImage *im_out, - int x1, - int y1, - int x2, - int y2, - int ix, - int iy, - int ox, - int oy) -{ - int div; - int xi, yi, si, sifrac, ci, cifrac, add_whole, add_frac; - - /* buffers for pixel rows: */ - rgb_type prev[MAX_ICON_WIDTH]; - rgb_type next[MAX_ICON_WIDTH]; - rgb_type temp[MAX_ICON_WIDTH]; - - bool_ get_next_row; - - /* get divider value for the horizontal scaling: */ - if (ix == ox) - div = 1; - else if (ix < ox) - div = ox - 1; - else - div = ix; - - /* no scaling needed vertically: */ - if (iy == oy) - { - for (yi = 0; yi < oy; yi++) - { - get_scaled_row(im_in, x1, y1 + yi, ix, ox, temp); - put_rgb_scan(im_out, x2, y2 + yi, ox, div, temp); - } - } - - /* scaling by subsampling (grow): */ - else if (iy < oy) - { - iy--; - oy--; - div *= oy; - - /* get first row: */ - get_scaled_row(im_in, x1, y1, ix, ox, next); - - /* si and sifrac give the subsampling position: */ - si = y1; - sifrac = 0; - - /* get_next_row tells us, that we need the next row */ - get_next_row = TRUE; - for (yi = 0; yi <= oy; yi++) - { - if (get_next_row) - { - for (xi = 0; xi < ox; xi++) - { - prev[xi] = next[xi]; - } - if (yi < oy) - { - /* only get next row if in same icon */ - get_scaled_row(im_in, x1, si + 1, ix, ox, next); - } - } - - /* calculate subsampled color values: */ - /* division by oy occurs in put_rgb_scan */ - for (xi = 0; xi < ox; xi++) - { - temp[xi].red = (prev[xi].red * (oy - sifrac) + - next[xi].red * sifrac); - temp[xi].green = (prev[xi].green * (oy - sifrac) + - next[xi].green * sifrac); - temp[xi].blue = (prev[xi].blue * (oy - sifrac) + - next[xi].blue * sifrac); - } - - /* write row to output image: */ - put_rgb_scan(im_out, x2, y2 + yi, ox, div, temp); - - /* advance sampling position: */ - sifrac += iy; - if (sifrac >= oy) - { - si++; - sifrac -= oy; - get_next_row = TRUE; - } - else - { - get_next_row = FALSE; - } - - } - } - - /* scaling by averaging (shrink) */ - else - { - div *= iy; - - /* height of a output row in input rows: */ - add_whole = iy / oy; - add_frac = iy % oy; - - /* start position of the first output row: */ - si = y1; - sifrac = 0; - - /* get first input row: */ - get_scaled_row(im_in, x1, y1, ix, ox, next); - for (yi = 0; yi < oy; yi++) - { - /* find endpoint of the current output row: */ - ci = si + add_whole; - cifrac = sifrac + add_frac; - if (cifrac >= oy) - { - ci++; - cifrac -= oy; - } - - /* take fraction of current input row (starting segment): */ - for (xi = 0; xi < ox; xi++) - { - temp[xi].red = next[xi].red * (oy - sifrac); - temp[xi].green = next[xi].green * (oy - sifrac); - temp[xi].blue = next[xi].blue * (oy - sifrac); - } - si++; - - /* add values for whole pixels: */ - while (si < ci) - { - get_scaled_row(im_in, x1, si, ix, ox, next); - for (xi = 0; xi < ox; xi++) - { - temp[xi].red += next[xi].red * oy; - temp[xi].green += next[xi].green * oy; - temp[xi].blue += next[xi].blue * oy; - } - si++; - } - - /* add fraction of current input row (ending segment): */ - if (yi < oy - 1) - { - /* only get next row if still in icon: */ - get_scaled_row(im_in, x1, si, ix, ox, next); - } - sifrac = cifrac; - for (xi = 0; xi < ox; xi++) - { - temp[xi].red += next[xi].red * sifrac; - temp[xi].green += next[xi].green * sifrac; - temp[xi].blue += next[xi].blue * sifrac; - } - - /* write row to output image: */ - put_rgb_scan(im_out, x2, y2 + yi, ox, div, temp); - } - } -} - - -/* - * Rescale icons using sort of anti-aliasing technique. - */ -static GdkRGBImage *resize_tiles_smooth( - GdkRGBImage *im, - int ix, - int iy, - int ox, - int oy) -{ - int width1, height1, width2, height2; - int x1, x2, y1, y2; - - GdkRGBImage *tmp; - - /* Original size */ - width1 = im->width; - height1 = im->height; - - /* Rescaled size */ - width2 = ox * width1 / ix; - height2 = oy * height1 / iy; - - /* Allocate GdkRGBImage for resized tiles */ - tmp = gdk_rgb_image_new(width2, height2); - - /* Oops */ - if (tmp == NULL) return (NULL); - - /* Scale each icon */ - for (y1 = 0, y2 = 0; (y1 < height1) && (y2 < height2); y1 += iy, y2 += oy) - { - for (x1 = 0, x2 = 0; (x1 < width1) && (x2 < width2); x1 += ix, x2 += ox) - { - scale_icon(im, tmp, x1, y1, x2, y2, - ix, iy, ox, oy); - } - } - - return tmp; -} - - -/* - * Steven Fuerst's tile resizing code - * Taken from Z because I think the algorithm is cool. - */ - -/* 24-bit version - GdkRGB uses 24 bit RGB data internally */ -static void copy_pixels( - int wid, - int y, - int offset, - int *xoffsets, - GdkRGBImage *old_image, - GdkRGBImage *new_image) -{ - int i; - - /* Get source and destination */ - byte *src = &old_image->image[offset * old_image->width * 3]; - byte *dst = &new_image->image[y * new_image->width * 3]; - - /* Copy to the image */ - for (i = 0; i < wid; i++) - { - *dst++ = src[3 * xoffsets[i]]; - *dst++ = src[3 * xoffsets[i] + 1]; - *dst++ = src[3 * xoffsets[i] + 2]; - } -} - - -#if 0 - -/* 32-bit version: it might be useful in the future */ -static void copy_pixels( - int wid, - int y, - int offset, - int *xoffsets, - GdkRGBImage *old_image, - GdkRGBImage *new_image) -{ - int i; - - /* Get source and destination */ - byte *src = &old_image->image[offset * old_image->width * 4]; - byte *dst = &new_image->image[y * new_image->width * 4]; - - /* Copy to the image */ - for (i = 0; i < wid; i++) - { - *dst++ = src[4 * xoffsets[i]]; - *dst++ = src[4 * xoffsets[i] + 1]; - *dst++ = src[4 * xoffsets[i] + 2]; - *dst++ = src[4 * xoffsets[i] + 3]; - } -} - -#endif - - -/* - * Resize ix * iy pixel tiles in old to ox * oy pixels - * and return a new GdkRGBImage containing the resized tiles - */ -static GdkRGBImage *resize_tiles_fast( - GdkRGBImage *old_image, - int ix, - int iy, - int ox, - int oy) -{ - GdkRGBImage *new_image; - - int old_wid, old_hgt; - - int new_wid, new_hgt; - - int add, remainder, rem_tot, offset; - - int *xoffsets; - - int i; - - - /* Get the size of the old image */ - old_wid = old_image->width; - old_hgt = old_image->height; - - /* Calculate the size of the new image */ - new_wid = (old_wid / ix) * ox; - new_hgt = (old_hgt / iy) * oy; - - /* Allocate a GdkRGBImage to store resized tiles */ - new_image = gdk_rgb_image_new(new_wid, new_hgt); - - /* Paranoia */ - if (new_image == NULL) return (NULL); - - /* now begins the cool part of SF's code */ - - /* - * Calculate an offsets table, so the transformation - * is faster. This is much like the Bresenham algorithm - */ - - /* Set up x offset table */ - C_MAKE(xoffsets, new_wid, int); - - /* Initialize line parameters */ - add = old_wid / new_wid; - remainder = old_wid % new_wid; - - /* Start at left */ - offset = 0; - - /* Half-tile offset so 'line' is centered correctly */ - rem_tot = new_wid / 2; - - for (i = 0; i < new_wid; i++) - { - /* Store into the table */ - xoffsets[i] = offset; - - /* Move to next entry */ - offset += add; - - /* Take care of fractional part */ - rem_tot += remainder; - if (rem_tot >= new_wid) - { - rem_tot -= new_wid; - offset++; - } - } - - /* Scan each row */ - - /* Initialize line parameters */ - add = old_hgt / new_hgt; - remainder = old_hgt % new_hgt; - - /* Start at left */ - offset = 0; - - /* Half-tile offset so 'line' is centered correctly */ - rem_tot = new_hgt / 2; - - for (i = 0; i < new_hgt; i++) - { - /* Copy pixels to new image */ - copy_pixels(new_wid, i, offset, xoffsets, old_image, new_image); - - /* Move to next entry */ - offset += add; - - /* Take care of fractional part */ - rem_tot += remainder; - if (rem_tot >= new_hgt) - { - rem_tot -= new_hgt; - offset++; - } - } - - /* Free offset table */ - C_FREE(xoffsets, new_wid, int); - - return (new_image); -} - - -/* - * Resize an image of ix * iy pixels and return a newly allocated - * image of ox * oy pixels. - */ -static GdkRGBImage *resize_tiles( - GdkRGBImage *im, - int ix, - int iy, - int ox, - int oy) -{ - GdkRGBImage *result; - - /* - * I hope we can always use this with GdkRGB, which uses a 5x5x5 - * colour cube (125 colours) by default, and resort to dithering - * when it can't find good match there or expand the cube, so it - * works with 8bpp X servers. - */ - if (smooth_rescaling_request && (ix != ox || iy != oy)) - { - result = resize_tiles_smooth(im, ix, iy, ox, oy); - } - - /* - * Unless smoothing is requested by user, we use the fast - * resizing code. - */ - else - { - result = resize_tiles_fast(im, ix, iy, ox, oy); - } - - /* Return rescaled tiles, or NULL */ - return (result); -} - - -/* - * Tile loaders - XPM and BMP - */ - -/* - * A helper function for the XPM loader - * - * Read next string delimited by double quotes from - * the input stream. Return TRUE on success, FALSE - * if it finds EOF or buffer overflow. - * - * I never mean this to be generic, so its EOF and buffer - * overflow behaviour is terribly stupid -- there are no - * provisions for recovery. - * - * CAVEAT: treatment of backslash is not compatible with the standard - * C usage XXX XXX XXX XXX - */ -static bool_ read_str(char *buf, u32b len, FILE *f) -{ - int c; - - /* Paranoia - Buffer too small */ - if (len <= 0) return (FALSE); - - /* Find " */ - while ((c = getc(f)) != '"') - { - /* Premature EOF */ - if (c == EOF) return (FALSE); - } - - while (1) - { - /* Read next char */ - c = getc(f); - - /* Premature EOF */ - if (c == EOF) return (FALSE); - - /* Terminating " */ - if (c == '"') break; - - /* Escape */ - if (c == '\\') - { - /* Use next char */ - c = getc(f); - - /* Premature EOF */ - if (c == EOF) return (FALSE); - } - - /* Store character in the buffer */ - *buf++ = c; - - /* Decrement count */ - len--; - - /* Buffer full - we have to place a NULL at the end */ - if (len <= 0) return (FALSE); - } - - /* Make a C string if there's room left */ - if (len > 0) *buf = '\0'; - - /* Success */ - return (TRUE); -} - - -/* - * Remember pixel symbol to RGB colour mappings - */ - -/* - * I've forgot the formula, but I remember prime number yields - * good results - */ -#define HASH_SIZE 19 - -typedef struct pal_type pal_type; - -struct pal_type -{ - u32b str; - u32b rgb; - pal_type *next; -}; - - -/* - * A simple, slow and stupid XPM loader - */ -static GdkRGBImage *load_xpm(cptr filename) -{ - FILE *f; - GdkRGBImage *img = NULL; - int width, height, colours, chars; - int i, j, k; - bool_ ret; - pal_type *pal = NULL; - pal_type *head[HASH_SIZE]; - u32b buflen = 0; - char *lin = NULL; - char buf[1024]; - - /* Build path to the XPM file */ - path_build(buf, 1024, ANGBAND_DIR_XTRA_GRAF, filename); - - /* Open it */ - f = my_fopen(buf, "r"); - - /* Oops */ - if (f == NULL) return (NULL); - - /* Read header */ - ret = read_str(buf, 1024, f); - - /* Oops */ - if (!ret) - { - /* Notify error */ - plog("Cannot find XPM header"); - - /* Failure */ - goto oops; - } - - /* Parse header */ - if (4 != sscanf(buf, "%d %d %d %d", &width, &height, &colours, &chars)) - { - /* Notify error */ - plog("Bad XPM header"); - - /* Failure */ - goto oops; - } - - /* - * Paranoia - the code can handle upto four letters per pixel, - * but such large number of colours certainly requires a smarter - * symbol-to-colour mapping algorithm... - */ - if ((width <= 0) || (height <= 0) || (colours <= 0) || (chars <= 0) || - (chars > 2)) - { - /* Notify error */ - plog("Invalid width/height/depth"); - - /* Failure */ - goto oops; - } - - /* Allocate palette */ - C_MAKE(pal, colours, pal_type); - - /* Initialise hash table */ - for (i = 0; i < HASH_SIZE; i++) head[i] = NULL; - - /* Parse palette */ - for (i = 0; i < colours; i++) - { - u32b tmp; - int h_idx; - - /* Read next string */ - ret = read_str(buf, 1024, f); - - /* Check I/O result */ - if (!ret) - { - /* Notify error */ - plog("EOF in palette"); - - /* Failure */ - goto oops; - } - - /* Clear symbol code */ - tmp = 0; - - /* Encode pixel symbol */ - for (j = 0; j < chars; j++) - { - tmp = (tmp << 8) | (buf[j] & 0xFF); - } - - /* Remember it */ - pal[i].str = tmp; - - /* Skip spaces */ - while ((buf[j] == ' ') || (buf[j] == '\t')) j++; - - /* Verify 'c' */ - if (buf[j] != 'c') - { - /* Notify error */ - plog("No 'c' in palette definition"); - - /* Failure */ - goto oops; - } - - /* Advance cursor */ - j++; - - /* Skip spaces */ - while ((buf[j] == ' ') || (buf[j] == '\t')) j++; - - /* Hack - Assume 'None' */ - if (buf[j] == 'N') - { - /* Angband always uses black background */ - pal[i].rgb = 0x000000; - } - - /* Read colour */ - else if ((1 != sscanf(&buf[j], "#%06lX", &tmp)) && - (1 != sscanf(&buf[j], "#%06lx", &tmp))) - { - /* Notify error */ - plog("Badly formatted colour"); - - /* Failure */ - goto oops; - } - - /* Remember it */ - pal[i].rgb = tmp; - - /* Store it in hash table as well */ - h_idx = pal[i].str % HASH_SIZE; - - /* Link the entry */ - pal[i].next = head[h_idx]; - head[h_idx] = &pal[i]; - } - - /* Allocate image */ - img = gdk_rgb_image_new(width, height); - - /* Oops */ - if (img == NULL) - { - /* Notify error */ - plog("Cannot allocate image"); - - /* Failure */ - goto oops; - } - - /* Calculate buffer length */ - buflen = width * chars + 1; - - /* Allocate line buffer */ - C_MAKE(lin, buflen, char); - - /* For each row */ - for (i = 0; i < height; i++) - { - /* Read a row of image data */ - ret = read_str(lin, buflen, f); - - /* Oops */ - if (!ret) - { - /* Notify error */ - plog("EOF in middle of image data"); - - /* Failure */ - goto oops; - } - - /* For each column */ - for (j = 0; j < width; j++) - { - u32b tmp; - pal_type *h_ptr; - - /* Clear encoded pixel */ - tmp = 0; - - /* Encode pixel symbol */ - for (k = 0; k < chars; k++) - { - tmp = (tmp << 8) | (lin[j * chars + k] & 0xFF); - } - - /* Find colour */ - for (h_ptr = head[tmp % HASH_SIZE]; - h_ptr != NULL; - h_ptr = h_ptr->next) - { - /* Found a match */ - if (h_ptr->str == tmp) break; - } - - /* No match found */ - if (h_ptr == NULL) - { - /* Notify error */ - plog("Invalid pixel symbol"); - - /* Failure */ - goto oops; - } - - /* Draw it */ - gdk_rgb_image_put_pixel( - img, - j, - i, - h_ptr->rgb); - } - } - - /* Close file */ - my_fclose(f); - - /* Free line buffer */ - C_FREE(lin, buflen, char); - - /* Free palette */ - C_FREE(pal, colours, pal_type); - - /* Return result */ - return (img); - -oops: - - /* Close file */ - my_fclose(f); - - /* Free image */ - if (img) gdk_rgb_image_destroy(img); - - /* Free line buffer */ - if (lin) C_FREE(lin, buflen, char); - - /* Free palette */ - if (pal) C_FREE(pal, colours, pal_type); - - /* Failure */ - return (NULL); -} - - -/* - * A BMP loader, yet another duplication of maid-x11.c functions. - * - * Another duplication, again because of different image format and - * avoidance of colour allocation. - * - * XXX XXX XXX XXX Should avoid using a propriatary and closed format. - * Since it's much bigger than gif that was used before, why don't - * we switch to XPM? NetHack does. Well, NH has always been much - * closer to the GNU/Un*x camp and it's GPL'ed quite early... - * - * The names and naming convention are worse than the worst I've ever - * seen, so I deliberately changed them to fit well with the rest of - * the code. Or are they what xx calls them? If it's the case, there's - * no reason to follow *their* words. - */ - -/* - * BMP file header - */ -typedef struct bmp_file_type bmp_file_type; - -struct bmp_file_type -{ - u16b type; - u32b size; - u16b reserved1; - u16b reserved2; - u32b offset; -}; - - -/* - * BMP file information fields - */ -typedef struct bmp_info_type bmp_info_type; - -struct bmp_info_type -{ - u32b size; - u32b width; - u32b height; - u16b planes; - u16b bit_count; - u32b compression; - u32b size_image; - u32b x_pels_per_meter; - u32b y_pels_per_meter; - u32b colors_used; - u32b color_importand; -}; - -/* - * "RGBQUAD" type. - */ -typedef struct rgb_quad_type rgb_quad_type; - -struct rgb_quad_type -{ - unsigned char b, g, r; - unsigned char filler; -}; - - -/*** Helper functions for system independent file loading. ***/ - -static byte get_byte(FILE *fff) -{ - /* Get a character, and return it */ - return (getc(fff) & 0xFF); -} - -static void rd_byte(FILE *fff, byte *ip) -{ - *ip = get_byte(fff); -} - -static void rd_u16b(FILE *fff, u16b *ip) -{ - (*ip) = get_byte(fff); - (*ip) |= ((u16b)(get_byte(fff)) << 8); -} - -static void rd_u32b(FILE *fff, u32b *ip) -{ - (*ip) = get_byte(fff); - (*ip) |= ((u32b)(get_byte(fff)) << 8); - (*ip) |= ((u32b)(get_byte(fff)) << 16); - (*ip) |= ((u32b)(get_byte(fff)) << 24); -} - - -/* - * Read a BMP file (a certain trademark nuked) - * - * This function replaces the old ReadRaw and RemapColors functions. - * - * Assumes that the bitmap has a size such that no padding is needed in - * various places. Currently only handles bitmaps with 3 to 256 colors. - */ -GdkRGBImage *load_bmp(cptr filename) -{ - FILE *f; - - char path[1024]; - - bmp_file_type file_hdr; - bmp_info_type info_hdr; - - GdkRGBImage *result = NULL; - - int ncol; - - int i; - - u32b x, y; - - guint32 colour_pixels[256]; - - - /* Build the path to the bmp file */ - path_build(path, 1024, ANGBAND_DIR_XTRA_GRAF, filename); - - /* Open the BMP file */ - f = fopen(path, "r"); - - /* No such file */ - if (f == NULL) - { - return (NULL); - } - - /* Read the "bmp_file_type" */ - rd_u16b(f, &file_hdr.type); - rd_u32b(f, &file_hdr.size); - rd_u16b(f, &file_hdr.reserved1); - rd_u16b(f, &file_hdr.reserved2); - rd_u32b(f, &file_hdr.offset); - - /* Read the "bmp_info_type" */ - rd_u32b(f, &info_hdr.size); - rd_u32b(f, &info_hdr.width); - rd_u32b(f, &info_hdr.height); - rd_u16b(f, &info_hdr.planes); - rd_u16b(f, &info_hdr.bit_count); - rd_u32b(f, &info_hdr.compression); - rd_u32b(f, &info_hdr.size_image); - rd_u32b(f, &info_hdr.x_pels_per_meter); - rd_u32b(f, &info_hdr.y_pels_per_meter); - rd_u32b(f, &info_hdr.colors_used); - rd_u32b(f, &info_hdr.color_importand); - - /* Verify the header */ - if (feof(f) || - (file_hdr.type != 19778) || - (info_hdr.size != 40)) - { - plog(format("Incorrect BMP file format %s", filename)); - fclose(f); - return (NULL); - } - - /* - * The two headers above occupy 54 bytes total - * The "offset" field says where the data starts - * The "colors_used" field does not seem to be reliable - */ - - /* Compute number of colors recorded */ - ncol = (file_hdr.offset - 54) / 4; - - for (i = 0; i < ncol; i++) - { - rgb_quad_type clr; - - /* Read an "rgb_quad_type" */ - rd_byte(f, &clr.b); - rd_byte(f, &clr.g); - rd_byte(f, &clr.r); - rd_byte(f, &clr.filler); - - /* Remember the pixel */ - colour_pixels[i] = (clr.r << 16) | (clr.g << 8) | (clr.b); - } - - /* Allocate GdkRGBImage large enough to store the image */ - result = gdk_rgb_image_new(info_hdr.width, info_hdr.height); - - /* Failure */ - if (result == NULL) - { - fclose(f); - return (NULL); - } - - for (y = 0; y < info_hdr.height; y++) - { - u32b y2 = info_hdr.height - y - 1; - - for (x = 0; x < info_hdr.width; x++) - { - int ch = getc(f); - - /* Verify not at end of file XXX XXX */ - if (feof(f)) - { - plog(format("Unexpected end of file in %s", filename)); - gdk_rgb_image_destroy(result); - fclose(f); - return (NULL); - } - - if (info_hdr.bit_count == 24) - { - int c3, c2 = getc(f); - - /* Verify not at end of file XXX XXX */ - if (feof(f)) - { - plog(format("Unexpected end of file in %s", filename)); - gdk_rgb_image_destroy(result); - fclose(f); - return (NULL); - } - - c3 = getc(f); - - /* Verify not at end of file XXX XXX */ - if (feof(f)) - { - plog(format("Unexpected end of file in %s", filename)); - gdk_rgb_image_destroy(result); - fclose(f); - return (NULL); - } - - /* Draw the pixel */ - gdk_rgb_image_put_pixel( - result, - x, - y2, - (ch << 16) | (c2 << 8) | (c3)); - } - else if (info_hdr.bit_count == 8) - { - gdk_rgb_image_put_pixel(result, x, y2, colour_pixels[ch]); - } - else if (info_hdr.bit_count == 4) - { - gdk_rgb_image_put_pixel(result, x, y2, colour_pixels[ch / 16]); - x++; - gdk_rgb_image_put_pixel(result, x, y2, colour_pixels[ch % 16]); - } - else - { - /* Technically 1 bit is legal too */ - plog(format("Illegal bit count %d in %s", - info_hdr.bit_count, filename)); - gdk_rgb_image_destroy(result); - fclose(f); - return (NULL); - } - } - } - - fclose(f); - - return result; -} - - -/* - * Try to load an XPM file, or a BMP file if it fails - * - * Choice of file format may better be made yet another option XXX - */ -static GdkRGBImage *load_tiles(cptr basename) -{ - char buf[32]; - GdkRGBImage *img; - - /* build xpm file name */ - strnfmt(buf, 32, "%s.xpm", basename); - - /* Try to load it */ - img = load_xpm(buf); - - /* OK */ - if (img) return (img); - - /* Try again for a bmp file */ - strnfmt(buf, 32, "%s.bmp", basename); - - /* Try loading it */ - img = load_bmp(buf); - - /* Return result, success or failure */ - return (img); -} - - -/* - * Free all tiles and graphics buffers associated with windows - * - * This is conspirator of graf_init() below, sharing its inefficiency - */ -static void graf_nuke() -{ - int i; - - term_data *td; - - - /* Nuke all terms */ - for (i = 0; i < MAX_TERM_DATA; i++) - { - /* Access term_data structure */ - td = &data[i]; - - /* Disable graphics */ - td->t.higher_pict = FALSE; - - /* Free previously allocated tiles */ - if (td->tiles) gdk_rgb_image_destroy(td->tiles); - - /* Forget pointer */ - td->tiles = NULL; - - /* Free previously allocated transparency buffer */ - if (td->trans_buf) gdk_rgb_image_destroy(td->trans_buf); - - /* Forget stale pointer */ - td->trans_buf = NULL; - } -} - - -/* - * Load tiles, scale them to current font size, and store a pointer - * to them in a term_data structure for each term. - * - * XXX XXX XXX This is a terribly stupid quick hack. - * - * XXX XXX XXX Windows using the same font should share resized tiles - */ -static bool_ graf_init( - cptr filename, - int tile_wid, - int tile_hgt) -{ - term_data *td; - - bool_ result; - - GdkRGBImage *raw_tiles, *scaled_tiles; - - GdkRGBImage *buffer; - - int i; - - - /* Paranoia */ - if (filename == NULL) return (FALSE); - - /* Load tiles */ - raw_tiles = load_tiles(filename); - - /* Oops */ - if (raw_tiles == NULL) - { - /* Clean up */ - graf_nuke(); - - /* Failure */ - return (FALSE); - } - - /* Calculate and remember numbers of rows and columns */ - tile_rows = raw_tiles->height / tile_hgt; - tile_cols = raw_tiles->width / tile_wid; - - /* Be optimistic */ - result = TRUE; - - - /* - * (Re-)init each term - * XXX It might help speeding this up to avoid doing so if a window - * doesn't need graphics (e.g. inventory/equipment and message recall). - */ - for (i = 0; i < MAX_TERM_DATA; i++) - { - /* Access term_data */ - td = &data[i]; - - /* Shouldn't waste anything for unused terms */ - if (!td->shown) continue; - - /* Enable graphics */ - td->t.higher_pict = TRUE; - - /* See if we need rescaled tiles XXX */ - if ((td->tiles == NULL) || - (td->tiles->width != td->tile_wid * tile_cols) || - (td->tiles->height != td->tile_hgt * tile_rows)) - { - /* Free old tiles if present */ - if (td->tiles) gdk_rgb_image_destroy(td->tiles); - - /* Forget pointer */ - td->tiles = NULL; - - /* Scale the tiles to current font bounding rect */ - scaled_tiles = resize_tiles( - raw_tiles, - tile_wid, tile_hgt, - td->tile_wid, td->tile_hgt); - - /* Oops */ - if (scaled_tiles == NULL) - { - /* Failure */ - result = FALSE; - - break; - } - - /* Store it */ - td->tiles = scaled_tiles; - } - - /* See if we have to (re)allocate a new buffer XXX */ - if ((td->trans_buf == NULL) || - (td->trans_buf->width != td->tile_wid) || - (td->trans_buf->height != td->tile_hgt)) - { - /* Free old buffer if present */ - if (td->trans_buf) gdk_rgb_image_destroy(td->trans_buf); - - /* Forget pointer */ - td->trans_buf = NULL; - - /* Allocate a new buffer */ - buffer = gdk_rgb_image_new(td->tile_wid, td->tile_hgt); - - /* Oops */ - if (buffer == NULL) - { - /* Failure */ - result = FALSE; - - break; - } - - /* Store it */ - td->trans_buf = buffer; - } - - /* - * Giga-Hack - assume top left corner of 0x86/0x80 should be - * in the background colour XXX XXX XXX XXX - */ - td->bg_pixel = gdk_rgb_image_get_pixel( - raw_tiles, - 0, - tile_hgt * 6); - - } - - - /* Alas, we need to free wasted images */ - if (result == FALSE) graf_nuke(); - - /* We don't need the raw image any longer */ - gdk_rgb_image_destroy(raw_tiles); - - /* Report success or failure */ - return (result); -} - - -/* - * React to various changes in graphics mode settings - * - * It is *not* a requirement for tiles to have same pixel width and height. - * The program can work with any conbinations of graf_wid and graf_hgt - * (oops, they must be representable by u16b), as long as they are lesser - * or equal to 32 if you use smooth rescaling. - */ -static void init_graphics(void) -{ - cptr tile_name; - - u16b graf_wid = 0, graf_hgt = 0; - - - /* No graphics requests are made - Can't this be simpler? XXX XXX */ - if ((graf_mode_request == graf_mode) && - (smooth_rescaling_request == smooth_rescaling) && - !resize_request) return; - - /* Prevent further unsolicited reaction */ - resize_request = FALSE; - - - /* Dispose unusable old tiles - awkward... XXX XXX */ - if ((graf_mode_request == GRAF_MODE_NONE) || - (graf_mode_request != graf_mode) || - (smooth_rescaling_request != smooth_rescaling)) graf_nuke(); - - - /* Setup parameters according to request */ - switch (graf_mode_request) - { - /* ASCII - no graphics whatsoever */ - default: - case GRAF_MODE_NONE: - { - tile_name = NULL; - use_graphics = arg_graphics = FALSE; - - break; - } - - /* - * 8x8 tiles originally collected for the Amiga port - * from several contributers by Lars Haugseth, converted - * to 256 colours and expanded by the Z devteam - * - * Use the "old" tile assignments - * - * Dawnmist is working on it for ToME - */ - case GRAF_MODE_OLD: - { - tile_name = "8x8"; - graf_wid = graf_hgt = 8; - ANGBAND_GRAF = "old"; - use_graphics = arg_graphics = TRUE; - - break; - } - - /* - * Adam Bolt's 16x16 tiles - * "new" tile assignments - * It is updated for ToME by Andreas Koch - */ - case GRAF_MODE_NEW: - { - tile_name = "16x16"; - graf_wid = graf_hgt = 16; - ANGBAND_GRAF = "new"; - use_graphics = arg_graphics = TRUE; - - break; - } - } - - - /* load tiles and set them up if tiles are requested */ - if ((graf_mode_request != GRAF_MODE_NONE) && - !graf_init(tile_name, graf_wid, graf_hgt)) - { - /* Oops */ - plog("Cannot initialize graphics"); - - /* reject requests */ - graf_mode_request = GRAF_MODE_NONE; - smooth_rescaling_request = smooth_rescaling; - - /* reset graphics flags */ - use_graphics = arg_graphics = FALSE; - } - - /* Update current graphics mode */ - graf_mode = graf_mode_request; - smooth_rescaling = smooth_rescaling_request; - - /* Reset visuals */ -#ifndef ANG281_RESET_VISUALS - reset_visuals(TRUE); -#else - reset_visuals(); -#endif /* !ANG281_RESET_VISUALS */ -} - -#endif /* USE_GRAPHICS */ @@ -2303,7 +267,7 @@ static void Term_nuke_gtk(term *t) /* Free name */ - if (td->name) string_free(td->name); + if (td->name) free(td->name); /* Forget it */ td->name = NULL; @@ -2320,21 +284,6 @@ static void Term_nuke_gtk(term *t) /* Forget it too */ td->backing_store = NULL; -#ifdef USE_GRAPHICS - - /* Free tiles */ - if (td->tiles) gdk_rgb_image_destroy(td->tiles); - - /* Forget pointer */ - td->tiles = NULL; - - /* Free transparency buffer */ - if (td->trans_buf) gdk_rgb_image_destroy(td->trans_buf); - - /* Amnesia */ - td->trans_buf = NULL; - -#endif /* USE_GRAPHICS */ } @@ -2458,20 +407,6 @@ static errr Term_curs_gtk(int x, int y) /* Set foreground colour */ term_data_set_fg(td, TERM_YELLOW); -#ifdef USE_DOUBLE_TILES - - /* Mogami's bigtile patch */ - - /* Adjust it if wide tiles are requested */ - if (use_bigtile && - (x + 1 < Term->wid) && - (Term->old->a[y][x + 1] == 255)) - { - cells = 2; - } - -#endif /* USE_DOUBLE_TILES */ - /* Draw the software cursor */ gdk_draw_rectangle( TERM_DATA_DRAWABLE(td), @@ -2490,299 +425,6 @@ static errr Term_curs_gtk(int x, int y) } -#ifdef USE_GRAPHICS - -/* - * XXX XXX Low level graphics helper - * Draw a tile at (s_x, s_y) over one at (t_x, t_y) and store the - * result in td->trans_buf - * - * XXX XXX Even if CPU's are faster than necessary these days, - * this should be made inline. Or better, there should be an API - * to take advantage of graphics hardware. They almost always have - * assortment of builtin bitblt's... - */ -static void overlay_tiles_2( - term_data *td, - int s_x, int s_y, - int t_x, int t_y) -{ - guint32 pix; - int x, y; - - - /* Process each row */ - for (y = 0; y < td->tile_hgt; y++) - { - /* Process each column */ - for (x = 0; x < td->tile_wid; x++) - { - /* Get an overlay pixel */ - pix = gdk_rgb_image_get_pixel(td->tiles, s_x + x, s_y + y); - - /* If it's in background color, use terrain instead */ - if (pix == td->bg_pixel) - pix = gdk_rgb_image_get_pixel(td->tiles, t_x + x, t_y + y); - - /* Store the result in trans_buf */ - gdk_rgb_image_put_pixel(td->trans_buf, x, y, pix); - } - } -} - - -/* - * XXX XXX Low level graphics helper - * Draw a tile at (e_x, e_y) over one at (s_x, s_y) over another one - * at (t_x, t_y) and store the result in td->trans_buf - * - * XXX XXX The same comment applies as that for the above... - */ -static void overlay_tiles_3( - term_data *td, - int e_x, int e_y, - int s_x, int s_y, - int t_x, int t_y) -{ - guint32 pix; - int x, y; - - - /* Process each row */ - for (y = 0; y < td->tile_hgt; y++) - { - /* Process each column */ - for (x = 0; x < td->tile_wid; x++) - { - /* Get an overlay pixel */ - pix = gdk_rgb_image_get_pixel(td->tiles, e_x + x, e_y + y); - - /* - * If it's background colour, try to use one from - * the second layer - */ - if (pix == td->bg_pixel) - pix = gdk_rgb_image_get_pixel(td->tiles, s_x + x, s_y + y); - - /* - * If it's background colour again, fall back to - * the terrain layer - */ - if (pix == td->bg_pixel) - pix = gdk_rgb_image_get_pixel(td->tiles, t_x + x, t_y + y); - - /* Store the pixel in trans_buf */ - gdk_rgb_image_put_pixel(td->trans_buf, x, y, pix); - } - } -} - - - -/* - * Low level graphics (Assumes valid input) - * - * Draw "n" tiles/characters starting at (x,y) - */ -static errr Term_pict_gtk( - int x, int y, int n, - const byte *ap, const char *cp, - const byte *tap, const char *tcp, - const byte *eap, const char *ecp) -{ - term_data *td = (term_data*)(Term->data); - - int i; - - int d_x, d_y; - -# ifdef USE_DOUBLE_TILES - - /* Hack - remember real number of columns affected XXX XXX XXX */ - int cols; - -# endif /* USE_DOUBLE_TILES */ - - - /* Don't draw to hidden windows */ - if (!td->shown) return (0); - - /* Paranoia */ - g_assert(td->drawing_area->window != 0); - - /* Top left corner of the destination rect */ - d_x = x * td->font_wid; - d_y = y * td->font_hgt; - - -# ifdef USE_DOUBLE_TILES - - /* Reset column counter */ - cols = 0; - -# endif /* USE_DOUBLE_TILES */ - - /* Scan the input */ - for (i = 0; i < n; i++) - { - byte a; - char c; - int s_x, s_y; - - byte ta; - char tc; - int t_x, t_y; - - byte ea; - char ec; - int e_x = 0, e_y = 0; - bool_ has_overlay; - - - /* Grid attr/char */ - a = *ap++; - c = *cp++; - - /* Terrain attr/char */ - ta = *tap++; - tc = *tcp++; - - /* Overlay attr/char */ - ea = *eap++; - ec = *ecp++; - has_overlay = (ea && ec); - - /* Row and Col */ - s_y = (((byte)a & 0x7F) % tile_rows) * td->tile_hgt; - s_x = (((byte)c & 0x7F) % tile_cols) * td->tile_wid; - - /* Terrain Row and Col */ - t_y = (((byte)ta & 0x7F) % tile_rows) * td->tile_hgt; - t_x = (((byte)tc & 0x7F) % tile_cols) * td->tile_wid; - - /* Overlay Row and Col */ - if (has_overlay) - { - e_y = (((byte)ea & 0x7F) % tile_rows) * td->tile_hgt; - e_x = (((byte)ec & 0x7F) % tile_cols) * td->tile_wid; - } - - -# ifdef USE_DOUBLE_TILES - - /* Mogami's bigtile patch */ - - /* Hack -- a filler for wide tile */ - if (use_bigtile && (a == 255)) - { - /* Advance */ - d_x += td->font_wid; - - /* Ignore */ - continue; - } - -# endif /* USE_DOUBLE_TILES */ - - /* Optimise the common case: terrain == obj/mons */ - if (!use_transparency || - ((s_x == t_x) && (s_y == t_y))) - { - - /* The simplest possible case - no overlay */ - if (!has_overlay) - { - /* Draw the tile */ - gdk_draw_rgb_image_2( - TERM_DATA_DRAWABLE(td), td->gc, td->tiles, - s_x, s_y, - d_x, d_y, - td->tile_wid, td->tile_hgt); - } - - /* We have to draw overlay... */ - else - { - /* Overlay */ - overlay_tiles_2(td, e_x, e_y, s_x, s_y); - - /* And draw the result */ - gdk_draw_rgb_image_2( - TERM_DATA_DRAWABLE(td), td->gc, td->trans_buf, - 0, 0, - d_x, d_y, - td->tile_wid, td->tile_hgt); - - /* Hack -- Prevent potential display problem */ - gdk_flush(); - } - - } - - /* - * Since there's no masking bitblt in X, - * we have to do that manually... - */ - else - { - - /* No overlay */ - if (!has_overlay) - { - /* Build terrain + masked overlay image */ - overlay_tiles_2(td, s_x, s_y, t_x, t_y); - } - - /* With overlay */ - else - { - /* Ego over mon/PC over terrain */ - overlay_tiles_3(td, e_x, e_y, s_x, s_y, - t_x, t_y); - } - - /* Draw it */ - gdk_draw_rgb_image_2( - TERM_DATA_DRAWABLE(td), td->gc, td->trans_buf, - 0, 0, - d_x, d_y, - td->tile_wid, td->tile_hgt); - - /* Hack -- Prevent potential display problem */ - gdk_flush(); - } - - /* - * Advance x-coordinate - wide font fillers are taken care of - * before entering the tile drawing code. - */ - d_x += td->font_wid; - -# ifdef USE_DOUBLE_TILES - - /* Add up *real* number of columns updated XXX XXX XXX */ - cols += use_bigtile ? 2 : 1; - -# endif /* USE_DOUBLE_TILES */ - } - -# ifndef USE_DOUBLE_TILES - - /* Copy image from backing store if present */ - TERM_DATA_REFRESH(td, x, y, n, 1); - -# else - - /* Copy image from backing store if present */ - TERM_DATA_REFRESH(td, x, y, cols, 1); - -# endif /* USE_DOUBLE_TILES */ - - /* Success */ - return (0); -} - -#endif /* USE_GRAPHICS */ /* @@ -2872,58 +514,6 @@ static errr Term_xtra_gtk(int n, int v) case TERM_XTRA_CLEAR: return (Term_clear_gtk()); - /* Delay for some milliseconds */ - case TERM_XTRA_DELAY: - { - /* sleep for v milliseconds */ - usleep(v * 1000); - - /* Done */ - return (0); - } - - /* Get Delay of some milliseconds */ - case TERM_XTRA_GET_DELAY: - { - int ret; - struct timeval tv; - - ret = gettimeofday(&tv, NULL); - Term_xtra_long = (tv.tv_sec * 1000) + (tv.tv_usec / 1000); - - return ret; - } - - /* Subdirectory scan */ - case TERM_XTRA_SCANSUBDIR: - { - DIR *directory; - struct dirent *entry; - - scansubdir_max = 0; - - directory = opendir(scansubdir_dir); - if (!directory) return (1); - - while ((entry = readdir(directory)) != NULL) - { - char file[PATH_MAX + NAME_MAX + 2]; - struct stat filedata; - - file[PATH_MAX + NAME_MAX] = 0; - strncpy(file, scansubdir_dir, PATH_MAX); - strncat(file, "/", 2); - strncat(file, entry->d_name, NAME_MAX); - if ((stat(file, &filedata) == 0) && S_ISDIR(filedata.st_mode)) - { - string_free(scansubdir_result[scansubdir_max]); - scansubdir_result[scansubdir_max] = - string_make(entry->d_name); - ++scansubdir_max; - } - } - } - /* Rename main window */ case TERM_XTRA_RENAME_MAIN_WIN: gtk_window_set_title(GTK_WINDOW(data[0].window), angband_term_name[0]); return (0); @@ -2933,12 +523,6 @@ static errr Term_xtra_gtk(int n, int v) /* (re-)init colours */ init_colours(); -#ifdef USE_GRAPHICS - - /* Initialise graphics */ - init_graphics(); - -#endif /* USE_GRAPHICS */ /* Success */ return (0); @@ -3095,13 +679,7 @@ static void save_game_gtk(void) msg_flag = FALSE; /* Save the game */ -#ifdef ZANG_SAVE_GAME - /* Also for OAngband - the parameter tells if it's autosave */ - do_cmd_save_game(FALSE); -#else -/* Everything else */ do_cmd_save_game(); -#endif /* ZANG_SAVE_GAME */ } @@ -3208,41 +786,6 @@ static void destroy_sub_event_handler( } -#ifndef SAVEFILE_SCREEN - -/* - * Process File-New menu command - */ -static void new_event_handler( - gpointer user_data, - guint user_action, - GtkWidget *was_clicked) -{ - if (game_in_progress) - { - plog("You can't start a new game while you're still playing!"); - return; - } - - /* The game is in progress */ - game_in_progress = TRUE; - - /* Flush input */ - Term_flush(); - - /* Play game */ - play_game(TRUE); - - /* Houseclearing */ - cleanup_angband(); - - /* Done */ - quit(NULL); -} - -#endif /* !SAVEFILE_SCREEN */ - - /* * Load fond specified by an XLFD fontname and * set up related term_data members @@ -3269,20 +812,6 @@ static void load_font(term_data *td, cptr fontname) td->font_wid = gdk_char_width(td->font, '@'); td->font_hgt = td->font->ascent + td->font->descent; -#ifndef USE_DOUBLE_TILES - - /* Use the current font size for tiles as well */ - td->tile_wid = td->font_wid; - td->tile_hgt = td->font_hgt; - -#else /* !USE_DOUBLE_TILES */ - - /* Calculate the size of tiles */ - if (use_bigtile && (td == &data[0])) td->tile_wid = td->font_wid * 2; - else td->tile_wid = td->font_wid; - td->tile_hgt = td->font_hgt; - -#endif /* !USE_DOUBLE_TILES */ } @@ -3349,216 +878,6 @@ static void change_backing_store_event_handler( } -#ifdef USE_GRAPHICS - -/* - * Set graf_mode_request according to user selection, - * and let Term_xtra react to the change. - */ -static void change_graf_mode_event_handler( - gpointer user_data, - guint user_action, - GtkWidget *was_clicked) -{ - /* Set request according to user selection */ - graf_mode_request = (int)user_action; - - /* - * Hack - force redraw - * This induces a call to Term_xtra(TERM_XTRA_REACT, 0) as well - */ - Term_key_push(KTRL('R')); -} - - -/* - * Set dither_mode according to user selection - */ -static void change_dith_mode_event_handler( - gpointer user_data, - guint user_action, - GtkWidget *was_clicked) -{ - /* Set request according to user selection */ - dith_mode = (int)user_action; - - /* - * Hack - force redraw - */ - Term_key_push(KTRL('R')); -} - - -/* - * Toggles the graphics tile scaling mode (Fast/Smooth) - */ -static void change_smooth_mode_event_handler( - gpointer user_data, - guint user_action, - GtkWidget *was_clicked) -{ - /* (Try to) toggle the smooth rescaling mode */ - smooth_rescaling_request = !smooth_rescaling; - - /* - * Hack - force redraw - * This induces a call to Term_xtra(TERM_XTRA_REACT, 0) as well - */ - Term_key_push(KTRL('R')); -} - - -# ifdef USE_DOUBLE_TILES - -static void change_wide_tile_mode_event_handler( - gpointer user_data, - guint user_action, - GtkWidget *was_clicked) -{ - term *old = Term; - term_data *td = &data[0]; - - /* Toggle "use_bigtile" */ - use_bigtile = !use_bigtile; - -#ifdef TOME - /* T.o.M.E. requires this as well */ - arg_bigtile = use_bigtile; -#endif /* TOME */ - - /* Double the width of tiles (only for the main window) */ - if (use_bigtile) - { - td->tile_wid = td->font_wid * 2; - } - - /* Use the width of current font */ - else - { - td->tile_wid = td->font_wid; - } - - /* Need to resize the tiles */ - resize_request = TRUE; - - /* Activate the main window */ - Term_activate(&td->t); - - /* Resize the term */ - Term_resize(td->cols, td->rows); - - /* Activate the old term */ - Term_activate(old); - - /* Hack - force redraw XXX ??? XXX */ - Term_key_push(KTRL('R')); -} - -# endif /* USE_DOUBLE_TILES */ - - -/* - * Toggles the boolean value of use_transparency - */ -static void change_trans_mode_event_handler( - gpointer user_data, - guint user_aciton, - GtkWidget *was_clicked) -{ - /* Toggle the transparency mode */ - use_transparency = !use_transparency; - - /* Hack - force redraw */ - Term_key_push(KTRL('R')); -} - -#endif /* USE_GRAPHICS */ - - -#ifndef SAVEFILE_SCREEN - -/* - * Caution: Modal or not, callbacks are called by gtk_main(), - * so this is the right place to start a game. - */ -static void file_ok_callback( - GtkWidget *widget, - GtkWidget *file_selector) -{ - strcpy(savefile, - gtk_file_selection_get_filename(GTK_FILE_SELECTION(file_selector))); - - gtk_widget_destroy(file_selector); - - /* game is in progress */ - game_in_progress = TRUE; - - /* Flush input */ - Term_flush(); - - /* Play game */ - play_game(FALSE); - - /* Free memory allocated by game */ - cleanup_angband(); - - /* Done */ - quit(NULL); -} - - -/* - * Process File-Open menu command - */ -static void open_event_handler( - gpointer user_data, - guint user_action, - GtkWidget *was_clicked) -{ - GtkWidget *file_selector; - char buf[1024]; - - - if (game_in_progress) - { - plog("You can't open a new game while you're still playing!"); - return; - } - - /* Prepare the savefile path */ - path_build(buf, 1024, ANGBAND_DIR_SAVE, "*"); - - file_selector = gtk_file_selection_new("Select a savefile"); - gtk_file_selection_set_filename( - GTK_FILE_SELECTION(file_selector), - buf); - gtk_signal_connect( - GTK_OBJECT(GTK_FILE_SELECTION(file_selector)->ok_button), - "clicked", - file_ok_callback, - (gpointer)file_selector); - - /* - * Ensure that the dialog box is destroyed when the user - * clicks a button. - */ - gtk_signal_connect_object( - GTK_OBJECT(GTK_FILE_SELECTION(file_selector)->ok_button), - "clicked", - GTK_SIGNAL_FUNC(gtk_widget_destroy), - (gpointer)file_selector); - - gtk_signal_connect_object( - GTK_OBJECT(GTK_FILE_SELECTION(file_selector)->cancel_button), - "clicked", - GTK_SIGNAL_FUNC(gtk_widget_destroy), - (gpointer)file_selector); - - gtk_window_set_modal(GTK_WINDOW(file_selector), TRUE); - gtk_widget_show(GTK_WIDGET(file_selector)); -} - -#endif /* !SAVEFILE_SCREEN */ /* @@ -3586,7 +905,6 @@ static gboolean keypress_event_handler( GdkEventKey *event, gpointer user_data) { -#if 1 int i, mc, ms, mo, mx; char msg[128]; @@ -3703,123 +1021,6 @@ static gboolean keypress_event_handler( } return (TRUE); - -#else - int i, mc, ms, mo, mx; - - char msg[128]; - - - /* Extract four "modifier flags" */ - mc = (event->state & GDK_CONTROL_MASK) ? TRUE : FALSE; - ms = (event->state & GDK_SHIFT_MASK) ? TRUE : FALSE; - mo = (event->state & GDK_MOD1_MASK) ? TRUE : FALSE; - mx = (event->state & GDK_MOD3_MASK) ? TRUE : FALSE; - printf("0=%d 9=%d;; keyval=%d; mc=%d, ms=%d ::=:: ", GDK_KP_0, GDK_KP_9, event->keyval, mc, ms); - /* Enqueue the normal key(s) */ - for (i = 0; i < event->length; i++) printf("%d;", event->string[i]); - printf("\n"); - - /* - * Hack XXX - * Parse shifted numeric (keypad) keys specially. - */ - if ((event->state & GDK_SHIFT_MASK) - && (event->keyval >= GDK_KP_Left) && (event->keyval <= GDK_KP_Delete)) - { - /* Build the macro trigger string */ - strnfmt(msg, 128, "%cS_%X%c", 31, event->keyval, 13); - printf("%cS_%X%c", 31, event->keyval, 13); - - /* Enqueue the "macro trigger" string */ - for (i = 0; msg[i]; i++) Term_keypress(msg[i]); - - /* Hack -- auto-define macros as needed */ - if (event->length && (macro_find_exact(msg) < 0)) - { - /* Create a macro */ - macro_add(msg, event->string); - } - - return (TRUE); - } - - /* Normal keys with no modifiers */ - if (event->length && !mo && !mx) - { - /* Enqueue the normal key(s) */ - for (i = 0; i < event->length; i++) Term_keypress(event->string[i]); - - /* All done */ - return (TRUE); - } - - /* Handle a few standard keys (bypass modifiers) XXX XXX XXX */ - switch ((uint) event->keyval) - { - case GDK_Escape: - { - Term_keypress(ESCAPE); - return (TRUE); - } - - case GDK_Return: - { - Term_keypress('\r'); - return (TRUE); - } - - case GDK_Tab: - { - Term_keypress('\t'); - return (TRUE); - } - - case GDK_Delete: - case GDK_BackSpace: - { - Term_keypress('\010'); - return (TRUE); - } - - case GDK_Shift_L: - case GDK_Shift_R: - case GDK_Control_L: - case GDK_Control_R: - case GDK_Caps_Lock: - case GDK_Shift_Lock: - case GDK_Meta_L: - case GDK_Meta_R: - case GDK_Alt_L: - case GDK_Alt_R: - case GDK_Super_L: - case GDK_Super_R: - case GDK_Hyper_L: - case GDK_Hyper_R: - { - /* Hack - do nothing to control characters */ - return (TRUE); - } - } - - /* Build the macro trigger string */ - strnfmt(msg, 128, "%c%s%s%s%s_%X%c", 31, - mc ? "N" : "", ms ? "S" : "", - mo ? "O" : "", mx ? "M" : "", - event->keyval, 13); - - /* Enqueue the "macro trigger" string */ - for (i = 0; msg[i]; i++) Term_keypress(msg[i]); - - /* Hack -- auto-define macros as needed */ - if (event->length && (macro_find_exact(msg) < 0)) - { - /* Create a macro */ - macro_add(msg, event->string); - } - - return (TRUE); -#endif } @@ -4061,7 +1262,8 @@ static errr term_data_init(term_data *td, int i) term_init(t, td->cols, td->rows, 1024); /* Store the name of the term */ - td->name = string_make(angband_term_name[i]); + assert(angband_term_name[i] != NULL); + td->name = strdup(angband_term_name[i]); /* Instance names should start with a lowercase letter XXX */ for (p = (char *)td->name; *p; p++) *p = tolower(*p); @@ -4069,17 +1271,10 @@ static errr term_data_init(term_data *td, int i) /* Use a "soft" cursor */ t->soft_cursor = TRUE; - /* Erase with "white space" */ - t->attr_blank = TERM_WHITE; - t->char_blank = ' '; - + /* Hooks */ t->xtra_hook = Term_xtra_gtk; t->text_hook = Term_text_gtk; - t->wipe_hook = Term_wipe_gtk; t->curs_hook = Term_curs_gtk; -#ifdef USE_GRAPHICS - t->pict_hook = Term_pict_gtk; -#endif /* USE_GRAPHICS */ t->nuke_hook = Term_nuke_gtk; /* Save the data */ @@ -4112,14 +1307,6 @@ static GtkItemFactoryEntry main_menu_items[] = { "/File", NULL, NULL, 0, "<Branch>", NULL }, -#ifndef SAVEFILE_SCREEN - { "/File/New", "<mod1>N", - new_event_handler, 0, NULL, NULL }, - { "/File/Open", "<mod1>O", - open_event_handler, 0, NULL, NULL }, - { "/File/sep1", NULL, - NULL, 0, "<Separator>", NULL }, -#endif /* !SAVEFILE_SCREEN */ { "/File/Save", "<mod1>S", save_event_handler, 0, NULL, NULL }, { "/File/Quit", "<mod1>Q", @@ -4171,37 +1358,6 @@ static GtkItemFactoryEntry main_menu_items[] = { NULL, NULL, change_font_event_handler, 7, NULL, NULL }, -#ifdef USE_GRAPHICS - - /* "Graphics" submenu */ - { "/Options/Graphics", NULL, - NULL, 0, "<Branch>", NULL }, - { "/Options/Graphics/None", NULL, - change_graf_mode_event_handler, GRAF_MODE_NONE, "<CheckItem>", NULL }, - { "/Options/Graphics/Old", NULL, - change_graf_mode_event_handler, GRAF_MODE_OLD, "<CheckItem>", NULL }, - { "/Options/Graphics/New", NULL, - change_graf_mode_event_handler, GRAF_MODE_NEW, "<CheckItem>", NULL }, -# ifdef USE_DOUBLE_TILES - { "/Options/Graphics/sep3", NULL, - NULL, 0, "<Separator>", NULL }, - { "/Options/Graphics/Wide tiles", NULL, - change_wide_tile_mode_event_handler, 0, "<CheckItem>", NULL }, -# endif /* USE_DOUBLE_TILES */ - { "/Options/Graphics/sep1", NULL, - NULL, 0, "<Separator>", NULL }, - { "/Options/Graphics/Dither if <= 8bpp", NULL, - change_dith_mode_event_handler, GDK_RGB_DITHER_NORMAL, "<CheckItem>", NULL }, - { "/Options/Graphics/Dither if <= 16bpp", NULL, - change_dith_mode_event_handler, GDK_RGB_DITHER_MAX, "<CheckItem>", NULL }, - { "/Options/Graphics/sep2", NULL, - NULL, 0, "<Separator>", NULL }, - { "/Options/Graphics/Smoothing", NULL, - change_smooth_mode_event_handler, 0, "<CheckItem>", NULL }, - { "/Options/Graphics/Transparency", NULL, - change_trans_mode_event_handler, 0, "<CheckItem>", NULL }, - -#endif /* USE_GRAPHICS */ /* "Misc" submenu */ { "/Options/Misc", NULL, @@ -4257,13 +1413,13 @@ static void setup_menu_paths(void) strnfmt(buf, 64, "/Terms/%s", angband_term_name[i]); /* XXX XXX Store it in the menu definition */ - term_entry[i].path = (gchar*)string_make(buf); + term_entry[i].path = (gchar*) strdup(buf); /* XXX XXX Build the real path name to the entry */ strnfmt(buf, 64, "/Options/Font/%s", angband_term_name[i]); /* XXX XXX Store it in the menu definition */ - font_entry[i].path = (gchar*)string_make(buf); + font_entry[i].path = (gchar*) strdup(buf); } } @@ -4309,10 +1465,10 @@ static void free_menu_paths(void) for (i = 0; i < MAX_TERM_DATA; i++) { /* XXX XXX Free Term menu path */ - if (term_entry[i].path) string_free((cptr)term_entry[i].path); + if (term_entry[i].path) free(term_entry[i].path); /* XXX XXX Free Font menu path */ - if (font_entry[i].path) string_free((cptr)font_entry[i].path); + if (font_entry[i].path) free(font_entry[i].path); } } @@ -4399,18 +1555,8 @@ static void file_menu_update_handler( GtkWidget *widget, gpointer user_data) { -#ifndef SAVEFILE_SCREEN - bool_ game_start_ok; -#endif /* !SAVEFILE_SCREEN */ bool_ save_ok, quit_ok; -#ifndef SAVEFILE_SCREEN - - /* Can we start a game now? */ - game_start_ok = !game_in_progress; - -#endif /* !SAVEFILE_SCREEN */ - /* Cave we save/quit now? */ if (!character_generated || !game_in_progress) { @@ -4424,10 +1570,6 @@ static void file_menu_update_handler( } /* Enable / disable menu items according to those conditions */ -#ifndef SAVEFILE_SCREEN - enable_menu_item("<Angband>/File/New", game_start_ok); - enable_menu_item("<Angband>/File/Open", game_start_ok); -#endif /* !SAVEFILE_SCREEN */ enable_menu_item("<Angband>/File/Save", save_ok); enable_menu_item("<Angband>/File/Quit", quit_ok); } @@ -4491,51 +1633,6 @@ static void misc_menu_update_handler( } -#ifdef USE_GRAPHICS - -/* - * Update the "Graphics" submenu - */ -static void graf_menu_update_handler( - GtkWidget *widget, - gpointer user_data) -{ - /* Update menu items */ - check_menu_item( - "<Angband>/Options/Graphics/None", - (graf_mode == GRAF_MODE_NONE)); - check_menu_item( - "<Angband>/Options/Graphics/Old", - (graf_mode == GRAF_MODE_OLD)); - check_menu_item( - "<Angband>/Options/Graphics/New", - (graf_mode == GRAF_MODE_NEW)); - -#ifdef USE_DOUBLE_TILES - - check_menu_item( - "<Angband>/Options/Graphics/Wide tiles", - use_bigtile); - -#endif /* USE_DOUBLE_TILES */ - - check_menu_item( - "<Angband>/Options/Graphics/Dither if <= 8bpp", - (dith_mode == GDK_RGB_DITHER_NORMAL)); - check_menu_item( - "<Angband>/Options/Graphics/Dither if <= 16bpp", - (dith_mode == GDK_RGB_DITHER_MAX)); - - check_menu_item( - "<Angband>/Options/Graphics/Smoothing", - smooth_rescaling); - - check_menu_item( - "<Angband>/Options/Graphics/Transparency", - use_transparency); -} - -#endif /* USE_GRAPHICS */ /* @@ -4644,23 +1741,6 @@ static void add_menu_update_callbacks() GTK_SIGNAL_FUNC(misc_menu_update_handler), NULL); -#ifdef USE_GRAPHICS - - /* Access Graphics menu */ - widget = get_widget_from_path("<Angband>/Options/Graphics"); - - /* Paranoia */ - g_assert(widget != NULL); - g_assert(GTK_IS_MENU(widget)); - - /* Assign callback */ - gtk_signal_connect( - GTK_OBJECT(widget), - "show", - GTK_SIGNAL_FUNC(graf_menu_update_handler), - NULL); - -#endif /* USE_GRAPHICS */ } @@ -4808,38 +1888,12 @@ static void hook_quit(cptr str) /* Free menu paths dynamically allocated */ free_menu_paths(); -# ifdef USE_GRAPHICS - - /* Free pathname string */ - if (ANGBAND_DIR_XTRA_GRAF) string_free(ANGBAND_DIR_XTRA_GRAF); - -# endif /* USE_GRAPHICS */ /* Terminate the program */ gtk_exit(0); } -#ifdef ANGBAND300 - -/* - * Help message for this port - */ -const char help_gtk[] = - "GTK for X11, subopts -n<windows>\n" - " -b(acking store off)\n" -#ifdef USE_GRAPHICS - " -g(raphics) -o(ld graphics) -s(moothscaling off) \n" - " -t(ransparency on)\n" -# ifdef USE_DOUBLE_TILES - " -w(ide tiles)\n" -# endif /* USE_DOUBLE_TILES */ -#endif /* USE_GRAPHICS */ - " and standard GTK options"; - -#endif /* ANGBAND300 */ - - /* * Initialization function */ @@ -4852,10 +1906,7 @@ errr init_gtk2(int argc, char **argv) gtk_init(&argc, &argv); /* Activate hooks - Use gtk/glib interface throughout */ - ralloc_aux = hook_ralloc; - rnfree_aux = hook_rnfree; quit_aux = hook_quit; - core_aux = hook_quit; /* Parse args */ for (i = 1; i < argc; i++) @@ -4876,71 +1927,11 @@ errr init_gtk2(int argc, char **argv) continue; } -#ifdef USE_GRAPHICS - - /* Requests "old" graphics */ - if (streq(argv[i], "-o")) - { - graf_mode_request = GRAF_MODE_OLD; - continue; - } - - /* Requests "new" graphics */ - if (streq(argv[i], "-g")) - { - graf_mode_request = GRAF_MODE_NEW; - continue; - } - -# ifdef USE_DOUBLE_TILES - - /* Requests wide tile mode */ - if (streq(argv[i], "-w")) - { - use_bigtile = TRUE; -# ifdef TOME - /* T.o.M.E. uses older version of the patch */ - arg_bigtile = TRUE; -# endif /* TOME */ - continue; - } - -# endif /* USE_DOUBLE_TILES */ - - - /* Enable transparency effect */ - if (streq(argv[i], "-t")) - { - use_transparency = TRUE; - continue; - } - - /* Disable smooth rescaling of tiles */ - if (streq(argv[i], "-s")) - { - smooth_rescaling_request = FALSE; - continue; - } - -#endif /* USE_GRAPHICS */ /* None of the above */ - plog_fmt("Ignoring option: %s", argv[i]); + fprintf(stderr, "Ignoring option: %s", argv[i]); } -#ifdef USE_GRAPHICS - - { - char path[1024]; - - /* Build the "graf" path */ - path_build(path, 1024, ANGBAND_DIR_XTRA, "graf"); - - /* Allocate the path */ - ANGBAND_DIR_XTRA_GRAF = string_make(path); - } - -#endif /* USE_GRAPHICS */ /* Initialise colours */ gdk_rgb_init(); @@ -4973,52 +1964,12 @@ errr init_gtk2(int argc, char **argv) /* Activate the "Angband" window screen */ Term_activate(&data[0].t); -#ifndef SAVEFILE_SCREEN - - /* Set the system suffix */ - ANGBAND_SYS = "gtk"; - - /* Catch nasty signals */ - signals_init(); - - /* Initialize */ - init_angband(); - -#ifndef OLD_SAVEFILE_CODE - - /* Hack - because this port has New/Open menus XXX */ - savefile[0] = '\0'; - -#endif /* !OLD_SAVEFILE_CODE */ - - /* Prompt the user */ - prt("[Choose 'New' or 'Open' from the 'File' menu]", 23, 17); - Term_fresh(); - - /* Activate more hook */ - plog_aux = hook_plog; - - - /* Processing loop */ - gtk_main(); - - - /* Free allocated memory */ - cleanup_angband(); - - /* Stop now */ - quit(NULL); - -#else /* !SAVEFILE_SCREEN */ - /* Activate more hook */ plog_aux = hook_plog; /* It's too early to set this, but cannot do so elsewhere XXX XXX */ game_in_progress = TRUE; -#endif /* !SAVEFILE_SCREEN */ - /* Success */ return (0); } |