From d4ace0bf36e361874f881e64f7db4e3e132da699 Mon Sep 17 00:00:00 2001 From: Nick Bowler Date: Sun, 7 Feb 2010 20:19:31 -0500 Subject: [PATCH 01/16] liblbx: Set the file offset in lbx_file_seek. This function previously would do the underlying seek correctly, but not actually record what it did. This breaks lots of things, fix it. --- src/lbx.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/lbx.c b/src/lbx.c index 17bf976..c2db146 100644 --- a/src/lbx.c +++ b/src/lbx.c @@ -293,6 +293,8 @@ int lbx_file_seek(struct lbx_file_state *f, long offset, int whence) f->lbx->last_file = NULL; if (fops->seek(f->lbx->f, f->base + pos, SEEK_SET) != 0) return -1; + + f->offset = pos; f->lbx->last_file = f; f->eof = 0; -- 2.43.2 From bd821672161db0f2be855b75e1f11a332478b8ba Mon Sep 17 00:00:00 2001 From: Nick Bowler Date: Sun, 7 Feb 2010 20:20:48 -0500 Subject: [PATCH 02/16] lbxgui: Allow frame to be specified. --- src/gui/lbxgui.c | 77 ++++++++++++++++++++++++++++---------------- src/gui/lbxgui.glade | 54 +++++++++++++++++++++++++++++-- 2 files changed, 101 insertions(+), 30 deletions(-) diff --git a/src/gui/lbxgui.c b/src/gui/lbxgui.c index 2d60e6e..f943be3 100644 --- a/src/gui/lbxgui.c +++ b/src/gui/lbxgui.c @@ -19,20 +19,7 @@ static struct lbx_colour palette_override[256]; GdkPixbuf *framebuf; -gboolean canvas_expose(GtkWidget *canvas, GdkEventExpose *event, gpointer data) -{ - if (!framebuf) - return TRUE; - - gdk_draw_pixbuf(canvas->window, NULL, framebuf, - event->area.x, event->area.y, event->area.x, event->area.y, - event->area.width, event->area.height, - GDK_RGB_DITHER_NORMAL, 0, 0); - - return TRUE; -} - -void get_colour(unsigned char index, unsigned char out[static 3]) +static void get_colour(unsigned char index, unsigned char out[static 3]) { struct lbx_colour *colour; @@ -50,30 +37,23 @@ void get_colour(unsigned char index, unsigned char out[static 3]) out[2] = colour->blue; } -static int init_framedata(void) +static int render_frame(LBX_IMG *img, GdkPixbuf *buf, unsigned frame) { - struct lbx_imginfo info; unsigned char **imgdata, **imgmask; + struct lbx_imginfo info; unsigned char *data; unsigned stride; lbximg_getinfo(image, &info); - imgdata = lbximg_getframe(image, 0); + imgdata = lbximg_getframe(image, frame); if (!imgdata) { - printf("failed to decode frame 0\n"); + printf("failed to decode frame %u\n", frame); return -1; } imgmask = lbximg_getmask(image); - framebuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, 8, - info.width, info.height); - if (!framebuf) { - printf("failed to allocate pixbuf\n"); - return -1; - } - - data = gdk_pixbuf_get_pixels(framebuf); - stride = gdk_pixbuf_get_rowstride(framebuf); + data = gdk_pixbuf_get_pixels(buf); + stride = gdk_pixbuf_get_rowstride(buf); for (unsigned i = 0; i < info.height; i++) { unsigned char (*p)[3] = (void *)(data + i*stride); @@ -89,8 +69,49 @@ static int init_framedata(void) } } - gtk_widget_set_size_request(canvas, info.width, info.height); + return 0; +} + +void set_frame(GtkSpinButton *spin, gpointer data) +{ + unsigned frame = gtk_spin_button_get_value_as_int(spin); + + render_frame(image, framebuf, frame); gdk_window_invalidate_rect(canvas->window, NULL, FALSE); +} + +gboolean canvas_expose(GtkWidget *canvas, GdkEventExpose *event, gpointer data) +{ + if (!framebuf) + return TRUE; + + gdk_draw_pixbuf(canvas->window, NULL, framebuf, + event->area.x, event->area.y, event->area.x, event->area.y, + event->area.width, event->area.height, + GDK_RGB_DITHER_NORMAL, 0, 0); + + return TRUE; +} + +static int init_framedata(void) +{ + struct lbx_imginfo info; + GtkSpinButton *spin; + + lbximg_getinfo(image, &info); + framebuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, 8, + info.width, info.height); + if (!framebuf) { + printf("failed to allocate pixbuf\n"); + return -1; + } + + gtk_widget_set_size_request(canvas, info.width, info.height); + + spin = GTK_SPIN_BUTTON(gtk_builder_get_object(builder, "framespin")); + gtk_spin_button_set_range(spin, 0, info.nframes-1); + gtk_spin_button_set_value(spin, 0); + set_frame(spin, NULL); return 0; } diff --git a/src/gui/lbxgui.glade b/src/gui/lbxgui.glade index 1896267..fb12bce 100644 --- a/src/gui/lbxgui.glade +++ b/src/gui/lbxgui.glade @@ -102,9 +102,55 @@ True vertical - + True - + + + True + 1 + 3 + Image: + + + False + 0 + + + + + True + + + + False + 3 + 1 + + + + + True + 1 + 3 + Frame: + + + 2 + + + + + True + True + + adjustment1 + + + + False + 3 + + False @@ -141,4 +187,8 @@ + + 1 + 10 + -- 2.43.2 From 2edc8f09257b4bbf13ac64ba2ead16359e93de8b Mon Sep 17 00:00:00 2001 From: Nick Bowler Date: Sun, 7 Feb 2010 21:24:32 -0500 Subject: [PATCH 03/16] lbxgui: Add support for animating images. --- src/gui/lbxgui.c | 80 +++++++++++++++++++++++++++++++++++++++++++- src/gui/lbxgui.glade | 19 +++++++++++ 2 files changed, 98 insertions(+), 1 deletion(-) diff --git a/src/gui/lbxgui.c b/src/gui/lbxgui.c index f943be3..0592a7e 100644 --- a/src/gui/lbxgui.c +++ b/src/gui/lbxgui.c @@ -1,6 +1,8 @@ #include #include #include +#include + #include #include "lbx.h" @@ -11,7 +13,6 @@ static GtkBuilder *builder; static GtkWidget *canvas; static LBX_IMG *image; - /* LBX images can have up to three palettes, with each superseding the last. */ static struct lbx_colour palette_external[256]; static struct lbx_colour palette_internal[256]; @@ -19,6 +20,24 @@ static struct lbx_colour palette_override[256]; GdkPixbuf *framebuf; +void play_toggled(GtkToggleButton *button, gpointer data) +{ + gboolean active = gtk_toggle_button_get_active(button); + GtkWidget *spin; + + if (active && !image) { + gtk_toggle_button_set_active(button, FALSE); + return; + } + + spin = GTK_WIDGET(gtk_builder_get_object(builder, "framespin")); + gtk_widget_set_sensitive(spin, !active); + + if (active) { + gtk_spin_button_set_value(GTK_SPIN_BUTTON(spin), 0); + } +} + static void get_colour(unsigned char index, unsigned char out[static 3]) { struct lbx_colour *colour; @@ -80,6 +99,63 @@ void set_frame(GtkSpinButton *spin, gpointer data) gdk_window_invalidate_rect(canvas->window, NULL, FALSE); } +static void tick(void *p, double delta) +{ + static double elapsed = 0; + double seconds_per_frame = 1.0/15; + struct lbx_imginfo info; + GtkSpinButton *spin; + GtkToggleButton *play; + unsigned frame; + + if (!image) + return; + + lbximg_getinfo(image, &info); + spin = GTK_SPIN_BUTTON(gtk_builder_get_object(builder, "framespin")); + play = GTK_TOGGLE_BUTTON(gtk_builder_get_object(builder, "playbutton")); + + frame = gtk_spin_button_get_value_as_int(spin); + if (!gtk_toggle_button_get_active(play)) + return; + + elapsed += delta; + while (elapsed > seconds_per_frame) { + elapsed -= seconds_per_frame; + + if (++frame >= info.nframes) { + if (!info.looping) { + gtk_toggle_button_set_active(play, FALSE); + break; + } + + frame = info.loopstart; + } + + gtk_spin_button_set_value(spin, frame); + } +} + +static gboolean timeout(gpointer data) +{ + static double lasttime = INFINITY; + static GTimer *timer; + + if (isinf(lasttime)) { + timer = g_timer_new(); + if (timer) { + lasttime = 0; + } + } else { + double time = g_timer_elapsed(timer, NULL); + + tick(data, time - lasttime); + lasttime = time; + } + + return TRUE; +} + gboolean canvas_expose(GtkWidget *canvas, GdkEventExpose *event, gpointer data) { if (!framebuf) @@ -310,6 +386,8 @@ int main(int argc, char **argv) interface_init(); gtk_builder_connect_signals(builder, window); + + g_timeout_add(33, timeout, NULL); gtk_widget_show_all(window); gtk_main(); } diff --git a/src/gui/lbxgui.glade b/src/gui/lbxgui.glade index fb12bce..510098b 100644 --- a/src/gui/lbxgui.glade +++ b/src/gui/lbxgui.glade @@ -151,6 +151,25 @@ 3 + + + True + True + True + + + + True + gtk-media-play + + + + + False + 3 + 4 + + False -- 2.43.2 From beecbda1887c5838c497bcb9fc166d527c3e2660 Mon Sep 17 00:00:00 2001 From: Nick Bowler Date: Sun, 7 Feb 2010 21:29:05 -0500 Subject: [PATCH 04/16] lbxgui: Recognise *.LBX as an LBX archive. The files on the Moo2 CD show up in ALL CAPITALS, so it's useful to match them with the file filter. --- src/gui/lbxgui.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/gui/lbxgui.c b/src/gui/lbxgui.c index 0592a7e..33dfdd8 100644 --- a/src/gui/lbxgui.c +++ b/src/gui/lbxgui.c @@ -316,6 +316,7 @@ void open_archive(GtkWidget *widget) lbxfilter = gtk_file_filter_new(); gtk_file_filter_set_name(lbxfilter, "LBX Archives (*.lbx)"); gtk_file_filter_add_pattern(lbxfilter, "*.lbx"); + gtk_file_filter_add_pattern(lbxfilter, "*.LBX"); allfilter = gtk_file_filter_new(); gtk_file_filter_set_name(allfilter, "All Files"); -- 2.43.2 From d1728478ec0a212e2c601cfa911e24ee1018c83d Mon Sep 17 00:00:00 2001 From: Nick Bowler Date: Sun, 7 Feb 2010 21:44:31 -0500 Subject: [PATCH 05/16] liblbx: Use lbx_file_ops for lbximg_loadpalette. --- src/image.c | 8 +++++--- src/image.h | 3 ++- src/lbximg.c | 2 +- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/image.c b/src/image.c index c8a7165..83bac21 100644 --- a/src/image.c +++ b/src/image.c @@ -324,13 +324,15 @@ unsigned char **lbximg_getframe(struct lbx_image *img, int frame) return img->framedata; } -int lbximg_loadpalette(FILE *f, struct lbx_colour palette[static 256]) +int +lbximg_loadpalette(void *f, const struct lbx_file_ops *fops, + struct lbx_colour palette[static 256]) { unsigned char entry[4]; int i; for (i = 0; i < 256; i++) { - if (fread(entry, sizeof entry, 1, f) != 1) { + if (fops->read(entry, sizeof entry, f) != sizeof entry) { lbx_errno = (feof(f)) ? LBX_EEOF : -errno; return -1; } @@ -340,7 +342,7 @@ int lbximg_loadpalette(FILE *f, struct lbx_colour palette[static 256]) return -1; } - palette[i] = (struct lbx_colour){ + palette[i] = (struct lbx_colour) { .red = entry[1] << 2, .green = entry[2] << 2, .blue = entry[3] << 2, diff --git a/src/image.h b/src/image.h index e12372b..2f427d1 100644 --- a/src/image.h +++ b/src/image.h @@ -28,7 +28,8 @@ int lbximg_close(LBX_IMG *img); unsigned char **lbximg_getframe(LBX_IMG *img, int frame); unsigned char **lbximg_getmask(LBX_IMG *img); -int lbximg_loadpalette(FILE *f, struct lbx_colour palette[static 256]); +int lbximg_loadpalette(void *f, const struct lbx_file_ops *fops, + struct lbx_colour palette[static 256]); int lbximg_getpalette(LBX_IMG *img, struct lbx_colour palette[static 256]); void lbximg_getinfo(LBX_IMG *img, struct lbx_imginfo *info); diff --git a/src/lbximg.c b/src/lbximg.c index 1cf765d..67d8635 100644 --- a/src/lbximg.c +++ b/src/lbximg.c @@ -288,7 +288,7 @@ static int loadpalette(LBX_IMG *img, struct lbx_imginfo *info, } /* Read the external palette, if any. */ - if (palf && lbximg_loadpalette(palf, palette) == -1) { + if (palf && lbximg_loadpalette(palf, &lbx_default_fops, palette) != 0) { errmsg("error reading external palette: %s\n", lbx_strerror()); return -1; } -- 2.43.2 From 039d6c1bce02ff7c7aba3bb5ad4dc05cf67b969f Mon Sep 17 00:00:00 2001 From: Nick Bowler Date: Sun, 7 Feb 2010 22:14:39 -0500 Subject: [PATCH 06/16] lbxgui: Add support for external palettes. --- src/gui/lbxgui.c | 35 ++++++++++++++++++++++++++++++++--- src/gui/lbxgui.glade | 44 ++++++++++++++++++++++++++++++++++++-------- 2 files changed, 68 insertions(+), 11 deletions(-) diff --git a/src/gui/lbxgui.c b/src/gui/lbxgui.c index 33dfdd8..650f263 100644 --- a/src/gui/lbxgui.c +++ b/src/gui/lbxgui.c @@ -169,7 +169,7 @@ gboolean canvas_expose(GtkWidget *canvas, GdkEventExpose *event, gpointer data) return TRUE; } -static int init_framedata(void) +static int init_framedata(int reset) { struct lbx_imginfo info; GtkSpinButton *spin; @@ -197,6 +197,31 @@ static int img_close(void *handle) return 0; } +void set_palette_data(GtkComboBox *combo) +{ + GtkTreeIter iter; + gpointer lbx; + guint index; + LBXfile *f; + + if (!gtk_combo_box_get_active_iter(combo, &iter)) + return; + + gtk_tree_model_get(GTK_TREE_MODEL(archives), &iter, + 1, &lbx, + 2, &index, + -1); + + f = lbx_file_open(lbx, index); + if (f) { + if (lbximg_loadpalette(f, &lbx_arch_fops, palette_external)) + memset(palette_external, 0, sizeof palette_external); + lbx_file_close(f); + } + + init_framedata(0); +} + void set_image_data(GtkComboBox *combo) { GtkTreeIter iter; @@ -224,7 +249,7 @@ void set_image_data(GtkComboBox *combo) lbximg_close(image); } - if (init_framedata() == -1) { + if (init_framedata(1) == -1) { puts("crap"); lbximg_close(image); } @@ -356,6 +381,10 @@ static void interface_init(void) gtk_tree_view_set_model(tree, GTK_TREE_MODEL(archives)); gtk_tree_view_append_column(tree, column); + combo = GTK_COMBO_BOX(gtk_builder_get_object(builder, "palettechooser")); + gtk_combo_box_set_model(combo, GTK_TREE_MODEL(archives)); + gtk_combo_box_entry_set_text_column(GTK_COMBO_BOX_ENTRY(combo), 0); + combo = GTK_COMBO_BOX(gtk_builder_get_object(builder, "imagechooser")); gtk_combo_box_set_model(combo, GTK_TREE_MODEL(archives)); gtk_combo_box_entry_set_text_column(GTK_COMBO_BOX_ENTRY(combo), 0); @@ -388,7 +417,7 @@ int main(int argc, char **argv) interface_init(); gtk_builder_connect_signals(builder, window); - g_timeout_add(33, timeout, NULL); + g_timeout_add(10, timeout, NULL); gtk_widget_show_all(window); gtk_main(); } diff --git a/src/gui/lbxgui.glade b/src/gui/lbxgui.glade index 510098b..53e5ce2 100644 --- a/src/gui/lbxgui.glade +++ b/src/gui/lbxgui.glade @@ -104,6 +104,27 @@ True + + + True + 1 + 4 + Palette: + + + 0 + + + + + True + + + + False + 1 + + True @@ -113,7 +134,7 @@ False - 0 + 2 @@ -124,7 +145,7 @@ False 3 - 1 + 3 @@ -135,7 +156,7 @@ Frame: - 2 + 4 @@ -148,7 +169,7 @@ False - 3 + 5 @@ -167,12 +188,13 @@ False 3 - 4 + 6 False + 3 0 @@ -180,11 +202,17 @@ True queue - etched-in - + True - + 0 + 0 + + + True + + + -- 2.43.2 From c6bde872a51bea0beb105d5b9fde0f4aad36ca1d Mon Sep 17 00:00:00 2001 From: Nick Bowler Date: Sun, 7 Feb 2010 22:32:07 -0500 Subject: [PATCH 07/16] lbxgui: Add support for override palettes. --- src/gui/lbxgui.c | 41 +++++++++++++++++++++++++++++++++++++++-- src/gui/lbxgui.glade | 26 +++++++++++++++++++++++--- 2 files changed, 62 insertions(+), 5 deletions(-) diff --git a/src/gui/lbxgui.c b/src/gui/lbxgui.c index 650f263..21dee9a 100644 --- a/src/gui/lbxgui.c +++ b/src/gui/lbxgui.c @@ -174,6 +174,9 @@ static int init_framedata(int reset) struct lbx_imginfo info; GtkSpinButton *spin; + if (!image) + return 0; + lbximg_getinfo(image, &info); framebuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, 8, info.width, info.height); @@ -197,6 +200,38 @@ static int img_close(void *handle) return 0; } +void set_override_data(GtkComboBox *combo) +{ + GtkTreeIter iter; + gpointer lbx; + guint index; + LBXfile *f; + LBX_IMG *img; + + if (!gtk_combo_box_get_active_iter(combo, &iter)) + return; + + gtk_tree_model_get(GTK_TREE_MODEL(archives), &iter, + 1, &lbx, + 2, &index, + -1); + + f = lbx_file_open(lbx, index); + if (f) { + img = lbximg_open(f, &lbx_arch_fops, NULL); + if (img) { + memset(palette_override, 0, sizeof palette_override); + lbximg_getpalette(img, palette_override); + lbximg_close(img); + init_framedata(0); + } + + lbx_file_close(f); + } else { + puts("damn"); + } +} + void set_palette_data(GtkComboBox *combo) { GtkTreeIter iter; @@ -239,8 +274,6 @@ void set_image_data(GtkComboBox *combo) f = lbx_file_open(lbx, index); if (f) { - struct lbx_imginfo info; - image = lbximg_open(f, &lbx_arch_fops, img_close); if (image) { memset(palette_internal, 0, sizeof palette_internal); @@ -388,6 +421,10 @@ static void interface_init(void) combo = GTK_COMBO_BOX(gtk_builder_get_object(builder, "imagechooser")); gtk_combo_box_set_model(combo, GTK_TREE_MODEL(archives)); gtk_combo_box_entry_set_text_column(GTK_COMBO_BOX_ENTRY(combo), 0); + + combo = GTK_COMBO_BOX(gtk_builder_get_object(builder, "overchooser")); + gtk_combo_box_set_model(combo, GTK_TREE_MODEL(archives)); + gtk_combo_box_entry_set_text_column(GTK_COMBO_BOX_ENTRY(combo), 0); } int main(int argc, char **argv) diff --git a/src/gui/lbxgui.glade b/src/gui/lbxgui.glade index 53e5ce2..8b44249 100644 --- a/src/gui/lbxgui.glade +++ b/src/gui/lbxgui.glade @@ -148,6 +148,26 @@ 3 + + + True + 1 + 3 + Override: + + + 4 + + + + + True + + + + 5 + + True @@ -156,7 +176,7 @@ Frame: - 4 + 6 @@ -169,7 +189,7 @@ False - 5 + 7 @@ -188,7 +208,7 @@ False 3 - 6 + 8 -- 2.43.2 From 9311c2e7ce657110da33c9bc5ebc529b320484b9 Mon Sep 17 00:00:00 2001 From: Nick Bowler Date: Sun, 7 Feb 2010 23:24:06 -0500 Subject: [PATCH 08/16] liblbx: Add new flag. Building images have a previously-unknown flag, 0x0800. The images have a part that looks like a shadow, but it does not have any palette entry. I suspect that this flag is related to that shadow. --- src/image.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/image.c b/src/image.c index 83bac21..9ad154a 100644 --- a/src/image.c +++ b/src/image.c @@ -31,9 +31,11 @@ #include "image.h" #define FLAG_OVERWRITE 0x0400 /* Draw each frame on a clean slate (unsure). */ +#define FLAG_BUILDING 0x0800 /* Buildings have this, related to shadow? */ #define FLAG_PALETTE 0x1000 /* Image contains embedded palette. */ #define FLAG_LOOPING 0x2000 /* Loop over all frames in the image (unsure). */ -#define FLAG_ALL (FLAG_OVERWRITE|FLAG_PALETTE|FLAG_LOOPING) + +#define FLAG_ALL (FLAG_OVERWRITE|FLAG_BUILDING|FLAG_PALETTE|FLAG_LOOPING) #define HDR_LEN 12 -- 2.43.2 From 0f2525a0289276c502087c62bb228d9ad7a1880f Mon Sep 17 00:00:00 2001 From: Nick Bowler Date: Sun, 7 Feb 2010 23:26:22 -0500 Subject: [PATCH 09/16] doc: Update moo2-data. --- doc/txt/moo2-data.txt | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/doc/txt/moo2-data.txt b/doc/txt/moo2-data.txt index 54ba4f0..9f82054 100644 --- a/doc/txt/moo2-data.txt +++ b/doc/txt/moo2-data.txt @@ -21,20 +21,30 @@ Music: streamhd.lbx - Short music tracks (audience screens, etc). Graphics: + bldg#.lbx - Buildings for the colony view. Use fonts.lbx.002 for the + palette. Part of the image, clearly meant to be a shadow, + is not coloured properly. There is an extra flag in these + images, which is probably related. logo.lbx - Simtex and Microprose logo images. mainmenu.lbx - Graphics for the main menu. Use fonts.lbx.006 for palette. + planets.lbx - Backgrounds for the colony view. Use fonts.lbx.002 for the + palette. ships.lbx - Ship graphics. Use fonts.lbx.012 for the base palette. Every 50th image contains an override palette which will colour the ships for a particular player colour. science.lbx - Contains the mouse cursor and the textbox/swirling mist animations for tech screens. Use the mouse cursor image as the override palette for the other two. + sr_r#_XX.lbx - The background of tech screens. Three for each race: science, + spying, and military. tanm_###.lbx - The spinning tech animations used on the tech screens. One file for each tech. There appears to be some data between the LBX header and the first file in the archive. - sr_r#_XX.lbx - The background of tech screens. Three for each race: science, - spying, and military. - + techsel.lbx - The menu for selecting research. Probably some mistakes here, + but for images 0-13, use fonts.lbx.004 as the base palette and + techsel.lbx.000 as the override. For images 14-27, use + fonts.lbx.005 as the base palette and techsel.lbx.014 as the + override. Uncatalogued: antarmsg.lbx @@ -42,12 +52,6 @@ antaroom.lbx app_pics.lbx beams.lbx billtext.lbx -bldg0.lbx -bldg1.lbx -bldg2.lbx -bldg3.lbx -bldg4.lbx -bldg5.lbx buffer0.lbx cmbtfgtr.lbx cmbtmisl.lbx @@ -109,7 +113,6 @@ newgame.lbx nextplyr.lbx ocpol.lbx officer.lbx -planets.lbx playspec.lbx plntsum.lbx raceicon.lbx @@ -130,7 +133,6 @@ starname.lbx sysdisp.lbx techdesc.lbx techname.lbx -techsel.lbx textbox.lbx turnsum.lbx warning.lbx -- 2.43.2 From 5cd07246cf1e87f099c88e89c6aa0a4cfb3b202b Mon Sep 17 00:00:00 2001 From: Nick Bowler Date: Sun, 7 Feb 2010 23:58:57 -0500 Subject: [PATCH 10/16] liblbx: Clear the image mask when backtracking frames. Without this, undrawn pixels in the first frame will have the pixel values from the previously drawn frame. --- src/image.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/image.c b/src/image.c index 9ad154a..76fbfed 100644 --- a/src/image.c +++ b/src/image.c @@ -291,8 +291,10 @@ unsigned char **lbximg_getframe(struct lbx_image *img, int frame) memset(img->mask[0], 0, img->width * img->height); } else { /* Start over if we are backtracking. */ - if (img->currentframe > frame) + if (img->currentframe > frame) { + memset(img->mask[0], 0, img->width * img->height); img->currentframe = -1; + } /* We must have previous frame decoded to continue. */ if (frame > img->currentframe + 1) { -- 2.43.2 From 357a488a0f5eed26ecae5cb9224e6495efb7bdaa Mon Sep 17 00:00:00 2001 From: Nick Bowler Date: Mon, 8 Feb 2010 00:13:30 -0500 Subject: [PATCH 11/16] doc: Update moo2-data. --- doc/txt/moo2-data.txt | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/doc/txt/moo2-data.txt b/doc/txt/moo2-data.txt index 9f82054..f1362e3 100644 --- a/doc/txt/moo2-data.txt +++ b/doc/txt/moo2-data.txt @@ -25,6 +25,14 @@ Graphics: palette. Part of the image, clearly meant to be a shadow, is not coloured properly. There is an extra flag in these images, which is probably related. + bldg5.lbx is an archive with one empty file. There *is* + some other junk in the archive file, though... + buffer0.lbx - Just about every UI element for every dialog that is used on + the galactic map screen. Use fonts.lbx.005 for the palette. + colbldg.lbx - The colony building menu. Use fonts.lbx.002 for the palette. + game.lbx - The "game" menu. Images 0-19, 27 and 28 use fonts.lbx.005 as + the palette: these are for the in-game menu. Images 20-26 use + fonts.lbx.006 as the palette, these are for the main menu. logo.lbx - Simtex and Microprose logo images. mainmenu.lbx - Graphics for the main menu. Use fonts.lbx.006 for palette. planets.lbx - Backgrounds for the colony view. Use fonts.lbx.002 for the @@ -52,13 +60,11 @@ antaroom.lbx app_pics.lbx beams.lbx billtext.lbx -buffer0.lbx cmbtfgtr.lbx cmbtmisl.lbx cmbtplnt.lbx cmbtsfx.lbx cmbtshp.lbx -colbldg.lbx colgcbt.lbx colony.lbx colony2.lbx @@ -92,7 +98,6 @@ firepts.lbx fleet.lbx flticons.lbx fonts.lbx -game.lbx gstar.lbx help.lbx herodata.lbx -- 2.43.2 From 225387c1fdec54fe9eb1b65cb3f77bdfaa662ffb Mon Sep 17 00:00:00 2001 From: Nick Bowler Date: Mon, 8 Feb 2010 11:32:30 -0500 Subject: [PATCH 12/16] build: Update project dependencies. --- README | 7 +++---- configure.ac | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/README b/README index a2d4a21..2967733 100644 --- a/README +++ b/README @@ -7,10 +7,9 @@ subject to frequent changes. Probably not a good idea for it to be used in external programs, yet. Requirements: -- A C99 compiler -- The tools themselves currently require some GNU library features, this should - change in the future. -- The lbximg tool requires libpng-1.2 +- A C99 compiler. +- The lbximg tool requires libpng-1.2 or later. +- The lbxgui tool requires GTK+-2.16 or later. The configure script will attempt to autodetect the presence of the above; if it fails to work for some reason, paths can be specified manually. diff --git a/configure.ac b/configure.ac index a53e22a..c03b931 100644 --- a/configure.ac +++ b/configure.ac @@ -28,7 +28,7 @@ AM_CONDITIONAL([BUILD_LBXIMG], [test x"$have_libpng" = x"yes"]) # A horrible combination of bugs makes this necessary for GTK+ detection. unset POSIXLY_CORRECT -AM_PATH_GTK_2_0([2.12.0], [have_gtk=yes], [have_gtk=no]) +AM_PATH_GTK_2_0([2.16.0], [have_gtk=yes], [have_gtk=no]) AM_CONDITIONAL([BUILD_LBXGUI], [test x"$have_gtk" = x"yes"]) AC_CONFIG_FILES([ -- 2.43.2 From 09db9b32090dc53d69a8ca82d89547cac7dd34be Mon Sep 17 00:00:00 2001 From: Nick Bowler Date: Mon, 8 Feb 2010 18:20:43 -0500 Subject: [PATCH 13/16] lbxgui: Don't use as much horizontal space in GUI. --- src/gui/lbxgui.glade | 224 +++++++++++++++++++++++++------------------ 1 file changed, 133 insertions(+), 91 deletions(-) diff --git a/src/gui/lbxgui.glade b/src/gui/lbxgui.glade index 8b44249..e8bf676 100644 --- a/src/gui/lbxgui.glade +++ b/src/gui/lbxgui.glade @@ -104,117 +104,159 @@ True + 6 - + True - 1 - 4 - Palette: - - - 0 - - - - - True - - - - False - 1 - - - - - True - 1 - 3 - Image: - - - False - 2 - - - - - True - - - - False - 3 - 3 - - - - - True - 1 - 3 - Override: - - - 4 - - - - - True - - - - 5 - - - - - True - 1 - 3 - Frame: - - - 6 - - - - - True - True - - adjustment1 - + 2 + 2 + + + True + 1 + 3 + Palette: + + + GTK_FILL + + + + + True + 1 + 3 + Override: + + + 1 + 2 + GTK_FILL + + + + + True + + + + 1 + 2 + 1 + 2 + GTK_FILL + + + + + True + + + + 1 + 2 + GTK_FILL + + False - 7 + 0 - + True - True - True - + 2 + 2 - + True - gtk-media-play + + + True + True + + adjustment1 + + + + False + 0 + + + + + True + True + True + + + + True + gtk-media-play + + + + + False + False + 3 + 1 + + + + 1 + 2 + 1 + 2 + GTK_FILL + + + + + True + 1 + 3 + Frame: + + + 1 + 2 + GTK_FILL + + + + + True + 1 + 3 + Image: + + + GTK_FILL + + + + + True + + + + 1 + 2 + GTK_FILL + - False - 3 - 8 + 1 False - 3 0 -- 2.43.2 From 242547a147c741c338b22a095a398785280e6f8f Mon Sep 17 00:00:00 2001 From: Nick Bowler Date: Mon, 8 Feb 2010 21:19:36 -0500 Subject: [PATCH 14/16] lbxgui: Make transparent pixels more obvious. --- src/gui/bg.xbm | 27 +++++++++++++++++++++++++++ src/gui/lbxgui.c | 37 ++++++++++++++++++++++++++++++++----- 2 files changed, 59 insertions(+), 5 deletions(-) create mode 100644 src/gui/bg.xbm diff --git a/src/gui/bg.xbm b/src/gui/bg.xbm new file mode 100644 index 0000000..b37f454 --- /dev/null +++ b/src/gui/bg.xbm @@ -0,0 +1,27 @@ +#define bg_width 48 +#define bg_height 48 +static unsigned char bg_bits[] = { + 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, + 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, + 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, + 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, + 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, + 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, + 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, + 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, + 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, + 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, + 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, + 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff }; diff --git a/src/gui/lbxgui.c b/src/gui/lbxgui.c index 21dee9a..ebb92ab 100644 --- a/src/gui/lbxgui.c +++ b/src/gui/lbxgui.c @@ -8,10 +8,14 @@ #include "lbx.h" #include "image.h" +#include "bg.xbm" + static GtkTreeStore *archives; static GtkBuilder *builder; static GtkWidget *canvas; +static GdkGC *bg_gc; + static LBX_IMG *image; /* LBX images can have up to three palettes, with each superseding the last. */ static struct lbx_colour palette_external[256]; @@ -75,15 +79,14 @@ static int render_frame(LBX_IMG *img, GdkPixbuf *buf, unsigned frame) stride = gdk_pixbuf_get_rowstride(buf); for (unsigned i = 0; i < info.height; i++) { - unsigned char (*p)[3] = (void *)(data + i*stride); + unsigned char (*p)[4] = (void *)(data + i*stride); for (unsigned j = 0; j < info.width; j++) { if (imgmask[i][j]) { get_colour(imgdata[i][j], p[j]); + p[j][3] = -1; } else { - p[j][0] = 0; - p[j][1] = 0; - p[j][2] = 0; + p[j][3] = 0; } } } @@ -161,6 +164,10 @@ gboolean canvas_expose(GtkWidget *canvas, GdkEventExpose *event, gpointer data) if (!framebuf) return TRUE; + gdk_draw_rectangle(canvas->window, bg_gc, TRUE, + event->area.x, event->area.y, + event->area.width, event->area.height); + gdk_draw_pixbuf(canvas->window, NULL, framebuf, event->area.x, event->area.y, event->area.x, event->area.y, event->area.width, event->area.height, @@ -178,7 +185,7 @@ static int init_framedata(int reset) return 0; lbximg_getinfo(image, &info); - framebuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, 8, + framebuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, info.width, info.height); if (!framebuf) { printf("failed to allocate pixbuf\n"); @@ -427,6 +434,23 @@ static void interface_init(void) gtk_combo_box_entry_set_text_column(GTK_COMBO_BOX_ENTRY(combo), 0); } +GdkBitmap *init_bg(GdkDrawable *drawable, GdkGC *gc) +{ + GdkColor fg = { .red = 0x6666, .green = 0x6666, .blue = 0x6666 }; + GdkColor bg = { .red = 0x9999, .green = 0x9999, .blue = 0x9999 }; + GdkBitmap *bitmap; + + bitmap = gdk_bitmap_create_from_data(drawable, bg_bits, + bg_width, bg_height); + + gdk_gc_set_rgb_fg_color(gc, &fg); + gdk_gc_set_rgb_bg_color(gc, &bg); + gdk_gc_set_fill(gc, GDK_OPAQUE_STIPPLED); + gdk_gc_set_stipple(gc, bitmap); + gdk_gc_set_ts_origin(gc, 0, 0); + return bitmap; +} + int main(int argc, char **argv) { GtkWidget *window; @@ -456,5 +480,8 @@ int main(int argc, char **argv) g_timeout_add(10, timeout, NULL); gtk_widget_show_all(window); + + bg_gc = gdk_gc_new(canvas->window); + init_bg(canvas->window, bg_gc); gtk_main(); } -- 2.43.2 From 10c0aa08b84a0a26c9c642f2dbfee6e8b11efb83 Mon Sep 17 00:00:00 2001 From: Nick Bowler Date: Mon, 8 Feb 2010 23:13:50 -0500 Subject: [PATCH 15/16] lbxgui: Make an effort to not leak resources. --- src/gui/lbxgui.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/gui/lbxgui.c b/src/gui/lbxgui.c index ebb92ab..21256e4 100644 --- a/src/gui/lbxgui.c +++ b/src/gui/lbxgui.c @@ -203,6 +203,11 @@ static int init_framedata(int reset) static int img_close(void *handle) { + if (framebuf) { + g_object_unref(framebuf); + framebuf = NULL; + } + lbx_file_close(handle); return 0; } @@ -281,6 +286,11 @@ void set_image_data(GtkComboBox *combo) f = lbx_file_open(lbx, index); if (f) { + if (image) { + lbximg_close(image); + image = NULL; + } + image = lbximg_open(f, &lbx_arch_fops, img_close); if (image) { memset(palette_internal, 0, sizeof palette_internal); -- 2.43.2 From bdad20799885211ac4c76bdaef5b027552d6241d Mon Sep 17 00:00:00 2001 From: Nick Bowler Date: Mon, 8 Feb 2010 23:14:16 -0500 Subject: [PATCH 16/16] liblbx: Add support for "raw" LBX images. There is a new image format in town. If a particular flag bit is set, then there are no row headers and data for every pixel of a frame is simply stored in row-major order. An example of such an image is starbg.lbx.009, as well as several others in the same archive. Don't you just *love* the designers of this format? --- src/image.c | 33 ++++++++++++++++++++++++++++++++- tests/regress.zsh | 7 +++++++ 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/src/image.c b/src/image.c index 76fbfed..21f5a8e 100644 --- a/src/image.c +++ b/src/image.c @@ -30,12 +30,13 @@ #include "lbx.h" #include "image.h" +#define FLAG_RAW 0x0100 /* Image is stored as a flat array of bytes. */ #define FLAG_OVERWRITE 0x0400 /* Draw each frame on a clean slate (unsure). */ #define FLAG_BUILDING 0x0800 /* Buildings have this, related to shadow? */ #define FLAG_PALETTE 0x1000 /* Image contains embedded palette. */ #define FLAG_LOOPING 0x2000 /* Loop over all frames in the image (unsure). */ -#define FLAG_ALL (FLAG_OVERWRITE|FLAG_BUILDING|FLAG_PALETTE|FLAG_LOOPING) +#define FLAG_ALL (FLAG_RAW|FLAG_OVERWRITE|FLAG_BUILDING|FLAG_PALETTE|FLAG_LOOPING) #define HDR_LEN 12 @@ -265,6 +266,33 @@ static unsigned char **allocframebuffer(size_t width, size_t height) return new; } +static unsigned char **read_raw_frame(struct lbx_image *img, int frame) +{ + unsigned long size = img->width * img->height; + + assert(img->flags & FLAG_RAW); + + if (img->fops->seek(img->f, img->offsets[frame], SEEK_SET)) { + lbx_errno = -errno; + return NULL; + } + + if (img->fops->read(img->framedata[0], size, img->f) != size) { + lbx_errno = -errno; + if (img->fops->eof(img->f)) + lbx_errno = LBX_EEOF; + return NULL; + } + memset(img->mask[0], 1, size); + + if (img->fops->tell(img->f) > img->offsets[frame+1]) { + lbx_errno = LBX_EFORMAT; + return NULL; + } + + return img->framedata; +} + unsigned char **lbximg_getframe(struct lbx_image *img, int frame) { if (frame >= img->frames || frame < 0) { @@ -284,6 +312,9 @@ unsigned char **lbximg_getframe(struct lbx_image *img, int frame) return NULL; } + if (img->flags & FLAG_RAW) + return read_raw_frame(img, frame); + if (img->flags & FLAG_OVERWRITE) { /* Clear the slate. */ img->currentframe = -1; diff --git a/tests/regress.zsh b/tests/regress.zsh index 20239b5..0131fbd 100755 --- a/tests/regress.zsh +++ b/tests/regress.zsh @@ -75,6 +75,13 @@ echo "ships.lbx.042: single frame, external+override palette, transparency:" $LBXIMG -df ships.lbx.042 -p fonts.lbx.012 -O ships.lbx.049 compare 0 bd643736d46ef387bcffcc8803aabb83 +# Nebulae +$LBXTOOL -xf $DATADIR/starbg.lbx starbg.lbx.009 + +echo "starbg.lbx.009: single frame, raw data:" +$LBXIMG -df starbg.lbx.009 -p fonts.lbx.005 +compare 0 cfc5d92b6503951c4962498c7dcfea31 + # Clean up if [[ $FAILED -eq 0 ]]; then echo "All tests completed successfully." -- 2.43.2