mirror of
https://github.com/aseprite/aseprite.git
synced 2025-01-28 00:35:30 +00:00
Added threads to load files in background.
Added a new file-selector (using PIDLs for Win32).
This commit is contained in:
parent
2aea148245
commit
528eaab937
33
ChangeLog
33
ChangeLog
@ -1,3 +1,36 @@
|
|||||||
|
2008-02-04 David A. Capello <dacap@users.sourceforge.net>
|
||||||
|
|
||||||
|
* src/dialogs/filesel.c: Done (navigation history added, and
|
||||||
|
file-type combo-box).
|
||||||
|
|
||||||
|
* src/core/file_system.c: Done the Allegro interface with
|
||||||
|
for_each_file.
|
||||||
|
|
||||||
|
2008-02-03 David A. Capello <dacap@users.sourceforge.net>
|
||||||
|
|
||||||
|
* src/jinete/jcombox.c (jcombobox_del_index): Fixed a memory leak.
|
||||||
|
(jcombobox_add_string): Added 'data' field for each item.
|
||||||
|
(jcombobox_get_data): Added.
|
||||||
|
|
||||||
|
* src/test/test_file_system.c: Added.
|
||||||
|
|
||||||
|
* src/core/file_system.c: All these days I was working in
|
||||||
|
this. The PIDL interface for Win32 is done.
|
||||||
|
|
||||||
|
2008-01-27 David A. Capello <dacap@users.sourceforge.net>
|
||||||
|
|
||||||
|
* src/commands/cmd_configure_screen.c (show_dialog): Added a
|
||||||
|
confirmation dialog after changing the gfx-mode.
|
||||||
|
|
||||||
|
2008-01-24 David A. Capello <dacap@users.sourceforge.net>
|
||||||
|
|
||||||
|
* src/modules/gui.c (rebuild_sprite_list): Removed.
|
||||||
|
|
||||||
|
* src/file/*.c: A lot of work to make it thread safe through the
|
||||||
|
new FileOp structure.
|
||||||
|
|
||||||
|
* src/raster/gfxobj.c: Added a mutex to be thread safe.
|
||||||
|
|
||||||
2008-01-23 David A. Capello <dacap@users.sourceforge.net>
|
2008-01-23 David A. Capello <dacap@users.sourceforge.net>
|
||||||
|
|
||||||
* src/widgets/editor/editor.c (show_drawing_cursor): Added the
|
* src/widgets/editor/editor.c (show_drawing_cursor): Added the
|
||||||
|
7
TODO.txt
7
TODO.txt
@ -1,10 +1,11 @@
|
|||||||
High priority work
|
High priority work
|
||||||
------------------
|
------------------
|
||||||
|
|
||||||
- the user_data of hook_signal should be void*.
|
|
||||||
- search for TODO;
|
- search for TODO;
|
||||||
- Problems:
|
- rename jcombox.c to jcombobox.c
|
||||||
- test UNDO in 64bits plataforms (reported by Jon Rafkind);
|
- fix a bug in the film editor when move the separator (panel) outside
|
||||||
|
the screen (to left or right)
|
||||||
|
- the user_data of hook_signal should be void*.
|
||||||
- ver por el nuevo load_font de Allegro.
|
- ver por el nuevo load_font de Allegro.
|
||||||
- complete palette operations, and palette editor (it needs a slider
|
- complete palette operations, and palette editor (it needs a slider
|
||||||
or something to move between palette changes);
|
or something to move between palette changes);
|
||||||
|
30
data/jids/filesel.jid
Normal file
30
data/jids/filesel.jid
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
<!-- ASE - Allegro Sprite Editor -->
|
||||||
|
<!-- Copyright (C) 2001-2005, 2007, 2008 by David A. Capello -->
|
||||||
|
|
||||||
|
<!-- Read "LEGAL.txt" for more information. -->
|
||||||
|
|
||||||
|
<window text="" name="file_selector">
|
||||||
|
<box vertical>
|
||||||
|
<box horizontal>
|
||||||
|
<box horizontal noborders>
|
||||||
|
<button text="" name="goback" bevel="2 0 2 0" />
|
||||||
|
<button text="" name="goforward" bevel="0 2 0 2" />
|
||||||
|
</box>
|
||||||
|
<button text="" name="goup" />
|
||||||
|
<combobox name="location" expansive />
|
||||||
|
</box>
|
||||||
|
<box vertical expansive name="box" />
|
||||||
|
<box horizontal>
|
||||||
|
<label text="Name:" />
|
||||||
|
<entry text="" maxsize=256 name="filename" expansive />
|
||||||
|
<combobox name="filetype" minwidth=70 />
|
||||||
|
</box>
|
||||||
|
<box horizontal>
|
||||||
|
<box horizontal expansive />
|
||||||
|
<box horizontal homogeneous>
|
||||||
|
<button text="&OK" name="ok" magnetic width="60" />
|
||||||
|
<button text="&Cancel" />
|
||||||
|
</box>
|
||||||
|
</box>
|
||||||
|
</box>
|
||||||
|
</window>
|
@ -1,5 +1,5 @@
|
|||||||
ASE Files (.ASE) Format description
|
ASE Files (.ASE) Format description
|
||||||
Copyright (C) 2004-2005, 2007 by David A. Capello
|
Copyright (C) 2004-2005, 2007, 2008 by David A. Capello
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
1. References
|
1. References
|
||||||
@ -19,7 +19,6 @@ BYTE An 8-bit unsigned integer value
|
|||||||
WORD A 16-bit unsigned integer value
|
WORD A 16-bit unsigned integer value
|
||||||
DWORD A 32-bit unsigned integer value
|
DWORD A 32-bit unsigned integer value
|
||||||
LONG A 32-bit signed integer value
|
LONG A 32-bit signed integer value
|
||||||
DOUBLE A 64-bit floating point value
|
|
||||||
BYTE[n] "n" bytes.
|
BYTE[n] "n" bytes.
|
||||||
RECT Four LONGs (in the order: x-pos, y-pos, width, heigth)
|
RECT Four LONGs (in the order: x-pos, y-pos, width, heigth)
|
||||||
STRING length=WORD (how many characters to read next)
|
STRING length=WORD (how many characters to read next)
|
||||||
@ -211,6 +210,7 @@ NOTE.1: The child level is used to show the relationship of this
|
|||||||
| `- Layer2 2
|
| `- Layer2 2
|
||||||
`- Layer3 1
|
`- Layer3 1
|
||||||
|
|
||||||
|
|
||||||
NOTE.2: The layer index is a number to identify any layer in the
|
NOTE.2: The layer index is a number to identify any layer in the
|
||||||
sprite, for example:
|
sprite, for example:
|
||||||
|
|
||||||
@ -223,6 +223,7 @@ NOTE.2: The layer index is a number to identify any layer in the
|
|||||||
| `- Layer2 4
|
| `- Layer2 4
|
||||||
`- Layer3 5
|
`- Layer3 5
|
||||||
|
|
||||||
|
|
||||||
NOTE.3: The raw pixel data is saved row by row from top to bottom, and
|
NOTE.3: The raw pixel data is saved row by row from top to bottom, and
|
||||||
each scanline is from pixel by pixel from left to right.
|
each scanline is from pixel by pixel from left to right.
|
||||||
In RGB images, each pixel have 4 bytes in the order R, G, B, A.
|
In RGB images, each pixel have 4 bytes in the order R, G, B, A.
|
||||||
|
11
makefile.gcc
11
makefile.gcc
@ -190,11 +190,15 @@ endif
|
|||||||
|
|
||||||
TESTS = $(addsuffix $(EXE), \
|
TESTS = $(addsuffix $(EXE), \
|
||||||
$(basename \
|
$(basename \
|
||||||
$(wildcard src/test/convmatr/*.c) \
|
$(wildcard src/test/*.c) \
|
||||||
$(wildcard src/test/raster/*.c) \
|
$(wildcard src/test/raster/*.c) \
|
||||||
$(wildcard src/test/jinete/*.c)))
|
$(wildcard src/test/jinete/*.c)))
|
||||||
|
|
||||||
src/test/convmatr/%$(EXE): src/test/convmatr/%.c $(COMMON_OBJS)
|
AUTOTESTS = $(addsuffix $(EXE), \
|
||||||
|
$(basename \
|
||||||
|
$(wildcard src/test/*.c)))
|
||||||
|
|
||||||
|
src/test/%$(EXE): src/test/%.c $(COMMON_OBJS)
|
||||||
$(CC) $(CFLAGS) -o $@ $^ $(LFLAGS) $(LFLAGS_LAST)
|
$(CC) $(CFLAGS) -o $@ $^ $(LFLAGS) $(LFLAGS_LAST)
|
||||||
|
|
||||||
src/test/raster/%$(EXE): src/test/raster/%.c $(COMMON_OBJS)
|
src/test/raster/%$(EXE): src/test/raster/%.c $(COMMON_OBJS)
|
||||||
@ -204,3 +208,6 @@ src/test/jinete/%$(EXE): src/test/jinete/%.c $(COMMON_OBJS)
|
|||||||
$(CC) $(CFLAGS) -o $@ $^ $(LFLAGS) $(LFLAGS_LAST)
|
$(CC) $(CFLAGS) -o $@ $^ $(LFLAGS) $(LFLAGS_LAST)
|
||||||
|
|
||||||
test: $(TESTS)
|
test: $(TESTS)
|
||||||
|
|
||||||
|
runtest:
|
||||||
|
@-$(foreach TEST, $(AUTOTESTS), ./$(TEST))
|
||||||
|
@ -79,6 +79,7 @@ COMMON_SOURCES = \
|
|||||||
src/core/config.c \
|
src/core/config.c \
|
||||||
src/core/core.c \
|
src/core/core.c \
|
||||||
src/core/dirs.c \
|
src/core/dirs.c \
|
||||||
|
src/core/file_system.c \
|
||||||
src/core/modules.c \
|
src/core/modules.c \
|
||||||
src/dialogs/canvasze.c \
|
src/dialogs/canvasze.c \
|
||||||
src/dialogs/colsel.c \
|
src/dialogs/colsel.c \
|
||||||
@ -148,6 +149,7 @@ COMMON_SOURCES = \
|
|||||||
src/jinete/jsystem.c \
|
src/jinete/jsystem.c \
|
||||||
src/jinete/jtextbox.c \
|
src/jinete/jtextbox.c \
|
||||||
src/jinete/jtheme.c \
|
src/jinete/jtheme.c \
|
||||||
|
src/jinete/jthread.c \
|
||||||
src/jinete/jview.c \
|
src/jinete/jview.c \
|
||||||
src/jinete/jwidget.c \
|
src/jinete/jwidget.c \
|
||||||
src/jinete/jwindow.c \
|
src/jinete/jwindow.c \
|
||||||
@ -206,6 +208,7 @@ COMMON_SOURCES = \
|
|||||||
src/widgets/editor/cursor.c \
|
src/widgets/editor/cursor.c \
|
||||||
src/widgets/editor/editor.c \
|
src/widgets/editor/editor.c \
|
||||||
src/widgets/editor/keys.c \
|
src/widgets/editor/keys.c \
|
||||||
|
src/widgets/fileview.c \
|
||||||
src/widgets/groupbut.c \
|
src/widgets/groupbut.c \
|
||||||
src/widgets/menuitem.c \
|
src/widgets/menuitem.c \
|
||||||
src/widgets/paledit.c \
|
src/widgets/paledit.c \
|
||||||
@ -215,6 +218,11 @@ COMMON_SOURCES = \
|
|||||||
src/widgets/target.c \
|
src/widgets/target.c \
|
||||||
src/widgets/toolbar.c
|
src/widgets/toolbar.c
|
||||||
|
|
||||||
|
ifdef WIN32
|
||||||
|
COMMON_SOURCES += src/core/file_system_win32.c
|
||||||
|
else
|
||||||
|
endif
|
||||||
|
|
||||||
ifdef USE_X86_INT_MULT
|
ifdef USE_X86_INT_MULT
|
||||||
COMMON_SOURCES += src/raster/x86/int_mult.s
|
COMMON_SOURCES += src/raster/x86/int_mult.s
|
||||||
endif
|
endif
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
# Copyright (C) 2001-2005, 2007 by David A. Capello -*-Makefile-*-
|
# Copyright (C) 2001-2005, 2007, 2008 by David A. Capello -*-Makefile-*-
|
||||||
|
|
||||||
ifndef CONFIGURED
|
ifndef CONFIGURED
|
||||||
include makefile.cfg
|
include makefile.cfg
|
||||||
@ -14,8 +14,9 @@ endif
|
|||||||
######################################################################
|
######################################################################
|
||||||
# Flags for MinGW
|
# Flags for MinGW
|
||||||
|
|
||||||
|
# CFLAGS = -D_WIN32_WINNT=0x0500
|
||||||
CFLAGS =
|
CFLAGS =
|
||||||
LFLAGS = -mwindows
|
LFLAGS = -mwindows -lshlwapi
|
||||||
ifdef DEBUGMODE
|
ifdef DEBUGMODE
|
||||||
LFLAGS_LAST = -lalld
|
LFLAGS_LAST = -lalld
|
||||||
else
|
else
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#! /bin/sh
|
#! /bin/sh
|
||||||
|
|
||||||
find data/scripts jinete src third_party \
|
find data/scripts src third_party \
|
||||||
\( -name '*.[ch]' -o \
|
\( -name '*.[ch]' -o \
|
||||||
-name '*.lua' \) -print | \
|
-name '*.lua' \) -print | \
|
||||||
sed -e "/_old/D" | \
|
sed -e "/_old/D" | \
|
||||||
|
@ -93,23 +93,23 @@ static void show_dialog(void)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
jcombobox_add_string(resolution, "320x200");
|
jcombobox_add_string(resolution, "320x200", NULL);
|
||||||
jcombobox_add_string(resolution, "320x240");
|
jcombobox_add_string(resolution, "320x240", NULL);
|
||||||
jcombobox_add_string(resolution, "640x400");
|
jcombobox_add_string(resolution, "640x400", NULL);
|
||||||
jcombobox_add_string(resolution, "640x480");
|
jcombobox_add_string(resolution, "640x480", NULL);
|
||||||
jcombobox_add_string(resolution, "800x600");
|
jcombobox_add_string(resolution, "800x600", NULL);
|
||||||
jcombobox_add_string(resolution, "1024x768");
|
jcombobox_add_string(resolution, "1024x768", NULL);
|
||||||
|
|
||||||
jcombobox_add_string(color_depth, _("8 bpp (256 colors)"));
|
jcombobox_add_string(color_depth, _("8 bpp (256 colors)"), NULL);
|
||||||
jcombobox_add_string(color_depth, _("15 bpp (32K colors)"));
|
jcombobox_add_string(color_depth, _("15 bpp (32K colors)"), NULL);
|
||||||
jcombobox_add_string(color_depth, _("16 bpp (64K colors)"));
|
jcombobox_add_string(color_depth, _("16 bpp (64K colors)"), NULL);
|
||||||
jcombobox_add_string(color_depth, _("24 bpp (16M colors)"));
|
jcombobox_add_string(color_depth, _("24 bpp (16M colors)"), NULL);
|
||||||
jcombobox_add_string(color_depth, _("32 bpp (16M colors)"));
|
jcombobox_add_string(color_depth, _("32 bpp (16M colors)"), NULL);
|
||||||
|
|
||||||
jcombobox_add_string(pixel_scale, "x1 (normal)");
|
jcombobox_add_string(pixel_scale, _("x1 (normal)"), NULL);
|
||||||
jcombobox_add_string(pixel_scale, "x2 (double)");
|
jcombobox_add_string(pixel_scale, _("x2 (double)"), NULL);
|
||||||
jcombobox_add_string(pixel_scale, "x3 (big)");
|
jcombobox_add_string(pixel_scale, _("x3 (big)"), NULL);
|
||||||
jcombobox_add_string(pixel_scale, "x4 (huge)");
|
jcombobox_add_string(pixel_scale, _("x4 (huge)"), NULL);
|
||||||
|
|
||||||
usprintf(buf, "%dx%d", old_w, old_h);
|
usprintf(buf, "%dx%d", old_w, old_h);
|
||||||
jcombobox_select_string(resolution, buf);
|
jcombobox_select_string(resolution, buf);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/* ASE - Allegro Sprite Editor
|
/* ASE - Allegro Sprite Editor
|
||||||
* Copyright (C) 2007 David A. Capello
|
* Copyright (C) 2007, 2008 David A. Capello
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -42,7 +42,7 @@ static void cmd_load_mask_execute(const char *argument)
|
|||||||
{
|
{
|
||||||
/* get current sprite */
|
/* get current sprite */
|
||||||
Sprite *sprite = current_sprite;
|
Sprite *sprite = current_sprite;
|
||||||
char *filename = GUI_FileSelect(_("Load .msk File"), "", "msk");
|
char *filename = ase_file_selector(_("Load .msk File"), "", "msk");
|
||||||
if (filename) {
|
if (filename) {
|
||||||
Mask *mask = load_msk_file(filename);
|
Mask *mask = load_msk_file(filename);
|
||||||
if (!mask) {
|
if (!mask) {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/* ASE - Allegro Sprite Editor
|
/* ASE - Allegro Sprite Editor
|
||||||
* Copyright (C) 2007 David A. Capello
|
* Copyright (C) 2007, 2008 David A. Capello
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -20,23 +20,98 @@
|
|||||||
|
|
||||||
#ifndef USE_PRECOMPILED_HEADER
|
#ifndef USE_PRECOMPILED_HEADER
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "jinete/jinete.h"
|
||||||
|
|
||||||
#include "commands/commands.h"
|
#include "commands/commands.h"
|
||||||
|
#include "console/console.h"
|
||||||
|
#include "core/app.h"
|
||||||
#include "dialogs/filesel.h"
|
#include "dialogs/filesel.h"
|
||||||
#include "file/file.h"
|
#include "file/file.h"
|
||||||
#include "raster/sprite.h"
|
#include "raster/sprite.h"
|
||||||
|
#include "modules/editors.h"
|
||||||
|
#include "modules/gui.h"
|
||||||
#include "modules/recent.h"
|
#include "modules/recent.h"
|
||||||
#include "modules/sprites.h"
|
#include "modules/sprites.h"
|
||||||
|
#include "widgets/statebar.h"
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
typedef struct OpenFileData
|
||||||
|
{
|
||||||
|
FileOp *fop;
|
||||||
|
Progress *progress;
|
||||||
|
} OpenFileData;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Thread to do the hard work: load the file from the disk.
|
||||||
|
*
|
||||||
|
* [loading thread]
|
||||||
|
*/
|
||||||
|
static void bg_open_file(void *fop_data)
|
||||||
|
{
|
||||||
|
FileOp *fop = (FileOp *)fop_data;
|
||||||
|
fop_operate(fop);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called by the gui-monitor (a timer in the gui module that is called
|
||||||
|
* every 100 milliseconds).
|
||||||
|
*
|
||||||
|
* [main thread]
|
||||||
|
*/
|
||||||
|
static bool bg_monitor_fop(void *_data)
|
||||||
|
{
|
||||||
|
OpenFileData *data = (OpenFileData *)_data;
|
||||||
|
FileOp *fop = (FileOp *)data->fop;
|
||||||
|
|
||||||
|
if (data->progress)
|
||||||
|
progress_update(data->progress, fop_get_progress(fop));
|
||||||
|
|
||||||
|
/* is done? ...ok, now the sprite is in the main thread only... */
|
||||||
|
if (fop_is_done(fop)) {
|
||||||
|
Sprite *sprite = fop->sprite;
|
||||||
|
if (sprite) {
|
||||||
|
recent_file(fop->filename);
|
||||||
|
sprite_mount(sprite);
|
||||||
|
sprite_show(sprite);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
unrecent_file(fop->filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data->progress)
|
||||||
|
progress_free(data->progress);
|
||||||
|
|
||||||
|
if (fop->error) {
|
||||||
|
console_open();
|
||||||
|
console_printf(fop->error);
|
||||||
|
console_close();
|
||||||
|
}
|
||||||
|
|
||||||
|
fop_free(fop);
|
||||||
|
jfree(data);
|
||||||
|
return TRUE; /* done */
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return FALSE; /* work isn't yet */
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Command to open a file.
|
||||||
|
*
|
||||||
|
* [main thread]
|
||||||
|
*/
|
||||||
static void cmd_open_file_execute(const char *argument)
|
static void cmd_open_file_execute(const char *argument)
|
||||||
{
|
{
|
||||||
char *filename;
|
char *filename;
|
||||||
|
|
||||||
/* interactive */
|
/* interactive */
|
||||||
if (!argument) {
|
if (!argument) {
|
||||||
filename = GUI_FileSelect(_("Open Sprite"), "",
|
char exts[4096];
|
||||||
get_readable_extensions());
|
get_readable_extensions(exts, sizeof(exts));
|
||||||
|
filename = ase_file_selector(_("Open Sprite"), "", exts);
|
||||||
}
|
}
|
||||||
/* load the file specified in the argument */
|
/* load the file specified in the argument */
|
||||||
else {
|
else {
|
||||||
@ -44,18 +119,38 @@ static void cmd_open_file_execute(const char *argument)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (filename) {
|
if (filename) {
|
||||||
Sprite *sprite = sprite_load(filename);
|
FileOp *fop = fop_to_load_sprite(filename);
|
||||||
if (sprite) {
|
|
||||||
recent_file(filename);
|
|
||||||
sprite_mount(sprite);
|
|
||||||
sprite_show(sprite);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
unrecent_file(filename);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (filename != argument)
|
if (filename != argument)
|
||||||
jfree(filename);
|
jfree(filename);
|
||||||
|
|
||||||
|
if (fop) {
|
||||||
|
if (fop->error) {
|
||||||
|
console_printf(fop->error);
|
||||||
|
fop_free(fop);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
JThread thread = jthread_new(bg_open_file, fop);
|
||||||
|
if (thread) {
|
||||||
|
OpenFileData *data = jnew(OpenFileData, 1);
|
||||||
|
|
||||||
|
data->fop = fop;
|
||||||
|
|
||||||
|
/* add the progress bar */
|
||||||
|
if (app_get_status_bar())
|
||||||
|
data->progress = progress_new(app_get_status_bar());
|
||||||
|
else
|
||||||
|
data->progress = NULL;
|
||||||
|
|
||||||
|
/* add a monitor to check the loading (FileOp) progress */
|
||||||
|
add_gui_monitor(bg_monitor_fop, data);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
console_printf(_("Error creating thread to load the sprite"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* else do nothing (the user canceled or something like that) */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/* ASE - Allegro Sprite Editor
|
/* ASE - Allegro Sprite Editor
|
||||||
* Copyright (C) 2007 David A. Capello
|
* Copyright (C) 2007, 2008 David A. Capello
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -20,14 +20,18 @@
|
|||||||
|
|
||||||
#ifndef USE_PRECOMPILED_HEADER
|
#ifndef USE_PRECOMPILED_HEADER
|
||||||
|
|
||||||
|
#include <allegro.h>
|
||||||
|
|
||||||
#include "jinete/jbase.h"
|
#include "jinete/jbase.h"
|
||||||
|
|
||||||
#include "commands/commands.h"
|
#include "commands/commands.h"
|
||||||
|
#include "core/app.h"
|
||||||
#include "console/console.h"
|
#include "console/console.h"
|
||||||
#include "file/file.h"
|
#include "file/file.h"
|
||||||
#include "modules/recent.h"
|
#include "modules/recent.h"
|
||||||
#include "modules/sprites.h"
|
#include "modules/sprites.h"
|
||||||
#include "raster/sprite.h"
|
#include "raster/sprite.h"
|
||||||
|
#include "widgets/statebar.h"
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -44,12 +48,15 @@ static void cmd_save_file_execute(const char *argument)
|
|||||||
if (sprite_save(current_sprite) == 0) {
|
if (sprite_save(current_sprite) == 0) {
|
||||||
recent_file(current_sprite->filename);
|
recent_file(current_sprite->filename);
|
||||||
sprite_mark_as_saved(current_sprite);
|
sprite_mark_as_saved(current_sprite);
|
||||||
|
|
||||||
|
if (app_get_status_bar())
|
||||||
|
status_bar_set_text(app_get_status_bar(),
|
||||||
|
1000, "File %s, saved.",
|
||||||
|
get_filename(current_sprite->filename));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
/* TODO if the user cancel we shouldn't unrecent the file */
|
||||||
unrecent_file(current_sprite->filename);
|
unrecent_file(current_sprite->filename);
|
||||||
console_printf("%s: %s",
|
|
||||||
_("Error saving sprite file"),
|
|
||||||
current_sprite->filename);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* if the sprite isn't associated to a file, we must to show the
|
/* if the sprite isn't associated to a file, we must to show the
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/* ASE - Allegro Sprite Editor
|
/* ASE - Allegro Sprite Editor
|
||||||
* Copyright (C) 2007 David A. Capello
|
* Copyright (C) 2007, 2008 David A. Capello
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -26,7 +26,7 @@
|
|||||||
|
|
||||||
#include "commands/commands.h"
|
#include "commands/commands.h"
|
||||||
#include "console/console.h"
|
#include "console/console.h"
|
||||||
/* #include "core/app.h" */
|
#include "core/app.h"
|
||||||
#include "dialogs/filesel.h"
|
#include "dialogs/filesel.h"
|
||||||
#include "file/file.h"
|
#include "file/file.h"
|
||||||
#include "modules/recent.h"
|
#include "modules/recent.h"
|
||||||
@ -44,14 +44,15 @@ static bool cmd_save_file_as_enabled(const char *argument)
|
|||||||
static void cmd_save_file_as_execute(const char *argument)
|
static void cmd_save_file_as_execute(const char *argument)
|
||||||
{
|
{
|
||||||
char filename[4096];
|
char filename[4096];
|
||||||
|
char exts[4096];
|
||||||
char *newfilename;
|
char *newfilename;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ustrcpy(filename, current_sprite->filename);
|
ustrcpy(filename, current_sprite->filename);
|
||||||
|
get_writable_extensions(exts, sizeof(exts));
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
newfilename = GUI_FileSelect(_("Save Sprite"), filename,
|
newfilename = ase_file_selector(_("Save Sprite"), filename, exts);
|
||||||
get_writable_extensions());
|
|
||||||
if (!newfilename)
|
if (!newfilename)
|
||||||
return;
|
return;
|
||||||
ustrcpy(filename, newfilename);
|
ustrcpy(filename, newfilename);
|
||||||
@ -80,17 +81,15 @@ static void cmd_save_file_as_execute(const char *argument)
|
|||||||
}
|
}
|
||||||
|
|
||||||
sprite_set_filename(current_sprite, filename);
|
sprite_set_filename(current_sprite, filename);
|
||||||
rebuild_sprite_list();
|
app_realloc_sprite_list();
|
||||||
|
|
||||||
if (sprite_save(current_sprite) == 0) {
|
if (sprite_save(current_sprite) == 0) {
|
||||||
recent_file(filename);
|
recent_file(filename);
|
||||||
sprite_mark_as_saved(current_sprite);
|
sprite_mark_as_saved(current_sprite);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
/* TODO if the user cancel we shouldn't unrecent the file */
|
||||||
unrecent_file(filename);
|
unrecent_file(filename);
|
||||||
console_printf("%s: %s",
|
|
||||||
_("Error saving sprite file"),
|
|
||||||
filename);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/* ASE - Allegro Sprite Editor
|
/* ASE - Allegro Sprite Editor
|
||||||
* Copyright (C) 2007 David A. Capello
|
* Copyright (C) 2007, 2008 David A. Capello
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -50,7 +50,7 @@ static void cmd_save_mask_execute(const char *argument)
|
|||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
char *filename = GUI_FileSelect(_("Save .msk File"), filename, "msk");
|
char *filename = ase_file_selector(_("Save .msk File"), filename, "msk");
|
||||||
if (!filename)
|
if (!filename)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -171,36 +171,3 @@ void user_printf(const char *format, ...)
|
|||||||
/* else */
|
/* else */
|
||||||
allegro_message(buf);
|
allegro_message(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
void do_progress(int progress)
|
|
||||||
{
|
|
||||||
JWidget status_bar = app_get_status_bar();
|
|
||||||
|
|
||||||
if (status_bar) {
|
|
||||||
status_bar_do_progress(status_bar, progress);
|
|
||||||
|
|
||||||
jwidget_flush_redraw(status_bar);
|
|
||||||
jmanager_dispatch_messages(ji_get_default_manager());
|
|
||||||
gui_feedback();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void add_progress(int max)
|
|
||||||
{
|
|
||||||
JWidget status_bar = app_get_status_bar();
|
|
||||||
|
|
||||||
if (status_bar)
|
|
||||||
status_bar_add_progress(status_bar, max);
|
|
||||||
|
|
||||||
jmouse_hide();
|
|
||||||
}
|
|
||||||
|
|
||||||
void del_progress(void)
|
|
||||||
{
|
|
||||||
JWidget status_bar = app_get_status_bar();
|
|
||||||
|
|
||||||
if (status_bar)
|
|
||||||
status_bar_del_progress(status_bar);
|
|
||||||
|
|
||||||
jmouse_show();
|
|
||||||
}
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/* ASE - Allegro Sprite Editor
|
/* ASE - Allegro Sprite Editor
|
||||||
* Copyright (C) 2001-2005, 2007 David A. Capello
|
* Copyright (C) 2001-2005, 2007, 2008 David A. Capello
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -25,8 +25,4 @@ void console_close(void);
|
|||||||
void console_printf(const char *format, ...);
|
void console_printf(const char *format, ...);
|
||||||
void user_printf(const char *format, ...);
|
void user_printf(const char *format, ...);
|
||||||
|
|
||||||
void do_progress(int progress);
|
|
||||||
void add_progress(int max);
|
|
||||||
void del_progress(void);
|
|
||||||
|
|
||||||
#endif /* CONSOLE_H */
|
#endif /* CONSOLE_H */
|
||||||
|
140
src/core/app.c
140
src/core/app.c
@ -37,6 +37,7 @@
|
|||||||
#include "core/app.h"
|
#include "core/app.h"
|
||||||
#include "core/cfg.h"
|
#include "core/cfg.h"
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
|
#include "core/file_system.h"
|
||||||
#include "core/modules.h"
|
#include "core/modules.h"
|
||||||
#include "dialogs/options.h"
|
#include "dialogs/options.h"
|
||||||
#include "dialogs/tips.h"
|
#include "dialogs/tips.h"
|
||||||
@ -99,7 +100,7 @@ static Option *option_new(int type, const char *data);
|
|||||||
static void option_free(Option *option);
|
static void option_free(Option *option);
|
||||||
|
|
||||||
/* install and load all initial stuff */
|
/* install and load all initial stuff */
|
||||||
int app_init(int argc, char *argv[])
|
bool app_init(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
exe_name = argv[0];
|
exe_name = argv[0];
|
||||||
|
|
||||||
@ -107,11 +108,15 @@ int app_init(int argc, char *argv[])
|
|||||||
intl_init();
|
intl_init();
|
||||||
|
|
||||||
/* install the `core' of ASE application */
|
/* install the `core' of ASE application */
|
||||||
if (core_init() < 0) {
|
if (!core_init()) {
|
||||||
user_printf(_("ASE core initialization error.\n"));
|
user_printf(_("ASE core initialization error.\n"));
|
||||||
return -1;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* install the file-system access module */
|
||||||
|
if (!file_system_init())
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
/* init configuration */
|
/* init configuration */
|
||||||
ase_config_init();
|
ase_config_init();
|
||||||
|
|
||||||
@ -120,16 +125,21 @@ int app_init(int argc, char *argv[])
|
|||||||
|
|
||||||
/* search options in the arguments */
|
/* search options in the arguments */
|
||||||
if (check_args(argc, argv) < 0)
|
if (check_args(argc, argv) < 0)
|
||||||
return -1;
|
return FALSE;
|
||||||
|
|
||||||
/* GUI is the default mode */
|
/* GUI is the default mode */
|
||||||
if (!(ase_mode & MODE_BATCH))
|
if (!(ase_mode & MODE_BATCH))
|
||||||
ase_mode |= MODE_GUI;
|
ase_mode |= MODE_GUI;
|
||||||
|
|
||||||
|
/* install 'raster' stuff */
|
||||||
|
if (!gfxobj_init()) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
/* install the modules */
|
/* install the modules */
|
||||||
if (modules_init (ase_mode & MODE_GUI ? REQUIRE_INTERFACE:
|
if (!modules_init(ase_mode & MODE_GUI ? REQUIRE_INTERFACE:
|
||||||
REQUIRE_SCRIPTING) < 0)
|
REQUIRE_SCRIPTING))
|
||||||
return -1;
|
return FALSE;
|
||||||
|
|
||||||
_ji_font_init();
|
_ji_font_init();
|
||||||
|
|
||||||
@ -145,7 +155,7 @@ int app_init(int argc, char *argv[])
|
|||||||
set_gfx_mode(GFX_TEXT, 0, 0, 0, 0);
|
set_gfx_mode(GFX_TEXT, 0, 0, 0, 0);
|
||||||
console_printf(_("Error loading default palette from `%s'\n"),
|
console_printf(_("Error loading default palette from `%s'\n"),
|
||||||
palette_filename);
|
palette_filename);
|
||||||
return -1;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
destroy_bitmap(bmp);
|
destroy_bitmap(bmp);
|
||||||
@ -157,7 +167,7 @@ int app_init(int argc, char *argv[])
|
|||||||
set_current_palette(NULL, TRUE);
|
set_current_palette(NULL, TRUE);
|
||||||
|
|
||||||
/* ok */
|
/* ok */
|
||||||
return 0;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* runs ASE main dialog */
|
/* runs ASE main dialog */
|
||||||
@ -335,7 +345,9 @@ void app_exit(void)
|
|||||||
|
|
||||||
/* finalize modules, configuration and core */
|
/* finalize modules, configuration and core */
|
||||||
modules_exit();
|
modules_exit();
|
||||||
|
gfxobj_exit();
|
||||||
ase_config_exit();
|
ase_config_exit();
|
||||||
|
file_system_exit();
|
||||||
core_exit();
|
core_exit();
|
||||||
_ji_font_exit();
|
_ji_font_exit();
|
||||||
|
|
||||||
@ -364,15 +376,10 @@ void app_refresh_screen(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* updates the sprites list menu. WARNING!: This routine can't be used
|
|
||||||
when a menu callback was called, because, it destroy some menus,
|
|
||||||
you should use rebuild_sprite_list() instead (src/gui/gui.c) */
|
|
||||||
void app_realloc_sprite_list(void)
|
void app_realloc_sprite_list(void)
|
||||||
{
|
{
|
||||||
Sprite *sprite;
|
Sprite *sprite;
|
||||||
JLink link;
|
JLink link;
|
||||||
#if 1
|
|
||||||
PRINTF("Reallocating sprite list...\n");
|
|
||||||
|
|
||||||
/* insert all other sprites */
|
/* insert all other sprites */
|
||||||
JI_LIST_FOR_EACH(get_sprite_list(), link) {
|
JI_LIST_FOR_EACH(get_sprite_list(), link) {
|
||||||
@ -381,115 +388,26 @@ void app_realloc_sprite_list(void)
|
|||||||
get_filename(sprite->filename),
|
get_filename(sprite->filename),
|
||||||
sprite);
|
sprite);
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
JWidget list_menuitem = get_sprite_list_menuitem();
|
|
||||||
JWidget menuitem;
|
|
||||||
|
|
||||||
PRINTF("Reallocating sprite list...\n");
|
|
||||||
|
|
||||||
/* update the sprite-list menu */
|
|
||||||
if (list_menuitem) {
|
|
||||||
Command *cmd_select_file = command_get_by_name(CMD_SELECT_FILE);
|
|
||||||
Sprite *clipboard = get_clipboard_sprite();
|
|
||||||
JWidget submenu;
|
|
||||||
char buf[256];
|
|
||||||
int c, count = 0;
|
|
||||||
|
|
||||||
submenu = jmenuitem_get_submenu(list_menuitem);
|
|
||||||
if (submenu) {
|
|
||||||
jmenuitem_set_submenu(list_menuitem, NULL);
|
|
||||||
jwidget_free(submenu);
|
|
||||||
}
|
|
||||||
|
|
||||||
submenu = jmenu_new();
|
|
||||||
jmenuitem_set_submenu(list_menuitem, submenu);
|
|
||||||
|
|
||||||
/* for `null' */
|
|
||||||
menuitem = menuitem_new(_("Nothing"), cmd_select_file, NULL);
|
|
||||||
|
|
||||||
/* if (!current_sprite) */
|
|
||||||
/* jwidget_select(menuitem); */
|
|
||||||
|
|
||||||
jwidget_add_child(submenu, menuitem);
|
|
||||||
count++;
|
|
||||||
|
|
||||||
/* for `clipboard' */
|
|
||||||
if (clipboard)
|
|
||||||
usprintf(buf, "%d", clipboard->gfxobj.id);
|
|
||||||
|
|
||||||
menuitem = menuitem_new(_("Clipboard"), cmd_select_file,
|
|
||||||
clipboard ? buf: "0");
|
|
||||||
|
|
||||||
/* if (!clipboard) */
|
|
||||||
/* jwidget_disable(menuitem); */
|
|
||||||
/* else if (current_sprite == clipboard) */
|
|
||||||
/* jwidget_select(menuitem); */
|
|
||||||
|
|
||||||
jwidget_add_child(submenu, menuitem);
|
|
||||||
count++;
|
|
||||||
|
|
||||||
/* insert a separator */
|
|
||||||
|
|
||||||
c = 0;
|
|
||||||
JI_LIST_FOR_EACH(get_sprite_list(), link) {
|
|
||||||
if (link->data == clipboard)
|
|
||||||
continue;
|
|
||||||
c++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (c > 0) {
|
|
||||||
jwidget_add_child(submenu, ji_separator_new(NULL, JI_HORIZONTAL));
|
|
||||||
count++;
|
|
||||||
|
|
||||||
/* insert all other sprites */
|
|
||||||
JI_LIST_FOR_EACH(get_sprite_list(), link) {
|
|
||||||
sprite = link->data;
|
|
||||||
|
|
||||||
if (sprite == clipboard)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/* `count' limit -- TODO how I know the height of menu-items? */
|
|
||||||
/* if (count >= SCREEN_H/(text_height (font)+4)-2) { */
|
|
||||||
if (count >= 14) {
|
|
||||||
menuitem = menuitem_new(_("More"), NULL, NULL);
|
|
||||||
jwidget_add_child(submenu, menuitem);
|
|
||||||
|
|
||||||
submenu = jmenu_new();
|
|
||||||
jmenuitem_set_submenu(menuitem, submenu);
|
|
||||||
count = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
usprintf(buf, "%d", sprite->gfxobj.id);
|
|
||||||
|
|
||||||
menuitem = menuitem_new(get_filename(sprite->filename),
|
|
||||||
cmd_select_file, buf);
|
|
||||||
|
|
||||||
if (current_sprite == sprite)
|
|
||||||
jwidget_select(menuitem);
|
|
||||||
|
|
||||||
jwidget_add_child(submenu, menuitem);
|
|
||||||
count++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* updates the recent list menu. WARNING!: This routine can't be used
|
/* updates the recent list menu. WARNING!: This routine can't be used
|
||||||
when a menu callback was called, because, it destroy the menus,
|
when a menu callback was called, because, it destroy the menus,
|
||||||
you should use rebuild_recent_list() instead (src/gui/gui.c). */
|
you should use rebuild_recent_list() instead (src/gui/gui.c). */
|
||||||
void app_realloc_recent_list(void)
|
bool app_realloc_recent_list(void)
|
||||||
{
|
{
|
||||||
JWidget list_menuitem = get_recent_list_menuitem();
|
JWidget list_menuitem = get_recent_list_menuitem();
|
||||||
JWidget menuitem;
|
JWidget menuitem;
|
||||||
|
|
||||||
PRINTF("Reallocating recent list...\n");
|
|
||||||
|
|
||||||
/* update the recent file list menu item */
|
/* update the recent file list menu item */
|
||||||
if (list_menuitem) {
|
if (list_menuitem) {
|
||||||
Command *cmd_open_file = command_get_by_name(CMD_OPEN_FILE);
|
Command *cmd_open_file;
|
||||||
JWidget submenu;
|
JWidget submenu;
|
||||||
|
|
||||||
|
if (jmenuitem_has_submenu_opened(list_menuitem))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
cmd_open_file = command_get_by_name(CMD_OPEN_FILE);
|
||||||
|
|
||||||
submenu = jmenuitem_get_submenu(list_menuitem);
|
submenu = jmenuitem_get_submenu(list_menuitem);
|
||||||
if (submenu) {
|
if (submenu) {
|
||||||
jmenuitem_set_submenu(list_menuitem, NULL);
|
jmenuitem_set_submenu(list_menuitem, NULL);
|
||||||
@ -518,6 +436,8 @@ void app_realloc_recent_list(void)
|
|||||||
jwidget_add_child(submenu, menuitem);
|
jwidget_add_child(submenu, menuitem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
int app_get_current_image_type(void)
|
int app_get_current_image_type(void)
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/* ASE - Allegro Sprite Editor
|
/* ASE - Allegro Sprite Editor
|
||||||
* Copyright (C) 2001-2005, 2007 David A. Capello
|
* Copyright (C) 2001-2005, 2007, 2008 David A. Capello
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -21,14 +21,14 @@
|
|||||||
|
|
||||||
#include "jinete/jbase.h"
|
#include "jinete/jbase.h"
|
||||||
|
|
||||||
int app_init(int argc, char *argv[]);
|
bool app_init(int argc, char *argv[]);
|
||||||
void app_loop(void);
|
void app_loop(void);
|
||||||
void app_exit(void);
|
void app_exit(void);
|
||||||
|
|
||||||
void app_refresh_screen(void);
|
void app_refresh_screen(void);
|
||||||
|
|
||||||
void app_realloc_sprite_list(void);
|
void app_realloc_sprite_list(void);
|
||||||
void app_realloc_recent_list(void);
|
bool app_realloc_recent_list(void);
|
||||||
|
|
||||||
int app_get_current_image_type(void);
|
int app_get_current_image_type(void);
|
||||||
|
|
||||||
|
@ -51,7 +51,7 @@ static char *log_filename = NULL;
|
|||||||
static FILE *log_fileptr = NULL;
|
static FILE *log_fileptr = NULL;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int core_init(void)
|
bool core_init(void)
|
||||||
{
|
{
|
||||||
#ifdef NEED_LOG
|
#ifdef NEED_LOG
|
||||||
char buf[512];
|
char buf[512];
|
||||||
@ -71,7 +71,7 @@ int core_init(void)
|
|||||||
dirs_free(dirs);
|
dirs_free(dirs);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return 0;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void core_exit(void)
|
void core_exit(void)
|
||||||
@ -121,5 +121,5 @@ void verbose_printf(const char *format, ...)
|
|||||||
|
|
||||||
bool is_interactive(void)
|
bool is_interactive(void)
|
||||||
{
|
{
|
||||||
return ase_mode & MODE_GUI;
|
return ase_mode & MODE_GUI ? TRUE: FALSE;
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/* ASE - Allegro Sprite Editor
|
/* ASE - Allegro Sprite Editor
|
||||||
* Copyright (C) 2001-2005, 2007 David A. Capello
|
* Copyright (C) 2001-2005, 2007, 2008 David A. Capello
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -30,7 +30,7 @@ enum {
|
|||||||
|
|
||||||
extern int ase_mode;
|
extern int ase_mode;
|
||||||
|
|
||||||
int core_init(void);
|
bool core_init(void);
|
||||||
void core_exit(void);
|
void core_exit(void);
|
||||||
|
|
||||||
void verbose_printf(const char *format, ...);
|
void verbose_printf(const char *format, ...);
|
||||||
|
946
src/core/file_system.c
Normal file
946
src/core/file_system.c
Normal file
@ -0,0 +1,946 @@
|
|||||||
|
/* ASE - Allegro Sprite Editor
|
||||||
|
* Copyright (C) 2001-2005, 2007, 2008 David A. Capello
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Some of the original code to handle PIDLs come from the
|
||||||
|
MiniExplorer example of the Vaca library:
|
||||||
|
http://vaca.sourceforge.net/
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <allegro.h>
|
||||||
|
|
||||||
|
#if defined ALLEGRO_WINDOWS
|
||||||
|
# define USE_PIDLS
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined ALLEGRO_UNIX || defined ALLEGRO_DJGPP || defined ALLEGRO_MINGW32
|
||||||
|
# include <sys/stat.h>
|
||||||
|
#endif
|
||||||
|
#if defined ALLEGRO_UNIX || defined ALLEGRO_MINGW32
|
||||||
|
# include <sys/unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined USE_PIDLS
|
||||||
|
# define COBJMACROS
|
||||||
|
# include <winalleg.h>
|
||||||
|
# include <shlobj.h>
|
||||||
|
# include <shlwapi.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "jinete/jlist.h"
|
||||||
|
#include "jinete/jfilesel.h"
|
||||||
|
|
||||||
|
#include "core/file_system.h"
|
||||||
|
#include "util/hash.h"
|
||||||
|
|
||||||
|
#ifdef USE_PIDLS /* using Win32 Shell (PIDLs) */
|
||||||
|
|
||||||
|
#define IS_FOLDER(fi) \
|
||||||
|
(((fi)->attrib & SFGAO_FOLDER) == SFGAO_FOLDER)
|
||||||
|
|
||||||
|
#else /* using Allegro (for_each_file) */
|
||||||
|
|
||||||
|
#define IS_FOLDER(fi) \
|
||||||
|
(((fi)->attrib & FA_DIREC) == FA_DIREC)
|
||||||
|
|
||||||
|
#if (DEVICE_SEPARATOR != 0) && (DEVICE_SEPARATOR != '\0')
|
||||||
|
# define HAVE_DRIVES
|
||||||
|
#else
|
||||||
|
# define CASE_SENSITIVE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef FA_ALL
|
||||||
|
#define FA_ALL FA_RDONLY | FA_DIREC | FA_ARCH | FA_HIDDEN | FA_SYSTEM
|
||||||
|
#endif
|
||||||
|
#define FA_TO_SHOW FA_RDONLY | FA_DIREC | FA_ARCH | FA_SYSTEM
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* a position in the file-system */
|
||||||
|
struct FileItem
|
||||||
|
{
|
||||||
|
char *filename;
|
||||||
|
char *displayname;
|
||||||
|
FileItem *parent;
|
||||||
|
JList children;
|
||||||
|
int last_update;
|
||||||
|
#ifdef USE_PIDLS
|
||||||
|
LPITEMIDLIST pidl; /* relative to parent */
|
||||||
|
LPITEMIDLIST fullpidl; /* relative to the Desktop folder
|
||||||
|
(like a full path-name, because the
|
||||||
|
desktop is the root on Windows) */
|
||||||
|
SFGAOF attrib;
|
||||||
|
#else
|
||||||
|
char *keyname;
|
||||||
|
int attrib;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
/* the root of the file-system */
|
||||||
|
static FileItem *rootitem = NULL;
|
||||||
|
static HashTable *hash_fileitems = NULL;
|
||||||
|
|
||||||
|
#ifdef USE_PIDLS
|
||||||
|
static LPMALLOC shl_imalloc = NULL;
|
||||||
|
static IShellFolder *shl_idesktop = NULL;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* local auxiliary routines */
|
||||||
|
static FileItem *fileitem_new(FileItem *parent);
|
||||||
|
static void fileitem_free(FileItem *fileitem);
|
||||||
|
static void fileitem_insert_child_sorted(FileItem *fileitem, FileItem *child);
|
||||||
|
static int fileitem_cmp(FileItem *fi1, FileItem *fi2);
|
||||||
|
|
||||||
|
/* a more easy PIDLs interface (without using the SH* & IL* routines of W2K) */
|
||||||
|
#ifdef USE_PIDLS
|
||||||
|
static void update_by_pidl(FileItem *fileitem);
|
||||||
|
static LPITEMIDLIST concat_pidl(LPITEMIDLIST pidlHead, LPITEMIDLIST pidlTail);
|
||||||
|
static UINT get_pidl_size(LPITEMIDLIST pidl);
|
||||||
|
static LPITEMIDLIST get_next_pidl(LPITEMIDLIST pidl);
|
||||||
|
static LPITEMIDLIST get_last_pidl(LPITEMIDLIST pidl);
|
||||||
|
static LPITEMIDLIST clone_pidl(LPITEMIDLIST pidl);
|
||||||
|
static LPITEMIDLIST remove_last_pidl(LPITEMIDLIST pidl);
|
||||||
|
static void free_pidl(LPITEMIDLIST pidl);
|
||||||
|
static char *get_key_for_pidl(LPITEMIDLIST pidl);
|
||||||
|
|
||||||
|
static FileItem *get_fileitem_by_fullpidl(LPITEMIDLIST pidl, bool create_if_not);
|
||||||
|
static void put_fileitem(FileItem *fileitem);
|
||||||
|
#else
|
||||||
|
static FileItem *get_fileitem_by_path(const char *path, bool create_if_not);
|
||||||
|
static void for_each_child_callback(const char *filename, int attrib, int param);
|
||||||
|
static char *remove_backslash(char *filename);
|
||||||
|
static char *get_key_for_filename(const char *filename);
|
||||||
|
static void put_fileitem(FileItem *fileitem);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes the file-system module to navigate the file-system.
|
||||||
|
*/
|
||||||
|
bool file_system_init(void)
|
||||||
|
{
|
||||||
|
#ifdef USE_PIDLS
|
||||||
|
/* get the IMalloc interface */
|
||||||
|
SHGetMalloc(&shl_imalloc);
|
||||||
|
|
||||||
|
/* get desktop IShellFolder interface */
|
||||||
|
SHGetDesktopFolder(&shl_idesktop);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
hash_fileitems = hash_new(512);
|
||||||
|
get_root_fileitem();
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shutdowns the file-system module.
|
||||||
|
*/
|
||||||
|
void file_system_exit(void)
|
||||||
|
{
|
||||||
|
if (rootitem)
|
||||||
|
fileitem_free(rootitem);
|
||||||
|
|
||||||
|
if (hash_fileitems)
|
||||||
|
hash_free(hash_fileitems, NULL);
|
||||||
|
|
||||||
|
#ifdef USE_PIDLS
|
||||||
|
/* relase desktop IShellFolder interface */
|
||||||
|
IShellFolder_Release(shl_idesktop);
|
||||||
|
|
||||||
|
/* release IMalloc interface */
|
||||||
|
IMalloc_Release(shl_imalloc);
|
||||||
|
shl_imalloc = NULL;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
FileItem *get_root_fileitem(void)
|
||||||
|
{
|
||||||
|
FileItem *fileitem;
|
||||||
|
|
||||||
|
if (rootitem)
|
||||||
|
return rootitem;
|
||||||
|
|
||||||
|
fileitem = fileitem_new(NULL);
|
||||||
|
if (!fileitem)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
rootitem = fileitem;
|
||||||
|
|
||||||
|
#ifdef USE_PIDLS
|
||||||
|
{
|
||||||
|
/* get the desktop PIDL */
|
||||||
|
LPITEMIDLIST pidl = NULL;
|
||||||
|
|
||||||
|
if (SHGetSpecialFolderLocation(NULL, CSIDL_DESKTOP, &pidl) != S_OK) {
|
||||||
|
/* TODO do something better */
|
||||||
|
assert(FALSE);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
fileitem->pidl = pidl;
|
||||||
|
fileitem->fullpidl = pidl;
|
||||||
|
fileitem->attrib = SFGAO_FOLDER;
|
||||||
|
IShellFolder_GetAttributesOf(shl_idesktop, 1,
|
||||||
|
(LPCITEMIDLIST *)&pidl,
|
||||||
|
&fileitem->attrib);
|
||||||
|
|
||||||
|
update_by_pidl(fileitem);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
{
|
||||||
|
char buf[MAX_PATH];
|
||||||
|
|
||||||
|
#if defined HAVE_DRIVES
|
||||||
|
ustrcpy(buf, "C:\\");
|
||||||
|
#else
|
||||||
|
ustrcpy(buf, "/");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
fileitem->filename = jstrdup(buf);
|
||||||
|
fileitem->displayname = jstrdup(buf);
|
||||||
|
fileitem->attrib = FA_DIREC;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* insert the file-item in the hash-table */
|
||||||
|
put_fileitem(fileitem);
|
||||||
|
return fileitem;
|
||||||
|
}
|
||||||
|
|
||||||
|
FileItem *get_fileitem_from_path(const char *path)
|
||||||
|
{
|
||||||
|
FileItem *fileitem = NULL;
|
||||||
|
|
||||||
|
#ifdef USE_PIDLS
|
||||||
|
{
|
||||||
|
ULONG cbEaten;
|
||||||
|
WCHAR wStr[MAX_PATH];
|
||||||
|
LPITEMIDLIST fullpidl = NULL;
|
||||||
|
SFGAOF attrib = SFGAO_FOLDER;
|
||||||
|
|
||||||
|
MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, path, ustrlen(path)+1, wStr, MAX_PATH);
|
||||||
|
if (IShellFolder_ParseDisplayName(shl_idesktop,
|
||||||
|
NULL, NULL,
|
||||||
|
wStr, &cbEaten,
|
||||||
|
&fullpidl,
|
||||||
|
&attrib) != S_OK) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
fileitem = get_fileitem_by_fullpidl(fullpidl, TRUE);
|
||||||
|
free_pidl(fullpidl);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
{
|
||||||
|
char buf[MAX_PATH];
|
||||||
|
ustrcpy(buf, path);
|
||||||
|
remove_backslash(buf);
|
||||||
|
fileitem = get_fileitem_by_path(buf, TRUE);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return fileitem;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool fileitem_is_folder(FileItem *fileitem)
|
||||||
|
{
|
||||||
|
assert(fileitem != NULL);
|
||||||
|
|
||||||
|
return IS_FOLDER(fileitem);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool fileitem_is_browsable(FileItem *fileitem)
|
||||||
|
{
|
||||||
|
assert(fileitem != NULL);
|
||||||
|
assert(fileitem->filename != NULL);
|
||||||
|
|
||||||
|
#ifdef USE_PIDLS
|
||||||
|
return
|
||||||
|
IS_FOLDER(fileitem) &&
|
||||||
|
(fileitem->filename[0] != ':' ||
|
||||||
|
/* My Computer = {20D04FE0-3AEA-1069-A2D8-08002B30309D} */
|
||||||
|
ustrcmp(fileitem->filename, "::{20D04FE0-3AEA-1069-A2D8-08002B30309D}") == 0);
|
||||||
|
#else
|
||||||
|
return IS_FOLDER(fileitem);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *fileitem_get_filename(FileItem *fileitem)
|
||||||
|
{
|
||||||
|
assert(fileitem != NULL);
|
||||||
|
assert(fileitem->filename != NULL);
|
||||||
|
|
||||||
|
return fileitem->filename;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *fileitem_get_displayname(FileItem *fileitem)
|
||||||
|
{
|
||||||
|
assert(fileitem != NULL);
|
||||||
|
assert(fileitem->displayname != NULL);
|
||||||
|
|
||||||
|
return fileitem->displayname;
|
||||||
|
}
|
||||||
|
|
||||||
|
FileItem *fileitem_get_parent(FileItem *fileitem)
|
||||||
|
{
|
||||||
|
assert(fileitem != NULL);
|
||||||
|
|
||||||
|
if (fileitem == rootitem)
|
||||||
|
return NULL;
|
||||||
|
else {
|
||||||
|
assert(fileitem->parent != NULL);
|
||||||
|
return fileitem->parent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
JList fileitem_get_children(FileItem *fileitem)
|
||||||
|
{
|
||||||
|
assert(fileitem != NULL);
|
||||||
|
|
||||||
|
if (!fileitem->children && IS_FOLDER(fileitem)) {
|
||||||
|
fileitem->children = jlist_new();
|
||||||
|
|
||||||
|
#ifdef USE_PIDLS
|
||||||
|
{
|
||||||
|
IShellFolder *pFolder = NULL;
|
||||||
|
|
||||||
|
if (fileitem == rootitem)
|
||||||
|
pFolder = shl_idesktop;
|
||||||
|
else
|
||||||
|
IShellFolder_BindToObject(shl_idesktop,
|
||||||
|
fileitem->fullpidl,
|
||||||
|
NULL,
|
||||||
|
&IID_IShellFolder,
|
||||||
|
(LPVOID *)&pFolder);
|
||||||
|
|
||||||
|
if (pFolder != NULL) {
|
||||||
|
IEnumIDList *pEnum = NULL;
|
||||||
|
ULONG c, fetched;
|
||||||
|
|
||||||
|
/* get the interface to enumerate subitems */
|
||||||
|
IShellFolder_EnumObjects(pFolder, win_get_window(),
|
||||||
|
SHCONTF_FOLDERS | SHCONTF_NONFOLDERS, &pEnum);
|
||||||
|
|
||||||
|
if (pEnum != NULL) {
|
||||||
|
LPITEMIDLIST itempidl[256];
|
||||||
|
SFGAOF attribs[256];
|
||||||
|
|
||||||
|
/* enumerate the items in the folder */
|
||||||
|
while (IEnumIDList_Next(pEnum, 256, itempidl, &fetched) == S_OK &&
|
||||||
|
fetched > 0) {
|
||||||
|
/* request the SFGAO_FOLDER attribute to know what of the
|
||||||
|
item is a folder */
|
||||||
|
for (c=0; c<fetched; ++c)
|
||||||
|
attribs[c] = SFGAO_FOLDER;
|
||||||
|
|
||||||
|
if (IShellFolder_GetAttributesOf(pFolder, fetched,
|
||||||
|
(LPCITEMIDLIST *)itempidl, attribs) != S_OK) {
|
||||||
|
for (c=0; c<fetched; ++c)
|
||||||
|
attribs[c] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* generate the FileItems */
|
||||||
|
for (c=0; c<fetched; ++c) {
|
||||||
|
FileItem *child;
|
||||||
|
LPITEMIDLIST fullpidl = concat_pidl(fileitem->fullpidl,
|
||||||
|
itempidl[c]);
|
||||||
|
|
||||||
|
child = get_fileitem_by_fullpidl(fullpidl, FALSE);
|
||||||
|
if (!child) {
|
||||||
|
child = fileitem_new(fileitem);
|
||||||
|
|
||||||
|
child->pidl = itempidl[c];
|
||||||
|
child->fullpidl = fullpidl;
|
||||||
|
child->attrib = attribs[c];
|
||||||
|
|
||||||
|
update_by_pidl(child);
|
||||||
|
put_fileitem(child);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
assert(child->parent == fileitem);
|
||||||
|
free_pidl(fullpidl);
|
||||||
|
free_pidl(itempidl[c]);
|
||||||
|
}
|
||||||
|
|
||||||
|
fileitem_insert_child_sorted(fileitem, child);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
IEnumIDList_Release(pEnum);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pFolder != shl_idesktop)
|
||||||
|
IShellFolder_Release(pFolder);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
{
|
||||||
|
char buf[MAX_PATH], path[MAX_PATH], tmp[32];
|
||||||
|
|
||||||
|
ustrcpy(path, fileitem->filename);
|
||||||
|
put_backslash(path);
|
||||||
|
|
||||||
|
replace_filename(buf,
|
||||||
|
path,
|
||||||
|
uconvert_ascii("*.*", tmp),
|
||||||
|
sizeof(buf));
|
||||||
|
|
||||||
|
for_each_file(buf, FA_TO_SHOW,
|
||||||
|
for_each_child_callback,
|
||||||
|
(int)fileitem); /* TODO warning with 64bits */
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
return fileitem->children;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool filename_has_extension(const char *filename, const char *list_of_extensions)
|
||||||
|
{
|
||||||
|
const char *extension = get_extension(filename);
|
||||||
|
bool ret = FALSE;
|
||||||
|
if (extension) {
|
||||||
|
char *extdup = ustrlwr(jstrdup(extension));
|
||||||
|
int extsz = ustrlen(extdup);
|
||||||
|
char *p = ustrstr(list_of_extensions, extdup);
|
||||||
|
if ((p != NULL) &&
|
||||||
|
(p[extsz] == 0 || p[extsz] == ',') &&
|
||||||
|
(p == list_of_extensions || *(p-1) == ',')) {
|
||||||
|
ret = TRUE;
|
||||||
|
}
|
||||||
|
jfree(extdup);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool fileitem_has_extension(FileItem *fileitem, const char *list_of_extensions)
|
||||||
|
{
|
||||||
|
return filename_has_extension(fileitem_get_filename(fileitem),
|
||||||
|
list_of_extensions);
|
||||||
|
}
|
||||||
|
|
||||||
|
static FileItem *fileitem_new(FileItem *parent)
|
||||||
|
{
|
||||||
|
FileItem *fileitem = jnew(FileItem, 1);
|
||||||
|
if (!fileitem)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
fileitem->filename = NULL;
|
||||||
|
fileitem->displayname = NULL;
|
||||||
|
fileitem->parent = parent;
|
||||||
|
fileitem->children = NULL;
|
||||||
|
fileitem->last_update = -1;
|
||||||
|
#ifdef USE_PIDLS
|
||||||
|
fileitem->pidl = NULL;
|
||||||
|
fileitem->fullpidl = NULL;
|
||||||
|
fileitem->attrib = 0;
|
||||||
|
#else
|
||||||
|
fileitem->keyname = NULL;
|
||||||
|
fileitem->attrib = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return fileitem;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void fileitem_free(FileItem *fileitem)
|
||||||
|
{
|
||||||
|
assert(fileitem != NULL);
|
||||||
|
|
||||||
|
#ifdef USE_PIDLS
|
||||||
|
if (fileitem->fullpidl &&
|
||||||
|
fileitem->fullpidl != fileitem->pidl) {
|
||||||
|
free_pidl(fileitem->fullpidl);
|
||||||
|
fileitem->fullpidl = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fileitem->pidl) {
|
||||||
|
free_pidl(fileitem->pidl);
|
||||||
|
fileitem->pidl = NULL;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
if (fileitem->keyname)
|
||||||
|
jfree(fileitem->keyname);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* this isn't neccessary (if fileitem_free is called with the
|
||||||
|
root-item at the first time)...
|
||||||
|
|
||||||
|
if (fileitem->parent)
|
||||||
|
jlist_remove(fileitem->parent->children, fileitem);
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (fileitem->filename)
|
||||||
|
jfree(fileitem->filename);
|
||||||
|
|
||||||
|
if (fileitem->displayname)
|
||||||
|
jfree(fileitem->displayname);
|
||||||
|
|
||||||
|
if (fileitem->children) {
|
||||||
|
JLink link, next;
|
||||||
|
JI_LIST_FOR_EACH_SAFE(fileitem->children, link, next) {
|
||||||
|
fileitem_free(link->data);
|
||||||
|
}
|
||||||
|
jlist_free(fileitem->children);
|
||||||
|
}
|
||||||
|
|
||||||
|
jfree(fileitem);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void fileitem_insert_child_sorted(FileItem *fileitem, FileItem *child)
|
||||||
|
{
|
||||||
|
JLink link;
|
||||||
|
bool inserted = FALSE;
|
||||||
|
JI_LIST_FOR_EACH(fileitem->children, link) {
|
||||||
|
if (fileitem_cmp((FileItem *)link->data, child) > 0) {
|
||||||
|
jlist_insert_before(fileitem->children, link, child);
|
||||||
|
inserted = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!inserted)
|
||||||
|
jlist_append(fileitem->children, child);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* fileitem_cmp:
|
||||||
|
* ustricmp for filenames: makes sure that eg "foo.bar" comes before
|
||||||
|
* "foo-1.bar", and also that "foo9.bar" comes before "foo10.bar".
|
||||||
|
*/
|
||||||
|
static int fileitem_cmp(FileItem *fi1, FileItem *fi2)
|
||||||
|
{
|
||||||
|
if (IS_FOLDER(fi1)) {
|
||||||
|
if (!IS_FOLDER(fi2))
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
else if (IS_FOLDER(fi2))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
#ifdef USE_PIDLS
|
||||||
|
{
|
||||||
|
int c1, c2;
|
||||||
|
int x1, x2;
|
||||||
|
char *t1, *t2;
|
||||||
|
const char *s1 = fi1->displayname;
|
||||||
|
const char *s2 = fi2->displayname;
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
c1 = utolower(ugetxc(&s1));
|
||||||
|
c2 = utolower(ugetxc(&s2));
|
||||||
|
|
||||||
|
if ((c1 >= '0') && (c1 <= '9') && (c2 >= '0') && (c2 <= '9')) {
|
||||||
|
x1 = ustrtol(s1 - ucwidth(c1), &t1, 10);
|
||||||
|
x2 = ustrtol(s2 - ucwidth(c2), &t2, 10);
|
||||||
|
if (x1 != x2)
|
||||||
|
return x1 - x2;
|
||||||
|
else if (t1 - s1 != t2 - s2)
|
||||||
|
return (t2 - s2) - (t1 - s1);
|
||||||
|
s1 = t1;
|
||||||
|
s2 = t2;
|
||||||
|
}
|
||||||
|
else if (c1 != c2) {
|
||||||
|
if (!c1)
|
||||||
|
return -1;
|
||||||
|
else if (!c2)
|
||||||
|
return 1;
|
||||||
|
else if (c1 == '.')
|
||||||
|
return -1;
|
||||||
|
else if (c2 == '.')
|
||||||
|
return 1;
|
||||||
|
return c1 - c2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!c1)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/********************************************************************/
|
||||||
|
/* PIDLS: Only for Win32 */
|
||||||
|
/********************************************************************/
|
||||||
|
|
||||||
|
#ifdef USE_PIDLS
|
||||||
|
|
||||||
|
/* updates the names of the file-item through its PIDL */
|
||||||
|
static void update_by_pidl(FileItem *fileitem)
|
||||||
|
{
|
||||||
|
STRRET strret;
|
||||||
|
TCHAR pszName[MAX_PATH];
|
||||||
|
IShellFolder *pFolder = NULL;
|
||||||
|
|
||||||
|
if (fileitem->filename) {
|
||||||
|
jfree(fileitem->filename);
|
||||||
|
fileitem->filename = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fileitem->displayname) {
|
||||||
|
jfree(fileitem->displayname);
|
||||||
|
fileitem->displayname = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fileitem == rootitem)
|
||||||
|
pFolder = shl_idesktop;
|
||||||
|
else {
|
||||||
|
assert(fileitem->parent != NULL);
|
||||||
|
IShellFolder_BindToObject(shl_idesktop,
|
||||||
|
fileitem->parent->fullpidl,
|
||||||
|
NULL,
|
||||||
|
&IID_IShellFolder,
|
||||||
|
(LPVOID *)&pFolder);
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************/
|
||||||
|
/* get the file name */
|
||||||
|
|
||||||
|
if (pFolder &&
|
||||||
|
IShellFolder_GetDisplayNameOf(pFolder,
|
||||||
|
fileitem->pidl,
|
||||||
|
SHGDN_NORMAL | SHGDN_FORPARSING,
|
||||||
|
&strret) == S_OK) {
|
||||||
|
StrRetToBuf(&strret, fileitem->pidl, pszName, MAX_PATH);
|
||||||
|
fileitem->filename = jstrdup(pszName);
|
||||||
|
}
|
||||||
|
else if (IShellFolder_GetDisplayNameOf(shl_idesktop,
|
||||||
|
fileitem->fullpidl,
|
||||||
|
SHGDN_NORMAL | SHGDN_FORPARSING,
|
||||||
|
&strret) == S_OK) {
|
||||||
|
StrRetToBuf(&strret, fileitem->fullpidl, pszName, MAX_PATH);
|
||||||
|
fileitem->filename = jstrdup(pszName);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
fileitem->filename = jstrdup("ERR");
|
||||||
|
|
||||||
|
|
||||||
|
/****************************************/
|
||||||
|
/* get the name to display */
|
||||||
|
|
||||||
|
if (pFolder &&
|
||||||
|
IShellFolder_GetDisplayNameOf(pFolder,
|
||||||
|
fileitem->pidl,
|
||||||
|
SHGDN_INFOLDER,
|
||||||
|
&strret) == S_OK) {
|
||||||
|
StrRetToBuf(&strret, fileitem->pidl, pszName, MAX_PATH);
|
||||||
|
fileitem->displayname = jstrdup(pszName);
|
||||||
|
}
|
||||||
|
else if (IShellFolder_GetDisplayNameOf(shl_idesktop,
|
||||||
|
fileitem->fullpidl,
|
||||||
|
SHGDN_INFOLDER,
|
||||||
|
&strret) == S_OK) {
|
||||||
|
StrRetToBuf(&strret, fileitem->fullpidl, pszName, MAX_PATH);
|
||||||
|
fileitem->displayname = jstrdup(pszName);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
fileitem->displayname = jstrdup("ERR");
|
||||||
|
|
||||||
|
if (pFolder && pFolder != shl_idesktop) {
|
||||||
|
IShellFolder_Release(pFolder);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static LPITEMIDLIST concat_pidl(LPITEMIDLIST pidlHead, LPITEMIDLIST pidlTail)
|
||||||
|
{
|
||||||
|
LPITEMIDLIST pidlNew;
|
||||||
|
UINT cb1, cb2;
|
||||||
|
|
||||||
|
assert(pidlHead != NULL);
|
||||||
|
assert(pidlTail != NULL);
|
||||||
|
|
||||||
|
cb1 = get_pidl_size(pidlHead) - sizeof(pidlHead->mkid.cb);
|
||||||
|
cb2 = get_pidl_size(pidlTail);
|
||||||
|
|
||||||
|
pidlNew = (LPITEMIDLIST)IMalloc_Alloc(shl_imalloc, cb1 + cb2);
|
||||||
|
if (pidlNew) {
|
||||||
|
CopyMemory(pidlNew, pidlHead, cb1);
|
||||||
|
CopyMemory(((LPSTR)pidlNew) + cb1, pidlTail, cb2);
|
||||||
|
}
|
||||||
|
|
||||||
|
return pidlNew;
|
||||||
|
}
|
||||||
|
|
||||||
|
static UINT get_pidl_size(LPITEMIDLIST pidl)
|
||||||
|
{
|
||||||
|
UINT cbTotal = 0;
|
||||||
|
|
||||||
|
if (pidl) {
|
||||||
|
cbTotal += sizeof(pidl->mkid.cb); /* null terminator */
|
||||||
|
|
||||||
|
while (pidl) {
|
||||||
|
cbTotal += pidl->mkid.cb;
|
||||||
|
pidl = get_next_pidl(pidl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return cbTotal;
|
||||||
|
}
|
||||||
|
|
||||||
|
static LPITEMIDLIST get_next_pidl(LPITEMIDLIST pidl)
|
||||||
|
{
|
||||||
|
if (pidl != NULL && pidl->mkid.cb > 0) {
|
||||||
|
pidl = (LPITEMIDLIST)(((LPBYTE)(pidl)) + pidl->mkid.cb);
|
||||||
|
if (pidl->mkid.cb > 0)
|
||||||
|
return pidl;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static LPITEMIDLIST get_last_pidl(LPITEMIDLIST pidl)
|
||||||
|
{
|
||||||
|
LPITEMIDLIST pidlLast = pidl;
|
||||||
|
LPITEMIDLIST pidlNew = NULL;
|
||||||
|
|
||||||
|
while (pidl) {
|
||||||
|
pidlLast = pidl;
|
||||||
|
pidl = get_next_pidl(pidl);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pidlLast) {
|
||||||
|
ULONG sz = get_pidl_size(pidlLast);
|
||||||
|
pidlNew = (LPITEMIDLIST)IMalloc_Alloc(shl_imalloc, sz);
|
||||||
|
CopyMemory(pidlNew, pidlLast, sz);
|
||||||
|
}
|
||||||
|
|
||||||
|
return pidlNew;
|
||||||
|
}
|
||||||
|
|
||||||
|
static LPITEMIDLIST clone_pidl(LPITEMIDLIST pidl)
|
||||||
|
{
|
||||||
|
ULONG sz = get_pidl_size(pidl);
|
||||||
|
LPITEMIDLIST pidlNew = (LPITEMIDLIST)IMalloc_Alloc(shl_imalloc, sz);
|
||||||
|
|
||||||
|
CopyMemory(pidlNew, pidl, sz);
|
||||||
|
|
||||||
|
return pidlNew;
|
||||||
|
}
|
||||||
|
|
||||||
|
static LPITEMIDLIST remove_last_pidl(LPITEMIDLIST pidl)
|
||||||
|
{
|
||||||
|
LPITEMIDLIST pidlFirst = pidl;
|
||||||
|
LPITEMIDLIST pidlLast = pidl;
|
||||||
|
|
||||||
|
while (pidl) {
|
||||||
|
pidlLast = pidl;
|
||||||
|
pidl = get_next_pidl(pidl);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pidlLast)
|
||||||
|
pidlLast->mkid.cb = 0;
|
||||||
|
|
||||||
|
return pidlFirst;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void free_pidl(LPITEMIDLIST pidl)
|
||||||
|
{
|
||||||
|
IMalloc_Free(shl_imalloc, pidl);
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *get_key_for_pidl(LPITEMIDLIST pidl)
|
||||||
|
{
|
||||||
|
char *key = jmalloc(sizeof(char) * (get_pidl_size(pidl)+1));
|
||||||
|
UINT c, i = 0;
|
||||||
|
|
||||||
|
while (pidl) {
|
||||||
|
for (c=0; c<pidl->mkid.cb; ++c) {
|
||||||
|
if (pidl->mkid.abID[c])
|
||||||
|
key[i++] = pidl->mkid.abID[c];
|
||||||
|
else
|
||||||
|
key[i++] = 1;
|
||||||
|
}
|
||||||
|
pidl = get_next_pidl(pidl);
|
||||||
|
}
|
||||||
|
key[i] = 0;
|
||||||
|
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
|
||||||
|
static FileItem *get_fileitem_by_fullpidl(LPITEMIDLIST fullpidl, bool create_if_not)
|
||||||
|
{
|
||||||
|
char *key;
|
||||||
|
FileItem *fileitem;
|
||||||
|
|
||||||
|
key = get_key_for_pidl(fullpidl);
|
||||||
|
fileitem = hash_lookup(hash_fileitems, key);
|
||||||
|
jfree(key);
|
||||||
|
|
||||||
|
if (fileitem)
|
||||||
|
return fileitem;
|
||||||
|
|
||||||
|
if (!create_if_not)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
/* new file-item */
|
||||||
|
fileitem = fileitem_new(NULL);
|
||||||
|
fileitem->fullpidl = clone_pidl(fullpidl);
|
||||||
|
|
||||||
|
fileitem->attrib = SFGAO_FOLDER;
|
||||||
|
IShellFolder_GetAttributesOf(shl_idesktop, 1,
|
||||||
|
(LPCITEMIDLIST *)&fileitem->fullpidl,
|
||||||
|
&fileitem->attrib);
|
||||||
|
|
||||||
|
{
|
||||||
|
LPITEMIDLIST parent_fullpidl = clone_pidl(fileitem->fullpidl);
|
||||||
|
remove_last_pidl(parent_fullpidl);
|
||||||
|
|
||||||
|
fileitem->pidl = get_last_pidl(fileitem->fullpidl);
|
||||||
|
fileitem->parent = get_fileitem_by_fullpidl(parent_fullpidl, TRUE);
|
||||||
|
|
||||||
|
free_pidl(parent_fullpidl);
|
||||||
|
}
|
||||||
|
|
||||||
|
update_by_pidl(fileitem);
|
||||||
|
put_fileitem(fileitem);
|
||||||
|
|
||||||
|
return fileitem;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void put_fileitem(FileItem *fileitem)
|
||||||
|
{
|
||||||
|
char *key;
|
||||||
|
|
||||||
|
assert(fileitem->filename != NULL);
|
||||||
|
|
||||||
|
key = get_key_for_pidl(fileitem->fullpidl);
|
||||||
|
hash_insert(hash_fileitems, key, fileitem);
|
||||||
|
jfree(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
/********************************************************************/
|
||||||
|
/* Allegro for_each_file: Portable */
|
||||||
|
/********************************************************************/
|
||||||
|
|
||||||
|
static FileItem *get_fileitem_by_path(const char *path, bool create_if_not)
|
||||||
|
{
|
||||||
|
char *key;
|
||||||
|
FileItem *fileitem;
|
||||||
|
int attrib;
|
||||||
|
|
||||||
|
key = get_key_for_filename(path);
|
||||||
|
fileitem = hash_lookup(hash_fileitems, key);
|
||||||
|
jfree(key);
|
||||||
|
|
||||||
|
if (fileitem)
|
||||||
|
return fileitem;
|
||||||
|
|
||||||
|
if (!create_if_not)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
/* get the attributes of the file */
|
||||||
|
attrib = 0;
|
||||||
|
if (!file_exists(path, FA_ALL, &attrib)) {
|
||||||
|
if (!ji_dir_exists(path))
|
||||||
|
return NULL;
|
||||||
|
attrib = FA_DIREC;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* new file-item */
|
||||||
|
fileitem = fileitem_new(NULL);
|
||||||
|
|
||||||
|
fileitem->filename = jstrdup(path);
|
||||||
|
fileitem->displayname = jstrdup(get_filename(path));
|
||||||
|
fileitem->attrib = attrib;
|
||||||
|
|
||||||
|
/* get the parent */
|
||||||
|
{
|
||||||
|
char parent_path[MAX_PATH];
|
||||||
|
replace_filename(parent_path, path, "", sizeof(parent_path));
|
||||||
|
remove_backslash(parent_path);
|
||||||
|
fileitem->parent = get_fileitem_by_path(parent_path, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
put_fileitem(fileitem);
|
||||||
|
|
||||||
|
return fileitem;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void for_each_child_callback(const char *filename, int attrib, int param)
|
||||||
|
{
|
||||||
|
FileItem *fileitem = (FileItem *)param;
|
||||||
|
FileItem *child;
|
||||||
|
const char *filename_without_path = get_filename(filename);
|
||||||
|
|
||||||
|
if (*filename_without_path == '.' &&
|
||||||
|
(ustrcmp(filename_without_path, ".") == 0 ||
|
||||||
|
ustrcmp(filename_without_path, "..") == 0))
|
||||||
|
return;
|
||||||
|
|
||||||
|
child = get_fileitem_by_path(filename, FALSE);
|
||||||
|
if (!child) {
|
||||||
|
child = fileitem_new(fileitem);
|
||||||
|
|
||||||
|
child->filename = jstrdup(filename);
|
||||||
|
child->displayname = jstrdup(filename_without_path);
|
||||||
|
child->attrib = attrib;
|
||||||
|
|
||||||
|
put_fileitem(child);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
assert(child->parent == fileitem);
|
||||||
|
}
|
||||||
|
|
||||||
|
fileitem_insert_child_sorted(fileitem, child);
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *remove_backslash(char *filename)
|
||||||
|
{
|
||||||
|
int len = ustrlen(filename);
|
||||||
|
|
||||||
|
if (len > 0 &&
|
||||||
|
(filename[len-1] == '/' ||
|
||||||
|
filename[len-1] == OTHER_PATH_SEPARATOR)) {
|
||||||
|
#ifdef HAVE_DRIVES
|
||||||
|
/* if the name is C:\ or something like that, the backslash isn't
|
||||||
|
removed */
|
||||||
|
if (len == 3 && filename[1] == DEVICE_SEPARATOR)
|
||||||
|
return filename;
|
||||||
|
#endif
|
||||||
|
filename[len-1] = 0;
|
||||||
|
}
|
||||||
|
return filename;
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *get_key_for_filename(const char *filename)
|
||||||
|
{
|
||||||
|
char buf[MAX_PATH];
|
||||||
|
|
||||||
|
ustrcpy(buf, filename);
|
||||||
|
|
||||||
|
#if !defined CASE_SENSITIVE
|
||||||
|
ustrlwr(buf);
|
||||||
|
#endif
|
||||||
|
fix_filename_slashes(buf);
|
||||||
|
|
||||||
|
return jstrdup(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void put_fileitem(FileItem *fileitem)
|
||||||
|
{
|
||||||
|
assert(fileitem->filename != NULL);
|
||||||
|
assert(fileitem->keyname == NULL);
|
||||||
|
|
||||||
|
fileitem->keyname = get_key_for_filename(fileitem->filename);
|
||||||
|
|
||||||
|
/* insert this file-item in the hash-table */
|
||||||
|
hash_insert(hash_fileitems, fileitem->keyname, fileitem);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
46
src/core/file_system.h
Normal file
46
src/core/file_system.h
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
/* ASE - Allegro Sprite Editor
|
||||||
|
* Copyright (C) 2008 David A. Capello
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef CORE_FILE_SYSTEM_H
|
||||||
|
#define CORE_FILE_SYSTEM_H
|
||||||
|
|
||||||
|
#include "jinete/jbase.h"
|
||||||
|
|
||||||
|
struct FileItem;
|
||||||
|
typedef struct FileItem FileItem;
|
||||||
|
|
||||||
|
bool file_system_init(void);
|
||||||
|
void file_system_exit(void);
|
||||||
|
|
||||||
|
FileItem *get_root_fileitem(void);
|
||||||
|
FileItem *get_fileitem_from_path(const char *path);
|
||||||
|
|
||||||
|
bool fileitem_is_folder(FileItem *fileitem);
|
||||||
|
bool fileitem_is_browsable(FileItem *fileitem);
|
||||||
|
|
||||||
|
const char *fileitem_get_filename(FileItem *fileitem);
|
||||||
|
const char *fileitem_get_displayname(FileItem *fileitem);
|
||||||
|
|
||||||
|
FileItem *fileitem_get_parent(FileItem *fileitem);
|
||||||
|
JList fileitem_get_children(FileItem *fileitem);
|
||||||
|
|
||||||
|
bool filename_has_extension(const char *filename, const char *list_of_extensions);
|
||||||
|
bool fileitem_has_extension(FileItem *fileitem, const char *list_of_extensions);
|
||||||
|
|
||||||
|
#endif /* CORE_FILE_SYSTEM_H */
|
||||||
|
|
@ -68,7 +68,7 @@ static Module module[] =
|
|||||||
|
|
||||||
static int modules = sizeof(module) / sizeof(Module);
|
static int modules = sizeof(module) / sizeof(Module);
|
||||||
|
|
||||||
int modules_init(int requirements)
|
bool modules_init(int requirements)
|
||||||
{
|
{
|
||||||
int c;
|
int c;
|
||||||
|
|
||||||
@ -76,11 +76,12 @@ int modules_init(int requirements)
|
|||||||
if (module[c].reqs & requirements) {
|
if (module[c].reqs & requirements) {
|
||||||
PRINTF("Installing module: %s\n", module[c].name);
|
PRINTF("Installing module: %s\n", module[c].name);
|
||||||
if ((*module[c].init)() < 0)
|
if ((*module[c].init)() < 0)
|
||||||
return -1;
|
return FALSE;
|
||||||
|
|
||||||
module[c].installed = TRUE;
|
module[c].installed = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void modules_exit(void)
|
void modules_exit(void)
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/* ASE - Allegro Sprite Editor
|
/* ASE - Allegro Sprite Editor
|
||||||
* Copyright (C) 2001-2005, 2007 David A. Capello
|
* Copyright (C) 2001-2005, 2007, 2008 David A. Capello
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -19,10 +19,12 @@
|
|||||||
#ifndef CORE_MODULES_H
|
#ifndef CORE_MODULES_H
|
||||||
#define CORE_MODULES_H
|
#define CORE_MODULES_H
|
||||||
|
|
||||||
|
#include "jinete/jbase.h"
|
||||||
|
|
||||||
#define REQUIRE_INTERFACE 1
|
#define REQUIRE_INTERFACE 1
|
||||||
#define REQUIRE_SCRIPTING 2
|
#define REQUIRE_SCRIPTING 2
|
||||||
|
|
||||||
int modules_init(int requirements);
|
bool modules_init(int requirements);
|
||||||
void modules_exit(void);
|
void modules_exit(void);
|
||||||
|
|
||||||
#endif /* CORE_MODULES_H */
|
#endif /* CORE_MODULES_H */
|
||||||
|
@ -240,7 +240,7 @@ static void load_command(JWidget widget)
|
|||||||
RGB *palette;
|
RGB *palette;
|
||||||
char *filename;
|
char *filename;
|
||||||
|
|
||||||
filename = GUI_FileSelect(_("Load Palette"), "", "pcx,bmp,tga,lbm,col");
|
filename = ase_file_selector(_("Load Palette"), "", "pcx,bmp,tga,lbm,col");
|
||||||
if (filename) {
|
if (filename) {
|
||||||
palette = palette_load(filename);
|
palette = palette_load(filename);
|
||||||
if (!palette) {
|
if (!palette) {
|
||||||
@ -260,7 +260,7 @@ static void save_command(JWidget widget)
|
|||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
again:
|
again:
|
||||||
filename = GUI_FileSelect(_("Save Palette"), "", "pcx,bmp,tga,col");
|
filename = ase_file_selector(_("Save Palette"), "", "pcx,bmp,tga,col");
|
||||||
if (filename) {
|
if (filename) {
|
||||||
if (exists(filename)) {
|
if (exists(filename)) {
|
||||||
ret = jalert("%s<<%s<<%s||%s",
|
ret = jalert("%s<<%s<<%s||%s",
|
||||||
|
@ -283,9 +283,9 @@ static void button_font_command(JWidget widget)
|
|||||||
{
|
{
|
||||||
char *filename;
|
char *filename;
|
||||||
|
|
||||||
filename = GUI_FileSelect(_("Open Font (TTF or Allegro bitmap format)"),
|
filename = ase_file_selector(_("Open Font (TTF or Allegro bitmap format)"),
|
||||||
get_config_string ("DrawText", "Font", ""),
|
get_config_string ("DrawText", "Font", ""),
|
||||||
"pcx,bmp,tga,lbm,ttf");
|
"pcx,bmp,tga,lbm,ttf");
|
||||||
if (filename) {
|
if (filename) {
|
||||||
set_config_string("DrawText", "Font", filename);
|
set_config_string("DrawText", "Font", filename);
|
||||||
update_button_text();
|
update_button_text();
|
||||||
|
@ -20,20 +20,10 @@
|
|||||||
|
|
||||||
#ifndef USE_PRECOMPILED_HEADER
|
#ifndef USE_PRECOMPILED_HEADER
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
#include <allegro.h>
|
#include <allegro.h>
|
||||||
#include <allegro/internal/aintern.h>
|
#include <allegro/internal/aintern.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#if defined ALLEGRO_UNIX || defined ALLEGRO_DJGPP || defined ALLEGRO_MINGW32
|
|
||||||
# include <sys/stat.h>
|
|
||||||
#endif
|
|
||||||
#if defined ALLEGRO_UNIX || defined ALLEGRO_MINGW32
|
|
||||||
# include <sys/unistd.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef ALLEGRO_WINDOWS
|
|
||||||
#include <winalleg.h>
|
|
||||||
#include <shlobj.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "jinete/jinete.h"
|
#include "jinete/jinete.h"
|
||||||
|
|
||||||
@ -41,6 +31,7 @@
|
|||||||
#include "core/dirs.h"
|
#include "core/dirs.h"
|
||||||
#include "modules/gfx.h"
|
#include "modules/gfx.h"
|
||||||
#include "modules/gui.h"
|
#include "modules/gui.h"
|
||||||
|
#include "widgets/fileview.h"
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -48,38 +39,50 @@
|
|||||||
# define HAVE_DRIVES
|
# define HAVE_DRIVES
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define FA_ALL FA_RDONLY | FA_DIREC | FA_ARCH | FA_HIDDEN | FA_SYSTEM
|
/* Variables used only to maintain the history of navigation. */
|
||||||
|
static JLink navigation_position = NULL; /* current position in the navigation history */
|
||||||
|
static JList navigation_history = NULL; /* set of FileItems navigated */
|
||||||
|
static bool navigation_locked = FALSE; /* if TRUE the navigation_history isn't
|
||||||
|
modified if the current folder
|
||||||
|
changes (used when the back/forward
|
||||||
|
buttons are pushed) */
|
||||||
|
|
||||||
static bool combobox_msg_proc(JWidget widget, JMessage message);
|
static void update_location(JWidget window);
|
||||||
static void add_bookmark_command(JWidget widget, void *data);
|
static void update_navigation_buttons(JWidget window);
|
||||||
static void del_bookmark_command(JWidget widget, void *data);
|
static void add_in_navigation_history(FileItem *folder);
|
||||||
static void fill_bookmarks_combobox(JWidget combobox);
|
static void select_filetype_from_filename(JWidget window);
|
||||||
static void home_command(JWidget widget);
|
|
||||||
static void fonts_command(JWidget widget);
|
static void goback_command(JWidget widget);
|
||||||
static void palettes_command(JWidget widget);
|
static void goforward_command(JWidget widget);
|
||||||
static void mkdir_command(JWidget widget);
|
static void goup_command(JWidget widget);
|
||||||
|
|
||||||
|
static bool fileview_msg_proc(JWidget widget, JMessage msg);
|
||||||
|
static bool location_msg_proc(JWidget widget, JMessage msg);
|
||||||
|
static bool filetype_msg_proc(JWidget widget, JMessage msg);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The routine to select file in ASE.
|
* The routine that shows the dialog to select a file in ASE.
|
||||||
*
|
|
||||||
* It add some extra functionalities to the default Jinete
|
|
||||||
* file-selection dialog.
|
|
||||||
*
|
|
||||||
* @see ji_file_select_ex.
|
|
||||||
*/
|
*/
|
||||||
char *GUI_FileSelect(const char *message,
|
char *ase_file_selector(const char *message,
|
||||||
const char *init_path,
|
const char *init_path,
|
||||||
const char *exts)
|
const char *exts)
|
||||||
{
|
{
|
||||||
JWidget box_left, button_home;
|
static JWidget window = NULL;
|
||||||
JWidget button_fonts, button_palettes, button_mkdir;
|
JWidget fileview, box, ok;
|
||||||
JWidget box_top, box_top2, combobox, add_bookmark, del_bookmark, entry_path;
|
JWidget goback, goforward, goup;
|
||||||
JWidget widget_extension;
|
JWidget filename_entry;
|
||||||
char buf[512], *selected_filename;
|
JWidget filetype;
|
||||||
|
char buf[512];
|
||||||
|
char *result = NULL;
|
||||||
|
char *tok;
|
||||||
|
|
||||||
|
if (!navigation_history)
|
||||||
|
navigation_history = jlist_new();
|
||||||
|
|
||||||
|
/* 'buf' will contain the start folder path */
|
||||||
ustrcpy(buf, init_path);
|
ustrcpy(buf, init_path);
|
||||||
|
|
||||||
/* insert the path */
|
/* use the current path */
|
||||||
if (get_filename(buf) == buf) {
|
if (get_filename(buf) == buf) {
|
||||||
char path[512];
|
char path[512];
|
||||||
|
|
||||||
@ -105,297 +108,410 @@ char *GUI_FileSelect(const char *message,
|
|||||||
ustrcat(path, buf);
|
ustrcat(path, buf);
|
||||||
ustrcpy(buf, path);
|
ustrcpy(buf, path);
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
/* remove the filename */
|
||||||
|
*get_filename(buf) = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!window) {
|
||||||
|
JWidget view, location;
|
||||||
|
|
||||||
/**********************************************************************/
|
/* load the window widget */
|
||||||
/* prepare left side */
|
window = load_widget("filesel.jid", "file_selector");
|
||||||
|
if (!window)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
box_left = jbox_new(JI_VERTICAL);
|
box = jwidget_find_name(window, "box");
|
||||||
button_home = jbutton_new(NULL);
|
goback = jwidget_find_name(window, "goback");
|
||||||
button_fonts = jbutton_new(NULL);
|
goforward = jwidget_find_name(window, "goforward");
|
||||||
button_palettes = jbutton_new(NULL);
|
goup = jwidget_find_name(window, "goup");
|
||||||
button_mkdir = jbutton_new(NULL);
|
location = jwidget_find_name(window, "location");
|
||||||
|
filetype = jwidget_find_name(window, "filetype");
|
||||||
|
|
||||||
add_gfxicon_to_button(button_home, GFX_FILE_HOME, JI_CENTER | JI_MIDDLE);
|
jwidget_focusrest(goback, FALSE);
|
||||||
add_gfxicon_to_button(button_fonts, GFX_FILE_FONTS, JI_CENTER | JI_MIDDLE);
|
jwidget_focusrest(goforward, FALSE);
|
||||||
add_gfxicon_to_button(button_palettes, GFX_FILE_PALETTES, JI_CENTER | JI_MIDDLE);
|
jwidget_focusrest(goup, FALSE);
|
||||||
add_gfxicon_to_button(button_mkdir, GFX_FILE_MKDIR, JI_CENTER | JI_MIDDLE);
|
|
||||||
|
|
||||||
/* hook signals */
|
add_gfxicon_to_button(goback, GFX_ARROW_LEFT, JI_CENTER | JI_MIDDLE);
|
||||||
jbutton_add_command(button_home, home_command);
|
add_gfxicon_to_button(goforward, GFX_ARROW_RIGHT, JI_CENTER | JI_MIDDLE);
|
||||||
jbutton_add_command(button_fonts, fonts_command);
|
add_gfxicon_to_button(goup, GFX_ARROW_UP, JI_CENTER | JI_MIDDLE);
|
||||||
jbutton_add_command(button_palettes, palettes_command);
|
|
||||||
jbutton_add_command(button_mkdir, mkdir_command);
|
|
||||||
|
|
||||||
jwidget_add_childs(box_left,
|
jbutton_add_command(goback, goback_command);
|
||||||
button_home, button_fonts,
|
jbutton_add_command(goforward, goforward_command);
|
||||||
button_palettes, button_mkdir, NULL);
|
jbutton_add_command(goup, goup_command);
|
||||||
|
|
||||||
/**********************************************************************/
|
view = jview_new();
|
||||||
/* prepare top side */
|
fileview = fileview_new(get_fileitem_from_path(buf), exts);
|
||||||
|
|
||||||
box_top = jbox_new(JI_HORIZONTAL);
|
jwidget_add_hook(fileview, -1, fileview_msg_proc, NULL);
|
||||||
box_top2 = jbox_new(JI_HORIZONTAL | JI_HOMOGENEOUS);
|
jwidget_add_hook(location, -1, location_msg_proc, NULL);
|
||||||
combobox = jcombobox_new();
|
jwidget_add_hook(filetype, -1, filetype_msg_proc, NULL);
|
||||||
entry_path = jcombobox_get_entry_widget(combobox);
|
|
||||||
add_bookmark = jbutton_new("+");
|
|
||||||
del_bookmark = jbutton_new("-");
|
|
||||||
|
|
||||||
#ifdef HAVE_DRIVES
|
jwidget_set_name(fileview, "fileview");
|
||||||
jcombobox_casesensitive(combobox, FALSE);
|
jwidget_magnetic(fileview, TRUE);
|
||||||
#else
|
|
||||||
jcombobox_casesensitive(combobox, TRUE);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
jwidget_noborders(box_top2);
|
jview_attach(view, fileview);
|
||||||
jbutton_set_bevel(add_bookmark, 2, 0, 2, 0);
|
jwidget_expansive(view, TRUE);
|
||||||
jbutton_set_bevel(del_bookmark, 0, 2, 0, 2);
|
|
||||||
jcombobox_editable(combobox, TRUE);
|
|
||||||
jcombobox_clickopen(combobox, FALSE);
|
|
||||||
|
|
||||||
jwidget_add_hook(combobox, JI_WIDGET, combobox_msg_proc, NULL);
|
jwidget_add_child(box, view);
|
||||||
jbutton_add_command_data(add_bookmark, add_bookmark_command, combobox);
|
|
||||||
jbutton_add_command_data(del_bookmark, del_bookmark_command, combobox);
|
|
||||||
|
|
||||||
fill_bookmarks_combobox(combobox);
|
jwidget_set_min_size(window, JI_SCREEN_W*9/10, JI_SCREEN_H*9/10);
|
||||||
|
jwindow_remap(window);
|
||||||
|
jwindow_center(window);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
fileview = jwidget_find_name(window, "fileview");
|
||||||
|
filetype = jwidget_find_name(window, "filetype");
|
||||||
|
|
||||||
jwidget_expansive(combobox, TRUE);
|
jwidget_signal_off(fileview);
|
||||||
jwidget_add_childs(box_top, combobox, box_top2, NULL);
|
fileview_set_current_folder(fileview, get_fileitem_from_path(buf));
|
||||||
jwidget_add_childs(box_top2, add_bookmark, del_bookmark, NULL);
|
jwidget_signal_on(fileview);
|
||||||
|
}
|
||||||
|
|
||||||
/**********************************************************************/
|
/* current location */
|
||||||
/* prepare widget_extension */
|
navigation_position = NULL;
|
||||||
|
add_in_navigation_history(fileview_get_current_folder(fileview));
|
||||||
|
|
||||||
|
/* fill the location combo-box */
|
||||||
|
update_location(window);
|
||||||
|
update_navigation_buttons(window);
|
||||||
|
|
||||||
widget_extension = jwidget_new(JI_WIDGET);
|
/* fill file-type combo-box */
|
||||||
jwidget_set_name(box_left, "left");
|
jcombobox_clear(filetype);
|
||||||
jwidget_set_name(box_top, "top");
|
ustrcpy(buf, exts);
|
||||||
jwidget_set_name(entry_path, "path");
|
for (tok = ustrtok(buf, ",");
|
||||||
jwidget_add_childs(widget_extension, box_left, box_top, NULL);
|
tok != NULL;
|
||||||
|
tok = ustrtok(NULL, ",")) {
|
||||||
|
jcombobox_add_string(filetype, tok, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
/* call the jinete file selector */
|
/* file name entry field */
|
||||||
selected_filename = ji_file_select_ex(message, buf, exts, widget_extension);
|
filename_entry = jwidget_find_name(window, "filename");
|
||||||
if (selected_filename) {
|
jwidget_set_text(filename_entry, get_filename(init_path));
|
||||||
char *s, *name_dup = jstrdup(selected_filename);
|
select_filetype_from_filename(window);
|
||||||
|
|
||||||
|
/* setup the title of the window */
|
||||||
|
jwidget_set_text(window, message);
|
||||||
|
|
||||||
|
/* get the ok-button */
|
||||||
|
ok = jwidget_find_name(window, "ok");
|
||||||
|
|
||||||
|
/* update the view */
|
||||||
|
jview_update(jwidget_get_view(fileview));
|
||||||
|
|
||||||
|
/* open the window and run... the user press ok? */
|
||||||
|
jwindow_open_fg(window);
|
||||||
|
if (jwindow_get_killer(window) == ok ||
|
||||||
|
jwindow_get_killer(window) == fileview) {
|
||||||
|
char *p;
|
||||||
|
|
||||||
|
/* open the selected file */
|
||||||
|
FileItem *folder = fileview_get_current_folder(fileview);
|
||||||
|
assert(folder != NULL);
|
||||||
|
|
||||||
|
ustrcpy(buf, fileitem_get_filename(folder));
|
||||||
|
put_backslash(buf);
|
||||||
|
ustrcat(buf, jwidget_get_text(filename_entry));
|
||||||
|
|
||||||
|
/* does it not have extension? ...we should add the extension
|
||||||
|
selected in the filetype combo-box */
|
||||||
|
p = get_extension(buf);
|
||||||
|
if (!p || *p == 0) {
|
||||||
|
ustrcat(buf, ".");
|
||||||
|
ustrcat(buf, jcombobox_get_selected_string(filetype));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* duplicate the buffer to return a new string */
|
||||||
|
result = jstrdup(buf);
|
||||||
|
|
||||||
/* save the path in the configuration file */
|
/* save the path in the configuration file */
|
||||||
s = get_filename(name_dup);
|
{
|
||||||
if (s)
|
char *name_dup = jstrdup(result);
|
||||||
*s = 0;
|
char *s = get_filename(name_dup);
|
||||||
|
if (s)
|
||||||
set_config_string("FileSelect", "CurrentDirectory", name_dup);
|
*s = 0;
|
||||||
jfree(name_dup);
|
set_config_string("FileSelect", "CurrentDirectory", name_dup);
|
||||||
|
jfree(name_dup);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
jwidget_free(widget_extension);
|
/* TODO why this doesn't work if I remove this? */
|
||||||
|
jwidget_free(window);
|
||||||
|
window = NULL;
|
||||||
|
|
||||||
return selected_filename;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool combobox_msg_proc(JWidget widget, JMessage msg)
|
/**
|
||||||
|
* Updates the content of the combo-box that shows the current
|
||||||
|
* location in the file-system.
|
||||||
|
*/
|
||||||
|
static void update_location(JWidget window)
|
||||||
{
|
{
|
||||||
switch (msg->type) {
|
char buf[MAX_PATH*2];
|
||||||
|
JWidget fileview = jwidget_find_name(window, "fileview");
|
||||||
|
JWidget location = jwidget_find_name(window, "location");
|
||||||
|
FileItem *current_folder = fileview_get_current_folder(fileview);
|
||||||
|
FileItem *fileitem = current_folder;
|
||||||
|
JList locations = jlist_new();
|
||||||
|
int c, level = 0;
|
||||||
|
JLink link;
|
||||||
|
int selected_index = -1;
|
||||||
|
|
||||||
case JM_SIGNAL:
|
while (fileitem != NULL) {
|
||||||
if (msg->signal.num == JI_SIGNAL_COMBOBOX_SELECT) {
|
jlist_prepend(locations, fileitem);
|
||||||
ji_file_select_enter_to_path(jcombobox_get_selected_string(widget));
|
fileitem = fileitem_get_parent(fileitem);
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* clear all the items from the combo-box */
|
||||||
|
jcombobox_clear(location);
|
||||||
|
|
||||||
|
/* add item by item (from root to the specific current folder) */
|
||||||
|
level = 0;
|
||||||
|
JI_LIST_FOR_EACH(locations, link) {
|
||||||
|
fileitem = link->data;
|
||||||
|
|
||||||
|
/* indentation */
|
||||||
|
ustrcpy(buf, empty_string);
|
||||||
|
for (c=0; c<level; ++c)
|
||||||
|
ustrcat(buf, " ");
|
||||||
|
|
||||||
|
/* location name */
|
||||||
|
ustrcat(buf, fileitem_get_displayname(fileitem));
|
||||||
|
|
||||||
|
/* add the new location to the combo-box */
|
||||||
|
jcombobox_add_string(location, buf, fileitem);
|
||||||
|
|
||||||
|
if (fileitem == current_folder)
|
||||||
|
selected_index = level;
|
||||||
|
|
||||||
|
level++;
|
||||||
|
}
|
||||||
|
|
||||||
|
jwidget_signal_off(location);
|
||||||
|
jcombobox_select_index(location, selected_index);
|
||||||
|
jwidget_set_text(jcombobox_get_entry_widget(location),
|
||||||
|
fileitem_get_displayname(current_folder));
|
||||||
|
jentry_deselect_text(jcombobox_get_entry_widget(location));
|
||||||
|
jwidget_signal_on(location);
|
||||||
|
|
||||||
|
jlist_free(locations);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void update_navigation_buttons(JWidget window)
|
||||||
|
{
|
||||||
|
JWidget fileview = jwidget_find_name(window, "fileview");
|
||||||
|
JWidget goback = jwidget_find_name(window, "goback");
|
||||||
|
JWidget goforward = jwidget_find_name(window, "goforward");
|
||||||
|
JWidget goup = jwidget_find_name(window, "goup");
|
||||||
|
FileItem *current_folder = fileview_get_current_folder(fileview);
|
||||||
|
|
||||||
|
/* update the state of the go back button: if the navigation-history
|
||||||
|
has two elements and the navigation-position isn't the first
|
||||||
|
one */
|
||||||
|
if (jlist_length(navigation_history) > 1 &&
|
||||||
|
(!navigation_position ||
|
||||||
|
navigation_position != jlist_first(navigation_history))) {
|
||||||
|
jwidget_enable(goback);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
jwidget_disable(goback);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* update the state of the go forward button: if the
|
||||||
|
navigation-history has two elements and the navigation-position
|
||||||
|
isn't the last one */
|
||||||
|
if (jlist_length(navigation_history) > 1 &&
|
||||||
|
(!navigation_position ||
|
||||||
|
navigation_position != jlist_last(navigation_history))) {
|
||||||
|
jwidget_enable(goforward);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
jwidget_disable(goforward);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* update the state of the go up button: if the current-folder isn't
|
||||||
|
the root-item */
|
||||||
|
if (current_folder != get_root_fileitem())
|
||||||
|
jwidget_enable(goup);
|
||||||
|
else
|
||||||
|
jwidget_disable(goup);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void add_in_navigation_history(FileItem *folder)
|
||||||
|
{
|
||||||
|
assert(fileitem_is_folder(folder));
|
||||||
|
|
||||||
|
/* remove the history from the current position */
|
||||||
|
if (navigation_position) {
|
||||||
|
JLink next;
|
||||||
|
for (navigation_position = navigation_position->next;
|
||||||
|
navigation_position != navigation_history->end;
|
||||||
|
navigation_position = next) {
|
||||||
|
next = navigation_position->next;
|
||||||
|
jlist_delete_link(navigation_history,
|
||||||
|
navigation_position);
|
||||||
|
}
|
||||||
|
navigation_position = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* if the history is empty or if the last item isn't the folder that
|
||||||
|
we are visiting... */
|
||||||
|
if (jlist_empty(navigation_history) ||
|
||||||
|
jlist_last_data(navigation_history) != folder) {
|
||||||
|
/* ...we can add the location in the history */
|
||||||
|
jlist_append(navigation_history, folder);
|
||||||
|
navigation_position = jlist_last(navigation_history);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void select_filetype_from_filename(JWidget window)
|
||||||
|
{
|
||||||
|
JWidget entry = jwidget_find_name(window, "filename");
|
||||||
|
JWidget filetype = jwidget_find_name(window, "filetype");
|
||||||
|
const char *filename = jwidget_get_text(entry);
|
||||||
|
char *p = get_extension(filename);
|
||||||
|
char buf[MAX_PATH];
|
||||||
|
|
||||||
|
if (p && *p != 0) {
|
||||||
|
ustrcpy(buf, get_extension(filename));
|
||||||
|
ustrlwr(buf);
|
||||||
|
jcombobox_select_string(filetype, buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void goback_command(JWidget widget)
|
||||||
|
{
|
||||||
|
JWidget fileview = jwidget_find_name(jwidget_get_window(widget),
|
||||||
|
"fileview");
|
||||||
|
|
||||||
|
if (jlist_length(navigation_history) > 1) {
|
||||||
|
if (!navigation_position)
|
||||||
|
navigation_position = jlist_last(navigation_history);
|
||||||
|
|
||||||
|
if (navigation_position->prev != navigation_history->end) {
|
||||||
|
navigation_position = navigation_position->prev;
|
||||||
|
|
||||||
|
navigation_locked = TRUE;
|
||||||
|
fileview_set_current_folder(fileview,
|
||||||
|
navigation_position->data);
|
||||||
|
navigation_locked = FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void goforward_command(JWidget widget)
|
||||||
|
{
|
||||||
|
JWidget fileview = jwidget_find_name(jwidget_get_window(widget),
|
||||||
|
"fileview");
|
||||||
|
|
||||||
|
if (jlist_length(navigation_history) > 1) {
|
||||||
|
if (!navigation_position)
|
||||||
|
navigation_position = jlist_first(navigation_history);
|
||||||
|
|
||||||
|
if (navigation_position->next != navigation_history->end) {
|
||||||
|
navigation_position = navigation_position->next;
|
||||||
|
|
||||||
|
navigation_locked = TRUE;
|
||||||
|
fileview_set_current_folder(fileview,
|
||||||
|
navigation_position->data);
|
||||||
|
navigation_locked = FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void goup_command(JWidget widget)
|
||||||
|
{
|
||||||
|
JWidget fileview = jwidget_find_name(jwidget_get_window(widget),
|
||||||
|
"fileview");
|
||||||
|
fileview_goup(fileview);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool fileview_msg_proc(JWidget widget, JMessage msg)
|
||||||
|
{
|
||||||
|
if (msg->type == JM_SIGNAL) {
|
||||||
|
switch (msg->signal.num) {
|
||||||
|
|
||||||
|
case SIGNAL_FILEVIEW_FILE_SELECTED: {
|
||||||
|
FileItem *fileitem = fileview_get_selected(widget);
|
||||||
|
|
||||||
|
if (!fileitem_is_folder(fileitem)) {
|
||||||
|
JWidget window = jwidget_get_window(widget);
|
||||||
|
JWidget entry = jwidget_find_name(window, "filename");
|
||||||
|
const char *filename = fileitem_get_filename(fileitem);
|
||||||
|
|
||||||
|
jwidget_set_text(entry, get_filename(filename));
|
||||||
|
select_filetype_from_filename(window);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case SIGNAL_FILEVIEW_FILE_ACCEPT:
|
||||||
|
jwidget_close_window(widget);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SIGNAL_FILEVIEW_CURRENT_FOLDER_CHANGED: {
|
||||||
|
JWidget window = jwidget_get_window(widget);
|
||||||
|
|
||||||
|
if (!navigation_locked)
|
||||||
|
add_in_navigation_history(fileview_get_current_folder(widget));
|
||||||
|
|
||||||
|
update_location(window);
|
||||||
|
update_navigation_buttons(window);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
static bool location_msg_proc(JWidget widget, JMessage msg)
|
||||||
* Adds a new bookmark.
|
|
||||||
*/
|
|
||||||
static void add_bookmark_command(JWidget widget, void *data)
|
|
||||||
{
|
{
|
||||||
JWidget combobox = data;
|
if (msg->type == JM_SIGNAL) {
|
||||||
char buf[64], path[1024];
|
switch (msg->signal.num) {
|
||||||
int count;
|
|
||||||
|
case JI_SIGNAL_COMBOBOX_SELECT: {
|
||||||
|
FileItem *fileitem =
|
||||||
|
jcombobox_get_data(widget,
|
||||||
|
jcombobox_get_selected_index(widget));
|
||||||
|
|
||||||
count = get_config_int("Bookmarks", "Count", 0);
|
if (fileitem) {
|
||||||
count = MID(0, count, 256);
|
JWidget fileview = jwidget_find_name(jwidget_get_window(widget),
|
||||||
|
"fileview");
|
||||||
|
|
||||||
if (count < 256) {
|
fileview_set_current_folder(fileview, fileitem);
|
||||||
replace_filename(path, ji_file_select_get_current_path(), "", 1024);
|
}
|
||||||
|
break;
|
||||||
jcombobox_add_string(combobox, path);
|
|
||||||
|
|
||||||
usprintf(buf, "Mark%02d", count);
|
|
||||||
|
|
||||||
set_config_string("Bookmarks", buf, path);
|
|
||||||
set_config_int("Bookmarks", "Count", count+1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Deletes a bookmark.
|
|
||||||
*/
|
|
||||||
static void del_bookmark_command(JWidget widget, void *data)
|
|
||||||
{
|
|
||||||
JWidget combobox = data;
|
|
||||||
char buf[64], path[1024];
|
|
||||||
int index, count;
|
|
||||||
|
|
||||||
count = jcombobox_get_count(combobox);
|
|
||||||
if (count > 0) {
|
|
||||||
replace_filename(path, ji_file_select_get_current_path(), "", 1024);
|
|
||||||
|
|
||||||
index = jcombobox_get_index(combobox, path);
|
|
||||||
if (index >= 0 && index < count) {
|
|
||||||
jcombobox_del_index(combobox, index);
|
|
||||||
|
|
||||||
for (; index<count; index++) {
|
|
||||||
usprintf(buf, "Mark%02d", index);
|
|
||||||
set_config_string("Bookmarks", buf,
|
|
||||||
jcombobox_get_string(combobox, index));
|
|
||||||
}
|
}
|
||||||
usprintf(buf, "Mark%02d", index);
|
|
||||||
set_config_string("Bookmarks", buf, "");
|
|
||||||
|
|
||||||
set_config_int("Bookmarks", "Count", count-1);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
static bool filetype_msg_proc(JWidget widget, JMessage msg)
|
||||||
* Fills the combo-box with the existent bookmarks.
|
|
||||||
*/
|
|
||||||
static void fill_bookmarks_combobox(JWidget combobox)
|
|
||||||
{
|
{
|
||||||
const char *path;
|
if (msg->type == JM_SIGNAL) {
|
||||||
char buf[256];
|
switch (msg->signal.num) {
|
||||||
int c, count;
|
|
||||||
|
|
||||||
count = get_config_int("Bookmarks", "Count", 0);
|
case JI_SIGNAL_COMBOBOX_SELECT: {
|
||||||
count = MID(0, count, 256);
|
const char *ext = jcombobox_get_selected_string(widget);
|
||||||
|
JWidget window = jwidget_get_window(widget);
|
||||||
|
JWidget entry = jwidget_find_name(window, "filename");
|
||||||
|
char buf[MAX_PATH];
|
||||||
|
char *p;
|
||||||
|
|
||||||
for (c=0; c<count; c++) {
|
ustrcpy(buf, jwidget_get_text(entry));
|
||||||
usprintf(buf, "Mark%02d", c);
|
p = get_extension(buf);
|
||||||
path = get_config_string("Bookmarks", buf, "");
|
if (p && *p != 0) {
|
||||||
if (path && *path)
|
ustrcpy(p, ext);
|
||||||
jcombobox_add_string(combobox, path);
|
jwidget_set_text(entry, buf);
|
||||||
}
|
}
|
||||||
}
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Goes to the "Home" folder.
|
|
||||||
*/
|
|
||||||
static void home_command(JWidget widget)
|
|
||||||
{
|
|
||||||
char *env;
|
|
||||||
|
|
||||||
/* in Windows we can use the "My Documents" folder */
|
|
||||||
#ifdef ALLEGRO_WINDOWS
|
|
||||||
TCHAR szPath[MAX_PATH];
|
|
||||||
if (SHGetFolderPath(NULL, CSIDL_PERSONAL | CSIDL_FLAG_CREATE,
|
|
||||||
NULL, 0, szPath) == S_OK) {
|
|
||||||
ji_file_select_enter_to_path(szPath);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* in Unix we can use the HOME enviroment variable */
|
|
||||||
env = getenv("HOME");
|
|
||||||
|
|
||||||
/* home directory? */
|
|
||||||
if ((env) && (*env)) {
|
|
||||||
ji_file_select_enter_to_path(env);
|
|
||||||
}
|
|
||||||
/* ok, maybe we are in DOS, so we can use the ASE directory */
|
|
||||||
else {
|
|
||||||
char path[1024];
|
|
||||||
|
|
||||||
get_executable_name(path, sizeof(path));
|
|
||||||
*get_filename(path) = 0;
|
|
||||||
|
|
||||||
ji_file_select_enter_to_path(path);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Goes to the "Fonts" directory.
|
|
||||||
*/
|
|
||||||
static void fonts_command(JWidget widget)
|
|
||||||
{
|
|
||||||
DIRS *dir, *dirs = filename_in_datadir("fonts/");
|
|
||||||
|
|
||||||
for (dir=dirs; dir; dir=dir->next) {
|
|
||||||
if (ji_dir_exists (dir->path)) {
|
|
||||||
ji_file_select_enter_to_path(dir->path);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return FALSE;
|
||||||
dirs_free(dirs);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Goes to the "Palettes" directory.
|
|
||||||
*/
|
|
||||||
static void palettes_command(JWidget widget)
|
|
||||||
{
|
|
||||||
DIRS *dir, *dirs = filename_in_datadir("palettes/");
|
|
||||||
|
|
||||||
for (dir=dirs; dir; dir=dir->next) {
|
|
||||||
if (ji_dir_exists (dir->path)) {
|
|
||||||
ji_file_select_enter_to_path(dir->path);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dirs_free(dirs);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Shows the dialog to makes a new folder/directory.
|
|
||||||
*/
|
|
||||||
static void mkdir_command(JWidget widget)
|
|
||||||
{
|
|
||||||
JWidget window, box1, box2, label_name, entry_name, button_create, button_cancel;
|
|
||||||
|
|
||||||
window = jwindow_new(_("Make Directory"));
|
|
||||||
box1 = jbox_new(JI_VERTICAL);
|
|
||||||
box2 = jbox_new(JI_HORIZONTAL | JI_HOMOGENEOUS);
|
|
||||||
label_name = jlabel_new(_("Name:"));
|
|
||||||
entry_name = jentry_new(256, _("New Directory"));
|
|
||||||
button_create = jbutton_new(_("&OK"));
|
|
||||||
button_cancel = jbutton_new(_("&Cancel"));
|
|
||||||
|
|
||||||
jwidget_set_min_size(entry_name, JI_SCREEN_W*75/100, 0);
|
|
||||||
|
|
||||||
jwidget_add_child(box2, button_create);
|
|
||||||
jwidget_add_child(box2, button_cancel);
|
|
||||||
jwidget_add_child(box1, label_name);
|
|
||||||
jwidget_add_child(box1, entry_name);
|
|
||||||
jwidget_add_child(box1, box2);
|
|
||||||
jwidget_add_child(window, box1);
|
|
||||||
|
|
||||||
jwidget_magnetic(button_create, TRUE);
|
|
||||||
|
|
||||||
jwindow_open_fg(window);
|
|
||||||
|
|
||||||
if (jwindow_get_killer(window) == button_create) {
|
|
||||||
char buf[1024];
|
|
||||||
int res;
|
|
||||||
|
|
||||||
ustrcpy(buf, ji_file_select_get_current_path());
|
|
||||||
put_backslash(buf);
|
|
||||||
ustrcat(buf, jwidget_get_text(entry_name));
|
|
||||||
|
|
||||||
#if defined ALLEGRO_UNIX || defined ALLEGRO_DJGPP
|
|
||||||
res = mkdir(buf, 0777);
|
|
||||||
#else
|
|
||||||
res = mkdir(buf);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (res != 0)
|
|
||||||
jalert(_("Error<<Error making the directory||&Close"));
|
|
||||||
/* fill again the file-list */
|
|
||||||
else
|
|
||||||
ji_file_select_refresh_listbox();
|
|
||||||
}
|
|
||||||
|
|
||||||
jwidget_free(window);
|
|
||||||
}
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/* ASE - Allegro Sprite Editor
|
/* ASE - Allegro Sprite Editor
|
||||||
* Copyright (C) 2001-2005, 2007 David A. Capello
|
* Copyright (C) 2001-2005, 2007, 2008 David A. Capello
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -19,9 +19,9 @@
|
|||||||
#ifndef DIALOGS_FILESEL_H
|
#ifndef DIALOGS_FILESEL_H
|
||||||
#define DIALOGS_FILESEL_H
|
#define DIALOGS_FILESEL_H
|
||||||
|
|
||||||
char *GUI_FileSelect(const char *message,
|
char *ase_file_selector(const char *message,
|
||||||
const char *init_path,
|
const char *init_path,
|
||||||
const char *exts);
|
const char *exts);
|
||||||
|
|
||||||
#endif /* DIALOGS_FILESEL_H */
|
#endif /* DIALOGS_FILESEL_H */
|
||||||
|
|
||||||
|
@ -268,11 +268,12 @@ bool effect_apply_step(Effect *effect)
|
|||||||
|
|
||||||
void effect_apply(Effect *effect)
|
void effect_apply(Effect *effect)
|
||||||
{
|
{
|
||||||
add_progress(effect->h);
|
/* add_progress(effect->h); */
|
||||||
|
|
||||||
effect_begin(effect);
|
effect_begin(effect);
|
||||||
while (effect_apply_step(effect))
|
while (effect_apply_step(effect))
|
||||||
do_progress(effect->row);
|
;
|
||||||
|
/* do_progress(effect->row); */
|
||||||
|
|
||||||
/* undo stuff */
|
/* undo stuff */
|
||||||
if (undo_is_enabled(effect->sprite->undo))
|
if (undo_is_enabled(effect->sprite->undo))
|
||||||
@ -282,7 +283,7 @@ void effect_apply(Effect *effect)
|
|||||||
/* copy "dst" to "src" */
|
/* copy "dst" to "src" */
|
||||||
image_copy(effect->src, effect->dst, 0, 0);
|
image_copy(effect->src, effect->dst, 0, 0);
|
||||||
|
|
||||||
del_progress();
|
/* del_progress(); */
|
||||||
}
|
}
|
||||||
|
|
||||||
void effect_flush(Effect *effect)
|
void effect_flush(Effect *effect)
|
||||||
@ -343,15 +344,15 @@ void effect_apply_to_target(Effect *effect)
|
|||||||
undo_open(effect->sprite->undo);
|
undo_open(effect->sprite->undo);
|
||||||
}
|
}
|
||||||
|
|
||||||
add_progress(images);
|
/* add_progress(images); */
|
||||||
for (n=n2=0; n<stock->nimage; n++) {
|
for (n=n2=0; n<stock->nimage; n++) {
|
||||||
if (!stock->image[n])
|
if (!stock->image[n])
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
do_progress(n2++);
|
/* do_progress(n2++); */
|
||||||
effect_apply_to_image(effect, stock->image[n], x[n], y[n]);
|
effect_apply_to_image(effect, stock->image[n], x[n], y[n]);
|
||||||
}
|
}
|
||||||
del_progress();
|
/* del_progress(); */
|
||||||
|
|
||||||
if (images > 1) {
|
if (images > 1) {
|
||||||
/* close */
|
/* close */
|
||||||
|
@ -24,8 +24,7 @@
|
|||||||
|
|
||||||
#include "jinete/jlist.h"
|
#include "jinete/jlist.h"
|
||||||
|
|
||||||
#include "console/console.h"
|
/* #include "file/ase_format.h" */
|
||||||
#include "file/ase_format.h"
|
|
||||||
#include "file/file.h"
|
#include "file/file.h"
|
||||||
#include "raster/raster.h"
|
#include "raster/raster.h"
|
||||||
|
|
||||||
@ -69,17 +68,14 @@ typedef struct ASE_FrameHeader
|
|||||||
ase_uint16 duration;
|
ase_uint16 duration;
|
||||||
} ASE_FrameHeader;
|
} ASE_FrameHeader;
|
||||||
|
|
||||||
static Sprite *load_ASE(const char *filename);
|
static bool load_ASE(FileOp *fop);
|
||||||
static int save_ASE(Sprite *sprite);
|
static bool save_ASE(FileOp *fop);
|
||||||
|
|
||||||
static ASE_FrameHeader *current_frame_header = NULL;
|
static ASE_FrameHeader *current_frame_header = NULL;
|
||||||
static int chunk_type;
|
static int chunk_type;
|
||||||
static int chunk_start;
|
static int chunk_start;
|
||||||
|
|
||||||
static Sprite *ase_file_read(const char *filename);
|
static bool ase_file_read_header(FILE *f, ASE_Header *header);
|
||||||
static int ase_file_write(Sprite *sprite);
|
|
||||||
|
|
||||||
static int ase_file_read_header(FILE *f, ASE_Header *header);
|
|
||||||
static void ase_file_prepare_header(FILE *f, ASE_Header *header, Sprite *sprite);
|
static void ase_file_prepare_header(FILE *f, ASE_Header *header, Sprite *sprite);
|
||||||
static void ase_file_write_header(FILE *f, ASE_Header *header);
|
static void ase_file_write_header(FILE *f, ASE_Header *header);
|
||||||
|
|
||||||
@ -88,7 +84,7 @@ static void ase_file_prepare_frame_header(FILE *f, ASE_FrameHeader *frame_header
|
|||||||
static void ase_file_write_frame_header(FILE *f, ASE_FrameHeader *frame_header);
|
static void ase_file_write_frame_header(FILE *f, ASE_FrameHeader *frame_header);
|
||||||
|
|
||||||
static void ase_file_write_layers(FILE *f, Layer *layer);
|
static void ase_file_write_layers(FILE *f, Layer *layer);
|
||||||
static void ase_file_write_cels(FILE *f, Sprite *sprite, Layer *layer, int frpos);
|
static void ase_file_write_cels(FILE *f, Sprite *sprite, Layer *layer, int frame);
|
||||||
|
|
||||||
static void ase_file_read_padding(FILE *f, int bytes);
|
static void ase_file_read_padding(FILE *f, int bytes);
|
||||||
static void ase_file_write_padding(FILE *f, int bytes);
|
static void ase_file_write_padding(FILE *f, int bytes);
|
||||||
@ -102,15 +98,20 @@ static void ase_file_read_color_chunk(FILE *f, RGB *pal);
|
|||||||
static void ase_file_write_color_chunk(FILE *f, RGB *pal);
|
static void ase_file_write_color_chunk(FILE *f, RGB *pal);
|
||||||
static Layer *ase_file_read_layer_chunk(FILE *f, Sprite *sprite, Layer **previous_layer, int *current_level);
|
static Layer *ase_file_read_layer_chunk(FILE *f, Sprite *sprite, Layer **previous_layer, int *current_level);
|
||||||
static void ase_file_write_layer_chunk(FILE *f, Layer *layer);
|
static void ase_file_write_layer_chunk(FILE *f, Layer *layer);
|
||||||
static Cel *ase_file_read_cel_chunk(FILE *f, Sprite *sprite, int frpos, int imgtype);
|
static Cel *ase_file_read_cel_chunk(FILE *f, Sprite *sprite, int frame, int imgtype, FileOp *fop, ASE_Header *header);
|
||||||
static void ase_file_write_cel_chunk(FILE *f, Cel *cel, Layer *layer, Sprite *sprite);
|
static void ase_file_write_cel_chunk(FILE *f, Cel *cel, Layer *layer, Sprite *sprite);
|
||||||
static Mask *ase_file_read_mask_chunk(FILE *f);
|
static Mask *ase_file_read_mask_chunk(FILE *f);
|
||||||
static void ase_file_write_mask_chunk(FILE *f, Mask *mask);
|
static void ase_file_write_mask_chunk(FILE *f, Mask *mask);
|
||||||
|
|
||||||
|
static int fgetw(FILE *file);
|
||||||
|
static long fgetl(FILE *file);
|
||||||
|
static int fputw(int w, FILE *file);
|
||||||
|
static int fputl(long l, FILE *file);
|
||||||
|
|
||||||
FileFormat format_ase =
|
FileFormat format_ase =
|
||||||
{
|
{
|
||||||
"ase",
|
"ase,aseprite",
|
||||||
"ase",
|
"ase,aseprite",
|
||||||
load_ASE,
|
load_ASE,
|
||||||
save_ASE,
|
save_ASE,
|
||||||
FILE_SUPPORT_RGB |
|
FILE_SUPPORT_RGB |
|
||||||
@ -125,45 +126,7 @@ FileFormat format_ase =
|
|||||||
FILE_SUPPORT_PATHS_REPOSITORY
|
FILE_SUPPORT_PATHS_REPOSITORY
|
||||||
};
|
};
|
||||||
|
|
||||||
static Sprite *load_ASE(const char *filename)
|
static bool load_ASE(FileOp *fop)
|
||||||
{
|
|
||||||
return ase_file_read(filename);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int save_ASE(Sprite *sprite)
|
|
||||||
{
|
|
||||||
return ase_file_write(sprite);
|
|
||||||
}
|
|
||||||
|
|
||||||
static Sprite *ase_file_read(const char *filename)
|
|
||||||
{
|
|
||||||
Sprite *sprite = NULL;
|
|
||||||
FILE *f;
|
|
||||||
|
|
||||||
f = fopen(filename, "rb");
|
|
||||||
if (f) {
|
|
||||||
sprite = ase_file_read_f(f);
|
|
||||||
fclose(f);
|
|
||||||
}
|
|
||||||
|
|
||||||
return sprite;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int ase_file_write(Sprite *sprite)
|
|
||||||
{
|
|
||||||
int ret = -1;
|
|
||||||
FILE *f;
|
|
||||||
|
|
||||||
f = fopen(sprite->filename, "wb");
|
|
||||||
if (f) {
|
|
||||||
ret = ase_file_write_f(f, sprite);
|
|
||||||
fclose(f);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
Sprite *ase_file_read_f(FILE *f)
|
|
||||||
{
|
{
|
||||||
Sprite *sprite = NULL;
|
Sprite *sprite = NULL;
|
||||||
ASE_Header header;
|
ASE_Header header;
|
||||||
@ -174,11 +137,17 @@ Sprite *ase_file_read_f(FILE *f)
|
|||||||
int chunk_pos;
|
int chunk_pos;
|
||||||
int chunk_size;
|
int chunk_size;
|
||||||
int chunk_type;
|
int chunk_type;
|
||||||
int c, frpos;
|
int c, frame;
|
||||||
|
FILE *f;
|
||||||
|
|
||||||
if (ase_file_read_header(f, &header) != 0) {
|
f = fopen(fop->filename, "rb");
|
||||||
console_printf(_("Error reading header\n"));
|
if (!f)
|
||||||
return NULL;
|
return FALSE;
|
||||||
|
|
||||||
|
if (!ase_file_read_header(f, &header)) {
|
||||||
|
fop_error(fop, _("Error reading header\n"));
|
||||||
|
fclose(f);
|
||||||
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* create the new sprite */
|
/* create the new sprite */
|
||||||
@ -186,8 +155,9 @@ Sprite *ase_file_read_f(FILE *f)
|
|||||||
header.depth == 16 ? IMAGE_GRAYSCALE: IMAGE_INDEXED,
|
header.depth == 16 ? IMAGE_GRAYSCALE: IMAGE_INDEXED,
|
||||||
header.width, header.height);
|
header.width, header.height);
|
||||||
if (!sprite) {
|
if (!sprite) {
|
||||||
console_printf(_("Error creating sprite with file spec\n"));
|
fop_error(fop, _("Error creating sprite with file spec\n"));
|
||||||
return NULL;
|
fclose(f);
|
||||||
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* set frames and speed */
|
/* set frames and speed */
|
||||||
@ -215,14 +185,11 @@ Sprite *ase_file_read_f(FILE *f)
|
|||||||
last_layer = sprite->set;
|
last_layer = sprite->set;
|
||||||
current_level = -1;
|
current_level = -1;
|
||||||
|
|
||||||
/* progress */
|
|
||||||
add_progress(header.size);
|
|
||||||
|
|
||||||
/* read frame by frame to end-of-file */
|
/* read frame by frame to end-of-file */
|
||||||
for (frpos=0; frpos<sprite->frames; frpos++) {
|
for (frame=0; frame<sprite->frames; frame++) {
|
||||||
/* start frame position */
|
/* start frame position */
|
||||||
frame_pos = ftell(f);
|
frame_pos = ftell(f);
|
||||||
do_progress(frame_pos);
|
fop_progress(fop, (float)frame_pos / (float)header.size);
|
||||||
|
|
||||||
/* read frame header */
|
/* read frame header */
|
||||||
ase_file_read_frame_header(f, &frame_header);
|
ase_file_read_frame_header(f, &frame_header);
|
||||||
@ -231,13 +198,13 @@ Sprite *ase_file_read_f(FILE *f)
|
|||||||
if (frame_header.magic == ASE_FILE_FRAME_MAGIC) {
|
if (frame_header.magic == ASE_FILE_FRAME_MAGIC) {
|
||||||
/* use frame-duration field? */
|
/* use frame-duration field? */
|
||||||
if (frame_header.duration > 0)
|
if (frame_header.duration > 0)
|
||||||
sprite_set_frlen(sprite, frame_header.duration, frpos);
|
sprite_set_frlen(sprite, frame_header.duration, frame);
|
||||||
|
|
||||||
/* read chunks */
|
/* read chunks */
|
||||||
for (c=0; c<frame_header.chunks; c++) {
|
for (c=0; c<frame_header.chunks; c++) {
|
||||||
/* start chunk position */
|
/* start chunk position */
|
||||||
chunk_pos = ftell(f);
|
chunk_pos = ftell(f);
|
||||||
do_progress(chunk_pos);
|
fop_progress(fop, (float)chunk_pos / (float)header.size);
|
||||||
|
|
||||||
/* read chunk information */
|
/* read chunk information */
|
||||||
chunk_size = fgetl(f);
|
chunk_size = fgetl(f);
|
||||||
@ -247,7 +214,7 @@ Sprite *ase_file_read_f(FILE *f)
|
|||||||
|
|
||||||
/* only for 8 bpp images */
|
/* only for 8 bpp images */
|
||||||
case ASE_FILE_CHUNK_FLI_COLOR:
|
case ASE_FILE_CHUNK_FLI_COLOR:
|
||||||
/* console_printf ("Color chunk\n"); */
|
/* fop_error(fop, "Color chunk\n"); */
|
||||||
|
|
||||||
if (sprite->imgtype == IMAGE_INDEXED) {
|
if (sprite->imgtype == IMAGE_INDEXED) {
|
||||||
/* TODO fix to read palette-per-frame */
|
/* TODO fix to read palette-per-frame */
|
||||||
@ -256,11 +223,11 @@ Sprite *ase_file_read_f(FILE *f)
|
|||||||
sprite_set_palette(sprite, palette, 0);
|
sprite_set_palette(sprite, palette, 0);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
console_printf(_("Warning: was found a color chunk in non-8bpp file\n"));
|
fop_error(fop, _("Warning: was found a color chunk in non-8bpp file\n"));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ASE_FILE_CHUNK_LAYER: {
|
case ASE_FILE_CHUNK_LAYER: {
|
||||||
/* console_printf("Layer chunk\n"); */
|
/* fop_error(fop, "Layer chunk\n"); */
|
||||||
|
|
||||||
ase_file_read_layer_chunk(f, sprite,
|
ase_file_read_layer_chunk(f, sprite,
|
||||||
&last_layer,
|
&last_layer,
|
||||||
@ -269,32 +236,32 @@ Sprite *ase_file_read_f(FILE *f)
|
|||||||
}
|
}
|
||||||
|
|
||||||
case ASE_FILE_CHUNK_CEL: {
|
case ASE_FILE_CHUNK_CEL: {
|
||||||
/* console_printf("Cel chunk\n"); */
|
/* fop_error(fop, "Cel chunk\n"); */
|
||||||
|
|
||||||
ase_file_read_cel_chunk(f, sprite, frpos, sprite->imgtype);
|
ase_file_read_cel_chunk(f, sprite, frame, sprite->imgtype, fop, &header);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case ASE_FILE_CHUNK_MASK: {
|
case ASE_FILE_CHUNK_MASK: {
|
||||||
Mask *mask;
|
Mask *mask;
|
||||||
|
|
||||||
/* console_printf("Mask chunk\n"); */
|
/* fop_error(fop, "Mask chunk\n"); */
|
||||||
|
|
||||||
mask = ase_file_read_mask_chunk(f);
|
mask = ase_file_read_mask_chunk(f);
|
||||||
if (mask)
|
if (mask)
|
||||||
sprite_add_mask(sprite, mask);
|
sprite_add_mask(sprite, mask);
|
||||||
else
|
else
|
||||||
console_printf(_("Warning: error loading a mask chunk\n"));
|
fop_error(fop, _("Warning: error loading a mask chunk\n"));
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case ASE_FILE_CHUNK_PATH:
|
case ASE_FILE_CHUNK_PATH:
|
||||||
/* console_printf("Path chunk\n"); */
|
/* fop_error(fop, "Path chunk\n"); */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
console_printf(_("Warning: Unsupported chunk type %d (skipping)\n"), chunk_type);
|
fop_error(fop, _("Warning: Unsupported chunk type %d (skipping)\n"), chunk_type);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -307,37 +274,38 @@ Sprite *ase_file_read_f(FILE *f)
|
|||||||
fseek(f, frame_pos+frame_header.size, SEEK_SET);
|
fseek(f, frame_pos+frame_header.size, SEEK_SET);
|
||||||
}
|
}
|
||||||
|
|
||||||
del_progress();
|
fop->sprite = sprite;
|
||||||
|
fclose(f);
|
||||||
|
|
||||||
return sprite;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ase_file_write_f(FILE *f, Sprite *sprite)
|
static bool save_ASE(FileOp *fop)
|
||||||
{
|
{
|
||||||
|
Sprite *sprite = fop->sprite;
|
||||||
ASE_Header header;
|
ASE_Header header;
|
||||||
ASE_FrameHeader frame_header;
|
ASE_FrameHeader frame_header;
|
||||||
JLink link;
|
JLink link;
|
||||||
int frpos;
|
int frame;
|
||||||
|
FILE *f;
|
||||||
|
|
||||||
|
f = fopen(fop->filename, "wb");
|
||||||
|
if (!f)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
/* prepare the header */
|
/* prepare the header */
|
||||||
ase_file_prepare_header(f, &header, sprite);
|
ase_file_prepare_header(f, &header, sprite);
|
||||||
|
|
||||||
/* add a new progress bar */
|
|
||||||
add_progress(sprite->frames);
|
|
||||||
|
|
||||||
/* write frame */
|
/* write frame */
|
||||||
for (frpos=0; frpos<sprite->frames; frpos++) {
|
for (frame=0; frame<sprite->frames; frame++) {
|
||||||
/* progress */
|
|
||||||
do_progress(frpos);
|
|
||||||
|
|
||||||
/* prepare the header */
|
/* prepare the header */
|
||||||
ase_file_prepare_frame_header(f, &frame_header);
|
ase_file_prepare_frame_header(f, &frame_header);
|
||||||
|
|
||||||
/* frame duration */
|
/* frame duration */
|
||||||
frame_header.duration = sprite_get_frlen(sprite, frpos);
|
frame_header.duration = sprite_get_frlen(sprite, frame);
|
||||||
|
|
||||||
/* write extra chunks in the first frame */
|
/* write extra chunks in the first frame */
|
||||||
if (frpos == 0) {
|
if (frame == 0) {
|
||||||
/* color chunk */
|
/* color chunk */
|
||||||
if (sprite->imgtype == IMAGE_INDEXED)
|
if (sprite->imgtype == IMAGE_INDEXED)
|
||||||
/* TODO fix this to write palette per-frame */
|
/* TODO fix this to write palette per-frame */
|
||||||
@ -353,27 +321,30 @@ int ase_file_write_f(FILE *f, Sprite *sprite)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* write cel chunks */
|
/* write cel chunks */
|
||||||
ase_file_write_cels(f, sprite, sprite->set, frpos);
|
ase_file_write_cels(f, sprite, sprite->set, frame);
|
||||||
|
|
||||||
/* write the frame header */
|
/* write the frame header */
|
||||||
ase_file_write_frame_header(f, &frame_header);
|
ase_file_write_frame_header(f, &frame_header);
|
||||||
}
|
|
||||||
|
|
||||||
del_progress();
|
/* progress */
|
||||||
|
if (sprite->frames > 1)
|
||||||
|
fop_progress(fop, (float)(frame+1) / (float)(sprite->frames));
|
||||||
|
}
|
||||||
|
|
||||||
/* write the header */
|
/* write the header */
|
||||||
ase_file_write_header(f, &header);
|
ase_file_write_header(f, &header);
|
||||||
return 0;
|
fclose(f);
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ase_file_read_header(FILE *f, ASE_Header *header)
|
static bool ase_file_read_header(FILE *f, ASE_Header *header)
|
||||||
{
|
{
|
||||||
header->pos = ftell(f);
|
header->pos = ftell(f);
|
||||||
|
|
||||||
header->size = fgetl(f);
|
header->size = fgetl(f);
|
||||||
header->magic = fgetw(f);
|
header->magic = fgetw(f);
|
||||||
if (header->magic != ASE_FILE_MAGIC)
|
if (header->magic != ASE_FILE_MAGIC)
|
||||||
return -1;
|
return FALSE;
|
||||||
|
|
||||||
header->frames = fgetw(f);
|
header->frames = fgetw(f);
|
||||||
header->width = fgetw(f);
|
header->width = fgetw(f);
|
||||||
@ -389,7 +360,7 @@ static int ase_file_read_header(FILE *f, ASE_Header *header)
|
|||||||
header->bgcolor[3] = fgetc(f);
|
header->bgcolor[3] = fgetc(f);
|
||||||
|
|
||||||
fseek(f, header->pos+128, SEEK_SET);
|
fseek(f, header->pos+128, SEEK_SET);
|
||||||
return 0;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ase_file_prepare_header(FILE *f, ASE_Header *header, Sprite *sprite)
|
static void ase_file_prepare_header(FILE *f, ASE_Header *header, Sprite *sprite)
|
||||||
@ -512,14 +483,14 @@ static void ase_file_write_layers(FILE *f, Layer *layer)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ase_file_write_cels(FILE *f, Sprite *sprite, Layer *layer, int frpos)
|
static void ase_file_write_cels(FILE *f, Sprite *sprite, Layer *layer, int frame)
|
||||||
{
|
{
|
||||||
if (layer_is_image(layer)) {
|
if (layer_is_image(layer)) {
|
||||||
Cel *cel = layer_get_cel(layer, frpos);
|
Cel *cel = layer_get_cel(layer, frame);
|
||||||
|
|
||||||
if (cel) {
|
if (cel) {
|
||||||
/* console_printf("New cel in frpos %d, in layer %d\n", */
|
/* fop_error(fop, "New cel in frame %d, in layer %d\n", */
|
||||||
/* frpos, sprite_layer2index(sprite, layer)); */
|
/* frame, sprite_layer2index(sprite, layer)); */
|
||||||
|
|
||||||
ase_file_write_cel_chunk(f, cel, layer, sprite);
|
ase_file_write_cel_chunk(f, cel, layer, sprite);
|
||||||
}
|
}
|
||||||
@ -528,7 +499,7 @@ static void ase_file_write_cels(FILE *f, Sprite *sprite, Layer *layer, int frpos
|
|||||||
if (layer_is_set(layer)) {
|
if (layer_is_set(layer)) {
|
||||||
JLink link;
|
JLink link;
|
||||||
JI_LIST_FOR_EACH(layer->layers, link)
|
JI_LIST_FOR_EACH(layer->layers, link)
|
||||||
ase_file_write_cels(f, sprite, link->data, frpos);
|
ase_file_write_cels(f, sprite, link->data, frame);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -731,10 +702,10 @@ static void ase_file_write_layer_chunk(FILE *f, Layer *layer)
|
|||||||
|
|
||||||
ase_file_write_close_chunk(f);
|
ase_file_write_close_chunk(f);
|
||||||
|
|
||||||
/* console_printf("Layer name \"%s\" child level: %d\n", layer->name, child_level); */
|
/* fop_error(fop, "Layer name \"%s\" child level: %d\n", layer->name, child_level); */
|
||||||
}
|
}
|
||||||
|
|
||||||
static Cel *ase_file_read_cel_chunk(FILE *f, Sprite *sprite, int frpos, int imgtype)
|
static Cel *ase_file_read_cel_chunk(FILE *f, Sprite *sprite, int frame, int imgtype, FileOp *fop, ASE_Header *header)
|
||||||
{
|
{
|
||||||
Cel *cel;
|
Cel *cel;
|
||||||
/* read chunk data */
|
/* read chunk data */
|
||||||
@ -749,14 +720,13 @@ static Cel *ase_file_read_cel_chunk(FILE *f, Sprite *sprite, int frpos, int imgt
|
|||||||
|
|
||||||
layer = sprite_index2layer(sprite, layer_index);
|
layer = sprite_index2layer(sprite, layer_index);
|
||||||
if (!layer) {
|
if (!layer) {
|
||||||
console_printf(_("Frame %d didn't found layer with index %d\n"),
|
fop_error(fop, _("Frame %d didn't found layer with index %d\n"),
|
||||||
frpos, layer_index);
|
frame, layer_index);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
/* console_printf("Layer found: %d -> %s\n", layer_index, layer->name); */
|
|
||||||
|
|
||||||
/* create the new frame */
|
/* create the new frame */
|
||||||
cel = cel_new(frpos, 0);
|
cel = cel_new(frame, 0);
|
||||||
cel_set_position(cel, x, y);
|
cel_set_position(cel, x, y);
|
||||||
cel_set_opacity(cel, opacity);
|
cel_set_opacity(cel, opacity);
|
||||||
|
|
||||||
@ -789,8 +759,8 @@ static Cel *ase_file_read_cel_chunk(FILE *f, Sprite *sprite, int frpos, int imgt
|
|||||||
a = fgetc(f);
|
a = fgetc(f);
|
||||||
image->method->putpixel(image, x, y, _rgba(r, g, b, a));
|
image->method->putpixel(image, x, y, _rgba(r, g, b, a));
|
||||||
}
|
}
|
||||||
|
fop_progress(fop, (float)ftell(f) / (float)header->size);
|
||||||
}
|
}
|
||||||
do_progress(ftell(f));
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IMAGE_GRAYSCALE:
|
case IMAGE_GRAYSCALE:
|
||||||
@ -800,16 +770,17 @@ static Cel *ase_file_read_cel_chunk(FILE *f, Sprite *sprite, int frpos, int imgt
|
|||||||
a = fgetc(f);
|
a = fgetc(f);
|
||||||
image->method->putpixel(image, x, y, _graya(k, a));
|
image->method->putpixel(image, x, y, _graya(k, a));
|
||||||
}
|
}
|
||||||
|
fop_progress(fop, (float)ftell(f) / (float)header->size);
|
||||||
}
|
}
|
||||||
do_progress(ftell(f));
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IMAGE_INDEXED:
|
case IMAGE_INDEXED:
|
||||||
for (y=0; y<image->h; y++) {
|
for (y=0; y<image->h; y++) {
|
||||||
for (x=0; x<image->w; x++)
|
for (x=0; x<image->w; x++)
|
||||||
image->method->putpixel(image, x, y, fgetc(f));
|
image->method->putpixel(image, x, y, fgetc(f));
|
||||||
|
|
||||||
|
fop_progress(fop, (float)ftell(f) / (float)header->size);
|
||||||
}
|
}
|
||||||
do_progress(ftell(f));
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -820,8 +791,8 @@ static Cel *ase_file_read_cel_chunk(FILE *f, Sprite *sprite, int frpos, int imgt
|
|||||||
|
|
||||||
case ASE_FILE_LINK_CEL: {
|
case ASE_FILE_LINK_CEL: {
|
||||||
/* read link position */
|
/* read link position */
|
||||||
int link_frpos = fgetw(f);
|
int link_frame = fgetw(f);
|
||||||
Cel *link = layer_get_cel(layer, link_frpos);
|
Cel *link = layer_get_cel(layer, link_frame);
|
||||||
|
|
||||||
if (link)
|
if (link)
|
||||||
cel->image = link->image;
|
cel->image = link->image;
|
||||||
@ -868,9 +839,6 @@ static void ase_file_write_cel_chunk(FILE *f, Cel *cel, Layer *layer, Sprite *sp
|
|||||||
fputw(image->w, f);
|
fputw(image->w, f);
|
||||||
fputw(image->h, f);
|
fputw(image->h, f);
|
||||||
|
|
||||||
/* TODO */
|
|
||||||
/* add_progress(image->h); */
|
|
||||||
|
|
||||||
/* pixel data */
|
/* pixel data */
|
||||||
switch (image->imgtype) {
|
switch (image->imgtype) {
|
||||||
|
|
||||||
@ -883,7 +851,6 @@ static void ase_file_write_cel_chunk(FILE *f, Cel *cel, Layer *layer, Sprite *sp
|
|||||||
fputc(_rgba_getb(c), f);
|
fputc(_rgba_getb(c), f);
|
||||||
fputc(_rgba_geta(c), f);
|
fputc(_rgba_geta(c), f);
|
||||||
}
|
}
|
||||||
/* do_progress(y); */
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -894,7 +861,6 @@ static void ase_file_write_cel_chunk(FILE *f, Cel *cel, Layer *layer, Sprite *sp
|
|||||||
fputc(_graya_getk(c), f);
|
fputc(_graya_getk(c), f);
|
||||||
fputc(_graya_geta(c), f);
|
fputc(_graya_geta(c), f);
|
||||||
}
|
}
|
||||||
/* do_progress(y); */
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -902,13 +868,9 @@ static void ase_file_write_cel_chunk(FILE *f, Cel *cel, Layer *layer, Sprite *sp
|
|||||||
for (y=0; y<image->h; y++) {
|
for (y=0; y<image->h; y++) {
|
||||||
for (x=0; x<image->w; x++)
|
for (x=0; x<image->w; x++)
|
||||||
fputc(image->method->getpixel(image, x, y), f);
|
fputc(image->method->getpixel(image, x, y), f);
|
||||||
|
|
||||||
/* do_progress(y); */
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* del_progress(); */
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* width and height */
|
/* width and height */
|
||||||
@ -993,7 +955,7 @@ static void ase_file_write_mask_chunk(FILE *f, Mask *mask)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* returns a word (16 bits) */
|
/* returns a word (16 bits) */
|
||||||
int fgetw(FILE *file)
|
static int fgetw(FILE *file)
|
||||||
{
|
{
|
||||||
int b1, b2;
|
int b1, b2;
|
||||||
|
|
||||||
@ -1010,7 +972,7 @@ int fgetw(FILE *file)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* returns a dword (32 bits) */
|
/* returns a dword (32 bits) */
|
||||||
long fgetl(FILE *file)
|
static long fgetl(FILE *file)
|
||||||
{
|
{
|
||||||
int b1, b2, b3, b4;
|
int b1, b2, b3, b4;
|
||||||
|
|
||||||
@ -1035,7 +997,7 @@ long fgetl(FILE *file)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* returns 0 in success or -1 in error */
|
/* returns 0 in success or -1 in error */
|
||||||
int fputw(int w, FILE *file)
|
static int fputw(int w, FILE *file)
|
||||||
{
|
{
|
||||||
int b1, b2;
|
int b1, b2;
|
||||||
|
|
||||||
@ -1051,7 +1013,7 @@ int fputw(int w, FILE *file)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* returns 0 in success or -1 in error */
|
/* returns 0 in success or -1 in error */
|
||||||
int fputl(long l, FILE *file)
|
static int fputl(long l, FILE *file)
|
||||||
{
|
{
|
||||||
int b1, b2, b3, b4;
|
int b1, b2, b3, b4;
|
||||||
|
|
||||||
|
@ -25,14 +25,13 @@
|
|||||||
#include <allegro/color.h>
|
#include <allegro/color.h>
|
||||||
#include <allegro/file.h>
|
#include <allegro/file.h>
|
||||||
|
|
||||||
#include "console/console.h"
|
|
||||||
#include "file/file.h"
|
#include "file/file.h"
|
||||||
#include "raster/raster.h"
|
#include "raster/raster.h"
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static Sprite *load_BMP(const char *filename);
|
static bool load_BMP(FileOp *fop);
|
||||||
static int save_BMP(Sprite *sprite);
|
static bool save_BMP(FileOp *fop);
|
||||||
|
|
||||||
FileFormat format_bmp =
|
FileFormat format_bmp =
|
||||||
{
|
{
|
||||||
@ -162,7 +161,7 @@ static int read_os2_bminfoheader(PACKFILE *f, BITMAPINFOHEADER *infoheader)
|
|||||||
/* read_bmicolors:
|
/* read_bmicolors:
|
||||||
* Loads the color palette for 1,4,8 bit formats.
|
* Loads the color palette for 1,4,8 bit formats.
|
||||||
*/
|
*/
|
||||||
static void read_bmicolors(int ncols, PACKFILE *f,int win_flag)
|
static void read_bmicolors(FileOp *fop, int ncols, PACKFILE *f,int win_flag)
|
||||||
{
|
{
|
||||||
int i, r, g, b;
|
int i, r, g, b;
|
||||||
|
|
||||||
@ -170,7 +169,7 @@ static void read_bmicolors(int ncols, PACKFILE *f,int win_flag)
|
|||||||
b = pack_getc(f) / 4;
|
b = pack_getc(f) / 4;
|
||||||
g = pack_getc(f) / 4;
|
g = pack_getc(f) / 4;
|
||||||
r = pack_getc(f) / 4;
|
r = pack_getc(f) / 4;
|
||||||
file_sequence_set_color(i, r, g, b);
|
fop_sequence_set_color(fop, i, r, g, b);
|
||||||
if (win_flag)
|
if (win_flag)
|
||||||
pack_getc(f);
|
pack_getc(f);
|
||||||
}
|
}
|
||||||
@ -280,7 +279,7 @@ static void read_24bit_line(int length, PACKFILE *f, Image *image, int line)
|
|||||||
/* read_image:
|
/* read_image:
|
||||||
* For reading the noncompressed BMP image format.
|
* For reading the noncompressed BMP image format.
|
||||||
*/
|
*/
|
||||||
static void read_image(PACKFILE *f, Image *image, AL_CONST BITMAPINFOHEADER *infoheader)
|
static void read_image(PACKFILE *f, Image *image, AL_CONST BITMAPINFOHEADER *infoheader, FileOp *fop)
|
||||||
{
|
{
|
||||||
int i, line;
|
int i, line;
|
||||||
|
|
||||||
@ -306,8 +305,7 @@ static void read_image(PACKFILE *f, Image *image, AL_CONST BITMAPINFOHEADER *inf
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (infoheader->biHeight > 1)
|
fop_progress(fop, (float)(i+1) / (float)(infoheader->biHeight));
|
||||||
do_progress(100 * i / (infoheader->biHeight-1));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -500,27 +498,23 @@ static void read_bitfields_image(PACKFILE *f, Image *image, int bpp, BITMAPINFOH
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static Sprite *load_BMP(const char *filename)
|
static bool load_BMP(FileOp *fop)
|
||||||
{
|
{
|
||||||
BITMAPFILEHEADER fileheader;
|
BITMAPFILEHEADER fileheader;
|
||||||
BITMAPINFOHEADER infoheader;
|
BITMAPINFOHEADER infoheader;
|
||||||
Image *image;
|
Image *image;
|
||||||
Sprite *sprite;
|
|
||||||
PACKFILE *f;
|
PACKFILE *f;
|
||||||
int ncol;
|
int ncol;
|
||||||
unsigned long biSize;
|
unsigned long biSize;
|
||||||
int type, bpp = 0;
|
int type, bpp = 0;
|
||||||
|
|
||||||
f = pack_fopen(filename, F_READ);
|
f = pack_fopen(fop->filename, F_READ);
|
||||||
if (!f) {
|
if (!f)
|
||||||
if (!file_sequence_sprite())
|
return FALSE;
|
||||||
console_printf(_("Error opening file.\n"));
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (read_bmfileheader(f, &fileheader) != 0) {
|
if (read_bmfileheader(f, &fileheader) != 0) {
|
||||||
pack_fclose(f);
|
pack_fclose(f);
|
||||||
return NULL;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
biSize = pack_igetl(f);
|
biSize = pack_igetl(f);
|
||||||
@ -528,28 +522,28 @@ static Sprite *load_BMP(const char *filename)
|
|||||||
if (biSize == WININFOHEADERSIZE) {
|
if (biSize == WININFOHEADERSIZE) {
|
||||||
if (read_win_bminfoheader(f, &infoheader) != 0) {
|
if (read_win_bminfoheader(f, &infoheader) != 0) {
|
||||||
pack_fclose(f);
|
pack_fclose(f);
|
||||||
return NULL;
|
return FALSE;
|
||||||
}
|
}
|
||||||
/* compute number of colors recorded */
|
/* compute number of colors recorded */
|
||||||
ncol = (fileheader.bfOffBits - 54) / 4;
|
ncol = (fileheader.bfOffBits - 54) / 4;
|
||||||
|
|
||||||
if (infoheader.biCompression != BI_BITFIELDS)
|
if (infoheader.biCompression != BI_BITFIELDS)
|
||||||
read_bmicolors(ncol, f, 1);
|
read_bmicolors(fop, ncol, f, 1);
|
||||||
}
|
}
|
||||||
else if (biSize == OS2INFOHEADERSIZE) {
|
else if (biSize == OS2INFOHEADERSIZE) {
|
||||||
if (read_os2_bminfoheader(f, &infoheader) != 0) {
|
if (read_os2_bminfoheader(f, &infoheader) != 0) {
|
||||||
pack_fclose(f);
|
pack_fclose(f);
|
||||||
return NULL;
|
return FALSE;
|
||||||
}
|
}
|
||||||
/* compute number of colors recorded */
|
/* compute number of colors recorded */
|
||||||
ncol = (fileheader.bfOffBits - 26) / 3;
|
ncol = (fileheader.bfOffBits - 26) / 3;
|
||||||
|
|
||||||
if (infoheader.biCompression != BI_BITFIELDS)
|
if (infoheader.biCompression != BI_BITFIELDS)
|
||||||
read_bmicolors(ncol, f, 0);
|
read_bmicolors(fop, ncol, f, 0);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
pack_fclose(f);
|
pack_fclose(f);
|
||||||
return NULL;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((infoheader.biBitCount == 24) || (infoheader.biBitCount == 16))
|
if ((infoheader.biBitCount == 24) || (infoheader.biBitCount == 16))
|
||||||
@ -573,16 +567,16 @@ static Sprite *load_BMP(const char *filename)
|
|||||||
else {
|
else {
|
||||||
/* Unrecognised bit masks/depth */
|
/* Unrecognised bit masks/depth */
|
||||||
pack_fclose(f);
|
pack_fclose(f);
|
||||||
return NULL;
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
image = file_sequence_image(type,
|
image = fop_sequence_image(fop, type,
|
||||||
infoheader.biWidth,
|
infoheader.biWidth,
|
||||||
infoheader.biHeight);
|
infoheader.biHeight);
|
||||||
if (!image) {
|
if (!image) {
|
||||||
pack_fclose(f);
|
pack_fclose(f);
|
||||||
return NULL;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type == IMAGE_RGB)
|
if (type == IMAGE_RGB)
|
||||||
@ -590,12 +584,10 @@ static Sprite *load_BMP(const char *filename)
|
|||||||
else
|
else
|
||||||
image_clear(image, 0);
|
image_clear(image, 0);
|
||||||
|
|
||||||
sprite = file_sequence_sprite();
|
|
||||||
|
|
||||||
switch (infoheader.biCompression) {
|
switch (infoheader.biCompression) {
|
||||||
|
|
||||||
case BI_RGB:
|
case BI_RGB:
|
||||||
read_image(f, image, &infoheader);
|
read_image(f, image, &infoheader, fop);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BI_RLE8:
|
case BI_RLE8:
|
||||||
@ -611,42 +603,41 @@ static Sprite *load_BMP(const char *filename)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
sprite = NULL;
|
pack_fclose(f);
|
||||||
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
pack_fclose(f);
|
pack_fclose(f);
|
||||||
return sprite;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int save_BMP(Sprite *sprite)
|
static bool save_BMP(FileOp *fop)
|
||||||
{
|
{
|
||||||
Image *image;
|
Image *image = fop->seq.image;
|
||||||
PACKFILE *f;
|
PACKFILE *f;
|
||||||
int bfSize;
|
int bfSize;
|
||||||
int biSizeImage;
|
int biSizeImage;
|
||||||
int bpp = (sprite->imgtype == IMAGE_RGB) ? 24 : 8;
|
int bpp = (image->imgtype == IMAGE_RGB) ? 24 : 8;
|
||||||
int filler = 3 - ((sprite->w*(bpp/8)-1) & 3);
|
int filler = 3 - ((image->w*(bpp/8)-1) & 3);
|
||||||
int c, i, j, r, g, b;
|
int c, i, j, r, g, b;
|
||||||
|
|
||||||
if (bpp == 8) {
|
if (bpp == 8) {
|
||||||
biSizeImage = (sprite->w + filler) * sprite->h;
|
biSizeImage = (image->w + filler) * image->h;
|
||||||
bfSize = (54 /* header */
|
bfSize = (54 /* header */
|
||||||
+ 256*4 /* palette */
|
+ 256*4 /* palette */
|
||||||
+ biSizeImage); /* image data */
|
+ biSizeImage); /* image data */
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
biSizeImage = (sprite->w*3 + filler) * sprite->h;
|
biSizeImage = (image->w*3 + filler) * image->h;
|
||||||
bfSize = 54 + biSizeImage; /* header + image data */
|
bfSize = 54 + biSizeImage; /* header + image data */
|
||||||
}
|
}
|
||||||
|
|
||||||
f = pack_fopen(sprite->filename, F_WRITE);
|
f = pack_fopen(fop->filename, F_WRITE);
|
||||||
if (!f) {
|
if (!f) {
|
||||||
console_printf(_("Error creating file.\n"));
|
fop_error(fop, _("Error creating file.\n"));
|
||||||
return -1;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
image = file_sequence_image_to_save();
|
|
||||||
|
|
||||||
*allegro_errno = 0;
|
*allegro_errno = 0;
|
||||||
|
|
||||||
/* file_header */
|
/* file_header */
|
||||||
@ -677,7 +668,7 @@ static int save_BMP(Sprite *sprite)
|
|||||||
|
|
||||||
/* palette */
|
/* palette */
|
||||||
for (i=0; i<256; i++) {
|
for (i=0; i<256; i++) {
|
||||||
file_sequence_get_color(i, &r, &g, &b);
|
fop_sequence_get_color(fop, i, &r, &g, &b);
|
||||||
pack_putc(_rgb_scale_6[b], f);
|
pack_putc(_rgb_scale_6[b], f);
|
||||||
pack_putc(_rgb_scale_6[g], f);
|
pack_putc(_rgb_scale_6[g], f);
|
||||||
pack_putc(_rgb_scale_6[r], f);
|
pack_putc(_rgb_scale_6[r], f);
|
||||||
@ -709,16 +700,15 @@ static int save_BMP(Sprite *sprite)
|
|||||||
for (j=0; j<filler; j++)
|
for (j=0; j<filler; j++)
|
||||||
pack_putc(0, f);
|
pack_putc(0, f);
|
||||||
|
|
||||||
if (image->h > 1)
|
fop_progress(fop, (float)(image->h-i) / (float)image->h);
|
||||||
do_progress(100 * (image->h-1-i) / (image->h-1));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pack_fclose(f);
|
pack_fclose(f);
|
||||||
|
|
||||||
if (*allegro_errno) {
|
if (*allegro_errno) {
|
||||||
console_printf(_("Error writing bytes.\n"));
|
fop_error(fop, _("Error writing bytes.\n"));
|
||||||
return -1;
|
return FALSE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return 0;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
1221
src/file/file.c
1221
src/file/file.c
File diff suppressed because it is too large
Load Diff
@ -19,6 +19,9 @@
|
|||||||
#ifndef FILE_H
|
#ifndef FILE_H
|
||||||
#define FILE_H
|
#define FILE_H
|
||||||
|
|
||||||
|
#include "jinete/jbase.h"
|
||||||
|
#include <allegro/color.h>
|
||||||
|
|
||||||
#define FILE_SUPPORT_RGB (1<<0)
|
#define FILE_SUPPORT_RGB (1<<0)
|
||||||
#define FILE_SUPPORT_RGBA (1<<1)
|
#define FILE_SUPPORT_RGBA (1<<1)
|
||||||
#define FILE_SUPPORT_GRAY (1<<2)
|
#define FILE_SUPPORT_GRAY (1<<2)
|
||||||
@ -31,8 +34,18 @@
|
|||||||
#define FILE_SUPPORT_MASKS_REPOSITORY (1<<9)
|
#define FILE_SUPPORT_MASKS_REPOSITORY (1<<9)
|
||||||
#define FILE_SUPPORT_PATHS_REPOSITORY (1<<10)
|
#define FILE_SUPPORT_PATHS_REPOSITORY (1<<10)
|
||||||
|
|
||||||
typedef struct Sprite *(*FileLoad)(const char *filename);
|
struct Image;
|
||||||
typedef int (*FileSave)(struct Sprite *sprite);
|
struct Cel;
|
||||||
|
struct Layer;
|
||||||
|
struct Sprite;
|
||||||
|
|
||||||
|
struct FileFormat;
|
||||||
|
struct FileOp;
|
||||||
|
|
||||||
|
/* file operations */
|
||||||
|
typedef enum { FileOpLoad, FileOpSave } FileOpType;
|
||||||
|
typedef bool (*FileLoad)(struct FileOp *fop);
|
||||||
|
typedef bool (*FileSave)(struct FileOp *fop);
|
||||||
|
|
||||||
/* load or/and save a file format */
|
/* load or/and save a file format */
|
||||||
typedef struct FileFormat
|
typedef struct FileFormat
|
||||||
@ -44,22 +57,62 @@ typedef struct FileFormat
|
|||||||
int flags;
|
int flags;
|
||||||
} FileFormat;
|
} FileFormat;
|
||||||
|
|
||||||
/* routines to handle sequences */
|
/* structure to load & save files */
|
||||||
|
typedef struct FileOp
|
||||||
|
{
|
||||||
|
FileOpType type; /* operation type: 0=load, 1=save */
|
||||||
|
FileFormat *format;
|
||||||
|
struct Sprite *sprite; /* loaded sprite/sprite to be saved */
|
||||||
|
char *filename; /* file-name to load/save */
|
||||||
|
|
||||||
void file_sequence_set_color(int index, int r, int g, int b);
|
/* shared fields between threads */
|
||||||
void file_sequence_get_color(int index, int *r, int *g, int *b);
|
JMutex mutex; /* mutex to access to the next two fields */
|
||||||
struct Image *file_sequence_image(int imgtype, int w, int h);
|
float progress; /* progress (1.0 is ready) */
|
||||||
struct Sprite *file_sequence_sprite(void);
|
char *error; /* error string */
|
||||||
struct Image *file_sequence_image_to_save(void);
|
bool done : 1; /* true if the operation finished */
|
||||||
|
bool stop : 1; /* force the break of the operation */
|
||||||
|
|
||||||
|
/* data for sequences */
|
||||||
|
struct {
|
||||||
|
JList filename_list; /* all file names to load/save */
|
||||||
|
RGB *palette; /* palette of the sequence */
|
||||||
|
struct Image *image; /* image to be saved/loaded */
|
||||||
|
/* for the progress bar */
|
||||||
|
float progress_offset; /* progress offset from the current frame */
|
||||||
|
float progress_fraction; /* progress fraction for one frame */
|
||||||
|
/* to load sequences */
|
||||||
|
int frame;
|
||||||
|
struct Layer *layer;
|
||||||
|
struct Cel *last_cel;
|
||||||
|
} seq;
|
||||||
|
} FileOp;
|
||||||
|
|
||||||
/* available extensions for each load/save operation */
|
/* available extensions for each load/save operation */
|
||||||
|
|
||||||
const char *get_readable_extensions(void);
|
void get_readable_extensions(char *buf, int size);
|
||||||
const char *get_writable_extensions(void);
|
void get_writable_extensions(char *buf, int size);
|
||||||
|
|
||||||
/* mainly routines to load/save images */
|
/* high-level routines to load/save sprites */
|
||||||
|
|
||||||
struct Sprite *sprite_load(const char *filename);
|
struct Sprite *sprite_load(const char *filename);
|
||||||
int sprite_save(struct Sprite *sprite);
|
int sprite_save(struct Sprite *sprite);
|
||||||
|
|
||||||
|
/* low-level routines to load/save sprites */
|
||||||
|
|
||||||
|
FileOp *fop_to_load_sprite(const char *filename);
|
||||||
|
FileOp *fop_to_save_sprite(struct Sprite *sprite);
|
||||||
|
void fop_operate(FileOp *fop);
|
||||||
|
void fop_free(FileOp *fop);
|
||||||
|
|
||||||
|
void fop_sequence_set_color(FileOp *fop, int index, int r, int g, int b);
|
||||||
|
void fop_sequence_get_color(FileOp *fop, int index, int *r, int *g, int *b);
|
||||||
|
struct Image *fop_sequence_image(FileOp *fi, int imgtype, int w, int h);
|
||||||
|
|
||||||
|
void fop_error(FileOp *fop, const char *error, ...);
|
||||||
|
void fop_progress(FileOp *fop, float progress);
|
||||||
|
|
||||||
|
float fop_get_progress(FileOp *fop);
|
||||||
|
bool fop_is_done(FileOp *fop);
|
||||||
|
bool fop_is_stop(FileOp *fop);
|
||||||
|
|
||||||
#endif /* FILE_H */
|
#endif /* FILE_H */
|
||||||
|
@ -23,7 +23,6 @@
|
|||||||
#include <allegro/color.h>
|
#include <allegro/color.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include "console/console.h"
|
|
||||||
#include "file/file.h"
|
#include "file/file.h"
|
||||||
#include "modules/palette.h"
|
#include "modules/palette.h"
|
||||||
#include "raster/raster.h"
|
#include "raster/raster.h"
|
||||||
@ -33,8 +32,8 @@
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static Sprite *load_FLI(const char *filename);
|
static bool load_FLI(FileOp *fop);
|
||||||
static int save_FLI(Sprite *sprite);
|
static bool save_FLI(FileOp *fop);
|
||||||
|
|
||||||
static int get_time_precision(Sprite *sprite);
|
static int get_time_precision(Sprite *sprite);
|
||||||
|
|
||||||
@ -50,7 +49,7 @@ FileFormat format_fli =
|
|||||||
};
|
};
|
||||||
|
|
||||||
/* loads a FLI/FLC file */
|
/* loads a FLI/FLC file */
|
||||||
static Sprite *load_FLI(const char *filename)
|
static bool load_FLI(FileOp *fop)
|
||||||
{
|
{
|
||||||
#define SETPAL() \
|
#define SETPAL() \
|
||||||
do { \
|
do { \
|
||||||
@ -77,9 +76,9 @@ static Sprite *load_FLI(const char *filename)
|
|||||||
FILE *f;
|
FILE *f;
|
||||||
|
|
||||||
/* open the file to read in binary mode */
|
/* open the file to read in binary mode */
|
||||||
f = fopen(filename, "rb");
|
f = fopen(fop->filename, "rb");
|
||||||
if (!f)
|
if (!f)
|
||||||
return NULL;
|
return FALSE;
|
||||||
|
|
||||||
fli_read_header(f, &fli_header);
|
fli_read_header(f, &fli_header);
|
||||||
fseek(f, 128, SEEK_SET);
|
fseek(f, 128, SEEK_SET);
|
||||||
@ -92,11 +91,11 @@ static Sprite *load_FLI(const char *filename)
|
|||||||
bmp = image_new(IMAGE_INDEXED, w, h);
|
bmp = image_new(IMAGE_INDEXED, w, h);
|
||||||
old = image_new(IMAGE_INDEXED, w, h);
|
old = image_new(IMAGE_INDEXED, w, h);
|
||||||
if ((!bmp) || (!old)) {
|
if ((!bmp) || (!old)) {
|
||||||
console_printf(_("Not enough memory for temporary bitmaps.\n"));
|
fop_error(fop, _("Not enough memory for temporary bitmaps.\n"));
|
||||||
if (bmp) image_free(bmp);
|
if (bmp) image_free(bmp);
|
||||||
if (old) image_free(old);
|
if (old) image_free(old);
|
||||||
fclose(f);
|
fclose(f);
|
||||||
return NULL;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* create the image */
|
/* create the image */
|
||||||
@ -110,8 +109,6 @@ static Sprite *load_FLI(const char *filename)
|
|||||||
sprite_set_speed(sprite, fli_header.speed);
|
sprite_set_speed(sprite, fli_header.speed);
|
||||||
|
|
||||||
/* write frame by frame */
|
/* write frame by frame */
|
||||||
add_progress(100);
|
|
||||||
|
|
||||||
inc_frpos_out = FALSE;
|
inc_frpos_out = FALSE;
|
||||||
|
|
||||||
for (frpos_in=frpos_out=0;
|
for (frpos_in=frpos_out=0;
|
||||||
@ -156,15 +153,12 @@ static Sprite *load_FLI(const char *filename)
|
|||||||
memcpy(omap, cmap, 768);
|
memcpy(omap, cmap, 768);
|
||||||
|
|
||||||
/* update progress */
|
/* update progress */
|
||||||
if (sprite->frames > 1)
|
fop_progress(fop, (float)(frpos_in+1) / (float)(sprite->frames));
|
||||||
do_progress(100 * (frpos_in) / (sprite->frames-1));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* update sprites frames */
|
/* update sprites frames */
|
||||||
sprite_set_frames(sprite, frpos_out+1);
|
sprite_set_frames(sprite, frpos_out+1);
|
||||||
|
|
||||||
del_progress();
|
|
||||||
|
|
||||||
/* close the file */
|
/* close the file */
|
||||||
fclose(f);
|
fclose(f);
|
||||||
|
|
||||||
@ -172,12 +166,14 @@ static Sprite *load_FLI(const char *filename)
|
|||||||
image_free(bmp);
|
image_free(bmp);
|
||||||
image_free(old);
|
image_free(old);
|
||||||
|
|
||||||
return sprite;
|
fop->sprite = sprite;
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* saves a FLC file */
|
/* saves a FLC file */
|
||||||
static int save_FLI(Sprite *sprite)
|
static bool save_FLI(FileOp *fop)
|
||||||
{
|
{
|
||||||
|
Sprite *sprite = fop->sprite;
|
||||||
unsigned char cmap[768];
|
unsigned char cmap[768];
|
||||||
unsigned char omap[768];
|
unsigned char omap[768];
|
||||||
s_fli_header fli_header;
|
s_fli_header fli_header;
|
||||||
@ -207,9 +203,9 @@ static int save_FLI(Sprite *sprite)
|
|||||||
fli_header.oframe1 = fli_header.oframe2 = 0;
|
fli_header.oframe1 = fli_header.oframe2 = 0;
|
||||||
|
|
||||||
/* open the file to write in binary mode */
|
/* open the file to write in binary mode */
|
||||||
f = fopen(sprite->filename, "wb");
|
f = fopen(fop->filename, "wb");
|
||||||
if (!f)
|
if (!f)
|
||||||
return -1;
|
return FALSE;
|
||||||
|
|
||||||
fseek(f, 128, SEEK_SET);
|
fseek(f, 128, SEEK_SET);
|
||||||
|
|
||||||
@ -217,16 +213,14 @@ static int save_FLI(Sprite *sprite)
|
|||||||
bmp = image_new(IMAGE_INDEXED, sprite->w, sprite->h);
|
bmp = image_new(IMAGE_INDEXED, sprite->w, sprite->h);
|
||||||
old = image_new(IMAGE_INDEXED, sprite->w, sprite->h);
|
old = image_new(IMAGE_INDEXED, sprite->w, sprite->h);
|
||||||
if ((!bmp) || (!old)) {
|
if ((!bmp) || (!old)) {
|
||||||
console_printf(_("Not enough memory for temporary bitmaps.\n"));
|
fop_error(fop, _("Not enough memory for temporary bitmaps.\n"));
|
||||||
if (bmp) image_free(bmp);
|
if (bmp) image_free(bmp);
|
||||||
if (old) image_free(old);
|
if (old) image_free(old);
|
||||||
fclose(f);
|
fclose(f);
|
||||||
return -1;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* write frame by frame */
|
/* write frame by frame */
|
||||||
add_progress(100);
|
|
||||||
|
|
||||||
for (frpos=0;
|
for (frpos=0;
|
||||||
frpos<sprite->frames;
|
frpos<sprite->frames;
|
||||||
frpos++) {
|
frpos++) {
|
||||||
@ -262,12 +256,9 @@ static int save_FLI(Sprite *sprite)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* update progress */
|
/* update progress */
|
||||||
if (sprite->frames > 1)
|
fop_progress(fop, (float)(frpos+1) / (float)(sprite->frames));
|
||||||
do_progress(100 * (frpos) / (sprite->frames-1));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
del_progress();
|
|
||||||
|
|
||||||
/* write the header and close the file */
|
/* write the header and close the file */
|
||||||
fli_write_header(f, &fli_header);
|
fli_write_header(f, &fli_header);
|
||||||
fclose(f);
|
fclose(f);
|
||||||
@ -276,7 +267,7 @@ static int save_FLI(Sprite *sprite)
|
|||||||
image_free(bmp);
|
image_free(bmp);
|
||||||
image_free(old);
|
image_free(old);
|
||||||
|
|
||||||
return 0;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int get_time_precision(Sprite *sprite)
|
static int get_time_precision(Sprite *sprite)
|
||||||
|
@ -86,7 +86,8 @@ static void lzw_write_pixel (int pos, int c, unsigned char *data)
|
|||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
gif_save_animation (const char *filename, GIF_ANIMATION *gif,
|
gif_save_animation (const char *filename, GIF_ANIMATION *gif,
|
||||||
void (*progress) (int))
|
void (*progress) (void *, float),
|
||||||
|
void *dp)
|
||||||
{
|
{
|
||||||
int frame;
|
int frame;
|
||||||
int i, j;
|
int i, j;
|
||||||
@ -125,7 +126,7 @@ gif_save_animation (const char *filename, GIF_ANIMATION *gif,
|
|||||||
pack_putc (0, file);
|
pack_putc (0, file);
|
||||||
}
|
}
|
||||||
|
|
||||||
progress(0);
|
progress(dp, 0.0f);
|
||||||
for (frame = 0; frame < gif->frames_count; frame++)
|
for (frame = 0; frame < gif->frames_count; frame++)
|
||||||
{
|
{
|
||||||
int w = gif->frames[frame].w;
|
int w = gif->frames[frame].w;
|
||||||
@ -169,9 +170,9 @@ gif_save_animation (const char *filename, GIF_ANIMATION *gif,
|
|||||||
|
|
||||||
pack_putc (0x00, file); /* Terminator. */
|
pack_putc (0x00, file); /* Terminator. */
|
||||||
|
|
||||||
progress(100 * frame / gif->frames_count);
|
progress(dp, (float)frame / (float)gif->frames_count);
|
||||||
}
|
}
|
||||||
progress(100);
|
progress(dp, 1.0f);
|
||||||
|
|
||||||
pack_putc (0x3b, file); /* Trailer. */
|
pack_putc (0x3b, file); /* Trailer. */
|
||||||
|
|
||||||
@ -205,7 +206,7 @@ deinterlace (unsigned char *bmp, int w, int h)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static GIF_ANIMATION *
|
static GIF_ANIMATION *
|
||||||
load_object (PACKFILE * file, long size, void (*progress) (int))
|
load_object (PACKFILE * file, long size, void (*progress) (void *, float), void *dp)
|
||||||
{
|
{
|
||||||
int version;
|
int version;
|
||||||
unsigned char *bmp = NULL;
|
unsigned char *bmp = NULL;
|
||||||
@ -252,11 +253,11 @@ load_object (PACKFILE * file, long size, void (*progress) (int))
|
|||||||
have_global_palette = 1;
|
have_global_palette = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
progress(0);
|
progress(dp, 0.0f);
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
i = pack_getc (file);
|
i = pack_getc (file);
|
||||||
progress(100 * i / size);
|
progress(dp, (float)i / (float)size);
|
||||||
|
|
||||||
switch (i)
|
switch (i)
|
||||||
{
|
{
|
||||||
@ -361,7 +362,7 @@ load_object (PACKFILE * file, long size, void (*progress) (int))
|
|||||||
case 0x3b:
|
case 0x3b:
|
||||||
/* GIF Trailer. */
|
/* GIF Trailer. */
|
||||||
pack_fclose (file);
|
pack_fclose (file);
|
||||||
progress(100);
|
progress(dp, 1.0f);
|
||||||
return gif;
|
return gif;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -388,7 +389,7 @@ load_object (PACKFILE * file, long size, void (*progress) (int))
|
|||||||
* All bitmaps will have a color depth of 8.
|
* All bitmaps will have a color depth of 8.
|
||||||
*/
|
*/
|
||||||
GIF_ANIMATION *
|
GIF_ANIMATION *
|
||||||
gif_load_animation (const char *filename, void (*progress) (int))
|
gif_load_animation (const char *filename, void (*progress) (void *, float), void *dp)
|
||||||
{
|
{
|
||||||
PACKFILE *file;
|
PACKFILE *file;
|
||||||
GIF_ANIMATION *gif = NULL;
|
GIF_ANIMATION *gif = NULL;
|
||||||
@ -402,7 +403,7 @@ gif_load_animation (const char *filename, void (*progress) (int))
|
|||||||
|
|
||||||
file = pack_fopen (filename, "r");
|
file = pack_fopen (filename, "r");
|
||||||
if (file)
|
if (file)
|
||||||
gif = load_object (file, size, progress);
|
gif = load_object (file, size, progress, dp);
|
||||||
return gif;
|
return gif;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,9 +37,11 @@ struct GIF_FRAME
|
|||||||
GIF_ANIMATION *gif_create_animation(int frames_count);
|
GIF_ANIMATION *gif_create_animation(int frames_count);
|
||||||
void gif_destroy_animation(GIF_ANIMATION *gif);
|
void gif_destroy_animation(GIF_ANIMATION *gif);
|
||||||
int gif_save_animation(const char *filename, GIF_ANIMATION *gif,
|
int gif_save_animation(const char *filename, GIF_ANIMATION *gif,
|
||||||
void (*progress) (int));
|
void (*progress) (void *, float),
|
||||||
|
void *dp);
|
||||||
GIF_ANIMATION *gif_load_animation(const char *filename,
|
GIF_ANIMATION *gif_load_animation(const char *filename,
|
||||||
void (*progress) (int));
|
void (*progress) (void *, float),
|
||||||
|
void *dp);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -31,7 +31,6 @@
|
|||||||
|
|
||||||
#include "jinete/jbase.h"
|
#include "jinete/jbase.h"
|
||||||
|
|
||||||
#include "console/console.h"
|
|
||||||
#include "file/file.h"
|
#include "file/file.h"
|
||||||
#include "modules/palette.h"
|
#include "modules/palette.h"
|
||||||
#include "raster/raster.h"
|
#include "raster/raster.h"
|
||||||
@ -43,8 +42,8 @@
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static Sprite *load_GIF(const char *filename);
|
static bool load_GIF(FileOp *fop);
|
||||||
static int save_GIF(Sprite *sprite);
|
static bool save_GIF(FileOp *fop);
|
||||||
|
|
||||||
FileFormat format_gif =
|
FileFormat format_gif =
|
||||||
{
|
{
|
||||||
@ -78,7 +77,7 @@ static void render_gif_frame(GIF_FRAME *frame, Image *image,
|
|||||||
/* load_GIF:
|
/* load_GIF:
|
||||||
* Loads a GIF into a sprite.
|
* Loads a GIF into a sprite.
|
||||||
*/
|
*/
|
||||||
static Sprite *load_GIF(const char *filename)
|
static bool load_GIF(FileOp *fop)
|
||||||
{
|
{
|
||||||
GIF_ANIMATION *gif = NULL;
|
GIF_ANIMATION *gif = NULL;
|
||||||
Sprite *sprite = NULL;
|
Sprite *sprite = NULL;
|
||||||
@ -90,13 +89,10 @@ static Sprite *load_GIF(const char *filename)
|
|||||||
PALETTE opal, npal;
|
PALETTE opal, npal;
|
||||||
int i, c;
|
int i, c;
|
||||||
|
|
||||||
add_progress(100);
|
gif = gif_load_animation(fop->filename, fop_progress, fop);
|
||||||
gif = gif_load_animation(filename, do_progress);
|
|
||||||
del_progress();
|
|
||||||
|
|
||||||
if (!gif) {
|
if (!gif) {
|
||||||
console_printf(_("Error loading GIF file.\n"));
|
fop_error(fop, _("Error loading GIF file.\n"));
|
||||||
return NULL;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
current_image = image_new(IMAGE_INDEXED, gif->width, gif->height);
|
current_image = image_new(IMAGE_INDEXED, gif->width, gif->height);
|
||||||
@ -106,16 +102,16 @@ static Sprite *load_GIF(const char *filename)
|
|||||||
if (current_image_old) image_free(current_image_old);
|
if (current_image_old) image_free(current_image_old);
|
||||||
|
|
||||||
gif_destroy_animation(gif);
|
gif_destroy_animation(gif);
|
||||||
console_printf(_("Error creating temporary image.\n"));
|
fop_error(fop, _("Error creating temporary image.\n"));
|
||||||
return NULL;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
sprite = sprite_new(IMAGE_INDEXED, gif->width, gif->height);
|
sprite = sprite_new(IMAGE_INDEXED, gif->width, gif->height);
|
||||||
if (!sprite) {
|
if (!sprite) {
|
||||||
gif_destroy_animation(gif);
|
gif_destroy_animation(gif);
|
||||||
image_free(current_image);
|
image_free(current_image);
|
||||||
console_printf(_("Error creating sprite.\n"));
|
fop_error(fop, _("Error creating sprite.\n"));
|
||||||
return NULL;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
sprite_set_frames(sprite, gif->frames_count);
|
sprite_set_frames(sprite, gif->frames_count);
|
||||||
@ -125,8 +121,8 @@ static Sprite *load_GIF(const char *filename)
|
|||||||
gif_destroy_animation(gif);
|
gif_destroy_animation(gif);
|
||||||
image_free(current_image);
|
image_free(current_image);
|
||||||
sprite_free(sprite);
|
sprite_free(sprite);
|
||||||
console_printf(_("Error creating main layer.\n"));
|
fop_error(fop, _("Error creating main layer.\n"));
|
||||||
return NULL;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
layer_add_layer(sprite->set, layer);
|
layer_add_layer(sprite->set, layer);
|
||||||
@ -180,7 +176,7 @@ static Sprite *load_GIF(const char *filename)
|
|||||||
if (!cel || !image) {
|
if (!cel || !image) {
|
||||||
if (cel) cel_free(cel);
|
if (cel) cel_free(cel);
|
||||||
if (image) image_free(image);
|
if (image) image_free(image);
|
||||||
console_printf(_("Error creating cel %d.\n"), i);
|
fop_error(fop, _("Error creating cel %d.\n"), i);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -260,7 +256,8 @@ static Sprite *load_GIF(const char *filename)
|
|||||||
image_free(current_image);
|
image_free(current_image);
|
||||||
image_free(current_image_old);
|
image_free(current_image_old);
|
||||||
|
|
||||||
return sprite;
|
fop->sprite = sprite;
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO: find the colors that are used and resort the palette */
|
/* TODO: find the colors that are used and resort the palette */
|
||||||
@ -283,8 +280,9 @@ static int max_used_index(Image *image)
|
|||||||
* TODO: transparent index is not stored. And reserve a single color
|
* TODO: transparent index is not stored. And reserve a single color
|
||||||
* as transparent.
|
* as transparent.
|
||||||
*/
|
*/
|
||||||
static int save_GIF(Sprite *sprite)
|
static bool save_GIF(FileOp *fop)
|
||||||
{
|
{
|
||||||
|
Sprite *sprite = fop->sprite;
|
||||||
GIF_ANIMATION *gif;
|
GIF_ANIMATION *gif;
|
||||||
int x1, y1, x2, y2;
|
int x1, y1, x2, y2;
|
||||||
int u1, v1, u2, v2;
|
int u1, v1, u2, v2;
|
||||||
@ -300,16 +298,16 @@ static int save_GIF(Sprite *sprite)
|
|||||||
if (!bmp || !old) {
|
if (!bmp || !old) {
|
||||||
if (bmp) image_free(bmp);
|
if (bmp) image_free(bmp);
|
||||||
if (old) image_free(old);
|
if (old) image_free(old);
|
||||||
console_printf(_("Not enough memory for temporary bitmaps.\n"));
|
fop_error(fop, _("Not enough memory for temporary bitmaps.\n"));
|
||||||
return -1;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
gif = gif_create_animation(sprite->frames);
|
gif = gif_create_animation(sprite->frames);
|
||||||
if (!gif) {
|
if (!gif) {
|
||||||
image_free(bmp);
|
image_free(bmp);
|
||||||
image_free(old);
|
image_free(old);
|
||||||
console_printf(_("Error creating GIF structure.\n"));
|
fop_error(fop, _("Error creating GIF structure.\n"));
|
||||||
return -1;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
gif->width = sprite->w;
|
gif->width = sprite->w;
|
||||||
@ -327,8 +325,6 @@ static int save_GIF(Sprite *sprite)
|
|||||||
/* avoid compilation warnings */
|
/* avoid compilation warnings */
|
||||||
x1 = y1 = x2 = y2 = 0;
|
x1 = y1 = x2 = y2 = 0;
|
||||||
|
|
||||||
add_progress(2);
|
|
||||||
add_progress(sprite->frames);
|
|
||||||
for (i = 0; i < sprite->frames; i++) {
|
for (i = 0; i < sprite->frames; i++) {
|
||||||
/* frame palette */
|
/* frame palette */
|
||||||
palette_copy(npal, sprite_get_palette(sprite, i));
|
palette_copy(npal, sprite_get_palette(sprite, i));
|
||||||
@ -442,19 +438,9 @@ static int save_GIF(Sprite *sprite)
|
|||||||
/* update the old image and color-map to the new ones to compare later */
|
/* update the old image and color-map to the new ones to compare later */
|
||||||
image_copy(old, bmp, 0, 0);
|
image_copy(old, bmp, 0, 0);
|
||||||
palette_copy(opal, npal);
|
palette_copy(opal, npal);
|
||||||
|
|
||||||
do_progress(i);
|
|
||||||
}
|
}
|
||||||
del_progress();
|
|
||||||
do_progress(1);
|
|
||||||
|
|
||||||
add_progress(100);
|
|
||||||
ret = gif_save_animation(sprite->filename, gif, do_progress);
|
|
||||||
del_progress();
|
|
||||||
|
|
||||||
do_progress(2);
|
|
||||||
del_progress();
|
|
||||||
|
|
||||||
|
ret = gif_save_animation(fop->filename, gif, fop_progress, fop);
|
||||||
gif_destroy_animation(gif);
|
gif_destroy_animation(gif);
|
||||||
return ret;
|
return ret == 0 ? TRUE: FALSE;
|
||||||
}
|
}
|
||||||
|
@ -25,45 +25,42 @@
|
|||||||
#include <allegro/color.h>
|
#include <allegro/color.h>
|
||||||
#include <allegro/file.h>
|
#include <allegro/file.h>
|
||||||
|
|
||||||
#include "console/console.h"
|
|
||||||
#include "file/file.h"
|
#include "file/file.h"
|
||||||
#include "raster/raster.h"
|
#include "raster/raster.h"
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static Sprite *load_ICO(const char *filename);
|
/* static bool load_ICO(FileOp *fop); */
|
||||||
static int save_ICO(Sprite *sprite);
|
static bool save_ICO(FileOp *fop);
|
||||||
|
|
||||||
FileFormat format_ico =
|
FileFormat format_ico =
|
||||||
{
|
{
|
||||||
"ico",
|
"ico",
|
||||||
"ico",
|
"ico",
|
||||||
load_ICO,
|
NULL, /* load_ICO, */
|
||||||
save_ICO,
|
save_ICO,
|
||||||
/* FILE_SUPPORT_RGB | */
|
/* FILE_SUPPORT_RGB | */
|
||||||
/* FILE_SUPPORT_GRAY | */
|
/* FILE_SUPPORT_GRAY | */
|
||||||
FILE_SUPPORT_INDEXED
|
FILE_SUPPORT_INDEXED
|
||||||
};
|
};
|
||||||
|
|
||||||
static Sprite *load_ICO(const char *filename)
|
/* static bool load_ICO(FileOp *fop) */
|
||||||
{
|
/* { */
|
||||||
return NULL; /* TODO */
|
/* return NULL; /\* TODO *\/ */
|
||||||
}
|
/* } */
|
||||||
|
|
||||||
static int save_ICO(Sprite *sprite)
|
static bool save_ICO(FileOp *fop)
|
||||||
{
|
{
|
||||||
PACKFILE *f;
|
PACKFILE *f;
|
||||||
int depth, bpp, bw, bitsw;
|
int depth, bpp, bw, bitsw;
|
||||||
int size, offset, n, i;
|
int size, offset, n, i;
|
||||||
int c, x, y, b, m, v;
|
int c, x, y, b, m, v;
|
||||||
int num = sprite->frames;
|
int num = fop->sprite->frames;
|
||||||
Image *bmp;
|
Image *bmp;
|
||||||
|
|
||||||
errno = 0;
|
f = pack_fopen(fop->filename, F_WRITE);
|
||||||
|
|
||||||
f = pack_fopen(sprite->filename, F_WRITE);
|
|
||||||
if (!f)
|
if (!f)
|
||||||
return errno;
|
return FALSE;
|
||||||
|
|
||||||
offset = 6 + num * 16; /* ICONDIR + ICONDIRENTRYs */
|
offset = 6 + num * 16; /* ICONDIR + ICONDIRENTRYs */
|
||||||
|
|
||||||
@ -75,16 +72,16 @@ static int save_ICO(Sprite *sprite)
|
|||||||
for(n = 0; n < num; n++) {
|
for(n = 0; n < num; n++) {
|
||||||
depth = 8;/* bitmap_color_depth(bmp[n]); */
|
depth = 8;/* bitmap_color_depth(bmp[n]); */
|
||||||
bpp = (depth == 8) ? 8 : 24;
|
bpp = (depth == 8) ? 8 : 24;
|
||||||
bw = (((sprite->w * bpp / 8) + 3) / 4) * 4;
|
bw = (((fop->sprite->w * bpp / 8) + 3) / 4) * 4;
|
||||||
bitsw = ((((sprite->w + 7) / 8) + 3) / 4) * 4;
|
bitsw = ((((fop->sprite->w + 7) / 8) + 3) / 4) * 4;
|
||||||
size = sprite->h * (bw + bitsw) + 40;
|
size = fop->sprite->h * (bw + bitsw) + 40;
|
||||||
|
|
||||||
if (bpp == 8)
|
if (bpp == 8)
|
||||||
size += 256 * 4;
|
size += 256 * 4;
|
||||||
|
|
||||||
/* ICONDIRENTRY */
|
/* ICONDIRENTRY */
|
||||||
pack_putc(sprite->w, f); /* width */
|
pack_putc(fop->sprite->w, f); /* width */
|
||||||
pack_putc(sprite->h, f); /* height */
|
pack_putc(fop->sprite->h, f); /* height */
|
||||||
pack_putc(0, f); /* color count */
|
pack_putc(0, f); /* color count */
|
||||||
pack_putc(0, f); /* reserved */
|
pack_putc(0, f); /* reserved */
|
||||||
pack_iputw(1, f); /* color planes */
|
pack_iputw(1, f); /* color planes */
|
||||||
@ -95,11 +92,13 @@ static int save_ICO(Sprite *sprite)
|
|||||||
offset += size;
|
offset += size;
|
||||||
}
|
}
|
||||||
|
|
||||||
bmp = image_new(sprite->imgtype, sprite->w, sprite->h);
|
bmp = image_new(fop->sprite->imgtype,
|
||||||
|
fop->sprite->w,
|
||||||
|
fop->sprite->h);
|
||||||
|
|
||||||
for(n = 0; n < num; n++) {
|
for (n = 0; n < num; n++) {
|
||||||
image_clear(bmp, 0);
|
image_clear(bmp, 0);
|
||||||
layer_render(sprite->set, bmp, 0, 0, n);
|
layer_render(fop->sprite->set, bmp, 0, 0, n);
|
||||||
|
|
||||||
depth = 8; /* bitmap_color_depth(bmp); */
|
depth = 8; /* bitmap_color_depth(bmp); */
|
||||||
bpp = (depth == 8) ? 8 : 24;
|
bpp = (depth == 8) ? 8 : 24;
|
||||||
@ -125,7 +124,7 @@ static int save_ICO(Sprite *sprite)
|
|||||||
|
|
||||||
/* PALETTE */
|
/* PALETTE */
|
||||||
if (bpp == 8) {
|
if (bpp == 8) {
|
||||||
RGB *pal = sprite_get_palette(sprite, n);
|
RGB *pal = sprite_get_palette(fop->sprite, n);
|
||||||
|
|
||||||
pack_iputl(0, f); /* color 0 is black, so the XOR mask works */
|
pack_iputl(0, f); /* color 0 is black, so the XOR mask works */
|
||||||
|
|
||||||
@ -185,5 +184,5 @@ static int save_ICO(Sprite *sprite)
|
|||||||
image_free(bmp);
|
image_free(bmp);
|
||||||
pack_fclose(f);
|
pack_fclose(f);
|
||||||
|
|
||||||
return errno;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -26,7 +26,6 @@
|
|||||||
|
|
||||||
#include "jinete/jinete.h"
|
#include "jinete/jinete.h"
|
||||||
|
|
||||||
#include "console/console.h"
|
|
||||||
#include "core/app.h"
|
#include "core/app.h"
|
||||||
#include "core/cfg.h"
|
#include "core/cfg.h"
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
@ -38,10 +37,10 @@
|
|||||||
|
|
||||||
#include "jpeglib.h"
|
#include "jpeglib.h"
|
||||||
|
|
||||||
static Sprite *load_JPEG(const char *filename);
|
static bool load_JPEG(FileOp *fop);
|
||||||
static int save_JPEG(Sprite *sprite);
|
static bool save_JPEG(FileOp *fop);
|
||||||
|
|
||||||
static int configure_jpeg(void);
|
static bool configure_jpeg(void); /* TODO warning: not thread safe */
|
||||||
|
|
||||||
FileFormat format_jpeg =
|
FileFormat format_jpeg =
|
||||||
{
|
{
|
||||||
@ -54,17 +53,10 @@ FileFormat format_jpeg =
|
|||||||
FILE_SUPPORT_SEQUENCES
|
FILE_SUPPORT_SEQUENCES
|
||||||
};
|
};
|
||||||
|
|
||||||
static void progress_monitor(j_common_ptr cinfo)
|
|
||||||
{
|
|
||||||
if (cinfo->progress->pass_limit > 1)
|
|
||||||
do_progress(100 *
|
|
||||||
(cinfo->progress->pass_counter) /
|
|
||||||
(cinfo->progress->pass_limit-1));
|
|
||||||
}
|
|
||||||
|
|
||||||
struct error_mgr {
|
struct error_mgr {
|
||||||
struct jpeg_error_mgr pub;
|
struct jpeg_error_mgr head;
|
||||||
jmp_buf setjmp_buffer;
|
jmp_buf setjmp_buffer;
|
||||||
|
FileOp *fop;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void error_exit(j_common_ptr cinfo)
|
static void error_exit(j_common_ptr cinfo)
|
||||||
@ -87,14 +79,13 @@ static void output_message(j_common_ptr cinfo)
|
|||||||
PRINTF("JPEG library: \"%s\"\n", buffer);
|
PRINTF("JPEG library: \"%s\"\n", buffer);
|
||||||
|
|
||||||
/* Leave the message for the application. */
|
/* Leave the message for the application. */
|
||||||
console_printf("%s\n", buffer);
|
fop_error(((struct error_mgr *)cinfo->err)->fop, "%s\n", buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Sprite *load_JPEG(const char *filename)
|
static bool load_JPEG(FileOp *fop)
|
||||||
{
|
{
|
||||||
struct jpeg_decompress_struct cinfo;
|
struct jpeg_decompress_struct cinfo;
|
||||||
struct error_mgr jerr;
|
struct error_mgr jerr;
|
||||||
struct jpeg_progress_mgr progress;
|
|
||||||
Image *image;
|
Image *image;
|
||||||
FILE *file;
|
FILE *file;
|
||||||
JDIMENSION num_scanlines;
|
JDIMENSION num_scanlines;
|
||||||
@ -102,24 +93,22 @@ static Sprite *load_JPEG(const char *filename)
|
|||||||
JDIMENSION buffer_height;
|
JDIMENSION buffer_height;
|
||||||
int c;
|
int c;
|
||||||
|
|
||||||
file = fopen(filename, "rb");
|
file = fopen(fop->filename, "rb");
|
||||||
if (!file) {
|
if (!file)
|
||||||
if (!file_sequence_sprite())
|
return FALSE;
|
||||||
console_printf(_("Error opening file.\n"));
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* initialize the JPEG decompression object with error handling */
|
/* initialize the JPEG decompression object with error handling */
|
||||||
cinfo.err = jpeg_std_error(&jerr.pub);
|
jerr.fop = fop;
|
||||||
|
cinfo.err = jpeg_std_error(&jerr.head);
|
||||||
|
|
||||||
jerr.pub.error_exit = error_exit;
|
jerr.head.error_exit = error_exit;
|
||||||
jerr.pub.output_message = output_message;
|
jerr.head.output_message = output_message;
|
||||||
|
|
||||||
/* establish the setjmp return context for error_exit to use */
|
/* establish the setjmp return context for error_exit to use */
|
||||||
if (setjmp(jerr.setjmp_buffer)) {
|
if (setjmp(jerr.setjmp_buffer)) {
|
||||||
jpeg_destroy_decompress(&cinfo);
|
jpeg_destroy_decompress(&cinfo);
|
||||||
fclose(file);
|
fclose(file);
|
||||||
return NULL;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
jpeg_create_decompress(&cinfo);
|
jpeg_create_decompress(&cinfo);
|
||||||
@ -139,14 +128,15 @@ static Sprite *load_JPEG(const char *filename)
|
|||||||
jpeg_start_decompress(&cinfo);
|
jpeg_start_decompress(&cinfo);
|
||||||
|
|
||||||
/* create the image */
|
/* create the image */
|
||||||
image = file_sequence_image((cinfo.out_color_space == JCS_RGB ? IMAGE_RGB:
|
image = fop_sequence_image(fop,
|
||||||
IMAGE_GRAYSCALE),
|
(cinfo.out_color_space == JCS_RGB ? IMAGE_RGB:
|
||||||
cinfo.output_width,
|
IMAGE_GRAYSCALE),
|
||||||
cinfo.output_height);
|
cinfo.output_width,
|
||||||
|
cinfo.output_height);
|
||||||
if (!image) {
|
if (!image) {
|
||||||
jpeg_destroy_decompress(&cinfo);
|
jpeg_destroy_decompress(&cinfo);
|
||||||
fclose(file);
|
fclose(file);
|
||||||
return NULL;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* create the buffer */
|
/* create the buffer */
|
||||||
@ -155,7 +145,7 @@ static Sprite *load_JPEG(const char *filename)
|
|||||||
if (!buffer) {
|
if (!buffer) {
|
||||||
jpeg_destroy_decompress(&cinfo);
|
jpeg_destroy_decompress(&cinfo);
|
||||||
fclose(file);
|
fclose(file);
|
||||||
return NULL;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (c=0; c<(int)buffer_height; c++) {
|
for (c=0; c<(int)buffer_height; c++) {
|
||||||
@ -167,21 +157,18 @@ static Sprite *load_JPEG(const char *filename)
|
|||||||
jfree(buffer);
|
jfree(buffer);
|
||||||
jpeg_destroy_decompress(&cinfo);
|
jpeg_destroy_decompress(&cinfo);
|
||||||
fclose(file);
|
fclose(file);
|
||||||
return NULL;
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* generate a grayscale palette if is necessary */
|
/* generate a grayscale palette if is necessary */
|
||||||
if (image->imgtype == IMAGE_GRAYSCALE)
|
if (image->imgtype == IMAGE_GRAYSCALE)
|
||||||
for (c=0; c<256; c++)
|
for (c=0; c<256; c++)
|
||||||
file_sequence_set_color(c, c >> 2, c >> 2, c >> 2);
|
fop_sequence_set_color(fop, c, c >> 2, c >> 2, c >> 2);
|
||||||
|
|
||||||
/* for progress bar */
|
|
||||||
progress.progress_monitor = progress_monitor;
|
|
||||||
cinfo.progress = &progress;
|
|
||||||
|
|
||||||
/* read each scan line */
|
/* read each scan line */
|
||||||
while (cinfo.output_scanline < cinfo.output_height) {
|
while (cinfo.output_scanline < cinfo.output_height) {
|
||||||
|
/* TODO */
|
||||||
/* if (plugin_want_close()) */
|
/* if (plugin_want_close()) */
|
||||||
/* break; */
|
/* break; */
|
||||||
|
|
||||||
@ -219,6 +206,8 @@ static Sprite *load_JPEG(const char *filename)
|
|||||||
*(dst_address++) = _graya(*(src_address++), 255);
|
*(dst_address++) = _graya(*(src_address++), 255);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fop_progress(fop, (float)(cinfo.output_scanline+1) / (float)(cinfo.output_height));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* destroy all data */
|
/* destroy all data */
|
||||||
@ -230,26 +219,25 @@ static Sprite *load_JPEG(const char *filename)
|
|||||||
jpeg_destroy_decompress(&cinfo);
|
jpeg_destroy_decompress(&cinfo);
|
||||||
|
|
||||||
fclose(file);
|
fclose(file);
|
||||||
return file_sequence_sprite();
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int save_JPEG(Sprite *sprite)
|
static bool save_JPEG(FileOp *fop)
|
||||||
{
|
{
|
||||||
struct jpeg_compress_struct cinfo;
|
struct jpeg_compress_struct cinfo;
|
||||||
struct jpeg_error_mgr jerr;
|
struct error_mgr jerr;
|
||||||
struct jpeg_progress_mgr progress;
|
Image *image = fop->seq.image;
|
||||||
FILE *file;
|
FILE *file;
|
||||||
JSAMPARRAY buffer;
|
JSAMPARRAY buffer;
|
||||||
JDIMENSION buffer_height;
|
JDIMENSION buffer_height;
|
||||||
Image *image;
|
|
||||||
int c;
|
int c;
|
||||||
int smooth;
|
int smooth;
|
||||||
int quality;
|
int quality;
|
||||||
J_DCT_METHOD method;
|
J_DCT_METHOD method;
|
||||||
|
|
||||||
/* Configure JPEG compression only in the first frame. */
|
/* Configure JPEG compression only in the first frame. */
|
||||||
if (sprite->frame == 0 && configure_jpeg() < 0)
|
if (fop->sprite->frame == 0 && !configure_jpeg())
|
||||||
return 0;
|
return FALSE;
|
||||||
|
|
||||||
/* Options. */
|
/* Options. */
|
||||||
smooth = get_config_int("JPEG", "Smooth", 0);
|
smooth = get_config_int("JPEG", "Smooth", 0);
|
||||||
@ -257,16 +245,15 @@ static int save_JPEG(Sprite *sprite)
|
|||||||
method = get_config_int("JPEG", "Method", JDCT_DEFAULT);
|
method = get_config_int("JPEG", "Method", JDCT_DEFAULT);
|
||||||
|
|
||||||
/* Open the file for write in it. */
|
/* Open the file for write in it. */
|
||||||
file = fopen(sprite->filename, "wb");
|
file = fopen(fop->filename, "wb");
|
||||||
if (!file) {
|
if (!file) {
|
||||||
console_printf(_("Error creating file.\n"));
|
fop_error(fop, _("Error creating file.\n"));
|
||||||
return -1;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
image = file_sequence_image_to_save();
|
|
||||||
|
|
||||||
/* Allocate and initialize JPEG compression object. */
|
/* Allocate and initialize JPEG compression object. */
|
||||||
cinfo.err = jpeg_std_error(&jerr);
|
jerr.fop = fop;
|
||||||
|
cinfo.err = jpeg_std_error(&jerr.head);
|
||||||
jpeg_create_compress(&cinfo);
|
jpeg_create_compress(&cinfo);
|
||||||
|
|
||||||
/* Specify data destination file. */
|
/* Specify data destination file. */
|
||||||
@ -297,30 +284,26 @@ static int save_JPEG(Sprite *sprite)
|
|||||||
buffer_height = 1;
|
buffer_height = 1;
|
||||||
buffer = jmalloc(sizeof(JSAMPROW) * buffer_height);
|
buffer = jmalloc(sizeof(JSAMPROW) * buffer_height);
|
||||||
if (!buffer) {
|
if (!buffer) {
|
||||||
console_printf(_("Not enough memory for the buffer.\n"));
|
fop_error(fop, _("Not enough memory for the buffer.\n"));
|
||||||
jpeg_destroy_compress(&cinfo);
|
jpeg_destroy_compress(&cinfo);
|
||||||
fclose(file);
|
fclose(file);
|
||||||
return -1;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (c=0; c<(int)buffer_height; c++) {
|
for (c=0; c<(int)buffer_height; c++) {
|
||||||
buffer[c] = jmalloc(sizeof(JSAMPLE) *
|
buffer[c] = jmalloc(sizeof(JSAMPLE) *
|
||||||
cinfo.image_width * cinfo.num_components);
|
cinfo.image_width * cinfo.num_components);
|
||||||
if (!buffer[c]) {
|
if (!buffer[c]) {
|
||||||
console_printf(_("Not enough memory for buffer scanlines.\n"));
|
fop_error(fop, _("Not enough memory for buffer scanlines.\n"));
|
||||||
for (c--; c>=0; c--)
|
for (c--; c>=0; c--)
|
||||||
jfree(buffer[c]);
|
jfree(buffer[c]);
|
||||||
jfree(buffer);
|
jfree(buffer);
|
||||||
jpeg_destroy_compress(&cinfo);
|
jpeg_destroy_compress(&cinfo);
|
||||||
fclose(file);
|
fclose(file);
|
||||||
return -1;
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* For progress bar. */
|
|
||||||
progress.progress_monitor = progress_monitor;
|
|
||||||
cinfo.progress = &progress;
|
|
||||||
|
|
||||||
/* Write each scan line. */
|
/* Write each scan line. */
|
||||||
while (cinfo.next_scanline < cinfo.image_height) {
|
while (cinfo.next_scanline < cinfo.image_height) {
|
||||||
/* RGB */
|
/* RGB */
|
||||||
@ -352,6 +335,8 @@ static int save_JPEG(Sprite *sprite)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
jpeg_write_scanlines(&cinfo, buffer, buffer_height);
|
jpeg_write_scanlines(&cinfo, buffer, buffer_height);
|
||||||
|
|
||||||
|
fop_progress(fop, (float)(cinfo.next_scanline+1) / (float)(cinfo.image_height));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Destroy all data. */
|
/* Destroy all data. */
|
||||||
@ -369,23 +354,24 @@ static int save_JPEG(Sprite *sprite)
|
|||||||
fclose(file);
|
fclose(file);
|
||||||
|
|
||||||
/* All fine. */
|
/* All fine. */
|
||||||
return 0;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Shows the JPEG configuration dialog.
|
* Shows the JPEG configuration dialog.
|
||||||
*/
|
*/
|
||||||
static int configure_jpeg(void)
|
static bool configure_jpeg(void)
|
||||||
{
|
{
|
||||||
JWidget window, box1, box2, box3, box4, box5;
|
JWidget window, box1, box2, box3, box4, box5;
|
||||||
JWidget label_quality, label_smooth, label_method;
|
JWidget label_quality, label_smooth, label_method;
|
||||||
JWidget slider_quality, slider_smooth, view_method;
|
JWidget slider_quality, slider_smooth, view_method;
|
||||||
JWidget list_method, button_ok, button_cancel;
|
JWidget list_method, button_ok, button_cancel;
|
||||||
int ret, quality, smooth, method;
|
int quality, smooth, method;
|
||||||
|
bool ret;
|
||||||
|
|
||||||
/* interactive mode */
|
/* interactive mode */
|
||||||
if (!is_interactive())
|
if (!is_interactive())
|
||||||
return 0;
|
return TRUE;
|
||||||
|
|
||||||
/* configuration parameters */
|
/* configuration parameters */
|
||||||
quality = get_config_int("JPEG", "Quality", 100);
|
quality = get_config_int("JPEG", "Quality", 100);
|
||||||
|
@ -25,14 +25,13 @@
|
|||||||
#include <allegro/color.h>
|
#include <allegro/color.h>
|
||||||
#include <allegro/file.h>
|
#include <allegro/file.h>
|
||||||
|
|
||||||
#include "console/console.h"
|
|
||||||
#include "file/file.h"
|
#include "file/file.h"
|
||||||
#include "raster/raster.h"
|
#include "raster/raster.h"
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static Sprite *load_PCX(const char *filename);
|
static bool load_PCX(FileOp *fop);
|
||||||
static int save_PCX(Sprite *sprite);
|
static bool save_PCX(FileOp *fop);
|
||||||
|
|
||||||
FileFormat format_pcx =
|
FileFormat format_pcx =
|
||||||
{
|
{
|
||||||
@ -46,7 +45,7 @@ FileFormat format_pcx =
|
|||||||
FILE_SUPPORT_SEQUENCES
|
FILE_SUPPORT_SEQUENCES
|
||||||
};
|
};
|
||||||
|
|
||||||
static Sprite *load_PCX(const char *filename)
|
static bool load_PCX(FileOp *fop)
|
||||||
{
|
{
|
||||||
Image *image;
|
Image *image;
|
||||||
PACKFILE *f;
|
PACKFILE *f;
|
||||||
@ -57,18 +56,18 @@ static Sprite *load_PCX(const char *filename)
|
|||||||
int x, y;
|
int x, y;
|
||||||
char ch = 0;
|
char ch = 0;
|
||||||
|
|
||||||
f = pack_fopen(filename, F_READ);
|
f = pack_fopen(fop->filename, F_READ);
|
||||||
if (!f)
|
if (!f)
|
||||||
return NULL;
|
return FALSE;
|
||||||
|
|
||||||
pack_getc(f); /* skip manufacturer ID */
|
pack_getc(f); /* skip manufacturer ID */
|
||||||
pack_getc(f); /* skip version flag */
|
pack_getc(f); /* skip version flag */
|
||||||
pack_getc(f); /* skip encoding flag */
|
pack_getc(f); /* skip encoding flag */
|
||||||
|
|
||||||
if (pack_getc(f) != 8) { /* we like 8 bit color planes */
|
if (pack_getc(f) != 8) { /* we like 8 bit color planes */
|
||||||
console_printf(_("This PCX doesn't have 8 bit color planes.\n"));
|
fop_error(fop, _("This PCX doesn't have 8 bit color planes.\n"));
|
||||||
pack_fclose(f);
|
pack_fclose(f);
|
||||||
return NULL;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
width = -(pack_igetw(f)); /* xmin */
|
width = -(pack_igetw(f)); /* xmin */
|
||||||
@ -82,7 +81,7 @@ static Sprite *load_PCX(const char *filename)
|
|||||||
r = pack_getc(f) / 4;
|
r = pack_getc(f) / 4;
|
||||||
g = pack_getc(f) / 4;
|
g = pack_getc(f) / 4;
|
||||||
b = pack_getc(f) / 4;
|
b = pack_getc(f) / 4;
|
||||||
file_sequence_set_color(c, r, g, b);
|
fop_sequence_set_color(fop, c, r, g, b);
|
||||||
}
|
}
|
||||||
|
|
||||||
pack_getc(f);
|
pack_getc(f);
|
||||||
@ -90,7 +89,7 @@ static Sprite *load_PCX(const char *filename)
|
|||||||
bpp = pack_getc(f) * 8; /* how many color planes? */
|
bpp = pack_getc(f) * 8; /* how many color planes? */
|
||||||
if ((bpp != 8) && (bpp != 24)) {
|
if ((bpp != 8) && (bpp != 24)) {
|
||||||
pack_fclose(f);
|
pack_fclose(f);
|
||||||
return NULL;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
bytes_per_line = pack_igetw(f);
|
bytes_per_line = pack_igetw(f);
|
||||||
@ -98,12 +97,13 @@ static Sprite *load_PCX(const char *filename)
|
|||||||
for (c=0; c<60; c++) /* skip some more junk */
|
for (c=0; c<60; c++) /* skip some more junk */
|
||||||
pack_getc(f);
|
pack_getc(f);
|
||||||
|
|
||||||
image = file_sequence_image(bpp == 8 ?
|
image = fop_sequence_image(fop, bpp == 8 ?
|
||||||
IMAGE_INDEXED:
|
IMAGE_INDEXED:
|
||||||
IMAGE_RGB, width, height);
|
IMAGE_RGB,
|
||||||
|
width, height);
|
||||||
if (!image) {
|
if (!image) {
|
||||||
pack_fclose(f);
|
pack_fclose(f);
|
||||||
return NULL;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bpp == 24)
|
if (bpp == 24)
|
||||||
@ -150,8 +150,7 @@ static Sprite *load_PCX(const char *filename)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (height > 1)
|
fop_progress(fop, (float)(y+1) / (float)(height));
|
||||||
do_progress(100 * y / (height-1));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bpp == 8) { /* look for a 256 color palette */
|
if (bpp == 8) { /* look for a 256 color palette */
|
||||||
@ -161,7 +160,7 @@ static Sprite *load_PCX(const char *filename)
|
|||||||
r = pack_getc(f) / 4;
|
r = pack_getc(f) / 4;
|
||||||
g = pack_getc(f) / 4;
|
g = pack_getc(f) / 4;
|
||||||
b = pack_getc(f) / 4;
|
b = pack_getc(f) / 4;
|
||||||
file_sequence_set_color(c, r, g, b);
|
fop_sequence_set_color(fop, c, r, g, b);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -169,19 +168,19 @@ static Sprite *load_PCX(const char *filename)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (*allegro_errno) {
|
if (*allegro_errno) {
|
||||||
console_printf(_("Error reading bytes.\n"));
|
fop_error(fop, _("Error reading bytes.\n"));
|
||||||
pack_fclose(f);
|
pack_fclose(f);
|
||||||
return NULL;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
pack_fclose(f);
|
pack_fclose(f);
|
||||||
return file_sequence_sprite();
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int save_PCX(Sprite *sprite)
|
static bool save_PCX(FileOp *fop)
|
||||||
{
|
{
|
||||||
|
Image *image = fop->seq.image;
|
||||||
PACKFILE *f;
|
PACKFILE *f;
|
||||||
Image *image;
|
|
||||||
int c, r, g, b;
|
int c, r, g, b;
|
||||||
int x, y;
|
int x, y;
|
||||||
int runcount;
|
int runcount;
|
||||||
@ -189,15 +188,13 @@ static int save_PCX(Sprite *sprite)
|
|||||||
char runchar;
|
char runchar;
|
||||||
char ch = 0;
|
char ch = 0;
|
||||||
|
|
||||||
f = pack_fopen(sprite->filename, F_WRITE);
|
f = pack_fopen(fop->filename, F_WRITE);
|
||||||
if (!f) {
|
if (!f) {
|
||||||
console_printf(_("Error creating file.\n"));
|
fop_error(fop, _("Error creating file.\n"));
|
||||||
return -1;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
image = file_sequence_image_to_save();
|
if (image->imgtype == IMAGE_RGB) {
|
||||||
|
|
||||||
if (sprite->imgtype == IMAGE_RGB) {
|
|
||||||
depth = 24;
|
depth = 24;
|
||||||
planes = 3;
|
planes = 3;
|
||||||
}
|
}
|
||||||
@ -220,7 +217,7 @@ static int save_PCX(Sprite *sprite)
|
|||||||
pack_iputw(200, f); /* VDpi */
|
pack_iputw(200, f); /* VDpi */
|
||||||
|
|
||||||
for (c=0; c<16; c++) {
|
for (c=0; c<16; c++) {
|
||||||
file_sequence_get_color(c, &r, &g, &b);
|
fop_sequence_get_color(fop, c, &r, &g, &b);
|
||||||
pack_putc(_rgb_scale_6[r], f);
|
pack_putc(_rgb_scale_6[r], f);
|
||||||
pack_putc(_rgb_scale_6[g], f);
|
pack_putc(_rgb_scale_6[g], f);
|
||||||
pack_putc(_rgb_scale_6[b], f);
|
pack_putc(_rgb_scale_6[b], f);
|
||||||
@ -283,15 +280,14 @@ static int save_PCX(Sprite *sprite)
|
|||||||
|
|
||||||
pack_putc(runchar, f);
|
pack_putc(runchar, f);
|
||||||
|
|
||||||
if (image->h > 1)
|
fop_progress(fop, (float)(y+1) / (float)(image->h));
|
||||||
do_progress(100 * y / (image->h-1));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (depth == 8) { /* 256 color palette */
|
if (depth == 8) { /* 256 color palette */
|
||||||
pack_putc(12, f);
|
pack_putc(12, f);
|
||||||
|
|
||||||
for (c=0; c<256; c++) {
|
for (c=0; c<256; c++) {
|
||||||
file_sequence_get_color(c, &r, &g, &b);
|
fop_sequence_get_color(fop, c, &r, &g, &b);
|
||||||
pack_putc(_rgb_scale_6[r], f);
|
pack_putc(_rgb_scale_6[r], f);
|
||||||
pack_putc(_rgb_scale_6[g], f);
|
pack_putc(_rgb_scale_6[g], f);
|
||||||
pack_putc(_rgb_scale_6[b], f);
|
pack_putc(_rgb_scale_6[b], f);
|
||||||
@ -301,9 +297,9 @@ static int save_PCX(Sprite *sprite)
|
|||||||
pack_fclose(f);
|
pack_fclose(f);
|
||||||
|
|
||||||
if (*allegro_errno) {
|
if (*allegro_errno) {
|
||||||
console_printf(_("Error writing bytes.\n"));
|
fop_error(fop, _("Error writing bytes.\n"));
|
||||||
return -1;
|
return FALSE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return 0;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/* ASE - Allegro Sprite Editor
|
/* ASE - Allegro Sprite Editor
|
||||||
* Copyright (C) 2001-2005, 2007 David A. Capello
|
* Copyright (C) 2001-2005, 2007, 2008 David A. Capello
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -23,7 +23,6 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include "console/console.h"
|
|
||||||
#include "core/app.h"
|
#include "core/app.h"
|
||||||
#include "core/cfg.h"
|
#include "core/cfg.h"
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
@ -36,8 +35,8 @@
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static Sprite *load_PNG(const char *filename);
|
static bool load_PNG(FileOp *fop);
|
||||||
static int save_PNG(Sprite *sprite);
|
static bool save_PNG(FileOp *fop);
|
||||||
|
|
||||||
/* static int configure_png(void); */
|
/* static int configure_png(void); */
|
||||||
|
|
||||||
@ -57,10 +56,10 @@ FileFormat format_png =
|
|||||||
|
|
||||||
static void report_png_error(png_structp png_ptr, png_const_charp error)
|
static void report_png_error(png_structp png_ptr, png_const_charp error)
|
||||||
{
|
{
|
||||||
console_printf("libpng: %s\n", error);
|
fop_error((FileOp *)png_ptr->error_ptr, "libpng: %s\n", error);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Sprite *load_PNG(const char *filename)
|
static bool load_PNG(FileOp *fop)
|
||||||
{
|
{
|
||||||
png_uint_32 width, height, y;
|
png_uint_32 width, height, y;
|
||||||
unsigned int sig_read = 0;
|
unsigned int sig_read = 0;
|
||||||
@ -75,12 +74,9 @@ static Sprite *load_PNG(const char *filename)
|
|||||||
int imgtype;
|
int imgtype;
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
|
|
||||||
fp = fopen(filename, "rb");
|
fp = fopen(fop->filename, "rb");
|
||||||
if (!fp) {
|
if (!fp)
|
||||||
if (!file_sequence_sprite())
|
return FALSE;
|
||||||
console_printf(_("Error opening file.\n"));
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Create and initialize the png_struct with the desired error handler
|
/* Create and initialize the png_struct with the desired error handler
|
||||||
* functions. If you want to use the default stderr and longjump method,
|
* functions. If you want to use the default stderr and longjump method,
|
||||||
@ -88,33 +84,33 @@ static Sprite *load_PNG(const char *filename)
|
|||||||
* the compiler header file version, so that we know if the application
|
* the compiler header file version, so that we know if the application
|
||||||
* was compiled with a compatible version of the library
|
* was compiled with a compatible version of the library
|
||||||
*/
|
*/
|
||||||
png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL,
|
png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, (png_voidp)fop,
|
||||||
report_png_error, report_png_error);
|
report_png_error, report_png_error);
|
||||||
if (png_ptr == NULL) {
|
if (png_ptr == NULL) {
|
||||||
console_printf("png_create_read_struct\n");
|
fop_error(fop, "png_create_read_struct\n");
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
return NULL;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Allocate/initialize the memory for image information. */
|
/* Allocate/initialize the memory for image information. */
|
||||||
info_ptr = png_create_info_struct(png_ptr);
|
info_ptr = png_create_info_struct(png_ptr);
|
||||||
if (info_ptr == NULL) {
|
if (info_ptr == NULL) {
|
||||||
console_printf("png_create_info_struct\n");
|
fop_error(fop, "png_create_info_struct\n");
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
png_destroy_read_struct(&png_ptr, png_infopp_NULL, png_infopp_NULL);
|
png_destroy_read_struct(&png_ptr, png_infopp_NULL, png_infopp_NULL);
|
||||||
return NULL;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set error handling if you are using the setjmp/longjmp method (this is
|
/* Set error handling if you are using the setjmp/longjmp method (this is
|
||||||
* the normal method of doing things with libpng).
|
* the normal method of doing things with libpng).
|
||||||
*/
|
*/
|
||||||
if (setjmp(png_jmpbuf(png_ptr))) {
|
if (setjmp(png_jmpbuf(png_ptr))) {
|
||||||
console_printf("Error reading PNG file\n");
|
fop_error(fop, "Error reading PNG file\n");
|
||||||
/* Free all of the memory associated with the png_ptr and info_ptr */
|
/* Free all of the memory associated with the png_ptr and info_ptr */
|
||||||
png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL);
|
png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL);
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
/* If we get here, we had a problem reading the file */
|
/* If we get here, we had a problem reading the file */
|
||||||
return NULL;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set up the input control if you are using standard C streams */
|
/* Set up the input control if you are using standard C streams */
|
||||||
@ -175,18 +171,18 @@ static Sprite *load_PNG(const char *filename)
|
|||||||
imgtype = IMAGE_INDEXED;
|
imgtype = IMAGE_INDEXED;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
console_printf("Color type not supported\n)");
|
fop_error(fop, "Color type not supported\n)");
|
||||||
png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL);
|
png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL);
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
return NULL;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
image = file_sequence_image(imgtype, info_ptr->width, info_ptr->height);
|
image = fop_sequence_image(fop, imgtype, info_ptr->width, info_ptr->height);
|
||||||
if (!image) {
|
if (!image) {
|
||||||
console_printf("file_sequence_image %dx%d\n", info_ptr->width, info_ptr->height);
|
fop_error(fop, "file_sequence_image %dx%d\n", info_ptr->width, info_ptr->height);
|
||||||
png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL);
|
png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL);
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
return NULL;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* read palette */
|
/* read palette */
|
||||||
@ -196,13 +192,13 @@ static Sprite *load_PNG(const char *filename)
|
|||||||
int c;
|
int c;
|
||||||
|
|
||||||
for (c = 0; c < num_palette; c++) {
|
for (c = 0; c < num_palette; c++) {
|
||||||
file_sequence_set_color(c,
|
fop_sequence_set_color(fop, c,
|
||||||
palette[c].red / 4,
|
palette[c].red / 4,
|
||||||
palette[c].green / 4,
|
palette[c].green / 4,
|
||||||
palette[c].blue / 4);
|
palette[c].blue / 4);
|
||||||
}
|
}
|
||||||
for (; c < 256; c++) {
|
for (; c < 256; c++) {
|
||||||
file_sequence_set_color(c, 0, 0, 0);
|
fop_sequence_set_color(fop, c, 0, 0, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -277,7 +273,9 @@ static Sprite *load_PNG(const char *filename)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
do_progress(100 * y / height);
|
fop_progress(fop,
|
||||||
|
(float)((float)pass + (float)(y+1) / (float)(height))
|
||||||
|
/ (float)number_passes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
png_free(png_ptr, row_pointer);
|
png_free(png_ptr, row_pointer);
|
||||||
@ -287,27 +285,25 @@ static Sprite *load_PNG(const char *filename)
|
|||||||
|
|
||||||
/* close the file */
|
/* close the file */
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
|
return TRUE;
|
||||||
/* return the sprite */
|
|
||||||
return file_sequence_sprite();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int save_PNG(Sprite *sprite)
|
static bool save_PNG(FileOp *fop)
|
||||||
{
|
{
|
||||||
|
Image *image = fop->seq.image;
|
||||||
png_uint_32 width, height, y;
|
png_uint_32 width, height, y;
|
||||||
png_structp png_ptr;
|
png_structp png_ptr;
|
||||||
png_infop info_ptr;
|
png_infop info_ptr;
|
||||||
png_colorp palette;
|
png_colorp palette;
|
||||||
png_bytep row_pointer;
|
png_bytep row_pointer;
|
||||||
int color_type;
|
int color_type;
|
||||||
Image *image;
|
|
||||||
int pass, number_passes;
|
int pass, number_passes;
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
|
|
||||||
/* open the file */
|
/* open the file */
|
||||||
fp = fopen(sprite->filename, "wb");
|
fp = fopen(fop->filename, "wb");
|
||||||
if (fp == NULL)
|
if (fp == NULL)
|
||||||
return -1;
|
return FALSE;
|
||||||
|
|
||||||
/* Create and initialize the png_struct with the desired error handler
|
/* Create and initialize the png_struct with the desired error handler
|
||||||
* functions. If you want to use the default stderr and longjump method,
|
* functions. If you want to use the default stderr and longjump method,
|
||||||
@ -315,11 +311,11 @@ static int save_PNG(Sprite *sprite)
|
|||||||
* the library version is compatible with the one used at compile time,
|
* the library version is compatible with the one used at compile time,
|
||||||
* in case we are using dynamically linked libraries. REQUIRED.
|
* in case we are using dynamically linked libraries. REQUIRED.
|
||||||
*/
|
*/
|
||||||
png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL,
|
png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, (png_voidp)fop,
|
||||||
report_png_error, report_png_error);
|
report_png_error, report_png_error);
|
||||||
if (png_ptr == NULL) {
|
if (png_ptr == NULL) {
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
return -1;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Allocate/initialize the image information data. REQUIRED */
|
/* Allocate/initialize the image information data. REQUIRED */
|
||||||
@ -327,7 +323,7 @@ static int save_PNG(Sprite *sprite)
|
|||||||
if (info_ptr == NULL) {
|
if (info_ptr == NULL) {
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
png_destroy_write_struct(&png_ptr, png_infopp_NULL);
|
png_destroy_write_struct(&png_ptr, png_infopp_NULL);
|
||||||
return -1;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set error handling. REQUIRED if you aren't supplying your own
|
/* Set error handling. REQUIRED if you aren't supplying your own
|
||||||
@ -337,7 +333,7 @@ static int save_PNG(Sprite *sprite)
|
|||||||
/* If we get here, we had a problem reading the file */
|
/* If we get here, we had a problem reading the file */
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
png_destroy_write_struct(&png_ptr, &info_ptr);
|
png_destroy_write_struct(&png_ptr, &info_ptr);
|
||||||
return -1;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* set up the output control if you are using standard C streams */
|
/* set up the output control if you are using standard C streams */
|
||||||
@ -351,18 +347,17 @@ static int save_PNG(Sprite *sprite)
|
|||||||
* PNG_INTERLACE_ADAM7, and the compression_type and filter_type MUST
|
* PNG_INTERLACE_ADAM7, and the compression_type and filter_type MUST
|
||||||
* currently be PNG_COMPRESSION_TYPE_BASE and PNG_FILTER_TYPE_BASE. REQUIRED
|
* currently be PNG_COMPRESSION_TYPE_BASE and PNG_FILTER_TYPE_BASE. REQUIRED
|
||||||
*/
|
*/
|
||||||
image = file_sequence_image_to_save();
|
|
||||||
width = image->w;
|
width = image->w;
|
||||||
height = image->h;
|
height = image->h;
|
||||||
|
|
||||||
switch (image->imgtype) {
|
switch (image->imgtype) {
|
||||||
case IMAGE_RGB:
|
case IMAGE_RGB:
|
||||||
color_type = _rgba_geta(sprite->bgcolor) < 255 ?
|
color_type = sprite_need_alpha(fop->sprite) ?
|
||||||
PNG_COLOR_TYPE_RGB_ALPHA:
|
PNG_COLOR_TYPE_RGB_ALPHA:
|
||||||
PNG_COLOR_TYPE_RGB;
|
PNG_COLOR_TYPE_RGB;
|
||||||
break;
|
break;
|
||||||
case IMAGE_GRAYSCALE:
|
case IMAGE_GRAYSCALE:
|
||||||
color_type = _graya_geta(sprite->bgcolor) < 255 ?
|
color_type = sprite_need_alpha(fop->sprite) ?
|
||||||
PNG_COLOR_TYPE_GRAY_ALPHA:
|
PNG_COLOR_TYPE_GRAY_ALPHA:
|
||||||
PNG_COLOR_TYPE_GRAY;
|
PNG_COLOR_TYPE_GRAY;
|
||||||
break;
|
break;
|
||||||
@ -386,7 +381,7 @@ static int save_PNG(Sprite *sprite)
|
|||||||
* png_sizeof(png_color));
|
* png_sizeof(png_color));
|
||||||
/* ... set palette colors ... */
|
/* ... set palette colors ... */
|
||||||
for (c = 0; c < PNG_MAX_PALETTE_LENGTH; c++) {
|
for (c = 0; c < PNG_MAX_PALETTE_LENGTH; c++) {
|
||||||
file_sequence_get_color(c, &r, &g, &b);
|
fop_sequence_get_color(fop, c, &r, &g, &b);
|
||||||
palette[c].red = _rgb_scale_6[r];
|
palette[c].red = _rgb_scale_6[r];
|
||||||
palette[c].green = _rgb_scale_6[g];
|
palette[c].green = _rgb_scale_6[g];
|
||||||
palette[c].blue = _rgb_scale_6[b];
|
palette[c].blue = _rgb_scale_6[b];
|
||||||
@ -474,7 +469,10 @@ static int save_PNG(Sprite *sprite)
|
|||||||
|
|
||||||
/* write the line */
|
/* write the line */
|
||||||
png_write_rows(png_ptr, &row_pointer, 1);
|
png_write_rows(png_ptr, &row_pointer, 1);
|
||||||
do_progress(100 * y / height);
|
|
||||||
|
fop_progress(fop,
|
||||||
|
(float)((float)pass + (float)(y+1) / (float)(height))
|
||||||
|
/ (float)number_passes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -500,7 +498,7 @@ static int save_PNG(Sprite *sprite)
|
|||||||
fclose(fp);
|
fclose(fp);
|
||||||
|
|
||||||
/* all right */
|
/* all right */
|
||||||
return 0;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* static int configure_png(void) */
|
/* static int configure_png(void) */
|
||||||
|
@ -28,14 +28,13 @@
|
|||||||
|
|
||||||
#include "jinete/jbase.h"
|
#include "jinete/jbase.h"
|
||||||
|
|
||||||
#include "console/console.h"
|
|
||||||
#include "file/file.h"
|
#include "file/file.h"
|
||||||
#include "raster/raster.h"
|
#include "raster/raster.h"
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int save_TGA(Sprite *sprite);
|
static bool load_TGA(FileOp *fop);
|
||||||
static Sprite *load_TGA(const char *filename);
|
static bool save_TGA(FileOp *fop);
|
||||||
|
|
||||||
FileFormat format_tga =
|
FileFormat format_tga =
|
||||||
{
|
{
|
||||||
@ -191,7 +190,7 @@ static void rle_tga_read16(ase_uint32 *address, int w, PACKFILE *f)
|
|||||||
* structure and storing the palette data in the specified palette (this
|
* structure and storing the palette data in the specified palette (this
|
||||||
* should be an array of at least 256 RGB structures).
|
* should be an array of at least 256 RGB structures).
|
||||||
*/
|
*/
|
||||||
static Sprite *load_TGA(const char *filename)
|
static bool load_TGA(FileOp *fop)
|
||||||
{
|
{
|
||||||
unsigned char image_id[256], image_palette[256][3], rgb[4];
|
unsigned char image_id[256], image_palette[256][3], rgb[4];
|
||||||
unsigned char id_length, palette_type, image_type, palette_entry_size;
|
unsigned char id_length, palette_type, image_type, palette_entry_size;
|
||||||
@ -204,12 +203,9 @@ static Sprite *load_TGA(const char *filename)
|
|||||||
PACKFILE *f;
|
PACKFILE *f;
|
||||||
int type;
|
int type;
|
||||||
|
|
||||||
f = pack_fopen(filename, F_READ);
|
f = pack_fopen(fop->filename, F_READ);
|
||||||
if (!f) {
|
if (!f)
|
||||||
if (!file_sequence_sprite())
|
return FALSE;
|
||||||
console_printf(_("Error opening file.\n"));
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
*allegro_errno = 0;
|
*allegro_errno = 0;
|
||||||
|
|
||||||
@ -252,7 +248,7 @@ static Sprite *load_TGA(const char *filename)
|
|||||||
}
|
}
|
||||||
else if (palette_type != 0) {
|
else if (palette_type != 0) {
|
||||||
pack_fclose(f);
|
pack_fclose(f);
|
||||||
return NULL;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Image type:
|
/* Image type:
|
||||||
@ -273,14 +269,14 @@ static Sprite *load_TGA(const char *filename)
|
|||||||
case 1:
|
case 1:
|
||||||
if ((palette_type != 1) || (bpp != 8)) {
|
if ((palette_type != 1) || (bpp != 8)) {
|
||||||
pack_fclose(f);
|
pack_fclose(f);
|
||||||
return NULL;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i=0; i<palette_colors; i++) {
|
for (i=0; i<palette_colors; i++) {
|
||||||
file_sequence_set_color(i,
|
fop_sequence_set_color(fop, i,
|
||||||
image_palette[i][2] >> 2,
|
image_palette[i][2] >> 2,
|
||||||
image_palette[i][1] >> 2,
|
image_palette[i][1] >> 2,
|
||||||
image_palette[i][0] >> 2);
|
image_palette[i][0] >> 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
type = IMAGE_INDEXED;
|
type = IMAGE_INDEXED;
|
||||||
@ -292,7 +288,7 @@ static Sprite *load_TGA(const char *filename)
|
|||||||
((bpp != 15) && (bpp != 16) &&
|
((bpp != 15) && (bpp != 16) &&
|
||||||
(bpp != 24) && (bpp != 32))) {
|
(bpp != 24) && (bpp != 32))) {
|
||||||
pack_fclose(f);
|
pack_fclose(f);
|
||||||
return NULL;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
type = IMAGE_RGB;
|
type = IMAGE_RGB;
|
||||||
@ -302,11 +298,11 @@ static Sprite *load_TGA(const char *filename)
|
|||||||
case 3:
|
case 3:
|
||||||
if ((palette_type != 0) || (bpp != 8)) {
|
if ((palette_type != 0) || (bpp != 8)) {
|
||||||
pack_fclose(f);
|
pack_fclose(f);
|
||||||
return NULL;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i=0; i<256; i++)
|
for (i=0; i<256; i++)
|
||||||
file_sequence_set_color(i, i>>2, i>>2, i>>2);
|
fop_sequence_set_color(fop, i, i>>2, i>>2, i>>2);
|
||||||
|
|
||||||
type = IMAGE_GRAYSCALE;
|
type = IMAGE_GRAYSCALE;
|
||||||
break;
|
break;
|
||||||
@ -315,13 +311,13 @@ static Sprite *load_TGA(const char *filename)
|
|||||||
/* TODO add support for more TGA types? */
|
/* TODO add support for more TGA types? */
|
||||||
|
|
||||||
pack_fclose(f);
|
pack_fclose(f);
|
||||||
return NULL;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
image = file_sequence_image(type, image_width, image_height);
|
image = fop_sequence_image(fop, type, image_width, image_height);
|
||||||
if (!image) {
|
if (!image) {
|
||||||
pack_fclose(f);
|
pack_fclose(f);
|
||||||
return NULL;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (y=image_height; y; y--) {
|
for (y=image_height; y; y--) {
|
||||||
@ -385,48 +381,46 @@ static Sprite *load_TGA(const char *filename)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (image_height > 1)
|
if (image_height > 1)
|
||||||
do_progress(100 * (image_height-y) / image_height);
|
fop_progress(fop, (float)(image_height-y) / (float)(image_height));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*allegro_errno) {
|
if (*allegro_errno) {
|
||||||
console_printf(_("Error reading bytes.\n"));
|
fop_error(fop, _("Error reading bytes.\n"));
|
||||||
pack_fclose(f);
|
pack_fclose(f);
|
||||||
return NULL;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
pack_fclose(f);
|
pack_fclose(f);
|
||||||
return file_sequence_sprite();
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* save_tga:
|
/* save_tga:
|
||||||
* Writes a bitmap into a TGA file, using the specified palette (this
|
* Writes a bitmap into a TGA file, using the specified palette (this
|
||||||
* should be an array of at least 256 RGB structures).
|
* should be an array of at least 256 RGB structures).
|
||||||
*/
|
*/
|
||||||
static int save_TGA(Sprite *sprite)
|
static bool save_TGA(FileOp *fop)
|
||||||
{
|
{
|
||||||
|
Image *image = fop->seq.image;
|
||||||
unsigned char image_palette[256][3];
|
unsigned char image_palette[256][3];
|
||||||
int x, y, c, r, g, b;
|
int x, y, c, r, g, b;
|
||||||
int depth = (sprite->imgtype == IMAGE_RGB) ? 32 : 8;
|
int depth = (image->imgtype == IMAGE_RGB) ? 32 : 8;
|
||||||
bool need_pal = (sprite->imgtype == IMAGE_INDEXED)? TRUE: FALSE;
|
bool need_pal = (image->imgtype == IMAGE_INDEXED)? TRUE: FALSE;
|
||||||
PACKFILE *f;
|
PACKFILE *f;
|
||||||
Image *image;
|
|
||||||
|
|
||||||
f = pack_fopen(sprite->filename, F_WRITE);
|
f = pack_fopen(fop->filename, F_WRITE);
|
||||||
if (!f) {
|
if (!f) {
|
||||||
console_printf(_("Error creating file.\n"));
|
fop_error(fop, _("Error creating file.\n"));
|
||||||
return -1;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
image = file_sequence_image_to_save();
|
|
||||||
|
|
||||||
*allegro_errno = 0;
|
*allegro_errno = 0;
|
||||||
|
|
||||||
pack_putc(0, f); /* id length (no id saved) */
|
pack_putc(0, f); /* id length (no id saved) */
|
||||||
pack_putc((need_pal) ? 1 : 0, f); /* palette type */
|
pack_putc((need_pal) ? 1 : 0, f); /* palette type */
|
||||||
/* image type */
|
/* image type */
|
||||||
pack_putc((sprite->imgtype == IMAGE_RGB ) ? 2 :
|
pack_putc((image->imgtype == IMAGE_RGB ) ? 2 :
|
||||||
(sprite->imgtype == IMAGE_GRAYSCALE) ? 3 :
|
(image->imgtype == IMAGE_GRAYSCALE) ? 3 :
|
||||||
(sprite->imgtype == IMAGE_INDEXED ) ? 1 : 0, f);
|
(image->imgtype == IMAGE_INDEXED ) ? 1 : 0, f);
|
||||||
pack_iputw(0, f); /* first colour */
|
pack_iputw(0, f); /* first colour */
|
||||||
pack_iputw((need_pal) ? 256 : 0, f); /* number of colours */
|
pack_iputw((need_pal) ? 256 : 0, f); /* number of colours */
|
||||||
pack_putc((need_pal) ? 24 : 0, f); /* palette entry size */
|
pack_putc((need_pal) ? 24 : 0, f); /* palette entry size */
|
||||||
@ -437,11 +431,11 @@ static int save_TGA(Sprite *sprite)
|
|||||||
pack_putc(depth, f); /* bits per pixel */
|
pack_putc(depth, f); /* bits per pixel */
|
||||||
|
|
||||||
/* descriptor (bottom to top, 8-bit alpha) */
|
/* descriptor (bottom to top, 8-bit alpha) */
|
||||||
pack_putc(sprite->imgtype == IMAGE_RGB ? 8: 0, f);
|
pack_putc(image->imgtype == IMAGE_RGB ? 8: 0, f);
|
||||||
|
|
||||||
if (need_pal) {
|
if (need_pal) {
|
||||||
for (y=0; y<256; y++) {
|
for (y=0; y<256; y++) {
|
||||||
file_sequence_get_color(y, &r, &g, &b);
|
fop_sequence_get_color(fop, y, &r, &g, &b);
|
||||||
image_palette[y][2] = _rgb_scale_6[r];
|
image_palette[y][2] = _rgb_scale_6[r];
|
||||||
image_palette[y][1] = _rgb_scale_6[g];
|
image_palette[y][1] = _rgb_scale_6[g];
|
||||||
image_palette[y][0] = _rgb_scale_6[b];
|
image_palette[y][0] = _rgb_scale_6[b];
|
||||||
@ -449,40 +443,37 @@ static int save_TGA(Sprite *sprite)
|
|||||||
pack_fwrite(image_palette, 768, f);
|
pack_fwrite(image_palette, 768, f);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (sprite->imgtype) {
|
switch (image->imgtype) {
|
||||||
|
|
||||||
case IMAGE_RGB:
|
case IMAGE_RGB:
|
||||||
for (y=image->h; y; y--) {
|
for (y=image->h-1; y>=0; y--) {
|
||||||
for (x=0; x<image->w; x++) {
|
for (x=0; x<image->w; x++) {
|
||||||
c = image_getpixel(image, x, y-1);
|
c = image_getpixel(image, x, y);
|
||||||
pack_putc(_rgba_getb(c), f);
|
pack_putc(_rgba_getb(c), f);
|
||||||
pack_putc(_rgba_getg(c), f);
|
pack_putc(_rgba_getg(c), f);
|
||||||
pack_putc(_rgba_getr(c), f);
|
pack_putc(_rgba_getr(c), f);
|
||||||
pack_putc(_rgba_geta(c), f);
|
pack_putc(_rgba_geta(c), f);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (image->h > 1)
|
fop_progress(fop, (float)(image->h-y) / (float)(image->h));
|
||||||
do_progress(100 * (image->h-y) / (image->h-1));
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IMAGE_GRAYSCALE:
|
case IMAGE_GRAYSCALE:
|
||||||
for (y=image->h; y; y--) {
|
for (y=image->h-1; y>=0; y--) {
|
||||||
for (x=0; x<image->w; x++)
|
for (x=0; x<image->w; x++)
|
||||||
pack_putc(_graya_getk(image_getpixel(image, x, y-1)), f);
|
pack_putc(_graya_getk(image_getpixel(image, x, y)), f);
|
||||||
|
|
||||||
if (image->h > 1)
|
fop_progress(fop, (float)(image->h-y) / (float)(image->h));
|
||||||
do_progress(100 * (image->h-y) / (image->h-1));
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IMAGE_INDEXED:
|
case IMAGE_INDEXED:
|
||||||
for (y=image->h; y; y--) {
|
for (y=image->h-1; y>=0; y--) {
|
||||||
for (x=0; x<image->w; x++)
|
for (x=0; x<image->w; x++)
|
||||||
pack_putc(image_getpixel(image, x, y-1), f);
|
pack_putc(image_getpixel(image, x, y), f);
|
||||||
|
|
||||||
if (image->h > 1)
|
fop_progress(fop, (float)(image->h-y) / (float)(image->h));
|
||||||
do_progress(100 * (image->h-y) / (image->h-1));
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -490,9 +481,9 @@ static int save_TGA(Sprite *sprite)
|
|||||||
pack_fclose(f);
|
pack_fclose(f);
|
||||||
|
|
||||||
if (*allegro_errno) {
|
if (*allegro_errno) {
|
||||||
console_printf(_("Error writing bytes.\n"));
|
fop_error(fop, _("Error writing bytes.\n"));
|
||||||
return -1;
|
return FALSE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return 0;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -76,9 +76,6 @@ void intl_set_lang(const char *lang)
|
|||||||
/* clear msgids and load them again */
|
/* clear msgids and load them again */
|
||||||
msgids_clear();
|
msgids_clear();
|
||||||
intl_load_lang();
|
intl_load_lang();
|
||||||
|
|
||||||
/* reload the main menu */
|
|
||||||
rebuild_root_menu();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* int init_intl(void) */
|
/* int init_intl(void) */
|
||||||
|
@ -231,7 +231,9 @@ enum {
|
|||||||
|
|
||||||
typedef unsigned int JID;
|
typedef unsigned int JID;
|
||||||
|
|
||||||
|
typedef void *JThread;
|
||||||
typedef void *JMutex;
|
typedef void *JMutex;
|
||||||
|
|
||||||
typedef struct jaccel *JAccel;
|
typedef struct jaccel *JAccel;
|
||||||
typedef struct jhook *JHook;
|
typedef struct jhook *JHook;
|
||||||
typedef struct jquickmenu *JQuickMenu;
|
typedef struct jquickmenu *JQuickMenu;
|
||||||
@ -249,9 +251,6 @@ typedef struct jxmlnode *JXmlNode;
|
|||||||
typedef struct jxmlelem *JXmlElem;
|
typedef struct jxmlelem *JXmlElem;
|
||||||
typedef struct jxmltext *JXmlText;
|
typedef struct jxmltext *JXmlText;
|
||||||
|
|
||||||
typedef void (*JFunc) (void *data, void *user_data);
|
|
||||||
typedef int (*JCompareFunc) (const void *a, const void *b);
|
|
||||||
typedef int (*JCompareDataFunc) (const void *a, const void *b, void *user_data);
|
|
||||||
typedef bool (*JMessageFunc) (JWidget widget, JMessage msg);
|
typedef bool (*JMessageFunc) (JWidget widget, JMessage msg);
|
||||||
typedef void (*JDrawFunc) (JWidget widget);
|
typedef void (*JDrawFunc) (JWidget widget);
|
||||||
|
|
||||||
|
@ -46,9 +46,10 @@ bool jcombobox_is_editable(JWidget combobox);
|
|||||||
bool jcombobox_is_clickopen(JWidget combobox);
|
bool jcombobox_is_clickopen(JWidget combobox);
|
||||||
bool jcombobox_is_casesensitive(JWidget combobox);
|
bool jcombobox_is_casesensitive(JWidget combobox);
|
||||||
|
|
||||||
void jcombobox_add_string(JWidget combobox, const char *string);
|
void jcombobox_add_string(JWidget combobox, const char *string, void *data);
|
||||||
void jcombobox_del_string(JWidget combobox, const char *string);
|
void jcombobox_del_string(JWidget combobox, const char *string);
|
||||||
void jcombobox_del_index(JWidget combobox, int index);
|
void jcombobox_del_index(JWidget combobox, int index);
|
||||||
|
void jcombobox_clear(JWidget combobox);
|
||||||
|
|
||||||
void jcombobox_select_index(JWidget combobox, int index);
|
void jcombobox_select_index(JWidget combobox, int index);
|
||||||
void jcombobox_select_string(JWidget combobox, const char *string);
|
void jcombobox_select_string(JWidget combobox, const char *string);
|
||||||
@ -56,10 +57,12 @@ int jcombobox_get_selected_index(JWidget combobox);
|
|||||||
const char *jcombobox_get_selected_string(JWidget combobox);
|
const char *jcombobox_get_selected_string(JWidget combobox);
|
||||||
|
|
||||||
const char *jcombobox_get_string(JWidget combobox, int index);
|
const char *jcombobox_get_string(JWidget combobox, int index);
|
||||||
|
void *jcombobox_get_data(JWidget combobox, int index);
|
||||||
int jcombobox_get_index(JWidget combobox, const char *string);
|
int jcombobox_get_index(JWidget combobox, const char *string);
|
||||||
int jcombobox_get_count(JWidget combobox);
|
int jcombobox_get_count(JWidget combobox);
|
||||||
|
|
||||||
JWidget jcombobox_get_entry_widget(JWidget combobox);
|
JWidget jcombobox_get_entry_widget(JWidget combobox);
|
||||||
|
JWidget jcombobox_get_button_widget(JWidget combobox);
|
||||||
|
|
||||||
JI_END_DECLS
|
JI_END_DECLS
|
||||||
|
|
||||||
|
@ -38,6 +38,7 @@ typedef struct ComboBox
|
|||||||
JWidget entry;
|
JWidget entry;
|
||||||
JWidget button;
|
JWidget button;
|
||||||
JWidget window;
|
JWidget window;
|
||||||
|
JWidget listbox;
|
||||||
JList items;
|
JList items;
|
||||||
int selected;
|
int selected;
|
||||||
bool editable : 1;
|
bool editable : 1;
|
||||||
@ -45,6 +46,12 @@ typedef struct ComboBox
|
|||||||
bool casesensitive : 1;
|
bool casesensitive : 1;
|
||||||
} ComboBox;
|
} ComboBox;
|
||||||
|
|
||||||
|
typedef struct ComboItem
|
||||||
|
{
|
||||||
|
char *text;
|
||||||
|
void *data;
|
||||||
|
} ComboItem;
|
||||||
|
|
||||||
#define COMBOBOX(widget) ((ComboBox *)jwidget_get_data(widget, JI_COMBOBOX))
|
#define COMBOBOX(widget) ((ComboBox *)jwidget_get_data(widget, JI_COMBOBOX))
|
||||||
#define IS_VALID_ITEM(widget, index) \
|
#define IS_VALID_ITEM(widget, index) \
|
||||||
(index >= 0 && index < jlist_length(COMBOBOX(widget)->items))
|
(index >= 0 && index < jlist_length(COMBOBOX(widget)->items))
|
||||||
@ -58,13 +65,16 @@ static void combobox_close_window(JWidget widget);
|
|||||||
static void combobox_switch_window(JWidget widget);
|
static void combobox_switch_window(JWidget widget);
|
||||||
static JRect combobox_get_windowpos(ComboBox *combobox);
|
static JRect combobox_get_windowpos(ComboBox *combobox);
|
||||||
|
|
||||||
|
static ComboItem *comboitem_new(const char *text, void *data);
|
||||||
|
static void comboitem_free(ComboItem *item);
|
||||||
|
|
||||||
JWidget jcombobox_new(void)
|
JWidget jcombobox_new(void)
|
||||||
{
|
{
|
||||||
JWidget widget = jbox_new(JI_HORIZONTAL);
|
JWidget widget = jwidget_new(JI_COMBOBOX);
|
||||||
ComboBox *combobox = jnew(ComboBox, 1);
|
ComboBox *combobox = jnew(ComboBox, 1);
|
||||||
|
|
||||||
combobox->entry = jentry_new(256, "");
|
combobox->entry = jentry_new(256, "");
|
||||||
combobox->button = jbutton_new("^");
|
combobox->button = jbutton_new("");
|
||||||
combobox->window = NULL;
|
combobox->window = NULL;
|
||||||
combobox->items = jlist_new();
|
combobox->items = jlist_new();
|
||||||
combobox->selected = 0;
|
combobox->selected = 0;
|
||||||
@ -91,6 +101,8 @@ JWidget jcombobox_new(void)
|
|||||||
|
|
||||||
jcombobox_editable(widget, combobox->editable);
|
jcombobox_editable(widget, combobox->editable);
|
||||||
|
|
||||||
|
jwidget_init_theme(widget);
|
||||||
|
|
||||||
return widget;
|
return widget;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -145,12 +157,13 @@ bool jcombobox_is_casesensitive(JWidget widget)
|
|||||||
return combobox->casesensitive;
|
return combobox->casesensitive;
|
||||||
}
|
}
|
||||||
|
|
||||||
void jcombobox_add_string(JWidget widget, const char *string)
|
void jcombobox_add_string(JWidget widget, const char *string, void *data)
|
||||||
{
|
{
|
||||||
ComboBox *combobox = jwidget_get_data(widget, JI_COMBOBOX);
|
ComboBox *combobox = jwidget_get_data(widget, JI_COMBOBOX);
|
||||||
bool sel_first = jlist_empty(combobox->items);
|
bool sel_first = jlist_empty(combobox->items);
|
||||||
|
ComboItem *item = comboitem_new(string, data);
|
||||||
|
|
||||||
jlist_append(combobox->items, jstrdup(string));
|
jlist_append(combobox->items, item);
|
||||||
|
|
||||||
if (sel_first)
|
if (sel_first)
|
||||||
jcombobox_select_index(widget, 0);
|
jcombobox_select_index(widget, 0);
|
||||||
@ -164,17 +177,34 @@ void jcombobox_del_string(JWidget widget, const char *string)
|
|||||||
void jcombobox_del_index(JWidget widget, int index)
|
void jcombobox_del_index(JWidget widget, int index)
|
||||||
{
|
{
|
||||||
ComboBox *combobox = jwidget_get_data(widget, JI_COMBOBOX);
|
ComboBox *combobox = jwidget_get_data(widget, JI_COMBOBOX);
|
||||||
|
ComboItem *item = jlist_nth_data(combobox->items, index);
|
||||||
|
|
||||||
jlist_remove(combobox->items, jlist_nth_data(combobox->items, index));
|
jlist_remove(combobox->items, item);
|
||||||
|
comboitem_free(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
void jcombobox_clear(JWidget widget)
|
||||||
|
{
|
||||||
|
ComboBox *combobox = jwidget_get_data(widget, JI_COMBOBOX);
|
||||||
|
JLink link;
|
||||||
|
|
||||||
|
JI_LIST_FOR_EACH(combobox->items, link)
|
||||||
|
comboitem_free(link->data);
|
||||||
|
|
||||||
|
jlist_clear(combobox->items);
|
||||||
}
|
}
|
||||||
|
|
||||||
void jcombobox_select_index(JWidget widget, int index)
|
void jcombobox_select_index(JWidget widget, int index)
|
||||||
{
|
{
|
||||||
ComboBox *combobox = jwidget_get_data(widget, JI_COMBOBOX);
|
ComboBox *combobox = jwidget_get_data(widget, JI_COMBOBOX);
|
||||||
JLink link = jlist_nth_link(combobox->items, index);
|
JLink link = jlist_nth_link(combobox->items, index);
|
||||||
|
ComboItem *item;
|
||||||
|
|
||||||
if (link != combobox->items->end) {
|
if (link != combobox->items->end) {
|
||||||
combobox->selected = index;
|
combobox->selected = index;
|
||||||
jwidget_set_text(combobox->entry, link->data);
|
|
||||||
|
item = link->data;
|
||||||
|
jwidget_set_text(combobox->entry, item->text);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -194,15 +224,29 @@ const char *jcombobox_get_selected_string(JWidget widget)
|
|||||||
{
|
{
|
||||||
ComboBox *combobox = jwidget_get_data(widget, JI_COMBOBOX);
|
ComboBox *combobox = jwidget_get_data(widget, JI_COMBOBOX);
|
||||||
|
|
||||||
return jlist_nth_data(combobox->items, combobox->selected);
|
return jcombobox_get_string(widget, combobox->selected);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *jcombobox_get_string(JWidget widget, int index)
|
const char *jcombobox_get_string(JWidget widget, int index)
|
||||||
{
|
{
|
||||||
ComboBox *combobox = jwidget_get_data(widget, JI_COMBOBOX);
|
ComboBox *combobox = jwidget_get_data(widget, JI_COMBOBOX);
|
||||||
|
|
||||||
if (index >= 0 && index < jlist_length(combobox->items))
|
if (index >= 0 && index < jlist_length(combobox->items)) {
|
||||||
return jlist_nth_link(combobox->items, index)->data;
|
ComboItem *item = jlist_nth_link(combobox->items, index)->data;
|
||||||
|
return item->text;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *jcombobox_get_data(JWidget widget, int index)
|
||||||
|
{
|
||||||
|
ComboBox *combobox = jwidget_get_data(widget, JI_COMBOBOX);
|
||||||
|
|
||||||
|
if (index >= 0 && index < jlist_length(combobox->items)) {
|
||||||
|
ComboItem *item = jlist_nth_link(combobox->items, index)->data;
|
||||||
|
return item->data;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -214,8 +258,10 @@ int jcombobox_get_index(JWidget widget, const char *string)
|
|||||||
JLink link;
|
JLink link;
|
||||||
|
|
||||||
JI_LIST_FOR_EACH(combobox->items, link) {
|
JI_LIST_FOR_EACH(combobox->items, link) {
|
||||||
if ((combobox->casesensitive && ustrcmp(link->data, string) == 0) ||
|
ComboItem *item = link->data;
|
||||||
(!combobox->casesensitive && ustricmp(link->data, string) == 0))
|
|
||||||
|
if ((combobox->casesensitive && ustrcmp(item->text, string) == 0) ||
|
||||||
|
(!combobox->casesensitive && ustricmp(item->text, string) == 0))
|
||||||
return index;
|
return index;
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
@ -237,8 +283,17 @@ JWidget jcombobox_get_entry_widget(JWidget widget)
|
|||||||
return combobox->entry;
|
return combobox->entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
JWidget jcombobox_get_button_widget(JWidget widget)
|
||||||
|
{
|
||||||
|
ComboBox *combobox = jwidget_get_data(widget, JI_COMBOBOX);
|
||||||
|
|
||||||
|
return combobox->button;
|
||||||
|
}
|
||||||
|
|
||||||
static bool combobox_msg_proc(JWidget widget, JMessage msg)
|
static bool combobox_msg_proc(JWidget widget, JMessage msg)
|
||||||
{
|
{
|
||||||
|
ComboBox *combobox = jwidget_get_data(widget, JI_COMBOBOX);
|
||||||
|
|
||||||
switch (msg->type) {
|
switch (msg->type) {
|
||||||
|
|
||||||
case JM_CLOSE:
|
case JM_CLOSE:
|
||||||
@ -246,28 +301,65 @@ static bool combobox_msg_proc(JWidget widget, JMessage msg)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case JM_DESTROY:
|
case JM_DESTROY:
|
||||||
{
|
jcombobox_clear(widget);
|
||||||
ComboBox *combobox = jwidget_get_data(widget, JI_COMBOBOX);
|
jlist_free(combobox->items);
|
||||||
JLink link;
|
jfree(combobox);
|
||||||
|
break;
|
||||||
|
|
||||||
JI_LIST_FOR_EACH(combobox->items, link)
|
case JM_REQSIZE: {
|
||||||
jfree(link->data);
|
int w, h;
|
||||||
|
|
||||||
jlist_free(combobox->items);
|
msg->reqsize.w = 0;
|
||||||
jfree(combobox);
|
msg->reqsize.h = 0;
|
||||||
|
|
||||||
|
jwidget_request_size(combobox->entry, &w, &h);
|
||||||
|
msg->reqsize.w += w;
|
||||||
|
msg->reqsize.h += h;
|
||||||
|
|
||||||
|
jwidget_request_size(combobox->button, &w, &h);
|
||||||
|
msg->reqsize.w += w;
|
||||||
|
msg->reqsize.h = MAX(msg->reqsize.h, h);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
case JM_SETPOS: {
|
||||||
|
JRect cbox = jrect_new_copy(&msg->setpos.rect);
|
||||||
|
int w, h;
|
||||||
|
|
||||||
|
jrect_copy(widget->rc, cbox);
|
||||||
|
|
||||||
|
/* button */
|
||||||
|
jwidget_request_size(combobox->button, &w, &h);
|
||||||
|
cbox->x1 = msg->setpos.rect.x2 - w;
|
||||||
|
jwidget_set_rect(combobox->button, cbox);
|
||||||
|
|
||||||
|
/* entry */
|
||||||
|
cbox->x2 = cbox->x1;
|
||||||
|
cbox->x1 = msg->setpos.rect.x1;
|
||||||
|
jwidget_set_rect(combobox->entry, cbox);
|
||||||
|
|
||||||
|
jrect_free(cbox);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
case JM_WINMOVE:
|
||||||
|
if (combobox->window) {
|
||||||
|
JRect rc = combobox_get_windowpos(combobox);
|
||||||
|
jwindow_move(combobox->window, rc);
|
||||||
|
jrect_free(rc);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case JM_WINMOVE:
|
case JM_BUTTONPRESSED:
|
||||||
{
|
if (combobox->window != NULL) {
|
||||||
ComboBox *combobox = jwidget_get_data(widget, JI_COMBOBOX);
|
if (!jwidget_has_mouse(jwidget_get_view(combobox->listbox))) {
|
||||||
if (combobox->window) {
|
combobox_close_window(widget);
|
||||||
JRect rc = combobox_get_windowpos(combobox);
|
return TRUE;
|
||||||
jwindow_move(combobox->window, rc);
|
|
||||||
jrect_free(rc);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@ -384,20 +476,24 @@ static void combobox_open_window(JWidget widget)
|
|||||||
{
|
{
|
||||||
ComboBox *combobox = jwidget_get_data(widget, JI_COMBOBOX);
|
ComboBox *combobox = jwidget_get_data(widget, JI_COMBOBOX);
|
||||||
if (!combobox->window) {
|
if (!combobox->window) {
|
||||||
JWidget view, listbox;
|
JWidget view;
|
||||||
JLink link;
|
JLink link;
|
||||||
int size;
|
int size;
|
||||||
JRect rc;
|
JRect rc;
|
||||||
|
|
||||||
combobox->window = jwindow_new(NULL);
|
combobox->window = jwindow_new(NULL);
|
||||||
view = jview_new();
|
view = jview_new();
|
||||||
listbox = jlistbox_new();
|
combobox->listbox = jlistbox_new();
|
||||||
|
|
||||||
listbox->user_data[0] = widget;
|
combobox->listbox->user_data[0] = widget;
|
||||||
jwidget_add_hook(listbox, JI_WIDGET, combobox_listbox_msg_proc, NULL);
|
jwidget_add_hook(combobox->listbox, JI_WIDGET,
|
||||||
|
combobox_listbox_msg_proc, NULL);
|
||||||
|
|
||||||
JI_LIST_FOR_EACH(combobox->items, link)
|
JI_LIST_FOR_EACH(combobox->items, link) {
|
||||||
jwidget_add_child(listbox, jlistitem_new(link->data));
|
ComboItem *item = link->data;
|
||||||
|
jwidget_add_child(combobox->listbox,
|
||||||
|
jlistitem_new(item->text));
|
||||||
|
}
|
||||||
|
|
||||||
jwindow_ontop(combobox->window, TRUE);
|
jwindow_ontop(combobox->window, TRUE);
|
||||||
jwidget_noborders(combobox->window);
|
jwidget_noborders(combobox->window);
|
||||||
@ -406,14 +502,14 @@ static void combobox_open_window(JWidget widget)
|
|||||||
jwidget_set_min_size
|
jwidget_set_min_size
|
||||||
(view,
|
(view,
|
||||||
jrect_w(combobox->entry->rc),
|
jrect_w(combobox->entry->rc),
|
||||||
2+(2+jwidget_get_text_height(listbox))*MID(1, size, 10)+2);
|
2+(2+jwidget_get_text_height(combobox->listbox))*MID(1, size, 10)+2);
|
||||||
|
|
||||||
jwidget_add_child(combobox->window, view);
|
jwidget_add_child(combobox->window, view);
|
||||||
jview_attach(view, listbox);
|
jview_attach(view, combobox->listbox);
|
||||||
|
|
||||||
jwidget_signal_off(listbox);
|
jwidget_signal_off(combobox->listbox);
|
||||||
jlistbox_select_index(listbox, combobox->selected);
|
jlistbox_select_index(combobox->listbox, combobox->selected);
|
||||||
jwidget_signal_on(listbox);
|
jwidget_signal_on(combobox->listbox);
|
||||||
|
|
||||||
jwindow_remap(combobox->window);
|
jwindow_remap(combobox->window);
|
||||||
|
|
||||||
@ -421,8 +517,10 @@ static void combobox_open_window(JWidget widget)
|
|||||||
jwindow_position(combobox->window, rc->x1, rc->y1);
|
jwindow_position(combobox->window, rc->x1, rc->y1);
|
||||||
jrect_free(rc);
|
jrect_free(rc);
|
||||||
|
|
||||||
|
jmanager_add_msg_filter(JM_BUTTONPRESSED, widget);
|
||||||
|
|
||||||
jwindow_open_bg(combobox->window);
|
jwindow_open_bg(combobox->window);
|
||||||
jmanager_set_focus(listbox);
|
jmanager_set_focus(combobox->listbox);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -433,6 +531,7 @@ static void combobox_close_window(JWidget widget)
|
|||||||
jwindow_close(combobox->window, widget);
|
jwindow_close(combobox->window, widget);
|
||||||
combobox->window = NULL;
|
combobox->window = NULL;
|
||||||
|
|
||||||
|
jmanager_remove_msg_filter(JM_BUTTONPRESSED, widget);
|
||||||
jmanager_set_focus(combobox->entry);
|
jmanager_set_focus(combobox->entry);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -457,3 +556,23 @@ static JRect combobox_get_windowpos(ComboBox *combobox)
|
|||||||
jrect_displace(rc, 0, -(jrect_h(rc)+jrect_h(combobox->entry->rc)));
|
jrect_displace(rc, 0, -(jrect_h(rc)+jrect_h(combobox->entry->rc)));
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static ComboItem *comboitem_new(const char *text, void *data)
|
||||||
|
{
|
||||||
|
ComboItem *comboitem = jnew(ComboItem, 1);
|
||||||
|
if (!comboitem)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
comboitem->text = jstrdup(text);
|
||||||
|
comboitem->data = data;
|
||||||
|
|
||||||
|
return comboitem;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void comboitem_free(ComboItem *comboitem)
|
||||||
|
{
|
||||||
|
if (comboitem->text)
|
||||||
|
jfree(comboitem->text);
|
||||||
|
|
||||||
|
jfree(comboitem);
|
||||||
|
}
|
||||||
|
@ -33,6 +33,7 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
#include <allegro/unicode.h>
|
||||||
|
|
||||||
#include "jinete/jinete.h"
|
#include "jinete/jinete.h"
|
||||||
|
|
||||||
@ -133,12 +134,27 @@ static JWidget convert_tag_to_widget(Tag *tag)
|
|||||||
Attr *right = tag_get_attr(tag, "right");
|
Attr *right = tag_get_attr(tag, "right");
|
||||||
Attr *top = tag_get_attr(tag, "top");
|
Attr *top = tag_get_attr(tag, "top");
|
||||||
Attr *bottom = tag_get_attr(tag, "bottom");
|
Attr *bottom = tag_get_attr(tag, "bottom");
|
||||||
|
Attr *bevel = tag_get_attr(tag, "bevel");
|
||||||
|
|
||||||
jwidget_set_align(widget,
|
jwidget_set_align(widget,
|
||||||
(left ? JI_LEFT:
|
(left ? JI_LEFT: (right ? JI_RIGHT: JI_CENTER)) |
|
||||||
right ? JI_RIGHT: JI_CENTER) |
|
(top ? JI_TOP: (bottom ? JI_BOTTOM: JI_MIDDLE)));
|
||||||
(top ? JI_TOP:
|
|
||||||
bottom ? JI_BOTTOM: JI_MIDDLE));
|
if (bevel) {
|
||||||
|
int c, b[4];
|
||||||
|
char *tok;
|
||||||
|
|
||||||
|
for (c=0; c<4; ++c)
|
||||||
|
b[c] = 0;
|
||||||
|
|
||||||
|
for (tok=ustrtok(bevel->value, " "), c=0;
|
||||||
|
tok;
|
||||||
|
tok=ustrtok(NULL, " "), ++c) {
|
||||||
|
if (c < 4)
|
||||||
|
b[c] = ustrtol(tok, NULL, 10);
|
||||||
|
}
|
||||||
|
jbutton_set_bevel(widget, b[0], b[1], b[2], b[3]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -155,10 +171,8 @@ static JWidget convert_tag_to_widget(Tag *tag)
|
|||||||
Attr *bottom = tag_get_attr(tag, "bottom");
|
Attr *bottom = tag_get_attr(tag, "bottom");
|
||||||
|
|
||||||
jwidget_set_align(widget,
|
jwidget_set_align(widget,
|
||||||
(center ? JI_CENTER:
|
(center ? JI_CENTER: (right ? JI_RIGHT: JI_LEFT)) |
|
||||||
right ? JI_RIGHT: JI_LEFT) |
|
(top ? JI_TOP: (bottom ? JI_BOTTOM: JI_MIDDLE)));
|
||||||
(top ? JI_TOP:
|
|
||||||
bottom ? JI_BOTTOM: JI_MIDDLE));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -64,6 +64,7 @@
|
|||||||
#include "jinete/jsystem.h"
|
#include "jinete/jsystem.h"
|
||||||
#include "jinete/jtextbox.h"
|
#include "jinete/jtextbox.h"
|
||||||
#include "jinete/jtheme.h"
|
#include "jinete/jtheme.h"
|
||||||
|
#include "jinete/jthread.h"
|
||||||
#include "jinete/jview.h"
|
#include "jinete/jview.h"
|
||||||
#include "jinete/jwidget.h"
|
#include "jinete/jwidget.h"
|
||||||
#include "jinete/jwindow.h"
|
#include "jinete/jwindow.h"
|
||||||
|
@ -33,7 +33,7 @@
|
|||||||
|
|
||||||
#include "jinete/jlist.h"
|
#include "jinete/jlist.h"
|
||||||
|
|
||||||
#ifdef USE_JUNKLIST
|
#ifdef USE_JUNKLIST /* TODO warning not thread safe */
|
||||||
static JList junklist = NULL;
|
static JList junklist = NULL;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -533,12 +533,7 @@ bool jmanager_generate_messages(JWidget manager)
|
|||||||
count = 0;
|
count = 0;
|
||||||
while (t - timers[c]->last_time > timers[c]->interval) {
|
while (t - timers[c]->last_time > timers[c]->interval) {
|
||||||
timers[c]->last_time += timers[c]->interval;
|
timers[c]->last_time += timers[c]->interval;
|
||||||
|
++count;
|
||||||
msg = jmessage_new(JM_TIMER);
|
|
||||||
msg->timer.count = count;
|
|
||||||
msg->timer.timer_id = c;
|
|
||||||
jmessage_add_dest(msg, timers[c]->widget);
|
|
||||||
jmanager_enqueue_message(msg);
|
|
||||||
|
|
||||||
/* we spend too much time here */
|
/* we spend too much time here */
|
||||||
if (ji_clock - t > timers[c]->interval) {
|
if (ji_clock - t > timers[c]->interval) {
|
||||||
@ -546,6 +541,14 @@ bool jmanager_generate_messages(JWidget manager)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (count > 0) {
|
||||||
|
msg = jmessage_new(JM_TIMER);
|
||||||
|
msg->timer.count = count;
|
||||||
|
msg->timer.timer_id = c;
|
||||||
|
jmessage_add_dest(msg, timers[c]->widget);
|
||||||
|
jmanager_enqueue_message(msg);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -604,11 +607,26 @@ int jmanager_add_timer(JWidget widget, int interval)
|
|||||||
|
|
||||||
void jmanager_remove_timer(int timer_id)
|
void jmanager_remove_timer(int timer_id)
|
||||||
{
|
{
|
||||||
|
JMessage message;
|
||||||
|
JLink link, next;
|
||||||
|
|
||||||
assert(timer_id >= 0 && timer_id < n_timers);
|
assert(timer_id >= 0 && timer_id < n_timers);
|
||||||
assert(timers[timer_id] != NULL);
|
assert(timers[timer_id] != NULL);
|
||||||
|
|
||||||
jfree(timers[timer_id]);
|
jfree(timers[timer_id]);
|
||||||
timers[timer_id] = NULL;
|
timers[timer_id] = NULL;
|
||||||
|
|
||||||
|
/* remove messages of this timer in the queue */
|
||||||
|
JI_LIST_FOR_EACH_SAFE(msg_queue, link, next) {
|
||||||
|
message = link->data;
|
||||||
|
if (!message->any.used &&
|
||||||
|
message->any.type == JM_TIMER &&
|
||||||
|
message->timer.timer_id == timer_id) {
|
||||||
|
printf("REMOVING A TIMER MESSAGE FROM THE QUEUE!!\n"); fflush(stdout);
|
||||||
|
jmessage_free(link->data);
|
||||||
|
jlist_delete_link(msg_queue, link);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void jmanager_start_timer(int timer_id)
|
void jmanager_start_timer(int timer_id)
|
||||||
|
@ -31,6 +31,7 @@
|
|||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <allegro/unicode.h>
|
||||||
|
|
||||||
void *jmalloc(unsigned long n_bytes)
|
void *jmalloc(unsigned long n_bytes)
|
||||||
{
|
{
|
||||||
@ -80,6 +81,6 @@ void jfree(void *mem)
|
|||||||
|
|
||||||
char *jstrdup(const char *string)
|
char *jstrdup(const char *string)
|
||||||
{
|
{
|
||||||
return strdup(string);
|
return ustrdup(string);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -240,6 +240,13 @@ JAccel jmenuitem_get_accel(JWidget widget)
|
|||||||
return MITEM(widget)->accel;
|
return MITEM(widget)->accel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool jmenuitem_has_submenu_opened(JWidget widget)
|
||||||
|
{
|
||||||
|
assert_valid_widget(widget);
|
||||||
|
|
||||||
|
return MITEM(widget)->submenu_menubox != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
void jmenubox_set_menu(JWidget widget, JWidget widget_menu)
|
void jmenubox_set_menu(JWidget widget, JWidget widget_menu)
|
||||||
{
|
{
|
||||||
JWidget old_menu;
|
JWidget old_menu;
|
||||||
|
@ -45,6 +45,7 @@ JWidget jmenubox_get_menu(JWidget menubox);
|
|||||||
JWidget jmenubar_get_menu(JWidget menubar);
|
JWidget jmenubar_get_menu(JWidget menubar);
|
||||||
JWidget jmenuitem_get_submenu(JWidget menuitem);
|
JWidget jmenuitem_get_submenu(JWidget menuitem);
|
||||||
JAccel jmenuitem_get_accel(JWidget menuitem);
|
JAccel jmenuitem_get_accel(JWidget menuitem);
|
||||||
|
bool jmenuitem_has_submenu_opened(JWidget menuitem);
|
||||||
|
|
||||||
void jmenubox_set_menu(JWidget menubox, JWidget menu);
|
void jmenubox_set_menu(JWidget menubox, JWidget menu);
|
||||||
void jmenubar_set_menu(JWidget menubar, JWidget menu);
|
void jmenubar_set_menu(JWidget menubar, JWidget menu);
|
||||||
|
@ -96,7 +96,7 @@ struct jmessage_signal
|
|||||||
struct jmessage_timer
|
struct jmessage_timer
|
||||||
{
|
{
|
||||||
struct jmessage_any any;
|
struct jmessage_any any;
|
||||||
int count; /* cound=0 if it's first msg of timer-chain */
|
int count; /* accumulated calls */
|
||||||
int timer_id; /* number of timer */
|
int timer_id; /* number of timer */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
99
src/jinete/jthread.c
Normal file
99
src/jinete/jthread.c
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
/* Jinete - a GUI library
|
||||||
|
* Copyright (C) 2003, 2004, 2005, 2007, 2008 David A. Capello.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in
|
||||||
|
* the documentation and/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
* * Neither the name of the Jinete nor the names of its contributors may
|
||||||
|
* be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <allegro.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
#include "jinete/jthread.h"
|
||||||
|
|
||||||
|
#undef UNIX_LIKE
|
||||||
|
#if defined ALLEGRO_UNIX || \
|
||||||
|
defined ALLEGRO_LINUX || \
|
||||||
|
defined ALLEGRO_MACOSX || \
|
||||||
|
defined ALLEGRO_BEOS || \
|
||||||
|
defined ALLEGRO_QNX
|
||||||
|
#define UNIX_LIKE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined ALLEGRO_WINDOWS
|
||||||
|
#include <winalleg.h>
|
||||||
|
#include <process.h>
|
||||||
|
#elif defined UNIX_LIKE
|
||||||
|
#include <pthread.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined UNIX_LIKE
|
||||||
|
struct pthread_proxy_data {
|
||||||
|
void (*proc)(JThread thread, void *data);
|
||||||
|
void *data;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void *pthread_proxy(void *arg)
|
||||||
|
{
|
||||||
|
pthread_proxy_data *ptr = arg;
|
||||||
|
void (*proc)(JThread thread, void *data) = ptr->proc;
|
||||||
|
void *data = ptr->data;
|
||||||
|
jfree(ptr);
|
||||||
|
|
||||||
|
(*proc)(data);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
JThread jthread_new(void (*proc)(void *data), void *data)
|
||||||
|
{
|
||||||
|
#if defined ALLEGRO_WINDOWS
|
||||||
|
return (JThread)_beginthread(proc, 0, data);
|
||||||
|
#elif defined UNIX_LIKE
|
||||||
|
pthread_t thread = 0;
|
||||||
|
struct pthread_proxy_data *ptr = jnew(struct pthread_proxy_data, 1);
|
||||||
|
ptr->proc = proc;
|
||||||
|
ptr->data = data;
|
||||||
|
|
||||||
|
if (pthread_create(&thread, NULL, pthread_proxy, ptr))
|
||||||
|
return NULL;
|
||||||
|
else
|
||||||
|
return (JThread)thread;
|
||||||
|
#else
|
||||||
|
#error ASE doesn\'t support threads for your platform
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void jthread_join(JThread thread)
|
||||||
|
{
|
||||||
|
#if defined ALLEGRO_WINDOWS
|
||||||
|
WaitForSingleObject(thread, INFINITE);
|
||||||
|
#elif defined UNIX_LIKE
|
||||||
|
pthread_join((pthread_t)thread, NULL);
|
||||||
|
#else
|
||||||
|
#error ASE doesn\'t support threads for your platform
|
||||||
|
#endif
|
||||||
|
}
|
44
src/jinete/jthread.h
Normal file
44
src/jinete/jthread.h
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
/* Jinete - a GUI library
|
||||||
|
* Copyright (C) 2003, 2004, 2005, 2007, 2008 David A. Capello.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in
|
||||||
|
* the documentation and/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
* * Neither the name of the Jinete nor the names of its contributors may
|
||||||
|
* be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef JINETE_THREAD_H
|
||||||
|
#define JINETE_THREAD_H
|
||||||
|
|
||||||
|
#include "jinete/jbase.h"
|
||||||
|
|
||||||
|
JI_BEGIN_DECLS
|
||||||
|
|
||||||
|
JThread jthread_new(void (*proc)(void *data), void *data);
|
||||||
|
void jthread_join(JThread thread);
|
||||||
|
|
||||||
|
JI_END_DECLS
|
||||||
|
|
||||||
|
#endif /* JINETE_THREAD_H */
|
@ -232,7 +232,7 @@ JHook jwidget_get_hook(JWidget widget, int type)
|
|||||||
*/
|
*/
|
||||||
void *jwidget_get_data(JWidget widget, int type)
|
void *jwidget_get_data(JWidget widget, int type)
|
||||||
{
|
{
|
||||||
JLink link;
|
register JLink link;
|
||||||
assert_valid_widget(widget);
|
assert_valid_widget(widget);
|
||||||
|
|
||||||
JI_LIST_FOR_EACH(widget->hooks, link) {
|
JI_LIST_FOR_EACH(widget->hooks, link) {
|
||||||
|
@ -60,6 +60,7 @@ enum {
|
|||||||
ICON_MENU_MARK,
|
ICON_MENU_MARK,
|
||||||
ICON_RADIO_EDGE,
|
ICON_RADIO_EDGE,
|
||||||
ICON_RADIO_MARK,
|
ICON_RADIO_MARK,
|
||||||
|
ICON_COMBOBOX,
|
||||||
ICONS,
|
ICONS,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -86,12 +87,10 @@ static struct {
|
|||||||
{ TRUE, default_theme_imenum },
|
{ TRUE, default_theme_imenum },
|
||||||
{ FALSE, default_theme_iradioe },
|
{ FALSE, default_theme_iradioe },
|
||||||
{ FALSE, default_theme_iradiom },
|
{ FALSE, default_theme_iradiom },
|
||||||
|
{ FALSE, default_theme_icombobox },
|
||||||
};
|
};
|
||||||
|
|
||||||
static BITMAP *icons_bitmap[ICONS] = {
|
static BITMAP *icons_bitmap[ICONS];
|
||||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
|
||||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
|
||||||
};
|
|
||||||
|
|
||||||
static void theme_destroy(void);
|
static void theme_destroy(void);
|
||||||
static void theme_regen(void);
|
static void theme_regen(void);
|
||||||
@ -138,11 +137,15 @@ static bool theme_button_msg_proc(JWidget widget, JMessage msg);
|
|||||||
JTheme jtheme_new_standard(void)
|
JTheme jtheme_new_standard(void)
|
||||||
{
|
{
|
||||||
JTheme theme;
|
JTheme theme;
|
||||||
|
int c;
|
||||||
|
|
||||||
theme = jtheme_new();
|
theme = jtheme_new();
|
||||||
if (!theme)
|
if (!theme)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
for (c=0; c<ICONS; c++)
|
||||||
|
icons_bitmap[c] = NULL;
|
||||||
|
|
||||||
theme->name = "Standard Theme";
|
theme->name = "Standard Theme";
|
||||||
theme->check_icon_size = 8;
|
theme->check_icon_size = 8;
|
||||||
theme->radio_icon_size = 8;
|
theme->radio_icon_size = 8;
|
||||||
@ -327,6 +330,12 @@ static void theme_init_widget(JWidget widget)
|
|||||||
BORDER(1);
|
BORDER(1);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case JI_COMBOBOX: {
|
||||||
|
JWidget button = jcombobox_get_button_widget(widget);
|
||||||
|
ji_generic_button_set_icon(button, icons_bitmap[ICON_COMBOBOX]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case JI_MENU:
|
case JI_MENU:
|
||||||
case JI_MENUBAR:
|
case JI_MENUBAR:
|
||||||
case JI_MENUBOX:
|
case JI_MENUBOX:
|
||||||
|
@ -296,6 +296,18 @@ static unsigned char default_theme_iclose[66] = {
|
|||||||
0, 0, 0, 0, 0, 0, 0, 0
|
0, 0, 0, 0, 0, 0, 0, 0
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static unsigned char default_theme_icombobox[66] = {
|
||||||
|
8, 8,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
1, 1, 1, 1, 1, 1, 1, 0,
|
||||||
|
0, 1, 1, 1, 1, 1, 0, 0,
|
||||||
|
0, 0, 1, 1, 1, 0, 0, 0,
|
||||||
|
0, 0, 0, 1, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0
|
||||||
|
};
|
||||||
|
|
||||||
static unsigned char default_theme_imenum[66] = {
|
static unsigned char default_theme_imenum[66] = {
|
||||||
8, 8,
|
8, 8,
|
||||||
0, 0, 0, 0, 0, 0, 0, 0,
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
BIN
src/jinete/themes/stand/icombobox.pcx
Normal file
BIN
src/jinete/themes/stand/icombobox.pcx
Normal file
Binary file not shown.
@ -44,7 +44,7 @@ int main(int argc, char *argv[])
|
|||||||
set_uformat(U_ASCII);
|
set_uformat(U_ASCII);
|
||||||
|
|
||||||
/* initialises the application */
|
/* initialises the application */
|
||||||
if (app_init(argc, argv) < 0)
|
if (!app_init(argc, argv))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
app_loop();
|
app_loop();
|
||||||
|
@ -206,7 +206,7 @@ void set_current_editor(JWidget editor)
|
|||||||
|
|
||||||
set_current_sprite(editor_get_sprite(current_editor));
|
set_current_sprite(editor_get_sprite(current_editor));
|
||||||
app_refresh_screen();
|
app_refresh_screen();
|
||||||
rebuild_sprite_list();
|
app_realloc_sprite_list();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -221,7 +221,7 @@ void set_sprite_in_current_editor(Sprite *sprite)
|
|||||||
jwidget_dirty(jwidget_get_view(current_editor));
|
jwidget_dirty(jwidget_get_view(current_editor));
|
||||||
|
|
||||||
app_refresh_screen();
|
app_refresh_screen();
|
||||||
rebuild_sprite_list();
|
app_realloc_sprite_list();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,6 +81,8 @@ enum {
|
|||||||
|
|
||||||
GFX_ARROW_LEFT,
|
GFX_ARROW_LEFT,
|
||||||
GFX_ARROW_RIGHT,
|
GFX_ARROW_RIGHT,
|
||||||
|
GFX_ARROW_UP,
|
||||||
|
GFX_ARROW_DOWN,
|
||||||
|
|
||||||
GFX_BOX_SHOW,
|
GFX_BOX_SHOW,
|
||||||
GFX_BOX_HIDE,
|
GFX_BOX_HIDE,
|
||||||
|
@ -259,14 +259,14 @@ static DATA gfx_data[GFX_BITMAP_COUNT] =
|
|||||||
/* GFX_FILE_HOME */
|
/* GFX_FILE_HOME */
|
||||||
{ 7, 9,
|
{ 7, 9,
|
||||||
" # "
|
" # "
|
||||||
" # # "
|
" ### "
|
||||||
" # # "
|
" ##### "
|
||||||
"#######"
|
"#######"
|
||||||
"# #"
|
"#######"
|
||||||
"# ### #"
|
"## ##"
|
||||||
"# # # #"
|
"## ##"
|
||||||
"# # # #"
|
"## ##"
|
||||||
"#######" },
|
"## ##" },
|
||||||
/* GFX_FILE_FONTS */
|
/* GFX_FILE_FONTS */
|
||||||
{ 7, 9,
|
{ 7, 9,
|
||||||
" "
|
" "
|
||||||
@ -450,6 +450,26 @@ static DATA gfx_data[GFX_BITMAP_COUNT] =
|
|||||||
" ## "
|
" ## "
|
||||||
" # "
|
" # "
|
||||||
" " },
|
" " },
|
||||||
|
/* GFX_ARROW_UP */
|
||||||
|
{ 8, 8,
|
||||||
|
" "
|
||||||
|
" "
|
||||||
|
" # "
|
||||||
|
" ### "
|
||||||
|
" ##### "
|
||||||
|
"####### "
|
||||||
|
" "
|
||||||
|
" " },
|
||||||
|
/* GFX_ARROW_DOWN */
|
||||||
|
{ 8, 8,
|
||||||
|
" "
|
||||||
|
" "
|
||||||
|
"####### "
|
||||||
|
" ##### "
|
||||||
|
" ### "
|
||||||
|
" # "
|
||||||
|
" "
|
||||||
|
" " },
|
||||||
/* GFX_BOX_SHOW */
|
/* GFX_BOX_SHOW */
|
||||||
{ 8, 8,
|
{ 8, 8,
|
||||||
" #### "
|
" #### "
|
||||||
|
@ -54,10 +54,8 @@
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define REBUILD_LOCK 1
|
#define REBUILD_RECENT_LIST 2
|
||||||
#define REBUILD_ROOT_MENU 2
|
#define REFRESH_FULL_SCREEN 4
|
||||||
#define REBUILD_RECENT_LIST 8
|
|
||||||
#define REBUILD_FULLREFRESH 16
|
|
||||||
|
|
||||||
/**************************************************************/
|
/**************************************************************/
|
||||||
|
|
||||||
@ -82,7 +80,20 @@ static int try_depths[] = { 32, 24, 16, 15, 8 };
|
|||||||
|
|
||||||
/**************************************************************/
|
/**************************************************************/
|
||||||
|
|
||||||
|
typedef struct Monitor {
|
||||||
|
/**
|
||||||
|
* Returns true when the job is done and the monitor can be removed.
|
||||||
|
*/
|
||||||
|
bool (*proc)(void *);
|
||||||
|
void *data;
|
||||||
|
bool lock;
|
||||||
|
} Monitor;
|
||||||
|
|
||||||
static JWidget manager = NULL;
|
static JWidget manager = NULL;
|
||||||
|
|
||||||
|
static int monitor_timer = -1;
|
||||||
|
static JList monitors;
|
||||||
|
|
||||||
static bool ji_screen_created = FALSE;
|
static bool ji_screen_created = FALSE;
|
||||||
|
|
||||||
static volatile int next_idle_flags = 0;
|
static volatile int next_idle_flags = 0;
|
||||||
@ -92,6 +103,9 @@ static JList icon_buttons;
|
|||||||
static bool double_buffering;
|
static bool double_buffering;
|
||||||
static int screen_scaling;
|
static int screen_scaling;
|
||||||
|
|
||||||
|
static Monitor *monitor_new(bool (*proc)(void *), void *data);
|
||||||
|
static void monitor_free(Monitor *monitor);
|
||||||
|
|
||||||
/* load & save graphics configuration */
|
/* load & save graphics configuration */
|
||||||
static void load_gui_config(int *w, int *h, int *bpp, bool *fullscreen);
|
static void load_gui_config(int *w, int *h, int *bpp, bool *fullscreen);
|
||||||
static void save_gui_config(void);
|
static void save_gui_config(void);
|
||||||
@ -106,7 +120,7 @@ static void regen_theme_and_fixup_icons(void);
|
|||||||
*/
|
*/
|
||||||
static void display_switch_in_callback()
|
static void display_switch_in_callback()
|
||||||
{
|
{
|
||||||
next_idle_flags |= REBUILD_FULLREFRESH;
|
next_idle_flags |= REFRESH_FULL_SCREEN;
|
||||||
}
|
}
|
||||||
|
|
||||||
END_OF_STATIC_FUNCTION(display_switch_in_callback);
|
END_OF_STATIC_FUNCTION(display_switch_in_callback);
|
||||||
@ -222,6 +236,8 @@ int init_module_gui(void)
|
|||||||
}
|
}
|
||||||
gfx_done:;
|
gfx_done:;
|
||||||
|
|
||||||
|
monitors = jlist_new();
|
||||||
|
|
||||||
/* create the default-manager */
|
/* create the default-manager */
|
||||||
manager = jmanager_new();
|
manager = jmanager_new();
|
||||||
jwidget_add_hook(manager, JI_WIDGET, manager_msg_proc, NULL);
|
jwidget_add_hook(manager, JI_WIDGET, manager_msg_proc, NULL);
|
||||||
@ -261,6 +277,14 @@ int init_module_gui(void)
|
|||||||
|
|
||||||
void exit_module_gui(void)
|
void exit_module_gui(void)
|
||||||
{
|
{
|
||||||
|
JLink link;
|
||||||
|
|
||||||
|
JI_LIST_FOR_EACH(monitors, link) {
|
||||||
|
monitor_free(link->data);
|
||||||
|
}
|
||||||
|
jlist_free(monitors);
|
||||||
|
monitors = NULL;
|
||||||
|
|
||||||
if (double_buffering) {
|
if (double_buffering) {
|
||||||
BITMAP *old_bmp = ji_screen;
|
BITMAP *old_bmp = ji_screen;
|
||||||
ji_set_screen(screen);
|
ji_set_screen(screen);
|
||||||
@ -281,6 +305,24 @@ void exit_module_gui(void)
|
|||||||
remove_timer();
|
remove_timer();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Monitor *monitor_new(bool (*proc)(void *), void *data)
|
||||||
|
{
|
||||||
|
Monitor *monitor = jnew(Monitor, 1);
|
||||||
|
if (!monitor)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
monitor->proc = proc;
|
||||||
|
monitor->data = data;
|
||||||
|
monitor->lock = FALSE;
|
||||||
|
|
||||||
|
return monitor;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void monitor_free(Monitor *monitor)
|
||||||
|
{
|
||||||
|
jfree(monitor);
|
||||||
|
}
|
||||||
|
|
||||||
static void load_gui_config(int *w, int *h, int *bpp, bool *fullscreen)
|
static void load_gui_config(int *w, int *h, int *bpp, bool *fullscreen)
|
||||||
{
|
{
|
||||||
*w = get_config_int("GfxMode", "Width", 0);
|
*w = get_config_int("GfxMode", "Width", 0);
|
||||||
@ -347,23 +389,14 @@ void gui_run(void)
|
|||||||
void gui_feedback(void)
|
void gui_feedback(void)
|
||||||
{
|
{
|
||||||
/* menu stuff */
|
/* menu stuff */
|
||||||
if (!(next_idle_flags & REBUILD_LOCK)) {
|
if (next_idle_flags & REBUILD_RECENT_LIST) {
|
||||||
if (next_idle_flags & REBUILD_ROOT_MENU) {
|
if (app_realloc_recent_list())
|
||||||
next_idle_flags ^= REBUILD_ROOT_MENU;
|
|
||||||
load_root_menu();
|
|
||||||
|
|
||||||
next_idle_flags |= REBUILD_RECENT_LIST;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (next_idle_flags & REBUILD_RECENT_LIST) {
|
|
||||||
next_idle_flags ^= REBUILD_RECENT_LIST;
|
next_idle_flags ^= REBUILD_RECENT_LIST;
|
||||||
app_realloc_recent_list();
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (next_idle_flags & REBUILD_FULLREFRESH) {
|
if (next_idle_flags & REFRESH_FULL_SCREEN) {
|
||||||
next_idle_flags ^= REBUILD_FULLREFRESH;
|
next_idle_flags ^= REFRESH_FULL_SCREEN;
|
||||||
update_screen_for_sprite(current_sprite);
|
update_screen_for_sprite(current_sprite);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* record file if is necessary */
|
/* record file if is necessary */
|
||||||
@ -534,26 +567,6 @@ JWidget load_widget(const char *filename, const char *name)
|
|||||||
return widget;
|
return widget;
|
||||||
}
|
}
|
||||||
|
|
||||||
void rebuild_lock(void)
|
|
||||||
{
|
|
||||||
next_idle_flags |= REBUILD_LOCK;
|
|
||||||
}
|
|
||||||
|
|
||||||
void rebuild_unlock(void)
|
|
||||||
{
|
|
||||||
next_idle_flags &= ~REBUILD_LOCK;
|
|
||||||
}
|
|
||||||
|
|
||||||
void rebuild_root_menu(void)
|
|
||||||
{
|
|
||||||
next_idle_flags |= REBUILD_ROOT_MENU;
|
|
||||||
}
|
|
||||||
|
|
||||||
void rebuild_sprite_list(void)
|
|
||||||
{
|
|
||||||
app_realloc_sprite_list();
|
|
||||||
}
|
|
||||||
|
|
||||||
void rebuild_recent_list(void)
|
void rebuild_recent_list(void)
|
||||||
{
|
{
|
||||||
next_idle_flags |= REBUILD_RECENT_LIST;
|
next_idle_flags |= REBUILD_RECENT_LIST;
|
||||||
@ -708,6 +721,16 @@ JWidget check_button_new(const char *text, int b1, int b2, int b3, int b4)
|
|||||||
return widget;
|
return widget;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void add_gui_monitor(bool (*proc)(void *data), void *data)
|
||||||
|
{
|
||||||
|
jlist_append(monitors, monitor_new(proc, data));
|
||||||
|
|
||||||
|
if (monitor_timer < 0)
|
||||||
|
monitor_timer = jmanager_add_timer(manager, 100);
|
||||||
|
|
||||||
|
jmanager_start_timer(monitor_timer);
|
||||||
|
}
|
||||||
|
|
||||||
/**********************************************************************/
|
/**********************************************************************/
|
||||||
/* manager event handler */
|
/* manager event handler */
|
||||||
|
|
||||||
@ -719,6 +742,32 @@ static bool manager_msg_proc(JWidget widget, JMessage msg)
|
|||||||
gui_feedback();
|
gui_feedback();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case JM_TIMER:
|
||||||
|
if (msg->timer.timer_id == monitor_timer) {
|
||||||
|
JLink link, next;
|
||||||
|
JI_LIST_FOR_EACH_SAFE(monitors, link, next) {
|
||||||
|
Monitor *monitor = link->data;
|
||||||
|
|
||||||
|
/* is the monitor not lock? */
|
||||||
|
if (!monitor->lock) {
|
||||||
|
/* call the monitor procedure */
|
||||||
|
monitor->lock = TRUE;
|
||||||
|
if ((*monitor->proc)(monitor->data)) {
|
||||||
|
/* the function returns true, the job is done... remove the monitor */
|
||||||
|
monitor_free(link->data);
|
||||||
|
jlist_delete_link(monitors, link);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
monitor->lock = FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* is monitors empty? we can stop the timer so */
|
||||||
|
if (jlist_empty(monitors))
|
||||||
|
jmanager_stop_timer(monitor_timer);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case JM_CHAR: {
|
case JM_CHAR: {
|
||||||
Command *command = command_get_by_key(msg);
|
Command *command = command_get_by_key(msg);
|
||||||
if (!command)
|
if (!command)
|
||||||
|
@ -45,10 +45,6 @@ void save_window_pos(JWidget window, const char *section);
|
|||||||
|
|
||||||
JWidget load_widget(const char *filename, const char *name);
|
JWidget load_widget(const char *filename, const char *name);
|
||||||
|
|
||||||
void rebuild_lock(void);
|
|
||||||
void rebuild_unlock(void);
|
|
||||||
void rebuild_root_menu(void);
|
|
||||||
void rebuild_sprite_list(void);
|
|
||||||
void rebuild_recent_list(void);
|
void rebuild_recent_list(void);
|
||||||
|
|
||||||
void hook_signal(JWidget widget,
|
void hook_signal(JWidget widget,
|
||||||
@ -65,4 +61,6 @@ JWidget radio_button_new(int radio_group, int b1, int b2, int b3, int b4);
|
|||||||
JWidget check_button_new(const char *text, int b1, int b2, int b3, int b4);
|
JWidget check_button_new(const char *text, int b1, int b2, int b3, int b4);
|
||||||
/* void change_to_button_style(JWidget widget, int b1, int b2, int b3, int b4); */
|
/* void change_to_button_style(JWidget widget, int b1, int b2, int b3, int b4); */
|
||||||
|
|
||||||
|
void add_gui_monitor(bool (*proc)(void *data), void *data);
|
||||||
|
|
||||||
#endif /* MODULES_GUI_H */
|
#endif /* MODULES_GUI_H */
|
||||||
|
@ -46,6 +46,7 @@ static JWidget frame_popup_menu;
|
|||||||
static JWidget cel_popup_menu;
|
static JWidget cel_popup_menu;
|
||||||
static JWidget filters_popup_menu;
|
static JWidget filters_popup_menu;
|
||||||
|
|
||||||
|
static int load_root_menu(void);
|
||||||
static JWidget load_menu_by_id(JXml xml, const char *id, const char *filename);
|
static JWidget load_menu_by_id(JXml xml, const char *id, const char *filename);
|
||||||
static JWidget convert_xmlelem_to_menu(JXmlElem elem);
|
static JWidget convert_xmlelem_to_menu(JXmlElem elem);
|
||||||
static JWidget convert_xmlelem_to_menuitem(JXmlElem elem);
|
static JWidget convert_xmlelem_to_menuitem(JXmlElem elem);
|
||||||
@ -75,7 +76,24 @@ void exit_module_rootmenu(void)
|
|||||||
if (filters_popup_menu) jwidget_free(filters_popup_menu);
|
if (filters_popup_menu) jwidget_free(filters_popup_menu);
|
||||||
}
|
}
|
||||||
|
|
||||||
int load_root_menu(void)
|
JWidget get_root_menu(void) { return root_menu; }
|
||||||
|
|
||||||
|
JWidget get_recent_list_menuitem(void) { return recent_list_menuitem; }
|
||||||
|
JWidget get_layer_popup_menu(void) { return layer_popup_menu; }
|
||||||
|
JWidget get_frame_popup_menu(void) { return frame_popup_menu; }
|
||||||
|
JWidget get_cel_popup_menu(void) { return cel_popup_menu; }
|
||||||
|
|
||||||
|
/* void show_fx_popup_menu(void) */
|
||||||
|
/* { */
|
||||||
|
/* if (is_interactive() && */
|
||||||
|
/* filters_popup_menuitem && */
|
||||||
|
/* jmenuitem_get_submenu(filters_popup_menuitem)) { */
|
||||||
|
/* jmenu_popup(jmenuitem_get_submenu(filters_popup_menuitem), */
|
||||||
|
/* jmouse_x(0), jmouse_y(0)); */
|
||||||
|
/* } */
|
||||||
|
/* } */
|
||||||
|
|
||||||
|
static int load_root_menu(void)
|
||||||
{
|
{
|
||||||
JLink link, link2;
|
JLink link, link2;
|
||||||
DIRS *dirs, *dir;
|
DIRS *dirs, *dir;
|
||||||
@ -199,23 +217,6 @@ int load_root_menu(void)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
JWidget get_root_menu(void) { return root_menu; }
|
|
||||||
|
|
||||||
JWidget get_recent_list_menuitem(void) { return recent_list_menuitem; }
|
|
||||||
JWidget get_layer_popup_menu(void) { return layer_popup_menu; }
|
|
||||||
JWidget get_frame_popup_menu(void) { return frame_popup_menu; }
|
|
||||||
JWidget get_cel_popup_menu(void) { return cel_popup_menu; }
|
|
||||||
|
|
||||||
/* void show_fx_popup_menu(void) */
|
|
||||||
/* { */
|
|
||||||
/* if (is_interactive() && */
|
|
||||||
/* filters_popup_menuitem && */
|
|
||||||
/* jmenuitem_get_submenu(filters_popup_menuitem)) { */
|
|
||||||
/* jmenu_popup(jmenuitem_get_submenu(filters_popup_menuitem), */
|
|
||||||
/* jmouse_x(0), jmouse_y(0)); */
|
|
||||||
/* } */
|
|
||||||
/* } */
|
|
||||||
|
|
||||||
static JWidget load_menu_by_id(JXml xml, const char *id, const char *filename)
|
static JWidget load_menu_by_id(JXml xml, const char *id, const char *filename)
|
||||||
{
|
{
|
||||||
JWidget menu = NULL;
|
JWidget menu = NULL;
|
||||||
|
@ -33,8 +33,6 @@ enum {
|
|||||||
int init_module_rootmenu(void);
|
int init_module_rootmenu(void);
|
||||||
void exit_module_rootmenu(void);
|
void exit_module_rootmenu(void);
|
||||||
|
|
||||||
int load_root_menu(void);
|
|
||||||
|
|
||||||
JWidget get_root_menu(void);
|
JWidget get_root_menu(void);
|
||||||
|
|
||||||
JWidget get_recent_list_menuitem(void);
|
JWidget get_recent_list_menuitem(void);
|
||||||
|
@ -115,7 +115,7 @@ void set_clipboard_sprite(Sprite *sprite)
|
|||||||
clipboard_sprite = sprite;
|
clipboard_sprite = sprite;
|
||||||
|
|
||||||
if (is_interactive())
|
if (is_interactive())
|
||||||
rebuild_sprite_list();
|
app_realloc_sprite_list();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* adds the "sprite" in the list of sprites */
|
/* adds the "sprite" in the list of sprites */
|
||||||
@ -130,7 +130,7 @@ void sprite_mount(Sprite *sprite)
|
|||||||
get_filename(sprite->filename), sprite);
|
get_filename(sprite->filename), sprite);
|
||||||
|
|
||||||
/* rebuild the menu list of sprites */
|
/* rebuild the menu list of sprites */
|
||||||
rebuild_sprite_list();
|
app_realloc_sprite_list();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -149,7 +149,7 @@ void sprite_unmount(Sprite *sprite)
|
|||||||
tabs_remove_tab(app_get_tabs_bar(), sprite);
|
tabs_remove_tab(app_get_tabs_bar(), sprite);
|
||||||
|
|
||||||
/* rebuild the menu list of sprites */
|
/* rebuild the menu list of sprites */
|
||||||
rebuild_sprite_list();
|
app_realloc_sprite_list();
|
||||||
|
|
||||||
/* select other sprites in the editors where are this sprite */
|
/* select other sprites in the editors where are this sprite */
|
||||||
editors_hide_sprite(sprite);
|
editors_hide_sprite(sprite);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/* ASE - Allegro Sprite Editor
|
/* ASE - Allegro Sprite Editor
|
||||||
* Copyright (C) 2001-2005, 2007 David A. Capello
|
* Copyright (C) 2001-2005, 2007, 2008 David A. Capello
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -24,6 +24,7 @@
|
|||||||
|
|
||||||
#include "jinete/jbase.h"
|
#include "jinete/jbase.h"
|
||||||
#include "jinete/jlist.h"
|
#include "jinete/jlist.h"
|
||||||
|
#include "jinete/jmutex.h"
|
||||||
|
|
||||||
#include "raster/gfxobj.h"
|
#include "raster/gfxobj.h"
|
||||||
|
|
||||||
@ -35,46 +36,79 @@
|
|||||||
/* void *data; */
|
/* void *data; */
|
||||||
/* } Property; */
|
/* } Property; */
|
||||||
|
|
||||||
|
static JMutex objects_mutex;
|
||||||
static unsigned int object_id = 0; /* last object ID created */
|
static unsigned int object_id = 0; /* last object ID created */
|
||||||
static JList objects; /* graphics objects list */
|
static JList objects; /* graphics objects list */
|
||||||
|
|
||||||
GfxObj *gfxobj_new (int type, int size)
|
bool gfxobj_init(void)
|
||||||
|
{
|
||||||
|
objects_mutex = jmutex_new();
|
||||||
|
if (!objects_mutex)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
objects = jlist_new();
|
||||||
|
if (!objects)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void gfxobj_exit(void)
|
||||||
|
{
|
||||||
|
jlist_free(objects);
|
||||||
|
jmutex_free(objects_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
GfxObj *gfxobj_new(int type, int size)
|
||||||
{
|
{
|
||||||
GfxObj *gfxobj;
|
GfxObj *gfxobj;
|
||||||
|
|
||||||
gfxobj = jmalloc (size);
|
gfxobj = jmalloc(size);
|
||||||
if (!gfxobj)
|
if (!gfxobj)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
gfxobj->type = type;
|
jmutex_lock(objects_mutex);
|
||||||
gfxobj->id = ++object_id;
|
{
|
||||||
/* gfxobj->properties = NULL; */
|
gfxobj->type = type;
|
||||||
|
gfxobj->id = ++object_id;
|
||||||
if (!objects)
|
/* gfxobj->properties = NULL; */
|
||||||
objects = jlist_new();
|
jlist_append(objects, gfxobj);
|
||||||
jlist_append(objects, gfxobj);
|
}
|
||||||
|
jmutex_unlock(objects_mutex);
|
||||||
|
|
||||||
return gfxobj;
|
return gfxobj;
|
||||||
}
|
}
|
||||||
|
|
||||||
void gfxobj_free (GfxObj *gfxobj)
|
void gfxobj_free(GfxObj *gfxobj)
|
||||||
{
|
{
|
||||||
jlist_remove (objects, gfxobj);
|
jmutex_lock(objects_mutex);
|
||||||
jfree (gfxobj);
|
{
|
||||||
|
jlist_remove(objects, gfxobj);
|
||||||
|
}
|
||||||
|
jmutex_unlock(objects_mutex);
|
||||||
|
|
||||||
|
jfree(gfxobj);
|
||||||
}
|
}
|
||||||
|
|
||||||
GfxObj *gfxobj_find (unsigned int id)
|
GfxObj *gfxobj_find(unsigned int id)
|
||||||
{
|
{
|
||||||
|
GfxObj *ret = NULL;
|
||||||
JLink link;
|
JLink link;
|
||||||
|
|
||||||
|
jmutex_lock(objects_mutex);
|
||||||
|
{
|
||||||
JI_LIST_FOR_EACH(objects, link)
|
JI_LIST_FOR_EACH(objects, link)
|
||||||
if (((GfxObj *)link->data)->id == id)
|
if (((GfxObj *)link->data)->id == id) {
|
||||||
return (GfxObj *)link->data;
|
ret = (GfxObj *)link->data;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
jmutex_unlock(objects_mutex);
|
||||||
|
|
||||||
return NULL;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _gfxobj_set_id (GfxObj *gfxobj, int id)
|
void _gfxobj_set_id(GfxObj *gfxobj, int id)
|
||||||
{
|
{
|
||||||
/* TODO */
|
/* TODO */
|
||||||
/* ji_assert (!gfxobj_find (id)); */
|
/* ji_assert (!gfxobj_find (id)); */
|
||||||
@ -83,7 +117,7 @@ void _gfxobj_set_id (GfxObj *gfxobj, int id)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
void gfxobj_set_data (GfxObj *gfxobj, const char *key, void *data)
|
void gfxobj_set_data(GfxObj *gfxobj, const char *key, void *data)
|
||||||
{
|
{
|
||||||
Property *property;
|
Property *property;
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/* ASE - Allegro Sprite Editor
|
/* ASE - Allegro Sprite Editor
|
||||||
* Copyright (C) 2001-2005, 2007 David A. Capello
|
* Copyright (C) 2001-2005, 2007, 2008 David A. Capello
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -45,6 +45,9 @@ struct GfxObj
|
|||||||
/* struct GfxObjProperty *properties; */
|
/* struct GfxObjProperty *properties; */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
bool gfxobj_init(void);
|
||||||
|
void gfxobj_exit(void);
|
||||||
|
|
||||||
GfxObj *gfxobj_new(int type, int size);
|
GfxObj *gfxobj_new(int type, int size);
|
||||||
void gfxobj_free(GfxObj *gfxobj);
|
void gfxobj_free(GfxObj *gfxobj);
|
||||||
|
|
||||||
|
@ -38,10 +38,8 @@ typedef struct PAL
|
|||||||
PALETTE pal;
|
PALETTE pal;
|
||||||
} PAL;
|
} PAL;
|
||||||
|
|
||||||
static int index_count;
|
static Layer *index2layer(Layer *layer, int index, int *index_count);
|
||||||
|
static int layer2index(const Layer *layer, const Layer *find_layer, int *index_count);
|
||||||
static Layer *index2layer(Layer *layer, int index);
|
|
||||||
static int layer2index(const Layer *layer, const Layer *find_layer);
|
|
||||||
|
|
||||||
static Sprite *general_copy(const Sprite *sprite);
|
static Sprite *general_copy(const Sprite *sprite);
|
||||||
|
|
||||||
@ -316,6 +314,20 @@ void sprite_mark_as_saved(Sprite *sprite)
|
|||||||
sprite->associated_to_file = TRUE;
|
sprite->associated_to_file = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool sprite_need_alpha(Sprite *sprite)
|
||||||
|
{
|
||||||
|
switch (sprite->imgtype) {
|
||||||
|
|
||||||
|
case IMAGE_RGB:
|
||||||
|
return _rgba_geta(sprite->bgcolor) < 255;
|
||||||
|
|
||||||
|
case IMAGE_GRAYSCALE:
|
||||||
|
return _graya_geta(sprite->bgcolor) < 255;
|
||||||
|
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
bool sprite_lock(Sprite *sprite)
|
bool sprite_lock(Sprite *sprite)
|
||||||
{
|
{
|
||||||
bool res = FALSE;
|
bool res = FALSE;
|
||||||
@ -734,31 +746,31 @@ void sprite_generate_mask_boundaries(Sprite *sprite)
|
|||||||
|
|
||||||
Layer *sprite_index2layer(Sprite *sprite, int index)
|
Layer *sprite_index2layer(Sprite *sprite, int index)
|
||||||
{
|
{
|
||||||
index_count = -1;
|
int index_count = -1;
|
||||||
|
|
||||||
return index2layer(sprite->set, index);
|
return index2layer(sprite->set, index, &index_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
int sprite_layer2index(const Sprite *sprite, const Layer *layer)
|
int sprite_layer2index(const Sprite *sprite, const Layer *layer)
|
||||||
{
|
{
|
||||||
index_count = -1;
|
int index_count = -1;
|
||||||
|
|
||||||
return layer2index(sprite->set, layer);
|
return layer2index(sprite->set, layer, &index_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Layer *index2layer(Layer *layer, int index)
|
static Layer *index2layer(Layer *layer, int index, int *index_count)
|
||||||
{
|
{
|
||||||
if (index == index_count)
|
if (index == *index_count)
|
||||||
return layer;
|
return layer;
|
||||||
else {
|
else {
|
||||||
index_count++;
|
(*index_count)++;
|
||||||
|
|
||||||
if (layer_is_set (layer)) {
|
if (layer_is_set (layer)) {
|
||||||
Layer *found;
|
Layer *found;
|
||||||
JLink link;
|
JLink link;
|
||||||
|
|
||||||
JI_LIST_FOR_EACH(layer->layers, link) {
|
JI_LIST_FOR_EACH(layer->layers, link) {
|
||||||
if ((found = index2layer(link->data, index)))
|
if ((found = index2layer(link->data, index, index_count)))
|
||||||
return found;
|
return found;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -767,19 +779,19 @@ static Layer *index2layer(Layer *layer, int index)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int layer2index(const Layer *layer, const Layer *find_layer)
|
static int layer2index(const Layer *layer, const Layer *find_layer, int *index_count)
|
||||||
{
|
{
|
||||||
if (layer == find_layer)
|
if (layer == find_layer)
|
||||||
return index_count;
|
return *index_count;
|
||||||
else {
|
else {
|
||||||
index_count++;
|
(*index_count)++;
|
||||||
|
|
||||||
if (layer_is_set (layer)) {
|
if (layer_is_set(layer)) {
|
||||||
JLink link;
|
JLink link;
|
||||||
int found;
|
int found;
|
||||||
|
|
||||||
JI_LIST_FOR_EACH(layer->layers, link) {
|
JI_LIST_FOR_EACH(layer->layers, link) {
|
||||||
if ((found = layer2index(link->data, find_layer)) >= 0)
|
if ((found = layer2index(link->data, find_layer, index_count)) >= 0)
|
||||||
return found;
|
return found;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -80,6 +80,8 @@ bool sprite_is_associated_to_file(Sprite *sprite);
|
|||||||
bool sprite_is_locked(Sprite *sprite);
|
bool sprite_is_locked(Sprite *sprite);
|
||||||
void sprite_mark_as_saved(Sprite *sprite);
|
void sprite_mark_as_saved(Sprite *sprite);
|
||||||
|
|
||||||
|
bool sprite_need_alpha(Sprite *sprite);
|
||||||
|
|
||||||
bool sprite_lock(Sprite *sprite);
|
bool sprite_lock(Sprite *sprite);
|
||||||
void sprite_unlock(Sprite *sprite);
|
void sprite_unlock(Sprite *sprite);
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/* ASE - Allegro Sprite Editor
|
/* ASE - Allegro Sprite Editor
|
||||||
* Copyright (C) 2001-2005, 2007 David A. Capello
|
* Copyright (C) 2001-2005, 2007, 2008 David A. Capello
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -24,6 +24,7 @@
|
|||||||
#include "jinete/jinete.h"
|
#include "jinete/jinete.h"
|
||||||
|
|
||||||
#include "console/console.h"
|
#include "console/console.h"
|
||||||
|
#include "core/app.h"
|
||||||
#include "file/file.h"
|
#include "file/file.h"
|
||||||
#include "modules/gui.h"
|
#include "modules/gui.h"
|
||||||
#include "modules/sprites.h"
|
#include "modules/sprites.h"
|
||||||
@ -128,7 +129,7 @@ void SaveSprite(const char *filename)
|
|||||||
}
|
}
|
||||||
|
|
||||||
sprite_set_filename(current_sprite, filename);
|
sprite_set_filename(current_sprite, filename);
|
||||||
rebuild_sprite_list();
|
app_realloc_sprite_list();
|
||||||
|
|
||||||
if (sprite_save(current_sprite) == 0)
|
if (sprite_save(current_sprite) == 0)
|
||||||
sprite_mark_as_saved(current_sprite);
|
sprite_mark_as_saved(current_sprite);
|
||||||
|
@ -16,19 +16,24 @@
|
|||||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef FILE_ASE_H
|
#ifndef TEST_TEST_H
|
||||||
#define FILE_ASE_H
|
#define TEST_TEST_H
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <allegro.h>
|
||||||
|
|
||||||
struct Sprite;
|
void trace(const char *format, ...)
|
||||||
|
{
|
||||||
|
char buf[4096];
|
||||||
|
va_list ap;
|
||||||
|
|
||||||
struct Sprite *ase_file_read_f(FILE *f);
|
va_start(ap, format);
|
||||||
int ase_file_write_f(FILE *f, struct Sprite *sprite);
|
uvszprintf(buf, sizeof(buf), format, ap);
|
||||||
|
va_end(ap);
|
||||||
|
|
||||||
int fgetw(FILE *file);
|
fputs(buf, stdout);
|
||||||
long fgetl(FILE *file);
|
fflush(stdout);
|
||||||
int fputw(int w, FILE *file);
|
}
|
||||||
int fputl(long l, FILE *file);
|
|
||||||
|
|
||||||
#endif /* FILE_ASE_H */
|
#endif /* TEST_TEST_H */
|
106
src/test/test_file_system.c
Normal file
106
src/test/test_file_system.c
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
/* ASE - Allegro Sprite Editor
|
||||||
|
* Copyright (C) 2001, 2002, 2003, 2004, 2005, 2007, 2008 David A. Capello
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "test/test.h"
|
||||||
|
|
||||||
|
#include "jinete/jinete.h"
|
||||||
|
#include "core/file_system.h"
|
||||||
|
|
||||||
|
static void display_fileitem(FileItem *fi, int level, int deep)
|
||||||
|
{
|
||||||
|
JList list;
|
||||||
|
JLink link;
|
||||||
|
int c;
|
||||||
|
|
||||||
|
if (level == 0)
|
||||||
|
printf("+ ");
|
||||||
|
else
|
||||||
|
printf(" ");
|
||||||
|
|
||||||
|
for (c=0; c<level; ++c)
|
||||||
|
printf(" ");
|
||||||
|
|
||||||
|
printf("%s (%s)\n",
|
||||||
|
fileitem_get_filename(fi),
|
||||||
|
fileitem_get_displayname(fi));
|
||||||
|
fflush(stdout);
|
||||||
|
|
||||||
|
if (!fileitem_is_browsable(fi) || deep == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
list = fileitem_get_children(fi);
|
||||||
|
if (list) {
|
||||||
|
JI_LIST_FOR_EACH(list, link) {
|
||||||
|
display_fileitem(link->data, level+1, deep-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
allegro_init();
|
||||||
|
assert(file_system_init());
|
||||||
|
|
||||||
|
trace("*** Listing root of the file-system (deep = 2)...\n");
|
||||||
|
{
|
||||||
|
FileItem *root = get_root_fileitem();
|
||||||
|
assert(root != NULL);
|
||||||
|
display_fileitem(root, 0, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef ALLEGRO_WINDOWS
|
||||||
|
trace("*** Testing specific directories retrieval...\n");
|
||||||
|
{
|
||||||
|
FileItem *c_drive;
|
||||||
|
FileItem *my_pc;
|
||||||
|
|
||||||
|
trace("*** Getting 'C:\\' using 'get_fileitem_from_path'...\n");
|
||||||
|
c_drive = get_fileitem_from_path("C:\\");
|
||||||
|
assert(c_drive != NULL);
|
||||||
|
|
||||||
|
trace("*** Displaying 'C:\\'...\n");
|
||||||
|
display_fileitem(c_drive, 0, 0);
|
||||||
|
|
||||||
|
trace("*** Getting 'My PC' (using 'fileitem_get_parent')...\n");
|
||||||
|
my_pc = fileitem_get_parent(c_drive);
|
||||||
|
assert(my_pc != NULL);
|
||||||
|
|
||||||
|
trace("*** Listing 'My PC'...\n");
|
||||||
|
display_fileitem(my_pc, 0, 1);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
trace("*** Testing 'filename_has_extension'...\n");
|
||||||
|
{
|
||||||
|
assert(filename_has_extension("hi.png", "png"));
|
||||||
|
assert(!filename_has_extension("hi.png", "pngg"));
|
||||||
|
assert(!filename_has_extension("hi.png", "ppng"));
|
||||||
|
assert(filename_has_extension("hi.jpeg", "jpg,jpeg"));
|
||||||
|
assert(filename_has_extension("hi.jpg", "jpg,jpeg"));
|
||||||
|
assert(!filename_has_extension("hi.ase", "jpg,jpeg"));
|
||||||
|
assert(filename_has_extension("hi.ase", "jpg,jpeg,ase"));
|
||||||
|
assert(filename_has_extension("hi.ase", "ase,jpg,jpeg"));
|
||||||
|
trace("+ All OK.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
file_system_exit();
|
||||||
|
allegro_exit();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
END_OF_MAIN();
|
@ -1,5 +1,5 @@
|
|||||||
/* ASE - Allegro Sprite Editor
|
/* ASE - Allegro Sprite Editor
|
||||||
* Copyright (C) 2001-2005, 2007 David A. Capello
|
* Copyright (C) 2001-2005, 2007, 2008 David A. Capello
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -19,23 +19,25 @@
|
|||||||
#ifndef UTIL_HASH_H
|
#ifndef UTIL_HASH_H
|
||||||
#define UTIL_HASH_H
|
#define UTIL_HASH_H
|
||||||
|
|
||||||
typedef struct HashBucket {
|
typedef struct HashBucket
|
||||||
|
{
|
||||||
char *key;
|
char *key;
|
||||||
void *data;
|
void *data;
|
||||||
struct HashBucket *next;
|
struct HashBucket *next;
|
||||||
} HashBucket;
|
} HashBucket;
|
||||||
|
|
||||||
typedef struct HashTable {
|
typedef struct HashTable
|
||||||
|
{
|
||||||
int size;
|
int size;
|
||||||
HashBucket **table;
|
HashBucket **table;
|
||||||
} HashTable;
|
} HashTable;
|
||||||
|
|
||||||
HashTable *hash_new (int size);
|
HashTable *hash_new(int size);
|
||||||
void hash_free (HashTable *table, void (*func) (void *));
|
void hash_free(HashTable *table, void (*func)(void *));
|
||||||
|
|
||||||
void *hash_insert (HashTable *table, const char *key, void *data);
|
void *hash_insert(HashTable *table, const char *key, void *data);
|
||||||
void *hash_lookup (HashTable *table, const char *key);
|
void *hash_lookup(HashTable *table, const char *key);
|
||||||
void *hash_remove (HashTable *table, const char *key);
|
void *hash_remove(HashTable *table, const char *key);
|
||||||
void hash_enumerate (HashTable *table, void (*callback) (const char *, void *));
|
void hash_enumerate(HashTable *table, void (*callback)(const char *, void *));
|
||||||
|
|
||||||
#endif /* UTIL_HASH_H */
|
#endif /* UTIL_HASH_H */
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/* ASE - Allegro Sprite Editor
|
/* ASE - Allegro Sprite Editor
|
||||||
* Copyright (C) 2001-2005, 2007 David A. Capello
|
* Copyright (C) 2001-2005, 2007, 2008 David A. Capello
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -29,8 +29,9 @@
|
|||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include "console/console.h"
|
#include "core/app.h"
|
||||||
#include "raster/image.h"
|
#include "raster/image.h"
|
||||||
|
#include "widgets/statebar.h"
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -40,6 +41,7 @@ static float FRandom (float amount);
|
|||||||
|
|
||||||
void mapgen (Image *image, int seed, float fractal_factor)
|
void mapgen (Image *image, int seed, float fractal_factor)
|
||||||
{
|
{
|
||||||
|
Progress *progress = NULL;
|
||||||
float **map;
|
float **map;
|
||||||
float amount = 128;
|
float amount = 128;
|
||||||
float min, max;
|
float min, max;
|
||||||
@ -51,9 +53,9 @@ void mapgen (Image *image, int seed, float fractal_factor)
|
|||||||
/**********************************************************************/
|
/**********************************************************************/
|
||||||
/* create the map */
|
/* create the map */
|
||||||
|
|
||||||
map = malloc (sizeof (float *) * size);
|
map = malloc (sizeof(float *) * size);
|
||||||
for (i = 0; i < size; i++)
|
for (i = 0; i < size; i++)
|
||||||
map[i] = malloc (sizeof (float) * size);
|
map[i] = malloc(sizeof(float) * size);
|
||||||
|
|
||||||
/* Do the corners */
|
/* Do the corners */
|
||||||
map[0][0] = 0; /* map[0][0] = FRandom(amount); */
|
map[0][0] = 0; /* map[0][0] = FRandom(amount); */
|
||||||
@ -62,7 +64,9 @@ void mapgen (Image *image, int seed, float fractal_factor)
|
|||||||
map[0][size-1] = map[0][0];
|
map[0][size-1] = map[0][0];
|
||||||
amount /= fractal_factor;
|
amount /= fractal_factor;
|
||||||
|
|
||||||
add_progress (128);
|
if (app_get_status_bar())
|
||||||
|
progress = progress_new(app_get_status_bar());
|
||||||
|
|
||||||
for (i=128; i>0; i/=2) {
|
for (i=128; i>0; i/=2) {
|
||||||
/* This is the square phase */
|
/* This is the square phase */
|
||||||
for (j=i; j<size; j+=2*i)
|
for (j=i; j<size; j+=2*i)
|
||||||
@ -92,9 +96,12 @@ void mapgen (Image *image, int seed, float fractal_factor)
|
|||||||
|
|
||||||
amount /= fractal_factor;
|
amount /= fractal_factor;
|
||||||
|
|
||||||
do_progress (100 * (128-i) / 128);
|
if (progress)
|
||||||
|
progress_update(progress, (128.0f-i) / 128.0f);
|
||||||
}
|
}
|
||||||
del_progress ();
|
|
||||||
|
if (progress)
|
||||||
|
progress_free(progress);
|
||||||
|
|
||||||
/**********************************************************************/
|
/**********************************************************************/
|
||||||
/* Copy the map to the image */
|
/* Copy the map to the image */
|
||||||
@ -112,12 +119,12 @@ void mapgen (Image *image, int seed, float fractal_factor)
|
|||||||
k = (int)((map[i][j] - min)/(max - min) * 256);
|
k = (int)((map[i][j] - min)/(max - min) * 256);
|
||||||
if (k > 255)
|
if (k > 255)
|
||||||
k = 255;
|
k = 255;
|
||||||
image_putpixel (image, i, j, k);
|
image_putpixel(image, i, j, k);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i=0; i<size; i++)
|
for (i=0; i<size; i++)
|
||||||
jfree (map[i]);
|
jfree(map[i]);
|
||||||
jfree (map);
|
jfree(map);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Handles wrapping when seeking neighbours */
|
/* Handles wrapping when seeking neighbours */
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/* ASE - Allegro Sprite Editor
|
/* ASE - Allegro Sprite Editor
|
||||||
* Copyright (C) 2001-2005, 2007 David A. Capello
|
* Copyright (C) 2001-2005, 2007, 2008 David A. Capello
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -304,10 +304,10 @@ int quantize_bitmaps1 (Stock *stock, RGB *pal, int *bmp_i, int fill_other)
|
|||||||
/*Create the tree structure*/
|
/*Create the tree structure*/
|
||||||
tree=create_node(0,0,0,64,64,64,0);
|
tree=create_node(0,0,0,64,64,64,0);
|
||||||
/*Scan the bitmaps*/
|
/*Scan the bitmaps*/
|
||||||
add_progress(stock->nimage+1);
|
/* add_progress(stock->nimage+1); */
|
||||||
for (c_bmp=0;c_bmp<stock->nimage;c_bmp++) {
|
for (c_bmp=0;c_bmp<stock->nimage;c_bmp++) {
|
||||||
if (stock->image[c_bmp]) {
|
if (stock->image[c_bmp]) {
|
||||||
add_progress(stock->image[c_bmp]->h);
|
/* add_progress(stock->image[c_bmp]->h); */
|
||||||
for (y=0;y<stock->image[c_bmp]->h;y++) {
|
for (y=0;y<stock->image[c_bmp]->h;y++) {
|
||||||
for (x=0;x<stock->image[c_bmp]->w;x++) {
|
for (x=0;x<stock->image[c_bmp]->w;x++) {
|
||||||
c=stock->image[c_bmp]->method->getpixel(stock->image[c_bmp],x,y);
|
c=stock->image[c_bmp]->method->getpixel(stock->image[c_bmp],x,y);
|
||||||
@ -327,11 +327,11 @@ int quantize_bitmaps1 (Stock *stock, RGB *pal, int *bmp_i, int fill_other)
|
|||||||
node=node->parent;
|
node=node->parent;
|
||||||
} while (node);
|
} while (node);
|
||||||
}
|
}
|
||||||
do_progress(y);
|
/* do_progress(y); */
|
||||||
}
|
}
|
||||||
del_progress();
|
/* del_progress(); */
|
||||||
}
|
}
|
||||||
do_progress(c_bmp);
|
/* do_progress(c_bmp); */
|
||||||
}
|
}
|
||||||
/*Collapse empty nodes in the tree, and count leaves*/
|
/*Collapse empty nodes in the tree, and count leaves*/
|
||||||
tree=collapse_empty(tree,&n_colours);
|
tree=collapse_empty(tree,&n_colours);
|
||||||
@ -341,19 +341,19 @@ int quantize_bitmaps1 (Stock *stock, RGB *pal, int *bmp_i, int fill_other)
|
|||||||
}
|
}
|
||||||
/*Collapse nodes until there are few enough to fit in the palette*/
|
/*Collapse nodes until there are few enough to fit in the palette*/
|
||||||
if (n_colours > n_entries) {
|
if (n_colours > n_entries) {
|
||||||
int n_colours1 = n_colours;
|
/* int n_colours1 = n_colours; */
|
||||||
add_progress(n_colours1 - n_entries);
|
/* add_progress(n_colours1 - n_entries); */
|
||||||
while (n_colours>n_entries) {
|
while (n_colours>n_entries) {
|
||||||
Ep=0xFFFFFFFFul;
|
Ep=0xFFFFFFFFul;
|
||||||
minimum_Ep(tree,&Ep);
|
minimum_Ep(tree,&Ep);
|
||||||
tree=collapse_nodes(tree,&n_colours,n_entries,Ep);
|
tree=collapse_nodes(tree,&n_colours,n_entries,Ep);
|
||||||
|
|
||||||
if (n_colours > n_entries)
|
/* if (n_colours > n_entries) */
|
||||||
do_progress(n_colours1 - n_colours);
|
/* do_progress(n_colours1 - n_colours); */
|
||||||
}
|
}
|
||||||
del_progress();
|
/* del_progress(); */
|
||||||
}
|
}
|
||||||
del_progress();
|
/* del_progress(); */
|
||||||
/*Fill palette*/
|
/*Fill palette*/
|
||||||
c=0;
|
c=0;
|
||||||
fill_palette(tree,&c,pal,1);
|
fill_palette(tree,&c,pal,1);
|
||||||
|
@ -1068,8 +1068,7 @@ static bool editor_msg_proc(JWidget widget, JMessage msg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
case JM_TIMER:
|
case JM_TIMER:
|
||||||
if (msg->timer.timer_id == editor->mask_timer_id &&
|
if (msg->timer.timer_id == editor->mask_timer_id) {
|
||||||
msg->timer.count == 0) {
|
|
||||||
if (editor->sprite) {
|
if (editor->sprite) {
|
||||||
editor_draw_mask_safe(widget);
|
editor_draw_mask_safe(widget);
|
||||||
|
|
||||||
|
489
src/widgets/fileview.c
Normal file
489
src/widgets/fileview.c
Normal file
@ -0,0 +1,489 @@
|
|||||||
|
/* ASE - Allegro Sprite Editor
|
||||||
|
* Copyright (C) 2008 David A. Capello
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#ifndef USE_PRECOMPILED_HEADER
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <allegro.h>
|
||||||
|
|
||||||
|
#include "jinete/jinete.h"
|
||||||
|
|
||||||
|
#include "modules/gfx.h"
|
||||||
|
#include "widgets/fileview.h"
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct FileView
|
||||||
|
{
|
||||||
|
FileItem *current_folder;
|
||||||
|
JList list;
|
||||||
|
bool req_valid;
|
||||||
|
int req_w, req_h;
|
||||||
|
FileItem *selected;
|
||||||
|
const char *exts;
|
||||||
|
} FileView;
|
||||||
|
|
||||||
|
static FileView *fileview_data(JWidget widget);
|
||||||
|
static bool fileview_msg_proc(JWidget widget, JMessage msg);
|
||||||
|
static void fileview_get_fileitem_size(JWidget widget, FileItem *fi, int *w, int *h);
|
||||||
|
static void fileview_make_selected_fileitem_visible(JWidget widget);
|
||||||
|
static void fileview_regenerate_list(JWidget widget);
|
||||||
|
static int fileview_get_selected_index(JWidget widget);
|
||||||
|
static void fileview_select_index(JWidget widget, int index);
|
||||||
|
|
||||||
|
JWidget fileview_new(FileItem *start_folder, const char *exts)
|
||||||
|
{
|
||||||
|
JWidget widget = jwidget_new(fileview_type());
|
||||||
|
FileView *fileview = jnew(FileView, 1);
|
||||||
|
|
||||||
|
if (!start_folder)
|
||||||
|
start_folder = get_root_fileitem();
|
||||||
|
else {
|
||||||
|
while (!fileitem_is_folder(start_folder) &&
|
||||||
|
fileitem_get_parent(start_folder) != NULL) {
|
||||||
|
start_folder = fileitem_get_parent(start_folder);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
jwidget_add_hook(widget, fileview_type(),
|
||||||
|
fileview_msg_proc, fileview);
|
||||||
|
jwidget_focusrest(widget, TRUE);
|
||||||
|
|
||||||
|
fileview->current_folder = start_folder;
|
||||||
|
fileview->list = NULL;
|
||||||
|
fileview->req_valid = FALSE;
|
||||||
|
fileview->selected = NULL;
|
||||||
|
fileview->exts = exts;
|
||||||
|
|
||||||
|
fileview_regenerate_list(widget);
|
||||||
|
|
||||||
|
return widget;
|
||||||
|
}
|
||||||
|
|
||||||
|
int fileview_type(void)
|
||||||
|
{
|
||||||
|
static int type = 0;
|
||||||
|
if (!type)
|
||||||
|
type = ji_register_widget_type();
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
FileItem *fileview_get_current_folder(JWidget widget)
|
||||||
|
{
|
||||||
|
return fileview_data(widget)->current_folder;
|
||||||
|
}
|
||||||
|
|
||||||
|
FileItem *fileview_get_selected(JWidget widget)
|
||||||
|
{
|
||||||
|
return fileview_data(widget)->selected;
|
||||||
|
}
|
||||||
|
|
||||||
|
void fileview_set_current_folder(JWidget widget, FileItem *folder)
|
||||||
|
{
|
||||||
|
FileView *fileview = fileview_data(widget);
|
||||||
|
|
||||||
|
assert(folder != NULL);
|
||||||
|
assert(fileitem_is_browsable(folder));
|
||||||
|
|
||||||
|
fileview->current_folder = folder;
|
||||||
|
fileview->req_valid = FALSE;
|
||||||
|
fileview->selected = NULL;
|
||||||
|
|
||||||
|
fileview_regenerate_list(widget);
|
||||||
|
|
||||||
|
/* select first folder */
|
||||||
|
if (!jlist_empty(fileview->list) &&
|
||||||
|
fileitem_is_browsable(jlist_first_data(fileview->list))) {
|
||||||
|
fileview_select_index(widget, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
jwidget_emit_signal(widget, SIGNAL_FILEVIEW_CURRENT_FOLDER_CHANGED);
|
||||||
|
|
||||||
|
jwidget_dirty(widget);
|
||||||
|
jview_update(jwidget_get_view(widget));
|
||||||
|
}
|
||||||
|
|
||||||
|
void fileview_goup(JWidget widget)
|
||||||
|
{
|
||||||
|
FileView *fileview = fileview_data(widget);
|
||||||
|
FileItem *folder = fileview->current_folder;
|
||||||
|
FileItem *parent = fileitem_get_parent(folder);
|
||||||
|
if (parent) {
|
||||||
|
fileview_set_current_folder(widget, parent);
|
||||||
|
fileview->selected = folder;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static FileView *fileview_data(JWidget widget)
|
||||||
|
{
|
||||||
|
return jwidget_get_data(widget, fileview_type());
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool fileview_msg_proc(JWidget widget, JMessage msg)
|
||||||
|
{
|
||||||
|
FileView *fileview = fileview_data(widget);
|
||||||
|
|
||||||
|
switch (msg->type) {
|
||||||
|
|
||||||
|
case JM_DESTROY:
|
||||||
|
jfree(fileview);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case JM_REQSIZE:
|
||||||
|
if (!fileview->req_valid) {
|
||||||
|
FileItem *fileitem;
|
||||||
|
int w, h, iw, ih;
|
||||||
|
JLink link;
|
||||||
|
|
||||||
|
w = 0;
|
||||||
|
h = 0;
|
||||||
|
|
||||||
|
/* rows */
|
||||||
|
JI_LIST_FOR_EACH(fileview->list, link) {
|
||||||
|
fileitem = link->data;
|
||||||
|
fileview_get_fileitem_size(widget, fileitem, &iw, &ih);
|
||||||
|
w = MAX(w, iw);
|
||||||
|
h += ih;
|
||||||
|
}
|
||||||
|
|
||||||
|
fileview->req_valid = TRUE;
|
||||||
|
fileview->req_w = w;
|
||||||
|
fileview->req_h = h;
|
||||||
|
}
|
||||||
|
|
||||||
|
msg->reqsize.w = fileview->req_w;
|
||||||
|
msg->reqsize.h = fileview->req_h;
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
case JM_DRAW: {
|
||||||
|
FileItem *fi;
|
||||||
|
JLink link;
|
||||||
|
int iw, ih;
|
||||||
|
int th = jwidget_get_text_height(widget);
|
||||||
|
int x, y = widget->rc->y1;
|
||||||
|
int row = 0;
|
||||||
|
int bgcolor;
|
||||||
|
int fgcolor;
|
||||||
|
|
||||||
|
jdraw_rectfill(widget->rc, makecol(255, 255, 255));
|
||||||
|
|
||||||
|
/* rows */
|
||||||
|
JI_LIST_FOR_EACH(fileview->list, link) {
|
||||||
|
fi = link->data;
|
||||||
|
fileview_get_fileitem_size(widget, fi, &iw, &ih);
|
||||||
|
|
||||||
|
if (fi == fileview->selected) {
|
||||||
|
bgcolor = ji_color_selected();
|
||||||
|
fgcolor = ji_color_background();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
bgcolor = row ? makecol(240, 240, 240):
|
||||||
|
makecol(255, 255, 255);
|
||||||
|
|
||||||
|
fgcolor =
|
||||||
|
fileitem_is_folder(fi) &&
|
||||||
|
!fileitem_is_browsable(fi) ? makecol(255, 200, 200):
|
||||||
|
ji_color_foreground();
|
||||||
|
}
|
||||||
|
|
||||||
|
rectfill(ji_screen,
|
||||||
|
widget->rc->x1, y,
|
||||||
|
widget->rc->x2-1, y+2+th+2-1,
|
||||||
|
bgcolor);
|
||||||
|
|
||||||
|
x = widget->rc->x1+2;
|
||||||
|
|
||||||
|
if (fileitem_is_folder(fi)) {
|
||||||
|
jdraw_text(widget->text_font,
|
||||||
|
"[+]", x, y+2,
|
||||||
|
fgcolor, 0, FALSE);
|
||||||
|
|
||||||
|
x += ji_font_text_len(widget->text_font, "[+]")+2;
|
||||||
|
}
|
||||||
|
|
||||||
|
jdraw_text(widget->text_font,
|
||||||
|
fileitem_get_displayname(fi), x, y+2,
|
||||||
|
fgcolor, 0, FALSE);
|
||||||
|
|
||||||
|
y += ih;
|
||||||
|
row ^= 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case JM_BUTTONPRESSED:
|
||||||
|
jwidget_capture_mouse(widget);
|
||||||
|
|
||||||
|
case JM_MOTION:
|
||||||
|
if (jwidget_has_capture(widget)) {
|
||||||
|
FileItem *fi;
|
||||||
|
JLink link;
|
||||||
|
int iw, ih;
|
||||||
|
int th = jwidget_get_text_height(widget);
|
||||||
|
int y = widget->rc->y1;
|
||||||
|
FileItem *old_selected = fileview->selected;
|
||||||
|
fileview->selected = NULL;
|
||||||
|
|
||||||
|
/* rows */
|
||||||
|
JI_LIST_FOR_EACH(fileview->list, link) {
|
||||||
|
fi = link->data;
|
||||||
|
fileview_get_fileitem_size(widget, fi, &iw, &ih);
|
||||||
|
|
||||||
|
if (((msg->mouse.y >= y) && (msg->mouse.y < y+2+th+2)) ||
|
||||||
|
(link == jlist_first(fileview->list) && msg->mouse.y < y) ||
|
||||||
|
(link == jlist_last(fileview->list) && msg->mouse.y >= y+2+th+2)) {
|
||||||
|
fileview->selected = fi;
|
||||||
|
fileview_make_selected_fileitem_visible(widget);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
y += ih;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (old_selected != fileview->selected) {
|
||||||
|
jwidget_dirty(widget);
|
||||||
|
jwidget_emit_signal(widget, SIGNAL_FILEVIEW_FILE_SELECTED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case JM_BUTTONRELEASED:
|
||||||
|
if (jwidget_has_capture(widget)) {
|
||||||
|
jwidget_release_mouse(widget);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case JM_CHAR:
|
||||||
|
if (jwidget_has_focus(widget)) {
|
||||||
|
int select = fileview_get_selected_index(widget);
|
||||||
|
JWidget view = jwidget_get_view(widget);
|
||||||
|
int bottom = MAX(0, jlist_length(fileview->list)-1);
|
||||||
|
|
||||||
|
switch (msg->key.scancode) {
|
||||||
|
case KEY_UP:
|
||||||
|
if (select >= 0)
|
||||||
|
select--;
|
||||||
|
else
|
||||||
|
select = 0;
|
||||||
|
break;
|
||||||
|
case KEY_DOWN:
|
||||||
|
if (select >= 0)
|
||||||
|
select++;
|
||||||
|
else
|
||||||
|
select = 0;
|
||||||
|
break;
|
||||||
|
case KEY_HOME:
|
||||||
|
select = 0;
|
||||||
|
break;
|
||||||
|
case KEY_END:
|
||||||
|
select = bottom;
|
||||||
|
break;
|
||||||
|
case KEY_PGUP:
|
||||||
|
case KEY_PGDN: {
|
||||||
|
int sgn = (msg->key.scancode == KEY_PGUP) ? -1: 1;
|
||||||
|
JRect vp = jview_get_viewport_position(view);
|
||||||
|
if (select < 0)
|
||||||
|
select = 0;
|
||||||
|
select += sgn * jrect_h(vp) / (2+jwidget_get_text_height(widget)+2);
|
||||||
|
jrect_free(vp);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case KEY_LEFT:
|
||||||
|
case KEY_RIGHT:
|
||||||
|
if (select >= 0) {
|
||||||
|
JRect vp = jview_get_viewport_position(view);
|
||||||
|
int sgn = (msg->key.scancode == KEY_LEFT) ? -1: 1;
|
||||||
|
int scroll_x, scroll_y;
|
||||||
|
|
||||||
|
jview_get_scroll(view, &scroll_x, &scroll_y);
|
||||||
|
jview_set_scroll(view, scroll_x + jrect_w(vp)/2*sgn, scroll_y);
|
||||||
|
jrect_free(vp);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case KEY_ENTER:
|
||||||
|
if (fileview->selected) {
|
||||||
|
if (fileitem_is_browsable(fileview->selected)) {
|
||||||
|
fileview_set_current_folder(widget, fileview->selected);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
jwidget_emit_signal(widget, SIGNAL_FILEVIEW_FILE_ACCEPT);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return FALSE;
|
||||||
|
case KEY_BACKSPACE:
|
||||||
|
fileview_goup(widget);
|
||||||
|
return TRUE;
|
||||||
|
default:
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
fileview_select_index(widget, MID(0, select, bottom));
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case JM_WHEEL: {
|
||||||
|
JWidget view = jwidget_get_view(widget);
|
||||||
|
if (view) {
|
||||||
|
int scroll_x, scroll_y;
|
||||||
|
|
||||||
|
jview_get_scroll(view, &scroll_x, &scroll_y);
|
||||||
|
jview_set_scroll(view,
|
||||||
|
scroll_x,
|
||||||
|
scroll_y +
|
||||||
|
(jmouse_z(1) - jmouse_z(0))
|
||||||
|
*(2+jwidget_get_text_height(widget)+2)*3);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case JM_DOUBLECLICK:
|
||||||
|
if (fileview->selected) {
|
||||||
|
if (fileitem_is_browsable(fileview->selected)) {
|
||||||
|
fileview_set_current_folder(widget, fileview->selected);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
jwidget_emit_signal(widget, SIGNAL_FILEVIEW_FILE_ACCEPT);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void fileview_get_fileitem_size(JWidget widget, FileItem *fi, int *w, int *h)
|
||||||
|
{
|
||||||
|
/* char buf[512]; */
|
||||||
|
int len = 0;
|
||||||
|
|
||||||
|
if (fileitem_is_folder(fi)) {
|
||||||
|
len += ji_font_text_len(widget->text_font, "[+]")+2;
|
||||||
|
}
|
||||||
|
|
||||||
|
len += ji_font_text_len(widget->text_font,
|
||||||
|
fileitem_get_displayname(fi));
|
||||||
|
|
||||||
|
/* if (!fileitem_is_folder(fi)) { */
|
||||||
|
/* len += 2+ji_font_text_len(widget->text_font, buf); */
|
||||||
|
/* } */
|
||||||
|
|
||||||
|
*w = 2+len+2;
|
||||||
|
*h = 2+jwidget_get_text_height(widget)+2;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void fileview_make_selected_fileitem_visible(JWidget widget)
|
||||||
|
{
|
||||||
|
FileView *fileview = fileview_data(widget);
|
||||||
|
JWidget view = jwidget_get_view(widget);
|
||||||
|
JRect vp = jview_get_viewport_position(view);
|
||||||
|
FileItem *fi;
|
||||||
|
JLink link;
|
||||||
|
int iw, ih;
|
||||||
|
int th = jwidget_get_text_height(widget);
|
||||||
|
int y = widget->rc->y1;
|
||||||
|
int scroll_x, scroll_y;
|
||||||
|
|
||||||
|
jview_get_scroll(view, &scroll_x, &scroll_y);
|
||||||
|
|
||||||
|
/* rows */
|
||||||
|
JI_LIST_FOR_EACH(fileview->list, link) {
|
||||||
|
fi = link->data;
|
||||||
|
fileview_get_fileitem_size(widget, fi, &iw, &ih);
|
||||||
|
|
||||||
|
if (fi == fileview->selected) {
|
||||||
|
if (y < vp->y1)
|
||||||
|
jview_set_scroll(view, scroll_x, y - widget->rc->y1);
|
||||||
|
else if (y > vp->y2 - (2+th+2))
|
||||||
|
jview_set_scroll(view, scroll_x,
|
||||||
|
y - widget->rc->y1 - jrect_h(vp) + (2+th+2));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
y += ih;
|
||||||
|
}
|
||||||
|
|
||||||
|
jrect_free(vp);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void fileview_regenerate_list(JWidget widget)
|
||||||
|
{
|
||||||
|
FileView *fileview = fileview_data(widget);
|
||||||
|
FileItem *fileitem;
|
||||||
|
JLink link, next;
|
||||||
|
JList children;
|
||||||
|
|
||||||
|
if (fileview->list)
|
||||||
|
jlist_free(fileview->list);
|
||||||
|
|
||||||
|
/* get the list of children */
|
||||||
|
children = fileitem_get_children(fileview->current_folder);
|
||||||
|
if (children) {
|
||||||
|
fileview->list = jlist_copy(children);
|
||||||
|
|
||||||
|
/* filter the list */
|
||||||
|
if (fileview->exts) {
|
||||||
|
JI_LIST_FOR_EACH_SAFE(fileview->list, link, next) {
|
||||||
|
fileitem = link->data;
|
||||||
|
if (!fileitem_is_folder(fileitem) &&
|
||||||
|
!fileitem_has_extension(fileitem, fileview->exts)) {
|
||||||
|
jlist_delete_link(fileview->list, link);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
fileview->list = jlist_new();
|
||||||
|
}
|
||||||
|
|
||||||
|
static int fileview_get_selected_index(JWidget widget)
|
||||||
|
{
|
||||||
|
FileView *fileview = fileview_data(widget);
|
||||||
|
JLink link;
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
JI_LIST_FOR_EACH(fileview->list, link) {
|
||||||
|
if (link->data == fileview->selected)
|
||||||
|
return i;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void fileview_select_index(JWidget widget, int index)
|
||||||
|
{
|
||||||
|
FileView *fileview = fileview_data(widget);
|
||||||
|
FileItem *old_selected = fileview->selected;
|
||||||
|
|
||||||
|
fileview->selected = jlist_nth_data(fileview->list, index);
|
||||||
|
if (old_selected != fileview->selected) {
|
||||||
|
fileview_make_selected_fileitem_visible(widget);
|
||||||
|
|
||||||
|
jwidget_dirty(widget);
|
||||||
|
jwidget_emit_signal(widget, SIGNAL_FILEVIEW_FILE_SELECTED);
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,5 @@
|
|||||||
/* ASE - Allegro Sprite Editor
|
/* ASE - Allegro Sprite Editor
|
||||||
* Copyright (C) 2001-2005, 2007 David A. Capello
|
* Copyright (C) 2008 David A. Capello
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -16,26 +16,25 @@
|
|||||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
extern FileType filetype_ase;
|
#ifndef WIDGETS_FILEVIEW_H
|
||||||
extern FileType filetype_bmp;
|
#define WIDGETS_FILEVIEW_H
|
||||||
extern FileType filetype_fli;
|
|
||||||
extern FileType filetype_jpeg;
|
|
||||||
extern FileType filetype_pcx;
|
|
||||||
extern FileType filetype_tga;
|
|
||||||
extern FileType filetype_gif;
|
|
||||||
extern FileType filetype_ico;
|
|
||||||
extern FileType filetype_png;
|
|
||||||
|
|
||||||
static FileType *filetypes[] =
|
#include "jinete/jbase.h"
|
||||||
{
|
|
||||||
&filetype_ase,
|
#include "core/file_system.h"
|
||||||
&filetype_bmp,
|
|
||||||
&filetype_fli,
|
/* TODO use some JI_SIGNAL_USER */
|
||||||
&filetype_jpeg,
|
#define SIGNAL_FILEVIEW_FILE_SELECTED 0x10006
|
||||||
&filetype_pcx,
|
#define SIGNAL_FILEVIEW_FILE_ACCEPT 0x10007
|
||||||
&filetype_tga,
|
#define SIGNAL_FILEVIEW_CURRENT_FOLDER_CHANGED 0x10008
|
||||||
&filetype_gif,
|
|
||||||
&filetype_ico,
|
JWidget fileview_new(FileItem *start_folder, const char *exts);
|
||||||
&filetype_png,
|
int fileview_type(void);
|
||||||
NULL
|
|
||||||
};
|
FileItem *fileview_get_current_folder(JWidget fileview);
|
||||||
|
FileItem *fileview_get_selected(JWidget fileview);
|
||||||
|
void fileview_set_current_folder(JWidget widget, FileItem *folder);
|
||||||
|
|
||||||
|
void fileview_goup(JWidget fileview);
|
||||||
|
|
||||||
|
#endif /* WIDGETS_FILEVIEW_H */
|
@ -60,8 +60,6 @@ static void button_command(JWidget widget, void *data);
|
|||||||
|
|
||||||
static void update_from_layer(StatusBar *status_bar);
|
static void update_from_layer(StatusBar *status_bar);
|
||||||
|
|
||||||
static void play_animation(void);
|
|
||||||
|
|
||||||
JWidget status_bar_new(void)
|
JWidget status_bar_new(void)
|
||||||
{
|
{
|
||||||
#define BUTTON_NEW(name, text, data) \
|
#define BUTTON_NEW(name, text, data) \
|
||||||
@ -85,7 +83,7 @@ JWidget status_bar_new(void)
|
|||||||
|
|
||||||
status_bar->widget = widget;
|
status_bar->widget = widget;
|
||||||
status_bar->timeout = 0;
|
status_bar->timeout = 0;
|
||||||
status_bar->nprogress = 0;
|
status_bar->progress = jlist_new();
|
||||||
|
|
||||||
/* construct the commands box */
|
/* construct the commands box */
|
||||||
box1 = jbox_new(JI_HORIZONTAL);
|
box1 = jbox_new(JI_HORIZONTAL);
|
||||||
@ -154,55 +152,6 @@ void status_bar_set_text(JWidget widget, int msecs, const char *format, ...)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void status_bar_do_progress(JWidget widget, int progress)
|
|
||||||
{
|
|
||||||
StatusBar *status_bar = status_bar_data(widget);
|
|
||||||
int n = status_bar->nprogress-1;
|
|
||||||
|
|
||||||
if (n >= 0) {
|
|
||||||
progress = MID(0, progress, status_bar->progress[n].max);
|
|
||||||
|
|
||||||
if (status_bar->progress[n].pos != progress) {
|
|
||||||
status_bar->progress[n].pos = progress;
|
|
||||||
jwidget_dirty(widget);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void status_bar_add_progress(JWidget widget, int max)
|
|
||||||
{
|
|
||||||
StatusBar *status_bar = status_bar_data(widget);
|
|
||||||
int n = status_bar->nprogress++;
|
|
||||||
|
|
||||||
status_bar->progress[n].max = max;
|
|
||||||
status_bar->progress[n].pos = 0;
|
|
||||||
|
|
||||||
ji_dirty_region = jregion_new(NULL, 0);
|
|
||||||
|
|
||||||
jwidget_dirty(widget);
|
|
||||||
}
|
|
||||||
|
|
||||||
void status_bar_del_progress(JWidget widget)
|
|
||||||
{
|
|
||||||
StatusBar *status_bar = status_bar_data(widget);
|
|
||||||
|
|
||||||
jwidget_dirty(widget);
|
|
||||||
|
|
||||||
/* to show 100% progress-bar */
|
|
||||||
if (status_bar->nprogress == 1) {
|
|
||||||
status_bar->progress[0].pos = status_bar->progress[0].max;
|
|
||||||
jwidget_flush_redraw(widget);
|
|
||||||
jmanager_dispatch_messages(ji_get_default_manager());
|
|
||||||
rest(5);
|
|
||||||
jwidget_dirty(widget);
|
|
||||||
|
|
||||||
jregion_free(ji_dirty_region);
|
|
||||||
ji_dirty_region = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
status_bar->nprogress--;
|
|
||||||
}
|
|
||||||
|
|
||||||
void status_bar_update(JWidget widget)
|
void status_bar_update(JWidget widget)
|
||||||
{
|
{
|
||||||
StatusBar *status_bar = status_bar_data(widget);
|
StatusBar *status_bar = status_bar_data(widget);
|
||||||
@ -210,15 +159,56 @@ void status_bar_update(JWidget widget)
|
|||||||
update_from_layer(status_bar);
|
update_from_layer(status_bar);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Progress *progress_new(JWidget status_bar)
|
||||||
|
{
|
||||||
|
Progress *progress = jnew(Progress, 1);
|
||||||
|
if (!progress)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
progress->status_bar = status_bar;
|
||||||
|
progress->pos = 0.0f;
|
||||||
|
|
||||||
|
jlist_append(status_bar_data(status_bar)->progress,
|
||||||
|
progress);
|
||||||
|
jwidget_dirty(status_bar);
|
||||||
|
|
||||||
|
return progress;
|
||||||
|
}
|
||||||
|
|
||||||
|
void progress_free(Progress *progress)
|
||||||
|
{
|
||||||
|
jlist_remove(status_bar_data(progress->status_bar)->progress,
|
||||||
|
progress);
|
||||||
|
jwidget_dirty(progress->status_bar);
|
||||||
|
|
||||||
|
jfree(progress);
|
||||||
|
}
|
||||||
|
|
||||||
|
void progress_update(Progress *progress, float progress_pos)
|
||||||
|
{
|
||||||
|
if (progress->pos != progress_pos) {
|
||||||
|
progress->pos = progress_pos;
|
||||||
|
jwidget_dirty(progress->status_bar);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static bool status_bar_msg_proc(JWidget widget, JMessage msg)
|
static bool status_bar_msg_proc(JWidget widget, JMessage msg)
|
||||||
{
|
{
|
||||||
StatusBar *status_bar = status_bar_data(widget);
|
StatusBar *status_bar = status_bar_data(widget);
|
||||||
|
|
||||||
switch (msg->type) {
|
switch (msg->type) {
|
||||||
|
|
||||||
case JM_DESTROY:
|
case JM_DESTROY: {
|
||||||
|
JLink link;
|
||||||
|
|
||||||
|
JI_LIST_FOR_EACH(status_bar->progress, link) {
|
||||||
|
jfree(link->data);
|
||||||
|
}
|
||||||
|
jlist_free(status_bar->progress);
|
||||||
|
|
||||||
jfree(status_bar);
|
jfree(status_bar);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case JM_REQSIZE:
|
case JM_REQSIZE:
|
||||||
msg->reqsize.w = msg->reqsize.h =
|
msg->reqsize.w = msg->reqsize.h =
|
||||||
@ -238,63 +228,53 @@ static bool status_bar_msg_proc(JWidget widget, JMessage msg)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case JM_DRAW: {
|
case JM_DRAW: {
|
||||||
JRect rect = jwidget_get_rect(widget);
|
JRect rc = jwidget_get_rect(widget);
|
||||||
|
|
||||||
jdraw_rectedge(rect, ji_color_facelight(), ji_color_faceshadow());
|
jdraw_rectedge(rc, ji_color_facelight(), ji_color_faceshadow());
|
||||||
jrect_shrink(rect, 1);
|
jrect_shrink(rc, 1);
|
||||||
|
|
||||||
jdraw_rect(rect, ji_color_face());
|
jdraw_rect(rc, ji_color_face());
|
||||||
jrect_shrink(rect, 1);
|
jrect_shrink(rc, 1);
|
||||||
|
|
||||||
/* progress bar */
|
|
||||||
if (status_bar->nprogress > 0) {
|
|
||||||
int i, pos, x1, y1, x2, y2;
|
|
||||||
double x, width;
|
|
||||||
|
|
||||||
jdraw_rectedge(rect,
|
|
||||||
ji_color_faceshadow(),
|
|
||||||
ji_color_facelight());
|
|
||||||
jrect_shrink(rect, 1);
|
|
||||||
|
|
||||||
x1 = rect->x1;
|
|
||||||
y1 = rect->y1;
|
|
||||||
x2 = rect->x2-1;
|
|
||||||
y2 = rect->y2-1;
|
|
||||||
|
|
||||||
x = x1;
|
|
||||||
width = x2-x1+1;
|
|
||||||
|
|
||||||
for (i=0; i<status_bar->nprogress; i++) {
|
|
||||||
if (status_bar->progress[i].max > 0) {
|
|
||||||
pos = status_bar->progress[i].pos;
|
|
||||||
|
|
||||||
if (status_bar->nprogress == 1)
|
|
||||||
pos = MID(0, pos, status_bar->progress[i].max);
|
|
||||||
else
|
|
||||||
pos = MID(0, pos, status_bar->progress[i].max-1);
|
|
||||||
|
|
||||||
width /= (double)status_bar->progress[i].max;
|
|
||||||
x += width * (double)pos;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
x = MID(x1, x, x2);
|
|
||||||
rectfill(ji_screen, x1, y1, x, y2, ji_color_selected());
|
|
||||||
if (x < x2)
|
|
||||||
rectfill(ji_screen, x+1, y1, x2, y2, ji_color_background());
|
|
||||||
}
|
|
||||||
/* status bar text */
|
/* status bar text */
|
||||||
else if (widget->text) {
|
if (widget->text) {
|
||||||
jdraw_rectfill(rect, ji_color_face());
|
jdraw_rectfill(rc, ji_color_face());
|
||||||
|
|
||||||
text_mode(-1);
|
text_mode(-1);
|
||||||
textout(ji_screen, widget->text_font, widget->text,
|
textout(ji_screen, widget->text_font, widget->text,
|
||||||
rect->x1+2,
|
rc->x1+2,
|
||||||
(widget->rc->y1+widget->rc->y2)/2-text_height(widget->text_font)/2,
|
(widget->rc->y1+widget->rc->y2)/2-text_height(widget->text_font)/2,
|
||||||
ji_color_foreground());
|
ji_color_foreground());
|
||||||
}
|
}
|
||||||
|
|
||||||
jrect_free(rect);
|
/* draw progress bar */
|
||||||
|
if (!jlist_empty(status_bar->progress)) {
|
||||||
|
int width = 64;
|
||||||
|
int y1, y2;
|
||||||
|
int x = rc->x2 - (width+4);
|
||||||
|
JLink link;
|
||||||
|
|
||||||
|
y1 = rc->y1;
|
||||||
|
y2 = rc->y2-1;
|
||||||
|
|
||||||
|
JI_LIST_FOR_EACH(status_bar->progress, link) {
|
||||||
|
Progress *progress = link->data;
|
||||||
|
int u = (int)((float)(width-2)*progress->pos);
|
||||||
|
u = MID(0, u, width-2);
|
||||||
|
|
||||||
|
rect(ji_screen, x, y1, x+width-1, y2, ji_color_foreground());
|
||||||
|
|
||||||
|
if (u > 0)
|
||||||
|
rectfill(ji_screen, x+1, y1+1, x+u, y2-1, ji_color_selected());
|
||||||
|
|
||||||
|
if (1+u < width-2)
|
||||||
|
rectfill(ji_screen, x+1+u, y1+1, x+width-2, y2-1, ji_color_background());
|
||||||
|
|
||||||
|
x -= width+4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
jrect_free(rc);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -369,41 +349,37 @@ static void button_command(JWidget widget, void *data)
|
|||||||
Sprite *sprite = current_sprite;
|
Sprite *sprite = current_sprite;
|
||||||
|
|
||||||
if (sprite) {
|
if (sprite) {
|
||||||
int old_frame = sprite->frame;
|
const char *cmd = NULL;
|
||||||
|
|
||||||
switch ((int)data) {
|
switch ((int)data) {
|
||||||
|
|
||||||
case ACTION_LAYER:
|
case ACTION_LAYER:
|
||||||
command_execute(command_get_by_name(CMD_LAYER_PROPERTIES), NULL);
|
cmd = CMD_LAYER_PROPERTIES;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ACTION_FIRST:
|
case ACTION_FIRST:
|
||||||
sprite->frame = 0;
|
cmd = CMD_GOTO_FIRST_FRAME;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ACTION_PREV:
|
case ACTION_PREV:
|
||||||
if ((--sprite->frame) < 0)
|
cmd = CMD_GOTO_PREVIOUS_FRAME;
|
||||||
sprite->frame = sprite->frames-1;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ACTION_PLAY:
|
case ACTION_PLAY:
|
||||||
play_animation();
|
cmd = CMD_PLAY_ANIMATION;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ACTION_NEXT:
|
case ACTION_NEXT:
|
||||||
if ((++sprite->frame) >= sprite->frames)
|
cmd = CMD_GOTO_NEXT_FRAME;
|
||||||
sprite->frame = 0;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ACTION_LAST:
|
case ACTION_LAST:
|
||||||
sprite->frame = sprite->frames-1;
|
cmd = CMD_GOTO_LAST_FRAME;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sprite->frame != old_frame) {
|
if (cmd)
|
||||||
update_from_layer(widget->user_data[0]);
|
command_execute(command_get_by_name(cmd), NULL);
|
||||||
update_screen_for_sprite(sprite);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -436,83 +412,3 @@ static void update_from_layer(StatusBar *status_bar)
|
|||||||
jwidget_disable(status_bar->slider);
|
jwidget_disable(status_bar->slider);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
|
||||||
Animation Playing stuff
|
|
||||||
***********************************************************************/
|
|
||||||
|
|
||||||
static int speed_timer;
|
|
||||||
|
|
||||||
static void speed_timer_callback(void)
|
|
||||||
{
|
|
||||||
speed_timer++;
|
|
||||||
}
|
|
||||||
|
|
||||||
END_OF_STATIC_FUNCTION(speed_timer_callback);
|
|
||||||
|
|
||||||
static void play_animation(void)
|
|
||||||
{
|
|
||||||
Sprite *sprite = current_sprite;
|
|
||||||
int old_frame, msecs;
|
|
||||||
bool done = FALSE;
|
|
||||||
|
|
||||||
if (sprite->frames < 2)
|
|
||||||
return;
|
|
||||||
|
|
||||||
jmouse_hide();
|
|
||||||
|
|
||||||
old_frame = sprite->frame;
|
|
||||||
|
|
||||||
LOCK_VARIABLE(speed_timer);
|
|
||||||
LOCK_FUNCTION(speed_timer_callback);
|
|
||||||
|
|
||||||
clear_keybuf();
|
|
||||||
|
|
||||||
/* clear all the screen */
|
|
||||||
clear_bitmap(ji_screen);
|
|
||||||
|
|
||||||
/* do animation */
|
|
||||||
speed_timer = 0;
|
|
||||||
while (!done) {
|
|
||||||
msecs = sprite_get_frlen(sprite, sprite->frame);
|
|
||||||
install_int_ex(speed_timer_callback, MSEC_TO_TIMER(msecs));
|
|
||||||
|
|
||||||
set_palette(sprite_get_palette(sprite, sprite->frame));
|
|
||||||
editor_draw_sprite_safe(current_editor, 0, 0, sprite->w, sprite->h);
|
|
||||||
|
|
||||||
do {
|
|
||||||
poll_mouse();
|
|
||||||
poll_keyboard();
|
|
||||||
if (keypressed() || mouse_b)
|
|
||||||
done = TRUE;
|
|
||||||
gui_feedback();
|
|
||||||
} while (!done && (speed_timer <= 0));
|
|
||||||
|
|
||||||
if (!done) {
|
|
||||||
sprite->frame++;
|
|
||||||
if (sprite->frame >= sprite->frames)
|
|
||||||
sprite->frame = 0;
|
|
||||||
|
|
||||||
speed_timer--;
|
|
||||||
}
|
|
||||||
gui_feedback();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* if right-click or ESC */
|
|
||||||
if (mouse_b == 2 || (keypressed() && (readkey()>>8) == KEY_ESC))
|
|
||||||
/* return to the old frame position */
|
|
||||||
sprite->frame = old_frame;
|
|
||||||
|
|
||||||
/* refresh all */
|
|
||||||
set_current_palette(sprite_get_palette(sprite, sprite->frame), TRUE);
|
|
||||||
jmanager_refresh_screen();
|
|
||||||
gui_feedback();
|
|
||||||
|
|
||||||
while (mouse_b)
|
|
||||||
poll_mouse();
|
|
||||||
|
|
||||||
clear_keybuf();
|
|
||||||
remove_int(speed_timer_callback);
|
|
||||||
|
|
||||||
jmouse_show();
|
|
||||||
}
|
|
||||||
|
@ -22,17 +22,19 @@
|
|||||||
|
|
||||||
#include "jinete/jbase.h"
|
#include "jinete/jbase.h"
|
||||||
|
|
||||||
|
typedef struct Progress
|
||||||
|
{
|
||||||
|
JWidget status_bar;
|
||||||
|
float pos;
|
||||||
|
} Progress;
|
||||||
|
|
||||||
typedef struct StatusBar
|
typedef struct StatusBar
|
||||||
{
|
{
|
||||||
JWidget widget;
|
JWidget widget;
|
||||||
int timeout;
|
int timeout;
|
||||||
|
|
||||||
/* progress bar */
|
/* progress bar */
|
||||||
int nprogress;
|
JList progress;
|
||||||
struct {
|
|
||||||
int max;
|
|
||||||
int pos;
|
|
||||||
} progress[2];
|
|
||||||
|
|
||||||
/* box of main commands */
|
/* box of main commands */
|
||||||
JWidget commands_box;
|
JWidget commands_box;
|
||||||
@ -45,17 +47,20 @@ typedef struct StatusBar
|
|||||||
JWidget b_last; /* go to last frame */
|
JWidget b_last; /* go to last frame */
|
||||||
} StatusBar;
|
} StatusBar;
|
||||||
|
|
||||||
|
/* status_bar */
|
||||||
|
|
||||||
JWidget status_bar_new(void);
|
JWidget status_bar_new(void);
|
||||||
int status_bar_type(void);
|
int status_bar_type(void);
|
||||||
|
|
||||||
StatusBar *status_bar_data(JWidget status_bar);
|
StatusBar *status_bar_data(JWidget status_bar);
|
||||||
|
|
||||||
void status_bar_set_text(JWidget status_bar, int msecs, const char *format, ...);
|
void status_bar_set_text(JWidget status_bar, int msecs, const char *format, ...);
|
||||||
|
|
||||||
void status_bar_do_progress(JWidget status_bar, int progress);
|
|
||||||
void status_bar_add_progress(JWidget status_bar, int max);
|
|
||||||
void status_bar_del_progress(JWidget status_bar);
|
|
||||||
|
|
||||||
void status_bar_update(JWidget status_bar);
|
void status_bar_update(JWidget status_bar);
|
||||||
|
|
||||||
|
/* progress */
|
||||||
|
|
||||||
|
Progress *progress_new(JWidget status_bar);
|
||||||
|
void progress_free(Progress *progress);
|
||||||
|
void progress_update(Progress *progress, float progress_pos);
|
||||||
|
|
||||||
#endif /* WIDGETS_STATEBAR_H */
|
#endif /* WIDGETS_STATEBAR_H */
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/* ASE - Allegro Sprite Editor
|
/* ASE - Allegro Sprite Editor
|
||||||
* Copyright (C) 2001-2005, 2007 David A. Capello
|
* Copyright (C) 2001-2005, 2007, 2008 David A. Capello
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -315,7 +315,7 @@ static bool tabs_msg_proc(JWidget widget, JMessage msg)
|
|||||||
/* Tabs *tabs = jwidget_get_data(parent, tabs_type()); */
|
/* Tabs *tabs = jwidget_get_data(parent, tabs_type()); */
|
||||||
/* int dir = (int)jwidget_get_data(widget, tabs_type()); */
|
/* int dir = (int)jwidget_get_data(widget, tabs_type()); */
|
||||||
int dir = jmanager_get_capture() == tabs->button_left ? -1: 1;
|
int dir = jmanager_get_capture() == tabs->button_left ? -1: 1;
|
||||||
set_scroll_x(widget, tabs->scroll_x + dir*8);
|
set_scroll_x(widget, tabs->scroll_x + dir*8*msg->timer.count);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user