diff --git a/ChangeLog b/ChangeLog index b238212d2..c51179369 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,21 @@ +2008-04-13 David A. Capello + + * src/raster/undo.c (read_raw_cel, write_raw_cel): Fixed to + read/write the position of the Cel with sign (int16_t instead of + uint16_t). + + * src/commands/cmd_advanced_mode.c (cmd_advanced_mode_execute): + Fixed another typo (reported by Manuel Quiñones). + + * src/dialogs/tips.c (dialogs_tips): Fixed a typo (reported by + Manuel Quiñones). + + * makefile.lnx: Applied Manuel Quiñones's patch to fix the + install/uninstall rules. + + * src/commands/cmd_new_frame.c (copy_cel_in_next_frame): Fixed, + now it copies the entiry cel instead of the visible area. + 2008-04-11 David A. Capello * src/modules/sprites.h (ImageRef): Added. @@ -533,7 +551,7 @@ 2007-11-16 David A. Capello * src/raster/cel.c: Renamed "frame" to "cel" to avoid - confusion (Manuel Quiñones advice) + confusion (Manuel Quiñones advice). * src/modules/render.[ch]: Moved to util/. diff --git a/TODO.txt b/TODO.txt index 0e0ca81f6..9bb557e96 100644 --- a/TODO.txt +++ b/TODO.txt @@ -1,7 +1,6 @@ Next beta --------- -- search for "TODO next release" - Check these routines: + move_cel + copy_cel diff --git a/data/gui-en.xml b/data/gui-en.xml index 67cff1648..9ad5c78c8 100644 --- a/data/gui-en.xml +++ b/data/gui-en.xml @@ -60,6 +60,7 @@ + diff --git a/data/tips/tips.en b/data/tips/tips.en index d7bea8837..ca17d7831 100644 --- a/data/tips/tips.en +++ b/data/tips/tips.en @@ -1,5 +1,5 @@ # Allegro Sprite Editor tips -# Copyright (C) 2001, 2002, 2003, 2004, 2005, 2007, 2008 David A. Capello +# Copyright (C) 2001-2008 David A. Capello ********************************************************************** \palette ase.pcx diff --git a/makefile.lnx b/makefile.lnx index 5d2ef3575..2e0338f1e 100644 --- a/makefile.lnx +++ b/makefile.lnx @@ -14,13 +14,13 @@ endif ###################################################################### # Flags for GCC in GNU/Linux system -#ifdef DEBUGMODE +ifdef DEBUGMODE CFLAGS = `allegro-config --cflags debug` LFLAGS = `allegro-config --libs debug` -#else +else CFLAGS = `allegro-config --cflags` LFLAGS = `allegro-config --libs` -#endif +endif ###################################################################### # GCC stuff @@ -51,12 +51,12 @@ distclean: clean -rm -f $(ASE) install: - cp ase $(DEFAULT_PREFIX)/bin + cp aseprite $(DEFAULT_PREFIX)/bin cp -r data $(DEFAULT_PREFIX)/share/ase cp AUTHORS.txt $(DEFAULT_PREFIX)/share/ase uninstall: - -rm -vf $(DEFAULT_PREFIX)/bin/ase + -rm -vf $(DEFAULT_PREFIX)/bin/aseprite -rm -rvf $(DEFAULT_PREFIX)/share/ase -include makefile.dep diff --git a/src/commands/cmd_advanced_mode.c b/src/commands/cmd_advanced_mode.c index a3f2dfb6a..df0765a9a 100644 --- a/src/commands/cmd_advanced_mode.c +++ b/src/commands/cmd_advanced_mode.c @@ -64,7 +64,7 @@ static void cmd_advanced_mode_execute(const char *argument) if (jalert("%s<<%s||%s||%s", _("Warning - Important"), buf, - _("&Don't show it again"), _("&Continue")) == 1) { + _("&Don't show this again"), _("&Continue")) == 1) { set_config_bool("AdvancedMode", "Warning", FALSE); } } diff --git a/src/commands/cmd_merge_down_layer.c b/src/commands/cmd_merge_down_layer.c index e5d47e098..748ba1a3c 100644 --- a/src/commands/cmd_merge_down_layer.c +++ b/src/commands/cmd_merge_down_layer.c @@ -73,20 +73,20 @@ static void cmd_merge_down_layer_execute(const char *argument) dst_cel = layer_get_cel(dst_layer, frpos); /* get images */ - if (src_cel) + if (src_cel != NULL) src_image = stock_get_image(sprite->stock, src_cel->image); else src_image = NULL; - if (dst_cel) + if (dst_cel != NULL) dst_image = stock_get_image(sprite->stock, dst_cel->image); else dst_image = NULL; /* with source image? */ - if (src_image) { + if (src_image != NULL) { /* no destination image */ - if (!dst_image) { + if (dst_image == NULL) { /* copy this cel to the destination layer... */ /* creating a copy of the image */ @@ -95,7 +95,7 @@ static void cmd_merge_down_layer_execute(const char *argument) /* adding it in the stock of images */ index = stock_add_image(sprite->stock, dst_image); if (undo_is_enabled(sprite->undo)) - undo_add_image(sprite->undo, sprite->stock, dst_image); + undo_add_image(sprite->undo, sprite->stock, index); /* creating a copy of the cell */ dst_cel = cel_new(frpos, index); @@ -124,6 +124,11 @@ static void cmd_merge_down_layer_execute(const char *argument) src_cel->opacity, src_layer->blend_mode); + if (undo_is_enabled(sprite->undo)) { + undo_int(sprite->undo, (GfxObj *)dst_cel, &dst_cel->x); + undo_int(sprite->undo, (GfxObj *)dst_cel, &dst_cel->y); + } + cel_set_position(dst_cel, x1, y1); if (undo_is_enabled(sprite->undo)) diff --git a/src/commands/cmd_new_cel.c b/src/commands/cmd_new_cel.c index d81642cf4..d1ac6cb32 100644 --- a/src/commands/cmd_new_cel.c +++ b/src/commands/cmd_new_cel.c @@ -68,7 +68,7 @@ static void cmd_new_cel_execute(const char *argument) undo_set_label(current_sprite->undo, "New Cel"); undo_open(current_sprite->undo); undo_add_image(current_sprite->undo, - current_sprite->stock, image); + current_sprite->stock, image_index); } /* create the new cel */ diff --git a/src/commands/cmd_new_frame.c b/src/commands/cmd_new_frame.c index 27e6bf565..7dc791284 100644 --- a/src/commands/cmd_new_frame.c +++ b/src/commands/cmd_new_frame.c @@ -117,32 +117,48 @@ static bool new_frame_for_layer(Sprite *sprite, Layer *layer, int frame) return TRUE; } +/* makes a copy of the cel in 'frame-1' to a new cel in 'frame' */ static bool copy_cel_in_next_frame(Sprite *sprite, Layer *layer, int frame) { int image_index; - Image *image; - Cel *cel; + Image *src_image; + Image *dst_image; + Cel *src_cel; + Cel *dst_cel; - /* create a new empty cel with a new clean image */ - image = image_new(sprite->imgtype, sprite->w, sprite->h); - if (!image) { + /* create a copy of the previous cel */ + src_cel = layer_get_cel(layer, frame-1); + src_image = src_cel ? stock_get_image(sprite->stock, + src_cel->image): + NULL; + + if (src_image == NULL || frame == 0) + dst_image = image_new(sprite->imgtype, sprite->w, sprite->h); + else + dst_image = image_new_copy(src_image); + + if (!dst_image) { console_printf(_("Not enough memory.\n")); return FALSE; } - /* background color */ - image_clear(image, 0); - if (frame > 0) - layer_render(layer, image, 0, 0, frame-1); - /* add the image in the stock */ - image_index = stock_add_image(sprite->stock, image); - undo_add_image(sprite->undo, sprite->stock, image); + image_index = stock_add_image(sprite->stock, dst_image); + if (undo_is_enabled(sprite->undo)) + undo_add_image(sprite->undo, sprite->stock, image_index); + /* create the new cel */ + dst_cel = cel_new(frame, image_index); + + if (src_cel != NULL) { + cel_set_position(dst_cel, src_cel->x, src_cel->y); + cel_set_opacity(dst_cel, src_cel->opacity); + } + /* add the cel in the layer */ - cel = cel_new(frame, image_index); - undo_add_cel(sprite->undo, layer, cel); - layer_add_cel(layer, cel); + if (undo_is_enabled(sprite->undo)) + undo_add_cel(sprite->undo, layer, dst_cel); + layer_add_cel(layer, dst_cel); return TRUE; } diff --git a/src/dialogs/tips.c b/src/dialogs/tips.c index c9b393230..0985eaa8f 100644 --- a/src/dialogs/tips.c +++ b/src/dialogs/tips.c @@ -92,7 +92,7 @@ void dialogs_tips(bool forced) button_next = jbutton_new(_("&Next")); view = jview_new(); tips = tips_new(); - check = jcheck_new(_("Show me it in the start up")); + check = jcheck_new(_("Show this at startup")); jwidget_set_min_size(button_close, 50, 0); jwidget_set_min_size(button_prev, 50, 0); diff --git a/src/effect/effect.c b/src/effect/effect.c index abda039e1..d44421a41 100644 --- a/src/effect/effect.c +++ b/src/effect/effect.c @@ -311,11 +311,11 @@ void effect_flush(Effect *effect) void effect_apply_to_target(Effect *effect) { - ImageRef *p, *next, *images; + ImageRef *p, *images; bool cancelled = FALSE; int nimages; - images = sprite_get_images(effect->sprite, effect->target, TRUE); + images = images_ref_get_from_sprite(effect->sprite, effect->target, TRUE); if (images == NULL) return; @@ -351,10 +351,7 @@ void effect_apply_to_target(Effect *effect) } /* free all ImageRefs */ - for (p=images; p; p=next) { - next = p->next; - jfree(p); - } + images_ref_free(images); } static EffectData *get_effect_data(const char *name) diff --git a/src/modules/sprites.c b/src/modules/sprites.c index d9250d8ab..8908a565c 100644 --- a/src/modules/sprites.c +++ b/src/modules/sprites.c @@ -49,7 +49,7 @@ Sprite *current_sprite = NULL; static JList sprites_list; static Sprite *clipboard_sprite; -static ImageRef *layer_get_images(Sprite *sprite, Layer *layer, int target, bool write); +static ImageRef *images_ref_get_from_layer(Sprite *sprite, Layer *layer, int target, bool write); static void layer_get_pos(Sprite *sprite, Layer *layer, int target, bool write, int **x, int **y, int *count); int init_module_sprites(void) @@ -218,15 +218,25 @@ Sprite *lock_current_sprite(void) return NULL; } -ImageRef *sprite_get_images(struct Sprite *sprite, int target, bool write) +ImageRef *images_ref_get_from_sprite(Sprite *sprite, int target, bool write) { Layer *layer = target & TARGET_ALL_LAYERS ? sprite->set: sprite->layer; - return layer_get_images(sprite, layer, target, write); + return images_ref_get_from_layer(sprite, layer, target, write); } -static ImageRef *layer_get_images(Sprite *sprite, Layer *layer, int target, bool write) +void images_ref_free(ImageRef *image_ref) +{ + ImageRef *p, *next; + + for (p=image_ref; p; p=next) { + next = p->next; + jfree(p); + } +} + +static ImageRef *images_ref_get_from_layer(Sprite *sprite, Layer *layer, int target, bool write) { #define ADD_IMAGES(images) \ { \ @@ -288,7 +298,7 @@ static ImageRef *layer_get_images(Sprite *sprite, Layer *layer, int target, bool JLink link; JI_LIST_FOR_EACH(layer->layers, link) { - sub_images = layer_get_images(sprite, link->data, target, write); + sub_images = images_ref_get_from_layer(sprite, link->data, target, write); if (sub_images != NULL) ADD_IMAGES(sub_images); diff --git a/src/modules/sprites.h b/src/modules/sprites.h index 7b6c2c12a..081e66fd2 100644 --- a/src/modules/sprites.h +++ b/src/modules/sprites.h @@ -58,7 +58,8 @@ bool is_current_sprite_writable(void); struct Sprite *lock_current_sprite(void); -ImageRef *sprite_get_images(struct Sprite *sprite, int target, bool write); +ImageRef *images_ref_get_from_sprite(struct Sprite *sprite, int target, bool write); +void images_ref_free(ImageRef *image_ref); #endif /* MODULES_SPRITES_H */ diff --git a/src/raster/layer.c b/src/raster/layer.c index ea2e2e076..e68fd8ca5 100644 --- a/src/raster/layer.c +++ b/src/raster/layer.c @@ -117,10 +117,9 @@ Layer *layer_new_copy(Sprite *dst_sprite, const Layer *src_layer) image_copy = image_new_copy(image); - if (undo_is_enabled(dst_sprite->undo)) - undo_add_image(dst_sprite->undo, dst_sprite->stock, image_copy); - cel_copy->image = stock_add_image(dst_sprite->stock, image_copy); + if (undo_is_enabled(dst_sprite->undo)) + undo_add_image(dst_sprite->undo, dst_sprite->stock, cel_copy->image); layer_add_cel(layer_copy, cel_copy); } diff --git a/src/raster/undo.c b/src/raster/undo.c index c62c2c9f3..58723572c 100644 --- a/src/raster/undo.c +++ b/src/raster/undo.c @@ -135,13 +135,13 @@ static void chunk_flip_invert(UndoStream *stream, UndoChunkFlip *chunk, int stat static void chunk_dirty_new(UndoStream *stream, Dirty *dirty); static void chunk_dirty_invert(UndoStream *stream, UndoChunkDirty *chunk, int state); -static void chunk_add_image_new(UndoStream *stream, Stock *stock, Image *image); +static void chunk_add_image_new(UndoStream *stream, Stock *stock, int image_index); static void chunk_add_image_invert(UndoStream *stream, UndoChunkAddImage *chunk, int state); -static void chunk_remove_image_new(UndoStream *stream, Stock *stock, Image *image); +static void chunk_remove_image_new(UndoStream *stream, Stock *stock, int image_index); static void chunk_remove_image_invert(UndoStream *stream, UndoChunkRemoveImage *chunk, int state); -static void chunk_replace_image_new(UndoStream *stream, Stock *stock, int index); +static void chunk_replace_image_new(UndoStream *stream, Stock *stock, int image_index); static void chunk_replace_image_invert(UndoStream *stream, UndoChunkReplaceImage *chunk, int state); static void chunk_add_cel_new(UndoStream *stream, Layer *layer, Cel *cel); @@ -762,7 +762,7 @@ static void chunk_dirty_invert(UndoStream *stream, UndoChunkDirty *chunk, int st "add_image" DWORD stock ID - DWORD index + DWORD index of the image in the stock ***********************************************************************/ @@ -770,45 +770,36 @@ struct UndoChunkAddImage { UndoChunk head; ase_uint32 stock_id; - ase_uint32 index; + ase_uint32 image_index; }; -/* TODO fix this so it doesn't need to be called as: - image_index = stock_add_image(sprite->stock, image); - undo_add_image(sprite->undo, sprite->stock, image); - */ -void undo_add_image(Undo *undo, Stock *stock, Image *image) +void undo_add_image(Undo *undo, Stock *stock, int image_index) { - chunk_add_image_new(undo->undo_stream, stock, image); + chunk_add_image_new(undo->undo_stream, stock, image_index); update_undo(undo); } -static void chunk_add_image_new(UndoStream *stream, Stock *stock, Image *image) +static void chunk_add_image_new(UndoStream *stream, Stock *stock, int image_index) { UndoChunkAddImage *chunk = (UndoChunkAddImage *) undo_chunk_new(stream, UNDO_TYPE_ADD_IMAGE, sizeof(UndoChunkAddImage)); - int index; - - for (index=0; indexnimage; index++) - if (stock->image[index] == image) - break; chunk->stock_id = stock->gfxobj.id; - chunk->index = index; + chunk->image_index = image_index; } static void chunk_add_image_invert(UndoStream *stream, UndoChunkAddImage *chunk, int state) { unsigned int stock_id = chunk->stock_id; - unsigned int index = chunk->index; + unsigned int image_index = chunk->image_index; Stock *stock = (Stock *)gfxobj_find(stock_id); if (stock) { - Image *image = stock_get_image(stock, index); - if (image) { - chunk_remove_image_new(stream, stock, image); + Image *image = stock_get_image(stock, image_index); + if (image != NULL) { + chunk_remove_image_new(stream, stock, image_index); stock_remove_image(stock, image); image_free(image); } @@ -820,7 +811,7 @@ static void chunk_add_image_invert(UndoStream *stream, UndoChunkAddImage *chunk, "remove_image" DWORD stock ID - DWORD index + DWORD index of the image in the stock IMAGE_DATA see read/write_raw_image ***********************************************************************/ @@ -829,30 +820,26 @@ struct UndoChunkRemoveImage { UndoChunk head; ase_uint32 stock_id; - ase_uint32 index; + ase_uint32 image_index; ase_uint8 data[0]; }; -void undo_remove_image(Undo *undo, Stock *stock, Image *image) +void undo_remove_image(Undo *undo, Stock *stock, int image_index) { - chunk_remove_image_new(undo->undo_stream, stock, image); + chunk_remove_image_new(undo->undo_stream, stock, image_index); update_undo(undo); } -static void chunk_remove_image_new(UndoStream *stream, Stock *stock, Image *image) +static void chunk_remove_image_new(UndoStream *stream, Stock *stock, int image_index) { + Image *image = stock->image[image_index]; UndoChunkRemoveImage *chunk = (UndoChunkRemoveImage *) undo_chunk_new(stream, UNDO_TYPE_REMOVE_IMAGE, sizeof(UndoChunkRemoveImage)+get_raw_image_size(image)); - int index; - - for (index=0; indexnimage; index++) - if (stock->image[index] == image) - break; chunk->stock_id = stock->gfxobj.id; - chunk->index = index; + chunk->image_index = image_index; write_raw_image(chunk->data, image); } @@ -860,7 +847,7 @@ static void chunk_remove_image_new(UndoStream *stream, Stock *stock, Image *imag static void chunk_remove_image_invert(UndoStream *stream, UndoChunkRemoveImage *chunk, int state) { unsigned int stock_id = chunk->stock_id; - unsigned int index = chunk->index; + unsigned int image_index = chunk->image_index; Stock *stock = (Stock *)gfxobj_find(stock_id); if (stock) { @@ -868,8 +855,8 @@ static void chunk_remove_image_invert(UndoStream *stream, UndoChunkRemoveImage * /* assert(image != NULL); */ - stock_replace_image(stock, index, image); - chunk_add_image_new(stream, stock, image); + stock_replace_image(stock, image_index, image); + chunk_add_image_new(stream, stock, image_index); } } @@ -878,7 +865,7 @@ static void chunk_remove_image_invert(UndoStream *stream, UndoChunkRemoveImage * "replace_image" DWORD stock ID - DWORD index + DWORD index of the image in the stock IMAGE_DATA see read/write_raw_image ***********************************************************************/ @@ -887,26 +874,26 @@ struct UndoChunkReplaceImage { UndoChunk head; ase_uint32 stock_id; - ase_uint32 index; + ase_uint32 image_index; ase_uint8 data[0]; }; -void undo_replace_image(Undo *undo, Stock *stock, int index) +void undo_replace_image(Undo *undo, Stock *stock, int image_index) { - chunk_replace_image_new(undo->undo_stream, stock, index); + chunk_replace_image_new(undo->undo_stream, stock, image_index); update_undo(undo); } -static void chunk_replace_image_new(UndoStream *stream, Stock *stock, int index) +static void chunk_replace_image_new(UndoStream *stream, Stock *stock, int image_index) { - Image *image = stock->image[index]; + Image *image = stock->image[image_index]; UndoChunkReplaceImage *chunk = (UndoChunkReplaceImage *) undo_chunk_new(stream, UNDO_TYPE_REPLACE_IMAGE, sizeof(UndoChunkReplaceImage)+get_raw_image_size(image)); chunk->stock_id = stock->gfxobj.id; - chunk->index = index; + chunk->image_index = image_index; write_raw_image(chunk->data, image); } @@ -914,18 +901,18 @@ static void chunk_replace_image_new(UndoStream *stream, Stock *stock, int index) static void chunk_replace_image_invert(UndoStream *stream, UndoChunkReplaceImage *chunk, int state) { unsigned long stock_id = chunk->stock_id; - unsigned long index = chunk->index; + unsigned long image_index = chunk->image_index; Stock *stock = (Stock *)gfxobj_find(stock_id); if (stock) { Image *image = read_raw_image(chunk->data); - chunk_replace_image_new(stream, stock, index); + chunk_replace_image_new(stream, stock, image_index); - if (stock->image[index]) - image_free(stock->image[index]); + if (stock->image[image_index]) + image_free(stock->image[image_index]); - stock_replace_image(stock, index, image); + stock_replace_image(stock, image_index, image); } } @@ -1104,7 +1091,8 @@ static void chunk_remove_layer_new(UndoStream *stream, Layer *layer) Layer *after = layer_get_prev(layer); chunk->set_id = set->gfxobj.id; - chunk->after_id = after ? after->gfxobj.id: 0; + chunk->after_id = after != NULL ? after->gfxobj.id: 0; + write_raw_layer(chunk->data, layer); } @@ -1113,7 +1101,7 @@ static void chunk_remove_layer_invert(UndoStream *stream, UndoChunkRemoveLayer * Layer *set = (Layer *)gfxobj_find(chunk->set_id); Layer *after = (Layer *)gfxobj_find(chunk->after_id); - if (set) { + if (set != NULL) { Layer *layer = read_raw_layer(chunk->data); /* assert(layer != NULL); */ @@ -1360,6 +1348,13 @@ static void undo_chunk_free(UndoChunk *chunk) raw_data += 2; \ } +#define read_raw_int16(dst) \ + { \ + memcpy(&word, raw_data, 2); \ + dst = (int16_t)word; \ + raw_data += 2; \ + } + #define read_raw_uint8(dst) \ { \ dst = *raw_data; \ @@ -1386,6 +1381,13 @@ static void undo_chunk_free(UndoChunk *chunk) raw_data += 2; \ } +#define write_raw_int16(src) \ + { \ + word = (int16_t)src; \ + memcpy(raw_data, &word, 2); \ + raw_data += 2; \ + } + #define write_raw_uint8(src) \ { \ *raw_data = src; \ @@ -1585,6 +1587,7 @@ static ase_uint8 *write_raw_image(ase_uint8 *raw_data, Image *image) static int get_raw_image_size(Image *image) { + assert(image != NULL); return 4+1+2+2+IMAGE_LINE_SIZE(image, image->w) * image->h; } @@ -1611,8 +1614,8 @@ static Cel *read_raw_cel(ase_uint8 *raw_data) read_raw_uint32(cel_id); read_raw_uint16(frame); read_raw_uint16(image); - read_raw_uint16(x); - read_raw_uint16(y); + read_raw_int16(x); + read_raw_int16(y); read_raw_uint16(opacity); cel = cel_new(frame, image); @@ -1631,8 +1634,8 @@ static ase_uint8 *write_raw_cel(ase_uint8 *raw_data, Cel *cel) write_raw_uint32(cel->gfxobj.id); write_raw_uint16(cel->frame); write_raw_uint16(cel->image); - write_raw_uint16(cel->x); - write_raw_uint16(cel->y); + write_raw_int16(cel->x); + write_raw_int16(cel->y); write_raw_uint16(cel->opacity); return raw_data; @@ -1684,7 +1687,7 @@ static Layer *read_raw_layer(ase_uint8 *raw_data) /* read cels */ for (c=0; cstock, cel->image); if (undo_is_enabled(sprite->undo)) - undo_remove_image(sprite->undo, sprite->stock, image); + undo_remove_image(sprite->undo, sprite->stock, cel->image); stock_remove_image(sprite->stock, image); image_free(image); diff --git a/src/util/celmove.c b/src/util/celmove.c index 73878a3cc..803a20309 100644 --- a/src/util/celmove.c +++ b/src/util/celmove.c @@ -128,7 +128,7 @@ void copy_cel(void) image_index = stock_add_image(sprite->stock, image); if (undo_is_enabled(sprite->undo)) - undo_add_image(sprite->undo, sprite->stock, image); + undo_add_image(sprite->undo, sprite->stock, image_index); } /* setup the cel */ diff --git a/src/util/misc.c b/src/util/misc.c index 9d5f7c5b7..10ad8d39d 100644 --- a/src/util/misc.c +++ b/src/util/misc.c @@ -309,30 +309,25 @@ int interactive_move_layer(int mode, bool use_undo, int (*callback)(void)) gui_feedback(); } while (editor_click(editor, &new_x, &new_y, &update, NULL)); + new_x = cel->x; + new_y = cel->y; + cel_set_position(cel, begin_x, begin_y); + /* the position was changed */ if (!editor_click_cancel(editor)) { if (use_undo && undo_is_enabled(sprite->undo)) { - new_x = cel->x; - new_y = cel->y; - undo_set_label(sprite->undo, "Cel Movement"); undo_open(sprite->undo); - cel->x = begin_x; - cel->y = begin_y; undo_int(sprite->undo, (GfxObj *)cel, &cel->x); undo_int(sprite->undo, (GfxObj *)cel, &cel->y); - cel->x = new_x; - cel->y = new_y; undo_close(sprite->undo); } + cel_set_position(cel, new_x, new_y); ret = TRUE; } /* the position wasn't changed */ else { - cel->x = begin_x; - cel->y = begin_y; - ret = FALSE; } diff --git a/src/util/quantize.c b/src/util/quantize.c index 3ad9da579..fd21796ba 100644 --- a/src/util/quantize.c +++ b/src/util/quantize.c @@ -26,15 +26,12 @@ #include "raster/image.h" #include "raster/palette.h" #include "raster/sprite.h" -#include "raster/stock.h" #include "util/quantize.h" -/* static int quantize_bitmaps1(struct Stock *stock, struct RGB *pal, int *bmp_i, int fill_other); */ -/* static int quantize_bitmaps2(struct Stock *stock, struct Palette *pal); */ +static int quantize_bitmaps(Image **image, int nimage, RGB *pal, int *bmp_i, int fill_other); -void sprite_quantize(struct Sprite *sprite) +void sprite_quantize(Sprite *sprite) { -#if 0 /* TODO next release */ Palette *palette = palette_new(0, MAX_PALETTE_COLORS); sprite_quantize_ex(sprite, palette); @@ -42,25 +39,39 @@ void sprite_quantize(struct Sprite *sprite) /* just one palette */ sprite_reset_palettes(sprite); sprite_set_palette(sprite, palette, FALSE); -#endif + + palette_free(palette); } void sprite_quantize_ex(Sprite *sprite, Palette *palette) { -#if 0 /* TODO */ - Stock *stock; - Image *flat_image; - int c; + Image *flat_image, **image_array; + ImageRef *p, *images; + int c, nimage; - stock = sprite_get_images(sprite, TARGET_ALL_LAYERS | - TARGET_ALL_FRAMES, FALSE, NULL, NULL); - if (stock) { + images = images_ref_get_from_sprite(sprite, TARGET_ALL_LAYERS | + TARGET_ALL_FRAMES, FALSE); + if (images != NULL) { /* add a flat image with the current sprite's frame rendered */ flat_image = image_new(sprite->imgtype, sprite->w, sprite->h); image_clear(flat_image, 0); sprite_render(sprite, flat_image, 0, 0); - stock_add_image(stock, flat_image); + /* count images in the 'images' list */ + c = 0; + for (p=images; p; p=p->next) + c++; + c++; /* the 'flat_image' */ + + /* create an array of images */ + nimage = c; + image_array = jmalloc(sizeof(Image**) * nimage); + + c = 0; + for (p=images; p; p=p->next) + image_array[c++] = p->image; + image_array[c++] = flat_image; /* the 'flat_image' */ + /* generate the optimized palette */ { PALETTE rgbpal; @@ -69,25 +80,23 @@ void sprite_quantize_ex(Sprite *sprite, Palette *palette) for (c=0; c<256; c++) rgbpal[c].r = rgbpal[c].g = rgbpal[c].b = 255; - ibmp = jmalloc(sizeof (int) * stock->nimage); - for (c=0; cnimage; c++) + ibmp = jmalloc(sizeof(int) * nimage); + for (c=0; crl=rl; - node->gl=gl; - node->bl=bl; - node->rh=rh; - node->gh=gh; - node->bh=bh; - node->E=node->Sb=node->Sg=node->Sr=node->n2=node->n1=0; - node->parent=parent; - if (rh-rl>TREE_DEPTH) { - rm=(rl+rh)>>1; - gm=(gl+gh)>>1; - bm=(bl+bh)>>1; - node->subnode[0][0][0]=create_node(rl,gl,bl,rm,gm,bm,node); - node->subnode[0][0][1]=create_node(rm,gl,bl,rh,gm,bm,node); - node->subnode[0][1][0]=create_node(rl,gm,bl,rm,gh,bm,node); - node->subnode[0][1][1]=create_node(rm,gm,bl,rh,gh,bm,node); - node->subnode[1][0][0]=create_node(rl,gl,bm,rm,gm,bh,node); - node->subnode[1][0][1]=create_node(rm,gl,bm,rh,gm,bh,node); - node->subnode[1][1][0]=create_node(rl,gm,bm,rm,gh,bh,node); - node->subnode[1][1][1]=create_node(rm,gm,bm,rh,gh,bh,node); - } else { - for (bm=bl;bmrl=rl; + node->gl=gl; + node->bl=bl; + node->rh=rh; + node->gh=gh; + node->bh=bh; + node->E=node->Sb=node->Sg=node->Sr=node->n2=node->n1=0; + node->parent=parent; + if (rh-rl>TREE_DEPTH) { + rm=(rl+rh)>>1; + gm=(gl+gh)>>1; + bm=(bl+bh)>>1; + node->subnode[0][0][0]=create_node(rl,gl,bl,rm,gm,bm,node); + node->subnode[0][0][1]=create_node(rm,gl,bl,rh,gm,bm,node); + node->subnode[0][1][0]=create_node(rl,gm,bl,rm,gh,bm,node); + node->subnode[0][1][1]=create_node(rm,gm,bl,rh,gh,bm,node); + node->subnode[1][0][0]=create_node(rl,gl,bm,rm,gm,bh,node); + node->subnode[1][0][1]=create_node(rm,gl,bm,rh,gm,bh,node); + node->subnode[1][1][0]=create_node(rl,gm,bm,rm,gh,bh,node); + node->subnode[1][1][1]=create_node(rm,gm,bm,rh,gh,bh,node); + } else { + for (bm=bl;bmsubnode[1][1][1]= + node->subnode[1][1][0]= + node->subnode[1][0][1]= + node->subnode[1][0][0]= + node->subnode[0][1][1]= + node->subnode[0][1][0]= + node->subnode[0][0][1]= + node->subnode[0][0][0]=0; } - node->subnode[1][1][1]= - node->subnode[1][1][0]= - node->subnode[1][0][1]= - node->subnode[1][0][0]= - node->subnode[0][1][1]= - node->subnode[0][1][0]= - node->subnode[0][0][1]= - node->subnode[0][0][0]=0; - } - return node; + return node; } -static PALETTE_NODE *collapse_empty(PALETTE_NODE *node,unsigned int *n_colours) { - unsigned int b,g,r; - for (b=0;b<2;b++) { - for (g=0;g<2;g++) { - for (r=0;r<2;r++) { - if (node->subnode[b][g][r]) - node->subnode[b][g][r]=collapse_empty(node->subnode[b][g][r],n_colours); - } +static PALETTE_NODE *collapse_empty(PALETTE_NODE *node,unsigned int *n_colours) +{ + unsigned int b,g,r; + for (b=0;b<2;b++) { + for (g=0;g<2;g++) { + for (r=0;r<2;r++) { + if (node->subnode[b][g][r]) + node->subnode[b][g][r]=collapse_empty(node->subnode[b][g][r],n_colours); + } + } } - } - if (node->n1==0) { - jfree(node); - node=0; - } else if (node->n2) (*n_colours)++; - return node; + if (node->n1==0) { + jfree(node); + node=0; + } else if (node->n2) (*n_colours)++; + return node; } static PALETTE_NODE *collapse_nodes(PALETTE_NODE *node,unsigned int *n_colours, - unsigned int n_entries,unsigned int Ep) { - unsigned int b,g,r; - if (node->E<=Ep) { - for (b=0;b<2;b++) { - for (g=0;g<2;g++) { - for (r=0;r<2;r++) { - if (node->subnode[b][g][r]) { - node->subnode[b][g][r]=collapse_nodes(node->subnode[b][g][r], - n_colours,n_entries,0); - if (*n_colours<=n_entries) return node; - } - } - } - } - if (node->parent->n2) (*n_colours)--; - node->parent->n2+=node->n2; - node->parent->Sr+=node->Sr; - node->parent->Sg+=node->Sg; - node->parent->Sb+=node->Sb; - jfree(node); - node=0; - } else { - for (b=0;b<2;b++) { - for (g=0;g<2;g++) { - for (r=0;r<2;r++) { - if (node->subnode[b][g][r]) { - node->subnode[b][g][r]=collapse_nodes(node->subnode[b][g][r], - n_colours,n_entries,Ep); - if (*n_colours<=n_entries) return node; - } - } - } - } - } - return node; -} - -static unsigned int distance_squared(int r,int g,int b) { - return r*r+g*g+b*b; -} - -static void minimum_Ep(PALETTE_NODE *node,unsigned int *Ep) { - unsigned int r,g,b; - if (node->E<*Ep) *Ep=node->E; - for (b=0;b<2;b++) { - for (g=0;g<2;g++) { - for (r=0;r<2;r++) { - if (node->subnode[b][g][r]) minimum_Ep(node->subnode[b][g][r],Ep); - } - } - } -} - -static void fill_palette(PALETTE_NODE *node,unsigned int *c,RGB *pal,int depth) { - unsigned int r,g,b; - if (node->n2) { - for (;pal[*c].r!=255;(*c)++); - pal[*c].r=node->Sr/node->n2; - pal[*c].g=node->Sg/node->n2; - pal[*c].b=node->Sb/node->n2; - (*c)++; - } - for (b=0;b<2;b++) { - for (g=0;g<2;g++) { - for (r=0;r<2;r++) { - if (node->subnode[b][g][r]) - fill_palette(node->subnode[b][g][r],c,pal,depth+1); - } - } - } -} - -static void destroy_tree(PALETTE_NODE *tree) { - unsigned int r,g,b; - for (b=0;b<2;b++) { - for (g=0;g<2;g++) { - for (r=0;r<2;r++) { - if (tree->subnode[b][g][r]) destroy_tree(tree->subnode[b][g][r]); - } - } - } - jfree(tree); -} - -static int quantize_bitmaps1(Stock *stock, RGB *pal, int *bmp_i, int fill_other) + unsigned int n_entries,unsigned int Ep) { - int c_bmp,x,y,c,r,g,b,n_colours=0,n_entries=0,Ep; - PALETTE_NODE *tree,*node; - - /* only support RGB bitmaps */ - if ((stock->nimage < 1) || (stock->imgtype != IMAGE_RGB)) - return 0; - -/*Create the tree structure*/ - tree=create_node(0,0,0,64,64,64,0); -/*Scan the bitmaps*/ -/* add_progress(stock->nimage+1); */ - for (c_bmp=0;c_bmpnimage;c_bmp++) { - if (stock->image[c_bmp]) { -/* add_progress(stock->image[c_bmp]->h); */ - for (y=0;yimage[c_bmp]->h;y++) { - for (x=0;ximage[c_bmp]->w;x++) { - c=stock->image[c_bmp]->method->getpixel(stock->image[c_bmp],x,y); - r=_rgba_getr(c)>>2; - g=_rgba_getg(c)>>2; - b=_rgba_getb(c)>>2; - node=rgb_node[b][g][r]; - node->n2+=bmp_i[c_bmp]; - node->Sr+=r*bmp_i[c_bmp]; - node->Sg+=g*bmp_i[c_bmp]; - node->Sb+=b*bmp_i[c_bmp]; - do { - node->n1+=bmp_i[c_bmp]; - node->E+=distance_squared((r<<1)-node->rl-node->rh, - (g<<1)-node->gl-node->gh, - (b<<1)-node->bl-node->bh)*bmp_i[c_bmp]; - node=node->parent; - } while (node); + unsigned int b,g,r; + if (node->E<=Ep) { + for (b=0;b<2;b++) { + for (g=0;g<2;g++) { + for (r=0;r<2;r++) { + if (node->subnode[b][g][r]) { + node->subnode[b][g][r]=collapse_nodes(node->subnode[b][g][r], + n_colours,n_entries,0); + if (*n_colours<=n_entries) return node; + } + } + } + } + if (node->parent->n2) (*n_colours)--; + node->parent->n2+=node->n2; + node->parent->Sr+=node->Sr; + node->parent->Sg+=node->Sg; + node->parent->Sb+=node->Sb; + jfree(node); + node=0; + } else { + for (b=0;b<2;b++) { + for (g=0;g<2;g++) { + for (r=0;r<2;r++) { + if (node->subnode[b][g][r]) { + node->subnode[b][g][r]=collapse_nodes(node->subnode[b][g][r], + n_colours,n_entries,Ep); + if (*n_colours<=n_entries) return node; + } + } + } } -/* do_progress(y); */ - } -/* del_progress(); */ } -/* do_progress(c_bmp); */ - } -/*Collapse empty nodes in the tree, and count leaves*/ - tree=collapse_empty(tree,&n_colours); -/*Count free palette entries*/ - for (c=0;c<256;c++) { - if (pal[c].r==255) n_entries++; - } -/*Collapse nodes until there are few enough to fit in the palette*/ - if (n_colours > n_entries) { -/* int n_colours1 = n_colours; */ -/* add_progress(n_colours1 - n_entries); */ - while (n_colours>n_entries) { - Ep=0xFFFFFFFFul; - minimum_Ep(tree,&Ep); - tree=collapse_nodes(tree,&n_colours,n_entries,Ep); - -/* if (n_colours > n_entries) */ -/* do_progress(n_colours1 - n_colours); */ - } -/* del_progress(); */ - } -/* del_progress(); */ -/*Fill palette*/ - c=0; - fill_palette(tree,&c,pal,1); - if (fill_other) { - for (;c<256;c++) { - if (pal[c].r==255) - pal[c].b=pal[c].g=pal[c].r=0; - } - } -/*Free memory used by tree*/ - destroy_tree(tree); - return n_colours; + return node; } -#endif +static unsigned int distance_squared(int r,int g,int b) +{ + return r*r+g*g+b*b; +} + +static void minimum_Ep(PALETTE_NODE *node,unsigned int *Ep) +{ + unsigned int r,g,b; + if (node->E<*Ep) *Ep=node->E; + for (b=0;b<2;b++) { + for (g=0;g<2;g++) { + for (r=0;r<2;r++) { + if (node->subnode[b][g][r]) minimum_Ep(node->subnode[b][g][r],Ep); + } + } + } +} + +static void fill_palette(PALETTE_NODE *node,unsigned int *c,RGB *pal,int depth) +{ + unsigned int r,g,b; + if (node->n2) { + for (;pal[*c].r!=255;(*c)++); + pal[*c].r=node->Sr/node->n2; + pal[*c].g=node->Sg/node->n2; + pal[*c].b=node->Sb/node->n2; + (*c)++; + } + for (b=0;b<2;b++) { + for (g=0;g<2;g++) { + for (r=0;r<2;r++) { + if (node->subnode[b][g][r]) + fill_palette(node->subnode[b][g][r],c,pal,depth+1); + } + } + } +} + +static void destroy_tree(PALETTE_NODE *tree) +{ + unsigned int r,g,b; + for (b=0;b<2;b++) { + for (g=0;g<2;g++) { + for (r=0;r<2;r++) { + if (tree->subnode[b][g][r]) destroy_tree(tree->subnode[b][g][r]); + } + } + } + jfree(tree); +} + +static int quantize_bitmaps(Image **image, int nimage, RGB *pal, int *bmp_i, int fill_other) +{ + int c_bmp,x,y,c,r,g,b,n_colours=0,n_entries=0,Ep; + PALETTE_NODE *tree,*node; + + /* only support RGB bitmaps */ + if ((nimage < 1) || (image[0]->imgtype != IMAGE_RGB)) + return 0; + + /*Create the tree structure*/ + tree=create_node(0,0,0,64,64,64,0); + /*Scan the bitmaps*/ + /* add_progress(nimage+1); */ + for (c_bmp=0;c_bmph); */ + for (y=0;yh;y++) { + for (x=0;xw;x++) { + c=image[c_bmp]->method->getpixel(image[c_bmp],x,y); + r=_rgba_getr(c)>>2; + g=_rgba_getg(c)>>2; + b=_rgba_getb(c)>>2; + node=rgb_node[b][g][r]; + node->n2+=bmp_i[c_bmp]; + node->Sr+=r*bmp_i[c_bmp]; + node->Sg+=g*bmp_i[c_bmp]; + node->Sb+=b*bmp_i[c_bmp]; + do { + node->n1+=bmp_i[c_bmp]; + node->E+=distance_squared((r<<1)-node->rl-node->rh, + (g<<1)-node->gl-node->gh, + (b<<1)-node->bl-node->bh)*bmp_i[c_bmp]; + node=node->parent; + } while (node); + } + /* do_progress(y); */ + } + /* del_progress(); */ + /* do_progress(c_bmp); */ + } + /*Collapse empty nodes in the tree, and count leaves*/ + tree=collapse_empty(tree,&n_colours); + /*Count free palette entries*/ + for (c=0;c<256;c++) { + if (pal[c].r==255) n_entries++; + } + /*Collapse nodes until there are few enough to fit in the palette*/ + if (n_colours > n_entries) { + /* int n_colours1 = n_colours; */ + /* add_progress(n_colours1 - n_entries); */ + while (n_colours>n_entries) { + Ep=0xFFFFFFFFul; + minimum_Ep(tree,&Ep); + tree=collapse_nodes(tree,&n_colours,n_entries,Ep); + + /* if (n_colours > n_entries) */ + /* do_progress(n_colours1 - n_colours); */ + } + /* del_progress(); */ + } + /* del_progress(); */ + /* fill palette */ + c=0; + fill_palette(tree,&c,pal,1); + if (fill_other) { + for (;c<256;c++) { + if (pal[c].r==255) + pal[c].b=pal[c].g=pal[c].r=0; + } + } + /* free memory used by tree */ + destroy_tree(tree); + return n_colours; +}