00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "pent_include.h"
00020
00021 #include <gtk/gtk.h>
00022
00023 #include <libgimp/gimp.h>
00024 #include <libgimp/gimpui.h>
00025
00026 #include <cstring>
00027
00028 #include "pentpal.h"
00029
00030 #include "FileSystem.h"
00031 #include "ConvertShape.h"
00032 #include "Shape.h"
00033 #include "ShapeFrame.h"
00034 #include "Palette.h"
00035
00036
00037
00038 #define LOAD_PROC "file_pshp_load"
00039 #define SAVE_PROC "file_pshp_save"
00040 #define EXT "PSHP"
00041 #define AUTHORS "The Pentagram Team"
00042 #define HELP "Pentagram Shape plugin loads and saves shapes which consist of multiple images, sometimes used as animation frames, for use with the Pentagram engine and the games it supports. Frames are handled in separate layers by this plugin"
00043
00044
00045 static void query(void);
00046 static void run(const gchar *name, gint nparams, const GimpParam * param,
00047 gint *nreturn_vals, GimpParam **return_vals);
00048 static gint32 load_image(IDataSource * ids, const gchar * filename);
00049 static void load_frame(Shape * s, uint32 framenum, GimpDrawable * drawable);
00050 static void paintFrame(Shape * s, uint32 framenum, void * pixels,
00051 uint32 pitch, sint32 x, sint32 y, GimpPixelRgn * clip_window);
00052
00053 static gint32 save_image(gchar *filename, gint32 image_ID,
00054 gint32 drawable_ID, gint32 orig_image_ID);
00055
00056 GimpPlugInInfo PLUG_IN_INFO =
00057 {
00058 NULL,
00059 NULL,
00060 query,
00061 run,
00062 };
00063
00064 MAIN ()
00065
00066 static void query(void)
00067 {
00068 static GimpParamDef load_args[] = {
00069 { GIMP_PDB_INT32, "run_mode", "Interactive, non-interactive" },
00070 { GIMP_PDB_STRING, "filename", "The name of the file to load" },
00071 { GIMP_PDB_STRING, "raw_filename", "The name entered" }
00072 };
00073
00074 static GimpParamDef load_return_vals[] = {
00075 { GIMP_PDB_IMAGE, "image", "Output image" }
00076 };
00077
00078 static GimpParamDef save_args[] = {
00079 { GIMP_PDB_INT32, "run_mode", "Interactive, non-interactive" },
00080 { GIMP_PDB_IMAGE, "image", "Image to save" },
00081 { GIMP_PDB_DRAWABLE, "drawable", "Drawable to save" },
00082 { GIMP_PDB_STRING, "filename", "The name of the file to save" },
00083 { GIMP_PDB_STRING, "raw_filename", "The name entered" }
00084 };
00085
00086 gimp_install_procedure (LOAD_PROC,
00087 "Load files in Pentagram SHP format",
00088 HELP,
00089 AUTHORS,
00090 AUTHORS,
00091 "2004",
00092
00093 "<Load>/" EXT,
00094 NULL,
00095 GIMP_PLUGIN,
00096 G_N_ELEMENTS (load_args), G_N_ELEMENTS (load_return_vals),
00097 load_args, load_return_vals);
00098
00099 gimp_register_magic_load_handler (LOAD_PROC, EXT, "", "");
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117 }
00118
00119 static void run(const gchar *name, gint nparams, const GimpParam * param,
00120 gint *nreturn_vals, GimpParam **return_vals)
00121 {
00122 static GimpParam values[2];
00123 GimpPDBStatusType status = GIMP_PDB_SUCCESS;
00124 gint32 image_ID;
00125 gint32 drawable_ID;
00126 gint32 orig_image_ID;
00127 gchar * name_buf;
00128 gchar * filename;
00129 GimpRunMode run_mode;
00130
00131 *nreturn_vals = 1;
00132 *return_vals = values;
00133 values[0].type = GIMP_PDB_STATUS;
00134 run_mode = (GimpRunMode) param[0].data.d_int32;
00135
00136 if (! strcmp(name, LOAD_PROC))
00137 {
00138 FileSystem filesys(true);
00139 IDataSource * ids = filesys.ReadFile(param[1].data.d_string);
00140 gimp_ui_init("pentshp", FALSE);
00141
00142 if (ids)
00143 {
00144 image_ID = load_image(ids, param[1].data.d_string);
00145 if (image_ID != -1)
00146 {
00147 *nreturn_vals = 2;
00148 values[1].type = GIMP_PDB_IMAGE;
00149 values[1].data.d_image = image_ID;
00150 }
00151 else
00152 {
00153 status = GIMP_PDB_EXECUTION_ERROR;
00154 }
00155
00156 delete ids;
00157 ids = 0;
00158 }
00159 else
00160 {
00161 status = GIMP_PDB_EXECUTION_ERROR;
00162 }
00163 }
00164 else if (! strcmp(name, SAVE_PROC))
00165 {
00166 orig_image_ID = param[1].data.d_int32;
00167 image_ID = orig_image_ID;
00168 drawable_ID = param[2].data.d_int32;
00169 filename = param[3].data.d_string;
00170 if (run_mode != GIMP_RUN_NONINTERACTIVE)
00171 {
00172 name_buf = g_strdup_printf("Saving %s:", filename);
00173 gimp_progress_init(name_buf);
00174 g_free(name_buf);
00175 }
00176 save_image(filename, image_ID,
00177 drawable_ID, orig_image_ID);
00178 }
00179 else
00180 {
00181 status = GIMP_PDB_CALLING_ERROR;
00182 }
00183
00184 values[0].data.d_status = status;
00185 }
00186
00187 static gint32 load_image(IDataSource * ids, const gchar * filename)
00188 {
00189 gint32 image_ID, layer_ID;
00190 sint32 height, width;
00191 sint32 min_x, min_y;
00192 uint32 i;
00193 ShapeFrame *frame;
00194 Pentagram::Palette pal;
00195 guchar cmap[768];
00196 const ConvertShapeFormat *read_format;
00197 uint32 read_size = ids->getSize();
00198 gchar *framename;
00199 GimpDrawable *drawable;
00200
00201 read_format = Shape::DetectShapeFormat(ids, read_size);
00202 if (!read_format)
00203 {
00204 return -1;
00205 }
00206
00207 if (loadPalette(&pal, read_format))
00208 {
00209 for (int i = 0; i < 256; ++i)
00210 {
00211 cmap[i* 3] = pal.palette[i * 3];
00212 cmap[i* 3 + 1] = pal.palette[i * 3 + 1];
00213 cmap[i* 3 + 2] = pal.palette[i * 3 + 2];
00214 }
00215 }
00216 else
00217 {
00218 return -1;
00219 }
00220
00221 Shape shape(ids, read_format);
00222 shape.setPalette(&pal);
00223
00224 min_x = 0;
00225 min_y = 0;
00226 height = 0;
00227 width = 0;
00228 for (i = 0; i < shape.frameCount(); ++i)
00229 {
00230 frame = shape.getFrame(i);
00231
00232 if (frame->xoff < min_x)
00233 min_x = frame->xoff;
00234 if (frame->yoff < min_y)
00235 min_y = frame->yoff;
00236 if (frame->height + frame->yoff > height)
00237 height = frame->height + frame->yoff;
00238 if (frame->width + frame->xoff > width)
00239 width = frame->width + frame->xoff;
00240 }
00241 image_ID = gimp_image_new(width - min_x, height - min_y, GIMP_INDEXED);
00242 gimp_image_set_filename(image_ID, filename);
00243 gimp_image_set_colormap(image_ID, cmap, 256);
00244
00245 for (i = 0; i < shape.frameCount(); ++i)
00246 {
00247 frame = shape.getFrame(i);
00248 framename = g_strdup_printf("Frame %d", i);
00249 layer_ID = gimp_layer_new(image_ID, framename, frame->width, frame->height, GIMP_INDEXEDA_IMAGE, 100, GIMP_NORMAL_MODE);
00250 g_free(framename);
00251 gimp_image_add_layer(image_ID, layer_ID, 0);
00252 gimp_layer_translate(layer_ID, frame->xoff - min_x, frame->yoff - min_y);
00253
00254 drawable = gimp_drawable_get(layer_ID);
00255 if (i > 0)
00256 {
00257 gimp_drawable_set_visible(layer_ID, FALSE);
00258 }
00259 load_frame(&shape, i, drawable);
00260
00261 gimp_drawable_flush(drawable);
00262 gimp_drawable_detach(drawable);
00263 }
00264
00265 return image_ID;
00266 }
00267
00268 static void load_frame(Shape * s, uint32 framenum, GimpDrawable * drawable)
00269 {
00270 GimpPixelRgn clip_window;
00271 ShapeFrame * frame;
00272
00273 gimp_pixel_rgn_init(&clip_window, drawable, 0, 0, drawable->width, drawable->height, TRUE, FALSE);
00274
00275 uint32 pitch = drawable->width;
00276 gulong psize = drawable->width * drawable->height;
00277 guchar *pixels = g_new0(guchar, psize * 2);
00278
00279 frame = s->getFrame(framenum);
00280 paintFrame(s, framenum, (uint16 *) pixels, pitch * 2, frame->xoff, frame->yoff, &clip_window);
00281
00282 gimp_pixel_rgn_set_rect(&clip_window, pixels, 0, 0, drawable->width, drawable->height);
00283 g_free(pixels);
00284
00285
00286 }
00287
00288 #include <cstdio>
00289
00290 static void paintFrame(Shape * s, uint32 framenum, void * pixels,
00291 uint32 pitch, sint32 x, sint32 y, GimpPixelRgn * clip_window)
00292 {
00293 #define untformed_pal true
00294 #define NO_CLIPPING
00295 #define uintX uint16
00296
00297 #define clip_window (*clip_window)
00298
00299 #include "SoftRenderSurface.inl"
00300
00301 #undef clip_window
00302 #undef uintX
00303 #undef NO_CLIPPING
00304 }
00305
00306 static gint32 save_image(gchar *filename, gint32 image_ID,
00307 gint32 drawable_ID, gint32 orig_image_ID)
00308 {
00309 return -1;
00310 }